[
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "请按照下面的规则提交您的issue，符合标准的issue会被优先处理,\n请先查看有没有同类型的issue已经存在.\n\n1. demo问题的issue格式： [demo]:title\n\n   title尽量反应问题的状况，如果是编译问题或者无法运行，正文写明是windows还是mac，如果是不清楚如何使用demo，请先查看https://github.com/alibaba/atlas/blob/master/atlas-demo/README.zh_cn.md\n     \n2. 容器功能接入或者如何使用的答疑：[use]:title\n3. 提新需求的格式：[feature]:title"
  },
  {
    "path": ".gitignore",
    "content": "*.iml\n.gradle\n.idea/\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n!.idea/codeStyleSettings.xml\n.DS_Store\n#/build\n/captures\n.vscode/\n\n# Taken from Android.gitignore https://github.com/github/gitignore/blob/master/Android.gitignore\n#\n# Built application files\n*.apk\n*.ap_\n\n# Files for the Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\n#build/\n!**/atlas-aapt/**/build/\n!**/src/**/build/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\n#proguard/\n!**/src/**/proguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# Intellij\n*.iml\n\natlas-demo/AtlasDemo/hisTpatch/\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"atlas-aapt/build\"]\n\tpath = atlas-aapt/build\n\turl = https://android.googlesource.com/platform/build\n[submodule \"atlas-aapt/prebuilts/clang/darwin-x86/host/3.6\"]\n\tpath = atlas-aapt/prebuilts/clang/darwin-x86/host/3.6\n\turl = https://android.googlesource.com/platform/prebuilts/clang/darwin-x86/host/3.6\n[submodule \"atlas-aapt/prebuilts/clang/host/darwin-x86\"]\n\tpath = atlas-aapt/prebuilts/clang/host/darwin-x86\n\turl = https://android.googlesource.com/platform/prebuilts/clang/host/darwin-x86\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Atlas Contributing Guide\n\nWelcome to create [Pull Requests](https://github.com/alibaba/atlas/compare) or open [Issues](https://github.com/alibaba/atlas/issues/new) for bugfix, doc, example, suggestion and anything.\n\n## Branch Management\n\n```\nmaster\n ↑\ndev         <--- PR(hotfix/typo/3rd-PR)\n ↑ PR\n{domain}-feature-{date}\n```  \nAtlas Branches\n\n0. `master` branch\n    0. `master` is the latest (pre-)release branch.\n0. `dev` branch\n    0. `dev` is the stable developing branch. [Github Release](https://help.github.com/articles/creating-releases/) is used to publish a (pre-)release version to `master` branch.\n    0. ***It's RECOMMENDED to commit hotfix (like typo) or feature PR to `dev`***.\n0. `{domain}-feature-{date}` branch\n    0. The branch for a developing iteration, e.g. `core-feature-20170118` is an atlas-core developing iteration which is done at 2017.01.18. `{domain}` consists of `core`, `update`, `plugin` and `aapt`. \n    0. **DO NOT commit any PR to such a branch**.\n\n### Branch Name \n\n```\n{module}-{action}-{shortName}\n```\n\n* `{module}`, see [commit log module](#commit-log)\n* `{action}`\n    * `feature`: checkout from `{module}` and merge to `{module}` later. If `{module}` not exists, merge to `dev`\n    * `bugfix`: like `feature`, for bugfix only\n    * `hotfix`: checkout from `master` or release `tag`, merge to `master` and `{module}` later. If `{module}` not exists, merge to `dev`\n\nfor example:\n\n* `core-bugfix-memory`\n* `plugin-feature-redex`\n* `update-hotfix-sequence`\n\n## Commit Log\n\n```\n[{module}] {description}\n```\n* `{module}`\n    * Including: atlas-core, atlas-aapt, atlas-update, atlas-gradle-plugin, atlas-doc, atlas-website, atlas-demo, test, all \n* `{description}`\n    * It's ***RECOMMENDED*** to close issue with syntax `close #66` or `fix #66`, see [the doc](https://help.github.com/articles/closing-issues-via-commit-messages/) for more detail. It's useful for responding issues.\n\nfor example:\n\n* `[all] close #66, add refreshing for memory`\n* `[atlas-doc] fix #68, update some instruction`\n* `[atlas-demo] remove abc`\n\n\n## Pull Request\n\n[Create Pull Requests](https://github.com/alibaba/atlas/compare).\n\n## Contributor License Agreement\nIn order to contribute code to Atlas, you (or the legal entity you represent) must sign the Contributor License Agreement (CLA).\n\nYou can read and sign the [Alibaba CLA](https://cla-assistant.io/alibaba/atlas) online.\n\nFor CLA assistant service works properly, please make sure you have added email address that your commits linked to GitHub account.\n\nPlease read [How to setting your Email address in Git](https://help.github.com/articles/setting-your-email-in-git/) and [How to adding an email address to your GitHub Account](https://help.github.com/articles/adding-an-email-address-to-your-github-account/).\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "NOTICE",
    "content": "Atlas-Framework\nCopyright 2016 Alibaba Group\n\nThis product includes software developed at Alibaba Group. (http://www.alibabagroup.com).\n\nThis product modifed software aapt(https://android.googlesource.com/platform/frameworks/base/+/master/tools/aapt/) developed by The Android Open Source Project (http://source.android.com).\n\nThis product modifed software Android Gradle Build System(https://android.googlesource.com/platform/tools/base/+/gradle-dev/build-system/) developed by The Android Open Source Project (http://source.android.com).\n"
  },
  {
    "path": "README.md",
    "content": "# Atlas\n\n[![license](http://img.shields.io/badge/license-Apache2.0-brightgreen.svg?style=flat)](https://github.com/alibaba/atlas/blob/master/LICENSE)\n[![Release Version](https://img.shields.io/badge/atlas__core-5.1.0.9--rc26-orange.svg)](https://github.com/alibaba/atlas/releases/tag/v5.1.0.9-rc26) \n[![Release Version](https://img.shields.io/badge/atlasplugin-3.0.1--rc88-green.svg)](https://github.com/alibaba/atlas/releases/tag/v5.1.0.9-rc26) \n\n\n> A powerful Android Dynamic Component Framework.\n\nAtlas is an Android client-side containerization framework. we call it android dynamic component framework.\n\nAtlas provides decoupled, component, and dynamic support. Atlas covers various issues in the project coding period, Apk run-time and follow-up operation and maintenance.\n\nIn the project period, Atlas enable engineers independent development, independent debug, because their project were physical isolation.\n\nIn the apk run-time, Atlas has complete component life cycle, class isolation and other mechanisms.\n\nIn the operation and maintenance period, Atlas provide rapid incremental update and rapid upgrade capacity.\n\nAtlas put the work into the project period as much as possible, to ensure runtime simple and stable, maintenance easy.\n\n------\n\nCompared with multidex solution, Atlas not only solved the limitation of the method count(65535), but also clarified the boundary of development, provied the powerful capabilities for Android development, such as Parallel Iteration, Rapid Development, Flexible Release, Dynamically Update, Quick Fix Online Failure.\n\nUnlike some Android plugin frameworks, Atlas is a component framework (we call it Bundle), Atlas is not a multi-process framework.\n\n------\nYou can see there were three main library in this project ([atlas-core](./atlas-core)/[atlas-update](./atlas-update)/[atlas-gradle-plugin](./atlas-gradle-plugin))\n\n* [atlas-core](./atlas-core): This is client-side core library, it's job is to install each bundle, load the classes and resources on-demand when runtime.\n* [atlas-update](./atlas-update): This is client-side update library, which provide dexmerge capacity for update or upgrade.\n* [atlas-gradle-plugin](./atlas-gradle-plugin): This is Android Studio Gradle Plugin for engineers developing in project period, because we change some android default package mechanisms, include android aapt [atlas-aapt](./atlas-aapt).\n\n## Use Atlas\n\n* [Demo](./atlas-demo)\n* Doc: [English](), [中文](./atlas-docs)\n* DingTalk im group: Scan the follow QR code or Search group 11727755 using DingTalk(钉钉) app.\n![dingtalk.jpg](assets/dingtalk.jpg) \n\n\n## Support\n----------\nAtlas support all Android version from Android 4.0 to 9.0. \n\nFollow is support status.\n\nRuntime | Android Version | Support\n------  | --------------- | --------\nDalvik  | 2.2             | Not Test\nDalvik  | 2.3             | Not Test\nDalvik  | 3.0             | Not Test\nDalvik  | 4.0-4.4         | Yes\nART     | 5.0             | Yes\nART     | 5.1             | Yes\nART     | M               | Yes\nART     | N               | Yes\nART     | 8.0             | Yes\nART     | 9.0             | Yes\n\n<!--## Contributing\n\nSee [Atlas Contributing Guide](./CONTRIBUTING.md) for more information.\n No newline at end of file\n-->\n"
  },
  {
    "path": "_config.yml",
    "content": "theme: jekyll-theme-cayman"
  },
  {
    "path": "atlas-aapt/.gitignore",
    "content": ".idea/\n.ccache/\nout/\nout-x86_64/\nout-x86/\nShakaAaptBin/"
  },
  {
    "path": "atlas-aapt/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.3)\nproject(ShakaAapt)\n\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++11\")\n\nset(AAPTROOT frameworks/base/tools/aapt)\nset(aaptMain ${AAPTROOT}/Main.cpp)\nset(aaptSources\n        ${AAPTROOT}/AaptAssets.cpp\n        ${AAPTROOT}/AaptConfig.cpp\n        ${AAPTROOT}/AaptUtil.cpp\n        ${AAPTROOT}/AaptXml.cpp\n        ${AAPTROOT}/ApkBuilder.cpp\n        ${AAPTROOT}/Command.cpp\n        ${AAPTROOT}/CrunchCache.cpp\n        ${AAPTROOT}/FileFinder.cpp\n        ${AAPTROOT}/Images.cpp\n        ${AAPTROOT}/Package.cpp\n        ${AAPTROOT}/pseudolocalize.cpp\n        ${AAPTROOT}/Resource.cpp\n        ${AAPTROOT}/ResourceFilter.cpp\n        ${AAPTROOT}/ResourceIdCache.cpp\n        ${AAPTROOT}/ResourceTable.cpp\n        ${AAPTROOT}/SourcePos.cpp\n        ${AAPTROOT}/StringPool.cpp\n        ${AAPTROOT}/WorkQueue.cpp\n        ${AAPTROOT}/XMLNode.cpp\n        ${AAPTROOT}/ZipEntry.cpp\n        ${AAPTROOT}/ZipFile.cpp\n)\n\nset(LIB_androidfw_ROOT frameworks/base/libs/androidfw)\nset(LIB_androidfw_commonSources\n        ${LIB_androidfw_ROOT}/Asset.cpp\n        ${LIB_androidfw_ROOT}/AssetDir.cpp\n        ${LIB_androidfw_ROOT}/AssetManager.cpp\n        ${LIB_androidfw_ROOT}/misc.cpp\n        ${LIB_androidfw_ROOT}/ObbFile.cpp\n        ${LIB_androidfw_ROOT}/ResourceTypes.cpp\n        ${LIB_androidfw_ROOT}/StreamingZipInflater.cpp\n        ${LIB_androidfw_ROOT}/TypeWrappers.cpp\n        ${LIB_androidfw_ROOT}/ZipFileRO.cpp\n        ${LIB_androidfw_ROOT}/ZipUtils.cpp)\n\nset(LIB_LIBUTILS system/core/libutils)\nset(LIB_LIBUTILS_commonSources\n        ${LIB_LIBUTILS}/BlobCache.cpp\n        ${LIB_LIBUTILS}/CallStack.cpp\n        ${LIB_LIBUTILS}/FileMap.cpp\n        ${LIB_LIBUTILS}/JenkinsHash.cpp\n        ${LIB_LIBUTILS}/LinearTransform.cpp\n        ${LIB_LIBUTILS}/Log.cpp\n        ${LIB_LIBUTILS}/NativeHandle.cpp\n        ${LIB_LIBUTILS}/Printer.cpp\n        ${LIB_LIBUTILS}/ProcessCallStack.cpp\n        ${LIB_LIBUTILS}/PropertyMap.cpp\n        ${LIB_LIBUTILS}/RefBase.cpp\n        ${LIB_LIBUTILS}/SharedBuffer.cpp\n        ${LIB_LIBUTILS}/Static.cpp\n        ${LIB_LIBUTILS}/StopWatch.cpp\n        ${LIB_LIBUTILS}/String8.cpp\n        ${LIB_LIBUTILS}/String16.cpp\n        ${LIB_LIBUTILS}/SystemClock.cpp\n        ${LIB_LIBUTILS}/Threads.cpp\n        ${LIB_LIBUTILS}/Timers.cpp\n        ${LIB_LIBUTILS}/Tokenizer.cpp\n        ${LIB_LIBUTILS}/Unicode.cpp\n        ${LIB_LIBUTILS}/VectorImpl.cpp\n        ${LIB_LIBUTILS}/misc.cpp\n)\n\nset(LIB_EXPAT external/expat)\nset(LIB_EXPAT_commonSources\n    ${LIB_EXPAT}/lib/xmlparse.c\n    ${LIB_EXPAT}/lib/xmlrole.c\n    ${LIB_EXPAT}/lib/xmltok.c\n    ${LIB_EXPAT}/lib/xmltok_impl.c\n    ${LIB_EXPAT}/lib/xmltok_ns.c\n)\n\nset(SOURCE_FILES ${SOURCE_FILES}\n        ${aaptMain}\n        ${aaptSources}\n        ${LIB_androidfw_commonSources}\n        ${LIB_LIBUTILS_commonSources}\n        ${LIB_EXPAT_commonSources}\n)\n\ninclude_directories(${AAPTROOT})\ninclude_directories(frameworks/base/include\n        external/safe-iop/include\n        system/core/include\n        external/zlib\n        external/expat/lib\n)\n\nadd_definitions(-DXML_TOK_IMPL_C)\n\nadd_executable(ShakaAapt ${SOURCE_FILES})"
  },
  {
    "path": "atlas-aapt/Makefile",
    "content": "### DO NOT EDIT THIS FILE ###\ninclude build/core/main.mk\n### DO NOT EDIT THIS FILE ###\n"
  },
  {
    "path": "atlas-aapt/README.md",
    "content": "# atlas-aapt\n\nThis project base on [ShakaAapt](https://github.com/rover12421/ShakaAapt)，which strip the necessary aapt code from AOSP android-7.0.0_r6 branch.\n\n## Compile Env\n\nPlease refer to AOSP\n\n## atlas-aapt\n\natlas-aapt expand follow options base on AOSP aapt:\n\n1. --customized-package-id: generally aapt typed package resource id is 0x7f, this is the application bundle package-id of resources. Use this option to specify the resource package-id for other values, but must be less than or equal to 0x7f. (example: - customized package - id 126).\n\n2. --use-skt-package-name: generally a package reference another package of resources, resources must be combined with the package name for reference, such as a reference when android resource must be combined with '@ android:' for reference. Use this option, can eliminate the process of writing a package name, find resources directly. The name of this package is usually the main atlas package name.\n\n3. -B: used for dynamic deployment of resources, if you want to hit this package based on the a package of resources patch package, so use this option to specify the basic package."
  },
  {
    "path": "atlas-aapt/README.zh-cn.md",
    "content": "## atlas-aapt\n\n此项目基于[ShakaAapt](https://github.com/rover12421/ShakaAapt)，该项目抽离了AOSP——android-7.0.0_r6中编译aapt的必要代码。\n\n## 编译环境\n\n具体参考AOSP编译官方文档\n\n## atlas-aapt提供的功能\n\natlas-aapt在官方aapt的基础上添加了以下扩展选项：\n\n1. --customized-package-id：一般aapt打出来包的资源id都是以7f开头，这个就是应用包资源的package-id。使用这个选项可以指定资源的package-id为其他数值，但是必须小于等于7f。（示例：--customized-package-id 126）。\n2. --use-skt-package-name：一般一个包引用另一个包的资源的时候，都必须加上资源的包名来进行引用，比如引用android的资源的时候必须加上`@android:`来进行引用。使用这个选项，可以省去写包名的过程，直接找到资源。这个包的名字通常是atlas中主包的包名。\n3. -B：资源动态部署用，如果你想基于一个包来打出这个包的资源patch包，那么使用该选项来指定基础包。"
  },
  {
    "path": "atlas-aapt/UpdateAndroidSource.sh",
    "content": "#! /bin/bash\nSRCROOT=/Develop/android/source/android-last\nDESROOT=.\n\narray=( \\\n\tbionic/libc/include \\\n\texternal/compiler-rt \\\n\texternal/expat \\\n\texternal/libcxx \\\n\texternal/libcxxabi \\\n\texternal/libpng \\\n\texternal/safe-iop \\\n\texternal/zlib \\\n\tframeworks/base/include \\\n\tframeworks/base/libs/androidfw \\\n\tframeworks/base/tools/aapt \\\n\tframeworks/native/include \\\n\tlibnativehelper \\\n\tprebuilts/clang/darwin-x86 \\\n\tprebuilts/clang/host \\\n\tprebuilts/gcc \\\n\tsdk/build \\\n\tsystem/core/base \\\n\tsystem/core/include \\\n\tsystem/core/libcutils \\\n\tsystem/core/liblog \\\n\tsystem/core/libutils \\\n\tsystem/core/libziparchive \\\n\t)\n\nfor var in ${array[@]};do\nrsync -aP --delete $SRCROOT/$var/ $DESROOT/$var/ \\\n  --exclude .git \\\n  --exclude test \\\n  --exclude tests \\\n  --exclude testdata \\\n  --exclude examples \\\n  --exclude doc \\\n  --exclude www \\\n  --exclude unittests \\\n  --exclude common \\\n  --exclude linux-x86/mips \\\n  --exclude linux-x86/arm \\\n  --exclude linux-x86/aarch64 \\\n  --exclude linux-x86/x86 \\\n  --exclude linux-x86/host/x86_64-linux-glibc2.11-4.8 \\\n  --exclude linux-x86/host/x86_64-w64-mingw32-4.8 \\\n  --exclude darwin-x86/mips \\\n  --exclude darwin-x86/arm \\\n  --exclude darwin-x86/aarch64 \\\n  --exclude darwin-x86/x86\ndone\n\n\n\n\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/alloca.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _ALLOCA_H\n#define _ALLOCA_H\n\n#define alloca(size)   __builtin_alloca(size)\n\n#endif /* _ALLOCA_H */\n\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/android/api-level.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef ANDROID_API_LEVEL_H\n#define ANDROID_API_LEVEL_H\n\n/*\n * Magic version number for a current development build, which has\n * not yet turned into an official release.\n */\n#define __ANDROID_API__ 10000\n\n#endif /* ANDROID_API_LEVEL_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/android/dlext.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __ANDROID_DLEXT_H__\n#define __ANDROID_DLEXT_H__\n\n#include <stddef.h>\n#include <stdint.h>\n#include <sys/cdefs.h>\n#include <sys/types.h>  /* for off64_t */\n\n__BEGIN_DECLS\n\n/* bitfield definitions for android_dlextinfo.flags */\nenum {\n  /* When set, the reserved_addr and reserved_size fields must point to an\n   * already-reserved region of address space which will be used to load the\n   * library if it fits. If the reserved region is not large enough, the load\n   * will fail.\n   */\n  ANDROID_DLEXT_RESERVED_ADDRESS      = 0x1,\n\n  /* As DLEXT_RESERVED_ADDRESS, but if the reserved region is not large enough,\n   * the linker will choose an available address instead.\n   */\n  ANDROID_DLEXT_RESERVED_ADDRESS_HINT = 0x2,\n\n  /* When set, write the GNU RELRO section of the mapped library to relro_fd\n   * after relocation has been performed, to allow it to be reused by another\n   * process loading the same library at the same address. This implies\n   * ANDROID_DLEXT_USE_RELRO.\n   */\n  ANDROID_DLEXT_WRITE_RELRO           = 0x4,\n\n  /* When set, compare the GNU RELRO section of the mapped library to relro_fd\n   * after relocation has been performed, and replace any relocated pages that\n   * are identical with a version mapped from the file.\n   */\n  ANDROID_DLEXT_USE_RELRO             = 0x8,\n\n  /* Instruct dlopen to use library_fd instead of opening file by name.\n   * The filename parameter is still used to identify the library.\n   */\n  ANDROID_DLEXT_USE_LIBRARY_FD        = 0x10,\n\n  /* If opening a library using library_fd read it starting at library_fd_offset.\n   * This flag is only valid when ANDROID_DLEXT_USE_LIBRARY_FD is set.\n   */\n  ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET    = 0x20,\n\n  /* When set, do not check if the library has already been loaded by file stat(2)s.\n   *\n   * This flag allows forced loading of the library in the case when for some\n   * reason multiple ELF files share the same filename (because the already-loaded\n   * library has been removed and overwritten, for example).\n   *\n   * Note that if the library has the same dt_soname as an old one and some other\n   * library has the soname in DT_NEEDED list, the first one will be used to resolve any\n   * dependencies.\n   */\n  ANDROID_DLEXT_FORCE_LOAD = 0x40,\n\n  /* When set, if the minimum p_vaddr of the ELF file's PT_LOAD segments is non-zero,\n   * the dynamic linker will load it at that address.\n   *\n   * This flag is for ART internal use only.\n   */\n  ANDROID_DLEXT_FORCE_FIXED_VADDR = 0x80,\n\n  /* Instructs dlopen to load the library at the address specified by reserved_addr.\n   *\n   * The difference between ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS and ANDROID_DLEXT_RESERVED_ADDRESS\n   * is that for ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS the linker reserves memory at reserved_addr\n   * whereas for ANDROID_DLEXT_RESERVED_ADDRESS the linker relies on the caller to reserve the memory.\n   *\n   * This flag can be used with ANDROID_DLEXT_FORCE_FIXED_VADDR; when ANDROID_DLEXT_FORCE_FIXED_VADDR\n   * is set and load_bias is not 0 (load_bias is min(p_vaddr) of PT_LOAD segments) this flag is ignored.\n   * This is implemented this way because the linker has to pick one address over the other and this\n   * way is more convenient for art. Note that ANDROID_DLEXT_FORCE_FIXED_VADDR does not generate\n   * an error when min(p_vaddr) is 0.\n   *\n   * Cannot be used with ANDROID_DLEXT_RESERVED_ADDRESS or ANDROID_DLEXT_RESERVED_ADDRESS_HINT.\n   *\n   * This flag is for ART internal use only.\n   */\n  ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS = 0x100,\n\n  /* This flag used to load library in a different namespace. The namespace is\n   * specified in library_namespace.\n   */\n  ANDROID_DLEXT_USE_NAMESPACE = 0x200,\n\n  /* Mask of valid bits */\n  ANDROID_DLEXT_VALID_FLAG_BITS       = ANDROID_DLEXT_RESERVED_ADDRESS |\n                                        ANDROID_DLEXT_RESERVED_ADDRESS_HINT |\n                                        ANDROID_DLEXT_WRITE_RELRO |\n                                        ANDROID_DLEXT_USE_RELRO |\n                                        ANDROID_DLEXT_USE_LIBRARY_FD |\n                                        ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET |\n                                        ANDROID_DLEXT_FORCE_LOAD |\n                                        ANDROID_DLEXT_FORCE_FIXED_VADDR |\n                                        ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS |\n                                        ANDROID_DLEXT_USE_NAMESPACE,\n};\n\nstruct android_namespace_t;\n\ntypedef struct {\n  uint64_t flags;\n  void*   reserved_addr;\n  size_t  reserved_size;\n  int     relro_fd;\n  int     library_fd;\n  off64_t library_fd_offset;\n  struct android_namespace_t* library_namespace;\n} android_dlextinfo;\n\nextern void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo);\n\n__END_DECLS\n\n#endif /* __ANDROID_DLEXT_H__ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/android/legacy_errno_inlines.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _ANDROID_LEGACY_ERRNO_INLINES_H\n#define _ANDROID_LEGACY_ERRNO_INLINES_H\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\nstatic __inline int __attribute__((deprecated)) __set_errno(int n) {\n  errno = n;\n  return -1;\n}\n\n__END_DECLS\n\n#endif /* _ANDROID_LEGACY_ERRNO_INLINES_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/android/legacy_signal_inlines.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _ANDROID_LEGACY_SIGNAL_INLINES_H_\n#define _ANDROID_LEGACY_SIGNAL_INLINES_H_\n\n#include <string.h>\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\nextern sighandler_t bsd_signal(int signum, sighandler_t handler);\n\nstatic __inline int sigismember(sigset_t *set, int signum) {\n  /* Signal numbers start at 1, but bit positions start at 0. */\n  int bit = signum - 1;\n  const unsigned long *local_set = (const unsigned long *)set;\n  if (set == NULL || bit < 0 || bit >= (int)(8 * sizeof(sigset_t))) {\n    errno = EINVAL;\n    return -1;\n  }\n  return (int)((local_set[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1);\n}\n\nstatic __inline int sigaddset(sigset_t *set, int signum) {\n  /* Signal numbers start at 1, but bit positions start at 0. */\n  int bit = signum - 1;\n  unsigned long *local_set = (unsigned long *)set;\n  if (set == NULL || bit < 0 || bit >= (int)(8 * sizeof(sigset_t))) {\n    errno = EINVAL;\n    return -1;\n  }\n  local_set[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT);\n  return 0;\n}\n\nstatic __inline int sigdelset(sigset_t *set, int signum) {\n  /* Signal numbers start at 1, but bit positions start at 0. */\n  int bit = signum - 1;\n  unsigned long *local_set = (unsigned long *)set;\n  if (set == NULL || bit < 0 || bit >= (int)(8 * sizeof(sigset_t))) {\n    errno = EINVAL;\n    return -1;\n  }\n  local_set[bit / LONG_BIT] &= ~(1UL << (bit % LONG_BIT));\n  return 0;\n}\n\nstatic __inline int sigemptyset(sigset_t *set) {\n  if (set == NULL) {\n    errno = EINVAL;\n    return -1;\n  }\n  memset(set, 0, sizeof(sigset_t));\n  return 0;\n}\n\nstatic __inline int sigfillset(sigset_t *set) {\n  if (set == NULL) {\n    errno = EINVAL;\n    return -1;\n  }\n  memset(set, ~0, sizeof(sigset_t));\n  return 0;\n}\n\nstatic __inline sighandler_t signal(int s, sighandler_t f) {\n  return bsd_signal(s, f);\n}\n\n__END_DECLS\n\n#endif /* _ANDROID_LEGACY_SIGNAL_INLINES_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/android/legacy_stdlib_inlines.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _ANDROID_LEGACY_STDLIB_INLINES_H_\n#define _ANDROID_LEGACY_STDLIB_INLINES_H_\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\nstatic __inline float strtof(const char *nptr, char **endptr) {\n  return (float)strtod(nptr, endptr);\n}\n\nstatic __inline double atof(const char *nptr) { return (strtod(nptr, NULL)); }\n\nstatic __inline int abs(int __n) { return (__n < 0) ? -__n : __n; }\n\nstatic __inline long labs(long __n) { return (__n < 0L) ? -__n : __n; }\n\nstatic __inline long long llabs(long long __n) {\n  return (__n < 0LL) ? -__n : __n;\n}\n\nstatic __inline int rand(void) { return (int)lrand48(); }\n\nstatic __inline void srand(unsigned int __s) { srand48(__s); }\n\nstatic __inline long random(void) { return lrand48(); }\n\nstatic __inline void srandom(unsigned int __s) { srand48(__s); }\n\nstatic __inline int grantpt(int __fd __attribute((unused))) {\n  return 0; /* devpts does this all for us! */\n}\n\n__END_DECLS\n\n#endif /* _ANDROID_LEGACY_STDLIB_INLINES_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/android/legacy_sys_atomics_inlines.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _ANDROID_LEGACY_SYS_ATOMICS_INLINES_H_\n#define _ANDROID_LEGACY_SYS_ATOMICS_INLINES_H_\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\n/* Note: atomic operations that were exported by the C library didn't\n *       provide any memory barriers, which created potential issues on\n *       multi-core devices. We now define them as inlined calls to\n *       GCC sync builtins, which always provide a full barrier.\n *\n *       NOTE: The C library still exports atomic functions by the same\n *              name to ensure ABI stability for existing NDK machine code.\n *\n *       If you are an NDK developer, we encourage you to rebuild your\n *       unmodified sources against this header as soon as possible.\n */\n#define __ATOMIC_INLINE__ static __inline __attribute__((always_inline))\n\n__ATOMIC_INLINE__ int __atomic_cmpxchg(int old, int _new, volatile int *ptr) {\n  /* We must return 0 on success */\n  return __sync_val_compare_and_swap(ptr, old, _new) != old;\n}\n\n__ATOMIC_INLINE__ int __atomic_swap(int _new, volatile int *ptr) {\n  int prev;\n  do {\n    prev = *ptr;\n  } while (__sync_val_compare_and_swap(ptr, prev, _new) != prev);\n  return prev;\n}\n\n__ATOMIC_INLINE__ int __atomic_dec(volatile int *ptr) {\n  return __sync_fetch_and_sub(ptr, 1);\n}\n\n__ATOMIC_INLINE__ int __atomic_inc(volatile int *ptr) {\n  return __sync_fetch_and_add(ptr, 1);\n}\n\n__END_DECLS\n\n#endif /* _ANDROID_LEGACY_SYS_ATOMICS_INLINES_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/android/legacy_sys_stat_inlines.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _ANDROID_LEGACY_SYS_STAT_INLINES_H_\n#define _ANDROID_LEGACY_SYS_STAT_INLINES_H_\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\nstatic __inline int mkfifo(const char *__p, mode_t __m) {\n  return mknod(__p, (__m & ~S_IFMT) | S_IFIFO, (dev_t)0);\n}\n\n__END_DECLS\n\n#endif /* _ANDROID_LEGACY_SYS_STAT_INLINES_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/android/legacy_termios_inlines.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _ANDROID_LEGACY_TERMIOS_INLINES_H_\n#define _ANDROID_LEGACY_TERMIOS_INLINES_H_\n\n#include <linux/termios.h>\n#include <sys/cdefs.h>\n#include <sys/ioctl.h>\n#include <sys/types.h>\n\n__BEGIN_DECLS\n\nstatic __inline int tcgetattr(int fd, struct termios *s) {\n  return ioctl(fd, TCGETS, s);\n}\n\nstatic __inline int tcsetattr(int fd, int __opt, const struct termios *s) {\n  return ioctl(fd, __opt, (void *)s);\n}\n\nstatic __inline int tcflow(int fd, int action) {\n  return ioctl(fd, TCXONC, (void *)(intptr_t)action);\n}\n\nstatic __inline int tcflush(int fd, int __queue) {\n  return ioctl(fd, TCFLSH, (void *)(intptr_t)__queue);\n}\n\nstatic __inline pid_t tcgetsid(int fd) {\n  pid_t _pid;\n  return ioctl(fd, TIOCGSID, &_pid) ? (pid_t)-1 : _pid;\n}\n\nstatic __inline int tcsendbreak(int fd, int __duration) {\n  return ioctl(fd, TCSBRKP, (void *)(uintptr_t)__duration);\n}\n\nstatic __inline speed_t cfgetospeed(const struct termios *s) {\n  return (speed_t)(s->c_cflag & CBAUD);\n}\n\nstatic __inline int cfsetospeed(struct termios *s, speed_t speed) {\n  s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);\n  return 0;\n}\n\nstatic __inline speed_t cfgetispeed(const struct termios *s) {\n  return (speed_t)(s->c_cflag & CBAUD);\n}\n\nstatic __inline int cfsetispeed(struct termios *s, speed_t speed) {\n  s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);\n  return 0;\n}\n\nstatic __inline void cfmakeraw(struct termios *s) {\n  s->c_iflag &=\n      ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);\n  s->c_oflag &= ~OPOST;\n  s->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);\n  s->c_cflag &= ~(CSIZE | PARENB);\n  s->c_cflag |= CS8;\n}\n\n__END_DECLS\n\n#endif /* _ANDROID_LEGACY_TERMIOS_INLINES_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/android/set_abort_message.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SET_ABORT_MESSAGE_H\n#define _SET_ABORT_MESSAGE_H\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\nvoid android_set_abort_message(const char* msg);\n\n__END_DECLS\n\n#endif // _SET_ABORT_MESSAGE_H\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/ar.h",
    "content": "/*\t$OpenBSD: ar.h,v 1.3 2003/06/02 19:34:12 millert Exp $\t*/\n/*\t$NetBSD: ar.h,v 1.4 1994/10/26 00:55:43 cgd Exp $\t*/\n\n/*-\n * Copyright (c) 1991, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n * (c) UNIX System Laboratories, Inc.\n * All or some portions of this file are derived from material licensed\n * to the University of California by American Telephone and Telegraph\n * Co. or Unix System Laboratories, Inc. and are reproduced herein with\n * the permission of UNIX System Laboratories, Inc.\n *\n * This code is derived from software contributed to Berkeley by\n * Hugh Smith at The University of Guelph.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)ar.h\t8.2 (Berkeley) 1/21/94\n */\n\n#ifndef _AR_H_\n#define\t_AR_H_\n\n/* Pre-4BSD archives had these magic numbers in them. */\n#define\tOARMAG1\t0177555\n#define\tOARMAG2\t0177545\n\n#define\tARMAG\t\t\"!<arch>\\n\"\t/* ar \"magic number\" */\n#define\tSARMAG\t\t8\t\t/* strlen(ARMAG); */\n\n#define\tAR_EFMT1\t\"#1/\"\t\t/* extended format #1 */\n\nstruct ar_hdr {\n\tchar ar_name[16];\t\t/* name */\n\tchar ar_date[12];\t\t/* modification time */\n\tchar ar_uid[6];\t\t\t/* user id */\n\tchar ar_gid[6];\t\t\t/* group id */\n\tchar ar_mode[8];\t\t/* octal file permissions */\n\tchar ar_size[10];\t\t/* size in bytes */\n#define\tARFMAG\t\"`\\n\"\n\tchar ar_fmag[2];\t\t/* consistency check */\n};\n\n#endif /* !_AR_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/arpa/inet.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _ARPA_INET_H_\n#define _ARPA_INET_H_\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <netinet/in.h>\n\n__BEGIN_DECLS\n\nin_addr_t inet_addr(const char*);\nint inet_aton(const char*, struct in_addr*);\nin_addr_t inet_lnaof(struct in_addr);\nstruct in_addr inet_makeaddr(in_addr_t, in_addr_t);\nin_addr_t inet_netof(struct in_addr);\nin_addr_t inet_network(const char*);\nchar* inet_ntoa(struct in_addr);\nconst char* inet_ntop(int, const void*, char*, socklen_t);\nunsigned int inet_nsap_addr(const char*, unsigned char*, int);\nchar* inet_nsap_ntoa(int, const unsigned char*, char*);\nint inet_pton(int, const char*, void*);\n\n__END_DECLS\n\n#endif /* _ARPA_INET_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/arpa/nameser.h",
    "content": "/*\t$NetBSD: nameser.h,v 1.25 2009/04/12 17:07:34 christos Exp $\t*/\n\n/*\n * Portions Copyright (C) 2004, 2005, 2008, 2009  Internet Systems Consortium, Inc. (\"ISC\")\n * Portions Copyright (C) 1996-2003  Internet Software Consortium.\n *\n * Permission to use, copy, modify, and/or distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND ISC DISCLAIMS ALL WARRANTIES WITH\n * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,\n * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE\n * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n * PERFORMANCE OF THIS SOFTWARE.\n */\n\n/*\n * Copyright (c) 1983, 1989, 1993\n *    The Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*\n *\tId: nameser.h,v 1.16 2009/03/03 01:52:48 each Exp\n */\n\n#ifndef _ARPA_NAMESER_H_\n#define _ARPA_NAMESER_H_\n\n#define BIND_4_COMPAT\n\n#include <sys/types.h>\n#include <sys/cdefs.h>\n\n/*\n * Revision information.  This is the release date in YYYYMMDD format.\n * It can change every day so the right thing to do with it is use it\n * in preprocessor commands such as \"#if (__NAMESER > 19931104)\".  Do not\n * compare for equality; rather, use it to determine whether your libbind.a\n * contains a new enough lib/nameser/ to support the feature you need.\n */\n\n#define __NAMESER\t20090302\t/*%< New interface version stamp. */\n\n/*\n * Define constants based on RFC0883, RFC1034, RFC 1035\n */\n#define NS_PACKETSZ\t512\t/* default UDP packet size */\n#define NS_MAXDNAME\t1025\t/* maximum domain name (presentation format)*/\n#define NS_MAXMSG\t65535\t/* maximum message size */\n#define NS_MAXCDNAME\t255\t/* maximum compressed domain name */\n#define NS_MAXLABEL\t63\t/* maximum length of domain label */\n#define NS_MAXLABELS\t128\t/* theoretical max #/labels per domain name */\n#define NS_MAXNNAME\t256\t/* maximum uncompressed (binary) domain name*/\n#define\tNS_MAXPADDR\t(sizeof \"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff\")\n#define NS_HFIXEDSZ\t12\t/* #/bytes of fixed data in header */\n#define NS_QFIXEDSZ\t4\t/* #/bytes of fixed data in query */\n#define NS_RRFIXEDSZ\t10\t/* #/bytes of fixed data in r record */\n#define NS_INT32SZ\t4\t/* #/bytes of data in a uint32_t */\n#define NS_INT16SZ\t2\t/* #/bytes of data in a uint16_t */\n#define NS_INT8SZ\t1\t/* #/bytes of data in a uint8_t */\n#define NS_INADDRSZ\t4\t/* IPv4 T_A */\n#define NS_IN6ADDRSZ\t16\t/* IPv6 T_AAAA */\n#define NS_CMPRSFLGS\t0xc0\t/* Flag bits indicating name compression. */\n#define NS_DEFAULTPORT\t53\t/* For both TCP and UDP. */\n\n/*\n * These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord()\n * in synch with it.\n */\ntypedef enum __ns_sect {\n\tns_s_qd = 0,\t\t/* Query: Question. */\n\tns_s_zn = 0,\t\t/* Update: Zone. */\n\tns_s_an = 1,\t\t/* Query: Answer. */\n\tns_s_pr = 1,\t\t/* Update: Prerequisites. */\n\tns_s_ns = 2,\t\t/* Query: Name servers. */\n\tns_s_ud = 2,\t\t/* Update: Update. */\n\tns_s_ar = 3,\t\t/* Query|Update: Additional records. */\n\tns_s_max = 4\n} ns_sect;\n\n/*\n * Network name (compressed or not) type.  Equivilent to a pointer when used\n * in a function prototype.  Can be const'd.\n */\ntypedef u_char ns_nname[NS_MAXNNAME];\ntypedef const u_char *ns_nname_ct;\ntypedef u_char *ns_nname_t;\n\nstruct ns_namemap { ns_nname_ct base; int len; };\ntypedef struct ns_namemap *ns_namemap_t;\ntypedef const struct ns_namemap *ns_namemap_ct;\n\n/*\n * This is a message handle.  It is caller allocated and has no dynamic data.\n * This structure is intended to be opaque to all but ns_parse.c, thus the\n * leading _'s on the member names.  Use the accessor functions, not the _'s.\n */\ntypedef struct __ns_msg {\n\tconst u_char\t*_msg, *_eom;\n\tuint16_t\t_id, _flags, _counts[ns_s_max];\n\tconst u_char\t*_sections[ns_s_max];\n\tns_sect\t\t_sect;\n\tint\t\t_rrnum;\n\tconst u_char\t*_msg_ptr;\n} ns_msg;\n/*\n * This is a newmsg handle, used when constructing new messages with\n * ns_newmsg_init, et al.\n */\nstruct ns_newmsg {\n\tns_msg\t\tmsg;\n\tconst u_char\t*dnptrs[25];\n\tconst u_char\t**lastdnptr;\n};\ntypedef struct ns_newmsg ns_newmsg;\n\n/* Private data structure - do not use from outside library. */\nstruct _ns_flagdata {  int mask, shift;  };\nextern const struct _ns_flagdata _ns_flagdata[];\n\n/* Accessor macros - this is part of the public interface. */\n\n#define ns_msg_id(handle) ((handle)._id + 0)\n#define ns_msg_base(handle) ((handle)._msg + 0)\n#define ns_msg_end(handle) ((handle)._eom + 0)\n#define ns_msg_size(handle) ((size_t)((handle)._eom - (handle)._msg))\n#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)\n\n/*\n * This is a parsed record.  It is caller allocated and has no dynamic data.\n */\ntypedef\tstruct __ns_rr {\n\tchar\t\tname[NS_MAXDNAME];\n\tuint16_t\ttype;\n\tuint16_t\trr_class;\n\tuint32_t\tttl;\n\tuint16_t\trdlength;\n\tconst u_char *\trdata;\n} ns_rr;\n\n/*\n * Same thing, but using uncompressed network binary names, and real C types.\n */\ntypedef\tstruct __ns_rr2 {\n\tns_nname\tnname;\n\tsize_t\t\tnnamel;\n\tint\t\ttype;\n\tint\t\trr_class;\n\tu_int\t\tttl;\n\tint\t\trdlength;\n\tconst u_char *\trdata;\n} ns_rr2;\n/* Accessor macros - this is part of the public interface. */\n#define ns_rr_name(rr)\t(((rr).name[0] != '\\0') ? (rr).name : \".\")\n#define ns_rr_nname(rr)\t((const ns_nname_t)(rr).nname)\n#define ns_rr_nnamel(rr) ((rr).nnamel + 0)\n#define ns_rr_type(rr)\t((ns_type)((rr).type + 0))\n#define ns_rr_class(rr)\t((ns_class)((rr).rr_class + 0))\n#define ns_rr_ttl(rr)\t((u_long)(rr).ttl + 0)\n#define ns_rr_rdlen(rr)\t((size_t)(rr).rdlength + 0)\n#define ns_rr_rdata(rr)\t((rr).rdata + 0)\n\n/*\n * These don't have to be in the same order as in the packet flags word,\n * and they can even overlap in some cases, but they will need to be kept\n * in synch with ns_parse.c:ns_flagdata[].\n */\ntypedef enum __ns_flag {\n\tns_f_qr,\t\t/* Question/Response. */\n\tns_f_opcode,\t\t/* Operation code. */\n\tns_f_aa,\t\t/* Authoritative Answer. */\n\tns_f_tc,\t\t/* Truncation occurred. */\n\tns_f_rd,\t\t/* Recursion Desired. */\n\tns_f_ra,\t\t/* Recursion Available. */\n\tns_f_z,\t\t\t/* MBZ. */\n\tns_f_ad,\t\t/* Authentic Data (DNSSEC). */\n\tns_f_cd,\t\t/* Checking Disabled (DNSSEC). */\n\tns_f_rcode,\t\t/* Response code. */\n\tns_f_max\n} ns_flag;\n\n/*\n * Currently defined opcodes.\n */\ntypedef enum __ns_opcode {\n\tns_o_query = 0,\t\t/* Standard query. */\n\tns_o_iquery = 1,\t/* Inverse query (deprecated/unsupported). */\n\tns_o_status = 2,\t/* Name server status query (unsupported). */\n\t\t\t\t/* Opcode 3 is undefined/reserved. */\n\tns_o_notify = 4,\t/* Zone change notification. */\n\tns_o_update = 5,\t/* Zone update message. */\n\tns_o_max = 6\n} ns_opcode;\n\n/*\n * Currently defined response codes.\n */\ntypedef\tenum __ns_rcode {\n\tns_r_noerror = 0,\t/* No error occurred. */\n\tns_r_formerr = 1,\t/* Format error. */\n\tns_r_servfail = 2,\t/* Server failure. */\n\tns_r_nxdomain = 3,\t/* Name error. */\n\tns_r_notimpl = 4,\t/* Unimplemented. */\n\tns_r_refused = 5,\t/* Operation refused. */\n\t/* these are for BIND_UPDATE */\n\tns_r_yxdomain = 6,\t/* Name exists */\n\tns_r_yxrrset = 7,\t/* RRset exists */\n\tns_r_nxrrset = 8,\t/* RRset does not exist */\n\tns_r_notauth = 9,\t/* Not authoritative for zone */\n\tns_r_notzone = 10,\t/* Zone of record different from zone section */\n\tns_r_max = 11,\n\t/* The following are EDNS extended rcodes */\n\tns_r_badvers = 16,\n\t/* The following are TSIG errors */\n\tns_r_badsig = 16,\n\tns_r_badkey = 17,\n\tns_r_badtime = 18\n} ns_rcode;\n\n/* BIND_UPDATE */\ntypedef enum __ns_update_operation {\n\tns_uop_delete = 0,\n\tns_uop_add = 1,\n\tns_uop_max = 2\n} ns_update_operation;\n\n/*\n * This structure is used for TSIG authenticated messages\n */\nstruct ns_tsig_key {\n        char name[NS_MAXDNAME], alg[NS_MAXDNAME];\n        unsigned char *data;\n        int len;\n};\ntypedef struct ns_tsig_key ns_tsig_key;\n\n/*\n * This structure is used for TSIG authenticated TCP messages\n */\nstruct ns_tcp_tsig_state {\n\tint counter;\n\tstruct dst_key *key;\n\tvoid *ctx;\n\tunsigned char sig[NS_PACKETSZ];\n\tint siglen;\n};\ntypedef struct ns_tcp_tsig_state ns_tcp_tsig_state;\n\n#define NS_TSIG_FUDGE 300\n#define NS_TSIG_TCP_COUNT 100\n#define NS_TSIG_ALG_HMAC_MD5 \"HMAC-MD5.SIG-ALG.REG.INT\"\n\n#define NS_TSIG_ERROR_NO_TSIG -10\n#define NS_TSIG_ERROR_NO_SPACE -11\n#define NS_TSIG_ERROR_FORMERR -12\n\n/*\n * Currently defined type values for resources and queries.\n */\ntypedef enum __ns_type {\n\tns_t_invalid = 0,\t/* Cookie. */\n\tns_t_a = 1,\t\t/* Host address. */\n\tns_t_ns = 2,\t\t/* Authoritative server. */\n\tns_t_md = 3,\t\t/* Mail destination. */\n\tns_t_mf = 4,\t\t/* Mail forwarder. */\n\tns_t_cname = 5,\t\t/* Canonical name. */\n\tns_t_soa = 6,\t\t/* Start of authority zone. */\n\tns_t_mb = 7,\t\t/* Mailbox domain name. */\n\tns_t_mg = 8,\t\t/* Mail group member. */\n\tns_t_mr = 9,\t\t/* Mail rename name. */\n\tns_t_null = 10,\t\t/* Null resource record. */\n\tns_t_wks = 11,\t\t/* Well known service. */\n\tns_t_ptr = 12,\t\t/* Domain name pointer. */\n\tns_t_hinfo = 13,\t/* Host information. */\n\tns_t_minfo = 14,\t/* Mailbox information. */\n\tns_t_mx = 15,\t\t/* Mail routing information. */\n\tns_t_txt = 16,\t\t/* Text strings. */\n\tns_t_rp = 17,\t\t/* Responsible person. */\n\tns_t_afsdb = 18,\t/* AFS cell database. */\n\tns_t_x25 = 19,\t\t/* X_25 calling address. */\n\tns_t_isdn = 20,\t\t/* ISDN calling address. */\n\tns_t_rt = 21,\t\t/* Router. */\n\tns_t_nsap = 22,\t\t/* NSAP address. */\n\tns_t_nsap_ptr = 23,\t/* Reverse NSAP lookup (deprecated). */\n\tns_t_sig = 24,\t\t/* Security signature. */\n\tns_t_key = 25,\t\t/* Security key. */\n\tns_t_px = 26,\t\t/* X.400 mail mapping. */\n\tns_t_gpos = 27,\t\t/* Geographical position (withdrawn). */\n\tns_t_aaaa = 28,\t\t/* IPv6 Address. */\n\tns_t_loc = 29,\t\t/* Location Information. */\n\tns_t_nxt = 30,\t\t/* Next domain (security). */\n\tns_t_eid = 31,\t\t/* Endpoint identifier. */\n\tns_t_nimloc = 32,\t/* Nimrod Locator. */\n\tns_t_srv = 33,\t\t/* Server Selection. */\n\tns_t_atma = 34,\t\t/* ATM Address */\n\tns_t_naptr = 35,\t/* Naming Authority PoinTeR */\n\tns_t_kx = 36,\t\t/* Key Exchange */\n\tns_t_cert = 37,\t\t/* Certification record */\n\tns_t_a6 = 38,\t\t/* IPv6 address (experimental) */\n\tns_t_dname = 39,\t/* Non-terminal DNAME */\n\tns_t_sink = 40,\t\t/* Kitchen sink (experimentatl) */\n\tns_t_opt = 41,\t\t/* EDNS0 option (meta-RR) */\n\tns_t_apl = 42,\t\t/* Address prefix list (RFC 3123) */\n\tns_t_ds = 43,\t\t/* Delegation Signer */\n\tns_t_sshfp = 44,\t/* SSH Fingerprint */\n\tns_t_ipseckey = 45,\t/* IPSEC Key */\n\tns_t_rrsig = 46,\t/* RRset Signature */\n\tns_t_nsec = 47,\t\t/* Negative security */\n\tns_t_dnskey = 48,\t/* DNS Key */\n\tns_t_dhcid = 49,\t/* Dynamic host configuratin identifier */\n\tns_t_nsec3 = 50,\t/* Negative security type 3 */\n\tns_t_nsec3param = 51,\t/* Negative security type 3 parameters */\n\tns_t_hip = 55,\t\t/* Host Identity Protocol */\n\tns_t_spf = 99,\t\t/* Sender Policy Framework */\n\tns_t_tkey = 249,\t/* Transaction key */\n\tns_t_tsig = 250,\t/* Transaction signature. */\n\tns_t_ixfr = 251,\t/* Incremental zone transfer. */\n\tns_t_axfr = 252,\t/* Transfer zone of authority. */\n\tns_t_mailb = 253,\t/* Transfer mailbox records. */\n\tns_t_maila = 254,\t/* Transfer mail agent records. */\n\tns_t_any = 255,\t\t/* Wildcard match. */\n\tns_t_zxfr = 256,\t/* BIND-specific, nonstandard. */\n\tns_t_dlv = 32769,\t/* DNSSEC look-aside validatation. */\n\tns_t_max = 65536\n} ns_type;\n\n/* Exclusively a QTYPE? (not also an RTYPE) */\n#define\tns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \\\n\t\t      (t) == ns_t_mailb || (t) == ns_t_maila)\n/* Some kind of meta-RR? (not a QTYPE, but also not an RTYPE) */\n#define\tns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)\n/* Exclusively an RTYPE? (not also a QTYPE or a meta-RR) */\n#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))\n#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)\n#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \\\n\t\t       (t) == ns_t_zxfr)\n\n/*\n * Values for class field\n */\ntypedef enum __ns_class {\n\tns_c_invalid = 0,\t/* Cookie. */\n\tns_c_in = 1,\t\t/* Internet. */\n\tns_c_2 = 2,\t\t/* unallocated/unsupported. */\n\tns_c_chaos = 3,\t\t/* MIT Chaos-net. */\n\tns_c_hs = 4,\t\t/* MIT Hesiod. */\n\t/* Query class values which do not appear in resource records */\n\tns_c_none = 254,\t/* for prereq. sections in update requests */\n\tns_c_any = 255,\t\t/* Wildcard match. */\n\tns_c_max = 65536\n} ns_class;\n\n/* DNSSEC constants. */\n\ntypedef enum __ns_key_types {\n\tns_kt_rsa = 1,\t\t/* key type RSA/MD5 */\n\tns_kt_dh  = 2,\t\t/* Diffie Hellman */\n\tns_kt_dsa = 3,\t\t/* Digital Signature Standard (MANDATORY) */\n\tns_kt_private = 254\t/* Private key type starts with OID */\n} ns_key_types;\n\ntypedef enum __ns_cert_types {\n\tcert_t_pkix = 1,\t/* PKIX (X.509v3) */\n\tcert_t_spki = 2,\t/* SPKI */\n\tcert_t_pgp  = 3,\t/* PGP */\n\tcert_t_url  = 253,\t/* URL private type */\n\tcert_t_oid  = 254\t/* OID private type */\n} ns_cert_types;\n\n/* Flags field of the KEY RR rdata. */\n#define\tNS_KEY_TYPEMASK\t\t0xC000\t/* Mask for \"type\" bits */\n#define\tNS_KEY_TYPE_AUTH_CONF\t0x0000\t/* Key usable for both */\n#define\tNS_KEY_TYPE_CONF_ONLY\t0x8000\t/* Key usable for confidentiality */\n#define\tNS_KEY_TYPE_AUTH_ONLY\t0x4000\t/* Key usable for authentication */\n#define\tNS_KEY_TYPE_NO_KEY\t0xC000\t/* No key usable for either; no key */\n/* The type bits can also be interpreted independently, as single bits: */\n#define\tNS_KEY_NO_AUTH\t\t0x8000\t/* Key unusable for authentication */\n#define\tNS_KEY_NO_CONF\t\t0x4000\t/* Key unusable for confidentiality */\n#define\tNS_KEY_RESERVED2\t0x2000\t/* Security is *mandatory* if bit=0 */\n#define\tNS_KEY_EXTENDED_FLAGS\t0x1000\t/* reserved - must be zero */\n#define\tNS_KEY_RESERVED4\t0x0800  /* reserved - must be zero */\n#define\tNS_KEY_RESERVED5\t0x0400  /* reserved - must be zero */\n#define\tNS_KEY_NAME_TYPE\t0x0300\t/* these bits determine the type */\n#define\tNS_KEY_NAME_USER\t0x0000\t/* key is assoc. with user */\n#define\tNS_KEY_NAME_ENTITY\t0x0200\t/* key is assoc. with entity eg host */\n#define\tNS_KEY_NAME_ZONE\t0x0100\t/* key is zone key */\n#define\tNS_KEY_NAME_RESERVED\t0x0300\t/* reserved meaning */\n#define\tNS_KEY_RESERVED8\t0x0080  /* reserved - must be zero */\n#define\tNS_KEY_RESERVED9\t0x0040  /* reserved - must be zero */\n#define\tNS_KEY_RESERVED10\t0x0020  /* reserved - must be zero */\n#define\tNS_KEY_RESERVED11\t0x0010  /* reserved - must be zero */\n#define\tNS_KEY_SIGNATORYMASK\t0x000F\t/* key can sign RR's of same name */\n#define\tNS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \\\n\t\t\t\t  NS_KEY_RESERVED4 | \\\n\t\t\t\t  NS_KEY_RESERVED5 | \\\n\t\t\t\t  NS_KEY_RESERVED8 | \\\n\t\t\t\t  NS_KEY_RESERVED9 | \\\n\t\t\t\t  NS_KEY_RESERVED10 | \\\n\t\t\t\t  NS_KEY_RESERVED11 )\n#define NS_KEY_RESERVED_BITMASK2 0xFFFF /* no bits defined here */\n\n/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */\n#define\tNS_ALG_MD5RSA\t\t1\t/* MD5 with RSA */\n#define\tNS_ALG_DH               2\t/* Diffie Hellman KEY */\n#define\tNS_ALG_DSA              3\t/* DSA KEY */\n#define\tNS_ALG_DSS              NS_ALG_DSA\n#define\tNS_ALG_EXPIRE_ONLY\t253\t/* No alg, no security */\n#define\tNS_ALG_PRIVATE_OID\t254\t/* Key begins with OID giving alg */\n\n/* Protocol values  */\n/* value 0 is reserved */\n#define NS_KEY_PROT_TLS         1\n#define NS_KEY_PROT_EMAIL       2\n#define NS_KEY_PROT_DNSSEC      3\n#define NS_KEY_PROT_IPSEC       4\n#define NS_KEY_PROT_ANY\t\t255\n\n/* Signatures */\n#define\tNS_MD5RSA_MIN_BITS\t 512\t/* Size of a mod or exp in bits */\n#define\tNS_MD5RSA_MAX_BITS\t4096\n\t/* Total of binary mod and exp */\n#define\tNS_MD5RSA_MAX_BYTES\t((NS_MD5RSA_MAX_BITS+7/8)*2+3)\n\t/* Max length of text sig block */\n#define\tNS_MD5RSA_MAX_BASE64\t(((NS_MD5RSA_MAX_BYTES+2)/3)*4)\n#define NS_MD5RSA_MIN_SIZE\t((NS_MD5RSA_MIN_BITS+7)/8)\n#define NS_MD5RSA_MAX_SIZE\t((NS_MD5RSA_MAX_BITS+7)/8)\n\n#define NS_DSA_SIG_SIZE         41\n#define NS_DSA_MIN_SIZE         213\n#define NS_DSA_MAX_BYTES        405\n\n/* Offsets into SIG record rdata to find various values */\n#define\tNS_SIG_TYPE\t0\t/* Type flags */\n#define\tNS_SIG_ALG\t2\t/* Algorithm */\n#define\tNS_SIG_LABELS\t3\t/* How many labels in name */\n#define\tNS_SIG_OTTL\t4\t/* Original TTL */\n#define\tNS_SIG_EXPIR\t8\t/* Expiration time */\n#define\tNS_SIG_SIGNED\t12\t/* Signature time */\n#define\tNS_SIG_FOOT\t16\t/* Key footprint */\n#define\tNS_SIG_SIGNER\t18\t/* Domain name of who signed it */\n\n/* How RR types are represented as bit-flags in NXT records */\n#define\tNS_NXT_BITS 8\n#define\tNS_NXT_BIT_SET(  n,p) (p[(n)/NS_NXT_BITS] |=  (0x80>>((n)%NS_NXT_BITS)))\n#define\tNS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))\n#define\tNS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] &   (0x80>>((n)%NS_NXT_BITS)))\n#define NS_NXT_MAX 127\n\n/*\n * EDNS0 extended flags and option codes, host order.\n */\n#define NS_OPT_DNSSEC_OK\t0x8000U\n#define NS_OPT_NSID             3\n\n/*\n * Inline versions of get/put short/long.  Pointer is advanced.\n */\n#define NS_GET16(s, cp) do { \\\n\tconst u_char *t_cp = (const u_char *)(cp); \\\n\t(s) = ((uint16_t)t_cp[0] << 8) \\\n\t    | ((uint16_t)t_cp[1]) \\\n\t    ; \\\n\t(cp) += NS_INT16SZ; \\\n} while (/*CONSTCOND*/0)\n\n#define NS_GET32(l, cp) do { \\\n\tconst u_char *t_cp = (const u_char *)(cp); \\\n\t(l) = ((uint32_t)t_cp[0] << 24) \\\n\t    | ((uint32_t)t_cp[1] << 16) \\\n\t    | ((uint32_t)t_cp[2] << 8) \\\n\t    | ((uint32_t)t_cp[3]) \\\n\t    ; \\\n\t(cp) += NS_INT32SZ; \\\n} while (/*CONSTCOND*/0)\n\n#define NS_PUT16(s, cp) do { \\\n\tuint32_t t_s = (uint32_t)(s); \\\n\tu_char *t_cp = (u_char *)(cp); \\\n\t*t_cp++ = t_s >> 8; \\\n\t*t_cp   = t_s; \\\n\t(cp) += NS_INT16SZ; \\\n} while (/*CONSTCOND*/0)\n\n#define NS_PUT32(l, cp) do { \\\n\tuint32_t t_l = (uint32_t)(l); \\\n\tu_char *t_cp = (u_char *)(cp); \\\n\t*t_cp++ = t_l >> 24; \\\n\t*t_cp++ = t_l >> 16; \\\n\t*t_cp++ = t_l >> 8; \\\n\t*t_cp   = t_l; \\\n\t(cp) += NS_INT32SZ; \\\n} while (/*CONSTCOND*/0)\n\n#if !defined(__LP64__)\n/* Annoyingly, LP32 shipped with __ names. */\n#define\tns_msg_getflag\t\t__ns_msg_getflag\n#define ns_get16\t\t__ns_get16\n#define ns_get32\t\t__ns_get32\n#define ns_put16\t\t__ns_put16\n#define ns_put32\t\t__ns_put32\n#define ns_initparse\t\t__ns_initparse\n#define ns_skiprr\t\t__ns_skiprr\n#define ns_parserr\t\t__ns_parserr\n#define ns_parserr2\t\t__ns_parserr2\n#define\tns_sprintrr\t\t__ns_sprintrr\n#define\tns_sprintrrf\t\t__ns_sprintrrf\n#define\tns_format_ttl\t\t__ns_format_ttl\n#define\tns_parse_ttl\t\t__ns_parse_ttl\n#define ns_datetosecs\t\t__ns_datetosecs\n#define\tns_name_ntol\t\t__ns_name_ntol\n#define\tns_name_ntop\t\t__ns_name_ntop\n#define\tns_name_pton\t\t__ns_name_pton\n#define\tns_name_pton2\t\t__ns_name_pton2\n#define\tns_name_unpack\t\t__ns_name_unpack\n#define\tns_name_unpack2\t\t__ns_name_unpack2\n#define\tns_name_pack\t\t__ns_name_pack\n#define\tns_name_compress\t__ns_name_compress\n#define\tns_name_uncompress\t__ns_name_uncompress\n#define\tns_name_skip\t\t__ns_name_skip\n#define\tns_name_rollback\t__ns_name_rollback\n#define\tns_name_length\t\t__ns_name_length\n#define\tns_name_eq\t\t__ns_name_eq\n#define\tns_name_owned\t\t__ns_name_owned\n#define\tns_name_map\t\t__ns_name_map\n#define\tns_name_labels\t\t__ns_name_labels\n#define\tns_sign\t\t\t__ns_sign\n#define\tns_sign2\t\t__ns_sign2\n#define\tns_sign_tcp\t\t__ns_sign_tcp\n#define\tns_sign_tcp2\t\t__ns_sign_tcp2\n#define\tns_sign_tcp_init\t__ns_sign_tcp_init\n#define ns_find_tsig\t\t__ns_find_tsig\n#define\tns_verify\t\t__ns_verify\n#define\tns_verify_tcp\t\t__ns_verify_tcp\n#define\tns_verify_tcp_init\t__ns_verify_tcp_init\n#define\tns_samedomain\t\t__ns_samedomain\n#define\tns_subdomain\t\t__ns_subdomain\n#define\tns_makecanon\t\t__ns_makecanon\n#define\tns_samename\t\t__ns_samename\n#endif\n\n__BEGIN_DECLS\nint\t\tns_msg_getflag(ns_msg, int) __LIBC_ABI_PUBLIC__;\nuint16_t\tns_get16(const u_char *) __LIBC_ABI_PUBLIC__;\nuint32_t\tns_get32(const u_char *) __LIBC_ABI_PUBLIC__;\nvoid\t\tns_put16(uint16_t, u_char *) __LIBC_ABI_PUBLIC__;\nvoid\t\tns_put32(uint32_t, u_char *) __LIBC_ABI_PUBLIC__;\nint\t\tns_initparse(const u_char *, int, ns_msg *) __LIBC_ABI_PUBLIC__;\nint\t\tns_skiprr(const u_char *, const u_char *, ns_sect, int) __LIBC_ABI_PUBLIC__;\nint\t\tns_parserr(ns_msg *, ns_sect, int, ns_rr *) __LIBC_ABI_PUBLIC__;\nint\t\tns_parserr2(ns_msg *, ns_sect, int, ns_rr2 *) __LIBC_HIDDEN__;\nint\t\tns_sprintrr(const ns_msg *, const ns_rr *,\n\t\t\t\t const char *, const char *, char *, size_t) __LIBC_ABI_PUBLIC__;\nint\t\tns_sprintrrf(const u_char *, size_t, const char *,\n\t\t\t\t  ns_class, ns_type, u_long, const u_char *,\n\t\t\t\t  size_t, const char *, const char *,\n\t\t\t\t  char *, size_t) __LIBC_ABI_PUBLIC__;\nint\t\tns_format_ttl(u_long, char *, size_t) __LIBC_ABI_PUBLIC__;\nint\t\tns_parse_ttl(const char *, u_long *) __LIBC_ABI_PUBLIC__;\nuint32_t\tns_datetosecs(const char *cp, int *errp) __LIBC_ABI_PUBLIC__;\nint\t\tns_name_ntol(const u_char *, u_char *, size_t) __LIBC_ABI_PUBLIC__;\nint\t\tns_name_ntop(const u_char *, char *, size_t) __LIBC_ABI_PUBLIC__;\nint\t\tns_name_pton(const char *, u_char *, size_t) __LIBC_ABI_PUBLIC__;\nint\t\tns_name_pton2(const char *, u_char *, size_t, size_t *) __LIBC_HIDDEN__;\nint\t\tns_name_unpack(const u_char *, const u_char *,\n\t\t\t\t    const u_char *, u_char *, size_t) __LIBC_ABI_PUBLIC__;\nint\t\tns_name_unpack2(const u_char *, const u_char *,\n\t\t\t\t     const u_char *, u_char *, size_t,\n\t\t\t\t     size_t *) __LIBC_HIDDEN__;\nint\t\tns_name_pack(const u_char *, u_char *, int,\n\t\t\t\t  const u_char **, const u_char **) __LIBC_ABI_PUBLIC__;\nint\t\tns_name_uncompress(const u_char *, const u_char *,\n\t\t\t\t\tconst u_char *, char *, size_t) __LIBC_ABI_PUBLIC__;\nint\t\tns_name_compress(const char *, u_char *, size_t,\n\t\t\t\t      const u_char **, const u_char **) __LIBC_ABI_PUBLIC__;\nint\t\tns_name_skip(const u_char **, const u_char *) __LIBC_ABI_PUBLIC__;\nvoid\t\tns_name_rollback(const u_char *, const u_char **,\n\t\t\t\t      const u_char **) __LIBC_ABI_PUBLIC__;\nint\t\tns_sign(u_char *, int *, int, int, void *,\n\t\t\t     const u_char *, int, u_char *, int *, time_t) __LIBC_ABI_PUBLIC__;\nint\t\tns_sign2(u_char *, int *, int, int, void *,\n\t\t\t      const u_char *, int, u_char *, int *, time_t,\n\t\t\t      u_char **, u_char **) __LIBC_ABI_PUBLIC__;\nssize_t\t\tns_name_length(ns_nname_ct, size_t) __LIBC_HIDDEN__;\nint\t\tns_name_eq(ns_nname_ct, size_t, ns_nname_ct, size_t) __LIBC_HIDDEN__;\nint\t\tns_name_owned(ns_namemap_ct, int, ns_namemap_ct, int) __LIBC_HIDDEN__;\nint\t\tns_name_map(ns_nname_ct, size_t, ns_namemap_t, int) __LIBC_HIDDEN__;\nint\t\tns_name_labels(ns_nname_ct, size_t) __LIBC_HIDDEN__;\nint\t\tns_sign_tcp(u_char *, int *, int, int,\n\t\t\t\t ns_tcp_tsig_state *, int) __LIBC_ABI_PUBLIC__;\nint\t\tns_sign_tcp2(u_char *, int *, int, int,\n\t\t\t\t  ns_tcp_tsig_state *, int,\n\t\t\t\t  u_char **, u_char **) __LIBC_ABI_PUBLIC__;\nint\t\tns_sign_tcp_init(void *, const u_char *, int,\n\t\t\t\t\tns_tcp_tsig_state *) __LIBC_ABI_PUBLIC__;\nu_char\t\t*ns_find_tsig(u_char *, u_char *) __LIBC_ABI_PUBLIC__;\nint\t\tns_verify(u_char *, int *, void *,\n\t\t\t       const u_char *, int, u_char *, int *,\n\t\t\t       time_t *, int) __LIBC_ABI_PUBLIC__;\nint\t\tns_verify_tcp(u_char *, int *, ns_tcp_tsig_state *, int);\nint\t\tns_verify_tcp_init(void *, const u_char *, int,\n\t\t\t\t\tns_tcp_tsig_state *) __LIBC_ABI_PUBLIC__;\nint\t\tns_samedomain(const char *, const char *) __LIBC_ABI_PUBLIC__;\nint\t\tns_subdomain(const char *, const char *) __LIBC_ABI_PUBLIC__;\nint\t\tns_makecanon(const char *, char *, size_t) __LIBC_ABI_PUBLIC__;\nint\t\tns_samename(const char *, const char *) __LIBC_ABI_PUBLIC__;\n__END_DECLS\n\n#ifdef BIND_4_COMPAT\n#include <arpa/nameser_compat.h>\n#endif\n\n#endif /* !_ARPA_NAMESER_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/arpa/nameser_compat.h",
    "content": "/*\t$NetBSD: nameser_compat.h,v 1.1.1.2 2004/11/07 01:28:27 christos Exp $\t*/\n\n/* Copyright (c) 1983, 1989\n *    The Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. All advertising materials mentioning features or use of this software\n *    must display the following acknowledgement:\n * \tThis product includes software developed by the University of\n * \tCalifornia, Berkeley and its contributors.\n * 4. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*\n *      from nameser.h\t8.1 (Berkeley) 6/2/93\n *\tId: nameser_compat.h,v 1.8 2006/05/19 02:33:40 marka Exp\n */\n\n#ifndef _ARPA_NAMESER_COMPAT_\n#define\t_ARPA_NAMESER_COMPAT_\n\n#define\t__BIND\t\t19950621\t/* (DEAD) interface version stamp. */\n\n#include <endian.h>\n\n/*\n * Structure for query header.  The order of the fields is machine- and\n * compiler-dependent, depending on the byte/bit order and the layout\n * of bit fields.  We use bit fields only in int variables, as this\n * is all ANSI requires.  This requires a somewhat confusing rearrangement.\n */\n\ntypedef struct {\n\tunsigned\tid :16;\t\t/* query identification number */\n#if BYTE_ORDER == BIG_ENDIAN\n\t\t\t/* fields in third byte */\n\tunsigned\tqr: 1;\t\t/* response flag */\n\tunsigned\topcode: 4;\t/* purpose of message */\n\tunsigned\taa: 1;\t\t/* authoritive answer */\n\tunsigned\ttc: 1;\t\t/* truncated message */\n\tunsigned\trd: 1;\t\t/* recursion desired */\n\t\t\t/* fields in fourth byte */\n\tunsigned\tra: 1;\t\t/* recursion available */\n\tunsigned\tunused :1;\t/* unused bits (MBZ as of 4.9.3a3) */\n\tunsigned\tad: 1;\t\t/* authentic data from named */\n\tunsigned\tcd: 1;\t\t/* checking disabled by resolver */\n\tunsigned\trcode :4;\t/* response code */\n#endif\n#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN\n\t\t\t/* fields in third byte */\n\tunsigned\trd :1;\t\t/* recursion desired */\n\tunsigned\ttc :1;\t\t/* truncated message */\n\tunsigned\taa :1;\t\t/* authoritive answer */\n\tunsigned\topcode :4;\t/* purpose of message */\n\tunsigned\tqr :1;\t\t/* response flag */\n\t\t\t/* fields in fourth byte */\n\tunsigned\trcode :4;\t/* response code */\n\tunsigned\tcd: 1;\t\t/* checking disabled by resolver */\n\tunsigned\tad: 1;\t\t/* authentic data from named */\n\tunsigned\tunused :1;\t/* unused bits (MBZ as of 4.9.3a3) */\n\tunsigned\tra :1;\t\t/* recursion available */\n#endif\n\t\t\t/* remaining bytes */\n\tunsigned\tqdcount :16;\t/* number of question entries */\n\tunsigned\tancount :16;\t/* number of answer entries */\n\tunsigned\tnscount :16;\t/* number of authority entries */\n\tunsigned\tarcount :16;\t/* number of resource entries */\n} HEADER;\n\n#define PACKETSZ\tNS_PACKETSZ\n#define MAXDNAME\tNS_MAXDNAME\n#define MAXCDNAME\tNS_MAXCDNAME\n#define MAXLABEL\tNS_MAXLABEL\n#define\tHFIXEDSZ\tNS_HFIXEDSZ\n#define QFIXEDSZ\tNS_QFIXEDSZ\n#define RRFIXEDSZ\tNS_RRFIXEDSZ\n#define\tINT32SZ\t\tNS_INT32SZ\n#define\tINT16SZ\t\tNS_INT16SZ\n#define\tINT8SZ\t\tNS_INT8SZ\n#define\tINADDRSZ\tNS_INADDRSZ\n#define\tIN6ADDRSZ\tNS_IN6ADDRSZ\n#define\tINDIR_MASK\tNS_CMPRSFLGS\n#define NAMESERVER_PORT\tNS_DEFAULTPORT\n\n#define S_ZONE\t\tns_s_zn\n#define S_PREREQ\tns_s_pr\n#define S_UPDATE\tns_s_ud\n#define S_ADDT\t\tns_s_ar\n\n#define QUERY\t\tns_o_query\n#define IQUERY\t\tns_o_iquery\n#define STATUS\t\tns_o_status\n#define\tNS_NOTIFY_OP\tns_o_notify\n#define\tNS_UPDATE_OP\tns_o_update\n\n#define NOERROR\t\tns_r_noerror\n#define FORMERR\t\tns_r_formerr\n#define SERVFAIL\tns_r_servfail\n#define NXDOMAIN\tns_r_nxdomain\n#define NOTIMP\t\tns_r_notimpl\n#define REFUSED\t\tns_r_refused\n#define YXDOMAIN\tns_r_yxdomain\n#define YXRRSET\t\tns_r_yxrrset\n#define NXRRSET\t\tns_r_nxrrset\n#define NOTAUTH\t\tns_r_notauth\n#define NOTZONE\t\tns_r_notzone\n/*#define BADSIG\t\tns_r_badsig*/\n/*#define BADKEY\t\tns_r_badkey*/\n/*#define BADTIME\t\tns_r_badtime*/\n\n\n#define DELETE\t\tns_uop_delete\n#define ADD\t\tns_uop_add\n\n#define T_A\t\tns_t_a\n#define T_NS\t\tns_t_ns\n#define T_MD\t\tns_t_md\n#define T_MF\t\tns_t_mf\n#define T_CNAME\t\tns_t_cname\n#define T_SOA\t\tns_t_soa\n#define T_MB\t\tns_t_mb\n#define T_MG\t\tns_t_mg\n#define T_MR\t\tns_t_mr\n#define T_NULL\t\tns_t_null\n#define T_WKS\t\tns_t_wks\n#define T_PTR\t\tns_t_ptr\n#define T_HINFO\t\tns_t_hinfo\n#define T_MINFO\t\tns_t_minfo\n#define T_MX\t\tns_t_mx\n#define T_TXT\t\tns_t_txt\n#define\tT_RP\t\tns_t_rp\n#define T_AFSDB\t\tns_t_afsdb\n#define T_X25\t\tns_t_x25\n#define T_ISDN\t\tns_t_isdn\n#define T_RT\t\tns_t_rt\n#define T_NSAP\t\tns_t_nsap\n#define T_NSAP_PTR\tns_t_nsap_ptr\n#define\tT_SIG\t\tns_t_sig\n#define\tT_KEY\t\tns_t_key\n#define\tT_PX\t\tns_t_px\n#define\tT_GPOS\t\tns_t_gpos\n#define\tT_AAAA\t\tns_t_aaaa\n#define\tT_LOC\t\tns_t_loc\n#define\tT_NXT\t\tns_t_nxt\n#define\tT_EID\t\tns_t_eid\n#define\tT_NIMLOC\tns_t_nimloc\n#define\tT_SRV\t\tns_t_srv\n#define T_ATMA\t\tns_t_atma\n#define T_NAPTR\t\tns_t_naptr\n#define T_A6\t\tns_t_a6\n#define\tT_TSIG\t\tns_t_tsig\n#define\tT_IXFR\t\tns_t_ixfr\n#define T_AXFR\t\tns_t_axfr\n#define T_MAILB\t\tns_t_mailb\n#define T_MAILA\t\tns_t_maila\n#define T_ANY\t\tns_t_any\n\n#define C_IN\t\tns_c_in\n#define C_CHAOS\t\tns_c_chaos\n#define C_HS\t\tns_c_hs\n/* BIND_UPDATE */\n#define C_NONE\t\tns_c_none\n#define C_ANY\t\tns_c_any\n\n#define\tGETSHORT\t\tNS_GET16\n#define\tGETLONG\t\t\tNS_GET32\n#define\tPUTSHORT\t\tNS_PUT16\n#define\tPUTLONG\t\t\tNS_PUT32\n\n#endif /* _ARPA_NAMESER_COMPAT_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/arpa/telnet.h",
    "content": "/*\n * Copyright (c) 1983, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 4. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)telnet.h\t8.2 (Berkeley) 12/15/93\n */\n\n#ifndef _ARPA_TELNET_H\n#define\t_ARPA_TELNET_H 1\n\n/*\n * Definitions for the TELNET protocol.\n */\n#define\tIAC\t255\t\t/* interpret as command: */\n#define\tDONT\t254\t\t/* you are not to use option */\n#define\tDO\t253\t\t/* please, you use option */\n#define\tWONT\t252\t\t/* I won't use option */\n#define\tWILL\t251\t\t/* I will use option */\n#define\tSB\t250\t\t/* interpret as subnegotiation */\n#define\tGA\t249\t\t/* you may reverse the line */\n#define\tEL\t248\t\t/* erase the current line */\n#define\tEC\t247\t\t/* erase the current character */\n#define\tAYT\t246\t\t/* are you there */\n#define\tAO\t245\t\t/* abort output--but let prog finish */\n#define\tIP\t244\t\t/* interrupt process--permanently */\n#define\tBREAK\t243\t\t/* break */\n#define\tDM\t242\t\t/* data mark--for connect. cleaning */\n#define\tNOP\t241\t\t/* nop */\n#define\tSE\t240\t\t/* end sub negotiation */\n#define EOR     239             /* end of record (transparent mode) */\n#define\tABORT\t238\t\t/* Abort process */\n#define\tSUSP\t237\t\t/* Suspend process */\n#define\txEOF\t236\t\t/* End of file: EOF is already used... */\n\n#define SYNCH\t242\t\t/* for telfunc calls */\n\n#ifdef TELCMDS\nchar *telcmds[] = {\n\t\"EOF\", \"SUSP\", \"ABORT\", \"EOR\",\n\t\"SE\", \"NOP\", \"DMARK\", \"BRK\", \"IP\", \"AO\", \"AYT\", \"EC\",\n\t\"EL\", \"GA\", \"SB\", \"WILL\", \"WONT\", \"DO\", \"DONT\", \"IAC\", 0,\n};\n#else\nextern char *telcmds[];\n#endif\n\n#define\tTELCMD_FIRST\txEOF\n#define\tTELCMD_LAST\tIAC\n#define\tTELCMD_OK(x)\t((unsigned int)(x) <= TELCMD_LAST && \\\n\t\t\t (unsigned int)(x) >= TELCMD_FIRST)\n#define\tTELCMD(x)\ttelcmds[(x)-TELCMD_FIRST]\n\n/* telnet options */\n#define TELOPT_BINARY\t0\t/* 8-bit data path */\n#define TELOPT_ECHO\t1\t/* echo */\n#define\tTELOPT_RCP\t2\t/* prepare to reconnect */\n#define\tTELOPT_SGA\t3\t/* suppress go ahead */\n#define\tTELOPT_NAMS\t4\t/* approximate message size */\n#define\tTELOPT_STATUS\t5\t/* give status */\n#define\tTELOPT_TM\t6\t/* timing mark */\n#define\tTELOPT_RCTE\t7\t/* remote controlled transmission and echo */\n#define TELOPT_NAOL \t8\t/* negotiate about output line width */\n#define TELOPT_NAOP \t9\t/* negotiate about output page size */\n#define TELOPT_NAOCRD\t10\t/* negotiate about CR disposition */\n#define TELOPT_NAOHTS\t11\t/* negotiate about horizontal tabstops */\n#define TELOPT_NAOHTD\t12\t/* negotiate about horizontal tab disposition */\n#define TELOPT_NAOFFD\t13\t/* negotiate about formfeed disposition */\n#define TELOPT_NAOVTS\t14\t/* negotiate about vertical tab stops */\n#define TELOPT_NAOVTD\t15\t/* negotiate about vertical tab disposition */\n#define TELOPT_NAOLFD\t16\t/* negotiate about output LF disposition */\n#define TELOPT_XASCII\t17\t/* extended ascii character set */\n#define\tTELOPT_LOGOUT\t18\t/* force logout */\n#define\tTELOPT_BM\t19\t/* byte macro */\n#define\tTELOPT_DET\t20\t/* data entry terminal */\n#define\tTELOPT_SUPDUP\t21\t/* supdup protocol */\n#define\tTELOPT_SUPDUPOUTPUT 22\t/* supdup output */\n#define\tTELOPT_SNDLOC\t23\t/* send location */\n#define\tTELOPT_TTYPE\t24\t/* terminal type */\n#define\tTELOPT_EOR\t25\t/* end or record */\n#define\tTELOPT_TUID\t26\t/* TACACS user identification */\n#define\tTELOPT_OUTMRK\t27\t/* output marking */\n#define\tTELOPT_TTYLOC\t28\t/* terminal location number */\n#define\tTELOPT_3270REGIME 29\t/* 3270 regime */\n#define\tTELOPT_X3PAD\t30\t/* X.3 PAD */\n#define\tTELOPT_NAWS\t31\t/* window size */\n#define\tTELOPT_TSPEED\t32\t/* terminal speed */\n#define\tTELOPT_LFLOW\t33\t/* remote flow control */\n#define TELOPT_LINEMODE\t34\t/* Linemode option */\n#define TELOPT_XDISPLOC\t35\t/* X Display Location */\n#define TELOPT_OLD_ENVIRON 36\t/* Old - Environment variables */\n#define\tTELOPT_AUTHENTICATION 37/* Authenticate */\n#define\tTELOPT_ENCRYPT\t38\t/* Encryption option */\n#define TELOPT_NEW_ENVIRON 39\t/* New - Environment variables */\n#define\tTELOPT_EXOPL\t255\t/* extended-options-list */\n\n\n#define\tNTELOPTS\t(1+TELOPT_NEW_ENVIRON)\n#ifdef TELOPTS\nconst char *telopts[NTELOPTS+1] = {\n\t\"BINARY\", \"ECHO\", \"RCP\", \"SUPPRESS GO AHEAD\", \"NAME\",\n\t\"STATUS\", \"TIMING MARK\", \"RCTE\", \"NAOL\", \"NAOP\",\n\t\"NAOCRD\", \"NAOHTS\", \"NAOHTD\", \"NAOFFD\", \"NAOVTS\",\n\t\"NAOVTD\", \"NAOLFD\", \"EXTEND ASCII\", \"LOGOUT\", \"BYTE MACRO\",\n\t\"DATA ENTRY TERMINAL\", \"SUPDUP\", \"SUPDUP OUTPUT\",\n\t\"SEND LOCATION\", \"TERMINAL TYPE\", \"END OF RECORD\",\n\t\"TACACS UID\", \"OUTPUT MARKING\", \"TTYLOC\",\n\t\"3270 REGIME\", \"X.3 PAD\", \"NAWS\", \"TSPEED\", \"LFLOW\",\n\t\"LINEMODE\", \"XDISPLOC\", \"OLD-ENVIRON\", \"AUTHENTICATION\",\n\t\"ENCRYPT\", \"NEW-ENVIRON\",\n\t0,\n};\n#define\tTELOPT_FIRST\tTELOPT_BINARY\n#define\tTELOPT_LAST\tTELOPT_NEW_ENVIRON\n#define\tTELOPT_OK(x)\t((unsigned int)(x) <= TELOPT_LAST)\n#define\tTELOPT(x)\ttelopts[(x)-TELOPT_FIRST]\n#endif\n\n/* sub-option qualifiers */\n#define\tTELQUAL_IS\t0\t/* option is... */\n#define\tTELQUAL_SEND\t1\t/* send option */\n#define\tTELQUAL_INFO\t2\t/* ENVIRON: informational version of IS */\n#define\tTELQUAL_REPLY\t2\t/* AUTHENTICATION: client version of IS */\n#define\tTELQUAL_NAME\t3\t/* AUTHENTICATION: client version of IS */\n\n#define\tLFLOW_OFF\t\t0\t/* Disable remote flow control */\n#define\tLFLOW_ON\t\t1\t/* Enable remote flow control */\n#define\tLFLOW_RESTART_ANY\t2\t/* Restart output on any char */\n#define\tLFLOW_RESTART_XON\t3\t/* Restart output only on XON */\n\n/*\n * LINEMODE suboptions\n */\n\n#define\tLM_MODE\t\t1\n#define\tLM_FORWARDMASK\t2\n#define\tLM_SLC\t\t3\n\n#define\tMODE_EDIT\t0x01\n#define\tMODE_TRAPSIG\t0x02\n#define\tMODE_ACK\t0x04\n#define MODE_SOFT_TAB\t0x08\n#define MODE_LIT_ECHO\t0x10\n\n#define\tMODE_MASK\t0x1f\n\n/* Not part of protocol, but needed to simplify things... */\n#define MODE_FLOW\t\t0x0100\n#define MODE_ECHO\t\t0x0200\n#define MODE_INBIN\t\t0x0400\n#define MODE_OUTBIN\t\t0x0800\n#define MODE_FORCE\t\t0x1000\n\n#define\tSLC_SYNCH\t1\n#define\tSLC_BRK\t\t2\n#define\tSLC_IP\t\t3\n#define\tSLC_AO\t\t4\n#define\tSLC_AYT\t\t5\n#define\tSLC_EOR\t\t6\n#define\tSLC_ABORT\t7\n#define\tSLC_EOF\t\t8\n#define\tSLC_SUSP\t9\n#define\tSLC_EC\t\t10\n#define\tSLC_EL\t\t11\n#define\tSLC_EW\t\t12\n#define\tSLC_RP\t\t13\n#define\tSLC_LNEXT\t14\n#define\tSLC_XON\t\t15\n#define\tSLC_XOFF\t16\n#define\tSLC_FORW1\t17\n#define\tSLC_FORW2\t18\n\n#define\tNSLC\t\t18\n\n/*\n * For backwards compatibility, we define SLC_NAMES to be the\n * list of names if SLC_NAMES is not defined.\n */\n#define\tSLC_NAMELIST\t\"0\", \"SYNCH\", \"BRK\", \"IP\", \"AO\", \"AYT\", \"EOR\", \\\n\t\t\t\"ABORT\", \"EOF\", \"SUSP\", \"EC\", \"EL\", \"EW\", \"RP\", \\\n\t\t\t\"LNEXT\", \"XON\", \"XOFF\", \"FORW1\", \"FORW2\", 0,\n#ifdef\tSLC_NAMES\nconst char *slc_names[] = {\n\tSLC_NAMELIST\n};\n#else\nextern char *slc_names[];\n#define\tSLC_NAMES SLC_NAMELIST\n#endif\n\n#define\tSLC_NAME_OK(x)\t((unsigned int)(x) <= NSLC)\n#define SLC_NAME(x)\tslc_names[x]\n\n#define\tSLC_NOSUPPORT\t0\n#define\tSLC_CANTCHANGE\t1\n#define\tSLC_VARIABLE\t2\n#define\tSLC_DEFAULT\t3\n#define\tSLC_LEVELBITS\t0x03\n\n#define\tSLC_FUNC\t0\n#define\tSLC_FLAGS\t1\n#define\tSLC_VALUE\t2\n\n#define\tSLC_ACK\t\t0x80\n#define\tSLC_FLUSHIN\t0x40\n#define\tSLC_FLUSHOUT\t0x20\n\n#define\tOLD_ENV_VAR\t1\n#define\tOLD_ENV_VALUE\t0\n#define\tNEW_ENV_VAR\t0\n#define\tNEW_ENV_VALUE\t1\n#define\tENV_ESC\t\t2\n#define ENV_USERVAR\t3\n\n/*\n * AUTHENTICATION suboptions\n */\n\n/*\n * Who is authenticating who ...\n */\n#define\tAUTH_WHO_CLIENT\t\t0\t/* Client authenticating server */\n#define\tAUTH_WHO_SERVER\t\t1\t/* Server authenticating client */\n#define\tAUTH_WHO_MASK\t\t1\n\n/*\n * amount of authentication done\n */\n#define\tAUTH_HOW_ONE_WAY\t0\n#define\tAUTH_HOW_MUTUAL\t\t2\n#define\tAUTH_HOW_MASK\t\t2\n\n#define\tAUTHTYPE_NULL\t\t0\n#define\tAUTHTYPE_KERBEROS_V4\t1\n#define\tAUTHTYPE_KERBEROS_V5\t2\n#define\tAUTHTYPE_SPX\t\t3\n#define\tAUTHTYPE_MINK\t\t4\n#define\tAUTHTYPE_CNT\t\t5\n\n#define\tAUTHTYPE_TEST\t\t99\n\n#ifdef\tAUTH_NAMES\nconst char *authtype_names[] = {\n\t\"NULL\", \"KERBEROS_V4\", \"KERBEROS_V5\", \"SPX\", \"MINK\", 0,\n};\n#else\nextern char *authtype_names[];\n#endif\n\n#define\tAUTHTYPE_NAME_OK(x)\t((unsigned int)(x) < AUTHTYPE_CNT)\n#define\tAUTHTYPE_NAME(x)\tauthtype_names[x]\n\n/*\n * ENCRYPTion suboptions\n */\n#define\tENCRYPT_IS\t\t0\t/* I pick encryption type ... */\n#define\tENCRYPT_SUPPORT\t\t1\t/* I support encryption types ... */\n#define\tENCRYPT_REPLY\t\t2\t/* Initial setup response */\n#define\tENCRYPT_START\t\t3\t/* Am starting to send encrypted */\n#define\tENCRYPT_END\t\t4\t/* Am ending encrypted */\n#define\tENCRYPT_REQSTART\t5\t/* Request you start encrypting */\n#define\tENCRYPT_REQEND\t\t6\t/* Request you send encrypting */\n#define\tENCRYPT_ENC_KEYID\t7\n#define\tENCRYPT_DEC_KEYID\t8\n#define\tENCRYPT_CNT\t\t9\n\n#define\tENCTYPE_ANY\t\t0\n#define\tENCTYPE_DES_CFB64\t1\n#define\tENCTYPE_DES_OFB64\t2\n#define\tENCTYPE_CNT\t\t3\n\n#ifdef\tENCRYPT_NAMES\nconst char *encrypt_names[] = {\n\t\"IS\", \"SUPPORT\", \"REPLY\", \"START\", \"END\",\n\t\"REQUEST-START\", \"REQUEST-END\", \"ENC-KEYID\", \"DEC-KEYID\",\n\t0,\n};\nconst char *enctype_names[] = {\n\t\"ANY\", \"DES_CFB64\",  \"DES_OFB64\",  0,\n};\n#else\nextern const char *encrypt_names[];\nextern const char *enctype_names[];\n#endif\n\n\n#define\tENCRYPT_NAME_OK(x)\t((unsigned int)(x) < ENCRYPT_CNT)\n#define\tENCRYPT_NAME(x)\t\tencrypt_names[x]\n\n#define\tENCTYPE_NAME_OK(x)\t((unsigned int)(x) < ENCTYPE_CNT)\n#define\tENCTYPE_NAME(x)\t\tenctype_names[x]\n\n#endif /* arpa/telnet.h */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/assert.h",
    "content": "/*\t$OpenBSD: assert.h,v 1.12 2006/01/31 10:53:51 hshoexer Exp $\t*/\n/*\t$NetBSD: assert.h,v 1.6 1994/10/26 00:55:44 cgd Exp $\t*/\n\n/*-\n * Copyright (c) 1992, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n * (c) UNIX System Laboratories, Inc.\n * All or some portions of this file are derived from material licensed\n * to the University of California by American Telephone and Telegraph\n * Co. or Unix System Laboratories, Inc. and are reproduced herein with\n * the permission of UNIX System Laboratories, Inc.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)assert.h\t8.2 (Berkeley) 1/21/94\n */\n\n/*\n * Unlike other ANSI header files, <assert.h> may usefully be included\n * multiple times, with and without NDEBUG defined.\n */\n\n#include <sys/cdefs.h>\n\n#undef assert\n#undef _assert\n\n#ifdef NDEBUG\n# define\tassert(e)\t((void)0)\n# define\t_assert(e)\t((void)0)\n#else\n# define\t_assert(e)\tassert(e)\n# if __ISO_C_VISIBLE >= 1999\n#  define\tassert(e)\t((e) ? (void)0 : __assert2(__FILE__, __LINE__, __func__, #e))\n# else\n#  define\tassert(e)\t((e) ? (void)0 : __assert(__FILE__, __LINE__, #e))\n# endif\n#endif\n\n__BEGIN_DECLS\n__dead void __assert(const char *, int, const char *) __noreturn;\n__dead void __assert2(const char *, int, const char *, const char *) __noreturn;\n__END_DECLS\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/bits/lockf.h",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _BITS_LOCKF_H_\n#define _BITS_LOCKF_H_\n\n#include <sys/cdefs.h>\n\n#define F_ULOCK 0\n#define F_LOCK 1\n#define F_TLOCK 2\n#define F_TEST 3\n\n__BEGIN_DECLS\n\n#if defined(__USE_FILE_OFFSET64)\nint lockf(int, int, off_t) __RENAME(lockf64);\n#else\nint lockf(int, int, off_t);\n#endif\nint lockf64(int, int, off64_t);\n\n__END_DECLS\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/bits/posix_limits.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _BITS_POSIX_LIMITS_H_\n#define _BITS_POSIX_LIMITS_H_\n\n\n/* Any constant values here other than -1 or 200809L are explicitly specified by POSIX.1-2008. */\n/* Keep it sorted. */\n#define _POSIX_ADVISORY_INFO        200809L\n#define _POSIX_AIO_LISTIO_MAX       2\n#define _POSIX_AIO_MAX              1\n#define _POSIX_ARG_MAX              4096\n#define _POSIX_ASYNCHRONOUS_IO      -1  /* not implemented */\n#define _POSIX_BARRIERS             -1  /* not implemented */\n#define _POSIX_CHILD_MAX            25\n#define _POSIX_CHOWN_RESTRICTED     1  /* yes, chown requires appropriate privileges */\n#define _POSIX_CLOCK_SELECTION      200809L\n#define _POSIX_CPUTIME              0  /* Use sysconf to detect support at runtime. */\n#define _POSIX_DELAYTIMER_MAX       32\n#define _POSIX_FSYNC                200809L  /* fdatasync() supported */\n#define _POSIX_HOST_NAME_MAX        255\n#define _POSIX_IPV6                 200809L\n#define _POSIX_JOB_CONTROL          1  /* job control is a Linux feature */\n#define _POSIX_LINK_MAX             8\n#define _POSIX_LOGIN_NAME_MAX       9  /* includes trailing NUL */\n#define _POSIX_MAPPED_FILES         200809L  /* mmap-ed files supported */\n#define _POSIX_MAX_CANON            255\n#define _POSIX_MAX_INPUT            255\n#define _POSIX_MEMLOCK              200809L\n#define _POSIX_MEMLOCK_RANGE        200809L\n#define _POSIX_MEMORY_PROTECTION    200809L\n#define _POSIX_MESSAGE_PASSING      -1  /* not implemented */\n#define _POSIX_MONOTONIC_CLOCK      0  /* the monotonic clock may be available; ask sysconf */\n#define _POSIX_MQ_OPEN_MAX          8\n#define _POSIX_MQ_PRIO_MAX          32\n#define _POSIX_NAME_MAX             14\n#define _POSIX_NGROUPS_MAX          8\n#define _POSIX_NO_TRUNC             1  /* very long pathnames generate an error */\n#define _POSIX_OPEN_MAX             20\n#define _POSIX_PATH_MAX             256\n#define _POSIX_PIPE_BUF             512\n#define _POSIX_PRIORITY_SCHEDULING  200809L  /* priority scheduling is a Linux feature */\n#define _POSIX_PRIORITIZED_IO       -1  /* not implemented */\n#define _POSIX_RAW_SOCKETS          200809L\n#define _POSIX_READER_WRITER_LOCKS  200809L\n#define _POSIX_REALTIME_SIGNALS     200809L\n#define _POSIX_REGEXP               1\n#define _POSIX_RE_DUP_MAX           255\n#define _POSIX_SAVED_IDS            1  /* saved user ids is a Linux feature */\n#define _POSIX_SEMAPHORES           200809L\n#define _POSIX_SEM_NSEMS_MAX        256\n#define _POSIX_SEM_VALUE_MAX        32767\n#define _POSIX_SHARED_MEMORY_OBJECTS  -1  /* shm_open()/shm_unlink() not implemented */\n#define _POSIX_SHELL                1   /* system() supported */\n#define _POSIX_SIGQUEUE_MAX         32\n#define _POSIX_SPAWN                -1  /* not implemented */\n#define _POSIX_SPIN_LOCKS           -1  /* not implemented */\n#define _POSIX_SPORADIC_SERVER      -1  /* not implemented */\n#define _POSIX_SSIZE_MAX            32767\n#define _POSIX_STREAM_MAX           8\n#define _POSIX_SYMLINK_MAX          255\n#define _POSIX_SYMLOOP_MAX          8\n#define _POSIX_SYNCHRONIZED_IO      200809L  /* synchronized i/o supported */\n#define _POSIX_THREADS              200809L  /* we support threads */\n#define _POSIX_THREAD_ATTR_STACKADDR  200809L\n#define _POSIX_THREAD_ATTR_STACKSIZE  200809L\n#define _POSIX_THREAD_CPUTIME       0  /* Use sysconf to detect support at runtime. */\n#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4\n#define _POSIX_THREAD_KEYS_MAX      128\n#define _POSIX_THREAD_PRIORITY_SCHEDULING 200809L\n#define _POSIX_THREAD_PRIO_INHERIT  200809L  /* linux feature */\n#define _POSIX_THREAD_PRIO_PROTECT  200809L  /* linux feature */\n#define _POSIX_THREAD_PROCESS_SHARED  -1  /* not implemented */\n#define _POSIX_THREAD_ROBUST_PRIO_INHERIT -1  /* not implemented */\n#define _POSIX_THREAD_ROBUST_PRIO_PROTECT -1  /* not implemented */\n#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L\n#define _POSIX_THREAD_SPORADIC_SERVER -1  /* not implemented */\n#define _POSIX_THREAD_THREADS_MAX   64\n#define _POSIX_TIMEOUTS             200809L\n#define _POSIX_TIMERS               200809L  /* Posix timers are supported */\n#define _POSIX_TIMER_MAX            32\n#define _POSIX_TRACE                -1  /* not implemented */\n#define _POSIX_TRACE_EVENT_FILTER   -1  /* not implemented */\n#define _POSIX_TRACE_INHERIT        -1  /* not implemented */\n#define _POSIX_TRACE_LOG            -1  /* not implemented */\n#define _POSIX_TRACE_NAME_MAX       8\n#define _POSIX_TRACE_SYS_MAX        8\n#define _POSIX_TRACE_USER_EVENT_MAX 32\n#define _POSIX_TTY_NAME_MAX         9  /* includes trailing NUL */\n#define _POSIX_TYPED_MEMORY_OBJECTS -1  /* not implemented */\n#define _POSIX_TZNAME_MAX           6\n#define _POSIX_VDISABLE             '\\0'\n\n#if defined(__LP64__)\n#define _POSIX_V7_ILP32_OFF32       -1\n#define _POSIX_V7_ILP32_OFFBIG      -1\n#define _POSIX_V7_LP64_OFF64         1\n#define _POSIX_V7_LPBIG_OFFBIG       1\n#else\n#define _POSIX_V7_ILP32_OFF32        1\n#define _POSIX_V7_ILP32_OFFBIG      -1\n#define _POSIX_V7_LP64_OFF64        -1\n#define _POSIX_V7_LPBIG_OFFBIG      -1\n#endif\n\n#define _POSIX2_BC_BASE_MAX         99\n#define _POSIX2_BC_DIM_MAX          2048\n#define _POSIX2_BC_SCALE_MAX        99\n#define _POSIX2_BC_STRING_MAX       1000\n#define _POSIX2_CHARCLASS_NAME_MAX  14\n#define _POSIX2_CHAR_TERM           -1  /* not implemented */\n#define _POSIX2_COLL_WEIGHTS_MAX    2\n#define _POSIX2_C_BIND              _POSIX_VERSION\n#define _POSIX2_C_DEV               -1  /* c dev utilities not implemented */\n#define _POSIX2_EXPR_NEST_MAX       32\n#define _POSIX2_LINE_MAX            2048\n#define _POSIX2_LOCALEDEF           -1  /* localedef utilitiy not implemented */\n#define _POSIX2_RE_DUP_MAX          _POSIX_RE_DUP_MAX\n#define _POSIX2_SW_DEV              -1  /* software dev utilities not implemented */\n#define _POSIX2_UPE                 -1  /* user portability utilities not implemented */\n\n#define _XOPEN_ENH_I18N             -1  /* we don't support internationalization in the C library */\n#define _XOPEN_CRYPT                -1  /* don't support X/Open Encryption */\n#define _XOPEN_IOV_MAX              16\n#define _XOPEN_LEGACY               -1  /* not support all */\n#define _XOPEN_REALTIME             -1 /* we don't support all these functions */\n#define _XOPEN_REALTIME_THREADS     -1  /* same here */\n#define _XOPEN_SHM                  -1\n#define _XOPEN_UNIX                 1\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/bits/pthread_types.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _BITS_PTHREAD_TYPES_H_\n#define _BITS_PTHREAD_TYPES_H_\n\n#include <sys/types.h>\n\ntypedef long pthread_t;\n\ntypedef struct {\n  uint32_t flags;\n  void* stack_base;\n  size_t stack_size;\n  size_t guard_size;\n  int32_t sched_policy;\n  int32_t sched_priority;\n#ifdef __LP64__\n  char __reserved[16];\n#endif\n} pthread_attr_t;\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/bits/timespec.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _BITS_TIMESPEC_H_\n#define _BITS_TIMESPEC_H_\n\n#include <sys/types.h>\n\n/*\n * This file is used to include timespec definition without introducing the whole\n * <linux/time.h>, <sys/time.h> or <time.h>.\n */\n#ifndef _STRUCT_TIMESPEC\n#define _STRUCT_TIMESPEC\nstruct timespec {\n  time_t tv_sec;\n  long tv_nsec;\n};\n#endif\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/bits/wchar_limits.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _BITS_WCHAR_LIMITS_H_\n#define _BITS_WCHAR_LIMITS_H_\n\n/* Both GCC and clang define __WCHAR_MAX__. */\n#define WCHAR_MAX __WCHAR_MAX__\n\n/* As of 3.4, clang still doesn't define __WCHAR_MIN__. */\n#if defined(__WCHAR_UNSIGNED__)\n#  define WCHAR_MIN L'\\0'\n#else\n#  define WCHAR_MIN (-(WCHAR_MAX) - 1)\n#endif\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/byteswap.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _BYTESWAP_H_\n#define _BYTESWAP_H_\n\n#include <sys/endian.h>\n\n#define bswap_16(x) __swap16(x)\n#define bswap_32(x) __swap32(x)\n#define bswap_64(x) __swap64(x)\n\n#endif /* _BYTESWAP_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/ctype.h",
    "content": "/*\t$OpenBSD: ctype.h,v 1.19 2005/12/13 00:35:22 millert Exp $\t*/\n/*\t$NetBSD: ctype.h,v 1.14 1994/10/26 00:55:47 cgd Exp $\t*/\n\n/*\n * Copyright (c) 1989 The Regents of the University of California.\n * All rights reserved.\n * (c) UNIX System Laboratories, Inc.\n * All or some portions of this file are derived from material licensed\n * to the University of California by American Telephone and Telegraph\n * Co. or Unix System Laboratories, Inc. and are reproduced herein with\n * the permission of UNIX System Laboratories, Inc.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)ctype.h\t5.3 (Berkeley) 4/3/91\n */\n\n#ifndef _CTYPE_H_\n#define _CTYPE_H_\n\n#include <sys/cdefs.h>\n#include <xlocale.h>\n\n#define _CTYPE_U 0x01\n#define _CTYPE_L 0x02\n#define _CTYPE_D 0x04\n#define _CTYPE_S 0x08\n#define _CTYPE_P 0x10\n#define _CTYPE_C 0x20\n#define _CTYPE_X 0x40\n#define _CTYPE_B 0x80\n#define _CTYPE_R (_CTYPE_P|_CTYPE_U|_CTYPE_L|_CTYPE_D|_CTYPE_B)\n#define _CTYPE_A (_CTYPE_L|_CTYPE_U)\n\n__BEGIN_DECLS\n\nextern const char\t*_ctype_;\n\n#if defined(__GNUC__) || defined(_ANSI_LIBRARY) || defined(lint)\nint isalnum(int);\nint isalpha(int);\nint iscntrl(int);\nint isdigit(int);\nint isgraph(int);\nint islower(int);\nint isprint(int);\nint ispunct(int);\nint isspace(int);\nint isupper(int);\nint isxdigit(int);\nint tolower(int);\nint toupper(int);\n\n#if __ANDROID_API__ >= 21\nint isalnum_l(int, locale_t);\nint isalpha_l(int, locale_t);\nint isblank_l(int, locale_t);\nint iscntrl_l(int, locale_t);\nint isdigit_l(int, locale_t);\nint isgraph_l(int, locale_t);\nint islower_l(int, locale_t);\nint isprint_l(int, locale_t);\nint ispunct_l(int, locale_t);\nint isspace_l(int, locale_t);\nint isupper_l(int, locale_t);\nint isxdigit_l(int, locale_t);\nint tolower_l(int, locale_t);\nint toupper_l(int, locale_t);\n#endif /* __ANDROID_API__ >= 21 */\n\n#if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __POSIX_VISIBLE > 200112 \\\n    || __XPG_VISIBLE > 600\nint isblank(int);\n#endif\n\n#if __BSD_VISIBLE || __XPG_VISIBLE\nint isascii(int);\nint toascii(int);\nint _tolower(int);\nint _toupper(int);\n#endif /* __BSD_VISIBLE || __XPG_VISIBLE */\n\n#endif /* __GNUC__ || _ANSI_LIBRARY || lint */\n\n__END_DECLS\n\n#endif /* !_CTYPE_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/dirent.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _DIRENT_H_\n#define _DIRENT_H_\n\n#include <stdint.h>\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\n#ifndef DT_UNKNOWN\n#define DT_UNKNOWN 0\n#define DT_FIFO 1\n#define DT_CHR 2\n#define DT_DIR 4\n#define DT_BLK 6\n#define DT_REG 8\n#define DT_LNK 10\n#define DT_SOCK 12\n#define DT_WHT 14\n#endif\n\n#define __DIRENT64_BODY \\\n    uint64_t         d_ino; \\\n    int64_t          d_off; \\\n    unsigned short   d_reclen; \\\n    unsigned char    d_type; \\\n    char             d_name[256]; \\\n\nstruct dirent { __DIRENT64_BODY };\nstruct dirent64 { __DIRENT64_BODY };\n\n#undef __DIRENT64_BODY\n\n/* glibc compatibility. */\n#undef _DIRENT_HAVE_D_NAMLEN /* Linux doesn't have a d_namlen field. */\n#define _DIRENT_HAVE_D_RECLEN\n#define _DIRENT_HAVE_D_OFF\n#define _DIRENT_HAVE_D_TYPE\n\n#define d_fileno d_ino\n\ntypedef struct DIR DIR;\n\nextern DIR* opendir(const char*);\nextern DIR* fdopendir(int);\nextern struct dirent* readdir(DIR*);\nextern struct dirent64* readdir64(DIR*);\nextern int readdir_r(DIR*, struct dirent*, struct dirent**);\nextern int readdir64_r(DIR*, struct dirent64*, struct dirent64**);\nextern int closedir(DIR*);\nextern void rewinddir(DIR*);\nextern void seekdir(DIR*, long);\nextern long telldir(DIR*);\nextern int dirfd(DIR*);\nextern int alphasort(const struct dirent**, const struct dirent**);\nextern int alphasort64(const struct dirent64**, const struct dirent64**);\nextern int scandir64(const char*, struct dirent64***, int (*)(const struct dirent64*), int (*)(const struct dirent64**, const struct dirent64**));\nextern int scandir(const char*, struct dirent***, int (*)(const struct dirent*), int (*)(const struct dirent**, const struct dirent**));\n\n#if defined(__USE_GNU)\nint scandirat64(int, const char*, struct dirent64***, int (*)(const struct dirent64*), int (*)(const struct dirent64**, const struct dirent64**));\nint scandirat(int, const char*, struct dirent***, int (*)(const struct dirent*), int (*)(const struct dirent**, const struct dirent**));\n#endif\n\n__END_DECLS\n\n#endif /* _DIRENT_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/dlfcn.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef __DLFCN_H__\n#define __DLFCN_H__\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\ntypedef struct {\n    const char *dli_fname;  /* Pathname of shared object that\n                               contains address */\n    void       *dli_fbase;  /* Address at which shared object\n                               is loaded */\n    const char *dli_sname;  /* Name of nearest symbol with address\n                               lower than addr */\n    void       *dli_saddr;  /* Exact address of symbol named\n                               in dli_sname */\n} Dl_info;\n\nextern void* dlopen(const char*  filename, int flag);\nextern int dlclose(void*  handle);\nextern const char* dlerror(void);\nextern void* dlsym(void* handle, const char* symbol) __nonnull((2));\nextern void* dlvsym(void* handle, const char* symbol, const char* version) __nonnull((2, 3));\nextern int dladdr(const void* addr, Dl_info *info);\n\nenum {\n#if defined(__LP64__)\n  RTLD_NOW  = 2,\n#else\n  RTLD_NOW  = 0,\n#endif\n  RTLD_LAZY = 1,\n\n  RTLD_LOCAL  = 0,\n#if defined(__LP64__)\n  RTLD_GLOBAL = 0x00100,\n#else\n  RTLD_GLOBAL = 2,\n#endif\n  RTLD_NOLOAD = 4,\n  RTLD_NODELETE = 0x01000,\n};\n\n#if defined (__LP64__)\n#define RTLD_DEFAULT  ((void*) 0)\n#define RTLD_NEXT     ((void*) -1L)\n#else\n#define RTLD_DEFAULT  ((void*) 0xffffffff)\n#define RTLD_NEXT     ((void*) 0xfffffffe)\n#endif\n\n__END_DECLS\n\n#endif /* __DLFCN_H */\n\n\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/elf.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _ELF_H\n#define _ELF_H\n\n#include <linux/auxvec.h>\n#include <linux/elf.h>\n#include <linux/elf-em.h>\n\n#include <machine/elf_machdep.h>\n\n#define ELF32_R_INFO(sym, type) ((((Elf32_Word)sym) << 8) | ((type) & 0xff))\n#define ELF64_R_INFO(sym, type) ((((Elf64_Xword)sym) << 32) | ((type) & 0xffffffff))\n\ntypedef __s64 Elf32_Sxword;\n\ntypedef struct {\n  __u32 a_type;\n  union {\n    __u32 a_val;\n  } a_un;\n} Elf32_auxv_t;\n\ntypedef struct {\n  __u64 a_type;\n  union {\n    __u64 a_val;\n  } a_un;\n} Elf64_auxv_t;\n\ntypedef Elf32_Half Elf32_Versym;\ntypedef Elf64_Half Elf64_Versym;\n\ntypedef struct {\n  Elf32_Half vd_version;\n  Elf32_Half vd_flags;\n  Elf32_Half vd_ndx;\n  Elf32_Half vd_cnt;\n  Elf32_Word vd_hash;\n  Elf32_Word vd_aux;\n  Elf32_Word vd_next;\n} Elf32_Verdef;\n\ntypedef struct {\n  Elf32_Word vda_name;\n  Elf32_Word vda_next;\n} Elf32_Verdaux;\n\ntypedef struct {\n  Elf64_Half vd_version;\n  Elf64_Half vd_flags;\n  Elf64_Half vd_ndx;\n  Elf64_Half vd_cnt;\n  Elf64_Word vd_hash;\n  Elf64_Word vd_aux;\n  Elf64_Word vd_next;\n} Elf64_Verdef;\n\ntypedef struct {\n  Elf64_Word vda_name;\n  Elf64_Word vda_next;\n} Elf64_Verdaux;\n\ntypedef struct {\n  Elf32_Half vn_version;\n  Elf32_Half vn_cnt;\n  Elf32_Word vn_file;\n  Elf32_Word vn_aux;\n  Elf32_Word vn_next;\n} Elf32_Verneed;\n\ntypedef struct {\n  Elf32_Word vna_hash;\n  Elf32_Half vna_flags;\n  Elf32_Half vna_other;\n  Elf32_Word vna_name;\n  Elf32_Word vna_next;\n} Elf32_Vernaux;\n\ntypedef struct {\n  Elf64_Half vn_version;\n  Elf64_Half vn_cnt;\n  Elf64_Word vn_file;\n  Elf64_Word vn_aux;\n  Elf64_Word vn_next;\n} Elf64_Verneed;\n\ntypedef struct {\n  Elf64_Word vna_hash;\n  Elf64_Half vna_flags;\n  Elf64_Half vna_other;\n  Elf64_Word vna_name;\n  Elf64_Word vna_next;\n} Elf64_Vernaux;\n\n#define DF_ORIGIN     0x00000001\n#define DF_SYMBOLIC   0x00000002\n#define DF_TEXTREL    0x00000004\n#define DF_BIND_NOW   0x00000008\n#define DF_STATIC_TLS 0x00000010\n\n#define DF_1_NOW        0x00000001 /* Perform complete relocation processing. */\n#define DF_1_GLOBAL     0x00000002 /* implies RTLD_GLOBAL */\n#define DF_1_GROUP      0x00000004\n#define DF_1_NODELETE   0x00000008 /* implies RTLD_NODELETE */\n#define DF_1_LOADFLTR   0x00000010\n#define DF_1_INITFIRST  0x00000020\n#define DF_1_NOOPEN     0x00000040 /* Object can not be used with dlopen(3) */\n#define DF_1_ORIGIN     0x00000080\n#define DF_1_DIRECT     0x00000100\n#define DF_1_TRANS      0x00000200\n#define DF_1_INTERPOSE  0x00000400\n#define DF_1_NODEFLIB   0x00000800\n#define DF_1_NODUMP     0x00001000 /* Object cannot be dumped with dldump(3) */\n#define DF_1_CONFALT    0x00002000\n#define DF_1_ENDFILTEE  0x00004000\n#define DF_1_DISPRELDNE 0x00008000\n#define DF_1_DISPRELPND 0x00010000\n#define DF_1_NODIRECT   0x00020000\n#define DF_1_IGNMULDEF  0x00040000 /* Internal use */\n#define DF_1_NOKSYMS    0x00080000 /* Internal use */\n#define DF_1_NOHDR      0x00100000 /* Internal use */\n#define DF_1_EDITED     0x00200000\n#define DF_1_NORELOC    0x00400000 /* Internal use */\n#define DF_1_SYMINTPOSE 0x00800000\n#define DF_1_GLOBAUDIT  0x01000000\n#define DF_1_SINGLETON  0x02000000\n#define DF_1_STUB       0x04000000\n#define DF_1_PIE        0x08000000\n\n#define DT_BIND_NOW 24\n#define DT_INIT_ARRAY 25\n#define DT_FINI_ARRAY 26\n#define DT_INIT_ARRAYSZ 27\n#define DT_FINI_ARRAYSZ 28\n#define DT_RUNPATH 29\n#define DT_FLAGS 30\n/* glibc and BSD disagree for DT_ENCODING; glibc looks wrong. */\n#define DT_PREINIT_ARRAY 32\n#define DT_PREINIT_ARRAYSZ 33\n\n/* Android compressed rel/rela sections */\n#define DT_ANDROID_REL (DT_LOOS + 2)\n#define DT_ANDROID_RELSZ (DT_LOOS + 3)\n\n#define DT_ANDROID_RELA (DT_LOOS + 4)\n#define DT_ANDROID_RELASZ (DT_LOOS + 5)\n\n/* gnu hash entry */\n#define DT_GNU_HASH 0x6ffffef5\n\n#define ELFOSABI_SYSV 0 /* Synonym for ELFOSABI_NONE used by valgrind. */\n\n#define PT_GNU_RELRO 0x6474e552\n\n#define STB_LOOS      10\n#define STB_HIOS      12\n#define STB_LOPROC    13\n#define STB_HIPROC    15\n\n#define SHT_LOOS    0x60000000\n#define SHT_HIOS    0x6fffffff\n\n#define STT_GNU_IFUNC 10\n#define STT_LOOS      10\n#define STT_HIOS      12\n#define STT_LOPROC    13\n#define STT_HIPROC    15\n\n#define STV_DEFAULT   0\n#define STV_INTERNAL  1\n#define STV_HIDDEN    2\n#define STV_PROTECTED 3\n\n/* The kernel uses NT_PRFPREG but glibc also offers NT_FPREGSET */\n#define NT_FPREGSET NT_PRFPREG\n\n#define ELF_NOTE_GNU \"GNU\"\n\n#define NT_GNU_BUILD_ID 3\n\n#define VER_FLG_BASE 0x1\n#define VER_FLG_WEAK 0x2\n\n#define VER_NDX_LOCAL  0\n#define VER_NDX_GLOBAL 1\n\n#endif /* _ELF_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/endian.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _ENDIAN_H_\n#define _ENDIAN_H_\n\n#include <sys/endian.h>\n\n#endif /* _ENDIAN_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/err.h",
    "content": "/*\t$OpenBSD: err.h,v 1.10 2006/01/06 18:53:04 millert Exp $\t*/\n/*\t$NetBSD: err.h,v 1.11 1994/10/26 00:55:52 cgd Exp $\t*/\n\n/*-\n * Copyright (c) 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)err.h\t8.1 (Berkeley) 6/2/93\n */\n\n#ifndef _ERR_H_\n#define _ERR_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n__BEGIN_DECLS\n\n/* printf's format string isn't nullable; the err family's one is,\n * so we can't use __errlike here. */\n#define __errlike(x, y) __attribute__((__format__(printf, x, y)))\n\n__noreturn void err(int, const char *, ...) __errlike(2, 3);\n__noreturn void verr(int, const char *, __va_list) __errlike(2, 0);\n__noreturn void errx(int, const char *, ...) __errlike(2, 3);\n__noreturn void verrx(int, const char *, __va_list) __errlike(2, 0);\nvoid warn(const char *, ...) __errlike(1, 2);\nvoid vwarn(const char *, __va_list) __errlike(1, 0);\nvoid warnx(const char *, ...) __errlike(1, 2);\nvoid vwarnx(const char *, __va_list) __errlike(1, 0);\n\n__END_DECLS\n\n#endif /* !_ERR_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/errno.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _ERRNO_H\n#define _ERRNO_H\n\n#include <sys/cdefs.h>\n#include <linux/errno.h>\n\n__BEGIN_DECLS\n\n/* on Linux, ENOTSUP and EOPNOTSUPP are defined as the same error code\n * even if 1000.3 states that they should be different\n */\n#ifndef  ENOTSUP\n#define  ENOTSUP  EOPNOTSUPP\n#endif\n\n/* internal function returning the address of the thread-specific errno */\nextern volatile int* __errno(void) __pure2;\n\n/* a macro expanding to the errno l-value */\n#define  errno   (*__errno())\n\n#if __ANDROID_API__ < 21\n#include <android/legacy_errno_inlines.h>\n#endif\n\n__END_DECLS\n\n#endif /* _ERRNO_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/error.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _ERROR_H\n#define _ERROR_H 1\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\nvoid error(int, int, const char*, ...) __printflike(3, 4);\nvoid error_at_line(int, int, const char*, unsigned int, const char*, ...) __printflike(5, 6);\n\nextern void (*error_print_progname)(void);\nextern unsigned int error_message_count;\nextern int error_one_per_line;\n\n__END_DECLS\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/fcntl.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _FCNTL_H\n#define _FCNTL_H\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <linux/fadvise.h>\n#include <linux/fcntl.h>\n#include <linux/stat.h>\n#include <linux/uio.h>\n\n#if defined(__USE_GNU) || defined(__USE_BSD)\n#include <bits/lockf.h>\n#endif\n\n__BEGIN_DECLS\n\n#ifdef __LP64__\n/* LP64 kernels don't have F_*64 defines because their flock is 64-bit. */\n#define F_GETLK64  F_GETLK\n#define F_SETLK64  F_SETLK\n#define F_SETLKW64 F_SETLKW\n#endif\n\n#define O_ASYNC FASYNC\n#define O_RSYNC O_SYNC\n\n#define SPLICE_F_MOVE 1\n#define SPLICE_F_NONBLOCK 2\n#define SPLICE_F_MORE 4\n#define SPLICE_F_GIFT 8\n\n#define SYNC_FILE_RANGE_WAIT_BEFORE 1\n#define SYNC_FILE_RANGE_WRITE 2\n#define SYNC_FILE_RANGE_WAIT_AFTER 4\n\nextern int creat(const char*, mode_t);\nextern int creat64(const char*, mode_t);\nextern int fcntl(int, int, ...);\nextern int openat(int, const char*, int, ...);\nextern int openat64(int, const char*, int, ...);\nextern int open(const char*, int, ...);\nextern int open64(const char*, int, ...);\nextern ssize_t splice(int, off64_t*, int, off64_t*, size_t, unsigned int);\nextern ssize_t tee(int, int, size_t, unsigned int);\nextern int unlinkat(int, const char*, int);\nextern ssize_t vmsplice(int, const struct iovec*, size_t, unsigned int);\n\n#if defined(__USE_FILE_OFFSET64)\nextern int fallocate(int, int, off_t, off_t) __RENAME(fallocate64);\nextern int posix_fadvise(int, off_t, off_t, int) __RENAME(posix_fadvise64);\nextern int posix_fallocate(int, off_t, off_t) __RENAME(posix_fallocate);\n#else\nextern int fallocate(int, int, off_t, off_t);\nextern int posix_fadvise(int, off_t, off_t, int);\nextern int posix_fallocate(int, off_t, off_t);\n#endif\nextern int fallocate64(int, int, off64_t, off64_t);\nextern int posix_fadvise64(int, off64_t, off64_t, int);\nextern int posix_fallocate64(int, off64_t, off64_t);\n\nextern int __open_2(const char*, int);\nextern int __open_real(const char*, int, ...) __RENAME(open);\nextern int __openat_2(int, const char*, int);\nextern int __openat_real(int, const char*, int, ...) __RENAME(openat);\n__errordecl(__creat_missing_mode, \"called with O_CREAT, but missing mode\");\n__errordecl(__creat_too_many_args, \"too many arguments\");\n\n#if defined(__BIONIC_FORTIFY)\n\n#if !defined(__clang__)\n\n__BIONIC_FORTIFY_INLINE\nint open(const char* pathname, int flags, ...) {\n    if (__builtin_constant_p(flags)) {\n        if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) {\n            __creat_missing_mode();  // compile time error\n        }\n    }\n\n    if (__builtin_va_arg_pack_len() > 1) {\n        __creat_too_many_args();  // compile time error\n    }\n\n    if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {\n        return __open_2(pathname, flags);\n    }\n\n    return __open_real(pathname, flags, __builtin_va_arg_pack());\n}\n\n__BIONIC_FORTIFY_INLINE\nint openat(int dirfd, const char* pathname, int flags, ...) {\n    if (__builtin_constant_p(flags)) {\n        if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) {\n            __creat_missing_mode();  // compile time error\n        }\n    }\n\n    if (__builtin_va_arg_pack_len() > 1) {\n        __creat_too_many_args();  // compile time error\n    }\n\n    if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {\n        return __openat_2(dirfd, pathname, flags);\n    }\n\n    return __openat_real(dirfd, pathname, flags, __builtin_va_arg_pack());\n}\n\n#endif /* !defined(__clang__) */\n\n#endif /* defined(__BIONIC_FORTIFY) */\n\n__END_DECLS\n\n#endif /* _FCNTL_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/features.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _FEATURES_H_\n#define _FEATURES_H_\n\n/* Our <features.h> macro fun is all in <sys/cdefs.h>. */\n#include <sys/cdefs.h>\n\n#endif /* _FEATURES_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/fnmatch.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _FNMATCH_H\n#define _FNMATCH_H\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\n#define FNM_NOMATCH      1     /* Match failed. */\n#define FNM_NOSYS        2     /* Function not supported (unused). */\n\n#define FNM_NOESCAPE     0x01        /* Disable backslash escaping. */\n#define FNM_PATHNAME     0x02        /* Slash must be matched by slash. */\n#define FNM_PERIOD       0x04        /* Period must be matched by period. */\n#define FNM_LEADING_DIR  0x08        /* Ignore /<tail> after Imatch. */\n#define FNM_CASEFOLD     0x10        /* Case insensitive search. */\n\n#define FNM_IGNORECASE   FNM_CASEFOLD\n#define FNM_FILE_NAME    FNM_PATHNAME\n\nextern int  fnmatch(const char *pattern, const char *string, int flags);\n\n__END_DECLS\n\n#endif /* _FNMATCH_H */\n\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/fts.h",
    "content": "/*\t$OpenBSD: fts.h,v 1.12 2009/08/27 16:19:27 millert Exp $\t*/\n/*\t$NetBSD: fts.h,v 1.5 1994/12/28 01:41:50 mycroft Exp $\t*/\n\n/*\n * Copyright (c) 1989, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)fts.h\t8.3 (Berkeley) 8/14/94\n */\n\n#ifndef\t_FTS_H_\n#define\t_FTS_H_\n\n#include <sys/types.h>\n\ntypedef struct {\n\tstruct _ftsent *fts_cur;\t/* current node */\n\tstruct _ftsent *fts_child;\t/* linked list of children */\n\tstruct _ftsent **fts_array;\t/* sort array */\n\tdev_t fts_dev;\t\t\t/* starting device # */\n\tchar *fts_path;\t\t\t/* path for this descent */\n\tint fts_rfd;\t\t\t/* fd for root */\n\tsize_t fts_pathlen;\t\t/* sizeof(path) */\n\tint fts_nitems;\t\t\t/* elements in the sort array */\n\tint (*fts_compar)();\t\t/* compare function */\n\n#define\tFTS_COMFOLLOW\t0x0001\t\t/* follow command line symlinks */\n#define\tFTS_LOGICAL\t0x0002\t\t/* logical walk */\n#define\tFTS_NOCHDIR\t0x0004\t\t/* don't change directories */\n#define\tFTS_NOSTAT\t0x0008\t\t/* don't get stat info */\n#define\tFTS_PHYSICAL\t0x0010\t\t/* physical walk */\n#define\tFTS_SEEDOT\t0x0020\t\t/* return dot and dot-dot */\n#define\tFTS_XDEV\t0x0040\t\t/* don't cross devices */\n#define\tFTS_OPTIONMASK\t0x00ff\t\t/* valid user option mask */\n\n#define\tFTS_NAMEONLY\t0x1000\t\t/* (private) child names only */\n#define\tFTS_STOP\t0x2000\t\t/* (private) unrecoverable error */\n\tint fts_options;\t\t/* fts_open options, global flags */\n} FTS;\n\ntypedef struct _ftsent {\n\tstruct _ftsent *fts_cycle;\t/* cycle node */\n\tstruct _ftsent *fts_parent;\t/* parent directory */\n\tstruct _ftsent *fts_link;\t/* next file in directory */\n\tlong fts_number;\t        /* local numeric value */\n\tvoid *fts_pointer;\t        /* local address value */\n\tchar *fts_accpath;\t\t/* access path */\n\tchar *fts_path;\t\t\t/* root path */\n\tint fts_errno;\t\t\t/* errno for this node */\n\tint fts_symfd;\t\t\t/* fd for symlink */\n\tsize_t fts_pathlen;\t\t/* strlen(fts_path) */\n\tsize_t fts_namelen;\t\t/* strlen(fts_name) */\n\n\tino_t fts_ino;\t\t\t/* inode */\n\tdev_t fts_dev;\t\t\t/* device */\n\tnlink_t fts_nlink;\t\t/* link count */\n\n#define\tFTS_ROOTPARENTLEVEL\t-1\n#define\tFTS_ROOTLEVEL\t\t 0\n#define\tFTS_MAXLEVEL\t\t 0x7fff\n\tshort fts_level;\t\t/* depth (-1 to N) */\n\n#define\tFTS_D\t\t 1\t\t/* preorder directory */\n#define\tFTS_DC\t\t 2\t\t/* directory that causes cycles */\n#define\tFTS_DEFAULT\t 3\t\t/* none of the above */\n#define\tFTS_DNR\t\t 4\t\t/* unreadable directory */\n#define\tFTS_DOT\t\t 5\t\t/* dot or dot-dot */\n#define\tFTS_DP\t\t 6\t\t/* postorder directory */\n#define\tFTS_ERR\t\t 7\t\t/* error; errno is set */\n#define\tFTS_F\t\t 8\t\t/* regular file */\n#define\tFTS_INIT\t 9\t\t/* initialized only */\n#define\tFTS_NS\t\t10\t\t/* stat(2) failed */\n#define\tFTS_NSOK\t11\t\t/* no stat(2) requested */\n#define\tFTS_SL\t\t12\t\t/* symbolic link */\n#define\tFTS_SLNONE\t13\t\t/* symbolic link without target */\n\tunsigned short fts_info;\t/* user flags for FTSENT structure */\n\n#define\tFTS_DONTCHDIR\t 0x01\t\t/* don't chdir .. to the parent */\n#define\tFTS_SYMFOLLOW\t 0x02\t\t/* followed a symlink to get here */\n\tunsigned short fts_flags;\t/* private flags for FTSENT structure */\n\n#define\tFTS_AGAIN\t 1\t\t/* read node again */\n#define\tFTS_FOLLOW\t 2\t\t/* follow symbolic link */\n#define\tFTS_NOINSTR\t 3\t\t/* no instructions */\n#define\tFTS_SKIP\t 4\t\t/* discard node */\n\tunsigned short fts_instr;\t/* fts_set() instructions */\n\n\tstruct stat *fts_statp;\t\t/* stat(2) information */\n\tchar fts_name[1];\t\t/* file name */\n} FTSENT;\n\n__BEGIN_DECLS\nFTSENT\t*fts_children(FTS *, int);\nint\t fts_close(FTS *);\nFTS\t*fts_open(char * const *, int,\n\t    int (*)(const FTSENT **, const FTSENT **));\nFTSENT\t*fts_read(FTS *);\nint\t fts_set(FTS *, FTSENT *, int);\n__END_DECLS\n\n#endif /* !_FTS_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/ftw.h",
    "content": "/* $NetBSD: ftw.h,v 1.1 2005/12/30 23:07:33 agc Exp $ */\n\n/*\tFrom OpenBSD: ftw.h,v 1.1 2003/07/21 21:13:18 millert Exp \t*/\n\n/*\n * Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n *\n * Sponsored in part by the Defense Advanced Research Projects\n * Agency (DARPA) and Air Force Research Laboratory, Air Force\n * Materiel Command, USAF, under agreement number F39502-99-1-0512.\n */\n\n#ifndef\t_FTW_H\n#define\t_FTW_H\n\n#include <sys/types.h>\n#include <sys/stat.h>\n\n/*\n * Valid flags for the 3rd argument to the function that is passed as the\n * second argument to ftw(3) and nftw(3).  Say it three times fast!\n */\n#define\tFTW_F\t\t0\t/* File.  */\n#define\tFTW_D\t\t1\t/* Directory.  */\n#define\tFTW_DNR\t\t2\t/* Directory without read permission.  */\n#define\tFTW_DP\t\t3\t/* Directory with subdirectories visited.  */\n#define\tFTW_NS\t\t4\t/* Unknown type; stat() failed.  */\n#define\tFTW_SL\t\t5\t/* Symbolic link.  */\n#define\tFTW_SLN\t\t6\t/* Sym link that names a nonexistent file.  */\n\n/*\n * Flags for use as the 4th argument to nftw(3).  These may be ORed together.\n */\n#define\tFTW_PHYS\t0x01\t/* Physical walk, don't follow sym links.  */\n#define\tFTW_MOUNT\t0x02\t/* The walk does not cross a mount point.  */\n#define\tFTW_DEPTH\t0x04\t/* Subdirs visited before the dir itself. */\n#define\tFTW_CHDIR\t0x08\t/* Change to a directory before reading it. */\n\nstruct FTW {\n\tint base;\n\tint level;\n};\n\n__BEGIN_DECLS\nint\tftw(const char *, int (*)(const char *, const struct stat *, int), int);\nint\tnftw(const char *, int (*)(const char *, const struct stat *, int,\n\t    struct FTW *), int, int);\nint\tftw64(const char *, int (*)(const char *, const struct stat64 *, int), int);\nint\tnftw64(const char *, int (*)(const char *, const struct stat64 *, int,\n\t    struct FTW *), int, int);\n__END_DECLS\n\n#endif\t/* !_FTW_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/getopt.h",
    "content": "/*\t$NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $\t*/\n/*\t$FreeBSD$ */\n\n/*-\n * Copyright (c) 2000 The NetBSD Foundation, Inc.\n * All rights reserved.\n *\n * This code is derived from software contributed to The NetBSD Foundation\n * by Dieter Baron and Thomas Klausner.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS\n * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\n * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS\n * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n * POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef _GETOPT_H_\n#define _GETOPT_H_\n\n#include <sys/cdefs.h>\n\n/*\n * GNU-like getopt_long()/getopt_long_only() with 4.4BSD optreset extension.\n * getopt() is declared here too for GNU programs.\n */\n#define no_argument        0\n#define required_argument  1\n#define optional_argument  2\n\nstruct option {\n\t/* name of long option */\n\tconst char *name;\n\t/*\n\t * one of no_argument, required_argument, and optional_argument:\n\t * whether option takes an argument\n\t */\n\tint has_arg;\n\t/* if not NULL, set *flag to val when option found */\n\tint *flag;\n\t/* if flag not NULL, value to set *flag to; else return value */\n\tint val;\n};\n\n__BEGIN_DECLS\nint\tgetopt_long(int, char * const *, const char *,\n\tconst struct option *, int *);\nint\tgetopt_long_only(int, char * const *, const char *,\n\tconst struct option *, int *);\n#ifndef _GETOPT_DECLARED\n#define\t_GETOPT_DECLARED\nint\t getopt(int, char * const [], const char *);\n\nextern char *optarg;\t\t\t/* getopt(3) external variables */\nextern int optind, opterr, optopt;\n#endif\n#ifndef _OPTRESET_DECLARED\n#define\t_OPTRESET_DECLARED\nextern int optreset;\t\t\t/* getopt(3) external variable */\n#endif\n__END_DECLS\n \n#endif /* !_GETOPT_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/grp.h",
    "content": "/*\t$OpenBSD: grp.h,v 1.8 2005/12/13 00:35:22 millert Exp $\t*/\n/*\t$NetBSD: grp.h,v 1.7 1995/04/29 05:30:40 cgd Exp $\t*/\n\n/*-\n * Copyright (c) 1989, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n * (c) UNIX System Laboratories, Inc.\n * All or some portions of this file are derived from material licensed\n * to the University of California by American Telephone and Telegraph\n * Co. or Unix System Laboratories, Inc. and are reproduced herein with\n * the permission of UNIX System Laboratories, Inc.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)grp.h\t8.2 (Berkeley) 1/21/94\n */\n\n#ifndef _GRP_H_\n#define\t_GRP_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\nstruct group {\n\tchar\t*gr_name;\t\t/* group name */\n\tchar\t*gr_passwd;\t\t/* group password */\n\tgid_t\tgr_gid;\t\t\t/* group id */\n\tchar\t**gr_mem;\t\t/* group members */\n};\n\n__BEGIN_DECLS\nstruct group\t*getgrgid(gid_t);\nstruct group\t*getgrnam(const char *);\n#if __POSIX_VISIBLE >= 200112 || __XPG_VISIBLE\nstruct group\t*getgrent(void)  __attribute__((deprecated(\"getgrent is meaningless on Android\")));\nvoid setgrent(void) __attribute__((deprecated(\"setgrent is meaningless on Android\")));\nvoid endgrent(void) __attribute__((deprecated(\"endgrent is meaningless on Android\")));\nint\t\t getgrgid_r(gid_t, struct group *, char *,\n\t\t    size_t, struct group **);\nint\t\t getgrnam_r(const char *, struct group *, char *,\n\t\t    size_t, struct group **);\n#endif\n\nint   getgrouplist (const char *user, gid_t group,\n                  gid_t *groups, int *ngroups);\n\nint   initgroups (const char *user, gid_t group);\n\n__END_DECLS\n\n#endif /* !_GRP_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/ifaddrs.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _IFADDRS_H_\n#define _IFADDRS_H_\n\n#include <sys/cdefs.h>\n#include <netinet/in.h>\n#include <sys/socket.h>\n\n__BEGIN_DECLS\n\nstruct ifaddrs {\n  struct ifaddrs* ifa_next;\n  char* ifa_name;\n  unsigned int ifa_flags;\n  struct sockaddr* ifa_addr;\n  struct sockaddr* ifa_netmask;\n  union {\n    struct sockaddr* ifu_broadaddr;\n    struct sockaddr* ifu_dstaddr;\n  } ifa_ifu;\n  void* ifa_data;\n};\n\n#define ifa_broadaddr ifa_ifu.ifu_broadaddr\n#define ifa_dstaddr ifa_ifu.ifu_dstaddr\n\nvoid freeifaddrs(struct ifaddrs*);\nint getifaddrs(struct ifaddrs**);\n\n__END_DECLS\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/inttypes.h",
    "content": "/*\t$OpenBSD: inttypes.h,v 1.9 2006/01/15 00:47:51 millert Exp $\t*/\n\n/*\n * Copyright (c) 1997, 2005 Todd C. Miller <Todd.Miller@courtesan.com>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n#ifndef\t_INTTYPES_H_\n#define\t_INTTYPES_H_\n\n#include <stdint.h>\n#include <sys/cdefs.h>\n\n#ifdef __LP64__\n#define __PRI_64_prefix  \"l\"\n#define __PRI_PTR_prefix \"l\"\n#else\n#define __PRI_64_prefix \"ll\"\n#define __PRI_PTR_prefix\n#endif\n\n/*\n * 7.8.1 Macros for format specifiers\n *\n * Each of the following object-like macros expands to a string\n * literal containing a conversion specifier, possibly modified by\n * a prefix such as hh, h, l, or ll, suitable for use within the\n * format argument of a formatted input/output function when\n * converting the corresponding integer type.  These macro names\n * have the general form of PRI (character string literals for the\n * fprintf family) or SCN (character string literals for the fscanf\n * family), followed by the conversion specifier, followed by a\n * name corresponding to a similar typedef name.  For example,\n * PRIdFAST32 can be used in a format string to print the value of\n * an integer of type int_fast32_t.\n */\n\n/* fprintf macros for signed integers */\n#define\tPRId8\t\t\t\"d\"\t\t/* int8_t */\n#define\tPRId16\t\t\t\"d\"\t\t/* int16_t */\n#define\tPRId32\t\t\t\"d\"\t\t/* int32_t */\n#define\tPRId64\t\t\t__PRI_64_prefix\"d\"\t\t/* int64_t */\n\n#define\tPRIdLEAST8\t\t\"d\"\t\t/* int_least8_t */\n#define\tPRIdLEAST16\t\t\"d\"\t\t/* int_least16_t */\n#define\tPRIdLEAST32\t\t\"d\"\t\t/* int_least32_t */\n#define\tPRIdLEAST64\t\t__PRI_64_prefix\"d\"\t\t/* int_least64_t */\n\n#define\tPRIdFAST8\t\t\"d\"\t\t/* int_fast8_t */\n#define\tPRIdFAST16\t\t\"d\"\t\t/* int_fast16_t */\n#define\tPRIdFAST32\t\t\"d\"\t\t/* int_fast32_t */\n#define\tPRIdFAST64\t\t__PRI_64_prefix\"d\"\t\t/* int_fast64_t */\n\n#define\tPRIdMAX\t\t\t\"jd\"\t\t/* intmax_t */\n#define\tPRIdPTR\t\t\t__PRI_PTR_prefix\"d\"\t\t/* intptr_t */\n\n#define\tPRIi8\t\t\t\"i\"\t\t/* int8_t */\n#define\tPRIi16\t\t\t\"i\"\t\t/* int16_t */\n#define\tPRIi32\t\t\t\"i\"\t\t/* int32_t */\n#define\tPRIi64\t\t\t__PRI_64_prefix\"i\"\t\t/* int64_t */\n\n#define\tPRIiLEAST8\t\t\"i\"\t\t/* int_least8_t */\n#define\tPRIiLEAST16\t\t\"i\"\t\t/* int_least16_t */\n#define\tPRIiLEAST32\t\t\"i\"\t\t/* int_least32_t */\n#define\tPRIiLEAST64\t\t__PRI_64_prefix\"i\"\t\t/* int_least64_t */\n\n#define\tPRIiFAST8\t\t\"i\"\t\t/* int_fast8_t */\n#define\tPRIiFAST16\t\t\"i\"\t\t/* int_fast16_t */\n#define\tPRIiFAST32\t\t\"i\"\t\t/* int_fast32_t */\n#define\tPRIiFAST64\t\t__PRI_64_prefix\"i\"\t\t/* int_fast64_t */\n\n#define\tPRIiMAX\t\t\t\"ji\"\t\t/* intmax_t */\n#define\tPRIiPTR\t\t\t__PRI_PTR_prefix\"i\"\t\t/* intptr_t */\n\n/* fprintf macros for unsigned integers */\n#define\tPRIo8\t\t\t\"o\"\t\t/* int8_t */\n#define\tPRIo16\t\t\t\"o\"\t\t/* int16_t */\n#define\tPRIo32\t\t\t\"o\"\t\t/* int32_t */\n#define\tPRIo64\t\t\t__PRI_64_prefix\"o\"\t\t/* int64_t */\n\n#define\tPRIoLEAST8\t\t\"o\"\t\t/* int_least8_t */\n#define\tPRIoLEAST16\t\t\"o\"\t\t/* int_least16_t */\n#define\tPRIoLEAST32\t\t\"o\"\t\t/* int_least32_t */\n#define\tPRIoLEAST64\t\t__PRI_64_prefix\"o\"\t\t/* int_least64_t */\n\n#define\tPRIoFAST8\t\t\"o\"\t\t/* int_fast8_t */\n#define\tPRIoFAST16\t\t\"o\"\t\t/* int_fast16_t */\n#define\tPRIoFAST32\t\t\"o\"\t\t/* int_fast32_t */\n#define\tPRIoFAST64\t\t__PRI_64_prefix\"o\"\t\t/* int_fast64_t */\n\n#define\tPRIoMAX\t\t\t\"jo\"\t\t/* intmax_t */\n#define\tPRIoPTR\t\t\t__PRI_PTR_prefix\"o\"\t\t/* intptr_t */\n\n#define\tPRIu8\t\t\t\"u\"\t\t/* uint8_t */\n#define\tPRIu16\t\t\t\"u\"\t\t/* uint16_t */\n#define\tPRIu32\t\t\t\"u\"\t\t/* uint32_t */\n#define\tPRIu64\t\t\t__PRI_64_prefix\"u\"\t\t/* uint64_t */\n\n#define\tPRIuLEAST8\t\t\"u\"\t\t/* uint_least8_t */\n#define\tPRIuLEAST16\t\t\"u\"\t\t/* uint_least16_t */\n#define\tPRIuLEAST32\t\t\"u\"\t\t/* uint_least32_t */\n#define\tPRIuLEAST64\t\t__PRI_64_prefix\"u\"\t\t/* uint_least64_t */\n\n#define\tPRIuFAST8\t\t\"u\"\t\t/* uint_fast8_t */\n#define\tPRIuFAST16\t\t\"u\"\t\t/* uint_fast16_t */\n#define\tPRIuFAST32\t\t\"u\"\t\t/* uint_fast32_t */\n#define\tPRIuFAST64\t\t__PRI_64_prefix\"u\"\t\t/* uint_fast64_t */\n\n#define\tPRIuMAX\t\t\t\"ju\"\t\t/* uintmax_t */\n#define\tPRIuPTR\t\t\t__PRI_PTR_prefix\"u\"\t\t/* uintptr_t */\n\n#define\tPRIx8\t\t\t\"x\"\t\t/* uint8_t */\n#define\tPRIx16\t\t\t\"x\"\t\t/* uint16_t */\n#define\tPRIx32\t\t\t\"x\"\t\t/* uint32_t */\n#define\tPRIx64\t\t\t__PRI_64_prefix\"x\"\t\t/* uint64_t */\n\n#define\tPRIxLEAST8\t\t\"x\"\t\t/* uint_least8_t */\n#define\tPRIxLEAST16\t\t\"x\"\t\t/* uint_least16_t */\n#define\tPRIxLEAST32\t\t\"x\"\t\t/* uint_least32_t */\n#define\tPRIxLEAST64\t\t__PRI_64_prefix\"x\"\t\t/* uint_least64_t */\n\n#define\tPRIxFAST8\t\t\"x\"\t\t/* uint_fast8_t */\n#define\tPRIxFAST16\t\t\"x\"\t\t/* uint_fast16_t */\n#define\tPRIxFAST32\t\t\"x\"\t\t/* uint_fast32_t */\n#define\tPRIxFAST64\t\t__PRI_64_prefix\"x\"\t\t/* uint_fast64_t */\n\n#define\tPRIxMAX\t\t\t\"jx\"\t\t/* uintmax_t */\n#define\tPRIxPTR\t\t\t__PRI_PTR_prefix\"x\"\t\t/* uintptr_t */\n\n#define\tPRIX8\t\t\t\"X\"\t\t/* uint8_t */\n#define\tPRIX16\t\t\t\"X\"\t\t/* uint16_t */\n#define\tPRIX32\t\t\t\"X\"\t\t/* uint32_t */\n#define\tPRIX64\t\t\t__PRI_64_prefix\"X\"\t\t/* uint64_t */\n\n#define\tPRIXLEAST8\t\t\"X\"\t\t/* uint_least8_t */\n#define\tPRIXLEAST16\t\t\"X\"\t\t/* uint_least16_t */\n#define\tPRIXLEAST32\t\t\"X\"\t\t/* uint_least32_t */\n#define\tPRIXLEAST64\t\t__PRI_64_prefix\"X\"\t\t/* uint_least64_t */\n\n#define\tPRIXFAST8\t\t\"X\"\t\t/* uint_fast8_t */\n#define\tPRIXFAST16\t\t\"X\"\t\t/* uint_fast16_t */\n#define\tPRIXFAST32\t\t\"X\"\t\t/* uint_fast32_t */\n#define\tPRIXFAST64\t\t__PRI_64_prefix\"X\"\t\t/* uint_fast64_t */\n\n#define\tPRIXMAX\t\t\t\"jX\"\t\t/* uintmax_t */\n#define\tPRIXPTR\t\t\t__PRI_PTR_prefix\"X\"\t\t/* uintptr_t */\n\n/* fscanf macros for signed integers */\n#define\tSCNd8\t\t\t\"hhd\"\t\t/* int8_t */\n#define\tSCNd16\t\t\t\"hd\"\t\t/* int16_t */\n#define\tSCNd32\t\t\t\"d\"\t\t/* int32_t */\n#define\tSCNd64\t\t\t__PRI_64_prefix\"d\"\t\t/* int64_t */\n\n#define\tSCNdLEAST8\t\t\"hhd\"\t\t/* int_least8_t */\n#define\tSCNdLEAST16\t\t\"hd\"\t\t/* int_least16_t */\n#define\tSCNdLEAST32\t\t\"d\"\t\t/* int_least32_t */\n#define\tSCNdLEAST64\t\t__PRI_64_prefix\"d\"\t\t/* int_least64_t */\n\n#define\tSCNdFAST8\t\t\"hhd\"\t\t/* int_fast8_t */\n#define\tSCNdFAST16\t\t\"hd\"\t\t/* int_fast16_t */\n#define\tSCNdFAST32\t\t\"d\"\t\t/* int_fast32_t */\n#define\tSCNdFAST64\t\t__PRI_64_prefix\"d\"\t\t/* int_fast64_t */\n\n#define\tSCNdMAX\t\t\t\"jd\"\t\t/* intmax_t */\n#define\tSCNdPTR\t\t\t__PRI_PTR_prefix\"d\"\t\t/* intptr_t */\n\n#define\tSCNi8\t\t\t\"hhi\"\t\t/* int8_t */\n#define\tSCNi16\t\t\t\"hi\"\t\t/* int16_t */\n#define\tSCNi32\t\t\t\"i\"\t\t/* int32_t */\n#define\tSCNi64\t\t\t__PRI_64_prefix\"i\"\t\t/* int64_t */\n\n#define\tSCNiLEAST8\t\t\"hhi\"\t\t/* int_least8_t */\n#define\tSCNiLEAST16\t\t\"hi\"\t\t/* int_least16_t */\n#define\tSCNiLEAST32\t\t\"i\"\t\t/* int_least32_t */\n#define\tSCNiLEAST64\t\t__PRI_64_prefix\"i\"\t\t/* int_least64_t */\n\n#define\tSCNiFAST8\t\t\"hhi\"\t\t/* int_fast8_t */\n#define\tSCNiFAST16\t\t\"hi\"\t\t/* int_fast16_t */\n#define\tSCNiFAST32\t\t\"i\"\t\t/* int_fast32_t */\n#define\tSCNiFAST64\t\t__PRI_64_prefix\"i\"\t\t/* int_fast64_t */\n\n#define\tSCNiMAX\t\t\t\"ji\"\t\t/* intmax_t */\n#define\tSCNiPTR\t\t\t__PRI_PTR_prefix\"i\"\t\t/* intptr_t */\n\n/* fscanf macros for unsigned integers */\n#define\tSCNo8\t\t\t\"hho\"\t\t/* uint8_t */\n#define\tSCNo16\t\t\t\"ho\"\t\t/* uint16_t */\n#define\tSCNo32\t\t\t\"o\"\t\t/* uint32_t */\n#define\tSCNo64\t\t\t__PRI_64_prefix\"o\"\t\t/* uint64_t */\n\n#define\tSCNoLEAST8\t\t\"hho\"\t\t/* uint_least8_t */\n#define\tSCNoLEAST16\t\t\"ho\"\t\t/* uint_least16_t */\n#define\tSCNoLEAST32\t\t\"o\"\t\t/* uint_least32_t */\n#define\tSCNoLEAST64\t\t__PRI_64_prefix\"o\"\t\t/* uint_least64_t */\n\n#define\tSCNoFAST8\t\t\"hho\"\t\t/* uint_fast8_t */\n#define\tSCNoFAST16\t\t\"ho\"\t\t/* uint_fast16_t */\n#define\tSCNoFAST32\t\t\"o\"\t\t/* uint_fast32_t */\n#define\tSCNoFAST64\t\t__PRI_64_prefix\"o\"\t\t/* uint_fast64_t */\n\n#define\tSCNoMAX\t\t\t\"jo\"\t\t/* uintmax_t */\n#define\tSCNoPTR\t\t\t__PRI_PTR_prefix\"o\"\t\t/* uintptr_t */\n\n#define\tSCNu8\t\t\t\"hhu\"\t\t/* uint8_t */\n#define\tSCNu16\t\t\t\"hu\"\t\t/* uint16_t */\n#define\tSCNu32\t\t\t\"u\"\t\t/* uint32_t */\n#define\tSCNu64\t\t\t__PRI_64_prefix\"u\"\t\t/* uint64_t */\n\n#define\tSCNuLEAST8\t\t\"hhu\"\t\t/* uint_least8_t */\n#define\tSCNuLEAST16\t\t\"hu\"\t\t/* uint_least16_t */\n#define\tSCNuLEAST32\t\t\"u\"\t\t/* uint_least32_t */\n#define\tSCNuLEAST64\t\t__PRI_64_prefix\"u\"\t\t/* uint_least64_t */\n\n#define\tSCNuFAST8\t\t\"hhu\"\t\t/* uint_fast8_t */\n#define\tSCNuFAST16\t\t\"hu\"\t\t/* uint_fast16_t */\n#define\tSCNuFAST32\t\t\"u\"\t\t/* uint_fast32_t */\n#define\tSCNuFAST64\t\t__PRI_64_prefix\"u\"\t\t/* uint_fast64_t */\n\n#define\tSCNuMAX\t\t\t\"ju\"\t\t/* uintmax_t */\n#define\tSCNuPTR\t\t\t__PRI_PTR_prefix\"u\"\t\t/* uintptr_t */\n\n#define\tSCNx8\t\t\t\"hhx\"\t\t/* uint8_t */\n#define\tSCNx16\t\t\t\"hx\"\t\t/* uint16_t */\n#define\tSCNx32\t\t\t\"x\"\t\t/* uint32_t */\n#define\tSCNx64\t\t\t__PRI_64_prefix\"x\"\t\t/* uint64_t */\n\n#define\tSCNxLEAST8\t\t\"hhx\"\t\t/* uint_least8_t */\n#define\tSCNxLEAST16\t\t\"hx\"\t\t/* uint_least16_t */\n#define\tSCNxLEAST32\t\t\"x\"\t\t/* uint_least32_t */\n#define\tSCNxLEAST64\t\t__PRI_64_prefix\"x\"\t\t/* uint_least64_t */\n\n#define\tSCNxFAST8\t\t\"hhx\"\t\t/* uint_fast8_t */\n#define\tSCNxFAST16\t\t\"hx\"\t\t/* uint_fast16_t */\n#define\tSCNxFAST32\t\t\"x\"\t\t/* uint_fast32_t */\n#define\tSCNxFAST64\t\t__PRI_64_prefix\"x\"\t\t/* uint_fast64_t */\n\n#define\tSCNxMAX\t\t\t\"jx\"\t\t/* uintmax_t */\n#define\tSCNxPTR\t\t\t__PRI_PTR_prefix\"x\"\t\t/* uintptr_t */\n\ntypedef struct {\n\tintmax_t quot;\t\t/* quotient */\n\tintmax_t rem;\t\t/* remainder */\n} imaxdiv_t;\n\n__BEGIN_DECLS\nintmax_t\timaxabs(intmax_t) __pure2;\nimaxdiv_t\timaxdiv(intmax_t, intmax_t) __pure2;\nintmax_t\tstrtoimax(const char *, char **, int);\nuintmax_t\tstrtoumax(const char *, char **, int);\nintmax_t\twcstoimax(const wchar_t * __restrict,\n\t\t    wchar_t ** __restrict, int);\nuintmax_t\twcstoumax(const wchar_t * __restrict,\n\t\t    wchar_t ** __restrict, int);\n__END_DECLS\n\n#endif /* _INTTYPES_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/lastlog.h",
    "content": ""
  },
  {
    "path": "atlas-aapt/bionic/libc/include/libgen.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _LIBGEN_H\n#define _LIBGEN_H\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n\n__BEGIN_DECLS\n\n/*\n * Including <string.h> will get you the GNU basename, unless <libgen.h> is\n * included, either before or after including <string.h>.\n *\n * Note that this has the wrong argument cv-qualifiers, but doesn't modify its\n * input and uses thread-local storage for the result if necessary.\n */\nextern char* __posix_basename(const char*) __RENAME(basename);\n\n#define basename __posix_basename\n\n/* This has the wrong argument cv-qualifiers, but doesn't modify its input and uses thread-local storage for the result if necessary. */\nextern char* dirname(const char*);\n\n#if !defined(__LP64__)\n/* These non-standard functions are not needed on Android; basename and dirname use thread-local storage. */\nextern int dirname_r(const char*, char*, size_t);\nextern int basename_r(const char*, char*, size_t);\n#endif\n\n__END_DECLS\n\n#endif /* _LIBGEN_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/limits.h",
    "content": "/*\t$OpenBSD: limits.h,v 1.13 2005/12/31 19:29:38 millert Exp $\t*/\n/*\t$NetBSD: limits.h,v 1.7 1994/10/26 00:56:00 cgd Exp $\t*/\n\n/*\n * Copyright (c) 1988 The Regents of the University of California.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)limits.h\t5.9 (Berkeley) 4/3/91\n */\n\n#ifndef _LIMITS_H_\n#define\t_LIMITS_H_\n\n#include <sys/cdefs.h>\n\n#if __XPG_VISIBLE\n#define PASS_MAX\t\t128\t/* _PASSWORD_LEN from <pwd.h> */\n\n#define NL_ARGMAX\t\t9\n#define NL_LANGMAX\t\t14\n#define NL_MSGMAX\t\t32767\n#define NL_NMAX\t\t\t1\n#define NL_SETMAX\t\t255\n#define NL_TEXTMAX\t\t255\n\n#define TMP_MAX                 308915776\n#endif /* __XPG_VISIBLE */\n\n#include <sys/limits.h>\n\n#if __POSIX_VISIBLE\n#include <sys/syslimits.h>\n#endif\n\n/* GLibc compatibility definitions.\n   Note that these are defined by GCC's <limits.h>\n   only when __GNU_LIBRARY__ is defined, i.e. when\n   targetting GLibc. */\n#ifndef LONG_LONG_MIN\n#define LONG_LONG_MIN  LLONG_MIN\n#endif\n\n#ifndef LONG_LONG_MAX\n#define LONG_LONG_MAX  LLONG_MAX\n#endif\n\n#ifndef ULONG_LONG_MAX\n#define ULONG_LONG_MAX  ULLONG_MAX\n#endif\n\n/* BSD compatibility definitions. */\n#if __BSD_VISIBLE\n#define SIZE_T_MAX ULONG_MAX\n#endif /* __BSD_VISIBLE */\n\n#define SSIZE_MAX LONG_MAX\n\n#define MB_LEN_MAX 4\n\n#define SEM_VALUE_MAX 0x3fffffff\n\n/* POSIX says these belong in <unistd.h> but BSD has some in <limits.h>. */\n#include <bits/posix_limits.h>\n\n#define HOST_NAME_MAX _POSIX_HOST_NAME_MAX\n#endif /* !_LIMITS_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/link.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _LINK_H_\n#define _LINK_H_\n\n#include <sys/types.h>\n#include <elf.h>\n\n__BEGIN_DECLS\n\n#if __LP64__\n#define ElfW(type) Elf64_ ## type\n#else\n#define ElfW(type) Elf32_ ## type\n#endif\n\nstruct dl_phdr_info {\n  ElfW(Addr) dlpi_addr;\n  const char* dlpi_name;\n  const ElfW(Phdr)* dlpi_phdr;\n  ElfW(Half) dlpi_phnum;\n};\n\nint dl_iterate_phdr(int (*)(struct dl_phdr_info*, size_t, void*), void*);\n\n#ifdef __arm__\ntypedef long unsigned int* _Unwind_Ptr;\n_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr, int*);\n#endif\n\n/* Used by the dynamic linker to communicate with the debugger. */\nstruct link_map {\n  ElfW(Addr) l_addr;\n  char* l_name;\n  ElfW(Dyn)* l_ld;\n  struct link_map* l_next;\n  struct link_map* l_prev;\n};\n\n/* Used by the dynamic linker to communicate with the debugger. */\nstruct r_debug {\n  int32_t r_version;\n  struct link_map* r_map;\n  ElfW(Addr) r_brk;\n  enum {\n    RT_CONSISTENT,\n    RT_ADD,\n    RT_DELETE\n  } r_state;\n  ElfW(Addr) r_ldbase;\n};\n\n__END_DECLS\n\n#endif /* _LINK_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/locale.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _LOCALE_H_\n#define _LOCALE_H_\n\n#include <sys/cdefs.h>\n#include <xlocale.h>\n\n__BEGIN_DECLS\n\n#define LC_CTYPE           0\n#define LC_NUMERIC         1\n#define LC_TIME            2\n#define LC_COLLATE         3\n#define LC_MONETARY        4\n#define LC_MESSAGES        5\n#define LC_ALL             6\n#define LC_PAPER           7\n#define LC_NAME            8\n#define LC_ADDRESS         9\n#define LC_TELEPHONE      10\n#define LC_MEASUREMENT    11\n#define LC_IDENTIFICATION 12\n\n#define LC_CTYPE_MASK          (1 << LC_CTYPE)\n#define LC_NUMERIC_MASK        (1 << LC_NUMERIC)\n#define LC_TIME_MASK           (1 << LC_TIME)\n#define LC_COLLATE_MASK        (1 << LC_COLLATE)\n#define LC_MONETARY_MASK       (1 << LC_MONETARY)\n#define LC_MESSAGES_MASK       (1 << LC_MESSAGES)\n#define LC_PAPER_MASK          (1 << LC_PAPER)\n#define LC_NAME_MASK           (1 << LC_NAME)\n#define LC_ADDRESS_MASK        (1 << LC_ADDRESS)\n#define LC_TELEPHONE_MASK      (1 << LC_TELEPHONE)\n#define LC_MEASUREMENT_MASK    (1 << LC_MEASUREMENT)\n#define LC_IDENTIFICATION_MASK (1 << LC_IDENTIFICATION)\n\n#define LC_ALL_MASK (LC_CTYPE_MASK | LC_NUMERIC_MASK | LC_TIME_MASK | LC_COLLATE_MASK | \\\n                     LC_MONETARY_MASK | LC_MESSAGES_MASK | LC_PAPER_MASK | LC_NAME_MASK | \\\n                     LC_ADDRESS_MASK | LC_TELEPHONE_MASK | LC_MEASUREMENT_MASK | \\\n                     LC_IDENTIFICATION_MASK)\n\nstruct lconv {\n    char* decimal_point;\n    char* thousands_sep;\n    char* grouping;\n    char* int_curr_symbol;\n    char* currency_symbol;\n    char* mon_decimal_point;\n    char* mon_thousands_sep;\n    char* mon_grouping;\n    char* positive_sign;\n    char* negative_sign;\n    char  int_frac_digits;\n    char  frac_digits;\n    char  p_cs_precedes;\n    char  p_sep_by_space;\n    char  n_cs_precedes;\n    char  n_sep_by_space;\n    char  p_sign_posn;\n    char  n_sign_posn;\n    char  int_p_cs_precedes;\n    char  int_p_sep_by_space;\n    char  int_n_cs_precedes;\n    char  int_n_sep_by_space;\n    char  int_p_sign_posn;\n    char  int_n_sign_posn;\n};\n\nstruct lconv* localeconv(void);\n\nlocale_t duplocale(locale_t);\nvoid freelocale(locale_t);\nlocale_t newlocale(int, const char*, locale_t);\nchar* setlocale(int, const char*);\nlocale_t uselocale(locale_t);\n\n#define LC_GLOBAL_LOCALE ((locale_t) -1L)\n\n__END_DECLS\n\n#endif /* _LOCALE_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/machine/endian.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _MACHINE_ENDIAN_H_\n#define _MACHINE_ENDIAN_H_\n\n/* This file is for BSD source compatibility only. Use <endian.h> or <sys/endian.h> instead. */\n#include <sys/endian.h>\n\n#endif /* _MACHINE_ENDIAN_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/machine/ieee.h",
    "content": "/*\t$OpenBSD: ieee.h,v 1.4 2011/11/08 17:06:51 deraadt Exp $\t*/\n/*\t$NetBSD: ieee.h,v 1.2 2001/02/21 17:43:50 bjh21 Exp $\t*/\n\n/*\n * Copyright (c) 1992, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * This software was developed by the Computer Systems Engineering group\n * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and\n * contributed to Berkeley.\n *\n * All advertising materials mentioning features or use of this software\n * must display the following acknowledgement:\n *\tThis product includes software developed by the University of\n *\tCalifornia, Lawrence Berkeley Laboratory.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. All advertising materials mentioning features or use of this software\n *    must display the following acknowledgement:\n *\tThis product includes software developed by the University of\n *\tCalifornia, Berkeley and its contributors.\n * 4. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)ieee.h\t8.1 (Berkeley) 6/11/93\n */\n\n#ifndef _MACHINE_IEEE_H_\n#define _MACHINE_IEEE_H_\n\n#include <sys/types.h>\n\n__BEGIN_DECLS\n\n#define SNG_EXPBITS\t8\n#define SNG_FRACBITS\t23\n\n#define SNG_EXP_INFNAN\t255\n#define SNG_EXP_BIAS\t127\n\nstruct ieee_single {\n  unsigned sng_frac:23;\n  unsigned sng_exp:8;\n  unsigned sng_sign:1;\n};\n\n#define DBL_EXPBITS\t11\n#define DBL_FRACHBITS\t20\n#define DBL_FRACLBITS\t32\n#define DBL_FRACBITS\t52\n\n#define DBL_EXP_INFNAN\t2047\n#define DBL_EXP_BIAS\t1023\n\nstruct ieee_double {\n  unsigned dbl_fracl;\n  unsigned dbl_frach:20;\n  unsigned dbl_exp:11;\n  unsigned dbl_sign:1;\n};\n\n#if __LP64__\n\n/* 64-bit Android uses ld128 long doubles. */\n\n#define EXT_EXPBITS\t15\n#define EXT_FRACHBITS\t16\n#define EXT_FRACHMBITS\t32\n#define EXT_FRACLMBITS\t32\n#define EXT_FRACLBITS\t32\n#define EXT_FRACBITS\t112\n\n#define EXT_EXP_INFNAN\t32767\n#define EXT_EXP_BIAS\t16383\n\n#define EXT_IMPLICIT_NBIT\n\n#define EXT_TO_ARRAY32(p, a) do { \\\n  (a)[0] = (uint32_t)(p)->ext_fracl; \\\n  (a)[1] = (uint32_t)(p)->ext_fraclm; \\\n  (a)[2] = (uint32_t)(p)->ext_frachm; \\\n  (a)[3] = (uint32_t)(p)->ext_frach; \\\n} while(0)\n\nstruct ieee_ext {\n  unsigned ext_fracl;\n  unsigned ext_fraclm;\n  unsigned ext_frachm;\n  unsigned ext_frach:16;\n  unsigned ext_exp:15;\n  unsigned ext_sign:1;\n};\n\n#endif\n\n__END_DECLS\n\n#endif /* _MACHINE_IEEE_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/malloc.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef LIBC_INCLUDE_MALLOC_H_\n#define LIBC_INCLUDE_MALLOC_H_\n\n#include <sys/cdefs.h>\n#include <stddef.h>\n#include <stdio.h>\n\n__BEGIN_DECLS\n\nextern void* malloc(size_t byte_count) __mallocfunc __wur __attribute__((alloc_size(1)));\nextern void* calloc(size_t item_count, size_t item_size) __mallocfunc __wur __attribute__((alloc_size(1,2)));\nextern void* realloc(void* p, size_t byte_count) __wur __attribute__((alloc_size(2)));\nextern void free(void* p);\n\nextern void* memalign(size_t alignment, size_t byte_count) __mallocfunc __wur __attribute__((alloc_size(2)));\nextern size_t malloc_usable_size(const void* p);\n\n#ifndef STRUCT_MALLINFO_DECLARED\n#define STRUCT_MALLINFO_DECLARED 1\nstruct mallinfo {\n  size_t arena;    /* Total number of non-mmapped bytes currently allocated from OS. */\n  size_t ordblks;  /* Number of free chunks. */\n  size_t smblks;   /* (Unused.) */\n  size_t hblks;    /* (Unused.) */\n  size_t hblkhd;   /* Total number of bytes in mmapped regions. */\n  size_t usmblks;  /* Maximum total allocated space; greater than total if trimming has occurred. */\n  size_t fsmblks;  /* (Unused.) */\n  size_t uordblks; /* Total allocated space (normal or mmapped.) */\n  size_t fordblks; /* Total free space. */\n  size_t keepcost; /* Upper bound on number of bytes releasable by malloc_trim. */\n};\n#endif  /* STRUCT_MALLINFO_DECLARED */\n\nextern struct mallinfo mallinfo(void);\n\n/*\n * XML structure for malloc_info(3) is in the following format:\n *\n * <malloc version=\"jemalloc-1\">\n *   <heap nr=\"INT\">\n *     <allocated-large>INT</allocated-large>\n *     <allocated-huge>INT</allocated-huge>\n *     <allocated-bins>INT</allocated-bins>\n *     <bins-total>INT</bins-total>\n *     <bin nr=\"INT\">\n *       <allocated>INT</allocated>\n *       <nmalloc>INT</nmalloc>\n *       <ndalloc>INT</ndalloc>\n *     </bin>\n *     <!-- more bins -->\n *   </heap>\n *   <!-- more heaps -->\n * </malloc>\n */\nextern int malloc_info(int, FILE *);\n\n__END_DECLS\n\n#endif  /* LIBC_INCLUDE_MALLOC_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/memory.h",
    "content": "#include <string.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/mntent.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _MNTENT_H_\n#define _MNTENT_H_\n\n#include <stdio.h>\n#include <sys/cdefs.h>\n#include <paths.h>  /* for _PATH_MOUNTED */\n\n#define MOUNTED _PATH_MOUNTED\n#define MNTTYPE_IGNORE \"ignore\"\n\nstruct mntent {\n  char* mnt_fsname;\n  char* mnt_dir;\n  char* mnt_type;\n  char* mnt_opts;\n  int mnt_freq;\n  int mnt_passno;\n};\n\n__BEGIN_DECLS\n\nint endmntent(FILE*);\nstruct mntent* getmntent(FILE*);\nstruct mntent* getmntent_r(FILE*, struct mntent*, char*, int);\nFILE* setmntent(const char*, const char*);\n\n__END_DECLS\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/net/ethernet.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _NET_ETHERNET_H_\n#define _NET_ETHERNET_H_\n\n#include <linux/if_ether.h>\n#include <net/if_ether.h>\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/net/ethertypes.h",
    "content": "/*\t$NetBSD: ethertypes.h,v 1.17 2005/12/10 23:21:38 elad Exp $\t*/\n\n/*\n * Copyright (c) 1982, 1986, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)if_ether.h\t8.1 (Berkeley) 6/10/93\n */\n\n/*\n * Ethernet protocol types.\n *\n * According to \"assigned numbers\", the Ethernet protocol numbers are also\n * used as ARP protocol type numbers.\n *\n * I factor them out here to avoid pulling all the Ethernet header file\n * into the hardware independent ARP code. -is\n *\n * Additional sources of information:\n *\thttp://www.mit.edu/~map/Ethernet/Ethernet.txt\n *\tftp://venera.isi.edu/in-notes/iana/assignments/ethernet-numbers\n *\n */\n\n#ifndef _NET_ETHERTYPES_H_\n#define\t_NET_ETHERTYPES_H_\n\n/*\n *  NOTE: 0x0000-0x05DC (0..1500) are generally IEEE 802.3 length fields.\n *  However, there are some conflicts.\n */\n\n#define\tETHERTYPE_8023\t\t0x0004\t/* IEEE 802.3 packet */\n\t\t   /* 0x0101 .. 0x1FF\t   Experimental */\n#define\tETHERTYPE_PUP\t\t0x0200\t/* Xerox PUP protocol - see 0A00 */\n#define\tETHERTYPE_PUPAT\t\t0x0200\t/* PUP Address Translation - see 0A01 */\n#define\tETHERTYPE_SPRITE\t0x0500\t/* ??? */\n\t\t\t     /* 0x0400\t   Nixdorf */\n#define\tETHERTYPE_NS\t\t0x0600\t/* XNS */\n#define\tETHERTYPE_NSAT\t\t0x0601\t/* XNS Address Translation (3Mb only) */\n#define\tETHERTYPE_DLOG1 \t0x0660\t/* DLOG (?) */\n#define\tETHERTYPE_DLOG2 \t0x0661\t/* DLOG (?) */\n#define\tETHERTYPE_IP\t\t0x0800\t/* IP protocol */\n#define\tETHERTYPE_X75\t\t0x0801\t/* X.75 Internet */\n#define\tETHERTYPE_NBS\t\t0x0802\t/* NBS Internet */\n#define\tETHERTYPE_ECMA\t\t0x0803\t/* ECMA Internet */\n#define\tETHERTYPE_CHAOS \t0x0804\t/* CHAOSnet */\n#define\tETHERTYPE_X25\t\t0x0805\t/* X.25 Level 3 */\n#define\tETHERTYPE_ARP\t\t0x0806\t/* Address resolution protocol */\n#define\tETHERTYPE_NSCOMPAT\t0x0807\t/* XNS Compatibility */\n#define\tETHERTYPE_FRARP \t0x0808\t/* Frame Relay ARP (RFC1701) */\n\t\t\t     /* 0x081C\t   Symbolics Private */\n\t\t    /* 0x0888 - 0x088A\t   Xyplex */\n#define\tETHERTYPE_UBDEBUG\t0x0900\t/* Ungermann-Bass network debugger */\n#define\tETHERTYPE_IEEEPUP\t0x0A00\t/* Xerox IEEE802.3 PUP */\n#define\tETHERTYPE_IEEEPUPAT\t0x0A01\t/* Xerox IEEE802.3 PUP Address Translation */\n#define\tETHERTYPE_VINES \t0x0BAD\t/* Banyan VINES */\n#define\tETHERTYPE_VINESLOOP\t0x0BAE\t/* Banyan VINES Loopback */\n#define\tETHERTYPE_VINESECHO\t0x0BAF\t/* Banyan VINES Echo */\n\n/*\t\t       0x1000 - 0x100F\t   Berkeley Trailer */\n/*\n * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have\n * (type-ETHERTYPE_TRAIL)*512 bytes of data followed\n * by an ETHER type (as given above) and then the (variable-length) header.\n */\n#define\tETHERTYPE_TRAIL\t\t0x1000\t/* Trailer packet */\n#define\tETHERTYPE_NTRAILER\t16\n\n#define\tETHERTYPE_DCA\t\t0x1234\t/* DCA - Multicast */\n#define\tETHERTYPE_VALID \t0x1600\t/* VALID system protocol */\n#define\tETHERTYPE_DOGFIGHT\t0x1989\t/* Artificial Horizons (\"Aviator\" dogfight simulator [on Sun]) */\n#define\tETHERTYPE_RCL\t\t0x1995\t/* Datapoint Corporation (RCL lan protocol) */\n\n\t\t\t\t\t/* The following 3C0x types\n\t\t\t\t\t   are unregistered: */\n#define\tETHERTYPE_NBPVCD\t0x3C00\t/* 3Com NBP virtual circuit datagram (like XNS SPP) not registered */\n#define\tETHERTYPE_NBPSCD\t0x3C01\t/* 3Com NBP System control datagram not registered */\n#define\tETHERTYPE_NBPCREQ\t0x3C02\t/* 3Com NBP Connect request (virtual cct) not registered */\n#define\tETHERTYPE_NBPCRSP\t0x3C03\t/* 3Com NBP Connect repsonse not registered */\n#define\tETHERTYPE_NBPCC\t\t0x3C04\t/* 3Com NBP Connect complete not registered */\n#define\tETHERTYPE_NBPCLREQ\t0x3C05\t/* 3Com NBP Close request (virtual cct) not registered */\n#define\tETHERTYPE_NBPCLRSP\t0x3C06\t/* 3Com NBP Close response not registered */\n#define\tETHERTYPE_NBPDG\t\t0x3C07\t/* 3Com NBP Datagram (like XNS IDP) not registered */\n#define\tETHERTYPE_NBPDGB\t0x3C08\t/* 3Com NBP Datagram broadcast not registered */\n#define\tETHERTYPE_NBPCLAIM\t0x3C09\t/* 3Com NBP Claim NetBIOS name not registered */\n#define\tETHERTYPE_NBPDLTE\t0x3C0A\t/* 3Com NBP Delete Netbios name not registered */\n#define\tETHERTYPE_NBPRAS\t0x3C0B\t/* 3Com NBP Remote adaptor status request not registered */\n#define\tETHERTYPE_NBPRAR\t0x3C0C\t/* 3Com NBP Remote adaptor response not registered */\n#define\tETHERTYPE_NBPRST\t0x3C0D\t/* 3Com NBP Reset not registered */\n\n#define\tETHERTYPE_PCS\t\t0x4242\t/* PCS Basic Block Protocol */\n#define\tETHERTYPE_IMLBLDIAG\t0x424C\t/* Information Modes Little Big LAN diagnostic */\n#define\tETHERTYPE_DIDDLE\t0x4321\t/* THD - Diddle */\n#define\tETHERTYPE_IMLBL\t\t0x4C42\t/* Information Modes Little Big LAN */\n#define\tETHERTYPE_SIMNET\t0x5208\t/* BBN Simnet Private */\n#define\tETHERTYPE_DECEXPER\t0x6000\t/* DEC Unassigned, experimental */\n#define\tETHERTYPE_MOPDL\t\t0x6001\t/* DEC MOP dump/load */\n#define\tETHERTYPE_MOPRC\t\t0x6002\t/* DEC MOP remote console */\n#define\tETHERTYPE_DECnet\t0x6003\t/* DEC DECNET Phase IV route */\n#define\tETHERTYPE_DN\t\tETHERTYPE_DECnet\t/* libpcap, tcpdump */\n#define\tETHERTYPE_LAT\t\t0x6004\t/* DEC LAT */\n#define\tETHERTYPE_DECDIAG\t0x6005\t/* DEC diagnostic protocol (at interface initialization?) */\n#define\tETHERTYPE_DECCUST\t0x6006\t/* DEC customer protocol */\n#define\tETHERTYPE_SCA\t\t0x6007\t/* DEC LAVC, SCA */\n#define\tETHERTYPE_AMBER\t\t0x6008\t/* DEC AMBER */\n#define\tETHERTYPE_DECMUMPS\t0x6009\t/* DEC MUMPS */\n\t\t    /* 0x6010 - 0x6014\t   3Com Corporation */\n#define\tETHERTYPE_TRANSETHER\t0x6558\t/* Trans Ether Bridging (RFC1701)*/\n#define\tETHERTYPE_RAWFR\t\t0x6559\t/* Raw Frame Relay (RFC1701) */\n#define\tETHERTYPE_UBDL\t\t0x7000\t/* Ungermann-Bass download */\n#define\tETHERTYPE_UBNIU\t\t0x7001\t/* Ungermann-Bass NIUs */\n#define\tETHERTYPE_UBDIAGLOOP\t0x7002\t/* Ungermann-Bass diagnostic/loopback */\n#define\tETHERTYPE_UBNMC\t\t0x7003\t/* Ungermann-Bass ??? (NMC to/from UB Bridge) */\n#define\tETHERTYPE_UBBST\t\t0x7005\t/* Ungermann-Bass Bridge Spanning Tree */\n#define\tETHERTYPE_OS9\t\t0x7007\t/* OS/9 Microware */\n#define\tETHERTYPE_OS9NET\t0x7009\t/* OS/9 Net? */\n\t\t    /* 0x7020 - 0x7029\t   LRT (England) (now Sintrom) */\n#define\tETHERTYPE_RACAL\t\t0x7030\t/* Racal-Interlan */\n#define\tETHERTYPE_PRIMENTS\t0x7031\t/* Prime NTS (Network Terminal Service) */\n#define\tETHERTYPE_CABLETRON\t0x7034\t/* Cabletron */\n#define\tETHERTYPE_CRONUSVLN\t0x8003\t/* Cronus VLN */\n#define\tETHERTYPE_CRONUS\t0x8004\t/* Cronus Direct */\n#define\tETHERTYPE_HP\t\t0x8005\t/* HP Probe */\n#define\tETHERTYPE_NESTAR\t0x8006\t/* Nestar */\n#define\tETHERTYPE_ATTSTANFORD\t0x8008\t/* AT&T/Stanford (local use) */\n#define\tETHERTYPE_EXCELAN\t0x8010\t/* Excelan */\n#define\tETHERTYPE_SG_DIAG\t0x8013\t/* SGI diagnostic type */\n#define\tETHERTYPE_SG_NETGAMES\t0x8014\t/* SGI network games */\n#define\tETHERTYPE_SG_RESV\t0x8015\t/* SGI reserved type */\n#define\tETHERTYPE_SG_BOUNCE\t0x8016\t/* SGI bounce server */\n#define\tETHERTYPE_APOLLODOMAIN\t0x8019\t/* Apollo DOMAIN */\n#define\tETHERTYPE_TYMSHARE\t0x802E\t/* Tymeshare */\n#define\tETHERTYPE_TIGAN\t\t0x802F\t/* Tigan, Inc. */\n#define\tETHERTYPE_REVARP\t0x8035\t/* Reverse addr resolution protocol */\n#define\tETHERTYPE_AEONIC\t0x8036\t/* Aeonic Systems */\n#define\tETHERTYPE_IPXNEW\t0x8037\t/* IPX (Novell Netware?) */\n#define\tETHERTYPE_LANBRIDGE\t0x8038\t/* DEC LANBridge */\n#define\tETHERTYPE_DSMD\t0x8039\t/* DEC DSM/DDP */\n#define\tETHERTYPE_ARGONAUT\t0x803A\t/* DEC Argonaut Console */\n#define\tETHERTYPE_VAXELN\t0x803B\t/* DEC VAXELN */\n#define\tETHERTYPE_DECDNS\t0x803C\t/* DEC DNS Naming Service */\n#define\tETHERTYPE_ENCRYPT\t0x803D\t/* DEC Ethernet Encryption */\n#define\tETHERTYPE_DECDTS\t0x803E\t/* DEC Distributed Time Service */\n#define\tETHERTYPE_DECLTM\t0x803F\t/* DEC LAN Traffic Monitor */\n#define\tETHERTYPE_DECNETBIOS\t0x8040\t/* DEC PATHWORKS DECnet NETBIOS Emulation */\n#define\tETHERTYPE_DECLAST\t0x8041\t/* DEC Local Area System Transport */\n\t\t\t     /* 0x8042\t   DEC Unassigned */\n#define\tETHERTYPE_PLANNING\t0x8044\t/* Planning Research Corp. */\n\t\t    /* 0x8046 - 0x8047\t   AT&T */\n#define\tETHERTYPE_DECAM\t\t0x8048\t/* DEC Availability Manager for Distributed Systems DECamds (but someone at DEC says not) */\n#define\tETHERTYPE_EXPERDATA\t0x8049\t/* ExperData */\n#define\tETHERTYPE_VEXP\t\t0x805B\t/* Stanford V Kernel exp. */\n#define\tETHERTYPE_VPROD\t\t0x805C\t/* Stanford V Kernel prod. */\n#define\tETHERTYPE_ES\t\t0x805D\t/* Evans & Sutherland */\n#define\tETHERTYPE_LITTLE\t0x8060\t/* Little Machines */\n#define\tETHERTYPE_COUNTERPOINT\t0x8062\t/* Counterpoint Computers */\n\t\t    /* 0x8065 - 0x8066\t   Univ. of Mass @ Amherst */\n#define\tETHERTYPE_VEECO\t\t0x8067\t/* Veeco Integrated Auto. */\n#define\tETHERTYPE_GENDYN\t0x8068\t/* General Dynamics */\n#define\tETHERTYPE_ATT\t\t0x8069\t/* AT&T */\n#define\tETHERTYPE_AUTOPHON\t0x806A\t/* Autophon */\n#define\tETHERTYPE_COMDESIGN\t0x806C\t/* ComDesign */\n#define\tETHERTYPE_COMPUGRAPHIC\t0x806D\t/* Compugraphic Corporation */\n\t\t    /* 0x806E - 0x8077\t   Landmark Graphics Corp. */\n#define\tETHERTYPE_MATRA\t\t0x807A\t/* Matra */\n#define\tETHERTYPE_DDE\t\t0x807B\t/* Dansk Data Elektronik */\n#define\tETHERTYPE_MERIT\t\t0x807C\t/* Merit Internodal (or Univ of Michigan?) */\n\t\t    /* 0x807D - 0x807F\t   Vitalink Communications */\n#define\tETHERTYPE_VLTLMAN\t0x8080\t/* Vitalink TransLAN III Management */\n\t\t    /* 0x8081 - 0x8083\t   Counterpoint Computers */\n\t\t    /* 0x8088 - 0x808A\t   Xyplex */\n#define\tETHERTYPE_ATALK\t\t0x809B\t/* AppleTalk */\n#define\tETHERTYPE_AT\t\tETHERTYPE_ATALK\t\t/* old NetBSD */\n#define\tETHERTYPE_APPLETALK\tETHERTYPE_ATALK\t\t/* HP-UX */\n\t\t    /* 0x809C - 0x809E\t   Datability */\n#define\tETHERTYPE_SPIDER\t0x809F\t/* Spider Systems Ltd. */\n\t\t\t     /* 0x80A3\t   Nixdorf */\n\t\t    /* 0x80A4 - 0x80B3\t   Siemens Gammasonics Inc. */\n\t\t    /* 0x80C0 - 0x80C3\t   DCA (Digital Comm. Assoc.) Data Exchange Cluster */\n\t\t    /* 0x80C4 - 0x80C5\t   Banyan Systems */\n#define\tETHERTYPE_PACER\t\t0x80C6\t/* Pacer Software */\n#define\tETHERTYPE_APPLITEK\t0x80C7\t/* Applitek Corporation */\n\t\t    /* 0x80C8 - 0x80CC\t   Intergraph Corporation */\n\t\t    /* 0x80CD - 0x80CE\t   Harris Corporation */\n\t\t    /* 0x80CF - 0x80D2\t   Taylor Instrument */\n\t\t    /* 0x80D3 - 0x80D4\t   Rosemount Corporation */\n#define\tETHERTYPE_SNA\t\t0x80D5\t/* IBM SNA Services over Ethernet */\n#define\tETHERTYPE_VARIAN\t0x80DD\t/* Varian Associates */\n\t\t    /* 0x80DE - 0x80DF\t   TRFS (Integrated Solutions Transparent Remote File System) */\n\t\t    /* 0x80E0 - 0x80E3\t   Allen-Bradley */\n\t\t    /* 0x80E4 - 0x80F0\t   Datability */\n#define\tETHERTYPE_RETIX\t\t0x80F2\t/* Retix */\n#define\tETHERTYPE_AARP\t\t0x80F3\t/* AppleTalk AARP */\n\t\t    /* 0x80F4 - 0x80F5\t   Kinetics */\n#define\tETHERTYPE_APOLLO\t0x80F7\t/* Apollo Computer */\n#define ETHERTYPE_VLAN\t\t0x8100\t/* IEEE 802.1Q VLAN tagging (XXX conflicts) */\n\t\t    /* 0x80FF - 0x8101\t   Wellfleet Communications (XXX conflicts) */\n#define\tETHERTYPE_BOFL\t\t0x8102\t/* Wellfleet; BOFL (Breath OF Life) pkts [every 5-10 secs.] */\n#define\tETHERTYPE_WELLFLEET\t0x8103\t/* Wellfleet Communications */\n\t\t    /* 0x8107 - 0x8109\t   Symbolics Private */\n#define\tETHERTYPE_TALARIS\t0x812B\t/* Talaris */\n#define\tETHERTYPE_WATERLOO\t0x8130\t/* Waterloo Microsystems Inc. (XXX which?) */\n#define\tETHERTYPE_HAYES\t\t0x8130\t/* Hayes Microcomputers (XXX which?) */\n#define\tETHERTYPE_VGLAB\t\t0x8131\t/* VG Laboratory Systems */\n\t\t    /* 0x8132 - 0x8137\t   Bridge Communications */\n#define\tETHERTYPE_IPX\t\t0x8137\t/* Novell (old) NetWare IPX (ECONFIG E option) */\n#define\tETHERTYPE_NOVELL\t0x8138\t/* Novell, Inc. */\n\t\t    /* 0x8139 - 0x813D\t   KTI */\n#define\tETHERTYPE_MUMPS\t\t0x813F\t/* M/MUMPS data sharing */\n#define\tETHERTYPE_AMOEBA\t0x8145\t/* Vrije Universiteit (NL) Amoeba 4 RPC (obsolete) */\n#define\tETHERTYPE_FLIP\t\t0x8146\t/* Vrije Universiteit (NL) FLIP (Fast Local Internet Protocol) */\n#define\tETHERTYPE_VURESERVED\t0x8147\t/* Vrije Universiteit (NL) [reserved] */\n#define\tETHERTYPE_LOGICRAFT\t0x8148\t/* Logicraft */\n#define\tETHERTYPE_NCD\t\t0x8149\t/* Network Computing Devices */\n#define\tETHERTYPE_ALPHA\t\t0x814A\t/* Alpha Micro */\n#define\tETHERTYPE_SNMP\t\t0x814C\t/* SNMP over Ethernet (see RFC1089) */\n\t\t    /* 0x814D - 0x814E\t   BIIN */\n#define\tETHERTYPE_TEC\t0x814F\t/* Technically Elite Concepts */\n#define\tETHERTYPE_RATIONAL\t0x8150\t/* Rational Corp */\n\t\t    /* 0x8151 - 0x8153\t   Qualcomm */\n\t\t    /* 0x815C - 0x815E\t   Computer Protocol Pty Ltd */\n\t\t    /* 0x8164 - 0x8166\t   Charles River Data Systems */\n#define\tETHERTYPE_XTP\t\t0x817D\t/* Protocol Engines XTP */\n#define\tETHERTYPE_SGITW\t\t0x817E\t/* SGI/Time Warner prop. */\n#define\tETHERTYPE_HIPPI_FP\t0x8180\t/* HIPPI-FP encapsulation */\n#define\tETHERTYPE_STP\t\t0x8181\t/* Scheduled Transfer STP, HIPPI-ST */\n\t\t    /* 0x8182 - 0x8183\t   Reserved for HIPPI-6400 */\n\t\t    /* 0x8184 - 0x818C\t   SGI prop. */\n#define\tETHERTYPE_MOTOROLA\t0x818D\t/* Motorola */\n#define\tETHERTYPE_NETBEUI\t0x8191\t/* PowerLAN NetBIOS/NetBEUI (PC) */\n\t\t    /* 0x819A - 0x81A3\t   RAD Network Devices */\n\t\t    /* 0x81B7 - 0x81B9\t   Xyplex */\n\t\t    /* 0x81CC - 0x81D5\t   Apricot Computers */\n\t\t    /* 0x81D6 - 0x81DD\t   Artisoft Lantastic */\n\t\t    /* 0x81E6 - 0x81EF\t   Polygon */\n\t\t    /* 0x81F0 - 0x81F2\t   Comsat Labs */\n\t\t    /* 0x81F3 - 0x81F5\t   SAIC */\n\t\t    /* 0x81F6 - 0x81F8\t   VG Analytical */\n\t\t    /* 0x8203 - 0x8205\t   QNX Software Systems Ltd. */\n\t\t    /* 0x8221 - 0x8222\t   Ascom Banking Systems */\n\t\t    /* 0x823E - 0x8240\t   Advanced Encryption Systems */\n\t\t    /* 0x8263 - 0x826A\t   Charles River Data Systems */\n\t\t    /* 0x827F - 0x8282\t   Athena Programming */\n\t\t    /* 0x829A - 0x829B\t   Inst Ind Info Tech */\n\t\t    /* 0x829C - 0x82AB\t   Taurus Controls */\n\t\t    /* 0x82AC - 0x8693\t   Walker Richer & Quinn */\n#define\tETHERTYPE_ACCTON\t0x8390\t/* Accton Technologies (unregistered) */\n#define\tETHERTYPE_TALARISMC\t0x852B\t/* Talaris multicast */\n#define\tETHERTYPE_KALPANA\t0x8582\t/* Kalpana */\n\t\t    /* 0x8694 - 0x869D\t   Idea Courier */\n\t\t    /* 0x869E - 0x86A1\t   Computer Network Tech */\n\t\t    /* 0x86A3 - 0x86AC\t   Gateway Communications */\n#define\tETHERTYPE_SECTRA\t0x86DB\t/* SECTRA */\n#define\tETHERTYPE_IPV6\t\t0x86DD\t/* IP protocol version 6 */\n#define\tETHERTYPE_DELTACON\t0x86DE\t/* Delta Controls */\n#define\tETHERTYPE_ATOMIC\t0x86DF\t/* ATOMIC */\n\t\t    /* 0x86E0 - 0x86EF\t   Landis & Gyr Powers */\n\t\t    /* 0x8700 - 0x8710\t   Motorola */\n#define\tETHERTYPE_RDP\t\t0x8739\t/* Control Technology Inc. RDP Without IP */\n#define\tETHERTYPE_MICP\t\t0x873A\t/* Control Technology Inc. Mcast Industrial Ctrl Proto. */\n\t\t    /* 0x873B - 0x873C\t   Control Technology Inc. Proprietary */\n#define\tETHERTYPE_TCPCOMP\t0x876B\t/* TCP/IP Compression (RFC1701) */\n#define\tETHERTYPE_IPAS\t\t0x876C\t/* IP Autonomous Systems (RFC1701) */\n#define\tETHERTYPE_SECUREDATA\t0x876D\t/* Secure Data (RFC1701) */\n#define\tETHERTYPE_FLOWCONTROL\t0x8808\t/* 802.3x flow control packet */\n#define\tETHERTYPE_SLOWPROTOCOLS\t0x8809\t/* Slow protocols */\n#define\tETHERTYPE_PPP\t\t0x880B\t/* PPP (obsolete by PPPOE) */\n#define\tETHERTYPE_HITACHI\t0x8820\t/* Hitachi Cable (Optoelectronic Systems Laboratory) */\n#define\tETHERTYPE_MPLS\t\t0x8847\t/* MPLS Unicast */\n#define\tETHERTYPE_MPLS_MCAST\t0x8848\t/* MPLS Multicast */\n#define\tETHERTYPE_AXIS\t\t0x8856\t/* Axis Communications AB proprietary bootstrap/config */\n#define\tETHERTYPE_PPPOEDISC\t0x8863\t/* PPP Over Ethernet Discovery Stage */\n#define\tETHERTYPE_PPPOE\t\t0x8864\t/* PPP Over Ethernet Session Stage */\n#define\tETHERTYPE_LANPROBE\t0x8888\t/* HP LanProbe test? */\n#define\tETHERTYPE_PAE\t\t0x888e\t/* EAPOL PAE/802.1x */\n#define\tETHERTYPE_LOOPBACK\t0x9000\t/* Loopback */\n#define\tETHERTYPE_LBACK\t\tETHERTYPE_LOOPBACK\t/* DEC MOP loopback */\n#define\tETHERTYPE_XNSSM\t\t0x9001\t/* 3Com (Formerly Bridge Communications), XNS Systems Management */\n#define\tETHERTYPE_TCPSM\t\t0x9002\t/* 3Com (Formerly Bridge Communications), TCP/IP Systems Management */\n#define\tETHERTYPE_BCLOOP\t0x9003\t/* 3Com (Formerly Bridge Communications), loopback detection */\n#define\tETHERTYPE_DEBNI\t\t0xAAAA\t/* DECNET? Used by VAX 6220 DEBNI */\n#define\tETHERTYPE_SONIX\t\t0xFAF5\t/* Sonix Arpeggio */\n#define\tETHERTYPE_VITAL\t\t0xFF00\t/* BBN VITAL-LanBridge cache wakeups */\n\t\t    /* 0xFF00 - 0xFFOF\t   ISC Bunker Ramo */\n\n#define\tETHERTYPE_MAX\t\t0xFFFF\t/* Maximum valid ethernet type, reserved */\n\n#endif /* !_NET_ETHERTYPES_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/net/if.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _NET_IF_H_\n#define _NET_IF_H_\n\n#include <sys/socket.h>\n#include <linux/if.h>\n#include <sys/cdefs.h>\n\n#ifndef IF_NAMESIZE\n#define IF_NAMESIZE IFNAMSIZ\n#endif\n\n__BEGIN_DECLS\n\nstruct if_nameindex {\n  unsigned if_index;\n  char* if_name;\n};\n\nchar* if_indextoname(unsigned, char*);\nunsigned if_nametoindex(const char*);\nstruct if_nameindex* if_nameindex(void);\nvoid if_freenameindex(struct if_nameindex*);\n\n__END_DECLS\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/net/if_arp.h",
    "content": "#include <sys/socket.h>\n#include <linux/if_arp.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/net/if_ether.h",
    "content": "/*\t$NetBSD: if_ether.h,v 1.43 2006/11/24 01:04:30 rpaulo Exp $\t*/\n\n/*\n * Copyright (c) 1982, 1986, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)if_ether.h\t8.1 (Berkeley) 6/10/93\n */\n\n#ifndef _NET_IF_ETHER_H_\n#define _NET_IF_ETHER_H_\n\n#include <sys/types.h>\n\n#ifdef _KERNEL\n#ifdef _KERNEL_OPT\n#include \"opt_mbuftrace.h\"\n#endif\n#include <sys/mbuf.h>\n#endif\n\n/*\n * Some basic Ethernet constants.\n */\n#define\tETHER_ADDR_LEN\t6\t/* length of an Ethernet address */\n#define\tETHER_TYPE_LEN\t2\t/* length of the Ethernet type field */\n#define\tETHER_CRC_LEN\t4\t/* length of the Ethernet CRC */\n#define\tETHER_HDR_LEN\t((ETHER_ADDR_LEN * 2) + ETHER_TYPE_LEN)\n#define\tETHER_MIN_LEN\t64\t/* minimum frame length, including CRC */\n#define\tETHER_MAX_LEN\t1518\t/* maximum frame length, including CRC */\n#define\tETHER_MAX_LEN_JUMBO 9018 /* maximum jumbo frame len, including CRC */\n\n/*\n * Some Ethernet extensions.\n */\n#define\tETHER_VLAN_ENCAP_LEN 4\t/* length of 802.1Q VLAN encapsulation */\n\n/*\n * Ethernet address - 6 octets\n * this is only used by the ethers(3) functions.\n */\nstruct ether_addr {\n\tu_int8_t ether_addr_octet[ETHER_ADDR_LEN];\n} __attribute__((__packed__));\n\n/*\n * Structure of a 10Mb/s Ethernet header.\n */\nstruct\tether_header {\n\tu_int8_t  ether_dhost[ETHER_ADDR_LEN];\n\tu_int8_t  ether_shost[ETHER_ADDR_LEN];\n\tu_int16_t ether_type;\n} __attribute__((__packed__));\n\n#include <net/ethertypes.h>\n\n#define\tETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */\n\n#define\tETHERMTU_JUMBO\t(ETHER_MAX_LEN_JUMBO - ETHER_HDR_LEN - ETHER_CRC_LEN)\n#define\tETHERMTU\t(ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)\n#define\tETHERMIN\t(ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)\n\n/*\n * Compute the maximum frame size based on ethertype (i.e. possible\n * encapsulation) and whether or not an FCS is present.\n */\n#define\tETHER_MAX_FRAME(ifp, etype, hasfcs)\t\t\t\t\\\n\t((ifp)->if_mtu + ETHER_HDR_LEN +\t\t\t\t\\\n\t ((hasfcs) ? ETHER_CRC_LEN : 0) +\t\t\t\t\\\n\t (((etype) == ETHERTYPE_VLAN) ? ETHER_VLAN_ENCAP_LEN : 0))\n\n/*\n * Ethernet CRC32 polynomials (big- and little-endian verions).\n */\n#define\tETHER_CRC_POLY_LE\t0xedb88320\n#define\tETHER_CRC_POLY_BE\t0x04c11db6\n\n#ifndef _STANDALONE\n\n/*\n * Ethernet-specific mbuf flags.\n */\n#define\tM_HASFCS\tM_LINK0\t/* FCS included at end of frame */\n#define\tM_PROMISC\tM_LINK1\t/* this packet is not for us */\n\n#ifdef _KERNEL\n/*\n * Macro to map an IP multicast address to an Ethernet multicast address.\n * The high-order 25 bits of the Ethernet address are statically assigned,\n * and the low-order 23 bits are taken from the low end of the IP address.\n */\n#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr)\t\t\t\t\\\n\t/* struct in_addr *ipaddr; */\t\t\t\t\t\\\n\t/* u_int8_t enaddr[ETHER_ADDR_LEN]; */\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\t(enaddr)[0] = 0x01;\t\t\t\t\t\t\\\n\t(enaddr)[1] = 0x00;\t\t\t\t\t\t\\\n\t(enaddr)[2] = 0x5e;\t\t\t\t\t\t\\\n\t(enaddr)[3] = ((u_int8_t *)ipaddr)[1] & 0x7f;\t\t\t\\\n\t(enaddr)[4] = ((u_int8_t *)ipaddr)[2];\t\t\t\t\\\n\t(enaddr)[5] = ((u_int8_t *)ipaddr)[3];\t\t\t\t\\\n}\n/*\n * Macro to map an IP6 multicast address to an Ethernet multicast address.\n * The high-order 16 bits of the Ethernet address are statically assigned,\n * and the low-order 32 bits are taken from the low end of the IP6 address.\n */\n#define ETHER_MAP_IPV6_MULTICAST(ip6addr, enaddr)\t\t\t\\\n\t/* struct in6_addr *ip6addr; */\t\t\t\t\t\\\n\t/* u_int8_t enaddr[ETHER_ADDR_LEN]; */\t\t\t\t\\\n{                                                                       \\\n\t(enaddr)[0] = 0x33;\t\t\t\t\t\t\\\n\t(enaddr)[1] = 0x33;\t\t\t\t\t\t\\\n\t(enaddr)[2] = ((u_int8_t *)ip6addr)[12];\t\t\t\\\n\t(enaddr)[3] = ((u_int8_t *)ip6addr)[13];\t\t\t\\\n\t(enaddr)[4] = ((u_int8_t *)ip6addr)[14];\t\t\t\\\n\t(enaddr)[5] = ((u_int8_t *)ip6addr)[15];\t\t\t\\\n}\n#endif\n\n#define\tETHERCAP_VLAN_MTU\t0x00000001\t/* VLAN-compatible MTU */\n#define\tETHERCAP_VLAN_HWTAGGING\t0x00000002\t/* hardware VLAN tag support */\n#define\tETHERCAP_JUMBO_MTU\t0x00000004\t/* 9000 byte MTU supported */\n\n#ifdef\t_KERNEL\nextern const uint8_t etherbroadcastaddr[ETHER_ADDR_LEN];\nextern const uint8_t ethermulticastaddr_slowprotocols[ETHER_ADDR_LEN];\nextern const uint8_t ether_ipmulticast_min[ETHER_ADDR_LEN];\nextern const uint8_t ether_ipmulticast_max[ETHER_ADDR_LEN];\n\nint\tether_ioctl(struct ifnet *, u_long, caddr_t);\nint\tether_addmulti (struct ifreq *, struct ethercom *);\nint\tether_delmulti (struct ifreq *, struct ethercom *);\nint\tether_changeaddr (struct ifreq *, struct ethercom *);\nint\tether_multiaddr(struct sockaddr *, u_int8_t[], u_int8_t[]);\n\n/*\n * Ethernet 802.1Q VLAN structures.\n */\n\n/* add VLAN tag to input/received packet */\n#define\tVLAN_INPUT_TAG(ifp, m, vlanid, _errcase)\t\\\n\tdo {\t\t\t\t\t\t\t\t\\\n                struct m_tag *mtag =\t\t\t\t\t\\\n                    m_tag_get(PACKET_TAG_VLAN, sizeof(u_int), M_NOWAIT);\\\n                if (mtag == NULL) {\t\t\t\t\t\\\n\t\t\tifp->if_ierrors++;\t\t\t\t\\\n                        printf(\"%s: unable to allocate VLAN tag\\n\",\t\\\n                            ifp->if_xname);\t\t\t\t\\\n                        m_freem(m);\t\t\t\t\t\\\n                        _errcase;\t\t\t\t\t\\\n                }\t\t\t\t\t\t\t\\\n                *(u_int *)(mtag + 1) = vlanid;\t\t\t\t\\\n                m_tag_prepend(m, mtag);\t\t\t\t\t\\\n\t} while(0)\n\n/* extract VLAN tag from output/trasmit packet */\n#define VLAN_OUTPUT_TAG(ec, m0)\t\t\t\\\n\tVLAN_ATTACHED(ec) ? m_tag_find((m0), PACKET_TAG_VLAN, NULL) : NULL\n\n/* extract VLAN ID value from a VLAN tag */\n#define VLAN_TAG_VALUE(mtag)\t\\\n\t((*(u_int *)(mtag + 1)) & 4095)\n\n/* test if any VLAN is configured for this interface */\n#define VLAN_ATTACHED(ec)\t((ec)->ec_nvlans > 0)\n\nvoid\tether_ifattach(struct ifnet *, const u_int8_t *);\nvoid\tether_ifdetach(struct ifnet *);\n\nchar\t*ether_sprintf(const u_int8_t *);\nchar\t*ether_snprintf(char *, size_t, const u_int8_t *);\n\nu_int32_t ether_crc32_le(const u_int8_t *, size_t);\nu_int32_t ether_crc32_be(const u_int8_t *, size_t);\n\nint\tether_nonstatic_aton(u_char *, char *);\n#else\n/*\n * Prototype ethers(3) functions.\n */\n#include <sys/cdefs.h>\n__BEGIN_DECLS\nchar *\tether_ntoa __P((const struct ether_addr *));\nstruct ether_addr *\n\tether_aton __P((const char *));\nint\tether_ntohost __P((char *, const struct ether_addr *));\nint\tether_hostton __P((const char *, struct ether_addr *));\nint\tether_line __P((const char *, struct ether_addr *, char *));\n__END_DECLS\n#endif\n\n#endif /* _STANDALONE */\n\n#endif /* !_NET_IF_ETHER_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/net/if_ieee1394.h",
    "content": "/*\t$NetBSD: if_ieee1394.h,v 1.6 2005/12/10 23:21:38 elad Exp $\t*/\n\n/*\n * Copyright (c) 2000 The NetBSD Foundation, Inc.\n * All rights reserved.\n *\n * This code is derived from software contributed to The NetBSD Foundation\n * by Atsushi Onoe.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. All advertising materials mentioning features or use of this software\n *    must display the following acknowledgement:\n *\tThis product includes software developed by the NetBSD\n *\tFoundation, Inc. and its contributors.\n * 4. Neither the name of The NetBSD Foundation nor the names of its\n *    contributors may be used to endorse or promote products derived\n *    from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS\n * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\n * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS\n * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n * POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef _NET_IF_IEEE1394_H_\n#define _NET_IF_IEEE1394_H_\n\n/* hardware address information for arp / nd */\nstruct ieee1394_hwaddr {\n\tu_int8_t\tiha_uid[8];\t\t/* node unique ID */\n\tu_int8_t\tiha_maxrec;\t\t/* max_rec in the config ROM */\n\tu_int8_t\tiha_speed;\t\t/* min of link/PHY speed */\n\tu_int8_t\tiha_offset[6];\t\t/* unicast FIFO address */\n};\n\n/*\n * BPF wants to see one of these.\n */\nstruct ieee1394_bpfhdr {\n\tuint8_t\t\tibh_dhost[8];\n\tuint8_t\t\tibh_shost[8];\n\tuint16_t\tibh_type;\n};\n\n#ifdef _KERNEL\n\n/* pseudo header */\nstruct ieee1394_header {\n\tu_int8_t\tih_uid[8];\t\t/* dst/src uid */\n\tu_int8_t\tih_maxrec;\t\t/* dst maxrec for tx */\n\tu_int8_t\tih_speed;\t\t/* speed */\n\tu_int8_t\tih_offset[6];\t\t/* dst offset */\n};\n\n/* unfragment encapsulation header */\nstruct ieee1394_unfraghdr {\n\tu_int16_t\tiuh_ft;\t\t\t/* fragment type == 0 */\n\tu_int16_t\tiuh_etype;\t\t/* ether_type */\n};\n\n/* fragmented encapsulation header */\nstruct ieee1394_fraghdr {\n\tu_int16_t\tifh_ft_size;\t\t/* fragment type, data size-1 */\n\tu_int16_t\tifh_etype_off;\t\t/* etype for first fragment */\n\t\t\t\t\t\t/* offset for subseq frag */\n\tu_int16_t\tifh_dgl;\t\t/* datagram label */\n\tu_int16_t\tifh_reserved;\n};\n\n#define\tIEEE1394_FT_SUBSEQ\t0x8000\n#define\tIEEE1394_FT_MORE\t0x4000\n\n#define\tIEEE1394MTU\t\t1500\n\n#define\tIEEE1394_GASP_LEN\t8\t\t/* GASP header for Stream */\n#define\tIEEE1394_ADDR_LEN\t8\n#define\tIEEE1394_CRC_LEN\t4\n\nstruct ieee1394_reass_pkt {\n\tLIST_ENTRY(ieee1394_reass_pkt) rp_next;\n\tstruct mbuf\t*rp_m;\n\tu_int16_t\trp_size;\n\tu_int16_t\trp_etype;\n\tu_int16_t\trp_off;\n\tu_int16_t\trp_dgl;\n\tu_int16_t\trp_len;\n\tu_int16_t\trp_ttl;\n};\n\nstruct ieee1394_reassq {\n\tLIST_ENTRY(ieee1394_reassq) rq_node;\n\tLIST_HEAD(, ieee1394_reass_pkt) rq_pkt;\n\tu_int32_t\tfr_id;\n};\n\nstruct ieee1394com {\n\tstruct ifnet\tfc_if;\n\tstruct ieee1394_hwaddr ic_hwaddr;\n\tu_int16_t\tic_dgl;\n\tLIST_HEAD(, ieee1394_reassq) ic_reassq;\n};\n\nconst char *ieee1394_sprintf(const u_int8_t *);\nvoid ieee1394_input(struct ifnet *, struct mbuf *, u_int16_t);\nvoid ieee1394_ifattach(struct ifnet *, const struct ieee1394_hwaddr *);\nvoid ieee1394_ifdetach(struct ifnet *);\nint  ieee1394_ioctl(struct ifnet *, u_long, caddr_t);\nstruct mbuf * ieee1394_fragment(struct ifnet *, struct mbuf *, int, u_int16_t);\nvoid ieee1394_drain(struct ifnet *);\nvoid ieee1394_watchdog(struct ifnet *);\n#endif /* _KERNEL */\n\n#endif /* !_NET_IF_IEEE1394_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/net/if_packet.h",
    "content": "#include <linux/if_packet.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/net/if_types.h",
    "content": "/*\t$NetBSD: if_types.h,v 1.26 2012/08/05 21:21:41 wiz Exp $\t*/\n\n/*\n * Copyright (c) 1989, 1993, 1994\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)if_types.h\t8.3 (Berkeley) 4/28/95\n */\n\n#ifndef _NET_IF_TYPES_H_\n#define _NET_IF_TYPES_H_\n\n/*\n * Interface types for benefit of parsing media address headers.\n * This list is derived from the SNMP list of ifTypes, originally\n * documented in RFC1573, now maintained as:\n *\n * <URL:http://www.iana.org/assignments/smi-numbers>\n */\n\n#define\tIFT_OTHER\t0x1\t\t/* none of the following */\n#define\tIFT_1822\t0x2\t\t/* old-style arpanet imp */\n#define\tIFT_HDH1822\t0x3\t\t/* HDH arpanet imp */\n#define\tIFT_X25DDN\t0x4\t\t/* x25 to imp */\n#define\tIFT_X25\t\t0x5\t\t/* PDN X25 interface (RFC877) */\n#define\tIFT_ETHER\t0x6\t\t/* Ethernet CSMA/CD */\n#define\tIFT_ISO88023\t0x7\t\t/* CSMA/CD */\n#define\tIFT_ISO88024\t0x8\t\t/* Token Bus */\n#define\tIFT_ISO88025\t0x9\t\t/* Token Ring */\n#define\tIFT_ISO88026\t0xa\t\t/* MAN */\n#define\tIFT_STARLAN\t0xb\n#define\tIFT_P10\t\t0xc\t\t/* Proteon 10MBit ring */\n#define\tIFT_P80\t\t0xd\t\t/* Proteon 80MBit ring */\n#define\tIFT_HY\t\t0xe\t\t/* Hyperchannel */\n#define\tIFT_FDDI\t0xf\n#define\tIFT_LAPB\t0x10\n#define\tIFT_SDLC\t0x11\n#define\tIFT_T1\t\t0x12\n#define\tIFT_CEPT\t0x13\t\t/* E1 - european T1 */\n#define\tIFT_ISDNBASIC\t0x14\n#define\tIFT_ISDNPRIMARY\t0x15\n#define\tIFT_PTPSERIAL\t0x16\t\t/* Proprietary PTP serial */\n#define\tIFT_PPP\t\t0x17\t\t/* RFC 1331 */\n#define\tIFT_LOOP\t0x18\t\t/* loopback */\n#define\tIFT_EON\t\t0x19\t\t/* ISO over IP */\n#define\tIFT_XETHER\t0x1a\t\t/* obsolete 3MB experimental ethernet */\n#define\tIFT_NSIP\t0x1b\t\t/* XNS over IP */\n#define\tIFT_SLIP\t0x1c\t\t/* IP over generic TTY */\n#define\tIFT_ULTRA\t0x1d\t\t/* Ultra Technologies */\n#define\tIFT_DS3\t\t0x1e\t\t/* Generic T3 */\n#define\tIFT_SIP\t\t0x1f\t\t/* SMDS */\n#define\tIFT_FRELAY\t0x20\t\t/* Frame Relay DTE only */\n#define\tIFT_RS232\t0x21\n#define\tIFT_PARA\t0x22\t\t/* parallel-port */\n#define\tIFT_ARCNET\t0x23\n#define\tIFT_ARCNETPLUS\t0x24\n#define\tIFT_ATM\t\t0x25\t\t/* ATM cells */\n#define\tIFT_MIOX25\t0x26\n#define\tIFT_SONET\t0x27\t\t/* SONET or SDH */\n#define\tIFT_X25PLE\t0x28\n#define\tIFT_ISO88022LLC\t0x29\n#define\tIFT_LOCALTALK\t0x2a\n#define\tIFT_SMDSDXI\t0x2b\n#define\tIFT_FRELAYDCE\t0x2c\t\t/* Frame Relay DCE */\n#define\tIFT_V35\t\t0x2d\n#define\tIFT_HSSI\t0x2e\n#define\tIFT_HIPPI\t0x2f\n#define\tIFT_MODEM\t0x30\t\t/* Generic Modem */\n#define\tIFT_AAL5\t0x31\t\t/* AAL5 over ATM */\n#define\tIFT_SONETPATH\t0x32\n#define\tIFT_SONETVT\t0x33\n#define\tIFT_SMDSICIP\t0x34\t\t/* SMDS InterCarrier Interface */\n#define\tIFT_PROPVIRTUAL\t0x35\t\t/* Proprietary Virtual/internal */\n#define\tIFT_PROPMUX\t0x36\t\t/* Proprietary Multiplexing */\n#define IFT_IEEE80212\t\t   0x37 /* 100BaseVG */\n#define IFT_FIBRECHANNEL\t   0x38 /* Fibre Channel */\n#define IFT_HIPPIINTERFACE\t   0x39 /* HIPPI interfaces\t */\n#define IFT_FRAMERELAYINTERCONNECT 0x3a /* Obsolete, use either 0x20 or 0x2c */\n#define IFT_AFLANE8023\t\t   0x3b /* ATM Emulated LAN for 802.3 */\n#define IFT_AFLANE8025\t\t   0x3c /* ATM Emulated LAN for 802.5 */\n#define IFT_CCTEMUL\t\t   0x3d /* ATM Emulated circuit\t\t  */\n#define IFT_FASTETHER\t\t   0x3e /* Fast Ethernet (100BaseT) */\n#define IFT_ISDN\t\t   0x3f /* ISDN and X.25\t    */\n#define IFT_V11\t\t\t   0x40 /* CCITT V.11/X.21\t\t*/\n#define IFT_V36\t\t\t   0x41 /* CCITT V.36\t\t\t*/\n#define IFT_G703AT64K\t\t   0x42 /* CCITT G703 at 64Kbps */\n#define IFT_G703AT2MB\t\t   0x43 /* Obsolete see DS1-MIB */\n#define IFT_QLLC\t\t   0x44 /* SNA QLLC\t\t\t*/\n#define IFT_FASTETHERFX\t\t   0x45 /* Fast Ethernet (100BaseFX)\t*/\n#define IFT_CHANNEL\t\t   0x46 /* channel\t\t\t*/\n#define IFT_IEEE80211\t\t   0x47 /* radio spread spectrum\t*/\n#define IFT_IBM370PARCHAN\t   0x48 /* IBM System 360/370 OEMI Channel */\n#define IFT_ESCON\t\t   0x49 /* IBM Enterprise Systems Connection */\n#define IFT_DLSW\t\t   0x4a /* Data Link Switching */\n#define IFT_ISDNS\t\t   0x4b /* ISDN S/T interface */\n#define IFT_ISDNU\t\t   0x4c /* ISDN U interface */\n#define IFT_LAPD\t\t   0x4d /* Link Access Protocol D */\n#define IFT_IPSWITCH\t\t   0x4e /* IP Switching Objects */\n#define IFT_RSRB\t\t   0x4f /* Remote Source Route Bridging */\n#define IFT_ATMLOGICAL\t\t   0x50 /* ATM Logical Port */\n#define IFT_DS0\t\t\t   0x51 /* Digital Signal Level 0 */\n#define IFT_DS0BUNDLE\t\t   0x52 /* group of ds0s on the same ds1 */\n#define IFT_BSC\t\t\t   0x53 /* Bisynchronous Protocol */\n#define IFT_ASYNC\t\t   0x54 /* Asynchronous Protocol */\n#define IFT_CNR\t\t\t   0x55 /* Combat Net Radio */\n#define IFT_ISO88025DTR\t\t   0x56 /* ISO 802.5r DTR */\n#define IFT_EPLRS\t\t   0x57 /* Ext Pos Loc Report Sys */\n#define IFT_ARAP\t\t   0x58 /* Appletalk Remote Access Protocol */\n#define IFT_PROPCNLS\t\t   0x59 /* Proprietary Connectionless Protocol*/\n#define IFT_HOSTPAD\t\t   0x5a /* CCITT-ITU X.29 PAD Protocol */\n#define IFT_TERMPAD\t\t   0x5b /* CCITT-ITU X.3 PAD Facility */\n#define IFT_FRAMERELAYMPI\t   0x5c /* Multiproto Interconnect over FR */\n#define IFT_X213\t\t   0x5d /* CCITT-ITU X213 */\n#define IFT_ADSL\t\t   0x5e /* Asymmetric Digital Subscriber Loop */\n#define IFT_RADSL\t\t   0x5f /* Rate-Adapt. Digital Subscriber Loop*/\n#define IFT_SDSL\t\t   0x60 /* Symmetric Digital Subscriber Loop */\n#define IFT_VDSL\t\t   0x61 /* Very H-Speed Digital Subscrib. Loop*/\n#define IFT_ISO88025CRFPINT\t   0x62 /* ISO 802.5 CRFP */\n#define IFT_MYRINET\t\t   0x63 /* Myricom Myrinet */\n#define IFT_VOICEEM\t\t   0x64 /* voice recEive and transMit */\n#define IFT_VOICEFXO\t\t   0x65 /* voice Foreign Exchange Office */\n#define IFT_VOICEFXS\t\t   0x66 /* voice Foreign Exchange Station */\n#define IFT_VOICEENCAP\t\t   0x67 /* voice encapsulation */\n#define IFT_VOICEOVERIP\t\t   0x68 /* voice over IP encapsulation */\n#define IFT_ATMDXI\t\t   0x69 /* ATM DXI */\n#define IFT_ATMFUNI\t\t   0x6a /* ATM FUNI */\n#define IFT_ATMIMA\t\t   0x6b /* ATM IMA\t\t      */\n#define IFT_PPPMULTILINKBUNDLE\t   0x6c /* PPP Multilink Bundle */\n#define IFT_IPOVERCDLC\t\t   0x6d /* IBM ipOverCdlc */\n#define IFT_IPOVERCLAW\t\t   0x6e /* IBM Common Link Access to Workstn */\n#define IFT_STACKTOSTACK\t   0x6f /* IBM stackToStack */\n#define IFT_VIRTUALIPADDRESS\t   0x70 /* IBM VIPA */\n#define IFT_MPC\t\t\t   0x71 /* IBM multi-protocol channel support */\n#define IFT_IPOVERATM\t\t   0x72 /* IBM ipOverAtm */\n#define IFT_ISO88025FIBER\t   0x73 /* ISO 802.5j Fiber Token Ring */\n#define IFT_TDLC\t\t   0x74 /* IBM twinaxial data link control */\n#define IFT_GIGABITETHERNET\t   0x75 /* Gigabit Ethernet */\n#define IFT_HDLC\t\t   0x76 /* HDLC */\n#define IFT_LAPF\t\t   0x77 /* LAP F */\n#define IFT_V37\t\t\t   0x78 /* V.37 */\n#define IFT_X25MLP\t\t   0x79 /* Multi-Link Protocol */\n#define IFT_X25HUNTGROUP\t   0x7a /* X25 Hunt Group */\n#define IFT_TRANSPHDLC\t\t   0x7b /* Transp HDLC */\n#define IFT_INTERLEAVE\t\t   0x7c /* Interleave channel */\n#define IFT_FAST\t\t   0x7d /* Fast channel */\n#define IFT_IP\t\t\t   0x7e /* IP (for APPN HPR in IP networks) */\n#define IFT_DOCSCABLEMACLAYER\t   0x7f /* CATV Mac Layer */\n#define IFT_DOCSCABLEDOWNSTREAM\t   0x80 /* CATV Downstream interface */\n#define IFT_DOCSCABLEUPSTREAM\t   0x81 /* CATV Upstream interface */\n#define IFT_A12MPPSWITCH\t   0x82\t/* Avalon Parallel Processor */\n#define IFT_TUNNEL\t\t   0x83\t/* Encapsulation interface */\n#define IFT_COFFEE\t\t   0x84\t/* coffee pot */\n#define IFT_CES\t\t\t   0x85\t/* Circiut Emulation Service */\n#define IFT_ATMSUBINTERFACE\t   0x86\t/* (x)  ATM Sub Interface */\n#define IFT_L2VLAN\t\t   0x87\t/* Layer 2 Virtual LAN using 802.1Q */\n#define IFT_L3IPVLAN\t\t   0x88\t/* Layer 3 Virtual LAN - IP Protocol */\n#define IFT_L3IPXVLAN\t\t   0x89\t/* Layer 3 Virtual LAN - IPX Prot. */\n#define IFT_DIGITALPOWERLINE\t   0x8a\t/* IP over Power Lines */\n#define IFT_MEDIAMAILOVERIP\t   0x8b\t/* (xxx)  Multimedia Mail over IP */\n#define IFT_DTM\t\t\t   0x8c\t/* Dynamic synchronous Transfer Mode */\n#define IFT_DCN\t\t\t   0x8d\t/* Data Communications Network */\n#define IFT_IPFORWARD\t\t   0x8e\t/* IP Forwarding Interface */\n#define IFT_MSDSL\t\t   0x8f\t/* Multi-rate Symmetric DSL */\n#define IFT_IEEE1394\t\t   0x90\t/* IEEE1394 High Performance SerialBus*/\n#define IFT_IFGSN\t\t   0x91\t/* HIPPI-6400 */\n#define IFT_DVBRCCMACLAYER\t   0x92\t/* DVB-RCC MAC Layer */\n#define IFT_DVBRCCDOWNSTREAM\t   0x93\t/* DVB-RCC Downstream Channel */\n#define IFT_DVBRCCUPSTREAM\t   0x94\t/* DVB-RCC Upstream Channel */\n#define IFT_ATMVIRTUAL\t\t   0x95\t/* ATM Virtual Interface */\n#define IFT_MPLSTUNNEL\t\t   0x96\t/* MPLS Tunnel Virtual Interface */\n#define IFT_SRP\t\t\t   0x97\t/* Spatial Reuse Protocol */\n#define IFT_VOICEOVERATM\t   0x98\t/* Voice over ATM */\n#define IFT_VOICEOVERFRAMERELAY\t   0x99\t/* Voice Over Frame Relay */\n#define IFT_IDSL\t\t   0x9a\t/* Digital Subscriber Loop over ISDN */\n#define IFT_COMPOSITELINK\t   0x9b\t/* Avici Composite Link Interface */\n#define IFT_SS7SIGLINK\t\t   0x9c\t/* SS7 Signaling Link */\n#define IFT_PROPWIRELESSP2P\t   0x9d\t/* Prop. P2P wireless interface */\n#define IFT_FRFORWARD\t\t   0x9e\t/* Frame forward Interface */\n#define IFT_RFC1483\t\t   0x9f\t/* Multiprotocol over ATM AAL5 */\n#define IFT_USB\t\t\t   0xa0\t/* USB Interface */\n#define IFT_IEEE8023ADLAG\t   0xa1\t/* IEEE 802.3ad Link Aggregate*/\n#define IFT_BGPPOLICYACCOUNTING\t   0xa2\t/* BGP Policy Accounting */\n#define IFT_FRF16MFRBUNDLE\t   0xa3\t/* FRF.16 Multilik Frame Relay*/\n#define IFT_H323GATEKEEPER\t   0xa4\t/* H323 Gatekeeper */\n#define IFT_H323PROXY\t\t   0xa5\t/* H323 Voice and Video Proxy */\n#define IFT_MPLS\t\t   0xa6\t/* MPLS */\n#define IFT_MFSIGLINK\t\t   0xa7\t/* Multi-frequency signaling link */\n#define IFT_HDSL2\t\t   0xa8\t/* High Bit-Rate DSL, 2nd gen. */\n#define IFT_SHDSL\t\t   0xa9\t/* Multirate HDSL2 */\n#define IFT_DS1FDL\t\t   0xaa\t/* Facility Data Link (4Kbps) on a DS1*/\n#define IFT_POS\t\t\t   0xab\t/* Packet over SONET/SDH Interface */\n#define IFT_DVBASILN\t\t   0xac\t/* DVB-ASI Input */\n#define IFT_DVBASIOUT\t\t   0xad\t/* DVB-ASI Output */\n#define IFT_PLC\t\t\t   0xae\t/* Power Line Communications */\n#define IFT_NFAS\t\t   0xaf\t/* Non-Facility Associated Signaling */\n#define IFT_TR008\t\t   0xb0\t/* TROO8 */\n#define IFT_GR303RDT\t\t   0xb1\t/* Remote Digital Terminal */\n#define IFT_GR303IDT\t\t   0xb2\t/* Integrated Digital Terminal */\n#define IFT_ISUP\t\t   0xb3\t/* ISUP */\n#define IFT_PROPDOCSWIRELESSMACLAYER\t   0xb4\t/* prop/Wireless MAC Layer */\n#define IFT_PROPDOCSWIRELESSDOWNSTREAM\t   0xb5\t/* prop/Wireless Downstream */\n#define IFT_PROPDOCSWIRELESSUPSTREAM\t   0xb6\t/* prop/Wireless Upstream */\n#define IFT_HIPERLAN2\t\t   0xb7\t/* HIPERLAN Type 2 Radio Interface */\n#define IFT_PROPBWAP2MP\t\t   0xb8\t/* PropBroadbandWirelessAccess P2MP*/\n#define IFT_SONETOVERHEADCHANNEL   0xb9\t/* SONET Overhead Channel */\n#define IFT_DIGITALWRAPPEROVERHEADCHANNEL  0xba\t/* Digital Wrapper Overhead */\n#define IFT_AAL2\t\t   0xbb\t/* ATM adaptation layer 2 */\n#define IFT_RADIOMAC\t\t   0xbc\t/* MAC layer over radio links */\n#define IFT_ATMRADIO\t\t   0xbd\t/* ATM over radio links */\n#define IFT_IMT\t\t\t   0xbe /* Inter-Machine Trunks */\n#define IFT_MVL\t\t\t   0xbf /* Multiple Virtual Lines DSL */\n#define IFT_REACHDSL\t\t   0xc0 /* Long Reach DSL */\n#define IFT_FRDLCIENDPT\t\t   0xc1 /* Frame Relay DLCI End Point */\n#define IFT_ATMVCIENDPT\t\t   0xc2 /* ATM VCI End Point */\n#define IFT_OPTICALCHANNEL\t   0xc3 /* Optical Channel */\n#define IFT_OPTICALTRANSPORT\t   0xc4 /* Optical Transport */\n#define IFT_PROPATM\t\t   0xc5 /* Proprietary ATM */\n#define IFT_VOICEOVERCABLE\t   0xc6 /* Voice Over Cable Interface */\n#define IFT_INFINIBAND\t\t   0xc7 /* Infiniband */\n#define IFT_TELINK\t\t   0xc8 /* TE Link */\n#define IFT_Q2931\t\t   0xc9 /* Q.2931 */\n#define IFT_VIRTUALTG\t\t   0xca /* Virtual Trunk Group */\n#define IFT_SIPTG\t\t   0xcb /* SIP Trunk Group */\n#define IFT_SIPSIG\t\t   0xcc /* SIP Signaling */\n#define IFT_DOCSCABLEUPSTREAMCHANNEL 0xcd /* CATV Upstream Channel */\n#define IFT_ECONET\t\t   0xce /* Acorn Econet */\n#define IFT_PON155\t\t   0xcf /* FSAN 155Mb Symetrical PON interface */\n#define IFT_PON622\t\t   0xd0 /* FSAN 622Mb Symetrical PON interface */\n#define IFT_BRIDGE\t\t   0xd1 /* Transparent bridge interface */\n#define IFT_LINEGROUP\t\t   0xd2 /* Interface common to multiple lines */\n#define IFT_VOICEEMFGD\t\t   0xd3 /* voice E&M Feature Group D */\n#define IFT_VOICEFGDEANA\t   0xd4 /* voice FGD Exchange Access North American */\n#define IFT_VOICEDID\t\t   0xd5 /* voice Direct Inward Dialing */\n#define IFT_STF\t\t\t   0xd7\t/* 6to4 interface */\n\n/* not based on IANA assignments - how should we treat these? */\n#define IFT_GIF\t\t0xf0\n#define IFT_PVC\t\t0xf1\n#define IFT_FAITH\t0xf2\n#define IFT_PFLOG\t0xf5\t\t/* Packet filter logging */\n#define IFT_PFSYNC\t0xf6\t\t/* Packet filter state syncing */\n#define IFT_CARP\t0xf8\t\t/* Common Address Redundancy Protocol */\n\n#endif /* !_NET_IF_TYPES_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/net/route.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _NET_ROUTE_H_\n#define _NET_ROUTE_H_\n\n#include <sys/socket.h>\n#include <linux/route.h>\n#include <linux/in6.h>\n#include <linux/ipv6_route.h>\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/netdb.h",
    "content": "/*-\n * Copyright (c) 1980, 1983, 1988, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. All advertising materials mentioning features or use of this software\n *    must display the following acknowledgement:\n *\tThis product includes software developed by the University of\n *\tCalifornia, Berkeley and its contributors.\n * 4. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n * -\n * Portions Copyright (c) 1993 by Digital Equipment Corporation.\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies, and that\n * the name of Digital Equipment Corporation not be used in advertising or\n * publicity pertaining to distribution of the document or software without\n * specific, written prior permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL\n * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT\n * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\n * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\n * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\n * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\n * SOFTWARE.\n * -\n * --Copyright--\n */\n\n/*\n *      @(#)netdb.h\t8.1 (Berkeley) 6/2/93\n *      From: Id: netdb.h,v 8.9 1996/11/19 08:39:29 vixie Exp $\n * $FreeBSD: /repoman/r/ncvs/src/include/netdb.h,v 1.41 2006/04/15 16:20:26 ume Exp $\n */\n\n#ifndef _NETDB_H_\n#define _NETDB_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n\n#ifndef _PATH_HEQUIV\n# define\t_PATH_HEQUIV\t\"/system/etc/hosts.equiv\"\n#endif\n#define\t_PATH_HOSTS\t\"/system/etc/hosts\"\n#define\t_PATH_NETWORKS\t\"/system/etc/networks\"\n#define\t_PATH_PROTOCOLS\t\"/system/etc/protocols\"\n#define\t_PATH_SERVICES\t\"/system/etc/services\"\n\n/*\n * Structures returned by network data base library.  All addresses are\n * supplied in host order, and returned in network order (suitable for\n * use in system calls).\n */\nstruct hostent {\n\tchar\t*h_name;\t/* official name of host */\n\tchar\t**h_aliases;\t/* alias list */\n\tint\th_addrtype;\t/* host address type */\n\tint\th_length;\t/* length of address */\n\tchar\t**h_addr_list;\t/* list of addresses from name server */\n#define\th_addr\th_addr_list[0]\t/* address, for backward compatibility */\n};\n\nstruct netent {\n\tchar\t\t*n_name;\t/* official name of net */\n\tchar\t\t**n_aliases;\t/* alias list */\n\tint\t\tn_addrtype;\t/* net address type */\n\tuint32_t\tn_net;\t\t/* network # */\n};\n\nstruct servent {\n\tchar\t*s_name;\t/* official service name */\n\tchar\t**s_aliases;\t/* alias list */\n\tint\ts_port;\t\t/* port # */\n\tchar\t*s_proto;\t/* protocol to use */\n};\n\nstruct protoent {\n\tchar\t*p_name;\t/* official protocol name */\n\tchar\t**p_aliases;\t/* alias list */\n\tint\tp_proto;\t/* protocol # */\n};\n\nstruct addrinfo {\n\tint\tai_flags;\t/* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */\n\tint\tai_family;\t/* PF_xxx */\n\tint\tai_socktype;\t/* SOCK_xxx */\n\tint\tai_protocol;\t/* 0 or IPPROTO_xxx for IPv4 and IPv6 */\n\tsocklen_t ai_addrlen;\t/* length of ai_addr */\n\tchar\t*ai_canonname;\t/* canonical name for hostname */\n\tstruct\tsockaddr *ai_addr;\t/* binary address */\n\tstruct\taddrinfo *ai_next;\t/* next structure in linked list */\n};\n\n/*\n * Error return codes from gethostbyname() and gethostbyaddr()\n * (left in h_errno).\n */\n\n#define\tNETDB_INTERNAL\t-1\t/* see errno */\n#define\tNETDB_SUCCESS\t0\t/* no problem */\n#define\tHOST_NOT_FOUND\t1 /* Authoritative Answer Host not found */\n#define\tTRY_AGAIN\t2 /* Non-Authoritative Host not found, or SERVERFAIL */\n#define\tNO_RECOVERY\t3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */\n#define\tNO_DATA\t\t4 /* Valid name, no data record of requested type */\n#define\tNO_ADDRESS\tNO_DATA\t\t/* no address, look for MX record */\n\n/*\n * Error return codes from getaddrinfo()\n */\n#define\tEAI_ADDRFAMILY\t 1\t/* address family for hostname not supported */\n#define\tEAI_AGAIN\t 2\t/* temporary failure in name resolution */\n#define\tEAI_BADFLAGS\t 3\t/* invalid value for ai_flags */\n#define\tEAI_FAIL\t 4\t/* non-recoverable failure in name resolution */\n#define\tEAI_FAMILY\t 5\t/* ai_family not supported */\n#define\tEAI_MEMORY\t 6\t/* memory allocation failure */\n#define\tEAI_NODATA\t 7\t/* no address associated with hostname */\n#define\tEAI_NONAME\t 8\t/* hostname nor servname provided, or not known */\n#define\tEAI_SERVICE\t 9\t/* servname not supported for ai_socktype */\n#define\tEAI_SOCKTYPE\t10\t/* ai_socktype not supported */\n#define\tEAI_SYSTEM\t11\t/* system error returned in errno */\n#define\tEAI_BADHINTS\t12\t/* invalid value for hints */\n#define\tEAI_PROTOCOL\t13\t/* resolved protocol is unknown */\n#define\tEAI_OVERFLOW\t14\t/* argument buffer overflow */\n#define\tEAI_MAX\t\t15\n\n/*\n * Flag values for getaddrinfo()\n */\n#define\tAI_PASSIVE\t0x00000001 /* get address to use bind() */\n#define\tAI_CANONNAME\t0x00000002 /* fill ai_canonname */\n#define\tAI_NUMERICHOST\t0x00000004 /* prevent host name resolution */\n#define\tAI_NUMERICSERV\t0x00000008 /* prevent service name resolution */\n/* valid flags for addrinfo (not a standard def, apps should not use it) */\n#define AI_MASK \\\n    (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | \\\n    AI_ADDRCONFIG)\n\n#define\tAI_ALL\t\t0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */\n#define\tAI_V4MAPPED_CFG\t0x00000200 /* accept IPv4-mapped if kernel supports */\n#define\tAI_ADDRCONFIG\t0x00000400 /* only if any address is assigned */\n#define\tAI_V4MAPPED\t0x00000800 /* accept IPv4-mapped IPv6 address */\n/* special recommended flags for getipnodebyname */\n#define\tAI_DEFAULT\t(AI_V4MAPPED_CFG | AI_ADDRCONFIG)\n\n/*\n * Constants for getnameinfo()\n */\n#define\tNI_MAXHOST\t1025\n#define\tNI_MAXSERV\t32\n\n/*\n * Flag values for getnameinfo()\n */\n#define\tNI_NOFQDN\t0x00000001\n#define\tNI_NUMERICHOST\t0x00000002\n#define\tNI_NAMEREQD\t0x00000004\n#define\tNI_NUMERICSERV\t0x00000008\n#define\tNI_DGRAM\t0x00000010\n#if 0 /* obsolete */\n#define NI_WITHSCOPEID\t0x00000020\n#endif\n\n/*\n * Scope delimit character\n */\n#define\tSCOPE_DELIMITER\t'%'\n\n__BEGIN_DECLS\n#pragma GCC visibility push(default)\n\n/* BIONIC-BEGIN */\n#define  h_errno   (*__get_h_errno())\nint*  __get_h_errno(void);\n/* BIONIC-END */\nvoid endhostent(void);\nvoid endnetent(void);\nvoid endnetgrent(void);\nvoid endprotoent(void);\nvoid endservent(void);\nvoid freehostent(struct hostent *);\nstruct hostent\t*gethostbyaddr(const void *, socklen_t, int);\nint gethostbyaddr_r(const void *, socklen_t, int, struct hostent *, char *, size_t, struct hostent **, int *);\nstruct hostent\t*gethostbyname(const char *);\nint gethostbyname_r(const char *, struct hostent *, char *, size_t, struct hostent **, int *);\nstruct hostent\t*gethostbyname2(const char *, int);\nint gethostbyname2_r(const char *, int, struct hostent *, char *, size_t, struct hostent **, int *);\nstruct hostent\t*gethostent(void);\nint gethostent_r(struct hostent *, char *, size_t, struct hostent **, int *);\nstruct hostent\t*getipnodebyaddr(const void *, size_t, int, int *);\nstruct hostent\t*getipnodebyname(const char *, int, int, int *);\nstruct netent\t*getnetbyaddr(uint32_t, int);\nint getnetbyaddr_r(uint32_t, int, struct netent *, char *, size_t, struct netent**, int *);\nstruct netent\t*getnetbyname(const char *);\nint getnetbyname_r(const char *, struct netent *, char *, size_t, struct netent **, int *);\nstruct netent\t*getnetent(void);\nint getnetent_r(struct netent *, char *, size_t, struct netent **, int *);\nint getnetgrent(char **, char **, char **);\nstruct protoent\t*getprotobyname(const char *);\nint getprotobyname_r(const char *, struct protoent *, char *, size_t, struct protoent **);\nstruct protoent\t*getprotobynumber(int);\nint getprotobynumber_r(int, struct protoent *, char *, size_t, struct protoent **);\nstruct protoent\t*getprotoent(void);\nint getprotoent_r(struct protoent *, char *, size_t, struct protoent **);\nstruct servent\t*getservbyname(const char *, const char *);\nstruct servent\t*getservbyport(int, const char *);\nstruct servent\t*getservent(void);\nvoid herror(const char *);\nconst char\t*hstrerror(int);\nint innetgr(const char *, const char *, const char *, const char *);\nvoid sethostent(int);\nvoid setnetent(int);\nvoid setprotoent(int);\nint getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **);\nint getnameinfo(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t, int);\nvoid freeaddrinfo(struct addrinfo *);\nconst char\t*gai_strerror(int);\nvoid setnetgrent(const char *);\nvoid setservent(int);\n\n#pragma GCC visibility pop\n__END_DECLS\n\n#endif /* !_NETDB_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/netinet/ether.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#include <net/if_ether.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/netinet/icmp6.h",
    "content": "/*\t$NetBSD: icmp6.h,v 1.47 2013/07/01 12:43:15 christos Exp $\t*/\n/*\t$KAME: icmp6.h,v 1.84 2003/04/23 10:26:51 itojun Exp $\t*/\n\n\n/*\n * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the project nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*\n * Copyright (c) 1982, 1986, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)ip_icmp.h\t8.1 (Berkeley) 6/10/93\n */\n\n#ifndef _NETINET_ICMP6_H_\n#define _NETINET_ICMP6_H_\n\n#include <netinet/in.h> /* android-added: glibc source compatibility. */\n\n#define ICMPV6_PLD_MAXLEN\t1232\t/* IPV6_MMTU - sizeof(struct ip6_hdr)\n\t\t\t\t\t   - sizeof(struct icmp6_hdr) */\n\nstruct icmp6_hdr {\n\tu_int8_t\ticmp6_type;\t/* type field */\n\tu_int8_t\ticmp6_code;\t/* code field */\n\tu_int16_t\ticmp6_cksum;\t/* checksum field */\n\tunion {\n\t\tu_int32_t\ticmp6_un_data32[1]; /* type-specific field */\n\t\tu_int16_t\ticmp6_un_data16[2]; /* type-specific field */\n\t\tu_int8_t\ticmp6_un_data8[4];  /* type-specific field */\n\t} icmp6_dataun;\n} __packed;\n\n#define icmp6_data32\ticmp6_dataun.icmp6_un_data32\n#define icmp6_data16\ticmp6_dataun.icmp6_un_data16\n#define icmp6_data8\ticmp6_dataun.icmp6_un_data8\n#define icmp6_pptr\ticmp6_data32[0]\t\t/* parameter prob */\n#define icmp6_mtu\ticmp6_data32[0]\t\t/* packet too big */\n#define icmp6_id\ticmp6_data16[0]\t\t/* echo request/reply */\n#define icmp6_seq\ticmp6_data16[1]\t\t/* echo request/reply */\n#define icmp6_maxdelay\ticmp6_data16[0]\t\t/* mcast group membership */\n\n#define ICMP6_DST_UNREACH\t\t1\t/* dest unreachable, codes: */\n#define ICMP6_PACKET_TOO_BIG\t\t2\t/* packet too big */\n#define ICMP6_TIME_EXCEEDED\t\t3\t/* time exceeded, code: */\n#define ICMP6_PARAM_PROB\t\t4\t/* ip6 header bad */\n\n#define ICMP6_ECHO_REQUEST\t\t128\t/* echo service */\n#define ICMP6_ECHO_REPLY\t\t129\t/* echo reply */\n#define MLD_LISTENER_QUERY\t\t130 \t/* multicast listener query */\n#define MLD_LISTENER_REPORT\t\t131\t/* multicast listener report */\n#define MLD_LISTENER_DONE\t\t132\t/* multicast listener done */\n#define MLD_LISTENER_REDUCTION MLD_LISTENER_DONE /* RFC3542 definition */\n\n/* RFC2292 decls */\n#define ICMP6_MEMBERSHIP_QUERY\t\t130\t/* group membership query */\n#define ICMP6_MEMBERSHIP_REPORT\t\t131\t/* group membership report */\n#define ICMP6_MEMBERSHIP_REDUCTION\t132\t/* group membership termination */\n\n#ifndef _KERNEL\n/* the followings are for backward compatibility to old KAME apps. */\n#define MLD6_LISTENER_QUERY\tMLD_LISTENER_QUERY\n#define MLD6_LISTENER_REPORT\tMLD_LISTENER_REPORT\n#define MLD6_LISTENER_DONE\tMLD_LISTENER_DONE\n#endif\n\n#define ND_ROUTER_SOLICIT\t\t133\t/* router solicitation */\n#define ND_ROUTER_ADVERT\t\t134\t/* router advertisement */\n#define ND_NEIGHBOR_SOLICIT\t\t135\t/* neighbor solicitation */\n#define ND_NEIGHBOR_ADVERT\t\t136\t/* neighbor advertisement */\n#define ND_REDIRECT\t\t\t137\t/* redirect */\n\n#define ICMP6_ROUTER_RENUMBERING\t138\t/* router renumbering */\n\n#define ICMP6_WRUREQUEST\t\t139\t/* who are you request */\n#define ICMP6_WRUREPLY\t\t\t140\t/* who are you reply */\n#define ICMP6_FQDN_QUERY\t\t139\t/* FQDN query */\n#define ICMP6_FQDN_REPLY\t\t140\t/* FQDN reply */\n#define ICMP6_NI_QUERY\t\t\t139\t/* node information request */\n#define ICMP6_NI_REPLY\t\t\t140\t/* node information reply */\n#define MLDV2_LISTENER_REPORT\t\t143\t/* RFC3810 listener report */\n\n/* The definitions below are experimental. TBA */\n#define MLD_MTRACE_RESP\t\t\t200\t/* mtrace response(to sender) */\n#define MLD_MTRACE\t\t\t201\t/* mtrace messages */\n\n#ifndef _KERNEL\n/* the followings are for backward compatibility to old KAME apps. */\n#define MLD6_MTRACE_RESP\tMLD_MTRACE_RESP\n#define MLD6_MTRACE\t\tMLD_MTRACE\n#endif\n\n#define ICMP6_MAXTYPE\t\t\t201\n\n#define ICMP6_DST_UNREACH_NOROUTE\t0\t/* no route to destination */\n#define ICMP6_DST_UNREACH_ADMIN\t \t1\t/* administratively prohibited */\n#define ICMP6_DST_UNREACH_NOTNEIGHBOR\t2\t/* not a neighbor(obsolete) */\n#define ICMP6_DST_UNREACH_BEYONDSCOPE\t2\t/* beyond scope of source address */\n#define ICMP6_DST_UNREACH_ADDR\t\t3\t/* address unreachable */\n#define ICMP6_DST_UNREACH_NOPORT\t4\t/* port unreachable */\n#define ICMP6_DST_UNREACH_POLICY\t5\t/* source address failed ingress/egress policy */\n#define ICMP6_DST_UNREACH_REJROUTE\t6\t/* reject route to destination */\n#define ICMP6_DST_UNREACH_SOURCERT\t7\t/* error in source routing header */\n\n#define ICMP6_TIME_EXCEED_TRANSIT \t0\t/* ttl==0 in transit */\n#define ICMP6_TIME_EXCEED_REASSEMBLY\t1\t/* ttl==0 in reass */\n\n#define ICMP6_PARAMPROB_HEADER \t \t0\t/* erroneous header field */\n#define ICMP6_PARAMPROB_NEXTHEADER\t1\t/* unrecognized next header */\n#define ICMP6_PARAMPROB_OPTION\t\t2\t/* unrecognized option */\n\n#define ICMP6_INFOMSG_MASK\t\t0x80\t/* all informational messages */\n\n#define ICMP6_NI_SUBJ_IPV6\t0\t/* Query Subject is an IPv6 address */\n#define ICMP6_NI_SUBJ_FQDN\t1\t/* Query Subject is a Domain name */\n#define ICMP6_NI_SUBJ_IPV4\t2\t/* Query Subject is an IPv4 address */\n\n#define ICMP6_NI_SUCCESS\t0\t/* node information successful reply */\n#define ICMP6_NI_REFUSED\t1\t/* node information request is refused */\n#define ICMP6_NI_UNKNOWN\t2\t/* unknown Qtype */\n\n#define ICMP6_ROUTER_RENUMBERING_COMMAND  0\t/* rr command */\n#define ICMP6_ROUTER_RENUMBERING_RESULT   1\t/* rr result */\n#define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET   255\t/* rr seq num reset */\n\n/* Used in kernel only */\n#define ND_REDIRECT_ONLINK\t0\t/* redirect to an on-link node */\n#define ND_REDIRECT_ROUTER\t1\t/* redirect to a better router */\n\n/*\n * Multicast Listener Discovery\n */\nstruct mld_hdr {\n\tstruct icmp6_hdr\tmld_icmp6_hdr;\n\tstruct in6_addr\t\tmld_addr; /* multicast address */\n} __packed;\n\n/* definitions to provide backward compatibility to old KAME applications */\n#ifndef _KERNEL\n#define mld6_hdr\tmld_hdr\n#define mld6_type\tmld_type\n#define mld6_code\tmld_code\n#define mld6_cksum\tmld_cksum\n#define mld6_maxdelay\tmld_maxdelay\n#define mld6_reserved\tmld_reserved\n#define mld6_addr\tmld_addr\n#endif\n\n/* shortcut macro definitions */\n#define mld_type\tmld_icmp6_hdr.icmp6_type\n#define mld_code\tmld_icmp6_hdr.icmp6_code\n#define mld_cksum\tmld_icmp6_hdr.icmp6_cksum\n#define mld_maxdelay\tmld_icmp6_hdr.icmp6_data16[0]\n#define mld_reserved\tmld_icmp6_hdr.icmp6_data16[1]\n\n#define MLD_MINLEN\t\t\t24\n\n/*\n * Neighbor Discovery\n */\n\nstruct nd_router_solicit {\t/* router solicitation */\n\tstruct icmp6_hdr \tnd_rs_hdr;\n\t/* could be followed by options */\n} __packed;\n\n#define nd_rs_type\tnd_rs_hdr.icmp6_type\n#define nd_rs_code\tnd_rs_hdr.icmp6_code\n#define nd_rs_cksum\tnd_rs_hdr.icmp6_cksum\n#define nd_rs_reserved\tnd_rs_hdr.icmp6_data32[0]\n\nstruct nd_router_advert {\t/* router advertisement */\n\tstruct icmp6_hdr\tnd_ra_hdr;\n\tu_int32_t\t\tnd_ra_reachable;\t/* reachable time */\n\tu_int32_t\t\tnd_ra_retransmit;\t/* retransmit timer */\n\t/* could be followed by options */\n} __packed;\n\n#define nd_ra_type\t\tnd_ra_hdr.icmp6_type\n#define nd_ra_code\t\tnd_ra_hdr.icmp6_code\n#define nd_ra_cksum\t\tnd_ra_hdr.icmp6_cksum\n#define nd_ra_curhoplimit\tnd_ra_hdr.icmp6_data8[0]\n#define nd_ra_flags_reserved\tnd_ra_hdr.icmp6_data8[1]\n#define ND_RA_FLAG_MANAGED\t0x80\n#define ND_RA_FLAG_OTHER\t0x40\n#define ND_RA_FLAG_HOME_AGENT\t0x20\n\n/*\n * Router preference values based on RFC4191.\n */\n#define ND_RA_FLAG_RTPREF_MASK\t0x18 /* 00011000 */\n\n#define ND_RA_FLAG_RTPREF_HIGH\t0x08 /* 00001000 */\n#define ND_RA_FLAG_RTPREF_MEDIUM\t0x00 /* 00000000 */\n#define ND_RA_FLAG_RTPREF_LOW\t0x18 /* 00011000 */\n#define ND_RA_FLAG_RTPREF_RSV\t0x10 /* 00010000 */\n\n#define nd_ra_router_lifetime\tnd_ra_hdr.icmp6_data16[1]\n\nstruct nd_neighbor_solicit {\t/* neighbor solicitation */\n\tstruct icmp6_hdr\tnd_ns_hdr;\n\tstruct in6_addr\t\tnd_ns_target;\t/*target address */\n\t/* could be followed by options */\n} __packed;\n\n#define nd_ns_type\t\tnd_ns_hdr.icmp6_type\n#define nd_ns_code\t\tnd_ns_hdr.icmp6_code\n#define nd_ns_cksum\t\tnd_ns_hdr.icmp6_cksum\n#define nd_ns_reserved\t\tnd_ns_hdr.icmp6_data32[0]\n\nstruct nd_neighbor_advert {\t/* neighbor advertisement */\n\tstruct icmp6_hdr\tnd_na_hdr;\n\tstruct in6_addr\t\tnd_na_target;\t/* target address */\n\t/* could be followed by options */\n} __packed;\n\n#define nd_na_type\t\tnd_na_hdr.icmp6_type\n#define nd_na_code\t\tnd_na_hdr.icmp6_code\n#define nd_na_cksum\t\tnd_na_hdr.icmp6_cksum\n#define nd_na_flags_reserved\tnd_na_hdr.icmp6_data32[0]\n#if BYTE_ORDER == BIG_ENDIAN\n#define ND_NA_FLAG_ROUTER\t\t0x80000000\n#define ND_NA_FLAG_SOLICITED\t\t0x40000000\n#define ND_NA_FLAG_OVERRIDE\t\t0x20000000\n#else\n#if BYTE_ORDER == LITTLE_ENDIAN\n#define ND_NA_FLAG_ROUTER\t\t0x80\n#define ND_NA_FLAG_SOLICITED\t\t0x40\n#define ND_NA_FLAG_OVERRIDE\t\t0x20\n#endif\n#endif\n\nstruct nd_redirect {\t\t/* redirect */\n\tstruct icmp6_hdr\tnd_rd_hdr;\n\tstruct in6_addr\t\tnd_rd_target;\t/* target address */\n\tstruct in6_addr\t\tnd_rd_dst;\t/* destination address */\n\t/* could be followed by options */\n} __packed;\n\n#define nd_rd_type\t\tnd_rd_hdr.icmp6_type\n#define nd_rd_code\t\tnd_rd_hdr.icmp6_code\n#define nd_rd_cksum\t\tnd_rd_hdr.icmp6_cksum\n#define nd_rd_reserved\t\tnd_rd_hdr.icmp6_data32[0]\n\nstruct nd_opt_hdr {\t\t/* Neighbor discovery option header */\n\tu_int8_t\tnd_opt_type;\n\tu_int8_t\tnd_opt_len;\n\t/* followed by option specific data*/\n} __packed;\n\n#define ND_OPT_SOURCE_LINKADDR\t\t1\n#define ND_OPT_TARGET_LINKADDR\t\t2\n#define ND_OPT_PREFIX_INFORMATION\t3\n#define ND_OPT_REDIRECTED_HEADER\t4\n#define ND_OPT_MTU\t\t\t5\n#define ND_OPT_ADVINTERVAL\t\t7\n#define ND_OPT_HOMEAGENT_INFO\t\t8\n#define ND_OPT_SOURCE_ADDRLIST\t\t9\n#define ND_OPT_TARGET_ADDRLIST\t\t10\n#define ND_OPT_MAP\t\t\t23\t/* RFC 5380 */\n#define ND_OPT_ROUTE_INFO\t\t24\t/* RFC 4191 */\n#define ND_OPT_RDNSS\t\t\t25\t/* RFC 6016 */\n#define ND_OPT_DNSSL\t\t\t31\t/* RFC 6016 */\n\nstruct nd_opt_route_info {\t/* route info */\n\tu_int8_t\tnd_opt_rti_type;\n\tu_int8_t\tnd_opt_rti_len;\n\tu_int8_t\tnd_opt_rti_prefixlen;\n\tu_int8_t\tnd_opt_rti_flags;\n\tu_int32_t\tnd_opt_rti_lifetime;\n\t/* prefix follows */\n};\n\nstruct nd_opt_prefix_info {\t/* prefix information */\n\tu_int8_t\tnd_opt_pi_type;\n\tu_int8_t\tnd_opt_pi_len;\n\tu_int8_t\tnd_opt_pi_prefix_len;\n\tu_int8_t\tnd_opt_pi_flags_reserved;\n\tu_int32_t\tnd_opt_pi_valid_time;\n\tu_int32_t\tnd_opt_pi_preferred_time;\n\tu_int32_t\tnd_opt_pi_reserved2;\n\tstruct in6_addr\tnd_opt_pi_prefix;\n} __packed;\n\n#define ND_OPT_PI_FLAG_ONLINK\t\t0x80\n#define ND_OPT_PI_FLAG_AUTO\t\t0x40\n\nstruct nd_opt_rd_hdr {\t\t/* redirected header */\n\tu_int8_t\tnd_opt_rh_type;\n\tu_int8_t\tnd_opt_rh_len;\n\tu_int16_t\tnd_opt_rh_reserved1;\n\tu_int32_t\tnd_opt_rh_reserved2;\n\t/* followed by IP header and data */\n} __packed;\n\nstruct nd_opt_mtu {\t\t/* MTU option */\n\tu_int8_t\tnd_opt_mtu_type;\n\tu_int8_t\tnd_opt_mtu_len;\n\tu_int16_t\tnd_opt_mtu_reserved;\n\tu_int32_t\tnd_opt_mtu_mtu;\n} __packed;\n\nstruct nd_opt_rdnss {\t\t/* RDNSS option RFC 6106 */\n\tu_int8_t\tnd_opt_rdnss_type;\n\tu_int8_t\tnd_opt_rdnss_len;\n\tu_int16_t\tnd_opt_rdnss_reserved;\n\tu_int32_t\tnd_opt_rdnss_lifetime;\n\t/* followed by list of IP prefixes */\n} __packed;\n\nstruct nd_opt_dnssl {\t\t/* DNSSL option RFC 6106 */\n\tu_int8_t\tnd_opt_dnssl_type;\n\tu_int8_t\tnd_opt_dnssl_len;\n\tu_int16_t\tnd_opt_dnssl_reserved;\n\tu_int32_t\tnd_opt_dnssl_lifetime;\n\t/* followed by list of IP prefixes */\n} __packed;\n\n/*\n * icmp6 namelookup\n */\n\nstruct icmp6_namelookup {\n\tstruct icmp6_hdr \ticmp6_nl_hdr;\n\tu_int8_t\ticmp6_nl_nonce[8];\n\tint32_t\t\ticmp6_nl_ttl;\n#if 0\n\tu_int8_t\ticmp6_nl_len;\n\tu_int8_t\ticmp6_nl_name[3];\n#endif\n\t/* could be followed by options */\n} __packed;\n\n/*\n * icmp6 node information\n */\nstruct icmp6_nodeinfo {\n\tstruct icmp6_hdr icmp6_ni_hdr;\n\tu_int8_t icmp6_ni_nonce[8];\n\t/* could be followed by reply data */\n} __packed;\n\n/*\n * BEGIN android-removed: glibc doesn't have these, and external/ping declares them itself.\n#define ni_type\t\ticmp6_ni_hdr.icmp6_type\n#define ni_code\t\ticmp6_ni_hdr.icmp6_code\n#define ni_cksum\ticmp6_ni_hdr.icmp6_cksum\n#define ni_qtype\ticmp6_ni_hdr.icmp6_data16[0]\n#define ni_flags\ticmp6_ni_hdr.icmp6_data16[1]\n * END android-removed\n */\n\n#define NI_QTYPE_NOOP\t\t0 /* NOOP  */\n#define NI_QTYPE_SUPTYPES\t1 /* Supported Qtypes */\n#define NI_QTYPE_FQDN\t\t2 /* FQDN (draft 04) */\n#define NI_QTYPE_DNSNAME\t2 /* DNS Name */\n#define NI_QTYPE_NODEADDR\t3 /* Node Addresses */\n#define NI_QTYPE_IPV4ADDR\t4 /* IPv4 Addresses */\n\n#if BYTE_ORDER == BIG_ENDIAN\n#define NI_SUPTYPE_FLAG_COMPRESS\t0x1\n#define NI_FQDN_FLAG_VALIDTTL\t\t0x1\n#elif BYTE_ORDER == LITTLE_ENDIAN\n#define NI_SUPTYPE_FLAG_COMPRESS\t0x0100\n#define NI_FQDN_FLAG_VALIDTTL\t\t0x0100\n#endif\n\n#ifdef NAME_LOOKUPS_04\n#if BYTE_ORDER == BIG_ENDIAN\n#define NI_NODEADDR_FLAG_LINKLOCAL\t0x1\n#define NI_NODEADDR_FLAG_SITELOCAL\t0x2\n#define NI_NODEADDR_FLAG_GLOBAL\t\t0x4\n#define NI_NODEADDR_FLAG_ALL\t\t0x8\n#define NI_NODEADDR_FLAG_TRUNCATE\t0x10\n#define NI_NODEADDR_FLAG_ANYCAST\t0x20 /* just experimental. not in spec */\n#elif BYTE_ORDER == LITTLE_ENDIAN\n#define NI_NODEADDR_FLAG_LINKLOCAL\t0x0100\n#define NI_NODEADDR_FLAG_SITELOCAL\t0x0200\n#define NI_NODEADDR_FLAG_GLOBAL\t\t0x0400\n#define NI_NODEADDR_FLAG_ALL\t\t0x0800\n#define NI_NODEADDR_FLAG_TRUNCATE\t0x1000\n#define NI_NODEADDR_FLAG_ANYCAST\t0x2000 /* just experimental. not in spec */\n#endif\n#else  /* draft-ietf-ipngwg-icmp-name-lookups-05 (and later?) */\n#if BYTE_ORDER == BIG_ENDIAN\n#define NI_NODEADDR_FLAG_TRUNCATE\t0x1\n#define NI_NODEADDR_FLAG_ALL\t\t0x2\n#define NI_NODEADDR_FLAG_COMPAT\t\t0x4\n#define NI_NODEADDR_FLAG_LINKLOCAL\t0x8\n#define NI_NODEADDR_FLAG_SITELOCAL\t0x10\n#define NI_NODEADDR_FLAG_GLOBAL\t\t0x20\n#define NI_NODEADDR_FLAG_ANYCAST\t0x40 /* just experimental. not in spec */\n#elif BYTE_ORDER == LITTLE_ENDIAN\n#define NI_NODEADDR_FLAG_TRUNCATE\t0x0100\n#define NI_NODEADDR_FLAG_ALL\t\t0x0200\n#define NI_NODEADDR_FLAG_COMPAT\t\t0x0400\n#define NI_NODEADDR_FLAG_LINKLOCAL\t0x0800\n#define NI_NODEADDR_FLAG_SITELOCAL\t0x1000\n#define NI_NODEADDR_FLAG_GLOBAL\t\t0x2000\n#define NI_NODEADDR_FLAG_ANYCAST\t0x4000 /* just experimental. not in spec */\n#endif\n#endif\n\nstruct ni_reply_fqdn {\n\tu_int32_t ni_fqdn_ttl;\t/* TTL */\n\tu_int8_t ni_fqdn_namelen; /* length in octets of the FQDN */\n\tu_int8_t ni_fqdn_name[3]; /* XXX: alignment */\n} __packed;\n\n/*\n * Router Renumbering. as router-renum-08.txt\n */\nstruct icmp6_router_renum {\t/* router renumbering header */\n\tstruct icmp6_hdr\trr_hdr;\n\tu_int8_t\trr_segnum;\n\tu_int8_t\trr_flags;\n\tu_int16_t\trr_maxdelay;\n\tu_int32_t\trr_reserved;\n} __packed;\n\n#define ICMP6_RR_FLAGS_TEST\t\t0x80\n#define ICMP6_RR_FLAGS_REQRESULT\t0x40\n#define ICMP6_RR_FLAGS_FORCEAPPLY\t0x20\n#define ICMP6_RR_FLAGS_SPECSITE\t\t0x10\n#define ICMP6_RR_FLAGS_PREVDONE\t\t0x08\n\n#define rr_type\t\trr_hdr.icmp6_type\n#define rr_code\t\trr_hdr.icmp6_code\n#define rr_cksum\trr_hdr.icmp6_cksum\n#define rr_seqnum \trr_hdr.icmp6_data32[0]\n\nstruct rr_pco_match {\t\t/* match prefix part */\n\tu_int8_t\trpm_code;\n\tu_int8_t\trpm_len;\n\tu_int8_t\trpm_ordinal;\n\tu_int8_t\trpm_matchlen;\n\tu_int8_t\trpm_minlen;\n\tu_int8_t\trpm_maxlen;\n\tu_int16_t\trpm_reserved;\n\tstruct\tin6_addr\trpm_prefix;\n} __packed;\n\n#define RPM_PCO_ADD\t\t1\n#define RPM_PCO_CHANGE\t\t2\n#define RPM_PCO_SETGLOBAL\t3\n#define RPM_PCO_MAX\t\t4\n\nstruct rr_pco_use {\t\t/* use prefix part */\n\tu_int8_t\trpu_uselen;\n\tu_int8_t\trpu_keeplen;\n\tu_int8_t\trpu_ramask;\n\tu_int8_t\trpu_raflags;\n\tu_int32_t\trpu_vltime;\n\tu_int32_t\trpu_pltime;\n\tu_int32_t\trpu_flags;\n\tstruct\tin6_addr rpu_prefix;\n} __packed;\n#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK\t0x80\n#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO\t0x40\n\n#if BYTE_ORDER == BIG_ENDIAN\n#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME     0x80000000\n#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME     0x40000000\n#elif BYTE_ORDER == LITTLE_ENDIAN\n#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME     0x80\n#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME     0x40\n#endif\n\nstruct rr_result {\t\t/* router renumbering result message */\n\tu_int16_t\trrr_flags;\n\tu_int8_t\trrr_ordinal;\n\tu_int8_t\trrr_matchedlen;\n\tu_int32_t\trrr_ifid;\n\tstruct\tin6_addr rrr_prefix;\n} __packed;\n#if BYTE_ORDER == BIG_ENDIAN\n#define ICMP6_RR_RESULT_FLAGS_OOB\t\t0x0002\n#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN\t\t0x0001\n#elif BYTE_ORDER == LITTLE_ENDIAN\n#define ICMP6_RR_RESULT_FLAGS_OOB\t\t0x0200\n#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN\t\t0x0100\n#endif\n\n/*\n * icmp6 filter structures.\n */\n\nstruct icmp6_filter {\n\tu_int32_t icmp6_filt[8];\n};\n\n/*\n * BEGIN android-changed\n * Linux and *BSD kernels use opposite values to indicate pass/block in ICMPv6\n * filters, and assign a different value to the ICMP6_FILTER sockopt.\n */\n#define ICMP6_FILTER 1\n\n#define\tICMP6_FILTER_SETPASSALL(filterp) \\\n\t(void)memset(filterp, 0x00, sizeof(struct icmp6_filter))\n#define\tICMP6_FILTER_SETBLOCKALL(filterp) \\\n\t(void)memset(filterp, 0xff, sizeof(struct icmp6_filter))\n#define\tICMP6_FILTER_SETPASS(type, filterp) \\\n\t(((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31)))\n#define\tICMP6_FILTER_SETBLOCK(type, filterp) \\\n\t(((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31)))\n#define\tICMP6_FILTER_WILLPASS(type, filterp) \\\n\t((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)\n#define\tICMP6_FILTER_WILLBLOCK(type, filterp) \\\n\t((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)\n/*\n * END android-changed\n */\n\n/*\n * Variables related to this implementation\n * of the internet control message protocol version 6.\n */\n\n/*\n * IPv6 ICMP statistics.\n * Each counter is an unsigned 64-bit value.\n */\n#define\tICMP6_STAT_ERROR\t0\t/* # of calls to icmp6_error */\n#define\tICMP6_STAT_CANTERROR\t1\t/* no error (old was icmp) */\n#define\tICMP6_STAT_TOOFREQ\t2\t/* no error (rate limitation) */\n#define\tICMP6_STAT_OUTHIST\t3\t/* # of output messages */\n\t\t/* space for 256 counters */\n#define\tICMP6_STAT_BADCODE\t259\t/* icmp6_code out of range */\n#define\tICMP6_STAT_TOOSHORT\t260\t/* packet < sizeof(struct icmp6_hdr) */\n#define\tICMP6_STAT_CHECKSUM\t261\t/* bad checksum */\n#define\tICMP6_STAT_BADLEN\t262\t/* calculated bound mismatch */\n\t/*\n\t * number of responses; this member is inherited from the netinet code,\n\t * but for netinet6 code, it is already available in outhist[].\n\t */\n#define\tICMP6_STAT_REFLECT\t263\n#define\tICMP6_STAT_INHIST\t264\t/* # of input messages */\n\t\t/* space for 256 counters */\n#define\tICMP6_STAT_ND_TOOMANYOPT 520\t/* too many ND options */\n#define\tICMP6_STAT_OUTERRHIST\t521\n\t\t/* space for 13 counters */\n#define\tICMP6_STAT_PMTUCHG\t534\t/* path MTU changes */\n#define\tICMP6_STAT_ND_BADOPT\t535\t/* bad ND options */\n#define\tICMP6_STAT_BADNS\t536\t/* bad neighbor solicititation */\n#define\tICMP6_STAT_BADNA\t537\t/* bad neighbor advertisement */\n#define\tICMP6_STAT_BADRS\t538\t/* bad router solicitiation */\n#define\tICMP6_STAT_BADRA\t539\t/* bad router advertisement */\n#define\tICMP6_STAT_BADREDIRECT\t540\t/* bad redirect message */\n#define ICMP6_STAT_DROPPED_RAROUTE 541\t/* discarded routes from router advertisement */\n\n#define\tICMP6_NSTATS\t\t542\n\n#define\tICMP6_ERRSTAT_DST_UNREACH_NOROUTE\t0\n#define\tICMP6_ERRSTAT_DST_UNREACH_ADMIN\t\t1\n#define\tICMP6_ERRSTAT_DST_UNREACH_BEYONDSCOPE\t2\n#define\tICMP6_ERRSTAT_DST_UNREACH_ADDR\t\t3\n#define\tICMP6_ERRSTAT_DST_UNREACH_NOPORT\t4\n#define\tICMP6_ERRSTAT_PACKET_TOO_BIG\t\t5\n#define\tICMP6_ERRSTAT_TIME_EXCEED_TRANSIT\t6\n#define\tICMP6_ERRSTAT_TIME_EXCEED_REASSEMBLY\t7\n#define\tICMP6_ERRSTAT_PARAMPROB_HEADER\t\t8\n#define\tICMP6_ERRSTAT_PARAMPROB_NEXTHEADER\t9\n#define\tICMP6_ERRSTAT_PARAMPROB_OPTION\t\t10\n#define\tICMP6_ERRSTAT_REDIRECT\t\t\t11\n#define\tICMP6_ERRSTAT_UNKNOWN\t\t\t12\n\n/*\n * Names for ICMP sysctl objects\n */\n#define ICMPV6CTL_STATS\t\t1\n#define ICMPV6CTL_REDIRACCEPT\t2\t/* accept/process redirects */\n#define ICMPV6CTL_REDIRTIMEOUT\t3\t/* redirect cache time */\n#if 0\t/*obsoleted*/\n#define ICMPV6CTL_ERRRATELIMIT\t5\t/* ICMPv6 error rate limitation */\n#endif\n#define ICMPV6CTL_ND6_PRUNE\t6\n#define ICMPV6CTL_ND6_DELAY\t8\n#define ICMPV6CTL_ND6_UMAXTRIES\t9\n#define ICMPV6CTL_ND6_MMAXTRIES\t\t10\n#define ICMPV6CTL_ND6_USELOOPBACK\t11\n/*#define ICMPV6CTL_ND6_PROXYALL\t12\tobsoleted, do not reuse here */\n#define ICMPV6CTL_NODEINFO\t13\n#define ICMPV6CTL_ERRPPSLIMIT\t14\t/* ICMPv6 error pps limitation */\n#define ICMPV6CTL_ND6_MAXNUDHINT\t15\n#define ICMPV6CTL_MTUDISC_HIWAT\t16\n#define ICMPV6CTL_MTUDISC_LOWAT\t17\n#define ICMPV6CTL_ND6_DEBUG\t18\n#define ICMPV6CTL_ND6_DRLIST\t19\n#define ICMPV6CTL_ND6_PRLIST\t20\n#define\tICMPV6CTL_ND6_MAXQLEN\t24\n#define ICMPV6CTL_MAXID\t\t25\n\n#define ICMPV6CTL_NAMES { \\\n\t{ 0, 0 }, \\\n\t{ 0, 0 }, \\\n\t{ \"rediraccept\", CTLTYPE_INT }, \\\n\t{ \"redirtimeout\", CTLTYPE_INT }, \\\n\t{ 0, 0 }, \\\n\t{ 0, 0 }, \\\n\t{ \"nd6_prune\", CTLTYPE_INT }, \\\n\t{ 0, 0 }, \\\n\t{ \"nd6_delay\", CTLTYPE_INT }, \\\n\t{ \"nd6_umaxtries\", CTLTYPE_INT }, \\\n\t{ \"nd6_mmaxtries\", CTLTYPE_INT }, \\\n\t{ \"nd6_useloopback\", CTLTYPE_INT }, \\\n\t{ 0, 0 }, \\\n\t{ \"nodeinfo\", CTLTYPE_INT }, \\\n\t{ \"errppslimit\", CTLTYPE_INT }, \\\n\t{ \"nd6_maxnudhint\", CTLTYPE_INT }, \\\n\t{ \"mtudisc_hiwat\", CTLTYPE_INT }, \\\n\t{ \"mtudisc_lowat\", CTLTYPE_INT }, \\\n\t{ \"nd6_debug\", CTLTYPE_INT }, \\\n\t{ 0, 0 }, \\\n\t{ 0, 0 }, \\\n\t{ 0, 0 }, \\\n\t{ 0, 0 }, \\\n\t{ 0, 0 }, \\\n\t{ \"nd6_maxqueuelen\", CTLTYPE_INT }, \\\n}\n\n#ifdef _KERNEL\nstruct\trtentry;\nstruct\trttimer;\nstruct\tin6_multi;\n\nvoid\ticmp6_init(void);\nvoid\ticmp6_paramerror(struct mbuf *, int);\nvoid\ticmp6_error(struct mbuf *, int, int, int);\nvoid\ticmp6_error2(struct mbuf *, int, int, int, struct ifnet *);\nint\ticmp6_input(struct mbuf **, int *, int);\nvoid\ticmp6_fasttimo(void);\nvoid\ticmp6_reflect(struct mbuf *, size_t);\nvoid\ticmp6_prepare(struct mbuf *);\nvoid\ticmp6_redirect_input(struct mbuf *, int);\nvoid\ticmp6_redirect_output(struct mbuf *, struct rtentry *);\nint\ticmp6_sysctl(int *, u_int, void *, size_t *, void *, size_t);\n\nvoid\ticmp6_statinc(u_int);\n\nstruct\tip6ctlparam;\nvoid\ticmp6_mtudisc_update(struct ip6ctlparam *, int);\nvoid\ticmp6_mtudisc_callback_register(void (*)(struct in6_addr *));\n\n/* XXX: is this the right place for these macros? */\n#define icmp6_ifstat_inc(ifp, tag) \\\ndo {\t\t\t\t\t\t\t\t\\\n\tif (ifp)\t\t\t\t\t\t\\\n\t\t((struct in6_ifextra *)((ifp)->if_afdata[AF_INET6]))->icmp6_ifstat->tag++; \\\n} while (/*CONSTCOND*/ 0)\n\n#define icmp6_ifoutstat_inc(ifp, type, code) \\\ndo { \\\n\t\ticmp6_ifstat_inc(ifp, ifs6_out_msg); \\\n\t\tswitch(type) { \\\n\t\t case ICMP6_DST_UNREACH: \\\n\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_dstunreach); \\\n\t\t\t if (code == ICMP6_DST_UNREACH_ADMIN) \\\n\t\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_adminprohib); \\\n\t\t\t break; \\\n\t\t case ICMP6_PACKET_TOO_BIG: \\\n\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_pkttoobig); \\\n\t\t\t break; \\\n\t\t case ICMP6_TIME_EXCEEDED: \\\n\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_timeexceed); \\\n\t\t\t break; \\\n\t\t case ICMP6_PARAM_PROB: \\\n\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_paramprob); \\\n\t\t\t break; \\\n\t\t case ICMP6_ECHO_REQUEST: \\\n\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_echo); \\\n\t\t\t break; \\\n\t\t case ICMP6_ECHO_REPLY: \\\n\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_echoreply); \\\n\t\t\t break; \\\n\t\t case MLD_LISTENER_QUERY: \\\n\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_mldquery); \\\n\t\t\t break; \\\n\t\t case MLD_LISTENER_REPORT: \\\n\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_mldreport); \\\n\t\t\t break; \\\n\t\t case MLD_LISTENER_DONE: \\\n\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_mlddone); \\\n\t\t\t break; \\\n\t\t case ND_ROUTER_SOLICIT: \\\n\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_routersolicit); \\\n\t\t\t break; \\\n\t\t case ND_ROUTER_ADVERT: \\\n\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_routeradvert); \\\n\t\t\t break; \\\n\t\t case ND_NEIGHBOR_SOLICIT: \\\n\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit); \\\n\t\t\t break; \\\n\t\t case ND_NEIGHBOR_ADVERT: \\\n\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert); \\\n\t\t\t break; \\\n\t\t case ND_REDIRECT: \\\n\t\t\t icmp6_ifstat_inc(ifp, ifs6_out_redirect); \\\n\t\t\t break; \\\n\t\t} \\\n} while (/*CONSTCOND*/ 0)\n\nextern int\ticmp6_rediraccept;\t/* accept/process redirects */\nextern int\ticmp6_redirtimeout;\t/* cache time for redirect routes */\n#endif /* _KERNEL */\n\n#ifdef ICMP6_STRINGS\n/* Info: http://www.iana.org/assignments/icmpv6-parameters */\n\nstatic const char * const icmp6_type_err[] = {\n\t\"reserved0\", \"unreach\", \"packet_too_big\", \"timxceed\", \"paramprob\",\n\tNULL\n};\n\nstatic const char * const icmp6_type_info[] = {\n\t\"echo\", \"echoreply\",\n\t\"mcastlistenq\", \"mcastlistenrep\", \"mcastlistendone\",\n\t\"rtsol\", \"rtadv\", \"neighsol\", \"neighadv\", \"redirect\",\n\t\"routerrenum\", \"nodeinfoq\", \"nodeinfor\", \"invneighsol\", \"invneighrep\",\n\t\"mcastlistenrep2\", \"haad_req\", \"haad_rep\",\n\t\"mobile_psol\", \"mobile_padv\", \"cga_sol\", \"cga_adv\",\n\t\"experimental150\", \"mcast_rtadv\", \"mcast_rtsol\", \"mcast_rtterm\",\n\t\"fmipv6_msg\", \"rpl_control\", NULL\n};\n\nstatic const char * const icmp6_code_none[] = { \"none\", NULL };\n\nstatic const char * const icmp6_code_unreach[] = {\n\t\"noroute\", \"admin\", \"beyondscope\", \"addr\", \"port\",\n\t\"srcaddr_policy\", \"reject_route\", \"source_route_err\", NULL\n};\n\nstatic const char * const icmp6_code_timxceed[] = {\n\t\"intrans\", \"reass\", NULL\n};\n\nstatic const char * const icmp6_code_paramprob[] = {\n\t\"hdr_field\", \"nxthdr_type\", \"option\", NULL\n};      \n\n/* not all informational icmps that have codes have a names array */\n#endif\n\n#endif /* !_NETINET_ICMP6_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/netinet/if_ether.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <sys/socket.h>\n#include <linux/if_ether.h>\n#include <linux/if_arp.h>\n#ifndef ETHER_ADDR_LEN\n#define ETHER_ADDR_LEN ETH_ALEN\n#include <net/ethertypes.h>\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/netinet/in.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _NETINET_IN_H_\n#define _NETINET_IN_H_\n\n#include <endian.h>\n#include <netinet/in6.h>\n#include <sys/cdefs.h>\n#include <sys/socket.h>\n\n#include <linux/in.h>\n#include <linux/in6.h>\n#include <linux/ipv6.h>\n\n__BEGIN_DECLS\n\n#define IPPORT_RESERVED  1024\n\n#define INET_ADDRSTRLEN 16\n\ntypedef uint16_t in_port_t;\ntypedef uint32_t in_addr_t;\n\nint bindresvport(int, struct sockaddr_in*);\n\nextern const struct in6_addr in6addr_any;\nextern const struct in6_addr in6addr_loopback;\n\n__END_DECLS\n\n#endif /* _NETINET_IN_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/netinet/in6.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _NETINET_IN6_H\n#define _NETINET_IN6_H\n\n#include <linux/in6.h>\n\n#define IN6_IS_ADDR_UNSPECIFIED(a) \\\n  ((*(const uint32_t*)(&(a)->s6_addr[0]) == 0) && \\\n   (*(const uint32_t*)(&(a)->s6_addr[4]) == 0) && \\\n   (*(const uint32_t*)(&(a)->s6_addr[8]) == 0) && \\\n   (*(const uint32_t*)(&(a)->s6_addr[12]) == 0))\n\n#define IN6_IS_ADDR_LOOPBACK(a) \\\n  ((*(const uint32_t*)(&(a)->s6_addr[0]) == 0) && \\\n   (*(const uint32_t*)(&(a)->s6_addr[4]) == 0) && \\\n   (*(const uint32_t*)(&(a)->s6_addr[8]) == 0) && \\\n   (*(const uint32_t*)(&(a)->s6_addr[12]) == ntohl(1)))\n\n#define IN6_IS_ADDR_V4COMPAT(a) \\\n  ((*(const uint32_t*)(&(a)->s6_addr[0]) == 0) && \\\n   (*(const uint32_t*)(&(a)->s6_addr[4]) == 0) && \\\n   (*(const uint32_t*)(&(a)->s6_addr[8]) == 0) && \\\n   (*(const uint32_t*)(&(a)->s6_addr[12]) != 0) && \\\n   (*(const uint32_t*)(&(a)->s6_addr[12]) != ntohl(1)))\n\n#define IN6_IS_ADDR_V4MAPPED(a) \\\n  ((*(const uint32_t*)(&(a)->s6_addr[0]) == 0) && \\\n   (*(const uint32_t*)(&(a)->s6_addr[4]) == 0) && \\\n   (*(const uint32_t*)(&(a)->s6_addr[8]) == ntohl(0x0000ffff)))\n\n#define __bionic_s6_addr(a) ((const uint8_t*)(a))\n\n#define IN6_IS_ADDR_LINKLOCAL(a) \\\n  ((__bionic_s6_addr(a)[0] == 0xfe) && ((__bionic_s6_addr(a)[1] & 0xc0) == 0x80))\n\n#define IN6_IS_ADDR_SITELOCAL(a) \\\n  ((__bionic_s6_addr(a)[0] == 0xfe) && ((__bionic_s6_addr(a)[1] & 0xc0) == 0xc0))\n\n#define IN6_IS_ADDR_MULTICAST(a) (__bionic_s6_addr(a)[0] == 0xff)\n\n#define IN6_IS_ADDR_ULA(a) ((__bionic_s6_addr(a)[0] & 0xfe) == 0xfc)\n\n#define IPV6_ADDR_SCOPE_NODELOCAL       0x01\n#define IPV6_ADDR_SCOPE_INTFACELOCAL    0x01\n#define IPV6_ADDR_SCOPE_LINKLOCAL       0x02\n#define IPV6_ADDR_SCOPE_SITELOCAL       0x05\n#define IPV6_ADDR_SCOPE_ORGLOCAL        0x08\n#define IPV6_ADDR_SCOPE_GLOBAL          0x0e\n\n#define IPV6_ADDR_MC_SCOPE(a) (__bionic_s6_addr(a)[1] & 0x0f)\n\n#define IN6_IS_ADDR_MC_NODELOCAL(a) \\\n  (IN6_IS_ADDR_MULTICAST(a) && (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL))\n#define IN6_IS_ADDR_MC_LINKLOCAL(a) \\\n  (IN6_IS_ADDR_MULTICAST(a) && (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL))\n#define IN6_IS_ADDR_MC_SITELOCAL(a) \\\n  (IN6_IS_ADDR_MULTICAST(a) && (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_SITELOCAL))\n#define IN6_IS_ADDR_MC_ORGLOCAL(a) \\\n  (IN6_IS_ADDR_MULTICAST(a) && (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL))\n#define IN6_IS_ADDR_MC_GLOBAL(a) \\\n  (IN6_IS_ADDR_MULTICAST(a) && (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL))\n\n#define IN6_ARE_ADDR_EQUAL(a, b) \\\n  (memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)\n\n#define INET6_ADDRSTRLEN 46\n\n#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP\n#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP\n\n#define IN6ADDR_ANY_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}\n#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}}\n\n#define ipv6mr_interface ipv6mr_ifindex\n\n#endif /* _NETINET_IN6_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/netinet/in_systm.h",
    "content": "/*\t$NetBSD: in_systm.h,v 1.13 2005/12/10 23:36:23 elad Exp $\t*/\n\n/*\n * Copyright (c) 1982, 1986, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)in_systm.h\t8.1 (Berkeley) 6/10/93\n */\n\n#ifndef _NETINET_IN_SYSTM_H_\n#define _NETINET_IN_SYSTM_H_\n\n/*\n * Miscellaneous internetwork\n * definitions for kernel.\n */\n\n/*\n * Network types.\n *\n * Internally the system keeps counters in the headers with the bytes\n * swapped so that VAX instructions will work on them.  It reverses\n * the bytes before transmission at each protocol level.  The n_ types\n * represent the types with the bytes in ``high-ender'' order.\n */\ntypedef u_int16_t n_short;\t\t/* short as received from the net */\ntypedef u_int32_t n_long;\t\t/* long as received from the net */\n\ntypedef u_int32_t n_time;\t\t/* ms since 00:00 GMT, byte rev */\n\n#ifdef _KERNEL\nn_time\t iptime (void);\n#endif\n\n#endif /* !_NETINET_IN_SYSTM_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/netinet/ip.h",
    "content": "/*\t$OpenBSD: ip.h,v 1.12 2006/04/27 02:19:32 tedu Exp $\t*/\n/*\t$NetBSD: ip.h,v 1.9 1995/05/15 01:22:44 cgd Exp $\t*/\n\n/*\n * Copyright (c) 1982, 1986, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)ip.h\t8.1 (Berkeley) 6/10/93\n */\n\n#ifndef _NETINET_IP_H_\n#define _NETINET_IP_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <endian.h>\n#include <netinet/in.h>\n#include <netinet/in_systm.h>\n\n__BEGIN_DECLS\n\n/*\n * Definitions for internet protocol version 4.\n * Per RFC 791, September 1981.\n */\n#define\tIPVERSION\t4\n\n/*\n * Structure of an internet header, naked of options.\n */\nstruct ip {\n#if BYTE_ORDER == LITTLE_ENDIAN\n\tu_int32_t ip_hl:4,\t\t/* header length */\n\t\t  ip_v:4;\t\t/* version */\n#endif\n#if BYTE_ORDER == BIG_ENDIAN\n\tu_int32_t ip_v:4,\t\t/* version */\n\t\t  ip_hl:4;\t\t/* header length */\n#endif\n\tu_int8_t  ip_tos;\t\t/* type of service */\n\tu_int16_t ip_len;\t\t/* total length */\n\tu_int16_t ip_id;\t\t/* identification */\n\tu_int16_t ip_off;\t\t/* fragment offset field */\n#define\tIP_RF 0x8000\t\t\t/* reserved fragment flag */\n#define\tIP_DF 0x4000\t\t\t/* dont fragment flag */\n#define\tIP_MF 0x2000\t\t\t/* more fragments flag */\n#define\tIP_OFFMASK 0x1fff\t\t/* mask for fragmenting bits */\n\tu_int8_t  ip_ttl;\t\t/* time to live */\n\tu_int8_t  ip_p;\t\t\t/* protocol */\n\tu_int16_t ip_sum;\t\t/* checksum */\n\tstruct\t  in_addr ip_src, ip_dst; /* source and dest address */\n};\n\n#define\tIP_MAXPACKET\t65535\t\t/* maximum packet size */\n\n/*\n * Definitions for IP type of service (ip_tos)\n */\n#define\tIPTOS_LOWDELAY\t\t0x10\n#define\tIPTOS_THROUGHPUT\t0x08\n#define\tIPTOS_RELIABILITY\t0x04\n#define\tIPTOS_MINCOST\t\t0x02\n#if 1\n/* ECN RFC3168 obsoletes RFC2481, and these will be deprecated soon. */\n#define IPTOS_CE\t\t0x01\t/* congestion experienced */\n#define IPTOS_ECT\t\t0x02\t/* ECN-capable transport */\n#endif\n\n/*\n * Definitions for IP precedence (also in ip_tos) (hopefully unused)\n */\n#define\tIPTOS_PREC_NETCONTROL\t\t0xe0\n#define\tIPTOS_PREC_INTERNETCONTROL\t0xc0\n#define\tIPTOS_PREC_CRITIC_ECP\t\t0xa0\n#define\tIPTOS_PREC_FLASHOVERRIDE\t0x80\n#define\tIPTOS_PREC_FLASH\t\t0x60\n#define\tIPTOS_PREC_IMMEDIATE\t\t0x40\n#define\tIPTOS_PREC_PRIORITY\t\t0x20\n#define\tIPTOS_PREC_ROUTINE\t\t0x00\n\n/*\n * ECN (Explicit Congestion Notification) codepoints in RFC3168\n * mapped to the lower 2 bits of the TOS field.\n */\n#define\tIPTOS_ECN_NOTECT\t0x00\t/* not-ECT */\n#define\tIPTOS_ECN_ECT1\t\t0x01\t/* ECN-capable transport (1) */\n#define\tIPTOS_ECN_ECT0\t\t0x02\t/* ECN-capable transport (0) */\n#define\tIPTOS_ECN_CE\t\t0x03\t/* congestion experienced */\n#define\tIPTOS_ECN_MASK\t\t0x03\t/* ECN field mask */\n\n/*\n * Definitions for options.\n */\n#define\tIPOPT_COPIED(o)\t\t((o)&0x80)\n#define\tIPOPT_CLASS(o)\t\t((o)&0x60)\n#define\tIPOPT_NUMBER(o)\t\t((o)&0x1f)\n\n#define\tIPOPT_CONTROL\t\t0x00\n#define\tIPOPT_RESERVED1\t\t0x20\n#define\tIPOPT_DEBMEAS\t\t0x40\n#define\tIPOPT_RESERVED2\t\t0x60\n\n#define\tIPOPT_EOL\t\t0\t\t/* end of option list */\n#define\tIPOPT_NOP\t\t1\t\t/* no operation */\n\n#define\tIPOPT_RR\t\t7\t\t/* record packet route */\n#define\tIPOPT_TS\t\t68\t\t/* timestamp */\n#define\tIPOPT_SECURITY\t\t130\t\t/* provide s,c,h,tcc */\n#define\tIPOPT_LSRR\t\t131\t\t/* loose source route */\n#define\tIPOPT_SATID\t\t136\t\t/* satnet id */\n#define\tIPOPT_SSRR\t\t137\t\t/* strict source route */\n\n/*\n * Offsets to fields in options other than EOL and NOP.\n */\n#define\tIPOPT_OPTVAL\t\t0\t\t/* option ID */\n#define\tIPOPT_OLEN\t\t1\t\t/* option length */\n#define\tIPOPT_OFFSET\t\t2\t\t/* offset within option */\n#define\tIPOPT_MINOFF\t\t4\t\t/* min value of above */\n\n/*\n * Time stamp option structure.\n */\nstruct\tip_timestamp {\n\tu_int8_t ipt_code;\t\t/* IPOPT_TS */\n\tu_int8_t ipt_len;\t\t/* size of structure (variable) */\n\tu_int8_t ipt_ptr;\t\t/* index of current entry */\n#if _BYTE_ORDER == _LITTLE_ENDIAN\n\tu_int32_t ipt_flg:4,\t\t/* flags, see below */\n\t\t  ipt_oflw:4;\t\t/* overflow counter */\n#endif\n#if _BYTE_ORDER == _BIG_ENDIAN\n\tu_int32_t ipt_oflw:4,\t\t/* overflow counter */\n\t\t  ipt_flg:4;\t\t/* flags, see below */\n#endif\n\tunion ipt_timestamp {\n\tn_time\tipt_time[1];\n\tstruct\tipt_ta {\n\t\tstruct in_addr ipt_addr;\n\t\tn_time ipt_time;\n\t} ipt_ta[1];\n\t} ipt_timestamp;\n};\n\n/* flag bits for ipt_flg */\n#define\tIPOPT_TS_TSONLY\t\t0\t\t/* timestamps only */\n#define\tIPOPT_TS_TSANDADDR\t1\t\t/* timestamps and addresses */\n#define\tIPOPT_TS_PRESPEC\t3\t\t/* specified modules only */\n\n/* bits for security (not byte swapped) */\n#define\tIPOPT_SECUR_UNCLASS\t0x0000\n#define\tIPOPT_SECUR_CONFID\t0xf135\n#define\tIPOPT_SECUR_EFTO\t0x789a\n#define\tIPOPT_SECUR_MMMM\t0xbc4d\n#define\tIPOPT_SECUR_RESTR\t0xaf13\n#define\tIPOPT_SECUR_SECRET\t0xd788\n#define\tIPOPT_SECUR_TOPSECRET\t0x6bc5\n\n/*\n * Internet implementation parameters.\n */\n#define\tMAXTTL\t\t255\t\t/* maximum time to live (seconds) */\n#define\tIPDEFTTL\t64\t\t/* default ttl, from RFC 1340 */\n#define\tIPFRAGTTL\t60\t\t/* time to live for frags, slowhz */\n#define\tIPTTLDEC\t1\t\t/* subtracted when forwarding */\n\n#define\tIP_MSS\t\t576\t\t/* default maximum segment size */\n\n/*\n * This is the real IPv4 pseudo header, used for computing the TCP and UDP\n * checksums. For the Internet checksum, struct ipovly can be used instead.\n * For stronger checksums, the real thing must be used.\n */\nstruct ippseudo {\n\tstruct    in_addr ippseudo_src;\t/* source internet address */\n\tstruct    in_addr ippseudo_dst;\t/* destination internet address */\n\tu_int8_t  ippseudo_pad;\t\t/* pad, must be zero */\n\tu_int8_t  ippseudo_p;\t\t/* protocol */\n\tu_int16_t ippseudo_len;\t\t/* protocol length */\n};\n\n/* BIONIC addition: declarations matching the Linux kernel */\n/*                  some programs expect these...          */\n\n#define IPOPT_OPTVAL 0\n#define IPOPT_OLEN   1\n#define IPOPT_OFFSET 2\n#define IPOPT_MINOFF 4\n#define MAX_IPOPTLEN 40\n\n#define IPOPT_COPY\t\t0x80\n#define IPOPT_CLASS_MASK\t0x60\n#define IPOPT_NUMBER_MASK\t0x1f\n\n#define\tIPOPT_CONTROL\t\t0x00\n#define\tIPOPT_RESERVED1\t\t0x20\n#define\tIPOPT_MEASUREMENT\t0x40\n#define\tIPOPT_RESERVED2\t\t0x60\n\n#define IPOPT_END\t(0 |IPOPT_CONTROL)\n#define IPOPT_NOOP\t(1 |IPOPT_CONTROL)\n#define IPOPT_SEC\t(2 |IPOPT_CONTROL|IPOPT_COPY)\n#define IPOPT_TIMESTAMP\t(4 |IPOPT_MEASUREMENT)\n#define IPOPT_SID\t(8 |IPOPT_CONTROL|IPOPT_COPY)\n#define IPOPT_RA\t(20|IPOPT_CONTROL|IPOPT_COPY)\n\nstruct iphdr {\n#if defined(__LITTLE_ENDIAN_BITFIELD)\n\tuint8_t  ihl    :4,\n\t\t version:4;\n#elif defined (__BIG_ENDIAN_BITFIELD)\n\tuint8_t  version:4,\n  \t\t ihl    :4;\n#else\n#error\t\"Please fix <asm/byteorder.h>\"\n#endif\n\tuint8_t\t  tos;\n\tuint16_t  tot_len;\n\tuint16_t  id;\n\tuint16_t  frag_off;\n\tuint8_t   ttl;\n\tuint8_t   protocol;\n\tuint16_t  check;\n\tint32_t   saddr;\n\tint32_t   daddr;\n};\n\nstruct ip_auth_hdr {\n\tuint8_t  nexthdr;\n\tuint8_t  hdrlen;\n\tuint16_t reserved;\n\tuint32_t spi;\n\tuint32_t seq_no;\n\tuint8_t  auth_data[0];\n};\n\nstruct ip_esp_hdr {\n\tuint32_t spi;\n\tuint32_t seq_no;\n\tuint8_t  enc_data[0];\n};\n\nstruct ip_comp_hdr {\n\tuint8_t  nexthdr;\n\tuint8_t  flags;\n\tuint16_t cpi;\n};\n\n__END_DECLS\n\n#endif /* _NETINET_IP_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/netinet/ip6.h",
    "content": "/*\t$NetBSD: ip6.h,v 1.23 2007/12/25 18:33:46 perry Exp $\t*/\n/*\t$KAME: ip6.h,v 1.45 2003/06/05 04:46:38 keiichi Exp $\t*/\n\n/*\n * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the project nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*\n * Copyright (c) 1982, 1986, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)ip.h\t8.1 (Berkeley) 6/10/93\n */\n\n#ifndef _NETINET_IP6_H_\n#define _NETINET_IP6_H_\n\n/*\n * Definition for internet protocol version 6.\n * RFC 2460\n */\n\nstruct ip6_hdr {\n\tunion {\n\t\tstruct ip6_hdrctl {\n\t\t\tu_int32_t ip6_un1_flow;\t/* 20 bits of flow-ID */\n\t\t\tu_int16_t ip6_un1_plen;\t/* payload length */\n\t\t\tu_int8_t  ip6_un1_nxt;\t/* next header */\n\t\t\tu_int8_t  ip6_un1_hlim;\t/* hop limit */\n\t\t} ip6_un1;\n\t\tu_int8_t ip6_un2_vfc;\t/* 4 bits version, top 4 bits class */\n\t} ip6_ctlun;\n\tstruct in6_addr ip6_src;\t/* source address */\n\tstruct in6_addr ip6_dst;\t/* destination address */\n} __packed;\n\n#define ip6_vfc\t\tip6_ctlun.ip6_un2_vfc\n#define ip6_flow\tip6_ctlun.ip6_un1.ip6_un1_flow\n#define ip6_plen\tip6_ctlun.ip6_un1.ip6_un1_plen\n#define ip6_nxt\t\tip6_ctlun.ip6_un1.ip6_un1_nxt\n#define ip6_hlim\tip6_ctlun.ip6_un1.ip6_un1_hlim\n#define ip6_hops\tip6_ctlun.ip6_un1.ip6_un1_hlim\n\n#define IPV6_VERSION\t\t0x60\n#define IPV6_VERSION_MASK\t0xf0\n\n#if BYTE_ORDER == BIG_ENDIAN\n#define IPV6_FLOWINFO_MASK\t0x0fffffff\t/* flow info (28 bits) */\n#define IPV6_FLOWLABEL_MASK\t0x000fffff\t/* flow label (20 bits) */\n#else\n#if BYTE_ORDER == LITTLE_ENDIAN\n#define IPV6_FLOWINFO_MASK\t0xffffff0f\t/* flow info (28 bits) */\n#define IPV6_FLOWLABEL_MASK\t0xffff0f00\t/* flow label (20 bits) */\n#endif /* LITTLE_ENDIAN */\n#endif\n#if 1\n/* ECN bits proposed by Sally Floyd */\n#define IP6TOS_CE\t\t0x01\t/* congestion experienced */\n#define IP6TOS_ECT\t\t0x02\t/* ECN-capable transport */\n#endif\n\n#ifdef _KERNEL\n/*\n * for IPv6 pseudo header checksum\n * XXX nonstandard\n */\nstruct ip6_hdr_pseudo {\n\tstruct in6_addr ip6ph_src;\n\tstruct in6_addr ip6ph_dst;\n\tu_int32_t\tip6ph_len;\n\tu_int8_t\tip6ph_zero[3];\n\tu_int8_t\tip6ph_nxt;\n} __packed;\n#endif\n\n/*\n * Extension Headers\n */\n\nstruct\tip6_ext {\n\tu_int8_t ip6e_nxt;\n\tu_int8_t ip6e_len;\n} __packed;\n\n/* Hop-by-Hop options header */\n/* XXX should we pad it to force alignment on an 8-byte boundary? */\nstruct ip6_hbh {\n\tu_int8_t ip6h_nxt;\t/* next header */\n\tu_int8_t ip6h_len;\t/* length in units of 8 octets */\n\t/* followed by options */\n} __packed;\n\n/* Destination options header */\n/* XXX should we pad it to force alignment on an 8-byte boundary? */\nstruct ip6_dest {\n\tu_int8_t ip6d_nxt;\t/* next header */\n\tu_int8_t ip6d_len;\t/* length in units of 8 octets */\n\t/* followed by options */\n} __packed;\n\n/* Option types and related macros */\n#define IP6OPT_PAD1\t\t0x00\t/* 00 0 00000 */\n#define IP6OPT_PADN\t\t0x01\t/* 00 0 00001 */\n#define IP6OPT_JUMBO\t\t0xC2\t/* 11 0 00010 = 194 */\n#define IP6OPT_NSAP_ADDR\t0xC3\t/* 11 0 00011 */\n#define IP6OPT_TUNNEL_LIMIT\t0x04\t/* 00 0 00100 */\n#define IP6OPT_RTALERT\t\t0x05\t/* 00 0 00101 (KAME definition) */\n#define IP6OPT_ROUTER_ALERT\t0x05\t/* (RFC3542 def, recommended) */\n\n#define IP6OPT_RTALERT_LEN\t4\n#define IP6OPT_RTALERT_MLD\t0\t/* Datagram contains an MLD message */\n#define IP6OPT_RTALERT_RSVP\t1\t/* Datagram contains an RSVP message */\n#define IP6OPT_RTALERT_ACTNET\t2 \t/* contains an Active Networks msg */\n#define IP6OPT_MINLEN\t\t2\n\n#define IP6OPT_TYPE(o)\t\t((o) & 0xC0)\n#define IP6OPT_TYPE_SKIP\t0x00\n#define IP6OPT_TYPE_DISCARD\t0x40\n#define IP6OPT_TYPE_FORCEICMP\t0x80\n#define IP6OPT_TYPE_ICMP\t0xC0\n\n#define IP6OPT_MUTABLE\t\t0x20\n\n/* IPv6 options: common part */\nstruct ip6_opt {\n\tu_int8_t ip6o_type;\n\tu_int8_t ip6o_len;\n} __packed;\n\n/* Jumbo Payload Option */\nstruct ip6_opt_jumbo {\n\tu_int8_t ip6oj_type;\n\tu_int8_t ip6oj_len;\n\tu_int8_t ip6oj_jumbo_len[4];\n} __packed;\n#define IP6OPT_JUMBO_LEN 6\n\n/* NSAP Address Option */\nstruct ip6_opt_nsap {\n\tu_int8_t ip6on_type;\n\tu_int8_t ip6on_len;\n\tu_int8_t ip6on_src_nsap_len;\n\tu_int8_t ip6on_dst_nsap_len;\n\t/* followed by source NSAP */\n\t/* followed by destination NSAP */\n} __packed;\n\n/* Tunnel Limit Option */\nstruct ip6_opt_tunnel {\n\tu_int8_t ip6ot_type;\n\tu_int8_t ip6ot_len;\n\tu_int8_t ip6ot_encap_limit;\n} __packed;\n\n/* Router Alert Option */\nstruct ip6_opt_router {\n\tu_int8_t ip6or_type;\n\tu_int8_t ip6or_len;\n\tu_int8_t ip6or_value[2];\n} __packed;\n/* Router alert values (in network byte order) */\n#if BYTE_ORDER == BIG_ENDIAN\n#define IP6_ALERT_MLD\t0x0000\n#define IP6_ALERT_RSVP\t0x0001\n#define IP6_ALERT_AN\t0x0002\n#else\n#if BYTE_ORDER == LITTLE_ENDIAN\n#define IP6_ALERT_MLD\t0x0000\n#define IP6_ALERT_RSVP\t0x0100\n#define IP6_ALERT_AN\t0x0200\n#endif /* LITTLE_ENDIAN */\n#endif\n\n/* Routing header */\nstruct ip6_rthdr {\n\tu_int8_t  ip6r_nxt;\t/* next header */\n\tu_int8_t  ip6r_len;\t/* length in units of 8 octets */\n\tu_int8_t  ip6r_type;\t/* routing type */\n\tu_int8_t  ip6r_segleft;\t/* segments left */\n\t/* followed by routing type specific data */\n} __packed;\n\n/* Type 0 Routing header */\nstruct ip6_rthdr0 {\n\tu_int8_t  ip6r0_nxt;\t\t/* next header */\n\tu_int8_t  ip6r0_len;\t\t/* length in units of 8 octets */\n\tu_int8_t  ip6r0_type;\t\t/* always zero */\n\tu_int8_t  ip6r0_segleft;\t/* segments left */\n\tu_int32_t ip6r0_reserved;\t/* reserved field */\n} __packed;\n\n/* Fragment header */\nstruct ip6_frag {\n\tu_int8_t  ip6f_nxt;\t\t/* next header */\n\tu_int8_t  ip6f_reserved;\t/* reserved field */\n\tu_int16_t ip6f_offlg;\t\t/* offset, reserved, and flag */\n\tu_int32_t ip6f_ident;\t\t/* identification */\n} __packed;\n\n#if BYTE_ORDER == BIG_ENDIAN\n#define IP6F_OFF_MASK\t\t0xfff8\t/* mask out offset from _offlg */\n#define IP6F_RESERVED_MASK\t0x0006\t/* reserved bits in ip6f_offlg */\n#define IP6F_MORE_FRAG\t\t0x0001\t/* more-fragments flag */\n#else /* BYTE_ORDER == LITTLE_ENDIAN */\n#define IP6F_OFF_MASK\t\t0xf8ff\t/* mask out offset from _offlg */\n#define IP6F_RESERVED_MASK\t0x0600\t/* reserved bits in ip6f_offlg */\n#define IP6F_MORE_FRAG\t\t0x0100\t/* more-fragments flag */\n#endif /* BYTE_ORDER == LITTLE_ENDIAN */\n\n/*\n * Internet implementation parameters.\n */\n#define IPV6_MAXHLIM\t255\t/* maximum hoplimit */\n#define IPV6_DEFHLIM\t64\t/* default hlim */\n#define IPV6_FRAGTTL\t120\t/* ttl for fragment packets, in slowtimo tick */\n#define IPV6_HLIMDEC\t1\t/* subtracted when forwarding */\n\n#define IPV6_MMTU\t1280\t/* minimal MTU and reassembly. 1024 + 256 */\n#define IPV6_MAXPACKET\t65535\t/* ip6 max packet size without Jumbo payload*/\n\n#ifdef _KERNEL\n/*\n * IP6_EXTHDR_GET ensures that intermediate protocol header (from \"off\" to\n * \"len\") is located in single mbuf, on contiguous memory region.\n * The pointer to the region will be returned to pointer variable \"val\",\n * with type \"typ\".\n * IP6_EXTHDR_GET0 does the same, except that it aligns the structure at the\n * very top of mbuf.  GET0 is likely to make memory copy than GET.\n *\n * XXX we're now testing this, needs m_pulldown()\n */\n#define IP6_EXTHDR_GET(val, typ, m, off, len) \\\ndo {\t\t\t\t\t\t\t\t\t\\\n\tstruct mbuf *_t;\t\t\t\t\t\t\\\n\tint _tmp;\t\t\t\t\t\t\t\\\n\tif ((m)->m_len >= (off) + (len))\t\t\t\t\\\n\t\t(val) = (typ)(mtod((m), char *) + (off));\t\t\\\n\telse {\t\t\t\t\t\t\t\t\\\n\t\t_t = m_pulldown((m), (off), (len), &_tmp);\t\t\\\n\t\tif (_t) {\t\t\t\t\t\t\\\n\t\t\tif (_t->m_len < _tmp + (len))\t\t\t\\\n\t\t\t\tpanic(\"m_pulldown malfunction\");\t\\\n\t\t\t(val) = (typ)(mtod(_t, char *) + _tmp);\t\\\n\t\t} else {\t\t\t\t\t\t\\\n\t\t\t(val) = (typ)NULL;\t\t\t\t\\\n\t\t\t(m) = NULL;\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (/*CONSTCOND*/ 0)\n\n#define IP6_EXTHDR_GET0(val, typ, m, off, len) \\\ndo {\t\t\t\t\t\t\t\t\t\\\n\tstruct mbuf *_t;\t\t\t\t\t\t\\\n\tif ((off) == 0 && (m)->m_len >= len)\t\t\t\t\\\n\t\t(val) = (typ)mtod((m), void *);\t\t\t\\\n\telse {\t\t\t\t\t\t\t\t\\\n\t\t_t = m_pulldown((m), (off), (len), NULL);\t\t\\\n\t\tif (_t) {\t\t\t\t\t\t\\\n\t\t\tif (_t->m_len < (len))\t\t\t\t\\\n\t\t\t\tpanic(\"m_pulldown malfunction\");\t\\\n\t\t\t(val) = (typ)mtod(_t, void *);\t\t\t\\\n\t\t} else {\t\t\t\t\t\t\\\n\t\t\t(val) = (typ)NULL;\t\t\t\t\\\n\t\t\t(m) = NULL;\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (/*CONSTCOND*/ 0)\n#endif /*_KERNEL*/\n\n#endif /* !_NETINET_IP6_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/netinet/ip_icmp.h",
    "content": "/*\t$OpenBSD: ip_icmp.h,v 1.21 2005/07/31 03:30:55 pascoe Exp $\t*/\n/*\t$NetBSD: ip_icmp.h,v 1.10 1996/02/13 23:42:28 christos Exp $\t*/\n\n/*\n * Copyright (c) 1982, 1986, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)ip_icmp.h\t8.1 (Berkeley) 6/10/93\n */\n\n#ifndef _NETINET_IP_ICMP_H_\n#define _NETINET_IP_ICMP_H_\n\n#include <netinet/ip.h>\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\n/*\n * Interface Control Message Protocol Definitions.\n * Per RFC 792, September 1981.\n * RFC 950, August 1985. (Address Mask Request / Reply)\n * RFC 1256, September 1991. (Router Advertisement and Solicitation)\n * RFC 1108, November 1991. (Param Problem, Missing Req. Option)\n * RFC 1393, January 1993. (Traceroute)\n * RFC 1475, June 1993. (Datagram Conversion Error)\n * RFC 1812, June 1995. (adm prohib, host precedence, precedence cutoff)\n * RFC 2002, October 1996. (Mobility changes to Router Advertisement)\n */\n\n/*\n * ICMP Router Advertisement data\n */\nstruct icmp_ra_addr {\n\tuint32_t  ira_addr;\n\tuint32_t  ira_preference;\n};\n\n/*\n * Structure of an icmp header.\n */\nstruct icmp {\n\tuint8_t  icmp_type;\t\t/* type of message, see below */\n\tuint8_t  icmp_code;\t\t/* type sub code */\n\tuint16_t icmp_cksum;\t\t/* ones complement cksum of struct */\n\tunion {\n\t\tuint8_t   ih_pptr;\t\t/* ICMP_PARAMPROB */\n\t\tstruct in_addr ih_gwaddr;\t/* ICMP_REDIRECT */\n\t\tstruct ih_idseq {\n\t\t\t  uint16_t  icd_id;\n\t\t\t  uint16_t  icd_seq;\n\t\t} ih_idseq;\n\t\tint32_t   ih_void;\n\n\t\t/* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */\n\t\tstruct ih_pmtu {\n\t\t\t  uint16_t  ipm_void;\n\t\t\t  uint16_t  ipm_nextmtu;\n\t\t} ih_pmtu;\n\n\t\tstruct ih_rtradv {\n\t\t\tuint8_t   irt_num_addrs;\n\t\t\tuint8_t   irt_wpa;\n\t\t\tuint16_t  irt_lifetime;\n\t\t} ih_rtradv;\n\t} icmp_hun;\n#define\ticmp_pptr\t  icmp_hun.ih_pptr\n#define\ticmp_gwaddr\t  icmp_hun.ih_gwaddr\n#define\ticmp_id\t\t  icmp_hun.ih_idseq.icd_id\n#define\ticmp_seq\t  icmp_hun.ih_idseq.icd_seq\n#define\ticmp_void\t  icmp_hun.ih_void\n#define\ticmp_pmvoid\t  icmp_hun.ih_pmtu.ipm_void\n#define\ticmp_nextmtu\t  icmp_hun.ih_pmtu.ipm_nextmtu\n#define\ticmp_num_addrs\t  icmp_hun.ih_rtradv.irt_num_addrs\n#define\ticmp_wpa\t  icmp_hun.ih_rtradv.irt_wpa\n#define\ticmp_lifetime\t  icmp_hun.ih_rtradv.irt_lifetime\n\tunion {\n\t\tstruct id_ts {\n\t\t\t  uint32_t  its_otime;\n\t\t\t  uint32_t  its_rtime;\n\t\t\t  uint32_t  its_ttime;\n\t\t} id_ts;\n\t\tstruct id_ip  {\n\t\t\t  struct ip idi_ip;\n\t\t\t  /* options and then 64 bits of data */\n\t\t} id_ip;\n\t\tuint32_t  id_mask;\n\t\tint8_t\t  id_data[1];\n\t} icmp_dun;\n#define\ticmp_otime\t  icmp_dun.id_ts.its_otime\n#define\ticmp_rtime\t  icmp_dun.id_ts.its_rtime\n#define\ticmp_ttime\t  icmp_dun.id_ts.its_ttime\n#define\ticmp_ip\t\t  icmp_dun.id_ip.idi_ip\n#define\ticmp_mask\t  icmp_dun.id_mask\n#define\ticmp_data\t  icmp_dun.id_data\n};\n\n/*\n * For IPv6 transition related ICMP errors.\n */\n#define\tICMP_V6ADVLENMIN\t(8 + sizeof(struct ip) + 40)\n#define\tICMP_V6ADVLEN(p)\t(8 + ((p)->icmp_ip.ip_hl << 2) + 40)\n\n/*\n * Lower bounds on packet lengths for various types.\n * For the error advice packets must first insure that the\n * packet is large enough to contain the returned ip header.\n * Only then can we do the check to see if 64 bits of packet\n * data have been returned, since we need to check the returned\n * ip header length.\n */\n#define\tICMP_MINLEN\t8\t\t\t\t/* abs minimum */\n#define\tICMP_TSLEN\t(8 + 3 * sizeof (n_time))\t/* timestamp */\n#define\tICMP_MASKLEN\t12\t\t\t\t/* address mask */\n#define\tICMP_ADVLENMIN\t(8 + sizeof (struct ip) + 8)\t/* min */\n#define\tICMP_ADVLEN(p)\t(8 + ((p)->icmp_ip.ip_hl << 2) + 8)\n\t/* N.B.: must separately check that ip_hl >= 5 */\n\n/*\n * Definition of type and code field values.\n *\thttp://www.iana.org/assignments/icmp-parameters\n */\n#define\tICMP_ECHOREPLY\t\t0\t\t/* echo reply */\n#define\tICMP_UNREACH\t\t3\t\t/* dest unreachable, codes: */\n#define\tICMP_UNREACH_NET\t\t0\t/* bad net */\n#define\tICMP_UNREACH_HOST\t\t1\t/* bad host */\n#define\tICMP_UNREACH_PROTOCOL\t\t2\t/* bad protocol */\n#define\tICMP_UNREACH_PORT\t\t3\t/* bad port */\n#define\tICMP_UNREACH_NEEDFRAG\t\t4\t/* IP_DF caused drop */\n#define\tICMP_UNREACH_SRCFAIL\t\t5\t/* src route failed */\n#define\tICMP_UNREACH_NET_UNKNOWN\t6\t/* unknown net */\n#define\tICMP_UNREACH_HOST_UNKNOWN\t7\t/* unknown host */\n#define\tICMP_UNREACH_ISOLATED\t\t8\t/* src host isolated */\n#define\tICMP_UNREACH_NET_PROHIB\t\t9\t/* for crypto devs */\n#define\tICMP_UNREACH_HOST_PROHIB\t10\t/* ditto */\n#define\tICMP_UNREACH_TOSNET\t\t11\t/* bad tos for net */\n#define\tICMP_UNREACH_TOSHOST\t\t12\t/* bad tos for host */\n#define\tICMP_UNREACH_FILTER_PROHIB\t13\t/* prohibited access */\n#define\tICMP_UNREACH_HOST_PRECEDENCE\t14\t/* precedence violat'n*/\n#define\tICMP_UNREACH_PRECEDENCE_CUTOFF\t15\t/* precedence cutoff */\n#define\tICMP_SOURCEQUENCH\t4\t\t/* packet lost, slow down */\n#define\tICMP_REDIRECT\t\t5\t\t/* shorter route, codes: */\n#define\tICMP_REDIRECT_NET\t0\t\t/* for network */\n#define\tICMP_REDIRECT_HOST\t1\t\t/* for host */\n#define\tICMP_REDIRECT_TOSNET\t2\t\t/* for tos and net */\n#define\tICMP_REDIRECT_TOSHOST\t3\t\t/* for tos and host */\n#define\tICMP_ALTHOSTADDR\t6\t\t/* alternate host address */\n#define\tICMP_ECHO\t\t8\t\t/* echo service */\n#define\tICMP_ROUTERADVERT\t9\t\t/* router advertisement */\n#define\tICMP_ROUTERADVERT_NORMAL\t\t0\t/* normal advertisement */\n#define\tICMP_ROUTERADVERT_NOROUTE_COMMON\t16\t/* selective routing */\n#define\tICMP_ROUTERSOLICIT\t10\t\t/* router solicitation */\n#define\tICMP_TIMXCEED\t\t11\t\t/* time exceeded, code: */\n#define\tICMP_TIMXCEED_INTRANS\t0\t\t/* ttl==0 in transit */\n#define\tICMP_TIMXCEED_REASS\t1\t\t/* ttl==0 in reass */\n#define\tICMP_PARAMPROB\t\t12\t\t/* ip header bad */\n#define\tICMP_PARAMPROB_ERRATPTR 0\t\t/* req. opt. absent */\n#define\tICMP_PARAMPROB_OPTABSENT 1\t\t/* req. opt. absent */\n#define\tICMP_PARAMPROB_LENGTH\t2\t\t/* bad length */\n#define\tICMP_TSTAMP\t\t13\t\t/* timestamp request */\n#define\tICMP_TSTAMPREPLY\t14\t\t/* timestamp reply */\n#define\tICMP_IREQ\t\t15\t\t/* information request */\n#define\tICMP_IREQREPLY\t\t16\t\t/* information reply */\n#define\tICMP_MASKREQ\t\t17\t\t/* address mask request */\n#define\tICMP_MASKREPLY\t\t18\t\t/* address mask reply */\n#define\tICMP_TRACEROUTE\t\t30\t\t/* traceroute */\n#define\tICMP_DATACONVERR\t31\t\t/* data conversion error */\n#define\tICMP_MOBILE_REDIRECT\t32\t\t/* mobile host redirect */\n#define\tICMP_IPV6_WHEREAREYOU\t33\t\t/* IPv6 where-are-you */\n#define\tICMP_IPV6_IAMHERE\t34\t\t/* IPv6 i-am-here */\n#define\tICMP_MOBILE_REGREQUEST\t35\t\t/* mobile registration req */\n#define\tICMP_MOBILE_REGREPLY\t36\t\t/* mobile registration reply */\n#define\tICMP_SKIP\t\t39\t\t/* SKIP */\n#define\tICMP_PHOTURIS\t\t40\t\t/* Photuris */\n#define\tICMP_PHOTURIS_UNKNOWN_INDEX\t1\t/* unknown sec index */\n#define\tICMP_PHOTURIS_AUTH_FAILED\t2\t/* auth failed */\n#define\tICMP_PHOTURIS_DECRYPT_FAILED\t3\t/* decrypt failed */\n\n#define\tICMP_MAXTYPE\t\t40\n\n#define\tICMP_INFOTYPE(type) \\\n\t((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \\\n\t(type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \\\n\t(type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \\\n\t(type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \\\n\t(type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)\n\n__END_DECLS\n\n#endif /* _NETINET_IP_ICMP_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/netinet/tcp.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _NETINET_TCP_H\n#define _NETINET_TCP_H\n\n#include <linux/tcp.h>\n\n__BEGIN_DECLS\n\nenum {\n  TCP_ESTABLISHED = 1,\n  TCP_SYN_SENT,\n  TCP_SYN_RECV,\n  TCP_FIN_WAIT1,\n  TCP_FIN_WAIT2,\n  TCP_TIME_WAIT,\n  TCP_CLOSE,\n  TCP_CLOSE_WAIT,\n  TCP_LAST_ACK,\n  TCP_LISTEN,\n  TCP_CLOSING\n};\n\n#define TCPOPT_EOL 0\n#define TCPOPT_NOP 1\n#define TCPOPT_MAXSEG 2\n#define TCPOLEN_MAXSEG 4\n#define TCPOPT_WINDOW 3\n#define TCPOLEN_WINDOW 3\n#define TCPOPT_SACK_PERMITTED 4\n#define TCPOLEN_SACK_PERMITTED 2\n#define TCPOPT_SACK 5\n#define TCPOPT_TIMESTAMP 8\n#define TCPOLEN_TIMESTAMP 10\n#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2)\n\n#define TCPOPT_TSTAMP_HDR (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)\n\n__END_DECLS\n\n#endif /* _NETINET_TCP_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/netinet/udp.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _NETINET_UDP_H\n#define _NETINET_UDP_H\n\n#include <sys/types.h>\n\n#include <linux/udp.h>\n\nstruct udphdr {\n    __extension__ union {\n        struct /* BSD names */ {\n            u_int16_t uh_sport;\n            u_int16_t uh_dport;\n            u_int16_t uh_ulen;\n            u_int16_t uh_sum;\n        };\n        struct /* Linux names */ {\n            u_int16_t source;\n            u_int16_t dest;\n            u_int16_t len;\n            u_int16_t check;\n        };\n    };\n};\n\n#endif /* _NETINET_UDP_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/netpacket/packet.h",
    "content": "#include <linux/if_packet.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/nsswitch.h",
    "content": "/*\t$NetBSD: nsswitch.h,v 1.21 2011/07/17 20:54:34 joerg Exp $\t*/\n\n/*-\n * Copyright (c) 1997, 1998, 1999, 2004 The NetBSD Foundation, Inc.\n * All rights reserved.\n *\n * This code is derived from software contributed to The NetBSD Foundation\n * by Luke Mewburn.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS\n * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\n * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS\n * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n * POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef _NSSWITCH_H\n#define _NSSWITCH_H\t1\n\n#include <sys/types.h>\n#include <stdarg.h>\n\n#define\tNSS_MODULE_INTERFACE_VERSION\t0\n\n#ifndef _PATH_NS_CONF\n#define _PATH_NS_CONF\t\"/etc/nsswitch.conf\"\n#endif\n\n#define\tNS_CONTINUE\t0\n#define\tNS_RETURN\t1\n\n/*\n * Layout of:\n *\tuint32_t ns_src.flags\n */\n\t/* nsswitch.conf status codes and nsdispatch(3) return values */\n#define\tNS_SUCCESS\t(1<<0)\t\t/* entry was found */\n#define\tNS_UNAVAIL\t(1<<1)\t\t/* source not responding, or corrupt */\n#define\tNS_NOTFOUND\t(1<<2)\t\t/* source responded 'no such entry' */\n#define\tNS_TRYAGAIN\t(1<<3)\t\t/* source busy, may respond to retrys */\n#define\tNS_STATUSMASK\t0x000000ff\t/* bitmask to get the status flags */\n\n\t/* internal nsdispatch(3) flags; not settable in nsswitch.conf(5)  */\n#define\tNS_FORCEALL\t(1<<8)\t\t/* force all methods to be invoked; */\n\n/*\n * Currently implemented sources.\n */\n#define NSSRC_FILES\t\"files\"\t\t/* local files */\n#define\tNSSRC_DNS\t\"dns\"\t\t/* DNS; IN for hosts, HS for others */\n#define\tNSSRC_NIS\t\"nis\"\t\t/* YP/NIS */\n#define\tNSSRC_COMPAT\t\"compat\"\t/* passwd,group in YP compat mode */\n\n/*\n * Currently implemented databases.\n */\n#define NSDB_HOSTS\t\t\"hosts\"\n#define NSDB_GROUP\t\t\"group\"\n#define NSDB_GROUP_COMPAT\t\"group_compat\"\n#define NSDB_NETGROUP\t\t\"netgroup\"\n#define NSDB_NETWORKS\t\t\"networks\"\n#define NSDB_PASSWD\t\t\"passwd\"\n#define NSDB_PASSWD_COMPAT\t\"passwd_compat\"\n#define NSDB_SHELLS\t\t\"shells\"\n\n/*\n * Suggested databases to implement.\n */\n#define NSDB_ALIASES\t\t\"aliases\"\n#define NSDB_AUTH\t\t\"auth\"\n#define NSDB_AUTOMOUNT\t\t\"automount\"\n#define NSDB_BOOTPARAMS\t\t\"bootparams\"\n#define NSDB_ETHERS\t\t\"ethers\"\n#define NSDB_EXPORTS\t\t\"exports\"\n#define NSDB_NETMASKS\t\t\"netmasks\"\n#define NSDB_PHONES\t\t\"phones\"\n#define NSDB_PRINTCAP\t\t\"printcap\"\n#define NSDB_PROTOCOLS\t\t\"protocols\"\n#define NSDB_REMOTE\t\t\"remote\"\n#define NSDB_RPC\t\t\"rpc\"\n#define NSDB_SENDMAILVARS\t\"sendmailvars\"\n#define NSDB_SERVICES\t\t\"services\"\n#define NSDB_TERMCAP\t\t\"termcap\"\n#define NSDB_TTYS\t\t\"ttys\"\n\n/*\n * ns_dtab `callback' function signature.\n */\ntypedef\tint (*nss_method)(void *, void *, va_list);\n\n/*\n * ns_dtab - `nsswitch dispatch table'\n * Contains an entry for each source and the appropriate function to call.\n */\ntypedef struct {\n\tconst char\t *src;\n\tnss_method\t callback;\n\tvoid\t\t *cb_data;\n} ns_dtab;\n\n/*\n * Macros to help build an ns_dtab[]\n */\n#define NS_FILES_CB(F,C)\t{ NSSRC_FILES,\tF,\t__UNCONST(C) },\n#define NS_COMPAT_CB(F,C)\t{ NSSRC_COMPAT,\tF,\t__UNCONST(C) },\n\n#ifdef HESIOD\n#   define NS_DNS_CB(F,C)\t{ NSSRC_DNS,\tF,\t__UNCONST(C) },\n#else\n#   define NS_DNS_CB(F,C)\n#endif\n\n#ifdef YP\n#   define NS_NIS_CB(F,C)\t{ NSSRC_NIS,\tF,\t__UNCONST(C) },\n#else\n#   define NS_NIS_CB(F,C)\n#endif\n#define\tNS_NULL_CB\t\t{ .src = NULL },\n\n/*\n * ns_src - `nsswitch source'\n * Used by the nsparser routines to store a mapping between a source\n * and its dispatch control flags for a given database.\n */\ntypedef struct {\n\tconst char\t*name;\n\tuint32_t\t flags;\n} ns_src;\n\n\n/*\n * Default sourcelists (if nsswitch.conf is missing, corrupt,\n * or the requested database doesn't have an entry)\n */\nextern const ns_src __nsdefaultsrc[];\nextern const ns_src __nsdefaultcompat[];\nextern const ns_src __nsdefaultcompat_forceall[];\nextern const ns_src __nsdefaultfiles[];\nextern const ns_src __nsdefaultfiles_forceall[];\nextern const ns_src __nsdefaultnis[];\nextern const ns_src __nsdefaultnis_forceall[];\n\n\n/*\n * ns_mtab - `nsswitch method table'\n * An nsswitch module provides a mapping from (database name, method name)\n * tuples to the nss_method and associated callback data.  Effectively,\n * ns_dtab, but used for dynamically loaded modules.\n */\ntypedef struct {\n\tconst char\t*database;\n\tconst char\t*name;\n\tnss_method\t method;\n\tvoid\t\t*mdata;\n} ns_mtab;\n\n/*\n * nss_module_register_fn - module registration function\n *\tcalled at module load\n * nss_module_unregister_fn - module un-registration function\n *\tcalled at module unload\n */\ntypedef\tvoid (*nss_module_unregister_fn)(ns_mtab *, u_int);\ntypedef\tns_mtab *(*nss_module_register_fn)(const char *, u_int *,\n\t\t\t\t\t   nss_module_unregister_fn *);\n\n#ifdef _NS_PRIVATE\n\n/*\n * Private data structures for back-end nsswitch implementation.\n */\n\n/*\n * ns_dbt - `nsswitch database thang'\n * For each database in /etc/nsswitch.conf there is a ns_dbt, with its\n * name and a list of ns_src's containing the source information.\n */\ntypedef struct {\n\tconst char\t*name;\t\t/* name of database */\n\tns_src\t\t*srclist;\t/* list of sources */\n\tu_int\t\t srclistsize;\t/* size of srclist */\n} ns_dbt;\n\n/*\n * ns_mod - `nsswitch module'\n */\ntypedef struct {\n\tconst char\t*name;\t\t/* module name */\n\tvoid\t\t*handle;\t/* handle from dlopen() */\n\tns_mtab\t\t*mtab;\t\t/* method table */\n\tu_int\t\t mtabsize;\t/* size of mtab */\n\t\t\t\t\t/* called to unload module */\n\tnss_module_unregister_fn unregister;\n} ns_mod;\n\n#endif /* _NS_PRIVATE */\n\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\nint\tnsdispatch(void *, const ns_dtab [], const char *,\n\t\t\tconst char *, const ns_src [], ...) __LIBC_ABI_PUBLIC__;\n\n#ifdef _NS_PRIVATE\nint\t\t _nsdbtaddsrc(ns_dbt *, const ns_src *);\nvoid\t\t _nsdbtdump(const ns_dbt *);\nint\t\t _nsdbtput(const ns_dbt *);\nvoid\t\t _nsyyerror(const char *);\nint\t\t _nsyylex(void);\n#endif /* _NS_PRIVATE */\n\n__END_DECLS\n\n#endif /* !_NSSWITCH_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/paths.h",
    "content": "/*\n * Copyright (c) 1989, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 4. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)paths.h\t8.1 (Berkeley) 6/2/93\n */\n\n#ifndef _PATHS_H_\n#define\t_PATHS_H_\n\n#define\t_PATH_BSHELL\t\"/system/bin/sh\"\n#define\t_PATH_CONSOLE\t\"/dev/console\"\n#define\t_PATH_DEFPATH\t\"/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin\"\n#define\t_PATH_DEV\t\"/dev/\"\n#define\t_PATH_DEVNULL\t\"/dev/null\"\n#define\t_PATH_KLOG\t\"/proc/kmsg\"\n#define\t_PATH_MOUNTED\t\"/proc/mounts\"\n#define\t_PATH_TTY\t\"/dev/tty\"\n\n#endif /* !_PATHS_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/poll.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _POLL_H_\n#define _POLL_H_\n\n#include <sys/cdefs.h>\n#include <linux/poll.h>\n#include <signal.h> /* For sigset_t. */\n#include <time.h> /* For timespec. */\n\n__BEGIN_DECLS\n\ntypedef unsigned int nfds_t;\n\nint poll(struct pollfd*, nfds_t, int);\nint ppoll(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*);\n\nint __poll_chk(struct pollfd*, nfds_t, int, size_t);\nint __poll_real(struct pollfd*, nfds_t, int) __RENAME(poll);\n__errordecl(__poll_too_small_error, \"poll: pollfd array smaller than fd count\");\n\nint __ppoll_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*, size_t);\nint __ppoll_real(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*) __RENAME(ppoll);\n__errordecl(__ppoll_too_small_error, \"ppoll: pollfd array smaller than fd count\");\n\n#if defined(__BIONIC_FORTIFY)\n\n__BIONIC_FORTIFY_INLINE\nint poll(struct pollfd* fds, nfds_t fd_count, int timeout) {\n#if defined(__clang__)\n  return __poll_chk(fds, fd_count, timeout, __bos(fds));\n#else\n  if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n    if (!__builtin_constant_p(fd_count)) {\n      return __poll_chk(fds, fd_count, timeout, __bos(fds));\n    } else if (__bos(fds) / sizeof(*fds) < fd_count) {\n      __poll_too_small_error();\n    }\n  }\n  return __poll_real(fds, fd_count, timeout);\n#endif\n}\n\n__BIONIC_FORTIFY_INLINE\nint ppoll(struct pollfd* fds, nfds_t fd_count, const struct timespec* timeout, const sigset_t* mask) {\n#if defined(__clang__)\n  return __ppoll_chk(fds, fd_count, timeout, mask, __bos(fds));\n#else\n  if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n    if (!__builtin_constant_p(fd_count)) {\n      return __ppoll_chk(fds, fd_count, timeout, mask, __bos(fds));\n    } else if (__bos(fds) / sizeof(*fds) < fd_count) {\n      __ppoll_too_small_error();\n    }\n  }\n  return __ppoll_real(fds, fd_count, timeout, mask);\n#endif\n}\n\n#endif\n\n__END_DECLS\n\n#endif /* _POLL_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/pthread.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _PTHREAD_H_\n#define _PTHREAD_H_\n\n#include <limits.h>\n#include <bits/pthread_types.h>\n#include <sched.h>\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <time.h>\n\ntypedef struct {\n#if defined(__LP64__)\n  int32_t __private[10];\n#else\n  int32_t __private[1];\n#endif\n} pthread_mutex_t;\n\ntypedef long pthread_mutexattr_t;\n\nenum {\n    PTHREAD_MUTEX_NORMAL = 0,\n    PTHREAD_MUTEX_RECURSIVE = 1,\n    PTHREAD_MUTEX_ERRORCHECK = 2,\n\n    PTHREAD_MUTEX_ERRORCHECK_NP = PTHREAD_MUTEX_ERRORCHECK,\n    PTHREAD_MUTEX_RECURSIVE_NP  = PTHREAD_MUTEX_RECURSIVE,\n\n    PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL\n};\n\n#define PTHREAD_MUTEX_INITIALIZER { { ((PTHREAD_MUTEX_NORMAL & 3) << 14) } }\n#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP { { ((PTHREAD_MUTEX_RECURSIVE & 3) << 14) } }\n#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP { { ((PTHREAD_MUTEX_ERRORCHECK & 3) << 14) } }\n\ntypedef struct {\n#if defined(__LP64__)\n  int32_t __private[12];\n#else\n  int32_t __private[1];\n#endif\n} pthread_cond_t;\n\ntypedef long pthread_condattr_t;\n\n#define PTHREAD_COND_INITIALIZER  { { 0 } }\n\ntypedef struct {\n#if defined(__LP64__)\n  int32_t __private[14];\n#else\n  int32_t __private[10];\n#endif\n} pthread_rwlock_t;\n\ntypedef long pthread_rwlockattr_t;\n\n#define PTHREAD_RWLOCK_INITIALIZER  { { 0 } }\n\nenum {\n  PTHREAD_RWLOCK_PREFER_READER_NP = 0,\n  PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP = 1,\n};\n\ntypedef int pthread_key_t;\n\ntypedef int pthread_once_t;\n\n#define PTHREAD_ONCE_INIT 0\n\ntypedef struct {\n#if defined(__LP64__)\n  int64_t __private[4];\n#else\n  int32_t __private[8];\n#endif\n} pthread_barrier_t;\n\ntypedef int pthread_barrierattr_t;\n\n#define PTHREAD_BARRIER_SERIAL_THREAD -1\n\ntypedef struct {\n#if defined(__LP64__)\n  int64_t __private;\n#else\n  int32_t __private[2];\n#endif\n} pthread_spinlock_t;\n\n#if defined(__LP64__)\n#define PTHREAD_STACK_MIN (4 * PAGE_SIZE)\n#else\n#define PTHREAD_STACK_MIN (2 * PAGE_SIZE)\n#endif\n\n#define PTHREAD_CREATE_DETACHED  0x00000001\n#define PTHREAD_CREATE_JOINABLE  0x00000000\n\n#define PTHREAD_PROCESS_PRIVATE  0\n#define PTHREAD_PROCESS_SHARED   1\n\n#define PTHREAD_SCOPE_SYSTEM     0\n#define PTHREAD_SCOPE_PROCESS    1\n\n__BEGIN_DECLS\n\nint pthread_atfork(void (*)(void), void (*)(void), void(*)(void));\n\nint pthread_attr_destroy(pthread_attr_t*) __nonnull((1));\nint pthread_attr_getdetachstate(const pthread_attr_t*, int*) __nonnull((1, 2));\nint pthread_attr_getguardsize(const pthread_attr_t*, size_t*) __nonnull((1, 2));\nint pthread_attr_getschedparam(const pthread_attr_t*, struct sched_param*) __nonnull((1, 2));\nint pthread_attr_getschedpolicy(const pthread_attr_t*, int*) __nonnull((1, 2));\nint pthread_attr_getscope(const pthread_attr_t*, int*) __nonnull((1, 2));\nint pthread_attr_getstack(const pthread_attr_t*, void**, size_t*) __nonnull((1, 2, 3));\nint pthread_attr_getstacksize(const pthread_attr_t*, size_t*) __nonnull((1, 2));\nint pthread_attr_init(pthread_attr_t*) __nonnull((1));\nint pthread_attr_setdetachstate(pthread_attr_t*, int) __nonnull((1));\nint pthread_attr_setguardsize(pthread_attr_t*, size_t) __nonnull((1));\nint pthread_attr_setschedparam(pthread_attr_t*, const struct sched_param*) __nonnull((1, 2));\nint pthread_attr_setschedpolicy(pthread_attr_t*, int) __nonnull((1));\nint pthread_attr_setscope(pthread_attr_t*, int) __nonnull((1));\nint pthread_attr_setstack(pthread_attr_t*, void*, size_t) __nonnull((1));\nint pthread_attr_setstacksize(pthread_attr_t*, size_t) __nonnull((1));\n\nint pthread_condattr_destroy(pthread_condattr_t*) __nonnull((1));\nint pthread_condattr_getclock(const pthread_condattr_t*, clockid_t*) __nonnull((1, 2));\nint pthread_condattr_getpshared(const pthread_condattr_t*, int*) __nonnull((1, 2));\nint pthread_condattr_init(pthread_condattr_t*) __nonnull((1));\nint pthread_condattr_setclock(pthread_condattr_t*, clockid_t) __nonnull((1));\nint pthread_condattr_setpshared(pthread_condattr_t*, int) __nonnull((1));\n\nint pthread_cond_broadcast(pthread_cond_t*) __nonnull((1));\nint pthread_cond_destroy(pthread_cond_t*) __nonnull((1));\nint pthread_cond_init(pthread_cond_t*, const pthread_condattr_t*) __nonnull((1));\nint pthread_cond_signal(pthread_cond_t*) __nonnull((1));\nint pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, const struct timespec*) __nonnull((1, 2, 3));\nint pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*) __nonnull((1, 2));\n\nint pthread_create(pthread_t*, pthread_attr_t const*, void *(*)(void*), void*) __nonnull((1, 3));\nint pthread_detach(pthread_t);\nvoid pthread_exit(void*) __noreturn;\n\nint pthread_equal(pthread_t, pthread_t);\n\nint pthread_getattr_np(pthread_t, pthread_attr_t*) __nonnull((2));\n\nint pthread_getcpuclockid(pthread_t, clockid_t*) __nonnull((2));\n\nint pthread_getschedparam(pthread_t, int*, struct sched_param*) __nonnull((2, 3));\n\nvoid* pthread_getspecific(pthread_key_t);\n\npid_t pthread_gettid_np(pthread_t);\n\nint pthread_join(pthread_t, void**);\n\nint pthread_key_create(pthread_key_t*, void (*)(void*)) __nonnull((1));\nint pthread_key_delete(pthread_key_t);\n\nint pthread_mutexattr_destroy(pthread_mutexattr_t*) __nonnull((1));\nint pthread_mutexattr_getpshared(const pthread_mutexattr_t*, int*) __nonnull((1, 2));\nint pthread_mutexattr_gettype(const pthread_mutexattr_t*, int*) __nonnull((1, 2));\nint pthread_mutexattr_init(pthread_mutexattr_t*) __nonnull((1));\nint pthread_mutexattr_setpshared(pthread_mutexattr_t*, int) __nonnull((1));\nint pthread_mutexattr_settype(pthread_mutexattr_t*, int) __nonnull((1));\n\nint pthread_mutex_destroy(pthread_mutex_t*) __nonnull((1));\nint pthread_mutex_init(pthread_mutex_t*, const pthread_mutexattr_t*) __nonnull((1));\n#if !defined(__LP64__)\nint pthread_mutex_lock(pthread_mutex_t*) /* __nonnull((1)) */;\n#else\nint pthread_mutex_lock(pthread_mutex_t*) __nonnull((1));\n#endif\nint pthread_mutex_timedlock(pthread_mutex_t*, const struct timespec*) __nonnull((1, 2));\nint pthread_mutex_trylock(pthread_mutex_t*) __nonnull((1));\n#if !defined(__LP4__)\nint pthread_mutex_unlock(pthread_mutex_t*) /* __nonnull((1)) */;\n#else\nint pthread_mutex_unlock(pthread_mutex_t*) __nonnull((1));\n#endif\n\nint pthread_once(pthread_once_t*, void (*)(void)) __nonnull((1, 2));\n\nint pthread_rwlockattr_init(pthread_rwlockattr_t*) __nonnull((1));\nint pthread_rwlockattr_destroy(pthread_rwlockattr_t*) __nonnull((1));\nint pthread_rwlockattr_getpshared(const pthread_rwlockattr_t*, int*) __nonnull((1, 2));\nint pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int) __nonnull((1));\nint pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t*, int*) __nonnull((1, 2));\nint pthread_rwlockattr_setkind_np(pthread_rwlockattr_t*, int) __nonnull((1));\n\nint pthread_rwlock_destroy(pthread_rwlock_t*) __nonnull((1));\nint pthread_rwlock_init(pthread_rwlock_t*, const pthread_rwlockattr_t*) __nonnull((1));\nint pthread_rwlock_rdlock(pthread_rwlock_t*) __nonnull((1));\nint pthread_rwlock_timedrdlock(pthread_rwlock_t*, const struct timespec*) __nonnull((1, 2));\nint pthread_rwlock_timedwrlock(pthread_rwlock_t*, const struct timespec*) __nonnull((1, 2));\nint pthread_rwlock_tryrdlock(pthread_rwlock_t*) __nonnull((1));\nint pthread_rwlock_trywrlock(pthread_rwlock_t*) __nonnull((1));\nint pthread_rwlock_unlock(pthread_rwlock_t *) __nonnull((1));\nint pthread_rwlock_wrlock(pthread_rwlock_t*) __nonnull((1));\n\nint pthread_barrierattr_init(pthread_barrierattr_t* attr) __nonnull((1));\nint pthread_barrierattr_destroy(pthread_barrierattr_t* attr) __nonnull((1));\nint pthread_barrierattr_getpshared(pthread_barrierattr_t* attr, int* pshared) __nonnull((1, 2));\nint pthread_barrierattr_setpshared(pthread_barrierattr_t* attr, int pshared) __nonnull((1));\n\nint pthread_barrier_init(pthread_barrier_t*, const pthread_barrierattr_t*, unsigned) __nonnull((1));\nint pthread_barrier_destroy(pthread_barrier_t*) __nonnull((1));\nint pthread_barrier_wait(pthread_barrier_t*) __nonnull((1));\n\nint pthread_spin_destroy(pthread_spinlock_t*) __nonnull((1));\nint pthread_spin_init(pthread_spinlock_t*, int) __nonnull((1));\nint pthread_spin_lock(pthread_spinlock_t*) __nonnull((1));\nint pthread_spin_trylock(pthread_spinlock_t*) __nonnull((1));\nint pthread_spin_unlock(pthread_spinlock_t*) __nonnull((1));\n\npthread_t pthread_self(void) __pure2;\n\nint pthread_setname_np(pthread_t, const char*) __nonnull((2));\n\nint pthread_setschedparam(pthread_t, int, const struct sched_param*) __nonnull((3));\n\nint pthread_setspecific(pthread_key_t, const void*);\n\ntypedef void (*__pthread_cleanup_func_t)(void*);\n\ntypedef struct __pthread_cleanup_t {\n  struct __pthread_cleanup_t*   __cleanup_prev;\n  __pthread_cleanup_func_t      __cleanup_routine;\n  void*                         __cleanup_arg;\n} __pthread_cleanup_t;\n\nextern void __pthread_cleanup_push(__pthread_cleanup_t* c, __pthread_cleanup_func_t, void*);\nextern void __pthread_cleanup_pop(__pthread_cleanup_t*, int);\n\n/* Believe or not, the definitions of pthread_cleanup_push and\n * pthread_cleanup_pop below are correct. Posix states that these\n * can be implemented as macros that might introduce opening and\n * closing braces, and that using setjmp/longjmp/return/break/continue\n * between them results in undefined behavior.\n */\n#define  pthread_cleanup_push(routine, arg)                      \\\n    do {                                                         \\\n        __pthread_cleanup_t  __cleanup;                          \\\n        __pthread_cleanup_push( &__cleanup, (routine), (arg) );  \\\n\n#define  pthread_cleanup_pop(execute)                  \\\n        __pthread_cleanup_pop( &__cleanup, (execute)); \\\n    } while (0);                                       \\\n\n\n#if !defined(__LP64__)\n\n// Bionic additions that are deprecated even in the 32-bit ABI.\n//\n// TODO: Remove them once chromium_org / NFC have switched over.\nint pthread_cond_timedwait_monotonic_np(pthread_cond_t*, pthread_mutex_t*, const struct timespec*);\nint pthread_cond_timedwait_monotonic(pthread_cond_t*, pthread_mutex_t*, const struct timespec*);\n\nint pthread_cond_timedwait_relative_np(pthread_cond_t*, pthread_mutex_t*, const struct timespec*) /* TODO: __attribute__((deprecated(\"use pthread_cond_timedwait instead\")))*/;\n#define HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE 1 /* TODO: stop defining this to push LP32 off this API sooner. */\nint pthread_cond_timeout_np(pthread_cond_t*, pthread_mutex_t*, unsigned) /* TODO: __attribute__((deprecated(\"use pthread_cond_timedwait instead\")))*/;\n\nint pthread_mutex_lock_timeout_np(pthread_mutex_t*, unsigned) __attribute__((deprecated(\"use pthread_mutex_timedlock instead\")));\n\n#endif /* !defined(__LP64__) */\n\n__END_DECLS\n\n#endif /* _PTHREAD_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/pty.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _PTY_H\n#define _PTY_H\n\n#include <sys/cdefs.h>\n\n#include <termios.h>\n#include <sys/ioctl.h>\n\n__BEGIN_DECLS\n\nint openpty(int*, int*, char*, const struct termios*, const struct winsize*);\nint forkpty(int*, char*, const struct termios*, const struct winsize*);\n\n__END_DECLS\n\n#endif /* _PTY_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/pwd.h",
    "content": "/*-\n * Copyright (c) 1989, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n * (c) UNIX System Laboratories, Inc.\n * All or some portions of this file are derived from material licensed\n * to the University of California by American Telephone and Telegraph\n * Co. or Unix System Laboratories, Inc. and are reproduced herein with\n * the permission of UNIX System Laboratories, Inc.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)pwd.h\t8.2 (Berkeley) 1/21/94\n */\n\n/*-\n * Portions Copyright(C) 1995, Jason Downs.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS\n * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _PWD_H_\n#define _PWD_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n#define _PATH_PASSWD        \"/etc/passwd\"\n#define _PATH_MASTERPASSWD  \"/etc/master.passwd\"\n#define _PATH_MASTERPASSWD_LOCK \"/etc/ptmp\"\n\n#define _PATH_PASSWD_CONF   \"/etc/passwd.conf\"\n#define _PATH_PASSWDCONF    _PATH_PASSWD_CONF   /* XXX: compat */\n#define _PATH_USERMGMT_CONF \"/etc/usermgmt.conf\"\n\n#define _PATH_MP_DB     \"/etc/pwd.db\"\n#define _PATH_SMP_DB        \"/etc/spwd.db\"\n\n#define _PATH_PWD_MKDB      \"/usr/sbin/pwd_mkdb\"\n\n#define _PW_KEYBYNAME       '1' /* stored by name */\n#define _PW_KEYBYNUM        '2' /* stored by entry in the \"file\" */\n#define _PW_KEYBYUID        '3' /* stored by uid */\n\n#define _PASSWORD_EFMT1     '_' /* extended DES encryption format */\n#define _PASSWORD_NONDES    '$' /* non-DES encryption formats */\n\n#define _PASSWORD_LEN       128 /* max length, not counting NUL */\n\n#define _PASSWORD_NOUID     0x01    /* flag for no specified uid. */\n#define _PASSWORD_NOGID     0x02    /* flag for no specified gid. */\n#define _PASSWORD_NOCHG     0x04    /* flag for no specified change. */\n#define _PASSWORD_NOEXP     0x08    /* flag for no specified expire. */\n\n#define _PASSWORD_OLDFMT    0x10    /* flag to expect an old style entry */\n#define _PASSWORD_NOWARN    0x20    /* no warnings for bad entries */\n\n#define _PASSWORD_WARNDAYS  14  /* days to warn about expiry */\n#define _PASSWORD_CHGNOW    -1  /* special day to force password change at next login */\n\nstruct passwd\n{\n  char* pw_name;\n  char* pw_passwd;\n  uid_t pw_uid;\n  gid_t pw_gid;\n#ifdef __LP64__\n  char* pw_gecos;\n#else\n  // Note: On LP32, we define pw_gecos to pw_passwd since they're both NULL.\n# define pw_gecos pw_passwd\n#endif\n  char* pw_dir;\n  char* pw_shell;\n};\n\n__BEGIN_DECLS\n\nstruct passwd* getpwnam(const char*);\nstruct passwd* getpwuid(uid_t);\n\nint getpwnam_r(const char*, struct passwd*, char*, size_t, struct passwd**);\nint getpwuid_r(uid_t, struct passwd*, char*, size_t, struct passwd**);\n\n__END_DECLS\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/regex.h",
    "content": "/*\t$OpenBSD: regex.h,v 1.6 2003/06/02 19:34:12 millert Exp $\t*/\n/*\t$NetBSD: regex.h,v 1.4.6.1 1996/06/10 18:57:07 explorer Exp $\t*/\n\n/*-\n * Copyright (c) 1992 Henry Spencer.\n * Copyright (c) 1992, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * This code is derived from software contributed to Berkeley by\n * Henry Spencer of the University of Toronto.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)regex.h\t8.1 (Berkeley) 6/2/93\n */\n\n#ifndef _REGEX_H_\n#define\t_REGEX_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n/* POSIX says regoff_t is at least as large as the larger of ptrdiff_t and\n * ssize_t. BSD uses off_t, but that interacts badly with _FILE_OFFSET_BITS. */\ntypedef ssize_t regoff_t;\n\ntypedef struct {\n\tint re_magic;\n\tsize_t re_nsub;\t\t/* number of parenthesized subexpressions */\n\tconst char *re_endp;\t/* end pointer for REG_PEND */\n\tstruct re_guts *re_g;\t/* none of your business :-) */\n} regex_t;\n\ntypedef struct {\n\tregoff_t rm_so;\t\t/* start of match */\n\tregoff_t rm_eo;\t\t/* end of match */\n} regmatch_t;\n\n/* regcomp() flags */\n#define\tREG_BASIC\t0000\n#define\tREG_EXTENDED\t0001\n#define\tREG_ICASE\t0002\n#define\tREG_NOSUB\t0004\n#define\tREG_NEWLINE\t0010\n#define\tREG_NOSPEC\t0020\n#define\tREG_PEND\t0040\n#define\tREG_DUMP\t0200\n\n/* regerror() flags */\n#define\tREG_NOMATCH\t 1\n#define\tREG_BADPAT\t 2\n#define\tREG_ECOLLATE\t 3\n#define\tREG_ECTYPE\t 4\n#define\tREG_EESCAPE\t 5\n#define\tREG_ESUBREG\t 6\n#define\tREG_EBRACK\t 7\n#define\tREG_EPAREN\t 8\n#define\tREG_EBRACE\t 9\n#define\tREG_BADBR\t10\n#define\tREG_ERANGE\t11\n#define\tREG_ESPACE\t12\n#define\tREG_BADRPT\t13\n#define\tREG_EMPTY\t14\n#define\tREG_ASSERT\t15\n#define\tREG_INVARG\t16\n#define\tREG_ATOI\t255\t/* convert name to number (!) */\n#define\tREG_ITOA\t0400\t/* convert number to name (!) */\n\n/* regexec() flags */\n#define\tREG_NOTBOL\t00001\n#define\tREG_NOTEOL\t00002\n#define\tREG_STARTEND\t00004\n#define\tREG_TRACE\t00400\t/* tracing of execution */\n#define\tREG_LARGE\t01000\t/* force large representation */\n#define\tREG_BACKR\t02000\t/* force use of backref code */\n\n__BEGIN_DECLS\nint\tregcomp(regex_t *, const char *, int);\nsize_t\tregerror(int, const regex_t *, char *, size_t);\nint\tregexec(const regex_t *, const char *, size_t, regmatch_t [], int);\nvoid\tregfree(regex_t *);\n__END_DECLS\n\n#endif /* !_REGEX_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/resolv.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _RESOLV_H_\n#define _RESOLV_H_\n\n#include <sys/param.h>\n#include <sys/types.h>\n#include <sys/cdefs.h>\n#include <sys/socket.h>\n#include <stdio.h>\n#include <arpa/nameser.h>\n#include <netinet/in.h>\n\n__BEGIN_DECLS\n#pragma GCC visibility push(default)\n\nstruct res_state;\n\nextern struct __res_state *__res_state(void);\n#define _res (*__res_state())\n\n#define b64_ntop __b64_ntop\n#define b64_pton __b64_pton\nextern int b64_ntop(u_char const*, size_t, char*, size_t);\nextern int b64_pton(char const*, u_char*, size_t);\n\n#define dn_comp __dn_comp\nextern int dn_comp(const char*, u_char*, int, u_char**, u_char**);\nextern int dn_expand(const u_char*, const u_char*, const u_char*, char*, int);\n\n#pragma GCC visibility pop\n__END_DECLS\n\n#endif /* _RESOLV_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sched.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SCHED_H_\n#define _SCHED_H_\n\n#include <bits/timespec.h>\n#include <linux/sched.h>\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\n/* This name is used by glibc, but not by the kernel. */\n#define SCHED_OTHER SCHED_NORMAL\n\nstruct sched_param {\n  int sched_priority;\n};\n\nextern int sched_setscheduler(pid_t, int, const struct sched_param*);\nextern int sched_getscheduler(pid_t);\nextern int sched_yield(void);\nextern int sched_get_priority_max(int);\nextern int sched_get_priority_min(int);\nextern int sched_setparam(pid_t, const struct sched_param*);\nextern int sched_getparam(pid_t, struct sched_param*);\nextern int sched_rr_get_interval(pid_t, struct timespec*);\n\n#if defined(__USE_GNU)\n\nextern int clone(int (*)(void*), void*, int, void*, ...);\nextern int unshare(int);\nextern int sched_getcpu(void);\nextern int setns(int, int);\n\n#ifdef __LP64__\n#define CPU_SETSIZE 1024\n#else\n#define CPU_SETSIZE 32\n#endif\n\n#define __CPU_BITTYPE  unsigned long int  /* mandated by the kernel  */\n#define __CPU_BITS     (8 * sizeof(__CPU_BITTYPE))\n#define __CPU_ELT(x)   ((x) / __CPU_BITS)\n#define __CPU_MASK(x)  ((__CPU_BITTYPE)1 << ((x) & (__CPU_BITS - 1)))\n\ntypedef struct {\n  __CPU_BITTYPE  __bits[ CPU_SETSIZE / __CPU_BITS ];\n} cpu_set_t;\n\nextern int sched_setaffinity(pid_t pid, size_t setsize, const cpu_set_t* set);\n\nextern int sched_getaffinity(pid_t pid, size_t setsize, cpu_set_t* set);\n\n#define CPU_ZERO(set)          CPU_ZERO_S(sizeof(cpu_set_t), set)\n#define CPU_SET(cpu, set)      CPU_SET_S(cpu, sizeof(cpu_set_t), set)\n#define CPU_CLR(cpu, set)      CPU_CLR_S(cpu, sizeof(cpu_set_t), set)\n#define CPU_ISSET(cpu, set)    CPU_ISSET_S(cpu, sizeof(cpu_set_t), set)\n#define CPU_COUNT(set)         CPU_COUNT_S(sizeof(cpu_set_t), set)\n#define CPU_EQUAL(set1, set2)  CPU_EQUAL_S(sizeof(cpu_set_t), set1, set2)\n\n#define CPU_AND(dst, set1, set2)  __CPU_OP(dst, set1, set2, &)\n#define CPU_OR(dst, set1, set2)   __CPU_OP(dst, set1, set2, |)\n#define CPU_XOR(dst, set1, set2)  __CPU_OP(dst, set1, set2, ^)\n\n#define __CPU_OP(dst, set1, set2, op)  __CPU_OP_S(sizeof(cpu_set_t), dst, set1, set2, op)\n\n/* Support for dynamically-allocated cpu_set_t */\n\n#define CPU_ALLOC_SIZE(count) \\\n  __CPU_ELT((count) + (__CPU_BITS - 1)) * sizeof(__CPU_BITTYPE)\n\n#define CPU_ALLOC(count)  __sched_cpualloc((count))\n#define CPU_FREE(set)     __sched_cpufree((set))\n\nextern cpu_set_t* __sched_cpualloc(size_t count);\nextern void       __sched_cpufree(cpu_set_t* set);\n\n#define CPU_ZERO_S(setsize, set)  __builtin_memset(set, 0, setsize)\n\n#define CPU_SET_S(cpu, setsize, set) \\\n  do { \\\n    size_t __cpu = (cpu); \\\n    if (__cpu < 8 * (setsize)) \\\n      (set)->__bits[__CPU_ELT(__cpu)] |= __CPU_MASK(__cpu); \\\n  } while (0)\n\n#define CPU_CLR_S(cpu, setsize, set) \\\n  do { \\\n    size_t __cpu = (cpu); \\\n    if (__cpu < 8 * (setsize)) \\\n      (set)->__bits[__CPU_ELT(__cpu)] &= ~__CPU_MASK(__cpu); \\\n  } while (0)\n\n#define CPU_ISSET_S(cpu, setsize, set) \\\n  (__extension__ ({ \\\n    size_t __cpu = (cpu); \\\n    (__cpu < 8 * (setsize)) \\\n      ? ((set)->__bits[__CPU_ELT(__cpu)] & __CPU_MASK(__cpu)) != 0 \\\n      : 0; \\\n  }))\n\n#define CPU_EQUAL_S(setsize, set1, set2)  (__builtin_memcmp(set1, set2, setsize) == 0)\n\n#define CPU_AND_S(setsize, dst, set1, set2)  __CPU_OP_S(setsize, dst, set1, set2, &)\n#define CPU_OR_S(setsize, dst, set1, set2)   __CPU_OP_S(setsize, dst, set1, set2, |)\n#define CPU_XOR_S(setsize, dst, set1, set2)  __CPU_OP_S(setsize, dst, set1, set2, ^)\n\n#define __CPU_OP_S(setsize, dstset, srcset1, srcset2, op) \\\n  do { \\\n    cpu_set_t* __dst = (dstset); \\\n    const __CPU_BITTYPE* __src1 = (srcset1)->__bits; \\\n    const __CPU_BITTYPE* __src2 = (srcset2)->__bits; \\\n    size_t __nn = 0, __nn_max = (setsize)/sizeof(__CPU_BITTYPE); \\\n    for (; __nn < __nn_max; __nn++) \\\n      (__dst)->__bits[__nn] = __src1[__nn] op __src2[__nn]; \\\n  } while (0)\n\n#define CPU_COUNT_S(setsize, set)  __sched_cpucount((setsize), (set))\n\nextern int __sched_cpucount(size_t setsize, cpu_set_t* set);\n\n#endif /* __USE_GNU */\n\n__END_DECLS\n\n#endif /* _SCHED_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/search.h",
    "content": "/*-\n * Written by J.T. Conklin <jtc@netbsd.org>\n * Public domain.\n *\n *\t$NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $\n * $FreeBSD: release/9.0.0/include/search.h 105250 2002-10-16 14:29:23Z robert $\n */\n\n#ifndef _SEARCH_H_\n#define _SEARCH_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\ntypedef enum {\n  preorder,\n  postorder,\n  endorder,\n  leaf\n} VISIT;\n\n#ifdef _SEARCH_PRIVATE\ntypedef struct node {\n  char* key;\n  struct node* llink;\n  struct node* rlink;\n} node_t;\n#endif\n\n__BEGIN_DECLS\n\nvoid insque(void*, void*);\nvoid remque(void*);\n\nvoid* lfind(const void*, const void*, size_t*, size_t, int (*)(const void*, const void*));\nvoid* lsearch(const void*, void*, size_t*, size_t, int (*)(const void*, const void*));\n\nvoid* tdelete(const void* __restrict, void** __restrict, int (*)(const void*, const void*));\nvoid tdestroy(void*, void (*)(void*));\nvoid* tfind(const void*, void* const*, int (*)(const void*, const void*));\nvoid* tsearch(const void*, void**, int (*)(const void*, const void*));\nvoid twalk(const void*, void (*)(const void*, VISIT, int));\n\n__END_DECLS\n\n#endif /* !_SEARCH_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/semaphore.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SEMAPHORE_H\n#define _SEMAPHORE_H\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\nstruct timespec;\n\ntypedef struct {\n  unsigned int count;\n#ifdef __LP64__\n  int __reserved[3];\n#endif\n} sem_t;\n\n#define SEM_FAILED NULL\n\nint sem_destroy(sem_t*);\nint sem_getvalue(sem_t*, int*);\nint sem_init(sem_t*, int, unsigned int);\nint sem_post(sem_t*);\nint sem_timedwait(sem_t*, const struct timespec*);\nint sem_trywait(sem_t*);\nint sem_wait(sem_t*);\n\n/* These aren't actually implemented. */\nsem_t* sem_open(const char*, int, ...);\nint sem_close(sem_t*);\nint sem_unlink(const char*);\n\n__END_DECLS\n\n#endif /* _SEMAPHORE_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/setjmp.h",
    "content": "/*\t$OpenBSD: setjmp.h,v 1.5 2005/12/13 00:35:22 millert Exp $\t*/\n/*\t$NetBSD: setjmp.h,v 1.11 1994/12/20 10:35:44 cgd Exp $\t*/\n\n/*-\n * Copyright (c) 1990, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n * (c) UNIX System Laboratories, Inc.\n * All or some portions of this file are derived from material licensed\n * to the University of California by American Telephone and Telegraph\n * Co. or Unix System Laboratories, Inc. and are reproduced herein with\n * the permission of UNIX System Laboratories, Inc.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)setjmp.h\t8.2 (Berkeley) 1/21/94\n */\n\n#ifndef _SETJMP_H_\n#define _SETJMP_H_\n\n#include <sys/cdefs.h>\n#include <machine/setjmp.h>\n\ntypedef long sigjmp_buf[_JBLEN + 1];\ntypedef long jmp_buf[_JBLEN];\n\n__BEGIN_DECLS\n\nint     _setjmp(jmp_buf);\nvoid    _longjmp(jmp_buf, int);\n\nint     setjmp(jmp_buf);\nvoid    longjmp(jmp_buf, int);\n\nint     sigsetjmp(sigjmp_buf, int);\nvoid    siglongjmp(sigjmp_buf, int);\n\n__END_DECLS\n\n#endif /* !_SETJMP_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sgtty.h",
    "content": "/*\t$NetBSD: sgtty.h,v 1.8 2005/02/03 04:39:32 perry Exp $\t*/\n\n/*\n * Copyright (c) 1985, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)sgtty.h\t8.1 (Berkeley) 6/2/93\n */\n\n#ifndef _SGTTY_H_\n#define _SGTTY_H_\n\n#ifndef USE_OLD_TTY\n#define\tUSE_OLD_TTY\n#endif\n#include <sys/ioctl.h>\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\nint gtty(int, struct sgttyb *);\nint stty(int, struct sgttyb *);\n__END_DECLS\n\n#endif /* _SGTTY_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/signal.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SIGNAL_H_\n#define _SIGNAL_H_\n\n#include <asm/sigcontext.h>\n#include <bits/pthread_types.h>\n#include <bits/timespec.h>\n#include <limits.h>\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n#if defined(__LP64__) || defined(__mips__)\n/* For 64-bit (and mips), the kernel's struct sigaction doesn't match the POSIX one,\n * so we need to expose our own and translate behind the scenes. */\n#  define sigaction __kernel_sigaction\n#  include <linux/signal.h>\n#  undef sigaction\n#else\n/* For 32-bit, we're stuck with the definitions we already shipped,\n * even though they contain a sigset_t that's too small. */\n#  include <linux/signal.h>\n#endif\n\n#include <sys/ucontext.h>\n#define __BIONIC_HAVE_UCONTEXT_T\n\n__BEGIN_DECLS\n\ntypedef int sig_atomic_t;\n\n/* The arm and x86 kernel header files don't define _NSIG. */\n#ifndef _KERNEL__NSIG\n#define _KERNEL__NSIG 64\n#endif\n\n/* Userspace's NSIG is the kernel's _NSIG + 1. */\n#define _NSIG (_KERNEL__NSIG + 1)\n#define NSIG _NSIG\n\n/* We take a few real-time signals for ourselves. May as well use the same names as glibc. */\n#define SIGRTMIN (__libc_current_sigrtmin())\n#define SIGRTMAX (__libc_current_sigrtmax())\nextern int __libc_current_sigrtmin(void);\nextern int __libc_current_sigrtmax(void);\n\nextern const char* const sys_siglist[];\nextern const char* const sys_signame[]; /* BSD compatibility. */\n\ntypedef __sighandler_t sig_t; /* BSD compatibility. */\ntypedef __sighandler_t sighandler_t; /* glibc compatibility. */\n\n#define si_timerid si_tid /* glibc compatibility. */\n\n#if defined(__LP64__)\n\nstruct sigaction {\n  unsigned int sa_flags;\n  union {\n    sighandler_t sa_handler;\n    void (*sa_sigaction)(int, struct siginfo*, void*);\n  };\n  sigset_t sa_mask;\n  void (*sa_restorer)(void);\n};\n\n#elif defined(__mips__)\n\nstruct sigaction {\n  unsigned int sa_flags;\n  union {\n    sighandler_t sa_handler;\n    void (*sa_sigaction) (int, struct siginfo*, void*);\n  };\n  sigset_t sa_mask;\n};\n\n#endif\n\nextern int sigaction(int, const struct sigaction*, struct sigaction*);\n\nextern sighandler_t signal(int, sighandler_t) __INTRODUCED_IN(21);\n\nextern int siginterrupt(int, int);\n\nextern int sigaddset(sigset_t*, int) __INTRODUCED_IN(21);\nextern int sigdelset(sigset_t*, int) __INTRODUCED_IN(21);\nextern int sigemptyset(sigset_t*) __INTRODUCED_IN(21);\nextern int sigfillset(sigset_t*) __INTRODUCED_IN(21);\nextern int sigismember(const sigset_t*, int) __INTRODUCED_IN(21);\n\nextern int sigpending(sigset_t*) __nonnull((1));\nextern int sigprocmask(int, const sigset_t*, sigset_t*);\nextern int sigsuspend(const sigset_t*) __nonnull((1));\nextern int sigwait(const sigset_t*, int*) __nonnull((1, 2));\n\nextern int raise(int);\nextern int kill(pid_t, int);\nextern int killpg(int, int);\n\nextern int sigaltstack(const stack_t*, stack_t*);\n\nextern void psiginfo(const siginfo_t*, const char*);\nextern void psignal(int, const char*);\n\nextern int pthread_kill(pthread_t, int);\nextern int pthread_sigmask(int, const sigset_t*, sigset_t*);\n\nextern int sigqueue(pid_t, int, const union sigval);\nextern int sigtimedwait(const sigset_t*, siginfo_t*, const struct timespec*);\nextern int sigwaitinfo(const sigset_t*, siginfo_t*);\n\n#if __ANDROID_API__ < 21\n#include <android/legacy_signal_inlines.h>\n#endif\n\n__END_DECLS\n\n#endif /* _SIGNAL_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/stdatomic.h",
    "content": "/*-\n * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org>\n *                    David Chisnall <theraven@FreeBSD.org>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n * $FreeBSD$\n */\n\n#ifndef _STDATOMIC_H_\n#define\t_STDATOMIC_H_\n\n#include <sys/cdefs.h>\n\n#if defined(__GNUC__) && !defined(__GNUC_PREREQ)\n/* Duplicate definition here, since the mingw sys/cdefs.h omits the  */\n/* definition, and this needs to be usable there.                    */\n#define\t__GNUC_PREREQ(x, y)    \\\n\t((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || (__GNUC__ > (x)))\n#endif /* __GNUC__ && ... */\n\n#if defined(__cplusplus) && __cplusplus >= 201103L && defined(_USING_LIBCXX)\n# ifdef __clang__\n#  if __has_feature(cxx_atomic)\n#   define _STDATOMIC_HAVE_ATOMIC\n#  endif\n# else /* gcc */\n#  if __GNUC_PREREQ(4, 7)\n#   define _STDATOMIC_HAVE_ATOMIC\n#  endif\n# endif\n#endif\n\n#ifdef _STDATOMIC_HAVE_ATOMIC\n\n/* We have a usable C++ <atomic>; use it instead.  */\n\n#include <atomic>\n\n#undef _Atomic\n        /* Also defined by <atomic> for gcc.  But not used in macros. */\n        /* Also a clang intrinsic.                                    */\n        /* Should not be used by client code before this file is      */\n        /* included.  The definitions in <atomic> themselves see      */\n        /* the old definition, as they should.                        */\n        /* Client code sees the following definition.                 */\n\n#define _Atomic(t) std::atomic<t>\n\nusing std::atomic_is_lock_free;\nusing std::atomic_init;\nusing std::atomic_store;\nusing std::atomic_store_explicit;\nusing std::atomic_load;\nusing std::atomic_load_explicit;\nusing std::atomic_exchange;\nusing std::atomic_exchange_explicit;\nusing std::atomic_compare_exchange_strong;\nusing std::atomic_compare_exchange_strong_explicit;\nusing std::atomic_compare_exchange_weak;\nusing std::atomic_compare_exchange_weak_explicit;\nusing std::atomic_fetch_add;\nusing std::atomic_fetch_add_explicit;\nusing std::atomic_fetch_sub;\nusing std::atomic_fetch_sub_explicit;\nusing std::atomic_fetch_or;\nusing std::atomic_fetch_or_explicit;\nusing std::atomic_fetch_xor;\nusing std::atomic_fetch_xor_explicit;\nusing std::atomic_fetch_and;\nusing std::atomic_fetch_and_explicit;\nusing std::atomic_thread_fence;\nusing std::atomic_signal_fence;\n\nusing std::memory_order;\nusing std::memory_order_relaxed;\nusing std::memory_order_consume;\nusing std::memory_order_acquire;\nusing std::memory_order_release;\nusing std::memory_order_acq_rel;\nusing std::memory_order_seq_cst;\n\nusing std::atomic_bool;\nusing std::atomic_char;\nusing std::atomic_schar;\nusing std::atomic_uchar;\nusing std::atomic_short;\nusing std::atomic_ushort;\nusing std::atomic_int;\nusing std::atomic_uint;\nusing std::atomic_long;\nusing std::atomic_ulong;\nusing std::atomic_llong;\nusing std::atomic_ullong;\nusing std::atomic_char16_t;\nusing std::atomic_char32_t;\nusing std::atomic_wchar_t;\nusing std::atomic_int_least8_t;\nusing std::atomic_uint_least8_t;\nusing std::atomic_int_least16_t;\nusing std::atomic_uint_least16_t;\nusing std::atomic_int_least32_t;\nusing std::atomic_uint_least32_t;\nusing std::atomic_int_least64_t;\nusing std::atomic_uint_least64_t;\nusing std::atomic_int_fast8_t;\nusing std::atomic_uint_fast8_t;\nusing std::atomic_int_fast16_t;\nusing std::atomic_uint_fast16_t;\nusing std::atomic_int_fast32_t;\nusing std::atomic_uint_fast32_t;\nusing std::atomic_int_fast64_t;\nusing std::atomic_uint_fast64_t;\nusing std::atomic_intptr_t;\nusing std::atomic_uintptr_t;\nusing std::atomic_size_t;\nusing std::atomic_ptrdiff_t;\nusing std::atomic_intmax_t;\nusing std::atomic_uintmax_t;\n\n#else /* <atomic> unavailable, possibly because this is C, not C++ */\n\n#include <sys/types.h>\n#include <stdbool.h>\n\n/*\n * C: Do it ourselves.\n * Note that the runtime representation defined here should be compatible\n * with the C++ one, i.e. an _Atomic(T) needs to contain the same\n * bits as a T.\n */\n\n#include <stddef.h>  /* For ptrdiff_t.                          */\n#include <stdint.h>  /* TODO: Should pollute namespace less.    */\n#if __STDC_VERSION__ >= 201112L\n# include <uchar.h>  /* For char16_t and char32_t.              */\n#endif\n\n#ifdef __clang__\n# if __has_extension(c_atomic) || __has_extension(cxx_atomic)\n#  define       __CLANG_ATOMICS\n# else\n#  error \"stdatomic.h does not support your compiler\"\n# endif\n# if __has_builtin(__sync_swap)\n#  define __HAS_BUILTIN_SYNC_SWAP\n# endif\n#else\n# if __GNUC_PREREQ(4, 7)\n#  define\t__GNUC_ATOMICS\n# else\n#  define\t__SYNC_ATOMICS\n#  ifdef __cplusplus\n#   define       __ATOMICS_AVOID_DOT_INIT\n#  endif\n# endif\n#endif\n\n/*\n * 7.17.1 Atomic lock-free macros.\n */\n\n#ifdef __GCC_ATOMIC_BOOL_LOCK_FREE\n#define\tATOMIC_BOOL_LOCK_FREE\t\t__GCC_ATOMIC_BOOL_LOCK_FREE\n#elif defined(__SYNC_ATOMICS)\n#define\tATOMIC_BOOL_LOCK_FREE           2 /* For all modern platforms */\n#endif\n#ifdef __GCC_ATOMIC_CHAR_LOCK_FREE\n#define\tATOMIC_CHAR_LOCK_FREE\t\t__GCC_ATOMIC_CHAR_LOCK_FREE\n#elif defined(__SYNC_ATOMICS)\n#define\tATOMIC_CHAR_LOCK_FREE           2\n#endif\n#ifdef __GCC_ATOMIC_CHAR16_T_LOCK_FREE\n#define\tATOMIC_CHAR16_T_LOCK_FREE\t__GCC_ATOMIC_CHAR16_T_LOCK_FREE\n#elif defined(__SYNC_ATOMICS)\n#define\tATOMIC_CHAR16_T_LOCK_FREE       2\n#endif\n#ifdef __GCC_ATOMIC_CHAR32_T_LOCK_FREE\n#define\tATOMIC_CHAR32_T_LOCK_FREE\t__GCC_ATOMIC_CHAR32_T_LOCK_FREE\n#elif defined(__SYNC_ATOMICS)\n#define\tATOMIC_CHAR32_T_LOCK_FREE       2\n#endif\n#ifdef __GCC_ATOMIC_WCHAR_T_LOCK_FREE\n#define\tATOMIC_WCHAR_T_LOCK_FREE\t__GCC_ATOMIC_WCHAR_T_LOCK_FREE\n#elif defined(__SYNC_ATOMICS)\n#define\tATOMIC_WCHAR_T_LOCK_FREE        2\n#endif\n#ifdef __GCC_ATOMIC_SHORT_LOCK_FREE\n#define\tATOMIC_SHORT_LOCK_FREE\t\t__GCC_ATOMIC_SHORT_LOCK_FREE\n#elif defined(__SYNC_ATOMICS)\n#define\tATOMIC_SHORT_LOCK_FREE          2\n#endif\n#ifdef __GCC_ATOMIC_INT_LOCK_FREE\n#define\tATOMIC_INT_LOCK_FREE\t\t__GCC_ATOMIC_INT_LOCK_FREE\n#elif defined(__SYNC_ATOMICS)\n#define\tATOMIC_INT_LOCK_FREE            2\n#endif\n#ifdef __GCC_ATOMIC_LONG_LOCK_FREE\n#define\tATOMIC_LONG_LOCK_FREE\t\t__GCC_ATOMIC_LONG_LOCK_FREE\n#elif defined(__SYNC_ATOMICS)\n#define\tATOMIC_LONG_LOCK_FREE           2\n#endif\n#ifdef __GCC_ATOMIC_LLONG_LOCK_FREE\n#define\tATOMIC_LLONG_LOCK_FREE\t\t__GCC_ATOMIC_LLONG_LOCK_FREE\n#elif defined(__SYNC_ATOMICS)\n#define\tATOMIC_LLONG_LOCK_FREE          1 /* maybe */\n#endif\n#ifdef __GCC_ATOMIC_POINTER_LOCK_FREE\n#define\tATOMIC_POINTER_LOCK_FREE\t__GCC_ATOMIC_POINTER_LOCK_FREE\n#elif defined(__SYNC_ATOMICS)\n#define\tATOMIC_POINTER_LOCK_FREE        2\n#endif\n\n/*\n * 7.17.2 Initialization.\n */\n\n#if defined(__CLANG_ATOMICS)\n#define\tATOMIC_VAR_INIT(value)\t\t(value)\n#define\tatomic_init(obj, value)\t\t__c11_atomic_init(obj, value)\n#else\n#ifdef __ATOMICS_AVOID_DOT_INIT\n#define\tATOMIC_VAR_INIT(value)\t\t{ value }\n#else\n#define\tATOMIC_VAR_INIT(value)\t\t{ .__val = (value) }\n#endif\n#define\tatomic_init(obj, value)\t\t((void)((obj)->__val = (value)))\n#endif\n\n/*\n * Clang and recent GCC both provide predefined macros for the memory\n * orderings.  If we are using a compiler that doesn't define them, use the\n * clang values - these will be ignored in the fallback path.\n */\n\n#ifndef __ATOMIC_RELAXED\n#define __ATOMIC_RELAXED\t\t0\n#endif\n#ifndef __ATOMIC_CONSUME\n#define __ATOMIC_CONSUME\t\t1\n#endif\n#ifndef __ATOMIC_ACQUIRE\n#define __ATOMIC_ACQUIRE\t\t2\n#endif\n#ifndef __ATOMIC_RELEASE\n#define __ATOMIC_RELEASE\t\t3\n#endif\n#ifndef __ATOMIC_ACQ_REL\n#define __ATOMIC_ACQ_REL\t\t4\n#endif\n#ifndef __ATOMIC_SEQ_CST\n#define __ATOMIC_SEQ_CST\t\t5\n#endif\n\n/*\n * 7.17.3 Order and consistency.\n *\n * The memory_order_* constants that denote the barrier behaviour of the\n * atomic operations.\n * The enum values must be identical to those used by the\n * C++ <atomic> header.\n */\n\ntypedef enum {\n\tmemory_order_relaxed = __ATOMIC_RELAXED,\n\tmemory_order_consume = __ATOMIC_CONSUME,\n\tmemory_order_acquire = __ATOMIC_ACQUIRE,\n\tmemory_order_release = __ATOMIC_RELEASE,\n\tmemory_order_acq_rel = __ATOMIC_ACQ_REL,\n\tmemory_order_seq_cst = __ATOMIC_SEQ_CST\n} memory_order;\n\n/*\n * 7.17.4 Fences.\n */\n\nstatic __inline void\natomic_thread_fence(memory_order __order __attribute__((unused)))\n{\n\n#ifdef __CLANG_ATOMICS\n\t__c11_atomic_thread_fence(__order);\n#elif defined(__GNUC_ATOMICS)\n\t__atomic_thread_fence(__order);\n#else\n\t__sync_synchronize();\n#endif\n}\n\nstatic __inline void\natomic_signal_fence(memory_order __order __attribute__((unused)))\n{\n\n#ifdef __CLANG_ATOMICS\n\t__c11_atomic_signal_fence(__order);\n#elif defined(__GNUC_ATOMICS)\n\t__atomic_signal_fence(__order);\n#else\n\t__asm volatile (\"\" ::: \"memory\");\n#endif\n}\n\n/*\n * 7.17.5 Lock-free property.\n */\n\n#if defined(_KERNEL)\n/* Atomics in kernelspace are always lock-free. */\n#define\tatomic_is_lock_free(obj) \\\n\t((void)(obj), (_Bool)1)\n#elif defined(__CLANG_ATOMICS)\n#define\tatomic_is_lock_free(obj) \\\n\t__c11_atomic_is_lock_free(sizeof(*(obj)))\n#elif defined(__GNUC_ATOMICS)\n#define\tatomic_is_lock_free(obj) \\\n\t__atomic_is_lock_free(sizeof((obj)->__val), &(obj)->__val)\n#else\n#define\tatomic_is_lock_free(obj) \\\n\t((void)(obj), sizeof((obj)->__val) <= sizeof(void *))\n#endif\n\n/*\n * 7.17.6 Atomic integer types.\n */\n\n#ifndef __CLANG_ATOMICS\n/*\n * No native support for _Atomic(). Place object in structure to prevent\n * most forms of direct non-atomic access.\n */\n#define _Atomic(T)              struct { T volatile __val; }\n#endif\n\ntypedef _Atomic(bool)\t\t\tatomic_bool;\ntypedef _Atomic(char)\t\t\tatomic_char;\ntypedef _Atomic(signed char)\t\tatomic_schar;\ntypedef _Atomic(unsigned char)\t\tatomic_uchar;\ntypedef _Atomic(short)\t\t\tatomic_short;\ntypedef _Atomic(unsigned short)\t\tatomic_ushort;\ntypedef _Atomic(int)\t\t\tatomic_int;\ntypedef _Atomic(unsigned int)\t\tatomic_uint;\ntypedef _Atomic(long)\t\t\tatomic_long;\ntypedef _Atomic(unsigned long)\t\tatomic_ulong;\ntypedef _Atomic(long long)\t\tatomic_llong;\ntypedef _Atomic(unsigned long long)\tatomic_ullong;\n#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L\n  typedef _Atomic(char16_t)\t\tatomic_char16_t;\n  typedef _Atomic(char32_t)\t\tatomic_char32_t;\n#endif\ntypedef _Atomic(wchar_t)\t\tatomic_wchar_t;\ntypedef _Atomic(int_least8_t)\t\tatomic_int_least8_t;\ntypedef _Atomic(uint_least8_t)\tatomic_uint_least8_t;\ntypedef _Atomic(int_least16_t)\tatomic_int_least16_t;\ntypedef _Atomic(uint_least16_t)\tatomic_uint_least16_t;\ntypedef _Atomic(int_least32_t)\tatomic_int_least32_t;\ntypedef _Atomic(uint_least32_t)\tatomic_uint_least32_t;\ntypedef _Atomic(int_least64_t)\tatomic_int_least64_t;\ntypedef _Atomic(uint_least64_t)\tatomic_uint_least64_t;\ntypedef _Atomic(int_fast8_t)\t\tatomic_int_fast8_t;\ntypedef _Atomic(uint_fast8_t)\t\tatomic_uint_fast8_t;\ntypedef _Atomic(int_fast16_t)\t\tatomic_int_fast16_t;\ntypedef _Atomic(uint_fast16_t)\tatomic_uint_fast16_t;\ntypedef _Atomic(int_fast32_t)\t\tatomic_int_fast32_t;\ntypedef _Atomic(uint_fast32_t)\tatomic_uint_fast32_t;\ntypedef _Atomic(int_fast64_t)\t\tatomic_int_fast64_t;\ntypedef _Atomic(uint_fast64_t)\tatomic_uint_fast64_t;\ntypedef _Atomic(intptr_t)\t\tatomic_intptr_t;\ntypedef _Atomic(uintptr_t)\t\tatomic_uintptr_t;\ntypedef _Atomic(size_t)\t\tatomic_size_t;\ntypedef _Atomic(ptrdiff_t)\t\tatomic_ptrdiff_t;\ntypedef _Atomic(intmax_t)\t\tatomic_intmax_t;\ntypedef _Atomic(uintmax_t)\t\tatomic_uintmax_t;\n\n/*\n * 7.17.7 Operations on atomic types.\n */\n\n/*\n * Compiler-specific operations.\n */\n\n#if defined(__CLANG_ATOMICS)\n#define\tatomic_compare_exchange_strong_explicit(object, expected,\t\\\n    desired, success, failure)\t\t\t\t\t\t\\\n\t__c11_atomic_compare_exchange_strong(object, expected, desired,\t\\\n\t    success, failure)\n#define\tatomic_compare_exchange_weak_explicit(object, expected,\t\t\\\n    desired, success, failure)\t\t\t\t\t\t\\\n\t__c11_atomic_compare_exchange_weak(object, expected, desired,\t\\\n\t    success, failure)\n#define\tatomic_exchange_explicit(object, desired, order)\t\t\\\n\t__c11_atomic_exchange(object, desired, order)\n#define\tatomic_fetch_add_explicit(object, operand, order)\t\t\\\n\t__c11_atomic_fetch_add(object, operand, order)\n#define\tatomic_fetch_and_explicit(object, operand, order)\t\t\\\n\t__c11_atomic_fetch_and(object, operand, order)\n#define\tatomic_fetch_or_explicit(object, operand, order)\t\t\\\n\t__c11_atomic_fetch_or(object, operand, order)\n#define\tatomic_fetch_sub_explicit(object, operand, order)\t\t\\\n\t__c11_atomic_fetch_sub(object, operand, order)\n#define\tatomic_fetch_xor_explicit(object, operand, order)\t\t\\\n\t__c11_atomic_fetch_xor(object, operand, order)\n#define\tatomic_load_explicit(object, order)\t\t\t\t\\\n\t__c11_atomic_load(object, order)\n#define\tatomic_store_explicit(object, desired, order)\t\t\t\\\n\t__c11_atomic_store(object, desired, order)\n#elif defined(__GNUC_ATOMICS)\n#define\tatomic_compare_exchange_strong_explicit(object, expected,\t\\\n    desired, success, failure)\t\t\t\t\t\t\\\n\t__atomic_compare_exchange_n(&(object)->__val, expected,\t\t\\\n\t    desired, 0, success, failure)\n#define\tatomic_compare_exchange_weak_explicit(object, expected,\t\t\\\n    desired, success, failure)\t\t\t\t\t\t\\\n\t__atomic_compare_exchange_n(&(object)->__val, expected,\t\t\\\n\t    desired, 1, success, failure)\n#define\tatomic_exchange_explicit(object, desired, order)\t\t\\\n\t__atomic_exchange_n(&(object)->__val, desired, order)\n#define\tatomic_fetch_add_explicit(object, operand, order)\t\t\\\n\t__atomic_fetch_add(&(object)->__val, operand, order)\n#define\tatomic_fetch_and_explicit(object, operand, order)\t\t\\\n\t__atomic_fetch_and(&(object)->__val, operand, order)\n#define\tatomic_fetch_or_explicit(object, operand, order)\t\t\\\n\t__atomic_fetch_or(&(object)->__val, operand, order)\n#define\tatomic_fetch_sub_explicit(object, operand, order)\t\t\\\n\t__atomic_fetch_sub(&(object)->__val, operand, order)\n#define\tatomic_fetch_xor_explicit(object, operand, order)\t\t\\\n\t__atomic_fetch_xor(&(object)->__val, operand, order)\n#define\tatomic_load_explicit(object, order)\t\t\t\t\\\n\t__atomic_load_n(&(object)->__val, order)\n#define\tatomic_store_explicit(object, desired, order)\t\t\t\\\n\t__atomic_store_n(&(object)->__val, desired, order)\n#else\n#define\t__atomic_apply_stride(object, operand) \\\n\t(((__typeof__((object)->__val))0) + (operand))\n#define\tatomic_compare_exchange_strong_explicit(object, expected,\t\\\n    desired, success, failure)\t__extension__ ({\t\t\t\\\n\t__typeof__(expected) __ep = (expected);\t\t\t\t\\\n\t__typeof__(*__ep) __e = *__ep;\t\t\t\t\t\\\n\t(void)(success); (void)(failure);\t\t\t\t\\\n\t(bool)((*__ep = __sync_val_compare_and_swap(&(object)->__val,\t\\\n\t    __e, desired)) == __e);\t\t\t\t\t\\\n})\n#define\tatomic_compare_exchange_weak_explicit(object, expected,\t\t\\\n    desired, success, failure)\t\t\t\t\t\t\\\n\tatomic_compare_exchange_strong_explicit(object, expected,\t\\\n\t\tdesired, success, failure)\n#ifdef __HAS_BUILTIN_SYNC_SWAP\n/* Clang provides a full-barrier atomic exchange - use it if available. */\n#define\tatomic_exchange_explicit(object, desired, order)\t\t\\\n\t((void)(order), __sync_swap(&(object)->__val, desired))\n#else\n/*\n * __sync_lock_test_and_set() is only an acquire barrier in theory (although in\n * practice it is usually a full barrier) so we need an explicit barrier before\n * it.\n */\n#define\tatomic_exchange_explicit(object, desired, order)\t\t\\\n__extension__ ({\t\t\t\t\t\t\t\\\n\t__typeof__(object) __o = (object);\t\t\t\t\\\n\t__typeof__(desired) __d = (desired);\t\t\t\t\\\n\t(void)(order);\t\t\t\t\t\t\t\\\n\t__sync_synchronize();\t\t\t\t\t\t\\\n\t__sync_lock_test_and_set(&(__o)->__val, __d);\t\t\t\\\n})\n#endif\n#define\tatomic_fetch_add_explicit(object, operand, order)\t\t\\\n\t((void)(order), __sync_fetch_and_add(&(object)->__val,\t\t\\\n\t    __atomic_apply_stride(object, operand)))\n#define\tatomic_fetch_and_explicit(object, operand, order)\t\t\\\n\t((void)(order), __sync_fetch_and_and(&(object)->__val, operand))\n#define\tatomic_fetch_or_explicit(object, operand, order)\t\t\\\n\t((void)(order), __sync_fetch_and_or(&(object)->__val, operand))\n#define\tatomic_fetch_sub_explicit(object, operand, order)\t\t\\\n\t((void)(order), __sync_fetch_and_sub(&(object)->__val,\t\t\\\n\t    __atomic_apply_stride(object, operand)))\n#define\tatomic_fetch_xor_explicit(object, operand, order)\t\t\\\n\t((void)(order), __sync_fetch_and_xor(&(object)->__val, operand))\n#define\tatomic_load_explicit(object, order)\t\t\t\t\\\n\t((void)(order), __sync_fetch_and_add(&(object)->__val, 0))\n#define\tatomic_store_explicit(object, desired, order)\t\t\t\\\n\t((void)atomic_exchange_explicit(object, desired, order))\n#endif\n\n/*\n * Convenience functions.\n *\n * Don't provide these in kernel space. In kernel space, we should be\n * disciplined enough to always provide explicit barriers.\n */\n\n#ifndef _KERNEL\n#define\tatomic_compare_exchange_strong(object, expected, desired)\t\\\n\tatomic_compare_exchange_strong_explicit(object, expected,\t\\\n\t    desired, memory_order_seq_cst, memory_order_seq_cst)\n#define\tatomic_compare_exchange_weak(object, expected, desired)\t\t\\\n\tatomic_compare_exchange_weak_explicit(object, expected,\t\t\\\n\t    desired, memory_order_seq_cst, memory_order_seq_cst)\n#define\tatomic_exchange(object, desired)\t\t\t\t\\\n\tatomic_exchange_explicit(object, desired, memory_order_seq_cst)\n#define\tatomic_fetch_add(object, operand)\t\t\t\t\\\n\tatomic_fetch_add_explicit(object, operand, memory_order_seq_cst)\n#define\tatomic_fetch_and(object, operand)\t\t\t\t\\\n\tatomic_fetch_and_explicit(object, operand, memory_order_seq_cst)\n#define\tatomic_fetch_or(object, operand)\t\t\t\t\\\n\tatomic_fetch_or_explicit(object, operand, memory_order_seq_cst)\n#define\tatomic_fetch_sub(object, operand)\t\t\t\t\\\n\tatomic_fetch_sub_explicit(object, operand, memory_order_seq_cst)\n#define\tatomic_fetch_xor(object, operand)\t\t\t\t\\\n\tatomic_fetch_xor_explicit(object, operand, memory_order_seq_cst)\n#define\tatomic_load(object)\t\t\t\t\t\t\\\n\tatomic_load_explicit(object, memory_order_seq_cst)\n#define\tatomic_store(object, desired)\t\t\t\t\t\\\n\tatomic_store_explicit(object, desired, memory_order_seq_cst)\n#endif /* !_KERNEL */\n\n/*\n * 7.17.8 Atomic flag type and operations.\n *\n * XXX: Assume atomic_bool can be used as an atomic_flag. Is there some\n * kind of compiler built-in type we could use?\n */\n\ntypedef struct {\n\tatomic_bool\t__flag;\n} atomic_flag;\n\n#define\tATOMIC_FLAG_INIT\t\t{ ATOMIC_VAR_INIT(false) }\n\nstatic __inline bool\natomic_flag_test_and_set_explicit(volatile atomic_flag *__object,\n    memory_order __order)\n{\n\treturn (atomic_exchange_explicit(&__object->__flag, 1, __order));\n}\n\nstatic __inline void\natomic_flag_clear_explicit(volatile atomic_flag *__object, memory_order __order)\n{\n\n\tatomic_store_explicit(&__object->__flag, 0, __order);\n}\n\n#ifndef _KERNEL\nstatic __inline bool\natomic_flag_test_and_set(volatile atomic_flag *__object)\n{\n\n\treturn (atomic_flag_test_and_set_explicit(__object,\n\t    memory_order_seq_cst));\n}\n\nstatic __inline void\natomic_flag_clear(volatile atomic_flag *__object)\n{\n\n\tatomic_flag_clear_explicit(__object, memory_order_seq_cst);\n}\n#endif /* !_KERNEL */\n\n#endif /* <atomic> unavailable */\n\n#endif /* !_STDATOMIC_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/stdint.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _STDINT_H\n#define _STDINT_H\n\n#include <bits/wchar_limits.h>\n#include <stddef.h>\n\ntypedef __signed char __int8_t;\ntypedef unsigned char __uint8_t;\ntypedef short __int16_t;\ntypedef unsigned short __uint16_t;\ntypedef int __int32_t;\ntypedef unsigned int __uint32_t;\n#if __LP64__\ntypedef long __int64_t;\ntypedef unsigned long __uint64_t;\n#else\ntypedef long long __int64_t;\ntypedef unsigned long long __uint64_t;\n#endif\n\n#if __LP64__\ntypedef long __intptr_t;\ntypedef unsigned long __uintptr_t;\n#else\ntypedef int __intptr_t;\ntypedef unsigned int __uintptr_t;\n#endif\n\ntypedef __int8_t      int8_t;\ntypedef __uint8_t     uint8_t;\n\ntypedef __int16_t     int16_t;\ntypedef __uint16_t    uint16_t;\n\ntypedef __int32_t     int32_t;\ntypedef __uint32_t    uint32_t;\n\ntypedef __int64_t     int64_t;\ntypedef __uint64_t    uint64_t;\n\ntypedef __intptr_t    intptr_t;\ntypedef __uintptr_t   uintptr_t;\n\ntypedef int8_t        int_least8_t;\ntypedef uint8_t       uint_least8_t;\n\ntypedef int16_t       int_least16_t;\ntypedef uint16_t      uint_least16_t;\n\ntypedef int32_t       int_least32_t;\ntypedef uint32_t      uint_least32_t;\n\ntypedef int64_t       int_least64_t;\ntypedef uint64_t      uint_least64_t;\n\ntypedef int8_t        int_fast8_t;\ntypedef uint8_t       uint_fast8_t;\n\ntypedef int64_t       int_fast64_t;\ntypedef uint64_t      uint_fast64_t;\n\n#if defined(__LP64__)\ntypedef int64_t       int_fast16_t;\ntypedef uint64_t      uint_fast16_t;\ntypedef int64_t       int_fast32_t;\ntypedef uint64_t      uint_fast32_t;\n#else\ntypedef int32_t       int_fast16_t;\ntypedef uint32_t      uint_fast16_t;\ntypedef int32_t       int_fast32_t;\ntypedef uint32_t      uint_fast32_t;\n#endif\n\ntypedef uint64_t      uintmax_t;\ntypedef int64_t       intmax_t;\n\n/* Keep the kernel from trying to define these types... */\n#define __BIT_TYPES_DEFINED__\n\n#define INT8_C(c)         c\n#define INT_LEAST8_C(c)   INT8_C(c)\n#define INT_FAST8_C(c)    INT8_C(c)\n\n#define UINT8_C(c)        c\n#define UINT_LEAST8_C(c)  UINT8_C(c)\n#define UINT_FAST8_C(c)   UINT8_C(c)\n\n#define INT16_C(c)        c\n#define INT_LEAST16_C(c)  INT16_C(c)\n#define INT_FAST16_C(c)   INT32_C(c)\n\n#define UINT16_C(c)       c\n#define UINT_LEAST16_C(c) UINT16_C(c)\n#define UINT_FAST16_C(c)  UINT32_C(c)\n#define INT32_C(c)        c\n#define INT_LEAST32_C(c)  INT32_C(c)\n#define INT_FAST32_C(c)   INT32_C(c)\n\n#define UINT32_C(c)       c ## U\n#define UINT_LEAST32_C(c) UINT32_C(c)\n#define UINT_FAST32_C(c)  UINT32_C(c)\n#define INT_LEAST64_C(c)  INT64_C(c)\n#define INT_FAST64_C(c)   INT64_C(c)\n\n#define UINT_LEAST64_C(c) UINT64_C(c)\n#define UINT_FAST64_C(c)  UINT64_C(c)\n\n#define INTMAX_C(c)       INT64_C(c)\n#define UINTMAX_C(c)      UINT64_C(c)\n\n#if defined(__LP64__)\n#  define INT64_C(c)      c ## L\n#  define UINT64_C(c)     c ## UL\n#  define INTPTR_C(c)     INT64_C(c)\n#  define UINTPTR_C(c)    UINT64_C(c)\n#  define PTRDIFF_C(c)    INT64_C(c)\n#else\n#  define INT64_C(c)      c ## LL\n#  define UINT64_C(c)     c ## ULL\n#  define INTPTR_C(c)     INT32_C(c)\n#  define UINTPTR_C(c)    UINT32_C(c)\n#  define PTRDIFF_C(c)    INT32_C(c)\n#endif\n\n#define INT8_MIN         (-128)\n#define INT8_MAX         (127)\n#define INT_LEAST8_MIN   INT8_MIN\n#define INT_LEAST8_MAX   INT8_MAX\n#define INT_FAST8_MIN    INT8_MIN\n#define INT_FAST8_MAX    INT8_MAX\n\n#define UINT8_MAX        (255)\n#define UINT_LEAST8_MAX  UINT8_MAX\n#define UINT_FAST8_MAX   UINT8_MAX\n\n#define INT16_MIN        (-32768)\n#define INT16_MAX        (32767)\n#define INT_LEAST16_MIN  INT16_MIN\n#define INT_LEAST16_MAX  INT16_MAX\n#define INT_FAST16_MIN   INT32_MIN\n#define INT_FAST16_MAX   INT32_MAX\n\n#define UINT16_MAX       (65535)\n#define UINT_LEAST16_MAX UINT16_MAX\n#define UINT_FAST16_MAX  UINT32_MAX\n\n#define INT32_MIN        (-2147483647-1)\n#define INT32_MAX        (2147483647)\n#define INT_LEAST32_MIN  INT32_MIN\n#define INT_LEAST32_MAX  INT32_MAX\n#define INT_FAST32_MIN   INT32_MIN\n#define INT_FAST32_MAX   INT32_MAX\n\n#define UINT32_MAX       (4294967295U)\n#define UINT_LEAST32_MAX UINT32_MAX\n#define UINT_FAST32_MAX  UINT32_MAX\n\n#define INT64_MIN        (INT64_C(-9223372036854775807)-1)\n#define INT64_MAX        (INT64_C(9223372036854775807))\n#define INT_LEAST64_MIN  INT64_MIN\n#define INT_LEAST64_MAX  INT64_MAX\n#define INT_FAST64_MIN   INT64_MIN\n#define INT_FAST64_MAX   INT64_MAX\n#define UINT64_MAX       (UINT64_C(18446744073709551615))\n\n#define UINT_LEAST64_MAX UINT64_MAX\n#define UINT_FAST64_MAX  UINT64_MAX\n\n#define INTMAX_MIN       INT64_MIN\n#define INTMAX_MAX       INT64_MAX\n#define UINTMAX_MAX      UINT64_MAX\n\n#define SIG_ATOMIC_MAX   INT32_MAX\n#define SIG_ATOMIC_MIN   INT32_MIN\n\n#if defined(__WINT_UNSIGNED__)\n#  define WINT_MAX       UINT32_MAX\n#  define WINT_MIN       0\n#else\n#  define WINT_MAX       INT32_MAX\n#  define WINT_MIN       INT32_MIN\n#endif\n\n#if defined(__LP64__)\n#  define INTPTR_MIN     INT64_MIN\n#  define INTPTR_MAX     INT64_MAX\n#  define UINTPTR_MAX    UINT64_MAX\n#  define PTRDIFF_MIN    INT64_MIN\n#  define PTRDIFF_MAX    INT64_MAX\n#  define SIZE_MAX       UINT64_MAX\n#else\n#  define INTPTR_MIN     INT32_MIN\n#  define INTPTR_MAX     INT32_MAX\n#  define UINTPTR_MAX    UINT32_MAX\n#  define PTRDIFF_MIN    INT32_MIN\n#  define PTRDIFF_MAX    INT32_MAX\n#  define SIZE_MAX       UINT32_MAX\n#endif\n\n#endif /* _STDINT_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/stdio.h",
    "content": "/*\t$OpenBSD: stdio.h,v 1.35 2006/01/13 18:10:09 miod Exp $\t*/\n/*\t$NetBSD: stdio.h,v 1.18 1996/04/25 18:29:21 jtc Exp $\t*/\n\n/*-\n * Copyright (c) 1990 The Regents of the University of California.\n * All rights reserved.\n *\n * This code is derived from software contributed to Berkeley by\n * Chris Torek.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)stdio.h\t5.17 (Berkeley) 6/3/91\n */\n\n#ifndef\t_STDIO_H_\n#define\t_STDIO_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n#include <stdarg.h>\n#include <stddef.h>\n\n#define __need_NULL\n#include <stddef.h>\n\n__BEGIN_DECLS\n\ntypedef off_t fpos_t;\ntypedef off64_t fpos64_t;\n\nstruct __sFILE;\ntypedef struct __sFILE FILE;\n\nextern FILE* stdin;\nextern FILE* stdout;\nextern FILE* stderr;\n/* C99 and earlier plus current C++ standards say these must be macros. */\n#define stdin stdin\n#define stdout stdout\n#define stderr stderr\n\n/*\n * The following three definitions are for ANSI C, which took them\n * from System V, which brilliantly took internal interface macros and\n * made them official arguments to setvbuf(), without renaming them.\n * Hence, these ugly _IOxxx names are *supposed* to appear in user code.\n *\n * Although numbered as their counterparts above, the implementation\n * does not rely on this.\n */\n#define\t_IOFBF\t0\t\t/* setvbuf should set fully buffered */\n#define\t_IOLBF\t1\t\t/* setvbuf should set line buffered */\n#define\t_IONBF\t2\t\t/* setvbuf should set unbuffered */\n\n#define\tBUFSIZ\t1024\t\t/* size of buffer used by setbuf */\n#define\tEOF\t(-1)\n\n/*\n * FOPEN_MAX is a minimum maximum, and is the number of streams that\n * stdio can provide without attempting to allocate further resources\n * (which could fail).  Do not use this for anything.\n */\n\n#define\tFOPEN_MAX\t20\t/* must be <= OPEN_MAX <sys/syslimits.h> */\n#define\tFILENAME_MAX\t1024\t/* must be <= PATH_MAX <sys/syslimits.h> */\n\n/* System V/ANSI C; this is the wrong way to do this, do *not* use these. */\n#if __BSD_VISIBLE || __XPG_VISIBLE\n#define\tP_tmpdir\t\"/tmp/\"\n#endif\n#define\tL_tmpnam\t1024\t/* XXX must be == PATH_MAX */\n#define\tTMP_MAX\t\t308915776\n\n#define SEEK_SET 0\n#define SEEK_CUR 1\n#define SEEK_END 2\n\n/*\n * Functions defined in ANSI C standard.\n */\nvoid\t clearerr(FILE *);\nint\t fclose(FILE *);\nint\t feof(FILE *);\nint\t ferror(FILE *);\nint\t fflush(FILE *);\nint\t fgetc(FILE *);\nchar\t*fgets(char * __restrict, int, FILE * __restrict);\nint\t fprintf(FILE * __restrict , const char * __restrict, ...)\n\t\t__printflike(2, 3);\nint\t fputc(int, FILE *);\nint\t fputs(const char * __restrict, FILE * __restrict);\nsize_t\t fread(void * __restrict, size_t, size_t, FILE * __restrict);\nint\t fscanf(FILE * __restrict, const char * __restrict, ...)\n\t\t__scanflike(2, 3);\nsize_t\t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict);\nint\t getc(FILE *);\nint\t getchar(void);\nssize_t\t getdelim(char ** __restrict, size_t * __restrict, int,\n\t    FILE * __restrict);\nssize_t\t getline(char ** __restrict, size_t * __restrict, FILE * __restrict);\n\nvoid\t perror(const char *);\nint\t printf(const char * __restrict, ...)\n\t\t__printflike(1, 2);\nint\t putc(int, FILE *);\nint\t putchar(int);\nint\t puts(const char *);\nint\t remove(const char *);\nvoid\t rewind(FILE *);\nint\t scanf(const char * __restrict, ...)\n\t\t__scanflike(1, 2);\nvoid\t setbuf(FILE * __restrict, char * __restrict);\nint\t setvbuf(FILE * __restrict, char * __restrict, int, size_t);\nint\t sscanf(const char * __restrict, const char * __restrict, ...)\n\t\t__scanflike(2, 3);\nint\t ungetc(int, FILE *);\nint\t vfprintf(FILE * __restrict, const char * __restrict, __va_list)\n\t\t__printflike(2, 0);\nint\t vprintf(const char * __restrict, __va_list)\n\t\t__printflike(1, 0);\n\nint dprintf(int, const char * __restrict, ...) __printflike(2, 3);\nint vdprintf(int, const char * __restrict, __va_list) __printflike(2, 0);\n\n#ifndef __AUDIT__\n#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L\nchar* gets(char*) __attribute__((deprecated(\"gets is unsafe, use fgets instead\")));\n#endif\nint sprintf(char* __restrict, const char* __restrict, ...)\n    __printflike(2, 3) __warnattr(\"sprintf is often misused; please use snprintf\");\nint vsprintf(char* __restrict, const char* __restrict, __va_list)\n    __printflike(2, 0) __warnattr(\"vsprintf is often misused; please use vsnprintf\");\nchar* tmpnam(char*) __attribute__((deprecated(\"tmpnam is unsafe, use mkstemp or tmpfile instead\")));\n#if __XPG_VISIBLE\nchar* tempnam(const char*, const char*)\n    __attribute__((deprecated(\"tempnam is unsafe, use mkstemp or tmpfile instead\")));\n#endif\n#endif\n\nint rename(const char*, const char*);\nint renameat(int, const char*, int, const char*);\n\nint fseek(FILE*, long, int);\nlong ftell(FILE*);\n\n#if defined(__USE_FILE_OFFSET64)\nint fgetpos(FILE*, fpos_t*) __RENAME(fgetpos64);\nint fsetpos(FILE*, const fpos_t*) __RENAME(fsetpos64);\nint fseeko(FILE*, off_t, int) __RENAME(fseeko64);\noff_t ftello(FILE*) __RENAME(ftello64);\n#  if defined(__USE_BSD)\nFILE* funopen(const void*,\n              int (*)(void*, char*, int),\n              int (*)(void*, const char*, int),\n              fpos_t (*)(void*, fpos_t, int),\n              int (*)(void*)) __RENAME(funopen64);\n#  endif\n#else\nint fgetpos(FILE*, fpos_t*);\nint fsetpos(FILE*, const fpos_t*);\nint fseeko(FILE*, off_t, int);\noff_t ftello(FILE*);\n#  if defined(__USE_BSD)\nFILE* funopen(const void*,\n              int (*)(void*, char*, int),\n              int (*)(void*, const char*, int),\n              fpos_t (*)(void*, fpos_t, int),\n              int (*)(void*));\n#  endif\n#endif\nint fgetpos64(FILE*, fpos64_t*);\nint fsetpos64(FILE*, const fpos64_t*);\nint fseeko64(FILE*, off64_t, int);\noff64_t ftello64(FILE*);\n#if defined(__USE_BSD)\nFILE* funopen64(const void*,\n                int (*)(void*, char*, int),\n                int (*)(void*, const char*, int),\n                fpos64_t (*)(void*, fpos64_t, int),\n                int (*)(void*));\n#endif\n\nFILE* fopen(const char* __restrict, const char* __restrict);\nFILE* fopen64(const char* __restrict, const char* __restrict);\nFILE* freopen(const char* __restrict, const char* __restrict, FILE* __restrict);\nFILE* freopen64(const char* __restrict, const char* __restrict, FILE* __restrict);\nFILE* tmpfile(void);\nFILE* tmpfile64(void);\n\n#if __ISO_C_VISIBLE >= 1999 || __BSD_VISIBLE\nint\t snprintf(char * __restrict, size_t, const char * __restrict, ...)\n\t\t__printflike(3, 4);\nint\t vfscanf(FILE * __restrict, const char * __restrict, __va_list)\n\t\t__scanflike(2, 0);\nint\t vscanf(const char *, __va_list)\n\t\t__scanflike(1, 0);\nint\t vsnprintf(char * __restrict, size_t, const char * __restrict, __va_list)\n\t\t__printflike(3, 0);\nint\t vsscanf(const char * __restrict, const char * __restrict, __va_list)\n\t\t__scanflike(2, 0);\n#endif /* __ISO_C_VISIBLE >= 1999 || __BSD_VISIBLE */\n\n/*\n * Functions defined in POSIX 1003.1.\n */\n#if __BSD_VISIBLE || __POSIX_VISIBLE || __XPG_VISIBLE\n#define\tL_ctermid\t1024\t/* size for ctermid(); PATH_MAX */\n\nFILE\t*fdopen(int, const char *);\nint\t fileno(FILE *);\n\n#if (__POSIX_VISIBLE >= 199209)\nint\t pclose(FILE *);\nFILE\t*popen(const char *, const char *);\n#endif\n\n#if __POSIX_VISIBLE >= 199506\nvoid\t flockfile(FILE *);\nint\t ftrylockfile(FILE *);\nvoid\t funlockfile(FILE *);\n\n/*\n * These are normally used through macros as defined below, but POSIX\n * requires functions as well.\n */\nint\t getc_unlocked(FILE *);\nint\t getchar_unlocked(void);\nint\t putc_unlocked(int, FILE *);\nint\t putchar_unlocked(int);\n#endif /* __POSIX_VISIBLE >= 199506 */\n\n#if __POSIX_VISIBLE >= 200809\nFILE* fmemopen(void*, size_t, const char*);\nFILE* open_memstream(char**, size_t*);\n#endif /* __POSIX_VISIBLE >= 200809 */\n\n#endif /* __BSD_VISIBLE || __POSIX_VISIBLE || __XPG_VISIBLE */\n\n/*\n * Routines that are purely local.\n */\n#if __BSD_VISIBLE\nint\t asprintf(char ** __restrict, const char * __restrict, ...)\n\t\t__printflike(2, 3);\nchar\t*fgetln(FILE * __restrict, size_t * __restrict);\nint\t fpurge(FILE *);\nvoid\t setbuffer(FILE *, char *, int);\nint\t setlinebuf(FILE *);\nint\t vasprintf(char ** __restrict, const char * __restrict,\n    __va_list)\n\t\t__printflike(2, 0);\n\nvoid clearerr_unlocked(FILE*);\nint feof_unlocked(FILE*);\nint ferror_unlocked(FILE*);\nint fileno_unlocked(FILE*);\n\n#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)\n#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)\n#endif /* __BSD_VISIBLE */\n\nextern char* __fgets_chk(char*, int, FILE*, size_t);\nextern char* __fgets_real(char*, int, FILE*) __RENAME(fgets);\n__errordecl(__fgets_too_big_error, \"fgets called with size bigger than buffer\");\n__errordecl(__fgets_too_small_error, \"fgets called with size less than zero\");\n\nextern size_t __fread_chk(void * __restrict, size_t, size_t, FILE * __restrict, size_t);\nextern size_t __fread_real(void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fread);\n__errordecl(__fread_too_big_error, \"fread called with size * count bigger than buffer\");\n__errordecl(__fread_overflow, \"fread called with overflowing size * count\");\n\nextern size_t __fwrite_chk(const void * __restrict, size_t, size_t, FILE * __restrict, size_t);\nextern size_t __fwrite_real(const void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fwrite);\n__errordecl(__fwrite_too_big_error, \"fwrite called with size * count bigger than buffer\");\n__errordecl(__fwrite_overflow, \"fwrite called with overflowing size * count\");\n\n#if defined(__BIONIC_FORTIFY)\n\n__BIONIC_FORTIFY_INLINE\n__printflike(3, 0)\nint vsnprintf(char *dest, size_t size, const char *format, __va_list ap)\n{\n    return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);\n}\n\n__BIONIC_FORTIFY_INLINE\n__printflike(2, 0)\nint vsprintf(char *dest, const char *format, __va_list ap)\n{\n    return __builtin___vsprintf_chk(dest, 0, __bos(dest), format, ap);\n}\n\n#if defined(__clang__)\n  #if !defined(snprintf)\n    #define __wrap_snprintf(dest, size, ...) __builtin___snprintf_chk(dest, size, 0, __bos(dest), __VA_ARGS__)\n    #define snprintf(...) __wrap_snprintf(__VA_ARGS__)\n  #endif\n#else\n__BIONIC_FORTIFY_INLINE\n__printflike(3, 4)\nint snprintf(char *dest, size_t size, const char *format, ...)\n{\n    return __builtin___snprintf_chk(dest, size, 0,\n        __bos(dest), format, __builtin_va_arg_pack());\n}\n#endif\n\n#if defined(__clang__)\n  #if !defined(sprintf)\n    #define __wrap_sprintf(dest, ...) __builtin___sprintf_chk(dest, 0, __bos(dest), __VA_ARGS__)\n    #define sprintf(...) __wrap_sprintf(__VA_ARGS__)\n  #endif\n#else\n__BIONIC_FORTIFY_INLINE\n__printflike(2, 3)\nint sprintf(char *dest, const char *format, ...)\n{\n    return __builtin___sprintf_chk(dest, 0,\n        __bos(dest), format, __builtin_va_arg_pack());\n}\n#endif\n\n__BIONIC_FORTIFY_INLINE\nsize_t fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict stream) {\n    size_t bos = __bos0(buf);\n\n#if !defined(__clang__)\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __fread_real(buf, size, count, stream);\n    }\n\n    if (__builtin_constant_p(size) && __builtin_constant_p(count)) {\n        size_t total;\n        if (__size_mul_overflow(size, count, &total)) {\n            __fread_overflow();\n        }\n\n        if (total > bos) {\n            __fread_too_big_error();\n        }\n\n        return __fread_real(buf, size, count, stream);\n    }\n#endif\n\n    return __fread_chk(buf, size, count, stream, bos);\n}\n\n__BIONIC_FORTIFY_INLINE\nsize_t fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict stream) {\n    size_t bos = __bos0(buf);\n\n#if !defined(__clang__)\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __fwrite_real(buf, size, count, stream);\n    }\n\n    if (__builtin_constant_p(size) && __builtin_constant_p(count)) {\n        size_t total;\n        if (__size_mul_overflow(size, count, &total)) {\n            __fwrite_overflow();\n        }\n\n        if (total > bos) {\n            __fwrite_too_big_error();\n        }\n\n        return __fwrite_real(buf, size, count, stream);\n    }\n#endif\n\n    return __fwrite_chk(buf, size, count, stream, bos);\n}\n\n#if !defined(__clang__)\n\n__BIONIC_FORTIFY_INLINE\nchar *fgets(char* dest, int size, FILE* stream) {\n    size_t bos = __bos(dest);\n\n    // Compiler can prove, at compile time, that the passed in size\n    // is always negative. Force a compiler error.\n    if (__builtin_constant_p(size) && (size < 0)) {\n        __fgets_too_small_error();\n    }\n\n    // Compiler doesn't know destination size. Don't call __fgets_chk\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __fgets_real(dest, size, stream);\n    }\n\n    // Compiler can prove, at compile time, that the passed in size\n    // is always <= the actual object size. Don't call __fgets_chk\n    if (__builtin_constant_p(size) && (size <= (int) bos)) {\n        return __fgets_real(dest, size, stream);\n    }\n\n    // Compiler can prove, at compile time, that the passed in size\n    // is always > the actual object size. Force a compiler error.\n    if (__builtin_constant_p(size) && (size > (int) bos)) {\n        __fgets_too_big_error();\n    }\n\n    return __fgets_chk(dest, size, stream, bos);\n}\n\n#endif /* !defined(__clang__) */\n\n#endif /* defined(__BIONIC_FORTIFY) */\n\n__END_DECLS\n\n#endif /* _STDIO_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/stdio_ext.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _STDIO_EXT_H\n#define _STDIO_EXT_H\n\n#include <sys/cdefs.h>\n#include <stdio.h>\n\n#define FSETLOCKING_QUERY 0\n#define FSETLOCKING_INTERNAL 1\n#define FSETLOCKING_BYCALLER 2\n\n__BEGIN_DECLS\n\nsize_t __fbufsize(FILE*);\nint __freading(FILE*);\nint __fwriting(FILE*);\nint __freadable(FILE*);\nint __fwritable(FILE*);\nint __flbf(FILE*);\nvoid __fpurge(FILE*);\nsize_t __fpending(FILE*);\nvoid _flushlbf(void);\nint __fsetlocking(FILE*, int);\n\n__END_DECLS\n\n#endif /* _STDIO_EXT_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/stdlib.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _STDLIB_H\n#define _STDLIB_H\n\n#include <sys/cdefs.h>\n#include <xlocale.h>\n\n#include <alloca.h>\n#include <malloc.h>\n#include <stddef.h>\n\n__BEGIN_DECLS\n\n#define EXIT_FAILURE 1\n#define EXIT_SUCCESS 0\n\nextern __noreturn void abort(void);\nextern __noreturn void exit(int);\nextern __noreturn void _Exit(int);\nextern int atexit(void (*)(void));\n\n#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L\nint at_quick_exit(void (*)(void));\nvoid quick_exit(int) __noreturn;\n#endif\n\nextern char* getenv(const char*);\nextern int putenv(char*);\nextern int setenv(const char*, const char*, int);\nextern int unsetenv(const char*);\nextern int clearenv(void);\n\nextern char* mkdtemp(char*);\nextern char* mktemp(char*) __attribute__((deprecated(\"mktemp is unsafe, use mkstemp or tmpfile instead\")));\n\nextern int mkostemp64(char*, int);\nextern int mkostemp(char*, int);\nextern int mkostemps64(char*, int, int);\nextern int mkostemps(char*, int, int);\nextern int mkstemp64(char*);\nextern int mkstemp(char*);\nextern int mkstemps64(char*, int);\nextern int mkstemps(char*, int);\n\nextern long strtol(const char *, char **, int);\nextern long long strtoll(const char *, char **, int);\nextern unsigned long strtoul(const char *, char **, int);\nextern unsigned long long strtoull(const char *, char **, int);\n\nextern int posix_memalign(void **memptr, size_t alignment, size_t size);\n\nextern double atof(const char*) __INTRODUCED_IN(21);\n\nextern double strtod(const char*, char**) __LIBC_ABI_PUBLIC__;\nextern float strtof(const char*, char**) __LIBC_ABI_PUBLIC__ __INTRODUCED_IN(21);\nextern long double strtold(const char*, char**) __LIBC_ABI_PUBLIC__;\n\nextern long double strtold_l(const char *, char **, locale_t) __LIBC_ABI_PUBLIC__;\nextern long long strtoll_l(const char *, char **, int, locale_t) __LIBC_ABI_PUBLIC__;\nextern unsigned long long strtoull_l(const char *, char **, int, locale_t) __LIBC_ABI_PUBLIC__;\n\nextern int atoi(const char*) __purefunc;\nextern long atol(const char*) __purefunc;\nextern long long atoll(const char*) __purefunc;\n\nextern int abs(int) __pure2 __INTRODUCED_IN(21);\nextern long labs(long) __pure2 __INTRODUCED_IN(21);\nextern long long llabs(long long) __pure2 __INTRODUCED_IN(21);\n\nextern char * realpath(const char *path, char *resolved);\nextern int system(const char *string);\n\nextern void * bsearch(const void *key, const void *base0,\n\tsize_t nmemb, size_t size,\n\tint (*compar)(const void *, const void *));\n\nextern void qsort(void *, size_t, size_t, int (*)(const void *, const void *));\n\nuint32_t arc4random(void);\nuint32_t arc4random_uniform(uint32_t);\nvoid arc4random_buf(void*, size_t);\n\n#define RAND_MAX 0x7fffffff\n\nint rand(void) __INTRODUCED_IN(21);\nint rand_r(unsigned int*);\nvoid srand(unsigned int) __INTRODUCED_IN(21);\n\ndouble drand48(void);\ndouble erand48(unsigned short[3]);\nlong jrand48(unsigned short[3]);\nvoid lcong48(unsigned short[7]);\nlong lrand48(void);\nlong mrand48(void);\nlong nrand48(unsigned short[3]);\nunsigned short* seed48(unsigned short[3]);\nvoid srand48(long);\n\nchar* initstate(unsigned int, char*, size_t);\nlong random(void) __INTRODUCED_IN(21);\nchar* setstate(char*);\nvoid srandom(unsigned int) __INTRODUCED_IN(21);\n\nint getpt(void);\nint grantpt(int) __INTRODUCED_IN(21);\nint posix_openpt(int);\nchar* ptsname(int);\nint ptsname_r(int, char*, size_t);\nint unlockpt(int);\n\ntypedef struct {\n    int  quot;\n    int  rem;\n} div_t;\n\nextern div_t   div(int, int) __pure2;\n\ntypedef struct {\n    long int  quot;\n    long int  rem;\n} ldiv_t;\n\nextern ldiv_t   ldiv(long, long) __pure2;\n\ntypedef struct {\n    long long int  quot;\n    long long int  rem;\n} lldiv_t;\n\nextern lldiv_t   lldiv(long long, long long) __pure2;\n\n/* BSD compatibility. */\nextern const char* getprogname(void);\nextern void setprogname(const char*);\n\n/* make STLPort happy */\nextern int      mblen(const char *, size_t);\nextern size_t   mbstowcs(wchar_t *, const char *, size_t);\nextern int      mbtowc(wchar_t *, const char *, size_t);\n\n/* Likewise, make libstdc++-v3 happy.  */\nextern int\twctomb(char *, wchar_t);\nextern size_t\twcstombs(char *, const wchar_t *, size_t);\n\nextern size_t __ctype_get_mb_cur_max(void);\n#define MB_CUR_MAX __ctype_get_mb_cur_max()\n\n#if __ANDROID_API__ < 21\n#include <android/legacy_stdlib_inlines.h>\n#endif\n\n#if defined(__BIONIC_FORTIFY)\n\nextern char* __realpath_real(const char*, char*) __RENAME(realpath);\n__errordecl(__realpath_size_error, \"realpath output parameter must be NULL or a >= PATH_MAX bytes buffer\");\n\n#if !defined(__clang__)\n__BIONIC_FORTIFY_INLINE\nchar* realpath(const char* path, char* resolved) {\n    size_t bos = __bos(resolved);\n\n    /* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */\n    if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < 4096) {\n        __realpath_size_error();\n    }\n\n    return __realpath_real(path, resolved);\n}\n#endif\n\n#endif /* defined(__BIONIC_FORTIFY) */\n\n__END_DECLS\n\n#endif /* _STDLIB_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/string.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _STRING_H\n#define _STRING_H\n\n#include <sys/cdefs.h>\n#include <stddef.h>\n#include <xlocale.h>\n\n__BEGIN_DECLS\n\n#if defined(__USE_BSD)\n#include <strings.h>\n#endif\n\nextern void*  memccpy(void* __restrict, const void* __restrict, int, size_t);\nextern void*  memchr(const void *, int, size_t) __purefunc;\nextern void*  memrchr(const void *, int, size_t) __purefunc;\nextern int    memcmp(const void *, const void *, size_t) __purefunc;\nextern void*  memcpy(void* __restrict, const void* __restrict, size_t);\n#if defined(__USE_GNU)\nextern void*  mempcpy(void* __restrict, const void* __restrict, size_t);\n#endif\nextern void*  memmove(void *, const void *, size_t);\nextern void*  memset(void *, int, size_t);\nextern void*  memmem(const void *, size_t, const void *, size_t) __purefunc;\n\nextern char*  strchr(const char *, int) __purefunc;\nextern char* __strchr_chk(const char *, int, size_t);\n#if defined(__USE_GNU)\n#if defined(__cplusplus)\nextern \"C++\" char* strchrnul(char*, int) __RENAME(strchrnul) __purefunc;\nextern \"C++\" const char* strchrnul(const char*, int) __RENAME(strchrnul) __purefunc;\n#else\nchar* strchrnul(const char*, int) __purefunc;\n#endif\n#endif\n\nextern char*  strrchr(const char *, int) __purefunc;\nextern char* __strrchr_chk(const char *, int, size_t);\n\nextern size_t strlen(const char *) __purefunc;\nextern size_t __strlen_chk(const char *, size_t);\nextern int    strcmp(const char *, const char *) __purefunc;\nextern char*  stpcpy(char* __restrict, const char* __restrict);\nextern char*  strcpy(char* __restrict, const char* __restrict);\nextern char*  strcat(char* __restrict, const char* __restrict);\n\nint strcasecmp(const char*, const char*) __purefunc;\nint strcasecmp_l(const char*, const char*, locale_t) __purefunc;\nint strncasecmp(const char*, const char*, size_t) __purefunc;\nint strncasecmp_l(const char*, const char*, size_t, locale_t) __purefunc;\n\nextern char*  strdup(const char *);\n\nextern char*  strstr(const char *, const char *) __purefunc;\nextern char*  strcasestr(const char *haystack, const char *needle) __purefunc;\nextern char*  strtok(char* __restrict, const char* __restrict);\nextern char*  strtok_r(char* __restrict, const char* __restrict, char** __restrict);\n\nextern char* strerror(int);\nextern char* strerror_l(int, locale_t);\n#if defined(__USE_GNU)\nextern char* strerror_r(int, char*, size_t) __RENAME(__gnu_strerror_r);\n#else /* POSIX */\nextern int strerror_r(int, char*, size_t);\n#endif\n\nextern size_t strnlen(const char *, size_t) __purefunc;\nextern char*  strncat(char* __restrict, const char* __restrict, size_t);\nextern char*  strndup(const char *, size_t);\nextern int    strncmp(const char *, const char *, size_t) __purefunc;\nextern char*  stpncpy(char* __restrict, const char* __restrict, size_t);\nextern char*  strncpy(char* __restrict, const char* __restrict, size_t);\n\nextern size_t strlcat(char* __restrict, const char* __restrict, size_t);\nextern size_t strlcpy(char* __restrict, const char* __restrict, size_t);\n\nextern size_t strcspn(const char *, const char *) __purefunc;\nextern char*  strpbrk(const char *, const char *) __purefunc;\nextern char*  strsep(char** __restrict, const char* __restrict);\nextern size_t strspn(const char *, const char *);\n\nextern char*  strsignal(int  sig);\n\nextern int    strcoll(const char *, const char *) __purefunc;\nextern size_t strxfrm(char* __restrict, const char* __restrict, size_t);\n\nextern int    strcoll_l(const char *, const char *, locale_t) __purefunc;\nextern size_t strxfrm_l(char* __restrict, const char* __restrict, size_t, locale_t);\n\n#if defined(__USE_GNU) && !defined(basename)\n/*\n * glibc has a basename in <string.h> that's different to the POSIX one in <libgen.h>.\n * It doesn't modify its argument, and in C++ it's const-correct.\n */\n\n#if defined(__cplusplus)\nextern \"C++\" char* basename(char*) __RENAME(__gnu_basename) __nonnull((1));\nextern \"C++\" const char* basename(const char*) __RENAME(__gnu_basename) __nonnull((1));\n#else\nextern char* basename(const char*) __RENAME(__gnu_basename) __nonnull((1));\n#endif\n#endif\n\nextern void* __memchr_chk(const void*, int, size_t, size_t);\n__errordecl(__memchr_buf_size_error, \"memchr called with size bigger than buffer\");\n\nextern void* __memrchr_chk(const void*, int, size_t, size_t);\n__errordecl(__memrchr_buf_size_error, \"memrchr called with size bigger than buffer\");\nextern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);\n\nextern char* __stpncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t);\nextern char* __strncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t);\nextern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t) __RENAME(strlcpy);\nextern size_t __strlcpy_chk(char *, const char *, size_t, size_t);\nextern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t) __RENAME(strlcat);\nextern size_t __strlcat_chk(char* __restrict, const char* __restrict, size_t, size_t);\n\n#if defined(__BIONIC_FORTIFY)\n\n__BIONIC_FORTIFY_INLINE\nvoid* memchr(const void *s, int c, size_t n) {\n    size_t bos = __bos(s);\n\n#if !defined(__clang__)\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __builtin_memchr(s, c, n);\n    }\n\n    if (__builtin_constant_p(n) && (n > bos)) {\n        __memchr_buf_size_error();\n    }\n\n    if (__builtin_constant_p(n) && (n <= bos)) {\n        return __builtin_memchr(s, c, n);\n    }\n#endif\n\n    return __memchr_chk(s, c, n, bos);\n}\n\n__BIONIC_FORTIFY_INLINE\nvoid* memrchr(const void *s, int c, size_t n) {\n    size_t bos = __bos(s);\n\n#if !defined(__clang__)\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __memrchr_real(s, c, n);\n    }\n\n    if (__builtin_constant_p(n) && (n > bos)) {\n        __memrchr_buf_size_error();\n    }\n\n    if (__builtin_constant_p(n) && (n <= bos)) {\n        return __memrchr_real(s, c, n);\n    }\n#endif\n\n    return __memrchr_chk(s, c, n, bos);\n}\n\n__BIONIC_FORTIFY_INLINE\nvoid* memcpy(void* __restrict dest, const void* __restrict src, size_t copy_amount) {\n    return __builtin___memcpy_chk(dest, src, copy_amount, __bos0(dest));\n}\n\n__BIONIC_FORTIFY_INLINE\nvoid* memmove(void *dest, const void *src, size_t len) {\n    return __builtin___memmove_chk(dest, src, len, __bos0(dest));\n}\n\n__BIONIC_FORTIFY_INLINE\nchar* stpcpy(char* __restrict dest, const char* __restrict src) {\n    return __builtin___stpcpy_chk(dest, src, __bos(dest));\n}\n\n__BIONIC_FORTIFY_INLINE\nchar* strcpy(char* __restrict dest, const char* __restrict src) {\n    return __builtin___strcpy_chk(dest, src, __bos(dest));\n}\n\n__BIONIC_FORTIFY_INLINE\nchar* stpncpy(char* __restrict dest, const char* __restrict src, size_t n) {\n    size_t bos_dest = __bos(dest);\n    size_t bos_src = __bos(src);\n\n    if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __builtin___stpncpy_chk(dest, src, n, bos_dest);\n    }\n\n    if (__builtin_constant_p(n) && (n <= bos_src)) {\n        return __builtin___stpncpy_chk(dest, src, n, bos_dest);\n    }\n\n    size_t slen = __builtin_strlen(src);\n    if (__builtin_constant_p(slen)) {\n        return __builtin___stpncpy_chk(dest, src, n, bos_dest);\n    }\n\n    return __stpncpy_chk2(dest, src, n, bos_dest, bos_src);\n}\n\n__BIONIC_FORTIFY_INLINE\nchar* strncpy(char* __restrict dest, const char* __restrict src, size_t n) {\n    size_t bos_dest = __bos(dest);\n    size_t bos_src = __bos(src);\n\n    if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __builtin___strncpy_chk(dest, src, n, bos_dest);\n    }\n\n    if (__builtin_constant_p(n) && (n <= bos_src)) {\n        return __builtin___strncpy_chk(dest, src, n, bos_dest);\n    }\n\n    size_t slen = __builtin_strlen(src);\n    if (__builtin_constant_p(slen)) {\n        return __builtin___strncpy_chk(dest, src, n, bos_dest);\n    }\n\n    return __strncpy_chk2(dest, src, n, bos_dest, bos_src);\n}\n\n__BIONIC_FORTIFY_INLINE\nchar* strcat(char* __restrict dest, const char* __restrict src) {\n    return __builtin___strcat_chk(dest, src, __bos(dest));\n}\n\n__BIONIC_FORTIFY_INLINE\nchar *strncat(char* __restrict dest, const char* __restrict src, size_t n) {\n    return __builtin___strncat_chk(dest, src, n, __bos(dest));\n}\n\n__BIONIC_FORTIFY_INLINE\nvoid* memset(void *s, int c, size_t n) {\n    return __builtin___memset_chk(s, c, n, __bos0(s));\n}\n\n__BIONIC_FORTIFY_INLINE\nsize_t strlcpy(char* __restrict dest, const char* __restrict src, size_t size) {\n    size_t bos = __bos(dest);\n\n#if !defined(__clang__)\n    // Compiler doesn't know destination size. Don't call __strlcpy_chk\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __strlcpy_real(dest, src, size);\n    }\n\n    // Compiler can prove, at compile time, that the passed in size\n    // is always <= the actual object size. Don't call __strlcpy_chk\n    if (__builtin_constant_p(size) && (size <= bos)) {\n        return __strlcpy_real(dest, src, size);\n    }\n#endif /* !defined(__clang__) */\n\n    return __strlcpy_chk(dest, src, size, bos);\n}\n\n\n__BIONIC_FORTIFY_INLINE\nsize_t strlcat(char* __restrict dest, const char* __restrict src, size_t size) {\n    size_t bos = __bos(dest);\n\n#if !defined(__clang__)\n    // Compiler doesn't know destination size. Don't call __strlcat_chk\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __strlcat_real(dest, src, size);\n    }\n\n    // Compiler can prove, at compile time, that the passed in size\n    // is always <= the actual object size. Don't call __strlcat_chk\n    if (__builtin_constant_p(size) && (size <= bos)) {\n        return __strlcat_real(dest, src, size);\n    }\n#endif /* !defined(__clang__) */\n\n    return __strlcat_chk(dest, src, size, bos);\n}\n\n__BIONIC_FORTIFY_INLINE\nsize_t strlen(const char *s) {\n    size_t bos = __bos(s);\n\n#if !defined(__clang__)\n    // Compiler doesn't know destination size. Don't call __strlen_chk\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __builtin_strlen(s);\n    }\n\n    size_t slen = __builtin_strlen(s);\n    if (__builtin_constant_p(slen)) {\n        return slen;\n    }\n#endif /* !defined(__clang__) */\n\n    return __strlen_chk(s, bos);\n}\n\n__BIONIC_FORTIFY_INLINE\nchar* strchr(const char *s, int c) {\n    size_t bos = __bos(s);\n\n#if !defined(__clang__)\n    // Compiler doesn't know destination size. Don't call __strchr_chk\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __builtin_strchr(s, c);\n    }\n\n    size_t slen = __builtin_strlen(s);\n    if (__builtin_constant_p(slen) && (slen < bos)) {\n        return __builtin_strchr(s, c);\n    }\n#endif /* !defined(__clang__) */\n\n    return __strchr_chk(s, c, bos);\n}\n\n__BIONIC_FORTIFY_INLINE\nchar* strrchr(const char *s, int c) {\n    size_t bos = __bos(s);\n\n#if !defined(__clang__)\n    // Compiler doesn't know destination size. Don't call __strrchr_chk\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __builtin_strrchr(s, c);\n    }\n\n    size_t slen = __builtin_strlen(s);\n    if (__builtin_constant_p(slen) && (slen < bos)) {\n        return __builtin_strrchr(s, c);\n    }\n#endif /* !defined(__clang__) */\n\n    return __strrchr_chk(s, c, bos);\n}\n\n\n#endif /* defined(__BIONIC_FORTIFY) */\n\n__END_DECLS\n\n#endif /* _STRING_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/strings.h",
    "content": "/*\t$NetBSD: strings.h,v 1.10 2005/02/03 04:39:32 perry Exp $\t*/\n\n/*-\n * Copyright (c) 1998 The NetBSD Foundation, Inc.\n * All rights reserved.\n *\n * This code is derived from software contributed to The NetBSD Foundation\n * by Klaus Klein.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. All advertising materials mentioning features or use of this software\n *    must display the following acknowledgement:\n *        This product includes software developed by the NetBSD\n *        Foundation, Inc. and its contributors.\n * 4. Neither the name of The NetBSD Foundation nor the names of its\n *    contributors may be used to endorse or promote products derived\n *    from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS\n * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\n * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS\n * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n * POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef _STRINGS_H_\n#define _STRINGS_H_\n\n#include <sys/types.h>\n#include <sys/cdefs.h>\n#include <xlocale.h>\n\n__BEGIN_DECLS\n#if defined(__BIONIC_FORTIFY)\n#define bcopy(b1, b2, len) (void)(__builtin___memmove_chk((b2), (b1), (len), __bos0(b2)))\n#define bzero(b, len) (void)(__builtin___memset_chk((b), '\\0', (len), __bos0(b)))\n#else\n#define bcopy(b1, b2, len) (void)(__builtin_memmove((b2), (b1), (len)))\n#define bzero(b, len) (void)(__builtin_memset((b), '\\0', (len)))\n#endif\n\nint ffs(int);\n\nint strcasecmp(const char*, const char*) __purefunc;\nint strcasecmp_l(const char*, const char*, locale_t) __purefunc;\nint strncasecmp(const char*, const char*, size_t) __purefunc;\nint strncasecmp_l(const char*, const char*, size_t, locale_t) __purefunc;\n\n__END_DECLS\n\n#endif /* !defined(_STRINGS_H_) */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/_errdefs.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/* the following corresponds to the error codes of the Linux kernel used by the Android platform\n * these are distinct from the OpenBSD ones, which is why we need to redeclare them here\n *\n * this file may be included several times to define either error constants or their\n * string representation\n */\n\n#ifndef __BIONIC_ERRDEF\n#error \"__BIONIC_ERRDEF must be defined before including this file\"\n#endif\n__BIONIC_ERRDEF( 0              ,   0, \"Success\" )\n__BIONIC_ERRDEF( EPERM          ,   1, \"Operation not permitted\" )\n__BIONIC_ERRDEF( ENOENT         ,   2, \"No such file or directory\" )\n__BIONIC_ERRDEF( ESRCH          ,   3, \"No such process\" )\n__BIONIC_ERRDEF( EINTR          ,   4, \"Interrupted system call\" )\n__BIONIC_ERRDEF( EIO            ,   5, \"I/O error\" )\n__BIONIC_ERRDEF( ENXIO          ,   6, \"No such device or address\" )\n__BIONIC_ERRDEF( E2BIG          ,   7, \"Argument list too long\" )\n__BIONIC_ERRDEF( ENOEXEC        ,   8, \"Exec format error\" )\n__BIONIC_ERRDEF( EBADF          ,   9, \"Bad file descriptor\" )\n__BIONIC_ERRDEF( ECHILD         ,  10, \"No child processes\" )\n__BIONIC_ERRDEF( EAGAIN         ,  11, \"Try again\" )\n__BIONIC_ERRDEF( ENOMEM         ,  12, \"Out of memory\" )\n__BIONIC_ERRDEF( EACCES         ,  13, \"Permission denied\" )\n__BIONIC_ERRDEF( EFAULT         ,  14, \"Bad address\" )\n__BIONIC_ERRDEF( ENOTBLK        ,  15, \"Block device required\" )\n__BIONIC_ERRDEF( EBUSY          ,  16, \"Device or resource busy\" )\n__BIONIC_ERRDEF( EEXIST         ,  17, \"File exists\" )\n__BIONIC_ERRDEF( EXDEV          ,  18, \"Cross-device link\" )\n__BIONIC_ERRDEF( ENODEV         ,  19, \"No such device\" )\n__BIONIC_ERRDEF( ENOTDIR        ,  20, \"Not a directory\" )\n__BIONIC_ERRDEF( EISDIR         ,  21, \"Is a directory\" )\n__BIONIC_ERRDEF( EINVAL         ,  22, \"Invalid argument\" )\n__BIONIC_ERRDEF( ENFILE         ,  23, \"File table overflow\" )\n__BIONIC_ERRDEF( EMFILE         ,  24, \"Too many open files\" )\n__BIONIC_ERRDEF( ENOTTY         ,  25, \"Not a typewriter\" )\n__BIONIC_ERRDEF( ETXTBSY        ,  26, \"Text file busy\" )\n__BIONIC_ERRDEF( EFBIG          ,  27, \"File too large\" )\n__BIONIC_ERRDEF( ENOSPC         ,  28, \"No space left on device\" )\n__BIONIC_ERRDEF( ESPIPE         ,  29, \"Illegal seek\" )\n__BIONIC_ERRDEF( EROFS          ,  30, \"Read-only file system\" )\n__BIONIC_ERRDEF( EMLINK         ,  31, \"Too many links\" )\n__BIONIC_ERRDEF( EPIPE          ,  32, \"Broken pipe\" )\n__BIONIC_ERRDEF( EDOM           ,  33, \"Math argument out of domain of func\" )\n__BIONIC_ERRDEF( ERANGE         ,  34, \"Math result not representable\" )\n__BIONIC_ERRDEF( EDEADLK        ,  35, \"Resource deadlock would occur\" )\n__BIONIC_ERRDEF( ENAMETOOLONG   ,  36, \"File name too long\" )\n__BIONIC_ERRDEF( ENOLCK         ,  37, \"No record locks available\" )\n__BIONIC_ERRDEF( ENOSYS         ,  38, \"Function not implemented\" )\n__BIONIC_ERRDEF( ENOTEMPTY      ,  39, \"Directory not empty\" )\n__BIONIC_ERRDEF( ELOOP          ,  40, \"Too many symbolic links encountered\" )\n__BIONIC_ERRDEF( ENOMSG         ,  42, \"No message of desired type\" )\n__BIONIC_ERRDEF( EIDRM          ,  43, \"Identifier removed\" )\n__BIONIC_ERRDEF( ECHRNG         ,  44, \"Channel number out of range\" )\n__BIONIC_ERRDEF( EL2NSYNC       ,  45, \"Level 2 not synchronized\" )\n__BIONIC_ERRDEF( EL3HLT         ,  46, \"Level 3 halted\" )\n__BIONIC_ERRDEF( EL3RST         ,  47, \"Level 3 reset\" )\n__BIONIC_ERRDEF( ELNRNG         ,  48, \"Link number out of range\" )\n__BIONIC_ERRDEF( EUNATCH        ,  49, \"Protocol driver not attached\" )\n__BIONIC_ERRDEF( ENOCSI         ,  50, \"No CSI structure available\" )\n__BIONIC_ERRDEF( EL2HLT         ,  51, \"Level 2 halted\" )\n__BIONIC_ERRDEF( EBADE          ,  52, \"Invalid exchange\" )\n__BIONIC_ERRDEF( EBADR          ,  53, \"Invalid request descriptor\" )\n__BIONIC_ERRDEF( EXFULL         ,  54, \"Exchange full\" )\n__BIONIC_ERRDEF( ENOANO         ,  55, \"No anode\" )\n__BIONIC_ERRDEF( EBADRQC        ,  56, \"Invalid request code\" )\n__BIONIC_ERRDEF( EBADSLT        ,  57, \"Invalid slot\" )\n__BIONIC_ERRDEF( EBFONT         ,  59, \"Bad font file format\" )\n__BIONIC_ERRDEF( ENOSTR         ,  60, \"Device not a stream\" )\n__BIONIC_ERRDEF( ENODATA        ,  61, \"No data available\" )\n__BIONIC_ERRDEF( ETIME          ,  62, \"Timer expired\" )\n__BIONIC_ERRDEF( ENOSR          ,  63, \"Out of streams resources\" )\n__BIONIC_ERRDEF( ENONET         ,  64, \"Machine is not on the network\" )\n__BIONIC_ERRDEF( ENOPKG         ,  65, \"Package not installed\" )\n__BIONIC_ERRDEF( EREMOTE        ,  66, \"Object is remote\" )\n__BIONIC_ERRDEF( ENOLINK        ,  67, \"Link has been severed\" )\n__BIONIC_ERRDEF( EADV           ,  68, \"Advertise error\" )\n__BIONIC_ERRDEF( ESRMNT         ,  69, \"Srmount error\" )\n__BIONIC_ERRDEF( ECOMM          ,  70, \"Communication error on send\" )\n__BIONIC_ERRDEF( EPROTO         ,  71, \"Protocol error\" )\n__BIONIC_ERRDEF( EMULTIHOP      ,  72, \"Multihop attempted\" )\n__BIONIC_ERRDEF( EDOTDOT        ,  73, \"RFS specific error\" )\n__BIONIC_ERRDEF( EBADMSG        ,  74, \"Not a data message\" )\n__BIONIC_ERRDEF( EOVERFLOW      ,  75, \"Value too large for defined data type\" )\n__BIONIC_ERRDEF( ENOTUNIQ       ,  76, \"Name not unique on network\" )\n__BIONIC_ERRDEF( EBADFD         ,  77, \"File descriptor in bad state\" )\n__BIONIC_ERRDEF( EREMCHG        ,  78, \"Remote address changed\" )\n__BIONIC_ERRDEF( ELIBACC        ,  79, \"Can not access a needed shared library\" )\n__BIONIC_ERRDEF( ELIBBAD        ,  80, \"Accessing a corrupted shared library\" )\n__BIONIC_ERRDEF( ELIBSCN        ,  81, \".lib section in a.out corrupted\" )\n__BIONIC_ERRDEF( ELIBMAX        ,  82, \"Attempting to link in too many shared libraries\" )\n__BIONIC_ERRDEF( ELIBEXEC       ,  83, \"Cannot exec a shared library directly\" )\n__BIONIC_ERRDEF( EILSEQ         ,  84, \"Illegal byte sequence\" )\n__BIONIC_ERRDEF( ERESTART       ,  85, \"Interrupted system call should be restarted\" )\n__BIONIC_ERRDEF( ESTRPIPE       ,  86, \"Streams pipe error\" )\n__BIONIC_ERRDEF( EUSERS         ,  87, \"Too many users\" )\n__BIONIC_ERRDEF( ENOTSOCK       ,  88, \"Socket operation on non-socket\" )\n__BIONIC_ERRDEF( EDESTADDRREQ   ,  89, \"Destination address required\" )\n__BIONIC_ERRDEF( EMSGSIZE       ,  90, \"Message too long\" )\n__BIONIC_ERRDEF( EPROTOTYPE     ,  91, \"Protocol wrong type for socket\" )\n__BIONIC_ERRDEF( ENOPROTOOPT    ,  92, \"Protocol not available\" )\n__BIONIC_ERRDEF( EPROTONOSUPPORT,  93, \"Protocol not supported\" )\n__BIONIC_ERRDEF( ESOCKTNOSUPPORT,  94, \"Socket type not supported\" )\n__BIONIC_ERRDEF( EOPNOTSUPP     ,  95, \"Operation not supported on transport endpoint\" )\n__BIONIC_ERRDEF( EPFNOSUPPORT   ,  96, \"Protocol family not supported\" )\n__BIONIC_ERRDEF( EAFNOSUPPORT   ,  97, \"Address family not supported by protocol\" )\n__BIONIC_ERRDEF( EADDRINUSE     ,  98, \"Address already in use\" )\n__BIONIC_ERRDEF( EADDRNOTAVAIL  ,  99, \"Cannot assign requested address\" )\n__BIONIC_ERRDEF( ENETDOWN       , 100, \"Network is down\" )\n__BIONIC_ERRDEF( ENETUNREACH    , 101, \"Network is unreachable\" )\n__BIONIC_ERRDEF( ENETRESET      , 102, \"Network dropped connection because of reset\" )\n__BIONIC_ERRDEF( ECONNABORTED   , 103, \"Software caused connection abort\" )\n__BIONIC_ERRDEF( ECONNRESET     , 104, \"Connection reset by peer\" )\n__BIONIC_ERRDEF( ENOBUFS        , 105, \"No buffer space available\" )\n__BIONIC_ERRDEF( EISCONN        , 106, \"Transport endpoint is already connected\" )\n__BIONIC_ERRDEF( ENOTCONN       , 107, \"Transport endpoint is not connected\" )\n__BIONIC_ERRDEF( ESHUTDOWN      , 108, \"Cannot send after transport endpoint shutdown\" )\n__BIONIC_ERRDEF( ETOOMANYREFS   , 109, \"Too many references: cannot splice\" )\n__BIONIC_ERRDEF( ETIMEDOUT      , 110, \"Connection timed out\" )\n__BIONIC_ERRDEF( ECONNREFUSED   , 111, \"Connection refused\" )\n__BIONIC_ERRDEF( EHOSTDOWN      , 112, \"Host is down\" )\n__BIONIC_ERRDEF( EHOSTUNREACH   , 113, \"No route to host\" )\n__BIONIC_ERRDEF( EALREADY       , 114, \"Operation already in progress\" )\n__BIONIC_ERRDEF( EINPROGRESS    , 115, \"Operation now in progress\" )\n__BIONIC_ERRDEF( ESTALE         , 116, \"Stale NFS file handle\" )\n__BIONIC_ERRDEF( EUCLEAN        , 117, \"Structure needs cleaning\" )\n__BIONIC_ERRDEF( ENOTNAM        , 118, \"Not a XENIX named type file\" )\n__BIONIC_ERRDEF( ENAVAIL        , 119, \"No XENIX semaphores available\" )\n__BIONIC_ERRDEF( EISNAM         , 120, \"Is a named type file\" )\n__BIONIC_ERRDEF( EREMOTEIO      , 121, \"Remote I/O error\" )\n__BIONIC_ERRDEF( EDQUOT         , 122, \"Quota exceeded\" )\n__BIONIC_ERRDEF( ENOMEDIUM      , 123, \"No medium found\" )\n__BIONIC_ERRDEF( EMEDIUMTYPE    , 124, \"Wrong medium type\" )\n__BIONIC_ERRDEF( ECANCELED      , 125, \"Operation Canceled\" )\n__BIONIC_ERRDEF( ENOKEY         , 126, \"Required key not available\" )\n__BIONIC_ERRDEF( EKEYEXPIRED    , 127, \"Key has expired\" )\n__BIONIC_ERRDEF( EKEYREVOKED    , 128, \"Key has been revoked\" )\n__BIONIC_ERRDEF( EKEYREJECTED   , 129, \"Key was rejected by service\" )\n__BIONIC_ERRDEF( EOWNERDEAD     , 130, \"Owner died\" )\n__BIONIC_ERRDEF( ENOTRECOVERABLE, 131, \"State not recoverable\" )\n\n#undef __BIONIC_ERRDEF\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/_sigdefs.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*\n * this header is used to define signal constants and names;\n * it might be included several times\n */\n\n#ifndef __BIONIC_SIGDEF\n#error __BIONIC_SIGDEF not defined\n#endif\n\n__BIONIC_SIGDEF(SIGHUP,    \"Hangup\")\n__BIONIC_SIGDEF(SIGINT,    \"Interrupt\")\n__BIONIC_SIGDEF(SIGQUIT,   \"Quit\")\n__BIONIC_SIGDEF(SIGILL,    \"Illegal instruction\")\n__BIONIC_SIGDEF(SIGTRAP,   \"Trap\")\n__BIONIC_SIGDEF(SIGABRT,   \"Aborted\")\n#ifdef SIGEMT\n__BIONIC_SIGDEF(SIGEMT,    \"EMT\")\n#endif\n__BIONIC_SIGDEF(SIGFPE,    \"Floating point exception\")\n__BIONIC_SIGDEF(SIGKILL,   \"Killed\")\n__BIONIC_SIGDEF(SIGBUS,    \"Bus error\")\n__BIONIC_SIGDEF(SIGSEGV,   \"Segmentation fault\")\n__BIONIC_SIGDEF(SIGPIPE,   \"Broken pipe\")\n__BIONIC_SIGDEF(SIGALRM,   \"Alarm clock\")\n__BIONIC_SIGDEF(SIGTERM,   \"Terminated\")\n__BIONIC_SIGDEF(SIGUSR1,   \"User signal 1\")\n__BIONIC_SIGDEF(SIGUSR2,   \"User signal 2\")\n__BIONIC_SIGDEF(SIGCHLD,   \"Child exited\")\n__BIONIC_SIGDEF(SIGPWR,    \"Power failure\")\n__BIONIC_SIGDEF(SIGWINCH,  \"Window size changed\")\n__BIONIC_SIGDEF(SIGURG,    \"Urgent I/O condition\")\n__BIONIC_SIGDEF(SIGIO,     \"I/O possible\")\n__BIONIC_SIGDEF(SIGSTOP,   \"Stopped (signal)\")\n__BIONIC_SIGDEF(SIGTSTP,   \"Stopped\")\n__BIONIC_SIGDEF(SIGCONT,   \"Continue\")\n__BIONIC_SIGDEF(SIGTTIN,   \"Stopped (tty input)\")\n__BIONIC_SIGDEF(SIGTTOU,   \"Stopped (tty output)\")\n__BIONIC_SIGDEF(SIGVTALRM, \"Virtual timer expired\")\n__BIONIC_SIGDEF(SIGPROF,   \"Profiling timer expired\")\n__BIONIC_SIGDEF(SIGXCPU,   \"CPU time limit exceeded\")\n__BIONIC_SIGDEF(SIGXFSZ,   \"File size limit exceeded\")\n#if defined(SIGSTKFLT)\n__BIONIC_SIGDEF(SIGSTKFLT, \"Stack fault\")\n#endif\n__BIONIC_SIGDEF(SIGSYS,    \"Bad system call\")\n\n#undef __BIONIC_SIGDEF\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/_system_properties.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _INCLUDE_SYS__SYSTEM_PROPERTIES_H\n#define _INCLUDE_SYS__SYSTEM_PROPERTIES_H\n\n#ifndef _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_\n#error you should #include <sys/system_properties.h> instead\n#else\n#include <sys/system_properties.h>\n\ntypedef struct prop_msg prop_msg;\n\n#define PROP_AREA_MAGIC   0x504f5250\n#define PROP_AREA_VERSION 0xfc6ed0ab\n#define PROP_AREA_VERSION_COMPAT 0x45434f76\n\n#define PROP_SERVICE_NAME \"property_service\"\n#define PROP_FILENAME_MAX 1024\n#define PROP_FILENAME \"/dev/__properties__\"\n\n#define PA_SIZE         (128 * 1024)\n\n#define SERIAL_VALUE_LEN(serial) ((serial) >> 24)\n#define SERIAL_DIRTY(serial) ((serial) & 1)\n\n__BEGIN_DECLS\n\nstruct prop_msg\n{\n    unsigned cmd;\n    char name[PROP_NAME_MAX];\n    char value[PROP_VALUE_MAX];\n};\n\n#define PROP_MSG_SETPROP 1\n\n/*\n** Rules:\n**\n** - there is only one writer, but many readers\n** - prop_area.count will never decrease in value\n** - once allocated, a prop_info's name will not change\n** - once allocated, a prop_info's offset will not change\n** - reading a value requires the following steps\n**   1. serial = pi->serial\n**   2. if SERIAL_DIRTY(serial), wait*, then goto 1\n**   3. memcpy(local, pi->value, SERIAL_VALUE_LEN(serial) + 1)\n**   4. if pi->serial != serial, goto 2\n**\n** - writing a value requires the following steps\n**   1. pi->serial = pi->serial | 1\n**   2. memcpy(pi->value, local_value, value_len)\n**   3. pi->serial = (value_len << 24) | ((pi->serial + 1) & 0xffffff)\n*/\n\n#define PROP_PATH_RAMDISK_DEFAULT  \"/default.prop\"\n#define PROP_PATH_SYSTEM_BUILD     \"/system/build.prop\"\n#define PROP_PATH_VENDOR_BUILD     \"/vendor/build.prop\"\n#define PROP_PATH_LOCAL_OVERRIDE   \"/data/local.prop\"\n#define PROP_PATH_FACTORY          \"/factory/factory.prop\"\n\n/*\n** Map the property area from the specified filename.  This\n** method is for testing only.\n*/\nint __system_property_set_filename(const char *filename);\n\n/*\n** Initialize the area to be used to store properties.  Can\n** only be done by a single process that has write access to\n** the property area.\n*/\nint __system_property_area_init();\n\n/* Read the global serial number of the system properties\n**\n** Called to predict if a series of cached __system_property_find\n** objects will have seen __system_property_serial values change.\n** But also aids the converse, as changes in the global serial can\n** also be used to predict if a failed __system_property_find\n** could in-turn now find a new object; thus preventing the\n** cycles of effort to poll __system_property_find.\n**\n** Typically called at beginning of a cache cycle to signal if _any_ possible\n** changes have occurred since last. If there is, one may check each individual\n** __system_property_serial to confirm dirty, or __system_property_find\n** to check if the property now exists. If a call to __system_property_add\n** or __system_property_update has completed between two calls to\n** __system_property_area_serial then the second call will return a larger\n** value than the first call. Beware of race conditions as changes to the\n** properties are not atomic, the main value of this call is to determine\n** whether the expensive __system_property_find is worth retrying to see if\n** a property now exists.\n**\n** Returns the serial number on success, -1 on error.\n*/\nunsigned int __system_property_area_serial();\n\n/* Add a new system property.  Can only be done by a single\n** process that has write access to the property area, and\n** that process must handle sequencing to ensure the property\n** does not already exist and that only one property is added\n** or updated at a time.\n**\n** Returns 0 on success, -1 if the property area is full.\n*/\nint __system_property_add(const char *name, unsigned int namelen,\n\t\t\tconst char *value, unsigned int valuelen);\n\n/* Update the value of a system property returned by\n** __system_property_find.  Can only be done by a single process\n** that has write access to the property area, and that process\n** must handle sequencing to ensure that only one property is\n** updated at a time.\n**\n** Returns 0 on success, -1 if the parameters are incorrect.\n*/\nint __system_property_update(prop_info *pi, const char *value, unsigned int len);\n\n/* Read the serial number of a system property returned by\n** __system_property_find.\n**\n** Returns the serial number on success, -1 on error.\n*/\nunsigned int __system_property_serial(const prop_info *pi);\n\n/* Wait for any system property to be updated.  Caller must pass\n** in 0 the first time, and the previous return value on each\n** successive call. */\nunsigned int __system_property_wait_any(unsigned int serial);\n\n/*  Compatibility functions to support using an old init with a new libc,\n ** mostly for the OTA updater binary.  These can be deleted once OTAs from\n ** a pre-K release no longer needed to be supported. */\nconst prop_info *__system_property_find_compat(const char *name);\nint __system_property_read_compat(const prop_info *pi, char *name, char *value);\nint __system_property_foreach_compat(\n        void (*propfn)(const prop_info *pi, void *cookie),\n        void *cookie);\n\n/* Initialize the system properties area in read only mode.\n * Should be done by all processes that need to read system\n * properties.\n *\n * Returns 0 on success, -1 otherwise.\n */\nint __system_properties_init();\n\n__END_DECLS\n\n#endif\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/atomics.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_ATOMICS_H_\n#define _SYS_ATOMICS_H_\n\n/*\n * These got proper out of line definitions in L. Putting the inline definitions\n * back for old targets brings us closer to being able to use one set of headers\n * for all API levels.\n *\n * The other inlines we put back went in to their appropriate headers, but the\n * sys/atomics.h header was removed, so we'll just add these somewhere we can be\n * sure they will be included.\n */\n#if __ANDROID_API__ < 21\n#include <android/legacy_sys_atomics_inlines.h>\n#endif\n\n#endif /* _SYS_ATOMICS_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/auxv.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_AUXV_H_\n#define _SYS_AUXV_H_\n\n#include <linux/auxvec.h>\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\nunsigned long int getauxval(unsigned long int type);\n\n__END_DECLS\n\n#endif /* _SYS_AUXV_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/cachectl.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_CACHECTL_H\n#define _SYS_CACHECTL_H 1\n\n#ifdef __mips__\n#include <asm/cachectl.h>\nextern int __cachectl (void *addr, __const int nbytes, __const int op);\n#endif\n#endif /* sys/cachectl.h */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/capability.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _BIONIC_SYS_CAPABILITY_H\n#define _BIONIC_SYS_CAPABILITY_H\n\n#include <sys/cdefs.h>\n#include <linux/capability.h>\n\n__BEGIN_DECLS\n\nextern int capget(cap_user_header_t hdrp, cap_user_data_t datap);\nextern int capset(cap_user_header_t hdrp, const cap_user_data_t datap);\n\n__END_DECLS\n\n#endif /* _BIONIC_SYS_CAPABILITY_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/cdefs.h",
    "content": "/*\t$NetBSD: cdefs.h,v 1.58 2004/12/11 05:59:00 christos Exp $\t*/\n\n/*\n * Copyright (c) 1991, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * This code is derived from software contributed to Berkeley by\n * Berkeley Software Design, Inc.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)cdefs.h\t8.8 (Berkeley) 1/9/95\n */\n\n#ifndef\t_SYS_CDEFS_H_\n#define\t_SYS_CDEFS_H_\n\n/*\n * Testing against Clang-specific extensions.\n */\n\n#ifndef __has_extension\n#define __has_extension         __has_feature\n#endif\n#ifndef __has_feature\n#define __has_feature(x)        0\n#endif\n#ifndef __has_include\n#define __has_include(x)        0\n#endif\n#ifndef __has_builtin\n#define __has_builtin(x)        0\n#endif\n#ifndef __has_attribute\n#define __has_attribute(x)      0\n#endif\n\n\n/*\n * Macro to test if we're using a GNU C compiler of a specific vintage\n * or later, for e.g. features that appeared in a particular version\n * of GNU C.  Usage:\n *\n *\t#if __GNUC_PREREQ(major, minor)\n *\t...cool feature...\n *\t#else\n *\t...delete feature...\n *\t#endif\n */\n#ifdef __GNUC__\n#define\t__GNUC_PREREQ(x, y)\t\t\t\t\t\t\\\n\t((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) ||\t\t\t\\\n\t (__GNUC__ > (x)))\n#else\n#define\t__GNUC_PREREQ(x, y)\t0\n#endif\n\n#define __strong_alias(alias, sym) \\\n    __asm__(\".global \" #alias \"\\n\" \\\n            #alias \" = \" #sym);\n\n#if defined(__cplusplus)\n#define\t__BEGIN_DECLS\t\textern \"C\" {\n#define\t__END_DECLS\t\t}\n#define\t__static_cast(x,y)\tstatic_cast<x>(y)\n#else\n#define\t__BEGIN_DECLS\n#define\t__END_DECLS\n#define\t__static_cast(x,y)\t(x)y\n#endif\n\n/*\n * The __CONCAT macro is used to concatenate parts of symbol names, e.g.\n * with \"#define OLD(foo) __CONCAT(old,foo)\", OLD(foo) produces oldfoo.\n * The __CONCAT macro is a bit tricky -- make sure you don't put spaces\n * in between its arguments.  __CONCAT can also concatenate double-quoted\n * strings produced by the __STRING macro, but this only works with ANSI C.\n */\n\n#define\t___STRING(x)\t__STRING(x)\n#define\t___CONCAT(x,y)\t__CONCAT(x,y)\n\n#if defined(__STDC__) || defined(__cplusplus)\n#define\t__P(protos)\tprotos\t\t/* full-blown ANSI C */\n#define\t__CONCAT(x,y)\tx ## y\n#define\t__STRING(x)\t#x\n\n#define\t__const\t\tconst\t\t/* define reserved names to standard */\n#define\t__signed\tsigned\n#define\t__volatile\tvolatile\n#if defined(__cplusplus)\n#define\t__inline\tinline\t\t/* convert to C++ keyword */\n#else\n#if !defined(__GNUC__) && !defined(__lint__)\n#define\t__inline\t\t\t/* delete GCC keyword */\n#endif /* !__GNUC__  && !__lint__ */\n#endif /* !__cplusplus */\n\n#else\t/* !(__STDC__ || __cplusplus) */\n#define\t__P(protos)\t()\t\t/* traditional C preprocessor */\n#define\t__CONCAT(x,y)\tx/**/y\n#define\t__STRING(x)\t\"x\"\n\n#ifndef __GNUC__\n#define\t__const\t\t\t\t/* delete pseudo-ANSI C keywords */\n#define\t__inline\n#define\t__signed\n#define\t__volatile\n#endif\t/* !__GNUC__ */\n\n#endif\t/* !(__STDC__ || __cplusplus) */\n\n/*\n * The following macro is used to remove const cast-away warnings\n * from gcc -Wcast-qual; it should be used with caution because it\n * can hide valid errors; in particular most valid uses are in\n * situations where the API requires it, not to cast away string\n * constants. We don't use *intptr_t on purpose here and we are\n * explicit about unsigned long so that we don't have additional\n * dependencies.\n */\n#define __UNCONST(a)\t((void *)(unsigned long)(const void *)(a))\n\n#define __dead __attribute__((__noreturn__))\n#define __pure __attribute__((__const__))\n#define __pure2 __attribute__((__const__)) /* Android-added: used by FreeBSD libm */\n\n#define\t__unused\t__attribute__((__unused__))\n\n#define\t__used\t\t__attribute__((__used__))\n\n#define\t__packed\t__attribute__((__packed__))\n#define\t__aligned(x)\t__attribute__((__aligned__(x)))\n#define\t__section(x)\t__attribute__((__section__(x)))\n\n#define __statement(x)\t__extension__(x)\n\n#define __nonnull(args) __attribute__((__nonnull__ args))\n\n#define __printflike(x, y) __attribute__((__format__(printf, x, y))) __nonnull((x))\n#define __scanflike(x, y) __attribute__((__format__(scanf, x, y))) __nonnull((x))\n\n/*\n * C99 defines the restrict type qualifier keyword.\n */\n#if defined(__STDC__VERSION__) && __STDC_VERSION__ >= 199901L\n#define\t__restrict\trestrict\n#endif\n\n/*\n * C99 defines __func__ predefined identifier.\n */\n#if !defined(__STDC_VERSION__) || !(__STDC_VERSION__ >= 199901L)\n#define\t__func__\t__PRETTY_FUNCTION__\n#endif /* !(__STDC_VERSION__ >= 199901L) */\n\n/*\n * GNU C version 2.96 adds explicit branch prediction so that\n * the CPU back-end can hint the processor and also so that\n * code blocks can be reordered such that the predicted path\n * sees a more linear flow, thus improving cache behavior, etc.\n *\n * The following two macros provide us with a way to use this\n * compiler feature.  Use __predict_true() if you expect the expression\n * to evaluate to true, and __predict_false() if you expect the\n * expression to evaluate to false.\n *\n * A few notes about usage:\n *\n *\t* Generally, __predict_false() error condition checks (unless\n *\t  you have some _strong_ reason to do otherwise, in which case\n *\t  document it), and/or __predict_true() `no-error' condition\n *\t  checks, assuming you want to optimize for the no-error case.\n *\n *\t* Other than that, if you don't know the likelihood of a test\n *\t  succeeding from empirical or other `hard' evidence, don't\n *\t  make predictions.\n *\n *\t* These are meant to be used in places that are run `a lot'.\n *\t  It is wasteful to make predictions in code that is run\n *\t  seldomly (e.g. at subsystem initialization time) as the\n *\t  basic block reordering that this affects can often generate\n *\t  larger code.\n */\n#define\t__predict_true(exp)\t__builtin_expect((exp) != 0, 1)\n#define\t__predict_false(exp)\t__builtin_expect((exp) != 0, 0)\n\n#define __noreturn    __attribute__((__noreturn__))\n#define __mallocfunc  __attribute__((malloc))\n#define __purefunc    __attribute__((pure))\n\n#define __always_inline __attribute__((__always_inline__))\n\n#define __wur __attribute__((__warn_unused_result__))\n\n#define __errorattr(msg) __attribute__((__error__(msg)))\n#define __warnattr(msg) __attribute__((__warning__(msg)))\n\n#define __errordecl(name, msg) extern void name(void) __errorattr(msg)\n\n/*\n * Some BSD source needs these macros.\n * Originally they embedded the rcs versions of each source file\n * in the generated binary. We strip strings during build anyway,.\n */\n#define __IDSTRING(_prefix,_s) /* nothing */\n#define __COPYRIGHT(_s) /* nothing */\n#define __FBSDID(_s) /* nothing */\n#define __RCSID(_s) /* nothing */\n#define __SCCSID(_s) /* nothing */\n\n/*\n * _BSD_SOURCE and _GNU_SOURCE are expected to be defined by callers before\n * any standard header file is included. In those header files we test\n * against __USE_BSD and __USE_GNU. glibc does this in <features.h> but we\n * do it in <sys/cdefs.h> instead because that's where our existing\n * _POSIX_C_SOURCE tests were, and we're already confident that <sys/cdefs.h>\n * is included everywhere it should be.\n *\n * The _GNU_SOURCE test needs to come before any _BSD_SOURCE or _POSIX* tests\n * because _GNU_SOURCE implies everything else.\n */\n#if defined(_GNU_SOURCE)\n# define __USE_GNU 1\n# undef _POSIX_SOURCE\n# define _POSIX_SOURCE 1\n# undef _POSIX_C_SOURCE\n# define _POSIX_C_SOURCE 200809L\n# undef _BSD_SOURCE\n# define _BSD_SOURCE 1\n#endif\n\n#if defined(_BSD_SOURCE)\n# define __USE_BSD 1\n#endif\n\n/*\n * _FILE_OFFSET_BITS 64 support.\n */\n#if !defined(__LP64__) && defined(_FILE_OFFSET_BITS)\n#if _FILE_OFFSET_BITS == 64\n#define __USE_FILE_OFFSET64 1\n#endif\n#endif\n\n/*-\n * POSIX.1 requires that the macros we test be defined before any standard\n * header file is included.\n *\n * Here's a quick run-down of the versions:\n *  defined(_POSIX_SOURCE)\t\t1003.1-1988\n *  _POSIX_C_SOURCE == 1\t\t1003.1-1990\n *  _POSIX_C_SOURCE == 2\t\t1003.2-1992 C Language Binding Option\n *  _POSIX_C_SOURCE == 199309\t\t1003.1b-1993\n *  _POSIX_C_SOURCE == 199506\t\t1003.1c-1995, 1003.1i-1995,\n *\t\t\t\t\tand the omnibus ISO/IEC 9945-1: 1996\n *  _POSIX_C_SOURCE == 200112\t\t1003.1-2001\n *  _POSIX_C_SOURCE == 200809\t\t1003.1-2008\n *\n * In addition, the X/Open Portability Guide, which is now the Single UNIX\n * Specification, defines a feature-test macro which indicates the version of\n * that specification, and which subsumes _POSIX_C_SOURCE.\n *\n * Our macros begin with two underscores to avoid namespace screwage.\n */\n\n/* Deal with IEEE Std. 1003.1-1990, in which _POSIX_C_SOURCE == 1. */\n#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 1\n#undef _POSIX_C_SOURCE\t\t/* Probably illegal, but beyond caring now. */\n#define\t_POSIX_C_SOURCE\t\t199009\n#endif\n\n/* Deal with IEEE Std. 1003.2-1992, in which _POSIX_C_SOURCE == 2. */\n#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 2\n#undef _POSIX_C_SOURCE\n#define\t_POSIX_C_SOURCE\t\t199209\n#endif\n\n/* Deal with various X/Open Portability Guides and Single UNIX Spec. */\n#ifdef _XOPEN_SOURCE\n#if _XOPEN_SOURCE - 0 >= 700\n#define\t__XSI_VISIBLE\t\t700\n#undef _POSIX_C_SOURCE\n#define\t_POSIX_C_SOURCE\t\t200809\n#elif _XOPEN_SOURCE - 0 >= 600\n#define\t__XSI_VISIBLE\t\t600\n#undef _POSIX_C_SOURCE\n#define\t_POSIX_C_SOURCE\t\t200112\n#elif _XOPEN_SOURCE - 0 >= 500\n#define\t__XSI_VISIBLE\t\t500\n#undef _POSIX_C_SOURCE\n#define\t_POSIX_C_SOURCE\t\t199506\n#endif\n#endif\n\n/*\n * Deal with all versions of POSIX.  The ordering relative to the tests above is\n * important.\n */\n#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)\n#define\t_POSIX_C_SOURCE\t\t198808\n#endif\n#ifdef _POSIX_C_SOURCE\n#if _POSIX_C_SOURCE >= 200809\n#define\t__POSIX_VISIBLE\t\t200809\n#define\t__ISO_C_VISIBLE\t\t1999\n#elif _POSIX_C_SOURCE >= 200112\n#define\t__POSIX_VISIBLE\t\t200112\n#define\t__ISO_C_VISIBLE\t\t1999\n#elif _POSIX_C_SOURCE >= 199506\n#define\t__POSIX_VISIBLE\t\t199506\n#define\t__ISO_C_VISIBLE\t\t1990\n#elif _POSIX_C_SOURCE >= 199309\n#define\t__POSIX_VISIBLE\t\t199309\n#define\t__ISO_C_VISIBLE\t\t1990\n#elif _POSIX_C_SOURCE >= 199209\n#define\t__POSIX_VISIBLE\t\t199209\n#define\t__ISO_C_VISIBLE\t\t1990\n#elif _POSIX_C_SOURCE >= 199009\n#define\t__POSIX_VISIBLE\t\t199009\n#define\t__ISO_C_VISIBLE\t\t1990\n#else\n#define\t__POSIX_VISIBLE\t\t198808\n#define\t__ISO_C_VISIBLE\t\t0\n#endif /* _POSIX_C_SOURCE */\n#else\n/*-\n * Deal with _ANSI_SOURCE:\n * If it is defined, and no other compilation environment is explicitly\n * requested, then define our internal feature-test macros to zero.  This\n * makes no difference to the preprocessor (undefined symbols in preprocessing\n * expressions are defined to have value zero), but makes it more convenient for\n * a test program to print out the values.\n *\n * If a program mistakenly defines _ANSI_SOURCE and some other macro such as\n * _POSIX_C_SOURCE, we will assume that it wants the broader compilation\n * environment (and in fact we will never get here).\n */\n#if defined(_ANSI_SOURCE)\t/* Hide almost everything. */\n#define\t__POSIX_VISIBLE\t\t0\n#define\t__XSI_VISIBLE\t\t0\n#define\t__BSD_VISIBLE\t\t0\n#define\t__ISO_C_VISIBLE\t\t1990\n#elif defined(_C99_SOURCE)\t/* Localism to specify strict C99 env. */\n#define\t__POSIX_VISIBLE\t\t0\n#define\t__XSI_VISIBLE\t\t0\n#define\t__BSD_VISIBLE\t\t0\n#define\t__ISO_C_VISIBLE\t\t1999\n#else\t\t\t\t/* Default environment: show everything. */\n#define\t__POSIX_VISIBLE\t\t200809\n#define\t__XSI_VISIBLE\t\t700\n#define\t__BSD_VISIBLE\t\t1\n#define\t__ISO_C_VISIBLE\t\t1999\n#endif\n#endif\n\n/*\n * Default values.\n */\n#ifndef __XPG_VISIBLE\n# define __XPG_VISIBLE          700\n#endif\n#ifndef __POSIX_VISIBLE\n# define __POSIX_VISIBLE        200809\n#endif\n#ifndef __ISO_C_VISIBLE\n# define __ISO_C_VISIBLE        1999\n#endif\n#ifndef __BSD_VISIBLE\n# define __BSD_VISIBLE          1\n#endif\n\n#define  __BIONIC__   1\n#include <android/api-level.h>\n\n/* glibc compatibility. */\n#if __POSIX_VISIBLE >= 200809\n#define __USE_ISOC99 1\n#define __USE_XOPEN2K 1\n#define __USE_XOPEN2K8 1\n#endif\n#if __LP64__\n#define __WORDSIZE 64\n#else\n#define __WORDSIZE 32\n#endif\n\n/*\n * When _FORTIFY_SOURCE is defined, automatic bounds checking is\n * added to commonly used libc functions. If a buffer overrun is\n * detected, the program is safely aborted.\n *\n * See\n * http://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html for details.\n */\n#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0\n#  define __BIONIC_FORTIFY 1\n#  if _FORTIFY_SOURCE == 2\n#    define __bos(s) __builtin_object_size((s), 1)\n#  else\n#    define __bos(s) __builtin_object_size((s), 0)\n#  endif\n#  define __bos0(s) __builtin_object_size((s), 0)\n#  define __BIONIC_FORTIFY_INLINE extern __inline__ __always_inline __attribute__((gnu_inline)) __attribute__((__artificial__))\n#endif\n#define __BIONIC_FORTIFY_UNKNOWN_SIZE ((size_t) -1)\n\n/* Used to tag non-static symbols that are private and never exposed by the shared library. */\n#define __LIBC_HIDDEN__ __attribute__((visibility(\"hidden\")))\n\n/* Like __LIBC_HIDDEN__, but preserves binary compatibility for LP32. */\n#ifdef __LP64__\n#define __LIBC32_LEGACY_PUBLIC__ __LIBC_HIDDEN__\n#else\n#define __LIBC32_LEGACY_PUBLIC__ __LIBC_ABI_PUBLIC__\n#endif\n\n/* Used to tag non-static symbols that are public and exposed by the shared library. */\n#define __LIBC_ABI_PUBLIC__ __attribute__((visibility (\"default\")))\n\n/* Used to rename functions so that the compiler emits a call to 'x' rather than the function this was applied to. */\n#define __RENAME(x) __asm__(#x)\n\n#ifdef __clang__\n#define __AVAILABILITY(...) __attribute__((availability(android,__VA_ARGS__)))\n#define __INTRODUCED_IN(api_level) __AVAILABILITY(introduced=api_level)\n#define __DEPRECATED_IN(api_level) __AVAILABILITY(deprecated=api_level)\n#define __REMOVED_IN(api_level) __AVAILABILITY(obsoleted=api_level)\n#else\n#define __AVAILABILITY(...)\n#define __INTRODUCED_IN(api_level)\n#define __DEPRECATED_IN(api_level)\n#define __REMOVED_IN(api_level)\n#endif // __clang__\n\n#if __has_builtin(__builtin_umul_overflow) || __GNUC__ >= 5\n#if __LP64__\n#define __size_mul_overflow(a, b, result) __builtin_umull_overflow(a, b, result)\n#else\n#define __size_mul_overflow(a, b, result) __builtin_umul_overflow(a, b, result)\n#endif\n#else\nextern __inline__ __always_inline __attribute__((gnu_inline))\nint __size_mul_overflow(__SIZE_TYPE__ a, __SIZE_TYPE__ b, __SIZE_TYPE__ *result) {\n    *result = a * b;\n    static const __SIZE_TYPE__ mul_no_overflow = 1UL << (sizeof(__SIZE_TYPE__) * 4);\n    return (a >= mul_no_overflow || b >= mul_no_overflow) && a > 0 && (__SIZE_TYPE__)-1 / a < b;\n}\n#endif\n\n#endif /* !_SYS_CDEFS_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/endian.h",
    "content": "/*-\n * Copyright (c) 1997 Niklas Hallqvist.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef _SYS_ENDIAN_H_\n#define _SYS_ENDIAN_H_\n\n#include <sys/cdefs.h>\n\n#include <stdint.h>\n\n#define _LITTLE_ENDIAN\t1234\n#define _BIG_ENDIAN\t4321\n#define _PDP_ENDIAN\t3412\n#define _BYTE_ORDER _LITTLE_ENDIAN\n#define __LITTLE_ENDIAN_BITFIELD\n\n#ifndef __LITTLE_ENDIAN\n#define __LITTLE_ENDIAN _LITTLE_ENDIAN\n#endif\n#ifndef __BIG_ENDIAN\n#define __BIG_ENDIAN _BIG_ENDIAN\n#endif\n#define __BYTE_ORDER _BYTE_ORDER\n\n#define __swap16 __builtin_bswap16\n#define __swap32 __builtin_bswap32\n#define __swap64 __builtin_bswap64\n\n/* glibc compatibility. */\n__BEGIN_DECLS\nuint32_t htonl(uint32_t) __pure2;\nuint16_t htons(uint16_t) __pure2;\nuint32_t ntohl(uint32_t) __pure2;\nuint16_t ntohs(uint16_t) __pure2;\n__END_DECLS\n\n#define htonl(x) __swap32(x)\n#define htons(x) __swap16(x)\n#define ntohl(x) __swap32(x)\n#define ntohs(x) __swap16(x)\n\n/* Bionic additions */\n#define htonq(x) __swap64(x)\n#define ntohq(x) __swap64(x)\n\n#if __BSD_VISIBLE\n#define LITTLE_ENDIAN _LITTLE_ENDIAN\n#define BIG_ENDIAN _BIG_ENDIAN\n#define PDP_ENDIAN _PDP_ENDIAN\n#define BYTE_ORDER _BYTE_ORDER\n\n#define\tNTOHL(x) (x) = ntohl((u_int32_t)(x))\n#define\tNTOHS(x) (x) = ntohs((u_int16_t)(x))\n#define\tHTONL(x) (x) = htonl((u_int32_t)(x))\n#define\tHTONS(x) (x) = htons((u_int16_t)(x))\n\n#define htobe16 __swap16\n#define htobe32 __swap32\n#define htobe64 __swap64\n#define betoh16 __swap16\n#define betoh32 __swap32\n#define betoh64 __swap64\n\n#define htole16(x) (x)\n#define htole32(x) (x)\n#define htole64(x) (x)\n#define letoh16(x) (x)\n#define letoh32(x) (x)\n#define letoh64(x) (x)\n\n/*\n * glibc-compatible beXXtoh/leXXtoh synonyms for htobeXX/htoleXX.\n * The BSDs export both sets of names, bionic historically only\n * exported the ones above (or on the rhs here), and glibc only\n * exports these names (on the lhs).\n */\n#define be16toh(x) htobe16(x)\n#define be32toh(x) htobe32(x)\n#define be64toh(x) htobe64(x)\n#define le16toh(x) htole16(x)\n#define le32toh(x) htole32(x)\n#define le64toh(x) htole64(x)\n#endif /* __BSD_VISIBLE */\n\n#endif /* _SYS_ENDIAN_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/epoll.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_EPOLL_H_\n#define _SYS_EPOLL_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <fcntl.h> /* For O_CLOEXEC. */\n#include <signal.h> /* For sigset_t. */\n\n__BEGIN_DECLS\n\n#define EPOLLIN          0x00000001\n#define EPOLLPRI         0x00000002\n#define EPOLLOUT         0x00000004\n#define EPOLLERR         0x00000008\n#define EPOLLHUP         0x00000010\n#define EPOLLRDNORM      0x00000040\n#define EPOLLRDBAND      0x00000080\n#define EPOLLWRNORM      0x00000100\n#define EPOLLWRBAND      0x00000200\n#define EPOLLMSG         0x00000400\n#define EPOLLRDHUP       0x00002000\n#define EPOLLWAKEUP      0x20000000\n#define EPOLLONESHOT     0x40000000\n#define EPOLLET          0x80000000\n\n#define EPOLL_CTL_ADD    1\n#define EPOLL_CTL_DEL    2\n#define EPOLL_CTL_MOD    3\n\n#define EPOLL_CLOEXEC O_CLOEXEC\n\ntypedef union epoll_data {\n  void* ptr;\n  int fd;\n  uint32_t u32;\n  uint64_t u64;\n} epoll_data_t;\n\nstruct epoll_event {\n  uint32_t events;\n  epoll_data_t data;\n}\n#ifdef __x86_64__\n__packed\n#endif\n;\n\nint epoll_create(int);\nint epoll_create1(int);\nint epoll_ctl(int, int, int, struct epoll_event*);\nint epoll_wait(int, struct epoll_event*, int, int);\nint epoll_pwait(int, struct epoll_event*, int, int, const sigset_t*);\n\n__END_DECLS\n\n#endif  /* _SYS_EPOLL_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/errno.h",
    "content": "#include <errno.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/eventfd.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_EVENTFD_H\n#define _SYS_EVENTFD_H\n\n#include <sys/cdefs.h>\n#include <fcntl.h>\n\n__BEGIN_DECLS\n\n#define EFD_CLOEXEC O_CLOEXEC\n#define EFD_NONBLOCK O_NONBLOCK\n\n/* type of event counter */\ntypedef uint64_t eventfd_t;\n\nextern int eventfd(unsigned int initial_value, int flags);\n\nextern int eventfd_read(int fd, eventfd_t* value);\nextern int eventfd_write(int fd, eventfd_t value);\n\n__END_DECLS\n\n#endif /* _SYS_EVENTFD_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/fcntl.h",
    "content": "#include <fcntl.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/file.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_FILE_H_\n#define _SYS_FILE_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n#include <fcntl.h>\n\n__BEGIN_DECLS\n\nint flock(int, int);\n\n__END_DECLS\n\n#endif /* _SYS_FILE_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/fsuid.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_FSUID_H_\n#define _SYS_FSUID_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n__BEGIN_DECLS\n\nextern int setfsuid(uid_t);\nextern int setfsgid(gid_t);\n\n__END_DECLS\n\n#endif /* _SYS_FSUID_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/glibc-syscalls.h",
    "content": "/* Generated by gensyscalls.py. Do not edit. */\n#ifndef _BIONIC_GLIBC_SYSCALLS_H_\n#define _BIONIC_GLIBC_SYSCALLS_H_\n#if defined(__aarch64__)\n#define SYS_accept __NR_accept\n#define SYS_accept4 __NR_accept4\n#define SYS_access __NR_access\n#define SYS_acct __NR_acct\n#define SYS_add_key __NR_add_key\n#define SYS_adjtimex __NR_adjtimex\n#define SYS_alarm __NR_alarm\n#define SYS_arch_specific_syscall __NR_arch_specific_syscall\n#define SYS_bdflush __NR_bdflush\n#define SYS_bind __NR_bind\n#define SYS_bpf __NR_bpf\n#define SYS_brk __NR_brk\n#define SYS_capget __NR_capget\n#define SYS_capset __NR_capset\n#define SYS_chdir __NR_chdir\n#define SYS_chmod __NR_chmod\n#define SYS_chown __NR_chown\n#define SYS_chroot __NR_chroot\n#define SYS_clock_adjtime __NR_clock_adjtime\n#define SYS_clock_getres __NR_clock_getres\n#define SYS_clock_gettime __NR_clock_gettime\n#define SYS_clock_nanosleep __NR_clock_nanosleep\n#define SYS_clock_settime __NR_clock_settime\n#define SYS_clone __NR_clone\n#define SYS_close __NR_close\n#define SYS_connect __NR_connect\n#define SYS_creat __NR_creat\n#define SYS_delete_module __NR_delete_module\n#define SYS_dup __NR_dup\n#define SYS_dup2 __NR_dup2\n#define SYS_dup3 __NR_dup3\n#define SYS_epoll_create __NR_epoll_create\n#define SYS_epoll_create1 __NR_epoll_create1\n#define SYS_epoll_ctl __NR_epoll_ctl\n#define SYS_epoll_pwait __NR_epoll_pwait\n#define SYS_epoll_wait __NR_epoll_wait\n#define SYS_eventfd __NR_eventfd\n#define SYS_eventfd2 __NR_eventfd2\n#define SYS_execve __NR_execve\n#define SYS_execveat __NR_execveat\n#define SYS_exit __NR_exit\n#define SYS_exit_group __NR_exit_group\n#define SYS_faccessat __NR_faccessat\n#define SYS_fadvise64 __NR_fadvise64\n#define SYS_fadvise64_64 __NR_fadvise64_64\n#define SYS_fallocate __NR_fallocate\n#define SYS_fanotify_init __NR_fanotify_init\n#define SYS_fanotify_mark __NR_fanotify_mark\n#define SYS_fchdir __NR_fchdir\n#define SYS_fchmod __NR_fchmod\n#define SYS_fchmodat __NR_fchmodat\n#define SYS_fchown __NR_fchown\n#define SYS_fchownat __NR_fchownat\n#define SYS_fcntl __NR_fcntl\n#define SYS_fcntl64 __NR_fcntl64\n#define SYS_fdatasync __NR_fdatasync\n#define SYS_fgetxattr __NR_fgetxattr\n#define SYS_finit_module __NR_finit_module\n#define SYS_flistxattr __NR_flistxattr\n#define SYS_flock __NR_flock\n#define SYS_fork __NR_fork\n#define SYS_fremovexattr __NR_fremovexattr\n#define SYS_fsetxattr __NR_fsetxattr\n#define SYS_fstat __NR_fstat\n#define SYS_fstat64 __NR_fstat64\n#define SYS_fstatat64 __NR_fstatat64\n#define SYS_fstatfs __NR_fstatfs\n#define SYS_fstatfs64 __NR_fstatfs64\n#define SYS_fsync __NR_fsync\n#define SYS_ftruncate __NR_ftruncate\n#define SYS_ftruncate64 __NR_ftruncate64\n#define SYS_futex __NR_futex\n#define SYS_futimesat __NR_futimesat\n#define SYS_get_mempolicy __NR_get_mempolicy\n#define SYS_get_robust_list __NR_get_robust_list\n#define SYS_getcpu __NR_getcpu\n#define SYS_getcwd __NR_getcwd\n#define SYS_getdents __NR_getdents\n#define SYS_getdents64 __NR_getdents64\n#define SYS_getegid __NR_getegid\n#define SYS_geteuid __NR_geteuid\n#define SYS_getgid __NR_getgid\n#define SYS_getgroups __NR_getgroups\n#define SYS_getitimer __NR_getitimer\n#define SYS_getpeername __NR_getpeername\n#define SYS_getpgid __NR_getpgid\n#define SYS_getpgrp __NR_getpgrp\n#define SYS_getpid __NR_getpid\n#define SYS_getppid __NR_getppid\n#define SYS_getpriority __NR_getpriority\n#define SYS_getrandom __NR_getrandom\n#define SYS_getresgid __NR_getresgid\n#define SYS_getresuid __NR_getresuid\n#define SYS_getrlimit __NR_getrlimit\n#define SYS_getrusage __NR_getrusage\n#define SYS_getsid __NR_getsid\n#define SYS_getsockname __NR_getsockname\n#define SYS_getsockopt __NR_getsockopt\n#define SYS_gettid __NR_gettid\n#define SYS_gettimeofday __NR_gettimeofday\n#define SYS_getuid __NR_getuid\n#define SYS_getxattr __NR_getxattr\n#define SYS_init_module __NR_init_module\n#define SYS_inotify_add_watch __NR_inotify_add_watch\n#define SYS_inotify_init __NR_inotify_init\n#define SYS_inotify_init1 __NR_inotify_init1\n#define SYS_inotify_rm_watch __NR_inotify_rm_watch\n#define SYS_io_cancel __NR_io_cancel\n#define SYS_io_destroy __NR_io_destroy\n#define SYS_io_getevents __NR_io_getevents\n#define SYS_io_setup __NR_io_setup\n#define SYS_io_submit __NR_io_submit\n#define SYS_ioctl __NR_ioctl\n#define SYS_ioprio_get __NR_ioprio_get\n#define SYS_ioprio_set __NR_ioprio_set\n#define SYS_kcmp __NR_kcmp\n#define SYS_kexec_load __NR_kexec_load\n#define SYS_keyctl __NR_keyctl\n#define SYS_kill __NR_kill\n#define SYS_lchown __NR_lchown\n#define SYS_lgetxattr __NR_lgetxattr\n#define SYS_link __NR_link\n#define SYS_linkat __NR_linkat\n#define SYS_listen __NR_listen\n#define SYS_listxattr __NR_listxattr\n#define SYS_llistxattr __NR_llistxattr\n#define SYS_llseek __NR_llseek\n#define SYS_lookup_dcookie __NR_lookup_dcookie\n#define SYS_lremovexattr __NR_lremovexattr\n#define SYS_lseek __NR_lseek\n#define SYS_lsetxattr __NR_lsetxattr\n#define SYS_lstat __NR_lstat\n#define SYS_lstat64 __NR_lstat64\n#define SYS_madvise __NR_madvise\n#define SYS_mbind __NR_mbind\n#define SYS_membarrier __NR_membarrier\n#define SYS_memfd_create __NR_memfd_create\n#define SYS_migrate_pages __NR_migrate_pages\n#define SYS_mincore __NR_mincore\n#define SYS_mkdir __NR_mkdir\n#define SYS_mkdirat __NR_mkdirat\n#define SYS_mknod __NR_mknod\n#define SYS_mknodat __NR_mknodat\n#define SYS_mlock __NR_mlock\n#define SYS_mlock2 __NR_mlock2\n#define SYS_mlockall __NR_mlockall\n#define SYS_mmap __NR_mmap\n#define SYS_mmap2 __NR_mmap2\n#define SYS_mount __NR_mount\n#define SYS_move_pages __NR_move_pages\n#define SYS_mprotect __NR_mprotect\n#define SYS_mq_getsetattr __NR_mq_getsetattr\n#define SYS_mq_notify __NR_mq_notify\n#define SYS_mq_open __NR_mq_open\n#define SYS_mq_timedreceive __NR_mq_timedreceive\n#define SYS_mq_timedsend __NR_mq_timedsend\n#define SYS_mq_unlink __NR_mq_unlink\n#define SYS_mremap __NR_mremap\n#define SYS_msgctl __NR_msgctl\n#define SYS_msgget __NR_msgget\n#define SYS_msgrcv __NR_msgrcv\n#define SYS_msgsnd __NR_msgsnd\n#define SYS_msync __NR_msync\n#define SYS_munlock __NR_munlock\n#define SYS_munlockall __NR_munlockall\n#define SYS_munmap __NR_munmap\n#define SYS_name_to_handle_at __NR_name_to_handle_at\n#define SYS_nanosleep __NR_nanosleep\n#define SYS_newfstatat __NR_newfstatat\n#define SYS_nfsservctl __NR_nfsservctl\n#define SYS_oldwait4 __NR_oldwait4\n#define SYS_open __NR_open\n#define SYS_open_by_handle_at __NR_open_by_handle_at\n#define SYS_openat __NR_openat\n#define SYS_pause __NR_pause\n#define SYS_perf_event_open __NR_perf_event_open\n#define SYS_personality __NR_personality\n#define SYS_pipe __NR_pipe\n#define SYS_pipe2 __NR_pipe2\n#define SYS_pivot_root __NR_pivot_root\n#define SYS_poll __NR_poll\n#define SYS_ppoll __NR_ppoll\n#define SYS_prctl __NR_prctl\n#define SYS_pread64 __NR_pread64\n#define SYS_preadv __NR_preadv\n#define SYS_prlimit64 __NR_prlimit64\n#define SYS_process_vm_readv __NR_process_vm_readv\n#define SYS_process_vm_writev __NR_process_vm_writev\n#define SYS_pselect6 __NR_pselect6\n#define SYS_ptrace __NR_ptrace\n#define SYS_pwrite64 __NR_pwrite64\n#define SYS_pwritev __NR_pwritev\n#define SYS_quotactl __NR_quotactl\n#define SYS_read __NR_read\n#define SYS_readahead __NR_readahead\n#define SYS_readlink __NR_readlink\n#define SYS_readlinkat __NR_readlinkat\n#define SYS_readv __NR_readv\n#define SYS_reboot __NR_reboot\n#define SYS_recv __NR_recv\n#define SYS_recvfrom __NR_recvfrom\n#define SYS_recvmmsg __NR_recvmmsg\n#define SYS_recvmsg __NR_recvmsg\n#define SYS_remap_file_pages __NR_remap_file_pages\n#define SYS_removexattr __NR_removexattr\n#define SYS_rename __NR_rename\n#define SYS_renameat __NR_renameat\n#define SYS_renameat2 __NR_renameat2\n#define SYS_request_key __NR_request_key\n#define SYS_restart_syscall __NR_restart_syscall\n#define SYS_rmdir __NR_rmdir\n#define SYS_rt_sigaction __NR_rt_sigaction\n#define SYS_rt_sigpending __NR_rt_sigpending\n#define SYS_rt_sigprocmask __NR_rt_sigprocmask\n#define SYS_rt_sigqueueinfo __NR_rt_sigqueueinfo\n#define SYS_rt_sigreturn __NR_rt_sigreturn\n#define SYS_rt_sigsuspend __NR_rt_sigsuspend\n#define SYS_rt_sigtimedwait __NR_rt_sigtimedwait\n#define SYS_rt_tgsigqueueinfo __NR_rt_tgsigqueueinfo\n#define SYS_sched_get_priority_max __NR_sched_get_priority_max\n#define SYS_sched_get_priority_min __NR_sched_get_priority_min\n#define SYS_sched_getaffinity __NR_sched_getaffinity\n#define SYS_sched_getattr __NR_sched_getattr\n#define SYS_sched_getparam __NR_sched_getparam\n#define SYS_sched_getscheduler __NR_sched_getscheduler\n#define SYS_sched_rr_get_interval __NR_sched_rr_get_interval\n#define SYS_sched_setaffinity __NR_sched_setaffinity\n#define SYS_sched_setattr __NR_sched_setattr\n#define SYS_sched_setparam __NR_sched_setparam\n#define SYS_sched_setscheduler __NR_sched_setscheduler\n#define SYS_sched_yield __NR_sched_yield\n#define SYS_seccomp __NR_seccomp\n#define SYS_select __NR_select\n#define SYS_semctl __NR_semctl\n#define SYS_semget __NR_semget\n#define SYS_semop __NR_semop\n#define SYS_semtimedop __NR_semtimedop\n#define SYS_send __NR_send\n#define SYS_sendfile __NR_sendfile\n#define SYS_sendfile64 __NR_sendfile64\n#define SYS_sendmmsg __NR_sendmmsg\n#define SYS_sendmsg __NR_sendmsg\n#define SYS_sendto __NR_sendto\n#define SYS_set_mempolicy __NR_set_mempolicy\n#define SYS_set_robust_list __NR_set_robust_list\n#define SYS_set_tid_address __NR_set_tid_address\n#define SYS_setdomainname __NR_setdomainname\n#define SYS_setfsgid __NR_setfsgid\n#define SYS_setfsuid __NR_setfsuid\n#define SYS_setgid __NR_setgid\n#define SYS_setgroups __NR_setgroups\n#define SYS_sethostname __NR_sethostname\n#define SYS_setitimer __NR_setitimer\n#define SYS_setns __NR_setns\n#define SYS_setpgid __NR_setpgid\n#define SYS_setpriority __NR_setpriority\n#define SYS_setregid __NR_setregid\n#define SYS_setresgid __NR_setresgid\n#define SYS_setresuid __NR_setresuid\n#define SYS_setreuid __NR_setreuid\n#define SYS_setrlimit __NR_setrlimit\n#define SYS_setsid __NR_setsid\n#define SYS_setsockopt __NR_setsockopt\n#define SYS_settimeofday __NR_settimeofday\n#define SYS_setuid __NR_setuid\n#define SYS_setxattr __NR_setxattr\n#define SYS_shmat __NR_shmat\n#define SYS_shmctl __NR_shmctl\n#define SYS_shmdt __NR_shmdt\n#define SYS_shmget __NR_shmget\n#define SYS_shutdown __NR_shutdown\n#define SYS_sigaltstack __NR_sigaltstack\n#define SYS_signalfd __NR_signalfd\n#define SYS_signalfd4 __NR_signalfd4\n#define SYS_socket __NR_socket\n#define SYS_socketpair __NR_socketpair\n#define SYS_splice __NR_splice\n#define SYS_stat __NR_stat\n#define SYS_stat64 __NR_stat64\n#define SYS_statfs __NR_statfs\n#define SYS_statfs64 __NR_statfs64\n#define SYS_swapoff __NR_swapoff\n#define SYS_swapon __NR_swapon\n#define SYS_symlink __NR_symlink\n#define SYS_symlinkat __NR_symlinkat\n#define SYS_sync __NR_sync\n#define SYS_sync_file_range __NR_sync_file_range\n#define SYS_sync_file_range2 __NR_sync_file_range2\n#define SYS_syncfs __NR_syncfs\n#define SYS_syscalls __NR_syscalls\n#define SYS_sysinfo __NR_sysinfo\n#define SYS_syslog __NR_syslog\n#define SYS_tee __NR_tee\n#define SYS_tgkill __NR_tgkill\n#define SYS_time __NR_time\n#define SYS_timer_create __NR_timer_create\n#define SYS_timer_delete __NR_timer_delete\n#define SYS_timer_getoverrun __NR_timer_getoverrun\n#define SYS_timer_gettime __NR_timer_gettime\n#define SYS_timer_settime __NR_timer_settime\n#define SYS_timerfd_create __NR_timerfd_create\n#define SYS_timerfd_gettime __NR_timerfd_gettime\n#define SYS_timerfd_settime __NR_timerfd_settime\n#define SYS_times __NR_times\n#define SYS_tkill __NR_tkill\n#define SYS_truncate __NR_truncate\n#define SYS_truncate64 __NR_truncate64\n#define SYS_umask __NR_umask\n#define SYS_umount __NR_umount\n#define SYS_umount2 __NR_umount2\n#define SYS_uname __NR_uname\n#define SYS_unlink __NR_unlink\n#define SYS_unlinkat __NR_unlinkat\n#define SYS_unshare __NR_unshare\n#define SYS_uselib __NR_uselib\n#define SYS_userfaultfd __NR_userfaultfd\n#define SYS_ustat __NR_ustat\n#define SYS_utime __NR_utime\n#define SYS_utimensat __NR_utimensat\n#define SYS_utimes __NR_utimes\n#define SYS_vfork __NR_vfork\n#define SYS_vhangup __NR_vhangup\n#define SYS_vmsplice __NR_vmsplice\n#define SYS_wait4 __NR_wait4\n#define SYS_waitid __NR_waitid\n#define SYS_write __NR_write\n#define SYS_writev __NR_writev\n#elif defined(__arm__)\n#define SYS_accept __NR_accept\n#define SYS_accept4 __NR_accept4\n#define SYS_access __NR_access\n#define SYS_acct __NR_acct\n#define SYS_add_key __NR_add_key\n#define SYS_adjtimex __NR_adjtimex\n#define SYS_alarm __NR_alarm\n#define SYS_arm_fadvise64_64 __NR_arm_fadvise64_64\n#define SYS_arm_sync_file_range __NR_arm_sync_file_range\n#define SYS_bdflush __NR_bdflush\n#define SYS_bind __NR_bind\n#define SYS_bpf __NR_bpf\n#define SYS_brk __NR_brk\n#define SYS_capget __NR_capget\n#define SYS_capset __NR_capset\n#define SYS_chdir __NR_chdir\n#define SYS_chmod __NR_chmod\n#define SYS_chown __NR_chown\n#define SYS_chown32 __NR_chown32\n#define SYS_chroot __NR_chroot\n#define SYS_clock_adjtime __NR_clock_adjtime\n#define SYS_clock_getres __NR_clock_getres\n#define SYS_clock_gettime __NR_clock_gettime\n#define SYS_clock_nanosleep __NR_clock_nanosleep\n#define SYS_clock_settime __NR_clock_settime\n#define SYS_clone __NR_clone\n#define SYS_close __NR_close\n#define SYS_connect __NR_connect\n#define SYS_creat __NR_creat\n#define SYS_delete_module __NR_delete_module\n#define SYS_dup __NR_dup\n#define SYS_dup2 __NR_dup2\n#define SYS_dup3 __NR_dup3\n#define SYS_epoll_create __NR_epoll_create\n#define SYS_epoll_create1 __NR_epoll_create1\n#define SYS_epoll_ctl __NR_epoll_ctl\n#define SYS_epoll_pwait __NR_epoll_pwait\n#define SYS_epoll_wait __NR_epoll_wait\n#define SYS_eventfd __NR_eventfd\n#define SYS_eventfd2 __NR_eventfd2\n#define SYS_execve __NR_execve\n#define SYS_execveat __NR_execveat\n#define SYS_exit __NR_exit\n#define SYS_exit_group __NR_exit_group\n#define SYS_faccessat __NR_faccessat\n#define SYS_fallocate __NR_fallocate\n#define SYS_fanotify_init __NR_fanotify_init\n#define SYS_fanotify_mark __NR_fanotify_mark\n#define SYS_fchdir __NR_fchdir\n#define SYS_fchmod __NR_fchmod\n#define SYS_fchmodat __NR_fchmodat\n#define SYS_fchown __NR_fchown\n#define SYS_fchown32 __NR_fchown32\n#define SYS_fchownat __NR_fchownat\n#define SYS_fcntl __NR_fcntl\n#define SYS_fcntl64 __NR_fcntl64\n#define SYS_fdatasync __NR_fdatasync\n#define SYS_fgetxattr __NR_fgetxattr\n#define SYS_finit_module __NR_finit_module\n#define SYS_flistxattr __NR_flistxattr\n#define SYS_flock __NR_flock\n#define SYS_fork __NR_fork\n#define SYS_fremovexattr __NR_fremovexattr\n#define SYS_fsetxattr __NR_fsetxattr\n#define SYS_fstat __NR_fstat\n#define SYS_fstat64 __NR_fstat64\n#define SYS_fstatat64 __NR_fstatat64\n#define SYS_fstatfs __NR_fstatfs\n#define SYS_fstatfs64 __NR_fstatfs64\n#define SYS_fsync __NR_fsync\n#define SYS_ftruncate __NR_ftruncate\n#define SYS_ftruncate64 __NR_ftruncate64\n#define SYS_futex __NR_futex\n#define SYS_futimesat __NR_futimesat\n#define SYS_get_mempolicy __NR_get_mempolicy\n#define SYS_get_robust_list __NR_get_robust_list\n#define SYS_getcpu __NR_getcpu\n#define SYS_getcwd __NR_getcwd\n#define SYS_getdents __NR_getdents\n#define SYS_getdents64 __NR_getdents64\n#define SYS_getegid __NR_getegid\n#define SYS_getegid32 __NR_getegid32\n#define SYS_geteuid __NR_geteuid\n#define SYS_geteuid32 __NR_geteuid32\n#define SYS_getgid __NR_getgid\n#define SYS_getgid32 __NR_getgid32\n#define SYS_getgroups __NR_getgroups\n#define SYS_getgroups32 __NR_getgroups32\n#define SYS_getitimer __NR_getitimer\n#define SYS_getpeername __NR_getpeername\n#define SYS_getpgid __NR_getpgid\n#define SYS_getpgrp __NR_getpgrp\n#define SYS_getpid __NR_getpid\n#define SYS_getppid __NR_getppid\n#define SYS_getpriority __NR_getpriority\n#define SYS_getrandom __NR_getrandom\n#define SYS_getresgid __NR_getresgid\n#define SYS_getresgid32 __NR_getresgid32\n#define SYS_getresuid __NR_getresuid\n#define SYS_getresuid32 __NR_getresuid32\n#define SYS_getrlimit __NR_getrlimit\n#define SYS_getrusage __NR_getrusage\n#define SYS_getsid __NR_getsid\n#define SYS_getsockname __NR_getsockname\n#define SYS_getsockopt __NR_getsockopt\n#define SYS_gettid __NR_gettid\n#define SYS_gettimeofday __NR_gettimeofday\n#define SYS_getuid __NR_getuid\n#define SYS_getuid32 __NR_getuid32\n#define SYS_getxattr __NR_getxattr\n#define SYS_init_module __NR_init_module\n#define SYS_inotify_add_watch __NR_inotify_add_watch\n#define SYS_inotify_init __NR_inotify_init\n#define SYS_inotify_init1 __NR_inotify_init1\n#define SYS_inotify_rm_watch __NR_inotify_rm_watch\n#define SYS_io_cancel __NR_io_cancel\n#define SYS_io_destroy __NR_io_destroy\n#define SYS_io_getevents __NR_io_getevents\n#define SYS_io_setup __NR_io_setup\n#define SYS_io_submit __NR_io_submit\n#define SYS_ioctl __NR_ioctl\n#define SYS_ioprio_get __NR_ioprio_get\n#define SYS_ioprio_set __NR_ioprio_set\n#define SYS_ipc __NR_ipc\n#define SYS_kcmp __NR_kcmp\n#define SYS_kexec_load __NR_kexec_load\n#define SYS_keyctl __NR_keyctl\n#define SYS_kill __NR_kill\n#define SYS_lchown __NR_lchown\n#define SYS_lchown32 __NR_lchown32\n#define SYS_lgetxattr __NR_lgetxattr\n#define SYS_link __NR_link\n#define SYS_linkat __NR_linkat\n#define SYS_listen __NR_listen\n#define SYS_listxattr __NR_listxattr\n#define SYS_llistxattr __NR_llistxattr\n#define SYS_lookup_dcookie __NR_lookup_dcookie\n#define SYS_lremovexattr __NR_lremovexattr\n#define SYS_lseek __NR_lseek\n#define SYS_lsetxattr __NR_lsetxattr\n#define SYS_lstat __NR_lstat\n#define SYS_lstat64 __NR_lstat64\n#define SYS_madvise __NR_madvise\n#define SYS_mbind __NR_mbind\n#define SYS_membarrier __NR_membarrier\n#define SYS_memfd_create __NR_memfd_create\n#define SYS_mincore __NR_mincore\n#define SYS_mkdir __NR_mkdir\n#define SYS_mkdirat __NR_mkdirat\n#define SYS_mknod __NR_mknod\n#define SYS_mknodat __NR_mknodat\n#define SYS_mlock __NR_mlock\n#define SYS_mlock2 __NR_mlock2\n#define SYS_mlockall __NR_mlockall\n#define SYS_mmap __NR_mmap\n#define SYS_mmap2 __NR_mmap2\n#define SYS_mount __NR_mount\n#define SYS_move_pages __NR_move_pages\n#define SYS_mprotect __NR_mprotect\n#define SYS_mq_getsetattr __NR_mq_getsetattr\n#define SYS_mq_notify __NR_mq_notify\n#define SYS_mq_open __NR_mq_open\n#define SYS_mq_timedreceive __NR_mq_timedreceive\n#define SYS_mq_timedsend __NR_mq_timedsend\n#define SYS_mq_unlink __NR_mq_unlink\n#define SYS_mremap __NR_mremap\n#define SYS_msgctl __NR_msgctl\n#define SYS_msgget __NR_msgget\n#define SYS_msgrcv __NR_msgrcv\n#define SYS_msgsnd __NR_msgsnd\n#define SYS_msync __NR_msync\n#define SYS_munlock __NR_munlock\n#define SYS_munlockall __NR_munlockall\n#define SYS_munmap __NR_munmap\n#define SYS_name_to_handle_at __NR_name_to_handle_at\n#define SYS_nanosleep __NR_nanosleep\n#define SYS_nfsservctl __NR_nfsservctl\n#define SYS_nice __NR_nice\n#define SYS_open __NR_open\n#define SYS_open_by_handle_at __NR_open_by_handle_at\n#define SYS_openat __NR_openat\n#define SYS_pause __NR_pause\n#define SYS_pciconfig_iobase __NR_pciconfig_iobase\n#define SYS_pciconfig_read __NR_pciconfig_read\n#define SYS_pciconfig_write __NR_pciconfig_write\n#define SYS_perf_event_open __NR_perf_event_open\n#define SYS_personality __NR_personality\n#define SYS_pipe __NR_pipe\n#define SYS_pipe2 __NR_pipe2\n#define SYS_pivot_root __NR_pivot_root\n#define SYS_poll __NR_poll\n#define SYS_ppoll __NR_ppoll\n#define SYS_prctl __NR_prctl\n#define SYS_pread64 __NR_pread64\n#define SYS_preadv __NR_preadv\n#define SYS_prlimit64 __NR_prlimit64\n#define SYS_process_vm_readv __NR_process_vm_readv\n#define SYS_process_vm_writev __NR_process_vm_writev\n#define SYS_pselect6 __NR_pselect6\n#define SYS_ptrace __NR_ptrace\n#define SYS_pwrite64 __NR_pwrite64\n#define SYS_pwritev __NR_pwritev\n#define SYS_quotactl __NR_quotactl\n#define SYS_read __NR_read\n#define SYS_readahead __NR_readahead\n#define SYS_readdir __NR_readdir\n#define SYS_readlink __NR_readlink\n#define SYS_readlinkat __NR_readlinkat\n#define SYS_readv __NR_readv\n#define SYS_reboot __NR_reboot\n#define SYS_recv __NR_recv\n#define SYS_recvfrom __NR_recvfrom\n#define SYS_recvmmsg __NR_recvmmsg\n#define SYS_recvmsg __NR_recvmsg\n#define SYS_remap_file_pages __NR_remap_file_pages\n#define SYS_removexattr __NR_removexattr\n#define SYS_rename __NR_rename\n#define SYS_renameat __NR_renameat\n#define SYS_renameat2 __NR_renameat2\n#define SYS_request_key __NR_request_key\n#define SYS_restart_syscall __NR_restart_syscall\n#define SYS_rmdir __NR_rmdir\n#define SYS_rt_sigaction __NR_rt_sigaction\n#define SYS_rt_sigpending __NR_rt_sigpending\n#define SYS_rt_sigprocmask __NR_rt_sigprocmask\n#define SYS_rt_sigqueueinfo __NR_rt_sigqueueinfo\n#define SYS_rt_sigreturn __NR_rt_sigreturn\n#define SYS_rt_sigsuspend __NR_rt_sigsuspend\n#define SYS_rt_sigtimedwait __NR_rt_sigtimedwait\n#define SYS_rt_tgsigqueueinfo __NR_rt_tgsigqueueinfo\n#define SYS_sched_get_priority_max __NR_sched_get_priority_max\n#define SYS_sched_get_priority_min __NR_sched_get_priority_min\n#define SYS_sched_getaffinity __NR_sched_getaffinity\n#define SYS_sched_getattr __NR_sched_getattr\n#define SYS_sched_getparam __NR_sched_getparam\n#define SYS_sched_getscheduler __NR_sched_getscheduler\n#define SYS_sched_rr_get_interval __NR_sched_rr_get_interval\n#define SYS_sched_setaffinity __NR_sched_setaffinity\n#define SYS_sched_setattr __NR_sched_setattr\n#define SYS_sched_setparam __NR_sched_setparam\n#define SYS_sched_setscheduler __NR_sched_setscheduler\n#define SYS_sched_yield __NR_sched_yield\n#define SYS_seccomp __NR_seccomp\n#define SYS_select __NR_select\n#define SYS_semctl __NR_semctl\n#define SYS_semget __NR_semget\n#define SYS_semop __NR_semop\n#define SYS_semtimedop __NR_semtimedop\n#define SYS_send __NR_send\n#define SYS_sendfile __NR_sendfile\n#define SYS_sendfile64 __NR_sendfile64\n#define SYS_sendmmsg __NR_sendmmsg\n#define SYS_sendmsg __NR_sendmsg\n#define SYS_sendto __NR_sendto\n#define SYS_set_mempolicy __NR_set_mempolicy\n#define SYS_set_robust_list __NR_set_robust_list\n#define SYS_set_tid_address __NR_set_tid_address\n#define SYS_setdomainname __NR_setdomainname\n#define SYS_setfsgid __NR_setfsgid\n#define SYS_setfsgid32 __NR_setfsgid32\n#define SYS_setfsuid __NR_setfsuid\n#define SYS_setfsuid32 __NR_setfsuid32\n#define SYS_setgid __NR_setgid\n#define SYS_setgid32 __NR_setgid32\n#define SYS_setgroups __NR_setgroups\n#define SYS_setgroups32 __NR_setgroups32\n#define SYS_sethostname __NR_sethostname\n#define SYS_setitimer __NR_setitimer\n#define SYS_setns __NR_setns\n#define SYS_setpgid __NR_setpgid\n#define SYS_setpriority __NR_setpriority\n#define SYS_setregid __NR_setregid\n#define SYS_setregid32 __NR_setregid32\n#define SYS_setresgid __NR_setresgid\n#define SYS_setresgid32 __NR_setresgid32\n#define SYS_setresuid __NR_setresuid\n#define SYS_setresuid32 __NR_setresuid32\n#define SYS_setreuid __NR_setreuid\n#define SYS_setreuid32 __NR_setreuid32\n#define SYS_setrlimit __NR_setrlimit\n#define SYS_setsid __NR_setsid\n#define SYS_setsockopt __NR_setsockopt\n#define SYS_settimeofday __NR_settimeofday\n#define SYS_setuid __NR_setuid\n#define SYS_setuid32 __NR_setuid32\n#define SYS_setxattr __NR_setxattr\n#define SYS_shmat __NR_shmat\n#define SYS_shmctl __NR_shmctl\n#define SYS_shmdt __NR_shmdt\n#define SYS_shmget __NR_shmget\n#define SYS_shutdown __NR_shutdown\n#define SYS_sigaction __NR_sigaction\n#define SYS_sigaltstack __NR_sigaltstack\n#define SYS_signalfd __NR_signalfd\n#define SYS_signalfd4 __NR_signalfd4\n#define SYS_sigpending __NR_sigpending\n#define SYS_sigprocmask __NR_sigprocmask\n#define SYS_sigreturn __NR_sigreturn\n#define SYS_sigsuspend __NR_sigsuspend\n#define SYS_socket __NR_socket\n#define SYS_socketcall __NR_socketcall\n#define SYS_socketpair __NR_socketpair\n#define SYS_splice __NR_splice\n#define SYS_stat __NR_stat\n#define SYS_stat64 __NR_stat64\n#define SYS_statfs __NR_statfs\n#define SYS_statfs64 __NR_statfs64\n#define SYS_stime __NR_stime\n#define SYS_swapoff __NR_swapoff\n#define SYS_swapon __NR_swapon\n#define SYS_symlink __NR_symlink\n#define SYS_symlinkat __NR_symlinkat\n#define SYS_sync __NR_sync\n#define SYS_sync_file_range2 __NR_sync_file_range2\n#define SYS_syncfs __NR_syncfs\n#define SYS_syscall __NR_syscall\n#define SYS_sysfs __NR_sysfs\n#define SYS_sysinfo __NR_sysinfo\n#define SYS_syslog __NR_syslog\n#define SYS_tee __NR_tee\n#define SYS_tgkill __NR_tgkill\n#define SYS_time __NR_time\n#define SYS_timer_create __NR_timer_create\n#define SYS_timer_delete __NR_timer_delete\n#define SYS_timer_getoverrun __NR_timer_getoverrun\n#define SYS_timer_gettime __NR_timer_gettime\n#define SYS_timer_settime __NR_timer_settime\n#define SYS_timerfd_create __NR_timerfd_create\n#define SYS_timerfd_gettime __NR_timerfd_gettime\n#define SYS_timerfd_settime __NR_timerfd_settime\n#define SYS_times __NR_times\n#define SYS_tkill __NR_tkill\n#define SYS_truncate __NR_truncate\n#define SYS_truncate64 __NR_truncate64\n#define SYS_ugetrlimit __NR_ugetrlimit\n#define SYS_umask __NR_umask\n#define SYS_umount __NR_umount\n#define SYS_umount2 __NR_umount2\n#define SYS_uname __NR_uname\n#define SYS_unlink __NR_unlink\n#define SYS_unlinkat __NR_unlinkat\n#define SYS_unshare __NR_unshare\n#define SYS_uselib __NR_uselib\n#define SYS_userfaultfd __NR_userfaultfd\n#define SYS_ustat __NR_ustat\n#define SYS_utime __NR_utime\n#define SYS_utimensat __NR_utimensat\n#define SYS_utimes __NR_utimes\n#define SYS_vfork __NR_vfork\n#define SYS_vhangup __NR_vhangup\n#define SYS_vmsplice __NR_vmsplice\n#define SYS_vserver __NR_vserver\n#define SYS_wait4 __NR_wait4\n#define SYS_waitid __NR_waitid\n#define SYS_write __NR_write\n#define SYS_writev __NR_writev\n#elif defined(__mips__)\n#define SYS_accept __NR_accept\n#define SYS_accept4 __NR_accept4\n#define SYS_access __NR_access\n#define SYS_acct __NR_acct\n#define SYS_add_key __NR_add_key\n#define SYS_adjtimex __NR_adjtimex\n#define SYS_afs_syscall __NR_afs_syscall\n#define SYS_alarm __NR_alarm\n#define SYS_bdflush __NR_bdflush\n#define SYS_bind __NR_bind\n#define SYS_bpf __NR_bpf\n#define SYS_break __NR_break\n#define SYS_brk __NR_brk\n#define SYS_cachectl __NR_cachectl\n#define SYS_cacheflush __NR_cacheflush\n#define SYS_capget __NR_capget\n#define SYS_capset __NR_capset\n#define SYS_chdir __NR_chdir\n#define SYS_chmod __NR_chmod\n#define SYS_chown __NR_chown\n#define SYS_chroot __NR_chroot\n#define SYS_clock_adjtime __NR_clock_adjtime\n#define SYS_clock_getres __NR_clock_getres\n#define SYS_clock_gettime __NR_clock_gettime\n#define SYS_clock_nanosleep __NR_clock_nanosleep\n#define SYS_clock_settime __NR_clock_settime\n#define SYS_clone __NR_clone\n#define SYS_close __NR_close\n#define SYS_connect __NR_connect\n#define SYS_creat __NR_creat\n#define SYS_create_module __NR_create_module\n#define SYS_delete_module __NR_delete_module\n#define SYS_dup __NR_dup\n#define SYS_dup2 __NR_dup2\n#define SYS_dup3 __NR_dup3\n#define SYS_epoll_create __NR_epoll_create\n#define SYS_epoll_create1 __NR_epoll_create1\n#define SYS_epoll_ctl __NR_epoll_ctl\n#define SYS_epoll_pwait __NR_epoll_pwait\n#define SYS_epoll_wait __NR_epoll_wait\n#define SYS_eventfd __NR_eventfd\n#define SYS_eventfd2 __NR_eventfd2\n#define SYS_execve __NR_execve\n#define SYS_execveat __NR_execveat\n#define SYS_exit __NR_exit\n#define SYS_exit_group __NR_exit_group\n#define SYS_faccessat __NR_faccessat\n#define SYS_fadvise64 __NR_fadvise64\n#define SYS_fallocate __NR_fallocate\n#define SYS_fanotify_init __NR_fanotify_init\n#define SYS_fanotify_mark __NR_fanotify_mark\n#define SYS_fchdir __NR_fchdir\n#define SYS_fchmod __NR_fchmod\n#define SYS_fchmodat __NR_fchmodat\n#define SYS_fchown __NR_fchown\n#define SYS_fchownat __NR_fchownat\n#define SYS_fcntl __NR_fcntl\n#define SYS_fcntl64 __NR_fcntl64\n#define SYS_fdatasync __NR_fdatasync\n#define SYS_fgetxattr __NR_fgetxattr\n#define SYS_finit_module __NR_finit_module\n#define SYS_flistxattr __NR_flistxattr\n#define SYS_flock __NR_flock\n#define SYS_fork __NR_fork\n#define SYS_fremovexattr __NR_fremovexattr\n#define SYS_fsetxattr __NR_fsetxattr\n#define SYS_fstat __NR_fstat\n#define SYS_fstat64 __NR_fstat64\n#define SYS_fstatat64 __NR_fstatat64\n#define SYS_fstatfs __NR_fstatfs\n#define SYS_fstatfs64 __NR_fstatfs64\n#define SYS_fsync __NR_fsync\n#define SYS_ftime __NR_ftime\n#define SYS_ftruncate __NR_ftruncate\n#define SYS_ftruncate64 __NR_ftruncate64\n#define SYS_futex __NR_futex\n#define SYS_futimesat __NR_futimesat\n#define SYS_get_kernel_syms __NR_get_kernel_syms\n#define SYS_get_mempolicy __NR_get_mempolicy\n#define SYS_get_robust_list __NR_get_robust_list\n#define SYS_getcpu __NR_getcpu\n#define SYS_getcwd __NR_getcwd\n#define SYS_getdents __NR_getdents\n#define SYS_getdents64 __NR_getdents64\n#define SYS_getegid __NR_getegid\n#define SYS_geteuid __NR_geteuid\n#define SYS_getgid __NR_getgid\n#define SYS_getgroups __NR_getgroups\n#define SYS_getitimer __NR_getitimer\n#define SYS_getpeername __NR_getpeername\n#define SYS_getpgid __NR_getpgid\n#define SYS_getpgrp __NR_getpgrp\n#define SYS_getpid __NR_getpid\n#define SYS_getpmsg __NR_getpmsg\n#define SYS_getppid __NR_getppid\n#define SYS_getpriority __NR_getpriority\n#define SYS_getrandom __NR_getrandom\n#define SYS_getresgid __NR_getresgid\n#define SYS_getresuid __NR_getresuid\n#define SYS_getrlimit __NR_getrlimit\n#define SYS_getrusage __NR_getrusage\n#define SYS_getsid __NR_getsid\n#define SYS_getsockname __NR_getsockname\n#define SYS_getsockopt __NR_getsockopt\n#define SYS_gettid __NR_gettid\n#define SYS_gettimeofday __NR_gettimeofday\n#define SYS_getuid __NR_getuid\n#define SYS_getxattr __NR_getxattr\n#define SYS_gtty __NR_gtty\n#define SYS_idle __NR_idle\n#define SYS_init_module __NR_init_module\n#define SYS_inotify_add_watch __NR_inotify_add_watch\n#define SYS_inotify_init __NR_inotify_init\n#define SYS_inotify_init1 __NR_inotify_init1\n#define SYS_inotify_rm_watch __NR_inotify_rm_watch\n#define SYS_io_cancel __NR_io_cancel\n#define SYS_io_destroy __NR_io_destroy\n#define SYS_io_getevents __NR_io_getevents\n#define SYS_io_setup __NR_io_setup\n#define SYS_io_submit __NR_io_submit\n#define SYS_ioctl __NR_ioctl\n#define SYS_ioperm __NR_ioperm\n#define SYS_iopl __NR_iopl\n#define SYS_ioprio_get __NR_ioprio_get\n#define SYS_ioprio_set __NR_ioprio_set\n#define SYS_ipc __NR_ipc\n#define SYS_kcmp __NR_kcmp\n#define SYS_kexec_load __NR_kexec_load\n#define SYS_keyctl __NR_keyctl\n#define SYS_kill __NR_kill\n#define SYS_lchown __NR_lchown\n#define SYS_lgetxattr __NR_lgetxattr\n#define SYS_link __NR_link\n#define SYS_linkat __NR_linkat\n#define SYS_listen __NR_listen\n#define SYS_listxattr __NR_listxattr\n#define SYS_llistxattr __NR_llistxattr\n#define SYS_lock __NR_lock\n#define SYS_lookup_dcookie __NR_lookup_dcookie\n#define SYS_lremovexattr __NR_lremovexattr\n#define SYS_lseek __NR_lseek\n#define SYS_lsetxattr __NR_lsetxattr\n#define SYS_lstat __NR_lstat\n#define SYS_lstat64 __NR_lstat64\n#define SYS_madvise __NR_madvise\n#define SYS_mbind __NR_mbind\n#define SYS_membarrier __NR_membarrier\n#define SYS_memfd_create __NR_memfd_create\n#define SYS_migrate_pages __NR_migrate_pages\n#define SYS_mincore __NR_mincore\n#define SYS_mkdir __NR_mkdir\n#define SYS_mkdirat __NR_mkdirat\n#define SYS_mknod __NR_mknod\n#define SYS_mknodat __NR_mknodat\n#define SYS_mlock __NR_mlock\n#define SYS_mlock2 __NR_mlock2\n#define SYS_mlockall __NR_mlockall\n#define SYS_mmap __NR_mmap\n#define SYS_mmap2 __NR_mmap2\n#define SYS_modify_ldt __NR_modify_ldt\n#define SYS_mount __NR_mount\n#define SYS_move_pages __NR_move_pages\n#define SYS_mprotect __NR_mprotect\n#define SYS_mpx __NR_mpx\n#define SYS_mq_getsetattr __NR_mq_getsetattr\n#define SYS_mq_notify __NR_mq_notify\n#define SYS_mq_open __NR_mq_open\n#define SYS_mq_timedreceive __NR_mq_timedreceive\n#define SYS_mq_timedsend __NR_mq_timedsend\n#define SYS_mq_unlink __NR_mq_unlink\n#define SYS_mremap __NR_mremap\n#define SYS_msgctl __NR_msgctl\n#define SYS_msgget __NR_msgget\n#define SYS_msgrcv __NR_msgrcv\n#define SYS_msgsnd __NR_msgsnd\n#define SYS_msync __NR_msync\n#define SYS_munlock __NR_munlock\n#define SYS_munlockall __NR_munlockall\n#define SYS_munmap __NR_munmap\n#define SYS_name_to_handle_at __NR_name_to_handle_at\n#define SYS_nanosleep __NR_nanosleep\n#define SYS_newfstatat __NR_newfstatat\n#define SYS_nfsservctl __NR_nfsservctl\n#define SYS_nice __NR_nice\n#define SYS_open __NR_open\n#define SYS_open_by_handle_at __NR_open_by_handle_at\n#define SYS_openat __NR_openat\n#define SYS_pause __NR_pause\n#define SYS_perf_event_open __NR_perf_event_open\n#define SYS_personality __NR_personality\n#define SYS_pipe __NR_pipe\n#define SYS_pipe2 __NR_pipe2\n#define SYS_pivot_root __NR_pivot_root\n#define SYS_poll __NR_poll\n#define SYS_ppoll __NR_ppoll\n#define SYS_prctl __NR_prctl\n#define SYS_pread64 __NR_pread64\n#define SYS_preadv __NR_preadv\n#define SYS_prlimit64 __NR_prlimit64\n#define SYS_process_vm_readv __NR_process_vm_readv\n#define SYS_process_vm_writev __NR_process_vm_writev\n#define SYS_prof __NR_prof\n#define SYS_profil __NR_profil\n#define SYS_pselect6 __NR_pselect6\n#define SYS_ptrace __NR_ptrace\n#define SYS_putpmsg __NR_putpmsg\n#define SYS_pwrite64 __NR_pwrite64\n#define SYS_pwritev __NR_pwritev\n#define SYS_query_module __NR_query_module\n#define SYS_quotactl __NR_quotactl\n#define SYS_read __NR_read\n#define SYS_readahead __NR_readahead\n#define SYS_readdir __NR_readdir\n#define SYS_readlink __NR_readlink\n#define SYS_readlinkat __NR_readlinkat\n#define SYS_readv __NR_readv\n#define SYS_reboot __NR_reboot\n#define SYS_recv __NR_recv\n#define SYS_recvfrom __NR_recvfrom\n#define SYS_recvmmsg __NR_recvmmsg\n#define SYS_recvmsg __NR_recvmsg\n#define SYS_remap_file_pages __NR_remap_file_pages\n#define SYS_removexattr __NR_removexattr\n#define SYS_rename __NR_rename\n#define SYS_renameat __NR_renameat\n#define SYS_renameat2 __NR_renameat2\n#define SYS_request_key __NR_request_key\n#define SYS_reserved177 __NR_reserved177\n#define SYS_reserved193 __NR_reserved193\n#define SYS_reserved221 __NR_reserved221\n#define SYS_reserved82 __NR_reserved82\n#define SYS_restart_syscall __NR_restart_syscall\n#define SYS_rmdir __NR_rmdir\n#define SYS_rt_sigaction __NR_rt_sigaction\n#define SYS_rt_sigpending __NR_rt_sigpending\n#define SYS_rt_sigprocmask __NR_rt_sigprocmask\n#define SYS_rt_sigqueueinfo __NR_rt_sigqueueinfo\n#define SYS_rt_sigreturn __NR_rt_sigreturn\n#define SYS_rt_sigsuspend __NR_rt_sigsuspend\n#define SYS_rt_sigtimedwait __NR_rt_sigtimedwait\n#define SYS_rt_tgsigqueueinfo __NR_rt_tgsigqueueinfo\n#define SYS_sched_get_priority_max __NR_sched_get_priority_max\n#define SYS_sched_get_priority_min __NR_sched_get_priority_min\n#define SYS_sched_getaffinity __NR_sched_getaffinity\n#define SYS_sched_getattr __NR_sched_getattr\n#define SYS_sched_getparam __NR_sched_getparam\n#define SYS_sched_getscheduler __NR_sched_getscheduler\n#define SYS_sched_rr_get_interval __NR_sched_rr_get_interval\n#define SYS_sched_setaffinity __NR_sched_setaffinity\n#define SYS_sched_setattr __NR_sched_setattr\n#define SYS_sched_setparam __NR_sched_setparam\n#define SYS_sched_setscheduler __NR_sched_setscheduler\n#define SYS_sched_yield __NR_sched_yield\n#define SYS_seccomp __NR_seccomp\n#define SYS_semctl __NR_semctl\n#define SYS_semget __NR_semget\n#define SYS_semop __NR_semop\n#define SYS_semtimedop __NR_semtimedop\n#define SYS_send __NR_send\n#define SYS_sendfile __NR_sendfile\n#define SYS_sendfile64 __NR_sendfile64\n#define SYS_sendmmsg __NR_sendmmsg\n#define SYS_sendmsg __NR_sendmsg\n#define SYS_sendto __NR_sendto\n#define SYS_set_mempolicy __NR_set_mempolicy\n#define SYS_set_robust_list __NR_set_robust_list\n#define SYS_set_thread_area __NR_set_thread_area\n#define SYS_set_tid_address __NR_set_tid_address\n#define SYS_setdomainname __NR_setdomainname\n#define SYS_setfsgid __NR_setfsgid\n#define SYS_setfsuid __NR_setfsuid\n#define SYS_setgid __NR_setgid\n#define SYS_setgroups __NR_setgroups\n#define SYS_sethostname __NR_sethostname\n#define SYS_setitimer __NR_setitimer\n#define SYS_setns __NR_setns\n#define SYS_setpgid __NR_setpgid\n#define SYS_setpriority __NR_setpriority\n#define SYS_setregid __NR_setregid\n#define SYS_setresgid __NR_setresgid\n#define SYS_setresuid __NR_setresuid\n#define SYS_setreuid __NR_setreuid\n#define SYS_setrlimit __NR_setrlimit\n#define SYS_setsid __NR_setsid\n#define SYS_setsockopt __NR_setsockopt\n#define SYS_settimeofday __NR_settimeofday\n#define SYS_setuid __NR_setuid\n#define SYS_setxattr __NR_setxattr\n#define SYS_sgetmask __NR_sgetmask\n#define SYS_shmat __NR_shmat\n#define SYS_shmctl __NR_shmctl\n#define SYS_shmdt __NR_shmdt\n#define SYS_shmget __NR_shmget\n#define SYS_shutdown __NR_shutdown\n#define SYS_sigaction __NR_sigaction\n#define SYS_sigaltstack __NR_sigaltstack\n#define SYS_signal __NR_signal\n#define SYS_signalfd __NR_signalfd\n#define SYS_signalfd4 __NR_signalfd4\n#define SYS_sigpending __NR_sigpending\n#define SYS_sigprocmask __NR_sigprocmask\n#define SYS_sigreturn __NR_sigreturn\n#define SYS_sigsuspend __NR_sigsuspend\n#define SYS_socket __NR_socket\n#define SYS_socketcall __NR_socketcall\n#define SYS_socketpair __NR_socketpair\n#define SYS_splice __NR_splice\n#define SYS_ssetmask __NR_ssetmask\n#define SYS_stat __NR_stat\n#define SYS_stat64 __NR_stat64\n#define SYS_statfs __NR_statfs\n#define SYS_statfs64 __NR_statfs64\n#define SYS_stime __NR_stime\n#define SYS_stty __NR_stty\n#define SYS_swapoff __NR_swapoff\n#define SYS_swapon __NR_swapon\n#define SYS_symlink __NR_symlink\n#define SYS_symlinkat __NR_symlinkat\n#define SYS_sync __NR_sync\n#define SYS_sync_file_range __NR_sync_file_range\n#define SYS_syncfs __NR_syncfs\n#define SYS_syscall __NR_syscall\n#define SYS_sysfs __NR_sysfs\n#define SYS_sysinfo __NR_sysinfo\n#define SYS_syslog __NR_syslog\n#define SYS_sysmips __NR_sysmips\n#define SYS_tee __NR_tee\n#define SYS_tgkill __NR_tgkill\n#define SYS_time __NR_time\n#define SYS_timer_create __NR_timer_create\n#define SYS_timer_delete __NR_timer_delete\n#define SYS_timer_getoverrun __NR_timer_getoverrun\n#define SYS_timer_gettime __NR_timer_gettime\n#define SYS_timer_settime __NR_timer_settime\n#define SYS_timerfd __NR_timerfd\n#define SYS_timerfd_create __NR_timerfd_create\n#define SYS_timerfd_gettime __NR_timerfd_gettime\n#define SYS_timerfd_settime __NR_timerfd_settime\n#define SYS_times __NR_times\n#define SYS_tkill __NR_tkill\n#define SYS_truncate __NR_truncate\n#define SYS_truncate64 __NR_truncate64\n#define SYS_ulimit __NR_ulimit\n#define SYS_umask __NR_umask\n#define SYS_umount __NR_umount\n#define SYS_umount2 __NR_umount2\n#define SYS_uname __NR_uname\n#define SYS_unlink __NR_unlink\n#define SYS_unlinkat __NR_unlinkat\n#define SYS_unshare __NR_unshare\n#define SYS_unused109 __NR_unused109\n#define SYS_unused150 __NR_unused150\n#define SYS_unused18 __NR_unused18\n#define SYS_unused28 __NR_unused28\n#define SYS_unused59 __NR_unused59\n#define SYS_unused84 __NR_unused84\n#define SYS_uselib __NR_uselib\n#define SYS_userfaultfd __NR_userfaultfd\n#define SYS_ustat __NR_ustat\n#define SYS_utime __NR_utime\n#define SYS_utimensat __NR_utimensat\n#define SYS_utimes __NR_utimes\n#define SYS_vhangup __NR_vhangup\n#define SYS_vm86 __NR_vm86\n#define SYS_vmsplice __NR_vmsplice\n#define SYS_vserver __NR_vserver\n#define SYS_wait4 __NR_wait4\n#define SYS_waitid __NR_waitid\n#define SYS_waitpid __NR_waitpid\n#define SYS_write __NR_write\n#define SYS_writev __NR_writev\n#elif defined(__i386__)\n#define SYS_accept4 __NR_accept4\n#define SYS_access __NR_access\n#define SYS_acct __NR_acct\n#define SYS_add_key __NR_add_key\n#define SYS_adjtimex __NR_adjtimex\n#define SYS_afs_syscall __NR_afs_syscall\n#define SYS_alarm __NR_alarm\n#define SYS_bdflush __NR_bdflush\n#define SYS_bind __NR_bind\n#define SYS_bpf __NR_bpf\n#define SYS_break __NR_break\n#define SYS_brk __NR_brk\n#define SYS_capget __NR_capget\n#define SYS_capset __NR_capset\n#define SYS_chdir __NR_chdir\n#define SYS_chmod __NR_chmod\n#define SYS_chown __NR_chown\n#define SYS_chown32 __NR_chown32\n#define SYS_chroot __NR_chroot\n#define SYS_clock_adjtime __NR_clock_adjtime\n#define SYS_clock_getres __NR_clock_getres\n#define SYS_clock_gettime __NR_clock_gettime\n#define SYS_clock_nanosleep __NR_clock_nanosleep\n#define SYS_clock_settime __NR_clock_settime\n#define SYS_clone __NR_clone\n#define SYS_close __NR_close\n#define SYS_connect __NR_connect\n#define SYS_creat __NR_creat\n#define SYS_create_module __NR_create_module\n#define SYS_delete_module __NR_delete_module\n#define SYS_dup __NR_dup\n#define SYS_dup2 __NR_dup2\n#define SYS_dup3 __NR_dup3\n#define SYS_epoll_create __NR_epoll_create\n#define SYS_epoll_create1 __NR_epoll_create1\n#define SYS_epoll_ctl __NR_epoll_ctl\n#define SYS_epoll_pwait __NR_epoll_pwait\n#define SYS_epoll_wait __NR_epoll_wait\n#define SYS_eventfd __NR_eventfd\n#define SYS_eventfd2 __NR_eventfd2\n#define SYS_execve __NR_execve\n#define SYS_execveat __NR_execveat\n#define SYS_exit __NR_exit\n#define SYS_exit_group __NR_exit_group\n#define SYS_faccessat __NR_faccessat\n#define SYS_fadvise64 __NR_fadvise64\n#define SYS_fadvise64_64 __NR_fadvise64_64\n#define SYS_fallocate __NR_fallocate\n#define SYS_fanotify_init __NR_fanotify_init\n#define SYS_fanotify_mark __NR_fanotify_mark\n#define SYS_fchdir __NR_fchdir\n#define SYS_fchmod __NR_fchmod\n#define SYS_fchmodat __NR_fchmodat\n#define SYS_fchown __NR_fchown\n#define SYS_fchown32 __NR_fchown32\n#define SYS_fchownat __NR_fchownat\n#define SYS_fcntl __NR_fcntl\n#define SYS_fcntl64 __NR_fcntl64\n#define SYS_fdatasync __NR_fdatasync\n#define SYS_fgetxattr __NR_fgetxattr\n#define SYS_finit_module __NR_finit_module\n#define SYS_flistxattr __NR_flistxattr\n#define SYS_flock __NR_flock\n#define SYS_fork __NR_fork\n#define SYS_fremovexattr __NR_fremovexattr\n#define SYS_fsetxattr __NR_fsetxattr\n#define SYS_fstat __NR_fstat\n#define SYS_fstat64 __NR_fstat64\n#define SYS_fstatat64 __NR_fstatat64\n#define SYS_fstatfs __NR_fstatfs\n#define SYS_fstatfs64 __NR_fstatfs64\n#define SYS_fsync __NR_fsync\n#define SYS_ftime __NR_ftime\n#define SYS_ftruncate __NR_ftruncate\n#define SYS_ftruncate64 __NR_ftruncate64\n#define SYS_futex __NR_futex\n#define SYS_futimesat __NR_futimesat\n#define SYS_get_kernel_syms __NR_get_kernel_syms\n#define SYS_get_mempolicy __NR_get_mempolicy\n#define SYS_get_robust_list __NR_get_robust_list\n#define SYS_get_thread_area __NR_get_thread_area\n#define SYS_getcpu __NR_getcpu\n#define SYS_getcwd __NR_getcwd\n#define SYS_getdents __NR_getdents\n#define SYS_getdents64 __NR_getdents64\n#define SYS_getegid __NR_getegid\n#define SYS_getegid32 __NR_getegid32\n#define SYS_geteuid __NR_geteuid\n#define SYS_geteuid32 __NR_geteuid32\n#define SYS_getgid __NR_getgid\n#define SYS_getgid32 __NR_getgid32\n#define SYS_getgroups __NR_getgroups\n#define SYS_getgroups32 __NR_getgroups32\n#define SYS_getitimer __NR_getitimer\n#define SYS_getpeername __NR_getpeername\n#define SYS_getpgid __NR_getpgid\n#define SYS_getpgrp __NR_getpgrp\n#define SYS_getpid __NR_getpid\n#define SYS_getpmsg __NR_getpmsg\n#define SYS_getppid __NR_getppid\n#define SYS_getpriority __NR_getpriority\n#define SYS_getrandom __NR_getrandom\n#define SYS_getresgid __NR_getresgid\n#define SYS_getresgid32 __NR_getresgid32\n#define SYS_getresuid __NR_getresuid\n#define SYS_getresuid32 __NR_getresuid32\n#define SYS_getrlimit __NR_getrlimit\n#define SYS_getrusage __NR_getrusage\n#define SYS_getsid __NR_getsid\n#define SYS_getsockname __NR_getsockname\n#define SYS_getsockopt __NR_getsockopt\n#define SYS_gettid __NR_gettid\n#define SYS_gettimeofday __NR_gettimeofday\n#define SYS_getuid __NR_getuid\n#define SYS_getuid32 __NR_getuid32\n#define SYS_getxattr __NR_getxattr\n#define SYS_gtty __NR_gtty\n#define SYS_idle __NR_idle\n#define SYS_init_module __NR_init_module\n#define SYS_inotify_add_watch __NR_inotify_add_watch\n#define SYS_inotify_init __NR_inotify_init\n#define SYS_inotify_init1 __NR_inotify_init1\n#define SYS_inotify_rm_watch __NR_inotify_rm_watch\n#define SYS_io_cancel __NR_io_cancel\n#define SYS_io_destroy __NR_io_destroy\n#define SYS_io_getevents __NR_io_getevents\n#define SYS_io_setup __NR_io_setup\n#define SYS_io_submit __NR_io_submit\n#define SYS_ioctl __NR_ioctl\n#define SYS_ioperm __NR_ioperm\n#define SYS_iopl __NR_iopl\n#define SYS_ioprio_get __NR_ioprio_get\n#define SYS_ioprio_set __NR_ioprio_set\n#define SYS_ipc __NR_ipc\n#define SYS_kcmp __NR_kcmp\n#define SYS_kexec_load __NR_kexec_load\n#define SYS_keyctl __NR_keyctl\n#define SYS_kill __NR_kill\n#define SYS_lchown __NR_lchown\n#define SYS_lchown32 __NR_lchown32\n#define SYS_lgetxattr __NR_lgetxattr\n#define SYS_link __NR_link\n#define SYS_linkat __NR_linkat\n#define SYS_listen __NR_listen\n#define SYS_listxattr __NR_listxattr\n#define SYS_llistxattr __NR_llistxattr\n#define SYS_lock __NR_lock\n#define SYS_lookup_dcookie __NR_lookup_dcookie\n#define SYS_lremovexattr __NR_lremovexattr\n#define SYS_lseek __NR_lseek\n#define SYS_lsetxattr __NR_lsetxattr\n#define SYS_lstat __NR_lstat\n#define SYS_lstat64 __NR_lstat64\n#define SYS_madvise __NR_madvise\n#define SYS_mbind __NR_mbind\n#define SYS_membarrier __NR_membarrier\n#define SYS_memfd_create __NR_memfd_create\n#define SYS_migrate_pages __NR_migrate_pages\n#define SYS_mincore __NR_mincore\n#define SYS_mkdir __NR_mkdir\n#define SYS_mkdirat __NR_mkdirat\n#define SYS_mknod __NR_mknod\n#define SYS_mknodat __NR_mknodat\n#define SYS_mlock __NR_mlock\n#define SYS_mlock2 __NR_mlock2\n#define SYS_mlockall __NR_mlockall\n#define SYS_mmap __NR_mmap\n#define SYS_mmap2 __NR_mmap2\n#define SYS_modify_ldt __NR_modify_ldt\n#define SYS_mount __NR_mount\n#define SYS_move_pages __NR_move_pages\n#define SYS_mprotect __NR_mprotect\n#define SYS_mpx __NR_mpx\n#define SYS_mq_getsetattr __NR_mq_getsetattr\n#define SYS_mq_notify __NR_mq_notify\n#define SYS_mq_open __NR_mq_open\n#define SYS_mq_timedreceive __NR_mq_timedreceive\n#define SYS_mq_timedsend __NR_mq_timedsend\n#define SYS_mq_unlink __NR_mq_unlink\n#define SYS_mremap __NR_mremap\n#define SYS_msync __NR_msync\n#define SYS_munlock __NR_munlock\n#define SYS_munlockall __NR_munlockall\n#define SYS_munmap __NR_munmap\n#define SYS_name_to_handle_at __NR_name_to_handle_at\n#define SYS_nanosleep __NR_nanosleep\n#define SYS_nfsservctl __NR_nfsservctl\n#define SYS_nice __NR_nice\n#define SYS_oldfstat __NR_oldfstat\n#define SYS_oldlstat __NR_oldlstat\n#define SYS_oldolduname __NR_oldolduname\n#define SYS_oldstat __NR_oldstat\n#define SYS_olduname __NR_olduname\n#define SYS_open __NR_open\n#define SYS_open_by_handle_at __NR_open_by_handle_at\n#define SYS_openat __NR_openat\n#define SYS_pause __NR_pause\n#define SYS_perf_event_open __NR_perf_event_open\n#define SYS_personality __NR_personality\n#define SYS_pipe __NR_pipe\n#define SYS_pipe2 __NR_pipe2\n#define SYS_pivot_root __NR_pivot_root\n#define SYS_poll __NR_poll\n#define SYS_ppoll __NR_ppoll\n#define SYS_prctl __NR_prctl\n#define SYS_pread64 __NR_pread64\n#define SYS_preadv __NR_preadv\n#define SYS_prlimit64 __NR_prlimit64\n#define SYS_process_vm_readv __NR_process_vm_readv\n#define SYS_process_vm_writev __NR_process_vm_writev\n#define SYS_prof __NR_prof\n#define SYS_profil __NR_profil\n#define SYS_pselect6 __NR_pselect6\n#define SYS_ptrace __NR_ptrace\n#define SYS_putpmsg __NR_putpmsg\n#define SYS_pwrite64 __NR_pwrite64\n#define SYS_pwritev __NR_pwritev\n#define SYS_query_module __NR_query_module\n#define SYS_quotactl __NR_quotactl\n#define SYS_read __NR_read\n#define SYS_readahead __NR_readahead\n#define SYS_readdir __NR_readdir\n#define SYS_readlink __NR_readlink\n#define SYS_readlinkat __NR_readlinkat\n#define SYS_readv __NR_readv\n#define SYS_reboot __NR_reboot\n#define SYS_recvfrom __NR_recvfrom\n#define SYS_recvmmsg __NR_recvmmsg\n#define SYS_recvmsg __NR_recvmsg\n#define SYS_remap_file_pages __NR_remap_file_pages\n#define SYS_removexattr __NR_removexattr\n#define SYS_rename __NR_rename\n#define SYS_renameat __NR_renameat\n#define SYS_renameat2 __NR_renameat2\n#define SYS_request_key __NR_request_key\n#define SYS_restart_syscall __NR_restart_syscall\n#define SYS_rmdir __NR_rmdir\n#define SYS_rt_sigaction __NR_rt_sigaction\n#define SYS_rt_sigpending __NR_rt_sigpending\n#define SYS_rt_sigprocmask __NR_rt_sigprocmask\n#define SYS_rt_sigqueueinfo __NR_rt_sigqueueinfo\n#define SYS_rt_sigreturn __NR_rt_sigreturn\n#define SYS_rt_sigsuspend __NR_rt_sigsuspend\n#define SYS_rt_sigtimedwait __NR_rt_sigtimedwait\n#define SYS_rt_tgsigqueueinfo __NR_rt_tgsigqueueinfo\n#define SYS_sched_get_priority_max __NR_sched_get_priority_max\n#define SYS_sched_get_priority_min __NR_sched_get_priority_min\n#define SYS_sched_getaffinity __NR_sched_getaffinity\n#define SYS_sched_getattr __NR_sched_getattr\n#define SYS_sched_getparam __NR_sched_getparam\n#define SYS_sched_getscheduler __NR_sched_getscheduler\n#define SYS_sched_rr_get_interval __NR_sched_rr_get_interval\n#define SYS_sched_setaffinity __NR_sched_setaffinity\n#define SYS_sched_setattr __NR_sched_setattr\n#define SYS_sched_setparam __NR_sched_setparam\n#define SYS_sched_setscheduler __NR_sched_setscheduler\n#define SYS_sched_yield __NR_sched_yield\n#define SYS_seccomp __NR_seccomp\n#define SYS_select __NR_select\n#define SYS_sendfile __NR_sendfile\n#define SYS_sendfile64 __NR_sendfile64\n#define SYS_sendmmsg __NR_sendmmsg\n#define SYS_sendmsg __NR_sendmsg\n#define SYS_sendto __NR_sendto\n#define SYS_set_mempolicy __NR_set_mempolicy\n#define SYS_set_robust_list __NR_set_robust_list\n#define SYS_set_thread_area __NR_set_thread_area\n#define SYS_set_tid_address __NR_set_tid_address\n#define SYS_setdomainname __NR_setdomainname\n#define SYS_setfsgid __NR_setfsgid\n#define SYS_setfsgid32 __NR_setfsgid32\n#define SYS_setfsuid __NR_setfsuid\n#define SYS_setfsuid32 __NR_setfsuid32\n#define SYS_setgid __NR_setgid\n#define SYS_setgid32 __NR_setgid32\n#define SYS_setgroups __NR_setgroups\n#define SYS_setgroups32 __NR_setgroups32\n#define SYS_sethostname __NR_sethostname\n#define SYS_setitimer __NR_setitimer\n#define SYS_setns __NR_setns\n#define SYS_setpgid __NR_setpgid\n#define SYS_setpriority __NR_setpriority\n#define SYS_setregid __NR_setregid\n#define SYS_setregid32 __NR_setregid32\n#define SYS_setresgid __NR_setresgid\n#define SYS_setresgid32 __NR_setresgid32\n#define SYS_setresuid __NR_setresuid\n#define SYS_setresuid32 __NR_setresuid32\n#define SYS_setreuid __NR_setreuid\n#define SYS_setreuid32 __NR_setreuid32\n#define SYS_setrlimit __NR_setrlimit\n#define SYS_setsid __NR_setsid\n#define SYS_setsockopt __NR_setsockopt\n#define SYS_settimeofday __NR_settimeofday\n#define SYS_setuid __NR_setuid\n#define SYS_setuid32 __NR_setuid32\n#define SYS_setxattr __NR_setxattr\n#define SYS_sgetmask __NR_sgetmask\n#define SYS_shutdown __NR_shutdown\n#define SYS_sigaction __NR_sigaction\n#define SYS_sigaltstack __NR_sigaltstack\n#define SYS_signal __NR_signal\n#define SYS_signalfd __NR_signalfd\n#define SYS_signalfd4 __NR_signalfd4\n#define SYS_sigpending __NR_sigpending\n#define SYS_sigprocmask __NR_sigprocmask\n#define SYS_sigreturn __NR_sigreturn\n#define SYS_sigsuspend __NR_sigsuspend\n#define SYS_socket __NR_socket\n#define SYS_socketcall __NR_socketcall\n#define SYS_socketpair __NR_socketpair\n#define SYS_splice __NR_splice\n#define SYS_ssetmask __NR_ssetmask\n#define SYS_stat __NR_stat\n#define SYS_stat64 __NR_stat64\n#define SYS_statfs __NR_statfs\n#define SYS_statfs64 __NR_statfs64\n#define SYS_stime __NR_stime\n#define SYS_stty __NR_stty\n#define SYS_swapoff __NR_swapoff\n#define SYS_swapon __NR_swapon\n#define SYS_symlink __NR_symlink\n#define SYS_symlinkat __NR_symlinkat\n#define SYS_sync __NR_sync\n#define SYS_sync_file_range __NR_sync_file_range\n#define SYS_syncfs __NR_syncfs\n#define SYS_sysfs __NR_sysfs\n#define SYS_sysinfo __NR_sysinfo\n#define SYS_syslog __NR_syslog\n#define SYS_tee __NR_tee\n#define SYS_tgkill __NR_tgkill\n#define SYS_time __NR_time\n#define SYS_timer_create __NR_timer_create\n#define SYS_timer_delete __NR_timer_delete\n#define SYS_timer_getoverrun __NR_timer_getoverrun\n#define SYS_timer_gettime __NR_timer_gettime\n#define SYS_timer_settime __NR_timer_settime\n#define SYS_timerfd_create __NR_timerfd_create\n#define SYS_timerfd_gettime __NR_timerfd_gettime\n#define SYS_timerfd_settime __NR_timerfd_settime\n#define SYS_times __NR_times\n#define SYS_tkill __NR_tkill\n#define SYS_truncate __NR_truncate\n#define SYS_truncate64 __NR_truncate64\n#define SYS_ugetrlimit __NR_ugetrlimit\n#define SYS_ulimit __NR_ulimit\n#define SYS_umask __NR_umask\n#define SYS_umount __NR_umount\n#define SYS_umount2 __NR_umount2\n#define SYS_uname __NR_uname\n#define SYS_unlink __NR_unlink\n#define SYS_unlinkat __NR_unlinkat\n#define SYS_unshare __NR_unshare\n#define SYS_uselib __NR_uselib\n#define SYS_userfaultfd __NR_userfaultfd\n#define SYS_ustat __NR_ustat\n#define SYS_utime __NR_utime\n#define SYS_utimensat __NR_utimensat\n#define SYS_utimes __NR_utimes\n#define SYS_vfork __NR_vfork\n#define SYS_vhangup __NR_vhangup\n#define SYS_vm86 __NR_vm86\n#define SYS_vm86old __NR_vm86old\n#define SYS_vmsplice __NR_vmsplice\n#define SYS_vserver __NR_vserver\n#define SYS_wait4 __NR_wait4\n#define SYS_waitid __NR_waitid\n#define SYS_waitpid __NR_waitpid\n#define SYS_write __NR_write\n#define SYS_writev __NR_writev\n#elif defined(__x86_64__)\n#define SYS_accept __NR_accept\n#define SYS_accept4 __NR_accept4\n#define SYS_access __NR_access\n#define SYS_acct __NR_acct\n#define SYS_add_key __NR_add_key\n#define SYS_adjtimex __NR_adjtimex\n#define SYS_afs_syscall __NR_afs_syscall\n#define SYS_alarm __NR_alarm\n#define SYS_arch_prctl __NR_arch_prctl\n#define SYS_bind __NR_bind\n#define SYS_bpf __NR_bpf\n#define SYS_brk __NR_brk\n#define SYS_capget __NR_capget\n#define SYS_capset __NR_capset\n#define SYS_chdir __NR_chdir\n#define SYS_chmod __NR_chmod\n#define SYS_chown __NR_chown\n#define SYS_chroot __NR_chroot\n#define SYS_clock_adjtime __NR_clock_adjtime\n#define SYS_clock_getres __NR_clock_getres\n#define SYS_clock_gettime __NR_clock_gettime\n#define SYS_clock_nanosleep __NR_clock_nanosleep\n#define SYS_clock_settime __NR_clock_settime\n#define SYS_clone __NR_clone\n#define SYS_close __NR_close\n#define SYS_connect __NR_connect\n#define SYS_creat __NR_creat\n#define SYS_create_module __NR_create_module\n#define SYS_delete_module __NR_delete_module\n#define SYS_dup __NR_dup\n#define SYS_dup2 __NR_dup2\n#define SYS_dup3 __NR_dup3\n#define SYS_epoll_create __NR_epoll_create\n#define SYS_epoll_create1 __NR_epoll_create1\n#define SYS_epoll_ctl __NR_epoll_ctl\n#define SYS_epoll_ctl_old __NR_epoll_ctl_old\n#define SYS_epoll_pwait __NR_epoll_pwait\n#define SYS_epoll_wait __NR_epoll_wait\n#define SYS_epoll_wait_old __NR_epoll_wait_old\n#define SYS_eventfd __NR_eventfd\n#define SYS_eventfd2 __NR_eventfd2\n#define SYS_execve __NR_execve\n#define SYS_execveat __NR_execveat\n#define SYS_exit __NR_exit\n#define SYS_exit_group __NR_exit_group\n#define SYS_faccessat __NR_faccessat\n#define SYS_fadvise64 __NR_fadvise64\n#define SYS_fallocate __NR_fallocate\n#define SYS_fanotify_init __NR_fanotify_init\n#define SYS_fanotify_mark __NR_fanotify_mark\n#define SYS_fchdir __NR_fchdir\n#define SYS_fchmod __NR_fchmod\n#define SYS_fchmodat __NR_fchmodat\n#define SYS_fchown __NR_fchown\n#define SYS_fchownat __NR_fchownat\n#define SYS_fcntl __NR_fcntl\n#define SYS_fdatasync __NR_fdatasync\n#define SYS_fgetxattr __NR_fgetxattr\n#define SYS_finit_module __NR_finit_module\n#define SYS_flistxattr __NR_flistxattr\n#define SYS_flock __NR_flock\n#define SYS_fork __NR_fork\n#define SYS_fremovexattr __NR_fremovexattr\n#define SYS_fsetxattr __NR_fsetxattr\n#define SYS_fstat __NR_fstat\n#define SYS_fstatfs __NR_fstatfs\n#define SYS_fsync __NR_fsync\n#define SYS_ftruncate __NR_ftruncate\n#define SYS_futex __NR_futex\n#define SYS_futimesat __NR_futimesat\n#define SYS_get_kernel_syms __NR_get_kernel_syms\n#define SYS_get_mempolicy __NR_get_mempolicy\n#define SYS_get_robust_list __NR_get_robust_list\n#define SYS_get_thread_area __NR_get_thread_area\n#define SYS_getcpu __NR_getcpu\n#define SYS_getcwd __NR_getcwd\n#define SYS_getdents __NR_getdents\n#define SYS_getdents64 __NR_getdents64\n#define SYS_getegid __NR_getegid\n#define SYS_geteuid __NR_geteuid\n#define SYS_getgid __NR_getgid\n#define SYS_getgroups __NR_getgroups\n#define SYS_getitimer __NR_getitimer\n#define SYS_getpeername __NR_getpeername\n#define SYS_getpgid __NR_getpgid\n#define SYS_getpgrp __NR_getpgrp\n#define SYS_getpid __NR_getpid\n#define SYS_getpmsg __NR_getpmsg\n#define SYS_getppid __NR_getppid\n#define SYS_getpriority __NR_getpriority\n#define SYS_getrandom __NR_getrandom\n#define SYS_getresgid __NR_getresgid\n#define SYS_getresuid __NR_getresuid\n#define SYS_getrlimit __NR_getrlimit\n#define SYS_getrusage __NR_getrusage\n#define SYS_getsid __NR_getsid\n#define SYS_getsockname __NR_getsockname\n#define SYS_getsockopt __NR_getsockopt\n#define SYS_gettid __NR_gettid\n#define SYS_gettimeofday __NR_gettimeofday\n#define SYS_getuid __NR_getuid\n#define SYS_getxattr __NR_getxattr\n#define SYS_init_module __NR_init_module\n#define SYS_inotify_add_watch __NR_inotify_add_watch\n#define SYS_inotify_init __NR_inotify_init\n#define SYS_inotify_init1 __NR_inotify_init1\n#define SYS_inotify_rm_watch __NR_inotify_rm_watch\n#define SYS_io_cancel __NR_io_cancel\n#define SYS_io_destroy __NR_io_destroy\n#define SYS_io_getevents __NR_io_getevents\n#define SYS_io_setup __NR_io_setup\n#define SYS_io_submit __NR_io_submit\n#define SYS_ioctl __NR_ioctl\n#define SYS_ioperm __NR_ioperm\n#define SYS_iopl __NR_iopl\n#define SYS_ioprio_get __NR_ioprio_get\n#define SYS_ioprio_set __NR_ioprio_set\n#define SYS_kcmp __NR_kcmp\n#define SYS_kexec_file_load __NR_kexec_file_load\n#define SYS_kexec_load __NR_kexec_load\n#define SYS_keyctl __NR_keyctl\n#define SYS_kill __NR_kill\n#define SYS_lchown __NR_lchown\n#define SYS_lgetxattr __NR_lgetxattr\n#define SYS_link __NR_link\n#define SYS_linkat __NR_linkat\n#define SYS_listen __NR_listen\n#define SYS_listxattr __NR_listxattr\n#define SYS_llistxattr __NR_llistxattr\n#define SYS_lookup_dcookie __NR_lookup_dcookie\n#define SYS_lremovexattr __NR_lremovexattr\n#define SYS_lseek __NR_lseek\n#define SYS_lsetxattr __NR_lsetxattr\n#define SYS_lstat __NR_lstat\n#define SYS_madvise __NR_madvise\n#define SYS_mbind __NR_mbind\n#define SYS_membarrier __NR_membarrier\n#define SYS_memfd_create __NR_memfd_create\n#define SYS_migrate_pages __NR_migrate_pages\n#define SYS_mincore __NR_mincore\n#define SYS_mkdir __NR_mkdir\n#define SYS_mkdirat __NR_mkdirat\n#define SYS_mknod __NR_mknod\n#define SYS_mknodat __NR_mknodat\n#define SYS_mlock __NR_mlock\n#define SYS_mlock2 __NR_mlock2\n#define SYS_mlockall __NR_mlockall\n#define SYS_mmap __NR_mmap\n#define SYS_modify_ldt __NR_modify_ldt\n#define SYS_mount __NR_mount\n#define SYS_move_pages __NR_move_pages\n#define SYS_mprotect __NR_mprotect\n#define SYS_mq_getsetattr __NR_mq_getsetattr\n#define SYS_mq_notify __NR_mq_notify\n#define SYS_mq_open __NR_mq_open\n#define SYS_mq_timedreceive __NR_mq_timedreceive\n#define SYS_mq_timedsend __NR_mq_timedsend\n#define SYS_mq_unlink __NR_mq_unlink\n#define SYS_mremap __NR_mremap\n#define SYS_msgctl __NR_msgctl\n#define SYS_msgget __NR_msgget\n#define SYS_msgrcv __NR_msgrcv\n#define SYS_msgsnd __NR_msgsnd\n#define SYS_msync __NR_msync\n#define SYS_munlock __NR_munlock\n#define SYS_munlockall __NR_munlockall\n#define SYS_munmap __NR_munmap\n#define SYS_name_to_handle_at __NR_name_to_handle_at\n#define SYS_nanosleep __NR_nanosleep\n#define SYS_newfstatat __NR_newfstatat\n#define SYS_nfsservctl __NR_nfsservctl\n#define SYS_open __NR_open\n#define SYS_open_by_handle_at __NR_open_by_handle_at\n#define SYS_openat __NR_openat\n#define SYS_pause __NR_pause\n#define SYS_perf_event_open __NR_perf_event_open\n#define SYS_personality __NR_personality\n#define SYS_pipe __NR_pipe\n#define SYS_pipe2 __NR_pipe2\n#define SYS_pivot_root __NR_pivot_root\n#define SYS_poll __NR_poll\n#define SYS_ppoll __NR_ppoll\n#define SYS_prctl __NR_prctl\n#define SYS_pread64 __NR_pread64\n#define SYS_preadv __NR_preadv\n#define SYS_prlimit64 __NR_prlimit64\n#define SYS_process_vm_readv __NR_process_vm_readv\n#define SYS_process_vm_writev __NR_process_vm_writev\n#define SYS_pselect6 __NR_pselect6\n#define SYS_ptrace __NR_ptrace\n#define SYS_putpmsg __NR_putpmsg\n#define SYS_pwrite64 __NR_pwrite64\n#define SYS_pwritev __NR_pwritev\n#define SYS_query_module __NR_query_module\n#define SYS_quotactl __NR_quotactl\n#define SYS_read __NR_read\n#define SYS_readahead __NR_readahead\n#define SYS_readlink __NR_readlink\n#define SYS_readlinkat __NR_readlinkat\n#define SYS_readv __NR_readv\n#define SYS_reboot __NR_reboot\n#define SYS_recvfrom __NR_recvfrom\n#define SYS_recvmmsg __NR_recvmmsg\n#define SYS_recvmsg __NR_recvmsg\n#define SYS_remap_file_pages __NR_remap_file_pages\n#define SYS_removexattr __NR_removexattr\n#define SYS_rename __NR_rename\n#define SYS_renameat __NR_renameat\n#define SYS_renameat2 __NR_renameat2\n#define SYS_request_key __NR_request_key\n#define SYS_restart_syscall __NR_restart_syscall\n#define SYS_rmdir __NR_rmdir\n#define SYS_rt_sigaction __NR_rt_sigaction\n#define SYS_rt_sigpending __NR_rt_sigpending\n#define SYS_rt_sigprocmask __NR_rt_sigprocmask\n#define SYS_rt_sigqueueinfo __NR_rt_sigqueueinfo\n#define SYS_rt_sigreturn __NR_rt_sigreturn\n#define SYS_rt_sigsuspend __NR_rt_sigsuspend\n#define SYS_rt_sigtimedwait __NR_rt_sigtimedwait\n#define SYS_rt_tgsigqueueinfo __NR_rt_tgsigqueueinfo\n#define SYS_sched_get_priority_max __NR_sched_get_priority_max\n#define SYS_sched_get_priority_min __NR_sched_get_priority_min\n#define SYS_sched_getaffinity __NR_sched_getaffinity\n#define SYS_sched_getattr __NR_sched_getattr\n#define SYS_sched_getparam __NR_sched_getparam\n#define SYS_sched_getscheduler __NR_sched_getscheduler\n#define SYS_sched_rr_get_interval __NR_sched_rr_get_interval\n#define SYS_sched_setaffinity __NR_sched_setaffinity\n#define SYS_sched_setattr __NR_sched_setattr\n#define SYS_sched_setparam __NR_sched_setparam\n#define SYS_sched_setscheduler __NR_sched_setscheduler\n#define SYS_sched_yield __NR_sched_yield\n#define SYS_seccomp __NR_seccomp\n#define SYS_security __NR_security\n#define SYS_select __NR_select\n#define SYS_semctl __NR_semctl\n#define SYS_semget __NR_semget\n#define SYS_semop __NR_semop\n#define SYS_semtimedop __NR_semtimedop\n#define SYS_sendfile __NR_sendfile\n#define SYS_sendmmsg __NR_sendmmsg\n#define SYS_sendmsg __NR_sendmsg\n#define SYS_sendto __NR_sendto\n#define SYS_set_mempolicy __NR_set_mempolicy\n#define SYS_set_robust_list __NR_set_robust_list\n#define SYS_set_thread_area __NR_set_thread_area\n#define SYS_set_tid_address __NR_set_tid_address\n#define SYS_setdomainname __NR_setdomainname\n#define SYS_setfsgid __NR_setfsgid\n#define SYS_setfsuid __NR_setfsuid\n#define SYS_setgid __NR_setgid\n#define SYS_setgroups __NR_setgroups\n#define SYS_sethostname __NR_sethostname\n#define SYS_setitimer __NR_setitimer\n#define SYS_setns __NR_setns\n#define SYS_setpgid __NR_setpgid\n#define SYS_setpriority __NR_setpriority\n#define SYS_setregid __NR_setregid\n#define SYS_setresgid __NR_setresgid\n#define SYS_setresuid __NR_setresuid\n#define SYS_setreuid __NR_setreuid\n#define SYS_setrlimit __NR_setrlimit\n#define SYS_setsid __NR_setsid\n#define SYS_setsockopt __NR_setsockopt\n#define SYS_settimeofday __NR_settimeofday\n#define SYS_setuid __NR_setuid\n#define SYS_setxattr __NR_setxattr\n#define SYS_shmat __NR_shmat\n#define SYS_shmctl __NR_shmctl\n#define SYS_shmdt __NR_shmdt\n#define SYS_shmget __NR_shmget\n#define SYS_shutdown __NR_shutdown\n#define SYS_sigaltstack __NR_sigaltstack\n#define SYS_signalfd __NR_signalfd\n#define SYS_signalfd4 __NR_signalfd4\n#define SYS_socket __NR_socket\n#define SYS_socketpair __NR_socketpair\n#define SYS_splice __NR_splice\n#define SYS_stat __NR_stat\n#define SYS_statfs __NR_statfs\n#define SYS_swapoff __NR_swapoff\n#define SYS_swapon __NR_swapon\n#define SYS_symlink __NR_symlink\n#define SYS_symlinkat __NR_symlinkat\n#define SYS_sync __NR_sync\n#define SYS_sync_file_range __NR_sync_file_range\n#define SYS_syncfs __NR_syncfs\n#define SYS_sysfs __NR_sysfs\n#define SYS_sysinfo __NR_sysinfo\n#define SYS_syslog __NR_syslog\n#define SYS_tee __NR_tee\n#define SYS_tgkill __NR_tgkill\n#define SYS_time __NR_time\n#define SYS_timer_create __NR_timer_create\n#define SYS_timer_delete __NR_timer_delete\n#define SYS_timer_getoverrun __NR_timer_getoverrun\n#define SYS_timer_gettime __NR_timer_gettime\n#define SYS_timer_settime __NR_timer_settime\n#define SYS_timerfd_create __NR_timerfd_create\n#define SYS_timerfd_gettime __NR_timerfd_gettime\n#define SYS_timerfd_settime __NR_timerfd_settime\n#define SYS_times __NR_times\n#define SYS_tkill __NR_tkill\n#define SYS_truncate __NR_truncate\n#define SYS_tuxcall __NR_tuxcall\n#define SYS_umask __NR_umask\n#define SYS_umount2 __NR_umount2\n#define SYS_uname __NR_uname\n#define SYS_unlink __NR_unlink\n#define SYS_unlinkat __NR_unlinkat\n#define SYS_unshare __NR_unshare\n#define SYS_uselib __NR_uselib\n#define SYS_userfaultfd __NR_userfaultfd\n#define SYS_ustat __NR_ustat\n#define SYS_utime __NR_utime\n#define SYS_utimensat __NR_utimensat\n#define SYS_utimes __NR_utimes\n#define SYS_vfork __NR_vfork\n#define SYS_vhangup __NR_vhangup\n#define SYS_vmsplice __NR_vmsplice\n#define SYS_vserver __NR_vserver\n#define SYS_wait4 __NR_wait4\n#define SYS_waitid __NR_waitid\n#define SYS_write __NR_write\n#define SYS_writev __NR_writev\n#endif\n#endif /* _BIONIC_GLIBC_SYSCALLS_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/inotify.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_INOTIFY_H_\n#define _SYS_INOTIFY_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <stdint.h>\n#include <linux/inotify.h>\n#include <asm/fcntl.h> /* For O_CLOEXEC and O_NONBLOCK. */\n\n__BEGIN_DECLS\n\n#define IN_CLOEXEC O_CLOEXEC\n#define IN_NONBLOCK O_NONBLOCK\n\nextern int inotify_init(void);\nextern int inotify_init1(int);\nextern int inotify_add_watch(int, const char*, uint32_t);\nextern int inotify_rm_watch(int, uint32_t);\n\n__END_DECLS\n\n#endif /* _SYS_INOTIFY_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/ioctl.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_IOCTL_H_\n#define _SYS_IOCTL_H_\n\n#include <sys/cdefs.h>\n#include <linux/ioctl.h>\n/*\n * NetBSD and glibc's <sys/ioctl.h> provide some of the\n * terminal-related ioctl data structures such as struct winsize.\n */\n#include <linux/termios.h>\n#include <asm/ioctls.h>\n#include <asm/termbits.h>\n#include <sys/ioctl_compat.h>\n#include <linux/tty.h>\n\n__BEGIN_DECLS\n\nextern int ioctl(int, int, ...);\n\n__END_DECLS\n\n#endif /* _SYS_IOCTL_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/ioctl_compat.h",
    "content": "/*\t$NetBSD: ioctl_compat.h,v 1.15 2005/12/03 17:10:46 christos Exp $\t*/\n\n/*\n * Copyright (c) 1990, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n * (c) UNIX System Laboratories, Inc.\n * All or some portions of this file are derived from material licensed\n * to the University of California by American Telephone and Telegraph\n * Co. or Unix System Laboratories, Inc. and are reproduced herein with\n * the permission of UNIX System Laboratories, Inc.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)ioctl_compat.h\t8.4 (Berkeley) 1/21/94\n */\n\n#ifndef _SYS_IOCTL_COMPAT_H_\n#define\t_SYS_IOCTL_COMPAT_H_\n\n/*#include <sys/ttychars.h>*/\n/*#include <sys/ttydev.h>*/\n\n#if !defined(__mips__)\nstruct tchars {\n\tchar\tt_intrc;\t/* interrupt */\n\tchar\tt_quitc;\t/* quit */\n\tchar\tt_startc;\t/* start output */\n\tchar\tt_stopc;\t/* stop output */\n\tchar\tt_eofc;\t\t/* end-of-file */\n\tchar\tt_brkc;\t\t/* input delimiter (like nl) */\n};\n\nstruct ltchars {\n\tchar\tt_suspc;\t/* stop process signal */\n\tchar\tt_dsuspc;\t/* delayed stop process signal */\n\tchar\tt_rprntc;\t/* reprint line */\n\tchar\tt_flushc;\t/* flush output (toggles) */\n\tchar\tt_werasc;\t/* word erase */\n\tchar\tt_lnextc;\t/* literal next character */\n};\n\n/*\n * Structure for TIOCGETP and TIOCSETP ioctls.\n */\n#ifndef _SGTTYB_\n#define\t_SGTTYB_\nstruct sgttyb {\n\tchar\tsg_ispeed;\t\t/* input speed */\n\tchar\tsg_ospeed;\t\t/* output speed */\n\tchar\tsg_erase;\t\t/* erase character */\n\tchar\tsg_kill;\t\t/* kill character */\n\tshort\tsg_flags;\t\t/* mode flags */\n};\n#endif\n#endif\n\n#ifdef USE_OLD_TTY\n# undef  TIOCGETD\n# define TIOCGETD\t_IOR('t', 0, int)\t/* get line discipline */\n# undef  TIOCSETD\n# define TIOCSETD\t_IOW('t', 1, int)\t/* set line discipline */\n#else\n# define OTIOCGETD\t_IOR('t', 0, int)\t/* get line discipline */\n# define OTIOCSETD\t_IOW('t', 1, int)\t/* set line discipline */\n#endif\n#define\tTIOCHPCL\t_IO('t', 2)\t\t/* hang up on last close */\n#if !defined(__mips__)\n#define\tTIOCGETP\t_IOR('t', 8,struct sgttyb)/* get parameters -- gtty */\n#define\tTIOCSETP\t_IOW('t', 9,struct sgttyb)/* set parameters -- stty */\n#define\tTIOCSETN\t_IOW('t',10,struct sgttyb)/* as above, but no flushtty*/\n#endif\n#define\tTIOCSETC\t_IOW('t',17,struct tchars)/* set special characters */\n#define\tTIOCGETC\t_IOR('t',18,struct tchars)/* get special characters */\n#if 0\n/* BUG: a bunch of these conflict with #defines in asm/termbits.h */\n#define\t\tTANDEM\t\t0x00000001\t/* send stopc on out q full */\n#define\t\tCBREAK\t\t0x00000002\t/* half-cooked mode */\n#define\t\tLCASE\t\t0x00000004\t/* simulate lower case */\n#define\t\tECHO\t\t0x00000008\t/* enable echoing */\n#define\t\tCRMOD\t\t0x00000010\t/* map \\r to \\r\\n on output */\n#define\t\tRAW\t\t0x00000020\t/* no i/o processing */\n#define\t\tODDP\t\t0x00000040\t/* get/send odd parity */\n#define\t\tEVENP\t\t0x00000080\t/* get/send even parity */\n#define\t\tANYP\t\t0x000000c0\t/* get any parity/send none */\n#define\t\tNLDELAY\t\t0x00000300\t/* \\n delay */\n#define\t\t\tNL0\t0x00000000\n#define\t\t\tNL1\t0x00000100\t/* tty 37 */\n#define\t\t\tNL2\t0x00000200\t/* vt05 */\n#define\t\t\tNL3\t0x00000300\n#define\t\tTBDELAY\t\t0x00000c00\t/* horizontal tab delay */\n#define\t\t\tTAB0\t0x00000000\n#define\t\t\tTAB1\t0x00000400\t/* tty 37 */\n#define\t\t\tTAB2\t0x00000800\n#define\t\tXTABS\t\t0x00000c00\t/* expand tabs on output */\n#define\t\tCRDELAY\t\t0x00003000\t/* \\r delay */\n#define\t\t\tCR0\t0x00000000\n#define\t\t\tCR1\t0x00001000\t/* tn 300 */\n#define\t\t\tCR2\t0x00002000\t/* tty 37 */\n#define\t\t\tCR3\t0x00003000\t/* concept 100 */\n#define\t\tVTDELAY\t\t0x00004000\t/* vertical tab delay */\n#define\t\t\tFF0\t0x00000000\n#define\t\t\tFF1\t0x00004000\t/* tty 37 */\n#define\t\tBSDELAY\t\t0x00008000\t/* \\b delay */\n#define\t\t\tBS0\t0x00000000\n#define\t\t\tBS1\t0x00008000\n#define\t\tALLDELAY\t(NLDELAY|TBDELAY|CRDELAY|VTDELAY|BSDELAY)\n#define\t\tCRTBS\t\t0x00010000\t/* do backspacing for crt */\n#define\t\tPRTERA\t\t0x00020000\t/* \\ ... / erase */\n#define\t\tCRTERA\t\t0x00040000\t/* \" \\b \" to wipe out char */\n#define\t\tTILDE\t\t0x00080000\t/* hazeltine tilde kludge */\n#define\t\tMDMBUF\t\t0x00100000\t/* DTR/DCD hardware flow control */\n#define\t\tLITOUT\t\t0x00200000\t/* literal output */\n#define\t\tTOSTOP\t\t0x00400000\t/* stop background jobs on output */\n#define\t\tFLUSHO\t\t0x00800000\t/* output being flushed (state) */\n#define\t\tNOHANG\t\t0x01000000\t/* (no-op) was no SIGHUP on carrier drop */\n#define\t\tL001000\t\t0x02000000\n#define\t\tCRTKIL\t\t0x04000000\t/* kill line with \" \\b \" */\n#define\t\tPASS8\t\t0x08000000\n#define\t\tCTLECH\t\t0x10000000\t/* echo control chars as ^X */\n#define\t\tPENDIN\t\t0x20000000\t/* re-echo input buffer at next read */\n#define\t\tDECCTQ\t\t0x40000000\t/* only ^Q starts after ^S */\n#define\t\tNOFLSH\t\t0x80000000\t/* don't flush output on signal */\n#endif\n#define\tTIOCLBIS\t_IOW('t', 127, int)\t/* bis local mode bits */\n#define\tTIOCLBIC\t_IOW('t', 126, int)\t/* bic local mode bits */\n#define\tTIOCLSET\t_IOW('t', 125, int)\t/* set entire local mode word */\n#define\tTIOCLGET\t_IOR('t', 124, int)\t/* get local modes */\n#define\t\tLCRTBS\t\t(CRTBS>>16)\n#define\t\tLPRTERA\t\t(PRTERA>>16)\n#define\t\tLCRTERA\t\t(CRTERA>>16)\n#define\t\tLTILDE\t\t(TILDE>>16)\n#define\t\tLMDMBUF\t\t(MDMBUF>>16)\n#define\t\tLLITOUT\t\t(LITOUT>>16)\n#define\t\tLTOSTOP\t\t(TOSTOP>>16)\n#define\t\tLFLUSHO\t\t(FLUSHO>>16)\n#define\t\tLNOHANG\t\t(NOHANG>>16)\n#define\t\tLCRTKIL\t\t(CRTKIL>>16)\n#define\t\tLPASS8\t\t(PASS8>>16)\n#define\t\tLCTLECH\t\t(CTLECH>>16)\n#define\t\tLPENDIN\t\t(PENDIN>>16)\n#define\t\tLDECCTQ\t\t(DECCTQ>>16)\n#define\t\tLNOFLSH\t\t(NOFLSH>>16)\n#if !defined(__mips__)\n#define\tTIOCSLTC\t_IOW('t',117,struct ltchars)/* set local special chars*/\n#define\tTIOCGLTC\t_IOR('t',116,struct ltchars)/* get local special chars*/\n#endif\n#define OTIOCCONS\t_IO('t', 98)\t/* for hp300 -- sans int arg */\n#define\tOTTYDISC\t0\n#define\tNETLDISC\t1\n#define\tNTTYDISC\t2\n\n#endif /* !_SYS_IOCTL_COMPAT_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/ipc.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_IPC_H\n#define _SYS_IPC_H\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <linux/ipc.h>\n\n__BEGIN_DECLS\n\nextern key_t  ftok(const char*  path, int  id);\n\n__END_DECLS\n\n#endif /* _SYS_IPC_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/klog.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_KLOG_H_\n#define _SYS_KLOG_H_\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\n/* These correspond to the kernel's SYSLOG_ACTION_whatever constants. */\n#define KLOG_CLOSE         0\n#define KLOG_OPEN          1\n#define KLOG_READ          2\n#define KLOG_READ_ALL      3\n#define KLOG_READ_CLEAR    4\n#define KLOG_CLEAR         5\n#define KLOG_CONSOLE_OFF   6\n#define KLOG_CONSOLE_ON    7\n#define KLOG_CONSOLE_LEVEL 8\n#define KLOG_SIZE_UNREAD   9\n#define KLOG_SIZE_BUFFER   10\n\nextern int klogctl(int, char *, int);\n\n__END_DECLS\n\n#endif /* _SYS_KLOG_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/limits.h",
    "content": "/* $OpenBSD: limits.h,v 1.6 2005/12/13 00:35:23 millert Exp $ */\n/*\n * Copyright (c) 2002 Marc Espie.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS\n * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OPENBSD\n * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#ifndef _SYS_LIMITS_H_\n#define _SYS_LIMITS_H_\n\n#include <sys/cdefs.h>\n#include <linux/limits.h>\n\n/* Common definitions for limits.h. */\n\n#define\tCHAR_BIT\t8\t\t/* number of bits in a char */\n\n#define\tSCHAR_MAX\t0x7f\t\t/* max value for a signed char */\n#define SCHAR_MIN\t(-0x7f-1)\t/* min value for a signed char */\n\n#define\tUCHAR_MAX\t0xffU\t\t/* max value for an unsigned char */\n#ifdef __CHAR_UNSIGNED__\n# define CHAR_MIN\t0\t\t/* min value for a char */\n# define CHAR_MAX\t0xff\t\t/* max value for a char */\n#else\n# define CHAR_MAX\t0x7f\n# define CHAR_MIN\t(-0x7f-1)\n#endif\n\n#define\tUSHRT_MAX\t0xffffU\t\t/* max value for an unsigned short */\n#define\tSHRT_MAX\t0x7fff\t\t/* max value for a short */\n#define SHRT_MIN        (-0x7fff-1)     /* min value for a short */\n\n#define\tUINT_MAX\t0xffffffffU\t/* max value for an unsigned int */\n#define\tINT_MAX\t\t0x7fffffff\t/* max value for an int */\n#define\tINT_MIN\t\t(-0x7fffffff-1)\t/* min value for an int */\n\n#ifdef __LP64__\n# define ULONG_MAX\t0xffffffffffffffffUL\n\t\t\t\t\t/* max value for unsigned long */\n# define LONG_MAX\t0x7fffffffffffffffL\n\t\t\t\t\t/* max value for a signed long */\n# define LONG_MIN\t(-0x7fffffffffffffffL-1)\n\t\t\t\t\t/* min value for a signed long */\n#else\n# define ULONG_MAX\t0xffffffffUL\t/* max value for an unsigned long */\n# define LONG_MAX\t0x7fffffffL\t/* max value for a long */\n# define LONG_MIN\t(-0x7fffffffL-1)/* min value for a long */\n#endif\n\n#if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999\n# define ULLONG_MAX\t0xffffffffffffffffULL\n\t\t\t\t\t/* max value for unsigned long long */\n# define LLONG_MAX\t0x7fffffffffffffffLL\n\t\t\t\t\t/* max value for a signed long long */\n# define LLONG_MIN\t(-0x7fffffffffffffffLL-1)\n\t\t\t\t\t/* min value for a signed long long */\n#endif\n\n#if __BSD_VISIBLE\n# define UID_MAX\tUINT_MAX\t/* max value for a uid_t */\n# define GID_MAX\tUINT_MAX\t/* max value for a gid_t */\n#endif\n\n\n#ifdef __LP64__\n# define LONG_BIT\t64\n#else\n# define LONG_BIT\t32\n#endif\n\n/* float.h defines these as well */\n# if !defined(DBL_DIG)\n#  if defined(__DBL_DIG)\n#   define DBL_DIG\t__DBL_DIG\n#   define DBL_MAX\t__DBL_MAX\n#   define DBL_MIN\t__DBL_MIN\n\n#   define FLT_DIG\t__FLT_DIG\n#   define FLT_MAX\t__FLT_MAX\n#   define FLT_MIN\t__FLT_MIN\n#  else\n#   define DBL_DIG\t15\n#   define DBL_MAX\t1.7976931348623157E+308\n#   define DBL_MIN\t2.2250738585072014E-308\n\n#   define FLT_DIG\t6\n#   define FLT_MAX\t3.40282347E+38F\n#   define FLT_MIN\t1.17549435E-38F\n#  endif\n# endif\n\n/* Bionic: the following has been optimized out from our processed kernel headers */\n\n#define  CHILD_MAX   999\n#define  OPEN_MAX    256\n\n/* Bionic-specific definitions */\n\n#define  _POSIX_VERSION             200809L   /* Posix C language bindings version */\n#define  _POSIX2_VERSION            -1        /* we don't support Posix command-line tools */\n#define  _XOPEN_VERSION             700       /* by Posix definition */\n\n\n#define PTHREAD_DESTRUCTOR_ITERATIONS 4     // >= _POSIX_THREAD_DESTRUCTOR_ITERATIONS\n#define PTHREAD_KEYS_MAX              128   // >= _POSIX_THREAD_KEYS_MAX\n#define PTHREAD_THREADS_MAX           2048  // bionic has no specific limit\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/mman.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_MMAN_H_\n#define _SYS_MMAN_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <asm/mman.h>\n\n__BEGIN_DECLS\n\n#ifndef MAP_ANON\n#define MAP_ANON  MAP_ANONYMOUS\n#endif\n\n#define MAP_FAILED ((void *)-1)\n\n#define MREMAP_MAYMOVE  1\n#define MREMAP_FIXED    2\n\n#define POSIX_MADV_NORMAL     MADV_NORMAL\n#define POSIX_MADV_RANDOM     MADV_RANDOM\n#define POSIX_MADV_SEQUENTIAL MADV_SEQUENTIAL\n#define POSIX_MADV_WILLNEED   MADV_WILLNEED\n#define POSIX_MADV_DONTNEED   MADV_DONTNEED\n\n#if defined(__USE_FILE_OFFSET64)\nextern void* mmap(void*, size_t, int, int, int, off_t) __RENAME(mmap64);\n#else\nextern void* mmap(void*, size_t, int, int, int, off_t);\n#endif\nextern void* mmap64(void*, size_t, int, int, int, off64_t);\n\nextern int munmap(void*, size_t);\nextern int msync(const void*, size_t, int);\nextern int mprotect(const void*, size_t, int);\nextern void* mremap(void*, size_t, size_t, int, ...);\n\nextern int mlockall(int);\nextern int munlockall(void);\nextern int mlock(const void*, size_t);\nextern int munlock(const void*, size_t);\nextern int madvise(void*, size_t, int);\n\nextern int mlock(const void*, size_t);\nextern int munlock(const void*, size_t);\n\nextern int mincore(void*, size_t, unsigned char*);\n\nextern int posix_madvise(void*, size_t, int);\n\n__END_DECLS\n\n#endif /* _SYS_MMAN_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/mount.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_MOUNT_H\n#define _SYS_MOUNT_H\n\n#include <sys/cdefs.h>\n#include <sys/ioctl.h>\n#include <linux/fs.h>\n\n__BEGIN_DECLS\n\n/* umount2 flags. */\n#define MNT_FORCE 1\n#define MNT_DETACH 2\n#define MNT_EXPIRE 4\n#define UMOUNT_NOFOLLOW 8\n\nextern int mount(const char*, const char*, const char*, unsigned long, const void*);\nextern int umount(const char*);\nextern int umount2(const char*, int);\n\n__END_DECLS\n\n#endif /* _SYS_MOUNT_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/msg.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_MSG_H_\n#define _SYS_MSG_H_\n\n#include <linux/msg.h>\n\n#endif /* _SYS_MSG_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/param.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_PARAM_H_\n#define _SYS_PARAM_H_\n\n#include <limits.h>\n#include <linux/param.h>\n\n#define MAXPATHLEN  PATH_MAX\n#define MAXSYMLINKS 8\n\n/* Macros for counting and rounding. */\n#ifndef howmany\n#define howmany(x, y)   (((x)+((y)-1))/(y))\n#endif\n#define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))\n#define powerof2(x)     ((((x)-1)&(x))==0)\n\n/* Macros for min/max. */\n#define MIN(a,b) (((a)<(b))?(a):(b))\n#define MAX(a,b) (((a)>(b))?(a):(b))\n\n#endif /* _SYS_PARAM_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/personality.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_PERSONALITY_H_\n#define _SYS_PERSONALITY_H_\n\n#include <sys/cdefs.h>\n#include <linux/personality.h>\n\n__BEGIN_DECLS\n\nextern int personality (unsigned int persona);\n\n__END_DECLS\n\n#endif /* _SYS_PERSONALITY_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/poll.h",
    "content": "#include <poll.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/prctl.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_PRCTL_H\n#define _SYS_PRCTL_H\n\n#include <sys/cdefs.h>\n\n#include <linux/prctl.h>\n\n__BEGIN_DECLS\n\nextern int prctl(int option, ...);\n\n__END_DECLS\n\n#endif /* _SYS_PRCTL_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/procfs.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_PROCFS_H_\n#define _SYS_PROCFS_H_\n\n#include <sys/cdefs.h>\n#include <sys/ucontext.h>\n\n__BEGIN_DECLS\n\ntypedef unsigned long elf_greg_t;\ntypedef elf_greg_t elf_gregset_t[NGREG];\n\ntypedef fpregset_t elf_fpregset_t;\n\n#if defined(__i386__)\ntypedef struct user_fpxregs_struct elf_fpxregset_t;\n#endif\n\ntypedef elf_gregset_t prgregset_t;\ntypedef elf_fpregset_t prfpregset_t;\n\ntypedef pid_t lwpid_t;\ntypedef void* psaddr_t;\n\n__END_DECLS\n\n#endif /* _SYS_PROCFS_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/ptrace.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_PTRACE_H_\n#define _SYS_PTRACE_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <linux/ptrace.h>\n\n__BEGIN_DECLS\n\n/* glibc uses different PTRACE_ names from the kernel for these two... */\n#define PTRACE_POKEUSER PTRACE_POKEUSR\n#define PTRACE_PEEKUSER PTRACE_PEEKUSR\n\n/* glibc exports a different set of PT_ names too... */\n#define PT_TRACE_ME PTRACE_TRACEME\n#define PT_READ_I PTRACE_PEEKTEXT\n#define PT_READ_D PTRACE_PEEKDATA\n#define PT_READ_U PTRACE_PEEKUSR\n#define PT_WRITE_I PTRACE_POKETEXT\n#define PT_WRITE_D PTRACE_POKEDATA\n#define PT_WRITE_U PTRACE_POKEUSR\n#define PT_CONT PTRACE_CONT\n#define PT_KILL PTRACE_KILL\n#define PT_STEP PTRACE_SINGLESTEP\n#define PT_GETFPREGS PTRACE_GETFPREGS\n#define PT_ATTACH PTRACE_ATTACH\n#define PT_DETACH PTRACE_DETACH\n#define PT_SYSCALL PTRACE_SYSCALL\n#define PT_SETOPTIONS PTRACE_SETOPTIONS\n#define PT_GETEVENTMSG PTRACE_GETEVENTMSG\n#define PT_GETSIGINFO PTRACE_GETSIGINFO\n#define PT_SETSIGINFO PTRACE_SETSIGINFO\n\nlong ptrace(int, ...);\n\n__END_DECLS\n\n#endif /* _SYS_PTRACE_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/queue.h",
    "content": "/*\n * Copyright (c) 1991, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)queue.h\t8.5 (Berkeley) 8/20/94\n */\n\n#ifndef\t_SYS_QUEUE_H_\n#define\t_SYS_QUEUE_H_\n\n/*\n * This file defines five types of data structures: singly-linked lists,\n * lists, simple queues, tail queues, and circular queues.\n *\n * A singly-linked list is headed by a single forward pointer. The\n * elements are singly linked for minimum space and pointer manipulation\n * overhead at the expense of O(n) removal for arbitrary elements. New\n * elements can be added to the list after an existing element or at the\n * head of the list.  Elements being removed from the head of the list\n * should use the explicit macro for this purpose for optimum\n * efficiency. A singly-linked list may only be traversed in the forward\n * direction.  Singly-linked lists are ideal for applications with large\n * datasets and few or no removals or for implementing a LIFO queue.\n *\n * A list is headed by a single forward pointer (or an array of forward\n * pointers for a hash table header). The elements are doubly linked\n * so that an arbitrary element can be removed without a need to\n * traverse the list. New elements can be added to the list before\n * or after an existing element or at the head of the list. A list\n * may only be traversed in the forward direction.\n *\n * A simple queue is headed by a pair of pointers, one the head of the\n * list and the other to the tail of the list. The elements are singly\n * linked to save space, so elements can only be removed from the\n * head of the list. New elements can be added to the list after\n * an existing element, at the head of the list, or at the end of the\n * list. A simple queue may only be traversed in the forward direction.\n *\n * A tail queue is headed by a pair of pointers, one to the head of the\n * list and the other to the tail of the list. The elements are doubly\n * linked so that an arbitrary element can be removed without a need to\n * traverse the list. New elements can be added to the list before or\n * after an existing element, at the head of the list, or at the end of\n * the list. A tail queue may be traversed in either direction.\n *\n * A circle queue is headed by a pair of pointers, one to the head of the\n * list and the other to the tail of the list. The elements are doubly\n * linked so that an arbitrary element can be removed without a need to\n * traverse the list. New elements can be added to the list before or after\n * an existing element, at the head of the list, or at the end of the list.\n * A circle queue may be traversed in either direction, but has a more\n * complex end of list detection.\n *\n * For details on the use of these macros, see the queue(3) manual page.\n */\n\n/*\n * List definitions.\n */\n#define\tLIST_HEAD(name, type)\t\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tstruct type *lh_first;\t/* first element */\t\t\t\\\n}\n\n#define\tLIST_HEAD_INITIALIZER(head)\t\t\t\t\t\\\n\t{ NULL }\n\n#define\tLIST_ENTRY(type)\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tstruct type *le_next;\t/* next element */\t\t\t\\\n\tstruct type **le_prev;\t/* address of previous next element */\t\\\n}\n\n/*\n * List functions.\n */\n#define\tLIST_INIT(head) do {\t\t\t\t\t\t\\\n\t(head)->lh_first = NULL;\t\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tLIST_INSERT_AFTER(listelm, elm, field) do {\t\t\t\\\n\tif (((elm)->field.le_next = (listelm)->field.le_next) != NULL)\t\\\n\t\t(listelm)->field.le_next->field.le_prev =\t\t\\\n\t\t    &(elm)->field.le_next;\t\t\t\t\\\n\t(listelm)->field.le_next = (elm);\t\t\t\t\\\n\t(elm)->field.le_prev = &(listelm)->field.le_next;\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tLIST_INSERT_BEFORE(listelm, elm, field) do {\t\t\t\\\n\t(elm)->field.le_prev = (listelm)->field.le_prev;\t\t\\\n\t(elm)->field.le_next = (listelm);\t\t\t\t\\\n\t*(listelm)->field.le_prev = (elm);\t\t\t\t\\\n\t(listelm)->field.le_prev = &(elm)->field.le_next;\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tLIST_INSERT_HEAD(head, elm, field) do {\t\t\t\t\\\n\tif (((elm)->field.le_next = (head)->lh_first) != NULL)\t\t\\\n\t\t(head)->lh_first->field.le_prev = &(elm)->field.le_next;\\\n\t(head)->lh_first = (elm);\t\t\t\t\t\\\n\t(elm)->field.le_prev = &(head)->lh_first;\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tLIST_REMOVE(elm, field) do {\t\t\t\t\t\\\n\tif ((elm)->field.le_next != NULL)\t\t\t\t\\\n\t\t(elm)->field.le_next->field.le_prev = \t\t\t\\\n\t\t    (elm)->field.le_prev;\t\t\t\t\\\n\t*(elm)->field.le_prev = (elm)->field.le_next;\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tLIST_FOREACH(var, head, field)\t\t\t\t\t\\\n\tfor ((var) = ((head)->lh_first);\t\t\t\t\\\n\t\t(var);\t\t\t\t\t\t\t\\\n\t\t(var) = ((var)->field.le_next))\n\n/*\n * List access methods.\n */\n#define\tLIST_EMPTY(head)\t\t((head)->lh_first == NULL)\n#define\tLIST_FIRST(head)\t\t((head)->lh_first)\n#define\tLIST_NEXT(elm, field)\t\t((elm)->field.le_next)\n\n\n/*\n * Singly-linked List definitions.\n */\n#define\tSLIST_HEAD(name, type)\t\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tstruct type *slh_first;\t/* first element */\t\t\t\\\n}\n\n#define\tSLIST_HEAD_INITIALIZER(head)\t\t\t\t\t\\\n\t{ NULL }\n\n#define\tSLIST_ENTRY(type)\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tstruct type *sle_next;\t/* next element */\t\t\t\\\n}\n\n/*\n * Singly-linked List functions.\n */\n#define\tSLIST_INIT(head) do {\t\t\t\t\t\t\\\n\t(head)->slh_first = NULL;\t\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSLIST_INSERT_AFTER(slistelm, elm, field) do {\t\t\t\\\n\t(elm)->field.sle_next = (slistelm)->field.sle_next;\t\t\\\n\t(slistelm)->field.sle_next = (elm);\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSLIST_INSERT_HEAD(head, elm, field) do {\t\t\t\\\n\t(elm)->field.sle_next = (head)->slh_first;\t\t\t\\\n\t(head)->slh_first = (elm);\t\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSLIST_REMOVE_HEAD(head, field) do {\t\t\t\t\\\n\t(head)->slh_first = (head)->slh_first->field.sle_next;\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSLIST_REMOVE(head, elm, type, field) do {\t\t\t\\\n\tif ((head)->slh_first == (elm)) {\t\t\t\t\\\n\t\tSLIST_REMOVE_HEAD((head), field);\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\telse {\t\t\t\t\t\t\t\t\\\n\t\tstruct type *curelm = (head)->slh_first;\t\t\\\n\t\twhile(curelm->field.sle_next != (elm))\t\t\t\\\n\t\t\tcurelm = curelm->field.sle_next;\t\t\\\n\t\tcurelm->field.sle_next =\t\t\t\t\\\n\t\t    curelm->field.sle_next->field.sle_next;\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSLIST_FOREACH(var, head, field)\t\t\t\t\t\\\n\tfor((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)\n\n/*\n * Singly-linked List access methods.\n */\n#define\tSLIST_EMPTY(head)\t((head)->slh_first == NULL)\n#define\tSLIST_FIRST(head)\t((head)->slh_first)\n#define\tSLIST_NEXT(elm, field)\t((elm)->field.sle_next)\n\n\n/*\n * Singly-linked Tail queue declarations.\n */\n#define\tSTAILQ_HEAD(name, type)\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tstruct type *stqh_first;\t/* first element */\t\t\t\\\n\tstruct type **stqh_last;\t/* addr of last next element */\t\t\\\n}\n\n#define\tSTAILQ_HEAD_INITIALIZER(head)\t\t\t\t\t\\\n\t{ NULL, &(head).stqh_first }\n\n#define\tSTAILQ_ENTRY(type)\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tstruct type *stqe_next;\t/* next element */\t\t\t\\\n}\n\n/*\n * Singly-linked Tail queue functions.\n */\n#define\tSTAILQ_INIT(head) do {\t\t\t\t\t\t\\\n\t(head)->stqh_first = NULL;\t\t\t\t\t\\\n\t(head)->stqh_last = &(head)->stqh_first;\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSTAILQ_INSERT_HEAD(head, elm, field) do {\t\t\t\\\n\tif (((elm)->field.stqe_next = (head)->stqh_first) == NULL)\t\\\n\t\t(head)->stqh_last = &(elm)->field.stqe_next;\t\t\\\n\t(head)->stqh_first = (elm);\t\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSTAILQ_INSERT_TAIL(head, elm, field) do {\t\t\t\\\n\t(elm)->field.stqe_next = NULL;\t\t\t\t\t\\\n\t*(head)->stqh_last = (elm);\t\t\t\t\t\\\n\t(head)->stqh_last = &(elm)->field.stqe_next;\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSTAILQ_INSERT_AFTER(head, listelm, elm, field) do {\t\t\\\n\tif (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\\\n\t\t(head)->stqh_last = &(elm)->field.stqe_next;\t\t\\\n\t(listelm)->field.stqe_next = (elm);\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSTAILQ_REMOVE_HEAD(head, field) do {\t\t\t\t\\\n\tif (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \\\n\t\t(head)->stqh_last = &(head)->stqh_first;\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSTAILQ_REMOVE(head, elm, type, field) do {\t\t\t\\\n\tif ((head)->stqh_first == (elm)) {\t\t\t\t\\\n\t\tSTAILQ_REMOVE_HEAD((head), field);\t\t\t\\\n\t} else {\t\t\t\t\t\t\t\\\n\t\tstruct type *curelm = (head)->stqh_first;\t\t\\\n\t\twhile (curelm->field.stqe_next != (elm))\t\t\t\\\n\t\t\tcurelm = curelm->field.stqe_next;\t\t\\\n\t\tif ((curelm->field.stqe_next =\t\t\t\t\\\n\t\t\tcurelm->field.stqe_next->field.stqe_next) == NULL) \\\n\t\t\t    (head)->stqh_last = &(curelm)->field.stqe_next; \\\n\t}\t\t\t\t\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSTAILQ_FOREACH(var, head, field)\t\t\t\t\\\n\tfor ((var) = ((head)->stqh_first);\t\t\t\t\\\n\t\t(var);\t\t\t\t\t\t\t\\\n\t\t(var) = ((var)->field.stqe_next))\n\n/*\n * Singly-linked Tail queue access methods.\n */\n#define\tSTAILQ_EMPTY(head)\t((head)->stqh_first == NULL)\n#define\tSTAILQ_FIRST(head)\t((head)->stqh_first)\n#define\tSTAILQ_NEXT(elm, field)\t((elm)->field.stqe_next)\n\n\n/*\n * Simple queue definitions.\n */\n#define\tSIMPLEQ_HEAD(name, type)\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tstruct type *sqh_first;\t/* first element */\t\t\t\\\n\tstruct type **sqh_last;\t/* addr of last next element */\t\t\\\n}\n\n#define\tSIMPLEQ_HEAD_INITIALIZER(head)\t\t\t\t\t\\\n\t{ NULL, &(head).sqh_first }\n\n#define\tSIMPLEQ_ENTRY(type)\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tstruct type *sqe_next;\t/* next element */\t\t\t\\\n}\n\n/*\n * Simple queue functions.\n */\n#define\tSIMPLEQ_INIT(head) do {\t\t\t\t\t\t\\\n\t(head)->sqh_first = NULL;\t\t\t\t\t\\\n\t(head)->sqh_last = &(head)->sqh_first;\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSIMPLEQ_INSERT_HEAD(head, elm, field) do {\t\t\t\\\n\tif (((elm)->field.sqe_next = (head)->sqh_first) == NULL)\t\\\n\t\t(head)->sqh_last = &(elm)->field.sqe_next;\t\t\\\n\t(head)->sqh_first = (elm);\t\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSIMPLEQ_INSERT_TAIL(head, elm, field) do {\t\t\t\\\n\t(elm)->field.sqe_next = NULL;\t\t\t\t\t\\\n\t*(head)->sqh_last = (elm);\t\t\t\t\t\\\n\t(head)->sqh_last = &(elm)->field.sqe_next;\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {\t\t\\\n\tif (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\\\n\t\t(head)->sqh_last = &(elm)->field.sqe_next;\t\t\\\n\t(listelm)->field.sqe_next = (elm);\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSIMPLEQ_REMOVE_HEAD(head, field) do {\t\t\t\t\\\n\tif (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \\\n\t\t(head)->sqh_last = &(head)->sqh_first;\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSIMPLEQ_REMOVE(head, elm, type, field) do {\t\t\t\\\n\tif ((head)->sqh_first == (elm)) {\t\t\t\t\\\n\t\tSIMPLEQ_REMOVE_HEAD((head), field);\t\t\t\\\n\t} else {\t\t\t\t\t\t\t\\\n\t\tstruct type *curelm = (head)->sqh_first;\t\t\\\n\t\twhile (curelm->field.sqe_next != (elm))\t\t\t\\\n\t\t\tcurelm = curelm->field.sqe_next;\t\t\\\n\t\tif ((curelm->field.sqe_next =\t\t\t\t\\\n\t\t\tcurelm->field.sqe_next->field.sqe_next) == NULL) \\\n\t\t\t    (head)->sqh_last = &(curelm)->field.sqe_next; \\\n\t}\t\t\t\t\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tSIMPLEQ_FOREACH(var, head, field)\t\t\t\t\\\n\tfor ((var) = ((head)->sqh_first);\t\t\t\t\\\n\t\t(var);\t\t\t\t\t\t\t\\\n\t\t(var) = ((var)->field.sqe_next))\n\n/*\n * Simple queue access methods.\n */\n#define\tSIMPLEQ_EMPTY(head)\t\t((head)->sqh_first == NULL)\n#define\tSIMPLEQ_FIRST(head)\t\t((head)->sqh_first)\n#define\tSIMPLEQ_NEXT(elm, field)\t((elm)->field.sqe_next)\n\n\n/*\n * Tail queue definitions.\n */\n#define\t_TAILQ_HEAD(name, type, qual)\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tqual type *tqh_first;\t\t/* first element */\t\t\\\n\tqual type *qual *tqh_last;\t/* addr of last next element */\t\\\n}\n#define TAILQ_HEAD(name, type)\t_TAILQ_HEAD(name, struct type,)\n\n#define\tTAILQ_HEAD_INITIALIZER(head)\t\t\t\t\t\\\n\t{ NULL, &(head).tqh_first }\n\n#define\t_TAILQ_ENTRY(type, qual)\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tqual type *tqe_next;\t\t/* next element */\t\t\\\n\tqual type *qual *tqe_prev;\t/* address of previous next element */\\\n}\n#define TAILQ_ENTRY(type)\t_TAILQ_ENTRY(struct type,)\n\n/*\n * Tail queue functions.\n */\n#define\tTAILQ_INIT(head) do {\t\t\t\t\t\t\\\n\t(head)->tqh_first = NULL;\t\t\t\t\t\\\n\t(head)->tqh_last = &(head)->tqh_first;\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tTAILQ_INSERT_HEAD(head, elm, field) do {\t\t\t\\\n\tif (((elm)->field.tqe_next = (head)->tqh_first) != NULL)\t\\\n\t\t(head)->tqh_first->field.tqe_prev =\t\t\t\\\n\t\t    &(elm)->field.tqe_next;\t\t\t\t\\\n\telse\t\t\t\t\t\t\t\t\\\n\t\t(head)->tqh_last = &(elm)->field.tqe_next;\t\t\\\n\t(head)->tqh_first = (elm);\t\t\t\t\t\\\n\t(elm)->field.tqe_prev = &(head)->tqh_first;\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tTAILQ_INSERT_TAIL(head, elm, field) do {\t\t\t\\\n\t(elm)->field.tqe_next = NULL;\t\t\t\t\t\\\n\t(elm)->field.tqe_prev = (head)->tqh_last;\t\t\t\\\n\t*(head)->tqh_last = (elm);\t\t\t\t\t\\\n\t(head)->tqh_last = &(elm)->field.tqe_next;\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tTAILQ_INSERT_AFTER(head, listelm, elm, field) do {\t\t\\\n\tif (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\\\n\t\t(elm)->field.tqe_next->field.tqe_prev = \t\t\\\n\t\t    &(elm)->field.tqe_next;\t\t\t\t\\\n\telse\t\t\t\t\t\t\t\t\\\n\t\t(head)->tqh_last = &(elm)->field.tqe_next;\t\t\\\n\t(listelm)->field.tqe_next = (elm);\t\t\t\t\\\n\t(elm)->field.tqe_prev = &(listelm)->field.tqe_next;\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tTAILQ_INSERT_BEFORE(listelm, elm, field) do {\t\t\t\\\n\t(elm)->field.tqe_prev = (listelm)->field.tqe_prev;\t\t\\\n\t(elm)->field.tqe_next = (listelm);\t\t\t\t\\\n\t*(listelm)->field.tqe_prev = (elm);\t\t\t\t\\\n\t(listelm)->field.tqe_prev = &(elm)->field.tqe_next;\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tTAILQ_REMOVE(head, elm, field) do {\t\t\t\t\\\n\tif (((elm)->field.tqe_next) != NULL)\t\t\t\t\\\n\t\t(elm)->field.tqe_next->field.tqe_prev = \t\t\\\n\t\t    (elm)->field.tqe_prev;\t\t\t\t\\\n\telse\t\t\t\t\t\t\t\t\\\n\t\t(head)->tqh_last = (elm)->field.tqe_prev;\t\t\\\n\t*(elm)->field.tqe_prev = (elm)->field.tqe_next;\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tTAILQ_FOREACH(var, head, field)\t\t\t\t\t\\\n\tfor ((var) = ((head)->tqh_first);\t\t\t\t\\\n\t\t(var);\t\t\t\t\t\t\t\\\n\t\t(var) = ((var)->field.tqe_next))\n\n#define\tTAILQ_FOREACH_REVERSE(var, head, headname, field)\t\t\\\n\tfor ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));\t\\\n\t\t(var);\t\t\t\t\t\t\t\\\n\t\t(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))\n\n/*\n * Tail queue access methods.\n */\n#define\tTAILQ_EMPTY(head)\t\t((head)->tqh_first == NULL)\n#define\tTAILQ_FIRST(head)\t\t((head)->tqh_first)\n#define\tTAILQ_NEXT(elm, field)\t\t((elm)->field.tqe_next)\n\n#define\tTAILQ_LAST(head, headname) \\\n\t(*(((struct headname *)((head)->tqh_last))->tqh_last))\n#define\tTAILQ_PREV(elm, headname, field) \\\n\t(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))\n\n\n/*\n * Circular queue definitions.\n */\n#define\tCIRCLEQ_HEAD(name, type)\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tstruct type *cqh_first;\t\t/* first element */\t\t\\\n\tstruct type *cqh_last;\t\t/* last element */\t\t\\\n}\n\n#define\tCIRCLEQ_HEAD_INITIALIZER(head)\t\t\t\t\t\\\n\t{ (void *)&head, (void *)&head }\n\n#define\tCIRCLEQ_ENTRY(type)\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tstruct type *cqe_next;\t\t/* next element */\t\t\\\n\tstruct type *cqe_prev;\t\t/* previous element */\t\t\\\n}\n\n/*\n * Circular queue functions.\n */\n#define\tCIRCLEQ_INIT(head) do {\t\t\t\t\t\t\\\n\t(head)->cqh_first = (void *)(head);\t\t\t\t\\\n\t(head)->cqh_last = (void *)(head);\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tCIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {\t\t\\\n\t(elm)->field.cqe_next = (listelm)->field.cqe_next;\t\t\\\n\t(elm)->field.cqe_prev = (listelm);\t\t\t\t\\\n\tif ((listelm)->field.cqe_next == (void *)(head))\t\t\\\n\t\t(head)->cqh_last = (elm);\t\t\t\t\\\n\telse\t\t\t\t\t\t\t\t\\\n\t\t(listelm)->field.cqe_next->field.cqe_prev = (elm);\t\\\n\t(listelm)->field.cqe_next = (elm);\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tCIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {\t\t\\\n\t(elm)->field.cqe_next = (listelm);\t\t\t\t\\\n\t(elm)->field.cqe_prev = (listelm)->field.cqe_prev;\t\t\\\n\tif ((listelm)->field.cqe_prev == (void *)(head))\t\t\\\n\t\t(head)->cqh_first = (elm);\t\t\t\t\\\n\telse\t\t\t\t\t\t\t\t\\\n\t\t(listelm)->field.cqe_prev->field.cqe_next = (elm);\t\\\n\t(listelm)->field.cqe_prev = (elm);\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tCIRCLEQ_INSERT_HEAD(head, elm, field) do {\t\t\t\\\n\t(elm)->field.cqe_next = (head)->cqh_first;\t\t\t\\\n\t(elm)->field.cqe_prev = (void *)(head);\t\t\t\t\\\n\tif ((head)->cqh_last == (void *)(head))\t\t\t\t\\\n\t\t(head)->cqh_last = (elm);\t\t\t\t\\\n\telse\t\t\t\t\t\t\t\t\\\n\t\t(head)->cqh_first->field.cqe_prev = (elm);\t\t\\\n\t(head)->cqh_first = (elm);\t\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tCIRCLEQ_INSERT_TAIL(head, elm, field) do {\t\t\t\\\n\t(elm)->field.cqe_next = (void *)(head);\t\t\t\t\\\n\t(elm)->field.cqe_prev = (head)->cqh_last;\t\t\t\\\n\tif ((head)->cqh_first == (void *)(head))\t\t\t\\\n\t\t(head)->cqh_first = (elm);\t\t\t\t\\\n\telse\t\t\t\t\t\t\t\t\\\n\t\t(head)->cqh_last->field.cqe_next = (elm);\t\t\\\n\t(head)->cqh_last = (elm);\t\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tCIRCLEQ_REMOVE(head, elm, field) do {\t\t\t\t\\\n\tif ((elm)->field.cqe_next == (void *)(head))\t\t\t\\\n\t\t(head)->cqh_last = (elm)->field.cqe_prev;\t\t\\\n\telse\t\t\t\t\t\t\t\t\\\n\t\t(elm)->field.cqe_next->field.cqe_prev =\t\t\t\\\n\t\t    (elm)->field.cqe_prev;\t\t\t\t\\\n\tif ((elm)->field.cqe_prev == (void *)(head))\t\t\t\\\n\t\t(head)->cqh_first = (elm)->field.cqe_next;\t\t\\\n\telse\t\t\t\t\t\t\t\t\\\n\t\t(elm)->field.cqe_prev->field.cqe_next =\t\t\t\\\n\t\t    (elm)->field.cqe_next;\t\t\t\t\\\n} while (/*CONSTCOND*/0)\n\n#define\tCIRCLEQ_FOREACH(var, head, field)\t\t\t\t\\\n\tfor ((var) = ((head)->cqh_first);\t\t\t\t\\\n\t\t(var) != (const void *)(head);\t\t\t\t\\\n\t\t(var) = ((var)->field.cqe_next))\n\n#define\tCIRCLEQ_FOREACH_REVERSE(var, head, field)\t\t\t\\\n\tfor ((var) = ((head)->cqh_last);\t\t\t\t\\\n\t\t(var) != (const void *)(head);\t\t\t\t\\\n\t\t(var) = ((var)->field.cqe_prev))\n\n/*\n * Circular queue access methods.\n */\n#define\tCIRCLEQ_EMPTY(head)\t\t((head)->cqh_first == (void *)(head))\n#define\tCIRCLEQ_FIRST(head)\t\t((head)->cqh_first)\n#define\tCIRCLEQ_LAST(head)\t\t((head)->cqh_last)\n#define\tCIRCLEQ_NEXT(elm, field)\t((elm)->field.cqe_next)\n#define\tCIRCLEQ_PREV(elm, field)\t((elm)->field.cqe_prev)\n\n#define CIRCLEQ_LOOP_NEXT(head, elm, field)\t\t\t\t\\\n\t(((elm)->field.cqe_next == (void *)(head))\t\t\t\\\n\t    ? ((head)->cqh_first)\t\t\t\t\t\\\n\t    : (elm->field.cqe_next))\n#define CIRCLEQ_LOOP_PREV(head, elm, field)\t\t\t\t\\\n\t(((elm)->field.cqe_prev == (void *)(head))\t\t\t\\\n\t    ? ((head)->cqh_last)\t\t\t\t\t\\\n\t    : (elm->field.cqe_prev))\n\n#endif\t/* sys/queue.h */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/reboot.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_REBOOT_H_\n#define _SYS_REBOOT_H_\n\n#include <sys/cdefs.h>\n#include <linux/reboot.h>\n\n__BEGIN_DECLS\n\n/* use glibc names as well */\n\n#define RB_AUTOBOOT     LINUX_REBOOT_CMD_RESTART\n#define RB_HALT_SYSTEM  LINUX_REBOOT_CMD_HALT\n#define RB_ENABLE_CAD   LINUX_REBOOT_CMD_CAD_ON\n#define RB_DISABLE_CAD  LINUX_REBOOT_CMD_CAD_OFF\n#define RB_POWER_OFF    LINUX_REBOOT_CMD_POWER_OFF\n\nextern int reboot(int  reboot_type);\n\n__END_DECLS\n\n#endif /* _SYS_REBOOT_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/reg.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_REG_H_\n#define _SYS_REG_H_\n\n#if defined(__i386__)\n\n#define EBX 0\n#define ECX 1\n#define EDX 2\n#define ESI 3\n#define EDI 4\n#define EBP 5\n#define EAX 6\n#define DS 7\n#define ES 8\n#define FS 9\n#define GS 10\n#define ORIG_EAX 11\n#define EIP 12\n#define CS 13\n#define EFL 14\n#define UESP 15\n#define SS 16\n\n#elif defined(__x86_64__)\n\n#define R15 0\n#define R14 1\n#define R13 2\n#define R12 3\n#define RBP 4\n#define RBX 5\n#define R11 6\n#define R10 7\n#define R9 8\n#define R8 9\n#define RAX 10\n#define RCX 11\n#define RDX 12\n#define RSI 13\n#define RDI 14\n#define ORIG_RAX 15\n#define RIP 16\n#define CS 17\n#define EFLAGS 18\n#define RSP 19\n#define SS 20\n#define FS_BASE 21\n#define GS_BASE 22\n#define DS 23\n#define ES 24\n#define FS 25\n#define GS 26\n\n#endif\n\n#endif /* _SYS_REG_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/resource.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_RESOURCE_H_\n#define _SYS_RESOURCE_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n#include <linux/resource.h>\n\n__BEGIN_DECLS\n\n/* The kernel header doesn't have these, but POSIX does. */\n#define RLIM_SAVED_CUR RLIM_INFINITY\n#define RLIM_SAVED_MAX RLIM_INFINITY\n\ntypedef unsigned long rlim_t;\n\nextern int getrlimit(int, struct rlimit*);\nextern int setrlimit(int, const struct rlimit*);\n\nextern int getrlimit64(int, struct rlimit64*);\nextern int setrlimit64(int, const struct rlimit64*);\n\nextern int getpriority(int, int);\nextern int setpriority(int, int, int);\n\nextern int getrusage(int, struct rusage*);\n\nextern int prlimit(pid_t, int, const struct rlimit*, struct rlimit*);\nextern int prlimit64(pid_t, int, const struct rlimit64*, struct rlimit64*);\n\n__END_DECLS\n\n#endif /* _SYS_RESOURCE_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/select.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_SELECT_H_\n#define _SYS_SELECT_H_\n\n#include <linux/time.h>\n#include <signal.h>\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n__BEGIN_DECLS\n\n#define FD_SETSIZE 1024\n#define NFDBITS (8 * sizeof(unsigned long))\n#define __FDSET_LONGS (FD_SETSIZE/NFDBITS)\n\ntypedef struct {\n  unsigned long fds_bits[__FDSET_LONGS];\n} fd_set;\n\n#define __FDELT(fd) ((fd) / NFDBITS)\n#define __FDMASK(fd) (1UL << ((fd) % NFDBITS))\n#define __FDS_BITS(set) (((fd_set*)(set))->fds_bits)\n\n/* Inline loop so we don't have to declare memset. */\n#define FD_ZERO(set) \\\n  do { \\\n    size_t __i; \\\n    for (__i = 0; __i < __FDSET_LONGS; ++__i) { \\\n      (set)->fds_bits[__i] = 0; \\\n    } \\\n  } while (0)\n\nextern void __FD_CLR_chk(int, fd_set*, size_t);\nextern void __FD_SET_chk(int, fd_set*, size_t);\nextern int  __FD_ISSET_chk(int, fd_set*, size_t);\n\n#if defined(__BIONIC_FORTIFY)\n#define FD_CLR(fd, set) __FD_CLR_chk(fd, set, __bos(set))\n#define FD_SET(fd, set) __FD_SET_chk(fd, set, __bos(set))\n#define FD_ISSET(fd, set) __FD_ISSET_chk(fd, set, __bos(set))\n#else\n#define FD_CLR(fd, set) (__FDS_BITS(set)[__FDELT(fd)] &= ~__FDMASK(fd))\n#define FD_SET(fd, set) (__FDS_BITS(set)[__FDELT(fd)] |= __FDMASK(fd))\n#define FD_ISSET(fd, set) ((__FDS_BITS(set)[__FDELT(fd)] & __FDMASK(fd)) != 0)\n#endif /* defined(__BIONIC_FORTIFY) */\n\nextern int select(int, fd_set*, fd_set*, fd_set*, struct timeval*);\nextern int pselect(int, fd_set*, fd_set*, fd_set*, const struct timespec*, const sigset_t*);\n\n__END_DECLS\n\n#endif /* _SYS_SELECT_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/sem.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_SEM_H_\n#define _SYS_SEM_H_\n\n#include <linux/sem.h>\n\n#endif /* _SYS_SEM_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/sendfile.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_SENDFILE_H_\n#define _SYS_SENDFILE_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n__BEGIN_DECLS\n\n#if defined(__USE_FILE_OFFSET64)\nextern ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) __RENAME(sendfile64);\n#else\nextern ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count);\n#endif\nextern ssize_t sendfile64(int out_fd, int in_fd, off64_t* offset, size_t count);\n\n__END_DECLS\n\n#endif /* _SYS_SENDFILE_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/signal.h",
    "content": "#include <signal.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/signalfd.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_SIGNALFD_H_\n#define _SYS_SIGNALFD_H_\n\n#include <linux/signalfd.h>\n#include <signal.h>\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\nextern int signalfd(int fd, const sigset_t* mask, int flags) __nonnull((2));\n\n__END_DECLS\n\n#endif /* _SYS_SIGNALFD_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/socket.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_SOCKET_H_\n#define _SYS_SOCKET_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <linux/socket.h>\n\n#include <asm/fcntl.h>\n#include <asm/socket.h>\n#include <linux/sockios.h>\n#include <linux/uio.h>\n#include <linux/types.h>\n#include <linux/compiler.h>\n\n__BEGIN_DECLS\n\n#define sockaddr_storage __kernel_sockaddr_storage\ntypedef unsigned short sa_family_t;\n\nstruct timespec;\n\n#ifdef __mips__\n#define SOCK_DGRAM      1\n#define SOCK_STREAM     2\n#else\n#define SOCK_STREAM     1\n#define SOCK_DGRAM      2\n#endif\n#define SOCK_RAW        3\n#define SOCK_RDM        4\n#define SOCK_SEQPACKET  5\n#define SOCK_DCCP       6\n#define SOCK_PACKET     10\n\n#define SOCK_CLOEXEC O_CLOEXEC\n#define SOCK_NONBLOCK O_NONBLOCK\n\nenum {\n  SHUT_RD = 0,\n#define SHUT_RD         SHUT_RD\n  SHUT_WR,\n#define SHUT_WR         SHUT_WR\n  SHUT_RDWR\n#define SHUT_RDWR       SHUT_RDWR\n};\n\nstruct sockaddr {\n  sa_family_t sa_family;\n  char sa_data[14];\n};\n\nstruct linger {\n  int l_onoff;\n  int l_linger;\n};\n\nstruct msghdr {\n  void* msg_name;\n  socklen_t msg_namelen;\n  struct iovec* msg_iov;\n  size_t msg_iovlen;\n  void* msg_control;\n  size_t msg_controllen;\n  int msg_flags;\n};\n\nstruct mmsghdr {\n  struct msghdr msg_hdr;\n  unsigned int msg_len;\n};\n\nstruct cmsghdr {\n  size_t cmsg_len;\n  int cmsg_level;\n  int cmsg_type;\n};\n\n#define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr((mhdr), (cmsg))\n#define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) )\n#define CMSG_DATA(cmsg) (((unsigned char*)(cmsg) + CMSG_ALIGN(sizeof(struct cmsghdr))))\n#define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len))\n#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))\n#define CMSG_FIRSTHDR(msg) \\\n  ((msg)->msg_controllen >= sizeof(struct cmsghdr) \\\n   ? (struct cmsghdr*) (msg)->msg_control : (struct cmsghdr*) NULL)\n#define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) &&   (cmsg)->cmsg_len <= (unsigned long)   ((mhdr)->msg_controllen -   ((char*)(cmsg) - (char*)(mhdr)->msg_control)))\n\nstruct cmsghdr* __cmsg_nxthdr(struct msghdr*, struct cmsghdr*);\n\n#define SCM_RIGHTS 0x01\n#define SCM_CREDENTIALS 0x02\n#define SCM_SECURITY 0x03\n\nstruct ucred {\n  pid_t pid;\n  uid_t uid;\n  gid_t gid;\n};\n\n#define AF_UNSPEC 0\n#define AF_UNIX 1\n#define AF_LOCAL 1\n#define AF_INET 2\n#define AF_AX25 3\n#define AF_IPX 4\n#define AF_APPLETALK 5\n#define AF_NETROM 6\n#define AF_BRIDGE 7\n#define AF_ATMPVC 8\n#define AF_X25 9\n#define AF_INET6 10\n#define AF_ROSE 11\n#define AF_DECnet 12\n#define AF_NETBEUI 13\n#define AF_SECURITY 14\n#define AF_KEY 15\n#define AF_NETLINK 16\n#define AF_ROUTE AF_NETLINK\n#define AF_PACKET 17\n#define AF_ASH 18\n#define AF_ECONET 19\n#define AF_ATMSVC 20\n#define AF_RDS 21\n#define AF_SNA 22\n#define AF_IRDA 23\n#define AF_PPPOX 24\n#define AF_WANPIPE 25\n#define AF_LLC 26\n#define AF_CAN 29\n#define AF_TIPC 30\n#define AF_BLUETOOTH 31\n#define AF_IUCV 32\n#define AF_RXRPC 33\n#define AF_ISDN 34\n#define AF_PHONET 35\n#define AF_IEEE802154 36\n#define AF_CAIF 37\n#define AF_ALG 38\n#define AF_NFC 39\n#define AF_VSOCK 40\n#define AF_MAX 41\n\n#define PF_UNSPEC AF_UNSPEC\n#define PF_UNIX AF_UNIX\n#define PF_LOCAL AF_LOCAL\n#define PF_INET AF_INET\n#define PF_AX25 AF_AX25\n#define PF_IPX AF_IPX\n#define PF_APPLETALK AF_APPLETALK\n#define PF_NETROM AF_NETROM\n#define PF_BRIDGE AF_BRIDGE\n#define PF_ATMPVC AF_ATMPVC\n#define PF_X25 AF_X25\n#define PF_INET6 AF_INET6\n#define PF_ROSE AF_ROSE\n#define PF_DECnet AF_DECnet\n#define PF_NETBEUI AF_NETBEUI\n#define PF_SECURITY AF_SECURITY\n#define PF_KEY AF_KEY\n#define PF_NETLINK AF_NETLINK\n#define PF_ROUTE AF_ROUTE\n#define PF_PACKET AF_PACKET\n#define PF_ASH AF_ASH\n#define PF_ECONET AF_ECONET\n#define PF_ATMSVC AF_ATMSVC\n#define PF_RDS AF_RDS\n#define PF_SNA AF_SNA\n#define PF_IRDA AF_IRDA\n#define PF_PPPOX AF_PPPOX\n#define PF_WANPIPE AF_WANPIPE\n#define PF_LLC AF_LLC\n#define PF_CAN AF_CAN\n#define PF_TIPC AF_TIPC\n#define PF_BLUETOOTH AF_BLUETOOTH\n#define PF_IUCV AF_IUCV\n#define PF_RXRPC AF_RXRPC\n#define PF_ISDN AF_ISDN\n#define PF_PHONET AF_PHONET\n#define PF_IEEE802154 AF_IEEE802154\n#define PF_CAIF AF_CAIF\n#define PF_ALG AF_ALG\n#define PF_NFC AF_NFC\n#define PF_VSOCK AF_VSOCK\n#define PF_MAX AF_MAX\n\n#define SOMAXCONN 128\n\n#define MSG_OOB 1\n#define MSG_PEEK 2\n#define MSG_DONTROUTE 4\n#define MSG_TRYHARD 4\n#define MSG_CTRUNC 8\n#define MSG_PROBE 0x10\n#define MSG_TRUNC 0x20\n#define MSG_DONTWAIT 0x40\n#define MSG_EOR 0x80\n#define MSG_WAITALL 0x100\n#define MSG_FIN 0x200\n#define MSG_SYN 0x400\n#define MSG_CONFIRM 0x800\n#define MSG_RST 0x1000\n#define MSG_ERRQUEUE 0x2000\n#define MSG_NOSIGNAL 0x4000\n#define MSG_MORE 0x8000\n#define MSG_WAITFORONE 0x10000\n#define MSG_FASTOPEN 0x20000000\n#define MSG_CMSG_CLOEXEC 0x40000000\n#define MSG_EOF MSG_FIN\n#define MSG_CMSG_COMPAT 0\n\n#define SOL_IP 0\n#define SOL_TCP 6\n#define SOL_UDP 17\n#define SOL_IPV6 41\n#define SOL_ICMPV6 58\n#define SOL_SCTP 132\n#define SOL_RAW 255\n#define SOL_IPX 256\n#define SOL_AX25 257\n#define SOL_ATALK 258\n#define SOL_NETROM 259\n#define SOL_ROSE 260\n#define SOL_DECNET 261\n#define SOL_X25 262\n#define SOL_PACKET 263\n#define SOL_ATM 264\n#define SOL_AAL 265\n#define SOL_IRDA 266\n#define SOL_NETBEUI 267\n#define SOL_LLC 268\n#define SOL_DCCP 269\n#define SOL_NETLINK 270\n#define SOL_TIPC 271\n\n#define IPX_TYPE 1\n\n#ifdef __i386__\n# define __socketcall extern __attribute__((__cdecl__))\n#else\n# define __socketcall extern\n#endif\n\n__socketcall int accept(int, struct sockaddr*, socklen_t*);\n__socketcall int accept4(int, struct sockaddr*, socklen_t*, int);\n__socketcall int bind(int, const struct sockaddr*, int);\n__socketcall int connect(int, const struct sockaddr*, socklen_t);\n__socketcall int getpeername(int, struct sockaddr*, socklen_t*);\n__socketcall int getsockname(int, struct sockaddr*, socklen_t*);\n__socketcall int getsockopt(int, int, int, void*, socklen_t*);\n__socketcall int listen(int, int);\n__socketcall int recvmmsg(int, struct mmsghdr*, unsigned int, int, const struct timespec*);\n__socketcall int recvmsg(int, struct msghdr*, int);\n__socketcall int sendmmsg(int, const struct mmsghdr*, unsigned int, int);\n__socketcall int sendmsg(int, const struct msghdr*, int);\n__socketcall int setsockopt(int, int, int, const void*, socklen_t);\n__socketcall int shutdown(int, int);\n__socketcall int socket(int, int, int);\n__socketcall int socketpair(int, int, int, int*);\n\nextern ssize_t send(int, const void*, size_t, int);\nextern ssize_t recv(int, void*, size_t, int);\n\n__socketcall ssize_t sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t);\n__socketcall ssize_t recvfrom(int, void*, size_t, int, const struct sockaddr*, socklen_t*);\n\n__errordecl(__recvfrom_error, \"recvfrom called with size bigger than buffer\");\nextern ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, const struct sockaddr*, socklen_t*);\nextern ssize_t __recvfrom_real(int, void*, size_t, int, const struct sockaddr*, socklen_t*) __RENAME(recvfrom);\n\n#if defined(__BIONIC_FORTIFY)\n\n__BIONIC_FORTIFY_INLINE\nssize_t recvfrom(int fd, void* buf, size_t len, int flags, const struct sockaddr* src_addr, socklen_t* addr_len) {\n  size_t bos = __bos0(buf);\n\n#if !defined(__clang__)\n  if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n    return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);\n  }\n\n  if (__builtin_constant_p(len) && (len <= bos)) {\n    return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);\n  }\n\n  if (__builtin_constant_p(len) && (len > bos)) {\n    __recvfrom_error();\n  }\n#endif\n\n  return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);\n}\n\n__BIONIC_FORTIFY_INLINE\nssize_t recv(int socket, void* buf, size_t len, int flags) {\n  return recvfrom(socket, buf, len, flags, NULL, 0);\n}\n\n#endif /* __BIONIC_FORTIFY */\n\n#undef __socketcall\n\n__END_DECLS\n\n#endif /* _SYS_SOCKET_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/socketcalls.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_SOCKETCALLS_H_\n#define _SYS_SOCKETCALLS_H_\n\n/* socketcalls by number */\n\n#define SYS_SOCKET      1               /* sys_socket(2)                */\n#define SYS_BIND        2               /* sys_bind(2)                  */\n#define SYS_CONNECT     3               /* sys_connect(2)               */\n#define SYS_LISTEN      4               /* sys_listen(2)                */\n#define SYS_ACCEPT      5               /* sys_accept(2)                */\n#define SYS_GETSOCKNAME 6               /* sys_getsockname(2)           */\n#define SYS_GETPEERNAME 7               /* sys_getpeername(2)           */\n#define SYS_SOCKETPAIR  8               /* sys_socketpair(2)            */\n#define SYS_SEND        9               /* sys_send(2)                  */\n#define SYS_RECV        10              /* sys_recv(2)                  */\n#define SYS_SENDTO      11              /* sys_sendto(2)                */\n#define SYS_RECVFROM    12              /* sys_recvfrom(2)              */\n#define SYS_SHUTDOWN    13              /* sys_shutdown(2)              */\n#define SYS_SETSOCKOPT  14              /* sys_setsockopt(2)            */\n#define SYS_GETSOCKOPT  15              /* sys_getsockopt(2)            */\n#define SYS_SENDMSG     16              /* sys_sendmsg(2)               */\n#define SYS_RECVMSG     17              /* sys_recvmsg(2)               */\n#define SYS_ACCEPT4     18              /* sys_accept4(2)               */\n#define SYS_RECVMMSG    19              /* sys_recvmmsg(2)              */\n#define SYS_SENDMMSG    20              /* sys_sendmmsg(2)              */\n\n#endif /* _SYS_SOCKETCALLS_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/stat.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_STAT_H_\n#define _SYS_STAT_H_\n\n#include <bits/timespec.h>\n#include <linux/stat.h>\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n__BEGIN_DECLS\n\n#if defined(__aarch64__) || (defined(__mips__) && defined(__LP64__))\n#define __STAT64_BODY \\\n  dev_t st_dev; \\\n  ino_t st_ino; \\\n  mode_t st_mode; \\\n  nlink_t st_nlink; \\\n  uid_t st_uid; \\\n  gid_t st_gid; \\\n  dev_t st_rdev; \\\n  unsigned long __pad1; \\\n  off_t st_size; \\\n  int st_blksize; \\\n  int __pad2; \\\n  long st_blocks; \\\n  struct timespec st_atim; \\\n  struct timespec st_mtim; \\\n  struct timespec st_ctim; \\\n  unsigned int __unused4; \\\n  unsigned int __unused5; \\\n\n#elif defined(__mips__) && !defined(__LP64__)\n#define __STAT64_BODY \\\n  unsigned int st_dev; \\\n  unsigned int __pad0[3]; \\\n  unsigned long long st_ino; \\\n  mode_t st_mode; \\\n  nlink_t st_nlink; \\\n  uid_t st_uid; \\\n  gid_t st_gid; \\\n  unsigned int st_rdev; \\\n  unsigned int __pad1[3]; \\\n  long long st_size; \\\n  struct timespec st_atim; \\\n  struct timespec st_mtim; \\\n  struct timespec st_ctim; \\\n  unsigned int st_blksize; \\\n  unsigned int __pad2; \\\n  unsigned long long st_blocks; \\\n\n#elif defined(__x86_64__)\n#define __STAT64_BODY \\\n  dev_t st_dev; \\\n  ino_t st_ino; \\\n  unsigned long st_nlink; \\\n  mode_t st_mode; \\\n  uid_t st_uid; \\\n  gid_t st_gid; \\\n  unsigned int __pad0; \\\n  dev_t st_rdev; \\\n  off_t st_size; \\\n  long st_blksize; \\\n  long st_blocks; \\\n  struct timespec st_atim; \\\n  struct timespec st_mtim; \\\n  struct timespec st_ctim; \\\n  long __pad3[3]; \\\n\n#else /* __arm__ || __i386__ */\n#define __STAT64_BODY \\\n  unsigned long long st_dev; \\\n  unsigned char __pad0[4]; \\\n  unsigned long __st_ino; \\\n  unsigned int st_mode; \\\n  nlink_t st_nlink; \\\n  uid_t st_uid; \\\n  gid_t st_gid; \\\n  unsigned long long st_rdev; \\\n  unsigned char __pad3[4]; \\\n  long long st_size; \\\n  unsigned long st_blksize; \\\n  unsigned long long st_blocks; \\\n  struct timespec st_atim; \\\n  struct timespec st_mtim; \\\n  struct timespec st_ctim; \\\n  unsigned long long st_ino; \\\n\n#endif\n\nstruct stat { __STAT64_BODY };\nstruct stat64 { __STAT64_BODY };\n\n#undef __STAT64_BODY\n\n/* Compatibility with older versions of POSIX. */\n#define st_atime st_atim.tv_sec\n#define st_mtime st_mtim.tv_sec\n#define st_ctime st_ctim.tv_sec\n/* Compatibility with glibc. */\n#define st_atimensec st_atim.tv_nsec\n#define st_mtimensec st_mtim.tv_nsec\n#define st_ctimensec st_ctim.tv_nsec\n\n#ifdef __USE_BSD\n/* Permission macros provided by glibc for compatibility with BSDs. */\n#define ACCESSPERMS (S_IRWXU | S_IRWXG | S_IRWXO) /* 0777 */\n#define ALLPERMS    (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) /* 07777 */\n#define DEFFILEMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) /* 0666 */\n#endif\n\nextern int chmod(const char*, mode_t);\nextern int fchmod(int, mode_t);\nextern int mkdir(const char*, mode_t);\n\nextern int fstat(int, struct stat*);\nextern int fstat64(int, struct stat64*);\nextern int fstatat(int, const char*, struct stat*, int);\nextern int fstatat64(int, const char*, struct stat64*, int);\nextern int lstat(const char*, struct stat*);\nextern int lstat64(const char*, struct stat64*);\nextern int stat(const char*, struct stat*);\nextern int stat64(const char*, struct stat64*);\n\nextern int mknod(const char*, mode_t, dev_t);\nextern mode_t umask(mode_t);\n\nextern mode_t __umask_chk(mode_t);\nextern mode_t __umask_real(mode_t) __RENAME(umask);\n__errordecl(__umask_invalid_mode, \"umask called with invalid mode\");\n\n#if defined(__BIONIC_FORTIFY)\n\n__BIONIC_FORTIFY_INLINE\nmode_t umask(mode_t mode) {\n#if !defined(__clang__)\n  if (__builtin_constant_p(mode)) {\n    if ((mode & 0777) != mode) {\n      __umask_invalid_mode();\n    }\n    return __umask_real(mode);\n  }\n#endif\n  return __umask_chk(mode);\n}\n#endif /* defined(__BIONIC_FORTIFY) */\n\nextern int mkfifo(const char*, mode_t) __INTRODUCED_IN(21);\nextern int mkfifoat(int, const char*, mode_t);\n\nextern int fchmodat(int, const char*, mode_t, int);\nextern int mkdirat(int, const char*, mode_t);\nextern int mknodat(int, const char*, mode_t, dev_t);\n\n#define UTIME_NOW  ((1L << 30) - 1L)\n#define UTIME_OMIT ((1L << 30) - 2L)\nextern int utimensat(int fd, const char *path, const struct timespec times[2], int flags);\nextern int futimens(int fd, const struct timespec times[2]);\n\n#if __ANDROID_API__ < 21\n#include <android/legacy_sys_stat_inlines.h>\n#endif\n\n__END_DECLS\n\n#endif /* _SYS_STAT_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/statfs.h",
    "content": "#include <sys/vfs.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/statvfs.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _SYS_STATVFS_H_\n#define _SYS_STATVFS_H_\n\n#include <stdint.h>\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n__BEGIN_DECLS\n\n#ifdef __LP64__\n#define __STATVFS64_RESERVED uint32_t __f_reserved[6];\n#else\n#define __STATVFS64_RESERVED\n#endif\n\n#define __STATVFS64_BODY \\\n  unsigned long f_bsize; \\\n  unsigned long f_frsize; \\\n  fsblkcnt_t    f_blocks; \\\n  fsblkcnt_t    f_bfree; \\\n  fsblkcnt_t    f_bavail; \\\n  fsfilcnt_t    f_files; \\\n  fsfilcnt_t    f_ffree; \\\n  fsfilcnt_t    f_favail; \\\n  unsigned long f_fsid; \\\n  unsigned long f_flag; \\\n  unsigned long f_namemax; \\\n  __STATVFS64_RESERVED\n\nstruct statvfs { __STATVFS64_BODY };\nstruct statvfs64 { __STATVFS64_BODY };\n\n#undef __STATVFS64_BODY\n#undef __STATVFS64_RESERVED\n\n#define ST_RDONLY      0x0001\n#define ST_NOSUID      0x0002\n#define ST_NODEV       0x0004\n#define ST_NOEXEC      0x0008\n#define ST_SYNCHRONOUS 0x0010\n#define ST_MANDLOCK    0x0040\n#define ST_NOATIME     0x0400\n#define ST_NODIRATIME  0x0800\n#define ST_RELATIME    0x1000\n\nextern int statvfs(const char* __restrict, struct statvfs* __restrict) __nonnull((1, 2));\nextern int statvfs64(const char* __restrict, struct statvfs64* __restrict) __nonnull((1, 2));\nextern int fstatvfs(int, struct statvfs*) __nonnull((2));\nextern int fstatvfs64(int, struct statvfs64*) __nonnull((2));\n\n__END_DECLS\n\n#endif /* _SYS_STATVFS_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/swap.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_SWAP_H_\n#define _SYS_SWAP_H_\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\n#define SWAP_FLAG_DISCARD 0x10000\n#define SWAP_FLAG_PREFER 0x8000\n#define SWAP_FLAG_PRIO_MASK 0x7fff\n#define SWAP_FLAG_PRIO_SHIFT 0\n\nextern int swapon(const char*, int) __nonnull((1));\nextern int swapoff(const char*) __nonnull((1));\n\n__END_DECLS\n\n#endif /* _SYS_SWAP_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/syscall.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_SYSCALL_H_\n#define _SYS_SYSCALL_H_\n\n#include <asm/unistd.h> /* Linux kernel __NR_* names. */\n#include <sys/glibc-syscalls.h> /* glibc-compatible SYS_* aliases. */\n\n/* The syscall function itself is declared in <unistd.h>, not here. */\n\n#endif /* _SYS_SYSCALL_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/sysconf.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_SYSCONF_H_\n#define _SYS_SYSCONF_H_\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\n/* as listed by Posix sysconf() description */\n/* most of these will return -1 and ENOSYS  */\n\n#define _SC_ARG_MAX             0x0000\n#define _SC_BC_BASE_MAX         0x0001\n#define _SC_BC_DIM_MAX          0x0002\n#define _SC_BC_SCALE_MAX        0x0003\n#define _SC_BC_STRING_MAX       0x0004\n#define _SC_CHILD_MAX           0x0005\n#define _SC_CLK_TCK             0x0006\n#define _SC_COLL_WEIGHTS_MAX    0x0007\n#define _SC_EXPR_NEST_MAX       0x0008\n#define _SC_LINE_MAX            0x0009\n#define _SC_NGROUPS_MAX         0x000a\n#define _SC_OPEN_MAX            0x000b\n#define _SC_PASS_MAX            0x000c\n#define _SC_2_C_BIND            0x000d\n#define _SC_2_C_DEV             0x000e\n#define _SC_2_C_VERSION         0x000f  /* Obsolescent in POSIX.1-2008, TODO: remove it. */\n#define _SC_2_CHAR_TERM         0x0010\n#define _SC_2_FORT_DEV          0x0011\n#define _SC_2_FORT_RUN          0x0012\n#define _SC_2_LOCALEDEF         0x0013\n#define _SC_2_SW_DEV            0x0014\n#define _SC_2_UPE               0x0015\n#define _SC_2_VERSION           0x0016\n#define _SC_JOB_CONTROL         0x0017\n#define _SC_SAVED_IDS           0x0018\n#define _SC_VERSION             0x0019\n#define _SC_RE_DUP_MAX          0x001a\n#define _SC_STREAM_MAX          0x001b\n#define _SC_TZNAME_MAX          0x001c\n#define _SC_XOPEN_CRYPT         0x001d\n#define _SC_XOPEN_ENH_I18N      0x001e\n#define _SC_XOPEN_SHM           0x001f\n#define _SC_XOPEN_VERSION       0x0020\n#define _SC_XOPEN_XCU_VERSION   0x0021  /* Obsolescent in POSIX.1-2008, TODO: remove it. */\n#define _SC_XOPEN_REALTIME      0x0022\n#define _SC_XOPEN_REALTIME_THREADS  0x0023\n#define _SC_XOPEN_LEGACY        0x0024\n#define _SC_ATEXIT_MAX          0x0025\n#define _SC_IOV_MAX             0x0026\n#define _SC_PAGESIZE            0x0027\n#define _SC_PAGE_SIZE           0x0028\n#define _SC_XOPEN_UNIX          0x0029\n#define _SC_XBS5_ILP32_OFF32    0x002a  /* Obsolescent in POSIX.1-2008, TODO: remove it. */\n#define _SC_XBS5_ILP32_OFFBIG   0x002b  /* Obsolescent in POSIX.1-2008, TODO: remove it. */\n#define _SC_XBS5_LP64_OFF64     0x002c  /* Obsolescent in POSIX.1-2008, TODO: remove it. */\n#define _SC_XBS5_LPBIG_OFFBIG   0x002d  /* Obsolescent in POSIX.1-2008, TODO: remove it. */\n#define _SC_AIO_LISTIO_MAX      0x002e\n#define _SC_AIO_MAX             0x002f\n#define _SC_AIO_PRIO_DELTA_MAX  0x0030\n#define _SC_DELAYTIMER_MAX      0x0031\n#define _SC_MQ_OPEN_MAX         0x0032\n#define _SC_MQ_PRIO_MAX         0x0033\n#define _SC_RTSIG_MAX           0x0034\n#define _SC_SEM_NSEMS_MAX       0x0035\n#define _SC_SEM_VALUE_MAX       0x0036\n#define _SC_SIGQUEUE_MAX        0x0037\n#define _SC_TIMER_MAX           0x0038\n#define _SC_ASYNCHRONOUS_IO     0x0039\n#define _SC_FSYNC               0x003a\n#define _SC_MAPPED_FILES        0x003b\n#define _SC_MEMLOCK             0x003c\n#define _SC_MEMLOCK_RANGE       0x003d\n#define _SC_MEMORY_PROTECTION   0x003e\n#define _SC_MESSAGE_PASSING     0x003f\n#define _SC_PRIORITIZED_IO      0x0040\n#define _SC_PRIORITY_SCHEDULING 0x0041\n#define _SC_REALTIME_SIGNALS    0x0042\n#define _SC_SEMAPHORES          0x0043\n#define _SC_SHARED_MEMORY_OBJECTS  0x0044\n#define _SC_SYNCHRONIZED_IO     0x0045\n#define _SC_TIMERS              0x0046\n#define _SC_GETGR_R_SIZE_MAX    0x0047\n#define _SC_GETPW_R_SIZE_MAX    0x0048\n#define _SC_LOGIN_NAME_MAX      0x0049\n#define _SC_THREAD_DESTRUCTOR_ITERATIONS  0x004a\n#define _SC_THREAD_KEYS_MAX     0x004b\n#define _SC_THREAD_STACK_MIN    0x004c\n#define _SC_THREAD_THREADS_MAX  0x004d\n#define _SC_TTY_NAME_MAX        0x004e\n\n#define _SC_THREADS                     0x004f\n#define _SC_THREAD_ATTR_STACKADDR       0x0050\n#define _SC_THREAD_ATTR_STACKSIZE       0x0051\n#define _SC_THREAD_PRIORITY_SCHEDULING  0x0052\n#define _SC_THREAD_PRIO_INHERIT         0x0053\n#define _SC_THREAD_PRIO_PROTECT         0x0054\n#define _SC_THREAD_SAFE_FUNCTIONS       0x0055\n\n#define _SC_NPROCESSORS_CONF            0x0060\n#define _SC_NPROCESSORS_ONLN            0x0061\n#define _SC_PHYS_PAGES                  0x0062\n#define _SC_AVPHYS_PAGES                0x0063\n#define _SC_MONOTONIC_CLOCK             0x0064\n\n#define _SC_2_PBS               0x0065\n#define _SC_2_PBS_ACCOUNTING    0x0066\n#define _SC_2_PBS_CHECKPOINT    0x0067\n#define _SC_2_PBS_LOCATE        0x0068\n#define _SC_2_PBS_MESSAGE       0x0069\n#define _SC_2_PBS_TRACK         0x006a\n#define _SC_ADVISORY_INFO       0x006b\n#define _SC_BARRIERS            0x006c\n#define _SC_CLOCK_SELECTION     0x006d\n#define _SC_CPUTIME             0x006e\n#define _SC_HOST_NAME_MAX       0x006f\n#define _SC_IPV6                0x0070\n#define _SC_RAW_SOCKETS         0x0071\n#define _SC_READER_WRITER_LOCKS 0x0072\n#define _SC_REGEXP              0x0073\n#define _SC_SHELL               0x0074\n#define _SC_SPAWN               0x0075\n#define _SC_SPIN_LOCKS          0x0076\n#define _SC_SPORADIC_SERVER     0x0077\n#define _SC_SS_REPL_MAX         0x0078\n#define _SC_SYMLOOP_MAX         0x0079\n#define _SC_THREAD_CPUTIME      0x007a\n#define _SC_THREAD_PROCESS_SHARED       0x007b\n#define _SC_THREAD_ROBUST_PRIO_INHERIT  0x007c\n#define _SC_THREAD_ROBUST_PRIO_PROTECT  0x007d\n#define _SC_THREAD_SPORADIC_SERVER      0x007e\n#define _SC_TIMEOUTS            0x007f\n#define _SC_TRACE               0x0080\n#define _SC_TRACE_EVENT_FILTER  0x0081\n#define _SC_TRACE_EVENT_NAME_MAX  0x0082\n#define _SC_TRACE_INHERIT       0x0083\n#define _SC_TRACE_LOG           0x0084\n#define _SC_TRACE_NAME_MAX      0x0085\n#define _SC_TRACE_SYS_MAX       0x0086\n#define _SC_TRACE_USER_EVENT_MAX  0x0087\n#define _SC_TYPED_MEMORY_OBJECTS  0x0088\n#define _SC_V7_ILP32_OFF32      0x0089\n#define _SC_V7_ILP32_OFFBIG     0x008a\n#define _SC_V7_LP64_OFF64       0x008b\n#define _SC_V7_LPBIG_OFFBIG     0x008c\n#define _SC_XOPEN_STREAMS       0x008d\n#define _SC_XOPEN_UUCP          0x008e\n\n#define _SC_LEVEL1_ICACHE_SIZE      0x008f\n#define _SC_LEVEL1_ICACHE_ASSOC     0x0090\n#define _SC_LEVEL1_ICACHE_LINESIZE  0x0091\n#define _SC_LEVEL1_DCACHE_SIZE      0x0092\n#define _SC_LEVEL1_DCACHE_ASSOC     0x0093\n#define _SC_LEVEL1_DCACHE_LINESIZE  0x0094\n#define _SC_LEVEL2_CACHE_SIZE       0x0095\n#define _SC_LEVEL2_CACHE_ASSOC      0x0096\n#define _SC_LEVEL2_CACHE_LINESIZE   0x0097\n#define _SC_LEVEL3_CACHE_SIZE       0x0098\n#define _SC_LEVEL3_CACHE_ASSOC      0x0099\n#define _SC_LEVEL3_CACHE_LINESIZE   0x009a\n#define _SC_LEVEL4_CACHE_SIZE       0x009b\n#define _SC_LEVEL4_CACHE_ASSOC      0x009c\n#define _SC_LEVEL4_CACHE_LINESIZE   0x009d\n\nlong sysconf(int);\n\n__END_DECLS\n\n#endif /* _SYS_SYSCONF_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/sysinfo.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_SYSINFO_H_\n#define _SYS_SYSINFO_H_\n\n#include <sys/cdefs.h>\n#include <linux/kernel.h>\n\n__BEGIN_DECLS\n\nint sysinfo(struct sysinfo* info);\n\nint get_nprocs_conf(void);\n\nint get_nprocs(void);\n\nlong get_phys_pages(void);\n\nlong get_avphys_pages(void);\n\n__END_DECLS\n\n#endif /* _SYS_SYSINFO_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/syslimits.h",
    "content": ""
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/syslog.h",
    "content": "#include <syslog.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/sysmacros.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_SYSMACROS_H_\n#define _SYS_SYSMACROS_H_\n\n#define makedev(__major, __minor) \\\n  ( \\\n    (((__major) & 0xfffff000ULL) << 32) | (((__major) & 0xfffULL) << 8) | \\\n    (((__minor) & 0xffffff00ULL) << 12) | (((__minor) & 0xffULL)) \\\n  )\n\n#define major(__dev) \\\n  ((unsigned) ((((unsigned long long) (__dev) >> 32) & 0xfffff000) | (((__dev) >> 8) & 0xfff)))\n\n#define minor(__dev) \\\n  ((unsigned) ((((__dev) >> 12) & 0xffffff00) | ((__dev) & 0xff)))\n\n#endif /* _SYS_SYSMACROS_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/system_properties.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _INCLUDE_SYS_SYSTEM_PROPERTIES_H\n#define _INCLUDE_SYS_SYSTEM_PROPERTIES_H\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\ntypedef struct prop_info prop_info;\n\n#define PROP_NAME_MAX   32\n#define PROP_VALUE_MAX  92\n\n/* Look up a system property by name, copying its value and a\n** \\0 terminator to the provided pointer.  The total bytes\n** copied will be no greater than PROP_VALUE_MAX.  Returns\n** the string length of the value.  A property that is not\n** defined is identical to a property with a length 0 value.\n*/\nint __system_property_get(const char *name, char *value);\n\n/* Set a system property by name.\n**/\nint __system_property_set(const char *key, const char *value);\n\n/* Return a pointer to the system property named name, if it\n** exists, or NULL if there is no such property.  Use \n** __system_property_read() to obtain the string value from\n** the returned prop_info pointer.\n**\n** It is safe to cache the prop_info pointer to avoid future\n** lookups.  These returned pointers will remain valid for\n** the lifetime of the system.\n*/\nconst prop_info *__system_property_find(const char *name);\n\n/* Read the value of a system property.  Returns the length\n** of the value.  Copies the value and \\0 terminator into\n** the provided value pointer.  Total length (including\n** terminator) will be no greater that PROP_VALUE_MAX.\n**\n** If name is nonzero, up to PROP_NAME_MAX bytes will be\n** copied into the provided name pointer.  The name will\n** be \\0 terminated.\n*/\nint __system_property_read(const prop_info *pi, char *name, char *value);\n\n/* Return a prop_info for the nth system property, or NULL if \n** there is no nth property.  Use __system_property_read() to\n** read the value of this property.\n**\n** Please do not call this method.  It only exists to provide\n** backwards compatibility to NDK apps.  Its implementation\n** is inefficient and order of results may change from call\n** to call.\n*/ \nconst prop_info *__system_property_find_nth(unsigned n);\n\n/* Pass a prop_info for each system property to the provided\n** callback.  Use __system_property_read() to read the value\n** of this property.\n**\n** This method is for inspecting and debugging the property\n** system.  Please use __system_property_find() instead.\n**\n** Order of results may change from call to call.  This is\n** not a bug.\n*/\nint __system_property_foreach(\n        void (*propfn)(const prop_info *pi, void *cookie),\n        void *cookie);\n\n__END_DECLS\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/time.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_TIME_H_\n#define _SYS_TIME_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <linux/time.h>\n\n/* POSIX says <sys/time.h> gets you most of <sys/select.h> and may get you all of it. */\n#include <sys/select.h>\n\n__BEGIN_DECLS\n\nextern int gettimeofday(struct timeval *, struct timezone *);\nextern int settimeofday(const struct timeval *, const struct timezone *);\n\nextern int getitimer(int, struct itimerval *);\nextern int setitimer(int, const struct itimerval *, struct itimerval *);\n\nextern int utimes(const char *, const struct timeval *);\n\n#define timerclear(a)   \\\n        ((a)->tv_sec = (a)->tv_usec = 0)\n\n#define timerisset(a)    \\\n        ((a)->tv_sec != 0 || (a)->tv_usec != 0)\n\n#define timercmp(a, b, op)               \\\n        ((a)->tv_sec == (b)->tv_sec      \\\n        ? (a)->tv_usec op (b)->tv_usec   \\\n        : (a)->tv_sec op (b)->tv_sec)\n\n#define timeradd(a, b, res)                           \\\n    do {                                              \\\n        (res)->tv_sec  = (a)->tv_sec  + (b)->tv_sec;  \\\n        (res)->tv_usec = (a)->tv_usec + (b)->tv_usec; \\\n        if ((res)->tv_usec >= 1000000) {              \\\n            (res)->tv_usec -= 1000000;                \\\n            (res)->tv_sec  += 1;                      \\\n        }                                             \\\n    } while (0)\n\n#define timersub(a, b, res)                           \\\n    do {                                              \\\n        (res)->tv_sec  = (a)->tv_sec  - (b)->tv_sec;  \\\n        (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \\\n        if ((res)->tv_usec < 0) {                     \\\n            (res)->tv_usec += 1000000;                \\\n            (res)->tv_sec  -= 1;                      \\\n        }                                             \\\n    } while (0)\n\n#define TIMEVAL_TO_TIMESPEC(tv, ts) {     \\\n    (ts)->tv_sec = (tv)->tv_sec;          \\\n    (ts)->tv_nsec = (tv)->tv_usec * 1000; \\\n}\n#define TIMESPEC_TO_TIMEVAL(tv, ts) {     \\\n    (tv)->tv_sec = (ts)->tv_sec;          \\\n    (tv)->tv_usec = (ts)->tv_nsec / 1000; \\\n}\n\n__END_DECLS\n\n#endif /* _SYS_TIME_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/timerfd.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_TIMERFD_H_\n#define _SYS_TIMERFD_H_\n\n#include <fcntl.h> /* For O_CLOEXEC and O_NONBLOCK. */\n#include <time.h>\n#include <sys/types.h>\n\n__BEGIN_DECLS\n\n#define TFD_TIMER_ABSTIME (1 << 0)\n#define TFD_TIMER_CANCEL_ON_SET (1 << 1)\n\n#define TFD_CLOEXEC O_CLOEXEC\n#define TFD_NONBLOCK O_NONBLOCK\n\nextern int timerfd_create(clockid_t, int);\nextern int timerfd_settime(int, int, const struct itimerspec*,\n                           struct itimerspec*);\nextern int timerfd_gettime(int, struct itimerspec*);\n\n__END_DECLS\n\n#endif /* _SYS_TIMERFD_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/times.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_TIMES_H_\n#define _SYS_TIMES_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <linux/times.h>\n\n__BEGIN_DECLS\n\nextern clock_t times(struct tms*);\n\n__END_DECLS\n\n#endif /* _SYS_TIMES_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/timex.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_TIMEX_H_\n#define _SYS_TIMEX_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <linux/timex.h>\n\n__BEGIN_DECLS\n\nint adjtimex(struct timex*);\nint clock_adjtime(clockid_t, struct timex*);\n\n__END_DECLS\n\n#endif /* _SYS_TIMEX_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/ttychars.h",
    "content": ""
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/ttydefaults.h",
    "content": "/*\t$NetBSD: ttydefaults.h,v 1.16 2008/05/24 14:06:39 yamt Exp $\t*/\n\n/*-\n * Copyright (c) 1982, 1986, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n * (c) UNIX System Laboratories, Inc.\n * All or some portions of this file are derived from material licensed\n * to the University of California by American Telephone and Telegraph\n * Co. or Unix System Laboratories, Inc. and are reproduced herein with\n * the permission of UNIX System Laboratories, Inc.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)ttydefaults.h\t8.4 (Berkeley) 1/21/94\n */\n\n/*\n * System wide defaults for terminal state.\n */\n#ifndef _SYS_TTYDEFAULTS_H_\n#define\t_SYS_TTYDEFAULTS_H_\n\n/*\n * Defaults on \"first\" open.\n */\n#define\tTTYDEF_IFLAG\t(BRKINT | ICRNL | IMAXBEL | IXON | IXANY)\n#define TTYDEF_OFLAG\t(OPOST | ONLCR | OXTABS)\n#define TTYDEF_LFLAG\t(ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL)\n#define TTYDEF_CFLAG\t(CREAD | CS8 | HUPCL)\n#define TTYDEF_SPEED\t(B9600)\n\n/*\n * Control Character Defaults\n */\n#define CTRL(x)\t(x&037)\n#define\tCEOF\t\tCTRL('d')\n#define\tCEOL\t\t((unsigned char)'\\377')\t/* XXX avoid _POSIX_VDISABLE */\n#define\tCERASE\t\t0177\n#define\tCINTR\t\tCTRL('c')\n#define\tCSTATUS\t\tCTRL('t')\n#define\tCKILL\t\tCTRL('u')\n#define\tCMIN\t\t1\n#define\tCQUIT\t\t034\t\t/* FS, ^\\ */\n#define\tCSUSP\t\tCTRL('z')\n#define\tCTIME\t\t0\n#define\tCDSUSP\t\tCTRL('y')\n#define\tCSTART\t\tCTRL('q')\n#define\tCSTOP\t\tCTRL('s')\n#define\tCLNEXT\t\tCTRL('v')\n#define\tCDISCARD \tCTRL('o')\n#define\tCWERASE \tCTRL('w')\n#define\tCREPRINT \tCTRL('r')\n#define\tCEOT\t\tCEOF\n/* compat */\n#define\tCBRK\t\tCEOL\n#define CRPRNT\t\tCREPRINT\n#define\tCFLUSH\t\tCDISCARD\n\n/* PROTECTED INCLUSION ENDS HERE */\n#endif /* !_SYS_TTYDEFAULTS_H_ */\n\n/*\n * #define TTYDEFCHARS to include an array of default control characters.\n */\n#ifdef _KERNEL\n#ifdef TTYDEFCHARS\nconst cc_t ttydefchars[NCCS] = {\n\t[VEOF] = CEOF,\n\t[VEOL] = CEOL,\n\t[VEOL2] = CEOL,\n\t[VERASE] = CERASE,\n\t[VWERASE] = CWERASE,\n\t[VKILL] = CKILL,\n\t[VREPRINT] = CREPRINT,\n\t[7] = _POSIX_VDISABLE,\t/* spare */\n\t[VINTR] = CINTR,\n\t[VQUIT] = CQUIT,\n\t[VSUSP] = CSUSP,\n\t[VDSUSP] = CDSUSP,\n\t[VSTART] = CSTART,\n\t[VSTOP] = CSTOP,\n\t[VLNEXT] = CLNEXT,\n\t[VDISCARD] = CDISCARD,\n\t[VMIN] = CMIN,\n\t[VTIME] = CTIME,\n\t[VSTATUS] = CSTATUS,\n\t[19] = _POSIX_VDISABLE,\t/* spare */\n};\n#undef TTYDEFCHARS\n#else\nextern const cc_t ttydefchars[NCCS];\n#endif\n#endif /* _KERNEL */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/ttydev.h",
    "content": ""
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/types.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_TYPES_H_\n#define _SYS_TYPES_H_\n\n#include <stddef.h>\n#include <stdint.h>\n#include <sys/cdefs.h>\n\n#include <linux/types.h>\n#include <linux/posix_types.h>\n\n/* gids, uids, and pids are all 32-bit. */\ntypedef __kernel_gid32_t __gid_t;\ntypedef __gid_t gid_t;\ntypedef __kernel_uid32_t __uid_t;\ntypedef __uid_t uid_t;\ntypedef __kernel_pid_t __pid_t;\ntypedef __pid_t pid_t;\ntypedef uint32_t __id_t;\ntypedef __id_t id_t;\n\ntypedef unsigned long blkcnt_t;\ntypedef unsigned long blksize_t;\ntypedef __kernel_caddr_t caddr_t;\ntypedef __kernel_clock_t clock_t;\n\ntypedef __kernel_clockid_t __clockid_t;\ntypedef __clockid_t clockid_t;\n\ntypedef __kernel_daddr_t daddr_t;\ntypedef unsigned long fsblkcnt_t;\ntypedef unsigned long fsfilcnt_t;\n\ntypedef __kernel_mode_t __mode_t;\ntypedef __mode_t mode_t;\n\ntypedef __kernel_key_t __key_t;\ntypedef __key_t key_t;\n\ntypedef __kernel_ino_t __ino_t;\ntypedef __ino_t ino_t;\n\ntypedef uint32_t __nlink_t;\ntypedef __nlink_t nlink_t;\n\ntypedef void* __timer_t;\ntypedef __timer_t timer_t;\n\ntypedef __kernel_suseconds_t __suseconds_t;\ntypedef __suseconds_t suseconds_t;\n\n/* useconds_t is 32-bit on both LP32 and LP64. */\ntypedef uint32_t __useconds_t;\ntypedef __useconds_t useconds_t;\n\n#if !defined(__LP64__)\n/* This historical accident means that we had a 32-bit dev_t on 32-bit architectures. */\ntypedef uint32_t dev_t;\n#else\ntypedef uint64_t dev_t;\n#endif\n\n/* This historical accident means that we had a 32-bit time_t on 32-bit architectures. */\ntypedef __kernel_time_t __time_t;\ntypedef __time_t time_t;\n\n#if defined(__USE_FILE_OFFSET64) || defined(__LP64__)\ntypedef int64_t off_t;\ntypedef off_t loff_t;\ntypedef loff_t off64_t;\n#else\n/* This historical accident means that we had a 32-bit off_t on 32-bit architectures. */\ntypedef __kernel_off_t off_t;\ntypedef __kernel_loff_t loff_t;\ntypedef loff_t off64_t;\n#endif\n\n/* while POSIX wants these in <sys/types.h>, we\n * declare then in <pthread.h> instead */\n#if 0\ntypedef  .... pthread_attr_t;\ntypedef  .... pthread_cond_t;\ntypedef  .... pthread_condattr_t;\ntypedef  .... pthread_key_t;\ntypedef  .... pthread_mutex_t;\ntypedef  .... pthread_once_t;\ntypedef  .... pthread_rwlock_t;\ntypedef  .... pthread_rwlock_attr_t;\ntypedef  .... pthread_t;\n#endif\n\n#if !defined(__LP64__)\n/* This historical accident means that we had a signed socklen_t on 32-bit architectures. */\ntypedef int32_t __socklen_t;\n#else\n/* LP64 still has a 32-bit socklen_t. */\ntypedef uint32_t __socklen_t;\n#endif\ntypedef __socklen_t socklen_t;\n\ntypedef __builtin_va_list __va_list;\n\n#ifndef _SSIZE_T_DEFINED_\n#define _SSIZE_T_DEFINED_\n/* Traditionally, bionic's ssize_t was \"long int\". This caused GCC to emit warnings when you\n * pass a ssize_t to a printf-style function. The correct type is __kernel_ssize_t, which is\n * \"int\", which isn't an ABI change for C code (because they're the same size) but is an ABI\n * change for C++ because \"int\" and \"long int\" mangle to \"i\" and \"l\" respectively. So until\n * we can fix the ABI, this change should not be propagated to the NDK. http://b/8253769. */\ntypedef __kernel_ssize_t ssize_t;\n#endif\n\ntypedef unsigned int        uint_t;\ntypedef unsigned int        uint;\n\n#ifdef __BSD_VISIBLE\n#include <sys/sysmacros.h>\n\ntypedef unsigned char  u_char;\ntypedef unsigned short u_short;\ntypedef unsigned int   u_int;\ntypedef unsigned long  u_long;\n\ntypedef uint32_t u_int32_t;\ntypedef uint16_t u_int16_t;\ntypedef uint8_t  u_int8_t;\ntypedef uint64_t u_int64_t;\n#endif\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/ucontext.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_UCONTEXT_H_\n#define _SYS_UCONTEXT_H_\n\n#include <signal.h>\n#include <sys/user.h>\n\n__BEGIN_DECLS\n\n#if defined(__arm__)\n\nenum {\n  REG_R0 = 0,\n  REG_R1,\n  REG_R2,\n  REG_R3,\n  REG_R4,\n  REG_R5,\n  REG_R6,\n  REG_R7,\n  REG_R8,\n  REG_R9,\n  REG_R10,\n  REG_R11,\n  REG_R12,\n  REG_R13,\n  REG_R14,\n  REG_R15,\n};\n\n#define NGREG 18 /* Like glibc. */\n\ntypedef int greg_t;\ntypedef greg_t gregset_t[NGREG];\ntypedef struct user_fpregs fpregset_t;\n\n#include <asm/sigcontext.h>\ntypedef struct sigcontext mcontext_t;\n\ntypedef struct ucontext {\n  unsigned long uc_flags;\n  struct ucontext* uc_link;\n  stack_t uc_stack;\n  mcontext_t uc_mcontext;\n  sigset_t uc_sigmask;\n  // Android has a wrong (smaller) sigset_t on ARM.\n  uint32_t __padding_rt_sigset;\n  // The kernel adds extra padding after uc_sigmask to match glibc sigset_t on ARM.\n  char __padding[120];\n  unsigned long uc_regspace[128] __attribute__((__aligned__(8)));\n} ucontext_t;\n\n#elif defined(__aarch64__)\n\n#define NGREG 34 /* x0..x30 + sp + pc + pstate */\ntypedef unsigned long greg_t;\ntypedef greg_t gregset_t[NGREG];\ntypedef struct user_fpsimd_struct fpregset_t;\n\n#include <asm/sigcontext.h>\ntypedef struct sigcontext mcontext_t;\n\ntypedef struct ucontext {\n  unsigned long uc_flags;\n  struct ucontext *uc_link;\n  stack_t uc_stack;\n  sigset_t uc_sigmask;\n  // The kernel adds extra padding after uc_sigmask to match glibc sigset_t on ARM64.\n  char __padding[128 - sizeof(sigset_t)];\n  mcontext_t uc_mcontext;\n} ucontext_t;\n\n#elif defined(__i386__)\n\nenum {\n  REG_GS = 0,\n  REG_FS,\n  REG_ES,\n  REG_DS,\n  REG_EDI,\n  REG_ESI,\n  REG_EBP,\n  REG_ESP,\n  REG_EBX,\n  REG_EDX,\n  REG_ECX,\n  REG_EAX,\n  REG_TRAPNO,\n  REG_ERR,\n  REG_EIP,\n  REG_CS,\n  REG_EFL,\n  REG_UESP,\n  REG_SS,\n  NGREG\n};\n\ntypedef int greg_t;\ntypedef greg_t gregset_t[NGREG];\n\nstruct _libc_fpreg {\n  unsigned short significand[4];\n  unsigned short exponent;\n};\n\nstruct _libc_fpstate {\n  unsigned long cw;\n  unsigned long sw;\n  unsigned long tag;\n  unsigned long ipoff;\n  unsigned long cssel;\n  unsigned long dataoff;\n  unsigned long datasel;\n  struct _libc_fpreg _st[8];\n  unsigned long status;\n};\n\ntypedef struct _libc_fpstate* fpregset_t;\n\ntypedef struct {\n  gregset_t gregs;\n  fpregset_t fpregs;\n  unsigned long oldmask;\n  unsigned long cr2;\n} mcontext_t;\n\ntypedef struct ucontext {\n  unsigned long uc_flags;\n  struct ucontext* uc_link;\n  stack_t uc_stack;\n  mcontext_t uc_mcontext;\n  sigset_t uc_sigmask;\n  // Android has a wrong (smaller) sigset_t on x86.\n  uint32_t __padding_rt_sigset;\n  struct _libc_fpstate __fpregs_mem;\n} ucontext_t;\n\n#elif defined(__mips__)\n\n/* glibc doesn't have names for MIPS registers. */\n\n#define NGREG 32\n#define NFPREG 32\n\ntypedef unsigned long long greg_t;\ntypedef greg_t gregset_t[NGREG];\n\ntypedef struct fpregset {\n  union {\n    double fp_dregs[NFPREG];\n    struct {\n      float _fp_fregs;\n      unsigned _fp_pad;\n    } fp_fregs[NFPREG];\n  } fp_r;\n} fpregset_t;\n\n#ifdef __LP64__\ntypedef struct {\n  gregset_t gregs;\n  fpregset_t fpregs;\n  greg_t mdhi;\n  greg_t hi1;\n  greg_t hi2;\n  greg_t hi3;\n  greg_t mdlo;\n  greg_t lo1;\n  greg_t lo2;\n  greg_t lo3;\n  greg_t pc;\n  uint32_t fpc_csr;\n  uint32_t used_math;\n  uint32_t dsp;\n  uint32_t reserved;\n} mcontext_t;\n#else\ntypedef struct {\n  unsigned regmask;\n  unsigned status;\n  greg_t pc;\n  gregset_t gregs;\n  fpregset_t fpregs;\n  unsigned fp_owned;\n  unsigned fpc_csr;\n  unsigned fpc_eir;\n  unsigned used_math;\n  unsigned dsp;\n  greg_t mdhi;\n  greg_t mdlo;\n  unsigned long hi1;\n  unsigned long lo1;\n  unsigned long hi2;\n  unsigned long lo2;\n  unsigned long hi3;\n  unsigned long lo3;\n} mcontext_t;\n#endif\n\ntypedef struct ucontext {\n  unsigned long uc_flags;\n  struct ucontext* uc_link;\n  stack_t uc_stack;\n  mcontext_t uc_mcontext;\n  sigset_t uc_sigmask;\n} ucontext_t;\n\n#elif defined(__x86_64__)\n\nenum {\n  REG_R8 = 0,\n  REG_R9,\n  REG_R10,\n  REG_R11,\n  REG_R12,\n  REG_R13,\n  REG_R14,\n  REG_R15,\n  REG_RDI,\n  REG_RSI,\n  REG_RBP,\n  REG_RBX,\n  REG_RDX,\n  REG_RAX,\n  REG_RCX,\n  REG_RSP,\n  REG_RIP,\n  REG_EFL,\n  REG_CSGSFS,\n  REG_ERR,\n  REG_TRAPNO,\n  REG_OLDMASK,\n  REG_CR2,\n  NGREG\n};\n\ntypedef long greg_t;\ntypedef greg_t gregset_t[NGREG];\n\nstruct _libc_fpxreg {\n  unsigned short significand[4];\n  unsigned short exponent;\n  unsigned short padding[3];\n};\n\nstruct _libc_xmmreg {\n  uint32_t element[4];\n};\n\nstruct _libc_fpstate {\n  uint16_t cwd;\n  uint16_t swd;\n  uint16_t ftw;\n  uint16_t fop;\n  uint64_t rip;\n  uint64_t rdp;\n  uint32_t mxcsr;\n  uint32_t mxcr_mask;\n  struct _libc_fpxreg _st[8];\n  struct _libc_xmmreg _xmm[16];\n  uint32_t padding[24];\n};\n\ntypedef struct _libc_fpstate* fpregset_t;\n\ntypedef struct {\n  gregset_t gregs;\n  fpregset_t fpregs;\n  unsigned long __reserved1[8];\n} mcontext_t;\n\ntypedef struct ucontext {\n  unsigned long uc_flags;\n  struct ucontext* uc_link;\n  stack_t uc_stack;\n  mcontext_t uc_mcontext;\n  sigset_t uc_sigmask;\n  struct _libc_fpstate __fpregs_mem;\n} ucontext_t;\n\n#endif\n\n__END_DECLS\n\n#endif /* _SYS_UCONTEXT_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/uio.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_UIO_H_\n#define _SYS_UIO_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <linux/uio.h>\n\n__BEGIN_DECLS\n\nint readv(int, const struct iovec*, int);\nint writev(int, const struct iovec*, int);\n\n#if defined(__USE_GNU)\n#if defined(__USE_FILE_OFFSET64)\nssize_t preadv(int, const struct iovec*, int, off_t) __RENAME(preadv64);\nssize_t pwritev(int, const struct iovec*, int, off_t) __RENAME(pwritev64);\n#else\nssize_t preadv(int, const struct iovec*, int, off_t);\nssize_t pwritev(int, const struct iovec*, int, off_t);\n#endif\nssize_t preadv64(int, const struct iovec*, int, off64_t);\nssize_t pwritev64(int, const struct iovec*, int, off64_t);\n#endif\n\n#if defined(__USE_GNU)\nssize_t process_vm_readv(pid_t, const struct iovec*, unsigned long, const struct iovec*, unsigned long, unsigned long);\nssize_t process_vm_writev(pid_t, const struct iovec*, unsigned long, const struct iovec*, unsigned long, unsigned long);\n#endif\n\n__END_DECLS\n\n#endif /* _SYS_UIO_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/un.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_UN_H_\n#define _SYS_UN_H_\n\ntypedef unsigned short sa_family_t;\n\n#include <linux/un.h>\n\n#endif /* _SYS_UN_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/unistd.h",
    "content": "#include <unistd.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/user.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_USER_H_\n#define _SYS_USER_H_\n\n#include <sys/cdefs.h>\n#include <stddef.h> /* For size_t. */\n\n__BEGIN_DECLS\n\n#define PAGE_SIZE 4096\n#define PAGE_MASK (~(PAGE_SIZE - 1))\n\n#if __i386__\n\nstruct user_fpregs_struct {\n  long cwd;\n  long swd;\n  long twd;\n  long fip;\n  long fcs;\n  long foo;\n  long fos;\n  long st_space[20];\n};\nstruct user_fpxregs_struct {\n  unsigned short cwd;\n  unsigned short swd;\n  unsigned short twd;\n  unsigned short fop;\n  long fip;\n  long fcs;\n  long foo;\n  long fos;\n  long mxcsr;\n  long reserved;\n  long st_space[32];\n  long xmm_space[32];\n  long padding[56];\n};\nstruct user_regs_struct {\n  long ebx;\n  long ecx;\n  long edx;\n  long esi;\n  long edi;\n  long ebp;\n  long eax;\n  long xds;\n  long xes;\n  long xfs;\n  long xgs;\n  long orig_eax;\n  long eip;\n  long xcs;\n  long eflags;\n  long esp;\n  long xss;\n};\nstruct user {\n  struct user_regs_struct regs;\n  int u_fpvalid;\n  struct user_fpregs_struct i387;\n  unsigned long int u_tsize;\n  unsigned long int u_dsize;\n  unsigned long int u_ssize;\n  unsigned long start_code;\n  unsigned long start_stack;\n  long int signal;\n  int reserved;\n  struct user_regs_struct* u_ar0;\n  struct user_fpregs_struct* u_fpstate;\n  unsigned long magic;\n  char u_comm[32];\n  int u_debugreg[8];\n};\n\n#elif defined(__x86_64__)\n\nstruct user_fpregs_struct {\n  unsigned short cwd;\n  unsigned short swd;\n  unsigned short ftw;\n  unsigned short fop;\n  __u64 rip;\n  __u64 rdp;\n  __u32 mxcsr;\n  __u32 mxcr_mask;\n  __u32 st_space[32];\n  __u32 xmm_space[64];\n  __u32 padding[24];\n};\nstruct user_regs_struct {\n  unsigned long r15;\n  unsigned long r14;\n  unsigned long r13;\n  unsigned long r12;\n  unsigned long rbp;\n  unsigned long rbx;\n  unsigned long r11;\n  unsigned long r10;\n  unsigned long r9;\n  unsigned long r8;\n  unsigned long rax;\n  unsigned long rcx;\n  unsigned long rdx;\n  unsigned long rsi;\n  unsigned long rdi;\n  unsigned long orig_rax;\n  unsigned long rip;\n  unsigned long cs;\n  unsigned long eflags;\n  unsigned long rsp;\n  unsigned long ss;\n  unsigned long fs_base;\n  unsigned long gs_base;\n  unsigned long ds;\n  unsigned long es;\n  unsigned long fs;\n  unsigned long gs;\n};\nstruct user {\n  struct user_regs_struct regs;\n  int u_fpvalid;\n  int pad0;\n  struct user_fpregs_struct i387;\n  unsigned long int u_tsize;\n  unsigned long int u_dsize;\n  unsigned long int u_ssize;\n  unsigned long start_code;\n  unsigned long start_stack;\n  long int signal;\n  int reserved;\n  int pad1;\n  struct user_regs_struct* u_ar0;\n  struct user_fpregs_struct* u_fpstate;\n  unsigned long magic;\n  char u_comm[32];\n  unsigned long u_debugreg[8];\n  unsigned long error_code;\n  unsigned long fault_address;\n};\n\n#elif defined(__mips__)\n\nstruct user {\n  unsigned long regs[180 / sizeof(unsigned long) + 64];\n  size_t u_tsize;\n  size_t u_dsize;\n  size_t u_ssize;\n  unsigned long start_code;\n  unsigned long start_data;\n  unsigned long start_stack;\n  long int signal;\n  void* u_ar0;\n  unsigned long magic;\n  char u_comm[32];\n};\n\n#elif defined(__arm__)\n\nstruct user_fpregs {\n  struct fp_reg {\n    unsigned int sign1:1;\n    unsigned int unused:15;\n    unsigned int sign2:1;\n    unsigned int exponent:14;\n    unsigned int j:1;\n    unsigned int mantissa1:31;\n    unsigned int mantissa0:32;\n  } fpregs[8];\n  unsigned int fpsr:32;\n  unsigned int fpcr:32;\n  unsigned char ftype[8];\n  unsigned int init_flag;\n};\nstruct user_regs {\n  unsigned long uregs[18];\n};\nstruct user_vfp {\n  unsigned long long fpregs[32];\n  unsigned long fpscr;\n};\nstruct user_vfp_exc {\n  unsigned long fpexc;\n  unsigned long fpinst;\n  unsigned long fpinst2;\n};\nstruct user {\n  struct user_regs regs;\n  int u_fpvalid;\n  unsigned long int u_tsize;\n  unsigned long int u_dsize;\n  unsigned long int u_ssize;\n  unsigned long start_code;\n  unsigned long start_stack;\n  long int signal;\n  int reserved;\n  struct user_regs* u_ar0;\n  unsigned long magic;\n  char u_comm[32];\n  int u_debugreg[8];\n  struct user_fpregs u_fp;\n  struct user_fpregs* u_fp0;\n};\n\n#elif defined(__aarch64__)\n\nstruct user_regs_struct {\n  uint64_t regs[31];\n  uint64_t sp;\n  uint64_t pc;\n  uint64_t pstate;\n};\nstruct user_fpsimd_struct {\n  __uint128_t vregs[32];\n  uint32_t fpsr;\n  uint32_t fpcr;\n};\n\n#else\n\n#error \"Unsupported architecture.\"\n\n#endif\n\n__END_DECLS\n\n#endif  /* _SYS_USER_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/utime.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_UTIME_H_\n#define _SYS_UTIME_H_\n\n#include <linux/utime.h>\n\n#endif /* _SYS_UTIME_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/utsname.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_UTSNAME_H_\n#define _SYS_UTSNAME_H_\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\n#define SYS_NMLN 65\n\nstruct utsname {\n    char  sysname   [SYS_NMLN];\n    char  nodename  [SYS_NMLN];\n    char  release   [SYS_NMLN];\n    char  version   [SYS_NMLN];\n    char  machine   [SYS_NMLN];\n    char  domainname[SYS_NMLN];\n};\n\nextern int uname(struct utsname *);\n\n__END_DECLS\n\n#endif /* _SYS_UTSNAME_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/vfs.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYS_VFS_H_\n#define _SYS_VFS_H_\n\n#include <stdint.h>\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n__BEGIN_DECLS\n\n/* The kernel's __kernel_fsid_t has a 'val' member but glibc uses '__val'. */\ntypedef struct { int __val[2]; } __fsid_t;\ntypedef __fsid_t fsid_t;\n\n#if defined(__aarch64__) || defined(__x86_64__)\n#define __STATFS64_BODY \\\n  uint64_t f_type; \\\n  uint64_t f_bsize; \\\n  uint64_t f_blocks; \\\n  uint64_t f_bfree; \\\n  uint64_t f_bavail; \\\n  uint64_t f_files; \\\n  uint64_t f_ffree; \\\n  fsid_t f_fsid; \\\n  uint64_t f_namelen; \\\n  uint64_t f_frsize; \\\n  uint64_t f_flags; \\\n  uint64_t f_spare[4]; \\\n\n#elif defined(__mips__) && defined(__LP64__)\n/* 64-bit MIPS. */\n#define __STATFS64_BODY \\\n  uint64_t f_type; \\\n  uint64_t f_bsize; \\\n  uint64_t f_frsize; /* Fragment size - unsupported. */ \\\n  uint64_t f_blocks; \\\n  uint64_t f_bfree; \\\n  uint64_t f_files; \\\n  uint64_t f_ffree; \\\n  uint64_t f_bavail; \\\n  fsid_t f_fsid; \\\n  uint64_t f_namelen; \\\n  uint64_t f_flags; \\\n  uint64_t f_spare[5]; \\\n\n#elif defined(__mips__)\n/* 32-bit MIPS (corresponds to the kernel's statfs64 type). */\n#define __STATFS64_BODY \\\n  uint32_t f_type; \\\n  uint32_t f_bsize; \\\n  uint32_t f_frsize; \\\n  uint32_t __pad; \\\n  uint64_t f_blocks; \\\n  uint64_t f_bfree; \\\n  uint64_t f_files; \\\n  uint64_t f_ffree; \\\n  uint64_t f_bavail; \\\n  fsid_t f_fsid; \\\n  uint32_t f_namelen; \\\n  uint32_t f_flags; \\\n  uint32_t f_spare[5]; \\\n\n#else\n/* 32-bit ARM or x86 (corresponds to the kernel's statfs64 type). */\n#define __STATFS64_BODY \\\n  uint32_t f_type; \\\n  uint32_t f_bsize; \\\n  uint64_t f_blocks; \\\n  uint64_t f_bfree; \\\n  uint64_t f_bavail; \\\n  uint64_t f_files; \\\n  uint64_t f_ffree; \\\n  fsid_t f_fsid; \\\n  uint32_t f_namelen; \\\n  uint32_t f_frsize; \\\n  uint32_t f_flags; \\\n  uint32_t f_spare[4]; \\\n\n#endif\n\nstruct statfs { __STATFS64_BODY };\nstruct statfs64 { __STATFS64_BODY };\n\n#undef __STATFS64_BODY\n\n/* Declare that we have the f_namelen, f_frsize, and f_flags fields. */\n#define _STATFS_F_NAMELEN\n#define _STATFS_F_FRSIZE\n#define _STATFS_F_FLAGS\n\n/* Pull in the kernel magic numbers. */\n#include <linux/magic.h>\n/* Add in ones that we had historically that aren't in the uapi header. */\n#define BEFS_SUPER_MAGIC      0x42465331\n#define BFS_MAGIC             0x1BADFACE\n#define CIFS_MAGIC_NUMBER     0xFF534D42\n#define COH_SUPER_MAGIC       0x012FF7B7\n#define DEVFS_SUPER_MAGIC     0x1373\n#define EXT_SUPER_MAGIC       0x137D\n#define EXT2_OLD_SUPER_MAGIC  0xEF51\n#define HFS_SUPER_MAGIC       0x4244\n#define JFS_SUPER_MAGIC       0x3153464a\n#define NTFS_SB_MAGIC         0x5346544e\n#define ROMFS_MAGIC           0x7275\n#define SYSV2_SUPER_MAGIC     0x012FF7B6\n#define SYSV4_SUPER_MAGIC     0x012FF7B5\n#define UDF_SUPER_MAGIC       0x15013346\n#define UFS_MAGIC             0x00011954\n#define VXFS_SUPER_MAGIC      0xa501FCF5\n#define XENIX_SUPER_MAGIC     0x012FF7B4\n#define XFS_SUPER_MAGIC       0x58465342\n\nextern int statfs(const char*, struct statfs*) __nonnull((1, 2));\nextern int statfs64(const char*, struct statfs64*) __nonnull((1, 2));\nextern int fstatfs(int, struct statfs*) __nonnull((2));\nextern int fstatfs64(int, struct statfs64*) __nonnull((2));\n\n__END_DECLS\n\n#endif /* _SYS_VFS_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/vt.h",
    "content": "#include <linux/vt.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/wait.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_WAIT_H_\n#define _SYS_WAIT_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <sys/resource.h>\n#include <linux/wait.h>\n#include <signal.h>\n\n__BEGIN_DECLS\n\n#define WEXITSTATUS(s)  (((s) & 0xff00) >> 8)\n#define WCOREDUMP(s)    ((s) & 0x80)\n#define WTERMSIG(s)     ((s) & 0x7f)\n#define WSTOPSIG(s)     WEXITSTATUS(s)\n\n#define WIFEXITED(s)    (WTERMSIG(s) == 0)\n#define WIFSTOPPED(s)   (WTERMSIG(s) == 0x7f)\n#define WIFSIGNALED(s)  (WTERMSIG((s)+1) >= 2)\n#define WIFCONTINUED(s) ((s) == 0xffff)\n\n#define W_EXITCODE(ret, sig)    ((ret) << 8 | (sig))\n#define W_STOPCODE(sig)         ((sig) << 8 | 0x7f)\n\nextern pid_t  wait(int *);\nextern pid_t  waitpid(pid_t, int *, int);\nextern pid_t  wait4(pid_t, int *, int, struct rusage *);\n\n/* Posix states that idtype_t should be an enumeration type, but\n * the kernel headers define P_ALL, P_PID and P_PGID as constant macros\n * instead.\n */\ntypedef int idtype_t;\n\nextern int  waitid(idtype_t which, id_t id, siginfo_t *info, int options);\n\n__END_DECLS\n\n#endif /* _SYS_WAIT_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sys/xattr.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _SYS_XATTR_H_\n#define _SYS_XATTR_H_\n\n#include <sys/types.h>\n\n__BEGIN_DECLS\n\n#define XATTR_CREATE 1\n#define XATTR_REPLACE 2\n\nextern int fsetxattr(int fd, const char *name, const void *value, size_t size, int flags);\nextern int setxattr(const char *path, const char *name, const void *value, size_t size, int flags);\nextern int lsetxattr(const char *path, const char *name, const void *value, size_t size, int flags);\n\nextern ssize_t fgetxattr(int fd, const char *name, void *value, size_t size);\nextern ssize_t getxattr(const char *path, const char *name, void *value, size_t size);\nextern ssize_t lgetxattr(const char *path, const char *name, void *value, size_t size);\n\nextern ssize_t listxattr(const char *path, char *list, size_t size);\nextern ssize_t llistxattr(const char *path, char *list, size_t size);\nextern ssize_t flistxattr(int fd, char *list, size_t size);\n\nextern int removexattr(const char *path, const char *name);\nextern int lremovexattr(const char *path, const char *name);\nextern int fremovexattr(int fd, const char *name);\n\n__END_DECLS\n\n#endif /* _SYS_XATTR_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/syscall.h",
    "content": "#include <sys/syscall.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/sysexits.h",
    "content": "/*\t$OpenBSD: sysexits.h,v 1.5 2003/06/02 19:34:12 millert Exp $\t*/\n/*\t$NetBSD: sysexits.h,v 1.4 1994/10/26 00:56:33 cgd Exp $\t*/\n\n/*\n * Copyright (c) 1987 Regents of the University of California.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)sysexits.h\t4.8 (Berkeley) 4/3/91\n */\n\n#ifndef\t_SYSEXITS_H_\n#define\t_SYSEXITS_H_\n\n/*\n *  SYSEXITS.H -- Exit status codes for system programs.\n *\n *\tThis include file attempts to categorize possible error\n *\texit statuses for system programs, notably delivermail\n *\tand the Berkeley network.\n *\n *\tError numbers begin at EX__BASE to reduce the possibility of\n *\tclashing with other exit statuses that random programs may\n *\talready return.  The meaning of the codes is approximately\n *\tas follows:\n *\n *\tEX_USAGE -- The command was used incorrectly, e.g., with\n *\t\tthe wrong number of arguments, a bad flag, a bad\n *\t\tsyntax in a parameter, or whatever.\n *\tEX_DATAERR -- The input data was incorrect in some way.\n *\t\tThis should only be used for user's data & not\n *\t\tsystem files.\n *\tEX_NOINPUT -- An input file (not a system file) did not\n *\t\texist or was not readable.  This could also include\n *\t\terrors like \"No message\" to a mailer (if it cared\n *\t\tto catch it).\n *\tEX_NOUSER -- The user specified did not exist.  This might\n *\t\tbe used for mail addresses or remote logins.\n *\tEX_NOHOST -- The host specified did not exist.  This is used\n *\t\tin mail addresses or network requests.\n *\tEX_UNAVAILABLE -- A service is unavailable.  This can occur\n *\t\tif a support program or file does not exist.  This\n *\t\tcan also be used as a catchall message when something\n *\t\tyou wanted to do doesn't work, but you don't know\n *\t\twhy.\n *\tEX_SOFTWARE -- An internal software error has been detected.\n *\t\tThis should be limited to non-operating system related\n *\t\terrors as possible.\n *\tEX_OSERR -- An operating system error has been detected.\n *\t\tThis is intended to be used for such things as \"cannot\n *\t\tfork\", \"cannot create pipe\", or the like.  It includes\n *\t\tthings like getuid returning a user that does not\n *\t\texist in the passwd file.\n *\tEX_OSFILE -- Some system file (e.g., /etc/passwd, /var/run/utmp,\n *\t\tetc.) does not exist, cannot be opened, or has some\n *\t\tsort of error (e.g., syntax error).\n *\tEX_CANTCREAT -- A (user specified) output file cannot be\n *\t\tcreated.\n *\tEX_IOERR -- An error occurred while doing I/O on some file.\n *\tEX_TEMPFAIL -- temporary failure, indicating something that\n *\t\tis not really an error.  In sendmail, this means\n *\t\tthat a mailer (e.g.) could not create a connection,\n *\t\tand the request should be reattempted later.\n *\tEX_PROTOCOL -- the remote system returned something that\n *\t\twas \"not possible\" during a protocol exchange.\n *\tEX_NOPERM -- You did not have sufficient permission to\n *\t\tperform the operation.  This is not intended for\n *\t\tfile system problems, which should use EX_NOINPUT or\n *\t\tEX_CANTCREAT, but rather for higher level permissions.\n *\tEX_CONFIG -- Something was found in an unconfigured or\n *\t\tmisconfigured state.\n */\n\n#define EX_OK\t\t0\t/* successful termination */\n\n#define EX__BASE\t64\t/* base value for error messages */\n\n#define EX_USAGE\t64\t/* command line usage error */\n#define EX_DATAERR\t65\t/* data format error */\n#define EX_NOINPUT\t66\t/* cannot open input */\n#define EX_NOUSER\t67\t/* addressee unknown */\n#define EX_NOHOST\t68\t/* host name unknown */\n#define EX_UNAVAILABLE\t69\t/* service unavailable */\n#define EX_SOFTWARE\t70\t/* internal software error */\n#define EX_OSERR\t71\t/* system error (e.g., can't fork) */\n#define EX_OSFILE\t72\t/* critical OS file missing */\n#define EX_CANTCREAT\t73\t/* can't create (user) output file */\n#define EX_IOERR\t74\t/* input/output error */\n#define EX_TEMPFAIL\t75\t/* temp failure; user is invited to retry */\n#define EX_PROTOCOL\t76\t/* remote error in protocol */\n#define EX_NOPERM\t77\t/* permission denied */\n#define EX_CONFIG\t78\t/* configuration error */\n\n#define EX__MAX\t\t78\t/* maximum listed value */\n\n#endif /* !_SYSEXITS_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/syslog.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _SYSLOG_H\n#define _SYSLOG_H\n\n#include <stdio.h>\n#include <sys/cdefs.h>\n#include <stdarg.h>\n\n__BEGIN_DECLS\n\n/* Priorities are translated to Android log priorities as shown. */\n#define LOG_EMERG   0 /* ERROR */\n#define LOG_ALERT   1 /* ERROR */\n#define LOG_CRIT    2 /* ERROR */\n#define LOG_ERR     3 /* ERROR */\n#define LOG_WARNING 4 /* WARN */\n#define LOG_NOTICE  5 /* INFO */\n#define LOG_INFO    6 /* INFO */\n#define LOG_DEBUG   7 /* DEBUG */\n\n#define LOG_PRIMASK 7\n#define LOG_PRI(x) ((x) & LOG_PRIMASK)\n#define LOG_MAKEPRI(fac, pri) ((fac) | (pri))\n\n/* Facilities are currently ignored on Android. */\n#define LOG_KERN     0000\n#define LOG_USER     0010\n#define LOG_MAIL     0020\n#define LOG_DAEMON   0030\n#define LOG_AUTH     0040\n#define LOG_SYSLOG   0050\n#define LOG_LPR      0060\n#define LOG_NEWS     0070\n#define LOG_UUCP     0100\n#define LOG_CRON     0110\n#define LOG_AUTHPRIV 0120\n#define LOG_FTP      0130\n#define LOG_LOCAL0   0200\n#define LOG_LOCAL1   0210\n#define LOG_LOCAL2   0220\n#define LOG_LOCAL3   0230\n#define LOG_LOCAL4   0240\n#define LOG_LOCAL5   0250\n#define LOG_LOCAL6   0260\n#define LOG_LOCAL7   0270\n\n#define LOG_FACMASK 01770\n#define LOG_FAC(x) (((x) >> 3) & (LOG_FACMASK >> 3))\n\n#define LOG_MASK(pri) (1 << (pri))\n#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1)\n\n/* openlog(3) flags are currently ignored on Android. */\n#define LOG_PID    0x01\n#define LOG_CONS   0x02\n#define LOG_ODELAY 0x04\n#define LOG_NDELAY 0x08\n#define LOG_NOWAIT 0x10\n#define LOG_PERROR 0x20\n\nvoid closelog(void);\nvoid openlog(const char*, int, int);\nint setlogmask(int);\nvoid syslog(int, const char*, ...) __printflike(2, 3);\nvoid vsyslog(int, const char*, va_list) __printflike(2, 0);\n\n__END_DECLS\n\n#endif /* _SYSLOG_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/termio.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/* All definitions related to termio are in Linux kernel headers\n * that are already included by <termios.h>\n */\n#include <termios.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/termios.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _TERMIOS_H_\n#define _TERMIOS_H_\n\n#include <sys/cdefs.h>\n#include <sys/ioctl.h>\n#include <sys/types.h>\n#include <linux/termios.h>\n\n__BEGIN_DECLS\n\n#if __ANDROID_API__ >= 21\nspeed_t cfgetispeed(const struct termios*);\nspeed_t cfgetospeed(const struct termios*);\nvoid cfmakeraw(struct termios*);\nint cfsetispeed(struct termios*, speed_t);\nint cfsetospeed(struct termios*, speed_t);\nint cfsetspeed(struct termios*, speed_t);\nint tcdrain(int);\nint tcflow(int, int);\nint tcflush(int, int);\nint tcgetattr(int, struct termios*);\npid_t tcgetsid(int);\nint tcsendbreak(int, int);\nint tcsetattr(int, int, const struct termios*);\n#else\n#include <android/legacy_termios_inlines.h>\n#endif\n\n__END_DECLS\n\n#endif /* _TERMIOS_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/time.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _TIME_H_\n#define _TIME_H_\n\n#include <sys/cdefs.h>\n#include <sys/time.h>\n#include <xlocale.h>\n\n__BEGIN_DECLS\n\n#define CLOCKS_PER_SEC 1000000\n\nextern char* tzname[] __LIBC_ABI_PUBLIC__;\nextern int daylight __LIBC_ABI_PUBLIC__;\nextern long int timezone __LIBC_ABI_PUBLIC__;\n\nstruct sigevent;\n\nstruct tm {\n  int tm_sec;\n  int tm_min;\n  int tm_hour;\n  int tm_mday;\n  int tm_mon;\n  int tm_year;\n  int tm_wday;\n  int tm_yday;\n  int tm_isdst;\n  long int tm_gmtoff;\n  const char* tm_zone;\n};\n\n#define TM_ZONE tm_zone\n\nextern time_t time(time_t*) __LIBC_ABI_PUBLIC__;\nextern int nanosleep(const struct timespec*, struct timespec*) __LIBC_ABI_PUBLIC__;\n\nextern char* asctime(const struct tm*) __LIBC_ABI_PUBLIC__;\nextern char* asctime_r(const struct tm*, char*) __LIBC_ABI_PUBLIC__;\n\nextern double difftime(time_t, time_t) __LIBC_ABI_PUBLIC__;\nextern time_t mktime(struct tm*) __LIBC_ABI_PUBLIC__;\n\nextern struct tm* localtime(const time_t*) __LIBC_ABI_PUBLIC__;\nextern struct tm* localtime_r(const time_t*, struct tm*) __LIBC_ABI_PUBLIC__;\n\nextern struct tm* gmtime(const time_t*) __LIBC_ABI_PUBLIC__;\nextern struct tm* gmtime_r(const time_t*, struct tm*) __LIBC_ABI_PUBLIC__;\n\nextern char* strptime(const char*, const char*, struct tm*) __LIBC_ABI_PUBLIC__;\nextern size_t strftime(char*, size_t, const char*, const struct tm*) __LIBC_ABI_PUBLIC__;\nextern size_t strftime_l(char *, size_t, const char *, const struct tm *, locale_t) __LIBC_ABI_PUBLIC__;\n\nextern char* ctime(const time_t*) __LIBC_ABI_PUBLIC__;\nextern char* ctime_r(const time_t*, char*) __LIBC_ABI_PUBLIC__;\n\nextern void tzset(void) __LIBC_ABI_PUBLIC__;\n\nextern clock_t clock(void) __LIBC_ABI_PUBLIC__;\n\nextern int clock_getcpuclockid(pid_t, clockid_t*) __LIBC_ABI_PUBLIC__;\n\nextern int clock_getres(clockid_t, struct timespec*) __LIBC_ABI_PUBLIC__;\nextern int clock_gettime(clockid_t, struct timespec*) __LIBC_ABI_PUBLIC__;\nextern int clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*) __LIBC_ABI_PUBLIC__;\nextern int clock_settime(clockid_t, const struct timespec*) __LIBC_ABI_PUBLIC__;\n\nextern int timer_create(int, struct sigevent*, timer_t*) __LIBC_ABI_PUBLIC__;\nextern int timer_delete(timer_t) __LIBC_ABI_PUBLIC__;\nextern int timer_settime(timer_t, int, const struct itimerspec*, struct itimerspec*) __LIBC_ABI_PUBLIC__;\nextern int timer_gettime(timer_t, struct itimerspec*) __LIBC_ABI_PUBLIC__;\nextern int timer_getoverrun(timer_t) __LIBC_ABI_PUBLIC__;\n\n/* Non-standard extensions that are in the BSDs and glibc. */\nextern time_t timelocal(struct tm*) __LIBC_ABI_PUBLIC__;\nextern time_t timegm(struct tm*) __LIBC_ABI_PUBLIC__;\n\n__END_DECLS\n\n#endif /* _TIME_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/time64.h",
    "content": "/*\n\nCopyright (c) 2007-2008  Michael G Schwern\n\nThis software originally derived from Paul Sheer's pivotal_gmtime_r.c.\n\nThe MIT License:\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\nOrigin: http://code.google.com/p/y2038\nModified for Bionic by the Android Open Source Project\n\n*/\n#ifndef TIME64_H\n#define TIME64_H\n\n#if defined(__LP64__)\n\n#error Your time_t is already 64-bit.\n\n#else\n\n/* Legacy cruft for LP32 where time_t was 32-bit. */\n\n#include <sys/cdefs.h>\n#include <time.h>\n#include <stdint.h>\n\n__BEGIN_DECLS\n\ntypedef int64_t time64_t;\n\nchar* asctime64(const struct tm*);\nchar* asctime64_r(const struct tm*, char*);\nchar* ctime64(const time64_t*);\nchar* ctime64_r(const time64_t*, char*);\nstruct tm* gmtime64(const time64_t*);\nstruct tm* gmtime64_r(const time64_t*, struct tm*);\nstruct tm* localtime64(const time64_t*);\nstruct tm* localtime64_r(const time64_t*, struct tm*);\ntime64_t mktime64(const struct tm*);\ntime64_t timegm64(const struct tm*);\ntime64_t timelocal64(const struct tm*);\n\n__END_DECLS\n\n#endif\n\n#endif /* TIME64_H */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/uchar.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _UCHAR_H_\n#define _UCHAR_H_\n\n#include <sys/cdefs.h>\n#include <wchar.h>\n\n__BEGIN_DECLS\n\n#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus)\ntypedef __CHAR16_TYPE__ char16_t;\ntypedef __CHAR32_TYPE__ char32_t;\n#endif\n\n#define __STD_UTF_16__ 1\n#define __STD_UTF_32__ 1\n\nsize_t c16rtomb(char* __restrict, char16_t, mbstate_t* __restrict);\nsize_t c32rtomb(char* __restrict, char32_t, mbstate_t* __restrict);\nsize_t mbrtoc16(char16_t* __restrict,\n                const char* __restrict,\n                size_t,\n                mbstate_t* __restrict);\nsize_t mbrtoc32(char32_t* __restrict,\n                const char* __restrict,\n                size_t,\n                mbstate_t* __restrict);\n\n__END_DECLS\n\n#endif /* _UCHAR_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/ucontext.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _UCONTEXT_H_\n#define _UCONTEXT_H_\n\n#include <sys/ucontext.h>\n\n#endif /* _UCONTEXT_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/unistd.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _UNISTD_H_\n#define _UNISTD_H_\n\n#include <stddef.h>\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <sys/select.h>\n#include <sys/sysconf.h>\n\n#include <bits/lockf.h>\n#include <bits/posix_limits.h>\n\n__BEGIN_DECLS\n\n#define STDIN_FILENO\t0\n#define STDOUT_FILENO\t1\n#define STDERR_FILENO\t2\n\n#define F_OK 0\n#define X_OK 1\n#define W_OK 2\n#define R_OK 4\n\n#define SEEK_SET 0\n#define SEEK_CUR 1\n#define SEEK_END 2\n\n#define _PC_FILESIZEBITS 0\n#define _PC_LINK_MAX 1\n#define _PC_MAX_CANON 2\n#define _PC_MAX_INPUT 3\n#define _PC_NAME_MAX 4\n#define _PC_PATH_MAX 5\n#define _PC_PIPE_BUF 6\n#define _PC_2_SYMLINKS 7\n#define _PC_ALLOC_SIZE_MIN 8\n#define _PC_REC_INCR_XFER_SIZE 9\n#define _PC_REC_MAX_XFER_SIZE 10\n#define _PC_REC_MIN_XFER_SIZE 11\n#define _PC_REC_XFER_ALIGN 12\n#define _PC_SYMLINK_MAX 13\n#define _PC_CHOWN_RESTRICTED 14\n#define _PC_NO_TRUNC 15\n#define _PC_VDISABLE 16\n#define _PC_ASYNC_IO 17\n#define _PC_PRIO_IO 18\n#define _PC_SYNC_IO 19\n\nextern char** environ;\n\nextern __noreturn void _exit(int __status);\n\nextern pid_t  fork(void);\nextern pid_t  vfork(void);\nextern pid_t  getpid(void);\nextern pid_t  gettid(void) __pure2;\nextern pid_t  getpgid(pid_t __pid);\nextern int    setpgid(pid_t __pid, pid_t __pgid);\nextern pid_t  getppid(void);\nextern pid_t  getpgrp(void);\nextern int    setpgrp(void);\nextern pid_t  getsid(pid_t __pid) __INTRODUCED_IN(21);\nextern pid_t  setsid(void);\n\nextern int execv(const char* __path, char* const* __argv);\nextern int execvp(const char* __file, char* const* __argv);\nextern int execvpe(const char* __file, char* const* __argv, char* const* __envp)\n  __INTRODUCED_IN(21);\nextern int execve(const char* __file, char* const* __argv, char* const* __envp);\nextern int execl(const char* __path, const char* __arg0, ...);\nextern int execlp(const char* __file, const char* __arg0, ...);\nextern int execle(const char* __path, const char* __arg0, ...);\n\nextern int nice(int __incr);\n\nextern int setuid(uid_t __uid);\nextern uid_t getuid(void);\nextern int seteuid(uid_t __uid);\nextern uid_t geteuid(void);\nextern int setgid(gid_t __gid);\nextern gid_t getgid(void);\nextern int setegid(gid_t __gid);\nextern gid_t getegid(void);\nextern int getgroups(int __size, gid_t* __list);\nextern int setgroups(size_t __size, const gid_t* __list);\nextern int setreuid(uid_t __ruid, uid_t __euid);\nextern int setregid(gid_t __rgid, gid_t __egid);\nextern int setresuid(uid_t __ruid, uid_t __euid, uid_t __suid);\nextern int setresgid(gid_t __rgid, gid_t __egid, gid_t __sgid);\nextern int getresuid(uid_t* __ruid, uid_t* __euid, uid_t* __suid);\nextern int getresgid(gid_t* __rgid, gid_t* __egid, gid_t* __sgid);\nextern char* getlogin(void);\n\nextern long fpathconf(int __fd, int __name);\nextern long pathconf(const char* __path, int __name);\n\nextern int access(const char* __path, int __mode);\nextern int faccessat(int __dirfd, const char* __path, int __mode, int __flags)\n  __INTRODUCED_IN(21);\nextern int link(const char* __oldpath, const char* __newpath);\nextern int linkat(int __olddirfd, const char* __oldpath, int __newdirfd,\n                  const char* __newpath, int __flags) __INTRODUCED_IN(21);\nextern int unlink(const char* __path);\nextern int unlinkat(int __dirfd, const char* __path, int __flags);\nextern int chdir(const char* __path);\nextern int fchdir(int __fd);\nextern int rmdir(const char* __path);\nextern int pipe(int* __pipefd);\n#if defined(__USE_GNU)\nextern int pipe2(int* __pipefd, int __flags) __INTRODUCED_IN(9);\n#endif\nextern int chroot(const char* __path);\nextern int symlink(const char* __oldpath, const char* __newpath);\nextern int symlinkat(const char* __oldpath, int __newdirfd,\n                     const char* __newpath) __INTRODUCED_IN(21);\nextern ssize_t readlink(const char* __path, char* __buf, size_t __bufsiz);\nextern ssize_t readlinkat(int __dirfd, const char* __path, char* __buf,\n                          size_t __bufsiz) __INTRODUCED_IN(21);\nextern int chown(const char* __path, uid_t __owner, gid_t __group);\nextern int fchown(int __fd, uid_t __owner, gid_t __group);\nextern int fchownat(int __dirfd, const char* __path, uid_t __owner,\n                    gid_t __group, int __flags);\nextern int lchown(const char* __path, uid_t __owner, gid_t __group);\nextern char* getcwd(char* __buf, size_t __size);\n\nextern int sync(void);\n\nextern int close(int __fd);\n\nextern ssize_t read(int __fd, void* __buf, size_t __count);\nextern ssize_t write(int __fd, const void* __buf, size_t __count);\n\nextern int dup(int __oldfd);\nextern int dup2(int __oldfd, int __newfd);\nextern int dup3(int __oldfd, int __newfd, int __flags) __INTRODUCED_IN(21);\nextern int fcntl(int __fd, int __cmd, ...);\nextern int ioctl(int __fd, int __request, ...);\nextern int fsync(int __fd);\nextern int fdatasync(int __fd) __INTRODUCED_IN(9);\n\n#if defined(__USE_FILE_OFFSET64)\nextern off_t lseek(int __fd, off_t __offset, int __whence) __RENAME(lseek64);\n#else\nextern off_t lseek(int __fd, off_t __offset, int __whence);\n#endif\n\nextern off64_t lseek64(int __fd, off64_t __offset, int __whence);\n\n#if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= 21\nextern int truncate(const char* __path, off_t __length) __RENAME(truncate64);\nextern ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset)\n  __RENAME(pread64);\nextern ssize_t pwrite(int __fd, const void* __buf, size_t __count,\n                      off_t __offset) __RENAME(pwrite64);\nextern int ftruncate(int __fd, off_t __length) __RENAME(ftruncate64);\n#else\nextern int truncate(const char* __path, off_t __length);\nextern ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset);\nextern ssize_t pwrite(int __fd, const void* __buf, size_t __count,\n                      off_t __offset);\nextern int ftruncate(int __fd, off_t __length);\n#endif\n\nextern int truncate64(const char* __path, off64_t __length) __INTRODUCED_IN(21);\nextern ssize_t pread64(int __fd, void* __buf, size_t __count, off64_t __offset) __INTRODUCED_IN(21);\nextern ssize_t pwrite64(int __fd, const void* __buf, size_t __count,\n                        off64_t __offset) __INTRODUCED_IN(21);\nextern int ftruncate64(int __fd, off64_t __length) __INTRODUCED_IN(21);\n\nextern int pause(void);\nextern unsigned int alarm(unsigned int __seconds);\nextern unsigned int sleep(unsigned int __seconds);\nextern int usleep(useconds_t __usec);\n\nint gethostname(char* __name, size_t __len);\nint sethostname(const char* __name, size_t __len);\n\nextern void* __brk(void* __addr);\nextern int brk(void* __addr);\nextern void* sbrk(ptrdiff_t __increment);\n\nextern int getopt(int __argc, char* const* __argv, const char* __argstring);\nextern char* optarg;\nextern int optind, opterr, optopt;\n\nextern int isatty(int __fd);\nextern char* ttyname(int __fd);\nextern int ttyname_r(int __fd, char* __buf, size_t __buflen) __INTRODUCED_IN(8);\n\nextern int acct(const char* __filepath);\n\nlong sysconf(int __name);\n\n#if __ANDROID_API__ >= 21\nint getpagesize(void);\n#else\n__inline__ int getpagesize(void) {\n  return sysconf(_SC_PAGESIZE);\n}\n#endif\n\nlong syscall(long __number, ...);\n\nextern int daemon(int __nochdir, int __noclose);\n\n#if defined(__arm__) || (defined(__mips__) && !defined(__LP64__))\nextern int cacheflush(long __addr, long __nbytes, long __cache);\n    /* __attribute__((deprecated(\"use __builtin___clear_cache instead\"))); */\n#endif\n\nextern pid_t tcgetpgrp(int __fd);\nextern int tcsetpgrp(int __fd, pid_t __pid);\n\n/* Used to retry syscalls that can return EINTR. */\n#define TEMP_FAILURE_RETRY(exp) ({         \\\n    __typeof__(exp) _rc;                   \\\n    do {                                   \\\n        _rc = (exp);                       \\\n    } while (_rc == -1 && errno == EINTR); \\\n    _rc; })\n\n/* TODO(unified-headers): Factor out all the FORTIFY features. */\nextern char* __getcwd_chk(char*, size_t, size_t);\n__errordecl(__getcwd_dest_size_error, \"getcwd called with size bigger than destination\");\nextern char* __getcwd_real(char*, size_t) __RENAME(getcwd);\n\nextern ssize_t __pread_chk(int, void*, size_t, off_t, size_t);\n__errordecl(__pread_dest_size_error, \"pread called with size bigger than destination\");\n__errordecl(__pread_count_toobig_error, \"pread called with count > SSIZE_MAX\");\nextern ssize_t __pread_real(int, void*, size_t, off_t) __RENAME(pread);\n\nextern ssize_t __pread64_chk(int, void*, size_t, off64_t, size_t);\n__errordecl(__pread64_dest_size_error, \"pread64 called with size bigger than destination\");\n__errordecl(__pread64_count_toobig_error, \"pread64 called with count > SSIZE_MAX\");\nextern ssize_t __pread64_real(int, void*, size_t, off64_t) __RENAME(pread64);\n\nextern ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t);\n__errordecl(__pwrite_dest_size_error, \"pwrite called with size bigger than destination\");\n__errordecl(__pwrite_count_toobig_error, \"pwrite called with count > SSIZE_MAX\");\nextern ssize_t __pwrite_real(int, const void*, size_t, off_t) __RENAME(pwrite);\n\nextern ssize_t __pwrite64_chk(int, const void*, size_t, off64_t, size_t);\n__errordecl(__pwrite64_dest_size_error, \"pwrite64 called with size bigger than destination\");\n__errordecl(__pwrite64_count_toobig_error, \"pwrite64 called with count > SSIZE_MAX\");\nextern ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64);\n\nextern ssize_t __read_chk(int, void*, size_t, size_t);\n__errordecl(__read_dest_size_error, \"read called with size bigger than destination\");\n__errordecl(__read_count_toobig_error, \"read called with count > SSIZE_MAX\");\nextern ssize_t __read_real(int, void*, size_t) __RENAME(read);\n\nextern ssize_t __write_chk(int, const void*, size_t, size_t);\n__errordecl(__write_dest_size_error, \"write called with size bigger than destination\");\n__errordecl(__write_count_toobig_error, \"write called with count > SSIZE_MAX\");\nextern ssize_t __write_real(int, const void*, size_t) __RENAME(write);\n\nextern ssize_t __readlink_chk(const char*, char*, size_t, size_t);\n__errordecl(__readlink_dest_size_error, \"readlink called with size bigger than destination\");\n__errordecl(__readlink_size_toobig_error, \"readlink called with size > SSIZE_MAX\");\nextern ssize_t __readlink_real(const char*, char*, size_t) __RENAME(readlink);\n\nextern ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t);\n__errordecl(__readlinkat_dest_size_error, \"readlinkat called with size bigger than destination\");\n__errordecl(__readlinkat_size_toobig_error, \"readlinkat called with size > SSIZE_MAX\");\nextern ssize_t __readlinkat_real(int dirfd, const char*, char*, size_t) __RENAME(readlinkat);\n\n#if defined(__BIONIC_FORTIFY)\n\n__BIONIC_FORTIFY_INLINE\nchar* getcwd(char* buf, size_t size) {\n    size_t bos = __bos(buf);\n\n#if defined(__clang__)\n    /*\n     * Work around LLVM's incorrect __builtin_object_size implementation here\n     * to avoid needing the workaround in the __getcwd_chk ABI forever.\n     *\n     * https://llvm.org/bugs/show_bug.cgi?id=23277\n     */\n    if (buf == NULL) {\n        bos = __BIONIC_FORTIFY_UNKNOWN_SIZE;\n    }\n#else\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __getcwd_real(buf, size);\n    }\n\n    if (__builtin_constant_p(size) && (size > bos)) {\n        __getcwd_dest_size_error();\n    }\n\n    if (__builtin_constant_p(size) && (size <= bos)) {\n        return __getcwd_real(buf, size);\n    }\n#endif\n\n    return __getcwd_chk(buf, size, bos);\n}\n\n#if defined(__USE_FILE_OFFSET64)\n#define __PREAD_PREFIX(x) __pread64_ ## x\n#else\n#define __PREAD_PREFIX(x) __pread_ ## x\n#endif\n\n__BIONIC_FORTIFY_INLINE\nssize_t pread(int fd, void* buf, size_t count, off_t offset) {\n    size_t bos = __bos0(buf);\n\n#if !defined(__clang__)\n    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {\n        __PREAD_PREFIX(count_toobig_error)();\n    }\n\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __PREAD_PREFIX(real)(fd, buf, count, offset);\n    }\n\n    if (__builtin_constant_p(count) && (count > bos)) {\n        __PREAD_PREFIX(dest_size_error)();\n    }\n\n    if (__builtin_constant_p(count) && (count <= bos)) {\n        return __PREAD_PREFIX(real)(fd, buf, count, offset);\n    }\n#endif\n\n    return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);\n}\n\n__BIONIC_FORTIFY_INLINE\nssize_t pread64(int fd, void* buf, size_t count, off64_t offset) {\n    size_t bos = __bos0(buf);\n\n#if !defined(__clang__)\n    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {\n        __pread64_count_toobig_error();\n    }\n\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __pread64_real(fd, buf, count, offset);\n    }\n\n    if (__builtin_constant_p(count) && (count > bos)) {\n        __pread64_dest_size_error();\n    }\n\n    if (__builtin_constant_p(count) && (count <= bos)) {\n        return __pread64_real(fd, buf, count, offset);\n    }\n#endif\n\n    return __pread64_chk(fd, buf, count, offset, bos);\n}\n\n#if defined(__USE_FILE_OFFSET64)\n#define __PWRITE_PREFIX(x) __pwrite64_ ## x\n#else\n#define __PWRITE_PREFIX(x) __pwrite_ ## x\n#endif\n\n__BIONIC_FORTIFY_INLINE\nssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) {\n    size_t bos = __bos0(buf);\n\n#if !defined(__clang__)\n    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {\n        __PWRITE_PREFIX(count_toobig_error)();\n    }\n\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __PWRITE_PREFIX(real)(fd, buf, count, offset);\n    }\n\n    if (__builtin_constant_p(count) && (count > bos)) {\n        __PWRITE_PREFIX(dest_size_error)();\n    }\n\n    if (__builtin_constant_p(count) && (count <= bos)) {\n        return __PWRITE_PREFIX(real)(fd, buf, count, offset);\n    }\n#endif\n\n    return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);\n}\n\n__BIONIC_FORTIFY_INLINE\nssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset) {\n    size_t bos = __bos0(buf);\n\n#if !defined(__clang__)\n    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {\n        __pwrite64_count_toobig_error();\n    }\n\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __pwrite64_real(fd, buf, count, offset);\n    }\n\n    if (__builtin_constant_p(count) && (count > bos)) {\n        __pwrite64_dest_size_error();\n    }\n\n    if (__builtin_constant_p(count) && (count <= bos)) {\n        return __pwrite64_real(fd, buf, count, offset);\n    }\n#endif\n\n    return __pwrite64_chk(fd, buf, count, offset, bos);\n}\n\n__BIONIC_FORTIFY_INLINE\nssize_t read(int fd, void* buf, size_t count) {\n    size_t bos = __bos0(buf);\n\n#if !defined(__clang__)\n    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {\n        __read_count_toobig_error();\n    }\n\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __read_real(fd, buf, count);\n    }\n\n    if (__builtin_constant_p(count) && (count > bos)) {\n        __read_dest_size_error();\n    }\n\n    if (__builtin_constant_p(count) && (count <= bos)) {\n        return __read_real(fd, buf, count);\n    }\n#endif\n\n    return __read_chk(fd, buf, count, bos);\n}\n\n__BIONIC_FORTIFY_INLINE\nssize_t write(int fd, const void* buf, size_t count) {\n    size_t bos = __bos0(buf);\n\n#if !defined(__clang__)\n#if 0 /* work around a false positive due to a missed optimization */\n    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {\n        __write_count_toobig_error();\n    }\n#endif\n\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __write_real(fd, buf, count);\n    }\n\n    if (__builtin_constant_p(count) && (count > bos)) {\n        __write_dest_size_error();\n    }\n\n    if (__builtin_constant_p(count) && (count <= bos)) {\n        return __write_real(fd, buf, count);\n    }\n#endif\n\n    return __write_chk(fd, buf, count, bos);\n}\n\n__BIONIC_FORTIFY_INLINE\nssize_t readlink(const char* path, char* buf, size_t size) {\n    size_t bos = __bos(buf);\n\n#if !defined(__clang__)\n    if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {\n        __readlink_size_toobig_error();\n    }\n\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __readlink_real(path, buf, size);\n    }\n\n    if (__builtin_constant_p(size) && (size > bos)) {\n        __readlink_dest_size_error();\n    }\n\n    if (__builtin_constant_p(size) && (size <= bos)) {\n        return __readlink_real(path, buf, size);\n    }\n#endif\n\n    return __readlink_chk(path, buf, size, bos);\n}\n\n__BIONIC_FORTIFY_INLINE\nssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size) {\n    size_t bos = __bos(buf);\n\n#if !defined(__clang__)\n    if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {\n        __readlinkat_size_toobig_error();\n    }\n\n    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {\n        return __readlinkat_real(dirfd, path, buf, size);\n    }\n\n    if (__builtin_constant_p(size) && (size > bos)) {\n        __readlinkat_dest_size_error();\n    }\n\n    if (__builtin_constant_p(size) && (size <= bos)) {\n        return __readlinkat_real(dirfd, path, buf, size);\n    }\n#endif\n\n    return __readlinkat_chk(dirfd, path, buf, size, bos);\n}\n\n#endif /* defined(__BIONIC_FORTIFY) */\n\n__END_DECLS\n\n#endif /* _UNISTD_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/util.h",
    "content": ""
  },
  {
    "path": "atlas-aapt/bionic/libc/include/utime.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _UTIME_H_\n#define _UTIME_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <linux/utime.h>\n\n__BEGIN_DECLS\n\nextern int utime(const char*, const struct utimbuf*);\n\n__END_DECLS\n\n#endif /* _UTIME_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/utmp.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _UTMP_H_\n#define _UTMP_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <time.h>\n\n#define _PATH_UTMP      \"/var/run/utmp\"\n#define _PATH_WTMP      \"/var/log/wtmp\"\n#define _PATH_LASTLOG   \"/var/log/lastlog\"\n\n#ifdef __LP64__\n#define UT_NAMESIZE 32\n#define UT_LINESIZE 32\n#define UT_HOSTSIZE 256\n#else\n#define UT_NAMESIZE 8\n#define UT_LINESIZE 8\n#define UT_HOSTSIZE 16\n#endif\n\n#define EMPTY         0\n#define RUN_LVL       1\n#define BOOT_TIME     2\n#define NEW_TIME      3\n#define OLD_TIME      4\n#define INIT_PROCESS  5\n#define LOGIN_PROCESS 6\n#define USER_PROCESS  7\n#define DEAD_PROCESS  8\n#define ACCOUNTING    9\n\nstruct lastlog\n{\n    time_t ll_time;\n    char ll_line[UT_LINESIZE];\n    char ll_host[UT_HOSTSIZE];\n};\n\nstruct exit_status\n{\n    short int e_termination;\n    short int e_exit;\n};\n\n\nstruct utmp\n{\n    short int ut_type;\n    pid_t ut_pid;\n    char ut_line[UT_LINESIZE];\n    char ut_id[4];\n    char ut_user[UT_NAMESIZE];\n    char ut_host[UT_HOSTSIZE];\n\n    struct exit_status ut_exit;\n\n    long int ut_session;\n    struct timeval ut_tv;\n\n    int32_t ut_addr_v6[4];\n    char unsed[20];\n};\n\n\n#define ut_name ut_user\n#define ut_time ut_tv.tv_sec\n#define ut_addr ut_addr_v6[0]\n\n__BEGIN_DECLS\n\nint utmpname(const char*);\nvoid setutent(void);\nstruct utmp* getutent(void);\nvoid endutent(void);\n\nint login_tty(int);\n\n__END_DECLS\n\n#endif /* _UTMP_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/wait.h",
    "content": "#include <sys/wait.h>\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/wchar.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef _WCHAR_H_\n#define _WCHAR_H_\n\n#include <sys/cdefs.h>\n#include <stdio.h>\n\n#include <stdarg.h>\n#include <stddef.h>\n#include <time.h>\n#include <xlocale.h>\n\n#include <bits/wchar_limits.h>\n\n__BEGIN_DECLS\n\ntypedef __WINT_TYPE__  wint_t;\ntypedef struct {\n  uint8_t __seq[4];\n#ifdef __LP64__\n  char __reserved[4];\n#endif\n} mbstate_t;\n\nenum {\n    WC_TYPE_INVALID = 0,\n    WC_TYPE_ALNUM,\n    WC_TYPE_ALPHA,\n    WC_TYPE_BLANK,\n    WC_TYPE_CNTRL,\n    WC_TYPE_DIGIT,\n    WC_TYPE_GRAPH,\n    WC_TYPE_LOWER,\n    WC_TYPE_PRINT,\n    WC_TYPE_PUNCT,\n    WC_TYPE_SPACE,\n    WC_TYPE_UPPER,\n    WC_TYPE_XDIGIT,\n    WC_TYPE_MAX\n};\n\ntypedef long wctype_t;\n\n#define  WEOF        ((wint_t)(-1))\n\nextern wint_t            btowc(int);\nextern int               fwprintf(FILE *, const wchar_t *, ...);\nextern int               fwscanf(FILE *, const wchar_t *, ...);\nextern int               iswalnum(wint_t);\nextern int               iswalpha(wint_t);\nextern int               iswblank(wint_t);\nextern int               iswcntrl(wint_t);\nextern int               iswdigit(wint_t);\nextern int               iswgraph(wint_t);\nextern int               iswlower(wint_t);\nextern int               iswprint(wint_t);\nextern int               iswpunct(wint_t);\nextern int               iswspace(wint_t);\nextern int               iswupper(wint_t);\nextern int               iswxdigit(wint_t);\nextern int               iswctype(wint_t, wctype_t);\nextern wint_t            fgetwc(FILE *);\nextern wchar_t          *fgetws(wchar_t *, int, FILE *);\nextern wint_t            fputwc(wchar_t, FILE *);\nextern int               fputws(const wchar_t *, FILE *);\nextern int               fwide(FILE *, int);\nextern wint_t            getwc(FILE *);\nextern wint_t            getwchar(void);\nextern int               mbsinit(const mbstate_t *);\nextern size_t            mbrlen(const char *, size_t, mbstate_t *);\nextern size_t            mbrtowc(wchar_t *, const char *, size_t, mbstate_t *);\nextern size_t mbsrtowcs(wchar_t*, const char**, size_t, mbstate_t*);\nextern size_t mbsnrtowcs(wchar_t*, const char**, size_t, size_t, mbstate_t*);\nextern size_t            mbstowcs(wchar_t *, const char *, size_t);\nextern wint_t            putwc(wchar_t, FILE *);\nextern wint_t            putwchar(wchar_t);\nextern int               swprintf(wchar_t *, size_t, const wchar_t *, ...);\nextern int               swscanf(const wchar_t *, const wchar_t *, ...);\nextern wint_t            towlower(wint_t);\nextern wint_t            towupper(wint_t);\nextern wint_t            ungetwc(wint_t, FILE *);\nextern int vfwprintf(FILE*, const wchar_t*, va_list);\nextern int vfwscanf(FILE*, const wchar_t*, va_list);\nextern int vswprintf(wchar_t*, size_t, const wchar_t*, va_list);\nextern int vswscanf(const wchar_t*, const wchar_t*, va_list);\nextern int vwprintf(const wchar_t*, va_list);\nextern int vwscanf(const wchar_t*, va_list);\nextern wchar_t* wcpcpy (wchar_t*, const wchar_t *);\nextern wchar_t* wcpncpy (wchar_t*, const wchar_t *, size_t);\nextern size_t            wcrtomb(char *, wchar_t, mbstate_t *);\nextern int               wcscasecmp(const wchar_t *, const wchar_t *);\nextern int               wcscasecmp_l(const wchar_t *, const wchar_t *, locale_t);\nextern wchar_t          *wcscat(wchar_t *, const wchar_t *);\nextern wchar_t          *wcschr(const wchar_t *, wchar_t);\nextern int               wcscmp(const wchar_t *, const wchar_t *);\nextern int               wcscoll(const wchar_t *, const wchar_t *);\nextern wchar_t          *wcscpy(wchar_t *, const wchar_t *);\nextern size_t            wcscspn(const wchar_t *, const wchar_t *);\nextern size_t            wcsftime(wchar_t *, size_t, const wchar_t *, const struct tm *) __LIBC_ABI_PUBLIC__;\nextern size_t            wcslen(const wchar_t *);\nextern int               wcsncasecmp(const wchar_t *, const wchar_t *, size_t);\nextern int               wcsncasecmp_l(const wchar_t *, const wchar_t *, size_t, locale_t);\nextern wchar_t          *wcsncat(wchar_t *, const wchar_t *, size_t);\nextern int               wcsncmp(const wchar_t *, const wchar_t *, size_t);\nextern wchar_t          *wcsncpy(wchar_t *, const wchar_t *, size_t);\nextern size_t wcsnrtombs(char*, const wchar_t**, size_t, size_t, mbstate_t*);\nextern wchar_t          *wcspbrk(const wchar_t *, const wchar_t *);\nextern wchar_t          *wcsrchr(const wchar_t *, wchar_t);\nextern size_t wcsrtombs(char*, const wchar_t**, size_t, mbstate_t*);\nextern size_t            wcsspn(const wchar_t *, const wchar_t *);\nextern wchar_t          *wcsstr(const wchar_t *, const wchar_t *);\nextern double wcstod(const wchar_t*, wchar_t**);\nextern float wcstof(const wchar_t*, wchar_t**);\nextern wchar_t* wcstok(wchar_t*, const wchar_t*, wchar_t**);\nextern long wcstol(const wchar_t*, wchar_t**, int);\nextern long long wcstoll(const wchar_t*, wchar_t**, int);\nextern long double wcstold(const wchar_t*, wchar_t**);\nextern unsigned long wcstoul(const wchar_t*, wchar_t**, int);\nextern unsigned long long wcstoull(const wchar_t*, wchar_t**, int);\nextern int               wcswidth(const wchar_t *, size_t);\nextern size_t            wcsxfrm(wchar_t *, const wchar_t *, size_t);\nextern int               wctob(wint_t);\nextern wctype_t          wctype(const char *);\nextern int               wcwidth(wchar_t);\nextern wchar_t          *wmemchr(const wchar_t *, wchar_t, size_t);\nextern int               wmemcmp(const wchar_t *, const wchar_t *, size_t);\nextern wchar_t          *wmemcpy(wchar_t *, const wchar_t *, size_t);\n#if defined(__USE_GNU)\nextern wchar_t          *wmempcpy(wchar_t *, const wchar_t *, size_t);\n#endif\nextern wchar_t          *wmemmove(wchar_t *, const wchar_t *, size_t);\nextern wchar_t          *wmemset(wchar_t *, wchar_t, size_t);\nextern int               wprintf(const wchar_t *, ...);\nextern int               wscanf(const wchar_t *, ...);\n\nextern long long          wcstoll_l(const wchar_t *, wchar_t **, int, locale_t);\nextern unsigned long long wcstoull_l(const wchar_t *, wchar_t **, int, locale_t);\nextern long double        wcstold_l(const wchar_t *, wchar_t **, locale_t );\n\nextern int    wcscoll_l(const wchar_t *, const wchar_t *, locale_t);\nextern size_t wcsxfrm_l(wchar_t *, const wchar_t *, size_t, locale_t);\n\nextern size_t wcslcat(wchar_t*, const wchar_t*, size_t);\nextern size_t wcslcpy(wchar_t*, const wchar_t*, size_t);\n\ntypedef void *wctrans_t;\nextern wint_t towctrans(wint_t, wctrans_t);\nextern wctrans_t wctrans(const char*);\n\n#if __POSIX_VISIBLE >= 200809\nFILE* open_wmemstream(wchar_t**, size_t*);\nwchar_t* wcsdup(const wchar_t*);\nsize_t wcsnlen(const wchar_t*, size_t);\n#endif\n\n__END_DECLS\n\n#endif /* _WCHAR_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/wctype.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _WCTYPE_H_\n#define _WCTYPE_H_\n\n#include <wchar.h>\n\n__BEGIN_DECLS\n\nextern int iswalnum_l(wint_t, locale_t);\nextern int iswalpha_l(wint_t, locale_t);\nextern int iswblank_l(wint_t, locale_t);\nextern int iswcntrl_l(wint_t, locale_t);\nextern int iswdigit_l(wint_t, locale_t);\nextern int iswgraph_l(wint_t, locale_t);\nextern int iswlower_l(wint_t, locale_t);\nextern int iswprint_l(wint_t, locale_t);\nextern int iswpunct_l(wint_t, locale_t);\nextern int iswspace_l(wint_t, locale_t);\nextern int iswupper_l(wint_t, locale_t);\nextern int iswxdigit_l(wint_t, locale_t);\nextern int towlower_l(int, locale_t);\nextern int towupper_l(int, locale_t);\n\nextern int iswctype_l(wint_t, wctype_t, locale_t);\nextern wctype_t wctype_l(const char*, locale_t);\n\n__END_DECLS\n\n#endif /* _WCTYPE_H_ */\n"
  },
  {
    "path": "atlas-aapt/bionic/libc/include/xlocale.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _XLOCALE_H_\n#define _XLOCALE_H_\n\n/* If we just use void* here, GCC exposes that in error messages. */\nstruct __locale_t;\ntypedef struct __locale_t* locale_t;\n\n#endif /* _XLOCALE_H_ */\n"
  },
  {
    "path": "atlas-aapt/build_ShakaAapt_all_in_linux.sh",
    "content": "#! /bin/bash\n#43\n\nexport Project=ShakaAapt\nexport BUILD_NUMBER=$Project.$(date +%Y%m%d.%H%M%S)\nexport BinDir=ShakaAaptBin\n\nexport USE_CCACHE=1\nexport CCACHE_DIR=$(pwd)/.ccache\nexport OUT_DIR=out-x86_64\nprebuilts/misc/linux-x86/ccache/ccache -M 50G\n\nrm -rf out-x86 out-x86_64\n\n# linux-x86_64\nOUT_DIR=out-x86_64 make -B BUILD_NUMBER=$BUILD_NUMBER LOCAL_MULTILIB=64 USE_NINJA=false aapt -j4\nstrip out-x86_64/host/linux-x86/bin/aapt\nmkdir -p $BinDir/linux-x86_64/bin\ncp out-x86_64/host/linux-x86/bin/aapt $BinDir/linux-x86_64/bin/aapt\n\n# linux-x86\nOUT_DIR=out-x86 make -B BUILD_NUMBER=$BUILD_NUMBER LOCAL_MULTILIB=32 USE_NINJA=false aapt -j4\nstrip out-x86/host/linux-x86/bin/aapt\nmkdir -p $BinDir/linux-x86/bin\ncp out-x86/host/linux-x86/bin/aapt $BinDir/linux-x86/bin/aapt\n\n# windows-x86\nOUT_DIR=out-x86 make -B winsdk-tools -j4 USE_NINJA=false\nstrip out-x86/host/windows-x86/bin/aapt.exe\nmkdir -p $BinDir/windows-x86/bin\ncp out-x86/host/windows-x86/bin/aapt.exe $BinDir/windows-x86/bin/aapt.exe\n"
  },
  {
    "path": "atlas-aapt/build_ShakaAapt_all_in_maxos.sh",
    "content": "#! /bin/bash\n\nexport Project=ShakaAapt\nexport BUILD_NUMBER=$Project.$(date +%Y%m%d.%H%M%S)\nexport BinDir=ShakaAaptBin\n\nexport USE_CCACHE=1\nexport CCACHE_DIR=$(pwd)/.ccache\nprebuilts/misc/darwin-x86/ccache/ccache -M 50G\n. build/envsetup.sh\nlunch sdk-eng\n\nrm -rf out-x86 out-x86_64\n\n# darwin-x86\n\nOUT_DIR=out-x86 make -B BUILD_NUMBER=$BUILD_NUMBER LOCAL_MULTILIB=32 USE_NINJA=false aapt -j4\nmkdir -p \"$BinDir/darwin-x86/bin\"\ncp out-x86/host/darwin-x86/bin/aapt \"$BinDir/darwin-x86/bin/aapt\"\n\n#mkdir -p lib \"$BinDir/darwin-x86/lib\"\n#cp out-x86/host/darwin-x86/lib/libc++.dylib \"$BinDir/darwin-x86/lib/libc++.dylib\"\n\n# darwin-x86_64\n\nOUT_DIR=out-x86_64 make -B BUILD_NUMBER=$BUILD_NUMBER LOCAL_MULTILIB=64 USE_NINJA=false aapt -j4\nmkdir -p \"$BinDir/darwin-x86_64/bin\"\ncp out-x86_64/host/darwin-x86/bin/aapt \"$BinDir/darwin-x86_64/bin/aapt\"\n\n#mkdir -p \"$BinDir/darwin-x86_64/lib64/\"\n#cp out-x86_64/host/darwin-x86/lib64/libc++.dylib \"$BinDir/darwin-x86_64/lib64/libc++.dylib\"\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/.arcconfig",
    "content": "{\n  \"project_id\" : \"compiler-rt\",\n  \"conduit_uri\" : \"http://reviews.llvm.org/\"\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/.gitignore",
    "content": "*~\ndarwin_fat\nclang_darwin\nmulti_arch\n*.sw?\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/Android.bp",
    "content": "//\n// Copyright (C) 2012 The Android Open Source Project\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n//\n\n//=====================================================================\n// Static Library: libcompiler_rt-extras\n//=====================================================================\n\ncc_library_static {\n    name: \"libcompiler_rt-extras\",\n    host_supported: true,\n    clang: true,\n    // The following list contains functions that are not available in libgcc.a, so\n    // we potentially need them when using a Clang-built component (e.g., -ftrapv\n    // with 64-bit integer multiplies. See http://llvm.org/bugs/show_bug.cgi?id=14469.)\n    srcs: [\"lib/builtins/mulodi4.c\"],\n    sanitize: [\"never\"],\n    stl: \"none\",\n\n    cflags: [\n        \"-Wno-unused-parameter\",\n        \"-Werror\",\n    ],\n\n    arch: {\n        mips: {\n            srcs: [\"lib/builtins/clear_cache.c\"],\n        },\n        mips64: {\n            srcs: [\"lib/builtins/clear_cache.c\"],\n        },\n    },\n\n    target: {\n        windows: {\n            enabled: true,\n        },\n    },\n}\n\n// Don't build compiler-rt without clang\n// ANDROIDMK TRANSLATION ERROR: unsupported directive\n// ifneq ($(WITHOUT_TARGET_CLANG), true)\n//=====================================================================\n// Device and Host Static Library: libcompiler_rt\n//=====================================================================\n\ncc_library {\n    name: \"libcompiler_rt\",\n    host_supported: true,\n    // The following list contains platform-independent functionalities.\n    //\n    // Skip apple_versioning.c since it is unused.\n    // Skip atomic.c since it needs to be built separately according to the docs.\n    srcs: [\n        \"lib/builtins/absvdi2.c\",\n        \"lib/builtins/absvsi2.c\",\n        \"lib/builtins/absvti2.c\",\n        \"lib/builtins/adddf3.c\",\n        \"lib/builtins/addsf3.c\",\n        \"lib/builtins/addtf3.c\",\n        \"lib/builtins/addvdi3.c\",\n        \"lib/builtins/addvsi3.c\",\n        \"lib/builtins/addvti3.c\",\n        \"lib/builtins/ashldi3.c\",\n        \"lib/builtins/ashlti3.c\",\n        \"lib/builtins/ashrdi3.c\",\n        \"lib/builtins/ashrti3.c\",\n        \"lib/builtins/clear_cache.c\",\n        \"lib/builtins/clzdi2.c\",\n        \"lib/builtins/clzsi2.c\",\n        \"lib/builtins/clzti2.c\",\n        \"lib/builtins/cmpdi2.c\",\n        \"lib/builtins/cmpti2.c\",\n        \"lib/builtins/comparedf2.c\",\n        \"lib/builtins/comparesf2.c\",\n        \"lib/builtins/comparetf2.c\",\n        \"lib/builtins/ctzdi2.c\",\n        \"lib/builtins/ctzsi2.c\",\n        \"lib/builtins/ctzti2.c\",\n        \"lib/builtins/divdc3.c\",\n        \"lib/builtins/divdf3.c\",\n        \"lib/builtins/divdi3.c\",\n        \"lib/builtins/divmoddi4.c\",\n        \"lib/builtins/divmodsi4.c\",\n        \"lib/builtins/divsc3.c\",\n        \"lib/builtins/divsf3.c\",\n        \"lib/builtins/divsi3.c\",\n        \"lib/builtins/divtf3.c\",\n        \"lib/builtins/divti3.c\",\n        \"lib/builtins/divxc3.c\",\n        \"lib/builtins/eprintf.c\",\n        \"lib/builtins/extenddftf2.c\",\n        \"lib/builtins/extendhfsf2.c\",\n        \"lib/builtins/extendsfdf2.c\",\n        \"lib/builtins/extendsftf2.c\",\n        \"lib/builtins/ffsdi2.c\",\n        \"lib/builtins/ffsti2.c\",\n        \"lib/builtins/fixdfdi.c\",\n        \"lib/builtins/fixdfsi.c\",\n        \"lib/builtins/fixdfti.c\",\n        \"lib/builtins/fixsfdi.c\",\n        \"lib/builtins/fixsfsi.c\",\n        \"lib/builtins/fixsfti.c\",\n        \"lib/builtins/fixtfdi.c\",\n        \"lib/builtins/fixtfsi.c\",\n        \"lib/builtins/fixtfti.c\",\n        \"lib/builtins/fixunsdfdi.c\",\n        \"lib/builtins/fixunsdfsi.c\",\n        \"lib/builtins/fixunsdfti.c\",\n        \"lib/builtins/fixunssfdi.c\",\n        \"lib/builtins/fixunssfsi.c\",\n        \"lib/builtins/fixunssfti.c\",\n        \"lib/builtins/fixunstfdi.c\",\n        \"lib/builtins/fixunstfsi.c\",\n        \"lib/builtins/fixunstfti.c\",\n        \"lib/builtins/fixunsxfdi.c\",\n        \"lib/builtins/fixunsxfsi.c\",\n        \"lib/builtins/fixunsxfti.c\",\n        \"lib/builtins/fixxfdi.c\",\n        \"lib/builtins/fixxfti.c\",\n        \"lib/builtins/floatdidf.c\",\n        \"lib/builtins/floatdisf.c\",\n        \"lib/builtins/floatdixf.c\",\n        \"lib/builtins/floatsidf.c\",\n        \"lib/builtins/floatsisf.c\",\n        \"lib/builtins/floatsitf.c\",\n        \"lib/builtins/floattidf.c\",\n        \"lib/builtins/floattisf.c\",\n        \"lib/builtins/floattixf.c\",\n        \"lib/builtins/floatundidf.c\",\n        \"lib/builtins/floatundisf.c\",\n        \"lib/builtins/floatundixf.c\",\n        \"lib/builtins/floatunsidf.c\",\n        \"lib/builtins/floatunsisf.c\",\n        \"lib/builtins/floatunsitf.c\",\n        \"lib/builtins/floatuntidf.c\",\n        \"lib/builtins/floatuntisf.c\",\n        \"lib/builtins/floatuntixf.c\",\n        \"lib/builtins/gcc_personality_v0.c\",\n        \"lib/builtins/int_util.c\",\n        \"lib/builtins/lshrdi3.c\",\n        \"lib/builtins/lshrti3.c\",\n        \"lib/builtins/moddi3.c\",\n        \"lib/builtins/modsi3.c\",\n        \"lib/builtins/modti3.c\",\n        \"lib/builtins/muldc3.c\",\n        \"lib/builtins/muldf3.c\",\n        \"lib/builtins/muldi3.c\",\n        \"lib/builtins/mulodi4.c\",\n        \"lib/builtins/mulosi4.c\",\n        \"lib/builtins/muloti4.c\",\n        \"lib/builtins/mulsc3.c\",\n        \"lib/builtins/mulsf3.c\",\n        \"lib/builtins/multf3.c\",\n        \"lib/builtins/multi3.c\",\n        \"lib/builtins/mulvdi3.c\",\n        \"lib/builtins/mulvsi3.c\",\n        \"lib/builtins/mulvti3.c\",\n        \"lib/builtins/mulxc3.c\",\n        \"lib/builtins/negdf2.c\",\n        \"lib/builtins/negdi2.c\",\n        \"lib/builtins/negsf2.c\",\n        \"lib/builtins/negti2.c\",\n        \"lib/builtins/negvdi2.c\",\n        \"lib/builtins/negvsi2.c\",\n        \"lib/builtins/negvti2.c\",\n        \"lib/builtins/paritydi2.c\",\n        \"lib/builtins/paritysi2.c\",\n        \"lib/builtins/parityti2.c\",\n        \"lib/builtins/popcountdi2.c\",\n        \"lib/builtins/popcountsi2.c\",\n        \"lib/builtins/popcountti2.c\",\n        \"lib/builtins/powidf2.c\",\n        \"lib/builtins/powisf2.c\",\n        \"lib/builtins/powitf2.c\",\n        \"lib/builtins/powixf2.c\",\n        \"lib/builtins/subdf3.c\",\n        \"lib/builtins/subsf3.c\",\n        \"lib/builtins/subtf3.c\",\n        \"lib/builtins/subvdi3.c\",\n        \"lib/builtins/subvsi3.c\",\n        \"lib/builtins/subvti3.c\",\n        \"lib/builtins/trampoline_setup.c\",\n        \"lib/builtins/truncdfhf2.c\",\n        \"lib/builtins/truncdfsf2.c\",\n        \"lib/builtins/truncsfhf2.c\",\n        \"lib/builtins/trunctfdf2.c\",\n        \"lib/builtins/trunctfsf2.c\",\n        \"lib/builtins/ucmpdi2.c\",\n        \"lib/builtins/ucmpti2.c\",\n        \"lib/builtins/udivdi3.c\",\n        \"lib/builtins/udivmoddi4.c\",\n        \"lib/builtins/udivmodsi4.c\",\n        \"lib/builtins/udivmodti4.c\",\n        \"lib/builtins/udivsi3.c\",\n        \"lib/builtins/udivti3.c\",\n        \"lib/builtins/umoddi3.c\",\n        \"lib/builtins/umodsi3.c\",\n        \"lib/builtins/umodti3.c\",\n    ],\n\n    cflags: [\n        \"-Wno-unused-parameter\",\n        \"-Werror\",\n    ],\n\n    arch: {\n        arm: {\n            cflags: [\"-D__ARM_EABI__\"],\n            srcs: [\n                \"lib/builtins/arm/aeabi_dcmp.S\",\n                \"lib/builtins/arm/aeabi_div0.c\",\n                \"lib/builtins/arm/aeabi_fcmp.S\",\n                \"lib/builtins/arm/aeabi_idivmod.S\",\n                \"lib/builtins/arm/aeabi_ldivmod.S\",\n                \"lib/builtins/arm/aeabi_memcmp.S\",\n                \"lib/builtins/arm/aeabi_memcpy.S\",\n                \"lib/builtins/arm/aeabi_memmove.S\",\n                \"lib/builtins/arm/aeabi_memset.S\",\n                \"lib/builtins/arm/aeabi_uidivmod.S\",\n                \"lib/builtins/arm/aeabi_uldivmod.S\",\n                \"lib/builtins/arm/comparesf2.S\",\n                \"lib/builtins/arm/divmodsi4.S\",\n                \"lib/builtins/arm/divsi3.S\",\n                \"lib/builtins/arm/modsi3.S\",\n                \"lib/builtins/arm/udivmodsi4.S\",\n                \"lib/builtins/arm/udivsi3.S\",\n                \"lib/builtins/arm/umodsi3.S\",\n                \"lib/builtins/arm/adddf3vfp.S\",\n                \"lib/builtins/arm/addsf3vfp.S\",\n                \"lib/builtins/arm/divdf3vfp.S\",\n                \"lib/builtins/arm/divsf3vfp.S\",\n                \"lib/builtins/arm/eqdf2vfp.S\",\n                \"lib/builtins/arm/eqsf2vfp.S\",\n                \"lib/builtins/arm/extendsfdf2vfp.S\",\n                \"lib/builtins/arm/fixdfsivfp.S\",\n                \"lib/builtins/arm/fixsfsivfp.S\",\n                \"lib/builtins/arm/fixunsdfsivfp.S\",\n                \"lib/builtins/arm/fixunssfsivfp.S\",\n                \"lib/builtins/arm/floatsidfvfp.S\",\n                \"lib/builtins/arm/floatsisfvfp.S\",\n                \"lib/builtins/arm/floatunssidfvfp.S\",\n                \"lib/builtins/arm/floatunssisfvfp.S\",\n                \"lib/builtins/arm/gedf2vfp.S\",\n                \"lib/builtins/arm/gesf2vfp.S\",\n                \"lib/builtins/arm/gtdf2vfp.S\",\n                \"lib/builtins/arm/gtsf2vfp.S\",\n                \"lib/builtins/arm/ledf2vfp.S\",\n                \"lib/builtins/arm/lesf2vfp.S\",\n                \"lib/builtins/arm/ltdf2vfp.S\",\n                \"lib/builtins/arm/ltsf2vfp.S\",\n                \"lib/builtins/arm/muldf3vfp.S\",\n                \"lib/builtins/arm/mulsf3vfp.S\",\n                \"lib/builtins/arm/nedf2vfp.S\",\n                \"lib/builtins/arm/negdf2vfp.S\",\n                \"lib/builtins/arm/negsf2vfp.S\",\n                \"lib/builtins/arm/nesf2vfp.S\",\n                \"lib/builtins/arm/subdf3vfp.S\",\n                \"lib/builtins/arm/subsf3vfp.S\",\n                \"lib/builtins/arm/truncdfsf2vfp.S\",\n                \"lib/builtins/arm/unorddf2vfp.S\",\n                \"lib/builtins/arm/unordsf2vfp.S\",\n            ],\n            exclude_srcs: [\n                \"lib/builtins/comparesf2.c\",\n                \"lib/builtins/divmodsi4.c\",\n                \"lib/builtins/divsi3.c\",\n                \"lib/builtins/modsi3.c\",\n                \"lib/builtins/udivmodsi4.c\",\n                \"lib/builtins/udivsi3.c\",\n                \"lib/builtins/umodsi3.c\",\n            ],\n        },\n        mips64: {\n            cflags: [\n                \"-DCRT_HAS_128BIT\",\n            ],\n        },\n        x86: {\n            srcs: [\n                \"lib/builtins/i386/ashldi3.S\",\n                \"lib/builtins/i386/ashrdi3.S\",\n                \"lib/builtins/i386/divdi3.S\",\n                \"lib/builtins/i386/floatdidf.S\",\n                \"lib/builtins/i386/floatdisf.S\",\n                \"lib/builtins/i386/floatdixf.S\",\n                \"lib/builtins/i386/floatundidf.S\",\n                \"lib/builtins/i386/floatundisf.S\",\n                \"lib/builtins/i386/floatundixf.S\",\n                \"lib/builtins/i386/lshrdi3.S\",\n                \"lib/builtins/i386/moddi3.S\",\n                \"lib/builtins/i386/muldi3.S\",\n                \"lib/builtins/i386/udivdi3.S\",\n                \"lib/builtins/i386/umoddi3.S\",\n            ],\n            exclude_srcs: [\n                \"lib/builtins/ashldi3.c\",\n                \"lib/builtins/ashrdi3.c\",\n                \"lib/builtins/divdi3.c\",\n                \"lib/builtins/floatdidf.c\",\n                \"lib/builtins/floatdisf.c\",\n                \"lib/builtins/floatdixf.c\",\n                \"lib/builtins/floatundidf.c\",\n                \"lib/builtins/floatundisf.c\",\n                \"lib/builtins/floatundixf.c\",\n                \"lib/builtins/lshrdi3.c\",\n                \"lib/builtins/moddi3.c\",\n                \"lib/builtins/muldi3.c\",\n                \"lib/builtins/udivdi3.c\",\n                \"lib/builtins/umoddi3.c\",\n            ],\n        },\n        x86_64: {\n            srcs: [\n                \"lib/builtins/x86_64/floatundixf.S\",\n                \"lib/builtins/x86_64/floatdisf.c\",\n                \"lib/builtins/x86_64/floatdidf.c\",\n                \"lib/builtins/x86_64/floatdixf.c\",\n                \"lib/builtins/x86_64/floatundisf.S\",\n                \"lib/builtins/x86_64/floatundidf.S\",\n            ],\n            exclude_srcs: [\n                \"lib/builtins/floatundixf.c\",\n                \"lib/builtins/floatdisf.c\",\n                \"lib/builtins/floatdidf.c\",\n                \"lib/builtins/floatdixf.c\",\n                \"lib/builtins/floatundisf.c\",\n                \"lib/builtins/floatundidf.c\",\n            ],\n        },\n    },\n\n    target: {\n        not_windows: {\n            // Only build enable_execute_stack.c on non-Windows hosts.\n            srcs: [\"lib/builtins/enable_execute_stack.c\"],\n            host_ldlibs: [\n                \"-lpthread\",\n                \"-lc\",\n                \"-lm\",\n            ],\n        },\n        android: {\n            srcs: [\"lib/builtins/enable_execute_stack.c\"],\n            shared_libs: [\"libdl\", \"liblog\"],\n            static_libs: [\"liblzma\"],\n        },\n        android_arm: {\n            static_libs: [\"libunwind_llvm\"],\n            ldflags: [\"-Wl,--exclude-libs,libunwind_llvm.a\"],\n        },\n        android_arm64: {\n            // b/26968262 liblzma needs to be after libunwindbacktrace\n            static_libs: [\"libunwindbacktrace\",\"liblzma\"],\n            ldflags: [\"-Wl,--exclude-libs,libunwindbacktrace.a\"],\n        },\n        android_mips: {\n            // b/26968262 liblzma needs to be after libunwindbacktrace\n            static_libs: [\"libunwindbacktrace\",\"liblzma\"],\n            ldflags: [\"-Wl,--exclude-libs,libunwindbacktrace.a\"],\n        },\n        android_mips64: {\n            // b/26968262 liblzma needs to be after libunwindbacktrace\n            static_libs: [\"libunwindbacktrace\",\"liblzma\"],\n            ldflags: [\"-Wl,--exclude-libs,libunwindbacktrace.a\"],\n        },\n        android_x86: {\n            // b/26968262 liblzma needs to be after libunwindbacktrace\n            static_libs: [\"libunwindbacktrace\",\"liblzma\"],\n            ldflags: [\"-Wl,--exclude-libs,libunwindbacktrace.a\"],\n        },\n        android_x86_64: {\n            srcs: [\"lib/builtins/ppc/floatditf.c\"],\n            // b/26968262 liblzma needs to be after libunwindbacktrace\n            static_libs: [\"libunwindbacktrace\",\"liblzma\"],\n            ldflags: [\"-Wl,--exclude-libs,libunwindbacktrace.a\"],\n        },\n        linux: {\n            static_libs: [\"libunwindbacktrace\"],\n        },\n        windows: {\n            static_libs: [\"libunwindbacktrace\"],\n        },\n    },\n\n    asflags: [\"-integrated-as\"],\n    clang: true,\n    no_libgcc: true,\n\n    sanitize: [\"never\"],\n    stl: \"none\",\n}\n\n// Build asan, lsan, etc.\n// ANDROIDMK TRANSLATION ERROR: unsupported include\n// include $(call all-makefiles-under,$(LOCAL_PATH)/lib)\n// ANDROIDMK TRANSLATION ERROR: unsupported directive\n// endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/Android.mk",
    "content": "#\n# Copyright (C) 2012 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n#\n\nLOCAL_PATH := $(call my-dir)\n\n\n# The following list contains platform-independent functionalities.\n#\n# Skip apple_versioning.c since it is unused.\n# Skip atomic.c since it needs to be built separately according to the docs.\nlibcompiler_rt_common_SRC_FILES := \\\n  lib/builtins/absvdi2.c \\\n  lib/builtins/absvsi2.c \\\n  lib/builtins/absvti2.c \\\n  lib/builtins/adddf3.c \\\n  lib/builtins/addsf3.c \\\n  lib/builtins/addtf3.c \\\n  lib/builtins/addvdi3.c \\\n  lib/builtins/addvsi3.c \\\n  lib/builtins/addvti3.c \\\n  lib/builtins/ashldi3.c \\\n  lib/builtins/ashlti3.c \\\n  lib/builtins/ashrdi3.c \\\n  lib/builtins/ashrti3.c \\\n  lib/builtins/clear_cache.c \\\n  lib/builtins/clzdi2.c \\\n  lib/builtins/clzsi2.c \\\n  lib/builtins/clzti2.c \\\n  lib/builtins/cmpdi2.c \\\n  lib/builtins/cmpti2.c \\\n  lib/builtins/comparedf2.c \\\n  lib/builtins/comparesf2.c \\\n  lib/builtins/comparetf2.c \\\n  lib/builtins/ctzdi2.c \\\n  lib/builtins/ctzsi2.c \\\n  lib/builtins/ctzti2.c \\\n  lib/builtins/divdc3.c \\\n  lib/builtins/divdf3.c \\\n  lib/builtins/divdi3.c \\\n  lib/builtins/divmoddi4.c \\\n  lib/builtins/divmodsi4.c \\\n  lib/builtins/divsc3.c \\\n  lib/builtins/divsf3.c \\\n  lib/builtins/divsi3.c \\\n  lib/builtins/divtf3.c \\\n  lib/builtins/divti3.c \\\n  lib/builtins/divxc3.c \\\n  lib/builtins/eprintf.c \\\n  lib/builtins/extenddftf2.c \\\n  lib/builtins/extendhfsf2.c \\\n  lib/builtins/extendsfdf2.c \\\n  lib/builtins/extendsftf2.c \\\n  lib/builtins/ffsdi2.c \\\n  lib/builtins/ffsti2.c \\\n  lib/builtins/fixdfdi.c \\\n  lib/builtins/fixdfsi.c \\\n  lib/builtins/fixdfti.c \\\n  lib/builtins/fixsfdi.c \\\n  lib/builtins/fixsfsi.c \\\n  lib/builtins/fixsfti.c \\\n  lib/builtins/fixtfdi.c \\\n  lib/builtins/fixtfsi.c \\\n  lib/builtins/fixtfti.c \\\n  lib/builtins/fixunsdfdi.c \\\n  lib/builtins/fixunsdfsi.c \\\n  lib/builtins/fixunsdfti.c \\\n  lib/builtins/fixunssfdi.c \\\n  lib/builtins/fixunssfsi.c \\\n  lib/builtins/fixunssfti.c \\\n  lib/builtins/fixunstfdi.c \\\n  lib/builtins/fixunstfsi.c \\\n  lib/builtins/fixunstfti.c \\\n  lib/builtins/fixunsxfdi.c \\\n  lib/builtins/fixunsxfsi.c \\\n  lib/builtins/fixunsxfti.c \\\n  lib/builtins/fixxfdi.c \\\n  lib/builtins/fixxfti.c \\\n  lib/builtins/floatdidf.c \\\n  lib/builtins/floatdisf.c \\\n  lib/builtins/floatdixf.c \\\n  lib/builtins/floatsidf.c \\\n  lib/builtins/floatsisf.c \\\n  lib/builtins/floatsitf.c \\\n  lib/builtins/floattidf.c \\\n  lib/builtins/floattisf.c \\\n  lib/builtins/floattixf.c \\\n  lib/builtins/floatundidf.c \\\n  lib/builtins/floatundisf.c \\\n  lib/builtins/floatundixf.c \\\n  lib/builtins/floatunsidf.c \\\n  lib/builtins/floatunsisf.c \\\n  lib/builtins/floatunsitf.c \\\n  lib/builtins/floatuntidf.c \\\n  lib/builtins/floatuntisf.c \\\n  lib/builtins/floatuntixf.c \\\n  lib/builtins/gcc_personality_v0.c \\\n  lib/builtins/int_util.c \\\n  lib/builtins/lshrdi3.c \\\n  lib/builtins/lshrti3.c \\\n  lib/builtins/moddi3.c \\\n  lib/builtins/modsi3.c \\\n  lib/builtins/modti3.c \\\n  lib/builtins/muldc3.c \\\n  lib/builtins/muldf3.c \\\n  lib/builtins/muldi3.c \\\n  lib/builtins/mulodi4.c \\\n  lib/builtins/mulosi4.c \\\n  lib/builtins/muloti4.c \\\n  lib/builtins/mulsc3.c \\\n  lib/builtins/mulsf3.c \\\n  lib/builtins/multf3.c \\\n  lib/builtins/multi3.c \\\n  lib/builtins/mulvdi3.c \\\n  lib/builtins/mulvsi3.c \\\n  lib/builtins/mulvti3.c \\\n  lib/builtins/mulxc3.c \\\n  lib/builtins/negdf2.c \\\n  lib/builtins/negdi2.c \\\n  lib/builtins/negsf2.c \\\n  lib/builtins/negti2.c \\\n  lib/builtins/negvdi2.c \\\n  lib/builtins/negvsi2.c \\\n  lib/builtins/negvti2.c \\\n  lib/builtins/paritydi2.c \\\n  lib/builtins/paritysi2.c \\\n  lib/builtins/parityti2.c \\\n  lib/builtins/popcountdi2.c \\\n  lib/builtins/popcountsi2.c \\\n  lib/builtins/popcountti2.c \\\n  lib/builtins/powidf2.c \\\n  lib/builtins/powisf2.c \\\n  lib/builtins/powitf2.c \\\n  lib/builtins/powixf2.c \\\n  lib/builtins/subdf3.c \\\n  lib/builtins/subsf3.c \\\n  lib/builtins/subtf3.c \\\n  lib/builtins/subvdi3.c \\\n  lib/builtins/subvsi3.c \\\n  lib/builtins/subvti3.c \\\n  lib/builtins/trampoline_setup.c \\\n  lib/builtins/truncdfhf2.c \\\n  lib/builtins/truncdfsf2.c \\\n  lib/builtins/truncsfhf2.c \\\n  lib/builtins/trunctfdf2.c \\\n  lib/builtins/trunctfsf2.c \\\n  lib/builtins/ucmpdi2.c \\\n  lib/builtins/ucmpti2.c \\\n  lib/builtins/udivdi3.c \\\n  lib/builtins/udivmoddi4.c \\\n  lib/builtins/udivmodsi4.c \\\n  lib/builtins/udivmodti4.c \\\n  lib/builtins/udivsi3.c \\\n  lib/builtins/udivti3.c \\\n  lib/builtins/umoddi3.c \\\n  lib/builtins/umodsi3.c \\\n  lib/builtins/umodti3.c\n\n# ARM-specific runtimes\nlibcompiler_rt_arm_SRC_FILES := \\\n  lib/builtins/arm/aeabi_dcmp.S \\\n  lib/builtins/arm/aeabi_div0.c \\\n  lib/builtins/arm/aeabi_fcmp.S \\\n  lib/builtins/arm/aeabi_idivmod.S \\\n  lib/builtins/arm/aeabi_ldivmod.S \\\n  lib/builtins/arm/aeabi_memcmp.S \\\n  lib/builtins/arm/aeabi_memcpy.S \\\n  lib/builtins/arm/aeabi_memmove.S \\\n  lib/builtins/arm/aeabi_memset.S \\\n  lib/builtins/arm/aeabi_uidivmod.S \\\n  lib/builtins/arm/aeabi_uldivmod.S \\\n  lib/builtins/arm/comparesf2.S \\\n  lib/builtins/arm/divmodsi4.S \\\n  lib/builtins/arm/divsi3.S \\\n  lib/builtins/arm/modsi3.S \\\n  lib/builtins/arm/udivmodsi4.S \\\n  lib/builtins/arm/udivsi3.S \\\n  lib/builtins/arm/umodsi3.S \\\n  lib/builtins/arm/adddf3vfp.S \\\n  lib/builtins/arm/addsf3vfp.S \\\n  lib/builtins/arm/divdf3vfp.S \\\n  lib/builtins/arm/divsf3vfp.S \\\n  lib/builtins/arm/eqdf2vfp.S \\\n  lib/builtins/arm/eqsf2vfp.S \\\n  lib/builtins/arm/extendsfdf2vfp.S \\\n  lib/builtins/arm/fixdfsivfp.S \\\n  lib/builtins/arm/fixsfsivfp.S \\\n  lib/builtins/arm/fixunsdfsivfp.S \\\n  lib/builtins/arm/fixunssfsivfp.S \\\n  lib/builtins/arm/floatsidfvfp.S \\\n  lib/builtins/arm/floatsisfvfp.S \\\n  lib/builtins/arm/floatunssidfvfp.S \\\n  lib/builtins/arm/floatunssisfvfp.S \\\n  lib/builtins/arm/gedf2vfp.S \\\n  lib/builtins/arm/gesf2vfp.S \\\n  lib/builtins/arm/gtdf2vfp.S \\\n  lib/builtins/arm/gtsf2vfp.S \\\n  lib/builtins/arm/ledf2vfp.S \\\n  lib/builtins/arm/lesf2vfp.S \\\n  lib/builtins/arm/ltdf2vfp.S \\\n  lib/builtins/arm/ltsf2vfp.S \\\n  lib/builtins/arm/muldf3vfp.S \\\n  lib/builtins/arm/mulsf3vfp.S \\\n  lib/builtins/arm/nedf2vfp.S \\\n  lib/builtins/arm/negdf2vfp.S \\\n  lib/builtins/arm/negsf2vfp.S \\\n  lib/builtins/arm/nesf2vfp.S \\\n  lib/builtins/arm/subdf3vfp.S \\\n  lib/builtins/arm/subsf3vfp.S \\\n  lib/builtins/arm/truncdfsf2vfp.S \\\n  lib/builtins/arm/unorddf2vfp.S \\\n  lib/builtins/arm/unordsf2vfp.S\n\n\n# ARM64-specific runtimes\nlibcompiler_rt_arm64_SRC_FILES :=\n\n# MIPS-specific runtimes\nlibcompiler_rt_mips_SRC_FILES := # nothing to add\nlibcompiler_rt_mips64_SRC_FILES := # nothing to add\n\n# X86-specific runtimes\nlibcompiler_rt_x86_SRC_FILES := \\\n  lib/builtins/i386/ashldi3.S \\\n  lib/builtins/i386/ashrdi3.S \\\n  lib/builtins/i386/divdi3.S \\\n  lib/builtins/i386/floatdidf.S \\\n  lib/builtins/i386/floatdisf.S \\\n  lib/builtins/i386/floatdixf.S \\\n  lib/builtins/i386/floatundidf.S \\\n  lib/builtins/i386/floatundisf.S \\\n  lib/builtins/i386/floatundixf.S \\\n  lib/builtins/i386/lshrdi3.S \\\n  lib/builtins/i386/moddi3.S \\\n  lib/builtins/i386/muldi3.S \\\n  lib/builtins/i386/udivdi3.S \\\n  lib/builtins/i386/umoddi3.S\n\n# X86_64-specific runtimes\nlibcompiler_rt_x86_64_SRC_FILES := \\\n  lib/builtins/x86_64/floatundixf.S \\\n  lib/builtins/x86_64/floatdisf.c \\\n  lib/builtins/x86_64/floatdidf.c \\\n  lib/builtins/x86_64/floatdixf.c \\\n  lib/builtins/x86_64/floatundisf.S \\\n  lib/builtins/x86_64/floatundidf.S\n\n# The following list contains functions that are not available in libgcc.a, so\n# we potentially need them when using a Clang-built component (e.g., -ftrapv\n# with 64-bit integer multiplies. See http://llvm.org/bugs/show_bug.cgi?id=14469.)\nlibcompiler_rt_extras_SRC_FILES := \\\n  lib/builtins/mulodi4.c\n\n# $(1): arch\ndefine get-libcompiler-rt-source-files\n  $(if $(findstring $(1),arm),$(call get-libcompiler-rt-arm-source-files),\n      $(if $(findstring $(1),mips),$(call get-libcompiler-rt-mips-source-files),\n          $(if $(findstring $(1),x86),$(call get-libcompiler-rt-x86-source-files),\n             $(if $(findstring $(1),x86_64),$(call get-libcompiler-rt-x86_64-source-files),\n                 $(if $(findstring $(1),x32),$(call get-libcompiler-rt-x86-source-files),\n                    $(if $(findstring $(1),arm64),$(call get-libcompiler-rt-arm64-source-files),\n                       $(if $(findstring $(1),mips64),$(call get-libcompiler-rt-mips64-source-files),\n  $(error Unsupported ARCH $(1)))))))))\nendef\n\n# $(1): source list\n# $(2): arch\n#\n# If lib/builtins/<arch>/X.[cS] is included in the source list, we should filter out lib/builtins/X.c\n# in the result source list (i.e., use the one optimized for the arch.) Otherwise\n# there'll be multiple definitions for one symbol.\ndefine filter-libcompiler-rt-common-source-files\n  $(filter-out $(patsubst lib/builtins/$(strip $(2))/%.S,lib/builtins/%.c,\\\n                          $(filter lib/builtins/$(strip $(2))/%.S,$(1))) \\\n               $(patsubst lib/builtins/$(strip $(2))/%.c,lib/builtins/%.c,\\\n                          $(filter lib/builtins/$(strip $(2))/%.c,$(1))),$(1))\nendef\n\ndefine get-libcompiler-rt-arm-source-files\n  $(call filter-libcompiler-rt-common-source-files,\n      $(libcompiler_rt_common_SRC_FILES) \\\n      $(libcompiler_rt_arm_SRC_FILES), arm)\nendef\n\ndefine get-libcompiler-rt-arm64-source-files\n  $(call filter-libcompiler-rt-common-source-files,\n      $(libcompiler_rt_common_SRC_FILES) \\\n      $(libcompiler_rt_arm64_SRC_FILES),arm64)\nendef\n\ndefine get-libcompiler-rt-mips-source-files\n  $(call filter-libcompiler-rt-common-source-files,\n      $(libcompiler_rt_common_SRC_FILES) \\\n      $(libcompiler_rt_mips_SRC_FILES),mips)\nendef\n\ndefine get-libcompiler-rt-mips64-source-files\n  $(call filter-libcompiler-rt-common-source-files,\n      $(libcompiler_rt_common_SRC_FILES) \\\n      $(libcompiler_rt_mips64_SRC_FILES),mips64)\nendef\n\ndefine get-libcompiler-rt-x86-source-files\n  $(call filter-libcompiler-rt-common-source-files,\n      $(libcompiler_rt_common_SRC_FILES) \\\n      $(libcompiler_rt_x86_SRC_FILES),i386)\nendef\n\ndefine get-libcompiler-rt-x86_64-source-files\n  $(call filter-libcompiler-rt-common-source-files,\n      $(libcompiler_rt_common_SRC_FILES) \\\n      $(libcompiler_rt_x86_64_SRC_FILES),x86_64)\nendef\n\nlibcompiler_rt_common_CFLAGS := \\\n  -Wno-unused-parameter \\\n  -Werror\n\n#=====================================================================\n# Device Static Library: libcompiler_rt-extras\n#=====================================================================\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libcompiler_rt-extras\nLOCAL_MODULE_TAGS := optional\nLOCAL_MODULE_CLASS := STATIC_LIBRARIES\nLOCAL_CFLAGS := $(libcompiler_rt_common_CFLAGS)\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := $(libcompiler_rt_extras_SRC_FILES)\nLOCAL_SRC_FILES_mips += lib/builtins/clear_cache.c\nLOCAL_SRC_FILES_mips64 += lib/builtins/clear_cache.c\nLOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk\nLOCAL_SANITIZE := never\nLOCAL_CXX_STL := none\n\ninclude $(BUILD_STATIC_LIBRARY)\n\n#=====================================================================\n# Host Static Library: libcompiler_rt-extras\n#=====================================================================\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libcompiler_rt-extras\nLOCAL_CFLAGS := $(libcompiler_rt_common_CFLAGS)\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := $(libcompiler_rt_extras_SRC_FILES)\nLOCAL_SANITIZE := never\nLOCAL_MULTILIB := both\nLOCAL_CXX_STL := none\nLOCAL_MODULE_HOST_OS := darwin linux windows\n\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\n# Don't build compiler-rt without clang\nifneq ($(WITHOUT_TARGET_CLANG), true)\n\n#=====================================================================\n# Device Static Library: libcompiler_rt\n#=====================================================================\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libcompiler_rt\nLOCAL_CFLAGS := $(libcompiler_rt_common_CFLAGS)\nLOCAL_CFLAGS_arm += -D__ARM_EABI__\nLOCAL_CFLAGS_mips64 += -DCRT_HAS_128BIT\nLOCAL_ASFLAGS := -integrated-as\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := lib/builtins/enable_execute_stack.c\nLOCAL_SRC_FILES_arm := $(call get-libcompiler-rt-source-files,arm)\nLOCAL_SRC_FILES_arm64 := $(call get-libcompiler-rt-source-files,arm64)\nLOCAL_SRC_FILES_mips := $(call get-libcompiler-rt-source-files,mips)\nLOCAL_SRC_FILES_mips64 := $(call get-libcompiler-rt-source-files,mips64)\nLOCAL_SRC_FILES_x86 := $(call get-libcompiler-rt-source-files,x86)\nLOCAL_SRC_FILES_x86_64 := $(call get-libcompiler-rt-source-files,x86_64)\nLOCAL_SRC_FILES_x86_64 += lib/builtins/ppc/floatditf.c\nLOCAL_MODULE_TARGET_ARCH := arm arm64 mips mips64 x86 x86_64\nLOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk\nLOCAL_SANITIZE := never\nLOCAL_CXX_STL := none\n\n# These don't actually link, but are required to get exported headers\nLOCAL_STATIC_LIBRARIES_arm64 := libunwindbacktrace\nLOCAL_STATIC_LIBRARIES_mips := libunwindbacktrace\nLOCAL_STATIC_LIBRARIES_mips64 := libunwindbacktrace\nLOCAL_STATIC_LIBRARIES_x86 := libunwindbacktrace\nLOCAL_STATIC_LIBRARIES_x86_64 := libunwindbacktrace\n\ninclude $(BUILD_STATIC_LIBRARY)\n\n#=====================================================================\n# Host Static Library: libcompiler_rt\n#=====================================================================\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libcompiler_rt\nLOCAL_CFLAGS := $(libcompiler_rt_common_CFLAGS)\nLOCAL_ASFLAGS := -integrated-as\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := $(call get-libcompiler-rt-source-files,x86_64)\n# Only build enable_execute_stack.c on non-Windows hosts.\nLOCAL_SRC_FILES_darwin := lib/builtins/enable_execute_stack.c\nLOCAL_SRC_FILES_linux := lib/builtins/enable_execute_stack.c\nLOCAL_SANITIZE := never\nLOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk\nLOCAL_MULTILIB := both\nLOCAL_CXX_STL := none\n\n# These don't actually link, but are required to get exported headers\nLOCAL_STATIC_LIBRARIES_linux := libunwindbacktrace\nLOCAL_STATIC_LIBRARIES_windows := libunwindbacktrace\n\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\n#=====================================================================\n# Device Shared Library: libcompiler_rt\n#=====================================================================\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libcompiler_rt\nLOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk\nLOCAL_WHOLE_STATIC_LIBRARIES := libcompiler_rt\nLOCAL_SHARED_LIBRARIES := libdl liblog\nLOCAL_STATIC_LIBRARIES := liblzma\nLOCAL_STATIC_LIBRARIES_arm := libunwind_llvm\nLOCAL_STATIC_LIBRARIES_arm64 := libunwindbacktrace\nLOCAL_STATIC_LIBRARIES_mips := libunwindbacktrace\nLOCAL_STATIC_LIBRARIES_mips64 := libunwindbacktrace\nLOCAL_STATIC_LIBRARIES_x86 := libunwindbacktrace\nLOCAL_STATIC_LIBRARIES_x86_64 := libunwindbacktrace\nLOCAL_LDFLAGS_arm := -Wl,--exclude-libs,libunwind_llvm.a\nLOCAL_LDFLAGS_arm64 := -Wl,--exclude-libs,libunwindbacktrace.a\nLOCAL_LDFLAGS_mips := -Wl,--exclude-libs,libunwindbacktrace.a\nLOCAL_LDFLAGS_mips64 := -Wl,--exclude-libs,libunwindbacktrace.a\nLOCAL_LDFLAGS_x86 := -Wl,--exclude-libs,libunwindbacktrace.a\nLOCAL_LDFLAGS_x86_64 := -Wl,--exclude-libs,libunwindbacktrace.a\nLOCAL_MODULE_TARGET_ARCH := arm arm64 mips mips64 x86 x86_64\nLOCAL_SANITIZE := never\nLOCAL_CXX_STL := none\nLOCAL_NO_LIBGCC := true\n\ninclude $(BUILD_SHARED_LIBRARY)\n\n#=====================================================================\n# Host Shared Library: libcompiler_rt\n#=====================================================================\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libcompiler_rt\nLOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk\nLOCAL_WHOLE_STATIC_LIBRARIES := libcompiler_rt\nLOCAL_STATIC_LIBRARIES_linux := libunwindbacktrace\nLOCAL_STATIC_LIBRARIES_windows := libunwindbacktrace\nLOCAL_CPPFLAGS := -nostdinc++\nLOCAL_LDFLAGS_darwin := -nodefaultlibs\nLOCAL_LDFLAGS_linux := -nodefaultlibs\nLOCAL_LDLIBS_darwin := -lpthread -lc -lm\nLOCAL_LDLIBS_linux := -lpthread -lc -lm\nLOCAL_MULTILIB := both\nLOCAL_SANITIZE := never\nLOCAL_CXX_STL := none\nLOCAL_NO_LIBGCC := true\n\ninclude $(BUILD_HOST_SHARED_LIBRARY)\n\n# Build asan, lsan, etc.\ninclude $(call all-makefiles-under,$(LOCAL_PATH)/lib)\n\nendif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/CMakeLists.txt",
    "content": "# CMake build for CompilerRT.\n#\n# This build assumes that CompilerRT is checked out into the\n# 'projects/compiler-rt' inside of an LLVM tree.\n# Standalone build system for CompilerRT is not yet ready.\n#\n# An important constraint of the build is that it only produces libraries\n# based on the ability of the host toolchain to target various platforms.\n\n# Check if compiler-rt is built as a standalone project.\nif (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)\n  project(CompilerRT C CXX ASM)\n  set(COMPILER_RT_STANDALONE_BUILD TRUE)\nelse()\n  set(COMPILER_RT_STANDALONE_BUILD FALSE)\nendif()\n\n# The CompilerRT build system requires CMake version 2.8.8 or higher in order\n# to use its support for building convenience \"libraries\" as a collection of\n# .o files. This is particularly useful in producing larger, more complex\n# runtime libraries.\nif (NOT MSVC)\n  cmake_minimum_required(VERSION 2.8.8)\nelse()\n  # Version 2.8.12.1 is required to build with Visual Studio 2013.\n  cmake_minimum_required(VERSION 2.8.12.1)\nendif()\n\n# FIXME: It may be removed when we use 2.8.12.\nif(CMAKE_VERSION VERSION_LESS 2.8.12)\n  # Invalidate a couple of keywords.\n  set(cmake_2_8_12_INTERFACE)\n  set(cmake_2_8_12_PRIVATE)\nelse()\n  # Use ${cmake_2_8_12_KEYWORD} intead of KEYWORD in target_link_libraries().\n  set(cmake_2_8_12_INTERFACE INTERFACE)\n  set(cmake_2_8_12_PRIVATE PRIVATE)\n  if(POLICY CMP0022)\n    cmake_policy(SET CMP0022 NEW) # automatic when 2.8.12 is required\n  endif()\nendif()\n\n# Top level target used to build all compiler-rt libraries.\nadd_custom_target(compiler-rt ALL)\n\noption(COMPILER_RT_BUILD_BUILTINS \"Build builtins\" ON)\nmark_as_advanced(COMPILER_RT_BUILD_BUILTINS)\noption(COMPILER_RT_BUILD_SANITIZERS \"Build sanitizers\" ON)\nmark_as_advanced(COMPILER_RT_BUILD_SANITIZERS)\n\nif (NOT COMPILER_RT_STANDALONE_BUILD)\n  # Compute the Clang version from the LLVM version.\n  # FIXME: We should be able to reuse CLANG_VERSION variable calculated\n  #        in Clang cmake files, instead of copying the rules here.\n  string(REGEX MATCH \"[0-9]+\\\\.[0-9]+(\\\\.[0-9]+)?\" CLANG_VERSION\n         ${PACKAGE_VERSION})\n  # Setup the paths where compiler-rt runtimes and headers should be stored.\n  set(COMPILER_RT_OUTPUT_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION})\n  set(COMPILER_RT_EXEC_OUTPUT_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})\n  set(COMPILER_RT_INSTALL_PATH lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION})\n  option(COMPILER_RT_INCLUDE_TESTS \"Generate and build compiler-rt unit tests.\"\n         ${LLVM_INCLUDE_TESTS})\n option(COMPILER_RT_ENABLE_WERROR \"Fail and stop if warning is triggered\"\n        ${LLVM_ENABLE_WERROR})\n  # Use just-built Clang to compile/link tests on all platforms, except for\n  # Windows where we need to use clang-cl instead.\n  if(NOT MSVC)\n    set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang)\n  else()\n    set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang.exe)\n  endif()\nelse()\n  # Take output dir and install path from the user.\n  set(COMPILER_RT_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH\n    \"Path where built compiler-rt libraries should be stored.\")\n  set(COMPILER_RT_EXEC_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin CACHE PATH\n    \"Path where built compiler-rt executables should be stored.\")\n  set(COMPILER_RT_INSTALL_PATH ${CMAKE_INSTALL_PREFIX} CACHE PATH\n    \"Path where built compiler-rt libraries should be installed.\")\n  option(COMPILER_RT_INCLUDE_TESTS \"Generate and build compiler-rt unit tests.\" OFF)\n  option(COMPILER_RT_ENABLE_WERROR \"Fail and stop if warning is triggered\" OFF)\n  # Use a host compiler to compile/link tests.\n  set(COMPILER_RT_TEST_COMPILER ${CMAKE_C_COMPILER} CACHE PATH \"Compiler to use for testing\")\n\n  if (NOT LLVM_CONFIG_PATH)\n    find_program(LLVM_CONFIG_PATH \"llvm-config\"\n                 DOC \"Path to llvm-config binary\")\n    if (NOT LLVM_CONFIG_PATH)\n      message(FATAL_ERROR \"llvm-config not found: specify LLVM_CONFIG_PATH\")\n    endif()\n  endif()\n  execute_process(\n    COMMAND ${LLVM_CONFIG_PATH} \"--obj-root\" \"--bindir\" \"--libdir\" \"--src-root\"\n    RESULT_VARIABLE HAD_ERROR\n    OUTPUT_VARIABLE CONFIG_OUTPUT)\n  if (HAD_ERROR)\n    message(FATAL_ERROR \"llvm-config failed with status ${HAD_ERROR}\")\n  endif()\n  string(REGEX REPLACE \"[ \\t]*[\\r\\n]+[ \\t]*\" \";\" CONFIG_OUTPUT ${CONFIG_OUTPUT})\n  list(GET CONFIG_OUTPUT 0 LLVM_BINARY_DIR)\n  list(GET CONFIG_OUTPUT 1 LLVM_TOOLS_BINARY_DIR)\n  list(GET CONFIG_OUTPUT 2 LLVM_LIBRARY_DIR)\n  list(GET CONFIG_OUTPUT 3 LLVM_MAIN_SRC_DIR)\n\n  # Make use of LLVM CMake modules.\n  file(TO_CMAKE_PATH ${LLVM_BINARY_DIR} LLVM_BINARY_DIR_CMAKE_STYLE)\n  set(LLVM_CMAKE_PATH \"${LLVM_BINARY_DIR_CMAKE_STYLE}/share/llvm/cmake\")\n  list(APPEND CMAKE_MODULE_PATH \"${LLVM_CMAKE_PATH}\")\n  # Get some LLVM variables from LLVMConfig.\n  include(\"${LLVM_CMAKE_PATH}/LLVMConfig.cmake\")\n\n  set(LLVM_LIBRARY_OUTPUT_INTDIR\n    ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX})\n\n  # Find Python interpreter.\n  set(Python_ADDITIONAL_VERSIONS 2.7 2.6 2.5)\n  include(FindPythonInterp)\n  if(NOT PYTHONINTERP_FOUND)\n    message(FATAL_ERROR \"\n      Unable to find Python interpreter required testing. Please install Python\n      or specify the PYTHON_EXECUTABLE CMake variable.\")\n  endif()\n\n  # Define default arguments to lit.\n  set(LIT_ARGS_DEFAULT \"-sv\")\n  if (MSVC OR XCODE)\n    set(LIT_ARGS_DEFAULT \"${LIT_ARGS_DEFAULT} --no-progress-bar\")\n  endif()\n  set(LLVM_LIT_ARGS \"${LIT_ARGS_DEFAULT}\" CACHE STRING \"Default options for lit\")\nendif()\n\nif(\"${COMPILER_RT_TEST_COMPILER}\" MATCHES \"clang[+]*$\")\n  set(COMPILER_RT_TEST_COMPILER_ID Clang)\nelseif(\"${COMPILER_RT_TEST_COMPILER}\" MATCHES \"clang.*.exe$\")\n  set(COMPILER_RT_TEST_COMPILER_ID Clang)\nelse()\n  set(COMPILER_RT_TEST_COMPILER_ID GNU)\nendif()\n\nset(COMPILER_RT_DEFAULT_TARGET_TRIPLE ${TARGET_TRIPLE} CACHE STRING\n    \"Default triple for which compiler-rt runtimes will be built.\")\nif(DEFINED COMPILER_RT_TEST_TARGET_TRIPLE)\n  # Backwards compatibility: this variable used to be called\n  # COMPILER_RT_TEST_TARGET_TRIPLE.\n  set(COMPILER_RT_DEFAULT_TARGET_TRIPLE ${COMPILER_RT_TEST_TARGET_TRIPLE})\nendif()\n\nstring(REPLACE \"-\" \";\" TARGET_TRIPLE_LIST ${COMPILER_RT_DEFAULT_TARGET_TRIPLE})\nlist(GET TARGET_TRIPLE_LIST 0 COMPILER_RT_DEFAULT_TARGET_ARCH)\nlist(GET TARGET_TRIPLE_LIST 1 COMPILER_RT_DEFAULT_TARGET_OS)\nlist(GET TARGET_TRIPLE_LIST 2 COMPILER_RT_DEFAULT_TARGET_ABI)\n# Determine if test target triple is specified explicitly, and doesn't match the\n# default.\nif(NOT COMPILER_RT_DEFAULT_TARGET_TRIPLE STREQUAL TARGET_TRIPLE)\n  set(COMPILER_RT_HAS_EXPLICIT_DEFAULT_TARGET_TRIPLE TRUE)\nelse()\n  set(COMPILER_RT_HAS_EXPLICIT_DEFAULT_TARGET_TRIPLE FALSE)\nendif()\n\nif (\"${COMPILER_RT_DEFAULT_TARGET_ABI}\" STREQUAL \"androideabi\")\n  set(ANDROID 1)\nendif()\n\nstring(TOLOWER ${CMAKE_SYSTEM_NAME} COMPILER_RT_OS_DIR)\nset(COMPILER_RT_LIBRARY_OUTPUT_DIR\n  ${COMPILER_RT_OUTPUT_DIR}/lib/${COMPILER_RT_OS_DIR})\nset(COMPILER_RT_LIBRARY_INSTALL_DIR\n  ${COMPILER_RT_INSTALL_PATH}/lib/${COMPILER_RT_OS_DIR})\n\n# Add path for custom compiler-rt modules.\nset(CMAKE_MODULE_PATH\n  \"${CMAKE_CURRENT_SOURCE_DIR}/cmake\"\n  \"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules\"\n  ${CMAKE_MODULE_PATH}\n  )\ninclude(CompilerRTUtils)\n\nset(COMPILER_RT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})\nset(COMPILER_RT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})\n\n# We support running instrumented tests when we're not cross compiling\n# and target a UNIX-like system or Windows.\n# We can run tests on Android even when we are cross-compiling.\nif((\"${CMAKE_HOST_SYSTEM}\" STREQUAL \"${CMAKE_SYSTEM}\" AND (UNIX OR WIN32)) OR ANDROID\n   OR COMPILER_RT_EMULATOR)\n  option(COMPILER_RT_CAN_EXECUTE_TESTS \"Can we execute instrumented tests\" ON)\nelse()\n  option(COMPILER_RT_CAN_EXECUTE_TESTS \"Can we execute instrumented tests\" OFF)\nendif()\n\noption(COMPILER_RT_DEBUG \"Build runtimes with full debug info\" OFF)\noption(COMPILER_RT_EXTERNALIZE_DEBUGINFO\n  \"Generate dSYM files and strip executables and libraries (Darwin Only)\" OFF)\n# COMPILER_RT_DEBUG_PYBOOL is used by lit.common.configured.in.\npythonize_bool(COMPILER_RT_DEBUG)\n\n#================================\n# Setup Compiler Flags\n#================================\ninclude(CheckIncludeFile)\ncheck_include_file(unwind.h HAVE_UNWIND_H)\n\ninclude(config-ix)\n\nif(MSVC)\n  append_string_if(COMPILER_RT_HAS_W3_FLAG /W3 CMAKE_C_FLAGS CMAKE_CXX_FLAGS)\nelse()\n  append_string_if(COMPILER_RT_HAS_WALL_FLAG -Wall CMAKE_C_FLAGS CMAKE_CXX_FLAGS)\nendif()\nif(COMPILER_RT_ENABLE_WERROR)\n  append_string_if(COMPILER_RT_HAS_WERROR_FLAG -Werror CMAKE_C_FLAGS CMAKE_CXX_FLAGS)\n  append_string_if(COMPILER_RT_HAS_WX_FLAG /WX CMAKE_C_FLAGS CMAKE_CXX_FLAGS)\nendif()\n\nappend_string_if(COMPILER_RT_HAS_STD_CXX11_FLAG -std=c++11 CMAKE_CXX_FLAGS)\n\n# Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP.\nif(NOT COMPILER_RT_HAS_FUNC_SYMBOL)\n  add_definitions(-D__func__=__FUNCTION__)\nendif()\n\n# Provide some common commmandline flags for Sanitizer runtimes.\nappend_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_FNO_BUILTIN_FLAG -fno-builtin SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_FNO_EXCEPTIONS_FLAG -fno-exceptions SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG -fomit-frame-pointer SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_FUNWIND_TABLES_FLAG -funwind-tables SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG -fno-stack-protector SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_FNO_SANITIZE_SAFE_STACK_FLAG -fno-sanitize=safe-stack SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG -fvisibility=hidden SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_FVISIBILITY_INLINES_HIDDEN_FLAG -fvisibility-inlines-hidden SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_FNO_FUNCTION_SECTIONS_FLAG -fno-function-sections SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto SANITIZER_COMMON_CFLAGS)\n\nif(MSVC)\n  # Replace the /M[DT][d] flags with /MT, and strip any definitions of _DEBUG,\n  # which cause definition mismatches at link time.\n  # FIXME: In fact, sanitizers should support both /MT and /MD, see PR20214.\n  if(COMPILER_RT_HAS_MT_FLAG)\n    foreach(flag_var\n      CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE\n      CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)\n      string(REGEX REPLACE \"/M[DT]d\" \"/MT\" ${flag_var} \"${${flag_var}}\")\n      string(REGEX REPLACE \"/MD\" \"/MT\" ${flag_var} \"${${flag_var}}\")\n      string(REGEX REPLACE \"/D_DEBUG\" \"\" ${flag_var} \"${${flag_var}}\")\n    endforeach()\n  endif()\n  append_list_if(COMPILER_RT_HAS_Oy_FLAG /Oy- SANITIZER_COMMON_CFLAGS)\n  append_list_if(COMPILER_RT_HAS_GS_FLAG /GS- SANITIZER_COMMON_CFLAGS)\nendif()\n\nappend_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 SANITIZER_COMMON_CFLAGS)\n\n# Build with optimization, unless we're in debug mode. If we're using MSVC,\n# always respect the optimization flags set by CMAKE_BUILD_TYPE instead.\nif(NOT COMPILER_RT_DEBUG AND NOT MSVC)\n  list(APPEND SANITIZER_COMMON_CFLAGS -O3)\nendif()\n\n# Determine if we should restrict stack frame sizes.\n# Stack frames on PowerPC and Mips and in debug biuld can be much larger than\n# anticipated.\n# FIXME: Fix all sanitizers and add -Wframe-larger-than to\n# SANITIZER_COMMON_FLAGS\nif(COMPILER_RT_HAS_WFRAME_LARGER_THAN_FLAG AND NOT COMPILER_RT_DEBUG\n   AND NOT ${COMPILER_RT_DEFAULT_TARGET_ARCH} MATCHES \"powerpc|mips\")\n  set(SANITIZER_LIMIT_FRAME_SIZE TRUE)\nelse()\n  set(SANITIZER_LIMIT_FRAME_SIZE FALSE)\nendif()\n\n# Build sanitizer runtimes with debug info.\nif(COMPILER_RT_HAS_GLINE_TABLES_ONLY_FLAG AND NOT COMPILER_RT_DEBUG)\n  list(APPEND SANITIZER_COMMON_CFLAGS -gline-tables-only)\nelseif(COMPILER_RT_HAS_G_FLAG)\n  list(APPEND SANITIZER_COMMON_CFLAGS -g)\nelseif(COMPILER_RT_HAS_Zi_FLAG)\n  list(APPEND SANITIZER_COMMON_CFLAGS /Zi)\nendif()\n\n# Turn off several warnings.\nappend_list_if(COMPILER_RT_HAS_WGNU_FLAG -Wno-gnu SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG -Wno-variadic-macros SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_WC99_EXTENSIONS_FLAG -Wno-c99-extensions SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_WNON_VIRTUAL_DTOR_FLAG -Wno-non-virtual-dtor SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_WD4146_FLAG /wd4146 SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_WD4291_FLAG /wd4291 SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_WD4391_FLAG /wd4391 SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_WD4722_FLAG /wd4722 SANITIZER_COMMON_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_WD4800_FLAG /wd4800 SANITIZER_COMMON_CFLAGS)\n\nif(APPLE AND SANITIZER_MIN_OSX_VERSION VERSION_LESS \"10.9\")\n  # Mac OS X prior to 10.9 had problems with exporting symbols from\n  # libc++/libc++abi.\n  set(SANITIZER_CAN_USE_CXXABI FALSE)\nelse()\n  set(SANITIZER_CAN_USE_CXXABI TRUE)\nendif()\npythonize_bool(SANITIZER_CAN_USE_CXXABI)\n\nadd_subdirectory(include)\n\nset(COMPILER_RT_LIBCXX_PATH ${LLVM_MAIN_SRC_DIR}/projects/libcxx)\nif(EXISTS ${COMPILER_RT_LIBCXX_PATH}/)\n  set(COMPILER_RT_HAS_LIBCXX_SOURCES TRUE)\nelse()\n  set(COMPILER_RT_HAS_LIBCXX_SOURCES FALSE)\nendif()\n\nset(COMPILER_RT_LLD_PATH ${LLVM_MAIN_SRC_DIR}/tools/lld)\nif(EXISTS ${COMPILER_RT_LLD_PATH}/)\n  set(COMPILER_RT_HAS_LLD_SOURCES TRUE)\nelse()\n  set(COMPILER_RT_HAS_LLD_SOURCES FALSE)\nendif()\npythonize_bool(COMPILER_RT_HAS_LLD_SOURCES)\n\nadd_subdirectory(lib)\n\nif(COMPILER_RT_INCLUDE_TESTS)\n  add_subdirectory(unittests)\n  add_subdirectory(test)\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/CODE_OWNERS.TXT",
    "content": "This file is a list of the people responsible for ensuring that patches for a\nparticular part of compiler-rt are reviewed, either by themself or by\nsomeone else. They are also the gatekeepers for their part of compiler-rt, with\nthe final word on what goes in or not.\n\nThe list is sorted by surname and formatted to allow easy grepping and\nbeautification by scripts. The fields are: name (N), email (E), web-address\n(W), PGP key ID and fingerprint (P), description (D), and snail-mail address\n(S).\n\nN: Peter Collingbourne\nE: peter@pcc.me.uk\nD: DataFlowSanitizer\n\nN: Daniel Dunbar\nE: daniel@zuster.org\nD: Makefile build\n\nN: Timur Iskhodzhanov\nE: timurrrr@google.com\nD: AddressSanitizer for Windows\n\nN: Howard Hinnant\nE: howard.hinnant@gmail.com\nD: builtins library\n\nN: Sergey Matveev\nE: earthdok@google.com\nD: LeakSanitizer\n\nN: Alexander Potapenko\nE: glider@google.com\nD: MacOS/iOS port of sanitizers\n\nN: Alexey Samsonov\nE: samsonov@google.com\nD: CMake build, test suite\n\nN: Kostya Serebryany\nE: kcc@google.com\nD: AddressSanitizer, sanitizer_common, porting sanitizers to another platforms\n\nN: Richard Smith\nE: richard-llvm@metafoo.co.uk\nD: UndefinedBehaviorSanitizer\n\nN: Evgeniy Stepanov\nE: eugenis@google.com\nD: MemorySanitizer, Android port of sanitizers\n\nN: Dmitry Vyukov\nE: dvyukov@google.com\nD: ThreadSanitizer\n\nN: Bill Wendling\nE: isanbard@gmail.com\nD: Profile runtime library\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/CREDITS.TXT",
    "content": "This file is a partial list of people who have contributed to the LLVM/CompilerRT\nproject.  If you have contributed a patch or made some other contribution to\nLLVM/CompilerRT, please submit a patch to this file to add yourself, and it will be\ndone!\n\nThe list is sorted by surname and formatted to allow easy grepping and\nbeautification by scripts.  The fields are: name (N), email (E), web-address\n(W), PGP key ID and fingerprint (P), description (D), and snail-mail address\n(S).\n\nN: Craig van Vliet\nE: cvanvliet@auroraux.org\nW: http://www.auroraux.org\nD: Code style and Readability fixes.\n\nN: Edward O'Callaghan\nE: eocallaghan@auroraux.org\nW: http://www.auroraux.org\nD: CMake'ify Compiler-RT build system\nD: Maintain Solaris & AuroraUX ports of Compiler-RT\n\nN: Howard Hinnant\nE: hhinnant@apple.com\nD: Architect and primary author of compiler-rt\n\nN: Guan-Hong Liu\nE: koviankevin@hotmail.com\nD: IEEE Quad-precision functions\n\nN: Joerg Sonnenberger\nE: joerg@NetBSD.org\nD: Maintains NetBSD port.\n\nN: Matt Thomas\nE: matt@NetBSD.org\nD: ARM improvements.\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/LICENSE.TXT",
    "content": "==============================================================================\ncompiler_rt License\n==============================================================================\n\nThe compiler_rt library is dual licensed under both the University of Illinois\n\"BSD-Like\" license and the MIT license.  As a user of this code you may choose\nto use it under either license.  As a contributor, you agree to allow your code\nto be used under both.\n\nFull text of the relevant licenses is included below.\n\n==============================================================================\n\nUniversity of Illinois/NCSA\nOpen Source License\n\nCopyright (c) 2009-2015 by the contributors listed in CREDITS.TXT\n\nAll rights reserved.\n\nDeveloped by:\n\n    LLVM Team\n\n    University of Illinois at Urbana-Champaign\n\n    http://llvm.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal with\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimers.\n\n    * Redistributions in binary form must reproduce the above copyright notice,\n      this list of conditions and the following disclaimers in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the names of the LLVM Team, University of Illinois at\n      Urbana-Champaign, nor the names of its contributors may be used to\n      endorse or promote products derived from this Software without specific\n      prior written permission.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\nCONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE\nSOFTWARE.\n\n==============================================================================\n\nCopyright (c) 2009-2015 by the contributors listed in CREDITS.TXT\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n==============================================================================\nCopyrights and Licenses for Third Party Software Distributed with LLVM:\n==============================================================================\nThe LLVM software contains code written by third parties.  Such software will\nhave its own individual LICENSE.TXT file in the directory in which it appears.\nThis file will describe the copyrights, license, and restrictions which apply\nto that code.\n\nThe disclaimer of warranty in the University of Illinois Open Source License\napplies to all code in the LLVM Distribution, and nothing in any of the\nother licenses gives permission to use the names of the LLVM Team or the\nUniversity of Illinois to endorse or promote products derived from this\nSoftware.\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/MODULE_LICENSE_MIT",
    "content": ""
  },
  {
    "path": "atlas-aapt/external/compiler-rt/Makefile",
    "content": "SubDirs := lib\n\n# Set default rule before anything else.\nall: help\n\ninclude make/config.mk\ninclude make/util.mk\n# If SRCROOT is defined, assume we are doing an Apple style build. We should be\n# able to use RC_XBS for this but that is unused during \"make installsrc\".\nifdef SRCROOT\n  include make/AppleBI.mk\nendif\n\n# Make sure we don't build with a missing ProjObjRoot.\nifeq ($(ProjObjRoot),)\n$(error Refusing to build with empty ProjObjRoot variable)\nendif\n\n##############\n\n###\n# Rules\n\n###\n# Top level targets\n\n# FIXME: Document the available subtargets.\nhelp:\n\t@echo \"usage: make [{VARIABLE=VALUE}*] target\"\n\t@echo\n\t@echo \"User variables:\"\n\t@echo \"  VERBOSE=1: Use to show all commands [default=0]\"\n\t@echo\n\t@echo \"Available targets:\"\n\t@echo \"  <platform name>: build the libraries for 'platform'\"\n\t@echo \"  clean:           clean all configurations\"\n\t@echo \"  test:            run unit tests\"\n\t@echo\n\t@echo \"  info-platforms:  list available platforms\"\n\t@echo \"  help-devel:      print additional help for developers\"\n\t@echo\n\nhelp-devel: help\n\t@echo \"Development targets:\"\n\t@echo \"  <platform name>-<config name>:\"\n\t@echo \"    build the libraries for a single platform config\"\n\t@echo \"  <platform name>-<config name>-<arch name>:\"\n\t@echo \"    build the libraries for a single config and arch\"\n\t@echo \"  info-functions: list available compiler-rt functions\"\n\t@echo \"  help-hidden: print help for Makefile debugging\"\n\t@echo\n\nhelp-hidden: help-devel\n\t@echo \"Debugging variables:\"\n\t@echo \"  DEBUGMAKE=1: enable some Makefile logging [default=]\"\n\t@echo \"           =2: enable more Makefile logging\"\n\t@echo\n\t@echo \"Debugging targets:\"\n\t@echo \"  make-print-FOO: print information on the variable 'FOO'\"\n\t@echo\n\ninfo-functions:\n\t@echo \"compiler-rt Available Functions\"\n\t@echo\n\t@echo \"All Functions: $(AvailableFunctions)\"\n\t@$(foreach fn,$(AvailableFunctions),\\\n\t  printf \"  %-20s - available in (%s)\\n\" $(fn)\\\n\t    \"$(foreach key,$(AvailableIn.$(fn)),$($(key).Dir))\";)\n\ninfo-platforms:\n\t@echo \"compiler-rt Available Platforms\"\n\t@echo\n\t@echo \"Platforms:\"\n\t@$(foreach key,$(PlatformKeys),\\\n\t  printf \"  %s - from '%s'\\n\" $($(key).Name) $($(key).Path);\\\n\t  printf \"    %s\\n\" \"$($(key).Description)\";\\\n\t  printf \"    Configurations: %s\\n\\n\" \"$($(key).Configs)\";)\n\n# Provide default clean target which is extended by other templates.\n.PHONY: clean\nclean::\n\n# Test\n.PHONY: test\ntest:\n\tcd test/Unit && ./test\n\n###\n# Directory handling magic.\n\n# Create directories as needed, and timestamp their creation.\n%/.dir:\n\t$(Summary) \"  MKDIR:     $*\"\n\t$(Verb) $(MKDIR) $* > /dev/null\n\t$(Verb) echo 'Created.' > $@\n\n# Remove directories\n%/.remove:\n\t$(Verb) $(RM) -r $*\n\n###\n# Include child makefile fragments\n\nDir := .\ninclude make/subdir.mk\ninclude make/lib_info.mk\ninclude make/lib_util.mk\ninclude make/lib_platforms.mk\n\n###\n# Define Platform Rules\n\ndefine PerPlatform_template\n$(call Set,Tmp.Key,$(1))\n$(call Set,Tmp.Name,$($(Tmp.Key).Name))\n$(call Set,Tmp.Configs,$($(Tmp.Key).Configs))\n$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name))\n\n# Top-Level Platform Target\n$(Tmp.Name):: $(Tmp.Configs:%=$(Tmp.Name)-%)\n.PHONY: $(Tmp.Name)\n\nclean::\n\t$(Verb) rm -rf $(Tmp.ObjPath)\n\n# Per-Config Libraries\n$(foreach config,$(Tmp.Configs),\\\n  $(call PerPlatformConfig_template,$(config)))\nendef\n\ndefine PerPlatformConfig_template\n$(call Set,Tmp.Config,$(1))\n$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config))\n$(call Set,Tmp.SHARED_LIBRARY,$(strip \\\n  $(call GetCNAVar,SHARED_LIBRARY,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n$(call Set,Tmp.SHARED_LIBRARY_SUFFIX,$(strip \\\n  $(call GetCNAVar,SHARED_LIBRARY_SUFFIX,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n\n# Compute the library suffix.\n$(if $(call streq,1,$(Tmp.SHARED_LIBRARY)),\n  $(call Set,Tmp.LibrarySuffix,$(Tmp.SHARED_LIBRARY_SUFFIX)),\n  $(call Set,Tmp.LibrarySuffix,a))\n\n# Compute the archs to build, depending on whether this is a universal build or\n# not.\n$(call Set,Tmp.ArchsToBuild,\\\n  $(if $(call IsDefined,$(Tmp.Key).UniversalArchs),\\\n       $(strip \\\n         $(or $($(Tmp.Key).UniversalArchs.$(Tmp.Config)),\\\n              $($(Tmp.Key).UniversalArchs))),\\\n       $(call VarOrDefault,$(Tmp.Key).Arch.$(Tmp.Config),$($(Tmp.Key).Arch))))\n\n# Copy or lipo to create the per-config library.\n$(call Set,Tmp.Inputs,$(Tmp.ArchsToBuild:%=$(Tmp.ObjPath)/%/libcompiler_rt.$(Tmp.LibrarySuffix)))\n$(Tmp.ObjPath)/libcompiler_rt.$(Tmp.LibrarySuffix): $(Tmp.Inputs) $(Tmp.ObjPath)/.dir\n\t$(Summary) \"  FINAL-ARCHIVE: $(Tmp.Name)/$(Tmp.Config): $$@\"\n\t-$(Verb) $(RM) $$@\n\t$(if $(call streq,1,$(words $(Tmp.ArchsToBuild))), \\\n\t  $(Verb) $(CP) $(Tmp.Inputs) $$@, \\\n\t  $(Verb) $(LIPO) -create -output $$@ $(Tmp.Inputs))\n.PRECIOUS: $(Tmp.ObjPath)/.dir\n\n# Per-Config Targets\n$(Tmp.Name)-$(Tmp.Config):: $(Tmp.ObjPath)/libcompiler_rt.$(Tmp.LibrarySuffix)\n.PHONY: $(Tmp.Name)-$(Tmp.Config)\n\n# Per-Config-Arch Libraries\n$(foreach arch,$(Tmp.ArchsToBuild),\\\n  $(call PerPlatformConfigArch_template,$(arch)))\nendef\n\ndefine PerPlatformConfigArch_template\n$(call Set,Tmp.Arch,$(1))\n$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch))\n$(call Set,Tmp.Functions,$(strip \\\n  $(AlwaysRequiredModules) \\\n  $(call GetCNAVar,FUNCTIONS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n$(call Set,Tmp.Optimized,$(strip \\\n  $(call GetCNAVar,OPTIMIZED,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n$(call Set,Tmp.AR,$(strip \\\n  $(call GetCNAVar,AR,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n$(call Set,Tmp.ARFLAGS,$(strip \\\n  $(call GetCNAVar,ARFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n$(call Set,Tmp.CC,$(strip \\\n  $(call GetCNAVar,CC,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n$(call Set,Tmp.LDFLAGS,$(strip \\\n  $(call GetCNAVar,LDFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n$(call Set,Tmp.RANLIB,$(strip \\\n  $(call GetCNAVar,RANLIB,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n$(call Set,Tmp.RANLIBFLAGS,$(strip \\\n  $(call GetCNAVar,RANLIBFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n$(call Set,Tmp.SHARED_LIBRARY,$(strip \\\n  $(call GetCNAVar,SHARED_LIBRARY,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n\n# Compute the library suffix.\n$(if $(call streq,1,$(Tmp.SHARED_LIBRARY)),\n  $(call Set,Tmp.LibrarySuffix,$(Tmp.SHARED_LIBRARY_SUFFIX)),\n  $(call Set,Tmp.LibrarySuffix,a))\n\n# Compute the object inputs for this library.\n$(call Set,Tmp.Inputs,\\\n  $(foreach fn,$(sort $(Tmp.Functions)),\\\n    $(call Set,Tmp.FnDir,\\\n      $(call SelectFunctionDir,$(Tmp.Config),$(Tmp.Arch),$(fn),$(Tmp.Optimized)))\\\n    $(Tmp.ObjPath)/$(Tmp.FnDir)/$(fn).o))\n$(Tmp.ObjPath)/libcompiler_rt.a: $(Tmp.Inputs) $(Tmp.ObjPath)/.dir\n\t$(Summary) \"  ARCHIVE:   $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$@\"\n\t-$(Verb) $(RM) $$@\n\t$(Verb) $(Tmp.AR) $(Tmp.ARFLAGS) $$@ $(Tmp.Inputs)\n\t$(Verb) $(Tmp.RANLIB) $(Tmp.RANLIBFLAGS) $$@\n$(Tmp.ObjPath)/libcompiler_rt.dylib: $(Tmp.Inputs) $(Tmp.ObjPath)/.dir\n\t$(Summary) \"  DYLIB:   $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$@\"\n\t$(Verb) $(Tmp.CC) -arch $(Tmp.Arch) -dynamiclib -o $$@ \\\n\t  $(Tmp.Inputs) $(Tmp.LDFLAGS)\n$(Tmp.ObjPath)/libcompiler_rt.so: $(Tmp.Inputs) $(Tmp.ObjPath)/.dir\n\t$(Summary) \"  SO:   $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$@\"\n\t$(Verb) $(Tmp.CC) -shared -o $$@ \\\n\t  $(Tmp.Inputs) $(Tmp.LDFLAGS)\n.PRECIOUS: $(Tmp.ObjPath)/.dir\n\n# Per-Config-Arch Targets\n$(Tmp.Name)-$(Tmp.Config)-$(Tmp.Arch):: $(Tmp.ObjPath)/libcompiler_rt.$(Tmp.LibrarySuffix)\n.PHONY: $(Tmp.Name)-$(Tmp.Config)-$(Tmp.Arch)\n\n# Per-Config-Arch-SubDir Objects\n$(foreach key,$(SubDirKeys),\\\n  $(call PerPlatformConfigArchSubDir_template,$(key)))\nendef\n\ndefine PerPlatformConfigArchSubDir_template\n$(call Set,Tmp.SubDirKey,$(1))\n$(call Set,Tmp.SubDir,$($(Tmp.SubDirKey).Dir))\n$(call Set,Tmp.SrcPath,$(ProjSrcRoot)/$(Tmp.SubDir))\n$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch)/$(Tmp.SubDirKey))\n$(call Set,Tmp.Dependencies,$($(Tmp.SubDirKey).Dependencies))\n$(call Set,Tmp.CC,$(strip \\\n  $(call GetCNAVar,CC,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n$(call Set,Tmp.KERNEL_USE,$(strip \\\n  $(call GetCNAVar,KERNEL_USE,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n$(call Set,Tmp.VISIBILITY_HIDDEN,$(strip \\\n  $(call GetCNAVar,VISIBILITY_HIDDEN,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n$(call Set,Tmp.CFLAGS,$(strip \\\n  $(if $(call IsDefined,$(Tmp.Key).UniversalArchs),-arch $(Tmp.Arch),)\\\n  $(if $(call streq,$(Tmp.VISIBILITY_HIDDEN),1),\\\n       -fvisibility=hidden -DVISIBILITY_HIDDEN,)\\\n  $(if $(call streq,$(Tmp.KERNEL_USE),1),\\\n       -mkernel -DKERNEL_USE,)\\\n  $(call GetCNAVar,CFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))\n\n$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.s $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir\n\t$(Summary) \"  ASSEMBLE:  $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<\"\n\t$(Verb) $(Tmp.CC) $(COMMON_ASMFLAGS) $(Tmp.CFLAGS)  -c -o $$@ $$<\n$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.S $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir\n\t$(Summary) \"  ASSEMBLE:  $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<\"\n\t$(Verb) $(Tmp.CC) $(COMMON_ASMFLAGS) $(Tmp.CFLAGS) -c -o $$@ $$<\n$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.c $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir\n\t$(Summary) \"  COMPILE:   $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<\"\n\t$(Verb) $(Tmp.CC) $(COMMON_CFLAGS) $(Tmp.CFLAGS) -c -o $$@ $$<\n$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.cc $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir\n\t$(Summary) \"  COMPILE:   $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<\"\n\t$(Verb) $(Tmp.CC) $(COMMON_CXXFLAGS) $(Tmp.CFLAGS) -c -o $$@ $$<\n.PRECIOUS: $(Tmp.ObjPath)/.dir\n\nendef\n\n# Run templates.\n$(foreach key,$(PlatformKeys),\\\n  $(eval $(call PerPlatform_template,$(key))))\n\n###\n\nifneq ($(DEBUGMAKE),)\n  $(info MAKE: Done processing Makefile)\n  $(info  )\nendif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/NOTICE",
    "content": "==============================================================================\ncompiler_rt License\n==============================================================================\n\nThe compiler_rt library is dual licensed under both the University of Illinois\n\"BSD-Like\" license and the MIT license.  As a user of this code you may choose\nto use it under either license.  As a contributor, you agree to allow your code\nto be used under both.\n\nFull text of the relevant licenses is included below.\n\n==============================================================================\n\nUniversity of Illinois/NCSA\nOpen Source License\n\nCopyright (c) 2009-2014 by the contributors listed in CREDITS.TXT\n\nAll rights reserved.\n\nDeveloped by:\n\n    LLVM Team\n\n    University of Illinois at Urbana-Champaign\n\n    http://llvm.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal with\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimers.\n\n    * Redistributions in binary form must reproduce the above copyright notice,\n      this list of conditions and the following disclaimers in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the names of the LLVM Team, University of Illinois at\n      Urbana-Champaign, nor the names of its contributors may be used to\n      endorse or promote products derived from this Software without specific\n      prior written permission.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\nCONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE\nSOFTWARE.\n\n==============================================================================\n\nCopyright (c) 2009-2014 by the contributors listed in CREDITS.TXT\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n==============================================================================\nCopyrights and Licenses for Third Party Software Distributed with LLVM:\n==============================================================================\nThe LLVM software contains code written by third parties.  Such software will\nhave its own individual LICENSE.TXT file in the directory in which it appears.\nThis file will describe the copyrights, license, and restrictions which apply\nto that code.\n\nThe disclaimer of warranty in the University of Illinois Open Source License\napplies to all code in the LLVM Distribution, and nothing in any of the\nother licenses gives permission to use the names of the LLVM Team or the\nUniversity of Illinois to endorse or promote products derived from this\nSoftware.\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/README.android",
    "content": "/*\n * README.android describes in high-level the compiler-rt changes that we\n * cannot push upstream to the llvm.org repository:\n *  - Changes due to Android's build system.\n *  - Changes due to Android's toolchain.\n *  - Changes due to the limitations in Android-based consumer electronics.\n *\n * Some of them are to-dos. If and when they are done, there will no longer be\n * merge conflicts with upstream on those parts.\n *\n * The file contains useful hints when we try to resolve future 3-way merge\n * conflicts.\n */\n\n* For JellyBean: Synced to upstream r155350\n* For JellyBean MR1: Synced to upstream r162279\n* For Jellybean MR2: Synced to upstream r177337\n* For Key Lime Pie: Synced to upstream r187889\n* For FUTURE: Synced to LLVM 3.4 r197381\n\n* Cherry-pick on 2014/2/11: https://llvm.org/svn/llvm-project/compiler-rt/trunk@201068 and https://llvm.org/svn/llvm-project/compiler-rt/trunk@201070\n* Recent downstreaming on 2013/2/11: Synced to r197381 (Contact srhines for merge questions.)\n* Recent downstreaming on 2013/8/8: Synced to r187889 (Contact srhines for merge questions.)\n* Recent downstreaming on 2013/6/13: Synced to r183849 (Contact srhines for merge questions.)\n* Recent downstreaming on 2013/5/3: Synced to r180792 (Contact srhines for merge questions.)\n* Recent downstreaming on 2013/3/18: Synced to r177337 (Contact srhines for merge questions.)\n* Recent downstreaming on 2013/3/5: Synced to r176091 (Contact srhines for merge questions.)\n* Recent downstreaming on 2013/1/8: Synced to r171802 (Contact srhines for merge questions.)\n* Recent downstreaming on 2012/08/23: Synced to r162279 (Contact srhines for merge questions.)\n* Recent downstreaming on 2012/08/15: Synced to r159129 (Contact sliao for merge questions.)\n* Cherry-pick on 2012/07/27: https://llvm.org/svn/llvm-project/compiler-rt/trunk@160853 for ASan (Contact srhines for merge questions.)\n* Cherry-pick on 2012/05/23: https://llvm.org/svn/llvm-project/compiler-rt/trunk@157318 for ASan (Contact srhines for merge questions.)\n* Recent downstreaming on 2012/04/25: Synced to r155350 (Contact sliao for merge questions.)\n* Recent downstreaming on 2012/03/08: Synced to r152058 (Contact srhines for merge questions.)\n\nTODO: This is still not building by default (no Android.mk files are present\nyet). Look at frameworks/compile/libbcc/runtime for potential starting points.\n\nTODO: Switch libbcc to use this version of compiler-rt instead of its own\ntweaked version.\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/README.txt",
    "content": "Compiler-RT\n================================\n\nThis directory and its subdirectories contain source code for the compiler\nsupport routines.\n\nCompiler-RT is open source software. You may freely distribute it under the\nterms of the license agreement found in LICENSE.txt.\n\n================================\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/cmake/Modules/AddCompilerRT.cmake",
    "content": "include(AddLLVM)\ninclude(ExternalProject)\ninclude(CompilerRTUtils)\n\n# Tries to add an \"object library\" target for a given list of OSs and/or\n# architectures with name \"<name>.<arch>\" for non-Darwin platforms if\n# architecture can be targeted, and \"<name>.<os>\" for Darwin platforms.\n# add_compiler_rt_object_libraries(<name>\n#                                  OS <os names>\n#                                  ARCHS <architectures>\n#                                  SOURCES <source files>\n#                                  CFLAGS <compile flags>\n#                                  DEFS <compile definitions>)\nfunction(add_compiler_rt_object_libraries name)\n  cmake_parse_arguments(LIB \"\" \"\" \"OS;ARCHS;SOURCES;CFLAGS;DEFS\" ${ARGN})\n  set(libnames)\n  if(APPLE)\n    foreach(os ${LIB_OS})\n      set(libname \"${name}.${os}\")\n      set(libnames ${libnames} ${libname})\n      set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS})\n      list_union(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)\n    endforeach()\n  else()\n    foreach(arch ${LIB_ARCHS})\n      set(libname \"${name}.${arch}\")\n      set(libnames ${libnames} ${libname})\n      set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS})\n      if(NOT CAN_TARGET_${arch})\n        message(FATAL_ERROR \"Architecture ${arch} can't be targeted\")\n        return()\n      endif()\n    endforeach()\n  endif()\n  \n  foreach(libname ${libnames})\n    add_library(${libname} OBJECT ${LIB_SOURCES})\n    set_target_compile_flags(${libname}\n      ${CMAKE_CXX_FLAGS} ${extra_cflags_${libname}} ${LIB_CFLAGS})\n    set_property(TARGET ${libname} APPEND PROPERTY\n      COMPILE_DEFINITIONS ${LIB_DEFS})\n    if(APPLE)\n      set_target_properties(${libname} PROPERTIES\n        OSX_ARCHITECTURES \"${LIB_ARCHS_${libname}}\")\n    endif()\n  endforeach()\nendfunction()\n\n# Takes a list of object library targets, and a suffix and appends the proper\n# TARGET_OBJECTS string to the output variable.\n# format_object_libs(<output> <suffix> ...)\nmacro(format_object_libs output suffix)\n  foreach(lib ${ARGN})\n    list(APPEND ${output} $<TARGET_OBJECTS:${lib}.${suffix}>)\n  endforeach()\nendmacro()\n\n# Adds static or shared runtime for a list of architectures and operating\n# systems and puts it in the proper directory in the build and install trees.\n# add_compiler_rt_runtime(<name>\n#                         {STATIC|SHARED}\n#                         ARCHS <architectures>\n#                         OS <os list>\n#                         SOURCES <source files>\n#                         CFLAGS <compile flags>\n#                         LINKFLAGS <linker flags>\n#                         DEFS <compile definitions>\n#                         LINK_LIBS <linked libraries> (only for shared library)\n#                         OBJECT_LIBS <object libraries to use as sources>\n#                         PARENT_TARGET <convenience parent target>)\nfunction(add_compiler_rt_runtime name type)\n  if(NOT type MATCHES \"^(STATIC|SHARED)$\")\n    message(FATAL_ERROR \"type argument must be STATIC or SHARED\")\n    return()\n  endif()\n  cmake_parse_arguments(LIB\n    \"\"\n    \"PARENT_TARGET\"\n    \"OS;ARCHS;SOURCES;CFLAGS;LINKFLAGS;DEFS;LINK_LIBS;OBJECT_LIBS\"\n    ${ARGN})\n  set(libnames)\n  if(APPLE)\n    foreach(os ${LIB_OS})\n      if(type STREQUAL \"STATIC\")\n        set(libname \"${name}_${os}\")\n      else()\n        set(libname \"${name}_${os}_dynamic\")\n        set(extra_linkflags_${libname} ${DARWIN_${os}_LINKFLAGS} ${LIB_LINKFLAGS})\n      endif()\n      list_union(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)\n      if(LIB_ARCHS_${libname})\n        list(APPEND libnames ${libname})\n        set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS} ${LIB_CFLAGS})\n        set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX})\n        set(sources_${libname} ${LIB_SOURCES})\n        format_object_libs(sources_${libname} ${os} ${LIB_OBJECT_LIBS})\n      endif()\n    endforeach()\n  else()\n    foreach(arch ${LIB_ARCHS})\n      if(NOT CAN_TARGET_${arch})\n        message(FATAL_ERROR \"Architecture ${arch} can't be targeted\")\n        return()\n      endif()\n      if(type STREQUAL \"STATIC\")\n        set(libname \"${name}-${arch}\")\n        set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX})\n      else()\n        set(libname \"${name}-dynamic-${arch}\")\n        set(extra_linkflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS} ${LIB_LINKFLAGS})\n        if(WIN32)\n          set(output_name_${libname} ${name}_dynamic-${arch}${COMPILER_RT_OS_SUFFIX})\n        else()\n          set(output_name_${libname} ${name}-${arch}${COMPILER_RT_OS_SUFFIX})\n        endif()\n      endif()\n      set(sources_${libname} ${LIB_SOURCES})\n      format_object_libs(sources_${libname} ${arch} ${LIB_OBJECT_LIBS})\n      set(libnames ${libnames} ${libname})\n      set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS})\n    endforeach()\n  endif()\n\n  if(NOT libnames)\n    return()\n  endif()\n\n  if(LIB_PARENT_TARGET)\n    set(COMPONENT_OPTION COMPONENT ${LIB_PARENT_TARGET})\n  endif()\n\n  foreach(libname ${libnames})\n    add_library(${libname} ${type} ${sources_${libname}})\n    set_target_compile_flags(${libname} ${extra_cflags_${libname}})\n    set_target_link_flags(${libname} ${extra_linkflags_${libname}})\n    set_property(TARGET ${libname} APPEND PROPERTY \n                COMPILE_DEFINITIONS ${LIB_DEFS})\n    set_target_properties(${libname} PROPERTIES\n        ARCHIVE_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}\n        LIBRARY_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}\n        RUNTIME_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR})\n    set_target_properties(${libname} PROPERTIES\n        OUTPUT_NAME ${output_name_${libname}})\n    if(LIB_LINK_LIBS AND ${type} STREQUAL \"SHARED\")\n      target_link_libraries(${libname} ${LIB_LINK_LIBS})\n    endif()\n    install(TARGETS ${libname}\n      ARCHIVE DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}\n              ${COMPONENT_OPTION}\n      LIBRARY DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}\n              ${COMPONENT_OPTION}\n      RUNTIME DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}\n              ${COMPONENT_OPTION})\n    if(APPLE)\n      set_target_properties(${libname} PROPERTIES\n      OSX_ARCHITECTURES \"${LIB_ARCHS_${libname}}\")\n    endif()\n\n    if(type STREQUAL \"SHARED\")\n      rt_externalize_debuginfo(${libname})\n    endif()\n  endforeach()\n  if(LIB_PARENT_TARGET)\n    add_dependencies(${LIB_PARENT_TARGET} ${libnames})\n  endif()\nendfunction()\n\nset(COMPILER_RT_TEST_CFLAGS)\n\n# Unittests support.\nset(COMPILER_RT_GTEST_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest)\nset(COMPILER_RT_GTEST_SOURCE ${COMPILER_RT_GTEST_PATH}/src/gtest-all.cc)\nset(COMPILER_RT_GTEST_CFLAGS\n  -DGTEST_NO_LLVM_RAW_OSTREAM=1\n  -DGTEST_HAS_RTTI=0\n  -I${COMPILER_RT_GTEST_PATH}/include\n  -I${COMPILER_RT_GTEST_PATH}\n)\n\nappend_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 COMPILER_RT_TEST_CFLAGS)\n\nif(MSVC)\n  # clang doesn't support exceptions on Windows yet.\n  list(APPEND COMPILER_RT_TEST_CFLAGS -D_HAS_EXCEPTIONS=0)\n\n  # We should teach clang to understand \"#pragma intrinsic\", see PR19898.\n  list(APPEND COMPILER_RT_TEST_CFLAGS -Wno-undefined-inline)\n\n  # Clang doesn't support SEH on Windows yet.\n  list(APPEND COMPILER_RT_GTEST_CFLAGS -DGTEST_HAS_SEH=0)\n\n  # gtest use a lot of stuff marked as deprecated on Windows.\n  list(APPEND COMPILER_RT_GTEST_CFLAGS -Wno-deprecated-declarations)\n\n  # Visual Studio 2012 only supports up to 8 template parameters in\n  # std::tr1::tuple by default, but gtest requires 10\n  if(MSVC_VERSION EQUAL 1700)\n    list(APPEND COMPILER_RT_GTEST_CFLAGS -D_VARIADIC_MAX=10)\n  endif()\nendif()\n\n# Link objects into a single executable with COMPILER_RT_TEST_COMPILER,\n# using specified link flags. Make executable a part of provided\n# test_suite.\n# add_compiler_rt_test(<test_suite> <test_name>\n#                      SUBDIR <subdirectory for binary>\n#                      OBJECTS <object files>\n#                      DEPS <deps (e.g. runtime libs)>\n#                      LINK_FLAGS <link flags>)\nmacro(add_compiler_rt_test test_suite test_name)\n  cmake_parse_arguments(TEST \"\" \"SUBDIR\" \"OBJECTS;DEPS;LINK_FLAGS\" \"\" ${ARGN})\n  if(TEST_SUBDIR)\n    set(output_bin \"${CMAKE_CURRENT_BINARY_DIR}/${TEST_SUBDIR}/${test_name}\")\n  else()\n    set(output_bin \"${CMAKE_CURRENT_BINARY_DIR}/${test_name}\")\n  endif()\n  if(MSVC)\n    set(output_bin \"${output_bin}.exe\")\n  endif()\n  # Use host compiler in a standalone build, and just-built Clang otherwise.\n  if(NOT COMPILER_RT_STANDALONE_BUILD)\n    list(APPEND TEST_DEPS clang)\n  endif()\n  # If we're not on MSVC, include the linker flags from CMAKE but override them\n  # with the provided link flags. This ensures that flags which are required to\n  # link programs at all are included, but the changes needed for the test\n  # trump. With MSVC we can't do that because CMake is set up to run link.exe\n  # when linking, not the compiler. Here, we hack it to use the compiler\n  # because we want to use -fsanitize flags.\n  if(NOT MSVC)\n    set(TEST_LINK_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} ${TEST_LINK_FLAGS}\")\n    separate_arguments(TEST_LINK_FLAGS)\n  endif()\n  add_custom_target(${test_name}\n    COMMAND ${COMPILER_RT_TEST_COMPILER} ${TEST_OBJECTS}\n            -o \"${output_bin}\"\n            ${TEST_LINK_FLAGS}\n    DEPENDS ${TEST_DEPS})\n  # Make the test suite depend on the binary.\n  add_dependencies(${test_suite} ${test_name})\nendmacro()\n\nmacro(add_compiler_rt_resource_file target_name file_name)\n  set(src_file \"${CMAKE_CURRENT_SOURCE_DIR}/${file_name}\")\n  set(dst_file \"${COMPILER_RT_OUTPUT_DIR}/${file_name}\")\n  add_custom_command(OUTPUT ${dst_file}\n    DEPENDS ${src_file}\n    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file}\n    COMMENT \"Copying ${file_name}...\")\n  add_custom_target(${target_name} DEPENDS ${dst_file})\n  # Install in Clang resource directory.\n  install(FILES ${file_name} DESTINATION ${COMPILER_RT_INSTALL_PATH})\nendmacro()\n\nmacro(add_compiler_rt_script name)\n  set(dst ${COMPILER_RT_EXEC_OUTPUT_DIR}/${name})\n  set(src ${CMAKE_CURRENT_SOURCE_DIR}/${name})\n  add_custom_command(OUTPUT ${dst}\n    DEPENDS ${src}\n    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}\n    COMMENT \"Copying ${name}...\")\n  add_custom_target(${name} DEPENDS ${dst})\n  install(FILES ${dst}\n    PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE\n    DESTINATION ${COMPILER_RT_INSTALL_PATH}/bin)\nendmacro(add_compiler_rt_script src name)\n\n# Builds custom version of libc++ and installs it in <prefix>.\n# Can be used to build sanitized versions of libc++ for running unit tests.\n# add_custom_libcxx(<name> <prefix>\n#                   DEPS <list of build deps>\n#                   CFLAGS <list of compile flags>)\nmacro(add_custom_libcxx name prefix)\n  if(NOT COMPILER_RT_HAS_LIBCXX_SOURCES)\n    message(FATAL_ERROR \"libcxx not found!\")\n  endif()\n\n  cmake_parse_arguments(LIBCXX \"\" \"\" \"DEPS;CFLAGS\" ${ARGN})\n  foreach(flag ${LIBCXX_CFLAGS})\n    set(flagstr \"${flagstr} ${flag}\")\n  endforeach()\n  set(LIBCXX_CFLAGS ${flagstr})\n\n  if(NOT COMPILER_RT_STANDALONE_BUILD)\n    list(APPEND LIBCXX_DEPS clang)\n  endif()\n\n  ExternalProject_Add(${name}\n    PREFIX ${prefix}\n    SOURCE_DIR ${COMPILER_RT_LIBCXX_PATH}\n    CMAKE_ARGS -DCMAKE_MAKE_PROGRAM:STRING=${CMAKE_MAKE_PROGRAM}\n               -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER}\n               -DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_COMPILER}\n               -DCMAKE_C_FLAGS=${LIBCXX_CFLAGS}\n               -DCMAKE_CXX_FLAGS=${LIBCXX_CFLAGS}\n               -DCMAKE_BUILD_TYPE=Release\n               -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>\n    LOG_BUILD 1\n    LOG_CONFIGURE 1\n    LOG_INSTALL 1\n    )\n  set_target_properties(${name} PROPERTIES EXCLUDE_FROM_ALL TRUE)\n\n  ExternalProject_Add_Step(${name} force-reconfigure\n    DEPENDERS configure\n    ALWAYS 1\n    )\n\n  ExternalProject_Add_Step(${name} clobber\n    COMMAND ${CMAKE_COMMAND} -E remove_directory <BINARY_DIR>\n    COMMAND ${CMAKE_COMMAND} -E make_directory <BINARY_DIR>\n    COMMENT \"Clobberring ${name} build directory...\"\n    DEPENDERS configure\n    DEPENDS ${LIBCXX_DEPS}\n    )\nendmacro()\n\nfunction(rt_externalize_debuginfo name)\n  if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO)\n    return()\n  endif()\n\n  if(APPLE)\n    if(CMAKE_CXX_FLAGS MATCHES \"-flto\"\n      OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES \"-flto\")\n\n      set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o)\n      set_property(TARGET ${name} APPEND_STRING PROPERTY\n        LINK_FLAGS \" -Wl,-object_path_lto -Wl,${lto_object}\")\n    endif()\n    add_custom_command(TARGET ${name} POST_BUILD\n      COMMAND xcrun dsymutil $<TARGET_FILE:${name}>\n      COMMAND xcrun strip -Sl $<TARGET_FILE:${name}>)\n  else()\n    message(FATAL_ERROR \"COMPILER_RT_EXTERNALIZE_DEBUGINFO isn't implemented for non-darwin platforms!\")\n  endif()\nendfunction()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/cmake/Modules/CompilerRTCompile.cmake",
    "content": "# On Windows, CMAKE_*_FLAGS are built for MSVC but we use the GCC clang.exe,\n# which uses completely different flags. Translate some common flag types, and\n# drop the rest.\nfunction(translate_msvc_cflags out_flags msvc_flags)\n  # Insert an empty string in the list to simplify processing.\n  set(msvc_flags \";${msvc_flags}\")\n\n  # Canonicalize /flag to -flag.\n  string(REPLACE \";/\" \";-\" msvc_flags \"${msvc_flags}\")\n\n  # Make space separated -D and -U flags into joined flags.\n  string(REGEX REPLACE \";-\\([DU]\\);\" \";-\\\\1\" msvc_flags \"${msvc_flags}\")\n\n  set(clang_flags \"\")\n  foreach(flag ${msvc_flags})\n    if (\"${flag}\" MATCHES \"^-[DU]\")\n      # Pass through basic command line macro definitions (-DNDEBUG).\n      list(APPEND clang_flags \"${flag}\")\n    elseif (\"${flag}\" MATCHES \"^-O[2x]\")\n      # Canonicalize normal optimization flags to -O2.\n      list(APPEND clang_flags \"-O2\")\n    endif()\n  endforeach()\n  set(${out_flags} \"${clang_flags}\" PARENT_SCOPE)\nendfunction()\n\n# Compile a source into an object file with COMPILER_RT_TEST_COMPILER using\n# a provided compile flags and dependenices.\n# clang_compile(<object> <source>\n#               CFLAGS <list of compile flags>\n#               DEPS <list of dependencies>)\nmacro(clang_compile object_file source)\n  cmake_parse_arguments(SOURCE \"\" \"\" \"CFLAGS;DEPS\" ${ARGN})\n  get_filename_component(source_rpath ${source} REALPATH)\n  if(NOT COMPILER_RT_STANDALONE_BUILD)\n    list(APPEND SOURCE_DEPS clang compiler-rt-headers)\n  endif()\n  if (TARGET CompilerRTUnitTestCheckCxx)\n    list(APPEND SOURCE_DEPS CompilerRTUnitTestCheckCxx)\n  endif()\n  string(REGEX MATCH \"[.](cc|cpp)$\" is_cxx ${source_rpath})\n  if(is_cxx)\n    string(REPLACE \" \" \";\" global_flags \"${CMAKE_CXX_FLAGS}\")\n  else()\n    string(REPLACE \" \" \";\" global_flags \"${CMAKE_C_FLAGS}\")\n  endif()\n\n  if (MSVC)\n    translate_msvc_cflags(global_flags \"${global_flags}\")\n  endif()\n\n  if (APPLE)\n    set(global_flags ${OSX_SYSROOT_FLAG} ${global_flags})\n  endif()\n\n  # Ignore unknown warnings. CMAKE_CXX_FLAGS may contain GCC-specific options\n  # which are not supported by Clang.\n  list(APPEND global_flags -Wno-unknown-warning-option)\n  set(compile_flags ${global_flags} ${SOURCE_CFLAGS})\n  add_custom_command(\n    OUTPUT ${object_file}\n    COMMAND ${COMPILER_RT_TEST_COMPILER} ${compile_flags} -c\n            -o \"${object_file}\"\n            ${source_rpath}\n    MAIN_DEPENDENCY ${source}\n    DEPENDS ${SOURCE_DEPS})\nendmacro()\n\n# On Darwin, there are no system-wide C++ headers and the just-built clang is\n# therefore not able to compile C++ files unless they are copied/symlinked into\n# ${LLVM_BINARY_DIR}/include/c++\n# The just-built clang is used to build compiler-rt unit tests. Let's detect\n# this before we try to build the tests and print out a suggestion how to fix\n# it.\n# On other platforms, this is currently not an issue.\nmacro(clang_compiler_add_cxx_check)\n  if (APPLE)\n    set(CMD\n      \"echo '#include <iostream>' | ${COMPILER_RT_TEST_COMPILER} ${OSX_SYSROOT_FLAG} -E -x c++ - > /dev/null\"\n      \"if [ $? != 0 ] \"\n      \"  then echo\"\n      \"  echo 'Your just-built clang cannot find C++ headers, which are needed to build and run compiler-rt tests.'\"\n      \"  echo 'You should copy or symlink your system C++ headers into ${LLVM_BINARY_DIR}/include/c++'\"\n      \"  if [ -d $(dirname $(dirname $(xcrun -f clang)))/include/c++ ]\"\n      \"    then echo 'e.g. with:'\"\n      \"    echo '  cp -r' $(dirname $(dirname $(xcrun -f clang)))/include/c++ '${LLVM_BINARY_DIR}/include/'\"\n      \"  elif [ -d $(dirname $(dirname $(xcrun -f clang)))/lib/c++ ]\"\n      \"    then echo 'e.g. with:'\"\n      \"    echo '  cp -r' $(dirname $(dirname $(xcrun -f clang)))/lib/c++ '${LLVM_BINARY_DIR}/include/'\"\n      \"  fi\"\n      \"  echo 'This can also be fixed by checking out the libcxx project from llvm.org and installing the headers'\"\n      \"  echo 'into your build directory:'\"\n      \"  echo '  cd ${LLVM_SOURCE_DIR}/projects && svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx'\"\n      \"  echo '  cd ${LLVM_BINARY_DIR} && make -C ${LLVM_SOURCE_DIR}/projects/libcxx installheaders HEADER_DIR=${LLVM_BINARY_DIR}/include'\"\n      \"  echo\"\n      \"  false\"\n      \"fi\"\n      )\n    add_custom_target(CompilerRTUnitTestCheckCxx\n      COMMAND bash -c \"${CMD}\"\n      COMMENT \"Checking that just-built clang can find C++ headers...\"\n      VERBATIM)\n    if (TARGET clang)\n      ADD_DEPENDENCIES(CompilerRTUnitTestCheckCxx clang)\n    endif()\n  endif()\nendmacro()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake",
    "content": "# On OS X SDKs can be installed anywhere on the base system and xcode-select can\n# set the default Xcode to use. This function finds the SDKs that are present in\n# the current Xcode.\nfunction(find_darwin_sdk_dir var sdk_name)\n  # Let's first try the internal SDK, otherwise use the public SDK.\n  execute_process(\n    COMMAND xcodebuild -version -sdk ${sdk_name}.internal Path\n    OUTPUT_VARIABLE var_internal\n    OUTPUT_STRIP_TRAILING_WHITESPACE\n    ERROR_FILE /dev/null\n  )\n  if(\"\" STREQUAL \"${var_internal}\")\n    execute_process(\n      COMMAND xcodebuild -version -sdk ${sdk_name} Path\n      OUTPUT_VARIABLE var_internal\n      OUTPUT_STRIP_TRAILING_WHITESPACE\n      ERROR_FILE /dev/null\n    )\n  endif()\n  set(${var} ${var_internal} PARENT_SCOPE)\nendfunction()\n\n# There isn't a clear mapping of what architectures are supported with a given\n# target platform, but ld's version output does list the architectures it can\n# link for.\nfunction(darwin_get_toolchain_supported_archs output_var)\n  execute_process(\n    COMMAND ld -v\n    ERROR_VARIABLE LINKER_VERSION)\n\n  string(REGEX MATCH \"configured to support archs: ([^\\n]+)\"\n         ARCHES_MATCHED \"${LINKER_VERSION}\")\n  if(ARCHES_MATCHED)\n    set(ARCHES \"${CMAKE_MATCH_1}\")\n    message(STATUS \"Got ld supported ARCHES: ${ARCHES}\")\n    string(REPLACE \" \" \";\" ARCHES ${ARCHES})\n  else()\n    # If auto-detecting fails, fall back to a default set\n    message(WARNING \"Detecting supported architectures from 'ld -v' failed. Returning default set.\")\n    set(ARCHES \"i386;x86_64;armv7;armv7s;arm64\")\n  endif()\n  \n  set(${output_var} ${ARCHES} PARENT_SCOPE)\nendfunction()\n\n# This function takes an OS and a list of architectures and identifies the\n# subset of the architectures list that the installed toolchain can target.\nfunction(darwin_test_archs os valid_archs)\n  if(${valid_archs})\n    message(STATUS \"Using cached valid architectures for ${os}.\")\n    return()\n  endif()\n\n  set(archs ${ARGN})\n  message(STATUS \"Finding valid architectures for ${os}...\")\n  set(SIMPLE_CPP ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/src.cpp)\n  file(WRITE ${SIMPLE_CPP} \"#include <iostream>\\nint main() { std::cout << std::endl; return 0; }\\n\")\n\n  set(os_linker_flags)\n  foreach(flag ${DARWIN_${os}_LINKFLAGS})\n    set(os_linker_flags \"${os_linker_flags} ${flag}\")\n  endforeach()\n\n  # The simple program will build for x86_64h on the simulator because it is \n  # compatible with x86_64 libraries (mostly), but since x86_64h isn't actually\n  # a valid or useful architecture for the iOS simulator we should drop it.\n  if(${os} STREQUAL \"iossim\")\n    list(REMOVE_ITEM archs \"x86_64h\")\n  endif()\n\n  set(working_archs)\n  foreach(arch ${archs})\n    \n    set(arch_linker_flags \"-arch ${arch} ${os_linker_flags}\")\n    try_compile(CAN_TARGET_${os}_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_CPP}\n                COMPILE_DEFINITIONS \"-v -arch ${arch}\" ${DARWIN_${os}_CFLAGS}\n                CMAKE_FLAGS \"-DCMAKE_EXE_LINKER_FLAGS=${arch_linker_flags}\"\n                OUTPUT_VARIABLE TEST_OUTPUT)\n    if(${CAN_TARGET_${os}_${arch}})\n      list(APPEND working_archs ${arch})\n    else()\n      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log\n        \"Testing compiler for supporting ${os}-${arch}:\\n\"\n        \"${TEST_OUTPUT}\\n\")\n    endif()\n  endforeach()\n  set(${valid_archs} ${working_archs}\n    CACHE STRING \"List of valid architectures for platform ${os}.\")\nendfunction()\n\n# This function checks the host cpusubtype to see if it is post-haswell. Haswell\n# and later machines can run x86_64h binaries. Haswell is cpusubtype 8.\nfunction(darwin_filter_host_archs input output)\n  list_union(tmp_var DARWIN_osx_ARCHS ${input})\n  execute_process(\n    COMMAND sysctl hw.cpusubtype\n    OUTPUT_VARIABLE SUBTYPE)\n\n  string(REGEX MATCH \"hw.cpusubtype: ([0-9]*)\"\n         SUBTYPE_MATCHED \"${SUBTYPE}\")\n  set(HASWELL_SUPPORTED Off)\n  if(SUBTYPE_MATCHED)\n    if(${CMAKE_MATCH_1} GREATER 7)\n      set(HASWELL_SUPPORTED On)\n    endif()\n  endif()\n  if(NOT HASWELL_SUPPORTED)\n    list(REMOVE_ITEM tmp_var x86_64h)\n  endif()\n  set(${output} ${tmp_var} PARENT_SCOPE)\nendfunction()\n\n# Read and process the exclude file into a list of symbols\nfunction(darwin_read_list_from_file output_var file)\n  if(EXISTS ${file})\n    file(READ ${file} EXCLUDES)\n    string(REPLACE \"\\n\" \";\" EXCLUDES ${EXCLUDES})\n    set(${output_var} ${EXCLUDES} PARENT_SCOPE)\n  endif()\nendfunction()\n\n# this function takes an OS, architecture and minimum version and provides a\n# list of builtin functions to exclude\nfunction(darwin_find_excluded_builtins_list output_var)\n  cmake_parse_arguments(LIB\n    \"\"\n    \"OS;ARCH;MIN_VERSION\"\n    \"\"\n    ${ARGN})\n\n  if(NOT LIB_OS OR NOT LIB_ARCH)\n    message(FATAL_ERROR \"Must specify OS and ARCH to darwin_find_excluded_builtins_list!\")\n  endif()\n\n  darwin_read_list_from_file(${LIB_OS}_BUILTINS\n    ${DARWIN_EXCLUDE_DIR}/${LIB_OS}.txt)\n  darwin_read_list_from_file(${LIB_OS}_${LIB_ARCH}_BASE_BUILTINS\n    ${DARWIN_EXCLUDE_DIR}/${LIB_OS}-${LIB_ARCH}.txt)\n\n  if(LIB_MIN_VERSION)\n    file(GLOB builtin_lists ${DARWIN_EXCLUDE_DIR}/${LIB_OS}*-${LIB_ARCH}.txt)\n    foreach(builtin_list ${builtin_lists})\n      string(REGEX MATCH \"${LIB_OS}([0-9\\\\.]*)-${LIB_ARCH}.txt\" VERSION_MATCHED \"${builtin_list}\")\n      if (VERSION_MATCHED AND NOT CMAKE_MATCH_1 VERSION_LESS LIB_MIN_VERSION)\n        if(NOT smallest_version)\n          set(smallest_version ${CMAKE_MATCH_1})\n        elseif(CMAKE_MATCH_1 VERSION_LESS smallest_version)\n          set(smallest_version ${CMAKE_MATCH_1})\n        endif()\n      endif()\n    endforeach()\n\n    if(smallest_version)\n      darwin_read_list_from_file(${LIB_ARCH}_${LIB_OS}_BUILTINS\n        ${DARWIN_EXCLUDE_DIR}/${LIB_OS}${smallest_version}-${LIB_ARCH}.txt)\n    endif()\n  endif()\n  \n  set(${output_var}\n      ${${LIB_ARCH}_${LIB_OS}_BUILTINS}\n      ${${LIB_OS}_${LIB_ARCH}_BASE_BUILTINS}\n      ${${LIB_OS}_BUILTINS} PARENT_SCOPE)\nendfunction()\n\n# adds a single builtin library for a single OS & ARCH\nmacro(darwin_add_builtin_library name suffix)\n  cmake_parse_arguments(LIB\n    \"\"\n    \"PARENT_TARGET;OS;ARCH\"\n    \"SOURCES;CFLAGS;DEFS\"\n    ${ARGN})\n  set(libname \"${name}.${suffix}_${LIB_ARCH}_${LIB_OS}\")\n  add_library(${libname} STATIC ${LIB_SOURCES})\n  if(DARWIN_${LIB_OS}_SYSROOT)\n    set(sysroot_flag -isysroot ${DARWIN_${LIB_OS}_SYSROOT})\n  endif()\n  set_target_compile_flags(${libname}\n    ${sysroot_flag}\n    ${DARWIN_${LIB_OS}_BUILTIN_MIN_VER_FLAG}\n    ${LIB_CFLAGS})\n  set_property(TARGET ${libname} APPEND PROPERTY\n      COMPILE_DEFINITIONS ${LIB_DEFS})\n  set_target_properties(${libname} PROPERTIES\n      OUTPUT_NAME ${libname}${COMPILER_RT_OS_SUFFIX})\n  set_target_properties(${libname} PROPERTIES\n    OSX_ARCHITECTURES ${LIB_ARCH})\n\n  if(LIB_PARENT_TARGET)\n    add_dependencies(${LIB_PARENT_TARGET} ${libname})\n  endif()\n\n  list(APPEND ${LIB_OS}_${suffix}_libs ${libname})\n  list(APPEND ${LIB_OS}_${suffix}_lipo_flags -arch ${arch} $<TARGET_FILE:${libname}>)\nendmacro()\n\nfunction(darwin_lipo_libs name)\n  cmake_parse_arguments(LIB\n    \"\"\n    \"PARENT_TARGET;OUTPUT_DIR;INSTALL_DIR\"\n    \"LIPO_FLAGS;DEPENDS\"\n    ${ARGN})\n  if(LIB_DEPENDS AND LIB_LIPO_FLAGS)\n    add_custom_command(OUTPUT ${LIB_OUTPUT_DIR}/lib${name}.a\n      COMMAND ${CMAKE_COMMAND} -E make_directory ${LIB_OUTPUT_DIR}\n      COMMAND lipo -output\n              ${LIB_OUTPUT_DIR}/lib${name}.a\n              -create ${LIB_LIPO_FLAGS}\n      DEPENDS ${LIB_DEPENDS}\n      )\n    add_custom_target(${name}\n      DEPENDS ${LIB_OUTPUT_DIR}/lib${name}.a)\n    add_dependencies(${LIB_PARENT_TARGET} ${name})\n    install(FILES ${LIB_OUTPUT_DIR}/lib${name}.a\n      DESTINATION ${LIB_INSTALL_DIR})\n  else()\n    message(WARNING \"Not generating lipo target for ${name} because no input libraries exist.\")\n  endif()\nendfunction()\n\n# Filter out generic versions of routines that are re-implemented in\n# architecture specific manner.  This prevents multiple definitions of the\n# same symbols, making the symbol selection non-deterministic.\nfunction(darwin_filter_builtin_sources output_var exclude_or_include excluded_list)\n  if(exclude_or_include STREQUAL \"EXCLUDE\")\n    set(filter_action GREATER)\n    set(filter_value -1)\n  elseif(exclude_or_include STREQUAL \"INCLUDE\")\n    set(filter_action LESS)\n    set(filter_value 0)\n  else()\n    message(FATAL_ERROR \"darwin_filter_builtin_sources called without EXCLUDE|INCLUDE\")\n  endif()\n\n  set(intermediate ${ARGN})\n  foreach (_file ${intermediate})\n    get_filename_component(_name_we ${_file} NAME_WE)\n    list(FIND ${excluded_list} ${_name_we} _found)\n    if(_found ${filter_action} ${filter_value})\n      list(REMOVE_ITEM intermediate ${_file})\n    elseif(${_file} MATCHES \".*/.*\\\\.S\" OR ${_file} MATCHES \".*/.*\\\\.c\")\n      get_filename_component(_name ${_file} NAME)\n      string(REPLACE \".S\" \".c\" _cname \"${_name}\")\n      list(REMOVE_ITEM intermediate ${_cname})\n    endif ()\n  endforeach ()\n  set(${output_var} ${intermediate} PARENT_SCOPE)\nendfunction()\n\nfunction(darwin_add_eprintf_library)\n  cmake_parse_arguments(LIB\n    \"\"\n    \"\"\n    \"CFLAGS\"\n    ${ARGN})\n\n  add_library(clang_rt.eprintf STATIC eprintf.c)\n  set_target_compile_flags(clang_rt.eprintf\n    -isysroot ${DARWIN_osx_SYSROOT}\n    ${DARWIN_osx_BUILTIN_MIN_VER_FLAG}\n    -arch i386\n    ${LIB_CFLAGS})\n  set_target_properties(clang_rt.eprintf PROPERTIES\n      OUTPUT_NAME clang_rt.eprintf${COMPILER_RT_OS_SUFFIX})\n  set_target_properties(clang_rt.eprintf PROPERTIES\n    OSX_ARCHITECTURES i386)\n  add_dependencies(builtins clang_rt.eprintf)\n  set_target_properties(clang_rt.eprintf PROPERTIES\n        ARCHIVE_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR})\n  install(TARGETS clang_rt.eprintf\n      ARCHIVE DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR})\nendfunction()\n\n# Generates builtin libraries for all operating systems specified in ARGN. Each\n# OS library is constructed by lipo-ing together single-architecture libraries.\nmacro(darwin_add_builtin_libraries)\n  set(DARWIN_EXCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Darwin-excludes)\n\n  set(CFLAGS \"-fPIC -O3 -fvisibility=hidden -DVISIBILITY_HIDDEN -Wall -fomit-frame-pointer\")\n  set(CMAKE_C_FLAGS \"\")\n  set(CMAKE_CXX_FLAGS \"\")\n  set(CMAKE_ASM_FLAGS \"\")\n\n  set(PROFILE_SOURCES ../profile/InstrProfiling \n                      ../profile/InstrProfilingBuffer\n                      ../profile/InstrProfilingPlatformDarwin)\n  foreach (os ${ARGN})\n    list_union(DARWIN_BUILTIN_ARCHS DARWIN_${os}_ARCHS BUILTIN_SUPPORTED_ARCH)\n    foreach (arch ${DARWIN_BUILTIN_ARCHS})\n      darwin_find_excluded_builtins_list(${arch}_${os}_EXCLUDED_BUILTINS\n                              OS ${os}\n                              ARCH ${arch}\n                              MIN_VERSION ${DARWIN_${os}_BUILTIN_MIN_VER})\n\n      darwin_filter_builtin_sources(filtered_sources\n        EXCLUDE ${arch}_${os}_EXCLUDED_BUILTINS\n        ${${arch}_SOURCES})\n\n      darwin_add_builtin_library(clang_rt builtins\n                              OS ${os}\n                              ARCH ${arch}\n                              SOURCES ${filtered_sources}\n                              CFLAGS ${CFLAGS} -arch ${arch}\n                              PARENT_TARGET builtins)\n    endforeach()\n\n    # Don't build cc_kext libraries for simulator platforms\n    if(NOT DARWIN_${os}_SKIP_CC_KEXT)\n      foreach (arch ${DARWIN_BUILTIN_ARCHS})\n        # By not specifying MIN_VERSION this only reads the OS and OS-arch lists.\n        # We don't want to filter out the builtins that are present in libSystem\n        # because kexts can't link libSystem.\n        darwin_find_excluded_builtins_list(${arch}_${os}_EXCLUDED_BUILTINS\n                              OS ${os}\n                              ARCH ${arch})\n\n        darwin_filter_builtin_sources(filtered_sources\n          EXCLUDE ${arch}_${os}_EXCLUDED_BUILTINS\n          ${${arch}_SOURCES})\n\n        # In addition to the builtins cc_kext includes some profile sources\n        darwin_add_builtin_library(clang_rt cc_kext\n                                OS ${os}\n                                ARCH ${arch}\n                                SOURCES ${filtered_sources} ${PROFILE_SOURCES}\n                                CFLAGS ${CFLAGS} -arch ${arch} -mkernel\n                                DEFS KERNEL_USE\n                                PARENT_TARGET builtins)\n      endforeach()\n      set(archive_name clang_rt.cc_kext_${os})\n      if(${os} STREQUAL \"osx\")\n        set(archive_name clang_rt.cc_kext)\n      endif()\n      darwin_lipo_libs(${archive_name}\n                      PARENT_TARGET builtins\n                      LIPO_FLAGS ${${os}_cc_kext_lipo_flags}\n                      DEPENDS ${${os}_cc_kext_libs}\n                      OUTPUT_DIR ${COMPILER_RT_LIBRARY_OUTPUT_DIR}\n                      INSTALL_DIR ${COMPILER_RT_LIBRARY_INSTALL_DIR})\n    endif()\n  endforeach()\n\n  darwin_add_eprintf_library(CFLAGS ${CFLAGS})\n\n  # We put the x86 sim slices into the archives for their base OS\n  foreach (os ${ARGN})\n    if(NOT ${os} MATCHES \".*sim$\")\n      darwin_lipo_libs(clang_rt.${os}\n                        PARENT_TARGET builtins\n                        LIPO_FLAGS ${${os}_builtins_lipo_flags} ${${os}sim_builtins_lipo_flags}\n                        DEPENDS ${${os}_builtins_libs} ${${os}sim_builtins_libs}\n                        OUTPUT_DIR ${COMPILER_RT_LIBRARY_OUTPUT_DIR}\n                        INSTALL_DIR ${COMPILER_RT_LIBRARY_INSTALL_DIR})\n    endif()\n  endforeach()\n  darwin_add_embedded_builtin_libraries()\nendmacro()\n\nmacro(darwin_add_embedded_builtin_libraries)\n  # this is a hacky opt-out. If you can't target both intel and arm\n  # architectures we bail here.\n  set(DARWIN_SOFT_FLOAT_ARCHS armv6m armv7m armv7em armv7)\n  set(DARWIN_HARD_FLOAT_ARCHS armv7em armv7)\n  if(COMPILER_RT_SUPPORTED_ARCH MATCHES \".*armv.*\")\n    list(FIND COMPILER_RT_SUPPORTED_ARCH i386 i386_idx)\n    if(i386_idx GREATER -1)\n      list(APPEND DARWIN_HARD_FLOAT_ARCHS i386)\n    endif()\n\n    list(FIND COMPILER_RT_SUPPORTED_ARCH x86_64 x86_64_idx)\n    if(x86_64_idx GREATER -1)\n      list(APPEND DARWIN_HARD_FLOAT_ARCHS x86_64)\n    endif()\n\n    set(MACHO_SYM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/macho_embedded)\n\n    set(CFLAGS \"-Oz -Wall -fomit-frame-pointer -ffreestanding\")\n    set(CMAKE_C_FLAGS \"\")\n    set(CMAKE_CXX_FLAGS \"\")\n    set(CMAKE_ASM_FLAGS \"\")\n\n    set(SOFT_FLOAT_FLAG -mfloat-abi=soft)\n    set(HARD_FLOAT_FLAG -mfloat-abi=hard)\n\n    set(ENABLE_PIC Off)\n    set(PIC_FLAG -fPIC)\n    set(STATIC_FLAG -static)\n\n    set(DARWIN_macho_embedded_ARCHS armv6m armv7m armv7em armv7 i386 x86_64)\n\n    set(DARWIN_macho_embedded_LIBRARY_OUTPUT_DIR\n      ${COMPILER_RT_OUTPUT_DIR}/lib/macho_embedded)\n    set(DARWIN_macho_embedded_LIBRARY_INSTALL_DIR\n      ${COMPILER_RT_INSTALL_PATH}/lib/macho_embedded)\n      \n    set(CFLAGS_armv7 \"-target thumbv7-apple-darwin-eabi\")\n    set(CFLAGS_i386 \"-march=pentium\")\n\n    darwin_read_list_from_file(common_FUNCTIONS ${MACHO_SYM_DIR}/common.txt)\n    darwin_read_list_from_file(thumb2_FUNCTIONS ${MACHO_SYM_DIR}/thumb2.txt)\n    darwin_read_list_from_file(thumb2_64_FUNCTIONS ${MACHO_SYM_DIR}/thumb2-64.txt)\n    darwin_read_list_from_file(arm_FUNCTIONS ${MACHO_SYM_DIR}/arm.txt)\n    darwin_read_list_from_file(i386_FUNCTIONS ${MACHO_SYM_DIR}/i386.txt)\n\n\n    set(armv6m_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS})\n    set(armv7m_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS})\n    set(armv7em_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS})\n    set(armv7_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS} ${thumb2_64_FUNCTIONS})\n    set(i386_FUNCTIONS ${common_FUNCTIONS} ${i386_FUNCTIONS})\n    set(x86_64_FUNCTIONS ${common_FUNCTIONS})\n\n    foreach(arch ${DARWIN_macho_embedded_ARCHS})\n      darwin_filter_builtin_sources(${arch}_filtered_sources\n        INCLUDE ${arch}_FUNCTIONS\n        ${${arch}_SOURCES})\n      if(NOT ${arch}_filtered_sources)\n        message(\"${arch}_SOURCES: ${${arch}_SOURCES}\")\n        message(\"${arch}_FUNCTIONS: ${${arch}_FUNCTIONS}\")\n        message(FATAL_ERROR \"Empty filtered sources!\")\n      endif()\n    endforeach()\n\n    foreach(float_type SOFT HARD)\n      foreach(type PIC STATIC)\n        string(TOLOWER \"${float_type}_${type}\" lib_suffix)\n        foreach(arch ${DARWIN_${float_type}_FLOAT_ARCHS})\n          set(DARWIN_macho_embedded_SYSROOT ${DARWIN_osx_SYSROOT})\n          set(float_flag)\n          if(${arch} MATCHES \"^arm\")\n            # x86 targets are hard float by default, but the complain about the\n            # float ABI flag, so don't pass it unless we're targeting arm.\n            set(float_flag ${${float_type}_FLOAT_FLAG})\n          endif()\n          darwin_add_builtin_library(clang_rt ${lib_suffix}\n                                OS macho_embedded\n                                ARCH ${arch}\n                                SOURCES ${${arch}_filtered_sources}\n                                CFLAGS ${CFLAGS} -arch ${arch} ${${type}_FLAG} ${float_flag} ${CFLAGS_${arch}}\n                                PARENT_TARGET builtins)\n        endforeach()\n        foreach(lib ${macho_embedded_${lib_suffix}_libs})\n          set_target_properties(${lib} PROPERTIES LINKER_LANGUAGE C)\n        endforeach()\n        darwin_lipo_libs(clang_rt.${lib_suffix}\n                      PARENT_TARGET builtins\n                      LIPO_FLAGS ${macho_embedded_${lib_suffix}_lipo_flags}\n                      DEPENDS ${macho_embedded_${lib_suffix}_libs}\n                      OUTPUT_DIR ${DARWIN_macho_embedded_LIBRARY_OUTPUT_DIR}\n                      INSTALL_DIR ${DARWIN_macho_embedded_LIBRARY_INSTALL_DIR})\n      endforeach()\n    endforeach()\n  endif()\nendmacro()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/cmake/Modules/CompilerRTLink.cmake",
    "content": "# Link a shared library with COMPILER_RT_TEST_COMPILER.\n# clang_link_shared(<output.so>\n#                   OBJECTS <list of input objects>\n#                   LINKFLAGS <list of link flags>\n#                   DEPS <list of dependencies>)\nmacro(clang_link_shared so_file)\n  cmake_parse_arguments(SOURCE \"\" \"\" \"OBJECTS;LINKFLAGS;DEPS\" ${ARGN})\n  if(NOT COMPILER_RT_STANDALONE_BUILD)\n    list(APPEND SOURCE_DEPS clang)\n  endif()\n  add_custom_command(\n    OUTPUT ${so_file}\n    COMMAND ${COMPILER_RT_TEST_COMPILER} -o \"${so_file}\" -shared\n            ${SOURCE_LINKFLAGS} ${SOURCE_OBJECTS}\n    DEPENDS ${SOURCE_DEPS})\nendmacro()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/cmake/Modules/CompilerRTUtils.cmake",
    "content": "# Because compiler-rt spends a lot of time setting up custom compile flags,\n# define a handy helper function for it. The compile flags setting in CMake\n# has serious issues that make its syntax challenging at best.\nfunction(set_target_compile_flags target)\n  set(argstring \"\")\n  foreach(arg ${ARGN})\n    set(argstring \"${argstring} ${arg}\")\n  endforeach()\n  set_property(TARGET ${target} PROPERTY COMPILE_FLAGS \"${argstring}\")\nendfunction()\n\nfunction(set_target_link_flags target)\n  set(argstring \"\")\n  foreach(arg ${ARGN})\n    set(argstring \"${argstring} ${arg}\")\n  endforeach()\n  set_property(TARGET ${target} PROPERTY LINK_FLAGS \"${argstring}\")\nendfunction()\n\n# Set the variable var_PYBOOL to True if var holds a true-ish string,\n# otherwise set it to False.\nmacro(pythonize_bool var)\n  if (${var})\n    set(${var}_PYBOOL True)\n  else()\n    set(${var}_PYBOOL False)\n  endif()\nendmacro()\n\n# Appends value to all lists in ARGN, if the condition is true.\nmacro(append_list_if condition value)\n  if(${condition})\n    foreach(list ${ARGN})\n      list(APPEND ${list} ${value})\n    endforeach()\n  endif()\nendmacro()\n\n# Appends value to all strings in ARGN, if the condition is true.\nmacro(append_string_if condition value)\n  if(${condition})\n    foreach(str ${ARGN})\n      set(${str} \"${${str}} ${value}\")\n    endforeach()\n  endif()\nendmacro()\n\nmacro(append_no_rtti_flag list)\n  append_list_if(COMPILER_RT_HAS_FNO_RTTI_FLAG -fno-rtti ${list})\n  append_list_if(COMPILER_RT_HAS_GR_FLAG /GR- ${list})\nendmacro()\n\nmacro(append_have_file_definition filename varname list)\n  check_include_file(\"${filename}\" \"${varname}\")\n  if (NOT ${varname})\n    set(\"${varname}\" 0)\n  endif()\n  list(APPEND ${list} \"${varname}=${${varname}}\")\nendmacro()\n\nmacro(list_union output input1 input2)\n  set(${output})\n  foreach(it ${${input1}})\n    list(FIND ${input2} ${it} index)\n    if( NOT (index EQUAL -1))\n      list(APPEND ${output} ${it})\n    endif()\n  endforeach()\nendmacro()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/cmake/Modules/SanitizerUtils.cmake",
    "content": "set(SANITIZER_GEN_DYNAMIC_LIST\n  ${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/scripts/gen_dynamic_list.py)\n\nset(SANITIZER_LINT_SCRIPT\n  ${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/scripts/check_lint.sh)\n\n# Create a target \"<name>-<arch>-symbols\" that would generate the list of\n# symbols that need to be exported from sanitizer runtime \"<name>\". Function\n# interceptors are exported automatically, user can also provide files with\n# symbol names that should be exported as well.\n#   add_sanitizer_rt_symbols(<name>\n#                            ARCHS <architectures>\n#                            PARENT_TARGET <convenience parent target>\n#                            EXTRA <files with extra symbols to export>)\nmacro(add_sanitizer_rt_symbols name)\n  cmake_parse_arguments(ARG\n    \"\"\n    \"PARENT_TARGET\"\n    \"ARCHS;EXTRA\"\n    ${ARGN})\n  foreach(arch ${ARG_ARCHS})\n    set(target_name ${name}-${arch})\n    set(stamp ${CMAKE_CURRENT_BINARY_DIR}/${target_name}.syms-stamp)\n    set(extra_args)\n    foreach(arg ${ARG_EXTRA})\n      list(APPEND extra_args \"--extra\" ${arg})\n    endforeach()\n    add_custom_command(OUTPUT ${stamp}\n      COMMAND ${PYTHON_EXECUTABLE}\n        ${SANITIZER_GEN_DYNAMIC_LIST} ${extra_args} $<TARGET_FILE:${target_name}>\n        > $<TARGET_FILE:${target_name}>.syms\n      COMMAND ${CMAKE_COMMAND} -E touch ${stamp}\n      DEPENDS ${target_name} ${SANITIZER_GEN_DYNAMIC_LIST} ${ARG_EXTRA}\n      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n      COMMENT \"Generating exported symbols for ${target_name}\"\n      VERBATIM)\n    add_custom_target(${target_name}-symbols ALL\n      DEPENDS ${stamp}\n      SOURCES ${SANITIZER_GEN_DYNAMIC_LIST} ${ARG_EXTRA})\n\n    if(NOT CMAKE_VERSION VERSION_LESS 3.0)\n      install(FILES $<TARGET_FILE:${target_name}>.syms\n              DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR})\n    else()\n      # Per-config install location.\n      if(CMAKE_CONFIGURATION_TYPES)\n        foreach(c ${CMAKE_CONFIGURATION_TYPES})\n          get_target_property(libfile ${target_name} LOCATION_${c})\n          install(FILES ${libfile}.syms CONFIGURATIONS ${c}\n            DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR})\n        endforeach()\n      else()\n        get_target_property(libfile ${target_name} LOCATION_${CMAKE_BUILD_TYPE})\n        install(FILES ${libfile}.syms DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR})\n      endif()\n    endif()\n    if(ARG_PARENT_TARGET)\n      add_dependencies(${ARG_PARENT_TARGET} ${target_name}-symbols)\n    endif()\n  endforeach()\nendmacro()\n\nmacro(add_sanitizer_rt_version_list name)\n  set(vers ${CMAKE_CURRENT_BINARY_DIR}/${name}.vers)\n  cmake_parse_arguments(ARG \"\" \"\" \"LIBS;EXTRA\" ${ARGN})\n  set(args)\n  foreach(arg ${ARG_EXTRA})\n    list(APPEND args \"--extra\" ${arg})\n  endforeach()\n  foreach(arg ${ARG_LIBS})\n    list(APPEND args \"$<TARGET_FILE:${arg}>\")\n  endforeach()\n  add_custom_command(OUTPUT ${vers}\n    COMMAND ${PYTHON_EXECUTABLE}\n      ${SANITIZER_GEN_DYNAMIC_LIST} --version-list ${args}\n      > ${vers}\n    DEPENDS ${SANITIZER_GEN_DYNAMIC_LIST} ${ARG_EXTRA} ${ARG_LIBS}\n    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n    COMMENT \"Generating version list for ${name}\"\n    VERBATIM)\n\n  add_custom_target(${name}-version-list ALL\n    DEPENDS ${vers})\nendmacro()\n\n# Add target to check code style for sanitizer runtimes.\nif(UNIX)\n  add_custom_target(SanitizerLintCheck\n    COMMAND LLVM_CHECKOUT=${LLVM_MAIN_SRC_DIR} SILENT=1 TMPDIR=\n      PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}\n      COMPILER_RT=${COMPILER_RT_SOURCE_DIR}\n      ${SANITIZER_LINT_SCRIPT}\n    DEPENDS ${SANITIZER_LINT_SCRIPT}\n    COMMENT \"Running lint check for sanitizer sources...\"\n    VERBATIM)\nendif()\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/cmake/config-ix.cmake",
    "content": "include(CMakePushCheckState)\ninclude(CheckCXXCompilerFlag)\ninclude(CheckLibraryExists)\ninclude(CheckSymbolExists)\ninclude(TestBigEndian)\n\nfunction(check_linker_flag flag out_var)\n  cmake_push_check_state()\n  set(CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS} ${flag}\")\n  check_cxx_compiler_flag(\"\" ${out_var})\n  cmake_pop_check_state()\nendfunction()\n\n# CodeGen options.\ncheck_cxx_compiler_flag(-fPIC                COMPILER_RT_HAS_FPIC_FLAG)\ncheck_cxx_compiler_flag(-fPIE                COMPILER_RT_HAS_FPIE_FLAG)\ncheck_cxx_compiler_flag(-fno-builtin         COMPILER_RT_HAS_FNO_BUILTIN_FLAG)\ncheck_cxx_compiler_flag(-fno-exceptions      COMPILER_RT_HAS_FNO_EXCEPTIONS_FLAG)\ncheck_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG)\ncheck_cxx_compiler_flag(-funwind-tables      COMPILER_RT_HAS_FUNWIND_TABLES_FLAG)\ncheck_cxx_compiler_flag(-fno-stack-protector COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG)\ncheck_cxx_compiler_flag(-fno-sanitize=safe-stack COMPILER_RT_HAS_FNO_SANITIZE_SAFE_STACK_FLAG)\ncheck_cxx_compiler_flag(-fvisibility=hidden  COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG)\ncheck_cxx_compiler_flag(-fno-rtti            COMPILER_RT_HAS_FNO_RTTI_FLAG)\ncheck_cxx_compiler_flag(-ffreestanding       COMPILER_RT_HAS_FFREESTANDING_FLAG)\ncheck_cxx_compiler_flag(\"-Werror -fno-function-sections\" COMPILER_RT_HAS_FNO_FUNCTION_SECTIONS_FLAG)\ncheck_cxx_compiler_flag(-std=c++11           COMPILER_RT_HAS_STD_CXX11_FLAG)\ncheck_cxx_compiler_flag(-ftls-model=initial-exec COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC)\ncheck_cxx_compiler_flag(-fno-lto             COMPILER_RT_HAS_FNO_LTO_FLAG)\ncheck_cxx_compiler_flag(\"-Werror -msse3\" COMPILER_RT_HAS_MSSE3_FLAG)\ncheck_cxx_compiler_flag(-std=c99             COMPILER_RT_HAS_STD_C99_FLAG)\ncheck_cxx_compiler_flag(--sysroot=.          COMPILER_RT_HAS_SYSROOT_FLAG)\n\nif(NOT WIN32 AND NOT CYGWIN)\n  # MinGW warns if -fvisibility-inlines-hidden is used.\n  check_cxx_compiler_flag(\"-fvisibility-inlines-hidden\" COMPILER_RT_HAS_FVISIBILITY_INLINES_HIDDEN_FLAG)\nendif()\n\ncheck_cxx_compiler_flag(/GR COMPILER_RT_HAS_GR_FLAG)\ncheck_cxx_compiler_flag(/GS COMPILER_RT_HAS_GS_FLAG)\ncheck_cxx_compiler_flag(/MT COMPILER_RT_HAS_MT_FLAG)\ncheck_cxx_compiler_flag(/Oy COMPILER_RT_HAS_Oy_FLAG)\n\n# Debug info flags.\ncheck_cxx_compiler_flag(-gline-tables-only COMPILER_RT_HAS_GLINE_TABLES_ONLY_FLAG)\ncheck_cxx_compiler_flag(-g COMPILER_RT_HAS_G_FLAG)\ncheck_cxx_compiler_flag(/Zi COMPILER_RT_HAS_Zi_FLAG)\n\n# Warnings.\ncheck_cxx_compiler_flag(-Wall COMPILER_RT_HAS_WALL_FLAG)\ncheck_cxx_compiler_flag(-Werror COMPILER_RT_HAS_WERROR_FLAG)\ncheck_cxx_compiler_flag(\"-Werror -Wframe-larger-than=512\" COMPILER_RT_HAS_WFRAME_LARGER_THAN_FLAG)\ncheck_cxx_compiler_flag(\"-Werror -Wglobal-constructors\"   COMPILER_RT_HAS_WGLOBAL_CONSTRUCTORS_FLAG)\ncheck_cxx_compiler_flag(\"-Werror -Wc99-extensions\"     COMPILER_RT_HAS_WC99_EXTENSIONS_FLAG)\ncheck_cxx_compiler_flag(\"-Werror -Wgnu\"                COMPILER_RT_HAS_WGNU_FLAG)\ncheck_cxx_compiler_flag(\"-Werror -Wnon-virtual-dtor\"   COMPILER_RT_HAS_WNON_VIRTUAL_DTOR_FLAG)\ncheck_cxx_compiler_flag(\"-Werror -Wvariadic-macros\"    COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG)\n\ncheck_cxx_compiler_flag(/W3 COMPILER_RT_HAS_W3_FLAG)\ncheck_cxx_compiler_flag(/WX COMPILER_RT_HAS_WX_FLAG)\ncheck_cxx_compiler_flag(/wd4146 COMPILER_RT_HAS_WD4146_FLAG)\ncheck_cxx_compiler_flag(/wd4291 COMPILER_RT_HAS_WD4291_FLAG)\ncheck_cxx_compiler_flag(/wd4391 COMPILER_RT_HAS_WD4391_FLAG)\ncheck_cxx_compiler_flag(/wd4722 COMPILER_RT_HAS_WD4722_FLAG)\ncheck_cxx_compiler_flag(/wd4800 COMPILER_RT_HAS_WD4800_FLAG)\n\n# Symbols.\ncheck_symbol_exists(__func__ \"\" COMPILER_RT_HAS_FUNC_SYMBOL)\n\n# Libraries.\ncheck_library_exists(c fopen \"\" COMPILER_RT_HAS_LIBC)\ncheck_library_exists(dl dlopen \"\" COMPILER_RT_HAS_LIBDL)\ncheck_library_exists(rt shm_open \"\" COMPILER_RT_HAS_LIBRT)\ncheck_library_exists(m pow \"\" COMPILER_RT_HAS_LIBM)\ncheck_library_exists(pthread pthread_create \"\" COMPILER_RT_HAS_LIBPTHREAD)\ncheck_library_exists(stdc++ __cxa_throw \"\" COMPILER_RT_HAS_LIBSTDCXX)\n\n# Linker flags.\nif(ANDROID)\n  check_linker_flag(\"-Wl,-z,global\" COMPILER_RT_HAS_Z_GLOBAL)\n  check_library_exists(log __android_log_write \"\" COMPILER_RT_HAS_LIBLOG)\nendif()\n\n# Architectures.\n\n# List of all architectures we can target.\nset(COMPILER_RT_SUPPORTED_ARCH)\n\n# Try to compile a very simple source file to ensure we can target the given\n# platform. We use the results of these tests to build only the various target\n# runtime libraries supported by our current compilers cross-compiling\n# abilities.\nset(SIMPLE_SOURCE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/simple.cc)\nfile(WRITE ${SIMPLE_SOURCE} \"#include <stdlib.h>\\n#include <limits>\\nint main() {}\\n\")\n\nfunction(check_compile_definition def argstring out_var)\n  if(\"${def}\" STREQUAL \"\")\n    set(${out_var} TRUE PARENT_SCOPE)\n    return()\n  endif()\n  cmake_push_check_state()\n  set(CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS} ${argstring}\")\n  check_symbol_exists(${def} \"\" ${out_var})\n  cmake_pop_check_state()\nendfunction()\n\n# test_target_arch(<arch> <def> <target flags...>)\n# Checks if architecture is supported: runs host compiler with provided\n# flags to verify that:\n#   1) <def> is defined (if non-empty)\n#   2) simple file can be successfully built.\n# If successful, saves target flags for this architecture.\nmacro(test_target_arch arch def)\n  set(TARGET_${arch}_CFLAGS ${ARGN})\n  set(argstring \"\")\n  foreach(arg ${ARGN})\n    set(argstring \"${argstring} ${arg}\")\n  endforeach()\n  check_compile_definition(\"${def}\" \"${argstring}\" HAS_${arch}_DEF)\n  if(NOT HAS_${arch}_DEF)\n    set(CAN_TARGET_${arch} FALSE)\n  else()\n    set(argstring \"${CMAKE_EXE_LINKER_FLAGS} ${argstring}\")\n    try_compile(CAN_TARGET_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_SOURCE}\n                COMPILE_DEFINITIONS \"${TARGET_${arch}_CFLAGS}\"\n                OUTPUT_VARIABLE TARGET_${arch}_OUTPUT\n                CMAKE_FLAGS \"-DCMAKE_EXE_LINKER_FLAGS:STRING=${argstring}\")\n  endif()\n  if(${CAN_TARGET_${arch}})\n    list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})\n  elseif(\"${COMPILER_RT_DEFAULT_TARGET_ARCH}\" MATCHES \"${arch}\" AND\n         COMPILER_RT_HAS_EXPLICIT_DEFAULT_TARGET_TRIPLE)\n    # Bail out if we cannot target the architecture we plan to test.\n    message(FATAL_ERROR \"Cannot compile for ${arch}:\\n${TARGET_${arch}_OUTPUT}\")\n  endif()\nendmacro()\n\n# Add $arch as supported with no additional flags.\nmacro(add_default_target_arch arch)\n  set(TARGET_${arch}_CFLAGS \"\")\n  set(CAN_TARGET_${arch} 1)\n  list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})\nendmacro()\n\nmacro(detect_target_arch)\n  check_symbol_exists(__arm__ \"\" __ARM)\n  check_symbol_exists(__aarch64__ \"\" __AARCH64)\n  check_symbol_exists(__x86_64__ \"\" __X86_64)\n  check_symbol_exists(__i686__ \"\" __I686)\n  check_symbol_exists(__i386__ \"\" __I386)\n  check_symbol_exists(__mips__ \"\" __MIPS)\n  check_symbol_exists(__mips64__ \"\" __MIPS64)\n  if(__ARM)\n    add_default_target_arch(arm)\n  elseif(__AARCH64)\n    add_default_target_arch(aarch64)\n  elseif(__X86_64)\n    add_default_target_arch(x86_64)\n  elseif(__I686)\n    add_default_target_arch(i686)\n  elseif(__I386)\n    add_default_target_arch(i386)\n  elseif(__MIPS64) # must be checked before __MIPS\n    add_default_target_arch(mips64)\n  elseif(__MIPS)\n    add_default_target_arch(mips)\n  endif()\nendmacro()\n\n# Detect whether the current target platform is 32-bit or 64-bit, and setup\n# the correct commandline flags needed to attempt to target 32-bit and 64-bit.\nif (NOT CMAKE_SIZEOF_VOID_P EQUAL 4 AND\n    NOT CMAKE_SIZEOF_VOID_P EQUAL 8)\n  message(FATAL_ERROR \"Please use architecture with 4 or 8 byte pointers.\")\nendif()\n\n# Generate the COMPILER_RT_SUPPORTED_ARCH list.\nif(ANDROID)\n  # Examine compiler output to determine target architecture.\n  detect_target_arch()\n  set(COMPILER_RT_OS_SUFFIX \"-android\")\nelseif(NOT APPLE) # Supported archs for Apple platforms are generated later\n  if(\"${COMPILER_RT_DEFAULT_TARGET_ARCH}\" MATCHES \"i[2-6]86|x86|amd64\")\n    if(NOT MSVC)\n      test_target_arch(x86_64 \"\" \"-m64\")\n      # FIXME: We build runtimes for both i686 and i386, as \"clang -m32\" may\n      # target different variant than \"$CMAKE_C_COMPILER -m32\". This part should\n      # be gone after we resolve PR14109.\n      test_target_arch(i686 __i686__ \"-m32\")\n      test_target_arch(i386 __i386__ \"-m32\")\n    else()\n      if (CMAKE_SIZEOF_VOID_P EQUAL 4)\n        test_target_arch(i386 \"\" \"\")\n      else()\n        test_target_arch(x86_64 \"\" \"\")\n      endif()\n    endif()\n  elseif(\"${COMPILER_RT_DEFAULT_TARGET_ARCH}\" MATCHES \"powerpc\")\n    TEST_BIG_ENDIAN(HOST_IS_BIG_ENDIAN)\n    if(HOST_IS_BIG_ENDIAN)\n      test_target_arch(powerpc64 \"\" \"-m64\")\n    else()\n      test_target_arch(powerpc64le \"\" \"-m64\")\n    endif()\n  elseif(\"${COMPILER_RT_DEFAULT_TARGET_ARCH}\" MATCHES \"mipsel|mips64el\")\n    # Gcc doesn't accept -m32/-m64 so we do the next best thing and use\n    # -mips32r2/-mips64r2. We don't use -mips1/-mips3 because we want to match\n    # clang's default CPU's. In the 64-bit case, we must also specify the ABI\n    # since the default ABI differs between gcc and clang.\n    # FIXME: Ideally, we would build the N32 library too.\n    test_target_arch(mipsel \"\" \"-mips32r2\" \"--target=mipsel-linux-gnu\")\n    test_target_arch(mips64el \"\" \"-mips64r2\" \"--target=mips64el-linux-gnu\" \"-mabi=n64\")\n  elseif(\"${COMPILER_RT_DEFAULT_TARGET_ARCH}\" MATCHES \"mips\")\n    test_target_arch(mips \"\" \"-mips32r2\" \"--target=mips-linux-gnu\")\n    test_target_arch(mips64 \"\" \"-mips64r2\" \"--target=mips64-linux-gnu\" \"-mabi=n64\")\n  elseif(\"${COMPILER_RT_DEFAULT_TARGET_ARCH}\" MATCHES \"arm\")\n    test_target_arch(arm \"\" \"-march=armv7-a\" \"-mfloat-abi=soft\")\n    test_target_arch(armhf \"\" \"-march=armv7-a\" \"-mfloat-abi=hard\")\n  elseif(\"${COMPILER_RT_DEFAULT_TARGET_ARCH}\" MATCHES \"aarch32\")\n    test_target_arch(aarch32 \"\" \"-march=armv8-a\")\n  elseif(\"${COMPILER_RT_DEFAULT_TARGET_ARCH}\" MATCHES \"aarch64\")\n    test_target_arch(aarch64 \"\" \"-march=armv8-a\")\n  endif()\n  set(COMPILER_RT_OS_SUFFIX \"\")\nendif()\n\n# Takes ${ARGN} and puts only supported architectures in @out_var list.\nfunction(filter_available_targets out_var)\n  set(archs ${${out_var}})\n  foreach(arch ${ARGN})\n    list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX)\n    if(NOT (ARCH_INDEX EQUAL -1) AND CAN_TARGET_${arch})\n      list(APPEND archs ${arch})\n    endif()\n  endforeach()\n  set(${out_var} ${archs} PARENT_SCOPE)\nendfunction()\n\n# Returns a list of architecture specific target cflags in @out_var list.\nfunction(get_target_flags_for_arch arch out_var)\n  list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX)\n  if(ARCH_INDEX EQUAL -1)\n    message(FATAL_ERROR \"Unsupported architecture: ${arch}\")\n  else()\n    if (NOT APPLE)\n      set(${out_var} ${TARGET_${arch}_CFLAGS} PARENT_SCOPE)\n    else()\n      # This is only called in constructing cflags for tests executing on the\n      # host. This will need to all be cleaned up to support building tests\n      # for cross-targeted hardware (i.e. iOS).\n      set(${out_var} -arch ${arch} PARENT_SCOPE)\n    endif()\n  endif()\nendfunction()\n\nset(ARM64 aarch64)\nset(ARM32 arm armhf)\nset(X86 i386 i686)\nset(X86_64 x86_64)\nset(MIPS32 mips mipsel)\nset(MIPS64 mips64 mips64el)\nset(PPC64 powerpc64 powerpc64le)\n\nif(APPLE)\n  set(ARM64 arm64)\n  set(ARM32 armv7 armv7s)\n  set(X86_64 x86_64 x86_64h)\nendif()\n\nset(ALL_BUILTIN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}\n    ${MIPS32} ${MIPS64})\nset(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64}\n    ${ARM32} ${ARM64} ${MIPS32} ${MIPS64})\nset(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}\n    ${MIPS32} ${MIPS64} ${PPC64})\nset(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})\nset(ALL_LSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})\nset(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})\nset(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC64}\n    ${MIPS32} ${MIPS64})\nset(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64})\nset(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}\n    ${MIPS32} ${MIPS64} ${PPC64})\nset(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64})\nset(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64})\n\nif(APPLE)\n  include(CompilerRTDarwinUtils)\n\n  # On Darwin if /usr/include doesn't exist, the user probably has Xcode but not\n  # the command line tools. If this is the case, we need to find the OS X\n  # sysroot to pass to clang.\n  if(NOT EXISTS /usr/include)\n    execute_process(COMMAND xcodebuild -version -sdk macosx Path\n       OUTPUT_VARIABLE OSX_SYSROOT\n       ERROR_QUIET\n       OUTPUT_STRIP_TRAILING_WHITESPACE)\n    set(OSX_SYSROOT_FLAG \"-isysroot${OSX_SYSROOT}\")\n  endif()\n\n  option(COMPILER_RT_ENABLE_IOS \"Enable building for iOS - Experimental\" Off)\n\n  find_darwin_sdk_dir(DARWIN_osx_SYSROOT macosx)\n  find_darwin_sdk_dir(DARWIN_iossim_SYSROOT iphonesimulator)\n  find_darwin_sdk_dir(DARWIN_ios_SYSROOT iphoneos)\n\n  # Note: In order to target x86_64h on OS X the minimum deployment target must\n  # be 10.8 or higher.\n  set(SANITIZER_COMMON_SUPPORTED_OS osx)\n  set(BUILTIN_SUPPORTED_OS osx)\n  set(PROFILE_SUPPORTED_OS osx)\n  set(TSAN_SUPPORTED_OS osx)\n  if(NOT SANITIZER_MIN_OSX_VERSION)\n    string(REGEX MATCH \"-mmacosx-version-min=([.0-9]+)\"\n           MACOSX_VERSION_MIN_FLAG \"${CMAKE_CXX_FLAGS}\")\n    if(MACOSX_VERSION_MIN_FLAG)\n      set(SANITIZER_MIN_OSX_VERSION \"${CMAKE_MATCH_1}\")\n    elseif(CMAKE_OSX_DEPLOYMENT_TARGET)\n      set(SANITIZER_MIN_OSX_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET})\n    else()\n      set(SANITIZER_MIN_OSX_VERSION 10.9)\n    endif()\n    if(SANITIZER_MIN_OSX_VERSION VERSION_LESS \"10.7\")\n      message(FATAL_ERROR \"Too old OS X version: ${SANITIZER_MIN_OSX_VERSION}\")\n    endif()\n  endif()\n\n  # We're setting the flag manually for each target OS\n  set(CMAKE_OSX_DEPLOYMENT_TARGET \"\")\n  \n  set(DARWIN_COMMON_CFLAGS -stdlib=libc++)\n  set(DARWIN_COMMON_LINKFLAGS\n    -stdlib=libc++\n    -lc++\n    -lc++abi)\n  \n  set(DARWIN_osx_CFLAGS\n    ${DARWIN_COMMON_CFLAGS}\n    -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION})\n  set(DARWIN_osx_LINKFLAGS\n    ${DARWIN_COMMON_LINKFLAGS}\n    -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION})\n  set(DARWIN_osx_BUILTIN_MIN_VER 10.5)\n  set(DARWIN_osx_BUILTIN_MIN_VER_FLAG\n      -mmacosx-version-min=${DARWIN_osx_BUILTIN_MIN_VER})\n\n  if(DARWIN_osx_SYSROOT)\n    list(APPEND DARWIN_osx_CFLAGS -isysroot ${DARWIN_osx_SYSROOT})\n    list(APPEND DARWIN_osx_LINKFLAGS -isysroot ${DARWIN_osx_SYSROOT})\n  endif()\n\n  # Figure out which arches to use for each OS\n  darwin_get_toolchain_supported_archs(toolchain_arches)\n  message(STATUS \"Toolchain supported arches: ${toolchain_arches}\")\n  \n  if(NOT MACOSX_VERSION_MIN_FLAG)\n    darwin_test_archs(osx\n      DARWIN_osx_ARCHS\n      ${toolchain_arches})\n    message(STATUS \"OSX supported arches: ${DARWIN_osx_ARCHS}\")\n    foreach(arch ${DARWIN_osx_ARCHS})\n      list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})\n      set(CAN_TARGET_${arch} 1)\n    endforeach()\n\n    # Need to build a 10.4 compatible libclang_rt\n    set(DARWIN_10.4_SYSROOT ${DARWIN_osx_SYSROOT})\n    set(DARWIN_10.4_BUILTIN_MIN_VER 10.4)\n    set(DARWIN_10.4_BUILTIN_MIN_VER_FLAG\n        -mmacosx-version-min=${DARWIN_10.4_BUILTIN_MIN_VER})\n    set(DARWIN_10.4_SKIP_CC_KEXT On)\n    darwin_test_archs(10.4\n      DARWIN_10.4_ARCHS\n      ${toolchain_arches})\n    message(STATUS \"OSX 10.4 supported arches: ${DARWIN_10.4_ARCHS}\")\n    if(DARWIN_10.4_ARCHS)\n      # don't include the Haswell slice in the 10.4 compatibility library\n      list(REMOVE_ITEM DARWIN_10.4_ARCHS x86_64h)\n      list(APPEND BUILTIN_SUPPORTED_OS 10.4)\n    endif()\n\n    if(DARWIN_iossim_SYSROOT)\n      set(DARWIN_iossim_CFLAGS\n        ${DARWIN_COMMON_CFLAGS}\n        -mios-simulator-version-min=7.0\n        -isysroot ${DARWIN_iossim_SYSROOT})\n      set(DARWIN_iossim_LINKFLAGS\n        ${DARWIN_COMMON_LINKFLAGS}\n        -mios-simulator-version-min=7.0\n        -isysroot ${DARWIN_iossim_SYSROOT})\n      set(DARWIN_iossim_BUILTIN_MIN_VER 6.0)\n      set(DARWIN_iossim_BUILTIN_MIN_VER_FLAG\n        -mios-simulator-version-min=${DARWIN_iossim_BUILTIN_MIN_VER})\n\n      set(DARWIN_iossim_SKIP_CC_KEXT On)\n      darwin_test_archs(iossim\n        DARWIN_iossim_ARCHS\n        ${toolchain_arches})\n      message(STATUS \"iOS Simulator supported arches: ${DARWIN_iossim_ARCHS}\")\n      if(DARWIN_iossim_ARCHS)\n        list(APPEND SANITIZER_COMMON_SUPPORTED_OS iossim)\n        list(APPEND BUILTIN_SUPPORTED_OS iossim)\n        list(APPEND PROFILE_SUPPORTED_OS iossim)\n      endif()\n      foreach(arch ${DARWIN_iossim_ARCHS})\n        list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})\n        set(CAN_TARGET_${arch} 1)\n      endforeach()\n    endif()\n\n    if(DARWIN_ios_SYSROOT AND COMPILER_RT_ENABLE_IOS)\n      set(DARWIN_ios_CFLAGS\n        ${DARWIN_COMMON_CFLAGS}\n        -miphoneos-version-min=7.0\n        -isysroot ${DARWIN_ios_SYSROOT})\n      set(DARWIN_ios_LINKFLAGS\n        ${DARWIN_COMMON_LINKFLAGS}\n        -miphoneos-version-min=7.0\n        -isysroot ${DARWIN_ios_SYSROOT})\n      set(DARWIN_ios_BUILTIN_MIN_VER 6.0)\n      set(DARWIN_ios_BUILTIN_MIN_VER_FLAG\n        -miphoneos-version-min=${DARWIN_ios_BUILTIN_MIN_VER})\n\n      darwin_test_archs(ios\n        DARWIN_ios_ARCHS\n        ${toolchain_arches})\n      message(STATUS \"iOS supported arches: ${DARWIN_ios_ARCHS}\")\n      if(DARWIN_ios_ARCHS)\n        list(APPEND SANITIZER_COMMON_SUPPORTED_OS ios)\n        list(APPEND BUILTIN_SUPPORTED_OS ios)\n        list(APPEND PROFILE_SUPPORTED_OS ios)\n      endif()\n      foreach(arch ${DARWIN_ios_ARCHS})\n        list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})\n        set(CAN_TARGET_${arch} 1)\n      endforeach()\n    endif()\n  endif()\n\n  # for list_union\n  include(CompilerRTUtils)\n\n  list_union(BUILTIN_SUPPORTED_ARCH ALL_BUILTIN_SUPPORTED_ARCH toolchain_arches)\n\n  list_union(SANITIZER_COMMON_SUPPORTED_ARCH\n    ALL_SANITIZER_COMMON_SUPPORTED_ARCH\n    COMPILER_RT_SUPPORTED_ARCH\n    )\n  set(LSAN_COMMON_SUPPORTED_ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH})\n  set(UBSAN_COMMON_SUPPORTED_ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH})\n  list_union(ASAN_SUPPORTED_ARCH\n    ALL_ASAN_SUPPORTED_ARCH\n    SANITIZER_COMMON_SUPPORTED_ARCH)\n  list_union(DFSAN_SUPPORTED_ARCH\n    ALL_DFSAN_SUPPORTED_ARCH\n    SANITIZER_COMMON_SUPPORTED_ARCH)\n  list_union(LSAN_SUPPORTED_ARCH\n    ALL_LSAN_SUPPORTED_ARCH\n    SANITIZER_COMMON_SUPPORTED_ARCH)\n  list_union(MSAN_SUPPORTED_ARCH\n    ALL_MSAN_SUPPORTED_ARCH\n    SANITIZER_COMMON_SUPPORTED_ARCH)\n  list_union(PROFILE_SUPPORTED_ARCH\n    ALL_PROFILE_SUPPORTED_ARCH\n    SANITIZER_COMMON_SUPPORTED_ARCH)\n  list_union(TSAN_SUPPORTED_ARCH\n    ALL_TSAN_SUPPORTED_ARCH\n    SANITIZER_COMMON_SUPPORTED_ARCH)\n  list_union(UBSAN_SUPPORTED_ARCH\n    ALL_UBSAN_SUPPORTED_ARCH\n    SANITIZER_COMMON_SUPPORTED_ARCH)\n  list_union(SAFESTACK_SUPPORTED_ARCH\n    ALL_SAFESTACK_SUPPORTED_ARCH\n    SANITIZER_COMMON_SUPPORTED_ARCH)\n  list_union(CFI_SUPPORTED_ARCH\n    ALL_CFI_SUPPORTED_ARCH\n    SANITIZER_COMMON_SUPPORTED_ARCH)\nelse()\n  # Architectures supported by compiler-rt libraries.\n  filter_available_targets(BUILTIN_SUPPORTED_ARCH\n    ${ALL_BUILTIN_SUPPORTED_ARCH})\n  filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH\n    ${ALL_SANITIZER_COMMON_SUPPORTED_ARCH})\n  # LSan and UBSan common files should be available on all architectures\n  # supported by other sanitizers (even if they build into dummy object files).\n  filter_available_targets(LSAN_COMMON_SUPPORTED_ARCH\n    ${SANITIZER_COMMON_SUPPORTED_ARCH})\n  filter_available_targets(UBSAN_COMMON_SUPPORTED_ARCH\n    ${SANITIZER_COMMON_SUPPORTED_ARCH})\n  filter_available_targets(ASAN_SUPPORTED_ARCH ${ALL_ASAN_SUPPORTED_ARCH})\n  filter_available_targets(DFSAN_SUPPORTED_ARCH ${ALL_DFSAN_SUPPORTED_ARCH})\n  filter_available_targets(LSAN_SUPPORTED_ARCH ${ALL_LSAN_SUPPORTED_ARCH})\n  filter_available_targets(MSAN_SUPPORTED_ARCH ${ALL_MSAN_SUPPORTED_ARCH})\n  filter_available_targets(PROFILE_SUPPORTED_ARCH ${ALL_PROFILE_SUPPORTED_ARCH})\n  filter_available_targets(TSAN_SUPPORTED_ARCH ${ALL_TSAN_SUPPORTED_ARCH})\n  filter_available_targets(UBSAN_SUPPORTED_ARCH ${ALL_UBSAN_SUPPORTED_ARCH})\n  filter_available_targets(SAFESTACK_SUPPORTED_ARCH\n    ${ALL_SAFESTACK_SUPPORTED_ARCH})\n  filter_available_targets(CFI_SUPPORTED_ARCH ${ALL_CFI_SUPPORTED_ARCH})\nendif()\n\nmessage(STATUS \"Compiler-RT supported architectures: ${COMPILER_RT_SUPPORTED_ARCH}\")\n\nif(ANDROID)\n  set(OS_NAME \"Android\")\nelse()\n  set(OS_NAME \"${CMAKE_SYSTEM_NAME}\")\nendif()\n\nif (SANITIZER_COMMON_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND\n    (OS_NAME MATCHES \"Android|Darwin|Linux|FreeBSD\" OR\n    (OS_NAME MATCHES \"Windows\" AND MSVC)))\n  set(COMPILER_RT_HAS_SANITIZER_COMMON TRUE)\nelse()\n  set(COMPILER_RT_HAS_SANITIZER_COMMON FALSE)\nendif()\n\nif (COMPILER_RT_HAS_SANITIZER_COMMON AND\n    (NOT OS_NAME MATCHES \"Windows\" OR CMAKE_SIZEOF_VOID_P EQUAL 4))\n  set(COMPILER_RT_HAS_INTERCEPTION TRUE)\nelse()\n  set(COMPILER_RT_HAS_INTERCEPTION FALSE)\nendif()\n\nif (COMPILER_RT_HAS_SANITIZER_COMMON AND ASAN_SUPPORTED_ARCH AND\n    (NOT OS_NAME MATCHES \"Windows\" OR CMAKE_SIZEOF_VOID_P EQUAL 4))\n  set(COMPILER_RT_HAS_ASAN TRUE)\nelse()\n  set(COMPILER_RT_HAS_ASAN FALSE)\nendif()\n\nif (OS_NAME MATCHES \"Linux|FreeBSD|Windows\")\n  set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME TRUE)\nelse()\n  set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME FALSE)\nendif()\n\n# TODO: Add builtins support.\n\nif (COMPILER_RT_HAS_SANITIZER_COMMON AND DFSAN_SUPPORTED_ARCH AND\n    OS_NAME MATCHES \"Linux\")\n  set(COMPILER_RT_HAS_DFSAN TRUE)\nelse()\n  set(COMPILER_RT_HAS_DFSAN FALSE)\nendif()\n\nif (COMPILER_RT_HAS_SANITIZER_COMMON AND LSAN_SUPPORTED_ARCH AND\n    OS_NAME MATCHES \"Linux|FreeBSD\")\n  set(COMPILER_RT_HAS_LSAN TRUE)\nelse()\n  set(COMPILER_RT_HAS_LSAN FALSE)\nendif()\n\nif (COMPILER_RT_HAS_SANITIZER_COMMON AND MSAN_SUPPORTED_ARCH AND\n    OS_NAME MATCHES \"Linux\")\n  set(COMPILER_RT_HAS_MSAN TRUE)\nelse()\n  set(COMPILER_RT_HAS_MSAN FALSE)\nendif()\n\nif (PROFILE_SUPPORTED_ARCH AND\n    OS_NAME MATCHES \"Darwin|Linux|FreeBSD\")\n  set(COMPILER_RT_HAS_PROFILE TRUE)\nelse()\n  set(COMPILER_RT_HAS_PROFILE FALSE)\nendif()\n\nif (COMPILER_RT_HAS_SANITIZER_COMMON AND TSAN_SUPPORTED_ARCH AND\n    OS_NAME MATCHES \"Darwin|Linux|FreeBSD\")\n  set(COMPILER_RT_HAS_TSAN TRUE)\nelse()\n  set(COMPILER_RT_HAS_TSAN FALSE)\nendif()\n\nif (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND\n    OS_NAME MATCHES \"Darwin|Linux|FreeBSD|Windows\")\n  set(COMPILER_RT_HAS_UBSAN TRUE)\nelse()\n  set(COMPILER_RT_HAS_UBSAN FALSE)\nendif()\n\nif (COMPILER_RT_HAS_SANITIZER_COMMON AND SAFESTACK_SUPPORTED_ARCH AND\n    OS_NAME MATCHES \"Darwin|Linux|FreeBSD\")\n  set(COMPILER_RT_HAS_SAFESTACK TRUE)\nelse()\n  set(COMPILER_RT_HAS_SAFESTACK FALSE)\nendif()\n\nif (COMPILER_RT_HAS_SANITIZER_COMMON AND CFI_SUPPORTED_ARCH AND\n    OS_NAME MATCHES \"Linux\")\n  set(COMPILER_RT_HAS_CFI TRUE)\nelse()\n  set(COMPILER_RT_HAS_CFI FALSE)\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/include/CMakeLists.txt",
    "content": "set(SANITIZER_HEADERS\n  sanitizer/allocator_interface.h\n  sanitizer/asan_interface.h\n  sanitizer/common_interface_defs.h\n  sanitizer/coverage_interface.h\n  sanitizer/dfsan_interface.h\n  sanitizer/linux_syscall_hooks.h\n  sanitizer/lsan_interface.h\n  sanitizer/msan_interface.h\n  sanitizer/tsan_interface_atomic.h)\n\nset(output_dir ${COMPILER_RT_OUTPUT_DIR}/include)\n\n# Copy compiler-rt headers to the build tree.\nset(out_files)\nforeach( f ${SANITIZER_HEADERS} )\n  set( src ${CMAKE_CURRENT_SOURCE_DIR}/${f} )\n  set( dst ${output_dir}/${f} )\n  add_custom_command(OUTPUT ${dst}\n    DEPENDS ${src}\n    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}\n    COMMENT \"Copying compiler-rt's ${f}...\")\n  list(APPEND out_files ${dst})\nendforeach( f )\n\nadd_custom_target(compiler-rt-headers ALL DEPENDS ${out_files})\nadd_dependencies(compiler-rt compiler-rt-headers)\n\n# Install sanitizer headers.\ninstall(FILES ${SANITIZER_HEADERS}\n  PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ\n  DESTINATION ${COMPILER_RT_INSTALL_PATH}/include/sanitizer)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/include/sanitizer/allocator_interface.h",
    "content": "//===-- allocator_interface.h ---------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Public interface header for allocator used in sanitizers (ASan/TSan/MSan).\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_ALLOCATOR_INTERFACE_H\n#define SANITIZER_ALLOCATOR_INTERFACE_H\n\n#include <stddef.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n  /* Returns the estimated number of bytes that will be reserved by allocator\n     for request of \"size\" bytes. If allocator can't allocate that much\n     memory, returns the maximal possible allocation size, otherwise returns\n     \"size\". */\n  size_t __sanitizer_get_estimated_allocated_size(size_t size);\n\n  /* Returns true if p was returned by the allocator and\n     is not yet freed. */\n  int __sanitizer_get_ownership(const volatile void *p);\n\n  /* Returns the number of bytes reserved for the pointer p.\n     Requires (get_ownership(p) == true) or (p == 0). */\n  size_t __sanitizer_get_allocated_size(const volatile void *p);\n\n  /* Number of bytes, allocated and not yet freed by the application. */\n  size_t __sanitizer_get_current_allocated_bytes();\n\n  /* Number of bytes, mmaped by the allocator to fulfill allocation requests.\n     Generally, for request of X bytes, allocator can reserve and add to free\n     lists a large number of chunks of size X to use them for future requests.\n     All these chunks count toward the heap size. Currently, allocator never\n     releases memory to OS (instead, it just puts freed chunks to free\n     lists). */\n  size_t __sanitizer_get_heap_size();\n\n  /* Number of bytes, mmaped by the allocator, which can be used to fulfill\n     allocation requests. When a user program frees memory chunk, it can first\n     fall into quarantine and will count toward __sanitizer_get_free_bytes()\n     later. */\n  size_t __sanitizer_get_free_bytes();\n\n  /* Number of bytes in unmapped pages, that are released to OS. Currently,\n     always returns 0. */\n  size_t __sanitizer_get_unmapped_bytes();\n\n  /* Malloc hooks that may be optionally provided by user.\n     __sanitizer_malloc_hook(ptr, size) is called immediately after\n       allocation of \"size\" bytes, which returned \"ptr\".\n     __sanitizer_free_hook(ptr) is called immediately before\n       deallocation of \"ptr\". */\n  void __sanitizer_malloc_hook(const volatile void *ptr, size_t size);\n  void __sanitizer_free_hook(const volatile void *ptr);\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/include/sanitizer/asan_interface.h",
    "content": "//===-- sanitizer/asan_interface.h ------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer.\n//\n// Public interface header.\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_ASAN_INTERFACE_H\n#define SANITIZER_ASAN_INTERFACE_H\n\n#include <sanitizer/common_interface_defs.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n  // Marks memory region [addr, addr+size) as unaddressable.\n  // This memory must be previously allocated by the user program. Accessing\n  // addresses in this region from instrumented code is forbidden until\n  // this region is unpoisoned. This function is not guaranteed to poison\n  // the whole region - it may poison only subregion of [addr, addr+size) due\n  // to ASan alignment restrictions.\n  // Method is NOT thread-safe in the sense that no two threads can\n  // (un)poison memory in the same memory region simultaneously.\n  void __asan_poison_memory_region(void const volatile *addr, size_t size);\n  // Marks memory region [addr, addr+size) as addressable.\n  // This memory must be previously allocated by the user program. Accessing\n  // addresses in this region is allowed until this region is poisoned again.\n  // This function may unpoison a superregion of [addr, addr+size) due to\n  // ASan alignment restrictions.\n  // Method is NOT thread-safe in the sense that no two threads can\n  // (un)poison memory in the same memory region simultaneously.\n  void __asan_unpoison_memory_region(void const volatile *addr, size_t size);\n\n// User code should use macros instead of functions.\n#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)\n#define ASAN_POISON_MEMORY_REGION(addr, size) \\\n  __asan_poison_memory_region((addr), (size))\n#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \\\n  __asan_unpoison_memory_region((addr), (size))\n#else\n#define ASAN_POISON_MEMORY_REGION(addr, size) \\\n  ((void)(addr), (void)(size))\n#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \\\n  ((void)(addr), (void)(size))\n#endif\n\n  // Returns 1 if addr is poisoned (i.e. 1-byte read/write access to this\n  // address will result in error report from AddressSanitizer).\n  // Otherwise returns 0.\n  int __asan_address_is_poisoned(void const volatile *addr);\n\n  // If at least one byte in [beg, beg+size) is poisoned, return the address\n  // of the first such byte. Otherwise return 0.\n  void *__asan_region_is_poisoned(void *beg, size_t size);\n\n  // Print the description of addr (useful when debugging in gdb).\n  void __asan_describe_address(void *addr);\n\n  // Useful for calling from a debugger to get information about an ASan error.\n  // Returns 1 if an error has been (or is being) reported, otherwise returns 0.\n  int __asan_report_present();\n\n  // Useful for calling from a debugger to get information about an ASan error.\n  // If an error has been (or is being) reported, the following functions return\n  // the pc, bp, sp, address, access type (0 = read, 1 = write), access size and\n  // bug description (e.g. \"heap-use-after-free\"). Otherwise they return 0.\n  void *__asan_get_report_pc();\n  void *__asan_get_report_bp();\n  void *__asan_get_report_sp();\n  void *__asan_get_report_address();\n  int __asan_get_report_access_type();\n  size_t __asan_get_report_access_size();\n  const char *__asan_get_report_description();\n\n  // Useful for calling from the debugger to get information about a pointer.\n  // Returns the category of the given pointer as a constant string.\n  // Possible return values are \"global\", \"stack\", \"stack-fake\", \"heap\",\n  // \"heap-invalid\", \"shadow-low\", \"shadow-gap\", \"shadow-high\", \"unknown\".\n  // If global or stack, tries to also return the variable name, address and\n  // size. If heap, tries to return the chunk address and size. 'name' should\n  // point to an allocated buffer of size 'name_size'.\n  const char *__asan_locate_address(void *addr, char *name, size_t name_size,\n                                    void **region_address, size_t *region_size);\n\n  // Useful for calling from the debugger to get the allocation stack trace\n  // and thread ID for a heap address. Stores up to 'size' frames into 'trace',\n  // returns the number of stored frames or 0 on error.\n  size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size,\n                                int *thread_id);\n\n  // Useful for calling from the debugger to get the free stack trace\n  // and thread ID for a heap address. Stores up to 'size' frames into 'trace',\n  // returns the number of stored frames or 0 on error.\n  size_t __asan_get_free_stack(void *addr, void **trace, size_t size,\n                               int *thread_id);\n\n  // Useful for calling from the debugger to get the current shadow memory\n  // mapping.\n  void __asan_get_shadow_mapping(size_t *shadow_scale, size_t *shadow_offset);\n\n  // This is an internal function that is called to report an error.\n  // However it is still a part of the interface because users may want to\n  // set a breakpoint on this function in a debugger.\n  void __asan_report_error(void *pc, void *bp, void *sp,\n                           void *addr, int is_write, size_t access_size);\n\n  // Deprecated. Call __sanitizer_set_death_callback instead.\n  void __asan_set_death_callback(void (*callback)(void));\n\n  void __asan_set_error_report_callback(void (*callback)(const char*));\n\n  // User may provide function that would be called right when ASan detects\n  // an error. This can be used to notice cases when ASan detects an error, but\n  // the program crashes before ASan report is printed.\n  void __asan_on_error();\n\n  // Prints accumulated stats to stderr. Used for debugging.\n  void __asan_print_accumulated_stats();\n\n  // This function may be optionally provided by user and should return\n  // a string containing ASan runtime options. See asan_flags.h for details.\n  const char* __asan_default_options();\n\n  // The following 2 functions facilitate garbage collection in presence of\n  // asan's fake stack.\n\n  // Returns an opaque handler to be used later in __asan_addr_is_in_fake_stack.\n  // Returns NULL if the current thread does not have a fake stack.\n  void *__asan_get_current_fake_stack();\n\n  // If fake_stack is non-NULL and addr belongs to a fake frame in\n  // fake_stack, returns the address on real stack that corresponds to\n  // the fake frame and sets beg/end to the boundaries of this fake frame.\n  // Otherwise returns NULL and does not touch beg/end.\n  // If beg/end are NULL, they are not touched.\n  // This function may be called from a thread other than the owner of\n  // fake_stack, but the owner thread need to be alive.\n  void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,\n                                     void **end);\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#endif  // SANITIZER_ASAN_INTERFACE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/include/sanitizer/common_interface_defs.h",
    "content": "//===-- sanitizer/common_interface_defs.h -----------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Common part of the public sanitizer interface.\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_COMMON_INTERFACE_DEFS_H\n#define SANITIZER_COMMON_INTERFACE_DEFS_H\n\n#include <stddef.h>\n#include <stdint.h>\n\n// GCC does not understand __has_feature.\n#if !defined(__has_feature)\n# define __has_feature(x) 0\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n  // Arguments for __sanitizer_sandbox_on_notify() below.\n  typedef struct {\n    // Enable sandbox support in sanitizer coverage.\n    int coverage_sandboxed;\n    // File descriptor to write coverage data to. If -1 is passed, a file will\n    // be pre-opened by __sanitizer_sandobx_on_notify(). This field has no\n    // effect if coverage_sandboxed == 0.\n    intptr_t coverage_fd;\n    // If non-zero, split the coverage data into well-formed blocks. This is\n    // useful when coverage_fd is a socket descriptor. Each block will contain\n    // a header, allowing data from multiple processes to be sent over the same\n    // socket.\n    unsigned int coverage_max_block_size;\n  } __sanitizer_sandbox_arguments;\n\n  // Tell the tools to write their reports to \"path.<pid>\" instead of stderr.\n  void __sanitizer_set_report_path(const char *path);\n\n  // Notify the tools that the sandbox is going to be turned on. The reserved\n  // parameter will be used in the future to hold a structure with functions\n  // that the tools may call to bypass the sandbox.\n  void __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);\n\n  // This function is called by the tool when it has just finished reporting\n  // an error. 'error_summary' is a one-line string that summarizes\n  // the error message. This function can be overridden by the client.\n  void __sanitizer_report_error_summary(const char *error_summary);\n\n  // Some of the sanitizers (e.g. asan/tsan) may miss bugs that happen\n  // in unaligned loads/stores. In order to find such bugs reliably one needs\n  // to replace plain unaligned loads/stores with these calls.\n  uint16_t __sanitizer_unaligned_load16(const void *p);\n  uint32_t __sanitizer_unaligned_load32(const void *p);\n  uint64_t __sanitizer_unaligned_load64(const void *p);\n  void __sanitizer_unaligned_store16(void *p, uint16_t x);\n  void __sanitizer_unaligned_store32(void *p, uint32_t x);\n  void __sanitizer_unaligned_store64(void *p, uint64_t x);\n\n  // Annotate the current state of a contiguous container, such as\n  // std::vector, std::string or similar.\n  // A contiguous container is a container that keeps all of its elements\n  // in a contiguous region of memory. The container owns the region of memory\n  // [beg, end); the memory [beg, mid) is used to store the current elements\n  // and the memory [mid, end) is reserved for future elements;\n  // beg <= mid <= end. For example, in \"std::vector<> v\"\n  //   beg = &v[0];\n  //   end = beg + v.capacity() * sizeof(v[0]);\n  //   mid = beg + v.size()     * sizeof(v[0]);\n  //\n  // This annotation tells the Sanitizer tool about the current state of the\n  // container so that the tool can report errors when memory from [mid, end)\n  // is accessed. Insert this annotation into methods like push_back/pop_back.\n  // Supply the old and the new values of mid (old_mid/new_mid).\n  // In the initial state mid == end and so should be the final\n  // state when the container is destroyed or when it reallocates the storage.\n  //\n  // Use with caution and don't use for anything other than vector-like classes.\n  //\n  // For AddressSanitizer, 'beg' should be 8-aligned and 'end' should\n  // be either 8-aligned or it should point to the end of a separate heap-,\n  // stack-, or global- allocated buffer. I.e. the following will not work:\n  //   int64_t x[2];  // 16 bytes, 8-aligned.\n  //   char *beg = (char *)&x[0];\n  //   char *end = beg + 12;  // Not 8 aligned, not the end of the buffer.\n  // This however will work fine:\n  //   int32_t x[3];  // 12 bytes, but 8-aligned under AddressSanitizer.\n  //   char *beg = (char*)&x[0];\n  //   char *end = beg + 12;  // Not 8-aligned, but is the end of the buffer.\n  void __sanitizer_annotate_contiguous_container(const void *beg,\n                                                 const void *end,\n                                                 const void *old_mid,\n                                                 const void *new_mid);\n  // Returns true if the contiguous container [beg, end) is properly poisoned\n  // (e.g. with __sanitizer_annotate_contiguous_container), i.e. if\n  //  - [beg, mid) is addressable,\n  //  - [mid, end) is unaddressable.\n  // Full verification requires O(end-beg) time; this function tries to avoid\n  // such complexity by touching only parts of the container around beg/mid/end.\n  int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,\n                                              const void *end);\n\n  // Similar to __sanitizer_verify_contiguous_container but returns the address\n  // of the first improperly poisoned byte otherwise. Returns null if the area\n  // is poisoned properly.\n  const void *__sanitizer_contiguous_container_find_bad_address(\n      const void *beg, const void *mid, const void *end);\n\n  // Print the stack trace leading to this call. Useful for debugging user code.\n  void __sanitizer_print_stack_trace();\n\n  // Sets the callback to be called right before death on error.\n  // Passing 0 will unset the callback.\n  void __sanitizer_set_death_callback(void (*callback)(void));\n\n  // Interceptor hooks.\n  // Whenever a libc function interceptor is called it checks if the\n  // corresponding weak hook is defined, and it so -- calls it.\n  // The primary use case is data-flow-guided fuzzing, where the fuzzer needs\n  // to know what is being passed to libc functions, e.g. memcmp.\n  // FIXME: implement more hooks.\n  void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1,\n                                    const void *s2, size_t n);\n  void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,\n                                    const char *s2, size_t n);\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#endif  // SANITIZER_COMMON_INTERFACE_DEFS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/include/sanitizer/coverage_interface.h",
    "content": "//===-- sanitizer/coverage_interface.h --------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Public interface for sanitizer coverage.\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_COVERAG_INTERFACE_H\n#define SANITIZER_COVERAG_INTERFACE_H\n\n#include <sanitizer/common_interface_defs.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n  // Initialize coverage.\n  void __sanitizer_cov_init();\n  // Record and dump coverage info.\n  void __sanitizer_cov_dump();\n  // Open <name>.sancov.packed in the coverage directory and return the file\n  // descriptor. Returns -1 on failure, or if coverage dumping is disabled.\n  // This is intended for use by sandboxing code.\n  intptr_t __sanitizer_maybe_open_cov_file(const char *name);\n  // Get the number of unique covered blocks (or edges).\n  // This can be useful for coverage-directed in-process fuzzers.\n  uintptr_t __sanitizer_get_total_unique_coverage();\n  // Get the number of unique indirect caller-callee pairs.\n  uintptr_t __sanitizer_get_total_unique_caller_callee_pairs();\n\n  // Reset the basic-block (edge) coverage to the initial state.\n  // Useful for in-process fuzzing to start collecting coverage from scratch.\n  // Experimental, will likely not work for multi-threaded process.\n  void __sanitizer_reset_coverage();\n  // Set *data to the array of covered PCs and return the size of that array.\n  // Some of the entries in *data will be zero.\n  uintptr_t __sanitizer_get_coverage_guards(uintptr_t **data);\n\n  // The coverage instrumentation may optionally provide imprecise counters.\n  // Rather than exposing the counter values to the user we instead map\n  // the counters to a bitset.\n  // Every counter is associated with 8 bits in the bitset.\n  // We define 8 value ranges: 1, 2, 3, 4-7, 8-15, 16-31, 32-127, 128+\n  // The i-th bit is set to 1 if the counter value is in the i-th range.\n  // This counter-based coverage implementation is *not* thread-safe.\n\n  // Returns the number of registered coverage counters.\n  uintptr_t __sanitizer_get_number_of_counters();\n  // Updates the counter 'bitset', clears the counters and returns the number of\n  // new bits in 'bitset'.\n  // If 'bitset' is nullptr, only clears the counters.\n  // Otherwise 'bitset' should be at least\n  // __sanitizer_get_number_of_counters bytes long and 8-aligned.\n  uintptr_t\n  __sanitizer_update_counter_bitset_and_clear_counters(uint8_t *bitset);\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#endif  // SANITIZER_COVERAG_INTERFACE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/include/sanitizer/dfsan_interface.h",
    "content": "//===-- dfsan_interface.h -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of DataFlowSanitizer.\n//\n// Public interface header.\n//===----------------------------------------------------------------------===//\n#ifndef DFSAN_INTERFACE_H\n#define DFSAN_INTERFACE_H\n\n#include <stddef.h>\n#include <stdint.h>\n#include <sanitizer/common_interface_defs.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef uint16_t dfsan_label;\n\n/// Stores information associated with a specific label identifier.  A label\n/// may be a base label created using dfsan_create_label, with associated\n/// text description and user data, or an automatically created union label,\n/// which represents the union of two label identifiers (which may themselves\n/// be base or union labels).\nstruct dfsan_label_info {\n  // Fields for union labels, set to 0 for base labels.\n  dfsan_label l1;\n  dfsan_label l2;\n\n  // Fields for base labels.\n  const char *desc;\n  void *userdata;\n};\n\n/// Signature of the callback argument to dfsan_set_write_callback().\ntypedef void (*dfsan_write_callback_t)(int fd, const void *buf, size_t count);\n\n/// Computes the union of \\c l1 and \\c l2, possibly creating a union label in\n/// the process.\ndfsan_label dfsan_union(dfsan_label l1, dfsan_label l2);\n\n/// Creates and returns a base label with the given description and user data.\ndfsan_label dfsan_create_label(const char *desc, void *userdata);\n\n/// Sets the label for each address in [addr,addr+size) to \\c label.\nvoid dfsan_set_label(dfsan_label label, void *addr, size_t size);\n\n/// Sets the label for each address in [addr,addr+size) to the union of the\n/// current label for that address and \\c label.\nvoid dfsan_add_label(dfsan_label label, void *addr, size_t size);\n\n/// Retrieves the label associated with the given data.\n///\n/// The type of 'data' is arbitrary.  The function accepts a value of any type,\n/// which can be truncated or extended (implicitly or explicitly) as necessary.\n/// The truncation/extension operations will preserve the label of the original\n/// value.\ndfsan_label dfsan_get_label(long data);\n\n/// Retrieves the label associated with the data at the given address.\ndfsan_label dfsan_read_label(const void *addr, size_t size);\n\n/// Retrieves a pointer to the dfsan_label_info struct for the given label.\nconst struct dfsan_label_info *dfsan_get_label_info(dfsan_label label);\n\n/// Returns whether the given label label contains the label elem.\nint dfsan_has_label(dfsan_label label, dfsan_label elem);\n\n/// If the given label label contains a label with the description desc, returns\n/// that label, else returns 0.\ndfsan_label dfsan_has_label_with_desc(dfsan_label label, const char *desc);\n\n/// Returns the number of labels allocated.\nsize_t dfsan_get_label_count(void);\n\n/// Sets a callback to be invoked on calls to write().  The callback is invoked\n/// before the write is done.  The write is not guaranteed to succeed when the\n/// callback executes.  Pass in NULL to remove any callback.\nvoid dfsan_set_write_callback(dfsan_write_callback_t labeled_write_callback);\n\n/// Writes the labels currently used by the program to the given file\n/// descriptor. The lines of the output have the following format:\n///\n/// <label> <parent label 1> <parent label 2> <label description if any>\nvoid dfsan_dump_labels(int fd);\n\n/// Interceptor hooks.\n/// Whenever a dfsan's custom function is called the corresponding\n/// hook is called it non-zero. The hooks should be defined by the user.\n/// The primary use case is taint-guided fuzzing, where the fuzzer\n/// needs to see the parameters of the function and the labels.\n/// FIXME: implement more hooks.\nvoid dfsan_weak_hook_memcmp(void *caller_pc, const void *s1, const void *s2,\n                            size_t n, dfsan_label s1_label,\n                            dfsan_label s2_label, dfsan_label n_label);\nvoid dfsan_weak_hook_strncmp(void *caller_pc, const char *s1, const char *s2,\n                             size_t n, dfsan_label s1_label,\n                             dfsan_label s2_label, dfsan_label n_label);\n#ifdef __cplusplus\n}  // extern \"C\"\n\ntemplate <typename T>\nvoid dfsan_set_label(dfsan_label label, T &data) {  // NOLINT\n  dfsan_set_label(label, (void *)&data, sizeof(T));\n}\n\n#endif\n\n#endif  // DFSAN_INTERFACE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/include/sanitizer/linux_syscall_hooks.h",
    "content": "//===-- linux_syscall_hooks.h ---------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of public sanitizer interface.\n//\n// System call handlers.\n//\n// Interface methods declared in this header implement pre- and post- syscall\n// actions for the active sanitizer.\n// Usage:\n//   __sanitizer_syscall_pre_getfoo(...args...);\n//   long res = syscall(__NR_getfoo, ...args...);\n//   __sanitizer_syscall_post_getfoo(res, ...args...);\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_LINUX_SYSCALL_HOOKS_H\n#define SANITIZER_LINUX_SYSCALL_HOOKS_H\n\n#define __sanitizer_syscall_pre_time(tloc) \\\n  __sanitizer_syscall_pre_impl_time((long)(tloc))\n#define __sanitizer_syscall_post_time(res, tloc) \\\n  __sanitizer_syscall_post_impl_time(res, (long)(tloc))\n#define __sanitizer_syscall_pre_stime(tptr) \\\n  __sanitizer_syscall_pre_impl_stime((long)(tptr))\n#define __sanitizer_syscall_post_stime(res, tptr) \\\n  __sanitizer_syscall_post_impl_stime(res, (long)(tptr))\n#define __sanitizer_syscall_pre_gettimeofday(tv, tz) \\\n  __sanitizer_syscall_pre_impl_gettimeofday((long)(tv), (long)(tz))\n#define __sanitizer_syscall_post_gettimeofday(res, tv, tz) \\\n  __sanitizer_syscall_post_impl_gettimeofday(res, (long)(tv), (long)(tz))\n#define __sanitizer_syscall_pre_settimeofday(tv, tz) \\\n  __sanitizer_syscall_pre_impl_settimeofday((long)(tv), (long)(tz))\n#define __sanitizer_syscall_post_settimeofday(res, tv, tz) \\\n  __sanitizer_syscall_post_impl_settimeofday(res, (long)(tv), (long)(tz))\n#define __sanitizer_syscall_pre_adjtimex(txc_p) \\\n  __sanitizer_syscall_pre_impl_adjtimex((long)(txc_p))\n#define __sanitizer_syscall_post_adjtimex(res, txc_p) \\\n  __sanitizer_syscall_post_impl_adjtimex(res, (long)(txc_p))\n#define __sanitizer_syscall_pre_times(tbuf) \\\n  __sanitizer_syscall_pre_impl_times((long)(tbuf))\n#define __sanitizer_syscall_post_times(res, tbuf) \\\n  __sanitizer_syscall_post_impl_times(res, (long)(tbuf))\n#define __sanitizer_syscall_pre_gettid() __sanitizer_syscall_pre_impl_gettid()\n#define __sanitizer_syscall_post_gettid(res) \\\n  __sanitizer_syscall_post_impl_gettid(res)\n#define __sanitizer_syscall_pre_nanosleep(rqtp, rmtp) \\\n  __sanitizer_syscall_pre_impl_nanosleep((long)(rqtp), (long)(rmtp))\n#define __sanitizer_syscall_post_nanosleep(res, rqtp, rmtp) \\\n  __sanitizer_syscall_post_impl_nanosleep(res, (long)(rqtp), (long)(rmtp))\n#define __sanitizer_syscall_pre_alarm(seconds) \\\n  __sanitizer_syscall_pre_impl_alarm((long)(seconds))\n#define __sanitizer_syscall_post_alarm(res, seconds) \\\n  __sanitizer_syscall_post_impl_alarm(res, (long)(seconds))\n#define __sanitizer_syscall_pre_getpid() __sanitizer_syscall_pre_impl_getpid()\n#define __sanitizer_syscall_post_getpid(res) \\\n  __sanitizer_syscall_post_impl_getpid(res)\n#define __sanitizer_syscall_pre_getppid() __sanitizer_syscall_pre_impl_getppid()\n#define __sanitizer_syscall_post_getppid(res) \\\n  __sanitizer_syscall_post_impl_getppid(res)\n#define __sanitizer_syscall_pre_getuid() __sanitizer_syscall_pre_impl_getuid()\n#define __sanitizer_syscall_post_getuid(res) \\\n  __sanitizer_syscall_post_impl_getuid(res)\n#define __sanitizer_syscall_pre_geteuid() __sanitizer_syscall_pre_impl_geteuid()\n#define __sanitizer_syscall_post_geteuid(res) \\\n  __sanitizer_syscall_post_impl_geteuid(res)\n#define __sanitizer_syscall_pre_getgid() __sanitizer_syscall_pre_impl_getgid()\n#define __sanitizer_syscall_post_getgid(res) \\\n  __sanitizer_syscall_post_impl_getgid(res)\n#define __sanitizer_syscall_pre_getegid() __sanitizer_syscall_pre_impl_getegid()\n#define __sanitizer_syscall_post_getegid(res) \\\n  __sanitizer_syscall_post_impl_getegid(res)\n#define __sanitizer_syscall_pre_getresuid(ruid, euid, suid)          \\\n  __sanitizer_syscall_pre_impl_getresuid((long)(ruid), (long)(euid), \\\n                                         (long)(suid))\n#define __sanitizer_syscall_post_getresuid(res, ruid, euid, suid)          \\\n  __sanitizer_syscall_post_impl_getresuid(res, (long)(ruid), (long)(euid), \\\n                                          (long)(suid))\n#define __sanitizer_syscall_pre_getresgid(rgid, egid, sgid)          \\\n  __sanitizer_syscall_pre_impl_getresgid((long)(rgid), (long)(egid), \\\n                                         (long)(sgid))\n#define __sanitizer_syscall_post_getresgid(res, rgid, egid, sgid)          \\\n  __sanitizer_syscall_post_impl_getresgid(res, (long)(rgid), (long)(egid), \\\n                                          (long)(sgid))\n#define __sanitizer_syscall_pre_getpgid(pid) \\\n  __sanitizer_syscall_pre_impl_getpgid((long)(pid))\n#define __sanitizer_syscall_post_getpgid(res, pid) \\\n  __sanitizer_syscall_post_impl_getpgid(res, (long)(pid))\n#define __sanitizer_syscall_pre_getpgrp() __sanitizer_syscall_pre_impl_getpgrp()\n#define __sanitizer_syscall_post_getpgrp(res) \\\n  __sanitizer_syscall_post_impl_getpgrp(res)\n#define __sanitizer_syscall_pre_getsid(pid) \\\n  __sanitizer_syscall_pre_impl_getsid((long)(pid))\n#define __sanitizer_syscall_post_getsid(res, pid) \\\n  __sanitizer_syscall_post_impl_getsid(res, (long)(pid))\n#define __sanitizer_syscall_pre_getgroups(gidsetsize, grouplist) \\\n  __sanitizer_syscall_pre_impl_getgroups((long)(gidsetsize), (long)(grouplist))\n#define __sanitizer_syscall_post_getgroups(res, gidsetsize, grouplist) \\\n  __sanitizer_syscall_post_impl_getgroups(res, (long)(gidsetsize),     \\\n                                          (long)(grouplist))\n#define __sanitizer_syscall_pre_setregid(rgid, egid) \\\n  __sanitizer_syscall_pre_impl_setregid((long)(rgid), (long)(egid))\n#define __sanitizer_syscall_post_setregid(res, rgid, egid) \\\n  __sanitizer_syscall_post_impl_setregid(res, (long)(rgid), (long)(egid))\n#define __sanitizer_syscall_pre_setgid(gid) \\\n  __sanitizer_syscall_pre_impl_setgid((long)(gid))\n#define __sanitizer_syscall_post_setgid(res, gid) \\\n  __sanitizer_syscall_post_impl_setgid(res, (long)(gid))\n#define __sanitizer_syscall_pre_setreuid(ruid, euid) \\\n  __sanitizer_syscall_pre_impl_setreuid((long)(ruid), (long)(euid))\n#define __sanitizer_syscall_post_setreuid(res, ruid, euid) \\\n  __sanitizer_syscall_post_impl_setreuid(res, (long)(ruid), (long)(euid))\n#define __sanitizer_syscall_pre_setuid(uid) \\\n  __sanitizer_syscall_pre_impl_setuid((long)(uid))\n#define __sanitizer_syscall_post_setuid(res, uid) \\\n  __sanitizer_syscall_post_impl_setuid(res, (long)(uid))\n#define __sanitizer_syscall_pre_setresuid(ruid, euid, suid)          \\\n  __sanitizer_syscall_pre_impl_setresuid((long)(ruid), (long)(euid), \\\n                                         (long)(suid))\n#define __sanitizer_syscall_post_setresuid(res, ruid, euid, suid)          \\\n  __sanitizer_syscall_post_impl_setresuid(res, (long)(ruid), (long)(euid), \\\n                                          (long)(suid))\n#define __sanitizer_syscall_pre_setresgid(rgid, egid, sgid)          \\\n  __sanitizer_syscall_pre_impl_setresgid((long)(rgid), (long)(egid), \\\n                                         (long)(sgid))\n#define __sanitizer_syscall_post_setresgid(res, rgid, egid, sgid)          \\\n  __sanitizer_syscall_post_impl_setresgid(res, (long)(rgid), (long)(egid), \\\n                                          (long)(sgid))\n#define __sanitizer_syscall_pre_setfsuid(uid) \\\n  __sanitizer_syscall_pre_impl_setfsuid((long)(uid))\n#define __sanitizer_syscall_post_setfsuid(res, uid) \\\n  __sanitizer_syscall_post_impl_setfsuid(res, (long)(uid))\n#define __sanitizer_syscall_pre_setfsgid(gid) \\\n  __sanitizer_syscall_pre_impl_setfsgid((long)(gid))\n#define __sanitizer_syscall_post_setfsgid(res, gid) \\\n  __sanitizer_syscall_post_impl_setfsgid(res, (long)(gid))\n#define __sanitizer_syscall_pre_setpgid(pid, pgid) \\\n  __sanitizer_syscall_pre_impl_setpgid((long)(pid), (long)(pgid))\n#define __sanitizer_syscall_post_setpgid(res, pid, pgid) \\\n  __sanitizer_syscall_post_impl_setpgid(res, (long)(pid), (long)(pgid))\n#define __sanitizer_syscall_pre_setsid() __sanitizer_syscall_pre_impl_setsid()\n#define __sanitizer_syscall_post_setsid(res) \\\n  __sanitizer_syscall_post_impl_setsid(res)\n#define __sanitizer_syscall_pre_setgroups(gidsetsize, grouplist) \\\n  __sanitizer_syscall_pre_impl_setgroups((long)(gidsetsize), (long)(grouplist))\n#define __sanitizer_syscall_post_setgroups(res, gidsetsize, grouplist) \\\n  __sanitizer_syscall_post_impl_setgroups(res, (long)(gidsetsize),     \\\n                                          (long)(grouplist))\n#define __sanitizer_syscall_pre_acct(name) \\\n  __sanitizer_syscall_pre_impl_acct((long)(name))\n#define __sanitizer_syscall_post_acct(res, name) \\\n  __sanitizer_syscall_post_impl_acct(res, (long)(name))\n#define __sanitizer_syscall_pre_capget(header, dataptr) \\\n  __sanitizer_syscall_pre_impl_capget((long)(header), (long)(dataptr))\n#define __sanitizer_syscall_post_capget(res, header, dataptr) \\\n  __sanitizer_syscall_post_impl_capget(res, (long)(header), (long)(dataptr))\n#define __sanitizer_syscall_pre_capset(header, data) \\\n  __sanitizer_syscall_pre_impl_capset((long)(header), (long)(data))\n#define __sanitizer_syscall_post_capset(res, header, data) \\\n  __sanitizer_syscall_post_impl_capset(res, (long)(header), (long)(data))\n#define __sanitizer_syscall_pre_personality(personality) \\\n  __sanitizer_syscall_pre_impl_personality((long)(personality))\n#define __sanitizer_syscall_post_personality(res, personality) \\\n  __sanitizer_syscall_post_impl_personality(res, (long)(personality))\n#define __sanitizer_syscall_pre_sigpending(set) \\\n  __sanitizer_syscall_pre_impl_sigpending((long)(set))\n#define __sanitizer_syscall_post_sigpending(res, set) \\\n  __sanitizer_syscall_post_impl_sigpending(res, (long)(set))\n#define __sanitizer_syscall_pre_sigprocmask(how, set, oset)          \\\n  __sanitizer_syscall_pre_impl_sigprocmask((long)(how), (long)(set), \\\n                                           (long)(oset))\n#define __sanitizer_syscall_post_sigprocmask(res, how, set, oset)          \\\n  __sanitizer_syscall_post_impl_sigprocmask(res, (long)(how), (long)(set), \\\n                                            (long)(oset))\n#define __sanitizer_syscall_pre_getitimer(which, value) \\\n  __sanitizer_syscall_pre_impl_getitimer((long)(which), (long)(value))\n#define __sanitizer_syscall_post_getitimer(res, which, value) \\\n  __sanitizer_syscall_post_impl_getitimer(res, (long)(which), (long)(value))\n#define __sanitizer_syscall_pre_setitimer(which, value, ovalue)        \\\n  __sanitizer_syscall_pre_impl_setitimer((long)(which), (long)(value), \\\n                                         (long)(ovalue))\n#define __sanitizer_syscall_post_setitimer(res, which, value, ovalue)        \\\n  __sanitizer_syscall_post_impl_setitimer(res, (long)(which), (long)(value), \\\n                                          (long)(ovalue))\n#define __sanitizer_syscall_pre_timer_create(which_clock, timer_event_spec, \\\n                                             created_timer_id)              \\\n  __sanitizer_syscall_pre_impl_timer_create(                                \\\n      (long)(which_clock), (long)(timer_event_spec), (long)(created_timer_id))\n#define __sanitizer_syscall_post_timer_create(                         \\\n    res, which_clock, timer_event_spec, created_timer_id)              \\\n  __sanitizer_syscall_post_impl_timer_create(res, (long)(which_clock), \\\n                                             (long)(timer_event_spec), \\\n                                             (long)(created_timer_id))\n#define __sanitizer_syscall_pre_timer_gettime(timer_id, setting) \\\n  __sanitizer_syscall_pre_impl_timer_gettime((long)(timer_id), (long)(setting))\n#define __sanitizer_syscall_post_timer_gettime(res, timer_id, setting) \\\n  __sanitizer_syscall_post_impl_timer_gettime(res, (long)(timer_id),   \\\n                                              (long)(setting))\n#define __sanitizer_syscall_pre_timer_getoverrun(timer_id) \\\n  __sanitizer_syscall_pre_impl_timer_getoverrun((long)(timer_id))\n#define __sanitizer_syscall_post_timer_getoverrun(res, timer_id) \\\n  __sanitizer_syscall_post_impl_timer_getoverrun(res, (long)(timer_id))\n#define __sanitizer_syscall_pre_timer_settime(timer_id, flags, new_setting,   \\\n                                              old_setting)                    \\\n  __sanitizer_syscall_pre_impl_timer_settime((long)(timer_id), (long)(flags), \\\n                                             (long)(new_setting),             \\\n                                             (long)(old_setting))\n#define __sanitizer_syscall_post_timer_settime(res, timer_id, flags,     \\\n                                               new_setting, old_setting) \\\n  __sanitizer_syscall_post_impl_timer_settime(                           \\\n      res, (long)(timer_id), (long)(flags), (long)(new_setting),         \\\n      (long)(old_setting))\n#define __sanitizer_syscall_pre_timer_delete(timer_id) \\\n  __sanitizer_syscall_pre_impl_timer_delete((long)(timer_id))\n#define __sanitizer_syscall_post_timer_delete(res, timer_id) \\\n  __sanitizer_syscall_post_impl_timer_delete(res, (long)(timer_id))\n#define __sanitizer_syscall_pre_clock_settime(which_clock, tp) \\\n  __sanitizer_syscall_pre_impl_clock_settime((long)(which_clock), (long)(tp))\n#define __sanitizer_syscall_post_clock_settime(res, which_clock, tp)    \\\n  __sanitizer_syscall_post_impl_clock_settime(res, (long)(which_clock), \\\n                                              (long)(tp))\n#define __sanitizer_syscall_pre_clock_gettime(which_clock, tp) \\\n  __sanitizer_syscall_pre_impl_clock_gettime((long)(which_clock), (long)(tp))\n#define __sanitizer_syscall_post_clock_gettime(res, which_clock, tp)    \\\n  __sanitizer_syscall_post_impl_clock_gettime(res, (long)(which_clock), \\\n                                              (long)(tp))\n#define __sanitizer_syscall_pre_clock_adjtime(which_clock, tx) \\\n  __sanitizer_syscall_pre_impl_clock_adjtime((long)(which_clock), (long)(tx))\n#define __sanitizer_syscall_post_clock_adjtime(res, which_clock, tx)    \\\n  __sanitizer_syscall_post_impl_clock_adjtime(res, (long)(which_clock), \\\n                                              (long)(tx))\n#define __sanitizer_syscall_pre_clock_getres(which_clock, tp) \\\n  __sanitizer_syscall_pre_impl_clock_getres((long)(which_clock), (long)(tp))\n#define __sanitizer_syscall_post_clock_getres(res, which_clock, tp)    \\\n  __sanitizer_syscall_post_impl_clock_getres(res, (long)(which_clock), \\\n                                             (long)(tp))\n#define __sanitizer_syscall_pre_clock_nanosleep(which_clock, flags, rqtp, \\\n                                                rmtp)                     \\\n  __sanitizer_syscall_pre_impl_clock_nanosleep(                           \\\n      (long)(which_clock), (long)(flags), (long)(rqtp), (long)(rmtp))\n#define __sanitizer_syscall_post_clock_nanosleep(res, which_clock, flags, \\\n                                                 rqtp, rmtp)              \\\n  __sanitizer_syscall_post_impl_clock_nanosleep(                          \\\n      res, (long)(which_clock), (long)(flags), (long)(rqtp), (long)(rmtp))\n#define __sanitizer_syscall_pre_nice(increment) \\\n  __sanitizer_syscall_pre_impl_nice((long)(increment))\n#define __sanitizer_syscall_post_nice(res, increment) \\\n  __sanitizer_syscall_post_impl_nice(res, (long)(increment))\n#define __sanitizer_syscall_pre_sched_setscheduler(pid, policy, param)         \\\n  __sanitizer_syscall_pre_impl_sched_setscheduler((long)(pid), (long)(policy), \\\n                                                  (long)(param))\n#define __sanitizer_syscall_post_sched_setscheduler(res, pid, policy, param) \\\n  __sanitizer_syscall_post_impl_sched_setscheduler(                          \\\n      res, (long)(pid), (long)(policy), (long)(param))\n#define __sanitizer_syscall_pre_sched_setparam(pid, param) \\\n  __sanitizer_syscall_pre_impl_sched_setparam((long)(pid), (long)(param))\n#define __sanitizer_syscall_post_sched_setparam(res, pid, param) \\\n  __sanitizer_syscall_post_impl_sched_setparam(res, (long)(pid), (long)(param))\n#define __sanitizer_syscall_pre_sched_getscheduler(pid) \\\n  __sanitizer_syscall_pre_impl_sched_getscheduler((long)(pid))\n#define __sanitizer_syscall_post_sched_getscheduler(res, pid) \\\n  __sanitizer_syscall_post_impl_sched_getscheduler(res, (long)(pid))\n#define __sanitizer_syscall_pre_sched_getparam(pid, param) \\\n  __sanitizer_syscall_pre_impl_sched_getparam((long)(pid), (long)(param))\n#define __sanitizer_syscall_post_sched_getparam(res, pid, param) \\\n  __sanitizer_syscall_post_impl_sched_getparam(res, (long)(pid), (long)(param))\n#define __sanitizer_syscall_pre_sched_setaffinity(pid, len, user_mask_ptr) \\\n  __sanitizer_syscall_pre_impl_sched_setaffinity((long)(pid), (long)(len), \\\n                                                 (long)(user_mask_ptr))\n#define __sanitizer_syscall_post_sched_setaffinity(res, pid, len, \\\n                                                   user_mask_ptr) \\\n  __sanitizer_syscall_post_impl_sched_setaffinity(                \\\n      res, (long)(pid), (long)(len), (long)(user_mask_ptr))\n#define __sanitizer_syscall_pre_sched_getaffinity(pid, len, user_mask_ptr) \\\n  __sanitizer_syscall_pre_impl_sched_getaffinity((long)(pid), (long)(len), \\\n                                                 (long)(user_mask_ptr))\n#define __sanitizer_syscall_post_sched_getaffinity(res, pid, len, \\\n                                                   user_mask_ptr) \\\n  __sanitizer_syscall_post_impl_sched_getaffinity(                \\\n      res, (long)(pid), (long)(len), (long)(user_mask_ptr))\n#define __sanitizer_syscall_pre_sched_yield() \\\n  __sanitizer_syscall_pre_impl_sched_yield()\n#define __sanitizer_syscall_post_sched_yield(res) \\\n  __sanitizer_syscall_post_impl_sched_yield(res)\n#define __sanitizer_syscall_pre_sched_get_priority_max(policy) \\\n  __sanitizer_syscall_pre_impl_sched_get_priority_max((long)(policy))\n#define __sanitizer_syscall_post_sched_get_priority_max(res, policy) \\\n  __sanitizer_syscall_post_impl_sched_get_priority_max(res, (long)(policy))\n#define __sanitizer_syscall_pre_sched_get_priority_min(policy) \\\n  __sanitizer_syscall_pre_impl_sched_get_priority_min((long)(policy))\n#define __sanitizer_syscall_post_sched_get_priority_min(res, policy) \\\n  __sanitizer_syscall_post_impl_sched_get_priority_min(res, (long)(policy))\n#define __sanitizer_syscall_pre_sched_rr_get_interval(pid, interval) \\\n  __sanitizer_syscall_pre_impl_sched_rr_get_interval((long)(pid),    \\\n                                                     (long)(interval))\n#define __sanitizer_syscall_post_sched_rr_get_interval(res, pid, interval) \\\n  __sanitizer_syscall_post_impl_sched_rr_get_interval(res, (long)(pid),    \\\n                                                      (long)(interval))\n#define __sanitizer_syscall_pre_setpriority(which, who, niceval)       \\\n  __sanitizer_syscall_pre_impl_setpriority((long)(which), (long)(who), \\\n                                           (long)(niceval))\n#define __sanitizer_syscall_post_setpriority(res, which, who, niceval)       \\\n  __sanitizer_syscall_post_impl_setpriority(res, (long)(which), (long)(who), \\\n                                            (long)(niceval))\n#define __sanitizer_syscall_pre_getpriority(which, who) \\\n  __sanitizer_syscall_pre_impl_getpriority((long)(which), (long)(who))\n#define __sanitizer_syscall_post_getpriority(res, which, who) \\\n  __sanitizer_syscall_post_impl_getpriority(res, (long)(which), (long)(who))\n#define __sanitizer_syscall_pre_shutdown(arg0, arg1) \\\n  __sanitizer_syscall_pre_impl_shutdown((long)(arg0), (long)(arg1))\n#define __sanitizer_syscall_post_shutdown(res, arg0, arg1) \\\n  __sanitizer_syscall_post_impl_shutdown(res, (long)(arg0), (long)(arg1))\n#define __sanitizer_syscall_pre_reboot(magic1, magic2, cmd, arg)      \\\n  __sanitizer_syscall_pre_impl_reboot((long)(magic1), (long)(magic2), \\\n                                      (long)(cmd), (long)(arg))\n#define __sanitizer_syscall_post_reboot(res, magic1, magic2, cmd, arg)      \\\n  __sanitizer_syscall_post_impl_reboot(res, (long)(magic1), (long)(magic2), \\\n                                       (long)(cmd), (long)(arg))\n#define __sanitizer_syscall_pre_restart_syscall() \\\n  __sanitizer_syscall_pre_impl_restart_syscall()\n#define __sanitizer_syscall_post_restart_syscall(res) \\\n  __sanitizer_syscall_post_impl_restart_syscall(res)\n#define __sanitizer_syscall_pre_kexec_load(entry, nr_segments, segments,      \\\n                                           flags)                             \\\n  __sanitizer_syscall_pre_impl_kexec_load((long)(entry), (long)(nr_segments), \\\n                                          (long)(segments), (long)(flags))\n#define __sanitizer_syscall_post_kexec_load(res, entry, nr_segments, segments, \\\n                                            flags)                             \\\n  __sanitizer_syscall_post_impl_kexec_load(res, (long)(entry),                 \\\n                                           (long)(nr_segments),                \\\n                                           (long)(segments), (long)(flags))\n#define __sanitizer_syscall_pre_exit(error_code) \\\n  __sanitizer_syscall_pre_impl_exit((long)(error_code))\n#define __sanitizer_syscall_post_exit(res, error_code) \\\n  __sanitizer_syscall_post_impl_exit(res, (long)(error_code))\n#define __sanitizer_syscall_pre_exit_group(error_code) \\\n  __sanitizer_syscall_pre_impl_exit_group((long)(error_code))\n#define __sanitizer_syscall_post_exit_group(res, error_code) \\\n  __sanitizer_syscall_post_impl_exit_group(res, (long)(error_code))\n#define __sanitizer_syscall_pre_wait4(pid, stat_addr, options, ru)   \\\n  __sanitizer_syscall_pre_impl_wait4((long)(pid), (long)(stat_addr), \\\n                                     (long)(options), (long)(ru))\n#define __sanitizer_syscall_post_wait4(res, pid, stat_addr, options, ru)   \\\n  __sanitizer_syscall_post_impl_wait4(res, (long)(pid), (long)(stat_addr), \\\n                                      (long)(options), (long)(ru))\n#define __sanitizer_syscall_pre_waitid(which, pid, infop, options, ru) \\\n  __sanitizer_syscall_pre_impl_waitid(                                 \\\n      (long)(which), (long)(pid), (long)(infop), (long)(options), (long)(ru))\n#define __sanitizer_syscall_post_waitid(res, which, pid, infop, options, ru) \\\n  __sanitizer_syscall_post_impl_waitid(res, (long)(which), (long)(pid),      \\\n                                       (long)(infop), (long)(options),       \\\n                                       (long)(ru))\n#define __sanitizer_syscall_pre_waitpid(pid, stat_addr, options)       \\\n  __sanitizer_syscall_pre_impl_waitpid((long)(pid), (long)(stat_addr), \\\n                                       (long)(options))\n#define __sanitizer_syscall_post_waitpid(res, pid, stat_addr, options)       \\\n  __sanitizer_syscall_post_impl_waitpid(res, (long)(pid), (long)(stat_addr), \\\n                                        (long)(options))\n#define __sanitizer_syscall_pre_set_tid_address(tidptr) \\\n  __sanitizer_syscall_pre_impl_set_tid_address((long)(tidptr))\n#define __sanitizer_syscall_post_set_tid_address(res, tidptr) \\\n  __sanitizer_syscall_post_impl_set_tid_address(res, (long)(tidptr))\n#define __sanitizer_syscall_pre_init_module(umod, len, uargs)         \\\n  __sanitizer_syscall_pre_impl_init_module((long)(umod), (long)(len), \\\n                                           (long)(uargs))\n#define __sanitizer_syscall_post_init_module(res, umod, len, uargs)         \\\n  __sanitizer_syscall_post_impl_init_module(res, (long)(umod), (long)(len), \\\n                                            (long)(uargs))\n#define __sanitizer_syscall_pre_delete_module(name_user, flags) \\\n  __sanitizer_syscall_pre_impl_delete_module((long)(name_user), (long)(flags))\n#define __sanitizer_syscall_post_delete_module(res, name_user, flags) \\\n  __sanitizer_syscall_post_impl_delete_module(res, (long)(name_user), \\\n                                              (long)(flags))\n#define __sanitizer_syscall_pre_rt_sigprocmask(how, set, oset, sigsetsize) \\\n  __sanitizer_syscall_pre_impl_rt_sigprocmask(                             \\\n      (long)(how), (long)(set), (long)(oset), (long)(sigsetsize))\n#define __sanitizer_syscall_post_rt_sigprocmask(res, how, set, oset, \\\n                                                sigsetsize)          \\\n  __sanitizer_syscall_post_impl_rt_sigprocmask(                      \\\n      res, (long)(how), (long)(set), (long)(oset), (long)(sigsetsize))\n#define __sanitizer_syscall_pre_rt_sigpending(set, sigsetsize) \\\n  __sanitizer_syscall_pre_impl_rt_sigpending((long)(set), (long)(sigsetsize))\n#define __sanitizer_syscall_post_rt_sigpending(res, set, sigsetsize) \\\n  __sanitizer_syscall_post_impl_rt_sigpending(res, (long)(set),      \\\n                                              (long)(sigsetsize))\n#define __sanitizer_syscall_pre_rt_sigtimedwait(uthese, uinfo, uts, \\\n                                                sigsetsize)         \\\n  __sanitizer_syscall_pre_impl_rt_sigtimedwait(                     \\\n      (long)(uthese), (long)(uinfo), (long)(uts), (long)(sigsetsize))\n#define __sanitizer_syscall_post_rt_sigtimedwait(res, uthese, uinfo, uts, \\\n                                                 sigsetsize)              \\\n  __sanitizer_syscall_post_impl_rt_sigtimedwait(                          \\\n      res, (long)(uthese), (long)(uinfo), (long)(uts), (long)(sigsetsize))\n#define __sanitizer_syscall_pre_rt_tgsigqueueinfo(tgid, pid, sig, uinfo)    \\\n  __sanitizer_syscall_pre_impl_rt_tgsigqueueinfo((long)(tgid), (long)(pid), \\\n                                                 (long)(sig), (long)(uinfo))\n#define __sanitizer_syscall_post_rt_tgsigqueueinfo(res, tgid, pid, sig, uinfo) \\\n  __sanitizer_syscall_post_impl_rt_tgsigqueueinfo(                             \\\n      res, (long)(tgid), (long)(pid), (long)(sig), (long)(uinfo))\n#define __sanitizer_syscall_pre_kill(pid, sig) \\\n  __sanitizer_syscall_pre_impl_kill((long)(pid), (long)(sig))\n#define __sanitizer_syscall_post_kill(res, pid, sig) \\\n  __sanitizer_syscall_post_impl_kill(res, (long)(pid), (long)(sig))\n#define __sanitizer_syscall_pre_tgkill(tgid, pid, sig) \\\n  __sanitizer_syscall_pre_impl_tgkill((long)(tgid), (long)(pid), (long)(sig))\n#define __sanitizer_syscall_post_tgkill(res, tgid, pid, sig)           \\\n  __sanitizer_syscall_post_impl_tgkill(res, (long)(tgid), (long)(pid), \\\n                                       (long)(sig))\n#define __sanitizer_syscall_pre_tkill(pid, sig) \\\n  __sanitizer_syscall_pre_impl_tkill((long)(pid), (long)(sig))\n#define __sanitizer_syscall_post_tkill(res, pid, sig) \\\n  __sanitizer_syscall_post_impl_tkill(res, (long)(pid), (long)(sig))\n#define __sanitizer_syscall_pre_rt_sigqueueinfo(pid, sig, uinfo)         \\\n  __sanitizer_syscall_pre_impl_rt_sigqueueinfo((long)(pid), (long)(sig), \\\n                                               (long)(uinfo))\n#define __sanitizer_syscall_post_rt_sigqueueinfo(res, pid, sig, uinfo)         \\\n  __sanitizer_syscall_post_impl_rt_sigqueueinfo(res, (long)(pid), (long)(sig), \\\n                                                (long)(uinfo))\n#define __sanitizer_syscall_pre_sgetmask() \\\n  __sanitizer_syscall_pre_impl_sgetmask()\n#define __sanitizer_syscall_post_sgetmask(res) \\\n  __sanitizer_syscall_post_impl_sgetmask(res)\n#define __sanitizer_syscall_pre_ssetmask(newmask) \\\n  __sanitizer_syscall_pre_impl_ssetmask((long)(newmask))\n#define __sanitizer_syscall_post_ssetmask(res, newmask) \\\n  __sanitizer_syscall_post_impl_ssetmask(res, (long)(newmask))\n#define __sanitizer_syscall_pre_signal(sig, handler) \\\n  __sanitizer_syscall_pre_impl_signal((long)(sig), (long)(handler))\n#define __sanitizer_syscall_post_signal(res, sig, handler) \\\n  __sanitizer_syscall_post_impl_signal(res, (long)(sig), (long)(handler))\n#define __sanitizer_syscall_pre_pause() __sanitizer_syscall_pre_impl_pause()\n#define __sanitizer_syscall_post_pause(res) \\\n  __sanitizer_syscall_post_impl_pause(res)\n#define __sanitizer_syscall_pre_sync() __sanitizer_syscall_pre_impl_sync()\n#define __sanitizer_syscall_post_sync(res) \\\n  __sanitizer_syscall_post_impl_sync(res)\n#define __sanitizer_syscall_pre_fsync(fd) \\\n  __sanitizer_syscall_pre_impl_fsync((long)(fd))\n#define __sanitizer_syscall_post_fsync(res, fd) \\\n  __sanitizer_syscall_post_impl_fsync(res, (long)(fd))\n#define __sanitizer_syscall_pre_fdatasync(fd) \\\n  __sanitizer_syscall_pre_impl_fdatasync((long)(fd))\n#define __sanitizer_syscall_post_fdatasync(res, fd) \\\n  __sanitizer_syscall_post_impl_fdatasync(res, (long)(fd))\n#define __sanitizer_syscall_pre_bdflush(func, data) \\\n  __sanitizer_syscall_pre_impl_bdflush((long)(func), (long)(data))\n#define __sanitizer_syscall_post_bdflush(res, func, data) \\\n  __sanitizer_syscall_post_impl_bdflush(res, (long)(func), (long)(data))\n#define __sanitizer_syscall_pre_mount(dev_name, dir_name, type, flags, data) \\\n  __sanitizer_syscall_pre_impl_mount((long)(dev_name), (long)(dir_name),     \\\n                                     (long)(type), (long)(flags),            \\\n                                     (long)(data))\n#define __sanitizer_syscall_post_mount(res, dev_name, dir_name, type, flags,   \\\n                                       data)                                   \\\n  __sanitizer_syscall_post_impl_mount(res, (long)(dev_name), (long)(dir_name), \\\n                                      (long)(type), (long)(flags),             \\\n                                      (long)(data))\n#define __sanitizer_syscall_pre_umount(name, flags) \\\n  __sanitizer_syscall_pre_impl_umount((long)(name), (long)(flags))\n#define __sanitizer_syscall_post_umount(res, name, flags) \\\n  __sanitizer_syscall_post_impl_umount(res, (long)(name), (long)(flags))\n#define __sanitizer_syscall_pre_oldumount(name) \\\n  __sanitizer_syscall_pre_impl_oldumount((long)(name))\n#define __sanitizer_syscall_post_oldumount(res, name) \\\n  __sanitizer_syscall_post_impl_oldumount(res, (long)(name))\n#define __sanitizer_syscall_pre_truncate(path, length) \\\n  __sanitizer_syscall_pre_impl_truncate((long)(path), (long)(length))\n#define __sanitizer_syscall_post_truncate(res, path, length) \\\n  __sanitizer_syscall_post_impl_truncate(res, (long)(path), (long)(length))\n#define __sanitizer_syscall_pre_ftruncate(fd, length) \\\n  __sanitizer_syscall_pre_impl_ftruncate((long)(fd), (long)(length))\n#define __sanitizer_syscall_post_ftruncate(res, fd, length) \\\n  __sanitizer_syscall_post_impl_ftruncate(res, (long)(fd), (long)(length))\n#define __sanitizer_syscall_pre_stat(filename, statbuf) \\\n  __sanitizer_syscall_pre_impl_stat((long)(filename), (long)(statbuf))\n#define __sanitizer_syscall_post_stat(res, filename, statbuf) \\\n  __sanitizer_syscall_post_impl_stat(res, (long)(filename), (long)(statbuf))\n#define __sanitizer_syscall_pre_statfs(path, buf) \\\n  __sanitizer_syscall_pre_impl_statfs((long)(path), (long)(buf))\n#define __sanitizer_syscall_post_statfs(res, path, buf) \\\n  __sanitizer_syscall_post_impl_statfs(res, (long)(path), (long)(buf))\n#define __sanitizer_syscall_pre_statfs64(path, sz, buf) \\\n  __sanitizer_syscall_pre_impl_statfs64((long)(path), (long)(sz), (long)(buf))\n#define __sanitizer_syscall_post_statfs64(res, path, sz, buf)           \\\n  __sanitizer_syscall_post_impl_statfs64(res, (long)(path), (long)(sz), \\\n                                         (long)(buf))\n#define __sanitizer_syscall_pre_fstatfs(fd, buf) \\\n  __sanitizer_syscall_pre_impl_fstatfs((long)(fd), (long)(buf))\n#define __sanitizer_syscall_post_fstatfs(res, fd, buf) \\\n  __sanitizer_syscall_post_impl_fstatfs(res, (long)(fd), (long)(buf))\n#define __sanitizer_syscall_pre_fstatfs64(fd, sz, buf) \\\n  __sanitizer_syscall_pre_impl_fstatfs64((long)(fd), (long)(sz), (long)(buf))\n#define __sanitizer_syscall_post_fstatfs64(res, fd, sz, buf)           \\\n  __sanitizer_syscall_post_impl_fstatfs64(res, (long)(fd), (long)(sz), \\\n                                          (long)(buf))\n#define __sanitizer_syscall_pre_lstat(filename, statbuf) \\\n  __sanitizer_syscall_pre_impl_lstat((long)(filename), (long)(statbuf))\n#define __sanitizer_syscall_post_lstat(res, filename, statbuf) \\\n  __sanitizer_syscall_post_impl_lstat(res, (long)(filename), (long)(statbuf))\n#define __sanitizer_syscall_pre_fstat(fd, statbuf) \\\n  __sanitizer_syscall_pre_impl_fstat((long)(fd), (long)(statbuf))\n#define __sanitizer_syscall_post_fstat(res, fd, statbuf) \\\n  __sanitizer_syscall_post_impl_fstat(res, (long)(fd), (long)(statbuf))\n#define __sanitizer_syscall_pre_newstat(filename, statbuf) \\\n  __sanitizer_syscall_pre_impl_newstat((long)(filename), (long)(statbuf))\n#define __sanitizer_syscall_post_newstat(res, filename, statbuf) \\\n  __sanitizer_syscall_post_impl_newstat(res, (long)(filename), (long)(statbuf))\n#define __sanitizer_syscall_pre_newlstat(filename, statbuf) \\\n  __sanitizer_syscall_pre_impl_newlstat((long)(filename), (long)(statbuf))\n#define __sanitizer_syscall_post_newlstat(res, filename, statbuf) \\\n  __sanitizer_syscall_post_impl_newlstat(res, (long)(filename), (long)(statbuf))\n#define __sanitizer_syscall_pre_newfstat(fd, statbuf) \\\n  __sanitizer_syscall_pre_impl_newfstat((long)(fd), (long)(statbuf))\n#define __sanitizer_syscall_post_newfstat(res, fd, statbuf) \\\n  __sanitizer_syscall_post_impl_newfstat(res, (long)(fd), (long)(statbuf))\n#define __sanitizer_syscall_pre_ustat(dev, ubuf) \\\n  __sanitizer_syscall_pre_impl_ustat((long)(dev), (long)(ubuf))\n#define __sanitizer_syscall_post_ustat(res, dev, ubuf) \\\n  __sanitizer_syscall_post_impl_ustat(res, (long)(dev), (long)(ubuf))\n#define __sanitizer_syscall_pre_stat64(filename, statbuf) \\\n  __sanitizer_syscall_pre_impl_stat64((long)(filename), (long)(statbuf))\n#define __sanitizer_syscall_post_stat64(res, filename, statbuf) \\\n  __sanitizer_syscall_post_impl_stat64(res, (long)(filename), (long)(statbuf))\n#define __sanitizer_syscall_pre_fstat64(fd, statbuf) \\\n  __sanitizer_syscall_pre_impl_fstat64((long)(fd), (long)(statbuf))\n#define __sanitizer_syscall_post_fstat64(res, fd, statbuf) \\\n  __sanitizer_syscall_post_impl_fstat64(res, (long)(fd), (long)(statbuf))\n#define __sanitizer_syscall_pre_lstat64(filename, statbuf) \\\n  __sanitizer_syscall_pre_impl_lstat64((long)(filename), (long)(statbuf))\n#define __sanitizer_syscall_post_lstat64(res, filename, statbuf) \\\n  __sanitizer_syscall_post_impl_lstat64(res, (long)(filename), (long)(statbuf))\n#define __sanitizer_syscall_pre_setxattr(path, name, value, size, flags) \\\n  __sanitizer_syscall_pre_impl_setxattr(                                 \\\n      (long)(path), (long)(name), (long)(value), (long)(size), (long)(flags))\n#define __sanitizer_syscall_post_setxattr(res, path, name, value, size, flags) \\\n  __sanitizer_syscall_post_impl_setxattr(res, (long)(path), (long)(name),      \\\n                                         (long)(value), (long)(size),          \\\n                                         (long)(flags))\n#define __sanitizer_syscall_pre_lsetxattr(path, name, value, size, flags) \\\n  __sanitizer_syscall_pre_impl_lsetxattr(                                 \\\n      (long)(path), (long)(name), (long)(value), (long)(size), (long)(flags))\n#define __sanitizer_syscall_post_lsetxattr(res, path, name, value, size,   \\\n                                           flags)                          \\\n  __sanitizer_syscall_post_impl_lsetxattr(res, (long)(path), (long)(name), \\\n                                          (long)(value), (long)(size),     \\\n                                          (long)(flags))\n#define __sanitizer_syscall_pre_fsetxattr(fd, name, value, size, flags) \\\n  __sanitizer_syscall_pre_impl_fsetxattr(                               \\\n      (long)(fd), (long)(name), (long)(value), (long)(size), (long)(flags))\n#define __sanitizer_syscall_post_fsetxattr(res, fd, name, value, size, flags) \\\n  __sanitizer_syscall_post_impl_fsetxattr(res, (long)(fd), (long)(name),      \\\n                                          (long)(value), (long)(size),        \\\n                                          (long)(flags))\n#define __sanitizer_syscall_pre_getxattr(path, name, value, size)   \\\n  __sanitizer_syscall_pre_impl_getxattr((long)(path), (long)(name), \\\n                                        (long)(value), (long)(size))\n#define __sanitizer_syscall_post_getxattr(res, path, name, value, size)   \\\n  __sanitizer_syscall_post_impl_getxattr(res, (long)(path), (long)(name), \\\n                                         (long)(value), (long)(size))\n#define __sanitizer_syscall_pre_lgetxattr(path, name, value, size)   \\\n  __sanitizer_syscall_pre_impl_lgetxattr((long)(path), (long)(name), \\\n                                         (long)(value), (long)(size))\n#define __sanitizer_syscall_post_lgetxattr(res, path, name, value, size)   \\\n  __sanitizer_syscall_post_impl_lgetxattr(res, (long)(path), (long)(name), \\\n                                          (long)(value), (long)(size))\n#define __sanitizer_syscall_pre_fgetxattr(fd, name, value, size)   \\\n  __sanitizer_syscall_pre_impl_fgetxattr((long)(fd), (long)(name), \\\n                                         (long)(value), (long)(size))\n#define __sanitizer_syscall_post_fgetxattr(res, fd, name, value, size)   \\\n  __sanitizer_syscall_post_impl_fgetxattr(res, (long)(fd), (long)(name), \\\n                                          (long)(value), (long)(size))\n#define __sanitizer_syscall_pre_listxattr(path, list, size)          \\\n  __sanitizer_syscall_pre_impl_listxattr((long)(path), (long)(list), \\\n                                         (long)(size))\n#define __sanitizer_syscall_post_listxattr(res, path, list, size)          \\\n  __sanitizer_syscall_post_impl_listxattr(res, (long)(path), (long)(list), \\\n                                          (long)(size))\n#define __sanitizer_syscall_pre_llistxattr(path, list, size)          \\\n  __sanitizer_syscall_pre_impl_llistxattr((long)(path), (long)(list), \\\n                                          (long)(size))\n#define __sanitizer_syscall_post_llistxattr(res, path, list, size)          \\\n  __sanitizer_syscall_post_impl_llistxattr(res, (long)(path), (long)(list), \\\n                                           (long)(size))\n#define __sanitizer_syscall_pre_flistxattr(fd, list, size)          \\\n  __sanitizer_syscall_pre_impl_flistxattr((long)(fd), (long)(list), \\\n                                          (long)(size))\n#define __sanitizer_syscall_post_flistxattr(res, fd, list, size)          \\\n  __sanitizer_syscall_post_impl_flistxattr(res, (long)(fd), (long)(list), \\\n                                           (long)(size))\n#define __sanitizer_syscall_pre_removexattr(path, name) \\\n  __sanitizer_syscall_pre_impl_removexattr((long)(path), (long)(name))\n#define __sanitizer_syscall_post_removexattr(res, path, name) \\\n  __sanitizer_syscall_post_impl_removexattr(res, (long)(path), (long)(name))\n#define __sanitizer_syscall_pre_lremovexattr(path, name) \\\n  __sanitizer_syscall_pre_impl_lremovexattr((long)(path), (long)(name))\n#define __sanitizer_syscall_post_lremovexattr(res, path, name) \\\n  __sanitizer_syscall_post_impl_lremovexattr(res, (long)(path), (long)(name))\n#define __sanitizer_syscall_pre_fremovexattr(fd, name) \\\n  __sanitizer_syscall_pre_impl_fremovexattr((long)(fd), (long)(name))\n#define __sanitizer_syscall_post_fremovexattr(res, fd, name) \\\n  __sanitizer_syscall_post_impl_fremovexattr(res, (long)(fd), (long)(name))\n#define __sanitizer_syscall_pre_brk(brk) \\\n  __sanitizer_syscall_pre_impl_brk((long)(brk))\n#define __sanitizer_syscall_post_brk(res, brk) \\\n  __sanitizer_syscall_post_impl_brk(res, (long)(brk))\n#define __sanitizer_syscall_pre_mprotect(start, len, prot)          \\\n  __sanitizer_syscall_pre_impl_mprotect((long)(start), (long)(len), \\\n                                        (long)(prot))\n#define __sanitizer_syscall_post_mprotect(res, start, len, prot)          \\\n  __sanitizer_syscall_post_impl_mprotect(res, (long)(start), (long)(len), \\\n                                         (long)(prot))\n#define __sanitizer_syscall_pre_mremap(addr, old_len, new_len, flags, \\\n                                       new_addr)                      \\\n  __sanitizer_syscall_pre_impl_mremap((long)(addr), (long)(old_len),  \\\n                                      (long)(new_len), (long)(flags), \\\n                                      (long)(new_addr))\n#define __sanitizer_syscall_post_mremap(res, addr, old_len, new_len, flags, \\\n                                        new_addr)                           \\\n  __sanitizer_syscall_post_impl_mremap(res, (long)(addr), (long)(old_len),  \\\n                                       (long)(new_len), (long)(flags),      \\\n                                       (long)(new_addr))\n#define __sanitizer_syscall_pre_remap_file_pages(start, size, prot, pgoff, \\\n                                                 flags)                    \\\n  __sanitizer_syscall_pre_impl_remap_file_pages(                           \\\n      (long)(start), (long)(size), (long)(prot), (long)(pgoff), (long)(flags))\n#define __sanitizer_syscall_post_remap_file_pages(res, start, size, prot,    \\\n                                                  pgoff, flags)              \\\n  __sanitizer_syscall_post_impl_remap_file_pages(res, (long)(start),         \\\n                                                 (long)(size), (long)(prot), \\\n                                                 (long)(pgoff), (long)(flags))\n#define __sanitizer_syscall_pre_msync(start, len, flags) \\\n  __sanitizer_syscall_pre_impl_msync((long)(start), (long)(len), (long)(flags))\n#define __sanitizer_syscall_post_msync(res, start, len, flags)         \\\n  __sanitizer_syscall_post_impl_msync(res, (long)(start), (long)(len), \\\n                                      (long)(flags))\n#define __sanitizer_syscall_pre_munmap(addr, len) \\\n  __sanitizer_syscall_pre_impl_munmap((long)(addr), (long)(len))\n#define __sanitizer_syscall_post_munmap(res, addr, len) \\\n  __sanitizer_syscall_post_impl_munmap(res, (long)(addr), (long)(len))\n#define __sanitizer_syscall_pre_mlock(start, len) \\\n  __sanitizer_syscall_pre_impl_mlock((long)(start), (long)(len))\n#define __sanitizer_syscall_post_mlock(res, start, len) \\\n  __sanitizer_syscall_post_impl_mlock(res, (long)(start), (long)(len))\n#define __sanitizer_syscall_pre_munlock(start, len) \\\n  __sanitizer_syscall_pre_impl_munlock((long)(start), (long)(len))\n#define __sanitizer_syscall_post_munlock(res, start, len) \\\n  __sanitizer_syscall_post_impl_munlock(res, (long)(start), (long)(len))\n#define __sanitizer_syscall_pre_mlockall(flags) \\\n  __sanitizer_syscall_pre_impl_mlockall((long)(flags))\n#define __sanitizer_syscall_post_mlockall(res, flags) \\\n  __sanitizer_syscall_post_impl_mlockall(res, (long)(flags))\n#define __sanitizer_syscall_pre_munlockall() \\\n  __sanitizer_syscall_pre_impl_munlockall()\n#define __sanitizer_syscall_post_munlockall(res) \\\n  __sanitizer_syscall_post_impl_munlockall(res)\n#define __sanitizer_syscall_pre_madvise(start, len, behavior)      \\\n  __sanitizer_syscall_pre_impl_madvise((long)(start), (long)(len), \\\n                                       (long)(behavior))\n#define __sanitizer_syscall_post_madvise(res, start, len, behavior)      \\\n  __sanitizer_syscall_post_impl_madvise(res, (long)(start), (long)(len), \\\n                                        (long)(behavior))\n#define __sanitizer_syscall_pre_mincore(start, len, vec) \\\n  __sanitizer_syscall_pre_impl_mincore((long)(start), (long)(len), (long)(vec))\n#define __sanitizer_syscall_post_mincore(res, start, len, vec)           \\\n  __sanitizer_syscall_post_impl_mincore(res, (long)(start), (long)(len), \\\n                                        (long)(vec))\n#define __sanitizer_syscall_pre_pivot_root(new_root, put_old) \\\n  __sanitizer_syscall_pre_impl_pivot_root((long)(new_root), (long)(put_old))\n#define __sanitizer_syscall_post_pivot_root(res, new_root, put_old) \\\n  __sanitizer_syscall_post_impl_pivot_root(res, (long)(new_root),   \\\n                                           (long)(put_old))\n#define __sanitizer_syscall_pre_chroot(filename) \\\n  __sanitizer_syscall_pre_impl_chroot((long)(filename))\n#define __sanitizer_syscall_post_chroot(res, filename) \\\n  __sanitizer_syscall_post_impl_chroot(res, (long)(filename))\n#define __sanitizer_syscall_pre_mknod(filename, mode, dev)           \\\n  __sanitizer_syscall_pre_impl_mknod((long)(filename), (long)(mode), \\\n                                     (long)(dev))\n#define __sanitizer_syscall_post_mknod(res, filename, mode, dev)           \\\n  __sanitizer_syscall_post_impl_mknod(res, (long)(filename), (long)(mode), \\\n                                      (long)(dev))\n#define __sanitizer_syscall_pre_link(oldname, newname) \\\n  __sanitizer_syscall_pre_impl_link((long)(oldname), (long)(newname))\n#define __sanitizer_syscall_post_link(res, oldname, newname) \\\n  __sanitizer_syscall_post_impl_link(res, (long)(oldname), (long)(newname))\n#define __sanitizer_syscall_pre_symlink(old, new_) \\\n  __sanitizer_syscall_pre_impl_symlink((long)(old), (long)(new_))\n#define __sanitizer_syscall_post_symlink(res, old, new_) \\\n  __sanitizer_syscall_post_impl_symlink(res, (long)(old), (long)(new_))\n#define __sanitizer_syscall_pre_unlink(pathname) \\\n  __sanitizer_syscall_pre_impl_unlink((long)(pathname))\n#define __sanitizer_syscall_post_unlink(res, pathname) \\\n  __sanitizer_syscall_post_impl_unlink(res, (long)(pathname))\n#define __sanitizer_syscall_pre_rename(oldname, newname) \\\n  __sanitizer_syscall_pre_impl_rename((long)(oldname), (long)(newname))\n#define __sanitizer_syscall_post_rename(res, oldname, newname) \\\n  __sanitizer_syscall_post_impl_rename(res, (long)(oldname), (long)(newname))\n#define __sanitizer_syscall_pre_chmod(filename, mode) \\\n  __sanitizer_syscall_pre_impl_chmod((long)(filename), (long)(mode))\n#define __sanitizer_syscall_post_chmod(res, filename, mode) \\\n  __sanitizer_syscall_post_impl_chmod(res, (long)(filename), (long)(mode))\n#define __sanitizer_syscall_pre_fchmod(fd, mode) \\\n  __sanitizer_syscall_pre_impl_fchmod((long)(fd), (long)(mode))\n#define __sanitizer_syscall_post_fchmod(res, fd, mode) \\\n  __sanitizer_syscall_post_impl_fchmod(res, (long)(fd), (long)(mode))\n#define __sanitizer_syscall_pre_fcntl(fd, cmd, arg) \\\n  __sanitizer_syscall_pre_impl_fcntl((long)(fd), (long)(cmd), (long)(arg))\n#define __sanitizer_syscall_post_fcntl(res, fd, cmd, arg) \\\n  __sanitizer_syscall_post_impl_fcntl(res, (long)(fd), (long)(cmd), (long)(arg))\n#define __sanitizer_syscall_pre_fcntl64(fd, cmd, arg) \\\n  __sanitizer_syscall_pre_impl_fcntl64((long)(fd), (long)(cmd), (long)(arg))\n#define __sanitizer_syscall_post_fcntl64(res, fd, cmd, arg)           \\\n  __sanitizer_syscall_post_impl_fcntl64(res, (long)(fd), (long)(cmd), \\\n                                        (long)(arg))\n#define __sanitizer_syscall_pre_pipe(fildes) \\\n  __sanitizer_syscall_pre_impl_pipe((long)(fildes))\n#define __sanitizer_syscall_post_pipe(res, fildes) \\\n  __sanitizer_syscall_post_impl_pipe(res, (long)(fildes))\n#define __sanitizer_syscall_pre_pipe2(fildes, flags) \\\n  __sanitizer_syscall_pre_impl_pipe2((long)(fildes), (long)(flags))\n#define __sanitizer_syscall_post_pipe2(res, fildes, flags) \\\n  __sanitizer_syscall_post_impl_pipe2(res, (long)(fildes), (long)(flags))\n#define __sanitizer_syscall_pre_dup(fildes) \\\n  __sanitizer_syscall_pre_impl_dup((long)(fildes))\n#define __sanitizer_syscall_post_dup(res, fildes) \\\n  __sanitizer_syscall_post_impl_dup(res, (long)(fildes))\n#define __sanitizer_syscall_pre_dup2(oldfd, newfd) \\\n  __sanitizer_syscall_pre_impl_dup2((long)(oldfd), (long)(newfd))\n#define __sanitizer_syscall_post_dup2(res, oldfd, newfd) \\\n  __sanitizer_syscall_post_impl_dup2(res, (long)(oldfd), (long)(newfd))\n#define __sanitizer_syscall_pre_dup3(oldfd, newfd, flags) \\\n  __sanitizer_syscall_pre_impl_dup3((long)(oldfd), (long)(newfd), (long)(flags))\n#define __sanitizer_syscall_post_dup3(res, oldfd, newfd, flags)         \\\n  __sanitizer_syscall_post_impl_dup3(res, (long)(oldfd), (long)(newfd), \\\n                                     (long)(flags))\n#define __sanitizer_syscall_pre_ioperm(from, num, on) \\\n  __sanitizer_syscall_pre_impl_ioperm((long)(from), (long)(num), (long)(on))\n#define __sanitizer_syscall_post_ioperm(res, from, num, on)            \\\n  __sanitizer_syscall_post_impl_ioperm(res, (long)(from), (long)(num), \\\n                                       (long)(on))\n#define __sanitizer_syscall_pre_ioctl(fd, cmd, arg) \\\n  __sanitizer_syscall_pre_impl_ioctl((long)(fd), (long)(cmd), (long)(arg))\n#define __sanitizer_syscall_post_ioctl(res, fd, cmd, arg) \\\n  __sanitizer_syscall_post_impl_ioctl(res, (long)(fd), (long)(cmd), (long)(arg))\n#define __sanitizer_syscall_pre_flock(fd, cmd) \\\n  __sanitizer_syscall_pre_impl_flock((long)(fd), (long)(cmd))\n#define __sanitizer_syscall_post_flock(res, fd, cmd) \\\n  __sanitizer_syscall_post_impl_flock(res, (long)(fd), (long)(cmd))\n#define __sanitizer_syscall_pre_io_setup(nr_reqs, ctx) \\\n  __sanitizer_syscall_pre_impl_io_setup((long)(nr_reqs), (long)(ctx))\n#define __sanitizer_syscall_post_io_setup(res, nr_reqs, ctx) \\\n  __sanitizer_syscall_post_impl_io_setup(res, (long)(nr_reqs), (long)(ctx))\n#define __sanitizer_syscall_pre_io_destroy(ctx) \\\n  __sanitizer_syscall_pre_impl_io_destroy((long)(ctx))\n#define __sanitizer_syscall_post_io_destroy(res, ctx) \\\n  __sanitizer_syscall_post_impl_io_destroy(res, (long)(ctx))\n#define __sanitizer_syscall_pre_io_getevents(ctx_id, min_nr, nr, events,    \\\n                                             timeout)                       \\\n  __sanitizer_syscall_pre_impl_io_getevents((long)(ctx_id), (long)(min_nr), \\\n                                            (long)(nr), (long)(events),     \\\n                                            (long)(timeout))\n#define __sanitizer_syscall_post_io_getevents(res, ctx_id, min_nr, nr, events, \\\n                                              timeout)                         \\\n  __sanitizer_syscall_post_impl_io_getevents(res, (long)(ctx_id),              \\\n                                             (long)(min_nr), (long)(nr),       \\\n                                             (long)(events), (long)(timeout))\n#define __sanitizer_syscall_pre_io_submit(ctx_id, arg1, arg2)          \\\n  __sanitizer_syscall_pre_impl_io_submit((long)(ctx_id), (long)(arg1), \\\n                                         (long)(arg2))\n#define __sanitizer_syscall_post_io_submit(res, ctx_id, arg1, arg2)          \\\n  __sanitizer_syscall_post_impl_io_submit(res, (long)(ctx_id), (long)(arg1), \\\n                                          (long)(arg2))\n#define __sanitizer_syscall_pre_io_cancel(ctx_id, iocb, result)        \\\n  __sanitizer_syscall_pre_impl_io_cancel((long)(ctx_id), (long)(iocb), \\\n                                         (long)(result))\n#define __sanitizer_syscall_post_io_cancel(res, ctx_id, iocb, result)        \\\n  __sanitizer_syscall_post_impl_io_cancel(res, (long)(ctx_id), (long)(iocb), \\\n                                          (long)(result))\n#define __sanitizer_syscall_pre_sendfile(out_fd, in_fd, offset, count) \\\n  __sanitizer_syscall_pre_impl_sendfile((long)(out_fd), (long)(in_fd), \\\n                                        (long)(offset), (long)(count))\n#define __sanitizer_syscall_post_sendfile(res, out_fd, in_fd, offset, count) \\\n  __sanitizer_syscall_post_impl_sendfile(res, (long)(out_fd), (long)(in_fd), \\\n                                         (long)(offset), (long)(count))\n#define __sanitizer_syscall_pre_sendfile64(out_fd, in_fd, offset, count) \\\n  __sanitizer_syscall_pre_impl_sendfile64((long)(out_fd), (long)(in_fd), \\\n                                          (long)(offset), (long)(count))\n#define __sanitizer_syscall_post_sendfile64(res, out_fd, in_fd, offset, count) \\\n  __sanitizer_syscall_post_impl_sendfile64(res, (long)(out_fd), (long)(in_fd), \\\n                                           (long)(offset), (long)(count))\n#define __sanitizer_syscall_pre_readlink(path, buf, bufsiz)        \\\n  __sanitizer_syscall_pre_impl_readlink((long)(path), (long)(buf), \\\n                                        (long)(bufsiz))\n#define __sanitizer_syscall_post_readlink(res, path, buf, bufsiz)        \\\n  __sanitizer_syscall_post_impl_readlink(res, (long)(path), (long)(buf), \\\n                                         (long)(bufsiz))\n#define __sanitizer_syscall_pre_creat(pathname, mode) \\\n  __sanitizer_syscall_pre_impl_creat((long)(pathname), (long)(mode))\n#define __sanitizer_syscall_post_creat(res, pathname, mode) \\\n  __sanitizer_syscall_post_impl_creat(res, (long)(pathname), (long)(mode))\n#define __sanitizer_syscall_pre_open(filename, flags, mode)          \\\n  __sanitizer_syscall_pre_impl_open((long)(filename), (long)(flags), \\\n                                    (long)(mode))\n#define __sanitizer_syscall_post_open(res, filename, flags, mode)          \\\n  __sanitizer_syscall_post_impl_open(res, (long)(filename), (long)(flags), \\\n                                     (long)(mode))\n#define __sanitizer_syscall_pre_close(fd) \\\n  __sanitizer_syscall_pre_impl_close((long)(fd))\n#define __sanitizer_syscall_post_close(res, fd) \\\n  __sanitizer_syscall_post_impl_close(res, (long)(fd))\n#define __sanitizer_syscall_pre_access(filename, mode) \\\n  __sanitizer_syscall_pre_impl_access((long)(filename), (long)(mode))\n#define __sanitizer_syscall_post_access(res, filename, mode) \\\n  __sanitizer_syscall_post_impl_access(res, (long)(filename), (long)(mode))\n#define __sanitizer_syscall_pre_vhangup() __sanitizer_syscall_pre_impl_vhangup()\n#define __sanitizer_syscall_post_vhangup(res) \\\n  __sanitizer_syscall_post_impl_vhangup(res)\n#define __sanitizer_syscall_pre_chown(filename, user, group)         \\\n  __sanitizer_syscall_pre_impl_chown((long)(filename), (long)(user), \\\n                                     (long)(group))\n#define __sanitizer_syscall_post_chown(res, filename, user, group)         \\\n  __sanitizer_syscall_post_impl_chown(res, (long)(filename), (long)(user), \\\n                                      (long)(group))\n#define __sanitizer_syscall_pre_lchown(filename, user, group)         \\\n  __sanitizer_syscall_pre_impl_lchown((long)(filename), (long)(user), \\\n                                      (long)(group))\n#define __sanitizer_syscall_post_lchown(res, filename, user, group)         \\\n  __sanitizer_syscall_post_impl_lchown(res, (long)(filename), (long)(user), \\\n                                       (long)(group))\n#define __sanitizer_syscall_pre_fchown(fd, user, group) \\\n  __sanitizer_syscall_pre_impl_fchown((long)(fd), (long)(user), (long)(group))\n#define __sanitizer_syscall_post_fchown(res, fd, user, group)         \\\n  __sanitizer_syscall_post_impl_fchown(res, (long)(fd), (long)(user), \\\n                                       (long)(group))\n#define __sanitizer_syscall_pre_chown16(filename, user, group)       \\\n  __sanitizer_syscall_pre_impl_chown16((long)(filename), (long)user, \\\n                                       (long)group)\n#define __sanitizer_syscall_post_chown16(res, filename, user, group)       \\\n  __sanitizer_syscall_post_impl_chown16(res, (long)(filename), (long)user, \\\n                                        (long)group)\n#define __sanitizer_syscall_pre_lchown16(filename, user, group)       \\\n  __sanitizer_syscall_pre_impl_lchown16((long)(filename), (long)user, \\\n                                        (long)group)\n#define __sanitizer_syscall_post_lchown16(res, filename, user, group)       \\\n  __sanitizer_syscall_post_impl_lchown16(res, (long)(filename), (long)user, \\\n                                         (long)group)\n#define __sanitizer_syscall_pre_fchown16(fd, user, group) \\\n  __sanitizer_syscall_pre_impl_fchown16((long)(fd), (long)user, (long)group)\n#define __sanitizer_syscall_post_fchown16(res, fd, user, group)       \\\n  __sanitizer_syscall_post_impl_fchown16(res, (long)(fd), (long)user, \\\n                                         (long)group)\n#define __sanitizer_syscall_pre_setregid16(rgid, egid) \\\n  __sanitizer_syscall_pre_impl_setregid16((long)rgid, (long)egid)\n#define __sanitizer_syscall_post_setregid16(res, rgid, egid) \\\n  __sanitizer_syscall_post_impl_setregid16(res, (long)rgid, (long)egid)\n#define __sanitizer_syscall_pre_setgid16(gid) \\\n  __sanitizer_syscall_pre_impl_setgid16((long)gid)\n#define __sanitizer_syscall_post_setgid16(res, gid) \\\n  __sanitizer_syscall_post_impl_setgid16(res, (long)gid)\n#define __sanitizer_syscall_pre_setreuid16(ruid, euid) \\\n  __sanitizer_syscall_pre_impl_setreuid16((long)ruid, (long)euid)\n#define __sanitizer_syscall_post_setreuid16(res, ruid, euid) \\\n  __sanitizer_syscall_post_impl_setreuid16(res, (long)ruid, (long)euid)\n#define __sanitizer_syscall_pre_setuid16(uid) \\\n  __sanitizer_syscall_pre_impl_setuid16((long)uid)\n#define __sanitizer_syscall_post_setuid16(res, uid) \\\n  __sanitizer_syscall_post_impl_setuid16(res, (long)uid)\n#define __sanitizer_syscall_pre_setresuid16(ruid, euid, suid) \\\n  __sanitizer_syscall_pre_impl_setresuid16((long)ruid, (long)euid, (long)suid)\n#define __sanitizer_syscall_post_setresuid16(res, ruid, euid, suid)      \\\n  __sanitizer_syscall_post_impl_setresuid16(res, (long)ruid, (long)euid, \\\n                                            (long)suid)\n#define __sanitizer_syscall_pre_getresuid16(ruid, euid, suid)          \\\n  __sanitizer_syscall_pre_impl_getresuid16((long)(ruid), (long)(euid), \\\n                                           (long)(suid))\n#define __sanitizer_syscall_post_getresuid16(res, ruid, euid, suid)          \\\n  __sanitizer_syscall_post_impl_getresuid16(res, (long)(ruid), (long)(euid), \\\n                                            (long)(suid))\n#define __sanitizer_syscall_pre_setresgid16(rgid, egid, sgid) \\\n  __sanitizer_syscall_pre_impl_setresgid16((long)rgid, (long)egid, (long)sgid)\n#define __sanitizer_syscall_post_setresgid16(res, rgid, egid, sgid)      \\\n  __sanitizer_syscall_post_impl_setresgid16(res, (long)rgid, (long)egid, \\\n                                            (long)sgid)\n#define __sanitizer_syscall_pre_getresgid16(rgid, egid, sgid)          \\\n  __sanitizer_syscall_pre_impl_getresgid16((long)(rgid), (long)(egid), \\\n                                           (long)(sgid))\n#define __sanitizer_syscall_post_getresgid16(res, rgid, egid, sgid)          \\\n  __sanitizer_syscall_post_impl_getresgid16(res, (long)(rgid), (long)(egid), \\\n                                            (long)(sgid))\n#define __sanitizer_syscall_pre_setfsuid16(uid) \\\n  __sanitizer_syscall_pre_impl_setfsuid16((long)uid)\n#define __sanitizer_syscall_post_setfsuid16(res, uid) \\\n  __sanitizer_syscall_post_impl_setfsuid16(res, (long)uid)\n#define __sanitizer_syscall_pre_setfsgid16(gid) \\\n  __sanitizer_syscall_pre_impl_setfsgid16((long)gid)\n#define __sanitizer_syscall_post_setfsgid16(res, gid) \\\n  __sanitizer_syscall_post_impl_setfsgid16(res, (long)gid)\n#define __sanitizer_syscall_pre_getgroups16(gidsetsize, grouplist) \\\n  __sanitizer_syscall_pre_impl_getgroups16((long)(gidsetsize),     \\\n                                           (long)(grouplist))\n#define __sanitizer_syscall_post_getgroups16(res, gidsetsize, grouplist) \\\n  __sanitizer_syscall_post_impl_getgroups16(res, (long)(gidsetsize),     \\\n                                            (long)(grouplist))\n#define __sanitizer_syscall_pre_setgroups16(gidsetsize, grouplist) \\\n  __sanitizer_syscall_pre_impl_setgroups16((long)(gidsetsize),     \\\n                                           (long)(grouplist))\n#define __sanitizer_syscall_post_setgroups16(res, gidsetsize, grouplist) \\\n  __sanitizer_syscall_post_impl_setgroups16(res, (long)(gidsetsize),     \\\n                                            (long)(grouplist))\n#define __sanitizer_syscall_pre_getuid16() \\\n  __sanitizer_syscall_pre_impl_getuid16()\n#define __sanitizer_syscall_post_getuid16(res) \\\n  __sanitizer_syscall_post_impl_getuid16(res)\n#define __sanitizer_syscall_pre_geteuid16() \\\n  __sanitizer_syscall_pre_impl_geteuid16()\n#define __sanitizer_syscall_post_geteuid16(res) \\\n  __sanitizer_syscall_post_impl_geteuid16(res)\n#define __sanitizer_syscall_pre_getgid16() \\\n  __sanitizer_syscall_pre_impl_getgid16()\n#define __sanitizer_syscall_post_getgid16(res) \\\n  __sanitizer_syscall_post_impl_getgid16(res)\n#define __sanitizer_syscall_pre_getegid16() \\\n  __sanitizer_syscall_pre_impl_getegid16()\n#define __sanitizer_syscall_post_getegid16(res) \\\n  __sanitizer_syscall_post_impl_getegid16(res)\n#define __sanitizer_syscall_pre_utime(filename, times) \\\n  __sanitizer_syscall_pre_impl_utime((long)(filename), (long)(times))\n#define __sanitizer_syscall_post_utime(res, filename, times) \\\n  __sanitizer_syscall_post_impl_utime(res, (long)(filename), (long)(times))\n#define __sanitizer_syscall_pre_utimes(filename, utimes) \\\n  __sanitizer_syscall_pre_impl_utimes((long)(filename), (long)(utimes))\n#define __sanitizer_syscall_post_utimes(res, filename, utimes) \\\n  __sanitizer_syscall_post_impl_utimes(res, (long)(filename), (long)(utimes))\n#define __sanitizer_syscall_pre_lseek(fd, offset, origin) \\\n  __sanitizer_syscall_pre_impl_lseek((long)(fd), (long)(offset), (long)(origin))\n#define __sanitizer_syscall_post_lseek(res, fd, offset, origin)        \\\n  __sanitizer_syscall_post_impl_lseek(res, (long)(fd), (long)(offset), \\\n                                      (long)(origin))\n#define __sanitizer_syscall_pre_llseek(fd, offset_high, offset_low, result, \\\n                                       origin)                              \\\n  __sanitizer_syscall_pre_impl_llseek((long)(fd), (long)(offset_high),      \\\n                                      (long)(offset_low), (long)(result),   \\\n                                      (long)(origin))\n#define __sanitizer_syscall_post_llseek(res, fd, offset_high, offset_low,    \\\n                                        result, origin)                      \\\n  __sanitizer_syscall_post_impl_llseek(res, (long)(fd), (long)(offset_high), \\\n                                       (long)(offset_low), (long)(result),   \\\n                                       (long)(origin))\n#define __sanitizer_syscall_pre_read(fd, buf, count) \\\n  __sanitizer_syscall_pre_impl_read((long)(fd), (long)(buf), (long)(count))\n#define __sanitizer_syscall_post_read(res, fd, buf, count)         \\\n  __sanitizer_syscall_post_impl_read(res, (long)(fd), (long)(buf), \\\n                                     (long)(count))\n#define __sanitizer_syscall_pre_readv(fd, vec, vlen) \\\n  __sanitizer_syscall_pre_impl_readv((long)(fd), (long)(vec), (long)(vlen))\n#define __sanitizer_syscall_post_readv(res, fd, vec, vlen)          \\\n  __sanitizer_syscall_post_impl_readv(res, (long)(fd), (long)(vec), \\\n                                      (long)(vlen))\n#define __sanitizer_syscall_pre_write(fd, buf, count) \\\n  __sanitizer_syscall_pre_impl_write((long)(fd), (long)(buf), (long)(count))\n#define __sanitizer_syscall_post_write(res, fd, buf, count)         \\\n  __sanitizer_syscall_post_impl_write(res, (long)(fd), (long)(buf), \\\n                                      (long)(count))\n#define __sanitizer_syscall_pre_writev(fd, vec, vlen) \\\n  __sanitizer_syscall_pre_impl_writev((long)(fd), (long)(vec), (long)(vlen))\n#define __sanitizer_syscall_post_writev(res, fd, vec, vlen)          \\\n  __sanitizer_syscall_post_impl_writev(res, (long)(fd), (long)(vec), \\\n                                       (long)(vlen))\n\n#ifdef _LP64\n#define __sanitizer_syscall_pre_pread64(fd, buf, count, pos)                   \\\n  __sanitizer_syscall_pre_impl_pread64((long)(fd), (long)(buf), (long)(count), \\\n                                       (long)(pos))\n#define __sanitizer_syscall_post_pread64(res, fd, buf, count, pos)    \\\n  __sanitizer_syscall_post_impl_pread64(res, (long)(fd), (long)(buf), \\\n                                        (long)(count), (long)(pos))\n#define __sanitizer_syscall_pre_pwrite64(fd, buf, count, pos)    \\\n  __sanitizer_syscall_pre_impl_pwrite64((long)(fd), (long)(buf), \\\n                                        (long)(count), (long)(pos))\n#define __sanitizer_syscall_post_pwrite64(res, fd, buf, count, pos)    \\\n  __sanitizer_syscall_post_impl_pwrite64(res, (long)(fd), (long)(buf), \\\n                                         (long)(count), (long)(pos))\n#else\n#define __sanitizer_syscall_pre_pread64(fd, buf, count, pos0, pos1)            \\\n  __sanitizer_syscall_pre_impl_pread64((long)(fd), (long)(buf), (long)(count), \\\n                                       (long)(pos0), (long)(pos1))\n#define __sanitizer_syscall_post_pread64(res, fd, buf, count, pos0, pos1) \\\n  __sanitizer_syscall_post_impl_pread64(res, (long)(fd), (long)(buf),     \\\n                                        (long)(count), (long)(pos0), \\\n                                        (long)(pos1))\n#define __sanitizer_syscall_pre_pwrite64(fd, buf, count, pos0, pos1) \\\n  __sanitizer_syscall_pre_impl_pwrite64(                             \\\n      (long)(fd), (long)(buf), (long)(count), (long)(pos0), (long)(pos1))\n#define __sanitizer_syscall_post_pwrite64(res, fd, buf, count, pos0, pos1) \\\n  __sanitizer_syscall_post_impl_pwrite64(                                  \\\n      res, (long)(fd), (long)(buf), (long)(count), (long)(pos0), (long)(pos1))\n#endif\n\n#define __sanitizer_syscall_pre_preadv(fd, vec, vlen, pos_l, pos_h)          \\\n  __sanitizer_syscall_pre_impl_preadv((long)(fd), (long)(vec), (long)(vlen), \\\n                                      (long)(pos_l), (long)(pos_h))\n#define __sanitizer_syscall_post_preadv(res, fd, vec, vlen, pos_l, pos_h) \\\n  __sanitizer_syscall_post_impl_preadv(res, (long)(fd), (long)(vec),      \\\n                                       (long)(vlen), (long)(pos_l),       \\\n                                       (long)(pos_h))\n#define __sanitizer_syscall_pre_pwritev(fd, vec, vlen, pos_l, pos_h)          \\\n  __sanitizer_syscall_pre_impl_pwritev((long)(fd), (long)(vec), (long)(vlen), \\\n                                       (long)(pos_l), (long)(pos_h))\n#define __sanitizer_syscall_post_pwritev(res, fd, vec, vlen, pos_l, pos_h) \\\n  __sanitizer_syscall_post_impl_pwritev(res, (long)(fd), (long)(vec),      \\\n                                        (long)(vlen), (long)(pos_l),       \\\n                                        (long)(pos_h))\n#define __sanitizer_syscall_pre_getcwd(buf, size) \\\n  __sanitizer_syscall_pre_impl_getcwd((long)(buf), (long)(size))\n#define __sanitizer_syscall_post_getcwd(res, buf, size) \\\n  __sanitizer_syscall_post_impl_getcwd(res, (long)(buf), (long)(size))\n#define __sanitizer_syscall_pre_mkdir(pathname, mode) \\\n  __sanitizer_syscall_pre_impl_mkdir((long)(pathname), (long)(mode))\n#define __sanitizer_syscall_post_mkdir(res, pathname, mode) \\\n  __sanitizer_syscall_post_impl_mkdir(res, (long)(pathname), (long)(mode))\n#define __sanitizer_syscall_pre_chdir(filename) \\\n  __sanitizer_syscall_pre_impl_chdir((long)(filename))\n#define __sanitizer_syscall_post_chdir(res, filename) \\\n  __sanitizer_syscall_post_impl_chdir(res, (long)(filename))\n#define __sanitizer_syscall_pre_fchdir(fd) \\\n  __sanitizer_syscall_pre_impl_fchdir((long)(fd))\n#define __sanitizer_syscall_post_fchdir(res, fd) \\\n  __sanitizer_syscall_post_impl_fchdir(res, (long)(fd))\n#define __sanitizer_syscall_pre_rmdir(pathname) \\\n  __sanitizer_syscall_pre_impl_rmdir((long)(pathname))\n#define __sanitizer_syscall_post_rmdir(res, pathname) \\\n  __sanitizer_syscall_post_impl_rmdir(res, (long)(pathname))\n#define __sanitizer_syscall_pre_lookup_dcookie(cookie64, buf, len)           \\\n  __sanitizer_syscall_pre_impl_lookup_dcookie((long)(cookie64), (long)(buf), \\\n                                              (long)(len))\n#define __sanitizer_syscall_post_lookup_dcookie(res, cookie64, buf, len) \\\n  __sanitizer_syscall_post_impl_lookup_dcookie(res, (long)(cookie64),    \\\n                                               (long)(buf), (long)(len))\n#define __sanitizer_syscall_pre_quotactl(cmd, special, id, addr)      \\\n  __sanitizer_syscall_pre_impl_quotactl((long)(cmd), (long)(special), \\\n                                        (long)(id), (long)(addr))\n#define __sanitizer_syscall_post_quotactl(res, cmd, special, id, addr)      \\\n  __sanitizer_syscall_post_impl_quotactl(res, (long)(cmd), (long)(special), \\\n                                         (long)(id), (long)(addr))\n#define __sanitizer_syscall_pre_getdents(fd, dirent, count)         \\\n  __sanitizer_syscall_pre_impl_getdents((long)(fd), (long)(dirent), \\\n                                        (long)(count))\n#define __sanitizer_syscall_post_getdents(res, fd, dirent, count)         \\\n  __sanitizer_syscall_post_impl_getdents(res, (long)(fd), (long)(dirent), \\\n                                         (long)(count))\n#define __sanitizer_syscall_pre_getdents64(fd, dirent, count)         \\\n  __sanitizer_syscall_pre_impl_getdents64((long)(fd), (long)(dirent), \\\n                                          (long)(count))\n#define __sanitizer_syscall_post_getdents64(res, fd, dirent, count)         \\\n  __sanitizer_syscall_post_impl_getdents64(res, (long)(fd), (long)(dirent), \\\n                                           (long)(count))\n#define __sanitizer_syscall_pre_setsockopt(fd, level, optname, optval, optlen) \\\n  __sanitizer_syscall_pre_impl_setsockopt((long)(fd), (long)(level),           \\\n                                          (long)(optname), (long)(optval),     \\\n                                          (long)(optlen))\n#define __sanitizer_syscall_post_setsockopt(res, fd, level, optname, optval, \\\n                                            optlen)                          \\\n  __sanitizer_syscall_post_impl_setsockopt(res, (long)(fd), (long)(level),   \\\n                                           (long)(optname), (long)(optval),  \\\n                                           (long)(optlen))\n#define __sanitizer_syscall_pre_getsockopt(fd, level, optname, optval, optlen) \\\n  __sanitizer_syscall_pre_impl_getsockopt((long)(fd), (long)(level),           \\\n                                          (long)(optname), (long)(optval),     \\\n                                          (long)(optlen))\n#define __sanitizer_syscall_post_getsockopt(res, fd, level, optname, optval, \\\n                                            optlen)                          \\\n  __sanitizer_syscall_post_impl_getsockopt(res, (long)(fd), (long)(level),   \\\n                                           (long)(optname), (long)(optval),  \\\n                                           (long)(optlen))\n#define __sanitizer_syscall_pre_bind(arg0, arg1, arg2) \\\n  __sanitizer_syscall_pre_impl_bind((long)(arg0), (long)(arg1), (long)(arg2))\n#define __sanitizer_syscall_post_bind(res, arg0, arg1, arg2)          \\\n  __sanitizer_syscall_post_impl_bind(res, (long)(arg0), (long)(arg1), \\\n                                     (long)(arg2))\n#define __sanitizer_syscall_pre_connect(arg0, arg1, arg2) \\\n  __sanitizer_syscall_pre_impl_connect((long)(arg0), (long)(arg1), (long)(arg2))\n#define __sanitizer_syscall_post_connect(res, arg0, arg1, arg2)          \\\n  __sanitizer_syscall_post_impl_connect(res, (long)(arg0), (long)(arg1), \\\n                                        (long)(arg2))\n#define __sanitizer_syscall_pre_accept(arg0, arg1, arg2) \\\n  __sanitizer_syscall_pre_impl_accept((long)(arg0), (long)(arg1), (long)(arg2))\n#define __sanitizer_syscall_post_accept(res, arg0, arg1, arg2)          \\\n  __sanitizer_syscall_post_impl_accept(res, (long)(arg0), (long)(arg1), \\\n                                       (long)(arg2))\n#define __sanitizer_syscall_pre_accept4(arg0, arg1, arg2, arg3)    \\\n  __sanitizer_syscall_pre_impl_accept4((long)(arg0), (long)(arg1), \\\n                                       (long)(arg2), (long)(arg3))\n#define __sanitizer_syscall_post_accept4(res, arg0, arg1, arg2, arg3)    \\\n  __sanitizer_syscall_post_impl_accept4(res, (long)(arg0), (long)(arg1), \\\n                                        (long)(arg2), (long)(arg3))\n#define __sanitizer_syscall_pre_getsockname(arg0, arg1, arg2)          \\\n  __sanitizer_syscall_pre_impl_getsockname((long)(arg0), (long)(arg1), \\\n                                           (long)(arg2))\n#define __sanitizer_syscall_post_getsockname(res, arg0, arg1, arg2)          \\\n  __sanitizer_syscall_post_impl_getsockname(res, (long)(arg0), (long)(arg1), \\\n                                            (long)(arg2))\n#define __sanitizer_syscall_pre_getpeername(arg0, arg1, arg2)          \\\n  __sanitizer_syscall_pre_impl_getpeername((long)(arg0), (long)(arg1), \\\n                                           (long)(arg2))\n#define __sanitizer_syscall_post_getpeername(res, arg0, arg1, arg2)          \\\n  __sanitizer_syscall_post_impl_getpeername(res, (long)(arg0), (long)(arg1), \\\n                                            (long)(arg2))\n#define __sanitizer_syscall_pre_send(arg0, arg1, arg2, arg3)                  \\\n  __sanitizer_syscall_pre_impl_send((long)(arg0), (long)(arg1), (long)(arg2), \\\n                                    (long)(arg3))\n#define __sanitizer_syscall_post_send(res, arg0, arg1, arg2, arg3)    \\\n  __sanitizer_syscall_post_impl_send(res, (long)(arg0), (long)(arg1), \\\n                                     (long)(arg2), (long)(arg3))\n#define __sanitizer_syscall_pre_sendto(arg0, arg1, arg2, arg3, arg4, arg5) \\\n  __sanitizer_syscall_pre_impl_sendto((long)(arg0), (long)(arg1),          \\\n                                      (long)(arg2), (long)(arg3),          \\\n                                      (long)(arg4), (long)(arg5))\n#define __sanitizer_syscall_post_sendto(res, arg0, arg1, arg2, arg3, arg4, \\\n                                        arg5)                              \\\n  __sanitizer_syscall_post_impl_sendto(res, (long)(arg0), (long)(arg1),    \\\n                                       (long)(arg2), (long)(arg3),         \\\n                                       (long)(arg4), (long)(arg5))\n#define __sanitizer_syscall_pre_sendmsg(fd, msg, flags) \\\n  __sanitizer_syscall_pre_impl_sendmsg((long)(fd), (long)(msg), (long)(flags))\n#define __sanitizer_syscall_post_sendmsg(res, fd, msg, flags)         \\\n  __sanitizer_syscall_post_impl_sendmsg(res, (long)(fd), (long)(msg), \\\n                                        (long)(flags))\n#define __sanitizer_syscall_pre_sendmmsg(fd, msg, vlen, flags)                 \\\n  __sanitizer_syscall_pre_impl_sendmmsg((long)(fd), (long)(msg), (long)(vlen), \\\n                                        (long)(flags))\n#define __sanitizer_syscall_post_sendmmsg(res, fd, msg, vlen, flags)   \\\n  __sanitizer_syscall_post_impl_sendmmsg(res, (long)(fd), (long)(msg), \\\n                                         (long)(vlen), (long)(flags))\n#define __sanitizer_syscall_pre_recv(arg0, arg1, arg2, arg3)                  \\\n  __sanitizer_syscall_pre_impl_recv((long)(arg0), (long)(arg1), (long)(arg2), \\\n                                    (long)(arg3))\n#define __sanitizer_syscall_post_recv(res, arg0, arg1, arg2, arg3)    \\\n  __sanitizer_syscall_post_impl_recv(res, (long)(arg0), (long)(arg1), \\\n                                     (long)(arg2), (long)(arg3))\n#define __sanitizer_syscall_pre_recvfrom(arg0, arg1, arg2, arg3, arg4, arg5) \\\n  __sanitizer_syscall_pre_impl_recvfrom((long)(arg0), (long)(arg1),          \\\n                                        (long)(arg2), (long)(arg3),          \\\n                                        (long)(arg4), (long)(arg5))\n#define __sanitizer_syscall_post_recvfrom(res, arg0, arg1, arg2, arg3, arg4, \\\n                                          arg5)                              \\\n  __sanitizer_syscall_post_impl_recvfrom(res, (long)(arg0), (long)(arg1),    \\\n                                         (long)(arg2), (long)(arg3),         \\\n                                         (long)(arg4), (long)(arg5))\n#define __sanitizer_syscall_pre_recvmsg(fd, msg, flags) \\\n  __sanitizer_syscall_pre_impl_recvmsg((long)(fd), (long)(msg), (long)(flags))\n#define __sanitizer_syscall_post_recvmsg(res, fd, msg, flags)         \\\n  __sanitizer_syscall_post_impl_recvmsg(res, (long)(fd), (long)(msg), \\\n                                        (long)(flags))\n#define __sanitizer_syscall_pre_recvmmsg(fd, msg, vlen, flags, timeout)        \\\n  __sanitizer_syscall_pre_impl_recvmmsg((long)(fd), (long)(msg), (long)(vlen), \\\n                                        (long)(flags), (long)(timeout))\n#define __sanitizer_syscall_post_recvmmsg(res, fd, msg, vlen, flags, timeout) \\\n  __sanitizer_syscall_post_impl_recvmmsg(res, (long)(fd), (long)(msg),        \\\n                                         (long)(vlen), (long)(flags),         \\\n                                         (long)(timeout))\n#define __sanitizer_syscall_pre_socket(arg0, arg1, arg2) \\\n  __sanitizer_syscall_pre_impl_socket((long)(arg0), (long)(arg1), (long)(arg2))\n#define __sanitizer_syscall_post_socket(res, arg0, arg1, arg2)          \\\n  __sanitizer_syscall_post_impl_socket(res, (long)(arg0), (long)(arg1), \\\n                                       (long)(arg2))\n#define __sanitizer_syscall_pre_socketpair(arg0, arg1, arg2, arg3)    \\\n  __sanitizer_syscall_pre_impl_socketpair((long)(arg0), (long)(arg1), \\\n                                          (long)(arg2), (long)(arg3))\n#define __sanitizer_syscall_post_socketpair(res, arg0, arg1, arg2, arg3)    \\\n  __sanitizer_syscall_post_impl_socketpair(res, (long)(arg0), (long)(arg1), \\\n                                           (long)(arg2), (long)(arg3))\n#define __sanitizer_syscall_pre_socketcall(call, args) \\\n  __sanitizer_syscall_pre_impl_socketcall((long)(call), (long)(args))\n#define __sanitizer_syscall_post_socketcall(res, call, args) \\\n  __sanitizer_syscall_post_impl_socketcall(res, (long)(call), (long)(args))\n#define __sanitizer_syscall_pre_listen(arg0, arg1) \\\n  __sanitizer_syscall_pre_impl_listen((long)(arg0), (long)(arg1))\n#define __sanitizer_syscall_post_listen(res, arg0, arg1) \\\n  __sanitizer_syscall_post_impl_listen(res, (long)(arg0), (long)(arg1))\n#define __sanitizer_syscall_pre_poll(ufds, nfds, timeout) \\\n  __sanitizer_syscall_pre_impl_poll((long)(ufds), (long)(nfds), (long)(timeout))\n#define __sanitizer_syscall_post_poll(res, ufds, nfds, timeout)       \\\n  __sanitizer_syscall_post_impl_poll(res, (long)(ufds), (long)(nfds), \\\n                                     (long)(timeout))\n#define __sanitizer_syscall_pre_select(n, inp, outp, exp, tvp)              \\\n  __sanitizer_syscall_pre_impl_select((long)(n), (long)(inp), (long)(outp), \\\n                                      (long)(exp), (long)(tvp))\n#define __sanitizer_syscall_post_select(res, n, inp, outp, exp, tvp) \\\n  __sanitizer_syscall_post_impl_select(res, (long)(n), (long)(inp),  \\\n                                       (long)(outp), (long)(exp), (long)(tvp))\n#define __sanitizer_syscall_pre_old_select(arg) \\\n  __sanitizer_syscall_pre_impl_old_select((long)(arg))\n#define __sanitizer_syscall_post_old_select(res, arg) \\\n  __sanitizer_syscall_post_impl_old_select(res, (long)(arg))\n#define __sanitizer_syscall_pre_epoll_create(size) \\\n  __sanitizer_syscall_pre_impl_epoll_create((long)(size))\n#define __sanitizer_syscall_post_epoll_create(res, size) \\\n  __sanitizer_syscall_post_impl_epoll_create(res, (long)(size))\n#define __sanitizer_syscall_pre_epoll_create1(flags) \\\n  __sanitizer_syscall_pre_impl_epoll_create1((long)(flags))\n#define __sanitizer_syscall_post_epoll_create1(res, flags) \\\n  __sanitizer_syscall_post_impl_epoll_create1(res, (long)(flags))\n#define __sanitizer_syscall_pre_epoll_ctl(epfd, op, fd, event)                 \\\n  __sanitizer_syscall_pre_impl_epoll_ctl((long)(epfd), (long)(op), (long)(fd), \\\n                                         (long)(event))\n#define __sanitizer_syscall_post_epoll_ctl(res, epfd, op, fd, event)     \\\n  __sanitizer_syscall_post_impl_epoll_ctl(res, (long)(epfd), (long)(op), \\\n                                          (long)(fd), (long)(event))\n#define __sanitizer_syscall_pre_epoll_wait(epfd, events, maxevents, timeout) \\\n  __sanitizer_syscall_pre_impl_epoll_wait((long)(epfd), (long)(events),      \\\n                                          (long)(maxevents), (long)(timeout))\n#define __sanitizer_syscall_post_epoll_wait(res, epfd, events, maxevents,     \\\n                                            timeout)                          \\\n  __sanitizer_syscall_post_impl_epoll_wait(res, (long)(epfd), (long)(events), \\\n                                           (long)(maxevents), (long)(timeout))\n#define __sanitizer_syscall_pre_epoll_pwait(epfd, events, maxevents, timeout, \\\n                                            sigmask, sigsetsize)              \\\n  __sanitizer_syscall_pre_impl_epoll_pwait(                                   \\\n      (long)(epfd), (long)(events), (long)(maxevents), (long)(timeout),       \\\n      (long)(sigmask), (long)(sigsetsize))\n#define __sanitizer_syscall_post_epoll_pwait(res, epfd, events, maxevents,   \\\n                                             timeout, sigmask, sigsetsize)   \\\n  __sanitizer_syscall_post_impl_epoll_pwait(                                 \\\n      res, (long)(epfd), (long)(events), (long)(maxevents), (long)(timeout), \\\n      (long)(sigmask), (long)(sigsetsize))\n#define __sanitizer_syscall_pre_gethostname(name, len) \\\n  __sanitizer_syscall_pre_impl_gethostname((long)(name), (long)(len))\n#define __sanitizer_syscall_post_gethostname(res, name, len) \\\n  __sanitizer_syscall_post_impl_gethostname(res, (long)(name), (long)(len))\n#define __sanitizer_syscall_pre_sethostname(name, len) \\\n  __sanitizer_syscall_pre_impl_sethostname((long)(name), (long)(len))\n#define __sanitizer_syscall_post_sethostname(res, name, len) \\\n  __sanitizer_syscall_post_impl_sethostname(res, (long)(name), (long)(len))\n#define __sanitizer_syscall_pre_setdomainname(name, len) \\\n  __sanitizer_syscall_pre_impl_setdomainname((long)(name), (long)(len))\n#define __sanitizer_syscall_post_setdomainname(res, name, len) \\\n  __sanitizer_syscall_post_impl_setdomainname(res, (long)(name), (long)(len))\n#define __sanitizer_syscall_pre_newuname(name) \\\n  __sanitizer_syscall_pre_impl_newuname((long)(name))\n#define __sanitizer_syscall_post_newuname(res, name) \\\n  __sanitizer_syscall_post_impl_newuname(res, (long)(name))\n#define __sanitizer_syscall_pre_uname(arg0) \\\n  __sanitizer_syscall_pre_impl_uname((long)(arg0))\n#define __sanitizer_syscall_post_uname(res, arg0) \\\n  __sanitizer_syscall_post_impl_uname(res, (long)(arg0))\n#define __sanitizer_syscall_pre_olduname(arg0) \\\n  __sanitizer_syscall_pre_impl_olduname((long)(arg0))\n#define __sanitizer_syscall_post_olduname(res, arg0) \\\n  __sanitizer_syscall_post_impl_olduname(res, (long)(arg0))\n#define __sanitizer_syscall_pre_getrlimit(resource, rlim) \\\n  __sanitizer_syscall_pre_impl_getrlimit((long)(resource), (long)(rlim))\n#define __sanitizer_syscall_post_getrlimit(res, resource, rlim) \\\n  __sanitizer_syscall_post_impl_getrlimit(res, (long)(resource), (long)(rlim))\n#define __sanitizer_syscall_pre_old_getrlimit(resource, rlim) \\\n  __sanitizer_syscall_pre_impl_old_getrlimit((long)(resource), (long)(rlim))\n#define __sanitizer_syscall_post_old_getrlimit(res, resource, rlim)  \\\n  __sanitizer_syscall_post_impl_old_getrlimit(res, (long)(resource), \\\n                                              (long)(rlim))\n#define __sanitizer_syscall_pre_setrlimit(resource, rlim) \\\n  __sanitizer_syscall_pre_impl_setrlimit((long)(resource), (long)(rlim))\n#define __sanitizer_syscall_post_setrlimit(res, resource, rlim) \\\n  __sanitizer_syscall_post_impl_setrlimit(res, (long)(resource), (long)(rlim))\n#define __sanitizer_syscall_pre_prlimit64(pid, resource, new_rlim, old_rlim) \\\n  __sanitizer_syscall_pre_impl_prlimit64((long)(pid), (long)(resource),      \\\n                                         (long)(new_rlim), (long)(old_rlim))\n#define __sanitizer_syscall_post_prlimit64(res, pid, resource, new_rlim,      \\\n                                           old_rlim)                          \\\n  __sanitizer_syscall_post_impl_prlimit64(res, (long)(pid), (long)(resource), \\\n                                          (long)(new_rlim), (long)(old_rlim))\n#define __sanitizer_syscall_pre_getrusage(who, ru) \\\n  __sanitizer_syscall_pre_impl_getrusage((long)(who), (long)(ru))\n#define __sanitizer_syscall_post_getrusage(res, who, ru) \\\n  __sanitizer_syscall_post_impl_getrusage(res, (long)(who), (long)(ru))\n#define __sanitizer_syscall_pre_umask(mask) \\\n  __sanitizer_syscall_pre_impl_umask((long)(mask))\n#define __sanitizer_syscall_post_umask(res, mask) \\\n  __sanitizer_syscall_post_impl_umask(res, (long)(mask))\n#define __sanitizer_syscall_pre_msgget(key, msgflg) \\\n  __sanitizer_syscall_pre_impl_msgget((long)(key), (long)(msgflg))\n#define __sanitizer_syscall_post_msgget(res, key, msgflg) \\\n  __sanitizer_syscall_post_impl_msgget(res, (long)(key), (long)(msgflg))\n#define __sanitizer_syscall_pre_msgsnd(msqid, msgp, msgsz, msgflg) \\\n  __sanitizer_syscall_pre_impl_msgsnd((long)(msqid), (long)(msgp), \\\n                                      (long)(msgsz), (long)(msgflg))\n#define __sanitizer_syscall_post_msgsnd(res, msqid, msgp, msgsz, msgflg) \\\n  __sanitizer_syscall_post_impl_msgsnd(res, (long)(msqid), (long)(msgp), \\\n                                       (long)(msgsz), (long)(msgflg))\n#define __sanitizer_syscall_pre_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg) \\\n  __sanitizer_syscall_pre_impl_msgrcv((long)(msqid), (long)(msgp),         \\\n                                      (long)(msgsz), (long)(msgtyp),       \\\n                                      (long)(msgflg))\n#define __sanitizer_syscall_post_msgrcv(res, msqid, msgp, msgsz, msgtyp, \\\n                                        msgflg)                          \\\n  __sanitizer_syscall_post_impl_msgrcv(res, (long)(msqid), (long)(msgp), \\\n                                       (long)(msgsz), (long)(msgtyp),    \\\n                                       (long)(msgflg))\n#define __sanitizer_syscall_pre_msgctl(msqid, cmd, buf) \\\n  __sanitizer_syscall_pre_impl_msgctl((long)(msqid), (long)(cmd), (long)(buf))\n#define __sanitizer_syscall_post_msgctl(res, msqid, cmd, buf)           \\\n  __sanitizer_syscall_post_impl_msgctl(res, (long)(msqid), (long)(cmd), \\\n                                       (long)(buf))\n#define __sanitizer_syscall_pre_semget(key, nsems, semflg)        \\\n  __sanitizer_syscall_pre_impl_semget((long)(key), (long)(nsems), \\\n                                      (long)(semflg))\n#define __sanitizer_syscall_post_semget(res, key, nsems, semflg)        \\\n  __sanitizer_syscall_post_impl_semget(res, (long)(key), (long)(nsems), \\\n                                       (long)(semflg))\n#define __sanitizer_syscall_pre_semop(semid, sops, nsops) \\\n  __sanitizer_syscall_pre_impl_semop((long)(semid), (long)(sops), (long)(nsops))\n#define __sanitizer_syscall_post_semop(res, semid, sops, nsops)         \\\n  __sanitizer_syscall_post_impl_semop(res, (long)(semid), (long)(sops), \\\n                                      (long)(nsops))\n#define __sanitizer_syscall_pre_semctl(semid, semnum, cmd, arg)      \\\n  __sanitizer_syscall_pre_impl_semctl((long)(semid), (long)(semnum), \\\n                                      (long)(cmd), (long)(arg))\n#define __sanitizer_syscall_post_semctl(res, semid, semnum, cmd, arg)      \\\n  __sanitizer_syscall_post_impl_semctl(res, (long)(semid), (long)(semnum), \\\n                                       (long)(cmd), (long)(arg))\n#define __sanitizer_syscall_pre_semtimedop(semid, sops, nsops, timeout) \\\n  __sanitizer_syscall_pre_impl_semtimedop((long)(semid), (long)(sops),  \\\n                                          (long)(nsops), (long)(timeout))\n#define __sanitizer_syscall_post_semtimedop(res, semid, sops, nsops, timeout) \\\n  __sanitizer_syscall_post_impl_semtimedop(res, (long)(semid), (long)(sops),  \\\n                                           (long)(nsops), (long)(timeout))\n#define __sanitizer_syscall_pre_shmat(shmid, shmaddr, shmflg)        \\\n  __sanitizer_syscall_pre_impl_shmat((long)(shmid), (long)(shmaddr), \\\n                                     (long)(shmflg))\n#define __sanitizer_syscall_post_shmat(res, shmid, shmaddr, shmflg)        \\\n  __sanitizer_syscall_post_impl_shmat(res, (long)(shmid), (long)(shmaddr), \\\n                                      (long)(shmflg))\n#define __sanitizer_syscall_pre_shmget(key, size, flag) \\\n  __sanitizer_syscall_pre_impl_shmget((long)(key), (long)(size), (long)(flag))\n#define __sanitizer_syscall_post_shmget(res, key, size, flag)          \\\n  __sanitizer_syscall_post_impl_shmget(res, (long)(key), (long)(size), \\\n                                       (long)(flag))\n#define __sanitizer_syscall_pre_shmdt(shmaddr) \\\n  __sanitizer_syscall_pre_impl_shmdt((long)(shmaddr))\n#define __sanitizer_syscall_post_shmdt(res, shmaddr) \\\n  __sanitizer_syscall_post_impl_shmdt(res, (long)(shmaddr))\n#define __sanitizer_syscall_pre_shmctl(shmid, cmd, buf) \\\n  __sanitizer_syscall_pre_impl_shmctl((long)(shmid), (long)(cmd), (long)(buf))\n#define __sanitizer_syscall_post_shmctl(res, shmid, cmd, buf)           \\\n  __sanitizer_syscall_post_impl_shmctl(res, (long)(shmid), (long)(cmd), \\\n                                       (long)(buf))\n#define __sanitizer_syscall_pre_ipc(call, first, second, third, ptr, fifth)    \\\n  __sanitizer_syscall_pre_impl_ipc((long)(call), (long)(first),                \\\n                                   (long)(second), (long)(third), (long)(ptr), \\\n                                   (long)(fifth))\n#define __sanitizer_syscall_post_ipc(res, call, first, second, third, ptr, \\\n                                     fifth)                                \\\n  __sanitizer_syscall_post_impl_ipc(res, (long)(call), (long)(first),      \\\n                                    (long)(second), (long)(third),         \\\n                                    (long)(ptr), (long)(fifth))\n#define __sanitizer_syscall_pre_mq_open(name, oflag, mode, attr)    \\\n  __sanitizer_syscall_pre_impl_mq_open((long)(name), (long)(oflag), \\\n                                       (long)(mode), (long)(attr))\n#define __sanitizer_syscall_post_mq_open(res, name, oflag, mode, attr)    \\\n  __sanitizer_syscall_post_impl_mq_open(res, (long)(name), (long)(oflag), \\\n                                        (long)(mode), (long)(attr))\n#define __sanitizer_syscall_pre_mq_unlink(name) \\\n  __sanitizer_syscall_pre_impl_mq_unlink((long)(name))\n#define __sanitizer_syscall_post_mq_unlink(res, name) \\\n  __sanitizer_syscall_post_impl_mq_unlink(res, (long)(name))\n#define __sanitizer_syscall_pre_mq_timedsend(mqdes, msg_ptr, msg_len,          \\\n                                             msg_prio, abs_timeout)            \\\n  __sanitizer_syscall_pre_impl_mq_timedsend((long)(mqdes), (long)(msg_ptr),    \\\n                                            (long)(msg_len), (long)(msg_prio), \\\n                                            (long)(abs_timeout))\n#define __sanitizer_syscall_post_mq_timedsend(res, mqdes, msg_ptr, msg_len,   \\\n                                              msg_prio, abs_timeout)          \\\n  __sanitizer_syscall_post_impl_mq_timedsend(                                 \\\n      res, (long)(mqdes), (long)(msg_ptr), (long)(msg_len), (long)(msg_prio), \\\n      (long)(abs_timeout))\n#define __sanitizer_syscall_pre_mq_timedreceive(mqdes, msg_ptr, msg_len, \\\n                                                msg_prio, abs_timeout)   \\\n  __sanitizer_syscall_pre_impl_mq_timedreceive(                          \\\n      (long)(mqdes), (long)(msg_ptr), (long)(msg_len), (long)(msg_prio), \\\n      (long)(abs_timeout))\n#define __sanitizer_syscall_post_mq_timedreceive(res, mqdes, msg_ptr, msg_len, \\\n                                                 msg_prio, abs_timeout)        \\\n  __sanitizer_syscall_post_impl_mq_timedreceive(                               \\\n      res, (long)(mqdes), (long)(msg_ptr), (long)(msg_len), (long)(msg_prio),  \\\n      (long)(abs_timeout))\n#define __sanitizer_syscall_pre_mq_notify(mqdes, notification) \\\n  __sanitizer_syscall_pre_impl_mq_notify((long)(mqdes), (long)(notification))\n#define __sanitizer_syscall_post_mq_notify(res, mqdes, notification) \\\n  __sanitizer_syscall_post_impl_mq_notify(res, (long)(mqdes),        \\\n                                          (long)(notification))\n#define __sanitizer_syscall_pre_mq_getsetattr(mqdes, mqstat, omqstat)       \\\n  __sanitizer_syscall_pre_impl_mq_getsetattr((long)(mqdes), (long)(mqstat), \\\n                                             (long)(omqstat))\n#define __sanitizer_syscall_post_mq_getsetattr(res, mqdes, mqstat, omqstat) \\\n  __sanitizer_syscall_post_impl_mq_getsetattr(res, (long)(mqdes),           \\\n                                              (long)(mqstat), (long)(omqstat))\n#define __sanitizer_syscall_pre_pciconfig_iobase(which, bus, devfn)         \\\n  __sanitizer_syscall_pre_impl_pciconfig_iobase((long)(which), (long)(bus), \\\n                                                (long)(devfn))\n#define __sanitizer_syscall_post_pciconfig_iobase(res, which, bus, devfn) \\\n  __sanitizer_syscall_post_impl_pciconfig_iobase(res, (long)(which),      \\\n                                                 (long)(bus), (long)(devfn))\n#define __sanitizer_syscall_pre_pciconfig_read(bus, dfn, off, len, buf) \\\n  __sanitizer_syscall_pre_impl_pciconfig_read(                          \\\n      (long)(bus), (long)(dfn), (long)(off), (long)(len), (long)(buf))\n#define __sanitizer_syscall_post_pciconfig_read(res, bus, dfn, off, len, buf) \\\n  __sanitizer_syscall_post_impl_pciconfig_read(                               \\\n      res, (long)(bus), (long)(dfn), (long)(off), (long)(len), (long)(buf))\n#define __sanitizer_syscall_pre_pciconfig_write(bus, dfn, off, len, buf) \\\n  __sanitizer_syscall_pre_impl_pciconfig_write(                          \\\n      (long)(bus), (long)(dfn), (long)(off), (long)(len), (long)(buf))\n#define __sanitizer_syscall_post_pciconfig_write(res, bus, dfn, off, len, buf) \\\n  __sanitizer_syscall_post_impl_pciconfig_write(                               \\\n      res, (long)(bus), (long)(dfn), (long)(off), (long)(len), (long)(buf))\n#define __sanitizer_syscall_pre_swapon(specialfile, swap_flags) \\\n  __sanitizer_syscall_pre_impl_swapon((long)(specialfile), (long)(swap_flags))\n#define __sanitizer_syscall_post_swapon(res, specialfile, swap_flags) \\\n  __sanitizer_syscall_post_impl_swapon(res, (long)(specialfile),      \\\n                                       (long)(swap_flags))\n#define __sanitizer_syscall_pre_swapoff(specialfile) \\\n  __sanitizer_syscall_pre_impl_swapoff((long)(specialfile))\n#define __sanitizer_syscall_post_swapoff(res, specialfile) \\\n  __sanitizer_syscall_post_impl_swapoff(res, (long)(specialfile))\n#define __sanitizer_syscall_pre_sysctl(args) \\\n  __sanitizer_syscall_pre_impl_sysctl((long)(args))\n#define __sanitizer_syscall_post_sysctl(res, args) \\\n  __sanitizer_syscall_post_impl_sysctl(res, (long)(args))\n#define __sanitizer_syscall_pre_sysinfo(info) \\\n  __sanitizer_syscall_pre_impl_sysinfo((long)(info))\n#define __sanitizer_syscall_post_sysinfo(res, info) \\\n  __sanitizer_syscall_post_impl_sysinfo(res, (long)(info))\n#define __sanitizer_syscall_pre_sysfs(option, arg1, arg2) \\\n  __sanitizer_syscall_pre_impl_sysfs((long)(option), (long)(arg1), (long)(arg2))\n#define __sanitizer_syscall_post_sysfs(res, option, arg1, arg2)          \\\n  __sanitizer_syscall_post_impl_sysfs(res, (long)(option), (long)(arg1), \\\n                                      (long)(arg2))\n#define __sanitizer_syscall_pre_syslog(type, buf, len) \\\n  __sanitizer_syscall_pre_impl_syslog((long)(type), (long)(buf), (long)(len))\n#define __sanitizer_syscall_post_syslog(res, type, buf, len)           \\\n  __sanitizer_syscall_post_impl_syslog(res, (long)(type), (long)(buf), \\\n                                       (long)(len))\n#define __sanitizer_syscall_pre_uselib(library) \\\n  __sanitizer_syscall_pre_impl_uselib((long)(library))\n#define __sanitizer_syscall_post_uselib(res, library) \\\n  __sanitizer_syscall_post_impl_uselib(res, (long)(library))\n#define __sanitizer_syscall_pre_ni_syscall() \\\n  __sanitizer_syscall_pre_impl_ni_syscall()\n#define __sanitizer_syscall_post_ni_syscall(res) \\\n  __sanitizer_syscall_post_impl_ni_syscall(res)\n#define __sanitizer_syscall_pre_ptrace(request, pid, addr, data)    \\\n  __sanitizer_syscall_pre_impl_ptrace((long)(request), (long)(pid), \\\n                                      (long)(addr), (long)(data))\n#define __sanitizer_syscall_post_ptrace(res, request, pid, addr, data)    \\\n  __sanitizer_syscall_post_impl_ptrace(res, (long)(request), (long)(pid), \\\n                                       (long)(addr), (long)(data))\n#define __sanitizer_syscall_pre_add_key(_type, _description, _payload, plen, \\\n                                        destringid)                          \\\n  __sanitizer_syscall_pre_impl_add_key((long)(_type), (long)(_description),  \\\n                                       (long)(_payload), (long)(plen),       \\\n                                       (long)(destringid))\n#define __sanitizer_syscall_post_add_key(res, _type, _description, _payload, \\\n                                         plen, destringid)                   \\\n  __sanitizer_syscall_post_impl_add_key(                                     \\\n      res, (long)(_type), (long)(_description), (long)(_payload),            \\\n      (long)(plen), (long)(destringid))\n#define __sanitizer_syscall_pre_request_key(_type, _description,       \\\n                                            _callout_info, destringid) \\\n  __sanitizer_syscall_pre_impl_request_key(                            \\\n      (long)(_type), (long)(_description), (long)(_callout_info),      \\\n      (long)(destringid))\n#define __sanitizer_syscall_post_request_key(res, _type, _description,  \\\n                                             _callout_info, destringid) \\\n  __sanitizer_syscall_post_impl_request_key(                            \\\n      res, (long)(_type), (long)(_description), (long)(_callout_info),  \\\n      (long)(destringid))\n#define __sanitizer_syscall_pre_keyctl(cmd, arg2, arg3, arg4, arg5)            \\\n  __sanitizer_syscall_pre_impl_keyctl((long)(cmd), (long)(arg2), (long)(arg3), \\\n                                      (long)(arg4), (long)(arg5))\n#define __sanitizer_syscall_post_keyctl(res, cmd, arg2, arg3, arg4, arg5) \\\n  __sanitizer_syscall_post_impl_keyctl(res, (long)(cmd), (long)(arg2),    \\\n                                       (long)(arg3), (long)(arg4),        \\\n                                       (long)(arg5))\n#define __sanitizer_syscall_pre_ioprio_set(which, who, ioprio)        \\\n  __sanitizer_syscall_pre_impl_ioprio_set((long)(which), (long)(who), \\\n                                          (long)(ioprio))\n#define __sanitizer_syscall_post_ioprio_set(res, which, who, ioprio)        \\\n  __sanitizer_syscall_post_impl_ioprio_set(res, (long)(which), (long)(who), \\\n                                           (long)(ioprio))\n#define __sanitizer_syscall_pre_ioprio_get(which, who) \\\n  __sanitizer_syscall_pre_impl_ioprio_get((long)(which), (long)(who))\n#define __sanitizer_syscall_post_ioprio_get(res, which, who) \\\n  __sanitizer_syscall_post_impl_ioprio_get(res, (long)(which), (long)(who))\n#define __sanitizer_syscall_pre_set_mempolicy(mode, nmask, maxnode)       \\\n  __sanitizer_syscall_pre_impl_set_mempolicy((long)(mode), (long)(nmask), \\\n                                             (long)(maxnode))\n#define __sanitizer_syscall_post_set_mempolicy(res, mode, nmask, maxnode) \\\n  __sanitizer_syscall_post_impl_set_mempolicy(res, (long)(mode),          \\\n                                              (long)(nmask), (long)(maxnode))\n#define __sanitizer_syscall_pre_migrate_pages(pid, maxnode, from, to)      \\\n  __sanitizer_syscall_pre_impl_migrate_pages((long)(pid), (long)(maxnode), \\\n                                             (long)(from), (long)(to))\n#define __sanitizer_syscall_post_migrate_pages(res, pid, maxnode, from, to) \\\n  __sanitizer_syscall_post_impl_migrate_pages(                              \\\n      res, (long)(pid), (long)(maxnode), (long)(from), (long)(to))\n#define __sanitizer_syscall_pre_move_pages(pid, nr_pages, pages, nodes,  \\\n                                           status, flags)                \\\n  __sanitizer_syscall_pre_impl_move_pages((long)(pid), (long)(nr_pages), \\\n                                          (long)(pages), (long)(nodes),  \\\n                                          (long)(status), (long)(flags))\n#define __sanitizer_syscall_post_move_pages(res, pid, nr_pages, pages, nodes,  \\\n                                            status, flags)                     \\\n  __sanitizer_syscall_post_impl_move_pages(res, (long)(pid), (long)(nr_pages), \\\n                                           (long)(pages), (long)(nodes),       \\\n                                           (long)(status), (long)(flags))\n#define __sanitizer_syscall_pre_mbind(start, len, mode, nmask, maxnode, flags) \\\n  __sanitizer_syscall_pre_impl_mbind((long)(start), (long)(len), (long)(mode), \\\n                                     (long)(nmask), (long)(maxnode),           \\\n                                     (long)(flags))\n#define __sanitizer_syscall_post_mbind(res, start, len, mode, nmask, maxnode, \\\n                                       flags)                                 \\\n  __sanitizer_syscall_post_impl_mbind(res, (long)(start), (long)(len),        \\\n                                      (long)(mode), (long)(nmask),            \\\n                                      (long)(maxnode), (long)(flags))\n#define __sanitizer_syscall_pre_get_mempolicy(policy, nmask, maxnode, addr, \\\n                                              flags)                        \\\n  __sanitizer_syscall_pre_impl_get_mempolicy((long)(policy), (long)(nmask), \\\n                                             (long)(maxnode), (long)(addr), \\\n                                             (long)(flags))\n#define __sanitizer_syscall_post_get_mempolicy(res, policy, nmask, maxnode,   \\\n                                               addr, flags)                   \\\n  __sanitizer_syscall_post_impl_get_mempolicy(res, (long)(policy),            \\\n                                              (long)(nmask), (long)(maxnode), \\\n                                              (long)(addr), (long)(flags))\n#define __sanitizer_syscall_pre_inotify_init() \\\n  __sanitizer_syscall_pre_impl_inotify_init()\n#define __sanitizer_syscall_post_inotify_init(res) \\\n  __sanitizer_syscall_post_impl_inotify_init(res)\n#define __sanitizer_syscall_pre_inotify_init1(flags) \\\n  __sanitizer_syscall_pre_impl_inotify_init1((long)(flags))\n#define __sanitizer_syscall_post_inotify_init1(res, flags) \\\n  __sanitizer_syscall_post_impl_inotify_init1(res, (long)(flags))\n#define __sanitizer_syscall_pre_inotify_add_watch(fd, path, mask)          \\\n  __sanitizer_syscall_pre_impl_inotify_add_watch((long)(fd), (long)(path), \\\n                                                 (long)(mask))\n#define __sanitizer_syscall_post_inotify_add_watch(res, fd, path, mask) \\\n  __sanitizer_syscall_post_impl_inotify_add_watch(res, (long)(fd),      \\\n                                                  (long)(path), (long)(mask))\n#define __sanitizer_syscall_pre_inotify_rm_watch(fd, wd) \\\n  __sanitizer_syscall_pre_impl_inotify_rm_watch((long)(fd), (long)(wd))\n#define __sanitizer_syscall_post_inotify_rm_watch(res, fd, wd) \\\n  __sanitizer_syscall_post_impl_inotify_rm_watch(res, (long)(fd), (long)(wd))\n#define __sanitizer_syscall_pre_spu_run(fd, unpc, ustatus)       \\\n  __sanitizer_syscall_pre_impl_spu_run((long)(fd), (long)(unpc), \\\n                                       (long)(ustatus))\n#define __sanitizer_syscall_post_spu_run(res, fd, unpc, ustatus)       \\\n  __sanitizer_syscall_post_impl_spu_run(res, (long)(fd), (long)(unpc), \\\n                                        (long)(ustatus))\n#define __sanitizer_syscall_pre_spu_create(name, flags, mode, fd)      \\\n  __sanitizer_syscall_pre_impl_spu_create((long)(name), (long)(flags), \\\n                                          (long)(mode), (long)(fd))\n#define __sanitizer_syscall_post_spu_create(res, name, flags, mode, fd)      \\\n  __sanitizer_syscall_post_impl_spu_create(res, (long)(name), (long)(flags), \\\n                                           (long)(mode), (long)(fd))\n#define __sanitizer_syscall_pre_mknodat(dfd, filename, mode, dev)     \\\n  __sanitizer_syscall_pre_impl_mknodat((long)(dfd), (long)(filename), \\\n                                       (long)(mode), (long)(dev))\n#define __sanitizer_syscall_post_mknodat(res, dfd, filename, mode, dev)     \\\n  __sanitizer_syscall_post_impl_mknodat(res, (long)(dfd), (long)(filename), \\\n                                        (long)(mode), (long)(dev))\n#define __sanitizer_syscall_pre_mkdirat(dfd, pathname, mode)          \\\n  __sanitizer_syscall_pre_impl_mkdirat((long)(dfd), (long)(pathname), \\\n                                       (long)(mode))\n#define __sanitizer_syscall_post_mkdirat(res, dfd, pathname, mode)          \\\n  __sanitizer_syscall_post_impl_mkdirat(res, (long)(dfd), (long)(pathname), \\\n                                        (long)(mode))\n#define __sanitizer_syscall_pre_unlinkat(dfd, pathname, flag)          \\\n  __sanitizer_syscall_pre_impl_unlinkat((long)(dfd), (long)(pathname), \\\n                                        (long)(flag))\n#define __sanitizer_syscall_post_unlinkat(res, dfd, pathname, flag)          \\\n  __sanitizer_syscall_post_impl_unlinkat(res, (long)(dfd), (long)(pathname), \\\n                                         (long)(flag))\n#define __sanitizer_syscall_pre_symlinkat(oldname, newdfd, newname)       \\\n  __sanitizer_syscall_pre_impl_symlinkat((long)(oldname), (long)(newdfd), \\\n                                         (long)(newname))\n#define __sanitizer_syscall_post_symlinkat(res, oldname, newdfd, newname) \\\n  __sanitizer_syscall_post_impl_symlinkat(res, (long)(oldname),           \\\n                                          (long)(newdfd), (long)(newname))\n#define __sanitizer_syscall_pre_linkat(olddfd, oldname, newdfd, newname, \\\n                                       flags)                            \\\n  __sanitizer_syscall_pre_impl_linkat((long)(olddfd), (long)(oldname),   \\\n                                      (long)(newdfd), (long)(newname),   \\\n                                      (long)(flags))\n#define __sanitizer_syscall_post_linkat(res, olddfd, oldname, newdfd, newname, \\\n                                        flags)                                 \\\n  __sanitizer_syscall_post_impl_linkat(res, (long)(olddfd), (long)(oldname),   \\\n                                       (long)(newdfd), (long)(newname),        \\\n                                       (long)(flags))\n#define __sanitizer_syscall_pre_renameat(olddfd, oldname, newdfd, newname) \\\n  __sanitizer_syscall_pre_impl_renameat((long)(olddfd), (long)(oldname),   \\\n                                        (long)(newdfd), (long)(newname))\n#define __sanitizer_syscall_post_renameat(res, olddfd, oldname, newdfd,        \\\n                                          newname)                             \\\n  __sanitizer_syscall_post_impl_renameat(res, (long)(olddfd), (long)(oldname), \\\n                                         (long)(newdfd), (long)(newname))\n#define __sanitizer_syscall_pre_futimesat(dfd, filename, utimes)        \\\n  __sanitizer_syscall_pre_impl_futimesat((long)(dfd), (long)(filename), \\\n                                         (long)(utimes))\n#define __sanitizer_syscall_post_futimesat(res, dfd, filename, utimes)        \\\n  __sanitizer_syscall_post_impl_futimesat(res, (long)(dfd), (long)(filename), \\\n                                          (long)(utimes))\n#define __sanitizer_syscall_pre_faccessat(dfd, filename, mode)          \\\n  __sanitizer_syscall_pre_impl_faccessat((long)(dfd), (long)(filename), \\\n                                         (long)(mode))\n#define __sanitizer_syscall_post_faccessat(res, dfd, filename, mode)          \\\n  __sanitizer_syscall_post_impl_faccessat(res, (long)(dfd), (long)(filename), \\\n                                          (long)(mode))\n#define __sanitizer_syscall_pre_fchmodat(dfd, filename, mode)          \\\n  __sanitizer_syscall_pre_impl_fchmodat((long)(dfd), (long)(filename), \\\n                                        (long)(mode))\n#define __sanitizer_syscall_post_fchmodat(res, dfd, filename, mode)          \\\n  __sanitizer_syscall_post_impl_fchmodat(res, (long)(dfd), (long)(filename), \\\n                                         (long)(mode))\n#define __sanitizer_syscall_pre_fchownat(dfd, filename, user, group, flag) \\\n  __sanitizer_syscall_pre_impl_fchownat((long)(dfd), (long)(filename),     \\\n                                        (long)(user), (long)(group),       \\\n                                        (long)(flag))\n#define __sanitizer_syscall_post_fchownat(res, dfd, filename, user, group,   \\\n                                          flag)                              \\\n  __sanitizer_syscall_post_impl_fchownat(res, (long)(dfd), (long)(filename), \\\n                                         (long)(user), (long)(group),        \\\n                                         (long)(flag))\n#define __sanitizer_syscall_pre_openat(dfd, filename, flags, mode)   \\\n  __sanitizer_syscall_pre_impl_openat((long)(dfd), (long)(filename), \\\n                                      (long)(flags), (long)(mode))\n#define __sanitizer_syscall_post_openat(res, dfd, filename, flags, mode)   \\\n  __sanitizer_syscall_post_impl_openat(res, (long)(dfd), (long)(filename), \\\n                                       (long)(flags), (long)(mode))\n#define __sanitizer_syscall_pre_newfstatat(dfd, filename, statbuf, flag) \\\n  __sanitizer_syscall_pre_impl_newfstatat((long)(dfd), (long)(filename), \\\n                                          (long)(statbuf), (long)(flag))\n#define __sanitizer_syscall_post_newfstatat(res, dfd, filename, statbuf, flag) \\\n  __sanitizer_syscall_post_impl_newfstatat(res, (long)(dfd), (long)(filename), \\\n                                           (long)(statbuf), (long)(flag))\n#define __sanitizer_syscall_pre_fstatat64(dfd, filename, statbuf, flag) \\\n  __sanitizer_syscall_pre_impl_fstatat64((long)(dfd), (long)(filename), \\\n                                         (long)(statbuf), (long)(flag))\n#define __sanitizer_syscall_post_fstatat64(res, dfd, filename, statbuf, flag) \\\n  __sanitizer_syscall_post_impl_fstatat64(res, (long)(dfd), (long)(filename), \\\n                                          (long)(statbuf), (long)(flag))\n#define __sanitizer_syscall_pre_readlinkat(dfd, path, buf, bufsiz)   \\\n  __sanitizer_syscall_pre_impl_readlinkat((long)(dfd), (long)(path), \\\n                                          (long)(buf), (long)(bufsiz))\n#define __sanitizer_syscall_post_readlinkat(res, dfd, path, buf, bufsiz)   \\\n  __sanitizer_syscall_post_impl_readlinkat(res, (long)(dfd), (long)(path), \\\n                                           (long)(buf), (long)(bufsiz))\n#define __sanitizer_syscall_pre_utimensat(dfd, filename, utimes, flags) \\\n  __sanitizer_syscall_pre_impl_utimensat((long)(dfd), (long)(filename), \\\n                                         (long)(utimes), (long)(flags))\n#define __sanitizer_syscall_post_utimensat(res, dfd, filename, utimes, flags) \\\n  __sanitizer_syscall_post_impl_utimensat(res, (long)(dfd), (long)(filename), \\\n                                          (long)(utimes), (long)(flags))\n#define __sanitizer_syscall_pre_unshare(unshare_flags) \\\n  __sanitizer_syscall_pre_impl_unshare((long)(unshare_flags))\n#define __sanitizer_syscall_post_unshare(res, unshare_flags) \\\n  __sanitizer_syscall_post_impl_unshare(res, (long)(unshare_flags))\n#define __sanitizer_syscall_pre_splice(fd_in, off_in, fd_out, off_out, len, \\\n                                       flags)                               \\\n  __sanitizer_syscall_pre_impl_splice((long)(fd_in), (long)(off_in),        \\\n                                      (long)(fd_out), (long)(off_out),      \\\n                                      (long)(len), (long)(flags))\n#define __sanitizer_syscall_post_splice(res, fd_in, off_in, fd_out, off_out, \\\n                                        len, flags)                          \\\n  __sanitizer_syscall_post_impl_splice(res, (long)(fd_in), (long)(off_in),   \\\n                                       (long)(fd_out), (long)(off_out),      \\\n                                       (long)(len), (long)(flags))\n#define __sanitizer_syscall_pre_vmsplice(fd, iov, nr_segs, flags) \\\n  __sanitizer_syscall_pre_impl_vmsplice((long)(fd), (long)(iov),  \\\n                                        (long)(nr_segs), (long)(flags))\n#define __sanitizer_syscall_post_vmsplice(res, fd, iov, nr_segs, flags) \\\n  __sanitizer_syscall_post_impl_vmsplice(res, (long)(fd), (long)(iov),  \\\n                                         (long)(nr_segs), (long)(flags))\n#define __sanitizer_syscall_pre_tee(fdin, fdout, len, flags)                 \\\n  __sanitizer_syscall_pre_impl_tee((long)(fdin), (long)(fdout), (long)(len), \\\n                                   (long)(flags))\n#define __sanitizer_syscall_post_tee(res, fdin, fdout, len, flags)    \\\n  __sanitizer_syscall_post_impl_tee(res, (long)(fdin), (long)(fdout), \\\n                                    (long)(len), (long)(flags))\n#define __sanitizer_syscall_pre_get_robust_list(pid, head_ptr, len_ptr)       \\\n  __sanitizer_syscall_pre_impl_get_robust_list((long)(pid), (long)(head_ptr), \\\n                                               (long)(len_ptr))\n#define __sanitizer_syscall_post_get_robust_list(res, pid, head_ptr, len_ptr) \\\n  __sanitizer_syscall_post_impl_get_robust_list(                              \\\n      res, (long)(pid), (long)(head_ptr), (long)(len_ptr))\n#define __sanitizer_syscall_pre_set_robust_list(head, len) \\\n  __sanitizer_syscall_pre_impl_set_robust_list((long)(head), (long)(len))\n#define __sanitizer_syscall_post_set_robust_list(res, head, len) \\\n  __sanitizer_syscall_post_impl_set_robust_list(res, (long)(head), (long)(len))\n#define __sanitizer_syscall_pre_getcpu(cpu, node, cache) \\\n  __sanitizer_syscall_pre_impl_getcpu((long)(cpu), (long)(node), (long)(cache))\n#define __sanitizer_syscall_post_getcpu(res, cpu, node, cache)         \\\n  __sanitizer_syscall_post_impl_getcpu(res, (long)(cpu), (long)(node), \\\n                                       (long)(cache))\n#define __sanitizer_syscall_pre_signalfd(ufd, user_mask, sizemask)      \\\n  __sanitizer_syscall_pre_impl_signalfd((long)(ufd), (long)(user_mask), \\\n                                        (long)(sizemask))\n#define __sanitizer_syscall_post_signalfd(res, ufd, user_mask, sizemask)      \\\n  __sanitizer_syscall_post_impl_signalfd(res, (long)(ufd), (long)(user_mask), \\\n                                         (long)(sizemask))\n#define __sanitizer_syscall_pre_signalfd4(ufd, user_mask, sizemask, flags) \\\n  __sanitizer_syscall_pre_impl_signalfd4((long)(ufd), (long)(user_mask),   \\\n                                         (long)(sizemask), (long)(flags))\n#define __sanitizer_syscall_post_signalfd4(res, ufd, user_mask, sizemask,      \\\n                                           flags)                              \\\n  __sanitizer_syscall_post_impl_signalfd4(res, (long)(ufd), (long)(user_mask), \\\n                                          (long)(sizemask), (long)(flags))\n#define __sanitizer_syscall_pre_timerfd_create(clockid, flags) \\\n  __sanitizer_syscall_pre_impl_timerfd_create((long)(clockid), (long)(flags))\n#define __sanitizer_syscall_post_timerfd_create(res, clockid, flags) \\\n  __sanitizer_syscall_post_impl_timerfd_create(res, (long)(clockid), \\\n                                               (long)(flags))\n#define __sanitizer_syscall_pre_timerfd_settime(ufd, flags, utmr, otmr)    \\\n  __sanitizer_syscall_pre_impl_timerfd_settime((long)(ufd), (long)(flags), \\\n                                               (long)(utmr), (long)(otmr))\n#define __sanitizer_syscall_post_timerfd_settime(res, ufd, flags, utmr, otmr) \\\n  __sanitizer_syscall_post_impl_timerfd_settime(                              \\\n      res, (long)(ufd), (long)(flags), (long)(utmr), (long)(otmr))\n#define __sanitizer_syscall_pre_timerfd_gettime(ufd, otmr) \\\n  __sanitizer_syscall_pre_impl_timerfd_gettime((long)(ufd), (long)(otmr))\n#define __sanitizer_syscall_post_timerfd_gettime(res, ufd, otmr) \\\n  __sanitizer_syscall_post_impl_timerfd_gettime(res, (long)(ufd), (long)(otmr))\n#define __sanitizer_syscall_pre_eventfd(count) \\\n  __sanitizer_syscall_pre_impl_eventfd((long)(count))\n#define __sanitizer_syscall_post_eventfd(res, count) \\\n  __sanitizer_syscall_post_impl_eventfd(res, (long)(count))\n#define __sanitizer_syscall_pre_eventfd2(count, flags) \\\n  __sanitizer_syscall_pre_impl_eventfd2((long)(count), (long)(flags))\n#define __sanitizer_syscall_post_eventfd2(res, count, flags) \\\n  __sanitizer_syscall_post_impl_eventfd2(res, (long)(count), (long)(flags))\n#define __sanitizer_syscall_pre_old_readdir(arg0, arg1, arg2)          \\\n  __sanitizer_syscall_pre_impl_old_readdir((long)(arg0), (long)(arg1), \\\n                                           (long)(arg2))\n#define __sanitizer_syscall_post_old_readdir(res, arg0, arg1, arg2)          \\\n  __sanitizer_syscall_post_impl_old_readdir(res, (long)(arg0), (long)(arg1), \\\n                                            (long)(arg2))\n#define __sanitizer_syscall_pre_pselect6(arg0, arg1, arg2, arg3, arg4, arg5) \\\n  __sanitizer_syscall_pre_impl_pselect6((long)(arg0), (long)(arg1),          \\\n                                        (long)(arg2), (long)(arg3),          \\\n                                        (long)(arg4), (long)(arg5))\n#define __sanitizer_syscall_post_pselect6(res, arg0, arg1, arg2, arg3, arg4, \\\n                                          arg5)                              \\\n  __sanitizer_syscall_post_impl_pselect6(res, (long)(arg0), (long)(arg1),    \\\n                                         (long)(arg2), (long)(arg3),         \\\n                                         (long)(arg4), (long)(arg5))\n#define __sanitizer_syscall_pre_ppoll(arg0, arg1, arg2, arg3, arg4)            \\\n  __sanitizer_syscall_pre_impl_ppoll((long)(arg0), (long)(arg1), (long)(arg2), \\\n                                     (long)(arg3), (long)(arg4))\n#define __sanitizer_syscall_post_ppoll(res, arg0, arg1, arg2, arg3, arg4) \\\n  __sanitizer_syscall_post_impl_ppoll(res, (long)(arg0), (long)(arg1),    \\\n                                      (long)(arg2), (long)(arg3),         \\\n                                      (long)(arg4))\n#define __sanitizer_syscall_pre_syncfs(fd) \\\n  __sanitizer_syscall_pre_impl_syncfs((long)(fd))\n#define __sanitizer_syscall_post_syncfs(res, fd) \\\n  __sanitizer_syscall_post_impl_syncfs(res, (long)(fd))\n#define __sanitizer_syscall_pre_perf_event_open(attr_uptr, pid, cpu, group_fd, \\\n                                                flags)                         \\\n  __sanitizer_syscall_pre_impl_perf_event_open((long)(attr_uptr), (long)(pid), \\\n                                               (long)(cpu), (long)(group_fd),  \\\n                                               (long)(flags))\n#define __sanitizer_syscall_post_perf_event_open(res, attr_uptr, pid, cpu, \\\n                                                 group_fd, flags)          \\\n  __sanitizer_syscall_post_impl_perf_event_open(                           \\\n      res, (long)(attr_uptr), (long)(pid), (long)(cpu), (long)(group_fd),  \\\n      (long)(flags))\n#define __sanitizer_syscall_pre_mmap_pgoff(addr, len, prot, flags, fd, pgoff) \\\n  __sanitizer_syscall_pre_impl_mmap_pgoff((long)(addr), (long)(len),          \\\n                                          (long)(prot), (long)(flags),        \\\n                                          (long)(fd), (long)(pgoff))\n#define __sanitizer_syscall_post_mmap_pgoff(res, addr, len, prot, flags, fd, \\\n                                            pgoff)                           \\\n  __sanitizer_syscall_post_impl_mmap_pgoff(res, (long)(addr), (long)(len),   \\\n                                           (long)(prot), (long)(flags),      \\\n                                           (long)(fd), (long)(pgoff))\n#define __sanitizer_syscall_pre_old_mmap(arg) \\\n  __sanitizer_syscall_pre_impl_old_mmap((long)(arg))\n#define __sanitizer_syscall_post_old_mmap(res, arg) \\\n  __sanitizer_syscall_post_impl_old_mmap(res, (long)(arg))\n#define __sanitizer_syscall_pre_name_to_handle_at(dfd, name, handle, mnt_id, \\\n                                                  flag)                      \\\n  __sanitizer_syscall_pre_impl_name_to_handle_at(                            \\\n      (long)(dfd), (long)(name), (long)(handle), (long)(mnt_id), (long)(flag))\n#define __sanitizer_syscall_post_name_to_handle_at(res, dfd, name, handle, \\\n                                                   mnt_id, flag)           \\\n  __sanitizer_syscall_post_impl_name_to_handle_at(                         \\\n      res, (long)(dfd), (long)(name), (long)(handle), (long)(mnt_id),      \\\n      (long)(flag))\n#define __sanitizer_syscall_pre_open_by_handle_at(mountdirfd, handle, flags) \\\n  __sanitizer_syscall_pre_impl_open_by_handle_at(                            \\\n      (long)(mountdirfd), (long)(handle), (long)(flags))\n#define __sanitizer_syscall_post_open_by_handle_at(res, mountdirfd, handle, \\\n                                                   flags)                   \\\n  __sanitizer_syscall_post_impl_open_by_handle_at(                          \\\n      res, (long)(mountdirfd), (long)(handle), (long)(flags))\n#define __sanitizer_syscall_pre_setns(fd, nstype) \\\n  __sanitizer_syscall_pre_impl_setns((long)(fd), (long)(nstype))\n#define __sanitizer_syscall_post_setns(res, fd, nstype) \\\n  __sanitizer_syscall_post_impl_setns(res, (long)(fd), (long)(nstype))\n#define __sanitizer_syscall_pre_process_vm_readv(pid, lvec, liovcnt, rvec, \\\n                                                 riovcnt, flags)           \\\n  __sanitizer_syscall_pre_impl_process_vm_readv(                           \\\n      (long)(pid), (long)(lvec), (long)(liovcnt), (long)(rvec),            \\\n      (long)(riovcnt), (long)(flags))\n#define __sanitizer_syscall_post_process_vm_readv(res, pid, lvec, liovcnt, \\\n                                                  rvec, riovcnt, flags)    \\\n  __sanitizer_syscall_post_impl_process_vm_readv(                          \\\n      res, (long)(pid), (long)(lvec), (long)(liovcnt), (long)(rvec),       \\\n      (long)(riovcnt), (long)(flags))\n#define __sanitizer_syscall_pre_process_vm_writev(pid, lvec, liovcnt, rvec, \\\n                                                  riovcnt, flags)           \\\n  __sanitizer_syscall_pre_impl_process_vm_writev(                           \\\n      (long)(pid), (long)(lvec), (long)(liovcnt), (long)(rvec),             \\\n      (long)(riovcnt), (long)(flags))\n#define __sanitizer_syscall_post_process_vm_writev(res, pid, lvec, liovcnt, \\\n                                                   rvec, riovcnt, flags)    \\\n  __sanitizer_syscall_post_impl_process_vm_writev(                          \\\n      res, (long)(pid), (long)(lvec), (long)(liovcnt), (long)(rvec),        \\\n      (long)(riovcnt), (long)(flags))\n#define __sanitizer_syscall_pre_fork() \\\n  __sanitizer_syscall_pre_impl_fork()\n#define __sanitizer_syscall_post_fork(res) \\\n  __sanitizer_syscall_post_impl_fork(res)\n#define __sanitizer_syscall_pre_vfork() \\\n  __sanitizer_syscall_pre_impl_vfork()\n#define __sanitizer_syscall_post_vfork(res) \\\n  __sanitizer_syscall_post_impl_vfork(res)\n\n// And now a few syscalls we don't handle yet.\n#define __sanitizer_syscall_pre_afs_syscall(...)\n#define __sanitizer_syscall_pre_arch_prctl(...)\n#define __sanitizer_syscall_pre_break(...)\n#define __sanitizer_syscall_pre_chown32(...)\n#define __sanitizer_syscall_pre_clone(...)\n#define __sanitizer_syscall_pre_create_module(...)\n#define __sanitizer_syscall_pre_epoll_ctl_old(...)\n#define __sanitizer_syscall_pre_epoll_wait_old(...)\n#define __sanitizer_syscall_pre_execve(...)\n#define __sanitizer_syscall_pre_fadvise64(...)\n#define __sanitizer_syscall_pre_fadvise64_64(...)\n#define __sanitizer_syscall_pre_fallocate(...)\n#define __sanitizer_syscall_pre_fanotify_init(...)\n#define __sanitizer_syscall_pre_fanotify_mark(...)\n#define __sanitizer_syscall_pre_fchown32(...)\n#define __sanitizer_syscall_pre_ftime(...)\n#define __sanitizer_syscall_pre_ftruncate64(...)\n#define __sanitizer_syscall_pre_futex(...)\n#define __sanitizer_syscall_pre_getegid32(...)\n#define __sanitizer_syscall_pre_geteuid32(...)\n#define __sanitizer_syscall_pre_getgid32(...)\n#define __sanitizer_syscall_pre_getgroups32(...)\n#define __sanitizer_syscall_pre_get_kernel_syms(...)\n#define __sanitizer_syscall_pre_getpmsg(...)\n#define __sanitizer_syscall_pre_getresgid32(...)\n#define __sanitizer_syscall_pre_getresuid32(...)\n#define __sanitizer_syscall_pre_get_thread_area(...)\n#define __sanitizer_syscall_pre_getuid32(...)\n#define __sanitizer_syscall_pre_gtty(...)\n#define __sanitizer_syscall_pre_idle(...)\n#define __sanitizer_syscall_pre_iopl(...)\n#define __sanitizer_syscall_pre_lchown32(...)\n#define __sanitizer_syscall_pre__llseek(...)\n#define __sanitizer_syscall_pre_lock(...)\n#define __sanitizer_syscall_pre_madvise1(...)\n#define __sanitizer_syscall_pre_mmap(...)\n#define __sanitizer_syscall_pre_mmap2(...)\n#define __sanitizer_syscall_pre_modify_ldt(...)\n#define __sanitizer_syscall_pre_mpx(...)\n#define __sanitizer_syscall_pre__newselect(...)\n#define __sanitizer_syscall_pre_nfsservctl(...)\n#define __sanitizer_syscall_pre_oldfstat(...)\n#define __sanitizer_syscall_pre_oldlstat(...)\n#define __sanitizer_syscall_pre_oldolduname(...)\n#define __sanitizer_syscall_pre_oldstat(...)\n#define __sanitizer_syscall_pre_prctl(...)\n#define __sanitizer_syscall_pre_prof(...)\n#define __sanitizer_syscall_pre_profil(...)\n#define __sanitizer_syscall_pre_putpmsg(...)\n#define __sanitizer_syscall_pre_query_module(...)\n#define __sanitizer_syscall_pre_readahead(...)\n#define __sanitizer_syscall_pre_readdir(...)\n#define __sanitizer_syscall_pre_rt_sigaction(...)\n#define __sanitizer_syscall_pre_rt_sigreturn(...)\n#define __sanitizer_syscall_pre_rt_sigsuspend(...)\n#define __sanitizer_syscall_pre_security(...)\n#define __sanitizer_syscall_pre_setfsgid32(...)\n#define __sanitizer_syscall_pre_setfsuid32(...)\n#define __sanitizer_syscall_pre_setgid32(...)\n#define __sanitizer_syscall_pre_setgroups32(...)\n#define __sanitizer_syscall_pre_setregid32(...)\n#define __sanitizer_syscall_pre_setresgid32(...)\n#define __sanitizer_syscall_pre_setresuid32(...)\n#define __sanitizer_syscall_pre_setreuid32(...)\n#define __sanitizer_syscall_pre_set_thread_area(...)\n#define __sanitizer_syscall_pre_setuid32(...)\n#define __sanitizer_syscall_pre_sigaction(...)\n#define __sanitizer_syscall_pre_sigaltstack(...)\n#define __sanitizer_syscall_pre_sigreturn(...)\n#define __sanitizer_syscall_pre_sigsuspend(...)\n#define __sanitizer_syscall_pre_stty(...)\n#define __sanitizer_syscall_pre_sync_file_range(...)\n#define __sanitizer_syscall_pre__sysctl(...)\n#define __sanitizer_syscall_pre_truncate64(...)\n#define __sanitizer_syscall_pre_tuxcall(...)\n#define __sanitizer_syscall_pre_ugetrlimit(...)\n#define __sanitizer_syscall_pre_ulimit(...)\n#define __sanitizer_syscall_pre_umount2(...)\n#define __sanitizer_syscall_pre_vm86(...)\n#define __sanitizer_syscall_pre_vm86old(...)\n#define __sanitizer_syscall_pre_vserver(...)\n\n#define __sanitizer_syscall_post_afs_syscall(res, ...)\n#define __sanitizer_syscall_post_arch_prctl(res, ...)\n#define __sanitizer_syscall_post_break(res, ...)\n#define __sanitizer_syscall_post_chown32(res, ...)\n#define __sanitizer_syscall_post_clone(res, ...)\n#define __sanitizer_syscall_post_create_module(res, ...)\n#define __sanitizer_syscall_post_epoll_ctl_old(res, ...)\n#define __sanitizer_syscall_post_epoll_wait_old(res, ...)\n#define __sanitizer_syscall_post_execve(res, ...)\n#define __sanitizer_syscall_post_fadvise64(res, ...)\n#define __sanitizer_syscall_post_fadvise64_64(res, ...)\n#define __sanitizer_syscall_post_fallocate(res, ...)\n#define __sanitizer_syscall_post_fanotify_init(res, ...)\n#define __sanitizer_syscall_post_fanotify_mark(res, ...)\n#define __sanitizer_syscall_post_fchown32(res, ...)\n#define __sanitizer_syscall_post_ftime(res, ...)\n#define __sanitizer_syscall_post_ftruncate64(res, ...)\n#define __sanitizer_syscall_post_futex(res, ...)\n#define __sanitizer_syscall_post_getegid32(res, ...)\n#define __sanitizer_syscall_post_geteuid32(res, ...)\n#define __sanitizer_syscall_post_getgid32(res, ...)\n#define __sanitizer_syscall_post_getgroups32(res, ...)\n#define __sanitizer_syscall_post_get_kernel_syms(res, ...)\n#define __sanitizer_syscall_post_getpmsg(res, ...)\n#define __sanitizer_syscall_post_getresgid32(res, ...)\n#define __sanitizer_syscall_post_getresuid32(res, ...)\n#define __sanitizer_syscall_post_get_thread_area(res, ...)\n#define __sanitizer_syscall_post_getuid32(res, ...)\n#define __sanitizer_syscall_post_gtty(res, ...)\n#define __sanitizer_syscall_post_idle(res, ...)\n#define __sanitizer_syscall_post_iopl(res, ...)\n#define __sanitizer_syscall_post_lchown32(res, ...)\n#define __sanitizer_syscall_post__llseek(res, ...)\n#define __sanitizer_syscall_post_lock(res, ...)\n#define __sanitizer_syscall_post_madvise1(res, ...)\n#define __sanitizer_syscall_post_mmap2(res, ...)\n#define __sanitizer_syscall_post_mmap(res, ...)\n#define __sanitizer_syscall_post_modify_ldt(res, ...)\n#define __sanitizer_syscall_post_mpx(res, ...)\n#define __sanitizer_syscall_post__newselect(res, ...)\n#define __sanitizer_syscall_post_nfsservctl(res, ...)\n#define __sanitizer_syscall_post_oldfstat(res, ...)\n#define __sanitizer_syscall_post_oldlstat(res, ...)\n#define __sanitizer_syscall_post_oldolduname(res, ...)\n#define __sanitizer_syscall_post_oldstat(res, ...)\n#define __sanitizer_syscall_post_prctl(res, ...)\n#define __sanitizer_syscall_post_profil(res, ...)\n#define __sanitizer_syscall_post_prof(res, ...)\n#define __sanitizer_syscall_post_putpmsg(res, ...)\n#define __sanitizer_syscall_post_query_module(res, ...)\n#define __sanitizer_syscall_post_readahead(res, ...)\n#define __sanitizer_syscall_post_readdir(res, ...)\n#define __sanitizer_syscall_post_rt_sigaction(res, ...)\n#define __sanitizer_syscall_post_rt_sigreturn(res, ...)\n#define __sanitizer_syscall_post_rt_sigsuspend(res, ...)\n#define __sanitizer_syscall_post_security(res, ...)\n#define __sanitizer_syscall_post_setfsgid32(res, ...)\n#define __sanitizer_syscall_post_setfsuid32(res, ...)\n#define __sanitizer_syscall_post_setgid32(res, ...)\n#define __sanitizer_syscall_post_setgroups32(res, ...)\n#define __sanitizer_syscall_post_setregid32(res, ...)\n#define __sanitizer_syscall_post_setresgid32(res, ...)\n#define __sanitizer_syscall_post_setresuid32(res, ...)\n#define __sanitizer_syscall_post_setreuid32(res, ...)\n#define __sanitizer_syscall_post_set_thread_area(res, ...)\n#define __sanitizer_syscall_post_setuid32(res, ...)\n#define __sanitizer_syscall_post_sigaction(res, ...)\n#define __sanitizer_syscall_post_sigaltstack(res, ...)\n#define __sanitizer_syscall_post_sigreturn(res, ...)\n#define __sanitizer_syscall_post_sigsuspend(res, ...)\n#define __sanitizer_syscall_post_stty(res, ...)\n#define __sanitizer_syscall_post_sync_file_range(res, ...)\n#define __sanitizer_syscall_post__sysctl(res, ...)\n#define __sanitizer_syscall_post_truncate64(res, ...)\n#define __sanitizer_syscall_post_tuxcall(res, ...)\n#define __sanitizer_syscall_post_ugetrlimit(res, ...)\n#define __sanitizer_syscall_post_ulimit(res, ...)\n#define __sanitizer_syscall_post_umount2(res, ...)\n#define __sanitizer_syscall_post_vm86old(res, ...)\n#define __sanitizer_syscall_post_vm86(res, ...)\n#define __sanitizer_syscall_post_vserver(res, ...)\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// Private declarations. Do not call directly from user code. Use macros above.\nvoid __sanitizer_syscall_pre_impl_time(long tloc);\nvoid __sanitizer_syscall_post_impl_time(long res, long tloc);\nvoid __sanitizer_syscall_pre_impl_stime(long tptr);\nvoid __sanitizer_syscall_post_impl_stime(long res, long tptr);\nvoid __sanitizer_syscall_pre_impl_gettimeofday(long tv, long tz);\nvoid __sanitizer_syscall_post_impl_gettimeofday(long res, long tv, long tz);\nvoid __sanitizer_syscall_pre_impl_settimeofday(long tv, long tz);\nvoid __sanitizer_syscall_post_impl_settimeofday(long res, long tv, long tz);\nvoid __sanitizer_syscall_pre_impl_adjtimex(long txc_p);\nvoid __sanitizer_syscall_post_impl_adjtimex(long res, long txc_p);\nvoid __sanitizer_syscall_pre_impl_times(long tbuf);\nvoid __sanitizer_syscall_post_impl_times(long res, long tbuf);\nvoid __sanitizer_syscall_pre_impl_gettid();\nvoid __sanitizer_syscall_post_impl_gettid(long res);\nvoid __sanitizer_syscall_pre_impl_nanosleep(long rqtp, long rmtp);\nvoid __sanitizer_syscall_post_impl_nanosleep(long res, long rqtp, long rmtp);\nvoid __sanitizer_syscall_pre_impl_alarm(long seconds);\nvoid __sanitizer_syscall_post_impl_alarm(long res, long seconds);\nvoid __sanitizer_syscall_pre_impl_getpid();\nvoid __sanitizer_syscall_post_impl_getpid(long res);\nvoid __sanitizer_syscall_pre_impl_getppid();\nvoid __sanitizer_syscall_post_impl_getppid(long res);\nvoid __sanitizer_syscall_pre_impl_getuid();\nvoid __sanitizer_syscall_post_impl_getuid(long res);\nvoid __sanitizer_syscall_pre_impl_geteuid();\nvoid __sanitizer_syscall_post_impl_geteuid(long res);\nvoid __sanitizer_syscall_pre_impl_getgid();\nvoid __sanitizer_syscall_post_impl_getgid(long res);\nvoid __sanitizer_syscall_pre_impl_getegid();\nvoid __sanitizer_syscall_post_impl_getegid(long res);\nvoid __sanitizer_syscall_pre_impl_getresuid(long ruid, long euid, long suid);\nvoid __sanitizer_syscall_post_impl_getresuid(long res, long ruid, long euid,\n                                             long suid);\nvoid __sanitizer_syscall_pre_impl_getresgid(long rgid, long egid, long sgid);\nvoid __sanitizer_syscall_post_impl_getresgid(long res, long rgid, long egid,\n                                             long sgid);\nvoid __sanitizer_syscall_pre_impl_getpgid(long pid);\nvoid __sanitizer_syscall_post_impl_getpgid(long res, long pid);\nvoid __sanitizer_syscall_pre_impl_getpgrp();\nvoid __sanitizer_syscall_post_impl_getpgrp(long res);\nvoid __sanitizer_syscall_pre_impl_getsid(long pid);\nvoid __sanitizer_syscall_post_impl_getsid(long res, long pid);\nvoid __sanitizer_syscall_pre_impl_getgroups(long gidsetsize, long grouplist);\nvoid __sanitizer_syscall_post_impl_getgroups(long res, long gidsetsize,\n                                             long grouplist);\nvoid __sanitizer_syscall_pre_impl_setregid(long rgid, long egid);\nvoid __sanitizer_syscall_post_impl_setregid(long res, long rgid, long egid);\nvoid __sanitizer_syscall_pre_impl_setgid(long gid);\nvoid __sanitizer_syscall_post_impl_setgid(long res, long gid);\nvoid __sanitizer_syscall_pre_impl_setreuid(long ruid, long euid);\nvoid __sanitizer_syscall_post_impl_setreuid(long res, long ruid, long euid);\nvoid __sanitizer_syscall_pre_impl_setuid(long uid);\nvoid __sanitizer_syscall_post_impl_setuid(long res, long uid);\nvoid __sanitizer_syscall_pre_impl_setresuid(long ruid, long euid, long suid);\nvoid __sanitizer_syscall_post_impl_setresuid(long res, long ruid, long euid,\n                                             long suid);\nvoid __sanitizer_syscall_pre_impl_setresgid(long rgid, long egid, long sgid);\nvoid __sanitizer_syscall_post_impl_setresgid(long res, long rgid, long egid,\n                                             long sgid);\nvoid __sanitizer_syscall_pre_impl_setfsuid(long uid);\nvoid __sanitizer_syscall_post_impl_setfsuid(long res, long uid);\nvoid __sanitizer_syscall_pre_impl_setfsgid(long gid);\nvoid __sanitizer_syscall_post_impl_setfsgid(long res, long gid);\nvoid __sanitizer_syscall_pre_impl_setpgid(long pid, long pgid);\nvoid __sanitizer_syscall_post_impl_setpgid(long res, long pid, long pgid);\nvoid __sanitizer_syscall_pre_impl_setsid();\nvoid __sanitizer_syscall_post_impl_setsid(long res);\nvoid __sanitizer_syscall_pre_impl_setgroups(long gidsetsize, long grouplist);\nvoid __sanitizer_syscall_post_impl_setgroups(long res, long gidsetsize,\n                                             long grouplist);\nvoid __sanitizer_syscall_pre_impl_acct(long name);\nvoid __sanitizer_syscall_post_impl_acct(long res, long name);\nvoid __sanitizer_syscall_pre_impl_capget(long header, long dataptr);\nvoid __sanitizer_syscall_post_impl_capget(long res, long header, long dataptr);\nvoid __sanitizer_syscall_pre_impl_capset(long header, long data);\nvoid __sanitizer_syscall_post_impl_capset(long res, long header, long data);\nvoid __sanitizer_syscall_pre_impl_personality(long personality);\nvoid __sanitizer_syscall_post_impl_personality(long res, long personality);\nvoid __sanitizer_syscall_pre_impl_sigpending(long set);\nvoid __sanitizer_syscall_post_impl_sigpending(long res, long set);\nvoid __sanitizer_syscall_pre_impl_sigprocmask(long how, long set, long oset);\nvoid __sanitizer_syscall_post_impl_sigprocmask(long res, long how, long set,\n                                               long oset);\nvoid __sanitizer_syscall_pre_impl_getitimer(long which, long value);\nvoid __sanitizer_syscall_post_impl_getitimer(long res, long which, long value);\nvoid __sanitizer_syscall_pre_impl_setitimer(long which, long value,\n                                            long ovalue);\nvoid __sanitizer_syscall_post_impl_setitimer(long res, long which, long value,\n                                             long ovalue);\nvoid __sanitizer_syscall_pre_impl_timer_create(long which_clock,\n                                               long timer_event_spec,\n                                               long created_timer_id);\nvoid __sanitizer_syscall_post_impl_timer_create(long res, long which_clock,\n                                                long timer_event_spec,\n                                                long created_timer_id);\nvoid __sanitizer_syscall_pre_impl_timer_gettime(long timer_id, long setting);\nvoid __sanitizer_syscall_post_impl_timer_gettime(long res, long timer_id,\n                                                 long setting);\nvoid __sanitizer_syscall_pre_impl_timer_getoverrun(long timer_id);\nvoid __sanitizer_syscall_post_impl_timer_getoverrun(long res, long timer_id);\nvoid __sanitizer_syscall_pre_impl_timer_settime(long timer_id, long flags,\n                                                long new_setting,\n                                                long old_setting);\nvoid __sanitizer_syscall_post_impl_timer_settime(long res, long timer_id,\n                                                 long flags, long new_setting,\n                                                 long old_setting);\nvoid __sanitizer_syscall_pre_impl_timer_delete(long timer_id);\nvoid __sanitizer_syscall_post_impl_timer_delete(long res, long timer_id);\nvoid __sanitizer_syscall_pre_impl_clock_settime(long which_clock, long tp);\nvoid __sanitizer_syscall_post_impl_clock_settime(long res, long which_clock,\n                                                 long tp);\nvoid __sanitizer_syscall_pre_impl_clock_gettime(long which_clock, long tp);\nvoid __sanitizer_syscall_post_impl_clock_gettime(long res, long which_clock,\n                                                 long tp);\nvoid __sanitizer_syscall_pre_impl_clock_adjtime(long which_clock, long tx);\nvoid __sanitizer_syscall_post_impl_clock_adjtime(long res, long which_clock,\n                                                 long tx);\nvoid __sanitizer_syscall_pre_impl_clock_getres(long which_clock, long tp);\nvoid __sanitizer_syscall_post_impl_clock_getres(long res, long which_clock,\n                                                long tp);\nvoid __sanitizer_syscall_pre_impl_clock_nanosleep(long which_clock, long flags,\n                                                  long rqtp, long rmtp);\nvoid __sanitizer_syscall_post_impl_clock_nanosleep(long res, long which_clock,\n                                                   long flags, long rqtp,\n                                                   long rmtp);\nvoid __sanitizer_syscall_pre_impl_nice(long increment);\nvoid __sanitizer_syscall_post_impl_nice(long res, long increment);\nvoid __sanitizer_syscall_pre_impl_sched_setscheduler(long pid, long policy,\n                                                     long param);\nvoid __sanitizer_syscall_post_impl_sched_setscheduler(long res, long pid,\n                                                      long policy, long param);\nvoid __sanitizer_syscall_pre_impl_sched_setparam(long pid, long param);\nvoid __sanitizer_syscall_post_impl_sched_setparam(long res, long pid,\n                                                  long param);\nvoid __sanitizer_syscall_pre_impl_sched_getscheduler(long pid);\nvoid __sanitizer_syscall_post_impl_sched_getscheduler(long res, long pid);\nvoid __sanitizer_syscall_pre_impl_sched_getparam(long pid, long param);\nvoid __sanitizer_syscall_post_impl_sched_getparam(long res, long pid,\n                                                  long param);\nvoid __sanitizer_syscall_pre_impl_sched_setaffinity(long pid, long len,\n                                                    long user_mask_ptr);\nvoid __sanitizer_syscall_post_impl_sched_setaffinity(long res, long pid,\n                                                     long len,\n                                                     long user_mask_ptr);\nvoid __sanitizer_syscall_pre_impl_sched_getaffinity(long pid, long len,\n                                                    long user_mask_ptr);\nvoid __sanitizer_syscall_post_impl_sched_getaffinity(long res, long pid,\n                                                     long len,\n                                                     long user_mask_ptr);\nvoid __sanitizer_syscall_pre_impl_sched_yield();\nvoid __sanitizer_syscall_post_impl_sched_yield(long res);\nvoid __sanitizer_syscall_pre_impl_sched_get_priority_max(long policy);\nvoid __sanitizer_syscall_post_impl_sched_get_priority_max(long res,\n                                                          long policy);\nvoid __sanitizer_syscall_pre_impl_sched_get_priority_min(long policy);\nvoid __sanitizer_syscall_post_impl_sched_get_priority_min(long res,\n                                                          long policy);\nvoid __sanitizer_syscall_pre_impl_sched_rr_get_interval(long pid,\n                                                        long interval);\nvoid __sanitizer_syscall_post_impl_sched_rr_get_interval(long res, long pid,\n                                                         long interval);\nvoid __sanitizer_syscall_pre_impl_setpriority(long which, long who,\n                                              long niceval);\nvoid __sanitizer_syscall_post_impl_setpriority(long res, long which, long who,\n                                               long niceval);\nvoid __sanitizer_syscall_pre_impl_getpriority(long which, long who);\nvoid __sanitizer_syscall_post_impl_getpriority(long res, long which, long who);\nvoid __sanitizer_syscall_pre_impl_shutdown(long arg0, long arg1);\nvoid __sanitizer_syscall_post_impl_shutdown(long res, long arg0, long arg1);\nvoid __sanitizer_syscall_pre_impl_reboot(long magic1, long magic2, long cmd,\n                                         long arg);\nvoid __sanitizer_syscall_post_impl_reboot(long res, long magic1, long magic2,\n                                          long cmd, long arg);\nvoid __sanitizer_syscall_pre_impl_restart_syscall();\nvoid __sanitizer_syscall_post_impl_restart_syscall(long res);\nvoid __sanitizer_syscall_pre_impl_kexec_load(long entry, long nr_segments,\n                                             long segments, long flags);\nvoid __sanitizer_syscall_post_impl_kexec_load(long res, long entry,\n                                              long nr_segments, long segments,\n                                              long flags);\nvoid __sanitizer_syscall_pre_impl_exit(long error_code);\nvoid __sanitizer_syscall_post_impl_exit(long res, long error_code);\nvoid __sanitizer_syscall_pre_impl_exit_group(long error_code);\nvoid __sanitizer_syscall_post_impl_exit_group(long res, long error_code);\nvoid __sanitizer_syscall_pre_impl_wait4(long pid, long stat_addr, long options,\n                                        long ru);\nvoid __sanitizer_syscall_post_impl_wait4(long res, long pid, long stat_addr,\n                                         long options, long ru);\nvoid __sanitizer_syscall_pre_impl_waitid(long which, long pid, long infop,\n                                         long options, long ru);\nvoid __sanitizer_syscall_post_impl_waitid(long res, long which, long pid,\n                                          long infop, long options, long ru);\nvoid __sanitizer_syscall_pre_impl_waitpid(long pid, long stat_addr,\n                                          long options);\nvoid __sanitizer_syscall_post_impl_waitpid(long res, long pid, long stat_addr,\n                                           long options);\nvoid __sanitizer_syscall_pre_impl_set_tid_address(long tidptr);\nvoid __sanitizer_syscall_post_impl_set_tid_address(long res, long tidptr);\nvoid __sanitizer_syscall_pre_impl_init_module(long umod, long len, long uargs);\nvoid __sanitizer_syscall_post_impl_init_module(long res, long umod, long len,\n                                               long uargs);\nvoid __sanitizer_syscall_pre_impl_delete_module(long name_user, long flags);\nvoid __sanitizer_syscall_post_impl_delete_module(long res, long name_user,\n                                                 long flags);\nvoid __sanitizer_syscall_pre_impl_rt_sigprocmask(long how, long set, long oset,\n                                                 long sigsetsize);\nvoid __sanitizer_syscall_post_impl_rt_sigprocmask(long res, long how, long set,\n                                                  long oset, long sigsetsize);\nvoid __sanitizer_syscall_pre_impl_rt_sigpending(long set, long sigsetsize);\nvoid __sanitizer_syscall_post_impl_rt_sigpending(long res, long set,\n                                                 long sigsetsize);\nvoid __sanitizer_syscall_pre_impl_rt_sigtimedwait(long uthese, long uinfo,\n                                                  long uts, long sigsetsize);\nvoid __sanitizer_syscall_post_impl_rt_sigtimedwait(long res, long uthese,\n                                                   long uinfo, long uts,\n                                                   long sigsetsize);\nvoid __sanitizer_syscall_pre_impl_rt_tgsigqueueinfo(long tgid, long pid,\n                                                    long sig, long uinfo);\nvoid __sanitizer_syscall_post_impl_rt_tgsigqueueinfo(long res, long tgid,\n                                                     long pid, long sig,\n                                                     long uinfo);\nvoid __sanitizer_syscall_pre_impl_kill(long pid, long sig);\nvoid __sanitizer_syscall_post_impl_kill(long res, long pid, long sig);\nvoid __sanitizer_syscall_pre_impl_tgkill(long tgid, long pid, long sig);\nvoid __sanitizer_syscall_post_impl_tgkill(long res, long tgid, long pid,\n                                          long sig);\nvoid __sanitizer_syscall_pre_impl_tkill(long pid, long sig);\nvoid __sanitizer_syscall_post_impl_tkill(long res, long pid, long sig);\nvoid __sanitizer_syscall_pre_impl_rt_sigqueueinfo(long pid, long sig,\n                                                  long uinfo);\nvoid __sanitizer_syscall_post_impl_rt_sigqueueinfo(long res, long pid, long sig,\n                                                   long uinfo);\nvoid __sanitizer_syscall_pre_impl_sgetmask();\nvoid __sanitizer_syscall_post_impl_sgetmask(long res);\nvoid __sanitizer_syscall_pre_impl_ssetmask(long newmask);\nvoid __sanitizer_syscall_post_impl_ssetmask(long res, long newmask);\nvoid __sanitizer_syscall_pre_impl_signal(long sig, long handler);\nvoid __sanitizer_syscall_post_impl_signal(long res, long sig, long handler);\nvoid __sanitizer_syscall_pre_impl_pause();\nvoid __sanitizer_syscall_post_impl_pause(long res);\nvoid __sanitizer_syscall_pre_impl_sync();\nvoid __sanitizer_syscall_post_impl_sync(long res);\nvoid __sanitizer_syscall_pre_impl_fsync(long fd);\nvoid __sanitizer_syscall_post_impl_fsync(long res, long fd);\nvoid __sanitizer_syscall_pre_impl_fdatasync(long fd);\nvoid __sanitizer_syscall_post_impl_fdatasync(long res, long fd);\nvoid __sanitizer_syscall_pre_impl_bdflush(long func, long data);\nvoid __sanitizer_syscall_post_impl_bdflush(long res, long func, long data);\nvoid __sanitizer_syscall_pre_impl_mount(long dev_name, long dir_name, long type,\n                                        long flags, long data);\nvoid __sanitizer_syscall_post_impl_mount(long res, long dev_name, long dir_name,\n                                         long type, long flags, long data);\nvoid __sanitizer_syscall_pre_impl_umount(long name, long flags);\nvoid __sanitizer_syscall_post_impl_umount(long res, long name, long flags);\nvoid __sanitizer_syscall_pre_impl_oldumount(long name);\nvoid __sanitizer_syscall_post_impl_oldumount(long res, long name);\nvoid __sanitizer_syscall_pre_impl_truncate(long path, long length);\nvoid __sanitizer_syscall_post_impl_truncate(long res, long path, long length);\nvoid __sanitizer_syscall_pre_impl_ftruncate(long fd, long length);\nvoid __sanitizer_syscall_post_impl_ftruncate(long res, long fd, long length);\nvoid __sanitizer_syscall_pre_impl_stat(long filename, long statbuf);\nvoid __sanitizer_syscall_post_impl_stat(long res, long filename, long statbuf);\nvoid __sanitizer_syscall_pre_impl_statfs(long path, long buf);\nvoid __sanitizer_syscall_post_impl_statfs(long res, long path, long buf);\nvoid __sanitizer_syscall_pre_impl_statfs64(long path, long sz, long buf);\nvoid __sanitizer_syscall_post_impl_statfs64(long res, long path, long sz,\n                                            long buf);\nvoid __sanitizer_syscall_pre_impl_fstatfs(long fd, long buf);\nvoid __sanitizer_syscall_post_impl_fstatfs(long res, long fd, long buf);\nvoid __sanitizer_syscall_pre_impl_fstatfs64(long fd, long sz, long buf);\nvoid __sanitizer_syscall_post_impl_fstatfs64(long res, long fd, long sz,\n                                             long buf);\nvoid __sanitizer_syscall_pre_impl_lstat(long filename, long statbuf);\nvoid __sanitizer_syscall_post_impl_lstat(long res, long filename, long statbuf);\nvoid __sanitizer_syscall_pre_impl_fstat(long fd, long statbuf);\nvoid __sanitizer_syscall_post_impl_fstat(long res, long fd, long statbuf);\nvoid __sanitizer_syscall_pre_impl_newstat(long filename, long statbuf);\nvoid __sanitizer_syscall_post_impl_newstat(long res, long filename,\n                                           long statbuf);\nvoid __sanitizer_syscall_pre_impl_newlstat(long filename, long statbuf);\nvoid __sanitizer_syscall_post_impl_newlstat(long res, long filename,\n                                            long statbuf);\nvoid __sanitizer_syscall_pre_impl_newfstat(long fd, long statbuf);\nvoid __sanitizer_syscall_post_impl_newfstat(long res, long fd, long statbuf);\nvoid __sanitizer_syscall_pre_impl_ustat(long dev, long ubuf);\nvoid __sanitizer_syscall_post_impl_ustat(long res, long dev, long ubuf);\nvoid __sanitizer_syscall_pre_impl_stat64(long filename, long statbuf);\nvoid __sanitizer_syscall_post_impl_stat64(long res, long filename,\n                                          long statbuf);\nvoid __sanitizer_syscall_pre_impl_fstat64(long fd, long statbuf);\nvoid __sanitizer_syscall_post_impl_fstat64(long res, long fd, long statbuf);\nvoid __sanitizer_syscall_pre_impl_lstat64(long filename, long statbuf);\nvoid __sanitizer_syscall_post_impl_lstat64(long res, long filename,\n                                           long statbuf);\nvoid __sanitizer_syscall_pre_impl_setxattr(long path, long name, long value,\n                                           long size, long flags);\nvoid __sanitizer_syscall_post_impl_setxattr(long res, long path, long name,\n                                            long value, long size, long flags);\nvoid __sanitizer_syscall_pre_impl_lsetxattr(long path, long name, long value,\n                                            long size, long flags);\nvoid __sanitizer_syscall_post_impl_lsetxattr(long res, long path, long name,\n                                             long value, long size, long flags);\nvoid __sanitizer_syscall_pre_impl_fsetxattr(long fd, long name, long value,\n                                            long size, long flags);\nvoid __sanitizer_syscall_post_impl_fsetxattr(long res, long fd, long name,\n                                             long value, long size, long flags);\nvoid __sanitizer_syscall_pre_impl_getxattr(long path, long name, long value,\n                                           long size);\nvoid __sanitizer_syscall_post_impl_getxattr(long res, long path, long name,\n                                            long value, long size);\nvoid __sanitizer_syscall_pre_impl_lgetxattr(long path, long name, long value,\n                                            long size);\nvoid __sanitizer_syscall_post_impl_lgetxattr(long res, long path, long name,\n                                             long value, long size);\nvoid __sanitizer_syscall_pre_impl_fgetxattr(long fd, long name, long value,\n                                            long size);\nvoid __sanitizer_syscall_post_impl_fgetxattr(long res, long fd, long name,\n                                             long value, long size);\nvoid __sanitizer_syscall_pre_impl_listxattr(long path, long list, long size);\nvoid __sanitizer_syscall_post_impl_listxattr(long res, long path, long list,\n                                             long size);\nvoid __sanitizer_syscall_pre_impl_llistxattr(long path, long list, long size);\nvoid __sanitizer_syscall_post_impl_llistxattr(long res, long path, long list,\n                                              long size);\nvoid __sanitizer_syscall_pre_impl_flistxattr(long fd, long list, long size);\nvoid __sanitizer_syscall_post_impl_flistxattr(long res, long fd, long list,\n                                              long size);\nvoid __sanitizer_syscall_pre_impl_removexattr(long path, long name);\nvoid __sanitizer_syscall_post_impl_removexattr(long res, long path, long name);\nvoid __sanitizer_syscall_pre_impl_lremovexattr(long path, long name);\nvoid __sanitizer_syscall_post_impl_lremovexattr(long res, long path, long name);\nvoid __sanitizer_syscall_pre_impl_fremovexattr(long fd, long name);\nvoid __sanitizer_syscall_post_impl_fremovexattr(long res, long fd, long name);\nvoid __sanitizer_syscall_pre_impl_brk(long brk);\nvoid __sanitizer_syscall_post_impl_brk(long res, long brk);\nvoid __sanitizer_syscall_pre_impl_mprotect(long start, long len, long prot);\nvoid __sanitizer_syscall_post_impl_mprotect(long res, long start, long len,\n                                            long prot);\nvoid __sanitizer_syscall_pre_impl_mremap(long addr, long old_len, long new_len,\n                                         long flags, long new_addr);\nvoid __sanitizer_syscall_post_impl_mremap(long res, long addr, long old_len,\n                                          long new_len, long flags,\n                                          long new_addr);\nvoid __sanitizer_syscall_pre_impl_remap_file_pages(long start, long size,\n                                                   long prot, long pgoff,\n                                                   long flags);\nvoid __sanitizer_syscall_post_impl_remap_file_pages(long res, long start,\n                                                    long size, long prot,\n                                                    long pgoff, long flags);\nvoid __sanitizer_syscall_pre_impl_msync(long start, long len, long flags);\nvoid __sanitizer_syscall_post_impl_msync(long res, long start, long len,\n                                         long flags);\nvoid __sanitizer_syscall_pre_impl_munmap(long addr, long len);\nvoid __sanitizer_syscall_post_impl_munmap(long res, long addr, long len);\nvoid __sanitizer_syscall_pre_impl_mlock(long start, long len);\nvoid __sanitizer_syscall_post_impl_mlock(long res, long start, long len);\nvoid __sanitizer_syscall_pre_impl_munlock(long start, long len);\nvoid __sanitizer_syscall_post_impl_munlock(long res, long start, long len);\nvoid __sanitizer_syscall_pre_impl_mlockall(long flags);\nvoid __sanitizer_syscall_post_impl_mlockall(long res, long flags);\nvoid __sanitizer_syscall_pre_impl_munlockall();\nvoid __sanitizer_syscall_post_impl_munlockall(long res);\nvoid __sanitizer_syscall_pre_impl_madvise(long start, long len, long behavior);\nvoid __sanitizer_syscall_post_impl_madvise(long res, long start, long len,\n                                           long behavior);\nvoid __sanitizer_syscall_pre_impl_mincore(long start, long len, long vec);\nvoid __sanitizer_syscall_post_impl_mincore(long res, long start, long len,\n                                           long vec);\nvoid __sanitizer_syscall_pre_impl_pivot_root(long new_root, long put_old);\nvoid __sanitizer_syscall_post_impl_pivot_root(long res, long new_root,\n                                              long put_old);\nvoid __sanitizer_syscall_pre_impl_chroot(long filename);\nvoid __sanitizer_syscall_post_impl_chroot(long res, long filename);\nvoid __sanitizer_syscall_pre_impl_mknod(long filename, long mode, long dev);\nvoid __sanitizer_syscall_post_impl_mknod(long res, long filename, long mode,\n                                         long dev);\nvoid __sanitizer_syscall_pre_impl_link(long oldname, long newname);\nvoid __sanitizer_syscall_post_impl_link(long res, long oldname, long newname);\nvoid __sanitizer_syscall_pre_impl_symlink(long old, long new_);\nvoid __sanitizer_syscall_post_impl_symlink(long res, long old, long new_);\nvoid __sanitizer_syscall_pre_impl_unlink(long pathname);\nvoid __sanitizer_syscall_post_impl_unlink(long res, long pathname);\nvoid __sanitizer_syscall_pre_impl_rename(long oldname, long newname);\nvoid __sanitizer_syscall_post_impl_rename(long res, long oldname, long newname);\nvoid __sanitizer_syscall_pre_impl_chmod(long filename, long mode);\nvoid __sanitizer_syscall_post_impl_chmod(long res, long filename, long mode);\nvoid __sanitizer_syscall_pre_impl_fchmod(long fd, long mode);\nvoid __sanitizer_syscall_post_impl_fchmod(long res, long fd, long mode);\nvoid __sanitizer_syscall_pre_impl_fcntl(long fd, long cmd, long arg);\nvoid __sanitizer_syscall_post_impl_fcntl(long res, long fd, long cmd, long arg);\nvoid __sanitizer_syscall_pre_impl_fcntl64(long fd, long cmd, long arg);\nvoid __sanitizer_syscall_post_impl_fcntl64(long res, long fd, long cmd,\n                                           long arg);\nvoid __sanitizer_syscall_pre_impl_pipe(long fildes);\nvoid __sanitizer_syscall_post_impl_pipe(long res, long fildes);\nvoid __sanitizer_syscall_pre_impl_pipe2(long fildes, long flags);\nvoid __sanitizer_syscall_post_impl_pipe2(long res, long fildes, long flags);\nvoid __sanitizer_syscall_pre_impl_dup(long fildes);\nvoid __sanitizer_syscall_post_impl_dup(long res, long fildes);\nvoid __sanitizer_syscall_pre_impl_dup2(long oldfd, long newfd);\nvoid __sanitizer_syscall_post_impl_dup2(long res, long oldfd, long newfd);\nvoid __sanitizer_syscall_pre_impl_dup3(long oldfd, long newfd, long flags);\nvoid __sanitizer_syscall_post_impl_dup3(long res, long oldfd, long newfd,\n                                        long flags);\nvoid __sanitizer_syscall_pre_impl_ioperm(long from, long num, long on);\nvoid __sanitizer_syscall_post_impl_ioperm(long res, long from, long num,\n                                          long on);\nvoid __sanitizer_syscall_pre_impl_ioctl(long fd, long cmd, long arg);\nvoid __sanitizer_syscall_post_impl_ioctl(long res, long fd, long cmd, long arg);\nvoid __sanitizer_syscall_pre_impl_flock(long fd, long cmd);\nvoid __sanitizer_syscall_post_impl_flock(long res, long fd, long cmd);\nvoid __sanitizer_syscall_pre_impl_io_setup(long nr_reqs, long ctx);\nvoid __sanitizer_syscall_post_impl_io_setup(long res, long nr_reqs, long ctx);\nvoid __sanitizer_syscall_pre_impl_io_destroy(long ctx);\nvoid __sanitizer_syscall_post_impl_io_destroy(long res, long ctx);\nvoid __sanitizer_syscall_pre_impl_io_getevents(long ctx_id, long min_nr,\n                                               long nr, long events,\n                                               long timeout);\nvoid __sanitizer_syscall_post_impl_io_getevents(long res, long ctx_id,\n                                                long min_nr, long nr,\n                                                long events, long timeout);\nvoid __sanitizer_syscall_pre_impl_io_submit(long ctx_id, long arg1, long arg2);\nvoid __sanitizer_syscall_post_impl_io_submit(long res, long ctx_id, long arg1,\n                                             long arg2);\nvoid __sanitizer_syscall_pre_impl_io_cancel(long ctx_id, long iocb,\n                                            long result);\nvoid __sanitizer_syscall_post_impl_io_cancel(long res, long ctx_id, long iocb,\n                                             long result);\nvoid __sanitizer_syscall_pre_impl_sendfile(long out_fd, long in_fd, long offset,\n                                           long count);\nvoid __sanitizer_syscall_post_impl_sendfile(long res, long out_fd, long in_fd,\n                                            long offset, long count);\nvoid __sanitizer_syscall_pre_impl_sendfile64(long out_fd, long in_fd,\n                                             long offset, long count);\nvoid __sanitizer_syscall_post_impl_sendfile64(long res, long out_fd, long in_fd,\n                                              long offset, long count);\nvoid __sanitizer_syscall_pre_impl_readlink(long path, long buf, long bufsiz);\nvoid __sanitizer_syscall_post_impl_readlink(long res, long path, long buf,\n                                            long bufsiz);\nvoid __sanitizer_syscall_pre_impl_creat(long pathname, long mode);\nvoid __sanitizer_syscall_post_impl_creat(long res, long pathname, long mode);\nvoid __sanitizer_syscall_pre_impl_open(long filename, long flags, long mode);\nvoid __sanitizer_syscall_post_impl_open(long res, long filename, long flags,\n                                        long mode);\nvoid __sanitizer_syscall_pre_impl_close(long fd);\nvoid __sanitizer_syscall_post_impl_close(long res, long fd);\nvoid __sanitizer_syscall_pre_impl_access(long filename, long mode);\nvoid __sanitizer_syscall_post_impl_access(long res, long filename, long mode);\nvoid __sanitizer_syscall_pre_impl_vhangup();\nvoid __sanitizer_syscall_post_impl_vhangup(long res);\nvoid __sanitizer_syscall_pre_impl_chown(long filename, long user, long group);\nvoid __sanitizer_syscall_post_impl_chown(long res, long filename, long user,\n                                         long group);\nvoid __sanitizer_syscall_pre_impl_lchown(long filename, long user, long group);\nvoid __sanitizer_syscall_post_impl_lchown(long res, long filename, long user,\n                                          long group);\nvoid __sanitizer_syscall_pre_impl_fchown(long fd, long user, long group);\nvoid __sanitizer_syscall_post_impl_fchown(long res, long fd, long user,\n                                          long group);\nvoid __sanitizer_syscall_pre_impl_chown16(long filename, long user, long group);\nvoid __sanitizer_syscall_post_impl_chown16(long res, long filename, long user,\n                                           long group);\nvoid __sanitizer_syscall_pre_impl_lchown16(long filename, long user,\n                                           long group);\nvoid __sanitizer_syscall_post_impl_lchown16(long res, long filename, long user,\n                                            long group);\nvoid __sanitizer_syscall_pre_impl_fchown16(long fd, long user, long group);\nvoid __sanitizer_syscall_post_impl_fchown16(long res, long fd, long user,\n                                            long group);\nvoid __sanitizer_syscall_pre_impl_setregid16(long rgid, long egid);\nvoid __sanitizer_syscall_post_impl_setregid16(long res, long rgid, long egid);\nvoid __sanitizer_syscall_pre_impl_setgid16(long gid);\nvoid __sanitizer_syscall_post_impl_setgid16(long res, long gid);\nvoid __sanitizer_syscall_pre_impl_setreuid16(long ruid, long euid);\nvoid __sanitizer_syscall_post_impl_setreuid16(long res, long ruid, long euid);\nvoid __sanitizer_syscall_pre_impl_setuid16(long uid);\nvoid __sanitizer_syscall_post_impl_setuid16(long res, long uid);\nvoid __sanitizer_syscall_pre_impl_setresuid16(long ruid, long euid, long suid);\nvoid __sanitizer_syscall_post_impl_setresuid16(long res, long ruid, long euid,\n                                               long suid);\nvoid __sanitizer_syscall_pre_impl_getresuid16(long ruid, long euid, long suid);\nvoid __sanitizer_syscall_post_impl_getresuid16(long res, long ruid, long euid,\n                                               long suid);\nvoid __sanitizer_syscall_pre_impl_setresgid16(long rgid, long egid, long sgid);\nvoid __sanitizer_syscall_post_impl_setresgid16(long res, long rgid, long egid,\n                                               long sgid);\nvoid __sanitizer_syscall_pre_impl_getresgid16(long rgid, long egid, long sgid);\nvoid __sanitizer_syscall_post_impl_getresgid16(long res, long rgid, long egid,\n                                               long sgid);\nvoid __sanitizer_syscall_pre_impl_setfsuid16(long uid);\nvoid __sanitizer_syscall_post_impl_setfsuid16(long res, long uid);\nvoid __sanitizer_syscall_pre_impl_setfsgid16(long gid);\nvoid __sanitizer_syscall_post_impl_setfsgid16(long res, long gid);\nvoid __sanitizer_syscall_pre_impl_getgroups16(long gidsetsize, long grouplist);\nvoid __sanitizer_syscall_post_impl_getgroups16(long res, long gidsetsize,\n                                               long grouplist);\nvoid __sanitizer_syscall_pre_impl_setgroups16(long gidsetsize, long grouplist);\nvoid __sanitizer_syscall_post_impl_setgroups16(long res, long gidsetsize,\n                                               long grouplist);\nvoid __sanitizer_syscall_pre_impl_getuid16();\nvoid __sanitizer_syscall_post_impl_getuid16(long res);\nvoid __sanitizer_syscall_pre_impl_geteuid16();\nvoid __sanitizer_syscall_post_impl_geteuid16(long res);\nvoid __sanitizer_syscall_pre_impl_getgid16();\nvoid __sanitizer_syscall_post_impl_getgid16(long res);\nvoid __sanitizer_syscall_pre_impl_getegid16();\nvoid __sanitizer_syscall_post_impl_getegid16(long res);\nvoid __sanitizer_syscall_pre_impl_utime(long filename, long times);\nvoid __sanitizer_syscall_post_impl_utime(long res, long filename, long times);\nvoid __sanitizer_syscall_pre_impl_utimes(long filename, long utimes);\nvoid __sanitizer_syscall_post_impl_utimes(long res, long filename, long utimes);\nvoid __sanitizer_syscall_pre_impl_lseek(long fd, long offset, long origin);\nvoid __sanitizer_syscall_post_impl_lseek(long res, long fd, long offset,\n                                         long origin);\nvoid __sanitizer_syscall_pre_impl_llseek(long fd, long offset_high,\n                                         long offset_low, long result,\n                                         long origin);\nvoid __sanitizer_syscall_post_impl_llseek(long res, long fd, long offset_high,\n                                          long offset_low, long result,\n                                          long origin);\nvoid __sanitizer_syscall_pre_impl_read(long fd, long buf, long count);\nvoid __sanitizer_syscall_post_impl_read(long res, long fd, long buf,\n                                        long count);\nvoid __sanitizer_syscall_pre_impl_readv(long fd, long vec, long vlen);\nvoid __sanitizer_syscall_post_impl_readv(long res, long fd, long vec,\n                                         long vlen);\nvoid __sanitizer_syscall_pre_impl_write(long fd, long buf, long count);\nvoid __sanitizer_syscall_post_impl_write(long res, long fd, long buf,\n                                         long count);\nvoid __sanitizer_syscall_pre_impl_writev(long fd, long vec, long vlen);\nvoid __sanitizer_syscall_post_impl_writev(long res, long fd, long vec,\n                                          long vlen);\n\n#ifdef _LP64\nvoid __sanitizer_syscall_pre_impl_pread64(long fd, long buf, long count,\n                                          long pos);\nvoid __sanitizer_syscall_post_impl_pread64(long res, long fd, long buf,\n                                           long count, long pos);\nvoid __sanitizer_syscall_pre_impl_pwrite64(long fd, long buf, long count,\n                                           long pos);\nvoid __sanitizer_syscall_post_impl_pwrite64(long res, long fd, long buf,\n                                            long count, long pos);\n#else\nvoid __sanitizer_syscall_pre_impl_pread64(long fd, long buf, long count,\n                                          long pos0, long pos1);\nvoid __sanitizer_syscall_post_impl_pread64(long res, long fd, long buf,\n                                           long count, long pos0, long pos1);\nvoid __sanitizer_syscall_pre_impl_pwrite64(long fd, long buf, long count,\n                                           long pos0, long pos1);\nvoid __sanitizer_syscall_post_impl_pwrite64(long res, long fd, long buf,\n                                            long count, long pos0, long pos1);\n#endif\n\nvoid __sanitizer_syscall_pre_impl_preadv(long fd, long vec, long vlen,\n                                         long pos_l, long pos_h);\nvoid __sanitizer_syscall_post_impl_preadv(long res, long fd, long vec,\n                                          long vlen, long pos_l, long pos_h);\nvoid __sanitizer_syscall_pre_impl_pwritev(long fd, long vec, long vlen,\n                                          long pos_l, long pos_h);\nvoid __sanitizer_syscall_post_impl_pwritev(long res, long fd, long vec,\n                                           long vlen, long pos_l, long pos_h);\nvoid __sanitizer_syscall_pre_impl_getcwd(long buf, long size);\nvoid __sanitizer_syscall_post_impl_getcwd(long res, long buf, long size);\nvoid __sanitizer_syscall_pre_impl_mkdir(long pathname, long mode);\nvoid __sanitizer_syscall_post_impl_mkdir(long res, long pathname, long mode);\nvoid __sanitizer_syscall_pre_impl_chdir(long filename);\nvoid __sanitizer_syscall_post_impl_chdir(long res, long filename);\nvoid __sanitizer_syscall_pre_impl_fchdir(long fd);\nvoid __sanitizer_syscall_post_impl_fchdir(long res, long fd);\nvoid __sanitizer_syscall_pre_impl_rmdir(long pathname);\nvoid __sanitizer_syscall_post_impl_rmdir(long res, long pathname);\nvoid __sanitizer_syscall_pre_impl_lookup_dcookie(long cookie64, long buf,\n                                                 long len);\nvoid __sanitizer_syscall_post_impl_lookup_dcookie(long res, long cookie64,\n                                                  long buf, long len);\nvoid __sanitizer_syscall_pre_impl_quotactl(long cmd, long special, long id,\n                                           long addr);\nvoid __sanitizer_syscall_post_impl_quotactl(long res, long cmd, long special,\n                                            long id, long addr);\nvoid __sanitizer_syscall_pre_impl_getdents(long fd, long dirent, long count);\nvoid __sanitizer_syscall_post_impl_getdents(long res, long fd, long dirent,\n                                            long count);\nvoid __sanitizer_syscall_pre_impl_getdents64(long fd, long dirent, long count);\nvoid __sanitizer_syscall_post_impl_getdents64(long res, long fd, long dirent,\n                                              long count);\nvoid __sanitizer_syscall_pre_impl_setsockopt(long fd, long level, long optname,\n                                             long optval, long optlen);\nvoid __sanitizer_syscall_post_impl_setsockopt(long res, long fd, long level,\n                                              long optname, long optval,\n                                              long optlen);\nvoid __sanitizer_syscall_pre_impl_getsockopt(long fd, long level, long optname,\n                                             long optval, long optlen);\nvoid __sanitizer_syscall_post_impl_getsockopt(long res, long fd, long level,\n                                              long optname, long optval,\n                                              long optlen);\nvoid __sanitizer_syscall_pre_impl_bind(long arg0, long arg1, long arg2);\nvoid __sanitizer_syscall_post_impl_bind(long res, long arg0, long arg1,\n                                        long arg2);\nvoid __sanitizer_syscall_pre_impl_connect(long arg0, long arg1, long arg2);\nvoid __sanitizer_syscall_post_impl_connect(long res, long arg0, long arg1,\n                                           long arg2);\nvoid __sanitizer_syscall_pre_impl_accept(long arg0, long arg1, long arg2);\nvoid __sanitizer_syscall_post_impl_accept(long res, long arg0, long arg1,\n                                          long arg2);\nvoid __sanitizer_syscall_pre_impl_accept4(long arg0, long arg1, long arg2,\n                                          long arg3);\nvoid __sanitizer_syscall_post_impl_accept4(long res, long arg0, long arg1,\n                                           long arg2, long arg3);\nvoid __sanitizer_syscall_pre_impl_getsockname(long arg0, long arg1, long arg2);\nvoid __sanitizer_syscall_post_impl_getsockname(long res, long arg0, long arg1,\n                                               long arg2);\nvoid __sanitizer_syscall_pre_impl_getpeername(long arg0, long arg1, long arg2);\nvoid __sanitizer_syscall_post_impl_getpeername(long res, long arg0, long arg1,\n                                               long arg2);\nvoid __sanitizer_syscall_pre_impl_send(long arg0, long arg1, long arg2,\n                                       long arg3);\nvoid __sanitizer_syscall_post_impl_send(long res, long arg0, long arg1,\n                                        long arg2, long arg3);\nvoid __sanitizer_syscall_pre_impl_sendto(long arg0, long arg1, long arg2,\n                                         long arg3, long arg4, long arg5);\nvoid __sanitizer_syscall_post_impl_sendto(long res, long arg0, long arg1,\n                                          long arg2, long arg3, long arg4,\n                                          long arg5);\nvoid __sanitizer_syscall_pre_impl_sendmsg(long fd, long msg, long flags);\nvoid __sanitizer_syscall_post_impl_sendmsg(long res, long fd, long msg,\n                                           long flags);\nvoid __sanitizer_syscall_pre_impl_sendmmsg(long fd, long msg, long vlen,\n                                           long flags);\nvoid __sanitizer_syscall_post_impl_sendmmsg(long res, long fd, long msg,\n                                            long vlen, long flags);\nvoid __sanitizer_syscall_pre_impl_recv(long arg0, long arg1, long arg2,\n                                       long arg3);\nvoid __sanitizer_syscall_post_impl_recv(long res, long arg0, long arg1,\n                                        long arg2, long arg3);\nvoid __sanitizer_syscall_pre_impl_recvfrom(long arg0, long arg1, long arg2,\n                                           long arg3, long arg4, long arg5);\nvoid __sanitizer_syscall_post_impl_recvfrom(long res, long arg0, long arg1,\n                                            long arg2, long arg3, long arg4,\n                                            long arg5);\nvoid __sanitizer_syscall_pre_impl_recvmsg(long fd, long msg, long flags);\nvoid __sanitizer_syscall_post_impl_recvmsg(long res, long fd, long msg,\n                                           long flags);\nvoid __sanitizer_syscall_pre_impl_recvmmsg(long fd, long msg, long vlen,\n                                           long flags, long timeout);\nvoid __sanitizer_syscall_post_impl_recvmmsg(long res, long fd, long msg,\n                                            long vlen, long flags,\n                                            long timeout);\nvoid __sanitizer_syscall_pre_impl_socket(long arg0, long arg1, long arg2);\nvoid __sanitizer_syscall_post_impl_socket(long res, long arg0, long arg1,\n                                          long arg2);\nvoid __sanitizer_syscall_pre_impl_socketpair(long arg0, long arg1, long arg2,\n                                             long arg3);\nvoid __sanitizer_syscall_post_impl_socketpair(long res, long arg0, long arg1,\n                                              long arg2, long arg3);\nvoid __sanitizer_syscall_pre_impl_socketcall(long call, long args);\nvoid __sanitizer_syscall_post_impl_socketcall(long res, long call, long args);\nvoid __sanitizer_syscall_pre_impl_listen(long arg0, long arg1);\nvoid __sanitizer_syscall_post_impl_listen(long res, long arg0, long arg1);\nvoid __sanitizer_syscall_pre_impl_poll(long ufds, long nfds, long timeout);\nvoid __sanitizer_syscall_post_impl_poll(long res, long ufds, long nfds,\n                                        long timeout);\nvoid __sanitizer_syscall_pre_impl_select(long n, long inp, long outp, long exp,\n                                         long tvp);\nvoid __sanitizer_syscall_post_impl_select(long res, long n, long inp, long outp,\n                                          long exp, long tvp);\nvoid __sanitizer_syscall_pre_impl_old_select(long arg);\nvoid __sanitizer_syscall_post_impl_old_select(long res, long arg);\nvoid __sanitizer_syscall_pre_impl_epoll_create(long size);\nvoid __sanitizer_syscall_post_impl_epoll_create(long res, long size);\nvoid __sanitizer_syscall_pre_impl_epoll_create1(long flags);\nvoid __sanitizer_syscall_post_impl_epoll_create1(long res, long flags);\nvoid __sanitizer_syscall_pre_impl_epoll_ctl(long epfd, long op, long fd,\n                                            long event);\nvoid __sanitizer_syscall_post_impl_epoll_ctl(long res, long epfd, long op,\n                                             long fd, long event);\nvoid __sanitizer_syscall_pre_impl_epoll_wait(long epfd, long events,\n                                             long maxevents, long timeout);\nvoid __sanitizer_syscall_post_impl_epoll_wait(long res, long epfd, long events,\n                                              long maxevents, long timeout);\nvoid __sanitizer_syscall_pre_impl_epoll_pwait(long epfd, long events,\n                                              long maxevents, long timeout,\n                                              long sigmask, long sigsetsize);\nvoid __sanitizer_syscall_post_impl_epoll_pwait(long res, long epfd, long events,\n                                               long maxevents, long timeout,\n                                               long sigmask, long sigsetsize);\nvoid __sanitizer_syscall_pre_impl_gethostname(long name, long len);\nvoid __sanitizer_syscall_post_impl_gethostname(long res, long name, long len);\nvoid __sanitizer_syscall_pre_impl_sethostname(long name, long len);\nvoid __sanitizer_syscall_post_impl_sethostname(long res, long name, long len);\nvoid __sanitizer_syscall_pre_impl_setdomainname(long name, long len);\nvoid __sanitizer_syscall_post_impl_setdomainname(long res, long name, long len);\nvoid __sanitizer_syscall_pre_impl_newuname(long name);\nvoid __sanitizer_syscall_post_impl_newuname(long res, long name);\nvoid __sanitizer_syscall_pre_impl_uname(long arg0);\nvoid __sanitizer_syscall_post_impl_uname(long res, long arg0);\nvoid __sanitizer_syscall_pre_impl_olduname(long arg0);\nvoid __sanitizer_syscall_post_impl_olduname(long res, long arg0);\nvoid __sanitizer_syscall_pre_impl_getrlimit(long resource, long rlim);\nvoid __sanitizer_syscall_post_impl_getrlimit(long res, long resource,\n                                             long rlim);\nvoid __sanitizer_syscall_pre_impl_old_getrlimit(long resource, long rlim);\nvoid __sanitizer_syscall_post_impl_old_getrlimit(long res, long resource,\n                                                 long rlim);\nvoid __sanitizer_syscall_pre_impl_setrlimit(long resource, long rlim);\nvoid __sanitizer_syscall_post_impl_setrlimit(long res, long resource,\n                                             long rlim);\nvoid __sanitizer_syscall_pre_impl_prlimit64(long pid, long resource,\n                                            long new_rlim, long old_rlim);\nvoid __sanitizer_syscall_post_impl_prlimit64(long res, long pid, long resource,\n                                             long new_rlim, long old_rlim);\nvoid __sanitizer_syscall_pre_impl_getrusage(long who, long ru);\nvoid __sanitizer_syscall_post_impl_getrusage(long res, long who, long ru);\nvoid __sanitizer_syscall_pre_impl_umask(long mask);\nvoid __sanitizer_syscall_post_impl_umask(long res, long mask);\nvoid __sanitizer_syscall_pre_impl_msgget(long key, long msgflg);\nvoid __sanitizer_syscall_post_impl_msgget(long res, long key, long msgflg);\nvoid __sanitizer_syscall_pre_impl_msgsnd(long msqid, long msgp, long msgsz,\n                                         long msgflg);\nvoid __sanitizer_syscall_post_impl_msgsnd(long res, long msqid, long msgp,\n                                          long msgsz, long msgflg);\nvoid __sanitizer_syscall_pre_impl_msgrcv(long msqid, long msgp, long msgsz,\n                                         long msgtyp, long msgflg);\nvoid __sanitizer_syscall_post_impl_msgrcv(long res, long msqid, long msgp,\n                                          long msgsz, long msgtyp, long msgflg);\nvoid __sanitizer_syscall_pre_impl_msgctl(long msqid, long cmd, long buf);\nvoid __sanitizer_syscall_post_impl_msgctl(long res, long msqid, long cmd,\n                                          long buf);\nvoid __sanitizer_syscall_pre_impl_semget(long key, long nsems, long semflg);\nvoid __sanitizer_syscall_post_impl_semget(long res, long key, long nsems,\n                                          long semflg);\nvoid __sanitizer_syscall_pre_impl_semop(long semid, long sops, long nsops);\nvoid __sanitizer_syscall_post_impl_semop(long res, long semid, long sops,\n                                         long nsops);\nvoid __sanitizer_syscall_pre_impl_semctl(long semid, long semnum, long cmd,\n                                         long arg);\nvoid __sanitizer_syscall_post_impl_semctl(long res, long semid, long semnum,\n                                          long cmd, long arg);\nvoid __sanitizer_syscall_pre_impl_semtimedop(long semid, long sops, long nsops,\n                                             long timeout);\nvoid __sanitizer_syscall_post_impl_semtimedop(long res, long semid, long sops,\n                                              long nsops, long timeout);\nvoid __sanitizer_syscall_pre_impl_shmat(long shmid, long shmaddr, long shmflg);\nvoid __sanitizer_syscall_post_impl_shmat(long res, long shmid, long shmaddr,\n                                         long shmflg);\nvoid __sanitizer_syscall_pre_impl_shmget(long key, long size, long flag);\nvoid __sanitizer_syscall_post_impl_shmget(long res, long key, long size,\n                                          long flag);\nvoid __sanitizer_syscall_pre_impl_shmdt(long shmaddr);\nvoid __sanitizer_syscall_post_impl_shmdt(long res, long shmaddr);\nvoid __sanitizer_syscall_pre_impl_shmctl(long shmid, long cmd, long buf);\nvoid __sanitizer_syscall_post_impl_shmctl(long res, long shmid, long cmd,\n                                          long buf);\nvoid __sanitizer_syscall_pre_impl_ipc(long call, long first, long second,\n                                      long third, long ptr, long fifth);\nvoid __sanitizer_syscall_post_impl_ipc(long res, long call, long first,\n                                       long second, long third, long ptr,\n                                       long fifth);\nvoid __sanitizer_syscall_pre_impl_mq_open(long name, long oflag, long mode,\n                                          long attr);\nvoid __sanitizer_syscall_post_impl_mq_open(long res, long name, long oflag,\n                                           long mode, long attr);\nvoid __sanitizer_syscall_pre_impl_mq_unlink(long name);\nvoid __sanitizer_syscall_post_impl_mq_unlink(long res, long name);\nvoid __sanitizer_syscall_pre_impl_mq_timedsend(long mqdes, long msg_ptr,\n                                               long msg_len, long msg_prio,\n                                               long abs_timeout);\nvoid __sanitizer_syscall_post_impl_mq_timedsend(long res, long mqdes,\n                                                long msg_ptr, long msg_len,\n                                                long msg_prio,\n                                                long abs_timeout);\nvoid __sanitizer_syscall_pre_impl_mq_timedreceive(long mqdes, long msg_ptr,\n                                                  long msg_len, long msg_prio,\n                                                  long abs_timeout);\nvoid __sanitizer_syscall_post_impl_mq_timedreceive(long res, long mqdes,\n                                                   long msg_ptr, long msg_len,\n                                                   long msg_prio,\n                                                   long abs_timeout);\nvoid __sanitizer_syscall_pre_impl_mq_notify(long mqdes, long notification);\nvoid __sanitizer_syscall_post_impl_mq_notify(long res, long mqdes,\n                                             long notification);\nvoid __sanitizer_syscall_pre_impl_mq_getsetattr(long mqdes, long mqstat,\n                                                long omqstat);\nvoid __sanitizer_syscall_post_impl_mq_getsetattr(long res, long mqdes,\n                                                 long mqstat, long omqstat);\nvoid __sanitizer_syscall_pre_impl_pciconfig_iobase(long which, long bus,\n                                                   long devfn);\nvoid __sanitizer_syscall_post_impl_pciconfig_iobase(long res, long which,\n                                                    long bus, long devfn);\nvoid __sanitizer_syscall_pre_impl_pciconfig_read(long bus, long dfn, long off,\n                                                 long len, long buf);\nvoid __sanitizer_syscall_post_impl_pciconfig_read(long res, long bus, long dfn,\n                                                  long off, long len, long buf);\nvoid __sanitizer_syscall_pre_impl_pciconfig_write(long bus, long dfn, long off,\n                                                  long len, long buf);\nvoid __sanitizer_syscall_post_impl_pciconfig_write(long res, long bus, long dfn,\n                                                   long off, long len,\n                                                   long buf);\nvoid __sanitizer_syscall_pre_impl_swapon(long specialfile, long swap_flags);\nvoid __sanitizer_syscall_post_impl_swapon(long res, long specialfile,\n                                          long swap_flags);\nvoid __sanitizer_syscall_pre_impl_swapoff(long specialfile);\nvoid __sanitizer_syscall_post_impl_swapoff(long res, long specialfile);\nvoid __sanitizer_syscall_pre_impl_sysctl(long args);\nvoid __sanitizer_syscall_post_impl_sysctl(long res, long args);\nvoid __sanitizer_syscall_pre_impl_sysinfo(long info);\nvoid __sanitizer_syscall_post_impl_sysinfo(long res, long info);\nvoid __sanitizer_syscall_pre_impl_sysfs(long option, long arg1, long arg2);\nvoid __sanitizer_syscall_post_impl_sysfs(long res, long option, long arg1,\n                                         long arg2);\nvoid __sanitizer_syscall_pre_impl_syslog(long type, long buf, long len);\nvoid __sanitizer_syscall_post_impl_syslog(long res, long type, long buf,\n                                          long len);\nvoid __sanitizer_syscall_pre_impl_uselib(long library);\nvoid __sanitizer_syscall_post_impl_uselib(long res, long library);\nvoid __sanitizer_syscall_pre_impl_ni_syscall();\nvoid __sanitizer_syscall_post_impl_ni_syscall(long res);\nvoid __sanitizer_syscall_pre_impl_ptrace(long request, long pid, long addr,\n                                         long data);\nvoid __sanitizer_syscall_post_impl_ptrace(long res, long request, long pid,\n                                          long addr, long data);\nvoid __sanitizer_syscall_pre_impl_add_key(long _type, long _description,\n                                          long _payload, long plen,\n                                          long destringid);\nvoid __sanitizer_syscall_post_impl_add_key(long res, long _type,\n                                           long _description, long _payload,\n                                           long plen, long destringid);\nvoid __sanitizer_syscall_pre_impl_request_key(long _type, long _description,\n                                              long _callout_info,\n                                              long destringid);\nvoid __sanitizer_syscall_post_impl_request_key(long res, long _type,\n                                               long _description,\n                                               long _callout_info,\n                                               long destringid);\nvoid __sanitizer_syscall_pre_impl_keyctl(long cmd, long arg2, long arg3,\n                                         long arg4, long arg5);\nvoid __sanitizer_syscall_post_impl_keyctl(long res, long cmd, long arg2,\n                                          long arg3, long arg4, long arg5);\nvoid __sanitizer_syscall_pre_impl_ioprio_set(long which, long who, long ioprio);\nvoid __sanitizer_syscall_post_impl_ioprio_set(long res, long which, long who,\n                                              long ioprio);\nvoid __sanitizer_syscall_pre_impl_ioprio_get(long which, long who);\nvoid __sanitizer_syscall_post_impl_ioprio_get(long res, long which, long who);\nvoid __sanitizer_syscall_pre_impl_set_mempolicy(long mode, long nmask,\n                                                long maxnode);\nvoid __sanitizer_syscall_post_impl_set_mempolicy(long res, long mode,\n                                                 long nmask, long maxnode);\nvoid __sanitizer_syscall_pre_impl_migrate_pages(long pid, long maxnode,\n                                                long from, long to);\nvoid __sanitizer_syscall_post_impl_migrate_pages(long res, long pid,\n                                                 long maxnode, long from,\n                                                 long to);\nvoid __sanitizer_syscall_pre_impl_move_pages(long pid, long nr_pages,\n                                             long pages, long nodes,\n                                             long status, long flags);\nvoid __sanitizer_syscall_post_impl_move_pages(long res, long pid, long nr_pages,\n                                              long pages, long nodes,\n                                              long status, long flags);\nvoid __sanitizer_syscall_pre_impl_mbind(long start, long len, long mode,\n                                        long nmask, long maxnode, long flags);\nvoid __sanitizer_syscall_post_impl_mbind(long res, long start, long len,\n                                         long mode, long nmask, long maxnode,\n                                         long flags);\nvoid __sanitizer_syscall_pre_impl_get_mempolicy(long policy, long nmask,\n                                                long maxnode, long addr,\n                                                long flags);\nvoid __sanitizer_syscall_post_impl_get_mempolicy(long res, long policy,\n                                                 long nmask, long maxnode,\n                                                 long addr, long flags);\nvoid __sanitizer_syscall_pre_impl_inotify_init();\nvoid __sanitizer_syscall_post_impl_inotify_init(long res);\nvoid __sanitizer_syscall_pre_impl_inotify_init1(long flags);\nvoid __sanitizer_syscall_post_impl_inotify_init1(long res, long flags);\nvoid __sanitizer_syscall_pre_impl_inotify_add_watch(long fd, long path,\n                                                    long mask);\nvoid __sanitizer_syscall_post_impl_inotify_add_watch(long res, long fd,\n                                                     long path, long mask);\nvoid __sanitizer_syscall_pre_impl_inotify_rm_watch(long fd, long wd);\nvoid __sanitizer_syscall_post_impl_inotify_rm_watch(long res, long fd, long wd);\nvoid __sanitizer_syscall_pre_impl_spu_run(long fd, long unpc, long ustatus);\nvoid __sanitizer_syscall_post_impl_spu_run(long res, long fd, long unpc,\n                                           long ustatus);\nvoid __sanitizer_syscall_pre_impl_spu_create(long name, long flags, long mode,\n                                             long fd);\nvoid __sanitizer_syscall_post_impl_spu_create(long res, long name, long flags,\n                                              long mode, long fd);\nvoid __sanitizer_syscall_pre_impl_mknodat(long dfd, long filename, long mode,\n                                          long dev);\nvoid __sanitizer_syscall_post_impl_mknodat(long res, long dfd, long filename,\n                                           long mode, long dev);\nvoid __sanitizer_syscall_pre_impl_mkdirat(long dfd, long pathname, long mode);\nvoid __sanitizer_syscall_post_impl_mkdirat(long res, long dfd, long pathname,\n                                           long mode);\nvoid __sanitizer_syscall_pre_impl_unlinkat(long dfd, long pathname, long flag);\nvoid __sanitizer_syscall_post_impl_unlinkat(long res, long dfd, long pathname,\n                                            long flag);\nvoid __sanitizer_syscall_pre_impl_symlinkat(long oldname, long newdfd,\n                                            long newname);\nvoid __sanitizer_syscall_post_impl_symlinkat(long res, long oldname,\n                                             long newdfd, long newname);\nvoid __sanitizer_syscall_pre_impl_linkat(long olddfd, long oldname, long newdfd,\n                                         long newname, long flags);\nvoid __sanitizer_syscall_post_impl_linkat(long res, long olddfd, long oldname,\n                                          long newdfd, long newname,\n                                          long flags);\nvoid __sanitizer_syscall_pre_impl_renameat(long olddfd, long oldname,\n                                           long newdfd, long newname);\nvoid __sanitizer_syscall_post_impl_renameat(long res, long olddfd, long oldname,\n                                            long newdfd, long newname);\nvoid __sanitizer_syscall_pre_impl_futimesat(long dfd, long filename,\n                                            long utimes);\nvoid __sanitizer_syscall_post_impl_futimesat(long res, long dfd, long filename,\n                                             long utimes);\nvoid __sanitizer_syscall_pre_impl_faccessat(long dfd, long filename, long mode);\nvoid __sanitizer_syscall_post_impl_faccessat(long res, long dfd, long filename,\n                                             long mode);\nvoid __sanitizer_syscall_pre_impl_fchmodat(long dfd, long filename, long mode);\nvoid __sanitizer_syscall_post_impl_fchmodat(long res, long dfd, long filename,\n                                            long mode);\nvoid __sanitizer_syscall_pre_impl_fchownat(long dfd, long filename, long user,\n                                           long group, long flag);\nvoid __sanitizer_syscall_post_impl_fchownat(long res, long dfd, long filename,\n                                            long user, long group, long flag);\nvoid __sanitizer_syscall_pre_impl_openat(long dfd, long filename, long flags,\n                                         long mode);\nvoid __sanitizer_syscall_post_impl_openat(long res, long dfd, long filename,\n                                          long flags, long mode);\nvoid __sanitizer_syscall_pre_impl_newfstatat(long dfd, long filename,\n                                             long statbuf, long flag);\nvoid __sanitizer_syscall_post_impl_newfstatat(long res, long dfd, long filename,\n                                              long statbuf, long flag);\nvoid __sanitizer_syscall_pre_impl_fstatat64(long dfd, long filename,\n                                            long statbuf, long flag);\nvoid __sanitizer_syscall_post_impl_fstatat64(long res, long dfd, long filename,\n                                             long statbuf, long flag);\nvoid __sanitizer_syscall_pre_impl_readlinkat(long dfd, long path, long buf,\n                                             long bufsiz);\nvoid __sanitizer_syscall_post_impl_readlinkat(long res, long dfd, long path,\n                                              long buf, long bufsiz);\nvoid __sanitizer_syscall_pre_impl_utimensat(long dfd, long filename,\n                                            long utimes, long flags);\nvoid __sanitizer_syscall_post_impl_utimensat(long res, long dfd, long filename,\n                                             long utimes, long flags);\nvoid __sanitizer_syscall_pre_impl_unshare(long unshare_flags);\nvoid __sanitizer_syscall_post_impl_unshare(long res, long unshare_flags);\nvoid __sanitizer_syscall_pre_impl_splice(long fd_in, long off_in, long fd_out,\n                                         long off_out, long len, long flags);\nvoid __sanitizer_syscall_post_impl_splice(long res, long fd_in, long off_in,\n                                          long fd_out, long off_out, long len,\n                                          long flags);\nvoid __sanitizer_syscall_pre_impl_vmsplice(long fd, long iov, long nr_segs,\n                                           long flags);\nvoid __sanitizer_syscall_post_impl_vmsplice(long res, long fd, long iov,\n                                            long nr_segs, long flags);\nvoid __sanitizer_syscall_pre_impl_tee(long fdin, long fdout, long len,\n                                      long flags);\nvoid __sanitizer_syscall_post_impl_tee(long res, long fdin, long fdout,\n                                       long len, long flags);\nvoid __sanitizer_syscall_pre_impl_get_robust_list(long pid, long head_ptr,\n                                                  long len_ptr);\nvoid __sanitizer_syscall_post_impl_get_robust_list(long res, long pid,\n                                                   long head_ptr, long len_ptr);\nvoid __sanitizer_syscall_pre_impl_set_robust_list(long head, long len);\nvoid __sanitizer_syscall_post_impl_set_robust_list(long res, long head,\n                                                   long len);\nvoid __sanitizer_syscall_pre_impl_getcpu(long cpu, long node, long cache);\nvoid __sanitizer_syscall_post_impl_getcpu(long res, long cpu, long node,\n                                          long cache);\nvoid __sanitizer_syscall_pre_impl_signalfd(long ufd, long user_mask,\n                                           long sizemask);\nvoid __sanitizer_syscall_post_impl_signalfd(long res, long ufd, long user_mask,\n                                            long sizemask);\nvoid __sanitizer_syscall_pre_impl_signalfd4(long ufd, long user_mask,\n                                            long sizemask, long flags);\nvoid __sanitizer_syscall_post_impl_signalfd4(long res, long ufd, long user_mask,\n                                             long sizemask, long flags);\nvoid __sanitizer_syscall_pre_impl_timerfd_create(long clockid, long flags);\nvoid __sanitizer_syscall_post_impl_timerfd_create(long res, long clockid,\n                                                  long flags);\nvoid __sanitizer_syscall_pre_impl_timerfd_settime(long ufd, long flags,\n                                                  long utmr, long otmr);\nvoid __sanitizer_syscall_post_impl_timerfd_settime(long res, long ufd,\n                                                   long flags, long utmr,\n                                                   long otmr);\nvoid __sanitizer_syscall_pre_impl_timerfd_gettime(long ufd, long otmr);\nvoid __sanitizer_syscall_post_impl_timerfd_gettime(long res, long ufd,\n                                                   long otmr);\nvoid __sanitizer_syscall_pre_impl_eventfd(long count);\nvoid __sanitizer_syscall_post_impl_eventfd(long res, long count);\nvoid __sanitizer_syscall_pre_impl_eventfd2(long count, long flags);\nvoid __sanitizer_syscall_post_impl_eventfd2(long res, long count, long flags);\nvoid __sanitizer_syscall_pre_impl_old_readdir(long arg0, long arg1, long arg2);\nvoid __sanitizer_syscall_post_impl_old_readdir(long res, long arg0, long arg1,\n                                               long arg2);\nvoid __sanitizer_syscall_pre_impl_pselect6(long arg0, long arg1, long arg2,\n                                           long arg3, long arg4, long arg5);\nvoid __sanitizer_syscall_post_impl_pselect6(long res, long arg0, long arg1,\n                                            long arg2, long arg3, long arg4,\n                                            long arg5);\nvoid __sanitizer_syscall_pre_impl_ppoll(long arg0, long arg1, long arg2,\n                                        long arg3, long arg4);\nvoid __sanitizer_syscall_post_impl_ppoll(long res, long arg0, long arg1,\n                                         long arg2, long arg3, long arg4);\nvoid __sanitizer_syscall_pre_impl_fanotify_init(long flags, long event_f_flags);\nvoid __sanitizer_syscall_post_impl_fanotify_init(long res, long flags,\n                                                 long event_f_flags);\nvoid __sanitizer_syscall_pre_impl_fanotify_mark(long fanotify_fd, long flags,\n                                                long mask, long fd,\n                                                long pathname);\nvoid __sanitizer_syscall_post_impl_fanotify_mark(long res, long fanotify_fd,\n                                                 long flags, long mask, long fd,\n                                                 long pathname);\nvoid __sanitizer_syscall_pre_impl_syncfs(long fd);\nvoid __sanitizer_syscall_post_impl_syncfs(long res, long fd);\nvoid __sanitizer_syscall_pre_impl_perf_event_open(long attr_uptr, long pid,\n                                                  long cpu, long group_fd,\n                                                  long flags);\nvoid __sanitizer_syscall_post_impl_perf_event_open(long res, long attr_uptr,\n                                                   long pid, long cpu,\n                                                   long group_fd, long flags);\nvoid __sanitizer_syscall_pre_impl_mmap_pgoff(long addr, long len, long prot,\n                                             long flags, long fd, long pgoff);\nvoid __sanitizer_syscall_post_impl_mmap_pgoff(long res, long addr, long len,\n                                              long prot, long flags, long fd,\n                                              long pgoff);\nvoid __sanitizer_syscall_pre_impl_old_mmap(long arg);\nvoid __sanitizer_syscall_post_impl_old_mmap(long res, long arg);\nvoid __sanitizer_syscall_pre_impl_name_to_handle_at(long dfd, long name,\n                                                    long handle, long mnt_id,\n                                                    long flag);\nvoid __sanitizer_syscall_post_impl_name_to_handle_at(long res, long dfd,\n                                                     long name, long handle,\n                                                     long mnt_id, long flag);\nvoid __sanitizer_syscall_pre_impl_open_by_handle_at(long mountdirfd,\n                                                    long handle, long flags);\nvoid __sanitizer_syscall_post_impl_open_by_handle_at(long res, long mountdirfd,\n                                                     long handle, long flags);\nvoid __sanitizer_syscall_pre_impl_setns(long fd, long nstype);\nvoid __sanitizer_syscall_post_impl_setns(long res, long fd, long nstype);\nvoid __sanitizer_syscall_pre_impl_process_vm_readv(long pid, long lvec,\n                                                   long liovcnt, long rvec,\n                                                   long riovcnt, long flags);\nvoid __sanitizer_syscall_post_impl_process_vm_readv(long res, long pid,\n                                                    long lvec, long liovcnt,\n                                                    long rvec, long riovcnt,\n                                                    long flags);\nvoid __sanitizer_syscall_pre_impl_process_vm_writev(long pid, long lvec,\n                                                    long liovcnt, long rvec,\n                                                    long riovcnt, long flags);\nvoid __sanitizer_syscall_post_impl_process_vm_writev(long res, long pid,\n                                                     long lvec, long liovcnt,\n                                                     long rvec, long riovcnt,\n                                                     long flags);\nvoid __sanitizer_syscall_pre_impl_fork();\nvoid __sanitizer_syscall_post_impl_fork(long res);\nvoid __sanitizer_syscall_pre_impl_vfork();\nvoid __sanitizer_syscall_post_impl_vfork(long res);\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#endif  // SANITIZER_LINUX_SYSCALL_HOOKS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/include/sanitizer/lsan_interface.h",
    "content": "//===-- sanitizer/lsan_interface.h ------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of LeakSanitizer.\n//\n// Public interface header.\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_LSAN_INTERFACE_H\n#define SANITIZER_LSAN_INTERFACE_H\n\n#include <sanitizer/common_interface_defs.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n  // Allocations made between calls to __lsan_disable() and __lsan_enable() will\n  // be treated as non-leaks. Disable/enable pairs may be nested.\n  void __lsan_disable();\n  void __lsan_enable();\n\n  // The heap object into which p points will be treated as a non-leak.\n  void __lsan_ignore_object(const void *p);\n\n  // Memory regions registered through this interface will be treated as sources\n  // of live pointers during leak checking. Useful if you store pointers in\n  // mapped memory.\n  // Points of note:\n  // - __lsan_unregister_root_region() must be called with the same pointer and\n  // size that have earlier been passed to __lsan_register_root_region()\n  // - LSan will skip any inaccessible memory when scanning a root region. E.g.,\n  // if you map memory within a larger region that you have mprotect'ed, you can\n  // register the entire large region.\n  // - the implementation is not optimized for performance. This interface is\n  // intended to be used for a small number of relatively static regions.\n  void __lsan_register_root_region(const void *p, size_t size);\n  void __lsan_unregister_root_region(const void *p, size_t size);\n\n  // Check for leaks now. This function behaves identically to the default\n  // end-of-process leak check. In particular, it will terminate the process if\n  // leaks are found and the exitcode runtime flag is non-zero.\n  // Subsequent calls to this function will have no effect and end-of-process\n  // leak check will not run. Effectively, end-of-process leak check is moved to\n  // the time of first invocation of this function.\n  // By calling this function early during process shutdown, you can instruct\n  // LSan to ignore shutdown-only leaks which happen later on.\n  void __lsan_do_leak_check();\n\n  // Check for leaks now. Returns zero if no leaks have been found or if leak\n  // detection is disabled, non-zero otherwise.\n  // This function may be called repeatedly, e.g. to periodically check a\n  // long-running process. It prints a leak report if appropriate, but does not\n  // terminate the process. It does not affect the behavior of\n  // __lsan_do_leak_check() or the end-of-process leak check, and is not\n  // affected by them.\n  int __lsan_do_recoverable_leak_check();\n\n  // The user may optionally provide this function to disallow leak checking\n  // for the program it is linked into (if the return value is non-zero). This\n  // function must be defined as returning a constant value; any behavior beyond\n  // that is unsupported.\n  int __lsan_is_turned_off();\n\n  // This function may be optionally provided by the user and should return\n  // a string containing LSan suppressions.\n  const char *__lsan_default_suppressions();\n#ifdef __cplusplus\n}  // extern \"C\"\n\nnamespace __lsan {\nclass ScopedDisabler {\n public:\n  ScopedDisabler() { __lsan_disable(); }\n  ~ScopedDisabler() { __lsan_enable(); }\n};\n}  // namespace __lsan\n#endif\n\n#endif  // SANITIZER_LSAN_INTERFACE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/include/sanitizer/msan_interface.h",
    "content": "//===-- msan_interface.h --------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n// Public interface header.\n//===----------------------------------------------------------------------===//\n#ifndef MSAN_INTERFACE_H\n#define MSAN_INTERFACE_H\n\n#include <sanitizer/common_interface_defs.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n  /* Set raw origin for the memory range. */\n  void __msan_set_origin(const volatile void *a, size_t size, uint32_t origin);\n\n  /* Get raw origin for an address. */\n  uint32_t __msan_get_origin(const volatile void *a);\n\n  /* Test that this_id is a descendant of prev_id (or they are simply equal).\n   * \"descendant\" here means they are part of the same chain, created with\n   * __msan_chain_origin. */\n  int __msan_origin_is_descendant_or_same(uint32_t this_id, uint32_t prev_id);\n\n  /* Returns non-zero if tracking origins. */\n  int __msan_get_track_origins();\n\n  /* Returns the origin id of the latest UMR in the calling thread. */\n  uint32_t __msan_get_umr_origin();\n\n  /* Make memory region fully initialized (without changing its contents). */\n  void __msan_unpoison(const volatile void *a, size_t size);\n\n  /* Make a null-terminated string fully initialized (without changing its\n     contents). */\n  void __msan_unpoison_string(const volatile char *a);\n\n  /* Make memory region fully uninitialized (without changing its contents).\n     This is a legacy interface that does not update origin information. Use\n     __msan_allocated_memory() instead. */\n  void __msan_poison(const volatile void *a, size_t size);\n\n  /* Make memory region partially uninitialized (without changing its contents).\n   */\n  void __msan_partial_poison(const volatile void *data, void *shadow,\n                             size_t size);\n\n  /* Returns the offset of the first (at least partially) poisoned byte in the\n     memory range, or -1 if the whole range is good. */\n  intptr_t __msan_test_shadow(const volatile void *x, size_t size);\n\n  /* Checks that memory range is fully initialized, and reports an error if it\n   * is not. */\n  void __msan_check_mem_is_initialized(const volatile void *x, size_t size);\n\n  /* For testing:\n     __msan_set_expect_umr(1);\n     ... some buggy code ...\n     __msan_set_expect_umr(0);\n     The last line will verify that a UMR happened. */\n  void __msan_set_expect_umr(int expect_umr);\n\n  /* Change the value of keep_going flag. Non-zero value means don't terminate\n     program execution when an error is detected. This will not affect error in\n     modules that were compiled without the corresponding compiler flag. */\n  void __msan_set_keep_going(int keep_going);\n\n  /* Print shadow and origin for the memory range to stderr in a human-readable\n     format. */\n  void __msan_print_shadow(const volatile void *x, size_t size);\n\n  /* Print shadow for the memory range to stderr in a minimalistic\n     human-readable format. */\n  void __msan_dump_shadow(const volatile void *x, size_t size);\n\n  /* Returns true if running under a dynamic tool (DynamoRio-based). */\n  int  __msan_has_dynamic_component();\n\n  /* Tell MSan about newly allocated memory (ex.: custom allocator).\n     Memory will be marked uninitialized, with origin at the call site. */\n  void __msan_allocated_memory(const volatile void* data, size_t size);\n\n  /* Tell MSan about newly destroyed memory. Mark memory as uninitialized. */\n  void __sanitizer_dtor_callback(const volatile void* data, size_t size);\n\n  /* This function may be optionally provided by user and should return\n     a string containing Msan runtime options. See msan_flags.h for details. */\n  const char* __msan_default_options();\n\n  /* Deprecated. Call __sanitizer_set_death_callback instead. */\n  void __msan_set_death_callback(void (*callback)(void));\n\n  /* Update shadow for the application copy of size bytes from src to dst.\n     Src and dst are application addresses. This function does not copy the\n     actual application memory, it only updates shadow and origin for such\n     copy. Source and destination regions can overlap. */\n  void __msan_copy_shadow(const volatile void *dst, const volatile void *src,\n                          size_t size);\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/include/sanitizer/tsan_interface_atomic.h",
    "content": "//===-- tsan_interface_atomic.h ---------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Public interface header for TSan atomics.\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_INTERFACE_ATOMIC_H\n#define TSAN_INTERFACE_ATOMIC_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef char     __tsan_atomic8;\ntypedef short    __tsan_atomic16;  // NOLINT\ntypedef int      __tsan_atomic32;\ntypedef long     __tsan_atomic64;  // NOLINT\n#if defined(__SIZEOF_INT128__) \\\n    || (__clang_major__ * 100 + __clang_minor__ >= 302)\n__extension__ typedef __int128 __tsan_atomic128;\n# define __TSAN_HAS_INT128 1\n#else\n# define __TSAN_HAS_INT128 0\n#endif\n\n// Part of ABI, do not change.\n// http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/atomic?view=markup\ntypedef enum {\n  __tsan_memory_order_relaxed,\n  __tsan_memory_order_consume,\n  __tsan_memory_order_acquire,\n  __tsan_memory_order_release,\n  __tsan_memory_order_acq_rel,\n  __tsan_memory_order_seq_cst\n} __tsan_memory_order;\n\n__tsan_atomic8 __tsan_atomic8_load(const volatile __tsan_atomic8 *a,\n    __tsan_memory_order mo);\n__tsan_atomic16 __tsan_atomic16_load(const volatile __tsan_atomic16 *a,\n    __tsan_memory_order mo);\n__tsan_atomic32 __tsan_atomic32_load(const volatile __tsan_atomic32 *a,\n    __tsan_memory_order mo);\n__tsan_atomic64 __tsan_atomic64_load(const volatile __tsan_atomic64 *a,\n    __tsan_memory_order mo);\n#if __TSAN_HAS_INT128\n__tsan_atomic128 __tsan_atomic128_load(const volatile __tsan_atomic128 *a,\n    __tsan_memory_order mo);\n#endif\n\nvoid __tsan_atomic8_store(volatile __tsan_atomic8 *a, __tsan_atomic8 v,\n    __tsan_memory_order mo);\nvoid __tsan_atomic16_store(volatile __tsan_atomic16 *a, __tsan_atomic16 v,\n    __tsan_memory_order mo);\nvoid __tsan_atomic32_store(volatile __tsan_atomic32 *a, __tsan_atomic32 v,\n    __tsan_memory_order mo);\nvoid __tsan_atomic64_store(volatile __tsan_atomic64 *a, __tsan_atomic64 v,\n    __tsan_memory_order mo);\n#if __TSAN_HAS_INT128\nvoid __tsan_atomic128_store(volatile __tsan_atomic128 *a, __tsan_atomic128 v,\n    __tsan_memory_order mo);\n#endif\n\n__tsan_atomic8 __tsan_atomic8_exchange(volatile __tsan_atomic8 *a,\n    __tsan_atomic8 v, __tsan_memory_order mo);\n__tsan_atomic16 __tsan_atomic16_exchange(volatile __tsan_atomic16 *a,\n    __tsan_atomic16 v, __tsan_memory_order mo);\n__tsan_atomic32 __tsan_atomic32_exchange(volatile __tsan_atomic32 *a,\n    __tsan_atomic32 v, __tsan_memory_order mo);\n__tsan_atomic64 __tsan_atomic64_exchange(volatile __tsan_atomic64 *a,\n    __tsan_atomic64 v, __tsan_memory_order mo);\n#if __TSAN_HAS_INT128\n__tsan_atomic128 __tsan_atomic128_exchange(volatile __tsan_atomic128 *a,\n    __tsan_atomic128 v, __tsan_memory_order mo);\n#endif\n\n__tsan_atomic8 __tsan_atomic8_fetch_add(volatile __tsan_atomic8 *a,\n    __tsan_atomic8 v, __tsan_memory_order mo);\n__tsan_atomic16 __tsan_atomic16_fetch_add(volatile __tsan_atomic16 *a,\n    __tsan_atomic16 v, __tsan_memory_order mo);\n__tsan_atomic32 __tsan_atomic32_fetch_add(volatile __tsan_atomic32 *a,\n    __tsan_atomic32 v, __tsan_memory_order mo);\n__tsan_atomic64 __tsan_atomic64_fetch_add(volatile __tsan_atomic64 *a,\n    __tsan_atomic64 v, __tsan_memory_order mo);\n#if __TSAN_HAS_INT128\n__tsan_atomic128 __tsan_atomic128_fetch_add(volatile __tsan_atomic128 *a,\n    __tsan_atomic128 v, __tsan_memory_order mo);\n#endif\n\n__tsan_atomic8 __tsan_atomic8_fetch_sub(volatile __tsan_atomic8 *a,\n    __tsan_atomic8 v, __tsan_memory_order mo);\n__tsan_atomic16 __tsan_atomic16_fetch_sub(volatile __tsan_atomic16 *a,\n    __tsan_atomic16 v, __tsan_memory_order mo);\n__tsan_atomic32 __tsan_atomic32_fetch_sub(volatile __tsan_atomic32 *a,\n    __tsan_atomic32 v, __tsan_memory_order mo);\n__tsan_atomic64 __tsan_atomic64_fetch_sub(volatile __tsan_atomic64 *a,\n    __tsan_atomic64 v, __tsan_memory_order mo);\n#if __TSAN_HAS_INT128\n__tsan_atomic128 __tsan_atomic128_fetch_sub(volatile __tsan_atomic128 *a,\n    __tsan_atomic128 v, __tsan_memory_order mo);\n#endif\n\n__tsan_atomic8 __tsan_atomic8_fetch_and(volatile __tsan_atomic8 *a,\n    __tsan_atomic8 v, __tsan_memory_order mo);\n__tsan_atomic16 __tsan_atomic16_fetch_and(volatile __tsan_atomic16 *a,\n    __tsan_atomic16 v, __tsan_memory_order mo);\n__tsan_atomic32 __tsan_atomic32_fetch_and(volatile __tsan_atomic32 *a,\n    __tsan_atomic32 v, __tsan_memory_order mo);\n__tsan_atomic64 __tsan_atomic64_fetch_and(volatile __tsan_atomic64 *a,\n    __tsan_atomic64 v, __tsan_memory_order mo);\n#if __TSAN_HAS_INT128\n__tsan_atomic128 __tsan_atomic128_fetch_and(volatile __tsan_atomic128 *a,\n    __tsan_atomic128 v, __tsan_memory_order mo);\n#endif\n\n__tsan_atomic8 __tsan_atomic8_fetch_or(volatile __tsan_atomic8 *a,\n    __tsan_atomic8 v, __tsan_memory_order mo);\n__tsan_atomic16 __tsan_atomic16_fetch_or(volatile __tsan_atomic16 *a,\n    __tsan_atomic16 v, __tsan_memory_order mo);\n__tsan_atomic32 __tsan_atomic32_fetch_or(volatile __tsan_atomic32 *a,\n    __tsan_atomic32 v, __tsan_memory_order mo);\n__tsan_atomic64 __tsan_atomic64_fetch_or(volatile __tsan_atomic64 *a,\n    __tsan_atomic64 v, __tsan_memory_order mo);\n#if __TSAN_HAS_INT128\n__tsan_atomic128 __tsan_atomic128_fetch_or(volatile __tsan_atomic128 *a,\n    __tsan_atomic128 v, __tsan_memory_order mo);\n#endif\n\n__tsan_atomic8 __tsan_atomic8_fetch_xor(volatile __tsan_atomic8 *a,\n    __tsan_atomic8 v, __tsan_memory_order mo);\n__tsan_atomic16 __tsan_atomic16_fetch_xor(volatile __tsan_atomic16 *a,\n    __tsan_atomic16 v, __tsan_memory_order mo);\n__tsan_atomic32 __tsan_atomic32_fetch_xor(volatile __tsan_atomic32 *a,\n    __tsan_atomic32 v, __tsan_memory_order mo);\n__tsan_atomic64 __tsan_atomic64_fetch_xor(volatile __tsan_atomic64 *a,\n    __tsan_atomic64 v, __tsan_memory_order mo);\n#if __TSAN_HAS_INT128\n__tsan_atomic128 __tsan_atomic128_fetch_xor(volatile __tsan_atomic128 *a,\n    __tsan_atomic128 v, __tsan_memory_order mo);\n#endif\n\n__tsan_atomic8 __tsan_atomic8_fetch_nand(volatile __tsan_atomic8 *a,\n    __tsan_atomic8 v, __tsan_memory_order mo);\n__tsan_atomic16 __tsan_atomic16_fetch_nand(volatile __tsan_atomic16 *a,\n    __tsan_atomic16 v, __tsan_memory_order mo);\n__tsan_atomic32 __tsan_atomic32_fetch_nand(volatile __tsan_atomic32 *a,\n    __tsan_atomic32 v, __tsan_memory_order mo);\n__tsan_atomic64 __tsan_atomic64_fetch_nand(volatile __tsan_atomic64 *a,\n    __tsan_atomic64 v, __tsan_memory_order mo);\n#if __TSAN_HAS_INT128\n__tsan_atomic128 __tsan_atomic128_fetch_nand(volatile __tsan_atomic128 *a,\n    __tsan_atomic128 v, __tsan_memory_order mo);\n#endif\n\nint __tsan_atomic8_compare_exchange_weak(volatile __tsan_atomic8 *a,\n    __tsan_atomic8 *c, __tsan_atomic8 v, __tsan_memory_order mo,\n    __tsan_memory_order fail_mo);\nint __tsan_atomic16_compare_exchange_weak(volatile __tsan_atomic16 *a,\n    __tsan_atomic16 *c, __tsan_atomic16 v, __tsan_memory_order mo,\n    __tsan_memory_order fail_mo);\nint __tsan_atomic32_compare_exchange_weak(volatile __tsan_atomic32 *a,\n    __tsan_atomic32 *c, __tsan_atomic32 v, __tsan_memory_order mo,\n    __tsan_memory_order fail_mo);\nint __tsan_atomic64_compare_exchange_weak(volatile __tsan_atomic64 *a,\n    __tsan_atomic64 *c, __tsan_atomic64 v, __tsan_memory_order mo,\n    __tsan_memory_order fail_mo);\n#if __TSAN_HAS_INT128\nint __tsan_atomic128_compare_exchange_weak(volatile __tsan_atomic128 *a,\n    __tsan_atomic128 *c, __tsan_atomic128 v, __tsan_memory_order mo,\n    __tsan_memory_order fail_mo);\n#endif\n\nint __tsan_atomic8_compare_exchange_strong(volatile __tsan_atomic8 *a,\n    __tsan_atomic8 *c, __tsan_atomic8 v, __tsan_memory_order mo,\n    __tsan_memory_order fail_mo);\nint __tsan_atomic16_compare_exchange_strong(volatile __tsan_atomic16 *a,\n    __tsan_atomic16 *c, __tsan_atomic16 v, __tsan_memory_order mo,\n    __tsan_memory_order fail_mo);\nint __tsan_atomic32_compare_exchange_strong(volatile __tsan_atomic32 *a,\n    __tsan_atomic32 *c, __tsan_atomic32 v, __tsan_memory_order mo,\n    __tsan_memory_order fail_mo);\nint __tsan_atomic64_compare_exchange_strong(volatile __tsan_atomic64 *a,\n    __tsan_atomic64 *c, __tsan_atomic64 v, __tsan_memory_order mo,\n    __tsan_memory_order fail_mo);\n#if __TSAN_HAS_INT128\nint __tsan_atomic128_compare_exchange_strong(volatile __tsan_atomic128 *a,\n    __tsan_atomic128 *c, __tsan_atomic128 v, __tsan_memory_order mo,\n    __tsan_memory_order fail_mo);\n#endif\n\n__tsan_atomic8 __tsan_atomic8_compare_exchange_val(\n    volatile __tsan_atomic8 *a, __tsan_atomic8 c, __tsan_atomic8 v,\n    __tsan_memory_order mo, __tsan_memory_order fail_mo);\n__tsan_atomic16 __tsan_atomic16_compare_exchange_val(\n    volatile __tsan_atomic16 *a, __tsan_atomic16 c, __tsan_atomic16 v,\n    __tsan_memory_order mo, __tsan_memory_order fail_mo);\n__tsan_atomic32 __tsan_atomic32_compare_exchange_val(\n    volatile __tsan_atomic32 *a, __tsan_atomic32 c, __tsan_atomic32 v,\n    __tsan_memory_order mo, __tsan_memory_order fail_mo);\n__tsan_atomic64 __tsan_atomic64_compare_exchange_val(\n    volatile __tsan_atomic64 *a, __tsan_atomic64 c, __tsan_atomic64 v,\n    __tsan_memory_order mo, __tsan_memory_order fail_mo);\n#if __TSAN_HAS_INT128\n__tsan_atomic128 __tsan_atomic128_compare_exchange_val(\n    volatile __tsan_atomic128 *a, __tsan_atomic128 c, __tsan_atomic128 v,\n    __tsan_memory_order mo, __tsan_memory_order fail_mo);\n#endif\n\nvoid __tsan_atomic_thread_fence(__tsan_memory_order mo);\nvoid __tsan_atomic_signal_fence(__tsan_memory_order mo);\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#endif  // TSAN_INTERFACE_ATOMIC_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/BlocksRuntime/Block.h",
    "content": "/*\n * Block.h\n *\n * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge,\n * to any person obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without restriction,\n * including without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to permit\n * persons to whom the Software is furnished to do so, subject to the following\n * conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n */\n\n#ifndef _BLOCK_H_\n#define _BLOCK_H_\n\n#if !defined(BLOCK_EXPORT)\n#   if defined(__cplusplus)\n#       define BLOCK_EXPORT extern \"C\" \n#   else\n#       define BLOCK_EXPORT extern\n#   endif\n#endif\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/* Create a heap based copy of a Block or simply add a reference to an existing one.\n * This must be paired with Block_release to recover memory, even when running\n * under Objective-C Garbage Collection.\n */\nBLOCK_EXPORT void *_Block_copy(const void *aBlock);\n\n/* Lose the reference, and if heap based and last reference, recover the memory. */\nBLOCK_EXPORT void _Block_release(const void *aBlock);\n\n#if defined(__cplusplus)\n}\n#endif\n\n/* Type correct macros. */\n\n#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))\n#define Block_release(...) _Block_release((const void *)(__VA_ARGS__))\n\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/BlocksRuntime/Block_private.h",
    "content": "/*\n * Block_private.h\n *\n * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge,\n * to any person obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without restriction,\n * including without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to permit\n * persons to whom the Software is furnished to do so, subject to the following\n * conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n */\n\n#ifndef _BLOCK_PRIVATE_H_\n#define _BLOCK_PRIVATE_H_\n\n#if !defined(BLOCK_EXPORT)\n#   if defined(__cplusplus)\n#       define BLOCK_EXPORT extern \"C\" \n#   else\n#       define BLOCK_EXPORT extern\n#   endif\n#endif\n\n#ifndef _MSC_VER\n#include <stdbool.h>\n#else\n/* MSVC doesn't have <stdbool.h>. Compensate. */\ntypedef char bool;\n#define true (bool)1\n#define false (bool)0\n#endif\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n\nenum {\n    BLOCK_REFCOUNT_MASK =     (0xffff),\n    BLOCK_NEEDS_FREE =        (1 << 24),\n    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),\n    BLOCK_HAS_CTOR =          (1 << 26), /* Helpers have C++ code. */\n    BLOCK_IS_GC =             (1 << 27),\n    BLOCK_IS_GLOBAL =         (1 << 28),\n    BLOCK_HAS_DESCRIPTOR =    (1 << 29)\n};\n\n\n/* Revised new layout. */\nstruct Block_descriptor {\n    unsigned long int reserved;\n    unsigned long int size;\n    void (*copy)(void *dst, void *src);\n    void (*dispose)(void *);\n};\n\n\nstruct Block_layout {\n    void *isa;\n    int flags;\n    int reserved; \n    void (*invoke)(void *, ...);\n    struct Block_descriptor *descriptor;\n    /* Imported variables. */\n};\n\n\nstruct Block_byref {\n    void *isa;\n    struct Block_byref *forwarding;\n    int flags; /* refcount; */\n    int size;\n    void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src);\n    void (*byref_destroy)(struct Block_byref *);\n    /* long shared[0]; */\n};\n\n\nstruct Block_byref_header {\n    void *isa;\n    struct Block_byref *forwarding;\n    int flags;\n    int size;\n};\n\n\n/* Runtime support functions used by compiler when generating copy/dispose helpers. */\n\nenum {\n    /* See function implementation for a more complete description of these fields and combinations */\n    BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)), block, ... */\n    BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */\n    BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the __block variable */\n    BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy helpers */\n    BLOCK_BYREF_CALLER      = 128  /* called from __block (byref) copy/dispose support routines. */\n};\n\n/* Runtime entry point called by compiler when assigning objects inside copy helper routines */\nBLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags);\n    /* BLOCK_FIELD_IS_BYREF is only used from within block copy helpers */\n\n\n/* runtime entry point called by the compiler when disposing of objects inside dispose helper routine */\nBLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags);\n\n\n\n/* Other support functions */\n\n/* Runtime entry to get total size of a closure */\nBLOCK_EXPORT unsigned long int Block_size(void *block_basic);\n\n\n\n/* the raw data space for runtime classes for blocks */\n/* class+meta used for stack, malloc, and collectable based blocks */\nBLOCK_EXPORT void * _NSConcreteStackBlock[32];\nBLOCK_EXPORT void * _NSConcreteMallocBlock[32];\nBLOCK_EXPORT void * _NSConcreteAutoBlock[32];\nBLOCK_EXPORT void * _NSConcreteFinalizingBlock[32];\nBLOCK_EXPORT void * _NSConcreteGlobalBlock[32];\nBLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32];\n\n\n/* the intercept routines that must be used under GC */\nBLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),\n                                  void (*setHasRefcount)(const void *, const bool),\n                                  void (*gc_assign_strong)(void *, void **),\n                                  void (*gc_assign_weak)(const void *, void *),\n                                  void (*gc_memmove)(void *, void *, unsigned long));\n\n/* earlier version, now simply transitional */\nBLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),\n                                  void (*setHasRefcount)(const void *, const bool),\n                                  void (*gc_assign_strong)(void *, void **),\n                                  void (*gc_assign_weak)(const void *, void *));\n\nBLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *),\n                                 void (*release)(const void *));\n\n/* make a collectable GC heap based Block.  Not useful under non-GC. */\nBLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock);\n\n/* thread-unsafe diagnostic */\nBLOCK_EXPORT const char *_Block_dump(const void *block);\n\n\n/* Obsolete */\n\n/* first layout */\nstruct Block_basic {\n    void *isa;\n    int Block_flags;  /* int32_t */\n    int Block_size;  /* XXX should be packed into Block_flags */\n    void (*Block_invoke)(void *);\n    void (*Block_copy)(void *dst, void *src);  /* iff BLOCK_HAS_COPY_DISPOSE */\n    void (*Block_dispose)(void *);             /* iff BLOCK_HAS_COPY_DISPOSE */\n    /* long params[0];  // where const imports, __block storage references, etc. get laid down */\n};\n\n\n#if defined(__cplusplus)\n}\n#endif\n\n\n#endif /* _BLOCK_PRIVATE_H_ */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/BlocksRuntime/data.c",
    "content": "/*\n * data.c\n *\n * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge,\n * to any person obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without restriction,\n * including without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to permit\n * persons to whom the Software is furnished to do so, subject to the following\n * conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n */\n\n/********************\nNSBlock support\n\nWe allocate space and export a symbol to be used as the Class for the on-stack and malloc'ed copies until ObjC arrives on the scene.  These data areas are set up by Foundation to link in as real classes post facto.\n\nWe keep these in a separate file so that we can include the runtime code in test subprojects but not include the data so that compiled code that sees the data in libSystem doesn't get confused by a second copy.  Somehow these don't get unified in a common block.\n**********************/\n\nvoid * _NSConcreteStackBlock[32] = { 0 };\nvoid * _NSConcreteMallocBlock[32] = { 0 };\nvoid * _NSConcreteAutoBlock[32] = { 0 };\nvoid * _NSConcreteFinalizingBlock[32] = { 0 };\nvoid * _NSConcreteGlobalBlock[32] = { 0 };\nvoid * _NSConcreteWeakBlockVariable[32] = { 0 };\n\nvoid _Block_copy_error(void) {\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/BlocksRuntime/runtime.c",
    "content": "/*\n * runtime.c\n *\n * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge,\n * to any person obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without restriction,\n * including without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to permit\n * persons to whom the Software is furnished to do so, subject to the following\n * conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n */\n\n#include \"Block_private.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n\n#include \"config.h\"\n\n#ifdef HAVE_AVAILABILITY_MACROS_H\n#include <AvailabilityMacros.h>\n#endif /* HAVE_AVAILABILITY_MACROS_H */\n\n#ifdef HAVE_TARGET_CONDITIONALS_H\n#include <TargetConditionals.h>\n#endif /* HAVE_TARGET_CONDITIONALS_H */\n\n#if defined(HAVE_OSATOMIC_COMPARE_AND_SWAP_INT) && defined(HAVE_OSATOMIC_COMPARE_AND_SWAP_LONG)\n\n#ifdef HAVE_LIBKERN_OSATOMIC_H\n#include <libkern/OSAtomic.h>\n#endif /* HAVE_LIBKERN_OSATOMIC_H */\n\n#elif defined(__WIN32__) || defined(_WIN32)\n#define _CRT_SECURE_NO_WARNINGS 1\n#include <windows.h>\n\nstatic __inline bool OSAtomicCompareAndSwapLong(long oldl, long newl, long volatile *dst) {\n    /* fixme barrier is overkill -- see objc-os.h */\n    long original = InterlockedCompareExchange(dst, newl, oldl);\n    return (original == oldl);\n}\n\nstatic __inline bool OSAtomicCompareAndSwapInt(int oldi, int newi, int volatile *dst) {\n    /* fixme barrier is overkill -- see objc-os.h */\n    int original = InterlockedCompareExchange(dst, newi, oldi);\n    return (original == oldi);\n}\n\n/*\n * Check to see if the GCC atomic built-ins are available.  If we're on\n * a 64-bit system, make sure we have an 8-byte atomic function\n * available.\n *\n */\n\n#elif defined(HAVE_SYNC_BOOL_COMPARE_AND_SWAP_INT) && defined(HAVE_SYNC_BOOL_COMPARE_AND_SWAP_LONG)\n\nstatic __inline bool OSAtomicCompareAndSwapLong(long oldl, long newl, long volatile *dst) {\n  return __sync_bool_compare_and_swap(dst, oldl, newl);\n}\n\nstatic __inline bool OSAtomicCompareAndSwapInt(int oldi, int newi, int volatile *dst) {\n  return __sync_bool_compare_and_swap(dst, oldi, newi);\n}\n\n#else\n#error unknown atomic compare-and-swap primitive\n#endif /* HAVE_OSATOMIC_COMPARE_AND_SWAP_INT && HAVE_OSATOMIC_COMPARE_AND_SWAP_LONG */\n\n\n/*\n * Globals:\n */\n\nstatic void *_Block_copy_class = _NSConcreteMallocBlock;\nstatic void *_Block_copy_finalizing_class = _NSConcreteMallocBlock;\nstatic int _Block_copy_flag = BLOCK_NEEDS_FREE;\nstatic int _Byref_flag_initial_value = BLOCK_NEEDS_FREE | 2;\n\nstatic const int WANTS_ONE = (1 << 16);\n\nstatic bool isGC = false;\n\n/*\n * Internal Utilities:\n */\n\n#if 0\nstatic unsigned long int latching_incr_long(unsigned long int *where) {\n    while (1) {\n        unsigned long int old_value = *(volatile unsigned long int *)where;\n        if ((old_value & BLOCK_REFCOUNT_MASK) == BLOCK_REFCOUNT_MASK) {\n            return BLOCK_REFCOUNT_MASK;\n        }\n        if (OSAtomicCompareAndSwapLong(old_value, old_value+1, (volatile long int *)where)) {\n            return old_value+1;\n        }\n    }\n}\n#endif /* if 0 */\n\nstatic int latching_incr_int(int *where) {\n    while (1) {\n        int old_value = *(volatile int *)where;\n        if ((old_value & BLOCK_REFCOUNT_MASK) == BLOCK_REFCOUNT_MASK) {\n            return BLOCK_REFCOUNT_MASK;\n        }\n        if (OSAtomicCompareAndSwapInt(old_value, old_value+1, (volatile int *)where)) {\n            return old_value+1;\n        }\n    }\n}\n\n#if 0\nstatic int latching_decr_long(unsigned long int *where) {\n    while (1) {\n        unsigned long int old_value = *(volatile int *)where;\n        if ((old_value & BLOCK_REFCOUNT_MASK) == BLOCK_REFCOUNT_MASK) {\n            return BLOCK_REFCOUNT_MASK;\n        }\n        if ((old_value & BLOCK_REFCOUNT_MASK) == 0) {\n            return 0;\n        }\n        if (OSAtomicCompareAndSwapLong(old_value, old_value-1, (volatile long int *)where)) {\n            return old_value-1;\n        }\n    }\n}\n#endif /* if 0 */\n\nstatic int latching_decr_int(int *where) {\n    while (1) {\n        int old_value = *(volatile int *)where;\n        if ((old_value & BLOCK_REFCOUNT_MASK) == BLOCK_REFCOUNT_MASK) {\n            return BLOCK_REFCOUNT_MASK;\n        }\n        if ((old_value & BLOCK_REFCOUNT_MASK) == 0) {\n            return 0;\n        }\n        if (OSAtomicCompareAndSwapInt(old_value, old_value-1, (volatile int *)where)) {\n            return old_value-1;\n        }\n    }\n}\n\n\n/*\n * GC support stub routines:\n */\n#if 0\n#pragma mark GC Support Routines\n#endif /* if 0 */\n\n\nstatic void *_Block_alloc_default(const unsigned long size, const bool initialCountIsOne, const bool isObject) {\n    return malloc(size);\n}\n\nstatic void _Block_assign_default(void *value, void **destptr) {\n    *destptr = value;\n}\n\nstatic void _Block_setHasRefcount_default(const void *ptr, const bool hasRefcount) {\n}\n\nstatic void _Block_do_nothing(const void *aBlock) { }\n\nstatic void _Block_retain_object_default(const void *ptr) {\n    if (!ptr) return;\n}\n\nstatic void _Block_release_object_default(const void *ptr) {\n    if (!ptr) return;\n}\n\nstatic void _Block_assign_weak_default(const void *ptr, void *dest) {\n    *(void **)dest = (void *)ptr;\n}\n\nstatic void _Block_memmove_default(void *dst, void *src, unsigned long size) {\n    memmove(dst, src, (size_t)size);\n}\n\nstatic void _Block_memmove_gc_broken(void *dest, void *src, unsigned long size) {\n    void **destp = (void **)dest;\n    void **srcp = (void **)src;\n    while (size) {\n        _Block_assign_default(*srcp, destp);\n        destp++;\n        srcp++;\n        size -= sizeof(void *);\n    }\n}\n\n/*\n * GC support callout functions - initially set to stub routines:\n */\n\nstatic void *(*_Block_allocator)(const unsigned long, const bool isOne, const bool isObject) = _Block_alloc_default;\nstatic void (*_Block_deallocator)(const void *) = (void (*)(const void *))free;\nstatic void (*_Block_assign)(void *value, void **destptr) = _Block_assign_default;\nstatic void (*_Block_setHasRefcount)(const void *ptr, const bool hasRefcount) = _Block_setHasRefcount_default;\nstatic void (*_Block_retain_object)(const void *ptr) = _Block_retain_object_default;\nstatic void (*_Block_release_object)(const void *ptr) = _Block_release_object_default;\nstatic void (*_Block_assign_weak)(const void *dest, void *ptr) = _Block_assign_weak_default;\nstatic void (*_Block_memmove)(void *dest, void *src, unsigned long size) = _Block_memmove_default;\n\n\n/*\n * GC support SPI functions - called from ObjC runtime and CoreFoundation:\n */\n\n/* Public SPI\n * Called from objc-auto to turn on GC.\n * version 3, 4 arg, but changed 1st arg\n */\nvoid _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),\n                    void (*setHasRefcount)(const void *, const bool),\n                    void (*gc_assign)(void *, void **),\n                    void (*gc_assign_weak)(const void *, void *),\n                    void (*gc_memmove)(void *, void *, unsigned long)) {\n\n    isGC = true;\n    _Block_allocator = alloc;\n    _Block_deallocator = _Block_do_nothing;\n    _Block_assign = gc_assign;\n    _Block_copy_flag = BLOCK_IS_GC;\n    _Block_copy_class = _NSConcreteAutoBlock;\n    /* blocks with ctors & dtors need to have the dtor run from a class with a finalizer */\n    _Block_copy_finalizing_class = _NSConcreteFinalizingBlock;\n    _Block_setHasRefcount = setHasRefcount;\n    _Byref_flag_initial_value = BLOCK_IS_GC;   // no refcount\n    _Block_retain_object = _Block_do_nothing;\n    _Block_release_object = _Block_do_nothing;\n    _Block_assign_weak = gc_assign_weak;\n    _Block_memmove = gc_memmove;\n}\n\n/* transitional */\nvoid _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),\n                    void (*setHasRefcount)(const void *, const bool),\n                    void (*gc_assign)(void *, void **),\n                    void (*gc_assign_weak)(const void *, void *)) {\n    /* until objc calls _Block_use_GC it will call us; supply a broken internal memmove implementation until then */\n    _Block_use_GC(alloc, setHasRefcount, gc_assign, gc_assign_weak, _Block_memmove_gc_broken);\n}\n\n \n/*\n * Called from objc-auto to alternatively turn on retain/release.\n * Prior to this the only \"object\" support we can provide is for those\n * super special objects that live in libSystem, namely dispatch queues.\n * Blocks and Block_byrefs have their own special entry points.\n *\n */\nvoid _Block_use_RR( void (*retain)(const void *),\n                    void (*release)(const void *)) {\n    _Block_retain_object = retain;\n    _Block_release_object = release;\n}\n\n/*\n * Internal Support routines for copying:\n */\n\n#if 0\n#pragma mark Copy/Release support\n#endif /* if 0 */\n\n/* Copy, or bump refcount, of a block.  If really copying, call the copy helper if present. */\nstatic void *_Block_copy_internal(const void *arg, const int flags) {\n    struct Block_layout *aBlock;\n    const bool wantsOne = (WANTS_ONE & flags) == WANTS_ONE;\n\n    //printf(\"_Block_copy_internal(%p, %x)\\n\", arg, flags);\t\n    if (!arg) return NULL;\n    \n    \n    // The following would be better done as a switch statement\n    aBlock = (struct Block_layout *)arg;\n    if (aBlock->flags & BLOCK_NEEDS_FREE) {\n        // latches on high\n        latching_incr_int(&aBlock->flags);\n        return aBlock;\n    }\n    else if (aBlock->flags & BLOCK_IS_GC) {\n        // GC refcounting is expensive so do most refcounting here.\n        if (wantsOne && ((latching_incr_int(&aBlock->flags) & BLOCK_REFCOUNT_MASK) == 1)) {\n            // Tell collector to hang on this - it will bump the GC refcount version\n            _Block_setHasRefcount(aBlock, true);\n        }\n        return aBlock;\n    }\n    else if (aBlock->flags & BLOCK_IS_GLOBAL) {\n        return aBlock;\n    }\n\n    // Its a stack block.  Make a copy.\n    if (!isGC) {\n        struct Block_layout *result = malloc(aBlock->descriptor->size);\n        if (!result) return (void *)0;\n        memmove(result, aBlock, aBlock->descriptor->size); // bitcopy first\n        // reset refcount\n        result->flags &= ~(BLOCK_REFCOUNT_MASK);    // XXX not needed\n        result->flags |= BLOCK_NEEDS_FREE | 1;\n        result->isa = _NSConcreteMallocBlock;\n        if (result->flags & BLOCK_HAS_COPY_DISPOSE) {\n            //printf(\"calling block copy helper %p(%p, %p)...\\n\", aBlock->descriptor->copy, result, aBlock);\n            (*aBlock->descriptor->copy)(result, aBlock); // do fixup\n        }\n        return result;\n    }\n    else {\n        // Under GC want allocation with refcount 1 so we ask for \"true\" if wantsOne\n        // This allows the copy helper routines to make non-refcounted block copies under GC\n        unsigned long int flags = aBlock->flags;\n        bool hasCTOR = (flags & BLOCK_HAS_CTOR) != 0;\n        struct Block_layout *result = _Block_allocator(aBlock->descriptor->size, wantsOne, hasCTOR);\n        if (!result) return (void *)0;\n        memmove(result, aBlock, aBlock->descriptor->size); // bitcopy first\n        // reset refcount\n        // if we copy a malloc block to a GC block then we need to clear NEEDS_FREE.\n        flags &= ~(BLOCK_NEEDS_FREE|BLOCK_REFCOUNT_MASK);   // XXX not needed\n        if (wantsOne)\n            flags |= BLOCK_IS_GC | 1;\n        else\n            flags |= BLOCK_IS_GC;\n        result->flags = flags;\n        if (flags & BLOCK_HAS_COPY_DISPOSE) {\n            //printf(\"calling block copy helper...\\n\");\n            (*aBlock->descriptor->copy)(result, aBlock); // do fixup\n        }\n        if (hasCTOR) {\n            result->isa = _NSConcreteFinalizingBlock;\n        }\n        else {\n            result->isa = _NSConcreteAutoBlock;\n        }\n        return result;\n    }\n}\n\n\n/*\n * Runtime entry points for maintaining the sharing knowledge of byref data blocks.\n *\n * A closure has been copied and its fixup routine is asking us to fix up the reference to the shared byref data\n * Closures that aren't copied must still work, so everyone always accesses variables after dereferencing the forwarding ptr.\n * We ask if the byref pointer that we know about has already been copied to the heap, and if so, increment it.\n * Otherwise we need to copy it and update the stack forwarding pointer\n * XXX We need to account for weak/nonretained read-write barriers.\n */\n\nstatic void _Block_byref_assign_copy(void *dest, const void *arg, const int flags) {\n    struct Block_byref **destp = (struct Block_byref **)dest;\n    struct Block_byref *src = (struct Block_byref *)arg;\n        \n    //printf(\"_Block_byref_assign_copy called, byref destp %p, src %p, flags %x\\n\", destp, src, flags);\n    //printf(\"src dump: %s\\n\", _Block_byref_dump(src));\n    if (src->forwarding->flags & BLOCK_IS_GC) {\n        ;   // don't need to do any more work\n    }\n    else if ((src->forwarding->flags & BLOCK_REFCOUNT_MASK) == 0) {\n        //printf(\"making copy\\n\");\n        // src points to stack\n        bool isWeak = ((flags & (BLOCK_FIELD_IS_BYREF|BLOCK_FIELD_IS_WEAK)) == (BLOCK_FIELD_IS_BYREF|BLOCK_FIELD_IS_WEAK));\n        // if its weak ask for an object (only matters under GC)\n        struct Block_byref *copy = (struct Block_byref *)_Block_allocator(src->size, false, isWeak);\n        copy->flags = src->flags | _Byref_flag_initial_value; // non-GC one for caller, one for stack\n        copy->forwarding = copy; // patch heap copy to point to itself (skip write-barrier)\n        src->forwarding = copy;  // patch stack to point to heap copy\n        copy->size = src->size;\n        if (isWeak) {\n            copy->isa = &_NSConcreteWeakBlockVariable;  // mark isa field so it gets weak scanning\n        }\n        if (src->flags & BLOCK_HAS_COPY_DISPOSE) {\n            // Trust copy helper to copy everything of interest\n            // If more than one field shows up in a byref block this is wrong XXX\n            copy->byref_keep = src->byref_keep;\n            copy->byref_destroy = src->byref_destroy;\n            (*src->byref_keep)(copy, src);\n        }\n        else {\n            // just bits.  Blast 'em using _Block_memmove in case they're __strong\n            _Block_memmove(\n                (void *)&copy->byref_keep,\n                (void *)&src->byref_keep,\n                src->size - sizeof(struct Block_byref_header));\n        }\n    }\n    // already copied to heap\n    else if ((src->forwarding->flags & BLOCK_NEEDS_FREE) == BLOCK_NEEDS_FREE) {\n        latching_incr_int(&src->forwarding->flags);\n    }\n    // assign byref data block pointer into new Block\n    _Block_assign(src->forwarding, (void **)destp);\n}\n\n// Old compiler SPI\nstatic void _Block_byref_release(const void *arg) {\n    struct Block_byref *shared_struct = (struct Block_byref *)arg;\n    int refcount;\n\n    // dereference the forwarding pointer since the compiler isn't doing this anymore (ever?)\n    shared_struct = shared_struct->forwarding;\n    \n    //printf(\"_Block_byref_release %p called, flags are %x\\n\", shared_struct, shared_struct->flags);\n    // To support C++ destructors under GC we arrange for there to be a finalizer for this\n    // by using an isa that directs the code to a finalizer that calls the byref_destroy method.\n    if ((shared_struct->flags & BLOCK_NEEDS_FREE) == 0) {\n        return; // stack or GC or global\n    }\n    refcount = shared_struct->flags & BLOCK_REFCOUNT_MASK;\n    if (refcount <= 0) {\n        printf(\"_Block_byref_release: Block byref data structure at %p underflowed\\n\", arg);\n    }\n    else if ((latching_decr_int(&shared_struct->flags) & BLOCK_REFCOUNT_MASK) == 0) {\n        //printf(\"disposing of heap based byref block\\n\");\n        if (shared_struct->flags & BLOCK_HAS_COPY_DISPOSE) {\n            //printf(\"calling out to helper\\n\");\n            (*shared_struct->byref_destroy)(shared_struct);\n        }\n        _Block_deallocator((struct Block_layout *)shared_struct);\n    }\n}\n\n\n/*\n *\n * API supporting SPI\n * _Block_copy, _Block_release, and (old) _Block_destroy\n *\n */\n\n#if 0\n#pragma mark SPI/API\n#endif /* if 0 */\n\nvoid *_Block_copy(const void *arg) {\n    return _Block_copy_internal(arg, WANTS_ONE);\n}\n\n\n// API entry point to release a copied Block\nvoid _Block_release(void *arg) {\n    struct Block_layout *aBlock = (struct Block_layout *)arg;\n    int32_t newCount;\n    if (!aBlock) return;\n    newCount = latching_decr_int(&aBlock->flags) & BLOCK_REFCOUNT_MASK;\n    if (newCount > 0) return;\n    // Hit zero\n    if (aBlock->flags & BLOCK_IS_GC) {\n        // Tell GC we no longer have our own refcounts.  GC will decr its refcount\n        // and unless someone has done a CFRetain or marked it uncollectable it will\n        // now be subject to GC reclamation.\n        _Block_setHasRefcount(aBlock, false);\n    }\n    else if (aBlock->flags & BLOCK_NEEDS_FREE) {\n        if (aBlock->flags & BLOCK_HAS_COPY_DISPOSE)(*aBlock->descriptor->dispose)(aBlock);\n        _Block_deallocator(aBlock);\n    }\n    else if (aBlock->flags & BLOCK_IS_GLOBAL) {\n        ;\n    }\n    else {\n        printf(\"Block_release called upon a stack Block: %p, ignored\\n\", (void *)aBlock);\n    }\n}\n\n\n\n// Old Compiler SPI point to release a copied Block used by the compiler in dispose helpers\nstatic void _Block_destroy(const void *arg) {\n    struct Block_layout *aBlock;\n    if (!arg) return;\n    aBlock = (struct Block_layout *)arg;\n    if (aBlock->flags & BLOCK_IS_GC) {\n        // assert(aBlock->Block_flags & BLOCK_HAS_CTOR);\n        return; // ignore, we are being called because of a DTOR\n    }\n    _Block_release(aBlock);\n}\n\n\n\n/*\n *\n * SPI used by other layers\n *\n */\n\n// SPI, also internal.  Called from NSAutoBlock only under GC\nvoid *_Block_copy_collectable(const void *aBlock) {\n    return _Block_copy_internal(aBlock, 0);\n}\n\n\n// SPI\nunsigned long int Block_size(void *arg) {\n    return ((struct Block_layout *)arg)->descriptor->size;\n}\n\n\n#if 0\n#pragma mark Compiler SPI entry points\n#endif /* if 0 */\n\n    \n/*******************************************************\n\nEntry points used by the compiler - the real API!\n\n\nA Block can reference four different kinds of things that require help when the Block is copied to the heap.\n1) C++ stack based objects\n2) References to Objective-C objects\n3) Other Blocks\n4) __block variables\n\nIn these cases helper functions are synthesized by the compiler for use in Block_copy and Block_release, called the copy and dispose helpers.  The copy helper emits a call to the C++ const copy constructor for C++ stack based objects and for the rest calls into the runtime support function _Block_object_assign.  The dispose helper has a call to the C++ destructor for case 1 and a call into _Block_object_dispose for the rest.\n\nThe flags parameter of _Block_object_assign and _Block_object_dispose is set to\n\t* BLOCK_FIELD_IS_OBJECT (3), for the case of an Objective-C Object,\n\t* BLOCK_FIELD_IS_BLOCK (7), for the case of another Block, and\n\t* BLOCK_FIELD_IS_BYREF (8), for the case of a __block variable.\nIf the __block variable is marked weak the compiler also or's in BLOCK_FIELD_IS_WEAK (16).\n\nSo the Block copy/dispose helpers should only ever generate the four flag values of 3, 7, 8, and 24.\n\nWhen  a __block variable is either a C++ object, an Objective-C object, or another Block then the compiler also generates copy/dispose helper functions.  Similarly to the Block copy helper, the \"__block\" copy helper (formerly and still a.k.a. \"byref\" copy helper) will do a C++ copy constructor (not a const one though!) and the dispose helper will do the destructor.  And similarly the helpers will call into the same two support functions with the same values for objects and Blocks with the additional BLOCK_BYREF_CALLER (128) bit of information supplied.\n\nSo the __block copy/dispose helpers will generate flag values of 3 or 7 for objects and Blocks respectively, with BLOCK_FIELD_IS_WEAK (16) or'ed as appropriate and always 128 or'd in, for the following set of possibilities:\n\t__block id                   128+3\n        __weak block id              128+3+16\n\t__block (^Block)             128+7\n\t__weak __block (^Block)      128+7+16\n        \nThe implementation of the two routines would be improved by switch statements enumerating the eight cases.\n\n********************************************************/\n\n/*\n * When Blocks or Block_byrefs hold objects then their copy routine helpers use this entry point\n * to do the assignment.\n */\nvoid _Block_object_assign(void *destAddr, const void *object, const int flags) {\n    //printf(\"_Block_object_assign(*%p, %p, %x)\\n\", destAddr, object, flags);\n    if ((flags & BLOCK_BYREF_CALLER) == BLOCK_BYREF_CALLER) {\n        if ((flags & BLOCK_FIELD_IS_WEAK) == BLOCK_FIELD_IS_WEAK) {\n            _Block_assign_weak(object, destAddr);\n        }\n        else {\n            // do *not* retain or *copy* __block variables whatever they are\n            _Block_assign((void *)object, destAddr);\n        }\n    }\n    else if ((flags & BLOCK_FIELD_IS_BYREF) == BLOCK_FIELD_IS_BYREF)  {\n        // copying a __block reference from the stack Block to the heap\n        // flags will indicate if it holds a __weak reference and needs a special isa\n        _Block_byref_assign_copy(destAddr, object, flags);\n    }\n    // (this test must be before next one)\n    else if ((flags & BLOCK_FIELD_IS_BLOCK) == BLOCK_FIELD_IS_BLOCK) {\n        // copying a Block declared variable from the stack Block to the heap\n        _Block_assign(_Block_copy_internal(object, flags), destAddr);\n    }\n    // (this test must be after previous one)\n    else if ((flags & BLOCK_FIELD_IS_OBJECT) == BLOCK_FIELD_IS_OBJECT) {\n        //printf(\"retaining object at %p\\n\", object);\n        _Block_retain_object(object);\n        //printf(\"done retaining object at %p\\n\", object);\n        _Block_assign((void *)object, destAddr);\n    }\n}\n\n// When Blocks or Block_byrefs hold objects their destroy helper routines call this entry point\n// to help dispose of the contents\n// Used initially only for __attribute__((NSObject)) marked pointers.\nvoid _Block_object_dispose(const void *object, const int flags) {\n    //printf(\"_Block_object_dispose(%p, %x)\\n\", object, flags);\n    if (flags & BLOCK_FIELD_IS_BYREF)  {\n        // get rid of the __block data structure held in a Block\n        _Block_byref_release(object);\n    }\n    else if ((flags & (BLOCK_FIELD_IS_BLOCK|BLOCK_BYREF_CALLER)) == BLOCK_FIELD_IS_BLOCK) {\n        // get rid of a referenced Block held by this Block\n        // (ignore __block Block variables, compiler doesn't need to call us)\n        _Block_destroy(object);\n    }\n    else if ((flags & (BLOCK_FIELD_IS_WEAK|BLOCK_FIELD_IS_BLOCK|BLOCK_BYREF_CALLER)) == BLOCK_FIELD_IS_OBJECT) {\n        // get rid of a referenced object held by this Block\n        // (ignore __block object variables, compiler doesn't need to call us)\n        _Block_release_object(object);\n    }\n}\n\n\n/*\n * Debugging support:\n */\n#if 0\n#pragma mark Debugging\n#endif /* if 0 */\n\n\nconst char *_Block_dump(const void *block) {\n    struct Block_layout *closure = (struct Block_layout *)block;\n    static char buffer[512];\n    char *cp = buffer;\n    if (closure == NULL) {\n        sprintf(cp, \"NULL passed to _Block_dump\\n\");\n        return buffer;\n    }\n    if (! (closure->flags & BLOCK_HAS_DESCRIPTOR)) {\n        printf(\"Block compiled by obsolete compiler, please recompile source for this Block\\n\");\n        exit(1);\n    }\n    cp += sprintf(cp, \"^%p (new layout) =\\n\", (void *)closure);\n    if (closure->isa == NULL) {\n        cp += sprintf(cp, \"isa: NULL\\n\");\n    }\n    else if (closure->isa == _NSConcreteStackBlock) {\n        cp += sprintf(cp, \"isa: stack Block\\n\");\n    }\n    else if (closure->isa == _NSConcreteMallocBlock) {\n        cp += sprintf(cp, \"isa: malloc heap Block\\n\");\n    }\n    else if (closure->isa == _NSConcreteAutoBlock) {\n        cp += sprintf(cp, \"isa: GC heap Block\\n\");\n    }\n    else if (closure->isa == _NSConcreteGlobalBlock) {\n        cp += sprintf(cp, \"isa: global Block\\n\");\n    }\n    else if (closure->isa == _NSConcreteFinalizingBlock) {\n        cp += sprintf(cp, \"isa: finalizing Block\\n\");\n    }\n    else {\n        cp += sprintf(cp, \"isa?: %p\\n\", (void *)closure->isa);\n    }\n    cp += sprintf(cp, \"flags:\");\n    if (closure->flags & BLOCK_HAS_DESCRIPTOR) {\n        cp += sprintf(cp, \" HASDESCRIPTOR\");\n    }\n    if (closure->flags & BLOCK_NEEDS_FREE) {\n        cp += sprintf(cp, \" FREEME\");\n    }\n    if (closure->flags & BLOCK_IS_GC) {\n        cp += sprintf(cp, \" ISGC\");\n    }\n    if (closure->flags & BLOCK_HAS_COPY_DISPOSE) {\n        cp += sprintf(cp, \" HASHELP\");\n    }\n    if (closure->flags & BLOCK_HAS_CTOR) {\n        cp += sprintf(cp, \" HASCTOR\");\n    }\n    cp += sprintf(cp, \"\\nrefcount: %u\\n\", closure->flags & BLOCK_REFCOUNT_MASK);\n    cp += sprintf(cp, \"invoke: %p\\n\", (void *)(uintptr_t)closure->invoke);\n    {\n        struct Block_descriptor *dp = closure->descriptor;\n        cp += sprintf(cp, \"descriptor: %p\\n\", (void *)dp);\n        cp += sprintf(cp, \"descriptor->reserved: %lu\\n\", dp->reserved);\n        cp += sprintf(cp, \"descriptor->size: %lu\\n\", dp->size);\n\n        if (closure->flags & BLOCK_HAS_COPY_DISPOSE) {\n            cp += sprintf(cp, \"descriptor->copy helper: %p\\n\", (void *)(uintptr_t)dp->copy);\n            cp += sprintf(cp, \"descriptor->dispose helper: %p\\n\", (void *)(uintptr_t)dp->dispose);\n        }\n    }\n    return buffer;\n}\n\n\nconst char *_Block_byref_dump(struct Block_byref *src) {\n    static char buffer[256];\n    char *cp = buffer;\n    cp += sprintf(cp, \"byref data block %p contents:\\n\", (void *)src);\n    cp += sprintf(cp, \"  forwarding: %p\\n\", (void *)src->forwarding);\n    cp += sprintf(cp, \"  flags: 0x%x\\n\", src->flags);\n    cp += sprintf(cp, \"  size: %d\\n\", src->size);\n    if (src->flags & BLOCK_HAS_COPY_DISPOSE) {\n        cp += sprintf(cp, \"  copy helper: %p\\n\", (void *)(uintptr_t)src->byref_keep);\n        cp += sprintf(cp, \"  dispose helper: %p\\n\", (void *)(uintptr_t)src->byref_destroy);\n    }\n    return buffer;\n}\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/CMakeLists.txt",
    "content": "# First, add the subdirectories which contain feature-based runtime libraries\n# and several convenience helper libraries.\n\ninclude(AddCompilerRT)\ninclude(SanitizerUtils)\n\nif(COMPILER_RT_BUILD_BUILTINS)\n  add_subdirectory(builtins)\nendif()\n\nif(COMPILER_RT_BUILD_SANITIZERS)\n  if(COMPILER_RT_HAS_INTERCEPTION)\n    add_subdirectory(interception)\n  endif()\n\n  if(COMPILER_RT_HAS_SANITIZER_COMMON)\n    add_subdirectory(sanitizer_common)\n    add_subdirectory(lsan)\n    add_subdirectory(ubsan)\n  endif()\n\n  if(COMPILER_RT_HAS_ASAN)\n    add_subdirectory(asan)\n  endif()\n\n  if(COMPILER_RT_HAS_DFSAN)\n    add_subdirectory(dfsan)\n  endif()\n\n  if(COMPILER_RT_HAS_MSAN)\n    add_subdirectory(msan)\n  endif()\n\n  if(COMPILER_RT_HAS_PROFILE)\n    add_subdirectory(profile)\n  endif()\n\n  if(COMPILER_RT_HAS_TSAN)\n    add_subdirectory(tsan)\n    add_subdirectory(tsan/dd)\n  endif()\n\n  if(COMPILER_RT_HAS_SAFESTACK)\n    add_subdirectory(safestack)\n  endif()\n\n  if(COMPILER_RT_HAS_CFI)\n    add_subdirectory(cfi)\n  endif()\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/Makefile.mk",
    "content": "#===- lib/Makefile.mk --------------------------------------*- Makefile -*--===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\nSubDirs :=\n\n# Add submodules.\nSubDirs += asan\nSubDirs += builtins\nSubDirs += interception\nSubDirs += lsan\nSubDirs += profile\nSubDirs += sanitizer_common\nSubDirs += ubsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/.clang-format",
    "content": "BasedOnStyle: Google\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/Android.mk",
    "content": "#\n# Copyright (C) 2012 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n#\n\nLOCAL_PATH:= $(call my-dir)\n\nASAN_NEEDS_SEGV=0\nASAN_HAS_EXCEPTIONS=1\nASAN_FLEXIBLE_MAPPING_AND_OFFSET=0\n\nasan_rtl_files := \\\n  asan_activation.cc \\\n  asan_allocator.cc \\\n  asan_fake_stack.cc \\\n  asan_flags.cc \\\n  asan_globals.cc \\\n  asan_interceptors.cc \\\n  asan_linux.cc \\\n  asan_mac.cc \\\n  asan_malloc_linux.cc \\\n  asan_malloc_mac.cc \\\n  asan_malloc_win.cc \\\n  asan_poisoning.cc \\\n  asan_posix.cc \\\n  asan_report.cc \\\n  asan_rtl.cc \\\n  asan_stack.cc \\\n  asan_stats.cc \\\n  asan_suppressions.cc \\\n  asan_thread.cc \\\n  asan_win.cc \\\n  ../interception/interception_linux.cc \\\n  ../lsan/lsan_common.cc \\\n  ../lsan/lsan_common_linux.cc \\\n  ../sanitizer_common/sanitizer_allocator.cc \\\n  ../sanitizer_common/sanitizer_common.cc \\\n  ../sanitizer_common/sanitizer_common_libcdep.cc \\\n  ../sanitizer_common/sanitizer_coverage_libcdep.cc \\\n  ../sanitizer_common/sanitizer_coverage_mapping_libcdep.cc \\\n  ../sanitizer_common/sanitizer_deadlock_detector1.cc \\\n  ../sanitizer_common/sanitizer_deadlock_detector2.cc \\\n  ../sanitizer_common/sanitizer_flags.cc \\\n  ../sanitizer_common/sanitizer_flag_parser.cc \\\n  ../sanitizer_common/sanitizer_libc.cc \\\n  ../sanitizer_common/sanitizer_libignore.cc \\\n  ../sanitizer_common/sanitizer_linux.cc \\\n  ../sanitizer_common/sanitizer_linux_libcdep.cc \\\n  ../sanitizer_common/sanitizer_mac.cc \\\n  ../sanitizer_common/sanitizer_persistent_allocator.cc \\\n  ../sanitizer_common/sanitizer_platform_limits_linux.cc \\\n  ../sanitizer_common/sanitizer_platform_limits_posix.cc \\\n  ../sanitizer_common/sanitizer_posix.cc \\\n  ../sanitizer_common/sanitizer_posix_libcdep.cc \\\n  ../sanitizer_common/sanitizer_printf.cc \\\n  ../sanitizer_common/sanitizer_procmaps_common.cc \\\n  ../sanitizer_common/sanitizer_procmaps_freebsd.cc \\\n  ../sanitizer_common/sanitizer_procmaps_linux.cc \\\n  ../sanitizer_common/sanitizer_procmaps_mac.cc \\\n  ../sanitizer_common/sanitizer_stackdepot.cc \\\n  ../sanitizer_common/sanitizer_stacktrace.cc \\\n  ../sanitizer_common/sanitizer_stacktrace_libcdep.cc \\\n  ../sanitizer_common/sanitizer_stacktrace_printer.cc \\\n  ../sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc \\\n  ../sanitizer_common/sanitizer_suppressions.cc \\\n  ../sanitizer_common/sanitizer_symbolizer.cc \\\n  ../sanitizer_common/sanitizer_symbolizer_libbacktrace.cc \\\n  ../sanitizer_common/sanitizer_symbolizer_libcdep.cc \\\n  ../sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc \\\n  ../sanitizer_common/sanitizer_symbolizer_win.cc \\\n  ../sanitizer_common/sanitizer_thread_registry.cc \\\n  ../sanitizer_common/sanitizer_tls_get_addr.cc \\\n  ../sanitizer_common/sanitizer_unwind_linux_libcdep.cc \\\n  ../sanitizer_common/sanitizer_win.cc \\\n\nasan_rtl_cxx_files := \\\n\tasan_new_delete.cc\t\\\n\nasan_rtl_cflags := \\\n\t-fvisibility=hidden \\\n\t-fno-exceptions \\\n\t-DASAN_LOW_MEMORY=1 \\\n\t-DASAN_NEEDS_SEGV=$(ASAN_NEEDS_SEGV) \\\n\t-DASAN_HAS_EXCEPTIONS=$(ASAN_HAS_EXCEPTIONS) \\\n\t-DASAN_FLEXIBLE_MAPPING_AND_OFFSET=$(ASAN_FLEXIBLE_MAPPING_AND_OFFSET) \\\n\t-Wno-covered-switch-default \\\n\t-Wno-non-virtual-dtor \\\n\t-Wno-sign-compare \\\n\t-Wno-unused-parameter \\\n\t-std=c++11 \\\n\t-fno-rtti \\\n\t-fno-builtin\n\nasan_test_files := \\\n\ttests/asan_globals_test.cc \\\n\ttests/asan_test.cc\n\n#tests/asan_noinst_test.cc \\\n#tests/asan_test_main.cc \\\n\nasan_test_cflags := \\\n\t-fsanitize-blacklist=external/compiler-rt/lib/asan/tests/asan_test.ignore \\\n\t-DASAN_LOW_MEMORY=1 \\\n\t-DASAN_UAR=0 \\\n\t-DASAN_NEEDS_SEGV=$(ASAN_NEEDS_SEGV) \\\n\t-DASAN_HAS_EXCEPTIONS=$(ASAN_HAS_EXCEPTIONS) \\\n\t-DASAN_HAS_BLACKLIST=1 \\\n\t-Wno-covered-switch-default \\\n\t-Wno-non-virtual-dtor \\\n\t-Wno-sign-compare \\\n\t-Wno-unused-parameter \\\n\t-std=c++11\n\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libasan\nLOCAL_C_INCLUDES := \\\n    external/compiler-rt/lib \\\n    external/compiler-rt/include\nLOCAL_CFLAGS += $(asan_rtl_cflags)\nLOCAL_SRC_FILES := asan_preinit.cc\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_CLANG := true\nLOCAL_SANITIZE := never\nLOCAL_MODULE_TARGET_ARCH := arm arm64 x86\nLOCAL_NDK_STL_VARIANT := none\nLOCAL_SDK_VERSION := 19\ninclude $(BUILD_STATIC_LIBRARY)\n\ndefine build-asan-rt-shared-library\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := $(1)\nLOCAL_MULTILIB := $(2)\n# This library must go on /system partition, even in SANITIZE_TARGET mode (when all libraries are\n# installed on /data). That's because /data may not be available until vold does some magic and\n# vold itself depends on this library.\nLOCAL_MODULE_PATH_32 := $(TARGET_OUT)/lib\nLOCAL_MODULE_PATH_64 := $(TARGET_OUT)/lib64\n# We need to unwind by frame pointers through a small portion of ASan runtime library code,\n# and that only works with ARM, not with Thumb.\nLOCAL_ARM_MODE := arm\nLOCAL_C_INCLUDES := \\\n  external/compiler-rt/lib \\\n  external/compiler-rt/include\nLOCAL_CFLAGS += $(asan_rtl_cflags)\nLOCAL_SRC_FILES := $(asan_rtl_files) $(asan_rtl_cxx_files)\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_LDLIBS := -llog -ldl\nLOCAL_STATIC_LIBRARIES := libubsan\n# MacOS toolchain is out-of-date and does not support -z global.\n# TODO: re-enable once the toolchain issue is fixed.\nifneq ($(HOST_OS),darwin)\n  LOCAL_LDFLAGS += -Wl,-z,global\nendif\nLOCAL_CLANG := true\nLOCAL_SANITIZE := never\nLOCAL_MODULE_TARGET_ARCH := arm arm64 x86\nLOCAL_NDK_STL_VARIANT := none\nLOCAL_SDK_VERSION := 19\ninclude $(BUILD_SHARED_LIBRARY)\n\nendef\n\nifeq (true,$(FORCE_BUILD_SANITIZER_SHARED_OBJECTS))\nifdef 2ND_ADDRESS_SANITIZER_RUNTIME_LIBRARY\n  $(eval $(call build-asan-rt-shared-library,$(ADDRESS_SANITIZER_RUNTIME_LIBRARY),64))\n  $(eval $(call build-asan-rt-shared-library,$(2ND_ADDRESS_SANITIZER_RUNTIME_LIBRARY),32))\nelse\n  $(eval $(call build-asan-rt-shared-library,$(ADDRESS_SANITIZER_RUNTIME_LIBRARY),32))\nendif\nendif\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := asanwrapper\nLOCAL_SRC_FILES := asanwrapper.cc\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_CPPFLAGS := -std=c++11\nLOCAL_SANITIZE := never\nLOCAL_MODULE_TARGET_ARCH := arm arm64 x86\nLOCAL_CXX_STL := libc++\n\ninclude $(BUILD_EXECUTABLE)\n\nifneq (true,$(SKIP_LLVM_TESTS))\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libasan_noinst_test\nLOCAL_MODULE_TAGS := tests\nLOCAL_C_INCLUDES := \\\n    external/gtest/include \\\n    external/compiler-rt/include \\\n    external/compiler-rt/lib \\\n    external/compiler-rt/lib/asan/tests \\\n    external/compiler-rt/lib/sanitizer_common/tests\nLOCAL_CFLAGS += \\\n    -Wno-non-virtual-dtor \\\n    -Wno-unused-parameter \\\n    -Wno-sign-compare \\\n    -DASAN_UAR=0 \\\n    -DASAN_HAS_BLACKLIST=1 \\\n    -DASAN_HAS_EXCEPTIONS=$(ASAN_HAS_EXCEPTIONS) \\\n    -DASAN_NEEDS_SEGV=$(ASAN_NEEDS_SEGV) \\\n    -std=c++11\nLOCAL_SRC_FILES := tests/asan_noinst_test.cc tests/asan_test_main.cc\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_CLANG := true\nLOCAL_SANITIZE := never\nLOCAL_MODULE_TARGET_ARCH := arm arm64 x86\nLOCAL_CXX_STL := libc++\n\ninclude $(BUILD_STATIC_LIBRARY)\n\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := asan_test\nLOCAL_MODULE_TAGS := tests\nLOCAL_C_INCLUDES := \\\n    external/gtest/include \\\n    external/compiler-rt/lib \\\n    external/compiler-rt/lib/asan/tests \\\n    external/compiler-rt/lib/sanitizer_common/tests\nLOCAL_CFLAGS += $(asan_test_cflags)\nLOCAL_SRC_FILES := $(asan_test_files)\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_STATIC_LIBRARIES := libgtest libasan_noinst_test\nLOCAL_SHARED_LIBRARIES := libc\nLOCAL_SANITIZE := address\nLOCAL_CLANG := true\nLOCAL_MODULE_TARGET_ARCH := arm arm64 x86\nLOCAL_CXX_STL := libc++\n\ninclude $(BUILD_EXECUTABLE)\n\nendif # SKIP_LLVM_TESTS\n\n################################################################################\n# Host modules\n\nifneq ($(HOST_OS),darwin)\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libasan\nLOCAL_C_INCLUDES := external/compiler-rt/lib external/compiler-rt/include\nLOCAL_CFLAGS += $(asan_rtl_cflags)\nLOCAL_SRC_FILES := $(asan_rtl_files)\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_CLANG := true\nLOCAL_MULTILIB := both\nLOCAL_SANITIZE := never\nLOCAL_WHOLE_STATIC_LIBRARIES := libubsan\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libasan_cxx\nLOCAL_C_INCLUDES := external/compiler-rt/lib external/compiler-rt/include\nLOCAL_CFLAGS += $(asan_rtl_cflags)\nLOCAL_SRC_FILES := $(asan_rtl_cxx_files)\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_CLANG := true\nLOCAL_MULTILIB := both\nLOCAL_SANITIZE := never\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\nifneq (true,$(SKIP_LLVM_TESTS))\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libasan_noinst_test\nLOCAL_MODULE_TAGS := tests\nLOCAL_C_INCLUDES := \\\n    external/gtest/include \\\n    external/compiler-rt/include \\\n    external/compiler-rt/lib \\\n    external/compiler-rt/lib/asan/tests \\\n    external/compiler-rt/lib/sanitizer_common/tests\nLOCAL_CFLAGS += \\\n    -Wno-unused-parameter \\\n    -Wno-sign-compare \\\n    -DASAN_UAR=0 \\\n    -DASAN_HAS_BLACKLIST=1 \\\n    -DASAN_HAS_EXCEPTIONS=$(ASAN_HAS_EXCEPTIONS) \\\n    -DASAN_NEEDS_SEGV=$(ASAN_NEEDS_SEGV) \\\n    -std=c++11\nLOCAL_SRC_FILES := tests/asan_noinst_test.cc tests/asan_test_main.cc\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_CLANG := true\nLOCAL_CXX_STL := libc++\nLOCAL_MULTILIB := both\nLOCAL_SANITIZE := never\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := asan_test\nLOCAL_MODULE_TAGS := tests\nLOCAL_C_INCLUDES := \\\n    external/compiler-rt/lib \\\n    external/compiler-rt/lib/asan/tests \\\n    external/compiler-rt/lib/sanitizer_common/tests\nLOCAL_CFLAGS += $(asan_test_cflags)\nLOCAL_SRC_FILES := $(asan_test_files)\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_STATIC_LIBRARIES := libasan_noinst_test\nLOCAL_SANITIZE := address\nLOCAL_CLANG := true\nLOCAL_CXX_STL := libc++\nLOCAL_MULTILIB := both\nLOCAL_LDLIBS := -lrt\nLOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32\nLOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64\ninclude $(BUILD_HOST_NATIVE_TEST)\nendif # SKIP_LLVM_TESTS\nendif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/CMakeLists.txt",
    "content": "# Build for the AddressSanitizer runtime support library.\n\nset(ASAN_SOURCES\n  asan_allocator.cc\n  asan_activation.cc\n  asan_debugging.cc\n  asan_fake_stack.cc\n  asan_flags.cc\n  asan_globals.cc\n  asan_interceptors.cc\n  asan_linux.cc\n  asan_mac.cc\n  asan_malloc_linux.cc\n  asan_malloc_mac.cc\n  asan_malloc_win.cc\n  asan_poisoning.cc\n  asan_posix.cc\n  asan_report.cc\n  asan_rtl.cc\n  asan_stack.cc\n  asan_stats.cc\n  asan_suppressions.cc\n  asan_thread.cc\n  asan_win.cc)\n\nset(ASAN_CXX_SOURCES\n  asan_new_delete.cc)\n\nset(ASAN_PREINIT_SOURCES\n  asan_preinit.cc)\n\ninclude_directories(..)\n\nset(ASAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})\nappend_no_rtti_flag(ASAN_CFLAGS)\n\nset(ASAN_COMMON_DEFINITIONS\n  ASAN_HAS_EXCEPTIONS=1)\n\nset(ASAN_DYNAMIC_LINK_FLAGS)\n\nif(ANDROID)\n  list(APPEND ASAN_COMMON_DEFINITIONS\n    ASAN_LOW_MEMORY=1)\n# On Android, -z global does not do what it is documented to do.\n# On Android, -z global moves the library ahead in the lookup order,\n# placing it right after the LD_PRELOADs. This is used to compensate for the fact\n# that Android linker does not look at the dependencies of the main executable\n# that aren't dependencies of the current DSO when resolving symbols from said DSO.\n# As a net result, this allows running ASan executables without LD_PRELOAD-ing the\n# ASan runtime library.\n# The above is applicable to L MR1 or newer.\n  if (COMPILER_RT_HAS_Z_GLOBAL)\n    list(APPEND ASAN_DYNAMIC_LINK_FLAGS -Wl,-z,global)\n  endif()\nendif()\n\nset(ASAN_DYNAMIC_DEFINITIONS\n  ${ASAN_COMMON_DEFINITIONS} ASAN_DYNAMIC=1)\nappend_list_if(WIN32 INTERCEPTION_DYNAMIC_CRT ASAN_DYNAMIC_DEFINITIONS)\n\nset(ASAN_DYNAMIC_CFLAGS ${ASAN_CFLAGS})\nappend_list_if(COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC\n  -ftls-model=initial-exec ASAN_DYNAMIC_CFLAGS)\nappend_list_if(MSVC /DEBUG ASAN_DYNAMIC_CFLAGS)\n\nappend_list_if(COMPILER_RT_HAS_LIBC c ASAN_DYNAMIC_LIBS)\nappend_list_if(COMPILER_RT_HAS_LIBDL dl ASAN_DYNAMIC_LIBS)\nappend_list_if(COMPILER_RT_HAS_LIBRT rt ASAN_DYNAMIC_LIBS)\nappend_list_if(COMPILER_RT_HAS_LIBM m ASAN_DYNAMIC_LIBS)\nappend_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread ASAN_DYNAMIC_LIBS)\nappend_list_if(COMPILER_RT_HAS_LIBSTDCXX stdc++ ASAN_DYNAMIC_LIBS)\nappend_list_if(COMPILER_RT_HAS_LIBLOG log ASAN_DYNAMIC_LIBS)\n\n# Compile ASan sources into an object library.\n\nadd_compiler_rt_object_libraries(RTAsan_dynamic \n  OS ${SANITIZER_COMMON_SUPPORTED_OS}\n  ARCHS ${ASAN_SUPPORTED_ARCH}\n  SOURCES ${ASAN_SOURCES} ${ASAN_CXX_SOURCES}\n  CFLAGS ${ASAN_DYNAMIC_CFLAGS}\n  DEFS ${ASAN_DYNAMIC_DEFINITIONS})\n\nif(NOT APPLE)\n  add_compiler_rt_object_libraries(RTAsan \n    ARCHS ${ASAN_SUPPORTED_ARCH}\n    SOURCES ${ASAN_SOURCES} CFLAGS ${ASAN_CFLAGS}\n    DEFS ${ASAN_COMMON_DEFINITIONS})\n  add_compiler_rt_object_libraries(RTAsan_cxx \n    ARCHS ${ASAN_SUPPORTED_ARCH}\n    SOURCES ${ASAN_CXX_SOURCES} CFLAGS ${ASAN_CFLAGS}\n    DEFS ${ASAN_COMMON_DEFINITIONS})\n  add_compiler_rt_object_libraries(RTAsan_preinit \n    ARCHS ${ASAN_SUPPORTED_ARCH}\n    SOURCES ${ASAN_PREINIT_SOURCES} CFLAGS ${ASAN_CFLAGS}\n    DEFS ${ASAN_COMMON_DEFINITIONS})\n\n  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cc \"\")\n  add_compiler_rt_object_libraries(RTAsan_dynamic_version_script_dummy\n    ARCHS ${ASAN_SUPPORTED_ARCH}\n    SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cc\n    CFLAGS ${ASAN_DYNAMIC_CFLAGS}\n    DEFS ${ASAN_DYNAMIC_DEFINITIONS})\nendif()\n\n# Build ASan runtimes shipped with Clang.\nadd_custom_target(asan)\nif(APPLE)\n  add_compiler_rt_runtime(clang_rt.asan\n    SHARED\n    OS ${SANITIZER_COMMON_SUPPORTED_OS}\n    ARCHS ${ASAN_SUPPORTED_ARCH}\n    OBJECT_LIBS RTAsan_dynamic\n                RTInterception\n                RTSanitizerCommon\n                RTSanitizerCommonLibc\n                RTLSanCommon\n                RTUbsan\n    CFLAGS ${ASAN_DYNAMIC_CFLAGS}\n    DEFS ${ASAN_DYNAMIC_DEFINITIONS}\n    PARENT_TARGET asan)\nelse()\n  # Build separate libraries for each target.\n  \n    set(ASAN_COMMON_RUNTIME_OBJECT_LIBS\n      RTInterception\n      RTSanitizerCommon\n      RTSanitizerCommonLibc\n      RTLSanCommon\n      RTUbsan)\n\n    add_compiler_rt_runtime(clang_rt.asan\n      STATIC\n      ARCHS ${ASAN_SUPPORTED_ARCH}\n      OBJECT_LIBS RTAsan_preinit\n                  RTAsan\n                  ${ASAN_COMMON_RUNTIME_OBJECT_LIBS}\n      CFLAGS ${ASAN_CFLAGS}\n      DEFS ${ASAN_COMMON_DEFINITIONS}\n      PARENT_TARGET asan)\n\n    add_compiler_rt_runtime(clang_rt.asan_cxx\n      STATIC\n      ARCHS ${ASAN_SUPPORTED_ARCH}\n      OBJECT_LIBS RTAsan_cxx\n                  RTUbsan_cxx\n      CFLAGS ${ASAN_CFLAGS}\n      DEFS ${ASAN_COMMON_DEFINITIONS}\n      PARENT_TARGET asan)\n\n    add_compiler_rt_runtime(clang_rt.asan-preinit\n      STATIC\n      ARCHS ${ASAN_SUPPORTED_ARCH}\n      OBJECT_LIBS RTAsan_preinit\n      CFLAGS ${ASAN_CFLAGS}\n      DEFS ${ASAN_COMMON_DEFINITIONS}\n      PARENT_TARGET asan)\n\n  foreach(arch ${ASAN_SUPPORTED_ARCH})\n    if (UNIX AND NOT ${arch} MATCHES \"i386|i686\")\n      add_sanitizer_rt_version_list(clang_rt.asan-dynamic-${arch}\n                                    LIBS clang_rt.asan-${arch} clang_rt.asan_cxx-${arch}\n                                    EXTRA asan.syms.extra)\n      set(VERSION_SCRIPT_FLAG\n           -Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/clang_rt.asan-dynamic-${arch}.vers)\n      set_source_files_properties(\n        ${CMAKE_CURRENT_BINARY_DIR}/dummy.cc\n\tPROPERTIES\n\tOBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clang_rt.asan-dynamic-${arch}.vers)\n    else()\n      set(VERSION_SCRIPT_FLAG)\n    endif()\n\n    add_compiler_rt_runtime(clang_rt.asan\n      SHARED\n      ARCHS ${arch}\n      OBJECT_LIBS ${ASAN_COMMON_RUNTIME_OBJECT_LIBS}\n              RTAsan_dynamic\n              # The only purpose of RTAsan_dynamic_version_script_dummy is to carry\n              # a dependency of the shared runtime on the version script. With CMake\n              # 3.1 or later it can be replaced with a straightforward\n              # add_dependencies(clang_rt.asan-dynamic-${arch} clang_rt.asan-dynamic-${arch}-version-list)\n              RTAsan_dynamic_version_script_dummy\n              RTUbsan_cxx\n      CFLAGS ${ASAN_DYNAMIC_CFLAGS}\n      LINKFLAGS ${ASAN_DYNAMIC_LINK_FLAGS}\n                ${VERSION_SCRIPT_FLAG}\n      LINK_LIBS ${ASAN_DYNAMIC_LIBS}\n      DEFS ${ASAN_DYNAMIC_DEFINITIONS}\n      PARENT_TARGET asan)\n\n    if (UNIX AND NOT ${arch} MATCHES \"i386|i686\")\n      add_sanitizer_rt_symbols(clang_rt.asan_cxx\n        ARCHS ${arch})\n      add_dependencies(asan clang_rt.asan_cxx-${arch}-symbols)\n      add_sanitizer_rt_symbols(clang_rt.asan\n        ARCHS ${arch} \n        EXTRA asan.syms.extra)\n      add_dependencies(asan clang_rt.asan-${arch}-symbols)\n    endif()\n\n    if (WIN32)\n      add_compiler_rt_runtime(clang_rt.asan_dll_thunk\n        STATIC\n        ARCHS ${arch}\n        SOURCES asan_win_dll_thunk.cc\n                $<TARGET_OBJECTS:RTInterception.${arch}>\n        CFLAGS ${ASAN_CFLAGS} -DASAN_DLL_THUNK\n        DEFS ${ASAN_COMMON_DEFINITIONS}\n        PARENT_TARGET asan)\n      add_compiler_rt_runtime(clang_rt.asan_dynamic_runtime_thunk\n        STATIC\n        ARCHS ${arch}\n        SOURCES asan_win_dynamic_runtime_thunk.cc\n        CFLAGS ${ASAN_CFLAGS} -DASAN_DYNAMIC_RUNTIME_THUNK -Zl\n        DEFS ${ASAN_COMMON_DEFINITIONS}\n        PARENT_TARGET asan)\n    endif()\n  endforeach()\nendif()\n\nadd_compiler_rt_resource_file(asan_blacklist asan_blacklist.txt)\nadd_dependencies(asan asan_blacklist)\nadd_dependencies(compiler-rt asan)\n\nadd_subdirectory(scripts)\n\nif(COMPILER_RT_INCLUDE_TESTS)\n  add_subdirectory(tests)\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/Makefile.mk",
    "content": "#===- lib/asan/Makefile.mk ---------------------------------*- Makefile -*--===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\nModuleName := asan\nSubDirs := \n\nCCSources := $(foreach file,$(wildcard $(Dir)/*.cc),$(notdir $(file)))\nCXXOnlySources := asan_new_delete.cc\nCOnlySources := $(filter-out $(CXXOnlySources),$(CCSources))\nSSources := $(foreach file,$(wildcard $(Dir)/*.S),$(notdir $(file)))\nSources := $(CCSources) $(SSources)\nObjNames := $(CCSources:%.cc=%.o) $(SSources:%.S=%.o)\n\nImplementation := Generic\n\n# FIXME: use automatic dependencies?\nDependencies := $(wildcard $(Dir)/*.h)\nDependencies += $(wildcard $(Dir)/../interception/*.h)\nDependencies += $(wildcard $(Dir)/../sanitizer_common/*.h)\n\n# Define a convenience variable for all the asan functions.\nAsanFunctions := $(COnlySources:%.cc=%) $(SSources:%.S=%)\nAsanCXXFunctions := $(CXXOnlySources:%.cc=%)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/README.txt",
    "content": "AddressSanitizer RT\n================================\nThis directory contains sources of the AddressSanitizer (ASan) runtime library.\n\nDirectory structure:\nREADME.txt       : This file.\nMakefile.mk      : File for make-based build.\nCMakeLists.txt   : File for cmake-based build.\nasan_*.{cc,h}    : Sources of the asan runtime library.\nscripts/*        : Helper scripts.\ntests/*          : ASan unit tests.\n\nAlso ASan runtime needs the following libraries:\nlib/interception/      : Machinery used to intercept function calls.\nlib/sanitizer_common/  : Code shared between various sanitizers.\n\nASan runtime currently also embeds part of LeakSanitizer runtime for\nleak detection (lib/lsan/lsan_common.{cc,h}).\n\nASan runtime can only be built by CMake. You can run ASan tests\nfrom the root of your CMake build tree:\n\nmake check-asan\n\nFor more instructions see:\nhttps://github.com/google/sanitizers/wiki/AddressSanitizerHowToBuild\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan.syms.extra",
    "content": "__asan_*\n__lsan_*\n__ubsan_*\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_activation.cc",
    "content": "//===-- asan_activation.cc --------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// ASan activation/deactivation logic.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_activation.h\"\n#include \"asan_allocator.h\"\n#include \"asan_flags.h\"\n#include \"asan_internal.h\"\n#include \"asan_poisoning.h\"\n#include \"asan_stack.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n\nnamespace __asan {\n\nstatic struct AsanDeactivatedFlags {\n  AllocatorOptions allocator_options;\n  int malloc_context_size;\n  bool poison_heap;\n  bool coverage;\n  const char *coverage_dir;\n\n  void RegisterActivationFlags(FlagParser *parser, Flags *f, CommonFlags *cf) {\n#define ASAN_ACTIVATION_FLAG(Type, Name) \\\n  RegisterFlag(parser, #Name, \"\", &f->Name);\n#define COMMON_ACTIVATION_FLAG(Type, Name) \\\n  RegisterFlag(parser, #Name, \"\", &cf->Name);\n#include \"asan_activation_flags.inc\"\n#undef ASAN_ACTIVATION_FLAG\n#undef COMMON_ACTIVATION_FLAG\n\n    RegisterIncludeFlags(parser, cf);\n  }\n\n  void OverrideFromActivationFlags() {\n    Flags f;\n    CommonFlags cf;\n    FlagParser parser;\n    RegisterActivationFlags(&parser, &f, &cf);\n\n    // Copy the current activation flags.\n    allocator_options.CopyTo(&f, &cf);\n    cf.malloc_context_size = malloc_context_size;\n    f.poison_heap = poison_heap;\n    cf.coverage = coverage;\n    cf.coverage_dir = coverage_dir;\n    cf.verbosity = Verbosity();\n    cf.help = false; // this is activation-specific help\n\n    // Check if activation flags need to be overriden.\n    if (const char *env = GetEnv(\"ASAN_ACTIVATION_OPTIONS\")) {\n      parser.ParseString(env);\n    }\n\n    SetVerbosity(cf.verbosity);\n\n    if (Verbosity()) ReportUnrecognizedFlags();\n\n    if (cf.help) parser.PrintFlagDescriptions();\n\n    allocator_options.SetFrom(&f, &cf);\n    malloc_context_size = cf.malloc_context_size;\n    poison_heap = f.poison_heap;\n    coverage = cf.coverage;\n    coverage_dir = cf.coverage_dir;\n  }\n\n  void Print() {\n    Report(\n        \"quarantine_size_mb %d, max_redzone %d, poison_heap %d, \"\n        \"malloc_context_size %d, alloc_dealloc_mismatch %d, \"\n        \"allocator_may_return_null %d, coverage %d, coverage_dir %s\\n\",\n        allocator_options.quarantine_size_mb, allocator_options.max_redzone,\n        poison_heap, malloc_context_size,\n        allocator_options.alloc_dealloc_mismatch,\n        allocator_options.may_return_null, coverage, coverage_dir);\n  }\n} asan_deactivated_flags;\n\nstatic bool asan_is_deactivated;\n\nvoid AsanDeactivate() {\n  CHECK(!asan_is_deactivated);\n  VReport(1, \"Deactivating ASan\\n\");\n\n  // Stash runtime state.\n  GetAllocatorOptions(&asan_deactivated_flags.allocator_options);\n  asan_deactivated_flags.malloc_context_size = GetMallocContextSize();\n  asan_deactivated_flags.poison_heap = CanPoisonMemory();\n  asan_deactivated_flags.coverage = common_flags()->coverage;\n  asan_deactivated_flags.coverage_dir = common_flags()->coverage_dir;\n\n  // Deactivate the runtime.\n  SetCanPoisonMemory(false);\n  SetMallocContextSize(1);\n  ReInitializeCoverage(false, nullptr);\n\n  AllocatorOptions disabled = asan_deactivated_flags.allocator_options;\n  disabled.quarantine_size_mb = 0;\n  disabled.min_redzone = 16;  // Redzone must be at least 16 bytes long.\n  disabled.max_redzone = 16;\n  disabled.alloc_dealloc_mismatch = false;\n  disabled.may_return_null = true;\n  ReInitializeAllocator(disabled);\n\n  asan_is_deactivated = true;\n}\n\nvoid AsanActivate() {\n  if (!asan_is_deactivated) return;\n  VReport(1, \"Activating ASan\\n\");\n\n  UpdateProcessName();\n\n  asan_deactivated_flags.OverrideFromActivationFlags();\n\n  SetCanPoisonMemory(asan_deactivated_flags.poison_heap);\n  SetMallocContextSize(asan_deactivated_flags.malloc_context_size);\n  ReInitializeCoverage(asan_deactivated_flags.coverage,\n                       asan_deactivated_flags.coverage_dir);\n  ReInitializeAllocator(asan_deactivated_flags.allocator_options);\n\n  asan_is_deactivated = false;\n  if (Verbosity()) {\n    Report(\"Activated with flags:\\n\");\n    asan_deactivated_flags.Print();\n  }\n}\n\n}  // namespace __asan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_activation.h",
    "content": "//===-- asan_activation.h ---------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// ASan activation/deactivation logic.\n//===----------------------------------------------------------------------===//\n\n#ifndef ASAN_ACTIVATION_H\n#define ASAN_ACTIVATION_H\n\nnamespace __asan {\nvoid AsanDeactivate();\nvoid AsanActivate();\n}  // namespace __asan\n\n#endif  // ASAN_ACTIVATION_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_activation_flags.inc",
    "content": "//===-- asan_activation_flags.inc -------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// A subset of ASan (and common) runtime flags supported at activation time.\n//\n//===----------------------------------------------------------------------===//\n#ifndef ASAN_ACTIVATION_FLAG\n# error \"Define ASAN_ACTIVATION_FLAG prior to including this file!\"\n#endif\n\n#ifndef COMMON_ACTIVATION_FLAG\n# error \"Define COMMON_ACTIVATION_FLAG prior to including this file!\"\n#endif\n\n// ASAN_ACTIVATION_FLAG(Type, Name)\n// See COMMON_FLAG in sanitizer_flags.inc for more details.\n\nASAN_ACTIVATION_FLAG(int, redzone)\nASAN_ACTIVATION_FLAG(int, max_redzone)\nASAN_ACTIVATION_FLAG(int, quarantine_size_mb)\nASAN_ACTIVATION_FLAG(bool, alloc_dealloc_mismatch)\nASAN_ACTIVATION_FLAG(bool, poison_heap)\n\nCOMMON_ACTIVATION_FLAG(bool, allocator_may_return_null)\nCOMMON_ACTIVATION_FLAG(int, malloc_context_size)\nCOMMON_ACTIVATION_FLAG(bool, coverage)\nCOMMON_ACTIVATION_FLAG(const char *, coverage_dir)\nCOMMON_ACTIVATION_FLAG(int, verbosity)\nCOMMON_ACTIVATION_FLAG(bool, help)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_allocator.cc",
    "content": "//===-- asan_allocator.cc -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Implementation of ASan's memory allocator, 2-nd version.\n// This variant uses the allocator from sanitizer_common, i.e. the one shared\n// with ThreadSanitizer and MemorySanitizer.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"asan_allocator.h\"\n#include \"asan_mapping.h\"\n#include \"asan_poisoning.h\"\n#include \"asan_report.h\"\n#include \"asan_stack.h\"\n#include \"asan_thread.h\"\n#include \"sanitizer_common/sanitizer_allocator_interface.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"sanitizer_common/sanitizer_list.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n#include \"sanitizer_common/sanitizer_quarantine.h\"\n#include \"lsan/lsan_common.h\"\n\nnamespace __asan {\n\n// Valid redzone sizes are 16, 32, 64, ... 2048, so we encode them in 3 bits.\n// We use adaptive redzones: for larger allocation larger redzones are used.\nstatic u32 RZLog2Size(u32 rz_log) {\n  CHECK_LT(rz_log, 8);\n  return 16 << rz_log;\n}\n\nstatic u32 RZSize2Log(u32 rz_size) {\n  CHECK_GE(rz_size, 16);\n  CHECK_LE(rz_size, 2048);\n  CHECK(IsPowerOfTwo(rz_size));\n  u32 res = Log2(rz_size) - 4;\n  CHECK_EQ(rz_size, RZLog2Size(res));\n  return res;\n}\n\nstatic AsanAllocator &get_allocator();\n\n// The memory chunk allocated from the underlying allocator looks like this:\n// L L L L L L H H U U U U U U R R\n//   L -- left redzone words (0 or more bytes)\n//   H -- ChunkHeader (16 bytes), which is also a part of the left redzone.\n//   U -- user memory.\n//   R -- right redzone (0 or more bytes)\n// ChunkBase consists of ChunkHeader and other bytes that overlap with user\n// memory.\n\n// If the left redzone is greater than the ChunkHeader size we store a magic\n// value in the first uptr word of the memory block and store the address of\n// ChunkBase in the next uptr.\n// M B L L L L L L L L L  H H U U U U U U\n//   |                    ^\n//   ---------------------|\n//   M -- magic value kAllocBegMagic\n//   B -- address of ChunkHeader pointing to the first 'H'\nstatic const uptr kAllocBegMagic = 0xCC6E96B9;\n\nstruct ChunkHeader {\n  // 1-st 8 bytes.\n  u32 chunk_state       : 8;  // Must be first.\n  u32 alloc_tid         : 24;\n\n  u32 free_tid          : 24;\n  u32 from_memalign     : 1;\n  u32 alloc_type        : 2;\n  u32 rz_log            : 3;\n  u32 lsan_tag          : 2;\n  // 2-nd 8 bytes\n  // This field is used for small sizes. For large sizes it is equal to\n  // SizeClassMap::kMaxSize and the actual size is stored in the\n  // SecondaryAllocator's metadata.\n  u32 user_requested_size;\n  u32 alloc_context_id;\n};\n\nstruct ChunkBase : ChunkHeader {\n  // Header2, intersects with user memory.\n  u32 free_context_id;\n};\n\nstatic const uptr kChunkHeaderSize = sizeof(ChunkHeader);\nstatic const uptr kChunkHeader2Size = sizeof(ChunkBase) - kChunkHeaderSize;\nCOMPILER_CHECK(kChunkHeaderSize == 16);\nCOMPILER_CHECK(kChunkHeader2Size <= 16);\n\n// Every chunk of memory allocated by this allocator can be in one of 3 states:\n// CHUNK_AVAILABLE: the chunk is in the free list and ready to be allocated.\n// CHUNK_ALLOCATED: the chunk is allocated and not yet freed.\n// CHUNK_QUARANTINE: the chunk was freed and put into quarantine zone.\nenum {\n  CHUNK_AVAILABLE  = 0,  // 0 is the default value even if we didn't set it.\n  CHUNK_ALLOCATED  = 2,\n  CHUNK_QUARANTINE = 3\n};\n\nstruct AsanChunk: ChunkBase {\n  uptr Beg() { return reinterpret_cast<uptr>(this) + kChunkHeaderSize; }\n  uptr UsedSize(bool locked_version = false) {\n    if (user_requested_size != SizeClassMap::kMaxSize)\n      return user_requested_size;\n    return *reinterpret_cast<uptr *>(\n               get_allocator().GetMetaData(AllocBeg(locked_version)));\n  }\n  void *AllocBeg(bool locked_version = false) {\n    if (from_memalign) {\n      if (locked_version)\n        return get_allocator().GetBlockBeginFastLocked(\n            reinterpret_cast<void *>(this));\n      return get_allocator().GetBlockBegin(reinterpret_cast<void *>(this));\n    }\n    return reinterpret_cast<void*>(Beg() - RZLog2Size(rz_log));\n  }\n  bool AddrIsInside(uptr addr, bool locked_version = false) {\n    return (addr >= Beg()) && (addr < Beg() + UsedSize(locked_version));\n  }\n};\n\nstruct QuarantineCallback {\n  explicit QuarantineCallback(AllocatorCache *cache)\n      : cache_(cache) {\n  }\n\n  void Recycle(AsanChunk *m) {\n    CHECK_EQ(m->chunk_state, CHUNK_QUARANTINE);\n    atomic_store((atomic_uint8_t*)m, CHUNK_AVAILABLE, memory_order_relaxed);\n    CHECK_NE(m->alloc_tid, kInvalidTid);\n    CHECK_NE(m->free_tid, kInvalidTid);\n    PoisonShadow(m->Beg(),\n                 RoundUpTo(m->UsedSize(), SHADOW_GRANULARITY),\n                 kAsanHeapLeftRedzoneMagic);\n    void *p = reinterpret_cast<void *>(m->AllocBeg());\n    if (p != m) {\n      uptr *alloc_magic = reinterpret_cast<uptr *>(p);\n      CHECK_EQ(alloc_magic[0], kAllocBegMagic);\n      // Clear the magic value, as allocator internals may overwrite the\n      // contents of deallocated chunk, confusing GetAsanChunk lookup.\n      alloc_magic[0] = 0;\n      CHECK_EQ(alloc_magic[1], reinterpret_cast<uptr>(m));\n    }\n\n    // Statistics.\n    AsanStats &thread_stats = GetCurrentThreadStats();\n    thread_stats.real_frees++;\n    thread_stats.really_freed += m->UsedSize();\n\n    get_allocator().Deallocate(cache_, p);\n  }\n\n  void *Allocate(uptr size) {\n    return get_allocator().Allocate(cache_, size, 1, false);\n  }\n\n  void Deallocate(void *p) {\n    get_allocator().Deallocate(cache_, p);\n  }\n\n  AllocatorCache *cache_;\n};\n\ntypedef Quarantine<QuarantineCallback, AsanChunk> AsanQuarantine;\ntypedef AsanQuarantine::Cache QuarantineCache;\n\nvoid AsanMapUnmapCallback::OnMap(uptr p, uptr size) const {\n  PoisonShadow(p, size, kAsanHeapLeftRedzoneMagic);\n  // Statistics.\n  AsanStats &thread_stats = GetCurrentThreadStats();\n  thread_stats.mmaps++;\n  thread_stats.mmaped += size;\n}\nvoid AsanMapUnmapCallback::OnUnmap(uptr p, uptr size) const {\n  PoisonShadow(p, size, 0);\n  // We are about to unmap a chunk of user memory.\n  // Mark the corresponding shadow memory as not needed.\n  FlushUnneededASanShadowMemory(p, size);\n  // Statistics.\n  AsanStats &thread_stats = GetCurrentThreadStats();\n  thread_stats.munmaps++;\n  thread_stats.munmaped += size;\n}\n\n// We can not use THREADLOCAL because it is not supported on some of the\n// platforms we care about (OSX 10.6, Android).\n// static THREADLOCAL AllocatorCache cache;\nAllocatorCache *GetAllocatorCache(AsanThreadLocalMallocStorage *ms) {\n  CHECK(ms);\n  return &ms->allocator_cache;\n}\n\nQuarantineCache *GetQuarantineCache(AsanThreadLocalMallocStorage *ms) {\n  CHECK(ms);\n  CHECK_LE(sizeof(QuarantineCache), sizeof(ms->quarantine_cache));\n  return reinterpret_cast<QuarantineCache *>(ms->quarantine_cache);\n}\n\nvoid AllocatorOptions::SetFrom(const Flags *f, const CommonFlags *cf) {\n  quarantine_size_mb = f->quarantine_size_mb;\n  min_redzone = f->redzone;\n  max_redzone = f->max_redzone;\n  may_return_null = cf->allocator_may_return_null;\n  alloc_dealloc_mismatch = f->alloc_dealloc_mismatch;\n}\n\nvoid AllocatorOptions::CopyTo(Flags *f, CommonFlags *cf) {\n  f->quarantine_size_mb = quarantine_size_mb;\n  f->redzone = min_redzone;\n  f->max_redzone = max_redzone;\n  cf->allocator_may_return_null = may_return_null;\n  f->alloc_dealloc_mismatch = alloc_dealloc_mismatch;\n}\n\nstruct Allocator {\n  static const uptr kMaxAllowedMallocSize =\n      FIRST_32_SECOND_64(3UL << 30, 1UL << 40);\n  static const uptr kMaxThreadLocalQuarantine =\n      FIRST_32_SECOND_64(1 << 18, 1 << 20);\n\n  AsanAllocator allocator;\n  AsanQuarantine quarantine;\n  StaticSpinMutex fallback_mutex;\n  AllocatorCache fallback_allocator_cache;\n  QuarantineCache fallback_quarantine_cache;\n\n  // ------------------- Options --------------------------\n  atomic_uint16_t min_redzone;\n  atomic_uint16_t max_redzone;\n  atomic_uint8_t alloc_dealloc_mismatch;\n\n  // ------------------- Initialization ------------------------\n  explicit Allocator(LinkerInitialized)\n      : quarantine(LINKER_INITIALIZED),\n        fallback_quarantine_cache(LINKER_INITIALIZED) {}\n\n  void CheckOptions(const AllocatorOptions &options) const {\n    CHECK_GE(options.min_redzone, 16);\n    CHECK_GE(options.max_redzone, options.min_redzone);\n    CHECK_LE(options.max_redzone, 2048);\n    CHECK(IsPowerOfTwo(options.min_redzone));\n    CHECK(IsPowerOfTwo(options.max_redzone));\n  }\n\n  void SharedInitCode(const AllocatorOptions &options) {\n    CheckOptions(options);\n    quarantine.Init((uptr)options.quarantine_size_mb << 20,\n                    kMaxThreadLocalQuarantine);\n    atomic_store(&alloc_dealloc_mismatch, options.alloc_dealloc_mismatch,\n                 memory_order_release);\n    atomic_store(&min_redzone, options.min_redzone, memory_order_release);\n    atomic_store(&max_redzone, options.max_redzone, memory_order_release);\n  }\n\n  void Initialize(const AllocatorOptions &options) {\n    allocator.Init(options.may_return_null);\n    SharedInitCode(options);\n  }\n\n  void ReInitialize(const AllocatorOptions &options) {\n    allocator.SetMayReturnNull(options.may_return_null);\n    SharedInitCode(options);\n  }\n\n  void GetOptions(AllocatorOptions *options) const {\n    options->quarantine_size_mb = quarantine.GetSize() >> 20;\n    options->min_redzone = atomic_load(&min_redzone, memory_order_acquire);\n    options->max_redzone = atomic_load(&max_redzone, memory_order_acquire);\n    options->may_return_null = allocator.MayReturnNull();\n    options->alloc_dealloc_mismatch =\n        atomic_load(&alloc_dealloc_mismatch, memory_order_acquire);\n  }\n\n  // -------------------- Helper methods. -------------------------\n  uptr ComputeRZLog(uptr user_requested_size) {\n    u32 rz_log =\n      user_requested_size <= 64        - 16   ? 0 :\n      user_requested_size <= 128       - 32   ? 1 :\n      user_requested_size <= 512       - 64   ? 2 :\n      user_requested_size <= 4096      - 128  ? 3 :\n      user_requested_size <= (1 << 14) - 256  ? 4 :\n      user_requested_size <= (1 << 15) - 512  ? 5 :\n      user_requested_size <= (1 << 16) - 1024 ? 6 : 7;\n    u32 min_rz = atomic_load(&min_redzone, memory_order_acquire);\n    u32 max_rz = atomic_load(&max_redzone, memory_order_acquire);\n    return Min(Max(rz_log, RZSize2Log(min_rz)), RZSize2Log(max_rz));\n  }\n\n  // We have an address between two chunks, and we want to report just one.\n  AsanChunk *ChooseChunk(uptr addr, AsanChunk *left_chunk,\n                         AsanChunk *right_chunk) {\n    // Prefer an allocated chunk over freed chunk and freed chunk\n    // over available chunk.\n    if (left_chunk->chunk_state != right_chunk->chunk_state) {\n      if (left_chunk->chunk_state == CHUNK_ALLOCATED)\n        return left_chunk;\n      if (right_chunk->chunk_state == CHUNK_ALLOCATED)\n        return right_chunk;\n      if (left_chunk->chunk_state == CHUNK_QUARANTINE)\n        return left_chunk;\n      if (right_chunk->chunk_state == CHUNK_QUARANTINE)\n        return right_chunk;\n    }\n    // Same chunk_state: choose based on offset.\n    sptr l_offset = 0, r_offset = 0;\n    CHECK(AsanChunkView(left_chunk).AddrIsAtRight(addr, 1, &l_offset));\n    CHECK(AsanChunkView(right_chunk).AddrIsAtLeft(addr, 1, &r_offset));\n    if (l_offset < r_offset)\n      return left_chunk;\n    return right_chunk;\n  }\n\n  // -------------------- Allocation/Deallocation routines ---------------\n  void *Allocate(uptr size, uptr alignment, BufferedStackTrace *stack,\n                 AllocType alloc_type, bool can_fill) {\n    if (UNLIKELY(!asan_inited))\n      AsanInitFromRtl();\n    Flags &fl = *flags();\n    CHECK(stack);\n    const uptr min_alignment = SHADOW_GRANULARITY;\n    if (alignment < min_alignment)\n      alignment = min_alignment;\n    if (size == 0) {\n      // We'd be happy to avoid allocating memory for zero-size requests, but\n      // some programs/tests depend on this behavior and assume that malloc\n      // would not return NULL even for zero-size allocations. Moreover, it\n      // looks like operator new should never return NULL, and results of\n      // consecutive \"new\" calls must be different even if the allocated size\n      // is zero.\n      size = 1;\n    }\n    CHECK(IsPowerOfTwo(alignment));\n    uptr rz_log = ComputeRZLog(size);\n    uptr rz_size = RZLog2Size(rz_log);\n    uptr rounded_size = RoundUpTo(Max(size, kChunkHeader2Size), alignment);\n    uptr needed_size = rounded_size + rz_size;\n    if (alignment > min_alignment)\n      needed_size += alignment;\n    bool using_primary_allocator = true;\n    // If we are allocating from the secondary allocator, there will be no\n    // automatic right redzone, so add the right redzone manually.\n    if (!PrimaryAllocator::CanAllocate(needed_size, alignment)) {\n      needed_size += rz_size;\n      using_primary_allocator = false;\n    }\n    CHECK(IsAligned(needed_size, min_alignment));\n    if (size > kMaxAllowedMallocSize || needed_size > kMaxAllowedMallocSize) {\n      Report(\"WARNING: AddressSanitizer failed to allocate 0x%zx bytes\\n\",\n             (void*)size);\n      return allocator.ReturnNullOrDie();\n    }\n\n    AsanThread *t = GetCurrentThread();\n    void *allocated;\n    bool check_rss_limit = true;\n    if (t) {\n      AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());\n      allocated =\n          allocator.Allocate(cache, needed_size, 8, false, check_rss_limit);\n    } else {\n      SpinMutexLock l(&fallback_mutex);\n      AllocatorCache *cache = &fallback_allocator_cache;\n      allocated =\n          allocator.Allocate(cache, needed_size, 8, false, check_rss_limit);\n    }\n\n    if (!allocated)\n      return allocator.ReturnNullOrDie();\n\n    if (*(u8 *)MEM_TO_SHADOW((uptr)allocated) == 0 && CanPoisonMemory()) {\n      // Heap poisoning is enabled, but the allocator provides an unpoisoned\n      // chunk. This is possible if CanPoisonMemory() was false for some\n      // time, for example, due to flags()->start_disabled.\n      // Anyway, poison the block before using it for anything else.\n      uptr allocated_size = allocator.GetActuallyAllocatedSize(allocated);\n      PoisonShadow((uptr)allocated, allocated_size, kAsanHeapLeftRedzoneMagic);\n    }\n\n    uptr alloc_beg = reinterpret_cast<uptr>(allocated);\n    uptr alloc_end = alloc_beg + needed_size;\n    uptr beg_plus_redzone = alloc_beg + rz_size;\n    uptr user_beg = beg_plus_redzone;\n    if (!IsAligned(user_beg, alignment))\n      user_beg = RoundUpTo(user_beg, alignment);\n    uptr user_end = user_beg + size;\n    CHECK_LE(user_end, alloc_end);\n    uptr chunk_beg = user_beg - kChunkHeaderSize;\n    AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg);\n    m->alloc_type = alloc_type;\n    m->rz_log = rz_log;\n    u32 alloc_tid = t ? t->tid() : 0;\n    m->alloc_tid = alloc_tid;\n    CHECK_EQ(alloc_tid, m->alloc_tid);  // Does alloc_tid fit into the bitfield?\n    m->free_tid = kInvalidTid;\n    m->from_memalign = user_beg != beg_plus_redzone;\n    if (alloc_beg != chunk_beg) {\n      CHECK_LE(alloc_beg+ 2 * sizeof(uptr), chunk_beg);\n      reinterpret_cast<uptr *>(alloc_beg)[0] = kAllocBegMagic;\n      reinterpret_cast<uptr *>(alloc_beg)[1] = chunk_beg;\n    }\n    if (using_primary_allocator) {\n      CHECK(size);\n      m->user_requested_size = size;\n      CHECK(allocator.FromPrimary(allocated));\n    } else {\n      CHECK(!allocator.FromPrimary(allocated));\n      m->user_requested_size = SizeClassMap::kMaxSize;\n      uptr *meta = reinterpret_cast<uptr *>(allocator.GetMetaData(allocated));\n      meta[0] = size;\n      meta[1] = chunk_beg;\n    }\n\n    m->alloc_context_id = StackDepotPut(*stack);\n\n    uptr size_rounded_down_to_granularity =\n        RoundDownTo(size, SHADOW_GRANULARITY);\n    // Unpoison the bulk of the memory region.\n    if (size_rounded_down_to_granularity)\n      PoisonShadow(user_beg, size_rounded_down_to_granularity, 0);\n    // Deal with the end of the region if size is not aligned to granularity.\n    if (size != size_rounded_down_to_granularity && CanPoisonMemory()) {\n      u8 *shadow =\n          (u8 *)MemToShadow(user_beg + size_rounded_down_to_granularity);\n      *shadow = fl.poison_partial ? (size & (SHADOW_GRANULARITY - 1)) : 0;\n    }\n\n    AsanStats &thread_stats = GetCurrentThreadStats();\n    thread_stats.mallocs++;\n    thread_stats.malloced += size;\n    thread_stats.malloced_redzones += needed_size - size;\n    if (needed_size > SizeClassMap::kMaxSize)\n      thread_stats.malloc_large++;\n    else\n      thread_stats.malloced_by_size[SizeClassMap::ClassID(needed_size)]++;\n\n    void *res = reinterpret_cast<void *>(user_beg);\n    if (can_fill && fl.max_malloc_fill_size) {\n      uptr fill_size = Min(size, (uptr)fl.max_malloc_fill_size);\n      REAL(memset)(res, fl.malloc_fill_byte, fill_size);\n    }\n#if CAN_SANITIZE_LEAKS\n    m->lsan_tag = __lsan::DisabledInThisThread() ? __lsan::kIgnored\n                                                 : __lsan::kDirectlyLeaked;\n#endif\n    // Must be the last mutation of metadata in this function.\n    atomic_store((atomic_uint8_t *)m, CHUNK_ALLOCATED, memory_order_release);\n    ASAN_MALLOC_HOOK(res, size);\n    return res;\n  }\n\n  void AtomicallySetQuarantineFlag(AsanChunk *m, void *ptr,\n                                   BufferedStackTrace *stack) {\n    u8 old_chunk_state = CHUNK_ALLOCATED;\n    // Flip the chunk_state atomically to avoid race on double-free.\n    if (!atomic_compare_exchange_strong((atomic_uint8_t*)m, &old_chunk_state,\n                                        CHUNK_QUARANTINE, memory_order_acquire))\n      ReportInvalidFree(ptr, old_chunk_state, stack);\n    CHECK_EQ(CHUNK_ALLOCATED, old_chunk_state);\n  }\n\n  // Expects the chunk to already be marked as quarantined by using\n  // AtomicallySetQuarantineFlag.\n  void QuarantineChunk(AsanChunk *m, void *ptr, BufferedStackTrace *stack,\n                       AllocType alloc_type) {\n    CHECK_EQ(m->chunk_state, CHUNK_QUARANTINE);\n\n    if (m->alloc_type != alloc_type) {\n      if (atomic_load(&alloc_dealloc_mismatch, memory_order_acquire)) {\n        ReportAllocTypeMismatch((uptr)ptr, stack, (AllocType)m->alloc_type,\n                                (AllocType)alloc_type);\n      }\n    }\n\n    CHECK_GE(m->alloc_tid, 0);\n    if (SANITIZER_WORDSIZE == 64)  // On 32-bits this resides in user area.\n      CHECK_EQ(m->free_tid, kInvalidTid);\n    AsanThread *t = GetCurrentThread();\n    m->free_tid = t ? t->tid() : 0;\n    m->free_context_id = StackDepotPut(*stack);\n    // Poison the region.\n    PoisonShadow(m->Beg(),\n                 RoundUpTo(m->UsedSize(), SHADOW_GRANULARITY),\n                 kAsanHeapFreeMagic);\n\n    AsanStats &thread_stats = GetCurrentThreadStats();\n    thread_stats.frees++;\n    thread_stats.freed += m->UsedSize();\n\n    // Push into quarantine.\n    if (t) {\n      AsanThreadLocalMallocStorage *ms = &t->malloc_storage();\n      AllocatorCache *ac = GetAllocatorCache(ms);\n      quarantine.Put(GetQuarantineCache(ms), QuarantineCallback(ac), m,\n                           m->UsedSize());\n    } else {\n      SpinMutexLock l(&fallback_mutex);\n      AllocatorCache *ac = &fallback_allocator_cache;\n      quarantine.Put(&fallback_quarantine_cache, QuarantineCallback(ac), m,\n                           m->UsedSize());\n    }\n  }\n\n  void Deallocate(void *ptr, uptr delete_size, BufferedStackTrace *stack,\n                  AllocType alloc_type) {\n    uptr p = reinterpret_cast<uptr>(ptr);\n    if (p == 0) return;\n\n    uptr chunk_beg = p - kChunkHeaderSize;\n    AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg);\n    if (delete_size && flags()->new_delete_type_mismatch &&\n        delete_size != m->UsedSize()) {\n      ReportNewDeleteSizeMismatch(p, delete_size, stack);\n    }\n    ASAN_FREE_HOOK(ptr);\n    // Must mark the chunk as quarantined before any changes to its metadata.\n    AtomicallySetQuarantineFlag(m, ptr, stack);\n    QuarantineChunk(m, ptr, stack, alloc_type);\n  }\n\n  void *Reallocate(void *old_ptr, uptr new_size, BufferedStackTrace *stack) {\n    CHECK(old_ptr && new_size);\n    uptr p = reinterpret_cast<uptr>(old_ptr);\n    uptr chunk_beg = p - kChunkHeaderSize;\n    AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg);\n\n    AsanStats &thread_stats = GetCurrentThreadStats();\n    thread_stats.reallocs++;\n    thread_stats.realloced += new_size;\n\n    void *new_ptr = Allocate(new_size, 8, stack, FROM_MALLOC, true);\n    if (new_ptr) {\n      u8 chunk_state = m->chunk_state;\n      if (chunk_state != CHUNK_ALLOCATED)\n        ReportInvalidFree(old_ptr, chunk_state, stack);\n      CHECK_NE(REAL(memcpy), nullptr);\n      uptr memcpy_size = Min(new_size, m->UsedSize());\n      // If realloc() races with free(), we may start copying freed memory.\n      // However, we will report racy double-free later anyway.\n      REAL(memcpy)(new_ptr, old_ptr, memcpy_size);\n      Deallocate(old_ptr, 0, stack, FROM_MALLOC);\n    }\n    return new_ptr;\n  }\n\n  void *Calloc(uptr nmemb, uptr size, BufferedStackTrace *stack) {\n    if (CallocShouldReturnNullDueToOverflow(size, nmemb))\n      return allocator.ReturnNullOrDie();\n    void *ptr = Allocate(nmemb * size, 8, stack, FROM_MALLOC, false);\n    // If the memory comes from the secondary allocator no need to clear it\n    // as it comes directly from mmap.\n    if (ptr && allocator.FromPrimary(ptr))\n      REAL(memset)(ptr, 0, nmemb * size);\n    return ptr;\n  }\n\n  void ReportInvalidFree(void *ptr, u8 chunk_state, BufferedStackTrace *stack) {\n    if (chunk_state == CHUNK_QUARANTINE)\n      ReportDoubleFree((uptr)ptr, stack);\n    else\n      ReportFreeNotMalloced((uptr)ptr, stack);\n  }\n\n  void CommitBack(AsanThreadLocalMallocStorage *ms) {\n    AllocatorCache *ac = GetAllocatorCache(ms);\n    quarantine.Drain(GetQuarantineCache(ms), QuarantineCallback(ac));\n    allocator.SwallowCache(ac);\n  }\n\n  // -------------------------- Chunk lookup ----------------------\n\n  // Assumes alloc_beg == allocator.GetBlockBegin(alloc_beg).\n  AsanChunk *GetAsanChunk(void *alloc_beg) {\n    if (!alloc_beg) return nullptr;\n    if (!allocator.FromPrimary(alloc_beg)) {\n      uptr *meta = reinterpret_cast<uptr *>(allocator.GetMetaData(alloc_beg));\n      AsanChunk *m = reinterpret_cast<AsanChunk *>(meta[1]);\n      return m;\n    }\n    uptr *alloc_magic = reinterpret_cast<uptr *>(alloc_beg);\n    if (alloc_magic[0] == kAllocBegMagic)\n      return reinterpret_cast<AsanChunk *>(alloc_magic[1]);\n    return reinterpret_cast<AsanChunk *>(alloc_beg);\n  }\n\n  AsanChunk *GetAsanChunkByAddr(uptr p) {\n    void *alloc_beg = allocator.GetBlockBegin(reinterpret_cast<void *>(p));\n    return GetAsanChunk(alloc_beg);\n  }\n\n  // Allocator must be locked when this function is called.\n  AsanChunk *GetAsanChunkByAddrFastLocked(uptr p) {\n    void *alloc_beg =\n        allocator.GetBlockBeginFastLocked(reinterpret_cast<void *>(p));\n    return GetAsanChunk(alloc_beg);\n  }\n\n  uptr AllocationSize(uptr p) {\n    AsanChunk *m = GetAsanChunkByAddr(p);\n    if (!m) return 0;\n    if (m->chunk_state != CHUNK_ALLOCATED) return 0;\n    if (m->Beg() != p) return 0;\n    return m->UsedSize();\n  }\n\n  AsanChunkView FindHeapChunkByAddress(uptr addr) {\n    AsanChunk *m1 = GetAsanChunkByAddr(addr);\n    if (!m1) return AsanChunkView(m1);\n    sptr offset = 0;\n    if (AsanChunkView(m1).AddrIsAtLeft(addr, 1, &offset)) {\n      // The address is in the chunk's left redzone, so maybe it is actually\n      // a right buffer overflow from the other chunk to the left.\n      // Search a bit to the left to see if there is another chunk.\n      AsanChunk *m2 = nullptr;\n      for (uptr l = 1; l < GetPageSizeCached(); l++) {\n        m2 = GetAsanChunkByAddr(addr - l);\n        if (m2 == m1) continue;  // Still the same chunk.\n        break;\n      }\n      if (m2 && AsanChunkView(m2).AddrIsAtRight(addr, 1, &offset))\n        m1 = ChooseChunk(addr, m2, m1);\n    }\n    return AsanChunkView(m1);\n  }\n\n  void PrintStats() {\n    allocator.PrintStats();\n  }\n\n  void ForceLock() {\n    allocator.ForceLock();\n    fallback_mutex.Lock();\n  }\n\n  void ForceUnlock() {\n    fallback_mutex.Unlock();\n    allocator.ForceUnlock();\n  }\n};\n\nstatic Allocator instance(LINKER_INITIALIZED);\n\nstatic AsanAllocator &get_allocator() {\n  return instance.allocator;\n}\n\nbool AsanChunkView::IsValid() {\n  return chunk_ && chunk_->chunk_state != CHUNK_AVAILABLE;\n}\nuptr AsanChunkView::Beg() { return chunk_->Beg(); }\nuptr AsanChunkView::End() { return Beg() + UsedSize(); }\nuptr AsanChunkView::UsedSize() { return chunk_->UsedSize(); }\nuptr AsanChunkView::AllocTid() { return chunk_->alloc_tid; }\nuptr AsanChunkView::FreeTid() { return chunk_->free_tid; }\n\nstatic StackTrace GetStackTraceFromId(u32 id) {\n  CHECK(id);\n  StackTrace res = StackDepotGet(id);\n  CHECK(res.trace);\n  return res;\n}\n\nStackTrace AsanChunkView::GetAllocStack() {\n  return GetStackTraceFromId(chunk_->alloc_context_id);\n}\n\nStackTrace AsanChunkView::GetFreeStack() {\n  return GetStackTraceFromId(chunk_->free_context_id);\n}\n\nvoid InitializeAllocator(const AllocatorOptions &options) {\n  instance.Initialize(options);\n}\n\nvoid ReInitializeAllocator(const AllocatorOptions &options) {\n  instance.ReInitialize(options);\n}\n\nvoid GetAllocatorOptions(AllocatorOptions *options) {\n  instance.GetOptions(options);\n}\n\nAsanChunkView FindHeapChunkByAddress(uptr addr) {\n  return instance.FindHeapChunkByAddress(addr);\n}\n\nvoid AsanThreadLocalMallocStorage::CommitBack() {\n  instance.CommitBack(this);\n}\n\nvoid PrintInternalAllocatorStats() {\n  instance.PrintStats();\n}\n\nvoid *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack,\n                    AllocType alloc_type) {\n  return instance.Allocate(size, alignment, stack, alloc_type, true);\n}\n\nvoid asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type) {\n  instance.Deallocate(ptr, 0, stack, alloc_type);\n}\n\nvoid asan_sized_free(void *ptr, uptr size, BufferedStackTrace *stack,\n                     AllocType alloc_type) {\n  instance.Deallocate(ptr, size, stack, alloc_type);\n}\n\nvoid *asan_malloc(uptr size, BufferedStackTrace *stack) {\n  return instance.Allocate(size, 8, stack, FROM_MALLOC, true);\n}\n\nvoid *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack) {\n  return instance.Calloc(nmemb, size, stack);\n}\n\nvoid *asan_realloc(void *p, uptr size, BufferedStackTrace *stack) {\n  if (!p)\n    return instance.Allocate(size, 8, stack, FROM_MALLOC, true);\n  if (size == 0) {\n    instance.Deallocate(p, 0, stack, FROM_MALLOC);\n    return nullptr;\n  }\n  return instance.Reallocate(p, size, stack);\n}\n\nvoid *asan_valloc(uptr size, BufferedStackTrace *stack) {\n  return instance.Allocate(size, GetPageSizeCached(), stack, FROM_MALLOC, true);\n}\n\nvoid *asan_pvalloc(uptr size, BufferedStackTrace *stack) {\n  uptr PageSize = GetPageSizeCached();\n  size = RoundUpTo(size, PageSize);\n  if (size == 0) {\n    // pvalloc(0) should allocate one page.\n    size = PageSize;\n  }\n  return instance.Allocate(size, PageSize, stack, FROM_MALLOC, true);\n}\n\nint asan_posix_memalign(void **memptr, uptr alignment, uptr size,\n                        BufferedStackTrace *stack) {\n  void *ptr = instance.Allocate(size, alignment, stack, FROM_MALLOC, true);\n  CHECK(IsAligned((uptr)ptr, alignment));\n  *memptr = ptr;\n  return 0;\n}\n\nuptr asan_malloc_usable_size(void *ptr, uptr pc, uptr bp) {\n  if (!ptr) return 0;\n  uptr usable_size = instance.AllocationSize(reinterpret_cast<uptr>(ptr));\n  if (flags()->check_malloc_usable_size && (usable_size == 0)) {\n    GET_STACK_TRACE_FATAL(pc, bp);\n    ReportMallocUsableSizeNotOwned((uptr)ptr, &stack);\n  }\n  return usable_size;\n}\n\nuptr asan_mz_size(const void *ptr) {\n  return instance.AllocationSize(reinterpret_cast<uptr>(ptr));\n}\n\nvoid asan_mz_force_lock() {\n  instance.ForceLock();\n}\n\nvoid asan_mz_force_unlock() {\n  instance.ForceUnlock();\n}\n\nvoid AsanSoftRssLimitExceededCallback(bool exceeded) {\n  instance.allocator.SetRssLimitIsExceeded(exceeded);\n}\n\n} // namespace __asan\n\n// --- Implementation of LSan-specific functions --- {{{1\nnamespace __lsan {\nvoid LockAllocator() {\n  __asan::get_allocator().ForceLock();\n}\n\nvoid UnlockAllocator() {\n  __asan::get_allocator().ForceUnlock();\n}\n\nvoid GetAllocatorGlobalRange(uptr *begin, uptr *end) {\n  *begin = (uptr)&__asan::get_allocator();\n  *end = *begin + sizeof(__asan::get_allocator());\n}\n\nuptr PointsIntoChunk(void* p) {\n  uptr addr = reinterpret_cast<uptr>(p);\n  __asan::AsanChunk *m = __asan::instance.GetAsanChunkByAddrFastLocked(addr);\n  if (!m) return 0;\n  uptr chunk = m->Beg();\n  if (m->chunk_state != __asan::CHUNK_ALLOCATED)\n    return 0;\n  if (m->AddrIsInside(addr, /*locked_version=*/true))\n    return chunk;\n  if (IsSpecialCaseOfOperatorNew0(chunk, m->UsedSize(/*locked_version*/ true),\n                                  addr))\n    return chunk;\n  return 0;\n}\n\nuptr GetUserBegin(uptr chunk) {\n  __asan::AsanChunk *m = __asan::instance.GetAsanChunkByAddrFastLocked(chunk);\n  CHECK(m);\n  return m->Beg();\n}\n\nLsanMetadata::LsanMetadata(uptr chunk) {\n  metadata_ = reinterpret_cast<void *>(chunk - __asan::kChunkHeaderSize);\n}\n\nbool LsanMetadata::allocated() const {\n  __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);\n  return m->chunk_state == __asan::CHUNK_ALLOCATED;\n}\n\nChunkTag LsanMetadata::tag() const {\n  __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);\n  return static_cast<ChunkTag>(m->lsan_tag);\n}\n\nvoid LsanMetadata::set_tag(ChunkTag value) {\n  __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);\n  m->lsan_tag = value;\n}\n\nuptr LsanMetadata::requested_size() const {\n  __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);\n  return m->UsedSize(/*locked_version=*/true);\n}\n\nu32 LsanMetadata::stack_trace_id() const {\n  __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);\n  return m->alloc_context_id;\n}\n\nvoid ForEachChunk(ForEachChunkCallback callback, void *arg) {\n  __asan::get_allocator().ForEachChunk(callback, arg);\n}\n\nIgnoreObjectResult IgnoreObjectLocked(const void *p) {\n  uptr addr = reinterpret_cast<uptr>(p);\n  __asan::AsanChunk *m = __asan::instance.GetAsanChunkByAddr(addr);\n  if (!m) return kIgnoreObjectInvalid;\n  if ((m->chunk_state == __asan::CHUNK_ALLOCATED) && m->AddrIsInside(addr)) {\n    if (m->lsan_tag == kIgnored)\n      return kIgnoreObjectAlreadyIgnored;\n    m->lsan_tag = __lsan::kIgnored;\n    return kIgnoreObjectSuccess;\n  } else {\n    return kIgnoreObjectInvalid;\n  }\n}\n}  // namespace __lsan\n\n// ---------------------- Interface ---------------- {{{1\nusing namespace __asan;  // NOLINT\n\n// ASan allocator doesn't reserve extra bytes, so normally we would\n// just return \"size\". We don't want to expose our redzone sizes, etc here.\nuptr __sanitizer_get_estimated_allocated_size(uptr size) {\n  return size;\n}\n\nint __sanitizer_get_ownership(const void *p) {\n  uptr ptr = reinterpret_cast<uptr>(p);\n  return instance.AllocationSize(ptr) > 0;\n}\n\nuptr __sanitizer_get_allocated_size(const void *p) {\n  if (!p) return 0;\n  uptr ptr = reinterpret_cast<uptr>(p);\n  uptr allocated_size = instance.AllocationSize(ptr);\n  // Die if p is not malloced or if it is already freed.\n  if (allocated_size == 0) {\n    GET_STACK_TRACE_FATAL_HERE;\n    ReportSanitizerGetAllocatedSizeNotOwned(ptr, &stack);\n  }\n  return allocated_size;\n}\n\n#if !SANITIZER_SUPPORTS_WEAK_HOOKS\n// Provide default (no-op) implementation of malloc hooks.\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nvoid __sanitizer_malloc_hook(void *ptr, uptr size) {\n  (void)ptr;\n  (void)size;\n}\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nvoid __sanitizer_free_hook(void *ptr) {\n  (void)ptr;\n}\n} // extern \"C\"\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_allocator.h",
    "content": "//===-- asan_allocator.h ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// ASan-private header for asan_allocator.cc.\n//===----------------------------------------------------------------------===//\n\n#ifndef ASAN_ALLOCATOR_H\n#define ASAN_ALLOCATOR_H\n\n#include \"asan_flags.h\"\n#include \"asan_internal.h\"\n#include \"asan_interceptors.h\"\n#include \"sanitizer_common/sanitizer_allocator.h\"\n#include \"sanitizer_common/sanitizer_list.h\"\n\nnamespace __asan {\n\nenum AllocType {\n  FROM_MALLOC = 1,  // Memory block came from malloc, calloc, realloc, etc.\n  FROM_NEW = 2,     // Memory block came from operator new.\n  FROM_NEW_BR = 3   // Memory block came from operator new [ ]\n};\n\nstruct AsanChunk;\n\nstruct AllocatorOptions {\n  u32 quarantine_size_mb;\n  u16 min_redzone;\n  u16 max_redzone;\n  u8 may_return_null;\n  u8 alloc_dealloc_mismatch;\n\n  void SetFrom(const Flags *f, const CommonFlags *cf);\n  void CopyTo(Flags *f, CommonFlags *cf);\n};\n\nvoid InitializeAllocator(const AllocatorOptions &options);\nvoid ReInitializeAllocator(const AllocatorOptions &options);\nvoid GetAllocatorOptions(AllocatorOptions *options);\n\nclass AsanChunkView {\n public:\n  explicit AsanChunkView(AsanChunk *chunk) : chunk_(chunk) {}\n  bool IsValid();   // Checks if AsanChunkView points to a valid allocated\n                    // or quarantined chunk.\n  uptr Beg();       // First byte of user memory.\n  uptr End();       // Last byte of user memory.\n  uptr UsedSize();  // Size requested by the user.\n  uptr AllocTid();\n  uptr FreeTid();\n  bool Eq(const AsanChunkView &c) const { return chunk_ == c.chunk_; }\n  StackTrace GetAllocStack();\n  StackTrace GetFreeStack();\n  bool AddrIsInside(uptr addr, uptr access_size, sptr *offset) {\n    if (addr >= Beg() && (addr + access_size) <= End()) {\n      *offset = addr - Beg();\n      return true;\n    }\n    return false;\n  }\n  bool AddrIsAtLeft(uptr addr, uptr access_size, sptr *offset) {\n    (void)access_size;\n    if (addr < Beg()) {\n      *offset = Beg() - addr;\n      return true;\n    }\n    return false;\n  }\n  bool AddrIsAtRight(uptr addr, uptr access_size, sptr *offset) {\n    if (addr + access_size > End()) {\n      *offset = addr - End();\n      return true;\n    }\n    return false;\n  }\n\n private:\n  AsanChunk *const chunk_;\n};\n\nAsanChunkView FindHeapChunkByAddress(uptr address);\n\n// List of AsanChunks with total size.\nclass AsanChunkFifoList: public IntrusiveList<AsanChunk> {\n public:\n  explicit AsanChunkFifoList(LinkerInitialized) { }\n  AsanChunkFifoList() { clear(); }\n  void Push(AsanChunk *n);\n  void PushList(AsanChunkFifoList *q);\n  AsanChunk *Pop();\n  uptr size() { return size_; }\n  void clear() {\n    IntrusiveList<AsanChunk>::clear();\n    size_ = 0;\n  }\n private:\n  uptr size_;\n};\n\nstruct AsanMapUnmapCallback {\n  void OnMap(uptr p, uptr size) const;\n  void OnUnmap(uptr p, uptr size) const;\n};\n\n#if SANITIZER_CAN_USE_ALLOCATOR64\n# if defined(__powerpc64__)\nconst uptr kAllocatorSpace =  0xa0000000000ULL;\nconst uptr kAllocatorSize  =  0x20000000000ULL;  // 2T.\n# elif defined(__aarch64__)\n// AArch64/SANITIZIER_CAN_USER_ALLOCATOR64 is only for 42-bit VMA\n// so no need to different values for different VMA.\nconst uptr kAllocatorSpace =  0x10000000000ULL;\nconst uptr kAllocatorSize  =  0x10000000000ULL;  // 3T.\n# else\nconst uptr kAllocatorSpace = 0x600000000000ULL;\nconst uptr kAllocatorSize  =  0x40000000000ULL;  // 4T.\n# endif\ntypedef DefaultSizeClassMap SizeClassMap;\ntypedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 0 /*metadata*/,\n    SizeClassMap, AsanMapUnmapCallback> PrimaryAllocator;\n#else  // Fallback to SizeClassAllocator32.\nstatic const uptr kRegionSizeLog = 20;\nstatic const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;\n# if SANITIZER_WORDSIZE == 32\ntypedef FlatByteMap<kNumRegions> ByteMap;\n# elif SANITIZER_WORDSIZE == 64\ntypedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;\n# endif\ntypedef CompactSizeClassMap SizeClassMap;\ntypedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE, 16,\n  SizeClassMap, kRegionSizeLog,\n  ByteMap,\n  AsanMapUnmapCallback> PrimaryAllocator;\n#endif  // SANITIZER_CAN_USE_ALLOCATOR64\n\nstatic const uptr kNumberOfSizeClasses = SizeClassMap::kNumClasses;\ntypedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;\ntypedef LargeMmapAllocator<AsanMapUnmapCallback> SecondaryAllocator;\ntypedef CombinedAllocator<PrimaryAllocator, AllocatorCache,\n    SecondaryAllocator> AsanAllocator;\n\n\nstruct AsanThreadLocalMallocStorage {\n  uptr quarantine_cache[16];\n  AllocatorCache allocator_cache;\n  void CommitBack();\n private:\n  // These objects are allocated via mmap() and are zero-initialized.\n  AsanThreadLocalMallocStorage() {}\n};\n\nvoid *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack,\n                    AllocType alloc_type);\nvoid asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type);\nvoid asan_sized_free(void *ptr, uptr size, BufferedStackTrace *stack,\n                     AllocType alloc_type);\n\nvoid *asan_malloc(uptr size, BufferedStackTrace *stack);\nvoid *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack);\nvoid *asan_realloc(void *p, uptr size, BufferedStackTrace *stack);\nvoid *asan_valloc(uptr size, BufferedStackTrace *stack);\nvoid *asan_pvalloc(uptr size, BufferedStackTrace *stack);\n\nint asan_posix_memalign(void **memptr, uptr alignment, uptr size,\n                        BufferedStackTrace *stack);\nuptr asan_malloc_usable_size(void *ptr, uptr pc, uptr bp);\n\nuptr asan_mz_size(const void *ptr);\nvoid asan_mz_force_lock();\nvoid asan_mz_force_unlock();\n\nvoid PrintInternalAllocatorStats();\nvoid AsanSoftRssLimitExceededCallback(bool exceeded);\n\n}  // namespace __asan\n#endif  // ASAN_ALLOCATOR_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_android_stub.cc",
    "content": "#include \"sanitizer/asan_interface.h\"\n\n__attribute__((section(\".preinit_array\")))\n  typeof(__asan_init) *__asan_preinit =__asan_init;\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_blacklist.txt",
    "content": "# Blacklist for AddressSanitizer. Turns off instrumentation of particular\n# functions or sources. Use with care. You may set location of blacklist\n# at compile-time using -fsanitize-blacklist=<path> flag.\n\n# Example usage:\n# fun:*bad_function_name*\n# src:file_with_tricky_code.cc\n# global:*global_with_bad_access_or_initialization*\n# global:*global_with_initialization_issues*=init\n# type:*Namespace::ClassName*=init\n\n# Stack buffer overflow in VC/INCLUDE/xlocnum, see http://goo.gl/L4qqUG\nfun:*_Find_elem@*@std*\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_debugging.cc",
    "content": "//===-- asan_debugging.cc -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// This file contains various functions that are generally useful to call when\n// using a debugger (LLDB, GDB).\n//===----------------------------------------------------------------------===//\n\n#include \"asan_allocator.h\"\n#include \"asan_flags.h\"\n#include \"asan_internal.h\"\n#include \"asan_mapping.h\"\n#include \"asan_report.h\"\n#include \"asan_thread.h\"\n\nnamespace __asan {\n\nvoid GetInfoForStackVar(uptr addr, AddressDescription *descr, AsanThread *t) {\n  descr->name[0] = 0;\n  descr->region_address = 0;\n  descr->region_size = 0;\n  descr->region_kind = \"stack\";\n\n  AsanThread::StackFrameAccess access;\n  if (!t->GetStackFrameAccessByAddr(addr, &access))\n    return;\n  InternalMmapVector<StackVarDescr> vars(16);\n  if (!ParseFrameDescription(access.frame_descr, &vars)) {\n    return;\n  }\n\n  for (uptr i = 0; i < vars.size(); i++) {\n    if (access.offset <= vars[i].beg + vars[i].size) {\n      internal_strncat(descr->name, vars[i].name_pos,\n                       Min(descr->name_size, vars[i].name_len));\n      descr->region_address = addr - (access.offset - vars[i].beg);\n      descr->region_size = vars[i].size;\n      return;\n    }\n  }\n}\n\nvoid GetInfoForHeapAddress(uptr addr, AddressDescription *descr) {\n  AsanChunkView chunk = FindHeapChunkByAddress(addr);\n\n  descr->name[0] = 0;\n  descr->region_address = 0;\n  descr->region_size = 0;\n\n  if (!chunk.IsValid()) {\n    descr->region_kind = \"heap-invalid\";\n    return;\n  }\n\n  descr->region_address = chunk.Beg();\n  descr->region_size = chunk.UsedSize();\n  descr->region_kind = \"heap\";\n}\n\nvoid AsanLocateAddress(uptr addr, AddressDescription *descr) {\n  if (DescribeAddressIfShadow(addr, descr, /* print */ false)) {\n    return;\n  }\n  if (GetInfoForAddressIfGlobal(addr, descr)) {\n    return;\n  }\n  asanThreadRegistry().Lock();\n  AsanThread *thread = FindThreadByStackAddress(addr);\n  asanThreadRegistry().Unlock();\n  if (thread) {\n    GetInfoForStackVar(addr, descr, thread);\n    return;\n  }\n  GetInfoForHeapAddress(addr, descr);\n}\n\nstatic uptr AsanGetStack(uptr addr, uptr *trace, u32 size, u32 *thread_id,\n                         bool alloc_stack) {\n  AsanChunkView chunk = FindHeapChunkByAddress(addr);\n  if (!chunk.IsValid()) return 0;\n\n  StackTrace stack(nullptr, 0);\n  if (alloc_stack) {\n    if (chunk.AllocTid() == kInvalidTid) return 0;\n    stack = chunk.GetAllocStack();\n    if (thread_id) *thread_id = chunk.AllocTid();\n  } else {\n    if (chunk.FreeTid() == kInvalidTid) return 0;\n    stack = chunk.GetFreeStack();\n    if (thread_id) *thread_id = chunk.FreeTid();\n  }\n\n  if (trace && size) {\n    size = Min(size, Min(stack.size, kStackTraceMax));\n    for (uptr i = 0; i < size; i++)\n      trace[i] = StackTrace::GetPreviousInstructionPc(stack.trace[i]);\n\n    return size;\n  }\n\n  return 0;\n}\n\n} // namespace __asan\n\nusing namespace __asan;\n\nSANITIZER_INTERFACE_ATTRIBUTE\nconst char *__asan_locate_address(uptr addr, char *name, uptr name_size,\n                                  uptr *region_address, uptr *region_size) {\n  AddressDescription descr = { name, name_size, 0, 0, nullptr };\n  AsanLocateAddress(addr, &descr);\n  if (region_address) *region_address = descr.region_address;\n  if (region_size) *region_size = descr.region_size;\n  return descr.region_kind;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nuptr __asan_get_alloc_stack(uptr addr, uptr *trace, uptr size, u32 *thread_id) {\n  return AsanGetStack(addr, trace, size, thread_id, /* alloc_stack */ true);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nuptr __asan_get_free_stack(uptr addr, uptr *trace, uptr size, u32 *thread_id) {\n  return AsanGetStack(addr, trace, size, thread_id, /* alloc_stack */ false);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __asan_get_shadow_mapping(uptr *shadow_scale, uptr *shadow_offset) {\n  if (shadow_scale)\n    *shadow_scale = SHADOW_SCALE;\n  if (shadow_offset)\n    *shadow_offset = SHADOW_OFFSET;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_fake_stack.cc",
    "content": "//===-- asan_fake_stack.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// FakeStack is used to detect use-after-return bugs.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_allocator.h\"\n#include \"asan_poisoning.h\"\n#include \"asan_thread.h\"\n\nnamespace __asan {\n\nstatic const u64 kMagic1 = kAsanStackAfterReturnMagic;\nstatic const u64 kMagic2 = (kMagic1 << 8) | kMagic1;\nstatic const u64 kMagic4 = (kMagic2 << 16) | kMagic2;\nstatic const u64 kMagic8 = (kMagic4 << 32) | kMagic4;\n\nstatic const u64 kAllocaRedzoneSize = 32UL;\nstatic const u64 kAllocaRedzoneMask = 31UL;\n\n// For small size classes inline PoisonShadow for better performance.\nALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) {\n  CHECK_EQ(SHADOW_SCALE, 3);  // This code expects SHADOW_SCALE=3.\n  u64 *shadow = reinterpret_cast<u64*>(MemToShadow(ptr));\n  if (class_id <= 6) {\n    for (uptr i = 0; i < (1U << class_id); i++) {\n      shadow[i] = magic;\n      // Make sure this does not become memset.\n      SanitizerBreakOptimization(nullptr);\n    }\n  } else {\n    // The size class is too big, it's cheaper to poison only size bytes.\n    PoisonShadow(ptr, size, static_cast<u8>(magic));\n  }\n}\n\nFakeStack *FakeStack::Create(uptr stack_size_log) {\n  static uptr kMinStackSizeLog = 16;\n  static uptr kMaxStackSizeLog = FIRST_32_SECOND_64(24, 28);\n  if (stack_size_log < kMinStackSizeLog)\n    stack_size_log = kMinStackSizeLog;\n  if (stack_size_log > kMaxStackSizeLog)\n    stack_size_log = kMaxStackSizeLog;\n  uptr size = RequiredSize(stack_size_log);\n  FakeStack *res = reinterpret_cast<FakeStack *>(\n      flags()->uar_noreserve ? MmapNoReserveOrDie(size, \"FakeStack\")\n                             : MmapOrDie(size, \"FakeStack\"));\n  res->stack_size_log_ = stack_size_log;\n  u8 *p = reinterpret_cast<u8 *>(res);\n  VReport(1, \"T%d: FakeStack created: %p -- %p stack_size_log: %zd; \"\n          \"mmapped %zdK, noreserve=%d \\n\",\n          GetCurrentTidOrInvalid(), p,\n          p + FakeStack::RequiredSize(stack_size_log), stack_size_log,\n          size >> 10, flags()->uar_noreserve);\n  return res;\n}\n\nvoid FakeStack::Destroy(int tid) {\n  PoisonAll(0);\n  if (Verbosity() >= 2) {\n    InternalScopedString str(kNumberOfSizeClasses * 50);\n    for (uptr class_id = 0; class_id < kNumberOfSizeClasses; class_id++)\n      str.append(\"%zd: %zd/%zd; \", class_id, hint_position_[class_id],\n                 NumberOfFrames(stack_size_log(), class_id));\n    Report(\"T%d: FakeStack destroyed: %s\\n\", tid, str.data());\n  }\n  uptr size = RequiredSize(stack_size_log_);\n  FlushUnneededASanShadowMemory(reinterpret_cast<uptr>(this), size);\n  UnmapOrDie(this, size);\n}\n\nvoid FakeStack::PoisonAll(u8 magic) {\n  PoisonShadow(reinterpret_cast<uptr>(this), RequiredSize(stack_size_log()),\n               magic);\n}\n\n#if !defined(_MSC_VER) || defined(__clang__)\nALWAYS_INLINE USED\n#endif\nFakeFrame *FakeStack::Allocate(uptr stack_size_log, uptr class_id,\n                               uptr real_stack) {\n  CHECK_LT(class_id, kNumberOfSizeClasses);\n  if (needs_gc_)\n    GC(real_stack);\n  uptr &hint_position = hint_position_[class_id];\n  const int num_iter = NumberOfFrames(stack_size_log, class_id);\n  u8 *flags = GetFlags(stack_size_log, class_id);\n  for (int i = 0; i < num_iter; i++) {\n    uptr pos = ModuloNumberOfFrames(stack_size_log, class_id, hint_position++);\n    // This part is tricky. On one hand, checking and setting flags[pos]\n    // should be atomic to ensure async-signal safety. But on the other hand,\n    // if the signal arrives between checking and setting flags[pos], the\n    // signal handler's fake stack will start from a different hint_position\n    // and so will not touch this particular byte. So, it is safe to do this\n    // with regular non-atimic load and store (at least I was not able to make\n    // this code crash).\n    if (flags[pos]) continue;\n    flags[pos] = 1;\n    FakeFrame *res = reinterpret_cast<FakeFrame *>(\n        GetFrame(stack_size_log, class_id, pos));\n    res->real_stack = real_stack;\n    *SavedFlagPtr(reinterpret_cast<uptr>(res), class_id) = &flags[pos];\n    return res;\n  }\n  return nullptr; // We are out of fake stack.\n}\n\nuptr FakeStack::AddrIsInFakeStack(uptr ptr, uptr *frame_beg, uptr *frame_end) {\n  uptr stack_size_log = this->stack_size_log();\n  uptr beg = reinterpret_cast<uptr>(GetFrame(stack_size_log, 0, 0));\n  uptr end = reinterpret_cast<uptr>(this) + RequiredSize(stack_size_log);\n  if (ptr < beg || ptr >= end) return 0;\n  uptr class_id = (ptr - beg) >> stack_size_log;\n  uptr base = beg + (class_id << stack_size_log);\n  CHECK_LE(base, ptr);\n  CHECK_LT(ptr, base + (1UL << stack_size_log));\n  uptr pos = (ptr - base) >> (kMinStackFrameSizeLog + class_id);\n  uptr res = base + pos * BytesInSizeClass(class_id);\n  *frame_end = res + BytesInSizeClass(class_id);\n  *frame_beg = res + sizeof(FakeFrame);\n  return res;\n}\n\nvoid FakeStack::HandleNoReturn() {\n  needs_gc_ = true;\n}\n\n// When throw, longjmp or some such happens we don't call OnFree() and\n// as the result may leak one or more fake frames, but the good news is that\n// we are notified about all such events by HandleNoReturn().\n// If we recently had such no-return event we need to collect garbage frames.\n// We do it based on their 'real_stack' values -- everything that is lower\n// than the current real_stack is garbage.\nNOINLINE void FakeStack::GC(uptr real_stack) {\n  uptr collected = 0;\n  for (uptr class_id = 0; class_id < kNumberOfSizeClasses; class_id++) {\n    u8 *flags = GetFlags(stack_size_log(), class_id);\n    for (uptr i = 0, n = NumberOfFrames(stack_size_log(), class_id); i < n;\n         i++) {\n      if (flags[i] == 0) continue;  // not allocated.\n      FakeFrame *ff = reinterpret_cast<FakeFrame *>(\n          GetFrame(stack_size_log(), class_id, i));\n      if (ff->real_stack < real_stack) {\n        flags[i] = 0;\n        collected++;\n      }\n    }\n  }\n  needs_gc_ = false;\n}\n\nvoid FakeStack::ForEachFakeFrame(RangeIteratorCallback callback, void *arg) {\n  for (uptr class_id = 0; class_id < kNumberOfSizeClasses; class_id++) {\n    u8 *flags = GetFlags(stack_size_log(), class_id);\n    for (uptr i = 0, n = NumberOfFrames(stack_size_log(), class_id); i < n;\n         i++) {\n      if (flags[i] == 0) continue;  // not allocated.\n      FakeFrame *ff = reinterpret_cast<FakeFrame *>(\n          GetFrame(stack_size_log(), class_id, i));\n      uptr begin = reinterpret_cast<uptr>(ff);\n      callback(begin, begin + FakeStack::BytesInSizeClass(class_id), arg);\n    }\n  }\n}\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nstatic THREADLOCAL FakeStack *fake_stack_tls;\n\nFakeStack *GetTLSFakeStack() {\n  return fake_stack_tls;\n}\nvoid SetTLSFakeStack(FakeStack *fs) {\n  fake_stack_tls = fs;\n}\n#else\nFakeStack *GetTLSFakeStack() { return 0; }\nvoid SetTLSFakeStack(FakeStack *fs) { }\n#endif  // SANITIZER_LINUX && !SANITIZER_ANDROID\n\nstatic FakeStack *GetFakeStack() {\n  AsanThread *t = GetCurrentThread();\n  if (!t) return nullptr;\n  return t->fake_stack();\n}\n\nstatic FakeStack *GetFakeStackFast() {\n  if (FakeStack *fs = GetTLSFakeStack())\n    return fs;\n  if (!__asan_option_detect_stack_use_after_return)\n    return nullptr;\n  return GetFakeStack();\n}\n\nALWAYS_INLINE uptr OnMalloc(uptr class_id, uptr size) {\n  FakeStack *fs = GetFakeStackFast();\n  if (!fs) return 0;\n  uptr local_stack;\n  uptr real_stack = reinterpret_cast<uptr>(&local_stack);\n  FakeFrame *ff = fs->Allocate(fs->stack_size_log(), class_id, real_stack);\n  if (!ff) return 0;  // Out of fake stack.\n  uptr ptr = reinterpret_cast<uptr>(ff);\n  SetShadow(ptr, size, class_id, 0);\n  return ptr;\n}\n\nALWAYS_INLINE void OnFree(uptr ptr, uptr class_id, uptr size) {\n  FakeStack::Deallocate(ptr, class_id);\n  SetShadow(ptr, size, class_id, kMagic8);\n}\n\n} // namespace __asan\n\n// ---------------------- Interface ---------------- {{{1\nusing namespace __asan;\n#define DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(class_id)                       \\\n  extern \"C\" SANITIZER_INTERFACE_ATTRIBUTE uptr                                \\\n      __asan_stack_malloc_##class_id(uptr size) {                              \\\n    return OnMalloc(class_id, size);                                           \\\n  }                                                                            \\\n  extern \"C\" SANITIZER_INTERFACE_ATTRIBUTE void __asan_stack_free_##class_id(  \\\n      uptr ptr, uptr size) {                                                   \\\n    OnFree(ptr, class_id, size);                                               \\\n  }\n\nDEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(0)\nDEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(1)\nDEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(2)\nDEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(3)\nDEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(4)\nDEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(5)\nDEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(6)\nDEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(7)\nDEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(8)\nDEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(9)\nDEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(10)\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid *__asan_get_current_fake_stack() { return GetFakeStackFast(); }\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,\n                                   void **end) {\n  FakeStack *fs = reinterpret_cast<FakeStack*>(fake_stack);\n  if (!fs) return nullptr;\n  uptr frame_beg, frame_end;\n  FakeFrame *frame = reinterpret_cast<FakeFrame *>(fs->AddrIsInFakeStack(\n      reinterpret_cast<uptr>(addr), &frame_beg, &frame_end));\n  if (!frame) return nullptr;\n  if (frame->magic != kCurrentStackFrameMagic)\n    return nullptr;\n  if (beg) *beg = reinterpret_cast<void*>(frame_beg);\n  if (end) *end = reinterpret_cast<void*>(frame_end);\n  return reinterpret_cast<void*>(frame->real_stack);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __asan_alloca_poison(uptr addr, uptr size) {\n  uptr LeftRedzoneAddr = addr - kAllocaRedzoneSize;\n  uptr PartialRzAddr = addr + size;\n  uptr RightRzAddr = (PartialRzAddr + kAllocaRedzoneMask) & ~kAllocaRedzoneMask;\n  uptr PartialRzAligned = PartialRzAddr & ~(SHADOW_GRANULARITY - 1);\n  FastPoisonShadow(LeftRedzoneAddr, kAllocaRedzoneSize, kAsanAllocaLeftMagic);\n  FastPoisonShadowPartialRightRedzone(\n      PartialRzAligned, PartialRzAddr % SHADOW_GRANULARITY,\n      RightRzAddr - PartialRzAligned, kAsanAllocaRightMagic);\n  FastPoisonShadow(RightRzAddr, kAllocaRedzoneSize, kAsanAllocaRightMagic);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __asan_allocas_unpoison(uptr top, uptr bottom) {\n  if ((!top) || (top > bottom)) return;\n  REAL(memset)(reinterpret_cast<void*>(MemToShadow(top)), 0,\n               (bottom - top) / SHADOW_GRANULARITY);\n}\n} // extern \"C\"\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_fake_stack.h",
    "content": "//===-- asan_fake_stack.h ---------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// ASan-private header for asan_fake_stack.cc, implements FakeStack.\n//===----------------------------------------------------------------------===//\n\n#ifndef ASAN_FAKE_STACK_H\n#define ASAN_FAKE_STACK_H\n\n#include \"sanitizer_common/sanitizer_common.h\"\n\nnamespace __asan {\n\n// Fake stack frame contains local variables of one function.\nstruct FakeFrame {\n  uptr magic;  // Modified by the instrumented code.\n  uptr descr;  // Modified by the instrumented code.\n  uptr pc;     // Modified by the instrumented code.\n  uptr real_stack;\n};\n\n// For each thread we create a fake stack and place stack objects on this fake\n// stack instead of the real stack. The fake stack is not really a stack but\n// a fast malloc-like allocator so that when a function exits the fake stack\n// is not popped but remains there for quite some time until gets used again.\n// So, we poison the objects on the fake stack when function returns.\n// It helps us find use-after-return bugs.\n//\n// The FakeStack objects is allocated by a single mmap call and has no other\n// pointers. The size of the fake stack depends on the actual thread stack size\n// and thus can not be a constant.\n// stack_size is a power of two greater or equal to the thread's stack size;\n// we store it as its logarithm (stack_size_log).\n// FakeStack has kNumberOfSizeClasses (11) size classes, each size class\n// is a power of two, starting from 64 bytes. Each size class occupies\n// stack_size bytes and thus can allocate\n// NumberOfFrames=(stack_size/BytesInSizeClass) fake frames (also a power of 2).\n// For each size class we have NumberOfFrames allocation flags,\n// each flag indicates whether the given frame is currently allocated.\n// All flags for size classes 0 .. 10 are stored in a single contiguous region\n// followed by another contiguous region which contains the actual memory for\n// size classes. The addresses are computed by GetFlags and GetFrame without\n// any memory accesses solely based on 'this' and stack_size_log.\n// Allocate() flips the appropriate allocation flag atomically, thus achieving\n// async-signal safety.\n// This allocator does not have quarantine per se, but it tries to allocate the\n// frames in round robin fasion to maximize the delay between a deallocation\n// and the next allocation.\nclass FakeStack {\n  static const uptr kMinStackFrameSizeLog = 6;  // Min frame is 64B.\n  static const uptr kMaxStackFrameSizeLog = 16;  // Max stack frame is 64K.\n\n public:\n  static const uptr kNumberOfSizeClasses =\n       kMaxStackFrameSizeLog - kMinStackFrameSizeLog + 1;\n\n  // CTOR: create the FakeStack as a single mmap-ed object.\n  static FakeStack *Create(uptr stack_size_log);\n\n  void Destroy(int tid);\n\n  // stack_size_log is at least 15 (stack_size >= 32K).\n  static uptr SizeRequiredForFlags(uptr stack_size_log) {\n    return 1UL << (stack_size_log + 1 - kMinStackFrameSizeLog);\n  }\n\n  // Each size class occupies stack_size bytes.\n  static uptr SizeRequiredForFrames(uptr stack_size_log) {\n    return (1ULL << stack_size_log) * kNumberOfSizeClasses;\n  }\n\n  // Number of bytes requires for the whole object.\n  static uptr RequiredSize(uptr stack_size_log) {\n    return kFlagsOffset + SizeRequiredForFlags(stack_size_log) +\n           SizeRequiredForFrames(stack_size_log);\n  }\n\n  // Offset of the given flag from the first flag.\n  // The flags for class 0 begin at offset  000000000\n  // The flags for class 1 begin at offset  100000000\n  // ....................2................  110000000\n  // ....................3................  111000000\n  // and so on.\n  static uptr FlagsOffset(uptr stack_size_log, uptr class_id) {\n    uptr t = kNumberOfSizeClasses - 1 - class_id;\n    const uptr all_ones = (1 << (kNumberOfSizeClasses - 1)) - 1;\n    return ((all_ones >> t) << t) << (stack_size_log - 15);\n  }\n\n  static uptr NumberOfFrames(uptr stack_size_log, uptr class_id) {\n    return 1UL << (stack_size_log - kMinStackFrameSizeLog - class_id);\n  }\n\n  // Divide n by the numbe of frames in size class.\n  static uptr ModuloNumberOfFrames(uptr stack_size_log, uptr class_id, uptr n) {\n    return n & (NumberOfFrames(stack_size_log, class_id) - 1);\n  }\n\n  // The the pointer to the flags of the given class_id.\n  u8 *GetFlags(uptr stack_size_log, uptr class_id) {\n    return reinterpret_cast<u8 *>(this) + kFlagsOffset +\n           FlagsOffset(stack_size_log, class_id);\n  }\n\n  // Get frame by class_id and pos.\n  u8 *GetFrame(uptr stack_size_log, uptr class_id, uptr pos) {\n    return reinterpret_cast<u8 *>(this) + kFlagsOffset +\n           SizeRequiredForFlags(stack_size_log) +\n           (1 << stack_size_log) * class_id + BytesInSizeClass(class_id) * pos;\n  }\n\n  // Allocate the fake frame.\n  FakeFrame *Allocate(uptr stack_size_log, uptr class_id, uptr real_stack);\n\n  // Deallocate the fake frame: read the saved flag address and write 0 there.\n  static void Deallocate(uptr x, uptr class_id) {\n    **SavedFlagPtr(x, class_id) = 0;\n  }\n\n  // Poison the entire FakeStack's shadow with the magic value.\n  void PoisonAll(u8 magic);\n\n  // Return the beginning of the FakeFrame or 0 if the address is not ours.\n  uptr AddrIsInFakeStack(uptr addr, uptr *frame_beg, uptr *frame_end);\n  USED uptr AddrIsInFakeStack(uptr addr) {\n    uptr t1, t2;\n    return AddrIsInFakeStack(addr, &t1, &t2);\n  }\n\n  // Number of bytes in a fake frame of this size class.\n  static uptr BytesInSizeClass(uptr class_id) {\n    return 1UL << (class_id + kMinStackFrameSizeLog);\n  }\n\n  // The fake frame is guaranteed to have a right redzone.\n  // We use the last word of that redzone to store the address of the flag\n  // that corresponds to the current frame to make faster deallocation.\n  static u8 **SavedFlagPtr(uptr x, uptr class_id) {\n    return reinterpret_cast<u8 **>(x + BytesInSizeClass(class_id) - sizeof(x));\n  }\n\n  uptr stack_size_log() const { return stack_size_log_; }\n\n  void HandleNoReturn();\n  void GC(uptr real_stack);\n\n  void ForEachFakeFrame(RangeIteratorCallback callback, void *arg);\n\n private:\n  FakeStack() { }\n  static const uptr kFlagsOffset = 4096;  // This is were the flags begin.\n  // Must match the number of uses of DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID\n  COMPILER_CHECK(kNumberOfSizeClasses == 11);\n  static const uptr kMaxStackMallocSize = 1 << kMaxStackFrameSizeLog;\n\n  uptr hint_position_[kNumberOfSizeClasses];\n  uptr stack_size_log_;\n  // a bit is set if something was allocated from the corresponding size class.\n  bool needs_gc_;\n};\n\nFakeStack *GetTLSFakeStack();\nvoid SetTLSFakeStack(FakeStack *fs);\n\n}  // namespace __asan\n\n#endif  // ASAN_FAKE_STACK_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_flags.cc",
    "content": "//===-- asan_flags.cc -------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// ASan flag parsing logic.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_activation.h\"\n#include \"asan_flags.h\"\n#include \"asan_interface_internal.h\"\n#include \"asan_stack.h\"\n#include \"lsan/lsan_common.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_flag_parser.h\"\n#include \"ubsan/ubsan_flags.h\"\n#include \"ubsan/ubsan_platform.h\"\n\nnamespace __asan {\n\nFlags asan_flags_dont_use_directly;  // use via flags().\n\nstatic const char *MaybeCallAsanDefaultOptions() {\n  return (&__asan_default_options) ? __asan_default_options() : \"\";\n}\n\nstatic const char *MaybeUseAsanDefaultOptionsCompileDefinition() {\n#ifdef ASAN_DEFAULT_OPTIONS\n// Stringize the macro value.\n# define ASAN_STRINGIZE(x) #x\n# define ASAN_STRINGIZE_OPTIONS(options) ASAN_STRINGIZE(options)\n  return ASAN_STRINGIZE_OPTIONS(ASAN_DEFAULT_OPTIONS);\n#else\n  return \"\";\n#endif\n}\n\nvoid Flags::SetDefaults() {\n#define ASAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;\n#include \"asan_flags.inc\"\n#undef ASAN_FLAG\n}\n\nstatic void RegisterAsanFlags(FlagParser *parser, Flags *f) {\n#define ASAN_FLAG(Type, Name, DefaultValue, Description) \\\n  RegisterFlag(parser, #Name, Description, &f->Name);\n#include \"asan_flags.inc\"\n#undef ASAN_FLAG\n}\n\nvoid InitializeFlags() {\n  // Set the default values and prepare for parsing ASan and common flags.\n  SetCommonFlagsDefaults();\n  {\n    CommonFlags cf;\n    cf.CopyFrom(*common_flags());\n    cf.detect_leaks = CAN_SANITIZE_LEAKS;\n    cf.external_symbolizer_path = GetEnv(\"ASAN_SYMBOLIZER_PATH\");\n    cf.malloc_context_size = kDefaultMallocContextSize;\n    cf.intercept_tls_get_addr = true;\n    cf.exitcode = 1;\n    OverrideCommonFlags(cf);\n  }\n  Flags *f = flags();\n  f->SetDefaults();\n\n  FlagParser asan_parser;\n  RegisterAsanFlags(&asan_parser, f);\n  RegisterCommonFlags(&asan_parser);\n\n  // Set the default values and prepare for parsing LSan and UBSan flags\n  // (which can also overwrite common flags).\n#if CAN_SANITIZE_LEAKS\n  __lsan::Flags *lf = __lsan::flags();\n  lf->SetDefaults();\n\n  FlagParser lsan_parser;\n  __lsan::RegisterLsanFlags(&lsan_parser, lf);\n  RegisterCommonFlags(&lsan_parser);\n#endif\n\n#if CAN_SANITIZE_UB\n  __ubsan::Flags *uf = __ubsan::flags();\n  uf->SetDefaults();\n\n  FlagParser ubsan_parser;\n  __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);\n  RegisterCommonFlags(&ubsan_parser);\n#endif\n\n  // Override from ASan compile definition.\n  const char *asan_compile_def = MaybeUseAsanDefaultOptionsCompileDefinition();\n  asan_parser.ParseString(asan_compile_def);\n\n  // Override from user-specified string.\n  const char *asan_default_options = MaybeCallAsanDefaultOptions();\n  asan_parser.ParseString(asan_default_options);\n#if CAN_SANITIZE_UB\n  const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();\n  ubsan_parser.ParseString(ubsan_default_options);\n#endif\n\n  // Override from command line.\n  asan_parser.ParseString(GetEnv(\"ASAN_OPTIONS\"));\n#if CAN_SANITIZE_LEAKS\n  lsan_parser.ParseString(GetEnv(\"LSAN_OPTIONS\"));\n#endif\n#if CAN_SANITIZE_UB\n  ubsan_parser.ParseString(GetEnv(\"UBSAN_OPTIONS\"));\n#endif\n\n  SetVerbosity(common_flags()->verbosity);\n\n  // TODO(eugenis): dump all flags at verbosity>=2?\n  if (Verbosity()) ReportUnrecognizedFlags();\n\n  if (common_flags()->help) {\n    // TODO(samsonov): print all of the flags (ASan, LSan, common).\n    asan_parser.PrintFlagDescriptions();\n  }\n\n  // Flag validation:\n  if (!CAN_SANITIZE_LEAKS && common_flags()->detect_leaks) {\n    Report(\"%s: detect_leaks is not supported on this platform.\\n\",\n           SanitizerToolName);\n    Die();\n  }\n  // Make \"strict_init_order\" imply \"check_initialization_order\".\n  // TODO(samsonov): Use a single runtime flag for an init-order checker.\n  if (f->strict_init_order) {\n    f->check_initialization_order = true;\n  }\n  CHECK_LE((uptr)common_flags()->malloc_context_size, kStackTraceMax);\n  CHECK_LE(f->min_uar_stack_size_log, f->max_uar_stack_size_log);\n  CHECK_GE(f->redzone, 16);\n  CHECK_GE(f->max_redzone, f->redzone);\n  CHECK_LE(f->max_redzone, 2048);\n  CHECK(IsPowerOfTwo(f->redzone));\n  CHECK(IsPowerOfTwo(f->max_redzone));\n\n  // quarantine_size is deprecated but we still honor it.\n  // quarantine_size can not be used together with quarantine_size_mb.\n  if (f->quarantine_size >= 0 && f->quarantine_size_mb >= 0) {\n    Report(\"%s: please use either 'quarantine_size' (deprecated) or \"\n           \"quarantine_size_mb, but not both\\n\", SanitizerToolName);\n    Die();\n  }\n  if (f->quarantine_size >= 0)\n    f->quarantine_size_mb = f->quarantine_size >> 20;\n  if (f->quarantine_size_mb < 0) {\n    const int kDefaultQuarantineSizeMb =\n        (ASAN_LOW_MEMORY) ? 1UL << 6 : 1UL << 8;\n    f->quarantine_size_mb = kDefaultQuarantineSizeMb;\n  }\n}\n\n}  // namespace __asan\n\n#if !SANITIZER_SUPPORTS_WEAK_HOOKS\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nconst char* __asan_default_options() { return \"\"; }\n}  // extern \"C\"\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_flags.h",
    "content": "//===-- asan_flags.h -------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// ASan runtime flags.\n//===----------------------------------------------------------------------===//\n\n#ifndef ASAN_FLAGS_H\n#define ASAN_FLAGS_H\n\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"sanitizer_common/sanitizer_flag_parser.h\"\n\n// ASan flag values can be defined in four ways:\n// 1) initialized with default values at startup.\n// 2) overriden during compilation of ASan runtime by providing\n//    compile definition ASAN_DEFAULT_OPTIONS.\n// 3) overriden from string returned by user-specified function\n//    __asan_default_options().\n// 4) overriden from env variable ASAN_OPTIONS.\n// 5) overriden during ASan activation (for now used on Android only).\n\nnamespace __asan {\n\nstruct Flags {\n#define ASAN_FLAG(Type, Name, DefaultValue, Description) Type Name;\n#include \"asan_flags.inc\"\n#undef ASAN_FLAG\n\n  void SetDefaults();\n};\n\nextern Flags asan_flags_dont_use_directly;\ninline Flags *flags() {\n  return &asan_flags_dont_use_directly;\n}\n\nvoid InitializeFlags();\n\n}  // namespace __asan\n\n#endif  // ASAN_FLAGS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_flags.inc",
    "content": "//===-- asan_flags.inc ------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// ASan runtime flags.\n//\n//===----------------------------------------------------------------------===//\n#ifndef ASAN_FLAG\n# error \"Define ASAN_FLAG prior to including this file!\"\n#endif\n\n// ASAN_FLAG(Type, Name, DefaultValue, Description)\n// See COMMON_FLAG in sanitizer_flags.inc for more details.\n\nASAN_FLAG(int, quarantine_size, -1,\n            \"Deprecated, please use quarantine_size_mb.\")\nASAN_FLAG(int, quarantine_size_mb, -1,\n          \"Size (in Mb) of quarantine used to detect use-after-free \"\n          \"errors. Lower value may reduce memory usage but increase the \"\n          \"chance of false negatives.\")\nASAN_FLAG(int, redzone, 16,\n          \"Minimal size (in bytes) of redzones around heap objects. \"\n          \"Requirement: redzone >= 16, is a power of two.\")\nASAN_FLAG(int, max_redzone, 2048,\n          \"Maximal size (in bytes) of redzones around heap objects.\")\nASAN_FLAG(\n    bool, debug, false,\n    \"If set, prints some debugging information and does additional checks.\")\nASAN_FLAG(\n    int, report_globals, 1,\n    \"Controls the way to handle globals (0 - don't detect buffer overflow on \"\n    \"globals, 1 - detect buffer overflow, 2 - print data about registered \"\n    \"globals).\")\nASAN_FLAG(bool, check_initialization_order, false,\n          \"If set, attempts to catch initialization order issues.\")\nASAN_FLAG(\n    bool, replace_str, true,\n    \"If set, uses custom wrappers and replacements for libc string functions \"\n    \"to find more errors.\")\nASAN_FLAG(bool, replace_intrin, true,\n          \"If set, uses custom wrappers for memset/memcpy/memmove intinsics.\")\nASAN_FLAG(bool, detect_stack_use_after_return, false,\n          \"Enables stack-use-after-return checking at run-time.\")\nASAN_FLAG(int, min_uar_stack_size_log, 16, // We can't do smaller anyway.\n          \"Minimum fake stack size log.\")\nASAN_FLAG(int, max_uar_stack_size_log,\n          20, // 1Mb per size class, i.e. ~11Mb per thread\n          \"Maximum fake stack size log.\")\nASAN_FLAG(bool, uar_noreserve, false,\n          \"Use mmap with 'noreserve' flag to allocate fake stack.\")\nASAN_FLAG(\n    int, max_malloc_fill_size, 0x1000,  // By default, fill only the first 4K.\n    \"ASan allocator flag. max_malloc_fill_size is the maximal amount of \"\n    \"bytes that will be filled with malloc_fill_byte on malloc.\")\nASAN_FLAG(int, malloc_fill_byte, 0xbe,\n          \"Value used to fill the newly allocated memory.\")\nASAN_FLAG(bool, allow_user_poisoning, true,\n          \"If set, user may manually mark memory regions as poisoned or \"\n          \"unpoisoned.\")\nASAN_FLAG(\n    int, sleep_before_dying, 0,\n    \"Number of seconds to sleep between printing an error report and \"\n    \"terminating the program. Useful for debugging purposes (e.g. when one \"\n    \"needs to attach gdb).\")\nASAN_FLAG(bool, check_malloc_usable_size, true,\n          \"Allows the users to work around the bug in Nvidia drivers prior to \"\n          \"295.*.\")\nASAN_FLAG(bool, unmap_shadow_on_exit, false,\n          \"If set, explicitly unmaps the (huge) shadow at exit.\")\nASAN_FLAG(bool, protect_shadow_gap, true, \"If set, mprotect the shadow gap\")\nASAN_FLAG(bool, print_stats, false,\n          \"Print various statistics after printing an error message or if \"\n          \"atexit=1.\")\nASAN_FLAG(bool, print_legend, true, \"Print the legend for the shadow bytes.\")\nASAN_FLAG(bool, atexit, false,\n          \"If set, prints ASan exit stats even after program terminates \"\n          \"successfully.\")\nASAN_FLAG(\n    bool, print_full_thread_history, true,\n    \"If set, prints thread creation stacks for the threads involved in the \"\n    \"report and their ancestors up to the main thread.\")\nASAN_FLAG(\n    bool, poison_heap, true,\n    \"Poison (or not) the heap memory on [de]allocation. Zero value is useful \"\n    \"for benchmarking the allocator or instrumentator.\")\nASAN_FLAG(bool, poison_partial, true,\n          \"If true, poison partially addressable 8-byte aligned words \"\n          \"(default=true). This flag affects heap and global buffers, but not \"\n          \"stack buffers.\")\nASAN_FLAG(bool, poison_array_cookie, true,\n          \"Poison (or not) the array cookie after operator new[].\")\n\n// Turn off alloc/dealloc mismatch checker on Mac and Windows for now.\n// https://github.com/google/sanitizers/issues/131\n// https://github.com/google/sanitizers/issues/309\n// TODO(glider,timurrrr): Fix known issues and enable this back.\nASAN_FLAG(bool, alloc_dealloc_mismatch,\n          (SANITIZER_MAC == 0) && (SANITIZER_WINDOWS == 0),\n          \"Report errors on malloc/delete, new/free, new/delete[], etc.\")\n\nASAN_FLAG(bool, new_delete_type_mismatch, true,\n          \"Report errors on mismatch betwen size of new and delete.\")\nASAN_FLAG(\n    bool, strict_init_order, false,\n    \"If true, assume that dynamic initializers can never access globals from \"\n    \"other modules, even if the latter are already initialized.\")\nASAN_FLAG(\n    bool, start_deactivated, false,\n    \"If true, ASan tweaks a bunch of other flags (quarantine, redzone, heap \"\n    \"poisoning) to reduce memory consumption as much as possible, and \"\n    \"restores them to original values when the first instrumented module is \"\n    \"loaded into the process. This is mainly intended to be used on \"\n    \"Android. \")\nASAN_FLAG(\n    int, detect_invalid_pointer_pairs, 0,\n    \"If non-zero, try to detect operations like <, <=, >, >= and - on \"\n    \"invalid pointer pairs (e.g. when pointers belong to different objects). \"\n    \"The bigger the value the harder we try.\")\nASAN_FLAG(\n    bool, detect_container_overflow, true,\n    \"If true, honor the container overflow annotations. See \"\n    \"https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow\")\nASAN_FLAG(int, detect_odr_violation, 2,\n          \"If >=2, detect violation of One-Definition-Rule (ODR); \"\n          \"If ==1, detect ODR-violation only if the two variables \"\n          \"have different sizes\")\nASAN_FLAG(bool, dump_instruction_bytes, false,\n          \"If true, dump 16 bytes starting at the instruction that caused SEGV\")\nASAN_FLAG(const char *, suppressions, \"\", \"Suppressions file name.\")\nASAN_FLAG(bool, halt_on_error, true,\n          \"Crash the program after printing the first error report \"\n          \"(WARNING: USE AT YOUR OWN RISK!)\")\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_globals.cc",
    "content": "//===-- asan_globals.cc ---------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Handle globals.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_interceptors.h\"\n#include \"asan_internal.h\"\n#include \"asan_mapping.h\"\n#include \"asan_poisoning.h\"\n#include \"asan_report.h\"\n#include \"asan_stack.h\"\n#include \"asan_stats.h\"\n#include \"asan_suppressions.h\"\n#include \"asan_thread.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_mutex.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n\nnamespace __asan {\n\ntypedef __asan_global Global;\n\nstruct ListOfGlobals {\n  const Global *g;\n  ListOfGlobals *next;\n};\n\nstatic BlockingMutex mu_for_globals(LINKER_INITIALIZED);\nstatic LowLevelAllocator allocator_for_globals;\nstatic ListOfGlobals *list_of_all_globals;\n\nstatic const int kDynamicInitGlobalsInitialCapacity = 512;\nstruct DynInitGlobal {\n  Global g;\n  bool initialized;\n};\ntypedef InternalMmapVector<DynInitGlobal> VectorOfGlobals;\n// Lazy-initialized and never deleted.\nstatic VectorOfGlobals *dynamic_init_globals;\n\n// We want to remember where a certain range of globals was registered.\nstruct GlobalRegistrationSite {\n  u32 stack_id;\n  Global *g_first, *g_last;\n};\ntypedef InternalMmapVector<GlobalRegistrationSite> GlobalRegistrationSiteVector;\nstatic GlobalRegistrationSiteVector *global_registration_site_vector;\n\nALWAYS_INLINE void PoisonShadowForGlobal(const Global *g, u8 value) {\n  FastPoisonShadow(g->beg, g->size_with_redzone, value);\n}\n\nALWAYS_INLINE void PoisonRedZones(const Global &g) {\n  uptr aligned_size = RoundUpTo(g.size, SHADOW_GRANULARITY);\n  FastPoisonShadow(g.beg + aligned_size, g.size_with_redzone - aligned_size,\n                   kAsanGlobalRedzoneMagic);\n  if (g.size != aligned_size) {\n    FastPoisonShadowPartialRightRedzone(\n        g.beg + RoundDownTo(g.size, SHADOW_GRANULARITY),\n        g.size % SHADOW_GRANULARITY,\n        SHADOW_GRANULARITY,\n        kAsanGlobalRedzoneMagic);\n  }\n}\n\nconst uptr kMinimalDistanceFromAnotherGlobal = 64;\n\nstatic bool IsAddressNearGlobal(uptr addr, const __asan_global &g) {\n  if (addr <= g.beg - kMinimalDistanceFromAnotherGlobal) return false;\n  if (addr >= g.beg + g.size_with_redzone) return false;\n  return true;\n}\n\nstatic void ReportGlobal(const Global &g, const char *prefix) {\n  Report(\"%s Global[%p]: beg=%p size=%zu/%zu name=%s module=%s dyn_init=%zu\\n\",\n         prefix, &g, (void *)g.beg, g.size, g.size_with_redzone, g.name,\n         g.module_name, g.has_dynamic_init);\n  if (g.location) {\n    Report(\"  location (%p): name=%s[%p], %d %d\\n\", g.location,\n           g.location->filename, g.location->filename, g.location->line_no,\n           g.location->column_no);\n  }\n}\n\nstatic u32 FindRegistrationSite(const Global *g) {\n  mu_for_globals.CheckLocked();\n  CHECK(global_registration_site_vector);\n  for (uptr i = 0, n = global_registration_site_vector->size(); i < n; i++) {\n    GlobalRegistrationSite &grs = (*global_registration_site_vector)[i];\n    if (g >= grs.g_first && g <= grs.g_last)\n      return grs.stack_id;\n  }\n  return 0;\n}\n\nint GetGlobalsForAddress(uptr addr, Global *globals, u32 *reg_sites,\n                         int max_globals) {\n  if (!flags()->report_globals) return 0;\n  BlockingMutexLock lock(&mu_for_globals);\n  int res = 0;\n  for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {\n    const Global &g = *l->g;\n    if (flags()->report_globals >= 2)\n      ReportGlobal(g, \"Search\");\n    if (IsAddressNearGlobal(addr, g)) {\n      globals[res] = g;\n      if (reg_sites)\n        reg_sites[res] = FindRegistrationSite(&g);\n      res++;\n      if (res == max_globals) break;\n    }\n  }\n  return res;\n}\n\nbool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr) {\n  Global g = {};\n  if (GetGlobalsForAddress(addr, &g, nullptr, 1)) {\n    internal_strncpy(descr->name, g.name, descr->name_size);\n    descr->region_address = g.beg;\n    descr->region_size = g.size;\n    descr->region_kind = \"global\";\n    return true;\n  }\n  return false;\n}\n\n// Register a global variable.\n// This function may be called more than once for every global\n// so we store the globals in a map.\nstatic void RegisterGlobal(const Global *g) {\n  CHECK(asan_inited);\n  if (flags()->report_globals >= 2)\n    ReportGlobal(*g, \"Added\");\n  CHECK(flags()->report_globals);\n  CHECK(AddrIsInMem(g->beg));\n  CHECK(AddrIsAlignedByGranularity(g->beg));\n  CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));\n  if (flags()->detect_odr_violation) {\n    // Try detecting ODR (One Definition Rule) violation, i.e. the situation\n    // where two globals with the same name are defined in different modules.\n    if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) {\n      // This check may not be enough: if the first global is much larger\n      // the entire redzone of the second global may be within the first global.\n      for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {\n        if (g->beg == l->g->beg &&\n            (flags()->detect_odr_violation >= 2 || g->size != l->g->size) &&\n            !IsODRViolationSuppressed(g->name))\n          ReportODRViolation(g, FindRegistrationSite(g),\n                             l->g, FindRegistrationSite(l->g));\n      }\n    }\n  }\n  if (CanPoisonMemory())\n    PoisonRedZones(*g);\n  ListOfGlobals *l = new(allocator_for_globals) ListOfGlobals;\n  l->g = g;\n  l->next = list_of_all_globals;\n  list_of_all_globals = l;\n  if (g->has_dynamic_init) {\n    if (!dynamic_init_globals) {\n      dynamic_init_globals = new(allocator_for_globals)\n          VectorOfGlobals(kDynamicInitGlobalsInitialCapacity);\n    }\n    DynInitGlobal dyn_global = { *g, false };\n    dynamic_init_globals->push_back(dyn_global);\n  }\n}\n\nstatic void UnregisterGlobal(const Global *g) {\n  CHECK(asan_inited);\n  if (flags()->report_globals >= 2)\n    ReportGlobal(*g, \"Removed\");\n  CHECK(flags()->report_globals);\n  CHECK(AddrIsInMem(g->beg));\n  CHECK(AddrIsAlignedByGranularity(g->beg));\n  CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));\n  if (CanPoisonMemory())\n    PoisonShadowForGlobal(g, 0);\n  // We unpoison the shadow memory for the global but we do not remove it from\n  // the list because that would require O(n^2) time with the current list\n  // implementation. It might not be worth doing anyway.\n}\n\nvoid StopInitOrderChecking() {\n  BlockingMutexLock lock(&mu_for_globals);\n  if (!flags()->check_initialization_order || !dynamic_init_globals)\n    return;\n  flags()->check_initialization_order = false;\n  for (uptr i = 0, n = dynamic_init_globals->size(); i < n; ++i) {\n    DynInitGlobal &dyn_g = (*dynamic_init_globals)[i];\n    const Global *g = &dyn_g.g;\n    // Unpoison the whole global.\n    PoisonShadowForGlobal(g, 0);\n    // Poison redzones back.\n    PoisonRedZones(*g);\n  }\n}\n\n} // namespace __asan\n\n// ---------------------- Interface ---------------- {{{1\nusing namespace __asan;  // NOLINT\n\n// Register an array of globals.\nvoid __asan_register_globals(__asan_global *globals, uptr n) {\n  if (!flags()->report_globals) return;\n  GET_STACK_TRACE_MALLOC;\n  u32 stack_id = StackDepotPut(stack);\n  BlockingMutexLock lock(&mu_for_globals);\n  if (!global_registration_site_vector)\n    global_registration_site_vector =\n        new(allocator_for_globals) GlobalRegistrationSiteVector(128);\n  GlobalRegistrationSite site = {stack_id, &globals[0], &globals[n - 1]};\n  global_registration_site_vector->push_back(site);\n  if (flags()->report_globals >= 2) {\n    PRINT_CURRENT_STACK();\n    Printf(\"=== ID %d; %p %p\\n\", stack_id, &globals[0], &globals[n - 1]);\n  }\n  for (uptr i = 0; i < n; i++) {\n    RegisterGlobal(&globals[i]);\n  }\n}\n\n// Unregister an array of globals.\n// We must do this when a shared objects gets dlclosed.\nvoid __asan_unregister_globals(__asan_global *globals, uptr n) {\n  if (!flags()->report_globals) return;\n  BlockingMutexLock lock(&mu_for_globals);\n  for (uptr i = 0; i < n; i++) {\n    UnregisterGlobal(&globals[i]);\n  }\n}\n\n// This method runs immediately prior to dynamic initialization in each TU,\n// when all dynamically initialized globals are unpoisoned.  This method\n// poisons all global variables not defined in this TU, so that a dynamic\n// initializer can only touch global variables in the same TU.\nvoid __asan_before_dynamic_init(const char *module_name) {\n  if (!flags()->check_initialization_order ||\n      !CanPoisonMemory())\n    return;\n  bool strict_init_order = flags()->strict_init_order;\n  CHECK(dynamic_init_globals);\n  CHECK(module_name);\n  CHECK(asan_inited);\n  BlockingMutexLock lock(&mu_for_globals);\n  if (flags()->report_globals >= 3)\n    Printf(\"DynInitPoison module: %s\\n\", module_name);\n  for (uptr i = 0, n = dynamic_init_globals->size(); i < n; ++i) {\n    DynInitGlobal &dyn_g = (*dynamic_init_globals)[i];\n    const Global *g = &dyn_g.g;\n    if (dyn_g.initialized)\n      continue;\n    if (g->module_name != module_name)\n      PoisonShadowForGlobal(g, kAsanInitializationOrderMagic);\n    else if (!strict_init_order)\n      dyn_g.initialized = true;\n  }\n}\n\n// This method runs immediately after dynamic initialization in each TU, when\n// all dynamically initialized globals except for those defined in the current\n// TU are poisoned.  It simply unpoisons all dynamically initialized globals.\nvoid __asan_after_dynamic_init() {\n  if (!flags()->check_initialization_order ||\n      !CanPoisonMemory())\n    return;\n  CHECK(asan_inited);\n  BlockingMutexLock lock(&mu_for_globals);\n  // FIXME: Optionally report that we're unpoisoning globals from a module.\n  for (uptr i = 0, n = dynamic_init_globals->size(); i < n; ++i) {\n    DynInitGlobal &dyn_g = (*dynamic_init_globals)[i];\n    const Global *g = &dyn_g.g;\n    if (!dyn_g.initialized) {\n      // Unpoison the whole global.\n      PoisonShadowForGlobal(g, 0);\n      // Poison redzones back.\n      PoisonRedZones(*g);\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_init_version.h",
    "content": "//===-- asan_init_version.h -------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// This header defines a versioned __asan_init function to be called at the\n// startup of the instrumented program.\n//===----------------------------------------------------------------------===//\n#ifndef ASAN_INIT_VERSION_H\n#define ASAN_INIT_VERSION_H\n\nextern \"C\" {\n  // Every time the ASan ABI changes we also change the version number in the\n  // __asan_init function name.  Objects built with incompatible ASan ABI\n  // versions will not link with run-time.\n  // Changes between ABI versions:\n  // v1=>v2: added 'module_name' to __asan_global\n  // v2=>v3: stack frame description (created by the compiler)\n  //         contains the function PC as the 3-rd field (see\n  //         DescribeAddressIfStack).\n  // v3=>v4: added '__asan_global_source_location' to __asan_global.\n  // v4=>v5: changed the semantics and format of __asan_stack_malloc_ and\n  //         __asan_stack_free_ functions.\n  // v5=>v6: changed the name of the version check symbol\n  #define __asan_version_mismatch_check __asan_version_mismatch_check_v6\n}\n\n#endif  // ASAN_INIT_VERSION_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_interceptors.cc",
    "content": "//===-- asan_interceptors.cc ----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Intercept various libc functions.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_interceptors.h\"\n#include \"asan_allocator.h\"\n#include \"asan_internal.h\"\n#include \"asan_mapping.h\"\n#include \"asan_poisoning.h\"\n#include \"asan_report.h\"\n#include \"asan_stack.h\"\n#include \"asan_stats.h\"\n#include \"asan_suppressions.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n\n#if SANITIZER_POSIX\n#include \"sanitizer_common/sanitizer_posix.h\"\n#endif\n\n#if defined(__i386) && SANITIZER_LINUX\n#define ASAN_PTHREAD_CREATE_VERSION \"GLIBC_2.1\"\n#elif defined(__mips__) && SANITIZER_LINUX\n#define ASAN_PTHREAD_CREATE_VERSION \"GLIBC_2.2\"\n#endif\n\nnamespace __asan {\n\n// Return true if we can quickly decide that the region is unpoisoned.\nstatic inline bool QuickCheckForUnpoisonedRegion(uptr beg, uptr size) {\n  if (size == 0) return true;\n  if (size <= 32)\n    return !AddressIsPoisoned(beg) &&\n           !AddressIsPoisoned(beg + size - 1) &&\n           !AddressIsPoisoned(beg + size / 2);\n  return false;\n}\n\nstruct AsanInterceptorContext {\n  const char *interceptor_name;\n};\n\n// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,\n// and ASAN_WRITE_RANGE as macro instead of function so\n// that no extra frames are created, and stack trace contains\n// relevant information only.\n// We check all shadow bytes.\n#define ACCESS_MEMORY_RANGE(ctx, offset, size, isWrite) do {            \\\n    uptr __offset = (uptr)(offset);                                     \\\n    uptr __size = (uptr)(size);                                         \\\n    uptr __bad = 0;                                                     \\\n    if (__offset > __offset + __size) {                                 \\\n      GET_STACK_TRACE_FATAL_HERE;                                       \\\n      ReportStringFunctionSizeOverflow(__offset, __size, &stack);       \\\n    }                                                                   \\\n    if (!QuickCheckForUnpoisonedRegion(__offset, __size) &&             \\\n        (__bad = __asan_region_is_poisoned(__offset, __size))) {        \\\n      AsanInterceptorContext *_ctx = (AsanInterceptorContext *)ctx;     \\\n      bool suppressed = false;                                          \\\n      if (_ctx) {                                                       \\\n        suppressed = IsInterceptorSuppressed(_ctx->interceptor_name);   \\\n        if (!suppressed && HaveStackTraceBasedSuppressions()) {         \\\n          GET_STACK_TRACE_FATAL_HERE;                                   \\\n          suppressed = IsStackTraceSuppressed(&stack);                  \\\n        }                                                               \\\n      }                                                                 \\\n      if (!suppressed) {                                                \\\n        GET_CURRENT_PC_BP_SP;                                           \\\n        ReportGenericError(pc, bp, sp, __bad, isWrite, __size, 0, false);\\\n      }                                                                 \\\n    }                                                                   \\\n  } while (0)\n\n#define ASAN_READ_RANGE(ctx, offset, size) \\\n  ACCESS_MEMORY_RANGE(ctx, offset, size, false)\n#define ASAN_WRITE_RANGE(ctx, offset, size) \\\n  ACCESS_MEMORY_RANGE(ctx, offset, size, true)\n\n#define ASAN_READ_STRING_OF_LEN(ctx, s, len, n)                 \\\n  ASAN_READ_RANGE((ctx), (s),                                   \\\n    common_flags()->strict_string_checks ? (len) + 1 : (n))\n\n#define ASAN_READ_STRING(ctx, s, n)                             \\\n  ASAN_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n))\n\n// Behavior of functions like \"memcpy\" or \"strcpy\" is undefined\n// if memory intervals overlap. We report error in this case.\n// Macro is used to avoid creation of new frames.\nstatic inline bool RangesOverlap(const char *offset1, uptr length1,\n                                 const char *offset2, uptr length2) {\n  return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1));\n}\n#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \\\n  const char *offset1 = (const char*)_offset1; \\\n  const char *offset2 = (const char*)_offset2; \\\n  if (RangesOverlap(offset1, length1, offset2, length2)) { \\\n    GET_STACK_TRACE_FATAL_HERE; \\\n    ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \\\n                                            offset2, length2, &stack); \\\n  } \\\n} while (0)\n\nstatic inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {\n#if ASAN_INTERCEPT_STRNLEN\n  if (REAL(strnlen)) {\n    return REAL(strnlen)(s, maxlen);\n  }\n#endif\n  return internal_strnlen(s, maxlen);\n}\n\nvoid SetThreadName(const char *name) {\n  AsanThread *t = GetCurrentThread();\n  if (t)\n    asanThreadRegistry().SetThreadName(t->tid(), name);\n}\n\nint OnExit() {\n  // FIXME: ask frontend whether we need to return failure.\n  return 0;\n}\n\n} // namespace __asan\n\n// ---------------------- Wrappers ---------------- {{{1\nusing namespace __asan;  // NOLINT\n\nDECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr)\nDECLARE_REAL_AND_INTERCEPTOR(void, free, void *)\n\n#define ASAN_INTERCEPTOR_ENTER(ctx, func)                                      \\\n  AsanInterceptorContext _ctx = {#func};                                       \\\n  ctx = (void *)&_ctx;                                                         \\\n  (void) ctx;                                                                  \\\n\n#define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name)\n#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \\\n  ASAN_WRITE_RANGE(ctx, ptr, size)\n#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \\\n  ASAN_READ_RANGE(ctx, ptr, size)\n#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)                               \\\n  ASAN_INTERCEPTOR_ENTER(ctx, func);                                           \\\n  do {                                                                         \\\n    if (asan_init_is_running)                                                  \\\n      return REAL(func)(__VA_ARGS__);                                          \\\n    if (SANITIZER_MAC && UNLIKELY(!asan_inited))                               \\\n      return REAL(func)(__VA_ARGS__);                                          \\\n    ENSURE_ASAN_INITED();                                                      \\\n  } while (false)\n#define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \\\n  do {                                            \\\n  } while (false)\n#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \\\n  do {                                         \\\n  } while (false)\n#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \\\n  do {                                         \\\n  } while (false)\n#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \\\n  do {                                                      \\\n  } while (false)\n#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name)\n// Should be asanThreadRegistry().SetThreadNameByUserId(thread, name)\n// But asan does not remember UserId's for threads (pthread_t);\n// and remembers all ever existed threads, so the linear search by UserId\n// can be slow.\n#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \\\n  do {                                                         \\\n  } while (false)\n#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)\n// Strict init-order checking is dlopen-hostile:\n// https://github.com/google/sanitizers/issues/178\n#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag)                           \\\n  if (flags()->strict_init_order) {                                            \\\n    StopInitOrderChecking();                                                   \\\n  }\n#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()\n#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \\\n  CoverageUpdateMapping()\n#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() CoverageUpdateMapping()\n#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!asan_inited)\n#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end)                           \\\n  if (AsanThread *t = GetCurrentThread()) {                                    \\\n    *begin = t->tls_begin();                                                   \\\n    *end = t->tls_end();                                                       \\\n  } else {                                                                     \\\n    *begin = *end = 0;                                                         \\\n  }\n#include \"sanitizer_common/sanitizer_common_interceptors.inc\"\n\n// Syscall interceptors don't have contexts, we don't support suppressions\n// for them.\n#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(nullptr, p, s)\n#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(nullptr, p, s)\n#define COMMON_SYSCALL_POST_READ_RANGE(p, s) \\\n  do {                                       \\\n    (void)(p);                               \\\n    (void)(s);                               \\\n  } while (false)\n#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \\\n  do {                                        \\\n    (void)(p);                                \\\n    (void)(s);                                \\\n  } while (false)\n#include \"sanitizer_common/sanitizer_common_syscalls.inc\"\n\nstruct ThreadStartParam {\n  atomic_uintptr_t t;\n  atomic_uintptr_t is_registered;\n};\n\nstatic thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {\n  ThreadStartParam *param = reinterpret_cast<ThreadStartParam *>(arg);\n  AsanThread *t = nullptr;\n  while ((t = reinterpret_cast<AsanThread *>(\n              atomic_load(&param->t, memory_order_acquire))) == nullptr)\n    internal_sched_yield();\n  SetCurrentThread(t);\n  return t->ThreadStart(GetTid(), &param->is_registered);\n}\n\n#if ASAN_INTERCEPT_PTHREAD_CREATE\nINTERCEPTOR(int, pthread_create, void *thread,\n    void *attr, void *(*start_routine)(void*), void *arg) {\n  EnsureMainThreadIDIsCorrect();\n  // Strict init-order checking is thread-hostile.\n  if (flags()->strict_init_order)\n    StopInitOrderChecking();\n  GET_STACK_TRACE_THREAD;\n  int detached = 0;\n  if (attr)\n    REAL(pthread_attr_getdetachstate)(attr, &detached);\n  ThreadStartParam param;\n  atomic_store(&param.t, 0, memory_order_relaxed);\n  atomic_store(&param.is_registered, 0, memory_order_relaxed);\n  int result = REAL(pthread_create)(thread, attr, asan_thread_start, &param);\n  if (result == 0) {\n    u32 current_tid = GetCurrentTidOrInvalid();\n    AsanThread *t =\n        AsanThread::Create(start_routine, arg, current_tid, &stack, detached);\n    atomic_store(&param.t, reinterpret_cast<uptr>(t), memory_order_release);\n    // Wait until the AsanThread object is initialized and the ThreadRegistry\n    // entry is in \"started\" state. One reason for this is that after this\n    // interceptor exits, the child thread's stack may be the only thing holding\n    // the |arg| pointer. This may cause LSan to report a leak if leak checking\n    // happens at a point when the interceptor has already exited, but the stack\n    // range for the child thread is not yet known.\n    while (atomic_load(&param.is_registered, memory_order_acquire) == 0)\n      internal_sched_yield();\n  }\n  return result;\n}\n\nINTERCEPTOR(int, pthread_join, void *t, void **arg) {\n  return real_pthread_join(t, arg);\n}\n\nDEFINE_REAL_PTHREAD_FUNCTIONS\n#endif  // ASAN_INTERCEPT_PTHREAD_CREATE\n\n#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION\n\n#if SANITIZER_ANDROID\nINTERCEPTOR(void*, bsd_signal, int signum, void *handler) {\n  if (!IsDeadlySignal(signum) || common_flags()->allow_user_segv_handler) {\n    return REAL(bsd_signal)(signum, handler);\n  }\n  return 0;\n}\n#endif\n\nINTERCEPTOR(void*, signal, int signum, void *handler) {\n  if (!IsDeadlySignal(signum) || common_flags()->allow_user_segv_handler) {\n    return REAL(signal)(signum, handler);\n  }\n  return nullptr;\n}\n\nINTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,\n                            struct sigaction *oldact) {\n  if (!IsDeadlySignal(signum) || common_flags()->allow_user_segv_handler) {\n    return REAL(sigaction)(signum, act, oldact);\n  }\n  return 0;\n}\n\nnamespace __sanitizer {\nint real_sigaction(int signum, const void *act, void *oldact) {\n  return REAL(sigaction)(signum, (const struct sigaction *)act,\n                         (struct sigaction *)oldact);\n}\n} // namespace __sanitizer\n\n#elif SANITIZER_POSIX\n// We need to have defined REAL(sigaction) on posix systems.\nDEFINE_REAL(int, sigaction, int signum, const struct sigaction *act,\n    struct sigaction *oldact)\n#endif  // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION\n\n#if ASAN_INTERCEPT_SWAPCONTEXT\nstatic void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) {\n  // Align to page size.\n  uptr PageSize = GetPageSizeCached();\n  uptr bottom = stack & ~(PageSize - 1);\n  ssize += stack - bottom;\n  ssize = RoundUpTo(ssize, PageSize);\n  static const uptr kMaxSaneContextStackSize = 1 << 22;  // 4 Mb\n  if (AddrIsInMem(bottom) && ssize && ssize <= kMaxSaneContextStackSize) {\n    PoisonShadow(bottom, ssize, 0);\n  }\n}\n\nINTERCEPTOR(int, swapcontext, struct ucontext_t *oucp,\n            struct ucontext_t *ucp) {\n  static bool reported_warning = false;\n  if (!reported_warning) {\n    Report(\"WARNING: ASan doesn't fully support makecontext/swapcontext \"\n           \"functions and may produce false positives in some cases!\\n\");\n    reported_warning = true;\n  }\n  // Clear shadow memory for new context (it may share stack\n  // with current context).\n  uptr stack, ssize;\n  ReadContextStack(ucp, &stack, &ssize);\n  ClearShadowMemoryForContextStack(stack, ssize);\n  int res = REAL(swapcontext)(oucp, ucp);\n  // swapcontext technically does not return, but program may swap context to\n  // \"oucp\" later, that would look as if swapcontext() returned 0.\n  // We need to clear shadow for ucp once again, as it may be in arbitrary\n  // state.\n  ClearShadowMemoryForContextStack(stack, ssize);\n  return res;\n}\n#endif  // ASAN_INTERCEPT_SWAPCONTEXT\n\nINTERCEPTOR(void, longjmp, void *env, int val) {\n  __asan_handle_no_return();\n  REAL(longjmp)(env, val);\n}\n\n#if ASAN_INTERCEPT__LONGJMP\nINTERCEPTOR(void, _longjmp, void *env, int val) {\n  __asan_handle_no_return();\n  REAL(_longjmp)(env, val);\n}\n#endif\n\n#if ASAN_INTERCEPT_SIGLONGJMP\nINTERCEPTOR(void, siglongjmp, void *env, int val) {\n  __asan_handle_no_return();\n  REAL(siglongjmp)(env, val);\n}\n#endif\n\n#if ASAN_INTERCEPT___CXA_THROW\nINTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) {\n  CHECK(REAL(__cxa_throw));\n  __asan_handle_no_return();\n  REAL(__cxa_throw)(a, b, c);\n}\n#endif\n\n// memcpy is called during __asan_init() from the internals of printf(...).\n// We do not treat memcpy with to==from as a bug.\n// See http://llvm.org/bugs/show_bug.cgi?id=11763.\n#define ASAN_MEMCPY_IMPL(ctx, to, from, size) do {                             \\\n    if (UNLIKELY(!asan_inited)) return internal_memcpy(to, from, size);        \\\n    if (asan_init_is_running) {                                                \\\n      return REAL(memcpy)(to, from, size);                                     \\\n    }                                                                          \\\n    ENSURE_ASAN_INITED();                                                      \\\n    if (flags()->replace_intrin) {                                             \\\n      if (to != from) {                                                        \\\n        CHECK_RANGES_OVERLAP(\"memcpy\", to, size, from, size);                  \\\n      }                                                                        \\\n      ASAN_READ_RANGE(ctx, from, size);                                        \\\n      ASAN_WRITE_RANGE(ctx, to, size);                                         \\\n    }                                                                          \\\n    return REAL(memcpy)(to, from, size);                                       \\\n  } while (0)\n\n\nvoid *__asan_memcpy(void *to, const void *from, uptr size) {\n  ASAN_MEMCPY_IMPL(nullptr, to, from, size);\n}\n\n// memset is called inside Printf.\n#define ASAN_MEMSET_IMPL(ctx, block, c, size) do {                             \\\n    if (UNLIKELY(!asan_inited)) return internal_memset(block, c, size);        \\\n    if (asan_init_is_running) {                                                \\\n      return REAL(memset)(block, c, size);                                     \\\n    }                                                                          \\\n    ENSURE_ASAN_INITED();                                                      \\\n    if (flags()->replace_intrin) {                                             \\\n      ASAN_WRITE_RANGE(ctx, block, size);                                      \\\n    }                                                                          \\\n    return REAL(memset)(block, c, size);                                       \\\n  } while (0)\n\nvoid *__asan_memset(void *block, int c, uptr size) {\n  ASAN_MEMSET_IMPL(nullptr, block, c, size);\n}\n\n#define ASAN_MEMMOVE_IMPL(ctx, to, from, size) do {                            \\\n    if (UNLIKELY(!asan_inited))                                                \\\n      return internal_memmove(to, from, size);                                 \\\n    ENSURE_ASAN_INITED();                                                      \\\n    if (flags()->replace_intrin) {                                             \\\n      ASAN_READ_RANGE(ctx, from, size);                                        \\\n      ASAN_WRITE_RANGE(ctx, to, size);                                         \\\n    }                                                                          \\\n    return internal_memmove(to, from, size);                                   \\\n  } while (0)\n\nvoid *__asan_memmove(void *to, const void *from, uptr size) {\n  ASAN_MEMMOVE_IMPL(nullptr, to, from, size);\n}\n\nINTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) {\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, memmove);\n  ASAN_MEMMOVE_IMPL(ctx, to, from, size);\n}\n\nINTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) {\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, memcpy);\n#if !SANITIZER_MAC\n  ASAN_MEMCPY_IMPL(ctx, to, from, size);\n#else\n  // At least on 10.7 and 10.8 both memcpy() and memmove() are being replaced\n  // with WRAP(memcpy). As a result, false positives are reported for memmove()\n  // calls. If we just disable error reporting with\n  // ASAN_OPTIONS=replace_intrin=0, memmove() is still replaced with\n  // internal_memcpy(), which may lead to crashes, see\n  // http://llvm.org/bugs/show_bug.cgi?id=16362.\n  ASAN_MEMMOVE_IMPL(ctx, to, from, size);\n#endif  // !SANITIZER_MAC\n}\n\nINTERCEPTOR(void*, memset, void *block, int c, uptr size) {\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, memset);\n  ASAN_MEMSET_IMPL(ctx, block, c, size);\n}\n\nINTERCEPTOR(char*, strchr, const char *str, int c) {\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, strchr);\n  if (UNLIKELY(!asan_inited)) return internal_strchr(str, c);\n  // strchr is called inside create_purgeable_zone() when MallocGuardEdges=1 is\n  // used.\n  if (asan_init_is_running) {\n    return REAL(strchr)(str, c);\n  }\n  ENSURE_ASAN_INITED();\n  char *result = REAL(strchr)(str, c);\n  if (flags()->replace_str) {\n    uptr len = REAL(strlen)(str);\n    uptr bytes_read = (result ? result - str : len) + 1;\n    ASAN_READ_STRING_OF_LEN(ctx, str, len, bytes_read);\n  }\n  return result;\n}\n\n#if ASAN_INTERCEPT_INDEX\n# if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX\nINTERCEPTOR(char*, index, const char *string, int c)\n  ALIAS(WRAPPER_NAME(strchr));\n# else\n#  if SANITIZER_MAC\nDECLARE_REAL(char*, index, const char *string, int c)\nOVERRIDE_FUNCTION(index, strchr);\n#  else\nDEFINE_REAL(char*, index, const char *string, int c)\n#  endif\n# endif\n#endif  // ASAN_INTERCEPT_INDEX\n\n// For both strcat() and strncat() we need to check the validity of |to|\n// argument irrespective of the |from| length.\nINTERCEPTOR(char*, strcat, char *to, const char *from) {  // NOLINT\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, strcat);  // NOLINT\n  ENSURE_ASAN_INITED();\n  if (flags()->replace_str) {\n    uptr from_length = REAL(strlen)(from);\n    ASAN_READ_RANGE(ctx, from, from_length + 1);\n    uptr to_length = REAL(strlen)(to);\n    ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);\n    ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);\n    // If the copying actually happens, the |from| string should not overlap\n    // with the resulting string starting at |to|, which has a length of\n    // to_length + from_length + 1.\n    if (from_length > 0) {\n      CHECK_RANGES_OVERLAP(\"strcat\", to, from_length + to_length + 1,\n                           from, from_length + 1);\n    }\n  }\n  return REAL(strcat)(to, from);  // NOLINT\n}\n\nINTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) {\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, strncat);\n  ENSURE_ASAN_INITED();\n  if (flags()->replace_str) {\n    uptr from_length = MaybeRealStrnlen(from, size);\n    uptr copy_length = Min(size, from_length + 1);\n    ASAN_READ_RANGE(ctx, from, copy_length);\n    uptr to_length = REAL(strlen)(to);\n    ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);\n    ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);\n    if (from_length > 0) {\n      CHECK_RANGES_OVERLAP(\"strncat\", to, to_length + copy_length + 1,\n                           from, copy_length);\n    }\n  }\n  return REAL(strncat)(to, from, size);\n}\n\nINTERCEPTOR(char*, strcpy, char *to, const char *from) {  // NOLINT\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, strcpy);  // NOLINT\n#if SANITIZER_MAC\n  if (UNLIKELY(!asan_inited)) return REAL(strcpy)(to, from);  // NOLINT\n#endif\n  // strcpy is called from malloc_default_purgeable_zone()\n  // in __asan::ReplaceSystemAlloc() on Mac.\n  if (asan_init_is_running) {\n    return REAL(strcpy)(to, from);  // NOLINT\n  }\n  ENSURE_ASAN_INITED();\n  if (flags()->replace_str) {\n    uptr from_size = REAL(strlen)(from) + 1;\n    CHECK_RANGES_OVERLAP(\"strcpy\", to, from_size, from, from_size);\n    ASAN_READ_RANGE(ctx, from, from_size);\n    ASAN_WRITE_RANGE(ctx, to, from_size);\n  }\n  return REAL(strcpy)(to, from);  // NOLINT\n}\n\n#if ASAN_INTERCEPT_STRDUP\nINTERCEPTOR(char*, strdup, const char *s) {\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, strdup);\n  if (UNLIKELY(!asan_inited)) return internal_strdup(s);\n  ENSURE_ASAN_INITED();\n  uptr length = REAL(strlen)(s);\n  if (flags()->replace_str) {\n    ASAN_READ_RANGE(ctx, s, length + 1);\n  }\n  GET_STACK_TRACE_MALLOC;\n  void *new_mem = asan_malloc(length + 1, &stack);\n  REAL(memcpy)(new_mem, s, length + 1);\n  return reinterpret_cast<char*>(new_mem);\n}\n#endif\n\nINTERCEPTOR(SIZE_T, strlen, const char *s) {\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, strlen);\n  if (UNLIKELY(!asan_inited)) return internal_strlen(s);\n  // strlen is called from malloc_default_purgeable_zone()\n  // in __asan::ReplaceSystemAlloc() on Mac.\n  if (asan_init_is_running) {\n    return REAL(strlen)(s);\n  }\n  ENSURE_ASAN_INITED();\n  SIZE_T length = REAL(strlen)(s);\n  if (flags()->replace_str) {\n    ASAN_READ_RANGE(ctx, s, length + 1);\n  }\n  return length;\n}\n\nINTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, wcslen);\n  SIZE_T length = REAL(wcslen)(s);\n  if (!asan_init_is_running) {\n    ENSURE_ASAN_INITED();\n    ASAN_READ_RANGE(ctx, s, (length + 1) * sizeof(wchar_t));\n  }\n  return length;\n}\n\nINTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) {\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, strncpy);\n  ENSURE_ASAN_INITED();\n  if (flags()->replace_str) {\n    uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1);\n    CHECK_RANGES_OVERLAP(\"strncpy\", to, from_size, from, from_size);\n    ASAN_READ_RANGE(ctx, from, from_size);\n    ASAN_WRITE_RANGE(ctx, to, size);\n  }\n  return REAL(strncpy)(to, from, size);\n}\n\n#if ASAN_INTERCEPT_STRNLEN\nINTERCEPTOR(uptr, strnlen, const char *s, uptr maxlen) {\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, strnlen);\n  ENSURE_ASAN_INITED();\n  uptr length = REAL(strnlen)(s, maxlen);\n  if (flags()->replace_str) {\n    ASAN_READ_RANGE(ctx, s, Min(length + 1, maxlen));\n  }\n  return length;\n}\n#endif  // ASAN_INTERCEPT_STRNLEN\n\nINTERCEPTOR(long, strtol, const char *nptr,  // NOLINT\n            char **endptr, int base) {\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, strtol);\n  ENSURE_ASAN_INITED();\n  if (!flags()->replace_str) {\n    return REAL(strtol)(nptr, endptr, base);\n  }\n  char *real_endptr;\n  long result = REAL(strtol)(nptr, &real_endptr, base);  // NOLINT\n  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);\n  return result;\n}\n\nINTERCEPTOR(int, atoi, const char *nptr) {\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, atoi);\n#if SANITIZER_MAC\n  if (UNLIKELY(!asan_inited)) return REAL(atoi)(nptr);\n#endif\n  ENSURE_ASAN_INITED();\n  if (!flags()->replace_str) {\n    return REAL(atoi)(nptr);\n  }\n  char *real_endptr;\n  // \"man atoi\" tells that behavior of atoi(nptr) is the same as\n  // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the\n  // parsed integer can't be stored in *long* type (even if it's\n  // different from int). So, we just imitate this behavior.\n  int result = REAL(strtol)(nptr, &real_endptr, 10);\n  FixRealStrtolEndptr(nptr, &real_endptr);\n  ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);\n  return result;\n}\n\nINTERCEPTOR(long, atol, const char *nptr) {  // NOLINT\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, atol);\n#if SANITIZER_MAC\n  if (UNLIKELY(!asan_inited)) return REAL(atol)(nptr);\n#endif\n  ENSURE_ASAN_INITED();\n  if (!flags()->replace_str) {\n    return REAL(atol)(nptr);\n  }\n  char *real_endptr;\n  long result = REAL(strtol)(nptr, &real_endptr, 10);  // NOLINT\n  FixRealStrtolEndptr(nptr, &real_endptr);\n  ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);\n  return result;\n}\n\n#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL\nINTERCEPTOR(long long, strtoll, const char *nptr,  // NOLINT\n            char **endptr, int base) {\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, strtoll);\n  ENSURE_ASAN_INITED();\n  if (!flags()->replace_str) {\n    return REAL(strtoll)(nptr, endptr, base);\n  }\n  char *real_endptr;\n  long long result = REAL(strtoll)(nptr, &real_endptr, base);  // NOLINT\n  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);\n  return result;\n}\n\nINTERCEPTOR(long long, atoll, const char *nptr) {  // NOLINT\n  void *ctx;\n  ASAN_INTERCEPTOR_ENTER(ctx, atoll);\n  ENSURE_ASAN_INITED();\n  if (!flags()->replace_str) {\n    return REAL(atoll)(nptr);\n  }\n  char *real_endptr;\n  long long result = REAL(strtoll)(nptr, &real_endptr, 10);  // NOLINT\n  FixRealStrtolEndptr(nptr, &real_endptr);\n  ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);\n  return result;\n}\n#endif  // ASAN_INTERCEPT_ATOLL_AND_STRTOLL\n\nstatic void AtCxaAtexit(void *unused) {\n  (void)unused;\n  StopInitOrderChecking();\n}\n\n#if ASAN_INTERCEPT___CXA_ATEXIT\nINTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,\n            void *dso_handle) {\n#if SANITIZER_MAC\n  if (UNLIKELY(!asan_inited)) return REAL(__cxa_atexit)(func, arg, dso_handle);\n#endif\n  ENSURE_ASAN_INITED();\n  int res = REAL(__cxa_atexit)(func, arg, dso_handle);\n  REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr);\n  return res;\n}\n#endif  // ASAN_INTERCEPT___CXA_ATEXIT\n\n#if ASAN_INTERCEPT_FORK\nINTERCEPTOR(int, fork, void) {\n  ENSURE_ASAN_INITED();\n  if (common_flags()->coverage) CovBeforeFork();\n  int pid = REAL(fork)();\n  if (common_flags()->coverage) CovAfterFork(pid);\n  return pid;\n}\n#endif  // ASAN_INTERCEPT_FORK\n\n// ---------------------- InitializeAsanInterceptors ---------------- {{{1\nnamespace __asan {\nvoid InitializeAsanInterceptors() {\n  static bool was_called_once;\n  CHECK(was_called_once == false);\n  was_called_once = true;\n  InitializeCommonInterceptors();\n\n  // Intercept mem* functions.\n  ASAN_INTERCEPT_FUNC(memmove);\n  ASAN_INTERCEPT_FUNC(memset);\n  if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) {\n    ASAN_INTERCEPT_FUNC(memcpy);\n  }\n\n  // Intercept str* functions.\n  ASAN_INTERCEPT_FUNC(strcat);  // NOLINT\n  ASAN_INTERCEPT_FUNC(strchr);\n  ASAN_INTERCEPT_FUNC(strcpy);  // NOLINT\n  ASAN_INTERCEPT_FUNC(strlen);\n  ASAN_INTERCEPT_FUNC(wcslen);\n  ASAN_INTERCEPT_FUNC(strncat);\n  ASAN_INTERCEPT_FUNC(strncpy);\n#if ASAN_INTERCEPT_STRDUP\n  ASAN_INTERCEPT_FUNC(strdup);\n#endif\n#if ASAN_INTERCEPT_STRNLEN\n  ASAN_INTERCEPT_FUNC(strnlen);\n#endif\n#if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX\n  ASAN_INTERCEPT_FUNC(index);\n#endif\n\n  ASAN_INTERCEPT_FUNC(atoi);\n  ASAN_INTERCEPT_FUNC(atol);\n  ASAN_INTERCEPT_FUNC(strtol);\n#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL\n  ASAN_INTERCEPT_FUNC(atoll);\n  ASAN_INTERCEPT_FUNC(strtoll);\n#endif\n\n  // Intecept signal- and jump-related functions.\n  ASAN_INTERCEPT_FUNC(longjmp);\n#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION\n  ASAN_INTERCEPT_FUNC(sigaction);\n#if SANITIZER_ANDROID\n  ASAN_INTERCEPT_FUNC(bsd_signal);\n#endif\n  ASAN_INTERCEPT_FUNC(signal);\n#endif\n#if ASAN_INTERCEPT_SWAPCONTEXT\n  ASAN_INTERCEPT_FUNC(swapcontext);\n#endif\n#if ASAN_INTERCEPT__LONGJMP\n  ASAN_INTERCEPT_FUNC(_longjmp);\n#endif\n#if ASAN_INTERCEPT_SIGLONGJMP\n  ASAN_INTERCEPT_FUNC(siglongjmp);\n#endif\n\n  // Intercept exception handling functions.\n#if ASAN_INTERCEPT___CXA_THROW\n  ASAN_INTERCEPT_FUNC(__cxa_throw);\n#endif\n\n  // Intercept threading-related functions\n#if ASAN_INTERCEPT_PTHREAD_CREATE\n#if defined(ASAN_PTHREAD_CREATE_VERSION)\n  ASAN_INTERCEPT_FUNC_VER(pthread_create, ASAN_PTHREAD_CREATE_VERSION);\n#else\n  ASAN_INTERCEPT_FUNC(pthread_create);\n#endif\n  ASAN_INTERCEPT_FUNC(pthread_join);\n#endif\n\n  // Intercept atexit function.\n#if ASAN_INTERCEPT___CXA_ATEXIT\n  ASAN_INTERCEPT_FUNC(__cxa_atexit);\n#endif\n\n#if ASAN_INTERCEPT_FORK\n  ASAN_INTERCEPT_FUNC(fork);\n#endif\n\n  InitializePlatformInterceptors();\n\n  VReport(1, \"AddressSanitizer: libc interceptors initialized\\n\");\n}\n\n} // namespace __asan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_interceptors.h",
    "content": "//===-- asan_interceptors.h -------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// ASan-private header for asan_interceptors.cc\n//===----------------------------------------------------------------------===//\n#ifndef ASAN_INTERCEPTORS_H\n#define ASAN_INTERCEPTORS_H\n\n#include \"asan_internal.h\"\n#include \"interception/interception.h\"\n#include \"sanitizer_common/sanitizer_platform_interceptors.h\"\n\n// Use macro to describe if specific function should be\n// intercepted on a given platform.\n#if !SANITIZER_WINDOWS\n# define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 1\n# define ASAN_INTERCEPT__LONGJMP 1\n# define ASAN_INTERCEPT_STRDUP 1\n# define ASAN_INTERCEPT_INDEX 1\n# define ASAN_INTERCEPT_PTHREAD_CREATE 1\n# define ASAN_INTERCEPT_FORK 1\n#else\n# define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 0\n# define ASAN_INTERCEPT__LONGJMP 0\n# define ASAN_INTERCEPT_STRDUP 0\n# define ASAN_INTERCEPT_INDEX 0\n# define ASAN_INTERCEPT_PTHREAD_CREATE 0\n# define ASAN_INTERCEPT_FORK 0\n#endif\n\n#if SANITIZER_FREEBSD || SANITIZER_LINUX\n# define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 1\n#else\n# define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 0\n#endif\n\n#if !SANITIZER_MAC\n# define ASAN_INTERCEPT_STRNLEN 1\n#else\n# define ASAN_INTERCEPT_STRNLEN 0\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n# define ASAN_INTERCEPT_SWAPCONTEXT 1\n#else\n# define ASAN_INTERCEPT_SWAPCONTEXT 0\n#endif\n\n#if !SANITIZER_WINDOWS\n# define ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 1\n#else\n# define ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 0\n#endif\n\n#if !SANITIZER_WINDOWS\n# define ASAN_INTERCEPT_SIGLONGJMP 1\n#else\n# define ASAN_INTERCEPT_SIGLONGJMP 0\n#endif\n\n// Android bug: https://code.google.com/p/android/issues/detail?id=61799\n#if ASAN_HAS_EXCEPTIONS && !SANITIZER_WINDOWS && \\\n    !(SANITIZER_ANDROID && defined(__i386))\n# define ASAN_INTERCEPT___CXA_THROW 1\n#else\n# define ASAN_INTERCEPT___CXA_THROW 0\n#endif\n\n#if !SANITIZER_WINDOWS\n# define ASAN_INTERCEPT___CXA_ATEXIT 1\n#else\n# define ASAN_INTERCEPT___CXA_ATEXIT 0\n#endif\n\nDECLARE_REAL(int, memcmp, const void *a1, const void *a2, uptr size)\nDECLARE_REAL(void*, memcpy, void *to, const void *from, uptr size)\nDECLARE_REAL(void*, memset, void *block, int c, uptr size)\nDECLARE_REAL(char*, strchr, const char *str, int c)\nDECLARE_REAL(SIZE_T, strlen, const char *s)\nDECLARE_REAL(char*, strncpy, char *to, const char *from, uptr size)\nDECLARE_REAL(uptr, strnlen, const char *s, uptr maxlen)\nDECLARE_REAL(char*, strstr, const char *s1, const char *s2)\nstruct sigaction;\nDECLARE_REAL(int, sigaction, int signum, const struct sigaction *act,\n                             struct sigaction *oldact)\n\n#if !SANITIZER_MAC\n#define ASAN_INTERCEPT_FUNC(name)                                        \\\n  do {                                                                   \\\n    if ((!INTERCEPT_FUNCTION(name) || !REAL(name)))                      \\\n      VReport(1, \"AddressSanitizer: failed to intercept '\" #name \"'\\n\"); \\\n  } while (0)\n#define ASAN_INTERCEPT_FUNC_VER(name, ver)                                     \\\n  do {                                                                         \\\n    if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name)))                   \\\n      VReport(                                                                 \\\n          1, \"AddressSanitizer: failed to intercept '\" #name \"@@\" #ver \"'\\n\"); \\\n  } while (0)\n#else\n// OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION.\n#define ASAN_INTERCEPT_FUNC(name)\n#endif  // SANITIZER_MAC\n\nnamespace __asan {\n\nvoid InitializeAsanInterceptors();\nvoid InitializePlatformInterceptors();\n\n#define ENSURE_ASAN_INITED() do { \\\n  CHECK(!asan_init_is_running); \\\n  if (UNLIKELY(!asan_inited)) { \\\n    AsanInitFromRtl(); \\\n  } \\\n} while (0)\n\n}  // namespace __asan\n\n#endif  // ASAN_INTERCEPTORS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_interface_internal.h",
    "content": "//===-- asan_interface_internal.h -------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// This header declares the AddressSanitizer runtime interface functions.\n// The runtime library has to define these functions so the instrumented program\n// could call them.\n//\n// See also include/sanitizer/asan_interface.h\n//===----------------------------------------------------------------------===//\n#ifndef ASAN_INTERFACE_INTERNAL_H\n#define ASAN_INTERFACE_INTERNAL_H\n\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n\n#include \"asan_init_version.h\"\n\nusing __sanitizer::uptr;\n\nextern \"C\" {\n  // This function should be called at the very beginning of the process,\n  // before any instrumented code is executed and before any call to malloc.\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_init();\n\n  // This function exists purely to get a linker/loader error when using\n  // incompatible versions of instrumentation and runtime library. Please note\n  // that __asan_version_mismatch_check is a macro that is replaced with\n  // __asan_version_mismatch_check_vXXX at compile-time.\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_version_mismatch_check();\n\n  // This structure is used to describe the source location of a place where\n  // global was defined.\n  struct __asan_global_source_location {\n    const char *filename;\n    int line_no;\n    int column_no;\n  };\n\n  // This structure describes an instrumented global variable.\n  struct __asan_global {\n    uptr beg;                // The address of the global.\n    uptr size;               // The original size of the global.\n    uptr size_with_redzone;  // The size with the redzone.\n    const char *name;        // Name as a C string.\n    const char *module_name; // Module name as a C string. This pointer is a\n                             // unique identifier of a module.\n    uptr has_dynamic_init;   // Non-zero if the global has dynamic initializer.\n    __asan_global_source_location *location;  // Source location of a global,\n                                              // or NULL if it is unknown.\n  };\n\n  // These two functions should be called by the instrumented code.\n  // 'globals' is an array of structures describing 'n' globals.\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_register_globals(__asan_global *globals, uptr n);\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_unregister_globals(__asan_global *globals, uptr n);\n\n  // These two functions should be called before and after dynamic initializers\n  // of a single module run, respectively.\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_before_dynamic_init(const char *module_name);\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_after_dynamic_init();\n\n  // These two functions are used by instrumented code in the\n  // use-after-scope mode. They mark memory for local variables as\n  // unaddressable when they leave scope and addressable before the\n  // function exits.\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_poison_stack_memory(uptr addr, uptr size);\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_unpoison_stack_memory(uptr addr, uptr size);\n\n  // Performs cleanup before a NoReturn function. Must be called before things\n  // like _exit and execl to avoid false positives on stack.\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_handle_no_return();\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_poison_memory_region(void const volatile *addr, uptr size);\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_unpoison_memory_region(void const volatile *addr, uptr size);\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n  int __asan_address_is_poisoned(void const volatile *addr);\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n  uptr __asan_region_is_poisoned(uptr beg, uptr size);\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_describe_address(uptr addr);\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n  int __asan_report_present();\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n  uptr __asan_get_report_pc();\n  SANITIZER_INTERFACE_ATTRIBUTE\n  uptr __asan_get_report_bp();\n  SANITIZER_INTERFACE_ATTRIBUTE\n  uptr __asan_get_report_sp();\n  SANITIZER_INTERFACE_ATTRIBUTE\n  uptr __asan_get_report_address();\n  SANITIZER_INTERFACE_ATTRIBUTE\n  int __asan_get_report_access_type();\n  SANITIZER_INTERFACE_ATTRIBUTE\n  uptr __asan_get_report_access_size();\n  SANITIZER_INTERFACE_ATTRIBUTE\n  const char * __asan_get_report_description();\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n  const char * __asan_locate_address(uptr addr, char *name, uptr name_size,\n                                     uptr *region_address, uptr *region_size);\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n  uptr __asan_get_alloc_stack(uptr addr, uptr *trace, uptr size,\n                              u32 *thread_id);\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n  uptr __asan_get_free_stack(uptr addr, uptr *trace, uptr size,\n                             u32 *thread_id);\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_get_shadow_mapping(uptr *shadow_scale, uptr *shadow_offset);\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_report_error(uptr pc, uptr bp, uptr sp,\n                           uptr addr, int is_write, uptr access_size, u32 exp);\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_set_death_callback(void (*callback)(void));\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_set_error_report_callback(void (*callback)(const char*));\n\n  SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\n  /* OPTIONAL */ void __asan_on_error();\n\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_print_accumulated_stats();\n\n  SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\n  /* OPTIONAL */ const char* __asan_default_options();\n\n  // Global flag, copy of ASAN_OPTIONS=detect_stack_use_after_return\n  SANITIZER_INTERFACE_ATTRIBUTE\n  extern int __asan_option_detect_stack_use_after_return;\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n  extern uptr *__asan_test_only_reported_buggy_pointer;\n\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load1(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load2(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load4(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load8(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load16(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store1(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store2(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store4(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store8(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store16(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_loadN(uptr p, uptr size);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_storeN(uptr p, uptr size);\n\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load1_noabort(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load2_noabort(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load4_noabort(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load8_noabort(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_load16_noabort(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store1_noabort(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store2_noabort(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store4_noabort(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store8_noabort(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_store16_noabort(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_loadN_noabort(uptr p, uptr size);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_storeN_noabort(uptr p, uptr size);\n\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load1(uptr p, u32 exp);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load2(uptr p, u32 exp);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load4(uptr p, u32 exp);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load8(uptr p, u32 exp);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load16(uptr p, u32 exp);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_store1(uptr p, u32 exp);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_store2(uptr p, u32 exp);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_store4(uptr p, u32 exp);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_store8(uptr p, u32 exp);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_store16(uptr p, u32 exp);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_loadN(uptr p, uptr size,\n                                                      u32 exp);\n  SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_storeN(uptr p, uptr size,\n                                                       u32 exp);\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n      void* __asan_memcpy(void *dst, const void *src, uptr size);\n  SANITIZER_INTERFACE_ATTRIBUTE\n      void* __asan_memset(void *s, int c, uptr n);\n  SANITIZER_INTERFACE_ATTRIBUTE\n      void* __asan_memmove(void* dest, const void* src, uptr n);\n\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_poison_cxx_array_cookie(uptr p);\n  SANITIZER_INTERFACE_ATTRIBUTE\n  uptr __asan_load_cxx_array_cookie(uptr *p);\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_poison_intra_object_redzone(uptr p, uptr size);\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_unpoison_intra_object_redzone(uptr p, uptr size);\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_alloca_poison(uptr addr, uptr size);\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __asan_allocas_unpoison(uptr top, uptr bottom);\n}  // extern \"C\"\n\n#endif  // ASAN_INTERFACE_INTERNAL_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_internal.h",
    "content": "//===-- asan_internal.h -----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// ASan-private header which defines various general utilities.\n//===----------------------------------------------------------------------===//\n#ifndef ASAN_INTERNAL_H\n#define ASAN_INTERNAL_H\n\n#include \"asan_flags.h\"\n#include \"asan_interface_internal.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n\n#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)\n# error \"The AddressSanitizer run-time should not be\"\n        \" instrumented by AddressSanitizer\"\n#endif\n\n// Build-time configuration options.\n\n// If set, asan will intercept C++ exception api call(s).\n#ifndef ASAN_HAS_EXCEPTIONS\n# define ASAN_HAS_EXCEPTIONS 1\n#endif\n\n// If set, values like allocator chunk size, as well as defaults for some flags\n// will be changed towards less memory overhead.\n#ifndef ASAN_LOW_MEMORY\n#if SANITIZER_WORDSIZE == 32\n#  define ASAN_LOW_MEMORY 1\n#else\n#  define ASAN_LOW_MEMORY 0\n# endif\n#endif\n\n#ifndef ASAN_DYNAMIC\n# ifdef PIC\n#  define ASAN_DYNAMIC 1\n# else\n#  define ASAN_DYNAMIC 0\n# endif\n#endif\n\n// All internal functions in asan reside inside the __asan namespace\n// to avoid namespace collisions with the user programs.\n// Separate namespace also makes it simpler to distinguish the asan run-time\n// functions from the instrumented user code in a profile.\nnamespace __asan {\n\nclass AsanThread;\nusing __sanitizer::StackTrace;\n\nvoid AsanInitFromRtl();\n\n// asan_rtl.cc\nvoid NORETURN ShowStatsAndAbort();\n\n// asan_malloc_linux.cc / asan_malloc_mac.cc\nvoid ReplaceSystemMalloc();\n\n// asan_linux.cc / asan_mac.cc / asan_win.cc\nvoid *AsanDoesNotSupportStaticLinkage();\nvoid AsanCheckDynamicRTPrereqs();\nvoid AsanCheckIncompatibleRT();\n\nvoid AsanOnDeadlySignal(int, void *siginfo, void *context);\n\nvoid ReadContextStack(void *context, uptr *stack, uptr *ssize);\nvoid StopInitOrderChecking();\n\n// Wrapper for TLS/TSD.\nvoid AsanTSDInit(void (*destructor)(void *tsd));\nvoid *AsanTSDGet();\nvoid AsanTSDSet(void *tsd);\nvoid PlatformTSDDtor(void *tsd);\n\nvoid AppendToErrorMessageBuffer(const char *buffer);\n\nvoid *AsanDlSymNext(const char *sym);\n\nvoid ReserveShadowMemoryRange(uptr beg, uptr end, const char *name);\n\n// Platform-specific options.\n#if SANITIZER_MAC\nbool PlatformHasDifferentMemcpyAndMemmove();\n# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE \\\n    (PlatformHasDifferentMemcpyAndMemmove())\n#else\n# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE true\n#endif  // SANITIZER_MAC\n\n// Add convenient macro for interface functions that may be represented as\n// weak hooks.\n#define ASAN_MALLOC_HOOK(ptr, size) \\\n  if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(ptr, size)\n#define ASAN_FREE_HOOK(ptr) \\\n  if (&__sanitizer_free_hook) __sanitizer_free_hook(ptr)\n#define ASAN_ON_ERROR() \\\n  if (&__asan_on_error) __asan_on_error()\n\nextern int asan_inited;\n// Used to avoid infinite recursion in __asan_init().\nextern bool asan_init_is_running;\nextern void (*death_callback)(void);\n\n// These magic values are written to shadow for better error reporting.\nconst int kAsanHeapLeftRedzoneMagic = 0xfa;\nconst int kAsanHeapRightRedzoneMagic = 0xfb;\nconst int kAsanHeapFreeMagic = 0xfd;\nconst int kAsanStackLeftRedzoneMagic = 0xf1;\nconst int kAsanStackMidRedzoneMagic = 0xf2;\nconst int kAsanStackRightRedzoneMagic = 0xf3;\nconst int kAsanStackPartialRedzoneMagic = 0xf4;\nconst int kAsanStackAfterReturnMagic = 0xf5;\nconst int kAsanInitializationOrderMagic = 0xf6;\nconst int kAsanUserPoisonedMemoryMagic = 0xf7;\nconst int kAsanContiguousContainerOOBMagic = 0xfc;\nconst int kAsanStackUseAfterScopeMagic = 0xf8;\nconst int kAsanGlobalRedzoneMagic = 0xf9;\nconst int kAsanInternalHeapMagic = 0xfe;\nconst int kAsanArrayCookieMagic = 0xac;\nconst int kAsanIntraObjectRedzone = 0xbb;\nconst int kAsanAllocaLeftMagic = 0xca;\nconst int kAsanAllocaRightMagic = 0xcb;\n\nstatic const uptr kCurrentStackFrameMagic = 0x41B58AB3;\nstatic const uptr kRetiredStackFrameMagic = 0x45E0360E;\n\n}  // namespace __asan\n\n#endif  // ASAN_INTERNAL_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_linux.cc",
    "content": "//===-- asan_linux.cc -----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Linux-specific details.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_FREEBSD || SANITIZER_LINUX\n\n#include \"asan_interceptors.h\"\n#include \"asan_internal.h\"\n#include \"asan_thread.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_freebsd.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_procmaps.h\"\n\n#include <sys/time.h>\n#include <sys/resource.h>\n#include <sys/mman.h>\n#include <sys/syscall.h>\n#include <sys/types.h>\n#include <dlfcn.h>\n#include <fcntl.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <unistd.h>\n#include <unwind.h>\n\n#if SANITIZER_FREEBSD\n#include <sys/link_elf.h>\n#endif\n\n#if SANITIZER_ANDROID || SANITIZER_FREEBSD\n#include <ucontext.h>\nextern \"C\" void* _DYNAMIC;\n#else\n#include <sys/ucontext.h>\n#include <link.h>\n#endif\n\n// x86-64 FreeBSD 9.2 and older define 'ucontext_t' incorrectly in\n// 32-bit mode.\n#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) && \\\n  __FreeBSD_version <= 902001  // v9.2\n#define ucontext_t xucontext_t\n#endif\n\ntypedef enum {\n  ASAN_RT_VERSION_UNDEFINED = 0,\n  ASAN_RT_VERSION_DYNAMIC,\n  ASAN_RT_VERSION_STATIC,\n} asan_rt_version_t;\n\n// FIXME: perhaps also store abi version here?\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE\nasan_rt_version_t  __asan_rt_version;\n}\n\nnamespace __asan {\n\nvoid InitializePlatformInterceptors() {}\n\nvoid *AsanDoesNotSupportStaticLinkage() {\n  // This will fail to link with -static.\n  return &_DYNAMIC;  // defined in link.h\n}\n\n#if SANITIZER_ANDROID\n// FIXME: should we do anything for Android?\nvoid AsanCheckDynamicRTPrereqs() {}\nvoid AsanCheckIncompatibleRT() {}\n#else\nstatic int FindFirstDSOCallback(struct dl_phdr_info *info, size_t size,\n                                void *data) {\n  // Continue until the first dynamic library is found\n  if (!info->dlpi_name || info->dlpi_name[0] == 0)\n    return 0;\n\n  // Ignore vDSO\n  if (internal_strncmp(info->dlpi_name, \"linux-\", sizeof(\"linux-\") - 1) == 0)\n    return 0;\n\n  *(const char **)data = info->dlpi_name;\n  return 1;\n}\n\nstatic bool IsDynamicRTName(const char *libname) {\n  return internal_strstr(libname, \"libclang_rt.asan\") ||\n    internal_strstr(libname, \"libasan.so\");\n}\n\nstatic void ReportIncompatibleRT() {\n  Report(\"Your application is linked against incompatible ASan runtimes.\\n\");\n  Die();\n}\n\nvoid AsanCheckDynamicRTPrereqs() {\n  if (!ASAN_DYNAMIC)\n    return;\n\n  // Ensure that dynamic RT is the first DSO in the list\n  const char *first_dso_name = nullptr;\n  dl_iterate_phdr(FindFirstDSOCallback, &first_dso_name);\n  if (first_dso_name && !IsDynamicRTName(first_dso_name)) {\n    Report(\"ASan runtime does not come first in initial library list; \"\n           \"you should either link runtime to your application or \"\n           \"manually preload it with LD_PRELOAD.\\n\");\n    Die();\n  }\n}\n\nvoid AsanCheckIncompatibleRT() {\n  if (ASAN_DYNAMIC) {\n    if (__asan_rt_version == ASAN_RT_VERSION_UNDEFINED) {\n      __asan_rt_version = ASAN_RT_VERSION_DYNAMIC;\n    } else if (__asan_rt_version != ASAN_RT_VERSION_DYNAMIC) {\n      ReportIncompatibleRT();\n    }\n  } else {\n    if (__asan_rt_version == ASAN_RT_VERSION_UNDEFINED) {\n      // Ensure that dynamic runtime is not present. We should detect it\n      // as early as possible, otherwise ASan interceptors could bind to\n      // the functions in dynamic ASan runtime instead of the functions in\n      // system libraries, causing crashes later in ASan initialization.\n      MemoryMappingLayout proc_maps(/*cache_enabled*/true);\n      char filename[128];\n      while (proc_maps.Next(nullptr, nullptr, nullptr, filename,\n                            sizeof(filename), nullptr)) {\n        if (IsDynamicRTName(filename)) {\n          Report(\"Your application is linked against \"\n                 \"incompatible ASan runtimes.\\n\");\n          Die();\n        }\n      }\n      __asan_rt_version = ASAN_RT_VERSION_STATIC;\n    } else if (__asan_rt_version != ASAN_RT_VERSION_STATIC) {\n      ReportIncompatibleRT();\n    }\n  }\n}\n#endif // SANITIZER_ANDROID\n\n#if !SANITIZER_ANDROID\nvoid ReadContextStack(void *context, uptr *stack, uptr *ssize) {\n  ucontext_t *ucp = (ucontext_t*)context;\n  *stack = (uptr)ucp->uc_stack.ss_sp;\n  *ssize = ucp->uc_stack.ss_size;\n}\n#else\nvoid ReadContextStack(void *context, uptr *stack, uptr *ssize) {\n  UNIMPLEMENTED();\n}\n#endif\n\nvoid *AsanDlSymNext(const char *sym) {\n  return dlsym(RTLD_NEXT, sym);\n}\n\n} // namespace __asan\n\n#endif // SANITIZER_FREEBSD || SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_lock.h",
    "content": ""
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_mac.cc",
    "content": "//===-- asan_mac.cc -------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Mac-specific details.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_MAC\n\n#include \"asan_interceptors.h\"\n#include \"asan_internal.h\"\n#include \"asan_mapping.h\"\n#include \"asan_stack.h\"\n#include \"asan_thread.h\"\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_mac.h\"\n\n#include <fcntl.h>\n#include <libkern/OSAtomic.h>\n#include <mach-o/dyld.h>\n#include <mach-o/loader.h>\n#include <pthread.h>\n#include <stdlib.h>  // for free()\n#include <sys/mman.h>\n#include <sys/resource.h>\n#include <sys/sysctl.h>\n#include <sys/ucontext.h>\n#include <unistd.h>\n\nnamespace __asan {\n\nvoid InitializePlatformInterceptors() {}\n\nbool PlatformHasDifferentMemcpyAndMemmove() {\n  // On OS X 10.7 memcpy() and memmove() are both resolved\n  // into memmove$VARIANT$sse42.\n  // See also https://github.com/google/sanitizers/issues/34.\n  // TODO(glider): need to check dynamically that memcpy() and memmove() are\n  // actually the same function.\n  return GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD;\n}\n\n// No-op. Mac does not support static linkage anyway.\nvoid *AsanDoesNotSupportStaticLinkage() {\n  return 0;\n}\n\n// No-op. Mac does not support static linkage anyway.\nvoid AsanCheckDynamicRTPrereqs() {}\n\n// No-op. Mac does not support static linkage anyway.\nvoid AsanCheckIncompatibleRT() {}\n\nvoid ReadContextStack(void *context, uptr *stack, uptr *ssize) {\n  UNIMPLEMENTED();\n}\n\n// Support for the following functions from libdispatch on Mac OS:\n//   dispatch_async_f()\n//   dispatch_async()\n//   dispatch_sync_f()\n//   dispatch_sync()\n//   dispatch_after_f()\n//   dispatch_after()\n//   dispatch_group_async_f()\n//   dispatch_group_async()\n// TODO(glider): libdispatch API contains other functions that we don't support\n// yet.\n//\n// dispatch_sync() and dispatch_sync_f() are synchronous, although chances are\n// they can cause jobs to run on a thread different from the current one.\n// TODO(glider): if so, we need a test for this (otherwise we should remove\n// them).\n//\n// The following functions use dispatch_barrier_async_f() (which isn't a library\n// function but is exported) and are thus supported:\n//   dispatch_source_set_cancel_handler_f()\n//   dispatch_source_set_cancel_handler()\n//   dispatch_source_set_event_handler_f()\n//   dispatch_source_set_event_handler()\n//\n// The reference manual for Grand Central Dispatch is available at\n//   http://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html\n// The implementation details are at\n//   http://libdispatch.macosforge.org/trac/browser/trunk/src/queue.c\n\ntypedef void* dispatch_group_t;\ntypedef void* dispatch_queue_t;\ntypedef void* dispatch_source_t;\ntypedef u64 dispatch_time_t;\ntypedef void (*dispatch_function_t)(void *block);\ntypedef void* (*worker_t)(void *block);\n\n// A wrapper for the ObjC blocks used to support libdispatch.\ntypedef struct {\n  void *block;\n  dispatch_function_t func;\n  u32 parent_tid;\n} asan_block_context_t;\n\nALWAYS_INLINE\nvoid asan_register_worker_thread(int parent_tid, StackTrace *stack) {\n  AsanThread *t = GetCurrentThread();\n  if (!t) {\n    t = AsanThread::Create(/* start_routine */ nullptr, /* arg */ nullptr,\n                           parent_tid, stack, /* detached */ true);\n    t->Init();\n    asanThreadRegistry().StartThread(t->tid(), 0, 0);\n    SetCurrentThread(t);\n  }\n}\n\n// For use by only those functions that allocated the context via\n// alloc_asan_context().\nextern \"C\"\nvoid asan_dispatch_call_block_and_release(void *block) {\n  GET_STACK_TRACE_THREAD;\n  asan_block_context_t *context = (asan_block_context_t*)block;\n  VReport(2,\n          \"asan_dispatch_call_block_and_release(): \"\n          \"context: %p, pthread_self: %p\\n\",\n          block, pthread_self());\n  asan_register_worker_thread(context->parent_tid, &stack);\n  // Call the original dispatcher for the block.\n  context->func(context->block);\n  asan_free(context, &stack, FROM_MALLOC);\n}\n\n}  // namespace __asan\n\nusing namespace __asan;  // NOLINT\n\n// Wrap |ctxt| and |func| into an asan_block_context_t.\n// The caller retains control of the allocated context.\nextern \"C\"\nasan_block_context_t *alloc_asan_context(void *ctxt, dispatch_function_t func,\n                                         BufferedStackTrace *stack) {\n  asan_block_context_t *asan_ctxt =\n      (asan_block_context_t*) asan_malloc(sizeof(asan_block_context_t), stack);\n  asan_ctxt->block = ctxt;\n  asan_ctxt->func = func;\n  asan_ctxt->parent_tid = GetCurrentTidOrInvalid();\n  return asan_ctxt;\n}\n\n// Define interceptor for dispatch_*_f function with the three most common\n// parameters: dispatch_queue_t, context, dispatch_function_t.\n#define INTERCEPT_DISPATCH_X_F_3(dispatch_x_f)                                \\\n  INTERCEPTOR(void, dispatch_x_f, dispatch_queue_t dq, void *ctxt,            \\\n                                  dispatch_function_t func) {                 \\\n    GET_STACK_TRACE_THREAD;                                                   \\\n    asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); \\\n    if (Verbosity() >= 2) {                                     \\\n      Report(#dispatch_x_f \"(): context: %p, pthread_self: %p\\n\",             \\\n             asan_ctxt, pthread_self());                                      \\\n      PRINT_CURRENT_STACK();                                                  \\\n    }                                                                         \\\n    return REAL(dispatch_x_f)(dq, (void*)asan_ctxt,                           \\\n                              asan_dispatch_call_block_and_release);          \\\n  }\n\nINTERCEPT_DISPATCH_X_F_3(dispatch_async_f)\nINTERCEPT_DISPATCH_X_F_3(dispatch_sync_f)\nINTERCEPT_DISPATCH_X_F_3(dispatch_barrier_async_f)\n\nINTERCEPTOR(void, dispatch_after_f, dispatch_time_t when,\n                                    dispatch_queue_t dq, void *ctxt,\n                                    dispatch_function_t func) {\n  GET_STACK_TRACE_THREAD;\n  asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack);\n  if (Verbosity() >= 2) {\n    Report(\"dispatch_after_f: %p\\n\", asan_ctxt);\n    PRINT_CURRENT_STACK();\n  }\n  return REAL(dispatch_after_f)(when, dq, (void*)asan_ctxt,\n                                asan_dispatch_call_block_and_release);\n}\n\nINTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group,\n                                          dispatch_queue_t dq, void *ctxt,\n                                          dispatch_function_t func) {\n  GET_STACK_TRACE_THREAD;\n  asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack);\n  if (Verbosity() >= 2) {\n    Report(\"dispatch_group_async_f(): context: %p, pthread_self: %p\\n\",\n           asan_ctxt, pthread_self());\n    PRINT_CURRENT_STACK();\n  }\n  REAL(dispatch_group_async_f)(group, dq, (void*)asan_ctxt,\n                               asan_dispatch_call_block_and_release);\n}\n\n#if !defined(MISSING_BLOCKS_SUPPORT)\nextern \"C\" {\nvoid dispatch_async(dispatch_queue_t dq, void(^work)(void));\nvoid dispatch_group_async(dispatch_group_t dg, dispatch_queue_t dq,\n                          void(^work)(void));\nvoid dispatch_after(dispatch_time_t when, dispatch_queue_t queue,\n                    void(^work)(void));\nvoid dispatch_source_set_cancel_handler(dispatch_source_t ds,\n                                        void(^work)(void));\nvoid dispatch_source_set_event_handler(dispatch_source_t ds, void(^work)(void));\n}\n\n#define GET_ASAN_BLOCK(work) \\\n  void (^asan_block)(void);  \\\n  int parent_tid = GetCurrentTidOrInvalid(); \\\n  asan_block = ^(void) { \\\n    GET_STACK_TRACE_THREAD; \\\n    asan_register_worker_thread(parent_tid, &stack); \\\n    work(); \\\n  }\n\nINTERCEPTOR(void, dispatch_async,\n            dispatch_queue_t dq, void(^work)(void)) {\n  ENABLE_FRAME_POINTER;\n  GET_ASAN_BLOCK(work);\n  REAL(dispatch_async)(dq, asan_block);\n}\n\nINTERCEPTOR(void, dispatch_group_async,\n            dispatch_group_t dg, dispatch_queue_t dq, void(^work)(void)) {\n  ENABLE_FRAME_POINTER;\n  GET_ASAN_BLOCK(work);\n  REAL(dispatch_group_async)(dg, dq, asan_block);\n}\n\nINTERCEPTOR(void, dispatch_after,\n            dispatch_time_t when, dispatch_queue_t queue, void(^work)(void)) {\n  ENABLE_FRAME_POINTER;\n  GET_ASAN_BLOCK(work);\n  REAL(dispatch_after)(when, queue, asan_block);\n}\n\nINTERCEPTOR(void, dispatch_source_set_cancel_handler,\n            dispatch_source_t ds, void(^work)(void)) {\n  if (!work) {\n    REAL(dispatch_source_set_cancel_handler)(ds, work);\n    return;\n  }\n  ENABLE_FRAME_POINTER;\n  GET_ASAN_BLOCK(work);\n  REAL(dispatch_source_set_cancel_handler)(ds, asan_block);\n}\n\nINTERCEPTOR(void, dispatch_source_set_event_handler,\n            dispatch_source_t ds, void(^work)(void)) {\n  ENABLE_FRAME_POINTER;\n  GET_ASAN_BLOCK(work);\n  REAL(dispatch_source_set_event_handler)(ds, asan_block);\n}\n#endif\n\n#endif  // SANITIZER_MAC\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_malloc_linux.cc",
    "content": "//===-- asan_malloc_linux.cc ----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Linux-specific malloc interception.\n// We simply define functions like malloc, free, realloc, etc.\n// They will replace the corresponding libc functions automagically.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_FREEBSD || SANITIZER_LINUX\n\n#include \"sanitizer_common/sanitizer_tls_get_addr.h\"\n#include \"asan_allocator.h\"\n#include \"asan_interceptors.h\"\n#include \"asan_internal.h\"\n#include \"asan_stack.h\"\n\n// ---------------------- Replacement functions ---------------- {{{1\nusing namespace __asan;  // NOLINT\n\nstatic const uptr kCallocPoolSize = 1024;\nstatic uptr calloc_memory_for_dlsym[kCallocPoolSize];\n\nstatic bool IsInCallocPool(const void *ptr) {\n  sptr off = (sptr)ptr - (sptr)calloc_memory_for_dlsym;\n  return 0 <= off && off < (sptr)kCallocPoolSize;\n}\n\nINTERCEPTOR(void, free, void *ptr) {\n  GET_STACK_TRACE_FREE;\n  if (UNLIKELY(IsInCallocPool(ptr)))\n    return;\n  asan_free(ptr, &stack, FROM_MALLOC);\n}\n\nINTERCEPTOR(void, cfree, void *ptr) {\n  GET_STACK_TRACE_FREE;\n  if (UNLIKELY(IsInCallocPool(ptr)))\n    return;\n  asan_free(ptr, &stack, FROM_MALLOC);\n}\n\nINTERCEPTOR(void*, malloc, uptr size) {\n  GET_STACK_TRACE_MALLOC;\n  return asan_malloc(size, &stack);\n}\n\nINTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {\n  if (UNLIKELY(!asan_inited)) {\n    // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.\n    static uptr allocated;\n    uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;\n    void *mem = (void*)&calloc_memory_for_dlsym[allocated];\n    allocated += size_in_words;\n    CHECK(allocated < kCallocPoolSize);\n    return mem;\n  }\n  GET_STACK_TRACE_MALLOC;\n  return asan_calloc(nmemb, size, &stack);\n}\n\nINTERCEPTOR(void*, realloc, void *ptr, uptr size) {\n  GET_STACK_TRACE_MALLOC;\n  if (UNLIKELY(IsInCallocPool(ptr))) {\n    uptr offset = (uptr)ptr - (uptr)calloc_memory_for_dlsym;\n    uptr copy_size = Min(size, kCallocPoolSize - offset);\n    void *new_ptr = asan_malloc(size, &stack);\n    internal_memcpy(new_ptr, ptr, copy_size);\n    return new_ptr;\n  }\n  return asan_realloc(ptr, size, &stack);\n}\n\nINTERCEPTOR(void*, memalign, uptr boundary, uptr size) {\n  GET_STACK_TRACE_MALLOC;\n  return asan_memalign(boundary, size, &stack, FROM_MALLOC);\n}\n\nINTERCEPTOR(void*, aligned_alloc, uptr boundary, uptr size) {\n  GET_STACK_TRACE_MALLOC;\n  return asan_memalign(boundary, size, &stack, FROM_MALLOC);\n}\n\nINTERCEPTOR(void*, __libc_memalign, uptr boundary, uptr size) {\n  GET_STACK_TRACE_MALLOC;\n  void *res = asan_memalign(boundary, size, &stack, FROM_MALLOC);\n  DTLS_on_libc_memalign(res, size * boundary);\n  return res;\n}\n\nINTERCEPTOR(uptr, malloc_usable_size, void *ptr) {\n  GET_CURRENT_PC_BP_SP;\n  (void)sp;\n  return asan_malloc_usable_size(ptr, pc, bp);\n}\n\n// We avoid including malloc.h for portability reasons.\n// man mallinfo says the fields are \"long\", but the implementation uses int.\n// It doesn't matter much -- we just need to make sure that the libc's mallinfo\n// is not called.\nstruct fake_mallinfo {\n  int x[10];\n};\n\nINTERCEPTOR(struct fake_mallinfo, mallinfo, void) {\n  struct fake_mallinfo res;\n  REAL(memset)(&res, 0, sizeof(res));\n  return res;\n}\n\nINTERCEPTOR(int, mallopt, int cmd, int value) {\n  return -1;\n}\n\nINTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {\n  GET_STACK_TRACE_MALLOC;\n  // Printf(\"posix_memalign: %zx %zu\\n\", alignment, size);\n  return asan_posix_memalign(memptr, alignment, size, &stack);\n}\n\nINTERCEPTOR(void*, valloc, uptr size) {\n  GET_STACK_TRACE_MALLOC;\n  return asan_valloc(size, &stack);\n}\n\nINTERCEPTOR(void*, pvalloc, uptr size) {\n  GET_STACK_TRACE_MALLOC;\n  return asan_pvalloc(size, &stack);\n}\n\nINTERCEPTOR(void, malloc_stats, void) {\n  __asan_print_accumulated_stats();\n}\n\n#if SANITIZER_ANDROID\n// Format of __libc_malloc_dispatch has changed in Android L.\n// While we are moving towards a solution that does not depend on bionic\n// internals, here is something to support both K* and L releases.\nstruct MallocDebugK {\n  void *(*malloc)(uptr bytes);\n  void (*free)(void *mem);\n  void *(*calloc)(uptr n_elements, uptr elem_size);\n  void *(*realloc)(void *oldMem, uptr bytes);\n  void *(*memalign)(uptr alignment, uptr bytes);\n  uptr (*malloc_usable_size)(void *mem);\n};\n\nstruct MallocDebugL {\n  void *(*calloc)(uptr n_elements, uptr elem_size);\n  void (*free)(void *mem);\n  fake_mallinfo (*mallinfo)(void);\n  void *(*malloc)(uptr bytes);\n  uptr (*malloc_usable_size)(void *mem);\n  void *(*memalign)(uptr alignment, uptr bytes);\n  int (*posix_memalign)(void **memptr, uptr alignment, uptr size);\n  void* (*pvalloc)(uptr size);\n  void *(*realloc)(void *oldMem, uptr bytes);\n  void* (*valloc)(uptr size);\n};\n\nALIGNED(32) const MallocDebugK asan_malloc_dispatch_k = {\n    WRAP(malloc),  WRAP(free),     WRAP(calloc),\n    WRAP(realloc), WRAP(memalign), WRAP(malloc_usable_size)};\n\nALIGNED(32) const MallocDebugL asan_malloc_dispatch_l = {\n    WRAP(calloc),         WRAP(free),               WRAP(mallinfo),\n    WRAP(malloc),         WRAP(malloc_usable_size), WRAP(memalign),\n    WRAP(posix_memalign), WRAP(pvalloc),            WRAP(realloc),\n    WRAP(valloc)};\n\nnamespace __asan {\nvoid ReplaceSystemMalloc() {\n  void **__libc_malloc_dispatch_p =\n      (void **)AsanDlSymNext(\"__libc_malloc_dispatch\");\n  if (__libc_malloc_dispatch_p) {\n    // Decide on K vs L dispatch format by the presence of\n    // __libc_malloc_default_dispatch export in libc.\n    void *default_dispatch_p = AsanDlSymNext(\"__libc_malloc_default_dispatch\");\n    if (default_dispatch_p)\n      *__libc_malloc_dispatch_p = (void *)&asan_malloc_dispatch_k;\n    else\n      *__libc_malloc_dispatch_p = (void *)&asan_malloc_dispatch_l;\n  }\n}\n}  // namespace __asan\n\n#else  // SANITIZER_ANDROID\n\nnamespace __asan {\nvoid ReplaceSystemMalloc() {\n}\n}  // namespace __asan\n#endif  // SANITIZER_ANDROID\n\n#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_malloc_mac.cc",
    "content": "//===-- asan_malloc_mac.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Mac-specific malloc interception.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_MAC\n\n#include \"asan_interceptors.h\"\n#include \"asan_report.h\"\n#include \"asan_stack.h\"\n#include \"asan_stats.h\"\n\nusing namespace __asan;\n#define COMMON_MALLOC_ZONE_NAME \"asan\"\n#define COMMON_MALLOC_ENTER() ENSURE_ASAN_INITED()\n#define COMMON_MALLOC_SANITIZER_INITIALIZED asan_inited\n#define COMMON_MALLOC_FORCE_LOCK() asan_mz_force_lock()\n#define COMMON_MALLOC_FORCE_UNLOCK() asan_mz_force_unlock()\n#define COMMON_MALLOC_MEMALIGN(alignment, size) \\\n  GET_STACK_TRACE_MALLOC; \\\n  void *p = asan_memalign(alignment, size, &stack, FROM_MALLOC)\n#define COMMON_MALLOC_MALLOC(size) \\\n  GET_STACK_TRACE_MALLOC; \\\n  void *p = asan_malloc(size, &stack)\n#define COMMON_MALLOC_REALLOC(ptr, size) \\\n  GET_STACK_TRACE_MALLOC; \\\n  void *p = asan_realloc(ptr, size, &stack);\n#define COMMON_MALLOC_CALLOC(count, size) \\\n  GET_STACK_TRACE_MALLOC; \\\n  void *p = asan_calloc(count, size, &stack);\n#define COMMON_MALLOC_VALLOC(size) \\\n  GET_STACK_TRACE_MALLOC; \\\n  void *p = asan_memalign(GetPageSizeCached(), size, &stack, FROM_MALLOC);\n#define COMMON_MALLOC_FREE(ptr) \\\n  GET_STACK_TRACE_FREE; \\\n  asan_free(ptr, &stack, FROM_MALLOC);\n#define COMMON_MALLOC_SIZE(ptr) \\\n  uptr size = asan_mz_size(ptr);\n#define COMMON_MALLOC_FILL_STATS(zone, stats) \\\n  AsanMallocStats malloc_stats; \\\n  FillMallocStatistics(&malloc_stats); \\\n  CHECK(sizeof(malloc_statistics_t) == sizeof(AsanMallocStats)); \\\n  internal_memcpy(stats, &malloc_stats, sizeof(malloc_statistics_t));\n#define COMMON_MALLOC_REPORT_UNKNOWN_REALLOC(ptr, zone_ptr, zone_name) \\\n  GET_STACK_TRACE_FREE; \\\n  ReportMacMzReallocUnknown((uptr)ptr, (uptr)zone_ptr, zone_name, &stack);\n#define COMMON_MALLOC_NAMESPACE __asan\n\n#include \"sanitizer_common/sanitizer_malloc_mac.inc\"\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_malloc_win.cc",
    "content": "//===-- asan_malloc_win.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Windows-specific malloc interception.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_WINDOWS\n\n#include \"asan_allocator.h\"\n#include \"asan_interceptors.h\"\n#include \"asan_internal.h\"\n#include \"asan_stack.h\"\n#include \"interception/interception.h\"\n\n#include <stddef.h>\n\nusing namespace __asan;  // NOLINT\n\n// MT: Simply defining functions with the same signature in *.obj\n// files overrides the standard functions in the CRT.\n// MD: Memory allocation functions are defined in the CRT .dll,\n// so we have to intercept them before they are called for the first time.\n\n#if ASAN_DYNAMIC\n# define ALLOCATION_FUNCTION_ATTRIBUTE\n#else\n# define ALLOCATION_FUNCTION_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE\n#endif\n\nextern \"C\" {\nALLOCATION_FUNCTION_ATTRIBUTE\nvoid free(void *ptr) {\n  GET_STACK_TRACE_FREE;\n  return asan_free(ptr, &stack, FROM_MALLOC);\n}\n\nALLOCATION_FUNCTION_ATTRIBUTE\nvoid _free_dbg(void *ptr, int) {\n  free(ptr);\n}\n\nALLOCATION_FUNCTION_ATTRIBUTE\nvoid cfree(void *ptr) {\n  CHECK(!\"cfree() should not be used on Windows\");\n}\n\nALLOCATION_FUNCTION_ATTRIBUTE\nvoid *malloc(size_t size) {\n  GET_STACK_TRACE_MALLOC;\n  return asan_malloc(size, &stack);\n}\n\nALLOCATION_FUNCTION_ATTRIBUTE\nvoid *_malloc_dbg(size_t size, int, const char *, int) {\n  return malloc(size);\n}\n\nALLOCATION_FUNCTION_ATTRIBUTE\nvoid *calloc(size_t nmemb, size_t size) {\n  GET_STACK_TRACE_MALLOC;\n  return asan_calloc(nmemb, size, &stack);\n}\n\nALLOCATION_FUNCTION_ATTRIBUTE\nvoid *_calloc_dbg(size_t nmemb, size_t size, int, const char *, int) {\n  return calloc(nmemb, size);\n}\n\nALLOCATION_FUNCTION_ATTRIBUTE\nvoid *_calloc_impl(size_t nmemb, size_t size, int *errno_tmp) {\n  return calloc(nmemb, size);\n}\n\nALLOCATION_FUNCTION_ATTRIBUTE\nvoid *realloc(void *ptr, size_t size) {\n  GET_STACK_TRACE_MALLOC;\n  return asan_realloc(ptr, size, &stack);\n}\n\nALLOCATION_FUNCTION_ATTRIBUTE\nvoid *_realloc_dbg(void *ptr, size_t size, int) {\n  CHECK(!\"_realloc_dbg should not exist!\");\n  return 0;\n}\n\nALLOCATION_FUNCTION_ATTRIBUTE\nvoid *_recalloc(void *p, size_t n, size_t elem_size) {\n  if (!p)\n    return calloc(n, elem_size);\n  const size_t size = n * elem_size;\n  if (elem_size != 0 && size / elem_size != n)\n    return 0;\n  return realloc(p, size);\n}\n\nALLOCATION_FUNCTION_ATTRIBUTE\nsize_t _msize(void *ptr) {\n  GET_CURRENT_PC_BP_SP;\n  (void)sp;\n  return asan_malloc_usable_size(ptr, pc, bp);\n}\n\nALLOCATION_FUNCTION_ATTRIBUTE\nvoid *_expand(void *memblock, size_t size) {\n  // _expand is used in realloc-like functions to resize the buffer if possible.\n  // We don't want memory to stand still while resizing buffers, so return 0.\n  return 0;\n}\n\nALLOCATION_FUNCTION_ATTRIBUTE\nvoid *_expand_dbg(void *memblock, size_t size) {\n  return _expand(memblock, size);\n}\n\n// TODO(timurrrr): Might want to add support for _aligned_* allocation\n// functions to detect a bit more bugs.  Those functions seem to wrap malloc().\n\nint _CrtDbgReport(int, const char*, int,\n                  const char*, const char*, ...) {\n  ShowStatsAndAbort();\n}\n\nint _CrtDbgReportW(int reportType, const wchar_t*, int,\n                   const wchar_t*, const wchar_t*, ...) {\n  ShowStatsAndAbort();\n}\n\nint _CrtSetReportMode(int, int) {\n  return 0;\n}\n}  // extern \"C\"\n\nnamespace __asan {\nvoid ReplaceSystemMalloc() {\n#if defined(ASAN_DYNAMIC)\n  // We don't check the result because CRT might not be used in the process.\n  __interception::OverrideFunction(\"free\", (uptr)free);\n  __interception::OverrideFunction(\"malloc\", (uptr)malloc);\n  __interception::OverrideFunction(\"_malloc_crt\", (uptr)malloc);\n  __interception::OverrideFunction(\"calloc\", (uptr)calloc);\n  __interception::OverrideFunction(\"_calloc_crt\", (uptr)calloc);\n  __interception::OverrideFunction(\"realloc\", (uptr)realloc);\n  __interception::OverrideFunction(\"_realloc_crt\", (uptr)realloc);\n  __interception::OverrideFunction(\"_recalloc\", (uptr)_recalloc);\n  __interception::OverrideFunction(\"_recalloc_crt\", (uptr)_recalloc);\n  __interception::OverrideFunction(\"_msize\", (uptr)_msize);\n  __interception::OverrideFunction(\"_expand\", (uptr)_expand);\n\n  // Override different versions of 'operator new' and 'operator delete'.\n  // No need to override the nothrow versions as they just wrap the throw\n  // versions.\n  // FIXME: Unfortunately, MSVC miscompiles the statements that take the\n  // addresses of the array versions of these operators,\n  // see https://connect.microsoft.com/VisualStudio/feedbackdetail/view/946992\n  // We might want to try to work around this by [inline] assembly or compiling\n  // parts of the RTL with Clang.\n  void *(*op_new)(size_t sz) = operator new;\n  void (*op_delete)(void *p) = operator delete;\n  void *(*op_array_new)(size_t sz) = operator new[];\n  void (*op_array_delete)(void *p) = operator delete[];\n  __interception::OverrideFunction(\"??2@YAPAXI@Z\", (uptr)op_new);\n  __interception::OverrideFunction(\"??3@YAXPAX@Z\", (uptr)op_delete);\n  __interception::OverrideFunction(\"??_U@YAPAXI@Z\", (uptr)op_array_new);\n  __interception::OverrideFunction(\"??_V@YAXPAX@Z\", (uptr)op_array_delete);\n#endif\n}\n}  // namespace __asan\n\n#endif  // _WIN32\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_mapping.h",
    "content": "//===-- asan_mapping.h ------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Defines ASan memory mapping.\n//===----------------------------------------------------------------------===//\n#ifndef ASAN_MAPPING_H\n#define ASAN_MAPPING_H\n\n#include \"asan_internal.h\"\n\n// The full explanation of the memory mapping could be found here:\n// https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm\n//\n// Typical shadow mapping on Linux/x86_64 with SHADOW_OFFSET == 0x00007fff8000:\n// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem    ||\n// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||\n// || `[0x00008fff7000, 0x02008fff6fff]` || ShadowGap  ||\n// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow  ||\n// || `[0x000000000000, 0x00007fff7fff]` || LowMem     ||\n//\n// When SHADOW_OFFSET is zero (-pie):\n// || `[0x100000000000, 0x7fffffffffff]` || HighMem    ||\n// || `[0x020000000000, 0x0fffffffffff]` || HighShadow ||\n// || `[0x000000040000, 0x01ffffffffff]` || ShadowGap  ||\n//\n// Special case when something is already mapped between\n// 0x003000000000 and 0x005000000000 (e.g. when prelink is installed):\n// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem    ||\n// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||\n// || `[0x005000000000, 0x02008fff6fff]` || ShadowGap3 ||\n// || `[0x003000000000, 0x004fffffffff]` || MidMem     ||\n// || `[0x000a7fff8000, 0x002fffffffff]` || ShadowGap2 ||\n// || `[0x00067fff8000, 0x000a7fff7fff]` || MidShadow  ||\n// || `[0x00008fff7000, 0x00067fff7fff]` || ShadowGap  ||\n// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow  ||\n// || `[0x000000000000, 0x00007fff7fff]` || LowMem     ||\n//\n// Default Linux/i386 mapping on x86_64 machine:\n// || `[0x40000000, 0xffffffff]` || HighMem    ||\n// || `[0x28000000, 0x3fffffff]` || HighShadow ||\n// || `[0x24000000, 0x27ffffff]` || ShadowGap  ||\n// || `[0x20000000, 0x23ffffff]` || LowShadow  ||\n// || `[0x00000000, 0x1fffffff]` || LowMem     ||\n//\n// Default Linux/i386 mapping on i386 machine\n// (addresses starting with 0xc0000000 are reserved\n// for kernel and thus not sanitized):\n// || `[0x38000000, 0xbfffffff]` || HighMem    ||\n// || `[0x27000000, 0x37ffffff]` || HighShadow ||\n// || `[0x24000000, 0x26ffffff]` || ShadowGap  ||\n// || `[0x20000000, 0x23ffffff]` || LowShadow  ||\n// || `[0x00000000, 0x1fffffff]` || LowMem     ||\n//\n// Default Linux/MIPS32 mapping:\n// || `[0x2aaa0000, 0xffffffff]` || HighMem    ||\n// || `[0x0fff4000, 0x2aa9ffff]` || HighShadow ||\n// || `[0x0bff4000, 0x0fff3fff]` || ShadowGap  ||\n// || `[0x0aaa0000, 0x0bff3fff]` || LowShadow  ||\n// || `[0x00000000, 0x0aa9ffff]` || LowMem     ||\n//\n// Default Linux/MIPS64 mapping:\n// || `[0x4000000000, 0xffffffffff]` || HighMem    ||\n// || `[0x2800000000, 0x3fffffffff]` || HighShadow ||\n// || `[0x2400000000, 0x27ffffffff]` || ShadowGap  ||\n// || `[0x2000000000, 0x23ffffffff]` || LowShadow  ||\n// || `[0x0000000000, 0x1fffffffff]` || LowMem     ||\n//\n// Default Linux/AArch64 (39-bit VMA) mapping:\n// || `[0x2000000000, 0x7fffffffff]` || highmem    ||\n// || `[0x1400000000, 0x1fffffffff]` || highshadow ||\n// || `[0x1200000000, 0x13ffffffff]` || shadowgap  ||\n// || `[0x1000000000, 0x11ffffffff]` || lowshadow  ||\n// || `[0x0000000000, 0x0fffffffff]` || lowmem     ||\n//\n// Default Linux/AArch64 (42-bit VMA) mapping:\n// || `[0x10000000000, 0x3ffffffffff]` || highmem    ||\n// || `[0x0a000000000, 0x0ffffffffff]` || highshadow ||\n// || `[0x09000000000, 0x09fffffffff]` || shadowgap  ||\n// || `[0x08000000000, 0x08fffffffff]` || lowshadow  ||\n// || `[0x00000000000, 0x07fffffffff]` || lowmem     ||\n//\n// Shadow mapping on FreeBSD/x86-64 with SHADOW_OFFSET == 0x400000000000:\n// || `[0x500000000000, 0x7fffffffffff]` || HighMem    ||\n// || `[0x4a0000000000, 0x4fffffffffff]` || HighShadow ||\n// || `[0x480000000000, 0x49ffffffffff]` || ShadowGap  ||\n// || `[0x400000000000, 0x47ffffffffff]` || LowShadow  ||\n// || `[0x000000000000, 0x3fffffffffff]` || LowMem     ||\n//\n// Shadow mapping on FreeBSD/i386 with SHADOW_OFFSET == 0x40000000:\n// || `[0x60000000, 0xffffffff]` || HighMem    ||\n// || `[0x4c000000, 0x5fffffff]` || HighShadow ||\n// || `[0x48000000, 0x4bffffff]` || ShadowGap  ||\n// || `[0x40000000, 0x47ffffff]` || LowShadow  ||\n// || `[0x00000000, 0x3fffffff]` || LowMem     ||\n//\n// Default Windows/i386 mapping:\n// (the exact location of HighShadow/HighMem may vary depending\n//  on WoW64, /LARGEADDRESSAWARE, etc).\n// || `[0x50000000, 0xffffffff]` || HighMem    ||\n// || `[0x3a000000, 0x4fffffff]` || HighShadow ||\n// || `[0x36000000, 0x39ffffff]` || ShadowGap  ||\n// || `[0x30000000, 0x35ffffff]` || LowShadow  ||\n// || `[0x00000000, 0x2fffffff]` || LowMem     ||\n\nstatic const u64 kDefaultShadowScale = 3;\nstatic const u64 kDefaultShadowOffset32 = 1ULL << 29;  // 0x20000000\nstatic const u64 kDefaultShadowOffset64 = 1ULL << 44;\nstatic const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000;  // < 2G.\nstatic const u64 kIosShadowOffset32 = 1ULL << 30;  // 0x40000000\nstatic const u64 kIosShadowOffset64 = 0x130000000;\nstatic const u64 kIosSimShadowOffset32 = 1ULL << 30;\nstatic const u64 kIosSimShadowOffset64 = kDefaultShadowOffset64;\nstatic const u64 kAArch64_ShadowOffset64 = 1ULL << 36;\nstatic const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000;\nstatic const u64 kMIPS64_ShadowOffset64 = 1ULL << 37;\nstatic const u64 kPPC64_ShadowOffset64 = 1ULL << 41;\nstatic const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30;  // 0x40000000\nstatic const u64 kFreeBSD_ShadowOffset64 = 1ULL << 46;  // 0x400000000000\nstatic const u64 kWindowsShadowOffset32 = 3ULL << 28;  // 0x30000000\n\n#define SHADOW_SCALE kDefaultShadowScale\n\n\n#if SANITIZER_WORDSIZE == 32\n#  if SANITIZER_ANDROID\n#    define SHADOW_OFFSET (0)\n#  elif defined(__mips__)\n#    define SHADOW_OFFSET kMIPS32_ShadowOffset32\n#  elif SANITIZER_FREEBSD\n#    define SHADOW_OFFSET kFreeBSD_ShadowOffset32\n#  elif SANITIZER_WINDOWS\n#    define SHADOW_OFFSET kWindowsShadowOffset32\n#  elif SANITIZER_IOSSIM\n#    define SHADOW_OFFSET kIosSimShadowOffset32\n#  elif SANITIZER_IOS\n#    define SHADOW_OFFSET kIosShadowOffset32\n#  else\n#    define SHADOW_OFFSET kDefaultShadowOffset32\n#  endif\n#else\n#  if defined(__aarch64__)\n#    define SHADOW_OFFSET kAArch64_ShadowOffset64\n#  elif defined(__powerpc64__)\n#    define SHADOW_OFFSET kPPC64_ShadowOffset64\n#  elif SANITIZER_FREEBSD\n#    define SHADOW_OFFSET kFreeBSD_ShadowOffset64\n#  elif SANITIZER_MAC\n#   define SHADOW_OFFSET kDefaultShadowOffset64\n#  elif defined(__mips64)\n#   define SHADOW_OFFSET kMIPS64_ShadowOffset64\n#  elif SANITIZER_IOSSIM\n#    define SHADOW_OFFSET kIosSimShadowOffset64\n#  elif SANITIZER_IOS\n#    define SHADOW_OFFSET kIosShadowOffset64\n#  else\n#   define SHADOW_OFFSET kDefaultShort64bitShadowOffset\n#  endif\n#endif\n\n#define SHADOW_GRANULARITY (1ULL << SHADOW_SCALE)\n#define MEM_TO_SHADOW(mem) (((mem) >> SHADOW_SCALE) + (SHADOW_OFFSET))\n#define SHADOW_TO_MEM(shadow) (((shadow) - SHADOW_OFFSET) << SHADOW_SCALE)\n\n#define kLowMemBeg      0\n#define kLowMemEnd      (SHADOW_OFFSET ? SHADOW_OFFSET - 1 : 0)\n\n#define kLowShadowBeg   SHADOW_OFFSET\n#define kLowShadowEnd   MEM_TO_SHADOW(kLowMemEnd)\n\n#define kHighMemBeg     (MEM_TO_SHADOW(kHighMemEnd) + 1)\n\n#define kHighShadowBeg  MEM_TO_SHADOW(kHighMemBeg)\n#define kHighShadowEnd  MEM_TO_SHADOW(kHighMemEnd)\n\n# define kMidShadowBeg MEM_TO_SHADOW(kMidMemBeg)\n# define kMidShadowEnd MEM_TO_SHADOW(kMidMemEnd)\n\n// With the zero shadow base we can not actually map pages starting from 0.\n// This constant is somewhat arbitrary.\n#define kZeroBaseShadowStart 0\n#define kZeroBaseMaxShadowStart (1 << 18)\n\n#define kShadowGapBeg   (kLowShadowEnd ? kLowShadowEnd + 1 \\\n                                       : kZeroBaseShadowStart)\n#define kShadowGapEnd   ((kMidMemBeg ? kMidShadowBeg : kHighShadowBeg) - 1)\n\n#define kShadowGap2Beg (kMidMemBeg ? kMidShadowEnd + 1 : 0)\n#define kShadowGap2End (kMidMemBeg ? kMidMemBeg - 1 : 0)\n\n#define kShadowGap3Beg (kMidMemBeg ? kMidMemEnd + 1 : 0)\n#define kShadowGap3End (kMidMemBeg ? kHighShadowBeg - 1 : 0)\n\n#define DO_ASAN_MAPPING_PROFILE 0  // Set to 1 to profile the functions below.\n\n#if DO_ASAN_MAPPING_PROFILE\n# define PROFILE_ASAN_MAPPING() AsanMappingProfile[__LINE__]++;\n#else\n# define PROFILE_ASAN_MAPPING()\n#endif\n\n// If 1, all shadow boundaries are constants.\n// Don't set to 1 other than for testing.\n#define ASAN_FIXED_MAPPING 0\n\nnamespace __asan {\n\nextern uptr AsanMappingProfile[];\n\n#if ASAN_FIXED_MAPPING\n// Fixed mapping for 64-bit Linux. Mostly used for performance comparison\n// with non-fixed mapping. As of r175253 (Feb 2013) the performance\n// difference between fixed and non-fixed mapping is below the noise level.\nstatic uptr kHighMemEnd = 0x7fffffffffffULL;\nstatic uptr kMidMemBeg =    0x3000000000ULL;\nstatic uptr kMidMemEnd =    0x4fffffffffULL;\n#else\nextern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;  // Initialized in __asan_init.\n#endif\n\nstatic inline bool AddrIsInLowMem(uptr a) {\n  PROFILE_ASAN_MAPPING();\n  return a < kLowMemEnd;\n}\n\nstatic inline bool AddrIsInLowShadow(uptr a) {\n  PROFILE_ASAN_MAPPING();\n  return a >= kLowShadowBeg && a <= kLowShadowEnd;\n}\n\nstatic inline bool AddrIsInHighMem(uptr a) {\n  PROFILE_ASAN_MAPPING();\n  return a >= kHighMemBeg && a <= kHighMemEnd;\n}\n\nstatic inline bool AddrIsInMidMem(uptr a) {\n  PROFILE_ASAN_MAPPING();\n  return kMidMemBeg && a >= kMidMemBeg && a <= kMidMemEnd;\n}\n\nstatic inline bool AddrIsInMem(uptr a) {\n  PROFILE_ASAN_MAPPING();\n  return AddrIsInLowMem(a) || AddrIsInMidMem(a) || AddrIsInHighMem(a);\n}\n\nstatic inline uptr MemToShadow(uptr p) {\n  PROFILE_ASAN_MAPPING();\n  CHECK(AddrIsInMem(p));\n  return MEM_TO_SHADOW(p);\n}\n\nstatic inline bool AddrIsInHighShadow(uptr a) {\n  PROFILE_ASAN_MAPPING();\n  return a >= kHighShadowBeg && a <= kHighMemEnd;\n}\n\nstatic inline bool AddrIsInMidShadow(uptr a) {\n  PROFILE_ASAN_MAPPING();\n  return kMidMemBeg && a >= kMidShadowBeg && a <= kMidMemEnd;\n}\n\nstatic inline bool AddrIsInShadow(uptr a) {\n  PROFILE_ASAN_MAPPING();\n  return AddrIsInLowShadow(a) || AddrIsInMidShadow(a) || AddrIsInHighShadow(a);\n}\n\nstatic inline bool AddrIsInShadowGap(uptr a) {\n  PROFILE_ASAN_MAPPING();\n  if (kMidMemBeg) {\n    if (a <= kShadowGapEnd)\n      return SHADOW_OFFSET == 0 || a >= kShadowGapBeg;\n    return (a >= kShadowGap2Beg && a <= kShadowGap2End) ||\n           (a >= kShadowGap3Beg && a <= kShadowGap3End);\n  }\n  // In zero-based shadow mode we treat addresses near zero as addresses\n  // in shadow gap as well.\n  if (SHADOW_OFFSET == 0)\n    return a <= kShadowGapEnd;\n  return a >= kShadowGapBeg && a <= kShadowGapEnd;\n}\n\nstatic inline bool AddrIsAlignedByGranularity(uptr a) {\n  PROFILE_ASAN_MAPPING();\n  return (a & (SHADOW_GRANULARITY - 1)) == 0;\n}\n\nstatic inline bool AddressIsPoisoned(uptr a) {\n  PROFILE_ASAN_MAPPING();\n  const uptr kAccessSize = 1;\n  u8 *shadow_address = (u8*)MEM_TO_SHADOW(a);\n  s8 shadow_value = *shadow_address;\n  if (shadow_value) {\n    u8 last_accessed_byte = (a & (SHADOW_GRANULARITY - 1))\n                                 + kAccessSize - 1;\n    return (last_accessed_byte >= shadow_value);\n  }\n  return false;\n}\n\n// Must be after all calls to PROFILE_ASAN_MAPPING().\nstatic const uptr kAsanMappingProfileSize = __LINE__;\n\n}  // namespace __asan\n\n#endif  // ASAN_MAPPING_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_new_delete.cc",
    "content": "//===-- asan_interceptors.cc ----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Interceptors for operators new and delete.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_allocator.h\"\n#include \"asan_internal.h\"\n#include \"asan_stack.h\"\n\n#include \"interception/interception.h\"\n\n#include <stddef.h>\n\n// C++ operators can't have visibility attributes on Windows.\n#if SANITIZER_WINDOWS\n# define CXX_OPERATOR_ATTRIBUTE\n#else\n# define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE\n#endif\n\nusing namespace __asan;  // NOLINT\n\n// This code has issues on OSX.\n// See https://github.com/google/sanitizers/issues/131.\n\n// Fake std::nothrow_t to avoid including <new>.\nnamespace std {\nstruct nothrow_t {};\n}  // namespace std\n\n#define OPERATOR_NEW_BODY(type) \\\n  GET_STACK_TRACE_MALLOC;\\\n  return asan_memalign(0, size, &stack, type);\n\n// On OS X it's not enough to just provide our own 'operator new' and\n// 'operator delete' implementations, because they're going to be in the\n// runtime dylib, and the main executable will depend on both the runtime\n// dylib and libstdc++, each of those'll have its implementation of new and\n// delete.\n// To make sure that C++ allocation/deallocation operators are overridden on\n// OS X we need to intercept them using their mangled names.\n#if !SANITIZER_MAC\n// FreeBSD prior v9.2 have wrong definition of 'size_t'.\n// http://svnweb.freebsd.org/base?view=revision&revision=232261\n#if SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32\n#include <sys/param.h>\n#if __FreeBSD_version <= 902001  // v9.2\n#define size_t unsigned\n#endif  // __FreeBSD_version\n#endif  // SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32\n\nCXX_OPERATOR_ATTRIBUTE\nvoid *operator new(size_t size) { OPERATOR_NEW_BODY(FROM_NEW); }\nCXX_OPERATOR_ATTRIBUTE\nvoid *operator new[](size_t size) { OPERATOR_NEW_BODY(FROM_NEW_BR); }\nCXX_OPERATOR_ATTRIBUTE\nvoid *operator new(size_t size, std::nothrow_t const&)\n{ OPERATOR_NEW_BODY(FROM_NEW); }\nCXX_OPERATOR_ATTRIBUTE\nvoid *operator new[](size_t size, std::nothrow_t const&)\n{ OPERATOR_NEW_BODY(FROM_NEW_BR); }\n\n#else  // SANITIZER_MAC\nINTERCEPTOR(void *, _Znwm, size_t size) {\n  OPERATOR_NEW_BODY(FROM_NEW);\n}\nINTERCEPTOR(void *, _Znam, size_t size) {\n  OPERATOR_NEW_BODY(FROM_NEW_BR);\n}\nINTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&) {\n  OPERATOR_NEW_BODY(FROM_NEW);\n}\nINTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) {\n  OPERATOR_NEW_BODY(FROM_NEW_BR);\n}\n#endif\n\n#define OPERATOR_DELETE_BODY(type) \\\n  GET_STACK_TRACE_FREE;\\\n  asan_free(ptr, &stack, type);\n\n#if !SANITIZER_MAC\nCXX_OPERATOR_ATTRIBUTE\nvoid operator delete(void *ptr) NOEXCEPT {\n  OPERATOR_DELETE_BODY(FROM_NEW);\n}\nCXX_OPERATOR_ATTRIBUTE\nvoid operator delete[](void *ptr) NOEXCEPT {\n  OPERATOR_DELETE_BODY(FROM_NEW_BR);\n}\nCXX_OPERATOR_ATTRIBUTE\nvoid operator delete(void *ptr, std::nothrow_t const&) {\n  OPERATOR_DELETE_BODY(FROM_NEW);\n}\nCXX_OPERATOR_ATTRIBUTE\nvoid operator delete[](void *ptr, std::nothrow_t const&) {\n  OPERATOR_DELETE_BODY(FROM_NEW_BR);\n}\nCXX_OPERATOR_ATTRIBUTE\nvoid operator delete(void *ptr, size_t size) NOEXCEPT {\n  GET_STACK_TRACE_FREE;\n  asan_sized_free(ptr, size, &stack, FROM_NEW);\n}\nCXX_OPERATOR_ATTRIBUTE\nvoid operator delete[](void *ptr, size_t size) NOEXCEPT {\n  GET_STACK_TRACE_FREE;\n  asan_sized_free(ptr, size, &stack, FROM_NEW_BR);\n}\n\n#else  // SANITIZER_MAC\nINTERCEPTOR(void, _ZdlPv, void *ptr) {\n  OPERATOR_DELETE_BODY(FROM_NEW);\n}\nINTERCEPTOR(void, _ZdaPv, void *ptr) {\n  OPERATOR_DELETE_BODY(FROM_NEW_BR);\n}\nINTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) {\n  OPERATOR_DELETE_BODY(FROM_NEW);\n}\nINTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) {\n  OPERATOR_DELETE_BODY(FROM_NEW_BR);\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_poisoning.cc",
    "content": "//===-- asan_poisoning.cc -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Shadow memory poisoning by ASan RTL and by user application.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_poisoning.h\"\n#include \"asan_report.h\"\n#include \"asan_stack.h\"\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n\nnamespace __asan {\n\nstatic atomic_uint8_t can_poison_memory;\n\nvoid SetCanPoisonMemory(bool value) {\n  atomic_store(&can_poison_memory, value, memory_order_release);\n}\n\nbool CanPoisonMemory() {\n  return atomic_load(&can_poison_memory, memory_order_acquire);\n}\n\nvoid PoisonShadow(uptr addr, uptr size, u8 value) {\n  if (!CanPoisonMemory()) return;\n  CHECK(AddrIsAlignedByGranularity(addr));\n  CHECK(AddrIsInMem(addr));\n  CHECK(AddrIsAlignedByGranularity(addr + size));\n  CHECK(AddrIsInMem(addr + size - SHADOW_GRANULARITY));\n  CHECK(REAL(memset));\n  FastPoisonShadow(addr, size, value);\n}\n\nvoid PoisonShadowPartialRightRedzone(uptr addr,\n                                     uptr size,\n                                     uptr redzone_size,\n                                     u8 value) {\n  if (!CanPoisonMemory()) return;\n  CHECK(AddrIsAlignedByGranularity(addr));\n  CHECK(AddrIsInMem(addr));\n  FastPoisonShadowPartialRightRedzone(addr, size, redzone_size, value);\n}\n\nstruct ShadowSegmentEndpoint {\n  u8 *chunk;\n  s8 offset;  // in [0, SHADOW_GRANULARITY)\n  s8 value;  // = *chunk;\n\n  explicit ShadowSegmentEndpoint(uptr address) {\n    chunk = (u8*)MemToShadow(address);\n    offset = address & (SHADOW_GRANULARITY - 1);\n    value = *chunk;\n  }\n};\n\nvoid FlushUnneededASanShadowMemory(uptr p, uptr size) {\n    // Since asan's mapping is compacting, the shadow chunk may be\n    // not page-aligned, so we only flush the page-aligned portion.\n    uptr page_size = GetPageSizeCached();\n    uptr shadow_beg = RoundUpTo(MemToShadow(p), page_size);\n    uptr shadow_end = RoundDownTo(MemToShadow(p + size), page_size);\n    FlushUnneededShadowMemory(shadow_beg, shadow_end - shadow_beg);\n}\n\nvoid AsanPoisonOrUnpoisonIntraObjectRedzone(uptr ptr, uptr size, bool poison) {\n  uptr end = ptr + size;\n  if (Verbosity()) {\n    Printf(\"__asan_%spoison_intra_object_redzone [%p,%p) %zd\\n\",\n           poison ? \"\" : \"un\", ptr, end, size);\n    if (Verbosity() >= 2)\n      PRINT_CURRENT_STACK();\n  }\n  CHECK(size);\n  CHECK_LE(size, 4096);\n  CHECK(IsAligned(end, SHADOW_GRANULARITY));\n  if (!IsAligned(ptr, SHADOW_GRANULARITY)) {\n    *(u8 *)MemToShadow(ptr) =\n        poison ? static_cast<u8>(ptr % SHADOW_GRANULARITY) : 0;\n    ptr |= SHADOW_GRANULARITY - 1;\n    ptr++;\n  }\n  for (; ptr < end; ptr += SHADOW_GRANULARITY)\n    *(u8*)MemToShadow(ptr) = poison ? kAsanIntraObjectRedzone : 0;\n}\n\n}  // namespace __asan\n\n// ---------------------- Interface ---------------- {{{1\nusing namespace __asan;  // NOLINT\n\n// Current implementation of __asan_(un)poison_memory_region doesn't check\n// that user program (un)poisons the memory it owns. It poisons memory\n// conservatively, and unpoisons progressively to make sure asan shadow\n// mapping invariant is preserved (see detailed mapping description here:\n// https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm).\n//\n// * if user asks to poison region [left, right), the program poisons\n// at least [left, AlignDown(right)).\n// * if user asks to unpoison region [left, right), the program unpoisons\n// at most [AlignDown(left), right).\nvoid __asan_poison_memory_region(void const volatile *addr, uptr size) {\n  if (!flags()->allow_user_poisoning || size == 0) return;\n  uptr beg_addr = (uptr)addr;\n  uptr end_addr = beg_addr + size;\n  VPrintf(3, \"Trying to poison memory region [%p, %p)\\n\", (void *)beg_addr,\n          (void *)end_addr);\n  ShadowSegmentEndpoint beg(beg_addr);\n  ShadowSegmentEndpoint end(end_addr);\n  if (beg.chunk == end.chunk) {\n    CHECK(beg.offset < end.offset);\n    s8 value = beg.value;\n    CHECK(value == end.value);\n    // We can only poison memory if the byte in end.offset is unaddressable.\n    // No need to re-poison memory if it is poisoned already.\n    if (value > 0 && value <= end.offset) {\n      if (beg.offset > 0) {\n        *beg.chunk = Min(value, beg.offset);\n      } else {\n        *beg.chunk = kAsanUserPoisonedMemoryMagic;\n      }\n    }\n    return;\n  }\n  CHECK(beg.chunk < end.chunk);\n  if (beg.offset > 0) {\n    // Mark bytes from beg.offset as unaddressable.\n    if (beg.value == 0) {\n      *beg.chunk = beg.offset;\n    } else {\n      *beg.chunk = Min(beg.value, beg.offset);\n    }\n    beg.chunk++;\n  }\n  REAL(memset)(beg.chunk, kAsanUserPoisonedMemoryMagic, end.chunk - beg.chunk);\n  // Poison if byte in end.offset is unaddressable.\n  if (end.value > 0 && end.value <= end.offset) {\n    *end.chunk = kAsanUserPoisonedMemoryMagic;\n  }\n}\n\nvoid __asan_unpoison_memory_region(void const volatile *addr, uptr size) {\n  if (!flags()->allow_user_poisoning || size == 0) return;\n  uptr beg_addr = (uptr)addr;\n  uptr end_addr = beg_addr + size;\n  VPrintf(3, \"Trying to unpoison memory region [%p, %p)\\n\", (void *)beg_addr,\n          (void *)end_addr);\n  ShadowSegmentEndpoint beg(beg_addr);\n  ShadowSegmentEndpoint end(end_addr);\n  if (beg.chunk == end.chunk) {\n    CHECK(beg.offset < end.offset);\n    s8 value = beg.value;\n    CHECK(value == end.value);\n    // We unpoison memory bytes up to enbytes up to end.offset if it is not\n    // unpoisoned already.\n    if (value != 0) {\n      *beg.chunk = Max(value, end.offset);\n    }\n    return;\n  }\n  CHECK(beg.chunk < end.chunk);\n  if (beg.offset > 0) {\n    *beg.chunk = 0;\n    beg.chunk++;\n  }\n  REAL(memset)(beg.chunk, 0, end.chunk - beg.chunk);\n  if (end.offset > 0 && end.value != 0) {\n    *end.chunk = Max(end.value, end.offset);\n  }\n}\n\nint __asan_address_is_poisoned(void const volatile *addr) {\n  return __asan::AddressIsPoisoned((uptr)addr);\n}\n\nuptr __asan_region_is_poisoned(uptr beg, uptr size) {\n  if (!size) return 0;\n  uptr end = beg + size;\n  if (!AddrIsInMem(beg)) return beg;\n  if (!AddrIsInMem(end)) return end;\n  CHECK_LT(beg, end);\n  uptr aligned_b = RoundUpTo(beg, SHADOW_GRANULARITY);\n  uptr aligned_e = RoundDownTo(end, SHADOW_GRANULARITY);\n  uptr shadow_beg = MemToShadow(aligned_b);\n  uptr shadow_end = MemToShadow(aligned_e);\n  // First check the first and the last application bytes,\n  // then check the SHADOW_GRANULARITY-aligned region by calling\n  // mem_is_zero on the corresponding shadow.\n  if (!__asan::AddressIsPoisoned(beg) &&\n      !__asan::AddressIsPoisoned(end - 1) &&\n      (shadow_end <= shadow_beg ||\n       __sanitizer::mem_is_zero((const char *)shadow_beg,\n                                shadow_end - shadow_beg)))\n    return 0;\n  // The fast check failed, so we have a poisoned byte somewhere.\n  // Find it slowly.\n  for (; beg < end; beg++)\n    if (__asan::AddressIsPoisoned(beg))\n      return beg;\n  UNREACHABLE(\"mem_is_zero returned false, but poisoned byte was not found\");\n  return 0;\n}\n\n#define CHECK_SMALL_REGION(p, size, isWrite)                  \\\n  do {                                                        \\\n    uptr __p = reinterpret_cast<uptr>(p);                     \\\n    uptr __size = size;                                       \\\n    if (UNLIKELY(__asan::AddressIsPoisoned(__p) ||            \\\n        __asan::AddressIsPoisoned(__p + __size - 1))) {       \\\n      GET_CURRENT_PC_BP_SP;                                   \\\n      uptr __bad = __asan_region_is_poisoned(__p, __size);    \\\n      __asan_report_error(pc, bp, sp, __bad, isWrite, __size, 0);\\\n    }                                                         \\\n  } while (false);                                            \\\n\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nu16 __sanitizer_unaligned_load16(const uu16 *p) {\n  CHECK_SMALL_REGION(p, sizeof(*p), false);\n  return *p;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nu32 __sanitizer_unaligned_load32(const uu32 *p) {\n  CHECK_SMALL_REGION(p, sizeof(*p), false);\n  return *p;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nu64 __sanitizer_unaligned_load64(const uu64 *p) {\n  CHECK_SMALL_REGION(p, sizeof(*p), false);\n  return *p;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_unaligned_store16(uu16 *p, u16 x) {\n  CHECK_SMALL_REGION(p, sizeof(*p), true);\n  *p = x;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_unaligned_store32(uu32 *p, u32 x) {\n  CHECK_SMALL_REGION(p, sizeof(*p), true);\n  *p = x;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_unaligned_store64(uu64 *p, u64 x) {\n  CHECK_SMALL_REGION(p, sizeof(*p), true);\n  *p = x;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nvoid __asan_poison_cxx_array_cookie(uptr p) {\n  if (SANITIZER_WORDSIZE != 64) return;\n  if (!flags()->poison_array_cookie) return;\n  uptr s = MEM_TO_SHADOW(p);\n  *reinterpret_cast<u8*>(s) = kAsanArrayCookieMagic;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nuptr __asan_load_cxx_array_cookie(uptr *p) {\n  if (SANITIZER_WORDSIZE != 64) return *p;\n  if (!flags()->poison_array_cookie) return *p;\n  uptr s = MEM_TO_SHADOW(reinterpret_cast<uptr>(p));\n  u8 sval = *reinterpret_cast<u8*>(s);\n  if (sval == kAsanArrayCookieMagic) return *p;\n  // If sval is not kAsanArrayCookieMagic it can only be freed memory,\n  // which means that we are going to get double-free. So, return 0 to avoid\n  // infinite loop of destructors. We don't want to report a double-free here\n  // though, so print a warning just in case.\n  // CHECK_EQ(sval, kAsanHeapFreeMagic);\n  if (sval == kAsanHeapFreeMagic) {\n    Report(\"AddressSanitizer: loaded array cookie from free-d memory; \"\n           \"expect a double-free report\\n\");\n    return 0;\n  }\n  // The cookie may remain unpoisoned if e.g. it comes from a custom\n  // operator new defined inside a class.\n  return *p;\n}\n\n// This is a simplified version of __asan_(un)poison_memory_region, which\n// assumes that left border of region to be poisoned is properly aligned.\nstatic void PoisonAlignedStackMemory(uptr addr, uptr size, bool do_poison) {\n  if (size == 0) return;\n  uptr aligned_size = size & ~(SHADOW_GRANULARITY - 1);\n  PoisonShadow(addr, aligned_size,\n               do_poison ? kAsanStackUseAfterScopeMagic : 0);\n  if (size == aligned_size)\n    return;\n  s8 end_offset = (s8)(size - aligned_size);\n  s8* shadow_end = (s8*)MemToShadow(addr + aligned_size);\n  s8 end_value = *shadow_end;\n  if (do_poison) {\n    // If possible, mark all the bytes mapping to last shadow byte as\n    // unaddressable.\n    if (end_value > 0 && end_value <= end_offset)\n      *shadow_end = (s8)kAsanStackUseAfterScopeMagic;\n  } else {\n    // If necessary, mark few first bytes mapping to last shadow byte\n    // as addressable\n    if (end_value != 0)\n      *shadow_end = Max(end_value, end_offset);\n  }\n}\n\nvoid __asan_poison_stack_memory(uptr addr, uptr size) {\n  VReport(1, \"poisoning: %p %zx\\n\", (void *)addr, size);\n  PoisonAlignedStackMemory(addr, size, true);\n}\n\nvoid __asan_unpoison_stack_memory(uptr addr, uptr size) {\n  VReport(1, \"unpoisoning: %p %zx\\n\", (void *)addr, size);\n  PoisonAlignedStackMemory(addr, size, false);\n}\n\nvoid __sanitizer_annotate_contiguous_container(const void *beg_p,\n                                               const void *end_p,\n                                               const void *old_mid_p,\n                                               const void *new_mid_p) {\n  if (!flags()->detect_container_overflow) return;\n  VPrintf(2, \"contiguous_container: %p %p %p %p\\n\", beg_p, end_p, old_mid_p,\n          new_mid_p);\n  uptr beg = reinterpret_cast<uptr>(beg_p);\n  uptr end = reinterpret_cast<uptr>(end_p);\n  uptr old_mid = reinterpret_cast<uptr>(old_mid_p);\n  uptr new_mid = reinterpret_cast<uptr>(new_mid_p);\n  uptr granularity = SHADOW_GRANULARITY;\n  if (!(beg <= old_mid && beg <= new_mid && old_mid <= end && new_mid <= end &&\n        IsAligned(beg, granularity))) {\n    GET_STACK_TRACE_FATAL_HERE;\n    ReportBadParamsToAnnotateContiguousContainer(beg, end, old_mid, new_mid,\n                                                 &stack);\n  }\n  CHECK_LE(end - beg,\n           FIRST_32_SECOND_64(1UL << 30, 1UL << 34)); // Sanity check.\n\n  uptr a = RoundDownTo(Min(old_mid, new_mid), granularity);\n  uptr c = RoundUpTo(Max(old_mid, new_mid), granularity);\n  uptr d1 = RoundDownTo(old_mid, granularity);\n  // uptr d2 = RoundUpTo(old_mid, granularity);\n  // Currently we should be in this state:\n  // [a, d1) is good, [d2, c) is bad, [d1, d2) is partially good.\n  // Make a quick sanity check that we are indeed in this state.\n  //\n  // FIXME: Two of these three checks are disabled until we fix\n  // https://github.com/google/sanitizers/issues/258.\n  // if (d1 != d2)\n  //  CHECK_EQ(*(u8*)MemToShadow(d1), old_mid - d1);\n  if (a + granularity <= d1)\n    CHECK_EQ(*(u8*)MemToShadow(a), 0);\n  // if (d2 + granularity <= c && c <= end)\n  //   CHECK_EQ(*(u8 *)MemToShadow(c - granularity),\n  //            kAsanContiguousContainerOOBMagic);\n\n  uptr b1 = RoundDownTo(new_mid, granularity);\n  uptr b2 = RoundUpTo(new_mid, granularity);\n  // New state:\n  // [a, b1) is good, [b2, c) is bad, [b1, b2) is partially good.\n  PoisonShadow(a, b1 - a, 0);\n  PoisonShadow(b2, c - b2, kAsanContiguousContainerOOBMagic);\n  if (b1 != b2) {\n    CHECK_EQ(b2 - b1, granularity);\n    *(u8*)MemToShadow(b1) = static_cast<u8>(new_mid - b1);\n  }\n}\n\nconst void *__sanitizer_contiguous_container_find_bad_address(\n    const void *beg_p, const void *mid_p, const void *end_p) {\n  if (!flags()->detect_container_overflow)\n    return nullptr;\n  uptr beg = reinterpret_cast<uptr>(beg_p);\n  uptr end = reinterpret_cast<uptr>(end_p);\n  uptr mid = reinterpret_cast<uptr>(mid_p);\n  CHECK_LE(beg, mid);\n  CHECK_LE(mid, end);\n  // Check some bytes starting from beg, some bytes around mid, and some bytes\n  // ending with end.\n  uptr kMaxRangeToCheck = 32;\n  uptr r1_beg = beg;\n  uptr r1_end = Min(end + kMaxRangeToCheck, mid);\n  uptr r2_beg = Max(beg, mid - kMaxRangeToCheck);\n  uptr r2_end = Min(end, mid + kMaxRangeToCheck);\n  uptr r3_beg = Max(end - kMaxRangeToCheck, mid);\n  uptr r3_end = end;\n  for (uptr i = r1_beg; i < r1_end; i++)\n    if (AddressIsPoisoned(i))\n      return reinterpret_cast<const void *>(i);\n  for (uptr i = r2_beg; i < mid; i++)\n    if (AddressIsPoisoned(i))\n      return reinterpret_cast<const void *>(i);\n  for (uptr i = mid; i < r2_end; i++)\n    if (!AddressIsPoisoned(i))\n      return reinterpret_cast<const void *>(i);\n  for (uptr i = r3_beg; i < r3_end; i++)\n    if (!AddressIsPoisoned(i))\n      return reinterpret_cast<const void *>(i);\n  return nullptr;\n}\n\nint __sanitizer_verify_contiguous_container(const void *beg_p,\n                                            const void *mid_p,\n                                            const void *end_p) {\n  return __sanitizer_contiguous_container_find_bad_address(beg_p, mid_p,\n                                                           end_p) == nullptr;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nvoid __asan_poison_intra_object_redzone(uptr ptr, uptr size) {\n  AsanPoisonOrUnpoisonIntraObjectRedzone(ptr, size, true);\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nvoid __asan_unpoison_intra_object_redzone(uptr ptr, uptr size) {\n  AsanPoisonOrUnpoisonIntraObjectRedzone(ptr, size, false);\n}\n\n// --- Implementation of LSan-specific functions --- {{{1\nnamespace __lsan {\nbool WordIsPoisoned(uptr addr) {\n  return (__asan_region_is_poisoned(addr, sizeof(uptr)) != 0);\n}\n}\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_poisoning.h",
    "content": "//===-- asan_poisoning.h ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Shadow memory poisoning by ASan RTL and by user application.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_interceptors.h\"\n#include \"asan_internal.h\"\n#include \"asan_mapping.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n\nnamespace __asan {\n\n// Enable/disable memory poisoning.\nvoid SetCanPoisonMemory(bool value);\nbool CanPoisonMemory();\n\n// Poisons the shadow memory for \"size\" bytes starting from \"addr\".\nvoid PoisonShadow(uptr addr, uptr size, u8 value);\n\n// Poisons the shadow memory for \"redzone_size\" bytes starting from\n// \"addr + size\".\nvoid PoisonShadowPartialRightRedzone(uptr addr,\n                                     uptr size,\n                                     uptr redzone_size,\n                                     u8 value);\n\n// Fast versions of PoisonShadow and PoisonShadowPartialRightRedzone that\n// assume that memory addresses are properly aligned. Use in\n// performance-critical code with care.\nALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,\n                                    u8 value) {\n  DCHECK(CanPoisonMemory());\n  uptr shadow_beg = MEM_TO_SHADOW(aligned_beg);\n  uptr shadow_end = MEM_TO_SHADOW(\n      aligned_beg + aligned_size - SHADOW_GRANULARITY) + 1;\n  // FIXME: Page states are different on Windows, so using the same interface\n  // for mapping shadow and zeroing out pages doesn't \"just work\", so we should\n  // probably provide higher-level interface for these operations.\n  // For now, just memset on Windows.\n  if (value ||\n      SANITIZER_WINDOWS == 1 ||\n      shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {\n    REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);\n  } else {\n    uptr page_size = GetPageSizeCached();\n    uptr page_beg = RoundUpTo(shadow_beg, page_size);\n    uptr page_end = RoundDownTo(shadow_end, page_size);\n\n    if (page_beg >= page_end) {\n      REAL(memset)((void *)shadow_beg, 0, shadow_end - shadow_beg);\n    } else {\n      if (page_beg != shadow_beg) {\n        REAL(memset)((void *)shadow_beg, 0, page_beg - shadow_beg);\n      }\n      if (page_end != shadow_end) {\n        REAL(memset)((void *)page_end, 0, shadow_end - page_end);\n      }\n      ReserveShadowMemoryRange(page_beg, page_end - 1, nullptr);\n    }\n  }\n}\n\nALWAYS_INLINE void FastPoisonShadowPartialRightRedzone(\n    uptr aligned_addr, uptr size, uptr redzone_size, u8 value) {\n  DCHECK(CanPoisonMemory());\n  bool poison_partial = flags()->poison_partial;\n  u8 *shadow = (u8*)MEM_TO_SHADOW(aligned_addr);\n  for (uptr i = 0; i < redzone_size; i += SHADOW_GRANULARITY, shadow++) {\n    if (i + SHADOW_GRANULARITY <= size) {\n      *shadow = 0;  // fully addressable\n    } else if (i >= size) {\n      *shadow = (SHADOW_GRANULARITY == 128) ? 0xff : value;  // unaddressable\n    } else {\n      // first size-i bytes are addressable\n      *shadow = poison_partial ? static_cast<u8>(size - i) : 0;\n    }\n  }\n}\n\n// Calls __sanitizer::FlushUnneededShadowMemory() on\n// [MemToShadow(p), MemToShadow(p+size)] with proper rounding.\nvoid FlushUnneededASanShadowMemory(uptr p, uptr size);\n\n}  // namespace __asan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_posix.cc",
    "content": "//===-- asan_posix.cc -----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Posix-specific details.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_POSIX\n\n#include \"asan_internal.h\"\n#include \"asan_interceptors.h\"\n#include \"asan_mapping.h\"\n#include \"asan_report.h\"\n#include \"asan_stack.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_posix.h\"\n#include \"sanitizer_common/sanitizer_procmaps.h\"\n\n#include <pthread.h>\n#include <signal.h>\n#include <stdlib.h>\n#include <sys/time.h>\n#include <sys/resource.h>\n#include <unistd.h>\n\nnamespace __asan {\n\nvoid AsanOnDeadlySignal(int signo, void *siginfo, void *context) {\n  ScopedDeadlySignal signal_scope(GetCurrentThread());\n  int code = (int)((siginfo_t*)siginfo)->si_code;\n  // Write the first message using the bullet-proof write.\n  if (18 != internal_write(2, \"ASAN:DEADLYSIGNAL\\n\", 18)) Die();\n  SignalContext sig = SignalContext::Create(siginfo, context);\n\n  // Access at a reasonable offset above SP, or slightly below it (to account\n  // for x86_64 or PowerPC redzone, ARM push of multiple registers, etc) is\n  // probably a stack overflow.\n  bool IsStackAccess = sig.addr + 512 > sig.sp && sig.addr < sig.sp + 0xFFFF;\n\n#if __powerpc__\n  // Large stack frames can be allocated with e.g.\n  //   lis r0,-10000\n  //   stdux r1,r1,r0 # store sp to [sp-10000] and update sp by -10000\n  // If the store faults then sp will not have been updated, so test above\n  // will not work, becase the fault address will be more than just \"slightly\"\n  // below sp.\n  if (!IsStackAccess && IsAccessibleMemoryRange(sig.pc, 4)) {\n    u32 inst = *(unsigned *)sig.pc;\n    u32 ra = (inst >> 16) & 0x1F;\n    u32 opcd = inst >> 26;\n    u32 xo = (inst >> 1) & 0x3FF;\n    // Check for store-with-update to sp. The instructions we accept are:\n    //   stbu rs,d(ra)          stbux rs,ra,rb\n    //   sthu rs,d(ra)          sthux rs,ra,rb\n    //   stwu rs,d(ra)          stwux rs,ra,rb\n    //   stdu rs,ds(ra)         stdux rs,ra,rb\n    // where ra is r1 (the stack pointer).\n    if (ra == 1 &&\n        (opcd == 39 || opcd == 45 || opcd == 37 || opcd == 62 ||\n         (opcd == 31 && (xo == 247 || xo == 439 || xo == 183 || xo == 181))))\n      IsStackAccess = true;\n  }\n#endif // __powerpc__\n\n  // We also check si_code to filter out SEGV caused by something else other\n  // then hitting the guard page or unmapped memory, like, for example,\n  // unaligned memory access.\n  if (IsStackAccess && (code == si_SEGV_MAPERR || code == si_SEGV_ACCERR))\n    ReportStackOverflow(sig);\n  else if (signo == SIGFPE)\n    ReportDeadlySignal(\"FPE\", sig);\n  else if (signo == SIGILL)\n    ReportDeadlySignal(\"ILL\", sig);\n  else\n    ReportDeadlySignal(\"SEGV\", sig);\n}\n\n// ---------------------- TSD ---------------- {{{1\n\nstatic pthread_key_t tsd_key;\nstatic bool tsd_key_inited = false;\nvoid AsanTSDInit(void (*destructor)(void *tsd)) {\n  CHECK(!tsd_key_inited);\n  tsd_key_inited = true;\n  CHECK_EQ(0, pthread_key_create(&tsd_key, destructor));\n}\n\nvoid *AsanTSDGet() {\n  CHECK(tsd_key_inited);\n  return pthread_getspecific(tsd_key);\n}\n\nvoid AsanTSDSet(void *tsd) {\n  CHECK(tsd_key_inited);\n  pthread_setspecific(tsd_key, tsd);\n}\n\nvoid PlatformTSDDtor(void *tsd) {\n  AsanThreadContext *context = (AsanThreadContext*)tsd;\n  if (context->destructor_iterations > 1) {\n    context->destructor_iterations--;\n    CHECK_EQ(0, pthread_setspecific(tsd_key, tsd));\n    return;\n  }\n  AsanThread::TSDDtor(tsd);\n}\n}  // namespace __asan\n\n#endif  // SANITIZER_POSIX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_preinit.cc",
    "content": "//===-- asan_preinit.cc ---------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Call __asan_init at the very early stage of process startup.\n//===----------------------------------------------------------------------===//\n#include \"asan_internal.h\"\n\nusing namespace __asan;\n\n#if SANITIZER_CAN_USE_PREINIT_ARRAY\n  // The symbol is called __local_asan_preinit, because it's not intended to be\n  // exported.\n  // This code linked into the main executable when -fsanitize=address is in\n  // the link flags. It can only use exported interface functions.\n  __attribute__((section(\".preinit_array\"), used))\n  void (*__local_asan_preinit)(void) = __asan_init;\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_report.cc",
    "content": "//===-- asan_report.cc ----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// This file contains error reporting code.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_flags.h\"\n#include \"asan_internal.h\"\n#include \"asan_mapping.h\"\n#include \"asan_report.h\"\n#include \"asan_stack.h\"\n#include \"asan_thread.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_report_decorator.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n#include \"sanitizer_common/sanitizer_symbolizer.h\"\n\nnamespace __asan {\n\n// -------------------- User-specified callbacks ----------------- {{{1\nstatic void (*error_report_callback)(const char*);\nstatic char *error_message_buffer = nullptr;\nstatic uptr error_message_buffer_pos = 0;\nstatic BlockingMutex error_message_buf_mutex(LINKER_INITIALIZED);\nstatic const unsigned kAsanBuggyPcPoolSize = 25;\nstatic __sanitizer::atomic_uintptr_t AsanBuggyPcPool[kAsanBuggyPcPoolSize];\n\nstruct ReportData {\n  uptr pc;\n  uptr sp;\n  uptr bp;\n  uptr addr;\n  bool is_write;\n  uptr access_size;\n  const char *description;\n};\n\nstatic bool report_happened = false;\nstatic ReportData report_data = {};\n\nvoid AppendToErrorMessageBuffer(const char *buffer) {\n  BlockingMutexLock l(&error_message_buf_mutex);\n  if (!error_message_buffer) {\n    error_message_buffer =\n      (char*)MmapOrDieQuietly(kErrorMessageBufferSize, __func__);\n    error_message_buffer_pos = 0;\n  }\n  uptr length = internal_strlen(buffer);\n  RAW_CHECK(kErrorMessageBufferSize >= error_message_buffer_pos);\n  uptr remaining = kErrorMessageBufferSize - error_message_buffer_pos;\n  internal_strncpy(error_message_buffer + error_message_buffer_pos,\n                   buffer, remaining);\n  error_message_buffer[kErrorMessageBufferSize - 1] = '\\0';\n  // FIXME: reallocate the buffer instead of truncating the message.\n  error_message_buffer_pos += Min(remaining, length);\n}\n\n// ---------------------- Decorator ------------------------------ {{{1\nclass Decorator: public __sanitizer::SanitizerCommonDecorator {\n public:\n  Decorator() : SanitizerCommonDecorator() { }\n  const char *Access()     { return Blue(); }\n  const char *EndAccess()  { return Default(); }\n  const char *Location()   { return Green(); }\n  const char *EndLocation() { return Default(); }\n  const char *Allocation()  { return Magenta(); }\n  const char *EndAllocation()  { return Default(); }\n\n  const char *ShadowByte(u8 byte) {\n    switch (byte) {\n      case kAsanHeapLeftRedzoneMagic:\n      case kAsanHeapRightRedzoneMagic:\n      case kAsanArrayCookieMagic:\n        return Red();\n      case kAsanHeapFreeMagic:\n        return Magenta();\n      case kAsanStackLeftRedzoneMagic:\n      case kAsanStackMidRedzoneMagic:\n      case kAsanStackRightRedzoneMagic:\n      case kAsanStackPartialRedzoneMagic:\n        return Red();\n      case kAsanStackAfterReturnMagic:\n        return Magenta();\n      case kAsanInitializationOrderMagic:\n        return Cyan();\n      case kAsanUserPoisonedMemoryMagic:\n      case kAsanContiguousContainerOOBMagic:\n      case kAsanAllocaLeftMagic:\n      case kAsanAllocaRightMagic:\n        return Blue();\n      case kAsanStackUseAfterScopeMagic:\n        return Magenta();\n      case kAsanGlobalRedzoneMagic:\n        return Red();\n      case kAsanInternalHeapMagic:\n        return Yellow();\n      case kAsanIntraObjectRedzone:\n        return Yellow();\n      default:\n        return Default();\n    }\n  }\n  const char *EndShadowByte() { return Default(); }\n  const char *MemoryByte() { return Magenta(); }\n  const char *EndMemoryByte() { return Default(); }\n};\n\n// ---------------------- Helper functions ----------------------- {{{1\n\nstatic void PrintMemoryByte(InternalScopedString *str, const char *before,\n    u8 byte, bool in_shadow, const char *after = \"\\n\") {\n  Decorator d;\n  str->append(\"%s%s%x%x%s%s\", before,\n              in_shadow ? d.ShadowByte(byte) : d.MemoryByte(),\n              byte >> 4, byte & 15,\n              in_shadow ? d.EndShadowByte() : d.EndMemoryByte(), after);\n}\n\nstatic void PrintShadowByte(InternalScopedString *str, const char *before,\n    u8 byte, const char *after = \"\\n\") {\n  PrintMemoryByte(str, before, byte, /*in_shadow*/true, after);\n}\n\nstatic void PrintShadowBytes(InternalScopedString *str, const char *before,\n                             u8 *bytes, u8 *guilty, uptr n) {\n  Decorator d;\n  if (before) str->append(\"%s%p:\", before, bytes);\n  for (uptr i = 0; i < n; i++) {\n    u8 *p = bytes + i;\n    const char *before =\n        p == guilty ? \"[\" : (p - 1 == guilty && i != 0) ? \"\" : \" \";\n    const char *after = p == guilty ? \"]\" : \"\";\n    PrintShadowByte(str, before, *p, after);\n  }\n  str->append(\"\\n\");\n}\n\nstatic void PrintLegend(InternalScopedString *str) {\n  str->append(\n      \"Shadow byte legend (one shadow byte represents %d \"\n      \"application bytes):\\n\",\n      (int)SHADOW_GRANULARITY);\n  PrintShadowByte(str, \"  Addressable:           \", 0);\n  str->append(\"  Partially addressable: \");\n  for (u8 i = 1; i < SHADOW_GRANULARITY; i++) PrintShadowByte(str, \"\", i, \" \");\n  str->append(\"\\n\");\n  PrintShadowByte(str, \"  Heap left redzone:       \",\n                  kAsanHeapLeftRedzoneMagic);\n  PrintShadowByte(str, \"  Heap right redzone:      \",\n                  kAsanHeapRightRedzoneMagic);\n  PrintShadowByte(str, \"  Freed heap region:       \", kAsanHeapFreeMagic);\n  PrintShadowByte(str, \"  Stack left redzone:      \",\n                  kAsanStackLeftRedzoneMagic);\n  PrintShadowByte(str, \"  Stack mid redzone:       \",\n                  kAsanStackMidRedzoneMagic);\n  PrintShadowByte(str, \"  Stack right redzone:     \",\n                  kAsanStackRightRedzoneMagic);\n  PrintShadowByte(str, \"  Stack partial redzone:   \",\n                  kAsanStackPartialRedzoneMagic);\n  PrintShadowByte(str, \"  Stack after return:      \",\n                  kAsanStackAfterReturnMagic);\n  PrintShadowByte(str, \"  Stack use after scope:   \",\n                  kAsanStackUseAfterScopeMagic);\n  PrintShadowByte(str, \"  Global redzone:          \", kAsanGlobalRedzoneMagic);\n  PrintShadowByte(str, \"  Global init order:       \",\n                  kAsanInitializationOrderMagic);\n  PrintShadowByte(str, \"  Poisoned by user:        \",\n                  kAsanUserPoisonedMemoryMagic);\n  PrintShadowByte(str, \"  Container overflow:      \",\n                  kAsanContiguousContainerOOBMagic);\n  PrintShadowByte(str, \"  Array cookie:            \",\n                  kAsanArrayCookieMagic);\n  PrintShadowByte(str, \"  Intra object redzone:    \",\n                  kAsanIntraObjectRedzone);\n  PrintShadowByte(str, \"  ASan internal:           \", kAsanInternalHeapMagic);\n  PrintShadowByte(str, \"  Left alloca redzone:     \", kAsanAllocaLeftMagic);\n  PrintShadowByte(str, \"  Right alloca redzone:    \", kAsanAllocaRightMagic);\n}\n\nvoid MaybeDumpInstructionBytes(uptr pc) {\n  if (!flags()->dump_instruction_bytes || (pc < GetPageSizeCached()))\n    return;\n  InternalScopedString str(1024);\n  str.append(\"First 16 instruction bytes at pc: \");\n  if (IsAccessibleMemoryRange(pc, 16)) {\n    for (int i = 0; i < 16; ++i) {\n      PrintMemoryByte(&str, \"\", ((u8 *)pc)[i], /*in_shadow*/false, \" \");\n    }\n    str.append(\"\\n\");\n  } else {\n    str.append(\"unaccessible\\n\");\n  }\n  Report(\"%s\", str.data());\n}\n\nstatic void PrintShadowMemoryForAddress(uptr addr) {\n  if (!AddrIsInMem(addr)) return;\n  uptr shadow_addr = MemToShadow(addr);\n  const uptr n_bytes_per_row = 16;\n  uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1);\n  InternalScopedString str(4096 * 8);\n  str.append(\"Shadow bytes around the buggy address:\\n\");\n  for (int i = -5; i <= 5; i++) {\n    const char *prefix = (i == 0) ? \"=>\" : \"  \";\n    PrintShadowBytes(&str, prefix, (u8 *)(aligned_shadow + i * n_bytes_per_row),\n                     (u8 *)shadow_addr, n_bytes_per_row);\n  }\n  if (flags()->print_legend) PrintLegend(&str);\n  Printf(\"%s\", str.data());\n}\n\nstatic void PrintZoneForPointer(uptr ptr, uptr zone_ptr,\n                                const char *zone_name) {\n  if (zone_ptr) {\n    if (zone_name) {\n      Printf(\"malloc_zone_from_ptr(%p) = %p, which is %s\\n\",\n                 ptr, zone_ptr, zone_name);\n    } else {\n      Printf(\"malloc_zone_from_ptr(%p) = %p, which doesn't have a name\\n\",\n                 ptr, zone_ptr);\n    }\n  } else {\n    Printf(\"malloc_zone_from_ptr(%p) = 0\\n\", ptr);\n  }\n}\n\nstatic void DescribeThread(AsanThread *t) {\n  if (t)\n    DescribeThread(t->context());\n}\n\n// ---------------------- Address Descriptions ------------------- {{{1\n\nstatic bool IsASCII(unsigned char c) {\n  return /*0x00 <= c &&*/ c <= 0x7F;\n}\n\nstatic const char *MaybeDemangleGlobalName(const char *name) {\n  // We can spoil names of globals with C linkage, so use an heuristic\n  // approach to check if the name should be demangled.\n  bool should_demangle = false;\n  if (name[0] == '_' && name[1] == 'Z')\n    should_demangle = true;\n  else if (SANITIZER_WINDOWS && name[0] == '\\01' && name[1] == '?')\n    should_demangle = true;\n\n  return should_demangle ? Symbolizer::GetOrInit()->Demangle(name) : name;\n}\n\n// Check if the global is a zero-terminated ASCII string. If so, print it.\nstatic void PrintGlobalNameIfASCII(InternalScopedString *str,\n                                   const __asan_global &g) {\n  for (uptr p = g.beg; p < g.beg + g.size - 1; p++) {\n    unsigned char c = *(unsigned char*)p;\n    if (c == '\\0' || !IsASCII(c)) return;\n  }\n  if (*(char*)(g.beg + g.size - 1) != '\\0') return;\n  str->append(\"  '%s' is ascii string '%s'\\n\", MaybeDemangleGlobalName(g.name),\n              (char *)g.beg);\n}\n\nstatic const char *GlobalFilename(const __asan_global &g) {\n  const char *res = g.module_name;\n  // Prefer the filename from source location, if is available.\n  if (g.location)\n    res = g.location->filename;\n  CHECK(res);\n  return res;\n}\n\nstatic void PrintGlobalLocation(InternalScopedString *str,\n                                const __asan_global &g) {\n  str->append(\"%s\", GlobalFilename(g));\n  if (!g.location)\n    return;\n  if (g.location->line_no)\n    str->append(\":%d\", g.location->line_no);\n  if (g.location->column_no)\n    str->append(\":%d\", g.location->column_no);\n}\n\nstatic void DescribeAddressRelativeToGlobal(uptr addr, uptr size,\n                                            const __asan_global &g) {\n  InternalScopedString str(4096);\n  Decorator d;\n  str.append(\"%s\", d.Location());\n  if (addr < g.beg) {\n    str.append(\"%p is located %zd bytes to the left\", (void *)addr,\n               g.beg - addr);\n  } else if (addr + size > g.beg + g.size) {\n    if (addr < g.beg + g.size)\n      addr = g.beg + g.size;\n    str.append(\"%p is located %zd bytes to the right\", (void *)addr,\n               addr - (g.beg + g.size));\n  } else {\n    // Can it happen?\n    str.append(\"%p is located %zd bytes inside\", (void *)addr, addr - g.beg);\n  }\n  str.append(\" of global variable '%s' defined in '\",\n             MaybeDemangleGlobalName(g.name));\n  PrintGlobalLocation(&str, g);\n  str.append(\"' (0x%zx) of size %zu\\n\", g.beg, g.size);\n  str.append(\"%s\", d.EndLocation());\n  PrintGlobalNameIfASCII(&str, g);\n  Printf(\"%s\", str.data());\n}\n\nstatic bool DescribeAddressIfGlobal(uptr addr, uptr size,\n                                    const char *bug_type) {\n  // Assume address is close to at most four globals.\n  const int kMaxGlobalsInReport = 4;\n  __asan_global globals[kMaxGlobalsInReport];\n  u32 reg_sites[kMaxGlobalsInReport];\n  int globals_num =\n      GetGlobalsForAddress(addr, globals, reg_sites, ARRAY_SIZE(globals));\n  if (globals_num == 0)\n    return false;\n  for (int i = 0; i < globals_num; i++) {\n    DescribeAddressRelativeToGlobal(addr, size, globals[i]);\n    if (0 == internal_strcmp(bug_type, \"initialization-order-fiasco\") &&\n        reg_sites[i]) {\n      Printf(\"  registered at:\\n\");\n      StackDepotGet(reg_sites[i]).Print();\n    }\n  }\n  return true;\n}\n\nbool DescribeAddressIfShadow(uptr addr, AddressDescription *descr, bool print) {\n  if (AddrIsInMem(addr))\n    return false;\n  const char *area_type = nullptr;\n  if (AddrIsInShadowGap(addr)) area_type = \"shadow gap\";\n  else if (AddrIsInHighShadow(addr)) area_type = \"high shadow\";\n  else if (AddrIsInLowShadow(addr)) area_type = \"low shadow\";\n  if (area_type != nullptr) {\n    if (print) {\n      Printf(\"Address %p is located in the %s area.\\n\", addr, area_type);\n    } else {\n      CHECK(descr);\n      descr->region_kind = area_type;\n    }\n    return true;\n  }\n  CHECK(0 && \"Address is not in memory and not in shadow?\");\n  return false;\n}\n\n// Return \" (thread_name) \" or an empty string if the name is empty.\nconst char *ThreadNameWithParenthesis(AsanThreadContext *t, char buff[],\n                                      uptr buff_len) {\n  const char *name = t->name;\n  if (name[0] == '\\0') return \"\";\n  buff[0] = 0;\n  internal_strncat(buff, \" (\", 3);\n  internal_strncat(buff, name, buff_len - 4);\n  internal_strncat(buff, \")\", 2);\n  return buff;\n}\n\nconst char *ThreadNameWithParenthesis(u32 tid, char buff[],\n                                      uptr buff_len) {\n  if (tid == kInvalidTid) return \"\";\n  asanThreadRegistry().CheckLocked();\n  AsanThreadContext *t = GetThreadContextByTidLocked(tid);\n  return ThreadNameWithParenthesis(t, buff, buff_len);\n}\n\nstatic void PrintAccessAndVarIntersection(const StackVarDescr &var, uptr addr,\n                                          uptr access_size, uptr prev_var_end,\n                                          uptr next_var_beg) {\n  uptr var_end = var.beg + var.size;\n  uptr addr_end = addr + access_size;\n  const char *pos_descr = nullptr;\n  // If the variable [var.beg, var_end) is the nearest variable to the\n  // current memory access, indicate it in the log.\n  if (addr >= var.beg) {\n    if (addr_end <= var_end)\n      pos_descr = \"is inside\";  // May happen if this is a use-after-return.\n    else if (addr < var_end)\n      pos_descr = \"partially overflows\";\n    else if (addr_end <= next_var_beg &&\n             next_var_beg - addr_end >= addr - var_end)\n      pos_descr = \"overflows\";\n  } else {\n    if (addr_end > var.beg)\n      pos_descr = \"partially underflows\";\n    else if (addr >= prev_var_end &&\n             addr - prev_var_end >= var.beg - addr_end)\n      pos_descr = \"underflows\";\n  }\n  InternalScopedString str(1024);\n  str.append(\"    [%zd, %zd)\", var.beg, var_end);\n  // Render variable name.\n  str.append(\" '\");\n  for (uptr i = 0; i < var.name_len; ++i) {\n    str.append(\"%c\", var.name_pos[i]);\n  }\n  str.append(\"'\");\n  if (pos_descr) {\n    Decorator d;\n    // FIXME: we may want to also print the size of the access here,\n    // but in case of accesses generated by memset it may be confusing.\n    str.append(\"%s <== Memory access at offset %zd %s this variable%s\\n\",\n               d.Location(), addr, pos_descr, d.EndLocation());\n  } else {\n    str.append(\"\\n\");\n  }\n  Printf(\"%s\", str.data());\n}\n\nbool ParseFrameDescription(const char *frame_descr,\n                           InternalMmapVector<StackVarDescr> *vars) {\n  CHECK(frame_descr);\n  char *p;\n  // This string is created by the compiler and has the following form:\n  // \"n alloc_1 alloc_2 ... alloc_n\"\n  // where alloc_i looks like \"offset size len ObjectName\".\n  uptr n_objects = (uptr)internal_simple_strtoll(frame_descr, &p, 10);\n  if (n_objects == 0)\n    return false;\n\n  for (uptr i = 0; i < n_objects; i++) {\n    uptr beg  = (uptr)internal_simple_strtoll(p, &p, 10);\n    uptr size = (uptr)internal_simple_strtoll(p, &p, 10);\n    uptr len  = (uptr)internal_simple_strtoll(p, &p, 10);\n    if (beg == 0 || size == 0 || *p != ' ') {\n      return false;\n    }\n    p++;\n    StackVarDescr var = {beg, size, p, len};\n    vars->push_back(var);\n    p += len;\n  }\n\n  return true;\n}\n\nbool DescribeAddressIfStack(uptr addr, uptr access_size) {\n  AsanThread *t = FindThreadByStackAddress(addr);\n  if (!t) return false;\n\n  Decorator d;\n  char tname[128];\n  Printf(\"%s\", d.Location());\n  Printf(\"Address %p is located in stack of thread T%d%s\", addr, t->tid(),\n         ThreadNameWithParenthesis(t->tid(), tname, sizeof(tname)));\n\n  // Try to fetch precise stack frame for this access.\n  AsanThread::StackFrameAccess access;\n  if (!t->GetStackFrameAccessByAddr(addr, &access)) {\n    Printf(\"%s\\n\", d.EndLocation());\n    return true;\n  }\n  Printf(\" at offset %zu in frame%s\\n\", access.offset, d.EndLocation());\n\n  // Now we print the frame where the alloca has happened.\n  // We print this frame as a stack trace with one element.\n  // The symbolizer may print more than one frame if inlining was involved.\n  // The frame numbers may be different than those in the stack trace printed\n  // previously. That's unfortunate, but I have no better solution,\n  // especially given that the alloca may be from entirely different place\n  // (e.g. use-after-scope, or different thread's stack).\n#if defined(__powerpc64__) && defined(__BIG_ENDIAN__)\n  // On PowerPC64 ELFv1, the address of a function actually points to a\n  // three-doubleword data structure with the first field containing\n  // the address of the function's code.\n  access.frame_pc = *reinterpret_cast<uptr *>(access.frame_pc);\n#endif\n  access.frame_pc += 16;\n  Printf(\"%s\", d.EndLocation());\n  StackTrace alloca_stack(&access.frame_pc, 1);\n  alloca_stack.Print();\n\n  InternalMmapVector<StackVarDescr> vars(16);\n  if (!ParseFrameDescription(access.frame_descr, &vars)) {\n    Printf(\"AddressSanitizer can't parse the stack frame \"\n           \"descriptor: |%s|\\n\", access.frame_descr);\n    // 'addr' is a stack address, so return true even if we can't parse frame\n    return true;\n  }\n  uptr n_objects = vars.size();\n  // Report the number of stack objects.\n  Printf(\"  This frame has %zu object(s):\\n\", n_objects);\n\n  // Report all objects in this frame.\n  for (uptr i = 0; i < n_objects; i++) {\n    uptr prev_var_end = i ? vars[i - 1].beg + vars[i - 1].size : 0;\n    uptr next_var_beg = i + 1 < n_objects ? vars[i + 1].beg : ~(0UL);\n    PrintAccessAndVarIntersection(vars[i], access.offset, access_size,\n                                  prev_var_end, next_var_beg);\n  }\n  Printf(\"HINT: this may be a false positive if your program uses \"\n         \"some custom stack unwind mechanism or swapcontext\\n\");\n  if (SANITIZER_WINDOWS)\n    Printf(\"      (longjmp, SEH and C++ exceptions *are* supported)\\n\");\n  else\n    Printf(\"      (longjmp and C++ exceptions *are* supported)\\n\");\n\n  DescribeThread(t);\n  return true;\n}\n\nstatic void DescribeAccessToHeapChunk(AsanChunkView chunk, uptr addr,\n                                      uptr access_size) {\n  sptr offset;\n  Decorator d;\n  InternalScopedString str(4096);\n  str.append(\"%s\", d.Location());\n  if (chunk.AddrIsAtLeft(addr, access_size, &offset)) {\n    str.append(\"%p is located %zd bytes to the left of\", (void *)addr, offset);\n  } else if (chunk.AddrIsAtRight(addr, access_size, &offset)) {\n    if (offset < 0) {\n      addr -= offset;\n      offset = 0;\n    }\n    str.append(\"%p is located %zd bytes to the right of\", (void *)addr, offset);\n  } else if (chunk.AddrIsInside(addr, access_size, &offset)) {\n    str.append(\"%p is located %zd bytes inside of\", (void*)addr, offset);\n  } else {\n    str.append(\"%p is located somewhere around (this is AddressSanitizer bug!)\",\n               (void *)addr);\n  }\n  str.append(\" %zu-byte region [%p,%p)\\n\", chunk.UsedSize(),\n             (void *)(chunk.Beg()), (void *)(chunk.End()));\n  str.append(\"%s\", d.EndLocation());\n  Printf(\"%s\", str.data());\n}\n\nvoid DescribeHeapAddress(uptr addr, uptr access_size) {\n  AsanChunkView chunk = FindHeapChunkByAddress(addr);\n  if (!chunk.IsValid()) {\n    Printf(\"AddressSanitizer can not describe address in more detail \"\n           \"(wild memory access suspected).\\n\");\n    return;\n  }\n  DescribeAccessToHeapChunk(chunk, addr, access_size);\n  CHECK(chunk.AllocTid() != kInvalidTid);\n  asanThreadRegistry().CheckLocked();\n  AsanThreadContext *alloc_thread =\n      GetThreadContextByTidLocked(chunk.AllocTid());\n  StackTrace alloc_stack = chunk.GetAllocStack();\n  char tname[128];\n  Decorator d;\n  AsanThreadContext *free_thread = nullptr;\n  if (chunk.FreeTid() != kInvalidTid) {\n    free_thread = GetThreadContextByTidLocked(chunk.FreeTid());\n    Printf(\"%sfreed by thread T%d%s here:%s\\n\", d.Allocation(),\n           free_thread->tid,\n           ThreadNameWithParenthesis(free_thread, tname, sizeof(tname)),\n           d.EndAllocation());\n    StackTrace free_stack = chunk.GetFreeStack();\n    free_stack.Print();\n    Printf(\"%spreviously allocated by thread T%d%s here:%s\\n\",\n           d.Allocation(), alloc_thread->tid,\n           ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)),\n           d.EndAllocation());\n  } else {\n    Printf(\"%sallocated by thread T%d%s here:%s\\n\", d.Allocation(),\n           alloc_thread->tid,\n           ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)),\n           d.EndAllocation());\n  }\n  alloc_stack.Print();\n  DescribeThread(GetCurrentThread());\n  if (free_thread)\n    DescribeThread(free_thread);\n  DescribeThread(alloc_thread);\n}\n\nstatic void DescribeAddress(uptr addr, uptr access_size, const char *bug_type) {\n  // Check if this is shadow or shadow gap.\n  if (DescribeAddressIfShadow(addr))\n    return;\n  CHECK(AddrIsInMem(addr));\n  if (DescribeAddressIfGlobal(addr, access_size, bug_type))\n    return;\n  if (DescribeAddressIfStack(addr, access_size))\n    return;\n  // Assume it is a heap address.\n  DescribeHeapAddress(addr, access_size);\n}\n\n// ------------------- Thread description -------------------- {{{1\n\nvoid DescribeThread(AsanThreadContext *context) {\n  CHECK(context);\n  asanThreadRegistry().CheckLocked();\n  // No need to announce the main thread.\n  if (context->tid == 0 || context->announced) {\n    return;\n  }\n  context->announced = true;\n  char tname[128];\n  InternalScopedString str(1024);\n  str.append(\"Thread T%d%s\", context->tid,\n             ThreadNameWithParenthesis(context->tid, tname, sizeof(tname)));\n  if (context->parent_tid == kInvalidTid) {\n    str.append(\" created by unknown thread\\n\");\n    Printf(\"%s\", str.data());\n    return;\n  }\n  str.append(\n      \" created by T%d%s here:\\n\", context->parent_tid,\n      ThreadNameWithParenthesis(context->parent_tid, tname, sizeof(tname)));\n  Printf(\"%s\", str.data());\n  StackDepotGet(context->stack_id).Print();\n  // Recursively described parent thread if needed.\n  if (flags()->print_full_thread_history) {\n    AsanThreadContext *parent_context =\n        GetThreadContextByTidLocked(context->parent_tid);\n    DescribeThread(parent_context);\n  }\n}\n\n// -------------------- Different kinds of reports ----------------- {{{1\n\n// Use ScopedInErrorReport to run common actions just before and\n// immediately after printing error report.\nclass ScopedInErrorReport {\n public:\n  explicit ScopedInErrorReport(ReportData *report = nullptr,\n                               bool fatal = false) {\n    halt_on_error_ = fatal || flags()->halt_on_error;\n\n    if (lock_.TryLock()) {\n      StartReporting(report);\n      return;\n    }\n\n    // ASan found two bugs in different threads simultaneously.\n\n    u32 current_tid = GetCurrentTidOrInvalid();\n    if (reporting_thread_tid_ == current_tid ||\n        reporting_thread_tid_ == kInvalidTid) {\n      // This is either asynch signal or nested error during error reporting.\n      // Fail simple to avoid deadlocks in Report().\n\n      // Can't use Report() here because of potential deadlocks\n      // in nested signal handlers.\n      const char msg[] = \"AddressSanitizer: nested bug in the same thread, \"\n                         \"aborting.\\n\";\n      WriteToFile(kStderrFd, msg, sizeof(msg));\n\n      internal__exit(common_flags()->exitcode);\n    }\n\n    if (halt_on_error_) {\n      // Do not print more than one report, otherwise they will mix up.\n      // Error reporting functions shouldn't return at this situation, as\n      // they are effectively no-returns.\n\n      Report(\"AddressSanitizer: while reporting a bug found another one. \"\n             \"Ignoring.\\n\");\n\n      // Sleep long enough to make sure that the thread which started\n      // to print an error report will finish doing it.\n      SleepForSeconds(Max(100, flags()->sleep_before_dying + 1));\n\n      // If we're still not dead for some reason, use raw _exit() instead of\n      // Die() to bypass any additional checks.\n      internal__exit(common_flags()->exitcode);\n    } else {\n      // The other thread will eventually finish reporting\n      // so it's safe to wait\n      lock_.Lock();\n    }\n\n    StartReporting(report);\n  }\n\n  ~ScopedInErrorReport() {\n    // Make sure the current thread is announced.\n    DescribeThread(GetCurrentThread());\n    // We may want to grab this lock again when printing stats.\n    asanThreadRegistry().Unlock();\n    // Print memory stats.\n    if (flags()->print_stats)\n      __asan_print_accumulated_stats();\n\n    // Copy the message buffer so that we could start logging without holding a\n    // lock that gets aquired during printing.\n    InternalScopedBuffer<char> buffer_copy(kErrorMessageBufferSize);\n    {\n      BlockingMutexLock l(&error_message_buf_mutex);\n      internal_memcpy(buffer_copy.data(),\n                      error_message_buffer, kErrorMessageBufferSize);\n    }\n\n    // Remove color sequences since logs cannot print them.\n    RemoveANSIEscapeSequencesFromString(buffer_copy.data());\n\n    LogFullErrorReport(buffer_copy.data());\n\n    if (error_report_callback) {\n      error_report_callback(buffer_copy.data());\n    }\n    CommonSanitizerReportMutex.Unlock();\n    reporting_thread_tid_ = kInvalidTid;\n    lock_.Unlock();\n    if (halt_on_error_) {\n      Report(\"ABORTING\\n\");\n      Die();\n    }\n  }\n\n private:\n  void StartReporting(ReportData *report) {\n    if (report) report_data = *report;\n    report_happened = true;\n    ASAN_ON_ERROR();\n    // Make sure the registry and sanitizer report mutexes are locked while\n    // we're printing an error report.\n    // We can lock them only here to avoid self-deadlock in case of\n    // recursive reports.\n    asanThreadRegistry().Lock();\n    CommonSanitizerReportMutex.Lock();\n    reporting_thread_tid_ = GetCurrentTidOrInvalid();\n    Printf(\"====================================================\"\n           \"=============\\n\");\n  }\n\n  static StaticSpinMutex lock_;\n  static u32 reporting_thread_tid_;\n  bool halt_on_error_;\n};\n\nStaticSpinMutex ScopedInErrorReport::lock_;\nu32 ScopedInErrorReport::reporting_thread_tid_;\n\nvoid ReportStackOverflow(const SignalContext &sig) {\n  ScopedInErrorReport in_report;\n  Decorator d;\n  Printf(\"%s\", d.Warning());\n  Report(\n      \"ERROR: AddressSanitizer: stack-overflow on address %p\"\n      \" (pc %p bp %p sp %p T%d)\\n\",\n      (void *)sig.addr, (void *)sig.pc, (void *)sig.bp, (void *)sig.sp,\n      GetCurrentTidOrInvalid());\n  Printf(\"%s\", d.EndWarning());\n  GET_STACK_TRACE_SIGNAL(sig);\n  stack.Print();\n  ReportErrorSummary(\"stack-overflow\", &stack);\n}\n\nvoid ReportDeadlySignal(const char *description, const SignalContext &sig) {\n  ScopedInErrorReport in_report(/*report*/nullptr, /*fatal*/true);\n  Decorator d;\n  Printf(\"%s\", d.Warning());\n  Report(\n      \"ERROR: AddressSanitizer: %s on unknown address %p\"\n      \" (pc %p bp %p sp %p T%d)\\n\",\n      description, (void *)sig.addr, (void *)sig.pc, (void *)sig.bp,\n      (void *)sig.sp, GetCurrentTidOrInvalid());\n  if (sig.pc < GetPageSizeCached()) {\n    Report(\"Hint: pc points to the zero page.\\n\");\n  }\n  Printf(\"%s\", d.EndWarning());\n  GET_STACK_TRACE_SIGNAL(sig);\n  stack.Print();\n  MaybeDumpInstructionBytes(sig.pc);\n  Printf(\"AddressSanitizer can not provide additional info.\\n\");\n  ReportErrorSummary(description, &stack);\n}\n\nvoid ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack) {\n  ScopedInErrorReport in_report;\n  Decorator d;\n  Printf(\"%s\", d.Warning());\n  char tname[128];\n  u32 curr_tid = GetCurrentTidOrInvalid();\n  Report(\"ERROR: AddressSanitizer: attempting double-free on %p in \"\n         \"thread T%d%s:\\n\",\n         addr, curr_tid,\n         ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)));\n  Printf(\"%s\", d.EndWarning());\n  CHECK_GT(free_stack->size, 0);\n  GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);\n  stack.Print();\n  DescribeHeapAddress(addr, 1);\n  ReportErrorSummary(\"double-free\", &stack);\n}\n\nvoid ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,\n                                 BufferedStackTrace *free_stack) {\n  ScopedInErrorReport in_report;\n  Decorator d;\n  Printf(\"%s\", d.Warning());\n  char tname[128];\n  u32 curr_tid = GetCurrentTidOrInvalid();\n  Report(\"ERROR: AddressSanitizer: new-delete-type-mismatch on %p in \"\n         \"thread T%d%s:\\n\",\n         addr, curr_tid,\n         ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)));\n  Printf(\"%s  object passed to delete has wrong type:\\n\", d.EndWarning());\n  Printf(\"  size of the allocated type:   %zd bytes;\\n\"\n         \"  size of the deallocated type: %zd bytes.\\n\",\n         asan_mz_size(reinterpret_cast<void*>(addr)), delete_size);\n  CHECK_GT(free_stack->size, 0);\n  GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);\n  stack.Print();\n  DescribeHeapAddress(addr, 1);\n  ReportErrorSummary(\"new-delete-type-mismatch\", &stack);\n  Report(\"HINT: if you don't care about these errors you may set \"\n         \"ASAN_OPTIONS=new_delete_type_mismatch=0\\n\");\n}\n\nvoid ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack) {\n  ScopedInErrorReport in_report;\n  Decorator d;\n  Printf(\"%s\", d.Warning());\n  char tname[128];\n  u32 curr_tid = GetCurrentTidOrInvalid();\n  Report(\"ERROR: AddressSanitizer: attempting free on address \"\n             \"which was not malloc()-ed: %p in thread T%d%s\\n\", addr,\n         curr_tid, ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)));\n  Printf(\"%s\", d.EndWarning());\n  CHECK_GT(free_stack->size, 0);\n  GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);\n  stack.Print();\n  DescribeHeapAddress(addr, 1);\n  ReportErrorSummary(\"bad-free\", &stack);\n}\n\nvoid ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,\n                             AllocType alloc_type,\n                             AllocType dealloc_type) {\n  static const char *alloc_names[] =\n    {\"INVALID\", \"malloc\", \"operator new\", \"operator new []\"};\n  static const char *dealloc_names[] =\n    {\"INVALID\", \"free\", \"operator delete\", \"operator delete []\"};\n  CHECK_NE(alloc_type, dealloc_type);\n  ScopedInErrorReport in_report;\n  Decorator d;\n  Printf(\"%s\", d.Warning());\n  Report(\"ERROR: AddressSanitizer: alloc-dealloc-mismatch (%s vs %s) on %p\\n\",\n        alloc_names[alloc_type], dealloc_names[dealloc_type], addr);\n  Printf(\"%s\", d.EndWarning());\n  CHECK_GT(free_stack->size, 0);\n  GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);\n  stack.Print();\n  DescribeHeapAddress(addr, 1);\n  ReportErrorSummary(\"alloc-dealloc-mismatch\", &stack);\n  Report(\"HINT: if you don't care about these errors you may set \"\n         \"ASAN_OPTIONS=alloc_dealloc_mismatch=0\\n\");\n}\n\nvoid ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack) {\n  ScopedInErrorReport in_report;\n  Decorator d;\n  Printf(\"%s\", d.Warning());\n  Report(\"ERROR: AddressSanitizer: attempting to call \"\n             \"malloc_usable_size() for pointer which is \"\n             \"not owned: %p\\n\", addr);\n  Printf(\"%s\", d.EndWarning());\n  stack->Print();\n  DescribeHeapAddress(addr, 1);\n  ReportErrorSummary(\"bad-malloc_usable_size\", stack);\n}\n\nvoid ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,\n                                             BufferedStackTrace *stack) {\n  ScopedInErrorReport in_report;\n  Decorator d;\n  Printf(\"%s\", d.Warning());\n  Report(\"ERROR: AddressSanitizer: attempting to call \"\n             \"__sanitizer_get_allocated_size() for pointer which is \"\n             \"not owned: %p\\n\", addr);\n  Printf(\"%s\", d.EndWarning());\n  stack->Print();\n  DescribeHeapAddress(addr, 1);\n  ReportErrorSummary(\"bad-__sanitizer_get_allocated_size\", stack);\n}\n\nvoid ReportStringFunctionMemoryRangesOverlap(const char *function,\n                                             const char *offset1, uptr length1,\n                                             const char *offset2, uptr length2,\n                                             BufferedStackTrace *stack) {\n  ScopedInErrorReport in_report;\n  Decorator d;\n  char bug_type[100];\n  internal_snprintf(bug_type, sizeof(bug_type), \"%s-param-overlap\", function);\n  Printf(\"%s\", d.Warning());\n  Report(\"ERROR: AddressSanitizer: %s: \"\n             \"memory ranges [%p,%p) and [%p, %p) overlap\\n\", \\\n             bug_type, offset1, offset1 + length1, offset2, offset2 + length2);\n  Printf(\"%s\", d.EndWarning());\n  stack->Print();\n  DescribeAddress((uptr)offset1, length1, bug_type);\n  DescribeAddress((uptr)offset2, length2, bug_type);\n  ReportErrorSummary(bug_type, stack);\n}\n\nvoid ReportStringFunctionSizeOverflow(uptr offset, uptr size,\n                                      BufferedStackTrace *stack) {\n  ScopedInErrorReport in_report;\n  Decorator d;\n  const char *bug_type = \"negative-size-param\";\n  Printf(\"%s\", d.Warning());\n  Report(\"ERROR: AddressSanitizer: %s: (size=%zd)\\n\", bug_type, size);\n  Printf(\"%s\", d.EndWarning());\n  stack->Print();\n  DescribeAddress(offset, size, bug_type);\n  ReportErrorSummary(bug_type, stack);\n}\n\nvoid ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,\n                                                  uptr old_mid, uptr new_mid,\n                                                  BufferedStackTrace *stack) {\n  ScopedInErrorReport in_report;\n  Report(\"ERROR: AddressSanitizer: bad parameters to \"\n         \"__sanitizer_annotate_contiguous_container:\\n\"\n         \"      beg     : %p\\n\"\n         \"      end     : %p\\n\"\n         \"      old_mid : %p\\n\"\n         \"      new_mid : %p\\n\",\n         beg, end, old_mid, new_mid);\n  uptr granularity = SHADOW_GRANULARITY;\n  if (!IsAligned(beg, granularity))\n    Report(\"ERROR: beg is not aligned by %d\\n\", granularity);\n  stack->Print();\n  ReportErrorSummary(\"bad-__sanitizer_annotate_contiguous_container\", stack);\n}\n\nvoid ReportODRViolation(const __asan_global *g1, u32 stack_id1,\n                        const __asan_global *g2, u32 stack_id2) {\n  ScopedInErrorReport in_report;\n  Decorator d;\n  Printf(\"%s\", d.Warning());\n  Report(\"ERROR: AddressSanitizer: odr-violation (%p):\\n\", g1->beg);\n  Printf(\"%s\", d.EndWarning());\n  InternalScopedString g1_loc(256), g2_loc(256);\n  PrintGlobalLocation(&g1_loc, *g1);\n  PrintGlobalLocation(&g2_loc, *g2);\n  Printf(\"  [1] size=%zd '%s' %s\\n\", g1->size,\n         MaybeDemangleGlobalName(g1->name), g1_loc.data());\n  Printf(\"  [2] size=%zd '%s' %s\\n\", g2->size,\n         MaybeDemangleGlobalName(g2->name), g2_loc.data());\n  if (stack_id1 && stack_id2) {\n    Printf(\"These globals were registered at these points:\\n\");\n    Printf(\"  [1]:\\n\");\n    StackDepotGet(stack_id1).Print();\n    Printf(\"  [2]:\\n\");\n    StackDepotGet(stack_id2).Print();\n  }\n  Report(\"HINT: if you don't care about these errors you may set \"\n         \"ASAN_OPTIONS=detect_odr_violation=0\\n\");\n  InternalScopedString error_msg(256);\n  error_msg.append(\"odr-violation: global '%s' at %s\",\n                   MaybeDemangleGlobalName(g1->name), g1_loc.data());\n  ReportErrorSummary(error_msg.data());\n}\n\n// ----------------------- CheckForInvalidPointerPair ----------- {{{1\nstatic NOINLINE void\nReportInvalidPointerPair(uptr pc, uptr bp, uptr sp, uptr a1, uptr a2) {\n  ScopedInErrorReport in_report;\n  const char *bug_type = \"invalid-pointer-pair\";\n  Decorator d;\n  Printf(\"%s\", d.Warning());\n  Report(\"ERROR: AddressSanitizer: invalid-pointer-pair: %p %p\\n\", a1, a2);\n  Printf(\"%s\", d.EndWarning());\n  GET_STACK_TRACE_FATAL(pc, bp);\n  stack.Print();\n  DescribeAddress(a1, 1, bug_type);\n  DescribeAddress(a2, 1, bug_type);\n  ReportErrorSummary(bug_type, &stack);\n}\n\nstatic INLINE void CheckForInvalidPointerPair(void *p1, void *p2) {\n  if (!flags()->detect_invalid_pointer_pairs) return;\n  uptr a1 = reinterpret_cast<uptr>(p1);\n  uptr a2 = reinterpret_cast<uptr>(p2);\n  AsanChunkView chunk1 = FindHeapChunkByAddress(a1);\n  AsanChunkView chunk2 = FindHeapChunkByAddress(a2);\n  bool valid1 = chunk1.IsValid();\n  bool valid2 = chunk2.IsValid();\n  if ((valid1 != valid2) || (valid1 && valid2 && !chunk1.Eq(chunk2))) {\n    GET_CALLER_PC_BP_SP;                                              \\\n    return ReportInvalidPointerPair(pc, bp, sp, a1, a2);\n  }\n}\n// ----------------------- Mac-specific reports ----------------- {{{1\n\nvoid ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name,\n                               BufferedStackTrace *stack) {\n  ScopedInErrorReport in_report;\n  Printf(\"mz_realloc(%p) -- attempting to realloc unallocated memory.\\n\"\n             \"This is an unrecoverable problem, exiting now.\\n\",\n             addr);\n  PrintZoneForPointer(addr, zone_ptr, zone_name);\n  stack->Print();\n  DescribeHeapAddress(addr, 1);\n}\n\n// -------------- SuppressErrorReport -------------- {{{1\n// Avoid error reports duplicating for ASan recover mode.\nstatic bool SuppressErrorReport(uptr pc) {\n  if (!common_flags()->suppress_equal_pcs) return false;\n  for (unsigned i = 0; i < kAsanBuggyPcPoolSize; i++) {\n    uptr cmp = atomic_load_relaxed(&AsanBuggyPcPool[i]);\n    if (cmp == 0 && atomic_compare_exchange_strong(&AsanBuggyPcPool[i], &cmp,\n                                                   pc, memory_order_relaxed))\n      return false;\n    if (cmp == pc) return true;\n  }\n  Die();\n}\n\nvoid ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,\n                        uptr access_size, u32 exp, bool fatal) {\n  if (!fatal && SuppressErrorReport(pc)) return;\n  ENABLE_FRAME_POINTER;\n\n  // Optimization experiments.\n  // The experiments can be used to evaluate potential optimizations that remove\n  // instrumentation (assess false negatives). Instead of completely removing\n  // some instrumentation, compiler can emit special calls into runtime\n  // (e.g. __asan_report_exp_load1 instead of __asan_report_load1) and pass\n  // mask of experiments (exp).\n  // The reaction to a non-zero value of exp is to be defined.\n  (void)exp;\n\n  // Determine the error type.\n  const char *bug_descr = \"unknown-crash\";\n  if (AddrIsInMem(addr)) {\n    u8 *shadow_addr = (u8*)MemToShadow(addr);\n    // If we are accessing 16 bytes, look at the second shadow byte.\n    if (*shadow_addr == 0 && access_size > SHADOW_GRANULARITY)\n      shadow_addr++;\n    // If we are in the partial right redzone, look at the next shadow byte.\n    if (*shadow_addr > 0 && *shadow_addr < 128)\n      shadow_addr++;\n    switch (*shadow_addr) {\n      case kAsanHeapLeftRedzoneMagic:\n      case kAsanHeapRightRedzoneMagic:\n      case kAsanArrayCookieMagic:\n        bug_descr = \"heap-buffer-overflow\";\n        break;\n      case kAsanHeapFreeMagic:\n        bug_descr = \"heap-use-after-free\";\n        break;\n      case kAsanStackLeftRedzoneMagic:\n        bug_descr = \"stack-buffer-underflow\";\n        break;\n      case kAsanInitializationOrderMagic:\n        bug_descr = \"initialization-order-fiasco\";\n        break;\n      case kAsanStackMidRedzoneMagic:\n      case kAsanStackRightRedzoneMagic:\n      case kAsanStackPartialRedzoneMagic:\n        bug_descr = \"stack-buffer-overflow\";\n        break;\n      case kAsanStackAfterReturnMagic:\n        bug_descr = \"stack-use-after-return\";\n        break;\n      case kAsanUserPoisonedMemoryMagic:\n        bug_descr = \"use-after-poison\";\n        break;\n      case kAsanContiguousContainerOOBMagic:\n        bug_descr = \"container-overflow\";\n        break;\n      case kAsanStackUseAfterScopeMagic:\n        bug_descr = \"stack-use-after-scope\";\n        break;\n      case kAsanGlobalRedzoneMagic:\n        bug_descr = \"global-buffer-overflow\";\n        break;\n      case kAsanIntraObjectRedzone:\n        bug_descr = \"intra-object-overflow\";\n        break;\n      case kAsanAllocaLeftMagic:\n      case kAsanAllocaRightMagic:\n        bug_descr = \"dynamic-stack-buffer-overflow\";\n        break;\n    }\n  }\n\n  ReportData report = { pc, sp, bp, addr, (bool)is_write, access_size,\n                        bug_descr };\n  ScopedInErrorReport in_report(&report, fatal);\n\n  Decorator d;\n  Printf(\"%s\", d.Warning());\n  Report(\"ERROR: AddressSanitizer: %s on address \"\n             \"%p at pc %p bp %p sp %p\\n\",\n             bug_descr, (void*)addr, pc, bp, sp);\n  Printf(\"%s\", d.EndWarning());\n\n  u32 curr_tid = GetCurrentTidOrInvalid();\n  char tname[128];\n  Printf(\"%s%s of size %zu at %p thread T%d%s%s\\n\",\n         d.Access(),\n         access_size ? (is_write ? \"WRITE\" : \"READ\") : \"ACCESS\",\n         access_size, (void*)addr, curr_tid,\n         ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)),\n         d.EndAccess());\n\n  GET_STACK_TRACE_FATAL(pc, bp);\n  stack.Print();\n\n  DescribeAddress(addr, access_size, bug_descr);\n  ReportErrorSummary(bug_descr, &stack);\n  PrintShadowMemoryForAddress(addr);\n}\n\n}  // namespace __asan\n\n// --------------------------- Interface --------------------- {{{1\nusing namespace __asan;  // NOLINT\n\nvoid __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write,\n                         uptr access_size, u32 exp) {\n  ENABLE_FRAME_POINTER;\n  bool fatal = flags()->halt_on_error;\n  ReportGenericError(pc, bp, sp, addr, is_write, access_size, exp, fatal);\n}\n\nvoid NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) {\n  BlockingMutexLock l(&error_message_buf_mutex);\n  error_report_callback = callback;\n}\n\nvoid __asan_describe_address(uptr addr) {\n  // Thread registry must be locked while we're describing an address.\n  asanThreadRegistry().Lock();\n  DescribeAddress(addr, 1, \"\");\n  asanThreadRegistry().Unlock();\n}\n\nint __asan_report_present() {\n  return report_happened ? 1 : 0;\n}\n\nuptr __asan_get_report_pc() {\n  return report_data.pc;\n}\n\nuptr __asan_get_report_bp() {\n  return report_data.bp;\n}\n\nuptr __asan_get_report_sp() {\n  return report_data.sp;\n}\n\nuptr __asan_get_report_address() {\n  return report_data.addr;\n}\n\nint __asan_get_report_access_type() {\n  return report_data.is_write ? 1 : 0;\n}\n\nuptr __asan_get_report_access_size() {\n  return report_data.access_size;\n}\n\nconst char *__asan_get_report_description() {\n  return report_data.description;\n}\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_ptr_sub(void *a, void *b) {\n  CheckForInvalidPointerPair(a, b);\n}\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_ptr_cmp(void *a, void *b) {\n  CheckForInvalidPointerPair(a, b);\n}\n} // extern \"C\"\n\n#if !SANITIZER_SUPPORTS_WEAK_HOOKS\n// Provide default implementation of __asan_on_error that does nothing\n// and may be overriden by user.\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE NOINLINE\nvoid __asan_on_error() {}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_report.h",
    "content": "//===-- asan_report.h -------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// ASan-private header for error reporting functions.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_allocator.h\"\n#include \"asan_internal.h\"\n#include \"asan_thread.h\"\n\nnamespace __asan {\n\nstruct StackVarDescr {\n  uptr beg;\n  uptr size;\n  const char *name_pos;\n  uptr name_len;\n};\n\nstruct AddressDescription {\n  char *name;\n  uptr name_size;\n  uptr region_address;\n  uptr region_size;\n  const char *region_kind;\n};\n\n// Returns the number of globals close to the provided address and copies\n// them to \"globals\" array.\nint GetGlobalsForAddress(uptr addr, __asan_global *globals, u32 *reg_sites,\n                         int max_globals);\nbool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr);\n// The following functions prints address description depending\n// on the memory type (shadow/heap/stack/global).\nvoid DescribeHeapAddress(uptr addr, uptr access_size);\nbool DescribeAddressIfShadow(uptr addr, AddressDescription *descr = nullptr,\n                             bool print = true);\nbool ParseFrameDescription(const char *frame_descr,\n                           InternalMmapVector<StackVarDescr> *vars);\nbool DescribeAddressIfStack(uptr addr, uptr access_size);\nvoid DescribeThread(AsanThreadContext *context);\n\n// Different kinds of error reports.\nvoid ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,\n                        uptr access_size, u32 exp, bool fatal);\nvoid ReportStackOverflow(const SignalContext &sig);\nvoid ReportDeadlySignal(const char *description, const SignalContext &sig);\nvoid ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,\n                                 BufferedStackTrace *free_stack);\nvoid ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack);\nvoid ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack);\nvoid ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,\n                             AllocType alloc_type,\n                             AllocType dealloc_type);\nvoid ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack);\nvoid ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,\n                                             BufferedStackTrace *stack);\nvoid ReportStringFunctionMemoryRangesOverlap(const char *function,\n                                             const char *offset1, uptr length1,\n                                             const char *offset2, uptr length2,\n                                             BufferedStackTrace *stack);\nvoid ReportStringFunctionSizeOverflow(uptr offset, uptr size,\n                                      BufferedStackTrace *stack);\nvoid ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,\n                                                  uptr old_mid, uptr new_mid,\n                                                  BufferedStackTrace *stack);\n\nvoid ReportODRViolation(const __asan_global *g1, u32 stack_id1,\n                        const __asan_global *g2, u32 stack_id2);\n\n// Mac-specific errors and warnings.\nvoid ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr,\n                               const char *zone_name,\n                               BufferedStackTrace *stack);\nvoid ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr,\n                               const char *zone_name,\n                               BufferedStackTrace *stack);\n\n}  // namespace __asan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_rtl.cc",
    "content": "//===-- asan_rtl.cc -------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Main file of the ASan run-time library.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_activation.h\"\n#include \"asan_allocator.h\"\n#include \"asan_interceptors.h\"\n#include \"asan_interface_internal.h\"\n#include \"asan_internal.h\"\n#include \"asan_mapping.h\"\n#include \"asan_poisoning.h\"\n#include \"asan_report.h\"\n#include \"asan_stack.h\"\n#include \"asan_stats.h\"\n#include \"asan_suppressions.h\"\n#include \"asan_thread.h\"\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_symbolizer.h\"\n#include \"lsan/lsan_common.h\"\n#include \"ubsan/ubsan_init.h\"\n#include \"ubsan/ubsan_platform.h\"\n\nint __asan_option_detect_stack_use_after_return;  // Global interface symbol.\nuptr *__asan_test_only_reported_buggy_pointer;  // Used only for testing asan.\n\nnamespace __asan {\n\nuptr AsanMappingProfile[kAsanMappingProfileSize];\n\nstatic void AsanDie() {\n  static atomic_uint32_t num_calls;\n  if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {\n    // Don't die twice - run a busy loop.\n    while (1) { }\n  }\n  if (flags()->sleep_before_dying) {\n    Report(\"Sleeping for %d second(s)\\n\", flags()->sleep_before_dying);\n    SleepForSeconds(flags()->sleep_before_dying);\n  }\n  if (flags()->unmap_shadow_on_exit) {\n    if (kMidMemBeg) {\n      UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);\n      UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd);\n    } else {\n      UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);\n    }\n  }\n}\n\nstatic void AsanCheckFailed(const char *file, int line, const char *cond,\n                            u64 v1, u64 v2) {\n  Report(\"AddressSanitizer CHECK failed: %s:%d \\\"%s\\\" (0x%zx, 0x%zx)\\n\", file,\n         line, cond, (uptr)v1, (uptr)v2);\n  // FIXME: check for infinite recursion without a thread-local counter here.\n  PRINT_CURRENT_STACK_CHECK();\n  Die();\n}\n\n// -------------------------- Globals --------------------- {{{1\nint asan_inited;\nbool asan_init_is_running;\n\n#if !ASAN_FIXED_MAPPING\nuptr kHighMemEnd, kMidMemBeg, kMidMemEnd;\n#endif\n\n// -------------------------- Misc ---------------- {{{1\nvoid ShowStatsAndAbort() {\n  __asan_print_accumulated_stats();\n  Die();\n}\n\n// ---------------------- mmap -------------------- {{{1\n// Reserve memory range [beg, end].\n// We need to use inclusive range because end+1 may not be representable.\nvoid ReserveShadowMemoryRange(uptr beg, uptr end, const char *name) {\n  CHECK_EQ((beg % GetPageSizeCached()), 0);\n  CHECK_EQ(((end + 1) % GetPageSizeCached()), 0);\n  uptr size = end - beg + 1;\n  DecreaseTotalMmap(size);  // Don't count the shadow against mmap_limit_mb.\n  void *res = MmapFixedNoReserve(beg, size, name);\n  if (res != (void*)beg) {\n    Report(\"ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. \"\n           \"Perhaps you're using ulimit -v\\n\", size);\n    Abort();\n  }\n  if (common_flags()->no_huge_pages_for_shadow)\n    NoHugePagesInRegion(beg, size);\n  if (common_flags()->use_madv_dontdump)\n    DontDumpShadowMemory(beg, size);\n}\n\n// --------------- LowLevelAllocateCallbac ---------- {{{1\nstatic void OnLowLevelAllocate(uptr ptr, uptr size) {\n  PoisonShadow(ptr, size, kAsanInternalHeapMagic);\n}\n\n// -------------------------- Run-time entry ------------------- {{{1\n// exported functions\n#define ASAN_REPORT_ERROR(type, is_write, size)                     \\\nextern \"C\" NOINLINE INTERFACE_ATTRIBUTE                             \\\nvoid __asan_report_ ## type ## size(uptr addr) {                    \\\n  GET_CALLER_PC_BP_SP;                                              \\\n  ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true);    \\\n}                                                                   \\\nextern \"C\" NOINLINE INTERFACE_ATTRIBUTE                             \\\nvoid __asan_report_exp_ ## type ## size(uptr addr, u32 exp) {       \\\n  GET_CALLER_PC_BP_SP;                                              \\\n  ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true);  \\\n}                                                                   \\\nextern \"C\" NOINLINE INTERFACE_ATTRIBUTE                             \\\nvoid __asan_report_ ## type ## size ## _noabort(uptr addr) {        \\\n  GET_CALLER_PC_BP_SP;                                              \\\n  ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false);   \\\n}                                                                   \\\n\nASAN_REPORT_ERROR(load, false, 1)\nASAN_REPORT_ERROR(load, false, 2)\nASAN_REPORT_ERROR(load, false, 4)\nASAN_REPORT_ERROR(load, false, 8)\nASAN_REPORT_ERROR(load, false, 16)\nASAN_REPORT_ERROR(store, true, 1)\nASAN_REPORT_ERROR(store, true, 2)\nASAN_REPORT_ERROR(store, true, 4)\nASAN_REPORT_ERROR(store, true, 8)\nASAN_REPORT_ERROR(store, true, 16)\n\n#define ASAN_REPORT_ERROR_N(type, is_write)                                 \\\nextern \"C\" NOINLINE INTERFACE_ATTRIBUTE                                     \\\nvoid __asan_report_ ## type ## _n(uptr addr, uptr size) {                   \\\n  GET_CALLER_PC_BP_SP;                                                      \\\n  ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true);            \\\n}                                                                           \\\nextern \"C\" NOINLINE INTERFACE_ATTRIBUTE                                     \\\nvoid __asan_report_exp_ ## type ## _n(uptr addr, uptr size, u32 exp) {      \\\n  GET_CALLER_PC_BP_SP;                                                      \\\n  ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true);          \\\n}                                                                           \\\nextern \"C\" NOINLINE INTERFACE_ATTRIBUTE                                     \\\nvoid __asan_report_ ## type ## _n_noabort(uptr addr, uptr size) {           \\\n  GET_CALLER_PC_BP_SP;                                                      \\\n  ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false);           \\\n}                                                                           \\\n\nASAN_REPORT_ERROR_N(load, false)\nASAN_REPORT_ERROR_N(store, true)\n\n#define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg, fatal) \\\n    uptr sp = MEM_TO_SHADOW(addr);                                             \\\n    uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp)          \\\n                                        : *reinterpret_cast<u16 *>(sp);        \\\n    if (UNLIKELY(s)) {                                                         \\\n      if (UNLIKELY(size >= SHADOW_GRANULARITY ||                               \\\n                   ((s8)((addr & (SHADOW_GRANULARITY - 1)) + size - 1)) >=     \\\n                       (s8)s)) {                                               \\\n        if (__asan_test_only_reported_buggy_pointer) {                         \\\n          *__asan_test_only_reported_buggy_pointer = addr;                     \\\n        } else {                                                               \\\n          GET_CALLER_PC_BP_SP;                                                 \\\n          ReportGenericError(pc, bp, sp, addr, is_write, size, exp_arg,        \\\n                              fatal);                                          \\\n        }                                                                      \\\n      }                                                                        \\\n    }\n\n#define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size)                      \\\n  extern \"C\" NOINLINE INTERFACE_ATTRIBUTE                                      \\\n  void __asan_##type##size(uptr addr) {                                        \\\n    ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, true)            \\\n  }                                                                            \\\n  extern \"C\" NOINLINE INTERFACE_ATTRIBUTE                                      \\\n  void __asan_exp_##type##size(uptr addr, u32 exp) {                           \\\n    ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp, true)          \\\n  }                                                                            \\\n  extern \"C\" NOINLINE INTERFACE_ATTRIBUTE                                      \\\n  void __asan_##type##size ## _noabort(uptr addr) {                            \\\n    ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, false)           \\\n  }                                                                            \\\n\nASAN_MEMORY_ACCESS_CALLBACK(load, false, 1)\nASAN_MEMORY_ACCESS_CALLBACK(load, false, 2)\nASAN_MEMORY_ACCESS_CALLBACK(load, false, 4)\nASAN_MEMORY_ACCESS_CALLBACK(load, false, 8)\nASAN_MEMORY_ACCESS_CALLBACK(load, false, 16)\nASAN_MEMORY_ACCESS_CALLBACK(store, true, 1)\nASAN_MEMORY_ACCESS_CALLBACK(store, true, 2)\nASAN_MEMORY_ACCESS_CALLBACK(store, true, 4)\nASAN_MEMORY_ACCESS_CALLBACK(store, true, 8)\nASAN_MEMORY_ACCESS_CALLBACK(store, true, 16)\n\nextern \"C\"\nNOINLINE INTERFACE_ATTRIBUTE\nvoid __asan_loadN(uptr addr, uptr size) {\n  if (__asan_region_is_poisoned(addr, size)) {\n    GET_CALLER_PC_BP_SP;\n    ReportGenericError(pc, bp, sp, addr, false, size, 0, true);\n  }\n}\n\nextern \"C\"\nNOINLINE INTERFACE_ATTRIBUTE\nvoid __asan_exp_loadN(uptr addr, uptr size, u32 exp) {\n  if (__asan_region_is_poisoned(addr, size)) {\n    GET_CALLER_PC_BP_SP;\n    ReportGenericError(pc, bp, sp, addr, false, size, exp, true);\n  }\n}\n\nextern \"C\"\nNOINLINE INTERFACE_ATTRIBUTE\nvoid __asan_loadN_noabort(uptr addr, uptr size) {\n  if (__asan_region_is_poisoned(addr, size)) {\n    GET_CALLER_PC_BP_SP;\n    ReportGenericError(pc, bp, sp, addr, false, size, 0, false);\n  }\n}\n\nextern \"C\"\nNOINLINE INTERFACE_ATTRIBUTE\nvoid __asan_storeN(uptr addr, uptr size) {\n  if (__asan_region_is_poisoned(addr, size)) {\n    GET_CALLER_PC_BP_SP;\n    ReportGenericError(pc, bp, sp, addr, true, size, 0, true);\n  }\n}\n\nextern \"C\"\nNOINLINE INTERFACE_ATTRIBUTE\nvoid __asan_exp_storeN(uptr addr, uptr size, u32 exp) {\n  if (__asan_region_is_poisoned(addr, size)) {\n    GET_CALLER_PC_BP_SP;\n    ReportGenericError(pc, bp, sp, addr, true, size, exp, true);\n  }\n}\n\nextern \"C\"\nNOINLINE INTERFACE_ATTRIBUTE\nvoid __asan_storeN_noabort(uptr addr, uptr size) {\n  if (__asan_region_is_poisoned(addr, size)) {\n    GET_CALLER_PC_BP_SP;\n    ReportGenericError(pc, bp, sp, addr, true, size, 0, false);\n  }\n}\n\n// Force the linker to keep the symbols for various ASan interface functions.\n// We want to keep those in the executable in order to let the instrumented\n// dynamic libraries access the symbol even if it is not used by the executable\n// itself. This should help if the build system is removing dead code at link\n// time.\nstatic NOINLINE void force_interface_symbols() {\n  volatile int fake_condition = 0;  // prevent dead condition elimination.\n  // __asan_report_* functions are noreturn, so we need a switch to prevent\n  // the compiler from removing any of them.\n  switch (fake_condition) {\n    case 1: __asan_report_load1(0); break;\n    case 2: __asan_report_load2(0); break;\n    case 3: __asan_report_load4(0); break;\n    case 4: __asan_report_load8(0); break;\n    case 5: __asan_report_load16(0); break;\n    case 6: __asan_report_load_n(0, 0); break;\n    case 7: __asan_report_store1(0); break;\n    case 8: __asan_report_store2(0); break;\n    case 9: __asan_report_store4(0); break;\n    case 10: __asan_report_store8(0); break;\n    case 11: __asan_report_store16(0); break;\n    case 12: __asan_report_store_n(0, 0); break;\n    case 13: __asan_report_exp_load1(0, 0); break;\n    case 14: __asan_report_exp_load2(0, 0); break;\n    case 15: __asan_report_exp_load4(0, 0); break;\n    case 16: __asan_report_exp_load8(0, 0); break;\n    case 17: __asan_report_exp_load16(0, 0); break;\n    case 18: __asan_report_exp_load_n(0, 0, 0); break;\n    case 19: __asan_report_exp_store1(0, 0); break;\n    case 20: __asan_report_exp_store2(0, 0); break;\n    case 21: __asan_report_exp_store4(0, 0); break;\n    case 22: __asan_report_exp_store8(0, 0); break;\n    case 23: __asan_report_exp_store16(0, 0); break;\n    case 24: __asan_report_exp_store_n(0, 0, 0); break;\n    case 25: __asan_register_globals(nullptr, 0); break;\n    case 26: __asan_unregister_globals(nullptr, 0); break;\n    case 27: __asan_set_death_callback(nullptr); break;\n    case 28: __asan_set_error_report_callback(nullptr); break;\n    case 29: __asan_handle_no_return(); break;\n    case 30: __asan_address_is_poisoned(nullptr); break;\n    case 31: __asan_poison_memory_region(nullptr, 0); break;\n    case 32: __asan_unpoison_memory_region(nullptr, 0); break;\n    case 34: __asan_before_dynamic_init(nullptr); break;\n    case 35: __asan_after_dynamic_init(); break;\n    case 36: __asan_poison_stack_memory(0, 0); break;\n    case 37: __asan_unpoison_stack_memory(0, 0); break;\n    case 38: __asan_region_is_poisoned(0, 0); break;\n    case 39: __asan_describe_address(0); break;\n  }\n}\n\nstatic void asan_atexit() {\n  Printf(\"AddressSanitizer exit stats:\\n\");\n  __asan_print_accumulated_stats();\n  // Print AsanMappingProfile.\n  for (uptr i = 0; i < kAsanMappingProfileSize; i++) {\n    if (AsanMappingProfile[i] == 0) continue;\n    Printf(\"asan_mapping.h:%zd -- %zd\\n\", i, AsanMappingProfile[i]);\n  }\n}\n\nstatic void InitializeHighMemEnd() {\n#if !ASAN_FIXED_MAPPING\n  kHighMemEnd = GetMaxVirtualAddress();\n  // Increase kHighMemEnd to make sure it's properly\n  // aligned together with kHighMemBeg:\n  kHighMemEnd |= SHADOW_GRANULARITY * GetPageSizeCached() - 1;\n#endif  // !ASAN_FIXED_MAPPING\n  CHECK_EQ((kHighMemBeg % GetPageSizeCached()), 0);\n}\n\nstatic void ProtectGap(uptr addr, uptr size) {\n  if (!flags()->protect_shadow_gap)\n    return;\n  void *res = MmapNoAccess(addr, size, \"shadow gap\");\n  if (addr == (uptr)res)\n    return;\n  // A few pages at the start of the address space can not be protected.\n  // But we really want to protect as much as possible, to prevent this memory\n  // being returned as a result of a non-FIXED mmap().\n  if (addr == kZeroBaseShadowStart) {\n    uptr step = GetPageSizeCached();\n    while (size > step && addr < kZeroBaseMaxShadowStart) {\n      addr += step;\n      size -= step;\n      void *res = MmapNoAccess(addr, size, \"shadow gap\");\n      if (addr == (uptr)res)\n        return;\n    }\n  }\n\n  Report(\"ERROR: Failed to protect the shadow gap. \"\n         \"ASan cannot proceed correctly. ABORTING.\\n\");\n  DumpProcessMap();\n  Die();\n}\n\nstatic void PrintAddressSpaceLayout() {\n  Printf(\"|| `[%p, %p]` || HighMem    ||\\n\",\n         (void*)kHighMemBeg, (void*)kHighMemEnd);\n  Printf(\"|| `[%p, %p]` || HighShadow ||\\n\",\n         (void*)kHighShadowBeg, (void*)kHighShadowEnd);\n  if (kMidMemBeg) {\n    Printf(\"|| `[%p, %p]` || ShadowGap3 ||\\n\",\n           (void*)kShadowGap3Beg, (void*)kShadowGap3End);\n    Printf(\"|| `[%p, %p]` || MidMem     ||\\n\",\n           (void*)kMidMemBeg, (void*)kMidMemEnd);\n    Printf(\"|| `[%p, %p]` || ShadowGap2 ||\\n\",\n           (void*)kShadowGap2Beg, (void*)kShadowGap2End);\n    Printf(\"|| `[%p, %p]` || MidShadow  ||\\n\",\n           (void*)kMidShadowBeg, (void*)kMidShadowEnd);\n  }\n  Printf(\"|| `[%p, %p]` || ShadowGap  ||\\n\",\n         (void*)kShadowGapBeg, (void*)kShadowGapEnd);\n  if (kLowShadowBeg) {\n    Printf(\"|| `[%p, %p]` || LowShadow  ||\\n\",\n           (void*)kLowShadowBeg, (void*)kLowShadowEnd);\n    Printf(\"|| `[%p, %p]` || LowMem     ||\\n\",\n           (void*)kLowMemBeg, (void*)kLowMemEnd);\n  }\n  Printf(\"MemToShadow(shadow): %p %p %p %p\",\n         (void*)MEM_TO_SHADOW(kLowShadowBeg),\n         (void*)MEM_TO_SHADOW(kLowShadowEnd),\n         (void*)MEM_TO_SHADOW(kHighShadowBeg),\n         (void*)MEM_TO_SHADOW(kHighShadowEnd));\n  if (kMidMemBeg) {\n    Printf(\" %p %p\",\n           (void*)MEM_TO_SHADOW(kMidShadowBeg),\n           (void*)MEM_TO_SHADOW(kMidShadowEnd));\n  }\n  Printf(\"\\n\");\n  Printf(\"redzone=%zu\\n\", (uptr)flags()->redzone);\n  Printf(\"max_redzone=%zu\\n\", (uptr)flags()->max_redzone);\n  Printf(\"quarantine_size_mb=%zuM\\n\", (uptr)flags()->quarantine_size_mb);\n  Printf(\"malloc_context_size=%zu\\n\",\n         (uptr)common_flags()->malloc_context_size);\n\n  Printf(\"SHADOW_SCALE: %d\\n\", (int)SHADOW_SCALE);\n  Printf(\"SHADOW_GRANULARITY: %d\\n\", (int)SHADOW_GRANULARITY);\n  Printf(\"SHADOW_OFFSET: 0x%zx\\n\", (uptr)SHADOW_OFFSET);\n  CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);\n  if (kMidMemBeg)\n    CHECK(kMidShadowBeg > kLowShadowEnd &&\n          kMidMemBeg > kMidShadowEnd &&\n          kHighShadowBeg > kMidMemEnd);\n}\n\nstatic void AsanInitInternal() {\n  if (LIKELY(asan_inited)) return;\n  SanitizerToolName = \"AddressSanitizer\";\n  CHECK(!asan_init_is_running && \"ASan init calls itself!\");\n  asan_init_is_running = true;\n\n  CacheBinaryName();\n\n  // Initialize flags. This must be done early, because most of the\n  // initialization steps look at flags().\n  InitializeFlags();\n\n  AsanCheckIncompatibleRT();\n  AsanCheckDynamicRTPrereqs();\n\n  SetCanPoisonMemory(flags()->poison_heap);\n  SetMallocContextSize(common_flags()->malloc_context_size);\n\n  InitializeHighMemEnd();\n\n  // Make sure we are not statically linked.\n  AsanDoesNotSupportStaticLinkage();\n\n  // Install tool-specific callbacks in sanitizer_common.\n  AddDieCallback(AsanDie);\n  SetCheckFailedCallback(AsanCheckFailed);\n  SetPrintfAndReportCallback(AppendToErrorMessageBuffer);\n\n  __sanitizer_set_report_path(common_flags()->log_path);\n\n  // Enable UAR detection, if required.\n  __asan_option_detect_stack_use_after_return =\n      flags()->detect_stack_use_after_return;\n\n  // Re-exec ourselves if we need to set additional env or command line args.\n  MaybeReexec();\n\n  // Setup internal allocator callback.\n  SetLowLevelAllocateCallback(OnLowLevelAllocate);\n\n  InitializeAsanInterceptors();\n\n  // Enable system log (\"adb logcat\") on Android.\n  // Doing this before interceptors are initialized crashes in:\n  // AsanInitInternal -> android_log_write -> __interceptor_strcmp\n  AndroidLogInit();\n\n  ReplaceSystemMalloc();\n\n  uptr shadow_start = kLowShadowBeg;\n  if (kLowShadowBeg)\n    shadow_start -= GetMmapGranularity();\n  bool full_shadow_is_available =\n      MemoryRangeIsAvailable(shadow_start, kHighShadowEnd);\n\n#if SANITIZER_LINUX && defined(__x86_64__) && defined(_LP64) &&                \\\n    !ASAN_FIXED_MAPPING\n  if (!full_shadow_is_available) {\n    kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0;\n    kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x4fffffffffULL : 0;\n  }\n#endif\n\n  if (Verbosity()) PrintAddressSpaceLayout();\n\n  DisableCoreDumperIfNecessary();\n\n  if (full_shadow_is_available) {\n    // mmap the low shadow plus at least one page at the left.\n    if (kLowShadowBeg)\n      ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, \"low shadow\");\n    // mmap the high shadow.\n    ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, \"high shadow\");\n    // protect the gap.\n    ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);\n    CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1);\n  } else if (kMidMemBeg &&\n      MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) &&\n      MemoryRangeIsAvailable(kMidMemEnd + 1, kHighShadowEnd)) {\n    CHECK(kLowShadowBeg != kLowShadowEnd);\n    // mmap the low shadow plus at least one page at the left.\n    ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, \"low shadow\");\n    // mmap the mid shadow.\n    ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd, \"mid shadow\");\n    // mmap the high shadow.\n    ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, \"high shadow\");\n    // protect the gaps.\n    ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);\n    ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1);\n    ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1);\n  } else {\n    Report(\"Shadow memory range interleaves with an existing memory mapping. \"\n           \"ASan cannot proceed correctly. ABORTING.\\n\");\n    Report(\"ASan shadow was supposed to be located in the [%p-%p] range.\\n\",\n           shadow_start, kHighShadowEnd);\n    DumpProcessMap();\n    Die();\n  }\n\n  AsanTSDInit(PlatformTSDDtor);\n  InstallDeadlySignalHandlers(AsanOnDeadlySignal);\n\n  AllocatorOptions allocator_options;\n  allocator_options.SetFrom(flags(), common_flags());\n  InitializeAllocator(allocator_options);\n\n  MaybeStartBackgroudThread();\n  SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback);\n\n  // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited\n  // should be set to 1 prior to initializing the threads.\n  asan_inited = 1;\n  asan_init_is_running = false;\n\n  if (flags()->atexit)\n    Atexit(asan_atexit);\n\n  InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);\n\n  // Now that ASan runtime is (mostly) initialized, deactivate it if\n  // necessary, so that it can be re-activated when requested.\n  if (flags()->start_deactivated)\n    AsanDeactivate();\n\n  // interceptors\n  InitTlsSize();\n\n  // Create main thread.\n  AsanThread *main_thread = AsanThread::Create(\n      /* start_routine */ nullptr, /* arg */ nullptr, /* parent_tid */ 0,\n      /* stack */ nullptr, /* detached */ true);\n  CHECK_EQ(0, main_thread->tid());\n  SetCurrentThread(main_thread);\n  main_thread->ThreadStart(internal_getpid(),\n                           /* signal_thread_is_registered */ nullptr);\n  force_interface_symbols();  // no-op.\n  SanitizerInitializeUnwinder();\n\n#if CAN_SANITIZE_LEAKS\n  __lsan::InitCommonLsan();\n  if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) {\n    Atexit(__lsan::DoLeakCheck);\n  }\n#endif  // CAN_SANITIZE_LEAKS\n\n#if CAN_SANITIZE_UB\n  __ubsan::InitAsPlugin();\n#endif\n\n  InitializeSuppressions();\n\n  VReport(1, \"AddressSanitizer Init done\\n\");\n}\n\n// Initialize as requested from some part of ASan runtime library (interceptors,\n// allocator, etc).\nvoid AsanInitFromRtl() {\n  AsanInitInternal();\n}\n\n#if ASAN_DYNAMIC\n// Initialize runtime in case it's LD_PRELOAD-ed into unsanitized executable\n// (and thus normal initializers from .preinit_array or modules haven't run).\n\nclass AsanInitializer {\npublic:  // NOLINT\n  AsanInitializer() {\n    AsanInitFromRtl();\n  }\n};\n\nstatic AsanInitializer asan_initializer;\n#endif  // ASAN_DYNAMIC\n\n} // namespace __asan\n\n// ---------------------- Interface ---------------- {{{1\nusing namespace __asan;  // NOLINT\n\nvoid NOINLINE __asan_handle_no_return() {\n  int local_stack;\n  AsanThread *curr_thread = GetCurrentThread();\n  uptr PageSize = GetPageSizeCached();\n  uptr top, bottom;\n  if (curr_thread) {\n    top = curr_thread->stack_top();\n    bottom = ((uptr)&local_stack - PageSize) & ~(PageSize - 1);\n  } else {\n    // If we haven't seen this thread, try asking the OS for stack bounds.\n    uptr tls_addr, tls_size, stack_size;\n    GetThreadStackAndTls(/*main=*/false, &bottom, &stack_size, &tls_addr,\n                         &tls_size);\n    top = bottom + stack_size;\n  }\n  static const uptr kMaxExpectedCleanupSize = 64 << 20;  // 64M\n  if (top - bottom > kMaxExpectedCleanupSize) {\n    static bool reported_warning = false;\n    if (reported_warning)\n      return;\n    reported_warning = true;\n    Report(\"WARNING: ASan is ignoring requested __asan_handle_no_return: \"\n           \"stack top: %p; bottom %p; size: %p (%zd)\\n\"\n           \"False positive error reports may follow\\n\"\n           \"For details see \"\n           \"https://github.com/google/sanitizers/issues/189\\n\",\n           top, bottom, top - bottom, top - bottom);\n    return;\n  }\n  PoisonShadow(bottom, top - bottom, 0);\n  if (curr_thread && curr_thread->has_fake_stack())\n    curr_thread->fake_stack()->HandleNoReturn();\n}\n\nvoid NOINLINE __asan_set_death_callback(void (*callback)(void)) {\n  SetUserDieCallback(callback);\n}\n\n// Initialize as requested from instrumented application code.\n// We use this call as a trigger to wake up ASan from deactivated state.\nvoid __asan_init() {\n  AsanActivate();\n  AsanInitInternal();\n}\n\nvoid __asan_version_mismatch_check() {\n  // Do nothing.\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_stack.cc",
    "content": "//===-- asan_stack.cc -----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Code for ASan stack trace.\n//===----------------------------------------------------------------------===//\n#include \"asan_internal.h\"\n#include \"asan_stack.h\"\n#include \"sanitizer_common/sanitizer_atomic.h\"\n\nnamespace __asan {\n\nstatic atomic_uint32_t malloc_context_size;\n\nvoid SetMallocContextSize(u32 size) {\n  atomic_store(&malloc_context_size, size, memory_order_release);\n}\n\nu32 GetMallocContextSize() {\n  return atomic_load(&malloc_context_size, memory_order_acquire);\n}\n\n}  // namespace __asan\n\n// ------------------ Interface -------------- {{{1\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_print_stack_trace() {\n  using namespace __asan;\n  PRINT_CURRENT_STACK();\n}\n}  // extern \"C\"\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_stack.h",
    "content": "//===-- asan_stack.h --------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// ASan-private header for asan_stack.cc.\n//===----------------------------------------------------------------------===//\n\n#ifndef ASAN_STACK_H\n#define ASAN_STACK_H\n\n#include \"asan_flags.h\"\n#include \"asan_thread.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n\nnamespace __asan {\n\nstatic const u32 kDefaultMallocContextSize = 30;\n\nvoid SetMallocContextSize(u32 size);\nu32 GetMallocContextSize();\n\n// Get the stack trace with the given pc and bp.\n// The pc will be in the position 0 of the resulting stack trace.\n// The bp may refer to the current frame or to the caller's frame.\nALWAYS_INLINE\nvoid GetStackTraceWithPcBpAndContext(BufferedStackTrace *stack, uptr max_depth,\n                                     uptr pc, uptr bp, void *context,\n                                     bool fast) {\n#if SANITIZER_WINDOWS\n  stack->Unwind(max_depth, pc, bp, context, 0, 0, fast);\n#else\n  AsanThread *t;\n  stack->size = 0;\n  if (LIKELY(asan_inited)) {\n    if ((t = GetCurrentThread()) && !t->isUnwinding()) {\n      // On FreeBSD the slow unwinding that leverages _Unwind_Backtrace()\n      // yields the call stack of the signal's handler and not of the code\n      // that raised the signal (as it does on Linux).\n      if (SANITIZER_FREEBSD && t->isInDeadlySignal()) fast = true;\n      uptr stack_top = t->stack_top();\n      uptr stack_bottom = t->stack_bottom();\n      ScopedUnwinding unwind_scope(t);\n      stack->Unwind(max_depth, pc, bp, context, stack_top, stack_bottom, fast);\n    } else if (!t && !fast) {\n      /* If GetCurrentThread() has failed, try to do slow unwind anyways. */\n      stack->Unwind(max_depth, pc, bp, context, 0, 0, false);\n    }\n  }\n#endif // SANITIZER_WINDOWS\n}\n\n} // namespace __asan\n\n// NOTE: A Rule of thumb is to retrieve stack trace in the interceptors\n// as early as possible (in functions exposed to the user), as we generally\n// don't want stack trace to contain functions from ASan internals.\n\n#define GET_STACK_TRACE(max_size, fast)                                        \\\n  BufferedStackTrace stack;                                                    \\\n  if (max_size <= 2) {                                                         \\\n    stack.size = max_size;                                                     \\\n    if (max_size > 0) {                                                        \\\n      stack.top_frame_bp = GET_CURRENT_FRAME();                                \\\n      stack.trace_buffer[0] = StackTrace::GetCurrentPc();                      \\\n      if (max_size > 1)                                                        \\\n        stack.trace_buffer[1] = GET_CALLER_PC();                               \\\n    }                                                                          \\\n  } else {                                                                     \\\n    GetStackTraceWithPcBpAndContext(&stack, max_size,                          \\\n                                    StackTrace::GetCurrentPc(),                \\\n                                    GET_CURRENT_FRAME(), 0, fast);             \\\n  }\n\n#define GET_STACK_TRACE_FATAL(pc, bp)                                          \\\n  BufferedStackTrace stack;                                                    \\\n  GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, 0,           \\\n                                  common_flags()->fast_unwind_on_fatal)\n\n#define GET_STACK_TRACE_SIGNAL(sig)                                            \\\n  BufferedStackTrace stack;                                                    \\\n  GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax,                      \\\n                                  (sig).pc, (sig).bp, (sig).context,           \\\n                                  common_flags()->fast_unwind_on_fatal)\n\n#define GET_STACK_TRACE_FATAL_HERE                                \\\n  GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_fatal)\n\n#define GET_STACK_TRACE_CHECK_HERE                                \\\n  GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_check)\n\n#define GET_STACK_TRACE_THREAD                                    \\\n  GET_STACK_TRACE(kStackTraceMax, true)\n\n#define GET_STACK_TRACE_MALLOC                                                 \\\n  GET_STACK_TRACE(GetMallocContextSize(), common_flags()->fast_unwind_on_malloc)\n\n#define GET_STACK_TRACE_FREE GET_STACK_TRACE_MALLOC\n\n#define PRINT_CURRENT_STACK()   \\\n  {                             \\\n    GET_STACK_TRACE_FATAL_HERE; \\\n    stack.Print();              \\\n  }\n\n#define PRINT_CURRENT_STACK_CHECK() \\\n  {                                 \\\n    GET_STACK_TRACE_CHECK_HERE;     \\\n    stack.Print();                  \\\n  }\n\n#endif // ASAN_STACK_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_stats.cc",
    "content": "//===-- asan_stats.cc -----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Code related to statistics collected by AddressSanitizer.\n//===----------------------------------------------------------------------===//\n#include \"asan_interceptors.h\"\n#include \"asan_internal.h\"\n#include \"asan_stats.h\"\n#include \"asan_thread.h\"\n#include \"sanitizer_common/sanitizer_allocator_interface.h\"\n#include \"sanitizer_common/sanitizer_mutex.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n\nnamespace __asan {\n\nAsanStats::AsanStats() {\n  Clear();\n}\n\nvoid AsanStats::Clear() {\n  CHECK(REAL(memset));\n  REAL(memset)(this, 0, sizeof(AsanStats));\n}\n\nstatic void PrintMallocStatsArray(const char *prefix,\n                                  uptr (&array)[kNumberOfSizeClasses]) {\n  Printf(\"%s\", prefix);\n  for (uptr i = 0; i < kNumberOfSizeClasses; i++) {\n    if (!array[i]) continue;\n    Printf(\"%zu:%zu; \", i, array[i]);\n  }\n  Printf(\"\\n\");\n}\n\nvoid AsanStats::Print() {\n  Printf(\"Stats: %zuM malloced (%zuM for red zones) by %zu calls\\n\",\n             malloced>>20, malloced_redzones>>20, mallocs);\n  Printf(\"Stats: %zuM realloced by %zu calls\\n\", realloced>>20, reallocs);\n  Printf(\"Stats: %zuM freed by %zu calls\\n\", freed>>20, frees);\n  Printf(\"Stats: %zuM really freed by %zu calls\\n\",\n             really_freed>>20, real_frees);\n  Printf(\"Stats: %zuM (%zuM-%zuM) mmaped; %zu maps, %zu unmaps\\n\",\n             (mmaped-munmaped)>>20, mmaped>>20, munmaped>>20,\n             mmaps, munmaps);\n\n  PrintMallocStatsArray(\"  mallocs by size class: \", malloced_by_size);\n  Printf(\"Stats: malloc large: %zu\\n\", malloc_large);\n}\n\nvoid AsanStats::MergeFrom(const AsanStats *stats) {\n  uptr *dst_ptr = reinterpret_cast<uptr*>(this);\n  const uptr *src_ptr = reinterpret_cast<const uptr*>(stats);\n  uptr num_fields = sizeof(*this) / sizeof(uptr);\n  for (uptr i = 0; i < num_fields; i++)\n    dst_ptr[i] += src_ptr[i];\n}\n\nstatic BlockingMutex print_lock(LINKER_INITIALIZED);\n\nstatic AsanStats unknown_thread_stats(LINKER_INITIALIZED);\nstatic AsanStats dead_threads_stats(LINKER_INITIALIZED);\nstatic BlockingMutex dead_threads_stats_lock(LINKER_INITIALIZED);\n// Required for malloc_zone_statistics() on OS X. This can't be stored in\n// per-thread AsanStats.\nstatic uptr max_malloced_memory;\n\nstatic void MergeThreadStats(ThreadContextBase *tctx_base, void *arg) {\n  AsanStats *accumulated_stats = reinterpret_cast<AsanStats*>(arg);\n  AsanThreadContext *tctx = static_cast<AsanThreadContext*>(tctx_base);\n  if (AsanThread *t = tctx->thread)\n    accumulated_stats->MergeFrom(&t->stats());\n}\n\nstatic void GetAccumulatedStats(AsanStats *stats) {\n  stats->Clear();\n  {\n    ThreadRegistryLock l(&asanThreadRegistry());\n    asanThreadRegistry()\n        .RunCallbackForEachThreadLocked(MergeThreadStats, stats);\n  }\n  stats->MergeFrom(&unknown_thread_stats);\n  {\n    BlockingMutexLock lock(&dead_threads_stats_lock);\n    stats->MergeFrom(&dead_threads_stats);\n  }\n  // This is not very accurate: we may miss allocation peaks that happen\n  // between two updates of accumulated_stats_. For more accurate bookkeeping\n  // the maximum should be updated on every malloc(), which is unacceptable.\n  if (max_malloced_memory < stats->malloced) {\n    max_malloced_memory = stats->malloced;\n  }\n}\n\nvoid FlushToDeadThreadStats(AsanStats *stats) {\n  BlockingMutexLock lock(&dead_threads_stats_lock);\n  dead_threads_stats.MergeFrom(stats);\n  stats->Clear();\n}\n\nvoid FillMallocStatistics(AsanMallocStats *malloc_stats) {\n  AsanStats stats;\n  GetAccumulatedStats(&stats);\n  malloc_stats->blocks_in_use = stats.mallocs;\n  malloc_stats->size_in_use = stats.malloced;\n  malloc_stats->max_size_in_use = max_malloced_memory;\n  malloc_stats->size_allocated = stats.mmaped;\n}\n\nAsanStats &GetCurrentThreadStats() {\n  AsanThread *t = GetCurrentThread();\n  return (t) ? t->stats() : unknown_thread_stats;\n}\n\nstatic void PrintAccumulatedStats() {\n  AsanStats stats;\n  GetAccumulatedStats(&stats);\n  // Use lock to keep reports from mixing up.\n  BlockingMutexLock lock(&print_lock);\n  stats.Print();\n  StackDepotStats *stack_depot_stats = StackDepotGetStats();\n  Printf(\"Stats: StackDepot: %zd ids; %zdM allocated\\n\",\n         stack_depot_stats->n_uniq_ids, stack_depot_stats->allocated >> 20);\n  PrintInternalAllocatorStats();\n}\n\n}  // namespace __asan\n\n// ---------------------- Interface ---------------- {{{1\nusing namespace __asan;  // NOLINT\n\nuptr __sanitizer_get_current_allocated_bytes() {\n  AsanStats stats;\n  GetAccumulatedStats(&stats);\n  uptr malloced = stats.malloced;\n  uptr freed = stats.freed;\n  // Return sane value if malloced < freed due to racy\n  // way we update accumulated stats.\n  return (malloced > freed) ? malloced - freed : 1;\n}\n\nuptr __sanitizer_get_heap_size() {\n  AsanStats stats;\n  GetAccumulatedStats(&stats);\n  return stats.mmaped - stats.munmaped;\n}\n\nuptr __sanitizer_get_free_bytes() {\n  AsanStats stats;\n  GetAccumulatedStats(&stats);\n  uptr total_free = stats.mmaped\n                  - stats.munmaped\n                  + stats.really_freed;\n  uptr total_used = stats.malloced\n                  + stats.malloced_redzones;\n  // Return sane value if total_free < total_used due to racy\n  // way we update accumulated stats.\n  return (total_free > total_used) ? total_free - total_used : 1;\n}\n\nuptr __sanitizer_get_unmapped_bytes() {\n  return 0;\n}\n\nvoid __asan_print_accumulated_stats() {\n  PrintAccumulatedStats();\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_stats.h",
    "content": "//===-- asan_stats.h --------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// ASan-private header for statistics.\n//===----------------------------------------------------------------------===//\n#ifndef ASAN_STATS_H\n#define ASAN_STATS_H\n\n#include \"asan_allocator.h\"\n#include \"asan_internal.h\"\n\nnamespace __asan {\n\n// AsanStats struct is NOT thread-safe.\n// Each AsanThread has its own AsanStats, which are sometimes flushed\n// to the accumulated AsanStats.\nstruct AsanStats {\n  // AsanStats must be a struct consisting of uptr fields only.\n  // When merging two AsanStats structs, we treat them as arrays of uptr.\n  uptr mallocs;\n  uptr malloced;\n  uptr malloced_redzones;\n  uptr frees;\n  uptr freed;\n  uptr real_frees;\n  uptr really_freed;\n  uptr reallocs;\n  uptr realloced;\n  uptr mmaps;\n  uptr mmaped;\n  uptr munmaps;\n  uptr munmaped;\n  uptr malloc_large;\n  uptr malloced_by_size[kNumberOfSizeClasses];\n\n  // Ctor for global AsanStats (accumulated stats for dead threads).\n  explicit AsanStats(LinkerInitialized) { }\n  // Creates empty stats.\n  AsanStats();\n\n  void Print();  // Prints formatted stats to stderr.\n  void Clear();\n  void MergeFrom(const AsanStats *stats);\n};\n\n// Returns stats for GetCurrentThread(), or stats for fake \"unknown thread\"\n// if GetCurrentThread() returns 0.\nAsanStats &GetCurrentThreadStats();\n// Flushes a given stats into accumulated stats of dead threads.\nvoid FlushToDeadThreadStats(AsanStats *stats);\n\n// A cross-platform equivalent of malloc_statistics_t on Mac OS.\nstruct AsanMallocStats {\n  uptr blocks_in_use;\n  uptr size_in_use;\n  uptr max_size_in_use;\n  uptr size_allocated;\n};\n\nvoid FillMallocStatistics(AsanMallocStats *malloc_stats);\n\n}  // namespace __asan\n\n#endif  // ASAN_STATS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_suppressions.cc",
    "content": "//===-- asan_suppressions.cc ----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Issue suppression and suppression-related functions.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_suppressions.h\"\n\n#include \"asan_stack.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_suppressions.h\"\n#include \"sanitizer_common/sanitizer_symbolizer.h\"\n\nnamespace __asan {\n\nALIGNED(64) static char suppression_placeholder[sizeof(SuppressionContext)];\nstatic SuppressionContext *suppression_ctx = nullptr;\nstatic const char kInterceptorName[] = \"interceptor_name\";\nstatic const char kInterceptorViaFunction[] = \"interceptor_via_fun\";\nstatic const char kInterceptorViaLibrary[] = \"interceptor_via_lib\";\nstatic const char kODRViolation[] = \"odr_violation\";\nstatic const char *kSuppressionTypes[] = {\n    kInterceptorName, kInterceptorViaFunction, kInterceptorViaLibrary,\n    kODRViolation};\n\nextern \"C\" {\n#if SANITIZER_SUPPORTS_WEAK_HOOKS\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nconst char *__asan_default_suppressions();\n#else\n// No week hooks, provide empty implementation.\nconst char *__asan_default_suppressions() { return \"\"; }\n#endif  // SANITIZER_SUPPORTS_WEAK_HOOKS\n}  // extern \"C\"\n\nvoid InitializeSuppressions() {\n  CHECK_EQ(nullptr, suppression_ctx);\n  suppression_ctx = new (suppression_placeholder)  // NOLINT\n      SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes));\n  suppression_ctx->ParseFromFile(flags()->suppressions);\n  if (&__asan_default_suppressions)\n    suppression_ctx->Parse(__asan_default_suppressions());\n}\n\nbool IsInterceptorSuppressed(const char *interceptor_name) {\n  CHECK(suppression_ctx);\n  Suppression *s;\n  // Match \"interceptor_name\" suppressions.\n  return suppression_ctx->Match(interceptor_name, kInterceptorName, &s);\n}\n\nbool HaveStackTraceBasedSuppressions() {\n  CHECK(suppression_ctx);\n  return suppression_ctx->HasSuppressionType(kInterceptorViaFunction) ||\n         suppression_ctx->HasSuppressionType(kInterceptorViaLibrary);\n}\n\nbool IsODRViolationSuppressed(const char *global_var_name) {\n  CHECK(suppression_ctx);\n  Suppression *s;\n  // Match \"odr_violation\" suppressions.\n  return suppression_ctx->Match(global_var_name, kODRViolation, &s);\n}\n\nbool IsStackTraceSuppressed(const StackTrace *stack) {\n  if (!HaveStackTraceBasedSuppressions())\n    return false;\n\n  CHECK(suppression_ctx);\n  Symbolizer *symbolizer = Symbolizer::GetOrInit();\n  Suppression *s;\n  for (uptr i = 0; i < stack->size && stack->trace[i]; i++) {\n    uptr addr = stack->trace[i];\n\n    if (suppression_ctx->HasSuppressionType(kInterceptorViaLibrary)) {\n      // Match \"interceptor_via_lib\" suppressions.\n      if (const char *module_name = symbolizer->GetModuleNameForPc(addr))\n        if (suppression_ctx->Match(module_name, kInterceptorViaLibrary, &s))\n          return true;\n    }\n\n    if (suppression_ctx->HasSuppressionType(kInterceptorViaFunction)) {\n      SymbolizedStack *frames = symbolizer->SymbolizePC(addr);\n      for (SymbolizedStack *cur = frames; cur; cur = cur->next) {\n        const char *function_name = cur->info.function;\n        if (!function_name) {\n          continue;\n        }\n        // Match \"interceptor_via_fun\" suppressions.\n        if (suppression_ctx->Match(function_name, kInterceptorViaFunction,\n                                   &s)) {\n          frames->ClearAll();\n          return true;\n        }\n      }\n      frames->ClearAll();\n    }\n  }\n  return false;\n}\n\n} // namespace __asan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_suppressions.h",
    "content": "//===-- asan_suppressions.h -------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// ASan-private header for asan_suppressions.cc.\n//===----------------------------------------------------------------------===//\n#ifndef ASAN_SUPPRESSIONS_H\n#define ASAN_SUPPRESSIONS_H\n\n#include \"asan_internal.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n\nnamespace __asan {\n\nvoid InitializeSuppressions();\nbool IsInterceptorSuppressed(const char *interceptor_name);\nbool HaveStackTraceBasedSuppressions();\nbool IsStackTraceSuppressed(const StackTrace *stack);\nbool IsODRViolationSuppressed(const char *global_var_name);\n\n} // namespace __asan\n\n#endif // ASAN_SUPPRESSIONS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_thread.cc",
    "content": "//===-- asan_thread.cc ----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Thread-related code.\n//===----------------------------------------------------------------------===//\n#include \"asan_allocator.h\"\n#include \"asan_interceptors.h\"\n#include \"asan_poisoning.h\"\n#include \"asan_stack.h\"\n#include \"asan_thread.h\"\n#include \"asan_mapping.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n#include \"sanitizer_common/sanitizer_tls_get_addr.h\"\n#include \"lsan/lsan_common.h\"\n\nnamespace __asan {\n\n// AsanThreadContext implementation.\n\nstruct CreateThreadContextArgs {\n  AsanThread *thread;\n  StackTrace *stack;\n};\n\nvoid AsanThreadContext::OnCreated(void *arg) {\n  CreateThreadContextArgs *args = static_cast<CreateThreadContextArgs*>(arg);\n  if (args->stack)\n    stack_id = StackDepotPut(*args->stack);\n  thread = args->thread;\n  thread->set_context(this);\n}\n\nvoid AsanThreadContext::OnFinished() {\n  // Drop the link to the AsanThread object.\n  thread = nullptr;\n}\n\n// MIPS requires aligned address\nstatic ALIGNED(16) char thread_registry_placeholder[sizeof(ThreadRegistry)];\nstatic ThreadRegistry *asan_thread_registry;\n\nstatic BlockingMutex mu_for_thread_context(LINKER_INITIALIZED);\nstatic LowLevelAllocator allocator_for_thread_context;\n\nstatic ThreadContextBase *GetAsanThreadContext(u32 tid) {\n  BlockingMutexLock lock(&mu_for_thread_context);\n  return new(allocator_for_thread_context) AsanThreadContext(tid);\n}\n\nThreadRegistry &asanThreadRegistry() {\n  static bool initialized;\n  // Don't worry about thread_safety - this should be called when there is\n  // a single thread.\n  if (!initialized) {\n    // Never reuse ASan threads: we store pointer to AsanThreadContext\n    // in TSD and can't reliably tell when no more TSD destructors will\n    // be called. It would be wrong to reuse AsanThreadContext for another\n    // thread before all TSD destructors will be called for it.\n    asan_thread_registry = new(thread_registry_placeholder) ThreadRegistry(\n        GetAsanThreadContext, kMaxNumberOfThreads, kMaxNumberOfThreads);\n    initialized = true;\n  }\n  return *asan_thread_registry;\n}\n\nAsanThreadContext *GetThreadContextByTidLocked(u32 tid) {\n  return static_cast<AsanThreadContext *>(\n      asanThreadRegistry().GetThreadLocked(tid));\n}\n\n// AsanThread implementation.\n\nAsanThread *AsanThread::Create(thread_callback_t start_routine, void *arg,\n                               u32 parent_tid, StackTrace *stack,\n                               bool detached) {\n  uptr PageSize = GetPageSizeCached();\n  uptr size = RoundUpTo(sizeof(AsanThread), PageSize);\n  AsanThread *thread = (AsanThread*)MmapOrDie(size, __func__);\n  thread->start_routine_ = start_routine;\n  thread->arg_ = arg;\n  CreateThreadContextArgs args = { thread, stack };\n  asanThreadRegistry().CreateThread(*reinterpret_cast<uptr *>(thread), detached,\n                                    parent_tid, &args);\n\n  return thread;\n}\n\nvoid AsanThread::TSDDtor(void *tsd) {\n  AsanThreadContext *context = (AsanThreadContext*)tsd;\n  VReport(1, \"T%d TSDDtor\\n\", context->tid);\n  if (context->thread)\n    context->thread->Destroy();\n}\n\nvoid AsanThread::Destroy() {\n  int tid = this->tid();\n  VReport(1, \"T%d exited\\n\", tid);\n\n  malloc_storage().CommitBack();\n  if (common_flags()->use_sigaltstack) UnsetAlternateSignalStack();\n  asanThreadRegistry().FinishThread(tid);\n  FlushToDeadThreadStats(&stats_);\n  // We also clear the shadow on thread destruction because\n  // some code may still be executing in later TSD destructors\n  // and we don't want it to have any poisoned stack.\n  ClearShadowForThreadStackAndTLS();\n  DeleteFakeStack(tid);\n  uptr size = RoundUpTo(sizeof(AsanThread), GetPageSizeCached());\n  UnmapOrDie(this, size);\n  DTLS_Destroy();\n}\n\n// We want to create the FakeStack lazyly on the first use, but not eralier\n// than the stack size is known and the procedure has to be async-signal safe.\nFakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() {\n  uptr stack_size = this->stack_size();\n  if (stack_size == 0)  // stack_size is not yet available, don't use FakeStack.\n    return nullptr;\n  uptr old_val = 0;\n  // fake_stack_ has 3 states:\n  // 0   -- not initialized\n  // 1   -- being initialized\n  // ptr -- initialized\n  // This CAS checks if the state was 0 and if so changes it to state 1,\n  // if that was successful, it initializes the pointer.\n  if (atomic_compare_exchange_strong(\n      reinterpret_cast<atomic_uintptr_t *>(&fake_stack_), &old_val, 1UL,\n      memory_order_relaxed)) {\n    uptr stack_size_log = Log2(RoundUpToPowerOfTwo(stack_size));\n    CHECK_LE(flags()->min_uar_stack_size_log, flags()->max_uar_stack_size_log);\n    stack_size_log =\n        Min(stack_size_log, static_cast<uptr>(flags()->max_uar_stack_size_log));\n    stack_size_log =\n        Max(stack_size_log, static_cast<uptr>(flags()->min_uar_stack_size_log));\n    fake_stack_ = FakeStack::Create(stack_size_log);\n    SetTLSFakeStack(fake_stack_);\n    return fake_stack_;\n  }\n  return nullptr;\n}\n\nvoid AsanThread::Init() {\n  fake_stack_ = nullptr;  // Will be initialized lazily if needed.\n  CHECK_EQ(this->stack_size(), 0U);\n  SetThreadStackAndTls();\n  CHECK_GT(this->stack_size(), 0U);\n  CHECK(AddrIsInMem(stack_bottom_));\n  CHECK(AddrIsInMem(stack_top_ - 1));\n  ClearShadowForThreadStackAndTLS();\n  int local = 0;\n  VReport(1, \"T%d: stack [%p,%p) size 0x%zx; local=%p\\n\", tid(),\n          (void *)stack_bottom_, (void *)stack_top_, stack_top_ - stack_bottom_,\n          &local);\n}\n\nthread_return_t AsanThread::ThreadStart(\n    uptr os_id, atomic_uintptr_t *signal_thread_is_registered) {\n  Init();\n  asanThreadRegistry().StartThread(tid(), os_id, nullptr);\n  if (signal_thread_is_registered)\n    atomic_store(signal_thread_is_registered, 1, memory_order_release);\n\n  if (common_flags()->use_sigaltstack) SetAlternateSignalStack();\n\n  if (!start_routine_) {\n    // start_routine_ == 0 if we're on the main thread or on one of the\n    // OS X libdispatch worker threads. But nobody is supposed to call\n    // ThreadStart() for the worker threads.\n    CHECK_EQ(tid(), 0);\n    return 0;\n  }\n\n  thread_return_t res = start_routine_(arg_);\n\n  // On POSIX systems we defer this to the TSD destructor. LSan will consider\n  // the thread's memory as non-live from the moment we call Destroy(), even\n  // though that memory might contain pointers to heap objects which will be\n  // cleaned up by a user-defined TSD destructor. Thus, calling Destroy() before\n  // the TSD destructors have run might cause false positives in LSan.\n  if (!SANITIZER_POSIX)\n    this->Destroy();\n\n  return res;\n}\n\nvoid AsanThread::SetThreadStackAndTls() {\n  uptr tls_size = 0;\n  GetThreadStackAndTls(tid() == 0, &stack_bottom_, &stack_size_, &tls_begin_,\n                       &tls_size);\n  stack_top_ = stack_bottom_ + stack_size_;\n  tls_end_ = tls_begin_ + tls_size;\n\n  int local;\n  CHECK(AddrIsInStack((uptr)&local));\n}\n\nvoid AsanThread::ClearShadowForThreadStackAndTLS() {\n  PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0);\n  if (tls_begin_ != tls_end_)\n    PoisonShadow(tls_begin_, tls_end_ - tls_begin_, 0);\n}\n\nbool AsanThread::GetStackFrameAccessByAddr(uptr addr,\n                                           StackFrameAccess *access) {\n  uptr bottom = 0;\n  if (AddrIsInStack(addr)) {\n    bottom = stack_bottom();\n  } else if (has_fake_stack()) {\n    bottom = fake_stack()->AddrIsInFakeStack(addr);\n    CHECK(bottom);\n    access->offset = addr - bottom;\n    access->frame_pc = ((uptr*)bottom)[2];\n    access->frame_descr = (const char *)((uptr*)bottom)[1];\n    return true;\n  }\n  uptr aligned_addr = addr & ~(SANITIZER_WORDSIZE/8 - 1);  // align addr.\n  u8 *shadow_ptr = (u8*)MemToShadow(aligned_addr);\n  u8 *shadow_bottom = (u8*)MemToShadow(bottom);\n\n  while (shadow_ptr >= shadow_bottom &&\n         *shadow_ptr != kAsanStackLeftRedzoneMagic) {\n    shadow_ptr--;\n  }\n\n  while (shadow_ptr >= shadow_bottom &&\n         *shadow_ptr == kAsanStackLeftRedzoneMagic) {\n    shadow_ptr--;\n  }\n\n  if (shadow_ptr < shadow_bottom) {\n    return false;\n  }\n\n  uptr* ptr = (uptr*)SHADOW_TO_MEM((uptr)(shadow_ptr + 1));\n  CHECK(ptr[0] == kCurrentStackFrameMagic);\n  access->offset = addr - (uptr)ptr;\n  access->frame_pc = ptr[2];\n  access->frame_descr = (const char*)ptr[1];\n  return true;\n}\n\nstatic bool ThreadStackContainsAddress(ThreadContextBase *tctx_base,\n                                       void *addr) {\n  AsanThreadContext *tctx = static_cast<AsanThreadContext*>(tctx_base);\n  AsanThread *t = tctx->thread;\n  if (!t) return false;\n  if (t->AddrIsInStack((uptr)addr)) return true;\n  if (t->has_fake_stack() && t->fake_stack()->AddrIsInFakeStack((uptr)addr))\n    return true;\n  return false;\n}\n\nAsanThread *GetCurrentThread() {\n  AsanThreadContext *context =\n      reinterpret_cast<AsanThreadContext *>(AsanTSDGet());\n  if (!context) {\n    if (SANITIZER_ANDROID) {\n      // On Android, libc constructor is called _after_ asan_init, and cleans up\n      // TSD. Try to figure out if this is still the main thread by the stack\n      // address. We are not entirely sure that we have correct main thread\n      // limits, so only do this magic on Android, and only if the found thread\n      // is the main thread.\n      AsanThreadContext *tctx = GetThreadContextByTidLocked(0);\n      if (ThreadStackContainsAddress(tctx, &context)) {\n        SetCurrentThread(tctx->thread);\n        return tctx->thread;\n      }\n    }\n    return nullptr;\n  }\n  return context->thread;\n}\n\nvoid SetCurrentThread(AsanThread *t) {\n  CHECK(t->context());\n  VReport(2, \"SetCurrentThread: %p for thread %p\\n\", t->context(),\n          (void *)GetThreadSelf());\n  // Make sure we do not reset the current AsanThread.\n  CHECK_EQ(0, AsanTSDGet());\n  AsanTSDSet(t->context());\n  CHECK_EQ(t->context(), AsanTSDGet());\n}\n\nu32 GetCurrentTidOrInvalid() {\n  AsanThread *t = GetCurrentThread();\n  return t ? t->tid() : kInvalidTid;\n}\n\nAsanThread *FindThreadByStackAddress(uptr addr) {\n  asanThreadRegistry().CheckLocked();\n  AsanThreadContext *tctx = static_cast<AsanThreadContext *>(\n      asanThreadRegistry().FindThreadContextLocked(ThreadStackContainsAddress,\n                                                   (void *)addr));\n  return tctx ? tctx->thread : nullptr;\n}\n\nvoid EnsureMainThreadIDIsCorrect() {\n  AsanThreadContext *context =\n      reinterpret_cast<AsanThreadContext *>(AsanTSDGet());\n  if (context && (context->tid == 0))\n    context->os_id = GetTid();\n}\n\n__asan::AsanThread *GetAsanThreadByOsIDLocked(uptr os_id) {\n  __asan::AsanThreadContext *context = static_cast<__asan::AsanThreadContext *>(\n      __asan::asanThreadRegistry().FindThreadContextByOsIDLocked(os_id));\n  if (!context) return nullptr;\n  return context->thread;\n}\n} // namespace __asan\n\n// --- Implementation of LSan-specific functions --- {{{1\nnamespace __lsan {\nbool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end,\n                           uptr *tls_begin, uptr *tls_end,\n                           uptr *cache_begin, uptr *cache_end) {\n  __asan::AsanThread *t = __asan::GetAsanThreadByOsIDLocked(os_id);\n  if (!t) return false;\n  *stack_begin = t->stack_bottom();\n  *stack_end = t->stack_top();\n  *tls_begin = t->tls_begin();\n  *tls_end = t->tls_end();\n  // ASan doesn't keep allocator caches in TLS, so these are unused.\n  *cache_begin = 0;\n  *cache_end = 0;\n  return true;\n}\n\nvoid ForEachExtraStackRange(uptr os_id, RangeIteratorCallback callback,\n                            void *arg) {\n  __asan::AsanThread *t = __asan::GetAsanThreadByOsIDLocked(os_id);\n  if (t && t->has_fake_stack())\n    t->fake_stack()->ForEachFakeFrame(callback, arg);\n}\n\nvoid LockThreadRegistry() {\n  __asan::asanThreadRegistry().Lock();\n}\n\nvoid UnlockThreadRegistry() {\n  __asan::asanThreadRegistry().Unlock();\n}\n\nvoid EnsureMainThreadIDIsCorrect() {\n  __asan::EnsureMainThreadIDIsCorrect();\n}\n} // namespace __lsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_thread.h",
    "content": "//===-- asan_thread.h -------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// ASan-private header for asan_thread.cc.\n//===----------------------------------------------------------------------===//\n\n#ifndef ASAN_THREAD_H\n#define ASAN_THREAD_H\n\n#include \"asan_allocator.h\"\n#include \"asan_internal.h\"\n#include \"asan_fake_stack.h\"\n#include \"asan_stats.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_thread_registry.h\"\n\nnamespace __asan {\n\nconst u32 kInvalidTid = 0xffffff;  // Must fit into 24 bits.\nconst u32 kMaxNumberOfThreads = (1 << 22);  // 4M\n\nclass AsanThread;\n\n// These objects are created for every thread and are never deleted,\n// so we can find them by tid even if the thread is long dead.\nclass AsanThreadContext : public ThreadContextBase {\n public:\n  explicit AsanThreadContext(int tid)\n      : ThreadContextBase(tid), announced(false),\n        destructor_iterations(GetPthreadDestructorIterations()), stack_id(0),\n        thread(nullptr) {}\n  bool announced;\n  u8 destructor_iterations;\n  u32 stack_id;\n  AsanThread *thread;\n\n  void OnCreated(void *arg) override;\n  void OnFinished() override;\n};\n\n// AsanThreadContext objects are never freed, so we need many of them.\nCOMPILER_CHECK(sizeof(AsanThreadContext) <= 256);\n\n// AsanThread are stored in TSD and destroyed when the thread dies.\nclass AsanThread {\n public:\n  static AsanThread *Create(thread_callback_t start_routine, void *arg,\n                            u32 parent_tid, StackTrace *stack, bool detached);\n  static void TSDDtor(void *tsd);\n  void Destroy();\n\n  void Init();  // Should be called from the thread itself.\n  thread_return_t ThreadStart(uptr os_id,\n                              atomic_uintptr_t *signal_thread_is_registered);\n\n  uptr stack_top() { return stack_top_; }\n  uptr stack_bottom() { return stack_bottom_; }\n  uptr stack_size() { return stack_size_; }\n  uptr tls_begin() { return tls_begin_; }\n  uptr tls_end() { return tls_end_; }\n  u32 tid() { return context_->tid; }\n  AsanThreadContext *context() { return context_; }\n  void set_context(AsanThreadContext *context) { context_ = context; }\n\n  struct StackFrameAccess {\n    uptr offset;\n    uptr frame_pc;\n    const char *frame_descr;\n  };\n  bool GetStackFrameAccessByAddr(uptr addr, StackFrameAccess *access);\n\n  bool AddrIsInStack(uptr addr) {\n    return addr >= stack_bottom_ && addr < stack_top_;\n  }\n\n  void DeleteFakeStack(int tid) {\n    if (!fake_stack_) return;\n    FakeStack *t = fake_stack_;\n    fake_stack_ = nullptr;\n    SetTLSFakeStack(nullptr);\n    t->Destroy(tid);\n  }\n\n  bool has_fake_stack() {\n    return (reinterpret_cast<uptr>(fake_stack_) > 1);\n  }\n\n  FakeStack *fake_stack() {\n    if (!__asan_option_detect_stack_use_after_return)\n      return nullptr;\n    if (!has_fake_stack())\n      return AsyncSignalSafeLazyInitFakeStack();\n    return fake_stack_;\n  }\n\n  // True is this thread is currently unwinding stack (i.e. collecting a stack\n  // trace). Used to prevent deadlocks on platforms where libc unwinder calls\n  // malloc internally. See PR17116 for more details.\n  bool isUnwinding() const { return unwinding_; }\n  void setUnwinding(bool b) { unwinding_ = b; }\n\n  // True if we are in a deadly signal handler.\n  bool isInDeadlySignal() const { return in_deadly_signal_; }\n  void setInDeadlySignal(bool b) { in_deadly_signal_ = b; }\n\n  AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }\n  AsanStats &stats() { return stats_; }\n\n private:\n  // NOTE: There is no AsanThread constructor. It is allocated\n  // via mmap() and *must* be valid in zero-initialized state.\n  void SetThreadStackAndTls();\n  void ClearShadowForThreadStackAndTLS();\n  FakeStack *AsyncSignalSafeLazyInitFakeStack();\n\n  AsanThreadContext *context_;\n  thread_callback_t start_routine_;\n  void *arg_;\n  uptr stack_top_;\n  uptr stack_bottom_;\n  // stack_size_ == stack_top_ - stack_bottom_;\n  // It needs to be set in a async-signal-safe manner.\n  uptr stack_size_;\n  uptr tls_begin_;\n  uptr tls_end_;\n\n  FakeStack *fake_stack_;\n  AsanThreadLocalMallocStorage malloc_storage_;\n  AsanStats stats_;\n  bool unwinding_;\n  bool in_deadly_signal_;\n};\n\n// ScopedUnwinding is a scope for stacktracing member of a context\nclass ScopedUnwinding {\n public:\n  explicit ScopedUnwinding(AsanThread *t) : thread(t) {\n    t->setUnwinding(true);\n  }\n  ~ScopedUnwinding() { thread->setUnwinding(false); }\n\n private:\n  AsanThread *thread;\n};\n\n// ScopedDeadlySignal is a scope for handling deadly signals.\nclass ScopedDeadlySignal {\n public:\n  explicit ScopedDeadlySignal(AsanThread *t) : thread(t) {\n    if (thread) thread->setInDeadlySignal(true);\n  }\n  ~ScopedDeadlySignal() {\n    if (thread) thread->setInDeadlySignal(false);\n  }\n\n private:\n  AsanThread *thread;\n};\n\n// Returns a single instance of registry.\nThreadRegistry &asanThreadRegistry();\n\n// Must be called under ThreadRegistryLock.\nAsanThreadContext *GetThreadContextByTidLocked(u32 tid);\n\n// Get the current thread. May return 0.\nAsanThread *GetCurrentThread();\nvoid SetCurrentThread(AsanThread *t);\nu32 GetCurrentTidOrInvalid();\nAsanThread *FindThreadByStackAddress(uptr addr);\n\n// Used to handle fork().\nvoid EnsureMainThreadIDIsCorrect();\n} // namespace __asan\n\n#endif // ASAN_THREAD_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_win.cc",
    "content": "//===-- asan_win.cc -------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Windows-specific details.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_WINDOWS\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n\n#include <stdlib.h>\n\n#include \"asan_interceptors.h\"\n#include \"asan_internal.h\"\n#include \"asan_report.h\"\n#include \"asan_stack.h\"\n#include \"asan_thread.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_mutex.h\"\n\nusing namespace __asan;  // NOLINT\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE\nint __asan_should_detect_stack_use_after_return() {\n  __asan_init();\n  return __asan_option_detect_stack_use_after_return;\n}\n\n// -------------------- A workaround for the abscence of weak symbols ----- {{{\n// We don't have a direct equivalent of weak symbols when using MSVC, but we can\n// use the /alternatename directive to tell the linker to default a specific\n// symbol to a specific value, which works nicely for allocator hooks and\n// __asan_default_options().\nvoid __sanitizer_default_malloc_hook(void *ptr, uptr size) { }\nvoid __sanitizer_default_free_hook(void *ptr) { }\nconst char* __asan_default_default_options() { return \"\"; }\nconst char* __asan_default_default_suppressions() { return \"\"; }\nvoid __asan_default_on_error() {}\n#pragma comment(linker, \"/alternatename:___sanitizer_malloc_hook=___sanitizer_default_malloc_hook\")  // NOLINT\n#pragma comment(linker, \"/alternatename:___sanitizer_free_hook=___sanitizer_default_free_hook\")      // NOLINT\n#pragma comment(linker, \"/alternatename:___asan_default_options=___asan_default_default_options\")    // NOLINT\n#pragma comment(linker, \"/alternatename:___asan_default_suppressions=___asan_default_default_suppressions\")    // NOLINT\n#pragma comment(linker, \"/alternatename:___asan_on_error=___asan_default_on_error\")                  // NOLINT\n// }}}\n}  // extern \"C\"\n\n// ---------------------- Windows-specific inteceptors ---------------- {{{\nINTERCEPTOR_WINAPI(void, RaiseException, void *a, void *b, void *c, void *d) {\n  CHECK(REAL(RaiseException));\n  __asan_handle_no_return();\n  REAL(RaiseException)(a, b, c, d);\n}\n\nINTERCEPTOR(int, _except_handler3, void *a, void *b, void *c, void *d) {\n  CHECK(REAL(_except_handler3));\n  __asan_handle_no_return();\n  return REAL(_except_handler3)(a, b, c, d);\n}\n\n#if ASAN_DYNAMIC\n// This handler is named differently in -MT and -MD CRTs.\n#define _except_handler4 _except_handler4_common\n#endif\nINTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {\n  CHECK(REAL(_except_handler4));\n  __asan_handle_no_return();\n  return REAL(_except_handler4)(a, b, c, d);\n}\n\nstatic thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {\n  AsanThread *t = (AsanThread*)arg;\n  SetCurrentThread(t);\n  return t->ThreadStart(GetTid(), /* signal_thread_is_registered */ nullptr);\n}\n\nINTERCEPTOR_WINAPI(DWORD, CreateThread,\n                   void* security, uptr stack_size,\n                   DWORD (__stdcall *start_routine)(void*), void* arg,\n                   DWORD thr_flags, void* tid) {\n  // Strict init-order checking is thread-hostile.\n  if (flags()->strict_init_order)\n    StopInitOrderChecking();\n  GET_STACK_TRACE_THREAD;\n  // FIXME: The CreateThread interceptor is not the same as a pthread_create\n  // one.  This is a bandaid fix for PR22025.\n  bool detached = false;  // FIXME: how can we determine it on Windows?\n  u32 current_tid = GetCurrentTidOrInvalid();\n  AsanThread *t =\n        AsanThread::Create(start_routine, arg, current_tid, &stack, detached);\n  return REAL(CreateThread)(security, stack_size,\n                            asan_thread_start, t, thr_flags, tid);\n}\n\nnamespace {\nBlockingMutex mu_for_thread_tracking(LINKER_INITIALIZED);\n\nvoid EnsureWorkerThreadRegistered() {\n  // FIXME: GetCurrentThread relies on TSD, which might not play well with\n  // system thread pools.  We might want to use something like reference\n  // counting to zero out GetCurrentThread() underlying storage when the last\n  // work item finishes?  Or can we disable reclaiming of threads in the pool?\n  BlockingMutexLock l(&mu_for_thread_tracking);\n  if (__asan::GetCurrentThread())\n    return;\n\n  AsanThread *t = AsanThread::Create(\n      /* start_routine */ nullptr, /* arg */ nullptr,\n      /* parent_tid */ -1, /* stack */ nullptr, /* detached */ true);\n  t->Init();\n  asanThreadRegistry().StartThread(t->tid(), 0, 0);\n  SetCurrentThread(t);\n}\n}  // namespace\n\nINTERCEPTOR_WINAPI(DWORD, NtWaitForWorkViaWorkerFactory, DWORD a, DWORD b) {\n  // NtWaitForWorkViaWorkerFactory is called from system worker pool threads to\n  // query work scheduled by BindIoCompletionCallback, QueueUserWorkItem, etc.\n  // System worker pool threads are created at arbitraty point in time and\n  // without using CreateThread, so we wrap NtWaitForWorkViaWorkerFactory\n  // instead and don't register a specific parent_tid/stack.\n  EnsureWorkerThreadRegistered();\n  return REAL(NtWaitForWorkViaWorkerFactory)(a, b);\n}\n\n// }}}\n\nnamespace __asan {\n\nvoid InitializePlatformInterceptors() {\n  ASAN_INTERCEPT_FUNC(CreateThread);\n  ASAN_INTERCEPT_FUNC(RaiseException);\n  ASAN_INTERCEPT_FUNC(_except_handler3);\n  ASAN_INTERCEPT_FUNC(_except_handler4);\n\n  // NtWaitForWorkViaWorkerFactory is always linked dynamically.\n  CHECK(::__interception::OverrideFunction(\n      \"NtWaitForWorkViaWorkerFactory\",\n      (uptr)WRAP(NtWaitForWorkViaWorkerFactory),\n      (uptr *)&REAL(NtWaitForWorkViaWorkerFactory)));\n}\n\n// ---------------------- TSD ---------------- {{{\nstatic bool tsd_key_inited = false;\n\nstatic __declspec(thread) void *fake_tsd = 0;\n\nvoid AsanTSDInit(void (*destructor)(void *tsd)) {\n  // FIXME: we're ignoring the destructor for now.\n  tsd_key_inited = true;\n}\n\nvoid *AsanTSDGet() {\n  CHECK(tsd_key_inited);\n  return fake_tsd;\n}\n\nvoid AsanTSDSet(void *tsd) {\n  CHECK(tsd_key_inited);\n  fake_tsd = tsd;\n}\n\nvoid PlatformTSDDtor(void *tsd) {\n  AsanThread::TSDDtor(tsd);\n}\n// }}}\n\n// ---------------------- Various stuff ---------------- {{{\nvoid *AsanDoesNotSupportStaticLinkage() {\n#if defined(_DEBUG)\n#error Please build the runtime with a non-debug CRT: /MD or /MT\n#endif\n  return 0;\n}\n\nvoid AsanCheckDynamicRTPrereqs() {}\n\nvoid AsanCheckIncompatibleRT() {}\n\nvoid ReadContextStack(void *context, uptr *stack, uptr *ssize) {\n  UNIMPLEMENTED();\n}\n\nvoid AsanOnDeadlySignal(int, void *siginfo, void *context) {\n  UNIMPLEMENTED();\n}\n\nstatic LPTOP_LEVEL_EXCEPTION_FILTER default_seh_handler;\n\nstatic long WINAPI SEHHandler(EXCEPTION_POINTERS *info) {\n  EXCEPTION_RECORD *exception_record = info->ExceptionRecord;\n  CONTEXT *context = info->ContextRecord;\n\n  if (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ||\n      exception_record->ExceptionCode == EXCEPTION_IN_PAGE_ERROR) {\n    const char *description =\n        (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)\n            ? \"access-violation\"\n            : \"in-page-error\";\n    SignalContext sig = SignalContext::Create(exception_record, context);\n    ReportDeadlySignal(description, sig);\n  }\n\n  // FIXME: Handle EXCEPTION_STACK_OVERFLOW here.\n\n  return default_seh_handler(info);\n}\n\n// We want to install our own exception handler (EH) to print helpful reports\n// on access violations and whatnot.  Unfortunately, the CRT initializers assume\n// they are run before any user code and drop any previously-installed EHs on\n// the floor, so we can't install our handler inside __asan_init.\n// (See crt0dat.c in the CRT sources for the details)\n//\n// Things get even more complicated with the dynamic runtime, as it finishes its\n// initialization before the .exe module CRT begins to initialize.\n//\n// For the static runtime (-MT), it's enough to put a callback to\n// __asan_set_seh_filter in the last section for C initializers.\n//\n// For the dynamic runtime (-MD), we want link the same\n// asan_dynamic_runtime_thunk.lib to all the modules, thus __asan_set_seh_filter\n// will be called for each instrumented module.  This ensures that at least one\n// __asan_set_seh_filter call happens after the .exe module CRT is initialized.\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nint __asan_set_seh_filter() {\n  // We should only store the previous handler if it's not our own handler in\n  // order to avoid loops in the EH chain.\n  auto prev_seh_handler = SetUnhandledExceptionFilter(SEHHandler);\n  if (prev_seh_handler != &SEHHandler)\n    default_seh_handler = prev_seh_handler;\n  return 0;\n}\n\n#if !ASAN_DYNAMIC\n// Put a pointer to __asan_set_seh_filter at the end of the global list\n// of C initializers, after the default EH is set by the CRT.\n#pragma section(\".CRT$XIZ\", long, read)  // NOLINT\n__declspec(allocate(\".CRT$XIZ\"))\n    int (*__intercept_seh)() = __asan_set_seh_filter;\n#endif\n// }}}\n}  // namespace __asan\n\n#endif  // _WIN32\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_win_dll_thunk.cc",
    "content": "//===-- asan_win_dll_thunk.cc ---------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// This file defines a family of thunks that should be statically linked into\n// the DLLs that have ASan instrumentation in order to delegate the calls to the\n// shared runtime that lives in the main binary.\n// See https://github.com/google/sanitizers/issues/209 for the details.\n//===----------------------------------------------------------------------===//\n\n// Only compile this code when buidling asan_dll_thunk.lib\n// Using #ifdef rather than relying on Makefiles etc.\n// simplifies the build procedure.\n#ifdef ASAN_DLL_THUNK\n#include \"asan_init_version.h\"\n#include \"interception/interception.h\"\n\n// ---------- Function interception helper functions and macros ----------- {{{1\nextern \"C\" {\nvoid *__stdcall GetModuleHandleA(const char *module_name);\nvoid *__stdcall GetProcAddress(void *module, const char *proc_name);\nvoid abort();\n}\n\nstatic uptr getRealProcAddressOrDie(const char *name) {\n  uptr ret =\n      __interception::InternalGetProcAddress((void *)GetModuleHandleA(0), name);\n  if (!ret)\n    abort();\n  return ret;\n}\n\n// We need to intercept some functions (e.g. ASan interface, memory allocator --\n// let's call them \"hooks\") exported by the DLL thunk and forward the hooks to\n// the runtime in the main module.\n// However, we don't want to keep two lists of these hooks.\n// To avoid that, the list of hooks should be defined using the\n// INTERCEPT_WHEN_POSSIBLE macro. Then, all these hooks can be intercepted\n// at once by calling INTERCEPT_HOOKS().\n\n// Use macro+template magic to automatically generate the list of hooks.\n// Each hook at line LINE defines a template class with a static\n// FunctionInterceptor<LINE>::Execute() method intercepting the hook.\n// The default implementation of FunctionInterceptor<LINE> is to call\n// the Execute() method corresponding to the previous line.\ntemplate<int LINE>\nstruct FunctionInterceptor {\n  static void Execute() { FunctionInterceptor<LINE-1>::Execute(); }\n};\n\n// There shouldn't be any hooks with negative definition line number.\ntemplate<>\nstruct FunctionInterceptor<0> {\n  static void Execute() {}\n};\n\n#define INTERCEPT_WHEN_POSSIBLE(main_function, dll_function)                   \\\n  template <> struct FunctionInterceptor<__LINE__> {                           \\\n    static void Execute() {                                                    \\\n      uptr wrapper = getRealProcAddressOrDie(main_function);                   \\\n      if (!__interception::OverrideFunction((uptr)dll_function, wrapper, 0))   \\\n        abort();                                                               \\\n      FunctionInterceptor<__LINE__ - 1>::Execute();                            \\\n    }                                                                          \\\n  };\n\n// Special case of hooks -- ASan own interface functions.  Those are only called\n// after __asan_init, thus an empty implementation is sufficient.\n#define INTERFACE_FUNCTION(name)                                               \\\n  extern \"C\" __declspec(noinline) void name() {                                \\\n    volatile int prevent_icf = (__LINE__ << 8); (void)prevent_icf;             \\\n    __debugbreak();                                                            \\\n  }                                                                            \\\n  INTERCEPT_WHEN_POSSIBLE(#name, name)\n\n// INTERCEPT_HOOKS must be used after the last INTERCEPT_WHEN_POSSIBLE.\n#define INTERCEPT_HOOKS FunctionInterceptor<__LINE__>::Execute\n\n// We can't define our own version of strlen etc. because that would lead to\n// link-time or even type mismatch errors.  Instead, we can declare a function\n// just to be able to get its address.  Me may miss the first few calls to the\n// functions since it can be called before __asan_init, but that would lead to\n// false negatives in the startup code before user's global initializers, which\n// isn't a big deal.\n#define INTERCEPT_LIBRARY_FUNCTION(name)                                       \\\n  extern \"C\" void name();                                                      \\\n  INTERCEPT_WHEN_POSSIBLE(WRAPPER_NAME(name), name)\n\n// Disable compiler warnings that show up if we declare our own version\n// of a compiler intrinsic (e.g. strlen).\n#pragma warning(disable: 4391)\n#pragma warning(disable: 4392)\n\nstatic void InterceptHooks();\n// }}}\n\n// ---------- Function wrapping helpers ----------------------------------- {{{1\n#define WRAP_V_V(name)                                                         \\\n  extern \"C\" void name() {                                                     \\\n    typedef void (*fntype)();                                                  \\\n    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \\\n    fn();                                                                      \\\n  }                                                                            \\\n  INTERCEPT_WHEN_POSSIBLE(#name, name);\n\n#define WRAP_V_W(name)                                                         \\\n  extern \"C\" void name(void *arg) {                                            \\\n    typedef void (*fntype)(void *arg);                                         \\\n    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \\\n    fn(arg);                                                                   \\\n  }                                                                            \\\n  INTERCEPT_WHEN_POSSIBLE(#name, name);\n\n#define WRAP_V_WW(name)                                                        \\\n  extern \"C\" void name(void *arg1, void *arg2) {                               \\\n    typedef void (*fntype)(void *, void *);                                    \\\n    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \\\n    fn(arg1, arg2);                                                            \\\n  }                                                                            \\\n  INTERCEPT_WHEN_POSSIBLE(#name, name);\n\n#define WRAP_V_WWW(name)                                                       \\\n  extern \"C\" void name(void *arg1, void *arg2, void *arg3) {                   \\\n    typedef void *(*fntype)(void *, void *, void *);                           \\\n    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \\\n    fn(arg1, arg2, arg3);                                                      \\\n  }                                                                            \\\n  INTERCEPT_WHEN_POSSIBLE(#name, name);\n\n#define WRAP_W_V(name)                                                         \\\n  extern \"C\" void *name() {                                                    \\\n    typedef void *(*fntype)();                                                 \\\n    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \\\n    return fn();                                                               \\\n  }                                                                            \\\n  INTERCEPT_WHEN_POSSIBLE(#name, name);\n\n#define WRAP_W_W(name)                                                         \\\n  extern \"C\" void *name(void *arg) {                                           \\\n    typedef void *(*fntype)(void *arg);                                        \\\n    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \\\n    return fn(arg);                                                            \\\n  }                                                                            \\\n  INTERCEPT_WHEN_POSSIBLE(#name, name);\n\n#define WRAP_W_WW(name)                                                        \\\n  extern \"C\" void *name(void *arg1, void *arg2) {                              \\\n    typedef void *(*fntype)(void *, void *);                                   \\\n    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \\\n    return fn(arg1, arg2);                                                     \\\n  }                                                                            \\\n  INTERCEPT_WHEN_POSSIBLE(#name, name);\n\n#define WRAP_W_WWW(name)                                                       \\\n  extern \"C\" void *name(void *arg1, void *arg2, void *arg3) {                  \\\n    typedef void *(*fntype)(void *, void *, void *);                           \\\n    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \\\n    return fn(arg1, arg2, arg3);                                               \\\n  }                                                                            \\\n  INTERCEPT_WHEN_POSSIBLE(#name, name);\n\n#define WRAP_W_WWWW(name)                                                      \\\n  extern \"C\" void *name(void *arg1, void *arg2, void *arg3, void *arg4) {      \\\n    typedef void *(*fntype)(void *, void *, void *, void *);                   \\\n    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \\\n    return fn(arg1, arg2, arg3, arg4);                                         \\\n  }                                                                            \\\n  INTERCEPT_WHEN_POSSIBLE(#name, name);\n\n#define WRAP_W_WWWWW(name)                                                     \\\n  extern \"C\" void *name(void *arg1, void *arg2, void *arg3, void *arg4,        \\\n                        void *arg5) {                                          \\\n    typedef void *(*fntype)(void *, void *, void *, void *, void *);           \\\n    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \\\n    return fn(arg1, arg2, arg3, arg4, arg5);                                   \\\n  }                                                                            \\\n  INTERCEPT_WHEN_POSSIBLE(#name, name);\n\n#define WRAP_W_WWWWWW(name)                                                    \\\n  extern \"C\" void *name(void *arg1, void *arg2, void *arg3, void *arg4,        \\\n                        void *arg5, void *arg6) {                              \\\n    typedef void *(*fntype)(void *, void *, void *, void *, void *, void *);   \\\n    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \\\n    return fn(arg1, arg2, arg3, arg4, arg5, arg6);                             \\\n  }                                                                            \\\n  INTERCEPT_WHEN_POSSIBLE(#name, name);\n// }}}\n\n// ----------------- ASan own interface functions --------------------\n// Don't use the INTERFACE_FUNCTION machinery for this function as we actually\n// want to call it in the __asan_init interceptor.\nWRAP_W_V(__asan_should_detect_stack_use_after_return)\n\nextern \"C\" {\n  int __asan_option_detect_stack_use_after_return;\n\n  // Manually wrap __asan_init as we need to initialize\n  // __asan_option_detect_stack_use_after_return afterwards.\n  void __asan_init() {\n    typedef void (*fntype)();\n    static fntype fn = 0;\n    // __asan_init is expected to be called by only one thread.\n    if (fn) return;\n\n    fn = (fntype)getRealProcAddressOrDie(\"__asan_init\");\n    fn();\n    __asan_option_detect_stack_use_after_return =\n        (__asan_should_detect_stack_use_after_return() != 0);\n\n    InterceptHooks();\n  }\n}\n\nextern \"C\" void __asan_version_mismatch_check() {\n  // Do nothing.\n}\n\nINTERFACE_FUNCTION(__asan_handle_no_return)\n\nINTERFACE_FUNCTION(__asan_report_store1)\nINTERFACE_FUNCTION(__asan_report_store2)\nINTERFACE_FUNCTION(__asan_report_store4)\nINTERFACE_FUNCTION(__asan_report_store8)\nINTERFACE_FUNCTION(__asan_report_store16)\nINTERFACE_FUNCTION(__asan_report_store_n)\n\nINTERFACE_FUNCTION(__asan_report_load1)\nINTERFACE_FUNCTION(__asan_report_load2)\nINTERFACE_FUNCTION(__asan_report_load4)\nINTERFACE_FUNCTION(__asan_report_load8)\nINTERFACE_FUNCTION(__asan_report_load16)\nINTERFACE_FUNCTION(__asan_report_load_n)\n\nINTERFACE_FUNCTION(__asan_store1)\nINTERFACE_FUNCTION(__asan_store2)\nINTERFACE_FUNCTION(__asan_store4)\nINTERFACE_FUNCTION(__asan_store8)\nINTERFACE_FUNCTION(__asan_store16)\nINTERFACE_FUNCTION(__asan_storeN)\n\nINTERFACE_FUNCTION(__asan_load1)\nINTERFACE_FUNCTION(__asan_load2)\nINTERFACE_FUNCTION(__asan_load4)\nINTERFACE_FUNCTION(__asan_load8)\nINTERFACE_FUNCTION(__asan_load16)\nINTERFACE_FUNCTION(__asan_loadN)\n\nINTERFACE_FUNCTION(__asan_memcpy);\nINTERFACE_FUNCTION(__asan_memset);\nINTERFACE_FUNCTION(__asan_memmove);\n\nINTERFACE_FUNCTION(__asan_alloca_poison);\nINTERFACE_FUNCTION(__asan_allocas_unpoison);\n\nINTERFACE_FUNCTION(__asan_register_globals)\nINTERFACE_FUNCTION(__asan_unregister_globals)\n\nINTERFACE_FUNCTION(__asan_before_dynamic_init)\nINTERFACE_FUNCTION(__asan_after_dynamic_init)\n\nINTERFACE_FUNCTION(__asan_poison_stack_memory)\nINTERFACE_FUNCTION(__asan_unpoison_stack_memory)\n\nINTERFACE_FUNCTION(__asan_poison_memory_region)\nINTERFACE_FUNCTION(__asan_unpoison_memory_region)\n\nINTERFACE_FUNCTION(__asan_address_is_poisoned)\nINTERFACE_FUNCTION(__asan_region_is_poisoned)\n\nINTERFACE_FUNCTION(__asan_get_current_fake_stack)\nINTERFACE_FUNCTION(__asan_addr_is_in_fake_stack)\n\nINTERFACE_FUNCTION(__asan_stack_malloc_0)\nINTERFACE_FUNCTION(__asan_stack_malloc_1)\nINTERFACE_FUNCTION(__asan_stack_malloc_2)\nINTERFACE_FUNCTION(__asan_stack_malloc_3)\nINTERFACE_FUNCTION(__asan_stack_malloc_4)\nINTERFACE_FUNCTION(__asan_stack_malloc_5)\nINTERFACE_FUNCTION(__asan_stack_malloc_6)\nINTERFACE_FUNCTION(__asan_stack_malloc_7)\nINTERFACE_FUNCTION(__asan_stack_malloc_8)\nINTERFACE_FUNCTION(__asan_stack_malloc_9)\nINTERFACE_FUNCTION(__asan_stack_malloc_10)\n\nINTERFACE_FUNCTION(__asan_stack_free_0)\nINTERFACE_FUNCTION(__asan_stack_free_1)\nINTERFACE_FUNCTION(__asan_stack_free_2)\nINTERFACE_FUNCTION(__asan_stack_free_4)\nINTERFACE_FUNCTION(__asan_stack_free_5)\nINTERFACE_FUNCTION(__asan_stack_free_6)\nINTERFACE_FUNCTION(__asan_stack_free_7)\nINTERFACE_FUNCTION(__asan_stack_free_8)\nINTERFACE_FUNCTION(__asan_stack_free_9)\nINTERFACE_FUNCTION(__asan_stack_free_10)\n\n// FIXME: we might want to have a sanitizer_win_dll_thunk?\nINTERFACE_FUNCTION(__sanitizer_annotate_contiguous_container)\nINTERFACE_FUNCTION(__sanitizer_contiguous_container_find_bad_address)\nINTERFACE_FUNCTION(__sanitizer_cov)\nINTERFACE_FUNCTION(__sanitizer_cov_dump)\nINTERFACE_FUNCTION(__sanitizer_cov_indir_call16)\nINTERFACE_FUNCTION(__sanitizer_cov_init)\nINTERFACE_FUNCTION(__sanitizer_cov_module_init)\nINTERFACE_FUNCTION(__sanitizer_cov_trace_basic_block)\nINTERFACE_FUNCTION(__sanitizer_cov_trace_func_enter)\nINTERFACE_FUNCTION(__sanitizer_cov_trace_cmp)\nINTERFACE_FUNCTION(__sanitizer_cov_trace_switch)\nINTERFACE_FUNCTION(__sanitizer_cov_with_check)\nINTERFACE_FUNCTION(__sanitizer_get_allocated_size)\nINTERFACE_FUNCTION(__sanitizer_get_coverage_guards)\nINTERFACE_FUNCTION(__sanitizer_get_current_allocated_bytes)\nINTERFACE_FUNCTION(__sanitizer_get_estimated_allocated_size)\nINTERFACE_FUNCTION(__sanitizer_get_free_bytes)\nINTERFACE_FUNCTION(__sanitizer_get_heap_size)\nINTERFACE_FUNCTION(__sanitizer_get_ownership)\nINTERFACE_FUNCTION(__sanitizer_get_total_unique_caller_callee_pairs)\nINTERFACE_FUNCTION(__sanitizer_get_total_unique_coverage)\nINTERFACE_FUNCTION(__sanitizer_get_unmapped_bytes)\nINTERFACE_FUNCTION(__sanitizer_maybe_open_cov_file)\nINTERFACE_FUNCTION(__sanitizer_print_stack_trace)\nINTERFACE_FUNCTION(__sanitizer_ptr_cmp)\nINTERFACE_FUNCTION(__sanitizer_ptr_sub)\nINTERFACE_FUNCTION(__sanitizer_report_error_summary)\nINTERFACE_FUNCTION(__sanitizer_reset_coverage)\nINTERFACE_FUNCTION(__sanitizer_get_number_of_counters)\nINTERFACE_FUNCTION(__sanitizer_update_counter_bitset_and_clear_counters)\nINTERFACE_FUNCTION(__sanitizer_sandbox_on_notify)\nINTERFACE_FUNCTION(__sanitizer_set_death_callback)\nINTERFACE_FUNCTION(__sanitizer_set_report_path)\nINTERFACE_FUNCTION(__sanitizer_unaligned_load16)\nINTERFACE_FUNCTION(__sanitizer_unaligned_load32)\nINTERFACE_FUNCTION(__sanitizer_unaligned_load64)\nINTERFACE_FUNCTION(__sanitizer_unaligned_store16)\nINTERFACE_FUNCTION(__sanitizer_unaligned_store32)\nINTERFACE_FUNCTION(__sanitizer_unaligned_store64)\nINTERFACE_FUNCTION(__sanitizer_verify_contiguous_container)\n\n// TODO(timurrrr): Add more interface functions on the as-needed basis.\n\n// ----------------- Memory allocation functions ---------------------\nWRAP_V_W(free)\nWRAP_V_WW(_free_dbg)\n\nWRAP_W_W(malloc)\nWRAP_W_WWWW(_malloc_dbg)\n\nWRAP_W_WW(calloc)\nWRAP_W_WWWWW(_calloc_dbg)\nWRAP_W_WWW(_calloc_impl)\n\nWRAP_W_WW(realloc)\nWRAP_W_WWW(_realloc_dbg)\nWRAP_W_WWW(_recalloc)\n\nWRAP_W_W(_msize)\nWRAP_W_W(_expand)\nWRAP_W_W(_expand_dbg)\n\n// TODO(timurrrr): Might want to add support for _aligned_* allocation\n// functions to detect a bit more bugs.  Those functions seem to wrap malloc().\n\n// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cc).\n\nINTERCEPT_LIBRARY_FUNCTION(atoi);\nINTERCEPT_LIBRARY_FUNCTION(atol);\nINTERCEPT_LIBRARY_FUNCTION(_except_handler3);\n\n// _except_handler4 checks -GS cookie which is different for each module, so we\n// can't use INTERCEPT_LIBRARY_FUNCTION(_except_handler4).\nINTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {\n  __asan_handle_no_return();\n  return REAL(_except_handler4)(a, b, c, d);\n}\n\nINTERCEPT_LIBRARY_FUNCTION(frexp);\nINTERCEPT_LIBRARY_FUNCTION(longjmp);\nINTERCEPT_LIBRARY_FUNCTION(memchr);\nINTERCEPT_LIBRARY_FUNCTION(memcmp);\nINTERCEPT_LIBRARY_FUNCTION(memcpy);\nINTERCEPT_LIBRARY_FUNCTION(memmove);\nINTERCEPT_LIBRARY_FUNCTION(memset);\nINTERCEPT_LIBRARY_FUNCTION(strcat);  // NOLINT\nINTERCEPT_LIBRARY_FUNCTION(strchr);\nINTERCEPT_LIBRARY_FUNCTION(strcmp);\nINTERCEPT_LIBRARY_FUNCTION(strcpy);  // NOLINT\nINTERCEPT_LIBRARY_FUNCTION(strcspn);\nINTERCEPT_LIBRARY_FUNCTION(strlen);\nINTERCEPT_LIBRARY_FUNCTION(strncat);\nINTERCEPT_LIBRARY_FUNCTION(strncmp);\nINTERCEPT_LIBRARY_FUNCTION(strncpy);\nINTERCEPT_LIBRARY_FUNCTION(strnlen);\nINTERCEPT_LIBRARY_FUNCTION(strpbrk);\nINTERCEPT_LIBRARY_FUNCTION(strspn);\nINTERCEPT_LIBRARY_FUNCTION(strstr);\nINTERCEPT_LIBRARY_FUNCTION(strtol);\nINTERCEPT_LIBRARY_FUNCTION(wcslen);\n\n// Must be after all the interceptor declarations due to the way INTERCEPT_HOOKS\n// is defined.\nvoid InterceptHooks() {\n  INTERCEPT_HOOKS();\n  INTERCEPT_FUNCTION(_except_handler4);\n}\n\n// We want to call __asan_init before C/C++ initializers/constructors are\n// executed, otherwise functions like memset might be invoked.\n// For some strange reason, merely linking in asan_preinit.cc doesn't work\n// as the callback is never called...  Is link.exe doing something too smart?\n\n// In DLLs, the callbacks are expected to return 0,\n// otherwise CRT initialization fails.\nstatic int call_asan_init() {\n  __asan_init();\n  return 0;\n}\n#pragma section(\".CRT$XIB\", long, read)  // NOLINT\n__declspec(allocate(\".CRT$XIB\")) int (*__asan_preinit)() = call_asan_init;\n\n#endif // ASAN_DLL_THUNK\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cc",
    "content": "//===-- asan_win_uar_thunk.cc ---------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// This file defines things that need to be present in the application modules\n// to interact with the ASan DLL runtime correctly and can't be implemented\n// using the default \"import library\" generated when linking the DLL RTL.\n//\n// This includes:\n//  - forwarding the detect_stack_use_after_return runtime option\n//  - working around deficiencies of the MD runtime\n//  - installing a custom SEH handlerx\n//\n//===----------------------------------------------------------------------===//\n\n// Only compile this code when buidling asan_dynamic_runtime_thunk.lib\n// Using #ifdef rather than relying on Makefiles etc.\n// simplifies the build procedure.\n#ifdef ASAN_DYNAMIC_RUNTIME_THUNK\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n\n// First, declare CRT sections we'll be using in this file\n#pragma section(\".CRT$XID\", long, read)  // NOLINT\n#pragma section(\".CRT$XIZ\", long, read)  // NOLINT\n#pragma section(\".CRT$XTW\", long, read)  // NOLINT\n#pragma section(\".CRT$XTY\", long, read)  // NOLINT\n\n////////////////////////////////////////////////////////////////////////////////\n// Define a copy of __asan_option_detect_stack_use_after_return that should be\n// used when linking an MD runtime with a set of object files on Windows.\n//\n// The ASan MD runtime dllexports '__asan_option_detect_stack_use_after_return',\n// so normally we would just dllimport it.  Unfortunately, the dllimport\n// attribute adds __imp_ prefix to the symbol name of a variable.\n// Since in general we don't know if a given TU is going to be used\n// with a MT or MD runtime and we don't want to use ugly __imp_ names on Windows\n// just to work around this issue, let's clone the a variable that is\n// constant after initialization anyways.\nextern \"C\" {\n__declspec(dllimport) int __asan_should_detect_stack_use_after_return();\nint __asan_option_detect_stack_use_after_return =\n    __asan_should_detect_stack_use_after_return();\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// For some reason, the MD CRT doesn't call the C/C++ terminators during on DLL\n// unload or on exit.  ASan relies on LLVM global_dtors to call\n// __asan_unregister_globals on these events, which unfortunately doesn't work\n// with the MD runtime, see PR22545 for the details.\n// To work around this, for each DLL we schedule a call to UnregisterGlobals\n// using atexit() that calls a small subset of C terminators\n// where LLVM global_dtors is placed.  Fingers crossed, no other C terminators\n// are there.\nextern \"C\" int __cdecl atexit(void (__cdecl *f)(void));\nextern \"C\" void __cdecl _initterm(void *a, void *b);\n\nnamespace {\n__declspec(allocate(\".CRT$XTW\")) void* before_global_dtors = 0;\n__declspec(allocate(\".CRT$XTY\")) void* after_global_dtors = 0;\n\nvoid UnregisterGlobals() {\n  _initterm(&before_global_dtors, &after_global_dtors);\n}\n\nint ScheduleUnregisterGlobals() {\n  return atexit(UnregisterGlobals);\n}\n\n// We need to call 'atexit(UnregisterGlobals);' as early as possible, but after\n// atexit() is initialized (.CRT$XIC).  As this is executed before C++\n// initializers (think ctors for globals), UnregisterGlobals gets executed after\n// dtors for C++ globals.\n__declspec(allocate(\".CRT$XID\"))\nint (*__asan_schedule_unregister_globals)() = ScheduleUnregisterGlobals;\n\n}  // namespace\n\n////////////////////////////////////////////////////////////////////////////////\n// ASan SEH handling.\n// We need to set the ASan-specific SEH handler at the end of CRT initialization\n// of each module (see also asan_win.cc).\nextern \"C\" {\n__declspec(dllimport) int __asan_set_seh_filter();\nstatic int SetSEHFilter() { return __asan_set_seh_filter(); }\n\n// Unfortunately, putting a pointer to __asan_set_seh_filter into\n// __asan_intercept_seh gets optimized out, so we have to use an extra function.\n__declspec(allocate(\".CRT$XIZ\")) int (*__asan_seh_interceptor)() = SetSEHFilter;\n}\n\n#endif // ASAN_DYNAMIC_RUNTIME_THUNK\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/asanwrapper.cc",
    "content": "#include <elf.h>\n#include <fcntl.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#include <string>\n\nvoid usage(const char* me) {\n  static const char* usage_s = \"Usage:\\n\"\n    \"  %s /system/bin/app_process <args>\\n\"\n    \"or, better:\\n\"\n    \"  setprop wrap.<nicename> %s\\n\";\n  fprintf(stderr, usage_s, me, me);\n  exit(1);\n}\n\nvoid env_prepend(const char* name, const char* value, const char* delim) {\n  const char* value_old = getenv(name);\n  std::string value_new = value;\n  if (value_old) {\n    value_new += delim;\n    value_new += value_old;\n  }\n  setenv(name, value_new.c_str(), 1);\n}\n\nbool elf_is_64bit(const char* path) {\n  int fd = open(path, O_RDONLY);\n  if (fd == -1) return false;\n\n  const size_t kBufSize = EI_CLASS + 1;\n  char buf[kBufSize];\n  ssize_t sz = read(fd, buf, kBufSize);\n  if (sz != kBufSize) {\n    close(fd);\n    return false;\n  }\n\n  if (buf[EI_MAG0] != ELFMAG0 || buf[EI_MAG1] != ELFMAG1 ||\n      buf[EI_MAG2] != ELFMAG2 || buf[EI_MAG3] != ELFMAG3)\n    return false;\n\n  bool is_64bit = buf[EI_CLASS] == ELFCLASS64;\n  close(fd);\n  return is_64bit;\n}\n\nint main(int argc, char** argv) {\n  if (argc < 2) {\n    usage(argv[0]);\n  }\n  char** args = new char*[argc];\n  // If we are wrapping app_process, replace it with app_process_asan.\n  // TODO(eugenis): rewrite to <dirname>/asan/<basename>, if exists?\n  if (strcmp(argv[1], \"/system/bin/app_process\") == 0) {\n    args[0] = (char*)\"/system/bin/asan/app_process\";\n  } else if (strcmp(argv[1], \"/system/bin/app_process32\") == 0) {\n    args[0] = (char*)\"/system/bin/asan/app_process32\";\n  } else if (strcmp(argv[1], \"/system/bin/app_process64\") == 0) {\n    args[0] = (char*)\"/system/bin/asan/app_process64\";\n  } else {\n    args[0] = argv[1];\n  }\n\n  for (int i = 1; i < argc - 1; ++i)\n    args[i] = argv[i + 1];\n  args[argc - 1] = 0;\n\n  if (elf_is_64bit(args[0])) {\n    env_prepend(\"LD_LIBRARY_PATH\", \"/system/lib64/asan:/system/lib64\", \":\");\n  } else {\n    env_prepend(\"LD_LIBRARY_PATH\", \"/system/lib/asan:/system/lib\", \":\");\n  }\n  env_prepend(\"ASAN_OPTIONS\", \"allow_user_segv_handler=1\", \",\");\n\n  printf(\"ASAN_OPTIONS: %s\\n\", getenv(\"ASAN_OPTIONS\"));\n  printf(\"LD_LIBRARY_PATH: %s\\n\", getenv(\"LD_LIBRARY_PATH\"));\n  for (int i = 0; i < argc - 1; ++i)\n    printf(\"argv[%d] = %s\\n\", i, args[i]);\n\n  execv(args[0], args);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/scripts/CMakeLists.txt",
    "content": "if(ANDROID)\n  add_compiler_rt_script(asan_device_setup)\n  add_dependencies(asan asan_device_setup)\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/scripts/asan_device_setup",
    "content": "#!/bin/bash\n#===- lib/asan/scripts/asan_device_setup -----------------------------------===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n# Prepare Android device to run ASan applications.\n#\n#===------------------------------------------------------------------------===#\n\nset -e\n\nHERE=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\nrevert=no\nextra_options=\ndevice=\nlib=\nuse_su=0\n\nfunction usage {\n    echo \"usage: $0 [--revert] [--device device-id] [--lib path] [--extra-options options]\"\n    echo \"  --revert: Uninstall ASan from the device.\"\n    echo \"  --lib: Path to ASan runtime library.\"\n    echo \"  --extra-options: Extra ASAN_OPTIONS.\"\n    echo \"  --device: Install to the given device. Use 'adb devices' to find\"\n    echo \"            device-id.\"\n    echo \"  --use-su: Use 'su -c' prefix for every adb command instead of using\"\n    echo \"            'adb root' once.\"\n    echo\n    exit 1\n}\n\nfunction adb_push {\n  if [ $use_su -eq 0 ]; then\n    $ADB push \"$1\" \"$2\"\n  else\n    local FILENAME=$(basename $1)\n    $ADB push \"$1\" \"/data/local/tmp/$FILENAME\"\n    $ADB shell su -c \"rm \\\\\\\"$2/$FILENAME\\\\\\\"\" >&/dev/null\n    $ADB shell su -c \"cat \\\\\\\"/data/local/tmp/$FILENAME\\\\\\\" > \\\\\\\"$2/$FILENAME\\\\\\\"\"\n    $ADB shell su -c \"rm \\\\\\\"/data/local/tmp/$FILENAME\\\\\\\"\"\n  fi\n}\n\nfunction adb_remount {\n  if [ $use_su -eq 0 ]; then\n    $ADB remount\n  else\n    local STORAGE=`$ADB shell mount | grep /system | cut -d ' ' -f1`\n    if [ \"$STORAGE\" != \"\" ]; then\n      echo Remounting $STORAGE at /system\n      $ADB shell su -c \"mount -o remount,rw $STORAGE /system\"\n    else\n      echo Failed to get storage device name for \"/system\" mount point\n    fi\n  fi\n}\n\nfunction adb_shell {\n  if [ $use_su -eq 0 ]; then\n    $ADB shell $@\n  else\n    $ADB shell su -c \"$*\"\n  fi\n}\n\nfunction adb_root {\n  if [ $use_su -eq 0 ]; then\n    $ADB root\n  fi\n}\n\nfunction adb_wait_for_device {\n  $ADB wait-for-device\n}\n\nfunction adb_pull {\n  if [ $use_su -eq 0 ]; then\n    $ADB pull \"$1\" \"$2\"\n  else\n    local FILENAME=$(basename $1)\n    $ADB shell rm \"/data/local/tmp/$FILENAME\" >&/dev/null\n    $ADB shell su -c \"[ -f \\\\\\\"$1\\\\\\\" ] && cat \\\\\\\"$1\\\\\\\" > \\\\\\\"/data/local/tmp/$FILENAME\\\\\\\" && chown root.shell \\\\\\\"/data/local/tmp/$FILENAME\\\\\\\" && chmod 755 \\\\\\\"/data/local/tmp/$FILENAME\\\\\\\"\" &&\n    $ADB pull \"/data/local/tmp/$FILENAME\" \"$2\" >&/dev/null && $ADB shell \"rm \\\"/data/local/tmp/$FILENAME\\\"\"\n  fi\n}\n\nfunction get_device_arch { # OUT OUT64\n    local _outvar=$1\n    local _outvar64=$2\n    local _ABI=$(adb_shell getprop ro.product.cpu.abi)\n    local _ARCH=\n    local _ARCH64=\n    if [[ $_ABI == x86* ]]; then\n        _ARCH=i686\n    elif [[ $_ABI == armeabi* ]]; then\n        _ARCH=arm\n    elif [[ $_ABI == arm64-v8a* ]]; then\n        _ARCH=arm\n        _ARCH64=aarch64\n    else\n        echo \"Unrecognized device ABI: $_ABI\"\n        exit 1\n    fi\n    eval $_outvar=\\$_ARCH\n    eval $_outvar64=\\$_ARCH64\n}\n\nwhile [[ $# > 0 ]]; do\n  case $1 in\n    --revert)\n      revert=yes\n      ;;\n    --extra-options)\n      shift\n      if [[ $# == 0 ]]; then\n        echo \"--extra-options requires an argument.\"\n        exit 1\n      fi\n      extra_options=\"$1\"\n      ;;\n    --lib)\n      shift\n      if [[ $# == 0 ]]; then\n        echo \"--lib requires an argument.\"\n        exit 1\n      fi\n      lib=\"$1\"\n      ;;\n    --device)\n      shift\n      if [[ $# == 0 ]]; then\n        echo \"--device requires an argument.\"\n        exit 1\n      fi\n      device=\"$1\"\n      ;;\n    --use-su)\n      use_su=1\n      ;;\n    *)\n      usage\n      ;;\n  esac\n  shift\ndone\n\nADB=${ADB:-adb}\nif [[ x$device != x ]]; then\n    ADB=\"$ADB -s $device\"\nfi\n\nif [ $use_su -eq 1 ]; then\n  # Test if 'su' is present on the device\n  SU_TEST_OUT=`$ADB shell su -c \"echo foo\" 2>&1 | sed 's/\\r$//'`\n  if [ $? != 0 -o \"$SU_TEST_OUT\" != \"foo\" ]; then\n    echo \"ERROR: Cannot use 'su -c':\"\n    echo \"$ adb shell su -c \\\"echo foo\\\"\"\n    echo $SU_TEST_OUT\n    echo \"Check that 'su' binary is correctly installed on the device or omit\"\n    echo \"            --use-su flag\"\n    exit 1\n  fi\nfi\n\necho '>> Remounting /system rw'\nadb_wait_for_device\nadb_root\nadb_wait_for_device\nadb_remount\nadb_wait_for_device\n\nget_device_arch ARCH ARCH64\necho \"Target architecture: $ARCH\"\nASAN_RT=\"libclang_rt.asan-$ARCH-android.so\"\nif [[ -n $ARCH64 ]]; then\n  echo \"Target architecture: $ARCH64\"\n  ASAN_RT64=\"libclang_rt.asan-$ARCH64-android.so\"\nfi\n\nif [[ x$revert == xyes ]]; then\n    echo '>> Uninstalling ASan'\n\n    if ! adb_shell ls -l /system/bin/app_process | grep -o '\\->.*app_process' >&/dev/null; then\n      echo '>> Pre-L device detected.'\n      adb_shell mv /system/bin/app_process.real /system/bin/app_process\n      adb_shell rm /system/bin/asanwrapper\n    elif ! adb_shell ls -l /system/bin/app_process64.real | grep -o 'No such file or directory' >&/dev/null; then\n      # 64-bit installation.\n      adb_shell mv /system/bin/app_process32.real /system/bin/app_process32\n      adb_shell mv /system/bin/app_process64.real /system/bin/app_process64\n      adb_shell rm /system/bin/asanwrapper\n      adb_shell rm /system/bin/asanwrapper64\n    else\n      # 32-bit installation.\n      adb_shell rm /system/bin/app_process.wrap\n      adb_shell rm /system/bin/asanwrapper\n      adb_shell rm /system/bin/app_process\n      adb_shell ln -s /system/bin/app_process32 /system/bin/app_process\n    fi\n\n    echo '>> Restarting shell'\n    adb_shell stop\n    adb_shell start\n\n    # Remove the library on the last step to give a chance to the 'su' binary to\n    # be executed without problem.\n    adb_shell rm /system/lib/$ASAN_RT\n\n    echo '>> Done'\n    exit 0\nfi\n\nif [[ -d \"$lib\" ]]; then\n    ASAN_RT_PATH=\"$lib\"\nelif [[ -f \"$lib\" && \"$lib\" == *\"$ASAN_RT\" ]]; then\n    ASAN_RT_PATH=$(dirname \"$lib\")\nelif [[ -f \"$HERE/$ASAN_RT\" ]]; then\n    ASAN_RT_PATH=\"$HERE\"\nelif [[ $(basename \"$HERE\") == \"bin\" ]]; then\n    # We could be in the toolchain's base directory.\n    # Consider ../lib, ../lib/asan, ../lib/linux,\n    # ../lib/clang/$VERSION/lib/linux, and ../lib64/clang/$VERSION/lib/linux.\n    P=$(ls \"$HERE\"/../lib/\"$ASAN_RT\" \\\n           \"$HERE\"/../lib/asan/\"$ASAN_RT\" \\\n           \"$HERE\"/../lib/linux/\"$ASAN_RT\" \\\n           \"$HERE\"/../lib/clang/*/lib/linux/\"$ASAN_RT\" \\\n           \"$HERE\"/../lib64/clang/*/lib/linux/\"$ASAN_RT\" 2>/dev/null | sort | tail -1)\n    if [[ -n \"$P\" ]]; then\n        ASAN_RT_PATH=\"$(dirname \"$P\")\"\n    fi\nfi\n\nif [[ -z \"$ASAN_RT_PATH\" || ! -f \"$ASAN_RT_PATH/$ASAN_RT\" ]]; then\n    echo \">> ASan runtime library not found\"\n    exit 1\nfi\n\nif [[ -n \"$ASAN_RT64\" ]]; then\n  if [[ -z \"$ASAN_RT_PATH\" || ! -f \"$ASAN_RT_PATH/$ASAN_RT64\" ]]; then\n    echo \">> ASan runtime library not found\"\n    exit 1\n  fi\nfi\n\nTMPDIRBASE=$(mktemp -d)\nTMPDIROLD=\"$TMPDIRBASE/old\"\nTMPDIR=\"$TMPDIRBASE/new\"\nmkdir \"$TMPDIROLD\"\n\nRELEASE=$(adb_shell getprop ro.build.version.release)\nPRE_L=0\nif echo \"$RELEASE\" | grep '^4\\.' >&/dev/null; then\n    PRE_L=1\nfi\n\nif ! adb_shell ls -l /system/bin/app_process | grep -o '\\->.*app_process' >&/dev/null; then\n\n    if adb_pull /system/bin/app_process.real /dev/null >&/dev/null; then\n        echo '>> Old-style ASan installation detected. Reverting.'\n        adb_shell mv /system/bin/app_process.real /system/bin/app_process\n    fi\n\n    echo '>> Pre-L device detected. Setting up app_process symlink.'\n    adb_shell mv /system/bin/app_process /system/bin/app_process32\n    adb_shell ln -s /system/bin/app_process32 /system/bin/app_process\nfi\n\necho '>> Copying files from the device'\nif [[ -n \"$ASAN_RT64\" ]]; then\n  adb_pull /system/lib/\"$ASAN_RT\" \"$TMPDIROLD\" || true\n  adb_pull /system/lib64/\"$ASAN_RT64\" \"$TMPDIROLD\" || true\n  adb_pull /system/bin/app_process32 \"$TMPDIROLD\" || true\n  adb_pull /system/bin/app_process32.real \"$TMPDIROLD\" || true\n  adb_pull /system/bin/app_process64 \"$TMPDIROLD\" || true\n  adb_pull /system/bin/app_process64.real \"$TMPDIROLD\" || true\n  adb_pull /system/bin/asanwrapper \"$TMPDIROLD\" || true\n  adb_pull /system/bin/asanwrapper64 \"$TMPDIROLD\" || true\nelse\n  adb_pull /system/lib/\"$ASAN_RT\" \"$TMPDIROLD\" || true\n  adb_pull /system/bin/app_process32 \"$TMPDIROLD\" || true\n  adb_pull /system/bin/app_process.wrap \"$TMPDIROLD\" || true\n  adb_pull /system/bin/asanwrapper \"$TMPDIROLD\" || true\nfi\ncp -r \"$TMPDIROLD\" \"$TMPDIR\"\n\nif [[ -f \"$TMPDIR/app_process.wrap\" || -f \"$TMPDIR/app_process64.real\" ]]; then\n    echo \">> Previous installation detected\"\nelse\n    echo \">> New installation\"\nfi\n\necho '>> Generating wrappers'\n\ncp \"$ASAN_RT_PATH/$ASAN_RT\" \"$TMPDIR/\"\nif [[ -n \"$ASAN_RT64\" ]]; then\n  cp \"$ASAN_RT_PATH/$ASAN_RT64\" \"$TMPDIR/\"\nfi\n\n# FIXME: alloc_dealloc_mismatch=0 prevents a failure in libdvm startup,\n# which may or may not be a real bug (probably not).\nASAN_OPTIONS=start_deactivated=1,alloc_dealloc_mismatch=0,malloc_context_size=0\n\nfunction generate_zygote_wrapper { # from, to, asan_rt\n  local _from=$1\n  local _to=$2\n  local _asan_rt=$3\n  cat <<EOF >\"$TMPDIR/$_from\"\n#!/system/bin/sh-from-zygote\nASAN_OPTIONS=$ASAN_OPTIONS \\\\\nASAN_ACTIVATION_OPTIONS=include_if_exists=/data/local/tmp/asan.options.%b \\\\\nLD_PRELOAD=\\$LD_PRELOAD:$_asan_rt \\\\\nexec $_to \\$@\n\nEOF\n}\n\n# On Android-L not allowing user segv handler breaks some applications.\nif [[ PRE_L -eq 0 ]]; then\n    ASAN_OPTIONS=\"$ASAN_OPTIONS,allow_user_segv_handler=1\"\nfi\n\nif [[ x$extra_options != x ]] ; then\n    ASAN_OPTIONS=\"$ASAN_OPTIONS,$extra_options\"\nfi\n\n# Zygote wrapper.\nif [[ -f \"$TMPDIR/app_process64\" ]]; then\n  # A 64-bit device.\n  if [[ ! -f \"$TMPDIR/app_process64.real\" ]]; then\n    # New installation.\n    mv \"$TMPDIR/app_process32\" \"$TMPDIR/app_process32.real\"\n    mv \"$TMPDIR/app_process64\" \"$TMPDIR/app_process64.real\"\n  fi\n  generate_zygote_wrapper \"app_process32\" \"/system/bin/app_process32.real\" \"$ASAN_RT\"\n  generate_zygote_wrapper \"app_process64\" \"/system/bin/app_process64.real\" \"$ASAN_RT64\"\nelse\n  # A 32-bit device.\n  generate_zygote_wrapper \"app_process.wrap\" \"/system/bin/app_process32\" \"$ASAN_RT\"\nfi\n\n# General command-line tool wrapper (use for anything that's not started as\n# zygote).\ncat <<EOF >\"$TMPDIR/asanwrapper\"\n#!/system/bin/sh\nLD_PRELOAD=$ASAN_RT \\\\\nexec \\$@\n\nEOF\n\nif [[ -n \"$ASAN_RT64\" ]]; then\n  cat <<EOF >\"$TMPDIR/asanwrapper64\"\n#!/system/bin/sh\nLD_PRELOAD=$ASAN_RT64 \\\\\nexec \\$@\n\nEOF\nfi\n\nfunction install { # from, to, chmod, chcon\n  local _from=$1\n  local _to=$2\n  local _mode=$3\n  local _context=$4\n  local _basename=\"$(basename \"$_from\")\"\n  echo \"Installing $_to/$_basename $_mode $_context\"\n  adb_push \"$_from\" \"$_to/$_basename\"\n  adb_shell chown root.shell \"$_to/$_basename\"\n  if [[ -n \"$_mode\" ]]; then\n    adb_shell chmod \"$_mode\" \"$_to/$_basename\"\n  fi\n  if [[ -n \"$_context\" ]]; then\n    adb_shell chcon \"$_context\" \"$_to/$_basename\"\n  fi\n}\n\nif ! ( cd \"$TMPDIRBASE\" && diff -qr old/ new/ ) ; then\n    # Make SELinux happy by keeping app_process wrapper and the shell\n    # it runs on in zygote domain.\n    ENFORCING=0\n    if adb_shell getenforce | grep Enforcing >/dev/null; then\n        # Sometimes shell is not allowed to change file contexts.\n        # Temporarily switch to permissive.\n        ENFORCING=1\n        adb_shell setenforce 0\n    fi\n\n    if [[ PRE_L -eq 1 ]]; then\n        CTX=u:object_r:system_file:s0\n    else\n        CTX=u:object_r:zygote_exec:s0\n    fi\n\n    echo '>> Pushing files to the device'\n\n    if [[ -n \"$ASAN_RT64\" ]]; then\n      install \"$TMPDIR/$ASAN_RT\" /system/lib 644\n      install \"$TMPDIR/$ASAN_RT64\" /system/lib64 644\n      install \"$TMPDIR/app_process32\" /system/bin 755 $CTX\n      install \"$TMPDIR/app_process32.real\" /system/bin 755 $CTX\n      install \"$TMPDIR/app_process64\" /system/bin 755 $CTX\n      install \"$TMPDIR/app_process64.real\" /system/bin 755 $CTX\n      install \"$TMPDIR/asanwrapper\" /system/bin 755\n      install \"$TMPDIR/asanwrapper64\" /system/bin 755\n    else\n      install \"$TMPDIR/$ASAN_RT\" /system/lib 644\n      install \"$TMPDIR/app_process32\" /system/bin 755 $CTX\n      install \"$TMPDIR/app_process.wrap\" /system/bin 755 $CTX\n      install \"$TMPDIR/asanwrapper\" /system/bin 755 $CTX\n\n      adb_shell rm /system/bin/app_process\n      adb_shell ln -s /system/bin/app_process.wrap /system/bin/app_process\n    fi\n\n    adb_shell cp /system/bin/sh /system/bin/sh-from-zygote\n    adb_shell chcon $CTX /system/bin/sh-from-zygote\n\n    if [ $ENFORCING == 1 ]; then\n        adb_shell setenforce 1\n    fi\n\n    echo '>> Restarting shell (asynchronous)'\n    adb_shell stop\n    adb_shell start\n\n    echo '>> Please wait until the device restarts'\nelse\n    echo '>> Device is up to date'\nfi\n\nrm -r \"$TMPDIRBASE\"\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/scripts/asan_symbolize.py",
    "content": "#!/usr/bin/env python\n#===- lib/asan/scripts/asan_symbolize.py -----------------------------------===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\nimport argparse\nimport bisect\nimport getopt\nimport os\nimport re\nimport subprocess\nimport sys\n\nsymbolizers = {}\nDEBUG = False\ndemangle = False\nbinutils_prefix = None\nsysroot_path = None\nbinary_name_filter = None\nfix_filename_patterns = None\nlogfile = sys.stdin\nallow_system_symbolizer = True\n\n# FIXME: merge the code that calls fix_filename().\ndef fix_filename(file_name):\n  if fix_filename_patterns:\n    for path_to_cut in fix_filename_patterns:\n      file_name = re.sub('.*' + path_to_cut, '', file_name)\n  file_name = re.sub('.*asan_[a-z_]*.cc:[0-9]*', '_asan_rtl_', file_name)\n  file_name = re.sub('.*crtstuff.c:0', '???:0', file_name)\n  return file_name\n\ndef sysroot_path_filter(binary_name):\n  return sysroot_path + binary_name\n\ndef guess_arch(addr):\n  # Guess which arch we're running. 10 = len('0x') + 8 hex digits.\n  if len(addr) > 10:\n    return 'x86_64'\n  else:\n    return 'i386'\n\nclass Symbolizer(object):\n  def __init__(self):\n    pass\n\n  def symbolize(self, addr, binary, offset):\n    \"\"\"Symbolize the given address (pair of binary and offset).\n\n    Overriden in subclasses.\n    Args:\n        addr: virtual address of an instruction.\n        binary: path to executable/shared object containing this instruction.\n        offset: instruction offset in the @binary.\n    Returns:\n        list of strings (one string for each inlined frame) describing\n        the code locations for this instruction (that is, function name, file\n        name, line and column numbers).\n    \"\"\"\n    return None\n\n\nclass LLVMSymbolizer(Symbolizer):\n  def __init__(self, symbolizer_path, default_arch, system, dsym_hints=[]):\n    super(LLVMSymbolizer, self).__init__()\n    self.symbolizer_path = symbolizer_path\n    self.default_arch = default_arch\n    self.system = system\n    self.dsym_hints = dsym_hints\n    self.pipe = self.open_llvm_symbolizer()\n\n  def open_llvm_symbolizer(self):\n    cmd = [self.symbolizer_path,\n           '--use-symbol-table=true',\n           '--demangle=%s' % demangle,\n           '--functions=linkage',\n           '--inlining=true',\n           '--default-arch=%s' % self.default_arch]\n    if self.system == 'Darwin':\n      for hint in self.dsym_hints:\n        cmd.append('--dsym-hint=%s' % hint)\n    if DEBUG:\n      print ' '.join(cmd)\n    try:\n      result = subprocess.Popen(cmd, stdin=subprocess.PIPE,\n                                stdout=subprocess.PIPE)\n    except OSError:\n      result = None\n    return result\n\n  def symbolize(self, addr, binary, offset):\n    \"\"\"Overrides Symbolizer.symbolize.\"\"\"\n    if not self.pipe:\n      return None\n    result = []\n    try:\n      symbolizer_input = '\"%s\" %s' % (binary, offset)\n      if DEBUG:\n        print symbolizer_input\n      print >> self.pipe.stdin, symbolizer_input\n      while True:\n        function_name = self.pipe.stdout.readline().rstrip()\n        if not function_name:\n          break\n        file_name = self.pipe.stdout.readline().rstrip()\n        file_name = fix_filename(file_name)\n        if (not function_name.startswith('??') or\n            not file_name.startswith('??')):\n          # Append only non-trivial frames.\n          result.append('%s in %s %s' % (addr, function_name,\n                                         file_name))\n    except Exception:\n      result = []\n    if not result:\n      result = None\n    return result\n\n\ndef LLVMSymbolizerFactory(system, default_arch, dsym_hints=[]):\n  symbolizer_path = os.getenv('LLVM_SYMBOLIZER_PATH')\n  if not symbolizer_path:\n    symbolizer_path = os.getenv('ASAN_SYMBOLIZER_PATH')\n    if not symbolizer_path:\n      # Assume llvm-symbolizer is in PATH.\n      symbolizer_path = 'llvm-symbolizer'\n  return LLVMSymbolizer(symbolizer_path, default_arch, system, dsym_hints)\n\n\nclass Addr2LineSymbolizer(Symbolizer):\n  def __init__(self, binary):\n    super(Addr2LineSymbolizer, self).__init__()\n    self.binary = binary\n    self.pipe = self.open_addr2line()\n    self.output_terminator = -1\n\n  def open_addr2line(self):\n    addr2line_tool = 'addr2line'\n    if binutils_prefix:\n      addr2line_tool = binutils_prefix + addr2line_tool\n    cmd = [addr2line_tool, '-fi']\n    if demangle:\n      cmd += ['--demangle']\n    cmd += ['-e', self.binary]\n    if DEBUG:\n      print ' '.join(cmd)\n    return subprocess.Popen(cmd,\n                            stdin=subprocess.PIPE, stdout=subprocess.PIPE)\n\n  def symbolize(self, addr, binary, offset):\n    \"\"\"Overrides Symbolizer.symbolize.\"\"\"\n    if self.binary != binary:\n      return None\n    lines = []\n    try:\n      print >> self.pipe.stdin, offset\n      print >> self.pipe.stdin, self.output_terminator\n      is_first_frame = True\n      while True:\n        function_name = self.pipe.stdout.readline().rstrip()\n        file_name = self.pipe.stdout.readline().rstrip()\n        if is_first_frame:\n          is_first_frame = False\n        elif function_name in ['', '??']:\n          assert file_name == function_name\n          break\n        lines.append((function_name, file_name));\n    except Exception:\n      lines.append(('??', '??:0'))\n    return ['%s in %s %s' % (addr, function, fix_filename(file)) for (function, file) in lines]\n\nclass UnbufferedLineConverter(object):\n  \"\"\"\n  Wrap a child process that responds to each line of input with one line of\n  output.  Uses pty to trick the child into providing unbuffered output.\n  \"\"\"\n  def __init__(self, args, close_stderr=False):\n    # Local imports so that the script can start on Windows.\n    import pty\n    import termios\n    pid, fd = pty.fork()\n    if pid == 0:\n      # We're the child. Transfer control to command.\n      if close_stderr:\n        dev_null = os.open('/dev/null', 0)\n        os.dup2(dev_null, 2)\n      os.execvp(args[0], args)\n    else:\n      # Disable echoing.\n      attr = termios.tcgetattr(fd)\n      attr[3] = attr[3] & ~termios.ECHO\n      termios.tcsetattr(fd, termios.TCSANOW, attr)\n      # Set up a file()-like interface to the child process\n      self.r = os.fdopen(fd, \"r\", 1)\n      self.w = os.fdopen(os.dup(fd), \"w\", 1)\n\n  def convert(self, line):\n    self.w.write(line + \"\\n\")\n    return self.readline()\n\n  def readline(self):\n    return self.r.readline().rstrip()\n\n\nclass DarwinSymbolizer(Symbolizer):\n  def __init__(self, addr, binary):\n    super(DarwinSymbolizer, self).__init__()\n    self.binary = binary\n    self.arch = guess_arch(addr)\n    self.open_atos()\n\n  def open_atos(self):\n    if DEBUG:\n      print 'atos -o %s -arch %s' % (self.binary, self.arch)\n    cmdline = ['atos', '-o', self.binary, '-arch', self.arch]\n    self.atos = UnbufferedLineConverter(cmdline, close_stderr=True)\n\n  def symbolize(self, addr, binary, offset):\n    \"\"\"Overrides Symbolizer.symbolize.\"\"\"\n    if self.binary != binary:\n      return None\n    atos_line = self.atos.convert('0x%x' % int(offset, 16))\n    while \"got symbolicator for\" in atos_line:\n      atos_line = self.atos.readline()\n    # A well-formed atos response looks like this:\n    #   foo(type1, type2) (in object.name) (filename.cc:80)\n    match = re.match('^(.*) \\(in (.*)\\) \\((.*:\\d*)\\)$', atos_line)\n    if DEBUG:\n      print 'atos_line: ', atos_line\n    if match:\n      function_name = match.group(1)\n      function_name = re.sub('\\(.*?\\)', '', function_name)\n      file_name = fix_filename(match.group(3))\n      return ['%s in %s %s' % (addr, function_name, file_name)]\n    else:\n      return ['%s in %s' % (addr, atos_line)]\n\n\n# Chain several symbolizers so that if one symbolizer fails, we fall back\n# to the next symbolizer in chain.\nclass ChainSymbolizer(Symbolizer):\n  def __init__(self, symbolizer_list):\n    super(ChainSymbolizer, self).__init__()\n    self.symbolizer_list = symbolizer_list\n\n  def symbolize(self, addr, binary, offset):\n    \"\"\"Overrides Symbolizer.symbolize.\"\"\"\n    for symbolizer in self.symbolizer_list:\n      if symbolizer:\n        result = symbolizer.symbolize(addr, binary, offset)\n        if result:\n          return result\n    return None\n\n  def append_symbolizer(self, symbolizer):\n    self.symbolizer_list.append(symbolizer)\n\n\ndef BreakpadSymbolizerFactory(binary):\n  suffix = os.getenv('BREAKPAD_SUFFIX')\n  if suffix:\n    filename = binary + suffix\n    if os.access(filename, os.F_OK):\n      return BreakpadSymbolizer(filename)\n  return None\n\n\ndef SystemSymbolizerFactory(system, addr, binary):\n  if system == 'Darwin':\n    return DarwinSymbolizer(addr, binary)\n  elif system == 'Linux':\n    return Addr2LineSymbolizer(binary)\n\n\nclass BreakpadSymbolizer(Symbolizer):\n  def __init__(self, filename):\n    super(BreakpadSymbolizer, self).__init__()\n    self.filename = filename\n    lines = file(filename).readlines()\n    self.files = []\n    self.symbols = {}\n    self.address_list = []\n    self.addresses = {}\n    # MODULE mac x86_64 A7001116478B33F18FF9BEDE9F615F190 t\n    fragments = lines[0].rstrip().split()\n    self.arch = fragments[2]\n    self.debug_id = fragments[3]\n    self.binary = ' '.join(fragments[4:])\n    self.parse_lines(lines[1:])\n\n  def parse_lines(self, lines):\n    cur_function_addr = ''\n    for line in lines:\n      fragments = line.split()\n      if fragments[0] == 'FILE':\n        assert int(fragments[1]) == len(self.files)\n        self.files.append(' '.join(fragments[2:]))\n      elif fragments[0] == 'PUBLIC':\n        self.symbols[int(fragments[1], 16)] = ' '.join(fragments[3:])\n      elif fragments[0] in ['CFI', 'STACK']:\n        pass\n      elif fragments[0] == 'FUNC':\n        cur_function_addr = int(fragments[1], 16)\n        if not cur_function_addr in self.symbols.keys():\n          self.symbols[cur_function_addr] = ' '.join(fragments[4:])\n      else:\n        # Line starting with an address.\n        addr = int(fragments[0], 16)\n        self.address_list.append(addr)\n        # Tuple of symbol address, size, line, file number.\n        self.addresses[addr] = (cur_function_addr,\n                                int(fragments[1], 16),\n                                int(fragments[2]),\n                                int(fragments[3]))\n    self.address_list.sort()\n\n  def get_sym_file_line(self, addr):\n    key = None\n    if addr in self.addresses.keys():\n      key = addr\n    else:\n      index = bisect.bisect_left(self.address_list, addr)\n      if index == 0:\n        return None\n      else:\n        key = self.address_list[index - 1]\n    sym_id, size, line_no, file_no = self.addresses[key]\n    symbol = self.symbols[sym_id]\n    filename = self.files[file_no]\n    if addr < key + size:\n      return symbol, filename, line_no\n    else:\n      return None\n\n  def symbolize(self, addr, binary, offset):\n    if self.binary != binary:\n      return None\n    res = self.get_sym_file_line(int(offset, 16))\n    if res:\n      function_name, file_name, line_no = res\n      result = ['%s in %s %s:%d' % (\n          addr, function_name, file_name, line_no)]\n      print result\n      return result\n    else:\n      return None\n\n\nclass SymbolizationLoop(object):\n  def __init__(self, binary_name_filter=None, dsym_hint_producer=None):\n    if sys.platform == 'win32':\n      # ASan on Windows uses dbghelp.dll to symbolize in-process, which works\n      # even in sandboxed processes.  Nothing needs to be done here.\n      self.process_line = self.process_line_echo\n    else:\n      # Used by clients who may want to supply a different binary name.\n      # E.g. in Chrome several binaries may share a single .dSYM.\n      self.binary_name_filter = binary_name_filter\n      self.dsym_hint_producer = dsym_hint_producer\n      self.system = os.uname()[0]\n      if self.system not in ['Linux', 'Darwin', 'FreeBSD']:\n        raise Exception('Unknown system')\n      self.llvm_symbolizers = {}\n      self.last_llvm_symbolizer = None\n      self.dsym_hints = set([])\n      self.frame_no = 0\n      self.process_line = self.process_line_posix\n\n  def symbolize_address(self, addr, binary, offset):\n    # On non-Darwin (i.e. on platforms without .dSYM debug info) always use\n    # a single symbolizer binary.\n    # On Darwin, if the dsym hint producer is present:\n    #  1. check whether we've seen this binary already; if so,\n    #     use |llvm_symbolizers[binary]|, which has already loaded the debug\n    #     info for this binary (might not be the case for\n    #     |last_llvm_symbolizer|);\n    #  2. otherwise check if we've seen all the hints for this binary already;\n    #     if so, reuse |last_llvm_symbolizer| which has the full set of hints;\n    #  3. otherwise create a new symbolizer and pass all currently known\n    #     .dSYM hints to it.\n    if not binary in self.llvm_symbolizers:\n      use_new_symbolizer = True\n      if self.system == 'Darwin' and self.dsym_hint_producer:\n        dsym_hints_for_binary = set(self.dsym_hint_producer(binary))\n        use_new_symbolizer = bool(dsym_hints_for_binary - self.dsym_hints)\n        self.dsym_hints |= dsym_hints_for_binary\n      if self.last_llvm_symbolizer and not use_new_symbolizer:\n          self.llvm_symbolizers[binary] = self.last_llvm_symbolizer\n      else:\n        self.last_llvm_symbolizer = LLVMSymbolizerFactory(\n            self.system, guess_arch(addr), self.dsym_hints)\n        self.llvm_symbolizers[binary] = self.last_llvm_symbolizer\n    # Use the chain of symbolizers:\n    # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos\n    # (fall back to next symbolizer if the previous one fails).\n    if not binary in symbolizers:\n      symbolizers[binary] = ChainSymbolizer(\n          [BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]])\n    result = symbolizers[binary].symbolize(addr, binary, offset)\n    if result is None:\n      if not allow_system_symbolizer:\n        raise Exception('Failed to launch or use llvm-symbolizer.')\n      # Initialize system symbolizer only if other symbolizers failed.\n      symbolizers[binary].append_symbolizer(\n          SystemSymbolizerFactory(self.system, addr, binary))\n      result = symbolizers[binary].symbolize(addr, binary, offset)\n    # The system symbolizer must produce some result.\n    assert result\n    return result\n\n  def get_symbolized_lines(self, symbolized_lines):\n    if not symbolized_lines:\n      return [self.current_line]\n    else:\n      result = []\n      for symbolized_frame in symbolized_lines:\n        result.append('    #%s %s' % (str(self.frame_no), symbolized_frame.rstrip()))\n        self.frame_no += 1\n      return result\n\n  def process_logfile(self):\n    self.frame_no = 0\n    for line in logfile:\n      processed = self.process_line(line)\n      print '\\n'.join(processed)\n\n  def process_line_echo(self, line):\n    return [line.rstrip()]\n\n  def process_line_posix(self, line):\n    self.current_line = line.rstrip()\n    #0 0x7f6e35cf2e45  (/blah/foo.so+0x11fe45)\n    stack_trace_line_format = (\n        '^( *#([0-9]+) *)(0x[0-9a-f]+) *\\((.*)\\+(0x[0-9a-f]+)\\)')\n    match = re.match(stack_trace_line_format, line)\n    if not match:\n      return [self.current_line]\n    if DEBUG:\n      print line\n    _, frameno_str, addr, binary, offset = match.groups()\n    if frameno_str == '0':\n      # Assume that frame #0 is the first frame of new stack trace.\n      self.frame_no = 0\n    original_binary = binary\n    if self.binary_name_filter:\n      binary = self.binary_name_filter(binary)\n    symbolized_line = self.symbolize_address(addr, binary, offset)\n    if not symbolized_line:\n      if original_binary != binary:\n        symbolized_line = self.symbolize_address(addr, binary, offset)\n    return self.get_symbolized_lines(symbolized_line)\n\n\nif __name__ == '__main__':\n  parser = argparse.ArgumentParser(\n      formatter_class=argparse.RawDescriptionHelpFormatter,\n      description='ASan symbolization script',\n      epilog='Example of use:\\n'\n             'asan_symbolize.py -c \"$HOME/opt/cross/bin/arm-linux-gnueabi-\" '\n             '-s \"$HOME/SymbolFiles\" < asan.log')\n  parser.add_argument('path_to_cut', nargs='*',\n                      help='pattern to be cut from the result file path ')\n  parser.add_argument('-d','--demangle', action='store_true',\n                      help='demangle function names')\n  parser.add_argument('-s', metavar='SYSROOT',\n                      help='set path to sysroot for sanitized binaries')\n  parser.add_argument('-c', metavar='CROSS_COMPILE',\n                      help='set prefix for binutils')\n  parser.add_argument('-l','--logfile', default=sys.stdin,\n                      type=argparse.FileType('r'),\n                      help='set log file name to parse, default is stdin')\n  args = parser.parse_args()\n  if args.path_to_cut:\n    fix_filename_patterns = args.path_to_cut\n  if args.demangle:\n    demangle = True\n  if args.s:\n    binary_name_filter = sysroot_path_filter\n    sysroot_path = args.s\n  if args.c:\n    binutils_prefix = args.c\n  if args.logfile:\n    logfile = args.logfile\n  else:\n    logfile = sys.stdin\n  loop = SymbolizationLoop(binary_name_filter)\n  loop.process_logfile()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/scripts/symbolize.py",
    "content": "#!/usr/bin/env python\n#===- lib/asan/scripts/asan_symbolize.py -----------------------------------===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\nimport glob\nimport os\nimport re\nimport sys\nimport string\nimport subprocess\n\npipes = {}\nload_addresses = {}\nnext_inline_frameno = 0\n\ndef patch_address(frameno, addr_s):\n  ''' Subtracts 1 or 2 from the top frame's address.\n  Top frame is normally the return address from asan_report*\n  call, which is not expected to return at all. Because of that, this\n  address often belongs to the next source code line, or even to a different\n  function. '''\n  if frameno == '0':\n    addr = int(addr_s, 16)\n    if os.uname()[4].startswith('arm'):\n      # Cancel the Thumb bit\n      addr = addr & (~1)\n    addr -= 1\n    return hex(addr)\n  return addr_s\n\ndef android_get_load_address(path):\n  if load_addresses.has_key(path):\n    return load_addresses[path]\n  readelf_glob = os.path.join(os.environ['ANDROID_TOOLCHAIN'], '*-readelf')\n  readelf = glob.glob(readelf_glob)[0]\n  readelf_pipe = subprocess.Popen([readelf, \"-l\", path], stdin=subprocess.PIPE, stdout=subprocess.PIPE)\n  for line in readelf_pipe.stdout:\n      if ('LOAD' in line) and (' E ' in line):\n          match = re.match(r'\\s*LOAD\\s+0x[01-9a-zA-Z]+\\s+(0x[01-9a-zA-Z]+)', line, re.UNICODE)\n          if match:\n              load_addr = int(match.group(1), 16)\n              load_addresses[path] = load_addr\n              return load_addr\n          else: break\n  print 'Could not make sense of readelf output!'\n  sys.exit(1)\n\ndef postprocess_file_name(file_name, paths_to_cut):\n  for path_to_cut in paths_to_cut:\n    file_name = re.sub(\".*\" + path_to_cut, \"\", file_name)\n  file_name = re.sub(\".*asan_[a-z_]*.(cc|h):[0-9]*\", \"[asan_rtl]\", file_name)\n  file_name = re.sub(\".*crtstuff.c:0\", \"???:0\", file_name)\n  return file_name\n\n# TODO(glider): need some refactoring here\ndef symbolize_addr2line(line, binary_prefix, paths_to_cut):\n  global next_inline_frameno\n  # Strip the log prefix (\"I/asanwrapper( 1196): \").\n  line = re.sub(r'^.*?: ', '', line)\n  #0 0x7f6e35cf2e45  (/blah/foo.so+0x11fe45)\n  match = re.match(r'^(\\s*#)([0-9]+) *(0x[0-9a-f]+) *\\((.*)\\+(0x[0-9a-f]+)\\)', line, re.UNICODE)\n  if match:\n    frameno = match.group(2)\n    binary = match.group(4)\n    addr = match.group(5)\n    addr = patch_address(frameno, addr)\n\n    if binary.startswith('/'):\n      binary = binary[1:]\n    binary = os.path.join(binary_prefix, binary)\n\n    if not os.path.exists(binary):\n      print line.rstrip().encode('utf-8')\n      return\n\n    load_addr = android_get_load_address(binary)\n    addr = hex(int(addr, 16) + load_addr)\n\n    if not pipes.has_key(binary):\n      pipes[binary] = subprocess.Popen([\"addr2line\", \"-i\", \"-f\", \"-e\", binary],\n                         stdin=subprocess.PIPE, stdout=subprocess.PIPE)\n    p = pipes[binary]\n    frames = []\n    try:\n      print >>p.stdin, addr\n      # This will trigger a \"??\" response from addr2line so we know when to stop\n      print >>p.stdin\n      while True:\n        function_name = p.stdout.readline().rstrip()\n        file_name     = p.stdout.readline().rstrip()\n        if function_name in ['??', '']:\n          break\n        file_name = postprocess_file_name(file_name, paths_to_cut)\n        frames.append((function_name, file_name))\n    except:\n      pass\n    if not frames:\n      frames.append(('', ''))\n      # Consume another pair of \"??\" lines\n      try:\n        p.stdout.readline()\n        p.stdout.readline()\n      except:\n        pass\n    for frame in frames:\n      inline_frameno = next_inline_frameno\n      next_inline_frameno += 1\n      print \"%s%d\" % (match.group(1).encode('utf-8'), inline_frameno), \\\n          match.group(3).encode('utf-8'), \"in\", frame[0], frame[1]\n  else:\n    print line.rstrip().encode('utf-8')\n\n\nbinary_prefix = os.path.join(os.environ['ANDROID_PRODUCT_OUT'], 'symbols')\npaths_to_cut = [os.getcwd() + '/', os.environ['ANDROID_BUILD_TOP'] + '/'] + sys.argv[1:]\n\nfor line in sys.stdin:\n  line = line.decode('utf-8')\n  symbolize_addr2line(line, binary_prefix, paths_to_cut)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/CMakeLists.txt",
    "content": "# Testing rules for AddressSanitizer.\n#\n# These are broken into two buckets. One set of tests directly interacts with\n# the runtime library and checks its functionality. These are the\n# no-instrumentation tests.\n#\n# Another group of tests relies upon the ability to compile the test with\n# address sanitizer instrumentation pass. These tests form \"integration\" tests\n# and have some elements of version skew -- they test the *host* compiler's\n# instrumentation against the just-built runtime library.\n\ninclude(CheckCXXCompilerFlag)\ninclude(CompilerRTCompile)\n\ninclude_directories(..)\ninclude_directories(../..)\n\nset(ASAN_UNITTEST_HEADERS\n  asan_mac_test.h\n  asan_test_config.h\n  asan_test_utils.h)\n\nset(ASAN_UNITTEST_COMMON_CFLAGS\n  ${COMPILER_RT_TEST_CFLAGS}\n  ${COMPILER_RT_GTEST_CFLAGS}\n  -I${COMPILER_RT_SOURCE_DIR}/include\n  -I${COMPILER_RT_SOURCE_DIR}/lib\n  -I${COMPILER_RT_SOURCE_DIR}/lib/asan\n  -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests\n  -fno-rtti\n  -O2\n  -Wno-format\n  -Werror=sign-compare\n  -Wno-non-virtual-dtor)\nappend_list_if(COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG -Wno-variadic-macros ASAN_UNITTEST_COMMON_CFLAGS)\n\n# -gline-tables-only must be enough for ASan, so use it if possible.\nif(COMPILER_RT_TEST_COMPILER_ID MATCHES \"Clang\")\n  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only)\nelse()\n  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g)\nendif()\n\n# Use -D instead of definitions to please custom compile command.\nlist(APPEND ASAN_UNITTEST_COMMON_CFLAGS\n  -DASAN_HAS_BLACKLIST=1\n  -DASAN_HAS_EXCEPTIONS=1\n  -DASAN_UAR=0)\n\nif(APPLE)\n  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS ${DARWIN_osx_CFLAGS})\n  list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS ${DARWIN_osx_LINKFLAGS})\nendif()\n\nif(MSVC)\n  # Disable exceptions on Windows until they work reliably.\n  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -fno-exceptions -DGTEST_HAS_SEH=0)\nendif()\n\nset(ASAN_BLACKLIST_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore\")\nset(ASAN_UNITTEST_INSTRUMENTED_CFLAGS\n  ${ASAN_UNITTEST_COMMON_CFLAGS}\n  -fsanitize=address\n  \"-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}\"\n)\nif(CAN_TARGET_x86_64 OR CAN_TARGET_i386)\n  list(APPEND ASAN_UNITTEST_INSTRUMENTED_CFLAGS -mllvm -asan-instrument-assembly)\nendif()\n\nif(NOT MSVC)\n  list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS --driver-mode=g++)\nendif()\n\n# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests.\nif(CMAKE_SYSTEM MATCHES \"FreeBSD-9.2-RELEASE\")\n  list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS \"-lc++\")\nendif()\n\n# Unit tests on Mac depend on Foundation.\nif(APPLE)\n  list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -framework Foundation)\nendif()\nif(ANDROID)\n  list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -pie)\nendif()\n\nset(ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS\n  ${ASAN_UNITTEST_COMMON_LINKFLAGS})\nlist(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address)\n\nset(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS\n  ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}\n  -shared-libasan)\n\nset(ASAN_UNITTEST_INSTRUMENTED_LIBS)\n# NDK r10 requires -latomic almost always.\nappend_list_if(ANDROID atomic ASAN_UNITTEST_INSTRUMENTED_LIBS)\n\nset(ASAN_UNITTEST_NOINST_LINKFLAGS ${ASAN_UNITTEST_COMMON_LINKFLAGS})\nappend_list_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINKFLAGS)\nappend_list_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINKFLAGS)\nappend_list_if(COMPILER_RT_HAS_LIBRT -lrt ASAN_UNITTEST_NOINST_LINKFLAGS)\nappend_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINKFLAGS)\nappend_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread\n          ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS)\n\n# TODO(eugenis): move all -l flags above to _LIBS?\nset(ASAN_UNITTEST_NOINST_LIBS)\nappend_list_if(ANDROID log ASAN_UNITTEST_NOINST_LIBS)\n# NDK r10 requires -latomic almost always.\nappend_list_if(ANDROID atomic ASAN_UNITTEST_NOINST_LIBS)\n\n# Compile source for the given architecture, using compiler\n# options in ${ARGN}, and add it to the object list.\nmacro(asan_compile obj_list source arch kind)\n  get_filename_component(basename ${source} NAME)\n  set(output_obj \"${obj_list}.${basename}.${arch}${kind}.o\")\n  get_target_flags_for_arch(${arch} TARGET_CFLAGS)\n  set(COMPILE_DEPS ${ASAN_UNITTEST_HEADERS} ${ASAN_BLACKLIST_FILE})\n  if(NOT COMPILER_RT_STANDALONE_BUILD)\n    list(APPEND COMPILE_DEPS gtest asan)\n  endif()\n  clang_compile(${output_obj} ${source}\n                CFLAGS ${ARGN} ${TARGET_CFLAGS}\n                DEPS ${COMPILE_DEPS})\n  list(APPEND ${obj_list} ${output_obj})\nendmacro()\n\n# Link ASan unit test for a given architecture from a set\n# of objects in with given linker flags.\nmacro(add_asan_test test_suite test_name arch kind)\n  parse_arguments(TEST \"OBJECTS;LINKFLAGS;SUBDIR\" \"WITH_TEST_RUNTIME\" ${ARGN})\n  get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)\n  set(TEST_DEPS ${TEST_OBJECTS})\n  if(NOT COMPILER_RT_STANDALONE_BUILD)\n    list(APPEND TEST_DEPS asan)\n  endif()\n  if(TEST_WITH_TEST_RUNTIME)\n    list(APPEND TEST_DEPS ${ASAN_TEST_RUNTIME})\n    if(NOT MSVC)\n      list(APPEND TEST_OBJECTS lib${ASAN_TEST_RUNTIME}.a)\n    else()\n      list(APPEND TEST_OBJECTS ${ASAN_TEST_RUNTIME}.lib)\n    endif()\n  endif()\n  add_compiler_rt_test(${test_suite} ${test_name}\n                       SUBDIR ${TEST_SUBDIR}\n                       OBJECTS ${TEST_OBJECTS}\n                       DEPS ${TEST_DEPS}\n                       LINK_FLAGS ${TEST_LINKFLAGS}\n                                  ${TARGET_LINK_FLAGS})\nendmacro()\n\n# Main AddressSanitizer unit tests.\nadd_custom_target(AsanUnitTests)\nset_target_properties(AsanUnitTests PROPERTIES FOLDER \"ASan unit tests\")\n# AddressSanitizer unit tests with dynamic runtime (on platforms where it's\n# not the default).\nadd_custom_target(AsanDynamicUnitTests)\nset_target_properties(AsanDynamicUnitTests\n  PROPERTIES FOLDER \"ASan unit tests with dynamic runtime\")\n# ASan benchmarks (not actively used now).\nadd_custom_target(AsanBenchmarks)\nset_target_properties(AsanBenchmarks PROPERTIES FOLDER \"Asan benchmarks\")\n\nset(ASAN_NOINST_TEST_SOURCES\n  ${COMPILER_RT_GTEST_SOURCE}\n  asan_fake_stack_test.cc\n  asan_noinst_test.cc\n  asan_test_main.cc)\n\nset(ASAN_INST_TEST_SOURCES\n  ${COMPILER_RT_GTEST_SOURCE}\n  asan_asm_test.cc\n  asan_globals_test.cc\n  asan_interface_test.cc\n  asan_test.cc\n  asan_oob_test.cc\n  asan_mem_test.cc\n  asan_str_test.cc\n  asan_test_main.cc)\nif(APPLE)\n  list(APPEND ASAN_INST_TEST_SOURCES asan_mac_test.cc)\nendif()\n\nset(ASAN_BENCHMARKS_SOURCES\n  ${COMPILER_RT_GTEST_SOURCE}\n  asan_benchmarks_test.cc)\n\n# Adds ASan unit tests and benchmarks for architecture.\nmacro(add_asan_tests_for_arch_and_kind arch kind)\n  # Instrumented tests.\n  set(ASAN_INST_TEST_OBJECTS)\n  foreach(src ${ASAN_INST_TEST_SOURCES})\n    asan_compile(ASAN_INST_TEST_OBJECTS ${src} ${arch} ${kind}\n      ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})\n  endforeach()\n  if (APPLE)\n    # Add Mac-specific helper.\n    asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch} ${kind}\n                 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC ${ARGN})\n  endif()\n  file(MAKE_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/default\")\n  add_asan_test(AsanUnitTests \"Asan-${arch}${kind}-Test\"\n                ${arch} ${kind} SUBDIR \"default\"\n                OBJECTS ${ASAN_INST_TEST_OBJECTS}\n                LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})\n  if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)\n    file(MAKE_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/dynamic\")\n    add_asan_test(AsanDynamicUnitTests \"Asan-${arch}${kind}-Dynamic-Test\"\n                  ${arch} ${kind} SUBDIR \"dynamic\"\n                  OBJECTS ${ASAN_INST_TEST_OBJECTS}\n                  LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS})\n  endif()\n\n  # Add static ASan runtime that will be linked with uninstrumented tests.\n  set(ASAN_TEST_RUNTIME RTAsanTest.${arch}${kind})\n  if(APPLE)\n    set(ASAN_TEST_RUNTIME_OBJECTS\n      $<TARGET_OBJECTS:RTAsan.osx>\n      $<TARGET_OBJECTS:RTInterception.osx>\n      $<TARGET_OBJECTS:RTSanitizerCommon.osx>\n      $<TARGET_OBJECTS:RTLSanCommon.osx>\n      $<TARGET_OBJECTS:RTUbsan.osx>)\n  else()\n    set(ASAN_TEST_RUNTIME_OBJECTS\n      $<TARGET_OBJECTS:RTAsan.${arch}>\n      $<TARGET_OBJECTS:RTAsan_cxx.${arch}>\n      $<TARGET_OBJECTS:RTInterception.${arch}>\n      $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>\n      $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>\n      $<TARGET_OBJECTS:RTLSanCommon.${arch}>\n      $<TARGET_OBJECTS:RTUbsan.${arch}>\n      $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>)\n  endif()\n  add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS})\n  set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES\n    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})\n  # Uninstrumented tests.\n  set(ASAN_NOINST_TEST_OBJECTS)\n  foreach(src ${ASAN_NOINST_TEST_SOURCES})\n    asan_compile(ASAN_NOINST_TEST_OBJECTS ${src} ${arch} ${kind}\n                 ${ASAN_UNITTEST_COMMON_CFLAGS} ${ARGN})\n  endforeach()\n  add_asan_test(AsanUnitTests \"Asan-${arch}${kind}-Noinst-Test\"\n                ${arch} ${kind} SUBDIR \"default\"\n                OBJECTS ${ASAN_NOINST_TEST_OBJECTS}\n                LINKFLAGS ${ASAN_UNITTEST_NOINST_LINKFLAGS}\n                WITH_TEST_RUNTIME)\n\n  # Benchmarks.\n  set(ASAN_BENCHMARKS_OBJECTS)\n  foreach(src ${ASAN_BENCHMARKS_SOURCES})\n    asan_compile(ASAN_BENCHMARKS_OBJECTS ${src} ${arch} ${kind}\n                 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})\n  endforeach()\n  add_asan_test(AsanBenchmarks \"Asan-${arch}${kind}-Benchmark\"\n                ${arch} ${kind} SUBDIR \"default\"\n                OBJECTS ${ASAN_BENCHMARKS_OBJECTS}\n                LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})\nendmacro()\n\nif(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)\n  foreach(arch ${ASAN_SUPPORTED_ARCH})\n    add_asan_tests_for_arch_and_kind(${arch} \"-inline\")\n    add_asan_tests_for_arch_and_kind(${arch} \"-with-calls\"\n      -mllvm -asan-instrumentation-with-call-threshold=0)\n  endforeach()\nendif()\n\nif(ANDROID)\n  foreach(arch ${ASAN_SUPPORTED_ARCH})\n    # Test w/o ASan instrumentation. Link it with ASan statically.\n    add_executable(AsanNoinstTest # FIXME: .arch?\n      $<TARGET_OBJECTS:RTAsan.${arch}>\n      $<TARGET_OBJECTS:RTInterception.${arch}>\n      $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>\n      $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>\n      $<TARGET_OBJECTS:RTUbsan.${arch}>\n      $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>\n      ${COMPILER_RT_GTEST_SOURCE}\n      ${ASAN_NOINST_TEST_SOURCES})\n    set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS})\n    set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINKFLAGS})\n    target_link_libraries(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LIBS})\n\n    # Test with ASan instrumentation. Link with ASan dynamic runtime.\n    add_executable(AsanTest\n      ${COMPILER_RT_GTEST_SOURCE}\n      ${ASAN_INST_TEST_SOURCES})\n    set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})\n    set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})\n    target_link_libraries(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LIBS})\n\n    # Setup correct output directory and link flags.\n    set_target_properties(AsanNoinstTest AsanTest PROPERTIES\n      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})\n    # Add unit tests to the test suite.\n    add_dependencies(AsanUnitTests AsanNoinstTest AsanTest)\n  endforeach()\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_asm_test.cc",
    "content": "//===-- asan_asm_test.cc --------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n//===----------------------------------------------------------------------===//\n#include \"asan_test_utils.h\"\n\n#if defined(__linux__)\n\n#if defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))\n\n#include <emmintrin.h>\n\nnamespace {\n\ntemplate<typename T> void asm_write(T *ptr, T val);\ntemplate<typename T> T asm_read(T *ptr);\ntemplate<typename T> void asm_rep_movs(T *dst, T *src, size_t n);\n\n} // End of anonymous namespace\n\n#endif // defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))\n\n#if defined(__x86_64__)\n\nnamespace {\n\n#define DECLARE_ASM_WRITE(Type, Size, Mov, Reg)        \\\ntemplate<> void asm_write<Type>(Type *ptr, Type val) { \\\n  __asm__(                                             \\\n    Mov \" %[val], (%[ptr])  \\n\\t\"                      \\\n    :                                                  \\\n    : [ptr] \"r\" (ptr), [val] Reg (val)                 \\\n    : \"memory\"                                         \\\n  );                                                   \\\n}\n\n#define DECLARE_ASM_READ(Type, Size, Mov, Reg)     \\\ntemplate<> Type asm_read<Type>(Type *ptr) {        \\\n  Type res;                                        \\\n  __asm__(                                         \\\n    Mov \" (%[ptr]), %[res]  \\n\\t\"                  \\\n    : [res] Reg (res)                              \\\n    : [ptr] \"r\" (ptr)                              \\\n    : \"memory\"                                     \\\n  );                                               \\\n  return res;                                      \\\n}\n\n#define DECLARE_ASM_REP_MOVS(Type, Movs)                                       \\\n  template <> void asm_rep_movs<Type>(Type * dst, Type * src, size_t size) {   \\\n    __asm__(\"rep \" Movs \" \\n\\t\"                                                \\\n            :                                                                  \\\n            : \"D\"(dst), \"S\"(src), \"c\"(size)                                    \\\n            : \"rsi\", \"rdi\", \"rcx\", \"memory\");                                  \\\n  }\n\nDECLARE_ASM_WRITE(U8, \"8\", \"movq\", \"r\");\nDECLARE_ASM_READ(U8, \"8\", \"movq\", \"=r\");\nDECLARE_ASM_REP_MOVS(U8, \"movsq\");\n\n} // End of anonymous namespace\n\n#endif // defined(__x86_64__)\n\n#if defined(__i386__) && defined(__SSE2__)\n\nnamespace {\n\n#define DECLARE_ASM_WRITE(Type, Size, Mov, Reg)        \\\ntemplate<> void asm_write<Type>(Type *ptr, Type val) { \\\n  __asm__(                                             \\\n    Mov \" %[val], (%[ptr])  \\n\\t\"                      \\\n    :                                                  \\\n    : [ptr] \"r\" (ptr), [val] Reg (val)                 \\\n    : \"memory\"                                         \\\n  );                                                   \\\n}\n\n#define DECLARE_ASM_READ(Type, Size, Mov, Reg)     \\\ntemplate<> Type asm_read<Type>(Type *ptr) {        \\\n  Type res;                                        \\\n  __asm__(                                         \\\n    Mov \" (%[ptr]), %[res]  \\n\\t\"                  \\\n    : [res] Reg (res)                              \\\n    : [ptr] \"r\" (ptr)                              \\\n    : \"memory\"                                     \\\n  );                                               \\\n  return res;                                      \\\n}\n\n#define DECLARE_ASM_REP_MOVS(Type, Movs)                                       \\\n  template <> void asm_rep_movs<Type>(Type * dst, Type * src, size_t size) {   \\\n    __asm__(\"rep \" Movs \" \\n\\t\"                                                \\\n            :                                                                  \\\n            : \"D\"(dst), \"S\"(src), \"c\"(size)                                    \\\n            : \"esi\", \"edi\", \"ecx\", \"memory\");                                  \\\n  }\n\n} // End of anonymous namespace\n\n#endif  // defined(__i386__) && defined(__SSE2__)\n\n#if defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))\n\nnamespace {\n\nDECLARE_ASM_WRITE(U1, \"1\", \"movb\", \"r\");\nDECLARE_ASM_WRITE(U2, \"2\", \"movw\", \"r\");\nDECLARE_ASM_WRITE(U4, \"4\", \"movl\", \"r\");\nDECLARE_ASM_WRITE(__m128i, \"16\", \"movaps\", \"x\");\n\nDECLARE_ASM_READ(U1, \"1\", \"movb\", \"=r\");\nDECLARE_ASM_READ(U2, \"2\", \"movw\", \"=r\");\nDECLARE_ASM_READ(U4, \"4\", \"movl\", \"=r\");\nDECLARE_ASM_READ(__m128i, \"16\", \"movaps\", \"=x\");\n\nDECLARE_ASM_REP_MOVS(U1, \"movsb\");\nDECLARE_ASM_REP_MOVS(U2, \"movsw\");\nDECLARE_ASM_REP_MOVS(U4, \"movsl\");\n\ntemplate<typename T> void TestAsmWrite(const char *DeathPattern) {\n  T *buf = new T;\n  EXPECT_DEATH(asm_write(&buf[1], static_cast<T>(0)), DeathPattern);\n  T var = 0x12;\n  asm_write(&var, static_cast<T>(0x21));\n  ASSERT_EQ(static_cast<T>(0x21), var);\n  delete buf;\n}\n\ntemplate<> void TestAsmWrite<__m128i>(const char *DeathPattern) {\n  char *buf = new char[16];\n  char *p = buf + 16;\n  if (((uintptr_t) p % 16) != 0)\n    p = buf + 8;\n  assert(((uintptr_t) p % 16) == 0);\n  __m128i val = _mm_set1_epi16(0x1234);\n  EXPECT_DEATH(asm_write<__m128i>((__m128i*) p, val), DeathPattern);\n  __m128i var = _mm_set1_epi16(0x4321);\n  asm_write(&var, val);\n  ASSERT_EQ(0x1234, _mm_extract_epi16(var, 0));\n  delete [] buf;\n}\n\ntemplate<typename T> void TestAsmRead(const char *DeathPattern) {\n  T *buf = new T;\n  EXPECT_DEATH(asm_read(&buf[1]), DeathPattern);\n  T var = 0x12;\n  ASSERT_EQ(static_cast<T>(0x12), asm_read(&var));\n  delete buf;\n}\n\ntemplate<> void TestAsmRead<__m128i>(const char *DeathPattern) {\n  char *buf = new char[16];\n  char *p = buf + 16;\n  if (((uintptr_t) p % 16) != 0)\n    p = buf + 8;\n  assert(((uintptr_t) p % 16) == 0);\n  EXPECT_DEATH(asm_read<__m128i>((__m128i*) p), DeathPattern);\n  __m128i val = _mm_set1_epi16(0x1234);\n  ASSERT_EQ(0x1234, _mm_extract_epi16(asm_read(&val), 0));\n  delete [] buf;\n}\n\nU4 AsmLoad(U4 *a) {\n  U4 r;\n  __asm__(\"movl (%[a]), %[r]  \\n\\t\" : [r] \"=r\" (r) : [a] \"r\" (a) : \"memory\");\n  return r;\n}\n\nvoid AsmStore(U4 r, U4 *a) {\n  __asm__(\"movl %[r], (%[a])  \\n\\t\" : : [a] \"r\" (a), [r] \"r\" (r) : \"memory\");\n}\n\ntemplate <typename T>\nvoid TestAsmRepMovs(const char *DeathPatternRead,\n                    const char *DeathPatternWrite) {\n  T src_good[4] = { 0x0, 0x1, 0x2, 0x3 };\n  T dst_good[4] = {};\n  asm_rep_movs(dst_good, src_good, 4);\n  ASSERT_EQ(static_cast<T>(0x0), dst_good[0]);\n  ASSERT_EQ(static_cast<T>(0x1), dst_good[1]);\n  ASSERT_EQ(static_cast<T>(0x2), dst_good[2]);\n  ASSERT_EQ(static_cast<T>(0x3), dst_good[3]);\n\n  T dst_bad[3];\n  EXPECT_DEATH(asm_rep_movs(dst_bad, src_good, 4), DeathPatternWrite);\n\n  T src_bad[3] = { 0x0, 0x1, 0x2 };\n  EXPECT_DEATH(asm_rep_movs(dst_good, src_bad, 4), DeathPatternRead);\n\n  T* dp = dst_bad + 4;\n  T* sp = src_bad + 4;\n  asm_rep_movs(dp, sp, 0);\n}\n\n} // End of anonymous namespace\n\nTEST(AddressSanitizer, asm_load_store) {\n  U4* buf = new U4[2];\n  EXPECT_DEATH(AsmLoad(&buf[3]), \"READ of size 4\");\n  EXPECT_DEATH(AsmStore(0x1234, &buf[3]), \"WRITE of size 4\");\n  delete [] buf;\n}\n\nTEST(AddressSanitizer, asm_rw) {\n  TestAsmWrite<U1>(\"WRITE of size 1\");\n  TestAsmWrite<U2>(\"WRITE of size 2\");\n  TestAsmWrite<U4>(\"WRITE of size 4\");\n#if defined(__x86_64__)\n  TestAsmWrite<U8>(\"WRITE of size 8\");\n#endif // defined(__x86_64__)\n  TestAsmWrite<__m128i>(\"WRITE of size 16\");\n\n  TestAsmRead<U1>(\"READ of size 1\");\n  TestAsmRead<U2>(\"READ of size 2\");\n  TestAsmRead<U4>(\"READ of size 4\");\n#if defined(__x86_64__)\n  TestAsmRead<U8>(\"READ of size 8\");\n#endif // defined(__x86_64__)\n  TestAsmRead<__m128i>(\"READ of size 16\");\n}\n\nTEST(AddressSanitizer, asm_flags) {\n  long magic = 0x1234;\n  long r = 0x0;\n\n#if defined(__x86_64__) && !defined(__ILP32__)\n  __asm__(\"xorq %%rax, %%rax  \\n\\t\"\n          \"movq (%[p]), %%rax \\n\\t\"\n          \"sete %%al          \\n\\t\"\n          \"movzbq %%al, %[r]  \\n\\t\"\n          : [r] \"=r\"(r)\n          : [p] \"r\"(&magic)\n          : \"rax\", \"memory\");\n#else\n  __asm__(\"xorl %%eax, %%eax  \\n\\t\"\n          \"movl (%[p]), %%eax \\n\\t\"\n          \"sete %%al          \\n\\t\"\n          \"movzbl %%al, %[r]  \\n\\t\"\n          : [r] \"=r\"(r)\n          : [p] \"r\"(&magic)\n          : \"eax\", \"memory\");\n#endif // defined(__x86_64__) && !defined(__ILP32__)\n\n  ASSERT_EQ(0x1, r);\n}\n\nTEST(AddressSanitizer, asm_rep_movs) {\n  TestAsmRepMovs<U1>(\"READ of size 1\", \"WRITE of size 1\");\n  TestAsmRepMovs<U2>(\"READ of size 2\", \"WRITE of size 2\");\n  TestAsmRepMovs<U4>(\"READ of size 4\", \"WRITE of size 4\");\n#if defined(__x86_64__)\n  TestAsmRepMovs<U8>(\"READ of size 8\", \"WRITE of size 8\");\n#endif  // defined(__x86_64__)\n}\n\n#endif // defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))\n\n#endif // defined(__linux__)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_benchmarks_test.cc",
    "content": "//===-- asan_benchmarks_test.cc ----------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Some benchmarks for the instrumented code.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_test_utils.h\"\n\ntemplate<class T>\n__attribute__((noinline))\nstatic void ManyAccessFunc(T *x, size_t n_elements, size_t n_iter) {\n  for (size_t iter = 0; iter < n_iter; iter++) {\n    break_optimization(0);\n    // hand unroll the loop to stress the reg alloc.\n    for (size_t i = 0; i <= n_elements - 16; i += 16) {\n      x[i + 0] = i;\n      x[i + 1] = i;\n      x[i + 2] = i;\n      x[i + 3] = i;\n      x[i + 4] = i;\n      x[i + 5] = i;\n      x[i + 6] = i;\n      x[i + 7] = i;\n      x[i + 8] = i;\n      x[i + 9] = i;\n      x[i + 10] = i;\n      x[i + 11] = i;\n      x[i + 12] = i;\n      x[i + 13] = i;\n      x[i + 14] = i;\n      x[i + 15] = i;\n    }\n  }\n}\n\nTEST(AddressSanitizer, ManyAccessBenchmark) {\n  size_t kLen = 1024;\n  int *int_array = new int[kLen];\n  ManyAccessFunc(int_array, kLen, 1 << 24);\n  delete [] int_array;\n}\n\n// access 7 char elements in a 7 byte array (i.e. on the border).\n__attribute__((noinline))\nstatic void BorderAccessFunc(char *x, size_t n_iter) {\n  for (size_t iter = 0; iter < n_iter; iter++) {\n    break_optimization(x);\n    x[0] = 0;\n    x[1] = 0;\n    x[2] = 0;\n    x[3] = 0;\n    x[4] = 0;\n    x[5] = 0;\n    x[6] = 0;\n  }\n}\n\nTEST(AddressSanitizer, BorderAccessBenchmark) {\n  char *char_7_array = new char[7];\n  BorderAccessFunc(char_7_array, 1 << 30);\n  delete [] char_7_array;\n}\n\nstatic void FunctionWithLargeStack() {\n  int stack[1000];\n  Ident(stack);\n}\n\nTEST(AddressSanitizer, FakeStackBenchmark) {\n  for (int i = 0; i < 10000000; i++)\n    Ident(&FunctionWithLargeStack)();\n}\n\nint main(int argc, char **argv) {\n  testing::InitGoogleTest(&argc, argv);\n  return RUN_ALL_TESTS();\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_exceptions_test.cc",
    "content": "// See http://llvm.org/bugs/show_bug.cgi?id=11468\n#include <stdio.h>\n#include <string>\n\nclass Action {\n public:\n  Action() {}\n  void PrintString(const std::string& msg) const {\n    fprintf(stderr, \"%s\\n\", msg.c_str());\n  }\n  void Throw(const char& arg) const {\n    PrintString(\"PrintString called!\");  // this line is important\n    throw arg;\n  }\n};\n\nint main() {\n  const Action a;\n  fprintf(stderr, \"&a before = %p\\n\", &a);\n  try {\n    a.Throw('c');\n  } catch(const char&) {\n    fprintf(stderr, \"&a in catch = %p\\n\", &a);\n  }\n  fprintf(stderr, \"&a final = %p\\n\", &a);\n  return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_fake_stack_test.cc",
    "content": "//===-- asan_fake_stack_test.cc -------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Tests for FakeStack.\n// This test file should be compiled w/o asan instrumentation.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_fake_stack.h\"\n#include \"asan_test_utils.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n\n#include <assert.h>\n#include <stdlib.h>\n#include <stdio.h>\n\n#include <map>\n\nnamespace __asan {\n\nTEST(FakeStack, FlagsSize) {\n  EXPECT_EQ(FakeStack::SizeRequiredForFlags(10), 1U << 5);\n  EXPECT_EQ(FakeStack::SizeRequiredForFlags(11), 1U << 6);\n  EXPECT_EQ(FakeStack::SizeRequiredForFlags(20), 1U << 15);\n}\n\nTEST(FakeStack, RequiredSize) {\n  // for (int i = 15; i < 20; i++) {\n  //  uptr alloc_size = FakeStack::RequiredSize(i);\n  //  printf(\"%zdK ==> %zd\\n\", 1 << (i - 10), alloc_size);\n  // }\n  EXPECT_EQ(FakeStack::RequiredSize(15), 365568U);\n  EXPECT_EQ(FakeStack::RequiredSize(16), 727040U);\n  EXPECT_EQ(FakeStack::RequiredSize(17), 1449984U);\n  EXPECT_EQ(FakeStack::RequiredSize(18), 2895872U);\n  EXPECT_EQ(FakeStack::RequiredSize(19), 5787648U);\n}\n\nTEST(FakeStack, FlagsOffset) {\n  for (uptr stack_size_log = 15; stack_size_log <= 20; stack_size_log++) {\n    uptr stack_size = 1UL << stack_size_log;\n    uptr offset = 0;\n    for (uptr class_id = 0; class_id < FakeStack::kNumberOfSizeClasses;\n         class_id++) {\n      uptr frame_size = FakeStack::BytesInSizeClass(class_id);\n      uptr num_flags = stack_size / frame_size;\n      EXPECT_EQ(offset, FakeStack::FlagsOffset(stack_size_log, class_id));\n      // printf(\"%zd: %zd => %zd %zd\\n\", stack_size_log, class_id, offset,\n      //        FakeStack::FlagsOffset(stack_size_log, class_id));\n      offset += num_flags;\n    }\n  }\n}\n\n#if !defined(_WIN32)  // FIXME: Fails due to OOM on Windows.\nTEST(FakeStack, CreateDestroy) {\n  for (int i = 0; i < 1000; i++) {\n    for (uptr stack_size_log = 20; stack_size_log <= 22; stack_size_log++) {\n      FakeStack *fake_stack = FakeStack::Create(stack_size_log);\n      fake_stack->Destroy(0);\n    }\n  }\n}\n#endif\n\nTEST(FakeStack, ModuloNumberOfFrames) {\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, 0), 0U);\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<15)), 0U);\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<10)), 0U);\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<9)), 0U);\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<8)), 1U<<8);\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<15) + 1), 1U);\n\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 1, 0), 0U);\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 1, 1<<9), 0U);\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 1, 1<<8), 0U);\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 1, 1<<7), 1U<<7);\n\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 0), 0U);\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 1), 1U);\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 15), 15U);\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 16), 0U);\n  EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 17), 1U);\n}\n\nTEST(FakeStack, GetFrame) {\n  const uptr stack_size_log = 20;\n  const uptr stack_size = 1 << stack_size_log;\n  FakeStack *fs = FakeStack::Create(stack_size_log);\n  u8 *base = fs->GetFrame(stack_size_log, 0, 0);\n  EXPECT_EQ(base, reinterpret_cast<u8 *>(fs) +\n                      fs->SizeRequiredForFlags(stack_size_log) + 4096);\n  EXPECT_EQ(base + 0*stack_size + 64 * 7, fs->GetFrame(stack_size_log, 0, 7U));\n  EXPECT_EQ(base + 1*stack_size + 128 * 3, fs->GetFrame(stack_size_log, 1, 3U));\n  EXPECT_EQ(base + 2*stack_size + 256 * 5, fs->GetFrame(stack_size_log, 2, 5U));\n  fs->Destroy(0);\n}\n\nTEST(FakeStack, Allocate) {\n  const uptr stack_size_log = 19;\n  FakeStack *fs = FakeStack::Create(stack_size_log);\n  std::map<FakeFrame *, uptr> s;\n  for (int iter = 0; iter < 2; iter++) {\n    s.clear();\n    for (uptr cid = 0; cid < FakeStack::kNumberOfSizeClasses; cid++) {\n      uptr n = FakeStack::NumberOfFrames(stack_size_log, cid);\n      uptr bytes_in_class = FakeStack::BytesInSizeClass(cid);\n      for (uptr j = 0; j < n; j++) {\n        FakeFrame *ff = fs->Allocate(stack_size_log, cid, 0);\n        uptr x = reinterpret_cast<uptr>(ff);\n        EXPECT_TRUE(s.insert(std::make_pair(ff, cid)).second);\n        EXPECT_EQ(x, fs->AddrIsInFakeStack(x));\n        EXPECT_EQ(x, fs->AddrIsInFakeStack(x + 1));\n        EXPECT_EQ(x, fs->AddrIsInFakeStack(x + bytes_in_class - 1));\n        EXPECT_NE(x, fs->AddrIsInFakeStack(x + bytes_in_class));\n      }\n      // We are out of fake stack, so Allocate should return 0.\n      EXPECT_EQ(0UL, fs->Allocate(stack_size_log, cid, 0));\n    }\n    for (std::map<FakeFrame *, uptr>::iterator it = s.begin(); it != s.end();\n         ++it) {\n      fs->Deallocate(reinterpret_cast<uptr>(it->first), it->second);\n    }\n  }\n  fs->Destroy(0);\n}\n\nstatic void RecursiveFunction(FakeStack *fs, int depth) {\n  uptr class_id = depth / 3;\n  FakeFrame *ff = fs->Allocate(fs->stack_size_log(), class_id, 0);\n  if (depth) {\n    RecursiveFunction(fs, depth - 1);\n    RecursiveFunction(fs, depth - 1);\n  }\n  fs->Deallocate(reinterpret_cast<uptr>(ff), class_id);\n}\n\nTEST(FakeStack, RecursiveStressTest) {\n  const uptr stack_size_log = 16;\n  FakeStack *fs = FakeStack::Create(stack_size_log);\n  RecursiveFunction(fs, 22);  // with 26 runs for 2-3 seconds.\n  fs->Destroy(0);\n}\n\n}  // namespace __asan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_globals_test.cc",
    "content": "//===-- asan_globals_test.cc ----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Some globals in a separate file.\n//===----------------------------------------------------------------------===//\n#include \"asan_test_utils.h\"\n\nchar glob1[1];\nchar glob2[2];\nchar glob3[3];\nchar glob4[4];\nchar glob5[5];\nchar glob6[6];\nchar glob7[7];\nchar glob8[8];\nchar glob9[9];\nchar glob10[10];\nchar glob11[11];\nchar glob12[12];\nchar glob13[13];\nchar glob14[14];\nchar glob15[15];\nchar glob16[16];\nchar glob17[17];\nchar glob1000[1000];\nchar glob10000[10000];\nchar glob100000[100000];\n\nstatic char static10[10];\n\nint GlobalsTest(int zero) {\n  static char func_static15[15];\n  glob5[zero] = 0;\n  static10[zero] = 0;\n  func_static15[zero] = 0;\n  return glob5[1] + func_static15[2];\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_interface_test.cc",
    "content": "//===-- asan_interface_test.cc --------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n//===----------------------------------------------------------------------===//\n#include \"asan_test_utils.h\"\n#include <sanitizer/allocator_interface.h>\n#include <sanitizer/asan_interface.h>\n\nTEST(AddressSanitizerInterface, GetEstimatedAllocatedSize) {\n  EXPECT_EQ(0U, __sanitizer_get_estimated_allocated_size(0));\n  const size_t sizes[] = { 1, 30, 1<<30 };\n  for (size_t i = 0; i < 3; i++) {\n    EXPECT_EQ(sizes[i], __sanitizer_get_estimated_allocated_size(sizes[i]));\n  }\n}\n\nstatic const char* kGetAllocatedSizeErrorMsg =\n  \"attempting to call __sanitizer_get_allocated_size\";\n\nTEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) {\n  const size_t kArraySize = 100;\n  char *array = Ident((char*)malloc(kArraySize));\n  int *int_ptr = Ident(new int);\n\n  // Allocated memory is owned by allocator. Allocated size should be\n  // equal to requested size.\n  EXPECT_EQ(true, __sanitizer_get_ownership(array));\n  EXPECT_EQ(kArraySize, __sanitizer_get_allocated_size(array));\n  EXPECT_EQ(true, __sanitizer_get_ownership(int_ptr));\n  EXPECT_EQ(sizeof(int), __sanitizer_get_allocated_size(int_ptr));\n\n  // We cannot call GetAllocatedSize from the memory we didn't map,\n  // and from the interior pointers (not returned by previous malloc).\n  void *wild_addr = (void*)0x1;\n  EXPECT_FALSE(__sanitizer_get_ownership(wild_addr));\n  EXPECT_DEATH(__sanitizer_get_allocated_size(wild_addr),\n               kGetAllocatedSizeErrorMsg);\n  EXPECT_FALSE(__sanitizer_get_ownership(array + kArraySize / 2));\n  EXPECT_DEATH(__sanitizer_get_allocated_size(array + kArraySize / 2),\n               kGetAllocatedSizeErrorMsg);\n\n  // NULL is not owned, but is a valid argument for\n  // __sanitizer_get_allocated_size().\n  EXPECT_FALSE(__sanitizer_get_ownership(NULL));\n  EXPECT_EQ(0U, __sanitizer_get_allocated_size(NULL));\n\n  // When memory is freed, it's not owned, and call to GetAllocatedSize\n  // is forbidden.\n  free(array);\n  EXPECT_FALSE(__sanitizer_get_ownership(array));\n  EXPECT_DEATH(__sanitizer_get_allocated_size(array),\n               kGetAllocatedSizeErrorMsg);\n  delete int_ptr;\n\n  void *zero_alloc = Ident(malloc(0));\n  if (zero_alloc != 0) {\n    // If malloc(0) is not null, this pointer is owned and should have valid\n    // allocated size.\n    EXPECT_TRUE(__sanitizer_get_ownership(zero_alloc));\n    // Allocated size is 0 or 1 depending on the allocator used.\n    EXPECT_LT(__sanitizer_get_allocated_size(zero_alloc), 2U);\n  }\n  free(zero_alloc);\n}\n\nTEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) {\n  size_t before_malloc, after_malloc, after_free;\n  char *array;\n  const size_t kMallocSize = 100;\n  before_malloc = __sanitizer_get_current_allocated_bytes();\n\n  array = Ident((char*)malloc(kMallocSize));\n  after_malloc = __sanitizer_get_current_allocated_bytes();\n  EXPECT_EQ(before_malloc + kMallocSize, after_malloc);\n\n  free(array);\n  after_free = __sanitizer_get_current_allocated_bytes();\n  EXPECT_EQ(before_malloc, after_free);\n}\n\nTEST(AddressSanitizerInterface, GetHeapSizeTest) {\n  // ASan allocator does not keep huge chunks in free list, but unmaps them.\n  // The chunk should be greater than the quarantine size,\n  // otherwise it will be stuck in quarantine instead of being unmaped.\n  static const size_t kLargeMallocSize = (1 << 28) + 1;  // 256M\n  free(Ident(malloc(kLargeMallocSize)));  // Drain quarantine.\n  size_t old_heap_size = __sanitizer_get_heap_size();\n  for (int i = 0; i < 3; i++) {\n    // fprintf(stderr, \"allocating %zu bytes:\\n\", kLargeMallocSize);\n    free(Ident(malloc(kLargeMallocSize)));\n    EXPECT_EQ(old_heap_size, __sanitizer_get_heap_size());\n  }\n}\n\nstatic const size_t kManyThreadsMallocSizes[] = {5, 1UL<<10, 1UL<<14, 357};\nstatic const size_t kManyThreadsIterations = 250;\nstatic const size_t kManyThreadsNumThreads =\n  (SANITIZER_WORDSIZE == 32) ? 40 : 200;\n\nstatic void *ManyThreadsWithStatsWorker(void *arg) {\n  (void)arg;\n  for (size_t iter = 0; iter < kManyThreadsIterations; iter++) {\n    for (size_t size_index = 0; size_index < 4; size_index++) {\n      free(Ident(malloc(kManyThreadsMallocSizes[size_index])));\n    }\n  }\n  // Just one large allocation.\n  free(Ident(malloc(1 << 20)));\n  return 0;\n}\n\nTEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) {\n  size_t before_test, after_test, i;\n  pthread_t threads[kManyThreadsNumThreads];\n  before_test = __sanitizer_get_current_allocated_bytes();\n  for (i = 0; i < kManyThreadsNumThreads; i++) {\n    PTHREAD_CREATE(&threads[i], 0,\n                   (void* (*)(void *x))ManyThreadsWithStatsWorker, (void*)i);\n  }\n  for (i = 0; i < kManyThreadsNumThreads; i++) {\n    PTHREAD_JOIN(threads[i], 0);\n  }\n  after_test = __sanitizer_get_current_allocated_bytes();\n  // ASan stats also reflect memory usage of internal ASan RTL structs,\n  // so we can't check for equality here.\n  EXPECT_LT(after_test, before_test + (1UL<<20));\n}\n\nstatic void DoDoubleFree() {\n  int *x = Ident(new int);\n  delete Ident(x);\n  delete Ident(x);\n}\n\nTEST(AddressSanitizerInterface, ExitCode) {\n  int original_exit_code = __asan_set_error_exit_code(7);\n  EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(7), \"\");\n  EXPECT_EQ(7, __asan_set_error_exit_code(8));\n  EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(8), \"\");\n  EXPECT_EQ(8, __asan_set_error_exit_code(original_exit_code));\n  EXPECT_EXIT(DoDoubleFree(),\n              ::testing::ExitedWithCode(original_exit_code), \"\");\n}\n\nstatic void MyDeathCallback() {\n  fprintf(stderr, \"MyDeathCallback\\n\");\n  fflush(0);  // On Windows, stderr doesn't flush on crash.\n}\n\nTEST(AddressSanitizerInterface, DeathCallbackTest) {\n  __asan_set_death_callback(MyDeathCallback);\n  EXPECT_DEATH(DoDoubleFree(), \"MyDeathCallback\");\n  __asan_set_death_callback(NULL);\n}\n\nstatic const char* kUseAfterPoisonErrorMessage = \"use-after-poison\";\n\n#define GOOD_ACCESS(ptr, offset)  \\\n    EXPECT_FALSE(__asan_address_is_poisoned(ptr + offset))\n\n#define BAD_ACCESS(ptr, offset) \\\n    EXPECT_TRUE(__asan_address_is_poisoned(ptr + offset))\n\nTEST(AddressSanitizerInterface, SimplePoisonMemoryRegionTest) {\n  char *array = Ident((char*)malloc(120));\n  // poison array[40..80)\n  __asan_poison_memory_region(array + 40, 40);\n  GOOD_ACCESS(array, 39);\n  GOOD_ACCESS(array, 80);\n  BAD_ACCESS(array, 40);\n  BAD_ACCESS(array, 60);\n  BAD_ACCESS(array, 79);\n  char value;\n  EXPECT_DEATH(value = Ident(array[40]), kUseAfterPoisonErrorMessage);\n  __asan_unpoison_memory_region(array + 40, 40);\n  // access previously poisoned memory.\n  GOOD_ACCESS(array, 40);\n  GOOD_ACCESS(array, 79);\n  free(array);\n}\n\nTEST(AddressSanitizerInterface, OverlappingPoisonMemoryRegionTest) {\n  char *array = Ident((char*)malloc(120));\n  // Poison [0..40) and [80..120)\n  __asan_poison_memory_region(array, 40);\n  __asan_poison_memory_region(array + 80, 40);\n  BAD_ACCESS(array, 20);\n  GOOD_ACCESS(array, 60);\n  BAD_ACCESS(array, 100);\n  // Poison whole array - [0..120)\n  __asan_poison_memory_region(array, 120);\n  BAD_ACCESS(array, 60);\n  // Unpoison [24..96)\n  __asan_unpoison_memory_region(array + 24, 72);\n  BAD_ACCESS(array, 23);\n  GOOD_ACCESS(array, 24);\n  GOOD_ACCESS(array, 60);\n  GOOD_ACCESS(array, 95);\n  BAD_ACCESS(array, 96);\n  free(array);\n}\n\nTEST(AddressSanitizerInterface, PushAndPopWithPoisoningTest) {\n  // Vector of capacity 20\n  char *vec = Ident((char*)malloc(20));\n  __asan_poison_memory_region(vec, 20);\n  for (size_t i = 0; i < 7; i++) {\n    // Simulate push_back.\n    __asan_unpoison_memory_region(vec + i, 1);\n    GOOD_ACCESS(vec, i);\n    BAD_ACCESS(vec, i + 1);\n  }\n  for (size_t i = 7; i > 0; i--) {\n    // Simulate pop_back.\n    __asan_poison_memory_region(vec + i - 1, 1);\n    BAD_ACCESS(vec, i - 1);\n    if (i > 1) GOOD_ACCESS(vec, i - 2);\n  }\n  free(vec);\n}\n\n// Make sure that each aligned block of size \"2^granularity\" doesn't have\n// \"true\" value before \"false\" value.\nstatic void MakeShadowValid(bool *shadow, int length, int granularity) {\n  bool can_be_poisoned = true;\n  for (int i = length - 1; i >= 0; i--) {\n    if (!shadow[i])\n      can_be_poisoned = false;\n    if (!can_be_poisoned)\n      shadow[i] = false;\n    if (i % (1 << granularity) == 0) {\n      can_be_poisoned = true;\n    }\n  }\n}\n\nTEST(AddressSanitizerInterface, PoisoningStressTest) {\n  const size_t kSize = 24;\n  bool expected[kSize];\n  char *arr = Ident((char*)malloc(kSize));\n  for (size_t l1 = 0; l1 < kSize; l1++) {\n    for (size_t s1 = 1; l1 + s1 <= kSize; s1++) {\n      for (size_t l2 = 0; l2 < kSize; l2++) {\n        for (size_t s2 = 1; l2 + s2 <= kSize; s2++) {\n          // Poison [l1, l1+s1), [l2, l2+s2) and check result.\n          __asan_unpoison_memory_region(arr, kSize);\n          __asan_poison_memory_region(arr + l1, s1);\n          __asan_poison_memory_region(arr + l2, s2);\n          memset(expected, false, kSize);\n          memset(expected + l1, true, s1);\n          MakeShadowValid(expected, kSize, /*granularity*/ 3);\n          memset(expected + l2, true, s2);\n          MakeShadowValid(expected, kSize, /*granularity*/ 3);\n          for (size_t i = 0; i < kSize; i++) {\n            ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));\n          }\n          // Unpoison [l1, l1+s1) and [l2, l2+s2) and check result.\n          __asan_poison_memory_region(arr, kSize);\n          __asan_unpoison_memory_region(arr + l1, s1);\n          __asan_unpoison_memory_region(arr + l2, s2);\n          memset(expected, true, kSize);\n          memset(expected + l1, false, s1);\n          MakeShadowValid(expected, kSize, /*granularity*/ 3);\n          memset(expected + l2, false, s2);\n          MakeShadowValid(expected, kSize, /*granularity*/ 3);\n          for (size_t i = 0; i < kSize; i++) {\n            ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));\n          }\n        }\n      }\n    }\n  }\n  free(arr);\n}\n\nTEST(AddressSanitizerInterface, GlobalRedzones) {\n  GOOD_ACCESS(glob1, 1 - 1);\n  GOOD_ACCESS(glob2, 2 - 1);\n  GOOD_ACCESS(glob3, 3 - 1);\n  GOOD_ACCESS(glob4, 4 - 1);\n  GOOD_ACCESS(glob5, 5 - 1);\n  GOOD_ACCESS(glob6, 6 - 1);\n  GOOD_ACCESS(glob7, 7 - 1);\n  GOOD_ACCESS(glob8, 8 - 1);\n  GOOD_ACCESS(glob9, 9 - 1);\n  GOOD_ACCESS(glob10, 10 - 1);\n  GOOD_ACCESS(glob11, 11 - 1);\n  GOOD_ACCESS(glob12, 12 - 1);\n  GOOD_ACCESS(glob13, 13 - 1);\n  GOOD_ACCESS(glob14, 14 - 1);\n  GOOD_ACCESS(glob15, 15 - 1);\n  GOOD_ACCESS(glob16, 16 - 1);\n  GOOD_ACCESS(glob17, 17 - 1);\n  GOOD_ACCESS(glob1000, 1000 - 1);\n  GOOD_ACCESS(glob10000, 10000 - 1);\n  GOOD_ACCESS(glob100000, 100000 - 1);\n\n  BAD_ACCESS(glob1, 1);\n  BAD_ACCESS(glob2, 2);\n  BAD_ACCESS(glob3, 3);\n  BAD_ACCESS(glob4, 4);\n  BAD_ACCESS(glob5, 5);\n  BAD_ACCESS(glob6, 6);\n  BAD_ACCESS(glob7, 7);\n  BAD_ACCESS(glob8, 8);\n  BAD_ACCESS(glob9, 9);\n  BAD_ACCESS(glob10, 10);\n  BAD_ACCESS(glob11, 11);\n  BAD_ACCESS(glob12, 12);\n  BAD_ACCESS(glob13, 13);\n  BAD_ACCESS(glob14, 14);\n  BAD_ACCESS(glob15, 15);\n  BAD_ACCESS(glob16, 16);\n  BAD_ACCESS(glob17, 17);\n  BAD_ACCESS(glob1000, 1000);\n  BAD_ACCESS(glob1000, 1100);  // Redzone is at least 101 bytes.\n  BAD_ACCESS(glob10000, 10000);\n  BAD_ACCESS(glob10000, 11000);  // Redzone is at least 1001 bytes.\n  BAD_ACCESS(glob100000, 100000);\n  BAD_ACCESS(glob100000, 110000);  // Redzone is at least 10001 bytes.\n}\n\nTEST(AddressSanitizerInterface, PoisonedRegion) {\n  size_t rz = 16;\n  for (size_t size = 1; size <= 64; size++) {\n    char *p = new char[size];\n    for (size_t beg = 0; beg < size + rz; beg++) {\n      for (size_t end = beg; end < size + rz; end++) {\n        void *first_poisoned = __asan_region_is_poisoned(p + beg, end - beg);\n        if (beg == end) {\n          EXPECT_FALSE(first_poisoned);\n        } else if (beg < size && end <= size) {\n          EXPECT_FALSE(first_poisoned);\n        } else if (beg >= size) {\n          EXPECT_EQ(p + beg, first_poisoned);\n        } else {\n          EXPECT_GT(end, size);\n          EXPECT_EQ(p + size, first_poisoned);\n        }\n      }\n    }\n    delete [] p;\n  }\n}\n\n// This is a performance benchmark for manual runs.\n// asan's memset interceptor calls mem_is_zero for the entire shadow region.\n// the profile should look like this:\n//     89.10%   [.] __memset_sse2\n//     10.50%   [.] __sanitizer::mem_is_zero\n// I.e. mem_is_zero should consume ~ SHADOW_GRANULARITY less CPU cycles\n// than memset itself.\nTEST(AddressSanitizerInterface, DISABLED_StressLargeMemset) {\n  size_t size = 1 << 20;\n  char *x = new char[size];\n  for (int i = 0; i < 100000; i++)\n    Ident(memset)(x, 0, size);\n  delete [] x;\n}\n\n// Same here, but we run memset with small sizes.\nTEST(AddressSanitizerInterface, DISABLED_StressSmallMemset) {\n  size_t size = 32;\n  char *x = new char[size];\n  for (int i = 0; i < 100000000; i++)\n    Ident(memset)(x, 0, size);\n  delete [] x;\n}\nstatic const char *kInvalidPoisonMessage = \"invalid-poison-memory-range\";\nstatic const char *kInvalidUnpoisonMessage = \"invalid-unpoison-memory-range\";\n\nTEST(AddressSanitizerInterface, DISABLED_InvalidPoisonAndUnpoisonCallsTest) {\n  char *array = Ident((char*)malloc(120));\n  __asan_unpoison_memory_region(array, 120);\n  // Try to unpoison not owned memory\n  EXPECT_DEATH(__asan_unpoison_memory_region(array, 121),\n               kInvalidUnpoisonMessage);\n  EXPECT_DEATH(__asan_unpoison_memory_region(array - 1, 120),\n               kInvalidUnpoisonMessage);\n\n  __asan_poison_memory_region(array, 120);\n  // Try to poison not owned memory.\n  EXPECT_DEATH(__asan_poison_memory_region(array, 121), kInvalidPoisonMessage);\n  EXPECT_DEATH(__asan_poison_memory_region(array - 1, 120),\n               kInvalidPoisonMessage);\n  free(array);\n}\n\n#if !defined(_WIN32)  // FIXME: This should really be a lit test.\nstatic void ErrorReportCallbackOneToZ(const char *report) {\n  int report_len = strlen(report);\n  ASSERT_EQ(6, write(2, \"ABCDEF\", 6));\n  ASSERT_EQ(report_len, write(2, report, report_len));\n  ASSERT_EQ(6, write(2, \"ABCDEF\", 6));\n  _exit(1);\n}\n\nTEST(AddressSanitizerInterface, SetErrorReportCallbackTest) {\n  __asan_set_error_report_callback(ErrorReportCallbackOneToZ);\n  EXPECT_DEATH(__asan_report_error(0, 0, 0, 0, true, 1),\n               ASAN_PCRE_DOTALL \"ABCDEF.*AddressSanitizer.*WRITE.*ABCDEF\");\n  __asan_set_error_report_callback(NULL);\n}\n#endif\n\nTEST(AddressSanitizerInterface, GetOwnershipStressTest) {\n  std::vector<char *> pointers;\n  std::vector<size_t> sizes;\n  const size_t kNumMallocs = 1 << 9;\n  for (size_t i = 0; i < kNumMallocs; i++) {\n    size_t size = i * 100 + 1;\n    pointers.push_back((char*)malloc(size));\n    sizes.push_back(size);\n  }\n  for (size_t i = 0; i < 4000000; i++) {\n    EXPECT_FALSE(__sanitizer_get_ownership(&pointers));\n    EXPECT_FALSE(__sanitizer_get_ownership((void*)0x1234));\n    size_t idx = i % kNumMallocs;\n    EXPECT_TRUE(__sanitizer_get_ownership(pointers[idx]));\n    EXPECT_EQ(sizes[idx], __sanitizer_get_allocated_size(pointers[idx]));\n  }\n  for (size_t i = 0, n = pointers.size(); i < n; i++)\n    free(pointers[i]);\n}\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_mac_test.cc",
    "content": "//===-- asan_test_mac.cc --------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"asan_test_utils.h\"\n\n#include \"asan_mac_test.h\"\n\n#include <malloc/malloc.h>\n#include <AvailabilityMacros.h>  // For MAC_OS_X_VERSION_*\n#include <CoreFoundation/CFString.h>\n\nTEST(AddressSanitizerMac, CFAllocatorDefaultDoubleFree) {\n  EXPECT_DEATH(\n      CFAllocatorDefaultDoubleFree(NULL),\n      \"attempting double-free\");\n}\n\nvoid CFAllocator_DoubleFreeOnPthread() {\n  pthread_t child;\n  PTHREAD_CREATE(&child, NULL, CFAllocatorDefaultDoubleFree, NULL);\n  PTHREAD_JOIN(child, NULL);  // Shouldn't be reached.\n}\n\nTEST(AddressSanitizerMac, CFAllocatorDefaultDoubleFree_ChildPhread) {\n  EXPECT_DEATH(CFAllocator_DoubleFreeOnPthread(), \"attempting double-free\");\n}\n\nnamespace {\n\nvoid *GLOB;\n\nvoid *CFAllocatorAllocateToGlob(void *unused) {\n  GLOB = CFAllocatorAllocate(NULL, 100, /*hint*/0);\n  return NULL;\n}\n\nvoid *CFAllocatorDeallocateFromGlob(void *unused) {\n  char *p = (char*)GLOB;\n  p[100] = 'A';  // ASan should report an error here.\n  CFAllocatorDeallocate(NULL, GLOB);\n  return NULL;\n}\n\nvoid CFAllocator_PassMemoryToAnotherThread() {\n  pthread_t th1, th2;\n  PTHREAD_CREATE(&th1, NULL, CFAllocatorAllocateToGlob, NULL);\n  PTHREAD_JOIN(th1, NULL);\n  PTHREAD_CREATE(&th2, NULL, CFAllocatorDeallocateFromGlob, NULL);\n  PTHREAD_JOIN(th2, NULL);\n}\n\nTEST(AddressSanitizerMac, CFAllocator_PassMemoryToAnotherThread) {\n  EXPECT_DEATH(CFAllocator_PassMemoryToAnotherThread(),\n               \"heap-buffer-overflow\");\n}\n\n}  // namespace\n\n// TODO(glider): figure out whether we still need these tests. Is it correct\n// to intercept the non-default CFAllocators?\nTEST(AddressSanitizerMac, DISABLED_CFAllocatorSystemDefaultDoubleFree) {\n  EXPECT_DEATH(\n      CFAllocatorSystemDefaultDoubleFree(),\n      \"attempting double-free\");\n}\n\n// We're intercepting malloc, so kCFAllocatorMalloc is routed to ASan.\nTEST(AddressSanitizerMac, CFAllocatorMallocDoubleFree) {\n  EXPECT_DEATH(CFAllocatorMallocDoubleFree(), \"attempting double-free\");\n}\n\nTEST(AddressSanitizerMac, DISABLED_CFAllocatorMallocZoneDoubleFree) {\n  EXPECT_DEATH(CFAllocatorMallocZoneDoubleFree(), \"attempting double-free\");\n}\n\n// For libdispatch tests below we check that ASan got to the shadow byte\n// legend, i.e. managed to print the thread stacks (this almost certainly\n// means that the libdispatch task creation has been intercepted correctly).\nTEST(AddressSanitizerMac, GCDDispatchAsync) {\n  // Make sure the whole ASan report is printed, i.e. that we don't die\n  // on a CHECK.\n  EXPECT_DEATH(TestGCDDispatchAsync(), \"Shadow byte legend\");\n}\n\nTEST(AddressSanitizerMac, GCDDispatchSync) {\n  // Make sure the whole ASan report is printed, i.e. that we don't die\n  // on a CHECK.\n  EXPECT_DEATH(TestGCDDispatchSync(), \"Shadow byte legend\");\n}\n\n\nTEST(AddressSanitizerMac, GCDReuseWqthreadsAsync) {\n  // Make sure the whole ASan report is printed, i.e. that we don't die\n  // on a CHECK.\n  EXPECT_DEATH(TestGCDReuseWqthreadsAsync(), \"Shadow byte legend\");\n}\n\nTEST(AddressSanitizerMac, GCDReuseWqthreadsSync) {\n  // Make sure the whole ASan report is printed, i.e. that we don't die\n  // on a CHECK.\n  EXPECT_DEATH(TestGCDReuseWqthreadsSync(), \"Shadow byte legend\");\n}\n\nTEST(AddressSanitizerMac, GCDDispatchAfter) {\n  // Make sure the whole ASan report is printed, i.e. that we don't die\n  // on a CHECK.\n  EXPECT_DEATH(TestGCDDispatchAfter(), \"Shadow byte legend\");\n}\n\nTEST(AddressSanitizerMac, GCDSourceEvent) {\n  // Make sure the whole ASan report is printed, i.e. that we don't die\n  // on a CHECK.\n  EXPECT_DEATH(TestGCDSourceEvent(), \"Shadow byte legend\");\n}\n\nTEST(AddressSanitizerMac, GCDSourceCancel) {\n  // Make sure the whole ASan report is printed, i.e. that we don't die\n  // on a CHECK.\n  EXPECT_DEATH(TestGCDSourceCancel(), \"Shadow byte legend\");\n}\n\nTEST(AddressSanitizerMac, GCDGroupAsync) {\n  // Make sure the whole ASan report is printed, i.e. that we don't die\n  // on a CHECK.\n  EXPECT_DEATH(TestGCDGroupAsync(), \"Shadow byte legend\");\n}\n\nvoid *MallocIntrospectionLockWorker(void *_) {\n  const int kNumPointers = 100;\n  int i;\n  void *pointers[kNumPointers];\n  for (i = 0; i < kNumPointers; i++) {\n    pointers[i] = malloc(i + 1);\n  }\n  for (i = 0; i < kNumPointers; i++) {\n    free(pointers[i]);\n  }\n\n  return NULL;\n}\n\nvoid *MallocIntrospectionLockForker(void *_) {\n  pid_t result = fork();\n  if (result == -1) {\n    perror(\"fork\");\n  }\n  assert(result != -1);\n  if (result == 0) {\n    // Call malloc in the child process to make sure we won't deadlock.\n    void *ptr = malloc(42);\n    free(ptr);\n    exit(0);\n  } else {\n    // Return in the parent process.\n    return NULL;\n  }\n}\n\nTEST(AddressSanitizerMac, MallocIntrospectionLock) {\n  // Incorrect implementation of force_lock and force_unlock in our malloc zone\n  // will cause forked processes to deadlock.\n  // TODO(glider): need to detect that none of the child processes deadlocked.\n  const int kNumWorkers = 5, kNumIterations = 100;\n  int i, iter;\n  for (iter = 0; iter < kNumIterations; iter++) {\n    pthread_t workers[kNumWorkers], forker;\n    for (i = 0; i < kNumWorkers; i++) {\n      PTHREAD_CREATE(&workers[i], 0, MallocIntrospectionLockWorker, 0);\n    }\n    PTHREAD_CREATE(&forker, 0, MallocIntrospectionLockForker, 0);\n    for (i = 0; i < kNumWorkers; i++) {\n      PTHREAD_JOIN(workers[i], 0);\n    }\n    PTHREAD_JOIN(forker, 0);\n  }\n}\n\nvoid *TSDAllocWorker(void *test_key) {\n  if (test_key) {\n    void *mem = malloc(10);\n    pthread_setspecific(*(pthread_key_t*)test_key, mem);\n  }\n  return NULL;\n}\n\nTEST(AddressSanitizerMac, DISABLED_TSDWorkqueueTest) {\n  pthread_t th;\n  pthread_key_t test_key;\n  pthread_key_create(&test_key, CallFreeOnWorkqueue);\n  PTHREAD_CREATE(&th, NULL, TSDAllocWorker, &test_key);\n  PTHREAD_JOIN(th, NULL);\n  pthread_key_delete(test_key);\n}\n\n// Test that CFStringCreateCopy does not copy constant strings.\nTEST(AddressSanitizerMac, CFStringCreateCopy) {\n  CFStringRef str = CFSTR(\"Hello world!\\n\");\n  CFStringRef str2 = CFStringCreateCopy(0, str);\n  EXPECT_EQ(str, str2);\n}\n\nTEST(AddressSanitizerMac, NSObjectOOB) {\n  // Make sure that our allocators are used for NSObjects.\n  EXPECT_DEATH(TestOOBNSObjects(), \"heap-buffer-overflow\");\n}\n\n// Make sure that correct pointer is passed to free() when deallocating a\n// NSURL object.\n// See http://code.google.com/p/address-sanitizer/issues/detail?id=70.\nTEST(AddressSanitizerMac, NSURLDeallocation) {\n  TestNSURLDeallocation();\n}\n\n// See http://code.google.com/p/address-sanitizer/issues/detail?id=109.\nTEST(AddressSanitizerMac, Mstats) {\n  malloc_statistics_t stats1, stats2;\n  malloc_zone_statistics(/*all zones*/NULL, &stats1);\n  const size_t kMallocSize = 100000;\n  void *alloc = Ident(malloc(kMallocSize));\n  malloc_zone_statistics(/*all zones*/NULL, &stats2);\n  EXPECT_GT(stats2.blocks_in_use, stats1.blocks_in_use);\n  EXPECT_GE(stats2.size_in_use - stats1.size_in_use, kMallocSize);\n  free(alloc);\n  // Even the default OSX allocator may not change the stats after free().\n}\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_mac_test.h",
    "content": "extern \"C\" {\n  void *CFAllocatorDefaultDoubleFree(void *unused);\n  void CFAllocatorSystemDefaultDoubleFree();\n  void CFAllocatorMallocDoubleFree();\n  void CFAllocatorMallocZoneDoubleFree();\n  void CallFreeOnWorkqueue(void *mem);\n  void TestGCDDispatchAsync();\n  void TestGCDDispatchSync();\n  void TestGCDReuseWqthreadsAsync();\n  void TestGCDReuseWqthreadsSync();\n  void TestGCDDispatchAfter();\n  void TestGCDInTSDDestructor();\n  void TestGCDSourceEvent();\n  void TestGCDSourceCancel();\n  void TestGCDGroupAsync();\n  void TestOOBNSObjects();\n  void TestNSURLDeallocation();\n  void TestPassCFMemoryToAnotherThread();\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_mac_test_helpers.mm",
    "content": "// Mac OS X 10.6 or higher only.\n#include <dispatch/dispatch.h>\n#include <pthread.h>  // for pthread_yield_np()\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#import <CoreFoundation/CFBase.h>\n#import <Foundation/NSObject.h>\n#import <Foundation/NSURL.h>\n\n// This is a (void*)(void*) function so it can be passed to pthread_create.\nvoid *CFAllocatorDefaultDoubleFree(void *unused) {\n  void *mem = CFAllocatorAllocate(kCFAllocatorDefault, 5, 0);\n  CFAllocatorDeallocate(kCFAllocatorDefault, mem);\n  CFAllocatorDeallocate(kCFAllocatorDefault, mem);\n  return 0;\n}\n\nvoid CFAllocatorSystemDefaultDoubleFree() {\n  void *mem = CFAllocatorAllocate(kCFAllocatorSystemDefault, 5, 0);\n  CFAllocatorDeallocate(kCFAllocatorSystemDefault, mem);\n  CFAllocatorDeallocate(kCFAllocatorSystemDefault, mem);\n}\n\nvoid CFAllocatorMallocDoubleFree() {\n  void *mem = CFAllocatorAllocate(kCFAllocatorMalloc, 5, 0);\n  CFAllocatorDeallocate(kCFAllocatorMalloc, mem);\n  CFAllocatorDeallocate(kCFAllocatorMalloc, mem);\n}\n\nvoid CFAllocatorMallocZoneDoubleFree() {\n  void *mem = CFAllocatorAllocate(kCFAllocatorMallocZone, 5, 0);\n  CFAllocatorDeallocate(kCFAllocatorMallocZone, mem);\n  CFAllocatorDeallocate(kCFAllocatorMallocZone, mem);\n}\n\n__attribute__((noinline))\nvoid access_memory(char *a) {\n  *a = 0;\n}\n\n// Test the +load instrumentation.\n// Because the +load methods are invoked before anything else is initialized,\n// it makes little sense to wrap the code below into a gTest test case.\n// If AddressSanitizer doesn't instrument the +load method below correctly,\n// everything will just crash.\n\nchar kStartupStr[] =\n    \"If your test didn't crash, AddressSanitizer is instrumenting \"\n    \"the +load methods correctly.\";\n\n@interface LoadSomething : NSObject {\n}\n@end\n\n@implementation LoadSomething\n\n+(void) load {\n  for (size_t i = 0; i < strlen(kStartupStr); i++) {\n    access_memory(&kStartupStr[i]);  // make sure no optimizations occur.\n  }\n  // Don't print anything here not to interfere with the death tests.\n}\n\n@end\n\nvoid worker_do_alloc(int size) {\n  char * volatile mem = (char * volatile)malloc(size);\n  mem[0] = 0; // Ok\n  free(mem);\n}\n\nvoid worker_do_crash(int size) {\n  char * volatile mem = (char * volatile)malloc(size);\n  access_memory(&mem[size]);  // BOOM\n  free(mem);\n}\n\n// Used by the GCD tests to avoid a race between the worker thread reporting a\n// memory error and the main thread which may exit with exit code 0 before\n// that.\nvoid wait_forever() {\n  volatile bool infinite = true;\n  while (infinite) pthread_yield_np();\n}\n\n// Tests for the Grand Central Dispatch. See\n// http://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html\n// for the reference.\nvoid TestGCDDispatchAsync() {\n  dispatch_queue_t queue = dispatch_get_global_queue(0, 0);\n  dispatch_block_t block = ^{ worker_do_crash(1024); };\n  // dispatch_async() runs the task on a worker thread that does not go through\n  // pthread_create(). We need to verify that AddressSanitizer notices that the\n  // thread has started.\n  dispatch_async(queue, block);\n  wait_forever();\n}\n\nvoid TestGCDDispatchSync() {\n  dispatch_queue_t queue = dispatch_get_global_queue(2, 0);\n  dispatch_block_t block = ^{ worker_do_crash(1024); };\n  // dispatch_sync() runs the task on a worker thread that does not go through\n  // pthread_create(). We need to verify that AddressSanitizer notices that the\n  // thread has started.\n  dispatch_sync(queue, block);\n  wait_forever();\n}\n\n// libdispatch spawns a rather small number of threads and reuses them. We need\n// to make sure AddressSanitizer handles the reusing correctly.\nvoid TestGCDReuseWqthreadsAsync() {\n  dispatch_queue_t queue = dispatch_get_global_queue(0, 0);\n  dispatch_block_t block_alloc = ^{ worker_do_alloc(1024); };\n  dispatch_block_t block_crash = ^{ worker_do_crash(1024); };\n  for (int i = 0; i < 100; i++) {\n    dispatch_async(queue, block_alloc);\n  }\n  dispatch_async(queue, block_crash);\n  wait_forever();\n}\n\n// Try to trigger abnormal behaviour of dispatch_sync() being unhandled by us.\nvoid TestGCDReuseWqthreadsSync() {\n  dispatch_queue_t queue[4];\n  queue[0] = dispatch_get_global_queue(2, 0);\n  queue[1] = dispatch_get_global_queue(0, 0);\n  queue[2] = dispatch_get_global_queue(-2, 0);\n  queue[3] = dispatch_queue_create(\"my_queue\", NULL);\n  dispatch_block_t block_alloc = ^{ worker_do_alloc(1024); };\n  dispatch_block_t block_crash = ^{ worker_do_crash(1024); };\n  for (int i = 0; i < 1000; i++) {\n    dispatch_sync(queue[i % 4], block_alloc);\n  }\n  dispatch_sync(queue[3], block_crash);\n  wait_forever();\n}\n\nvoid TestGCDDispatchAfter() {\n  dispatch_queue_t queue = dispatch_get_global_queue(0, 0);\n  dispatch_block_t block_crash = ^{ worker_do_crash(1024); };\n  // Schedule the event one second from the current time.\n  dispatch_time_t milestone =\n      dispatch_time(DISPATCH_TIME_NOW, 1LL * NSEC_PER_SEC);\n  dispatch_after(milestone, queue, block_crash);\n  wait_forever();\n}\n\nvoid worker_do_deallocate(void *ptr) {\n  free(ptr);\n}\n\nvoid CallFreeOnWorkqueue(void *tsd) {\n  dispatch_queue_t queue = dispatch_get_global_queue(0, 0);\n  dispatch_block_t block_dealloc = ^{ worker_do_deallocate(tsd); };\n  dispatch_async(queue, block_dealloc);\n  // Do not wait for the worker to free the memory -- nobody is going to touch\n  // it.\n}\n\nvoid TestGCDSourceEvent() {\n  dispatch_queue_t queue = dispatch_get_global_queue(0, 0);\n  dispatch_source_t timer =\n      dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);\n  // Schedule the timer one second from the current time.\n  dispatch_time_t milestone =\n      dispatch_time(DISPATCH_TIME_NOW, 1LL * NSEC_PER_SEC);\n\n  dispatch_source_set_timer(timer, milestone, DISPATCH_TIME_FOREVER, 0);\n  char * volatile mem = (char * volatile)malloc(10);\n  dispatch_source_set_event_handler(timer, ^{\n    access_memory(&mem[10]);\n  });\n  dispatch_resume(timer);\n  wait_forever();\n}\n\nvoid TestGCDSourceCancel() {\n  dispatch_queue_t queue = dispatch_get_global_queue(0, 0);\n  dispatch_source_t timer =\n      dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);\n  // Schedule the timer one second from the current time.\n  dispatch_time_t milestone =\n      dispatch_time(DISPATCH_TIME_NOW, 1LL * NSEC_PER_SEC);\n\n  dispatch_source_set_timer(timer, milestone, DISPATCH_TIME_FOREVER, 0);\n  char * volatile mem = (char * volatile)malloc(10);\n  // Both dispatch_source_set_cancel_handler() and\n  // dispatch_source_set_event_handler() use dispatch_barrier_async_f().\n  // It's tricky to test dispatch_source_set_cancel_handler() separately,\n  // so we test both here.\n  dispatch_source_set_event_handler(timer, ^{\n    dispatch_source_cancel(timer);\n  });\n  dispatch_source_set_cancel_handler(timer, ^{\n    access_memory(&mem[10]);\n  });\n  dispatch_resume(timer);\n  wait_forever();\n}\n\nvoid TestGCDGroupAsync() {\n  dispatch_queue_t queue = dispatch_get_global_queue(0, 0);\n  dispatch_group_t group = dispatch_group_create(); \n  char * volatile mem = (char * volatile)malloc(10);\n  dispatch_group_async(group, queue, ^{\n    access_memory(&mem[10]);\n  });\n  dispatch_group_wait(group, DISPATCH_TIME_FOREVER);\n  wait_forever();\n}\n\n@interface FixedArray : NSObject {\n  int items[10];\n}\n@end\n\n@implementation FixedArray\n-(int) access: (int)index {\n  return items[index];\n}\n@end\n\nvoid TestOOBNSObjects() {\n  id anObject = [FixedArray new];\n  [anObject access:1];\n  [anObject access:11];\n  [anObject release];\n}\n\nvoid TestNSURLDeallocation() {\n  NSURL *base =\n      [[NSURL alloc] initWithString:@\"file://localhost/Users/glider/Library/\"];\n  volatile NSURL *u =\n      [[NSURL alloc] initWithString:@\"Saved Application State\"\n                     relativeToURL:base];\n  [u release];\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_mem_test.cc",
    "content": "//===-- asan_mem_test.cc --------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n//===----------------------------------------------------------------------===//\n#include \"asan_test_utils.h\"\n\ntemplate<typename T>\nvoid MemSetOOBTestTemplate(size_t length) {\n  if (length == 0) return;\n  size_t size = Ident(sizeof(T) * length);\n  T *array = Ident((T*)malloc(size));\n  int element = Ident(42);\n  int zero = Ident(0);\n  void *(*MEMSET)(void *s, int c, size_t n) = Ident(memset);\n  // memset interval inside array\n  MEMSET(array, element, size);\n  MEMSET(array, element, size - 1);\n  MEMSET(array + length - 1, element, sizeof(T));\n  MEMSET(array, element, 1);\n\n  // memset 0 bytes\n  MEMSET(array - 10, element, zero);\n  MEMSET(array - 1, element, zero);\n  MEMSET(array, element, zero);\n  MEMSET(array + length, 0, zero);\n  MEMSET(array + length + 1, 0, zero);\n\n  // try to memset bytes to the right of array\n  EXPECT_DEATH(MEMSET(array, 0, size + 1),\n               RightOOBWriteMessage(0));\n  EXPECT_DEATH(MEMSET((char*)(array + length) - 1, element, 6),\n               RightOOBWriteMessage(0));\n  EXPECT_DEATH(MEMSET(array + 1, element, size + sizeof(T)),\n               RightOOBWriteMessage(0));\n  // whole interval is to the right\n  EXPECT_DEATH(MEMSET(array + length + 1, 0, 10),\n               RightOOBWriteMessage(sizeof(T)));\n\n  // try to memset bytes to the left of array\n  EXPECT_DEATH(MEMSET((char*)array - 1, element, size),\n               LeftOOBWriteMessage(1));\n  EXPECT_DEATH(MEMSET((char*)array - 5, 0, 6),\n               LeftOOBWriteMessage(5));\n  if (length >= 100) {\n    // Large OOB, we find it only if the redzone is large enough.\n    EXPECT_DEATH(memset(array - 5, element, size + 5 * sizeof(T)),\n                 LeftOOBWriteMessage(5 * sizeof(T)));\n  }\n  // whole interval is to the left\n  EXPECT_DEATH(MEMSET(array - 2, 0, sizeof(T)),\n               LeftOOBWriteMessage(2 * sizeof(T)));\n\n  // try to memset bytes both to the left & to the right\n  EXPECT_DEATH(MEMSET((char*)array - 2, element, size + 4),\n               LeftOOBWriteMessage(2));\n\n  free(array);\n}\n\nTEST(AddressSanitizer, MemSetOOBTest) {\n  MemSetOOBTestTemplate<char>(100);\n  MemSetOOBTestTemplate<int>(5);\n  MemSetOOBTestTemplate<double>(256);\n  // We can test arrays of structres/classes here, but what for?\n}\n\n// Try to allocate two arrays of 'size' bytes that are near each other.\n// Strictly speaking we are not guaranteed to find such two pointers,\n// but given the structure of asan's allocator we will.\nstatic bool AllocateTwoAdjacentArrays(char **x1, char **x2, size_t size) {\n  vector<uintptr_t> v;\n  bool res = false;\n  for (size_t i = 0; i < 1000U && !res; i++) {\n    v.push_back(reinterpret_cast<uintptr_t>(new char[size]));\n    if (i == 0) continue;\n    sort(v.begin(), v.end());\n    for (size_t j = 1; j < v.size(); j++) {\n      assert(v[j] > v[j-1]);\n      if ((size_t)(v[j] - v[j-1]) < size * 2) {\n        *x2 = reinterpret_cast<char*>(v[j]);\n        *x1 = reinterpret_cast<char*>(v[j-1]);\n        res = true;\n        break;\n      }\n    }\n  }\n\n  for (size_t i = 0; i < v.size(); i++) {\n    char *p = reinterpret_cast<char *>(v[i]);\n    if (res && p == *x1) continue;\n    if (res && p == *x2) continue;\n    delete [] p;\n  }\n  return res;\n}\n\nTEST(AddressSanitizer, LargeOOBInMemset) {\n  for (size_t size = 200; size < 100000; size += size / 2) {\n    char *x1, *x2;\n    if (!Ident(AllocateTwoAdjacentArrays)(&x1, &x2, size))\n      continue;\n    // fprintf(stderr, \"  large oob memset: %p %p %zd\\n\", x1, x2, size);\n    // Do a memset on x1 with huge out-of-bound access that will end up in x2.\n    EXPECT_DEATH(Ident(memset)(x1, 0, size * 2),\n                 \"is located 0 bytes to the right\");\n    delete [] x1;\n    delete [] x2;\n    return;\n  }\n  assert(0 && \"Did not find two adjacent malloc-ed pointers\");\n}\n\n// Same test for memcpy and memmove functions\ntemplate <typename T, class M>\nvoid MemTransferOOBTestTemplate(size_t length) {\n  if (length == 0) return;\n  size_t size = Ident(sizeof(T) * length);\n  T *src = Ident((T*)malloc(size));\n  T *dest = Ident((T*)malloc(size));\n  int zero = Ident(0);\n\n  // valid transfer of bytes between arrays\n  M::transfer(dest, src, size);\n  M::transfer(dest + 1, src, size - sizeof(T));\n  M::transfer(dest, src + length - 1, sizeof(T));\n  M::transfer(dest, src, 1);\n\n  // transfer zero bytes\n  M::transfer(dest - 1, src, 0);\n  M::transfer(dest + length, src, zero);\n  M::transfer(dest, src - 1, zero);\n  M::transfer(dest, src, zero);\n\n  // try to change mem to the right of dest\n  EXPECT_DEATH(M::transfer(dest + 1, src, size),\n               RightOOBWriteMessage(0));\n  EXPECT_DEATH(M::transfer((char*)(dest + length) - 1, src, 5),\n               RightOOBWriteMessage(0));\n\n  // try to change mem to the left of dest\n  EXPECT_DEATH(M::transfer(dest - 2, src, size),\n               LeftOOBWriteMessage(2 * sizeof(T)));\n  EXPECT_DEATH(M::transfer((char*)dest - 3, src, 4),\n               LeftOOBWriteMessage(3));\n\n  // try to access mem to the right of src\n  EXPECT_DEATH(M::transfer(dest, src + 2, size),\n               RightOOBReadMessage(0));\n  EXPECT_DEATH(M::transfer(dest, (char*)(src + length) - 3, 6),\n               RightOOBReadMessage(0));\n\n  // try to access mem to the left of src\n  EXPECT_DEATH(M::transfer(dest, src - 1, size),\n               LeftOOBReadMessage(sizeof(T)));\n  EXPECT_DEATH(M::transfer(dest, (char*)src - 6, 7),\n               LeftOOBReadMessage(6));\n\n  // Generally we don't need to test cases where both accessing src and writing\n  // to dest address to poisoned memory.\n\n  T *big_src = Ident((T*)malloc(size * 2));\n  T *big_dest = Ident((T*)malloc(size * 2));\n  // try to change mem to both sides of dest\n  EXPECT_DEATH(M::transfer(dest - 1, big_src, size * 2),\n               LeftOOBWriteMessage(sizeof(T)));\n  // try to access mem to both sides of src\n  EXPECT_DEATH(M::transfer(big_dest, src - 2, size * 2),\n               LeftOOBReadMessage(2 * sizeof(T)));\n\n  free(src);\n  free(dest);\n  free(big_src);\n  free(big_dest);\n}\n\nclass MemCpyWrapper {\n public:\n  static void* transfer(void *to, const void *from, size_t size) {\n    return Ident(memcpy)(to, from, size);\n  }\n};\n\nTEST(AddressSanitizer, MemCpyOOBTest) {\n  MemTransferOOBTestTemplate<char, MemCpyWrapper>(100);\n  MemTransferOOBTestTemplate<int, MemCpyWrapper>(1024);\n}\n\nclass MemMoveWrapper {\n public:\n  static void* transfer(void *to, const void *from, size_t size) {\n    return Ident(memmove)(to, from, size);\n  }\n};\n\nTEST(AddressSanitizer, MemMoveOOBTest) {\n  MemTransferOOBTestTemplate<char, MemMoveWrapper>(100);\n  MemTransferOOBTestTemplate<int, MemMoveWrapper>(1024);\n}\n\n\nTEST(AddressSanitizer, MemCmpOOBTest) {\n  size_t size = Ident(100);\n  char *s1 = MallocAndMemsetString(size);\n  char *s2 = MallocAndMemsetString(size);\n  // Normal memcmp calls.\n  Ident(memcmp(s1, s2, size));\n  Ident(memcmp(s1 + size - 1, s2 + size - 1, 1));\n  Ident(memcmp(s1 - 1, s2 - 1, 0));\n  // One of arguments points to not allocated memory.\n  EXPECT_DEATH(Ident(memcmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1));\n  EXPECT_DEATH(Ident(memcmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1));\n  EXPECT_DEATH(Ident(memcmp)(s1 + size, s2, 1), RightOOBReadMessage(0));\n  EXPECT_DEATH(Ident(memcmp)(s1, s2 + size, 1), RightOOBReadMessage(0));\n  // Hit unallocated memory and die.\n  EXPECT_DEATH(Ident(memcmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0));\n  EXPECT_DEATH(Ident(memcmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0));\n  // Zero bytes are not terminators and don't prevent from OOB.\n  s1[size - 1] = '\\0';\n  s2[size - 1] = '\\0';\n  EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));\n\n  // Even if the buffers differ in the first byte, we still assume that\n  // memcmp may access the whole buffer and thus reporting the overflow here:\n  s1[0] = 1;\n  s2[0] = 123;\n  EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));\n\n  free(s1);\n  free(s2);\n}\n\n\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_noinst_test.cc",
    "content": "//===-- asan_noinst_test.cc -----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// This test file should be compiled w/o asan instrumentation.\n//===----------------------------------------------------------------------===//\n\n#include \"asan_allocator.h\"\n#include \"asan_internal.h\"\n#include \"asan_mapping.h\"\n#include \"asan_test_utils.h\"\n#include <sanitizer/allocator_interface.h>\n\n#include <assert.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>  // for memset()\n#include <algorithm>\n#include <vector>\n#include <limits>\n\n// ATTENTION!\n// Please don't call intercepted functions (including malloc() and friends)\n// in this test. The static runtime library is linked explicitly (without\n// -fsanitize=address), thus the interceptors do not work correctly on OS X.\n\n// Make sure __asan_init is called before any test case is run.\nstruct AsanInitCaller {\n  AsanInitCaller() {\n    __asan::DisableReexec();\n    __asan_init();\n  }\n};\nstatic AsanInitCaller asan_init_caller;\n\nTEST(AddressSanitizer, InternalSimpleDeathTest) {\n  EXPECT_DEATH(exit(1), \"\");\n}\n\nstatic void MallocStress(size_t n) {\n  u32 seed = my_rand();\n  BufferedStackTrace stack1;\n  stack1.trace_buffer[0] = 0xa123;\n  stack1.trace_buffer[1] = 0xa456;\n  stack1.size = 2;\n\n  BufferedStackTrace stack2;\n  stack2.trace_buffer[0] = 0xb123;\n  stack2.trace_buffer[1] = 0xb456;\n  stack2.size = 2;\n\n  BufferedStackTrace stack3;\n  stack3.trace_buffer[0] = 0xc123;\n  stack3.trace_buffer[1] = 0xc456;\n  stack3.size = 2;\n\n  std::vector<void *> vec;\n  for (size_t i = 0; i < n; i++) {\n    if ((i % 3) == 0) {\n      if (vec.empty()) continue;\n      size_t idx = my_rand_r(&seed) % vec.size();\n      void *ptr = vec[idx];\n      vec[idx] = vec.back();\n      vec.pop_back();\n      __asan::asan_free(ptr, &stack1, __asan::FROM_MALLOC);\n    } else {\n      size_t size = my_rand_r(&seed) % 1000 + 1;\n      switch ((my_rand_r(&seed) % 128)) {\n        case 0: size += 1024; break;\n        case 1: size += 2048; break;\n        case 2: size += 4096; break;\n      }\n      size_t alignment = 1 << (my_rand_r(&seed) % 10 + 1);\n      char *ptr = (char*)__asan::asan_memalign(alignment, size,\n                                               &stack2, __asan::FROM_MALLOC);\n      EXPECT_EQ(size, __asan::asan_malloc_usable_size(ptr, 0, 0));\n      vec.push_back(ptr);\n      ptr[0] = 0;\n      ptr[size-1] = 0;\n      ptr[size/2] = 0;\n    }\n  }\n  for (size_t i = 0; i < vec.size(); i++)\n    __asan::asan_free(vec[i], &stack3, __asan::FROM_MALLOC);\n}\n\n\nTEST(AddressSanitizer, NoInstMallocTest) {\n  MallocStress(ASAN_LOW_MEMORY ? 300000 : 1000000);\n}\n\nTEST(AddressSanitizer, ThreadedMallocStressTest) {\n  const int kNumThreads = 4;\n  const int kNumIterations = (ASAN_LOW_MEMORY) ? 10000 : 100000;\n  pthread_t t[kNumThreads];\n  for (int i = 0; i < kNumThreads; i++) {\n    PTHREAD_CREATE(&t[i], 0, (void* (*)(void *x))MallocStress,\n        (void*)kNumIterations);\n  }\n  for (int i = 0; i < kNumThreads; i++) {\n    PTHREAD_JOIN(t[i], 0);\n  }\n}\n\nstatic void PrintShadow(const char *tag, uptr ptr, size_t size) {\n  fprintf(stderr, \"%s shadow: %lx size % 3ld: \", tag, (long)ptr, (long)size);\n  uptr prev_shadow = 0;\n  for (sptr i = -32; i < (sptr)size + 32; i++) {\n    uptr shadow = __asan::MemToShadow(ptr + i);\n    if (i == 0 || i == (sptr)size)\n      fprintf(stderr, \".\");\n    if (shadow != prev_shadow) {\n      prev_shadow = shadow;\n      fprintf(stderr, \"%02x\", (int)*(u8*)shadow);\n    }\n  }\n  fprintf(stderr, \"\\n\");\n}\n\nTEST(AddressSanitizer, DISABLED_InternalPrintShadow) {\n  for (size_t size = 1; size <= 513; size++) {\n    char *ptr = new char[size];\n    PrintShadow(\"m\", (uptr)ptr, size);\n    delete [] ptr;\n    PrintShadow(\"f\", (uptr)ptr, size);\n  }\n}\n\nTEST(AddressSanitizer, QuarantineTest) {\n  BufferedStackTrace stack;\n  stack.trace_buffer[0] = 0x890;\n  stack.size = 1;\n\n  const int size = 1024;\n  void *p = __asan::asan_malloc(size, &stack);\n  __asan::asan_free(p, &stack, __asan::FROM_MALLOC);\n  size_t i;\n  size_t max_i = 1 << 30;\n  for (i = 0; i < max_i; i++) {\n    void *p1 = __asan::asan_malloc(size, &stack);\n    __asan::asan_free(p1, &stack, __asan::FROM_MALLOC);\n    if (p1 == p) break;\n  }\n  EXPECT_GE(i, 10000U);\n  EXPECT_LT(i, max_i);\n}\n\nvoid *ThreadedQuarantineTestWorker(void *unused) {\n  (void)unused;\n  u32 seed = my_rand();\n  BufferedStackTrace stack;\n  stack.trace_buffer[0] = 0x890;\n  stack.size = 1;\n\n  for (size_t i = 0; i < 1000; i++) {\n    void *p = __asan::asan_malloc(1 + (my_rand_r(&seed) % 4000), &stack);\n    __asan::asan_free(p, &stack, __asan::FROM_MALLOC);\n  }\n  return NULL;\n}\n\n// Check that the thread local allocators are flushed when threads are\n// destroyed.\nTEST(AddressSanitizer, ThreadedQuarantineTest) {\n  const int n_threads = 3000;\n  size_t mmaped1 = __sanitizer_get_heap_size();\n  for (int i = 0; i < n_threads; i++) {\n    pthread_t t;\n    PTHREAD_CREATE(&t, NULL, ThreadedQuarantineTestWorker, 0);\n    PTHREAD_JOIN(t, 0);\n    size_t mmaped2 = __sanitizer_get_heap_size();\n    EXPECT_LT(mmaped2 - mmaped1, 320U * (1 << 20));\n  }\n}\n\nvoid *ThreadedOneSizeMallocStress(void *unused) {\n  (void)unused;\n  BufferedStackTrace stack;\n  stack.trace_buffer[0] = 0x890;\n  stack.size = 1;\n  const size_t kNumMallocs = 1000;\n  for (int iter = 0; iter < 1000; iter++) {\n    void *p[kNumMallocs];\n    for (size_t i = 0; i < kNumMallocs; i++) {\n      p[i] = __asan::asan_malloc(32, &stack);\n    }\n    for (size_t i = 0; i < kNumMallocs; i++) {\n      __asan::asan_free(p[i], &stack, __asan::FROM_MALLOC);\n    }\n  }\n  return NULL;\n}\n\nTEST(AddressSanitizer, ThreadedOneSizeMallocStressTest) {\n  const int kNumThreads = 4;\n  pthread_t t[kNumThreads];\n  for (int i = 0; i < kNumThreads; i++) {\n    PTHREAD_CREATE(&t[i], 0, ThreadedOneSizeMallocStress, 0);\n  }\n  for (int i = 0; i < kNumThreads; i++) {\n    PTHREAD_JOIN(t[i], 0);\n  }\n}\n\nTEST(AddressSanitizer, ShadowRegionIsPoisonedTest) {\n  using __asan::kHighMemEnd;\n  // Check that __asan_region_is_poisoned works for shadow regions.\n  uptr ptr = kLowShadowBeg + 200;\n  EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));\n  ptr = kShadowGapBeg + 200;\n  EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));\n  ptr = kHighShadowBeg + 200;\n  EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));\n}\n\n// Test __asan_load1 & friends.\nTEST(AddressSanitizer, LoadStoreCallbacks) {\n  typedef void (*CB)(uptr p);\n  CB cb[2][5] = {\n      {\n        __asan_load1, __asan_load2, __asan_load4, __asan_load8, __asan_load16,\n      }, {\n        __asan_store1, __asan_store2, __asan_store4, __asan_store8,\n        __asan_store16,\n      }\n  };\n\n  uptr buggy_ptr;\n\n  __asan_test_only_reported_buggy_pointer = &buggy_ptr;\n  BufferedStackTrace stack;\n  stack.trace_buffer[0] = 0x890;\n  stack.size = 1;\n\n  for (uptr len = 16; len <= 32; len++) {\n    char *ptr = (char*) __asan::asan_malloc(len, &stack);\n    uptr p = reinterpret_cast<uptr>(ptr);\n    for (uptr is_write = 0; is_write <= 1; is_write++) {\n      for (uptr size_log = 0; size_log <= 4; size_log++) {\n        uptr size = 1 << size_log;\n        CB call = cb[is_write][size_log];\n        // Iterate only size-aligned offsets.\n        for (uptr offset = 0; offset <= len; offset += size) {\n          buggy_ptr = 0;\n          call(p + offset);\n          if (offset + size <= len)\n            EXPECT_EQ(buggy_ptr, 0U);\n          else\n            EXPECT_EQ(buggy_ptr, p + offset);\n        }\n      }\n    }\n    __asan::asan_free(ptr, &stack, __asan::FROM_MALLOC);\n  }\n  __asan_test_only_reported_buggy_pointer = 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_oob_test.cc",
    "content": "//===-- asan_oob_test.cc --------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n//===----------------------------------------------------------------------===//\n#include \"asan_test_utils.h\"\n\nNOINLINE void asan_write_sized_aligned(uint8_t *p, size_t size) {\n  EXPECT_EQ(0U, ((uintptr_t)p % size));\n  if      (size == 1) asan_write((uint8_t*)p);\n  else if (size == 2) asan_write((uint16_t*)p);\n  else if (size == 4) asan_write((uint32_t*)p);\n  else if (size == 8) asan_write((uint64_t*)p);\n}\n\ntemplate<typename T>\nNOINLINE void oob_test(int size, int off) {\n  char *p = (char*)malloc_aaa(size);\n  // fprintf(stderr, \"writing %d byte(s) into [%p,%p) with offset %d\\n\",\n  //        sizeof(T), p, p + size, off);\n  asan_write((T*)(p + off));\n  free_aaa(p);\n}\n\ntemplate<typename T>\nvoid OOBTest() {\n  char expected_str[100];\n  for (int size = sizeof(T); size < 20; size += 5) {\n    for (int i = -5; i < 0; i++) {\n      const char *str =\n          \"is located.*%d byte.*to the left\";\n      sprintf(expected_str, str, abs(i));\n      EXPECT_DEATH(oob_test<T>(size, i), expected_str);\n    }\n\n    for (int i = 0; i < (int)(size - sizeof(T) + 1); i++)\n      oob_test<T>(size, i);\n\n    for (int i = size - sizeof(T) + 1; i <= (int)(size + 2 * sizeof(T)); i++) {\n      const char *str =\n          \"is located.*%d byte.*to the right\";\n      int off = i >= size ? (i - size) : 0;\n      // we don't catch unaligned partially OOB accesses.\n      if (i % sizeof(T)) continue;\n      sprintf(expected_str, str, off);\n      EXPECT_DEATH(oob_test<T>(size, i), expected_str);\n    }\n  }\n\n  EXPECT_DEATH(oob_test<T>(kLargeMalloc, -1),\n          \"is located.*1 byte.*to the left\");\n  EXPECT_DEATH(oob_test<T>(kLargeMalloc, kLargeMalloc),\n          \"is located.*0 byte.*to the right\");\n}\n\n// TODO(glider): the following tests are EXTREMELY slow on Darwin:\n//   AddressSanitizer.OOB_char (125503 ms)\n//   AddressSanitizer.OOB_int (126890 ms)\n//   AddressSanitizer.OOBRightTest (315605 ms)\n//   AddressSanitizer.SimpleStackTest (366559 ms)\n\nTEST(AddressSanitizer, OOB_char) {\n  OOBTest<U1>();\n}\n\nTEST(AddressSanitizer, OOB_int) {\n  OOBTest<U4>();\n}\n\nTEST(AddressSanitizer, OOBRightTest) {\n  size_t max_access_size = SANITIZER_WORDSIZE == 64 ? 8 : 4;\n  for (size_t access_size = 1; access_size <= max_access_size;\n       access_size *= 2) {\n    for (size_t alloc_size = 1; alloc_size <= 8; alloc_size++) {\n      for (size_t offset = 0; offset <= 8; offset += access_size) {\n        void *p = malloc(alloc_size);\n        // allocated: [p, p + alloc_size)\n        // accessed:  [p + offset, p + offset + access_size)\n        uint8_t *addr = (uint8_t*)p + offset;\n        if (offset + access_size <= alloc_size) {\n          asan_write_sized_aligned(addr, access_size);\n        } else {\n          int outside_bytes = offset > alloc_size ? (offset - alloc_size) : 0;\n          const char *str =\n              \"is located.%d *byte.*to the right\";\n          char expected_str[100];\n          sprintf(expected_str, str, outside_bytes);\n          EXPECT_DEATH(asan_write_sized_aligned(addr, access_size),\n                       expected_str);\n        }\n        free(p);\n      }\n    }\n  }\n}\n\nTEST(AddressSanitizer, LargeOOBRightTest) {\n  size_t large_power_of_two = 1 << 19;\n  for (size_t i = 16; i <= 256; i *= 2) {\n    size_t size = large_power_of_two - i;\n    char *p = Ident(new char[size]);\n    EXPECT_DEATH(p[size] = 0, \"is located 0 bytes to the right\");\n    delete [] p;\n  }\n}\n\nTEST(AddressSanitizer, DISABLED_DemoOOBLeftLow) {\n  oob_test<U1>(10, -1);\n}\n\nTEST(AddressSanitizer, DISABLED_DemoOOBLeftHigh) {\n  oob_test<U1>(kLargeMalloc, -1);\n}\n\nTEST(AddressSanitizer, DISABLED_DemoOOBRightLow) {\n  oob_test<U1>(10, 10);\n}\n\nTEST(AddressSanitizer, DISABLED_DemoOOBRightHigh) {\n  oob_test<U1>(kLargeMalloc, kLargeMalloc);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_racy_double_free_test.cc",
    "content": "#include <pthread.h>\n#include <stdlib.h>\n#include <stdio.h>\n\nconst int N = 1000;\nvoid *x[N];\n\nvoid *Thread1(void *unused) {\n  for (int i = 0; i < N; i++) {\n    fprintf(stderr, \"%s %d\\n\", __func__, i);\n    free(x[i]);\n  }\n  return NULL;\n}\n\nvoid *Thread2(void *unused) {\n  for (int i = 0; i < N; i++) {\n    fprintf(stderr, \"%s %d\\n\", __func__, i);\n    free(x[i]);\n  }\n  return NULL;\n}\n\nint main() {\n  for (int i = 0; i < N; i++)\n    x[i] = malloc(128);\n  pthread_t t[2];\n  pthread_create(&t[0], 0, Thread1, 0);\n  pthread_create(&t[1], 0, Thread2, 0);\n  pthread_join(t[0], 0);\n  pthread_join(t[1], 0);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_str_test.cc",
    "content": "//=-- asan_str_test.cc ----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n//===----------------------------------------------------------------------===//\n#include \"asan_test_utils.h\"\n\n#if defined(__APPLE__)\n#include <AvailabilityMacros.h>  // For MAC_OS_X_VERSION_*\n#endif\n\n// Used for string functions tests\nstatic char global_string[] = \"global\";\nstatic size_t global_string_length = 6;\n\n// Input to a test is a zero-terminated string str with given length\n// Accesses to the bytes to the left and to the right of str\n// are presumed to produce OOB errors\nvoid StrLenOOBTestTemplate(char *str, size_t length, bool is_global) {\n  // Normal strlen calls\n  EXPECT_EQ(strlen(str), length);\n  if (length > 0) {\n    EXPECT_EQ(length - 1, strlen(str + 1));\n    EXPECT_EQ(0U, strlen(str + length));\n  }\n  // Arg of strlen is not malloced, OOB access\n  if (!is_global) {\n    // We don't insert RedZones to the left of global variables\n    EXPECT_DEATH(Ident(strlen(str - 1)), LeftOOBReadMessage(1));\n    EXPECT_DEATH(Ident(strlen(str - 5)), LeftOOBReadMessage(5));\n  }\n  EXPECT_DEATH(Ident(strlen(str + length + 1)), RightOOBReadMessage(0));\n  // Overwrite terminator\n  str[length] = 'a';\n  // String is not zero-terminated, strlen will lead to OOB access\n  EXPECT_DEATH(Ident(strlen(str)), RightOOBReadMessage(0));\n  EXPECT_DEATH(Ident(strlen(str + length)), RightOOBReadMessage(0));\n  // Restore terminator\n  str[length] = 0;\n}\nTEST(AddressSanitizer, StrLenOOBTest) {\n  // Check heap-allocated string\n  size_t length = Ident(10);\n  char *heap_string = Ident((char*)malloc(length + 1));\n  char stack_string[10 + 1];\n  break_optimization(&stack_string);\n  for (size_t i = 0; i < length; i++) {\n    heap_string[i] = 'a';\n    stack_string[i] = 'b';\n  }\n  heap_string[length] = 0;\n  stack_string[length] = 0;\n  StrLenOOBTestTemplate(heap_string, length, false);\n  // TODO(samsonov): Fix expected messages in StrLenOOBTestTemplate to\n  //      make test for stack_string work. Or move it to output tests.\n  // StrLenOOBTestTemplate(stack_string, length, false);\n  StrLenOOBTestTemplate(global_string, global_string_length, true);\n  free(heap_string);\n}\n\nTEST(AddressSanitizer, WcsLenTest) {\n  EXPECT_EQ(0U, wcslen(Ident(L\"\")));\n  size_t hello_len = 13;\n  size_t hello_size = (hello_len + 1) * sizeof(wchar_t);\n  EXPECT_EQ(hello_len, wcslen(Ident(L\"Hello, World!\")));\n  wchar_t *heap_string = Ident((wchar_t*)malloc(hello_size));\n  memcpy(heap_string, L\"Hello, World!\", hello_size);\n  EXPECT_EQ(hello_len, Ident(wcslen(heap_string)));\n  EXPECT_DEATH(Ident(wcslen(heap_string + 14)), RightOOBReadMessage(0));\n  free(heap_string);\n}\n\n#if SANITIZER_TEST_HAS_STRNLEN\nTEST(AddressSanitizer, StrNLenOOBTest) {\n  size_t size = Ident(123);\n  char *str = MallocAndMemsetString(size);\n  // Normal strnlen calls.\n  Ident(strnlen(str - 1, 0));\n  Ident(strnlen(str, size));\n  Ident(strnlen(str + size - 1, 1));\n  str[size - 1] = '\\0';\n  Ident(strnlen(str, 2 * size));\n  // Argument points to not allocated memory.\n  EXPECT_DEATH(Ident(strnlen(str - 1, 1)), LeftOOBReadMessage(1));\n  EXPECT_DEATH(Ident(strnlen(str + size, 1)), RightOOBReadMessage(0));\n  // Overwrite the terminating '\\0' and hit unallocated memory.\n  str[size - 1] = 'z';\n  EXPECT_DEATH(Ident(strnlen(str, size + 1)), RightOOBReadMessage(0));\n  free(str);\n}\n#endif  // SANITIZER_TEST_HAS_STRNLEN\n\nTEST(AddressSanitizer, StrDupOOBTest) {\n  size_t size = Ident(42);\n  char *str = MallocAndMemsetString(size);\n  char *new_str;\n  // Normal strdup calls.\n  str[size - 1] = '\\0';\n  new_str = strdup(str);\n  free(new_str);\n  new_str = strdup(str + size - 1);\n  free(new_str);\n  // Argument points to not allocated memory.\n  EXPECT_DEATH(Ident(strdup(str - 1)), LeftOOBReadMessage(1));\n  EXPECT_DEATH(Ident(strdup(str + size)), RightOOBReadMessage(0));\n  // Overwrite the terminating '\\0' and hit unallocated memory.\n  str[size - 1] = 'z';\n  EXPECT_DEATH(Ident(strdup(str)), RightOOBReadMessage(0));\n  free(str);\n}\n\nTEST(AddressSanitizer, StrCpyOOBTest) {\n  size_t to_size = Ident(30);\n  size_t from_size = Ident(6);  // less than to_size\n  char *to = Ident((char*)malloc(to_size));\n  char *from = Ident((char*)malloc(from_size));\n  // Normal strcpy calls.\n  strcpy(from, \"hello\");\n  strcpy(to, from);\n  strcpy(to + to_size - from_size, from);\n  // Length of \"from\" is too small.\n  EXPECT_DEATH(Ident(strcpy(from, \"hello2\")), RightOOBWriteMessage(0));\n  // \"to\" or \"from\" points to not allocated memory.\n  EXPECT_DEATH(Ident(strcpy(to - 1, from)), LeftOOBWriteMessage(1));\n  EXPECT_DEATH(Ident(strcpy(to, from - 1)), LeftOOBReadMessage(1));\n  EXPECT_DEATH(Ident(strcpy(to, from + from_size)), RightOOBReadMessage(0));\n  EXPECT_DEATH(Ident(strcpy(to + to_size, from)), RightOOBWriteMessage(0));\n  // Overwrite the terminating '\\0' character and hit unallocated memory.\n  from[from_size - 1] = '!';\n  EXPECT_DEATH(Ident(strcpy(to, from)), RightOOBReadMessage(0));\n  free(to);\n  free(from);\n}\n\nTEST(AddressSanitizer, StrNCpyOOBTest) {\n  size_t to_size = Ident(20);\n  size_t from_size = Ident(6);  // less than to_size\n  char *to = Ident((char*)malloc(to_size));\n  // From is a zero-terminated string \"hello\\0\" of length 6\n  char *from = Ident((char*)malloc(from_size));\n  strcpy(from, \"hello\");\n  // copy 0 bytes\n  strncpy(to, from, 0);\n  strncpy(to - 1, from - 1, 0);\n  // normal strncpy calls\n  strncpy(to, from, from_size);\n  strncpy(to, from, to_size);\n  strncpy(to, from + from_size - 1, to_size);\n  strncpy(to + to_size - 1, from, 1);\n  // One of {to, from} points to not allocated memory\n  EXPECT_DEATH(Ident(strncpy(to, from - 1, from_size)),\n               LeftOOBReadMessage(1));\n  EXPECT_DEATH(Ident(strncpy(to - 1, from, from_size)),\n               LeftOOBWriteMessage(1));\n  EXPECT_DEATH(Ident(strncpy(to, from + from_size, 1)),\n               RightOOBReadMessage(0));\n  EXPECT_DEATH(Ident(strncpy(to + to_size, from, 1)),\n               RightOOBWriteMessage(0));\n  // Length of \"to\" is too small\n  EXPECT_DEATH(Ident(strncpy(to + to_size - from_size + 1, from, from_size)),\n               RightOOBWriteMessage(0));\n  EXPECT_DEATH(Ident(strncpy(to + 1, from, to_size)),\n               RightOOBWriteMessage(0));\n  // Overwrite terminator in from\n  from[from_size - 1] = '!';\n  // normal strncpy call\n  strncpy(to, from, from_size);\n  // Length of \"from\" is too small\n  EXPECT_DEATH(Ident(strncpy(to, from, to_size)),\n               RightOOBReadMessage(0));\n  free(to);\n  free(from);\n}\n\n// Users may have different definitions of \"strchr\" and \"index\", so provide\n// function pointer typedefs and overload RunStrChrTest implementation.\n// We can't use macro for RunStrChrTest body here, as this macro would\n// confuse EXPECT_DEATH gtest macro.\ntypedef char*(*PointerToStrChr1)(const char*, int);\ntypedef char*(*PointerToStrChr2)(char*, int);\n\nUNUSED static void RunStrChrTest(PointerToStrChr1 StrChr) {\n  size_t size = Ident(100);\n  char *str = MallocAndMemsetString(size);\n  str[10] = 'q';\n  str[11] = '\\0';\n  EXPECT_EQ(str, StrChr(str, 'z'));\n  EXPECT_EQ(str + 10, StrChr(str, 'q'));\n  EXPECT_EQ(NULL, StrChr(str, 'a'));\n  // StrChr argument points to not allocated memory.\n  EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1));\n  EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0));\n  // Overwrite the terminator and hit not allocated memory.\n  str[11] = 'z';\n  EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0));\n  free(str);\n}\nUNUSED static void RunStrChrTest(PointerToStrChr2 StrChr) {\n  size_t size = Ident(100);\n  char *str = MallocAndMemsetString(size);\n  str[10] = 'q';\n  str[11] = '\\0';\n  EXPECT_EQ(str, StrChr(str, 'z'));\n  EXPECT_EQ(str + 10, StrChr(str, 'q'));\n  EXPECT_EQ(NULL, StrChr(str, 'a'));\n  // StrChr argument points to not allocated memory.\n  EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1));\n  EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0));\n  // Overwrite the terminator and hit not allocated memory.\n  str[11] = 'z';\n  EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0));\n  free(str);\n}\n\nTEST(AddressSanitizer, StrChrAndIndexOOBTest) {\n  RunStrChrTest(&strchr);\n// No index() on Windows and on Android L.\n#if !defined(_WIN32) && !defined(__ANDROID__)\n  RunStrChrTest(&index);\n#endif\n}\n\nTEST(AddressSanitizer, StrCmpAndFriendsLogicTest) {\n  // strcmp\n  EXPECT_EQ(0, strcmp(\"\", \"\"));\n  EXPECT_EQ(0, strcmp(\"abcd\", \"abcd\"));\n  EXPECT_GT(0, strcmp(\"ab\", \"ac\"));\n  EXPECT_GT(0, strcmp(\"abc\", \"abcd\"));\n  EXPECT_LT(0, strcmp(\"acc\", \"abc\"));\n  EXPECT_LT(0, strcmp(\"abcd\", \"abc\"));\n\n  // strncmp\n  EXPECT_EQ(0, strncmp(\"a\", \"b\", 0));\n  EXPECT_EQ(0, strncmp(\"abcd\", \"abcd\", 10));\n  EXPECT_EQ(0, strncmp(\"abcd\", \"abcef\", 3));\n  EXPECT_GT(0, strncmp(\"abcde\", \"abcfa\", 4));\n  EXPECT_GT(0, strncmp(\"a\", \"b\", 5));\n  EXPECT_GT(0, strncmp(\"bc\", \"bcde\", 4));\n  EXPECT_LT(0, strncmp(\"xyz\", \"xyy\", 10));\n  EXPECT_LT(0, strncmp(\"baa\", \"aaa\", 1));\n  EXPECT_LT(0, strncmp(\"zyx\", \"\", 2));\n\n#if !defined(_WIN32)  // no str[n]casecmp on Windows.\n  // strcasecmp\n  EXPECT_EQ(0, strcasecmp(\"\", \"\"));\n  EXPECT_EQ(0, strcasecmp(\"zzz\", \"zzz\"));\n  EXPECT_EQ(0, strcasecmp(\"abCD\", \"ABcd\"));\n  EXPECT_GT(0, strcasecmp(\"aB\", \"Ac\"));\n  EXPECT_GT(0, strcasecmp(\"ABC\", \"ABCd\"));\n  EXPECT_LT(0, strcasecmp(\"acc\", \"abc\"));\n  EXPECT_LT(0, strcasecmp(\"ABCd\", \"abc\"));\n\n  // strncasecmp\n  EXPECT_EQ(0, strncasecmp(\"a\", \"b\", 0));\n  EXPECT_EQ(0, strncasecmp(\"abCD\", \"ABcd\", 10));\n  EXPECT_EQ(0, strncasecmp(\"abCd\", \"ABcef\", 3));\n  EXPECT_GT(0, strncasecmp(\"abcde\", \"ABCfa\", 4));\n  EXPECT_GT(0, strncasecmp(\"a\", \"B\", 5));\n  EXPECT_GT(0, strncasecmp(\"bc\", \"BCde\", 4));\n  EXPECT_LT(0, strncasecmp(\"xyz\", \"xyy\", 10));\n  EXPECT_LT(0, strncasecmp(\"Baa\", \"aaa\", 1));\n  EXPECT_LT(0, strncasecmp(\"zyx\", \"\", 2));\n#endif\n\n  // memcmp\n  EXPECT_EQ(0, memcmp(\"a\", \"b\", 0));\n  EXPECT_EQ(0, memcmp(\"ab\\0c\", \"ab\\0c\", 4));\n  EXPECT_GT(0, memcmp(\"\\0ab\", \"\\0ac\", 3));\n  EXPECT_GT(0, memcmp(\"abb\\0\", \"abba\", 4));\n  EXPECT_LT(0, memcmp(\"ab\\0cd\", \"ab\\0c\\0\", 5));\n  EXPECT_LT(0, memcmp(\"zza\", \"zyx\", 3));\n}\n\ntypedef int(*PointerToStrCmp)(const char*, const char*);\nvoid RunStrCmpTest(PointerToStrCmp StrCmp) {\n  size_t size = Ident(100);\n  int fill = 'o';\n  char *s1 = MallocAndMemsetString(size, fill);\n  char *s2 = MallocAndMemsetString(size, fill);\n  s1[size - 1] = '\\0';\n  s2[size - 1] = '\\0';\n  // Normal StrCmp calls\n  Ident(StrCmp(s1, s2));\n  Ident(StrCmp(s1, s2 + size - 1));\n  Ident(StrCmp(s1 + size - 1, s2 + size - 1));\n  // One of arguments points to not allocated memory.\n  EXPECT_DEATH(Ident(StrCmp)(s1 - 1, s2), LeftOOBReadMessage(1));\n  EXPECT_DEATH(Ident(StrCmp)(s1, s2 - 1), LeftOOBReadMessage(1));\n  EXPECT_DEATH(Ident(StrCmp)(s1 + size, s2), RightOOBReadMessage(0));\n  EXPECT_DEATH(Ident(StrCmp)(s1, s2 + size), RightOOBReadMessage(0));\n  // Hit unallocated memory and die.\n  s1[size - 1] = fill;\n  EXPECT_DEATH(Ident(StrCmp)(s1, s1), RightOOBReadMessage(0));\n  EXPECT_DEATH(Ident(StrCmp)(s1 + size - 1, s2), RightOOBReadMessage(0));\n  free(s1);\n  free(s2);\n}\n\nTEST(AddressSanitizer, StrCmpOOBTest) {\n  RunStrCmpTest(&strcmp);\n}\n\n#if !defined(_WIN32)  // no str[n]casecmp on Windows.\nTEST(AddressSanitizer, StrCaseCmpOOBTest) {\n  RunStrCmpTest(&strcasecmp);\n}\n#endif\n\ntypedef int(*PointerToStrNCmp)(const char*, const char*, size_t);\nvoid RunStrNCmpTest(PointerToStrNCmp StrNCmp) {\n  size_t size = Ident(100);\n  char *s1 = MallocAndMemsetString(size);\n  char *s2 = MallocAndMemsetString(size);\n  s1[size - 1] = '\\0';\n  s2[size - 1] = '\\0';\n  // Normal StrNCmp calls\n  Ident(StrNCmp(s1, s2, size + 2));\n  s1[size - 1] = 'z';\n  s2[size - 1] = 'x';\n  Ident(StrNCmp(s1 + size - 2, s2 + size - 2, size));\n  s2[size - 1] = 'z';\n  Ident(StrNCmp(s1 - 1, s2 - 1, 0));\n  Ident(StrNCmp(s1 + size - 1, s2 + size - 1, 1));\n  // One of arguments points to not allocated memory.\n  EXPECT_DEATH(Ident(StrNCmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1));\n  EXPECT_DEATH(Ident(StrNCmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1));\n  EXPECT_DEATH(Ident(StrNCmp)(s1 + size, s2, 1), RightOOBReadMessage(0));\n  EXPECT_DEATH(Ident(StrNCmp)(s1, s2 + size, 1), RightOOBReadMessage(0));\n  // Hit unallocated memory and die.\n  EXPECT_DEATH(Ident(StrNCmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0));\n  EXPECT_DEATH(Ident(StrNCmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0));\n  free(s1);\n  free(s2);\n}\n\nTEST(AddressSanitizer, StrNCmpOOBTest) {\n  RunStrNCmpTest(&strncmp);\n}\n\n#if !defined(_WIN32)  // no str[n]casecmp on Windows.\nTEST(AddressSanitizer, StrNCaseCmpOOBTest) {\n  RunStrNCmpTest(&strncasecmp);\n}\n#endif\n\nTEST(AddressSanitizer, StrCatOOBTest) {\n  // strcat() reads strlen(to) bytes from |to| before concatenating.\n  size_t to_size = Ident(100);\n  char *to = MallocAndMemsetString(to_size);\n  to[0] = '\\0';\n  size_t from_size = Ident(20);\n  char *from = MallocAndMemsetString(from_size);\n  from[from_size - 1] = '\\0';\n  // Normal strcat calls.\n  strcat(to, from);\n  strcat(to, from);\n  strcat(to + from_size, from + from_size - 2);\n  // Passing an invalid pointer is an error even when concatenating an empty\n  // string.\n  EXPECT_DEATH(strcat(to - 1, from + from_size - 1), LeftOOBAccessMessage(1));\n  // One of arguments points to not allocated memory.\n  EXPECT_DEATH(strcat(to - 1, from), LeftOOBAccessMessage(1));\n  EXPECT_DEATH(strcat(to, from - 1), LeftOOBReadMessage(1));\n  EXPECT_DEATH(strcat(to, from + from_size), RightOOBReadMessage(0));\n\n  // \"from\" is not zero-terminated.\n  from[from_size - 1] = 'z';\n  EXPECT_DEATH(strcat(to, from), RightOOBReadMessage(0));\n  from[from_size - 1] = '\\0';\n  // \"to\" is too short to fit \"from\".\n  memset(to, 'z', to_size);\n  to[to_size - from_size + 1] = '\\0';\n  EXPECT_DEATH(strcat(to, from), RightOOBWriteMessage(0));\n  // length of \"to\" is just enough.\n  strcat(to, from + 1);\n\n  free(to);\n  free(from);\n}\n\nTEST(AddressSanitizer, StrNCatOOBTest) {\n  // strncat() reads strlen(to) bytes from |to| before concatenating.\n  size_t to_size = Ident(100);\n  char *to = MallocAndMemsetString(to_size);\n  to[0] = '\\0';\n  size_t from_size = Ident(20);\n  char *from = MallocAndMemsetString(from_size);\n  // Normal strncat calls.\n  strncat(to, from, 0);\n  strncat(to, from, from_size);\n  from[from_size - 1] = '\\0';\n  strncat(to, from, 2 * from_size);\n  // Catenating empty string with an invalid string is still an error.\n  EXPECT_DEATH(strncat(to - 1, from, 0), LeftOOBAccessMessage(1));\n  strncat(to, from + from_size - 1, 10);\n  // One of arguments points to not allocated memory.\n  EXPECT_DEATH(strncat(to - 1, from, 2), LeftOOBAccessMessage(1));\n  EXPECT_DEATH(strncat(to, from - 1, 2), LeftOOBReadMessage(1));\n  EXPECT_DEATH(strncat(to, from + from_size, 2), RightOOBReadMessage(0));\n\n  memset(from, 'z', from_size);\n  memset(to, 'z', to_size);\n  to[0] = '\\0';\n  // \"from\" is too short.\n  EXPECT_DEATH(strncat(to, from, from_size + 1), RightOOBReadMessage(0));\n  // \"to\" is too short to fit \"from\".\n  to[0] = 'z';\n  to[to_size - from_size + 1] = '\\0';\n  EXPECT_DEATH(strncat(to, from, from_size - 1), RightOOBWriteMessage(0));\n  // \"to\" is just enough.\n  strncat(to, from, from_size - 2);\n\n  free(to);\n  free(from);\n}\n\nstatic string OverlapErrorMessage(const string &func) {\n  return func + \"-param-overlap\";\n}\n\nTEST(AddressSanitizer, StrArgsOverlapTest) {\n  size_t size = Ident(100);\n  char *str = Ident((char*)malloc(size));\n\n// Do not check memcpy() on OS X 10.7 and later, where it actually aliases\n// memmove().\n#if !defined(__APPLE__) || !defined(MAC_OS_X_VERSION_10_7) || \\\n    (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)\n  // Check \"memcpy\". Use Ident() to avoid inlining.\n  memset(str, 'z', size);\n  Ident(memcpy)(str + 1, str + 11, 10);\n  Ident(memcpy)(str, str, 0);\n  EXPECT_DEATH(Ident(memcpy)(str, str + 14, 15), OverlapErrorMessage(\"memcpy\"));\n  EXPECT_DEATH(Ident(memcpy)(str + 14, str, 15), OverlapErrorMessage(\"memcpy\"));\n#endif\n\n  // We do not treat memcpy with to==from as a bug.\n  // See http://llvm.org/bugs/show_bug.cgi?id=11763.\n  // EXPECT_DEATH(Ident(memcpy)(str + 20, str + 20, 1),\n  //              OverlapErrorMessage(\"memcpy\"));\n\n  // Check \"strcpy\".\n  memset(str, 'z', size);\n  str[9] = '\\0';\n  strcpy(str + 10, str);\n  EXPECT_DEATH(strcpy(str + 9, str), OverlapErrorMessage(\"strcpy\"));\n  EXPECT_DEATH(strcpy(str, str + 4), OverlapErrorMessage(\"strcpy\"));\n  strcpy(str, str + 5);\n\n  // Check \"strncpy\".\n  memset(str, 'z', size);\n  strncpy(str, str + 10, 10);\n  EXPECT_DEATH(strncpy(str, str + 9, 10), OverlapErrorMessage(\"strncpy\"));\n  EXPECT_DEATH(strncpy(str + 9, str, 10), OverlapErrorMessage(\"strncpy\"));\n  str[10] = '\\0';\n  strncpy(str + 11, str, 20);\n  EXPECT_DEATH(strncpy(str + 10, str, 20), OverlapErrorMessage(\"strncpy\"));\n\n  // Check \"strcat\".\n  memset(str, 'z', size);\n  str[10] = '\\0';\n  str[20] = '\\0';\n  strcat(str, str + 10);\n  EXPECT_DEATH(strcat(str, str + 11), OverlapErrorMessage(\"strcat\"));\n  str[10] = '\\0';\n  strcat(str + 11, str);\n  EXPECT_DEATH(strcat(str, str + 9), OverlapErrorMessage(\"strcat\"));\n  EXPECT_DEATH(strcat(str + 9, str), OverlapErrorMessage(\"strcat\"));\n  EXPECT_DEATH(strcat(str + 10, str), OverlapErrorMessage(\"strcat\"));\n\n  // Check \"strncat\".\n  memset(str, 'z', size);\n  str[10] = '\\0';\n  strncat(str, str + 10, 10);  // from is empty\n  EXPECT_DEATH(strncat(str, str + 11, 10), OverlapErrorMessage(\"strncat\"));\n  str[10] = '\\0';\n  str[20] = '\\0';\n  strncat(str + 5, str, 5);\n  str[10] = '\\0';\n  EXPECT_DEATH(strncat(str + 5, str, 6), OverlapErrorMessage(\"strncat\"));\n  EXPECT_DEATH(strncat(str, str + 9, 10), OverlapErrorMessage(\"strncat\"));\n\n  free(str);\n}\n\ntypedef void(*PointerToCallAtoi)(const char*);\n\nvoid RunAtoiOOBTest(PointerToCallAtoi Atoi) {\n  char *array = MallocAndMemsetString(10, '1');\n  // Invalid pointer to the string.\n  EXPECT_DEATH(Atoi(array + 11), RightOOBReadMessage(1));\n  EXPECT_DEATH(Atoi(array - 1), LeftOOBReadMessage(1));\n  // Die if a buffer doesn't have terminating NULL.\n  EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));\n  // Make last symbol a terminating NULL\n  array[9] = '\\0';\n  Atoi(array);\n  // Sometimes we need to detect overflow if no digits are found.\n  memset(array, ' ', 10);\n  EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));\n  array[9] = '-';\n  EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));\n  EXPECT_DEATH(Atoi(array + 9), RightOOBReadMessage(0));\n  free(array);\n}\n\n#if !defined(_WIN32)  // FIXME: Fix and enable on Windows.\nvoid CallAtoi(const char *nptr) {\n  Ident(atoi(nptr));\n}\nvoid CallAtol(const char *nptr) {\n  Ident(atol(nptr));\n}\nvoid CallAtoll(const char *nptr) {\n  Ident(atoll(nptr));\n}\nTEST(AddressSanitizer, AtoiAndFriendsOOBTest) {\n  RunAtoiOOBTest(&CallAtoi);\n  RunAtoiOOBTest(&CallAtol);\n  RunAtoiOOBTest(&CallAtoll);\n}\n#endif\n\ntypedef void(*PointerToCallStrtol)(const char*, char**, int);\n\nvoid RunStrtolOOBTest(PointerToCallStrtol Strtol) {\n  char *array = MallocAndMemsetString(3);\n  array[0] = '1';\n  array[1] = '2';\n  array[2] = '3';\n  // Invalid pointer to the string.\n  EXPECT_DEATH(Strtol(array + 3, NULL, 0), RightOOBReadMessage(0));\n  EXPECT_DEATH(Strtol(array - 1, NULL, 0), LeftOOBReadMessage(1));\n  // Buffer overflow if there is no terminating null (depends on base).\n  EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));\n  array[2] = 'z';\n  EXPECT_DEATH(Strtol(array, NULL, 36), RightOOBReadMessage(0));\n  // Add terminating zero to get rid of overflow.\n  array[2] = '\\0';\n  Strtol(array, NULL, 36);\n  // Sometimes we need to detect overflow if no digits are found.\n  array[0] = array[1] = array[2] = ' ';\n  EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));\n  array[2] = '+';\n  EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));\n  array[2] = '-';\n  EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));\n  free(array);\n}\n\n#if !defined(_WIN32)  // FIXME: Fix and enable on Windows.\nvoid CallStrtol(const char *nptr, char **endptr, int base) {\n  Ident(strtol(nptr, endptr, base));\n}\nvoid CallStrtoll(const char *nptr, char **endptr, int base) {\n  Ident(strtoll(nptr, endptr, base));\n}\nTEST(AddressSanitizer, StrtollOOBTest) {\n  RunStrtolOOBTest(&CallStrtoll);\n}\nTEST(AddressSanitizer, StrtolOOBTest) {\n  RunStrtolOOBTest(&CallStrtol);\n}\n#endif\n\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_test.cc",
    "content": "//===-- asan_test.cc ------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n//===----------------------------------------------------------------------===//\n#include \"asan_test_utils.h\"\n\nNOINLINE void *malloc_fff(size_t size) {\n  void *res = malloc/**/(size); break_optimization(0); return res;}\nNOINLINE void *malloc_eee(size_t size) {\n  void *res = malloc_fff(size); break_optimization(0); return res;}\nNOINLINE void *malloc_ddd(size_t size) {\n  void *res = malloc_eee(size); break_optimization(0); return res;}\nNOINLINE void *malloc_ccc(size_t size) {\n  void *res = malloc_ddd(size); break_optimization(0); return res;}\nNOINLINE void *malloc_bbb(size_t size) {\n  void *res = malloc_ccc(size); break_optimization(0); return res;}\nNOINLINE void *malloc_aaa(size_t size) {\n  void *res = malloc_bbb(size); break_optimization(0); return res;}\n\nNOINLINE void free_ccc(void *p) { free(p); break_optimization(0);}\nNOINLINE void free_bbb(void *p) { free_ccc(p); break_optimization(0);}\nNOINLINE void free_aaa(void *p) { free_bbb(p); break_optimization(0);}\n\ntemplate<typename T>\nNOINLINE void uaf_test(int size, int off) {\n  void *p = malloc_aaa(size);\n  free_aaa(p);\n  for (int i = 1; i < 100; i++)\n    free_aaa(malloc_aaa(i));\n  fprintf(stderr, \"writing %ld byte(s) at %p with offset %d\\n\",\n          (long)sizeof(T), p, off);\n  asan_write((T *)((char *)p + off));\n}\n\nTEST(AddressSanitizer, HasFeatureAddressSanitizerTest) {\n#if defined(__has_feature) && __has_feature(address_sanitizer)\n  bool asan = 1;\n#elif defined(__SANITIZE_ADDRESS__)\n  bool asan = 1;\n#else\n  bool asan = 0;\n#endif\n  EXPECT_EQ(true, asan);\n}\n\nTEST(AddressSanitizer, SimpleDeathTest) {\n  EXPECT_DEATH(exit(1), \"\");\n}\n\nTEST(AddressSanitizer, VariousMallocsTest) {\n  int *a = (int*)malloc(100 * sizeof(int));\n  a[50] = 0;\n  free(a);\n\n  int *r = (int*)malloc(10);\n  r = (int*)realloc(r, 2000 * sizeof(int));\n  r[1000] = 0;\n  free(r);\n\n  int *b = new int[100];\n  b[50] = 0;\n  delete [] b;\n\n  int *c = new int;\n  *c = 0;\n  delete c;\n\n#if SANITIZER_TEST_HAS_POSIX_MEMALIGN\n  int *pm;\n  int pm_res = posix_memalign((void**)&pm, kPageSize, kPageSize);\n  EXPECT_EQ(0, pm_res);\n  free(pm);\n#endif  // SANITIZER_TEST_HAS_POSIX_MEMALIGN\n\n#if SANITIZER_TEST_HAS_MEMALIGN\n  int *ma = (int*)memalign(kPageSize, kPageSize);\n  EXPECT_EQ(0U, (uintptr_t)ma % kPageSize);\n  ma[123] = 0;\n  free(ma);\n#endif  // SANITIZER_TEST_HAS_MEMALIGN\n}\n\nTEST(AddressSanitizer, CallocTest) {\n  int *a = (int*)calloc(100, sizeof(int));\n  EXPECT_EQ(0, a[10]);\n  free(a);\n}\n\nTEST(AddressSanitizer, CallocReturnsZeroMem) {\n  size_t sizes[] = {16, 1000, 10000, 100000, 2100000};\n  for (size_t s = 0; s < sizeof(sizes)/sizeof(sizes[0]); s++) {\n    size_t size = sizes[s];\n    for (size_t iter = 0; iter < 5; iter++) {\n      char *x = Ident((char*)calloc(1, size));\n      EXPECT_EQ(x[0], 0);\n      EXPECT_EQ(x[size - 1], 0);\n      EXPECT_EQ(x[size / 2], 0);\n      EXPECT_EQ(x[size / 3], 0);\n      EXPECT_EQ(x[size / 4], 0);\n      memset(x, 0x42, size);\n      free(Ident(x));\n#if !defined(_WIN32)\n      // FIXME: OOM on Windows. We should just make this a lit test\n      // with quarantine size set to 1.\n      free(Ident(malloc(Ident(1 << 27))));  // Try to drain the quarantine.\n#endif\n    }\n  }\n}\n\n// No valloc on Windows or Android.\n#if !defined(_WIN32) && !defined(__ANDROID__)\nTEST(AddressSanitizer, VallocTest) {\n  void *a = valloc(100);\n  EXPECT_EQ(0U, (uintptr_t)a % kPageSize);\n  free(a);\n}\n#endif\n\n#if SANITIZER_TEST_HAS_PVALLOC\nTEST(AddressSanitizer, PvallocTest) {\n  char *a = (char*)pvalloc(kPageSize + 100);\n  EXPECT_EQ(0U, (uintptr_t)a % kPageSize);\n  a[kPageSize + 101] = 1;  // we should not report an error here.\n  free(a);\n\n  a = (char*)pvalloc(0);  // pvalloc(0) should allocate at least one page.\n  EXPECT_EQ(0U, (uintptr_t)a % kPageSize);\n  a[101] = 1;  // we should not report an error here.\n  free(a);\n}\n#endif  // SANITIZER_TEST_HAS_PVALLOC\n\n#if !defined(_WIN32)\n// FIXME: Use an equivalent of pthread_setspecific on Windows.\nvoid *TSDWorker(void *test_key) {\n  if (test_key) {\n    pthread_setspecific(*(pthread_key_t*)test_key, (void*)0xfeedface);\n  }\n  return NULL;\n}\n\nvoid TSDDestructor(void *tsd) {\n  // Spawning a thread will check that the current thread id is not -1.\n  pthread_t th;\n  PTHREAD_CREATE(&th, NULL, TSDWorker, NULL);\n  PTHREAD_JOIN(th, NULL);\n}\n\n// This tests triggers the thread-specific data destruction fiasco which occurs\n// if we don't manage the TSD destructors ourselves. We create a new pthread\n// key with a non-NULL destructor which is likely to be put after the destructor\n// of AsanThread in the list of destructors.\n// In this case the TSD for AsanThread will be destroyed before TSDDestructor\n// is called for the child thread, and a CHECK will fail when we call\n// pthread_create() to spawn the grandchild.\nTEST(AddressSanitizer, DISABLED_TSDTest) {\n  pthread_t th;\n  pthread_key_t test_key;\n  pthread_key_create(&test_key, TSDDestructor);\n  PTHREAD_CREATE(&th, NULL, TSDWorker, &test_key);\n  PTHREAD_JOIN(th, NULL);\n  pthread_key_delete(test_key);\n}\n#endif\n\nTEST(AddressSanitizer, UAF_char) {\n  const char *uaf_string = \"AddressSanitizer:.*heap-use-after-free\";\n  EXPECT_DEATH(uaf_test<U1>(1, 0), uaf_string);\n  EXPECT_DEATH(uaf_test<U1>(10, 0), uaf_string);\n  EXPECT_DEATH(uaf_test<U1>(10, 10), uaf_string);\n  EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, 0), uaf_string);\n  EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, kLargeMalloc / 2), uaf_string);\n}\n\nTEST(AddressSanitizer, UAF_long_double) {\n  if (sizeof(long double) == sizeof(double)) return;\n  long double *p = Ident(new long double[10]);\n  EXPECT_DEATH(Ident(p)[12] = 0, \"WRITE of size 1[026]\");\n  EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], \"READ of size 1[026]\");\n  delete [] Ident(p);\n}\n\n#if !defined(_WIN32)\nstruct Packed5 {\n  int x;\n  char c;\n} __attribute__((packed));\n#else\n# pragma pack(push, 1)\nstruct Packed5 {\n  int x;\n  char c;\n};\n# pragma pack(pop)\n#endif\n\nTEST(AddressSanitizer, UAF_Packed5) {\n  static_assert(sizeof(Packed5) == 5, \"Please check the keywords used\");\n  Packed5 *p = Ident(new Packed5[2]);\n  EXPECT_DEATH(p[0] = p[3], \"READ of size 5\");\n  EXPECT_DEATH(p[3] = p[0], \"WRITE of size 5\");\n  delete [] Ident(p);\n}\n\n#if ASAN_HAS_BLACKLIST\nTEST(AddressSanitizer, IgnoreTest) {\n  int *x = Ident(new int);\n  delete Ident(x);\n  *x = 0;\n}\n#endif  // ASAN_HAS_BLACKLIST\n\nstruct StructWithBitField {\n  int bf1:1;\n  int bf2:1;\n  int bf3:1;\n  int bf4:29;\n};\n\nTEST(AddressSanitizer, BitFieldPositiveTest) {\n  StructWithBitField *x = new StructWithBitField;\n  delete Ident(x);\n  EXPECT_DEATH(x->bf1 = 0, \"use-after-free\");\n  EXPECT_DEATH(x->bf2 = 0, \"use-after-free\");\n  EXPECT_DEATH(x->bf3 = 0, \"use-after-free\");\n  EXPECT_DEATH(x->bf4 = 0, \"use-after-free\");\n}\n\nstruct StructWithBitFields_8_24 {\n  int a:8;\n  int b:24;\n};\n\nTEST(AddressSanitizer, BitFieldNegativeTest) {\n  StructWithBitFields_8_24 *x = Ident(new StructWithBitFields_8_24);\n  x->a = 0;\n  x->b = 0;\n  delete Ident(x);\n}\n\n#if ASAN_NEEDS_SEGV\nnamespace {\n\nconst char kUnknownCrash[] = \"AddressSanitizer: SEGV on unknown address\";\nconst char kOverriddenHandler[] = \"ASan signal handler has been overridden\\n\";\n\nTEST(AddressSanitizer, WildAddressTest) {\n  char *c = (char*)0x123;\n  EXPECT_DEATH(*c = 0, kUnknownCrash);\n}\n\nvoid my_sigaction_sighandler(int, siginfo_t*, void*) {\n  fprintf(stderr, kOverriddenHandler);\n  exit(1);\n}\n\nvoid my_signal_sighandler(int signum) {\n  fprintf(stderr, kOverriddenHandler);\n  exit(1);\n}\n\nTEST(AddressSanitizer, SignalTest) {\n  struct sigaction sigact;\n  memset(&sigact, 0, sizeof(sigact));\n  sigact.sa_sigaction = my_sigaction_sighandler;\n  sigact.sa_flags = SA_SIGINFO;\n  // ASan should silently ignore sigaction()...\n  EXPECT_EQ(0, sigaction(SIGSEGV, &sigact, 0));\n#ifdef __APPLE__\n  EXPECT_EQ(0, sigaction(SIGBUS, &sigact, 0));\n#endif\n  char *c = (char*)0x123;\n  EXPECT_DEATH(*c = 0, kUnknownCrash);\n  // ... and signal().\n  EXPECT_EQ(0, signal(SIGSEGV, my_signal_sighandler));\n  EXPECT_DEATH(*c = 0, kUnknownCrash);\n}\n}  // namespace\n#endif\n\nstatic void TestLargeMalloc(size_t size) {\n  char buff[1024];\n  sprintf(buff, \"is located 1 bytes to the left of %lu-byte\", (long)size);\n  EXPECT_DEATH(Ident((char*)malloc(size))[-1] = 0, buff);\n}\n\nTEST(AddressSanitizer, LargeMallocTest) {\n  const int max_size = (SANITIZER_WORDSIZE == 32) ? 1 << 26 : 1 << 28;\n  for (int i = 113; i < max_size; i = i * 2 + 13) {\n    TestLargeMalloc(i);\n  }\n}\n\nTEST(AddressSanitizer, HugeMallocTest) {\n  if (SANITIZER_WORDSIZE != 64 || ASAN_AVOID_EXPENSIVE_TESTS) return;\n  size_t n_megs = 4100;\n  EXPECT_DEATH(Ident((char*)malloc(n_megs << 20))[-1] = 0,\n               \"is located 1 bytes to the left|\"\n               \"AddressSanitizer failed to allocate\");\n}\n\n#if SANITIZER_TEST_HAS_MEMALIGN\nvoid MemalignRun(size_t align, size_t size, int idx) {\n  char *p = (char *)memalign(align, size);\n  Ident(p)[idx] = 0;\n  free(p);\n}\n\nTEST(AddressSanitizer, memalign) {\n  for (int align = 16; align <= (1 << 23); align *= 2) {\n    size_t size = align * 5;\n    EXPECT_DEATH(MemalignRun(align, size, -1),\n                 \"is located 1 bytes to the left\");\n    EXPECT_DEATH(MemalignRun(align, size, size + 1),\n                 \"is located 1 bytes to the right\");\n  }\n}\n#endif  // SANITIZER_TEST_HAS_MEMALIGN\n\nvoid *ManyThreadsWorker(void *a) {\n  for (int iter = 0; iter < 100; iter++) {\n    for (size_t size = 100; size < 2000; size *= 2) {\n      free(Ident(malloc(size)));\n    }\n  }\n  return 0;\n}\n\nTEST(AddressSanitizer, ManyThreadsTest) {\n  const size_t kNumThreads =\n      (SANITIZER_WORDSIZE == 32 || ASAN_AVOID_EXPENSIVE_TESTS) ? 30 : 1000;\n  pthread_t t[kNumThreads];\n  for (size_t i = 0; i < kNumThreads; i++) {\n    PTHREAD_CREATE(&t[i], 0, ManyThreadsWorker, (void*)i);\n  }\n  for (size_t i = 0; i < kNumThreads; i++) {\n    PTHREAD_JOIN(t[i], 0);\n  }\n}\n\nTEST(AddressSanitizer, ReallocTest) {\n  const int kMinElem = 5;\n  int *ptr = (int*)malloc(sizeof(int) * kMinElem);\n  ptr[3] = 3;\n  for (int i = 0; i < 10000; i++) {\n    ptr = (int*)realloc(ptr,\n        (my_rand() % 1000 + kMinElem) * sizeof(int));\n    EXPECT_EQ(3, ptr[3]);\n  }\n  free(ptr);\n  // Realloc pointer returned by malloc(0).\n  int *ptr2 = Ident((int*)malloc(0));\n  ptr2 = Ident((int*)realloc(ptr2, sizeof(*ptr2)));\n  *ptr2 = 42;\n  EXPECT_EQ(42, *ptr2);\n  free(ptr2);\n}\n\nTEST(AddressSanitizer, ReallocFreedPointerTest) {\n  void *ptr = Ident(malloc(42));\n  ASSERT_TRUE(NULL != ptr);\n  free(ptr);\n  EXPECT_DEATH(ptr = realloc(ptr, 77), \"attempting double-free\");\n}\n\nTEST(AddressSanitizer, ReallocInvalidPointerTest) {\n  void *ptr = Ident(malloc(42));\n  EXPECT_DEATH(ptr = realloc((int*)ptr + 1, 77), \"attempting free.*not malloc\");\n  free(ptr);\n}\n\nTEST(AddressSanitizer, ZeroSizeMallocTest) {\n  // Test that malloc(0) and similar functions don't return NULL.\n  void *ptr = Ident(malloc(0));\n  EXPECT_TRUE(NULL != ptr);\n  free(ptr);\n#if SANITIZER_TEST_HAS_POSIX_MEMALIGN\n  int pm_res = posix_memalign(&ptr, 1<<20, 0);\n  EXPECT_EQ(0, pm_res);\n  EXPECT_TRUE(NULL != ptr);\n  free(ptr);\n#endif  // SANITIZER_TEST_HAS_POSIX_MEMALIGN\n  int *int_ptr = new int[0];\n  int *int_ptr2 = new int[0];\n  EXPECT_TRUE(NULL != int_ptr);\n  EXPECT_TRUE(NULL != int_ptr2);\n  EXPECT_NE(int_ptr, int_ptr2);\n  delete[] int_ptr;\n  delete[] int_ptr2;\n}\n\n#if SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE\nstatic const char *kMallocUsableSizeErrorMsg =\n  \"AddressSanitizer: attempting to call malloc_usable_size()\";\n\nTEST(AddressSanitizer, MallocUsableSizeTest) {\n  const size_t kArraySize = 100;\n  char *array = Ident((char*)malloc(kArraySize));\n  int *int_ptr = Ident(new int);\n  EXPECT_EQ(0U, malloc_usable_size(NULL));\n  EXPECT_EQ(kArraySize, malloc_usable_size(array));\n  EXPECT_EQ(sizeof(int), malloc_usable_size(int_ptr));\n  EXPECT_DEATH(malloc_usable_size((void*)0x123), kMallocUsableSizeErrorMsg);\n  EXPECT_DEATH(malloc_usable_size(array + kArraySize / 2),\n               kMallocUsableSizeErrorMsg);\n  free(array);\n  EXPECT_DEATH(malloc_usable_size(array), kMallocUsableSizeErrorMsg);\n  delete int_ptr;\n}\n#endif  // SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE\n\nvoid WrongFree() {\n  int *x = (int*)malloc(100 * sizeof(int));\n  // Use the allocated memory, otherwise Clang will optimize it out.\n  Ident(x);\n  free(x + 1);\n}\n\n#if !defined(_WIN32)  // FIXME: This should be a lit test.\nTEST(AddressSanitizer, WrongFreeTest) {\n  EXPECT_DEATH(WrongFree(), ASAN_PCRE_DOTALL\n               \"ERROR: AddressSanitizer: attempting free.*not malloc\"\n               \".*is located 4 bytes inside of 400-byte region\"\n               \".*allocated by thread\");\n}\n#endif\n\nvoid DoubleFree() {\n  int *x = (int*)malloc(100 * sizeof(int));\n  fprintf(stderr, \"DoubleFree: x=%p\\n\", (void *)x);\n  free(x);\n  free(x);\n  fprintf(stderr, \"should have failed in the second free(%p)\\n\", (void *)x);\n  abort();\n}\n\n#if !defined(_WIN32)  // FIXME: This should be a lit test.\nTEST(AddressSanitizer, DoubleFreeTest) {\n  EXPECT_DEATH(DoubleFree(), ASAN_PCRE_DOTALL\n               \"ERROR: AddressSanitizer: attempting double-free\"\n               \".*is located 0 bytes inside of 400-byte region\"\n               \".*freed by thread T0 here\"\n               \".*previously allocated by thread T0 here\");\n}\n#endif\n\ntemplate<int kSize>\nNOINLINE void SizedStackTest() {\n  char a[kSize];\n  char  *A = Ident((char*)&a);\n  const char *expected_death = \"AddressSanitizer: stack-buffer-\";\n  for (size_t i = 0; i < kSize; i++)\n    A[i] = i;\n  EXPECT_DEATH(A[-1] = 0, expected_death);\n  EXPECT_DEATH(A[-5] = 0, expected_death);\n  EXPECT_DEATH(A[kSize] = 0, expected_death);\n  EXPECT_DEATH(A[kSize + 1] = 0, expected_death);\n  EXPECT_DEATH(A[kSize + 5] = 0, expected_death);\n  if (kSize > 16)\n    EXPECT_DEATH(A[kSize + 31] = 0, expected_death);\n}\n\nTEST(AddressSanitizer, SimpleStackTest) {\n  SizedStackTest<1>();\n  SizedStackTest<2>();\n  SizedStackTest<3>();\n  SizedStackTest<4>();\n  SizedStackTest<5>();\n  SizedStackTest<6>();\n  SizedStackTest<7>();\n  SizedStackTest<16>();\n  SizedStackTest<25>();\n  SizedStackTest<34>();\n  SizedStackTest<43>();\n  SizedStackTest<51>();\n  SizedStackTest<62>();\n  SizedStackTest<64>();\n  SizedStackTest<128>();\n}\n\n#if !defined(_WIN32)\n// FIXME: It's a bit hard to write multi-line death test expectations\n// in a portable way.  Anyways, this should just be turned into a lit test.\nTEST(AddressSanitizer, ManyStackObjectsTest) {\n  char XXX[10];\n  char YYY[20];\n  char ZZZ[30];\n  Ident(XXX);\n  Ident(YYY);\n  EXPECT_DEATH(Ident(ZZZ)[-1] = 0, ASAN_PCRE_DOTALL \"XXX.*YYY.*ZZZ\");\n}\n#endif\n\n#if 0  // This test requires online symbolizer.\n// Moved to lit_tests/stack-oob-frames.cc.\n// Reenable here once we have online symbolizer by default.\nNOINLINE static void Frame0(int frame, char *a, char *b, char *c) {\n  char d[4] = {0};\n  char *D = Ident(d);\n  switch (frame) {\n    case 3: a[5]++; break;\n    case 2: b[5]++; break;\n    case 1: c[5]++; break;\n    case 0: D[5]++; break;\n  }\n}\nNOINLINE static void Frame1(int frame, char *a, char *b) {\n  char c[4] = {0}; Frame0(frame, a, b, c);\n  break_optimization(0);\n}\nNOINLINE static void Frame2(int frame, char *a) {\n  char b[4] = {0}; Frame1(frame, a, b);\n  break_optimization(0);\n}\nNOINLINE static void Frame3(int frame) {\n  char a[4] = {0}; Frame2(frame, a);\n  break_optimization(0);\n}\n\nTEST(AddressSanitizer, GuiltyStackFrame0Test) {\n  EXPECT_DEATH(Frame3(0), \"located .*in frame <.*Frame0\");\n}\nTEST(AddressSanitizer, GuiltyStackFrame1Test) {\n  EXPECT_DEATH(Frame3(1), \"located .*in frame <.*Frame1\");\n}\nTEST(AddressSanitizer, GuiltyStackFrame2Test) {\n  EXPECT_DEATH(Frame3(2), \"located .*in frame <.*Frame2\");\n}\nTEST(AddressSanitizer, GuiltyStackFrame3Test) {\n  EXPECT_DEATH(Frame3(3), \"located .*in frame <.*Frame3\");\n}\n#endif\n\nNOINLINE void LongJmpFunc1(jmp_buf buf) {\n  // create three red zones for these two stack objects.\n  int a;\n  int b;\n\n  int *A = Ident(&a);\n  int *B = Ident(&b);\n  *A = *B;\n  longjmp(buf, 1);\n}\n\nNOINLINE void TouchStackFunc() {\n  int a[100];  // long array will intersect with redzones from LongJmpFunc1.\n  int *A = Ident(a);\n  for (int i = 0; i < 100; i++)\n    A[i] = i*i;\n}\n\n// Test that we handle longjmp and do not report false positives on stack.\nTEST(AddressSanitizer, LongJmpTest) {\n  static jmp_buf buf;\n  if (!setjmp(buf)) {\n    LongJmpFunc1(buf);\n  } else {\n    TouchStackFunc();\n  }\n}\n\n#if !defined(_WIN32)  // Only basic longjmp is available on Windows.\nNOINLINE void UnderscopeLongJmpFunc1(jmp_buf buf) {\n  // create three red zones for these two stack objects.\n  int a;\n  int b;\n\n  int *A = Ident(&a);\n  int *B = Ident(&b);\n  *A = *B;\n  _longjmp(buf, 1);\n}\n\nNOINLINE void SigLongJmpFunc1(sigjmp_buf buf) {\n  // create three red zones for these two stack objects.\n  int a;\n  int b;\n\n  int *A = Ident(&a);\n  int *B = Ident(&b);\n  *A = *B;\n  siglongjmp(buf, 1);\n}\n\n#if !defined(__ANDROID__) && !defined(__arm__) && \\\n    !defined(__powerpc64__) && !defined(__powerpc__) && \\\n    !defined(__aarch64__) && !defined(__mips__) && \\\n    !defined(__mips64)\nNOINLINE void BuiltinLongJmpFunc1(jmp_buf buf) {\n  // create three red zones for these two stack objects.\n  int a;\n  int b;\n\n  int *A = Ident(&a);\n  int *B = Ident(&b);\n  *A = *B;\n  __builtin_longjmp((void**)buf, 1);\n}\n\n// Does not work on Power and ARM:\n// https://code.google.com/p/address-sanitizer/issues/detail?id=185\nTEST(AddressSanitizer, BuiltinLongJmpTest) {\n  static jmp_buf buf;\n  if (!__builtin_setjmp((void**)buf)) {\n    BuiltinLongJmpFunc1(buf);\n  } else {\n    TouchStackFunc();\n  }\n}\n#endif  // !defined(__ANDROID__) && !defined(__powerpc64__) &&\n        // !defined(__powerpc__) && !defined(__arm__) &&\n        // !defined(__mips__) && !defined(__mips64)\n\nTEST(AddressSanitizer, UnderscopeLongJmpTest) {\n  static jmp_buf buf;\n  if (!_setjmp(buf)) {\n    UnderscopeLongJmpFunc1(buf);\n  } else {\n    TouchStackFunc();\n  }\n}\n\nTEST(AddressSanitizer, SigLongJmpTest) {\n  static sigjmp_buf buf;\n  if (!sigsetjmp(buf, 1)) {\n    SigLongJmpFunc1(buf);\n  } else {\n    TouchStackFunc();\n  }\n}\n#endif\n\n// FIXME: Why does clang-cl define __EXCEPTIONS?\n#if defined(__EXCEPTIONS) && !defined(_WIN32)\nNOINLINE void ThrowFunc() {\n  // create three red zones for these two stack objects.\n  int a;\n  int b;\n\n  int *A = Ident(&a);\n  int *B = Ident(&b);\n  *A = *B;\n  ASAN_THROW(1);\n}\n\nTEST(AddressSanitizer, CxxExceptionTest) {\n  if (ASAN_UAR) return;\n  // TODO(kcc): this test crashes on 32-bit for some reason...\n  if (SANITIZER_WORDSIZE == 32) return;\n  try {\n    ThrowFunc();\n  } catch(...) {}\n  TouchStackFunc();\n}\n#endif\n\nvoid *ThreadStackReuseFunc1(void *unused) {\n  // create three red zones for these two stack objects.\n  int a;\n  int b;\n\n  int *A = Ident(&a);\n  int *B = Ident(&b);\n  *A = *B;\n  pthread_exit(0);\n  return 0;\n}\n\nvoid *ThreadStackReuseFunc2(void *unused) {\n  TouchStackFunc();\n  return 0;\n}\n\nTEST(AddressSanitizer, ThreadStackReuseTest) {\n  pthread_t t;\n  PTHREAD_CREATE(&t, 0, ThreadStackReuseFunc1, 0);\n  PTHREAD_JOIN(t, 0);\n  PTHREAD_CREATE(&t, 0, ThreadStackReuseFunc2, 0);\n  PTHREAD_JOIN(t, 0);\n}\n\n#if defined(__i686__) || defined(__x86_64__)\n#include <emmintrin.h>\nTEST(AddressSanitizer, Store128Test) {\n  char *a = Ident((char*)malloc(Ident(12)));\n  char *p = a;\n  if (((uintptr_t)a % 16) != 0)\n    p = a + 8;\n  assert(((uintptr_t)p % 16) == 0);\n  __m128i value_wide = _mm_set1_epi16(0x1234);\n  EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),\n               \"AddressSanitizer: heap-buffer-overflow\");\n  EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),\n               \"WRITE of size 16\");\n  EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),\n               \"located 0 bytes to the right of 12-byte\");\n  free(a);\n}\n#endif\n\n// FIXME: All tests that use this function should be turned into lit tests.\nstring RightOOBErrorMessage(int oob_distance, bool is_write) {\n  assert(oob_distance >= 0);\n  char expected_str[100];\n  sprintf(expected_str, ASAN_PCRE_DOTALL\n#if !GTEST_USES_SIMPLE_RE\n          \"buffer-overflow.*%s.*\"\n#endif\n          \"located %d bytes to the right\",\n#if !GTEST_USES_SIMPLE_RE\n          is_write ? \"WRITE\" : \"READ\",\n#endif\n          oob_distance);\n  return string(expected_str);\n}\n\nstring RightOOBWriteMessage(int oob_distance) {\n  return RightOOBErrorMessage(oob_distance, /*is_write*/true);\n}\n\nstring RightOOBReadMessage(int oob_distance) {\n  return RightOOBErrorMessage(oob_distance, /*is_write*/false);\n}\n\n// FIXME: All tests that use this function should be turned into lit tests.\nstring LeftOOBErrorMessage(int oob_distance, bool is_write) {\n  assert(oob_distance > 0);\n  char expected_str[100];\n  sprintf(expected_str,\n#if !GTEST_USES_SIMPLE_RE\n          ASAN_PCRE_DOTALL \"%s.*\"\n#endif\n          \"located %d bytes to the left\",\n#if !GTEST_USES_SIMPLE_RE\n          is_write ? \"WRITE\" : \"READ\",\n#endif\n          oob_distance);\n  return string(expected_str);\n}\n\nstring LeftOOBWriteMessage(int oob_distance) {\n  return LeftOOBErrorMessage(oob_distance, /*is_write*/true);\n}\n\nstring LeftOOBReadMessage(int oob_distance) {\n  return LeftOOBErrorMessage(oob_distance, /*is_write*/false);\n}\n\nstring LeftOOBAccessMessage(int oob_distance) {\n  assert(oob_distance > 0);\n  char expected_str[100];\n  sprintf(expected_str, \"located %d bytes to the left\", oob_distance);\n  return string(expected_str);\n}\n\nchar* MallocAndMemsetString(size_t size, char ch) {\n  char *s = Ident((char*)malloc(size));\n  memset(s, ch, size);\n  return s;\n}\n\nchar* MallocAndMemsetString(size_t size) {\n  return MallocAndMemsetString(size, 'z');\n}\n\n#if defined(__linux__) && !defined(__ANDROID__)\n#define READ_TEST(READ_N_BYTES)                                          \\\n  char *x = new char[10];                                                \\\n  int fd = open(\"/proc/self/stat\", O_RDONLY);                            \\\n  ASSERT_GT(fd, 0);                                                      \\\n  EXPECT_DEATH(READ_N_BYTES,                                             \\\n               ASAN_PCRE_DOTALL                                          \\\n               \"AddressSanitizer: heap-buffer-overflow\"                  \\\n               \".* is located 0 bytes to the right of 10-byte region\");  \\\n  close(fd);                                                             \\\n  delete [] x;                                                           \\\n\nTEST(AddressSanitizer, pread) {\n  READ_TEST(pread(fd, x, 15, 0));\n}\n\nTEST(AddressSanitizer, pread64) {\n  READ_TEST(pread64(fd, x, 15, 0));\n}\n\nTEST(AddressSanitizer, read) {\n  READ_TEST(read(fd, x, 15));\n}\n#endif  // defined(__linux__) && !defined(__ANDROID__)\n\n// This test case fails\n// Clang optimizes memcpy/memset calls which lead to unaligned access\nTEST(AddressSanitizer, DISABLED_MemIntrinsicUnalignedAccessTest) {\n  int size = Ident(4096);\n  char *s = Ident((char*)malloc(size));\n  EXPECT_DEATH(memset(s + size - 1, 0, 2), RightOOBWriteMessage(0));\n  free(s);\n}\n\n// TODO(samsonov): Add a test with malloc(0)\n// TODO(samsonov): Add tests for str* and mem* functions.\n\nNOINLINE static int LargeFunction(bool do_bad_access) {\n  int *x = new int[100];\n  x[0]++;\n  x[1]++;\n  x[2]++;\n  x[3]++;\n  x[4]++;\n  x[5]++;\n  x[6]++;\n  x[7]++;\n  x[8]++;\n  x[9]++;\n\n  x[do_bad_access ? 100 : 0]++; int res = __LINE__;\n\n  x[10]++;\n  x[11]++;\n  x[12]++;\n  x[13]++;\n  x[14]++;\n  x[15]++;\n  x[16]++;\n  x[17]++;\n  x[18]++;\n  x[19]++;\n\n  delete[] x;\n  return res;\n}\n\n// Test the we have correct debug info for the failing instruction.\n// This test requires the in-process symbolizer to be enabled by default.\nTEST(AddressSanitizer, DISABLED_LargeFunctionSymbolizeTest) {\n  int failing_line = LargeFunction(false);\n  char expected_warning[128];\n  sprintf(expected_warning, \"LargeFunction.*asan_test.*:%d\", failing_line);\n  EXPECT_DEATH(LargeFunction(true), expected_warning);\n}\n\n// Check that we unwind and symbolize correctly.\nTEST(AddressSanitizer, DISABLED_MallocFreeUnwindAndSymbolizeTest) {\n  int *a = (int*)malloc_aaa(sizeof(int));\n  *a = 1;\n  free_aaa(a);\n  EXPECT_DEATH(*a = 1, \"free_ccc.*free_bbb.*free_aaa.*\"\n               \"malloc_fff.*malloc_eee.*malloc_ddd\");\n}\n\nstatic bool TryToSetThreadName(const char *name) {\n#if defined(__linux__) && defined(PR_SET_NAME)\n  return 0 == prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);\n#else\n  return false;\n#endif\n}\n\nvoid *ThreadedTestAlloc(void *a) {\n  EXPECT_EQ(true, TryToSetThreadName(\"AllocThr\"));\n  int **p = (int**)a;\n  *p = new int;\n  return 0;\n}\n\nvoid *ThreadedTestFree(void *a) {\n  EXPECT_EQ(true, TryToSetThreadName(\"FreeThr\"));\n  int **p = (int**)a;\n  delete *p;\n  return 0;\n}\n\nvoid *ThreadedTestUse(void *a) {\n  EXPECT_EQ(true, TryToSetThreadName(\"UseThr\"));\n  int **p = (int**)a;\n  **p = 1;\n  return 0;\n}\n\nvoid ThreadedTestSpawn() {\n  pthread_t t;\n  int *x;\n  PTHREAD_CREATE(&t, 0, ThreadedTestAlloc, &x);\n  PTHREAD_JOIN(t, 0);\n  PTHREAD_CREATE(&t, 0, ThreadedTestFree, &x);\n  PTHREAD_JOIN(t, 0);\n  PTHREAD_CREATE(&t, 0, ThreadedTestUse, &x);\n  PTHREAD_JOIN(t, 0);\n}\n\n#if !defined(_WIN32)  // FIXME: This should be a lit test.\nTEST(AddressSanitizer, ThreadedTest) {\n  EXPECT_DEATH(ThreadedTestSpawn(),\n               ASAN_PCRE_DOTALL\n               \"Thread T.*created\"\n               \".*Thread T.*created\"\n               \".*Thread T.*created\");\n}\n#endif\n\nvoid *ThreadedTestFunc(void *unused) {\n  // Check if prctl(PR_SET_NAME) is supported. Return if not.\n  if (!TryToSetThreadName(\"TestFunc\"))\n    return 0;\n  EXPECT_DEATH(ThreadedTestSpawn(),\n               ASAN_PCRE_DOTALL\n               \"WRITE .*thread T. .UseThr.\"\n               \".*freed by thread T. .FreeThr. here:\"\n               \".*previously allocated by thread T. .AllocThr. here:\"\n               \".*Thread T. .UseThr. created by T.*TestFunc\"\n               \".*Thread T. .FreeThr. created by T\"\n               \".*Thread T. .AllocThr. created by T\"\n               \"\");\n  return 0;\n}\n\nTEST(AddressSanitizer, ThreadNamesTest) {\n  // Run ThreadedTestFunc in a separate thread because it tries to set a\n  // thread name and we don't want to change the main thread's name.\n  pthread_t t;\n  PTHREAD_CREATE(&t, 0, ThreadedTestFunc, 0);\n  PTHREAD_JOIN(t, 0);\n}\n\n#if ASAN_NEEDS_SEGV\nTEST(AddressSanitizer, ShadowGapTest) {\n#if SANITIZER_WORDSIZE == 32\n  char *addr = (char*)0x22000000;\n#else\n# if defined(__powerpc64__)\n  char *addr = (char*)0x024000800000;\n# else\n  char *addr = (char*)0x0000100000080000;\n# endif\n#endif\n  EXPECT_DEATH(*addr = 1, \"AddressSanitizer: SEGV on unknown\");\n}\n#endif  // ASAN_NEEDS_SEGV\n\nextern \"C\" {\nNOINLINE static void UseThenFreeThenUse() {\n  char *x = Ident((char*)malloc(8));\n  *x = 1;\n  free_aaa(x);\n  *x = 2;\n}\n}\n\nTEST(AddressSanitizer, UseThenFreeThenUseTest) {\n  EXPECT_DEATH(UseThenFreeThenUse(), \"freed by thread\");\n}\n\nTEST(AddressSanitizer, StrDupTest) {\n  free(strdup(Ident(\"123\")));\n}\n\n// Currently we create and poison redzone at right of global variables.\nstatic char static110[110];\nconst char ConstGlob[7] = {1, 2, 3, 4, 5, 6, 7};\nstatic const char StaticConstGlob[3] = {9, 8, 7};\n\nTEST(AddressSanitizer, GlobalTest) {\n  static char func_static15[15];\n\n  static char fs1[10];\n  static char fs2[10];\n  static char fs3[10];\n\n  glob5[Ident(0)] = 0;\n  glob5[Ident(1)] = 0;\n  glob5[Ident(2)] = 0;\n  glob5[Ident(3)] = 0;\n  glob5[Ident(4)] = 0;\n\n  EXPECT_DEATH(glob5[Ident(5)] = 0,\n               \"0 bytes to the right of global variable.*glob5.* size 5\");\n  EXPECT_DEATH(glob5[Ident(5+6)] = 0,\n               \"6 bytes to the right of global variable.*glob5.* size 5\");\n  Ident(static110);  // avoid optimizations\n  static110[Ident(0)] = 0;\n  static110[Ident(109)] = 0;\n  EXPECT_DEATH(static110[Ident(110)] = 0,\n               \"0 bytes to the right of global variable\");\n  EXPECT_DEATH(static110[Ident(110+7)] = 0,\n               \"7 bytes to the right of global variable\");\n\n  Ident(func_static15);  // avoid optimizations\n  func_static15[Ident(0)] = 0;\n  EXPECT_DEATH(func_static15[Ident(15)] = 0,\n               \"0 bytes to the right of global variable\");\n  EXPECT_DEATH(func_static15[Ident(15 + 9)] = 0,\n               \"9 bytes to the right of global variable\");\n\n  Ident(fs1);\n  Ident(fs2);\n  Ident(fs3);\n\n  // We don't create left redzones, so this is not 100% guaranteed to fail.\n  // But most likely will.\n  EXPECT_DEATH(fs2[Ident(-1)] = 0, \"is located.*of global variable\");\n\n  EXPECT_DEATH(Ident(Ident(ConstGlob)[8]),\n               \"is located 1 bytes to the right of .*ConstGlob\");\n  EXPECT_DEATH(Ident(Ident(StaticConstGlob)[5]),\n               \"is located 2 bytes to the right of .*StaticConstGlob\");\n\n  // call stuff from another file.\n  GlobalsTest(0);\n}\n\nTEST(AddressSanitizer, GlobalStringConstTest) {\n  static const char *zoo = \"FOOBAR123\";\n  const char *p = Ident(zoo);\n  EXPECT_DEATH(Ident(p[15]), \"is ascii string 'FOOBAR123'\");\n}\n\nTEST(AddressSanitizer, FileNameInGlobalReportTest) {\n  static char zoo[10];\n  const char *p = Ident(zoo);\n  // The file name should be present in the report.\n  EXPECT_DEATH(Ident(p[15]), \"zoo.*asan_test.\");\n}\n\nint *ReturnsPointerToALocalObject() {\n  int a = 0;\n  return Ident(&a);\n}\n\n#if ASAN_UAR == 1\nTEST(AddressSanitizer, LocalReferenceReturnTest) {\n  int *(*f)() = Ident(ReturnsPointerToALocalObject);\n  int *p = f();\n  // Call 'f' a few more times, 'p' should still be poisoned.\n  for (int i = 0; i < 32; i++)\n    f();\n  EXPECT_DEATH(*p = 1, \"AddressSanitizer: stack-use-after-return\");\n  EXPECT_DEATH(*p = 1, \"is located.*in frame .*ReturnsPointerToALocal\");\n}\n#endif\n\ntemplate <int kSize>\nNOINLINE static void FuncWithStack() {\n  char x[kSize];\n  Ident(x)[0] = 0;\n  Ident(x)[kSize-1] = 0;\n}\n\nstatic void LotsOfStackReuse() {\n  int LargeStack[10000];\n  Ident(LargeStack)[0] = 0;\n  for (int i = 0; i < 10000; i++) {\n    FuncWithStack<128 * 1>();\n    FuncWithStack<128 * 2>();\n    FuncWithStack<128 * 4>();\n    FuncWithStack<128 * 8>();\n    FuncWithStack<128 * 16>();\n    FuncWithStack<128 * 32>();\n    FuncWithStack<128 * 64>();\n    FuncWithStack<128 * 128>();\n    FuncWithStack<128 * 256>();\n    FuncWithStack<128 * 512>();\n    Ident(LargeStack)[0] = 0;\n  }\n}\n\nTEST(AddressSanitizer, StressStackReuseTest) {\n  LotsOfStackReuse();\n}\n\nTEST(AddressSanitizer, ThreadedStressStackReuseTest) {\n  const int kNumThreads = 20;\n  pthread_t t[kNumThreads];\n  for (int i = 0; i < kNumThreads; i++) {\n    PTHREAD_CREATE(&t[i], 0, (void* (*)(void *x))LotsOfStackReuse, 0);\n  }\n  for (int i = 0; i < kNumThreads; i++) {\n    PTHREAD_JOIN(t[i], 0);\n  }\n}\n\nstatic void *PthreadExit(void *a) {\n  pthread_exit(0);\n  return 0;\n}\n\nTEST(AddressSanitizer, PthreadExitTest) {\n  pthread_t t;\n  for (int i = 0; i < 1000; i++) {\n    PTHREAD_CREATE(&t, 0, PthreadExit, 0);\n    PTHREAD_JOIN(t, 0);\n  }\n}\n\n// FIXME: Why does clang-cl define __EXCEPTIONS?\n#if defined(__EXCEPTIONS) && !defined(_WIN32)\nNOINLINE static void StackReuseAndException() {\n  int large_stack[1000];\n  Ident(large_stack);\n  ASAN_THROW(1);\n}\n\n// TODO(kcc): support exceptions with use-after-return.\nTEST(AddressSanitizer, DISABLED_StressStackReuseAndExceptionsTest) {\n  for (int i = 0; i < 10000; i++) {\n    try {\n    StackReuseAndException();\n    } catch(...) {\n    }\n  }\n}\n#endif\n\n#if !defined(_WIN32)\nTEST(AddressSanitizer, MlockTest) {\n  EXPECT_EQ(0, mlockall(MCL_CURRENT));\n  EXPECT_EQ(0, mlock((void*)0x12345, 0x5678));\n  EXPECT_EQ(0, munlockall());\n  EXPECT_EQ(0, munlock((void*)0x987, 0x654));\n}\n#endif\n\nstruct LargeStruct {\n  int foo[100];\n};\n\n// Test for bug http://llvm.org/bugs/show_bug.cgi?id=11763.\n// Struct copy should not cause asan warning even if lhs == rhs.\nTEST(AddressSanitizer, LargeStructCopyTest) {\n  LargeStruct a;\n  *Ident(&a) = *Ident(&a);\n}\n\nATTRIBUTE_NO_SANITIZE_ADDRESS\nstatic void NoSanitizeAddress() {\n  char *foo = new char[10];\n  Ident(foo)[10] = 0;\n  delete [] foo;\n}\n\nTEST(AddressSanitizer, AttributeNoSanitizeAddressTest) {\n  Ident(NoSanitizeAddress)();\n}\n\n// The new/delete/etc mismatch checks don't work on Android,\n//   as calls to new/delete go through malloc/free.\n// OS X support is tracked here:\n//   https://code.google.com/p/address-sanitizer/issues/detail?id=131\n// Windows support is tracked here:\n//   https://code.google.com/p/address-sanitizer/issues/detail?id=309\n#if !defined(__ANDROID__) && \\\n    !defined(__APPLE__) && \\\n    !defined(_WIN32)\nstatic string MismatchStr(const string &str) {\n  return string(\"AddressSanitizer: alloc-dealloc-mismatch \\\\(\") + str;\n}\n\nTEST(AddressSanitizer, AllocDeallocMismatch) {\n  EXPECT_DEATH(free(Ident(new int)),\n               MismatchStr(\"operator new vs free\"));\n  EXPECT_DEATH(free(Ident(new int[2])),\n               MismatchStr(\"operator new \\\\[\\\\] vs free\"));\n  EXPECT_DEATH(delete (Ident(new int[2])),\n               MismatchStr(\"operator new \\\\[\\\\] vs operator delete\"));\n  EXPECT_DEATH(delete (Ident((int*)malloc(2 * sizeof(int)))),\n               MismatchStr(\"malloc vs operator delete\"));\n  EXPECT_DEATH(delete [] (Ident(new int)),\n               MismatchStr(\"operator new vs operator delete \\\\[\\\\]\"));\n  EXPECT_DEATH(delete [] (Ident((int*)malloc(2 * sizeof(int)))),\n               MismatchStr(\"malloc vs operator delete \\\\[\\\\]\"));\n}\n#endif\n\n// ------------------ demo tests; run each one-by-one -------------\n// e.g. --gtest_filter=*DemoOOBLeftHigh --gtest_also_run_disabled_tests\nTEST(AddressSanitizer, DISABLED_DemoThreadedTest) {\n  ThreadedTestSpawn();\n}\n\nvoid *SimpleBugOnSTack(void *x = 0) {\n  char a[20];\n  Ident(a)[20] = 0;\n  return 0;\n}\n\nTEST(AddressSanitizer, DISABLED_DemoStackTest) {\n  SimpleBugOnSTack();\n}\n\nTEST(AddressSanitizer, DISABLED_DemoThreadStackTest) {\n  pthread_t t;\n  PTHREAD_CREATE(&t, 0, SimpleBugOnSTack, 0);\n  PTHREAD_JOIN(t, 0);\n}\n\nTEST(AddressSanitizer, DISABLED_DemoUAFLowIn) {\n  uaf_test<U1>(10, 0);\n}\nTEST(AddressSanitizer, DISABLED_DemoUAFLowLeft) {\n  uaf_test<U1>(10, -2);\n}\nTEST(AddressSanitizer, DISABLED_DemoUAFLowRight) {\n  uaf_test<U1>(10, 10);\n}\n\nTEST(AddressSanitizer, DISABLED_DemoUAFHigh) {\n  uaf_test<U1>(kLargeMalloc, 0);\n}\n\nTEST(AddressSanitizer, DISABLED_DemoOOM) {\n  size_t size = SANITIZER_WORDSIZE == 64 ? (size_t)(1ULL << 40) : (0xf0000000);\n  printf(\"%p\\n\", malloc(size));\n}\n\nTEST(AddressSanitizer, DISABLED_DemoDoubleFreeTest) {\n  DoubleFree();\n}\n\nTEST(AddressSanitizer, DISABLED_DemoNullDerefTest) {\n  int *a = 0;\n  Ident(a)[10] = 0;\n}\n\nTEST(AddressSanitizer, DISABLED_DemoFunctionStaticTest) {\n  static char a[100];\n  static char b[100];\n  static char c[100];\n  Ident(a);\n  Ident(b);\n  Ident(c);\n  Ident(a)[5] = 0;\n  Ident(b)[105] = 0;\n  Ident(a)[5] = 0;\n}\n\nTEST(AddressSanitizer, DISABLED_DemoTooMuchMemoryTest) {\n  const size_t kAllocSize = (1 << 28) - 1024;\n  size_t total_size = 0;\n  while (true) {\n    void *x = malloc(kAllocSize);\n    memset(x, 0, kAllocSize);\n    total_size += kAllocSize;\n    fprintf(stderr, \"total: %ldM %p\\n\", (long)total_size >> 20, x);\n  }\n}\n\n// http://code.google.com/p/address-sanitizer/issues/detail?id=66\nTEST(AddressSanitizer, BufferOverflowAfterManyFrees) {\n  for (int i = 0; i < 1000000; i++) {\n    delete [] (Ident(new char [8644]));\n  }\n  char *x = new char[8192];\n  EXPECT_DEATH(x[Ident(8192)] = 0, \"AddressSanitizer: heap-buffer-overflow\");\n  delete [] Ident(x);\n}\n\n\n// Test that instrumentation of stack allocations takes into account\n// AllocSize of a type, and not its StoreSize (16 vs 10 bytes for long double).\n// See http://llvm.org/bugs/show_bug.cgi?id=12047 for more details.\nTEST(AddressSanitizer, LongDoubleNegativeTest) {\n  long double a, b;\n  static long double c;\n  memcpy(Ident(&a), Ident(&b), sizeof(long double));\n  memcpy(Ident(&c), Ident(&b), sizeof(long double));\n}\n\n#if !defined(_WIN32)\nTEST(AddressSanitizer, pthread_getschedparam) {\n  int policy;\n  struct sched_param param;\n  EXPECT_DEATH(\n      pthread_getschedparam(pthread_self(), &policy, Ident(&param) + 2),\n      \"AddressSanitizer: stack-buffer-.*flow\");\n  EXPECT_DEATH(\n      pthread_getschedparam(pthread_self(), Ident(&policy) - 1, &param),\n      \"AddressSanitizer: stack-buffer-.*flow\");\n  int res = pthread_getschedparam(pthread_self(), &policy, &param);\n  ASSERT_EQ(0, res);\n}\n#endif\n\n#if SANITIZER_TEST_HAS_PRINTF_L\nstatic int vsnprintf_l_wrapper(char *s, size_t n,\n                               locale_t l, const char *format, ...) {\n  va_list va;\n  va_start(va, format);\n  int res = vsnprintf_l(s, n , l, format, va);\n  va_end(va);\n  return res;\n}\n\nTEST(AddressSanitizer, snprintf_l) {\n  char buff[5];\n  // Check that snprintf_l() works fine with Asan.\n  int res = snprintf_l(buff, 5,\n                       _LIBCPP_GET_C_LOCALE, \"%s\", \"snprintf_l()\");\n  EXPECT_EQ(12, res);\n  // Check that vsnprintf_l() works fine with Asan.\n  res = vsnprintf_l_wrapper(buff, 5,\n                            _LIBCPP_GET_C_LOCALE, \"%s\", \"vsnprintf_l()\");\n  EXPECT_EQ(13, res);\n\n  EXPECT_DEATH(snprintf_l(buff, 10,\n                          _LIBCPP_GET_C_LOCALE, \"%s\", \"snprintf_l()\"),\n                \"AddressSanitizer: stack-buffer-overflow\");\n  EXPECT_DEATH(vsnprintf_l_wrapper(buff, 10,\n                                  _LIBCPP_GET_C_LOCALE, \"%s\", \"vsnprintf_l()\"),\n                \"AddressSanitizer: stack-buffer-overflow\");\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_test.ignore",
    "content": "# blacklisted functions for instrumented ASan unit test\nfun:*IgnoreTest*\nfun:*SomeOtherFunc*\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_test_config.h",
    "content": "//===-- asan_test_config.h --------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n//===----------------------------------------------------------------------===//\n#if !defined(INCLUDED_FROM_ASAN_TEST_UTILS_H)\n# error \"This file should be included into asan_test_utils.h only\"\n#endif\n\n#ifndef ASAN_TEST_CONFIG_H\n#define ASAN_TEST_CONFIG_H\n\n#include <vector>\n#include <string>\n#include <map>\n\nusing std::string;\nusing std::vector;\nusing std::map;\n\n#ifndef ASAN_UAR\n# error \"please define ASAN_UAR\"\n#endif\n\n#ifndef ASAN_HAS_EXCEPTIONS\n# error \"please define ASAN_HAS_EXCEPTIONS\"\n#endif\n\n#ifndef ASAN_HAS_BLACKLIST\n# error \"please define ASAN_HAS_BLACKLIST\"\n#endif\n\n#ifndef ASAN_NEEDS_SEGV\n# if defined(_WIN32)\n#  define ASAN_NEEDS_SEGV 0\n# else\n#  define ASAN_NEEDS_SEGV 1\n# endif\n#endif\n\n#ifndef ASAN_AVOID_EXPENSIVE_TESTS\n# define ASAN_AVOID_EXPENSIVE_TESTS 0\n#endif\n\n#define ASAN_PCRE_DOTALL \"\"\n\n#endif  // ASAN_TEST_CONFIG_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_test_main.cc",
    "content": "//===-- asan_test_main.cc -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n//===----------------------------------------------------------------------===//\n#include \"asan_test_utils.h\"\n\nint main(int argc, char **argv) {\n  testing::GTEST_FLAG(death_test_style) = \"threadsafe\";\n  testing::InitGoogleTest(&argc, argv);\n  return RUN_ALL_TESTS();\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/asan/tests/asan_test_utils.h",
    "content": "//===-- asan_test_utils.h ---------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef ASAN_TEST_UTILS_H\n#define ASAN_TEST_UTILS_H\n\n#if !defined(SANITIZER_EXTERNAL_TEST_CONFIG)\n# define INCLUDED_FROM_ASAN_TEST_UTILS_H\n# include \"asan_test_config.h\"\n# undef INCLUDED_FROM_ASAN_TEST_UTILS_H\n#endif\n\n#include \"sanitizer_test_utils.h\"\n#include \"sanitizer_pthread_wrappers.h\"\n\n#include <stdio.h>\n#include <signal.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n#include <assert.h>\n#include <algorithm>\n\n#if !defined(_WIN32)\n# include <strings.h>\n# include <sys/mman.h>\n# include <setjmp.h>\n#endif\n\n#ifdef __linux__\n# include <sys/prctl.h>\n# include <sys/types.h>\n# include <sys/stat.h>\n# include <fcntl.h>\n#include <unistd.h>\n#endif\n\n#if !defined(__APPLE__) && !defined(__FreeBSD__)\n#include <malloc.h>\n#endif\n\n#if ASAN_HAS_EXCEPTIONS\n# define ASAN_THROW(x) throw (x)\n#else\n# define ASAN_THROW(x)\n#endif\n\ntypedef uint8_t   U1;\ntypedef uint16_t  U2;\ntypedef uint32_t  U4;\ntypedef uint64_t  U8;\n\nstatic const int kPageSize = 4096;\n\nconst size_t kLargeMalloc = 1 << 24;\n\nextern void free_aaa(void *p);\nextern void *malloc_aaa(size_t size);\n\ntemplate<typename T>\nNOINLINE void asan_write(T *a) {\n  *a = 0;\n}\n\nstring RightOOBErrorMessage(int oob_distance, bool is_write);\nstring RightOOBWriteMessage(int oob_distance);\nstring RightOOBReadMessage(int oob_distance);\nstring LeftOOBErrorMessage(int oob_distance, bool is_write);\nstring LeftOOBWriteMessage(int oob_distance);\nstring LeftOOBReadMessage(int oob_distance);\nstring LeftOOBAccessMessage(int oob_distance);\nchar* MallocAndMemsetString(size_t size, char ch);\nchar* MallocAndMemsetString(size_t size);\n\nextern char glob1[1];\nextern char glob2[2];\nextern char glob3[3];\nextern char glob4[4];\nextern char glob5[5];\nextern char glob6[6];\nextern char glob7[7];\nextern char glob8[8];\nextern char glob9[9];\nextern char glob10[10];\nextern char glob11[11];\nextern char glob12[12];\nextern char glob13[13];\nextern char glob14[14];\nextern char glob15[15];\nextern char glob16[16];\nextern char glob17[17];\nextern char glob1000[1000];\nextern char glob10000[10000];\nextern char glob100000[100000];\nextern int GlobalsTest(int x);\n\n#endif  // ASAN_TEST_UTILS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/CMakeLists.txt",
    "content": "# This directory contains a large amount of C code which provides\n# generic implementations of the core runtime library along with optimized\n# architecture-specific code in various subdirectories.\n\n# TODO: Need to add a mechanism for logging errors when builtin source files are\n# added to a sub-directory and not this CMakeLists file.\n\nset(GENERIC_SOURCES\n  absvdi2.c\n  absvsi2.c\n  absvti2.c\n  adddf3.c\n  addsf3.c\n  addtf3.c\n  addvdi3.c\n  addvsi3.c\n  addvti3.c\n  apple_versioning.c\n  ashldi3.c\n  ashlti3.c\n  ashrdi3.c\n  ashrti3.c\n  # FIXME: atomic.c may only be compiled if host compiler understands _Atomic\n  # atomic.c\n  clear_cache.c\n  clzdi2.c\n  clzsi2.c\n  clzti2.c\n  cmpdi2.c\n  cmpti2.c\n  comparedf2.c\n  comparesf2.c\n  ctzdi2.c\n  ctzsi2.c\n  ctzti2.c\n  divdc3.c\n  divdf3.c\n  divdi3.c\n  divmoddi4.c\n  divmodsi4.c\n  divsc3.c\n  divsf3.c\n  divsi3.c\n  divtc3.c\n  divti3.c\n  divtf3.c\n  divxc3.c\n  enable_execute_stack.c\n  eprintf.c\n  extendsfdf2.c\n  extendhfsf2.c\n  ffsdi2.c\n  ffsti2.c\n  fixdfdi.c\n  fixdfsi.c\n  fixdfti.c\n  fixsfdi.c\n  fixsfsi.c\n  fixsfti.c\n  fixunsdfdi.c\n  fixunsdfsi.c\n  fixunsdfti.c\n  fixunssfdi.c\n  fixunssfsi.c\n  fixunssfti.c\n  fixunsxfdi.c\n  fixunsxfsi.c\n  fixunsxfti.c\n  fixxfdi.c\n  fixxfti.c\n  floatdidf.c\n  floatdisf.c\n  floatdixf.c\n  floatsidf.c\n  floatsisf.c\n  floattidf.c\n  floattisf.c\n  floattixf.c\n  floatundidf.c\n  floatundisf.c\n  floatundixf.c\n  floatunsidf.c\n  floatunsisf.c\n  floatuntidf.c\n  floatuntisf.c\n  floatuntixf.c\n  int_util.c\n  lshrdi3.c\n  lshrti3.c\n  moddi3.c\n  modsi3.c\n  modti3.c\n  muldc3.c\n  muldf3.c\n  muldi3.c\n  mulodi4.c\n  mulosi4.c\n  muloti4.c\n  mulsc3.c\n  mulsf3.c\n  multi3.c\n  multf3.c\n  mulvdi3.c\n  mulvsi3.c\n  mulvti3.c\n  mulxc3.c\n  negdf2.c\n  negdi2.c\n  negsf2.c\n  negti2.c\n  negvdi2.c\n  negvsi2.c\n  negvti2.c\n  paritydi2.c\n  paritysi2.c\n  parityti2.c\n  popcountdi2.c\n  popcountsi2.c\n  popcountti2.c\n  powidf2.c\n  powisf2.c\n  powitf2.c\n  powixf2.c\n  subdf3.c\n  subsf3.c\n  subvdi3.c\n  subvsi3.c\n  subvti3.c\n  subtf3.c\n  trampoline_setup.c\n  truncdfhf2.c\n  truncdfsf2.c\n  truncsfhf2.c\n  ucmpdi2.c\n  ucmpti2.c\n  udivdi3.c\n  udivmoddi4.c\n  udivmodsi4.c\n  udivmodti4.c\n  udivsi3.c\n  udivti3.c\n  umoddi3.c\n  umodsi3.c\n  umodti3.c)\n\nif(APPLE)\n  set(GENERIC_SOURCES\n    ${GENERIC_SOURCES}\n    atomic_flag_clear.c\n    atomic_flag_clear_explicit.c\n    atomic_flag_test_and_set.c\n    atomic_flag_test_and_set_explicit.c\n    atomic_signal_fence.c\n    atomic_thread_fence.c)\nendif()\n\nif(NOT WIN32 OR MINGW)\n  set(GENERIC_SOURCES\n      ${GENERIC_SOURCES}\n      emutls.c)\nendif()\n\nif (HAVE_UNWIND_H)\n  set(GENERIC_SOURCES\n      ${GENERIC_SOURCES}\n      gcc_personality_v0.c)\nendif ()\n\nif (NOT MSVC)\n  set(x86_64_SOURCES\n      x86_64/chkstk.S\n      x86_64/chkstk2.S\n      x86_64/floatdidf.c\n      x86_64/floatdisf.c\n      x86_64/floatdixf.c\n      x86_64/floatundidf.S\n      x86_64/floatundisf.S\n      x86_64/floatundixf.S\n      ${GENERIC_SOURCES})\n  set(x86_64h_SOURCES ${x86_64_SOURCES})\n\n  if (WIN32)\n    set(x86_64_SOURCES\n        ${x86_64_SOURCES}\n        x86_64/chkstk.S\n        x86_64/chkstk2.S)\n  endif()\n\n  set(i386_SOURCES\n      i386/ashldi3.S\n      i386/ashrdi3.S\n      i386/chkstk.S\n      i386/chkstk2.S\n      i386/divdi3.S\n      i386/floatdidf.S\n      i386/floatdisf.S\n      i386/floatdixf.S\n      i386/floatundidf.S\n      i386/floatundisf.S\n      i386/floatundixf.S\n      i386/lshrdi3.S\n      i386/moddi3.S\n      i386/muldi3.S\n      i386/udivdi3.S\n      i386/umoddi3.S\n      ${GENERIC_SOURCES})\n\n  if (WIN32)\n    set(i386_SOURCES\n        ${i386_SOURCES}\n        i386/chkstk.S\n        i386/chkstk2.S)\n  endif()\n\n  set(i686_SOURCES\n      ${i386_SOURCES})\nelse () # MSVC\n  # Use C versions of functions when building on MSVC\n  # MSVC's assembler takes Intel syntax, not AT&T syntax\n  set(x86_64_SOURCES\n      x86_64/floatdidf.c\n      x86_64/floatdisf.c\n      x86_64/floatdixf.c\n      ${GENERIC_SOURCES})\n  set(x86_64h_SOURCES ${x86_64_SOURCES})\n  set(i386_SOURCES ${GENERIC_SOURCES})\n  set(i686_SOURCES ${i386_SOURCES})\nendif () # if (NOT MSVC)\n\nset(arm_SOURCES\n  arm/adddf3vfp.S\n  arm/addsf3vfp.S\n  arm/aeabi_cdcmp.S\n  arm/aeabi_cdcmpeq_check_nan.c\n  arm/aeabi_cfcmp.S\n  arm/aeabi_cfcmpeq_check_nan.c\n  arm/aeabi_dcmp.S\n  arm/aeabi_div0.c\n  arm/aeabi_drsub.c\n  arm/aeabi_fcmp.S\n  arm/aeabi_frsub.c\n  arm/aeabi_idivmod.S\n  arm/aeabi_ldivmod.S\n  arm/aeabi_memcmp.S\n  arm/aeabi_memcpy.S\n  arm/aeabi_memmove.S\n  arm/aeabi_memset.S\n  arm/aeabi_uidivmod.S\n  arm/aeabi_uldivmod.S\n  arm/bswapdi2.S\n  arm/bswapsi2.S\n  arm/clzdi2.S\n  arm/clzsi2.S\n  arm/comparesf2.S\n  arm/divdf3vfp.S\n  arm/divmodsi4.S\n  arm/divsf3vfp.S\n  arm/divsi3.S\n  arm/eqdf2vfp.S\n  arm/eqsf2vfp.S\n  arm/extendsfdf2vfp.S\n  arm/fixdfsivfp.S\n  arm/fixsfsivfp.S\n  arm/fixunsdfsivfp.S\n  arm/fixunssfsivfp.S\n  arm/floatsidfvfp.S\n  arm/floatsisfvfp.S\n  arm/floatunssidfvfp.S\n  arm/floatunssisfvfp.S\n  arm/gedf2vfp.S\n  arm/gesf2vfp.S\n  arm/gtdf2vfp.S\n  arm/gtsf2vfp.S\n  arm/ledf2vfp.S\n  arm/lesf2vfp.S\n  arm/ltdf2vfp.S\n  arm/ltsf2vfp.S\n  arm/modsi3.S\n  arm/muldf3vfp.S\n  arm/mulsf3vfp.S\n  arm/nedf2vfp.S\n  arm/negdf2vfp.S\n  arm/negsf2vfp.S\n  arm/nesf2vfp.S\n  arm/restore_vfp_d8_d15_regs.S\n  arm/save_vfp_d8_d15_regs.S\n  arm/subdf3vfp.S\n  arm/subsf3vfp.S\n  arm/switch16.S\n  arm/switch32.S\n  arm/switch8.S\n  arm/switchu8.S\n  arm/sync_fetch_and_add_4.S\n  arm/sync_fetch_and_add_8.S\n  arm/sync_fetch_and_and_4.S\n  arm/sync_fetch_and_and_8.S\n  arm/sync_fetch_and_max_4.S\n  arm/sync_fetch_and_max_8.S\n  arm/sync_fetch_and_min_4.S\n  arm/sync_fetch_and_min_8.S\n  arm/sync_fetch_and_nand_4.S\n  arm/sync_fetch_and_nand_8.S\n  arm/sync_fetch_and_or_4.S\n  arm/sync_fetch_and_or_8.S\n  arm/sync_fetch_and_sub_4.S\n  arm/sync_fetch_and_sub_8.S\n  arm/sync_fetch_and_umax_4.S\n  arm/sync_fetch_and_umax_8.S\n  arm/sync_fetch_and_umin_4.S\n  arm/sync_fetch_and_umin_8.S\n  arm/sync_fetch_and_xor_4.S\n  arm/sync_fetch_and_xor_8.S\n  arm/sync_synchronize.S\n  arm/truncdfsf2vfp.S\n  arm/udivmodsi4.S\n  arm/udivsi3.S\n  arm/umodsi3.S\n  arm/unorddf2vfp.S\n  arm/unordsf2vfp.S\n  ${GENERIC_SOURCES})\n\nset(aarch64_SOURCES\n  comparetf2.c\n  extenddftf2.c\n  extendsftf2.c\n  fixtfdi.c\n  fixtfsi.c\n  fixtfti.c\n  fixunstfdi.c\n  fixunstfsi.c\n  fixunstfti.c\n  floatditf.c\n  floatsitf.c\n  floatunditf.c\n  floatunsitf.c\n  multc3.c\n  trunctfdf2.c\n  trunctfsf2.c\n  ${GENERIC_SOURCES})\n\nset(armhf_SOURCES ${arm_SOURCES})\nset(armv7_SOURCES ${arm_SOURCES})\nset(armv7s_SOURCES ${arm_SOURCES})\nset(arm64_SOURCES ${aarch64_SOURCES})\n\n# macho_embedded archs\nset(armv6m_SOURCES ${GENERIC_SOURCES})\nset(armv7m_SOURCES ${arm_SOURCES})\nset(armv7em_SOURCES ${arm_SOURCES})\n\nset(mips_SOURCES ${GENERIC_SOURCES})\nset(mipsel_SOURCES ${mips_SOURCES})\nset(mips64_SOURCES ${mips_SOURCES})\nset(mips64el_SOURCES ${mips_SOURCES})\n\nadd_custom_target(builtins)\n\nif (APPLE)\n  add_subdirectory(Darwin-excludes)\n  add_subdirectory(macho_embedded)\n  darwin_add_builtin_libraries(${BUILTIN_SUPPORTED_OS})\nelseif (NOT WIN32 OR MINGW)\n  append_string_if(COMPILER_RT_HAS_STD_C99_FLAG -std=c99 maybe_stdc99)\n\n  foreach (arch ${BUILTIN_SUPPORTED_ARCH})\n    if (CAN_TARGET_${arch})\n      # Filter out generic versions of routines that are re-implemented in\n      # architecture specific manner.  This prevents multiple definitions of the\n      # same symbols, making the symbol selection non-deterministic.\n      foreach (_file ${${arch}_SOURCES})\n        if (${_file} MATCHES ${arch}/*)\n          get_filename_component(_name ${_file} NAME)\n          string(REPLACE \".S\" \".c\" _cname \"${_name}\")\n          list(REMOVE_ITEM ${arch}_SOURCES ${_cname})\n        endif ()\n      endforeach ()\n\n      add_compiler_rt_runtime(clang_rt.builtins\n                              STATIC\n                              ARCHS ${arch}\n                              SOURCES ${${arch}_SOURCES}\n                              CFLAGS ${maybe_stdc99}\n                              PARENT_TARGET builtins)\n    endif ()\n  endforeach ()\nendif ()\n\nadd_dependencies(compiler-rt builtins)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/10.4-x86_64.txt",
    "content": "absvti2\naddvti3\nashlti3\nashrti3\nclzti2\ncmpti2\nctzti2\ndivti3\nffsti2\nfixdfti\nfixsfti\nfixunsdfti\nfixunssfti\nfixunsxfti\nfixxfti\nfloattidf\nfloattisf\nfloattixf\nfloatuntidf\nfloatuntisf\nfloatuntixf\nlshrti3\nmodti3\nmuloti4\nmulti3\nmulvti3\nnegti2\nnegvti2\nparityti2\npopcountti2\nsubvti3\nucmpti2\nudivmodti4\nudivti3\numodti3\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/10.4.txt",
    "content": "apple_versioning\nabsvdi2\nabsvsi2\nadddf3\naddsf3\naddvdi3\naddvsi3\nashldi3\nashrdi3\nclear_cache\nclzdi2\nclzsi2\ncmpdi2\nctzdi2\nctzsi2\ndivdc3\ndivdf3\ndivdi3\ndivmoddi4\ndivmodsi4\ndivsc3\ndivsf3\ndivsi3\ndivxc3\nenable_execute_stack\ncomparedf2\ncomparesf2\nextendhfsf2\nextendsfdf2\nffsdi2\nfixdfdi\nfixdfsi\nfixsfdi\nfixsfsi\nfixunsdfdi\nfixunsdfsi\nfixunssfdi\nfixunssfsi\nfixunsxfdi\nfixunsxfsi\nfixxfdi\nfloatdidf\nfloatdisf\nfloatdixf\nfloatsidf\nfloatsisf\nfloatunsidf\nfloatunsisf\ngcc_personality_v0\ngnu_f2h_ieee\ngnu_h2f_ieee\nlshrdi3\nmoddi3\nmodsi3\nmuldc3\nmuldf3\nmuldi3\nmulodi4\nmulosi4\nmulsc3\nmulsf3\nmulvdi3\nmulvsi3\nmulxc3\nnegdf2\nnegdi2\nnegsf2\nnegvdi2\nnegvsi2\nparitydi2\nparitysi2\npopcountdi2\npopcountsi2\npowidf2\npowisf2\npowixf2\nsubdf3\nsubsf3\nsubvdi3\nsubvsi3\ntruncdfhf2\ntruncdfsf2\ntruncsfhf2\nucmpdi2\nudivdi3\nudivmoddi4\nudivmodsi4\nudivsi3\numoddi3\numodsi3\natomic_flag_clear\natomic_flag_clear_explicit\natomic_flag_test_and_set\natomic_flag_test_and_set_explicit\natomic_signal_fence\natomic_thread_fence"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/CMakeLists.txt",
    "content": "file(GLOB filter_files ${CMAKE_CURRENT_SOURCE_DIR}/*.txt)\nforeach(filter_file ${filter_files})\n  set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${filter_file})\nendforeach()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/README.TXT",
    "content": "This folder contains list of symbols that should be excluded from the builtin\nlibraries for Darwin. There are two reasons symbols are excluded:\n\n(1) They aren't supported on Darwin\n(2) They are contained within the OS on the minimum supported target\n\nThe builtin libraries must contain all symbols not provided by the lowest\nsupported target OS. Meaning if minimum deployment target is iOS 6, all builtins\nnot included in the ios6-<arch>.txt files need to be included. The one catch is\nthat this is per-architecture. Since iOS 6 doesn't support arm64, when supporting\niOS 6, the minimum deployment target for arm64 binaries is iOS 7.\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/ios-armv7.txt",
    "content": "absvti2\naddtf3\naddvti3\naeabi_cdcmp\naeabi_cdcmpeq_check_nan\naeabi_cfcmp\naeabi_cfcmpeq_check_nan\naeabi_dcmp\naeabi_div0\naeabi_drsub\naeabi_fcmp\naeabi_frsub\naeabi_idivmod\naeabi_ldivmod\naeabi_memcmp\naeabi_memcpy\naeabi_memmove\naeabi_memset\naeabi_uidivmod\naeabi_uldivmod\nashlti3\nashrti3\nclzti2\ncmpti2\nctzti2\ndivtf3\ndivti3\nffsti2\nfixdfti\nfixsfti\nfixunsdfti\nfixunssfti\nfixunsxfti\nfixxfti\nfloattidf\nfloattisf\nfloattixf\nfloatuntidf\nfloatuntisf\nfloatuntixf\nlshrti3\nmodti3\nmultf3\nmulti3\nmulvti3\nnegti2\nnegvti2\nparityti2\npopcountti2\npowitf2\nsubtf3\nsubvti3\ntrampoline_setup\nucmpti2\nudivmodti4\nudivti3\numodti3\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/ios-armv7s.txt",
    "content": "absvti2\naddtf3\naddvti3\naeabi_cdcmp\naeabi_cdcmpeq_check_nan\naeabi_cfcmp\naeabi_cfcmpeq_check_nan\naeabi_dcmp\naeabi_div0\naeabi_drsub\naeabi_fcmp\naeabi_frsub\naeabi_idivmod\naeabi_ldivmod\naeabi_memcmp\naeabi_memcpy\naeabi_memmove\naeabi_memset\naeabi_uidivmod\naeabi_uldivmod\nashlti3\nashrti3\nclzti2\ncmpti2\nctzti2\ndivtf3\ndivti3\nffsti2\nfixdfti\nfixsfti\nfixunsdfti\nfixunssfti\nfixunsxfti\nfixxfti\nfloattidf\nfloattisf\nfloattixf\nfloatuntidf\nfloatuntisf\nfloatuntixf\nlshrti3\nmodti3\nmultf\nmulti3\nmulvti3\nnegti2\nnegvti2\nparityti2\npopcountti2\npowitf2\nsubtf3\nsubvti3\ntrampoline_setup\nucmpti2\nudivmodti4\nudivti3\numodti3\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/ios.txt",
    "content": "apple_versioning\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/ios6-armv7.txt",
    "content": "absvdi2\nabsvsi2\nadddf3\nadddf3vfp\naddsf3\naddsf3vfp\naddvdi3\naddvsi3\nashldi3\nashrdi3\nbswapdi2\nbswapsi2\nclzdi2\nclzsi2\ncmpdi2\nctzdi2\nctzsi2\ndivdc3\ndivdf3\ndivdf3vfp\ndivdi3\ndivmodsi4\ndivsc3\ndivsf3\ndivsf3vfp\ndivsi3\neqdf2\neqdf2vfp\neqsf2\neqsf2vfp\nextendsfdf2\nextendsfdf2vfp\nffsdi2\nfixdfdi\nfixdfsi\nfixdfsivfp\nfixsfdi\nfixsfsi\nfixsfsivfp\nfixunsdfdi\nfixunsdfsi\nfixunsdfsivfp\nfixunssfdi\nfixunssfsi\nfixunssfsivfp\nfloatdidf\nfloatdisf\nfloatsidf\nfloatsidfvfp\nfloatsisf\nfloatsisfvfp\nfloatundidf\nfloatundisf\nfloatunsidf\nfloatunsisf\nfloatunssidfvfp\nfloatunssisfvfp\ngcc_personality_sj0\ngedf2\ngedf2vfp\ngesf2\ngesf2vfp\ngtdf2\ngtdf2vfp\ngtsf2\ngtsf2vfp\nledf2\nledf2vfp\nlesf2\nlesf2vfp\nlshrdi3\nltdf2\nltdf2vfp\nltsf2\nltsf2vfp\nmoddi3\nmodsi3\nmuldc3\nmuldf3\nmuldf3vfp\nmuldi3\nmulodi4\nmulosi4\nmulsc3\nmulsf3\nmulsf3vfp\nmulvdi3\nmulvsi3\nnedf2\nnedf2vfp\nnegdi2\nnegvdi2\nnegvsi2\nnesf2\nnesf2vfp\nparitydi2\nparitysi2\npopcountdi2\npopcountsi2\npowidf2\npowisf2\nsubdf3\nsubdf3vfp\nsubsf3\nsubsf3vfp\nsubvdi3\nsubvsi3\ntruncdfsf2\ntruncdfsf2vfp\nucmpdi2\nudivdi3\nudivmoddi4\nudivmodsi4\nudivsi3\numoddi3\numodsi3\nunorddf2\nunorddf2vfp\nunordsf2\nunordsf2vfp\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/ios6-armv7s.txt",
    "content": "absvdi2\nabsvsi2\nadddf3\nadddf3vfp\naddsf3\naddsf3vfp\naddvdi3\naddvsi3\nashldi3\nashrdi3\nbswapdi2\nbswapsi2\nclzdi2\nclzsi2\ncmpdi2\nctzdi2\nctzsi2\ndivdc3\ndivdf3\ndivdf3vfp\ndivdi3\ndivmodsi4\ndivsc3\ndivsf3\ndivsf3vfp\ndivsi3\neqdf2\neqdf2vfp\neqsf2\neqsf2vfp\nextendsfdf2\nextendsfdf2vfp\nffsdi2\nfixdfdi\nfixdfsi\nfixdfsivfp\nfixsfdi\nfixsfsi\nfixsfsivfp\nfixunsdfdi\nfixunsdfsi\nfixunsdfsivfp\nfixunssfdi\nfixunssfsi\nfixunssfsivfp\nfloatdidf\nfloatdisf\nfloatsidf\nfloatsidfvfp\nfloatsisf\nfloatsisfvfp\nfloatundidf\nfloatundisf\nfloatunsidf\nfloatunsisf\nfloatunssidfvfp\nfloatunssisfvfp\ngcc_personality_sj0\ngedf2\ngedf2vfp\ngesf2\ngesf2vfp\ngtdf2\ngtdf2vfp\ngtsf2\ngtsf2vfp\nledf2\nledf2vfp\nlesf2\nlesf2vfp\nlshrdi3\nltdf2\nltdf2vfp\nltsf2\nltsf2vfp\nmoddi3\nmodsi3\nmuldc3\nmuldf3\nmuldf3vfp\nmuldi3\nmulodi4\nmulosi4\nmulsc3\nmulsf3\nmulsf3vfp\nmulvdi3\nmulvsi3\nnedf2\nnedf2vfp\nnegdi2\nnegvdi2\nnegvsi2\nnesf2\nnesf2vfp\nparitydi2\nparitysi2\npopcountdi2\npopcountsi2\npowidf2\npowisf2\nsubdf3\nsubdf3vfp\nsubsf3\nsubsf3vfp\nsubvdi3\nsubvsi3\ntruncdfsf2\ntruncdfsf2vfp\nucmpdi2\nudivdi3\nudivmoddi4\nudivmodsi4\nudivsi3\numoddi3\numodsi3\nunorddf2\nunorddf2vfp\nunordsf2\nunordsf2vfp\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/ios7-arm64.txt",
    "content": "clzti2\ndivti3\nfixdfti\nfixsfti\nfixunsdfti\nfloattidf\nfloattisf\nfloatuntidf\nfloatuntisf\ngcc_personality_v0\nmodti3\npowidf2\npowisf2\nudivmodti4\nudivti3\numodti3\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/iossim-i386.txt",
    "content": "absvti2\naddtf3\naddvti3\nashlti3\nashrti3\nclzti2\ncmpti2\nctzti2\ndivti3\ndivtf3\nffsti2\nfixdfti\nfixsfti\nfixunsdfti\nfixunssfti\nfixunsxfti\nfixxfti\nfloattidf\nfloattisf\nfloattixf\nfloatuntidf\nfloatuntisf\nfloatuntixf\nlshrti3\nmodti3\nmuloti4\nmulti3\nmultf3\nmulvti3\nnegti2\nnegvti2\nparityti2\npopcountti2\npowitf2\nsubvti3\nsubtf3\ntrampoline_setup\nucmpti2\nudivmodti4\nudivti3\numodti3\nabsvti2\naddtf3\naddvti3\nashlti3\nashrti3\nclzti2\ncmpti2\nctzti2\ndivti3\ndivtf3\nffsti2\nfixdfti\nfixsfti\nfixunsdfti\nfixunssfti\nfixunsxfti\nfixxfti\nfloattidf\nfloattisf\nfloattixf\nfloatuntidf\nfloatuntisf\nfloatuntixf\nlshrti3\nmodti3\nmuloti4\nmulti3\nmultf3\nmulvti3\nnegti2\nnegvti2\nparityti2\npopcountti2\npowitf2\nsubvti3\nsubtf3\ntrampoline_setup\nucmpti2\nudivmodti4\nudivti3\numodti3\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/iossim-x86_64.txt",
    "content": "addtf3\ndivtf3\nmultf3\npowitf2\nsubtf3\ntrampoline_setup\naddtf3\ndivtf3\nmultf3\npowitf2\nsubtf3\ntrampoline_setup\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/iossim.txt",
    "content": "apple_versioning\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/osx-i386.txt",
    "content": "absvti2\naddtf3\naddvti3\nashlti3\nashrti3\nclzti2\ncmpti2\nctzti2\ndivti3\ndivtf3\nffsti2\nfixdfti\nfixsfti\nfixunsdfti\nfixunssfti\nfixunsxfti\nfixxfti\nfloattidf\nfloattisf\nfloattixf\nfloatuntidf\nfloatuntisf\nfloatuntixf\nlshrti3\nmodti3\nmuloti4\nmulti3\nmultf3\nmulvti3\nnegti2\nnegvti2\nparityti2\npopcountti2\npowitf2\nsubvti3\nsubtf3\ntrampoline_setup\nucmpti2\nudivmodti4\nudivti3\numodti3\nabsvti2\naddtf3\naddvti3\nashlti3\nashrti3\nclzti2\ncmpti2\nctzti2\ndivti3\ndivtf3\nffsti2\nfixdfti\nfixsfti\nfixunsdfti\nfixunssfti\nfixunsxfti\nfixxfti\nfloattidf\nfloattisf\nfloattixf\nfloatuntidf\nfloatuntisf\nfloatuntixf\nlshrti3\nmodti3\nmuloti4\nmulti3\nmultf3\nmulvti3\nnegti2\nnegvti2\nparityti2\npopcountti2\npowitf2\nsubvti3\nsubtf3\ntrampoline_setup\nucmpti2\nudivmodti4\nudivti3\numodti3\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/osx-x86_64.txt",
    "content": "addtf3\ndivtf3\nmultf3\npowitf2\nsubtf3\ntrampoline_setup\naddtf3\ndivtf3\nmultf3\npowitf2\nsubtf3\ntrampoline_setup\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Darwin-excludes/osx.txt",
    "content": "apple_versioning\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/Makefile.mk",
    "content": "#===- lib/builtins/Makefile.mk -----------------------------*- Makefile -*--===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\nModuleName := builtins\nSubDirs :=\n\n# Add arch specific optimized implementations.\nSubDirs += i386 ppc x86_64 arm armv6m\n\n# Add ARM64 dir.\nSubDirs += arm64\n\n# Define the variables for this specific directory.\nSources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))\nObjNames := $(Sources:%.c=%.o)\nImplementation := Generic\n\n# FIXME: use automatic dependencies?\nDependencies := $(wildcard $(Dir)/*.h)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/README.txt",
    "content": "Compiler-RT\n================================\n\nThis directory and its subdirectories contain source code for the compiler\nsupport routines.\n\nCompiler-RT is open source software. You may freely distribute it under the\nterms of the license agreement found in LICENSE.txt.\n\n================================\n\nThis is a replacement library for libgcc.  Each function is contained\nin its own file.  Each function has a corresponding unit test under\ntest/Unit.\n\nA rudimentary script to test each file is in the file called\ntest/Unit/test.\n\nHere is the specification for this library:\n\nhttp://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc\n\nHere is a synopsis of the contents of this library:\n\ntypedef      int si_int;\ntypedef unsigned su_int;\n\ntypedef          long long di_int;\ntypedef unsigned long long du_int;\n\n// Integral bit manipulation\n\ndi_int __ashldi3(di_int a, si_int b);      // a << b\nti_int __ashlti3(ti_int a, si_int b);      // a << b\n\ndi_int __ashrdi3(di_int a, si_int b);      // a >> b  arithmetic (sign fill)\nti_int __ashrti3(ti_int a, si_int b);      // a >> b  arithmetic (sign fill)\ndi_int __lshrdi3(di_int a, si_int b);      // a >> b  logical    (zero fill)\nti_int __lshrti3(ti_int a, si_int b);      // a >> b  logical    (zero fill)\n\nsi_int __clzsi2(si_int a);  // count leading zeros\nsi_int __clzdi2(di_int a);  // count leading zeros\nsi_int __clzti2(ti_int a);  // count leading zeros\nsi_int __ctzsi2(si_int a);  // count trailing zeros\nsi_int __ctzdi2(di_int a);  // count trailing zeros\nsi_int __ctzti2(ti_int a);  // count trailing zeros\n\nsi_int __ffsdi2(di_int a);  // find least significant 1 bit\nsi_int __ffsti2(ti_int a);  // find least significant 1 bit\n\nsi_int __paritysi2(si_int a);  // bit parity\nsi_int __paritydi2(di_int a);  // bit parity\nsi_int __parityti2(ti_int a);  // bit parity\n\nsi_int __popcountsi2(si_int a);  // bit population\nsi_int __popcountdi2(di_int a);  // bit population\nsi_int __popcountti2(ti_int a);  // bit population\n\nuint32_t __bswapsi2(uint32_t a);   // a byteswapped, arm only\nuint64_t __bswapdi2(uint64_t a);   // a byteswapped, arm only\n\n// Integral arithmetic\n\ndi_int __negdi2    (di_int a);                         // -a\nti_int __negti2    (ti_int a);                         // -a\ndi_int __muldi3    (di_int a, di_int b);               // a * b\nti_int __multi3    (ti_int a, ti_int b);               // a * b\nsi_int __divsi3    (si_int a, si_int b);               // a / b   signed\ndi_int __divdi3    (di_int a, di_int b);               // a / b   signed\nti_int __divti3    (ti_int a, ti_int b);               // a / b   signed\nsu_int __udivsi3   (su_int n, su_int d);               // a / b   unsigned\ndu_int __udivdi3   (du_int a, du_int b);               // a / b   unsigned\ntu_int __udivti3   (tu_int a, tu_int b);               // a / b   unsigned\nsi_int __modsi3    (si_int a, si_int b);               // a % b   signed\ndi_int __moddi3    (di_int a, di_int b);               // a % b   signed\nti_int __modti3    (ti_int a, ti_int b);               // a % b   signed\nsu_int __umodsi3   (su_int a, su_int b);               // a % b   unsigned\ndu_int __umoddi3   (du_int a, du_int b);               // a % b   unsigned\ntu_int __umodti3   (tu_int a, tu_int b);               // a % b   unsigned\ndu_int __udivmoddi4(du_int a, du_int b, du_int* rem);  // a / b, *rem = a % b  unsigned\ntu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);  // a / b, *rem = a % b  unsigned\nsu_int __udivmodsi4(su_int a, su_int b, su_int* rem);  // a / b, *rem = a % b  unsigned\nsi_int __divmodsi4(si_int a, si_int b, si_int* rem);   // a / b, *rem = a % b  signed\n\n\n\n//  Integral arithmetic with trapping overflow\n\nsi_int __absvsi2(si_int a);           // abs(a)\ndi_int __absvdi2(di_int a);           // abs(a)\nti_int __absvti2(ti_int a);           // abs(a)\n\nsi_int __negvsi2(si_int a);           // -a\ndi_int __negvdi2(di_int a);           // -a\nti_int __negvti2(ti_int a);           // -a\n\nsi_int __addvsi3(si_int a, si_int b);  // a + b\ndi_int __addvdi3(di_int a, di_int b);  // a + b\nti_int __addvti3(ti_int a, ti_int b);  // a + b\n\nsi_int __subvsi3(si_int a, si_int b);  // a - b\ndi_int __subvdi3(di_int a, di_int b);  // a - b\nti_int __subvti3(ti_int a, ti_int b);  // a - b\n\nsi_int __mulvsi3(si_int a, si_int b);  // a * b\ndi_int __mulvdi3(di_int a, di_int b);  // a * b\nti_int __mulvti3(ti_int a, ti_int b);  // a * b\n\n\n// Integral arithmetic which returns if overflow\n\nsi_int __mulosi4(si_int a, si_int b, int* overflow);  // a * b, overflow set to one if result not in signed range\ndi_int __mulodi4(di_int a, di_int b, int* overflow);  // a * b, overflow set to one if result not in signed range\nti_int __muloti4(ti_int a, ti_int b, int* overflow);  // a * b, overflow set to\n one if result not in signed range\n\n\n//  Integral comparison: a  < b -> 0\n//                       a == b -> 1\n//                       a  > b -> 2\n\nsi_int __cmpdi2 (di_int a, di_int b);\nsi_int __cmpti2 (ti_int a, ti_int b);\nsi_int __ucmpdi2(du_int a, du_int b);\nsi_int __ucmpti2(tu_int a, tu_int b);\n\n//  Integral / floating point conversion\n\ndi_int __fixsfdi(      float a);\ndi_int __fixdfdi(     double a);\ndi_int __fixxfdi(long double a);\n\nti_int __fixsfti(      float a);\nti_int __fixdfti(     double a);\nti_int __fixxfti(long double a);\nuint64_t __fixtfdi(long double input);  // ppc only, doesn't match documentation\n\nsu_int __fixunssfsi(      float a);\nsu_int __fixunsdfsi(     double a);\nsu_int __fixunsxfsi(long double a);\n\ndu_int __fixunssfdi(      float a);\ndu_int __fixunsdfdi(     double a);\ndu_int __fixunsxfdi(long double a);\n\ntu_int __fixunssfti(      float a);\ntu_int __fixunsdfti(     double a);\ntu_int __fixunsxfti(long double a);\nuint64_t __fixunstfdi(long double input);  // ppc only\n\nfloat       __floatdisf(di_int a);\ndouble      __floatdidf(di_int a);\nlong double __floatdixf(di_int a);\nlong double __floatditf(int64_t a);        // ppc only\n\nfloat       __floattisf(ti_int a);\ndouble      __floattidf(ti_int a);\nlong double __floattixf(ti_int a);\n\nfloat       __floatundisf(du_int a);\ndouble      __floatundidf(du_int a);\nlong double __floatundixf(du_int a);\nlong double __floatunditf(uint64_t a);     // ppc only\n\nfloat       __floatuntisf(tu_int a);\ndouble      __floatuntidf(tu_int a);\nlong double __floatuntixf(tu_int a);\n\n//  Floating point raised to integer power\n\nfloat       __powisf2(      float a, si_int b);  // a ^ b\ndouble      __powidf2(     double a, si_int b);  // a ^ b\nlong double __powixf2(long double a, si_int b);  // a ^ b\nlong double __powitf2(long double a, si_int b);  // ppc only, a ^ b\n\n//  Complex arithmetic\n\n//  (a + ib) * (c + id)\n\n      float _Complex __mulsc3( float a,  float b,  float c,  float d);\n     double _Complex __muldc3(double a, double b, double c, double d);\nlong double _Complex __mulxc3(long double a, long double b,\n                              long double c, long double d);\nlong double _Complex __multc3(long double a, long double b,\n                              long double c, long double d); // ppc only\n\n//  (a + ib) / (c + id)\n\n      float _Complex __divsc3( float a,  float b,  float c,  float d);\n     double _Complex __divdc3(double a, double b, double c, double d);\nlong double _Complex __divxc3(long double a, long double b,\n                              long double c, long double d);\nlong double _Complex __divtc3(long double a, long double b,\n                              long double c, long double d);  // ppc only\n\n\n//         Runtime support\n\n// __clear_cache() is used to tell process that new instructions have been\n// written to an address range.  Necessary on processors that do not have\n// a unified instruction and data cache.\nvoid __clear_cache(void* start, void* end);\n\n// __enable_execute_stack() is used with nested functions when a trampoline\n// function is written onto the stack and that page range needs to be made\n// executable.\nvoid __enable_execute_stack(void* addr);\n\n// __gcc_personality_v0() is normally only called by the system unwinder.\n// C code (as opposed to C++) normally does not need a personality function\n// because there are no catch clauses or destructors to be run.  But there\n// is a C language extension __attribute__((cleanup(func))) which marks local\n// variables as needing the cleanup function \"func\" to be run when the\n// variable goes out of scope.  That includes when an exception is thrown,\n// so a personality handler is needed.  \n_Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions,\n         uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,\n         _Unwind_Context_t context);\n\n// for use with some implementations of assert() in <assert.h>\nvoid __eprintf(const char* format, const char* assertion_expression,\n\t\t\t\tconst char* line, const char* file);\n\n// for systems with emulated thread local storage\nvoid* __emutls_get_address(struct __emutls_control*);\n\n\n//   Power PC specific functions\n\n// There is no C interface to the saveFP/restFP functions.  They are helper\n// functions called by the prolog and epilog of functions that need to save\n// a number of non-volatile float point registers.  \nsaveFP\nrestFP\n\n// PowerPC has a standard template for trampoline functions.  This function\n// generates a custom trampoline function with the specific realFunc\n// and localsPtr values.\nvoid __trampoline_setup(uint32_t* trampOnStack, int trampSizeAllocated, \n                                const void* realFunc, void* localsPtr);\n\n// adds two 128-bit double-double precision values ( x + y )\nlong double __gcc_qadd(long double x, long double y);  \n\n// subtracts two 128-bit double-double precision values ( x - y )\nlong double __gcc_qsub(long double x, long double y); \n\n// multiples two 128-bit double-double precision values ( x * y )\nlong double __gcc_qmul(long double x, long double y);  \n\n// divides two 128-bit double-double precision values ( x / y )\nlong double __gcc_qdiv(long double a, long double b);  \n\n\n//    ARM specific functions\n\n// There is no C interface to the switch* functions.  These helper functions\n// are only needed by Thumb1 code for efficient switch table generation.\nswitch16\nswitch32\nswitch8\nswitchu8\n\n// There is no C interface to the *_vfp_d8_d15_regs functions.  There are\n// called in the prolog and epilog of Thumb1 functions.  When the C++ ABI use\n// SJLJ for exceptions, each function with a catch clause or destuctors needs\n// to save and restore all registers in it prolog and epliog.  But there is \n// no way to access vector and high float registers from thumb1 code, so the \n// compiler must add call outs to these helper functions in the prolog and \n// epilog.\nrestore_vfp_d8_d15_regs\nsave_vfp_d8_d15_regs\n\n\n// Note: long ago ARM processors did not have floating point hardware support.\n// Floating point was done in software and floating point parameters were \n// passed in integer registers.  When hardware support was added for floating\n// point, new *vfp functions were added to do the same operations but with \n// floating point parameters in floating point registers.\n\n// Undocumented functions\n\nfloat  __addsf3vfp(float a, float b);   // Appears to return a + b\ndouble __adddf3vfp(double a, double b); // Appears to return a + b\nfloat  __divsf3vfp(float a, float b);   // Appears to return a / b\ndouble __divdf3vfp(double a, double b); // Appears to return a / b\nint    __eqsf2vfp(float a, float b);    // Appears to return  one\n                                        //     iff a == b and neither is NaN.\nint    __eqdf2vfp(double a, double b);  // Appears to return  one\n                                        //     iff a == b and neither is NaN.\ndouble __extendsfdf2vfp(float a);       // Appears to convert from\n                                        //     float to double.\nint    __fixdfsivfp(double a);          // Appears to convert from\n                                        //     double to int.\nint    __fixsfsivfp(float a);           // Appears to convert from\n                                        //     float to int.\nunsigned int __fixunssfsivfp(float a);  // Appears to convert from\n                                        //     float to unsigned int.\nunsigned int __fixunsdfsivfp(double a); // Appears to convert from\n                                        //     double to unsigned int.\ndouble __floatsidfvfp(int a);           // Appears to convert from\n                                        //     int to double.\nfloat __floatsisfvfp(int a);            // Appears to convert from\n                                        //     int to float.\ndouble __floatunssidfvfp(unsigned int a); // Appears to convert from\n                                        //     unisgned int to double.\nfloat __floatunssisfvfp(unsigned int a); // Appears to convert from\n                                        //     unisgned int to float.\nint __gedf2vfp(double a, double b);     // Appears to return __gedf2\n                                        //     (a >= b)\nint __gesf2vfp(float a, float b);       // Appears to return __gesf2\n                                        //     (a >= b)\nint __gtdf2vfp(double a, double b);     // Appears to return __gtdf2\n                                        //     (a > b)\nint __gtsf2vfp(float a, float b);       // Appears to return __gtsf2\n                                        //     (a > b)\nint __ledf2vfp(double a, double b);     // Appears to return __ledf2\n                                        //     (a <= b)\nint __lesf2vfp(float a, float b);       // Appears to return __lesf2\n                                        //     (a <= b)\nint __ltdf2vfp(double a, double b);     // Appears to return __ltdf2\n                                        //     (a < b)\nint __ltsf2vfp(float a, float b);       // Appears to return __ltsf2\n                                        //     (a < b)\ndouble __muldf3vfp(double a, double b); // Appears to return a * b\nfloat __mulsf3vfp(float a, float b);    // Appears to return a * b\nint __nedf2vfp(double a, double b);     // Appears to return __nedf2\n                                        //     (a != b)\ndouble __negdf2vfp(double a);           // Appears to return -a\nfloat __negsf2vfp(float a);             // Appears to return -a\nfloat __negsf2vfp(float a);             // Appears to return -a\ndouble __subdf3vfp(double a, double b); // Appears to return a - b\nfloat __subsf3vfp(float a, float b);    // Appears to return a - b\nfloat __truncdfsf2vfp(double a);        // Appears to convert from\n                                        //     double to float.\nint __unorddf2vfp(double a, double b);  // Appears to return __unorddf2\nint __unordsf2vfp(float a, float b);    // Appears to return __unordsf2\n\n\nPreconditions are listed for each function at the definition when there are any.\nAny preconditions reflect the specification at\nhttp://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc.\n\nAssumptions are listed in \"int_lib.h\", and in individual files.  Where possible\nassumptions are checked at compile time.\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/absvdi2.c",
    "content": "/*===-- absvdi2.c - Implement __absvdi2 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===\n *\n * This file implements __absvdi2 for the compiler_rt library.\n *\n *===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: absolute value */\n\n/* Effects: aborts if abs(x) < 0 */\n\nCOMPILER_RT_ABI di_int\n__absvdi2(di_int a)\n{\n    const int N = (int)(sizeof(di_int) * CHAR_BIT);\n    if (a == ((di_int)1 << (N-1)))\n        compilerrt_abort();\n    const di_int t = a >> (N - 1);\n    return (a ^ t) - t;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/absvsi2.c",
    "content": "/* ===-- absvsi2.c - Implement __absvsi2 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __absvsi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: absolute value */\n\n/* Effects: aborts if abs(x) < 0 */\n\nCOMPILER_RT_ABI si_int\n__absvsi2(si_int a)\n{\n    const int N = (int)(sizeof(si_int) * CHAR_BIT);\n    if (a == (1 << (N-1)))\n        compilerrt_abort();\n    const si_int t = a >> (N - 1);\n    return (a ^ t) - t;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/absvti2.c",
    "content": "/* ===-- absvti2.c - Implement __absvdi2 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __absvti2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: absolute value */\n\n/* Effects: aborts if abs(x) < 0 */\n\nCOMPILER_RT_ABI ti_int\n__absvti2(ti_int a)\n{\n    const int N = (int)(sizeof(ti_int) * CHAR_BIT);\n    if (a == ((ti_int)1 << (N-1)))\n        compilerrt_abort();\n    const ti_int s = a >> (N - 1);\n    return (a ^ s) - s;\n}\n\n#endif /* CRT_HAS_128BIT */\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/adddf3.c",
    "content": "//===-- lib/adddf3.c - Double-precision addition ------------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements double-precision soft-float addition with the IEEE-754\n// default rounding (to nearest, ties to even).\n//\n//===----------------------------------------------------------------------===//\n\n#define DOUBLE_PRECISION\n#include \"fp_add_impl.inc\"\n\nARM_EABI_FNALIAS(dadd, adddf3)\n\nCOMPILER_RT_ABI double __adddf3(double a, double b){\n    return __addXf3__(a, b);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/addsf3.c",
    "content": "//===-- lib/addsf3.c - Single-precision addition ------------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements single-precision soft-float addition with the IEEE-754\n// default rounding (to nearest, ties to even).\n//\n//===----------------------------------------------------------------------===//\n\n#define SINGLE_PRECISION\n#include \"fp_add_impl.inc\"\n\nARM_EABI_FNALIAS(fadd, addsf3)\n\nCOMPILER_RT_ABI float __addsf3(float a, float b) {\n    return __addXf3__(a, b);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/addtf3.c",
    "content": "//===-- lib/addtf3.c - Quad-precision addition --------------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements quad-precision soft-float addition with the IEEE-754\n// default rounding (to nearest, ties to even).\n//\n//===----------------------------------------------------------------------===//\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\n#include \"fp_add_impl.inc\"\n\nCOMPILER_RT_ABI long double __addtf3(long double a, long double b){\n    return __addXf3__(a, b);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/addvdi3.c",
    "content": "/* ===-- addvdi3.c - Implement __addvdi3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __addvdi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a + b */\n\n/* Effects: aborts if a + b overflows */\n\nCOMPILER_RT_ABI di_int\n__addvdi3(di_int a, di_int b)\n{\n    di_int s = (du_int) a + (du_int) b;\n    if (b >= 0)\n    {\n        if (s < a)\n            compilerrt_abort();\n    }\n    else\n    {\n        if (s >= a)\n            compilerrt_abort();\n    }\n    return s;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/addvsi3.c",
    "content": "/* ===-- addvsi3.c - Implement __addvsi3 -----------------------------------===\n *\n *                    The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __addvsi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a + b */\n\n/* Effects: aborts if a + b overflows */\n\nCOMPILER_RT_ABI si_int\n__addvsi3(si_int a, si_int b)\n{\n    si_int s = (su_int) a + (su_int) b;\n    if (b >= 0)\n    {\n        if (s < a)\n            compilerrt_abort();\n    }\n    else\n    {\n        if (s >= a)\n            compilerrt_abort();\n    }\n    return s;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/addvti3.c",
    "content": "/* ===-- addvti3.c - Implement __addvti3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __addvti3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: a + b */\n\n/* Effects: aborts if a + b overflows */\n\nCOMPILER_RT_ABI ti_int\n__addvti3(ti_int a, ti_int b)\n{\n    ti_int s = (tu_int) a + (tu_int) b;\n    if (b >= 0)\n    {\n        if (s < a)\n            compilerrt_abort();\n    }\n    else\n    {\n        if (s >= a)\n            compilerrt_abort();\n    }\n    return s;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/apple_versioning.c",
    "content": "/* ===-- apple_versioning.c - Adds versioning symbols for ld ---------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n\n#if __APPLE__\n  #include <Availability.h>\n  \n  #if __IPHONE_OS_VERSION_MIN_REQUIRED\n    #define NOT_HERE_BEFORE_10_6(sym) \n    #define NOT_HERE_IN_10_8_AND_EARLIER(sym) \\\n        extern const char sym##_tmp61 __asm(\"$ld$hide$os6.1$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp61 = 0; \\\n        extern const char sym##_tmp60 __asm(\"$ld$hide$os6.0$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp60 = 0; \\\n        extern const char sym##_tmp51 __asm(\"$ld$hide$os5.1$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp51 = 0; \\\n        extern const char sym##_tmp50 __asm(\"$ld$hide$os5.0$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp50 = 0; \n  #else\n    #define NOT_HERE_BEFORE_10_6(sym) \\\n         extern const char sym##_tmp4 __asm(\"$ld$hide$os10.4$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp4 = 0; \\\n        extern const char sym##_tmp5 __asm(\"$ld$hide$os10.5$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp5 = 0; \n    #define NOT_HERE_IN_10_8_AND_EARLIER(sym) \\\n         extern const char sym##_tmp8 __asm(\"$ld$hide$os10.8$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp8 = 0; \\\n        extern const char sym##_tmp7 __asm(\"$ld$hide$os10.7$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp7 = 0; \\\n        extern const char sym##_tmp6 __asm(\"$ld$hide$os10.6$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp6 = 0; \n  #endif \n\n\n/* Symbols in libSystem.dylib in 10.6 and later, \n *  but are in libgcc_s.dylib in earlier versions\n */\n\nNOT_HERE_BEFORE_10_6(__absvdi2)\nNOT_HERE_BEFORE_10_6(__absvsi2)\nNOT_HERE_BEFORE_10_6(__absvti2)\nNOT_HERE_BEFORE_10_6(__addvdi3)\nNOT_HERE_BEFORE_10_6(__addvsi3)\nNOT_HERE_BEFORE_10_6(__addvti3)\nNOT_HERE_BEFORE_10_6(__ashldi3)\nNOT_HERE_BEFORE_10_6(__ashlti3)\nNOT_HERE_BEFORE_10_6(__ashrdi3)\nNOT_HERE_BEFORE_10_6(__ashrti3)\nNOT_HERE_BEFORE_10_6(__clear_cache)\nNOT_HERE_BEFORE_10_6(__clzdi2)\nNOT_HERE_BEFORE_10_6(__clzsi2)\nNOT_HERE_BEFORE_10_6(__clzti2)\nNOT_HERE_BEFORE_10_6(__cmpdi2)\nNOT_HERE_BEFORE_10_6(__cmpti2)\nNOT_HERE_BEFORE_10_6(__ctzdi2)\nNOT_HERE_BEFORE_10_6(__ctzsi2)\nNOT_HERE_BEFORE_10_6(__ctzti2)\nNOT_HERE_BEFORE_10_6(__divdc3)\nNOT_HERE_BEFORE_10_6(__divdi3)\nNOT_HERE_BEFORE_10_6(__divsc3)\nNOT_HERE_BEFORE_10_6(__divtc3)\nNOT_HERE_BEFORE_10_6(__divti3)\nNOT_HERE_BEFORE_10_6(__divxc3)\nNOT_HERE_BEFORE_10_6(__enable_execute_stack)\nNOT_HERE_BEFORE_10_6(__ffsdi2)\nNOT_HERE_BEFORE_10_6(__ffsti2)\nNOT_HERE_BEFORE_10_6(__fixdfdi)\nNOT_HERE_BEFORE_10_6(__fixdfti)\nNOT_HERE_BEFORE_10_6(__fixsfdi)\nNOT_HERE_BEFORE_10_6(__fixsfti)\nNOT_HERE_BEFORE_10_6(__fixtfdi)\nNOT_HERE_BEFORE_10_6(__fixunsdfdi)\nNOT_HERE_BEFORE_10_6(__fixunsdfsi)\nNOT_HERE_BEFORE_10_6(__fixunsdfti)\nNOT_HERE_BEFORE_10_6(__fixunssfdi)\nNOT_HERE_BEFORE_10_6(__fixunssfsi)\nNOT_HERE_BEFORE_10_6(__fixunssfti)\nNOT_HERE_BEFORE_10_6(__fixunstfdi)\nNOT_HERE_BEFORE_10_6(__fixunsxfdi)\nNOT_HERE_BEFORE_10_6(__fixunsxfsi)\nNOT_HERE_BEFORE_10_6(__fixunsxfti)\nNOT_HERE_BEFORE_10_6(__fixxfdi)\nNOT_HERE_BEFORE_10_6(__fixxfti)\nNOT_HERE_BEFORE_10_6(__floatdidf)\nNOT_HERE_BEFORE_10_6(__floatdisf)\nNOT_HERE_BEFORE_10_6(__floatditf)\nNOT_HERE_BEFORE_10_6(__floatdixf)\nNOT_HERE_BEFORE_10_6(__floattidf)\nNOT_HERE_BEFORE_10_6(__floattisf)\nNOT_HERE_BEFORE_10_6(__floattixf)\nNOT_HERE_BEFORE_10_6(__floatundidf)\nNOT_HERE_BEFORE_10_6(__floatundisf)\nNOT_HERE_BEFORE_10_6(__floatunditf)\nNOT_HERE_BEFORE_10_6(__floatundixf)\nNOT_HERE_BEFORE_10_6(__floatuntidf)\nNOT_HERE_BEFORE_10_6(__floatuntisf)\nNOT_HERE_BEFORE_10_6(__floatuntixf)\nNOT_HERE_BEFORE_10_6(__gcc_personality_v0)\nNOT_HERE_BEFORE_10_6(__lshrdi3)\nNOT_HERE_BEFORE_10_6(__lshrti3)\nNOT_HERE_BEFORE_10_6(__moddi3)\nNOT_HERE_BEFORE_10_6(__modti3)\nNOT_HERE_BEFORE_10_6(__muldc3)\nNOT_HERE_BEFORE_10_6(__muldi3)\nNOT_HERE_BEFORE_10_6(__mulsc3)\nNOT_HERE_BEFORE_10_6(__multc3)\nNOT_HERE_BEFORE_10_6(__multi3)\nNOT_HERE_BEFORE_10_6(__mulvdi3)\nNOT_HERE_BEFORE_10_6(__mulvsi3)\nNOT_HERE_BEFORE_10_6(__mulvti3)\nNOT_HERE_BEFORE_10_6(__mulxc3)\nNOT_HERE_BEFORE_10_6(__negdi2)\nNOT_HERE_BEFORE_10_6(__negti2)\nNOT_HERE_BEFORE_10_6(__negvdi2)\nNOT_HERE_BEFORE_10_6(__negvsi2)\nNOT_HERE_BEFORE_10_6(__negvti2)\nNOT_HERE_BEFORE_10_6(__paritydi2)\nNOT_HERE_BEFORE_10_6(__paritysi2)\nNOT_HERE_BEFORE_10_6(__parityti2)\nNOT_HERE_BEFORE_10_6(__popcountdi2)\nNOT_HERE_BEFORE_10_6(__popcountsi2)\nNOT_HERE_BEFORE_10_6(__popcountti2)\nNOT_HERE_BEFORE_10_6(__powidf2)\nNOT_HERE_BEFORE_10_6(__powisf2)\nNOT_HERE_BEFORE_10_6(__powitf2)\nNOT_HERE_BEFORE_10_6(__powixf2)\nNOT_HERE_BEFORE_10_6(__subvdi3)\nNOT_HERE_BEFORE_10_6(__subvsi3)\nNOT_HERE_BEFORE_10_6(__subvti3)\nNOT_HERE_BEFORE_10_6(__ucmpdi2)\nNOT_HERE_BEFORE_10_6(__ucmpti2)\nNOT_HERE_BEFORE_10_6(__udivdi3)\nNOT_HERE_BEFORE_10_6(__udivmoddi4)\nNOT_HERE_BEFORE_10_6(__udivmodti4)\nNOT_HERE_BEFORE_10_6(__udivti3)\nNOT_HERE_BEFORE_10_6(__umoddi3)\nNOT_HERE_BEFORE_10_6(__umodti3)\n\n\n#if __ppc__\nNOT_HERE_BEFORE_10_6(__gcc_qadd)\nNOT_HERE_BEFORE_10_6(__gcc_qdiv)\nNOT_HERE_BEFORE_10_6(__gcc_qmul)\nNOT_HERE_BEFORE_10_6(__gcc_qsub)\nNOT_HERE_BEFORE_10_6(__trampoline_setup)\n#endif /* __ppc__ */\n\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_compare_exchange)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_compare_exchange_1)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_compare_exchange_2)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_compare_exchange_4)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_compare_exchange_8)\n\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_exchange)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_exchange_1)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_exchange_2)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_exchange_4)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_exchange_8)\n\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_add_1)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_add_2)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_add_4)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_add_8)\n\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_and_1)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_and_2)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_and_4)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_and_8)\n\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_or_1)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_or_2)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_or_4)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_or_8)\n\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_sub_1)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_sub_2)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_sub_4)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_sub_8)\n\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_xor_1)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_xor_2)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_xor_4)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_fetch_xor_8)\n\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_load)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_load_1)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_load_2)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_load_4)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_load_8)\n\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_store)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_store_1)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_store_2)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_store_4)\nNOT_HERE_IN_10_8_AND_EARLIER(__atomic_store_8)\n\n\n#if __arm__ && __DYNAMIC__\n   #define NOT_HERE_UNTIL_AFTER_4_3(sym) \\\n        extern const char sym##_tmp1 __asm(\"$ld$hide$os3.0$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp1 = 0; \\\n        extern const char sym##_tmp2 __asm(\"$ld$hide$os3.1$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp2 = 0; \\\n        extern const char sym##_tmp3 __asm(\"$ld$hide$os3.2$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp3 = 0; \\\n        extern const char sym##_tmp4 __asm(\"$ld$hide$os4.0$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp4 = 0; \\\n        extern const char sym##_tmp5 __asm(\"$ld$hide$os4.1$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp5 = 0; \\\n        extern const char sym##_tmp6 __asm(\"$ld$hide$os4.2$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp6 = 0; \\\n        extern const char sym##_tmp7 __asm(\"$ld$hide$os4.3$_\" #sym ); \\\n            __attribute__((visibility(\"default\"))) const char sym##_tmp7 = 0; \n            \nNOT_HERE_UNTIL_AFTER_4_3(__absvdi2)\nNOT_HERE_UNTIL_AFTER_4_3(__absvsi2)\nNOT_HERE_UNTIL_AFTER_4_3(__adddf3)\nNOT_HERE_UNTIL_AFTER_4_3(__adddf3vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__addsf3)\nNOT_HERE_UNTIL_AFTER_4_3(__addsf3vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__addvdi3)\nNOT_HERE_UNTIL_AFTER_4_3(__addvsi3)\nNOT_HERE_UNTIL_AFTER_4_3(__ashldi3)\nNOT_HERE_UNTIL_AFTER_4_3(__ashrdi3)\nNOT_HERE_UNTIL_AFTER_4_3(__bswapdi2)\nNOT_HERE_UNTIL_AFTER_4_3(__bswapsi2)\nNOT_HERE_UNTIL_AFTER_4_3(__clzdi2)\nNOT_HERE_UNTIL_AFTER_4_3(__clzsi2)\nNOT_HERE_UNTIL_AFTER_4_3(__cmpdi2)\nNOT_HERE_UNTIL_AFTER_4_3(__ctzdi2)\nNOT_HERE_UNTIL_AFTER_4_3(__ctzsi2)\nNOT_HERE_UNTIL_AFTER_4_3(__divdc3)\nNOT_HERE_UNTIL_AFTER_4_3(__divdf3)\nNOT_HERE_UNTIL_AFTER_4_3(__divdf3vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__divdi3)\nNOT_HERE_UNTIL_AFTER_4_3(__divsc3)\nNOT_HERE_UNTIL_AFTER_4_3(__divsf3)\nNOT_HERE_UNTIL_AFTER_4_3(__divsf3vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__divsi3)\nNOT_HERE_UNTIL_AFTER_4_3(__eqdf2)\nNOT_HERE_UNTIL_AFTER_4_3(__eqdf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__eqsf2)\nNOT_HERE_UNTIL_AFTER_4_3(__eqsf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__extendsfdf2)\nNOT_HERE_UNTIL_AFTER_4_3(__extendsfdf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__ffsdi2)\nNOT_HERE_UNTIL_AFTER_4_3(__fixdfdi)\nNOT_HERE_UNTIL_AFTER_4_3(__fixdfsi)\nNOT_HERE_UNTIL_AFTER_4_3(__fixdfsivfp)\nNOT_HERE_UNTIL_AFTER_4_3(__fixsfdi)\nNOT_HERE_UNTIL_AFTER_4_3(__fixsfsi)\nNOT_HERE_UNTIL_AFTER_4_3(__fixsfsivfp)\nNOT_HERE_UNTIL_AFTER_4_3(__fixunsdfdi)\nNOT_HERE_UNTIL_AFTER_4_3(__fixunsdfsi)\nNOT_HERE_UNTIL_AFTER_4_3(__fixunsdfsivfp)\nNOT_HERE_UNTIL_AFTER_4_3(__fixunssfdi)\nNOT_HERE_UNTIL_AFTER_4_3(__fixunssfsi)\nNOT_HERE_UNTIL_AFTER_4_3(__fixunssfsivfp)\nNOT_HERE_UNTIL_AFTER_4_3(__floatdidf)\nNOT_HERE_UNTIL_AFTER_4_3(__floatdisf)\nNOT_HERE_UNTIL_AFTER_4_3(__floatsidf)\nNOT_HERE_UNTIL_AFTER_4_3(__floatsidfvfp)\nNOT_HERE_UNTIL_AFTER_4_3(__floatsisf)\nNOT_HERE_UNTIL_AFTER_4_3(__floatsisfvfp)\nNOT_HERE_UNTIL_AFTER_4_3(__floatundidf)\nNOT_HERE_UNTIL_AFTER_4_3(__floatundisf)\nNOT_HERE_UNTIL_AFTER_4_3(__floatunsidf)\nNOT_HERE_UNTIL_AFTER_4_3(__floatunsisf)\nNOT_HERE_UNTIL_AFTER_4_3(__floatunssidfvfp)\nNOT_HERE_UNTIL_AFTER_4_3(__floatunssisfvfp)\nNOT_HERE_UNTIL_AFTER_4_3(__gedf2)\nNOT_HERE_UNTIL_AFTER_4_3(__gedf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__gesf2)\nNOT_HERE_UNTIL_AFTER_4_3(__gesf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__gtdf2)\nNOT_HERE_UNTIL_AFTER_4_3(__gtdf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__gtsf2)\nNOT_HERE_UNTIL_AFTER_4_3(__gtsf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__ledf2)\nNOT_HERE_UNTIL_AFTER_4_3(__ledf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__lesf2)\nNOT_HERE_UNTIL_AFTER_4_3(__lesf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__lshrdi3)\nNOT_HERE_UNTIL_AFTER_4_3(__ltdf2)\nNOT_HERE_UNTIL_AFTER_4_3(__ltdf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__ltsf2)\nNOT_HERE_UNTIL_AFTER_4_3(__ltsf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__moddi3)\nNOT_HERE_UNTIL_AFTER_4_3(__modsi3)\nNOT_HERE_UNTIL_AFTER_4_3(__muldc3)\nNOT_HERE_UNTIL_AFTER_4_3(__muldf3)\nNOT_HERE_UNTIL_AFTER_4_3(__muldf3vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__muldi3)\nNOT_HERE_UNTIL_AFTER_4_3(__mulsc3)\nNOT_HERE_UNTIL_AFTER_4_3(__mulsf3)\nNOT_HERE_UNTIL_AFTER_4_3(__mulsf3vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__mulvdi3)\nNOT_HERE_UNTIL_AFTER_4_3(__mulvsi3)\nNOT_HERE_UNTIL_AFTER_4_3(__nedf2)\nNOT_HERE_UNTIL_AFTER_4_3(__nedf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__negdi2)\nNOT_HERE_UNTIL_AFTER_4_3(__negvdi2)\nNOT_HERE_UNTIL_AFTER_4_3(__negvsi2)\nNOT_HERE_UNTIL_AFTER_4_3(__nesf2)\nNOT_HERE_UNTIL_AFTER_4_3(__nesf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__paritydi2)\nNOT_HERE_UNTIL_AFTER_4_3(__paritysi2)\nNOT_HERE_UNTIL_AFTER_4_3(__popcountdi2)\nNOT_HERE_UNTIL_AFTER_4_3(__popcountsi2)\nNOT_HERE_UNTIL_AFTER_4_3(__powidf2)\nNOT_HERE_UNTIL_AFTER_4_3(__powisf2)\nNOT_HERE_UNTIL_AFTER_4_3(__subdf3)\nNOT_HERE_UNTIL_AFTER_4_3(__subdf3vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__subsf3)\nNOT_HERE_UNTIL_AFTER_4_3(__subsf3vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__subvdi3)\nNOT_HERE_UNTIL_AFTER_4_3(__subvsi3)\nNOT_HERE_UNTIL_AFTER_4_3(__truncdfsf2)\nNOT_HERE_UNTIL_AFTER_4_3(__truncdfsf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__ucmpdi2)\nNOT_HERE_UNTIL_AFTER_4_3(__udivdi3)\nNOT_HERE_UNTIL_AFTER_4_3(__udivmoddi4)\nNOT_HERE_UNTIL_AFTER_4_3(__udivsi3)\nNOT_HERE_UNTIL_AFTER_4_3(__umoddi3)\nNOT_HERE_UNTIL_AFTER_4_3(__umodsi3)\nNOT_HERE_UNTIL_AFTER_4_3(__unorddf2)\nNOT_HERE_UNTIL_AFTER_4_3(__unorddf2vfp)\nNOT_HERE_UNTIL_AFTER_4_3(__unordsf2)\nNOT_HERE_UNTIL_AFTER_4_3(__unordsf2vfp)\n\nNOT_HERE_UNTIL_AFTER_4_3(__divmodsi4)\nNOT_HERE_UNTIL_AFTER_4_3(__udivmodsi4)\n#endif // __arm__ && __DYNAMIC__\n\n       \n       \n\n\n#else /* !__APPLE__ */\n\nextern int avoid_empty_file;\n\n#endif /* !__APPLE__*/\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/Makefile.mk",
    "content": "#===- lib/builtins/arm/Makefile.mk -------------------------*- Makefile -*--===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\nModuleName := builtins\nSubDirs := \nOnlyArchs := armv5 armv6 armv7 armv7k armv7m armv7em armv7s\n\nAsmSources := $(foreach file,$(wildcard $(Dir)/*.S),$(notdir $(file)))\nSources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))\nObjNames := $(Sources:%.c=%.o) $(AsmSources:%.S=%.o)\nImplementation := Optimized\n\n# FIXME: use automatic dependencies?\nDependencies := $(wildcard lib/*.h $(Dir)/*.h)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/adddf3vfp.S",
    "content": "//===-- adddf3vfp.S - Implement adddf3vfp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// double __adddf3vfp(double a, double b) { return a + b; }\n//\n// Adds two double precision floating point numbers using the Darwin\n// calling convention where double arguments are passsed in GPR pairs\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__adddf3vfp)\n\tvmov\td6, r0, r1\t\t// move first param from r0/r1 pair into d6\n\tvmov\td7, r2, r3\t\t// move second param from r2/r3 pair into d7\n\tvadd.f64 d6, d6, d7\t\t\n\tvmov\tr0, r1, d6\t\t// move result back to r0/r1 pair\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__adddf3vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/addsf3vfp.S",
    "content": "//===-- addsf3vfp.S - Implement addsf3vfp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern float __addsf3vfp(float a, float b);\n//\n// Adds two single precision floating point numbers using the Darwin\n// calling convention where single arguments are passsed in GPRs\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__addsf3vfp)\n\tvmov\ts14, r0\t\t// move first param from r0 into float register\n\tvmov\ts15, r1\t\t// move second param from r1 into float register\n\tvadd.f32 s14, s14, s15\n\tvmov\tr0, s14\t\t// move result back to r0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__addsf3vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_cdcmp.S",
    "content": "//===-- aeabi_cdcmp.S - EABI cdcmp* implementation ------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__\n#error big endian support not implemented\n#endif\n\n#define APSR_Z (1 << 30)\n#define APSR_C (1 << 29)\n\n// void __aeabi_cdcmpeq(double a, double b) {\n//   if (isnan(a) || isnan(b)) {\n//     Z = 0; C = 1;\n//   } else {\n//     __aeabi_cdcmple(a, b);\n//   }\n// }\n\n        .syntax unified\n        .p2align 2\nDEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)\n        push {r0-r3, lr}\n        bl __aeabi_cdcmpeq_check_nan\n        cmp r0, #1\n        pop {r0-r3, lr}\n\n        // NaN has been ruled out, so __aeabi_cdcmple can't trap\n        bne __aeabi_cdcmple\n\n        msr CPSR_f, #APSR_C\n        JMP(lr)\nEND_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)\n\n\n// void __aeabi_cdcmple(double a, double b) {\n//   if (__aeabi_dcmplt(a, b)) {\n//     Z = 0; C = 0;\n//   } else if (__aeabi_dcmpeq(a, b)) {\n//     Z = 1; C = 1;\n//   } else {\n//     Z = 0; C = 1;\n//   }\n// }\n\n        .syntax unified\n        .p2align 2\nDEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmple)\n        // Per the RTABI, this function must preserve r0-r11.\n        // Save lr in the same instruction for compactness\n        push {r0-r3, lr}\n\n        bl __aeabi_dcmplt\n        cmp r0, #1\n        moveq ip, #0\n        beq 1f\n\n        ldm sp, {r0-r3}\n        bl __aeabi_dcmpeq\n        cmp r0, #1\n        moveq ip, #(APSR_C | APSR_Z)\n        movne ip, #(APSR_C)\n\n1:\n        msr CPSR_f, ip\n        pop {r0-r3}\n        POP_PC()\nEND_COMPILERRT_FUNCTION(__aeabi_cdcmple)\n\n// int __aeabi_cdrcmple(double a, double b) {\n//   return __aeabi_cdcmple(b, a);\n// }\n\n        .syntax unified\n        .p2align 2\nDEFINE_COMPILERRT_FUNCTION(__aeabi_cdrcmple)\n        // Swap r0 and r2\n        mov ip, r0\n        mov r0, r2\n        mov r2, ip\n\n        // Swap r1 and r3\n        mov ip, r1\n        mov r1, r3\n        mov r3, ip\n\n        b __aeabi_cdcmple\nEND_COMPILERRT_FUNCTION(__aeabi_cdrcmple)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_cdcmpeq_check_nan.c",
    "content": "//===-- lib/arm/aeabi_cdcmpeq_helper.c - Helper for cdcmpeq ---------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stdint.h>\n\n__attribute__((pcs(\"aapcs\")))\n__attribute__((visibility(\"hidden\")))\nint __aeabi_cdcmpeq_check_nan(double a, double b) {\n    return __builtin_isnan(a) || __builtin_isnan(b);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_cfcmp.S",
    "content": "//===-- aeabi_cfcmp.S - EABI cfcmp* implementation ------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__\n#error big endian support not implemented\n#endif\n\n#define APSR_Z (1 << 30)\n#define APSR_C (1 << 29)\n\n// void __aeabi_cfcmpeq(float a, float b) {\n//   if (isnan(a) || isnan(b)) {\n//     Z = 0; C = 1;\n//   } else {\n//     __aeabi_cfcmple(a, b);\n//   }\n// }\n\n        .syntax unified\n        .p2align 2\nDEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)\n        push {r0-r3, lr}\n        bl __aeabi_cfcmpeq_check_nan\n        cmp r0, #1\n        pop {r0-r3, lr}\n\n        // NaN has been ruled out, so __aeabi_cfcmple can't trap\n        bne __aeabi_cfcmple\n\n        msr CPSR_f, #APSR_C\n        JMP(lr)\nEND_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)\n\n\n// void __aeabi_cfcmple(float a, float b) {\n//   if (__aeabi_fcmplt(a, b)) {\n//     Z = 0; C = 0;\n//   } else if (__aeabi_fcmpeq(a, b)) {\n//     Z = 1; C = 1;\n//   } else {\n//     Z = 0; C = 1;\n//   }\n// }\n\n        .syntax unified\n        .p2align 2\nDEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmple)\n        // Per the RTABI, this function must preserve r0-r11.\n        // Save lr in the same instruction for compactness\n        push {r0-r3, lr}\n\n        bl __aeabi_fcmplt\n        cmp r0, #1\n        moveq ip, #0\n        beq 1f\n\n        ldm sp, {r0-r3}\n        bl __aeabi_fcmpeq\n        cmp r0, #1\n        moveq ip, #(APSR_C | APSR_Z)\n        movne ip, #(APSR_C)\n\n1:\n        msr CPSR_f, ip\n        pop {r0-r3}\n        POP_PC()\nEND_COMPILERRT_FUNCTION(__aeabi_cfcmple)\n\n// int __aeabi_cfrcmple(float a, float b) {\n//   return __aeabi_cfcmple(b, a);\n// }\n\n        .syntax unified\n        .p2align 2\nDEFINE_COMPILERRT_FUNCTION(__aeabi_cfrcmple)\n        // Swap r0 and r1\n        mov ip, r0\n        mov r0, r1\n        mov r1, ip\n\n        b __aeabi_cfcmple\nEND_COMPILERRT_FUNCTION(__aeabi_cfrcmple)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_cfcmpeq_check_nan.c",
    "content": "//===-- lib/arm/aeabi_cfcmpeq_helper.c - Helper for cdcmpeq ---------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stdint.h>\n\n__attribute__((pcs(\"aapcs\")))\n__attribute__((visibility(\"hidden\")))\nint __aeabi_cfcmpeq_check_nan(float a, float b) {\n    return __builtin_isnan(a) || __builtin_isnan(b);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_dcmp.S",
    "content": "//===-- aeabi_dcmp.S - EABI dcmp* implementation ---------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n// int __aeabi_dcmp{eq,lt,le,ge,gt}(double a, double b) {\n//   int result = __{eq,lt,le,ge,gt}df2(a, b);\n//   if (result {==,<,<=,>=,>} 0) {\n//     return 1;\n//   } else {\n//     return 0;\n//   }\n// }\n\n#define DEFINE_AEABI_DCMP(cond)                            \\\n        .syntax unified                          SEPARATOR \\\n        .p2align 2                               SEPARATOR \\\nDEFINE_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond)           \\\n        push      { r4, lr }                     SEPARATOR \\\n        bl        SYMBOL_NAME(__ ## cond ## df2) SEPARATOR \\\n        cmp       r0, #0                         SEPARATOR \\\n        b ## cond 1f                             SEPARATOR \\\n        mov       r0, #0                         SEPARATOR \\\n        pop       { r4, pc }                     SEPARATOR \\\n1:                                               SEPARATOR \\\n        mov       r0, #1                         SEPARATOR \\\n        pop       { r4, pc }                     SEPARATOR \\\nEND_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond)\n\nDEFINE_AEABI_DCMP(eq)\nDEFINE_AEABI_DCMP(lt)\nDEFINE_AEABI_DCMP(le)\nDEFINE_AEABI_DCMP(ge)\nDEFINE_AEABI_DCMP(gt)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_div0.c",
    "content": "/* ===-- aeabi_div0.c - ARM Runtime ABI support routines for compiler-rt ---===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements the division by zero helper routines as specified by the\n * Run-time ABI for the ARM Architecture.\n *\n * ===----------------------------------------------------------------------===\n */\n\n/*\n * RTABI 4.3.2 - Division by zero\n *\n * The *div0 functions:\n * - Return the value passed to them as a parameter\n * - Or, return a fixed value defined by the execution environment (such as 0)\n * - Or, raise a signal (often SIGFPE) or throw an exception, and do not return\n *\n * An application may provide its own implementations of the *div0 functions to\n * for a particular behaviour from the *div and *divmod functions called out of\n * line.\n */\n\n/* provide an unused declaration to pacify pendantic compilation */\nextern unsigned char declaration;\n\n#if defined(__ARM_EABI__)\nint __attribute__((weak)) __attribute__((visibility(\"hidden\")))\n__aeabi_idiv0(int return_value) {\n  return return_value;\n}\n\nlong long __attribute__((weak)) __attribute__((visibility(\"hidden\")))\n__aeabi_ldiv0(long long return_value) {\n  return return_value;\n}\n#endif\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_drsub.c",
    "content": "//===-- lib/arm/aeabi_drsub.c - Double-precision subtraction --------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define DOUBLE_PRECISION\n#include \"../fp_lib.h\"\n\nCOMPILER_RT_ABI fp_t\n__aeabi_dsub(fp_t, fp_t);\n\nCOMPILER_RT_ABI fp_t\n__aeabi_drsub(fp_t a, fp_t b) {\n    return __aeabi_dsub(b, a);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_fcmp.S",
    "content": "//===-- aeabi_fcmp.S - EABI fcmp* implementation ---------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n// int __aeabi_fcmp{eq,lt,le,ge,gt}(float a, float b) {\n//   int result = __{eq,lt,le,ge,gt}sf2(a, b);\n//   if (result {==,<,<=,>=,>} 0) {\n//     return 1;\n//   } else {\n//     return 0;\n//   }\n// }\n\n#define DEFINE_AEABI_FCMP(cond)                            \\\n        .syntax unified                          SEPARATOR \\\n        .p2align 2                               SEPARATOR \\\nDEFINE_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond)           \\\n        push      { r4, lr }                     SEPARATOR \\\n        bl        SYMBOL_NAME(__ ## cond ## sf2) SEPARATOR \\\n        cmp       r0, #0                         SEPARATOR \\\n        b ## cond 1f                             SEPARATOR \\\n        mov       r0, #0                         SEPARATOR \\\n        pop       { r4, pc }                     SEPARATOR \\\n1:                                               SEPARATOR \\\n        mov       r0, #1                         SEPARATOR \\\n        pop       { r4, pc }                     SEPARATOR \\\nEND_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond)\n\nDEFINE_AEABI_FCMP(eq)\nDEFINE_AEABI_FCMP(lt)\nDEFINE_AEABI_FCMP(le)\nDEFINE_AEABI_FCMP(ge)\nDEFINE_AEABI_FCMP(gt)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_frsub.c",
    "content": "//===-- lib/arm/aeabi_frsub.c - Single-precision subtraction --------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define SINGLE_PRECISION\n#include \"../fp_lib.h\"\n\nCOMPILER_RT_ABI fp_t\n__aeabi_fsub(fp_t, fp_t);\n\nCOMPILER_RT_ABI fp_t\n__aeabi_frsub(fp_t a, fp_t b) {\n    return __aeabi_fsub(b, a);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_idivmod.S",
    "content": "//===-- aeabi_idivmod.S - EABI idivmod implementation ---------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n// struct { int quot, int rem} __aeabi_idivmod(int numerator, int denominator) {\n//   int rem, quot;\n//   quot = __divmodsi4(numerator, denominator, &rem);\n//   return {quot, rem};\n// }\n\n        .syntax unified\n        .p2align 2\nDEFINE_COMPILERRT_FUNCTION(__aeabi_idivmod)\n        push    { lr }\n        sub     sp, sp, #4\n        mov     r2, sp\n        bl      SYMBOL_NAME(__divmodsi4)\n        ldr     r1, [sp]\n        add     sp, sp, #4\n        pop     { pc }\nEND_COMPILERRT_FUNCTION(__aeabi_idivmod)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_ldivmod.S",
    "content": "//===-- aeabi_ldivmod.S - EABI ldivmod implementation ---------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n// struct { int64_t quot, int64_t rem}\n//        __aeabi_ldivmod(int64_t numerator, int64_t denominator) {\n//   int64_t rem, quot;\n//   quot = __divmoddi4(numerator, denominator, &rem);\n//   return {quot, rem};\n// }\n\n        .syntax unified\n        .p2align 2\nDEFINE_COMPILERRT_FUNCTION(__aeabi_ldivmod)\n        push    {r11, lr}\n        sub     sp, sp, #16\n        add     r12, sp, #8\n        str     r12, [sp]\n        bl      SYMBOL_NAME(__divmoddi4)\n        ldr     r2, [sp, #8]\n        ldr     r3, [sp, #12]\n        add     sp, sp, #16\n        pop     {r11, pc}\nEND_COMPILERRT_FUNCTION(__aeabi_ldivmod)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_memcmp.S",
    "content": "//===-- aeabi_memcmp.S - EABI memcmp implementation -----------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//  void __aeabi_memcmp(void *dest, void *src, size_t n) { memcmp(dest, src, n); }\n\n        .p2align 2\nDEFINE_COMPILERRT_FUNCTION(__aeabi_memcmp)\n        b       memcmp\nEND_COMPILERRT_FUNCTION(__aeabi_memcmp)\n\nDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp4, __aeabi_memcmp)\nDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp8, __aeabi_memcmp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_memcpy.S",
    "content": "//===-- aeabi_memcpy.S - EABI memcpy implementation -----------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//  void __aeabi_memcpy(void *dest, void *src, size_t n) { memcpy(dest, src, n); }\n\n        .p2align 2\nDEFINE_COMPILERRT_FUNCTION(__aeabi_memcpy)\n        b       memcpy\nEND_COMPILERRT_FUNCTION(__aeabi_memcpy)\n\nDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy4, __aeabi_memcpy)\nDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy8, __aeabi_memcpy)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_memmove.S",
    "content": "//===-- aeabi_memmove.S - EABI memmove implementation --------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===---------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//  void __aeabi_memmove(void *dest, void *src, size_t n) { memmove(dest, src, n); }\n\n        .p2align 2\nDEFINE_COMPILERRT_FUNCTION(__aeabi_memmove)\n        b       memmove\nEND_COMPILERRT_FUNCTION(__aeabi_memmove)\n\nDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove4, __aeabi_memmove)\nDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove8, __aeabi_memmove)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_memset.S",
    "content": "//===-- aeabi_memset.S - EABI memset implementation -----------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//  void __aeabi_memset(void *dest, size_t n, int c) { memset(dest, c, n); }\n//  void __aeabi_memclr(void *dest, size_t n) { __aeabi_memset(dest, n, 0); }\n\n        .p2align 2\nDEFINE_COMPILERRT_FUNCTION(__aeabi_memset)\n        mov     r3, r1\n        mov     r1, r2\n        mov     r2, r3\n        b       memset\nEND_COMPILERRT_FUNCTION(__aeabi_memset)\n\nDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset4, __aeabi_memset)\nDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset8, __aeabi_memset)\n\nDEFINE_COMPILERRT_FUNCTION(__aeabi_memclr)\n        mov     r2, r1\n        mov     r1, #0\n        b       memset\nEND_COMPILERRT_FUNCTION(__aeabi_memclr)\n\nDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr4, __aeabi_memclr)\nDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr8, __aeabi_memclr)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_uidivmod.S",
    "content": "//===-- aeabi_uidivmod.S - EABI uidivmod implementation -------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n// struct { unsigned quot, unsigned rem}\n//        __aeabi_uidivmod(unsigned numerator, unsigned denominator) {\n//   unsigned rem, quot;\n//   quot = __udivmodsi4(numerator, denominator, &rem);\n//   return {quot, rem};\n// }\n\n        .syntax unified\n        .p2align 2\nDEFINE_COMPILERRT_FUNCTION(__aeabi_uidivmod)\n        push    { lr }\n        sub     sp, sp, #4\n        mov     r2, sp\n        bl      SYMBOL_NAME(__udivmodsi4)\n        ldr     r1, [sp]\n        add     sp, sp, #4\n        pop     { pc }\nEND_COMPILERRT_FUNCTION(__aeabi_uidivmod)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/aeabi_uldivmod.S",
    "content": "//===-- aeabi_uldivmod.S - EABI uldivmod implementation -------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n// struct { uint64_t quot, uint64_t rem}\n//        __aeabi_uldivmod(uint64_t numerator, uint64_t denominator) {\n//   uint64_t rem, quot;\n//   quot = __udivmoddi4(numerator, denominator, &rem);\n//   return {quot, rem};\n// }\n\n        .syntax unified\n        .p2align 2\nDEFINE_COMPILERRT_FUNCTION(__aeabi_uldivmod)\n        push\t{r11, lr}\n        sub\tsp, sp, #16\n        add\tr12, sp, #8\n        str\tr12, [sp]\n        bl\tSYMBOL_NAME(__udivmoddi4)\n        ldr\tr2, [sp, #8]\n        ldr\tr3, [sp, #12]\n        add\tsp, sp, #16\n        pop\t{r11, pc}\nEND_COMPILERRT_FUNCTION(__aeabi_uldivmod)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/bswapdi2.S",
    "content": "//===------- bswapdi2 - Implement bswapdi2 --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n\t.syntax unified\n\t.text\n#if __ARM_ARCH_ISA_THUMB == 2\n\t.thumb\n#endif\n\n//\n// extern uint64_t __bswapdi2(uint64_t);\n//\n// Reverse all the bytes in a 64-bit integer.\n//\n\t.p2align 2\n#if __ARM_ARCH_ISA_THUMB == 2\nDEFINE_COMPILERRT_THUMB_FUNCTION(__bswapdi2)\n#else\nDEFINE_COMPILERRT_FUNCTION(__bswapdi2)\n#endif\n#if __ARM_ARCH < 6\n    // before armv6 does not have \"rev\" instruction\n    // r2 = rev(r0)\n    eor r2, r0, r0, ror #16\n    bic r2, r2, #0xff0000\n    mov r2, r2, lsr #8\n    eor r2, r2, r0, ror #8\n    // r0 = rev(r1)\n    eor r0, r1, r1, ror #16\n    bic r0, r0, #0xff0000\n    mov r0, r0, lsr #8\n    eor r0, r0, r1, ror #8\n#else\n    rev r2, r0  // r2 = rev(r0)\n    rev r0, r1  // r0 = rev(r1)\n#endif\n    mov r1, r2  // r1 = r2 = rev(r0)\n    JMP(lr)\nEND_COMPILERRT_FUNCTION(__bswapdi2)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/bswapsi2.S",
    "content": "//===------- bswapsi2 - Implement bswapsi2 --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n\t.syntax unified\n\t.text\n#if __ARM_ARCH_ISA_THUMB == 2\n\t.thumb\n#endif\n\n//\n// extern uint32_t __bswapsi2(uint32_t);\n//\n// Reverse all the bytes in a 32-bit integer.\n//\n\t.p2align 2\n#if __ARM_ARCH_ISA_THUMB == 2\nDEFINE_COMPILERRT_THUMB_FUNCTION(__bswapsi2)\n#else\nDEFINE_COMPILERRT_FUNCTION(__bswapsi2)\n#endif\n#if __ARM_ARCH < 6\n    // before armv6 does not have \"rev\" instruction\n \teor\tr1, r0, r0, ror #16\n \tbic\tr1, r1, #0xff0000\n \tmov\tr1, r1, lsr #8\n \teor\tr0, r1, r0, ror #8\n#else\n    rev r0, r0\n#endif\n    JMP(lr)\nEND_COMPILERRT_FUNCTION(__bswapsi2)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/clzdi2.S",
    "content": "/* ===-- clzdi2.c - Implement __clzdi2 -------------------------------------===\n *\n *               The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements count leading zeros for 64bit arguments.\n *\n * ===----------------------------------------------------------------------===\n */\n#include \"../assembly.h\"\n\n\t.syntax unified\n\t.text\n#if __ARM_ARCH_ISA_THUMB == 2\n\t.thumb\n#endif\n\n\n\t.p2align\t2\n#if __ARM_ARCH_ISA_THUMB == 2\nDEFINE_COMPILERRT_THUMB_FUNCTION(__clzdi2)\n#else\nDEFINE_COMPILERRT_FUNCTION(__clzdi2)\n#endif\n#ifdef __ARM_FEATURE_CLZ\n#ifdef __ARMEB__\n\tcmp\tr0, 0\n\titee ne\n\tclzne\tr0, r0\n\tclzeq\tr0, r1\n\taddeq\tr0, r0, 32\n#else\n\tcmp\tr1, 0\n\titee ne\n\tclzne\tr0, r1\n\tclzeq\tr0, r0\n\taddeq\tr0, r0, 32\n#endif\n\tJMP(lr)\n#else\n\t/* Assumption: n != 0 */\n\n\t/*\n\t * r0: n\n\t * r1: upper half of n, overwritten after check\n\t * r1: count of leading zeros in n + 1\n\t * r2: scratch register for shifted r0\n\t */\n#ifdef __ARMEB__\n\tcmp\tr0, 0\n\tmoveq\tr0, r1\n#else\n\tcmp\tr1, 0\n\tmovne\tr0, r1\n#endif\n\tmovne\tr1, 1\n\tmoveq\tr1, 33\n\n\t/*\n\t * Basic block:\n\t * if ((r0 >> SHIFT) == 0)\n\t *   r1 += SHIFT;\n\t * else\n\t *   r0 >>= SHIFT;\n\t * for descending powers of two as SHIFT.\n\t */\n#define BLOCK(shift) \\\n\tlsrs\tr2, r0, shift; \\\n\tmovne\tr0, r2; \\\n\taddeq\tr1, shift \\\n\n\tBLOCK(16)\n\tBLOCK(8)\n\tBLOCK(4)\n\tBLOCK(2)\n\n\t/*\n\t * The basic block invariants at this point are (r0 >> 2) == 0 and\n\t * r0 != 0. This means 1 <= r0 <= 3 and 0 <= (r0 >> 1) <= 1.\n\t *\n\t * r0 | (r0 >> 1) == 0 | (r0 >> 1) == 1 | -(r0 >> 1) | 1 - (r0 >> 1)\n\t * ---+----------------+----------------+------------+--------------\n\t * 1  | 1              | 0              | 0          | 1\n\t * 2  | 0              | 1              | -1         | 0\n\t * 3  | 0              | 1              | -1         | 0\n\t *\n\t * The r1's initial value of 1 compensates for the 1 here.\n\t */\n\tsub\tr0, r1, r0, lsr #1\n\n\tJMP(lr)\n#endif // __ARM_FEATURE_CLZ\nEND_COMPILERRT_FUNCTION(__clzdi2)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/clzsi2.S",
    "content": "/* ===-- clzsi2.c - Implement __clzsi2 -------------------------------------===\n *\n *               The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements count leading zeros for 32bit arguments.\n *\n * ===----------------------------------------------------------------------===\n */\n#include \"../assembly.h\"\n\n\t.syntax unified\n\t.text\n#if __ARM_ARCH_ISA_THUMB == 2\n\t.thumb\n#endif\n\n\t.p2align\t2\n#if __ARM_ARCH_ISA_THUMB == 2\nDEFINE_COMPILERRT_THUMB_FUNCTION(__clzsi2)\n#else\nDEFINE_COMPILERRT_FUNCTION(__clzsi2)\n#endif\n#ifdef __ARM_FEATURE_CLZ\n\tclz\tr0, r0\n\tJMP(lr)\n#else\n\t/* Assumption: n != 0 */\n\n\t/*\n\t * r0: n\n\t * r1: count of leading zeros in n + 1\n\t * r2: scratch register for shifted r0\n\t */\n\tmov\tr1, 1\n\n\t/*\n\t * Basic block:\n\t * if ((r0 >> SHIFT) == 0)\n\t *   r1 += SHIFT;\n\t * else\n\t *   r0 >>= SHIFT;\n\t * for descending powers of two as SHIFT.\n\t */\n\n#define BLOCK(shift) \\\n\tlsrs\tr2, r0, shift; \\\n\tmovne\tr0, r2; \\\n\taddeq\tr1, shift \\\n\n\tBLOCK(16)\n\tBLOCK(8)\n\tBLOCK(4)\n\tBLOCK(2)\n\n\t/*\n\t * The basic block invariants at this point are (r0 >> 2) == 0 and\n\t * r0 != 0. This means 1 <= r0 <= 3 and 0 <= (r0 >> 1) <= 1.\n\t *\n\t * r0 | (r0 >> 1) == 0 | (r0 >> 1) == 1 | -(r0 >> 1) | 1 - (r0 >> 1)\n\t * ---+----------------+----------------+------------+--------------\n\t * 1  | 1              | 0              | 0          | 1\n\t * 2  | 0              | 1              | -1         | 0\n\t * 3  | 0              | 1              | -1         | 0\n\t *\n\t * The r1's initial value of 1 compensates for the 1 here.\n\t */\n\tsub\tr0, r1, r0, lsr #1\n\n\tJMP(lr)\n#endif // __ARM_FEATURE_CLZ\nEND_COMPILERRT_FUNCTION(__clzsi2)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/comparesf2.S",
    "content": "//===-- comparesf2.S - Implement single-precision soft-float comparisons --===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements the following soft-fp_t comparison routines:\n//\n//   __eqsf2   __gesf2   __unordsf2\n//   __lesf2   __gtsf2\n//   __ltsf2\n//   __nesf2\n//\n// The semantics of the routines grouped in each column are identical, so there\n// is a single implementation for each, with multiple names.\n//\n// The routines behave as follows:\n//\n//   __lesf2(a,b) returns -1 if a < b\n//                         0 if a == b\n//                         1 if a > b\n//                         1 if either a or b is NaN\n//\n//   __gesf2(a,b) returns -1 if a < b\n//                         0 if a == b\n//                         1 if a > b\n//                        -1 if either a or b is NaN\n//\n//   __unordsf2(a,b) returns 0 if both a and b are numbers\n//                           1 if either a or b is NaN\n//\n// Note that __lesf2( ) and __gesf2( ) are identical except in their handling of\n// NaN values.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n.syntax unified\n\n.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__eqsf2)\n    // Make copies of a and b with the sign bit shifted off the top.  These will\n    // be used to detect zeros and NaNs.\n    mov     r2,         r0, lsl #1\n    mov     r3,         r1, lsl #1\n\n    // We do the comparison in three stages (ignoring NaN values for the time\n    // being).  First, we orr the absolute values of a and b; this sets the Z\n    // flag if both a and b are zero (of either sign).  The shift of r3 doesn't\n    // effect this at all, but it *does* make sure that the C flag is clear for\n    // the subsequent operations.\n    orrs    r12,    r2, r3, lsr #1\n\n    // Next, we check if a and b have the same or different signs.  If they have\n    // opposite signs, this eor will set the N flag.\n    it ne\n    eorsne  r12,    r0, r1\n\n    // If a and b are equal (either both zeros or bit identical; again, we're\n    // ignoring NaNs for now), this subtract will zero out r0.  If they have the\n    // same sign, the flags are updated as they would be for a comparison of the\n    // absolute values of a and b.\n    it pl\n    subspl  r0,     r2, r3\n\n    // If a is smaller in magnitude than b and both have the same sign, place\n    // the negation of the sign of b in r0.  Thus, if both are negative and\n    // a > b, this sets r0 to 0; if both are positive and a < b, this sets\n    // r0 to -1.\n    //\n    // This is also done if a and b have opposite signs and are not both zero,\n    // because in that case the subtract was not performed and the C flag is\n    // still clear from the shift argument in orrs; if a is positive and b\n    // negative, this places 0 in r0; if a is negative and b positive, -1 is\n    // placed in r0.\n    it lo\n    mvnlo   r0,         r1, asr #31\n\n    // If a is greater in magnitude than b and both have the same sign, place\n    // the sign of b in r0.  Thus, if both are negative and a < b, -1 is placed\n    // in r0, which is the desired result.  Conversely, if both are positive\n    // and a > b, zero is placed in r0.\n    it hi\n    movhi   r0,         r1, asr #31\n\n    // If you've been keeping track, at this point r0 contains -1 if a < b and\n    // 0 if a >= b.  All that remains to be done is to set it to 1 if a > b.\n    // If a == b, then the Z flag is set, so we can get the correct final value\n    // into r0 by simply or'ing with 1 if Z is clear.\n    it ne\n    orrne   r0,     r0, #1\n\n    // Finally, we need to deal with NaNs.  If either argument is NaN, replace\n    // the value in r0 with 1.\n    cmp     r2,         #0xff000000\n    ite ls\n    cmpls   r3,         #0xff000000\n    movhi   r0,         #1\n    JMP(lr)\nEND_COMPILERRT_FUNCTION(__eqsf2)\nDEFINE_COMPILERRT_FUNCTION_ALIAS(__lesf2, __eqsf2)\nDEFINE_COMPILERRT_FUNCTION_ALIAS(__ltsf2, __eqsf2)\nDEFINE_COMPILERRT_FUNCTION_ALIAS(__nesf2, __eqsf2)\n\n.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__gtsf2)\n    // Identical to the preceding except in that we return -1 for NaN values.\n    // Given that the two paths share so much code, one might be tempted to \n    // unify them; however, the extra code needed to do so makes the code size\n    // to performance tradeoff very hard to justify for such small functions.\n    mov     r2,         r0, lsl #1\n    mov     r3,         r1, lsl #1\n    orrs    r12,    r2, r3, lsr #1\n    it ne\n    eorsne  r12,    r0, r1\n    it pl\n    subspl  r0,     r2, r3\n    it lo\n    mvnlo   r0,         r1, asr #31\n    it hi\n    movhi   r0,         r1, asr #31\n    it ne\n    orrne   r0,     r0, #1\n    cmp     r2,         #0xff000000\n    ite ls\n    cmpls   r3,         #0xff000000\n    movhi   r0,         #-1\n    JMP(lr)\nEND_COMPILERRT_FUNCTION(__gtsf2)\nDEFINE_COMPILERRT_FUNCTION_ALIAS(__gesf2, __gtsf2)\n\n.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__unordsf2)\n    // Return 1 for NaN values, 0 otherwise.\n    mov     r2,         r0, lsl #1\n    mov     r3,         r1, lsl #1\n    mov     r0,         #0\n    cmp     r2,         #0xff000000\n    ite ls\n    cmpls   r3,         #0xff000000\n    movhi   r0,         #1\n    JMP(lr)\nEND_COMPILERRT_FUNCTION(__unordsf2)\n\nDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_fcmpun, __unordsf2)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/divdf3vfp.S",
    "content": "//===-- divdf3vfp.S - Implement divdf3vfp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern double __divdf3vfp(double a, double b);\n//\n// Divides two double precision floating point numbers using the Darwin\n// calling convention where double arguments are passsed in GPR pairs\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__divdf3vfp)\n\tvmov\td6, r0, r1\t\t// move first param from r0/r1 pair into d6\n\tvmov\td7, r2, r3\t\t// move second param from r2/r3 pair into d7\n\tvdiv.f64 d5, d6, d7\t\t\n\tvmov\tr0, r1, d5\t\t// move result back to r0/r1 pair\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__divdf3vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/divmodsi4.S",
    "content": "/*===-- divmodsi4.S - 32-bit signed integer divide and modulus ------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __divmodsi4 (32-bit signed integer divide and\n * modulus) function for the ARM architecture.  A naive digit-by-digit\n * computation is employed for simplicity.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"../assembly.h\"\n\n#define ESTABLISH_FRAME    \\\n    push   {r4-r7, lr}   ;\\\n    add     r7,     sp, #12\n#define CLEAR_FRAME_AND_RETURN \\\n    pop    {r4-r7, pc}\n\n\t.syntax unified\n\t.text\n#if __ARM_ARCH_ISA_THUMB == 2\n\t.thumb\n#endif\n\n@ int __divmodsi4(int divident, int divisor, int *remainder)\n@   Calculate the quotient and remainder of the (signed) division.  The return\n@   value is the quotient, the remainder is placed in the variable.\n\n\t.p2align 3\n#if __ARM_ARCH_ISA_THUMB == 2\nDEFINE_COMPILERRT_THUMB_FUNCTION(__divmodsi4)\n#else\nDEFINE_COMPILERRT_FUNCTION(__divmodsi4)\n#endif\n#if __ARM_ARCH_EXT_IDIV__\n\ttst     r1, r1\n\tbeq     LOCAL_LABEL(divzero)\n\tmov \tr3, r0\n\tsdiv\tr0, r3, r1\n\tmls \tr1, r0, r1, r3\n\tstr \tr1, [r2]\n\tbx  \tlr\nLOCAL_LABEL(divzero):\n\tmov     r0, #0\n\tbx      lr\n#else\n    ESTABLISH_FRAME\n//  Set aside the sign of the quotient and modulus, and the address for the\n//  modulus.\n    eor     r4,     r0, r1\n    mov     r5,     r0\n    mov     r6,     r2\n//  Take the absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).\n    eor     ip,     r0, r0, asr #31\n    eor     lr,     r1, r1, asr #31\n    sub     r0,     ip, r0, asr #31\n    sub     r1,     lr, r1, asr #31\n//  Unsigned divmod:\n    bl      SYMBOL_NAME(__udivmodsi4)\n//  Apply the sign of quotient and modulus\n    ldr     r1,    [r6]\n    eor     r0,     r0, r4, asr #31\n    eor     r1,     r1, r5, asr #31\n    sub     r0,     r0, r4, asr #31\n    sub     r1,     r1, r5, asr #31\n    str     r1,    [r6]\n    CLEAR_FRAME_AND_RETURN\n#endif\nEND_COMPILERRT_FUNCTION(__divmodsi4)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/divsf3vfp.S",
    "content": "//===-- divsf3vfp.S - Implement divsf3vfp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern float __divsf3vfp(float a, float b);\n//\n// Divides two single precision floating point numbers using the Darwin\n// calling convention where single arguments are passsed like 32-bit ints.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__divsf3vfp)\n\tvmov\ts14, r0\t\t// move first param from r0 into float register\n\tvmov\ts15, r1\t\t// move second param from r1 into float register\n\tvdiv.f32 s13, s14, s15\n\tvmov\tr0, s13\t\t// move result back to r0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__divsf3vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/divsi3.S",
    "content": "/*===-- divsi3.S - 32-bit signed integer divide ---------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __divsi3 (32-bit signed integer divide) function\n * for the ARM architecture as a wrapper around the unsigned routine.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"../assembly.h\"\n\n#define ESTABLISH_FRAME \\\n    push   {r4, r7, lr}    ;\\\n    add     r7,     sp, #4\n#define CLEAR_FRAME_AND_RETURN \\\n    pop    {r4, r7, pc}\n\n\t.syntax unified\n\t.text\n#if __ARM_ARCH_ISA_THUMB == 2\n\t.thumb\n#endif\n\n\t.p2align 3\n// Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine.\nDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_idiv, __divsi3)\n\n@ int __divsi3(int divident, int divisor)\n@   Calculate and return the quotient of the (signed) division.\n\n#if __ARM_ARCH_ISA_THUMB == 2\nDEFINE_COMPILERRT_THUMB_FUNCTION(__divsi3)\n#else\nDEFINE_COMPILERRT_FUNCTION(__divsi3)\n#endif\n#if __ARM_ARCH_EXT_IDIV__\n   tst     r1,r1\n   beq     LOCAL_LABEL(divzero)\n   sdiv    r0, r0, r1\n   bx      lr\nLOCAL_LABEL(divzero):\n   mov     r0,#0\n   bx      lr\n#else\nESTABLISH_FRAME\n//  Set aside the sign of the quotient.\n    eor     r4,     r0, r1\n//  Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).\n    eor     r2,     r0, r0, asr #31\n    eor     r3,     r1, r1, asr #31\n    sub     r0,     r2, r0, asr #31\n    sub     r1,     r3, r1, asr #31\n//  abs(a) / abs(b)\n    bl      SYMBOL_NAME(__udivsi3)\n//  Apply sign of quotient to result and return.\n    eor     r0,     r0, r4, asr #31\n    sub     r0,     r0, r4, asr #31\n    CLEAR_FRAME_AND_RETURN\n#endif\nEND_COMPILERRT_FUNCTION(__divsi3)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/eqdf2vfp.S",
    "content": "//===-- eqdf2vfp.S - Implement eqdf2vfp -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern int __eqdf2vfp(double a, double b);\n//\n// Returns one iff a == b and neither is NaN.\n// Uses Darwin calling convention where double precision arguments are passsed \n// like in GPR pairs.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__eqdf2vfp)\n\tvmov\td6, r0, r1\t// load r0/r1 pair in double register\n\tvmov\td7, r2, r3\t// load r2/r3 pair in double register\n\tvcmp.f64 d6, d7\t\t\n\tvmrs\tapsr_nzcv, fpscr\n\tmoveq\tr0, #1\t\t// set result register to 1 if equal\n\tmovne\tr0, #0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__eqdf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/eqsf2vfp.S",
    "content": "//===-- eqsf2vfp.S - Implement eqsf2vfp -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern int __eqsf2vfp(float a, float b);\n//\n// Returns one iff a == b and neither is NaN.\n// Uses Darwin calling convention where single precision arguments are passsed \n// like 32-bit ints\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__eqsf2vfp)\n\tvmov\ts14, r0     // move from GPR 0 to float register\n\tvmov\ts15, r1\t    // move from GPR 1 to float register\n\tvcmp.f32 s14, s15\n\tvmrs\tapsr_nzcv, fpscr\n\tmoveq\tr0, #1      // set result register to 1 if equal\n\tmovne\tr0, #0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__eqsf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/extendsfdf2vfp.S",
    "content": "//===-- extendsfdf2vfp.S - Implement extendsfdf2vfp -----------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern double __extendsfdf2vfp(float a);\n//\n// Converts single precision float to double precision result.\n// Uses Darwin calling convention where a single precision parameter is \n// passed in a GPR and a double precision result is returned in R0/R1 pair.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__extendsfdf2vfp)\n\tvmov\ts15, r0      // load float register from R0\n\tvcvt.f64.f32 d7, s15 // convert single to double\n\tvmov\tr0, r1, d7   // return result in r0/r1 pair\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__extendsfdf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/fixdfsivfp.S",
    "content": "//===-- fixdfsivfp.S - Implement fixdfsivfp -----------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern int __fixdfsivfp(double a);\n//\n// Converts double precision float to a 32-bit int rounding towards zero.\n// Uses Darwin calling convention where a double precision parameter is \n// passed in GPR register pair.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__fixdfsivfp)\n\tvmov\td7, r0, r1    // load double register from R0/R1\n\tvcvt.s32.f64 s15, d7  // convert double to 32-bit int into s15\n\tvmov\tr0, s15\t      // move s15 to result register\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__fixdfsivfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/fixsfsivfp.S",
    "content": "//===-- fixsfsivfp.S - Implement fixsfsivfp -----------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern int __fixsfsivfp(float a);\n//\n// Converts single precision float to a 32-bit int rounding towards zero.\n// Uses Darwin calling convention where a single precision parameter is \n// passed in a GPR..\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__fixsfsivfp)\n\tvmov\ts15, r0        // load float register from R0\n\tvcvt.s32.f32 s15, s15  // convert single to 32-bit int into s15\n\tvmov\tr0, s15\t       // move s15 to result register\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__fixsfsivfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/fixunsdfsivfp.S",
    "content": "//===-- fixunsdfsivfp.S - Implement fixunsdfsivfp -------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern unsigned int __fixunsdfsivfp(double a);\n//\n// Converts double precision float to a 32-bit unsigned int rounding towards \n// zero. All negative values become zero.\n// Uses Darwin calling convention where a double precision parameter is \n// passed in GPR register pair.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__fixunsdfsivfp)\n\tvmov\td7, r0, r1    // load double register from R0/R1\n\tvcvt.u32.f64 s15, d7  // convert double to 32-bit int into s15\n\tvmov\tr0, s15\t      // move s15 to result register\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__fixunsdfsivfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/fixunssfsivfp.S",
    "content": "//===-- fixunssfsivfp.S - Implement fixunssfsivfp -------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern unsigned int __fixunssfsivfp(float a);\n//\n// Converts single precision float to a 32-bit unsigned int rounding towards \n// zero. All negative values become zero.\n// Uses Darwin calling convention where a single precision parameter is \n// passed in a GPR..\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__fixunssfsivfp)\n\tvmov\ts15, r0        // load float register from R0\n\tvcvt.u32.f32 s15, s15  // convert single to 32-bit unsigned into s15\n\tvmov\tr0, s15\t       // move s15 to result register\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__fixunssfsivfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/floatsidfvfp.S",
    "content": "//===-- floatsidfvfp.S - Implement floatsidfvfp ---------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern double __floatsidfvfp(int a);\n//\n// Converts a 32-bit int to a double precision float.\n// Uses Darwin calling convention where a double precision result is \n// return in GPR register pair.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__floatsidfvfp)\n\tvmov\ts15, r0        // move int to float register s15\n\tvcvt.f64.s32 d7, s15   // convert 32-bit int in s15 to double in d7\n\tvmov\tr0, r1, d7     // move d7 to result register pair r0/r1\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__floatsidfvfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/floatsisfvfp.S",
    "content": "//===-- floatsisfvfp.S - Implement floatsisfvfp ---------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern float __floatsisfvfp(int a);\n//\n// Converts single precision float to a 32-bit int rounding towards zero.\n// Uses Darwin calling convention where a single precision result is \n// return in a GPR..\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__floatsisfvfp)\n\tvmov\ts15, r0\t       // move int to float register s15\n\tvcvt.f32.s32 s15, s15  // convert 32-bit int in s15 to float in s15\n\tvmov\tr0, s15        // move s15 to result register\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__floatsisfvfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/floatunssidfvfp.S",
    "content": "//===-- floatunssidfvfp.S - Implement floatunssidfvfp ---------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern double __floatunssidfvfp(unsigned int a);\n//\n// Converts a 32-bit int to a double precision float.\n// Uses Darwin calling convention where a double precision result is \n// return in GPR register pair.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__floatunssidfvfp)\n\tvmov\ts15, r0        // move int to float register s15\n\tvcvt.f64.u32 d7, s15   // convert 32-bit int in s15 to double in d7\n\tvmov\tr0, r1, d7     // move d7 to result register pair r0/r1\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__floatunssidfvfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/floatunssisfvfp.S",
    "content": "//===-- floatunssisfvfp.S - Implement floatunssisfvfp ---------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern float __floatunssisfvfp(unsigned int a);\n//\n// Converts single precision float to a 32-bit int rounding towards zero.\n// Uses Darwin calling convention where a single precision result is \n// return in a GPR..\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__floatunssisfvfp)\n\tvmov\ts15, r0\t       // move int to float register s15\n\tvcvt.f32.u32 s15, s15  // convert 32-bit int in s15 to float in s15\n\tvmov\tr0, s15        // move s15 to result register\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__floatunssisfvfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/gedf2vfp.S",
    "content": "//===-- gedf2vfp.S - Implement gedf2vfp -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern int __gedf2vfp(double a, double b);\n//\n// Returns one iff a >= b and neither is NaN.\n// Uses Darwin calling convention where double precision arguments are passsed \n// like in GPR pairs.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__gedf2vfp)\n\tvmov \td6, r0, r1\t// load r0/r1 pair in double register\n\tvmov \td7, r2, r3\t// load r2/r3 pair in double register\n\tvcmp.f64 d6, d7\n\tvmrs\tapsr_nzcv, fpscr\n\tmovge\tr0, #1      // set result register to 1 if greater than or equal\n\tmovlt\tr0, #0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__gedf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/gesf2vfp.S",
    "content": "//===-- gesf2vfp.S - Implement gesf2vfp -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern int __gesf2vfp(float a, float b);\n//\n// Returns one iff a >= b and neither is NaN.\n// Uses Darwin calling convention where single precision arguments are passsed \n// like 32-bit ints\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__gesf2vfp)\n\tvmov\ts14, r0\t    // move from GPR 0 to float register\n\tvmov\ts15, r1\t    // move from GPR 1 to float register\n\tvcmp.f32 s14, s15\n\tvmrs\tapsr_nzcv, fpscr\n\tmovge\tr0, #1      // set result register to 1 if greater than or equal\n\tmovlt\tr0, #0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__gesf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/gtdf2vfp.S",
    "content": "//===-- gtdf2vfp.S - Implement gtdf2vfp -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern double __gtdf2vfp(double a, double b);\n//\n// Returns one iff a > b and neither is NaN.\n// Uses Darwin calling convention where double precision arguments are passsed \n// like in GPR pairs.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__gtdf2vfp)\n\tvmov \td6, r0, r1\t// load r0/r1 pair in double register\n\tvmov \td7, r2, r3\t// load r2/r3 pair in double register\n\tvcmp.f64 d6, d7\n\tvmrs\tapsr_nzcv, fpscr\n\tmovgt\tr0, #1\t\t// set result register to 1 if equal\n\tmovle\tr0, #0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__gtdf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/gtsf2vfp.S",
    "content": "//===-- gtsf2vfp.S - Implement gtsf2vfp -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern int __gtsf2vfp(float a, float b);\n//\n// Returns one iff a > b and neither is NaN.\n// Uses Darwin calling convention where single precision arguments are passsed \n// like 32-bit ints\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__gtsf2vfp)\n\tvmov\ts14, r0\t\t// move from GPR 0 to float register\n\tvmov\ts15, r1\t\t// move from GPR 1 to float register\n\tvcmp.f32 s14, s15\n\tvmrs\tapsr_nzcv, fpscr\n\tmovgt\tr0, #1\t\t// set result register to 1 if equal\n\tmovle\tr0, #0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__gtsf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/ledf2vfp.S",
    "content": "//===-- ledf2vfp.S - Implement ledf2vfp -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern double __ledf2vfp(double a, double b);\n//\n// Returns one iff a <= b and neither is NaN.\n// Uses Darwin calling convention where double precision arguments are passsed \n// like in GPR pairs.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__ledf2vfp)\n\tvmov \td6, r0, r1\t// load r0/r1 pair in double register\n\tvmov \td7, r2, r3\t// load r2/r3 pair in double register\n\tvcmp.f64 d6, d7\n\tvmrs\tapsr_nzcv, fpscr\n\tmovls\tr0, #1\t\t// set result register to 1 if equal\n\tmovhi\tr0, #0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__ledf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/lesf2vfp.S",
    "content": "//===-- lesf2vfp.S - Implement lesf2vfp -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern int __lesf2vfp(float a, float b);\n//\n// Returns one iff a <= b and neither is NaN.\n// Uses Darwin calling convention where single precision arguments are passsed \n// like 32-bit ints\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__lesf2vfp)\n\tvmov\ts14, r0     // move from GPR 0 to float register\n\tvmov\ts15, r1     // move from GPR 1 to float register\n\tvcmp.f32 s14, s15\n\tvmrs\tapsr_nzcv, fpscr\n\tmovls\tr0, #1      // set result register to 1 if equal\n\tmovhi\tr0, #0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__lesf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/ltdf2vfp.S",
    "content": "//===-- ltdf2vfp.S - Implement ltdf2vfp -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern double __ltdf2vfp(double a, double b);\n//\n// Returns one iff a < b and neither is NaN.\n// Uses Darwin calling convention where double precision arguments are passsed \n// like in GPR pairs.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__ltdf2vfp)\n\tvmov \td6, r0, r1\t// load r0/r1 pair in double register\n\tvmov \td7, r2, r3\t// load r2/r3 pair in double register\n\tvcmp.f64 d6, d7\n\tvmrs\tapsr_nzcv, fpscr\n\tmovmi\tr0, #1\t\t// set result register to 1 if equal\n\tmovpl\tr0, #0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__ltdf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/ltsf2vfp.S",
    "content": "//===-- ltsf2vfp.S - Implement ltsf2vfp -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern int __ltsf2vfp(float a, float b);\n//\n// Returns one iff a < b and neither is NaN.\n// Uses Darwin calling convention where single precision arguments are passsed \n// like 32-bit ints\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__ltsf2vfp)\n\tvmov\ts14, r0     // move from GPR 0 to float register\n\tvmov\ts15, r1     // move from GPR 1 to float register\n\tvcmp.f32 s14, s15\n\tvmrs\tapsr_nzcv, fpscr\n\tmovmi\tr0, #1      // set result register to 1 if equal\n\tmovpl\tr0, #0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__ltsf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/modsi3.S",
    "content": "/*===-- modsi3.S - 32-bit signed integer modulus --------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __modsi3 (32-bit signed integer modulus) function\n * for the ARM architecture as a wrapper around the unsigned routine.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"../assembly.h\"\n\n#define ESTABLISH_FRAME \\\n    push   {r4, r7, lr}    ;\\\n    add     r7,     sp, #4\n#define CLEAR_FRAME_AND_RETURN \\\n    pop    {r4, r7, pc}\n\n\t.syntax unified\n\t.text\n#if __ARM_ARCH_ISA_THUMB == 2\n\t.thumb\n#endif\n\n@ int __modsi3(int divident, int divisor)\n@   Calculate and return the remainder of the (signed) division.\n\n\t.p2align 3\n#if __ARM_ARCH_ISA_THUMB == 2\nDEFINE_COMPILERRT_THUMB_FUNCTION(__modsi3)\n#else\nDEFINE_COMPILERRT_FUNCTION(__modsi3)\n#endif\n#if __ARM_ARCH_EXT_IDIV__\n\ttst     r1, r1\n\tbeq     LOCAL_LABEL(divzero)\n\tsdiv\tr2, r0, r1\n\tmls \tr0, r2, r1, r0\n\tbx      lr\nLOCAL_LABEL(divzero):\n\tmov     r0, #0\n\tbx      lr\n#else\n    ESTABLISH_FRAME\n    //  Set aside the sign of the dividend.\n    mov     r4,     r0\n    //  Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).\n    eor     r2,     r0, r0, asr #31\n    eor     r3,     r1, r1, asr #31\n    sub     r0,     r2, r0, asr #31\n    sub     r1,     r3, r1, asr #31\n    //  abs(a) % abs(b)\n    bl     SYMBOL_NAME(__umodsi3)\n    //  Apply sign of dividend to result and return.\n    eor     r0,     r0, r4, asr #31\n    sub     r0,     r0, r4, asr #31\n    CLEAR_FRAME_AND_RETURN\n#endif\nEND_COMPILERRT_FUNCTION(__modsi3)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/muldf3vfp.S",
    "content": "//===-- muldf3vfp.S - Implement muldf3vfp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern double __muldf3vfp(double a, double b);\n//\n// Multiplies two double precision floating point numbers using the Darwin\n// calling convention where double arguments are passsed in GPR pairs\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__muldf3vfp)\n\tvmov \td6, r0, r1         // move first param from r0/r1 pair into d6\n\tvmov \td7, r2, r3         // move second param from r2/r3 pair into d7\n\tvmul.f64 d6, d6, d7\t\t\n\tvmov \tr0, r1, d6         // move result back to r0/r1 pair\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__muldf3vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/mulsf3vfp.S",
    "content": "//===-- mulsf3vfp.S - Implement mulsf3vfp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern float __mulsf3vfp(float a, float b);\n//\n// Multiplies two single precision floating point numbers using the Darwin\n// calling convention where single arguments are passsed like 32-bit ints.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__mulsf3vfp)\n\tvmov\ts14, r0\t\t// move first param from r0 into float register\n\tvmov\ts15, r1\t\t// move second param from r1 into float register\n\tvmul.f32 s13, s14, s15\n\tvmov\tr0, s13\t\t// move result back to r0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__mulsf3vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/nedf2vfp.S",
    "content": "//===-- nedf2vfp.S - Implement nedf2vfp -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern double __nedf2vfp(double a, double b);\n//\n// Returns zero if a and b are unequal and neither is NaN.\n// Uses Darwin calling convention where double precision arguments are passsed \n// like in GPR pairs.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__nedf2vfp)\n\tvmov \td6, r0, r1\t// load r0/r1 pair in double register\n\tvmov \td7, r2, r3\t// load r2/r3 pair in double register\n\tvcmp.f64 d6, d7\t\t\n\tvmrs\tapsr_nzcv, fpscr\n\tmovne\tr0, #1\t\t// set result register to 0 if unequal\n\tmoveq\tr0, #0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__nedf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/negdf2vfp.S",
    "content": "//===-- negdf2vfp.S - Implement negdf2vfp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern double __negdf2vfp(double a, double b);\n//\n// Returns the negation a double precision floating point numbers using the \n// Darwin calling convention where double arguments are passsed in GPR pairs.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__negdf2vfp)\n\teor\tr1, r1, #-2147483648\t// flip sign bit on double in r0/r1 pair\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__negdf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/negsf2vfp.S",
    "content": "//===-- negsf2vfp.S - Implement negsf2vfp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern float __negsf2vfp(float a);\n//\n// Returns the negation of a single precision floating point numbers using the \n// Darwin calling convention where single arguments are passsed like 32-bit ints\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__negsf2vfp)\n\teor\tr0, r0, #-2147483648\t// flip sign bit on float in r0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__negsf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/nesf2vfp.S",
    "content": "//===-- nesf2vfp.S - Implement nesf2vfp -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern int __nesf2vfp(float a, float b);\n//\n// Returns one iff a != b and neither is NaN.\n// Uses Darwin calling convention where single precision arguments are passsed \n// like 32-bit ints\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__nesf2vfp)\n\tvmov\ts14, r0\t    // move from GPR 0 to float register\n\tvmov\ts15, r1\t    // move from GPR 1 to float register\n\tvcmp.f32 s14, s15\n\tvmrs\tapsr_nzcv, fpscr\n\tmovne\tr0, #1      // set result register to 1 if unequal\n\tmoveq\tr0, #0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__nesf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/restore_vfp_d8_d15_regs.S",
    "content": "//===-- save_restore_regs.S - Implement save/restore* ---------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// When compiling C++ functions that need to handle thrown exceptions the\n// compiler is required to save all registers and call __Unwind_SjLj_Register\n// in the function prolog.  But when compiling for thumb1, there are\n// no instructions to access the floating point registers, so the\n// compiler needs to add a call to the helper function _save_vfp_d8_d15_regs\n// written in ARM to save the float registers.  In the epilog, the compiler\n// must also add a call to __restore_vfp_d8_d15_regs to restore those registers.\n//\n\n\t.text\n\t.syntax unified\n\n//\n// Restore registers d8-d15 from stack\n//\n\t.p2align 2\nDEFINE_COMPILERRT_PRIVATE_FUNCTION(__restore_vfp_d8_d15_regs)\n\tvldmia\tsp!, {d8-d15}           // pop registers d8-d15 off stack\n\tbx      lr                      // return to prolog\nEND_COMPILERRT_FUNCTION(__restore_vfp_d8_d15_regs)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/save_vfp_d8_d15_regs.S",
    "content": "//===-- save_restore_regs.S - Implement save/restore* ---------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// When compiling C++ functions that need to handle thrown exceptions the\n// compiler is required to save all registers and call __Unwind_SjLj_Register\n// in the function prolog.  But when compiling for thumb1, there are\n// no instructions to access the floating point registers, so the\n// compiler needs to add a call to the helper function _save_vfp_d8_d15_regs\n// written in ARM to save the float registers.  In the epilog, the compiler\n// must also add a call to __restore_vfp_d8_d15_regs to restore those registers.\n//\n\n\t.text\n\t.syntax unified\n\n//\n// Save registers d8-d15 onto stack\n//\n\t.p2align 2\nDEFINE_COMPILERRT_PRIVATE_FUNCTION(__save_vfp_d8_d15_regs)\n\tvstmdb\tsp!, {d8-d15}           // push registers d8-d15 onto stack\n\tbx      lr                      // return to prolog\nEND_COMPILERRT_FUNCTION(__save_vfp_d8_d15_regs)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/softfloat-alias.list",
    "content": "#\n# These are soft float functions which can be \n# aliased to the *vfp functions on arm processors\n# that support floating point instructions.\n#\n___adddf3vfp\t\t___adddf3\n___addsf3vfp\t\t___addsf3\n___divdf3vfp\t\t___divdf3\n___divsf3vfp\t\t___divsf3\n___extendsfdf2vfp\t___extendsfdf2\n___fixdfsivfp\t\t___fixdfsi\n___fixsfsivfp\t\t___fixsfsi\n___floatsidfvfp\t\t___floatsidf\n___floatsisfvfp\t\t___floatsisf\n___muldf3vfp\t\t___muldf3\n___mulsf3vfp\t\t___mulsf3\n___subdf3vfp\t\t___subdf3\n___subsf3vfp\t\t___subsf3\n___truncdfsf2vfp\t___truncdfsf2\n___floatunssidfvfp\t___floatunsidf\n___floatunssisfvfp\t___floatunsisf\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/subdf3vfp.S",
    "content": "//===-- subdf3vfp.S - Implement subdf3vfp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern double __subdf3vfp(double a, double b);\n//\n// Returns difference between two double precision floating point numbers using \n// the Darwin calling convention where double arguments are passsed in GPR pairs\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__subdf3vfp)\n\tvmov \td6, r0, r1         // move first param from r0/r1 pair into d6\n\tvmov \td7, r2, r3         // move second param from r2/r3 pair into d7\n\tvsub.f64 d6, d6, d7\t\t\n\tvmov \tr0, r1, d6         // move result back to r0/r1 pair\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__subdf3vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/subsf3vfp.S",
    "content": "//===-- subsf3vfp.S - Implement subsf3vfp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern float __subsf3vfp(float a, float b);\n//\n// Returns the difference between two single precision floating point numbers \n// using the Darwin calling convention where single arguments are passsed\n// like 32-bit ints.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__subsf3vfp)\n\tvmov\ts14, r0\t\t// move first param from r0 into float register\n\tvmov\ts15, r1\t\t// move second param from r1 into float register\n\tvsub.f32 s14, s14, s15\n\tvmov\tr0, s14\t\t// move result back to r0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__subsf3vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/switch16.S",
    "content": "//===-- switch.S - Implement switch* --------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// When compiling switch statements in thumb mode, the compiler\n// can use these __switch* helper functions  The compiler emits a blx to\n// the __switch* function followed by a table of displacements for each\n// case statement.  On entry, R0 is the index into the table. The __switch*\n// function uses the return address in lr to find the start of the table.\n// The first entry in the table is the count of the entries in the table.\n// It then uses R0 to index into the table and get the displacement of the\n// address to jump to.  If R0 is greater than the size of the table, it jumps\n// to the last entry in the table. Each displacement in the table is actually\n// the distance from lr to the label, thus making the tables PIC.\n\n\n\t.text\n\t.syntax unified\n\n//\n// The table contains signed 2-byte sized elements which are 1/2 the distance\n// from lr to the target label.\n//\n\t.p2align 2\nDEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch16)\n\tldrh    ip, [lr, #-1]           // get first 16-bit word in table\n\tcmp     r0, ip                  // compare with index\n\tadd     r0, lr, r0, lsl #1      // compute address of element in table\n\tadd     ip, lr, ip, lsl #1      // compute address of last element in table\n\tite lo\n\tldrshlo r0, [r0, #1]            // load 16-bit element if r0 is in range\n\tldrshhs r0, [ip, #1]            // load 16-bit element if r0 out of range\n\tadd     ip, lr, r0, lsl #1      // compute label = lr + element*2\n\tbx      ip                      // jump to computed label\nEND_COMPILERRT_FUNCTION(__switch16)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/switch32.S",
    "content": "//===-- switch.S - Implement switch* --------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// When compiling switch statements in thumb mode, the compiler\n// can use these __switch* helper functions  The compiler emits a blx to\n// the __switch* function followed by a table of displacements for each\n// case statement.  On entry, R0 is the index into the table. The __switch*\n// function uses the return address in lr to find the start of the table.\n// The first entry in the table is the count of the entries in the table.\n// It then uses R0 to index into the table and get the displacement of the\n// address to jump to.  If R0 is greater than the size of the table, it jumps\n// to the last entry in the table. Each displacement in the table is actually\n// the distance from lr to the label, thus making the tables PIC.\n\n\n\t.text\n\t.syntax unified\n\n//\n// The table contains signed 4-byte sized elements which are the distance\n// from lr to the target label.\n//\n\t.p2align 2\nDEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch32)\n\tldr     ip, [lr, #-1]            // get first 32-bit word in table\n\tcmp     r0, ip                   // compare with index\n\tadd     r0, lr, r0, lsl #2       // compute address of element in table\n\tadd     ip, lr, ip, lsl #2       // compute address of last element in table\n\tite lo\n\tldrlo   r0, [r0, #3]             // load 32-bit element if r0 is in range\n\tldrhs   r0, [ip, #3]             // load 32-bit element if r0 out of range\n\tadd     ip, lr, r0               // compute label = lr + element\n\tbx      ip                       // jump to computed label\nEND_COMPILERRT_FUNCTION(__switch32)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/switch8.S",
    "content": "//===-- switch.S - Implement switch* --------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// When compiling switch statements in thumb mode, the compiler\n// can use these __switch* helper functions  The compiler emits a blx to\n// the __switch* function followed by a table of displacements for each\n// case statement.  On entry, R0 is the index into the table. The __switch*\n// function uses the return address in lr to find the start of the table.\n// The first entry in the table is the count of the entries in the table.\n// It then uses R0 to index into the table and get the displacement of the\n// address to jump to.  If R0 is greater than the size of the table, it jumps\n// to the last entry in the table. Each displacement in the table is actually\n// the distance from lr to the label, thus making the tables PIC.\n\n\n\t.text\n\t.syntax unified\n\n//\n// The table contains signed byte sized elements which are 1/2 the distance\n// from lr to the target label.\n//\n\t.p2align 2\nDEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch8)\n\tldrb    ip, [lr, #-1]           // get first byte in table\n\tcmp     r0, ip                  // signed compare with index\n\tite lo\n\tldrsblo r0, [lr, r0]            // get indexed byte out of table\n\tldrsbhs r0, [lr, ip]            // if out of range, use last entry in table\n\tadd     ip, lr, r0, lsl #1      // compute label = lr + element*2\n\tbx      ip                      // jump to computed label\nEND_COMPILERRT_FUNCTION(__switch8)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/switchu8.S",
    "content": "//===-- switch.S - Implement switch* --------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// When compiling switch statements in thumb mode, the compiler\n// can use these __switch* helper functions  The compiler emits a blx to\n// the __switch* function followed by a table of displacements for each\n// case statement.  On entry, R0 is the index into the table. The __switch*\n// function uses the return address in lr to find the start of the table.\n// The first entry in the table is the count of the entries in the table.\n// It then uses R0 to index into the table and get the displacement of the\n// address to jump to.  If R0 is greater than the size of the table, it jumps\n// to the last entry in the table. Each displacement in the table is actually\n// the distance from lr to the label, thus making the tables PIC.\n\n\n\t.text\n\t.syntax unified\n\n//\n// The table contains unsigned byte sized elements which are 1/2 the distance\n// from lr to the target label.\n//\n\t.p2align 2\nDEFINE_COMPILERRT_PRIVATE_FUNCTION(__switchu8)\n\tldrb    ip, [lr, #-1]           // get first byte in table\n\tcmp     r0, ip                  // compare with index\n\tite lo\n\tldrblo  r0, [lr, r0]            // get indexed byte out of table\n\tldrbhs  r0, [lr, ip]            // if out of range, use last entry in table\n\tadd     ip, lr, r0, lsl #1      // compute label = lr + element*2\n\tbx      ip                      // jump to computed label\nEND_COMPILERRT_FUNCTION(__switchu8)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync-ops.h",
    "content": "/*===-- sync-ops.h - --===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements outline macros for the __sync_fetch_and_*\n * operations. Different instantiations will generate appropriate assembly for\n * ARM and Thumb-2 versions of the functions.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"../assembly.h\"\n\n#define SYNC_OP_4(op) \\\n        .p2align 2 ; \\\n        .thumb ; \\\n        .syntax unified ; \\\n        DEFINE_COMPILERRT_THUMB_FUNCTION(__sync_fetch_and_ ## op) \\\n        dmb ; \\\n        mov r12, r0 ; \\\n        LOCAL_LABEL(tryatomic_ ## op): \\\n        ldrex r0, [r12] ; \\\n        op(r2, r0, r1) ; \\\n        strex r3, r2, [r12] ; \\\n        cmp r3, #0 ; \\\n        bne LOCAL_LABEL(tryatomic_ ## op) ; \\\n        dmb ; \\\n        bx lr\n\n#define SYNC_OP_8(op) \\\n        .p2align 2 ; \\\n        .thumb ; \\\n        .syntax unified ; \\\n        DEFINE_COMPILERRT_THUMB_FUNCTION(__sync_fetch_and_ ## op) \\\n        push {r4, r5, r6, lr} ; \\\n        dmb ; \\\n        mov r12, r0 ; \\\n        LOCAL_LABEL(tryatomic_ ## op): \\\n        ldrexd r0, r1, [r12] ; \\\n        op(r4, r5, r0, r1, r2, r3) ; \\\n        strexd r6, r4, r5, [r12] ; \\\n        cmp r6, #0 ; \\\n        bne LOCAL_LABEL(tryatomic_ ## op) ; \\\n        dmb ; \\\n        pop {r4, r5, r6, pc}\n\n#define MINMAX_4(rD, rN, rM, cmp_kind) \\\n        cmp rN, rM ; \\\n        mov rD, rM ; \\\n        it cmp_kind ; \\\n        mov##cmp_kind rD, rN\n\n#define MINMAX_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI, cmp_kind) \\\n        cmp rN_LO, rM_LO ; \\\n        sbcs rN_HI, rM_HI ; \\\n        mov rD_LO, rM_LO ; \\\n        mov rD_HI, rM_HI ; \\\n        itt cmp_kind ; \\\n        mov##cmp_kind rD_LO, rN_LO ; \\\n        mov##cmp_kind rD_HI, rN_HI\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_add_4.S",
    "content": "/*===-- sync_fetch_and_add_4.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_add_4 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n/* \"adds\" is 2 bytes shorter than \"add\". */\n#define add_4(rD, rN, rM)  add rD, rN, rM\n\nSYNC_OP_4(add_4)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_add_8.S",
    "content": "/*===-- sync_fetch_and_add_8.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_add_8 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#if __ARM_ARCH_PROFILE != 'M'\n#define add_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI) \\\n    adds rD_LO, rN_LO, rM_LO ; \\\n    adc rD_HI, rN_HI, rM_HI\n\nSYNC_OP_8(add_8)\n#endif\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_and_4.S",
    "content": "/*===-- sync_fetch_and_and_4.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_and_4 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#define and_4(rD, rN, rM)  and rD, rN, rM\n\nSYNC_OP_4(and_4)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_and_8.S",
    "content": "/*===-- sync_fetch_and_and_8.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_and_8 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#if __ARM_ARCH_PROFILE != 'M'\n#define and_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI) \\\n    and rD_LO, rN_LO, rM_LO ; \\\n    and rD_HI, rN_HI, rM_HI\n\nSYNC_OP_8(and_8)\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_max_4.S",
    "content": "/*===-- sync_fetch_and_max_4.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_max_4 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#define max_4(rD, rN, rM)  MINMAX_4(rD, rN, rM, gt)\n\nSYNC_OP_4(max_4)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_max_8.S",
    "content": "/*===-- sync_fetch_and_max_8.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_max_8 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#if __ARM_ARCH_PROFILE != 'M'\n#define max_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI)         MINMAX_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI, gt)\n\nSYNC_OP_8(max_8)\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_min_4.S",
    "content": "/*===-- sync_fetch_and_min_4.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_min_4 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#define min_4(rD, rN, rM) MINMAX_4(rD, rN, rM, lt)\n\nSYNC_OP_4(min_4)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_min_8.S",
    "content": "/*===-- sync_fetch_and_min_8.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_min_8 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#if __ARM_ARCH_PROFILE != 'M'\n#define min_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI)         MINMAX_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI, lt)\n\nSYNC_OP_8(min_8)\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_nand_4.S",
    "content": "/*===-- sync_fetch_and_nand_4.S - -----------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_nand_4 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#define nand_4(rD, rN, rM)  bic rD, rN, rM\n\nSYNC_OP_4(nand_4)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_nand_8.S",
    "content": "/*===-- sync_fetch_and_nand_8.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_nand_8 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#if __ARM_ARCH_PROFILE != 'M'\n#define nand_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI) \\\n    bic rD_LO, rN_LO, rM_LO ; \\\n    bic rD_HI, rN_HI, rM_HI\n\nSYNC_OP_8(nand_8)\n#endif\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_or_4.S",
    "content": "/*===-- sync_fetch_and_or_4.S - -------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_or_4 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#define or_4(rD, rN, rM)  orr rD, rN, rM\n\nSYNC_OP_4(or_4)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_or_8.S",
    "content": "/*===-- sync_fetch_and_or_8.S - -------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_or_8 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#if __ARM_ARCH_PROFILE != 'M'\n#define or_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI) \\\n    orr rD_LO, rN_LO, rM_LO ; \\\n    orr rD_HI, rN_HI, rM_HI\n\nSYNC_OP_8(or_8)\n#endif\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_sub_4.S",
    "content": "/*===-- sync_fetch_and_sub_4.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_sub_4 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n/* \"subs\" is 2 bytes shorter than \"sub\". */\n#define sub_4(rD, rN, rM)  sub rD, rN, rM\n\nSYNC_OP_4(sub_4)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_sub_8.S",
    "content": "/*===-- sync_fetch_and_sub_8.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_sub_8 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#if __ARM_ARCH_PROFILE != 'M'\n#define sub_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI) \\\n    subs rD_LO, rN_LO, rM_LO ; \\\n    sbc rD_HI, rN_HI, rM_HI\n\nSYNC_OP_8(sub_8)\n#endif\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_umax_4.S",
    "content": "/*===-- sync_fetch_and_umax_4.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_umax_4 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#define umax_4(rD, rN, rM)  MINMAX_4(rD, rN, rM, hi)\n\nSYNC_OP_4(umax_4)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_umax_8.S",
    "content": "/*===-- sync_fetch_and_umax_8.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_umax_8 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#if __ARM_ARCH_PROFILE != 'M'\n#define umax_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI)         MINMAX_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI, hi)\n\nSYNC_OP_8(umax_8)\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_umin_4.S",
    "content": "/*===-- sync_fetch_and_umin_4.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_umin_4 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#define umin_4(rD, rN, rM) MINMAX_4(rD, rN, rM, lo)\n\nSYNC_OP_4(umin_4)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_umin_8.S",
    "content": "/*===-- sync_fetch_and_umin_8.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_umin_8 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#if __ARM_ARCH_PROFILE != 'M'\n#define umin_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI)         MINMAX_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI, lo)\n\nSYNC_OP_8(umin_8)\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_xor_4.S",
    "content": "/*===-- sync_fetch_and_xor_4.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_xor_4 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#define xor_4(rD, rN, rM)  eor rD, rN, rM\n\nSYNC_OP_4(xor_4)\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_fetch_and_xor_8.S",
    "content": "/*===-- sync_fetch_and_xor_8.S - ------------------------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __sync_fetch_and_xor_8 function for the ARM\n * architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"sync-ops.h\"\n\n#if __ARM_ARCH_PROFILE != 'M'\n#define xor_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI) \\\n    eor rD_LO, rN_LO, rM_LO ; \\\n    eor rD_HI, rN_HI, rM_HI\n\nSYNC_OP_8(xor_8)\n#endif\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/sync_synchronize.S",
    "content": "//===-- sync_synchronize - Implement memory barrier * ----------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// When compiling a use of the gcc built-in __sync_synchronize() in thumb1 mode\n// the compiler may emit a call to __sync_synchronize.  \n// On Darwin the implementation jumps to an OS supplied function named \n// OSMemoryBarrier\n//\n\n\t.text\n\t.syntax unified\n\n#if __APPLE__\n\n\t.p2align 2\nDEFINE_COMPILERRT_PRIVATE_FUNCTION(__sync_synchronize)\n\tstmfd\tsp!, {r7, lr}\n\tadd\t\tr7, sp, #0\n\tbl\t\t_OSMemoryBarrier\n\tldmfd\tsp!, {r7, pc}\nEND_COMPILERRT_FUNCTION(__sync_synchronize)\n\n\t// tell linker it can break up file at label boundaries\n\t.subsections_via_symbols\n\t\t\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/truncdfsf2vfp.S",
    "content": "//===-- truncdfsf2vfp.S - Implement truncdfsf2vfp -------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern float __truncdfsf2vfp(double a);\n//\n// Converts double precision float to signle precision result.\n// Uses Darwin calling convention where a double precision parameter is \n// passed in a R0/R1 pair and a signle precision result is returned in R0.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__truncdfsf2vfp)\n\tvmov \td7, r0, r1   // load double from r0/r1 pair\n\tvcvt.f32.f64 s15, d7 // convert double to single (trucate precision)\n\tvmov \tr0, s15      // return result in r0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__truncdfsf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/udivmodsi4.S",
    "content": "/*===-- udivmodsi4.S - 32-bit unsigned integer divide and modulus ---------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __udivmodsi4 (32-bit unsigned integer divide and\n * modulus) function for the ARM 32-bit architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"../assembly.h\"\n\n\t.syntax unified\n\t.text\n\n#if __ARM_ARCH_ISA_THUMB == 2\n\t.thumb\n#endif\n\n@ unsigned int __udivmodsi4(unsigned int divident, unsigned int divisor,\n@                           unsigned int *remainder)\n@   Calculate the quotient and remainder of the (unsigned) division.  The return\n@   value is the quotient, the remainder is placed in the variable.\n\n\t.p2align 2\n#if __ARM_ARCH_ISA_THUMB == 2\nDEFINE_COMPILERRT_THUMB_FUNCTION(__udivmodsi4)\n#else\nDEFINE_COMPILERRT_FUNCTION(__udivmodsi4)\n#endif\n#if __ARM_ARCH_EXT_IDIV__\n\ttst     r1, r1\n\tbeq     LOCAL_LABEL(divby0)\n\tmov \tr3, r0\n\tudiv\tr0, r3, r1\n\tmls \tr1, r0, r1, r3\n\tstr \tr1, [r2]\n\tbx  \tlr\n#else\n\tcmp\tr1, #1\n\tbcc\tLOCAL_LABEL(divby0)\n\tbeq\tLOCAL_LABEL(divby1)\n\tcmp\tr0, r1\n\tbcc\tLOCAL_LABEL(quotient0)\n\t/*\n\t * Implement division using binary long division algorithm.\n\t *\n\t * r0 is the numerator, r1 the denominator.\n\t *\n\t * The code before JMP computes the correct shift I, so that\n\t * r0 and (r1 << I) have the highest bit set in the same position.\n\t * At the time of JMP, ip := .Ldiv0block - 12 * I.\n\t * This depends on the fixed instruction size of block.\n\t * For ARM mode, this is 12 Bytes, for THUMB mode 14 Bytes.\n\t *\n\t * block(shift) implements the test-and-update-quotient core.\n\t * It assumes (r0 << shift) can be computed without overflow and\n\t * that (r0 << shift) < 2 * r1. The quotient is stored in r3.\n\t */\n\n#  ifdef __ARM_FEATURE_CLZ\n\tclz\tip, r0\n\tclz\tr3, r1\n\t/* r0 >= r1 implies clz(r0) <= clz(r1), so ip <= r3. */\n\tsub\tr3, r3, ip\n#    if __ARM_ARCH_ISA_THUMB == 2\n\tadr\tip, LOCAL_LABEL(div0block) + 1\n\tsub\tip, ip, r3, lsl #1\n#    else\n\tadr\tip, LOCAL_LABEL(div0block)\n#    endif\n\tsub\tip, ip, r3, lsl #2\n\tsub\tip, ip, r3, lsl #3\n\tmov\tr3, #0\n\tbx\tip\n#  else\n#    if __ARM_ARCH_ISA_THUMB == 2\n#    error THUMB mode requires CLZ or UDIV\n#    endif\n\tstr\tr4, [sp, #-8]!\n\n\tmov\tr4, r0\n\tadr\tip, LOCAL_LABEL(div0block)\n\n\tlsr\tr3, r4, #16\n\tcmp\tr3, r1\n\tmovhs\tr4, r3\n\tsubhs\tip, ip, #(16 * 12)\n\n\tlsr\tr3, r4, #8\n\tcmp\tr3, r1\n\tmovhs\tr4, r3\n\tsubhs\tip, ip, #(8 * 12)\n\n\tlsr\tr3, r4, #4\n\tcmp\tr3, r1\n\tmovhs\tr4, r3\n\tsubhs\tip, #(4 * 12)\n\n\tlsr\tr3, r4, #2\n\tcmp\tr3, r1\n\tmovhs\tr4, r3\n\tsubhs\tip, ip, #(2 * 12)\n\n\t/* Last block, no need to update r3 or r4. */\n\tcmp\tr1, r4, lsr #1\n\tsubls\tip, ip, #(1 * 12)\n\n\tldr\tr4, [sp], #8\t/* restore r4, we are done with it. */\n\tmov\tr3, #0\n\n\tJMP(ip)\n#  endif\n\n#define\tIMM\t#\n\n#define block(shift)                                                           \\\n\tcmp\tr0, r1, lsl IMM shift;                                         \\\n\tITT(hs);                                                               \\\n\tWIDE(addhs)\tr3, r3, IMM (1 << shift);                              \\\n\tWIDE(subhs)\tr0, r0, r1, lsl IMM shift\n\n\tblock(31)\n\tblock(30)\n\tblock(29)\n\tblock(28)\n\tblock(27)\n\tblock(26)\n\tblock(25)\n\tblock(24)\n\tblock(23)\n\tblock(22)\n\tblock(21)\n\tblock(20)\n\tblock(19)\n\tblock(18)\n\tblock(17)\n\tblock(16)\n\tblock(15)\n\tblock(14)\n\tblock(13)\n\tblock(12)\n\tblock(11)\n\tblock(10)\n\tblock(9)\n\tblock(8)\n\tblock(7)\n\tblock(6)\n\tblock(5)\n\tblock(4)\n\tblock(3)\n\tblock(2)\n\tblock(1)\nLOCAL_LABEL(div0block):\n\tblock(0)\n\n\tstr\tr0, [r2]\n\tmov\tr0, r3\n\tJMP(lr)\n\nLOCAL_LABEL(quotient0):\n\tstr\tr0, [r2]\n\tmov\tr0, #0\n\tJMP(lr)\n\nLOCAL_LABEL(divby1):\n\tmov\tr3, #0\n\tstr\tr3, [r2]\n\tJMP(lr)\n#endif /* __ARM_ARCH_EXT_IDIV__ */\n\nLOCAL_LABEL(divby0):\n\tmov\tr0, #0\n#ifdef __ARM_EABI__\n\tb\t__aeabi_idiv0\n#else\n\tJMP(lr)\n#endif\n\nEND_COMPILERRT_FUNCTION(__udivmodsi4)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/udivsi3.S",
    "content": "/*===-- udivsi3.S - 32-bit unsigned integer divide ------------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __udivsi3 (32-bit unsigned integer divide)\n * function for the ARM 32-bit architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"../assembly.h\"\n\n\t.syntax unified\n\t.text\n\n#if __ARM_ARCH_ISA_THUMB == 2\n\t.thumb\n#endif\n\n\t.p2align 2\nDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_uidiv, __udivsi3)\n\n@ unsigned int __udivsi3(unsigned int divident, unsigned int divisor)\n@   Calculate and return the quotient of the (unsigned) division.\n\n#if __ARM_ARCH_ISA_THUMB == 2\nDEFINE_COMPILERRT_THUMB_FUNCTION(__udivsi3)\n#else\nDEFINE_COMPILERRT_FUNCTION(__udivsi3)\n#endif\n#if __ARM_ARCH_EXT_IDIV__\n\ttst     r1, r1\n\tbeq     LOCAL_LABEL(divby0)\n\tudiv\tr0, r0, r1\n\tbx  \tlr\n#else\n\tcmp\tr1, #1\n\tbcc\tLOCAL_LABEL(divby0)\n\tIT(eq)\n\tJMPc(lr, eq)\n\tcmp\tr0, r1\n\tITT(cc)\n\tmovcc\tr0, #0\n\tJMPc(lr, cc)\n\t/*\n\t * Implement division using binary long division algorithm.\n\t *\n\t * r0 is the numerator, r1 the denominator.\n\t *\n\t * The code before JMP computes the correct shift I, so that\n\t * r0 and (r1 << I) have the highest bit set in the same position.\n\t * At the time of JMP, ip := .Ldiv0block - 12 * I.\n\t * This depends on the fixed instruction size of block.\n\t * For ARM mode, this is 12 Bytes, for THUMB mode 14 Bytes.\n\t *\n\t * block(shift) implements the test-and-update-quotient core.\n\t * It assumes (r0 << shift) can be computed without overflow and\n\t * that (r0 << shift) < 2 * r1. The quotient is stored in r3.\n\t */\n\n#  ifdef __ARM_FEATURE_CLZ\n\tclz\tip, r0\n\tclz\tr3, r1\n\t/* r0 >= r1 implies clz(r0) <= clz(r1), so ip <= r3. */\n\tsub\tr3, r3, ip\n#    if __ARM_ARCH_ISA_THUMB == 2\n\tadr\tip, LOCAL_LABEL(div0block) + 1\n\tsub\tip, ip, r3, lsl #1\n#    else\n\tadr\tip, LOCAL_LABEL(div0block)\n#    endif\n\tsub\tip, ip, r3, lsl #2\n\tsub\tip, ip, r3, lsl #3\n\tmov\tr3, #0\n\tbx\tip\n#  else\n#    if __ARM_ARCH_ISA_THUMB == 2\n#    error THUMB mode requires CLZ or UDIV\n#    endif\n\tmov\tr2, r0\n\tadr\tip, LOCAL_LABEL(div0block)\n\n\tlsr\tr3, r2, #16\n\tcmp\tr3, r1\n\tmovhs\tr2, r3\n\tsubhs\tip, ip, #(16 * 12)\n\n\tlsr\tr3, r2, #8\n\tcmp\tr3, r1\n\tmovhs\tr2, r3\n\tsubhs\tip, ip, #(8 * 12)\n\n\tlsr\tr3, r2, #4\n\tcmp\tr3, r1\n\tmovhs\tr2, r3\n\tsubhs\tip, #(4 * 12)\n\n\tlsr\tr3, r2, #2\n\tcmp\tr3, r1\n\tmovhs\tr2, r3\n\tsubhs\tip, ip, #(2 * 12)\n\n\t/* Last block, no need to update r2 or r3. */\n\tcmp\tr1, r2, lsr #1\n\tsubls\tip, ip, #(1 * 12)\n\n\tmov\tr3, #0\n\n\tJMP(ip)\n#  endif\n\n#define\tIMM\t#\n\n#define block(shift)                                                           \\\n\tcmp\tr0, r1, lsl IMM shift;                                         \\\n\tITT(hs);                                                               \\\n\tWIDE(addhs)\tr3, r3, IMM (1 << shift);                              \\\n\tWIDE(subhs)\tr0, r0, r1, lsl IMM shift\n\n\tblock(31)\n\tblock(30)\n\tblock(29)\n\tblock(28)\n\tblock(27)\n\tblock(26)\n\tblock(25)\n\tblock(24)\n\tblock(23)\n\tblock(22)\n\tblock(21)\n\tblock(20)\n\tblock(19)\n\tblock(18)\n\tblock(17)\n\tblock(16)\n\tblock(15)\n\tblock(14)\n\tblock(13)\n\tblock(12)\n\tblock(11)\n\tblock(10)\n\tblock(9)\n\tblock(8)\n\tblock(7)\n\tblock(6)\n\tblock(5)\n\tblock(4)\n\tblock(3)\n\tblock(2)\n\tblock(1)\nLOCAL_LABEL(div0block):\n\tblock(0)\n\n\tmov\tr0, r3\n\tJMP(lr)\n#endif /* __ARM_ARCH_EXT_IDIV__ */\n\nLOCAL_LABEL(divby0):\n\tmov\tr0, #0\n#ifdef __ARM_EABI__\n\tb\t__aeabi_idiv0\n#else\n\tJMP(lr)\n#endif\n\nEND_COMPILERRT_FUNCTION(__udivsi3)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/umodsi3.S",
    "content": "/*===-- umodsi3.S - 32-bit unsigned integer modulus -----------------------===//\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===//\n *\n * This file implements the __umodsi3 (32-bit unsigned integer modulus)\n * function for the ARM 32-bit architecture.\n *\n *===----------------------------------------------------------------------===*/\n\n#include \"../assembly.h\"\n\n\t.syntax unified\n\t.text\n#if __ARM_ARCH_ISA_THUMB == 2\n\t.thumb\n#endif\n\n@ unsigned int __umodsi3(unsigned int divident, unsigned int divisor)\n@   Calculate and return the remainder of the (unsigned) division.\n\n\t.p2align 2\n#if __ARM_ARCH_ISA_THUMB == 2\nDEFINE_COMPILERRT_THUMB_FUNCTION(__umodsi3)\n#else\nDEFINE_COMPILERRT_FUNCTION(__umodsi3)\n#endif\n#if __ARM_ARCH_EXT_IDIV__\n\ttst     r1, r1\n\tbeq     LOCAL_LABEL(divby0)\n\tudiv\tr2, r0, r1\n\tmls \tr0, r2, r1, r0\n\tbx  \tlr\n#else\n\tcmp\tr1, #1\n\tbcc\tLOCAL_LABEL(divby0)\n\tITT(eq)\n\tmoveq\tr0, #0\n\tJMPc(lr, eq)\n\tcmp\tr0, r1\n\tIT(cc)\n\tJMPc(lr, cc)\n\t/*\n\t * Implement division using binary long division algorithm.\n\t *\n\t * r0 is the numerator, r1 the denominator.\n\t *\n\t * The code before JMP computes the correct shift I, so that\n\t * r0 and (r1 << I) have the highest bit set in the same position.\n\t * At the time of JMP, ip := .Ldiv0block - 8 * I.\n\t * This depends on the fixed instruction size of block.\n\t * For ARM mode, this is 8 Bytes, for THUMB mode 10 Bytes.\n\t *\n\t * block(shift) implements the test-and-update-quotient core.\n\t * It assumes (r0 << shift) can be computed without overflow and\n\t * that (r0 << shift) < 2 * r1. The quotient is stored in r3.\n\t */\n\n#  ifdef __ARM_FEATURE_CLZ\n\tclz\tip, r0\n\tclz\tr3, r1\n\t/* r0 >= r1 implies clz(r0) <= clz(r1), so ip <= r3. */\n\tsub\tr3, r3, ip\n#    if __ARM_ARCH_ISA_THUMB == 2\n\tadr\tip, LOCAL_LABEL(div0block) + 1\n\tsub\tip, ip, r3, lsl #1\n#    else\n\tadr\tip, LOCAL_LABEL(div0block)\n#    endif\n\tsub\tip, ip, r3, lsl #3\n\tbx\tip\n#  else\n#    if __ARM_ARCH_ISA_THUMB == 2\n#    error THUMB mode requires CLZ or UDIV\n#    endif\n\tmov\tr2, r0\n\tadr\tip, LOCAL_LABEL(div0block)\n\n\tlsr\tr3, r2, #16\n\tcmp\tr3, r1\n\tmovhs\tr2, r3\n\tsubhs\tip, ip, #(16 * 8)\n\n\tlsr\tr3, r2, #8\n\tcmp\tr3, r1\n\tmovhs\tr2, r3\n\tsubhs\tip, ip, #(8 * 8)\n\n\tlsr\tr3, r2, #4\n\tcmp\tr3, r1\n\tmovhs\tr2, r3\n\tsubhs\tip, #(4 * 8)\n\n\tlsr\tr3, r2, #2\n\tcmp\tr3, r1\n\tmovhs\tr2, r3\n\tsubhs\tip, ip, #(2 * 8)\n\n\t/* Last block, no need to update r2 or r3. */\n\tcmp\tr1, r2, lsr #1\n\tsubls\tip, ip, #(1 * 8)\n\n\tJMP(ip)\n#  endif\n\n#define\tIMM\t#\n\n#define block(shift)                                                           \\\n\tcmp\tr0, r1, lsl IMM shift;                                         \\\n\tIT(hs);                                                                \\\n\tWIDE(subhs)\tr0, r0, r1, lsl IMM shift\n\n\tblock(31)\n\tblock(30)\n\tblock(29)\n\tblock(28)\n\tblock(27)\n\tblock(26)\n\tblock(25)\n\tblock(24)\n\tblock(23)\n\tblock(22)\n\tblock(21)\n\tblock(20)\n\tblock(19)\n\tblock(18)\n\tblock(17)\n\tblock(16)\n\tblock(15)\n\tblock(14)\n\tblock(13)\n\tblock(12)\n\tblock(11)\n\tblock(10)\n\tblock(9)\n\tblock(8)\n\tblock(7)\n\tblock(6)\n\tblock(5)\n\tblock(4)\n\tblock(3)\n\tblock(2)\n\tblock(1)\nLOCAL_LABEL(div0block):\n\tblock(0)\n\tJMP(lr)\n#endif /* __ARM_ARCH_EXT_IDIV__ */\n\nLOCAL_LABEL(divby0):\n\tmov\tr0, #0\n#ifdef __ARM_EABI__\n\tb\t__aeabi_idiv0\n#else\n\tJMP(lr)\n#endif\n\nEND_COMPILERRT_FUNCTION(__umodsi3)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/unorddf2vfp.S",
    "content": "//===-- unorddf2vfp.S - Implement unorddf2vfp ------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern int __unorddf2vfp(double a, double b);\n//\n// Returns one iff a or b is NaN\n// Uses Darwin calling convention where double precision arguments are passsed \n// like in GPR pairs.\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__unorddf2vfp)\n\tvmov \td6, r0, r1\t// load r0/r1 pair in double register\n\tvmov \td7, r2, r3\t// load r2/r3 pair in double register\n\tvcmp.f64 d6, d7\t\t\n\tvmrs\tapsr_nzcv, fpscr\n\tmovvs\tr0, #1      // set result register to 1 if \"overflow\" (any NaNs)\n\tmovvc\tr0, #0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__unorddf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm/unordsf2vfp.S",
    "content": "//===-- unordsf2vfp.S - Implement unordsf2vfp -----------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// extern int __unordsf2vfp(float a, float b);\n//\n// Returns one iff a or b is NaN\n// Uses Darwin calling convention where single precision arguments are passsed \n// like 32-bit ints\n//\n\t.syntax unified\n\t.p2align 2\nDEFINE_COMPILERRT_FUNCTION(__unordsf2vfp)\n\tvmov\ts14, r0     // move from GPR 0 to float register\n\tvmov\ts15, r1\t    // move from GPR 1 to float register\n\tvcmp.f32 s14, s15\n\tvmrs\tapsr_nzcv, fpscr\n\tmovvs\tr0, #1      // set result register to 1 if \"overflow\" (any NaNs)\n\tmovvc\tr0, #0\n\tbx\tlr\nEND_COMPILERRT_FUNCTION(__unordsf2vfp)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm64/Makefile.mk",
    "content": "#===- lib/builtins/arm64/Makefile.mk -----------------------*- Makefile -*--===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\nModuleName := builtins\nSubDirs := \nOnlyArchs := arm64 \n\nAsmSources := $(foreach file,$(wildcard $(Dir)/*.S),$(notdir $(file)))\nSources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))\nObjNames := $(Sources:%.c=%.o) $(AsmSources:%.S=%.o)\nImplementation := Optimized\n\n# FIXME: use automatic dependencies?\nDependencies := $(wildcard lib/*.h $(Dir)/*.h)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/arm64/dummy.c",
    "content": "/* ===---------- dummy.c - Implements dummy function, for bringup -----------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\nstatic void dummy(void) __attribute__((used));\n\nstatic void dummy(void) {}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/armv6m/Makefile.mk",
    "content": "#===- lib/builtins/arm/Makefile.mk -------------------------*- Makefile -*--===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\nModuleName := builtins\nSubDirs := \nOnlyArchs := armv6m\n\nAsmSources := $(foreach file,$(wildcard $(Dir)/*.S),$(notdir $(file)))\nSources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))\nObjNames := $(Sources:%.c=%.o) $(AsmSources:%.S=%.o)\nImplementation := Optimized\n\n# FIXME: use automatic dependencies?\nDependencies := $(wildcard lib/*.h $(Dir)/*.h)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ashldi3.c",
    "content": "/* ====-- ashldi3.c - Implement __ashldi3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __ashldi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a << b */\n\n/* Precondition:  0 <= b < bits_in_dword */\n\nARM_EABI_FNALIAS(llsl, ashldi3)\n\nCOMPILER_RT_ABI di_int\n__ashldi3(di_int a, si_int b)\n{\n    const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT);\n    dwords input;\n    dwords result;\n    input.all = a;\n    if (b & bits_in_word)  /* bits_in_word <= b < bits_in_dword */\n    {\n        result.s.low = 0;\n        result.s.high = input.s.low << (b - bits_in_word);\n    }\n    else  /* 0 <= b < bits_in_word */\n    {\n        if (b == 0)\n            return a;\n        result.s.low  = input.s.low << b;\n        result.s.high = (input.s.high << b) | (input.s.low >> (bits_in_word - b));\n    }\n    return result.all;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ashlti3.c",
    "content": "/* ===-- ashlti3.c - Implement __ashlti3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __ashlti3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: a << b */\n\n/* Precondition:  0 <= b < bits_in_tword */\n\nCOMPILER_RT_ABI ti_int\n__ashlti3(ti_int a, si_int b)\n{\n    const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT);\n    twords input;\n    twords result;\n    input.all = a;\n    if (b & bits_in_dword)  /* bits_in_dword <= b < bits_in_tword */\n    {\n        result.s.low = 0;\n        result.s.high = input.s.low << (b - bits_in_dword);\n    }\n    else  /* 0 <= b < bits_in_dword */\n    {\n        if (b == 0)\n            return a;\n        result.s.low  = input.s.low << b;\n        result.s.high = (input.s.high << b) | (input.s.low >> (bits_in_dword - b));\n    }\n    return result.all;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ashrdi3.c",
    "content": "/*===-- ashrdi3.c - Implement __ashrdi3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __ashrdi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: arithmetic a >> b */\n\n/* Precondition:  0 <= b < bits_in_dword */\n\nARM_EABI_FNALIAS(lasr, ashrdi3)\n\nCOMPILER_RT_ABI di_int\n__ashrdi3(di_int a, si_int b)\n{\n    const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT);\n    dwords input;\n    dwords result;\n    input.all = a;\n    if (b & bits_in_word)  /* bits_in_word <= b < bits_in_dword */\n    {\n        /* result.s.high = input.s.high < 0 ? -1 : 0 */\n        result.s.high = input.s.high >> (bits_in_word - 1);\n        result.s.low = input.s.high >> (b - bits_in_word);\n    }\n    else  /* 0 <= b < bits_in_word */\n    {\n        if (b == 0)\n            return a;\n        result.s.high  = input.s.high >> b;\n        result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b);\n    }\n    return result.all;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ashrti3.c",
    "content": "/* ===-- ashrti3.c - Implement __ashrti3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __ashrti3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: arithmetic a >> b */\n\n/* Precondition:  0 <= b < bits_in_tword */\n\nCOMPILER_RT_ABI ti_int\n__ashrti3(ti_int a, si_int b)\n{\n    const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT);\n    twords input;\n    twords result;\n    input.all = a;\n    if (b & bits_in_dword)  /* bits_in_dword <= b < bits_in_tword */\n    {\n        /* result.s.high = input.s.high < 0 ? -1 : 0 */\n        result.s.high = input.s.high >> (bits_in_dword - 1);\n        result.s.low = input.s.high >> (b - bits_in_dword);\n    }\n    else  /* 0 <= b < bits_in_dword */\n    {\n        if (b == 0)\n            return a;\n        result.s.high  = input.s.high >> b;\n        result.s.low = (input.s.high << (bits_in_dword - b)) | (input.s.low >> b);\n    }\n    return result.all;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/assembly.h",
    "content": "/* ===-- assembly.h - compiler-rt assembler support macros -----------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file defines macros for use in compiler-rt assembler source.\n * This file is not part of the interface of this library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#ifndef COMPILERRT_ASSEMBLY_H\n#define COMPILERRT_ASSEMBLY_H\n\n#if defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__)\n#define SEPARATOR @\n#else\n#define SEPARATOR ;\n#endif\n\n#if defined(__APPLE__)\n#define HIDDEN(name) .private_extern name\n#define LOCAL_LABEL(name) L_##name\n// tell linker it can break up file at label boundaries\n#define FILE_LEVEL_DIRECTIVE .subsections_via_symbols\n#define SYMBOL_IS_FUNC(name)\n#define CONST_SECTION .const\n\n#elif defined(__ELF__)\n\n#define HIDDEN(name) .hidden name\n#define LOCAL_LABEL(name) .L_##name\n#define FILE_LEVEL_DIRECTIVE\n#if defined(__arm__)\n#define SYMBOL_IS_FUNC(name) .type name,%function\n#else\n#define SYMBOL_IS_FUNC(name) .type name,@function\n#endif\n#define CONST_SECTION .section .rodata\n\n#else // !__APPLE__ && !__ELF__\n\n#define HIDDEN(name)\n#define LOCAL_LABEL(name) .L ## name\n#define FILE_LEVEL_DIRECTIVE\n#define SYMBOL_IS_FUNC(name)                                                   \\\n  .def name SEPARATOR                                                          \\\n    .scl 2 SEPARATOR                                                           \\\n    .type 32 SEPARATOR                                                         \\\n  .endef\n#define CONST_SECTION .section .rdata,\"rd\"\n\n#endif\n\n#if defined(__arm__)\n#if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5\n#define ARM_HAS_BX\n#endif\n#if !defined(__ARM_FEATURE_CLZ) &&                                             \\\n    (__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__)))\n#define __ARM_FEATURE_CLZ\n#endif\n\n#ifdef ARM_HAS_BX\n#define JMP(r) bx r\n#define JMPc(r, c) bx##c r\n#else\n#define JMP(r) mov pc, r\n#define JMPc(r, c) mov##c pc, r\n#endif\n\n// pop {pc} can't switch Thumb mode on ARMv4T\n#if __ARM_ARCH >= 5\n#define POP_PC() pop {pc}\n#else\n#define POP_PC()                                                               \\\n  pop {ip};                                                                    \\\n  JMP(ip)\n#endif\n\n#if __ARM_ARCH_ISA_THUMB == 2\n#define IT(cond)  it cond\n#define ITT(cond) itt cond\n#else\n#define IT(cond)\n#define ITT(cond)\n#endif\n\n#if __ARM_ARCH_ISA_THUMB == 2\n#define WIDE(op) op.w\n#else\n#define WIDE(op) op\n#endif\n#endif\n\n#define GLUE2(a, b) a##b\n#define GLUE(a, b) GLUE2(a, b)\n#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)\n\n#ifdef VISIBILITY_HIDDEN\n#define DECLARE_SYMBOL_VISIBILITY(name)                                        \\\n  HIDDEN(SYMBOL_NAME(name)) SEPARATOR\n#else\n#define DECLARE_SYMBOL_VISIBILITY(name)\n#endif\n\n#define DEFINE_COMPILERRT_FUNCTION(name)                                       \\\n  FILE_LEVEL_DIRECTIVE SEPARATOR                                               \\\n  .globl SYMBOL_NAME(name) SEPARATOR                                           \\\n  SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \\\n  DECLARE_SYMBOL_VISIBILITY(name)                                              \\\n  SYMBOL_NAME(name):\n\n#define DEFINE_COMPILERRT_THUMB_FUNCTION(name)                                 \\\n  FILE_LEVEL_DIRECTIVE SEPARATOR                                               \\\n  .globl SYMBOL_NAME(name) SEPARATOR                                           \\\n  SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \\\n  DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR                                    \\\n  .thumb_func SEPARATOR                                                        \\\n  SYMBOL_NAME(name):\n\n#define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name)                               \\\n  FILE_LEVEL_DIRECTIVE SEPARATOR                                               \\\n  .globl SYMBOL_NAME(name) SEPARATOR                                           \\\n  SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \\\n  HIDDEN(SYMBOL_NAME(name)) SEPARATOR                                          \\\n  SYMBOL_NAME(name):\n\n#define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name)                     \\\n  .globl name SEPARATOR                                                        \\\n  SYMBOL_IS_FUNC(name) SEPARATOR                                               \\\n  HIDDEN(name) SEPARATOR                                                       \\\n  name:\n\n#define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target)                         \\\n  .globl SYMBOL_NAME(name) SEPARATOR                                           \\\n  SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \\\n  .set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR\n\n#if defined(__ARM_EABI__)\n#define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name)                          \\\n  DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name)\n#else\n#define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name)\n#endif\n\n#ifdef __ELF__\n#define END_COMPILERRT_FUNCTION(name)                                          \\\n  .size SYMBOL_NAME(name), . - SYMBOL_NAME(name)\n#else\n#define END_COMPILERRT_FUNCTION(name)\n#endif\n\n#endif /* COMPILERRT_ASSEMBLY_H */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/atomic.c",
    "content": "/*===-- atomic.c - Implement support functions for atomic operations.------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===\n *\n *  atomic.c defines a set of functions for performing atomic accesses on\n *  arbitrary-sized memory locations.  This design uses locks that should\n *  be fast in the uncontended case, for two reasons:\n * \n *  1) This code must work with C programs that do not link to anything\n *     (including pthreads) and so it should not depend on any pthread\n *     functions.\n *  2) Atomic operations, rather than explicit mutexes, are most commonly used\n *     on code where contended operations are rate.\n * \n *  To avoid needing a per-object lock, this code allocates an array of\n *  locks and hashes the object pointers to find the one that it should use.\n *  For operations that must be atomic on two locations, the lower lock is\n *  always acquired first, to avoid deadlock.\n *\n *===----------------------------------------------------------------------===\n */\n\n#include <stdint.h>\n#include <string.h>\n\n#include \"assembly.h\"\n\n// Clang objects if you redefine a builtin.  This little hack allows us to\n// define a function with the same name as an intrinsic.\n#pragma redefine_extname __atomic_load_c SYMBOL_NAME(__atomic_load)\n#pragma redefine_extname __atomic_store_c SYMBOL_NAME(__atomic_store)\n#pragma redefine_extname __atomic_exchange_c SYMBOL_NAME(__atomic_exchange)\n#pragma redefine_extname __atomic_compare_exchange_c SYMBOL_NAME(__atomic_compare_exchange)\n\n/// Number of locks.  This allocates one page on 32-bit platforms, two on\n/// 64-bit.  This can be specified externally if a different trade between\n/// memory usage and contention probability is required for a given platform.\n#ifndef SPINLOCK_COUNT\n#define SPINLOCK_COUNT (1<<10)\n#endif\nstatic const long SPINLOCK_MASK = SPINLOCK_COUNT - 1;\n\n////////////////////////////////////////////////////////////////////////////////\n// Platform-specific lock implementation.  Falls back to spinlocks if none is\n// defined.  Each platform should define the Lock type, and corresponding\n// lock() and unlock() functions.\n////////////////////////////////////////////////////////////////////////////////\n#ifdef __FreeBSD__\n#include <errno.h>\n#include <sys/types.h>\n#include <machine/atomic.h>\n#include <sys/umtx.h>\ntypedef struct _usem Lock;\n__inline static void unlock(Lock *l) {\n  __c11_atomic_store((_Atomic(uint32_t)*)&l->_count, 1, __ATOMIC_RELEASE);\n  __c11_atomic_thread_fence(__ATOMIC_SEQ_CST);\n  if (l->_has_waiters)\n      _umtx_op(l, UMTX_OP_SEM_WAKE, 1, 0, 0);\n}\n__inline static void lock(Lock *l) {\n  uint32_t old = 1;\n  while (!__c11_atomic_compare_exchange_weak((_Atomic(uint32_t)*)&l->_count, &old,\n        0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) {\n    _umtx_op(l, UMTX_OP_SEM_WAIT, 0, 0, 0);\n    old = 1;\n  }\n}\n/// locks for atomic operations\nstatic Lock locks[SPINLOCK_COUNT] = { [0 ...  SPINLOCK_COUNT-1] = {0,1,0} };\n\n#elif defined(__APPLE__)\n#include <libkern/OSAtomic.h>\ntypedef OSSpinLock Lock;\n__inline static void unlock(Lock *l) {\n  OSSpinLockUnlock(l);\n}\n/// Locks a lock.  In the current implementation, this is potentially\n/// unbounded in the contended case.\n__inline static void lock(Lock *l) {\n  OSSpinLockLock(l);\n}\nstatic Lock locks[SPINLOCK_COUNT]; // initialized to OS_SPINLOCK_INIT which is 0\n\n#else\ntypedef _Atomic(uintptr_t) Lock;\n/// Unlock a lock.  This is a release operation.\n__inline static void unlock(Lock *l) {\n  __c11_atomic_store(l, 0, __ATOMIC_RELEASE);\n}\n/// Locks a lock.  In the current implementation, this is potentially\n/// unbounded in the contended case.\n__inline static void lock(Lock *l) {\n  uintptr_t old = 0;\n  while (!__c11_atomic_compare_exchange_weak(l, &old, 1, __ATOMIC_ACQUIRE,\n        __ATOMIC_RELAXED))\n    old = 0;\n}\n/// locks for atomic operations\nstatic Lock locks[SPINLOCK_COUNT];\n#endif\n\n\n/// Returns a lock to use for a given pointer.  \nstatic __inline Lock *lock_for_pointer(void *ptr) {\n  intptr_t hash = (intptr_t)ptr;\n  // Disregard the lowest 4 bits.  We want all values that may be part of the\n  // same memory operation to hash to the same value and therefore use the same\n  // lock.  \n  hash >>= 4;\n  // Use the next bits as the basis for the hash\n  intptr_t low = hash & SPINLOCK_MASK;\n  // Now use the high(er) set of bits to perturb the hash, so that we don't\n  // get collisions from atomic fields in a single object\n  hash >>= 16;\n  hash ^= low;\n  // Return a pointer to the word to use\n  return locks + (hash & SPINLOCK_MASK);\n}\n\n/// Macros for determining whether a size is lock free.  Clang can not yet\n/// codegen __atomic_is_lock_free(16), so for now we assume 16-byte values are\n/// not lock free.\n#define IS_LOCK_FREE_1 __c11_atomic_is_lock_free(1)\n#define IS_LOCK_FREE_2 __c11_atomic_is_lock_free(2)\n#define IS_LOCK_FREE_4 __c11_atomic_is_lock_free(4)\n#define IS_LOCK_FREE_8 __c11_atomic_is_lock_free(8)\n#define IS_LOCK_FREE_16 0\n\n/// Macro that calls the compiler-generated lock-free versions of functions\n/// when they exist.\n#define LOCK_FREE_CASES() \\\n  do {\\\n  switch (size) {\\\n    case 2:\\\n      if (IS_LOCK_FREE_2) {\\\n        LOCK_FREE_ACTION(uint16_t);\\\n      }\\\n    case 4:\\\n      if (IS_LOCK_FREE_4) {\\\n        LOCK_FREE_ACTION(uint32_t);\\\n      }\\\n    case 8:\\\n      if (IS_LOCK_FREE_8) {\\\n        LOCK_FREE_ACTION(uint64_t);\\\n      }\\\n    case 16:\\\n      if (IS_LOCK_FREE_16) {\\\n        /* FIXME: __uint128_t isn't available on 32 bit platforms.\n        LOCK_FREE_ACTION(__uint128_t);*/\\\n      }\\\n  }\\\n  } while (0)\n\n\n/// An atomic load operation.  This is atomic with respect to the source\n/// pointer only.\nvoid __atomic_load_c(int size, void *src, void *dest, int model) {\n#define LOCK_FREE_ACTION(type) \\\n    *((type*)dest) = __c11_atomic_load((_Atomic(type)*)src, model);\\\n    return;\n  LOCK_FREE_CASES();\n#undef LOCK_FREE_ACTION\n  Lock *l = lock_for_pointer(src);\n  lock(l);\n  memcpy(dest, src, size);\n  unlock(l);\n}\n\n/// An atomic store operation.  This is atomic with respect to the destination\n/// pointer only.\nvoid __atomic_store_c(int size, void *dest, void *src, int model) {\n#define LOCK_FREE_ACTION(type) \\\n    __c11_atomic_store((_Atomic(type)*)dest, *(type*)dest, model);\\\n    return;\n  LOCK_FREE_CASES();\n#undef LOCK_FREE_ACTION\n  Lock *l = lock_for_pointer(dest);\n  lock(l);\n  memcpy(dest, src, size);\n  unlock(l);\n}\n\n/// Atomic compare and exchange operation.  If the value at *ptr is identical\n/// to the value at *expected, then this copies value at *desired to *ptr.  If\n/// they  are not, then this stores the current value from *ptr in *expected.\n///\n/// This function returns 1 if the exchange takes place or 0 if it fails. \nint __atomic_compare_exchange_c(int size, void *ptr, void *expected,\n    void *desired, int success, int failure) {\n#define LOCK_FREE_ACTION(type) \\\n  return __c11_atomic_compare_exchange_strong((_Atomic(type)*)ptr, (type*)expected,\\\n      *(type*)desired, success, failure)\n  LOCK_FREE_CASES();\n#undef LOCK_FREE_ACTION\n  Lock *l = lock_for_pointer(ptr);\n  lock(l);\n  if (memcmp(ptr, expected, size) == 0) {\n    memcpy(ptr, desired, size);\n    unlock(l);\n    return 1;\n  }\n  memcpy(expected, ptr, size);\n  unlock(l);\n  return 0;\n}\n\n/// Performs an atomic exchange operation between two pointers.  This is atomic\n/// with respect to the target address.\nvoid __atomic_exchange_c(int size, void *ptr, void *val, void *old, int model) {\n#define LOCK_FREE_ACTION(type) \\\n    *(type*)old = __c11_atomic_exchange((_Atomic(type)*)ptr, *(type*)val,\\\n        model);\\\n    return;\n  LOCK_FREE_CASES();\n#undef LOCK_FREE_ACTION\n  Lock *l = lock_for_pointer(ptr);\n  lock(l);\n  memcpy(old, ptr, size);\n  memcpy(ptr, val, size);\n  unlock(l);\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Where the size is known at compile time, the compiler may emit calls to\n// specialised versions of the above functions.\n////////////////////////////////////////////////////////////////////////////////\n#define OPTIMISED_CASES\\\n  OPTIMISED_CASE(1, IS_LOCK_FREE_1, uint8_t)\\\n  OPTIMISED_CASE(2, IS_LOCK_FREE_2, uint16_t)\\\n  OPTIMISED_CASE(4, IS_LOCK_FREE_4, uint32_t)\\\n  OPTIMISED_CASE(8, IS_LOCK_FREE_8, uint64_t)\\\n  /* FIXME: __uint128_t isn't available on 32 bit platforms.\n  OPTIMISED_CASE(16, IS_LOCK_FREE_16, __uint128_t)*/\\\n\n#define OPTIMISED_CASE(n, lockfree, type)\\\ntype __atomic_load_##n(type *src, int model) {\\\n  if (lockfree)\\\n    return __c11_atomic_load((_Atomic(type)*)src, model);\\\n  Lock *l = lock_for_pointer(src);\\\n  lock(l);\\\n  type val = *src;\\\n  unlock(l);\\\n  return val;\\\n}\nOPTIMISED_CASES\n#undef OPTIMISED_CASE\n\n#define OPTIMISED_CASE(n, lockfree, type)\\\nvoid  __atomic_store_##n(type *dest, type val, int model) {\\\n  if (lockfree) {\\\n    __c11_atomic_store((_Atomic(type)*)dest, val, model);\\\n    return;\\\n  }\\\n  Lock *l = lock_for_pointer(dest);\\\n  lock(l);\\\n  *dest = val;\\\n  unlock(l);\\\n  return;\\\n}\nOPTIMISED_CASES\n#undef OPTIMISED_CASE\n\n#define OPTIMISED_CASE(n, lockfree, type)\\\ntype __atomic_exchange_##n(type *dest, type val, int model) {\\\n  if (lockfree)\\\n    return __c11_atomic_exchange((_Atomic(type)*)dest, val, model);\\\n  Lock *l = lock_for_pointer(dest);\\\n  lock(l);\\\n  type tmp = *dest;\\\n  *dest = val;\\\n  unlock(l);\\\n  return tmp;\\\n}\nOPTIMISED_CASES\n#undef OPTIMISED_CASE\n\n#define OPTIMISED_CASE(n, lockfree, type)\\\nint __atomic_compare_exchange_##n(type *ptr, type *expected, type desired,\\\n    int success, int failure) {\\\n  if (lockfree)\\\n    return __c11_atomic_compare_exchange_strong((_Atomic(type)*)ptr, expected, desired,\\\n        success, failure);\\\n  Lock *l = lock_for_pointer(ptr);\\\n  lock(l);\\\n  if (*ptr == *expected) {\\\n    *ptr = desired;\\\n    unlock(l);\\\n    return 1;\\\n  }\\\n  *expected = *ptr;\\\n  unlock(l);\\\n  return 0;\\\n}\nOPTIMISED_CASES\n#undef OPTIMISED_CASE\n\n////////////////////////////////////////////////////////////////////////////////\n// Atomic read-modify-write operations for integers of various sizes.\n////////////////////////////////////////////////////////////////////////////////\n#define ATOMIC_RMW(n, lockfree, type, opname, op) \\\ntype __atomic_fetch_##opname##_##n(type *ptr, type val, int model) {\\\n  if (lockfree) \\\n    return __c11_atomic_fetch_##opname((_Atomic(type)*)ptr, val, model);\\\n  Lock *l = lock_for_pointer(ptr);\\\n  lock(l);\\\n  type tmp = *ptr;\\\n  *ptr = tmp op val;\\\n  unlock(l);\\\n  return tmp;\\\n}\n\n#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, add, +)\nOPTIMISED_CASES\n#undef OPTIMISED_CASE\n#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, sub, -)\nOPTIMISED_CASES\n#undef OPTIMISED_CASE\n#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, and, &)\nOPTIMISED_CASES\n#undef OPTIMISED_CASE\n#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, or, |)\nOPTIMISED_CASES\n#undef OPTIMISED_CASE\n#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, xor, ^)\nOPTIMISED_CASES\n#undef OPTIMISED_CASE\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/atomic_flag_clear.c",
    "content": "/*===-- atomic_flag_clear.c -------------------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===------------------------------------------------------------------------===\n *\n * This file implements atomic_flag_clear from C11's stdatomic.h.\n *\n *===------------------------------------------------------------------------===\n */\n\n#ifndef __has_include\n#define __has_include(inc) 0\n#endif\n\n#if __has_include(<stdatomic.h>)\n\n#include <stdatomic.h>\n#undef atomic_flag_clear\nvoid atomic_flag_clear(volatile atomic_flag *object) {\n  __c11_atomic_store(&(object)->_Value, 0, __ATOMIC_SEQ_CST);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/atomic_flag_clear_explicit.c",
    "content": "/*===-- atomic_flag_clear_explicit.c ----------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===------------------------------------------------------------------------===\n *\n * This file implements atomic_flag_clear_explicit from C11's stdatomic.h.\n *\n *===------------------------------------------------------------------------===\n */\n\n#ifndef __has_include\n#define __has_include(inc) 0\n#endif\n\n#if __has_include(<stdatomic.h>)\n\n#include <stdatomic.h>\n#undef atomic_flag_clear_explicit\nvoid atomic_flag_clear_explicit(volatile atomic_flag *object,\n                                memory_order order) {\n  __c11_atomic_store(&(object)->_Value, 0, order);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/atomic_flag_test_and_set.c",
    "content": "/*===-- atomic_flag_test_and_set.c ------------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===------------------------------------------------------------------------===\n *\n * This file implements atomic_flag_test_and_set from C11's stdatomic.h.\n *\n *===------------------------------------------------------------------------===\n */\n\n#ifndef __has_include\n#define __has_include(inc) 0\n#endif\n\n#if __has_include(<stdatomic.h>)\n\n#include <stdatomic.h>\n#undef atomic_flag_test_and_set\n_Bool atomic_flag_test_and_set(volatile atomic_flag *object) {\n  return __c11_atomic_exchange(&(object)->_Value, 1, __ATOMIC_SEQ_CST);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/atomic_flag_test_and_set_explicit.c",
    "content": "/*===-- atomic_flag_test_and_set_explicit.c ---------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===------------------------------------------------------------------------===\n *\n * This file implements atomic_flag_test_and_set_explicit from C11's stdatomic.h\n *\n *===------------------------------------------------------------------------===\n */\n\n#ifndef __has_include\n#define __has_include(inc) 0\n#endif\n\n#if __has_include(<stdatomic.h>)\n\n#include <stdatomic.h>\n#undef atomic_flag_test_and_set_explicit\n_Bool atomic_flag_test_and_set_explicit(volatile atomic_flag *object,\n                                        memory_order order) {\n  return __c11_atomic_exchange(&(object)->_Value, 1, order);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/atomic_signal_fence.c",
    "content": "/*===-- atomic_signal_fence.c -----------------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===------------------------------------------------------------------------===\n *\n * This file implements atomic_signal_fence from C11's stdatomic.h.\n *\n *===------------------------------------------------------------------------===\n */\n\n#ifndef __has_include\n#define __has_include(inc) 0\n#endif\n\n#if __has_include(<stdatomic.h>)\n\n#include <stdatomic.h>\n#undef atomic_signal_fence\nvoid atomic_signal_fence(memory_order order) {\n  __c11_atomic_signal_fence(order);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/atomic_thread_fence.c",
    "content": "/*===-- atomic_thread_fence.c -----------------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===------------------------------------------------------------------------===\n *\n * This file implements atomic_thread_fence from C11's stdatomic.h.\n *\n *===------------------------------------------------------------------------===\n */\n\n#ifndef __has_include\n#define __has_include(inc) 0\n#endif\n\n#if __has_include(<stdatomic.h>)\n\n#include <stdatomic.h>\n#undef atomic_thread_fence\nvoid atomic_thread_fence(memory_order order) {\n  __c11_atomic_thread_fence(order);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/clear_cache.c",
    "content": "/* ===-- clear_cache.c - Implement __clear_cache ---------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n#include <stddef.h>\n\n#if __APPLE__\n  #include <libkern/OSCacheControl.h>\n#endif\n#if (defined(__FreeBSD__) || defined(__Bitrig__)) && defined(__arm__)\n  #include <sys/types.h>\n  #include <machine/sysarch.h>\n#endif\n\n#if defined(__NetBSD__) && defined(__arm__)\n  #include <machine/sysarch.h>\n#endif\n\n#if defined(__mips__)\n  #include <sys/cachectl.h>\n  #include <sys/syscall.h>\n  #include <unistd.h>\n  #if defined(__ANDROID__) && defined(__LP64__)\n    /*\n     * clear_mips_cache - Invalidates instruction cache for Mips.\n     */\n    static void clear_mips_cache(const void* Addr, size_t Size) {\n      asm volatile (\n        \".set push\\n\"\n        \".set noreorder\\n\"\n        \".set noat\\n\"\n        \"beq %[Size], $zero, 20f\\n\"          /* If size == 0, branch around. */\n        \"nop\\n\"\n        \"daddu %[Size], %[Addr], %[Size]\\n\"  /* Calculate end address + 1 */\n        \"rdhwr $v0, $1\\n\"                    /* Get step size for SYNCI.\n                                                $1 is $HW_SYNCI_Step */\n        \"beq $v0, $zero, 20f\\n\"              /* If no caches require\n                                                synchronization, branch\n                                                around. */\n        \"nop\\n\"\n        \"10:\\n\"\n        \"synci 0(%[Addr])\\n\"                 /* Synchronize all caches around\n                                                address. */\n        \"daddu %[Addr], %[Addr], $v0\\n\"      /* Add step size. */\n        \"sltu $at, %[Addr], %[Size]\\n\"       /* Compare current with end\n                                                address. */\n        \"bne $at, $zero, 10b\\n\"              /* Branch if more to do. */\n        \"nop\\n\"\n        \"sync\\n\"                             /* Clear memory hazards. */\n        \"20:\\n\"\n        \"bal 30f\\n\"\n        \"nop\\n\"\n        \"30:\\n\"\n        \"daddiu $ra, $ra, 12\\n\"              /* $ra has a value of $pc here.\n                                                Add offset of 12 to point to the\n                                                instruction after the last nop.\n                                              */\n        \"jr.hb $ra\\n\"                        /* Return, clearing instruction\n                                                hazards. */\n        \"nop\\n\"\n        \".set pop\\n\"\n        : [Addr] \"+r\"(Addr), [Size] \"+r\"(Size)\n        :: \"at\", \"ra\", \"v0\", \"memory\"\n      );\n    }\n  #endif\n#endif\n\n#if defined(__ANDROID__) && defined(__arm__)\n  #include <asm/unistd.h>\n#endif\n\n/*\n * The compiler generates calls to __clear_cache() when creating \n * trampoline functions on the stack for use with nested functions.\n * It is expected to invalidate the instruction cache for the \n * specified range.\n */\n\nvoid __clear_cache(void *start, void *end) {\n#if __i386__ || __x86_64__\n/*\n * Intel processors have a unified instruction and data cache\n * so there is nothing to do\n */\n#elif defined(__arm__) && !defined(__APPLE__)\n    #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__Bitrig__)\n        struct arm_sync_icache_args arg;\n\n        arg.addr = (uintptr_t)start;\n        arg.len = (uintptr_t)end - (uintptr_t)start;\n\n        sysarch(ARM_SYNC_ICACHE, &arg);\n    #elif defined(__ANDROID__)\n         register int start_reg __asm(\"r0\") = (int) (intptr_t) start;\n         const register int end_reg __asm(\"r1\") = (int) (intptr_t) end;\n         const register int flags __asm(\"r2\") = 0;\n         const register int syscall_nr __asm(\"r7\") = __ARM_NR_cacheflush;\n        __asm __volatile(\"svc 0x0\" : \"=r\"(start_reg)\n            : \"r\"(syscall_nr), \"r\"(start_reg), \"r\"(end_reg), \"r\"(flags) : \"r0\");\n         if (start_reg != 0) {\n             compilerrt_abort();\n         }\n    #else\n        compilerrt_abort();\n    #endif\n#elif defined(__mips__)\n  const uintptr_t start_int = (uintptr_t) start;\n  const uintptr_t end_int = (uintptr_t) end;\n    #if defined(__ANDROID__) && defined(__LP64__)\n        // Call synci implementation for short address range.\n        const uintptr_t address_range_limit = 256;\n        if ((end_int - start_int) <= address_range_limit) {\n            clear_mips_cache(start, (end_int - start_int));\n        } else {\n            syscall(__NR_cacheflush, start, (end_int - start_int), BCACHE);\n        }\n    #else\n        syscall(__NR_cacheflush, start, (end_int - start_int), BCACHE);\n    #endif\n#elif defined(__aarch64__) && !defined(__APPLE__)\n  uint64_t xstart = (uint64_t)(uintptr_t) start;\n  uint64_t xend = (uint64_t)(uintptr_t) end;\n  uint64_t addr;\n\n  // Get Cache Type Info\n  uint64_t ctr_el0;\n  __asm __volatile(\"mrs %0, ctr_el0\" : \"=r\"(ctr_el0));\n\n  /*\n   * dc & ic instructions must use 64bit registers so we don't use\n   * uintptr_t in case this runs in an IPL32 environment.\n   */\n  const size_t dcache_line_size = 4 << ((ctr_el0 >> 16) & 15);\n  for (addr = xstart; addr < xend; addr += dcache_line_size)\n    __asm __volatile(\"dc cvau, %0\" :: \"r\"(addr));\n  __asm __volatile(\"dsb ish\");\n\n  const size_t icache_line_size = 4 << ((ctr_el0 >> 0) & 15);\n  for (addr = xstart; addr < xend; addr += icache_line_size)\n    __asm __volatile(\"ic ivau, %0\" :: \"r\"(addr));\n  __asm __volatile(\"isb sy\");\n#else\n    #if __APPLE__\n        /* On Darwin, sys_icache_invalidate() provides this functionality */\n        sys_icache_invalidate(start, end-start);\n    #else\n        compilerrt_abort();\n    #endif\n#endif\n}\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/clzdi2.c",
    "content": "/* ===-- clzdi2.c - Implement __clzdi2 -------------------------------------===\n *\n *               The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __clzdi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: the number of leading 0-bits */\n\n/* Precondition: a != 0 */\n\nCOMPILER_RT_ABI si_int\n__clzdi2(di_int a)\n{\n    dwords x;\n    x.all = a;\n    const si_int f = -(x.s.high == 0);\n    return __builtin_clz((x.s.high & ~f) | (x.s.low & f)) +\n           (f & ((si_int)(sizeof(si_int) * CHAR_BIT)));\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/clzsi2.c",
    "content": "/* ===-- clzsi2.c - Implement __clzsi2 -------------------------------------===\n *\n *               The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __clzsi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: the number of leading 0-bits */\n\n/* Precondition: a != 0 */\n\nCOMPILER_RT_ABI si_int\n__clzsi2(si_int a)\n{\n    su_int x = (su_int)a;\n    si_int t = ((x & 0xFFFF0000) == 0) << 4;  /* if (x is small) t = 16 else 0 */\n    x >>= 16 - t;      /* x = [0 - 0xFFFF] */\n    su_int r = t;       /* r = [0, 16] */\n    /* return r + clz(x) */\n    t = ((x & 0xFF00) == 0) << 3;\n    x >>= 8 - t;       /* x = [0 - 0xFF] */\n    r += t;            /* r = [0, 8, 16, 24] */\n    /* return r + clz(x) */\n    t = ((x & 0xF0) == 0) << 2;\n    x >>= 4 - t;       /* x = [0 - 0xF] */\n    r += t;            /* r = [0, 4, 8, 12, 16, 20, 24, 28] */\n    /* return r + clz(x) */\n    t = ((x & 0xC) == 0) << 1;\n    x >>= 2 - t;       /* x = [0 - 3] */\n    r += t;            /* r = [0 - 30] and is even */\n    /* return r + clz(x) */\n/*     switch (x)\n *     {\n *     case 0:\n *         return r + 2;\n *     case 1:\n *         return r + 1;\n *     case 2:\n *     case 3:\n *         return r;\n *     }\n */\n    return r + ((2 - x) & -((x & 2) == 0));\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/clzti2.c",
    "content": "/* ===-- clzti2.c - Implement __clzti2 -------------------------------------===\n *\n *      \t       The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __clzti2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: the number of leading 0-bits */\n\n/* Precondition: a != 0 */\n\nCOMPILER_RT_ABI si_int\n__clzti2(ti_int a)\n{\n    twords x;\n    x.all = a;\n    const di_int f = -(x.s.high == 0);\n    return __builtin_clzll((x.s.high & ~f) | (x.s.low & f)) +\n           ((si_int)f & ((si_int)(sizeof(di_int) * CHAR_BIT)));\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/cmpdi2.c",
    "content": "/* ===-- cmpdi2.c - Implement __cmpdi2 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __cmpdi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: if (a <  b) returns 0\n*           if (a == b) returns 1\n*           if (a >  b) returns 2\n*/\n\nCOMPILER_RT_ABI si_int\n__cmpdi2(di_int a, di_int b)\n{\n    dwords x;\n    x.all = a;\n    dwords y;\n    y.all = b;\n    if (x.s.high < y.s.high)\n        return 0;\n    if (x.s.high > y.s.high)\n        return 2;\n    if (x.s.low < y.s.low)\n        return 0;\n    if (x.s.low > y.s.low)\n        return 2;\n    return 1;\n}\n\n#ifdef __ARM_EABI__\n/* Returns: if (a <  b) returns -1\n*           if (a == b) returns  0\n*           if (a >  b) returns  1\n*/\nCOMPILER_RT_ABI si_int\n__aeabi_lcmp(di_int a, di_int b)\n{\n\treturn __cmpdi2(a, b) - 1;\n}\n#endif\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/cmpti2.c",
    "content": "/* ===-- cmpti2.c - Implement __cmpti2 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __cmpti2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns:  if (a <  b) returns 0\n *           if (a == b) returns 1\n *           if (a >  b) returns 2\n */\n\nCOMPILER_RT_ABI si_int\n__cmpti2(ti_int a, ti_int b)\n{\n    twords x;\n    x.all = a;\n    twords y;\n    y.all = b;\n    if (x.s.high < y.s.high)\n        return 0;\n    if (x.s.high > y.s.high)\n        return 2;\n    if (x.s.low < y.s.low)\n        return 0;\n    if (x.s.low > y.s.low)\n        return 2;\n    return 1;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/comparedf2.c",
    "content": "//===-- lib/comparedf2.c - Double-precision comparisons -----------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// // This file implements the following soft-float comparison routines:\n//\n//   __eqdf2   __gedf2   __unorddf2\n//   __ledf2   __gtdf2\n//   __ltdf2\n//   __nedf2\n//\n// The semantics of the routines grouped in each column are identical, so there\n// is a single implementation for each, and wrappers to provide the other names.\n//\n// The main routines behave as follows:\n//\n//   __ledf2(a,b) returns -1 if a < b\n//                         0 if a == b\n//                         1 if a > b\n//                         1 if either a or b is NaN\n//\n//   __gedf2(a,b) returns -1 if a < b\n//                         0 if a == b\n//                         1 if a > b\n//                        -1 if either a or b is NaN\n//\n//   __unorddf2(a,b) returns 0 if both a and b are numbers\n//                           1 if either a or b is NaN\n//\n// Note that __ledf2( ) and __gedf2( ) are identical except in their handling of\n// NaN values.\n//\n//===----------------------------------------------------------------------===//\n\n#define DOUBLE_PRECISION\n#include \"fp_lib.h\"\n\nenum LE_RESULT {\n    LE_LESS      = -1,\n    LE_EQUAL     =  0,\n    LE_GREATER   =  1,\n    LE_UNORDERED =  1\n};\n\nCOMPILER_RT_ABI enum LE_RESULT\n__ledf2(fp_t a, fp_t b) {\n    \n    const srep_t aInt = toRep(a);\n    const srep_t bInt = toRep(b);\n    const rep_t aAbs = aInt & absMask;\n    const rep_t bAbs = bInt & absMask;\n    \n    // If either a or b is NaN, they are unordered.\n    if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED;\n    \n    // If a and b are both zeros, they are equal.\n    if ((aAbs | bAbs) == 0) return LE_EQUAL;\n    \n    // If at least one of a and b is positive, we get the same result comparing\n    // a and b as signed integers as we would with a floating-point compare.\n    if ((aInt & bInt) >= 0) {\n        if (aInt < bInt) return LE_LESS;\n        else if (aInt == bInt) return LE_EQUAL;\n        else return LE_GREATER;\n    }\n    \n    // Otherwise, both are negative, so we need to flip the sense of the\n    // comparison to get the correct result.  (This assumes a twos- or ones-\n    // complement integer representation; if integers are represented in a\n    // sign-magnitude representation, then this flip is incorrect).\n    else {\n        if (aInt > bInt) return LE_LESS;\n        else if (aInt == bInt) return LE_EQUAL;\n        else return LE_GREATER;\n    }\n}\n\n#if defined(__ELF__)\n// Alias for libgcc compatibility\nFNALIAS(__cmpdf2, __ledf2);\n#endif\n\nenum GE_RESULT {\n    GE_LESS      = -1,\n    GE_EQUAL     =  0,\n    GE_GREATER   =  1,\n    GE_UNORDERED = -1   // Note: different from LE_UNORDERED\n};\n\nCOMPILER_RT_ABI enum GE_RESULT\n__gedf2(fp_t a, fp_t b) {\n    \n    const srep_t aInt = toRep(a);\n    const srep_t bInt = toRep(b);\n    const rep_t aAbs = aInt & absMask;\n    const rep_t bAbs = bInt & absMask;\n    \n    if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED;\n    if ((aAbs | bAbs) == 0) return GE_EQUAL;\n    if ((aInt & bInt) >= 0) {\n        if (aInt < bInt) return GE_LESS;\n        else if (aInt == bInt) return GE_EQUAL;\n        else return GE_GREATER;\n    } else {\n        if (aInt > bInt) return GE_LESS;\n        else if (aInt == bInt) return GE_EQUAL;\n        else return GE_GREATER;\n    }\n}\n\nARM_EABI_FNALIAS(dcmpun, unorddf2)\n\nCOMPILER_RT_ABI int\n__unorddf2(fp_t a, fp_t b) {\n    const rep_t aAbs = toRep(a) & absMask;\n    const rep_t bAbs = toRep(b) & absMask;\n    return aAbs > infRep || bAbs > infRep;\n}\n\n// The following are alternative names for the preceding routines.\n\nCOMPILER_RT_ABI enum LE_RESULT\n__eqdf2(fp_t a, fp_t b) {\n    return __ledf2(a, b);\n}\n\nCOMPILER_RT_ABI enum LE_RESULT\n__ltdf2(fp_t a, fp_t b) {\n    return __ledf2(a, b);\n}\n\nCOMPILER_RT_ABI enum LE_RESULT\n__nedf2(fp_t a, fp_t b) {\n    return __ledf2(a, b);\n}\n\nCOMPILER_RT_ABI enum GE_RESULT\n__gtdf2(fp_t a, fp_t b) {\n    return __gedf2(a, b);\n}\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/comparesf2.c",
    "content": "//===-- lib/comparesf2.c - Single-precision comparisons -----------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements the following soft-fp_t comparison routines:\n//\n//   __eqsf2   __gesf2   __unordsf2\n//   __lesf2   __gtsf2\n//   __ltsf2\n//   __nesf2\n//\n// The semantics of the routines grouped in each column are identical, so there\n// is a single implementation for each, and wrappers to provide the other names.\n//\n// The main routines behave as follows:\n//\n//   __lesf2(a,b) returns -1 if a < b\n//                         0 if a == b\n//                         1 if a > b\n//                         1 if either a or b is NaN\n//\n//   __gesf2(a,b) returns -1 if a < b\n//                         0 if a == b\n//                         1 if a > b\n//                        -1 if either a or b is NaN\n//\n//   __unordsf2(a,b) returns 0 if both a and b are numbers\n//                           1 if either a or b is NaN\n//\n// Note that __lesf2( ) and __gesf2( ) are identical except in their handling of\n// NaN values.\n//\n//===----------------------------------------------------------------------===//\n\n#define SINGLE_PRECISION\n#include \"fp_lib.h\"\n\nenum LE_RESULT {\n    LE_LESS      = -1,\n    LE_EQUAL     =  0,\n    LE_GREATER   =  1,\n    LE_UNORDERED =  1\n};\n\nCOMPILER_RT_ABI enum LE_RESULT\n__lesf2(fp_t a, fp_t b) {\n    \n    const srep_t aInt = toRep(a);\n    const srep_t bInt = toRep(b);\n    const rep_t aAbs = aInt & absMask;\n    const rep_t bAbs = bInt & absMask;\n    \n    // If either a or b is NaN, they are unordered.\n    if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED;\n    \n    // If a and b are both zeros, they are equal.\n    if ((aAbs | bAbs) == 0) return LE_EQUAL;\n    \n    // If at least one of a and b is positive, we get the same result comparing\n    // a and b as signed integers as we would with a fp_ting-point compare.\n    if ((aInt & bInt) >= 0) {\n        if (aInt < bInt) return LE_LESS;\n        else if (aInt == bInt) return LE_EQUAL;\n        else return LE_GREATER;\n    }\n    \n    // Otherwise, both are negative, so we need to flip the sense of the\n    // comparison to get the correct result.  (This assumes a twos- or ones-\n    // complement integer representation; if integers are represented in a\n    // sign-magnitude representation, then this flip is incorrect).\n    else {\n        if (aInt > bInt) return LE_LESS;\n        else if (aInt == bInt) return LE_EQUAL;\n        else return LE_GREATER;\n    }\n}\n\n#if defined(__ELF__)\n// Alias for libgcc compatibility\nFNALIAS(__cmpsf2, __lesf2);\n#endif\n\nenum GE_RESULT {\n    GE_LESS      = -1,\n    GE_EQUAL     =  0,\n    GE_GREATER   =  1,\n    GE_UNORDERED = -1   // Note: different from LE_UNORDERED\n};\n\nCOMPILER_RT_ABI enum GE_RESULT\n__gesf2(fp_t a, fp_t b) {\n    \n    const srep_t aInt = toRep(a);\n    const srep_t bInt = toRep(b);\n    const rep_t aAbs = aInt & absMask;\n    const rep_t bAbs = bInt & absMask;\n    \n    if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED;\n    if ((aAbs | bAbs) == 0) return GE_EQUAL;\n    if ((aInt & bInt) >= 0) {\n        if (aInt < bInt) return GE_LESS;\n        else if (aInt == bInt) return GE_EQUAL;\n        else return GE_GREATER;\n    } else {\n        if (aInt > bInt) return GE_LESS;\n        else if (aInt == bInt) return GE_EQUAL;\n        else return GE_GREATER;\n    }\n}\n\nARM_EABI_FNALIAS(fcmpun, unordsf2)\n\nCOMPILER_RT_ABI int\n__unordsf2(fp_t a, fp_t b) {\n    const rep_t aAbs = toRep(a) & absMask;\n    const rep_t bAbs = toRep(b) & absMask;\n    return aAbs > infRep || bAbs > infRep;\n}\n\n// The following are alternative names for the preceding routines.\n\nCOMPILER_RT_ABI enum LE_RESULT\n__eqsf2(fp_t a, fp_t b) {\n    return __lesf2(a, b);\n}\n\nCOMPILER_RT_ABI enum LE_RESULT\n__ltsf2(fp_t a, fp_t b) {\n    return __lesf2(a, b);\n}\n\nCOMPILER_RT_ABI enum LE_RESULT\n__nesf2(fp_t a, fp_t b) {\n    return __lesf2(a, b);\n}\n\nCOMPILER_RT_ABI enum GE_RESULT\n__gtsf2(fp_t a, fp_t b) {\n    return __gesf2(a, b);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/comparetf2.c",
    "content": "//===-- lib/comparetf2.c - Quad-precision comparisons -------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// // This file implements the following soft-float comparison routines:\n//\n//   __eqtf2   __getf2   __unordtf2\n//   __letf2   __gttf2\n//   __lttf2\n//   __netf2\n//\n// The semantics of the routines grouped in each column are identical, so there\n// is a single implementation for each, and wrappers to provide the other names.\n//\n// The main routines behave as follows:\n//\n//   __letf2(a,b) returns -1 if a < b\n//                         0 if a == b\n//                         1 if a > b\n//                         1 if either a or b is NaN\n//\n//   __getf2(a,b) returns -1 if a < b\n//                         0 if a == b\n//                         1 if a > b\n//                        -1 if either a or b is NaN\n//\n//   __unordtf2(a,b) returns 0 if both a and b are numbers\n//                           1 if either a or b is NaN\n//\n// Note that __letf2( ) and __getf2( ) are identical except in their handling of\n// NaN values.\n//\n//===----------------------------------------------------------------------===//\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\nenum LE_RESULT {\n    LE_LESS      = -1,\n    LE_EQUAL     =  0,\n    LE_GREATER   =  1,\n    LE_UNORDERED =  1\n};\n\nCOMPILER_RT_ABI enum LE_RESULT __letf2(fp_t a, fp_t b) {\n\n    const srep_t aInt = toRep(a);\n    const srep_t bInt = toRep(b);\n    const rep_t aAbs = aInt & absMask;\n    const rep_t bAbs = bInt & absMask;\n\n    // If either a or b is NaN, they are unordered.\n    if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED;\n\n    // If a and b are both zeros, they are equal.\n    if ((aAbs | bAbs) == 0) return LE_EQUAL;\n\n    // If at least one of a and b is positive, we get the same result comparing\n    // a and b as signed integers as we would with a floating-point compare.\n    if ((aInt & bInt) >= 0) {\n        if (aInt < bInt) return LE_LESS;\n        else if (aInt == bInt) return LE_EQUAL;\n        else return LE_GREATER;\n    }\n    else {\n        // Otherwise, both are negative, so we need to flip the sense of the\n        // comparison to get the correct result.  (This assumes a twos- or ones-\n        // complement integer representation; if integers are represented in a\n        // sign-magnitude representation, then this flip is incorrect).\n        if (aInt > bInt) return LE_LESS;\n        else if (aInt == bInt) return LE_EQUAL;\n        else return LE_GREATER;\n    }\n}\n\n#if defined(__ELF__)\n// Alias for libgcc compatibility\nFNALIAS(__cmptf2, __letf2);\n#endif\n\nenum GE_RESULT {\n    GE_LESS      = -1,\n    GE_EQUAL     =  0,\n    GE_GREATER   =  1,\n    GE_UNORDERED = -1   // Note: different from LE_UNORDERED\n};\n\nCOMPILER_RT_ABI enum GE_RESULT __getf2(fp_t a, fp_t b) {\n\n    const srep_t aInt = toRep(a);\n    const srep_t bInt = toRep(b);\n    const rep_t aAbs = aInt & absMask;\n    const rep_t bAbs = bInt & absMask;\n\n    if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED;\n    if ((aAbs | bAbs) == 0) return GE_EQUAL;\n    if ((aInt & bInt) >= 0) {\n        if (aInt < bInt) return GE_LESS;\n        else if (aInt == bInt) return GE_EQUAL;\n        else return GE_GREATER;\n    } else {\n        if (aInt > bInt) return GE_LESS;\n        else if (aInt == bInt) return GE_EQUAL;\n        else return GE_GREATER;\n    }\n}\n\nCOMPILER_RT_ABI int __unordtf2(fp_t a, fp_t b) {\n    const rep_t aAbs = toRep(a) & absMask;\n    const rep_t bAbs = toRep(b) & absMask;\n    return aAbs > infRep || bAbs > infRep;\n}\n\n// The following are alternative names for the preceding routines.\n\nCOMPILER_RT_ABI enum LE_RESULT __eqtf2(fp_t a, fp_t b) {\n    return __letf2(a, b);\n}\n\nCOMPILER_RT_ABI enum LE_RESULT __lttf2(fp_t a, fp_t b) {\n    return __letf2(a, b);\n}\n\nCOMPILER_RT_ABI enum LE_RESULT __netf2(fp_t a, fp_t b) {\n    return __letf2(a, b);\n}\n\nCOMPILER_RT_ABI enum GE_RESULT __gttf2(fp_t a, fp_t b) {\n    return __getf2(a, b);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ctzdi2.c",
    "content": "/* ===-- ctzdi2.c - Implement __ctzdi2 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __ctzdi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: the number of trailing 0-bits  */\n\n/* Precondition: a != 0 */\n\nCOMPILER_RT_ABI si_int\n__ctzdi2(di_int a)\n{\n    dwords x;\n    x.all = a;\n    const si_int f = -(x.s.low == 0);\n    return __builtin_ctz((x.s.high & f) | (x.s.low & ~f)) +\n              (f & ((si_int)(sizeof(si_int) * CHAR_BIT)));\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ctzsi2.c",
    "content": "/* ===-- ctzsi2.c - Implement __ctzsi2 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __ctzsi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: the number of trailing 0-bits */\n\n/* Precondition: a != 0 */\n\nCOMPILER_RT_ABI si_int\n__ctzsi2(si_int a)\n{\n    su_int x = (su_int)a;\n    si_int t = ((x & 0x0000FFFF) == 0) << 4;  /* if (x has no small bits) t = 16 else 0 */\n    x >>= t;           /* x = [0 - 0xFFFF] + higher garbage bits */\n    su_int r = t;       /* r = [0, 16]  */\n    /* return r + ctz(x) */\n    t = ((x & 0x00FF) == 0) << 3;\n    x >>= t;           /* x = [0 - 0xFF] + higher garbage bits */\n    r += t;            /* r = [0, 8, 16, 24] */\n    /* return r + ctz(x) */\n    t = ((x & 0x0F) == 0) << 2;\n    x >>= t;           /* x = [0 - 0xF] + higher garbage bits */\n    r += t;            /* r = [0, 4, 8, 12, 16, 20, 24, 28] */\n    /* return r + ctz(x) */\n    t = ((x & 0x3) == 0) << 1;\n    x >>= t;\n    x &= 3;            /* x = [0 - 3] */\n    r += t;            /* r = [0 - 30] and is even */\n    /* return r + ctz(x) */\n\n/*  The branch-less return statement below is equivalent\n *  to the following switch statement:\n *     switch (x)\n *    {\n *     case 0:\n *         return r + 2;\n *     case 2:\n *         return r + 1;\n *     case 1:\n *     case 3:\n *         return r;\n *     }\n */\n    return r + ((2 - (x >> 1)) & -((x & 1) == 0));\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ctzti2.c",
    "content": "/* ===-- ctzti2.c - Implement __ctzti2 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __ctzti2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: the number of trailing 0-bits */\n\n/* Precondition: a != 0 */\n\nCOMPILER_RT_ABI si_int\n__ctzti2(ti_int a)\n{\n    twords x;\n    x.all = a;\n    const di_int f = -(x.s.low == 0);\n    return __builtin_ctzll((x.s.high & f) | (x.s.low & ~f)) +\n              ((si_int)f & ((si_int)(sizeof(di_int) * CHAR_BIT)));\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/divdc3.c",
    "content": "/* ===-- divdc3.c - Implement __divdc3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __divdc3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n#include \"int_math.h\"\n\n/* Returns: the quotient of (a + ib) / (c + id) */\n\nCOMPILER_RT_ABI Dcomplex\n__divdc3(double __a, double __b, double __c, double __d)\n{\n    int __ilogbw = 0;\n    double __logbw = crt_logb(crt_fmax(crt_fabs(__c), crt_fabs(__d)));\n    if (crt_isfinite(__logbw))\n    {\n        __ilogbw = (int)__logbw;\n        __c = crt_scalbn(__c, -__ilogbw);\n        __d = crt_scalbn(__d, -__ilogbw);\n    }\n    double __denom = __c * __c + __d * __d;\n    Dcomplex z;\n    COMPLEX_REAL(z) = crt_scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);\n    COMPLEX_IMAGINARY(z) = crt_scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);\n    if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))\n    {\n        if ((__denom == 0.0) && (!crt_isnan(__a) || !crt_isnan(__b)))\n        {\n            COMPLEX_REAL(z) = crt_copysign(CRT_INFINITY, __c) * __a;\n            COMPLEX_IMAGINARY(z) = crt_copysign(CRT_INFINITY, __c) * __b;\n        }\n        else if ((crt_isinf(__a) || crt_isinf(__b)) &&\n                 crt_isfinite(__c) && crt_isfinite(__d))\n        {\n            __a = crt_copysign(crt_isinf(__a) ? 1.0 : 0.0, __a);\n            __b = crt_copysign(crt_isinf(__b) ? 1.0 : 0.0, __b);\n            COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d);\n            COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d);\n        }\n        else if (crt_isinf(__logbw) && __logbw > 0.0 &&\n                 crt_isfinite(__a) && crt_isfinite(__b))\n        {\n            __c = crt_copysign(crt_isinf(__c) ? 1.0 : 0.0, __c);\n            __d = crt_copysign(crt_isinf(__d) ? 1.0 : 0.0, __d);\n            COMPLEX_REAL(z) = 0.0 * (__a * __c + __b * __d);\n            COMPLEX_IMAGINARY(z) = 0.0 * (__b * __c - __a * __d);\n        }\n    }\n    return z;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/divdf3.c",
    "content": "//===-- lib/divdf3.c - Double-precision division ------------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements double-precision soft-float division\n// with the IEEE-754 default rounding (to nearest, ties to even).\n//\n// For simplicity, this implementation currently flushes denormals to zero.\n// It should be a fairly straightforward exercise to implement gradual\n// underflow with correct rounding.\n//\n//===----------------------------------------------------------------------===//\n\n#define DOUBLE_PRECISION\n#include \"fp_lib.h\"\n\nARM_EABI_FNALIAS(ddiv, divdf3)\n\nCOMPILER_RT_ABI fp_t\n__divdf3(fp_t a, fp_t b) {\n    \n    const unsigned int aExponent = toRep(a) >> significandBits & maxExponent;\n    const unsigned int bExponent = toRep(b) >> significandBits & maxExponent;\n    const rep_t quotientSign = (toRep(a) ^ toRep(b)) & signBit;\n    \n    rep_t aSignificand = toRep(a) & significandMask;\n    rep_t bSignificand = toRep(b) & significandMask;\n    int scale = 0;\n    \n    // Detect if a or b is zero, denormal, infinity, or NaN.\n    if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) {\n        \n        const rep_t aAbs = toRep(a) & absMask;\n        const rep_t bAbs = toRep(b) & absMask;\n        \n        // NaN / anything = qNaN\n        if (aAbs > infRep) return fromRep(toRep(a) | quietBit);\n        // anything / NaN = qNaN\n        if (bAbs > infRep) return fromRep(toRep(b) | quietBit);\n        \n        if (aAbs == infRep) {\n            // infinity / infinity = NaN\n            if (bAbs == infRep) return fromRep(qnanRep);\n            // infinity / anything else = +/- infinity\n            else return fromRep(aAbs | quotientSign);\n        }\n        \n        // anything else / infinity = +/- 0\n        if (bAbs == infRep) return fromRep(quotientSign);\n        \n        if (!aAbs) {\n            // zero / zero = NaN\n            if (!bAbs) return fromRep(qnanRep);\n            // zero / anything else = +/- zero\n            else return fromRep(quotientSign);\n        }\n        // anything else / zero = +/- infinity\n        if (!bAbs) return fromRep(infRep | quotientSign);\n        \n        // one or both of a or b is denormal, the other (if applicable) is a\n        // normal number.  Renormalize one or both of a and b, and set scale to\n        // include the necessary exponent adjustment.\n        if (aAbs < implicitBit) scale += normalize(&aSignificand);\n        if (bAbs < implicitBit) scale -= normalize(&bSignificand);\n    }\n    \n    // Or in the implicit significand bit.  (If we fell through from the\n    // denormal path it was already set by normalize( ), but setting it twice\n    // won't hurt anything.)\n    aSignificand |= implicitBit;\n    bSignificand |= implicitBit;\n    int quotientExponent = aExponent - bExponent + scale;\n    \n    // Align the significand of b as a Q31 fixed-point number in the range\n    // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax\n    // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2.  This\n    // is accurate to about 3.5 binary digits.\n    const uint32_t q31b = bSignificand >> 21;\n    uint32_t recip32 = UINT32_C(0x7504f333) - q31b;\n    \n    // Now refine the reciprocal estimate using a Newton-Raphson iteration:\n    //\n    //     x1 = x0 * (2 - x0 * b)\n    //\n    // This doubles the number of correct binary digits in the approximation\n    // with each iteration, so after three iterations, we have about 28 binary\n    // digits of accuracy.\n    uint32_t correction32;\n    correction32 = -((uint64_t)recip32 * q31b >> 32);\n    recip32 = (uint64_t)recip32 * correction32 >> 31;\n    correction32 = -((uint64_t)recip32 * q31b >> 32);\n    recip32 = (uint64_t)recip32 * correction32 >> 31;\n    correction32 = -((uint64_t)recip32 * q31b >> 32);\n    recip32 = (uint64_t)recip32 * correction32 >> 31;\n    \n    // recip32 might have overflowed to exactly zero in the preceding\n    // computation if the high word of b is exactly 1.0.  This would sabotage\n    // the full-width final stage of the computation that follows, so we adjust\n    // recip32 downward by one bit.\n    recip32--;\n    \n    // We need to perform one more iteration to get us to 56 binary digits;\n    // The last iteration needs to happen with extra precision.\n    const uint32_t q63blo = bSignificand << 11;\n    uint64_t correction, reciprocal;\n    correction = -((uint64_t)recip32*q31b + ((uint64_t)recip32*q63blo >> 32));\n    uint32_t cHi = correction >> 32;\n    uint32_t cLo = correction;\n    reciprocal = (uint64_t)recip32*cHi + ((uint64_t)recip32*cLo >> 32);\n    \n    // We already adjusted the 32-bit estimate, now we need to adjust the final\n    // 64-bit reciprocal estimate downward to ensure that it is strictly smaller\n    // than the infinitely precise exact reciprocal.  Because the computation\n    // of the Newton-Raphson step is truncating at every step, this adjustment\n    // is small; most of the work is already done.\n    reciprocal -= 2;\n    \n    // The numerical reciprocal is accurate to within 2^-56, lies in the\n    // interval [0.5, 1.0), and is strictly smaller than the true reciprocal\n    // of b.  Multiplying a by this reciprocal thus gives a numerical q = a/b\n    // in Q53 with the following properties:\n    //\n    //    1. q < a/b\n    //    2. q is in the interval [0.5, 2.0)\n    //    3. the error in q is bounded away from 2^-53 (actually, we have a\n    //       couple of bits to spare, but this is all we need).\n    \n    // We need a 64 x 64 multiply high to compute q, which isn't a basic\n    // operation in C, so we need to be a little bit fussy.\n    rep_t quotient, quotientLo;\n    wideMultiply(aSignificand << 2, reciprocal, &quotient, &quotientLo);\n    \n    // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0).\n    // In either case, we are going to compute a residual of the form\n    //\n    //     r = a - q*b\n    //\n    // We know from the construction of q that r satisfies:\n    //\n    //     0 <= r < ulp(q)*b\n    // \n    // if r is greater than 1/2 ulp(q)*b, then q rounds up.  Otherwise, we\n    // already have the correct result.  The exact halfway case cannot occur.\n    // We also take this time to right shift quotient if it falls in the [1,2)\n    // range and adjust the exponent accordingly.\n    rep_t residual;\n    if (quotient < (implicitBit << 1)) {\n        residual = (aSignificand << 53) - quotient * bSignificand;\n        quotientExponent--;\n    } else {\n        quotient >>= 1;\n        residual = (aSignificand << 52) - quotient * bSignificand;\n    }\n    \n    const int writtenExponent = quotientExponent + exponentBias;\n    \n    if (writtenExponent >= maxExponent) {\n        // If we have overflowed the exponent, return infinity.\n        return fromRep(infRep | quotientSign);\n    }\n    \n    else if (writtenExponent < 1) {\n        // Flush denormals to zero.  In the future, it would be nice to add\n        // code to round them correctly.\n        return fromRep(quotientSign);\n    }\n    \n    else {\n        const bool round = (residual << 1) > bSignificand;\n        // Clear the implicit bit\n        rep_t absResult = quotient & significandMask;\n        // Insert the exponent\n        absResult |= (rep_t)writtenExponent << significandBits;\n        // Round\n        absResult += round;\n        // Insert the sign and return\n        const double result = fromRep(absResult | quotientSign);\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/divdi3.c",
    "content": "/* ===-- divdi3.c - Implement __divdi3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __divdi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a / b */\n\nCOMPILER_RT_ABI di_int\n__divdi3(di_int a, di_int b)\n{\n    const int bits_in_dword_m1 = (int)(sizeof(di_int) * CHAR_BIT) - 1;\n    di_int s_a = a >> bits_in_dword_m1;           /* s_a = a < 0 ? -1 : 0 */\n    di_int s_b = b >> bits_in_dword_m1;           /* s_b = b < 0 ? -1 : 0 */\n    a = (a ^ s_a) - s_a;                         /* negate if s_a == -1 */\n    b = (b ^ s_b) - s_b;                         /* negate if s_b == -1 */\n    s_a ^= s_b;                                  /*sign of quotient */\n    return (__udivmoddi4(a, b, (du_int*)0) ^ s_a) - s_a;  /* negate if s_a == -1 */\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/divmoddi4.c",
    "content": "/*===-- divmoddi4.c - Implement __divmoddi4 --------------------------------===\n *\n *                    The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __divmoddi4 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a / b, *rem = a % b  */\n\nCOMPILER_RT_ABI di_int\n__divmoddi4(di_int a, di_int b, di_int* rem)\n{\n  di_int d = __divdi3(a,b);\n  *rem = a - (d*b);\n  return d;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/divmodsi4.c",
    "content": "/*===-- divmodsi4.c - Implement __divmodsi4 --------------------------------===\n *\n *                    The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __divmodsi4 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a / b, *rem = a % b  */\n\nCOMPILER_RT_ABI si_int\n__divmodsi4(si_int a, si_int b, si_int* rem)\n{\n  si_int d = __divsi3(a,b);\n  *rem = a - (d*b);\n  return d; \n}\n\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/divsc3.c",
    "content": "/*===-- divsc3.c - Implement __divsc3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __divsc3 for the compiler_rt library.\n *\n *===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n#include \"int_math.h\"\n\n/* Returns: the quotient of (a + ib) / (c + id) */\n\nCOMPILER_RT_ABI Fcomplex\n__divsc3(float __a, float __b, float __c, float __d)\n{\n    int __ilogbw = 0;\n    float __logbw = crt_logbf(crt_fmaxf(crt_fabsf(__c), crt_fabsf(__d)));\n    if (crt_isfinite(__logbw))\n    {\n        __ilogbw = (int)__logbw;\n        __c = crt_scalbnf(__c, -__ilogbw);\n        __d = crt_scalbnf(__d, -__ilogbw);\n    }\n    float __denom = __c * __c + __d * __d;\n    Fcomplex z;\n    COMPLEX_REAL(z) = crt_scalbnf((__a * __c + __b * __d) / __denom, -__ilogbw);\n    COMPLEX_IMAGINARY(z) = crt_scalbnf((__b * __c - __a * __d) / __denom, -__ilogbw);\n    if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))\n    {\n        if ((__denom == 0) && (!crt_isnan(__a) || !crt_isnan(__b)))\n        {\n            COMPLEX_REAL(z) = crt_copysignf(CRT_INFINITY, __c) * __a;\n            COMPLEX_IMAGINARY(z) = crt_copysignf(CRT_INFINITY, __c) * __b;\n        }\n        else if ((crt_isinf(__a) || crt_isinf(__b)) &&\n                 crt_isfinite(__c) && crt_isfinite(__d))\n        {\n            __a = crt_copysignf(crt_isinf(__a) ? 1 : 0, __a);\n            __b = crt_copysignf(crt_isinf(__b) ? 1 : 0, __b);\n            COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d);\n            COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d);\n        }\n        else if (crt_isinf(__logbw) && __logbw > 0 &&\n                 crt_isfinite(__a) && crt_isfinite(__b))\n        {\n            __c = crt_copysignf(crt_isinf(__c) ? 1 : 0, __c);\n            __d = crt_copysignf(crt_isinf(__d) ? 1 : 0, __d);\n            COMPLEX_REAL(z) = 0 * (__a * __c + __b * __d);\n            COMPLEX_IMAGINARY(z) = 0 * (__b * __c - __a * __d);\n        }\n    }\n    return z;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/divsf3.c",
    "content": "//===-- lib/divsf3.c - Single-precision division ------------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements single-precision soft-float division\n// with the IEEE-754 default rounding (to nearest, ties to even).\n//\n// For simplicity, this implementation currently flushes denormals to zero.\n// It should be a fairly straightforward exercise to implement gradual\n// underflow with correct rounding.\n//\n//===----------------------------------------------------------------------===//\n\n#define SINGLE_PRECISION\n#include \"fp_lib.h\"\n\nARM_EABI_FNALIAS(fdiv, divsf3)\n\nCOMPILER_RT_ABI fp_t\n__divsf3(fp_t a, fp_t b) {\n    \n    const unsigned int aExponent = toRep(a) >> significandBits & maxExponent;\n    const unsigned int bExponent = toRep(b) >> significandBits & maxExponent;\n    const rep_t quotientSign = (toRep(a) ^ toRep(b)) & signBit;\n    \n    rep_t aSignificand = toRep(a) & significandMask;\n    rep_t bSignificand = toRep(b) & significandMask;\n    int scale = 0;\n    \n    // Detect if a or b is zero, denormal, infinity, or NaN.\n    if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) {\n        \n        const rep_t aAbs = toRep(a) & absMask;\n        const rep_t bAbs = toRep(b) & absMask;\n        \n        // NaN / anything = qNaN\n        if (aAbs > infRep) return fromRep(toRep(a) | quietBit);\n        // anything / NaN = qNaN\n        if (bAbs > infRep) return fromRep(toRep(b) | quietBit);\n        \n        if (aAbs == infRep) {\n            // infinity / infinity = NaN\n            if (bAbs == infRep) return fromRep(qnanRep);\n            // infinity / anything else = +/- infinity\n            else return fromRep(aAbs | quotientSign);\n        }\n        \n        // anything else / infinity = +/- 0\n        if (bAbs == infRep) return fromRep(quotientSign);\n        \n        if (!aAbs) {\n            // zero / zero = NaN\n            if (!bAbs) return fromRep(qnanRep);\n            // zero / anything else = +/- zero\n            else return fromRep(quotientSign);\n        }\n        // anything else / zero = +/- infinity\n        if (!bAbs) return fromRep(infRep | quotientSign);\n        \n        // one or both of a or b is denormal, the other (if applicable) is a\n        // normal number.  Renormalize one or both of a and b, and set scale to\n        // include the necessary exponent adjustment.\n        if (aAbs < implicitBit) scale += normalize(&aSignificand);\n        if (bAbs < implicitBit) scale -= normalize(&bSignificand);\n    }\n    \n    // Or in the implicit significand bit.  (If we fell through from the\n    // denormal path it was already set by normalize( ), but setting it twice\n    // won't hurt anything.)\n    aSignificand |= implicitBit;\n    bSignificand |= implicitBit;\n    int quotientExponent = aExponent - bExponent + scale;\n    \n    // Align the significand of b as a Q31 fixed-point number in the range\n    // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax\n    // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2.  This\n    // is accurate to about 3.5 binary digits.\n    uint32_t q31b = bSignificand << 8;\n    uint32_t reciprocal = UINT32_C(0x7504f333) - q31b;\n    \n    // Now refine the reciprocal estimate using a Newton-Raphson iteration:\n    //\n    //     x1 = x0 * (2 - x0 * b)\n    //\n    // This doubles the number of correct binary digits in the approximation\n    // with each iteration, so after three iterations, we have about 28 binary\n    // digits of accuracy.\n    uint32_t correction;\n    correction = -((uint64_t)reciprocal * q31b >> 32);\n    reciprocal = (uint64_t)reciprocal * correction >> 31;\n    correction = -((uint64_t)reciprocal * q31b >> 32);\n    reciprocal = (uint64_t)reciprocal * correction >> 31;\n    correction = -((uint64_t)reciprocal * q31b >> 32);\n    reciprocal = (uint64_t)reciprocal * correction >> 31;\n    \n    // Exhaustive testing shows that the error in reciprocal after three steps\n    // is in the interval [-0x1.f58108p-31, 0x1.d0e48cp-29], in line with our\n    // expectations.  We bump the reciprocal by a tiny value to force the error\n    // to be strictly positive (in the range [0x1.4fdfp-37,0x1.287246p-29], to\n    // be specific).  This also causes 1/1 to give a sensible approximation\n    // instead of zero (due to overflow).\n    reciprocal -= 2;\n    \n    // The numerical reciprocal is accurate to within 2^-28, lies in the\n    // interval [0x1.000000eep-1, 0x1.fffffffcp-1], and is strictly smaller\n    // than the true reciprocal of b.  Multiplying a by this reciprocal thus\n    // gives a numerical q = a/b in Q24 with the following properties:\n    //\n    //    1. q < a/b\n    //    2. q is in the interval [0x1.000000eep-1, 0x1.fffffffcp0)\n    //    3. the error in q is at most 2^-24 + 2^-27 -- the 2^24 term comes\n    //       from the fact that we truncate the product, and the 2^27 term\n    //       is the error in the reciprocal of b scaled by the maximum\n    //       possible value of a.  As a consequence of this error bound,\n    //       either q or nextafter(q) is the correctly rounded \n    rep_t quotient = (uint64_t)reciprocal*(aSignificand << 1) >> 32;\n    \n    // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0).\n    // In either case, we are going to compute a residual of the form\n    //\n    //     r = a - q*b\n    //\n    // We know from the construction of q that r satisfies:\n    //\n    //     0 <= r < ulp(q)*b\n    // \n    // if r is greater than 1/2 ulp(q)*b, then q rounds up.  Otherwise, we\n    // already have the correct result.  The exact halfway case cannot occur.\n    // We also take this time to right shift quotient if it falls in the [1,2)\n    // range and adjust the exponent accordingly.\n    rep_t residual;\n    if (quotient < (implicitBit << 1)) {\n        residual = (aSignificand << 24) - quotient * bSignificand;\n        quotientExponent--;\n    } else {\n        quotient >>= 1;\n        residual = (aSignificand << 23) - quotient * bSignificand;\n    }\n\n    const int writtenExponent = quotientExponent + exponentBias;\n    \n    if (writtenExponent >= maxExponent) {\n        // If we have overflowed the exponent, return infinity.\n        return fromRep(infRep | quotientSign);\n    }\n    \n    else if (writtenExponent < 1) {\n        // Flush denormals to zero.  In the future, it would be nice to add\n        // code to round them correctly.\n        return fromRep(quotientSign);\n    }\n    \n    else {\n        const bool round = (residual << 1) > bSignificand;\n        // Clear the implicit bit\n        rep_t absResult = quotient & significandMask;\n        // Insert the exponent\n        absResult |= (rep_t)writtenExponent << significandBits;\n        // Round\n        absResult += round;\n        // Insert the sign and return\n        return fromRep(absResult | quotientSign);\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/divsi3.c",
    "content": "/* ===-- divsi3.c - Implement __divsi3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __divsi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a / b */\n\nARM_EABI_FNALIAS(idiv, divsi3)\n\nCOMPILER_RT_ABI si_int\n__divsi3(si_int a, si_int b)\n{\n    const int bits_in_word_m1 = (int)(sizeof(si_int) * CHAR_BIT) - 1;\n    si_int s_a = a >> bits_in_word_m1;           /* s_a = a < 0 ? -1 : 0 */\n    si_int s_b = b >> bits_in_word_m1;           /* s_b = b < 0 ? -1 : 0 */\n    a = (a ^ s_a) - s_a;                         /* negate if s_a == -1 */\n    b = (b ^ s_b) - s_b;                         /* negate if s_b == -1 */\n    s_a ^= s_b;                                  /* sign of quotient */\n    /*\n     * On CPUs without unsigned hardware division support,\n     *  this calls __udivsi3 (notice the cast to su_int).\n     * On CPUs with unsigned hardware division support,\n     *  this uses the unsigned division instruction.\n     */\n    return ((su_int)a/(su_int)b ^ s_a) - s_a;    /* negate if s_a == -1 */\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/divtc3.c",
    "content": "/*===-- divtc3.c - Implement __divtc3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __divtc3 for the compiler_rt library.\n *\n *===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n#include \"int_math.h\"\n\n/* Returns: the quotient of (a + ib) / (c + id) */\n\nCOMPILER_RT_ABI long double _Complex\n__divtc3(long double __a, long double __b, long double __c, long double __d)\n{\n    int __ilogbw = 0;\n    long double __logbw = crt_logbl(crt_fmaxl(crt_fabsl(__c), crt_fabsl(__d)));\n    if (crt_isfinite(__logbw))\n    {\n        __ilogbw = (int)__logbw;\n        __c = crt_scalbnl(__c, -__ilogbw);\n        __d = crt_scalbnl(__d, -__ilogbw);\n    }\n    long double __denom = __c * __c + __d * __d;\n    long double _Complex z;\n    __real__ z = crt_scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw);\n    __imag__ z = crt_scalbnl((__b * __c - __a * __d) / __denom, -__ilogbw);\n    if (crt_isnan(__real__ z) && crt_isnan(__imag__ z))\n    {\n        if ((__denom == 0.0) && (!crt_isnan(__a) || !crt_isnan(__b)))\n        {\n            __real__ z = crt_copysignl(CRT_INFINITY, __c) * __a;\n            __imag__ z = crt_copysignl(CRT_INFINITY, __c) * __b;\n        }\n        else if ((crt_isinf(__a) || crt_isinf(__b)) &&\n                 crt_isfinite(__c) && crt_isfinite(__d))\n        {\n            __a = crt_copysignl(crt_isinf(__a) ? 1.0 : 0.0, __a);\n            __b = crt_copysignl(crt_isinf(__b) ? 1.0 : 0.0, __b);\n            __real__ z = CRT_INFINITY * (__a * __c + __b * __d);\n            __imag__ z = CRT_INFINITY * (__b * __c - __a * __d);\n        }\n        else if (crt_isinf(__logbw) && __logbw > 0.0 &&\n                 crt_isfinite(__a) && crt_isfinite(__b))\n        {\n            __c = crt_copysignl(crt_isinf(__c) ? 1.0 : 0.0, __c);\n            __d = crt_copysignl(crt_isinf(__d) ? 1.0 : 0.0, __d);\n            __real__ z = 0.0 * (__a * __c + __b * __d);\n            __imag__ z = 0.0 * (__b * __c - __a * __d);\n        }\n    }\n    return z;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/divtf3.c",
    "content": "//===-- lib/divtf3.c - Quad-precision division --------------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements quad-precision soft-float division\n// with the IEEE-754 default rounding (to nearest, ties to even).\n//\n// For simplicity, this implementation currently flushes denormals to zero.\n// It should be a fairly straightforward exercise to implement gradual\n// underflow with correct rounding.\n//\n//===----------------------------------------------------------------------===//\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\nCOMPILER_RT_ABI fp_t __divtf3(fp_t a, fp_t b) {\n\n    const unsigned int aExponent = toRep(a) >> significandBits & maxExponent;\n    const unsigned int bExponent = toRep(b) >> significandBits & maxExponent;\n    const rep_t quotientSign = (toRep(a) ^ toRep(b)) & signBit;\n\n    rep_t aSignificand = toRep(a) & significandMask;\n    rep_t bSignificand = toRep(b) & significandMask;\n    int scale = 0;\n\n    // Detect if a or b is zero, denormal, infinity, or NaN.\n    if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) {\n\n        const rep_t aAbs = toRep(a) & absMask;\n        const rep_t bAbs = toRep(b) & absMask;\n\n        // NaN / anything = qNaN\n        if (aAbs > infRep) return fromRep(toRep(a) | quietBit);\n        // anything / NaN = qNaN\n        if (bAbs > infRep) return fromRep(toRep(b) | quietBit);\n\n        if (aAbs == infRep) {\n            // infinity / infinity = NaN\n            if (bAbs == infRep) return fromRep(qnanRep);\n            // infinity / anything else = +/- infinity\n            else return fromRep(aAbs | quotientSign);\n        }\n\n        // anything else / infinity = +/- 0\n        if (bAbs == infRep) return fromRep(quotientSign);\n\n        if (!aAbs) {\n            // zero / zero = NaN\n            if (!bAbs) return fromRep(qnanRep);\n            // zero / anything else = +/- zero\n            else return fromRep(quotientSign);\n        }\n        // anything else / zero = +/- infinity\n        if (!bAbs) return fromRep(infRep | quotientSign);\n\n        // one or both of a or b is denormal, the other (if applicable) is a\n        // normal number.  Renormalize one or both of a and b, and set scale to\n        // include the necessary exponent adjustment.\n        if (aAbs < implicitBit) scale += normalize(&aSignificand);\n        if (bAbs < implicitBit) scale -= normalize(&bSignificand);\n    }\n\n    // Or in the implicit significand bit.  (If we fell through from the\n    // denormal path it was already set by normalize( ), but setting it twice\n    // won't hurt anything.)\n    aSignificand |= implicitBit;\n    bSignificand |= implicitBit;\n    int quotientExponent = aExponent - bExponent + scale;\n\n    // Align the significand of b as a Q63 fixed-point number in the range\n    // [1, 2.0) and get a Q64 approximate reciprocal using a small minimax\n    // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2.  This\n    // is accurate to about 3.5 binary digits.\n    const uint64_t q63b = bSignificand >> 49;\n    uint64_t recip64 = UINT64_C(0x7504f333F9DE6484) - q63b;\n    // 0x7504f333F9DE6484 / 2^64 + 1 = 3/4 + 1/sqrt(2)\n\n    // Now refine the reciprocal estimate using a Newton-Raphson iteration:\n    //\n    //     x1 = x0 * (2 - x0 * b)\n    //\n    // This doubles the number of correct binary digits in the approximation\n    // with each iteration.\n    uint64_t correction64;\n    correction64 = -((rep_t)recip64 * q63b >> 64);\n    recip64 = (rep_t)recip64 * correction64 >> 63;\n    correction64 = -((rep_t)recip64 * q63b >> 64);\n    recip64 = (rep_t)recip64 * correction64 >> 63;\n    correction64 = -((rep_t)recip64 * q63b >> 64);\n    recip64 = (rep_t)recip64 * correction64 >> 63;\n    correction64 = -((rep_t)recip64 * q63b >> 64);\n    recip64 = (rep_t)recip64 * correction64 >> 63;\n    correction64 = -((rep_t)recip64 * q63b >> 64);\n    recip64 = (rep_t)recip64 * correction64 >> 63;\n\n    // recip64 might have overflowed to exactly zero in the preceeding\n    // computation if the high word of b is exactly 1.0.  This would sabotage\n    // the full-width final stage of the computation that follows, so we adjust\n    // recip64 downward by one bit.\n    recip64--;\n\n    // We need to perform one more iteration to get us to 112 binary digits;\n    // The last iteration needs to happen with extra precision.\n    const uint64_t q127blo = bSignificand << 15;\n    rep_t correction, reciprocal;\n\n    // NOTE: This operation is equivalent to __multi3, which is not implemented\n    //       in some architechure\n    rep_t r64q63, r64q127, r64cH, r64cL, dummy;\n    wideMultiply((rep_t)recip64, (rep_t)q63b, &dummy, &r64q63);\n    wideMultiply((rep_t)recip64, (rep_t)q127blo, &dummy, &r64q127);\n\n    correction = -(r64q63 + (r64q127 >> 64));\n\n    uint64_t cHi = correction >> 64;\n    uint64_t cLo = correction;\n\n    wideMultiply((rep_t)recip64, (rep_t)cHi, &dummy, &r64cH);\n    wideMultiply((rep_t)recip64, (rep_t)cLo, &dummy, &r64cL);\n\n    reciprocal = r64cH + (r64cL >> 64);\n\n    // We already adjusted the 64-bit estimate, now we need to adjust the final\n    // 128-bit reciprocal estimate downward to ensure that it is strictly smaller\n    // than the infinitely precise exact reciprocal.  Because the computation\n    // of the Newton-Raphson step is truncating at every step, this adjustment\n    // is small; most of the work is already done.\n    reciprocal -= 2;\n\n    // The numerical reciprocal is accurate to within 2^-112, lies in the\n    // interval [0.5, 1.0), and is strictly smaller than the true reciprocal\n    // of b.  Multiplying a by this reciprocal thus gives a numerical q = a/b\n    // in Q127 with the following properties:\n    //\n    //    1. q < a/b\n    //    2. q is in the interval [0.5, 2.0)\n    //    3. the error in q is bounded away from 2^-113 (actually, we have a\n    //       couple of bits to spare, but this is all we need).\n\n    // We need a 128 x 128 multiply high to compute q, which isn't a basic\n    // operation in C, so we need to be a little bit fussy.\n    rep_t quotient, quotientLo;\n    wideMultiply(aSignificand << 2, reciprocal, &quotient, &quotientLo);\n\n    // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0).\n    // In either case, we are going to compute a residual of the form\n    //\n    //     r = a - q*b\n    //\n    // We know from the construction of q that r satisfies:\n    //\n    //     0 <= r < ulp(q)*b\n    //\n    // if r is greater than 1/2 ulp(q)*b, then q rounds up.  Otherwise, we\n    // already have the correct result.  The exact halfway case cannot occur.\n    // We also take this time to right shift quotient if it falls in the [1,2)\n    // range and adjust the exponent accordingly.\n    rep_t residual;\n    rep_t qb;\n\n    if (quotient < (implicitBit << 1)) {\n        wideMultiply(quotient, bSignificand, &dummy, &qb);\n        residual = (aSignificand << 113) - qb;\n        quotientExponent--;\n    } else {\n        quotient >>= 1;\n        wideMultiply(quotient, bSignificand, &dummy, &qb);\n        residual = (aSignificand << 112) - qb;\n    }\n\n    const int writtenExponent = quotientExponent + exponentBias;\n\n    if (writtenExponent >= maxExponent) {\n        // If we have overflowed the exponent, return infinity.\n        return fromRep(infRep | quotientSign);\n    }\n    else if (writtenExponent < 1) {\n        // Flush denormals to zero.  In the future, it would be nice to add\n        // code to round them correctly.\n        return fromRep(quotientSign);\n    }\n    else {\n        const bool round = (residual << 1) >= bSignificand;\n        // Clear the implicit bit\n        rep_t absResult = quotient & significandMask;\n        // Insert the exponent\n        absResult |= (rep_t)writtenExponent << significandBits;\n        // Round\n        absResult += round;\n        // Insert the sign and return\n        const long double result = fromRep(absResult | quotientSign);\n        return result;\n    }\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/divti3.c",
    "content": "/* ===-- divti3.c - Implement __divti3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __divti3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: a / b */\n\nCOMPILER_RT_ABI ti_int\n__divti3(ti_int a, ti_int b)\n{\n    const int bits_in_tword_m1 = (int)(sizeof(ti_int) * CHAR_BIT) - 1;\n    ti_int s_a = a >> bits_in_tword_m1;           /* s_a = a < 0 ? -1 : 0 */\n    ti_int s_b = b >> bits_in_tword_m1;           /* s_b = b < 0 ? -1 : 0 */\n    a = (a ^ s_a) - s_a;                         /* negate if s_a == -1 */\n    b = (b ^ s_b) - s_b;                         /* negate if s_b == -1 */\n    s_a ^= s_b;                                  /* sign of quotient */\n    return (__udivmodti4(a, b, (tu_int*)0) ^ s_a) - s_a;  /* negate if s_a == -1 */\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/divxc3.c",
    "content": "/* ===-- divxc3.c - Implement __divxc3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __divxc3 for the compiler_rt library.\n *\n */\n\n#if !_ARCH_PPC\n\n#include \"int_lib.h\"\n#include \"int_math.h\"\n\n/* Returns: the quotient of (a + ib) / (c + id) */\n\nCOMPILER_RT_ABI Lcomplex\n__divxc3(long double __a, long double __b, long double __c, long double __d)\n{\n    int __ilogbw = 0;\n    long double __logbw = crt_logbl(crt_fmaxl(crt_fabsl(__c), crt_fabsl(__d)));\n    if (crt_isfinite(__logbw))\n    {\n        __ilogbw = (int)__logbw;\n        __c = crt_scalbnl(__c, -__ilogbw);\n        __d = crt_scalbnl(__d, -__ilogbw);\n    }\n    long double __denom = __c * __c + __d * __d;\n    Lcomplex z;\n    COMPLEX_REAL(z) = crt_scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw);\n    COMPLEX_IMAGINARY(z) = crt_scalbnl((__b * __c - __a * __d) / __denom, -__ilogbw);\n    if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))\n    {\n        if ((__denom == 0) && (!crt_isnan(__a) || !crt_isnan(__b)))\n        {\n            COMPLEX_REAL(z) = crt_copysignl(CRT_INFINITY, __c) * __a;\n            COMPLEX_IMAGINARY(z) = crt_copysignl(CRT_INFINITY, __c) * __b;\n        }\n        else if ((crt_isinf(__a) || crt_isinf(__b)) &&\n                 crt_isfinite(__c) && crt_isfinite(__d))\n        {\n            __a = crt_copysignl(crt_isinf(__a) ? 1 : 0, __a);\n            __b = crt_copysignl(crt_isinf(__b) ? 1 : 0, __b);\n            COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d);\n            COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d);\n        }\n        else if (crt_isinf(__logbw) && __logbw > 0 &&\n                 crt_isfinite(__a) && crt_isfinite(__b))\n        {\n            __c = crt_copysignl(crt_isinf(__c) ? 1 : 0, __c);\n            __d = crt_copysignl(crt_isinf(__d) ? 1 : 0, __d);\n            COMPLEX_REAL(z) = 0 * (__a * __c + __b * __d);\n            COMPLEX_IMAGINARY(z) = 0 * (__b * __c - __a * __d);\n        }\n    }\n    return z;\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/emutls.c",
    "content": "/* ===---------- emutls.c - Implements __emutls_get_address ---------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n#include <pthread.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"int_lib.h\"\n#include \"int_util.h\"\n\n/* Default is not to use posix_memalign, so systems like Android\n * can use thread local data without heavier POSIX memory allocators.\n */\n#ifndef EMUTLS_USE_POSIX_MEMALIGN\n#define EMUTLS_USE_POSIX_MEMALIGN 0\n#endif\n\n/* For every TLS variable xyz,\n * there is one __emutls_control variable named __emutls_v.xyz.\n * If xyz has non-zero initial value, __emutls_v.xyz's \"value\"\n * will point to __emutls_t.xyz, which has the initial value.\n */\ntypedef struct __emutls_control {\n    size_t size;  /* size of the object in bytes */\n    size_t align;  /* alignment of the object in bytes */\n    union {\n        uintptr_t index;  /* data[index-1] is the object address */\n        void* address;  /* object address, when in single thread env */\n    } object;\n    void* value;  /* null or non-zero initial value for the object */\n} __emutls_control;\n\nstatic __inline void *emutls_memalign_alloc(size_t align, size_t size) {\n    void *base;\n#if EMUTLS_USE_POSIX_MEMALIGN\n    if (posix_memalign(&base, align, size) != 0)\n        abort();\n#else\n    #define EXTRA_ALIGN_PTR_BYTES (align - 1 + sizeof(void*))\n    char* object;\n    if ((object = malloc(EXTRA_ALIGN_PTR_BYTES + size)) == NULL)\n        abort();\n    base = (void*)(((uintptr_t)(object + EXTRA_ALIGN_PTR_BYTES))\n                    & ~(uintptr_t)(align - 1));\n\n    ((void**)base)[-1] = object;\n#endif\n    return base;\n}\n\nstatic __inline void emutls_memalign_free(void *base) {\n#if EMUTLS_USE_POSIX_MEMALIGN\n    free(base);\n#else\n    /* The mallocated address is in ((void**)base)[-1] */\n    free(((void**)base)[-1]);\n#endif\n}\n\n/* Emulated TLS objects are always allocated at run-time. */\nstatic __inline void *emutls_allocate_object(__emutls_control *control) {\n    /* Use standard C types, check with gcc's emutls.o. */\n    typedef unsigned int gcc_word __attribute__((mode(word)));\n    typedef unsigned int gcc_pointer __attribute__((mode(pointer)));\n    COMPILE_TIME_ASSERT(sizeof(size_t) == sizeof(gcc_word));\n    COMPILE_TIME_ASSERT(sizeof(uintptr_t) == sizeof(gcc_pointer));\n    COMPILE_TIME_ASSERT(sizeof(uintptr_t) == sizeof(void*));\n\n    size_t size = control->size;\n    size_t align = control->align;\n    if (align < sizeof(void*))\n        align = sizeof(void*);\n    /* Make sure that align is power of 2. */\n    if ((align & (align - 1)) != 0)\n        abort();\n\n    void* base = emutls_memalign_alloc(align, size);\n    if (control->value)\n        memcpy(base, control->value, size);\n    else\n        memset(base, 0, size);\n    return base;\n}\n\nstatic pthread_mutex_t emutls_mutex = PTHREAD_MUTEX_INITIALIZER;\n\nstatic size_t emutls_num_object = 0;  /* number of allocated TLS objects */\n\ntypedef struct emutls_address_array {\n    uintptr_t size;  /* number of elements in the 'data' array */\n    void* data[];\n} emutls_address_array;\n\nstatic pthread_key_t emutls_pthread_key;\n\nstatic void emutls_key_destructor(void* ptr) {\n    emutls_address_array* array = (emutls_address_array*)ptr;\n    uintptr_t i;\n    for (i = 0; i < array->size; ++i) {\n        if (array->data[i])\n            emutls_memalign_free(array->data[i]);\n    }\n    free(ptr);\n}\n\nstatic void emutls_init(void) {\n    if (pthread_key_create(&emutls_pthread_key, emutls_key_destructor) != 0)\n        abort();\n}\n\n/* Returns control->object.index; set index if not allocated yet. */\nstatic __inline uintptr_t emutls_get_index(__emutls_control *control) {\n    uintptr_t index = __atomic_load_n(&control->object.index, __ATOMIC_ACQUIRE);\n    if (!index) {\n        static pthread_once_t once = PTHREAD_ONCE_INIT;\n        pthread_once(&once, emutls_init);\n        pthread_mutex_lock(&emutls_mutex);\n        index = control->object.index;\n        if (!index) {\n            index = ++emutls_num_object;\n            __atomic_store_n(&control->object.index, index, __ATOMIC_RELEASE);\n        }\n        pthread_mutex_unlock(&emutls_mutex);\n    }\n    return index;\n}\n\n/* Updates newly allocated thread local emutls_address_array. */\nstatic __inline void emutls_check_array_set_size(emutls_address_array *array,\n                                                 uintptr_t size) {\n    if (array == NULL)\n        abort();\n    array->size = size;\n    pthread_setspecific(emutls_pthread_key, (void*)array);\n}\n\n/* Returns the new 'data' array size, number of elements,\n * which must be no smaller than the given index.\n */\nstatic __inline uintptr_t emutls_new_data_array_size(uintptr_t index) {\n   /* Need to allocate emutls_address_array with one extra slot\n    * to store the data array size.\n    * Round up the emutls_address_array size to multiple of 16.\n    */\n    return ((index + 1 + 15) & ~((uintptr_t)15)) - 1;\n}\n\n/* Returns the thread local emutls_address_array.\n * Extends its size if necessary to hold address at index.\n */\nstatic __inline emutls_address_array *\nemutls_get_address_array(uintptr_t index) {\n    emutls_address_array* array = pthread_getspecific(emutls_pthread_key);\n    if (array == NULL) {\n        uintptr_t new_size = emutls_new_data_array_size(index);\n        array = calloc(new_size + 1, sizeof(void*));\n        emutls_check_array_set_size(array, new_size);\n    } else if (index > array->size) {\n        uintptr_t orig_size = array->size;\n        uintptr_t new_size = emutls_new_data_array_size(index);\n        array = realloc(array, (new_size + 1) * sizeof(void*));\n        if (array)\n            memset(array->data + orig_size, 0,\n                   (new_size - orig_size) * sizeof(void*));\n        emutls_check_array_set_size(array, new_size);\n    }\n    return array;\n}\n\nvoid* __emutls_get_address(__emutls_control* control) {\n    uintptr_t index = emutls_get_index(control);\n    emutls_address_array* array = emutls_get_address_array(index);\n    if (array->data[index - 1] == NULL)\n        array->data[index - 1] = emutls_allocate_object(control);\n    return array->data[index - 1];\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/enable_execute_stack.c",
    "content": "/* ===-- enable_execute_stack.c - Implement __enable_execute_stack ---------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifndef _WIN32\n#include <sys/mman.h>\n#endif\n\n/* #include \"config.h\"\n * FIXME: CMake - include when cmake system is ready.\n * Remove #define HAVE_SYSCONF 1 line.\n */\n#define HAVE_SYSCONF 1\n\n#ifdef _WIN32\n#define WIN32_LEAN_AND_MEAN\n#include <Windows.h>\n#else\n#ifndef __APPLE__\n#include <unistd.h>\n#endif /* __APPLE__ */\n#endif /* _WIN32 */\n\n#if __LP64__\n\t#define TRAMPOLINE_SIZE 48\n#else\n\t#define TRAMPOLINE_SIZE 40\n#endif\n\n/*\n * The compiler generates calls to __enable_execute_stack() when creating \n * trampoline functions on the stack for use with nested functions.\n * It is expected to mark the page(s) containing the address \n * and the next 48 bytes as executable.  Since the stack is normally rw-\n * that means changing the protection on those page(s) to rwx. \n */\n\nCOMPILER_RT_ABI void\n__enable_execute_stack(void* addr)\n{\n\n#if _WIN32\n\tMEMORY_BASIC_INFORMATION mbi;\n\tif (!VirtualQuery (addr, &mbi, sizeof(mbi)))\n\t\treturn; /* We should probably assert here because there is no return value */\n\tVirtualProtect (mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &mbi.Protect);\n#else\n#if __APPLE__\n\t/* On Darwin, pagesize is always 4096 bytes */\n\tconst uintptr_t pageSize = 4096;\n#elif !defined(HAVE_SYSCONF)\n#error \"HAVE_SYSCONF not defined! See enable_execute_stack.c\"\n#else\n        const uintptr_t pageSize = sysconf(_SC_PAGESIZE);\n#endif /* __APPLE__ */\n\n\tconst uintptr_t pageAlignMask = ~(pageSize-1);\n\tuintptr_t p = (uintptr_t)addr;\n\tunsigned char* startPage = (unsigned char*)(p & pageAlignMask);\n\tunsigned char* endPage = (unsigned char*)((p+TRAMPOLINE_SIZE+pageSize) & pageAlignMask);\n\tsize_t length = endPage - startPage;\n\t(void) mprotect((void *)startPage, length, PROT_READ | PROT_WRITE | PROT_EXEC);\n#endif\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/eprintf.c",
    "content": "/* ===---------- eprintf.c - Implements __eprintf --------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n\n\n#include \"int_lib.h\"\n#include <stdio.h>\n\n\n/*\n * __eprintf() was used in an old version of <assert.h>.\n * It can eventually go away, but it is needed when linking\n * .o files built with the old <assert.h>.\n *\n * It should never be exported from a dylib, so it is marked\n * visibility hidden.\n */\n#ifndef _WIN32\n__attribute__((visibility(\"hidden\")))\n#endif\nCOMPILER_RT_ABI void\n__eprintf(const char* format, const char* assertion_expression,\n\t  const char* line, const char* file)\n{\n\tfprintf(stderr, format, assertion_expression, line, file);\n\tfflush(stderr);\n\tcompilerrt_abort();\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/extenddftf2.c",
    "content": "//===-- lib/extenddftf2.c - double -> quad conversion -------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\n#define SRC_DOUBLE\n#define DST_QUAD\n#include \"fp_extend_impl.inc\"\n\nCOMPILER_RT_ABI long double __extenddftf2(double a) {\n    return __extendXfYf2__(a);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/extendhfsf2.c",
    "content": "//===-- lib/extendhfsf2.c - half -> single conversion -------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n\n#define SRC_HALF\n#define DST_SINGLE\n#include \"fp_extend_impl.inc\"\n\nARM_EABI_FNALIAS(h2f, extendhfsf2)\n\n// Use a forwarding definition and noinline to implement a poor man's alias,\n// as there isn't a good cross-platform way of defining one.\nCOMPILER_RT_ABI NOINLINE float __extendhfsf2(uint16_t a) {\n    return __extendXfYf2__(a);\n}\n\nCOMPILER_RT_ABI float __gnu_h2f_ieee(uint16_t a) {\n    return __extendhfsf2(a);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/extendsfdf2.c",
    "content": "//===-- lib/extendsfdf2.c - single -> double conversion -----------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n\n#define SRC_SINGLE\n#define DST_DOUBLE\n#include \"fp_extend_impl.inc\"\n\nARM_EABI_FNALIAS(f2d, extendsfdf2)\n\nCOMPILER_RT_ABI double __extendsfdf2(float a) {\n    return __extendXfYf2__(a);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/extendsftf2.c",
    "content": "//===-- lib/extendsftf2.c - single -> quad conversion -------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\n#define SRC_SINGLE\n#define DST_QUAD\n#include \"fp_extend_impl.inc\"\n\nCOMPILER_RT_ABI long double __extendsftf2(float a) {\n    return __extendXfYf2__(a);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ffsdi2.c",
    "content": "/* ===-- ffsdi2.c - Implement __ffsdi2 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __ffsdi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: the index of the least significant 1-bit in a, or\n * the value zero if a is zero. The least significant bit is index one.\n */\n\nCOMPILER_RT_ABI si_int\n__ffsdi2(di_int a)\n{\n    dwords x;\n    x.all = a;\n    if (x.s.low == 0)\n    {\n        if (x.s.high == 0)\n            return 0;\n        return __builtin_ctz(x.s.high) + (1 + sizeof(si_int) * CHAR_BIT);\n    }\n    return __builtin_ctz(x.s.low) + 1;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ffsti2.c",
    "content": "/* ===-- ffsti2.c - Implement __ffsti2 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __ffsti2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: the index of the least significant 1-bit in a, or\n * the value zero if a is zero. The least significant bit is index one.\n */\n\nCOMPILER_RT_ABI si_int\n__ffsti2(ti_int a)\n{\n    twords x;\n    x.all = a;\n    if (x.s.low == 0)\n    {\n        if (x.s.high == 0)\n            return 0;\n        return __builtin_ctzll(x.s.high) + (1 + sizeof(di_int) * CHAR_BIT);\n    }\n    return __builtin_ctzll(x.s.low) + 1;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixdfdi.c",
    "content": "/* ===-- fixdfdi.c - Implement __fixdfdi -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define DOUBLE_PRECISION\n#include \"fp_lib.h\"\nARM_EABI_FNALIAS(d2lz, fixdfdi)\n\n#ifndef __SOFT_FP__\n/* Support for systems that have hardware floating-point; can set the invalid\n * flag as a side-effect of computation.\n */\n\nCOMPILER_RT_ABI du_int __fixunsdfdi(double a);\n\nCOMPILER_RT_ABI di_int\n__fixdfdi(double a)\n{\n    if (a < 0.0) {\n        return -__fixunsdfdi(-a);\n    }\n    return __fixunsdfdi(a);\n}\n\n#else\n/* Support for systems that don't have hardware floating-point; there are no\n * flags to set, and we don't want to code-gen to an unknown soft-float\n * implementation.\n */\n\ntypedef di_int fixint_t;\ntypedef du_int fixuint_t;\n#include \"fp_fixint_impl.inc\"\n\nCOMPILER_RT_ABI di_int\n__fixdfdi(fp_t a) {\n    return __fixint(a);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixdfsi.c",
    "content": "/* ===-- fixdfsi.c - Implement __fixdfsi -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define DOUBLE_PRECISION\n#include \"fp_lib.h\"\ntypedef si_int fixint_t;\ntypedef su_int fixuint_t;\n#include \"fp_fixint_impl.inc\"\n\nARM_EABI_FNALIAS(d2iz, fixdfsi)\n\nCOMPILER_RT_ABI si_int\n__fixdfsi(fp_t a) {\n    return __fixint(a);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixdfti.c",
    "content": "/* ===-- fixdfti.c - Implement __fixdfti -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n#define DOUBLE_PRECISION\n#include \"fp_lib.h\"\n\ntypedef ti_int fixint_t;\ntypedef tu_int fixuint_t;\n#include \"fp_fixint_impl.inc\"\n\nCOMPILER_RT_ABI ti_int\n__fixdfti(fp_t a) {\n    return __fixint(a);\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixsfdi.c",
    "content": "/* ===-- fixsfdi.c - Implement __fixsfdi -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define SINGLE_PRECISION\n#include \"fp_lib.h\"\n\nARM_EABI_FNALIAS(f2lz, fixsfdi)\n\n#ifndef __SOFT_FP__\n/* Support for systems that have hardware floating-point; can set the invalid\n * flag as a side-effect of computation.\n */\n\nCOMPILER_RT_ABI du_int __fixunssfdi(float a);\n\nCOMPILER_RT_ABI di_int\n__fixsfdi(float a)\n{\n    if (a < 0.0f) {\n        return -__fixunssfdi(-a);\n    }\n    return __fixunssfdi(a);\n}\n\n#else\n/* Support for systems that don't have hardware floating-point; there are no\n * flags to set, and we don't want to code-gen to an unknown soft-float\n * implementation.\n */\n\ntypedef di_int fixint_t;\ntypedef du_int fixuint_t;\n#include \"fp_fixint_impl.inc\"\n\nCOMPILER_RT_ABI di_int\n__fixsfdi(fp_t a) {\n    return __fixint(a);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixsfsi.c",
    "content": "/* ===-- fixsfsi.c - Implement __fixsfsi -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define SINGLE_PRECISION\n#include \"fp_lib.h\"\ntypedef si_int fixint_t;\ntypedef su_int fixuint_t;\n#include \"fp_fixint_impl.inc\"\n\nARM_EABI_FNALIAS(f2iz, fixsfsi)\n\nCOMPILER_RT_ABI si_int\n__fixsfsi(fp_t a) {\n    return __fixint(a);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixsfti.c",
    "content": "/* ===-- fixsfti.c - Implement __fixsfti -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n#define SINGLE_PRECISION\n#include \"fp_lib.h\"\n\ntypedef ti_int fixint_t;\ntypedef tu_int fixuint_t;\n#include \"fp_fixint_impl.inc\"\n\nCOMPILER_RT_ABI ti_int\n__fixsfti(fp_t a) {\n    return __fixint(a);\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixtfdi.c",
    "content": "/* ===-- fixtfdi.c - Implement __fixtfdi -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\ntypedef di_int fixint_t;\ntypedef du_int fixuint_t;\n#include \"fp_fixint_impl.inc\"\n\nCOMPILER_RT_ABI di_int\n__fixtfdi(fp_t a) {\n    return __fixint(a);\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixtfsi.c",
    "content": "/* ===-- fixtfsi.c - Implement __fixtfsi -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\ntypedef si_int fixint_t;\ntypedef su_int fixuint_t;\n#include \"fp_fixint_impl.inc\"\n\nCOMPILER_RT_ABI si_int\n__fixtfsi(fp_t a) {\n    return __fixint(a);\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixtfti.c",
    "content": "/* ===-- fixtfti.c - Implement __fixtfti -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\ntypedef ti_int fixint_t;\ntypedef tu_int fixuint_t;\n#include \"fp_fixint_impl.inc\"\n\nCOMPILER_RT_ABI ti_int\n__fixtfti(fp_t a) {\n    return __fixint(a);\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixunsdfdi.c",
    "content": "/* ===-- fixunsdfdi.c - Implement __fixunsdfdi -----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define DOUBLE_PRECISION\n#include \"fp_lib.h\"\n\nARM_EABI_FNALIAS(d2ulz, fixunsdfdi)\n\n#ifndef __SOFT_FP__\n/* Support for systems that have hardware floating-point; can set the invalid\n * flag as a side-effect of computation.\n */\n\nCOMPILER_RT_ABI du_int\n__fixunsdfdi(double a)\n{\n    if (a <= 0.0) return 0;\n    su_int high = a / 4294967296.f;               /* a / 0x1p32f; */\n    su_int low = a - (double)high * 4294967296.f; /* high * 0x1p32f; */\n    return ((du_int)high << 32) | low;\n}\n\n#else\n/* Support for systems that don't have hardware floating-point; there are no\n * flags to set, and we don't want to code-gen to an unknown soft-float\n * implementation.\n */\n\ntypedef du_int fixuint_t;\n#include \"fp_fixuint_impl.inc\"\n\nCOMPILER_RT_ABI du_int\n__fixunsdfdi(fp_t a) {\n    return __fixuint(a);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixunsdfsi.c",
    "content": "/* ===-- fixunsdfsi.c - Implement __fixunsdfsi -----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define DOUBLE_PRECISION\n#include \"fp_lib.h\"\ntypedef su_int fixuint_t;\n#include \"fp_fixuint_impl.inc\"\n\nARM_EABI_FNALIAS(d2uiz, fixunsdfsi)\n\nCOMPILER_RT_ABI su_int\n__fixunsdfsi(fp_t a) {\n    return __fixuint(a);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixunsdfti.c",
    "content": "/* ===-- fixunsdfti.c - Implement __fixunsdfti -----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n#define DOUBLE_PRECISION\n#include \"fp_lib.h\"\ntypedef tu_int fixuint_t;\n#include \"fp_fixuint_impl.inc\"\n\nCOMPILER_RT_ABI tu_int\n__fixunsdfti(fp_t a) {\n    return __fixuint(a);\n}\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixunssfdi.c",
    "content": "/* ===-- fixunssfdi.c - Implement __fixunssfdi -----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define SINGLE_PRECISION\n#include \"fp_lib.h\"\n\nARM_EABI_FNALIAS(f2ulz, fixunssfdi)\n\n#ifndef __SOFT_FP__\n/* Support for systems that have hardware floating-point; can set the invalid\n * flag as a side-effect of computation.\n */\n\nCOMPILER_RT_ABI du_int\n__fixunssfdi(float a)\n{\n    if (a <= 0.0f) return 0;\n    double da = a;\n    su_int high = da / 4294967296.f;               /* da / 0x1p32f; */\n    su_int low = da - (double)high * 4294967296.f; /* high * 0x1p32f; */\n    return ((du_int)high << 32) | low;\n}\n\n#else\n/* Support for systems that don't have hardware floating-point; there are no\n * flags to set, and we don't want to code-gen to an unknown soft-float\n * implementation.\n */\n\ntypedef du_int fixuint_t;\n#include \"fp_fixuint_impl.inc\"\n\nCOMPILER_RT_ABI du_int\n__fixunssfdi(fp_t a) {\n    return __fixuint(a);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixunssfsi.c",
    "content": "/* ===-- fixunssfsi.c - Implement __fixunssfsi -----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __fixunssfsi for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define SINGLE_PRECISION\n#include \"fp_lib.h\"\ntypedef su_int fixuint_t;\n#include \"fp_fixuint_impl.inc\"\n\nARM_EABI_FNALIAS(f2uiz, fixunssfsi)\n\nCOMPILER_RT_ABI su_int\n__fixunssfsi(fp_t a) {\n    return __fixuint(a);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixunssfti.c",
    "content": "/* ===-- fixunssfti.c - Implement __fixunssfti -----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __fixunssfti for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define SINGLE_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT)\ntypedef tu_int fixuint_t;\n#include \"fp_fixuint_impl.inc\"\n\nCOMPILER_RT_ABI tu_int\n__fixunssfti(fp_t a) {\n    return __fixuint(a);\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixunstfdi.c",
    "content": "/* ===-- fixunstfdi.c - Implement __fixunstfdi -----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\ntypedef du_int fixuint_t;\n#include \"fp_fixuint_impl.inc\"\n\nCOMPILER_RT_ABI du_int\n__fixunstfdi(fp_t a) {\n    return __fixuint(a);\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixunstfsi.c",
    "content": "/* ===-- fixunstfsi.c - Implement __fixunstfsi -----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\ntypedef su_int fixuint_t;\n#include \"fp_fixuint_impl.inc\"\n\nCOMPILER_RT_ABI su_int\n__fixunstfsi(fp_t a) {\n    return __fixuint(a);\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixunstfti.c",
    "content": "/* ===-- fixunstfsi.c - Implement __fixunstfsi -----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\ntypedef tu_int fixuint_t;\n#include \"fp_fixuint_impl.inc\"\n\nCOMPILER_RT_ABI tu_int\n__fixunstfti(fp_t a) {\n    return __fixuint(a);\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixunsxfdi.c",
    "content": "/* ===-- fixunsxfdi.c - Implement __fixunsxfdi -----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __fixunsxfdi for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#if !_ARCH_PPC\n\n#include \"int_lib.h\"\n\n/* Returns: convert a to a unsigned long long, rounding toward zero.\n *          Negative values all become zero.\n */\n\n/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes\n *             du_int is a 64 bit integral type\n *             value in long double is representable in du_int or is negative \n *                 (no range checking performed)\n */\n\n/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |\n * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm\n */\n\nCOMPILER_RT_ABI du_int\n__fixunsxfdi(long double a)\n{\n    long_double_bits fb;\n    fb.f = a;\n    int e = (fb.u.high.s.low & 0x00007FFF) - 16383;\n    if (e < 0 || (fb.u.high.s.low & 0x00008000))\n        return 0;\n    if ((unsigned)e > sizeof(du_int) * CHAR_BIT)\n        return ~(du_int)0;\n    return fb.u.low.all >> (63 - e);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixunsxfsi.c",
    "content": "/* ===-- fixunsxfsi.c - Implement __fixunsxfsi -----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __fixunsxfsi for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#if !_ARCH_PPC\n\n#include \"int_lib.h\"\n\n/* Returns: convert a to a unsigned int, rounding toward zero.\n *          Negative values all become zero.\n */\n\n/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes\n *             su_int is a 32 bit integral type\n *             value in long double is representable in su_int or is negative \n */\n\n/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |\n * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm\n */\n\nCOMPILER_RT_ABI su_int\n__fixunsxfsi(long double a)\n{\n    long_double_bits fb;\n    fb.f = a;\n    int e = (fb.u.high.s.low & 0x00007FFF) - 16383;\n    if (e < 0 || (fb.u.high.s.low & 0x00008000))\n        return 0;\n    if ((unsigned)e > sizeof(su_int) * CHAR_BIT)\n        return ~(su_int)0;\n    return fb.u.low.s.high >> (31 - e);\n}\n\n#endif /* !_ARCH_PPC */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixunsxfti.c",
    "content": "/* ===-- fixunsxfti.c - Implement __fixunsxfti -----------------------------===\n *\n *      \t       The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __fixunsxfti for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: convert a to a unsigned long long, rounding toward zero.\n *          Negative values all become zero.\n */\n\n/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes\n *             tu_int is a 128 bit integral type\n *             value in long double is representable in tu_int or is negative \n */\n\n/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |\n * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm\n */\n\nCOMPILER_RT_ABI tu_int\n__fixunsxfti(long double a)\n{\n    long_double_bits fb;\n    fb.f = a;\n    int e = (fb.u.high.s.low & 0x00007FFF) - 16383;\n    if (e < 0 || (fb.u.high.s.low & 0x00008000))\n        return 0;\n    if ((unsigned)e > sizeof(tu_int) * CHAR_BIT)\n        return ~(tu_int)0;\n    tu_int r = fb.u.low.all;\n    if (e > 63)\n        r <<= (e - 63);\n    else\n        r >>= (63 - e);\n    return r;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixxfdi.c",
    "content": "/* ===-- fixxfdi.c - Implement __fixxfdi -----------------------------------===\n *\n *      \t       The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __fixxfdi for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#if !_ARCH_PPC\n\n#include \"int_lib.h\"\n\n/* Returns: convert a to a signed long long, rounding toward zero. */\n\n/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes\n *             di_int is a 64 bit integral type\n *             value in long double is representable in di_int (no range checking performed)\n */\n\n/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |\n * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm\n */\n\nCOMPILER_RT_ABI di_int\n__fixxfdi(long double a)\n{\n    const di_int di_max = (di_int)((~(du_int)0) / 2);\n    const di_int di_min = -di_max - 1;\n    long_double_bits fb;\n    fb.f = a;\n    int e = (fb.u.high.s.low & 0x00007FFF) - 16383;\n    if (e < 0)\n        return 0;\n    if ((unsigned)e >= sizeof(di_int) * CHAR_BIT)\n        return a > 0 ? di_max : di_min;\n    di_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15);\n    di_int r = fb.u.low.all;\n    r = (du_int)r >> (63 - e);\n    return (r ^ s) - s;\n}\n\n#endif /* !_ARCH_PPC */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fixxfti.c",
    "content": "/* ===-- fixxfti.c - Implement __fixxfti -----------------------------------===\n *\n *      \t       The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __fixxfti for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: convert a to a signed long long, rounding toward zero. */\n\n/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes\n *             ti_int is a 128 bit integral type\n *             value in long double is representable in ti_int\n */\n\n/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |\n * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm\n */\n\nCOMPILER_RT_ABI ti_int\n__fixxfti(long double a)\n{\n    const ti_int ti_max = (ti_int)((~(tu_int)0) / 2);\n    const ti_int ti_min = -ti_max - 1;\n    long_double_bits fb;\n    fb.f = a;\n    int e = (fb.u.high.s.low & 0x00007FFF) - 16383;\n    if (e < 0)\n        return 0;\n    ti_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15);\n    ti_int r = fb.u.low.all;\n    if ((unsigned)e >= sizeof(ti_int) * CHAR_BIT)\n        return a > 0 ? ti_max : ti_min;\n    if (e > 63)\n        r <<= (e - 63);\n    else\n        r >>= (63 - e);\n    return (r ^ s) - s;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatdidf.c",
    "content": "/*===-- floatdidf.c - Implement __floatdidf -------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===\n *\n * This file implements __floatdidf for the compiler_rt library.\n *\n *===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: convert a to a double, rounding toward even. */\n\n/* Assumption: double is a IEEE 64 bit floating point type \n *             di_int is a 64 bit integral type\n */\n\n/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */\n\nARM_EABI_FNALIAS(l2d, floatdidf)\n\n#ifndef __SOFT_FP__\n/* Support for systems that have hardware floating-point; we'll set the inexact flag\n * as a side-effect of this computation.\n */\n\nCOMPILER_RT_ABI double\n__floatdidf(di_int a)\n{\n\tstatic const double twop52 = 4503599627370496.0; // 0x1.0p52\n\tstatic const double twop32 = 4294967296.0; // 0x1.0p32\n\t\n\tunion { int64_t x; double d; } low = { .d = twop52 };\n\t\n\tconst double high = (int32_t)(a >> 32) * twop32;\n\tlow.x |= a & INT64_C(0x00000000ffffffff);\n\t\n\tconst double result = (high - twop52) + low.d;\n\treturn result;\n}\n\n#else\n/* Support for systems that don't have hardware floating-point; there are no flags to\n * set, and we don't want to code-gen to an unknown soft-float implementation.\n */\n\nCOMPILER_RT_ABI double\n__floatdidf(di_int a)\n{\n    if (a == 0)\n        return 0.0;\n    const unsigned N = sizeof(di_int) * CHAR_BIT;\n    const di_int s = a >> (N-1);\n    a = (a ^ s) - s;\n    int sd = N - __builtin_clzll(a);  /* number of significant digits */\n    int e = sd - 1;             /* exponent */\n    if (sd > DBL_MANT_DIG)\n    {\n        /*  start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx\n         *  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR\n         *                                                12345678901234567890123456\n         *  1 = msb 1 bit\n         *  P = bit DBL_MANT_DIG-1 bits to the right of 1\n         * Q = bit DBL_MANT_DIG bits to the right of 1\n         *  R = \"or\" of all bits to the right of Q\n        */\n        switch (sd)\n        {\n        case DBL_MANT_DIG + 1:\n            a <<= 1;\n            break;\n        case DBL_MANT_DIG + 2:\n            break;\n        default:\n            a = ((du_int)a >> (sd - (DBL_MANT_DIG+2))) |\n                ((a & ((du_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);\n        };\n        /* finish: */\n        a |= (a & 4) != 0;  /* Or P into R */\n        ++a;  /* round - this step may add a significant bit */\n        a >>= 2;  /* dump Q and R */\n        /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */\n        if (a & ((du_int)1 << DBL_MANT_DIG))\n        {\n            a >>= 1;\n            ++e;\n        }\n        /* a is now rounded to DBL_MANT_DIG bits */\n    }\n    else\n    {\n        a <<= (DBL_MANT_DIG - sd);\n        /* a is now rounded to DBL_MANT_DIG bits */\n    }\n    double_bits fb;\n    fb.u.high = ((su_int)s & 0x80000000) |        /* sign */\n                ((e + 1023) << 20)      |        /* exponent */\n                ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */\n    fb.u.low = (su_int)a;                         /* mantissa-low */\n    return fb.f;\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatdisf.c",
    "content": "/*===-- floatdisf.c - Implement __floatdisf -------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===\n *\n * This file implements __floatdisf for the compiler_rt library.\n *\n *===----------------------------------------------------------------------===\n */\n\n/* Returns: convert a to a float, rounding toward even.*/\n\n/* Assumption: float is a IEEE 32 bit floating point type \n *             di_int is a 64 bit integral type\n */ \n\n/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */\n\n#include \"int_lib.h\"\n\nARM_EABI_FNALIAS(l2f, floatdisf)\n\nCOMPILER_RT_ABI float\n__floatdisf(di_int a)\n{\n    if (a == 0)\n        return 0.0F;\n    const unsigned N = sizeof(di_int) * CHAR_BIT;\n    const di_int s = a >> (N-1);\n    a = (a ^ s) - s;\n    int sd = N - __builtin_clzll(a);  /* number of significant digits */\n    int e = sd - 1;             /* exponent */\n    if (sd > FLT_MANT_DIG)\n    {\n        /*  start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx \n         *  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR \n         *                                                12345678901234567890123456 \n         *  1 = msb 1 bit \n         *  P = bit FLT_MANT_DIG-1 bits to the right of 1 \n         *  Q = bit FLT_MANT_DIG bits to the right of 1   \n         *  R = \"or\" of all bits to the right of Q \n         */\n        switch (sd)\n        {\n        case FLT_MANT_DIG + 1:\n            a <<= 1;\n            break;\n        case FLT_MANT_DIG + 2:\n            break;\n        default:\n            a = ((du_int)a >> (sd - (FLT_MANT_DIG+2))) |\n                ((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);\n        };\n        /* finish: */\n        a |= (a & 4) != 0;  /* Or P into R */\n        ++a;  /* round - this step may add a significant bit */\n        a >>= 2;  /* dump Q and R */\n        /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */\n        if (a & ((du_int)1 << FLT_MANT_DIG))\n        {\n            a >>= 1;\n            ++e;\n        }\n        /* a is now rounded to FLT_MANT_DIG bits */\n    }\n    else\n    {\n        a <<= (FLT_MANT_DIG - sd);\n        /* a is now rounded to FLT_MANT_DIG bits */\n    }\n    float_bits fb;\n    fb.u = ((su_int)s & 0x80000000) |  /* sign */\n           ((e + 127) << 23)       |  /* exponent */\n           ((su_int)a & 0x007FFFFF);   /* mantissa */\n    return fb.f;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatditf.c",
    "content": "//===-- lib/floatditf.c - integer -> quad-precision conversion ----*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements di_int to quad-precision conversion for the\n// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even\n// mode.\n//\n//===----------------------------------------------------------------------===//\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\nCOMPILER_RT_ABI fp_t __floatditf(di_int a) {\n\n    const int aWidth = sizeof a * CHAR_BIT;\n\n    // Handle zero as a special case to protect clz\n    if (a == 0)\n        return fromRep(0);\n\n    // All other cases begin by extracting the sign and absolute value of a\n    rep_t sign = 0;\n    du_int aAbs = (du_int)a;\n    if (a < 0) {\n        sign = signBit;\n        aAbs = ~(du_int)a + 1U;\n    }\n\n    // Exponent of (fp_t)a is the width of abs(a).\n    const int exponent = (aWidth - 1) - __builtin_clzll(aAbs);\n    rep_t result;\n\n    // Shift a into the significand field, rounding if it is a right-shift\n    const int shift = significandBits - exponent;\n    result = (rep_t)aAbs << shift ^ implicitBit;\n\n    // Insert the exponent\n    result += (rep_t)(exponent + exponentBias) << significandBits;\n    // Insert the sign bit and return\n    return fromRep(result | sign);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatdixf.c",
    "content": "/* ===-- floatdixf.c - Implement __floatdixf -------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __floatdixf for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */ \n\n#if !_ARCH_PPC\n\n#include \"int_lib.h\"\n\n/* Returns: convert a to a long double, rounding toward even. */\n\n/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits\n *             di_int is a 64 bit integral type\n */\n\n/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |\n * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm\n */\n\nCOMPILER_RT_ABI long double\n__floatdixf(di_int a)\n{\n    if (a == 0)\n        return 0.0;\n    const unsigned N = sizeof(di_int) * CHAR_BIT;\n    const di_int s = a >> (N-1);\n    a = (a ^ s) - s;\n    int clz = __builtin_clzll(a);\n    int e = (N - 1) - clz ;    /* exponent */\n    long_double_bits fb;\n    fb.u.high.s.low = ((su_int)s & 0x00008000) |  /* sign */\n\t\t      (e + 16383);                /* exponent */\n    fb.u.low.all = a << clz;                    /* mantissa */\n    return fb.f;\n}\n\n#endif /* !_ARCH_PPC */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatsidf.c",
    "content": "//===-- lib/floatsidf.c - integer -> double-precision conversion --*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements integer to double-precision conversion for the\n// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even\n// mode.\n//\n//===----------------------------------------------------------------------===//\n\n#define DOUBLE_PRECISION\n#include \"fp_lib.h\"\n\n#include \"int_lib.h\"\n\nARM_EABI_FNALIAS(i2d, floatsidf)\n\nCOMPILER_RT_ABI fp_t\n__floatsidf(int a) {\n    \n    const int aWidth = sizeof a * CHAR_BIT;\n    \n    // Handle zero as a special case to protect clz\n    if (a == 0)\n        return fromRep(0);\n    \n    // All other cases begin by extracting the sign and absolute value of a\n    rep_t sign = 0;\n    if (a < 0) {\n        sign = signBit;\n        a = -a;\n    }\n    \n    // Exponent of (fp_t)a is the width of abs(a).\n    const int exponent = (aWidth - 1) - __builtin_clz(a);\n    rep_t result;\n    \n    // Shift a into the significand field and clear the implicit bit.  Extra\n    // cast to unsigned int is necessary to get the correct behavior for\n    // the input INT_MIN.\n    const int shift = significandBits - exponent;\n    result = (rep_t)(unsigned int)a << shift ^ implicitBit;\n    \n    // Insert the exponent\n    result += (rep_t)(exponent + exponentBias) << significandBits;\n    // Insert the sign bit and return\n    return fromRep(result | sign);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatsisf.c",
    "content": "//===-- lib/floatsisf.c - integer -> single-precision conversion --*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements integer to single-precision conversion for the\n// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even\n// mode.\n//\n//===----------------------------------------------------------------------===//\n\n#define SINGLE_PRECISION\n#include \"fp_lib.h\"\n\n#include \"int_lib.h\"\n\nARM_EABI_FNALIAS(i2f, floatsisf)\n\nCOMPILER_RT_ABI fp_t\n__floatsisf(int a) {\n    \n    const int aWidth = sizeof a * CHAR_BIT;\n    \n    // Handle zero as a special case to protect clz\n    if (a == 0)\n        return fromRep(0);\n    \n    // All other cases begin by extracting the sign and absolute value of a\n    rep_t sign = 0;\n    if (a < 0) {\n        sign = signBit;\n        a = -a;\n    }\n    \n    // Exponent of (fp_t)a is the width of abs(a).\n    const int exponent = (aWidth - 1) - __builtin_clz(a);\n    rep_t result;\n    \n    // Shift a into the significand field, rounding if it is a right-shift\n    if (exponent <= significandBits) {\n        const int shift = significandBits - exponent;\n        result = (rep_t)a << shift ^ implicitBit;\n    } else {\n        const int shift = exponent - significandBits;\n        result = (rep_t)a >> shift ^ implicitBit;\n        rep_t round = (rep_t)a << (typeWidth - shift);\n        if (round > signBit) result++;\n        if (round == signBit) result += result & 1;\n    }\n    \n    // Insert the exponent\n    result += (rep_t)(exponent + exponentBias) << significandBits;\n    // Insert the sign bit and return\n    return fromRep(result | sign);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatsitf.c",
    "content": "//===-- lib/floatsitf.c - integer -> quad-precision conversion ----*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements integer to quad-precision conversion for the\n// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even\n// mode.\n//\n//===----------------------------------------------------------------------===//\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\nCOMPILER_RT_ABI fp_t __floatsitf(int a) {\n\n    const int aWidth = sizeof a * CHAR_BIT;\n\n    // Handle zero as a special case to protect clz\n    if (a == 0)\n        return fromRep(0);\n\n    // All other cases begin by extracting the sign and absolute value of a\n    rep_t sign = 0;\n    unsigned aAbs = (unsigned)a;\n    if (a < 0) {\n        sign = signBit;\n        aAbs = ~(unsigned)a + 1U;\n    }\n\n    // Exponent of (fp_t)a is the width of abs(a).\n    const int exponent = (aWidth - 1) - __builtin_clz(aAbs);\n    rep_t result;\n\n    // Shift a into the significand field and clear the implicit bit.\n    const int shift = significandBits - exponent;\n    result = (rep_t)aAbs << shift ^ implicitBit;\n\n    // Insert the exponent\n    result += (rep_t)(exponent + exponentBias) << significandBits;\n    // Insert the sign bit and return\n    return fromRep(result | sign);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floattidf.c",
    "content": "/* ===-- floattidf.c - Implement __floattidf -------------------------------===\n *\n *                    The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __floattidf for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */ \n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: convert a to a double, rounding toward even.*/\n\n/* Assumption: double is a IEEE 64 bit floating point type \n *            ti_int is a 128 bit integral type\n */\n\n/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ \n\nCOMPILER_RT_ABI double\n__floattidf(ti_int a)\n{\n    if (a == 0)\n        return 0.0;\n    const unsigned N = sizeof(ti_int) * CHAR_BIT;\n    const ti_int s = a >> (N-1);\n    a = (a ^ s) - s;\n    int sd = N - __clzti2(a);  /* number of significant digits */\n    int e = sd - 1;             /* exponent */\n    if (sd > DBL_MANT_DIG)\n    {\n        /* start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx\n         *  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR\n         *                                               12345678901234567890123456\n         * 1 = msb 1 bit\n         * P = bit DBL_MANT_DIG-1 bits to the right of 1\n         * Q = bit DBL_MANT_DIG bits to the right of 1\n         * R = \"or\" of all bits to the right of Q\n         */\n        switch (sd)\n        {\n        case DBL_MANT_DIG + 1:\n            a <<= 1;\n            break;\n        case DBL_MANT_DIG + 2:\n            break;\n        default:\n            a = ((tu_int)a >> (sd - (DBL_MANT_DIG+2))) |\n                ((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);\n        };\n        /* finish: */\n        a |= (a & 4) != 0;  /* Or P into R */\n        ++a;  /* round - this step may add a significant bit */\n        a >>= 2;  /* dump Q and R */\n        /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */\n        if (a & ((tu_int)1 << DBL_MANT_DIG))\n        {\n            a >>= 1;\n            ++e;\n        }\n        /* a is now rounded to DBL_MANT_DIG bits */\n    }\n    else\n    {\n        a <<= (DBL_MANT_DIG - sd);\n        /* a is now rounded to DBL_MANT_DIG bits */\n    }\n    double_bits fb;\n    fb.u.s.high = ((su_int)s & 0x80000000) |        /* sign */\n                ((e + 1023) << 20)      |        /* exponent */\n                ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */\n    fb.u.s.low = (su_int)a;                         /* mantissa-low */\n    return fb.f;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floattisf.c",
    "content": "/* ===-- floattisf.c - Implement __floattisf -------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __floattisf for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: convert a to a float, rounding toward even. */\n\n/* Assumption: float is a IEEE 32 bit floating point type \n *             ti_int is a 128 bit integral type\n */\n\n/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */\n\nCOMPILER_RT_ABI float\n__floattisf(ti_int a)\n{\n    if (a == 0)\n        return 0.0F;\n    const unsigned N = sizeof(ti_int) * CHAR_BIT;\n    const ti_int s = a >> (N-1);\n    a = (a ^ s) - s;\n    int sd = N - __clzti2(a);  /* number of significant digits */\n    int e = sd - 1;             /* exponent */\n    if (sd > FLT_MANT_DIG)\n    {\n        /*  start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx\n        * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR\n        *                                                12345678901234567890123456\n        *  1 = msb 1 bit\n        *  P = bit FLT_MANT_DIG-1 bits to the right of 1\n        *  Q = bit FLT_MANT_DIG bits to the right of 1\n        *  R = \"or\" of all bits to the right of Q\n        */\n        switch (sd)\n        {\n        case FLT_MANT_DIG + 1:\n            a <<= 1;\n            break;\n        case FLT_MANT_DIG + 2:\n            break;\n        default:\n            a = ((tu_int)a >> (sd - (FLT_MANT_DIG+2))) |\n                ((a & ((tu_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);\n        };\n        /* finish: */\n        a |= (a & 4) != 0;  /* Or P into R */\n        ++a;  /* round - this step may add a significant bit */\n        a >>= 2;  /* dump Q and R */\n        /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */\n        if (a & ((tu_int)1 << FLT_MANT_DIG))\n        {\n            a >>= 1;\n            ++e;\n        }\n        /* a is now rounded to FLT_MANT_DIG bits */\n    }\n    else\n    {\n        a <<= (FLT_MANT_DIG - sd);\n        /* a is now rounded to FLT_MANT_DIG bits */\n    }\n    float_bits fb;\n    fb.u = ((su_int)s & 0x80000000) |  /* sign */\n           ((e + 127) << 23)       |  /* exponent */\n           ((su_int)a & 0x007FFFFF);   /* mantissa */\n    return fb.f;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floattixf.c",
    "content": "/* ===-- floattixf.c - Implement __floattixf -------------------------------===\n *\n *      \t       The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __floattixf for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: convert a to a long double, rounding toward even. */\n\n/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits\n *             ti_int is a 128 bit integral type\n */\n\n/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |\n * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm\n */\n\nCOMPILER_RT_ABI long double\n__floattixf(ti_int a)\n{\n    if (a == 0)\n        return 0.0;\n    const unsigned N = sizeof(ti_int) * CHAR_BIT;\n    const ti_int s = a >> (N-1);\n    a = (a ^ s) - s;\n    int sd = N - __clzti2(a);  /* number of significant digits */\n    int e = sd - 1;             /* exponent */\n    if (sd > LDBL_MANT_DIG)\n    {\n        /*  start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx\n         *  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR\n         *                                                12345678901234567890123456\n         *  1 = msb 1 bit\n         *  P = bit LDBL_MANT_DIG-1 bits to the right of 1\n         *  Q = bit LDBL_MANT_DIG bits to the right of 1\n         *  R = \"or\" of all bits to the right of Q\n         */\n        switch (sd)\n        {\n        case LDBL_MANT_DIG + 1:\n            a <<= 1;\n            break;\n        case LDBL_MANT_DIG + 2:\n            break;\n        default:\n            a = ((tu_int)a >> (sd - (LDBL_MANT_DIG+2))) |\n                ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0);\n        };\n        /* finish: */\n        a |= (a & 4) != 0;  /* Or P into R */\n        ++a;  /* round - this step may add a significant bit */\n        a >>= 2;  /* dump Q and R */\n        /* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */\n        if (a & ((tu_int)1 << LDBL_MANT_DIG))\n        {\n            a >>= 1;\n            ++e;\n        }\n        /* a is now rounded to LDBL_MANT_DIG bits */\n    }\n    else\n    {\n        a <<= (LDBL_MANT_DIG - sd);\n        /* a is now rounded to LDBL_MANT_DIG bits */\n    }\n    long_double_bits fb;\n    fb.u.high.s.low = ((su_int)s & 0x8000) |        /* sign */\n                    (e + 16383);                  /* exponent */\n    fb.u.low.all = (du_int)a;                     /* mantissa */\n    return fb.f;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatundidf.c",
    "content": "/* ===-- floatundidf.c - Implement __floatundidf ---------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __floatundidf for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n/* Returns: convert a to a double, rounding toward even. */\n\n/* Assumption: double is a IEEE 64 bit floating point type \n *             du_int is a 64 bit integral type\n */\n\n/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */\n\n#include \"int_lib.h\"\n\nARM_EABI_FNALIAS(ul2d, floatundidf)\n\n#ifndef __SOFT_FP__\n/* Support for systems that have hardware floating-point; we'll set the inexact flag\n * as a side-effect of this computation.\n */\n\nCOMPILER_RT_ABI double\n__floatundidf(du_int a)\n{\n\tstatic const double twop52 = 4503599627370496.0; // 0x1.0p52\n\tstatic const double twop84 = 19342813113834066795298816.0; // 0x1.0p84\n\tstatic const double twop84_plus_twop52 = 19342813118337666422669312.0; // 0x1.00000001p84\n\t\n\tunion { uint64_t x; double d; } high = { .d = twop84 };\n\tunion { uint64_t x; double d; } low = { .d = twop52 };\n\t\n\thigh.x |= a >> 32;\n\tlow.x |= a & UINT64_C(0x00000000ffffffff);\n\t\n\tconst double result = (high.d - twop84_plus_twop52) + low.d;\n\treturn result;\n}\n\n#else\n/* Support for systems that don't have hardware floating-point; there are no flags to\n * set, and we don't want to code-gen to an unknown soft-float implementation.\n */ \n\nCOMPILER_RT_ABI double\n__floatundidf(du_int a)\n{\n    if (a == 0)\n        return 0.0;\n    const unsigned N = sizeof(du_int) * CHAR_BIT;\n    int sd = N - __builtin_clzll(a);  /* number of significant digits */\n    int e = sd - 1;             /* exponent */\n    if (sd > DBL_MANT_DIG)\n    {\n        /*  start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx\n         *  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR\n         *                                                12345678901234567890123456\n         *  1 = msb 1 bit\n         *  P = bit DBL_MANT_DIG-1 bits to the right of 1\n         *  Q = bit DBL_MANT_DIG bits to the right of 1\n         *  R = \"or\" of all bits to the right of Q\n         */\n        switch (sd)\n        {\n        case DBL_MANT_DIG + 1:\n            a <<= 1;\n            break;\n        case DBL_MANT_DIG + 2:\n            break;\n        default:\n            a = (a >> (sd - (DBL_MANT_DIG+2))) |\n                ((a & ((du_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);\n        };\n        /* finish: */\n        a |= (a & 4) != 0;  /* Or P into R */\n        ++a;  /* round - this step may add a significant bit */\n        a >>= 2;  /* dump Q and R */\n        /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */\n        if (a & ((du_int)1 << DBL_MANT_DIG))\n        {\n            a >>= 1;\n            ++e;\n        }\n        /* a is now rounded to DBL_MANT_DIG bits */\n    }\n    else\n    {\n        a <<= (DBL_MANT_DIG - sd);\n        /* a is now rounded to DBL_MANT_DIG bits */\n    }\n    double_bits fb;\n    fb.u.high = ((e + 1023) << 20)      |        /* exponent */\n                ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */\n    fb.u.low = (su_int)a;                         /* mantissa-low  */\n    return fb.f;\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatundisf.c",
    "content": "/*===-- floatundisf.c - Implement __floatundisf ---------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __floatundisf for the compiler_rt library.\n *\n *===----------------------------------------------------------------------===\n */\n\n/* Returns: convert a to a float, rounding toward even. */\n\n/* Assumption: float is a IEEE 32 bit floating point type \n *            du_int is a 64 bit integral type\n */\n\n/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */\n\n#include \"int_lib.h\"\n\nARM_EABI_FNALIAS(ul2f, floatundisf)\n\nCOMPILER_RT_ABI float\n__floatundisf(du_int a)\n{\n    if (a == 0)\n        return 0.0F;\n    const unsigned N = sizeof(du_int) * CHAR_BIT;\n    int sd = N - __builtin_clzll(a);  /* number of significant digits */\n    int e = sd - 1;             /* 8 exponent */\n    if (sd > FLT_MANT_DIG)\n    {\n        /*  start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx\n         *  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR\n         *                                                12345678901234567890123456\n         *  1 = msb 1 bit\n         *  P = bit FLT_MANT_DIG-1 bits to the right of 1\n         *  Q = bit FLT_MANT_DIG bits to the right of 1\n         *  R = \"or\" of all bits to the right of Q\n         */\n        switch (sd)\n        {\n        case FLT_MANT_DIG + 1:\n            a <<= 1;\n            break;\n        case FLT_MANT_DIG + 2:\n            break;\n        default:\n            a = (a >> (sd - (FLT_MANT_DIG+2))) |\n                ((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);\n        };\n        /* finish: */\n        a |= (a & 4) != 0;  /* Or P into R */\n        ++a;  /* round - this step may add a significant bit */\n        a >>= 2;  /* dump Q and R */\n        /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */\n        if (a & ((du_int)1 << FLT_MANT_DIG))\n        {\n            a >>= 1;\n            ++e;\n        }\n        /* a is now rounded to FLT_MANT_DIG bits */\n    }\n    else\n    {\n        a <<= (FLT_MANT_DIG - sd);\n        /* a is now rounded to FLT_MANT_DIG bits */\n    }\n    float_bits fb;\n    fb.u = ((e + 127) << 23)       |  /* exponent */\n           ((su_int)a & 0x007FFFFF);  /* mantissa */\n    return fb.f;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatunditf.c",
    "content": "//===-- lib/floatunditf.c - uint -> quad-precision conversion -----*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements du_int to quad-precision conversion for the\n// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even\n// mode.\n//\n//===----------------------------------------------------------------------===//\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\nCOMPILER_RT_ABI fp_t __floatunditf(du_int a) {\n\n    const int aWidth = sizeof a * CHAR_BIT;\n\n    // Handle zero as a special case to protect clz\n    if (a == 0) return fromRep(0);\n\n    // Exponent of (fp_t)a is the width of abs(a).\n    const int exponent = (aWidth - 1) - __builtin_clzll(a);\n    rep_t result;\n\n    // Shift a into the significand field and clear the implicit bit.\n    const int shift = significandBits - exponent;\n    result = (rep_t)a << shift ^ implicitBit;\n\n    // Insert the exponent\n    result += (rep_t)(exponent + exponentBias) << significandBits;\n    return fromRep(result);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatundixf.c",
    "content": "/* ===-- floatundixf.c - Implement __floatundixf ---------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __floatundixf for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#if !_ARCH_PPC\n\n#include \"int_lib.h\"\n\n/* Returns: convert a to a long double, rounding toward even. */\n\n/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits\n *             du_int is a 64 bit integral type\n */\n\n/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |\n * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm\n */\nCOMPILER_RT_ABI long double\n__floatundixf(du_int a)\n{\n    if (a == 0)\n        return 0.0;\n    const unsigned N = sizeof(du_int) * CHAR_BIT;\n    int clz = __builtin_clzll(a);\n    int e = (N - 1) - clz ;    /* exponent */\n    long_double_bits fb;\n    fb.u.high.s.low = (e + 16383);              /* exponent */\n    fb.u.low.all = a << clz;                   /* mantissa */\n    return fb.f;\n}\n\n#endif /* _ARCH_PPC */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatunsidf.c",
    "content": "//===-- lib/floatunsidf.c - uint -> double-precision conversion ---*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements unsigned integer to double-precision conversion for the\n// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even\n// mode.\n//\n//===----------------------------------------------------------------------===//\n\n#define DOUBLE_PRECISION\n#include \"fp_lib.h\"\n\n#include \"int_lib.h\"\n\nARM_EABI_FNALIAS(ui2d, floatunsidf)\n\nCOMPILER_RT_ABI fp_t\n__floatunsidf(unsigned int a) {\n    \n    const int aWidth = sizeof a * CHAR_BIT;\n    \n    // Handle zero as a special case to protect clz\n    if (a == 0) return fromRep(0);\n    \n    // Exponent of (fp_t)a is the width of abs(a).\n    const int exponent = (aWidth - 1) - __builtin_clz(a);\n    rep_t result;\n    \n    // Shift a into the significand field and clear the implicit bit.\n    const int shift = significandBits - exponent;\n    result = (rep_t)a << shift ^ implicitBit;\n    \n    // Insert the exponent\n    result += (rep_t)(exponent + exponentBias) << significandBits;\n    return fromRep(result);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatunsisf.c",
    "content": "//===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements unsigned integer to single-precision conversion for the\n// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even\n// mode.\n//\n//===----------------------------------------------------------------------===//\n\n#define SINGLE_PRECISION\n#include \"fp_lib.h\"\n\n#include \"int_lib.h\"\n\nARM_EABI_FNALIAS(ui2f, floatunsisf)\n\nCOMPILER_RT_ABI fp_t\n__floatunsisf(unsigned int a) {\n    \n    const int aWidth = sizeof a * CHAR_BIT;\n    \n    // Handle zero as a special case to protect clz\n    if (a == 0) return fromRep(0);\n    \n    // Exponent of (fp_t)a is the width of abs(a).\n    const int exponent = (aWidth - 1) - __builtin_clz(a);\n    rep_t result;\n    \n    // Shift a into the significand field, rounding if it is a right-shift\n    if (exponent <= significandBits) {\n        const int shift = significandBits - exponent;\n        result = (rep_t)a << shift ^ implicitBit;\n    } else {\n        const int shift = exponent - significandBits;\n        result = (rep_t)a >> shift ^ implicitBit;\n        rep_t round = (rep_t)a << (typeWidth - shift);\n        if (round > signBit) result++;\n        if (round == signBit) result += result & 1;\n    }\n    \n    // Insert the exponent\n    result += (rep_t)(exponent + exponentBias) << significandBits;\n    return fromRep(result);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatunsitf.c",
    "content": "//===-- lib/floatunsitf.c - uint -> quad-precision conversion -----*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements unsigned integer to quad-precision conversion for the\n// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even\n// mode.\n//\n//===----------------------------------------------------------------------===//\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\nCOMPILER_RT_ABI fp_t __floatunsitf(unsigned int a) {\n\n    const int aWidth = sizeof a * CHAR_BIT;\n\n    // Handle zero as a special case to protect clz\n    if (a == 0) return fromRep(0);\n\n    // Exponent of (fp_t)a is the width of abs(a).\n    const int exponent = (aWidth - 1) - __builtin_clz(a);\n    rep_t result;\n\n    // Shift a into the significand field and clear the implicit bit.\n    const int shift = significandBits - exponent;\n    result = (rep_t)a << shift ^ implicitBit;\n\n    // Insert the exponent\n    result += (rep_t)(exponent + exponentBias) << significandBits;\n    return fromRep(result);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatuntidf.c",
    "content": "/* ===-- floatuntidf.c - Implement __floatuntidf ---------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __floatuntidf for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: convert a to a double, rounding toward even. */\n\n/* Assumption: double is a IEEE 64 bit floating point type \n *             tu_int is a 128 bit integral type\n */\n\n/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */\n\nCOMPILER_RT_ABI double\n__floatuntidf(tu_int a)\n{\n    if (a == 0)\n        return 0.0;\n    const unsigned N = sizeof(tu_int) * CHAR_BIT;\n    int sd = N - __clzti2(a);  /* number of significant digits */\n    int e = sd - 1;             /* exponent */\n    if (sd > DBL_MANT_DIG)\n    {\n        /*  start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx\n         *  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR\n         *                                                12345678901234567890123456\n         *  1 = msb 1 bit\n         *  P = bit DBL_MANT_DIG-1 bits to the right of 1\n         *  Q = bit DBL_MANT_DIG bits to the right of 1\n         *  R = \"or\" of all bits to the right of Q\n         */\n        switch (sd)\n        {\n        case DBL_MANT_DIG + 1:\n            a <<= 1;\n            break;\n        case DBL_MANT_DIG + 2:\n            break;\n        default:\n            a = (a >> (sd - (DBL_MANT_DIG+2))) |\n                ((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0);\n        };\n        /* finish: */\n        a |= (a & 4) != 0;  /* Or P into R */\n        ++a;  /* round - this step may add a significant bit */\n        a >>= 2;  /* dump Q and R */\n        /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */\n        if (a & ((tu_int)1 << DBL_MANT_DIG))\n        {\n            a >>= 1;\n            ++e;\n        }\n        /* a is now rounded to DBL_MANT_DIG bits */\n    }\n    else\n    {\n        a <<= (DBL_MANT_DIG - sd);\n        /* a is now rounded to DBL_MANT_DIG bits */\n    }\n    double_bits fb;\n    fb.u.s.high = ((e + 1023) << 20)      |        /* exponent */\n                ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */\n    fb.u.s.low = (su_int)a;                         /* mantissa-low */\n    return fb.f;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatuntisf.c",
    "content": "/* ===-- floatuntisf.c - Implement __floatuntisf ---------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __floatuntisf for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: convert a to a float, rounding toward even. */\n\n/* Assumption: float is a IEEE 32 bit floating point type \n *             tu_int is a 128 bit integral type\n */\n\n/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */\n\nCOMPILER_RT_ABI float\n__floatuntisf(tu_int a)\n{\n    if (a == 0)\n        return 0.0F;\n    const unsigned N = sizeof(tu_int) * CHAR_BIT;\n    int sd = N - __clzti2(a);  /* number of significant digits */\n    int e = sd - 1;             /* exponent */\n    if (sd > FLT_MANT_DIG)\n    {\n        /*  start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx\n         *  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR\n         *                                                12345678901234567890123456\n         *  1 = msb 1 bit\n         *  P = bit FLT_MANT_DIG-1 bits to the right of 1\n         *  Q = bit FLT_MANT_DIG bits to the right of 1\n         *  R = \"or\" of all bits to the right of Q\n\t */\n        switch (sd)\n        {\n        case FLT_MANT_DIG + 1:\n            a <<= 1;\n            break;\n        case FLT_MANT_DIG + 2:\n            break;\n        default:\n            a = (a >> (sd - (FLT_MANT_DIG+2))) |\n                ((a & ((tu_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0);\n        };\n        /* finish: */\n        a |= (a & 4) != 0;  /* Or P into R */\n        ++a;  /* round - this step may add a significant bit */\n        a >>= 2;  /* dump Q and R */\n        /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */\n        if (a & ((tu_int)1 << FLT_MANT_DIG))\n        {\n            a >>= 1;\n            ++e;\n        }\n        /* a is now rounded to FLT_MANT_DIG bits */\n    }\n    else\n    {\n        a <<= (FLT_MANT_DIG - sd);\n        /* a is now rounded to FLT_MANT_DIG bits */\n    }\n    float_bits fb;\n    fb.u = ((e + 127) << 23)       |  /* exponent */\n           ((su_int)a & 0x007FFFFF);  /* mantissa */\n    return fb.f;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/floatuntixf.c",
    "content": "/* ===-- floatuntixf.c - Implement __floatuntixf ---------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __floatuntixf for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: convert a to a long double, rounding toward even. */\n\n/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits\n *             tu_int is a 128 bit integral type\n */\n\n/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |\n * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm\n */\n\nCOMPILER_RT_ABI long double\n__floatuntixf(tu_int a)\n{\n    if (a == 0)\n        return 0.0;\n    const unsigned N = sizeof(tu_int) * CHAR_BIT;\n    int sd = N - __clzti2(a);  /* number of significant digits */\n    int e = sd - 1;             /* exponent */\n    if (sd > LDBL_MANT_DIG)\n    {\n        /*  start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx\n         *  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR\n         *                                                12345678901234567890123456\n         *  1 = msb 1 bit\n         *  P = bit LDBL_MANT_DIG-1 bits to the right of 1\n         *  Q = bit LDBL_MANT_DIG bits to the right of 1\n         *  R = \"or\" of all bits to the right of Q\n\t */\n        switch (sd)\n        {\n        case LDBL_MANT_DIG + 1:\n            a <<= 1;\n            break;\n        case LDBL_MANT_DIG + 2:\n            break;\n        default:\n            a = (a >> (sd - (LDBL_MANT_DIG+2))) |\n                ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0);\n        };\n        /* finish: */\n        a |= (a & 4) != 0;  /* Or P into R */\n        ++a;  /* round - this step may add a significant bit */\n        a >>= 2;  /* dump Q and R */\n        /* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */\n        if (a & ((tu_int)1 << LDBL_MANT_DIG))\n        {\n            a >>= 1;\n            ++e;\n        }\n        /* a is now rounded to LDBL_MANT_DIG bits */\n    }\n    else\n    {\n        a <<= (LDBL_MANT_DIG - sd);\n        /* a is now rounded to LDBL_MANT_DIG bits */\n    }\n    long_double_bits fb;\n    fb.u.high.s.low = (e + 16383);                  /* exponent */\n    fb.u.low.all = (du_int)a;                     /* mantissa */\n    return fb.f;\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fp_add_impl.inc",
    "content": "//===----- lib/fp_add_impl.inc - floaing point addition -----------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements soft-float addition with the IEEE-754 default rounding\n// (to nearest, ties to even).\n//\n//===----------------------------------------------------------------------===//\n\n#include \"fp_lib.h\"\n\nstatic __inline fp_t __addXf3__(fp_t a, fp_t b) {\n    rep_t aRep = toRep(a);\n    rep_t bRep = toRep(b);\n    const rep_t aAbs = aRep & absMask;\n    const rep_t bAbs = bRep & absMask;\n\n    // Detect if a or b is zero, infinity, or NaN.\n    if (aAbs - REP_C(1) >= infRep - REP_C(1) ||\n        bAbs - REP_C(1) >= infRep - REP_C(1)) {\n        // NaN + anything = qNaN\n        if (aAbs > infRep) return fromRep(toRep(a) | quietBit);\n        // anything + NaN = qNaN\n        if (bAbs > infRep) return fromRep(toRep(b) | quietBit);\n\n        if (aAbs == infRep) {\n            // +/-infinity + -/+infinity = qNaN\n            if ((toRep(a) ^ toRep(b)) == signBit) return fromRep(qnanRep);\n            // +/-infinity + anything remaining = +/- infinity\n            else return a;\n        }\n\n        // anything remaining + +/-infinity = +/-infinity\n        if (bAbs == infRep) return b;\n\n        // zero + anything = anything\n        if (!aAbs) {\n            // but we need to get the sign right for zero + zero\n            if (!bAbs) return fromRep(toRep(a) & toRep(b));\n            else return b;\n        }\n\n        // anything + zero = anything\n        if (!bAbs) return a;\n    }\n\n    // Swap a and b if necessary so that a has the larger absolute value.\n    if (bAbs > aAbs) {\n        const rep_t temp = aRep;\n        aRep = bRep;\n        bRep = temp;\n    }\n\n    // Extract the exponent and significand from the (possibly swapped) a and b.\n    int aExponent = aRep >> significandBits & maxExponent;\n    int bExponent = bRep >> significandBits & maxExponent;\n    rep_t aSignificand = aRep & significandMask;\n    rep_t bSignificand = bRep & significandMask;\n\n    // Normalize any denormals, and adjust the exponent accordingly.\n    if (aExponent == 0) aExponent = normalize(&aSignificand);\n    if (bExponent == 0) bExponent = normalize(&bSignificand);\n\n    // The sign of the result is the sign of the larger operand, a.  If they\n    // have opposite signs, we are performing a subtraction; otherwise addition.\n    const rep_t resultSign = aRep & signBit;\n    const bool subtraction = (aRep ^ bRep) & signBit;\n\n    // Shift the significands to give us round, guard and sticky, and or in the\n    // implicit significand bit.  (If we fell through from the denormal path it\n    // was already set by normalize( ), but setting it twice won't hurt\n    // anything.)\n    aSignificand = (aSignificand | implicitBit) << 3;\n    bSignificand = (bSignificand | implicitBit) << 3;\n\n    // Shift the significand of b by the difference in exponents, with a sticky\n    // bottom bit to get rounding correct.\n    const unsigned int align = aExponent - bExponent;\n    if (align) {\n        if (align < typeWidth) {\n            const bool sticky = bSignificand << (typeWidth - align);\n            bSignificand = bSignificand >> align | sticky;\n        } else {\n            bSignificand = 1; // sticky; b is known to be non-zero.\n        }\n    }\n    if (subtraction) {\n        aSignificand -= bSignificand;\n        // If a == -b, return +zero.\n        if (aSignificand == 0) return fromRep(0);\n\n        // If partial cancellation occured, we need to left-shift the result\n        // and adjust the exponent:\n        if (aSignificand < implicitBit << 3) {\n            const int shift = rep_clz(aSignificand) - rep_clz(implicitBit << 3);\n            aSignificand <<= shift;\n            aExponent -= shift;\n        }\n    }\n    else /* addition */ {\n        aSignificand += bSignificand;\n\n        // If the addition carried up, we need to right-shift the result and\n        // adjust the exponent:\n        if (aSignificand & implicitBit << 4) {\n            const bool sticky = aSignificand & 1;\n            aSignificand = aSignificand >> 1 | sticky;\n            aExponent += 1;\n        }\n    }\n\n    // If we have overflowed the type, return +/- infinity:\n    if (aExponent >= maxExponent) return fromRep(infRep | resultSign);\n\n    if (aExponent <= 0) {\n        // Result is denormal before rounding; the exponent is zero and we\n        // need to shift the significand.\n        const int shift = 1 - aExponent;\n        const bool sticky = aSignificand << (typeWidth - shift);\n        aSignificand = aSignificand >> shift | sticky;\n        aExponent = 0;\n    }\n\n    // Low three bits are round, guard, and sticky.\n    const int roundGuardSticky = aSignificand & 0x7;\n\n    // Shift the significand into place, and mask off the implicit bit.\n    rep_t result = aSignificand >> 3 & significandMask;\n\n    // Insert the exponent and sign.\n    result |= (rep_t)aExponent << significandBits;\n    result |= resultSign;\n\n    // Final rounding.  The result may overflow to infinity, but that is the\n    // correct result in that case.\n    if (roundGuardSticky > 0x4) result++;\n    if (roundGuardSticky == 0x4) result += result & 1;\n    return fromRep(result);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fp_extend.h",
    "content": "//===-lib/fp_extend.h - low precision -> high precision conversion -*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Set source and destination setting\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef FP_EXTEND_HEADER\n#define FP_EXTEND_HEADER\n\n#include \"int_lib.h\"\n\n#if defined SRC_SINGLE\ntypedef float src_t;\ntypedef uint32_t src_rep_t;\n#define SRC_REP_C UINT32_C\nstatic const int srcSigBits = 23;\n#define src_rep_t_clz __builtin_clz\n\n#elif defined SRC_DOUBLE\ntypedef double src_t;\ntypedef uint64_t src_rep_t;\n#define SRC_REP_C UINT64_C\nstatic const int srcSigBits = 52;\nstatic __inline int src_rep_t_clz(src_rep_t a) {\n#if defined __LP64__\n    return __builtin_clzl(a);\n#else\n    if (a & REP_C(0xffffffff00000000))\n        return __builtin_clz(a >> 32);\n    else\n        return 32 + __builtin_clz(a & REP_C(0xffffffff));\n#endif\n}\n\n#elif defined SRC_HALF\ntypedef uint16_t src_t;\ntypedef uint16_t src_rep_t;\n#define SRC_REP_C UINT16_C\nstatic const int srcSigBits = 10;\n#define src_rep_t_clz __builtin_clz\n\n#else\n#error Source should be half, single, or double precision!\n#endif //end source precision\n\n#if defined DST_SINGLE\ntypedef float dst_t;\ntypedef uint32_t dst_rep_t;\n#define DST_REP_C UINT32_C\nstatic const int dstSigBits = 23;\n\n#elif defined DST_DOUBLE\ntypedef double dst_t;\ntypedef uint64_t dst_rep_t;\n#define DST_REP_C UINT64_C\nstatic const int dstSigBits = 52;\n\n#elif defined DST_QUAD\ntypedef long double dst_t;\ntypedef __uint128_t dst_rep_t;\n#define DST_REP_C (__uint128_t)\nstatic const int dstSigBits = 112;\n\n#else\n#error Destination should be single, double, or quad precision!\n#endif //end destination precision\n\n// End of specialization parameters.  Two helper routines for conversion to and\n// from the representation of floating-point data as integer values follow.\n\nstatic __inline src_rep_t srcToRep(src_t x) {\n    const union { src_t f; src_rep_t i; } rep = {.f = x};\n    return rep.i;\n}\n\nstatic __inline dst_t dstFromRep(dst_rep_t x) {\n    const union { dst_t f; dst_rep_t i; } rep = {.i = x};\n    return rep.f;\n}\n// End helper routines.  Conversion implementation follows.\n\n#endif //FP_EXTEND_HEADER\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fp_extend_impl.inc",
    "content": "//=-lib/fp_extend_impl.inc - low precision -> high precision conversion -*-- -//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements a fairly generic conversion from a narrower to a wider\n// IEEE-754 floating-point type.  The constants and types defined following the\n// includes below parameterize the conversion.\n//\n// It does not support types that don't use the usual IEEE-754 interchange\n// formats; specifically, some work would be needed to adapt it to\n// (for example) the Intel 80-bit format or PowerPC double-double format.\n//\n// Note please, however, that this implementation is only intended to support\n// *widening* operations; if you need to convert to a *narrower* floating-point\n// type (e.g. double -> float), then this routine will not do what you want it\n// to.\n//\n// It also requires that integer types at least as large as both formats\n// are available on the target platform; this may pose a problem when trying\n// to add support for quad on some 32-bit systems, for example.  You also may\n// run into trouble finding an appropriate CLZ function for wide source types;\n// you will likely need to roll your own on some platforms.\n//\n// Finally, the following assumptions are made:\n//\n// 1. floating-point types and integer types have the same endianness on the\n//    target platform\n//\n// 2. quiet NaNs, if supported, are indicated by the leading bit of the\n//    significand field being set\n//\n//===----------------------------------------------------------------------===//\n\n#include \"fp_extend.h\"\n\nstatic __inline dst_t __extendXfYf2__(src_t a) {\n    // Various constants whose values follow from the type parameters.\n    // Any reasonable optimizer will fold and propagate all of these.\n    const int srcBits = sizeof(src_t)*CHAR_BIT;\n    const int srcExpBits = srcBits - srcSigBits - 1;\n    const int srcInfExp = (1 << srcExpBits) - 1;\n    const int srcExpBias = srcInfExp >> 1;\n\n    const src_rep_t srcMinNormal = SRC_REP_C(1) << srcSigBits;\n    const src_rep_t srcInfinity = (src_rep_t)srcInfExp << srcSigBits;\n    const src_rep_t srcSignMask = SRC_REP_C(1) << (srcSigBits + srcExpBits);\n    const src_rep_t srcAbsMask = srcSignMask - 1;\n    const src_rep_t srcQNaN = SRC_REP_C(1) << (srcSigBits - 1);\n    const src_rep_t srcNaNCode = srcQNaN - 1;\n\n    const int dstBits = sizeof(dst_t)*CHAR_BIT;\n    const int dstExpBits = dstBits - dstSigBits - 1;\n    const int dstInfExp = (1 << dstExpBits) - 1;\n    const int dstExpBias = dstInfExp >> 1;\n\n    const dst_rep_t dstMinNormal = DST_REP_C(1) << dstSigBits;\n\n    // Break a into a sign and representation of the absolute value\n    const src_rep_t aRep = srcToRep(a);\n    const src_rep_t aAbs = aRep & srcAbsMask;\n    const src_rep_t sign = aRep & srcSignMask;\n    dst_rep_t absResult;\n\n    // If sizeof(src_rep_t) < sizeof(int), the subtraction result is promoted\n    // to (signed) int.  To avoid that, explicitly cast to src_rep_t.\n    if ((src_rep_t)(aAbs - srcMinNormal) < srcInfinity - srcMinNormal) {\n        // a is a normal number.\n        // Extend to the destination type by shifting the significand and\n        // exponent into the proper position and rebiasing the exponent.\n        absResult = (dst_rep_t)aAbs << (dstSigBits - srcSigBits);\n        absResult += (dst_rep_t)(dstExpBias - srcExpBias) << dstSigBits;\n    }\n\n    else if (aAbs >= srcInfinity) {\n        // a is NaN or infinity.\n        // Conjure the result by beginning with infinity, then setting the qNaN\n        // bit (if needed) and right-aligning the rest of the trailing NaN\n        // payload field.\n        absResult = (dst_rep_t)dstInfExp << dstSigBits;\n        absResult |= (dst_rep_t)(aAbs & srcQNaN) << (dstSigBits - srcSigBits);\n        absResult |= (dst_rep_t)(aAbs & srcNaNCode) << (dstSigBits - srcSigBits);\n    }\n\n    else if (aAbs) {\n        // a is denormal.\n        // renormalize the significand and clear the leading bit, then insert\n        // the correct adjusted exponent in the destination type.\n        const int scale = src_rep_t_clz(aAbs) - src_rep_t_clz(srcMinNormal);\n        absResult = (dst_rep_t)aAbs << (dstSigBits - srcSigBits + scale);\n        absResult ^= dstMinNormal;\n        const int resultExponent = dstExpBias - srcExpBias - scale + 1;\n        absResult |= (dst_rep_t)resultExponent << dstSigBits;\n    }\n\n    else {\n        // a is zero.\n        absResult = 0;\n    }\n\n    // Apply the signbit to (dst_t)abs(a).\n    const dst_rep_t result = absResult | (dst_rep_t)sign << (dstBits - srcBits);\n    return dstFromRep(result);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fp_fixint_impl.inc",
    "content": "//===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements float to integer conversion for the\n// compiler-rt library.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"fp_lib.h\"\n\nstatic __inline fixint_t __fixint(fp_t a) {\n    const fixint_t fixint_max = (fixint_t)((~(fixuint_t)0) / 2);\n    const fixint_t fixint_min = -fixint_max - 1;\n    // Break a into sign, exponent, significand\n    const rep_t aRep = toRep(a);\n    const rep_t aAbs = aRep & absMask;\n    const fixint_t sign = aRep & signBit ? -1 : 1;\n    const int exponent = (aAbs >> significandBits) - exponentBias;\n    const rep_t significand = (aAbs & significandMask) | implicitBit;\n\n    // If exponent is negative, the result is zero.\n    if (exponent < 0)\n        return 0;\n\n    // If the value is too large for the integer type, saturate.\n    if ((unsigned)exponent >= sizeof(fixint_t) * CHAR_BIT)\n        return sign == 1 ? fixint_max : fixint_min;\n\n    // If 0 <= exponent < significandBits, right shift to get the result.\n    // Otherwise, shift left.\n    if (exponent < significandBits)\n        return sign * (significand >> (significandBits - exponent));\n    else\n        return sign * ((fixint_t)significand << (exponent - significandBits));\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fp_fixuint_impl.inc",
    "content": "//===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements float to unsigned integer conversion for the\n// compiler-rt library.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"fp_lib.h\"\n\nstatic __inline fixuint_t __fixuint(fp_t a) {\n    // Break a into sign, exponent, significand\n    const rep_t aRep = toRep(a);\n    const rep_t aAbs = aRep & absMask;\n    const int sign = aRep & signBit ? -1 : 1;\n    const int exponent = (aAbs >> significandBits) - exponentBias;\n    const rep_t significand = (aAbs & significandMask) | implicitBit;\n\n    // If either the value or the exponent is negative, the result is zero.\n    if (sign == -1 || exponent < 0)\n        return 0;\n\n    // If the value is too large for the integer type, saturate.\n    if ((unsigned)exponent >= sizeof(fixuint_t) * CHAR_BIT)\n        return ~(fixuint_t)0;\n\n    // If 0 <= exponent < significandBits, right shift to get the result.\n    // Otherwise, shift left.\n    if (exponent < significandBits)\n        return significand >> (significandBits - exponent);\n    else\n        return (fixuint_t)significand << (exponent - significandBits);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fp_lib.h",
    "content": "//===-- lib/fp_lib.h - Floating-point utilities -------------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a configuration header for soft-float routines in compiler-rt.\n// This file does not provide any part of the compiler-rt interface, but defines\n// many useful constants and utility routines that are used in the\n// implementation of the soft-float routines in compiler-rt.\n//\n// Assumes that float, double and long double correspond to the IEEE-754\n// binary32, binary64 and binary 128 types, respectively, and that integer\n// endianness matches floating point endianness on the target platform.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef FP_LIB_HEADER\n#define FP_LIB_HEADER\n\n#include <stdint.h>\n#include <stdbool.h>\n#include <limits.h>\n#include \"int_lib.h\"\n\n// x86_64 FreeBSD prior v9.3 define fixed-width types incorrectly in\n// 32-bit mode.\n#if defined(__FreeBSD__) && defined(__i386__)\n# include <sys/param.h>\n# if __FreeBSD_version < 903000  // v9.3\n#  define uint64_t unsigned long long\n#  define int64_t long long\n#  undef UINT64_C\n#  define UINT64_C(c) (c ## ULL)\n# endif\n#endif\n\n#if defined SINGLE_PRECISION\n\ntypedef uint32_t rep_t;\ntypedef int32_t srep_t;\ntypedef float fp_t;\n#define REP_C UINT32_C\n#define significandBits 23\n\nstatic __inline int rep_clz(rep_t a) {\n    return __builtin_clz(a);\n}\n\n// 32x32 --> 64 bit multiply\nstatic __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {\n    const uint64_t product = (uint64_t)a*b;\n    *hi = product >> 32;\n    *lo = product;\n}\nCOMPILER_RT_ABI fp_t __addsf3(fp_t a, fp_t b);\n\n#elif defined DOUBLE_PRECISION\n\ntypedef uint64_t rep_t;\ntypedef int64_t srep_t;\ntypedef double fp_t;\n#define REP_C UINT64_C\n#define significandBits 52\n\nstatic __inline int rep_clz(rep_t a) {\n#if defined __LP64__\n    return __builtin_clzl(a);\n#else\n    if (a & REP_C(0xffffffff00000000))\n        return __builtin_clz(a >> 32);\n    else\n        return 32 + __builtin_clz(a & REP_C(0xffffffff));\n#endif\n}\n\n#define loWord(a) (a & 0xffffffffU)\n#define hiWord(a) (a >> 32)\n\n// 64x64 -> 128 wide multiply for platforms that don't have such an operation;\n// many 64-bit platforms have this operation, but they tend to have hardware\n// floating-point, so we don't bother with a special case for them here.\nstatic __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {\n    // Each of the component 32x32 -> 64 products\n    const uint64_t plolo = loWord(a) * loWord(b);\n    const uint64_t plohi = loWord(a) * hiWord(b);\n    const uint64_t philo = hiWord(a) * loWord(b);\n    const uint64_t phihi = hiWord(a) * hiWord(b);\n    // Sum terms that contribute to lo in a way that allows us to get the carry\n    const uint64_t r0 = loWord(plolo);\n    const uint64_t r1 = hiWord(plolo) + loWord(plohi) + loWord(philo);\n    *lo = r0 + (r1 << 32);\n    // Sum terms contributing to hi with the carry from lo\n    *hi = hiWord(plohi) + hiWord(philo) + hiWord(r1) + phihi;\n}\n#undef loWord\n#undef hiWord\n\nCOMPILER_RT_ABI fp_t __adddf3(fp_t a, fp_t b);\n\n#elif defined QUAD_PRECISION\n#if __LDBL_MANT_DIG__ == 113\n#define CRT_LDBL_128BIT\ntypedef __uint128_t rep_t;\ntypedef __int128_t srep_t;\ntypedef long double fp_t;\n#define REP_C (__uint128_t)\n// Note: Since there is no explicit way to tell compiler the constant is a\n// 128-bit integer, we let the constant be casted to 128-bit integer\n#define significandBits 112\n\nstatic __inline int rep_clz(rep_t a) {\n    const union\n        {\n             __uint128_t ll;\n#if _YUGA_BIG_ENDIAN\n             struct { uint64_t high, low; } s;\n#else\n             struct { uint64_t low, high; } s;\n#endif\n        } uu = { .ll = a };\n\n    uint64_t word;\n    uint64_t add;\n\n    if (uu.s.high){\n        word = uu.s.high;\n        add = 0;\n    }\n    else{\n        word = uu.s.low;\n        add = 64;\n    }\n    return __builtin_clzll(word) + add;\n}\n\n#define Word_LoMask   UINT64_C(0x00000000ffffffff)\n#define Word_HiMask   UINT64_C(0xffffffff00000000)\n#define Word_FullMask UINT64_C(0xffffffffffffffff)\n#define Word_1(a) (uint64_t)((a >> 96) & Word_LoMask)\n#define Word_2(a) (uint64_t)((a >> 64) & Word_LoMask)\n#define Word_3(a) (uint64_t)((a >> 32) & Word_LoMask)\n#define Word_4(a) (uint64_t)(a & Word_LoMask)\n\n// 128x128 -> 256 wide multiply for platforms that don't have such an operation;\n// many 64-bit platforms have this operation, but they tend to have hardware\n// floating-point, so we don't bother with a special case for them here.\nstatic __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) {\n\n    const uint64_t product11 = Word_1(a) * Word_1(b);\n    const uint64_t product12 = Word_1(a) * Word_2(b);\n    const uint64_t product13 = Word_1(a) * Word_3(b);\n    const uint64_t product14 = Word_1(a) * Word_4(b);\n    const uint64_t product21 = Word_2(a) * Word_1(b);\n    const uint64_t product22 = Word_2(a) * Word_2(b);\n    const uint64_t product23 = Word_2(a) * Word_3(b);\n    const uint64_t product24 = Word_2(a) * Word_4(b);\n    const uint64_t product31 = Word_3(a) * Word_1(b);\n    const uint64_t product32 = Word_3(a) * Word_2(b);\n    const uint64_t product33 = Word_3(a) * Word_3(b);\n    const uint64_t product34 = Word_3(a) * Word_4(b);\n    const uint64_t product41 = Word_4(a) * Word_1(b);\n    const uint64_t product42 = Word_4(a) * Word_2(b);\n    const uint64_t product43 = Word_4(a) * Word_3(b);\n    const uint64_t product44 = Word_4(a) * Word_4(b);\n\n    const __uint128_t sum0 = (__uint128_t)product44;\n    const __uint128_t sum1 = (__uint128_t)product34 +\n                             (__uint128_t)product43;\n    const __uint128_t sum2 = (__uint128_t)product24 +\n                             (__uint128_t)product33 +\n                             (__uint128_t)product42;\n    const __uint128_t sum3 = (__uint128_t)product14 +\n                             (__uint128_t)product23 +\n                             (__uint128_t)product32 +\n                             (__uint128_t)product41;\n    const __uint128_t sum4 = (__uint128_t)product13 +\n                             (__uint128_t)product22 +\n                             (__uint128_t)product31;\n    const __uint128_t sum5 = (__uint128_t)product12 +\n                             (__uint128_t)product21;\n    const __uint128_t sum6 = (__uint128_t)product11;\n\n    const __uint128_t r0 = (sum0 & Word_FullMask) +\n                           ((sum1 & Word_LoMask) << 32);\n    const __uint128_t r1 = (sum0 >> 64) +\n                           ((sum1 >> 32) & Word_FullMask) +\n                           (sum2 & Word_FullMask) +\n                           ((sum3 << 32) & Word_HiMask);\n\n    *lo = r0 + (r1 << 64);\n    *hi = (r1 >> 64) +\n          (sum1 >> 96) +\n          (sum2 >> 64) +\n          (sum3 >> 32) +\n          sum4 +\n          (sum5 << 32) +\n          (sum6 << 64);\n}\n#undef Word_1\n#undef Word_2\n#undef Word_3\n#undef Word_4\n#undef Word_HiMask\n#undef Word_LoMask\n#undef Word_FullMask\n#endif // __LDBL_MANT_DIG__ == 113\n#else\n#error SINGLE_PRECISION, DOUBLE_PRECISION or QUAD_PRECISION must be defined.\n#endif\n\n#if defined(SINGLE_PRECISION) || defined(DOUBLE_PRECISION) || defined(CRT_LDBL_128BIT)\n#define typeWidth       (sizeof(rep_t)*CHAR_BIT)\n#define exponentBits    (typeWidth - significandBits - 1)\n#define maxExponent     ((1 << exponentBits) - 1)\n#define exponentBias    (maxExponent >> 1)\n\n#define implicitBit     (REP_C(1) << significandBits)\n#define significandMask (implicitBit - 1U)\n#define signBit         (REP_C(1) << (significandBits + exponentBits))\n#define absMask         (signBit - 1U)\n#define exponentMask    (absMask ^ significandMask)\n#define oneRep          ((rep_t)exponentBias << significandBits)\n#define infRep          exponentMask\n#define quietBit        (implicitBit >> 1)\n#define qnanRep         (exponentMask | quietBit)\n\nstatic __inline rep_t toRep(fp_t x) {\n    const union { fp_t f; rep_t i; } rep = {.f = x};\n    return rep.i;\n}\n\nstatic __inline fp_t fromRep(rep_t x) {\n    const union { fp_t f; rep_t i; } rep = {.i = x};\n    return rep.f;\n}\n\nstatic __inline int normalize(rep_t *significand) {\n    const int shift = rep_clz(*significand) - rep_clz(implicitBit);\n    *significand <<= shift;\n    return 1 - shift;\n}\n\nstatic __inline void wideLeftShift(rep_t *hi, rep_t *lo, int count) {\n    *hi = *hi << count | *lo >> (typeWidth - count);\n    *lo = *lo << count;\n}\n\nstatic __inline void wideRightShiftWithSticky(rep_t *hi, rep_t *lo, unsigned int count) {\n    if (count < typeWidth) {\n        const bool sticky = *lo << (typeWidth - count);\n        *lo = *hi << (typeWidth - count) | *lo >> count | sticky;\n        *hi = *hi >> count;\n    }\n    else if (count < 2*typeWidth) {\n        const bool sticky = *hi << (2*typeWidth - count) | *lo;\n        *lo = *hi >> (count - typeWidth) | sticky;\n        *hi = 0;\n    } else {\n        const bool sticky = *hi | *lo;\n        *lo = sticky;\n        *hi = 0;\n    }\n}\n#endif\n\n#endif // FP_LIB_HEADER\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fp_mul_impl.inc",
    "content": "//===---- lib/fp_mul_impl.inc - floating point multiplication -----*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements soft-float multiplication with the IEEE-754 default\n// rounding (to nearest, ties to even).\n//\n//===----------------------------------------------------------------------===//\n\n#include \"fp_lib.h\"\n\nstatic __inline fp_t __mulXf3__(fp_t a, fp_t b) {\n    const unsigned int aExponent = toRep(a) >> significandBits & maxExponent;\n    const unsigned int bExponent = toRep(b) >> significandBits & maxExponent;\n    const rep_t productSign = (toRep(a) ^ toRep(b)) & signBit;\n\n    rep_t aSignificand = toRep(a) & significandMask;\n    rep_t bSignificand = toRep(b) & significandMask;\n    int scale = 0;\n\n    // Detect if a or b is zero, denormal, infinity, or NaN.\n    if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) {\n\n        const rep_t aAbs = toRep(a) & absMask;\n        const rep_t bAbs = toRep(b) & absMask;\n\n        // NaN * anything = qNaN\n        if (aAbs > infRep) return fromRep(toRep(a) | quietBit);\n        // anything * NaN = qNaN\n        if (bAbs > infRep) return fromRep(toRep(b) | quietBit);\n\n        if (aAbs == infRep) {\n            // infinity * non-zero = +/- infinity\n            if (bAbs) return fromRep(aAbs | productSign);\n            // infinity * zero = NaN\n            else return fromRep(qnanRep);\n        }\n\n        if (bAbs == infRep) {\n            //? non-zero * infinity = +/- infinity\n            if (aAbs) return fromRep(bAbs | productSign);\n            // zero * infinity = NaN\n            else return fromRep(qnanRep);\n        }\n\n        // zero * anything = +/- zero\n        if (!aAbs) return fromRep(productSign);\n        // anything * zero = +/- zero\n        if (!bAbs) return fromRep(productSign);\n\n        // one or both of a or b is denormal, the other (if applicable) is a\n        // normal number.  Renormalize one or both of a and b, and set scale to\n        // include the necessary exponent adjustment.\n        if (aAbs < implicitBit) scale += normalize(&aSignificand);\n        if (bAbs < implicitBit) scale += normalize(&bSignificand);\n    }\n\n    // Or in the implicit significand bit.  (If we fell through from the\n    // denormal path it was already set by normalize( ), but setting it twice\n    // won't hurt anything.)\n    aSignificand |= implicitBit;\n    bSignificand |= implicitBit;\n\n    // Get the significand of a*b.  Before multiplying the significands, shift\n    // one of them left to left-align it in the field.  Thus, the product will\n    // have (exponentBits + 2) integral digits, all but two of which must be\n    // zero.  Normalizing this result is just a conditional left-shift by one\n    // and bumping the exponent accordingly.\n    rep_t productHi, productLo;\n    wideMultiply(aSignificand, bSignificand << exponentBits,\n                 &productHi, &productLo);\n\n    int productExponent = aExponent + bExponent - exponentBias + scale;\n\n    // Normalize the significand, adjust exponent if needed.\n    if (productHi & implicitBit) productExponent++;\n    else wideLeftShift(&productHi, &productLo, 1);\n\n    // If we have overflowed the type, return +/- infinity.\n    if (productExponent >= maxExponent) return fromRep(infRep | productSign);\n\n    if (productExponent <= 0) {\n        // Result is denormal before rounding\n        //\n        // If the result is so small that it just underflows to zero, return\n        // a zero of the appropriate sign.  Mathematically there is no need to\n        // handle this case separately, but we make it a special case to\n        // simplify the shift logic.\n        const unsigned int shift = REP_C(1) - (unsigned int)productExponent;\n        if (shift >= typeWidth) return fromRep(productSign);\n\n        // Otherwise, shift the significand of the result so that the round\n        // bit is the high bit of productLo.\n        wideRightShiftWithSticky(&productHi, &productLo, shift);\n    }\n    else {\n        // Result is normal before rounding; insert the exponent.\n        productHi &= significandMask;\n        productHi |= (rep_t)productExponent << significandBits;\n    }\n\n    // Insert the sign of the result:\n    productHi |= productSign;\n\n    // Final rounding.  The final result may overflow to infinity, or underflow\n    // to zero, but those are the correct results in those cases.  We use the\n    // default IEEE-754 round-to-nearest, ties-to-even rounding mode.\n    if (productLo > signBit) productHi++;\n    if (productLo == signBit) productHi += productHi & 1;\n    return fromRep(productHi);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fp_trunc.h",
    "content": "//=== lib/fp_trunc.h - high precision -> low precision conversion *- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Set source and destination precision setting\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef FP_TRUNC_HEADER\n#define FP_TRUNC_HEADER\n\n#include \"int_lib.h\"\n\n#if defined SRC_SINGLE\ntypedef float src_t;\ntypedef uint32_t src_rep_t;\n#define SRC_REP_C UINT32_C\nstatic const int srcSigBits = 23;\n\n#elif defined SRC_DOUBLE\ntypedef double src_t;\ntypedef uint64_t src_rep_t;\n#define SRC_REP_C UINT64_C\nstatic const int srcSigBits = 52;\n\n#elif defined SRC_QUAD\ntypedef long double src_t;\ntypedef __uint128_t src_rep_t;\n#define SRC_REP_C (__uint128_t)\nstatic const int srcSigBits = 112;\n\n#else\n#error Source should be double precision or quad precision!\n#endif //end source precision\n\n#if defined DST_DOUBLE\ntypedef double dst_t;\ntypedef uint64_t dst_rep_t;\n#define DST_REP_C UINT64_C\nstatic const int dstSigBits = 52;\n\n#elif defined DST_SINGLE\ntypedef float dst_t;\ntypedef uint32_t dst_rep_t;\n#define DST_REP_C UINT32_C\nstatic const int dstSigBits = 23;\n\n#elif defined DST_HALF\ntypedef uint16_t dst_t;\ntypedef uint16_t dst_rep_t;\n#define DST_REP_C UINT16_C\nstatic const int dstSigBits = 10;\n\n#else\n#error Destination should be single precision or double precision!\n#endif //end destination precision\n\n// End of specialization parameters.  Two helper routines for conversion to and\n// from the representation of floating-point data as integer values follow.\n\nstatic __inline src_rep_t srcToRep(src_t x) {\n    const union { src_t f; src_rep_t i; } rep = {.f = x};\n    return rep.i;\n}\n\nstatic __inline dst_t dstFromRep(dst_rep_t x) {\n    const union { dst_t f; dst_rep_t i; } rep = {.i = x};\n    return rep.f;\n}\n\n#endif // FP_TRUNC_HEADER\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/fp_trunc_impl.inc",
    "content": "//= lib/fp_trunc_impl.inc - high precision -> low precision conversion *-*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements a fairly generic conversion from a wider to a narrower\n// IEEE-754 floating-point type in the default (round to nearest, ties to even)\n// rounding mode.  The constants and types defined following the includes below\n// parameterize the conversion.\n//\n// This routine can be trivially adapted to support conversions to\n// half-precision or from quad-precision. It does not support types that don't\n// use the usual IEEE-754 interchange formats; specifically, some work would be\n// needed to adapt it to (for example) the Intel 80-bit format or PowerPC\n// double-double format.\n//\n// Note please, however, that this implementation is only intended to support\n// *narrowing* operations; if you need to convert to a *wider* floating-point\n// type (e.g. float -> double), then this routine will not do what you want it\n// to.\n//\n// It also requires that integer types at least as large as both formats\n// are available on the target platform; this may pose a problem when trying\n// to add support for quad on some 32-bit systems, for example.\n//\n// Finally, the following assumptions are made:\n//\n// 1. floating-point types and integer types have the same endianness on the\n//    target platform\n//\n// 2. quiet NaNs, if supported, are indicated by the leading bit of the\n//    significand field being set\n//\n//===----------------------------------------------------------------------===//\n\n#include \"fp_trunc.h\"\n\nstatic __inline dst_t __truncXfYf2__(src_t a) {\n    // Various constants whose values follow from the type parameters.\n    // Any reasonable optimizer will fold and propagate all of these.\n    const int srcBits = sizeof(src_t)*CHAR_BIT;\n    const int srcExpBits = srcBits - srcSigBits - 1;\n    const int srcInfExp = (1 << srcExpBits) - 1;\n    const int srcExpBias = srcInfExp >> 1;\n\n    const src_rep_t srcMinNormal = SRC_REP_C(1) << srcSigBits;\n    const src_rep_t srcSignificandMask = srcMinNormal - 1;\n    const src_rep_t srcInfinity = (src_rep_t)srcInfExp << srcSigBits;\n    const src_rep_t srcSignMask = SRC_REP_C(1) << (srcSigBits + srcExpBits);\n    const src_rep_t srcAbsMask = srcSignMask - 1;\n    const src_rep_t roundMask = (SRC_REP_C(1) << (srcSigBits - dstSigBits)) - 1;\n    const src_rep_t halfway = SRC_REP_C(1) << (srcSigBits - dstSigBits - 1);\n    const src_rep_t srcQNaN = SRC_REP_C(1) << (srcSigBits - 1);\n    const src_rep_t srcNaNCode = srcQNaN - 1;\n\n    const int dstBits = sizeof(dst_t)*CHAR_BIT;\n    const int dstExpBits = dstBits - dstSigBits - 1;\n    const int dstInfExp = (1 << dstExpBits) - 1;\n    const int dstExpBias = dstInfExp >> 1;\n\n    const int underflowExponent = srcExpBias + 1 - dstExpBias;\n    const int overflowExponent = srcExpBias + dstInfExp - dstExpBias;\n    const src_rep_t underflow = (src_rep_t)underflowExponent << srcSigBits;\n    const src_rep_t overflow = (src_rep_t)overflowExponent << srcSigBits;\n\n    const dst_rep_t dstQNaN = DST_REP_C(1) << (dstSigBits - 1);\n    const dst_rep_t dstNaNCode = dstQNaN - 1;\n\n    // Break a into a sign and representation of the absolute value\n    const src_rep_t aRep = srcToRep(a);\n    const src_rep_t aAbs = aRep & srcAbsMask;\n    const src_rep_t sign = aRep & srcSignMask;\n    dst_rep_t absResult;\n\n    if (aAbs - underflow < aAbs - overflow) {\n        // The exponent of a is within the range of normal numbers in the\n        // destination format.  We can convert by simply right-shifting with\n        // rounding and adjusting the exponent.\n        absResult = aAbs >> (srcSigBits - dstSigBits);\n        absResult -= (dst_rep_t)(srcExpBias - dstExpBias) << dstSigBits;\n\n        const src_rep_t roundBits = aAbs & roundMask;\n        // Round to nearest\n        if (roundBits > halfway)\n            absResult++;\n        // Ties to even\n        else if (roundBits == halfway)\n            absResult += absResult & 1;\n    }\n    else if (aAbs > srcInfinity) {\n        // a is NaN.\n        // Conjure the result by beginning with infinity, setting the qNaN\n        // bit and inserting the (truncated) trailing NaN field.\n        absResult = (dst_rep_t)dstInfExp << dstSigBits;\n        absResult |= dstQNaN;\n        absResult |= ((aAbs & srcNaNCode) >> (srcSigBits - dstSigBits)) & dstNaNCode;\n    }\n    else if (aAbs >= overflow) {\n        // a overflows to infinity.\n        absResult = (dst_rep_t)dstInfExp << dstSigBits;\n    }\n    else {\n        // a underflows on conversion to the destination type or is an exact\n        // zero.  The result may be a denormal or zero.  Extract the exponent\n        // to get the shift amount for the denormalization.\n        const int aExp = aAbs >> srcSigBits;\n        const int shift = srcExpBias - dstExpBias - aExp + 1;\n\n        const src_rep_t significand = (aRep & srcSignificandMask) | srcMinNormal;\n\n        // Right shift by the denormalization amount with sticky.\n        if (shift > srcSigBits) {\n            absResult = 0;\n        } else {\n            const bool sticky = significand << (srcBits - shift);\n            src_rep_t denormalizedSignificand = significand >> shift | sticky;\n            absResult = denormalizedSignificand >> (srcSigBits - dstSigBits);\n            const src_rep_t roundBits = denormalizedSignificand & roundMask;\n            // Round to nearest\n            if (roundBits > halfway)\n                absResult++;\n            // Ties to even\n            else if (roundBits == halfway)\n                absResult += absResult & 1;\n        }\n    }\n\n    // Apply the signbit to (dst_t)abs(a).\n    const dst_rep_t result = absResult | sign >> (srcBits - dstBits);\n    return dstFromRep(result);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/gcc_personality_v0.c",
    "content": "/* ===-- gcc_personality_v0.c - Implement __gcc_personality_v0 -------------===\n *\n *      \t       The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n */\n\n#include \"int_lib.h\"\n\n#include <unwind.h>\n\n/*\n * Pointer encodings documented at:\n *   http://refspecs.freestandards.org/LSB_1.3.0/gLSB/gLSB/ehframehdr.html\n */\n\n#define DW_EH_PE_omit      0xff  /* no data follows */\n\n#define DW_EH_PE_absptr    0x00\n#define DW_EH_PE_uleb128   0x01\n#define DW_EH_PE_udata2    0x02\n#define DW_EH_PE_udata4    0x03\n#define DW_EH_PE_udata8    0x04\n#define DW_EH_PE_sleb128   0x09\n#define DW_EH_PE_sdata2    0x0A\n#define DW_EH_PE_sdata4    0x0B\n#define DW_EH_PE_sdata8    0x0C\n\n#define DW_EH_PE_pcrel     0x10\n#define DW_EH_PE_textrel   0x20\n#define DW_EH_PE_datarel   0x30\n#define DW_EH_PE_funcrel   0x40\n#define DW_EH_PE_aligned   0x50  \n#define DW_EH_PE_indirect  0x80 /* gcc extension */\n\n\n\n/* read a uleb128 encoded value and advance pointer */\nstatic uintptr_t readULEB128(const uint8_t** data)\n{\n    uintptr_t result = 0;\n    uintptr_t shift = 0;\n    unsigned char byte;\n    const uint8_t* p = *data;\n    do {\n        byte = *p++;\n        result |= (byte & 0x7f) << shift;\n        shift += 7;\n    } while (byte & 0x80);\n    *data = p;\n    return result;\n}\n\n/* read a pointer encoded value and advance pointer */\nstatic uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding)\n{\n    const uint8_t* p = *data;\n    uintptr_t result = 0;\n\n    if ( encoding == DW_EH_PE_omit ) \n        return 0;\n\n    /* first get value */\n    switch (encoding & 0x0F) {\n        case DW_EH_PE_absptr:\n            result = *((const uintptr_t*)p);\n            p += sizeof(uintptr_t);\n            break;\n        case DW_EH_PE_uleb128:\n            result = readULEB128(&p);\n            break;\n        case DW_EH_PE_udata2:\n            result = *((const uint16_t*)p);\n            p += sizeof(uint16_t);\n            break;\n        case DW_EH_PE_udata4:\n            result = *((const uint32_t*)p);\n            p += sizeof(uint32_t);\n            break;\n        case DW_EH_PE_udata8:\n            result = *((const uint64_t*)p);\n            p += sizeof(uint64_t);\n            break;\n        case DW_EH_PE_sdata2:\n            result = *((const int16_t*)p);\n            p += sizeof(int16_t);\n            break;\n        case DW_EH_PE_sdata4:\n            result = *((const int32_t*)p);\n            p += sizeof(int32_t);\n            break;\n        case DW_EH_PE_sdata8:\n            result = *((const int64_t*)p);\n            p += sizeof(int64_t);\n            break;\n        case DW_EH_PE_sleb128:\n        default:\n            /* not supported */\n            compilerrt_abort();\n            break;\n    }\n\n    /* then add relative offset */\n    switch ( encoding & 0x70 ) {\n        case DW_EH_PE_absptr:\n            /* do nothing */\n            break;\n        case DW_EH_PE_pcrel:\n            result += (uintptr_t)(*data);\n            break;\n        case DW_EH_PE_textrel:\n        case DW_EH_PE_datarel:\n        case DW_EH_PE_funcrel:\n        case DW_EH_PE_aligned:\n        default:\n            /* not supported */\n            compilerrt_abort();\n            break;\n    }\n\n    /* then apply indirection */\n    if (encoding & DW_EH_PE_indirect) {\n        result = *((const uintptr_t*)result);\n    }\n\n    *data = p;\n    return result;\n}\n\n\n/*\n * The C compiler makes references to __gcc_personality_v0 in\n * the dwarf unwind information for translation units that use\n * __attribute__((cleanup(xx))) on local variables.\n * This personality routine is called by the system unwinder\n * on each frame as the stack is unwound during a C++ exception\n * throw through a C function compiled with -fexceptions.\n */\n#if __USING_SJLJ_EXCEPTIONS__\n// the setjump-longjump based exceptions personality routine has a different name\nCOMPILER_RT_ABI _Unwind_Reason_Code\n__gcc_personality_sj0(int version, _Unwind_Action actions,\n         uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,\n         struct _Unwind_Context *context)\n#else\nCOMPILER_RT_ABI _Unwind_Reason_Code\n__gcc_personality_v0(int version, _Unwind_Action actions,\n         uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,\n         struct _Unwind_Context *context)\n#endif\n{\n    /* Since C does not have catch clauses, there is nothing to do during */\n    /* phase 1 (the search phase). */\n    if ( actions & _UA_SEARCH_PHASE ) \n        return _URC_CONTINUE_UNWIND;\n        \n    /* There is nothing to do if there is no LSDA for this frame. */\n    const uint8_t* lsda = (uint8_t*)_Unwind_GetLanguageSpecificData(context);\n    if ( lsda == (uint8_t*) 0 )\n        return _URC_CONTINUE_UNWIND;\n\n    uintptr_t pc = _Unwind_GetIP(context)-1;\n    uintptr_t funcStart = _Unwind_GetRegionStart(context);\n    uintptr_t pcOffset = pc - funcStart;\n\n    /* Parse LSDA header. */\n    uint8_t lpStartEncoding = *lsda++;\n    if (lpStartEncoding != DW_EH_PE_omit) {\n        readEncodedPointer(&lsda, lpStartEncoding); \n    }\n    uint8_t ttypeEncoding = *lsda++;\n    if (ttypeEncoding != DW_EH_PE_omit) {\n        readULEB128(&lsda);  \n    }\n    /* Walk call-site table looking for range that includes current PC. */\n    uint8_t         callSiteEncoding = *lsda++;\n    uint32_t        callSiteTableLength = readULEB128(&lsda);\n    const uint8_t*  callSiteTableStart = lsda;\n    const uint8_t*  callSiteTableEnd = callSiteTableStart + callSiteTableLength;\n    const uint8_t* p=callSiteTableStart;\n    while (p < callSiteTableEnd) {\n        uintptr_t start = readEncodedPointer(&p, callSiteEncoding);\n        uintptr_t length = readEncodedPointer(&p, callSiteEncoding);\n        uintptr_t landingPad = readEncodedPointer(&p, callSiteEncoding);\n        readULEB128(&p); /* action value not used for C code */\n        if ( landingPad == 0 )\n            continue; /* no landing pad for this entry */\n        if ( (start <= pcOffset) && (pcOffset < (start+length)) ) {\n            /* Found landing pad for the PC.\n             * Set Instruction Pointer to so we re-enter function \n             * at landing pad. The landing pad is created by the compiler\n             * to take two parameters in registers.\n             */\n            _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),\n                          (uintptr_t)exceptionObject);\n            _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 0);\n            _Unwind_SetIP(context, (funcStart + landingPad));\n            return _URC_INSTALL_CONTEXT;\n        }\n    }\n\n    /* No landing pad found, continue unwinding. */\n    return _URC_CONTINUE_UNWIND;\n}\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/Makefile.mk",
    "content": "#===- lib/builtins/i386/Makefile.mk ------------------------*- Makefile -*--===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\nModuleName := builtins\nSubDirs := \nOnlyArchs := i386\n\nAsmSources := $(foreach file,$(wildcard $(Dir)/*.S),$(notdir $(file)))\nSources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))\nObjNames := $(Sources:%.c=%.o) $(AsmSources:%.S=%.o)\nImplementation := Optimized\n\n# FIXME: use automatic dependencies?\nDependencies := $(wildcard lib/*.h $(Dir)/*.h)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/ashldi3.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// di_int __ashldi3(di_int input, int count);\n\n// This routine has some extra memory traffic, loading the 64-bit input via two\n// 32-bit loads, then immediately storing it back to the stack via a single 64-bit\n// store.  This is to avoid a write-small, read-large stall.\n// However, if callers of this routine can be safely assumed to store the argument\n// via a 64-bt store, this is unnecessary memory traffic, and should be avoided.\n// It can be turned off by defining the TRUST_CALLERS_USE_64_BIT_STORES macro.\n\n#ifdef __i386__\n#ifdef __SSE2__\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__ashldi3)\n\tmovd\t  12(%esp),\t\t%xmm2\t// Load count\n#ifndef TRUST_CALLERS_USE_64_BIT_STORES\n\tmovd\t   4(%esp),\t\t%xmm0\n\tmovd\t   8(%esp),\t\t%xmm1\n\tpunpckldq\t%xmm1,\t\t%xmm0\t// Load input\n#else\n\tmovq\t   4(%esp),\t\t%xmm0\t// Load input\n#endif\n\tpsllq\t\t%xmm2,\t\t%xmm0\t// shift input by count\n\tmovd\t\t%xmm0,\t\t%eax\n\tpsrlq\t\t$32,\t\t%xmm0\n\tmovd\t\t%xmm0,\t\t%edx\n\tret\nEND_COMPILERRT_FUNCTION(__ashldi3)\n\n#else // Use GPRs instead of SSE2 instructions, if they aren't available.\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__ashldi3)\n\tmovl\t  12(%esp),\t\t%ecx\t// Load count\n\tmovl\t   8(%esp),\t\t%edx\t// Load high\n\tmovl\t   4(%esp),\t\t%eax\t// Load low\n\n\ttestl\t\t$0x20,\t\t%ecx\t// If count >= 32\n\tjnz\t\t1f\t\t\t//    goto 1\n\tshldl\t\t%cl, %eax,\t%edx\t// left shift high by count\n\tshll\t\t%cl,\t\t%eax\t// left shift low by count\n\tret\n\n1:\tmovl\t\t%eax,\t\t%edx\t// Move low to high\n\txorl\t\t%eax,\t\t%eax\t// clear low\n\tshll\t\t%cl,\t\t%edx\t// shift high by count - 32\n\tret\nEND_COMPILERRT_FUNCTION(__ashldi3)\n\n#endif // __SSE2__\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/ashrdi3.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// di_int __ashrdi3(di_int input, int count);\n\n#ifdef __i386__\n#ifdef __SSE2__\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__ashrdi3)\n\tmovd\t  12(%esp),\t\t%xmm2\t// Load count\n\tmovl\t   8(%esp),\t\t%eax\n#ifndef TRUST_CALLERS_USE_64_BIT_STORES\n\tmovd\t   4(%esp),\t\t%xmm0\n\tmovd\t   8(%esp),\t\t%xmm1\n\tpunpckldq\t%xmm1,\t\t%xmm0\t// Load input\n#else\n\tmovq\t   4(%esp),\t\t%xmm0\t// Load input\n#endif\n\n\tpsrlq\t\t%xmm2,\t\t%xmm0\t// unsigned shift input by count\n\t\n\ttestl\t\t%eax,\t\t%eax\t// check the sign-bit of the input\n\tjns\t\t\t1f\t\t\t\t\t// early out for positive inputs\n\t\n\t// If the input is negative, we need to construct the shifted sign bit\n\t// to or into the result, as xmm does not have a signed right shift.\n\tpcmpeqb\t\t%xmm1,\t\t%xmm1\t// -1ULL\n\tpsrlq\t\t$58,\t\t%xmm1\t// 0x3f\n\tpandn\t\t%xmm1,\t\t%xmm2\t// 63 - count\n\tpcmpeqb\t\t%xmm1,\t\t%xmm1\t// -1ULL\n\tpsubq\t\t%xmm1,\t\t%xmm2\t// 64 - count\n\tpsllq\t\t%xmm2,\t\t%xmm1\t// -1 << (64 - count) = leading sign bits\n\tpor\t\t\t%xmm1,\t\t%xmm0\n\t\n\t// Move the result back to the general purpose registers and return\n1:\tmovd\t\t%xmm0,\t\t%eax\n\tpsrlq\t\t$32,\t\t%xmm0\n\tmovd\t\t%xmm0,\t\t%edx\n\tret\nEND_COMPILERRT_FUNCTION(__ashrdi3)\n\n#else // Use GPRs instead of SSE2 instructions, if they aren't available.\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__ashrdi3)\n\tmovl\t  12(%esp),\t\t%ecx\t// Load count\n\tmovl\t   8(%esp),\t\t%edx\t// Load high\n\tmovl\t   4(%esp),\t\t%eax\t// Load low\n\t\n\ttestl\t\t$0x20,\t\t%ecx\t// If count >= 32\n\tjnz\t\t\t1f\t\t\t\t\t//    goto 1\n\n\tshrdl\t\t%cl, %edx,\t%eax\t// right shift low by count\n\tsarl\t\t%cl,\t\t%edx\t// right shift high by count\n\tret\n\t\n1:\tmovl\t\t%edx,\t\t%eax\t// Move high to low\n\tsarl\t\t$31,\t\t%edx\t// clear high\n\tsarl\t\t%cl,\t\t%eax\t// shift low by count - 32\n\tret\nEND_COMPILERRT_FUNCTION(__ashrdi3)\n\n#endif // __SSE2__\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/chkstk.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// _chkstk routine\n// This routine is windows specific\n// http://msdn.microsoft.com/en-us/library/ms648426.aspx\n\n#ifdef __i386__\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__chkstk_ms)\n        push   %ecx\n        push   %eax\n        cmp    $0x1000,%eax\n        lea    12(%esp),%ecx\n        jb     1f\n2:\n        sub    $0x1000,%ecx\n        test   %ecx,(%ecx)\n        sub    $0x1000,%eax\n        cmp    $0x1000,%eax\n        ja     2b\n1:\n        sub    %eax,%ecx\n        test   %ecx,(%ecx)\n        pop    %eax\n        pop    %ecx\n        ret\nEND_COMPILERRT_FUNCTION(__chkstk_ms)\n\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/chkstk2.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n#ifdef __i386__\n\n// _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments,\n// then decrement %esp by %eax.  Preserves all registers except %esp and flags.\n// This routine is windows specific\n// http://msdn.microsoft.com/en-us/library/ms648426.aspx\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(_alloca) // _chkstk and _alloca are the same function\nDEFINE_COMPILERRT_FUNCTION(__chkstk)\n        push   %ecx\n        cmp    $0x1000,%eax\n        lea    8(%esp),%ecx     // esp before calling this routine -> ecx\n        jb     1f\n2:\n        sub    $0x1000,%ecx\n        test   %ecx,(%ecx)\n        sub    $0x1000,%eax\n        cmp    $0x1000,%eax\n        ja     2b\n1:\n        sub    %eax,%ecx\n        test   %ecx,(%ecx)\n\n        lea    4(%esp),%eax     // load pointer to the return address into eax\n        mov    %ecx,%esp        // install the new top of stack pointer into esp\n        mov    -4(%eax),%ecx    // restore ecx\n        push   (%eax)           // push return address onto the stack\n        sub    %esp,%eax        // restore the original value in eax\n        ret\nEND_COMPILERRT_FUNCTION(__chkstk)\nEND_COMPILERRT_FUNCTION(_alloca)\n\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/divdi3.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// di_int __divdi3(di_int a, di_int b);\n\n// result = a / b.\n// both inputs and the output are 64-bit signed integers.\n// This will do whatever the underlying hardware is set to do on division by zero.\n// No other exceptions are generated, as the divide cannot overflow.\n//\n// This is targeted at 32-bit x86 *only*, as this can be done directly in hardware\n// on x86_64.  The performance goal is ~40 cycles per divide, which is faster than\n// currently possible via simulation of integer divides on the x87 unit.\n//\n// Stephen Canon, December 2008\n\n#ifdef __i386__\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__divdi3)\n\n/* This is currently implemented by wrapping the unsigned divide up in an absolute\n   value, then restoring the correct sign at the end of the computation.  This could\n   certainly be improved upon. */\n\n\tpushl\t\t%esi\n\tmovl\t 20(%esp),\t\t\t%edx\t// high word of b\n\tmovl\t 16(%esp),\t\t\t%eax\t// low word of b\n\tmovl\t\t%edx,\t\t\t%ecx\n\tsarl\t\t$31,\t\t\t%ecx\t// (b < 0) ? -1 : 0\n\txorl\t\t%ecx,\t\t\t%eax\n\txorl\t\t%ecx,\t\t\t%edx\t// EDX:EAX = (b < 0) ? not(b) : b\n\tsubl\t\t%ecx,\t\t\t%eax\n\tsbbl\t\t%ecx,\t\t\t%edx\t// EDX:EAX = abs(b)\n\tmovl\t\t%edx,\t\t 20(%esp)\n\tmovl\t\t%eax,\t\t 16(%esp)\t// store abs(b) back to stack\n\tmovl\t\t%ecx,\t\t\t%esi\t// set aside sign of b\n\t\n\tmovl\t 12(%esp),\t\t\t%edx\t// high word of b\n\tmovl\t  8(%esp),\t\t\t%eax\t// low word of b\n\tmovl\t\t%edx,\t\t\t%ecx\n\tsarl\t\t$31,\t\t\t%ecx\t// (a < 0) ? -1 : 0\n\txorl\t\t%ecx,\t\t\t%eax\n\txorl\t\t%ecx,\t\t\t%edx\t// EDX:EAX = (a < 0) ? not(a) : a\n\tsubl\t\t%ecx,\t\t\t%eax\n\tsbbl\t\t%ecx,\t\t\t%edx\t// EDX:EAX = abs(a)\n\tmovl\t\t%edx,\t\t 12(%esp)\n\tmovl\t\t%eax,\t\t  8(%esp)\t// store abs(a) back to stack\n\txorl\t\t%ecx,\t\t\t%esi\t// sign of result = (sign of a) ^ (sign of b)\n\n\tpushl\t\t%ebx\n\tmovl\t 24(%esp),\t\t\t%ebx\t// Find the index i of the leading bit in b.\n\tbsrl\t\t%ebx,\t\t\t%ecx\t// If the high word of b is zero, jump to\n\tjz\t\t\t9f\t\t\t\t\t\t// the code to handle that special case [9].\n\t\n\t/* High word of b is known to be non-zero on this branch */\n\t\n\tmovl\t 20(%esp),\t\t\t%eax\t// Construct bhi, containing bits [1+i:32+i] of b\n\t\n\tshrl\t\t%cl,\t\t\t%eax\t// Practically, this means that bhi is given by:\n\tshrl\t\t%eax\t\t\t\t\t//\n\tnotl\t\t%ecx\t\t\t\t\t//\t\tbhi = (high word of b) << (31 - i) |\n\tshll\t\t%cl,\t\t\t%ebx\t//\t\t\t  (low word of b) >> (1 + i)\n\torl\t\t\t%eax,\t\t\t%ebx\t//\n\tmovl\t 16(%esp),\t\t\t%edx\t// Load the high and low words of a, and jump\n\tmovl\t 12(%esp),\t\t\t%eax\t// to [1] if the high word is larger than bhi\n\tcmpl\t\t%ebx,\t\t\t%edx\t// to avoid overflowing the upcoming divide.\n\tjae\t\t\t1f\t\t\t\t\t\t\n\t\t\n\t/* High word of a is greater than or equal to (b >> (1 + i)) on this branch */\n\t\n\tdivl\t\t%ebx\t\t\t\t\t// eax <-- qs, edx <-- r such that ahi:alo = bs*qs + r\n\n\tpushl\t\t%edi\n\tnotl\t\t%ecx\n\tshrl\t\t%eax\n\tshrl\t\t%cl,\t\t\t%eax\t// q = qs >> (1 + i)\n\tmovl\t\t%eax,\t\t\t%edi\n\tmull\t 24(%esp)\t\t\t\t\t// q*blo\n\tmovl\t 16(%esp),\t\t\t%ebx\n\tmovl\t 20(%esp),\t\t\t%ecx\t// ECX:EBX = a\n\tsubl\t\t%eax,\t\t\t%ebx\n\tsbbl\t\t%edx,\t\t\t%ecx\t// ECX:EBX = a - q*blo\n\tmovl\t 28(%esp),\t\t\t%eax\n\timull\t\t%edi,\t\t\t%eax\t// q*bhi\n\tsubl\t\t%eax,\t\t\t%ecx\t// ECX:EBX = a - q*b\n\tsbbl\t\t$0,\t\t\t\t%edi\t// decrement q if remainder is negative\n\txorl\t\t%edx,\t\t\t%edx\n\tmovl\t\t%edi,\t\t\t%eax\n\t\n\taddl\t\t%esi,\t\t\t%eax\t// Restore correct sign to result\n\tadcl\t\t%esi,\t\t\t%edx\n\txorl\t\t%esi,\t\t\t%eax\n\txorl\t\t%esi,\t\t\t%edx\n\tpopl\t\t%edi\t\t\t\t\t// Restore callee-save registers\n\tpopl\t\t%ebx\n\tpopl\t\t%esi\n\tretl\t\t\t\t\t\t\t\t// Return\n\n\n1:\t/* High word of a is greater than or equal to (b >> (1 + i)) on this branch */\n\t \n\tsubl\t\t%ebx,\t\t\t%edx\t// subtract bhi from ahi so that divide will not\n\tdivl\t\t%ebx\t\t\t\t\t// overflow, and find q and r such that\n\t\t\t\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t\t\t\t//\t\tahi:alo = (1:q)*bhi + r\n\t\t\t\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t\t\t\t// Note that q is a number in (31-i).(1+i)\n\t\t\t\t\t\t\t\t\t\t// fix point.\n\n\tpushl\t\t%edi\n\tnotl\t\t%ecx\n\tshrl\t\t%eax\n\torl\t\t\t$0x80000000,\t%eax\n\tshrl\t\t%cl,\t\t\t%eax\t// q = (1:qs) >> (1 + i)\n\tmovl\t\t%eax,\t\t\t%edi\n\tmull\t 24(%esp)\t\t\t\t\t// q*blo\n\tmovl\t 16(%esp),\t\t\t%ebx\n\tmovl\t 20(%esp),\t\t\t%ecx\t// ECX:EBX = a\n\tsubl\t\t%eax,\t\t\t%ebx\n\tsbbl\t\t%edx,\t\t\t%ecx\t// ECX:EBX = a - q*blo\n\tmovl\t 28(%esp),\t\t\t%eax\n\timull\t\t%edi,\t\t\t%eax\t// q*bhi\n\tsubl\t\t%eax,\t\t\t%ecx\t// ECX:EBX = a - q*b\n\tsbbl\t\t$0,\t\t\t\t%edi\t// decrement q if remainder is negative\n\txorl\t\t%edx,\t\t\t%edx\n\tmovl\t\t%edi,\t\t\t%eax\n\t\n\taddl\t\t%esi,\t\t\t%eax\t// Restore correct sign to result\n\tadcl\t\t%esi,\t\t\t%edx\n\txorl\t\t%esi,\t\t\t%eax\n\txorl\t\t%esi,\t\t\t%edx\n\tpopl\t\t%edi\t\t\t\t\t// Restore callee-save registers\n\tpopl\t\t%ebx\n\tpopl\t\t%esi\n\tretl\t\t\t\t\t\t\t\t// Return\n\n\t\n9:\t/* High word of b is zero on this branch */\n\n\tmovl\t 16(%esp),\t\t\t%eax\t// Find qhi and rhi such that\n\tmovl\t 20(%esp),\t\t\t%ecx\t//\n\txorl\t\t%edx,\t\t\t%edx\t//\t\tahi = qhi*b + rhi\twith\t0 ≤ rhi < b\n\tdivl\t\t%ecx\t\t\t\t\t//\n\tmovl\t\t%eax,\t\t\t%ebx\t//\n\tmovl\t 12(%esp),\t\t\t%eax\t// Find qlo such that\n\tdivl\t\t%ecx\t\t\t\t\t//\n\tmovl\t\t%ebx,\t\t\t%edx\t//\t\trhi:alo = qlo*b + rlo  with 0 ≤ rlo < b\n\t\n\taddl\t\t%esi,\t\t\t%eax\t// Restore correct sign to result\n\tadcl\t\t%esi,\t\t\t%edx\n\txorl\t\t%esi,\t\t\t%eax\n\txorl\t\t%esi,\t\t\t%edx\n\tpopl\t\t%ebx\t\t\t\t\t// Restore callee-save registers\n\tpopl\t\t%esi\n\tretl\t\t\t\t\t\t\t\t// Return\nEND_COMPILERRT_FUNCTION(__divdi3)\n\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/floatdidf.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// double __floatundidf(du_int a);\n\n#ifdef __i386__\n\nCONST_SECTION\n\n\t.balign 16\ntwop52:\n\t.quad 0x4330000000000000\n\n\t.balign 16\ntwop32:\n\t.quad 0x41f0000000000000\n\n#define REL_ADDR(_a)\t(_a)-0b(%eax)\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__floatdidf)\n\tcvtsi2sd\t8(%esp),\t\t\t%xmm1\n\tmovss\t\t4(%esp),\t\t\t%xmm0 // low 32 bits of a\n\tcalll\t\t0f\n0:\tpopl\t\t%eax\n\tmulsd\t\tREL_ADDR(twop32),\t%xmm1 // a_hi as a double (without rounding)\n\tmovsd\t\tREL_ADDR(twop52),\t%xmm2 // 0x1.0p52\n\tsubsd\t\t%xmm2,\t\t\t\t%xmm1 // a_hi - 0x1p52 (no rounding occurs)\n\torpd\t\t%xmm2,\t\t\t\t%xmm0 // 0x1p52 + a_lo (no rounding occurs)\n\taddsd\t\t%xmm1,\t\t\t\t%xmm0 // a_hi + a_lo   (round happens here)\n\tmovsd\t\t%xmm0,\t\t\t   4(%esp)\n\tfldl\t   4(%esp)\n\tret\nEND_COMPILERRT_FUNCTION(__floatdidf)\n\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/floatdisf.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// float __floatdisf(di_int a);\n\n// This routine has some extra memory traffic, loading the 64-bit input via two\n// 32-bit loads, then immediately storing it back to the stack via a single 64-bit\n// store.  This is to avoid a write-small, read-large stall.\n// However, if callers of this routine can be safely assumed to store the argument\n// via a 64-bt store, this is unnecessary memory traffic, and should be avoided.\n// It can be turned off by defining the TRUST_CALLERS_USE_64_BIT_STORES macro.\n\n#ifdef __i386__\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__floatdisf)\n#ifndef TRUST_CALLERS_USE_64_BIT_STORES\n\tmovd\t\t4(%esp),\t%xmm0\n\tmovd\t\t8(%esp),\t%xmm1\n\tpunpckldq\t%xmm1,\t\t%xmm0\n\tmovq\t\t%xmm0,\t\t4(%esp)\n#endif\n\tfildll\t\t4(%esp)\n\tfstps\t\t4(%esp)\n\tflds\t\t4(%esp)\n\tret\nEND_COMPILERRT_FUNCTION(__floatdisf)\n\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/floatdixf.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// float __floatdixf(di_int a);\n\n#ifdef __i386__\n\n// This routine has some extra memory traffic, loading the 64-bit input via two\n// 32-bit loads, then immediately storing it back to the stack via a single 64-bit\n// store.  This is to avoid a write-small, read-large stall.\n// However, if callers of this routine can be safely assumed to store the argument\n// via a 64-bt store, this is unnecessary memory traffic, and should be avoided.\n// It can be turned off by defining the TRUST_CALLERS_USE_64_BIT_STORES macro.\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__floatdixf)\n#ifndef TRUST_CALLERS_USE_64_BIT_STORES\n\tmovd\t\t4(%esp),\t%xmm0\n\tmovd\t\t8(%esp),\t%xmm1\n\tpunpckldq\t%xmm1,\t\t%xmm0\n\tmovq\t\t%xmm0,\t\t4(%esp)\n#endif\n\tfildll\t\t4(%esp)\n\tret\nEND_COMPILERRT_FUNCTION(__floatdixf)\n\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/floatundidf.S",
    "content": "//===-- floatundidf.S - Implement __floatundidf for i386 ------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements __floatundidf for the compiler_rt library.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n// double __floatundidf(du_int a);\n\n#ifdef __i386__\n\nCONST_SECTION\n\n\t.balign 16\ntwop52:\n\t.quad 0x4330000000000000\n\n\t.balign 16\ntwop84_plus_twop52:\n\t.quad 0x4530000000100000\n\n\t.balign 16\ntwop84:\n\t.quad 0x4530000000000000\n\n#define REL_ADDR(_a)\t(_a)-0b(%eax)\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__floatundidf)\n\tmovss\t8(%esp),\t\t\t\t\t\t%xmm1 // high 32 bits of a\n\tmovss\t4(%esp),\t\t\t\t\t\t%xmm0 // low 32 bits of a\n\tcalll\t0f\n0:\tpopl\t%eax\n\torpd\tREL_ADDR(twop84),\t\t\t\t%xmm1 // 0x1p84 + a_hi (no rounding occurs)\n\tsubsd\tREL_ADDR(twop84_plus_twop52),\t%xmm1 // a_hi - 0x1p52 (no rounding occurs)\n\torpd\tREL_ADDR(twop52),\t\t\t\t%xmm0 // 0x1p52 + a_lo (no rounding occurs)\n\taddsd\t%xmm1,\t\t\t\t\t\t\t%xmm0 // a_hi + a_lo   (round happens here)\n\tmovsd\t%xmm0,\t\t\t\t\t\t   4(%esp)\n\tfldl   4(%esp)\n\tret\nEND_COMPILERRT_FUNCTION(__floatundidf)\n\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/floatundisf.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// float __floatundisf(du_int a);\n\n// Note that there is a hardware instruction, fildll, that does most of what\n// this function needs to do.  However, because of our ia32 ABI, it will take\n// a write-small read-large stall, so the software implementation here is\n// actually several cycles faster.\n\n// This is a branch-free implementation.  A branchy implementation might be\n// faster for the common case if you know something a priori about the input\n// distribution.\n\n/* branch-free x87 implementation - one cycle slower than without x87.\n\n#ifdef __i386__\n\nCONST_SECTION\n.balign 3\n\n\t\t.quad\t0x43f0000000000000\ntwop64:\t.quad\t0x0000000000000000\n\n#define\t\t\tTWOp64\t\t\ttwop64-0b(%ecx,%eax,8)\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__floatundisf)\n\tmovl\t\t8(%esp),\t\t%eax\n\tmovd\t\t8(%esp),\t\t%xmm1\n\tmovd\t\t4(%esp),\t\t%xmm0\n\tpunpckldq\t%xmm1,\t\t\t%xmm0\n\tcalll\t\t0f\n0:\tpopl\t\t%ecx\n\tsarl\t\t$31,\t\t\t%eax\n\tmovq\t\t%xmm0,\t\t\t4(%esp)\n\tfildll\t\t4(%esp)\n\tfaddl\t\tTWOp64\n\tfstps\t\t4(%esp)\n\tflds\t\t4(%esp)\n\tret\nEND_COMPILERRT_FUNCTION(__floatundisf)\n\n#endif // __i386__\n\n*/\n\n/* branch-free, x87-free implementation - faster at the expense of code size */\n\n#ifdef __i386__\n\nCONST_SECTION\n\n\t.balign 16\ntwop52:\n\t.quad 0x4330000000000000\n\t.quad 0x0000000000000fff\n\n\t.balign 16\nsticky:\n\t.quad 0x0000000000000000\n\t.long 0x00000012\n\n\t.balign 16\ntwelve:\n\t.long 0x00000000\n\n#define\t\t\tTWOp52\t\t\ttwop52-0b(%ecx)\n#define\t\t\tSTICKY\t\t\tsticky-0b(%ecx,%eax,8)\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__floatundisf)\n\tmovl\t\t8(%esp),\t\t%eax\n\tmovd\t\t8(%esp),\t\t%xmm1\n\tmovd\t\t4(%esp),\t\t%xmm0\n\tpunpckldq\t%xmm1,\t\t\t%xmm0\n\t\n\tcalll\t\t0f\n0:\tpopl\t\t%ecx\n\tshrl\t\t%eax\t\t\t\t\t// high 31 bits of input as sint32\n\taddl\t\t$0x7ff80000,\t%eax\n\tsarl\t\t$31,\t\t\t%eax\t// (big input) ? -1 : 0\n\tmovsd\t\tSTICKY,\t\t\t%xmm1\t// (big input) ? 0xfff : 0\n\tmovl\t\t$12,\t\t\t%edx\n\tandl\t\t%eax,\t\t\t%edx\t// (big input) ? 12 : 0\n\tmovd\t\t%edx,\t\t\t%xmm3\n\tandpd\t\t%xmm0,\t\t\t%xmm1\t// (big input) ? input & 0xfff : 0\n\tmovsd\t\tTWOp52,\t\t\t%xmm2\t// 0x1.0p52\n\tpsrlq\t\t%xmm3,\t\t\t%xmm0\t// (big input) ? input >> 12 : input\n\torpd\t\t%xmm2,\t\t\t%xmm1\t// 0x1.0p52 + ((big input) ? input & 0xfff : input)\n\torpd\t\t%xmm1,\t\t\t%xmm0\t// 0x1.0p52 + ((big input) ? (input >> 12 | input & 0xfff) : input)\n\tsubsd\t\t%xmm2,\t\t\t%xmm0\t// (double)((big input) ? (input >> 12 | input & 0xfff) : input)\n\tcvtsd2ss\t%xmm0,\t\t\t%xmm0\t// (float)((big input) ? (input >> 12 | input & 0xfff) : input)\n\tpslld\t\t$23,\t\t\t%xmm3\n\tpaddd\t\t%xmm3,\t\t\t%xmm0\t// (float)input\n\tmovd\t\t%xmm0,\t\t\t4(%esp)\n\tflds\t\t4(%esp)\n\tret\nEND_COMPILERRT_FUNCTION(__floatundisf)\n\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/floatundixf.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// long double __floatundixf(du_int a);16\n\n#ifdef __i386__\n\nCONST_SECTION\n\n\t.balign 16\ntwop52:\n\t.quad 0x4330000000000000\n\n\t.balign 16\ntwop84_plus_twop52_neg:\n\t.quad 0xc530000000100000\n\n\t.balign 16\ntwop84:\n\t.quad 0x4530000000000000\n\n#define REL_ADDR(_a)\t(_a)-0b(%eax)\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__floatundixf)\n\tcalll\t0f\n0:\tpopl\t%eax\n\tmovss\t8(%esp),\t\t\t%xmm0\t// hi 32 bits of input\n\tmovss\t4(%esp),\t\t\t%xmm1\t// lo 32 bits of input\n\torpd\tREL_ADDR(twop84),\t%xmm0\t// 2^84 + hi (as a double)\n\torpd\tREL_ADDR(twop52),\t%xmm1\t// 2^52 + lo (as a double)\n\taddsd\tREL_ADDR(twop84_plus_twop52_neg),\t%xmm0\t// hi - 2^52 (no rounding occurs)\n\tmovsd\t%xmm1,\t\t\t\t4(%esp)\n\tfldl\t4(%esp)\n\tmovsd\t%xmm0,\t\t\t\t4(%esp)\n\tfaddl\t4(%esp)\n\tret\nEND_COMPILERRT_FUNCTION(__floatundixf)\n\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/lshrdi3.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// di_int __lshrdi3(di_int input, int count);\n\n// This routine has some extra memory traffic, loading the 64-bit input via two\n// 32-bit loads, then immediately storing it back to the stack via a single 64-bit\n// store.  This is to avoid a write-small, read-large stall.\n// However, if callers of this routine can be safely assumed to store the argument\n// via a 64-bt store, this is unnecessary memory traffic, and should be avoided.\n// It can be turned off by defining the TRUST_CALLERS_USE_64_BIT_STORES macro.\n\n#ifdef __i386__\n#ifdef __SSE2__\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__lshrdi3)\n\tmovd\t  12(%esp),\t\t%xmm2\t// Load count\n#ifndef TRUST_CALLERS_USE_64_BIT_STORES\n\tmovd\t   4(%esp),\t\t%xmm0\n\tmovd\t   8(%esp),\t\t%xmm1\n\tpunpckldq\t%xmm1,\t\t%xmm0\t// Load input\n#else\n\tmovq\t   4(%esp),\t\t%xmm0\t// Load input\n#endif\n\tpsrlq\t\t%xmm2,\t\t%xmm0\t// shift input by count\n\tmovd\t\t%xmm0,\t\t%eax\n\tpsrlq\t\t$32,\t\t%xmm0\n\tmovd\t\t%xmm0,\t\t%edx\n\tret\nEND_COMPILERRT_FUNCTION(__lshrdi3)\n\n#else // Use GPRs instead of SSE2 instructions, if they aren't available.\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__lshrdi3)\n\tmovl\t  12(%esp),\t\t%ecx\t// Load count\n\tmovl\t   8(%esp),\t\t%edx\t// Load high\n\tmovl\t   4(%esp),\t\t%eax\t// Load low\n\t\n\ttestl\t\t$0x20,\t\t%ecx\t// If count >= 32\n\tjnz\t\t\t1f\t\t\t\t\t//    goto 1\n\n\tshrdl\t\t%cl, %edx,\t%eax\t// right shift low by count\n\tshrl\t\t%cl,\t\t%edx\t// right shift high by count\n\tret\n\t\n1:\tmovl\t\t%edx,\t\t%eax\t// Move high to low\n\txorl\t\t%edx,\t\t%edx\t// clear high\n\tshrl\t\t%cl,\t\t%eax\t// shift low by count - 32\n\tret\nEND_COMPILERRT_FUNCTION(__lshrdi3)\n\n#endif // __SSE2__\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/moddi3.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// di_int __moddi3(di_int a, di_int b);\n\n// result = remainder of a / b.\n// both inputs and the output are 64-bit signed integers.\n// This will do whatever the underlying hardware is set to do on division by zero.\n// No other exceptions are generated, as the divide cannot overflow.\n//\n// This is targeted at 32-bit x86 *only*, as this can be done directly in hardware\n// on x86_64.  The performance goal is ~40 cycles per divide, which is faster than\n// currently possible via simulation of integer divides on the x87 unit.\n//\n\n// Stephen Canon, December 2008\n\n#ifdef __i386__\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__moddi3)\n\n/* This is currently implemented by wrapping the unsigned modulus up in an absolute\n   value.  This could certainly be improved upon. */\n\n\tpushl\t\t%esi\n\tmovl\t 20(%esp),\t\t\t%edx\t// high word of b\n\tmovl\t 16(%esp),\t\t\t%eax\t// low word of b\n\tmovl\t\t%edx,\t\t\t%ecx\n\tsarl\t\t$31,\t\t\t%ecx\t// (b < 0) ? -1 : 0\n\txorl\t\t%ecx,\t\t\t%eax\n\txorl\t\t%ecx,\t\t\t%edx\t// EDX:EAX = (b < 0) ? not(b) : b\n\tsubl\t\t%ecx,\t\t\t%eax\n\tsbbl\t\t%ecx,\t\t\t%edx\t// EDX:EAX = abs(b)\n\tmovl\t\t%edx,\t\t 20(%esp)\n\tmovl\t\t%eax,\t\t 16(%esp)\t// store abs(b) back to stack\n\t\n\tmovl\t 12(%esp),\t\t\t%edx\t// high word of b\n\tmovl\t  8(%esp),\t\t\t%eax\t// low word of b\n\tmovl\t\t%edx,\t\t\t%ecx\n\tsarl\t\t$31,\t\t\t%ecx\t// (a < 0) ? -1 : 0\n\txorl\t\t%ecx,\t\t\t%eax\n\txorl\t\t%ecx,\t\t\t%edx\t// EDX:EAX = (a < 0) ? not(a) : a\n\tsubl\t\t%ecx,\t\t\t%eax\n\tsbbl\t\t%ecx,\t\t\t%edx\t// EDX:EAX = abs(a)\n\tmovl\t\t%edx,\t\t 12(%esp)\n\tmovl\t\t%eax,\t\t  8(%esp)\t// store abs(a) back to stack\n\tmovl\t\t%ecx,\t\t\t%esi\t// set aside sign of a\n\n\tpushl\t\t%ebx\n\tmovl\t 24(%esp),\t\t\t%ebx\t// Find the index i of the leading bit in b.\n\tbsrl\t\t%ebx,\t\t\t%ecx\t// If the high word of b is zero, jump to\n\tjz\t\t\t9f\t\t\t\t\t\t// the code to handle that special case [9].\n\t\n\t/* High word of b is known to be non-zero on this branch */\n\t\n\tmovl\t 20(%esp),\t\t\t%eax\t// Construct bhi, containing bits [1+i:32+i] of b\n\t\n\tshrl\t\t%cl,\t\t\t%eax\t// Practically, this means that bhi is given by:\n\tshrl\t\t%eax\t\t\t\t\t//\n\tnotl\t\t%ecx\t\t\t\t\t//\t\tbhi = (high word of b) << (31 - i) |\n\tshll\t\t%cl,\t\t\t%ebx\t//\t\t\t  (low word of b) >> (1 + i)\n\torl\t\t\t%eax,\t\t\t%ebx\t//\n\tmovl\t 16(%esp),\t\t\t%edx\t// Load the high and low words of a, and jump\n\tmovl\t 12(%esp),\t\t\t%eax\t// to [2] if the high word is larger than bhi\n\tcmpl\t\t%ebx,\t\t\t%edx\t// to avoid overflowing the upcoming divide.\n\tjae\t\t\t2f\t\t\t\t\t\t\n\t\t\n\t/* High word of a is greater than or equal to (b >> (1 + i)) on this branch */\n\t\n\tdivl\t\t%ebx\t\t\t\t\t// eax <-- qs, edx <-- r such that ahi:alo = bs*qs + r\n\n\tpushl\t\t%edi\n\tnotl\t\t%ecx\n\tshrl\t\t%eax\n\tshrl\t\t%cl,\t\t\t%eax\t// q = qs >> (1 + i)\n\tmovl\t\t%eax,\t\t\t%edi\n\tmull\t 24(%esp)\t\t\t\t\t// q*blo\n\tmovl\t 16(%esp),\t\t\t%ebx\n\tmovl\t 20(%esp),\t\t\t%ecx\t// ECX:EBX = a\n\tsubl\t\t%eax,\t\t\t%ebx\n\tsbbl\t\t%edx,\t\t\t%ecx\t// ECX:EBX = a - q*blo\n\tmovl\t 28(%esp),\t\t\t%eax\n\timull\t\t%edi,\t\t\t%eax\t// q*bhi\n\tsubl\t\t%eax,\t\t\t%ecx\t// ECX:EBX = a - q*b\n\t\n\tjnc\t\t\t1f\t\t\t\t\t\t// if positive, this is the result.\n\taddl\t 24(%esp),\t\t\t%ebx\t// otherwise\n\tadcl\t 28(%esp),\t\t\t%ecx\t// ECX:EBX = a - (q-1)*b = result\n1:\tmovl\t\t%ebx,\t\t\t%eax\n\tmovl\t\t%ecx,\t\t\t%edx\n\t\n\taddl\t\t%esi,\t\t\t%eax\t// Restore correct sign to result\n\tadcl\t\t%esi,\t\t\t%edx\n\txorl\t\t%esi,\t\t\t%eax\n\txorl\t\t%esi,\t\t\t%edx\n\tpopl\t\t%edi\t\t\t\t\t// Restore callee-save registers\n\tpopl\t\t%ebx\n\tpopl\t\t%esi\n\tretl\t\t\t\t\t\t\t\t// Return\n\n2:\t/* High word of a is greater than or equal to (b >> (1 + i)) on this branch */\n\t \n\tsubl\t\t%ebx,\t\t\t%edx\t// subtract bhi from ahi so that divide will not\n\tdivl\t\t%ebx\t\t\t\t\t// overflow, and find q and r such that\n\t\t\t\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t\t\t\t//\t\tahi:alo = (1:q)*bhi + r\n\t\t\t\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t\t\t\t// Note that q is a number in (31-i).(1+i)\n\t\t\t\t\t\t\t\t\t\t// fix point.\n\n\tpushl\t\t%edi\n\tnotl\t\t%ecx\n\tshrl\t\t%eax\n\torl\t\t\t$0x80000000,\t%eax\n\tshrl\t\t%cl,\t\t\t%eax\t// q = (1:qs) >> (1 + i)\n\tmovl\t\t%eax,\t\t\t%edi\n\tmull\t 24(%esp)\t\t\t\t\t// q*blo\n\tmovl\t 16(%esp),\t\t\t%ebx\n\tmovl\t 20(%esp),\t\t\t%ecx\t// ECX:EBX = a\n\tsubl\t\t%eax,\t\t\t%ebx\n\tsbbl\t\t%edx,\t\t\t%ecx\t// ECX:EBX = a - q*blo\n\tmovl\t 28(%esp),\t\t\t%eax\n\timull\t\t%edi,\t\t\t%eax\t// q*bhi\n\tsubl\t\t%eax,\t\t\t%ecx\t// ECX:EBX = a - q*b\n\n\tjnc\t\t\t3f\t\t\t\t\t\t// if positive, this is the result.\n\taddl\t 24(%esp),\t\t\t%ebx\t// otherwise\n\tadcl\t 28(%esp),\t\t\t%ecx\t// ECX:EBX = a - (q-1)*b = result\n3:\tmovl\t\t%ebx,\t\t\t%eax\n\tmovl\t\t%ecx,\t\t\t%edx\n\t\n\taddl\t\t%esi,\t\t\t%eax\t// Restore correct sign to result\n\tadcl\t\t%esi,\t\t\t%edx\n\txorl\t\t%esi,\t\t\t%eax\n\txorl\t\t%esi,\t\t\t%edx\n\tpopl\t\t%edi\t\t\t\t\t// Restore callee-save registers\n\tpopl\t\t%ebx\n\tpopl\t\t%esi\n\tretl\t\t\t\t\t\t\t\t// Return\n\t\n9:\t/* High word of b is zero on this branch */\n\n\tmovl\t 16(%esp),\t\t\t%eax\t// Find qhi and rhi such that\n\tmovl\t 20(%esp),\t\t\t%ecx\t//\n\txorl\t\t%edx,\t\t\t%edx\t//\t\tahi = qhi*b + rhi\twith\t0 ≤ rhi < b\n\tdivl\t\t%ecx\t\t\t\t\t//\n\tmovl\t\t%eax,\t\t\t%ebx\t//\n\tmovl\t 12(%esp),\t\t\t%eax\t// Find rlo such that\n\tdivl\t\t%ecx\t\t\t\t\t//\n\tmovl\t\t%edx,\t\t\t%eax\t//\t\trhi:alo = qlo*b + rlo  with 0 ≤ rlo < b\n\tpopl\t\t%ebx\t\t\t\t\t//\n\txorl\t\t%edx,\t\t\t%edx\t// and return 0:rlo\n\n\taddl\t\t%esi,\t\t\t%eax\t// Restore correct sign to result\n\tadcl\t\t%esi,\t\t\t%edx\n\txorl\t\t%esi,\t\t\t%eax\n\txorl\t\t%esi,\t\t\t%edx\n\tpopl\t\t%esi\n\tretl\t\t\t\t\t\t\t\t// Return\nEND_COMPILERRT_FUNCTION(__moddi3)\n\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/muldi3.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// di_int __muldi3(di_int a, di_int b);\n\n#ifdef __i386__\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__muldi3)\n\tpushl\t%ebx\n\tmovl  16(%esp),\t\t%eax\t// b.lo\n\tmovl  12(%esp),\t\t%ecx\t// a.hi\n\timull\t%eax,\t\t%ecx\t// b.lo * a.hi\n\t\n\tmovl   8(%esp),\t\t%edx\t// a.lo\n\tmovl  20(%esp),\t\t%ebx\t// b.hi\n\timull\t%edx,\t\t%ebx\t// a.lo * b.hi\n\t\n\tmull\t%edx\t\t\t\t// EDX:EAX = a.lo * b.lo\n\taddl\t%ecx,\t\t%ebx\t// EBX = (a.lo*b.hi + a.hi*b.lo)\n\taddl\t%ebx,\t\t%edx\n\t\n\tpopl\t%ebx\n\tretl\nEND_COMPILERRT_FUNCTION(__muldi3)\n\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/udivdi3.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// du_int __udivdi3(du_int a, du_int b);\n\n// result = a / b.\n// both inputs and the output are 64-bit unsigned integers.\n// This will do whatever the underlying hardware is set to do on division by zero.\n// No other exceptions are generated, as the divide cannot overflow.\n//\n// This is targeted at 32-bit x86 *only*, as this can be done directly in hardware\n// on x86_64.  The performance goal is ~40 cycles per divide, which is faster than\n// currently possible via simulation of integer divides on the x87 unit.\n//\n// Stephen Canon, December 2008\n\n#ifdef __i386__\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__udivdi3)\n\n\tpushl\t\t%ebx\n\tmovl\t 20(%esp),\t\t\t%ebx\t// Find the index i of the leading bit in b.\n\tbsrl\t\t%ebx,\t\t\t%ecx\t// If the high word of b is zero, jump to\n\tjz\t\t\t9f\t\t\t\t\t\t// the code to handle that special case [9].\n\t\n\t/* High word of b is known to be non-zero on this branch */\n\t\n\tmovl\t 16(%esp),\t\t\t%eax\t// Construct bhi, containing bits [1+i:32+i] of b\n\t\n\tshrl\t\t%cl,\t\t\t%eax\t// Practically, this means that bhi is given by:\n\tshrl\t\t%eax\t\t\t\t\t//\n\tnotl\t\t%ecx\t\t\t\t\t//\t\tbhi = (high word of b) << (31 - i) |\n\tshll\t\t%cl,\t\t\t%ebx\t//\t\t\t  (low word of b) >> (1 + i)\n\torl\t\t\t%eax,\t\t\t%ebx\t//\n\tmovl\t 12(%esp),\t\t\t%edx\t// Load the high and low words of a, and jump\n\tmovl\t  8(%esp),\t\t\t%eax\t// to [1] if the high word is larger than bhi\n\tcmpl\t\t%ebx,\t\t\t%edx\t// to avoid overflowing the upcoming divide.\n\tjae\t\t\t1f\t\t\t\t\t\t\n\t\t\n\t/* High word of a is greater than or equal to (b >> (1 + i)) on this branch */\n\t\n\tdivl\t\t%ebx\t\t\t\t\t// eax <-- qs, edx <-- r such that ahi:alo = bs*qs + r\n\n\tpushl\t\t%edi\n\tnotl\t\t%ecx\n\tshrl\t\t%eax\n\tshrl\t\t%cl,\t\t\t%eax\t// q = qs >> (1 + i)\n\tmovl\t\t%eax,\t\t\t%edi\n\tmull\t 20(%esp)\t\t\t\t\t// q*blo\n\tmovl\t 12(%esp),\t\t\t%ebx\n\tmovl\t 16(%esp),\t\t\t%ecx\t// ECX:EBX = a\n\tsubl\t\t%eax,\t\t\t%ebx\n\tsbbl\t\t%edx,\t\t\t%ecx\t// ECX:EBX = a - q*blo\n\tmovl\t 24(%esp),\t\t\t%eax\n\timull\t\t%edi,\t\t\t%eax\t// q*bhi\n\tsubl\t\t%eax,\t\t\t%ecx\t// ECX:EBX = a - q*b\n\tsbbl\t\t$0,\t\t\t\t%edi\t// decrement q if remainder is negative\n\txorl\t\t%edx,\t\t\t%edx\n\tmovl\t\t%edi,\t\t\t%eax\n\tpopl\t\t%edi\n\tpopl\t\t%ebx\n\tretl\n\n\n1:\t/* High word of a is greater than or equal to (b >> (1 + i)) on this branch */\n\t \n\tsubl\t\t%ebx,\t\t\t%edx\t// subtract bhi from ahi so that divide will not\n\tdivl\t\t%ebx\t\t\t\t\t// overflow, and find q and r such that\n\t\t\t\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t\t\t\t//\t\tahi:alo = (1:q)*bhi + r\n\t\t\t\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t\t\t\t// Note that q is a number in (31-i).(1+i)\n\t\t\t\t\t\t\t\t\t\t// fix point.\n\n\tpushl\t\t%edi\n\tnotl\t\t%ecx\n\tshrl\t\t%eax\n\torl\t\t\t$0x80000000,\t%eax\n\tshrl\t\t%cl,\t\t\t%eax\t// q = (1:qs) >> (1 + i)\n\tmovl\t\t%eax,\t\t\t%edi\n\tmull\t 20(%esp)\t\t\t\t\t// q*blo\n\tmovl\t 12(%esp),\t\t\t%ebx\n\tmovl\t 16(%esp),\t\t\t%ecx\t// ECX:EBX = a\n\tsubl\t\t%eax,\t\t\t%ebx\n\tsbbl\t\t%edx,\t\t\t%ecx\t// ECX:EBX = a - q*blo\n\tmovl\t 24(%esp),\t\t\t%eax\n\timull\t\t%edi,\t\t\t%eax\t// q*bhi\n\tsubl\t\t%eax,\t\t\t%ecx\t// ECX:EBX = a - q*b\n\tsbbl\t\t$0,\t\t\t\t%edi\t// decrement q if remainder is negative\n\txorl\t\t%edx,\t\t\t%edx\n\tmovl\t\t%edi,\t\t\t%eax\n\tpopl\t\t%edi\n\tpopl\t\t%ebx\n\tretl\n\n\t\n9:\t/* High word of b is zero on this branch */\n\n\tmovl\t 12(%esp),\t\t\t%eax\t// Find qhi and rhi such that\n\tmovl\t 16(%esp),\t\t\t%ecx\t//\n\txorl\t\t%edx,\t\t\t%edx\t//\t\tahi = qhi*b + rhi\twith\t0 ≤ rhi < b\n\tdivl\t\t%ecx\t\t\t\t\t//\n\tmovl\t\t%eax,\t\t\t%ebx\t//\n\tmovl\t  8(%esp),\t\t\t%eax\t// Find qlo such that\n\tdivl\t\t%ecx\t\t\t\t\t//\n\tmovl\t\t%ebx,\t\t\t%edx\t//\t\trhi:alo = qlo*b + rlo  with 0 ≤ rlo < b\n\tpopl\t\t%ebx\t\t\t\t\t//\n\tretl\t\t\t\t\t\t\t\t// and return qhi:qlo\nEND_COMPILERRT_FUNCTION(__udivdi3)\n\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/i386/umoddi3.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// du_int __umoddi3(du_int a, du_int b);\n\n// result = remainder of a / b.\n// both inputs and the output are 64-bit unsigned integers.\n// This will do whatever the underlying hardware is set to do on division by zero.\n// No other exceptions are generated, as the divide cannot overflow.\n//\n// This is targeted at 32-bit x86 *only*, as this can be done directly in hardware\n// on x86_64.  The performance goal is ~40 cycles per divide, which is faster than\n// currently possible via simulation of integer divides on the x87 unit.\n//\n\n// Stephen Canon, December 2008\n\n#ifdef __i386__\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__umoddi3)\n\n\tpushl\t\t%ebx\n\tmovl\t 20(%esp),\t\t\t%ebx\t// Find the index i of the leading bit in b.\n\tbsrl\t\t%ebx,\t\t\t%ecx\t// If the high word of b is zero, jump to\n\tjz\t\t\t9f\t\t\t\t\t\t// the code to handle that special case [9].\n\t\n\t/* High word of b is known to be non-zero on this branch */\n\t\n\tmovl\t 16(%esp),\t\t\t%eax\t// Construct bhi, containing bits [1+i:32+i] of b\n\t\n\tshrl\t\t%cl,\t\t\t%eax\t// Practically, this means that bhi is given by:\n\tshrl\t\t%eax\t\t\t\t\t//\n\tnotl\t\t%ecx\t\t\t\t\t//\t\tbhi = (high word of b) << (31 - i) |\n\tshll\t\t%cl,\t\t\t%ebx\t//\t\t\t  (low word of b) >> (1 + i)\n\torl\t\t\t%eax,\t\t\t%ebx\t//\n\tmovl\t 12(%esp),\t\t\t%edx\t// Load the high and low words of a, and jump\n\tmovl\t  8(%esp),\t\t\t%eax\t// to [2] if the high word is larger than bhi\n\tcmpl\t\t%ebx,\t\t\t%edx\t// to avoid overflowing the upcoming divide.\n\tjae\t\t\t2f\t\t\t\t\t\t\n\t\t\n\t/* High word of a is greater than or equal to (b >> (1 + i)) on this branch */\n\t\n\tdivl\t\t%ebx\t\t\t\t\t// eax <-- qs, edx <-- r such that ahi:alo = bs*qs + r\n\n\tpushl\t\t%edi\n\tnotl\t\t%ecx\n\tshrl\t\t%eax\n\tshrl\t\t%cl,\t\t\t%eax\t// q = qs >> (1 + i)\n\tmovl\t\t%eax,\t\t\t%edi\n\tmull\t 20(%esp)\t\t\t\t\t// q*blo\n\tmovl\t 12(%esp),\t\t\t%ebx\n\tmovl\t 16(%esp),\t\t\t%ecx\t// ECX:EBX = a\n\tsubl\t\t%eax,\t\t\t%ebx\n\tsbbl\t\t%edx,\t\t\t%ecx\t// ECX:EBX = a - q*blo\n\tmovl\t 24(%esp),\t\t\t%eax\n\timull\t\t%edi,\t\t\t%eax\t// q*bhi\n\tsubl\t\t%eax,\t\t\t%ecx\t// ECX:EBX = a - q*b\n\t\n\tjnc\t\t\t1f\t\t\t\t\t\t// if positive, this is the result.\n\taddl\t 20(%esp),\t\t\t%ebx\t// otherwise\n\tadcl\t 24(%esp),\t\t\t%ecx\t// ECX:EBX = a - (q-1)*b = result\n1:\tmovl\t\t%ebx,\t\t\t%eax\n\tmovl\t\t%ecx,\t\t\t%edx\n\t\n\tpopl\t\t%edi\n\tpopl\t\t%ebx\n\tretl\n\n\n2:\t/* High word of a is greater than or equal to (b >> (1 + i)) on this branch */\n\t \n\tsubl\t\t%ebx,\t\t\t%edx\t// subtract bhi from ahi so that divide will not\n\tdivl\t\t%ebx\t\t\t\t\t// overflow, and find q and r such that\n\t\t\t\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t\t\t\t//\t\tahi:alo = (1:q)*bhi + r\n\t\t\t\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t\t\t\t// Note that q is a number in (31-i).(1+i)\n\t\t\t\t\t\t\t\t\t\t// fix point.\n\n\tpushl\t\t%edi\n\tnotl\t\t%ecx\n\tshrl\t\t%eax\n\torl\t\t\t$0x80000000,\t%eax\n\tshrl\t\t%cl,\t\t\t%eax\t// q = (1:qs) >> (1 + i)\n\tmovl\t\t%eax,\t\t\t%edi\n\tmull\t 20(%esp)\t\t\t\t\t// q*blo\n\tmovl\t 12(%esp),\t\t\t%ebx\n\tmovl\t 16(%esp),\t\t\t%ecx\t// ECX:EBX = a\n\tsubl\t\t%eax,\t\t\t%ebx\n\tsbbl\t\t%edx,\t\t\t%ecx\t// ECX:EBX = a - q*blo\n\tmovl\t 24(%esp),\t\t\t%eax\n\timull\t\t%edi,\t\t\t%eax\t// q*bhi\n\tsubl\t\t%eax,\t\t\t%ecx\t// ECX:EBX = a - q*b\n\n\tjnc\t\t\t3f\t\t\t\t\t\t// if positive, this is the result.\n\taddl\t 20(%esp),\t\t\t%ebx\t// otherwise\n\tadcl\t 24(%esp),\t\t\t%ecx\t// ECX:EBX = a - (q-1)*b = result\n3:\tmovl\t\t%ebx,\t\t\t%eax\n\tmovl\t\t%ecx,\t\t\t%edx\n\t\n\tpopl\t\t%edi\n\tpopl\t\t%ebx\n\tretl\n\n\n\t\n9:\t/* High word of b is zero on this branch */\n\n\tmovl\t 12(%esp),\t\t\t%eax\t// Find qhi and rhi such that\n\tmovl\t 16(%esp),\t\t\t%ecx\t//\n\txorl\t\t%edx,\t\t\t%edx\t//\t\tahi = qhi*b + rhi\twith\t0 ≤ rhi < b\n\tdivl\t\t%ecx\t\t\t\t\t//\n\tmovl\t\t%eax,\t\t\t%ebx\t//\n\tmovl\t  8(%esp),\t\t\t%eax\t// Find rlo such that\n\tdivl\t\t%ecx\t\t\t\t\t//\n\tmovl\t\t%edx,\t\t\t%eax\t//\t\trhi:alo = qlo*b + rlo  with 0 ≤ rlo < b\n\tpopl\t\t%ebx\t\t\t\t\t//\n\txorl\t\t%edx,\t\t\t%edx\t// and return 0:rlo\n\tretl\t\t\t\t\t\t\t\t// \nEND_COMPILERRT_FUNCTION(__umoddi3)\n\n#endif // __i386__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/int_endianness.h",
    "content": "/* ===-- int_endianness.h - configuration header for compiler-rt ------------===\n *\n *\t\t       The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file is a configuration header for compiler-rt.\n * This file is not part of the interface of this library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#ifndef INT_ENDIANNESS_H\n#define INT_ENDIANNESS_H\n\n#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \\\n    defined(__ORDER_LITTLE_ENDIAN__)\n\n/* Clang and GCC provide built-in endianness definitions. */\n#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__\n#define _YUGA_LITTLE_ENDIAN 0\n#define _YUGA_BIG_ENDIAN    1\n#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n#define _YUGA_LITTLE_ENDIAN 1\n#define _YUGA_BIG_ENDIAN    0\n#endif /* __BYTE_ORDER__ */\n\n#else /* Compilers other than Clang or GCC. */\n\n#if defined(__SVR4) && defined(__sun)\n#include <sys/byteorder.h>\n\n#if defined(_BIG_ENDIAN)\n#define _YUGA_LITTLE_ENDIAN 0\n#define _YUGA_BIG_ENDIAN    1\n#elif defined(_LITTLE_ENDIAN)\n#define _YUGA_LITTLE_ENDIAN 1\n#define _YUGA_BIG_ENDIAN    0\n#else /* !_LITTLE_ENDIAN */\n#error \"unknown endianness\"\n#endif /* !_LITTLE_ENDIAN */\n\n#endif /* Solaris and AuroraUX. */\n\n/* .. */\n\n#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) ||   \\\n    defined(__minix)\n#include <sys/endian.h>\n\n#if _BYTE_ORDER == _BIG_ENDIAN\n#define _YUGA_LITTLE_ENDIAN 0\n#define _YUGA_BIG_ENDIAN    1\n#elif _BYTE_ORDER == _LITTLE_ENDIAN\n#define _YUGA_LITTLE_ENDIAN 1\n#define _YUGA_BIG_ENDIAN    0\n#endif /* _BYTE_ORDER */\n\n#endif /* *BSD */\n\n#if defined(__OpenBSD__) || defined(__Bitrig__)\n#include <machine/endian.h>\n\n#if _BYTE_ORDER == _BIG_ENDIAN\n#define _YUGA_LITTLE_ENDIAN 0\n#define _YUGA_BIG_ENDIAN    1\n#elif _BYTE_ORDER == _LITTLE_ENDIAN\n#define _YUGA_LITTLE_ENDIAN 1\n#define _YUGA_BIG_ENDIAN    0\n#endif /* _BYTE_ORDER */\n\n#endif /* OpenBSD and Bitrig. */\n\n/* .. */\n\n/* Mac OSX has __BIG_ENDIAN__ or __LITTLE_ENDIAN__ automatically set by the\n * compiler (at least with GCC) */\n#if defined(__APPLE__) || defined(__ellcc__ )\n\n#ifdef __BIG_ENDIAN__\n#if __BIG_ENDIAN__\n#define _YUGA_LITTLE_ENDIAN 0\n#define _YUGA_BIG_ENDIAN    1\n#endif\n#endif /* __BIG_ENDIAN__ */\n\n#ifdef __LITTLE_ENDIAN__\n#if __LITTLE_ENDIAN__\n#define _YUGA_LITTLE_ENDIAN 1\n#define _YUGA_BIG_ENDIAN    0\n#endif\n#endif /* __LITTLE_ENDIAN__ */\n\n#endif /* Mac OSX */\n\n/* .. */\n\n#if defined(_WIN32)\n\n#define _YUGA_LITTLE_ENDIAN 1\n#define _YUGA_BIG_ENDIAN    0\n\n#endif /* Windows */\n\n#endif /* Clang or GCC. */\n\n/* . */\n\n#if !defined(_YUGA_LITTLE_ENDIAN) || !defined(_YUGA_BIG_ENDIAN)\n#error Unable to determine endian\n#endif /* Check we found an endianness correctly. */\n\n#endif /* INT_ENDIANNESS_H */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/int_lib.h",
    "content": "/* ===-- int_lib.h - configuration header for compiler-rt  -----------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file is a configuration header for compiler-rt.\n * This file is not part of the interface of this library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#ifndef INT_LIB_H\n#define INT_LIB_H\n\n/* Assumption: Signed integral is 2's complement. */\n/* Assumption: Right shift of signed negative is arithmetic shift. */\n/* Assumption: Endianness is little or big (not mixed). */\n\n#if defined(__ELF__)\n#define FNALIAS(alias_name, original_name) \\\n  void alias_name() __attribute__((alias(#original_name)))\n#else\n#define FNALIAS(alias, name) _Pragma(\"GCC error(\\\"alias unsupported on this file format\\\")\")\n#endif\n\n/* ABI macro definitions */\n\n#if __ARM_EABI__\n# define ARM_EABI_FNALIAS(aeabi_name, name)         \\\n  void __aeabi_##aeabi_name() __attribute__((alias(\"__\" #name)));\n# define COMPILER_RT_ABI __attribute__((pcs(\"aapcs\")))\n#else\n# define ARM_EABI_FNALIAS(aeabi_name, name)\n# if defined(__arm__) && defined(_WIN32) && (!defined(_MSC_VER) || defined(__clang__))\n#   define COMPILER_RT_ABI __attribute__((pcs(\"aapcs\")))\n# else\n#   define COMPILER_RT_ABI\n# endif\n#endif\n\n#ifdef _MSC_VER\n#define ALWAYS_INLINE __forceinline\n#define NOINLINE __declspec(noinline)\n#define NORETURN __declspec(noreturn)\n#define UNUSED\n#else\n#define ALWAYS_INLINE __attribute__((always_inline))\n#define NOINLINE __attribute__((noinline))\n#define NORETURN __attribute__((noreturn))\n#define UNUSED __attribute__((unused))\n#endif\n\n#if defined(__NetBSD__) && (defined(_KERNEL) || defined(_STANDALONE))\n/*\n * Kernel and boot environment can't use normal headers,\n * so use the equivalent system headers.\n */\n#  include <machine/limits.h>\n#  include <sys/stdint.h>\n#  include <sys/types.h>\n#else\n/* Include the standard compiler builtin headers we use functionality from. */\n#  include <limits.h>\n#  include <stdint.h>\n#  include <stdbool.h>\n#  include <float.h>\n#endif\n\n/* Include the commonly used internal type definitions. */\n#include \"int_types.h\"\n\n/* Include internal utility function declarations. */\n#include \"int_util.h\"\n\nCOMPILER_RT_ABI si_int __paritysi2(si_int a);\nCOMPILER_RT_ABI si_int __paritydi2(di_int a);\n\nCOMPILER_RT_ABI di_int __divdi3(di_int a, di_int b);\nCOMPILER_RT_ABI si_int __divsi3(si_int a, si_int b);\nCOMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d);\n\nCOMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int* rem);\nCOMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int* rem);\n#ifdef CRT_HAS_128BIT\nCOMPILER_RT_ABI si_int __clzti2(ti_int a);\nCOMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);\n#endif\n\n/* Definitions for builtins unavailable on MSVC */\n#if defined(_MSC_VER) && !defined(__clang__)\n#include <intrin.h>\n\nuint32_t __inline __builtin_ctz(uint32_t value) {\n  uint32_t trailing_zero = 0;\n  if (_BitScanForward(&trailing_zero, value))\n    return trailing_zero;\n  return 32;\n}\n\nuint32_t __inline __builtin_clz(uint32_t value) {\n  uint32_t leading_zero = 0;\n  if (_BitScanReverse(&leading_zero, value))\n    return 31 - leading_zero;\n  return 32;\n}\n\n#if defined(_M_ARM) || defined(_M_X64)\nuint32_t __inline __builtin_clzll(uint64_t value) {\n  uint32_t leading_zero = 0;\n  if (_BitScanReverse64(&leading_zero, value))\n    return 63 - leading_zero;\n  return 64;\n}\n#else\nuint32_t __inline __builtin_clzll(uint64_t value) {\n  if (value == 0)\n    return 64;\n  uint32_t msh = (uint32_t)(value >> 32);\n  uint32_t lsh = (uint32_t)(value & 0xFFFFFFFF);\n  if (msh != 0)\n    return __builtin_clz(msh);\n  return 32 + __builtin_clz(lsh);\n}\n#endif\n\n#define __builtin_clzl __builtin_clzll\n#endif // defined(_MSC_VER) && !defined(__clang__)\n\n#endif /* INT_LIB_H */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/int_math.h",
    "content": "/* ===-- int_math.h - internal math inlines ---------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===-----------------------------------------------------------------------===\n *\n * This file is not part of the interface of this library.\n *\n * This file defines substitutes for the libm functions used in some of the\n * compiler-rt implementations, defined in such a way that there is not a direct\n * dependency on libm or math.h. Instead, we use the compiler builtin versions\n * where available. This reduces our dependencies on the system SDK by foisting\n * the responsibility onto the compiler.\n *\n * ===-----------------------------------------------------------------------===\n */\n\n#ifndef INT_MATH_H\n#define INT_MATH_H\n\n#ifndef __has_builtin\n#  define  __has_builtin(x) 0\n#endif\n\n#if defined(_MSC_VER) && !defined(__clang__)\n#include <math.h>\n#include <stdlib.h>\n#include <ymath.h>\n#endif\n\n#if defined(_MSC_VER) && !defined(__clang__)\n#define CRT_INFINITY INFINITY\n#else\n#define CRT_INFINITY __builtin_huge_valf()\n#endif\n\n#if defined(_MSC_VER) && !defined(__clang__)\n#define crt_isfinite(x) _finite((x))\n#define crt_isinf(x) !_finite((x))\n#define crt_isnan(x) _isnan((x))\n#else\n/* Define crt_isfinite in terms of the builtin if available, otherwise provide\n * an alternate version in terms of our other functions. This supports some\n * versions of GCC which didn't have __builtin_isfinite.\n */\n#if __has_builtin(__builtin_isfinite)\n#  define crt_isfinite(x) __builtin_isfinite((x))\n#elif defined(__GNUC__)\n#  define crt_isfinite(x) \\\n  __extension__(({ \\\n      __typeof((x)) x_ = (x); \\\n      !crt_isinf(x_) && !crt_isnan(x_); \\\n    }))\n#else\n#  error \"Do not know how to check for infinity\"\n#endif /* __has_builtin(__builtin_isfinite) */\n#define crt_isinf(x) __builtin_isinf((x))\n#define crt_isnan(x) __builtin_isnan((x))\n#endif /* _MSC_VER */\n\n#if defined(_MSC_VER) && !defined(__clang__)\n#define crt_copysign(x, y) copysign((x), (y))\n#define crt_copysignf(x, y) copysignf((x), (y))\n#define crt_copysignl(x, y) copysignl((x), (y))\n#else\n#define crt_copysign(x, y) __builtin_copysign((x), (y))\n#define crt_copysignf(x, y) __builtin_copysignf((x), (y))\n#define crt_copysignl(x, y) __builtin_copysignl((x), (y))\n#endif\n\n#if defined(_MSC_VER) && !defined(__clang__)\n#define crt_fabs(x) fabs((x))\n#define crt_fabsf(x) fabsf((x))\n#define crt_fabsl(x) fabs((x))\n#else\n#define crt_fabs(x) __builtin_fabs((x))\n#define crt_fabsf(x) __builtin_fabsf((x))\n#define crt_fabsl(x) __builtin_fabsl((x))\n#endif\n\n#if defined(_MSC_VER) && !defined(__clang__)\n#define crt_fmax(x, y) __max((x), (y))\n#define crt_fmaxf(x, y) __max((x), (y))\n#define crt_fmaxl(x, y) __max((x), (y))\n#else\n#define crt_fmax(x, y) __builtin_fmax((x), (y))\n#define crt_fmaxf(x, y) __builtin_fmaxf((x), (y))\n#define crt_fmaxl(x, y) __builtin_fmaxl((x), (y))\n#endif\n\n#if defined(_MSC_VER) && !defined(__clang__)\n#define crt_logb(x) logb((x))\n#define crt_logbf(x) logbf((x))\n#define crt_logbl(x) logbl((x))\n#else\n#define crt_logb(x) __builtin_logb((x))\n#define crt_logbf(x) __builtin_logbf((x))\n#define crt_logbl(x) __builtin_logbl((x))\n#endif\n\n#if defined(_MSC_VER) && !defined(__clang__)\n#define crt_scalbn(x, y) scalbn((x), (y))\n#define crt_scalbnf(x, y) scalbnf((x), (y))\n#define crt_scalbnl(x, y) scalbnl((x), (y))\n#else\n#define crt_scalbn(x, y) __builtin_scalbn((x), (y))\n#define crt_scalbnf(x, y) __builtin_scalbnf((x), (y))\n#define crt_scalbnl(x, y) __builtin_scalbnl((x), (y))\n#endif\n\n#endif /* INT_MATH_H */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/int_types.h",
    "content": "/* ===-- int_lib.h - configuration header for compiler-rt  -----------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file is not part of the interface of this library.\n *\n * This file defines various standard types, most importantly a number of unions\n * used to access parts of larger types.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#ifndef INT_TYPES_H\n#define INT_TYPES_H\n\n#include \"int_endianness.h\"\n\n/* si_int is defined in Linux sysroot's asm-generic/siginfo.h */\n#ifdef si_int\n#undef si_int\n#endif\ntypedef      int si_int;\ntypedef unsigned su_int;\n\ntypedef          long long di_int;\ntypedef unsigned long long du_int;\n\ntypedef union\n{\n    di_int all;\n    struct\n    {\n#if _YUGA_LITTLE_ENDIAN\n        su_int low;\n        si_int high;\n#else\n        si_int high;\n        su_int low;\n#endif /* _YUGA_LITTLE_ENDIAN */\n    }s;\n} dwords;\n\ntypedef union\n{\n    du_int all;\n    struct\n    {\n#if _YUGA_LITTLE_ENDIAN\n        su_int low;\n        su_int high;\n#else\n        su_int high;\n        su_int low;\n#endif /* _YUGA_LITTLE_ENDIAN */\n    }s;\n} udwords;\n\n/* MIPS64 issue: PR 20098 */\n#if defined(__LP64__) && !(defined(__mips__) && defined(__clang__))\n#define CRT_HAS_128BIT\n#endif\n\n#ifdef CRT_HAS_128BIT\ntypedef int      ti_int __attribute__ ((mode (TI)));\ntypedef unsigned tu_int __attribute__ ((mode (TI)));\n\ntypedef union\n{\n    ti_int all;\n    struct\n    {\n#if _YUGA_LITTLE_ENDIAN\n        du_int low;\n        di_int high;\n#else\n        di_int high;\n        du_int low;\n#endif /* _YUGA_LITTLE_ENDIAN */\n    }s;\n} twords;\n\ntypedef union\n{\n    tu_int all;\n    struct\n    {\n#if _YUGA_LITTLE_ENDIAN\n        du_int low;\n        du_int high;\n#else\n        du_int high;\n        du_int low;\n#endif /* _YUGA_LITTLE_ENDIAN */\n    }s;\n} utwords;\n\nstatic __inline ti_int make_ti(di_int h, di_int l) {\n    twords r;\n    r.s.high = h;\n    r.s.low = l;\n    return r.all;\n}\n\nstatic __inline tu_int make_tu(du_int h, du_int l) {\n    utwords r;\n    r.s.high = h;\n    r.s.low = l;\n    return r.all;\n}\n\n#endif /* CRT_HAS_128BIT */\n\ntypedef union\n{\n    su_int u;\n    float f;\n} float_bits;\n\ntypedef union\n{\n    udwords u;\n    double  f;\n} double_bits;\n\ntypedef struct\n{\n#if _YUGA_LITTLE_ENDIAN\n    udwords low;\n    udwords high;\n#else\n    udwords high;\n    udwords low;\n#endif /* _YUGA_LITTLE_ENDIAN */\n} uqwords;\n\ntypedef union\n{\n    uqwords     u;\n    long double f;\n} long_double_bits;\n\n#if __STDC_VERSION__ >= 199901L\ntypedef float _Complex Fcomplex;\ntypedef double _Complex Dcomplex;\ntypedef long double _Complex Lcomplex;\n\n#define COMPLEX_REAL(x) __real__(x)\n#define COMPLEX_IMAGINARY(x) __imag__(x)\n#else\ntypedef struct { float real, imaginary; } Fcomplex;\n\ntypedef struct { double real, imaginary; } Dcomplex;\n\ntypedef struct { long double real, imaginary; } Lcomplex;\n\n#define COMPLEX_REAL(x) (x).real\n#define COMPLEX_IMAGINARY(x) (x).imaginary\n#endif\n#endif /* INT_TYPES_H */\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/int_util.c",
    "content": "/* ===-- int_util.c - Implement internal utilities --------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n#include \"int_util.h\"\n\n/* NOTE: The definitions in this file are declared weak because we clients to be\n * able to arbitrarily package individual functions into separate .a files. If\n * we did not declare these weak, some link situations might end up seeing\n * duplicate strong definitions of the same symbol.\n *\n * We can't use this solution for kernel use (which may not support weak), but\n * currently expect that when built for kernel use all the functionality is\n * packaged into a single library.\n */\n\n#ifdef KERNEL_USE\n\nNORETURN extern void panic(const char *, ...);\n#ifndef _WIN32\n__attribute__((visibility(\"hidden\")))\n#endif\nvoid compilerrt_abort_impl(const char *file, int line, const char *function) {\n  panic(\"%s:%d: abort in %s\", file, line, function);\n}\n\n#elif __APPLE__\n\n/* from libSystem.dylib */\nNORETURN extern void __assert_rtn(const char *func, const char *file, int line,\n                                  const char *message);\n\n#ifndef _WIN32\n__attribute__((weak))\n__attribute__((visibility(\"hidden\")))\n#endif\nvoid compilerrt_abort_impl(const char *file, int line, const char *function) {\n  __assert_rtn(function, file, line, \"libcompiler_rt abort\");\n}\n\n#else\n\n/* Get the system definition of abort() */\n#include <stdlib.h>\n\n#ifndef _WIN32\n__attribute__((weak))\n__attribute__((visibility(\"hidden\")))\n#endif\nvoid compilerrt_abort_impl(const char *file, int line, const char *function) {\n  abort();\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/int_util.h",
    "content": "/* ===-- int_util.h - internal utility functions ----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===-----------------------------------------------------------------------===\n *\n * This file is not part of the interface of this library.\n *\n * This file defines non-inline utilities which are available for use in the\n * library. The function definitions themselves are all contained in int_util.c\n * which will always be compiled into any compiler-rt library.\n *\n * ===-----------------------------------------------------------------------===\n */\n\n#ifndef INT_UTIL_H\n#define INT_UTIL_H\n\n/** \\brief Trigger a program abort (or panic for kernel code). */\n#define compilerrt_abort() compilerrt_abort_impl(__FILE__, __LINE__, __func__)\n\nNORETURN void compilerrt_abort_impl(const char *file, int line,\n                                    const char *function);\n\n#define COMPILE_TIME_ASSERT(expr) COMPILE_TIME_ASSERT1(expr, __COUNTER__)\n#define COMPILE_TIME_ASSERT1(expr, cnt) COMPILE_TIME_ASSERT2(expr, cnt)\n#define COMPILE_TIME_ASSERT2(expr, cnt)                                        \\\n  typedef char ct_assert_##cnt[(expr) ? 1 : -1] UNUSED\n\n#endif /* INT_UTIL_H */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/lshrdi3.c",
    "content": "/* ===-- lshrdi3.c - Implement __lshrdi3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __lshrdi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: logical a >> b */\n\n/* Precondition:  0 <= b < bits_in_dword */\n\nARM_EABI_FNALIAS(llsr, lshrdi3)\n\nCOMPILER_RT_ABI di_int\n__lshrdi3(di_int a, si_int b)\n{\n    const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT);\n    udwords input;\n    udwords result;\n    input.all = a;\n    if (b & bits_in_word)  /* bits_in_word <= b < bits_in_dword */\n    {\n        result.s.high = 0;\n        result.s.low = input.s.high >> (b - bits_in_word);\n    }\n    else  /* 0 <= b < bits_in_word */\n    {\n        if (b == 0)\n            return a;\n        result.s.high  = input.s.high >> b;\n        result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b);\n    }\n    return result.all;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/lshrti3.c",
    "content": "/* ===-- lshrti3.c - Implement __lshrti3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __lshrti3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: logical a >> b */\n\n/* Precondition:  0 <= b < bits_in_tword */\n\nCOMPILER_RT_ABI ti_int\n__lshrti3(ti_int a, si_int b)\n{\n    const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT);\n    utwords input;\n    utwords result;\n    input.all = a;\n    if (b & bits_in_dword)  /* bits_in_dword <= b < bits_in_tword */\n    {\n        result.s.high = 0;\n        result.s.low = input.s.high >> (b - bits_in_dword);\n    }\n    else  /* 0 <= b < bits_in_dword */\n    {\n        if (b == 0)\n            return a;\n        result.s.high  = input.s.high >> b;\n        result.s.low = (input.s.high << (bits_in_dword - b)) | (input.s.low >> b);\n    }\n    return result.all;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/macho_embedded/CMakeLists.txt",
    "content": "file(GLOB filter_files ${CMAKE_CURRENT_SOURCE_DIR}/*.txt)\nforeach(filter_file ${filter_files})\n  set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${filter_file})\nendforeach()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/macho_embedded/arm.txt",
    "content": "aeabi_cdcmpeq\naeabi_cdrcmple\naeabi_cfcmpeq\naeabi_cfrcmple\naeabi_dcmpeq\naeabi_dcmpge\naeabi_dcmpgt\naeabi_dcmple\naeabi_dcmplt\naeabi_drsub\naeabi_fcmpeq\naeabi_fcmpge\naeabi_fcmpgt\naeabi_fcmple\naeabi_fcmplt\naeabi_frsub\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/macho_embedded/common.txt",
    "content": "absvdi2\nabsvsi2\naddvdi3\naddvsi3\nashldi3\nashrdi3\nclzdi2\nclzsi2\ncmpdi2\nctzdi2\nctzsi2\ndivdc3\ndivdi3\ndivsc3\ndivmodsi4\nudivmodsi4\ndo_global_dtors\nffsdi2\nfixdfdi\nfixsfdi\nfixunsdfdi\nfixunsdfsi\nfixunssfdi\nfixunssfsi\nfloatdidf\nfloatdisf\nfloatundidf\nfloatundisf\ngcc_bcmp\nlshrdi3\nmoddi3\nmuldc3\nmuldi3\nmulsc3\nmulvdi3\nmulvsi3\nnegdi2\nnegvdi2\nnegvsi2\nparitydi2\nparitysi2\npopcountdi2\npopcountsi2\npowidf2\npowisf2\nsubvdi3\nsubvsi3\nucmpdi2\nudiv_w_sdiv\nudivdi3\nudivmoddi4\numoddi3\nadddf3\naddsf3\ncmpdf2\ncmpsf2\ndiv0\ndivdf3\ndivsf3\ndivsi3\nextendsfdf2\nextendhfsf2\nffssi2\nfixdfsi\nfixsfsi\nfloatsidf\nfloatsisf\nfloatunsidf\nfloatunsisf\ncomparedf2\ncomparesf2\nmodsi3\nmuldf3\nmulsf3\nnegdf2\nnegsf2\nsubdf3\nsubsf3\ntruncdfhf2\ntruncdfsf2\ntruncsfhf2\nudivsi3\numodsi3\nunorddf2\nunordsf2\natomic_flag_clear\natomic_flag_clear_explicit\natomic_flag_test_and_set\natomic_flag_test_and_set_explicit\natomic_signal_fence\natomic_thread_fence\nint_util\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/macho_embedded/i386.txt",
    "content": "i686.get_pc_thunk.eax\ni686.get_pc_thunk.ebp\ni686.get_pc_thunk.ebx\ni686.get_pc_thunk.ecx\ni686.get_pc_thunk.edi\ni686.get_pc_thunk.edx\ni686.get_pc_thunk.esi\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/macho_embedded/thumb2-64.txt",
    "content": "sync_fetch_and_add_8\nsync_fetch_and_sub_8\nsync_fetch_and_and_8\nsync_fetch_and_or_8\nsync_fetch_and_xor_8\nsync_fetch_and_nand_8\nsync_fetch_and_max_8\nsync_fetch_and_umax_8\nsync_fetch_and_min_8\nsync_fetch_and_umin_8\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/macho_embedded/thumb2.txt",
    "content": "switch16\nswitch32\nswitch8\nswitchu8\nsync_fetch_and_add_4\nsync_fetch_and_sub_4\nsync_fetch_and_and_4\nsync_fetch_and_or_4\nsync_fetch_and_xor_4\nsync_fetch_and_nand_4\nsync_fetch_and_max_4\nsync_fetch_and_umax_4\nsync_fetch_and_min_4\nsync_fetch_and_umin_4\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/moddi3.c",
    "content": "/*===-- moddi3.c - Implement __moddi3 -------------------------------------===\n *\n *                    The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __moddi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a % b */\n\nCOMPILER_RT_ABI di_int\n__moddi3(di_int a, di_int b)\n{\n    const int bits_in_dword_m1 = (int)(sizeof(di_int) * CHAR_BIT) - 1;\n    di_int s = b >> bits_in_dword_m1;  /* s = b < 0 ? -1 : 0 */\n    b = (b ^ s) - s;                   /* negate if s == -1 */\n    s = a >> bits_in_dword_m1;         /* s = a < 0 ? -1 : 0 */\n    a = (a ^ s) - s;                   /* negate if s == -1 */\n    du_int r;\n    __udivmoddi4(a, b, &r);\n    return ((di_int)r ^ s) - s;                /* negate if s == -1 */\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/modsi3.c",
    "content": "/* ===-- modsi3.c - Implement __modsi3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __modsi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a % b */\n\nCOMPILER_RT_ABI si_int\n__modsi3(si_int a, si_int b)\n{\n    return a - __divsi3(a, b) * b;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/modti3.c",
    "content": "/* ===-- modti3.c - Implement __modti3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __modti3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/*Returns: a % b */\n\nCOMPILER_RT_ABI ti_int\n__modti3(ti_int a, ti_int b)\n{\n    const int bits_in_tword_m1 = (int)(sizeof(ti_int) * CHAR_BIT) - 1;\n    ti_int s = b >> bits_in_tword_m1;  /* s = b < 0 ? -1 : 0 */\n    b = (b ^ s) - s;                   /* negate if s == -1 */\n    s = a >> bits_in_tword_m1;         /* s = a < 0 ? -1 : 0 */\n    a = (a ^ s) - s;                   /* negate if s == -1 */\n    tu_int r;\n    __udivmodti4(a, b, &r);\n    return ((ti_int)r ^ s) - s;                /* negate if s == -1 */\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/muldc3.c",
    "content": "/* ===-- muldc3.c - Implement __muldc3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __muldc3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n#include \"int_math.h\"\n\n/* Returns: the product of a + ib and c + id */\n\nCOMPILER_RT_ABI Dcomplex\n__muldc3(double __a, double __b, double __c, double __d)\n{\n    double __ac = __a * __c;\n    double __bd = __b * __d;\n    double __ad = __a * __d;\n    double __bc = __b * __c;\n    Dcomplex z;\n    COMPLEX_REAL(z) = __ac - __bd;\n    COMPLEX_IMAGINARY(z) = __ad + __bc;\n    if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))\n    {\n        int __recalc = 0;\n        if (crt_isinf(__a) || crt_isinf(__b))\n        {\n            __a = crt_copysign(crt_isinf(__a) ? 1 : 0, __a);\n            __b = crt_copysign(crt_isinf(__b) ? 1 : 0, __b);\n            if (crt_isnan(__c))\n                __c = crt_copysign(0, __c);\n            if (crt_isnan(__d))\n                __d = crt_copysign(0, __d);\n            __recalc = 1;\n        }\n        if (crt_isinf(__c) || crt_isinf(__d))\n        {\n            __c = crt_copysign(crt_isinf(__c) ? 1 : 0, __c);\n            __d = crt_copysign(crt_isinf(__d) ? 1 : 0, __d);\n            if (crt_isnan(__a))\n                __a = crt_copysign(0, __a);\n            if (crt_isnan(__b))\n                __b = crt_copysign(0, __b);\n            __recalc = 1;\n        }\n        if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) ||\n                          crt_isinf(__ad) || crt_isinf(__bc)))\n        {\n            if (crt_isnan(__a))\n                __a = crt_copysign(0, __a);\n            if (crt_isnan(__b))\n                __b = crt_copysign(0, __b);\n            if (crt_isnan(__c))\n                __c = crt_copysign(0, __c);\n            if (crt_isnan(__d))\n                __d = crt_copysign(0, __d);\n            __recalc = 1;\n        }\n        if (__recalc)\n        {\n            COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d);\n            COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c);\n        }\n    }\n    return z;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/muldf3.c",
    "content": "//===-- lib/muldf3.c - Double-precision multiplication ------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements double-precision soft-float multiplication\n// with the IEEE-754 default rounding (to nearest, ties to even).\n//\n//===----------------------------------------------------------------------===//\n\n#define DOUBLE_PRECISION\n#include \"fp_mul_impl.inc\"\n\nARM_EABI_FNALIAS(dmul, muldf3)\n\nCOMPILER_RT_ABI fp_t __muldf3(fp_t a, fp_t b) {\n    return __mulXf3__(a, b);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/muldi3.c",
    "content": "/* ===-- muldi3.c - Implement __muldi3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __muldi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a * b */\n\nstatic\ndi_int\n__muldsi3(su_int a, su_int b)\n{\n    dwords r;\n    const int bits_in_word_2 = (int)(sizeof(si_int) * CHAR_BIT) / 2;\n    const su_int lower_mask = (su_int)~0 >> bits_in_word_2;\n    r.s.low = (a & lower_mask) * (b & lower_mask);\n    su_int t = r.s.low >> bits_in_word_2;\n    r.s.low &= lower_mask;\n    t += (a >> bits_in_word_2) * (b & lower_mask);\n    r.s.low += (t & lower_mask) << bits_in_word_2;\n    r.s.high = t >> bits_in_word_2;\n    t = r.s.low >> bits_in_word_2;\n    r.s.low &= lower_mask;\n    t += (b >> bits_in_word_2) * (a & lower_mask);\n    r.s.low += (t & lower_mask) << bits_in_word_2;\n    r.s.high += t >> bits_in_word_2;\n    r.s.high += (a >> bits_in_word_2) * (b >> bits_in_word_2);\n    return r.all;\n}\n\n/* Returns: a * b */\n\nARM_EABI_FNALIAS(lmul, muldi3)\n\nCOMPILER_RT_ABI di_int\n__muldi3(di_int a, di_int b)\n{\n    dwords x;\n    x.all = a;\n    dwords y;\n    y.all = b;\n    dwords r;\n    r.all = __muldsi3(x.s.low, y.s.low);\n    r.s.high += x.s.high * y.s.low + x.s.low * y.s.high;\n    return r.all;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/mulodi4.c",
    "content": "/*===-- mulodi4.c - Implement __mulodi4 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __mulodi4 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a * b */\n\n/* Effects: sets *overflow to 1  if a * b overflows */\n\nCOMPILER_RT_ABI di_int\n__mulodi4(di_int a, di_int b, int* overflow)\n{\n    const int N = (int)(sizeof(di_int) * CHAR_BIT);\n    const di_int MIN = (di_int)1 << (N-1);\n    const di_int MAX = ~MIN;\n    *overflow = 0; \n    di_int result = a * b;\n    if (a == MIN)\n    {\n        if (b != 0 && b != 1)\n\t    *overflow = 1;\n\treturn result;\n    }\n    if (b == MIN)\n    {\n        if (a != 0 && a != 1)\n\t    *overflow = 1;\n        return result;\n    }\n    di_int sa = a >> (N - 1);\n    di_int abs_a = (a ^ sa) - sa;\n    di_int sb = b >> (N - 1);\n    di_int abs_b = (b ^ sb) - sb;\n    if (abs_a < 2 || abs_b < 2)\n        return result;\n    if (sa == sb)\n    {\n        if (abs_a > MAX / abs_b)\n            *overflow = 1;\n    }\n    else\n    {\n        if (abs_a > MIN / -abs_b)\n            *overflow = 1;\n    }\n    return result;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/mulosi4.c",
    "content": "/*===-- mulosi4.c - Implement __mulosi4 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __mulosi4 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a * b */\n\n/* Effects: sets *overflow to 1  if a * b overflows */\n\nCOMPILER_RT_ABI si_int\n__mulosi4(si_int a, si_int b, int* overflow)\n{\n    const int N = (int)(sizeof(si_int) * CHAR_BIT);\n    const si_int MIN = (si_int)1 << (N-1);\n    const si_int MAX = ~MIN;\n    *overflow = 0; \n    si_int result = a * b;\n    if (a == MIN)\n    {\n        if (b != 0 && b != 1)\n\t    *overflow = 1;\n\treturn result;\n    }\n    if (b == MIN)\n    {\n        if (a != 0 && a != 1)\n\t    *overflow = 1;\n        return result;\n    }\n    si_int sa = a >> (N - 1);\n    si_int abs_a = (a ^ sa) - sa;\n    si_int sb = b >> (N - 1);\n    si_int abs_b = (b ^ sb) - sb;\n    if (abs_a < 2 || abs_b < 2)\n        return result;\n    if (sa == sb)\n    {\n        if (abs_a > MAX / abs_b)\n            *overflow = 1;\n    }\n    else\n    {\n        if (abs_a > MIN / -abs_b)\n            *overflow = 1;\n    }\n    return result;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/muloti4.c",
    "content": "/*===-- muloti4.c - Implement __muloti4 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __muloti4 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: a * b */\n\n/* Effects: sets *overflow to 1  if a * b overflows */\n\nCOMPILER_RT_ABI ti_int\n__muloti4(ti_int a, ti_int b, int* overflow)\n{\n    const int N = (int)(sizeof(ti_int) * CHAR_BIT);\n    const ti_int MIN = (ti_int)1 << (N-1);\n    const ti_int MAX = ~MIN;\n    *overflow = 0;\n    ti_int result = a * b;\n    if (a == MIN)\n    {\n        if (b != 0 && b != 1)\n\t    *overflow = 1;\n\treturn result;\n    }\n    if (b == MIN)\n    {\n        if (a != 0 && a != 1)\n\t    *overflow = 1;\n        return result;\n    }\n    ti_int sa = a >> (N - 1);\n    ti_int abs_a = (a ^ sa) - sa;\n    ti_int sb = b >> (N - 1);\n    ti_int abs_b = (b ^ sb) - sb;\n    if (abs_a < 2 || abs_b < 2)\n        return result;\n    if (sa == sb)\n    {\n        if (abs_a > MAX / abs_b)\n            *overflow = 1;\n    }\n    else\n    {\n        if (abs_a > MIN / -abs_b)\n            *overflow = 1;\n    }\n    return result;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/mulsc3.c",
    "content": "/* ===-- mulsc3.c - Implement __mulsc3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __mulsc3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n#include \"int_math.h\"\n\n/* Returns: the product of a + ib and c + id */\n\nCOMPILER_RT_ABI Fcomplex\n__mulsc3(float __a, float __b, float __c, float __d)\n{\n    float __ac = __a * __c;\n    float __bd = __b * __d;\n    float __ad = __a * __d;\n    float __bc = __b * __c;\n    Fcomplex z;\n    COMPLEX_REAL(z) = __ac - __bd;\n    COMPLEX_IMAGINARY(z) = __ad + __bc;\n    if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))\n    {\n        int __recalc = 0;\n        if (crt_isinf(__a) || crt_isinf(__b))\n        {\n            __a = crt_copysignf(crt_isinf(__a) ? 1 : 0, __a);\n            __b = crt_copysignf(crt_isinf(__b) ? 1 : 0, __b);\n            if (crt_isnan(__c))\n                __c = crt_copysignf(0, __c);\n            if (crt_isnan(__d))\n                __d = crt_copysignf(0, __d);\n            __recalc = 1;\n        }\n        if (crt_isinf(__c) || crt_isinf(__d))\n        {\n            __c = crt_copysignf(crt_isinf(__c) ? 1 : 0, __c);\n            __d = crt_copysignf(crt_isinf(__d) ? 1 : 0, __d);\n            if (crt_isnan(__a))\n                __a = crt_copysignf(0, __a);\n            if (crt_isnan(__b))\n                __b = crt_copysignf(0, __b);\n            __recalc = 1;\n        }\n        if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) ||\n                          crt_isinf(__ad) || crt_isinf(__bc)))\n        {\n            if (crt_isnan(__a))\n                __a = crt_copysignf(0, __a);\n            if (crt_isnan(__b))\n                __b = crt_copysignf(0, __b);\n            if (crt_isnan(__c))\n                __c = crt_copysignf(0, __c);\n            if (crt_isnan(__d))\n                __d = crt_copysignf(0, __d);\n            __recalc = 1;\n        }\n        if (__recalc)\n        {\n            COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d);\n            COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c);\n        }\n    }\n    return z;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/mulsf3.c",
    "content": "//===-- lib/mulsf3.c - Single-precision multiplication ------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements single-precision soft-float multiplication\n// with the IEEE-754 default rounding (to nearest, ties to even).\n//\n//===----------------------------------------------------------------------===//\n\n#define SINGLE_PRECISION\n#include \"fp_mul_impl.inc\"\n\nARM_EABI_FNALIAS(fmul, mulsf3)\n\nCOMPILER_RT_ABI fp_t __mulsf3(fp_t a, fp_t b) {\n    return __mulXf3__(a, b);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/multc3.c",
    "content": "/* ===-- multc3.c - Implement __multc3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __multc3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n#include \"int_math.h\"\n\n/* Returns: the product of a + ib and c + id */\n\nCOMPILER_RT_ABI long double _Complex\n__multc3(long double a, long double b, long double c, long double d)\n{\n    long double ac = a * c;\n    long double bd = b * d;\n    long double ad = a * d;\n    long double bc = b * c;\n    long double _Complex z;\n    __real__ z = ac - bd;\n    __imag__ z = ad + bc;\n    if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) {\n        int recalc = 0;\n        if (crt_isinf(a) || crt_isinf(b)) {\n            a = crt_copysignl(crt_isinf(a) ? 1 : 0, a);\n            b = crt_copysignl(crt_isinf(b) ? 1 : 0, b);\n            if (crt_isnan(c))\n                c = crt_copysignl(0, c);\n            if (crt_isnan(d))\n                d = crt_copysignl(0, d);\n            recalc = 1;\n        }\n        if (crt_isinf(c) || crt_isinf(d)) {\n            c = crt_copysignl(crt_isinf(c) ? 1 : 0, c);\n            d = crt_copysignl(crt_isinf(d) ? 1 : 0, d);\n            if (crt_isnan(a))\n                a = crt_copysignl(0, a);\n            if (crt_isnan(b))\n                b = crt_copysignl(0, b);\n            recalc = 1;\n        }\n        if (!recalc && (crt_isinf(ac) || crt_isinf(bd) ||\n                          crt_isinf(ad) || crt_isinf(bc))) {\n            if (crt_isnan(a))\n                a = crt_copysignl(0, a);\n            if (crt_isnan(b))\n                b = crt_copysignl(0, b);\n            if (crt_isnan(c))\n                c = crt_copysignl(0, c);\n            if (crt_isnan(d))\n                d = crt_copysignl(0, d);\n            recalc = 1;\n        }\n        if (recalc) {\n            __real__ z = CRT_INFINITY * (a * c - b * d);\n            __imag__ z = CRT_INFINITY * (a * d + b * c);\n        }\n    }\n    return z;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/multf3.c",
    "content": "//===-- lib/multf3.c - Quad-precision multiplication --------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements quad-precision soft-float multiplication\n// with the IEEE-754 default rounding (to nearest, ties to even).\n//\n//===----------------------------------------------------------------------===//\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\n#include \"fp_mul_impl.inc\"\n\nCOMPILER_RT_ABI fp_t __multf3(fp_t a, fp_t b) {\n    return __mulXf3__(a, b);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/multi3.c",
    "content": "/* ===-- multi3.c - Implement __multi3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n\n * This file implements __multi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: a * b */\n\nstatic\nti_int\n__mulddi3(du_int a, du_int b)\n{\n    twords r;\n    const int bits_in_dword_2 = (int)(sizeof(di_int) * CHAR_BIT) / 2;\n    const du_int lower_mask = (du_int)~0 >> bits_in_dword_2;\n    r.s.low = (a & lower_mask) * (b & lower_mask);\n    du_int t = r.s.low >> bits_in_dword_2;\n    r.s.low &= lower_mask;\n    t += (a >> bits_in_dword_2) * (b & lower_mask);\n    r.s.low += (t & lower_mask) << bits_in_dword_2;\n    r.s.high = t >> bits_in_dword_2;\n    t = r.s.low >> bits_in_dword_2;\n    r.s.low &= lower_mask;\n    t += (b >> bits_in_dword_2) * (a & lower_mask);\n    r.s.low += (t & lower_mask) << bits_in_dword_2;\n    r.s.high += t >> bits_in_dword_2;\n    r.s.high += (a >> bits_in_dword_2) * (b >> bits_in_dword_2);\n    return r.all;\n}\n\n/* Returns: a * b */\n\nCOMPILER_RT_ABI ti_int\n__multi3(ti_int a, ti_int b)\n{\n    twords x;\n    x.all = a;\n    twords y;\n    y.all = b;\n    twords r;\n    r.all = __mulddi3(x.s.low, y.s.low);\n    r.s.high += x.s.high * y.s.low + x.s.low * y.s.high;\n    return r.all;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/mulvdi3.c",
    "content": "/*===-- mulvdi3.c - Implement __mulvdi3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __mulvdi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a * b */\n\n/* Effects: aborts if a * b overflows */\n\nCOMPILER_RT_ABI di_int\n__mulvdi3(di_int a, di_int b)\n{\n    const int N = (int)(sizeof(di_int) * CHAR_BIT);\n    const di_int MIN = (di_int)1 << (N-1);\n    const di_int MAX = ~MIN;\n    if (a == MIN)\n    {\n        if (b == 0 || b == 1)\n            return a * b;\n        compilerrt_abort();\n    }\n    if (b == MIN)\n    {\n        if (a == 0 || a == 1)\n            return a * b;\n        compilerrt_abort();\n    }\n    di_int sa = a >> (N - 1);\n    di_int abs_a = (a ^ sa) - sa;\n    di_int sb = b >> (N - 1);\n    di_int abs_b = (b ^ sb) - sb;\n    if (abs_a < 2 || abs_b < 2)\n        return a * b;\n    if (sa == sb)\n    {\n        if (abs_a > MAX / abs_b)\n            compilerrt_abort();\n    }\n    else\n    {\n        if (abs_a > MIN / -abs_b)\n            compilerrt_abort();\n    }\n    return a * b;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/mulvsi3.c",
    "content": "/* ===-- mulvsi3.c - Implement __mulvsi3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __mulvsi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a * b */\n\n/* Effects: aborts if a * b overflows */\n\nCOMPILER_RT_ABI si_int\n__mulvsi3(si_int a, si_int b)\n{\n    const int N = (int)(sizeof(si_int) * CHAR_BIT);\n    const si_int MIN = (si_int)1 << (N-1);\n    const si_int MAX = ~MIN;\n    if (a == MIN)\n    {\n        if (b == 0 || b == 1)\n            return a * b;\n        compilerrt_abort();\n    }\n    if (b == MIN)\n    {\n        if (a == 0 || a == 1)\n            return a * b;\n        compilerrt_abort();\n    }\n    si_int sa = a >> (N - 1);\n    si_int abs_a = (a ^ sa) - sa;\n    si_int sb = b >> (N - 1);\n    si_int abs_b = (b ^ sb) - sb;\n    if (abs_a < 2 || abs_b < 2)\n        return a * b;\n    if (sa == sb)\n    {\n        if (abs_a > MAX / abs_b)\n            compilerrt_abort();\n    }\n    else\n    {\n        if (abs_a > MIN / -abs_b)\n            compilerrt_abort();\n    }\n    return a * b;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/mulvti3.c",
    "content": "/* ===-- mulvti3.c - Implement __mulvti3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __mulvti3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: a * b */\n\n/* Effects: aborts if a * b overflows */\n\nCOMPILER_RT_ABI ti_int\n__mulvti3(ti_int a, ti_int b)\n{\n    const int N = (int)(sizeof(ti_int) * CHAR_BIT);\n    const ti_int MIN = (ti_int)1 << (N-1);\n    const ti_int MAX = ~MIN;\n    if (a == MIN)\n    {\n        if (b == 0 || b == 1)\n            return a * b;\n        compilerrt_abort();\n    }\n    if (b == MIN)\n    {\n        if (a == 0 || a == 1)\n            return a * b;\n        compilerrt_abort();\n    }\n    ti_int sa = a >> (N - 1);\n    ti_int abs_a = (a ^ sa) - sa;\n    ti_int sb = b >> (N - 1);\n    ti_int abs_b = (b ^ sb) - sb;\n    if (abs_a < 2 || abs_b < 2)\n        return a * b;\n    if (sa == sb)\n    {\n        if (abs_a > MAX / abs_b)\n            compilerrt_abort();\n    }\n    else\n    {\n        if (abs_a > MIN / -abs_b)\n            compilerrt_abort();\n    }\n    return a * b;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/mulxc3.c",
    "content": "/* ===-- mulxc3.c - Implement __mulxc3 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __mulxc3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#if !_ARCH_PPC\n\n#include \"int_lib.h\"\n#include \"int_math.h\"\n\n/* Returns: the product of a + ib and c + id */\n\nCOMPILER_RT_ABI Lcomplex\n__mulxc3(long double __a, long double __b, long double __c, long double __d)\n{\n    long double __ac = __a * __c;\n    long double __bd = __b * __d;\n    long double __ad = __a * __d;\n    long double __bc = __b * __c;\n    Lcomplex z;\n    COMPLEX_REAL(z) = __ac - __bd;\n    COMPLEX_IMAGINARY(z) = __ad + __bc;\n    if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z)))\n    {\n        int __recalc = 0;\n        if (crt_isinf(__a) || crt_isinf(__b))\n        {\n            __a = crt_copysignl(crt_isinf(__a) ? 1 : 0, __a);\n            __b = crt_copysignl(crt_isinf(__b) ? 1 : 0, __b);\n            if (crt_isnan(__c))\n                __c = crt_copysignl(0, __c);\n            if (crt_isnan(__d))\n                __d = crt_copysignl(0, __d);\n            __recalc = 1;\n        }\n        if (crt_isinf(__c) || crt_isinf(__d))\n        {\n            __c = crt_copysignl(crt_isinf(__c) ? 1 : 0, __c);\n            __d = crt_copysignl(crt_isinf(__d) ? 1 : 0, __d);\n            if (crt_isnan(__a))\n                __a = crt_copysignl(0, __a);\n            if (crt_isnan(__b))\n                __b = crt_copysignl(0, __b);\n            __recalc = 1;\n        }\n        if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) ||\n                          crt_isinf(__ad) || crt_isinf(__bc)))\n        {\n            if (crt_isnan(__a))\n                __a = crt_copysignl(0, __a);\n            if (crt_isnan(__b))\n                __b = crt_copysignl(0, __b);\n            if (crt_isnan(__c))\n                __c = crt_copysignl(0, __c);\n            if (crt_isnan(__d))\n                __d = crt_copysignl(0, __d);\n            __recalc = 1;\n        }\n        if (__recalc)\n        {\n            COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d);\n            COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c);\n        }\n    }\n    return z;\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/negdf2.c",
    "content": "//===-- lib/negdf2.c - double-precision negation ------------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements double-precision soft-float negation.\n//\n//===----------------------------------------------------------------------===//\n\n#define DOUBLE_PRECISION\n#include \"fp_lib.h\"\n\nARM_EABI_FNALIAS(dneg, negdf2)\n\nCOMPILER_RT_ABI fp_t\n__negdf2(fp_t a) {\n    return fromRep(toRep(a) ^ signBit);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/negdi2.c",
    "content": "/* ===-- negdi2.c - Implement __negdi2 -------------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __negdi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: -a */\n\nCOMPILER_RT_ABI di_int\n__negdi2(di_int a)\n{\n    /* Note: this routine is here for API compatibility; any sane compiler\n     * should expand it inline.\n     */\n    return -a;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/negsf2.c",
    "content": "//===-- lib/negsf2.c - single-precision negation ------------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements single-precision soft-float negation.\n//\n//===----------------------------------------------------------------------===//\n\n#define SINGLE_PRECISION\n#include \"fp_lib.h\"\n\nARM_EABI_FNALIAS(fneg, negsf2)\n\nCOMPILER_RT_ABI fp_t\n__negsf2(fp_t a) {\n    return fromRep(toRep(a) ^ signBit);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/negti2.c",
    "content": "/* ===-- negti2.c - Implement __negti2 -------------------------------------===\n *\n *      \t       The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __negti2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: -a */\n\nCOMPILER_RT_ABI ti_int\n__negti2(ti_int a)\n{\n    /* Note: this routine is here for API compatibility; any sane compiler\n     * should expand it inline.\n     */\n    return -a;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/negvdi2.c",
    "content": "/* ===-- negvdi2.c - Implement __negvdi2 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __negvdi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: -a */\n\n/* Effects: aborts if -a overflows */\n\nCOMPILER_RT_ABI di_int\n__negvdi2(di_int a)\n{\n    const di_int MIN = (di_int)1 << ((int)(sizeof(di_int) * CHAR_BIT)-1);\n    if (a == MIN)\n        compilerrt_abort();\n    return -a;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/negvsi2.c",
    "content": "/* ===-- negvsi2.c - Implement __negvsi2 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __negvsi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: -a */\n\n/* Effects: aborts if -a overflows */\n\nCOMPILER_RT_ABI si_int\n__negvsi2(si_int a)\n{\n    const si_int MIN = (si_int)1 << ((int)(sizeof(si_int) * CHAR_BIT)-1);\n    if (a == MIN)\n        compilerrt_abort();\n    return -a;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/negvti2.c",
    "content": "/*===-- negvti2.c - Implement __negvti2 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n *===----------------------------------------------------------------------===\n *\n *This file implements __negvti2 for the compiler_rt library.\n *\n *===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: -a */\n\n/* Effects: aborts if -a overflows */\n\nCOMPILER_RT_ABI ti_int\n__negvti2(ti_int a)\n{\n    const ti_int MIN = (ti_int)1 << ((int)(sizeof(ti_int) * CHAR_BIT)-1);\n    if (a == MIN)\n        compilerrt_abort();\n    return -a;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/paritydi2.c",
    "content": "/* ===-- paritydi2.c - Implement __paritydi2 -------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __paritydi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: 1 if number of bits is odd else returns 0 */\n\nCOMPILER_RT_ABI si_int\n__paritydi2(di_int a)\n{\n    dwords x;\n    x.all = a;\n    return __paritysi2(x.s.high ^ x.s.low);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/paritysi2.c",
    "content": "/* ===-- paritysi2.c - Implement __paritysi2 -------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __paritysi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: 1 if number of bits is odd else returns 0 */\n\nCOMPILER_RT_ABI si_int\n__paritysi2(si_int a)\n{\n    su_int x = (su_int)a;\n    x ^= x >> 16;\n    x ^= x >> 8;\n    x ^= x >> 4;\n    return (0x6996 >> (x & 0xF)) & 1;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/parityti2.c",
    "content": "/* ===-- parityti2.c - Implement __parityti2 -------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __parityti2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */ \n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: 1 if number of bits is odd else returns 0 */\n\nCOMPILER_RT_ABI si_int\n__parityti2(ti_int a)\n{\n    twords x;\n    x.all = a;\n    return __paritydi2(x.s.high ^ x.s.low);\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/popcountdi2.c",
    "content": "/* ===-- popcountdi2.c - Implement __popcountdi2 ----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __popcountdi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: count of 1 bits */\n\nCOMPILER_RT_ABI si_int\n__popcountdi2(di_int a)\n{\n    du_int x2 = (du_int)a;\n    x2 = x2 - ((x2 >> 1) & 0x5555555555555555uLL);\n    /* Every 2 bits holds the sum of every pair of bits (32) */\n    x2 = ((x2 >> 2) & 0x3333333333333333uLL) + (x2 & 0x3333333333333333uLL);\n    /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) (16) */\n    x2 = (x2 + (x2 >> 4)) & 0x0F0F0F0F0F0F0F0FuLL;\n    /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) (8) */\n    su_int x = (su_int)(x2 + (x2 >> 32));\n    /* The lower 32 bits hold four 16 bit sums (5 significant bits). */\n    /*   Upper 32 bits are garbage */\n    x = x + (x >> 16);\n    /* The lower 16 bits hold two 32 bit sums (6 significant bits). */\n    /*   Upper 16 bits are garbage */\n    return (x + (x >> 8)) & 0x0000007F;  /* (7 significant bits) */\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/popcountsi2.c",
    "content": "/* ===-- popcountsi2.c - Implement __popcountsi2 ---------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __popcountsi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: count of 1 bits */\n\nCOMPILER_RT_ABI si_int\n__popcountsi2(si_int a)\n{\n    su_int x = (su_int)a;\n    x = x - ((x >> 1) & 0x55555555);\n    /* Every 2 bits holds the sum of every pair of bits */\n    x = ((x >> 2) & 0x33333333) + (x & 0x33333333);\n    /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) */\n    x = (x + (x >> 4)) & 0x0F0F0F0F;\n    /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) */\n    x = (x + (x >> 16));\n    /* The lower 16 bits hold two 8 bit sums (5 significant bits).*/\n    /*    Upper 16 bits are garbage */\n    return (x + (x >> 8)) & 0x0000003F;  /* (6 significant bits) */\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/popcountti2.c",
    "content": "/* ===-- popcountti2.c - Implement __popcountti2 ----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __popcountti2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: count of 1 bits */\n\nCOMPILER_RT_ABI si_int\n__popcountti2(ti_int a)\n{\n    tu_int x3 = (tu_int)a;\n    x3 = x3 - ((x3 >> 1) & (((tu_int)0x5555555555555555uLL << 64) |\n                                     0x5555555555555555uLL));\n    /* Every 2 bits holds the sum of every pair of bits (64) */\n    x3 = ((x3 >> 2) & (((tu_int)0x3333333333333333uLL << 64) | 0x3333333333333333uLL))\n       + (x3 & (((tu_int)0x3333333333333333uLL << 64) | 0x3333333333333333uLL));\n    /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) (32) */\n    x3 = (x3 + (x3 >> 4))\n       & (((tu_int)0x0F0F0F0F0F0F0F0FuLL << 64) | 0x0F0F0F0F0F0F0F0FuLL);\n    /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) (16) */\n    du_int x2 = (du_int)(x3 + (x3 >> 64));\n    /* Every 8 bits holds the sum of every 8-set of bits (5 significant bits) (8) */\n    su_int x = (su_int)(x2 + (x2 >> 32));\n    /* Every 8 bits holds the sum of every 8-set of bits (6 significant bits) (4) */\n    x = x + (x >> 16);\n    /* Every 8 bits holds the sum of every 8-set of bits (7 significant bits) (2) */\n    /* Upper 16 bits are garbage */\n    return (x + (x >> 8)) & 0xFF;  /* (8 significant bits) */\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/powidf2.c",
    "content": "/* ===-- powidf2.cpp - Implement __powidf2 ---------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __powidf2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a ^ b */\n\nCOMPILER_RT_ABI double\n__powidf2(double a, si_int b)\n{\n    const int recip = b < 0;\n    double r = 1;\n    while (1)\n    {\n        if (b & 1)\n            r *= a;\n        b /= 2;\n        if (b == 0)\n            break;\n        a *= a;\n    }\n    return recip ? 1/r : r;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/powisf2.c",
    "content": "/*===-- powisf2.cpp - Implement __powisf2 ---------------------------------===\n *\n *                    The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __powisf2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a ^ b */\n\nCOMPILER_RT_ABI float\n__powisf2(float a, si_int b)\n{\n    const int recip = b < 0;\n    float r = 1;\n    while (1)\n    {\n        if (b & 1)\n            r *= a;\n        b /= 2;\n        if (b == 0)\n            break;\n        a *= a;\n    }\n    return recip ? 1/r : r;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/powitf2.c",
    "content": "/* ===-- powitf2.cpp - Implement __powitf2 ---------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __powitf2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#if _ARCH_PPC\n\n/* Returns: a ^ b */\n\nCOMPILER_RT_ABI long double\n__powitf2(long double a, si_int b)\n{\n    const int recip = b < 0;\n    long double r = 1;\n    while (1)\n    {\n        if (b & 1)\n            r *= a;\n        b /= 2;\n        if (b == 0)\n            break;\n        a *= a;\n    }\n    return recip ? 1/r : r;\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/powixf2.c",
    "content": "/* ===-- powixf2.cpp - Implement __powixf2 ---------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __powixf2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#if !_ARCH_PPC\n\n#include \"int_lib.h\"\n\n/* Returns: a ^ b */\n\nCOMPILER_RT_ABI long double\n__powixf2(long double a, si_int b)\n{\n    const int recip = b < 0;\n    long double r = 1;\n    while (1)\n    {\n        if (b & 1)\n            r *= a;\n        b /= 2;\n        if (b == 0)\n            break;\n        a *= a;\n    }\n    return recip ? 1/r : r;\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ppc/DD.h",
    "content": "#ifndef COMPILERRT_DD_HEADER\n#define COMPILERRT_DD_HEADER\n\n#include \"../int_lib.h\"\n\ntypedef union {\n\tlong double ld;\n\tstruct {\n\t\tdouble hi;\n\t\tdouble lo;\n\t}s;\n} DD;\n\ntypedef union { \n\tdouble d;\n\tuint64_t x;\n} doublebits;\n\n#define LOWORDER(xy,xHi,xLo,yHi,yLo) \\\n\t(((((xHi)*(yHi) - (xy)) + (xHi)*(yLo)) + (xLo)*(yHi)) + (xLo)*(yLo))\n\nstatic __inline ALWAYS_INLINE double local_fabs(double x) {\n  doublebits result = {.d = x};\n  result.x &= UINT64_C(0x7fffffffffffffff);\n  return result.d;\n}\n\nstatic __inline ALWAYS_INLINE double high26bits(double x) {\n  doublebits result = {.d = x};\n  result.x &= UINT64_C(0xfffffffff8000000);\n  return result.d;\n}\n\nstatic __inline ALWAYS_INLINE int different_sign(double x, double y) {\n  doublebits xsignbit = {.d = x}, ysignbit = {.d = y};\n  int result = (int)(xsignbit.x >> 63) ^ (int)(ysignbit.x >> 63);\n  return result;\n}\n\nlong double __gcc_qadd(long double, long double);\nlong double __gcc_qsub(long double, long double);\nlong double __gcc_qmul(long double, long double);\nlong double __gcc_qdiv(long double, long double);\n\n#endif /* COMPILERRT_DD_HEADER */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ppc/Makefile.mk",
    "content": "#===- lib/builtins/ppc/Makefile.mk -------------------------*- Makefile -*--===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\nModuleName := builtins\nSubDirs := \nOnlyArchs := ppc\n\nAsmSources := $(foreach file,$(wildcard $(Dir)/*.S),$(notdir $(file)))\nSources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))\nObjNames := $(Sources:%.c=%.o) $(AsmSources:%.S=%.o)\nImplementation := Optimized\n\n# FIXME: use automatic dependencies?\nDependencies := $(wildcard lib/*.h $(Dir)/*.h)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ppc/divtc3.c",
    "content": "/* This file is distributed under the University of Illinois Open Source\n * License. See LICENSE.TXT for details.\n */\n\n#include \"DD.h\"\n#include \"../int_math.h\"\n\n#if !defined(CRT_INFINITY) && defined(HUGE_VAL)\n#define CRT_INFINITY HUGE_VAL\n#endif /* CRT_INFINITY */\n\n#define makeFinite(x) { \\\n    (x).s.hi = crt_copysign(crt_isinf((x).s.hi) ? 1.0 : 0.0, (x).s.hi); \\\n    (x).s.lo = 0.0;                                                     \\\n  }\n\nlong double _Complex\n__divtc3(long double a, long double b, long double c, long double d)\n{\n\tDD cDD = { .ld = c };\n\tDD dDD = { .ld = d };\n\t\n\tint ilogbw = 0;\n\tconst double logbw = crt_logb(crt_fmax(crt_fabs(cDD.s.hi), crt_fabs(dDD.s.hi) ));\n\t\n\tif (crt_isfinite(logbw))\n\t{\n\t\tilogbw = (int)logbw;\n\t\t\n\t\tcDD.s.hi = crt_scalbn(cDD.s.hi, -ilogbw);\n\t\tcDD.s.lo = crt_scalbn(cDD.s.lo, -ilogbw);\n\t\tdDD.s.hi = crt_scalbn(dDD.s.hi, -ilogbw);\n\t\tdDD.s.lo = crt_scalbn(dDD.s.lo, -ilogbw);\n\t}\n\t\n\tconst long double denom = __gcc_qadd(__gcc_qmul(cDD.ld, cDD.ld), __gcc_qmul(dDD.ld, dDD.ld));\n\tconst long double realNumerator = __gcc_qadd(__gcc_qmul(a,cDD.ld), __gcc_qmul(b,dDD.ld));\n\tconst long double imagNumerator = __gcc_qsub(__gcc_qmul(b,cDD.ld), __gcc_qmul(a,dDD.ld));\n\t\n\tDD real = { .ld = __gcc_qdiv(realNumerator, denom) };\n\tDD imag = { .ld = __gcc_qdiv(imagNumerator, denom) };\n\t\n\treal.s.hi = crt_scalbn(real.s.hi, -ilogbw);\n\treal.s.lo = crt_scalbn(real.s.lo, -ilogbw);\n\timag.s.hi = crt_scalbn(imag.s.hi, -ilogbw);\n\timag.s.lo = crt_scalbn(imag.s.lo, -ilogbw);\n\t\n\tif (crt_isnan(real.s.hi) && crt_isnan(imag.s.hi))\n\t{\n\t\tDD aDD = { .ld = a };\n\t\tDD bDD = { .ld = b };\n\t\tDD rDD = { .ld = denom };\n\t\t\n\t\tif ((rDD.s.hi == 0.0) && (!crt_isnan(aDD.s.hi) ||\n                                          !crt_isnan(bDD.s.hi)))\n\t\t{\n\t\t\treal.s.hi = crt_copysign(CRT_INFINITY,cDD.s.hi) * aDD.s.hi;\n\t\t\treal.s.lo = 0.0;\n\t\t\timag.s.hi = crt_copysign(CRT_INFINITY,cDD.s.hi) * bDD.s.hi;\n\t\t\timag.s.lo = 0.0;\n\t\t}\n\t\t\n\t\telse if ((crt_isinf(aDD.s.hi) || crt_isinf(bDD.s.hi)) &&\n                         crt_isfinite(cDD.s.hi) && crt_isfinite(dDD.s.hi))\n\t\t{\n\t\t\tmakeFinite(aDD);\n\t\t\tmakeFinite(bDD);\n\t\t\treal.s.hi = CRT_INFINITY * (aDD.s.hi*cDD.s.hi + bDD.s.hi*dDD.s.hi);\n\t\t\treal.s.lo = 0.0;\n\t\t\timag.s.hi = CRT_INFINITY * (bDD.s.hi*cDD.s.hi - aDD.s.hi*dDD.s.hi);\n\t\t\timag.s.lo = 0.0;\n\t\t}\n\t\t\n\t\telse if ((crt_isinf(cDD.s.hi) || crt_isinf(dDD.s.hi)) &&\n                         crt_isfinite(aDD.s.hi) && crt_isfinite(bDD.s.hi))\n\t\t{\n\t\t\tmakeFinite(cDD);\n\t\t\tmakeFinite(dDD);\n\t\t\treal.s.hi = crt_copysign(0.0,(aDD.s.hi*cDD.s.hi + bDD.s.hi*dDD.s.hi));\n\t\t\treal.s.lo = 0.0;\n\t\t\timag.s.hi = crt_copysign(0.0,(bDD.s.hi*cDD.s.hi - aDD.s.hi*dDD.s.hi));\n\t\t\timag.s.lo = 0.0;\n\t\t}\n\t}\n\t\n\tlong double _Complex z;\n\t__real__ z = real.ld;\n\t__imag__ z = imag.ld;\n\t\n\treturn z;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ppc/fixtfdi.c",
    "content": "/* This file is distributed under the University of Illinois Open Source\n * License. See LICENSE.TXT for details.\n */\n\n/* int64_t __fixunstfdi(long double x);\n * This file implements the PowerPC 128-bit double-double -> int64_t conversion\n */\n\n#include \"DD.h\"\n#include \"../int_math.h\"\n\nuint64_t __fixtfdi(long double input)\n{\n\tconst DD x = { .ld = input };\n\tconst doublebits hibits = { .d = x.s.hi };\n\t\n\tconst uint32_t absHighWord = (uint32_t)(hibits.x >> 32) & UINT32_C(0x7fffffff);\n\tconst uint32_t absHighWordMinusOne = absHighWord - UINT32_C(0x3ff00000);\n\t\n\t/* If (1.0 - tiny) <= input < 0x1.0p63: */\n\tif (UINT32_C(0x03f00000) > absHighWordMinusOne)\n\t{\n\t\t/* Do an unsigned conversion of the absolute value, then restore the sign. */\n\t\tconst int unbiasedHeadExponent = absHighWordMinusOne >> 20;\n\t\t\n\t\tint64_t result = hibits.x & INT64_C(0x000fffffffffffff); /* mantissa(hi) */\n\t\tresult |= INT64_C(0x0010000000000000); /* matissa(hi) with implicit bit */\n\t\tresult <<= 10; /* mantissa(hi) with one zero preceding bit. */\n\t\t\n\t\tconst int64_t hiNegationMask = ((int64_t)(hibits.x)) >> 63;\n\t\t\n\t\t/* If the tail is non-zero, we need to patch in the tail bits. */\n\t\tif (0.0 != x.s.lo)\n\t\t{\n\t\t\tconst doublebits lobits = { .d = x.s.lo };\n\t\t\tint64_t tailMantissa = lobits.x & INT64_C(0x000fffffffffffff);\n\t\t\ttailMantissa |= INT64_C(0x0010000000000000);\n\t\t\t\n\t\t\t/* At this point we have the mantissa of |tail| */\n\t\t\t/* We need to negate it if head and tail have different signs. */\n\t\t\tconst int64_t loNegationMask = ((int64_t)(lobits.x)) >> 63;\n\t\t\tconst int64_t negationMask = loNegationMask ^ hiNegationMask;\n\t\t\ttailMantissa = (tailMantissa ^ negationMask) - negationMask;\n\t\t\t\n\t\t\t/* Now we have the mantissa of tail as a signed 2s-complement integer */\n\t\t\t\n\t\t\tconst int biasedTailExponent = (int)(lobits.x >> 52) & 0x7ff;\n\t\t\t\n\t\t\t/* Shift the tail mantissa into the right position, accounting for the\n\t\t\t * bias of 10 that we shifted the head mantissa by.\n\t\t\t */ \n\t\t\ttailMantissa >>= (unbiasedHeadExponent - (biasedTailExponent - (1023 - 10)));\n\t\t\t\n\t\t\tresult += tailMantissa;\n\t\t}\n\t\t\n\t\tresult >>= (62 - unbiasedHeadExponent);\n\t\t\n\t\t/* Restore the sign of the result and return */\n\t\tresult = (result ^ hiNegationMask) - hiNegationMask;\n\t\treturn result;\n\t\t\n\t}\n\n\t/* Edge cases handled here: */\n\t\n\t/* |x| < 1, result is zero. */\n\tif (1.0 > crt_fabs(x.s.hi))\n\t\treturn INT64_C(0);\n\t\n\t/* x very close to INT64_MIN, care must be taken to see which side we are on. */\n\tif (x.s.hi == -0x1.0p63) {\n\t\t\n\t\tint64_t result = INT64_MIN;\n\t\t\n\t\tif (0.0 < x.s.lo)\n\t\t{\n\t\t\t/* If the tail is positive, the correct result is something other than INT64_MIN.\n\t\t\t * we'll need to figure out what it is.\n\t\t\t */\n\n\t\t\tconst doublebits lobits = { .d = x.s.lo };\n\t\t\tint64_t tailMantissa = lobits.x & INT64_C(0x000fffffffffffff);\n\t\t\ttailMantissa |= INT64_C(0x0010000000000000);\n\t\t\t\n\t\t\t/* Now we negate the tailMantissa */\n\t\t\ttailMantissa = (tailMantissa ^ INT64_C(-1)) + INT64_C(1);\n\t\t\t\n\t\t\t/* And shift it by the appropriate amount */\n\t\t\tconst int biasedTailExponent = (int)(lobits.x >> 52) & 0x7ff;\n\t\t\ttailMantissa >>= 1075 - biasedTailExponent;\n\t\t\t\n\t\t\tresult -= tailMantissa;\n\t\t}\n\t\t\n\t\treturn result;\n\t}\n\t\n\t/* Signed overflows, infinities, and NaNs */\n\tif (x.s.hi > 0.0)\n\t\treturn INT64_MAX;\n\telse\n\t\treturn INT64_MIN;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ppc/fixunstfdi.c",
    "content": "/* This file is distributed under the University of Illinois Open Source\n * License. See LICENSE.TXT for details.\n */\n\n/* uint64_t __fixunstfdi(long double x); */\n/* This file implements the PowerPC 128-bit double-double -> uint64_t conversion */\n\n#include \"DD.h\"\n\nuint64_t __fixunstfdi(long double input)\n{\n\tconst DD x = { .ld = input };\n\tconst doublebits hibits = { .d = x.s.hi };\n\t\n\tconst uint32_t highWordMinusOne = (uint32_t)(hibits.x >> 32) - UINT32_C(0x3ff00000);\n\t\n\t/* If (1.0 - tiny) <= input < 0x1.0p64: */\n\tif (UINT32_C(0x04000000) > highWordMinusOne)\n\t{\n\t\tconst int unbiasedHeadExponent = highWordMinusOne >> 20;\n\t\t\n\t\tuint64_t result = hibits.x & UINT64_C(0x000fffffffffffff); /* mantissa(hi) */\n\t\tresult |= UINT64_C(0x0010000000000000); /* matissa(hi) with implicit bit */\n\t\tresult <<= 11; /* mantissa(hi) left aligned in the int64 field. */\n\t\t\n\t\t/* If the tail is non-zero, we need to patch in the tail bits. */\n\t\tif (0.0 != x.s.lo)\n\t\t{\n\t\t\tconst doublebits lobits = { .d = x.s.lo };\n\t\t\tint64_t tailMantissa = lobits.x & INT64_C(0x000fffffffffffff);\n\t\t\ttailMantissa |= INT64_C(0x0010000000000000);\n\t\t\t\n\t\t\t/* At this point we have the mantissa of |tail| */\n\t\t\t\n\t\t\tconst int64_t negationMask = ((int64_t)(lobits.x)) >> 63;\n\t\t\ttailMantissa = (tailMantissa ^ negationMask) - negationMask;\n\t\t\t\n\t\t\t/* Now we have the mantissa of tail as a signed 2s-complement integer */\n\t\t\t\n\t\t\tconst int biasedTailExponent = (int)(lobits.x >> 52) & 0x7ff;\n\t\t\t\n\t\t\t/* Shift the tail mantissa into the right position, accounting for the\n\t\t\t * bias of 11 that we shifted the head mantissa by.\n\t\t\t */\n\t\t\ttailMantissa >>= (unbiasedHeadExponent - (biasedTailExponent - (1023 - 11)));\n\t\t\t\n\t\t\tresult += tailMantissa;\n\t\t}\n\t\t\n\t\tresult >>= (63 - unbiasedHeadExponent);\n\t\treturn result;\n\t}\n\t\n\t/* Edge cases are handled here, with saturation. */\n\tif (1.0 > x.s.hi)\n\t\treturn UINT64_C(0);\n\telse\n\t\treturn UINT64_MAX;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ppc/floatditf.c",
    "content": "/* This file is distributed under the University of Illinois Open Source\n * License. See LICENSE.TXT for details.\n */\n\n/* long double __floatditf(long long x); */\n/* This file implements the PowerPC long long -> long double conversion */\n\n#include \"DD.h\"\n\nlong double __floatditf(int64_t a) {\n\t\n\tstatic const double twop32 = 0x1.0p32;\n\tstatic const double twop52 = 0x1.0p52;\n\t\n\tdoublebits low  = { .d = twop52 };\n\tlow.x |= a & UINT64_C(0x00000000ffffffff);\t/* 0x1.0p52 + low 32 bits of a. */\n\t\n\tconst double high_addend = (double)((int32_t)(a >> 32))*twop32 - twop52;\n\t\n\t/* At this point, we have two double precision numbers\n\t * high_addend and low.d, and we wish to return their sum\n\t * as a canonicalized long double:\n\t */\n\n\t/* This implementation sets the inexact flag spuriously.\n\t * This could be avoided, but at some substantial cost.\n\t*/\n\n\tDD result;\n\t\n\tresult.s.hi = high_addend + low.d;\n\tresult.s.lo = (high_addend - result.s.hi) + low.d;\n\t\n\treturn result.ld;\n\t\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ppc/floatunditf.c",
    "content": "/* This file is distributed under the University of Illinois Open Source\n * License. See LICENSE.TXT for details.\n */\n\n/* long double __floatunditf(unsigned long long x); */\n/* This file implements the PowerPC unsigned long long -> long double conversion */\n\n#include \"DD.h\"\n\nlong double __floatunditf(uint64_t a) {\n\t\n\t/* Begins with an exact copy of the code from __floatundidf */\n\t\n\tstatic const double twop52 = 0x1.0p52;\n\tstatic const double twop84 = 0x1.0p84;\n\tstatic const double twop84_plus_twop52 = 0x1.00000001p84;\n\t\n\tdoublebits high = { .d = twop84 };\n\tdoublebits low  = { .d = twop52 };\n\t\n\thigh.x |= a >> 32;\t\t\t\t\t\t\t/* 0x1.0p84 + high 32 bits of a */\n\tlow.x |= a & UINT64_C(0x00000000ffffffff);\t/* 0x1.0p52 + low 32 bits of a */\n\t\n\tconst double high_addend = high.d - twop84_plus_twop52;\n\t\n\t/* At this point, we have two double precision numbers\n\t * high_addend and low.d, and we wish to return their sum\n\t * as a canonicalized long double:\n\t */\n\n\t/* This implementation sets the inexact flag spuriously. */\n\t/* This could be avoided, but at some substantial cost. */\n\t\n\tDD result;\n\t\n\tresult.s.hi = high_addend + low.d;\n\tresult.s.lo = (high_addend - result.s.hi) + low.d;\n\t\n\treturn result.ld;\n\t\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ppc/gcc_qadd.c",
    "content": "/* This file is distributed under the University of Illinois Open Source\n *  License. See LICENSE.TXT for details.\n */\n\n/* long double __gcc_qadd(long double x, long double y);\n * This file implements the PowerPC 128-bit double-double add operation.\n * This implementation is shamelessly cribbed from Apple's DDRT, circa 1993(!)\n */\n\n#include \"DD.h\"\n\nlong double __gcc_qadd(long double x, long double y)\n{\n\tstatic const uint32_t infinityHi = UINT32_C(0x7ff00000);\n\t\n\tDD dst = { .ld = x }, src = { .ld = y };\n\t\n\tregister double A = dst.s.hi, a = dst.s.lo,\n\t\t\t\t\tB = src.s.hi, b = src.s.lo;\n\t\n\t/* If both operands are zero: */\n\tif ((A == 0.0) && (B == 0.0)) {\n\t\tdst.s.hi = A + B;\n\t\tdst.s.lo = 0.0;\n\t\treturn dst.ld;\n\t}\n\t\n\t/* If either operand is NaN or infinity: */\n\tconst doublebits abits = { .d = A };\n\tconst doublebits bbits = { .d = B };\n\tif ((((uint32_t)(abits.x >> 32) & infinityHi) == infinityHi) ||\n\t\t(((uint32_t)(bbits.x >> 32) & infinityHi) == infinityHi)) {\n\t\tdst.s.hi = A + B;\n\t\tdst.s.lo = 0.0;\n\t\treturn dst.ld;\n\t}\n\t\n\t/* If the computation overflows: */\n\t/* This may be playing things a little bit fast and loose, but it will do for a start. */\n\tconst double testForOverflow = A + (B + (a + b));\n\tconst doublebits testbits = { .d = testForOverflow };\n\tif (((uint32_t)(testbits.x >> 32) & infinityHi) == infinityHi) {\n\t\tdst.s.hi = testForOverflow;\n\t\tdst.s.lo = 0.0;\n\t\treturn dst.ld;\n\t}\n\t\n\tdouble H, h;\n\tdouble T, t;\n\tdouble W, w;\n\tdouble Y;\n\t\n\tH = B + (A - (A + B));\n\tT = b + (a - (a + b));\n\th = A + (B - (A + B));\n\tt = a + (b - (a + b));\n\t\n\tif (local_fabs(A) <= local_fabs(B))\n\t\tw = (a + b) + h;\n\telse\n\t\tw = (a + b) + H;\n\t\n\tW = (A + B) + w;\n\tY = (A + B) - W;\n\tY += w;\n\t\n\tif (local_fabs(a) <= local_fabs(b))\n\t\tw = t + Y;\n\telse\n\t\tw = T + Y;\n\t\n\tdst.s.hi = Y = W + w;\n\tdst.s.lo = (W - Y) + w;\n\t\n\treturn dst.ld;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ppc/gcc_qdiv.c",
    "content": "/* This file is distributed under the University of Illinois Open Source\n * License. See LICENSE.TXT for details.\n */\n\n/* long double __gcc_qdiv(long double x, long double y);\n * This file implements the PowerPC 128-bit double-double division operation.\n * This implementation is shamelessly cribbed from Apple's DDRT, circa 1993(!)\n */\n\n#include \"DD.h\"\n\nlong double __gcc_qdiv(long double a, long double b)\n{\t\n\tstatic const uint32_t infinityHi = UINT32_C(0x7ff00000);\n\tDD dst = { .ld = a }, src = { .ld = b };\n\t\n\tregister double x = dst.s.hi, x1 = dst.s.lo,\n\t\t\t\t\ty = src.s.hi, y1 = src.s.lo;\n\t\n    double yHi, yLo, qHi, qLo;\n    double yq, tmp, q;\n\t\n    q = x / y;\n\t\n\t/* Detect special cases */\n\tif (q == 0.0) {\n\t\tdst.s.hi = q;\n\t\tdst.s.lo = 0.0;\n\t\treturn dst.ld;\n\t}\n\t\n\tconst doublebits qBits = { .d = q };\n\tif (((uint32_t)(qBits.x >> 32) & infinityHi) == infinityHi) {\n\t\tdst.s.hi = q;\n\t\tdst.s.lo = 0.0;\n\t\treturn dst.ld;\n\t}\n\t\n    yHi = high26bits(y);\n    qHi = high26bits(q);\n\t\n    yq = y * q;\n    yLo = y - yHi;\n    qLo = q - qHi;\n\t\n    tmp = LOWORDER(yq, yHi, yLo, qHi, qLo);\n    tmp = (x - yq) - tmp;\n    tmp = ((tmp + x1) - y1 * q) / y;\n    x = q + tmp;\n\t\n    dst.s.lo = (q - x) + tmp;\n    dst.s.hi = x;\n\t\n    return dst.ld;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ppc/gcc_qmul.c",
    "content": "/* This file is distributed under the University of Illinois Open Source\n * License. See LICENSE.TXT for details.\n */\n\n/* long double __gcc_qmul(long double x, long double y);\n * This file implements the PowerPC 128-bit double-double multiply operation.\n * This implementation is shamelessly cribbed from Apple's DDRT, circa 1993(!)\n */\n\n#include \"DD.h\"\n\nlong double __gcc_qmul(long double x, long double y)\n{\t\n\tstatic const uint32_t infinityHi = UINT32_C(0x7ff00000);\n\tDD dst = { .ld = x }, src = { .ld = y };\n\t\n\tregister double A = dst.s.hi, a = dst.s.lo,\n\t\t\t\t\tB = src.s.hi, b = src.s.lo;\n\t\n\tdouble aHi, aLo, bHi, bLo;\n    double ab, tmp, tau;\n\t\n\tab = A * B;\n\t\n\t/* Detect special cases */\n\tif (ab == 0.0) {\n\t\tdst.s.hi = ab;\n\t\tdst.s.lo = 0.0;\n\t\treturn dst.ld;\n\t}\n\t\n\tconst doublebits abBits = { .d = ab };\n\tif (((uint32_t)(abBits.x >> 32) & infinityHi) == infinityHi) {\n\t\tdst.s.hi = ab;\n\t\tdst.s.lo = 0.0;\n\t\treturn dst.ld;\n\t}\n\t\n\t/* Generic cases handled here. */\n    aHi = high26bits(A);\n    bHi = high26bits(B);\n    aLo = A - aHi;\n    bLo = B - bHi;\n\t\n    tmp = LOWORDER(ab, aHi, aLo, bHi, bLo);\n    tmp += (A * b + a * B);\n    tau = ab + tmp;\n\t\n    dst.s.lo = (ab - tau) + tmp;\n    dst.s.hi = tau;\n\t\n    return dst.ld;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ppc/gcc_qsub.c",
    "content": "/* This file is distributed under the University of Illinois Open Source\n * License. See LICENSE.TXT for details.\n */\n\n/* long double __gcc_qsub(long double x, long double y);\n * This file implements the PowerPC 128-bit double-double add operation.\n * This implementation is shamelessly cribbed from Apple's DDRT, circa 1993(!)\n */\n\n#include \"DD.h\"\n\nlong double __gcc_qsub(long double x, long double y)\n{\n\tstatic const uint32_t infinityHi = UINT32_C(0x7ff00000);\n\t\n\tDD dst = { .ld = x }, src = { .ld = y };\n\t\n\tregister double A =  dst.s.hi, a =  dst.s.lo,\n\t\t\t\t\tB = -src.s.hi, b = -src.s.lo;\n\t\n\t/* If both operands are zero: */\n\tif ((A == 0.0) && (B == 0.0)) {\n\t\tdst.s.hi = A + B;\n\t\tdst.s.lo = 0.0;\n\t\treturn dst.ld;\n\t}\n\t\n\t/* If either operand is NaN or infinity: */\n\tconst doublebits abits = { .d = A };\n\tconst doublebits bbits = { .d = B };\n\tif ((((uint32_t)(abits.x >> 32) & infinityHi) == infinityHi) ||\n\t\t(((uint32_t)(bbits.x >> 32) & infinityHi) == infinityHi)) {\n\t\tdst.s.hi = A + B;\n\t\tdst.s.lo = 0.0;\n\t\treturn dst.ld;\n\t}\n\t\n\t/* If the computation overflows: */\n\t/* This may be playing things a little bit fast and loose, but it will do for a start. */\n\tconst double testForOverflow = A + (B + (a + b));\n\tconst doublebits testbits = { .d = testForOverflow };\n\tif (((uint32_t)(testbits.x >> 32) & infinityHi) == infinityHi) {\n\t\tdst.s.hi = testForOverflow;\n\t\tdst.s.lo = 0.0;\n\t\treturn dst.ld;\n\t}\n\t\n\tdouble H, h;\n\tdouble T, t;\n\tdouble W, w;\n\tdouble Y;\n\t\n\tH = B + (A - (A + B));\n\tT = b + (a - (a + b));\n\th = A + (B - (A + B));\n\tt = a + (b - (a + b));\n\t\n\tif (local_fabs(A) <= local_fabs(B))\n\t\tw = (a + b) + h;\n\telse\n\t\tw = (a + b) + H;\n\t\n\tW = (A + B) + w;\n\tY = (A + B) - W;\n\tY += w;\n\t\n\tif (local_fabs(a) <= local_fabs(b))\n\t\tw = t + Y;\n\telse\n\t\tw = T + Y;\n\t\n\tdst.s.hi = Y = W + w;\n\tdst.s.lo = (W - Y) + w;\n\t\n\treturn dst.ld;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ppc/multc3.c",
    "content": "/* This file is distributed under the University of Illinois Open Source\n * License. See LICENSE.TXT for details.\n */\n\n#include \"DD.h\"\n#include \"../int_math.h\"\n\n#define makeFinite(x) { \\\n    (x).s.hi = crt_copysign(crt_isinf((x).s.hi) ? 1.0 : 0.0, (x).s.hi); \\\n    (x).s.lo = 0.0;                                                     \\\n  }\n\n#define zeroNaN(x) { \\\n    if (crt_isnan((x).s.hi)) {                                          \\\n      (x).s.hi = crt_copysign(0.0, (x).s.hi);                     \\\n      (x).s.lo = 0.0;                                                   \\\n    }                                                                   \\\n  }\n\nlong double _Complex\n__multc3(long double a, long double b, long double c, long double d)\n{\n\tlong double ac = __gcc_qmul(a,c);\n\tlong double bd = __gcc_qmul(b,d);\n\tlong double ad = __gcc_qmul(a,d);\n\tlong double bc = __gcc_qmul(b,c);\n\t\n\tDD real = { .ld = __gcc_qsub(ac,bd) };\n\tDD imag = { .ld = __gcc_qadd(ad,bc) };\n\t\n\tif (crt_isnan(real.s.hi) && crt_isnan(imag.s.hi))\n\t{\n\t\tint recalc = 0;\n\t\t\n\t\tDD aDD = { .ld = a };\n\t\tDD bDD = { .ld = b };\n\t\tDD cDD = { .ld = c };\n\t\tDD dDD = { .ld = d };\n\t\t\n\t\tif (crt_isinf(aDD.s.hi) || crt_isinf(bDD.s.hi))\n\t\t{\n\t\t\tmakeFinite(aDD);\n\t\t\tmakeFinite(bDD);\n\t\t\tzeroNaN(cDD);\n\t\t\tzeroNaN(dDD);\n\t\t\trecalc = 1;\n\t\t}\n\t\t\n\t\tif (crt_isinf(cDD.s.hi) || crt_isinf(dDD.s.hi))\n\t\t{\n\t\t\tmakeFinite(cDD);\n\t\t\tmakeFinite(dDD);\n\t\t\tzeroNaN(aDD);\n\t\t\tzeroNaN(bDD);\n\t\t\trecalc = 1;\n\t\t}\n\t\t\n\t\tif (!recalc)\n\t\t{\n\t\t\tDD acDD = { .ld = ac };\n\t\t\tDD bdDD = { .ld = bd };\n\t\t\tDD adDD = { .ld = ad };\n\t\t\tDD bcDD = { .ld = bc };\n\t\t\t\n\t\t\tif (crt_isinf(acDD.s.hi) || crt_isinf(bdDD.s.hi) ||\n                            crt_isinf(adDD.s.hi) || crt_isinf(bcDD.s.hi))\n\t\t\t{\n\t\t\t\tzeroNaN(aDD);\n\t\t\t\tzeroNaN(bDD);\n\t\t\t\tzeroNaN(cDD);\n\t\t\t\tzeroNaN(dDD);\n\t\t\t\trecalc = 1;\n\t\t\t}\n\t\t}\n\t\t\n\t\tif (recalc)\n\t\t{\n\t\t\treal.s.hi = CRT_INFINITY * (aDD.s.hi*cDD.s.hi - bDD.s.hi*dDD.s.hi);\n\t\t\treal.s.lo = 0.0;\n\t\t\timag.s.hi = CRT_INFINITY * (aDD.s.hi*dDD.s.hi + bDD.s.hi*cDD.s.hi);\n\t\t\timag.s.lo = 0.0;\n\t\t}\n\t}\n\t\n\tlong double _Complex z;\n\t__real__ z = real.ld;\n\t__imag__ z = imag.ld;\n\t\n\treturn z;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ppc/restFP.S",
    "content": "//===-- restFP.S - Implement restFP ---------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// Helper function used by compiler to restore ppc floating point registers at\n// the end of the function epilog.  This function returns to the address\n// in the LR slot.  So a function epilog must branch (b) not branch and link\n// (bl) to this function.\n// If the compiler wants to restore f27..f31, it does a \"b restFP+52\"\n//\n// This function should never be exported by a shared library.  Each linkage\n// unit carries its own copy of this function.\n//\nDEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(restFP)\n        lfd    f14,-144(r1)\n        lfd    f15,-136(r1)\n        lfd    f16,-128(r1)\n        lfd    f17,-120(r1)\n        lfd    f18,-112(r1)\n        lfd    f19,-104(r1)\n        lfd    f20,-96(r1)\n        lfd    f21,-88(r1)\n        lfd    f22,-80(r1)\n        lfd    f23,-72(r1)\n        lfd    f24,-64(r1)\n        lfd    f25,-56(r1)\n        lfd    f26,-48(r1)\n        lfd    f27,-40(r1)\n        lfd    f28,-32(r1)\n        lfd    f29,-24(r1)\n        lfd    f30,-16(r1)\n        lfd    f31,-8(r1)\n        lwz     r0,8(r1)\n        mtlr\tr0\n        blr\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ppc/saveFP.S",
    "content": "//===-- saveFP.S - Implement saveFP ---------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n//\n// Helper function used by compiler to save ppc floating point registers in\n// function prologs.  This routines also saves r0 in the LR slot.\n// If the compiler wants to save f27..f31, it does a \"bl saveFP+52\"\n//\n// This function should never be exported by a shared library.  Each linkage\n// unit carries its own copy of this function.\n//\nDEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(saveFP)\n\tstfd    f14,-144(r1)\n        stfd    f15,-136(r1)\n        stfd    f16,-128(r1)\n        stfd    f17,-120(r1)\n        stfd    f18,-112(r1)\n        stfd    f19,-104(r1)\n        stfd    f20,-96(r1)\n        stfd    f21,-88(r1)\n        stfd    f22,-80(r1)\n        stfd    f23,-72(r1)\n        stfd    f24,-64(r1)\n        stfd    f25,-56(r1)\n        stfd    f26,-48(r1)\n        stfd    f27,-40(r1)\n        stfd    f28,-32(r1)\n        stfd    f29,-24(r1)\n        stfd    f30,-16(r1)\n        stfd    f31,-8(r1)\n        stw      r0,8(r1)\n        blr\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/subdf3.c",
    "content": "//===-- lib/adddf3.c - Double-precision subtraction ---------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements double-precision soft-float subtraction with the\n// IEEE-754 default rounding (to nearest, ties to even).\n//\n//===----------------------------------------------------------------------===//\n\n#define DOUBLE_PRECISION\n#include \"fp_lib.h\"\n\nARM_EABI_FNALIAS(dsub, subdf3)\n\n// Subtraction; flip the sign bit of b and add.\nCOMPILER_RT_ABI fp_t\n__subdf3(fp_t a, fp_t b) {\n    return __adddf3(a, fromRep(toRep(b) ^ signBit));\n}\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/subsf3.c",
    "content": "//===-- lib/subsf3.c - Single-precision subtraction ---------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements single-precision soft-float subtraction with the\n// IEEE-754 default rounding (to nearest, ties to even).\n//\n//===----------------------------------------------------------------------===//\n\n#define SINGLE_PRECISION\n#include \"fp_lib.h\"\n\nARM_EABI_FNALIAS(fsub, subsf3)\n\n// Subtraction; flip the sign bit of b and add.\nCOMPILER_RT_ABI fp_t\n__subsf3(fp_t a, fp_t b) {\n    return __addsf3(a, fromRep(toRep(b) ^ signBit));\n}\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/subtf3.c",
    "content": "//===-- lib/subtf3.c - Quad-precision subtraction -----------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements quad-precision soft-float subtraction with the\n// IEEE-754 default rounding (to nearest, ties to even).\n//\n//===----------------------------------------------------------------------===//\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\nCOMPILER_RT_ABI fp_t __addtf3(fp_t a, fp_t b);\n\n// Subtraction; flip the sign bit of b and add.\nCOMPILER_RT_ABI fp_t\n__subtf3(fp_t a, fp_t b) {\n    return __addtf3(a, fromRep(toRep(b) ^ signBit));\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/subvdi3.c",
    "content": "/* ===-- subvdi3.c - Implement __subvdi3 -----------------------------------===\n *\n *                The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __subvdi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a - b */\n\n/* Effects: aborts if a - b overflows */\n\nCOMPILER_RT_ABI di_int\n__subvdi3(di_int a, di_int b)\n{\n    di_int s = (du_int) a - (du_int) b;\n    if (b >= 0)\n    {\n        if (s > a)\n            compilerrt_abort();\n    }\n    else\n    {\n        if (s <= a)\n            compilerrt_abort();\n    }\n    return s;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/subvsi3.c",
    "content": "/* ===-- subvsi3.c - Implement __subvsi3 -----------------------------------===\n *\n *                The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __subvsi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a - b */\n\n/* Effects: aborts if a - b overflows */\n\nCOMPILER_RT_ABI si_int\n__subvsi3(si_int a, si_int b)\n{\n    si_int s = (su_int) a - (su_int) b;\n    if (b >= 0)\n    {\n        if (s > a)\n            compilerrt_abort();\n    }\n    else\n    {\n        if (s <= a)\n            compilerrt_abort();\n    }\n    return s;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/subvti3.c",
    "content": "/* ===-- subvti3.c - Implement __subvti3 -----------------------------------===\n *\n *      \t       The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __subvti3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: a - b */\n\n/* Effects: aborts if a - b overflows */\n\nCOMPILER_RT_ABI ti_int\n__subvti3(ti_int a, ti_int b)\n{\n    ti_int s = (tu_int) a - (tu_int) b;\n    if (b >= 0)\n    {\n        if (s > a)\n            compilerrt_abort();\n    }\n    else\n    {\n        if (s <= a)\n            compilerrt_abort();\n    }\n    return s;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/trampoline_setup.c",
    "content": "/* ===----- trampoline_setup.c - Implement __trampoline_setup -------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\nextern void __clear_cache(void* start, void* end);\n\n/*\n * The ppc compiler generates calls to __trampoline_setup() when creating \n * trampoline functions on the stack for use with nested functions.\n * This function creates a custom 40-byte trampoline function on the stack \n * which loads r11 with a pointer to the outer function's locals\n * and then jumps to the target nested function.\n */\n\n#if __ppc__ && !defined(__powerpc64__)\nCOMPILER_RT_ABI void\n__trampoline_setup(uint32_t* trampOnStack, int trampSizeAllocated, \n                   const void* realFunc, void* localsPtr)\n{\n    /* should never happen, but if compiler did not allocate */\n    /* enough space on stack for the trampoline, abort */\n    if ( trampSizeAllocated < 40 )\n        compilerrt_abort();\n    \n    /* create trampoline */\n    trampOnStack[0] = 0x7c0802a6;    /* mflr r0 */\n    trampOnStack[1] = 0x4800000d;    /* bl Lbase */\n    trampOnStack[2] = (uint32_t)realFunc;\n    trampOnStack[3] = (uint32_t)localsPtr;\n    trampOnStack[4] = 0x7d6802a6;    /* Lbase: mflr r11 */\n    trampOnStack[5] = 0x818b0000;    /* lwz    r12,0(r11) */\n    trampOnStack[6] = 0x7c0803a6;    /* mtlr r0 */\n    trampOnStack[7] = 0x7d8903a6;    /* mtctr r12 */\n    trampOnStack[8] = 0x816b0004;    /* lwz    r11,4(r11) */\n    trampOnStack[9] = 0x4e800420;    /* bctr */\n    \n    /* clear instruction cache */\n    __clear_cache(trampOnStack, &trampOnStack[10]);\n}\n#endif /* __ppc__ && !defined(__powerpc64__) */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/truncdfhf2.c",
    "content": "//===-- lib/truncdfhf2.c - double -> half conversion --------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define SRC_DOUBLE\n#define DST_HALF\n#include \"fp_trunc_impl.inc\"\n\nARM_EABI_FNALIAS(d2h, truncdfhf2)\n\nCOMPILER_RT_ABI uint16_t __truncdfhf2(double a) {\n    return __truncXfYf2__(a);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/truncdfsf2.c",
    "content": "//===-- lib/truncdfsf2.c - double -> single conversion ------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define SRC_DOUBLE\n#define DST_SINGLE\n#include \"fp_trunc_impl.inc\"\n\nARM_EABI_FNALIAS(d2f, truncdfsf2)\n\nCOMPILER_RT_ABI float __truncdfsf2(double a) {\n    return __truncXfYf2__(a);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/truncsfhf2.c",
    "content": "//===-- lib/truncsfhf2.c - single -> half conversion --------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define SRC_SINGLE\n#define DST_HALF\n#include \"fp_trunc_impl.inc\"\n\nARM_EABI_FNALIAS(f2h, truncsfhf2)\n\n// Use a forwarding definition and noinline to implement a poor man's alias,\n// as there isn't a good cross-platform way of defining one.\nCOMPILER_RT_ABI NOINLINE uint16_t __truncsfhf2(float a) {\n    return __truncXfYf2__(a);\n}\n\nCOMPILER_RT_ABI uint16_t __gnu_f2h_ieee(float a) {\n    return __truncsfhf2(a);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/trunctfdf2.c",
    "content": "//===-- lib/truncdfsf2.c - quad -> double conversion --------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\n#define SRC_QUAD\n#define DST_DOUBLE\n#include \"fp_trunc_impl.inc\"\n\nCOMPILER_RT_ABI double __trunctfdf2(long double a) {\n    return __truncXfYf2__(a);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/trunctfsf2.c",
    "content": "//===-- lib/trunctfsf2.c - quad -> single conversion --------------*- C -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define QUAD_PRECISION\n#include \"fp_lib.h\"\n\n#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)\n#define SRC_QUAD\n#define DST_SINGLE\n#include \"fp_trunc_impl.inc\"\n\nCOMPILER_RT_ABI float __trunctfsf2(long double a) {\n    return __truncXfYf2__(a);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ucmpdi2.c",
    "content": "/* ===-- ucmpdi2.c - Implement __ucmpdi2 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __ucmpdi2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns:  if (a <  b) returns 0\n *           if (a == b) returns 1\n *           if (a >  b) returns 2\n */\n\nCOMPILER_RT_ABI si_int\n__ucmpdi2(du_int a, du_int b)\n{\n    udwords x;\n    x.all = a;\n    udwords y;\n    y.all = b;\n    if (x.s.high < y.s.high)\n        return 0;\n    if (x.s.high > y.s.high)\n        return 2;\n    if (x.s.low < y.s.low)\n        return 0;\n    if (x.s.low > y.s.low)\n        return 2;\n    return 1;\n}\n\n#ifdef __ARM_EABI__\n/* Returns: if (a <  b) returns -1\n*           if (a == b) returns  0\n*           if (a >  b) returns  1\n*/\nCOMPILER_RT_ABI si_int\n__aeabi_ulcmp(di_int a, di_int b)\n{\n\treturn __ucmpdi2(a, b) - 1;\n}\n#endif\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/ucmpti2.c",
    "content": "/* ===-- ucmpti2.c - Implement __ucmpti2 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __ucmpti2 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns:  if (a <  b) returns 0\n *           if (a == b) returns 1\n *           if (a >  b) returns 2\n */\n\nCOMPILER_RT_ABI si_int\n__ucmpti2(tu_int a, tu_int b)\n{\n    utwords x;\n    x.all = a;\n    utwords y;\n    y.all = b;\n    if (x.s.high < y.s.high)\n        return 0;\n    if (x.s.high > y.s.high)\n        return 2;\n    if (x.s.low < y.s.low)\n        return 0;\n    if (x.s.low > y.s.low)\n        return 2;\n    return 1;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/udivdi3.c",
    "content": "/* ===-- udivdi3.c - Implement __udivdi3 -----------------------------------===\n *\n *                    The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __udivdi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a / b */\n\nCOMPILER_RT_ABI du_int\n__udivdi3(du_int a, du_int b)\n{\n    return __udivmoddi4(a, b, 0);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/udivmoddi4.c",
    "content": "/* ===-- udivmoddi4.c - Implement __udivmoddi4 -----------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __udivmoddi4 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Effects: if rem != 0, *rem = a % b\n * Returns: a / b\n */\n\n/* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */\n\nCOMPILER_RT_ABI du_int\n__udivmoddi4(du_int a, du_int b, du_int* rem)\n{\n    const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT;\n    const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT;\n    udwords n;\n    n.all = a;\n    udwords d;\n    d.all = b;\n    udwords q;\n    udwords r;\n    unsigned sr;\n    /* special cases, X is unknown, K != 0 */\n    if (n.s.high == 0)\n    {\n        if (d.s.high == 0)\n        {\n            /* 0 X\n             * ---\n             * 0 X\n             */\n            if (rem)\n                *rem = n.s.low % d.s.low;\n            return n.s.low / d.s.low;\n        }\n        /* 0 X\n         * ---\n         * K X\n         */\n        if (rem)\n            *rem = n.s.low;\n        return 0;\n    }\n    /* n.s.high != 0 */\n    if (d.s.low == 0)\n    {\n        if (d.s.high == 0)\n        {\n            /* K X\n             * ---\n             * 0 0\n             */ \n            if (rem)\n                *rem = n.s.high % d.s.low;\n            return n.s.high / d.s.low;\n        }\n        /* d.s.high != 0 */\n        if (n.s.low == 0)\n        {\n            /* K 0\n             * ---\n             * K 0\n             */\n            if (rem)\n            {\n                r.s.high = n.s.high % d.s.high;\n                r.s.low = 0;\n                *rem = r.all;\n            }\n            return n.s.high / d.s.high;\n        }\n        /* K K\n         * ---\n         * K 0\n         */\n        if ((d.s.high & (d.s.high - 1)) == 0)     /* if d is a power of 2 */\n        {\n            if (rem)\n            {\n                r.s.low = n.s.low;\n                r.s.high = n.s.high & (d.s.high - 1);\n                *rem = r.all;\n            }\n            return n.s.high >> __builtin_ctz(d.s.high);\n        }\n        /* K K\n         * ---\n         * K 0\n         */\n        sr = __builtin_clz(d.s.high) - __builtin_clz(n.s.high);\n        /* 0 <= sr <= n_uword_bits - 2 or sr large */\n        if (sr > n_uword_bits - 2)\n        {\n           if (rem)\n                *rem = n.all;\n            return 0;\n        }\n        ++sr;\n        /* 1 <= sr <= n_uword_bits - 1 */\n        /* q.all = n.all << (n_udword_bits - sr); */\n        q.s.low = 0;\n        q.s.high = n.s.low << (n_uword_bits - sr);\n        /* r.all = n.all >> sr; */\n        r.s.high = n.s.high >> sr;\n        r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);\n    }\n    else  /* d.s.low != 0 */\n    {\n        if (d.s.high == 0)\n        {\n            /* K X\n             * ---\n             * 0 K\n             */\n            if ((d.s.low & (d.s.low - 1)) == 0)     /* if d is a power of 2 */\n            {\n                if (rem)\n                    *rem = n.s.low & (d.s.low - 1);\n                if (d.s.low == 1)\n                    return n.all;\n                sr = __builtin_ctz(d.s.low);\n                q.s.high = n.s.high >> sr;\n                q.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);\n                return q.all;\n            }\n            /* K X\n             * ---\n             * 0 K\n             */\n            sr = 1 + n_uword_bits + __builtin_clz(d.s.low) - __builtin_clz(n.s.high);\n            /* 2 <= sr <= n_udword_bits - 1\n             * q.all = n.all << (n_udword_bits - sr);\n             * r.all = n.all >> sr;\n             */\n            if (sr == n_uword_bits)\n            {\n                q.s.low = 0;\n                q.s.high = n.s.low;\n                r.s.high = 0;\n                r.s.low = n.s.high;\n            }\n            else if (sr < n_uword_bits)  // 2 <= sr <= n_uword_bits - 1\n            {\n                q.s.low = 0;\n                q.s.high = n.s.low << (n_uword_bits - sr);\n                r.s.high = n.s.high >> sr;\n                r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);\n            }\n            else              // n_uword_bits + 1 <= sr <= n_udword_bits - 1\n            {\n                q.s.low = n.s.low << (n_udword_bits - sr);\n                q.s.high = (n.s.high << (n_udword_bits - sr)) |\n                           (n.s.low >> (sr - n_uword_bits));\n                r.s.high = 0;\n                r.s.low = n.s.high >> (sr - n_uword_bits);\n            }\n        }\n        else\n        {\n            /* K X\n             * ---\n             * K K\n             */\n            sr = __builtin_clz(d.s.high) - __builtin_clz(n.s.high);\n            /* 0 <= sr <= n_uword_bits - 1 or sr large */\n            if (sr > n_uword_bits - 1)\n            {\n                if (rem)\n                    *rem = n.all;\n                return 0;\n            }\n            ++sr;\n            /* 1 <= sr <= n_uword_bits */\n            /*  q.all = n.all << (n_udword_bits - sr); */\n            q.s.low = 0;\n            if (sr == n_uword_bits)\n            {\n                q.s.high = n.s.low;\n                r.s.high = 0;\n                r.s.low = n.s.high;\n            }\n            else\n            {\n                q.s.high = n.s.low << (n_uword_bits - sr);\n                r.s.high = n.s.high >> sr;\n                r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);\n            }\n        }\n    }\n    /* Not a special case\n     * q and r are initialized with:\n     * q.all = n.all << (n_udword_bits - sr);\n     * r.all = n.all >> sr;\n     * 1 <= sr <= n_udword_bits - 1\n     */\n    su_int carry = 0;\n    for (; sr > 0; --sr)\n    {\n        /* r:q = ((r:q)  << 1) | carry */\n        r.s.high = (r.s.high << 1) | (r.s.low  >> (n_uword_bits - 1));\n        r.s.low  = (r.s.low  << 1) | (q.s.high >> (n_uword_bits - 1));\n        q.s.high = (q.s.high << 1) | (q.s.low  >> (n_uword_bits - 1));\n        q.s.low  = (q.s.low  << 1) | carry;\n        /* carry = 0;\n         * if (r.all >= d.all)\n         * {\n         *      r.all -= d.all;\n         *      carry = 1;\n         * }\n         */\n        const di_int s = (di_int)(d.all - r.all - 1) >> (n_udword_bits - 1);\n        carry = s & 1;\n        r.all -= d.all & s;\n    }\n    q.all = (q.all << 1) | carry;\n    if (rem)\n        *rem = r.all;\n    return q.all;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/udivmodsi4.c",
    "content": "/*===-- udivmodsi4.c - Implement __udivmodsi4 ------------------------------===\n *\n *                    The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __udivmodsi4 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a / b, *rem = a % b  */\n\nCOMPILER_RT_ABI su_int\n__udivmodsi4(su_int a, su_int b, su_int* rem)\n{\n  si_int d = __udivsi3(a,b);\n  *rem = a - (d*b);\n  return d;\n}\n\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/udivmodti4.c",
    "content": "/* ===-- udivmodti4.c - Implement __udivmodti4 -----------------------------===\n *\n *                    The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __udivmodti4 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */ \n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Effects: if rem != 0, *rem = a % b \n * Returns: a / b \n */\n\n/* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */\n\nCOMPILER_RT_ABI tu_int\n__udivmodti4(tu_int a, tu_int b, tu_int* rem)\n{\n    const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT;\n    const unsigned n_utword_bits = sizeof(tu_int) * CHAR_BIT;\n    utwords n;\n    n.all = a;\n    utwords d;\n    d.all = b;\n    utwords q;\n    utwords r;\n    unsigned sr;\n    /* special cases, X is unknown, K != 0 */\n    if (n.s.high == 0)\n    {\n        if (d.s.high == 0)\n        {\n            /* 0 X\n             * ---\n             * 0 X\n             */\n            if (rem)\n                *rem = n.s.low % d.s.low;\n            return n.s.low / d.s.low;\n        }\n        /* 0 X\n         * ---\n         * K X\n         */\n        if (rem)\n            *rem = n.s.low;\n        return 0;\n    }\n    /* n.s.high != 0 */\n    if (d.s.low == 0)\n    {\n        if (d.s.high == 0)\n        {\n            /* K X\n             * ---\n             * 0 0\n             */\n            if (rem)\n                *rem = n.s.high % d.s.low;\n            return n.s.high / d.s.low;\n        }\n        /* d.s.high != 0 */\n        if (n.s.low == 0)\n        {\n            /* K 0\n             * ---\n             * K 0\n             */\n            if (rem)\n            {\n                r.s.high = n.s.high % d.s.high;\n                r.s.low = 0;\n                *rem = r.all;\n            }\n            return n.s.high / d.s.high;\n        }\n        /* K K\n         * ---\n         * K 0\n         */\n        if ((d.s.high & (d.s.high - 1)) == 0)     /* if d is a power of 2 */\n        {\n            if (rem)\n            {\n                r.s.low = n.s.low;\n                r.s.high = n.s.high & (d.s.high - 1);\n                *rem = r.all;\n            }\n            return n.s.high >> __builtin_ctzll(d.s.high);\n        }\n        /* K K\n         * ---\n         * K 0\n         */\n        sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);\n        /* 0 <= sr <= n_udword_bits - 2 or sr large */\n        if (sr > n_udword_bits - 2)\n        {\n           if (rem)\n                *rem = n.all;\n            return 0;\n        }\n        ++sr;\n        /* 1 <= sr <= n_udword_bits - 1 */\n        /* q.all = n.all << (n_utword_bits - sr); */\n        q.s.low = 0;\n        q.s.high = n.s.low << (n_udword_bits - sr);\n        /* r.all = n.all >> sr; */\n        r.s.high = n.s.high >> sr;\n        r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);\n    }\n    else  /* d.s.low != 0 */\n    {\n        if (d.s.high == 0)\n        {\n            /* K X\n             * ---\n             * 0 K\n             */\n            if ((d.s.low & (d.s.low - 1)) == 0)     /* if d is a power of 2 */\n            {\n                if (rem)\n                    *rem = n.s.low & (d.s.low - 1);\n                if (d.s.low == 1)\n                    return n.all;\n                sr = __builtin_ctzll(d.s.low);\n                q.s.high = n.s.high >> sr;\n                q.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);\n                return q.all;\n            }\n            /* K X\n             * ---\n             * 0 K\n             */\n            sr = 1 + n_udword_bits + __builtin_clzll(d.s.low)\n                                   - __builtin_clzll(n.s.high);\n            /* 2 <= sr <= n_utword_bits - 1\n             * q.all = n.all << (n_utword_bits - sr);\n             * r.all = n.all >> sr;\n             */\n            if (sr == n_udword_bits)\n            {\n                q.s.low = 0;\n                q.s.high = n.s.low;\n                r.s.high = 0;\n                r.s.low = n.s.high;\n            }\n            else if (sr < n_udword_bits)  // 2 <= sr <= n_udword_bits - 1\n            {\n                q.s.low = 0;\n                q.s.high = n.s.low << (n_udword_bits - sr);\n                r.s.high = n.s.high >> sr;\n                r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);\n            }\n            else              // n_udword_bits + 1 <= sr <= n_utword_bits - 1\n            {\n                q.s.low = n.s.low << (n_utword_bits - sr);\n                q.s.high = (n.s.high << (n_utword_bits - sr)) |\n                           (n.s.low >> (sr - n_udword_bits));\n                r.s.high = 0;\n                r.s.low = n.s.high >> (sr - n_udword_bits);\n            }\n        }\n        else\n        {\n            /* K X\n             * ---\n             * K K\n             */\n            sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);\n            /*0 <= sr <= n_udword_bits - 1 or sr large */\n            if (sr > n_udword_bits - 1)\n            {\n               if (rem)\n                    *rem = n.all;\n                return 0;\n            }\n            ++sr;\n            /* 1 <= sr <= n_udword_bits\n             * q.all = n.all << (n_utword_bits - sr);\n             * r.all = n.all >> sr;\n             */\n            q.s.low = 0;\n            if (sr == n_udword_bits)\n            {\n                q.s.high = n.s.low;\n                r.s.high = 0;\n                r.s.low = n.s.high;\n            }\n            else\n            {\n                r.s.high = n.s.high >> sr;\n                r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);\n                q.s.high = n.s.low << (n_udword_bits - sr);\n            }\n        }\n    }\n    /* Not a special case\n     * q and r are initialized with:\n     * q.all = n.all << (n_utword_bits - sr);\n     * r.all = n.all >> sr;\n     * 1 <= sr <= n_utword_bits - 1\n     */\n    su_int carry = 0;\n    for (; sr > 0; --sr)\n    {\n        /* r:q = ((r:q)  << 1) | carry */\n        r.s.high = (r.s.high << 1) | (r.s.low  >> (n_udword_bits - 1));\n        r.s.low  = (r.s.low  << 1) | (q.s.high >> (n_udword_bits - 1));\n        q.s.high = (q.s.high << 1) | (q.s.low  >> (n_udword_bits - 1));\n        q.s.low  = (q.s.low  << 1) | carry;\n        /* carry = 0;\n         * if (r.all >= d.all)\n         * {\n         *     r.all -= d.all;\n         *      carry = 1;\n         * }\n         */\n        const ti_int s = (ti_int)(d.all - r.all - 1) >> (n_utword_bits - 1);\n        carry = s & 1;\n        r.all -= d.all & s;\n    }\n    q.all = (q.all << 1) | carry;\n    if (rem)\n        *rem = r.all;\n    return q.all;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/udivsi3.c",
    "content": "/* ===-- udivsi3.c - Implement __udivsi3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __udivsi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a / b */\n\n/* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */\n\nARM_EABI_FNALIAS(uidiv, udivsi3)\n\n/* This function should not call __divsi3! */\nCOMPILER_RT_ABI su_int\n__udivsi3(su_int n, su_int d)\n{\n    const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT;\n    su_int q;\n    su_int r;\n    unsigned sr;\n    /* special cases */\n    if (d == 0)\n        return 0; /* ?! */\n    if (n == 0)\n        return 0;\n    sr = __builtin_clz(d) - __builtin_clz(n);\n    /* 0 <= sr <= n_uword_bits - 1 or sr large */\n    if (sr > n_uword_bits - 1)  /* d > r */\n        return 0;\n    if (sr == n_uword_bits - 1)  /* d == 1 */\n        return n;\n    ++sr;\n    /* 1 <= sr <= n_uword_bits - 1 */\n    /* Not a special case */\n    q = n << (n_uword_bits - sr);\n    r = n >> sr;\n    su_int carry = 0;\n    for (; sr > 0; --sr)\n    {\n        /* r:q = ((r:q)  << 1) | carry */\n        r = (r << 1) | (q >> (n_uword_bits - 1));\n        q = (q << 1) | carry;\n        /* carry = 0;\n         * if (r.all >= d.all)\n         * {\n         *      r.all -= d.all;\n         *      carry = 1;\n         * }\n         */\n        const si_int s = (si_int)(d - r - 1) >> (n_uword_bits - 1);\n        carry = s & 1;\n        r -= d & s;\n    }\n    q = (q << 1) | carry;\n    return q;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/udivti3.c",
    "content": "/* ===-- udivti3.c - Implement __udivti3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __udivti3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: a / b */\n\nCOMPILER_RT_ABI tu_int\n__udivti3(tu_int a, tu_int b)\n{\n    return __udivmodti4(a, b, 0);\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/umoddi3.c",
    "content": "/* ===-- umoddi3.c - Implement __umoddi3 -----------------------------------===\n *\n *                    The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __umoddi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a % b */\n\nCOMPILER_RT_ABI du_int\n__umoddi3(du_int a, du_int b)\n{\n    du_int r;\n    __udivmoddi4(a, b, &r);\n    return r;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/umodsi3.c",
    "content": "/* ===-- umodsi3.c - Implement __umodsi3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __umodsi3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n/* Returns: a % b */\n\nCOMPILER_RT_ABI su_int\n__umodsi3(su_int a, su_int b)\n{\n    return a - __udivsi3(a, b) * b;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/umodti3.c",
    "content": "/* ===-- umodti3.c - Implement __umodti3 -----------------------------------===\n *\n *                     The LLVM Compiler Infrastructure\n *\n * This file is dual licensed under the MIT and the University of Illinois Open\n * Source Licenses. See LICENSE.TXT for details.\n *\n * ===----------------------------------------------------------------------===\n *\n * This file implements __umodti3 for the compiler_rt library.\n *\n * ===----------------------------------------------------------------------===\n */\n\n#include \"int_lib.h\"\n\n#ifdef CRT_HAS_128BIT\n\n/* Returns: a % b */\n\nCOMPILER_RT_ABI tu_int\n__umodti3(tu_int a, tu_int b)\n{\n    tu_int r;\n    __udivmodti4(a, b, &r);\n    return r;\n}\n\n#endif /* CRT_HAS_128BIT */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/x86_64/Makefile.mk",
    "content": "#===- lib/builtins/x86_64/Makefile.mk ----------------------*- Makefile -*--===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\nModuleName := builtins\nSubDirs := \nOnlyArchs := x86_64 x86_64h\n\nAsmSources := $(foreach file,$(wildcard $(Dir)/*.S),$(notdir $(file)))\nSources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))\nObjNames := $(Sources:%.c=%.o) $(AsmSources:%.S=%.o)\nImplementation := Optimized\n\n# FIXME: use automatic dependencies?\nDependencies := $(wildcard lib/*.h $(Dir)/*.h)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/x86_64/chkstk.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// _chkstk routine\n// This routine is windows specific\n// http://msdn.microsoft.com/en-us/library/ms648426.aspx\n\n// Notes from r227519\n// MSVC x64s __chkstk and cygmings ___chkstk_ms do not adjust %rsp\n// themselves. It also does not clobber %rax so we can reuse it when\n// adjusting %rsp.\n\n#ifdef __x86_64__\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(___chkstk_ms)\n        push   %rcx\n        push   %rax\n        cmp    $0x1000,%rax\n        lea    24(%rsp),%rcx\n        jb     1f\n2:\n        sub    $0x1000,%rcx\n        test   %rcx,(%rcx)\n        sub    $0x1000,%rax\n        cmp    $0x1000,%rax\n        ja     2b\n1:\n        sub    %rax,%rcx\n        test   %rcx,(%rcx)\n        pop    %rax\n        pop    %rcx\n        ret\nEND_COMPILERRT_FUNCTION(___chkstk_ms)\n\n#endif // __x86_64__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/x86_64/chkstk2.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n#ifdef __x86_64__\n\n// _chkstk (_alloca) routine - probe stack between %rsp and (%rsp-%rax) in 4k increments,\n// then decrement %rsp by %rax.  Preserves all registers except %rsp and flags.\n// This routine is windows specific\n// http://msdn.microsoft.com/en-us/library/ms648426.aspx\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__alloca)\n        mov    %rcx,%rax        // x64 _alloca is a normal function with parameter in rcx\n        // fallthrough\nDEFINE_COMPILERRT_FUNCTION(___chkstk)\n        push   %rcx\n        cmp    $0x1000,%rax\n        lea    16(%rsp),%rcx     // rsp before calling this routine -> rcx\n        jb     1f\n2:\n        sub    $0x1000,%rcx\n        test   %rcx,(%rcx)\n        sub    $0x1000,%rax\n        cmp    $0x1000,%rax\n        ja     2b\n1:\n        sub    %rax,%rcx\n        test   %rcx,(%rcx)\n\n        lea    8(%rsp),%rax     // load pointer to the return address into rax\n        mov    %rcx,%rsp        // install the new top of stack pointer into rsp\n        mov    -8(%rax),%rcx    // restore rcx\n        push   (%rax)           // push return address onto the stack\n        sub    %rsp,%rax        // restore the original value in rax\n        ret\nEND_COMPILERRT_FUNCTION(___chkstk)\nEND_COMPILERRT_FUNCTION(__alloca)\n\n#endif // __x86_64__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/x86_64/floatdidf.c",
    "content": "/* This file is distributed under the University of Illinois Open Source\n * License. See LICENSE.TXT for details.\n */\n\n/* double __floatdidf(di_int a); */\n\n#ifdef __x86_64__\n\n#include \"../int_lib.h\"\n\ndouble __floatdidf(int64_t a)\n{\n\treturn (double)a;\n}\n\n#endif /* __x86_64__ */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/x86_64/floatdisf.c",
    "content": "/* This file is distributed under the University of Illinois Open Source\n * License. See LICENSE.TXT for details.\n */\n\n#ifdef __x86_64__\n\n#include \"../int_lib.h\"\n\nfloat __floatdisf(int64_t a)\n{\n\treturn (float)a;\n}\n\n#endif /* __x86_64__ */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/x86_64/floatdixf.c",
    "content": "/* This file is distributed under the University of Illinois Open Source\n * License. See LICENSE.TXT for details.\n */\n\n/* long double __floatdixf(di_int a); */\n\n#ifdef __x86_64__\n\n#include \"../int_lib.h\"\n\nlong double __floatdixf(int64_t a)\n{\n\treturn (long double)a;\n}\n\n#endif /* __i386__ */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/x86_64/floatundidf.S",
    "content": "//===-- floatundidf.S - Implement __floatundidf for x86_64 ----------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements __floatundidf for the compiler_rt library.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"../assembly.h\"\n\n// double __floatundidf(du_int a);\n\n#ifdef __x86_64__\n\nCONST_SECTION\n\n\t.balign 16\ntwop52:\n\t.quad 0x4330000000000000\n\n\t.balign 16\ntwop84_plus_twop52:\n\t.quad 0x4530000000100000\n\n\t.balign 16\ntwop84:\n\t.quad 0x4530000000000000\n\n#define REL_ADDR(_a)\t(_a)(%rip)\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__floatundidf)\n\tmovd\t%edi,\t\t\t\t\t\t\t%xmm0 // low 32 bits of a\n\tshrq\t$32,\t\t\t\t\t\t\t%rdi  // high 32 bits of a\n\torq\t\tREL_ADDR(twop84),\t\t\t\t%rdi  // 0x1p84 + a_hi (no rounding occurs)\n\torpd\tREL_ADDR(twop52),\t\t\t\t%xmm0 // 0x1p52 + a_lo (no rounding occurs)\n\tmovd\t%rdi,\t\t\t\t\t\t\t%xmm1\n\tsubsd\tREL_ADDR(twop84_plus_twop52),\t%xmm1 // a_hi - 0x1p52 (no rounding occurs)\n\taddsd\t%xmm1,\t\t\t\t\t\t\t%xmm0 // a_hi + a_lo   (round happens here)\n\tret\nEND_COMPILERRT_FUNCTION(__floatundidf)\n\n#endif // __x86_64__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/x86_64/floatundisf.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// float __floatundisf(du_int a);\n\n#ifdef __x86_64__\n\nCONST_SECTION\n\n\t.balign 16\ntwo:\n\t.single 2.0\n\n#define REL_ADDR(_a)\t(_a)(%rip)\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__floatundisf)\n\tmovq\t\t$1,\t\t\t%rsi\n\ttestq\t\t%rdi,\t\t%rdi\n\tjs\t\t\t1f\n\tcvtsi2ssq\t%rdi,\t\t%xmm0\n\tret\n\t\n1:\tandq\t\t%rdi,\t\t%rsi\n\tshrq\t\t%rdi\n\torq\t\t\t%rsi,\t\t%rdi\n\tcvtsi2ssq\t%rdi,\t\t%xmm0\n\tmulss\tREL_ADDR(two),\t%xmm0\n\tret\nEND_COMPILERRT_FUNCTION(__floatundisf)\n\n#endif // __x86_64__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/builtins/x86_64/floatundixf.S",
    "content": "// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n\n#include \"../assembly.h\"\n\n// long double __floatundixf(du_int a);\n\n#ifdef __x86_64__\n\nCONST_SECTION\n\n\t.balign 16\ntwop64:\n\t.quad 0x43f0000000000000\n\n#define REL_ADDR(_a)\t(_a)(%rip)\n\n\t.text\n\n\t.balign 4\nDEFINE_COMPILERRT_FUNCTION(__floatundixf)\n\tmovq\t%rdi,\t -8(%rsp)\n\tfildq\t-8(%rsp)\n\ttest\t%rdi,\t\t%rdi\n\tjs\t\t1f\n\tret\n1:\tfaddl\tREL_ADDR(twop64)\n\tret\nEND_COMPILERRT_FUNCTION(__floatundixf)\n\n#endif // __x86_64__\n\n\n/* Branch-free implementation is ever so slightly slower, but more beautiful.\n   It is likely superior for inlining, so I kept it around for future reference.\n\n#ifdef __x86_64__\n\nCONST_SECTION\n\n\t.balign 4\ntwop52:\n\t.quad 0x4330000000000000\ntwop84_plus_twop52_neg:\n\t.quad 0xc530000000100000\ntwop84:\n\t.quad 0x4530000000000000\n\n#define REL_ADDR(_a)\t(_a)(%rip)\n\n.text\n.balign 4\nDEFINE_COMPILERRT_FUNCTION(__floatundixf)\n\tmovl\t%edi,\t\t\t\t%esi\t\t\t// low 32 bits of input\n\tshrq\t$32,\t\t\t\t%rdi\t\t\t// hi 32 bits of input\n\torq\t\tREL_ADDR(twop84),\t%rdi\t\t\t// 2^84 + hi (as a double)\n\torq\t\tREL_ADDR(twop52),\t%rsi\t\t\t// 2^52 + lo (as a double)\n\tmovq\t%rdi,\t\t\t -8(%rsp)\n\tmovq\t%rsi,\t\t\t-16(%rsp)\n\tfldl\tREL_ADDR(twop84_plus_twop52_neg)\t\n\tfaddl\t-8(%rsp)\t// hi - 2^52 (as double extended, no rounding occurs)\n\tfaddl\t-16(%rsp)\t// hi + lo (as double extended)\n\tret\nEND_COMPILERRT_FUNCTION(__floatundixf)\n\n#endif // __x86_64__\n\n*/\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/cfi/CMakeLists.txt",
    "content": "add_custom_target(cfi)\n\nset(CFI_SOURCES cfi.cc)\n\ninclude_directories(..)\n\nset(CFI_CFLAGS\n  ${SANITIZER_COMMON_CFLAGS}\n)\n\nset(CFI_DIAG_CFLAGS\n  -DCFI_ENABLE_DIAG=1\n)\n\nforeach(arch ${CFI_SUPPORTED_ARCH})\n  add_compiler_rt_runtime(clang_rt.cfi\n    STATIC\n    ARCHS ${arch}\n    SOURCES ${CFI_SOURCES}\n    OBJECT_LIBS RTInterception\n                RTSanitizerCommon\n                RTSanitizerCommonLibc\n    CFLAGS ${CFI_CFLAGS}\n    PARENT_TARGET cfi)\n  add_compiler_rt_runtime(clang_rt.cfi_diag\n    STATIC\n    ARCHS ${arch}\n    SOURCES ${CFI_SOURCES}\n    OBJECT_LIBS RTInterception\n                RTSanitizerCommon\n                RTSanitizerCommonLibc\n\t\tRTUbsan\n\t\tRTUbsan_cxx\n    CFLAGS ${CFI_CFLAGS} ${CFI_DIAG_CFLAGS}\n    PARENT_TARGET cfi)\nendforeach()\n\nadd_compiler_rt_resource_file(cfi_blacklist cfi_blacklist.txt)\nadd_dependencies(cfi cfi_blacklist)\nadd_dependencies(compiler-rt cfi)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/cfi/cfi.cc",
    "content": "//===-------- cfi.cc ------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements the runtime support for the cross-DSO CFI.\n//\n//===----------------------------------------------------------------------===//\n\n// FIXME: Intercept dlopen/dlclose.\n// FIXME: Support diagnostic mode.\n// FIXME: Harden:\n//  * mprotect shadow, use mremap for updates\n//  * something else equally important\n\n#include <assert.h>\n#include <elf.h>\n#include <link.h>\n#include <string.h>\n\ntypedef ElfW(Phdr) Elf_Phdr;\ntypedef ElfW(Ehdr) Elf_Ehdr;\n\n#include \"interception/interception.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_flag_parser.h\"\n#include \"ubsan/ubsan_init.h\"\n#include \"ubsan/ubsan_flags.h\"\n\nstatic uptr __cfi_shadow;\nstatic constexpr uptr kShadowGranularity = 12;\nstatic constexpr uptr kShadowAlign = 1UL << kShadowGranularity; // 4096\n\nstatic constexpr uint16_t kInvalidShadow = 0;\nstatic constexpr uint16_t kUncheckedShadow = 0xFFFFU;\n\nstatic uint16_t *mem_to_shadow(uptr x) {\n  return (uint16_t *)(__cfi_shadow + ((x >> kShadowGranularity) << 1));\n}\n\ntypedef int (*CFICheckFn)(uptr, void *);\n\nclass ShadowValue {\n  uptr addr;\n  uint16_t v;\n  explicit ShadowValue(uptr addr, uint16_t v) : addr(addr), v(v) {}\n\npublic:\n  bool is_invalid() const { return v == kInvalidShadow; }\n\n  bool is_unchecked() const { return v == kUncheckedShadow; }\n\n  CFICheckFn get_cfi_check() const {\n    assert(!is_invalid() && !is_unchecked());\n    uptr aligned_addr = addr & ~(kShadowAlign - 1);\n    uptr p = aligned_addr - (((uptr)v - 1) << kShadowGranularity);\n    return reinterpret_cast<CFICheckFn>(p);\n  }\n\n  // Load a shadow valud for the given application memory address.\n  static const ShadowValue load(uptr addr) {\n    return ShadowValue(addr, *mem_to_shadow(addr));\n  }\n};\n\nstatic void fill_shadow_constant(uptr begin, uptr end, uint16_t v) {\n  assert(v == kInvalidShadow || v == kUncheckedShadow);\n  uint16_t *shadow_begin = mem_to_shadow(begin);\n  uint16_t *shadow_end = mem_to_shadow(end - 1) + 1;\n  memset(shadow_begin, v, (shadow_end - shadow_begin) * sizeof(*shadow_begin));\n}\n\nstatic void fill_shadow(uptr begin, uptr end, uptr cfi_check) {\n  assert((cfi_check & (kShadowAlign - 1)) == 0);\n\n  // Don't fill anything below cfi_check. We can not represent those addresses\n  // in the shadow, and must make sure at codegen to place all valid call\n  // targets above cfi_check.\n  uptr p = Max(begin, cfi_check);\n  uint16_t *s = mem_to_shadow(p);\n  uint16_t *s_end = mem_to_shadow(end - 1) + 1;\n  uint16_t sv = ((p - cfi_check) >> kShadowGranularity) + 1;\n  for (; s < s_end; s++, sv++)\n    *s = sv;\n\n  // Sanity checks.\n  uptr q = p & ~(kShadowAlign - 1);\n  for (; q < end; q += kShadowAlign) {\n    assert((uptr)ShadowValue::load(q).get_cfi_check() == cfi_check);\n    assert((uptr)ShadowValue::load(q + kShadowAlign / 2).get_cfi_check() ==\n           cfi_check);\n    assert((uptr)ShadowValue::load(q + kShadowAlign - 1).get_cfi_check() ==\n           cfi_check);\n  }\n}\n\n// This is a workaround for a glibc bug:\n// https://sourceware.org/bugzilla/show_bug.cgi?id=15199\n// Other platforms can, hopefully, just do\n//    dlopen(RTLD_NOLOAD | RTLD_LAZY)\n//    dlsym(\"__cfi_check\").\nstatic uptr find_cfi_check_in_dso(dl_phdr_info *info) {\n  const ElfW(Dyn) *dynamic = nullptr;\n  for (int i = 0; i < info->dlpi_phnum; ++i) {\n    if (info->dlpi_phdr[i].p_type == PT_DYNAMIC) {\n      dynamic =\n          (const ElfW(Dyn) *)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);\n      break;\n    }\n  }\n  if (!dynamic) return 0;\n  uptr strtab = 0, symtab = 0;\n  for (const ElfW(Dyn) *p = dynamic; p->d_tag != PT_NULL; ++p) {\n    if (p->d_tag == DT_SYMTAB)\n      symtab = p->d_un.d_ptr;\n    else if (p->d_tag == DT_STRTAB)\n      strtab = p->d_un.d_ptr;\n  }\n\n  if (symtab > strtab) {\n    VReport(1, \"Can not handle: symtab > strtab (%p > %zx)\\n\", symtab, strtab);\n    return 0;\n  }\n\n  // Verify that strtab and symtab are inside of the same LOAD segment.\n  // This excludes VDSO, which has (very high) bogus strtab and symtab pointers.\n  int phdr_idx;\n  for (phdr_idx = 0; phdr_idx < info->dlpi_phnum; phdr_idx++) {\n    const Elf_Phdr *phdr = &info->dlpi_phdr[phdr_idx];\n    if (phdr->p_type == PT_LOAD) {\n      uptr beg = info->dlpi_addr + phdr->p_vaddr;\n      uptr end = beg + phdr->p_memsz;\n      if (strtab >= beg && strtab < end && symtab >= beg && symtab < end)\n        break;\n    }\n  }\n  if (phdr_idx == info->dlpi_phnum) {\n    // Nope, either different segments or just bogus pointers.\n    // Can not handle this.\n    VReport(1, \"Can not handle: symtab %p, strtab %zx\\n\", symtab, strtab);\n    return 0;\n  }\n\n  for (const ElfW(Sym) *p = (const ElfW(Sym) *)symtab; (ElfW(Addr))p < strtab;\n       ++p) {\n    char *name = (char*)(strtab + p->st_name);\n    if (strcmp(name, \"__cfi_check\") == 0) {\n      assert(p->st_info == ELF32_ST_INFO(STB_GLOBAL, STT_FUNC));\n      uptr addr = info->dlpi_addr + p->st_value;\n      return addr;\n    }\n  }\n  return 0;\n}\n\nstatic int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *data) {\n  uptr cfi_check = find_cfi_check_in_dso(info);\n  if (cfi_check)\n    VReport(1, \"Module '%s' __cfi_check %zx\\n\", info->dlpi_name, cfi_check);\n\n  for (int i = 0; i < info->dlpi_phnum; i++) {\n    const Elf_Phdr *phdr = &info->dlpi_phdr[i];\n    if (phdr->p_type == PT_LOAD) {\n      // Jump tables are in the executable segment.\n      // VTables are in the non-executable one.\n      // Need to fill shadow for both.\n      // FIXME: reject writable if vtables are in the r/o segment. Depend on\n      // PT_RELRO?\n      uptr cur_beg = info->dlpi_addr + phdr->p_vaddr;\n      uptr cur_end = cur_beg + phdr->p_memsz;\n      if (cfi_check) {\n        VReport(1, \"   %zx .. %zx\\n\", cur_beg, cur_end);\n        fill_shadow(cur_beg, cur_end, cfi_check ? cfi_check : (uptr)(-1));\n      } else {\n        fill_shadow_constant(cur_beg, cur_end, kInvalidShadow);\n      }\n    }\n  }\n  return 0;\n}\n\n// Fill shadow for the initial libraries.\nstatic void init_shadow() {\n  dl_iterate_phdr(dl_iterate_phdr_cb, nullptr);\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nvoid __cfi_slowpath(uptr CallSiteTypeId, void *Ptr) {\n  uptr Addr = (uptr)Ptr;\n  VReport(3, \"__cfi_slowpath: %zx, %p\\n\", CallSiteTypeId, Ptr);\n  ShadowValue sv = ShadowValue::load(Addr);\n  if (sv.is_invalid()) {\n    VReport(2, \"CFI: invalid memory region for a function pointer (shadow==0): %p\\n\", Ptr);\n    Die();\n  }\n  if (sv.is_unchecked()) {\n    VReport(2, \"CFI: unchecked call (shadow=FFFF): %p\\n\", Ptr);\n    return;\n  }\n  CFICheckFn cfi_check = sv.get_cfi_check();\n  VReport(2, \"__cfi_check at %p\\n\", cfi_check);\n  cfi_check(CallSiteTypeId, Ptr);\n}\n\nstatic void InitializeFlags() {\n  SetCommonFlagsDefaults();\n#ifdef CFI_ENABLE_DIAG\n  __ubsan::Flags *uf = __ubsan::flags();\n  uf->SetDefaults();\n#endif\n\n  FlagParser cfi_parser;\n  RegisterCommonFlags(&cfi_parser);\n  cfi_parser.ParseString(GetEnv(\"CFI_OPTIONS\"));\n\n#ifdef CFI_ENABLE_DIAG\n  FlagParser ubsan_parser;\n  __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);\n  RegisterCommonFlags(&ubsan_parser);\n\n  const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();\n  ubsan_parser.ParseString(ubsan_default_options);\n  ubsan_parser.ParseString(GetEnv(\"UBSAN_OPTIONS\"));\n#endif\n\n  SetVerbosity(common_flags()->verbosity);\n\n  if (Verbosity()) ReportUnrecognizedFlags();\n\n  if (common_flags()->help) {\n    cfi_parser.PrintFlagDescriptions();\n  }\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\n#if !SANITIZER_CAN_USE_PREINIT_ARRAY\n// On ELF platforms, the constructor is invoked using .preinit_array (see below)\n__attribute__((constructor(0)))\n#endif\nvoid __cfi_init() {\n  SanitizerToolName = \"CFI\";\n  InitializeFlags();\n\n  uptr vma = GetMaxVirtualAddress();\n  // Shadow is 2 -> 2**kShadowGranularity.\n  uptr shadow_size = (vma >> (kShadowGranularity - 1)) + 1;\n  VReport(1, \"CFI: VMA size %zx, shadow size %zx\\n\", vma, shadow_size);\n  void *shadow = MmapNoReserveOrDie(shadow_size, \"CFI shadow\");\n  VReport(1, \"CFI: shadow at %zx .. %zx\\n\", shadow,\n          reinterpret_cast<uptr>(shadow) + shadow_size);\n  __cfi_shadow = (uptr)shadow;\n  init_shadow();\n\n#ifdef CFI_ENABLE_DIAG\n  __ubsan::InitAsPlugin();\n#endif\n}\n\n#if SANITIZER_CAN_USE_PREINIT_ARRAY\n// On ELF platforms, run cfi initialization before any other constructors.\n// On other platforms we use the constructor attribute to arrange to run our\n// initialization early.\nextern \"C\" {\n__attribute__((section(\".preinit_array\"),\n               used)) void (*__cfi_preinit)(void) = __cfi_init;\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/cfi/cfi_blacklist.txt",
    "content": "# Standard library types.\ntype:std::*\n\n# The stdext namespace contains Microsoft standard library extensions.\ntype:stdext::*\n\n# Types with a uuid attribute, i.e. COM types.\ntype:attr:uuid\n\n# STL allocators (T *allocator<T *>::allocate(size_type, const void*)).\n# The type signature mandates a cast from uninitialized void* to T*.\n# size_type can either be unsigned int (j) or unsigned long (m).\nfun:*8allocateEjPKv\nfun:*8allocateEmPKv\n\n# std::get_temporary_buffer, likewise (libstdc++, libc++).\nfun:_ZSt20get_temporary_buffer*\nfun:_ZNSt3__120get_temporary_buffer*\n\n# STL address-of magic (libstdc++, libc++).\nfun:*__addressof*\nfun:_ZNSt3__19addressof*\n\n# Windows C++ stdlib headers that contain bad unrelated casts.\nsrc:*xmemory0\nsrc:*xstddef\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/dfsan/.clang-format",
    "content": "BasedOnStyle: Google\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/dfsan/CMakeLists.txt",
    "content": "include_directories(..)\n\n# Runtime library sources and build flags.\nset(DFSAN_RTL_SOURCES\n  dfsan.cc\n  dfsan_custom.cc\n  dfsan_interceptors.cc)\nset(DFSAN_COMMON_CFLAGS ${SANITIZER_COMMON_CFLAGS})\nappend_no_rtti_flag(DFSAN_COMMON_CFLAGS)\n# Prevent clang from generating libc calls.\nappend_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding DFSAN_COMMON_CFLAGS)\n\n# Static runtime library.\nadd_custom_target(dfsan)\nforeach(arch ${DFSAN_SUPPORTED_ARCH})\n  set(DFSAN_CFLAGS ${DFSAN_COMMON_CFLAGS})\n  append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE DFSAN_CFLAGS)\n  add_compiler_rt_runtime(clang_rt.dfsan\n    STATIC\n    ARCHS ${arch}\n    SOURCES ${DFSAN_RTL_SOURCES}\n            $<TARGET_OBJECTS:RTInterception.${arch}>\n            $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>\n            $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>\n    CFLAGS ${DFSAN_CFLAGS}\n    PARENT_TARGET dfsan)\n  add_sanitizer_rt_symbols(clang_rt.dfsan\n    ARCHS ${arch}\n    EXTRA dfsan.syms.extra)\n  add_dependencies(dfsan\n    clang_rt.dfsan-${arch}-symbols)\nendforeach()\n\nset(dfsan_abilist_filename ${COMPILER_RT_OUTPUT_DIR}/dfsan_abilist.txt)\nadd_custom_target(dfsan_abilist ALL\n  DEPENDS ${dfsan_abilist_filename})\nadd_custom_command(OUTPUT ${dfsan_abilist_filename}\n                   VERBATIM\n                   COMMAND\n                     cat ${CMAKE_CURRENT_SOURCE_DIR}/done_abilist.txt\n                         ${CMAKE_CURRENT_SOURCE_DIR}/libc_ubuntu1404_abilist.txt\n                         > ${dfsan_abilist_filename}\n                   DEPENDS done_abilist.txt libc_ubuntu1404_abilist.txt)\nadd_dependencies(dfsan dfsan_abilist)\ninstall(FILES ${dfsan_abilist_filename}\n        DESTINATION ${COMPILER_RT_INSTALL_PATH})\n\nadd_dependencies(compiler-rt dfsan)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/dfsan/dfsan.cc",
    "content": "//===-- dfsan.cc ----------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of DataFlowSanitizer.\n//\n// DataFlowSanitizer runtime.  This file defines the public interface to\n// DataFlowSanitizer as well as the definition of certain runtime functions\n// called automatically by the compiler (specifically the instrumentation pass\n// in llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp).\n//\n// The public interface is defined in include/sanitizer/dfsan_interface.h whose\n// functions are prefixed dfsan_ while the compiler interface functions are\n// prefixed __dfsan_.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_flag_parser.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n\n#include \"dfsan/dfsan.h\"\n\nusing namespace __dfsan;\n\ntypedef atomic_uint16_t atomic_dfsan_label;\nstatic const dfsan_label kInitializingLabel = -1;\n\nstatic const uptr kNumLabels = 1 << (sizeof(dfsan_label) * 8);\n\nstatic atomic_dfsan_label __dfsan_last_label;\nstatic dfsan_label_info __dfsan_label_info[kNumLabels];\n\nFlags __dfsan::flags_data;\n\nSANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_retval_tls;\nSANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_arg_tls[64];\n\nSANITIZER_INTERFACE_ATTRIBUTE uptr __dfsan_shadow_ptr_mask;\n\n// On Linux/x86_64, memory is laid out as follows:\n//\n// +--------------------+ 0x800000000000 (top of memory)\n// | application memory |\n// +--------------------+ 0x700000008000 (kAppAddr)\n// |                    |\n// |       unused       |\n// |                    |\n// +--------------------+ 0x200200000000 (kUnusedAddr)\n// |    union table     |\n// +--------------------+ 0x200000000000 (kUnionTableAddr)\n// |   shadow memory    |\n// +--------------------+ 0x000000010000 (kShadowAddr)\n// | reserved by kernel |\n// +--------------------+ 0x000000000000\n//\n// To derive a shadow memory address from an application memory address,\n// bits 44-46 are cleared to bring the address into the range\n// [0x000000008000,0x100000000000).  Then the address is shifted left by 1 to\n// account for the double byte representation of shadow labels and move the\n// address into the shadow memory range.  See the function shadow_for below.\n\n// On Linux/MIPS64, memory is laid out as follows:\n//\n// +--------------------+ 0x10000000000 (top of memory)\n// | application memory |\n// +--------------------+ 0xF000008000 (kAppAddr)\n// |                    |\n// |       unused       |\n// |                    |\n// +--------------------+ 0x2200000000 (kUnusedAddr)\n// |    union table     |\n// +--------------------+ 0x2000000000 (kUnionTableAddr)\n// |   shadow memory    |\n// +--------------------+ 0x0000010000 (kShadowAddr)\n// | reserved by kernel |\n// +--------------------+ 0x0000000000\n\n// On Linux/AArch64 (39-bit VMA), memory is laid out as follow:\n//\n// +--------------------+ 0x8000000000 (top of memory)\n// | application memory |\n// +--------------------+ 0x7000008000 (kAppAddr)\n// |                    |\n// |       unused       |\n// |                    |\n// +--------------------+ 0x1200000000 (kUnusedAddr)\n// |    union table     |\n// +--------------------+ 0x1000000000 (kUnionTableAddr)\n// |   shadow memory    |\n// +--------------------+ 0x0000010000 (kShadowAddr)\n// | reserved by kernel |\n// +--------------------+ 0x0000000000\n\n// On Linux/AArch64 (42-bit VMA), memory is laid out as follow:\n//\n// +--------------------+ 0x40000000000 (top of memory)\n// | application memory |\n// +--------------------+ 0x3ff00008000 (kAppAddr)\n// |                    |\n// |       unused       |\n// |                    |\n// +--------------------+ 0x1200000000 (kUnusedAddr)\n// |    union table     |\n// +--------------------+ 0x8000000000 (kUnionTableAddr)\n// |   shadow memory    |\n// +--------------------+ 0x0000010000 (kShadowAddr)\n// | reserved by kernel |\n// +--------------------+ 0x0000000000\n\ntypedef atomic_dfsan_label dfsan_union_table_t[kNumLabels][kNumLabels];\n\n#ifdef DFSAN_RUNTIME_VMA\n// Runtime detected VMA size.\nint __dfsan::vmaSize;\n#endif\n\nstatic uptr UnusedAddr() {\n  return MappingArchImpl<MAPPING_UNION_TABLE_ADDR>()\n         + sizeof(dfsan_union_table_t);\n}\n\nstatic atomic_dfsan_label *union_table(dfsan_label l1, dfsan_label l2) {\n  return &(*(dfsan_union_table_t *) UnionTableAddr())[l1][l2];\n}\n\n// Checks we do not run out of labels.\nstatic void dfsan_check_label(dfsan_label label) {\n  if (label == kInitializingLabel) {\n    Report(\"FATAL: DataFlowSanitizer: out of labels\\n\");\n    Die();\n  }\n}\n\n// Resolves the union of two unequal labels.  Nonequality is a precondition for\n// this function (the instrumentation pass inlines the equality test).\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\ndfsan_label __dfsan_union(dfsan_label l1, dfsan_label l2) {\n  DCHECK_NE(l1, l2);\n\n  if (l1 == 0)\n    return l2;\n  if (l2 == 0)\n    return l1;\n\n  if (l1 > l2)\n    Swap(l1, l2);\n\n  atomic_dfsan_label *table_ent = union_table(l1, l2);\n  // We need to deal with the case where two threads concurrently request\n  // a union of the same pair of labels.  If the table entry is uninitialized,\n  // (i.e. 0) use a compare-exchange to set the entry to kInitializingLabel\n  // (i.e. -1) to mark that we are initializing it.\n  dfsan_label label = 0;\n  if (atomic_compare_exchange_strong(table_ent, &label, kInitializingLabel,\n                                     memory_order_acquire)) {\n    // Check whether l2 subsumes l1.  We don't need to check whether l1\n    // subsumes l2 because we are guaranteed here that l1 < l2, and (at least\n    // in the cases we are interested in) a label may only subsume labels\n    // created earlier (i.e. with a lower numerical value).\n    if (__dfsan_label_info[l2].l1 == l1 ||\n        __dfsan_label_info[l2].l2 == l1) {\n      label = l2;\n    } else {\n      label =\n        atomic_fetch_add(&__dfsan_last_label, 1, memory_order_relaxed) + 1;\n      dfsan_check_label(label);\n      __dfsan_label_info[label].l1 = l1;\n      __dfsan_label_info[label].l2 = l2;\n    }\n    atomic_store(table_ent, label, memory_order_release);\n  } else if (label == kInitializingLabel) {\n    // Another thread is initializing the entry.  Wait until it is finished.\n    do {\n      internal_sched_yield();\n      label = atomic_load(table_ent, memory_order_acquire);\n    } while (label == kInitializingLabel);\n  }\n  return label;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\ndfsan_label __dfsan_union_load(const dfsan_label *ls, uptr n) {\n  dfsan_label label = ls[0];\n  for (uptr i = 1; i != n; ++i) {\n    dfsan_label next_label = ls[i];\n    if (label != next_label)\n      label = __dfsan_union(label, next_label);\n  }\n  return label;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nvoid __dfsan_unimplemented(char *fname) {\n  if (flags().warn_unimplemented)\n    Report(\"WARNING: DataFlowSanitizer: call to uninstrumented function %s\\n\",\n           fname);\n}\n\n// Use '-mllvm -dfsan-debug-nonzero-labels' and break on this function\n// to try to figure out where labels are being introduced in a nominally\n// label-free program.\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE void __dfsan_nonzero_label() {\n  if (flags().warn_nonzero_labels)\n    Report(\"WARNING: DataFlowSanitizer: saw nonzero label\\n\");\n}\n\n// Indirect call to an uninstrumented vararg function. We don't have a way of\n// handling these at the moment.\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE void\n__dfsan_vararg_wrapper(const char *fname) {\n  Report(\"FATAL: DataFlowSanitizer: unsupported indirect call to vararg \"\n         \"function %s\\n\", fname);\n  Die();\n}\n\n// Like __dfsan_union, but for use from the client or custom functions.  Hence\n// the equality comparison is done here before calling __dfsan_union.\nSANITIZER_INTERFACE_ATTRIBUTE dfsan_label\ndfsan_union(dfsan_label l1, dfsan_label l2) {\n  if (l1 == l2)\n    return l1;\n  return __dfsan_union(l1, l2);\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\ndfsan_label dfsan_create_label(const char *desc, void *userdata) {\n  dfsan_label label =\n    atomic_fetch_add(&__dfsan_last_label, 1, memory_order_relaxed) + 1;\n  dfsan_check_label(label);\n  __dfsan_label_info[label].l1 = __dfsan_label_info[label].l2 = 0;\n  __dfsan_label_info[label].desc = desc;\n  __dfsan_label_info[label].userdata = userdata;\n  return label;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nvoid __dfsan_set_label(dfsan_label label, void *addr, uptr size) {\n  for (dfsan_label *labelp = shadow_for(addr); size != 0; --size, ++labelp) {\n    // Don't write the label if it is already the value we need it to be.\n    // In a program where most addresses are not labeled, it is common that\n    // a page of shadow memory is entirely zeroed.  The Linux copy-on-write\n    // implementation will share all of the zeroed pages, making a copy of a\n    // page when any value is written.  The un-sharing will happen even if\n    // the value written does not change the value in memory.  Avoiding the\n    // write when both |label| and |*labelp| are zero dramatically reduces\n    // the amount of real memory used by large programs.\n    if (label == *labelp)\n      continue;\n\n    *labelp = label;\n  }\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid dfsan_set_label(dfsan_label label, void *addr, uptr size) {\n  __dfsan_set_label(label, addr, size);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid dfsan_add_label(dfsan_label label, void *addr, uptr size) {\n  for (dfsan_label *labelp = shadow_for(addr); size != 0; --size, ++labelp)\n    if (*labelp != label)\n      *labelp = __dfsan_union(*labelp, label);\n}\n\n// Unlike the other dfsan interface functions the behavior of this function\n// depends on the label of one of its arguments.  Hence it is implemented as a\n// custom function.\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE dfsan_label\n__dfsw_dfsan_get_label(long data, dfsan_label data_label,\n                       dfsan_label *ret_label) {\n  *ret_label = 0;\n  return data_label;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE dfsan_label\ndfsan_read_label(const void *addr, uptr size) {\n  if (size == 0)\n    return 0;\n  return __dfsan_union_load(shadow_for(addr), size);\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nconst struct dfsan_label_info *dfsan_get_label_info(dfsan_label label) {\n  return &__dfsan_label_info[label];\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE int\ndfsan_has_label(dfsan_label label, dfsan_label elem) {\n  if (label == elem)\n    return true;\n  const dfsan_label_info *info = dfsan_get_label_info(label);\n  if (info->l1 != 0) {\n    return dfsan_has_label(info->l1, elem) || dfsan_has_label(info->l2, elem);\n  } else {\n    return false;\n  }\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE dfsan_label\ndfsan_has_label_with_desc(dfsan_label label, const char *desc) {\n  const dfsan_label_info *info = dfsan_get_label_info(label);\n  if (info->l1 != 0) {\n    return dfsan_has_label_with_desc(info->l1, desc) ||\n           dfsan_has_label_with_desc(info->l2, desc);\n  } else {\n    return internal_strcmp(desc, info->desc) == 0;\n  }\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE uptr\ndfsan_get_label_count(void) {\n  dfsan_label max_label_allocated =\n      atomic_load(&__dfsan_last_label, memory_order_relaxed);\n\n  return static_cast<uptr>(max_label_allocated);\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE void\ndfsan_dump_labels(int fd) {\n  dfsan_label last_label =\n      atomic_load(&__dfsan_last_label, memory_order_relaxed);\n\n  for (uptr l = 1; l <= last_label; ++l) {\n    char buf[64];\n    internal_snprintf(buf, sizeof(buf), \"%u %u %u \", l,\n                      __dfsan_label_info[l].l1, __dfsan_label_info[l].l2);\n    WriteToFile(fd, buf, internal_strlen(buf));\n    if (__dfsan_label_info[l].l1 == 0 && __dfsan_label_info[l].desc) {\n      WriteToFile(fd, __dfsan_label_info[l].desc,\n                  internal_strlen(__dfsan_label_info[l].desc));\n    }\n    WriteToFile(fd, \"\\n\", 1);\n  }\n}\n\nvoid Flags::SetDefaults() {\n#define DFSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;\n#include \"dfsan_flags.inc\"\n#undef DFSAN_FLAG\n}\n\nstatic void RegisterDfsanFlags(FlagParser *parser, Flags *f) {\n#define DFSAN_FLAG(Type, Name, DefaultValue, Description) \\\n  RegisterFlag(parser, #Name, Description, &f->Name);\n#include \"dfsan_flags.inc\"\n#undef DFSAN_FLAG\n}\n\nstatic void InitializeFlags() {\n  SetCommonFlagsDefaults();\n  flags().SetDefaults();\n\n  FlagParser parser;\n  RegisterCommonFlags(&parser);\n  RegisterDfsanFlags(&parser, &flags());\n  parser.ParseString(GetEnv(\"DFSAN_OPTIONS\"));\n  SetVerbosity(common_flags()->verbosity);\n  if (Verbosity()) ReportUnrecognizedFlags();\n  if (common_flags()->help) parser.PrintFlagDescriptions();\n}\n\nstatic void InitializePlatformEarly() {\n#ifdef DFSAN_RUNTIME_VMA\n  __dfsan::vmaSize =\n    (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1);\n  if (__dfsan::vmaSize == 39 || __dfsan::vmaSize == 42) {\n    __dfsan_shadow_ptr_mask = ShadowMask();\n  } else {\n    Printf(\"FATAL: DataFlowSanitizer: unsupported VMA range\\n\");\n    Printf(\"FATAL: Found %d - Supported 39 and 42\\n\", __dfsan::vmaSize);\n    Die();\n  }\n#endif\n}\n\nstatic void dfsan_fini() {\n  if (internal_strcmp(flags().dump_labels_at_exit, \"\") != 0) {\n    fd_t fd = OpenFile(flags().dump_labels_at_exit, WrOnly);\n    if (fd == kInvalidFd) {\n      Report(\"WARNING: DataFlowSanitizer: unable to open output file %s\\n\",\n             flags().dump_labels_at_exit);\n      return;\n    }\n\n    Report(\"INFO: DataFlowSanitizer: dumping labels to %s\\n\",\n           flags().dump_labels_at_exit);\n    dfsan_dump_labels(fd);\n    CloseFile(fd);\n  }\n}\n\nstatic void dfsan_init(int argc, char **argv, char **envp) {\n  InitializeFlags();\n\n  InitializePlatformEarly();\n\n  MmapFixedNoReserve(ShadowAddr(), UnusedAddr() - ShadowAddr());\n\n  // Protect the region of memory we don't use, to preserve the one-to-one\n  // mapping from application to shadow memory. But if ASLR is disabled, Linux\n  // will load our executable in the middle of our unused region. This mostly\n  // works so long as the program doesn't use too much memory. We support this\n  // case by disabling memory protection when ASLR is disabled.\n  uptr init_addr = (uptr)&dfsan_init;\n  if (!(init_addr >= UnusedAddr() && init_addr < AppAddr()))\n    MmapNoAccess(UnusedAddr(), AppAddr() - UnusedAddr());\n\n  InitializeInterceptors();\n\n  // Register the fini callback to run when the program terminates successfully\n  // or it is killed by the runtime.\n  Atexit(dfsan_fini);\n  AddDieCallback(dfsan_fini);\n\n  __dfsan_label_info[kInitializingLabel].desc = \"<init label>\";\n}\n\n#if SANITIZER_CAN_USE_PREINIT_ARRAY\n__attribute__((section(\".preinit_array\"), used))\nstatic void (*dfsan_init_ptr)(int, char **, char **) = dfsan_init;\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/dfsan/dfsan.h",
    "content": "//===-- dfsan.h -------------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of DataFlowSanitizer.\n//\n// Private DFSan header.\n//===----------------------------------------------------------------------===//\n\n#ifndef DFSAN_H\n#define DFSAN_H\n\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"dfsan_platform.h\"\n\n// Copy declarations from public sanitizer/dfsan_interface.h header here.\ntypedef u16 dfsan_label;\n\nstruct dfsan_label_info {\n  dfsan_label l1;\n  dfsan_label l2;\n  const char *desc;\n  void *userdata;\n};\n\nextern \"C\" {\nvoid dfsan_add_label(dfsan_label label, void *addr, uptr size);\nvoid dfsan_set_label(dfsan_label label, void *addr, uptr size);\ndfsan_label dfsan_read_label(const void *addr, uptr size);\ndfsan_label dfsan_union(dfsan_label l1, dfsan_label l2);\n}  // extern \"C\"\n\ntemplate <typename T>\nvoid dfsan_set_label(dfsan_label label, T &data) {  // NOLINT\n  dfsan_set_label(label, (void *)&data, sizeof(T));\n}\n\nnamespace __dfsan {\n\nvoid InitializeInterceptors();\n\ninline dfsan_label *shadow_for(void *ptr) {\n  return (dfsan_label *) ((((uptr) ptr) & ShadowMask()) << 1);\n}\n\ninline const dfsan_label *shadow_for(const void *ptr) {\n  return shadow_for(const_cast<void *>(ptr));\n}\n\nstruct Flags {\n#define DFSAN_FLAG(Type, Name, DefaultValue, Description) Type Name;\n#include \"dfsan_flags.inc\"\n#undef DFSAN_FLAG\n\n  void SetDefaults();\n};\n\nextern Flags flags_data;\ninline Flags &flags() {\n  return flags_data;\n}\n\n}  // namespace __dfsan\n\n#endif  // DFSAN_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/dfsan/dfsan.syms.extra",
    "content": "dfsan_*\n__dfsan_*\n__dfsw_*\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/dfsan/dfsan_custom.cc",
    "content": "//===-- dfsan.cc ----------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of DataFlowSanitizer.\n//\n// This file defines the custom functions listed in done_abilist.txt.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"sanitizer_common/sanitizer_linux.h\"\n\n#include \"dfsan/dfsan.h\"\n\n#include <arpa/inet.h>\n#include <assert.h>\n#include <ctype.h>\n#include <dlfcn.h>\n#include <link.h>\n#include <poll.h>\n#include <pthread.h>\n#include <pwd.h>\n#include <sched.h>\n#include <signal.h>\n#include <stdarg.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/resource.h>\n#include <sys/select.h>\n#include <sys/stat.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <time.h>\n#include <unistd.h>\n\nusing namespace __dfsan;\n\n#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)                                     \\\n  do {                                                                         \\\n    if (f)                                                                     \\\n      f(__VA_ARGS__);                                                          \\\n  } while (false)\n#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \\\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void f(__VA_ARGS__);\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE int\n__dfsw_stat(const char *path, struct stat *buf, dfsan_label path_label,\n            dfsan_label buf_label, dfsan_label *ret_label) {\n  int ret = stat(path, buf);\n  if (ret == 0)\n    dfsan_set_label(0, buf, sizeof(struct stat));\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE int __dfsw_fstat(int fd, struct stat *buf,\n                                               dfsan_label fd_label,\n                                               dfsan_label buf_label,\n                                               dfsan_label *ret_label) {\n  int ret = fstat(fd, buf);\n  if (ret == 0)\n    dfsan_set_label(0, buf, sizeof(struct stat));\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strchr(const char *s, int c,\n                                                  dfsan_label s_label,\n                                                  dfsan_label c_label,\n                                                  dfsan_label *ret_label) {\n  for (size_t i = 0;; ++i) {\n    if (s[i] == c || s[i] == 0) {\n      if (flags().strict_data_dependencies) {\n        *ret_label = s_label;\n      } else {\n        *ret_label = dfsan_union(dfsan_read_label(s, i + 1),\n                                 dfsan_union(s_label, c_label));\n      }\n      return s[i] == 0 ? nullptr : const_cast<char *>(s+i);\n    }\n  }\n}\n\nDECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, uptr caller_pc,\n                              const void *s1, const void *s2, size_t n,\n                              dfsan_label s1_label, dfsan_label s2_label,\n                              dfsan_label n_label)\n\nSANITIZER_INTERFACE_ATTRIBUTE int __dfsw_memcmp(const void *s1, const void *s2,\n                                                size_t n, dfsan_label s1_label,\n                                                dfsan_label s2_label,\n                                                dfsan_label n_label,\n                                                dfsan_label *ret_label) {\n  CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, GET_CALLER_PC(), s1, s2, n,\n                             s1_label, s2_label, n_label);\n  const char *cs1 = (const char *) s1, *cs2 = (const char *) s2;\n  for (size_t i = 0; i != n; ++i) {\n    if (cs1[i] != cs2[i]) {\n      if (flags().strict_data_dependencies) {\n        *ret_label = 0;\n      } else {\n        *ret_label = dfsan_union(dfsan_read_label(cs1, i + 1),\n                                 dfsan_read_label(cs2, i + 1));\n      }\n      return cs1[i] - cs2[i];\n    }\n  }\n\n  if (flags().strict_data_dependencies) {\n    *ret_label = 0;\n  } else {\n    *ret_label = dfsan_union(dfsan_read_label(cs1, n),\n                             dfsan_read_label(cs2, n));\n  }\n  return 0;\n}\n\nDECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, uptr caller_pc,\n                              const char *s1, const char *s2,\n                              dfsan_label s1_label, dfsan_label s2_label)\n\nSANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcmp(const char *s1, const char *s2,\n                                                dfsan_label s1_label,\n                                                dfsan_label s2_label,\n                                                dfsan_label *ret_label) {\n  CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, GET_CALLER_PC(), s1, s2,\n                             s1_label, s2_label);\n  for (size_t i = 0;; ++i) {\n    if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0) {\n      if (flags().strict_data_dependencies) {\n        *ret_label = 0;\n      } else {\n        *ret_label = dfsan_union(dfsan_read_label(s1, i + 1),\n                                 dfsan_read_label(s2, i + 1));\n      }\n      return s1[i] - s2[i];\n    }\n  }\n  return 0;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE int\n__dfsw_strcasecmp(const char *s1, const char *s2, dfsan_label s1_label,\n                  dfsan_label s2_label, dfsan_label *ret_label) {\n  for (size_t i = 0;; ++i) {\n    if (tolower(s1[i]) != tolower(s2[i]) || s1[i] == 0 || s2[i] == 0) {\n      if (flags().strict_data_dependencies) {\n        *ret_label = 0;\n      } else {\n        *ret_label = dfsan_union(dfsan_read_label(s1, i + 1),\n                                 dfsan_read_label(s2, i + 1));\n      }\n      return s1[i] - s2[i];\n    }\n  }\n  return 0;\n}\n\nDECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, uptr caller_pc,\n                              const char *s1, const char *s2, size_t n,\n                              dfsan_label s1_label, dfsan_label s2_label,\n                              dfsan_label n_label)\n\nSANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncmp(const char *s1, const char *s2,\n                                                 size_t n, dfsan_label s1_label,\n                                                 dfsan_label s2_label,\n                                                 dfsan_label n_label,\n                                                 dfsan_label *ret_label) {\n  if (n == 0) {\n    *ret_label = 0;\n    return 0;\n  }\n\n  CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, GET_CALLER_PC(), s1, s2,\n                             n, s1_label, s2_label, n_label);\n\n  for (size_t i = 0;; ++i) {\n    if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || i == n - 1) {\n      if (flags().strict_data_dependencies) {\n        *ret_label = 0;\n      } else {\n        *ret_label = dfsan_union(dfsan_read_label(s1, i + 1),\n                                 dfsan_read_label(s2, i + 1));\n      }\n      return s1[i] - s2[i];\n    }\n  }\n  return 0;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE int\n__dfsw_strncasecmp(const char *s1, const char *s2, size_t n,\n                   dfsan_label s1_label, dfsan_label s2_label,\n                   dfsan_label n_label, dfsan_label *ret_label) {\n  if (n == 0) {\n    *ret_label = 0;\n    return 0;\n  }\n\n  for (size_t i = 0;; ++i) {\n    if (tolower(s1[i]) != tolower(s2[i]) || s1[i] == 0 || s2[i] == 0 ||\n        i == n - 1) {\n      if (flags().strict_data_dependencies) {\n        *ret_label = 0;\n      } else {\n        *ret_label = dfsan_union(dfsan_read_label(s1, i + 1),\n                                 dfsan_read_label(s2, i + 1));\n      }\n      return s1[i] - s2[i];\n    }\n  }\n  return 0;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_calloc(size_t nmemb, size_t size,\n                                                  dfsan_label nmemb_label,\n                                                  dfsan_label size_label,\n                                                  dfsan_label *ret_label) {\n  void *p = calloc(nmemb, size);\n  dfsan_set_label(0, p, nmemb * size);\n  *ret_label = 0;\n  return p;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE size_t\n__dfsw_strlen(const char *s, dfsan_label s_label, dfsan_label *ret_label) {\n  size_t ret = strlen(s);\n  if (flags().strict_data_dependencies) {\n    *ret_label = 0;\n  } else {\n    *ret_label = dfsan_read_label(s, ret + 1);\n  }\n  return ret;\n}\n\n\nstatic void *dfsan_memcpy(void *dest, const void *src, size_t n) {\n  dfsan_label *sdest = shadow_for(dest);\n  const dfsan_label *ssrc = shadow_for(src);\n  internal_memcpy((void *)sdest, (const void *)ssrc, n * sizeof(dfsan_label));\n  return internal_memcpy(dest, src, n);\n}\n\nstatic void dfsan_memset(void *s, int c, dfsan_label c_label, size_t n) {\n  internal_memset(s, c, n);\n  dfsan_set_label(c_label, s, n);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid *__dfsw_memcpy(void *dest, const void *src, size_t n,\n                    dfsan_label dest_label, dfsan_label src_label,\n                    dfsan_label n_label, dfsan_label *ret_label) {\n  *ret_label = dest_label;\n  return dfsan_memcpy(dest, src, n);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid *__dfsw_memset(void *s, int c, size_t n,\n                    dfsan_label s_label, dfsan_label c_label,\n                    dfsan_label n_label, dfsan_label *ret_label) {\n  dfsan_memset(s, c, c_label, n);\n  *ret_label = s_label;\n  return s;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE char *\n__dfsw_strdup(const char *s, dfsan_label s_label, dfsan_label *ret_label) {\n  size_t len = strlen(s);\n  void *p = malloc(len+1);\n  dfsan_memcpy(p, s, len+1);\n  *ret_label = 0;\n  return static_cast<char *>(p);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE char *\n__dfsw_strncpy(char *s1, const char *s2, size_t n, dfsan_label s1_label,\n               dfsan_label s2_label, dfsan_label n_label,\n               dfsan_label *ret_label) {\n  size_t len = strlen(s2);\n  if (len < n) {\n    dfsan_memcpy(s1, s2, len+1);\n    dfsan_memset(s1+len+1, 0, 0, n-len-1);\n  } else {\n    dfsan_memcpy(s1, s2, n);\n  }\n\n  *ret_label = s1_label;\n  return s1;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE ssize_t\n__dfsw_pread(int fd, void *buf, size_t count, off_t offset,\n             dfsan_label fd_label, dfsan_label buf_label,\n             dfsan_label count_label, dfsan_label offset_label,\n             dfsan_label *ret_label) {\n  ssize_t ret = pread(fd, buf, count, offset);\n  if (ret > 0)\n    dfsan_set_label(0, buf, ret);\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE ssize_t\n__dfsw_read(int fd, void *buf, size_t count,\n             dfsan_label fd_label, dfsan_label buf_label,\n             dfsan_label count_label,\n             dfsan_label *ret_label) {\n  ssize_t ret = read(fd, buf, count);\n  if (ret > 0)\n    dfsan_set_label(0, buf, ret);\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE int __dfsw_clock_gettime(clockid_t clk_id,\n                                                       struct timespec *tp,\n                                                       dfsan_label clk_id_label,\n                                                       dfsan_label tp_label,\n                                                       dfsan_label *ret_label) {\n  int ret = clock_gettime(clk_id, tp);\n  if (ret == 0)\n    dfsan_set_label(0, tp, sizeof(struct timespec));\n  *ret_label = 0;\n  return ret;\n}\n\nstatic void unpoison(const void *ptr, uptr size) {\n  dfsan_set_label(0, const_cast<void *>(ptr), size);\n}\n\n// dlopen() ultimately calls mmap() down inside the loader, which generally\n// doesn't participate in dynamic symbol resolution.  Therefore we won't\n// intercept its calls to mmap, and we have to hook it here.\nSANITIZER_INTERFACE_ATTRIBUTE void *\n__dfsw_dlopen(const char *filename, int flag, dfsan_label filename_label,\n              dfsan_label flag_label, dfsan_label *ret_label) {\n  void *handle = dlopen(filename, flag);\n  link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE(handle);\n  if (map)\n    ForEachMappedRegion(map, unpoison);\n  *ret_label = 0;\n  return handle;\n}\n\nstruct pthread_create_info {\n  void *(*start_routine_trampoline)(void *, void *, dfsan_label, dfsan_label *);\n  void *start_routine;\n  void *arg;\n};\n\nstatic void *pthread_create_cb(void *p) {\n  pthread_create_info pci(*(pthread_create_info *)p);\n  free(p);\n  dfsan_label ret_label;\n  return pci.start_routine_trampoline(pci.start_routine, pci.arg, 0,\n                                      &ret_label);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_create(\n    pthread_t *thread, const pthread_attr_t *attr,\n    void *(*start_routine_trampoline)(void *, void *, dfsan_label,\n                                      dfsan_label *),\n    void *start_routine, void *arg, dfsan_label thread_label,\n    dfsan_label attr_label, dfsan_label start_routine_label,\n    dfsan_label arg_label, dfsan_label *ret_label) {\n  pthread_create_info *pci =\n      (pthread_create_info *)malloc(sizeof(pthread_create_info));\n  pci->start_routine_trampoline = start_routine_trampoline;\n  pci->start_routine = start_routine;\n  pci->arg = arg;\n  int rv = pthread_create(thread, attr, pthread_create_cb, (void *)pci);\n  if (rv != 0)\n    free(pci);\n  *ret_label = 0;\n  return rv;\n}\n\nstruct dl_iterate_phdr_info {\n  int (*callback_trampoline)(void *callback, struct dl_phdr_info *info,\n                             size_t size, void *data, dfsan_label info_label,\n                             dfsan_label size_label, dfsan_label data_label,\n                             dfsan_label *ret_label);\n  void *callback;\n  void *data;\n};\n\nint dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) {\n  dl_iterate_phdr_info *dipi = (dl_iterate_phdr_info *)data;\n  dfsan_set_label(0, *info);\n  dfsan_set_label(0, const_cast<char *>(info->dlpi_name),\n                  strlen(info->dlpi_name) + 1);\n  dfsan_set_label(\n      0, const_cast<char *>(reinterpret_cast<const char *>(info->dlpi_phdr)),\n      sizeof(*info->dlpi_phdr) * info->dlpi_phnum);\n  dfsan_label ret_label;\n  return dipi->callback_trampoline(dipi->callback, info, size, dipi->data, 0, 0,\n                                   0, &ret_label);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr(\n    int (*callback_trampoline)(void *callback, struct dl_phdr_info *info,\n                               size_t size, void *data, dfsan_label info_label,\n                               dfsan_label size_label, dfsan_label data_label,\n                               dfsan_label *ret_label),\n    void *callback, void *data, dfsan_label callback_label,\n    dfsan_label data_label, dfsan_label *ret_label) {\n  dl_iterate_phdr_info dipi = { callback_trampoline, callback, data };\n  *ret_label = 0;\n  return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nchar *__dfsw_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label,\n                     dfsan_label buf_label, dfsan_label *ret_label) {\n  char *ret = ctime_r(timep, buf);\n  if (ret) {\n    dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), buf,\n                    strlen(buf) + 1);\n    *ret_label = buf_label;\n  } else {\n    *ret_label = 0;\n  }\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nchar *__dfsw_fgets(char *s, int size, FILE *stream, dfsan_label s_label,\n                   dfsan_label size_label, dfsan_label stream_label,\n                   dfsan_label *ret_label) {\n  char *ret = fgets(s, size, stream);\n  if (ret) {\n    dfsan_set_label(0, ret, strlen(ret) + 1);\n    *ret_label = s_label;\n  } else {\n    *ret_label = 0;\n  }\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nchar *__dfsw_getcwd(char *buf, size_t size, dfsan_label buf_label,\n                    dfsan_label size_label, dfsan_label *ret_label) {\n  char *ret = getcwd(buf, size);\n  if (ret) {\n    dfsan_set_label(0, ret, strlen(ret) + 1);\n    *ret_label = buf_label;\n  } else {\n    *ret_label = 0;\n  }\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nchar *__dfsw_get_current_dir_name(dfsan_label *ret_label) {\n  char *ret = get_current_dir_name();\n  if (ret) {\n    dfsan_set_label(0, ret, strlen(ret) + 1);\n  }\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __dfsw_gethostname(char *name, size_t len, dfsan_label name_label,\n                       dfsan_label len_label, dfsan_label *ret_label) {\n  int ret = gethostname(name, len);\n  if (ret == 0) {\n    dfsan_set_label(0, name, strlen(name) + 1);\n  }\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __dfsw_getrlimit(int resource, struct rlimit *rlim,\n                     dfsan_label resource_label, dfsan_label rlim_label,\n                     dfsan_label *ret_label) {\n  int ret = getrlimit(resource, rlim);\n  if (ret == 0) {\n    dfsan_set_label(0, rlim, sizeof(struct rlimit));\n  }\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __dfsw_getrusage(int who, struct rusage *usage, dfsan_label who_label,\n                     dfsan_label usage_label, dfsan_label *ret_label) {\n  int ret = getrusage(who, usage);\n  if (ret == 0) {\n    dfsan_set_label(0, usage, sizeof(struct rusage));\n  }\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nchar *__dfsw_strcpy(char *dest, const char *src, dfsan_label dst_label,\n                    dfsan_label src_label, dfsan_label *ret_label) {\n  char *ret = strcpy(dest, src);\n  if (ret) {\n    internal_memcpy(shadow_for(dest), shadow_for(src),\n                    sizeof(dfsan_label) * (strlen(src) + 1));\n  }\n  *ret_label = dst_label;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nlong int __dfsw_strtol(const char *nptr, char **endptr, int base,\n                       dfsan_label nptr_label, dfsan_label endptr_label,\n                       dfsan_label base_label, dfsan_label *ret_label) {\n  char *tmp_endptr;\n  long int ret = strtol(nptr, &tmp_endptr, base);\n  if (endptr) {\n    *endptr = tmp_endptr;\n  }\n  if (tmp_endptr > nptr) {\n    // If *tmp_endptr is '\\0' include its label as well.\n    *ret_label = dfsan_union(\n        base_label,\n        dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)));\n  } else {\n    *ret_label = 0;\n  }\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\ndouble __dfsw_strtod(const char *nptr, char **endptr,\n                       dfsan_label nptr_label, dfsan_label endptr_label,\n                       dfsan_label *ret_label) {\n  char *tmp_endptr;\n  double ret = strtod(nptr, &tmp_endptr);\n  if (endptr) {\n    *endptr = tmp_endptr;\n  }\n  if (tmp_endptr > nptr) {\n    // If *tmp_endptr is '\\0' include its label as well.\n    *ret_label = dfsan_read_label(\n        nptr,\n        tmp_endptr - nptr + (*tmp_endptr ? 0 : 1));\n  } else {\n    *ret_label = 0;\n  }\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nlong long int __dfsw_strtoll(const char *nptr, char **endptr, int base,\n                       dfsan_label nptr_label, dfsan_label endptr_label,\n                       dfsan_label base_label, dfsan_label *ret_label) {\n  char *tmp_endptr;\n  long long int ret = strtoll(nptr, &tmp_endptr, base);\n  if (endptr) {\n    *endptr = tmp_endptr;\n  }\n  if (tmp_endptr > nptr) {\n    // If *tmp_endptr is '\\0' include its label as well.\n    *ret_label = dfsan_union(\n        base_label,\n        dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)));\n  } else {\n    *ret_label = 0;\n  }\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nunsigned long int __dfsw_strtoul(const char *nptr, char **endptr, int base,\n                       dfsan_label nptr_label, dfsan_label endptr_label,\n                       dfsan_label base_label, dfsan_label *ret_label) {\n  char *tmp_endptr;\n  unsigned long int ret = strtoul(nptr, &tmp_endptr, base);\n  if (endptr) {\n    *endptr = tmp_endptr;\n  }\n  if (tmp_endptr > nptr) {\n    // If *tmp_endptr is '\\0' include its label as well.\n    *ret_label = dfsan_union(\n        base_label,\n        dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)));\n  } else {\n    *ret_label = 0;\n  }\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nlong long unsigned int __dfsw_strtoull(const char *nptr, char **endptr,\n                                       dfsan_label nptr_label,\n                                       int base, dfsan_label endptr_label,\n                                       dfsan_label base_label,\n                                       dfsan_label *ret_label) {\n  char *tmp_endptr;\n  long long unsigned int ret = strtoull(nptr, &tmp_endptr, base);\n  if (endptr) {\n    *endptr = tmp_endptr;\n  }\n  if (tmp_endptr > nptr) {\n    // If *tmp_endptr is '\\0' include its label as well.\n    *ret_label = dfsan_union(\n        base_label,\n        dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)));\n  } else {\n    *ret_label = 0;\n  }\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\ntime_t __dfsw_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label) {\n  time_t ret = time(t);\n  if (ret != (time_t) -1 && t) {\n    dfsan_set_label(0, t, sizeof(time_t));\n  }\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __dfsw_inet_pton(int af, const char *src, void *dst, dfsan_label af_label,\n                     dfsan_label src_label, dfsan_label dst_label,\n                     dfsan_label *ret_label) {\n  int ret = inet_pton(af, src, dst);\n  if (ret == 1) {\n    dfsan_set_label(dfsan_read_label(src, strlen(src) + 1), dst,\n                    af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr));\n  }\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nstruct tm *__dfsw_localtime_r(const time_t *timep, struct tm *result,\n                              dfsan_label timep_label, dfsan_label result_label,\n                              dfsan_label *ret_label) {\n  struct tm *ret = localtime_r(timep, result);\n  if (ret) {\n    dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), result,\n                    sizeof(struct tm));\n    *ret_label = result_label;\n  } else {\n    *ret_label = 0;\n  }\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __dfsw_getpwuid_r(id_t uid, struct passwd *pwd,\n                      char *buf, size_t buflen, struct passwd **result,\n                      dfsan_label uid_label, dfsan_label pwd_label,\n                      dfsan_label buf_label, dfsan_label buflen_label,\n                      dfsan_label result_label, dfsan_label *ret_label) {\n  // Store the data in pwd, the strings referenced from pwd in buf, and the\n  // address of pwd in *result.  On failure, NULL is stored in *result.\n  int ret = getpwuid_r(uid, pwd, buf, buflen, result);\n  if (ret == 0) {\n    dfsan_set_label(0, pwd, sizeof(struct passwd));\n    dfsan_set_label(0, buf, strlen(buf) + 1);\n  }\n  *ret_label = 0;\n  dfsan_set_label(0, result, sizeof(struct passwd*));\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __dfsw_poll(struct pollfd *fds, nfds_t nfds, int timeout,\n                dfsan_label dfs_label, dfsan_label nfds_label,\n                dfsan_label timeout_label, dfsan_label *ret_label) {\n  int ret = poll(fds, nfds, timeout);\n  if (ret >= 0) {\n    for (; nfds > 0; --nfds) {\n      dfsan_set_label(0, &fds[nfds - 1].revents, sizeof(fds[nfds - 1].revents));\n    }\n  }\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __dfsw_select(int nfds, fd_set *readfds, fd_set *writefds,\n                  fd_set *exceptfds, struct timeval *timeout,\n                  dfsan_label nfds_label, dfsan_label readfds_label,\n                  dfsan_label writefds_label, dfsan_label exceptfds_label,\n                  dfsan_label timeout_label, dfsan_label *ret_label) {\n  int ret = select(nfds, readfds, writefds, exceptfds, timeout);\n  // Clear everything (also on error) since their content is either set or\n  // undefined.\n  if (readfds) {\n    dfsan_set_label(0, readfds, sizeof(fd_set));\n  }\n  if (writefds) {\n    dfsan_set_label(0, writefds, sizeof(fd_set));\n  }\n  if (exceptfds) {\n    dfsan_set_label(0, exceptfds, sizeof(fd_set));\n  }\n  dfsan_set_label(0, timeout, sizeof(struct timeval));\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __dfsw_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask,\n                             dfsan_label pid_label,\n                             dfsan_label cpusetsize_label,\n                             dfsan_label mask_label, dfsan_label *ret_label) {\n  int ret = sched_getaffinity(pid, cpusetsize, mask);\n  if (ret == 0) {\n    dfsan_set_label(0, mask, cpusetsize);\n  }\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __dfsw_sigemptyset(sigset_t *set, dfsan_label set_label,\n                       dfsan_label *ret_label) {\n  int ret = sigemptyset(set);\n  dfsan_set_label(0, set, sizeof(sigset_t));\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __dfsw_sigaction(int signum, const struct sigaction *act,\n                     struct sigaction *oldact, dfsan_label signum_label,\n                     dfsan_label act_label, dfsan_label oldact_label,\n                     dfsan_label *ret_label) {\n  int ret = sigaction(signum, act, oldact);\n  if (oldact) {\n    dfsan_set_label(0, oldact, sizeof(struct sigaction));\n  }\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __dfsw_gettimeofday(struct timeval *tv, struct timezone *tz,\n                        dfsan_label tv_label, dfsan_label tz_label,\n                        dfsan_label *ret_label) {\n  int ret = gettimeofday(tv, tz);\n  if (tv) {\n    dfsan_set_label(0, tv, sizeof(struct timeval));\n  }\n  if (tz) {\n    dfsan_set_label(0, tz, sizeof(struct timezone));\n  }\n  *ret_label = 0;\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memchr(void *s, int c, size_t n,\n                                                  dfsan_label s_label,\n                                                  dfsan_label c_label,\n                                                  dfsan_label n_label,\n                                                  dfsan_label *ret_label) {\n  void *ret = memchr(s, c, n);\n  if (flags().strict_data_dependencies) {\n    *ret_label = ret ? s_label : 0;\n  } else {\n    size_t len =\n        ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1\n            : n;\n    *ret_label =\n        dfsan_union(dfsan_read_label(s, len), dfsan_union(s_label, c_label));\n  }\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strrchr(char *s, int c,\n                                                   dfsan_label s_label,\n                                                   dfsan_label c_label,\n                                                   dfsan_label *ret_label) {\n  char *ret = strrchr(s, c);\n  if (flags().strict_data_dependencies) {\n    *ret_label = ret ? s_label : 0;\n  } else {\n    *ret_label =\n        dfsan_union(dfsan_read_label(s, strlen(s) + 1),\n                    dfsan_union(s_label, c_label));\n  }\n\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strstr(char *haystack, char *needle,\n                                                  dfsan_label haystack_label,\n                                                  dfsan_label needle_label,\n                                                  dfsan_label *ret_label) {\n  char *ret = strstr(haystack, needle);\n  if (flags().strict_data_dependencies) {\n    *ret_label = ret ? haystack_label : 0;\n  } else {\n    size_t len = ret ? ret + strlen(needle) - haystack : strlen(haystack) + 1;\n    *ret_label =\n        dfsan_union(dfsan_read_label(haystack, len),\n                    dfsan_union(dfsan_read_label(needle, strlen(needle) + 1),\n                                dfsan_union(haystack_label, needle_label)));\n  }\n\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE int __dfsw_nanosleep(const struct timespec *req,\n                                                   struct timespec *rem,\n                                                   dfsan_label req_label,\n                                                   dfsan_label rem_label,\n                                                   dfsan_label *ret_label) {\n  int ret = nanosleep(req, rem);\n  *ret_label = 0;\n  if (ret == -1) {\n    // Interrupted by a signal, rem is filled with the remaining time.\n    dfsan_set_label(0, rem, sizeof(struct timespec));\n  }\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE int\n__dfsw_socketpair(int domain, int type, int protocol, int sv[2],\n                  dfsan_label domain_label, dfsan_label type_label,\n                  dfsan_label protocol_label, dfsan_label sv_label,\n                  dfsan_label *ret_label) {\n  int ret = socketpair(domain, type, protocol, sv);\n  *ret_label = 0;\n  if (ret == 0) {\n    dfsan_set_label(0, sv, sizeof(*sv) * 2);\n  }\n  return ret;\n}\n\n// Type of the trampoline function passed to the custom version of\n// dfsan_set_write_callback.\ntypedef void (*write_trampoline_t)(\n    void *callback,\n    int fd, const void *buf, ssize_t count,\n    dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label);\n\n// Calls to dfsan_set_write_callback() set the values in this struct.\n// Calls to the custom version of write() read (and invoke) them.\nstatic struct {\n  write_trampoline_t write_callback_trampoline = nullptr;\n  void *write_callback = nullptr;\n} write_callback_info;\n\nSANITIZER_INTERFACE_ATTRIBUTE void\n__dfsw_dfsan_set_write_callback(\n    write_trampoline_t write_callback_trampoline,\n    void *write_callback,\n    dfsan_label write_callback_label,\n    dfsan_label *ret_label) {\n  write_callback_info.write_callback_trampoline = write_callback_trampoline;\n  write_callback_info.write_callback = write_callback;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE int\n__dfsw_write(int fd, const void *buf, size_t count,\n             dfsan_label fd_label, dfsan_label buf_label,\n             dfsan_label count_label, dfsan_label *ret_label) {\n  if (write_callback_info.write_callback) {\n    write_callback_info.write_callback_trampoline(\n        write_callback_info.write_callback,\n        fd, buf, count,\n        fd_label, buf_label, count_label);\n  }\n\n  *ret_label = 0;\n  return write(fd, buf, count);\n}\n} // namespace __dfsan\n\n// Type used to extract a dfsan_label with va_arg()\ntypedef int dfsan_label_va;\n\n// Formats a chunk either a constant string or a single format directive (e.g.,\n// '%.3f').\nstruct Formatter {\n  Formatter(char *str_, const char *fmt_, size_t size_)\n      : str(str_), str_off(0), size(size_), fmt_start(fmt_), fmt_cur(fmt_),\n        width(-1) {}\n\n  int format() {\n    char *tmp_fmt = build_format_string();\n    int retval =\n        snprintf(str + str_off, str_off < size ? size - str_off : 0, tmp_fmt,\n                 0 /* used only to avoid warnings */);\n    free(tmp_fmt);\n    return retval;\n  }\n\n  template <typename T> int format(T arg) {\n    char *tmp_fmt = build_format_string();\n    int retval;\n    if (width >= 0) {\n      retval = snprintf(str + str_off, str_off < size ? size - str_off : 0,\n                        tmp_fmt, width, arg);\n    } else {\n      retval = snprintf(str + str_off, str_off < size ? size - str_off : 0,\n                        tmp_fmt, arg);\n    }\n    free(tmp_fmt);\n    return retval;\n  }\n\n  char *build_format_string() {\n    size_t fmt_size = fmt_cur - fmt_start + 1;\n    char *new_fmt = (char *)malloc(fmt_size + 1);\n    assert(new_fmt);\n    internal_memcpy(new_fmt, fmt_start, fmt_size);\n    new_fmt[fmt_size] = '\\0';\n    return new_fmt;\n  }\n\n  char *str_cur() { return str + str_off; }\n\n  size_t num_written_bytes(int retval) {\n    if (retval < 0) {\n      return 0;\n    }\n\n    size_t num_avail = str_off < size ? size - str_off : 0;\n    if (num_avail == 0) {\n      return 0;\n    }\n\n    size_t num_written = retval;\n    // A return value of {v,}snprintf of size or more means that the output was\n    // truncated.\n    if (num_written >= num_avail) {\n      num_written -= num_avail;\n    }\n\n    return num_written;\n  }\n\n  char *str;\n  size_t str_off;\n  size_t size;\n  const char *fmt_start;\n  const char *fmt_cur;\n  int width;\n};\n\n// Formats the input and propagates the input labels to the output. The output\n// is stored in 'str'. 'size' bounds the number of output bytes. 'format' and\n// 'ap' are the format string and the list of arguments for formatting. Returns\n// the return value vsnprintf would return.\n//\n// The function tokenizes the format string in chunks representing either a\n// constant string or a single format directive (e.g., '%.3f') and formats each\n// chunk independently into the output string. This approach allows to figure\n// out which bytes of the output string depends on which argument and thus to\n// propagate labels more precisely.\n//\n// WARNING: This implementation does not support conversion specifiers with\n// positional arguments.\nstatic int format_buffer(char *str, size_t size, const char *fmt,\n                         dfsan_label *va_labels, dfsan_label *ret_label,\n                         va_list ap) {\n  Formatter formatter(str, fmt, size);\n\n  while (*formatter.fmt_cur) {\n    formatter.fmt_start = formatter.fmt_cur;\n    formatter.width = -1;\n    int retval = 0;\n\n    if (*formatter.fmt_cur != '%') {\n      // Ordinary character. Consume all the characters until a '%' or the end\n      // of the string.\n      for (; *(formatter.fmt_cur + 1) && *(formatter.fmt_cur + 1) != '%';\n           ++formatter.fmt_cur) {}\n      retval = formatter.format();\n      dfsan_set_label(0, formatter.str_cur(),\n                      formatter.num_written_bytes(retval));\n    } else {\n      // Conversion directive. Consume all the characters until a conversion\n      // specifier or the end of the string.\n      bool end_fmt = false;\n      for (; *formatter.fmt_cur && !end_fmt; ) {\n        switch (*++formatter.fmt_cur) {\n        case 'd':\n        case 'i':\n        case 'o':\n        case 'u':\n        case 'x':\n        case 'X':\n          switch (*(formatter.fmt_cur - 1)) {\n          case 'h':\n            // Also covers the 'hh' case (since the size of the arg is still\n            // an int).\n            retval = formatter.format(va_arg(ap, int));\n            break;\n          case 'l':\n            if (formatter.fmt_cur - formatter.fmt_start >= 2 &&\n                *(formatter.fmt_cur - 2) == 'l') {\n              retval = formatter.format(va_arg(ap, long long int));\n            } else {\n              retval = formatter.format(va_arg(ap, long int));\n            }\n            break;\n          case 'q':\n            retval = formatter.format(va_arg(ap, long long int));\n            break;\n          case 'j':\n            retval = formatter.format(va_arg(ap, intmax_t));\n            break;\n          case 'z':\n          case 't':\n            retval = formatter.format(va_arg(ap, size_t));\n            break;\n          default:\n            retval = formatter.format(va_arg(ap, int));\n          }\n          dfsan_set_label(*va_labels++, formatter.str_cur(),\n                          formatter.num_written_bytes(retval));\n          end_fmt = true;\n          break;\n\n        case 'a':\n        case 'A':\n        case 'e':\n        case 'E':\n        case 'f':\n        case 'F':\n        case 'g':\n        case 'G':\n          if (*(formatter.fmt_cur - 1) == 'L') {\n            retval = formatter.format(va_arg(ap, long double));\n          } else {\n            retval = formatter.format(va_arg(ap, double));\n          }\n          dfsan_set_label(*va_labels++, formatter.str_cur(),\n                          formatter.num_written_bytes(retval));\n          end_fmt = true;\n          break;\n\n        case 'c':\n          retval = formatter.format(va_arg(ap, int));\n          dfsan_set_label(*va_labels++, formatter.str_cur(),\n                          formatter.num_written_bytes(retval));\n          end_fmt = true;\n          break;\n\n        case 's': {\n          char *arg = va_arg(ap, char *);\n          retval = formatter.format(arg);\n          va_labels++;\n          internal_memcpy(shadow_for(formatter.str_cur()), shadow_for(arg),\n                          sizeof(dfsan_label) *\n                              formatter.num_written_bytes(retval));\n          end_fmt = true;\n          break;\n        }\n\n        case 'p':\n          retval = formatter.format(va_arg(ap, void *));\n          dfsan_set_label(*va_labels++, formatter.str_cur(),\n                          formatter.num_written_bytes(retval));\n          end_fmt = true;\n          break;\n\n        case 'n': {\n          int *ptr = va_arg(ap, int *);\n          *ptr = (int)formatter.str_off;\n          va_labels++;\n          dfsan_set_label(0, ptr, sizeof(ptr));\n          end_fmt = true;\n          break;\n        }\n\n        case '%':\n          retval = formatter.format();\n          dfsan_set_label(0, formatter.str_cur(),\n                          formatter.num_written_bytes(retval));\n          end_fmt = true;\n          break;\n\n        case '*':\n          formatter.width = va_arg(ap, int);\n          va_labels++;\n          break;\n\n        default:\n          break;\n        }\n      }\n    }\n\n    if (retval < 0) {\n      return retval;\n    }\n\n    formatter.fmt_cur++;\n    formatter.str_off += retval;\n  }\n\n  *ret_label = 0;\n\n  // Number of bytes written in total.\n  return formatter.str_off;\n}\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE\nint __dfsw_sprintf(char *str, const char *format, dfsan_label str_label,\n                   dfsan_label format_label, dfsan_label *va_labels,\n                   dfsan_label *ret_label, ...) {\n  va_list ap;\n  va_start(ap, ret_label);\n  int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, ap);\n  va_end(ap);\n  return ret;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __dfsw_snprintf(char *str, size_t size, const char *format,\n                    dfsan_label str_label, dfsan_label size_label,\n                    dfsan_label format_label, dfsan_label *va_labels,\n                    dfsan_label *ret_label, ...) {\n  va_list ap;\n  va_start(ap, ret_label);\n  int ret = format_buffer(str, size, format, va_labels, ret_label, ap);\n  va_end(ap);\n  return ret;\n}\n} // extern \"C\"\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/dfsan/dfsan_flags.inc",
    "content": "//===-- dfsan_flags.inc -----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// DFSan runtime flags.\n//\n//===----------------------------------------------------------------------===//\n#ifndef DFSAN_FLAG\n# error \"Define DFSAN_FLAG prior to including this file!\"\n#endif\n\n// DFSAN_FLAG(Type, Name, DefaultValue, Description)\n// See COMMON_FLAG in sanitizer_flags.inc for more details.\n\nDFSAN_FLAG(bool, warn_unimplemented, true,\n           \"Whether to warn on unimplemented functions.\")\nDFSAN_FLAG(bool, warn_nonzero_labels, false,\n           \"Whether to warn on unimplemented functions.\")\nDFSAN_FLAG(\n    bool, strict_data_dependencies, true,\n    \"Whether to propagate labels only when there is an obvious data dependency\"\n    \"(e.g., when comparing strings, ignore the fact that the output of the\"\n    \"comparison might be data-dependent on the content of the strings). This\"\n    \"applies only to the custom functions defined in 'custom.c'.\")\nDFSAN_FLAG(const char *, dump_labels_at_exit, \"\", \"The path of the file where \"\n                                                  \"to dump the labels when the \"\n                                                  \"program terminates.\")\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/dfsan/dfsan_interceptors.cc",
    "content": "//===-- dfsan_interceptors.cc ---------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of DataFlowSanitizer.\n//\n// Interceptors for standard library functions.\n//===----------------------------------------------------------------------===//\n\n#include \"dfsan/dfsan.h\"\n#include \"interception/interception.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n\nINTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,\n            int fd, OFF_T offset) {\n  void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);\n  if (res != (void*)-1)\n    dfsan_set_label(0, res, RoundUpTo(length, GetPageSize()));\n  return res;\n}\n\nINTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,\n            int fd, OFF64_T offset) {\n  void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);\n  if (res != (void*)-1)\n    dfsan_set_label(0, res, RoundUpTo(length, GetPageSize()));\n  return res;\n}\n\nnamespace __dfsan {\nvoid InitializeInterceptors() {\n  static int inited = 0;\n  CHECK_EQ(inited, 0);\n\n  INTERCEPT_FUNCTION(mmap);\n  INTERCEPT_FUNCTION(mmap64);\n  inited = 1;\n}\n}  // namespace __dfsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/dfsan/dfsan_platform.h",
    "content": "//===-- dfsan_platform.h ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of DataFlowSanitizer.\n//\n// Platform specific information for DFSan.\n//===----------------------------------------------------------------------===//\n\n#ifndef DFSAN_PLATFORM_H\n#define DFSAN_PLATFORM_H\n\nnamespace __dfsan {\n\n#if defined(__x86_64__)\nstruct Mapping {\n  static const uptr kShadowAddr = 0x10000;\n  static const uptr kUnionTableAddr = 0x200000000000;\n  static const uptr kAppAddr = 0x700000008000;\n  static const uptr kShadowMask = ~0x700000000000;\n};\n#elif defined(__mips64)\nstruct Mapping {\n  static const uptr kShadowAddr = 0x10000;\n  static const uptr kUnionTableAddr = 0x2000000000;\n  static const uptr kAppAddr = 0xF000008000;\n  static const uptr kShadowMask = ~0xF000000000;\n};\n#elif defined(__aarch64__)\nstruct Mapping39 {\n  static const uptr kShadowAddr = 0x10000;\n  static const uptr kUnionTableAddr = 0x1000000000;\n  static const uptr kAppAddr = 0x7000008000;\n  static const uptr kShadowMask = ~0x7800000000;\n};\n\nstruct Mapping42 {\n  static const uptr kShadowAddr = 0x10000;\n  static const uptr kUnionTableAddr = 0x8000000000;\n  static const uptr kAppAddr = 0x3ff00008000;\n  static const uptr kShadowMask = ~0x3c000000000;\n};\n\nextern int vmaSize;\n# define DFSAN_RUNTIME_VMA 1\n#else\n# error \"DFSan not supported for this platform!\"\n#endif\n\nenum MappingType {\n  MAPPING_SHADOW_ADDR,\n  MAPPING_UNION_TABLE_ADDR,\n  MAPPING_APP_ADDR,\n  MAPPING_SHADOW_MASK\n};\n\ntemplate<typename Mapping, int Type>\nuptr MappingImpl(void) {\n  switch (Type) {\n    case MAPPING_SHADOW_ADDR: return Mapping::kShadowAddr;\n    case MAPPING_UNION_TABLE_ADDR: return Mapping::kUnionTableAddr;\n    case MAPPING_APP_ADDR: return Mapping::kAppAddr;\n    case MAPPING_SHADOW_MASK: return Mapping::kShadowMask;\n  }\n}\n\ntemplate<int Type>\nuptr MappingArchImpl(void) {\n#ifdef __aarch64__\n  if (vmaSize == 39)\n    return MappingImpl<Mapping39, Type>();\n  else\n    return MappingImpl<Mapping42, Type>();\n  DCHECK(0);\n#else\n  return MappingImpl<Mapping, Type>();\n#endif\n}\n\nALWAYS_INLINE\nuptr ShadowAddr() {\n  return MappingArchImpl<MAPPING_SHADOW_ADDR>();\n}\n\nALWAYS_INLINE\nuptr UnionTableAddr() {\n  return MappingArchImpl<MAPPING_UNION_TABLE_ADDR>();\n}\n\nALWAYS_INLINE\nuptr AppAddr() {\n  return MappingArchImpl<MAPPING_APP_ADDR>();\n}\n\nALWAYS_INLINE\nuptr ShadowMask() {\n  return MappingArchImpl<MAPPING_SHADOW_MASK>();\n}\n\n}  // namespace __dfsan\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/dfsan/done_abilist.txt",
    "content": "fun:main=uninstrumented\nfun:main=discard\n\n###############################################################################\n# DFSan interface functions\n###############################################################################\nfun:dfsan_union=uninstrumented\nfun:dfsan_union=discard\nfun:dfsan_create_label=uninstrumented\nfun:dfsan_create_label=discard\nfun:dfsan_set_label=uninstrumented\nfun:dfsan_set_label=discard\nfun:dfsan_add_label=uninstrumented\nfun:dfsan_add_label=discard\nfun:dfsan_get_label=uninstrumented\nfun:dfsan_get_label=custom\nfun:dfsan_read_label=uninstrumented\nfun:dfsan_read_label=discard\nfun:dfsan_get_label_count=uninstrumented\nfun:dfsan_get_label_count=discard\nfun:dfsan_get_label_info=uninstrumented\nfun:dfsan_get_label_info=discard\nfun:dfsan_has_label=uninstrumented\nfun:dfsan_has_label=discard\nfun:dfsan_has_label_with_desc=uninstrumented\nfun:dfsan_has_label_with_desc=discard\nfun:dfsan_set_write_callback=uninstrumented\nfun:dfsan_set_write_callback=custom\n\n###############################################################################\n# glibc\n###############################################################################\nfun:malloc=discard\nfun:realloc=discard\nfun:free=discard\n\n# Functions that return a value that depends on the input, but the output might\n# not be necessarily data-dependent on the input.\nfun:isalpha=functional\nfun:isdigit=functional\nfun:isprint=functional\nfun:isxdigit=functional\nfun:isalnum=functional\nfun:ispunct=functional\nfun:isspace=functional\nfun:tolower=functional\nfun:toupper=functional\n\n# Functions that return a value that is data-dependent on the input.\nfun:btowc=functional\nfun:exp=functional\nfun:exp2=functional\nfun:fabs=functional\nfun:finite=functional\nfun:floor=functional\nfun:fmod=functional\nfun:isinf=functional\nfun:isnan=functional\nfun:log=functional\nfun:modf=functional\nfun:pow=functional\nfun:round=functional\nfun:sqrt=functional\nfun:wctob=functional\n\n# Functions that produce an output that does not depend on the input (shadow is\n# zeroed automatically).\nfun:__assert_fail=discard\nfun:__ctype_b_loc=discard\nfun:__cxa_atexit=discard\nfun:__errno_location=discard\nfun:__newlocale=discard\nfun:__sbrk=discard\nfun:__sigsetjmp=discard\nfun:__uselocale=discard\nfun:__wctype_l=discard\nfun:access=discard\nfun:alarm=discard\nfun:atexit=discard\nfun:bind=discard\nfun:chdir=discard\nfun:close=discard\nfun:closedir=discard\nfun:connect=discard\nfun:dladdr=discard\nfun:dlclose=discard\nfun:fclose=discard\nfun:feof=discard\nfun:ferror=discard\nfun:fflush=discard\nfun:fileno=discard\nfun:fopen=discard\nfun:fprintf=discard\nfun:fputc=discard\nfun:fputc=discard\nfun:fputs=discard\nfun:fputs=discard\nfun:fseek=discard\nfun:ftell=discard\nfun:fwrite=discard\nfun:getenv=discard\nfun:getuid=discard\nfun:geteuid=discard\nfun:getpagesize=discard\nfun:getpid=discard\nfun:kill=discard\nfun:listen=discard\nfun:lseek=discard\nfun:mkdir=discard\nfun:mmap=discard\nfun:munmap=discard\nfun:open=discard\nfun:pipe=discard\nfun:posix_fadvise=discard\nfun:posix_memalign=discard\nfun:prctl=discard\nfun:printf=discard\nfun:pthread_sigmask=discard\nfun:putc=discard\nfun:putchar=discard\nfun:puts=discard\nfun:rand=discard\nfun:random=discard\nfun:remove=discard\nfun:sched_getcpu=discard\nfun:sched_get_priority_max=discard\nfun:sched_setaffinity=discard\nfun:sched_yield=discard\nfun:sem_destroy=discard\nfun:sem_init=discard\nfun:sem_post=discard\nfun:sem_wait=discard\nfun:send=discard\nfun:sendmsg=discard\nfun:sendto=discard\nfun:setsockopt=discard\nfun:shutdown=discard\nfun:sleep=discard\nfun:socket=discard\nfun:strerror=discard\nfun:strspn=discard\nfun:strcspn=discard\nfun:symlink=discard\nfun:syscall=discard\nfun:unlink=discard\nfun:uselocale=discard\n\n# Functions that produce output does not depend on the input (need to zero the\n# shadow manually).\nfun:calloc=custom\nfun:clock_gettime=custom\nfun:dlopen=custom\nfun:fgets=custom\nfun:fstat=custom\nfun:getcwd=custom\nfun:get_current_dir_name=custom\nfun:gethostname=custom\nfun:getrlimit=custom\nfun:getrusage=custom\nfun:nanosleep=custom\nfun:pread=custom\nfun:read=custom\nfun:socketpair=custom\nfun:stat=custom\nfun:time=custom\n\n# Functions that produce an output that depend on the input (propagate the\n# shadow manually).\nfun:ctime_r=custom\nfun:inet_pton=custom\nfun:localtime_r=custom\nfun:memcpy=custom\nfun:memset=custom\nfun:strcpy=custom\nfun:strdup=custom\nfun:strncpy=custom\nfun:strtod=custom\nfun:strtol=custom\nfun:strtoll=custom\nfun:strtoul=custom\nfun:strtoull=custom\n\n# Functions that produce an output that is computed from the input, but is not\n# necessarily data dependent.\nfun:memchr=custom\nfun:memcmp=custom\nfun:strcasecmp=custom\nfun:strchr=custom\nfun:strcmp=custom\nfun:strlen=custom\nfun:strncasecmp=custom\nfun:strncmp=custom\nfun:strrchr=custom\nfun:strstr=custom\n\n# Functions which take action based on global state, such as running a callback\n# set by a sepperate function.\nfun:write=custom\n\n# Functions that take a callback (wrap the callback manually).\nfun:dl_iterate_phdr=custom\n\nfun:getpwuid_r=custom\nfun:poll=custom\nfun:sched_getaffinity=custom\nfun:select=custom\nfun:sigemptyset=custom\nfun:sigaction=custom\nfun:gettimeofday=custom\n\n# sprintf-like\nfun:sprintf=custom\nfun:snprintf=custom\n\n# TODO: custom\nfun:asprintf=discard\nfun:qsort=discard\n\n###############################################################################\n# pthread\n###############################################################################\nfun:pthread_equal=discard\nfun:pthread_getspecific=discard\nfun:pthread_key_create=discard\nfun:pthread_key_delete=discard\nfun:pthread_mutex_destroy=discard\nfun:pthread_mutex_init=discard\nfun:pthread_mutex_lock=discard\nfun:pthread_mutex_trylock=discard\nfun:pthread_mutex_unlock=discard\nfun:pthread_mutexattr_destroy=discard\nfun:pthread_mutexattr_init=discard\nfun:pthread_mutexattr_settype=discard\nfun:pthread_once=discard\nfun:pthread_self=discard\nfun:pthread_setspecific=discard\n\n# Functions that take a callback (wrap the callback manually).\nfun:pthread_create=custom\n\n###############################################################################\n# libffi/libgo\n###############################################################################\n# Functions that are written in asm or are called from asm.\nfun:ffi_call_unix64=uninstrumented\nfun:ffi_call_unix64=discard\nfun:ffi_closure_unix64_inner=uninstrumented\nfun:ffi_closure_unix64_inner=discard\nfun:ffi_closure_unix64=uninstrumented\nfun:ffi_closure_unix64=discard\nfun:__go_get_closure=uninstrumented\nfun:__go_get_closure=discard\nfun:__go_makefunc_can_recover=uninstrumented\nfun:__go_makefunc_can_recover=discard\nfun:__go_makefunc_returning=uninstrumented\nfun:__go_makefunc_returning=discard\nfun:reflect.MakeFuncStubGo=uninstrumented\nfun:reflect.MakeFuncStubGo=discard\nfun:reflect.makeFuncStub=uninstrumented\nfun:reflect.makeFuncStub=discard\n\n\n###############################################################################\n# lib/Fuzzer\n###############################################################################\n# Replaces __sanitizer_cov_trace_cmp with __dfsw___sanitizer_cov_trace_cmp\nfun:__sanitizer_cov_trace_cmp=custom\nfun:__sanitizer_cov_trace_cmp=uninstrumented\n# Similar for __sanitizer_cov_trace_switch\nfun:__sanitizer_cov_trace_switch=custom\nfun:__sanitizer_cov_trace_switch=uninstrumented\n\n# Ignores all other __sanitizer callbacks.\nfun:__sanitizer_cov=uninstrumented\nfun:__sanitizer_cov=discard\nfun:__sanitizer_cov_module_init=uninstrumented\nfun:__sanitizer_cov_module_init=discard\nfun:__sanitizer_cov_with_check=uninstrumented\nfun:__sanitizer_cov_with_check=discard\nfun:__sanitizer_cov_indir_call16=uninstrumented\nfun:__sanitizer_cov_indir_call16=discard\nfun:__sanitizer_cov_indir_call16=uninstrumented\nfun:__sanitizer_cov_indir_call16=discard\nfun:__sanitizer_reset_coverage=uninstrumented\nfun:__sanitizer_reset_coverage=discard\nfun:__sanitizer_set_death_callback=uninstrumented\nfun:__sanitizer_set_death_callback=discard\nfun:__sanitizer_get_coverage_guards=uninstrumented\nfun:__sanitizer_get_coverage_guards=discard\nfun:__sanitizer_get_number_of_counters=uninstrumented\nfun:__sanitizer_get_number_of_counters=discard\nfun:__sanitizer_update_counter_bitset_and_clear_counters=uninstrumented\nfun:__sanitizer_update_counter_bitset_and_clear_counters=discard\nfun:__sanitizer_get_total_unique_coverage=uninstrumented\nfun:__sanitizer_get_total_unique_coverage=discard\nfun:__sanitizer_get_total_unique_coverage=uninstrumented\nfun:__sanitizer_get_total_unique_coverage=discard\nfun:__sanitizer_update_counter_bitset_and_clear_counters=uninstrumented\nfun:__sanitizer_update_counter_bitset_and_clear_counters=discard\n\n# Ignores the dfsan wrappers.\nfun:__dfsw_*=uninstrumented\nfun:__dfsw_*=discard\n\n# Don't add extra parameters to the Fuzzer callback.\nfun:LLVMFuzzerTestOneInput=uninstrumented\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/dfsan/libc_ubuntu1404_abilist.txt",
    "content": "fun:_Exit=uninstrumented\nfun:_IO_adjust_column=uninstrumented\nfun:_IO_adjust_wcolumn=uninstrumented\nfun:_IO_default_doallocate=uninstrumented\nfun:_IO_default_finish=uninstrumented\nfun:_IO_default_pbackfail=uninstrumented\nfun:_IO_default_uflow=uninstrumented\nfun:_IO_default_xsgetn=uninstrumented\nfun:_IO_default_xsputn=uninstrumented\nfun:_IO_do_write=uninstrumented\nfun:_IO_doallocbuf=uninstrumented\nfun:_IO_fclose=uninstrumented\nfun:_IO_fdopen=uninstrumented\nfun:_IO_feof=uninstrumented\nfun:_IO_ferror=uninstrumented\nfun:_IO_fflush=uninstrumented\nfun:_IO_fgetpos=uninstrumented\nfun:_IO_fgetpos64=uninstrumented\nfun:_IO_fgets=uninstrumented\nfun:_IO_file_attach=uninstrumented\nfun:_IO_file_close=uninstrumented\nfun:_IO_file_close_it=uninstrumented\nfun:_IO_file_doallocate=uninstrumented\nfun:_IO_file_finish=uninstrumented\nfun:_IO_file_fopen=uninstrumented\nfun:_IO_file_init=uninstrumented\nfun:_IO_file_open=uninstrumented\nfun:_IO_file_overflow=uninstrumented\nfun:_IO_file_read=uninstrumented\nfun:_IO_file_seek=uninstrumented\nfun:_IO_file_seekoff=uninstrumented\nfun:_IO_file_setbuf=uninstrumented\nfun:_IO_file_stat=uninstrumented\nfun:_IO_file_sync=uninstrumented\nfun:_IO_file_underflow=uninstrumented\nfun:_IO_file_write=uninstrumented\nfun:_IO_file_xsputn=uninstrumented\nfun:_IO_flockfile=uninstrumented\nfun:_IO_flush_all=uninstrumented\nfun:_IO_flush_all_linebuffered=uninstrumented\nfun:_IO_fopen=uninstrumented\nfun:_IO_fprintf=uninstrumented\nfun:_IO_fputs=uninstrumented\nfun:_IO_fread=uninstrumented\nfun:_IO_free_backup_area=uninstrumented\nfun:_IO_free_wbackup_area=uninstrumented\nfun:_IO_fsetpos=uninstrumented\nfun:_IO_fsetpos64=uninstrumented\nfun:_IO_ftell=uninstrumented\nfun:_IO_ftrylockfile=uninstrumented\nfun:_IO_funlockfile=uninstrumented\nfun:_IO_fwrite=uninstrumented\nfun:_IO_getc=uninstrumented\nfun:_IO_getline=uninstrumented\nfun:_IO_getline_info=uninstrumented\nfun:_IO_gets=uninstrumented\nfun:_IO_init=uninstrumented\nfun:_IO_init_marker=uninstrumented\nfun:_IO_init_wmarker=uninstrumented\nfun:_IO_iter_begin=uninstrumented\nfun:_IO_iter_end=uninstrumented\nfun:_IO_iter_file=uninstrumented\nfun:_IO_iter_next=uninstrumented\nfun:_IO_least_wmarker=uninstrumented\nfun:_IO_link_in=uninstrumented\nfun:_IO_list_lock=uninstrumented\nfun:_IO_list_resetlock=uninstrumented\nfun:_IO_list_unlock=uninstrumented\nfun:_IO_marker_delta=uninstrumented\nfun:_IO_marker_difference=uninstrumented\nfun:_IO_padn=uninstrumented\nfun:_IO_peekc_locked=uninstrumented\nfun:_IO_popen=uninstrumented\nfun:_IO_printf=uninstrumented\nfun:_IO_proc_close=uninstrumented\nfun:_IO_proc_open=uninstrumented\nfun:_IO_putc=uninstrumented\nfun:_IO_puts=uninstrumented\nfun:_IO_remove_marker=uninstrumented\nfun:_IO_seekmark=uninstrumented\nfun:_IO_seekoff=uninstrumented\nfun:_IO_seekpos=uninstrumented\nfun:_IO_seekwmark=uninstrumented\nfun:_IO_setb=uninstrumented\nfun:_IO_setbuffer=uninstrumented\nfun:_IO_setvbuf=uninstrumented\nfun:_IO_sgetn=uninstrumented\nfun:_IO_sprintf=uninstrumented\nfun:_IO_sputbackc=uninstrumented\nfun:_IO_sputbackwc=uninstrumented\nfun:_IO_sscanf=uninstrumented\nfun:_IO_str_init_readonly=uninstrumented\nfun:_IO_str_init_static=uninstrumented\nfun:_IO_str_overflow=uninstrumented\nfun:_IO_str_pbackfail=uninstrumented\nfun:_IO_str_seekoff=uninstrumented\nfun:_IO_str_underflow=uninstrumented\nfun:_IO_sungetc=uninstrumented\nfun:_IO_sungetwc=uninstrumented\nfun:_IO_switch_to_get_mode=uninstrumented\nfun:_IO_switch_to_main_wget_area=uninstrumented\nfun:_IO_switch_to_wbackup_area=uninstrumented\nfun:_IO_switch_to_wget_mode=uninstrumented\nfun:_IO_un_link=uninstrumented\nfun:_IO_ungetc=uninstrumented\nfun:_IO_unsave_markers=uninstrumented\nfun:_IO_unsave_wmarkers=uninstrumented\nfun:_IO_vfprintf=uninstrumented\nfun:_IO_vfscanf=uninstrumented\nfun:_IO_vsprintf=uninstrumented\nfun:_IO_wdefault_doallocate=uninstrumented\nfun:_IO_wdefault_finish=uninstrumented\nfun:_IO_wdefault_pbackfail=uninstrumented\nfun:_IO_wdefault_uflow=uninstrumented\nfun:_IO_wdefault_xsgetn=uninstrumented\nfun:_IO_wdefault_xsputn=uninstrumented\nfun:_IO_wdo_write=uninstrumented\nfun:_IO_wdoallocbuf=uninstrumented\nfun:_IO_wfile_overflow=uninstrumented\nfun:_IO_wfile_seekoff=uninstrumented\nfun:_IO_wfile_sync=uninstrumented\nfun:_IO_wfile_underflow=uninstrumented\nfun:_IO_wfile_xsputn=uninstrumented\nfun:_IO_wmarker_delta=uninstrumented\nfun:_IO_wsetb=uninstrumented\nfun:_Unwind_Backtrace=uninstrumented\nfun:_Unwind_DeleteException=uninstrumented\nfun:_Unwind_FindEnclosingFunction=uninstrumented\nfun:_Unwind_Find_FDE=uninstrumented\nfun:_Unwind_ForcedUnwind=uninstrumented\nfun:_Unwind_GetCFA=uninstrumented\nfun:_Unwind_GetDataRelBase=uninstrumented\nfun:_Unwind_GetGR=uninstrumented\nfun:_Unwind_GetIP=uninstrumented\nfun:_Unwind_GetIPInfo=uninstrumented\nfun:_Unwind_GetLanguageSpecificData=uninstrumented\nfun:_Unwind_GetRegionStart=uninstrumented\nfun:_Unwind_GetTextRelBase=uninstrumented\nfun:_Unwind_RaiseException=uninstrumented\nfun:_Unwind_Resume=uninstrumented\nfun:_Unwind_Resume_or_Rethrow=uninstrumented\nfun:_Unwind_SetGR=uninstrumented\nfun:_Unwind_SetIP=uninstrumented\nfun:__absvdi2=uninstrumented\nfun:__absvsi2=uninstrumented\nfun:__absvti2=uninstrumented\nfun:__acos_finite=uninstrumented\nfun:__acosf_finite=uninstrumented\nfun:__acosh_finite=uninstrumented\nfun:__acoshf_finite=uninstrumented\nfun:__acoshl_finite=uninstrumented\nfun:__acosl_finite=uninstrumented\nfun:__addtf3=uninstrumented\nfun:__addvdi3=uninstrumented\nfun:__addvsi3=uninstrumented\nfun:__addvti3=uninstrumented\nfun:__adjtimex=uninstrumented\nfun:__arch_prctl=uninstrumented\nfun:__argz_count=uninstrumented\nfun:__argz_next=uninstrumented\nfun:__argz_stringify=uninstrumented\nfun:__ashlti3=uninstrumented\nfun:__ashrti3=uninstrumented\nfun:__asin_finite=uninstrumented\nfun:__asinf_finite=uninstrumented\nfun:__asinl_finite=uninstrumented\nfun:__asprintf=uninstrumented\nfun:__asprintf_chk=uninstrumented\nfun:__assert=uninstrumented\nfun:__assert_fail=uninstrumented\nfun:__assert_perror_fail=uninstrumented\nfun:__atan2_finite=uninstrumented\nfun:__atan2f_finite=uninstrumented\nfun:__atan2l_finite=uninstrumented\nfun:__atanh_finite=uninstrumented\nfun:__atanhf_finite=uninstrumented\nfun:__atanhl_finite=uninstrumented\nfun:__b64_ntop=uninstrumented\nfun:__b64_pton=uninstrumented\nfun:__backtrace=uninstrumented\nfun:__backtrace_symbols=uninstrumented\nfun:__backtrace_symbols_fd=uninstrumented\nfun:__bid128_abs=uninstrumented\nfun:__bid128_add=uninstrumented\nfun:__bid128_class=uninstrumented\nfun:__bid128_copy=uninstrumented\nfun:__bid128_copySign=uninstrumented\nfun:__bid128_div=uninstrumented\nfun:__bid128_fma=uninstrumented\nfun:__bid128_from_int32=uninstrumented\nfun:__bid128_from_int64=uninstrumented\nfun:__bid128_from_uint32=uninstrumented\nfun:__bid128_from_uint64=uninstrumented\nfun:__bid128_isCanonical=uninstrumented\nfun:__bid128_isFinite=uninstrumented\nfun:__bid128_isInf=uninstrumented\nfun:__bid128_isNaN=uninstrumented\nfun:__bid128_isNormal=uninstrumented\nfun:__bid128_isSignaling=uninstrumented\nfun:__bid128_isSigned=uninstrumented\nfun:__bid128_isSubnormal=uninstrumented\nfun:__bid128_isZero=uninstrumented\nfun:__bid128_mul=uninstrumented\nfun:__bid128_negate=uninstrumented\nfun:__bid128_quiet_equal=uninstrumented\nfun:__bid128_quiet_greater=uninstrumented\nfun:__bid128_quiet_greater_equal=uninstrumented\nfun:__bid128_quiet_greater_unordered=uninstrumented\nfun:__bid128_quiet_less=uninstrumented\nfun:__bid128_quiet_less_equal=uninstrumented\nfun:__bid128_quiet_less_unordered=uninstrumented\nfun:__bid128_quiet_not_equal=uninstrumented\nfun:__bid128_quiet_not_greater=uninstrumented\nfun:__bid128_quiet_not_less=uninstrumented\nfun:__bid128_quiet_ordered=uninstrumented\nfun:__bid128_quiet_unordered=uninstrumented\nfun:__bid128_radix=uninstrumented\nfun:__bid128_sameQuantum=uninstrumented\nfun:__bid128_signaling_greater=uninstrumented\nfun:__bid128_signaling_greater_equal=uninstrumented\nfun:__bid128_signaling_greater_unordered=uninstrumented\nfun:__bid128_signaling_less=uninstrumented\nfun:__bid128_signaling_less_equal=uninstrumented\nfun:__bid128_signaling_less_unordered=uninstrumented\nfun:__bid128_signaling_not_greater=uninstrumented\nfun:__bid128_signaling_not_less=uninstrumented\nfun:__bid128_sub=uninstrumented\nfun:__bid128_to_bid32=uninstrumented\nfun:__bid128_to_bid64=uninstrumented\nfun:__bid128_to_binary128=uninstrumented\nfun:__bid128_to_binary32=uninstrumented\nfun:__bid128_to_binary64=uninstrumented\nfun:__bid128_to_binary80=uninstrumented\nfun:__bid128_to_int32_ceil=uninstrumented\nfun:__bid128_to_int32_floor=uninstrumented\nfun:__bid128_to_int32_int=uninstrumented\nfun:__bid128_to_int32_rnint=uninstrumented\nfun:__bid128_to_int32_rninta=uninstrumented\nfun:__bid128_to_int32_xceil=uninstrumented\nfun:__bid128_to_int32_xfloor=uninstrumented\nfun:__bid128_to_int32_xint=uninstrumented\nfun:__bid128_to_int32_xrnint=uninstrumented\nfun:__bid128_to_int32_xrninta=uninstrumented\nfun:__bid128_to_int64_ceil=uninstrumented\nfun:__bid128_to_int64_floor=uninstrumented\nfun:__bid128_to_int64_int=uninstrumented\nfun:__bid128_to_int64_rnint=uninstrumented\nfun:__bid128_to_int64_rninta=uninstrumented\nfun:__bid128_to_int64_xceil=uninstrumented\nfun:__bid128_to_int64_xfloor=uninstrumented\nfun:__bid128_to_int64_xint=uninstrumented\nfun:__bid128_to_int64_xrnint=uninstrumented\nfun:__bid128_to_int64_xrninta=uninstrumented\nfun:__bid128_to_uint32_ceil=uninstrumented\nfun:__bid128_to_uint32_floor=uninstrumented\nfun:__bid128_to_uint32_int=uninstrumented\nfun:__bid128_to_uint32_rnint=uninstrumented\nfun:__bid128_to_uint32_rninta=uninstrumented\nfun:__bid128_to_uint32_xceil=uninstrumented\nfun:__bid128_to_uint32_xfloor=uninstrumented\nfun:__bid128_to_uint32_xint=uninstrumented\nfun:__bid128_to_uint32_xrnint=uninstrumented\nfun:__bid128_to_uint32_xrninta=uninstrumented\nfun:__bid128_to_uint64_ceil=uninstrumented\nfun:__bid128_to_uint64_floor=uninstrumented\nfun:__bid128_to_uint64_int=uninstrumented\nfun:__bid128_to_uint64_rnint=uninstrumented\nfun:__bid128_to_uint64_rninta=uninstrumented\nfun:__bid128_to_uint64_xceil=uninstrumented\nfun:__bid128_to_uint64_xfloor=uninstrumented\nfun:__bid128_to_uint64_xint=uninstrumented\nfun:__bid128_to_uint64_xrnint=uninstrumented\nfun:__bid128_to_uint64_xrninta=uninstrumented\nfun:__bid128_totalOrder=uninstrumented\nfun:__bid128_totalOrderMag=uninstrumented\nfun:__bid128dd_add=uninstrumented\nfun:__bid128dd_div=uninstrumented\nfun:__bid128dd_mul=uninstrumented\nfun:__bid128dd_sub=uninstrumented\nfun:__bid128ddd_fma=uninstrumented\nfun:__bid128ddq_fma=uninstrumented\nfun:__bid128dq_add=uninstrumented\nfun:__bid128dq_div=uninstrumented\nfun:__bid128dq_mul=uninstrumented\nfun:__bid128dq_sub=uninstrumented\nfun:__bid128dqd_fma=uninstrumented\nfun:__bid128dqq_fma=uninstrumented\nfun:__bid128qd_add=uninstrumented\nfun:__bid128qd_div=uninstrumented\nfun:__bid128qd_mul=uninstrumented\nfun:__bid128qd_sub=uninstrumented\nfun:__bid128qdd_fma=uninstrumented\nfun:__bid128qdq_fma=uninstrumented\nfun:__bid128qqd_fma=uninstrumented\nfun:__bid32_to_bid128=uninstrumented\nfun:__bid32_to_bid64=uninstrumented\nfun:__bid32_to_binary128=uninstrumented\nfun:__bid32_to_binary32=uninstrumented\nfun:__bid32_to_binary64=uninstrumented\nfun:__bid32_to_binary80=uninstrumented\nfun:__bid64_abs=uninstrumented\nfun:__bid64_add=uninstrumented\nfun:__bid64_class=uninstrumented\nfun:__bid64_copy=uninstrumented\nfun:__bid64_copySign=uninstrumented\nfun:__bid64_div=uninstrumented\nfun:__bid64_from_int32=uninstrumented\nfun:__bid64_from_int64=uninstrumented\nfun:__bid64_from_uint32=uninstrumented\nfun:__bid64_from_uint64=uninstrumented\nfun:__bid64_isCanonical=uninstrumented\nfun:__bid64_isFinite=uninstrumented\nfun:__bid64_isInf=uninstrumented\nfun:__bid64_isNaN=uninstrumented\nfun:__bid64_isNormal=uninstrumented\nfun:__bid64_isSignaling=uninstrumented\nfun:__bid64_isSigned=uninstrumented\nfun:__bid64_isSubnormal=uninstrumented\nfun:__bid64_isZero=uninstrumented\nfun:__bid64_mul=uninstrumented\nfun:__bid64_negate=uninstrumented\nfun:__bid64_quiet_equal=uninstrumented\nfun:__bid64_quiet_greater=uninstrumented\nfun:__bid64_quiet_greater_equal=uninstrumented\nfun:__bid64_quiet_greater_unordered=uninstrumented\nfun:__bid64_quiet_less=uninstrumented\nfun:__bid64_quiet_less_equal=uninstrumented\nfun:__bid64_quiet_less_unordered=uninstrumented\nfun:__bid64_quiet_not_equal=uninstrumented\nfun:__bid64_quiet_not_greater=uninstrumented\nfun:__bid64_quiet_not_less=uninstrumented\nfun:__bid64_quiet_ordered=uninstrumented\nfun:__bid64_quiet_unordered=uninstrumented\nfun:__bid64_radix=uninstrumented\nfun:__bid64_sameQuantum=uninstrumented\nfun:__bid64_signaling_greater=uninstrumented\nfun:__bid64_signaling_greater_equal=uninstrumented\nfun:__bid64_signaling_greater_unordered=uninstrumented\nfun:__bid64_signaling_less=uninstrumented\nfun:__bid64_signaling_less_equal=uninstrumented\nfun:__bid64_signaling_less_unordered=uninstrumented\nfun:__bid64_signaling_not_greater=uninstrumented\nfun:__bid64_signaling_not_less=uninstrumented\nfun:__bid64_sub=uninstrumented\nfun:__bid64_to_bid128=uninstrumented\nfun:__bid64_to_bid32=uninstrumented\nfun:__bid64_to_binary128=uninstrumented\nfun:__bid64_to_binary32=uninstrumented\nfun:__bid64_to_binary64=uninstrumented\nfun:__bid64_to_binary80=uninstrumented\nfun:__bid64_to_int32_ceil=uninstrumented\nfun:__bid64_to_int32_floor=uninstrumented\nfun:__bid64_to_int32_int=uninstrumented\nfun:__bid64_to_int32_rnint=uninstrumented\nfun:__bid64_to_int32_rninta=uninstrumented\nfun:__bid64_to_int32_xceil=uninstrumented\nfun:__bid64_to_int32_xfloor=uninstrumented\nfun:__bid64_to_int32_xint=uninstrumented\nfun:__bid64_to_int32_xrnint=uninstrumented\nfun:__bid64_to_int32_xrninta=uninstrumented\nfun:__bid64_to_int64_ceil=uninstrumented\nfun:__bid64_to_int64_floor=uninstrumented\nfun:__bid64_to_int64_int=uninstrumented\nfun:__bid64_to_int64_rnint=uninstrumented\nfun:__bid64_to_int64_rninta=uninstrumented\nfun:__bid64_to_int64_xceil=uninstrumented\nfun:__bid64_to_int64_xfloor=uninstrumented\nfun:__bid64_to_int64_xint=uninstrumented\nfun:__bid64_to_int64_xrnint=uninstrumented\nfun:__bid64_to_int64_xrninta=uninstrumented\nfun:__bid64_to_uint32_ceil=uninstrumented\nfun:__bid64_to_uint32_floor=uninstrumented\nfun:__bid64_to_uint32_int=uninstrumented\nfun:__bid64_to_uint32_rnint=uninstrumented\nfun:__bid64_to_uint32_rninta=uninstrumented\nfun:__bid64_to_uint32_xceil=uninstrumented\nfun:__bid64_to_uint32_xfloor=uninstrumented\nfun:__bid64_to_uint32_xint=uninstrumented\nfun:__bid64_to_uint32_xrnint=uninstrumented\nfun:__bid64_to_uint32_xrninta=uninstrumented\nfun:__bid64_to_uint64_ceil=uninstrumented\nfun:__bid64_to_uint64_floor=uninstrumented\nfun:__bid64_to_uint64_int=uninstrumented\nfun:__bid64_to_uint64_rnint=uninstrumented\nfun:__bid64_to_uint64_rninta=uninstrumented\nfun:__bid64_to_uint64_xceil=uninstrumented\nfun:__bid64_to_uint64_xfloor=uninstrumented\nfun:__bid64_to_uint64_xint=uninstrumented\nfun:__bid64_to_uint64_xrnint=uninstrumented\nfun:__bid64_to_uint64_xrninta=uninstrumented\nfun:__bid64_totalOrder=uninstrumented\nfun:__bid64_totalOrderMag=uninstrumented\nfun:__bid64ddq_fma=uninstrumented\nfun:__bid64dq_add=uninstrumented\nfun:__bid64dq_div=uninstrumented\nfun:__bid64dq_mul=uninstrumented\nfun:__bid64dq_sub=uninstrumented\nfun:__bid64dqd_fma=uninstrumented\nfun:__bid64dqq_fma=uninstrumented\nfun:__bid64qd_add=uninstrumented\nfun:__bid64qd_div=uninstrumented\nfun:__bid64qd_mul=uninstrumented\nfun:__bid64qd_sub=uninstrumented\nfun:__bid64qdd_fma=uninstrumented\nfun:__bid64qdq_fma=uninstrumented\nfun:__bid64qq_add=uninstrumented\nfun:__bid64qq_div=uninstrumented\nfun:__bid64qq_mul=uninstrumented\nfun:__bid64qq_sub=uninstrumented\nfun:__bid64qqd_fma=uninstrumented\nfun:__bid64qqq_fma=uninstrumented\nfun:__bid_adddd3=uninstrumented\nfun:__bid_addsd3=uninstrumented\nfun:__bid_addtd3=uninstrumented\nfun:__bid_divdd3=uninstrumented\nfun:__bid_divsd3=uninstrumented\nfun:__bid_divtd3=uninstrumented\nfun:__bid_eqdd2=uninstrumented\nfun:__bid_eqsd2=uninstrumented\nfun:__bid_eqtd2=uninstrumented\nfun:__bid_extendddtd2=uninstrumented\nfun:__bid_extendddtf=uninstrumented\nfun:__bid_extendddxf=uninstrumented\nfun:__bid_extenddfdd=uninstrumented\nfun:__bid_extenddftd=uninstrumented\nfun:__bid_extendsddd2=uninstrumented\nfun:__bid_extendsddf=uninstrumented\nfun:__bid_extendsdtd2=uninstrumented\nfun:__bid_extendsdtf=uninstrumented\nfun:__bid_extendsdxf=uninstrumented\nfun:__bid_extendsfdd=uninstrumented\nfun:__bid_extendsfsd=uninstrumented\nfun:__bid_extendsftd=uninstrumented\nfun:__bid_extendtftd=uninstrumented\nfun:__bid_extendxftd=uninstrumented\nfun:__bid_fixdddi=uninstrumented\nfun:__bid_fixddsi=uninstrumented\nfun:__bid_fixsddi=uninstrumented\nfun:__bid_fixsdsi=uninstrumented\nfun:__bid_fixtddi=uninstrumented\nfun:__bid_fixtdsi=uninstrumented\nfun:__bid_fixunsdddi=uninstrumented\nfun:__bid_fixunsddsi=uninstrumented\nfun:__bid_fixunssddi=uninstrumented\nfun:__bid_fixunssdsi=uninstrumented\nfun:__bid_fixunstddi=uninstrumented\nfun:__bid_fixunstdsi=uninstrumented\nfun:__bid_floatdidd=uninstrumented\nfun:__bid_floatdisd=uninstrumented\nfun:__bid_floatditd=uninstrumented\nfun:__bid_floatsidd=uninstrumented\nfun:__bid_floatsisd=uninstrumented\nfun:__bid_floatsitd=uninstrumented\nfun:__bid_floatunsdidd=uninstrumented\nfun:__bid_floatunsdisd=uninstrumented\nfun:__bid_floatunsditd=uninstrumented\nfun:__bid_floatunssidd=uninstrumented\nfun:__bid_floatunssisd=uninstrumented\nfun:__bid_floatunssitd=uninstrumented\nfun:__bid_gedd2=uninstrumented\nfun:__bid_gesd2=uninstrumented\nfun:__bid_getd2=uninstrumented\nfun:__bid_gtdd2=uninstrumented\nfun:__bid_gtsd2=uninstrumented\nfun:__bid_gttd2=uninstrumented\nfun:__bid_ledd2=uninstrumented\nfun:__bid_lesd2=uninstrumented\nfun:__bid_letd2=uninstrumented\nfun:__bid_ltdd2=uninstrumented\nfun:__bid_ltsd2=uninstrumented\nfun:__bid_lttd2=uninstrumented\nfun:__bid_muldd3=uninstrumented\nfun:__bid_mulsd3=uninstrumented\nfun:__bid_multd3=uninstrumented\nfun:__bid_nedd2=uninstrumented\nfun:__bid_nesd2=uninstrumented\nfun:__bid_netd2=uninstrumented\nfun:__bid_round128_19_38=uninstrumented\nfun:__bid_round192_39_57=uninstrumented\nfun:__bid_round256_58_76=uninstrumented\nfun:__bid_round64_2_18=uninstrumented\nfun:__bid_subdd3=uninstrumented\nfun:__bid_subsd3=uninstrumented\nfun:__bid_subtd3=uninstrumented\nfun:__bid_truncdddf=uninstrumented\nfun:__bid_truncddsd2=uninstrumented\nfun:__bid_truncddsf=uninstrumented\nfun:__bid_truncdfsd=uninstrumented\nfun:__bid_truncsdsf=uninstrumented\nfun:__bid_trunctddd2=uninstrumented\nfun:__bid_trunctddf=uninstrumented\nfun:__bid_trunctdsd2=uninstrumented\nfun:__bid_trunctdsf=uninstrumented\nfun:__bid_trunctdtf=uninstrumented\nfun:__bid_trunctdxf=uninstrumented\nfun:__bid_trunctfdd=uninstrumented\nfun:__bid_trunctfsd=uninstrumented\nfun:__bid_truncxfdd=uninstrumented\nfun:__bid_truncxfsd=uninstrumented\nfun:__bid_unorddd2=uninstrumented\nfun:__bid_unordsd2=uninstrumented\nfun:__bid_unordtd2=uninstrumented\nfun:__binary128_to_bid128=uninstrumented\nfun:__binary128_to_bid32=uninstrumented\nfun:__binary128_to_bid64=uninstrumented\nfun:__binary32_to_bid128=uninstrumented\nfun:__binary32_to_bid32=uninstrumented\nfun:__binary32_to_bid64=uninstrumented\nfun:__binary64_to_bid128=uninstrumented\nfun:__binary64_to_bid32=uninstrumented\nfun:__binary64_to_bid64=uninstrumented\nfun:__binary80_to_bid128=uninstrumented\nfun:__binary80_to_bid32=uninstrumented\nfun:__binary80_to_bid64=uninstrumented\nfun:__bsd_getpgrp=uninstrumented\nfun:__bswapdi2=uninstrumented\nfun:__bswapsi2=uninstrumented\nfun:__bzero=uninstrumented\nfun:__call_tls_dtors=uninstrumented\nfun:__chk_fail=uninstrumented\nfun:__clear_cache=uninstrumented\nfun:__clock_getcpuclockid=uninstrumented\nfun:__clock_getres=uninstrumented\nfun:__clock_gettime=uninstrumented\nfun:__clock_nanosleep=uninstrumented\nfun:__clock_settime=uninstrumented\nfun:__clog10=uninstrumented\nfun:__clog10f=uninstrumented\nfun:__clog10l=uninstrumented\nfun:__clone=uninstrumented\nfun:__close=uninstrumented\nfun:__clrsbdi2=uninstrumented\nfun:__clrsbti2=uninstrumented\nfun:__clzdi2=uninstrumented\nfun:__clzti2=uninstrumented\nfun:__cmpti2=uninstrumented\nfun:__cmsg_nxthdr=uninstrumented\nfun:__confstr_chk=uninstrumented\nfun:__connect=uninstrumented\nfun:__cosh_finite=uninstrumented\nfun:__coshf_finite=uninstrumented\nfun:__coshl_finite=uninstrumented\nfun:__cpu_indicator_init=uninstrumented\nfun:__create_ib_request=uninstrumented\nfun:__ctype_b_loc=uninstrumented\nfun:__ctype_get_mb_cur_max=uninstrumented\nfun:__ctype_init=uninstrumented\nfun:__ctype_tolower_loc=uninstrumented\nfun:__ctype_toupper_loc=uninstrumented\nfun:__ctzdi2=uninstrumented\nfun:__ctzti2=uninstrumented\nfun:__cxa_at_quick_exit=uninstrumented\nfun:__cxa_atexit=uninstrumented\nfun:__cxa_finalize=uninstrumented\nfun:__cxa_thread_atexit_impl=uninstrumented\nfun:__cyg_profile_func_enter=uninstrumented\nfun:__cyg_profile_func_exit=uninstrumented\nfun:__dcgettext=uninstrumented\nfun:__default_morecore=uninstrumented\nfun:__deregister_frame=uninstrumented\nfun:__deregister_frame_info=uninstrumented\nfun:__deregister_frame_info_bases=uninstrumented\nfun:__dfp_clear_except=uninstrumented\nfun:__dfp_get_round=uninstrumented\nfun:__dfp_raise_except=uninstrumented\nfun:__dfp_set_round=uninstrumented\nfun:__dfp_test_except=uninstrumented\nfun:__dgettext=uninstrumented\nfun:__divdc3=uninstrumented\nfun:__divsc3=uninstrumented\nfun:__divtc3=uninstrumented\nfun:__divtf3=uninstrumented\nfun:__divti3=uninstrumented\nfun:__divxc3=uninstrumented\nfun:__dn_comp=uninstrumented\nfun:__dn_count_labels=uninstrumented\nfun:__dn_expand=uninstrumented\nfun:__dn_skipname=uninstrumented\nfun:__do_niscall3=uninstrumented\nfun:__dprintf_chk=uninstrumented\nfun:__dup2=uninstrumented\nfun:__duplocale=uninstrumented\nfun:__emutls_get_address=uninstrumented\nfun:__emutls_register_common=uninstrumented\nfun:__enable_execute_stack=uninstrumented\nfun:__endmntent=uninstrumented\nfun:__eprintf=uninstrumented\nfun:__eqtf2=uninstrumented\nfun:__errno_location=uninstrumented\nfun:__exp10_finite=uninstrumented\nfun:__exp10f_finite=uninstrumented\nfun:__exp10l_finite=uninstrumented\nfun:__exp2_finite=uninstrumented\nfun:__exp2f_finite=uninstrumented\nfun:__exp2l_finite=uninstrumented\nfun:__exp_finite=uninstrumented\nfun:__expf_finite=uninstrumented\nfun:__expl_finite=uninstrumented\nfun:__extenddftf2=uninstrumented\nfun:__extendsftf2=uninstrumented\nfun:__extendxftf2=uninstrumented\nfun:__fbufsize=uninstrumented\nfun:__fcntl=uninstrumented\nfun:__fdelt_chk=uninstrumented\nfun:__fdelt_warn=uninstrumented\nfun:__fentry__=uninstrumented\nfun:__ffs=uninstrumented\nfun:__ffsdi2=uninstrumented\nfun:__ffsti2=uninstrumented\nfun:__fgets_chk=uninstrumented\nfun:__fgets_unlocked_chk=uninstrumented\nfun:__fgetws_chk=uninstrumented\nfun:__fgetws_unlocked_chk=uninstrumented\nfun:__finite=uninstrumented\nfun:__finitef=uninstrumented\nfun:__finitel=uninstrumented\nfun:__fixdfti=uninstrumented\nfun:__fixsfti=uninstrumented\nfun:__fixtfdi=uninstrumented\nfun:__fixtfsi=uninstrumented\nfun:__fixtfti=uninstrumented\nfun:__fixunsdfdi=uninstrumented\nfun:__fixunsdfti=uninstrumented\nfun:__fixunssfdi=uninstrumented\nfun:__fixunssfti=uninstrumented\nfun:__fixunstfdi=uninstrumented\nfun:__fixunstfsi=uninstrumented\nfun:__fixunstfti=uninstrumented\nfun:__fixunsxfdi=uninstrumented\nfun:__fixunsxfti=uninstrumented\nfun:__fixxfti=uninstrumented\nfun:__flbf=uninstrumented\nfun:__floatditf=uninstrumented\nfun:__floatsitf=uninstrumented\nfun:__floattidf=uninstrumented\nfun:__floattisf=uninstrumented\nfun:__floattitf=uninstrumented\nfun:__floattixf=uninstrumented\nfun:__floatunditf=uninstrumented\nfun:__floatunsitf=uninstrumented\nfun:__floatuntidf=uninstrumented\nfun:__floatuntisf=uninstrumented\nfun:__floatuntitf=uninstrumented\nfun:__floatuntixf=uninstrumented\nfun:__fmod_finite=uninstrumented\nfun:__fmodf_finite=uninstrumented\nfun:__fmodl_finite=uninstrumented\nfun:__follow_path=uninstrumented\nfun:__fork=uninstrumented\nfun:__fortify_fail=uninstrumented\nfun:__fp_nquery=uninstrumented\nfun:__fp_query=uninstrumented\nfun:__fp_resstat=uninstrumented\nfun:__fpclassify=uninstrumented\nfun:__fpclassifyf=uninstrumented\nfun:__fpclassifyl=uninstrumented\nfun:__fpending=uninstrumented\nfun:__fprintf_chk=uninstrumented\nfun:__fpurge=uninstrumented\nfun:__fread_chk=uninstrumented\nfun:__fread_unlocked_chk=uninstrumented\nfun:__freadable=uninstrumented\nfun:__freading=uninstrumented\nfun:__free_fdresult=uninstrumented\nfun:__freelocale=uninstrumented\nfun:__fsetlocking=uninstrumented\nfun:__fstat=uninstrumented\nfun:__fwprintf_chk=uninstrumented\nfun:__fwritable=uninstrumented\nfun:__fwriting=uninstrumented\nfun:__fxstat=uninstrumented\nfun:__fxstat64=uninstrumented\nfun:__fxstatat=uninstrumented\nfun:__fxstatat64=uninstrumented\nfun:__gai_sigqueue=uninstrumented\nfun:__gamma_r_finite=uninstrumented\nfun:__gammaf_r_finite=uninstrumented\nfun:__gammal_r_finite=uninstrumented\nfun:__gcc_bcmp=uninstrumented\nfun:__gcc_personality_v0=uninstrumented\nfun:__gconv_get_alias_db=uninstrumented\nfun:__gconv_get_cache=uninstrumented\nfun:__gconv_get_modules_db=uninstrumented\nfun:__generic_findstack=uninstrumented\nfun:__generic_morestack=uninstrumented\nfun:__generic_morestack_set_initial_sp=uninstrumented\nfun:__generic_releasestack=uninstrumented\nfun:__get_cpu_features=uninstrumented\nfun:__getauxval=uninstrumented\nfun:__getcwd_chk=uninstrumented\nfun:__getdelim=uninstrumented\nfun:__getdomainname_chk=uninstrumented\nfun:__getf2=uninstrumented\nfun:__getgroups_chk=uninstrumented\nfun:__gethostname_chk=uninstrumented\nfun:__getlogin_r_chk=uninstrumented\nfun:__getmntent_r=uninstrumented\nfun:__getpagesize=uninstrumented\nfun:__getpgid=uninstrumented\nfun:__getpid=uninstrumented\nfun:__gets_chk=uninstrumented\nfun:__gettimeofday=uninstrumented\nfun:__getwd_chk=uninstrumented\nfun:__gmtime_r=uninstrumented\nfun:__gttf2=uninstrumented\nfun:__h_errno_location=uninstrumented\nfun:__hostalias=uninstrumented\nfun:__hypot_finite=uninstrumented\nfun:__hypotf_finite=uninstrumented\nfun:__hypotl_finite=uninstrumented\nfun:__internal_endnetgrent=uninstrumented\nfun:__internal_getnetgrent_r=uninstrumented\nfun:__internal_setnetgrent=uninstrumented\nfun:__isalnum_l=uninstrumented\nfun:__isalpha_l=uninstrumented\nfun:__isascii_l=uninstrumented\nfun:__isblank_l=uninstrumented\nfun:__iscntrl_l=uninstrumented\nfun:__isctype=uninstrumented\nfun:__isdigit_l=uninstrumented\nfun:__isgraph_l=uninstrumented\nfun:__isinf=uninstrumented\nfun:__isinff=uninstrumented\nfun:__isinfl=uninstrumented\nfun:__islower_l=uninstrumented\nfun:__isnan=uninstrumented\nfun:__isnanf=uninstrumented\nfun:__isnanl=uninstrumented\nfun:__isoc99_fscanf=uninstrumented\nfun:__isoc99_fwscanf=uninstrumented\nfun:__isoc99_scanf=uninstrumented\nfun:__isoc99_sscanf=uninstrumented\nfun:__isoc99_swscanf=uninstrumented\nfun:__isoc99_vfscanf=uninstrumented\nfun:__isoc99_vfwscanf=uninstrumented\nfun:__isoc99_vscanf=uninstrumented\nfun:__isoc99_vsscanf=uninstrumented\nfun:__isoc99_vswscanf=uninstrumented\nfun:__isoc99_vwscanf=uninstrumented\nfun:__isoc99_wscanf=uninstrumented\nfun:__isprint_l=uninstrumented\nfun:__ispunct_l=uninstrumented\nfun:__issignaling=uninstrumented\nfun:__issignalingf=uninstrumented\nfun:__issignalingl=uninstrumented\nfun:__isspace_l=uninstrumented\nfun:__isupper_l=uninstrumented\nfun:__iswalnum_l=uninstrumented\nfun:__iswalpha_l=uninstrumented\nfun:__iswblank_l=uninstrumented\nfun:__iswcntrl_l=uninstrumented\nfun:__iswctype=uninstrumented\nfun:__iswctype_l=uninstrumented\nfun:__iswdigit_l=uninstrumented\nfun:__iswgraph_l=uninstrumented\nfun:__iswlower_l=uninstrumented\nfun:__iswprint_l=uninstrumented\nfun:__iswpunct_l=uninstrumented\nfun:__iswspace_l=uninstrumented\nfun:__iswupper_l=uninstrumented\nfun:__iswxdigit_l=uninstrumented\nfun:__isxdigit_l=uninstrumented\nfun:__ivaliduser=uninstrumented\nfun:__j0_finite=uninstrumented\nfun:__j0f_finite=uninstrumented\nfun:__j0l_finite=uninstrumented\nfun:__j1_finite=uninstrumented\nfun:__j1f_finite=uninstrumented\nfun:__j1l_finite=uninstrumented\nfun:__jn_finite=uninstrumented\nfun:__jnf_finite=uninstrumented\nfun:__jnl_finite=uninstrumented\nfun:__letf2=uninstrumented\nfun:__lgamma_r_finite=uninstrumented\nfun:__lgammaf_r_finite=uninstrumented\nfun:__lgammal_r_finite=uninstrumented\nfun:__libc_alloca_cutoff=uninstrumented\nfun:__libc_allocate_rtsig=uninstrumented\nfun:__libc_allocate_rtsig_private=uninstrumented\nfun:__libc_calloc=uninstrumented\nfun:__libc_clntudp_bufcreate=uninstrumented\nfun:__libc_csu_fini=uninstrumented\nfun:__libc_csu_init=uninstrumented\nfun:__libc_current_sigrtmax=uninstrumented\nfun:__libc_current_sigrtmax_private=uninstrumented\nfun:__libc_current_sigrtmin=uninstrumented\nfun:__libc_current_sigrtmin_private=uninstrumented\nfun:__libc_dl_error_tsd=uninstrumented\nfun:__libc_dlclose=uninstrumented\nfun:__libc_dlopen_mode=uninstrumented\nfun:__libc_dlsym=uninstrumented\nfun:__libc_fatal=uninstrumented\nfun:__libc_fork=uninstrumented\nfun:__libc_free=uninstrumented\nfun:__libc_freeres=uninstrumented\nfun:__libc_ifunc_impl_list=uninstrumented\nfun:__libc_init_first=uninstrumented\nfun:__libc_longjmp=uninstrumented\nfun:__libc_mallinfo=uninstrumented\nfun:__libc_malloc=uninstrumented\nfun:__libc_mallopt=uninstrumented\nfun:__libc_memalign=uninstrumented\nfun:__libc_pthread_init=uninstrumented\nfun:__libc_pvalloc=uninstrumented\nfun:__libc_pwrite=uninstrumented\nfun:__libc_realloc=uninstrumented\nfun:__libc_res_nquery=uninstrumented\nfun:__libc_res_nsearch=uninstrumented\nfun:__libc_rpc_getport=uninstrumented\nfun:__libc_sa_len=uninstrumented\nfun:__libc_secure_getenv=uninstrumented\nfun:__libc_siglongjmp=uninstrumented\nfun:__libc_start_main=uninstrumented\nfun:__libc_system=uninstrumented\nfun:__libc_thread_freeres=uninstrumented\nfun:__libc_valloc=uninstrumented\nfun:__loc_aton=uninstrumented\nfun:__loc_ntoa=uninstrumented\nfun:__log10_finite=uninstrumented\nfun:__log10f_finite=uninstrumented\nfun:__log10l_finite=uninstrumented\nfun:__log2_finite=uninstrumented\nfun:__log2f_finite=uninstrumented\nfun:__log2l_finite=uninstrumented\nfun:__log_finite=uninstrumented\nfun:__logf_finite=uninstrumented\nfun:__logl_finite=uninstrumented\nfun:__longjmp_chk=uninstrumented\nfun:__lseek=uninstrumented\nfun:__lshrti3=uninstrumented\nfun:__lstat=uninstrumented\nfun:__lttf2=uninstrumented\nfun:__lxstat=uninstrumented\nfun:__lxstat64=uninstrumented\nfun:__madvise=uninstrumented\nfun:__mbrlen=uninstrumented\nfun:__mbrtowc=uninstrumented\nfun:__mbsnrtowcs_chk=uninstrumented\nfun:__mbsrtowcs_chk=uninstrumented\nfun:__mbstowcs_chk=uninstrumented\nfun:__memcpy_chk=uninstrumented\nfun:__memmove_chk=uninstrumented\nfun:__mempcpy=uninstrumented\nfun:__mempcpy_chk=uninstrumented\nfun:__mempcpy_small=uninstrumented\nfun:__memset_chk=uninstrumented\nfun:__mknod=uninstrumented\nfun:__mktemp=uninstrumented\nfun:__modti3=uninstrumented\nfun:__monstartup=uninstrumented\nfun:__morestack=uninstrumented\nfun:__morestack_allocate_stack_space=uninstrumented\nfun:__morestack_block_signals=uninstrumented\nfun:__morestack_fail=uninstrumented\nfun:__morestack_get_guard=uninstrumented\nfun:__morestack_large_model=uninstrumented\nfun:__morestack_load_mmap=uninstrumented\nfun:__morestack_make_guard=uninstrumented\nfun:__morestack_non_split=uninstrumented\nfun:__morestack_release_segments=uninstrumented\nfun:__morestack_set_guard=uninstrumented\nfun:__morestack_unblock_signals=uninstrumented\nfun:__mq_open_2=uninstrumented\nfun:__muldc3=uninstrumented\nfun:__mulsc3=uninstrumented\nfun:__multc3=uninstrumented\nfun:__multf3=uninstrumented\nfun:__multi3=uninstrumented\nfun:__mulvdi3=uninstrumented\nfun:__mulvsi3=uninstrumented\nfun:__mulvti3=uninstrumented\nfun:__mulxc3=uninstrumented\nfun:__nanosleep=uninstrumented\nfun:__negtf2=uninstrumented\nfun:__negti2=uninstrumented\nfun:__negvdi2=uninstrumented\nfun:__negvsi2=uninstrumented\nfun:__negvti2=uninstrumented\nfun:__netf2=uninstrumented\nfun:__newlocale=uninstrumented\nfun:__nis_default_access=uninstrumented\nfun:__nis_default_group=uninstrumented\nfun:__nis_default_owner=uninstrumented\nfun:__nis_default_ttl=uninstrumented\nfun:__nis_finddirectory=uninstrumented\nfun:__nis_hash=uninstrumented\nfun:__nisbind_connect=uninstrumented\nfun:__nisbind_create=uninstrumented\nfun:__nisbind_destroy=uninstrumented\nfun:__nisbind_next=uninstrumented\nfun:__nl_langinfo_l=uninstrumented\nfun:__ns_get16=uninstrumented\nfun:__ns_get32=uninstrumented\nfun:__ns_name_ntop=uninstrumented\nfun:__ns_name_unpack=uninstrumented\nfun:__nss_configure_lookup=uninstrumented\nfun:__nss_database_lookup=uninstrumented\nfun:__nss_disable_nscd=uninstrumented\nfun:__nss_group_lookup=uninstrumented\nfun:__nss_group_lookup2=uninstrumented\nfun:__nss_hostname_digits_dots=uninstrumented\nfun:__nss_hosts_lookup=uninstrumented\nfun:__nss_hosts_lookup2=uninstrumented\nfun:__nss_lookup=uninstrumented\nfun:__nss_lookup_function=uninstrumented\nfun:__nss_next=uninstrumented\nfun:__nss_next2=uninstrumented\nfun:__nss_passwd_lookup=uninstrumented\nfun:__nss_passwd_lookup2=uninstrumented\nfun:__nss_services_lookup2=uninstrumented\nfun:__obstack_printf_chk=uninstrumented\nfun:__obstack_vprintf_chk=uninstrumented\nfun:__open=uninstrumented\nfun:__open64=uninstrumented\nfun:__open64_2=uninstrumented\nfun:__open_2=uninstrumented\nfun:__open_catalog=uninstrumented\nfun:__openat64_2=uninstrumented\nfun:__openat_2=uninstrumented\nfun:__overflow=uninstrumented\nfun:__p_cdname=uninstrumented\nfun:__p_cdnname=uninstrumented\nfun:__p_class=uninstrumented\nfun:__p_fqname=uninstrumented\nfun:__p_fqnname=uninstrumented\nfun:__p_option=uninstrumented\nfun:__p_query=uninstrumented\nfun:__p_rcode=uninstrumented\nfun:__p_secstodate=uninstrumented\nfun:__p_time=uninstrumented\nfun:__p_type=uninstrumented\nfun:__paritydi2=uninstrumented\nfun:__parityti2=uninstrumented\nfun:__pipe=uninstrumented\nfun:__poll=uninstrumented\nfun:__poll_chk=uninstrumented\nfun:__popcountdi2=uninstrumented\nfun:__popcountti2=uninstrumented\nfun:__posix_getopt=uninstrumented\nfun:__pow_finite=uninstrumented\nfun:__powf_finite=uninstrumented\nfun:__powidf2=uninstrumented\nfun:__powisf2=uninstrumented\nfun:__powitf2=uninstrumented\nfun:__powixf2=uninstrumented\nfun:__powl_finite=uninstrumented\nfun:__ppoll_chk=uninstrumented\nfun:__pread64=uninstrumented\nfun:__pread64_chk=uninstrumented\nfun:__pread_chk=uninstrumented\nfun:__prepare_niscall=uninstrumented\nfun:__printf_chk=uninstrumented\nfun:__printf_fp=uninstrumented\nfun:__profile_frequency=uninstrumented\nfun:__pthread_atfork=uninstrumented\nfun:__pthread_cleanup_routine=uninstrumented\nfun:__pthread_clock_gettime=uninstrumented\nfun:__pthread_clock_settime=uninstrumented\nfun:__pthread_get_minstack=uninstrumented\nfun:__pthread_getspecific=uninstrumented\nfun:__pthread_initialize_minimal=uninstrumented\nfun:__pthread_key_create=uninstrumented\nfun:__pthread_mutex_destroy=uninstrumented\nfun:__pthread_mutex_init=uninstrumented\nfun:__pthread_mutex_lock=uninstrumented\nfun:__pthread_mutex_trylock=uninstrumented\nfun:__pthread_mutex_unlock=uninstrumented\nfun:__pthread_mutexattr_destroy=uninstrumented\nfun:__pthread_mutexattr_init=uninstrumented\nfun:__pthread_mutexattr_settype=uninstrumented\nfun:__pthread_once=uninstrumented\nfun:__pthread_register_cancel=uninstrumented\nfun:__pthread_register_cancel_defer=uninstrumented\nfun:__pthread_rwlock_destroy=uninstrumented\nfun:__pthread_rwlock_init=uninstrumented\nfun:__pthread_rwlock_rdlock=uninstrumented\nfun:__pthread_rwlock_tryrdlock=uninstrumented\nfun:__pthread_rwlock_trywrlock=uninstrumented\nfun:__pthread_rwlock_unlock=uninstrumented\nfun:__pthread_rwlock_wrlock=uninstrumented\nfun:__pthread_setspecific=uninstrumented\nfun:__pthread_unregister_cancel=uninstrumented\nfun:__pthread_unregister_cancel_restore=uninstrumented\nfun:__pthread_unwind=uninstrumented\nfun:__pthread_unwind_next=uninstrumented\nfun:__ptsname_r_chk=uninstrumented\nfun:__putlong=uninstrumented\nfun:__putshort=uninstrumented\nfun:__pwrite64=uninstrumented\nfun:__rawmemchr=uninstrumented\nfun:__read=uninstrumented\nfun:__read_chk=uninstrumented\nfun:__readlink_chk=uninstrumented\nfun:__readlinkat_chk=uninstrumented\nfun:__realpath_chk=uninstrumented\nfun:__recv_chk=uninstrumented\nfun:__recvfrom_chk=uninstrumented\nfun:__register_atfork=uninstrumented\nfun:__register_frame=uninstrumented\nfun:__register_frame_info=uninstrumented\nfun:__register_frame_info_bases=uninstrumented\nfun:__register_frame_info_table=uninstrumented\nfun:__register_frame_info_table_bases=uninstrumented\nfun:__register_frame_table=uninstrumented\nfun:__remainder_finite=uninstrumented\nfun:__remainderf_finite=uninstrumented\nfun:__remainderl_finite=uninstrumented\nfun:__res_close=uninstrumented\nfun:__res_dnok=uninstrumented\nfun:__res_hnok=uninstrumented\nfun:__res_hostalias=uninstrumented\nfun:__res_iclose=uninstrumented\nfun:__res_init=uninstrumented\nfun:__res_isourserver=uninstrumented\nfun:__res_mailok=uninstrumented\nfun:__res_maybe_init=uninstrumented\nfun:__res_mkquery=uninstrumented\nfun:__res_nameinquery=uninstrumented\nfun:__res_nclose=uninstrumented\nfun:__res_ninit=uninstrumented\nfun:__res_nmkquery=uninstrumented\nfun:__res_nquery=uninstrumented\nfun:__res_nquerydomain=uninstrumented\nfun:__res_nsearch=uninstrumented\nfun:__res_nsend=uninstrumented\nfun:__res_ownok=uninstrumented\nfun:__res_queriesmatch=uninstrumented\nfun:__res_query=uninstrumented\nfun:__res_querydomain=uninstrumented\nfun:__res_randomid=uninstrumented\nfun:__res_search=uninstrumented\nfun:__res_send=uninstrumented\nfun:__res_state=uninstrumented\nfun:__rpc_thread_createerr=uninstrumented\nfun:__rpc_thread_svc_fdset=uninstrumented\nfun:__rpc_thread_svc_max_pollfd=uninstrumented\nfun:__rpc_thread_svc_pollfd=uninstrumented\nfun:__sbrk=uninstrumented\nfun:__scalb_finite=uninstrumented\nfun:__scalbf_finite=uninstrumented\nfun:__scalbl_finite=uninstrumented\nfun:__sched_cpualloc=uninstrumented\nfun:__sched_cpucount=uninstrumented\nfun:__sched_cpufree=uninstrumented\nfun:__sched_get_priority_max=uninstrumented\nfun:__sched_get_priority_min=uninstrumented\nfun:__sched_getparam=uninstrumented\nfun:__sched_getscheduler=uninstrumented\nfun:__sched_setscheduler=uninstrumented\nfun:__sched_yield=uninstrumented\nfun:__secure_getenv=uninstrumented\nfun:__select=uninstrumented\nfun:__send=uninstrumented\nfun:__sendmmsg=uninstrumented\nfun:__setmntent=uninstrumented\nfun:__setpgid=uninstrumented\nfun:__sfp_handle_exceptions=uninstrumented\nfun:__sigaction=uninstrumented\nfun:__sigaddset=uninstrumented\nfun:__sigdelset=uninstrumented\nfun:__sigismember=uninstrumented\nfun:__signbit=uninstrumented\nfun:__signbitf=uninstrumented\nfun:__signbitl=uninstrumented\nfun:__sigpause=uninstrumented\nfun:__sigsetjmp=uninstrumented\nfun:__sigsuspend=uninstrumented\nfun:__sinh_finite=uninstrumented\nfun:__sinhf_finite=uninstrumented\nfun:__sinhl_finite=uninstrumented\nfun:__snprintf_chk=uninstrumented\nfun:__splitstack_block_signals=uninstrumented\nfun:__splitstack_block_signals_context=uninstrumented\nfun:__splitstack_find=uninstrumented\nfun:__splitstack_find_context=uninstrumented\nfun:__splitstack_getcontext=uninstrumented\nfun:__splitstack_makecontext=uninstrumented\nfun:__splitstack_releasecontext=uninstrumented\nfun:__splitstack_resetcontext=uninstrumented\nfun:__splitstack_setcontext=uninstrumented\nfun:__sprintf_chk=uninstrumented\nfun:__sqrt_finite=uninstrumented\nfun:__sqrtf_finite=uninstrumented\nfun:__sqrtl_finite=uninstrumented\nfun:__stack_chk_fail=uninstrumented\nfun:__stack_chk_fail_local=uninstrumented\nfun:__stack_split_initialize=uninstrumented\nfun:__stat=uninstrumented\nfun:__statfs=uninstrumented\nfun:__stpcpy=uninstrumented\nfun:__stpcpy_chk=uninstrumented\nfun:__stpcpy_small=uninstrumented\nfun:__stpncpy=uninstrumented\nfun:__stpncpy_chk=uninstrumented\nfun:__strcasecmp=uninstrumented\nfun:__strcasecmp_l=uninstrumented\nfun:__strcasestr=uninstrumented\nfun:__strcat_chk=uninstrumented\nfun:__strcoll_l=uninstrumented\nfun:__strcpy_chk=uninstrumented\nfun:__strcpy_small=uninstrumented\nfun:__strcspn_c1=uninstrumented\nfun:__strcspn_c2=uninstrumented\nfun:__strcspn_c3=uninstrumented\nfun:__strdup=uninstrumented\nfun:__strerror_r=uninstrumented\nfun:__strfmon_l=uninstrumented\nfun:__strftime_l=uninstrumented\nfun:__strncasecmp_l=uninstrumented\nfun:__strncat_chk=uninstrumented\nfun:__strncpy_chk=uninstrumented\nfun:__strndup=uninstrumented\nfun:__strpbrk_c2=uninstrumented\nfun:__strpbrk_c3=uninstrumented\nfun:__strsep_1c=uninstrumented\nfun:__strsep_2c=uninstrumented\nfun:__strsep_3c=uninstrumented\nfun:__strsep_g=uninstrumented\nfun:__strspn_c1=uninstrumented\nfun:__strspn_c2=uninstrumented\nfun:__strspn_c3=uninstrumented\nfun:__strtod_internal=uninstrumented\nfun:__strtod_l=uninstrumented\nfun:__strtof_internal=uninstrumented\nfun:__strtof_l=uninstrumented\nfun:__strtok_r=uninstrumented\nfun:__strtok_r_1c=uninstrumented\nfun:__strtol_internal=uninstrumented\nfun:__strtol_l=uninstrumented\nfun:__strtold_internal=uninstrumented\nfun:__strtold_l=uninstrumented\nfun:__strtoll_internal=uninstrumented\nfun:__strtoll_l=uninstrumented\nfun:__strtoul_internal=uninstrumented\nfun:__strtoul_l=uninstrumented\nfun:__strtoull_internal=uninstrumented\nfun:__strtoull_l=uninstrumented\nfun:__strverscmp=uninstrumented\nfun:__strxfrm_l=uninstrumented\nfun:__subtf3=uninstrumented\nfun:__subvdi3=uninstrumented\nfun:__subvsi3=uninstrumented\nfun:__subvti3=uninstrumented\nfun:__swprintf_chk=uninstrumented\nfun:__sym_ntop=uninstrumented\nfun:__sym_ntos=uninstrumented\nfun:__sym_ston=uninstrumented\nfun:__sysconf=uninstrumented\nfun:__sysctl=uninstrumented\nfun:__syslog_chk=uninstrumented\nfun:__sysv_signal=uninstrumented\nfun:__tls_get_addr=uninstrumented\nfun:__toascii_l=uninstrumented\nfun:__tolower_l=uninstrumented\nfun:__toupper_l=uninstrumented\nfun:__towctrans=uninstrumented\nfun:__towctrans_l=uninstrumented\nfun:__towlower_l=uninstrumented\nfun:__towupper_l=uninstrumented\nfun:__trunctfdf2=uninstrumented\nfun:__trunctfsf2=uninstrumented\nfun:__trunctfxf2=uninstrumented\nfun:__ttyname_r_chk=uninstrumented\nfun:__ucmpti2=uninstrumented\nfun:__udiv_w_sdiv=uninstrumented\nfun:__udivmodti4=uninstrumented\nfun:__udivti3=uninstrumented\nfun:__uflow=uninstrumented\nfun:__umodti3=uninstrumented\nfun:__underflow=uninstrumented\nfun:__unordtf2=uninstrumented\nfun:__uselocale=uninstrumented\nfun:__vasprintf_chk=uninstrumented\nfun:__vdprintf_chk=uninstrumented\nfun:__vfork=uninstrumented\nfun:__vfprintf_chk=uninstrumented\nfun:__vfscanf=uninstrumented\nfun:__vfwprintf_chk=uninstrumented\nfun:__vprintf_chk=uninstrumented\nfun:__vsnprintf=uninstrumented\nfun:__vsnprintf_chk=uninstrumented\nfun:__vsprintf_chk=uninstrumented\nfun:__vsscanf=uninstrumented\nfun:__vswprintf_chk=uninstrumented\nfun:__vsyslog_chk=uninstrumented\nfun:__vwprintf_chk=uninstrumented\nfun:__wait=uninstrumented\nfun:__waitpid=uninstrumented\nfun:__warn_memset_zero_len=uninstrumented\nfun:__wcpcpy_chk=uninstrumented\nfun:__wcpncpy_chk=uninstrumented\nfun:__wcrtomb_chk=uninstrumented\nfun:__wcscasecmp_l=uninstrumented\nfun:__wcscat_chk=uninstrumented\nfun:__wcscoll_l=uninstrumented\nfun:__wcscpy_chk=uninstrumented\nfun:__wcsftime_l=uninstrumented\nfun:__wcsncasecmp_l=uninstrumented\nfun:__wcsncat_chk=uninstrumented\nfun:__wcsncpy_chk=uninstrumented\nfun:__wcsnrtombs_chk=uninstrumented\nfun:__wcsrtombs_chk=uninstrumented\nfun:__wcstod_internal=uninstrumented\nfun:__wcstod_l=uninstrumented\nfun:__wcstof_internal=uninstrumented\nfun:__wcstof_l=uninstrumented\nfun:__wcstol_internal=uninstrumented\nfun:__wcstol_l=uninstrumented\nfun:__wcstold_internal=uninstrumented\nfun:__wcstold_l=uninstrumented\nfun:__wcstoll_internal=uninstrumented\nfun:__wcstoll_l=uninstrumented\nfun:__wcstombs_chk=uninstrumented\nfun:__wcstoul_internal=uninstrumented\nfun:__wcstoul_l=uninstrumented\nfun:__wcstoull_internal=uninstrumented\nfun:__wcstoull_l=uninstrumented\nfun:__wcsxfrm_l=uninstrumented\nfun:__wctomb_chk=uninstrumented\nfun:__wctrans_l=uninstrumented\nfun:__wctype_l=uninstrumented\nfun:__wmemcpy_chk=uninstrumented\nfun:__wmemmove_chk=uninstrumented\nfun:__wmempcpy_chk=uninstrumented\nfun:__wmemset_chk=uninstrumented\nfun:__woverflow=uninstrumented\nfun:__wprintf_chk=uninstrumented\nfun:__wrap_pthread_create=uninstrumented\nfun:__write=uninstrumented\nfun:__wuflow=uninstrumented\nfun:__wunderflow=uninstrumented\nfun:__xmknod=uninstrumented\nfun:__xmknodat=uninstrumented\nfun:__xpg_basename=uninstrumented\nfun:__xpg_sigpause=uninstrumented\nfun:__xpg_strerror_r=uninstrumented\nfun:__xstat=uninstrumented\nfun:__xstat64=uninstrumented\nfun:__y0_finite=uninstrumented\nfun:__y0f_finite=uninstrumented\nfun:__y0l_finite=uninstrumented\nfun:__y1_finite=uninstrumented\nfun:__y1f_finite=uninstrumented\nfun:__y1l_finite=uninstrumented\nfun:__yn_finite=uninstrumented\nfun:__ynf_finite=uninstrumented\nfun:__ynl_finite=uninstrumented\nfun:__yp_check=uninstrumented\nfun:_authenticate=uninstrumented\nfun:_dl_addr=uninstrumented\nfun:_dl_allocate_tls=uninstrumented\nfun:_dl_allocate_tls_init=uninstrumented\nfun:_dl_deallocate_tls=uninstrumented\nfun:_dl_debug_state=uninstrumented\nfun:_dl_find_dso_for_object=uninstrumented\nfun:_dl_get_tls_static_info=uninstrumented\nfun:_dl_make_stack_executable=uninstrumented\nfun:_dl_mcount=uninstrumented\nfun:_dl_mcount_wrapper=uninstrumented\nfun:_dl_mcount_wrapper_check=uninstrumented\nfun:_dl_rtld_di_serinfo=uninstrumented\nfun:_dl_sym=uninstrumented\nfun:_dl_tls_setup=uninstrumented\nfun:_dl_vsym=uninstrumented\nfun:_exit=uninstrumented\nfun:_flushlbf=uninstrumented\nfun:_gethtbyaddr=uninstrumented\nfun:_gethtbyname=uninstrumented\nfun:_gethtbyname2=uninstrumented\nfun:_gethtent=uninstrumented\nfun:_getlong=uninstrumented\nfun:_getshort=uninstrumented\nfun:_longjmp=uninstrumented\nfun:_mcleanup=uninstrumented\nfun:_mcount=uninstrumented\nfun:_nsl_default_nss=uninstrumented\nfun:_nss_files_parse_grent=uninstrumented\nfun:_nss_files_parse_pwent=uninstrumented\nfun:_nss_files_parse_sgent=uninstrumented\nfun:_nss_files_parse_spent=uninstrumented\nfun:_obstack_allocated_p=uninstrumented\nfun:_obstack_begin=uninstrumented\nfun:_obstack_begin_1=uninstrumented\nfun:_obstack_free=uninstrumented\nfun:_obstack_memory_used=uninstrumented\nfun:_obstack_newchunk=uninstrumented\nfun:_pthread_cleanup_pop=uninstrumented\nfun:_pthread_cleanup_pop_restore=uninstrumented\nfun:_pthread_cleanup_push=uninstrumented\nfun:_pthread_cleanup_push_defer=uninstrumented\nfun:_rpc_dtablesize=uninstrumented\nfun:_seterr_reply=uninstrumented\nfun:_sethtent=uninstrumented\nfun:_setjmp=uninstrumented\nfun:_tolower=uninstrumented\nfun:_toupper=uninstrumented\nfun:_xdr_ib_request=uninstrumented\nfun:_xdr_nis_result=uninstrumented\nfun:a64l=uninstrumented\nfun:abort=uninstrumented\nfun:abs=uninstrumented\nfun:accept=uninstrumented\nfun:accept4=uninstrumented\nfun:access=uninstrumented\nfun:acct=uninstrumented\nfun:acos=uninstrumented\nfun:acosf=uninstrumented\nfun:acosh=uninstrumented\nfun:acoshf=uninstrumented\nfun:acoshl=uninstrumented\nfun:acosl=uninstrumented\nfun:addmntent=uninstrumented\nfun:addseverity=uninstrumented\nfun:adjtime=uninstrumented\nfun:adjtimex=uninstrumented\nfun:advance=uninstrumented\nfun:aio_cancel=uninstrumented\nfun:aio_cancel64=uninstrumented\nfun:aio_error=uninstrumented\nfun:aio_error64=uninstrumented\nfun:aio_fsync=uninstrumented\nfun:aio_fsync64=uninstrumented\nfun:aio_init=uninstrumented\nfun:aio_read=uninstrumented\nfun:aio_read64=uninstrumented\nfun:aio_return=uninstrumented\nfun:aio_return64=uninstrumented\nfun:aio_suspend=uninstrumented\nfun:aio_suspend64=uninstrumented\nfun:aio_write=uninstrumented\nfun:aio_write64=uninstrumented\nfun:alarm=uninstrumented\nfun:aligned_alloc=uninstrumented\nfun:alphasort=uninstrumented\nfun:alphasort64=uninstrumented\nfun:arch_prctl=uninstrumented\nfun:argp_error=uninstrumented\nfun:argp_failure=uninstrumented\nfun:argp_help=uninstrumented\nfun:argp_parse=uninstrumented\nfun:argp_state_help=uninstrumented\nfun:argp_usage=uninstrumented\nfun:argz_add=uninstrumented\nfun:argz_add_sep=uninstrumented\nfun:argz_append=uninstrumented\nfun:argz_count=uninstrumented\nfun:argz_create=uninstrumented\nfun:argz_create_sep=uninstrumented\nfun:argz_delete=uninstrumented\nfun:argz_extract=uninstrumented\nfun:argz_insert=uninstrumented\nfun:argz_next=uninstrumented\nfun:argz_replace=uninstrumented\nfun:argz_stringify=uninstrumented\nfun:asctime=uninstrumented\nfun:asctime_r=uninstrumented\nfun:asin=uninstrumented\nfun:asinf=uninstrumented\nfun:asinh=uninstrumented\nfun:asinhf=uninstrumented\nfun:asinhl=uninstrumented\nfun:asinl=uninstrumented\nfun:asprintf=uninstrumented\nfun:at_quick_exit=uninstrumented\nfun:atan=uninstrumented\nfun:atan2=uninstrumented\nfun:atan2f=uninstrumented\nfun:atan2l=uninstrumented\nfun:atanf=uninstrumented\nfun:atanh=uninstrumented\nfun:atanhf=uninstrumented\nfun:atanhl=uninstrumented\nfun:atanl=uninstrumented\nfun:atexit=uninstrumented\nfun:atof=uninstrumented\nfun:atoi=uninstrumented\nfun:atol=uninstrumented\nfun:atoll=uninstrumented\nfun:authdes_create=uninstrumented\nfun:authdes_getucred=uninstrumented\nfun:authdes_pk_create=uninstrumented\nfun:authnone_create=uninstrumented\nfun:authunix_create=uninstrumented\nfun:authunix_create_default=uninstrumented\nfun:backtrace=uninstrumented\nfun:backtrace_symbols=uninstrumented\nfun:backtrace_symbols_fd=uninstrumented\nfun:basename=uninstrumented\nfun:bcmp=uninstrumented\nfun:bcopy=uninstrumented\nfun:bdflush=uninstrumented\nfun:bind=uninstrumented\nfun:bind_textdomain_codeset=uninstrumented\nfun:bindresvport=uninstrumented\nfun:bindtextdomain=uninstrumented\nfun:brk=uninstrumented\nfun:bsd_signal=uninstrumented\nfun:bsearch=uninstrumented\nfun:btowc=uninstrumented\nfun:bzero=uninstrumented\nfun:c16rtomb=uninstrumented\nfun:c32rtomb=uninstrumented\nfun:cabs=uninstrumented\nfun:cabsf=uninstrumented\nfun:cabsl=uninstrumented\nfun:cacos=uninstrumented\nfun:cacosf=uninstrumented\nfun:cacosh=uninstrumented\nfun:cacoshf=uninstrumented\nfun:cacoshl=uninstrumented\nfun:cacosl=uninstrumented\nfun:calloc=uninstrumented\nfun:callrpc=uninstrumented\nfun:canonicalize_file_name=uninstrumented\nfun:capget=uninstrumented\nfun:capset=uninstrumented\nfun:carg=uninstrumented\nfun:cargf=uninstrumented\nfun:cargl=uninstrumented\nfun:casin=uninstrumented\nfun:casinf=uninstrumented\nfun:casinh=uninstrumented\nfun:casinhf=uninstrumented\nfun:casinhl=uninstrumented\nfun:casinl=uninstrumented\nfun:catan=uninstrumented\nfun:catanf=uninstrumented\nfun:catanh=uninstrumented\nfun:catanhf=uninstrumented\nfun:catanhl=uninstrumented\nfun:catanl=uninstrumented\nfun:catclose=uninstrumented\nfun:catgets=uninstrumented\nfun:catopen=uninstrumented\nfun:cbc_crypt=uninstrumented\nfun:cbrt=uninstrumented\nfun:cbrtf=uninstrumented\nfun:cbrtl=uninstrumented\nfun:ccos=uninstrumented\nfun:ccosf=uninstrumented\nfun:ccosh=uninstrumented\nfun:ccoshf=uninstrumented\nfun:ccoshl=uninstrumented\nfun:ccosl=uninstrumented\nfun:ceil=uninstrumented\nfun:ceilf=uninstrumented\nfun:ceill=uninstrumented\nfun:cexp=uninstrumented\nfun:cexpf=uninstrumented\nfun:cexpl=uninstrumented\nfun:cfgetispeed=uninstrumented\nfun:cfgetospeed=uninstrumented\nfun:cfmakeraw=uninstrumented\nfun:cfree=uninstrumented\nfun:cfsetispeed=uninstrumented\nfun:cfsetospeed=uninstrumented\nfun:cfsetspeed=uninstrumented\nfun:chdir=uninstrumented\nfun:chflags=uninstrumented\nfun:chmod=uninstrumented\nfun:chown=uninstrumented\nfun:chroot=uninstrumented\nfun:cimag=uninstrumented\nfun:cimagf=uninstrumented\nfun:cimagl=uninstrumented\nfun:clearenv=uninstrumented\nfun:clearerr=uninstrumented\nfun:clearerr_unlocked=uninstrumented\nfun:clnt_broadcast=uninstrumented\nfun:clnt_create=uninstrumented\nfun:clnt_pcreateerror=uninstrumented\nfun:clnt_perrno=uninstrumented\nfun:clnt_perror=uninstrumented\nfun:clnt_spcreateerror=uninstrumented\nfun:clnt_sperrno=uninstrumented\nfun:clnt_sperror=uninstrumented\nfun:clntraw_create=uninstrumented\nfun:clnttcp_create=uninstrumented\nfun:clntudp_bufcreate=uninstrumented\nfun:clntudp_create=uninstrumented\nfun:clntunix_create=uninstrumented\nfun:clock=uninstrumented\nfun:clock_adjtime=uninstrumented\nfun:clock_getcpuclockid=uninstrumented\nfun:clock_getres=uninstrumented\nfun:clock_gettime=uninstrumented\nfun:clock_nanosleep=uninstrumented\nfun:clock_settime=uninstrumented\nfun:clog=uninstrumented\nfun:clog10=uninstrumented\nfun:clog10f=uninstrumented\nfun:clog10l=uninstrumented\nfun:clogf=uninstrumented\nfun:clogl=uninstrumented\nfun:clone=uninstrumented\nfun:close=uninstrumented\nfun:closedir=uninstrumented\nfun:closelog=uninstrumented\nfun:confstr=uninstrumented\nfun:conj=uninstrumented\nfun:conjf=uninstrumented\nfun:conjl=uninstrumented\nfun:connect=uninstrumented\nfun:copysign=uninstrumented\nfun:copysignf=uninstrumented\nfun:copysignl=uninstrumented\nfun:cos=uninstrumented\nfun:cosf=uninstrumented\nfun:cosh=uninstrumented\nfun:coshf=uninstrumented\nfun:coshl=uninstrumented\nfun:cosl=uninstrumented\nfun:cpow=uninstrumented\nfun:cpowf=uninstrumented\nfun:cpowl=uninstrumented\nfun:cproj=uninstrumented\nfun:cprojf=uninstrumented\nfun:cprojl=uninstrumented\nfun:creal=uninstrumented\nfun:crealf=uninstrumented\nfun:creall=uninstrumented\nfun:creat=uninstrumented\nfun:creat64=uninstrumented\nfun:create_module=uninstrumented\nfun:crypt=uninstrumented\nfun:crypt_r=uninstrumented\nfun:csin=uninstrumented\nfun:csinf=uninstrumented\nfun:csinh=uninstrumented\nfun:csinhf=uninstrumented\nfun:csinhl=uninstrumented\nfun:csinl=uninstrumented\nfun:csqrt=uninstrumented\nfun:csqrtf=uninstrumented\nfun:csqrtl=uninstrumented\nfun:ctan=uninstrumented\nfun:ctanf=uninstrumented\nfun:ctanh=uninstrumented\nfun:ctanhf=uninstrumented\nfun:ctanhl=uninstrumented\nfun:ctanl=uninstrumented\nfun:ctermid=uninstrumented\nfun:ctime=uninstrumented\nfun:ctime_r=uninstrumented\nfun:cuserid=uninstrumented\nfun:daemon=uninstrumented\nfun:dcgettext=uninstrumented\nfun:dcngettext=uninstrumented\nfun:delete_module=uninstrumented\nfun:des_setparity=uninstrumented\nfun:dgettext=uninstrumented\nfun:difftime=uninstrumented\nfun:dirfd=uninstrumented\nfun:dirname=uninstrumented\nfun:div=uninstrumented\nfun:dl_iterate_phdr=uninstrumented\nfun:dladdr=uninstrumented\nfun:dladdr1=uninstrumented\nfun:dlclose=uninstrumented\nfun:dlerror=uninstrumented\nfun:dlinfo=uninstrumented\nfun:dlmopen=uninstrumented\nfun:dlopen=uninstrumented\nfun:dlsym=uninstrumented\nfun:dlvsym=uninstrumented\nfun:dngettext=uninstrumented\nfun:dprintf=uninstrumented\nfun:drand48=uninstrumented\nfun:drand48_r=uninstrumented\nfun:drem=uninstrumented\nfun:dremf=uninstrumented\nfun:dreml=uninstrumented\nfun:dup=uninstrumented\nfun:dup2=uninstrumented\nfun:dup3=uninstrumented\nfun:duplocale=uninstrumented\nfun:dysize=uninstrumented\nfun:eaccess=uninstrumented\nfun:ecb_crypt=uninstrumented\nfun:ecvt=uninstrumented\nfun:ecvt_r=uninstrumented\nfun:encrypt=uninstrumented\nfun:encrypt_r=uninstrumented\nfun:endaliasent=uninstrumented\nfun:endfsent=uninstrumented\nfun:endgrent=uninstrumented\nfun:endhostent=uninstrumented\nfun:endmntent=uninstrumented\nfun:endnetent=uninstrumented\nfun:endnetgrent=uninstrumented\nfun:endprotoent=uninstrumented\nfun:endpwent=uninstrumented\nfun:endrpcent=uninstrumented\nfun:endservent=uninstrumented\nfun:endsgent=uninstrumented\nfun:endspent=uninstrumented\nfun:endttyent=uninstrumented\nfun:endusershell=uninstrumented\nfun:endutent=uninstrumented\nfun:endutxent=uninstrumented\nfun:envz_add=uninstrumented\nfun:envz_entry=uninstrumented\nfun:envz_get=uninstrumented\nfun:envz_merge=uninstrumented\nfun:envz_remove=uninstrumented\nfun:envz_strip=uninstrumented\nfun:epoll_create=uninstrumented\nfun:epoll_create1=uninstrumented\nfun:epoll_ctl=uninstrumented\nfun:epoll_pwait=uninstrumented\nfun:epoll_wait=uninstrumented\nfun:erand48=uninstrumented\nfun:erand48_r=uninstrumented\nfun:erf=uninstrumented\nfun:erfc=uninstrumented\nfun:erfcf=uninstrumented\nfun:erfcl=uninstrumented\nfun:erff=uninstrumented\nfun:erfl=uninstrumented\nfun:err=uninstrumented\nfun:error=uninstrumented\nfun:error_at_line=uninstrumented\nfun:errx=uninstrumented\nfun:ether_aton=uninstrumented\nfun:ether_aton_r=uninstrumented\nfun:ether_hostton=uninstrumented\nfun:ether_line=uninstrumented\nfun:ether_ntoa=uninstrumented\nfun:ether_ntoa_r=uninstrumented\nfun:ether_ntohost=uninstrumented\nfun:euidaccess=uninstrumented\nfun:eventfd=uninstrumented\nfun:eventfd_read=uninstrumented\nfun:eventfd_write=uninstrumented\nfun:execl=uninstrumented\nfun:execle=uninstrumented\nfun:execlp=uninstrumented\nfun:execv=uninstrumented\nfun:execve=uninstrumented\nfun:execvp=uninstrumented\nfun:execvpe=uninstrumented\nfun:exit=uninstrumented\nfun:exp=uninstrumented\nfun:exp10=uninstrumented\nfun:exp10f=uninstrumented\nfun:exp10l=uninstrumented\nfun:exp2=uninstrumented\nfun:exp2f=uninstrumented\nfun:exp2l=uninstrumented\nfun:expf=uninstrumented\nfun:expl=uninstrumented\nfun:expm1=uninstrumented\nfun:expm1f=uninstrumented\nfun:expm1l=uninstrumented\nfun:fabs=uninstrumented\nfun:fabsf=uninstrumented\nfun:fabsl=uninstrumented\nfun:faccessat=uninstrumented\nfun:fallocate=uninstrumented\nfun:fallocate64=uninstrumented\nfun:fanotify_init=uninstrumented\nfun:fanotify_mark=uninstrumented\nfun:fattach=uninstrumented\nfun:fchdir=uninstrumented\nfun:fchflags=uninstrumented\nfun:fchmod=uninstrumented\nfun:fchmodat=uninstrumented\nfun:fchown=uninstrumented\nfun:fchownat=uninstrumented\nfun:fclose=uninstrumented\nfun:fcloseall=uninstrumented\nfun:fcntl=uninstrumented\nfun:fcrypt=uninstrumented\nfun:fcvt=uninstrumented\nfun:fcvt_r=uninstrumented\nfun:fdatasync=uninstrumented\nfun:fdetach=uninstrumented\nfun:fdim=uninstrumented\nfun:fdimf=uninstrumented\nfun:fdiml=uninstrumented\nfun:fdopen=uninstrumented\nfun:fdopendir=uninstrumented\nfun:feclearexcept=uninstrumented\nfun:fedisableexcept=uninstrumented\nfun:feenableexcept=uninstrumented\nfun:fegetenv=uninstrumented\nfun:fegetexcept=uninstrumented\nfun:fegetexceptflag=uninstrumented\nfun:fegetround=uninstrumented\nfun:feholdexcept=uninstrumented\nfun:feof=uninstrumented\nfun:feof_unlocked=uninstrumented\nfun:feraiseexcept=uninstrumented\nfun:ferror=uninstrumented\nfun:ferror_unlocked=uninstrumented\nfun:fesetenv=uninstrumented\nfun:fesetexceptflag=uninstrumented\nfun:fesetround=uninstrumented\nfun:fetestexcept=uninstrumented\nfun:feupdateenv=uninstrumented\nfun:fexecve=uninstrumented\nfun:fflush=uninstrumented\nfun:fflush_unlocked=uninstrumented\nfun:ffs=uninstrumented\nfun:ffsl=uninstrumented\nfun:ffsll=uninstrumented\nfun:fgetc=uninstrumented\nfun:fgetc_unlocked=uninstrumented\nfun:fgetgrent=uninstrumented\nfun:fgetgrent_r=uninstrumented\nfun:fgetpos=uninstrumented\nfun:fgetpos64=uninstrumented\nfun:fgetpwent=uninstrumented\nfun:fgetpwent_r=uninstrumented\nfun:fgets=uninstrumented\nfun:fgets_unlocked=uninstrumented\nfun:fgetsgent=uninstrumented\nfun:fgetsgent_r=uninstrumented\nfun:fgetspent=uninstrumented\nfun:fgetspent_r=uninstrumented\nfun:fgetwc=uninstrumented\nfun:fgetwc_unlocked=uninstrumented\nfun:fgetws=uninstrumented\nfun:fgetws_unlocked=uninstrumented\nfun:fgetxattr=uninstrumented\nfun:fileno=uninstrumented\nfun:fileno_unlocked=uninstrumented\nfun:finite=uninstrumented\nfun:finitef=uninstrumented\nfun:finitel=uninstrumented\nfun:flistxattr=uninstrumented\nfun:flock=uninstrumented\nfun:flockfile=uninstrumented\nfun:floor=uninstrumented\nfun:floorf=uninstrumented\nfun:floorl=uninstrumented\nfun:fma=uninstrumented\nfun:fmaf=uninstrumented\nfun:fmal=uninstrumented\nfun:fmax=uninstrumented\nfun:fmaxf=uninstrumented\nfun:fmaxl=uninstrumented\nfun:fmemopen=uninstrumented\nfun:fmin=uninstrumented\nfun:fminf=uninstrumented\nfun:fminl=uninstrumented\nfun:fmod=uninstrumented\nfun:fmodf=uninstrumented\nfun:fmodl=uninstrumented\nfun:fmtmsg=uninstrumented\nfun:fnmatch=uninstrumented\nfun:fopen=uninstrumented\nfun:fopen64=uninstrumented\nfun:fopencookie=uninstrumented\nfun:fork=uninstrumented\nfun:forkpty=uninstrumented\nfun:fpathconf=uninstrumented\nfun:fprintf=uninstrumented\nfun:fputc=uninstrumented\nfun:fputc_unlocked=uninstrumented\nfun:fputs=uninstrumented\nfun:fputs_unlocked=uninstrumented\nfun:fputwc=uninstrumented\nfun:fputwc_unlocked=uninstrumented\nfun:fputws=uninstrumented\nfun:fputws_unlocked=uninstrumented\nfun:fread=uninstrumented\nfun:fread_unlocked=uninstrumented\nfun:free=uninstrumented\nfun:freeaddrinfo=uninstrumented\nfun:freeifaddrs=uninstrumented\nfun:freelocale=uninstrumented\nfun:fremovexattr=uninstrumented\nfun:freopen=uninstrumented\nfun:freopen64=uninstrumented\nfun:frexp=uninstrumented\nfun:frexpf=uninstrumented\nfun:frexpl=uninstrumented\nfun:fscanf=uninstrumented\nfun:fseek=uninstrumented\nfun:fseeko=uninstrumented\nfun:fseeko64=uninstrumented\nfun:fsetpos=uninstrumented\nfun:fsetpos64=uninstrumented\nfun:fsetxattr=uninstrumented\nfun:fstat=uninstrumented\nfun:fstat64=uninstrumented\nfun:fstatat=uninstrumented\nfun:fstatat64=uninstrumented\nfun:fstatfs=uninstrumented\nfun:fstatfs64=uninstrumented\nfun:fstatvfs=uninstrumented\nfun:fstatvfs64=uninstrumented\nfun:fsync=uninstrumented\nfun:ftell=uninstrumented\nfun:ftello=uninstrumented\nfun:ftello64=uninstrumented\nfun:ftime=uninstrumented\nfun:ftok=uninstrumented\nfun:ftruncate=uninstrumented\nfun:ftruncate64=uninstrumented\nfun:ftrylockfile=uninstrumented\nfun:fts_children=uninstrumented\nfun:fts_close=uninstrumented\nfun:fts_open=uninstrumented\nfun:fts_read=uninstrumented\nfun:fts_set=uninstrumented\nfun:ftw=uninstrumented\nfun:ftw64=uninstrumented\nfun:funlockfile=uninstrumented\nfun:futimens=uninstrumented\nfun:futimes=uninstrumented\nfun:futimesat=uninstrumented\nfun:fwide=uninstrumented\nfun:fwprintf=uninstrumented\nfun:fwrite=uninstrumented\nfun:fwrite_unlocked=uninstrumented\nfun:fwscanf=uninstrumented\nfun:gai_cancel=uninstrumented\nfun:gai_error=uninstrumented\nfun:gai_strerror=uninstrumented\nfun:gai_suspend=uninstrumented\nfun:gamma=uninstrumented\nfun:gammaf=uninstrumented\nfun:gammal=uninstrumented\nfun:gcvt=uninstrumented\nfun:get_avphys_pages=uninstrumented\nfun:get_current_dir_name=uninstrumented\nfun:get_kernel_syms=uninstrumented\nfun:get_myaddress=uninstrumented\nfun:get_nprocs=uninstrumented\nfun:get_nprocs_conf=uninstrumented\nfun:get_phys_pages=uninstrumented\nfun:getaddrinfo=uninstrumented\nfun:getaddrinfo_a=uninstrumented\nfun:getaliasbyname=uninstrumented\nfun:getaliasbyname_r=uninstrumented\nfun:getaliasent=uninstrumented\nfun:getaliasent_r=uninstrumented\nfun:getauxval=uninstrumented\nfun:getc=uninstrumented\nfun:getc_unlocked=uninstrumented\nfun:getchar=uninstrumented\nfun:getchar_unlocked=uninstrumented\nfun:getcontext=uninstrumented\nfun:getcwd=uninstrumented\nfun:getdate=uninstrumented\nfun:getdate_r=uninstrumented\nfun:getdelim=uninstrumented\nfun:getdirentries=uninstrumented\nfun:getdirentries64=uninstrumented\nfun:getdomainname=uninstrumented\nfun:getdtablesize=uninstrumented\nfun:getegid=uninstrumented\nfun:getenv=uninstrumented\nfun:geteuid=uninstrumented\nfun:getfsent=uninstrumented\nfun:getfsfile=uninstrumented\nfun:getfsspec=uninstrumented\nfun:getgid=uninstrumented\nfun:getgrent=uninstrumented\nfun:getgrent_r=uninstrumented\nfun:getgrgid=uninstrumented\nfun:getgrgid_r=uninstrumented\nfun:getgrnam=uninstrumented\nfun:getgrnam_r=uninstrumented\nfun:getgrouplist=uninstrumented\nfun:getgroups=uninstrumented\nfun:gethostbyaddr=uninstrumented\nfun:gethostbyaddr_r=uninstrumented\nfun:gethostbyname=uninstrumented\nfun:gethostbyname2=uninstrumented\nfun:gethostbyname2_r=uninstrumented\nfun:gethostbyname_r=uninstrumented\nfun:gethostent=uninstrumented\nfun:gethostent_r=uninstrumented\nfun:gethostid=uninstrumented\nfun:gethostname=uninstrumented\nfun:getifaddrs=uninstrumented\nfun:getipv4sourcefilter=uninstrumented\nfun:getitimer=uninstrumented\nfun:getline=uninstrumented\nfun:getloadavg=uninstrumented\nfun:getlogin=uninstrumented\nfun:getlogin_r=uninstrumented\nfun:getmntent=uninstrumented\nfun:getmntent_r=uninstrumented\nfun:getmsg=uninstrumented\nfun:getnameinfo=uninstrumented\nfun:getnetbyaddr=uninstrumented\nfun:getnetbyaddr_r=uninstrumented\nfun:getnetbyname=uninstrumented\nfun:getnetbyname_r=uninstrumented\nfun:getnetent=uninstrumented\nfun:getnetent_r=uninstrumented\nfun:getnetgrent=uninstrumented\nfun:getnetgrent_r=uninstrumented\nfun:getnetname=uninstrumented\nfun:getopt=uninstrumented\nfun:getopt_long=uninstrumented\nfun:getopt_long_only=uninstrumented\nfun:getpagesize=uninstrumented\nfun:getpass=uninstrumented\nfun:getpeername=uninstrumented\nfun:getpgid=uninstrumented\nfun:getpgrp=uninstrumented\nfun:getpid=uninstrumented\nfun:getpmsg=uninstrumented\nfun:getppid=uninstrumented\nfun:getpriority=uninstrumented\nfun:getprotobyname=uninstrumented\nfun:getprotobyname_r=uninstrumented\nfun:getprotobynumber=uninstrumented\nfun:getprotobynumber_r=uninstrumented\nfun:getprotoent=uninstrumented\nfun:getprotoent_r=uninstrumented\nfun:getpt=uninstrumented\nfun:getpublickey=uninstrumented\nfun:getpw=uninstrumented\nfun:getpwent=uninstrumented\nfun:getpwent_r=uninstrumented\nfun:getpwnam=uninstrumented\nfun:getpwnam_r=uninstrumented\nfun:getpwuid=uninstrumented\nfun:getpwuid_r=uninstrumented\nfun:getresgid=uninstrumented\nfun:getresuid=uninstrumented\nfun:getrlimit=uninstrumented\nfun:getrlimit64=uninstrumented\nfun:getrpcbyname=uninstrumented\nfun:getrpcbyname_r=uninstrumented\nfun:getrpcbynumber=uninstrumented\nfun:getrpcbynumber_r=uninstrumented\nfun:getrpcent=uninstrumented\nfun:getrpcent_r=uninstrumented\nfun:getrpcport=uninstrumented\nfun:getrusage=uninstrumented\nfun:gets=uninstrumented\nfun:getsecretkey=uninstrumented\nfun:getservbyname=uninstrumented\nfun:getservbyname_r=uninstrumented\nfun:getservbyport=uninstrumented\nfun:getservbyport_r=uninstrumented\nfun:getservent=uninstrumented\nfun:getservent_r=uninstrumented\nfun:getsgent=uninstrumented\nfun:getsgent_r=uninstrumented\nfun:getsgnam=uninstrumented\nfun:getsgnam_r=uninstrumented\nfun:getsid=uninstrumented\nfun:getsockname=uninstrumented\nfun:getsockopt=uninstrumented\nfun:getsourcefilter=uninstrumented\nfun:getspent=uninstrumented\nfun:getspent_r=uninstrumented\nfun:getspnam=uninstrumented\nfun:getspnam_r=uninstrumented\nfun:getsubopt=uninstrumented\nfun:gettext=uninstrumented\nfun:gettimeofday=uninstrumented\nfun:getttyent=uninstrumented\nfun:getttynam=uninstrumented\nfun:getuid=uninstrumented\nfun:getusershell=uninstrumented\nfun:getutent=uninstrumented\nfun:getutent_r=uninstrumented\nfun:getutid=uninstrumented\nfun:getutid_r=uninstrumented\nfun:getutline=uninstrumented\nfun:getutline_r=uninstrumented\nfun:getutmp=uninstrumented\nfun:getutmpx=uninstrumented\nfun:getutxent=uninstrumented\nfun:getutxid=uninstrumented\nfun:getutxline=uninstrumented\nfun:getw=uninstrumented\nfun:getwc=uninstrumented\nfun:getwc_unlocked=uninstrumented\nfun:getwchar=uninstrumented\nfun:getwchar_unlocked=uninstrumented\nfun:getwd=uninstrumented\nfun:getxattr=uninstrumented\nfun:glob=uninstrumented\nfun:glob64=uninstrumented\nfun:glob_pattern_p=uninstrumented\nfun:globfree=uninstrumented\nfun:globfree64=uninstrumented\nfun:gmtime=uninstrumented\nfun:gmtime_r=uninstrumented\nfun:gnu_dev_major=uninstrumented\nfun:gnu_dev_makedev=uninstrumented\nfun:gnu_dev_minor=uninstrumented\nfun:gnu_get_libc_release=uninstrumented\nfun:gnu_get_libc_version=uninstrumented\nfun:grantpt=uninstrumented\nfun:group_member=uninstrumented\nfun:gsignal=uninstrumented\nfun:gtty=uninstrumented\nfun:hasmntopt=uninstrumented\nfun:hcreate=uninstrumented\nfun:hcreate_r=uninstrumented\nfun:hdestroy=uninstrumented\nfun:hdestroy_r=uninstrumented\nfun:herror=uninstrumented\nfun:host2netname=uninstrumented\nfun:hsearch=uninstrumented\nfun:hsearch_r=uninstrumented\nfun:hstrerror=uninstrumented\nfun:htonl=uninstrumented\nfun:htons=uninstrumented\nfun:hypot=uninstrumented\nfun:hypotf=uninstrumented\nfun:hypotl=uninstrumented\nfun:iconv=uninstrumented\nfun:iconv_close=uninstrumented\nfun:iconv_open=uninstrumented\nfun:idna_to_ascii_lz=uninstrumented\nfun:idna_to_unicode_lzlz=uninstrumented\nfun:if_freenameindex=uninstrumented\nfun:if_indextoname=uninstrumented\nfun:if_nameindex=uninstrumented\nfun:if_nametoindex=uninstrumented\nfun:ilogb=uninstrumented\nfun:ilogbf=uninstrumented\nfun:ilogbl=uninstrumented\nfun:imaxabs=uninstrumented\nfun:imaxdiv=uninstrumented\nfun:index=uninstrumented\nfun:inet6_opt_append=uninstrumented\nfun:inet6_opt_find=uninstrumented\nfun:inet6_opt_finish=uninstrumented\nfun:inet6_opt_get_val=uninstrumented\nfun:inet6_opt_init=uninstrumented\nfun:inet6_opt_next=uninstrumented\nfun:inet6_opt_set_val=uninstrumented\nfun:inet6_option_alloc=uninstrumented\nfun:inet6_option_append=uninstrumented\nfun:inet6_option_find=uninstrumented\nfun:inet6_option_init=uninstrumented\nfun:inet6_option_next=uninstrumented\nfun:inet6_option_space=uninstrumented\nfun:inet6_rth_add=uninstrumented\nfun:inet6_rth_getaddr=uninstrumented\nfun:inet6_rth_init=uninstrumented\nfun:inet6_rth_reverse=uninstrumented\nfun:inet6_rth_segments=uninstrumented\nfun:inet6_rth_space=uninstrumented\nfun:inet_addr=uninstrumented\nfun:inet_aton=uninstrumented\nfun:inet_lnaof=uninstrumented\nfun:inet_makeaddr=uninstrumented\nfun:inet_net_ntop=uninstrumented\nfun:inet_net_pton=uninstrumented\nfun:inet_neta=uninstrumented\nfun:inet_netof=uninstrumented\nfun:inet_network=uninstrumented\nfun:inet_nsap_addr=uninstrumented\nfun:inet_nsap_ntoa=uninstrumented\nfun:inet_ntoa=uninstrumented\nfun:inet_ntop=uninstrumented\nfun:inet_pton=uninstrumented\nfun:init_module=uninstrumented\nfun:initgroups=uninstrumented\nfun:initstate=uninstrumented\nfun:initstate_r=uninstrumented\nfun:innetgr=uninstrumented\nfun:inotify_add_watch=uninstrumented\nfun:inotify_init=uninstrumented\nfun:inotify_init1=uninstrumented\nfun:inotify_rm_watch=uninstrumented\nfun:insque=uninstrumented\nfun:ioctl=uninstrumented\nfun:ioperm=uninstrumented\nfun:iopl=uninstrumented\nfun:iruserok=uninstrumented\nfun:iruserok_af=uninstrumented\nfun:isalnum=uninstrumented\nfun:isalnum_l=uninstrumented\nfun:isalpha=uninstrumented\nfun:isalpha_l=uninstrumented\nfun:isascii=uninstrumented\nfun:isastream=uninstrumented\nfun:isatty=uninstrumented\nfun:isblank=uninstrumented\nfun:isblank_l=uninstrumented\nfun:iscntrl=uninstrumented\nfun:iscntrl_l=uninstrumented\nfun:isctype=uninstrumented\nfun:isdigit=uninstrumented\nfun:isdigit_l=uninstrumented\nfun:isfdtype=uninstrumented\nfun:isgraph=uninstrumented\nfun:isgraph_l=uninstrumented\nfun:isinf=uninstrumented\nfun:isinfd128=uninstrumented\nfun:isinfd32=uninstrumented\nfun:isinfd64=uninstrumented\nfun:isinff=uninstrumented\nfun:isinfl=uninstrumented\nfun:islower=uninstrumented\nfun:islower_l=uninstrumented\nfun:isnan=uninstrumented\nfun:isnanf=uninstrumented\nfun:isnanl=uninstrumented\nfun:isprint=uninstrumented\nfun:isprint_l=uninstrumented\nfun:ispunct=uninstrumented\nfun:ispunct_l=uninstrumented\nfun:isspace=uninstrumented\nfun:isspace_l=uninstrumented\nfun:isupper=uninstrumented\nfun:isupper_l=uninstrumented\nfun:iswalnum=uninstrumented\nfun:iswalnum_l=uninstrumented\nfun:iswalpha=uninstrumented\nfun:iswalpha_l=uninstrumented\nfun:iswblank=uninstrumented\nfun:iswblank_l=uninstrumented\nfun:iswcntrl=uninstrumented\nfun:iswcntrl_l=uninstrumented\nfun:iswctype=uninstrumented\nfun:iswctype_l=uninstrumented\nfun:iswdigit=uninstrumented\nfun:iswdigit_l=uninstrumented\nfun:iswgraph=uninstrumented\nfun:iswgraph_l=uninstrumented\nfun:iswlower=uninstrumented\nfun:iswlower_l=uninstrumented\nfun:iswprint=uninstrumented\nfun:iswprint_l=uninstrumented\nfun:iswpunct=uninstrumented\nfun:iswpunct_l=uninstrumented\nfun:iswspace=uninstrumented\nfun:iswspace_l=uninstrumented\nfun:iswupper=uninstrumented\nfun:iswupper_l=uninstrumented\nfun:iswxdigit=uninstrumented\nfun:iswxdigit_l=uninstrumented\nfun:isxdigit=uninstrumented\nfun:isxdigit_l=uninstrumented\nfun:j0=uninstrumented\nfun:j0f=uninstrumented\nfun:j0l=uninstrumented\nfun:j1=uninstrumented\nfun:j1f=uninstrumented\nfun:j1l=uninstrumented\nfun:jn=uninstrumented\nfun:jnf=uninstrumented\nfun:jnl=uninstrumented\nfun:jrand48=uninstrumented\nfun:jrand48_r=uninstrumented\nfun:key_decryptsession=uninstrumented\nfun:key_decryptsession_pk=uninstrumented\nfun:key_encryptsession=uninstrumented\nfun:key_encryptsession_pk=uninstrumented\nfun:key_gendes=uninstrumented\nfun:key_get_conv=uninstrumented\nfun:key_secretkey_is_set=uninstrumented\nfun:key_setnet=uninstrumented\nfun:key_setsecret=uninstrumented\nfun:kill=uninstrumented\nfun:killpg=uninstrumented\nfun:klogctl=uninstrumented\nfun:l64a=uninstrumented\nfun:labs=uninstrumented\nfun:lchmod=uninstrumented\nfun:lchown=uninstrumented\nfun:lckpwdf=uninstrumented\nfun:lcong48=uninstrumented\nfun:lcong48_r=uninstrumented\nfun:ldexp=uninstrumented\nfun:ldexpf=uninstrumented\nfun:ldexpl=uninstrumented\nfun:ldiv=uninstrumented\nfun:lfind=uninstrumented\nfun:lgamma=uninstrumented\nfun:lgamma_r=uninstrumented\nfun:lgammaf=uninstrumented\nfun:lgammaf_r=uninstrumented\nfun:lgammal=uninstrumented\nfun:lgammal_r=uninstrumented\nfun:lgetxattr=uninstrumented\nfun:link=uninstrumented\nfun:linkat=uninstrumented\nfun:lio_listio=uninstrumented\nfun:lio_listio64=uninstrumented\nfun:listen=uninstrumented\nfun:listxattr=uninstrumented\nfun:llabs=uninstrumented\nfun:lldiv=uninstrumented\nfun:llistxattr=uninstrumented\nfun:llrint=uninstrumented\nfun:llrintf=uninstrumented\nfun:llrintl=uninstrumented\nfun:llround=uninstrumented\nfun:llroundf=uninstrumented\nfun:llroundl=uninstrumented\nfun:llseek=uninstrumented\nfun:localeconv=uninstrumented\nfun:localtime=uninstrumented\nfun:localtime_r=uninstrumented\nfun:lockf=uninstrumented\nfun:lockf64=uninstrumented\nfun:log=uninstrumented\nfun:log10=uninstrumented\nfun:log10f=uninstrumented\nfun:log10l=uninstrumented\nfun:log1p=uninstrumented\nfun:log1pf=uninstrumented\nfun:log1pl=uninstrumented\nfun:log2=uninstrumented\nfun:log2f=uninstrumented\nfun:log2l=uninstrumented\nfun:logb=uninstrumented\nfun:logbf=uninstrumented\nfun:logbl=uninstrumented\nfun:logf=uninstrumented\nfun:login=uninstrumented\nfun:login_tty=uninstrumented\nfun:logl=uninstrumented\nfun:logout=uninstrumented\nfun:logwtmp=uninstrumented\nfun:longjmp=uninstrumented\nfun:lrand48=uninstrumented\nfun:lrand48_r=uninstrumented\nfun:lremovexattr=uninstrumented\nfun:lrint=uninstrumented\nfun:lrintf=uninstrumented\nfun:lrintl=uninstrumented\nfun:lround=uninstrumented\nfun:lroundf=uninstrumented\nfun:lroundl=uninstrumented\nfun:lsearch=uninstrumented\nfun:lseek=uninstrumented\nfun:lseek64=uninstrumented\nfun:lsetxattr=uninstrumented\nfun:lstat=uninstrumented\nfun:lstat64=uninstrumented\nfun:lutimes=uninstrumented\nfun:madvise=uninstrumented\nfun:makecontext=uninstrumented\nfun:mallinfo=uninstrumented\nfun:malloc=uninstrumented\nfun:malloc_get_state=uninstrumented\nfun:malloc_info=uninstrumented\nfun:malloc_set_state=uninstrumented\nfun:malloc_stats=uninstrumented\nfun:malloc_trim=uninstrumented\nfun:malloc_usable_size=uninstrumented\nfun:mallopt=uninstrumented\nfun:matherr=uninstrumented\nfun:mblen=uninstrumented\nfun:mbrlen=uninstrumented\nfun:mbrtoc16=uninstrumented\nfun:mbrtoc32=uninstrumented\nfun:mbrtowc=uninstrumented\nfun:mbsinit=uninstrumented\nfun:mbsnrtowcs=uninstrumented\nfun:mbsrtowcs=uninstrumented\nfun:mbstowcs=uninstrumented\nfun:mbtowc=uninstrumented\nfun:mcheck=uninstrumented\nfun:mcheck_check_all=uninstrumented\nfun:mcheck_pedantic=uninstrumented\nfun:mcount=uninstrumented\nfun:memalign=uninstrumented\nfun:memccpy=uninstrumented\nfun:memchr=uninstrumented\nfun:memcmp=uninstrumented\nfun:memcpy=uninstrumented\nfun:memfrob=uninstrumented\nfun:memmem=uninstrumented\nfun:memmove=uninstrumented\nfun:mempcpy=uninstrumented\nfun:memrchr=uninstrumented\nfun:memset=uninstrumented\nfun:mincore=uninstrumented\nfun:mkdir=uninstrumented\nfun:mkdirat=uninstrumented\nfun:mkdtemp=uninstrumented\nfun:mkfifo=uninstrumented\nfun:mkfifoat=uninstrumented\nfun:mknod=uninstrumented\nfun:mknodat=uninstrumented\nfun:mkostemp=uninstrumented\nfun:mkostemp64=uninstrumented\nfun:mkostemps=uninstrumented\nfun:mkostemps64=uninstrumented\nfun:mkstemp=uninstrumented\nfun:mkstemp64=uninstrumented\nfun:mkstemps=uninstrumented\nfun:mkstemps64=uninstrumented\nfun:mktemp=uninstrumented\nfun:mktime=uninstrumented\nfun:mlock=uninstrumented\nfun:mlockall=uninstrumented\nfun:mmap=uninstrumented\nfun:mmap64=uninstrumented\nfun:modf=uninstrumented\nfun:modff=uninstrumented\nfun:modfl=uninstrumented\nfun:modify_ldt=uninstrumented\nfun:moncontrol=uninstrumented\nfun:monstartup=uninstrumented\nfun:mount=uninstrumented\nfun:mprobe=uninstrumented\nfun:mprotect=uninstrumented\nfun:mq_close=uninstrumented\nfun:mq_getattr=uninstrumented\nfun:mq_notify=uninstrumented\nfun:mq_open=uninstrumented\nfun:mq_receive=uninstrumented\nfun:mq_send=uninstrumented\nfun:mq_setattr=uninstrumented\nfun:mq_timedreceive=uninstrumented\nfun:mq_timedsend=uninstrumented\nfun:mq_unlink=uninstrumented\nfun:mrand48=uninstrumented\nfun:mrand48_r=uninstrumented\nfun:mremap=uninstrumented\nfun:msgctl=uninstrumented\nfun:msgget=uninstrumented\nfun:msgrcv=uninstrumented\nfun:msgsnd=uninstrumented\nfun:msync=uninstrumented\nfun:mtrace=uninstrumented\nfun:munlock=uninstrumented\nfun:munlockall=uninstrumented\nfun:munmap=uninstrumented\nfun:muntrace=uninstrumented\nfun:name_to_handle_at=uninstrumented\nfun:nan=uninstrumented\nfun:nanf=uninstrumented\nfun:nanl=uninstrumented\nfun:nanosleep=uninstrumented\nfun:nearbyint=uninstrumented\nfun:nearbyintf=uninstrumented\nfun:nearbyintl=uninstrumented\nfun:netname2host=uninstrumented\nfun:netname2user=uninstrumented\nfun:newlocale=uninstrumented\nfun:nextafter=uninstrumented\nfun:nextafterf=uninstrumented\nfun:nextafterl=uninstrumented\nfun:nexttoward=uninstrumented\nfun:nexttowardf=uninstrumented\nfun:nexttowardl=uninstrumented\nfun:nfsservctl=uninstrumented\nfun:nftw=uninstrumented\nfun:nftw64=uninstrumented\nfun:ngettext=uninstrumented\nfun:nice=uninstrumented\nfun:nis_add=uninstrumented\nfun:nis_add_entry=uninstrumented\nfun:nis_addmember=uninstrumented\nfun:nis_checkpoint=uninstrumented\nfun:nis_clone_directory=uninstrumented\nfun:nis_clone_object=uninstrumented\nfun:nis_clone_result=uninstrumented\nfun:nis_creategroup=uninstrumented\nfun:nis_destroy_object=uninstrumented\nfun:nis_destroygroup=uninstrumented\nfun:nis_dir_cmp=uninstrumented\nfun:nis_domain_of=uninstrumented\nfun:nis_domain_of_r=uninstrumented\nfun:nis_first_entry=uninstrumented\nfun:nis_free_directory=uninstrumented\nfun:nis_free_object=uninstrumented\nfun:nis_free_request=uninstrumented\nfun:nis_freenames=uninstrumented\nfun:nis_freeresult=uninstrumented\nfun:nis_freeservlist=uninstrumented\nfun:nis_freetags=uninstrumented\nfun:nis_getnames=uninstrumented\nfun:nis_getservlist=uninstrumented\nfun:nis_ismember=uninstrumented\nfun:nis_leaf_of=uninstrumented\nfun:nis_leaf_of_r=uninstrumented\nfun:nis_lerror=uninstrumented\nfun:nis_list=uninstrumented\nfun:nis_local_directory=uninstrumented\nfun:nis_local_group=uninstrumented\nfun:nis_local_host=uninstrumented\nfun:nis_local_principal=uninstrumented\nfun:nis_lookup=uninstrumented\nfun:nis_mkdir=uninstrumented\nfun:nis_modify=uninstrumented\nfun:nis_modify_entry=uninstrumented\nfun:nis_name_of=uninstrumented\nfun:nis_name_of_r=uninstrumented\nfun:nis_next_entry=uninstrumented\nfun:nis_perror=uninstrumented\nfun:nis_ping=uninstrumented\nfun:nis_print_directory=uninstrumented\nfun:nis_print_entry=uninstrumented\nfun:nis_print_group=uninstrumented\nfun:nis_print_group_entry=uninstrumented\nfun:nis_print_link=uninstrumented\nfun:nis_print_object=uninstrumented\nfun:nis_print_result=uninstrumented\nfun:nis_print_rights=uninstrumented\nfun:nis_print_table=uninstrumented\nfun:nis_read_obj=uninstrumented\nfun:nis_remove=uninstrumented\nfun:nis_remove_entry=uninstrumented\nfun:nis_removemember=uninstrumented\nfun:nis_rmdir=uninstrumented\nfun:nis_servstate=uninstrumented\nfun:nis_sperrno=uninstrumented\nfun:nis_sperror=uninstrumented\nfun:nis_sperror_r=uninstrumented\nfun:nis_stats=uninstrumented\nfun:nis_verifygroup=uninstrumented\nfun:nis_write_obj=uninstrumented\nfun:nl_langinfo=uninstrumented\nfun:nl_langinfo_l=uninstrumented\nfun:nrand48=uninstrumented\nfun:nrand48_r=uninstrumented\nfun:ns_datetosecs=uninstrumented\nfun:ns_format_ttl=uninstrumented\nfun:ns_get16=uninstrumented\nfun:ns_get32=uninstrumented\nfun:ns_initparse=uninstrumented\nfun:ns_makecanon=uninstrumented\nfun:ns_msg_getflag=uninstrumented\nfun:ns_name_compress=uninstrumented\nfun:ns_name_ntol=uninstrumented\nfun:ns_name_ntop=uninstrumented\nfun:ns_name_pack=uninstrumented\nfun:ns_name_pton=uninstrumented\nfun:ns_name_rollback=uninstrumented\nfun:ns_name_skip=uninstrumented\nfun:ns_name_uncompress=uninstrumented\nfun:ns_name_unpack=uninstrumented\nfun:ns_parse_ttl=uninstrumented\nfun:ns_parserr=uninstrumented\nfun:ns_put16=uninstrumented\nfun:ns_put32=uninstrumented\nfun:ns_samedomain=uninstrumented\nfun:ns_samename=uninstrumented\nfun:ns_skiprr=uninstrumented\nfun:ns_sprintrr=uninstrumented\nfun:ns_sprintrrf=uninstrumented\nfun:ns_subdomain=uninstrumented\nfun:ntohl=uninstrumented\nfun:ntohs=uninstrumented\nfun:ntp_adjtime=uninstrumented\nfun:ntp_gettime=uninstrumented\nfun:ntp_gettimex=uninstrumented\nfun:obstack_free=uninstrumented\nfun:obstack_printf=uninstrumented\nfun:obstack_vprintf=uninstrumented\nfun:on_exit=uninstrumented\nfun:open=uninstrumented\nfun:open64=uninstrumented\nfun:open_by_handle_at=uninstrumented\nfun:open_memstream=uninstrumented\nfun:open_wmemstream=uninstrumented\nfun:openat=uninstrumented\nfun:openat64=uninstrumented\nfun:opendir=uninstrumented\nfun:openlog=uninstrumented\nfun:openpty=uninstrumented\nfun:parse_printf_format=uninstrumented\nfun:passwd2des=uninstrumented\nfun:pathconf=uninstrumented\nfun:pause=uninstrumented\nfun:pclose=uninstrumented\nfun:perror=uninstrumented\nfun:personality=uninstrumented\nfun:pipe=uninstrumented\nfun:pipe2=uninstrumented\nfun:pivot_root=uninstrumented\nfun:pmap_getmaps=uninstrumented\nfun:pmap_getport=uninstrumented\nfun:pmap_rmtcall=uninstrumented\nfun:pmap_set=uninstrumented\nfun:pmap_unset=uninstrumented\nfun:poll=uninstrumented\nfun:popen=uninstrumented\nfun:posix_fadvise=uninstrumented\nfun:posix_fadvise64=uninstrumented\nfun:posix_fallocate=uninstrumented\nfun:posix_fallocate64=uninstrumented\nfun:posix_madvise=uninstrumented\nfun:posix_memalign=uninstrumented\nfun:posix_openpt=uninstrumented\nfun:posix_spawn=uninstrumented\nfun:posix_spawn_file_actions_addclose=uninstrumented\nfun:posix_spawn_file_actions_adddup2=uninstrumented\nfun:posix_spawn_file_actions_addopen=uninstrumented\nfun:posix_spawn_file_actions_destroy=uninstrumented\nfun:posix_spawn_file_actions_init=uninstrumented\nfun:posix_spawnattr_destroy=uninstrumented\nfun:posix_spawnattr_getflags=uninstrumented\nfun:posix_spawnattr_getpgroup=uninstrumented\nfun:posix_spawnattr_getschedparam=uninstrumented\nfun:posix_spawnattr_getschedpolicy=uninstrumented\nfun:posix_spawnattr_getsigdefault=uninstrumented\nfun:posix_spawnattr_getsigmask=uninstrumented\nfun:posix_spawnattr_init=uninstrumented\nfun:posix_spawnattr_setflags=uninstrumented\nfun:posix_spawnattr_setpgroup=uninstrumented\nfun:posix_spawnattr_setschedparam=uninstrumented\nfun:posix_spawnattr_setschedpolicy=uninstrumented\nfun:posix_spawnattr_setsigdefault=uninstrumented\nfun:posix_spawnattr_setsigmask=uninstrumented\nfun:posix_spawnp=uninstrumented\nfun:pow=uninstrumented\nfun:pow10=uninstrumented\nfun:pow10f=uninstrumented\nfun:pow10l=uninstrumented\nfun:powf=uninstrumented\nfun:powl=uninstrumented\nfun:ppoll=uninstrumented\nfun:prctl=uninstrumented\nfun:pread=uninstrumented\nfun:pread64=uninstrumented\nfun:preadv=uninstrumented\nfun:preadv64=uninstrumented\nfun:printf=uninstrumented\nfun:printf_size=uninstrumented\nfun:printf_size_info=uninstrumented\nfun:prlimit=uninstrumented\nfun:prlimit64=uninstrumented\nfun:process_vm_readv=uninstrumented\nfun:process_vm_writev=uninstrumented\nfun:profil=uninstrumented\nfun:pselect=uninstrumented\nfun:psiginfo=uninstrumented\nfun:psignal=uninstrumented\nfun:pthread_atfork=uninstrumented\nfun:pthread_attr_destroy=uninstrumented\nfun:pthread_attr_getaffinity_np=uninstrumented\nfun:pthread_attr_getdetachstate=uninstrumented\nfun:pthread_attr_getguardsize=uninstrumented\nfun:pthread_attr_getinheritsched=uninstrumented\nfun:pthread_attr_getschedparam=uninstrumented\nfun:pthread_attr_getschedpolicy=uninstrumented\nfun:pthread_attr_getscope=uninstrumented\nfun:pthread_attr_getstack=uninstrumented\nfun:pthread_attr_getstackaddr=uninstrumented\nfun:pthread_attr_getstacksize=uninstrumented\nfun:pthread_attr_init=uninstrumented\nfun:pthread_attr_setaffinity_np=uninstrumented\nfun:pthread_attr_setdetachstate=uninstrumented\nfun:pthread_attr_setguardsize=uninstrumented\nfun:pthread_attr_setinheritsched=uninstrumented\nfun:pthread_attr_setschedparam=uninstrumented\nfun:pthread_attr_setschedpolicy=uninstrumented\nfun:pthread_attr_setscope=uninstrumented\nfun:pthread_attr_setstack=uninstrumented\nfun:pthread_attr_setstackaddr=uninstrumented\nfun:pthread_attr_setstacksize=uninstrumented\nfun:pthread_barrier_destroy=uninstrumented\nfun:pthread_barrier_init=uninstrumented\nfun:pthread_barrier_wait=uninstrumented\nfun:pthread_barrierattr_destroy=uninstrumented\nfun:pthread_barrierattr_getpshared=uninstrumented\nfun:pthread_barrierattr_init=uninstrumented\nfun:pthread_barrierattr_setpshared=uninstrumented\nfun:pthread_cancel=uninstrumented\nfun:pthread_cond_broadcast=uninstrumented\nfun:pthread_cond_destroy=uninstrumented\nfun:pthread_cond_init=uninstrumented\nfun:pthread_cond_signal=uninstrumented\nfun:pthread_cond_timedwait=uninstrumented\nfun:pthread_cond_wait=uninstrumented\nfun:pthread_condattr_destroy=uninstrumented\nfun:pthread_condattr_getclock=uninstrumented\nfun:pthread_condattr_getpshared=uninstrumented\nfun:pthread_condattr_init=uninstrumented\nfun:pthread_condattr_setclock=uninstrumented\nfun:pthread_condattr_setpshared=uninstrumented\nfun:pthread_create=uninstrumented\nfun:pthread_detach=uninstrumented\nfun:pthread_equal=uninstrumented\nfun:pthread_exit=uninstrumented\nfun:pthread_getaffinity_np=uninstrumented\nfun:pthread_getattr_default_np=uninstrumented\nfun:pthread_getattr_np=uninstrumented\nfun:pthread_getconcurrency=uninstrumented\nfun:pthread_getcpuclockid=uninstrumented\nfun:pthread_getname_np=uninstrumented\nfun:pthread_getschedparam=uninstrumented\nfun:pthread_getspecific=uninstrumented\nfun:pthread_join=uninstrumented\nfun:pthread_key_create=uninstrumented\nfun:pthread_key_delete=uninstrumented\nfun:pthread_kill=uninstrumented\nfun:pthread_kill_other_threads_np=uninstrumented\nfun:pthread_mutex_consistent=uninstrumented\nfun:pthread_mutex_consistent_np=uninstrumented\nfun:pthread_mutex_destroy=uninstrumented\nfun:pthread_mutex_getprioceiling=uninstrumented\nfun:pthread_mutex_init=uninstrumented\nfun:pthread_mutex_lock=uninstrumented\nfun:pthread_mutex_setprioceiling=uninstrumented\nfun:pthread_mutex_timedlock=uninstrumented\nfun:pthread_mutex_trylock=uninstrumented\nfun:pthread_mutex_unlock=uninstrumented\nfun:pthread_mutexattr_destroy=uninstrumented\nfun:pthread_mutexattr_getkind_np=uninstrumented\nfun:pthread_mutexattr_getprioceiling=uninstrumented\nfun:pthread_mutexattr_getprotocol=uninstrumented\nfun:pthread_mutexattr_getpshared=uninstrumented\nfun:pthread_mutexattr_getrobust=uninstrumented\nfun:pthread_mutexattr_getrobust_np=uninstrumented\nfun:pthread_mutexattr_gettype=uninstrumented\nfun:pthread_mutexattr_init=uninstrumented\nfun:pthread_mutexattr_setkind_np=uninstrumented\nfun:pthread_mutexattr_setprioceiling=uninstrumented\nfun:pthread_mutexattr_setprotocol=uninstrumented\nfun:pthread_mutexattr_setpshared=uninstrumented\nfun:pthread_mutexattr_setrobust=uninstrumented\nfun:pthread_mutexattr_setrobust_np=uninstrumented\nfun:pthread_mutexattr_settype=uninstrumented\nfun:pthread_once=uninstrumented\nfun:pthread_rwlock_destroy=uninstrumented\nfun:pthread_rwlock_init=uninstrumented\nfun:pthread_rwlock_rdlock=uninstrumented\nfun:pthread_rwlock_timedrdlock=uninstrumented\nfun:pthread_rwlock_timedwrlock=uninstrumented\nfun:pthread_rwlock_tryrdlock=uninstrumented\nfun:pthread_rwlock_trywrlock=uninstrumented\nfun:pthread_rwlock_unlock=uninstrumented\nfun:pthread_rwlock_wrlock=uninstrumented\nfun:pthread_rwlockattr_destroy=uninstrumented\nfun:pthread_rwlockattr_getkind_np=uninstrumented\nfun:pthread_rwlockattr_getpshared=uninstrumented\nfun:pthread_rwlockattr_init=uninstrumented\nfun:pthread_rwlockattr_setkind_np=uninstrumented\nfun:pthread_rwlockattr_setpshared=uninstrumented\nfun:pthread_self=uninstrumented\nfun:pthread_setaffinity_np=uninstrumented\nfun:pthread_setattr_default_np=uninstrumented\nfun:pthread_setcancelstate=uninstrumented\nfun:pthread_setcanceltype=uninstrumented\nfun:pthread_setconcurrency=uninstrumented\nfun:pthread_setname_np=uninstrumented\nfun:pthread_setschedparam=uninstrumented\nfun:pthread_setschedprio=uninstrumented\nfun:pthread_setspecific=uninstrumented\nfun:pthread_sigmask=uninstrumented\nfun:pthread_sigqueue=uninstrumented\nfun:pthread_spin_destroy=uninstrumented\nfun:pthread_spin_init=uninstrumented\nfun:pthread_spin_lock=uninstrumented\nfun:pthread_spin_trylock=uninstrumented\nfun:pthread_spin_unlock=uninstrumented\nfun:pthread_testcancel=uninstrumented\nfun:pthread_timedjoin_np=uninstrumented\nfun:pthread_tryjoin_np=uninstrumented\nfun:pthread_yield=uninstrumented\nfun:ptrace=uninstrumented\nfun:ptsname=uninstrumented\nfun:ptsname_r=uninstrumented\nfun:putc=uninstrumented\nfun:putc_unlocked=uninstrumented\nfun:putchar=uninstrumented\nfun:putchar_unlocked=uninstrumented\nfun:putenv=uninstrumented\nfun:putgrent=uninstrumented\nfun:putmsg=uninstrumented\nfun:putpmsg=uninstrumented\nfun:putpwent=uninstrumented\nfun:puts=uninstrumented\nfun:putsgent=uninstrumented\nfun:putspent=uninstrumented\nfun:pututline=uninstrumented\nfun:pututxline=uninstrumented\nfun:putw=uninstrumented\nfun:putwc=uninstrumented\nfun:putwc_unlocked=uninstrumented\nfun:putwchar=uninstrumented\nfun:putwchar_unlocked=uninstrumented\nfun:pvalloc=uninstrumented\nfun:pwrite=uninstrumented\nfun:pwrite64=uninstrumented\nfun:pwritev=uninstrumented\nfun:pwritev64=uninstrumented\nfun:qecvt=uninstrumented\nfun:qecvt_r=uninstrumented\nfun:qfcvt=uninstrumented\nfun:qfcvt_r=uninstrumented\nfun:qgcvt=uninstrumented\nfun:qsort=uninstrumented\nfun:qsort_r=uninstrumented\nfun:query_module=uninstrumented\nfun:quick_exit=uninstrumented\nfun:quotactl=uninstrumented\nfun:raise=uninstrumented\nfun:rand=uninstrumented\nfun:rand_r=uninstrumented\nfun:random=uninstrumented\nfun:random_r=uninstrumented\nfun:rawmemchr=uninstrumented\nfun:rcmd=uninstrumented\nfun:rcmd_af=uninstrumented\nfun:re_comp=uninstrumented\nfun:re_compile_fastmap=uninstrumented\nfun:re_compile_pattern=uninstrumented\nfun:re_exec=uninstrumented\nfun:re_match=uninstrumented\nfun:re_match_2=uninstrumented\nfun:re_search=uninstrumented\nfun:re_search_2=uninstrumented\nfun:re_set_registers=uninstrumented\nfun:re_set_syntax=uninstrumented\nfun:read=uninstrumented\nfun:readColdStartFile=uninstrumented\nfun:readahead=uninstrumented\nfun:readdir=uninstrumented\nfun:readdir64=uninstrumented\nfun:readdir64_r=uninstrumented\nfun:readdir_r=uninstrumented\nfun:readlink=uninstrumented\nfun:readlinkat=uninstrumented\nfun:readv=uninstrumented\nfun:realloc=uninstrumented\nfun:realpath=uninstrumented\nfun:reboot=uninstrumented\nfun:recv=uninstrumented\nfun:recvfrom=uninstrumented\nfun:recvmmsg=uninstrumented\nfun:recvmsg=uninstrumented\nfun:regcomp=uninstrumented\nfun:regerror=uninstrumented\nfun:regexec=uninstrumented\nfun:regfree=uninstrumented\nfun:register_printf_function=uninstrumented\nfun:register_printf_modifier=uninstrumented\nfun:register_printf_specifier=uninstrumented\nfun:register_printf_type=uninstrumented\nfun:registerrpc=uninstrumented\nfun:remainder=uninstrumented\nfun:remainderf=uninstrumented\nfun:remainderl=uninstrumented\nfun:remap_file_pages=uninstrumented\nfun:remove=uninstrumented\nfun:removexattr=uninstrumented\nfun:remque=uninstrumented\nfun:remquo=uninstrumented\nfun:remquof=uninstrumented\nfun:remquol=uninstrumented\nfun:rename=uninstrumented\nfun:renameat=uninstrumented\nfun:res_gethostbyaddr=uninstrumented\nfun:res_gethostbyname=uninstrumented\nfun:res_gethostbyname2=uninstrumented\nfun:res_send_setqhook=uninstrumented\nfun:res_send_setrhook=uninstrumented\nfun:revoke=uninstrumented\nfun:rewind=uninstrumented\nfun:rewinddir=uninstrumented\nfun:rexec=uninstrumented\nfun:rexec_af=uninstrumented\nfun:rindex=uninstrumented\nfun:rint=uninstrumented\nfun:rintf=uninstrumented\nfun:rintl=uninstrumented\nfun:rmdir=uninstrumented\nfun:round=uninstrumented\nfun:roundf=uninstrumented\nfun:roundl=uninstrumented\nfun:rpmatch=uninstrumented\nfun:rresvport=uninstrumented\nfun:rresvport_af=uninstrumented\nfun:rtime=uninstrumented\nfun:ruserok=uninstrumented\nfun:ruserok_af=uninstrumented\nfun:ruserpass=uninstrumented\nfun:sbrk=uninstrumented\nfun:scalb=uninstrumented\nfun:scalbf=uninstrumented\nfun:scalbl=uninstrumented\nfun:scalbln=uninstrumented\nfun:scalblnf=uninstrumented\nfun:scalblnl=uninstrumented\nfun:scalbn=uninstrumented\nfun:scalbnf=uninstrumented\nfun:scalbnl=uninstrumented\nfun:scandir=uninstrumented\nfun:scandir64=uninstrumented\nfun:scandirat=uninstrumented\nfun:scandirat64=uninstrumented\nfun:scanf=uninstrumented\nfun:sched_get_priority_max=uninstrumented\nfun:sched_get_priority_min=uninstrumented\nfun:sched_getaffinity=uninstrumented\nfun:sched_getcpu=uninstrumented\nfun:sched_getparam=uninstrumented\nfun:sched_getscheduler=uninstrumented\nfun:sched_rr_get_interval=uninstrumented\nfun:sched_setaffinity=uninstrumented\nfun:sched_setparam=uninstrumented\nfun:sched_setscheduler=uninstrumented\nfun:sched_yield=uninstrumented\nfun:secure_getenv=uninstrumented\nfun:seed48=uninstrumented\nfun:seed48_r=uninstrumented\nfun:seekdir=uninstrumented\nfun:select=uninstrumented\nfun:sem_close=uninstrumented\nfun:sem_destroy=uninstrumented\nfun:sem_getvalue=uninstrumented\nfun:sem_init=uninstrumented\nfun:sem_open=uninstrumented\nfun:sem_post=uninstrumented\nfun:sem_timedwait=uninstrumented\nfun:sem_trywait=uninstrumented\nfun:sem_unlink=uninstrumented\nfun:sem_wait=uninstrumented\nfun:semctl=uninstrumented\nfun:semget=uninstrumented\nfun:semop=uninstrumented\nfun:semtimedop=uninstrumented\nfun:send=uninstrumented\nfun:sendfile=uninstrumented\nfun:sendfile64=uninstrumented\nfun:sendmmsg=uninstrumented\nfun:sendmsg=uninstrumented\nfun:sendto=uninstrumented\nfun:setaliasent=uninstrumented\nfun:setbuf=uninstrumented\nfun:setbuffer=uninstrumented\nfun:setcontext=uninstrumented\nfun:setdomainname=uninstrumented\nfun:setegid=uninstrumented\nfun:setenv=uninstrumented\nfun:seteuid=uninstrumented\nfun:setfsent=uninstrumented\nfun:setfsgid=uninstrumented\nfun:setfsuid=uninstrumented\nfun:setgid=uninstrumented\nfun:setgrent=uninstrumented\nfun:setgroups=uninstrumented\nfun:sethostent=uninstrumented\nfun:sethostid=uninstrumented\nfun:sethostname=uninstrumented\nfun:setipv4sourcefilter=uninstrumented\nfun:setitimer=uninstrumented\nfun:setjmp=uninstrumented\nfun:setkey=uninstrumented\nfun:setkey_r=uninstrumented\nfun:setlinebuf=uninstrumented\nfun:setlocale=uninstrumented\nfun:setlogin=uninstrumented\nfun:setlogmask=uninstrumented\nfun:setmntent=uninstrumented\nfun:setnetent=uninstrumented\nfun:setnetgrent=uninstrumented\nfun:setns=uninstrumented\nfun:setpgid=uninstrumented\nfun:setpgrp=uninstrumented\nfun:setpriority=uninstrumented\nfun:setprotoent=uninstrumented\nfun:setpwent=uninstrumented\nfun:setregid=uninstrumented\nfun:setresgid=uninstrumented\nfun:setresuid=uninstrumented\nfun:setreuid=uninstrumented\nfun:setrlimit=uninstrumented\nfun:setrlimit64=uninstrumented\nfun:setrpcent=uninstrumented\nfun:setservent=uninstrumented\nfun:setsgent=uninstrumented\nfun:setsid=uninstrumented\nfun:setsockopt=uninstrumented\nfun:setsourcefilter=uninstrumented\nfun:setspent=uninstrumented\nfun:setstate=uninstrumented\nfun:setstate_r=uninstrumented\nfun:settimeofday=uninstrumented\nfun:setttyent=uninstrumented\nfun:setuid=uninstrumented\nfun:setusershell=uninstrumented\nfun:setutent=uninstrumented\nfun:setutxent=uninstrumented\nfun:setvbuf=uninstrumented\nfun:setxattr=uninstrumented\nfun:sgetsgent=uninstrumented\nfun:sgetsgent_r=uninstrumented\nfun:sgetspent=uninstrumented\nfun:sgetspent_r=uninstrumented\nfun:shm_open=uninstrumented\nfun:shm_unlink=uninstrumented\nfun:shmat=uninstrumented\nfun:shmctl=uninstrumented\nfun:shmdt=uninstrumented\nfun:shmget=uninstrumented\nfun:shutdown=uninstrumented\nfun:sigaction=uninstrumented\nfun:sigaddset=uninstrumented\nfun:sigaltstack=uninstrumented\nfun:sigandset=uninstrumented\nfun:sigblock=uninstrumented\nfun:sigdelset=uninstrumented\nfun:sigemptyset=uninstrumented\nfun:sigfillset=uninstrumented\nfun:siggetmask=uninstrumented\nfun:sighold=uninstrumented\nfun:sigignore=uninstrumented\nfun:siginterrupt=uninstrumented\nfun:sigisemptyset=uninstrumented\nfun:sigismember=uninstrumented\nfun:siglongjmp=uninstrumented\nfun:signal=uninstrumented\nfun:signalfd=uninstrumented\nfun:significand=uninstrumented\nfun:significandf=uninstrumented\nfun:significandl=uninstrumented\nfun:sigorset=uninstrumented\nfun:sigpause=uninstrumented\nfun:sigpending=uninstrumented\nfun:sigprocmask=uninstrumented\nfun:sigqueue=uninstrumented\nfun:sigrelse=uninstrumented\nfun:sigreturn=uninstrumented\nfun:sigset=uninstrumented\nfun:sigsetmask=uninstrumented\nfun:sigstack=uninstrumented\nfun:sigsuspend=uninstrumented\nfun:sigtimedwait=uninstrumented\nfun:sigvec=uninstrumented\nfun:sigwait=uninstrumented\nfun:sigwaitinfo=uninstrumented\nfun:sin=uninstrumented\nfun:sincos=uninstrumented\nfun:sincosf=uninstrumented\nfun:sincosl=uninstrumented\nfun:sinf=uninstrumented\nfun:sinh=uninstrumented\nfun:sinhf=uninstrumented\nfun:sinhl=uninstrumented\nfun:sinl=uninstrumented\nfun:sleep=uninstrumented\nfun:snprintf=uninstrumented\nfun:sockatmark=uninstrumented\nfun:socket=uninstrumented\nfun:socketpair=uninstrumented\nfun:splice=uninstrumented\nfun:sprintf=uninstrumented\nfun:sprofil=uninstrumented\nfun:sqrt=uninstrumented\nfun:sqrtf=uninstrumented\nfun:sqrtl=uninstrumented\nfun:srand=uninstrumented\nfun:srand48=uninstrumented\nfun:srand48_r=uninstrumented\nfun:srandom=uninstrumented\nfun:srandom_r=uninstrumented\nfun:sscanf=uninstrumented\nfun:ssignal=uninstrumented\nfun:sstk=uninstrumented\nfun:stat=uninstrumented\nfun:stat64=uninstrumented\nfun:statfs=uninstrumented\nfun:statfs64=uninstrumented\nfun:statvfs=uninstrumented\nfun:statvfs64=uninstrumented\nfun:step=uninstrumented\nfun:stime=uninstrumented\nfun:stpcpy=uninstrumented\nfun:stpncpy=uninstrumented\nfun:strcasecmp=uninstrumented\nfun:strcasecmp_l=uninstrumented\nfun:strcasestr=uninstrumented\nfun:strcat=uninstrumented\nfun:strchr=uninstrumented\nfun:strchrnul=uninstrumented\nfun:strcmp=uninstrumented\nfun:strcoll=uninstrumented\nfun:strcoll_l=uninstrumented\nfun:strcpy=uninstrumented\nfun:strcspn=uninstrumented\nfun:strdup=uninstrumented\nfun:strerror=uninstrumented\nfun:strerror_l=uninstrumented\nfun:strerror_r=uninstrumented\nfun:strfmon=uninstrumented\nfun:strfmon_l=uninstrumented\nfun:strfry=uninstrumented\nfun:strftime=uninstrumented\nfun:strftime_l=uninstrumented\nfun:strlen=uninstrumented\nfun:strncasecmp=uninstrumented\nfun:strncasecmp_l=uninstrumented\nfun:strncat=uninstrumented\nfun:strncmp=uninstrumented\nfun:strncpy=uninstrumented\nfun:strndup=uninstrumented\nfun:strnlen=uninstrumented\nfun:strpbrk=uninstrumented\nfun:strptime=uninstrumented\nfun:strptime_l=uninstrumented\nfun:strrchr=uninstrumented\nfun:strsep=uninstrumented\nfun:strsignal=uninstrumented\nfun:strspn=uninstrumented\nfun:strstr=uninstrumented\nfun:strtod=uninstrumented\nfun:strtod_l=uninstrumented\nfun:strtof=uninstrumented\nfun:strtof_l=uninstrumented\nfun:strtoimax=uninstrumented\nfun:strtok=uninstrumented\nfun:strtok_r=uninstrumented\nfun:strtol=uninstrumented\nfun:strtol_l=uninstrumented\nfun:strtold=uninstrumented\nfun:strtold_l=uninstrumented\nfun:strtoll=uninstrumented\nfun:strtoll_l=uninstrumented\nfun:strtoq=uninstrumented\nfun:strtoul=uninstrumented\nfun:strtoul_l=uninstrumented\nfun:strtoull=uninstrumented\nfun:strtoull_l=uninstrumented\nfun:strtoumax=uninstrumented\nfun:strtouq=uninstrumented\nfun:strverscmp=uninstrumented\nfun:strxfrm=uninstrumented\nfun:strxfrm_l=uninstrumented\nfun:stty=uninstrumented\nfun:svc_exit=uninstrumented\nfun:svc_getreq=uninstrumented\nfun:svc_getreq_common=uninstrumented\nfun:svc_getreq_poll=uninstrumented\nfun:svc_getreqset=uninstrumented\nfun:svc_register=uninstrumented\nfun:svc_run=uninstrumented\nfun:svc_sendreply=uninstrumented\nfun:svc_unregister=uninstrumented\nfun:svcerr_auth=uninstrumented\nfun:svcerr_decode=uninstrumented\nfun:svcerr_noproc=uninstrumented\nfun:svcerr_noprog=uninstrumented\nfun:svcerr_progvers=uninstrumented\nfun:svcerr_systemerr=uninstrumented\nfun:svcerr_weakauth=uninstrumented\nfun:svcfd_create=uninstrumented\nfun:svcraw_create=uninstrumented\nfun:svctcp_create=uninstrumented\nfun:svcudp_bufcreate=uninstrumented\nfun:svcudp_create=uninstrumented\nfun:svcudp_enablecache=uninstrumented\nfun:svcunix_create=uninstrumented\nfun:svcunixfd_create=uninstrumented\nfun:swab=uninstrumented\nfun:swapcontext=uninstrumented\nfun:swapoff=uninstrumented\nfun:swapon=uninstrumented\nfun:swprintf=uninstrumented\nfun:swscanf=uninstrumented\nfun:symlink=uninstrumented\nfun:symlinkat=uninstrumented\nfun:sync=uninstrumented\nfun:sync_file_range=uninstrumented\nfun:syncfs=uninstrumented\nfun:syscall=uninstrumented\nfun:sysconf=uninstrumented\nfun:sysctl=uninstrumented\nfun:sysinfo=uninstrumented\nfun:syslog=uninstrumented\nfun:system=uninstrumented\nfun:sysv_signal=uninstrumented\nfun:tan=uninstrumented\nfun:tanf=uninstrumented\nfun:tanh=uninstrumented\nfun:tanhf=uninstrumented\nfun:tanhl=uninstrumented\nfun:tanl=uninstrumented\nfun:tcdrain=uninstrumented\nfun:tcflow=uninstrumented\nfun:tcflush=uninstrumented\nfun:tcgetattr=uninstrumented\nfun:tcgetpgrp=uninstrumented\nfun:tcgetsid=uninstrumented\nfun:tcsendbreak=uninstrumented\nfun:tcsetattr=uninstrumented\nfun:tcsetpgrp=uninstrumented\nfun:td_init=uninstrumented\nfun:td_log=uninstrumented\nfun:td_symbol_list=uninstrumented\nfun:td_ta_clear_event=uninstrumented\nfun:td_ta_delete=uninstrumented\nfun:td_ta_enable_stats=uninstrumented\nfun:td_ta_event_addr=uninstrumented\nfun:td_ta_event_getmsg=uninstrumented\nfun:td_ta_get_nthreads=uninstrumented\nfun:td_ta_get_ph=uninstrumented\nfun:td_ta_get_stats=uninstrumented\nfun:td_ta_map_id2thr=uninstrumented\nfun:td_ta_map_lwp2thr=uninstrumented\nfun:td_ta_new=uninstrumented\nfun:td_ta_reset_stats=uninstrumented\nfun:td_ta_set_event=uninstrumented\nfun:td_ta_setconcurrency=uninstrumented\nfun:td_ta_thr_iter=uninstrumented\nfun:td_ta_tsd_iter=uninstrumented\nfun:td_thr_clear_event=uninstrumented\nfun:td_thr_dbresume=uninstrumented\nfun:td_thr_dbsuspend=uninstrumented\nfun:td_thr_event_enable=uninstrumented\nfun:td_thr_event_getmsg=uninstrumented\nfun:td_thr_get_info=uninstrumented\nfun:td_thr_getfpregs=uninstrumented\nfun:td_thr_getgregs=uninstrumented\nfun:td_thr_getxregs=uninstrumented\nfun:td_thr_getxregsize=uninstrumented\nfun:td_thr_set_event=uninstrumented\nfun:td_thr_setfpregs=uninstrumented\nfun:td_thr_setgregs=uninstrumented\nfun:td_thr_setprio=uninstrumented\nfun:td_thr_setsigpending=uninstrumented\nfun:td_thr_setxregs=uninstrumented\nfun:td_thr_sigsetmask=uninstrumented\nfun:td_thr_tls_get_addr=uninstrumented\nfun:td_thr_tlsbase=uninstrumented\nfun:td_thr_tsd=uninstrumented\nfun:td_thr_validate=uninstrumented\nfun:tdelete=uninstrumented\nfun:tdestroy=uninstrumented\nfun:tee=uninstrumented\nfun:telldir=uninstrumented\nfun:tempnam=uninstrumented\nfun:textdomain=uninstrumented\nfun:tfind=uninstrumented\nfun:tgamma=uninstrumented\nfun:tgammaf=uninstrumented\nfun:tgammal=uninstrumented\nfun:time=uninstrumented\nfun:timegm=uninstrumented\nfun:timelocal=uninstrumented\nfun:timer_create=uninstrumented\nfun:timer_delete=uninstrumented\nfun:timer_getoverrun=uninstrumented\nfun:timer_gettime=uninstrumented\nfun:timer_settime=uninstrumented\nfun:timerfd_create=uninstrumented\nfun:timerfd_gettime=uninstrumented\nfun:timerfd_settime=uninstrumented\nfun:times=uninstrumented\nfun:timespec_get=uninstrumented\nfun:tmpfile=uninstrumented\nfun:tmpfile64=uninstrumented\nfun:tmpnam=uninstrumented\nfun:tmpnam_r=uninstrumented\nfun:toascii=uninstrumented\nfun:tolower=uninstrumented\nfun:tolower_l=uninstrumented\nfun:toupper=uninstrumented\nfun:toupper_l=uninstrumented\nfun:towctrans=uninstrumented\nfun:towctrans_l=uninstrumented\nfun:towlower=uninstrumented\nfun:towlower_l=uninstrumented\nfun:towupper=uninstrumented\nfun:towupper_l=uninstrumented\nfun:tr_break=uninstrumented\nfun:trunc=uninstrumented\nfun:truncate=uninstrumented\nfun:truncate64=uninstrumented\nfun:truncf=uninstrumented\nfun:truncl=uninstrumented\nfun:tsearch=uninstrumented\nfun:ttyname=uninstrumented\nfun:ttyname_r=uninstrumented\nfun:ttyslot=uninstrumented\nfun:twalk=uninstrumented\nfun:tzset=uninstrumented\nfun:ualarm=uninstrumented\nfun:ulckpwdf=uninstrumented\nfun:ulimit=uninstrumented\nfun:umask=uninstrumented\nfun:umount=uninstrumented\nfun:umount2=uninstrumented\nfun:uname=uninstrumented\nfun:ungetc=uninstrumented\nfun:ungetwc=uninstrumented\nfun:unlink=uninstrumented\nfun:unlinkat=uninstrumented\nfun:unlockpt=uninstrumented\nfun:unsetenv=uninstrumented\nfun:unshare=uninstrumented\nfun:updwtmp=uninstrumented\nfun:updwtmpx=uninstrumented\nfun:uselib=uninstrumented\nfun:uselocale=uninstrumented\nfun:user2netname=uninstrumented\nfun:usleep=uninstrumented\nfun:ustat=uninstrumented\nfun:utime=uninstrumented\nfun:utimensat=uninstrumented\nfun:utimes=uninstrumented\nfun:utmpname=uninstrumented\nfun:utmpxname=uninstrumented\nfun:valloc=uninstrumented\nfun:vasprintf=uninstrumented\nfun:vdprintf=uninstrumented\nfun:verr=uninstrumented\nfun:verrx=uninstrumented\nfun:versionsort=uninstrumented\nfun:versionsort64=uninstrumented\nfun:vfork=uninstrumented\nfun:vfprintf=uninstrumented\nfun:vfscanf=uninstrumented\nfun:vfwprintf=uninstrumented\nfun:vfwscanf=uninstrumented\nfun:vhangup=uninstrumented\nfun:vlimit=uninstrumented\nfun:vmsplice=uninstrumented\nfun:vprintf=uninstrumented\nfun:vscanf=uninstrumented\nfun:vsnprintf=uninstrumented\nfun:vsprintf=uninstrumented\nfun:vsscanf=uninstrumented\nfun:vswprintf=uninstrumented\nfun:vswscanf=uninstrumented\nfun:vsyslog=uninstrumented\nfun:vtimes=uninstrumented\nfun:vwarn=uninstrumented\nfun:vwarnx=uninstrumented\nfun:vwprintf=uninstrumented\nfun:vwscanf=uninstrumented\nfun:wait=uninstrumented\nfun:wait3=uninstrumented\nfun:wait4=uninstrumented\nfun:waitid=uninstrumented\nfun:waitpid=uninstrumented\nfun:warn=uninstrumented\nfun:warnx=uninstrumented\nfun:wcpcpy=uninstrumented\nfun:wcpncpy=uninstrumented\nfun:wcrtomb=uninstrumented\nfun:wcscasecmp=uninstrumented\nfun:wcscasecmp_l=uninstrumented\nfun:wcscat=uninstrumented\nfun:wcschr=uninstrumented\nfun:wcschrnul=uninstrumented\nfun:wcscmp=uninstrumented\nfun:wcscoll=uninstrumented\nfun:wcscoll_l=uninstrumented\nfun:wcscpy=uninstrumented\nfun:wcscspn=uninstrumented\nfun:wcsdup=uninstrumented\nfun:wcsftime=uninstrumented\nfun:wcsftime_l=uninstrumented\nfun:wcslen=uninstrumented\nfun:wcsncasecmp=uninstrumented\nfun:wcsncasecmp_l=uninstrumented\nfun:wcsncat=uninstrumented\nfun:wcsncmp=uninstrumented\nfun:wcsncpy=uninstrumented\nfun:wcsnlen=uninstrumented\nfun:wcsnrtombs=uninstrumented\nfun:wcspbrk=uninstrumented\nfun:wcsrchr=uninstrumented\nfun:wcsrtombs=uninstrumented\nfun:wcsspn=uninstrumented\nfun:wcsstr=uninstrumented\nfun:wcstod=uninstrumented\nfun:wcstod_l=uninstrumented\nfun:wcstof=uninstrumented\nfun:wcstof_l=uninstrumented\nfun:wcstoimax=uninstrumented\nfun:wcstok=uninstrumented\nfun:wcstol=uninstrumented\nfun:wcstol_l=uninstrumented\nfun:wcstold=uninstrumented\nfun:wcstold_l=uninstrumented\nfun:wcstoll=uninstrumented\nfun:wcstoll_l=uninstrumented\nfun:wcstombs=uninstrumented\nfun:wcstoq=uninstrumented\nfun:wcstoul=uninstrumented\nfun:wcstoul_l=uninstrumented\nfun:wcstoull=uninstrumented\nfun:wcstoull_l=uninstrumented\nfun:wcstoumax=uninstrumented\nfun:wcstouq=uninstrumented\nfun:wcswcs=uninstrumented\nfun:wcswidth=uninstrumented\nfun:wcsxfrm=uninstrumented\nfun:wcsxfrm_l=uninstrumented\nfun:wctob=uninstrumented\nfun:wctomb=uninstrumented\nfun:wctrans=uninstrumented\nfun:wctrans_l=uninstrumented\nfun:wctype=uninstrumented\nfun:wctype_l=uninstrumented\nfun:wcwidth=uninstrumented\nfun:wmemchr=uninstrumented\nfun:wmemcmp=uninstrumented\nfun:wmemcpy=uninstrumented\nfun:wmemmove=uninstrumented\nfun:wmempcpy=uninstrumented\nfun:wmemset=uninstrumented\nfun:wordexp=uninstrumented\nfun:wordfree=uninstrumented\nfun:wprintf=uninstrumented\nfun:write=uninstrumented\nfun:writeColdStartFile=uninstrumented\nfun:writev=uninstrumented\nfun:wscanf=uninstrumented\nfun:xdecrypt=uninstrumented\nfun:xdr_accepted_reply=uninstrumented\nfun:xdr_array=uninstrumented\nfun:xdr_authdes_cred=uninstrumented\nfun:xdr_authdes_verf=uninstrumented\nfun:xdr_authunix_parms=uninstrumented\nfun:xdr_bool=uninstrumented\nfun:xdr_bytes=uninstrumented\nfun:xdr_callhdr=uninstrumented\nfun:xdr_callmsg=uninstrumented\nfun:xdr_cback_data=uninstrumented\nfun:xdr_char=uninstrumented\nfun:xdr_cryptkeyarg=uninstrumented\nfun:xdr_cryptkeyarg2=uninstrumented\nfun:xdr_cryptkeyres=uninstrumented\nfun:xdr_des_block=uninstrumented\nfun:xdr_domainname=uninstrumented\nfun:xdr_double=uninstrumented\nfun:xdr_enum=uninstrumented\nfun:xdr_float=uninstrumented\nfun:xdr_free=uninstrumented\nfun:xdr_getcredres=uninstrumented\nfun:xdr_hyper=uninstrumented\nfun:xdr_int=uninstrumented\nfun:xdr_int16_t=uninstrumented\nfun:xdr_int32_t=uninstrumented\nfun:xdr_int64_t=uninstrumented\nfun:xdr_int8_t=uninstrumented\nfun:xdr_key_netstarg=uninstrumented\nfun:xdr_key_netstres=uninstrumented\nfun:xdr_keybuf=uninstrumented\nfun:xdr_keydat=uninstrumented\nfun:xdr_keystatus=uninstrumented\nfun:xdr_long=uninstrumented\nfun:xdr_longlong_t=uninstrumented\nfun:xdr_mapname=uninstrumented\nfun:xdr_netnamestr=uninstrumented\nfun:xdr_netobj=uninstrumented\nfun:xdr_obj_p=uninstrumented\nfun:xdr_opaque=uninstrumented\nfun:xdr_opaque_auth=uninstrumented\nfun:xdr_peername=uninstrumented\nfun:xdr_pmap=uninstrumented\nfun:xdr_pmaplist=uninstrumented\nfun:xdr_pointer=uninstrumented\nfun:xdr_quad_t=uninstrumented\nfun:xdr_reference=uninstrumented\nfun:xdr_rejected_reply=uninstrumented\nfun:xdr_replymsg=uninstrumented\nfun:xdr_rmtcall_args=uninstrumented\nfun:xdr_rmtcallres=uninstrumented\nfun:xdr_short=uninstrumented\nfun:xdr_sizeof=uninstrumented\nfun:xdr_string=uninstrumented\nfun:xdr_u_char=uninstrumented\nfun:xdr_u_hyper=uninstrumented\nfun:xdr_u_int=uninstrumented\nfun:xdr_u_long=uninstrumented\nfun:xdr_u_longlong_t=uninstrumented\nfun:xdr_u_quad_t=uninstrumented\nfun:xdr_u_short=uninstrumented\nfun:xdr_uint16_t=uninstrumented\nfun:xdr_uint32_t=uninstrumented\nfun:xdr_uint64_t=uninstrumented\nfun:xdr_uint8_t=uninstrumented\nfun:xdr_union=uninstrumented\nfun:xdr_unixcred=uninstrumented\nfun:xdr_valdat=uninstrumented\nfun:xdr_vector=uninstrumented\nfun:xdr_void=uninstrumented\nfun:xdr_wrapstring=uninstrumented\nfun:xdr_yp_buf=uninstrumented\nfun:xdr_ypall=uninstrumented\nfun:xdr_ypbind_binding=uninstrumented\nfun:xdr_ypbind_resp=uninstrumented\nfun:xdr_ypbind_resptype=uninstrumented\nfun:xdr_ypbind_setdom=uninstrumented\nfun:xdr_ypdelete_args=uninstrumented\nfun:xdr_ypmap_parms=uninstrumented\nfun:xdr_ypmaplist=uninstrumented\nfun:xdr_yppush_status=uninstrumented\nfun:xdr_yppushresp_xfr=uninstrumented\nfun:xdr_ypreq_key=uninstrumented\nfun:xdr_ypreq_nokey=uninstrumented\nfun:xdr_ypreq_xfr=uninstrumented\nfun:xdr_ypresp_all=uninstrumented\nfun:xdr_ypresp_key_val=uninstrumented\nfun:xdr_ypresp_maplist=uninstrumented\nfun:xdr_ypresp_master=uninstrumented\nfun:xdr_ypresp_order=uninstrumented\nfun:xdr_ypresp_val=uninstrumented\nfun:xdr_ypresp_xfr=uninstrumented\nfun:xdr_ypstat=uninstrumented\nfun:xdr_ypupdate_args=uninstrumented\nfun:xdr_ypxfrstat=uninstrumented\nfun:xdrmem_create=uninstrumented\nfun:xdrrec_create=uninstrumented\nfun:xdrrec_endofrecord=uninstrumented\nfun:xdrrec_eof=uninstrumented\nfun:xdrrec_skiprecord=uninstrumented\nfun:xdrstdio_create=uninstrumented\nfun:xencrypt=uninstrumented\nfun:xprt_register=uninstrumented\nfun:xprt_unregister=uninstrumented\nfun:y0=uninstrumented\nfun:y0f=uninstrumented\nfun:y0l=uninstrumented\nfun:y1=uninstrumented\nfun:y1f=uninstrumented\nfun:y1l=uninstrumented\nfun:yn=uninstrumented\nfun:ynf=uninstrumented\nfun:ynl=uninstrumented\nfun:yp_all=uninstrumented\nfun:yp_bind=uninstrumented\nfun:yp_first=uninstrumented\nfun:yp_get_default_domain=uninstrumented\nfun:yp_maplist=uninstrumented\nfun:yp_master=uninstrumented\nfun:yp_match=uninstrumented\nfun:yp_next=uninstrumented\nfun:yp_order=uninstrumented\nfun:yp_unbind=uninstrumented\nfun:yp_update=uninstrumented\nfun:ypbinderr_string=uninstrumented\nfun:yperr_string=uninstrumented\nfun:ypprot_err=uninstrumented\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/dfsan/scripts/build-libc-list.py",
    "content": "#!/usr/bin/env python\n#===- lib/dfsan/scripts/build-libc-list.py ---------------------------------===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n# The purpose of this script is to identify every function symbol in a set of\n# libraries (in this case, libc and libgcc) so that they can be marked as\n# uninstrumented, thus allowing the instrumentation pass to treat calls to those\n# functions correctly.\n\nimport os\nimport subprocess\nimport sys\nfrom optparse import OptionParser\n\ndef defined_function_list(object):\n  functions = []\n  readelf_proc = subprocess.Popen(['readelf', '-s', '-W', object],\n                                  stdout=subprocess.PIPE)\n  readelf = readelf_proc.communicate()[0].split('\\n')\n  if readelf_proc.returncode != 0:\n    raise subprocess.CalledProcessError(readelf_proc.returncode, 'readelf')\n  for line in readelf:\n    if (line[31:35] == 'FUNC' or line[31:36] == 'IFUNC') and \\\n       line[39:44] != 'LOCAL' and \\\n       line[55:58] != 'UND':\n      function_name = line[59:].split('@')[0]\n      functions.append(function_name)\n  return functions\n\np = OptionParser()\n\np.add_option('--libc-dso-path', metavar='PATH',\n             help='path to libc DSO directory',\n             default='/lib/x86_64-linux-gnu')\np.add_option('--libc-archive-path', metavar='PATH',\n             help='path to libc archive directory',\n             default='/usr/lib/x86_64-linux-gnu')\n\np.add_option('--libgcc-dso-path', metavar='PATH',\n             help='path to libgcc DSO directory',\n             default='/lib/x86_64-linux-gnu')\np.add_option('--libgcc-archive-path', metavar='PATH',\n             help='path to libgcc archive directory',\n             default='/usr/lib/gcc/x86_64-linux-gnu/4.6')\n\np.add_option('--with-libstdcxx', action='store_true',\n             dest='with_libstdcxx',\n             help='include libstdc++ in the list (inadvisable)')\np.add_option('--libstdcxx-dso-path', metavar='PATH',\n             help='path to libstdc++ DSO directory',\n             default='/usr/lib/x86_64-linux-gnu')\n\n(options, args) = p.parse_args()\n\nlibs = [os.path.join(options.libc_dso_path, name) for name in\n        ['ld-linux-x86-64.so.2',\n         'libanl.so.1',\n         'libBrokenLocale.so.1',\n         'libcidn.so.1',\n         'libcrypt.so.1',\n         'libc.so.6',\n         'libdl.so.2',\n         'libm.so.6',\n         'libnsl.so.1',\n         'libpthread.so.0',\n         'libresolv.so.2',\n         'librt.so.1',\n         'libthread_db.so.1',\n         'libutil.so.1']]\nlibs += [os.path.join(options.libc_archive_path, name) for name in\n         ['libc_nonshared.a',\n          'libpthread_nonshared.a']]\n\nlibs.append(os.path.join(options.libgcc_dso_path, 'libgcc_s.so.1'))\nlibs.append(os.path.join(options.libgcc_archive_path, 'libgcc.a'))\n\nif options.with_libstdcxx:\n  libs.append(os.path.join(options.libstdcxx_dso_path, 'libstdc++.so.6'))\n\nfunctions = []\nfor l in libs:\n  if os.path.exists(l):\n    functions += defined_function_list(l)\n  else:\n    print >> sys.stderr, 'warning: library %s not found' % l\n\nfunctions = list(set(functions))\nfunctions.sort()\n\nfor f in functions:\n  print 'fun:%s=uninstrumented' % f\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/dfsan/scripts/check_custom_wrappers.sh",
    "content": "#!/bin/sh\n\nDFSAN_DIR=$(dirname \"$0\")/../\nDFSAN_CUSTOM_TESTS=${DFSAN_DIR}/../../test/dfsan/custom.cc\nDFSAN_CUSTOM_WRAPPERS=${DFSAN_DIR}/dfsan_custom.cc\nDFSAN_ABI_LIST=${DFSAN_DIR}/done_abilist.txt\n\nDIFFOUT=$(mktemp -q /tmp/tmp.XXXXXXXXXX)\nERRORLOG=$(mktemp -q /tmp/tmp.XXXXXXXXXX)\nDIFF_A=$(mktemp -q /tmp/tmp.XXXXXXXXXX)\nDIFF_B=$(mktemp -q /tmp/tmp.XXXXXXXXXX)\n\non_exit() {\n  rm -f ${DIFFOUT} 2> /dev/null\n  rm -f ${ERRORLOG} 2> /dev/null\n  rm -f ${DIFF_A} 2> /dev/null\n  rm -f ${DIFF_B} 2> /dev/null\n}\n\n# Ignore __sanitizer_cov_trace* because they are implemented elsewhere.\ntrap on_exit EXIT\ngrep -E \"^fun:.*=custom\" ${DFSAN_ABI_LIST} \\\n  | grep -v \"dfsan_get_label\\|__sanitizer_cov_trace\" \\\n  | sed \"s/^fun:\\(.*\\)=custom.*/\\1/\" | sort > $DIFF_A\ngrep -E \"__dfsw.*\\(\" ${DFSAN_CUSTOM_WRAPPERS} \\\n  | sed \"s/.*__dfsw_\\(.*\\)(.*/\\1/\" | sort > $DIFF_B\ndiff -u $DIFF_A $DIFF_B > ${DIFFOUT}\nif [ $? -ne 0 ]\nthen\n  echo -n \"The following differences between the ABI list and \">> ${ERRORLOG}\n  echo \"the implemented custom wrappers have been found:\" >> ${ERRORLOG}\n  cat ${DIFFOUT} >> ${ERRORLOG}\nfi\n\ngrep -E __dfsw_ ${DFSAN_CUSTOM_WRAPPERS} \\\n  | sed \"s/.*__dfsw_\\([^(]*\\).*/\\1/\" | sort > $DIFF_A\ngrep -E \"^[[:space:]]*test_.*\\(\\);\" ${DFSAN_CUSTOM_TESTS} \\\n  | sed \"s/.*test_\\(.*\\)();/\\1/\" | sort > $DIFF_B\ndiff -u $DIFF_A $DIFF_B > ${DIFFOUT}\nif [ $? -ne 0 ]\nthen\n  echo -n \"The following differences between the implemented \" >> ${ERRORLOG}\n  echo \"custom wrappers and the tests have been found:\" >> ${ERRORLOG}\n  cat ${DIFFOUT} >> ${ERRORLOG}\nfi\n\nif [ -s ${ERRORLOG} ]\nthen\n  cat ${ERRORLOG}\n  exit 1\nfi\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/interception/.clang-format",
    "content": "BasedOnStyle: Google\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/interception/Android.mk",
    "content": "#\n# Copyright (C) 2015 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n#\n\nLOCAL_PATH:= $(call my-dir)\n\ninterception_src_files := \\\n    interception_linux.cc \\\n    interception_mac.cc \\\n    interception_type_test.cc \\\n    interception_win.cc \\\n\ninterception_cppflags := \\\n    -fvisibility=hidden \\\n    -fno-exceptions \\\n    -std=c++11 \\\n    -Wall \\\n    -Werror \\\n    -Wno-unused-parameter \\\n\ninterception_c_includes := \\\n    external/compiler-rt/lib \\\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libinterception\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_C_INCLUDES := $(interception_c_includes)\nLOCAL_CPPFLAGS := $(interception_cppflags)\nLOCAL_SRC_FILES := $(interception_src_files)\nLOCAL_CXX_STL := none\nLOCAL_SANITIZE := never\nLOCAL_MULTILIB := both\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/interception/CMakeLists.txt",
    "content": "# Build for the runtime interception helper library.\n\nset(INTERCEPTION_SOURCES\n  interception_linux.cc\n  interception_mac.cc\n  interception_win.cc\n  interception_type_test.cc\n  )\n\ninclude_directories(..)\n\nset(INTERCEPTION_CFLAGS ${SANITIZER_COMMON_CFLAGS})\nappend_no_rtti_flag(INTERCEPTION_CFLAGS)\n\nadd_compiler_rt_object_libraries(RTInterception\n    OS ${SANITIZER_COMMON_SUPPORTED_OS}\n    ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}\n    SOURCES ${INTERCEPTION_SOURCES}\n    CFLAGS ${INTERCEPTION_CFLAGS})\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/interception/Makefile.mk",
    "content": "#===- lib/interception/Makefile.mk -------------------------*- Makefile -*--===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\nModuleName := interception\nSubDirs :=\n\nSources := $(foreach file,$(wildcard $(Dir)/*.cc),$(notdir $(file)))\nObjNames := $(Sources:%.cc=%.o)\n\nImplementation := Generic\n\n# FIXME: use automatic dependencies?\nDependencies := $(wildcard $(Dir)/*.h)\nDependencies += $(wildcard $(Dir)/../sanitizer_common/*.h)\n\n# Define a convenience variable for all the interception functions.\nInterceptionFunctions := $(Sources:%.cc=%)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/interception/interception.h",
    "content": "//===-- interception.h ------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Machinery for providing replacements/wrappers for system functions.\n//===----------------------------------------------------------------------===//\n\n#ifndef INTERCEPTION_H\n#define INTERCEPTION_H\n\n#if !defined(__linux__) && !defined(__FreeBSD__) && \\\n  !defined(__APPLE__) && !defined(_WIN32)\n# error \"Interception doesn't work on this operating system.\"\n#endif\n\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n\n// These typedefs should be used only in the interceptor definitions to replace\n// the standard system types (e.g. SSIZE_T instead of ssize_t)\ntypedef __sanitizer::uptr    SIZE_T;\ntypedef __sanitizer::sptr    SSIZE_T;\ntypedef __sanitizer::sptr    PTRDIFF_T;\ntypedef __sanitizer::s64     INTMAX_T;\ntypedef __sanitizer::OFF_T   OFF_T;\ntypedef __sanitizer::OFF64_T OFF64_T;\n\n// How to add an interceptor:\n// Suppose you need to wrap/replace system function (generally, from libc):\n//      int foo(const char *bar, double baz);\n// You'll need to:\n//      1) define INTERCEPTOR(int, foo, const char *bar, double baz) { ... } in\n//         your source file. See the notes below for cases when\n//         INTERCEPTOR_WITH_SUFFIX(...) should be used instead.\n//      2) Call \"INTERCEPT_FUNCTION(foo)\" prior to the first call of \"foo\".\n//         INTERCEPT_FUNCTION(foo) evaluates to \"true\" iff the function was\n//         intercepted successfully.\n// You can access original function by calling REAL(foo)(bar, baz).\n// By default, REAL(foo) will be visible only inside your interceptor, and if\n// you want to use it in other parts of RTL, you'll need to:\n//      3a) add DECLARE_REAL(int, foo, const char*, double) to a\n//          header file.\n// However, if the call \"INTERCEPT_FUNCTION(foo)\" and definition for\n// INTERCEPTOR(..., foo, ...) are in different files, you'll instead need to:\n//      3b) add DECLARE_REAL_AND_INTERCEPTOR(int, foo, const char*, double)\n//          to a header file.\n\n// Notes: 1. Things may not work properly if macro INTERCEPTOR(...) {...} or\n//           DECLARE_REAL(...) are located inside namespaces.\n//        2. On Mac you can also use: \"OVERRIDE_FUNCTION(foo, zoo)\" to\n//           effectively redirect calls from \"foo\" to \"zoo\". In this case\n//           you aren't required to implement\n//           INTERCEPTOR(int, foo, const char *bar, double baz) {...}\n//           but instead you'll have to add\n//           DECLARE_REAL(int, foo, const char *bar, double baz) in your\n//           source file (to define a pointer to overriden function).\n//        3. Some Mac functions have symbol variants discriminated by\n//           additional suffixes, e.g. _$UNIX2003 (see\n//           https://developer.apple.com/library/mac/#releasenotes/Darwin/SymbolVariantsRelNotes/index.html\n//           for more details). To intercept such functions you need to use the\n//           INTERCEPTOR_WITH_SUFFIX(...) macro.\n\n// How it works:\n// To replace system functions on Linux we just need to declare functions\n// with same names in our library and then obtain the real function pointers\n// using dlsym().\n// There is one complication. A user may also intercept some of the functions\n// we intercept. To resolve this we declare our interceptors with __interceptor_\n// prefix, and then make actual interceptors weak aliases to __interceptor_\n// functions.\n//\n// This is not so on Mac OS, where the two-level namespace makes\n// our replacement functions invisible to other libraries. This may be overcomed\n// using the DYLD_FORCE_FLAT_NAMESPACE, but some errors loading the shared\n// libraries in Chromium were noticed when doing so.\n// Instead we create a dylib containing a __DATA,__interpose section that\n// associates library functions with their wrappers. When this dylib is\n// preloaded before an executable using DYLD_INSERT_LIBRARIES, it routes all\n// the calls to interposed functions done through stubs to the wrapper\n// functions.\n// As it's decided at compile time which functions are to be intercepted on Mac,\n// INTERCEPT_FUNCTION() is effectively a no-op on this system.\n\n#if defined(__APPLE__)\n#include <sys/cdefs.h>  // For __DARWIN_ALIAS_C().\n\n// Just a pair of pointers.\nstruct interpose_substitution {\n  const uptr replacement;\n  const uptr original;\n};\n\n// For a function foo() create a global pair of pointers { wrap_foo, foo } in\n// the __DATA,__interpose section.\n// As a result all the calls to foo() will be routed to wrap_foo() at runtime.\n#define INTERPOSER(func_name) __attribute__((used)) \\\nconst interpose_substitution substitution_##func_name[] \\\n    __attribute__((section(\"__DATA, __interpose\"))) = { \\\n    { reinterpret_cast<const uptr>(WRAP(func_name)), \\\n      reinterpret_cast<const uptr>(func_name) } \\\n}\n\n// For a function foo() and a wrapper function bar() create a global pair\n// of pointers { bar, foo } in the __DATA,__interpose section.\n// As a result all the calls to foo() will be routed to bar() at runtime.\n#define INTERPOSER_2(func_name, wrapper_name) __attribute__((used)) \\\nconst interpose_substitution substitution_##func_name[] \\\n    __attribute__((section(\"__DATA, __interpose\"))) = { \\\n    { reinterpret_cast<const uptr>(wrapper_name), \\\n      reinterpret_cast<const uptr>(func_name) } \\\n}\n\n# define WRAP(x) wrap_##x\n# define WRAPPER_NAME(x) \"wrap_\"#x\n# define INTERCEPTOR_ATTRIBUTE\n# define DECLARE_WRAPPER(ret_type, func, ...)\n\n#elif defined(_WIN32)\n# define WRAP(x) __asan_wrap_##x\n# define WRAPPER_NAME(x) \"__asan_wrap_\"#x\n# define INTERCEPTOR_ATTRIBUTE __declspec(dllexport)\n# define DECLARE_WRAPPER(ret_type, func, ...) \\\n    extern \"C\" ret_type func(__VA_ARGS__);\n# define DECLARE_WRAPPER_WINAPI(ret_type, func, ...) \\\n    extern \"C\" __declspec(dllimport) ret_type __stdcall func(__VA_ARGS__);\n#elif defined(__FreeBSD__)\n# define WRAP(x) __interceptor_ ## x\n# define WRAPPER_NAME(x) \"__interceptor_\" #x\n# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility(\"default\")))\n// FreeBSD's dynamic linker (incompliantly) gives non-weak symbols higher\n// priority than weak ones so weak aliases won't work for indirect calls\n// in position-independent (-fPIC / -fPIE) mode.\n# define DECLARE_WRAPPER(ret_type, func, ...) \\\n     extern \"C\" ret_type func(__VA_ARGS__) \\\n     __attribute__((alias(\"__interceptor_\" #func), visibility(\"default\")));\n#else\n# define WRAP(x) __interceptor_ ## x\n# define WRAPPER_NAME(x) \"__interceptor_\" #x\n# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility(\"default\")))\n# define DECLARE_WRAPPER(ret_type, func, ...) \\\n    extern \"C\" ret_type func(__VA_ARGS__) \\\n    __attribute__((weak, alias(\"__interceptor_\" #func), visibility(\"default\")));\n#endif\n\n#if !defined(__APPLE__)\n# define PTR_TO_REAL(x) real_##x\n# define REAL(x) __interception::PTR_TO_REAL(x)\n# define FUNC_TYPE(x) x##_f\n\n# define DECLARE_REAL(ret_type, func, ...) \\\n    typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \\\n    namespace __interception { \\\n      extern FUNC_TYPE(func) PTR_TO_REAL(func); \\\n    }\n#else  // __APPLE__\n# define REAL(x) x\n# define DECLARE_REAL(ret_type, func, ...) \\\n    extern \"C\" ret_type func(__VA_ARGS__);\n#endif  // __APPLE__\n\n#define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) \\\n  DECLARE_REAL(ret_type, func, __VA_ARGS__) \\\n  extern \"C\" ret_type WRAP(func)(__VA_ARGS__);\n\n// Generally, you don't need to use DEFINE_REAL by itself, as INTERCEPTOR\n// macros does its job. In exceptional cases you may need to call REAL(foo)\n// without defining INTERCEPTOR(..., foo, ...). For example, if you override\n// foo with an interceptor for other function.\n#if !defined(__APPLE__)\n# define DEFINE_REAL(ret_type, func, ...) \\\n    typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \\\n    namespace __interception { \\\n      FUNC_TYPE(func) PTR_TO_REAL(func); \\\n    }\n#else\n# define DEFINE_REAL(ret_type, func, ...)\n#endif\n\n#if !defined(__APPLE__)\n#define INTERCEPTOR(ret_type, func, ...) \\\n  DEFINE_REAL(ret_type, func, __VA_ARGS__) \\\n  DECLARE_WRAPPER(ret_type, func, __VA_ARGS__) \\\n  extern \"C\" \\\n  INTERCEPTOR_ATTRIBUTE \\\n  ret_type WRAP(func)(__VA_ARGS__)\n\n// We don't need INTERCEPTOR_WITH_SUFFIX on non-Darwin for now.\n#define INTERCEPTOR_WITH_SUFFIX(ret_type, func, ...) \\\n  INTERCEPTOR(ret_type, func, __VA_ARGS__)\n\n#else  // __APPLE__\n\n#define INTERCEPTOR_ZZZ(suffix, ret_type, func, ...) \\\n  extern \"C\" ret_type func(__VA_ARGS__) suffix; \\\n  extern \"C\" ret_type WRAP(func)(__VA_ARGS__); \\\n  INTERPOSER(func); \\\n  extern \"C\" INTERCEPTOR_ATTRIBUTE ret_type WRAP(func)(__VA_ARGS__)\n\n#define INTERCEPTOR(ret_type, func, ...) \\\n  INTERCEPTOR_ZZZ(/*no symbol variants*/, ret_type, func, __VA_ARGS__)\n\n#define INTERCEPTOR_WITH_SUFFIX(ret_type, func, ...) \\\n  INTERCEPTOR_ZZZ(__DARWIN_ALIAS_C(func), ret_type, func, __VA_ARGS__)\n\n// Override |overridee| with |overrider|.\n#define OVERRIDE_FUNCTION(overridee, overrider) \\\n  INTERPOSER_2(overridee, WRAP(overrider))\n#endif\n\n#if defined(_WIN32)\n# define INTERCEPTOR_WINAPI(ret_type, func, ...) \\\n    typedef ret_type (__stdcall *FUNC_TYPE(func))(__VA_ARGS__); \\\n    namespace __interception { \\\n      FUNC_TYPE(func) PTR_TO_REAL(func); \\\n    } \\\n    extern \"C\" \\\n    INTERCEPTOR_ATTRIBUTE \\\n    ret_type __stdcall WRAP(func)(__VA_ARGS__)\n#endif\n\n// ISO C++ forbids casting between pointer-to-function and pointer-to-object,\n// so we use casting via an integral type __interception::uptr,\n// assuming that system is POSIX-compliant. Using other hacks seem\n// challenging, as we don't even pass function type to\n// INTERCEPT_FUNCTION macro, only its name.\nnamespace __interception {\n#if defined(_WIN64)\ntypedef unsigned long long uptr;  // NOLINT\n#else\ntypedef unsigned long uptr;  // NOLINT\n#endif  // _WIN64\n}  // namespace __interception\n\n#define INCLUDED_FROM_INTERCEPTION_LIB\n\n#if defined(__linux__) || defined(__FreeBSD__)\n# include \"interception_linux.h\"\n# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)\n# define INTERCEPT_FUNCTION_VER(func, symver) \\\n    INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver)\n#elif defined(__APPLE__)\n# include \"interception_mac.h\"\n# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_MAC(func)\n# define INTERCEPT_FUNCTION_VER(func, symver) \\\n    INTERCEPT_FUNCTION_VER_MAC(func, symver)\n#else  // defined(_WIN32)\n# include \"interception_win.h\"\n# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_WIN(func)\n# define INTERCEPT_FUNCTION_VER(func, symver) \\\n    INTERCEPT_FUNCTION_VER_WIN(func, symver)\n#endif\n\n#undef INCLUDED_FROM_INTERCEPTION_LIB\n\n#endif  // INTERCEPTION_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/interception/interception_linux.cc",
    "content": "//===-- interception_linux.cc -----------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Linux-specific interception methods.\n//===----------------------------------------------------------------------===//\n\n#if defined(__linux__) || defined(__FreeBSD__)\n#include \"interception.h\"\n\n#include <dlfcn.h>   // for dlsym() and dlvsym()\n\nnamespace __interception {\nbool GetRealFunctionAddress(const char *func_name, uptr *func_addr,\n    uptr real, uptr wrapper) {\n  *func_addr = (uptr)dlsym(RTLD_NEXT, func_name);\n  return real == wrapper;\n}\n\n#if !defined(__ANDROID__)  // android does not have dlvsym\nvoid *GetFuncAddrVer(const char *func_name, const char *ver) {\n  return dlvsym(RTLD_NEXT, func_name, ver);\n}\n#endif  // !defined(__ANDROID__)\n\n}  // namespace __interception\n\n\n#endif  // __linux__ || __FreeBSD__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/interception/interception_linux.h",
    "content": "//===-- interception_linux.h ------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Linux-specific interception methods.\n//===----------------------------------------------------------------------===//\n\n#if defined(__linux__) || defined(__FreeBSD__)\n\n#if !defined(INCLUDED_FROM_INTERCEPTION_LIB)\n# error \"interception_linux.h should be included from interception library only\"\n#endif\n\n#ifndef INTERCEPTION_LINUX_H\n#define INTERCEPTION_LINUX_H\n\nnamespace __interception {\n// returns true if a function with the given name was found.\nbool GetRealFunctionAddress(const char *func_name, uptr *func_addr,\n    uptr real, uptr wrapper);\nvoid *GetFuncAddrVer(const char *func_name, const char *ver);\n}  // namespace __interception\n\n#define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)                          \\\n  ::__interception::GetRealFunctionAddress(                                \\\n      #func, (::__interception::uptr *)&__interception::PTR_TO_REAL(func), \\\n      (::__interception::uptr) & (func),                                   \\\n      (::__interception::uptr) & WRAP(func))\n\n#if !defined(__ANDROID__)  // android does not have dlvsym\n#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \\\n  (::__interception::real_##func = (func##_f)(                \\\n       unsigned long)::__interception::GetFuncAddrVer(#func, symver))\n#else\n#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \\\n  INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)\n#endif  // !defined(__ANDROID__)\n\n#endif  // INTERCEPTION_LINUX_H\n#endif  // __linux__ || __FreeBSD__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/interception/interception_mac.cc",
    "content": "//===-- interception_mac.cc -------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Mac-specific interception methods.\n//===----------------------------------------------------------------------===//\n\n#ifdef __APPLE__\n\n#include \"interception.h\"\n\n\n#endif  // __APPLE__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/interception/interception_mac.h",
    "content": "//===-- interception_mac.h --------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Mac-specific interception methods.\n//===----------------------------------------------------------------------===//\n\n#ifdef __APPLE__\n\n#if !defined(INCLUDED_FROM_INTERCEPTION_LIB)\n# error \"interception_mac.h should be included from interception.h only\"\n#endif\n\n#ifndef INTERCEPTION_MAC_H\n#define INTERCEPTION_MAC_H\n\n#define INTERCEPT_FUNCTION_MAC(func)\n#define INTERCEPT_FUNCTION_VER_MAC(func, symver)\n\n#endif  // INTERCEPTION_MAC_H\n#endif  // __APPLE__\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/interception/interception_type_test.cc",
    "content": "//===-- interception_type_test.cc -------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Compile-time tests of the internal type definitions.\n//===----------------------------------------------------------------------===//\n\n#if defined(__linux__) || defined(__APPLE__)\n\n#include \"interception.h\"\n#include <sys/types.h>\n#include <stddef.h>\n#include <stdint.h>\n\nCOMPILER_CHECK(sizeof(::SIZE_T) == sizeof(size_t));\nCOMPILER_CHECK(sizeof(::SSIZE_T) == sizeof(ssize_t));\nCOMPILER_CHECK(sizeof(::PTRDIFF_T) == sizeof(ptrdiff_t));\nCOMPILER_CHECK(sizeof(::INTMAX_T) == sizeof(intmax_t));\n\n#ifndef __APPLE__\nCOMPILER_CHECK(sizeof(::OFF64_T) == sizeof(off64_t));\n#endif\n\n// The following are the cases when pread (and friends) is used instead of\n// pread64. In those cases we need OFF_T to match off_t. We don't care about the\n// rest (they depend on _FILE_OFFSET_BITS setting when building an application).\n# if defined(__ANDROID__) || !defined _FILE_OFFSET_BITS || \\\n  _FILE_OFFSET_BITS != 64\nCOMPILER_CHECK(sizeof(::OFF_T) == sizeof(off_t));\n# endif\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/interception/interception_win.cc",
    "content": "//===-- interception_linux.cc -----------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Windows-specific interception methods.\n//===----------------------------------------------------------------------===//\n\n#ifdef _WIN32\n\n#include \"interception.h\"\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n\nnamespace __interception {\n\n// FIXME: internal_str* and internal_mem* functions should be moved from the\n// ASan sources into interception/.\n\nstatic void _memset(void *p, int value, size_t sz) {\n  for (size_t i = 0; i < sz; ++i)\n    ((char*)p)[i] = (char)value;\n}\n\nstatic void _memcpy(void *dst, void *src, size_t sz) {\n  char *dst_c = (char*)dst,\n       *src_c = (char*)src;\n  for (size_t i = 0; i < sz; ++i)\n    dst_c[i] = src_c[i];\n}\n\nstatic void WriteJumpInstruction(char *jmp_from, char *to) {\n  // jmp XXYYZZWW = E9 WW ZZ YY XX, where XXYYZZWW is an offset fromt jmp_from\n  // to the next instruction to the destination.\n  ptrdiff_t offset = to - jmp_from - 5;\n  *jmp_from = '\\xE9';\n  *(ptrdiff_t*)(jmp_from + 1) = offset;\n}\n\nstatic char *GetMemoryForTrampoline(size_t size) {\n  // Trampolines are allocated from a common pool.\n  const int POOL_SIZE = 1024;\n  static char *pool = NULL;\n  static size_t pool_used = 0;\n  if (!pool) {\n    pool = (char *)VirtualAlloc(NULL, POOL_SIZE, MEM_RESERVE | MEM_COMMIT,\n                                PAGE_EXECUTE_READWRITE);\n    // FIXME: Might want to apply PAGE_EXECUTE_READ access after all the\n    // interceptors are in place.\n    if (!pool)\n      return NULL;\n    _memset(pool, 0xCC /* int 3 */, POOL_SIZE);\n  }\n\n  if (pool_used + size > POOL_SIZE)\n    return NULL;\n\n  char *ret = pool + pool_used;\n  pool_used += size;\n  return ret;\n}\n\n// Returns 0 on error.\nstatic size_t RoundUpToInstrBoundary(size_t size, char *code) {\n  size_t cursor = 0;\n  while (cursor < size) {\n    switch (code[cursor]) {\n      case '\\x51':  // push ecx\n      case '\\x52':  // push edx\n      case '\\x53':  // push ebx\n      case '\\x54':  // push esp\n      case '\\x55':  // push ebp\n      case '\\x56':  // push esi\n      case '\\x57':  // push edi\n      case '\\x5D':  // pop ebp\n        cursor++;\n        continue;\n      case '\\x6A':  // 6A XX = push XX\n        cursor += 2;\n        continue;\n      case '\\xE9':  // E9 XX YY ZZ WW = jmp WWZZYYXX\n      case '\\xB8':  // B8 XX YY ZZ WW = mov eax, WWZZYYXX\n        cursor += 5;\n        continue;\n    }\n    switch (*(unsigned short*)(code + cursor)) {  // NOLINT\n      case 0xFF8B:  // 8B FF = mov edi, edi\n      case 0xEC8B:  // 8B EC = mov ebp, esp\n      case 0xC033:  // 33 C0 = xor eax, eax\n        cursor += 2;\n        continue;\n      case 0x458B:  // 8B 45 XX = mov eax, dword ptr [ebp+XXh]\n      case 0x5D8B:  // 8B 5D XX = mov ebx, dword ptr [ebp+XXh]\n      case 0xEC83:  // 83 EC XX = sub esp, XX\n      case 0x75FF:  // FF 75 XX = push dword ptr [ebp+XXh]\n        cursor += 3;\n        continue;\n      case 0xC1F7:  // F7 C1 XX YY ZZ WW = test ecx, WWZZYYXX\n      case 0x25FF:  // FF 25 XX YY ZZ WW = jmp dword ptr ds:[WWZZYYXX]\n        cursor += 6;\n        continue;\n      case 0x3D83:  // 83 3D XX YY ZZ WW TT = cmp TT, WWZZYYXX\n        cursor += 7;\n        continue;\n    }\n    switch (0x00FFFFFF & *(unsigned int*)(code + cursor)) {\n      case 0x24448A:  // 8A 44 24 XX = mov eal, dword ptr [esp+XXh]\n      case 0x24448B:  // 8B 44 24 XX = mov eax, dword ptr [esp+XXh]\n      case 0x244C8B:  // 8B 4C 24 XX = mov ecx, dword ptr [esp+XXh]\n      case 0x24548B:  // 8B 54 24 XX = mov edx, dword ptr [esp+XXh]\n      case 0x24748B:  // 8B 74 24 XX = mov esi, dword ptr [esp+XXh]\n      case 0x247C8B:  // 8B 7C 24 XX = mov edi, dword ptr [esp+XXh]\n        cursor += 4;\n        continue;\n    }\n\n    // Unknown instruction!\n    // FIXME: Unknown instruction failures might happen when we add a new\n    // interceptor or a new compiler version. In either case, they should result\n    // in visible and readable error messages. However, merely calling abort()\n    // leads to an infinite recursion in CheckFailed.\n    // Do we have a good way to abort with an error message here?\n    __debugbreak();\n    return 0;\n  }\n\n  return cursor;\n}\n\nbool OverrideFunction(uptr old_func, uptr new_func, uptr *orig_old_func) {\n#ifdef _WIN64\n#error OverrideFunction is not yet supported on x64\n#endif\n  // Function overriding works basically like this:\n  // We write \"jmp <new_func>\" (5 bytes) at the beginning of the 'old_func'\n  // to override it.\n  // We might want to be able to execute the original 'old_func' from the\n  // wrapper, in this case we need to keep the leading 5+ bytes ('head')\n  // of the original code somewhere with a \"jmp <old_func+head>\".\n  // We call these 'head'+5 bytes of instructions a \"trampoline\".\n  char *old_bytes = (char *)old_func;\n\n  // We'll need at least 5 bytes for a 'jmp'.\n  size_t head = 5;\n  if (orig_old_func) {\n    // Find out the number of bytes of the instructions we need to copy\n    // to the trampoline and store it in 'head'.\n    head = RoundUpToInstrBoundary(head, old_bytes);\n    if (!head)\n      return false;\n\n    // Put the needed instructions into the trampoline bytes.\n    char *trampoline = GetMemoryForTrampoline(head + 5);\n    if (!trampoline)\n      return false;\n    _memcpy(trampoline, old_bytes, head);\n    WriteJumpInstruction(trampoline + head, old_bytes + head);\n    *orig_old_func = (uptr)trampoline;\n  }\n\n  // Now put the \"jmp <new_func>\" instruction at the original code location.\n  // We should preserve the EXECUTE flag as some of our own code might be\n  // located in the same page (sic!).  FIXME: might consider putting the\n  // __interception code into a separate section or something?\n  DWORD old_prot, unused_prot;\n  if (!VirtualProtect((void *)old_bytes, head, PAGE_EXECUTE_READWRITE,\n                      &old_prot))\n    return false;\n\n  WriteJumpInstruction(old_bytes, (char *)new_func);\n  _memset(old_bytes + 5, 0xCC /* int 3 */, head - 5);\n\n  // Restore the original permissions.\n  if (!VirtualProtect((void *)old_bytes, head, old_prot, &unused_prot))\n    return false;  // not clear if this failure bothers us.\n\n  return true;\n}\n\nstatic void **InterestingDLLsAvailable() {\n  const char *InterestingDLLs[] = {\n    \"kernel32.dll\",\n    \"msvcr110.dll\", // VS2012\n    \"msvcr120.dll\", // VS2013\n    // NTDLL should go last as it exports some functions that we should override\n    // in the CRT [presumably only used internally].\n    \"ntdll.dll\", NULL\n  };\n  static void *result[ARRAY_SIZE(InterestingDLLs)] = { 0 };\n  if (!result[0]) {\n    for (size_t i = 0, j = 0; InterestingDLLs[i]; ++i) {\n      if (HMODULE h = GetModuleHandleA(InterestingDLLs[i]))\n        result[j++] = (void *)h;\n    }\n  }\n  return &result[0];\n}\n\nnamespace {\n// Utility for reading loaded PE images.\ntemplate <typename T> class RVAPtr {\n public:\n  RVAPtr(void *module, uptr rva)\n      : ptr_(reinterpret_cast<T *>(reinterpret_cast<char *>(module) + rva)) {}\n  operator T *() { return ptr_; }\n  T *operator->() { return ptr_; }\n  T *operator++() { return ++ptr_; }\n\n private:\n  T *ptr_;\n};\n} // namespace\n\n// Internal implementation of GetProcAddress. At least since Windows 8,\n// GetProcAddress appears to initialize DLLs before returning function pointers\n// into them. This is problematic for the sanitizers, because they typically\n// want to intercept malloc *before* MSVCRT initializes. Our internal\n// implementation walks the export list manually without doing initialization.\nuptr InternalGetProcAddress(void *module, const char *func_name) {\n  // Check that the module header is full and present.\n  RVAPtr<IMAGE_DOS_HEADER> dos_stub(module, 0);\n  RVAPtr<IMAGE_NT_HEADERS> headers(module, dos_stub->e_lfanew);\n  if (!module || dos_stub->e_magic != IMAGE_DOS_SIGNATURE || // \"MZ\"\n      headers->Signature != IMAGE_NT_SIGNATURE ||           // \"PE\\0\\0\"\n      headers->FileHeader.SizeOfOptionalHeader <\n          sizeof(IMAGE_OPTIONAL_HEADER)) {\n    return 0;\n  }\n\n  IMAGE_DATA_DIRECTORY *export_directory =\n      &headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];\n  RVAPtr<IMAGE_EXPORT_DIRECTORY> exports(module,\n                                         export_directory->VirtualAddress);\n  RVAPtr<DWORD> functions(module, exports->AddressOfFunctions);\n  RVAPtr<DWORD> names(module, exports->AddressOfNames);\n  RVAPtr<WORD> ordinals(module, exports->AddressOfNameOrdinals);\n\n  for (DWORD i = 0; i < exports->NumberOfNames; i++) {\n    RVAPtr<char> name(module, names[i]);\n    if (!strcmp(func_name, name)) {\n      DWORD index = ordinals[i];\n      RVAPtr<char> func(module, functions[index]);\n      return (uptr)(char *)func;\n    }\n  }\n\n  return 0;\n}\n\nstatic bool GetFunctionAddressInDLLs(const char *func_name, uptr *func_addr) {\n  *func_addr = 0;\n  void **DLLs = InterestingDLLsAvailable();\n  for (size_t i = 0; *func_addr == 0 && DLLs[i]; ++i)\n    *func_addr = InternalGetProcAddress(DLLs[i], func_name);\n  return (*func_addr != 0);\n}\n\nbool OverrideFunction(const char *name, uptr new_func, uptr *orig_old_func) {\n  uptr orig_func;\n  if (!GetFunctionAddressInDLLs(name, &orig_func))\n    return false;\n  return OverrideFunction(orig_func, new_func, orig_old_func);\n}\n\n}  // namespace __interception\n\n#endif  // _WIN32\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/interception/interception_win.h",
    "content": "//===-- interception_linux.h ------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of AddressSanitizer, an address sanity checker.\n//\n// Windows-specific interception methods.\n//===----------------------------------------------------------------------===//\n\n#ifdef _WIN32\n\n#if !defined(INCLUDED_FROM_INTERCEPTION_LIB)\n# error \"interception_win.h should be included from interception library only\"\n#endif\n\n#ifndef INTERCEPTION_WIN_H\n#define INTERCEPTION_WIN_H\n\nnamespace __interception {\n// All the functions in the OverrideFunction() family return true on success,\n// false on failure (including \"couldn't find the function\").\n\n// Overrides a function by its address.\nbool OverrideFunction(uptr old_func, uptr new_func, uptr *orig_old_func = 0);\n\n// Overrides a function in a system DLL or DLL CRT by its exported name.\nbool OverrideFunction(const char *name, uptr new_func, uptr *orig_old_func = 0);\n\n// Windows-only replacement for GetProcAddress. Useful for some sanitizers.\nuptr InternalGetProcAddress(void *module, const char *func_name);\n\n}  // namespace __interception\n\n#if defined(INTERCEPTION_DYNAMIC_CRT)\n#define INTERCEPT_FUNCTION_WIN(func)                                           \\\n  ::__interception::OverrideFunction(#func,                                    \\\n                                     (::__interception::uptr)WRAP(func),       \\\n                                     (::__interception::uptr *)&REAL(func))\n#else\n#define INTERCEPT_FUNCTION_WIN(func)                                           \\\n  ::__interception::OverrideFunction((::__interception::uptr)func,             \\\n                                     (::__interception::uptr)WRAP(func),       \\\n                                     (::__interception::uptr *)&REAL(func))\n#endif\n\n#define INTERCEPT_FUNCTION_VER_WIN(func, symver) INTERCEPT_FUNCTION_WIN(func)\n\n#endif  // INTERCEPTION_WIN_H\n#endif  // _WIN32\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/.clang-format",
    "content": "BasedOnStyle: Google\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/CMakeLists.txt",
    "content": "include_directories(..)\n\nset(LSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})\nappend_no_rtti_flag(LSAN_CFLAGS)\n\nset(LSAN_COMMON_SOURCES\n  lsan_common.cc\n  lsan_common_linux.cc)\n\nset(LSAN_SOURCES\n  lsan.cc\n  lsan_allocator.cc\n  lsan_interceptors.cc\n  lsan_preinit.cc\n  lsan_thread.cc)\n\nset(LSAN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR})\n\nadd_custom_target(lsan)\n\nadd_compiler_rt_object_libraries(RTLSanCommon\n    OS ${SANITIZER_COMMON_SUPPORTED_OS}\n    ARCHS ${LSAN_COMMON_SUPPORTED_ARCH}\n    SOURCES ${LSAN_COMMON_SOURCES}\n    CFLAGS ${LSAN_CFLAGS})\n\nif(COMPILER_RT_HAS_LSAN)\n  foreach(arch ${LSAN_SUPPORTED_ARCH})\n    add_compiler_rt_runtime(clang_rt.lsan\n      STATIC\n      ARCHS ${arch}\n      SOURCES ${LSAN_SOURCES}\n              $<TARGET_OBJECTS:RTInterception.${arch}>\n              $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>\n              $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>\n              $<TARGET_OBJECTS:RTLSanCommon.${arch}>\n      CFLAGS ${LSAN_CFLAGS}\n      PARENT_TARGET lsan)\n  endforeach()\nendif()\n\nadd_dependencies(compiler-rt lsan)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/Makefile.mk",
    "content": "#===- lib/lsan/Makefile.mk ---------------------------------*- Makefile -*--===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\nModuleName := lsan\nSubDirs := \n\nSources := $(foreach file,$(wildcard $(Dir)/*.cc),$(notdir $(file)))\nObjNames := $(Sources:%.cc=%.o)\n\nImplementation := Generic\n\n# FIXME: use automatic dependencies?\nDependencies := $(wildcard $(Dir)/*.h)\nDependencies += $(wildcard $(Dir)/../interception/*.h)\nDependencies += $(wildcard $(Dir)/../sanitizer_common/*.h)\n\n# lsan functions used in another sanitizers.\nLsanCommonSources := $(foreach file,$(wildcard $(Dir)/lsan_common*.cc),$(notdir $(file)))\nLsanCommonFunctions := $(LsanCommonSources:%.cc=%)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/lsan.cc",
    "content": "//=-- lsan.cc -------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of LeakSanitizer.\n// Standalone LSan RTL.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"lsan.h\"\n\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_flag_parser.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"lsan_allocator.h\"\n#include \"lsan_common.h\"\n#include \"lsan_thread.h\"\n\nbool lsan_inited;\nbool lsan_init_is_running;\n\nnamespace __lsan {\n\n///// Interface to the common LSan module. /////\nbool WordIsPoisoned(uptr addr) {\n  return false;\n}\n\n}  // namespace __lsan\n\nusing namespace __lsan;  // NOLINT\n\nstatic void InitializeFlags() {\n  // Set all the default values.\n  SetCommonFlagsDefaults();\n  {\n    CommonFlags cf;\n    cf.CopyFrom(*common_flags());\n    cf.external_symbolizer_path = GetEnv(\"LSAN_SYMBOLIZER_PATH\");\n    cf.malloc_context_size = 30;\n    cf.detect_leaks = true;\n    cf.exitcode = 23;\n    OverrideCommonFlags(cf);\n  }\n\n  Flags *f = flags();\n  f->SetDefaults();\n\n  FlagParser parser;\n  RegisterLsanFlags(&parser, f);\n  RegisterCommonFlags(&parser);\n\n  parser.ParseString(GetEnv(\"LSAN_OPTIONS\"));\n\n  SetVerbosity(common_flags()->verbosity);\n\n  if (Verbosity()) ReportUnrecognizedFlags();\n\n  if (common_flags()->help) parser.PrintFlagDescriptions();\n}\n\nextern \"C\" void __lsan_init() {\n  CHECK(!lsan_init_is_running);\n  if (lsan_inited)\n    return;\n  lsan_init_is_running = true;\n  SanitizerToolName = \"LeakSanitizer\";\n  CacheBinaryName();\n  InitializeFlags();\n  InitCommonLsan();\n  InitializeAllocator();\n  InitTlsSize();\n  InitializeInterceptors();\n  InitializeThreadRegistry();\n  u32 tid = ThreadCreate(0, 0, true);\n  CHECK_EQ(tid, 0);\n  ThreadStart(tid, GetTid());\n  SetCurrentThread(tid);\n\n  if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit)\n    Atexit(DoLeakCheck);\n\n  InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);\n\n  lsan_inited = true;\n  lsan_init_is_running = false;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_print_stack_trace() {\n  GET_STACK_TRACE_FATAL;\n  stack.Print();\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/lsan.h",
    "content": "//=-- lsan.h --------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of LeakSanitizer.\n// Private header for standalone LSan RTL.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n\n#define GET_STACK_TRACE(max_size, fast)                                        \\\n  BufferedStackTrace stack;                                                    \\\n  {                                                                            \\\n    uptr stack_top = 0, stack_bottom = 0;                                      \\\n    ThreadContext *t;                                                          \\\n    if (fast && (t = CurrentThreadContext())) {                                \\\n      stack_top = t->stack_end();                                              \\\n      stack_bottom = t->stack_begin();                                         \\\n    }                                                                          \\\n    stack.Unwind(max_size, StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(),    \\\n                 /* context */ 0, stack_top, stack_bottom, fast);              \\\n  }\n\n#define GET_STACK_TRACE_FATAL \\\n  GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_fatal)\n\n#define GET_STACK_TRACE_MALLOC                                      \\\n  GET_STACK_TRACE(__sanitizer::common_flags()->malloc_context_size, \\\n                  common_flags()->fast_unwind_on_malloc)\n\nnamespace __lsan {\n\nvoid InitializeInterceptors();\n\n}  // namespace __lsan\n\nextern bool lsan_inited;\nextern bool lsan_init_is_running;\n\nextern \"C\" void __lsan_init();\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/lsan_allocator.cc",
    "content": "//=-- lsan_allocator.cc ---------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of LeakSanitizer.\n// See lsan_allocator.h for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"lsan_allocator.h\"\n\n#include \"sanitizer_common/sanitizer_allocator.h\"\n#include \"sanitizer_common/sanitizer_allocator_interface.h\"\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"lsan_common.h\"\n\nextern \"C\" void *memset(void *ptr, int value, uptr num);\n\nnamespace __lsan {\n\nstruct ChunkMetadata {\n  u8 allocated : 8;  // Must be first.\n  ChunkTag tag : 2;\n  uptr requested_size : 54;\n  u32 stack_trace_id;\n};\n\n#if defined(__mips64) || defined(__aarch64__)\nstatic const uptr kMaxAllowedMallocSize = 4UL << 30;\nstatic const uptr kRegionSizeLog = 20;\nstatic const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;\ntypedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;\ntypedef CompactSizeClassMap SizeClassMap;\ntypedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE,\n    sizeof(ChunkMetadata), SizeClassMap, kRegionSizeLog, ByteMap>\n    PrimaryAllocator;\n#else\nstatic const uptr kMaxAllowedMallocSize = 8UL << 30;\nstatic const uptr kAllocatorSpace = 0x600000000000ULL;\nstatic const uptr kAllocatorSize = 0x40000000000ULL; // 4T.\ntypedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize,\n        sizeof(ChunkMetadata), DefaultSizeClassMap> PrimaryAllocator;\n#endif\ntypedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;\ntypedef LargeMmapAllocator<> SecondaryAllocator;\ntypedef CombinedAllocator<PrimaryAllocator, AllocatorCache,\n          SecondaryAllocator> Allocator;\n\nstatic Allocator allocator;\nstatic THREADLOCAL AllocatorCache cache;\n\nvoid InitializeAllocator() {\n  allocator.InitLinkerInitialized(common_flags()->allocator_may_return_null);\n}\n\nvoid AllocatorThreadFinish() {\n  allocator.SwallowCache(&cache);\n}\n\nstatic ChunkMetadata *Metadata(const void *p) {\n  return reinterpret_cast<ChunkMetadata *>(allocator.GetMetaData(p));\n}\n\nstatic void RegisterAllocation(const StackTrace &stack, void *p, uptr size) {\n  if (!p) return;\n  ChunkMetadata *m = Metadata(p);\n  CHECK(m);\n  m->tag = DisabledInThisThread() ? kIgnored : kDirectlyLeaked;\n  m->stack_trace_id = StackDepotPut(stack);\n  m->requested_size = size;\n  atomic_store(reinterpret_cast<atomic_uint8_t *>(m), 1, memory_order_relaxed);\n}\n\nstatic void RegisterDeallocation(void *p) {\n  if (!p) return;\n  ChunkMetadata *m = Metadata(p);\n  CHECK(m);\n  atomic_store(reinterpret_cast<atomic_uint8_t *>(m), 0, memory_order_relaxed);\n}\n\nvoid *Allocate(const StackTrace &stack, uptr size, uptr alignment,\n               bool cleared) {\n  if (size == 0)\n    size = 1;\n  if (size > kMaxAllowedMallocSize) {\n    Report(\"WARNING: LeakSanitizer failed to allocate %zu bytes\\n\", size);\n    return nullptr;\n  }\n  void *p = allocator.Allocate(&cache, size, alignment, false);\n  // Do not rely on the allocator to clear the memory (it's slow).\n  if (cleared && allocator.FromPrimary(p))\n    memset(p, 0, size);\n  RegisterAllocation(stack, p, size);\n  if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(p, size);\n  return p;\n}\n\nvoid Deallocate(void *p) {\n  if (&__sanitizer_free_hook) __sanitizer_free_hook(p);\n  RegisterDeallocation(p);\n  allocator.Deallocate(&cache, p);\n}\n\nvoid *Reallocate(const StackTrace &stack, void *p, uptr new_size,\n                 uptr alignment) {\n  RegisterDeallocation(p);\n  if (new_size > kMaxAllowedMallocSize) {\n    Report(\"WARNING: LeakSanitizer failed to allocate %zu bytes\\n\", new_size);\n    allocator.Deallocate(&cache, p);\n    return nullptr;\n  }\n  p = allocator.Reallocate(&cache, p, new_size, alignment);\n  RegisterAllocation(stack, p, new_size);\n  return p;\n}\n\nvoid GetAllocatorCacheRange(uptr *begin, uptr *end) {\n  *begin = (uptr)&cache;\n  *end = *begin + sizeof(cache);\n}\n\nuptr GetMallocUsableSize(const void *p) {\n  ChunkMetadata *m = Metadata(p);\n  if (!m) return 0;\n  return m->requested_size;\n}\n\n///// Interface to the common LSan module. /////\n\nvoid LockAllocator() {\n  allocator.ForceLock();\n}\n\nvoid UnlockAllocator() {\n  allocator.ForceUnlock();\n}\n\nvoid GetAllocatorGlobalRange(uptr *begin, uptr *end) {\n  *begin = (uptr)&allocator;\n  *end = *begin + sizeof(allocator);\n}\n\nuptr PointsIntoChunk(void* p) {\n  uptr addr = reinterpret_cast<uptr>(p);\n  uptr chunk = reinterpret_cast<uptr>(allocator.GetBlockBeginFastLocked(p));\n  if (!chunk) return 0;\n  // LargeMmapAllocator considers pointers to the meta-region of a chunk to be\n  // valid, but we don't want that.\n  if (addr < chunk) return 0;\n  ChunkMetadata *m = Metadata(reinterpret_cast<void *>(chunk));\n  CHECK(m);\n  if (!m->allocated)\n    return 0;\n  if (addr < chunk + m->requested_size)\n    return chunk;\n  if (IsSpecialCaseOfOperatorNew0(chunk, m->requested_size, addr))\n    return chunk;\n  return 0;\n}\n\nuptr GetUserBegin(uptr chunk) {\n  return chunk;\n}\n\nLsanMetadata::LsanMetadata(uptr chunk) {\n  metadata_ = Metadata(reinterpret_cast<void *>(chunk));\n  CHECK(metadata_);\n}\n\nbool LsanMetadata::allocated() const {\n  return reinterpret_cast<ChunkMetadata *>(metadata_)->allocated;\n}\n\nChunkTag LsanMetadata::tag() const {\n  return reinterpret_cast<ChunkMetadata *>(metadata_)->tag;\n}\n\nvoid LsanMetadata::set_tag(ChunkTag value) {\n  reinterpret_cast<ChunkMetadata *>(metadata_)->tag = value;\n}\n\nuptr LsanMetadata::requested_size() const {\n  return reinterpret_cast<ChunkMetadata *>(metadata_)->requested_size;\n}\n\nu32 LsanMetadata::stack_trace_id() const {\n  return reinterpret_cast<ChunkMetadata *>(metadata_)->stack_trace_id;\n}\n\nvoid ForEachChunk(ForEachChunkCallback callback, void *arg) {\n  allocator.ForEachChunk(callback, arg);\n}\n\nIgnoreObjectResult IgnoreObjectLocked(const void *p) {\n  void *chunk = allocator.GetBlockBegin(p);\n  if (!chunk || p < chunk) return kIgnoreObjectInvalid;\n  ChunkMetadata *m = Metadata(chunk);\n  CHECK(m);\n  if (m->allocated && (uptr)p < (uptr)chunk + m->requested_size) {\n    if (m->tag == kIgnored)\n      return kIgnoreObjectAlreadyIgnored;\n    m->tag = kIgnored;\n    return kIgnoreObjectSuccess;\n  } else {\n    return kIgnoreObjectInvalid;\n  }\n}\n} // namespace __lsan\n\nusing namespace __lsan;\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE\nuptr __sanitizer_get_current_allocated_bytes() {\n  uptr stats[AllocatorStatCount];\n  allocator.GetStats(stats);\n  return stats[AllocatorStatAllocated];\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nuptr __sanitizer_get_heap_size() {\n  uptr stats[AllocatorStatCount];\n  allocator.GetStats(stats);\n  return stats[AllocatorStatMapped];\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nuptr __sanitizer_get_free_bytes() { return 0; }\n\nSANITIZER_INTERFACE_ATTRIBUTE\nuptr __sanitizer_get_unmapped_bytes() { return 0; }\n\nSANITIZER_INTERFACE_ATTRIBUTE\nuptr __sanitizer_get_estimated_allocated_size(uptr size) { return size; }\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __sanitizer_get_ownership(const void *p) { return Metadata(p) != nullptr; }\n\nSANITIZER_INTERFACE_ATTRIBUTE\nuptr __sanitizer_get_allocated_size(const void *p) {\n  return GetMallocUsableSize(p);\n}\n} // extern \"C\"\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/lsan_allocator.h",
    "content": "//=-- lsan_allocator.h ----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of LeakSanitizer.\n// Allocator for standalone LSan.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef LSAN_ALLOCATOR_H\n#define LSAN_ALLOCATOR_H\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n\nnamespace __lsan {\n\nvoid *Allocate(const StackTrace &stack, uptr size, uptr alignment,\n               bool cleared);\nvoid Deallocate(void *p);\nvoid *Reallocate(const StackTrace &stack, void *p, uptr new_size,\n                 uptr alignment);\nuptr GetMallocUsableSize(const void *p);\n\ntemplate<typename Callable>\nvoid ForEachChunk(const Callable &callback);\n\nvoid GetAllocatorCacheRange(uptr *begin, uptr *end);\nvoid AllocatorThreadFinish();\nvoid InitializeAllocator();\n\n}  // namespace __lsan\n\n#endif  // LSAN_ALLOCATOR_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/lsan_common.cc",
    "content": "//=-- lsan_common.cc ------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of LeakSanitizer.\n// Implementation of common leak checking functionality.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"lsan_common.h\"\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_flag_parser.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_procmaps.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"sanitizer_common/sanitizer_suppressions.h\"\n#include \"sanitizer_common/sanitizer_report_decorator.h\"\n\n#if CAN_SANITIZE_LEAKS\nnamespace __lsan {\n\n// This mutex is used to prevent races between DoLeakCheck and IgnoreObject, and\n// also to protect the global list of root regions.\nBlockingMutex global_mutex(LINKER_INITIALIZED);\n\nTHREADLOCAL int disable_counter;\nbool DisabledInThisThread() { return disable_counter > 0; }\n\nFlags lsan_flags;\n\nvoid Flags::SetDefaults() {\n#define LSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;\n#include \"lsan_flags.inc\"\n#undef LSAN_FLAG\n}\n\nvoid RegisterLsanFlags(FlagParser *parser, Flags *f) {\n#define LSAN_FLAG(Type, Name, DefaultValue, Description) \\\n  RegisterFlag(parser, #Name, Description, &f->Name);\n#include \"lsan_flags.inc\"\n#undef LSAN_FLAG\n}\n\n#define LOG_POINTERS(...)                           \\\n  do {                                              \\\n    if (flags()->log_pointers) Report(__VA_ARGS__); \\\n  } while (0);\n\n#define LOG_THREADS(...)                           \\\n  do {                                             \\\n    if (flags()->log_threads) Report(__VA_ARGS__); \\\n  } while (0);\n\nALIGNED(64) static char suppression_placeholder[sizeof(SuppressionContext)];\nstatic SuppressionContext *suppression_ctx = nullptr;\nstatic const char kSuppressionLeak[] = \"leak\";\nstatic const char *kSuppressionTypes[] = { kSuppressionLeak };\n\nvoid InitializeSuppressions() {\n  CHECK_EQ(nullptr, suppression_ctx);\n  suppression_ctx = new (suppression_placeholder) // NOLINT\n      SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes));\n  suppression_ctx->ParseFromFile(flags()->suppressions);\n  if (&__lsan_default_suppressions)\n    suppression_ctx->Parse(__lsan_default_suppressions());\n}\n\nstatic SuppressionContext *GetSuppressionContext() {\n  CHECK(suppression_ctx);\n  return suppression_ctx;\n}\n\nstruct RootRegion {\n  const void *begin;\n  uptr size;\n};\n\nInternalMmapVector<RootRegion> *root_regions;\n\nvoid InitializeRootRegions() {\n  CHECK(!root_regions);\n  ALIGNED(64) static char placeholder[sizeof(InternalMmapVector<RootRegion>)];\n  root_regions = new(placeholder) InternalMmapVector<RootRegion>(1);\n}\n\nvoid InitCommonLsan() {\n  InitializeRootRegions();\n  if (common_flags()->detect_leaks) {\n    // Initialization which can fail or print warnings should only be done if\n    // LSan is actually enabled.\n    InitializeSuppressions();\n    InitializePlatformSpecificModules();\n  }\n}\n\nclass Decorator: public __sanitizer::SanitizerCommonDecorator {\n public:\n  Decorator() : SanitizerCommonDecorator() { }\n  const char *Error() { return Red(); }\n  const char *Leak() { return Blue(); }\n  const char *End() { return Default(); }\n};\n\nstatic inline bool CanBeAHeapPointer(uptr p) {\n  // Since our heap is located in mmap-ed memory, we can assume a sensible lower\n  // bound on heap addresses.\n  const uptr kMinAddress = 4 * 4096;\n  if (p < kMinAddress) return false;\n#if defined(__x86_64__)\n  // Accept only canonical form user-space addresses.\n  return ((p >> 47) == 0);\n#elif defined(__mips64)\n  return ((p >> 40) == 0);\n#elif defined(__aarch64__)\n  unsigned runtimeVMA =\n    (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1);\n  return ((p >> runtimeVMA) == 0);\n#else\n  return true;\n#endif\n}\n\n// Scans the memory range, looking for byte patterns that point into allocator\n// chunks. Marks those chunks with |tag| and adds them to |frontier|.\n// There are two usage modes for this function: finding reachable chunks\n// (|tag| = kReachable) and finding indirectly leaked chunks\n// (|tag| = kIndirectlyLeaked). In the second case, there's no flood fill,\n// so |frontier| = 0.\nvoid ScanRangeForPointers(uptr begin, uptr end,\n                          Frontier *frontier,\n                          const char *region_type, ChunkTag tag) {\n  CHECK(tag == kReachable || tag == kIndirectlyLeaked);\n  const uptr alignment = flags()->pointer_alignment();\n  LOG_POINTERS(\"Scanning %s range %p-%p.\\n\", region_type, begin, end);\n  uptr pp = begin;\n  if (pp % alignment)\n    pp = pp + alignment - pp % alignment;\n  for (; pp + sizeof(void *) <= end; pp += alignment) {  // NOLINT\n    void *p = *reinterpret_cast<void **>(pp);\n    if (!CanBeAHeapPointer(reinterpret_cast<uptr>(p))) continue;\n    uptr chunk = PointsIntoChunk(p);\n    if (!chunk) continue;\n    // Pointers to self don't count. This matters when tag == kIndirectlyLeaked.\n    if (chunk == begin) continue;\n    LsanMetadata m(chunk);\n    if (m.tag() == kReachable || m.tag() == kIgnored) continue;\n\n    // Do this check relatively late so we can log only the interesting cases.\n    if (!flags()->use_poisoned && WordIsPoisoned(pp)) {\n      LOG_POINTERS(\n          \"%p is poisoned: ignoring %p pointing into chunk %p-%p of size \"\n          \"%zu.\\n\",\n          pp, p, chunk, chunk + m.requested_size(), m.requested_size());\n      continue;\n    }\n\n    m.set_tag(tag);\n    LOG_POINTERS(\"%p: found %p pointing into chunk %p-%p of size %zu.\\n\", pp, p,\n                 chunk, chunk + m.requested_size(), m.requested_size());\n    if (frontier)\n      frontier->push_back(chunk);\n  }\n}\n\nvoid ForEachExtraStackRangeCb(uptr begin, uptr end, void* arg) {\n  Frontier *frontier = reinterpret_cast<Frontier *>(arg);\n  ScanRangeForPointers(begin, end, frontier, \"FAKE STACK\", kReachable);\n}\n\n// Scans thread data (stacks and TLS) for heap pointers.\nstatic void ProcessThreads(SuspendedThreadsList const &suspended_threads,\n                           Frontier *frontier) {\n  InternalScopedBuffer<uptr> registers(SuspendedThreadsList::RegisterCount());\n  uptr registers_begin = reinterpret_cast<uptr>(registers.data());\n  uptr registers_end = registers_begin + registers.size();\n  for (uptr i = 0; i < suspended_threads.thread_count(); i++) {\n    uptr os_id = static_cast<uptr>(suspended_threads.GetThreadID(i));\n    LOG_THREADS(\"Processing thread %d.\\n\", os_id);\n    uptr stack_begin, stack_end, tls_begin, tls_end, cache_begin, cache_end;\n    bool thread_found = GetThreadRangesLocked(os_id, &stack_begin, &stack_end,\n                                              &tls_begin, &tls_end,\n                                              &cache_begin, &cache_end);\n    if (!thread_found) {\n      // If a thread can't be found in the thread registry, it's probably in the\n      // process of destruction. Log this event and move on.\n      LOG_THREADS(\"Thread %d not found in registry.\\n\", os_id);\n      continue;\n    }\n    uptr sp;\n    bool have_registers =\n        (suspended_threads.GetRegistersAndSP(i, registers.data(), &sp) == 0);\n    if (!have_registers) {\n      Report(\"Unable to get registers from thread %d.\\n\");\n      // If unable to get SP, consider the entire stack to be reachable.\n      sp = stack_begin;\n    }\n\n    if (flags()->use_registers && have_registers)\n      ScanRangeForPointers(registers_begin, registers_end, frontier,\n                           \"REGISTERS\", kReachable);\n\n    if (flags()->use_stacks) {\n      LOG_THREADS(\"Stack at %p-%p (SP = %p).\\n\", stack_begin, stack_end, sp);\n      if (sp < stack_begin || sp >= stack_end) {\n        // SP is outside the recorded stack range (e.g. the thread is running a\n        // signal handler on alternate stack). Again, consider the entire stack\n        // range to be reachable.\n        LOG_THREADS(\"WARNING: stack pointer not in stack range.\\n\");\n      } else {\n        // Shrink the stack range to ignore out-of-scope values.\n        stack_begin = sp;\n      }\n      ScanRangeForPointers(stack_begin, stack_end, frontier, \"STACK\",\n                           kReachable);\n      ForEachExtraStackRange(os_id, ForEachExtraStackRangeCb, frontier);\n    }\n\n    if (flags()->use_tls) {\n      LOG_THREADS(\"TLS at %p-%p.\\n\", tls_begin, tls_end);\n      if (cache_begin == cache_end) {\n        ScanRangeForPointers(tls_begin, tls_end, frontier, \"TLS\", kReachable);\n      } else {\n        // Because LSan should not be loaded with dlopen(), we can assume\n        // that allocator cache will be part of static TLS image.\n        CHECK_LE(tls_begin, cache_begin);\n        CHECK_GE(tls_end, cache_end);\n        if (tls_begin < cache_begin)\n          ScanRangeForPointers(tls_begin, cache_begin, frontier, \"TLS\",\n                               kReachable);\n        if (tls_end > cache_end)\n          ScanRangeForPointers(cache_end, tls_end, frontier, \"TLS\", kReachable);\n      }\n    }\n  }\n}\n\nstatic void ProcessRootRegion(Frontier *frontier, uptr root_begin,\n                              uptr root_end) {\n  MemoryMappingLayout proc_maps(/*cache_enabled*/true);\n  uptr begin, end, prot;\n  while (proc_maps.Next(&begin, &end,\n                        /*offset*/ nullptr, /*filename*/ nullptr,\n                        /*filename_size*/ 0, &prot)) {\n    uptr intersection_begin = Max(root_begin, begin);\n    uptr intersection_end = Min(end, root_end);\n    if (intersection_begin >= intersection_end) continue;\n    bool is_readable = prot & MemoryMappingLayout::kProtectionRead;\n    LOG_POINTERS(\"Root region %p-%p intersects with mapped region %p-%p (%s)\\n\",\n                 root_begin, root_end, begin, end,\n                 is_readable ? \"readable\" : \"unreadable\");\n    if (is_readable)\n      ScanRangeForPointers(intersection_begin, intersection_end, frontier,\n                           \"ROOT\", kReachable);\n  }\n}\n\n// Scans root regions for heap pointers.\nstatic void ProcessRootRegions(Frontier *frontier) {\n  if (!flags()->use_root_regions) return;\n  CHECK(root_regions);\n  for (uptr i = 0; i < root_regions->size(); i++) {\n    RootRegion region = (*root_regions)[i];\n    uptr begin_addr = reinterpret_cast<uptr>(region.begin);\n    ProcessRootRegion(frontier, begin_addr, begin_addr + region.size);\n  }\n}\n\nstatic void FloodFillTag(Frontier *frontier, ChunkTag tag) {\n  while (frontier->size()) {\n    uptr next_chunk = frontier->back();\n    frontier->pop_back();\n    LsanMetadata m(next_chunk);\n    ScanRangeForPointers(next_chunk, next_chunk + m.requested_size(), frontier,\n                         \"HEAP\", tag);\n  }\n}\n\n// ForEachChunk callback. If the chunk is marked as leaked, marks all chunks\n// which are reachable from it as indirectly leaked.\nstatic void MarkIndirectlyLeakedCb(uptr chunk, void *arg) {\n  chunk = GetUserBegin(chunk);\n  LsanMetadata m(chunk);\n  if (m.allocated() && m.tag() != kReachable) {\n    ScanRangeForPointers(chunk, chunk + m.requested_size(),\n                         /* frontier */ nullptr, \"HEAP\", kIndirectlyLeaked);\n  }\n}\n\n// ForEachChunk callback. If chunk is marked as ignored, adds its address to\n// frontier.\nstatic void CollectIgnoredCb(uptr chunk, void *arg) {\n  CHECK(arg);\n  chunk = GetUserBegin(chunk);\n  LsanMetadata m(chunk);\n  if (m.allocated() && m.tag() == kIgnored) {\n    LOG_POINTERS(\"Ignored: chunk %p-%p of size %zu.\\n\",\n                 chunk, chunk + m.requested_size(), m.requested_size());\n    reinterpret_cast<Frontier *>(arg)->push_back(chunk);\n  }\n}\n\n// Sets the appropriate tag on each chunk.\nstatic void ClassifyAllChunks(SuspendedThreadsList const &suspended_threads) {\n  // Holds the flood fill frontier.\n  Frontier frontier(1);\n\n  ForEachChunk(CollectIgnoredCb, &frontier);\n  ProcessGlobalRegions(&frontier);\n  ProcessThreads(suspended_threads, &frontier);\n  ProcessRootRegions(&frontier);\n  FloodFillTag(&frontier, kReachable);\n\n  // The check here is relatively expensive, so we do this in a separate flood\n  // fill. That way we can skip the check for chunks that are reachable\n  // otherwise.\n  LOG_POINTERS(\"Processing platform-specific allocations.\\n\");\n  CHECK_EQ(0, frontier.size());\n  ProcessPlatformSpecificAllocations(&frontier);\n  FloodFillTag(&frontier, kReachable);\n\n  // Iterate over leaked chunks and mark those that are reachable from other\n  // leaked chunks.\n  LOG_POINTERS(\"Scanning leaked chunks.\\n\");\n  ForEachChunk(MarkIndirectlyLeakedCb, nullptr);\n}\n\n// ForEachChunk callback. Resets the tags to pre-leak-check state.\nstatic void ResetTagsCb(uptr chunk, void *arg) {\n  (void)arg;\n  chunk = GetUserBegin(chunk);\n  LsanMetadata m(chunk);\n  if (m.allocated() && m.tag() != kIgnored)\n    m.set_tag(kDirectlyLeaked);\n}\n\nstatic void PrintStackTraceById(u32 stack_trace_id) {\n  CHECK(stack_trace_id);\n  StackDepotGet(stack_trace_id).Print();\n}\n\n// ForEachChunk callback. Aggregates information about unreachable chunks into\n// a LeakReport.\nstatic void CollectLeaksCb(uptr chunk, void *arg) {\n  CHECK(arg);\n  LeakReport *leak_report = reinterpret_cast<LeakReport *>(arg);\n  chunk = GetUserBegin(chunk);\n  LsanMetadata m(chunk);\n  if (!m.allocated()) return;\n  if (m.tag() == kDirectlyLeaked || m.tag() == kIndirectlyLeaked) {\n    u32 resolution = flags()->resolution;\n    u32 stack_trace_id = 0;\n    if (resolution > 0) {\n      StackTrace stack = StackDepotGet(m.stack_trace_id());\n      stack.size = Min(stack.size, resolution);\n      stack_trace_id = StackDepotPut(stack);\n    } else {\n      stack_trace_id = m.stack_trace_id();\n    }\n    leak_report->AddLeakedChunk(chunk, stack_trace_id, m.requested_size(),\n                                m.tag());\n  }\n}\n\nstatic void PrintMatchedSuppressions() {\n  InternalMmapVector<Suppression *> matched(1);\n  GetSuppressionContext()->GetMatched(&matched);\n  if (!matched.size())\n    return;\n  const char *line = \"-----------------------------------------------------\";\n  Printf(\"%s\\n\", line);\n  Printf(\"Suppressions used:\\n\");\n  Printf(\"  count      bytes template\\n\");\n  for (uptr i = 0; i < matched.size(); i++)\n    Printf(\"%7zu %10zu %s\\n\", static_cast<uptr>(atomic_load_relaxed(\n        &matched[i]->hit_count)), matched[i]->weight, matched[i]->templ);\n  Printf(\"%s\\n\\n\", line);\n}\n\nstruct CheckForLeaksParam {\n  bool success;\n  LeakReport leak_report;\n};\n\nstatic void CheckForLeaksCallback(const SuspendedThreadsList &suspended_threads,\n                                  void *arg) {\n  CheckForLeaksParam *param = reinterpret_cast<CheckForLeaksParam *>(arg);\n  CHECK(param);\n  CHECK(!param->success);\n  ClassifyAllChunks(suspended_threads);\n  ForEachChunk(CollectLeaksCb, &param->leak_report);\n  // Clean up for subsequent leak checks. This assumes we did not overwrite any\n  // kIgnored tags.\n  ForEachChunk(ResetTagsCb, nullptr);\n  param->success = true;\n}\n\nstatic bool CheckForLeaks() {\n  if (&__lsan_is_turned_off && __lsan_is_turned_off())\n      return false;\n  EnsureMainThreadIDIsCorrect();\n  CheckForLeaksParam param;\n  param.success = false;\n  LockThreadRegistry();\n  LockAllocator();\n  DoStopTheWorld(CheckForLeaksCallback, &param);\n  UnlockAllocator();\n  UnlockThreadRegistry();\n\n  if (!param.success) {\n    Report(\"LeakSanitizer has encountered a fatal error.\\n\");\n    Die();\n  }\n  param.leak_report.ApplySuppressions();\n  uptr unsuppressed_count = param.leak_report.UnsuppressedLeakCount();\n  if (unsuppressed_count > 0) {\n    Decorator d;\n    Printf(\"\\n\"\n           \"=================================================================\"\n           \"\\n\");\n    Printf(\"%s\", d.Error());\n    Report(\"ERROR: LeakSanitizer: detected memory leaks\\n\");\n    Printf(\"%s\", d.End());\n    param.leak_report.ReportTopLeaks(flags()->max_leaks);\n  }\n  if (common_flags()->print_suppressions)\n    PrintMatchedSuppressions();\n  if (unsuppressed_count > 0) {\n    param.leak_report.PrintSummary();\n    return true;\n  }\n  return false;\n}\n\nvoid DoLeakCheck() {\n  BlockingMutexLock l(&global_mutex);\n  static bool already_done;\n  if (already_done) return;\n  already_done = true;\n  bool have_leaks = CheckForLeaks();\n  if (!have_leaks) {\n    return;\n  }\n  if (common_flags()->exitcode) {\n    Die();\n  }\n}\n\nstatic int DoRecoverableLeakCheck() {\n  BlockingMutexLock l(&global_mutex);\n  bool have_leaks = CheckForLeaks();\n  return have_leaks ? 1 : 0;\n}\n\nstatic Suppression *GetSuppressionForAddr(uptr addr) {\n  Suppression *s = nullptr;\n\n  // Suppress by module name.\n  SuppressionContext *suppressions = GetSuppressionContext();\n  if (const char *module_name =\n          Symbolizer::GetOrInit()->GetModuleNameForPc(addr))\n    if (suppressions->Match(module_name, kSuppressionLeak, &s))\n      return s;\n\n  // Suppress by file or function name.\n  SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(addr);\n  for (SymbolizedStack *cur = frames; cur; cur = cur->next) {\n    if (suppressions->Match(cur->info.function, kSuppressionLeak, &s) ||\n        suppressions->Match(cur->info.file, kSuppressionLeak, &s)) {\n      break;\n    }\n  }\n  frames->ClearAll();\n  return s;\n}\n\nstatic Suppression *GetSuppressionForStack(u32 stack_trace_id) {\n  StackTrace stack = StackDepotGet(stack_trace_id);\n  for (uptr i = 0; i < stack.size; i++) {\n    Suppression *s = GetSuppressionForAddr(\n        StackTrace::GetPreviousInstructionPc(stack.trace[i]));\n    if (s) return s;\n  }\n  return nullptr;\n}\n\n///// LeakReport implementation. /////\n\n// A hard limit on the number of distinct leaks, to avoid quadratic complexity\n// in LeakReport::AddLeakedChunk(). We don't expect to ever see this many leaks\n// in real-world applications.\n// FIXME: Get rid of this limit by changing the implementation of LeakReport to\n// use a hash table.\nconst uptr kMaxLeaksConsidered = 5000;\n\nvoid LeakReport::AddLeakedChunk(uptr chunk, u32 stack_trace_id,\n                                uptr leaked_size, ChunkTag tag) {\n  CHECK(tag == kDirectlyLeaked || tag == kIndirectlyLeaked);\n  bool is_directly_leaked = (tag == kDirectlyLeaked);\n  uptr i;\n  for (i = 0; i < leaks_.size(); i++) {\n    if (leaks_[i].stack_trace_id == stack_trace_id &&\n        leaks_[i].is_directly_leaked == is_directly_leaked) {\n      leaks_[i].hit_count++;\n      leaks_[i].total_size += leaked_size;\n      break;\n    }\n  }\n  if (i == leaks_.size()) {\n    if (leaks_.size() == kMaxLeaksConsidered) return;\n    Leak leak = { next_id_++, /* hit_count */ 1, leaked_size, stack_trace_id,\n                  is_directly_leaked, /* is_suppressed */ false };\n    leaks_.push_back(leak);\n  }\n  if (flags()->report_objects) {\n    LeakedObject obj = {leaks_[i].id, chunk, leaked_size};\n    leaked_objects_.push_back(obj);\n  }\n}\n\nstatic bool LeakComparator(const Leak &leak1, const Leak &leak2) {\n  if (leak1.is_directly_leaked == leak2.is_directly_leaked)\n    return leak1.total_size > leak2.total_size;\n  else\n    return leak1.is_directly_leaked;\n}\n\nvoid LeakReport::ReportTopLeaks(uptr num_leaks_to_report) {\n  CHECK(leaks_.size() <= kMaxLeaksConsidered);\n  Printf(\"\\n\");\n  if (leaks_.size() == kMaxLeaksConsidered)\n    Printf(\"Too many leaks! Only the first %zu leaks encountered will be \"\n           \"reported.\\n\",\n           kMaxLeaksConsidered);\n\n  uptr unsuppressed_count = UnsuppressedLeakCount();\n  if (num_leaks_to_report > 0 && num_leaks_to_report < unsuppressed_count)\n    Printf(\"The %zu top leak(s):\\n\", num_leaks_to_report);\n  InternalSort(&leaks_, leaks_.size(), LeakComparator);\n  uptr leaks_reported = 0;\n  for (uptr i = 0; i < leaks_.size(); i++) {\n    if (leaks_[i].is_suppressed) continue;\n    PrintReportForLeak(i);\n    leaks_reported++;\n    if (leaks_reported == num_leaks_to_report) break;\n  }\n  if (leaks_reported < unsuppressed_count) {\n    uptr remaining = unsuppressed_count - leaks_reported;\n    Printf(\"Omitting %zu more leak(s).\\n\", remaining);\n  }\n}\n\nvoid LeakReport::PrintReportForLeak(uptr index) {\n  Decorator d;\n  Printf(\"%s\", d.Leak());\n  Printf(\"%s leak of %zu byte(s) in %zu object(s) allocated from:\\n\",\n         leaks_[index].is_directly_leaked ? \"Direct\" : \"Indirect\",\n         leaks_[index].total_size, leaks_[index].hit_count);\n  Printf(\"%s\", d.End());\n\n  PrintStackTraceById(leaks_[index].stack_trace_id);\n\n  if (flags()->report_objects) {\n    Printf(\"Objects leaked above:\\n\");\n    PrintLeakedObjectsForLeak(index);\n    Printf(\"\\n\");\n  }\n}\n\nvoid LeakReport::PrintLeakedObjectsForLeak(uptr index) {\n  u32 leak_id = leaks_[index].id;\n  for (uptr j = 0; j < leaked_objects_.size(); j++) {\n    if (leaked_objects_[j].leak_id == leak_id)\n      Printf(\"%p (%zu bytes)\\n\", leaked_objects_[j].addr,\n             leaked_objects_[j].size);\n  }\n}\n\nvoid LeakReport::PrintSummary() {\n  CHECK(leaks_.size() <= kMaxLeaksConsidered);\n  uptr bytes = 0, allocations = 0;\n  for (uptr i = 0; i < leaks_.size(); i++) {\n      if (leaks_[i].is_suppressed) continue;\n      bytes += leaks_[i].total_size;\n      allocations += leaks_[i].hit_count;\n  }\n  InternalScopedString summary(kMaxSummaryLength);\n  summary.append(\"%zu byte(s) leaked in %zu allocation(s).\", bytes,\n                 allocations);\n  ReportErrorSummary(summary.data());\n}\n\nvoid LeakReport::ApplySuppressions() {\n  for (uptr i = 0; i < leaks_.size(); i++) {\n    Suppression *s = GetSuppressionForStack(leaks_[i].stack_trace_id);\n    if (s) {\n      s->weight += leaks_[i].total_size;\n      atomic_store_relaxed(&s->hit_count, atomic_load_relaxed(&s->hit_count) +\n          leaks_[i].hit_count);\n      leaks_[i].is_suppressed = true;\n    }\n  }\n}\n\nuptr LeakReport::UnsuppressedLeakCount() {\n  uptr result = 0;\n  for (uptr i = 0; i < leaks_.size(); i++)\n    if (!leaks_[i].is_suppressed) result++;\n  return result;\n}\n\n} // namespace __lsan\n#endif // CAN_SANITIZE_LEAKS\n\nusing namespace __lsan;  // NOLINT\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __lsan_ignore_object(const void *p) {\n#if CAN_SANITIZE_LEAKS\n  if (!common_flags()->detect_leaks)\n    return;\n  // Cannot use PointsIntoChunk or LsanMetadata here, since the allocator is not\n  // locked.\n  BlockingMutexLock l(&global_mutex);\n  IgnoreObjectResult res = IgnoreObjectLocked(p);\n  if (res == kIgnoreObjectInvalid)\n    VReport(1, \"__lsan_ignore_object(): no heap object found at %p\", p);\n  if (res == kIgnoreObjectAlreadyIgnored)\n    VReport(1, \"__lsan_ignore_object(): \"\n           \"heap object at %p is already being ignored\\n\", p);\n  if (res == kIgnoreObjectSuccess)\n    VReport(1, \"__lsan_ignore_object(): ignoring heap object at %p\\n\", p);\n#endif // CAN_SANITIZE_LEAKS\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __lsan_register_root_region(const void *begin, uptr size) {\n#if CAN_SANITIZE_LEAKS\n  BlockingMutexLock l(&global_mutex);\n  CHECK(root_regions);\n  RootRegion region = {begin, size};\n  root_regions->push_back(region);\n  VReport(1, \"Registered root region at %p of size %llu\\n\", begin, size);\n#endif // CAN_SANITIZE_LEAKS\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __lsan_unregister_root_region(const void *begin, uptr size) {\n#if CAN_SANITIZE_LEAKS\n  BlockingMutexLock l(&global_mutex);\n  CHECK(root_regions);\n  bool removed = false;\n  for (uptr i = 0; i < root_regions->size(); i++) {\n    RootRegion region = (*root_regions)[i];\n    if (region.begin == begin && region.size == size) {\n      removed = true;\n      uptr last_index = root_regions->size() - 1;\n      (*root_regions)[i] = (*root_regions)[last_index];\n      root_regions->pop_back();\n      VReport(1, \"Unregistered root region at %p of size %llu\\n\", begin, size);\n      break;\n    }\n  }\n  if (!removed) {\n    Report(\n        \"__lsan_unregister_root_region(): region at %p of size %llu has not \"\n        \"been registered.\\n\",\n        begin, size);\n    Die();\n  }\n#endif // CAN_SANITIZE_LEAKS\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __lsan_disable() {\n#if CAN_SANITIZE_LEAKS\n  __lsan::disable_counter++;\n#endif\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __lsan_enable() {\n#if CAN_SANITIZE_LEAKS\n  if (!__lsan::disable_counter && common_flags()->detect_leaks) {\n    Report(\"Unmatched call to __lsan_enable().\\n\");\n    Die();\n  }\n  __lsan::disable_counter--;\n#endif\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __lsan_do_leak_check() {\n#if CAN_SANITIZE_LEAKS\n  if (common_flags()->detect_leaks)\n    __lsan::DoLeakCheck();\n#endif // CAN_SANITIZE_LEAKS\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __lsan_do_recoverable_leak_check() {\n#if CAN_SANITIZE_LEAKS\n  if (common_flags()->detect_leaks)\n    return __lsan::DoRecoverableLeakCheck();\n#endif // CAN_SANITIZE_LEAKS\n  return 0;\n}\n\n#if !SANITIZER_SUPPORTS_WEAK_HOOKS\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nint __lsan_is_turned_off() {\n  return 0;\n}\n#endif\n} // extern \"C\"\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/lsan_common.h",
    "content": "//=-- lsan_common.h -------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of LeakSanitizer.\n// Private LSan header.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef LSAN_COMMON_H\n#define LSAN_COMMON_H\n\n#include \"sanitizer_common/sanitizer_allocator.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"sanitizer_common/sanitizer_platform.h\"\n#include \"sanitizer_common/sanitizer_stoptheworld.h\"\n#include \"sanitizer_common/sanitizer_symbolizer.h\"\n\n#if (SANITIZER_LINUX && !SANITIZER_ANDROID) && (SANITIZER_WORDSIZE == 64) \\\n     && (defined(__x86_64__) ||  defined(__mips64) ||  defined(__aarch64__))\n#define CAN_SANITIZE_LEAKS 1\n#else\n#define CAN_SANITIZE_LEAKS 0\n#endif\n\nnamespace __sanitizer {\nclass FlagParser;\n}\n\nnamespace __lsan {\n\n// Chunk tags.\nenum ChunkTag {\n  kDirectlyLeaked = 0,  // default\n  kIndirectlyLeaked = 1,\n  kReachable = 2,\n  kIgnored = 3\n};\n\nstruct Flags {\n#define LSAN_FLAG(Type, Name, DefaultValue, Description) Type Name;\n#include \"lsan_flags.inc\"\n#undef LSAN_FLAG\n\n  void SetDefaults();\n  uptr pointer_alignment() const {\n    return use_unaligned ? 1 : sizeof(uptr);\n  }\n};\n\nextern Flags lsan_flags;\ninline Flags *flags() { return &lsan_flags; }\nvoid RegisterLsanFlags(FlagParser *parser, Flags *f);\n\nstruct Leak {\n  u32 id;\n  uptr hit_count;\n  uptr total_size;\n  u32 stack_trace_id;\n  bool is_directly_leaked;\n  bool is_suppressed;\n};\n\nstruct LeakedObject {\n  u32 leak_id;\n  uptr addr;\n  uptr size;\n};\n\n// Aggregates leaks by stack trace prefix.\nclass LeakReport {\n public:\n  LeakReport() : next_id_(0), leaks_(1), leaked_objects_(1) {}\n  void AddLeakedChunk(uptr chunk, u32 stack_trace_id, uptr leaked_size,\n                      ChunkTag tag);\n  void ReportTopLeaks(uptr max_leaks);\n  void PrintSummary();\n  void ApplySuppressions();\n  uptr UnsuppressedLeakCount();\n\n\n private:\n  void PrintReportForLeak(uptr index);\n  void PrintLeakedObjectsForLeak(uptr index);\n\n  u32 next_id_;\n  InternalMmapVector<Leak> leaks_;\n  InternalMmapVector<LeakedObject> leaked_objects_;\n};\n\ntypedef InternalMmapVector<uptr> Frontier;\n\n// Platform-specific functions.\nvoid InitializePlatformSpecificModules();\nvoid ProcessGlobalRegions(Frontier *frontier);\nvoid ProcessPlatformSpecificAllocations(Frontier *frontier);\n// Run stoptheworld while holding any platform-specific locks.\nvoid DoStopTheWorld(StopTheWorldCallback callback, void* argument);\n\nvoid ScanRangeForPointers(uptr begin, uptr end,\n                          Frontier *frontier,\n                          const char *region_type, ChunkTag tag);\n\nenum IgnoreObjectResult {\n  kIgnoreObjectSuccess,\n  kIgnoreObjectAlreadyIgnored,\n  kIgnoreObjectInvalid\n};\n\n// Functions called from the parent tool.\nvoid InitCommonLsan();\nvoid DoLeakCheck();\nbool DisabledInThisThread();\n\n// Special case for \"new T[0]\" where T is a type with DTOR.\n// new T[0] will allocate one word for the array size (0) and store a pointer\n// to the end of allocated chunk.\ninline bool IsSpecialCaseOfOperatorNew0(uptr chunk_beg, uptr chunk_size,\n                                        uptr addr) {\n  return chunk_size == sizeof(uptr) && chunk_beg + chunk_size == addr &&\n         *reinterpret_cast<uptr *>(chunk_beg) == 0;\n}\n\n// The following must be implemented in the parent tool.\n\nvoid ForEachChunk(ForEachChunkCallback callback, void *arg);\n// Returns the address range occupied by the global allocator object.\nvoid GetAllocatorGlobalRange(uptr *begin, uptr *end);\n// Wrappers for allocator's ForceLock()/ForceUnlock().\nvoid LockAllocator();\nvoid UnlockAllocator();\n// Returns true if [addr, addr + sizeof(void *)) is poisoned.\nbool WordIsPoisoned(uptr addr);\n// Wrappers for ThreadRegistry access.\nvoid LockThreadRegistry();\nvoid UnlockThreadRegistry();\nbool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end,\n                           uptr *tls_begin, uptr *tls_end,\n                           uptr *cache_begin, uptr *cache_end);\nvoid ForEachExtraStackRange(uptr os_id, RangeIteratorCallback callback,\n                            void *arg);\n// If called from the main thread, updates the main thread's TID in the thread\n// registry. We need this to handle processes that fork() without a subsequent\n// exec(), which invalidates the recorded TID. To update it, we must call\n// gettid() from the main thread. Our solution is to call this function before\n// leak checking and also before every call to pthread_create() (to handle cases\n// where leak checking is initiated from a non-main thread).\nvoid EnsureMainThreadIDIsCorrect();\n// If p points into a chunk that has been allocated to the user, returns its\n// user-visible address. Otherwise, returns 0.\nuptr PointsIntoChunk(void *p);\n// Returns address of user-visible chunk contained in this allocator chunk.\nuptr GetUserBegin(uptr chunk);\n// Helper for __lsan_ignore_object().\nIgnoreObjectResult IgnoreObjectLocked(const void *p);\n// Wrapper for chunk metadata operations.\nclass LsanMetadata {\n public:\n  // Constructor accepts address of user-visible chunk.\n  explicit LsanMetadata(uptr chunk);\n  bool allocated() const;\n  ChunkTag tag() const;\n  void set_tag(ChunkTag value);\n  uptr requested_size() const;\n  u32 stack_trace_id() const;\n private:\n  void *metadata_;\n};\n\n}  // namespace __lsan\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nint __lsan_is_turned_off();\n\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nconst char *__lsan_default_suppressions();\n}  // extern \"C\"\n\n#endif  // LSAN_COMMON_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/lsan_common_linux.cc",
    "content": "//=-- lsan_common_linux.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of LeakSanitizer.\n// Implementation of common leak checking functionality. Linux-specific code.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#include \"lsan_common.h\"\n\n#if CAN_SANITIZE_LEAKS && SANITIZER_LINUX\n#include <link.h>\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_linux.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n\nnamespace __lsan {\n\nstatic const char kLinkerName[] = \"ld\";\n// We request 2 modules matching \"ld\", so we can print a warning if there's more\n// than one match. But only the first one is actually used.\nstatic char linker_placeholder[2 * sizeof(LoadedModule)] ALIGNED(64);\nstatic LoadedModule *linker = nullptr;\n\nstatic bool IsLinker(const char* full_name) {\n  return LibraryNameIs(full_name, kLinkerName);\n}\n\nvoid InitializePlatformSpecificModules() {\n  internal_memset(linker_placeholder, 0, sizeof(linker_placeholder));\n  uptr num_matches = GetListOfModules(\n      reinterpret_cast<LoadedModule *>(linker_placeholder), 2, IsLinker);\n  if (num_matches == 1) {\n    linker = reinterpret_cast<LoadedModule *>(linker_placeholder);\n    return;\n  }\n  if (num_matches == 0)\n    VReport(1, \"LeakSanitizer: Dynamic linker not found. \"\n            \"TLS will not be handled correctly.\\n\");\n  else if (num_matches > 1)\n    VReport(1, \"LeakSanitizer: Multiple modules match \\\"%s\\\". \"\n            \"TLS will not be handled correctly.\\n\", kLinkerName);\n  linker = nullptr;\n}\n\nstatic int ProcessGlobalRegionsCallback(struct dl_phdr_info *info, size_t size,\n                                        void *data) {\n  Frontier *frontier = reinterpret_cast<Frontier *>(data);\n  for (uptr j = 0; j < info->dlpi_phnum; j++) {\n    const ElfW(Phdr) *phdr = &(info->dlpi_phdr[j]);\n    // We're looking for .data and .bss sections, which reside in writeable,\n    // loadable segments.\n    if (!(phdr->p_flags & PF_W) || (phdr->p_type != PT_LOAD) ||\n        (phdr->p_memsz == 0))\n      continue;\n    uptr begin = info->dlpi_addr + phdr->p_vaddr;\n    uptr end = begin + phdr->p_memsz;\n    uptr allocator_begin = 0, allocator_end = 0;\n    GetAllocatorGlobalRange(&allocator_begin, &allocator_end);\n    if (begin <= allocator_begin && allocator_begin < end) {\n      CHECK_LE(allocator_begin, allocator_end);\n      CHECK_LT(allocator_end, end);\n      if (begin < allocator_begin)\n        ScanRangeForPointers(begin, allocator_begin, frontier, \"GLOBAL\",\n                             kReachable);\n      if (allocator_end < end)\n        ScanRangeForPointers(allocator_end, end, frontier, \"GLOBAL\",\n                             kReachable);\n    } else {\n      ScanRangeForPointers(begin, end, frontier, \"GLOBAL\", kReachable);\n    }\n  }\n  return 0;\n}\n\n// Scans global variables for heap pointers.\nvoid ProcessGlobalRegions(Frontier *frontier) {\n  if (!flags()->use_globals) return;\n  dl_iterate_phdr(ProcessGlobalRegionsCallback, frontier);\n}\n\nstatic uptr GetCallerPC(u32 stack_id, StackDepotReverseMap *map) {\n  CHECK(stack_id);\n  StackTrace stack = map->Get(stack_id);\n  // The top frame is our malloc/calloc/etc. The next frame is the caller.\n  if (stack.size >= 2)\n    return stack.trace[1];\n  return 0;\n}\n\nstruct ProcessPlatformAllocParam {\n  Frontier *frontier;\n  StackDepotReverseMap *stack_depot_reverse_map;\n};\n\n// ForEachChunk callback. Identifies unreachable chunks which must be treated as\n// reachable. Marks them as reachable and adds them to the frontier.\nstatic void ProcessPlatformSpecificAllocationsCb(uptr chunk, void *arg) {\n  CHECK(arg);\n  ProcessPlatformAllocParam *param =\n      reinterpret_cast<ProcessPlatformAllocParam *>(arg);\n  chunk = GetUserBegin(chunk);\n  LsanMetadata m(chunk);\n  if (m.allocated() && m.tag() != kReachable && m.tag() != kIgnored) {\n    u32 stack_id = m.stack_trace_id();\n    uptr caller_pc = 0;\n    if (stack_id > 0)\n      caller_pc = GetCallerPC(stack_id, param->stack_depot_reverse_map);\n    // If caller_pc is unknown, this chunk may be allocated in a coroutine. Mark\n    // it as reachable, as we can't properly report its allocation stack anyway.\n    if (caller_pc == 0 || linker->containsAddress(caller_pc)) {\n      m.set_tag(kReachable);\n      param->frontier->push_back(chunk);\n    }\n  }\n}\n\n// Handles dynamically allocated TLS blocks by treating all chunks allocated\n// from ld-linux.so as reachable.\n// Dynamic TLS blocks contain the TLS variables of dynamically loaded modules.\n// They are allocated with a __libc_memalign() call in allocate_and_init()\n// (elf/dl-tls.c). Glibc won't tell us the address ranges occupied by those\n// blocks, but we can make sure they come from our own allocator by intercepting\n// __libc_memalign(). On top of that, there is no easy way to reach them. Their\n// addresses are stored in a dynamically allocated array (the DTV) which is\n// referenced from the static TLS. Unfortunately, we can't just rely on the DTV\n// being reachable from the static TLS, and the dynamic TLS being reachable from\n// the DTV. This is because the initial DTV is allocated before our interception\n// mechanism kicks in, and thus we don't recognize it as allocated memory. We\n// can't special-case it either, since we don't know its size.\n// Our solution is to include in the root set all allocations made from\n// ld-linux.so (which is where allocate_and_init() is implemented). This is\n// guaranteed to include all dynamic TLS blocks (and possibly other allocations\n// which we don't care about).\nvoid ProcessPlatformSpecificAllocations(Frontier *frontier) {\n  if (!flags()->use_tls) return;\n  if (!linker) return;\n  StackDepotReverseMap stack_depot_reverse_map;\n  ProcessPlatformAllocParam arg = {frontier, &stack_depot_reverse_map};\n  ForEachChunk(ProcessPlatformSpecificAllocationsCb, &arg);\n}\n\nstruct DoStopTheWorldParam {\n  StopTheWorldCallback callback;\n  void *argument;\n};\n\nstatic int DoStopTheWorldCallback(struct dl_phdr_info *info, size_t size,\n                                  void *data) {\n  DoStopTheWorldParam *param = reinterpret_cast<DoStopTheWorldParam *>(data);\n  StopTheWorld(param->callback, param->argument);\n  return 1;\n}\n\n// LSan calls dl_iterate_phdr() from the tracer task. This may deadlock: if one\n// of the threads is frozen while holding the libdl lock, the tracer will hang\n// in dl_iterate_phdr() forever.\n// Luckily, (a) the lock is reentrant and (b) libc can't distinguish between the\n// tracer task and the thread that spawned it. Thus, if we run the tracer task\n// while holding the libdl lock in the parent thread, we can safely reenter it\n// in the tracer. The solution is to run stoptheworld from a dl_iterate_phdr()\n// callback in the parent thread.\nvoid DoStopTheWorld(StopTheWorldCallback callback, void *argument) {\n  DoStopTheWorldParam param = {callback, argument};\n  dl_iterate_phdr(DoStopTheWorldCallback, &param);\n}\n\n} // namespace __lsan\n\n#endif // CAN_SANITIZE_LEAKS && SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/lsan_flags.inc",
    "content": "//===-- lsan_flags.inc ------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// LSan runtime flags.\n//\n//===----------------------------------------------------------------------===//\n#ifndef LSAN_FLAG\n# error \"Define LSAN_FLAG prior to including this file!\"\n#endif\n\n// LSAN_FLAG(Type, Name, DefaultValue, Description)\n// See COMMON_FLAG in sanitizer_flags.inc for more details.\n\nLSAN_FLAG(bool, report_objects, false,\n          \"Print addresses of leaked objects after main leak report.\")\nLSAN_FLAG(\n    int, resolution, 0,\n    \"Aggregate two objects into one leak if this many stack frames match. If \"\n    \"zero, the entire stack trace must match.\")\nLSAN_FLAG(int, max_leaks, 0, \"The number of leaks reported.\")\n\n// Flags controlling the root set of reachable memory.\nLSAN_FLAG(bool, use_globals, true,\n          \"Root set: include global variables (.data and .bss)\")\nLSAN_FLAG(bool, use_stacks, true, \"Root set: include thread stacks\")\nLSAN_FLAG(bool, use_registers, true, \"Root set: include thread registers\")\nLSAN_FLAG(bool, use_tls, true,\n          \"Root set: include TLS and thread-specific storage\")\nLSAN_FLAG(bool, use_root_regions, true,\n          \"Root set: include regions added via __lsan_register_root_region().\")\n\nLSAN_FLAG(bool, use_unaligned, false, \"Consider unaligned pointers valid.\")\nLSAN_FLAG(bool, use_poisoned, false,\n          \"Consider pointers found in poisoned memory to be valid.\")\nLSAN_FLAG(bool, log_pointers, false, \"Debug logging\")\nLSAN_FLAG(bool, log_threads, false, \"Debug logging\")\nLSAN_FLAG(const char *, suppressions, \"\", \"Suppressions file name.\")\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/lsan_interceptors.cc",
    "content": "//=-- lsan_interceptors.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of LeakSanitizer.\n// Interceptors for standalone LSan.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"interception/interception.h\"\n#include \"sanitizer_common/sanitizer_allocator.h\"\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"sanitizer_common/sanitizer_linux.h\"\n#include \"sanitizer_common/sanitizer_platform_limits_posix.h\"\n#include \"lsan.h\"\n#include \"lsan_allocator.h\"\n#include \"lsan_thread.h\"\n\nusing namespace __lsan;\n\nextern \"C\" {\nint pthread_attr_init(void *attr);\nint pthread_attr_destroy(void *attr);\nint pthread_attr_getdetachstate(void *attr, int *v);\nint pthread_key_create(unsigned *key, void (*destructor)(void* v));\nint pthread_setspecific(unsigned key, const void *v);\n}\n\n#define ENSURE_LSAN_INITED do {   \\\n  CHECK(!lsan_init_is_running);   \\\n  if (!lsan_inited)               \\\n    __lsan_init();                \\\n} while (0)\n\n///// Malloc/free interceptors. /////\n\nconst bool kAlwaysClearMemory = true;\n\nnamespace std {\n  struct nothrow_t;\n}\n\nINTERCEPTOR(void*, malloc, uptr size) {\n  ENSURE_LSAN_INITED;\n  GET_STACK_TRACE_MALLOC;\n  return Allocate(stack, size, 1, kAlwaysClearMemory);\n}\n\nINTERCEPTOR(void, free, void *p) {\n  ENSURE_LSAN_INITED;\n  Deallocate(p);\n}\n\nINTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {\n  if (lsan_init_is_running) {\n    // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.\n    const uptr kCallocPoolSize = 1024;\n    static uptr calloc_memory_for_dlsym[kCallocPoolSize];\n    static uptr allocated;\n    uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;\n    void *mem = (void*)&calloc_memory_for_dlsym[allocated];\n    allocated += size_in_words;\n    CHECK(allocated < kCallocPoolSize);\n    return mem;\n  }\n  if (CallocShouldReturnNullDueToOverflow(size, nmemb)) return nullptr;\n  ENSURE_LSAN_INITED;\n  GET_STACK_TRACE_MALLOC;\n  size *= nmemb;\n  return Allocate(stack, size, 1, true);\n}\n\nINTERCEPTOR(void*, realloc, void *q, uptr size) {\n  ENSURE_LSAN_INITED;\n  GET_STACK_TRACE_MALLOC;\n  return Reallocate(stack, q, size, 1);\n}\n\nINTERCEPTOR(void*, memalign, uptr alignment, uptr size) {\n  ENSURE_LSAN_INITED;\n  GET_STACK_TRACE_MALLOC;\n  return Allocate(stack, size, alignment, kAlwaysClearMemory);\n}\n\nINTERCEPTOR(void*, aligned_alloc, uptr alignment, uptr size) {\n  ENSURE_LSAN_INITED;\n  GET_STACK_TRACE_MALLOC;\n  return Allocate(stack, size, alignment, kAlwaysClearMemory);\n}\n\nINTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {\n  ENSURE_LSAN_INITED;\n  GET_STACK_TRACE_MALLOC;\n  *memptr = Allocate(stack, size, alignment, kAlwaysClearMemory);\n  // FIXME: Return ENOMEM if user requested more than max alloc size.\n  return 0;\n}\n\nINTERCEPTOR(void*, valloc, uptr size) {\n  ENSURE_LSAN_INITED;\n  GET_STACK_TRACE_MALLOC;\n  if (size == 0)\n    size = GetPageSizeCached();\n  return Allocate(stack, size, GetPageSizeCached(), kAlwaysClearMemory);\n}\n\nINTERCEPTOR(uptr, malloc_usable_size, void *ptr) {\n  ENSURE_LSAN_INITED;\n  return GetMallocUsableSize(ptr);\n}\n\nstruct fake_mallinfo {\n  int x[10];\n};\n\nINTERCEPTOR(struct fake_mallinfo, mallinfo, void) {\n  struct fake_mallinfo res;\n  internal_memset(&res, 0, sizeof(res));\n  return res;\n}\n\nINTERCEPTOR(int, mallopt, int cmd, int value) {\n  return -1;\n}\n\nINTERCEPTOR(void*, pvalloc, uptr size) {\n  ENSURE_LSAN_INITED;\n  GET_STACK_TRACE_MALLOC;\n  uptr PageSize = GetPageSizeCached();\n  size = RoundUpTo(size, PageSize);\n  if (size == 0) {\n    // pvalloc(0) should allocate one page.\n    size = PageSize;\n  }\n  return Allocate(stack, size, GetPageSizeCached(), kAlwaysClearMemory);\n}\n\nINTERCEPTOR(void, cfree, void *p) ALIAS(WRAPPER_NAME(free));\n\n#define OPERATOR_NEW_BODY                              \\\n  ENSURE_LSAN_INITED;                                  \\\n  GET_STACK_TRACE_MALLOC;                              \\\n  return Allocate(stack, size, 1, kAlwaysClearMemory);\n\nINTERCEPTOR_ATTRIBUTE\nvoid *operator new(uptr size) { OPERATOR_NEW_BODY; }\nINTERCEPTOR_ATTRIBUTE\nvoid *operator new[](uptr size) { OPERATOR_NEW_BODY; }\nINTERCEPTOR_ATTRIBUTE\nvoid *operator new(uptr size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }\nINTERCEPTOR_ATTRIBUTE\nvoid *operator new[](uptr size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }\n\n#define OPERATOR_DELETE_BODY \\\n  ENSURE_LSAN_INITED;        \\\n  Deallocate(ptr);\n\nINTERCEPTOR_ATTRIBUTE\nvoid operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }\nINTERCEPTOR_ATTRIBUTE\nvoid operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }\nINTERCEPTOR_ATTRIBUTE\nvoid operator delete(void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY; }\nINTERCEPTOR_ATTRIBUTE\nvoid operator delete[](void *ptr, std::nothrow_t const &) {\n  OPERATOR_DELETE_BODY;\n}\n\n// We need this to intercept the __libc_memalign calls that are used to\n// allocate dynamic TLS space in ld-linux.so.\nINTERCEPTOR(void *, __libc_memalign, uptr align, uptr s)\n    ALIAS(WRAPPER_NAME(memalign));\n\n///// Thread initialization and finalization. /////\n\nstatic unsigned g_thread_finalize_key;\n\nstatic void thread_finalize(void *v) {\n  uptr iter = (uptr)v;\n  if (iter > 1) {\n    if (pthread_setspecific(g_thread_finalize_key, (void*)(iter - 1))) {\n      Report(\"LeakSanitizer: failed to set thread key.\\n\");\n      Die();\n    }\n    return;\n  }\n  ThreadFinish();\n}\n\nstruct ThreadParam {\n  void *(*callback)(void *arg);\n  void *param;\n  atomic_uintptr_t tid;\n};\n\nextern \"C\" void *__lsan_thread_start_func(void *arg) {\n  ThreadParam *p = (ThreadParam*)arg;\n  void* (*callback)(void *arg) = p->callback;\n  void *param = p->param;\n  // Wait until the last iteration to maximize the chance that we are the last\n  // destructor to run.\n  if (pthread_setspecific(g_thread_finalize_key,\n                          (void*)GetPthreadDestructorIterations())) {\n    Report(\"LeakSanitizer: failed to set thread key.\\n\");\n    Die();\n  }\n  int tid = 0;\n  while ((tid = atomic_load(&p->tid, memory_order_acquire)) == 0)\n    internal_sched_yield();\n  SetCurrentThread(tid);\n  ThreadStart(tid, GetTid());\n  atomic_store(&p->tid, 0, memory_order_release);\n  return callback(param);\n}\n\nINTERCEPTOR(int, pthread_create, void *th, void *attr,\n            void *(*callback)(void *), void *param) {\n  ENSURE_LSAN_INITED;\n  EnsureMainThreadIDIsCorrect();\n  __sanitizer_pthread_attr_t myattr;\n  if (!attr) {\n    pthread_attr_init(&myattr);\n    attr = &myattr;\n  }\n  AdjustStackSize(attr);\n  int detached = 0;\n  pthread_attr_getdetachstate(attr, &detached);\n  ThreadParam p;\n  p.callback = callback;\n  p.param = param;\n  atomic_store(&p.tid, 0, memory_order_relaxed);\n  int res = REAL(pthread_create)(th, attr, __lsan_thread_start_func, &p);\n  if (res == 0) {\n    int tid = ThreadCreate(GetCurrentThread(), *(uptr *)th, detached);\n    CHECK_NE(tid, 0);\n    atomic_store(&p.tid, tid, memory_order_release);\n    while (atomic_load(&p.tid, memory_order_acquire) != 0)\n      internal_sched_yield();\n  }\n  if (attr == &myattr)\n    pthread_attr_destroy(&myattr);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_join, void *th, void **ret) {\n  ENSURE_LSAN_INITED;\n  int tid = ThreadTid((uptr)th);\n  int res = REAL(pthread_join)(th, ret);\n  if (res == 0)\n    ThreadJoin(tid);\n  return res;\n}\n\nnamespace __lsan {\n\nvoid InitializeInterceptors() {\n  INTERCEPT_FUNCTION(malloc);\n  INTERCEPT_FUNCTION(free);\n  INTERCEPT_FUNCTION(cfree);\n  INTERCEPT_FUNCTION(calloc);\n  INTERCEPT_FUNCTION(realloc);\n  INTERCEPT_FUNCTION(memalign);\n  INTERCEPT_FUNCTION(posix_memalign);\n  INTERCEPT_FUNCTION(__libc_memalign);\n  INTERCEPT_FUNCTION(valloc);\n  INTERCEPT_FUNCTION(pvalloc);\n  INTERCEPT_FUNCTION(malloc_usable_size);\n  INTERCEPT_FUNCTION(mallinfo);\n  INTERCEPT_FUNCTION(mallopt);\n  INTERCEPT_FUNCTION(pthread_create);\n  INTERCEPT_FUNCTION(pthread_join);\n\n  if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) {\n    Report(\"LeakSanitizer: failed to create thread key.\\n\");\n    Die();\n  }\n}\n\n} // namespace __lsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/lsan_preinit.cc",
    "content": "//===-- lsan_preinit.cc ---------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of LeakSanitizer.\n//\n// Call __lsan_init at the very early stage of process startup.\n//===----------------------------------------------------------------------===//\n\n#include \"lsan.h\"\n\n#if SANITIZER_CAN_USE_PREINIT_ARRAY\n  // We force __lsan_init to be called before anyone else by placing it into\n  // .preinit_array section.\n  __attribute__((section(\".preinit_array\"), used))\n  void (*__local_lsan_preinit)(void) = __lsan_init;\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/lsan_thread.cc",
    "content": "//=-- lsan_thread.cc ------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of LeakSanitizer.\n// See lsan_thread.h for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"lsan_thread.h\"\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_thread_registry.h\"\n#include \"lsan_allocator.h\"\n\nnamespace __lsan {\n\nconst u32 kInvalidTid = (u32) -1;\n\nstatic ThreadRegistry *thread_registry;\nstatic THREADLOCAL u32 current_thread_tid = kInvalidTid;\n\nstatic ThreadContextBase *CreateThreadContext(u32 tid) {\n  void *mem = MmapOrDie(sizeof(ThreadContext), \"ThreadContext\");\n  return new(mem) ThreadContext(tid);\n}\n\nstatic const uptr kMaxThreads = 1 << 13;\nstatic const uptr kThreadQuarantineSize = 64;\n\nvoid InitializeThreadRegistry() {\n  static char thread_registry_placeholder[sizeof(ThreadRegistry)] ALIGNED(64);\n  thread_registry = new(thread_registry_placeholder)\n    ThreadRegistry(CreateThreadContext, kMaxThreads, kThreadQuarantineSize);\n}\n\nu32 GetCurrentThread() {\n  return current_thread_tid;\n}\n\nvoid SetCurrentThread(u32 tid) {\n  current_thread_tid = tid;\n}\n\nThreadContext::ThreadContext(int tid)\n  : ThreadContextBase(tid),\n    stack_begin_(0),\n    stack_end_(0),\n    cache_begin_(0),\n    cache_end_(0),\n    tls_begin_(0),\n    tls_end_(0) {}\n\nstruct OnStartedArgs {\n  uptr stack_begin, stack_end,\n       cache_begin, cache_end,\n       tls_begin, tls_end;\n};\n\nvoid ThreadContext::OnStarted(void *arg) {\n  OnStartedArgs *args = reinterpret_cast<OnStartedArgs *>(arg);\n  stack_begin_ = args->stack_begin;\n  stack_end_ = args->stack_end;\n  tls_begin_ = args->tls_begin;\n  tls_end_ = args->tls_end;\n  cache_begin_ = args->cache_begin;\n  cache_end_ = args->cache_end;\n}\n\nvoid ThreadContext::OnFinished() {\n  AllocatorThreadFinish();\n}\n\nu32 ThreadCreate(u32 parent_tid, uptr user_id, bool detached) {\n  return thread_registry->CreateThread(user_id, detached, parent_tid,\n                                       /* arg */ nullptr);\n}\n\nvoid ThreadStart(u32 tid, uptr os_id) {\n  OnStartedArgs args;\n  uptr stack_size = 0;\n  uptr tls_size = 0;\n  GetThreadStackAndTls(tid == 0, &args.stack_begin, &stack_size,\n                       &args.tls_begin, &tls_size);\n  args.stack_end = args.stack_begin + stack_size;\n  args.tls_end = args.tls_begin + tls_size;\n  GetAllocatorCacheRange(&args.cache_begin, &args.cache_end);\n  thread_registry->StartThread(tid, os_id, &args);\n}\n\nvoid ThreadFinish() {\n  thread_registry->FinishThread(GetCurrentThread());\n}\n\nThreadContext *CurrentThreadContext() {\n  if (!thread_registry) return nullptr;\n  if (GetCurrentThread() == kInvalidTid)\n    return nullptr;\n  // No lock needed when getting current thread.\n  return (ThreadContext *)thread_registry->GetThreadLocked(GetCurrentThread());\n}\n\nstatic bool FindThreadByUid(ThreadContextBase *tctx, void *arg) {\n  uptr uid = (uptr)arg;\n  if (tctx->user_id == uid && tctx->status != ThreadStatusInvalid) {\n    return true;\n  }\n  return false;\n}\n\nu32 ThreadTid(uptr uid) {\n  return thread_registry->FindThread(FindThreadByUid, (void*)uid);\n}\n\nvoid ThreadJoin(u32 tid) {\n  CHECK_NE(tid, kInvalidTid);\n  thread_registry->JoinThread(tid, /* arg */nullptr);\n}\n\nvoid EnsureMainThreadIDIsCorrect() {\n  if (GetCurrentThread() == 0)\n    CurrentThreadContext()->os_id = GetTid();\n}\n\n///// Interface to the common LSan module. /////\n\nbool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end,\n                           uptr *tls_begin, uptr *tls_end,\n                           uptr *cache_begin, uptr *cache_end) {\n  ThreadContext *context = static_cast<ThreadContext *>(\n      thread_registry->FindThreadContextByOsIDLocked(os_id));\n  if (!context) return false;\n  *stack_begin = context->stack_begin();\n  *stack_end = context->stack_end();\n  *tls_begin = context->tls_begin();\n  *tls_end = context->tls_end();\n  *cache_begin = context->cache_begin();\n  *cache_end = context->cache_end();\n  return true;\n}\n\nvoid ForEachExtraStackRange(uptr os_id, RangeIteratorCallback callback,\n                            void *arg) {\n}\n\nvoid LockThreadRegistry() {\n  thread_registry->Lock();\n}\n\nvoid UnlockThreadRegistry() {\n  thread_registry->Unlock();\n}\n\n} // namespace __lsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/lsan/lsan_thread.h",
    "content": "//=-- lsan_thread.h -------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of LeakSanitizer.\n// Thread registry for standalone LSan.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef LSAN_THREAD_H\n#define LSAN_THREAD_H\n\n#include \"sanitizer_common/sanitizer_thread_registry.h\"\n\nnamespace __lsan {\n\nclass ThreadContext : public ThreadContextBase {\n public:\n  explicit ThreadContext(int tid);\n  void OnStarted(void *arg) override;\n  void OnFinished() override;\n  uptr stack_begin() { return stack_begin_; }\n  uptr stack_end() { return stack_end_; }\n  uptr tls_begin() { return tls_begin_; }\n  uptr tls_end() { return tls_end_; }\n  uptr cache_begin() { return cache_begin_; }\n  uptr cache_end() { return cache_end_; }\n private:\n  uptr stack_begin_, stack_end_,\n       cache_begin_, cache_end_,\n       tls_begin_, tls_end_;\n};\n\nvoid InitializeThreadRegistry();\n\nvoid ThreadStart(u32 tid, uptr os_id);\nvoid ThreadFinish();\nu32 ThreadCreate(u32 tid, uptr uid, bool detached);\nvoid ThreadJoin(u32 tid);\nu32 ThreadTid(uptr uid);\n\nu32 GetCurrentThread();\nvoid SetCurrentThread(u32 tid);\nThreadContext *CurrentThreadContext();\nvoid EnsureMainThreadIDIsCorrect();\n}  // namespace __lsan\n\n#endif  // LSAN_THREAD_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/.clang-format",
    "content": "BasedOnStyle: Google\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/CMakeLists.txt",
    "content": "include_directories(..)\n\n# Runtime library sources and build flags.\nset(MSAN_RTL_SOURCES\n  msan.cc\n  msan_allocator.cc\n  msan_chained_origin_depot.cc\n  msan_interceptors.cc\n  msan_linux.cc\n  msan_report.cc\n  msan_thread.cc\n  msan_poisoning.cc\n  )\n\nset(MSAN_RTL_CXX_SOURCES\n  msan_new_delete.cc)\n\n\nset(MSAN_RTL_CFLAGS ${SANITIZER_COMMON_CFLAGS})\nappend_no_rtti_flag(MSAN_RTL_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE MSAN_RTL_CFLAGS)\n# Prevent clang from generating libc calls.\nappend_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding MSAN_RTL_CFLAGS)\n\nset(MSAN_RUNTIME_LIBRARIES)\n\n# Static runtime library.\nadd_custom_target(msan)\nforeach(arch ${MSAN_SUPPORTED_ARCH})\n  add_compiler_rt_runtime(clang_rt.msan\n    STATIC\n    ARCHS ${arch}\n    SOURCES ${MSAN_RTL_SOURCES}\n            $<TARGET_OBJECTS:RTInterception.${arch}>\n            $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>\n            $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>\n            $<TARGET_OBJECTS:RTUbsan.${arch}>\n    CFLAGS ${MSAN_RTL_CFLAGS}\n    PARENT_TARGET msan)\n  add_compiler_rt_runtime(clang_rt.msan_cxx\n    STATIC\n    ARCHS ${arch}\n    SOURCES ${MSAN_RTL_CXX_SOURCES}\n            $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>\n    CFLAGS ${MSAN_RTL_CFLAGS}\n    PARENT_TARGET msan)\n  list(APPEND MSAN_RUNTIME_LIBRARIES clang_rt.msan-${arch}\n                                     clang_rt.msan_cxx-${arch})\n  if(UNIX)\n    add_sanitizer_rt_symbols(clang_rt.msan\n      ARCHS ${arch}\n      EXTRA msan.syms.extra)\n    add_sanitizer_rt_symbols(clang_rt.msan_cxx\n      ARCHS ${arch}\n      EXTRA msan.syms.extra)\n    add_dependencies(msan clang_rt.msan-${arch}-symbols\n                          clang_rt.msan_cxx-${arch}-symbols)\n  endif()\nendforeach()\n\nadd_compiler_rt_resource_file(msan_blacklist msan_blacklist.txt)\nadd_dependencies(msan msan_blacklist)\nadd_dependencies(compiler-rt msan)\n\nif(COMPILER_RT_INCLUDE_TESTS)\n  add_subdirectory(tests)\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan.cc",
    "content": "//===-- msan.cc -----------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n// MemorySanitizer runtime.\n//===----------------------------------------------------------------------===//\n\n#include \"msan.h\"\n#include \"msan_chained_origin_depot.h\"\n#include \"msan_origin.h\"\n#include \"msan_thread.h\"\n#include \"msan_poisoning.h\"\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_flag_parser.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_procmaps.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"sanitizer_common/sanitizer_symbolizer.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n#include \"ubsan/ubsan_flags.h\"\n#include \"ubsan/ubsan_init.h\"\n\n// ACHTUNG! No system header includes in this file.\n\nusing namespace __sanitizer;\n\n// Globals.\nstatic THREADLOCAL int msan_expect_umr = 0;\nstatic THREADLOCAL int msan_expected_umr_found = 0;\n\n// Function argument shadow. Each argument starts at the next available 8-byte\n// aligned address.\nSANITIZER_INTERFACE_ATTRIBUTE\nTHREADLOCAL u64 __msan_param_tls[kMsanParamTlsSize / sizeof(u64)];\n\n// Function argument origin. Each argument starts at the same offset as the\n// corresponding shadow in (__msan_param_tls). Slightly weird, but changing this\n// would break compatibility with older prebuilt binaries.\nSANITIZER_INTERFACE_ATTRIBUTE\nTHREADLOCAL u32 __msan_param_origin_tls[kMsanParamTlsSize / sizeof(u32)];\n\nSANITIZER_INTERFACE_ATTRIBUTE\nTHREADLOCAL u64 __msan_retval_tls[kMsanRetvalTlsSize / sizeof(u64)];\n\nSANITIZER_INTERFACE_ATTRIBUTE\nTHREADLOCAL u32 __msan_retval_origin_tls;\n\nSANITIZER_INTERFACE_ATTRIBUTE\nALIGNED(16) THREADLOCAL u64 __msan_va_arg_tls[kMsanParamTlsSize / sizeof(u64)];\n\nSANITIZER_INTERFACE_ATTRIBUTE\nTHREADLOCAL u64 __msan_va_arg_overflow_size_tls;\n\nSANITIZER_INTERFACE_ATTRIBUTE\nTHREADLOCAL u32 __msan_origin_tls;\n\nstatic THREADLOCAL int is_in_symbolizer;\n\nextern \"C\" SANITIZER_WEAK_ATTRIBUTE const int __msan_track_origins;\n\nint __msan_get_track_origins() {\n  return &__msan_track_origins ? __msan_track_origins : 0;\n}\n\nextern \"C\" SANITIZER_WEAK_ATTRIBUTE const int __msan_keep_going;\n\nnamespace __msan {\n\nvoid EnterSymbolizer() { ++is_in_symbolizer; }\nvoid ExitSymbolizer()  { --is_in_symbolizer; }\nbool IsInSymbolizer() { return is_in_symbolizer; }\n\nstatic Flags msan_flags;\n\nFlags *flags() {\n  return &msan_flags;\n}\n\nint msan_inited = 0;\nbool msan_init_is_running;\n\nint msan_report_count = 0;\n\n// Array of stack origins.\n// FIXME: make it resizable.\nstatic const uptr kNumStackOriginDescrs = 1024 * 1024;\nstatic const char *StackOriginDescr[kNumStackOriginDescrs];\nstatic uptr StackOriginPC[kNumStackOriginDescrs];\nstatic atomic_uint32_t NumStackOriginDescrs;\n\nvoid Flags::SetDefaults() {\n#define MSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;\n#include \"msan_flags.inc\"\n#undef MSAN_FLAG\n}\n\n// keep_going is an old name for halt_on_error,\n// and it has inverse meaning.\nclass FlagHandlerKeepGoing : public FlagHandlerBase {\n  bool *halt_on_error_;\n\n public:\n  explicit FlagHandlerKeepGoing(bool *halt_on_error)\n      : halt_on_error_(halt_on_error) {}\n  bool Parse(const char *value) final {\n    bool tmp;\n    FlagHandler<bool> h(&tmp);\n    if (!h.Parse(value)) return false;\n    *halt_on_error_ = !tmp;\n    return true;\n  }\n};\n\nstatic void RegisterMsanFlags(FlagParser *parser, Flags *f) {\n#define MSAN_FLAG(Type, Name, DefaultValue, Description) \\\n  RegisterFlag(parser, #Name, Description, &f->Name);\n#include \"msan_flags.inc\"\n#undef MSAN_FLAG\n\n  FlagHandlerKeepGoing *fh_keep_going = new (FlagParser::Alloc)  // NOLINT\n      FlagHandlerKeepGoing(&f->halt_on_error);\n  parser->RegisterHandler(\"keep_going\", fh_keep_going,\n                          \"deprecated, use halt_on_error\");\n}\n\nstatic void InitializeFlags() {\n  SetCommonFlagsDefaults();\n  {\n    CommonFlags cf;\n    cf.CopyFrom(*common_flags());\n    cf.external_symbolizer_path = GetEnv(\"MSAN_SYMBOLIZER_PATH\");\n    cf.malloc_context_size = 20;\n    cf.handle_ioctl = true;\n    // FIXME: test and enable.\n    cf.check_printf = false;\n    cf.intercept_tls_get_addr = true;\n    cf.exitcode = 77;\n    OverrideCommonFlags(cf);\n  }\n\n  Flags *f = flags();\n  f->SetDefaults();\n\n  FlagParser parser;\n  RegisterMsanFlags(&parser, f);\n  RegisterCommonFlags(&parser);\n\n#if MSAN_CONTAINS_UBSAN\n  __ubsan::Flags *uf = __ubsan::flags();\n  uf->SetDefaults();\n\n  FlagParser ubsan_parser;\n  __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);\n  RegisterCommonFlags(&ubsan_parser);\n#endif\n\n  // Override from user-specified string.\n  if (__msan_default_options)\n    parser.ParseString(__msan_default_options());\n#if MSAN_CONTAINS_UBSAN\n  const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();\n  ubsan_parser.ParseString(ubsan_default_options);\n#endif\n\n  const char *msan_options = GetEnv(\"MSAN_OPTIONS\");\n  parser.ParseString(msan_options);\n#if MSAN_CONTAINS_UBSAN\n  ubsan_parser.ParseString(GetEnv(\"UBSAN_OPTIONS\"));\n#endif\n  VPrintf(1, \"MSAN_OPTIONS: %s\\n\", msan_options ? msan_options : \"<empty>\");\n\n  SetVerbosity(common_flags()->verbosity);\n\n  if (Verbosity()) ReportUnrecognizedFlags();\n\n  if (common_flags()->help) parser.PrintFlagDescriptions();\n\n  // Check if deprecated exit_code MSan flag is set.\n  if (f->exit_code != -1) {\n    if (Verbosity())\n      Printf(\"MSAN_OPTIONS=exit_code is deprecated! \"\n             \"Please use MSAN_OPTIONS=exitcode instead.\\n\");\n    CommonFlags cf;\n    cf.CopyFrom(*common_flags());\n    cf.exitcode = f->exit_code;\n    OverrideCommonFlags(cf);\n  }\n\n  // Check flag values:\n  if (f->origin_history_size < 0 ||\n      f->origin_history_size > Origin::kMaxDepth) {\n    Printf(\n        \"Origin history size invalid: %d. Must be 0 (unlimited) or in [1, %d] \"\n        \"range.\\n\",\n        f->origin_history_size, Origin::kMaxDepth);\n    Die();\n  }\n  // Limiting to kStackDepotMaxUseCount / 2 to avoid overflow in\n  // StackDepotHandle::inc_use_count_unsafe.\n  if (f->origin_history_per_stack_limit < 0 ||\n      f->origin_history_per_stack_limit > kStackDepotMaxUseCount / 2) {\n    Printf(\n        \"Origin per-stack limit invalid: %d. Must be 0 (unlimited) or in [1, \"\n        \"%d] range.\\n\",\n        f->origin_history_per_stack_limit, kStackDepotMaxUseCount / 2);\n    Die();\n  }\n  if (f->store_context_size < 1) f->store_context_size = 1;\n}\n\nvoid GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,\n                   bool request_fast_unwind) {\n  MsanThread *t = GetCurrentThread();\n  if (!t || !StackTrace::WillUseFastUnwind(request_fast_unwind)) {\n    // Block reports from our interceptors during _Unwind_Backtrace.\n    SymbolizerScope sym_scope;\n    return stack->Unwind(max_s, pc, bp, nullptr, 0, 0, request_fast_unwind);\n  }\n  stack->Unwind(max_s, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),\n                request_fast_unwind);\n}\n\nvoid PrintWarning(uptr pc, uptr bp) {\n  PrintWarningWithOrigin(pc, bp, __msan_origin_tls);\n}\n\nvoid PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin) {\n  if (msan_expect_umr) {\n    // Printf(\"Expected UMR\\n\");\n    __msan_origin_tls = origin;\n    msan_expected_umr_found = 1;\n    return;\n  }\n\n  ++msan_report_count;\n\n  GET_FATAL_STACK_TRACE_PC_BP(pc, bp);\n\n  u32 report_origin =\n    (__msan_get_track_origins() && Origin::isValidId(origin)) ? origin : 0;\n  ReportUMR(&stack, report_origin);\n\n  if (__msan_get_track_origins() && !Origin::isValidId(origin)) {\n    Printf(\n        \"  ORIGIN: invalid (%x). Might be a bug in MemorySanitizer origin \"\n        \"tracking.\\n    This could still be a bug in your code, too!\\n\",\n        origin);\n  }\n}\n\nvoid UnpoisonParam(uptr n) {\n  internal_memset(__msan_param_tls, 0, n * sizeof(*__msan_param_tls));\n}\n\n// Backup MSan runtime TLS state.\n// Implementation must be async-signal-safe.\n// Instances of this class may live on the signal handler stack, and data size\n// may be an issue.\nvoid ScopedThreadLocalStateBackup::Backup() {\n  va_arg_overflow_size_tls = __msan_va_arg_overflow_size_tls;\n}\n\nvoid ScopedThreadLocalStateBackup::Restore() {\n  // A lame implementation that only keeps essential state and resets the rest.\n  __msan_va_arg_overflow_size_tls = va_arg_overflow_size_tls;\n\n  internal_memset(__msan_param_tls, 0, sizeof(__msan_param_tls));\n  internal_memset(__msan_retval_tls, 0, sizeof(__msan_retval_tls));\n  internal_memset(__msan_va_arg_tls, 0, sizeof(__msan_va_arg_tls));\n\n  if (__msan_get_track_origins()) {\n    internal_memset(&__msan_retval_origin_tls, 0,\n                    sizeof(__msan_retval_origin_tls));\n    internal_memset(__msan_param_origin_tls, 0,\n                    sizeof(__msan_param_origin_tls));\n  }\n}\n\nvoid UnpoisonThreadLocalState() {\n}\n\nconst char *GetStackOriginDescr(u32 id, uptr *pc) {\n  CHECK_LT(id, kNumStackOriginDescrs);\n  if (pc) *pc = StackOriginPC[id];\n  return StackOriginDescr[id];\n}\n\nu32 ChainOrigin(u32 id, StackTrace *stack) {\n  MsanThread *t = GetCurrentThread();\n  if (t && t->InSignalHandler())\n    return id;\n\n  Origin o = Origin::FromRawId(id);\n  stack->tag = StackTrace::TAG_UNKNOWN;\n  Origin chained = Origin::CreateChainedOrigin(o, stack);\n  return chained.raw_id();\n}\n\n} // namespace __msan\n\n// Interface.\n\nusing namespace __msan;\n\n#define MSAN_MAYBE_WARNING(type, size)              \\\n  void __msan_maybe_warning_##size(type s, u32 o) { \\\n    GET_CALLER_PC_BP_SP;                            \\\n    (void) sp;                                      \\\n    if (UNLIKELY(s)) {                              \\\n      PrintWarningWithOrigin(pc, bp, o);            \\\n      if (__msan::flags()->halt_on_error) {         \\\n        Printf(\"Exiting\\n\");                        \\\n        Die();                                      \\\n      }                                             \\\n    }                                               \\\n  }\n\nMSAN_MAYBE_WARNING(u8, 1)\nMSAN_MAYBE_WARNING(u16, 2)\nMSAN_MAYBE_WARNING(u32, 4)\nMSAN_MAYBE_WARNING(u64, 8)\n\n#define MSAN_MAYBE_STORE_ORIGIN(type, size)                       \\\n  void __msan_maybe_store_origin_##size(type s, void *p, u32 o) { \\\n    if (UNLIKELY(s)) {                                            \\\n      if (__msan_get_track_origins() > 1) {                       \\\n        GET_CALLER_PC_BP_SP;                                      \\\n        (void) sp;                                                \\\n        GET_STORE_STACK_TRACE_PC_BP(pc, bp);                      \\\n        o = ChainOrigin(o, &stack);                               \\\n      }                                                           \\\n      *(u32 *)MEM_TO_ORIGIN((uptr)p & ~3UL) = o;                  \\\n    }                                                             \\\n  }\n\nMSAN_MAYBE_STORE_ORIGIN(u8, 1)\nMSAN_MAYBE_STORE_ORIGIN(u16, 2)\nMSAN_MAYBE_STORE_ORIGIN(u32, 4)\nMSAN_MAYBE_STORE_ORIGIN(u64, 8)\n\nvoid __msan_warning() {\n  GET_CALLER_PC_BP_SP;\n  (void)sp;\n  PrintWarning(pc, bp);\n  if (__msan::flags()->halt_on_error) {\n    if (__msan::flags()->print_stats)\n      ReportStats();\n    Printf(\"Exiting\\n\");\n    Die();\n  }\n}\n\nvoid __msan_warning_noreturn() {\n  GET_CALLER_PC_BP_SP;\n  (void)sp;\n  PrintWarning(pc, bp);\n  if (__msan::flags()->print_stats)\n    ReportStats();\n  Printf(\"Exiting\\n\");\n  Die();\n}\n\nvoid __msan_init() {\n  CHECK(!msan_init_is_running);\n  if (msan_inited) return;\n  msan_init_is_running = 1;\n  SanitizerToolName = \"MemorySanitizer\";\n\n  InitTlsSize();\n\n  CacheBinaryName();\n  InitializeFlags();\n\n  __sanitizer_set_report_path(common_flags()->log_path);\n\n  InitializeInterceptors();\n  InstallAtExitHandler(); // Needs __cxa_atexit interceptor.\n\n  DisableCoreDumperIfNecessary();\n  if (StackSizeIsUnlimited()) {\n    VPrintf(1, \"Unlimited stack, doing reexec\\n\");\n    // A reasonably large stack size. It is bigger than the usual 8Mb, because,\n    // well, the program could have been run with unlimited stack for a reason.\n    SetStackSizeLimitInBytes(32 * 1024 * 1024);\n    ReExec();\n  }\n\n  __msan_clear_on_return();\n  if (__msan_get_track_origins())\n    VPrintf(1, \"msan_track_origins\\n\");\n  if (!InitShadow(__msan_get_track_origins())) {\n    Printf(\"FATAL: MemorySanitizer can not mmap the shadow memory.\\n\");\n    Printf(\"FATAL: Make sure to compile with -fPIE and to link with -pie.\\n\");\n    Printf(\"FATAL: Disabling ASLR is known to cause this error.\\n\");\n    Printf(\"FATAL: If running under GDB, try \"\n           \"'set disable-randomization off'.\\n\");\n    DumpProcessMap();\n    Die();\n  }\n\n  Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer);\n\n  InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);\n\n  MsanTSDInit(MsanTSDDtor);\n\n  MsanAllocatorInit();\n\n  MsanThread *main_thread = MsanThread::Create(nullptr, nullptr);\n  SetCurrentThread(main_thread);\n  main_thread->ThreadStart();\n\n#if MSAN_CONTAINS_UBSAN\n  __ubsan::InitAsPlugin();\n#endif\n\n  VPrintf(1, \"MemorySanitizer init done\\n\");\n\n  msan_init_is_running = 0;\n  msan_inited = 1;\n}\n\nvoid __msan_set_keep_going(int keep_going) {\n  flags()->halt_on_error = !keep_going;\n}\n\nvoid __msan_set_expect_umr(int expect_umr) {\n  if (expect_umr) {\n    msan_expected_umr_found = 0;\n  } else if (!msan_expected_umr_found) {\n    GET_CALLER_PC_BP_SP;\n    (void)sp;\n    GET_FATAL_STACK_TRACE_PC_BP(pc, bp);\n    ReportExpectedUMRNotFound(&stack);\n    Die();\n  }\n  msan_expect_umr = expect_umr;\n}\n\nvoid __msan_print_shadow(const void *x, uptr size) {\n  if (!MEM_IS_APP(x)) {\n    Printf(\"Not a valid application address: %p\\n\", x);\n    return;\n  }\n\n  DescribeMemoryRange(x, size);\n}\n\nvoid __msan_dump_shadow(const void *x, uptr size) {\n  if (!MEM_IS_APP(x)) {\n    Printf(\"Not a valid application address: %p\\n\", x);\n    return;\n  }\n\n  unsigned char *s = (unsigned char*)MEM_TO_SHADOW(x);\n  for (uptr i = 0; i < size; i++) {\n#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n    Printf(\"%x%x \", s[i] & 0xf, s[i] >> 4);\n#else\n    Printf(\"%x%x \", s[i] >> 4, s[i] & 0xf);\n#endif\n  }\n  Printf(\"\\n\");\n}\n\nsptr __msan_test_shadow(const void *x, uptr size) {\n  if (!MEM_IS_APP(x)) return -1;\n  unsigned char *s = (unsigned char *)MEM_TO_SHADOW((uptr)x);\n  for (uptr i = 0; i < size; ++i)\n    if (s[i])\n      return i;\n  return -1;\n}\n\nvoid __msan_check_mem_is_initialized(const void *x, uptr size) {\n  if (!__msan::flags()->report_umrs) return;\n  sptr offset = __msan_test_shadow(x, size);\n  if (offset < 0)\n    return;\n\n  GET_CALLER_PC_BP_SP;\n  (void)sp;\n  ReportUMRInsideAddressRange(__func__, x, size, offset);\n  __msan::PrintWarningWithOrigin(pc, bp,\n                                 __msan_get_origin(((const char *)x) + offset));\n  if (__msan::flags()->halt_on_error) {\n    Printf(\"Exiting\\n\");\n    Die();\n  }\n}\n\nint __msan_set_poison_in_malloc(int do_poison) {\n  int old = flags()->poison_in_malloc;\n  flags()->poison_in_malloc = do_poison;\n  return old;\n}\n\nint __msan_has_dynamic_component() { return false; }\n\nNOINLINE\nvoid __msan_clear_on_return() {\n  __msan_param_tls[0] = 0;\n}\n\nvoid __msan_partial_poison(const void* data, void* shadow, uptr size) {\n  internal_memcpy((void*)MEM_TO_SHADOW((uptr)data), shadow, size);\n}\n\nvoid __msan_load_unpoisoned(const void *src, uptr size, void *dst) {\n  internal_memcpy(dst, src, size);\n  __msan_unpoison(dst, size);\n}\n\nvoid __msan_set_origin(const void *a, uptr size, u32 origin) {\n  if (__msan_get_track_origins()) SetOrigin(a, size, origin);\n}\n\n// 'descr' is created at compile time and contains '----' in the beginning.\n// When we see descr for the first time we replace '----' with a uniq id\n// and set the origin to (id | (31-th bit)).\nvoid __msan_set_alloca_origin(void *a, uptr size, char *descr) {\n  __msan_set_alloca_origin4(a, size, descr, 0);\n}\n\nvoid __msan_set_alloca_origin4(void *a, uptr size, char *descr, uptr pc) {\n  static const u32 dash = '-';\n  static const u32 first_timer =\n      dash + (dash << 8) + (dash << 16) + (dash << 24);\n  u32 *id_ptr = (u32*)descr;\n  bool print = false;  // internal_strstr(descr + 4, \"AllocaTOTest\") != 0;\n  u32 id = *id_ptr;\n  if (id == first_timer) {\n    u32 idx = atomic_fetch_add(&NumStackOriginDescrs, 1, memory_order_relaxed);\n    CHECK_LT(idx, kNumStackOriginDescrs);\n    StackOriginDescr[idx] = descr + 4;\n    StackOriginPC[idx] = pc;\n    id = Origin::CreateStackOrigin(idx).raw_id();\n    *id_ptr = id;\n    if (print)\n      Printf(\"First time: idx=%d id=%d %s %p \\n\", idx, id, descr + 4, pc);\n  }\n  if (print)\n    Printf(\"__msan_set_alloca_origin: descr=%s id=%x\\n\", descr + 4, id);\n  __msan_set_origin(a, size, id);\n}\n\nu32 __msan_chain_origin(u32 id) {\n  GET_CALLER_PC_BP_SP;\n  (void)sp;\n  GET_STORE_STACK_TRACE_PC_BP(pc, bp);\n  return ChainOrigin(id, &stack);\n}\n\nu32 __msan_get_origin(const void *a) {\n  if (!__msan_get_track_origins()) return 0;\n  uptr x = (uptr)a;\n  uptr aligned = x & ~3ULL;\n  uptr origin_ptr = MEM_TO_ORIGIN(aligned);\n  return *(u32*)origin_ptr;\n}\n\nint __msan_origin_is_descendant_or_same(u32 this_id, u32 prev_id) {\n  Origin o = Origin::FromRawId(this_id);\n  while (o.raw_id() != prev_id && o.isChainedOrigin())\n    o = o.getNextChainedOrigin(nullptr);\n  return o.raw_id() == prev_id;\n}\n\nu32 __msan_get_umr_origin() {\n  return __msan_origin_tls;\n}\n\nu16 __sanitizer_unaligned_load16(const uu16 *p) {\n  __msan_retval_tls[0] = *(uu16 *)MEM_TO_SHADOW((uptr)p);\n  if (__msan_get_track_origins())\n    __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p));\n  return *p;\n}\nu32 __sanitizer_unaligned_load32(const uu32 *p) {\n  __msan_retval_tls[0] = *(uu32 *)MEM_TO_SHADOW((uptr)p);\n  if (__msan_get_track_origins())\n    __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p));\n  return *p;\n}\nu64 __sanitizer_unaligned_load64(const uu64 *p) {\n  __msan_retval_tls[0] = *(uu64 *)MEM_TO_SHADOW((uptr)p);\n  if (__msan_get_track_origins())\n    __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p));\n  return *p;\n}\nvoid __sanitizer_unaligned_store16(uu16 *p, u16 x) {\n  u16 s = __msan_param_tls[1];\n  *(uu16 *)MEM_TO_SHADOW((uptr)p) = s;\n  if (s && __msan_get_track_origins())\n    if (uu32 o = __msan_param_origin_tls[2])\n      SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o);\n  *p = x;\n}\nvoid __sanitizer_unaligned_store32(uu32 *p, u32 x) {\n  u32 s = __msan_param_tls[1];\n  *(uu32 *)MEM_TO_SHADOW((uptr)p) = s;\n  if (s && __msan_get_track_origins())\n    if (uu32 o = __msan_param_origin_tls[2])\n      SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o);\n  *p = x;\n}\nvoid __sanitizer_unaligned_store64(uu64 *p, u64 x) {\n  u64 s = __msan_param_tls[1];\n  *(uu64 *)MEM_TO_SHADOW((uptr)p) = s;\n  if (s && __msan_get_track_origins())\n    if (uu32 o = __msan_param_origin_tls[2])\n      SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o);\n  *p = x;\n}\n\nvoid __msan_set_death_callback(void (*callback)(void)) {\n  SetUserDieCallback(callback);\n}\n\n#if !SANITIZER_SUPPORTS_WEAK_HOOKS\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nconst char* __msan_default_options() { return \"\"; }\n}  // extern \"C\"\n#endif\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_print_stack_trace() {\n  GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME());\n  stack.Print();\n}\n} // extern \"C\"\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan.h",
    "content": "//===-- msan.h --------------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n// Private MSan header.\n//===----------------------------------------------------------------------===//\n\n#ifndef MSAN_H\n#define MSAN_H\n\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"msan_interface_internal.h\"\n#include \"msan_flags.h\"\n#include \"ubsan/ubsan_platform.h\"\n\n#ifndef MSAN_REPLACE_OPERATORS_NEW_AND_DELETE\n# define MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 1\n#endif\n\n#ifndef MSAN_CONTAINS_UBSAN\n# define MSAN_CONTAINS_UBSAN CAN_SANITIZE_UB\n#endif\n\nstruct MappingDesc {\n  uptr start;\n  uptr end;\n  enum Type {\n    INVALID, APP, SHADOW, ORIGIN\n  } type;\n  const char *name;\n};\n\n\n#if SANITIZER_LINUX && defined(__mips64)\n\n// Everything is above 0x00e000000000.\nconst MappingDesc kMemoryLayout[] = {\n    {0x000000000000ULL, 0x00a000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x00a000000000ULL, 0x00c000000000ULL, MappingDesc::SHADOW, \"shadow\"},\n    {0x00c000000000ULL, 0x00e000000000ULL, MappingDesc::ORIGIN, \"origin\"},\n    {0x00e000000000ULL, 0x010000000000ULL, MappingDesc::APP, \"app\"}};\n\n#define MEM_TO_SHADOW(mem) (((uptr)(mem)) & ~0x4000000000ULL)\n#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x002000000000)\n\n#elif SANITIZER_LINUX && defined(__aarch64__)\n\n// The mapping describes both 39-bits and 42-bits.  AArch64 maps:\n// - 0x00000000000-0x00010000000: 39/42-bits program own segments\n// - 0x05500000000-0x05600000000: 39-bits PIE program segments\n// - 0x07f80000000-0x07fffffffff: 39-bits libraries segments\n// - 0x2aa00000000-0x2ab00000000: 42-bits PIE program segments\n// - 0x3ff00000000-0x3ffffffffff: 42-bits libraries segments\n// It is fragmented in multiples segments to increase the memory available\n// on 42-bits (12.21% of total VMA available for 42-bits and 13.28 for\n// 39 bits).\nconst MappingDesc kMemoryLayout[] = {\n    {0x00000000000ULL, 0x01000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x01000000000ULL, 0x02000000000ULL, MappingDesc::SHADOW, \"shadow-2\"},\n    {0x02000000000ULL, 0x03000000000ULL, MappingDesc::ORIGIN, \"origin-2\"},\n    {0x03000000000ULL, 0x04000000000ULL, MappingDesc::SHADOW, \"shadow-1\"},\n    {0x04000000000ULL, 0x05000000000ULL, MappingDesc::ORIGIN, \"origin-1\"},\n    {0x05000000000ULL, 0x06000000000ULL, MappingDesc::APP, \"app-1\"},\n    {0x06000000000ULL, 0x07000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x07000000000ULL, 0x08000000000ULL, MappingDesc::APP, \"app-2\"},\n    {0x08000000000ULL, 0x09000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    // The mappings below are used only for 42-bits VMA.\n    {0x09000000000ULL, 0x0A000000000ULL, MappingDesc::SHADOW, \"shadow-3\"},\n    {0x0A000000000ULL, 0x0B000000000ULL, MappingDesc::ORIGIN, \"origin-3\"},\n    {0x0B000000000ULL, 0x0F000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x0F000000000ULL, 0x10000000000ULL, MappingDesc::APP, \"app-3\"},\n    {0x10000000000ULL, 0x11000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x11000000000ULL, 0x12000000000ULL, MappingDesc::APP, \"app-4\"},\n    {0x12000000000ULL, 0x17000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x17000000000ULL, 0x18000000000ULL, MappingDesc::SHADOW, \"shadow-4\"},\n    {0x18000000000ULL, 0x19000000000ULL, MappingDesc::ORIGIN, \"origin-4\"},\n    {0x19000000000ULL, 0x20000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x20000000000ULL, 0x21000000000ULL, MappingDesc::APP, \"app-5\"},\n    {0x21000000000ULL, 0x26000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x26000000000ULL, 0x27000000000ULL, MappingDesc::SHADOW, \"shadow-5\"},\n    {0x27000000000ULL, 0x28000000000ULL, MappingDesc::ORIGIN, \"origin-5\"},\n    {0x28000000000ULL, 0x29000000000ULL, MappingDesc::SHADOW, \"shadow-7\"},\n    {0x29000000000ULL, 0x2A000000000ULL, MappingDesc::ORIGIN, \"origin-7\"},\n    {0x2A000000000ULL, 0x2B000000000ULL, MappingDesc::APP, \"app-6\"},\n    {0x2B000000000ULL, 0x2C000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x2C000000000ULL, 0x2D000000000ULL, MappingDesc::SHADOW, \"shadow-6\"},\n    {0x2D000000000ULL, 0x2E000000000ULL, MappingDesc::ORIGIN, \"origin-6\"},\n    {0x2E000000000ULL, 0x2F000000000ULL, MappingDesc::APP, \"app-7\"},\n    {0x2F000000000ULL, 0x39000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x39000000000ULL, 0x3A000000000ULL, MappingDesc::SHADOW, \"shadow-9\"},\n    {0x3A000000000ULL, 0x3B000000000ULL, MappingDesc::ORIGIN, \"origin-9\"},\n    {0x3B000000000ULL, 0x3C000000000ULL, MappingDesc::APP, \"app-8\"},\n    {0x3C000000000ULL, 0x3D000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x3D000000000ULL, 0x3E000000000ULL, MappingDesc::SHADOW, \"shadow-8\"},\n    {0x3E000000000ULL, 0x3F000000000ULL, MappingDesc::ORIGIN, \"origin-8\"},\n    {0x3F000000000ULL, 0x40000000000ULL, MappingDesc::APP, \"app-9\"},\n};\n# define MEM_TO_SHADOW(mem) ((uptr)mem ^ 0x6000000000ULL)\n# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x1000000000ULL)\n\n#elif SANITIZER_LINUX && defined(__powerpc64__)\n\nconst MappingDesc kMemoryLayout[] = {\n    {0x000000000000ULL, 0x000100000000ULL, MappingDesc::APP, \"low memory\"},\n    {0x000100000000ULL, 0x080000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x080000000000ULL, 0x180100000000ULL, MappingDesc::SHADOW, \"shadow\"},\n    {0x180100000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x1C0000000000ULL, 0x2C0100000000ULL, MappingDesc::ORIGIN, \"origin\"},\n    {0x2C0100000000ULL, 0x300000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x300000000000ULL, 0x400000000000ULL, MappingDesc::APP, \"high memory\"}};\n\n// Maps low and high app ranges to contiguous space with zero base:\n//   Low:  0000 0000 0000 - 0000 ffff ffff  ->  1000 0000 0000 - 1000 ffff ffff\n//   High: 3000 0000 0000 - 3fff ffff ffff  ->  0000 0000 0000 - 0fff ffff ffff\n#define LINEARIZE_MEM(mem) \\\n  (((uptr)(mem) & ~0x200000000000ULL) ^ 0x100000000000ULL)\n#define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x080000000000ULL)\n#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x140000000000ULL)\n\n#elif SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 64\n\n// Low memory: main binary, MAP_32BIT mappings and modules\n// High memory: heap, modules and main thread stack\nconst MappingDesc kMemoryLayout[] = {\n    {0x000000000000ULL, 0x010000000000ULL, MappingDesc::APP, \"low memory\"},\n    {0x010000000000ULL, 0x100000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x100000000000ULL, 0x310000000000ULL, MappingDesc::SHADOW, \"shadow\"},\n    {0x310000000000ULL, 0x380000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x380000000000ULL, 0x590000000000ULL, MappingDesc::ORIGIN, \"origin\"},\n    {0x590000000000ULL, 0x600000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x600000000000ULL, 0x800000000000ULL, MappingDesc::APP, \"high memory\"}};\n\n// Maps low and high app ranges to contiguous space with zero base:\n//   Low:  0000 0000 0000 - 00ff ffff ffff  ->  2000 0000 0000 - 20ff ffff ffff\n//   High: 6000 0000 0000 - 7fff ffff ffff  ->  0000 0000 0000 - 1fff ffff ffff\n#define LINEARIZE_MEM(mem) \\\n  (((uptr)(mem) & ~0xc00000000000ULL) ^ 0x200000000000ULL)\n#define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x100000000000ULL)\n#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x280000000000)\n\n#elif SANITIZER_LINUX && SANITIZER_WORDSIZE == 64\n\n#ifdef MSAN_LINUX_X86_64_OLD_MAPPING\n// Requries PIE binary and ASLR enabled.\n// Main thread stack and DSOs at 0x7f0000000000 (sometimes 0x7e0000000000).\n// Heap at 0x600000000000.\nconst MappingDesc kMemoryLayout[] = {\n    {0x000000000000ULL, 0x200000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x200000000000ULL, 0x400000000000ULL, MappingDesc::SHADOW, \"shadow\"},\n    {0x400000000000ULL, 0x600000000000ULL, MappingDesc::ORIGIN, \"origin\"},\n    {0x600000000000ULL, 0x800000000000ULL, MappingDesc::APP, \"app\"}};\n\n#define MEM_TO_SHADOW(mem) (((uptr)(mem)) & ~0x400000000000ULL)\n#define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x200000000000ULL)\n#else  // MSAN_LINUX_X86_64_OLD_MAPPING\n// All of the following configurations are supported.\n// ASLR disabled: main executable and DSOs at 0x555550000000\n// PIE and ASLR: main executable and DSOs at 0x7f0000000000\n// non-PIE: main executable below 0x100000000, DSOs at 0x7f0000000000\n// Heap at 0x700000000000.\nconst MappingDesc kMemoryLayout[] = {\n    {0x000000000000ULL, 0x010000000000ULL, MappingDesc::APP, \"app-1\"},\n    {0x010000000000ULL, 0x100000000000ULL, MappingDesc::SHADOW, \"shadow-2\"},\n    {0x100000000000ULL, 0x110000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x110000000000ULL, 0x200000000000ULL, MappingDesc::ORIGIN, \"origin-2\"},\n    {0x200000000000ULL, 0x300000000000ULL, MappingDesc::SHADOW, \"shadow-3\"},\n    {0x300000000000ULL, 0x400000000000ULL, MappingDesc::ORIGIN, \"origin-3\"},\n    {0x400000000000ULL, 0x500000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x500000000000ULL, 0x510000000000ULL, MappingDesc::SHADOW, \"shadow-1\"},\n    {0x510000000000ULL, 0x600000000000ULL, MappingDesc::APP, \"app-2\"},\n    {0x600000000000ULL, 0x610000000000ULL, MappingDesc::ORIGIN, \"origin-1\"},\n    {0x610000000000ULL, 0x700000000000ULL, MappingDesc::INVALID, \"invalid\"},\n    {0x700000000000ULL, 0x800000000000ULL, MappingDesc::APP, \"app-3\"}};\n#define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL)\n#define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x100000000000ULL)\n#endif  // MSAN_LINUX_X86_64_OLD_MAPPING\n\n#else\n#error \"Unsupported platform\"\n#endif\n\nconst uptr kMemoryLayoutSize = sizeof(kMemoryLayout) / sizeof(kMemoryLayout[0]);\n\n#define MEM_TO_ORIGIN(mem) (SHADOW_TO_ORIGIN(MEM_TO_SHADOW((mem))))\n\n#ifndef __clang__\n__attribute__((optimize(\"unroll-loops\")))\n#endif\ninline bool addr_is_type(uptr addr, MappingDesc::Type mapping_type) {\n// It is critical for performance that this loop is unrolled (because then it is\n// simplified into just a few constant comparisons).\n#ifdef __clang__\n#pragma unroll\n#endif\n  for (unsigned i = 0; i < kMemoryLayoutSize; ++i)\n    if (kMemoryLayout[i].type == mapping_type &&\n        addr >= kMemoryLayout[i].start && addr < kMemoryLayout[i].end)\n      return true;\n  return false;\n}\n\n#define MEM_IS_APP(mem) addr_is_type((uptr)(mem), MappingDesc::APP)\n#define MEM_IS_SHADOW(mem) addr_is_type((uptr)(mem), MappingDesc::SHADOW)\n#define MEM_IS_ORIGIN(mem) addr_is_type((uptr)(mem), MappingDesc::ORIGIN)\n\n// These constants must be kept in sync with the ones in MemorySanitizer.cc.\nconst int kMsanParamTlsSize = 800;\nconst int kMsanRetvalTlsSize = 800;\n\nnamespace __msan {\nextern int msan_inited;\nextern bool msan_init_is_running;\nextern int msan_report_count;\n\nbool ProtectRange(uptr beg, uptr end);\nbool InitShadow(bool init_origins);\nchar *GetProcSelfMaps();\nvoid InitializeInterceptors();\n\nvoid MsanAllocatorInit();\nvoid MsanAllocatorThreadFinish();\nvoid *MsanCalloc(StackTrace *stack, uptr nmemb, uptr size);\nvoid *MsanReallocate(StackTrace *stack, void *oldp, uptr size,\n                     uptr alignment, bool zeroise);\nvoid MsanDeallocate(StackTrace *stack, void *ptr);\nvoid InstallTrapHandler();\nvoid InstallAtExitHandler();\n\nconst char *GetStackOriginDescr(u32 id, uptr *pc);\n\nvoid EnterSymbolizer();\nvoid ExitSymbolizer();\nbool IsInSymbolizer();\n\nstruct SymbolizerScope {\n  SymbolizerScope() { EnterSymbolizer(); }\n  ~SymbolizerScope() { ExitSymbolizer(); }\n};\n\nvoid PrintWarning(uptr pc, uptr bp);\nvoid PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin);\n\nvoid GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,\n                   bool request_fast_unwind);\n\nvoid ReportUMR(StackTrace *stack, u32 origin);\nvoid ReportExpectedUMRNotFound(StackTrace *stack);\nvoid ReportStats();\nvoid ReportAtExitStatistics();\nvoid DescribeMemoryRange(const void *x, uptr size);\nvoid ReportUMRInsideAddressRange(const char *what, const void *start, uptr size,\n                                 uptr offset);\n\n// Unpoison first n function arguments.\nvoid UnpoisonParam(uptr n);\nvoid UnpoisonThreadLocalState();\n\n// Returns a \"chained\" origin id, pointing to the given stack trace followed by\n// the previous origin id.\nu32 ChainOrigin(u32 id, StackTrace *stack);\n\nconst int STACK_TRACE_TAG_POISON = StackTrace::TAG_CUSTOM + 1;\n\n#define GET_MALLOC_STACK_TRACE                                                 \\\n  BufferedStackTrace stack;                                                    \\\n  if (__msan_get_track_origins() && msan_inited)                               \\\n  GetStackTrace(&stack, common_flags()->malloc_context_size,                   \\\n                StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(),               \\\n                common_flags()->fast_unwind_on_malloc)\n\n#define GET_STORE_STACK_TRACE_PC_BP(pc, bp)                                    \\\n  BufferedStackTrace stack;                                                    \\\n  if (__msan_get_track_origins() > 1 && msan_inited)                           \\\n  GetStackTrace(&stack, flags()->store_context_size, pc, bp,                   \\\n                common_flags()->fast_unwind_on_malloc)\n\n#define GET_FATAL_STACK_TRACE_PC_BP(pc, bp)                                    \\\n  BufferedStackTrace stack;                                                    \\\n  if (msan_inited)                                                             \\\n  GetStackTrace(&stack, kStackTraceMax, pc, bp,                                \\\n                common_flags()->fast_unwind_on_fatal)\n\n#define GET_STORE_STACK_TRACE \\\n  GET_STORE_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME())\n\nclass ScopedThreadLocalStateBackup {\n public:\n  ScopedThreadLocalStateBackup() { Backup(); }\n  ~ScopedThreadLocalStateBackup() { Restore(); }\n  void Backup();\n  void Restore();\n private:\n  u64 va_arg_overflow_size_tls;\n};\n\nvoid MsanTSDInit(void (*destructor)(void *tsd));\nvoid *MsanTSDGet();\nvoid MsanTSDSet(void *tsd);\nvoid MsanTSDDtor(void *tsd);\n\n}  // namespace __msan\n\n#define MSAN_MALLOC_HOOK(ptr, size) \\\n  if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(ptr, size)\n#define MSAN_FREE_HOOK(ptr) \\\n  if (&__sanitizer_free_hook) __sanitizer_free_hook(ptr)\n\n#endif  // MSAN_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan.syms.extra",
    "content": "__msan_*\n__ubsan_*\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_allocator.cc",
    "content": "//===-- msan_allocator.cc --------------------------- ---------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n// MemorySanitizer allocator.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_allocator.h\"\n#include \"sanitizer_common/sanitizer_allocator_interface.h\"\n#include \"msan.h\"\n#include \"msan_allocator.h\"\n#include \"msan_origin.h\"\n#include \"msan_thread.h\"\n#include \"msan_poisoning.h\"\n\nnamespace __msan {\n\nstruct Metadata {\n  uptr requested_size;\n};\n\nstruct MsanMapUnmapCallback {\n  void OnMap(uptr p, uptr size) const {}\n  void OnUnmap(uptr p, uptr size) const {\n    __msan_unpoison((void *)p, size);\n\n    // We are about to unmap a chunk of user memory.\n    // Mark the corresponding shadow memory as not needed.\n    FlushUnneededShadowMemory(MEM_TO_SHADOW(p), size);\n    if (__msan_get_track_origins())\n      FlushUnneededShadowMemory(MEM_TO_ORIGIN(p), size);\n  }\n};\n\n#if defined(__mips64)\n  static const uptr kMaxAllowedMallocSize = 2UL << 30;\n  static const uptr kRegionSizeLog = 20;\n  static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;\n  typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;\n  typedef CompactSizeClassMap SizeClassMap;\n\n  typedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE, sizeof(Metadata),\n                               SizeClassMap, kRegionSizeLog, ByteMap,\n                               MsanMapUnmapCallback> PrimaryAllocator;\n\n#elif defined(__x86_64__)\n#if SANITIZER_LINUX && !defined(MSAN_LINUX_X86_64_OLD_MAPPING)\n  static const uptr kAllocatorSpace = 0x700000000000ULL;\n#else\n  static const uptr kAllocatorSpace = 0x600000000000ULL;\n#endif\n  static const uptr kAllocatorSize = 0x80000000000; // 8T.\n  static const uptr kMetadataSize  = sizeof(Metadata);\n  static const uptr kMaxAllowedMallocSize = 8UL << 30;\n\n  typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, kMetadataSize,\n                             DefaultSizeClassMap,\n                             MsanMapUnmapCallback> PrimaryAllocator;\n\n#elif defined(__powerpc64__)\n  static const uptr kAllocatorSpace = 0x300000000000;\n  static const uptr kAllocatorSize  = 0x020000000000;  // 2T\n  static const uptr kMetadataSize  = sizeof(Metadata);\n  static const uptr kMaxAllowedMallocSize = 2UL << 30;  // 2G\n\n  typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, kMetadataSize,\n                             DefaultSizeClassMap,\n                             MsanMapUnmapCallback> PrimaryAllocator;\n#elif defined(__aarch64__)\n  static const uptr kMaxAllowedMallocSize = 2UL << 30;  // 2G\n  static const uptr kRegionSizeLog = 20;\n  static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;\n  typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;\n  typedef CompactSizeClassMap SizeClassMap;\n\n  typedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE, sizeof(Metadata),\n                               SizeClassMap, kRegionSizeLog, ByteMap,\n                               MsanMapUnmapCallback> PrimaryAllocator;\n#endif\ntypedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;\ntypedef LargeMmapAllocator<MsanMapUnmapCallback> SecondaryAllocator;\ntypedef CombinedAllocator<PrimaryAllocator, AllocatorCache,\n                          SecondaryAllocator> Allocator;\n\nstatic Allocator allocator;\nstatic AllocatorCache fallback_allocator_cache;\nstatic SpinMutex fallback_mutex;\n\nvoid MsanAllocatorInit() {\n  allocator.Init(common_flags()->allocator_may_return_null);\n}\n\nAllocatorCache *GetAllocatorCache(MsanThreadLocalMallocStorage *ms) {\n  CHECK(ms);\n  CHECK_LE(sizeof(AllocatorCache), sizeof(ms->allocator_cache));\n  return reinterpret_cast<AllocatorCache *>(ms->allocator_cache);\n}\n\nvoid MsanThreadLocalMallocStorage::CommitBack() {\n  allocator.SwallowCache(GetAllocatorCache(this));\n}\n\nstatic void *MsanAllocate(StackTrace *stack, uptr size, uptr alignment,\n                          bool zeroise) {\n  if (size > kMaxAllowedMallocSize) {\n    Report(\"WARNING: MemorySanitizer failed to allocate %p bytes\\n\",\n           (void *)size);\n    return allocator.ReturnNullOrDie();\n  }\n  MsanThread *t = GetCurrentThread();\n  void *allocated;\n  if (t) {\n    AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());\n    allocated = allocator.Allocate(cache, size, alignment, false);\n  } else {\n    SpinMutexLock l(&fallback_mutex);\n    AllocatorCache *cache = &fallback_allocator_cache;\n    allocated = allocator.Allocate(cache, size, alignment, false);\n  }\n  Metadata *meta =\n      reinterpret_cast<Metadata *>(allocator.GetMetaData(allocated));\n  meta->requested_size = size;\n  if (zeroise) {\n    __msan_clear_and_unpoison(allocated, size);\n  } else if (flags()->poison_in_malloc) {\n    __msan_poison(allocated, size);\n    if (__msan_get_track_origins()) {\n      stack->tag = StackTrace::TAG_ALLOC;\n      Origin o = Origin::CreateHeapOrigin(stack);\n      __msan_set_origin(allocated, size, o.raw_id());\n    }\n  }\n  MSAN_MALLOC_HOOK(allocated, size);\n  return allocated;\n}\n\nvoid MsanDeallocate(StackTrace *stack, void *p) {\n  CHECK(p);\n  MSAN_FREE_HOOK(p);\n  Metadata *meta = reinterpret_cast<Metadata *>(allocator.GetMetaData(p));\n  uptr size = meta->requested_size;\n  meta->requested_size = 0;\n  // This memory will not be reused by anyone else, so we are free to keep it\n  // poisoned.\n  if (flags()->poison_in_free) {\n    __msan_poison(p, size);\n    if (__msan_get_track_origins()) {\n      stack->tag = StackTrace::TAG_DEALLOC;\n      Origin o = Origin::CreateHeapOrigin(stack);\n      __msan_set_origin(p, size, o.raw_id());\n    }\n  }\n  MsanThread *t = GetCurrentThread();\n  if (t) {\n    AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());\n    allocator.Deallocate(cache, p);\n  } else {\n    SpinMutexLock l(&fallback_mutex);\n    AllocatorCache *cache = &fallback_allocator_cache;\n    allocator.Deallocate(cache, p);\n  }\n}\n\nvoid *MsanCalloc(StackTrace *stack, uptr nmemb, uptr size) {\n  if (CallocShouldReturnNullDueToOverflow(size, nmemb))\n    return allocator.ReturnNullOrDie();\n  return MsanReallocate(stack, nullptr, nmemb * size, sizeof(u64), true);\n}\n\nvoid *MsanReallocate(StackTrace *stack, void *old_p, uptr new_size,\n                     uptr alignment, bool zeroise) {\n  if (!old_p)\n    return MsanAllocate(stack, new_size, alignment, zeroise);\n  if (!new_size) {\n    MsanDeallocate(stack, old_p);\n    return nullptr;\n  }\n  Metadata *meta = reinterpret_cast<Metadata*>(allocator.GetMetaData(old_p));\n  uptr old_size = meta->requested_size;\n  uptr actually_allocated_size = allocator.GetActuallyAllocatedSize(old_p);\n  if (new_size <= actually_allocated_size) {\n    // We are not reallocating here.\n    meta->requested_size = new_size;\n    if (new_size > old_size) {\n      if (zeroise) {\n        __msan_clear_and_unpoison((char *)old_p + old_size,\n                                  new_size - old_size);\n      } else if (flags()->poison_in_malloc) {\n        stack->tag = StackTrace::TAG_ALLOC;\n        PoisonMemory((char *)old_p + old_size, new_size - old_size, stack);\n      }\n    }\n    return old_p;\n  }\n  uptr memcpy_size = Min(new_size, old_size);\n  void *new_p = MsanAllocate(stack, new_size, alignment, zeroise);\n  // Printf(\"realloc: old_size %zd new_size %zd\\n\", old_size, new_size);\n  if (new_p) {\n    CopyMemory(new_p, old_p, memcpy_size, stack);\n    MsanDeallocate(stack, old_p);\n  }\n  return new_p;\n}\n\nstatic uptr AllocationSize(const void *p) {\n  if (!p) return 0;\n  const void *beg = allocator.GetBlockBegin(p);\n  if (beg != p) return 0;\n  Metadata *b = (Metadata *)allocator.GetMetaData(p);\n  return b->requested_size;\n}\n\n} // namespace __msan\n\nusing namespace __msan;\n\nuptr __sanitizer_get_current_allocated_bytes() {\n  uptr stats[AllocatorStatCount];\n  allocator.GetStats(stats);\n  return stats[AllocatorStatAllocated];\n}\n\nuptr __sanitizer_get_heap_size() {\n  uptr stats[AllocatorStatCount];\n  allocator.GetStats(stats);\n  return stats[AllocatorStatMapped];\n}\n\nuptr __sanitizer_get_free_bytes() { return 1; }\n\nuptr __sanitizer_get_unmapped_bytes() { return 1; }\n\nuptr __sanitizer_get_estimated_allocated_size(uptr size) { return size; }\n\nint __sanitizer_get_ownership(const void *p) { return AllocationSize(p) != 0; }\n\nuptr __sanitizer_get_allocated_size(const void *p) { return AllocationSize(p); }\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_allocator.h",
    "content": "//===-- msan_allocator.h ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef MSAN_ALLOCATOR_H\n#define MSAN_ALLOCATOR_H\n\n#include \"sanitizer_common/sanitizer_common.h\"\n\nnamespace __msan {\n\nstruct MsanThreadLocalMallocStorage {\n  uptr quarantine_cache[16];\n  // Allocator cache contains atomic_uint64_t which must be 8-byte aligned.\n  ALIGNED(8) uptr allocator_cache[96 * (512 * 8 + 16)];  // Opaque.\n  void CommitBack();\n\n private:\n  // These objects are allocated via mmap() and are zero-initialized.\n  MsanThreadLocalMallocStorage() {}\n};\n\n} // namespace __msan\n#endif // MSAN_ALLOCATOR_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_blacklist.txt",
    "content": "# Blacklist for MemorySanitizer. Turns off instrumentation of particular\n# functions or sources. Use with care. You may set location of blacklist\n# at compile-time using -fsanitize-blacklist=<path> flag.\n\n# Example usage:\n# fun:*bad_function_name*\n# src:file_with_tricky_code.cc\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_chained_origin_depot.cc",
    "content": "//===-- msan_chained_origin_depot.cc -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// A storage for chained origins.\n//===----------------------------------------------------------------------===//\n\n#include \"msan_chained_origin_depot.h\"\n\n#include \"sanitizer_common/sanitizer_stackdepotbase.h\"\n\nnamespace __msan {\n\nstruct ChainedOriginDepotDesc {\n  u32 here_id;\n  u32 prev_id;\n};\n\nstruct ChainedOriginDepotNode {\n  ChainedOriginDepotNode *link;\n  u32 id;\n  u32 here_id;\n  u32 prev_id;\n\n  typedef ChainedOriginDepotDesc args_type;\n\n  bool eq(u32 hash, const args_type &args) const {\n    return here_id == args.here_id && prev_id == args.prev_id;\n  }\n\n  static uptr storage_size(const args_type &args) {\n    return sizeof(ChainedOriginDepotNode);\n  }\n\n  /* This is murmur2 hash for the 64->32 bit case.\n     It does not behave all that well because the keys have a very biased\n     distribution (I've seen 7-element buckets with the table only 14% full).\n\n     here_id is built of\n     * (1 bits) Reserved, zero.\n     * (8 bits) Part id = bits 13..20 of the hash value of here_id's key.\n     * (23 bits) Sequential number (each part has each own sequence).\n\n     prev_id has either the same distribution as here_id (but with 3:8:21)\n     split, or one of two reserved values (-1) or (-2). Either case can\n     dominate depending on the workload.\n  */\n  static u32 hash(const args_type &args) {\n    const u32 m = 0x5bd1e995;\n    const u32 seed = 0x9747b28c;\n    const u32 r = 24;\n    u32 h = seed;\n    u32 k = args.here_id;\n    k *= m;\n    k ^= k >> r;\n    k *= m;\n    h *= m;\n    h ^= k;\n\n    k = args.prev_id;\n    k *= m;\n    k ^= k >> r;\n    k *= m;\n    h *= m;\n    h ^= k;\n\n    h ^= h >> 13;\n    h *= m;\n    h ^= h >> 15;\n    return h;\n  }\n  static bool is_valid(const args_type &args) { return true; }\n  void store(const args_type &args, u32 other_hash) {\n    here_id = args.here_id;\n    prev_id = args.prev_id;\n  }\n\n  args_type load() const {\n    args_type ret = {here_id, prev_id};\n    return ret;\n  }\n\n  struct Handle {\n    ChainedOriginDepotNode *node_;\n    Handle() : node_(nullptr) {}\n    explicit Handle(ChainedOriginDepotNode *node) : node_(node) {}\n    bool valid() { return node_; }\n    u32 id() { return node_->id; }\n    int here_id() { return node_->here_id; }\n    int prev_id() { return node_->prev_id; }\n  };\n\n  Handle get_handle() { return Handle(this); }\n\n  typedef Handle handle_type;\n};\n\nstatic StackDepotBase<ChainedOriginDepotNode, 4, 20> chainedOriginDepot;\n\nStackDepotStats *ChainedOriginDepotGetStats() {\n  return chainedOriginDepot.GetStats();\n}\n\nbool ChainedOriginDepotPut(u32 here_id, u32 prev_id, u32 *new_id) {\n  ChainedOriginDepotDesc desc = {here_id, prev_id};\n  bool inserted;\n  ChainedOriginDepotNode::Handle h = chainedOriginDepot.Put(desc, &inserted);\n  *new_id = h.valid() ? h.id() : 0;\n  return inserted;\n}\n\n// Retrieves a stored stack trace by the id.\nu32 ChainedOriginDepotGet(u32 id, u32 *other) {\n  ChainedOriginDepotDesc desc = chainedOriginDepot.Get(id);\n  *other = desc.prev_id;\n  return desc.here_id;\n}\n\nvoid ChainedOriginDepotLockAll() {\n  chainedOriginDepot.LockAll();\n}\n\nvoid ChainedOriginDepotUnlockAll() {\n  chainedOriginDepot.UnlockAll();\n}\n\n} // namespace __msan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_chained_origin_depot.h",
    "content": "//===-- msan_chained_origin_depot.h --------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// A storage for chained origins.\n//===----------------------------------------------------------------------===//\n#ifndef MSAN_CHAINED_ORIGIN_DEPOT_H\n#define MSAN_CHAINED_ORIGIN_DEPOT_H\n\n#include \"sanitizer_common/sanitizer_common.h\"\n\nnamespace __msan {\n\nStackDepotStats *ChainedOriginDepotGetStats();\nbool ChainedOriginDepotPut(u32 here_id, u32 prev_id, u32 *new_id);\n// Retrieves a stored stack trace by the id.\nu32 ChainedOriginDepotGet(u32 id, u32 *other);\n\nvoid ChainedOriginDepotLockAll();\nvoid ChainedOriginDepotUnlockAll();\n\n}  // namespace __msan\n\n#endif  // MSAN_CHAINED_ORIGIN_DEPOT_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_flags.h",
    "content": "//===-- msan_flags.h --------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n//===----------------------------------------------------------------------===//\n#ifndef MSAN_FLAGS_H\n#define MSAN_FLAGS_H\n\nnamespace __msan {\n\nstruct Flags {\n#define MSAN_FLAG(Type, Name, DefaultValue, Description) Type Name;\n#include \"msan_flags.inc\"\n#undef MSAN_FLAG\n\n  void SetDefaults();\n};\n\nFlags *flags();\n\n}  // namespace __msan\n\n#endif  // MSAN_FLAGS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_flags.inc",
    "content": "//===-- msan_flags.inc ------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// MSan runtime flags.\n//\n//===----------------------------------------------------------------------===//\n#ifndef MSAN_FLAG\n# error \"Define MSAN_FLAG prior to including this file!\"\n#endif\n\n// MSAN_FLAG(Type, Name, DefaultValue, Description)\n// See COMMON_FLAG in sanitizer_flags.inc for more details.\n\nMSAN_FLAG(int, exit_code, -1,\n          \"DEPRECATED. Use exitcode from common flags instead.\")\nMSAN_FLAG(int, origin_history_size, Origin::kMaxDepth, \"\")\nMSAN_FLAG(int, origin_history_per_stack_limit, 20000, \"\")\nMSAN_FLAG(bool, poison_heap_with_zeroes, false, \"\")\nMSAN_FLAG(bool, poison_stack_with_zeroes, false, \"\")\nMSAN_FLAG(bool, poison_in_malloc, true, \"\")\nMSAN_FLAG(bool, poison_in_free, true, \"\")\nMSAN_FLAG(bool, poison_in_dtor, false, \"\")\nMSAN_FLAG(bool, report_umrs, true, \"\")\nMSAN_FLAG(bool, wrap_signals, true, \"\")\nMSAN_FLAG(bool, print_stats, false, \"\")\nMSAN_FLAG(bool, halt_on_error, !&__msan_keep_going, \"\")\nMSAN_FLAG(bool, atexit, false, \"\")\nMSAN_FLAG(int, store_context_size, 20,\n          \"Like malloc_context_size, but for uninit stores.\")\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_interceptors.cc",
    "content": "//===-- msan_interceptors.cc ----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n// Interceptors for standard library functions.\n//\n// FIXME: move as many interceptors as possible into\n// sanitizer_common/sanitizer_common_interceptors.h\n//===----------------------------------------------------------------------===//\n\n#include \"interception/interception.h\"\n#include \"msan.h\"\n#include \"msan_chained_origin_depot.h\"\n#include \"msan_origin.h\"\n#include \"msan_thread.h\"\n#include \"msan_poisoning.h\"\n#include \"sanitizer_common/sanitizer_platform_limits_posix.h\"\n#include \"sanitizer_common/sanitizer_allocator.h\"\n#include \"sanitizer_common/sanitizer_allocator_interface.h\"\n#include \"sanitizer_common/sanitizer_allocator_internal.h\"\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_linux.h\"\n#include \"sanitizer_common/sanitizer_tls_get_addr.h\"\n\n#include <stdarg.h>\n// ACHTUNG! No other system header includes in this file.\n// Ideally, we should get rid of stdarg.h as well.\n\nusing namespace __msan;\n\nusing __sanitizer::memory_order;\nusing __sanitizer::atomic_load;\nusing __sanitizer::atomic_store;\nusing __sanitizer::atomic_uintptr_t;\n\n#if SANITIZER_FREEBSD\n#define __errno_location __error\n#endif\n\n// True if this is a nested interceptor.\nstatic THREADLOCAL int in_interceptor_scope;\n\nextern \"C\" int *__errno_location(void);\n\nstruct InterceptorScope {\n  InterceptorScope() { ++in_interceptor_scope; }\n  ~InterceptorScope() { --in_interceptor_scope; }\n};\n\nbool IsInInterceptorScope() {\n  return in_interceptor_scope;\n}\n\n#define ENSURE_MSAN_INITED() do { \\\n  CHECK(!msan_init_is_running); \\\n  if (!msan_inited) { \\\n    __msan_init(); \\\n  } \\\n} while (0)\n\n// Check that [x, x+n) range is unpoisoned.\n#define CHECK_UNPOISONED_0(x, n)                                               \\\n  do {                                                                         \\\n    sptr offset = __msan_test_shadow(x, n);                                    \\\n    if (__msan::IsInSymbolizer())                                              \\\n      break;                                                                   \\\n    if (offset >= 0 && __msan::flags()->report_umrs) {                         \\\n      GET_CALLER_PC_BP_SP;                                                     \\\n      (void) sp;                                                               \\\n      ReportUMRInsideAddressRange(__func__, x, n, offset);                     \\\n      __msan::PrintWarningWithOrigin(                                          \\\n          pc, bp, __msan_get_origin((const char *)x + offset));                \\\n      if (__msan::flags()->halt_on_error) {                                    \\\n        Printf(\"Exiting\\n\");                                                   \\\n        Die();                                                                 \\\n      }                                                                        \\\n    }                                                                          \\\n  } while (0)\n\n// Check that [x, x+n) range is unpoisoned unless we are in a nested\n// interceptor.\n#define CHECK_UNPOISONED(x, n)                             \\\n  do {                                                     \\\n    if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n); \\\n  } while (0);\n\n#define CHECK_UNPOISONED_STRING_OF_LEN(x, len, n)               \\\n  CHECK_UNPOISONED((x),                                         \\\n    common_flags()->strict_string_checks ? (len) + 1 : (n) )\n\n#define CHECK_UNPOISONED_STRING(x, n)                           \\\n    CHECK_UNPOISONED_STRING_OF_LEN((x), internal_strlen(x), (n))\n\nINTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {\n  ENSURE_MSAN_INITED();\n  SIZE_T res = REAL(fread)(ptr, size, nmemb, file);\n  if (res > 0)\n    __msan_unpoison(ptr, res *size);\n  return res;\n}\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,\n            void *file) {\n  ENSURE_MSAN_INITED();\n  SIZE_T res = REAL(fread_unlocked)(ptr, size, nmemb, file);\n  if (res > 0)\n    __msan_unpoison(ptr, res *size);\n  return res;\n}\n#define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED INTERCEPT_FUNCTION(fread_unlocked)\n#else\n#define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED\n#endif\n\nINTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {\n  ENSURE_MSAN_INITED();\n  CHECK_UNPOISONED_STRING(path, 0)\n  SSIZE_T res = REAL(readlink)(path, buf, bufsiz);\n  if (res > 0)\n    __msan_unpoison(buf, res);\n  return res;\n}\n\nINTERCEPTOR(void *, memcpy, void *dest, const void *src, SIZE_T n) {\n  return __msan_memcpy(dest, src, n);\n}\n\nINTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) {\n  return (char *)__msan_memcpy(dest, src, n) + n;\n}\n\nINTERCEPTOR(void *, memccpy, void *dest, const void *src, int c, SIZE_T n) {\n  ENSURE_MSAN_INITED();\n  void *res = REAL(memccpy)(dest, src, c, n);\n  CHECK(!res || (res >= dest && res <= (char *)dest + n));\n  SIZE_T sz = res ? (char *)res - (char *)dest : n;\n  CHECK_UNPOISONED(src, sz);\n  __msan_unpoison(dest, sz);\n  return res;\n}\n\nINTERCEPTOR(void *, memmove, void *dest, const void *src, SIZE_T n) {\n  return __msan_memmove(dest, src, n);\n}\n\nINTERCEPTOR(void *, memset, void *s, int c, SIZE_T n) {\n  return __msan_memset(s, c, n);\n}\n\nINTERCEPTOR(void *, bcopy, const void *src, void *dest, SIZE_T n) {\n  return __msan_memmove(dest, src, n);\n}\n\nINTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {\n  GET_MALLOC_STACK_TRACE;\n  CHECK_EQ(alignment & (alignment - 1), 0);\n  CHECK_NE(memptr, 0);\n  *memptr = MsanReallocate(&stack, nullptr, size, alignment, false);\n  CHECK_NE(*memptr, 0);\n  __msan_unpoison(memptr, sizeof(*memptr));\n  return 0;\n}\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(void *, memalign, SIZE_T boundary, SIZE_T size) {\n  GET_MALLOC_STACK_TRACE;\n  CHECK_EQ(boundary & (boundary - 1), 0);\n  void *ptr = MsanReallocate(&stack, nullptr, size, boundary, false);\n  return ptr;\n}\n#define MSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)\n#else\n#define MSAN_MAYBE_INTERCEPT_MEMALIGN\n#endif\n\nINTERCEPTOR(void *, aligned_alloc, SIZE_T boundary, SIZE_T size) {\n  GET_MALLOC_STACK_TRACE;\n  CHECK_EQ(boundary & (boundary - 1), 0);\n  void *ptr = MsanReallocate(&stack, nullptr, size, boundary, false);\n  return ptr;\n}\n\nINTERCEPTOR(void *, __libc_memalign, SIZE_T boundary, SIZE_T size) {\n  GET_MALLOC_STACK_TRACE;\n  CHECK_EQ(boundary & (boundary - 1), 0);\n  void *ptr = MsanReallocate(&stack, nullptr, size, boundary, false);\n  DTLS_on_libc_memalign(ptr, size * boundary);\n  return ptr;\n}\n\nINTERCEPTOR(void *, valloc, SIZE_T size) {\n  GET_MALLOC_STACK_TRACE;\n  void *ptr = MsanReallocate(&stack, nullptr, size, GetPageSizeCached(), false);\n  return ptr;\n}\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(void *, pvalloc, SIZE_T size) {\n  GET_MALLOC_STACK_TRACE;\n  uptr PageSize = GetPageSizeCached();\n  size = RoundUpTo(size, PageSize);\n  if (size == 0) {\n    // pvalloc(0) should allocate one page.\n    size = PageSize;\n  }\n  void *ptr = MsanReallocate(&stack, nullptr, size, PageSize, false);\n  return ptr;\n}\n#define MSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)\n#else\n#define MSAN_MAYBE_INTERCEPT_PVALLOC\n#endif\n\nINTERCEPTOR(void, free, void *ptr) {\n  GET_MALLOC_STACK_TRACE;\n  if (!ptr) return;\n  MsanDeallocate(&stack, ptr);\n}\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(void, cfree, void *ptr) {\n  GET_MALLOC_STACK_TRACE;\n  if (!ptr) return;\n  MsanDeallocate(&stack, ptr);\n}\n#define MSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree)\n#else\n#define MSAN_MAYBE_INTERCEPT_CFREE\n#endif\n\nINTERCEPTOR(uptr, malloc_usable_size, void *ptr) {\n  return __sanitizer_get_allocated_size(ptr);\n}\n\n#if !SANITIZER_FREEBSD\n// This function actually returns a struct by value, but we can't unpoison a\n// temporary! The following is equivalent on all supported platforms but\n// aarch64 (which uses a different register for sret value).  We have a test\n// to confirm that.\nINTERCEPTOR(void, mallinfo, __sanitizer_mallinfo *sret) {\n#ifdef __aarch64__\n  uptr r8;\n  asm volatile(\"mov %0,x8\" : \"=r\" (r8));\n  sret = reinterpret_cast<__sanitizer_mallinfo*>(r8);\n#endif\n  REAL(memset)(sret, 0, sizeof(*sret));\n  __msan_unpoison(sret, sizeof(*sret));\n}\n#define MSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo)\n#else\n#define MSAN_MAYBE_INTERCEPT_MALLINFO\n#endif\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(int, mallopt, int cmd, int value) {\n  return -1;\n}\n#define MSAN_MAYBE_INTERCEPT_MALLOPT INTERCEPT_FUNCTION(mallopt)\n#else\n#define MSAN_MAYBE_INTERCEPT_MALLOPT\n#endif\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(void, malloc_stats, void) {\n  // FIXME: implement, but don't call REAL(malloc_stats)!\n}\n#define MSAN_MAYBE_INTERCEPT_MALLOC_STATS INTERCEPT_FUNCTION(malloc_stats)\n#else\n#define MSAN_MAYBE_INTERCEPT_MALLOC_STATS\n#endif\n\nINTERCEPTOR(SIZE_T, strlen, const char *s) {\n  if (msan_init_is_running)\n    return REAL(strlen)(s);\n  ENSURE_MSAN_INITED();\n  SIZE_T res = REAL(strlen)(s);\n  CHECK_UNPOISONED(s, res + 1);\n  return res;\n}\n\nINTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T n) {\n  ENSURE_MSAN_INITED();\n  SIZE_T res = REAL(strnlen)(s, n);\n  SIZE_T scan_size = (res == n) ? res : res + 1;\n  CHECK_UNPOISONED(s, scan_size);\n  return res;\n}\n\nINTERCEPTOR(char *, strcpy, char *dest, const char *src) {  // NOLINT\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  SIZE_T n = REAL(strlen)(src);\n  CHECK_UNPOISONED_STRING(src + n, 0);\n  char *res = REAL(strcpy)(dest, src);  // NOLINT\n  CopyShadowAndOrigin(dest, src, n + 1, &stack);\n  return res;\n}\n\nINTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) {  // NOLINT\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  SIZE_T copy_size = REAL(strnlen)(src, n);\n  if (copy_size < n)\n    copy_size++;  // trailing \\0\n  char *res = REAL(strncpy)(dest, src, n);  // NOLINT\n  CopyShadowAndOrigin(dest, src, copy_size, &stack);\n  __msan_unpoison(dest + copy_size, n - copy_size);\n  return res;\n}\n\nINTERCEPTOR(char *, stpcpy, char *dest, const char *src) {  // NOLINT\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  SIZE_T n = REAL(strlen)(src);\n  CHECK_UNPOISONED_STRING(src + n, 0);\n  char *res = REAL(stpcpy)(dest, src);  // NOLINT\n  CopyShadowAndOrigin(dest, src, n + 1, &stack);\n  return res;\n}\n\nINTERCEPTOR(char *, strdup, char *src) {\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  // On FreeBSD strdup() leverages strlen().\n  InterceptorScope interceptor_scope;\n  SIZE_T n = REAL(strlen)(src);\n  CHECK_UNPOISONED_STRING(src + n, 0);\n  char *res = REAL(strdup)(src);\n  CopyShadowAndOrigin(res, src, n + 1, &stack);\n  return res;\n}\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(char *, __strdup, char *src) {\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  SIZE_T n = REAL(strlen)(src);\n  CHECK_UNPOISONED_STRING(src + n, 0);\n  char *res = REAL(__strdup)(src);\n  CopyShadowAndOrigin(res, src, n + 1, &stack);\n  return res;\n}\n#define MSAN_MAYBE_INTERCEPT___STRDUP INTERCEPT_FUNCTION(__strdup)\n#else\n#define MSAN_MAYBE_INTERCEPT___STRDUP\n#endif\n\nINTERCEPTOR(char *, strndup, char *src, SIZE_T n) {\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  // On FreeBSD strndup() leverages strnlen().\n  InterceptorScope interceptor_scope;\n  SIZE_T copy_size = REAL(strnlen)(src, n);\n  char *res = REAL(strndup)(src, n);\n  CopyShadowAndOrigin(res, src, copy_size, &stack);\n  __msan_unpoison(res + copy_size, 1); // \\0\n  return res;\n}\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(char *, __strndup, char *src, SIZE_T n) {\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  SIZE_T copy_size = REAL(strnlen)(src, n);\n  char *res = REAL(__strndup)(src, n);\n  CopyShadowAndOrigin(res, src, copy_size, &stack);\n  __msan_unpoison(res + copy_size, 1); // \\0\n  return res;\n}\n#define MSAN_MAYBE_INTERCEPT___STRNDUP INTERCEPT_FUNCTION(__strndup)\n#else\n#define MSAN_MAYBE_INTERCEPT___STRNDUP\n#endif\n\nINTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {\n  ENSURE_MSAN_INITED();\n  char *res = REAL(gcvt)(number, ndigit, buf);\n  SIZE_T n = REAL(strlen)(buf);\n  __msan_unpoison(buf, n + 1);\n  return res;\n}\n\nINTERCEPTOR(char *, strcat, char *dest, const char *src) {  // NOLINT\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  SIZE_T src_size = REAL(strlen)(src);\n  SIZE_T dest_size = REAL(strlen)(dest);\n  CHECK_UNPOISONED_STRING(src + src_size, 0);\n  CHECK_UNPOISONED_STRING(dest + dest_size, 0);\n  char *res = REAL(strcat)(dest, src);  // NOLINT\n  CopyShadowAndOrigin(dest + dest_size, src, src_size + 1, &stack);\n  return res;\n}\n\nINTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {  // NOLINT\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  SIZE_T dest_size = REAL(strlen)(dest);\n  SIZE_T copy_size = REAL(strnlen)(src, n);\n  CHECK_UNPOISONED_STRING(dest + dest_size, 0);\n  char *res = REAL(strncat)(dest, src, n);  // NOLINT\n  CopyShadowAndOrigin(dest + dest_size, src, copy_size, &stack);\n  __msan_unpoison(dest + dest_size + copy_size, 1); // \\0\n  return res;\n}\n\n// Hack: always pass nptr and endptr as part of __VA_ARGS_ to avoid having to\n// deal with empty __VA_ARGS__ in the case of INTERCEPTOR_STRTO.\n#define INTERCEPTOR_STRTO_BODY(ret_type, func, ...) \\\n  ENSURE_MSAN_INITED();                             \\\n  ret_type res = REAL(func)(__VA_ARGS__);           \\\n  __msan_unpoison(endptr, sizeof(*endptr));         \\\n  return res;\n\n#define INTERCEPTOR_STRTO(ret_type, func, char_type)                       \\\n  INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr) { \\\n    INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr);                  \\\n  }\n\n#define INTERCEPTOR_STRTO_BASE(ret_type, func, char_type)                \\\n  INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \\\n              int base) {                                                \\\n    INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base);          \\\n  }\n\n#define INTERCEPTOR_STRTO_LOC(ret_type, func, char_type)                 \\\n  INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \\\n              void *loc) {                                               \\\n    INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, loc);           \\\n  }\n\n#define INTERCEPTOR_STRTO_BASE_LOC(ret_type, func, char_type)            \\\n  INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \\\n              int base, void *loc) {                                     \\\n    INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base, loc);     \\\n  }\n\n#define INTERCEPTORS_STRTO(ret_type, func, char_type)      \\\n  INTERCEPTOR_STRTO(ret_type, func, char_type)             \\\n  INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type)     \\\n  INTERCEPTOR_STRTO_LOC(ret_type, __##func##_l, char_type) \\\n  INTERCEPTOR_STRTO_LOC(ret_type, __##func##_internal, char_type)\n\n#define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type)      \\\n  INTERCEPTOR_STRTO_BASE(ret_type, func, char_type)             \\\n  INTERCEPTOR_STRTO_BASE_LOC(ret_type, func##_l, char_type)     \\\n  INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_l, char_type) \\\n  INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_internal, char_type)\n\nINTERCEPTORS_STRTO(double, strtod, char)                     // NOLINT\nINTERCEPTORS_STRTO(float, strtof, char)                      // NOLINT\nINTERCEPTORS_STRTO(long double, strtold, char)               // NOLINT\nINTERCEPTORS_STRTO_BASE(long, strtol, char)                  // NOLINT\nINTERCEPTORS_STRTO_BASE(long long, strtoll, char)            // NOLINT\nINTERCEPTORS_STRTO_BASE(unsigned long, strtoul, char)        // NOLINT\nINTERCEPTORS_STRTO_BASE(unsigned long long, strtoull, char)  // NOLINT\n\nINTERCEPTORS_STRTO(double, wcstod, wchar_t)                     // NOLINT\nINTERCEPTORS_STRTO(float, wcstof, wchar_t)                      // NOLINT\nINTERCEPTORS_STRTO(long double, wcstold, wchar_t)               // NOLINT\nINTERCEPTORS_STRTO_BASE(long, wcstol, wchar_t)                  // NOLINT\nINTERCEPTORS_STRTO_BASE(long long, wcstoll, wchar_t)            // NOLINT\nINTERCEPTORS_STRTO_BASE(unsigned long, wcstoul, wchar_t)        // NOLINT\nINTERCEPTORS_STRTO_BASE(unsigned long long, wcstoull, wchar_t)  // NOLINT\n\n#define INTERCEPT_STRTO(func) \\\n  INTERCEPT_FUNCTION(func); \\\n  INTERCEPT_FUNCTION(func##_l); \\\n  INTERCEPT_FUNCTION(__##func##_l); \\\n  INTERCEPT_FUNCTION(__##func##_internal);\n\n\n// FIXME: support *wprintf in common format interceptors.\nINTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(vswprintf)(str, size, format, ap);\n  if (res >= 0) {\n    __msan_unpoison(str, 4 * (res + 1));\n  }\n  return res;\n}\n\nINTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) {\n  ENSURE_MSAN_INITED();\n  va_list ap;\n  va_start(ap, format);\n  int res = vswprintf(str, size, format, ap);\n  va_end(ap);\n  return res;\n}\n\nINTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T n) {\n  ENSURE_MSAN_INITED();\n  CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);\n  SIZE_T res = REAL(strxfrm)(dest, src, n);\n  if (res < n) __msan_unpoison(dest, res + 1);\n  return res;\n}\n\nINTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T n,\n            void *loc) {\n  ENSURE_MSAN_INITED();\n  CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);\n  SIZE_T res = REAL(strxfrm_l)(dest, src, n, loc);\n  if (res < n) __msan_unpoison(dest, res + 1);\n  return res;\n}\n\n#define INTERCEPTOR_STRFTIME_BODY(char_type, ret_type, func, s, ...) \\\n  ENSURE_MSAN_INITED();                                              \\\n  ret_type res = REAL(func)(s, __VA_ARGS__);                         \\\n  if (s) __msan_unpoison(s, sizeof(char_type) * (res + 1));          \\\n  return res;\n\nINTERCEPTOR(SIZE_T, strftime, char *s, SIZE_T max, const char *format,\n            __sanitizer_tm *tm) {\n  INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime, s, max, format, tm);\n}\n\nINTERCEPTOR(SIZE_T, strftime_l, char *s, SIZE_T max, const char *format,\n            __sanitizer_tm *tm, void *loc) {\n  INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime_l, s, max, format, tm, loc);\n}\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(SIZE_T, __strftime_l, char *s, SIZE_T max, const char *format,\n            __sanitizer_tm *tm, void *loc) {\n  INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, __strftime_l, s, max, format, tm,\n                            loc);\n}\n#define MSAN_MAYBE_INTERCEPT___STRFTIME_L INTERCEPT_FUNCTION(__strftime_l)\n#else\n#define MSAN_MAYBE_INTERCEPT___STRFTIME_L\n#endif\n\nINTERCEPTOR(SIZE_T, wcsftime, wchar_t *s, SIZE_T max, const wchar_t *format,\n            __sanitizer_tm *tm) {\n  INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime, s, max, format, tm);\n}\n\nINTERCEPTOR(SIZE_T, wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,\n            __sanitizer_tm *tm, void *loc) {\n  INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime_l, s, max, format, tm,\n                            loc);\n}\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(SIZE_T, __wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,\n            __sanitizer_tm *tm, void *loc) {\n  INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, __wcsftime_l, s, max, format, tm,\n                            loc);\n}\n#define MSAN_MAYBE_INTERCEPT___WCSFTIME_L INTERCEPT_FUNCTION(__wcsftime_l)\n#else\n#define MSAN_MAYBE_INTERCEPT___WCSFTIME_L\n#endif\n\nINTERCEPTOR(int, mbtowc, wchar_t *dest, const char *src, SIZE_T n) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(mbtowc)(dest, src, n);\n  if (res != -1 && dest) __msan_unpoison(dest, sizeof(wchar_t));\n  return res;\n}\n\nINTERCEPTOR(int, mbrtowc, wchar_t *dest, const char *src, SIZE_T n, void *ps) {\n  ENSURE_MSAN_INITED();\n  SIZE_T res = REAL(mbrtowc)(dest, src, n, ps);\n  if (res != (SIZE_T)-1 && dest) __msan_unpoison(dest, sizeof(wchar_t));\n  return res;\n}\n\nINTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {\n  ENSURE_MSAN_INITED();\n  SIZE_T res = REAL(wcslen)(s);\n  CHECK_UNPOISONED(s, sizeof(wchar_t) * (res + 1));\n  return res;\n}\n\n// wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);\nINTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {\n  ENSURE_MSAN_INITED();\n  wchar_t *res = REAL(wcschr)(s, wc, ps);\n  return res;\n}\n\n// wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);\nINTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  wchar_t *res = REAL(wcscpy)(dest, src);\n  CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1),\n                      &stack);\n  return res;\n}\n\n// wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n);\nINTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  wchar_t *res = REAL(wmemcpy)(dest, src, n);\n  CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);\n  return res;\n}\n\nINTERCEPTOR(wchar_t *, wmempcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  wchar_t *res = REAL(wmempcpy)(dest, src, n);\n  CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);\n  return res;\n}\n\nINTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) {\n  CHECK(MEM_IS_APP(s));\n  ENSURE_MSAN_INITED();\n  wchar_t *res = REAL(wmemset)(s, c, n);\n  __msan_unpoison(s, n * sizeof(wchar_t));\n  return res;\n}\n\nINTERCEPTOR(wchar_t *, wmemmove, wchar_t *dest, const wchar_t *src, SIZE_T n) {\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  wchar_t *res = REAL(wmemmove)(dest, src, n);\n  MoveShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);\n  return res;\n}\n\nINTERCEPTOR(int, wcscmp, const wchar_t *s1, const wchar_t *s2) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(wcscmp)(s1, s2);\n  return res;\n}\n\nINTERCEPTOR(int, gettimeofday, void *tv, void *tz) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(gettimeofday)(tv, tz);\n  if (tv)\n    __msan_unpoison(tv, 16);\n  if (tz)\n    __msan_unpoison(tz, 8);\n  return res;\n}\n\nINTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {\n  ENSURE_MSAN_INITED();\n  char *res = REAL(fcvt)(x, a, b, c);\n  __msan_unpoison(b, sizeof(*b));\n  __msan_unpoison(c, sizeof(*c));\n  if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);\n  return res;\n}\n\nINTERCEPTOR(char *, getenv, char *name) {\n  if (msan_init_is_running)\n    return REAL(getenv)(name);\n  ENSURE_MSAN_INITED();\n  char *res = REAL(getenv)(name);\n  if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);\n  return res;\n}\n\nextern char **environ;\n\nstatic void UnpoisonEnviron() {\n  char **envp = environ;\n  for (; *envp; ++envp) {\n    __msan_unpoison(envp, sizeof(*envp));\n    __msan_unpoison(*envp, REAL(strlen)(*envp) + 1);\n  }\n  // Trailing NULL pointer.\n  __msan_unpoison(envp, sizeof(*envp));\n}\n\nINTERCEPTOR(int, setenv, const char *name, const char *value, int overwrite) {\n  ENSURE_MSAN_INITED();\n  CHECK_UNPOISONED_STRING(name, 0)\n  int res = REAL(setenv)(name, value, overwrite);\n  if (!res) UnpoisonEnviron();\n  return res;\n}\n\nINTERCEPTOR(int, putenv, char *string) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(putenv)(string);\n  if (!res) UnpoisonEnviron();\n  return res;\n}\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(__fxstat)(magic, fd, buf);\n  if (!res)\n    __msan_unpoison(buf, __sanitizer::struct_stat_sz);\n  return res;\n}\n#define MSAN_MAYBE_INTERCEPT___FXSTAT INTERCEPT_FUNCTION(__fxstat)\n#else\n#define MSAN_MAYBE_INTERCEPT___FXSTAT\n#endif\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(__fxstat64)(magic, fd, buf);\n  if (!res)\n    __msan_unpoison(buf, __sanitizer::struct_stat64_sz);\n  return res;\n}\n#define MSAN_MAYBE_INTERCEPT___FXSTAT64 INTERCEPT_FUNCTION(__fxstat64)\n#else\n#define MSAN_MAYBE_INTERCEPT___FXSTAT64\n#endif\n\n#if SANITIZER_FREEBSD\nINTERCEPTOR(int, fstatat, int fd, char *pathname, void *buf, int flags) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(fstatat)(fd, pathname, buf, flags);\n  if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz);\n  return res;\n}\n# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(fstatat)\n#else\nINTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf,\n            int flags) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(__fxstatat)(magic, fd, pathname, buf, flags);\n  if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz);\n  return res;\n}\n# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(__fxstatat)\n#endif\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf,\n            int flags) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(__fxstatat64)(magic, fd, pathname, buf, flags);\n  if (!res) __msan_unpoison(buf, __sanitizer::struct_stat64_sz);\n  return res;\n}\n#define MSAN_MAYBE_INTERCEPT___FXSTATAT64 INTERCEPT_FUNCTION(__fxstatat64)\n#else\n#define MSAN_MAYBE_INTERCEPT___FXSTATAT64\n#endif\n\n#if SANITIZER_FREEBSD\nINTERCEPTOR(int, stat, char *path, void *buf) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(stat)(path, buf);\n  if (!res)\n    __msan_unpoison(buf, __sanitizer::struct_stat_sz);\n  return res;\n}\n# define MSAN_INTERCEPT_STAT INTERCEPT_FUNCTION(stat)\n#else\nINTERCEPTOR(int, __xstat, int magic, char *path, void *buf) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(__xstat)(magic, path, buf);\n  if (!res)\n    __msan_unpoison(buf, __sanitizer::struct_stat_sz);\n  return res;\n}\n# define MSAN_INTERCEPT_STAT INTERCEPT_FUNCTION(__xstat)\n#endif\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(int, __xstat64, int magic, char *path, void *buf) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(__xstat64)(magic, path, buf);\n  if (!res)\n    __msan_unpoison(buf, __sanitizer::struct_stat64_sz);\n  return res;\n}\n#define MSAN_MAYBE_INTERCEPT___XSTAT64 INTERCEPT_FUNCTION(__xstat64)\n#else\n#define MSAN_MAYBE_INTERCEPT___XSTAT64\n#endif\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(int, __lxstat, int magic, char *path, void *buf) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(__lxstat)(magic, path, buf);\n  if (!res)\n    __msan_unpoison(buf, __sanitizer::struct_stat_sz);\n  return res;\n}\n#define MSAN_MAYBE_INTERCEPT___LXSTAT INTERCEPT_FUNCTION(__lxstat)\n#else\n#define MSAN_MAYBE_INTERCEPT___LXSTAT\n#endif\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(int, __lxstat64, int magic, char *path, void *buf) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(__lxstat64)(magic, path, buf);\n  if (!res)\n    __msan_unpoison(buf, __sanitizer::struct_stat64_sz);\n  return res;\n}\n#define MSAN_MAYBE_INTERCEPT___LXSTAT64 INTERCEPT_FUNCTION(__lxstat64)\n#else\n#define MSAN_MAYBE_INTERCEPT___LXSTAT64\n#endif\n\nINTERCEPTOR(int, pipe, int pipefd[2]) {\n  if (msan_init_is_running)\n    return REAL(pipe)(pipefd);\n  ENSURE_MSAN_INITED();\n  int res = REAL(pipe)(pipefd);\n  if (!res)\n    __msan_unpoison(pipefd, sizeof(int[2]));\n  return res;\n}\n\nINTERCEPTOR(int, pipe2, int pipefd[2], int flags) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(pipe2)(pipefd, flags);\n  if (!res)\n    __msan_unpoison(pipefd, sizeof(int[2]));\n  return res;\n}\n\nINTERCEPTOR(int, socketpair, int domain, int type, int protocol, int sv[2]) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(socketpair)(domain, type, protocol, sv);\n  if (!res)\n    __msan_unpoison(sv, sizeof(int[2]));\n  return res;\n}\n\nINTERCEPTOR(char *, fgets, char *s, int size, void *stream) {\n  ENSURE_MSAN_INITED();\n  char *res = REAL(fgets)(s, size, stream);\n  if (res)\n    __msan_unpoison(s, REAL(strlen)(s) + 1);\n  return res;\n}\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {\n  ENSURE_MSAN_INITED();\n  char *res = REAL(fgets_unlocked)(s, size, stream);\n  if (res)\n    __msan_unpoison(s, REAL(strlen)(s) + 1);\n  return res;\n}\n#define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED INTERCEPT_FUNCTION(fgets_unlocked)\n#else\n#define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED\n#endif\n\nINTERCEPTOR(int, getrlimit, int resource, void *rlim) {\n  if (msan_init_is_running)\n    return REAL(getrlimit)(resource, rlim);\n  ENSURE_MSAN_INITED();\n  int res = REAL(getrlimit)(resource, rlim);\n  if (!res)\n    __msan_unpoison(rlim, __sanitizer::struct_rlimit_sz);\n  return res;\n}\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(int, getrlimit64, int resource, void *rlim) {\n  if (msan_init_is_running)\n    return REAL(getrlimit64)(resource, rlim);\n  ENSURE_MSAN_INITED();\n  int res = REAL(getrlimit64)(resource, rlim);\n  if (!res)\n    __msan_unpoison(rlim, __sanitizer::struct_rlimit64_sz);\n  return res;\n}\n#define MSAN_MAYBE_INTERCEPT_GETRLIMIT64 INTERCEPT_FUNCTION(getrlimit64)\n#else\n#define MSAN_MAYBE_INTERCEPT_GETRLIMIT64\n#endif\n\n#if SANITIZER_FREEBSD\n// FreeBSD's <sys/utsname.h> define uname() as\n// static __inline int uname(struct utsname *name) {\n//   return __xuname(SYS_NMLN, (void*)name);\n// }\nINTERCEPTOR(int, __xuname, int size, void *utsname) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(__xuname)(size, utsname);\n  if (!res)\n    __msan_unpoison(utsname, __sanitizer::struct_utsname_sz);\n  return res;\n}\n#define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(__xuname)\n#else\nINTERCEPTOR(int, uname, struct utsname *utsname) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(uname)(utsname);\n  if (!res)\n    __msan_unpoison(utsname, __sanitizer::struct_utsname_sz);\n  return res;\n}\n#define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(uname)\n#endif\n\nINTERCEPTOR(int, gethostname, char *name, SIZE_T len) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(gethostname)(name, len);\n  if (!res) {\n    SIZE_T real_len = REAL(strnlen)(name, len);\n    if (real_len < len)\n      ++real_len;\n    __msan_unpoison(name, real_len);\n  }\n  return res;\n}\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,\n    int timeout) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(epoll_wait)(epfd, events, maxevents, timeout);\n  if (res > 0) {\n    __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);\n  }\n  return res;\n}\n#define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT INTERCEPT_FUNCTION(epoll_wait)\n#else\n#define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT\n#endif\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents,\n    int timeout, void *sigmask) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(epoll_pwait)(epfd, events, maxevents, timeout, sigmask);\n  if (res > 0) {\n    __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);\n  }\n  return res;\n}\n#define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT INTERCEPT_FUNCTION(epoll_pwait)\n#else\n#define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT\n#endif\n\nINTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {\n  ENSURE_MSAN_INITED();\n  SSIZE_T res = REAL(recv)(fd, buf, len, flags);\n  if (res > 0)\n    __msan_unpoison(buf, res);\n  return res;\n}\n\nINTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,\n            void *srcaddr, int *addrlen) {\n  ENSURE_MSAN_INITED();\n  SIZE_T srcaddr_sz;\n  if (srcaddr) srcaddr_sz = *addrlen;\n  SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);\n  if (res > 0) {\n    __msan_unpoison(buf, res);\n    if (srcaddr) {\n      SIZE_T sz = *addrlen;\n      __msan_unpoison(srcaddr, Min(sz, srcaddr_sz));\n    }\n  }\n  return res;\n}\n\nINTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {\n  GET_MALLOC_STACK_TRACE;\n  if (UNLIKELY(!msan_inited)) {\n    // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.\n    const SIZE_T kCallocPoolSize = 1024;\n    static uptr calloc_memory_for_dlsym[kCallocPoolSize];\n    static SIZE_T allocated;\n    SIZE_T size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;\n    void *mem = (void*)&calloc_memory_for_dlsym[allocated];\n    allocated += size_in_words;\n    CHECK(allocated < kCallocPoolSize);\n    return mem;\n  }\n  return MsanCalloc(&stack, nmemb, size);\n}\n\nINTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {\n  GET_MALLOC_STACK_TRACE;\n  return MsanReallocate(&stack, ptr, size, sizeof(u64), false);\n}\n\nINTERCEPTOR(void *, malloc, SIZE_T size) {\n  GET_MALLOC_STACK_TRACE;\n  return MsanReallocate(&stack, nullptr, size, sizeof(u64), false);\n}\n\nvoid __msan_allocated_memory(const void *data, uptr size) {\n  GET_MALLOC_STACK_TRACE;\n  if (flags()->poison_in_malloc) {\n    stack.tag = STACK_TRACE_TAG_POISON;\n    PoisonMemory(data, size, &stack);\n  }\n}\n\nvoid __msan_copy_shadow(void *dest, const void *src, uptr n) {\n  GET_STORE_STACK_TRACE;\n  MoveShadowAndOrigin(dest, src, n, &stack);\n}\n\nvoid __sanitizer_dtor_callback(const void *data, uptr size) {\n  GET_MALLOC_STACK_TRACE;\n  if (flags()->poison_in_dtor) {\n    stack.tag = STACK_TRACE_TAG_POISON;\n    PoisonMemory(data, size, &stack);\n  }\n}\n\nINTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,\n            int fd, OFF_T offset) {\n  if (msan_init_is_running)\n    return REAL(mmap)(addr, length, prot, flags, fd, offset);\n  ENSURE_MSAN_INITED();\n  if (addr && !MEM_IS_APP(addr)) {\n    if (flags & map_fixed) {\n      *__errno_location() = errno_EINVAL;\n      return (void *)-1;\n    } else {\n      addr = nullptr;\n    }\n  }\n  void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);\n  if (res != (void*)-1)\n    __msan_unpoison(res, RoundUpTo(length, GetPageSize()));\n  return res;\n}\n\n#if !SANITIZER_FREEBSD\nINTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,\n            int fd, OFF64_T offset) {\n  ENSURE_MSAN_INITED();\n  if (addr && !MEM_IS_APP(addr)) {\n    if (flags & map_fixed) {\n      *__errno_location() = errno_EINVAL;\n      return (void *)-1;\n    } else {\n      addr = nullptr;\n    }\n  }\n  void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);\n  if (res != (void*)-1)\n    __msan_unpoison(res, RoundUpTo(length, GetPageSize()));\n  return res;\n}\n#define MSAN_MAYBE_INTERCEPT_MMAP64 INTERCEPT_FUNCTION(mmap64)\n#else\n#define MSAN_MAYBE_INTERCEPT_MMAP64\n#endif\n\nstruct dlinfo {\n  char *dli_fname;\n  void *dli_fbase;\n  char *dli_sname;\n  void *dli_saddr;\n};\n\nINTERCEPTOR(int, dladdr, void *addr, dlinfo *info) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(dladdr)(addr, info);\n  if (res != 0) {\n    __msan_unpoison(info, sizeof(*info));\n    if (info->dli_fname)\n      __msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1);\n    if (info->dli_sname)\n      __msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1);\n  }\n  return res;\n}\n\nINTERCEPTOR(char *, dlerror, int fake) {\n  ENSURE_MSAN_INITED();\n  char *res = REAL(dlerror)(fake);\n  if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);\n  return res;\n}\n\ntypedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size,\n                                  void *data);\nstruct dl_iterate_phdr_data {\n  dl_iterate_phdr_cb callback;\n  void *data;\n};\n\nstatic int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,\n                                   void *data) {\n  if (info) {\n    __msan_unpoison(info, size);\n    if (info->dlpi_phdr && info->dlpi_phnum)\n      __msan_unpoison(info->dlpi_phdr, struct_ElfW_Phdr_sz * info->dlpi_phnum);\n    if (info->dlpi_name)\n      __msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1);\n  }\n  dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;\n  UnpoisonParam(3);\n  return cbdata->callback(info, size, cbdata->data);\n}\n\nINTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {\n  ENSURE_MSAN_INITED();\n  dl_iterate_phdr_data cbdata;\n  cbdata.callback = callback;\n  cbdata.data = data;\n  int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata);\n  return res;\n}\n\nINTERCEPTOR(int, getrusage, int who, void *usage) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(getrusage)(who, usage);\n  if (res == 0) {\n    __msan_unpoison(usage, __sanitizer::struct_rusage_sz);\n  }\n  return res;\n}\n\nclass SignalHandlerScope {\n public:\n  SignalHandlerScope() {\n    if (MsanThread *t = GetCurrentThread())\n      t->EnterSignalHandler();\n  }\n  ~SignalHandlerScope() {\n    if (MsanThread *t = GetCurrentThread())\n      t->LeaveSignalHandler();\n  }\n};\n\n// sigactions_mu guarantees atomicity of sigaction() and signal() calls.\n// Access to sigactions[] is gone with relaxed atomics to avoid data race with\n// the signal handler.\nconst int kMaxSignals = 1024;\nstatic atomic_uintptr_t sigactions[kMaxSignals];\nstatic StaticSpinMutex sigactions_mu;\n\nstatic void SignalHandler(int signo) {\n  SignalHandlerScope signal_handler_scope;\n  ScopedThreadLocalStateBackup stlsb;\n  UnpoisonParam(1);\n\n  typedef void (*signal_cb)(int x);\n  signal_cb cb =\n      (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);\n  cb(signo);\n}\n\nstatic void SignalAction(int signo, void *si, void *uc) {\n  SignalHandlerScope signal_handler_scope;\n  ScopedThreadLocalStateBackup stlsb;\n  UnpoisonParam(3);\n  __msan_unpoison(si, sizeof(__sanitizer_sigaction));\n  __msan_unpoison(uc, __sanitizer::ucontext_t_sz);\n\n  typedef void (*sigaction_cb)(int, void *, void *);\n  sigaction_cb cb =\n      (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);\n  cb(signo, si, uc);\n}\n\nINTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act,\n            __sanitizer_sigaction *oldact) {\n  ENSURE_MSAN_INITED();\n  // FIXME: check that *act is unpoisoned.\n  // That requires intercepting all of sigemptyset, sigfillset, etc.\n  int res;\n  if (flags()->wrap_signals) {\n    SpinMutexLock lock(&sigactions_mu);\n    CHECK_LT(signo, kMaxSignals);\n    uptr old_cb = atomic_load(&sigactions[signo], memory_order_relaxed);\n    __sanitizer_sigaction new_act;\n    __sanitizer_sigaction *pnew_act = act ? &new_act : nullptr;\n    if (act) {\n      REAL(memcpy)(pnew_act, act, sizeof(__sanitizer_sigaction));\n      uptr cb = (uptr)pnew_act->sigaction;\n      uptr new_cb = (pnew_act->sa_flags & __sanitizer::sa_siginfo)\n                        ? (uptr)SignalAction\n                        : (uptr)SignalHandler;\n      if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {\n        atomic_store(&sigactions[signo], cb, memory_order_relaxed);\n        pnew_act->sigaction = (void (*)(int, void *, void *))new_cb;\n      }\n    }\n    res = REAL(sigaction)(signo, pnew_act, oldact);\n    if (res == 0 && oldact) {\n      uptr cb = (uptr)oldact->sigaction;\n      if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {\n        oldact->sigaction = (void (*)(int, void *, void *))old_cb;\n      }\n    }\n  } else {\n    res = REAL(sigaction)(signo, act, oldact);\n  }\n\n  if (res == 0 && oldact) {\n    __msan_unpoison(oldact, sizeof(__sanitizer_sigaction));\n  }\n  return res;\n}\n\nINTERCEPTOR(int, signal, int signo, uptr cb) {\n  ENSURE_MSAN_INITED();\n  if (flags()->wrap_signals) {\n    CHECK_LT(signo, kMaxSignals);\n    SpinMutexLock lock(&sigactions_mu);\n    if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {\n      atomic_store(&sigactions[signo], cb, memory_order_relaxed);\n      cb = (uptr) SignalHandler;\n    }\n    return REAL(signal)(signo, cb);\n  } else {\n    return REAL(signal)(signo, cb);\n  }\n}\n\nextern \"C\" int pthread_attr_init(void *attr);\nextern \"C\" int pthread_attr_destroy(void *attr);\n\nstatic void *MsanThreadStartFunc(void *arg) {\n  MsanThread *t = (MsanThread *)arg;\n  SetCurrentThread(t);\n  return t->ThreadStart();\n}\n\nINTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),\n            void * param) {\n  ENSURE_MSAN_INITED(); // for GetTlsSize()\n  __sanitizer_pthread_attr_t myattr;\n  if (!attr) {\n    pthread_attr_init(&myattr);\n    attr = &myattr;\n  }\n\n  AdjustStackSize(attr);\n\n  MsanThread *t = MsanThread::Create(callback, param);\n\n  int res = REAL(pthread_create)(th, attr, MsanThreadStartFunc, t);\n\n  if (attr == &myattr)\n    pthread_attr_destroy(&myattr);\n  if (!res) {\n    __msan_unpoison(th, __sanitizer::pthread_t_sz);\n  }\n  return res;\n}\n\nINTERCEPTOR(int, pthread_key_create, __sanitizer_pthread_key_t *key,\n            void (*dtor)(void *value)) {\n  if (msan_init_is_running) return REAL(pthread_key_create)(key, dtor);\n  ENSURE_MSAN_INITED();\n  int res = REAL(pthread_key_create)(key, dtor);\n  if (!res && key)\n    __msan_unpoison(key, sizeof(*key));\n  return res;\n}\n\nINTERCEPTOR(int, pthread_join, void *th, void **retval) {\n  ENSURE_MSAN_INITED();\n  int res = REAL(pthread_join)(th, retval);\n  if (!res && retval)\n    __msan_unpoison(retval, sizeof(*retval));\n  return res;\n}\n\nextern char *tzname[2];\n\nINTERCEPTOR(void, tzset, int fake) {\n  ENSURE_MSAN_INITED();\n  REAL(tzset)(fake);\n  if (tzname[0])\n    __msan_unpoison(tzname[0], REAL(strlen)(tzname[0]) + 1);\n  if (tzname[1])\n    __msan_unpoison(tzname[1], REAL(strlen)(tzname[1]) + 1);\n  return;\n}\n\nstruct MSanAtExitRecord {\n  void (*func)(void *arg);\n  void *arg;\n};\n\nvoid MSanAtExitWrapper(void *arg) {\n  UnpoisonParam(1);\n  MSanAtExitRecord *r = (MSanAtExitRecord *)arg;\n  r->func(r->arg);\n  InternalFree(r);\n}\n\n// Unpoison argument shadow for C++ module destructors.\nINTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,\n            void *dso_handle) {\n  if (msan_init_is_running) return REAL(__cxa_atexit)(func, arg, dso_handle);\n  ENSURE_MSAN_INITED();\n  MSanAtExitRecord *r =\n      (MSanAtExitRecord *)InternalAlloc(sizeof(MSanAtExitRecord));\n  r->func = func;\n  r->arg = arg;\n  return REAL(__cxa_atexit)(MSanAtExitWrapper, r, dso_handle);\n}\n\nDECLARE_REAL(int, shmctl, int shmid, int cmd, void *buf)\n\nINTERCEPTOR(void *, shmat, int shmid, const void *shmaddr, int shmflg) {\n  ENSURE_MSAN_INITED();\n  void *p = REAL(shmat)(shmid, shmaddr, shmflg);\n  if (p != (void *)-1) {\n    __sanitizer_shmid_ds ds;\n    int res = REAL(shmctl)(shmid, shmctl_ipc_stat, &ds);\n    if (!res) {\n      __msan_unpoison(p, ds.shm_segsz);\n    }\n  }\n  return p;\n}\n\nstatic void BeforeFork() {\n  StackDepotLockAll();\n  ChainedOriginDepotLockAll();\n}\n\nstatic void AfterFork() {\n  ChainedOriginDepotUnlockAll();\n  StackDepotUnlockAll();\n}\n\nINTERCEPTOR(int, fork, void) {\n  ENSURE_MSAN_INITED();\n  BeforeFork();\n  int pid = REAL(fork)();\n  AfterFork();\n  return pid;\n}\n\nINTERCEPTOR(int, openpty, int *amaster, int *aslave, char *name,\n            const void *termp, const void *winp) {\n  ENSURE_MSAN_INITED();\n  InterceptorScope interceptor_scope;\n  int res = REAL(openpty)(amaster, aslave, name, termp, winp);\n  if (!res) {\n    __msan_unpoison(amaster, sizeof(*amaster));\n    __msan_unpoison(aslave, sizeof(*aslave));\n  }\n  return res;\n}\n\nINTERCEPTOR(int, forkpty, int *amaster, char *name, const void *termp,\n            const void *winp) {\n  ENSURE_MSAN_INITED();\n  InterceptorScope interceptor_scope;\n  int res = REAL(forkpty)(amaster, name, termp, winp);\n  if (res != -1)\n    __msan_unpoison(amaster, sizeof(*amaster));\n  return res;\n}\n\nstruct MSanInterceptorContext {\n  bool in_interceptor_scope;\n};\n\nnamespace __msan {\n\nint OnExit() {\n  // FIXME: ask frontend whether we need to return failure.\n  return 0;\n}\n\n} // namespace __msan\n\n// A version of CHECK_UNPOISONED using a saved scope value. Used in common\n// interceptors.\n#define CHECK_UNPOISONED_CTX(ctx, x, n)                         \\\n  do {                                                          \\\n    if (!((MSanInterceptorContext *)ctx)->in_interceptor_scope) \\\n      CHECK_UNPOISONED_0(x, n);                                 \\\n  } while (0)\n\n#define MSAN_INTERCEPT_FUNC(name)                                       \\\n  do {                                                                  \\\n    if ((!INTERCEPT_FUNCTION(name) || !REAL(name)))                     \\\n      VReport(1, \"MemorySanitizer: failed to intercept '\" #name \"'\\n\"); \\\n  } while (0)\n\n#define COMMON_INTERCEPT_FUNCTION(name) MSAN_INTERCEPT_FUNC(name)\n#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count)  \\\n  UnpoisonParam(count)\n#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \\\n  __msan_unpoison(ptr, size)\n#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \\\n  CHECK_UNPOISONED_CTX(ctx, ptr, size)\n#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ptr, size) \\\n  __msan_unpoison(ptr, size)\n#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)                  \\\n  if (msan_init_is_running) return REAL(func)(__VA_ARGS__);       \\\n  MSanInterceptorContext msan_ctx = {IsInInterceptorScope()};     \\\n  ctx = (void *)&msan_ctx;                                        \\\n  (void)ctx;                                                      \\\n  InterceptorScope interceptor_scope;                             \\\n  __msan_unpoison(__errno_location(), sizeof(int)); /* NOLINT */  \\\n  ENSURE_MSAN_INITED();\n#define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \\\n  do {                                            \\\n  } while (false)\n#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \\\n  do {                                         \\\n  } while (false)\n#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \\\n  do {                                         \\\n  } while (false)\n#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \\\n  do {                                                      \\\n  } while (false)\n#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \\\n  do {                                                \\\n  } while (false)  // FIXME\n#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \\\n  do {                                                         \\\n  } while (false)  // FIXME\n#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)\n#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()\n#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle)                    \\\n  do {                                                                         \\\n    link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE((handle));                   \\\n    if (filename && map)                                                       \\\n      ForEachMappedRegion(map, __msan_unpoison);                               \\\n  } while (false)\n\n#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end)                           \\\n  if (MsanThread *t = GetCurrentThread()) {                                    \\\n    *begin = t->tls_begin();                                                   \\\n    *end = t->tls_end();                                                       \\\n  } else {                                                                     \\\n    *begin = *end = 0;                                                         \\\n  }\n\n#include \"sanitizer_common/sanitizer_common_interceptors.inc\"\n\n#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)\n#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \\\n  do {                                       \\\n  } while (false)\n#define COMMON_SYSCALL_POST_READ_RANGE(p, s) \\\n  do {                                       \\\n  } while (false)\n#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s)\n#include \"sanitizer_common/sanitizer_common_syscalls.inc\"\n\n// These interface functions reside here so that they can use\n// REAL(memset), etc.\nvoid __msan_unpoison(const void *a, uptr size) {\n  if (!MEM_IS_APP(a)) return;\n  SetShadow(a, size, 0);\n}\n\nvoid __msan_poison(const void *a, uptr size) {\n  if (!MEM_IS_APP(a)) return;\n  SetShadow(a, size, __msan::flags()->poison_heap_with_zeroes ? 0 : -1);\n}\n\nvoid __msan_poison_stack(void *a, uptr size) {\n  if (!MEM_IS_APP(a)) return;\n  SetShadow(a, size, __msan::flags()->poison_stack_with_zeroes ? 0 : -1);\n}\n\nvoid __msan_clear_and_unpoison(void *a, uptr size) {\n  REAL(memset)(a, 0, size);\n  SetShadow(a, size, 0);\n}\n\nvoid *__msan_memcpy(void *dest, const void *src, SIZE_T n) {\n  if (!msan_inited) return internal_memcpy(dest, src, n);\n  if (msan_init_is_running || __msan::IsInSymbolizer())\n    return REAL(memcpy)(dest, src, n);\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  void *res = REAL(memcpy)(dest, src, n);\n  CopyShadowAndOrigin(dest, src, n, &stack);\n  return res;\n}\n\nvoid *__msan_memset(void *s, int c, SIZE_T n) {\n  if (!msan_inited) return internal_memset(s, c, n);\n  if (msan_init_is_running) return REAL(memset)(s, c, n);\n  ENSURE_MSAN_INITED();\n  void *res = REAL(memset)(s, c, n);\n  __msan_unpoison(s, n);\n  return res;\n}\n\nvoid *__msan_memmove(void *dest, const void *src, SIZE_T n) {\n  if (!msan_inited) return internal_memmove(dest, src, n);\n  if (msan_init_is_running) return REAL(memmove)(dest, src, n);\n  ENSURE_MSAN_INITED();\n  GET_STORE_STACK_TRACE;\n  void *res = REAL(memmove)(dest, src, n);\n  MoveShadowAndOrigin(dest, src, n, &stack);\n  return res;\n}\n\nvoid __msan_unpoison_string(const char* s) {\n  if (!MEM_IS_APP(s)) return;\n  __msan_unpoison(s, REAL(strlen)(s) + 1);\n}\n\nnamespace __msan {\n\nvoid InitializeInterceptors() {\n  static int inited = 0;\n  CHECK_EQ(inited, 0);\n  InitializeCommonInterceptors();\n\n  INTERCEPT_FUNCTION(mmap);\n  MSAN_MAYBE_INTERCEPT_MMAP64;\n  INTERCEPT_FUNCTION(posix_memalign);\n  MSAN_MAYBE_INTERCEPT_MEMALIGN;\n  INTERCEPT_FUNCTION(__libc_memalign);\n  INTERCEPT_FUNCTION(valloc);\n  MSAN_MAYBE_INTERCEPT_PVALLOC;\n  INTERCEPT_FUNCTION(malloc);\n  INTERCEPT_FUNCTION(calloc);\n  INTERCEPT_FUNCTION(realloc);\n  INTERCEPT_FUNCTION(free);\n  MSAN_MAYBE_INTERCEPT_CFREE;\n  INTERCEPT_FUNCTION(malloc_usable_size);\n  MSAN_MAYBE_INTERCEPT_MALLINFO;\n  MSAN_MAYBE_INTERCEPT_MALLOPT;\n  MSAN_MAYBE_INTERCEPT_MALLOC_STATS;\n  INTERCEPT_FUNCTION(fread);\n  MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED;\n  INTERCEPT_FUNCTION(readlink);\n  INTERCEPT_FUNCTION(memcpy);\n  INTERCEPT_FUNCTION(memccpy);\n  INTERCEPT_FUNCTION(mempcpy);\n  INTERCEPT_FUNCTION(memset);\n  INTERCEPT_FUNCTION(memmove);\n  INTERCEPT_FUNCTION(bcopy);\n  INTERCEPT_FUNCTION(wmemset);\n  INTERCEPT_FUNCTION(wmemcpy);\n  INTERCEPT_FUNCTION(wmempcpy);\n  INTERCEPT_FUNCTION(wmemmove);\n  INTERCEPT_FUNCTION(strcpy);  // NOLINT\n  INTERCEPT_FUNCTION(stpcpy);  // NOLINT\n  INTERCEPT_FUNCTION(strdup);\n  MSAN_MAYBE_INTERCEPT___STRDUP;\n  INTERCEPT_FUNCTION(strndup);\n  MSAN_MAYBE_INTERCEPT___STRNDUP;\n  INTERCEPT_FUNCTION(strncpy);  // NOLINT\n  INTERCEPT_FUNCTION(strlen);\n  INTERCEPT_FUNCTION(strnlen);\n  INTERCEPT_FUNCTION(gcvt);\n  INTERCEPT_FUNCTION(strcat);  // NOLINT\n  INTERCEPT_FUNCTION(strncat);  // NOLINT\n  INTERCEPT_STRTO(strtod);\n  INTERCEPT_STRTO(strtof);\n  INTERCEPT_STRTO(strtold);\n  INTERCEPT_STRTO(strtol);\n  INTERCEPT_STRTO(strtoul);\n  INTERCEPT_STRTO(strtoll);\n  INTERCEPT_STRTO(strtoull);\n  INTERCEPT_STRTO(wcstod);\n  INTERCEPT_STRTO(wcstof);\n  INTERCEPT_STRTO(wcstold);\n  INTERCEPT_STRTO(wcstol);\n  INTERCEPT_STRTO(wcstoul);\n  INTERCEPT_STRTO(wcstoll);\n  INTERCEPT_STRTO(wcstoull);\n  INTERCEPT_FUNCTION(vswprintf);\n  INTERCEPT_FUNCTION(swprintf);\n  INTERCEPT_FUNCTION(strxfrm);\n  INTERCEPT_FUNCTION(strxfrm_l);\n  INTERCEPT_FUNCTION(strftime);\n  INTERCEPT_FUNCTION(strftime_l);\n  MSAN_MAYBE_INTERCEPT___STRFTIME_L;\n  INTERCEPT_FUNCTION(wcsftime);\n  INTERCEPT_FUNCTION(wcsftime_l);\n  MSAN_MAYBE_INTERCEPT___WCSFTIME_L;\n  INTERCEPT_FUNCTION(mbtowc);\n  INTERCEPT_FUNCTION(mbrtowc);\n  INTERCEPT_FUNCTION(wcslen);\n  INTERCEPT_FUNCTION(wcschr);\n  INTERCEPT_FUNCTION(wcscpy);\n  INTERCEPT_FUNCTION(wcscmp);\n  INTERCEPT_FUNCTION(getenv);\n  INTERCEPT_FUNCTION(setenv);\n  INTERCEPT_FUNCTION(putenv);\n  INTERCEPT_FUNCTION(gettimeofday);\n  INTERCEPT_FUNCTION(fcvt);\n  MSAN_MAYBE_INTERCEPT___FXSTAT;\n  MSAN_INTERCEPT_FSTATAT;\n  MSAN_INTERCEPT_STAT;\n  MSAN_MAYBE_INTERCEPT___LXSTAT;\n  MSAN_MAYBE_INTERCEPT___FXSTAT64;\n  MSAN_MAYBE_INTERCEPT___FXSTATAT64;\n  MSAN_MAYBE_INTERCEPT___XSTAT64;\n  MSAN_MAYBE_INTERCEPT___LXSTAT64;\n  INTERCEPT_FUNCTION(pipe);\n  INTERCEPT_FUNCTION(pipe2);\n  INTERCEPT_FUNCTION(socketpair);\n  INTERCEPT_FUNCTION(fgets);\n  MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED;\n  INTERCEPT_FUNCTION(getrlimit);\n  MSAN_MAYBE_INTERCEPT_GETRLIMIT64;\n  MSAN_INTERCEPT_UNAME;\n  INTERCEPT_FUNCTION(gethostname);\n  MSAN_MAYBE_INTERCEPT_EPOLL_WAIT;\n  MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT;\n  INTERCEPT_FUNCTION(recv);\n  INTERCEPT_FUNCTION(recvfrom);\n  INTERCEPT_FUNCTION(dladdr);\n  INTERCEPT_FUNCTION(dlerror);\n  INTERCEPT_FUNCTION(dl_iterate_phdr);\n  INTERCEPT_FUNCTION(getrusage);\n  INTERCEPT_FUNCTION(sigaction);\n  INTERCEPT_FUNCTION(signal);\n  INTERCEPT_FUNCTION(pthread_create);\n  INTERCEPT_FUNCTION(pthread_key_create);\n  INTERCEPT_FUNCTION(pthread_join);\n  INTERCEPT_FUNCTION(tzset);\n  INTERCEPT_FUNCTION(__cxa_atexit);\n  INTERCEPT_FUNCTION(shmat);\n  INTERCEPT_FUNCTION(fork);\n  INTERCEPT_FUNCTION(openpty);\n  INTERCEPT_FUNCTION(forkpty);\n\n  inited = 1;\n}\n} // namespace __msan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_interface_internal.h",
    "content": "//===-- msan_interface_internal.h -------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n// Private MSan interface header.\n//===----------------------------------------------------------------------===//\n\n#ifndef MSAN_INTERFACE_INTERNAL_H\n#define MSAN_INTERFACE_INTERNAL_H\n\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n\nextern \"C\" {\n// FIXME: document all interface functions.\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __msan_get_track_origins();\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_init();\n\n// Print a warning and maybe return.\n// This function can die based on common_flags()->exitcode.\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_warning();\n\n// Print a warning and die.\n// Intrumentation inserts calls to this function when building in \"fast\" mode\n// (i.e. -mllvm -msan-keep-going)\nSANITIZER_INTERFACE_ATTRIBUTE __attribute__((noreturn))\nvoid __msan_warning_noreturn();\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_maybe_warning_1(u8 s, u32 o);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_maybe_warning_2(u16 s, u32 o);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_maybe_warning_4(u32 s, u32 o);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_maybe_warning_8(u64 s, u32 o);\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_maybe_store_origin_1(u8 s, void *p, u32 o);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_maybe_store_origin_2(u16 s, void *p, u32 o);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_maybe_store_origin_4(u32 s, void *p, u32 o);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_maybe_store_origin_8(u64 s, void *p, u32 o);\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_unpoison(const void *a, uptr size);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_unpoison_string(const char *s);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_clear_and_unpoison(void *a, uptr size);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid* __msan_memcpy(void *dst, const void *src, uptr size);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid* __msan_memset(void *s, int c, uptr n);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid* __msan_memmove(void* dest, const void* src, uptr n);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_poison(const void *a, uptr size);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_poison_stack(void *a, uptr size);\n\n// Copy size bytes from src to dst and unpoison the result.\n// Useful to implement unsafe loads.\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_load_unpoisoned(void *src, uptr size, void *dst);\n\n// Returns the offset of the first (at least partially) poisoned byte,\n// or -1 if the whole range is good.\nSANITIZER_INTERFACE_ATTRIBUTE\nsptr __msan_test_shadow(const void *x, uptr size);\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_check_mem_is_initialized(const void *x, uptr size);\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_set_origin(const void *a, uptr size, u32 origin);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_set_alloca_origin(void *a, uptr size, char *descr);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_set_alloca_origin4(void *a, uptr size, char *descr, uptr pc);\nSANITIZER_INTERFACE_ATTRIBUTE\nu32 __msan_chain_origin(u32 id);\nSANITIZER_INTERFACE_ATTRIBUTE\nu32 __msan_get_origin(const void *a);\n\n// Test that this_id is a descendant of prev_id (or they are simply equal).\n// \"descendant\" here means that are part of the same chain, created with\n// __msan_chain_origin.\nSANITIZER_INTERFACE_ATTRIBUTE\nint __msan_origin_is_descendant_or_same(u32 this_id, u32 prev_id);\n\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_clear_on_return();\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_set_keep_going(int keep_going);\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __msan_set_poison_in_malloc(int do_poison);\n\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\n/* OPTIONAL */ const char* __msan_default_options();\n\n// For testing.\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_set_expect_umr(int expect_umr);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_print_shadow(const void *x, uptr size);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_dump_shadow(const void *x, uptr size);\nSANITIZER_INTERFACE_ATTRIBUTE\nint  __msan_has_dynamic_component();\n\n// For testing.\nSANITIZER_INTERFACE_ATTRIBUTE\nu32 __msan_get_umr_origin();\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_partial_poison(const void* data, void* shadow, uptr size);\n\n// Tell MSan about newly allocated memory (ex.: custom allocator).\n// Memory will be marked uninitialized, with origin at the call site.\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_allocated_memory(const void* data, uptr size);\n\n// Tell MSan about newly destroyed memory. Memory will be marked\n// uninitialized.\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_dtor_callback(const void* data, uptr size);\n\nSANITIZER_INTERFACE_ATTRIBUTE\nu16 __sanitizer_unaligned_load16(const uu16 *p);\n\nSANITIZER_INTERFACE_ATTRIBUTE\nu32 __sanitizer_unaligned_load32(const uu32 *p);\n\nSANITIZER_INTERFACE_ATTRIBUTE\nu64 __sanitizer_unaligned_load64(const uu64 *p);\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_unaligned_store16(uu16 *p, u16 x);\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_unaligned_store32(uu32 *p, u32 x);\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_unaligned_store64(uu64 *p, u64 x);\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_set_death_callback(void (*callback)(void));\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __msan_copy_shadow(void *dst, const void *src, uptr size);\n}  // extern \"C\"\n\n#endif  // MSAN_INTERFACE_INTERNAL_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_linux.cc",
    "content": "//===-- msan_linux.cc -----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n// Linux- and FreeBSD-specific code.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_FREEBSD || SANITIZER_LINUX\n\n#include \"msan.h\"\n#include \"msan_thread.h\"\n\n#include <elf.h>\n#include <link.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <signal.h>\n#include <unistd.h>\n#include <unwind.h>\n#include <execinfo.h>\n#include <sys/time.h>\n#include <sys/resource.h>\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_procmaps.h\"\n\nnamespace __msan {\n\nvoid ReportMapRange(const char *descr, uptr beg, uptr size) {\n  if (size > 0) {\n    uptr end = beg + size - 1;\n    VPrintf(1, \"%s : %p - %p\\n\", descr, beg, end);\n  }\n}\n\nstatic bool CheckMemoryRangeAvailability(uptr beg, uptr size) {\n  if (size > 0) {\n    uptr end = beg + size - 1;\n    if (!MemoryRangeIsAvailable(beg, end)) {\n      Printf(\"FATAL: Memory range %p - %p is not available.\\n\", beg, end);\n      return false;\n    }\n  }\n  return true;\n}\n\nstatic bool ProtectMemoryRange(uptr beg, uptr size, const char *name) {\n  if (size > 0) {\n    void *addr = MmapNoAccess(beg, size, name);\n    if (beg == 0 && addr) {\n      // Depending on the kernel configuration, we may not be able to protect\n      // the page at address zero.\n      uptr gap = 16 * GetPageSizeCached();\n      beg += gap;\n      size -= gap;\n      addr = MmapNoAccess(beg, size, name);\n    }\n    if ((uptr)addr != beg) {\n      uptr end = beg + size - 1;\n      Printf(\"FATAL: Cannot protect memory range %p - %p.\\n\", beg, end);\n      return false;\n    }\n  }\n  return true;\n}\n\nstatic void CheckMemoryLayoutSanity() {\n  uptr prev_end = 0;\n  for (unsigned i = 0; i < kMemoryLayoutSize; ++i) {\n    uptr start = kMemoryLayout[i].start;\n    uptr end = kMemoryLayout[i].end;\n    MappingDesc::Type type = kMemoryLayout[i].type;\n    CHECK_LT(start, end);\n    CHECK_EQ(prev_end, start);\n    CHECK(addr_is_type(start, type));\n    CHECK(addr_is_type((start + end) / 2, type));\n    CHECK(addr_is_type(end - 1, type));\n    if (type == MappingDesc::APP) {\n      uptr addr = start;\n      CHECK(MEM_IS_SHADOW(MEM_TO_SHADOW(addr)));\n      CHECK(MEM_IS_ORIGIN(MEM_TO_ORIGIN(addr)));\n      CHECK_EQ(MEM_TO_ORIGIN(addr), SHADOW_TO_ORIGIN(MEM_TO_SHADOW(addr)));\n\n      addr = (start + end) / 2;\n      CHECK(MEM_IS_SHADOW(MEM_TO_SHADOW(addr)));\n      CHECK(MEM_IS_ORIGIN(MEM_TO_ORIGIN(addr)));\n      CHECK_EQ(MEM_TO_ORIGIN(addr), SHADOW_TO_ORIGIN(MEM_TO_SHADOW(addr)));\n\n      addr = end - 1;\n      CHECK(MEM_IS_SHADOW(MEM_TO_SHADOW(addr)));\n      CHECK(MEM_IS_ORIGIN(MEM_TO_ORIGIN(addr)));\n      CHECK_EQ(MEM_TO_ORIGIN(addr), SHADOW_TO_ORIGIN(MEM_TO_SHADOW(addr)));\n    }\n    prev_end = end;\n  }\n}\n\nbool InitShadow(bool init_origins) {\n  // Let user know mapping parameters first.\n  VPrintf(1, \"__msan_init %p\\n\", &__msan_init);\n  for (unsigned i = 0; i < kMemoryLayoutSize; ++i)\n    VPrintf(1, \"%s: %zx - %zx\\n\", kMemoryLayout[i].name, kMemoryLayout[i].start,\n            kMemoryLayout[i].end - 1);\n\n  CheckMemoryLayoutSanity();\n\n  if (!MEM_IS_APP(&__msan_init)) {\n    Printf(\"FATAL: Code %p is out of application range. Non-PIE build?\\n\",\n           (uptr)&__msan_init);\n    return false;\n  }\n\n  const uptr maxVirtualAddress = GetMaxVirtualAddress();\n\n  for (unsigned i = 0; i < kMemoryLayoutSize; ++i) {\n    uptr start = kMemoryLayout[i].start;\n    uptr end = kMemoryLayout[i].end;\n    uptr size= end - start;\n    MappingDesc::Type type = kMemoryLayout[i].type;\n\n    // Check if the segment should be mapped based on platform constraints.\n    if (start >= maxVirtualAddress)\n      continue;\n\n    bool map = type == MappingDesc::SHADOW ||\n               (init_origins && type == MappingDesc::ORIGIN);\n    bool protect = type == MappingDesc::INVALID ||\n                   (!init_origins && type == MappingDesc::ORIGIN);\n    CHECK(!(map && protect));\n    if (!map && !protect)\n      CHECK(type == MappingDesc::APP);\n    if (map) {\n      if (!CheckMemoryRangeAvailability(start, size))\n        return false;\n      if ((uptr)MmapFixedNoReserve(start, size, kMemoryLayout[i].name) != start)\n        return false;\n      if (common_flags()->use_madv_dontdump)\n        DontDumpShadowMemory(start, size);\n    }\n    if (protect) {\n      if (!CheckMemoryRangeAvailability(start, size))\n        return false;\n      if (!ProtectMemoryRange(start, size, kMemoryLayout[i].name))\n        return false;\n    }\n  }\n\n  return true;\n}\n\nstatic void MsanAtExit(void) {\n  if (flags()->print_stats && (flags()->atexit || msan_report_count > 0))\n    ReportStats();\n  if (msan_report_count > 0) {\n    ReportAtExitStatistics();\n    if (common_flags()->exitcode)\n      internal__exit(common_flags()->exitcode);\n  }\n}\n\nvoid InstallAtExitHandler() {\n  atexit(MsanAtExit);\n}\n\n// ---------------------- TSD ---------------- {{{1\n\nstatic pthread_key_t tsd_key;\nstatic bool tsd_key_inited = false;\n\nvoid MsanTSDInit(void (*destructor)(void *tsd)) {\n  CHECK(!tsd_key_inited);\n  tsd_key_inited = true;\n  CHECK_EQ(0, pthread_key_create(&tsd_key, destructor));\n}\n\nstatic THREADLOCAL MsanThread* msan_current_thread;\n\nMsanThread *GetCurrentThread() {\n  return msan_current_thread;\n}\n\nvoid SetCurrentThread(MsanThread *t) {\n  // Make sure we do not reset the current MsanThread.\n  CHECK_EQ(0, msan_current_thread);\n  msan_current_thread = t;\n  // Make sure that MsanTSDDtor gets called at the end.\n  CHECK(tsd_key_inited);\n  pthread_setspecific(tsd_key, (void *)t);\n}\n\nvoid MsanTSDDtor(void *tsd) {\n  MsanThread *t = (MsanThread*)tsd;\n  if (t->destructor_iterations_ > 1) {\n    t->destructor_iterations_--;\n    CHECK_EQ(0, pthread_setspecific(tsd_key, tsd));\n    return;\n  }\n  msan_current_thread = nullptr;\n  // Make sure that signal handler can not see a stale current thread pointer.\n  atomic_signal_fence(memory_order_seq_cst);\n  MsanThread::TSDDtor(tsd);\n}\n\n} // namespace __msan\n\n#endif // SANITIZER_FREEBSD || SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_new_delete.cc",
    "content": "//===-- msan_new_delete.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n// Interceptors for operators new and delete.\n//===----------------------------------------------------------------------===//\n\n#include \"msan.h\"\n#include \"interception/interception.h\"\n\n#if MSAN_REPLACE_OPERATORS_NEW_AND_DELETE\n\n#include <stddef.h>\n\nusing namespace __msan;  // NOLINT\n\n// Fake std::nothrow_t to avoid including <new>.\nnamespace std {\n  struct nothrow_t {};\n}  // namespace std\n\n\n#define OPERATOR_NEW_BODY \\\n  GET_MALLOC_STACK_TRACE; \\\n  return MsanReallocate(&stack, 0, size, sizeof(u64), false)\n\nINTERCEPTOR_ATTRIBUTE\nvoid *operator new(size_t size) { OPERATOR_NEW_BODY; }\nINTERCEPTOR_ATTRIBUTE\nvoid *operator new[](size_t size) { OPERATOR_NEW_BODY; }\nINTERCEPTOR_ATTRIBUTE\nvoid *operator new(size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }\nINTERCEPTOR_ATTRIBUTE\nvoid *operator new[](size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }\n\n#define OPERATOR_DELETE_BODY \\\n  GET_MALLOC_STACK_TRACE; \\\n  if (ptr) MsanDeallocate(&stack, ptr)\n\nINTERCEPTOR_ATTRIBUTE\nvoid operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }\nINTERCEPTOR_ATTRIBUTE\nvoid operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }\nINTERCEPTOR_ATTRIBUTE\nvoid operator delete(void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY; }\nINTERCEPTOR_ATTRIBUTE\nvoid operator delete[](void *ptr, std::nothrow_t const&) {\n  OPERATOR_DELETE_BODY;\n}\n\n#endif // MSAN_REPLACE_OPERATORS_NEW_AND_DELETE\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_origin.h",
    "content": "//===-- msan_origin.h ----------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Origin id utils.\n//===----------------------------------------------------------------------===//\n#ifndef MSAN_ORIGIN_H\n#define MSAN_ORIGIN_H\n\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n#include \"msan_chained_origin_depot.h\"\n\nnamespace __msan {\n\n// Origin handling.\n//\n// Origin is a 32-bit identifier that is attached to any uninitialized value in\n// the program and describes, more or less exactly, how this memory came to be\n// uninitialized.\n//\n// There are 3 kinds of origin ids:\n// 1xxx xxxx xxxx xxxx   heap origin id\n// 0000 xxxx xxxx xxxx   stack origin id\n// 0zzz xxxx xxxx xxxx   chained origin id\n//\n// Heap origin id describes a heap memory allocation and contains (in the xxx\n// part) a value of StackDepot.\n//\n// Stack origin id describes a stack memory allocation and contains (in the xxx\n// part) an index into StackOriginDescr and StackOriginPC. We don't store a\n// stack trace for such origins for performance reasons.\n//\n// Chained origin id describes an event of storing an uninitialized value to\n// memory. The xxx part is a value of ChainedOriginDepot, which is a mapping of\n// (stack_id, prev_id) -> id, where\n//  * stack_id describes the event.\n//    StackDepot keeps a mapping between those and corresponding stack traces.\n//  * prev_id is another origin id that describes the earlier part of the\n//    uninitialized value history.\n// Following a chain of prev_id provides the full recorded history of an\n// uninitialized value.\n//\n// This, effectively, defines a tree (or 2 trees, see below) where nodes are\n// points in value history marked with origin ids, and edges are events that are\n// marked with stack_id.\n//\n// The \"zzz\" bits of chained origin id are used to store the length (or depth)\n// of the origin chain.\n\nclass Origin {\n public:\n  static bool isValidId(u32 id) { return id != 0 && id != (u32)-1; }\n\n  u32 raw_id() const { return raw_id_; }\n  bool isHeapOrigin() const {\n    // 1xxx xxxx xxxx xxxx\n    return raw_id_ >> kHeapShift == 0;\n  }\n  bool isStackOrigin() const {\n    // 1000 xxxx xxxx xxxx\n    return (raw_id_ >> kDepthShift) == (1 << kDepthBits);\n  }\n  bool isChainedOrigin() const {\n    // 1zzz xxxx xxxx xxxx, zzz != 000\n    return (raw_id_ >> kDepthShift) > (1 << kDepthBits);\n  }\n  u32 getChainedId() const {\n    CHECK(isChainedOrigin());\n    return raw_id_ & kChainedIdMask;\n  }\n  u32 getStackId() const {\n    CHECK(isStackOrigin());\n    return raw_id_ & kChainedIdMask;\n  }\n  u32 getHeapId() const {\n    CHECK(isHeapOrigin());\n    return raw_id_ & kHeapIdMask;\n  }\n\n  // Returns the next origin in the chain and the current stack trace.\n  Origin getNextChainedOrigin(StackTrace *stack) const {\n    CHECK(isChainedOrigin());\n    u32 prev_id;\n    u32 stack_id = ChainedOriginDepotGet(getChainedId(), &prev_id);\n    if (stack) *stack = StackDepotGet(stack_id);\n    return Origin(prev_id);\n  }\n\n  StackTrace getStackTraceForHeapOrigin() const {\n    return StackDepotGet(getHeapId());\n  }\n\n  static Origin CreateStackOrigin(u32 id) {\n    CHECK((id & kStackIdMask) == id);\n    return Origin((1 << kHeapShift) | id);\n  }\n\n  static Origin CreateHeapOrigin(StackTrace *stack) {\n    u32 stack_id = StackDepotPut(*stack);\n    CHECK(stack_id);\n    CHECK((stack_id & kHeapIdMask) == stack_id);\n    return Origin(stack_id);\n  }\n\n  static Origin CreateChainedOrigin(Origin prev, StackTrace *stack) {\n    int depth = prev.isChainedOrigin() ? prev.depth() : 0;\n    // depth is the length of the chain minus 1.\n    // origin_history_size of 0 means unlimited depth.\n    if (flags()->origin_history_size > 0) {\n      if (depth + 1 >= flags()->origin_history_size) {\n        return prev;\n      } else {\n        ++depth;\n        CHECK(depth < (1 << kDepthBits));\n      }\n    }\n\n    StackDepotHandle h = StackDepotPut_WithHandle(*stack);\n    if (!h.valid()) return prev;\n\n    if (flags()->origin_history_per_stack_limit > 0) {\n      int use_count = h.use_count();\n      if (use_count > flags()->origin_history_per_stack_limit) return prev;\n    }\n\n    u32 chained_id;\n    bool inserted = ChainedOriginDepotPut(h.id(), prev.raw_id(), &chained_id);\n    CHECK((chained_id & kChainedIdMask) == chained_id);\n\n    if (inserted && flags()->origin_history_per_stack_limit > 0)\n      h.inc_use_count_unsafe();\n\n    return Origin((1 << kHeapShift) | (depth << kDepthShift) | chained_id);\n  }\n\n  static Origin FromRawId(u32 id) {\n    return Origin(id);\n  }\n\n private:\n  static const int kDepthBits = 3;\n  static const int kDepthShift = 32 - kDepthBits - 1;\n\n  static const int kHeapShift = 31;\n  static const u32 kChainedIdMask = ((u32)-1) >> (32 - kDepthShift);\n  static const u32 kStackIdMask = ((u32)-1) >> (32 - kDepthShift);\n  static const u32 kHeapIdMask = ((u32)-1) >> (32 - kHeapShift);\n\n  u32 raw_id_;\n\n  explicit Origin(u32 raw_id) : raw_id_(raw_id) {}\n\n  int depth() const {\n    CHECK(isChainedOrigin());\n    return (raw_id_ >> kDepthShift) & ((1 << kDepthBits) - 1);\n  }\n\n public:\n  static const int kMaxDepth = (1 << kDepthBits) - 1;\n};\n\n}  // namespace __msan\n\n#endif  // MSAN_ORIGIN_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_poisoning.cc",
    "content": "//===-- msan_poisoning.cc ---------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"msan_poisoning.h\"\n\n#include \"interception/interception.h\"\n#include \"msan_origin.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n\nDECLARE_REAL(void *, memset, void *dest, int c, uptr n)\nDECLARE_REAL(void *, memcpy, void *dest, const void *src, uptr n)\nDECLARE_REAL(void *, memmove, void *dest, const void *src, uptr n)\n\nnamespace __msan {\n\nu32 GetOriginIfPoisoned(uptr addr, uptr size) {\n  unsigned char *s = (unsigned char *)MEM_TO_SHADOW(addr);\n  for (uptr i = 0; i < size; ++i)\n    if (s[i]) return *(u32 *)SHADOW_TO_ORIGIN(((uptr)s + i) & ~3UL);\n  return 0;\n}\n\nvoid SetOriginIfPoisoned(uptr addr, uptr src_shadow, uptr size,\n                         u32 src_origin) {\n  uptr dst_s = MEM_TO_SHADOW(addr);\n  uptr src_s = src_shadow;\n  uptr src_s_end = src_s + size;\n\n  for (; src_s < src_s_end; ++dst_s, ++src_s)\n    if (*(u8 *)src_s) *(u32 *)SHADOW_TO_ORIGIN(dst_s & ~3UL) = src_origin;\n}\n\nvoid CopyOrigin(const void *dst, const void *src, uptr size,\n                StackTrace *stack) {\n  if (!MEM_IS_APP(dst) || !MEM_IS_APP(src)) return;\n\n  uptr d = (uptr)dst;\n  uptr beg = d & ~3UL;\n  // Copy left unaligned origin if that memory is poisoned.\n  if (beg < d) {\n    u32 o = GetOriginIfPoisoned((uptr)src, d - beg);\n    if (o) {\n      if (__msan_get_track_origins() > 1) o = ChainOrigin(o, stack);\n      *(u32 *)MEM_TO_ORIGIN(beg) = o;\n    }\n    beg += 4;\n  }\n\n  uptr end = (d + size) & ~3UL;\n  // If both ends fall into the same 4-byte slot, we are done.\n  if (end < beg) return;\n\n  // Copy right unaligned origin if that memory is poisoned.\n  if (end < d + size) {\n    u32 o = GetOriginIfPoisoned((uptr)src + (end - d), (d + size) - end);\n    if (o) {\n      if (__msan_get_track_origins() > 1) o = ChainOrigin(o, stack);\n      *(u32 *)MEM_TO_ORIGIN(end) = o;\n    }\n  }\n\n  if (beg < end) {\n    // Align src up.\n    uptr s = ((uptr)src + 3) & ~3UL;\n    // FIXME: factor out to msan_copy_origin_aligned\n    if (__msan_get_track_origins() > 1) {\n      u32 *src = (u32 *)MEM_TO_ORIGIN(s);\n      u32 *src_s = (u32 *)MEM_TO_SHADOW(s);\n      u32 *src_end = (u32 *)MEM_TO_ORIGIN(s + (end - beg));\n      u32 *dst = (u32 *)MEM_TO_ORIGIN(beg);\n      u32 src_o = 0;\n      u32 dst_o = 0;\n      for (; src < src_end; ++src, ++src_s, ++dst) {\n        if (!*src_s) continue;\n        if (*src != src_o) {\n          src_o = *src;\n          dst_o = ChainOrigin(src_o, stack);\n        }\n        *dst = dst_o;\n      }\n    } else {\n      REAL(memcpy)((void *)MEM_TO_ORIGIN(beg), (void *)MEM_TO_ORIGIN(s),\n                   end - beg);\n    }\n  }\n}\n\nvoid MoveShadowAndOrigin(const void *dst, const void *src, uptr size,\n                         StackTrace *stack) {\n  if (!MEM_IS_APP(dst)) return;\n  if (!MEM_IS_APP(src)) return;\n  if (src == dst) return;\n  REAL(memmove)((void *)MEM_TO_SHADOW((uptr)dst),\n                (void *)MEM_TO_SHADOW((uptr)src), size);\n  if (__msan_get_track_origins()) CopyOrigin(dst, src, size, stack);\n}\n\nvoid CopyShadowAndOrigin(const void *dst, const void *src, uptr size,\n                         StackTrace *stack) {\n  if (!MEM_IS_APP(dst)) return;\n  if (!MEM_IS_APP(src)) return;\n  REAL(memcpy)((void *)MEM_TO_SHADOW((uptr)dst),\n               (void *)MEM_TO_SHADOW((uptr)src), size);\n  if (__msan_get_track_origins()) CopyOrigin(dst, src, size, stack);\n}\n\nvoid CopyMemory(void *dst, const void *src, uptr size, StackTrace *stack) {\n  REAL(memcpy)(dst, src, size);\n  CopyShadowAndOrigin(dst, src, size, stack);\n}\n\nvoid SetShadow(const void *ptr, uptr size, u8 value) {\n  uptr PageSize = GetPageSizeCached();\n  uptr shadow_beg = MEM_TO_SHADOW(ptr);\n  uptr shadow_end = shadow_beg + size;\n  if (value ||\n      shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {\n    REAL(memset)((void *)shadow_beg, value, shadow_end - shadow_beg);\n  } else {\n    uptr page_beg = RoundUpTo(shadow_beg, PageSize);\n    uptr page_end = RoundDownTo(shadow_end, PageSize);\n\n    if (page_beg >= page_end) {\n      REAL(memset)((void *)shadow_beg, 0, shadow_end - shadow_beg);\n    } else {\n      if (page_beg != shadow_beg) {\n        REAL(memset)((void *)shadow_beg, 0, page_beg - shadow_beg);\n      }\n      if (page_end != shadow_end) {\n        REAL(memset)((void *)page_end, 0, shadow_end - page_end);\n      }\n      MmapFixedNoReserve(page_beg, page_end - page_beg);\n    }\n  }\n}\n\nvoid SetOrigin(const void *dst, uptr size, u32 origin) {\n  // Origin mapping is 4 bytes per 4 bytes of application memory.\n  // Here we extend the range such that its left and right bounds are both\n  // 4 byte aligned.\n  uptr x = MEM_TO_ORIGIN((uptr)dst);\n  uptr beg = x & ~3UL;               // align down.\n  uptr end = (x + size + 3) & ~3UL;  // align up.\n  u64 origin64 = ((u64)origin << 32) | origin;\n  // This is like memset, but the value is 32-bit. We unroll by 2 to write\n  // 64 bits at once. May want to unroll further to get 128-bit stores.\n  if (beg & 7ULL) {\n    *(u32 *)beg = origin;\n    beg += 4;\n  }\n  for (uptr addr = beg; addr < (end & ~7UL); addr += 8) *(u64 *)addr = origin64;\n  if (end & 7ULL) *(u32 *)(end - 4) = origin;\n}\n\nvoid PoisonMemory(const void *dst, uptr size, StackTrace *stack) {\n  SetShadow(dst, size, (u8)-1);\n\n  if (__msan_get_track_origins()) {\n    Origin o = Origin::CreateHeapOrigin(stack);\n    SetOrigin(dst, size, o.raw_id());\n  }\n}\n\n}  // namespace __msan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_poisoning.h",
    "content": "//===-- msan_poisoning.h ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef MSAN_POISONING_H\n#define MSAN_POISONING_H\n\n#include \"msan.h\"\n\nnamespace __msan {\n\n// Return origin for the first poisoned byte in the memory range, or 0.\nu32 GetOriginIfPoisoned(uptr addr, uptr size);\n\n// Walk [addr, addr+size) app memory region, copying origin tags from the\n// corresponding positions in [src_origin, src_origin+size) where the\n// corresponding shadow in [src_shadow, src_shadow+size) is non-zero.\nvoid SetOriginIfPoisoned(uptr addr, uptr src_shadow, uptr size, u32 src_origin);\n\n// Copy origin from src (app address) to dst (app address), creating chained\n// origin ids as necessary, without overriding origin for fully initialized\n// quads.\nvoid CopyOrigin(const void *dst, const void *src, uptr size, StackTrace *stack);\n\n// memmove() shadow and origin. Dst and src are application addresses.\n// See CopyOrigin() for the origin copying logic.\nvoid MoveShadowAndOrigin(const void *dst, const void *src, uptr size,\n                         StackTrace *stack);\n\n// memcpy() shadow and origin. Dst and src are application addresses.\n// See CopyOrigin() for the origin copying logic.\nvoid CopyShadowAndOrigin(const void *dst, const void *src, uptr size,\n                         StackTrace *stack);\n\n// memcpy() app memory, and do \"the right thing\" to the corresponding shadow and\n// origin regions.\nvoid CopyMemory(void *dst, const void *src, uptr size, StackTrace *stack);\n\n// Fill shadow will value. Ptr is an application address.\nvoid SetShadow(const void *ptr, uptr size, u8 value);\n\n// Set origin for the memory region.\nvoid SetOrigin(const void *dst, uptr size, u32 origin);\n\n// Mark memory region uninitialized, with origins.\nvoid PoisonMemory(const void *dst, uptr size, StackTrace *stack);\n\n}  // namespace __msan\n\n#endif  // MSAN_POISONING_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_report.cc",
    "content": "//===-- msan_report.cc ----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n// Error reporting.\n//===----------------------------------------------------------------------===//\n\n#include \"msan.h\"\n#include \"msan_chained_origin_depot.h\"\n#include \"msan_origin.h\"\n#include \"sanitizer_common/sanitizer_allocator_internal.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_mutex.h\"\n#include \"sanitizer_common/sanitizer_report_decorator.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n#include \"sanitizer_common/sanitizer_symbolizer.h\"\n\nusing namespace __sanitizer;\n\nnamespace __msan {\n\nclass Decorator: public __sanitizer::SanitizerCommonDecorator {\n public:\n  Decorator() : SanitizerCommonDecorator() { }\n  const char *Warning()    { return Red(); }\n  const char *Origin()     { return Magenta(); }\n  const char *Name()   { return Green(); }\n  const char *End()    { return Default(); }\n};\n\nstatic void DescribeStackOrigin(const char *so, uptr pc) {\n  Decorator d;\n  char *s = internal_strdup(so);\n  char *sep = internal_strchr(s, '@');\n  CHECK(sep);\n  *sep = '\\0';\n  Printf(\"%s\", d.Origin());\n  Printf(\n      \"  %sUninitialized value was created by an allocation of '%s%s%s'\"\n      \" in the stack frame of function '%s%s%s'%s\\n\",\n      d.Origin(), d.Name(), s, d.Origin(), d.Name(), sep + 1, d.Origin(),\n      d.End());\n  InternalFree(s);\n\n  if (pc) {\n    // For some reason function address in LLVM IR is 1 less then the address\n    // of the first instruction.\n    pc = StackTrace::GetNextInstructionPc(pc);\n    StackTrace(&pc, 1).Print();\n  }\n}\n\nstatic void DescribeOrigin(u32 id) {\n  VPrintf(1, \"  raw origin id: %d\\n\", id);\n  Decorator d;\n  Origin o = Origin::FromRawId(id);\n  while (o.isChainedOrigin()) {\n    StackTrace stack;\n    o = o.getNextChainedOrigin(&stack);\n    Printf(\"  %sUninitialized value was stored to memory at%s\\n\", d.Origin(),\n        d.End());\n    stack.Print();\n  }\n  if (o.isStackOrigin()) {\n    uptr pc;\n    const char *so = GetStackOriginDescr(o.getStackId(), &pc);\n    DescribeStackOrigin(so, pc);\n  } else {\n    StackTrace stack = o.getStackTraceForHeapOrigin();\n    switch (stack.tag) {\n      case StackTrace::TAG_ALLOC:\n        Printf(\"  %sUninitialized value was created by a heap allocation%s\\n\",\n               d.Origin(), d.End());\n        break;\n      case StackTrace::TAG_DEALLOC:\n        Printf(\"  %sUninitialized value was created by a heap deallocation%s\\n\",\n               d.Origin(), d.End());\n        break;\n      case STACK_TRACE_TAG_POISON:\n        Printf(\"  %sMemory was marked as uninitialized%s\\n\", d.Origin(),\n               d.End());\n        break;\n      default:\n        Printf(\"  %sUninitialized value was created%s\\n\", d.Origin(), d.End());\n        break;\n    }\n    stack.Print();\n  }\n}\n\nvoid ReportUMR(StackTrace *stack, u32 origin) {\n  if (!__msan::flags()->report_umrs) return;\n\n  SpinMutexLock l(&CommonSanitizerReportMutex);\n\n  Decorator d;\n  Printf(\"%s\", d.Warning());\n  Report(\"WARNING: MemorySanitizer: use-of-uninitialized-value\\n\");\n  Printf(\"%s\", d.End());\n  stack->Print();\n  if (origin) {\n    DescribeOrigin(origin);\n  }\n  ReportErrorSummary(\"use-of-uninitialized-value\", stack);\n}\n\nvoid ReportExpectedUMRNotFound(StackTrace *stack) {\n  SpinMutexLock l(&CommonSanitizerReportMutex);\n\n  Printf(\"WARNING: Expected use of uninitialized value not found\\n\");\n  stack->Print();\n}\n\nvoid ReportStats() {\n  SpinMutexLock l(&CommonSanitizerReportMutex);\n\n  if (__msan_get_track_origins() > 0) {\n    StackDepotStats *stack_depot_stats = StackDepotGetStats();\n    // FIXME: we want this at normal exit, too!\n    // FIXME: but only with verbosity=1 or something\n    Printf(\"Unique heap origins: %zu\\n\", stack_depot_stats->n_uniq_ids);\n    Printf(\"Stack depot allocated bytes: %zu\\n\", stack_depot_stats->allocated);\n\n    StackDepotStats *chained_origin_depot_stats = ChainedOriginDepotGetStats();\n    Printf(\"Unique origin histories: %zu\\n\",\n           chained_origin_depot_stats->n_uniq_ids);\n    Printf(\"History depot allocated bytes: %zu\\n\",\n           chained_origin_depot_stats->allocated);\n  }\n}\n\nvoid ReportAtExitStatistics() {\n  SpinMutexLock l(&CommonSanitizerReportMutex);\n\n  if (msan_report_count > 0) {\n    Decorator d;\n    Printf(\"%s\", d.Warning());\n    Printf(\"MemorySanitizer: %d warnings reported.\\n\", msan_report_count);\n    Printf(\"%s\", d.End());\n  }\n}\n\nclass OriginSet {\n public:\n  OriginSet() : next_id_(0) {}\n  int insert(u32 o) {\n    // Scan from the end for better locality.\n    for (int i = next_id_ - 1; i >= 0; --i)\n      if (origins_[i] == o) return i;\n    if (next_id_ == kMaxSize_) return OVERFLOW;\n    int id = next_id_++;\n    origins_[id] = o;\n    return id;\n  }\n  int size() { return next_id_; }\n  u32 get(int id) { return origins_[id]; }\n  static char asChar(int id) {\n    switch (id) {\n      case MISSING:\n        return '.';\n      case OVERFLOW:\n        return '*';\n      default:\n        return 'A' + id;\n    }\n  }\n  static const int OVERFLOW = -1;\n  static const int MISSING = -2;\n\n private:\n  static const int kMaxSize_ = 'Z' - 'A' + 1;\n  u32 origins_[kMaxSize_];\n  int next_id_;\n};\n\nvoid DescribeMemoryRange(const void *x, uptr size) {\n  // Real limits.\n  uptr start = MEM_TO_SHADOW(x);\n  uptr end = start + size;\n  // Scan limits: align start down to 4; align size up to 16.\n  uptr s = start & ~3UL;\n  size = end - s;\n  size = (size + 15) & ~15UL;\n  uptr e = s + size;\n\n  // Single letter names to origin id mapping.\n  OriginSet origin_set;\n\n  uptr pos = 0;  // Offset from aligned start.\n  bool with_origins = __msan_get_track_origins();\n  // True if there is at least 1 poisoned bit in the last 4-byte group.\n  bool last_quad_poisoned;\n  int origin_ids[4];  // Single letter origin ids for the current line.\n\n  Decorator d;\n  Printf(\"%s\", d.Warning());\n  Printf(\"Shadow map of [%p, %p), %zu bytes:\\n\", start, end, end - start);\n  Printf(\"%s\", d.End());\n  while (s < e) {\n    // Line start.\n    if (pos % 16 == 0) {\n      for (int i = 0; i < 4; ++i) origin_ids[i] = -1;\n      Printf(\"%p:\", s);\n    }\n    // Group start.\n    if (pos % 4 == 0) {\n      Printf(\" \");\n      last_quad_poisoned = false;\n    }\n    // Print shadow byte.\n    if (s < start || s >= end) {\n      Printf(\"..\");\n    } else {\n      unsigned char v = *(unsigned char *)s;\n      if (v) last_quad_poisoned = true;\n#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n      Printf(\"%x%x\", v & 0xf, v >> 4);\n#else\n      Printf(\"%x%x\", v >> 4, v & 0xf);\n#endif\n    }\n    // Group end.\n    if (pos % 4 == 3 && with_origins) {\n      int id = OriginSet::MISSING;\n      if (last_quad_poisoned) {\n        u32 o = *(u32 *)SHADOW_TO_ORIGIN(s - 3);\n        id = origin_set.insert(o);\n      }\n      origin_ids[(pos % 16) / 4] = id;\n    }\n    // Line end.\n    if (pos % 16 == 15) {\n      if (with_origins) {\n        Printf(\"  |\");\n        for (int i = 0; i < 4; ++i) {\n          char c = OriginSet::asChar(origin_ids[i]);\n          Printf(\"%c\", c);\n          if (i != 3) Printf(\" \");\n        }\n        Printf(\"|\");\n      }\n      Printf(\"\\n\");\n    }\n    size--;\n    s++;\n    pos++;\n  }\n\n  Printf(\"\\n\");\n\n  for (int i = 0; i < origin_set.size(); ++i) {\n    u32 o = origin_set.get(i);\n    Printf(\"Origin %c (origin_id %x):\\n\", OriginSet::asChar(i), o);\n    DescribeOrigin(o);\n  }\n}\n\nvoid ReportUMRInsideAddressRange(const char *what, const void *start, uptr size,\n                                 uptr offset) {\n  Decorator d;\n  Printf(\"%s\", d.Warning());\n  Printf(\"%sUninitialized bytes in %s%s%s at offset %zu inside [%p, %zu)%s\\n\",\n         d.Warning(), d.Name(), what, d.Warning(), offset, start, size,\n         d.End());\n  if (__sanitizer::Verbosity())\n    DescribeMemoryRange(start, size);\n}\n\n}  // namespace __msan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_thread.cc",
    "content": "\n#include \"msan.h\"\n#include \"msan_thread.h\"\n#include \"msan_interface_internal.h\"\n\n#include \"sanitizer_common/sanitizer_tls_get_addr.h\"\n\nnamespace __msan {\n\nMsanThread *MsanThread::Create(thread_callback_t start_routine,\n                               void *arg) {\n  uptr PageSize = GetPageSizeCached();\n  uptr size = RoundUpTo(sizeof(MsanThread), PageSize);\n  MsanThread *thread = (MsanThread*)MmapOrDie(size, __func__);\n  thread->start_routine_ = start_routine;\n  thread->arg_ = arg;\n  thread->destructor_iterations_ = GetPthreadDestructorIterations();\n\n  return thread;\n}\n\nvoid MsanThread::SetThreadStackAndTls() {\n  uptr tls_size = 0;\n  uptr stack_size = 0;\n  GetThreadStackAndTls(IsMainThread(), &stack_bottom_, &stack_size,\n                       &tls_begin_, &tls_size);\n  stack_top_ = stack_bottom_ + stack_size;\n  tls_end_ = tls_begin_ + tls_size;\n\n  int local;\n  CHECK(AddrIsInStack((uptr)&local));\n}\n\nvoid MsanThread::ClearShadowForThreadStackAndTLS() {\n  __msan_unpoison((void *)stack_bottom_, stack_top_ - stack_bottom_);\n  if (tls_begin_ != tls_end_)\n    __msan_unpoison((void *)tls_begin_, tls_end_ - tls_begin_);\n  DTLS *dtls = DTLS_Get();\n  CHECK_NE(dtls, 0);\n  for (uptr i = 0; i < dtls->dtv_size; ++i)\n    __msan_unpoison((void *)(dtls->dtv[i].beg), dtls->dtv[i].size);\n}\n\nvoid MsanThread::Init() {\n  SetThreadStackAndTls();\n  CHECK(MEM_IS_APP(stack_bottom_));\n  CHECK(MEM_IS_APP(stack_top_ - 1));\n  ClearShadowForThreadStackAndTLS();\n}\n\nvoid MsanThread::TSDDtor(void *tsd) {\n  MsanThread *t = (MsanThread*)tsd;\n  t->Destroy();\n}\n\nvoid MsanThread::Destroy() {\n  malloc_storage().CommitBack();\n  // We also clear the shadow on thread destruction because\n  // some code may still be executing in later TSD destructors\n  // and we don't want it to have any poisoned stack.\n  ClearShadowForThreadStackAndTLS();\n  uptr size = RoundUpTo(sizeof(MsanThread), GetPageSizeCached());\n  UnmapOrDie(this, size);\n  DTLS_Destroy();\n}\n\nthread_return_t MsanThread::ThreadStart() {\n  Init();\n\n  if (!start_routine_) {\n    // start_routine_ == 0 if we're on the main thread or on one of the\n    // OS X libdispatch worker threads. But nobody is supposed to call\n    // ThreadStart() for the worker threads.\n    return 0;\n  }\n\n  thread_return_t res = start_routine_(arg_);\n\n  return res;\n}\n\n} // namespace __msan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/msan_thread.h",
    "content": "//===-- msan_thread.h -------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef MSAN_THREAD_H\n#define MSAN_THREAD_H\n\n#include \"msan_allocator.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n\nnamespace __msan {\n\nclass MsanThread {\n public:\n  static MsanThread *Create(thread_callback_t start_routine, void *arg);\n  static void TSDDtor(void *tsd);\n  void Destroy();\n\n  void Init();  // Should be called from the thread itself.\n  thread_return_t ThreadStart();\n\n  uptr stack_top() { return stack_top_; }\n  uptr stack_bottom() { return stack_bottom_; }\n  uptr tls_begin() { return tls_begin_; }\n  uptr tls_end() { return tls_end_; }\n  bool IsMainThread() { return start_routine_ == nullptr; }\n\n  bool AddrIsInStack(uptr addr) {\n    return addr >= stack_bottom_ && addr < stack_top_;\n  }\n\n  bool InSignalHandler() { return in_signal_handler_; }\n  void EnterSignalHandler() { in_signal_handler_++; }\n  void LeaveSignalHandler() { in_signal_handler_--; }\n\n  MsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }\n\n  int destructor_iterations_;\n\n private:\n  // NOTE: There is no MsanThread constructor. It is allocated\n  // via mmap() and *must* be valid in zero-initialized state.\n  void SetThreadStackAndTls();\n  void ClearShadowForThreadStackAndTLS();\n  thread_callback_t start_routine_;\n  void *arg_;\n  uptr stack_top_;\n  uptr stack_bottom_;\n  uptr tls_begin_;\n  uptr tls_end_;\n\n  unsigned in_signal_handler_;\n\n  MsanThreadLocalMallocStorage malloc_storage_;\n};\n\nMsanThread *GetCurrentThread();\nvoid SetCurrentThread(MsanThread *t);\n\n} // namespace __msan\n\n#endif // MSAN_THREAD_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/tests/CMakeLists.txt",
    "content": "include(CheckCXXCompilerFlag)\ninclude(CompilerRTCompile)\ninclude(CompilerRTLink)\n\ninclude_directories(..)\ninclude_directories(../..)\n\nset(MSAN_LIBCXX_CFLAGS\n  -fsanitize=memory\n  -fsanitize-memory-track-origins\n  -Wno-pedantic)\n\n# Unittest sources and build flags.\nset(MSAN_UNITTEST_SOURCES msan_test.cc msan_test_main.cc)\nset(MSAN_LOADABLE_SOURCE msan_loadable.cc)\nset(MSAN_UNITTEST_HEADERS\n  msan_test_config.h\n  ../../../include/sanitizer/msan_interface.h\n)\nset(MSAN_UNITTEST_COMMON_CFLAGS\n  -I${COMPILER_RT_LIBCXX_PATH}/include\n  ${COMPILER_RT_TEST_CFLAGS}\n  ${COMPILER_RT_GTEST_CFLAGS}\n  -I${COMPILER_RT_SOURCE_DIR}/include\n  -I${COMPILER_RT_SOURCE_DIR}/lib\n  -I${COMPILER_RT_SOURCE_DIR}/lib/msan\n  -stdlib=libc++\n  -g\n  -O2\n  -fno-exceptions\n  -fno-omit-frame-pointer\n  -mno-omit-leaf-frame-pointer\n  -Wno-deprecated-declarations\n  -Wno-unused-variable\n  -Wno-zero-length-array\n  -Wno-uninitialized\n  -Werror=sign-compare\n)\nset(MSAN_UNITTEST_INSTRUMENTED_CFLAGS\n  ${MSAN_UNITTEST_COMMON_CFLAGS}\n  -fsanitize=memory\n  -fsanitize-memory-track-origins\n  -mllvm -msan-keep-going=1\n)\nset(MSAN_UNITTEST_LINK_FLAGS\n  -fsanitize=memory\n  # FIXME: we build libcxx without cxxabi and need libstdc++ to provide it.\n  -lstdc++\n)\n\nappend_list_if(COMPILER_RT_HAS_LIBDL -ldl MSAN_UNITTEST_LINK_FLAGS)\nset(MSAN_LOADABLE_LINK_FLAGS\n  -fsanitize=memory\n  -shared\n)\n\n# Compile source for the given architecture, using compiler\n# options in ${ARGN}, and add it to the object list.\nmacro(msan_compile obj_list source arch kind)\n  get_filename_component(basename ${source} NAME)\n  set(output_obj \"${basename}.${arch}${kind}.o\")\n  get_target_flags_for_arch(${arch} TARGET_CFLAGS)\n  set(COMPILE_DEPS ${MSAN_UNITTEST_HEADERS})\n  if(NOT COMPILER_RT_STANDALONE_BUILD)\n    list(APPEND COMPILE_DEPS gtest msan)\n  endif()\n  clang_compile(${output_obj} ${source}\n                CFLAGS ${ARGN} ${TARGET_CFLAGS}\n                DEPS ${COMPILE_DEPS})\n  list(APPEND ${obj_list} ${output_obj})\nendmacro()\n\nmacro(msan_link_shared so_list so_name arch kind)\n  parse_arguments(SOURCE \"OBJECTS;LINKFLAGS;DEPS\" \"\" ${ARGN})\n  set(output_so \"${CMAKE_CURRENT_BINARY_DIR}/${so_name}.${arch}${kind}.so\")\n  get_target_flags_for_arch(${arch} TARGET_LINKFLAGS)\n  if(NOT COMPILER_RT_STANDALONE_BUILD)\n    list(APPEND SOURCE_DEPS msan)\n  endif()\n  clang_link_shared(${output_so}\n                OBJECTS ${SOURCE_OBJECTS}\n                LINKFLAGS ${TARGET_LINKFLAGS} ${SOURCE_LINKFLAGS}\n                DEPS ${SOURCE_DEPS})\n  list(APPEND ${so_list} ${output_so})\nendmacro()\n\n# Main MemorySanitizer unit tests.\nadd_custom_target(MsanUnitTests)\nset_target_properties(MsanUnitTests PROPERTIES FOLDER \"MSan unit tests\")\n\n# Adds MSan unit tests and benchmarks for architecture.\nmacro(add_msan_tests_for_arch arch kind)\n  set(LIBCXX_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/../libcxx_msan${kind})\n  add_custom_libcxx(libcxx_msan${kind} ${LIBCXX_PREFIX}\n    DEPS ${MSAN_RUNTIME_LIBRARIES}\n    CFLAGS ${MSAN_LIBCXX_CFLAGS} ${ARGN})\n  set(MSAN_LIBCXX_SO ${LIBCXX_PREFIX}/lib/libc++.so)\n\n  # Build gtest instrumented with MSan.\n  set(MSAN_INST_GTEST)\n  msan_compile(MSAN_INST_GTEST ${COMPILER_RT_GTEST_SOURCE} ${arch} \"${kind}\"\n                               ${MSAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})\n\n  # Instrumented tests.\n  set(MSAN_INST_TEST_OBJECTS)\n  foreach (SOURCE ${MSAN_UNITTEST_SOURCES})\n    msan_compile(MSAN_INST_TEST_OBJECTS ${SOURCE} ${arch} \"${kind}\"\n                 ${MSAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})\n  endforeach(SOURCE)\n\n  # Instrumented loadable module objects.\n  set(MSAN_INST_LOADABLE_OBJECTS)\n  msan_compile(MSAN_INST_LOADABLE_OBJECTS ${MSAN_LOADABLE_SOURCE} ${arch} \"${kind}\"\n               ${MSAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})\n\n  # Instrumented loadable library tests.\n  set(MSAN_LOADABLE_SO)\n  msan_link_shared(MSAN_LOADABLE_SO \"libmsan_loadable\" ${arch} \"${kind}\"\n                   OBJECTS ${MSAN_INST_LOADABLE_OBJECTS}\n                   DEPS ${MSAN_INST_LOADABLE_OBJECTS})\n\n  set(MSAN_TEST_OBJECTS ${MSAN_INST_TEST_OBJECTS} ${MSAN_INST_GTEST})\n  set(MSAN_TEST_DEPS ${MSAN_TEST_OBJECTS} libcxx_msan${kind}\n                     ${MSAN_LOADABLE_SO})\n  if(NOT COMPILER_RT_STANDALONE_BUILD)\n    list(APPEND MSAN_TEST_DEPS msan)\n  endif()\n  get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)\n  add_compiler_rt_test(MsanUnitTests \"Msan-${arch}${kind}-Test\" ${arch}\n\t  OBJECTS ${MSAN_TEST_OBJECTS} ${MSAN_LIBCXX_SO}\n\t  DEPS ${MSAN_TEST_DEPS}\n\t  LINK_FLAGS ${MSAN_UNITTEST_LINK_FLAGS}\n                     ${TARGET_LINK_FLAGS}\n                     \"-Wl,-rpath=${CMAKE_CURRENT_BINARY_DIR}\"\n                     \"-Wl,-rpath=${LIBCXX_PREFIX}/lib\")\nendmacro()\n\n# We should only build MSan unit tests if we can build instrumented libcxx.\nif(COMPILER_RT_CAN_EXECUTE_TESTS AND COMPILER_RT_HAS_LIBCXX_SOURCES)\n  foreach(arch ${MSAN_SUPPORTED_ARCH})\n    add_msan_tests_for_arch(${arch} \"\")\n    add_msan_tests_for_arch(${arch} \"-with-call\"\n                            -mllvm -msan-instrumentation-with-call-threshold=0)\n  endforeach()\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/tests/msan_loadable.cc",
    "content": "//===-- msan_loadable.cc --------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n// MemorySanitizer unit tests.\n//===----------------------------------------------------------------------===//\n\n#include \"msan/msan_interface_internal.h\"\n#include <stdlib.h>\n\nstatic void *dso_global;\n\n// No name mangling.\nextern \"C\" {\n\nvoid **get_dso_global() {\n  return &dso_global;\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/tests/msan_test.cc",
    "content": "//===-- msan_test.cc ------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n// MemorySanitizer unit tests.\n//===----------------------------------------------------------------------===//\n\n#ifndef MSAN_EXTERNAL_TEST_CONFIG\n#include \"msan_test_config.h\"\n#endif // MSAN_EXTERNAL_TEST_CONFIG\n\n#include \"sanitizer_common/tests/sanitizer_test_utils.h\"\n\n#include \"sanitizer/allocator_interface.h\"\n#include \"sanitizer/msan_interface.h\"\n\n#if defined(__FreeBSD__)\n# define _KERNEL  // To declare 'shminfo' structure.\n# include <sys/shm.h>\n# undef _KERNEL\nextern \"C\" {\n// <sys/shm.h> doesn't declare these functions in _KERNEL mode.\nvoid *shmat(int, const void *, int);\nint shmget(key_t, size_t, int);\nint shmctl(int, int, struct shmid_ds *);\nint shmdt(const void *);\n}\n#endif\n\n#include <inttypes.h>\n#include <stdlib.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <wchar.h>\n#include <math.h>\n\n#include <arpa/inet.h>\n#include <dlfcn.h>\n#include <grp.h>\n#include <unistd.h>\n#include <link.h>\n#include <limits.h>\n#include <sys/time.h>\n#include <poll.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <sys/resource.h>\n#include <sys/ioctl.h>\n#include <sys/statvfs.h>\n#include <sys/utsname.h>\n#include <sys/mman.h>\n#include <dirent.h>\n#include <pwd.h>\n#include <sys/socket.h>\n#include <netdb.h>\n#include <wordexp.h>\n#include <sys/ipc.h>\n#include <sys/shm.h>\n\n#if !defined(__FreeBSD__)\n# include <malloc.h>\n# include <sys/sysinfo.h>\n# include <sys/vfs.h>\n# include <mntent.h>\n# include <netinet/ether.h>\n#else\n# include <signal.h>\n# include <netinet/in.h>\n# include <pthread_np.h>\n# include <sys/uio.h>\n# include <sys/mount.h>\n# include <sys/sysctl.h>\n# include <net/ethernet.h>\n# define f_namelen f_namemax  // FreeBSD names this statfs field so.\n# define cpu_set_t cpuset_t\nextern \"C\" {\n// FreeBSD's <ssp/string.h> defines mempcpy() to be a macro expanding into\n// a __builtin___mempcpy_chk() call, but since Msan RTL defines it as an\n// ordinary function, we can declare it here to complete the tests.\nvoid *mempcpy(void *dest, const void *src, size_t n);\n}\n#endif\n\n#if defined(__i386__) || defined(__x86_64__)\n# include <emmintrin.h>\n# define MSAN_HAS_M128 1\n#else\n# define MSAN_HAS_M128 0\n#endif\n\n#ifdef __AVX2__\n# include <immintrin.h>\n#endif\n\n// On FreeBSD procfs is not enabled by default.\n#if defined(__FreeBSD__)\n# define FILE_TO_READ \"/bin/cat\"\n# define DIR_TO_READ \"/bin\"\n# define SUBFILE_TO_READ \"cat\"\n# define SYMLINK_TO_READ \"/usr/bin/tar\"\n# define SUPERUSER_GROUP \"wheel\"\n#else\n# define FILE_TO_READ \"/proc/self/stat\"\n# define DIR_TO_READ \"/proc/self\"\n# define SUBFILE_TO_READ \"stat\"\n# define SYMLINK_TO_READ \"/proc/self/exe\"\n# define SUPERUSER_GROUP \"root\"\n#endif\n\nconst size_t kPageSize = 4096;\nconst size_t kMaxPathLength = 4096;\n\ntypedef unsigned char      U1;\ntypedef unsigned short     U2;  // NOLINT\ntypedef unsigned int       U4;\ntypedef unsigned long long U8;  // NOLINT\ntypedef   signed char      S1;\ntypedef   signed short     S2;  // NOLINT\ntypedef   signed int       S4;\ntypedef   signed long long S8;  // NOLINT\n#define NOINLINE      __attribute__((noinline))\n#define INLINE      __attribute__((always_inline))\n\nstatic bool TrackingOrigins() {\n  S8 x;\n  __msan_set_origin(&x, sizeof(x), 0x1234);\n  U4 origin = __msan_get_origin(&x);\n  __msan_set_origin(&x, sizeof(x), 0);\n  return __msan_origin_is_descendant_or_same(origin, 0x1234);\n}\n\n#define EXPECT_ORIGIN(expected, origin) \\\n  EXPECT_TRUE(__msan_origin_is_descendant_or_same((origin), (expected)))\n\n#define EXPECT_UMR(action) \\\n    do {                        \\\n      __msan_set_expect_umr(1); \\\n      action;                   \\\n      __msan_set_expect_umr(0); \\\n    } while (0)\n\n#define EXPECT_UMR_O(action, origin)                                       \\\n  do {                                                                     \\\n    __msan_set_expect_umr(1);                                              \\\n    action;                                                                \\\n    __msan_set_expect_umr(0);                                              \\\n    if (TrackingOrigins()) EXPECT_ORIGIN(origin, __msan_get_umr_origin()); \\\n  } while (0)\n\n#define EXPECT_POISONED(x) ExpectPoisoned(x)\n\ntemplate<typename T>\nvoid ExpectPoisoned(const T& t) {\n  EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t)));\n}\n\n#define EXPECT_POISONED_O(x, origin) \\\n  ExpectPoisonedWithOrigin(x, origin)\n\ntemplate<typename T>\nvoid ExpectPoisonedWithOrigin(const T& t, unsigned origin) {\n  EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t)));\n  if (TrackingOrigins()) EXPECT_ORIGIN(origin, __msan_get_origin((void *)&t));\n}\n\n#define EXPECT_NOT_POISONED(x) EXPECT_EQ(true, TestForNotPoisoned((x)))\n\ntemplate<typename T>\nbool TestForNotPoisoned(const T& t) {\n  return __msan_test_shadow((void*)&t, sizeof(t)) == -1;\n}\n\nstatic U8 poisoned_array[100];\ntemplate<class T>\nT *GetPoisoned(int i = 0, T val = 0) {\n  T *res = (T*)&poisoned_array[i];\n  *res = val;\n  __msan_poison(&poisoned_array[i], sizeof(T));\n  return res;\n}\n\ntemplate<class T>\nT *GetPoisonedO(int i, U4 origin, T val = 0) {\n  T *res = (T*)&poisoned_array[i];\n  *res = val;\n  __msan_poison(&poisoned_array[i], sizeof(T));\n  __msan_set_origin(&poisoned_array[i], sizeof(T), origin);\n  return res;\n}\n\ntemplate<typename T>\nT Poisoned(T v = 0, T s = (T)(-1)) {\n  __msan_partial_poison(&v, &s, sizeof(T));\n  return v;\n}\n\ntemplate<class T> NOINLINE T ReturnPoisoned() { return *GetPoisoned<T>(); }\n\nstatic volatile int g_one = 1;\nstatic volatile int g_zero = 0;\nstatic volatile int g_0 = 0;\nstatic volatile int g_1 = 1;\n\nS4 a_s4[100];\nS8 a_s8[100];\n\n// Check that malloc poisons memory.\n// A lot of tests below depend on this.\nTEST(MemorySanitizerSanity, PoisonInMalloc) {\n  int *x = (int*)malloc(sizeof(int));\n  EXPECT_POISONED(*x);\n  free(x);\n}\n\nTEST(MemorySanitizer, NegativeTest1) {\n  S4 *x = GetPoisoned<S4>();\n  if (g_one)\n    *x = 0;\n  EXPECT_NOT_POISONED(*x);\n}\n\nTEST(MemorySanitizer, PositiveTest1) {\n  // Load to store.\n  EXPECT_POISONED(*GetPoisoned<S1>());\n  EXPECT_POISONED(*GetPoisoned<S2>());\n  EXPECT_POISONED(*GetPoisoned<S4>());\n  EXPECT_POISONED(*GetPoisoned<S8>());\n\n  // S->S conversions.\n  EXPECT_POISONED(*GetPoisoned<S1>());\n  EXPECT_POISONED(*GetPoisoned<S1>());\n  EXPECT_POISONED(*GetPoisoned<S1>());\n\n  EXPECT_POISONED(*GetPoisoned<S2>());\n  EXPECT_POISONED(*GetPoisoned<S2>());\n  EXPECT_POISONED(*GetPoisoned<S2>());\n\n  EXPECT_POISONED(*GetPoisoned<S4>());\n  EXPECT_POISONED(*GetPoisoned<S4>());\n  EXPECT_POISONED(*GetPoisoned<S4>());\n\n  EXPECT_POISONED(*GetPoisoned<S8>());\n  EXPECT_POISONED(*GetPoisoned<S8>());\n  EXPECT_POISONED(*GetPoisoned<S8>());\n\n  // ZExt\n  EXPECT_POISONED(*GetPoisoned<U1>());\n  EXPECT_POISONED(*GetPoisoned<U1>());\n  EXPECT_POISONED(*GetPoisoned<U1>());\n  EXPECT_POISONED(*GetPoisoned<U2>());\n  EXPECT_POISONED(*GetPoisoned<U2>());\n  EXPECT_POISONED(*GetPoisoned<U4>());\n\n  // Unary ops.\n  EXPECT_POISONED(- *GetPoisoned<S4>());\n\n  EXPECT_UMR(a_s4[g_zero] = 100 / *GetPoisoned<S4>(0, 1));\n\n\n  a_s4[g_zero] = 1 - *GetPoisoned<S4>();\n  a_s4[g_zero] = 1 + *GetPoisoned<S4>();\n}\n\nTEST(MemorySanitizer, Phi1) {\n  S4 c;\n  if (g_one) {\n    c = *GetPoisoned<S4>();\n  } else {\n    break_optimization(0);\n    c = 0;\n  }\n  EXPECT_POISONED(c);\n}\n\nTEST(MemorySanitizer, Phi2) {\n  S4 i = *GetPoisoned<S4>();\n  S4 n = g_one;\n  EXPECT_UMR(for (; i < g_one; i++););\n  EXPECT_POISONED(i);\n}\n\nNOINLINE void Arg1ExpectUMR(S4 a1) { EXPECT_POISONED(a1); }\nNOINLINE void Arg2ExpectUMR(S4 a1, S4 a2) { EXPECT_POISONED(a2); }\nNOINLINE void Arg3ExpectUMR(S1 a1, S4 a2, S8 a3) { EXPECT_POISONED(a3); }\n\nTEST(MemorySanitizer, ArgTest) {\n  Arg1ExpectUMR(*GetPoisoned<S4>());\n  Arg2ExpectUMR(0, *GetPoisoned<S4>());\n  Arg3ExpectUMR(0, 1, *GetPoisoned<S8>());\n}\n\n\nTEST(MemorySanitizer, CallAndRet) {\n  ReturnPoisoned<S1>();\n  ReturnPoisoned<S2>();\n  ReturnPoisoned<S4>();\n  ReturnPoisoned<S8>();\n\n  EXPECT_POISONED(ReturnPoisoned<S1>());\n  EXPECT_POISONED(ReturnPoisoned<S2>());\n  EXPECT_POISONED(ReturnPoisoned<S4>());\n  EXPECT_POISONED(ReturnPoisoned<S8>());\n}\n\n// malloc() in the following test may be optimized to produce a compile-time\n// undef value. Check that we trap on the volatile assignment anyway.\nTEST(MemorySanitizer, DISABLED_MallocNoIdent) {\n  S4 *x = (int*)malloc(sizeof(S4));\n  EXPECT_POISONED(*x);\n  free(x);\n}\n\nTEST(MemorySanitizer, Malloc) {\n  S4 *x = (int*)Ident(malloc(sizeof(S4)));\n  EXPECT_POISONED(*x);\n  free(x);\n}\n\nTEST(MemorySanitizer, Realloc) {\n  S4 *x = (int*)Ident(realloc(0, sizeof(S4)));\n  EXPECT_POISONED(x[0]);\n  x[0] = 1;\n  x = (int*)Ident(realloc(x, 2 * sizeof(S4)));\n  EXPECT_NOT_POISONED(x[0]);  // Ok, was inited before.\n  EXPECT_POISONED(x[1]);\n  x = (int*)Ident(realloc(x, 3 * sizeof(S4)));\n  EXPECT_NOT_POISONED(x[0]);  // Ok, was inited before.\n  EXPECT_POISONED(x[2]);\n  EXPECT_POISONED(x[1]);\n  x[2] = 1;  // Init this here. Check that after realloc it is poisoned again.\n  x = (int*)Ident(realloc(x, 2 * sizeof(S4)));\n  EXPECT_NOT_POISONED(x[0]);  // Ok, was inited before.\n  EXPECT_POISONED(x[1]);\n  x = (int*)Ident(realloc(x, 3 * sizeof(S4)));\n  EXPECT_POISONED(x[1]);\n  EXPECT_POISONED(x[2]);\n  free(x);\n}\n\nTEST(MemorySanitizer, Calloc) {\n  S4 *x = (int*)Ident(calloc(1, sizeof(S4)));\n  EXPECT_NOT_POISONED(*x);  // Should not be poisoned.\n  EXPECT_EQ(0, *x);\n  free(x);\n}\n\nTEST(MemorySanitizer, CallocReturnsZeroMem) {\n  size_t sizes[] = {16, 1000, 10000, 100000, 2100000};\n  for (size_t s = 0; s < sizeof(sizes)/sizeof(sizes[0]); s++) {\n    size_t size = sizes[s];\n    for (size_t iter = 0; iter < 5; iter++) {\n      char *x = Ident((char*)calloc(1, size));\n      EXPECT_EQ(x[0], 0);\n      EXPECT_EQ(x[size - 1], 0);\n      EXPECT_EQ(x[size / 2], 0);\n      EXPECT_EQ(x[size / 3], 0);\n      EXPECT_EQ(x[size / 4], 0);\n      memset(x, 0x42, size);\n      free(Ident(x));\n    }\n  }\n}\n\nTEST(MemorySanitizer, AndOr) {\n  U4 *p = GetPoisoned<U4>();\n  // We poison two bytes in the midle of a 4-byte word to make the test\n  // correct regardless of endianness.\n  ((U1*)p)[1] = 0;\n  ((U1*)p)[2] = 0xff;\n  EXPECT_NOT_POISONED(*p & 0x00ffff00);\n  EXPECT_NOT_POISONED(*p & 0x00ff0000);\n  EXPECT_NOT_POISONED(*p & 0x0000ff00);\n  EXPECT_POISONED(*p & 0xff000000);\n  EXPECT_POISONED(*p & 0x000000ff);\n  EXPECT_POISONED(*p & 0x0000ffff);\n  EXPECT_POISONED(*p & 0xffff0000);\n\n  EXPECT_NOT_POISONED(*p | 0xff0000ff);\n  EXPECT_NOT_POISONED(*p | 0xff00ffff);\n  EXPECT_NOT_POISONED(*p | 0xffff00ff);\n  EXPECT_POISONED(*p | 0xff000000);\n  EXPECT_POISONED(*p | 0x000000ff);\n  EXPECT_POISONED(*p | 0x0000ffff);\n  EXPECT_POISONED(*p | 0xffff0000);\n\n  EXPECT_POISONED(*GetPoisoned<bool>() & *GetPoisoned<bool>());\n}\n\ntemplate<class T>\nstatic bool applyNot(T value, T shadow) {\n  __msan_partial_poison(&value, &shadow, sizeof(T));\n  return !value;\n}\n\nTEST(MemorySanitizer, Not) {\n  EXPECT_NOT_POISONED(applyNot<U4>(0x0, 0x0));\n  EXPECT_NOT_POISONED(applyNot<U4>(0xFFFFFFFF, 0x0));\n  EXPECT_POISONED(applyNot<U4>(0xFFFFFFFF, 0xFFFFFFFF));\n  EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x0FFFFFFF));\n  EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x00FFFFFF));\n  EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x0000FFFF));\n  EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x00000000));\n  EXPECT_POISONED(applyNot<U4>(0xFF000000, 0xFF000000));\n  EXPECT_NOT_POISONED(applyNot<U4>(0xFF800000, 0xFF000000));\n  EXPECT_POISONED(applyNot<U4>(0x00008000, 0x00008000));\n\n  EXPECT_NOT_POISONED(applyNot<U1>(0x0, 0x0));\n  EXPECT_NOT_POISONED(applyNot<U1>(0xFF, 0xFE));\n  EXPECT_NOT_POISONED(applyNot<U1>(0xFF, 0x0));\n  EXPECT_POISONED(applyNot<U1>(0xFF, 0xFF));\n\n  EXPECT_POISONED(applyNot<void*>((void*)0xFFFFFF, (void*)(-1)));\n  EXPECT_NOT_POISONED(applyNot<void*>((void*)0xFFFFFF, (void*)(-2)));\n}\n\nTEST(MemorySanitizer, Shift) {\n  U4 *up = GetPoisoned<U4>();\n  ((U1*)up)[0] = 0;\n  ((U1*)up)[3] = 0xff;\n  EXPECT_NOT_POISONED(*up >> 30);\n  EXPECT_NOT_POISONED(*up >> 24);\n  EXPECT_POISONED(*up >> 23);\n  EXPECT_POISONED(*up >> 10);\n\n  EXPECT_NOT_POISONED(*up << 30);\n  EXPECT_NOT_POISONED(*up << 24);\n  EXPECT_POISONED(*up << 23);\n  EXPECT_POISONED(*up << 10);\n\n  S4 *sp = (S4*)up;\n  EXPECT_NOT_POISONED(*sp >> 30);\n  EXPECT_NOT_POISONED(*sp >> 24);\n  EXPECT_POISONED(*sp >> 23);\n  EXPECT_POISONED(*sp >> 10);\n\n  sp = GetPoisoned<S4>();\n  ((S1*)sp)[1] = 0;\n  ((S1*)sp)[2] = 0;\n  EXPECT_POISONED(*sp >> 31);\n\n  EXPECT_POISONED(100 >> *GetPoisoned<S4>());\n  EXPECT_POISONED(100U >> *GetPoisoned<S4>());\n}\n\nNOINLINE static int GetPoisonedZero() {\n  int *zero = new int;\n  *zero = 0;\n  __msan_poison(zero, sizeof(*zero));\n  int res = *zero;\n  delete zero;\n  return res;\n}\n\nTEST(MemorySanitizer, LoadFromDirtyAddress) {\n  int *a = new int;\n  *a = 0;\n  EXPECT_UMR(break_optimization((void*)(U8)a[GetPoisonedZero()]));\n  delete a;\n}\n\nTEST(MemorySanitizer, StoreToDirtyAddress) {\n  int *a = new int;\n  EXPECT_UMR(a[GetPoisonedZero()] = 0);\n  break_optimization(a);\n  delete a;\n}\n\n\nNOINLINE void StackTestFunc() {\n  S4 p4;\n  S4 ok4 = 1;\n  S2 p2;\n  S2 ok2 = 1;\n  S1 p1;\n  S1 ok1 = 1;\n  break_optimization(&p4);\n  break_optimization(&ok4);\n  break_optimization(&p2);\n  break_optimization(&ok2);\n  break_optimization(&p1);\n  break_optimization(&ok1);\n\n  EXPECT_POISONED(p4);\n  EXPECT_POISONED(p2);\n  EXPECT_POISONED(p1);\n  EXPECT_NOT_POISONED(ok1);\n  EXPECT_NOT_POISONED(ok2);\n  EXPECT_NOT_POISONED(ok4);\n}\n\nTEST(MemorySanitizer, StackTest) {\n  StackTestFunc();\n}\n\nNOINLINE void StackStressFunc() {\n  int foo[10000];\n  break_optimization(foo);\n}\n\nTEST(MemorySanitizer, DISABLED_StackStressTest) {\n  for (int i = 0; i < 1000000; i++)\n    StackStressFunc();\n}\n\ntemplate<class T>\nvoid TestFloatingPoint() {\n  static volatile T v;\n  static T g[100];\n  break_optimization(&g);\n  T *x = GetPoisoned<T>();\n  T *y = GetPoisoned<T>(1);\n  EXPECT_POISONED(*x);\n  EXPECT_POISONED((long long)*x);\n  EXPECT_POISONED((int)*x);\n  g[0] = *x;\n  g[1] = *x + *y;\n  g[2] = *x - *y;\n  g[3] = *x * *y;\n}\n\nTEST(MemorySanitizer, FloatingPointTest) {\n  TestFloatingPoint<float>();\n  TestFloatingPoint<double>();\n}\n\nTEST(MemorySanitizer, DynMem) {\n  S4 x = 0;\n  S4 *y = GetPoisoned<S4>();\n  memcpy(y, &x, g_one * sizeof(S4));\n  EXPECT_NOT_POISONED(*y);\n}\n\nstatic char *DynRetTestStr;\n\nTEST(MemorySanitizer, DynRet) {\n  ReturnPoisoned<S8>();\n  EXPECT_NOT_POISONED(atoi(\"0\"));\n}\n\nTEST(MemorySanitizer, DynRet1) {\n  ReturnPoisoned<S8>();\n}\n\nstruct LargeStruct {\n  S4 x[10];\n};\n\nNOINLINE\nLargeStruct LargeRetTest() {\n  LargeStruct res;\n  res.x[0] = *GetPoisoned<S4>();\n  res.x[1] = *GetPoisoned<S4>();\n  res.x[2] = *GetPoisoned<S4>();\n  res.x[3] = *GetPoisoned<S4>();\n  res.x[4] = *GetPoisoned<S4>();\n  res.x[5] = *GetPoisoned<S4>();\n  res.x[6] = *GetPoisoned<S4>();\n  res.x[7] = *GetPoisoned<S4>();\n  res.x[8] = *GetPoisoned<S4>();\n  res.x[9] = *GetPoisoned<S4>();\n  return res;\n}\n\nTEST(MemorySanitizer, strcmp) {\n  char s1[10];\n  char s2[10];\n  strncpy(s1, \"foo\", 10);\n  s2[0] = 'f';\n  s2[1] = 'n';\n  EXPECT_GT(strcmp(s1, s2), 0);\n  s2[1] = 'o';\n  int res;\n  EXPECT_UMR(res = strcmp(s1, s2));\n  EXPECT_NOT_POISONED(res);\n  EXPECT_EQ(strncmp(s1, s2, 1), 0);\n}\n\nTEST(MemorySanitizer, LargeRet) {\n  LargeStruct a = LargeRetTest();\n  EXPECT_POISONED(a.x[0]);\n  EXPECT_POISONED(a.x[9]);\n}\n\nTEST(MemorySanitizer, strerror) {\n  char *buf = strerror(EINVAL);\n  EXPECT_NOT_POISONED(strlen(buf));\n  buf = strerror(123456);\n  EXPECT_NOT_POISONED(strlen(buf));\n}\n\nTEST(MemorySanitizer, strerror_r) {\n  errno = 0;\n  char buf[1000];\n  char *res = (char*) (size_t) strerror_r(EINVAL, buf, sizeof(buf));\n  ASSERT_EQ(0, errno);\n  if (!res) res = buf; // POSIX version success.\n  EXPECT_NOT_POISONED(strlen(res));\n}\n\nTEST(MemorySanitizer, fread) {\n  char *x = new char[32];\n  FILE *f = fopen(FILE_TO_READ, \"r\");\n  ASSERT_TRUE(f != NULL);\n  fread(x, 1, 32, f);\n  EXPECT_NOT_POISONED(x[0]);\n  EXPECT_NOT_POISONED(x[16]);\n  EXPECT_NOT_POISONED(x[31]);\n  fclose(f);\n  delete[] x;\n}\n\nTEST(MemorySanitizer, read) {\n  char *x = new char[32];\n  int fd = open(FILE_TO_READ, O_RDONLY);\n  ASSERT_GT(fd, 0);\n  int sz = read(fd, x, 32);\n  ASSERT_EQ(sz, 32);\n  EXPECT_NOT_POISONED(x[0]);\n  EXPECT_NOT_POISONED(x[16]);\n  EXPECT_NOT_POISONED(x[31]);\n  close(fd);\n  delete[] x;\n}\n\nTEST(MemorySanitizer, pread) {\n  char *x = new char[32];\n  int fd = open(FILE_TO_READ, O_RDONLY);\n  ASSERT_GT(fd, 0);\n  int sz = pread(fd, x, 32, 0);\n  ASSERT_EQ(sz, 32);\n  EXPECT_NOT_POISONED(x[0]);\n  EXPECT_NOT_POISONED(x[16]);\n  EXPECT_NOT_POISONED(x[31]);\n  close(fd);\n  delete[] x;\n}\n\nTEST(MemorySanitizer, readv) {\n  char buf[2011];\n  struct iovec iov[2];\n  iov[0].iov_base = buf + 1;\n  iov[0].iov_len = 5;\n  iov[1].iov_base = buf + 10;\n  iov[1].iov_len = 2000;\n  int fd = open(FILE_TO_READ, O_RDONLY);\n  ASSERT_GT(fd, 0);\n  int sz = readv(fd, iov, 2);\n  ASSERT_GE(sz, 0);\n  ASSERT_LE(sz, 5 + 2000);\n  ASSERT_GT((size_t)sz, iov[0].iov_len);\n  EXPECT_POISONED(buf[0]);\n  EXPECT_NOT_POISONED(buf[1]);\n  EXPECT_NOT_POISONED(buf[5]);\n  EXPECT_POISONED(buf[6]);\n  EXPECT_POISONED(buf[9]);\n  EXPECT_NOT_POISONED(buf[10]);\n  EXPECT_NOT_POISONED(buf[10 + (sz - 1) - 5]);\n  EXPECT_POISONED(buf[11 + (sz - 1) - 5]);\n  close(fd);\n}\n\nTEST(MemorySanitizer, preadv) {\n  char buf[2011];\n  struct iovec iov[2];\n  iov[0].iov_base = buf + 1;\n  iov[0].iov_len = 5;\n  iov[1].iov_base = buf + 10;\n  iov[1].iov_len = 2000;\n  int fd = open(FILE_TO_READ, O_RDONLY);\n  ASSERT_GT(fd, 0);\n  int sz = preadv(fd, iov, 2, 3);\n  ASSERT_GE(sz, 0);\n  ASSERT_LE(sz, 5 + 2000);\n  ASSERT_GT((size_t)sz, iov[0].iov_len);\n  EXPECT_POISONED(buf[0]);\n  EXPECT_NOT_POISONED(buf[1]);\n  EXPECT_NOT_POISONED(buf[5]);\n  EXPECT_POISONED(buf[6]);\n  EXPECT_POISONED(buf[9]);\n  EXPECT_NOT_POISONED(buf[10]);\n  EXPECT_NOT_POISONED(buf[10 + (sz - 1) - 5]);\n  EXPECT_POISONED(buf[11 + (sz - 1) - 5]);\n  close(fd);\n}\n\n// FIXME: fails now.\nTEST(MemorySanitizer, DISABLED_ioctl) {\n  struct winsize ws;\n  EXPECT_EQ(ioctl(2, TIOCGWINSZ, &ws), 0);\n  EXPECT_NOT_POISONED(ws.ws_col);\n}\n\nTEST(MemorySanitizer, readlink) {\n  char *x = new char[1000];\n  readlink(SYMLINK_TO_READ, x, 1000);\n  EXPECT_NOT_POISONED(x[0]);\n  delete [] x;\n}\n\nTEST(MemorySanitizer, stat) {\n  struct stat* st = new struct stat;\n  int res = stat(FILE_TO_READ, st);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(st->st_dev);\n  EXPECT_NOT_POISONED(st->st_mode);\n  EXPECT_NOT_POISONED(st->st_size);\n}\n\nTEST(MemorySanitizer, fstatat) {\n  struct stat* st = new struct stat;\n  int dirfd = open(DIR_TO_READ, O_RDONLY);\n  ASSERT_GT(dirfd, 0);\n  int res = fstatat(dirfd, SUBFILE_TO_READ, st, 0);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(st->st_dev);\n  EXPECT_NOT_POISONED(st->st_mode);\n  EXPECT_NOT_POISONED(st->st_size);\n  close(dirfd);\n}\n\nTEST(MemorySanitizer, statfs) {\n  struct statfs st;\n  int res = statfs(\"/\", &st);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(st.f_type);\n  EXPECT_NOT_POISONED(st.f_bfree);\n  EXPECT_NOT_POISONED(st.f_namelen);\n}\n\nTEST(MemorySanitizer, statvfs) {\n  struct statvfs st;\n  int res = statvfs(\"/\", &st);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(st.f_bsize);\n  EXPECT_NOT_POISONED(st.f_blocks);\n  EXPECT_NOT_POISONED(st.f_bfree);\n  EXPECT_NOT_POISONED(st.f_namemax);\n}\n\nTEST(MemorySanitizer, fstatvfs) {\n  struct statvfs st;\n  int fd = open(\"/\", O_RDONLY | O_DIRECTORY);\n  int res = fstatvfs(fd, &st);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(st.f_bsize);\n  EXPECT_NOT_POISONED(st.f_blocks);\n  EXPECT_NOT_POISONED(st.f_bfree);\n  EXPECT_NOT_POISONED(st.f_namemax);\n  close(fd);\n}\n\nTEST(MemorySanitizer, pipe) {\n  int* pipefd = new int[2];\n  int res = pipe(pipefd);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(pipefd[0]);\n  EXPECT_NOT_POISONED(pipefd[1]);\n  close(pipefd[0]);\n  close(pipefd[1]);\n}\n\nTEST(MemorySanitizer, pipe2) {\n  int* pipefd = new int[2];\n  int res = pipe2(pipefd, O_NONBLOCK);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(pipefd[0]);\n  EXPECT_NOT_POISONED(pipefd[1]);\n  close(pipefd[0]);\n  close(pipefd[1]);\n}\n\nTEST(MemorySanitizer, socketpair) {\n  int sv[2];\n  int res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(sv[0]);\n  EXPECT_NOT_POISONED(sv[1]);\n  close(sv[0]);\n  close(sv[1]);\n}\n\nTEST(MemorySanitizer, poll) {\n  int* pipefd = new int[2];\n  int res = pipe(pipefd);\n  ASSERT_EQ(0, res);\n\n  char data = 42;\n  res = write(pipefd[1], &data, 1);\n  ASSERT_EQ(1, res);\n\n  pollfd fds[2];\n  fds[0].fd = pipefd[0];\n  fds[0].events = POLLIN;\n  fds[1].fd = pipefd[1];\n  fds[1].events = POLLIN;\n  res = poll(fds, 2, 500);\n  ASSERT_EQ(1, res);\n  EXPECT_NOT_POISONED(fds[0].revents);\n  EXPECT_NOT_POISONED(fds[1].revents);\n\n  close(pipefd[0]);\n  close(pipefd[1]);\n}\n\n// There is no ppoll() on FreeBSD.\n#if !defined (__FreeBSD__)\nTEST(MemorySanitizer, ppoll) {\n  int* pipefd = new int[2];\n  int res = pipe(pipefd);\n  ASSERT_EQ(0, res);\n\n  char data = 42;\n  res = write(pipefd[1], &data, 1);\n  ASSERT_EQ(1, res);\n\n  pollfd fds[2];\n  fds[0].fd = pipefd[0];\n  fds[0].events = POLLIN;\n  fds[1].fd = pipefd[1];\n  fds[1].events = POLLIN;\n  sigset_t ss;\n  sigemptyset(&ss);\n  res = ppoll(fds, 2, NULL, &ss);\n  ASSERT_EQ(1, res);\n  EXPECT_NOT_POISONED(fds[0].revents);\n  EXPECT_NOT_POISONED(fds[1].revents);\n\n  close(pipefd[0]);\n  close(pipefd[1]);\n}\n#endif\n\nTEST(MemorySanitizer, poll_positive) {\n  int* pipefd = new int[2];\n  int res = pipe(pipefd);\n  ASSERT_EQ(0, res);\n\n  pollfd fds[2];\n  fds[0].fd = pipefd[0];\n  fds[0].events = POLLIN;\n  // fds[1].fd uninitialized\n  fds[1].events = POLLIN;\n  EXPECT_UMR(poll(fds, 2, 0));\n\n  close(pipefd[0]);\n  close(pipefd[1]);\n}\n\nTEST(MemorySanitizer, bind_getsockname) {\n  int sock = socket(AF_UNIX, SOCK_STREAM, 0);\n\n  struct sockaddr_in sai;\n  memset(&sai, 0, sizeof(sai));\n  sai.sin_family = AF_UNIX;\n  int res = bind(sock, (struct sockaddr *)&sai, sizeof(sai));\n\n  ASSERT_EQ(0, res);\n  char buf[200];\n  socklen_t addrlen;\n  EXPECT_UMR(getsockname(sock, (struct sockaddr *)&buf, &addrlen));\n\n  addrlen = sizeof(buf);\n  res = getsockname(sock, (struct sockaddr *)&buf, &addrlen);\n  EXPECT_NOT_POISONED(addrlen);\n  EXPECT_NOT_POISONED(buf[0]);\n  EXPECT_NOT_POISONED(buf[addrlen - 1]);\n  EXPECT_POISONED(buf[addrlen]);\n  close(sock);\n}\n\nTEST(MemorySanitizer, accept) {\n  int listen_socket = socket(AF_INET, SOCK_STREAM, 0);\n  ASSERT_LT(0, listen_socket);\n\n  struct sockaddr_in sai;\n  memset(&sai, 0, sizeof(sai));\n  sai.sin_family = AF_INET;\n  sai.sin_port = 0;\n  sai.sin_addr.s_addr = htonl(INADDR_LOOPBACK);\n  int res = bind(listen_socket, (struct sockaddr *)&sai, sizeof(sai));\n  ASSERT_EQ(0, res);\n\n  res = listen(listen_socket, 1);\n  ASSERT_EQ(0, res);\n\n  socklen_t sz = sizeof(sai);\n  res = getsockname(listen_socket, (struct sockaddr *)&sai, &sz);\n  ASSERT_EQ(0, res);\n  ASSERT_EQ(sizeof(sai), sz);\n\n  int connect_socket = socket(AF_INET, SOCK_STREAM, 0);\n  ASSERT_LT(0, connect_socket);\n  res = fcntl(connect_socket, F_SETFL, O_NONBLOCK);\n  ASSERT_EQ(0, res);\n  res = connect(connect_socket, (struct sockaddr *)&sai, sizeof(sai));\n  // On FreeBSD this connection completes immediately.\n  if (res != 0) {\n    ASSERT_EQ(-1, res);\n    ASSERT_EQ(EINPROGRESS, errno);\n  }\n\n  __msan_poison(&sai, sizeof(sai));\n  int new_sock = accept(listen_socket, (struct sockaddr *)&sai, &sz);\n  ASSERT_LT(0, new_sock);\n  ASSERT_EQ(sizeof(sai), sz);\n  EXPECT_NOT_POISONED(sai);\n\n  __msan_poison(&sai, sizeof(sai));\n  res = getpeername(new_sock, (struct sockaddr *)&sai, &sz);\n  ASSERT_EQ(0, res);\n  ASSERT_EQ(sizeof(sai), sz);\n  EXPECT_NOT_POISONED(sai);\n\n  close(new_sock);\n  close(connect_socket);\n  close(listen_socket);\n}\n\nTEST(MemorySanitizer, getaddrinfo) {\n  struct addrinfo *ai;\n  struct addrinfo hints;\n  memset(&hints, 0, sizeof(hints));\n  hints.ai_family = AF_INET;\n  int res = getaddrinfo(\"localhost\", NULL, &hints, &ai);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(*ai);\n  ASSERT_EQ(sizeof(sockaddr_in), ai->ai_addrlen);\n  EXPECT_NOT_POISONED(*(sockaddr_in*)ai->ai_addr); \n}\n\nTEST(MemorySanitizer, getnameinfo) {\n  struct sockaddr_in sai;\n  memset(&sai, 0, sizeof(sai));\n  sai.sin_family = AF_INET;\n  sai.sin_port = 80;\n  sai.sin_addr.s_addr = htonl(INADDR_LOOPBACK);\n  char host[500];\n  char serv[500];\n  int res = getnameinfo((struct sockaddr *)&sai, sizeof(sai), host,\n                        sizeof(host), serv, sizeof(serv), 0);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(host[0]);\n  EXPECT_POISONED(host[sizeof(host) - 1]);\n\n  ASSERT_NE(0U, strlen(host));\n  EXPECT_NOT_POISONED(serv[0]);\n  EXPECT_POISONED(serv[sizeof(serv) - 1]);\n  ASSERT_NE(0U, strlen(serv));\n}\n\n#define EXPECT_HOSTENT_NOT_POISONED(he)        \\\n  do {                                         \\\n    EXPECT_NOT_POISONED(*(he));                \\\n    ASSERT_NE((void *) 0, (he)->h_name);       \\\n    ASSERT_NE((void *) 0, (he)->h_aliases);    \\\n    ASSERT_NE((void *) 0, (he)->h_addr_list);  \\\n    EXPECT_NOT_POISONED(strlen((he)->h_name)); \\\n    char **p = (he)->h_aliases;                \\\n    while (*p) {                               \\\n      EXPECT_NOT_POISONED(strlen(*p));         \\\n      ++p;                                     \\\n    }                                          \\\n    char **q = (he)->h_addr_list;              \\\n    while (*q) {                               \\\n      EXPECT_NOT_POISONED(*q[0]);              \\\n      ++q;                                     \\\n    }                                          \\\n    EXPECT_NOT_POISONED(*q);                   \\\n  } while (0)\n\nTEST(MemorySanitizer, gethostent) {\n  struct hostent *he = gethostent();\n  ASSERT_NE((void *)NULL, he);\n  EXPECT_HOSTENT_NOT_POISONED(he);\n}\n\n#ifndef MSAN_TEST_DISABLE_GETHOSTBYNAME\n\nTEST(MemorySanitizer, gethostbyname) {\n  struct hostent *he = gethostbyname(\"localhost\");\n  ASSERT_NE((void *)NULL, he);\n  EXPECT_HOSTENT_NOT_POISONED(he);\n}\n\n#endif // MSAN_TEST_DISABLE_GETHOSTBYNAME\n\nTEST(MemorySanitizer, recvmsg) {\n  int server_socket = socket(AF_INET, SOCK_DGRAM, 0);\n  ASSERT_LT(0, server_socket);\n\n  struct sockaddr_in sai;\n  memset(&sai, 0, sizeof(sai));\n  sai.sin_family = AF_INET;\n  sai.sin_port = 0;\n  sai.sin_addr.s_addr = htonl(INADDR_LOOPBACK);\n  int res = bind(server_socket, (struct sockaddr *)&sai, sizeof(sai));\n  ASSERT_EQ(0, res);\n\n  socklen_t sz = sizeof(sai);\n  res = getsockname(server_socket, (struct sockaddr *)&sai, &sz);\n  ASSERT_EQ(0, res);\n  ASSERT_EQ(sizeof(sai), sz);\n\n\n  int client_socket = socket(AF_INET, SOCK_DGRAM, 0);\n  ASSERT_LT(0, client_socket);\n\n  struct sockaddr_in client_sai;\n  memset(&client_sai, 0, sizeof(client_sai));\n  client_sai.sin_family = AF_INET;\n  client_sai.sin_port = 0;\n  client_sai.sin_addr.s_addr = htonl(INADDR_LOOPBACK);\n  res = bind(client_socket, (struct sockaddr *)&client_sai, sizeof(client_sai));\n  ASSERT_EQ(0, res);\n\n  sz = sizeof(client_sai);\n  res = getsockname(client_socket, (struct sockaddr *)&client_sai, &sz);\n  ASSERT_EQ(0, res);\n  ASSERT_EQ(sizeof(client_sai), sz);\n\n  const char *s = \"message text\";\n  struct iovec iov;\n  iov.iov_base = (void *)s;\n  iov.iov_len = strlen(s) + 1;\n  struct msghdr msg;\n  memset(&msg, 0, sizeof(msg));\n  msg.msg_name = &sai;\n  msg.msg_namelen = sizeof(sai);\n  msg.msg_iov = &iov;\n  msg.msg_iovlen = 1;\n  res = sendmsg(client_socket, &msg, 0);\n  ASSERT_LT(0, res);\n\n\n  char buf[1000];\n  struct iovec recv_iov;\n  recv_iov.iov_base = (void *)&buf;\n  recv_iov.iov_len = sizeof(buf);\n  struct sockaddr_in recv_sai;\n  struct msghdr recv_msg;\n  memset(&recv_msg, 0, sizeof(recv_msg));\n  recv_msg.msg_name = &recv_sai;\n  recv_msg.msg_namelen = sizeof(recv_sai);\n  recv_msg.msg_iov = &recv_iov;\n  recv_msg.msg_iovlen = 1;\n  res = recvmsg(server_socket, &recv_msg, 0);\n  ASSERT_LT(0, res);\n\n  ASSERT_EQ(sizeof(recv_sai), recv_msg.msg_namelen);\n  EXPECT_NOT_POISONED(*(struct sockaddr_in *)recv_msg.msg_name);\n  EXPECT_STREQ(s, buf);\n\n  close(server_socket);\n  close(client_socket);\n}\n\nTEST(MemorySanitizer, gethostbyname2) {\n  struct hostent *he = gethostbyname2(\"localhost\", AF_INET);\n  ASSERT_NE((void *)NULL, he);\n  EXPECT_HOSTENT_NOT_POISONED(he);\n}\n\nTEST(MemorySanitizer, gethostbyaddr) {\n  in_addr_t addr = inet_addr(\"127.0.0.1\");\n  EXPECT_NOT_POISONED(addr);\n  struct hostent *he = gethostbyaddr(&addr, sizeof(addr), AF_INET);\n  ASSERT_NE((void *)NULL, he);\n  EXPECT_HOSTENT_NOT_POISONED(he);\n}\n\nTEST(MemorySanitizer, gethostent_r) {\n  char buf[2000];\n  struct hostent he;\n  struct hostent *result;\n  int err;\n  int res = gethostent_r(&he, buf, sizeof(buf), &result, &err);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(result);\n  ASSERT_NE((void *)NULL, result);\n  EXPECT_HOSTENT_NOT_POISONED(result);\n  EXPECT_NOT_POISONED(err);\n}\n\nTEST(MemorySanitizer, gethostbyname_r) {\n  char buf[2000];\n  struct hostent he;\n  struct hostent *result;\n  int err;\n  int res = gethostbyname_r(\"localhost\", &he, buf, sizeof(buf), &result, &err);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(result);\n  ASSERT_NE((void *)NULL, result);\n  EXPECT_HOSTENT_NOT_POISONED(result);\n  EXPECT_NOT_POISONED(err);\n}\n\nTEST(MemorySanitizer, gethostbyname_r_bad_host_name) {\n  char buf[2000];\n  struct hostent he;\n  struct hostent *result;\n  int err;\n  int res = gethostbyname_r(\"bad-host-name\", &he, buf, sizeof(buf), &result, &err);\n  ASSERT_EQ((struct hostent *)0, result);\n  EXPECT_NOT_POISONED(err);\n}\n\nTEST(MemorySanitizer, gethostbyname_r_erange) {\n  char buf[5];\n  struct hostent he;\n  struct hostent *result;\n  int err;\n  int res = gethostbyname_r(\"localhost\", &he, buf, sizeof(buf), &result, &err);\n  ASSERT_EQ(ERANGE, res);\n  EXPECT_NOT_POISONED(err);\n}\n\nTEST(MemorySanitizer, gethostbyname2_r) {\n  char buf[2000];\n  struct hostent he;\n  struct hostent *result;\n  int err;\n  int res = gethostbyname2_r(\"localhost\", AF_INET, &he, buf, sizeof(buf),\n                             &result, &err);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(result);\n  ASSERT_NE((void *)NULL, result);\n  EXPECT_HOSTENT_NOT_POISONED(result);\n  EXPECT_NOT_POISONED(err);\n}\n\nTEST(MemorySanitizer, gethostbyaddr_r) {\n  char buf[2000];\n  struct hostent he;\n  struct hostent *result;\n  int err;\n  in_addr_t addr = inet_addr(\"127.0.0.1\");\n  EXPECT_NOT_POISONED(addr);\n  int res = gethostbyaddr_r(&addr, sizeof(addr), AF_INET, &he, buf, sizeof(buf),\n                            &result, &err);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(result);\n  ASSERT_NE((void *)NULL, result);\n  EXPECT_HOSTENT_NOT_POISONED(result);\n  EXPECT_NOT_POISONED(err);\n}\n\nTEST(MemorySanitizer, getsockopt) {\n  int sock = socket(AF_UNIX, SOCK_STREAM, 0);\n  struct linger l[2];\n  socklen_t sz = sizeof(l[0]);\n  int res = getsockopt(sock, SOL_SOCKET, SO_LINGER, &l[0], &sz);\n  ASSERT_EQ(0, res);\n  ASSERT_EQ(sizeof(l[0]), sz);\n  EXPECT_NOT_POISONED(l[0]);\n  EXPECT_POISONED(*(char *)(l + 1));\n}\n\nTEST(MemorySanitizer, getcwd) {\n  char path[PATH_MAX + 1];\n  char* res = getcwd(path, sizeof(path));\n  ASSERT_TRUE(res != NULL);\n  EXPECT_NOT_POISONED(path[0]);\n}\n\nTEST(MemorySanitizer, getcwd_gnu) {\n  char* res = getcwd(NULL, 0);\n  ASSERT_TRUE(res != NULL);\n  EXPECT_NOT_POISONED(res[0]);\n  free(res);\n}\n\n// There's no get_current_dir_name() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, get_current_dir_name) {\n  char* res = get_current_dir_name();\n  ASSERT_TRUE(res != NULL);\n  EXPECT_NOT_POISONED(res[0]);\n  free(res);\n}\n#endif\n\nTEST(MemorySanitizer, shmctl) {\n  int id = shmget(IPC_PRIVATE, 4096, 0644 | IPC_CREAT);\n  ASSERT_GT(id, -1);\n\n  struct shmid_ds ds;\n  int res = shmctl(id, IPC_STAT, &ds);\n  ASSERT_GT(res, -1);\n  EXPECT_NOT_POISONED(ds);\n\n  // FreeBSD does not support shmctl(IPC_INFO) and shmctl(SHM_INFO).\n#if !defined(__FreeBSD__)\n  struct shminfo si;\n  res = shmctl(id, IPC_INFO, (struct shmid_ds *)&si);\n  ASSERT_GT(res, -1);\n  EXPECT_NOT_POISONED(si);\n\n  struct shm_info s_i;\n  res = shmctl(id, SHM_INFO, (struct shmid_ds *)&s_i);\n  ASSERT_GT(res, -1);\n  EXPECT_NOT_POISONED(s_i);\n#endif\n\n  res = shmctl(id, IPC_RMID, 0);\n  ASSERT_GT(res, -1);\n}\n\nTEST(MemorySanitizer, shmat) {\n  void *p = mmap(NULL, 4096, PROT_READ | PROT_WRITE,\n                 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);\n  ASSERT_NE(MAP_FAILED, p);\n\n  ((char *)p)[10] = *GetPoisoned<U1>();\n  ((char *)p)[4095] = *GetPoisoned<U1>();\n\n  int res = munmap(p, 4096);\n  ASSERT_EQ(0, res);\n\n  int id = shmget(IPC_PRIVATE, 4096, 0644 | IPC_CREAT);\n  ASSERT_GT(id, -1);\n\n  void *q = shmat(id, p, 0);\n  ASSERT_EQ(p, q);\n\n  EXPECT_NOT_POISONED(((char *)q)[0]);\n  EXPECT_NOT_POISONED(((char *)q)[10]);\n  EXPECT_NOT_POISONED(((char *)q)[4095]);\n\n  res = shmdt(q);\n  ASSERT_EQ(0, res);\n\n  res = shmctl(id, IPC_RMID, 0);\n  ASSERT_GT(res, -1);\n}\n\n// There's no random_r() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, random_r) {\n  int32_t x;\n  char z[64];\n  memset(z, 0, sizeof(z));\n\n  struct random_data buf;\n  memset(&buf, 0, sizeof(buf));\n\n  int res = initstate_r(0, z, sizeof(z), &buf);\n  ASSERT_EQ(0, res);\n\n  res = random_r(&buf, &x);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(x);\n}\n#endif\n\nTEST(MemorySanitizer, confstr) {\n  char buf[3];\n  size_t res = confstr(_CS_PATH, buf, sizeof(buf));\n  ASSERT_GT(res, sizeof(buf));\n  EXPECT_NOT_POISONED(buf[0]);\n  EXPECT_NOT_POISONED(buf[sizeof(buf) - 1]);\n\n  char buf2[1000];\n  res = confstr(_CS_PATH, buf2, sizeof(buf2));\n  ASSERT_LT(res, sizeof(buf2));\n  EXPECT_NOT_POISONED(buf2[0]);\n  EXPECT_NOT_POISONED(buf2[res - 1]);\n  EXPECT_POISONED(buf2[res]);\n  ASSERT_EQ(res, strlen(buf2) + 1);\n}\n\nTEST(MemorySanitizer, opendir) {\n  DIR *dir = opendir(\".\");\n  closedir(dir);\n\n  char name[10] = \".\";\n  __msan_poison(name, sizeof(name));\n  EXPECT_UMR(dir = opendir(name));\n  closedir(dir);\n}\n\nTEST(MemorySanitizer, readdir) {\n  DIR *dir = opendir(\".\");\n  struct dirent *d = readdir(dir);\n  ASSERT_TRUE(d != NULL);\n  EXPECT_NOT_POISONED(d->d_name[0]);\n  closedir(dir);\n}\n\nTEST(MemorySanitizer, readdir_r) {\n  DIR *dir = opendir(\".\");\n  struct dirent d;\n  struct dirent *pd;\n  int res = readdir_r(dir, &d, &pd);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(pd);\n  EXPECT_NOT_POISONED(d.d_name[0]);\n  closedir(dir);\n}\n\nTEST(MemorySanitizer, realpath) {\n  const char* relpath = \".\";\n  char path[PATH_MAX + 1];\n  char* res = realpath(relpath, path);\n  ASSERT_TRUE(res != NULL);\n  EXPECT_NOT_POISONED(path[0]);\n}\n\nTEST(MemorySanitizer, realpath_null) {\n  const char* relpath = \".\";\n  char* res = realpath(relpath, NULL);\n  printf(\"%d, %s\\n\", errno, strerror(errno));\n  ASSERT_TRUE(res != NULL);\n  EXPECT_NOT_POISONED(res[0]);\n  free(res);\n}\n\n// There's no canonicalize_file_name() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, canonicalize_file_name) {\n  const char* relpath = \".\";\n  char* res = canonicalize_file_name(relpath);\n  ASSERT_TRUE(res != NULL);\n  EXPECT_NOT_POISONED(res[0]);\n  free(res);\n}\n#endif\n\nextern char **environ;\n\nTEST(MemorySanitizer, setenv) {\n  setenv(\"AAA\", \"BBB\", 1);\n  for (char **envp = environ; *envp; ++envp) {\n    EXPECT_NOT_POISONED(*envp);\n    EXPECT_NOT_POISONED(*envp[0]);\n  }\n}\n\nTEST(MemorySanitizer, putenv) {\n  char s[] = \"AAA=BBB\";\n  putenv(s);\n  for (char **envp = environ; *envp; ++envp) {\n    EXPECT_NOT_POISONED(*envp);\n    EXPECT_NOT_POISONED(*envp[0]);\n  }\n}\n\nTEST(MemorySanitizer, memcpy) {\n  char* x = new char[2];\n  char* y = new char[2];\n  x[0] = 1;\n  x[1] = *GetPoisoned<char>();\n  memcpy(y, x, 2);\n  EXPECT_NOT_POISONED(y[0]);\n  EXPECT_POISONED(y[1]);\n}\n\nvoid TestUnalignedMemcpy(unsigned left, unsigned right, bool src_is_aligned,\n                         bool src_is_poisoned, bool dst_is_poisoned) {\n  fprintf(stderr, \"%s(%d, %d, %d, %d, %d)\\n\", __func__, left, right,\n          src_is_aligned, src_is_poisoned, dst_is_poisoned);\n\n  const unsigned sz = 20;\n  U4 dst_origin, src_origin;\n  char *dst = (char *)malloc(sz);\n  if (dst_is_poisoned)\n    dst_origin = __msan_get_origin(dst);\n  else\n    memset(dst, 0, sz);\n\n  char *src = (char *)malloc(sz);\n  if (src_is_poisoned)\n    src_origin = __msan_get_origin(src);\n  else\n    memset(src, 0, sz);\n\n  memcpy(dst + left, src_is_aligned ? src + left : src, sz - left - right);\n\n  for (unsigned i = 0; i < (left & (~3U)); ++i)\n    if (dst_is_poisoned)\n      EXPECT_POISONED_O(dst[i], dst_origin);\n    else\n      EXPECT_NOT_POISONED(dst[i]);\n\n  for (unsigned i = 0; i < (right & (~3U)); ++i)\n    if (dst_is_poisoned)\n      EXPECT_POISONED_O(dst[sz - i - 1], dst_origin);\n    else\n      EXPECT_NOT_POISONED(dst[sz - i - 1]);\n\n  for (unsigned i = left; i < sz - right; ++i)\n    if (src_is_poisoned)\n      EXPECT_POISONED_O(dst[i], src_origin);\n    else\n      EXPECT_NOT_POISONED(dst[i]);\n\n  free(dst);\n  free(src);\n}\n\nTEST(MemorySanitizer, memcpy_unaligned) {\n  for (int i = 0; i < 10; ++i)\n    for (int j = 0; j < 10; ++j)\n      for (int aligned = 0; aligned < 2; ++aligned)\n        for (int srcp = 0; srcp < 2; ++srcp)\n          for (int dstp = 0; dstp < 2; ++dstp)\n            TestUnalignedMemcpy(i, j, aligned, srcp, dstp);\n}\n\nTEST(MemorySanitizer, memmove) {\n  char* x = new char[2];\n  char* y = new char[2];\n  x[0] = 1;\n  x[1] = *GetPoisoned<char>();\n  memmove(y, x, 2);\n  EXPECT_NOT_POISONED(y[0]);\n  EXPECT_POISONED(y[1]);\n}\n\nTEST(MemorySanitizer, memccpy_nomatch) {\n  char* x = new char[5];\n  char* y = new char[5];\n  strcpy(x, \"abc\");\n  memccpy(y, x, 'd', 4);\n  EXPECT_NOT_POISONED(y[0]);\n  EXPECT_NOT_POISONED(y[1]);\n  EXPECT_NOT_POISONED(y[2]);\n  EXPECT_NOT_POISONED(y[3]);\n  EXPECT_POISONED(y[4]);\n  delete[] x;\n  delete[] y;\n}\n\nTEST(MemorySanitizer, memccpy_match) {\n  char* x = new char[5];\n  char* y = new char[5];\n  strcpy(x, \"abc\");\n  memccpy(y, x, 'b', 4);\n  EXPECT_NOT_POISONED(y[0]);\n  EXPECT_NOT_POISONED(y[1]);\n  EXPECT_POISONED(y[2]);\n  EXPECT_POISONED(y[3]);\n  EXPECT_POISONED(y[4]);\n  delete[] x;\n  delete[] y;\n}\n\nTEST(MemorySanitizer, memccpy_nomatch_positive) {\n  char* x = new char[5];\n  char* y = new char[5];\n  strcpy(x, \"abc\");\n  EXPECT_UMR(memccpy(y, x, 'd', 5));\n  delete[] x;\n  delete[] y;\n}\n\nTEST(MemorySanitizer, memccpy_match_positive) {\n  char* x = new char[5];\n  char* y = new char[5];\n  x[0] = 'a';\n  x[2] = 'b';\n  EXPECT_UMR(memccpy(y, x, 'b', 5));\n  delete[] x;\n  delete[] y;\n}\n\nTEST(MemorySanitizer, bcopy) {\n  char* x = new char[2];\n  char* y = new char[2];\n  x[0] = 1;\n  x[1] = *GetPoisoned<char>();\n  bcopy(x, y, 2);\n  EXPECT_NOT_POISONED(y[0]);\n  EXPECT_POISONED(y[1]);\n}\n\nTEST(MemorySanitizer, strdup) {\n  char buf[4] = \"abc\";\n  __msan_poison(buf + 2, sizeof(*buf));\n  char *x = strdup(buf);\n  EXPECT_NOT_POISONED(x[0]);\n  EXPECT_NOT_POISONED(x[1]);\n  EXPECT_POISONED(x[2]);\n  EXPECT_NOT_POISONED(x[3]);\n  free(x);\n}\n\nTEST(MemorySanitizer, strndup) {\n  char buf[4] = \"abc\";\n  __msan_poison(buf + 2, sizeof(*buf));\n  char *x = strndup(buf, 3);\n  EXPECT_NOT_POISONED(x[0]);\n  EXPECT_NOT_POISONED(x[1]);\n  EXPECT_POISONED(x[2]);\n  EXPECT_NOT_POISONED(x[3]);\n  free(x);\n}\n\nTEST(MemorySanitizer, strndup_short) {\n  char buf[4] = \"abc\";\n  __msan_poison(buf + 1, sizeof(*buf));\n  __msan_poison(buf + 2, sizeof(*buf));\n  char *x = strndup(buf, 2);\n  EXPECT_NOT_POISONED(x[0]);\n  EXPECT_POISONED(x[1]);\n  EXPECT_NOT_POISONED(x[2]);\n  free(x);\n}\n\n\ntemplate<class T, int size>\nvoid TestOverlapMemmove() {\n  T *x = new T[size];\n  ASSERT_GE(size, 3);\n  x[2] = 0;\n  memmove(x, x + 1, (size - 1) * sizeof(T));\n  EXPECT_NOT_POISONED(x[1]);\n  EXPECT_POISONED(x[0]);\n  EXPECT_POISONED(x[2]);\n  delete [] x;\n}\n\nTEST(MemorySanitizer, overlap_memmove) {\n  TestOverlapMemmove<U1, 10>();\n  TestOverlapMemmove<U1, 1000>();\n  TestOverlapMemmove<U8, 4>();\n  TestOverlapMemmove<U8, 1000>();\n}\n\nTEST(MemorySanitizer, strcpy) {  // NOLINT\n  char* x = new char[3];\n  char* y = new char[3];\n  x[0] = 'a';\n  x[1] = *GetPoisoned<char>(1, 1);\n  x[2] = 0;\n  strcpy(y, x);  // NOLINT\n  EXPECT_NOT_POISONED(y[0]);\n  EXPECT_POISONED(y[1]);\n  EXPECT_NOT_POISONED(y[2]);\n}\n\nTEST(MemorySanitizer, strncpy) {  // NOLINT\n  char* x = new char[3];\n  char* y = new char[5];\n  x[0] = 'a';\n  x[1] = *GetPoisoned<char>(1, 1);\n  x[2] = '\\0';\n  strncpy(y, x, 4);  // NOLINT\n  EXPECT_NOT_POISONED(y[0]);\n  EXPECT_POISONED(y[1]);\n  EXPECT_NOT_POISONED(y[2]);\n  EXPECT_NOT_POISONED(y[3]);\n  EXPECT_POISONED(y[4]);\n}\n\nTEST(MemorySanitizer, stpcpy) {  // NOLINT\n  char* x = new char[3];\n  char* y = new char[3];\n  x[0] = 'a';\n  x[1] = *GetPoisoned<char>(1, 1);\n  x[2] = 0;\n  char *res = stpcpy(y, x);  // NOLINT\n  ASSERT_EQ(res, y + 2);\n  EXPECT_NOT_POISONED(y[0]);\n  EXPECT_POISONED(y[1]);\n  EXPECT_NOT_POISONED(y[2]);\n}\n\nTEST(MemorySanitizer, strcat) {  // NOLINT\n  char a[10];\n  char b[] = \"def\";\n  strcpy(a, \"abc\");\n  __msan_poison(b + 1, 1);\n  strcat(a, b);\n  EXPECT_NOT_POISONED(a[3]);\n  EXPECT_POISONED(a[4]);\n  EXPECT_NOT_POISONED(a[5]);\n  EXPECT_NOT_POISONED(a[6]);\n  EXPECT_POISONED(a[7]);\n}\n\nTEST(MemorySanitizer, strncat) {  // NOLINT\n  char a[10];\n  char b[] = \"def\";\n  strcpy(a, \"abc\");\n  __msan_poison(b + 1, 1);\n  strncat(a, b, 5);\n  EXPECT_NOT_POISONED(a[3]);\n  EXPECT_POISONED(a[4]);\n  EXPECT_NOT_POISONED(a[5]);\n  EXPECT_NOT_POISONED(a[6]);\n  EXPECT_POISONED(a[7]);\n}\n\nTEST(MemorySanitizer, strncat_overflow) {  // NOLINT\n  char a[10];\n  char b[] = \"def\";\n  strcpy(a, \"abc\");\n  __msan_poison(b + 1, 1);\n  strncat(a, b, 2);\n  EXPECT_NOT_POISONED(a[3]);\n  EXPECT_POISONED(a[4]);\n  EXPECT_NOT_POISONED(a[5]);\n  EXPECT_POISONED(a[6]);\n  EXPECT_POISONED(a[7]);\n}\n\n#define TEST_STRTO_INT(func_name, char_type, str_prefix) \\\n  TEST(MemorySanitizer, func_name) {                     \\\n    char_type *e;                                        \\\n    EXPECT_EQ(1U, func_name(str_prefix##\"1\", &e, 10));   \\\n    EXPECT_NOT_POISONED((S8)e);                          \\\n  }\n\n#define TEST_STRTO_FLOAT(func_name, char_type, str_prefix) \\\n  TEST(MemorySanitizer, func_name) {                       \\\n    char_type *e;                                          \\\n    EXPECT_NE(0, func_name(str_prefix##\"1.5\", &e));        \\\n    EXPECT_NOT_POISONED((S8)e);                            \\\n  }\n\n#define TEST_STRTO_FLOAT_LOC(func_name, char_type, str_prefix)   \\\n  TEST(MemorySanitizer, func_name) {                             \\\n    locale_t loc = newlocale(LC_NUMERIC_MASK, \"C\", (locale_t)0); \\\n    char_type *e;                                                \\\n    EXPECT_NE(0, func_name(str_prefix##\"1.5\", &e, loc));         \\\n    EXPECT_NOT_POISONED((S8)e);                                  \\\n    freelocale(loc);                                             \\\n  }\n\n#define TEST_STRTO_INT_LOC(func_name, char_type, str_prefix)     \\\n  TEST(MemorySanitizer, func_name) {                             \\\n    locale_t loc = newlocale(LC_NUMERIC_MASK, \"C\", (locale_t)0); \\\n    char_type *e;                                                \\\n    ASSERT_EQ(1U, func_name(str_prefix##\"1\", &e, 10, loc));      \\\n    EXPECT_NOT_POISONED((S8)e);                                  \\\n    freelocale(loc);                                             \\\n  }\n\nTEST_STRTO_INT(strtol, char, )\nTEST_STRTO_INT(strtoll, char, )\nTEST_STRTO_INT(strtoul, char, )\nTEST_STRTO_INT(strtoull, char, )\n\nTEST_STRTO_FLOAT(strtof, char, )\nTEST_STRTO_FLOAT(strtod, char, )\nTEST_STRTO_FLOAT(strtold, char, )\n\nTEST_STRTO_FLOAT_LOC(strtof_l, char, )\nTEST_STRTO_FLOAT_LOC(strtod_l, char, )\nTEST_STRTO_FLOAT_LOC(strtold_l, char, )\n\nTEST_STRTO_INT_LOC(strtol_l, char, )\nTEST_STRTO_INT_LOC(strtoll_l, char, )\nTEST_STRTO_INT_LOC(strtoul_l, char, )\nTEST_STRTO_INT_LOC(strtoull_l, char, )\n\nTEST_STRTO_INT(wcstol, wchar_t, L)\nTEST_STRTO_INT(wcstoll, wchar_t, L)\nTEST_STRTO_INT(wcstoul, wchar_t, L)\nTEST_STRTO_INT(wcstoull, wchar_t, L)\n\nTEST_STRTO_FLOAT(wcstof, wchar_t, L)\nTEST_STRTO_FLOAT(wcstod, wchar_t, L)\nTEST_STRTO_FLOAT(wcstold, wchar_t, L)\n\nTEST_STRTO_FLOAT_LOC(wcstof_l, wchar_t, L)\nTEST_STRTO_FLOAT_LOC(wcstod_l, wchar_t, L)\nTEST_STRTO_FLOAT_LOC(wcstold_l, wchar_t, L)\n\nTEST_STRTO_INT_LOC(wcstol_l, wchar_t, L)\nTEST_STRTO_INT_LOC(wcstoll_l, wchar_t, L)\nTEST_STRTO_INT_LOC(wcstoul_l, wchar_t, L)\nTEST_STRTO_INT_LOC(wcstoull_l, wchar_t, L)\n\n\nTEST(MemorySanitizer, strtoimax) {\n  char *e;\n  ASSERT_EQ(1, strtoimax(\"1\", &e, 10));\n  EXPECT_NOT_POISONED((S8) e);\n}\n\nTEST(MemorySanitizer, strtoumax) {\n  char *e;\n  ASSERT_EQ(1U, strtoumax(\"1\", &e, 10));\n  EXPECT_NOT_POISONED((S8) e);\n}\n\n#ifdef __GLIBC__\nextern \"C\" float __strtof_l(const char *nptr, char **endptr, locale_t loc);\nTEST_STRTO_FLOAT_LOC(__strtof_l, char, )\nextern \"C\" double __strtod_l(const char *nptr, char **endptr, locale_t loc);\nTEST_STRTO_FLOAT_LOC(__strtod_l, char, )\nextern \"C\" long double __strtold_l(const char *nptr, char **endptr,\n                                   locale_t loc);\nTEST_STRTO_FLOAT_LOC(__strtold_l, char, )\n\nextern \"C\" float __wcstof_l(const wchar_t *nptr, wchar_t **endptr, locale_t loc);\nTEST_STRTO_FLOAT_LOC(__wcstof_l, wchar_t, L)\nextern \"C\" double __wcstod_l(const wchar_t *nptr, wchar_t **endptr, locale_t loc);\nTEST_STRTO_FLOAT_LOC(__wcstod_l, wchar_t, L)\nextern \"C\" long double __wcstold_l(const wchar_t *nptr, wchar_t **endptr,\n                                   locale_t loc);\nTEST_STRTO_FLOAT_LOC(__wcstold_l, wchar_t, L)\n#endif  // __GLIBC__\n\nTEST(MemorySanitizer, modf) {\n  double x, y;\n  x = modf(2.1, &y);\n  EXPECT_NOT_POISONED(y);\n}\n\nTEST(MemorySanitizer, modff) {\n  float x, y;\n  x = modff(2.1, &y);\n  EXPECT_NOT_POISONED(y);\n}\n\nTEST(MemorySanitizer, modfl) {\n  long double x, y;\n  x = modfl(2.1, &y);\n  EXPECT_NOT_POISONED(y);\n}\n\n// There's no sincos() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, sincos) {\n  double s, c;\n  sincos(0.2, &s, &c);\n  EXPECT_NOT_POISONED(s);\n  EXPECT_NOT_POISONED(c);\n}\n#endif\n\n// There's no sincosf() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, sincosf) {\n  float s, c;\n  sincosf(0.2, &s, &c);\n  EXPECT_NOT_POISONED(s);\n  EXPECT_NOT_POISONED(c);\n}\n#endif\n\n// There's no sincosl() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, sincosl) {\n  long double s, c;\n  sincosl(0.2, &s, &c);\n  EXPECT_NOT_POISONED(s);\n  EXPECT_NOT_POISONED(c);\n}\n#endif\n\nTEST(MemorySanitizer, remquo) {\n  int quo;\n  double res = remquo(29.0, 3.0, &quo);\n  ASSERT_NE(0.0, res);\n  EXPECT_NOT_POISONED(quo);\n}\n\nTEST(MemorySanitizer, remquof) {\n  int quo;\n  float res = remquof(29.0, 3.0, &quo);\n  ASSERT_NE(0.0, res);\n  EXPECT_NOT_POISONED(quo);\n}\n\nTEST(MemorySanitizer, remquol) {\n  int quo;\n  long double res = remquof(29.0, 3.0, &quo);\n  ASSERT_NE(0.0, res);\n  EXPECT_NOT_POISONED(quo);\n}\n\nTEST(MemorySanitizer, lgamma) {\n  double res = lgamma(1.1);\n  ASSERT_NE(0.0, res);\n  EXPECT_NOT_POISONED(signgam);\n}\n\nTEST(MemorySanitizer, lgammaf) {\n  float res = lgammaf(1.1);\n  ASSERT_NE(0.0, res);\n  EXPECT_NOT_POISONED(signgam);\n}\n\nTEST(MemorySanitizer, lgammal) {\n  long double res = lgammal(1.1);\n  ASSERT_NE(0.0, res);\n  EXPECT_NOT_POISONED(signgam);\n}\n\nTEST(MemorySanitizer, lgamma_r) {\n  int sgn;\n  double res = lgamma_r(1.1, &sgn);\n  ASSERT_NE(0.0, res);\n  EXPECT_NOT_POISONED(sgn);\n}\n\nTEST(MemorySanitizer, lgammaf_r) {\n  int sgn;\n  float res = lgammaf_r(1.1, &sgn);\n  ASSERT_NE(0.0, res);\n  EXPECT_NOT_POISONED(sgn);\n}\n\n// There's no lgammal_r() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, lgammal_r) {\n  int sgn;\n  long double res = lgammal_r(1.1, &sgn);\n  ASSERT_NE(0.0, res);\n  EXPECT_NOT_POISONED(sgn);\n}\n#endif\n\n// There's no drand48_r() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, drand48_r) {\n  struct drand48_data buf;\n  srand48_r(0, &buf);\n  double d;\n  drand48_r(&buf, &d);\n  EXPECT_NOT_POISONED(d);\n}\n#endif\n\n// There's no lrand48_r() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, lrand48_r) {\n  struct drand48_data buf;\n  srand48_r(0, &buf);\n  long d;\n  lrand48_r(&buf, &d);\n  EXPECT_NOT_POISONED(d);\n}\n#endif\n\nTEST(MemorySanitizer, sprintf) {  // NOLINT\n  char buff[10];\n  break_optimization(buff);\n  EXPECT_POISONED(buff[0]);\n  int res = sprintf(buff, \"%d\", 1234567);  // NOLINT\n  ASSERT_EQ(res, 7);\n  ASSERT_EQ(buff[0], '1');\n  ASSERT_EQ(buff[1], '2');\n  ASSERT_EQ(buff[2], '3');\n  ASSERT_EQ(buff[6], '7');\n  ASSERT_EQ(buff[7], 0);\n  EXPECT_POISONED(buff[8]);\n}\n\nTEST(MemorySanitizer, snprintf) {\n  char buff[10];\n  break_optimization(buff);\n  EXPECT_POISONED(buff[0]);\n  int res = snprintf(buff, sizeof(buff), \"%d\", 1234567);\n  ASSERT_EQ(res, 7);\n  ASSERT_EQ(buff[0], '1');\n  ASSERT_EQ(buff[1], '2');\n  ASSERT_EQ(buff[2], '3');\n  ASSERT_EQ(buff[6], '7');\n  ASSERT_EQ(buff[7], 0);\n  EXPECT_POISONED(buff[8]);\n}\n\nTEST(MemorySanitizer, swprintf) {\n  wchar_t buff[10];\n  ASSERT_EQ(4U, sizeof(wchar_t));\n  break_optimization(buff);\n  EXPECT_POISONED(buff[0]);\n  int res = swprintf(buff, 9, L\"%d\", 1234567);\n  ASSERT_EQ(res, 7);\n  ASSERT_EQ(buff[0], '1');\n  ASSERT_EQ(buff[1], '2');\n  ASSERT_EQ(buff[2], '3');\n  ASSERT_EQ(buff[6], '7');\n  ASSERT_EQ(buff[7], 0);\n  EXPECT_POISONED(buff[8]);\n}\n\nTEST(MemorySanitizer, asprintf) {  // NOLINT\n  char *pbuf;\n  EXPECT_POISONED(pbuf);\n  int res = asprintf(&pbuf, \"%d\", 1234567);  // NOLINT\n  ASSERT_EQ(res, 7);\n  EXPECT_NOT_POISONED(pbuf);\n  ASSERT_EQ(pbuf[0], '1');\n  ASSERT_EQ(pbuf[1], '2');\n  ASSERT_EQ(pbuf[2], '3');\n  ASSERT_EQ(pbuf[6], '7');\n  ASSERT_EQ(pbuf[7], 0);\n  free(pbuf);\n}\n\nTEST(MemorySanitizer, mbstowcs) {\n  const char *x = \"abc\";\n  wchar_t buff[10];\n  int res = mbstowcs(buff, x, 2);\n  EXPECT_EQ(2, res);\n  EXPECT_EQ(L'a', buff[0]);\n  EXPECT_EQ(L'b', buff[1]);\n  EXPECT_POISONED(buff[2]);\n  res = mbstowcs(buff, x, 10);\n  EXPECT_EQ(3, res);\n  EXPECT_NOT_POISONED(buff[3]);\n}\n\nTEST(MemorySanitizer, wcstombs) {\n  const wchar_t *x = L\"abc\";\n  char buff[10];\n  int res = wcstombs(buff, x, 4);\n  EXPECT_EQ(res, 3);\n  EXPECT_EQ(buff[0], 'a');\n  EXPECT_EQ(buff[1], 'b');\n  EXPECT_EQ(buff[2], 'c');\n}\n\nTEST(MemorySanitizer, wcsrtombs) {\n  const wchar_t *x = L\"abc\";\n  const wchar_t *p = x;\n  char buff[10];\n  mbstate_t mbs;\n  memset(&mbs, 0, sizeof(mbs));\n  int res = wcsrtombs(buff, &p, 4, &mbs);\n  EXPECT_EQ(res, 3);\n  EXPECT_EQ(buff[0], 'a');\n  EXPECT_EQ(buff[1], 'b');\n  EXPECT_EQ(buff[2], 'c');\n  EXPECT_EQ(buff[3], '\\0');\n  EXPECT_POISONED(buff[4]);\n}\n\nTEST(MemorySanitizer, wcsnrtombs) {\n  const wchar_t *x = L\"abc\";\n  const wchar_t *p = x;\n  char buff[10];\n  mbstate_t mbs;\n  memset(&mbs, 0, sizeof(mbs));\n  int res = wcsnrtombs(buff, &p, 2, 4, &mbs);\n  EXPECT_EQ(res, 2);\n  EXPECT_EQ(buff[0], 'a');\n  EXPECT_EQ(buff[1], 'b');\n  EXPECT_POISONED(buff[2]);\n}\n\nTEST(MemorySanitizer, wmemset) {\n    wchar_t x[25];\n    break_optimization(x);\n    EXPECT_POISONED(x[0]);\n    wmemset(x, L'A', 10);\n    EXPECT_EQ(x[0], L'A');\n    EXPECT_EQ(x[9], L'A');\n    EXPECT_POISONED(x[10]);\n}\n\nTEST(MemorySanitizer, mbtowc) {\n  const char *x = \"abc\";\n  wchar_t wx;\n  int res = mbtowc(&wx, x, 3);\n  EXPECT_GT(res, 0);\n  EXPECT_NOT_POISONED(wx);\n}\n\nTEST(MemorySanitizer, mbrtowc) {\n  const char *x = \"abc\";\n  wchar_t wx;\n  mbstate_t mbs;\n  memset(&mbs, 0, sizeof(mbs));\n  int res = mbrtowc(&wx, x, 3, &mbs);\n  EXPECT_GT(res, 0);\n  EXPECT_NOT_POISONED(wx);\n}\n\nTEST(MemorySanitizer, wcsftime) {\n  wchar_t x[100];\n  time_t t = time(NULL);\n  struct tm tms;\n  struct tm *tmres = localtime_r(&t, &tms);\n  ASSERT_NE((void *)0, tmres);\n  size_t res = wcsftime(x, sizeof(x) / sizeof(x[0]), L\"%Y-%m-%d\", tmres);\n  EXPECT_GT(res, 0UL);\n  EXPECT_EQ(res, wcslen(x));\n}\n\nTEST(MemorySanitizer, gettimeofday) {\n  struct timeval tv;\n  struct timezone tz;\n  break_optimization(&tv);\n  break_optimization(&tz);\n  ASSERT_EQ(16U, sizeof(tv));\n  ASSERT_EQ(8U, sizeof(tz));\n  EXPECT_POISONED(tv.tv_sec);\n  EXPECT_POISONED(tv.tv_usec);\n  EXPECT_POISONED(tz.tz_minuteswest);\n  EXPECT_POISONED(tz.tz_dsttime);\n  ASSERT_EQ(0, gettimeofday(&tv, &tz));\n  EXPECT_NOT_POISONED(tv.tv_sec);\n  EXPECT_NOT_POISONED(tv.tv_usec);\n  EXPECT_NOT_POISONED(tz.tz_minuteswest);\n  EXPECT_NOT_POISONED(tz.tz_dsttime);\n}\n\nTEST(MemorySanitizer, clock_gettime) {\n  struct timespec tp;\n  EXPECT_POISONED(tp.tv_sec);\n  EXPECT_POISONED(tp.tv_nsec);\n  ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &tp));\n  EXPECT_NOT_POISONED(tp.tv_sec);\n  EXPECT_NOT_POISONED(tp.tv_nsec);\n}\n\nTEST(MemorySanitizer, clock_getres) {\n  struct timespec tp;\n  EXPECT_POISONED(tp.tv_sec);\n  EXPECT_POISONED(tp.tv_nsec);\n  ASSERT_EQ(0, clock_getres(CLOCK_REALTIME, 0));\n  EXPECT_POISONED(tp.tv_sec);\n  EXPECT_POISONED(tp.tv_nsec);\n  ASSERT_EQ(0, clock_getres(CLOCK_REALTIME, &tp));\n  EXPECT_NOT_POISONED(tp.tv_sec);\n  EXPECT_NOT_POISONED(tp.tv_nsec);\n}\n\nTEST(MemorySanitizer, getitimer) {\n  struct itimerval it1, it2;\n  int res;\n  EXPECT_POISONED(it1.it_interval.tv_sec);\n  EXPECT_POISONED(it1.it_interval.tv_usec);\n  EXPECT_POISONED(it1.it_value.tv_sec);\n  EXPECT_POISONED(it1.it_value.tv_usec);\n  res = getitimer(ITIMER_VIRTUAL, &it1);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(it1.it_interval.tv_sec);\n  EXPECT_NOT_POISONED(it1.it_interval.tv_usec);\n  EXPECT_NOT_POISONED(it1.it_value.tv_sec);\n  EXPECT_NOT_POISONED(it1.it_value.tv_usec);\n\n  it1.it_interval.tv_sec = it1.it_value.tv_sec = 10000;\n  it1.it_interval.tv_usec = it1.it_value.tv_usec = 0;\n\n  res = setitimer(ITIMER_VIRTUAL, &it1, &it2);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(it2.it_interval.tv_sec);\n  EXPECT_NOT_POISONED(it2.it_interval.tv_usec);\n  EXPECT_NOT_POISONED(it2.it_value.tv_sec);\n  EXPECT_NOT_POISONED(it2.it_value.tv_usec);\n\n  // Check that old_value can be 0, and disable the timer.\n  memset(&it1, 0, sizeof(it1));\n  res = setitimer(ITIMER_VIRTUAL, &it1, 0);\n  ASSERT_EQ(0, res);\n}\n\nTEST(MemorySanitizer, setitimer_null) {\n  setitimer(ITIMER_VIRTUAL, 0, 0);\n  // Not testing the return value, since it the behaviour seems to differ\n  // between libc implementations and POSIX.\n  // Should never crash, though.\n}\n\nTEST(MemorySanitizer, time) {\n  time_t t;\n  EXPECT_POISONED(t);\n  time_t t2 = time(&t);\n  ASSERT_NE(t2, (time_t)-1);\n  EXPECT_NOT_POISONED(t);\n}\n\nTEST(MemorySanitizer, strptime) {\n  struct tm time;\n  char *p = strptime(\"11/1/2013-05:39\", \"%m/%d/%Y-%H:%M\", &time);\n  ASSERT_TRUE(p != NULL);\n  EXPECT_NOT_POISONED(time.tm_sec);\n  EXPECT_NOT_POISONED(time.tm_hour);\n  EXPECT_NOT_POISONED(time.tm_year);\n}\n\nTEST(MemorySanitizer, localtime) {\n  time_t t = 123;\n  struct tm *time = localtime(&t);\n  ASSERT_TRUE(time != NULL);\n  EXPECT_NOT_POISONED(time->tm_sec);\n  EXPECT_NOT_POISONED(time->tm_hour);\n  EXPECT_NOT_POISONED(time->tm_year);\n  EXPECT_NOT_POISONED(time->tm_isdst);\n  EXPECT_NE(0U, strlen(time->tm_zone));\n}\n\nTEST(MemorySanitizer, localtime_r) {\n  time_t t = 123;\n  struct tm time;\n  struct tm *res = localtime_r(&t, &time);\n  ASSERT_TRUE(res != NULL);\n  EXPECT_NOT_POISONED(time.tm_sec);\n  EXPECT_NOT_POISONED(time.tm_hour);\n  EXPECT_NOT_POISONED(time.tm_year);\n  EXPECT_NOT_POISONED(time.tm_isdst);\n  EXPECT_NE(0U, strlen(time.tm_zone));\n}\n\n// There's no getmntent() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, getmntent) {\n  FILE *fp = setmntent(\"/etc/fstab\", \"r\");\n  struct mntent *mnt = getmntent(fp);\n  ASSERT_TRUE(mnt != NULL);\n  ASSERT_NE(0U, strlen(mnt->mnt_fsname));\n  ASSERT_NE(0U, strlen(mnt->mnt_dir));\n  ASSERT_NE(0U, strlen(mnt->mnt_type));\n  ASSERT_NE(0U, strlen(mnt->mnt_opts));\n  EXPECT_NOT_POISONED(mnt->mnt_freq);\n  EXPECT_NOT_POISONED(mnt->mnt_passno);\n  fclose(fp);\n}\n#endif\n\n// There's no getmntent_r() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, getmntent_r) {\n  FILE *fp = setmntent(\"/etc/fstab\", \"r\");\n  struct mntent mntbuf;\n  char buf[1000];\n  struct mntent *mnt = getmntent_r(fp, &mntbuf, buf, sizeof(buf));\n  ASSERT_TRUE(mnt != NULL);\n  ASSERT_NE(0U, strlen(mnt->mnt_fsname));\n  ASSERT_NE(0U, strlen(mnt->mnt_dir));\n  ASSERT_NE(0U, strlen(mnt->mnt_type));\n  ASSERT_NE(0U, strlen(mnt->mnt_opts));\n  EXPECT_NOT_POISONED(mnt->mnt_freq);\n  EXPECT_NOT_POISONED(mnt->mnt_passno);\n  fclose(fp);\n}\n#endif\n\nTEST(MemorySanitizer, ether) {\n  const char *asc = \"11:22:33:44:55:66\";\n  struct ether_addr *paddr = ether_aton(asc);\n  EXPECT_NOT_POISONED(*paddr);\n\n  struct ether_addr addr;\n  paddr = ether_aton_r(asc, &addr);\n  ASSERT_EQ(paddr, &addr);\n  EXPECT_NOT_POISONED(addr);\n\n  char *s = ether_ntoa(&addr);\n  ASSERT_NE(0U, strlen(s));\n\n  char buf[100];\n  s = ether_ntoa_r(&addr, buf);\n  ASSERT_EQ(s, buf);\n  ASSERT_NE(0U, strlen(buf));\n}\n\nTEST(MemorySanitizer, mmap) {\n  const int size = 4096;\n  void *p1, *p2;\n  p1 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);\n  __msan_poison(p1, size);\n  munmap(p1, size);\n  for (int i = 0; i < 1000; i++) {\n    p2 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);\n    if (p2 == p1)\n      break;\n    else\n      munmap(p2, size);\n  }\n  if (p1 == p2) {\n    EXPECT_NOT_POISONED(*(char*)p2);\n    munmap(p2, size);\n  }\n}\n\n// There's no fcvt() on FreeBSD.\n#if !defined(__FreeBSD__)\n// FIXME: enable and add ecvt.\n// FIXME: check why msandr does nt handle fcvt.\nTEST(MemorySanitizer, fcvt) {\n  int a, b;\n  break_optimization(&a);\n  break_optimization(&b);\n  EXPECT_POISONED(a);\n  EXPECT_POISONED(b);\n  char *str = fcvt(12345.6789, 10, &a, &b);\n  EXPECT_NOT_POISONED(a);\n  EXPECT_NOT_POISONED(b);\n  ASSERT_NE(nullptr, str);\n  EXPECT_NOT_POISONED(str[0]);\n  ASSERT_NE(0U, strlen(str));\n}\n#endif\n\n// There's no fcvt_long() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, fcvt_long) {\n  int a, b;\n  break_optimization(&a);\n  break_optimization(&b);\n  EXPECT_POISONED(a);\n  EXPECT_POISONED(b);\n  char *str = fcvt(111111112345.6789, 10, &a, &b);\n  EXPECT_NOT_POISONED(a);\n  EXPECT_NOT_POISONED(b);\n  ASSERT_NE(nullptr, str);\n  EXPECT_NOT_POISONED(str[0]);\n  ASSERT_NE(0U, strlen(str));\n}\n#endif\n\nTEST(MemorySanitizer, memchr) {\n  char x[10];\n  break_optimization(x);\n  EXPECT_POISONED(x[0]);\n  x[2] = '2';\n  void *res;\n  EXPECT_UMR(res = memchr(x, '2', 10));\n  EXPECT_NOT_POISONED(res);\n  x[0] = '0';\n  x[1] = '1';\n  res = memchr(x, '2', 10);\n  EXPECT_EQ(&x[2], res);\n  EXPECT_UMR(res = memchr(x, '3', 10));\n  EXPECT_NOT_POISONED(res);\n}\n\nTEST(MemorySanitizer, memrchr) {\n  char x[10];\n  break_optimization(x);\n  EXPECT_POISONED(x[0]);\n  x[9] = '9';\n  void *res;\n  EXPECT_UMR(res = memrchr(x, '9', 10));\n  EXPECT_NOT_POISONED(res);\n  x[0] = '0';\n  x[1] = '1';\n  res = memrchr(x, '0', 2);\n  EXPECT_EQ(&x[0], res);\n  EXPECT_UMR(res = memrchr(x, '7', 10));\n  EXPECT_NOT_POISONED(res);\n}\n\nTEST(MemorySanitizer, frexp) {\n  int x;\n  x = *GetPoisoned<int>();\n  double r = frexp(1.1, &x);\n  EXPECT_NOT_POISONED(r);\n  EXPECT_NOT_POISONED(x);\n\n  x = *GetPoisoned<int>();\n  float rf = frexpf(1.1, &x);\n  EXPECT_NOT_POISONED(rf);\n  EXPECT_NOT_POISONED(x);\n\n  x = *GetPoisoned<int>();\n  double rl = frexpl(1.1, &x);\n  EXPECT_NOT_POISONED(rl);\n  EXPECT_NOT_POISONED(x);\n}\n\nnamespace {\n\nstatic int cnt;\n\nvoid SigactionHandler(int signo, siginfo_t* si, void* uc) {\n  ASSERT_EQ(signo, SIGPROF);\n  ASSERT_TRUE(si != NULL);\n  EXPECT_NOT_POISONED(si->si_errno);\n  EXPECT_NOT_POISONED(si->si_pid);\n#if __linux__\n# if defined(__x86_64__)\n  EXPECT_NOT_POISONED(((ucontext_t*)uc)->uc_mcontext.gregs[REG_RIP]);\n# elif defined(__i386__)\n  EXPECT_NOT_POISONED(((ucontext_t*)uc)->uc_mcontext.gregs[REG_EIP]);\n# endif\n#endif\n  ++cnt;\n}\n\nTEST(MemorySanitizer, sigaction) {\n  struct sigaction act = {};\n  struct sigaction oldact = {};\n  struct sigaction origact = {};\n\n  sigaction(SIGPROF, 0, &origact);\n\n  act.sa_flags |= SA_SIGINFO;\n  act.sa_sigaction = &SigactionHandler;\n  sigaction(SIGPROF, &act, 0);\n\n  kill(getpid(), SIGPROF);\n\n  act.sa_flags &= ~SA_SIGINFO;\n  act.sa_handler = SIG_DFL;\n  sigaction(SIGPROF, &act, 0);\n\n  act.sa_flags &= ~SA_SIGINFO;\n  act.sa_handler = SIG_IGN;\n  sigaction(SIGPROF, &act, &oldact);\n  EXPECT_FALSE(oldact.sa_flags & SA_SIGINFO);\n  EXPECT_EQ(SIG_DFL, oldact.sa_handler);\n  kill(getpid(), SIGPROF);\n\n  act.sa_flags |= SA_SIGINFO;\n  act.sa_sigaction = &SigactionHandler;\n  sigaction(SIGPROF, &act, &oldact);\n  EXPECT_FALSE(oldact.sa_flags & SA_SIGINFO);\n  EXPECT_EQ(SIG_IGN, oldact.sa_handler);\n  kill(getpid(), SIGPROF);\n\n  act.sa_flags &= ~SA_SIGINFO;\n  act.sa_handler = SIG_DFL;\n  sigaction(SIGPROF, &act, &oldact);\n  EXPECT_TRUE(oldact.sa_flags & SA_SIGINFO);\n  EXPECT_EQ(&SigactionHandler, oldact.sa_sigaction);\n  EXPECT_EQ(2, cnt);\n\n  sigaction(SIGPROF, &origact, 0);\n}\n\n} // namespace\n\n\nTEST(MemorySanitizer, sigemptyset) {\n  sigset_t s;\n  EXPECT_POISONED(s);\n  int res = sigemptyset(&s);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(s);\n}\n\nTEST(MemorySanitizer, sigfillset) {\n  sigset_t s;\n  EXPECT_POISONED(s);\n  int res = sigfillset(&s);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(s);\n}\n\nTEST(MemorySanitizer, sigpending) {\n  sigset_t s;\n  EXPECT_POISONED(s);\n  int res = sigpending(&s);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(s);\n}\n\nTEST(MemorySanitizer, sigprocmask) {\n  sigset_t s;\n  EXPECT_POISONED(s);\n  int res = sigprocmask(SIG_BLOCK, 0, &s);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(s);\n}\n\nstruct StructWithDtor {\n  ~StructWithDtor();\n};\n\nNOINLINE StructWithDtor::~StructWithDtor() {\n  break_optimization(0);\n}\n\nTEST(MemorySanitizer, Invoke) {\n  StructWithDtor s;  // Will cause the calls to become invokes.\n  EXPECT_NOT_POISONED(0);\n  EXPECT_POISONED(*GetPoisoned<int>());\n  EXPECT_NOT_POISONED(0);\n  EXPECT_POISONED(*GetPoisoned<int>());\n  EXPECT_POISONED(ReturnPoisoned<S4>());\n}\n\nTEST(MemorySanitizer, ptrtoint) {\n  // Test that shadow is propagated through pointer-to-integer conversion.\n  void* p = (void*)0xABCD;\n  __msan_poison(((char*)&p) + 1, sizeof(p));\n  EXPECT_NOT_POISONED((((uintptr_t)p) & 0xFF) == 0);\n\n  void* q = (void*)0xABCD;\n  __msan_poison(&q, sizeof(q) - 1);\n  EXPECT_POISONED((((uintptr_t)q) & 0xFF) == 0);\n}\n\nstatic void vaargsfn2(int guard, ...) {\n  va_list vl;\n  va_start(vl, guard);\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_POISONED(va_arg(vl, double));\n  va_end(vl);\n}\n\nstatic void vaargsfn(int guard, ...) {\n  va_list vl;\n  va_start(vl, guard);\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_POISONED(va_arg(vl, int));\n  // The following call will overwrite __msan_param_tls.\n  // Checks after it test that arg shadow was somehow saved across the call.\n  vaargsfn2(1, 2, 3, 4, *GetPoisoned<double>());\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_POISONED(va_arg(vl, int));\n  va_end(vl);\n}\n\nTEST(MemorySanitizer, VAArgTest) {\n  int* x = GetPoisoned<int>();\n  int* y = GetPoisoned<int>(4);\n  vaargsfn(1, 13, *x, 42, *y);\n}\n\nstatic void vaargsfn_many(int guard, ...) {\n  va_list vl;\n  va_start(vl, guard);\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_POISONED(va_arg(vl, int));\n  va_end(vl);\n}\n\nTEST(MemorySanitizer, VAArgManyTest) {\n  int* x = GetPoisoned<int>();\n  int* y = GetPoisoned<int>(4);\n  vaargsfn_many(1, 2, *x, 3, 4, 5, 6, 7, 8, 9, *y);\n}\n\nstatic void vaargsfn_pass2(va_list vl) {\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_POISONED(va_arg(vl, int));\n}\n\nstatic void vaargsfn_pass(int guard, ...) {\n  va_list vl;\n  va_start(vl, guard);\n  EXPECT_POISONED(va_arg(vl, int));\n  vaargsfn_pass2(vl);\n  va_end(vl);\n}\n\nTEST(MemorySanitizer, VAArgPass) {\n  int* x = GetPoisoned<int>();\n  int* y = GetPoisoned<int>(4);\n  vaargsfn_pass(1, *x, 2, 3, *y);\n}\n\nstatic void vaargsfn_copy2(va_list vl) {\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_POISONED(va_arg(vl, int));\n}\n\nstatic void vaargsfn_copy(int guard, ...) {\n  va_list vl;\n  va_start(vl, guard);\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_POISONED(va_arg(vl, int));\n  va_list vl2;\n  va_copy(vl2, vl);\n  vaargsfn_copy2(vl2);\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_POISONED(va_arg(vl, int));\n  va_end(vl);\n}\n\nTEST(MemorySanitizer, VAArgCopy) {\n  int* x = GetPoisoned<int>();\n  int* y = GetPoisoned<int>(4);\n  vaargsfn_copy(1, 2, *x, 3, *y);\n}\n\nstatic void vaargsfn_ptr(int guard, ...) {\n  va_list vl;\n  va_start(vl, guard);\n  EXPECT_NOT_POISONED(va_arg(vl, int*));\n  EXPECT_POISONED(va_arg(vl, int*));\n  EXPECT_NOT_POISONED(va_arg(vl, int*));\n  EXPECT_POISONED(va_arg(vl, double*));\n  va_end(vl);\n}\n\nTEST(MemorySanitizer, VAArgPtr) {\n  int** x = GetPoisoned<int*>();\n  double** y = GetPoisoned<double*>(8);\n  int z;\n  vaargsfn_ptr(1, &z, *x, &z, *y);\n}\n\nstatic void vaargsfn_overflow(int guard, ...) {\n  va_list vl;\n  va_start(vl, guard);\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n\n  EXPECT_NOT_POISONED(va_arg(vl, double));\n  EXPECT_NOT_POISONED(va_arg(vl, double));\n  EXPECT_NOT_POISONED(va_arg(vl, double));\n  EXPECT_POISONED(va_arg(vl, double));\n  EXPECT_NOT_POISONED(va_arg(vl, double));\n  EXPECT_POISONED(va_arg(vl, int*));\n  EXPECT_NOT_POISONED(va_arg(vl, double));\n  EXPECT_NOT_POISONED(va_arg(vl, double));\n\n  EXPECT_POISONED(va_arg(vl, int));\n  EXPECT_POISONED(va_arg(vl, double));\n  EXPECT_POISONED(va_arg(vl, int*));\n\n  EXPECT_NOT_POISONED(va_arg(vl, int));\n  EXPECT_NOT_POISONED(va_arg(vl, double));\n  EXPECT_NOT_POISONED(va_arg(vl, int*));\n\n  EXPECT_POISONED(va_arg(vl, int));\n  EXPECT_POISONED(va_arg(vl, double));\n  EXPECT_POISONED(va_arg(vl, int*));\n\n  va_end(vl);\n}\n\nTEST(MemorySanitizer, VAArgOverflow) {\n  int* x = GetPoisoned<int>();\n  double* y = GetPoisoned<double>(8);\n  int** p = GetPoisoned<int*>(16);\n  int z;\n  vaargsfn_overflow(1,\n      1, 2, *x, 4, 5, 6,\n      1.1, 2.2, 3.3, *y, 5.5, *p, 7.7, 8.8,\n      // the following args will overflow for sure\n      *x, *y, *p,\n      7, 9.9, &z,\n      *x, *y, *p);\n}\n\nstatic void vaargsfn_tlsoverwrite2(int guard, ...) {\n  va_list vl;\n  va_start(vl, guard);\n  for (int i = 0; i < 20; ++i)\n    EXPECT_NOT_POISONED(va_arg(vl, int));\n  va_end(vl);\n}\n\nstatic void vaargsfn_tlsoverwrite(int guard, ...) {\n  // This call will overwrite TLS contents unless it's backed up somewhere.\n  vaargsfn_tlsoverwrite2(2,\n      42, 42, 42, 42, 42,\n      42, 42, 42, 42, 42,\n      42, 42, 42, 42, 42,\n      42, 42, 42, 42, 42); // 20x\n  va_list vl;\n  va_start(vl, guard);\n  for (int i = 0; i < 20; ++i)\n    EXPECT_POISONED(va_arg(vl, int));\n  va_end(vl);\n}\n\nTEST(MemorySanitizer, VAArgTLSOverwrite) {\n  int* x = GetPoisoned<int>();\n  vaargsfn_tlsoverwrite(1,\n      *x, *x, *x, *x, *x,\n      *x, *x, *x, *x, *x,\n      *x, *x, *x, *x, *x,\n      *x, *x, *x, *x, *x); // 20x\n\n}\n\nstruct StructByVal {\n  int a, b, c, d, e, f;\n};\n\nstatic void vaargsfn_structbyval(int guard, ...) {\n  va_list vl;\n  va_start(vl, guard);\n  {\n    StructByVal s = va_arg(vl, StructByVal);\n    EXPECT_NOT_POISONED(s.a);\n    EXPECT_POISONED(s.b);\n    EXPECT_NOT_POISONED(s.c);\n    EXPECT_POISONED(s.d);\n    EXPECT_NOT_POISONED(s.e);\n    EXPECT_POISONED(s.f);\n  }\n  {\n    StructByVal s = va_arg(vl, StructByVal);\n    EXPECT_NOT_POISONED(s.a);\n    EXPECT_POISONED(s.b);\n    EXPECT_NOT_POISONED(s.c);\n    EXPECT_POISONED(s.d);\n    EXPECT_NOT_POISONED(s.e);\n    EXPECT_POISONED(s.f);\n  }\n  va_end(vl);\n}\n\nTEST(MemorySanitizer, VAArgStructByVal) {\n  StructByVal s;\n  s.a = 1;\n  s.b = *GetPoisoned<int>();\n  s.c = 2;\n  s.d = *GetPoisoned<int>();\n  s.e = 3;\n  s.f = *GetPoisoned<int>();\n  vaargsfn_structbyval(0, s, s);\n}\n\nNOINLINE void StructByValTestFunc(struct StructByVal s) {\n  EXPECT_NOT_POISONED(s.a);\n  EXPECT_POISONED(s.b);\n  EXPECT_NOT_POISONED(s.c);\n  EXPECT_POISONED(s.d);\n  EXPECT_NOT_POISONED(s.e);\n  EXPECT_POISONED(s.f);\n}\n\nNOINLINE void StructByValTestFunc1(struct StructByVal s) {\n  StructByValTestFunc(s);\n}\n\nNOINLINE void StructByValTestFunc2(int z, struct StructByVal s) {\n  StructByValTestFunc(s);\n}\n\nTEST(MemorySanitizer, StructByVal) {\n  // Large aggregates are passed as \"byval\" pointer argument in LLVM.\n  struct StructByVal s;\n  s.a = 1;\n  s.b = *GetPoisoned<int>();\n  s.c = 2;\n  s.d = *GetPoisoned<int>();\n  s.e = 3;\n  s.f = *GetPoisoned<int>();\n  StructByValTestFunc(s);\n  StructByValTestFunc1(s);\n  StructByValTestFunc2(0, s);\n}\n\n\n#if MSAN_HAS_M128\nNOINLINE __m128i m128Eq(__m128i *a, __m128i *b) { return _mm_cmpeq_epi16(*a, *b); }\nNOINLINE __m128i m128Lt(__m128i *a, __m128i *b) { return _mm_cmplt_epi16(*a, *b); }\nTEST(MemorySanitizer, m128) {\n  __m128i a = _mm_set1_epi16(0x1234);\n  __m128i b = _mm_set1_epi16(0x7890);\n  EXPECT_NOT_POISONED(m128Eq(&a, &b));\n  EXPECT_NOT_POISONED(m128Lt(&a, &b));\n}\n// FIXME: add more tests for __m128i.\n#endif  // MSAN_HAS_M128\n\n// We should not complain when copying this poisoned hole.\nstruct StructWithHole {\n  U4  a;\n  // 4-byte hole.\n  U8  b;\n};\n\nNOINLINE StructWithHole ReturnStructWithHole() {\n  StructWithHole res;\n  __msan_poison(&res, sizeof(res));\n  res.a = 1;\n  res.b = 2;\n  return res;\n}\n\nTEST(MemorySanitizer, StructWithHole) {\n  StructWithHole a = ReturnStructWithHole();\n  break_optimization(&a);\n}\n\ntemplate <class T>\nNOINLINE T ReturnStruct() {\n  T res;\n  __msan_poison(&res, sizeof(res));\n  res.a = 1;\n  return res;\n}\n\ntemplate <class T>\nNOINLINE void TestReturnStruct() {\n  T s1 = ReturnStruct<T>();\n  EXPECT_NOT_POISONED(s1.a);\n  EXPECT_POISONED(s1.b);\n}\n\nstruct SSS1 {\n  int a, b, c;\n};\nstruct SSS2 {\n  int b, a, c;\n};\nstruct SSS3 {\n  int b, c, a;\n};\nstruct SSS4 {\n  int c, b, a;\n};\n\nstruct SSS5 {\n  int a;\n  float b;\n};\nstruct SSS6 {\n  int a;\n  double b;\n};\nstruct SSS7 {\n  S8 b;\n  int a;\n};\nstruct SSS8 {\n  S2 b;\n  S8 a;\n};\n\nTEST(MemorySanitizer, IntStruct3) {\n  TestReturnStruct<SSS1>();\n  TestReturnStruct<SSS2>();\n  TestReturnStruct<SSS3>();\n  TestReturnStruct<SSS4>();\n  TestReturnStruct<SSS5>();\n  TestReturnStruct<SSS6>();\n  TestReturnStruct<SSS7>();\n  TestReturnStruct<SSS8>();\n}\n\nstruct LongStruct {\n  U1 a1, b1;\n  U2 a2, b2;\n  U4 a4, b4;\n  U8 a8, b8;\n};\n\nNOINLINE LongStruct ReturnLongStruct1() {\n  LongStruct res;\n  __msan_poison(&res, sizeof(res));\n  res.a1 = res.a2 = res.a4 = res.a8 = 111;\n  // leaves b1, .., b8 poisoned.\n  return res;\n}\n\nNOINLINE LongStruct ReturnLongStruct2() {\n  LongStruct res;\n  __msan_poison(&res, sizeof(res));\n  res.b1 = res.b2 = res.b4 = res.b8 = 111;\n  // leaves a1, .., a8 poisoned.\n  return res;\n}\n\nTEST(MemorySanitizer, LongStruct) {\n  LongStruct s1 = ReturnLongStruct1();\n  __msan_print_shadow(&s1, sizeof(s1));\n  EXPECT_NOT_POISONED(s1.a1);\n  EXPECT_NOT_POISONED(s1.a2);\n  EXPECT_NOT_POISONED(s1.a4);\n  EXPECT_NOT_POISONED(s1.a8);\n\n  EXPECT_POISONED(s1.b1);\n  EXPECT_POISONED(s1.b2);\n  EXPECT_POISONED(s1.b4);\n  EXPECT_POISONED(s1.b8);\n\n  LongStruct s2 = ReturnLongStruct2();\n  __msan_print_shadow(&s2, sizeof(s2));\n  EXPECT_NOT_POISONED(s2.b1);\n  EXPECT_NOT_POISONED(s2.b2);\n  EXPECT_NOT_POISONED(s2.b4);\n  EXPECT_NOT_POISONED(s2.b8);\n\n  EXPECT_POISONED(s2.a1);\n  EXPECT_POISONED(s2.a2);\n  EXPECT_POISONED(s2.a4);\n  EXPECT_POISONED(s2.a8);\n}\n\nTEST(MemorySanitizer, getrlimit) {\n  struct rlimit limit;\n  __msan_poison(&limit, sizeof(limit));\n  int result = getrlimit(RLIMIT_DATA, &limit);\n  ASSERT_EQ(result, 0);\n  EXPECT_NOT_POISONED(limit.rlim_cur);\n  EXPECT_NOT_POISONED(limit.rlim_max);\n}\n\nTEST(MemorySanitizer, getrusage) {\n  struct rusage usage;\n  __msan_poison(&usage, sizeof(usage));\n  int result = getrusage(RUSAGE_SELF, &usage);\n  ASSERT_EQ(result, 0);\n  EXPECT_NOT_POISONED(usage.ru_utime.tv_sec);\n  EXPECT_NOT_POISONED(usage.ru_utime.tv_usec);\n  EXPECT_NOT_POISONED(usage.ru_stime.tv_sec);\n  EXPECT_NOT_POISONED(usage.ru_stime.tv_usec);\n  EXPECT_NOT_POISONED(usage.ru_maxrss);\n  EXPECT_NOT_POISONED(usage.ru_minflt);\n  EXPECT_NOT_POISONED(usage.ru_majflt);\n  EXPECT_NOT_POISONED(usage.ru_inblock);\n  EXPECT_NOT_POISONED(usage.ru_oublock);\n  EXPECT_NOT_POISONED(usage.ru_nvcsw);\n  EXPECT_NOT_POISONED(usage.ru_nivcsw);\n}\n\n#if defined(__FreeBSD__)\nstatic void GetProgramPath(char *buf, size_t sz) {\n  int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };\n  int res = sysctl(mib, 4, buf, &sz, NULL, 0);\n  ASSERT_EQ(0, res);\n}\n#elif defined(__GLIBC__)\nstatic void GetProgramPath(char *buf, size_t sz) {\n  extern char *program_invocation_name;\n  int res = snprintf(buf, sz, \"%s\", program_invocation_name);\n  ASSERT_GE(res, 0);\n  ASSERT_LT((size_t)res, sz);\n}\n#else\n# error \"TODO: port this\"\n#endif\n\nstatic void dladdr_testfn() {}\n\nTEST(MemorySanitizer, dladdr) {\n  Dl_info info;\n  __msan_poison(&info, sizeof(info));\n  int result = dladdr((const void*)dladdr_testfn, &info);\n  ASSERT_NE(result, 0);\n  EXPECT_NOT_POISONED((unsigned long)info.dli_fname);\n  if (info.dli_fname)\n    EXPECT_NOT_POISONED(strlen(info.dli_fname));\n  EXPECT_NOT_POISONED((unsigned long)info.dli_fbase);\n  EXPECT_NOT_POISONED((unsigned long)info.dli_sname);\n  if (info.dli_sname)\n    EXPECT_NOT_POISONED(strlen(info.dli_sname));\n  EXPECT_NOT_POISONED((unsigned long)info.dli_saddr);\n}\n\n#ifndef MSAN_TEST_DISABLE_DLOPEN\n\nstatic int dl_phdr_callback(struct dl_phdr_info *info, size_t size, void *data) {\n  (*(int *)data)++;\n  EXPECT_NOT_POISONED(info->dlpi_addr);\n  EXPECT_NOT_POISONED(strlen(info->dlpi_name));\n  EXPECT_NOT_POISONED(info->dlpi_phnum);\n  for (int i = 0; i < info->dlpi_phnum; ++i)\n    EXPECT_NOT_POISONED(info->dlpi_phdr[i]);\n  return 0;\n}\n\n// Compute the path to our loadable DSO.  We assume it's in the same\n// directory.  Only use string routines that we intercept so far to do this.\nstatic void GetPathToLoadable(char *buf, size_t sz) {\n  char program_path[kMaxPathLength];\n  GetProgramPath(program_path, sizeof(program_path));\n\n  const char *last_slash = strrchr(program_path, '/');\n  ASSERT_NE(nullptr, last_slash);\n  size_t dir_len = (size_t)(last_slash - program_path);\n#if defined(__x86_64__)\n  static const char basename[] = \"libmsan_loadable.x86_64.so\";\n#elif defined(__MIPSEB__) || defined(MIPSEB)\n  static const char basename[] = \"libmsan_loadable.mips64.so\";\n#elif defined(__mips64)\n  static const char basename[] = \"libmsan_loadable.mips64el.so\";\n#endif\n  int res = snprintf(buf, sz, \"%.*s/%s\",\n                     (int)dir_len, program_path, basename);\n  ASSERT_GE(res, 0);\n  ASSERT_LT((size_t)res, sz);\n}\n\nTEST(MemorySanitizer, dl_iterate_phdr) {\n  char path[kMaxPathLength];\n  GetPathToLoadable(path, sizeof(path));\n\n  // Having at least one dlopen'ed library in the process makes this more\n  // entertaining.\n  void *lib = dlopen(path, RTLD_LAZY);\n  ASSERT_NE((void*)0, lib);\n\n  int count = 0;\n  int result = dl_iterate_phdr(dl_phdr_callback, &count);\n  ASSERT_GT(count, 0);\n\n  dlclose(lib);\n}\n\nTEST(MemorySanitizer, dlopen) {\n  char path[kMaxPathLength];\n  GetPathToLoadable(path, sizeof(path));\n\n  // We need to clear shadow for globals when doing dlopen.  In order to test\n  // this, we have to poison the shadow for the DSO before we load it.  In\n  // general this is difficult, but the loader tends to reload things in the\n  // same place, so we open, close, and then reopen.  The global should always\n  // start out clean after dlopen.\n  for (int i = 0; i < 2; i++) {\n    void *lib = dlopen(path, RTLD_LAZY);\n    if (lib == NULL) {\n      printf(\"dlerror: %s\\n\", dlerror());\n      ASSERT_TRUE(lib != NULL);\n    }\n    void **(*get_dso_global)() = (void **(*)())dlsym(lib, \"get_dso_global\");\n    ASSERT_TRUE(get_dso_global != NULL);\n    void **dso_global = get_dso_global();\n    EXPECT_NOT_POISONED(*dso_global);\n    __msan_poison(dso_global, sizeof(*dso_global));\n    EXPECT_POISONED(*dso_global);\n    dlclose(lib);\n  }\n}\n\n// Regression test for a crash in dlopen() interceptor.\nTEST(MemorySanitizer, dlopenFailed) {\n  const char *path = \"/libmsan_loadable_does_not_exist.so\";\n  void *lib = dlopen(path, RTLD_LAZY);\n  ASSERT_TRUE(lib == NULL);\n}\n\n#endif // MSAN_TEST_DISABLE_DLOPEN\n\n// There's no sched_getaffinity() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, sched_getaffinity) {\n  cpu_set_t mask;\n  int res = sched_getaffinity(getpid(), sizeof(mask), &mask);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(mask);\n}\n#endif\n\nTEST(MemorySanitizer, scanf) {\n  const char *input = \"42 hello\";\n  int* d = new int;\n  char* s = new char[7];\n  int res = sscanf(input, \"%d %5s\", d, s);\n  printf(\"res %d\\n\", res);\n  ASSERT_EQ(res, 2);\n  EXPECT_NOT_POISONED(*d);\n  EXPECT_NOT_POISONED(s[0]);\n  EXPECT_NOT_POISONED(s[1]);\n  EXPECT_NOT_POISONED(s[2]);\n  EXPECT_NOT_POISONED(s[3]);\n  EXPECT_NOT_POISONED(s[4]);\n  EXPECT_NOT_POISONED(s[5]);\n  EXPECT_POISONED(s[6]);\n  delete[] s;\n  delete d;\n}\n\nstatic void *SimpleThread_threadfn(void* data) {\n  return new int;\n}\n\nTEST(MemorySanitizer, SimpleThread) {\n  pthread_t t;\n  void *p;\n  int res = pthread_create(&t, NULL, SimpleThread_threadfn, NULL);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(t);\n  res = pthread_join(t, &p);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(p);\n  delete (int*)p;\n}\n\nstatic void *SmallStackThread_threadfn(void* data) {\n  return 0;\n}\n\nTEST(MemorySanitizer, SmallStackThread) {\n  pthread_attr_t attr;\n  pthread_t t;\n  void *p;\n  int res;\n  res = pthread_attr_init(&attr);\n  ASSERT_EQ(0, res);\n  res = pthread_attr_setstacksize(&attr, 64 * 1024);\n  ASSERT_EQ(0, res);\n  res = pthread_create(&t, &attr, SmallStackThread_threadfn, NULL);\n  ASSERT_EQ(0, res);\n  res = pthread_join(t, &p);\n  ASSERT_EQ(0, res);\n  res = pthread_attr_destroy(&attr);\n  ASSERT_EQ(0, res);\n}\n\nTEST(MemorySanitizer, SmallPreAllocatedStackThread) {\n  pthread_attr_t attr;\n  pthread_t t;\n  int res;\n  res = pthread_attr_init(&attr);\n  ASSERT_EQ(0, res);\n  void *stack;\n  const size_t kStackSize = 16 * 1024;\n  res = posix_memalign(&stack, 4096, kStackSize);\n  ASSERT_EQ(0, res);\n  res = pthread_attr_setstack(&attr, stack, kStackSize);\n  ASSERT_EQ(0, res);\n  res = pthread_create(&t, &attr, SmallStackThread_threadfn, NULL);\n  EXPECT_EQ(0, res);\n  res = pthread_join(t, NULL);\n  ASSERT_EQ(0, res);\n  res = pthread_attr_destroy(&attr);\n  ASSERT_EQ(0, res);\n}\n\nTEST(MemorySanitizer, pthread_attr_get) {\n  pthread_attr_t attr;\n  int res;\n  res = pthread_attr_init(&attr);\n  ASSERT_EQ(0, res);\n  {\n    int v;\n    res = pthread_attr_getdetachstate(&attr, &v);\n    ASSERT_EQ(0, res);\n    EXPECT_NOT_POISONED(v);\n  }\n  {\n    size_t v;\n    res = pthread_attr_getguardsize(&attr, &v);\n    ASSERT_EQ(0, res);\n    EXPECT_NOT_POISONED(v);\n  }\n  {\n    struct sched_param v;\n    res = pthread_attr_getschedparam(&attr, &v);\n    ASSERT_EQ(0, res);\n    EXPECT_NOT_POISONED(v);\n  }\n  {\n    int v;\n    res = pthread_attr_getschedpolicy(&attr, &v);\n    ASSERT_EQ(0, res);\n    EXPECT_NOT_POISONED(v);\n  }\n  {\n    int v;\n    res = pthread_attr_getinheritsched(&attr, &v);\n    ASSERT_EQ(0, res);\n    EXPECT_NOT_POISONED(v);\n  }\n  {\n    int v;\n    res = pthread_attr_getscope(&attr, &v);\n    ASSERT_EQ(0, res);\n    EXPECT_NOT_POISONED(v);\n  }\n  {\n    size_t v;\n    res = pthread_attr_getstacksize(&attr, &v);\n    ASSERT_EQ(0, res);\n    EXPECT_NOT_POISONED(v);\n  }\n  {\n    void *v;\n    size_t w;\n    res = pthread_attr_getstack(&attr, &v, &w);\n    ASSERT_EQ(0, res);\n    EXPECT_NOT_POISONED(v);\n    EXPECT_NOT_POISONED(w);\n  }\n  {\n    cpu_set_t v;\n    res = pthread_attr_getaffinity_np(&attr, sizeof(v), &v);\n    ASSERT_EQ(0, res);\n    EXPECT_NOT_POISONED(v);\n  }\n  res = pthread_attr_destroy(&attr);\n  ASSERT_EQ(0, res);\n}\n\nTEST(MemorySanitizer, pthread_getschedparam) {\n  int policy;\n  struct sched_param param;\n  int res = pthread_getschedparam(pthread_self(), &policy, &param);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(policy);\n  EXPECT_NOT_POISONED(param.sched_priority);\n}\n\nTEST(MemorySanitizer, pthread_key_create) {\n  pthread_key_t key;\n  int res = pthread_key_create(&key, NULL);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(key);\n  res = pthread_key_delete(key);\n  ASSERT_EQ(0, res);\n}\n\nnamespace {\nstruct SignalCondArg {\n  pthread_cond_t* cond;\n  pthread_mutex_t* mu;\n  bool broadcast;\n};\n\nvoid *SignalCond(void *param) {\n  SignalCondArg *arg = reinterpret_cast<SignalCondArg *>(param);\n  pthread_mutex_lock(arg->mu);\n  if (arg->broadcast)\n    pthread_cond_broadcast(arg->cond);\n  else\n    pthread_cond_signal(arg->cond);\n  pthread_mutex_unlock(arg->mu);\n  return 0;\n}\n}  // namespace\n\nTEST(MemorySanitizer, pthread_cond_wait) {\n  pthread_cond_t cond;\n  pthread_mutex_t mu;\n  SignalCondArg args = {&cond, &mu, false};\n  pthread_cond_init(&cond, 0);\n  pthread_mutex_init(&mu, 0);\n  pthread_mutex_lock(&mu);\n\n  // signal\n  pthread_t thr;\n  pthread_create(&thr, 0, SignalCond, &args);\n  int res = pthread_cond_wait(&cond, &mu);\n  ASSERT_EQ(0, res);\n  pthread_join(thr, 0);\n\n  // broadcast\n  args.broadcast = true;\n  pthread_create(&thr, 0, SignalCond, &args);\n  res = pthread_cond_wait(&cond, &mu);\n  ASSERT_EQ(0, res);\n  pthread_join(thr, 0);\n\n  pthread_mutex_unlock(&mu);\n  pthread_mutex_destroy(&mu);\n  pthread_cond_destroy(&cond);\n}\n\nTEST(MemorySanitizer, tmpnam) {\n  char s[L_tmpnam];\n  char *res = tmpnam(s);\n  ASSERT_EQ(s, res);\n  EXPECT_NOT_POISONED(strlen(res));\n}\n\nTEST(MemorySanitizer, tempnam) {\n  char *res = tempnam(NULL, \"zzz\");\n  EXPECT_NOT_POISONED(strlen(res));\n  free(res);\n}\n\nTEST(MemorySanitizer, posix_memalign) {\n  void *p;\n  EXPECT_POISONED(p);\n  int res = posix_memalign(&p, 4096, 13);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(p);\n  EXPECT_EQ(0U, (uintptr_t)p % 4096);\n  free(p);\n}\n\n// There's no memalign() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, memalign) {\n  void *p = memalign(4096, 13);\n  EXPECT_EQ(0U, (uintptr_t)p % kPageSize);\n  free(p);\n}\n#endif\n\nTEST(MemorySanitizer, valloc) {\n  void *a = valloc(100);\n  EXPECT_EQ(0U, (uintptr_t)a % kPageSize);\n  free(a);\n}\n\n// There's no pvalloc() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, pvalloc) {\n  void *p = pvalloc(kPageSize + 100);\n  EXPECT_EQ(0U, (uintptr_t)p % kPageSize);\n  EXPECT_EQ(2 * kPageSize, __sanitizer_get_allocated_size(p));\n  free(p);\n\n  p = pvalloc(0);  // pvalloc(0) should allocate at least one page.\n  EXPECT_EQ(0U, (uintptr_t)p % kPageSize);\n  EXPECT_EQ(kPageSize, __sanitizer_get_allocated_size(p));\n  free(p);\n}\n#endif\n\nTEST(MemorySanitizer, inet_pton) {\n  const char *s = \"1:0:0:0:0:0:0:8\";\n  unsigned char buf[sizeof(struct in6_addr)];\n  int res = inet_pton(AF_INET6, s, buf);\n  ASSERT_EQ(1, res);\n  EXPECT_NOT_POISONED(buf[0]);\n  EXPECT_NOT_POISONED(buf[sizeof(struct in6_addr) - 1]);\n\n  char s_out[INET6_ADDRSTRLEN];\n  EXPECT_POISONED(s_out[3]);\n  const char *q = inet_ntop(AF_INET6, buf, s_out, INET6_ADDRSTRLEN);\n  ASSERT_NE((void*)0, q);\n  EXPECT_NOT_POISONED(s_out[3]);\n}\n\nTEST(MemorySanitizer, inet_aton) {\n  const char *s = \"127.0.0.1\";\n  struct in_addr in[2];\n  int res = inet_aton(s, in);\n  ASSERT_NE(0, res);\n  EXPECT_NOT_POISONED(in[0]);\n  EXPECT_POISONED(*(char *)(in + 1));\n}\n\nTEST(MemorySanitizer, uname) {\n  struct utsname u;\n  int res = uname(&u);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(strlen(u.sysname));\n  EXPECT_NOT_POISONED(strlen(u.nodename));\n  EXPECT_NOT_POISONED(strlen(u.release));\n  EXPECT_NOT_POISONED(strlen(u.version));\n  EXPECT_NOT_POISONED(strlen(u.machine));\n}\n\nTEST(MemorySanitizer, gethostname) {\n  char buf[100];\n  int res = gethostname(buf, 100);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(strlen(buf));\n}\n\n// There's no sysinfo() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, sysinfo) {\n  struct sysinfo info;\n  int res = sysinfo(&info);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(info);\n}\n#endif\n\nTEST(MemorySanitizer, getpwuid) {\n  struct passwd *p = getpwuid(0); // root\n  ASSERT_TRUE(p != NULL);\n  EXPECT_NOT_POISONED(p->pw_name);\n  ASSERT_TRUE(p->pw_name != NULL);\n  EXPECT_NOT_POISONED(p->pw_name[0]);\n  EXPECT_NOT_POISONED(p->pw_uid);\n  ASSERT_EQ(0U, p->pw_uid);\n}\n\nTEST(MemorySanitizer, getpwuid_r) {\n  struct passwd pwd;\n  struct passwd *pwdres;\n  char buf[10000];\n  int res = getpwuid_r(0, &pwd, buf, sizeof(buf), &pwdres);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(pwd.pw_name);\n  ASSERT_TRUE(pwd.pw_name != NULL);\n  EXPECT_NOT_POISONED(pwd.pw_name[0]);\n  EXPECT_NOT_POISONED(pwd.pw_uid);\n  ASSERT_EQ(0U, pwd.pw_uid);\n  EXPECT_NOT_POISONED(pwdres);\n}\n\nTEST(MemorySanitizer, getpwnam_r) {\n  struct passwd pwd;\n  struct passwd *pwdres;\n  char buf[10000];\n  int res = getpwnam_r(\"root\", &pwd, buf, sizeof(buf), &pwdres);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(pwd.pw_name);\n  ASSERT_TRUE(pwd.pw_name != NULL);\n  EXPECT_NOT_POISONED(pwd.pw_name[0]);\n  EXPECT_NOT_POISONED(pwd.pw_uid);\n  ASSERT_EQ(0U, pwd.pw_uid);\n  EXPECT_NOT_POISONED(pwdres);\n}\n\nTEST(MemorySanitizer, getpwnam_r_positive) {\n  struct passwd pwd;\n  struct passwd *pwdres;\n  char s[5];\n  strncpy(s, \"abcd\", 5);\n  __msan_poison(s, 5);\n  char buf[10000];\n  int res;\n  EXPECT_UMR(res = getpwnam_r(s, &pwd, buf, sizeof(buf), &pwdres));\n}\n\nTEST(MemorySanitizer, getgrnam_r) {\n  struct group grp;\n  struct group *grpres;\n  char buf[10000];\n  int res = getgrnam_r(SUPERUSER_GROUP, &grp, buf, sizeof(buf), &grpres);\n  ASSERT_EQ(0, res);\n  // Note that getgrnam_r() returns 0 if the matching group is not found.\n  ASSERT_NE(nullptr, grpres);\n  EXPECT_NOT_POISONED(grp.gr_name);\n  ASSERT_TRUE(grp.gr_name != NULL);\n  EXPECT_NOT_POISONED(grp.gr_name[0]);\n  EXPECT_NOT_POISONED(grp.gr_gid);\n  EXPECT_NOT_POISONED(grpres);\n}\n\nTEST(MemorySanitizer, getpwent) {\n  setpwent();\n  struct passwd *p = getpwent();\n  ASSERT_TRUE(p != NULL);\n  EXPECT_NOT_POISONED(p->pw_name);\n  ASSERT_TRUE(p->pw_name != NULL);\n  EXPECT_NOT_POISONED(p->pw_name[0]);\n  EXPECT_NOT_POISONED(p->pw_uid);\n}\n\nTEST(MemorySanitizer, getpwent_r) {\n  struct passwd pwd;\n  struct passwd *pwdres;\n  char buf[10000];\n  setpwent();\n  int res = getpwent_r(&pwd, buf, sizeof(buf), &pwdres);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(pwd.pw_name);\n  ASSERT_TRUE(pwd.pw_name != NULL);\n  EXPECT_NOT_POISONED(pwd.pw_name[0]);\n  EXPECT_NOT_POISONED(pwd.pw_uid);\n  EXPECT_NOT_POISONED(pwdres);\n}\n\n// There's no fgetpwent() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, fgetpwent) {\n  FILE *fp = fopen(\"/etc/passwd\", \"r\");\n  struct passwd *p = fgetpwent(fp);\n  ASSERT_TRUE(p != NULL);\n  EXPECT_NOT_POISONED(p->pw_name);\n  ASSERT_TRUE(p->pw_name != NULL);\n  EXPECT_NOT_POISONED(p->pw_name[0]);\n  EXPECT_NOT_POISONED(p->pw_uid);\n  fclose(fp);\n}\n#endif\n\nTEST(MemorySanitizer, getgrent) {\n  setgrent();\n  struct group *p = getgrent();\n  ASSERT_TRUE(p != NULL);\n  EXPECT_NOT_POISONED(p->gr_name);\n  ASSERT_TRUE(p->gr_name != NULL);\n  EXPECT_NOT_POISONED(p->gr_name[0]);\n  EXPECT_NOT_POISONED(p->gr_gid);\n}\n\n// There's no fgetgrent() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, fgetgrent) {\n  FILE *fp = fopen(\"/etc/group\", \"r\");\n  struct group *grp = fgetgrent(fp);\n  ASSERT_TRUE(grp != NULL);\n  EXPECT_NOT_POISONED(grp->gr_name);\n  ASSERT_TRUE(grp->gr_name != NULL);\n  EXPECT_NOT_POISONED(grp->gr_name[0]);\n  EXPECT_NOT_POISONED(grp->gr_gid);\n  for (char **p = grp->gr_mem; *p; ++p) {\n    EXPECT_NOT_POISONED((*p)[0]);\n    EXPECT_TRUE(strlen(*p) > 0);\n  }\n  fclose(fp);\n}\n#endif\n\nTEST(MemorySanitizer, getgrent_r) {\n  struct group grp;\n  struct group *grpres;\n  char buf[10000];\n  setgrent();\n  int res = getgrent_r(&grp, buf, sizeof(buf), &grpres);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(grp.gr_name);\n  ASSERT_TRUE(grp.gr_name != NULL);\n  EXPECT_NOT_POISONED(grp.gr_name[0]);\n  EXPECT_NOT_POISONED(grp.gr_gid);\n  EXPECT_NOT_POISONED(grpres);\n}\n\n// There's no fgetgrent_r() on FreeBSD.\n#if !defined(__FreeBSD__)\nTEST(MemorySanitizer, fgetgrent_r) {\n  FILE *fp = fopen(\"/etc/group\", \"r\");\n  struct group grp;\n  struct group *grpres;\n  char buf[10000];\n  setgrent();\n  int res = fgetgrent_r(fp, &grp, buf, sizeof(buf), &grpres);\n  ASSERT_EQ(0, res);\n  EXPECT_NOT_POISONED(grp.gr_name);\n  ASSERT_TRUE(grp.gr_name != NULL);\n  EXPECT_NOT_POISONED(grp.gr_name[0]);\n  EXPECT_NOT_POISONED(grp.gr_gid);\n  EXPECT_NOT_POISONED(grpres);\n  fclose(fp);\n}\n#endif\n\nTEST(MemorySanitizer, getgroups) {\n  int n = getgroups(0, 0);\n  gid_t *gids = new gid_t[n];\n  int res = getgroups(n, gids);\n  ASSERT_EQ(n, res);\n  for (int i = 0; i < n; ++i)\n    EXPECT_NOT_POISONED(gids[i]);\n}\n\nTEST(MemorySanitizer, wordexp) {\n  wordexp_t w;\n  int res = wordexp(\"a b c\", &w, 0);\n  ASSERT_EQ(0, res);\n  ASSERT_EQ(3U, w.we_wordc);\n  ASSERT_STREQ(\"a\", w.we_wordv[0]);\n  ASSERT_STREQ(\"b\", w.we_wordv[1]);\n  ASSERT_STREQ(\"c\", w.we_wordv[2]);\n}\n\ntemplate<class T>\nstatic bool applySlt(T value, T shadow) {\n  __msan_partial_poison(&value, &shadow, sizeof(T));\n  volatile bool zzz = true;\n  // This \"|| zzz\" trick somehow makes LLVM emit \"icmp slt\" instead of\n  // a shift-and-trunc to get at the highest bit.\n  volatile bool v = value < 0 || zzz;\n  return v;\n}\n\nTEST(MemorySanitizer, SignedCompareWithZero) {\n  EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xF));\n  EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xFF));\n  EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xFFFFFF));\n  EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0x7FFFFFF));\n  EXPECT_UMR(applySlt<S4>(0xF, 0x80FFFFFF));\n  EXPECT_UMR(applySlt<S4>(0xF, 0xFFFFFFFF));\n}\n\ntemplate <class T, class S>\nstatic T poisoned(T Va, S Sa) {\n  char SIZE_CHECK1[(ssize_t)sizeof(T) - (ssize_t)sizeof(S)];\n  char SIZE_CHECK2[(ssize_t)sizeof(S) - (ssize_t)sizeof(T)];\n  T a;\n  a = Va;\n  __msan_partial_poison(&a, &Sa, sizeof(T));\n  return a;\n}\n\nTEST(MemorySanitizer, ICmpRelational) {\n  EXPECT_NOT_POISONED(poisoned(0, 0) < poisoned(0, 0));\n  EXPECT_NOT_POISONED(poisoned(0U, 0) < poisoned(0U, 0));\n  EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) < poisoned(0LL, 0LLU));\n  EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) < poisoned(0LLU, 0LLU));\n  EXPECT_POISONED(poisoned(0xFF, 0xFF) < poisoned(0xFF, 0xFF));\n  EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) <\n                  poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));\n  EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) <\n                  poisoned(-1, 0xFFFFFFFFU));\n\n  EXPECT_NOT_POISONED(poisoned(0, 0) <= poisoned(0, 0));\n  EXPECT_NOT_POISONED(poisoned(0U, 0) <= poisoned(0U, 0));\n  EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) <= poisoned(0LL, 0LLU));\n  EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) <= poisoned(0LLU, 0LLU));\n  EXPECT_POISONED(poisoned(0xFF, 0xFF) <= poisoned(0xFF, 0xFF));\n  EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) <=\n                  poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));\n  EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) <=\n                  poisoned(-1, 0xFFFFFFFFU));\n\n  EXPECT_NOT_POISONED(poisoned(0, 0) > poisoned(0, 0));\n  EXPECT_NOT_POISONED(poisoned(0U, 0) > poisoned(0U, 0));\n  EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) > poisoned(0LL, 0LLU));\n  EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) > poisoned(0LLU, 0LLU));\n  EXPECT_POISONED(poisoned(0xFF, 0xFF) > poisoned(0xFF, 0xFF));\n  EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) >\n                  poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));\n  EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) >\n                  poisoned(-1, 0xFFFFFFFFU));\n\n  EXPECT_NOT_POISONED(poisoned(0, 0) >= poisoned(0, 0));\n  EXPECT_NOT_POISONED(poisoned(0U, 0) >= poisoned(0U, 0));\n  EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) >= poisoned(0LL, 0LLU));\n  EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) >= poisoned(0LLU, 0LLU));\n  EXPECT_POISONED(poisoned(0xFF, 0xFF) >= poisoned(0xFF, 0xFF));\n  EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) >=\n                  poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));\n  EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) >=\n                  poisoned(-1, 0xFFFFFFFFU));\n\n  EXPECT_POISONED(poisoned(6, 0xF) > poisoned(7, 0));\n  EXPECT_POISONED(poisoned(0xF, 0xF) > poisoned(7, 0));\n\n  EXPECT_NOT_POISONED(poisoned(-1, 0x80000000U) >= poisoned(-1, 0U));\n}\n\n#if MSAN_HAS_M128\nTEST(MemorySanitizer, ICmpVectorRelational) {\n  EXPECT_NOT_POISONED(\n      _mm_cmplt_epi16(poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0)),\n                   poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0))));\n  EXPECT_NOT_POISONED(\n      _mm_cmplt_epi16(poisoned(_mm_set1_epi32(0), _mm_set1_epi32(0)),\n                   poisoned(_mm_set1_epi32(0), _mm_set1_epi32(0))));\n  EXPECT_POISONED(\n      _mm_cmplt_epi16(poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0xFFFF)),\n                   poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0xFFFF))));\n  EXPECT_POISONED(_mm_cmpgt_epi16(poisoned(_mm_set1_epi16(6), _mm_set1_epi16(0xF)),\n                               poisoned(_mm_set1_epi16(7), _mm_set1_epi16(0))));\n}\n#endif\n\n// Volatile bitfield store is implemented as load-mask-store\n// Test that we don't warn on the store of (uninitialized) padding.\nstruct VolatileBitfieldStruct {\n  volatile unsigned x : 1;\n  unsigned y : 1;\n};\n\nTEST(MemorySanitizer, VolatileBitfield) {\n  VolatileBitfieldStruct *S = new VolatileBitfieldStruct;\n  S->x = 1;\n  EXPECT_NOT_POISONED((unsigned)S->x);\n  EXPECT_POISONED((unsigned)S->y);\n}\n\nTEST(MemorySanitizer, UnalignedLoad) {\n  char x[32] __attribute__((aligned(8)));\n  U4 origin = __LINE__;\n  for (unsigned i = 0; i < sizeof(x) / 4; ++i)\n    __msan_set_origin(x + 4 * i, 4, origin + i);\n\n  memset(x + 8, 0, 16);\n  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 6), origin + 1);\n  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 7), origin + 1);\n  EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x + 8));\n  EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x + 9));\n  EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x + 22));\n  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 23), origin + 6);\n  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 24), origin + 6);\n\n  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 4), origin + 1);\n  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 7), origin + 1);\n  EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x + 8));\n  EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x + 9));\n  EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x + 20));\n  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 21), origin + 6);\n  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 24), origin + 6);\n\n  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x), origin);\n  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x + 1), origin);\n  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x + 7), origin + 1);\n  EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x + 8));\n  EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x + 9));\n  EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x + 16));\n  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x + 17), origin + 6);\n  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x + 21), origin + 6);\n  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x + 24), origin + 6);\n}\n\nTEST(MemorySanitizer, UnalignedStore16) {\n  char x[5] __attribute__((aligned(4)));\n  U2 y2 = 0;\n  U4 origin = __LINE__;\n  __msan_poison(&y2, 1);\n  __msan_set_origin(&y2, 1, origin);\n\n  __sanitizer_unaligned_store16(x + 1, y2);\n  EXPECT_POISONED_O(x[0], origin);\n  EXPECT_POISONED_O(x[1], origin);\n  EXPECT_NOT_POISONED(x[2]);\n  EXPECT_POISONED_O(x[3], origin);\n}\n\nTEST(MemorySanitizer, UnalignedStore32) {\n  char x[8] __attribute__((aligned(4)));\n  U4 y4 = 0;\n  U4 origin = __LINE__;\n  __msan_poison(&y4, 2);\n  __msan_set_origin(&y4, 2, origin);\n\n  __sanitizer_unaligned_store32(x + 3, y4);\n  EXPECT_POISONED_O(x[0], origin);\n  EXPECT_POISONED_O(x[1], origin);\n  EXPECT_POISONED_O(x[2], origin);\n  EXPECT_POISONED_O(x[3], origin);\n  EXPECT_POISONED_O(x[4], origin);\n  EXPECT_NOT_POISONED(x[5]);\n  EXPECT_NOT_POISONED(x[6]);\n  EXPECT_POISONED_O(x[7], origin);\n}\n\nTEST(MemorySanitizer, UnalignedStore64) {\n  char x[16] __attribute__((aligned(8)));\n  U8 y8 = 0;\n  U4 origin = __LINE__;\n  __msan_poison(&y8, 3);\n  __msan_poison(((char *)&y8) + sizeof(y8) - 2, 1);\n  __msan_set_origin(&y8, 8, origin);\n\n  __sanitizer_unaligned_store64(x + 3, y8);\n  EXPECT_POISONED_O(x[0], origin);\n  EXPECT_POISONED_O(x[1], origin);\n  EXPECT_POISONED_O(x[2], origin);\n  EXPECT_POISONED_O(x[3], origin);\n  EXPECT_POISONED_O(x[4], origin);\n  EXPECT_POISONED_O(x[5], origin);\n  EXPECT_NOT_POISONED(x[6]);\n  EXPECT_NOT_POISONED(x[7]);\n  EXPECT_NOT_POISONED(x[8]);\n  EXPECT_POISONED_O(x[9], origin);\n  EXPECT_NOT_POISONED(x[10]);\n  EXPECT_POISONED_O(x[11], origin);\n}\n\nTEST(MemorySanitizer, UnalignedStore16_precise) {\n  char x[8] __attribute__((aligned(4)));\n  U2 y = 0;\n  U4 originx1 = __LINE__;\n  U4 originx2 = __LINE__;\n  U4 originy = __LINE__;\n  __msan_poison(x, sizeof(x));\n  __msan_set_origin(x, 4, originx1);\n  __msan_set_origin(x + 4, 4, originx2);\n  __msan_poison(((char *)&y) + 1, 1);\n  __msan_set_origin(&y, sizeof(y), originy);\n\n  __sanitizer_unaligned_store16(x + 3, y);\n  EXPECT_POISONED_O(x[0], originx1);\n  EXPECT_POISONED_O(x[1], originx1);\n  EXPECT_POISONED_O(x[2], originx1);\n  EXPECT_NOT_POISONED(x[3]);\n  EXPECT_POISONED_O(x[4], originy);\n  EXPECT_POISONED_O(x[5], originy);\n  EXPECT_POISONED_O(x[6], originy);\n  EXPECT_POISONED_O(x[7], originy);\n}\n\nTEST(MemorySanitizer, UnalignedStore16_precise2) {\n  char x[8] __attribute__((aligned(4)));\n  U2 y = 0;\n  U4 originx1 = __LINE__;\n  U4 originx2 = __LINE__;\n  U4 originy = __LINE__;\n  __msan_poison(x, sizeof(x));\n  __msan_set_origin(x, 4, originx1);\n  __msan_set_origin(x + 4, 4, originx2);\n  __msan_poison(((char *)&y), 1);\n  __msan_set_origin(&y, sizeof(y), originy);\n\n  __sanitizer_unaligned_store16(x + 3, y);\n  EXPECT_POISONED_O(x[0], originy);\n  EXPECT_POISONED_O(x[1], originy);\n  EXPECT_POISONED_O(x[2], originy);\n  EXPECT_POISONED_O(x[3], originy);\n  EXPECT_NOT_POISONED(x[4]);\n  EXPECT_POISONED_O(x[5], originx2);\n  EXPECT_POISONED_O(x[6], originx2);\n  EXPECT_POISONED_O(x[7], originx2);\n}\n\nTEST(MemorySanitizer, UnalignedStore64_precise) {\n  char x[12] __attribute__((aligned(8)));\n  U8 y = 0;\n  U4 originx1 = __LINE__;\n  U4 originx2 = __LINE__;\n  U4 originx3 = __LINE__;\n  U4 originy = __LINE__;\n  __msan_poison(x, sizeof(x));\n  __msan_set_origin(x, 4, originx1);\n  __msan_set_origin(x + 4, 4, originx2);\n  __msan_set_origin(x + 8, 4, originx3);\n  __msan_poison(((char *)&y) + 1, 1);\n  __msan_poison(((char *)&y) + 7, 1);\n  __msan_set_origin(&y, sizeof(y), originy);\n\n  __sanitizer_unaligned_store64(x + 2, y);\n  EXPECT_POISONED_O(x[0], originy);\n  EXPECT_POISONED_O(x[1], originy);\n  EXPECT_NOT_POISONED(x[2]);\n  EXPECT_POISONED_O(x[3], originy);\n\n  EXPECT_NOT_POISONED(x[4]);\n  EXPECT_NOT_POISONED(x[5]);\n  EXPECT_NOT_POISONED(x[6]);\n  EXPECT_NOT_POISONED(x[7]);\n\n  EXPECT_NOT_POISONED(x[8]);\n  EXPECT_POISONED_O(x[9], originy);\n  EXPECT_POISONED_O(x[10], originy);\n  EXPECT_POISONED_O(x[11], originy);\n}\n\nTEST(MemorySanitizer, UnalignedStore64_precise2) {\n  char x[12] __attribute__((aligned(8)));\n  U8 y = 0;\n  U4 originx1 = __LINE__;\n  U4 originx2 = __LINE__;\n  U4 originx3 = __LINE__;\n  U4 originy = __LINE__;\n  __msan_poison(x, sizeof(x));\n  __msan_set_origin(x, 4, originx1);\n  __msan_set_origin(x + 4, 4, originx2);\n  __msan_set_origin(x + 8, 4, originx3);\n  __msan_poison(((char *)&y) + 3, 3);\n  __msan_set_origin(&y, sizeof(y), originy);\n\n  __sanitizer_unaligned_store64(x + 2, y);\n  EXPECT_POISONED_O(x[0], originx1);\n  EXPECT_POISONED_O(x[1], originx1);\n  EXPECT_NOT_POISONED(x[2]);\n  EXPECT_NOT_POISONED(x[3]);\n\n  EXPECT_NOT_POISONED(x[4]);\n  EXPECT_POISONED_O(x[5], originy);\n  EXPECT_POISONED_O(x[6], originy);\n  EXPECT_POISONED_O(x[7], originy);\n\n  EXPECT_NOT_POISONED(x[8]);\n  EXPECT_NOT_POISONED(x[9]);\n  EXPECT_POISONED_O(x[10], originx3);\n  EXPECT_POISONED_O(x[11], originx3);\n}\n\n#if (defined(__x86_64__) && defined(__clang__))\nnamespace {\ntypedef U1 V16x8 __attribute__((__vector_size__(16)));\ntypedef U2 V8x16 __attribute__((__vector_size__(16)));\ntypedef U4 V4x32 __attribute__((__vector_size__(16)));\ntypedef U8 V2x64 __attribute__((__vector_size__(16)));\ntypedef U4 V8x32 __attribute__((__vector_size__(32)));\ntypedef U8 V4x64 __attribute__((__vector_size__(32)));\ntypedef U4 V2x32 __attribute__((__vector_size__(8)));\ntypedef U2 V4x16 __attribute__((__vector_size__(8)));\ntypedef U1 V8x8 __attribute__((__vector_size__(8)));\n\n\nV8x16 shift_sse2_left_scalar(V8x16 x, U4 y) {\n  return _mm_slli_epi16(x, y);\n}\n\nV8x16 shift_sse2_left(V8x16 x, V8x16 y) {\n  return _mm_sll_epi16(x, y);\n}\n\nTEST(VectorShiftTest, sse2_left_scalar) {\n  V8x16 v = {Poisoned<U2>(0, 3), Poisoned<U2>(0, 7), 2, 3, 4, 5, 6, 7};\n  V8x16 u = shift_sse2_left_scalar(v, 2);\n  EXPECT_POISONED(u[0]);\n  EXPECT_POISONED(u[1]);\n  EXPECT_NOT_POISONED(u[0] | (3U << 2));\n  EXPECT_NOT_POISONED(u[1] | (7U << 2));\n  u[0] = u[1] = 0;\n  EXPECT_NOT_POISONED(u);\n}\n\nTEST(VectorShiftTest, sse2_left_scalar_by_uninit) {\n  V8x16 v = {0, 1, 2, 3, 4, 5, 6, 7};\n  V8x16 u = shift_sse2_left_scalar(v, Poisoned<U4>());\n  EXPECT_POISONED(u[0]);\n  EXPECT_POISONED(u[1]);\n  EXPECT_POISONED(u[2]);\n  EXPECT_POISONED(u[3]);\n  EXPECT_POISONED(u[4]);\n  EXPECT_POISONED(u[5]);\n  EXPECT_POISONED(u[6]);\n  EXPECT_POISONED(u[7]);\n}\n\nTEST(VectorShiftTest, sse2_left) {\n  V8x16 v = {Poisoned<U2>(0, 3), Poisoned<U2>(0, 7), 2, 3, 4, 5, 6, 7};\n  // Top 64 bits of shift count don't affect the result.\n  V2x64 s = {2, Poisoned<U8>()};\n  V8x16 u = shift_sse2_left(v, s);\n  EXPECT_POISONED(u[0]);\n  EXPECT_POISONED(u[1]);\n  EXPECT_NOT_POISONED(u[0] | (3U << 2));\n  EXPECT_NOT_POISONED(u[1] | (7U << 2));\n  u[0] = u[1] = 0;\n  EXPECT_NOT_POISONED(u);\n}\n\nTEST(VectorShiftTest, sse2_left_by_uninit) {\n  V8x16 v = {Poisoned<U2>(0, 3), Poisoned<U2>(0, 7), 2, 3, 4, 5, 6, 7};\n  V2x64 s = {Poisoned<U8>(), Poisoned<U8>()};\n  V8x16 u = shift_sse2_left(v, s);\n  EXPECT_POISONED(u[0]);\n  EXPECT_POISONED(u[1]);\n  EXPECT_POISONED(u[2]);\n  EXPECT_POISONED(u[3]);\n  EXPECT_POISONED(u[4]);\n  EXPECT_POISONED(u[5]);\n  EXPECT_POISONED(u[6]);\n  EXPECT_POISONED(u[7]);\n}\n\n#ifdef __AVX2__\nV4x32 shift_avx2_left(V4x32 x, V4x32 y) {\n  return _mm_sllv_epi32(x, y);\n}\n// This is variable vector shift that's only available starting with AVX2.\n// V4x32 shift_avx2_left(V4x32 x, V4x32 y) {\nTEST(VectorShiftTest, avx2_left) {\n  V4x32 v = {Poisoned<U2>(0, 3), Poisoned<U2>(0, 7), 2, 3};\n  V4x32 s = {2, Poisoned<U4>(), 3, Poisoned<U4>()};\n  V4x32 u = shift_avx2_left(v, s);\n  EXPECT_POISONED(u[0]);\n  EXPECT_NOT_POISONED(u[0] | (~7U));\n  EXPECT_POISONED(u[1]);\n  EXPECT_POISONED(u[1] | (~31U));\n  EXPECT_NOT_POISONED(u[2]);\n  EXPECT_POISONED(u[3]);\n  EXPECT_POISONED(u[3] | (~31U));\n}\n#endif // __AVX2__\n} // namespace\n\nTEST(VectorPackTest, sse2_packssdw_128) {\n  const unsigned S2_max = (1 << 15) - 1;\n  V4x32 a = {Poisoned<U4>(0, 0xFF0000), Poisoned<U4>(0, 0xFFFF0000),\n             S2_max + 100, 4};\n  V4x32 b = {Poisoned<U4>(0, 0xFF), S2_max + 10000, Poisoned<U4>(0, 0xFF00),\n             S2_max};\n\n  V8x16 c = _mm_packs_epi32(a, b);\n\n  EXPECT_POISONED(c[0]);\n  EXPECT_POISONED(c[1]);\n  EXPECT_NOT_POISONED(c[2]);\n  EXPECT_NOT_POISONED(c[3]);\n  EXPECT_POISONED(c[4]);\n  EXPECT_NOT_POISONED(c[5]);\n  EXPECT_POISONED(c[6]);\n  EXPECT_NOT_POISONED(c[7]);\n\n  EXPECT_EQ(c[2], S2_max);\n  EXPECT_EQ(c[3], 4);\n  EXPECT_EQ(c[5], S2_max);\n  EXPECT_EQ(c[7], S2_max);\n}\n\nTEST(VectorPackTest, mmx_packuswb) {\n  const unsigned U1_max = (1 << 8) - 1;\n  V4x16 a = {Poisoned<U2>(0, 0xFF00), Poisoned<U2>(0, 0xF000U), U1_max + 100,\n             4};\n  V4x16 b = {Poisoned<U2>(0, 0xFF), U1_max - 1, Poisoned<U2>(0, 0xF), U1_max};\n  V8x8 c = _mm_packs_pu16(a, b);\n\n  EXPECT_POISONED(c[0]);\n  EXPECT_POISONED(c[1]);\n  EXPECT_NOT_POISONED(c[2]);\n  EXPECT_NOT_POISONED(c[3]);\n  EXPECT_POISONED(c[4]);\n  EXPECT_NOT_POISONED(c[5]);\n  EXPECT_POISONED(c[6]);\n  EXPECT_NOT_POISONED(c[7]);\n\n  EXPECT_EQ(c[2], U1_max);\n  EXPECT_EQ(c[3], 4);\n  EXPECT_EQ(c[5], U1_max - 1);\n  EXPECT_EQ(c[7], U1_max);\n}\n\nTEST(VectorSadTest, sse2_psad_bw) {\n  V16x8 a = {Poisoned<U1>(), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};\n  V16x8 b = {100, 101, 102, 103, 104, 105, 106, 107,\n             108, 109, 110, 111, 112, 113, 114, 115};\n  V2x64 c = _mm_sad_epu8(a, b);\n\n  EXPECT_POISONED(c[0]);\n  EXPECT_NOT_POISONED(c[1]);\n\n  EXPECT_EQ(800U, c[1]);\n}\n\nTEST(VectorMaddTest, mmx_pmadd_wd) {\n  V4x16 a = {Poisoned<U2>(), 1, 2, 3};\n  V4x16 b = {100, 101, 102, 103};\n  V2x32 c = _mm_madd_pi16(a, b);\n\n  EXPECT_POISONED(c[0]);\n  EXPECT_NOT_POISONED(c[1]);\n\n  EXPECT_EQ((unsigned)(2 * 102 + 3 * 103), c[1]);\n}\n#endif  // defined(__clang__)\n\nTEST(MemorySanitizerOrigins, SetGet) {\n  EXPECT_EQ(TrackingOrigins(), !!__msan_get_track_origins());\n  if (!TrackingOrigins()) return;\n  int x;\n  __msan_set_origin(&x, sizeof(x), 1234);\n  EXPECT_ORIGIN(1234U, __msan_get_origin(&x));\n  __msan_set_origin(&x, sizeof(x), 5678);\n  EXPECT_ORIGIN(5678U, __msan_get_origin(&x));\n  __msan_set_origin(&x, sizeof(x), 0);\n  EXPECT_ORIGIN(0U, __msan_get_origin(&x));\n}\n\nnamespace {\nstruct S {\n  U4 dummy;\n  U2 a;\n  U2 b;\n};\n\nTEST(MemorySanitizerOrigins, InitializedStoreDoesNotChangeOrigin) {\n  if (!TrackingOrigins()) return;\n\n  S s;\n  U4 origin = rand();  // NOLINT\n  s.a = *GetPoisonedO<U2>(0, origin);\n  EXPECT_ORIGIN(origin, __msan_get_origin(&s.a));\n  EXPECT_ORIGIN(origin, __msan_get_origin(&s.b));\n\n  s.b = 42;\n  EXPECT_ORIGIN(origin, __msan_get_origin(&s.a));\n  EXPECT_ORIGIN(origin, __msan_get_origin(&s.b));\n}\n}  // namespace\n\ntemplate<class T, class BinaryOp>\nINLINE\nvoid BinaryOpOriginTest(BinaryOp op) {\n  U4 ox = rand();  //NOLINT\n  U4 oy = rand();  //NOLINT\n  T *x = GetPoisonedO<T>(0, ox, 0);\n  T *y = GetPoisonedO<T>(1, oy, 0);\n  T *z = GetPoisonedO<T>(2, 0, 0);\n\n  *z = op(*x, *y);\n  U4 origin = __msan_get_origin(z);\n  EXPECT_POISONED_O(*z, origin);\n  EXPECT_EQ(true, __msan_origin_is_descendant_or_same(origin, ox) ||\n                      __msan_origin_is_descendant_or_same(origin, oy));\n\n  // y is poisoned, x is not.\n  *x = 10101;\n  *y = *GetPoisonedO<T>(1, oy);\n  break_optimization(x);\n  __msan_set_origin(z, sizeof(*z), 0);\n  *z = op(*x, *y);\n  EXPECT_POISONED_O(*z, oy);\n  EXPECT_ORIGIN(oy, __msan_get_origin(z));\n\n  // x is poisoned, y is not.\n  *x = *GetPoisonedO<T>(0, ox);\n  *y = 10101010;\n  break_optimization(y);\n  __msan_set_origin(z, sizeof(*z), 0);\n  *z = op(*x, *y);\n  EXPECT_POISONED_O(*z, ox);\n  EXPECT_ORIGIN(ox, __msan_get_origin(z));\n}\n\ntemplate<class T> INLINE T XOR(const T &a, const T&b) { return a ^ b; }\ntemplate<class T> INLINE T ADD(const T &a, const T&b) { return a + b; }\ntemplate<class T> INLINE T SUB(const T &a, const T&b) { return a - b; }\ntemplate<class T> INLINE T MUL(const T &a, const T&b) { return a * b; }\ntemplate<class T> INLINE T AND(const T &a, const T&b) { return a & b; }\ntemplate<class T> INLINE T OR (const T &a, const T&b) { return a | b; }\n\nTEST(MemorySanitizerOrigins, BinaryOp) {\n  if (!TrackingOrigins()) return;\n  BinaryOpOriginTest<S8>(XOR<S8>);\n  BinaryOpOriginTest<U8>(ADD<U8>);\n  BinaryOpOriginTest<S4>(SUB<S4>);\n  BinaryOpOriginTest<S4>(MUL<S4>);\n  BinaryOpOriginTest<U4>(OR<U4>);\n  BinaryOpOriginTest<U4>(AND<U4>);\n  BinaryOpOriginTest<double>(ADD<U4>);\n  BinaryOpOriginTest<float>(ADD<S4>);\n  BinaryOpOriginTest<double>(ADD<double>);\n  BinaryOpOriginTest<float>(ADD<double>);\n}\n\nTEST(MemorySanitizerOrigins, Unary) {\n  if (!TrackingOrigins()) return;\n  EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);\n\n  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);\n\n  EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);\n\n  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);\n\n  EXPECT_POISONED_O((void*)*GetPoisonedO<S8>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O((U8)*GetPoisonedO<void*>(0, __LINE__), __LINE__);\n}\n\nTEST(MemorySanitizerOrigins, EQ) {\n  if (!TrackingOrigins()) return;\n  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__) <= 11, __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__) == 11, __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<float>(0, __LINE__) == 1.1, __LINE__);\n}\n\nTEST(MemorySanitizerOrigins, DIV) {\n  if (!TrackingOrigins()) return;\n  EXPECT_POISONED_O(*GetPoisonedO<U8>(0, __LINE__) / 100, __LINE__);\n  unsigned o = __LINE__;\n  EXPECT_UMR_O(volatile unsigned y = 100 / *GetPoisonedO<S4>(0, o, 1), o);\n}\n\nTEST(MemorySanitizerOrigins, SHIFT) {\n  if (!TrackingOrigins()) return;\n  EXPECT_POISONED_O(*GetPoisonedO<U8>(0, __LINE__) >> 10, __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__) >> 10, __LINE__);\n  EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__) << 10, __LINE__);\n  EXPECT_POISONED_O(10U << *GetPoisonedO<U8>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O(-10 >> *GetPoisonedO<S8>(0, __LINE__), __LINE__);\n  EXPECT_POISONED_O(-10 << *GetPoisonedO<S8>(0, __LINE__), __LINE__);\n}\n\ntemplate<class T, int N>\nvoid MemCpyTest() {\n  int ox = __LINE__;\n  T *x = new T[N];\n  T *y = new T[N];\n  T *z = new T[N];\n  T *q = new T[N];\n  __msan_poison(x, N * sizeof(T));\n  __msan_set_origin(x, N * sizeof(T), ox);\n  __msan_set_origin(y, N * sizeof(T), 777777);\n  __msan_set_origin(z, N * sizeof(T), 888888);\n  EXPECT_NOT_POISONED(x);\n  memcpy(y, x, N * sizeof(T));\n  EXPECT_POISONED_O(y[0], ox);\n  EXPECT_POISONED_O(y[N/2], ox);\n  EXPECT_POISONED_O(y[N-1], ox);\n  EXPECT_NOT_POISONED(x);\n  void *res = mempcpy(q, x, N * sizeof(T));\n  ASSERT_EQ(q + N, res);\n  EXPECT_POISONED_O(q[0], ox);\n  EXPECT_POISONED_O(q[N/2], ox);\n  EXPECT_POISONED_O(q[N-1], ox);\n  EXPECT_NOT_POISONED(x);\n  memmove(z, x, N * sizeof(T));\n  EXPECT_POISONED_O(z[0], ox);\n  EXPECT_POISONED_O(z[N/2], ox);\n  EXPECT_POISONED_O(z[N-1], ox);\n}\n\nTEST(MemorySanitizerOrigins, LargeMemCpy) {\n  if (!TrackingOrigins()) return;\n  MemCpyTest<U1, 10000>();\n  MemCpyTest<U8, 10000>();\n}\n\nTEST(MemorySanitizerOrigins, SmallMemCpy) {\n  if (!TrackingOrigins()) return;\n  MemCpyTest<U8, 1>();\n  MemCpyTest<U8, 2>();\n  MemCpyTest<U8, 3>();\n}\n\nTEST(MemorySanitizerOrigins, Select) {\n  if (!TrackingOrigins()) return;\n  EXPECT_NOT_POISONED(g_one ? 1 : *GetPoisonedO<S4>(0, __LINE__));\n  EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);\n  S4 x;\n  break_optimization(&x);\n  x = g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 0;\n\n  EXPECT_POISONED_O(g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 1, __LINE__);\n  EXPECT_POISONED_O(g_0 ? 1 : *GetPoisonedO<S4>(0, __LINE__), __LINE__);\n}\n\nNOINLINE int RetvalOriginTest(U4 origin) {\n  int *a = new int;\n  break_optimization(a);\n  __msan_set_origin(a, sizeof(*a), origin);\n  int res = *a;\n  delete a;\n  return res;\n}\n\nTEST(MemorySanitizerOrigins, Retval) {\n  if (!TrackingOrigins()) return;\n  EXPECT_POISONED_O(RetvalOriginTest(__LINE__), __LINE__);\n}\n\nNOINLINE void ParamOriginTest(int param, U4 origin) {\n  EXPECT_POISONED_O(param, origin);\n}\n\nTEST(MemorySanitizerOrigins, Param) {\n  if (!TrackingOrigins()) return;\n  int *a = new int;\n  U4 origin = __LINE__;\n  break_optimization(a);\n  __msan_set_origin(a, sizeof(*a), origin);\n  ParamOriginTest(*a, origin);\n  delete a;\n}\n\nTEST(MemorySanitizerOrigins, Invoke) {\n  if (!TrackingOrigins()) return;\n  StructWithDtor s;  // Will cause the calls to become invokes.\n  EXPECT_POISONED_O(RetvalOriginTest(__LINE__), __LINE__);\n}\n\nTEST(MemorySanitizerOrigins, strlen) {\n  S8 alignment;\n  break_optimization(&alignment);\n  char x[4] = {'a', 'b', 0, 0};\n  __msan_poison(&x[2], 1);\n  U4 origin = __LINE__;\n  __msan_set_origin(x, sizeof(x), origin);\n  EXPECT_UMR_O(volatile unsigned y = strlen(x), origin);\n}\n\nTEST(MemorySanitizerOrigins, wcslen) {\n  wchar_t w[3] = {'a', 'b', 0};\n  U4 origin = __LINE__;\n  __msan_set_origin(w, sizeof(w), origin);\n  __msan_poison(&w[2], sizeof(wchar_t));\n  EXPECT_UMR_O(volatile unsigned y = wcslen(w), origin);\n}\n\n#if MSAN_HAS_M128\nTEST(MemorySanitizerOrigins, StoreIntrinsic) {\n  __m128 x, y;\n  U4 origin = __LINE__;\n  __msan_set_origin(&x, sizeof(x), origin);\n  __msan_poison(&x, sizeof(x));\n  __builtin_ia32_storeups((float*)&y, x);\n  EXPECT_POISONED_O(y, origin);\n}\n#endif\n\nNOINLINE void RecursiveMalloc(int depth) {\n  static int count;\n  count++;\n  if ((count % (1024 * 1024)) == 0)\n    printf(\"RecursiveMalloc: %d\\n\", count);\n  int *x1 = new int;\n  int *x2 = new int;\n  break_optimization(x1);\n  break_optimization(x2);\n  if (depth > 0) {\n    RecursiveMalloc(depth-1);\n    RecursiveMalloc(depth-1);\n  }\n  delete x1;\n  delete x2;\n}\n\nTEST(MemorySanitizer, Select) {\n  int x;\n  int volatile* p = &x;\n  int z = *p ? 1 : 0;\n  EXPECT_POISONED(z);\n}\n\nTEST(MemorySanitizer, SelectPartial) {\n  // Precise instrumentation of select.\n  // Some bits of the result do not depend on select condition, and must stay\n  // initialized even if select condition is not. These are the bits that are\n  // equal and initialized in both left and right select arguments.\n  U4 x = 0xFFFFABCDU;\n  U4 x_s = 0xFFFF0000U;\n  __msan_partial_poison(&x, &x_s, sizeof(x));\n  U4 y = 0xAB00U;\n  U1 cond = true;\n  __msan_poison(&cond, sizeof(cond));\n  U4 z = cond ? x : y;\n  __msan_print_shadow(&z, sizeof(z));\n  EXPECT_POISONED(z & 0xFFU);\n  EXPECT_NOT_POISONED(z & 0xFF00U);\n  EXPECT_POISONED(z & 0xFF0000U);\n  EXPECT_POISONED(z & 0xFF000000U);\n  EXPECT_EQ(0xAB00U, z & 0xFF00U);\n}\n\nTEST(MemorySanitizerStress, DISABLED_MallocStackTrace) {\n  RecursiveMalloc(22);\n}\n\nTEST(MemorySanitizerAllocator, get_estimated_allocated_size) {\n  size_t sizes[] = {0, 20, 5000, 1<<20};\n  for (size_t i = 0; i < sizeof(sizes) / sizeof(*sizes); ++i) {\n    size_t alloc_size = __sanitizer_get_estimated_allocated_size(sizes[i]);\n    EXPECT_EQ(alloc_size, sizes[i]);\n  }\n}\n\nTEST(MemorySanitizerAllocator, get_allocated_size_and_ownership) {\n  char *array = reinterpret_cast<char*>(malloc(100));\n  int *int_ptr = new int;\n\n  EXPECT_TRUE(__sanitizer_get_ownership(array));\n  EXPECT_EQ(100U, __sanitizer_get_allocated_size(array));\n\n  EXPECT_TRUE(__sanitizer_get_ownership(int_ptr));\n  EXPECT_EQ(sizeof(*int_ptr), __sanitizer_get_allocated_size(int_ptr));\n\n  void *wild_addr = reinterpret_cast<void*>(0x1);\n  EXPECT_FALSE(__sanitizer_get_ownership(wild_addr));\n  EXPECT_EQ(0U, __sanitizer_get_allocated_size(wild_addr));\n\n  EXPECT_FALSE(__sanitizer_get_ownership(array + 50));\n  EXPECT_EQ(0U, __sanitizer_get_allocated_size(array + 50));\n\n  // NULL is a valid argument for GetAllocatedSize but is not owned.\n  EXPECT_FALSE(__sanitizer_get_ownership(NULL));\n  EXPECT_EQ(0U, __sanitizer_get_allocated_size(NULL));\n\n  free(array);\n  EXPECT_FALSE(__sanitizer_get_ownership(array));\n  EXPECT_EQ(0U, __sanitizer_get_allocated_size(array));\n\n  delete int_ptr;\n}\n\nTEST(MemorySanitizer, MlockTest) {\n  EXPECT_EQ(0, mlockall(MCL_CURRENT));\n  EXPECT_EQ(0, mlock((void*)0x12345, 0x5678));\n  EXPECT_EQ(0, munlockall());\n  EXPECT_EQ(0, munlock((void*)0x987, 0x654));\n}\n\n// Test that LargeAllocator unpoisons memory before releasing it to the OS.\nTEST(MemorySanitizer, LargeAllocatorUnpoisonsOnFree) {\n  void *p = malloc(1024 * 1024);\n  free(p);\n\n  typedef void *(*mmap_fn)(void *, size_t, int, int, int, off_t);\n  mmap_fn real_mmap = (mmap_fn)dlsym(RTLD_NEXT, \"mmap\");\n\n  // Allocate the page that was released to the OS in free() with the real mmap,\n  // bypassing the interceptor.\n  char *q = (char *)real_mmap(p, 4096, PROT_READ | PROT_WRITE,\n                              MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);\n  ASSERT_NE((char *)0, q);\n\n  ASSERT_TRUE(q <= p);\n  ASSERT_TRUE(q + 4096 > p);\n\n  EXPECT_NOT_POISONED(q[0]);\n  EXPECT_NOT_POISONED(q[10]);\n  EXPECT_NOT_POISONED(q[100]);\n\n  munmap(q, 4096);\n}\n\n#if SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE\nTEST(MemorySanitizer, MallocUsableSizeTest) {\n  const size_t kArraySize = 100;\n  char *array = Ident((char*)malloc(kArraySize));\n  int *int_ptr = Ident(new int);\n  EXPECT_EQ(0U, malloc_usable_size(NULL));\n  EXPECT_EQ(kArraySize, malloc_usable_size(array));\n  EXPECT_EQ(sizeof(int), malloc_usable_size(int_ptr));\n  free(array);\n  delete int_ptr;\n}\n#endif  // SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/tests/msan_test_config.h",
    "content": "//===-- msan_test_config.h ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n// MemorySanitizer unit tests.\n//===----------------------------------------------------------------------===//\n\n#ifndef MSAN_TEST_CONFIG_H\n#define MSAN_TEST_CONFIG_H\n\n#include \"gtest/gtest.h\"\n\n#endif // MSAN_TEST_CONFIG_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/msan/tests/msan_test_main.cc",
    "content": "//===-- msan_test_main.cc -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of MemorySanitizer.\n//\n//===----------------------------------------------------------------------===//\n#ifndef MSAN_EXTERNAL_TEST_CONFIG\n#include \"msan_test_config.h\"\n#endif // MSAN_EXTERNAL_TEST_CONFIG\n\nint main(int argc, char **argv) {\n  testing::GTEST_FLAG(death_test_style) = \"threadsafe\";\n  testing::InitGoogleTest(&argc, argv);\n  return RUN_ALL_TESTS();\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/Android.mk",
    "content": "#\n# Copyright (C) 2016 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n#\n\nLOCAL_PATH := $(call my-dir)\n\nlibprofile_rt_srcs := \\\n    GCDAProfiling.c \\\n    InstrProfiling.c \\\n    InstrProfilingBuffer.c \\\n    InstrProfilingFile.c \\\n    InstrProfilingPlatformDarwin.c \\\n    InstrProfilingPlatformOther.c \\\n    InstrProfilingRuntime.cc \\\n    InstrProfilingUtil.c \\\n\nlibprofile_rt_cflags := -Werror -Wall\n\n#=====================================================================\n# Host Static Library: libprofile_rt\n#=====================================================================\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE = libprofile_rt\nLOCAL_CFLAGS := $(libcompiler_rt_cflags)\nLOCAL_SRC_FILES := $(libprofile_rt_srcs)\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_SANITIZE := never\nLOCAL_MULTILIB := both\nLOCAL_CXX_STL := none\n\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\n#=====================================================================\n# Device Static Library: libprofile_rt\n#=====================================================================\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE = libprofile_rt\nLOCAL_CFLAGS := $(libcompiler_rt_cflags)\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := $(libprofile_rt_srcs)\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_SANITIZE := never\nLOCAL_MULTILIB := both\nLOCAL_NDK_STL_VARIANT := none\nLOCAL_SDK_VERSION := 21\n\ninclude $(BUILD_STATIC_LIBRARY)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/CMakeLists.txt",
    "content": "\nCHECK_CXX_SOURCE_COMPILES(\"\n#ifdef _MSC_VER\n#include <Intrin.h> /* Workaround for PR19898. */\n#include <windows.h>\n#endif\nint main() {\n#ifdef _MSC_VER\n        volatile LONG val = 1;\n        MemoryBarrier();\n        InterlockedCompareExchange(&val, 0, 1);\n        InterlockedIncrement(&val);\n        InterlockedDecrement(&val);\n#else\n        volatile unsigned long val = 1;\n        __sync_synchronize();\n        __sync_val_compare_and_swap(&val, 1, 0);\n        __sync_add_and_fetch(&val, 1);\n        __sync_sub_and_fetch(&val, 1);\n#endif\n        return 0;\n      }\n\" COMPILER_RT_TARGET_HAS_ATOMICS)\n\nadd_custom_target(profile)\n\nset(PROFILE_SOURCES\n  GCDAProfiling.c\n  InstrProfiling.c\n  InstrProfilingValue.c\n  InstrProfilingBuffer.c\n  InstrProfilingFile.c\n  InstrProfilingWriter.c\n  InstrProfilingPlatformDarwin.c\n  InstrProfilingPlatformLinux.c\n  InstrProfilingPlatformOther.c\n  InstrProfilingRuntime.cc\n  InstrProfilingUtil.c)\n\nif(UNIX)\n set(EXTRA_FLAGS\n     -fPIC\n     -Wno-pedantic)\nelse()\n set(EXTRA_FLAGS\n     -fPIC)\nendif()\n\nif(COMPILER_RT_TARGET_HAS_ATOMICS)\n set(EXTRA_FLAGS\n     ${EXTRA_FLAGS}\n     -DCOMPILER_RT_HAS_ATOMICS=1)\nendif() \n\nif(APPLE)\n  add_compiler_rt_runtime(clang_rt.profile\n    STATIC\n    OS ${PROFILE_SUPPORTED_OS}\n    ARCHS ${PROFILE_SUPPORTED_ARCH}\n    SOURCES ${PROFILE_SOURCES}\n    PARENT_TARGET profile)\nelse()\n  add_compiler_rt_runtime(clang_rt.profile\n    STATIC\n    ARCHS ${PROFILE_SUPPORTED_ARCH}\n    CFLAGS ${EXTRA_FLAGS}\n    SOURCES ${PROFILE_SOURCES}\n    PARENT_TARGET profile)\nendif()\n\nadd_dependencies(compiler-rt profile)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/GCDAProfiling.c",
    "content": "/*===- GCDAProfiling.c - Support library for GCDA file emission -----------===*\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|* \n|*===----------------------------------------------------------------------===*|\n|* \n|* This file implements the call back routines for the gcov profiling\n|* instrumentation pass. Link against this library when running code through\n|* the -insert-gcov-profiling LLVM pass.\n|*\n|* We emit files in a corrupt version of GCOV's \"gcda\" file format. These files\n|* are only close enough that LCOV will happily parse them. Anything that lcov\n|* ignores is missing.\n|*\n|* TODO: gcov is multi-process safe by having each exit open the existing file\n|* and append to it. We'd like to achieve that and be thread-safe too.\n|*\n\\*===----------------------------------------------------------------------===*/\n\n#include \"InstrProfilingUtil.h\"\n\n#include <errno.h>\n#include <fcntl.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/mman.h>\n#include <sys/file.h>\n\n#define I386_FREEBSD (defined(__FreeBSD__) && defined(__i386__))\n\n#if !defined(_MSC_VER) && !I386_FREEBSD\n#include <stdint.h>\n#endif\n\n#if defined(_MSC_VER)\ntypedef unsigned int uint32_t;\ntypedef unsigned long long uint64_t;\n#elif I386_FREEBSD\n/* System headers define 'size_t' incorrectly on x64 FreeBSD (prior to\n * FreeBSD 10, r232261) when compiled in 32-bit mode.\n */\ntypedef unsigned char uint8_t;\ntypedef unsigned int uint32_t;\ntypedef unsigned long long uint64_t;\n#endif\n\n/* #define DEBUG_GCDAPROFILING */\n\n/*\n * --- GCOV file format I/O primitives ---\n */\n\n/*\n * The current file name we're outputting. Used primarily for error logging.\n */\nstatic char *filename = NULL;\n\n/*\n * The current file we're outputting.\n */ \nstatic FILE *output_file = NULL;\n\n/*\n * Buffer that we write things into.\n */\n#define WRITE_BUFFER_SIZE (128 * 1024)\nstatic char *write_buffer = NULL;\nstatic uint64_t cur_buffer_size = 0;\nstatic uint64_t cur_pos = 0;\nstatic uint64_t file_size = 0;\nstatic int new_file = 0;\nstatic int fd = -1;\n\n/*\n * A list of functions to write out the data.\n */\ntypedef void (*writeout_fn)();\n\nstruct writeout_fn_node {\n  writeout_fn fn;\n  struct writeout_fn_node *next;\n};\n\nstatic struct writeout_fn_node *writeout_fn_head = NULL;\nstatic struct writeout_fn_node *writeout_fn_tail = NULL;\n\n/*\n *  A list of flush functions that our __gcov_flush() function should call.\n */\ntypedef void (*flush_fn)();\n\nstruct flush_fn_node {\n  flush_fn fn;\n  struct flush_fn_node *next;\n};\n\nstatic struct flush_fn_node *flush_fn_head = NULL;\nstatic struct flush_fn_node *flush_fn_tail = NULL;\n\nstatic void resize_write_buffer(uint64_t size) {\n  if (!new_file) return;\n  size += cur_pos;\n  if (size <= cur_buffer_size) return;\n  size = (size - 1) / WRITE_BUFFER_SIZE + 1;\n  size *= WRITE_BUFFER_SIZE;\n  write_buffer = realloc(write_buffer, size);\n  cur_buffer_size = size;\n}\n\nstatic void write_bytes(const char *s, size_t len) {\n  resize_write_buffer(len);\n  memcpy(&write_buffer[cur_pos], s, len);\n  cur_pos += len;\n}\n\nstatic void write_32bit_value(uint32_t i) {\n  write_bytes((char*)&i, 4);\n}\n\nstatic void write_64bit_value(uint64_t i) {\n  write_bytes((char*)&i, 8);\n}\n\nstatic uint32_t length_of_string(const char *s) {\n  return (strlen(s) / 4) + 1;\n}\n\nstatic void write_string(const char *s) {\n  uint32_t len = length_of_string(s);\n  write_32bit_value(len);\n  write_bytes(s, strlen(s));\n  write_bytes(\"\\0\\0\\0\\0\", 4 - (strlen(s) % 4));\n}\n\nstatic uint32_t read_32bit_value() {\n  uint32_t val;\n\n  if (new_file)\n    return (uint32_t)-1;\n\n  val = *(uint32_t*)&write_buffer[cur_pos];\n  cur_pos += 4;\n  return val;\n}\n\nstatic uint64_t read_64bit_value() {\n  uint64_t val;\n\n  if (new_file)\n    return (uint64_t)-1;\n\n  val = *(uint64_t*)&write_buffer[cur_pos];\n  cur_pos += 8;\n  return val;\n}\n\nstatic char *mangle_filename(const char *orig_filename) {\n  char *new_filename;\n  size_t filename_len, prefix_len;\n  int prefix_strip;\n  int level = 0;\n  const char *fname, *ptr;\n  const char *prefix = getenv(\"GCOV_PREFIX\");\n  const char *prefix_strip_str = getenv(\"GCOV_PREFIX_STRIP\");\n\n  if (prefix == NULL || prefix[0] == '\\0')\n    return strdup(orig_filename);\n\n  if (prefix_strip_str) {\n    prefix_strip = atoi(prefix_strip_str);\n\n    /* Negative GCOV_PREFIX_STRIP values are ignored */\n    if (prefix_strip < 0)\n      prefix_strip = 0;\n  } else {\n    prefix_strip = 0;\n  }\n\n  fname = orig_filename;\n  for (level = 0, ptr = fname + 1; level < prefix_strip; ++ptr) {\n    if (*ptr == '\\0')\n      break;\n    if (*ptr != '/')\n      continue;\n    fname = ptr;\n    ++level;\n  }\n\n  filename_len = strlen(fname);\n  prefix_len = strlen(prefix);\n  new_filename = malloc(prefix_len + 1 + filename_len + 1);\n  memcpy(new_filename, prefix, prefix_len);\n\n  if (prefix[prefix_len - 1] != '/')\n    new_filename[prefix_len++] = '/';\n  memcpy(new_filename + prefix_len, fname, filename_len + 1);\n\n  return new_filename;\n}\n\nstatic int map_file() {\n  fseek(output_file, 0L, SEEK_END);\n  file_size = ftell(output_file);\n\n  /* A size of 0 is invalid to `mmap'. Return a fail here, but don't issue an\n   * error message because it should \"just work\" for the user. */\n  if (file_size == 0)\n    return -1;\n\n  write_buffer = mmap(0, file_size, PROT_READ | PROT_WRITE,\n                      MAP_FILE | MAP_SHARED, fd, 0);\n  if (write_buffer == (void *)-1) {\n    int errnum = errno;\n    fprintf(stderr, \"profiling: %s: cannot map: %s\\n\", filename,\n            strerror(errnum));\n    return -1;\n  }\n  return 0;\n}\n\nstatic void unmap_file() {\n  if (msync(write_buffer, file_size, MS_SYNC) == -1) {\n    int errnum = errno;\n    fprintf(stderr, \"profiling: %s: cannot msync: %s\\n\", filename,\n            strerror(errnum));\n  }\n\n  /* We explicitly ignore errors from unmapping because at this point the data\n   * is written and we don't care.\n   */\n  (void)munmap(write_buffer, file_size);\n  write_buffer = NULL;\n  file_size = 0;\n}\n\n/*\n * --- LLVM line counter API ---\n */\n\n/* A file in this case is a translation unit. Each .o file built with line\n * profiling enabled will emit to a different file. Only one file may be\n * started at a time.\n */\nvoid llvm_gcda_start_file(const char *orig_filename, const char version[4],\n                          uint32_t checksum) {\n  const char *mode = \"r+b\";\n  filename = mangle_filename(orig_filename);\n\n  /* Try just opening the file. */\n  new_file = 0;\n  fd = open(filename, O_RDWR);\n\n  if (fd == -1) {\n    /* Try opening the file, creating it if necessary. */\n    new_file = 1;\n    mode = \"w+b\";\n    fd = open(filename, O_RDWR | O_CREAT, 0644);\n    if (fd == -1) {\n      /* Try creating the directories first then opening the file. */\n      __llvm_profile_recursive_mkdir(filename);\n      fd = open(filename, O_RDWR | O_CREAT, 0644);\n      if (fd == -1) {\n        /* Bah! It's hopeless. */\n        int errnum = errno;\n        fprintf(stderr, \"profiling: %s: cannot open: %s\\n\", filename,\n                strerror(errnum));\n        return;\n      }\n    }\n  }\n\n  /* Try to flock the file to serialize concurrent processes writing out to the\n   * same GCDA. This can fail if the filesystem doesn't support it, but in that\n   * case we'll just carry on with the old racy behaviour and hope for the best.\n   */\n  flock(fd, LOCK_EX);\n  output_file = fdopen(fd, mode);\n\n  /* Initialize the write buffer. */\n  write_buffer = NULL;\n  cur_buffer_size = 0;\n  cur_pos = 0;\n\n  if (new_file) {\n    resize_write_buffer(WRITE_BUFFER_SIZE);\n    memset(write_buffer, 0, WRITE_BUFFER_SIZE);\n  } else {\n    if (map_file() == -1) {\n      /* mmap failed, try to recover by clobbering */\n      new_file = 1;\n      write_buffer = NULL;\n      cur_buffer_size = 0;\n      resize_write_buffer(WRITE_BUFFER_SIZE);\n      memset(write_buffer, 0, WRITE_BUFFER_SIZE);\n    }\n  }\n\n  /* gcda file, version, stamp checksum. */\n  write_bytes(\"adcg\", 4);\n  write_bytes(version, 4);\n  write_32bit_value(checksum);\n\n#ifdef DEBUG_GCDAPROFILING\n  fprintf(stderr, \"llvmgcda: [%s]\\n\", orig_filename);\n#endif\n}\n\n/* Given an array of pointers to counters (counters), increment the n-th one,\n * where we're also given a pointer to n (predecessor).\n */\nvoid llvm_gcda_increment_indirect_counter(uint32_t *predecessor,\n                                          uint64_t **counters) {\n  uint64_t *counter;\n  uint32_t pred;\n\n  pred = *predecessor;\n  if (pred == 0xffffffff)\n    return;\n  counter = counters[pred];\n\n  /* Don't crash if the pred# is out of sync. This can happen due to threads,\n     or because of a TODO in GCOVProfiling.cpp buildEdgeLookupTable(). */\n  if (counter)\n    ++*counter;\n#ifdef DEBUG_GCDAPROFILING\n  else\n    fprintf(stderr,\n            \"llvmgcda: increment_indirect_counter counters=%08llx, pred=%u\\n\",\n            *counter, *predecessor);\n#endif\n}\n\nvoid llvm_gcda_emit_function(uint32_t ident, const char *function_name,\n                             uint32_t func_checksum, uint8_t use_extra_checksum,\n                             uint32_t cfg_checksum) {\n  uint32_t len = 2;\n\n  if (use_extra_checksum)\n    len++;\n#ifdef DEBUG_GCDAPROFILING\n  fprintf(stderr, \"llvmgcda: function id=0x%08x name=%s\\n\", ident,\n          function_name ? function_name : \"NULL\");\n#endif\n  if (!output_file) return;\n\n  /* function tag */\n  write_bytes(\"\\0\\0\\0\\1\", 4);\n  if (function_name)\n    len += 1 + length_of_string(function_name);\n  write_32bit_value(len);\n  write_32bit_value(ident);\n  write_32bit_value(func_checksum);\n  if (use_extra_checksum)\n    write_32bit_value(cfg_checksum);\n  if (function_name)\n    write_string(function_name);\n}\n\nvoid llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t *counters) {\n  uint32_t i;\n  uint64_t *old_ctrs = NULL;\n  uint32_t val = 0;\n  uint64_t save_cur_pos = cur_pos;\n\n  if (!output_file) return;\n\n  val = read_32bit_value();\n\n  if (val != (uint32_t)-1) {\n    /* There are counters present in the file. Merge them. */\n    if (val != 0x01a10000) {\n      fprintf(stderr, \"profiling: %s: cannot merge previous GCDA file: \"\n                      \"corrupt arc tag (0x%08x)\\n\",\n              filename, val);\n      return;\n    }\n\n    val = read_32bit_value();\n    if (val == (uint32_t)-1 || val / 2 != num_counters) {\n      fprintf(stderr, \"profiling: %s: cannot merge previous GCDA file: \"\n                      \"mismatched number of counters (%d)\\n\",\n              filename, val);\n      return;\n    }\n\n    old_ctrs = malloc(sizeof(uint64_t) * num_counters);\n    for (i = 0; i < num_counters; ++i)\n      old_ctrs[i] = read_64bit_value();\n  }\n\n  cur_pos = save_cur_pos;\n\n  /* Counter #1 (arcs) tag */\n  write_bytes(\"\\0\\0\\xa1\\1\", 4);\n  write_32bit_value(num_counters * 2);\n  for (i = 0; i < num_counters; ++i) {\n    counters[i] += (old_ctrs ? old_ctrs[i] : 0);\n    write_64bit_value(counters[i]);\n  }\n\n  free(old_ctrs);\n\n#ifdef DEBUG_GCDAPROFILING\n  fprintf(stderr, \"llvmgcda:   %u arcs\\n\", num_counters);\n  for (i = 0; i < num_counters; ++i)\n    fprintf(stderr, \"llvmgcda:   %llu\\n\", (unsigned long long)counters[i]);\n#endif\n}\n\nvoid llvm_gcda_summary_info() {\n  const uint32_t obj_summary_len = 9; /* Length for gcov compatibility. */\n  uint32_t i;\n  uint32_t runs = 1;\n  uint32_t val = 0;\n  uint64_t save_cur_pos = cur_pos;\n\n  if (!output_file) return;\n\n  val = read_32bit_value();\n\n  if (val != (uint32_t)-1) {\n    /* There are counters present in the file. Merge them. */\n    if (val != 0xa1000000) {\n      fprintf(stderr, \"profiling: %s: cannot merge previous run count: \"\n                      \"corrupt object tag (0x%08x)\\n\",\n              filename, val);\n      return;\n    }\n\n    val = read_32bit_value(); /* length */\n    if (val != obj_summary_len) {\n      fprintf(stderr, \"profiling: %s: cannot merge previous run count: \"\n                      \"mismatched object length (%d)\\n\",\n              filename, val);\n      return;\n    }\n\n    read_32bit_value(); /* checksum, unused */\n    read_32bit_value(); /* num, unused */\n    runs += read_32bit_value(); /* Add previous run count to new counter. */\n  }\n\n  cur_pos = save_cur_pos;\n\n  /* Object summary tag */\n  write_bytes(\"\\0\\0\\0\\xa1\", 4);\n  write_32bit_value(obj_summary_len);\n  write_32bit_value(0); /* checksum, unused */\n  write_32bit_value(0); /* num, unused */\n  write_32bit_value(runs);\n  for (i = 3; i < obj_summary_len; ++i)\n    write_32bit_value(0);\n\n  /* Program summary tag */\n  write_bytes(\"\\0\\0\\0\\xa3\", 4); /* tag indicates 1 program */\n  write_32bit_value(0); /* 0 length */\n\n#ifdef DEBUG_GCDAPROFILING\n  fprintf(stderr, \"llvmgcda:   %u runs\\n\", runs);\n#endif\n}\n\nvoid llvm_gcda_end_file() {\n  /* Write out EOF record. */\n  if (output_file) {\n    write_bytes(\"\\0\\0\\0\\0\\0\\0\\0\\0\", 8);\n\n    if (new_file) {\n      fwrite(write_buffer, cur_pos, 1, output_file);\n      free(write_buffer);\n    } else {\n      unmap_file();\n    }\n\n    fclose(output_file);\n    flock(fd, LOCK_UN);\n    output_file = NULL;\n    write_buffer = NULL;\n  }\n  free(filename);\n\n#ifdef DEBUG_GCDAPROFILING\n  fprintf(stderr, \"llvmgcda: -----\\n\");\n#endif\n}\n\nvoid llvm_register_writeout_function(writeout_fn fn) {\n  struct writeout_fn_node *new_node = malloc(sizeof(struct writeout_fn_node));\n  new_node->fn = fn;\n  new_node->next = NULL;\n\n  if (!writeout_fn_head) {\n    writeout_fn_head = writeout_fn_tail = new_node;\n  } else {\n    writeout_fn_tail->next = new_node;\n    writeout_fn_tail = new_node;\n  }\n}\n\nvoid llvm_writeout_files() {\n  struct writeout_fn_node *curr = writeout_fn_head;\n\n  while (curr) {\n    curr->fn();\n    curr = curr->next;\n  }\n}\n\nvoid llvm_delete_writeout_function_list() {\n  while (writeout_fn_head) {\n    struct writeout_fn_node *node = writeout_fn_head;\n    writeout_fn_head = writeout_fn_head->next;\n    free(node);\n  }\n  \n  writeout_fn_head = writeout_fn_tail = NULL;\n}\n\nvoid llvm_register_flush_function(flush_fn fn) {\n  struct flush_fn_node *new_node = malloc(sizeof(struct flush_fn_node));\n  new_node->fn = fn;\n  new_node->next = NULL;\n\n  if (!flush_fn_head) {\n    flush_fn_head = flush_fn_tail = new_node;\n  } else {\n    flush_fn_tail->next = new_node;\n    flush_fn_tail = new_node;\n  }\n}\n\nvoid __gcov_flush() {\n  struct flush_fn_node *curr = flush_fn_head;\n\n  while (curr) {\n    curr->fn();\n    curr = curr->next;\n  }\n}\n\nvoid llvm_delete_flush_function_list() {\n  while (flush_fn_head) {\n    struct flush_fn_node *node = flush_fn_head;\n    flush_fn_head = flush_fn_head->next;\n    free(node);\n  }\n\n  flush_fn_head = flush_fn_tail = NULL;\n}\n\nvoid llvm_gcov_init(writeout_fn wfn, flush_fn ffn) {\n  static int atexit_ran = 0;\n\n  if (wfn)\n    llvm_register_writeout_function(wfn);\n\n  if (ffn)\n    llvm_register_flush_function(ffn);\n\n  if (atexit_ran == 0) {\n    atexit_ran = 1;\n\n    /* Make sure we write out the data and delete the data structures. */\n    atexit(llvm_delete_flush_function_list);\n    atexit(llvm_delete_writeout_function_list);\n    atexit(llvm_writeout_files);\n  }\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfData.inc",
    "content": "/*===-- InstrProfData.inc - instr profiling runtime structures -----------=== *\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|*\n\\*===----------------------------------------------------------------------===*/\n/*\n * This is the master file that defines all the data structure, signature,\n * constant literals that are shared across profiling runtime library,\n * compiler (instrumentation), and host tools (reader/writer). The entities\n * defined in this file affect the profile runtime ABI, the raw profile format,\n * or both.\n *\n * The file has two identical copies. The master copy lives in LLVM and\n * the other one  sits in compiler-rt/lib/profile directory. To make changes\n * in this file, first modify the master copy and copy it over to compiler-rt.\n * Testing of any change in this file can start only after the two copies are\n * synced up.\n *\n * The first part of the file includes macros that defines types, names, and\n * initializers for the member fields of the core data structures. The field\n * declarations for one structure is enabled by defining the field activation\n * macro associated with that structure. Only one field activation record\n * can be defined at one time and the rest definitions will be filtered out by\n * the preprocessor.\n *\n * Examples of how the template is used to instantiate structure definition:\n * 1. To declare a structure:\n * \n * struct ProfData {\n * #define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) \\\n *    Type Name;\n * #include \"llvm/ProfileData/InstrProfData.inc\"\n * };\n *\n * 2. To construct LLVM type arrays for the struct type:\n *\n * Type *DataTypes[] = {\n * #define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) \\\n *   LLVMType,\n * #include \"llvm/ProfileData/InstrProfData.inc\"\n * };\n *\n * 4. To construct constant array for the initializers:\n * #define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) \\\n *   Initializer,\n * Constant *ConstantVals[] = {\n * #include \"llvm/ProfileData/InstrProfData.inc\"\n * };\n *\n *\n * The second part of the file includes definitions all other entities that\n * are related to runtime ABI and format. When no field activation macro is\n * defined, this file can be included to introduce the definitions.\n *\n\\*===----------------------------------------------------------------------===*/\n\n/* INSTR_PROF_DATA start. */\n/* Definition of member fields of the per-function control structure. */\n#ifndef INSTR_PROF_DATA\n#define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer)\n#else\n#define INSTR_PROF_DATA_DEFINED\n#endif\n\nINSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NameSize, \\\n                ConstantInt::get(llvm::Type::getInt32Ty(Ctx), \\\n                NamePtr->getType()->getPointerElementType()->getArrayNumElements()))\nINSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NumCounters, \\\n                ConstantInt::get(llvm::Type::getInt32Ty(Ctx), NumCounters))\nINSTR_PROF_DATA(const uint64_t, llvm::Type::getInt64Ty(Ctx), FuncHash, \\\n                ConstantInt::get(llvm::Type::getInt64Ty(Ctx), \\\n                Inc->getHash()->getZExtValue()))\nINSTR_PROF_DATA(const IntPtrT, llvm::Type::getInt8PtrTy(Ctx), NamePtr, \\\n                ConstantExpr::getBitCast(NamePtr, llvm::Type::getInt8PtrTy(Ctx)))\nINSTR_PROF_DATA(const IntPtrT, llvm::Type::getInt64PtrTy(Ctx), CounterPtr, \\\n                ConstantExpr::getBitCast(CounterPtr, \\\n                llvm::Type::getInt64PtrTy(Ctx)))\nINSTR_PROF_DATA(const IntPtrT, llvm::Type::getInt8PtrTy(Ctx), FunctionPointer, \\\n                FunctionAddr)\nINSTR_PROF_DATA(IntPtrT, llvm::Type::getInt8PtrTy(Ctx), Values, \\\n                ConstantPointerNull::get(Int8PtrTy))\nINSTR_PROF_DATA(const uint16_t, Int16ArrayTy, NumValueSites[IPVK_Last+1], \\\n                ConstantArray::get(Int16ArrayTy, Int16ArrayVals))\n#undef INSTR_PROF_DATA\n/* INSTR_PROF_DATA end. */\n\n/* INSTR_PROF_RAW_HEADER  start */\n/* Definition of member fields of the raw profile header data structure. */\n#ifndef INSTR_PROF_RAW_HEADER\n#define INSTR_PROF_RAW_HEADER(Type, Name, Initializer)\n#else\n#define INSTR_PROF_DATA_DEFINED\n#endif\nINSTR_PROF_RAW_HEADER(uint64_t, Magic, __llvm_profile_get_magic())\nINSTR_PROF_RAW_HEADER(uint64_t, Version, __llvm_profile_get_version())\nINSTR_PROF_RAW_HEADER(uint64_t, DataSize, DataSize)\nINSTR_PROF_RAW_HEADER(uint64_t, CountersSize, CountersSize)\nINSTR_PROF_RAW_HEADER(uint64_t, NamesSize,  NamesSize)\nINSTR_PROF_RAW_HEADER(uint64_t, CountersDelta, (uintptr_t)CountersBegin)\nINSTR_PROF_RAW_HEADER(uint64_t, NamesDelta, (uintptr_t)NamesBegin)\nINSTR_PROF_RAW_HEADER(uint64_t, ValueKindLast, IPVK_Last)\nINSTR_PROF_RAW_HEADER(uint64_t, ValueDataSize, ValueDataSize)\nINSTR_PROF_RAW_HEADER(uint64_t, ValueDataDelta, (uintptr_t)ValueDataBegin)\n#undef INSTR_PROF_RAW_HEADER\n/* INSTR_PROF_RAW_HEADER  end */\n\n/* VALUE_PROF_FUNC_PARAM start */\n/* Definition of parameter types of the runtime API used to do value profiling\n * for a given value site.\n */\n#ifndef VALUE_PROF_FUNC_PARAM\n#define VALUE_PROF_FUNC_PARAM(ArgType, ArgName, ArgLLVMType)\n#define INSTR_PROF_COMMA\n#else\n#define INSTR_PROF_DATA_DEFINED\n#define INSTR_PROF_COMMA ,\n#endif\nVALUE_PROF_FUNC_PARAM(uint64_t, TargetValue, Type::getInt64Ty(Ctx)) \\\n                      INSTR_PROF_COMMA\nVALUE_PROF_FUNC_PARAM(void *, Data, Type::getInt8PtrTy(Ctx)) INSTR_PROF_COMMA\nVALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx))\n#undef VALUE_PROF_FUNC_PARAM\n#undef INSTR_PROF_COMMA\n/* VALUE_PROF_FUNC_PARAM end */\n\n/* VALUE_PROF_KIND start */\n#ifndef VALUE_PROF_KIND\n#define VALUE_PROF_KIND(Enumerator, Value)\n#else\n#define INSTR_PROF_DATA_DEFINED\n#endif\nVALUE_PROF_KIND(IPVK_IndirectCallTarget, 0)\n/* These two kinds must be the last to be\n * declared. This is to make sure the string\n * array created with the template can be\n * indexed with the kind value.\n */\nVALUE_PROF_KIND(IPVK_First, IPVK_IndirectCallTarget)\nVALUE_PROF_KIND(IPVK_Last, IPVK_IndirectCallTarget)\n\n#undef VALUE_PROF_KIND\n/* VALUE_PROF_KIND end */\n\n/* COVMAP_FUNC_RECORD start */\n/* Definition of member fields of the function record structure in coverage\n * map.\n */\n#ifndef COVMAP_FUNC_RECORD\n#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Initializer)\n#else\n#define INSTR_PROF_DATA_DEFINED\n#endif\nCOVMAP_FUNC_RECORD(const IntPtrT, llvm::Type::getInt8PtrTy(Ctx), \\\n                   NamePtr, llvm::ConstantExpr::getBitCast(NamePtr, \\\n                   llvm::Type::getInt8PtrTy(Ctx))) \nCOVMAP_FUNC_RECORD(const uint32_t, llvm::Type::getInt32Ty(Ctx), NameSize, \\\n                   llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx),\\\n                   NameValue.size()))\nCOVMAP_FUNC_RECORD(const uint32_t, llvm::Type::getInt32Ty(Ctx), DataSize, \\\n                   llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx),\\\n                   CoverageMapping.size()))\nCOVMAP_FUNC_RECORD(const uint64_t, llvm::Type::getInt64Ty(Ctx), FuncHash, \\\n                   llvm::ConstantInt::get(llvm::Type::getInt64Ty(Ctx), FuncHash))\n#undef COVMAP_FUNC_RECORD\n/* COVMAP_FUNC_RECORD end.  */\n\n\n#ifdef INSTR_PROF_VALUE_PROF_DATA\n#define INSTR_PROF_DATA_DEFINED\n\n/*! \n * This is the header of the data structure that defines the on-disk\n * layout of the value profile data of a particular kind for one function.\n */\ntypedef struct ValueProfRecord {\n  /* The kind of the value profile record. */\n  uint32_t Kind;\n  /*\n   * The number of value profile sites. It is guaranteed to be non-zero;\n   * otherwise the record for this kind won't be emitted.\n   */\n  uint32_t NumValueSites;\n  /* \n   * The first element of the array that stores the number of profiled\n   * values for each value site. The size of the array is NumValueSites.\n   * Since NumValueSites is greater than zero, there is at least one\n   * element in the array.\n   */\n  uint8_t SiteCountArray[1];\n\n  /*\n   * The fake declaration is for documentation purpose only.\n   * Align the start of next field to be on 8 byte boundaries.\n  uint8_t Padding[X];\n   */\n\n  /* The array of value profile data. The size of the array is the sum\n   * of all elements in SiteCountArray[].\n  InstrProfValueData ValueData[];\n   */\n\n#ifdef __cplusplus\n  /*!\n   * \\brief Return the number of value sites.\n   */\n  uint32_t getNumValueSites() const { return NumValueSites; }\n  /*! \n   * \\brief Read data from this record and save it to Record.\n   */\n  void deserializeTo(InstrProfRecord &Record,\n                     InstrProfRecord::ValueMapType *VMap);\n  /*\n   * In-place byte swap:\n   * Do byte swap for this instance. \\c Old is the original order before\n   * the swap, and \\c New is the New byte order.\n   */\n  void swapBytes(support::endianness Old, support::endianness New);\n#endif\n} ValueProfRecord;\n\n/*!\n * Per-function header/control data structure for value profiling\n * data in indexed format.\n */\ntypedef struct ValueProfData {\n  /*\n   * Total size in bytes including this field. It must be a multiple\n   * of sizeof(uint64_t). \n   */\n  uint32_t TotalSize;\n  /* \n   *The number of value profile kinds that has value profile data.\n   * In this implementation, a value profile kind is considered to\n   * have profile data if the number of value profile sites for the\n   * kind is not zero. More aggressively, the implementation can\n   * choose to check the actual data value: if none of the value sites\n   * has any profiled values, the kind can be skipped.\n   */\n  uint32_t NumValueKinds;\n\n  /* \n   * Following are a sequence of variable length records. The prefix/header\n   * of each record is defined by ValueProfRecord type. The number of\n   * records is NumValueKinds.\n   * ValueProfRecord Record_1;\n   * ValueProfRecord Record_N;\n   */\n\n#if __cplusplus\n  /*!\n   * Return the total size in bytes of the on-disk value profile data\n   * given the data stored in Record.\n   */\n  static uint32_t getSize(const InstrProfRecord &Record);\n  /*!\n   * Return a pointer to \\c ValueProfData instance ready to be streamed.\n   */\n  static std::unique_ptr<ValueProfData>\n  serializeFrom(const InstrProfRecord &Record);\n  /*!\n   * Check the integrity of the record. Return the error code when\n   * an error is detected, otherwise return instrprof_error::success.\n   */\n  instrprof_error checkIntegrity();\n  /*!\n   * Return a pointer to \\c ValueProfileData instance ready to be read.\n   * All data in the instance are properly byte swapped. The input\n   * data is assumed to be in little endian order.\n   */\n  static ErrorOr<std::unique_ptr<ValueProfData>>\n  getValueProfData(const unsigned char *SrcBuffer,\n                   const unsigned char *const SrcBufferEnd,\n                   support::endianness SrcDataEndianness);\n  /*!\n   * Swap byte order from \\c Endianness order to host byte order.\n   */\n  void swapBytesToHost(support::endianness Endianness);\n  /*!\n   * Swap byte order from host byte order to \\c Endianness order.\n   */\n  void swapBytesFromHost(support::endianness Endianness);\n  /*!\n   * Return the total size of \\c ValueProfileData.\n   */\n  uint32_t getSize() const { return TotalSize; }\n  /*!\n   * Read data from this data and save it to \\c Record.\n   */\n  void deserializeTo(InstrProfRecord &Record,\n                     InstrProfRecord::ValueMapType *VMap);\n  void operator delete(void *ptr) { ::operator delete(ptr); }\n#endif\n} ValueProfData;\n\n/* \n * The closure is designed to abstact away two types of value profile data:\n * - InstrProfRecord which is the primary data structure used to\n *   represent profile data in host tools (reader, writer, and profile-use)\n * - value profile runtime data structure suitable to be used by C\n *   runtime library.\n *\n * Both sources of data need to serialize to disk/memory-buffer in common\n * format: ValueProfData. The abstraction allows compiler-rt's raw profiler\n * writer to share the same format and code with indexed profile writer.\n *\n * For documentation of the member methods below, refer to corresponding methods\n * in class InstrProfRecord.\n */\ntypedef struct ValueProfRecordClosure {\n  const void *Record;\n  uint32_t (*GetNumValueKinds)(const void *Record);\n  uint32_t (*GetNumValueSites)(const void *Record, uint32_t VKind);\n  uint32_t (*GetNumValueData)(const void *Record, uint32_t VKind);\n  uint32_t (*GetNumValueDataForSite)(const void *R, uint32_t VK, uint32_t S);\n\n  /* \n   * After extracting the value profile data from the value profile record,\n   * this method is used to map the in-memory value to on-disk value. If\n   * the method is null, value will be written out untranslated.\n   */\n  uint64_t (*RemapValueData)(uint32_t, uint64_t Value);\n  void (*GetValueForSite)(const void *R, InstrProfValueData *Dst, uint32_t K,\n                          uint32_t S, uint64_t (*Mapper)(uint32_t, uint64_t));\n  ValueProfData *(*AllocValueProfData)(size_t TotalSizeInBytes);\n} ValueProfRecordClosure;\n\n/* \n * A wrapper struct that represents value profile runtime data.\n * Like InstrProfRecord class which is used by profiling host tools,\n * ValueProfRuntimeRecord also implements the abstract intefaces defined in\n * ValueProfRecordClosure so that the runtime data can be serialized using\n * shared C implementation. In this structure, NumValueSites and Nodes\n * members are the primary fields while other fields hold the derived\n * information for fast implementation of closure interfaces.\n */\ntypedef struct ValueProfRuntimeRecord {\n  /* Number of sites for each value profile kind.  */\n  const uint16_t *NumValueSites;\n  /* An array of linked-list headers. The size of of the array is the\n   * total number of value profile sites : sum(NumValueSites[*])). Each\n   * linked-list stores the values profiled for a value profile site. */\n  ValueProfNode **Nodes;\n\n  /* Total number of value profile kinds which have at least one\n   *  value profile sites. */\n  uint32_t NumValueKinds;\n  /* An array recording the number of values tracked at each site.\n   * The size of the array is TotalNumValueSites. */\n  uint8_t *SiteCountArray[IPVK_Last + 1];\n  ValueProfNode **NodesKind[IPVK_Last + 1];\n} ValueProfRuntimeRecord;\n\n/* Forward declarations of C interfaces.  */\nint initializeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord,\n                                     const uint16_t *NumValueSites,\n                                     ValueProfNode **Nodes);\nvoid finalizeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord);\nuint32_t getValueProfDataSizeRT(const ValueProfRuntimeRecord *Record);\nValueProfData *\nserializeValueProfDataFromRT(const ValueProfRuntimeRecord *Record,\n                             ValueProfData *Dst);\nuint32_t getNumValueKindsRT(const void *R);\n\n#undef INSTR_PROF_VALUE_PROF_DATA\n#endif  /* INSTR_PROF_VALUE_PROF_DATA */ \n\n\n#ifdef INSTR_PROF_COMMON_API_IMPL\n#define INSTR_PROF_DATA_DEFINED\n#ifdef __cplusplus\n#define INSTR_PROF_INLINE inline\n#else\n#define INSTR_PROF_INLINE\n#endif\n\n#ifndef offsetof\n#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)\n#endif\n\n/*!\n * \\brief Return the \\c ValueProfRecord header size including the\n * padding bytes.\n */\nINSTR_PROF_INLINE\nuint32_t getValueProfRecordHeaderSize(uint32_t NumValueSites) {\n  uint32_t Size = offsetof(ValueProfRecord, SiteCountArray) +\n                  sizeof(uint8_t) * NumValueSites;\n  /* Round the size to multiple of 8 bytes. */\n  Size = (Size + 7) & ~7;\n  return Size;\n}\n\n/*! \n * \\brief Return the total size of the value profile record including the\n * header and the value data.\n */\nINSTR_PROF_INLINE\nuint32_t getValueProfRecordSize(uint32_t NumValueSites,\n                                uint32_t NumValueData) {\n  return getValueProfRecordHeaderSize(NumValueSites) +\n         sizeof(InstrProfValueData) * NumValueData;\n}\n\n/*!\n * \\brief Return the pointer to the start of value data array.\n */\nINSTR_PROF_INLINE\nInstrProfValueData *getValueProfRecordValueData(ValueProfRecord *This) {\n  return (InstrProfValueData *)((char *)This + getValueProfRecordHeaderSize(\n                                                   This->NumValueSites));\n}\n\n/*! \n * \\brief Return the total number of value data for \\c This record.\n */\nINSTR_PROF_INLINE\nuint32_t getValueProfRecordNumValueData(ValueProfRecord *This) {\n  uint32_t NumValueData = 0;\n  uint32_t I;\n  for (I = 0; I < This->NumValueSites; I++)\n    NumValueData += This->SiteCountArray[I];\n  return NumValueData;\n}\n\n/*! \n * \\brief Use this method to advance to the next \\c This \\c ValueProfRecord.\n */\nINSTR_PROF_INLINE\nValueProfRecord *getValueProfRecordNext(ValueProfRecord *This) {\n  uint32_t NumValueData = getValueProfRecordNumValueData(This);\n  return (ValueProfRecord *)((char *)This +\n                             getValueProfRecordSize(This->NumValueSites,\n                                                    NumValueData));\n}\n\n/*!\n * \\brief Return the first \\c ValueProfRecord instance.\n */\nINSTR_PROF_INLINE\nValueProfRecord *getFirstValueProfRecord(ValueProfData *This) {\n  return (ValueProfRecord *)((char *)This + sizeof(ValueProfData));\n}\n\n/* Closure based interfaces.  */\n\n/*! \n * Return the total size in bytes of the on-disk value profile data\n * given the data stored in Record.\n */\nuint32_t getValueProfDataSize(ValueProfRecordClosure *Closure) {\n  uint32_t Kind;\n  uint32_t TotalSize = sizeof(ValueProfData);\n  const void *Record = Closure->Record;\n  uint32_t NumValueKinds = Closure->GetNumValueKinds(Record);\n  if (NumValueKinds == 0)\n    return TotalSize;\n\n  for (Kind = IPVK_First; Kind <= IPVK_Last; Kind++) {\n    uint32_t NumValueSites = Closure->GetNumValueSites(Record, Kind);\n    if (!NumValueSites)\n      continue;\n    TotalSize += getValueProfRecordSize(NumValueSites,\n                                        Closure->GetNumValueData(Record, Kind));\n  }\n  return TotalSize;\n}\n\n/*!\n * Extract value profile data of a function for the profile kind \\c ValueKind\n * from the \\c Closure and serialize the data into \\c This record instance.\n */\nvoid serializeValueProfRecordFrom(ValueProfRecord *This,\n                                  ValueProfRecordClosure *Closure,\n                                  uint32_t ValueKind, uint32_t NumValueSites) {\n  uint32_t S;\n  const void *Record = Closure->Record;\n  This->Kind = ValueKind;\n  This->NumValueSites = NumValueSites;\n  InstrProfValueData *DstVD = getValueProfRecordValueData(This);\n\n  for (S = 0; S < NumValueSites; S++) {\n    uint32_t ND = Closure->GetNumValueDataForSite(Record, ValueKind, S);\n    This->SiteCountArray[S] = ND;\n    Closure->GetValueForSite(Record, DstVD, ValueKind, S,\n                             Closure->RemapValueData);\n    DstVD += ND;\n  }\n}\n\n/*!\n * Extract value profile data of a function  from the \\c Closure\n * and serialize the data into \\c DstData if it is not NULL or heap\n * memory allocated by the \\c Closure's allocator method.\n */\nValueProfData *serializeValueProfDataFrom(ValueProfRecordClosure *Closure,\n                                          ValueProfData *DstData) {\n  uint32_t Kind;\n  uint32_t TotalSize = getValueProfDataSize(Closure);\n\n  ValueProfData *VPD =\n      DstData ? DstData : Closure->AllocValueProfData(TotalSize);\n\n  VPD->TotalSize = TotalSize;\n  VPD->NumValueKinds = Closure->GetNumValueKinds(Closure->Record);\n  ValueProfRecord *VR = getFirstValueProfRecord(VPD);\n  for (Kind = IPVK_First; Kind <= IPVK_Last; Kind++) {\n    uint32_t NumValueSites = Closure->GetNumValueSites(Closure->Record, Kind);\n    if (!NumValueSites)\n      continue;\n    serializeValueProfRecordFrom(VR, Closure, Kind, NumValueSites);\n    VR = getValueProfRecordNext(VR);\n  }\n  return VPD;\n}\n\n/* \n * The value profiler runtime library stores the value profile data\n * for a given function in \\c NumValueSites and \\c Nodes structures.\n * \\c ValueProfRuntimeRecord class is used to encapsulate the runtime\n * profile data and provides fast interfaces to retrieve the profile\n * information. This interface is used to initialize the runtime record\n * and pre-compute the information needed for efficient implementation\n * of callbacks required by ValueProfRecordClosure class.\n */\nint initializeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord,\n                                     const uint16_t *NumValueSites,\n                                     ValueProfNode **Nodes) {\n  unsigned I, J, S = 0, NumValueKinds = 0;\n  RuntimeRecord->NumValueSites = NumValueSites;\n  RuntimeRecord->Nodes = Nodes;\n  for (I = 0; I <= IPVK_Last; I++) {\n    uint16_t N = NumValueSites[I];\n    if (!N) {\n      RuntimeRecord->SiteCountArray[I] = 0;\n      continue;\n    }\n    NumValueKinds++;\n    RuntimeRecord->SiteCountArray[I] = (uint8_t *)calloc(N, 1);\n    if (!RuntimeRecord->SiteCountArray[I])\n      return 1;\n    RuntimeRecord->NodesKind[I] = Nodes ? &Nodes[S] : NULL;\n    for (J = 0; J < N; J++) {\n      /* Compute value count for each site. */\n      uint32_t C = 0;\n      ValueProfNode *Site = Nodes ? RuntimeRecord->NodesKind[I][J] : NULL;\n      while (Site) {\n        C++;\n        Site = Site->Next;\n      }\n      if (C > UCHAR_MAX)\n        C = UCHAR_MAX;\n      RuntimeRecord->SiteCountArray[I][J] = C;\n    }\n    S += N;\n  }\n  RuntimeRecord->NumValueKinds = NumValueKinds;\n  return 0;\n}\n\nvoid finalizeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord) {\n  unsigned I;\n  for (I = 0; I <= IPVK_Last; I++) {\n    if (RuntimeRecord->SiteCountArray[I])\n      free(RuntimeRecord->SiteCountArray[I]);\n  }\n}\n\n/* ValueProfRecordClosure Interface implementation for\n * ValueProfDataRuntimeRecord.  */\nuint32_t getNumValueKindsRT(const void *R) {\n  return ((const ValueProfRuntimeRecord *)R)->NumValueKinds;\n}\n\nuint32_t getNumValueSitesRT(const void *R, uint32_t VK) {\n  return ((const ValueProfRuntimeRecord *)R)->NumValueSites[VK];\n}\n\nuint32_t getNumValueDataForSiteRT(const void *R, uint32_t VK, uint32_t S) {\n  const ValueProfRuntimeRecord *Record = (const ValueProfRuntimeRecord *)R;\n  return Record->SiteCountArray[VK][S];\n}\n\nuint32_t getNumValueDataRT(const void *R, uint32_t VK) {\n  unsigned I, S = 0;\n  const ValueProfRuntimeRecord *Record = (const ValueProfRuntimeRecord *)R;\n  if (Record->SiteCountArray[VK] == 0)\n    return 0;\n  for (I = 0; I < Record->NumValueSites[VK]; I++)\n    S += Record->SiteCountArray[VK][I];\n  return S;\n}\n\nvoid getValueForSiteRT(const void *R, InstrProfValueData *Dst, uint32_t VK,\n                       uint32_t S, uint64_t (*Mapper)(uint32_t, uint64_t)) {\n  unsigned I, N = 0;\n  const ValueProfRuntimeRecord *Record = (const ValueProfRuntimeRecord *)R;\n  N = getNumValueDataForSiteRT(R, VK, S);\n  if (N == 0)\n    return;\n  ValueProfNode *VNode = Record->NodesKind[VK][S];\n  for (I = 0; I < N; I++) {\n    Dst[I] = VNode->VData;\n    VNode = VNode->Next;\n  }\n}\n\nValueProfData *allocValueProfDataRT(size_t TotalSizeInBytes) {\n  return (ValueProfData *)calloc(TotalSizeInBytes, 1);\n}\n\nstatic ValueProfRecordClosure RTRecordClosure = {0,\n                                                 getNumValueKindsRT,\n                                                 getNumValueSitesRT,\n                                                 getNumValueDataRT,\n                                                 getNumValueDataForSiteRT,\n                                                 0,\n                                                 getValueForSiteRT,\n                                                 allocValueProfDataRT};\n\n/* \n * Return the size of ValueProfData structure to store data\n * recorded in the runtime record.\n */\nuint32_t getValueProfDataSizeRT(const ValueProfRuntimeRecord *Record) {\n  RTRecordClosure.Record = Record;\n  return getValueProfDataSize(&RTRecordClosure);\n}\n\n/* \n * Return a ValueProfData instance that stores the data collected\n * from runtime. If \\c DstData is provided by the caller, the value\n * profile data will be store in *DstData and DstData is returned,\n * otherwise the method will allocate space for the value data and\n * return pointer to the newly allocated space.\n */\nValueProfData *\nserializeValueProfDataFromRT(const ValueProfRuntimeRecord *Record,\n                             ValueProfData *DstData) {\n  RTRecordClosure.Record = Record;\n  return serializeValueProfDataFrom(&RTRecordClosure, DstData);\n}\n\n\n#undef INSTR_PROF_COMMON_API_IMPL\n#endif /* INSTR_PROF_COMMON_API_IMPL */\n\n/*============================================================================*/\n\n\n#ifndef INSTR_PROF_DATA_DEFINED\n\n#ifndef INSTR_PROF_DATA_INC_\n#define INSTR_PROF_DATA_INC_\n\n/* Helper macros.  */\n#define INSTR_PROF_SIMPLE_QUOTE(x) #x\n#define INSTR_PROF_QUOTE(x) INSTR_PROF_SIMPLE_QUOTE(x)\n#define INSTR_PROF_SIMPLE_CONCAT(x,y) x ## y\n#define INSTR_PROF_CONCAT(x,y) INSTR_PROF_SIMPLE_CONCAT(x,y)\n\n/* Magic number to detect file format and endianness.\n * Use 255 at one end, since no UTF-8 file can use that character.  Avoid 0,\n * so that utilities, like strings, don't grab it as a string.  129 is also\n * invalid UTF-8, and high enough to be interesting.\n * Use \"lprofr\" in the centre to stand for \"LLVM Profile Raw\", or \"lprofR\"\n * for 32-bit platforms.\n */\n#define INSTR_PROF_RAW_MAGIC_64 (uint64_t)255 << 56 | (uint64_t)'l' << 48 | \\\n       (uint64_t)'p' << 40 | (uint64_t)'r' << 32 | (uint64_t)'o' << 24 |  \\\n        (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129\n#define INSTR_PROF_RAW_MAGIC_32 (uint64_t)255 << 56 | (uint64_t)'l' << 48 | \\\n       (uint64_t)'p' << 40 | (uint64_t)'r' << 32 | (uint64_t)'o' << 24 |  \\\n        (uint64_t)'f' << 16 | (uint64_t)'R' << 8 | (uint64_t)129\n\n/* Raw profile format version. */\n#define INSTR_PROF_RAW_VERSION 2\n\n/* Runtime section names and name strings.  */\n#define INSTR_PROF_DATA_SECT_NAME __llvm_prf_data\n#define INSTR_PROF_NAME_SECT_NAME __llvm_prf_names\n#define INSTR_PROF_CNTS_SECT_NAME __llvm_prf_cnts\n\n#define INSTR_PROF_DATA_SECT_NAME_STR \\\n        INSTR_PROF_QUOTE(INSTR_PROF_DATA_SECT_NAME)\n#define INSTR_PROF_NAME_SECT_NAME_STR \\\n        INSTR_PROF_QUOTE(INSTR_PROF_NAME_SECT_NAME)\n#define INSTR_PROF_CNTS_SECT_NAME_STR \\\n        INSTR_PROF_QUOTE(INSTR_PROF_CNTS_SECT_NAME)\n\n/* Macros to define start/stop section symbol for a given\n * section on Linux. For instance\n * INSTR_PROF_SECT_START(INSTR_PROF_DATA_SECT_NAME) will\n * expand to __start___llvm_prof_data\n */\n#define INSTR_PROF_SECT_START(Sect) \\\n        INSTR_PROF_CONCAT(__start_,Sect)\n#define INSTR_PROF_SECT_STOP(Sect) \\\n        INSTR_PROF_CONCAT(__stop_,Sect)\n\n/* Value Profiling API linkage name.  */\n#define INSTR_PROF_VALUE_PROF_FUNC __llvm_profile_instrument_target\n#define INSTR_PROF_VALUE_PROF_FUNC_STR \\\n        INSTR_PROF_QUOTE(INSTR_PROF_VALUE_PROF_FUNC)\n\n/* InstrProfile per-function control data alignment.  */\n#define INSTR_PROF_DATA_ALIGNMENT 8\n\n/* The data structure that represents a tracked value by the\n * value profiler.\n */\ntypedef struct InstrProfValueData {\n  /* Profiled value. */\n  uint64_t Value;\n  /* Number of times the value appears in the training run. */\n  uint64_t Count;\n} InstrProfValueData;\n\n/* This is an internal data structure used by value profiler. It\n * is defined here to allow serialization code sharing by LLVM\n * to be used in unit test.\n */\ntypedef struct ValueProfNode {\n  InstrProfValueData VData;\n  struct ValueProfNode *Next;\n} ValueProfNode;\n\n#endif /* INSTR_PROF_DATA_INC_ */\n\n#else\n#undef INSTR_PROF_DATA_DEFINED\n#endif\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfiling.c",
    "content": "/*===- InstrProfiling.c - Support library for PGO instrumentation ---------===*\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|*\n\\*===----------------------------------------------------------------------===*/\n\n#include \"InstrProfiling.h\"\n#include \"InstrProfilingInternal.h\"\n#include <limits.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#define INSTR_PROF_VALUE_PROF_DATA\n#include \"InstrProfData.inc\"\n\nchar *(*GetEnvHook)(const char *) = 0;\n\nCOMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_magic(void) {\n  return sizeof(void *) == sizeof(uint64_t) ? (INSTR_PROF_RAW_MAGIC_64)\n                                            : (INSTR_PROF_RAW_MAGIC_32);\n}\n\n/* Return the number of bytes needed to add to SizeInBytes to make it\n *   the result a multiple of 8.\n */\nCOMPILER_RT_VISIBILITY uint8_t\n__llvm_profile_get_num_padding_bytes(uint64_t SizeInBytes) {\n  return 7 & (sizeof(uint64_t) - SizeInBytes % sizeof(uint64_t));\n}\n\nCOMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_version(void) {\n  return INSTR_PROF_RAW_VERSION;\n}\n\nCOMPILER_RT_VISIBILITY void __llvm_profile_reset_counters(void) {\n  uint64_t *I = __llvm_profile_begin_counters();\n  uint64_t *E = __llvm_profile_end_counters();\n\n  memset(I, 0, sizeof(uint64_t) * (E - I));\n\n  const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();\n  const __llvm_profile_data *DataEnd = __llvm_profile_end_data();\n  const __llvm_profile_data *DI;\n  for (DI = DataBegin; DI != DataEnd; ++DI) {\n    uint64_t CurrentVSiteCount = 0;\n    uint32_t VKI, i;\n    if (!DI->Values)\n      continue;\n\n    ValueProfNode **ValueCounters = (ValueProfNode **)DI->Values;\n\n    for (VKI = IPVK_First; VKI <= IPVK_Last; ++VKI)\n      CurrentVSiteCount += DI->NumValueSites[VKI];\n\n    for (i = 0; i < CurrentVSiteCount; ++i) {\n      ValueProfNode *CurrentVNode = ValueCounters[i];\n\n      while (CurrentVNode) {\n        CurrentVNode->VData.Count = 0;\n        CurrentVNode = CurrentVNode->Next;\n      }\n    }\n  }\n}\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfiling.h",
    "content": "/*===- InstrProfiling.h- Support library for PGO instrumentation ----------===*\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|*\n\\*===----------------------------------------------------------------------===*/\n\n#ifndef PROFILE_INSTRPROFILING_H_\n#define PROFILE_INSTRPROFILING_H_\n\n#include \"InstrProfilingPort.h\"\n#include \"InstrProfData.inc\"\n\nenum ValueKind {\n#define VALUE_PROF_KIND(Enumerator, Value) Enumerator = Value,\n#include \"InstrProfData.inc\"\n};\n\ntypedef void *IntPtrT;\ntypedef struct COMPILER_RT_ALIGNAS(INSTR_PROF_DATA_ALIGNMENT)\n    __llvm_profile_data {\n#define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) Type Name;\n#include \"InstrProfData.inc\"\n} __llvm_profile_data;\n\ntypedef struct __llvm_profile_header {\n#define INSTR_PROF_RAW_HEADER(Type, Name, Initializer) Type Name;\n#include \"InstrProfData.inc\"\n} __llvm_profile_header;\n\n/*!\n * \\brief Get number of bytes necessary to pad the argument to eight\n * byte boundary.\n */\nuint8_t __llvm_profile_get_num_padding_bytes(uint64_t SizeInBytes);\n\n/*!\n * \\brief Get required size for profile buffer.\n */\nuint64_t __llvm_profile_get_size_for_buffer(void);\n\n/*!\n * \\brief Write instrumentation data to the given buffer.\n *\n * \\pre \\c Buffer is the start of a buffer at least as big as \\a\n * __llvm_profile_get_size_for_buffer().\n */\nint __llvm_profile_write_buffer(char *Buffer);\n\nconst __llvm_profile_data *__llvm_profile_begin_data(void);\nconst __llvm_profile_data *__llvm_profile_end_data(void);\nconst char *__llvm_profile_begin_names(void);\nconst char *__llvm_profile_end_names(void);\nuint64_t *__llvm_profile_begin_counters(void);\nuint64_t *__llvm_profile_end_counters(void);\n\n/*!\n * \\brief Clear profile counters to zero.\n *\n */\nvoid __llvm_profile_reset_counters(void);\n\n/*!\n * \\brief Counts the number of times a target value is seen.\n *\n * Records the target value for the CounterIndex if not seen before. Otherwise,\n * increments the counter associated w/ the target value.\n * void __llvm_profile_instrument_target(uint64_t TargetValue, void *Data,\n *                                       uint32_t CounterIndex);\n */\nvoid INSTR_PROF_VALUE_PROF_FUNC(\n#define VALUE_PROF_FUNC_PARAM(ArgType, ArgName, ArgLLVMType) ArgType ArgName\n#include \"InstrProfData.inc\"\n);\n\n/*!\n * \\brief Prepares the value profiling data for output.\n *\n * Prepares a single __llvm_profile_value_data array out of the many\n * ValueProfNode trees (one per instrumented function).\n */\nuint64_t __llvm_profile_gather_value_data(uint8_t **DataArray);\n\n/*!\n * \\brief Write instrumentation data to the current file.\n *\n * Writes to the file with the last name given to \\a __llvm_profile_set_filename(),\n * or if it hasn't been called, the \\c LLVM_PROFILE_FILE environment variable,\n * or if that's not set, the last name given to\n * \\a __llvm_profile_override_default_filename(), or if that's not set,\n * \\c \"default.profraw\".\n */\nint __llvm_profile_write_file(void);\n\n/*!\n * \\brief Set the filename for writing instrumentation data.\n *\n * Sets the filename to be used for subsequent calls to\n * \\a __llvm_profile_write_file().\n *\n * \\c Name is not copied, so it must remain valid.  Passing NULL resets the\n * filename logic to the default behaviour.\n */\nvoid __llvm_profile_set_filename(const char *Name);\n\n/*!\n * \\brief Set the filename for writing instrumentation data, unless the\n * \\c LLVM_PROFILE_FILE environment variable was set.\n *\n * Unless overridden, sets the filename to be used for subsequent calls to\n * \\a __llvm_profile_write_file().\n *\n * \\c Name is not copied, so it must remain valid.  Passing NULL resets the\n * filename logic to the default behaviour (unless the \\c LLVM_PROFILE_FILE\n * was set in which case it has no effect).\n */\nvoid __llvm_profile_override_default_filename(const char *Name);\n\n/*! \\brief Register to write instrumentation data to file at exit. */\nint __llvm_profile_register_write_file_atexit(void);\n\n/*! \\brief Initialize file handling. */\nvoid __llvm_profile_initialize_file(void);\n\n/*! \\brief Get the magic token for the file format. */\nuint64_t __llvm_profile_get_magic(void);\n\n/*! \\brief Get the version of the file format. */\nuint64_t __llvm_profile_get_version(void);\n\n#endif /* PROFILE_INSTRPROFILING_H_ */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfilingBuffer.c",
    "content": "/*===- InstrProfilingBuffer.c - Write instrumentation to a memory buffer --===*\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|*\n\\*===----------------------------------------------------------------------===*/\n\n#include \"InstrProfiling.h\"\n#include \"InstrProfilingInternal.h\"\n\n#include <string.h>\n\nCOMPILER_RT_VISIBILITY\nuint64_t __llvm_profile_get_size_for_buffer(void) {\n  const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();\n  const __llvm_profile_data *DataEnd = __llvm_profile_end_data();\n  const uint64_t *CountersBegin = __llvm_profile_begin_counters();\n  const uint64_t *CountersEnd = __llvm_profile_end_counters();\n  const char *NamesBegin = __llvm_profile_begin_names();\n  const char *NamesEnd = __llvm_profile_end_names();\n\n  return __llvm_profile_get_size_for_buffer_internal(\n      DataBegin, DataEnd, CountersBegin, CountersEnd, NamesBegin, NamesEnd);\n}\n\n#define PROFILE_RANGE_SIZE(Range) (Range##End - Range##Begin)\n\nCOMPILER_RT_VISIBILITY\nuint64_t __llvm_profile_get_size_for_buffer_internal(\n    const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd,\n    const uint64_t *CountersBegin, const uint64_t *CountersEnd,\n    const char *NamesBegin, const char *NamesEnd) {\n  /* Match logic in __llvm_profile_write_buffer(). */\n  const uint64_t NamesSize = PROFILE_RANGE_SIZE(Names) * sizeof(char);\n  const uint8_t Padding = __llvm_profile_get_num_padding_bytes(NamesSize);\n  return sizeof(__llvm_profile_header) +\n         PROFILE_RANGE_SIZE(Data) * sizeof(__llvm_profile_data) +\n         PROFILE_RANGE_SIZE(Counters) * sizeof(uint64_t) + NamesSize + Padding;\n}\n\n/* The buffer writer is reponsponsible in keeping writer state\n * across the call.\n */\nstatic uint32_t bufferWriter(ProfDataIOVec *IOVecs, uint32_t NumIOVecs,\n                             void **WriterCtx) {\n  uint32_t I;\n  char **Buffer = (char **)WriterCtx;\n  for (I = 0; I < NumIOVecs; I++) {\n    size_t Length = IOVecs[I].ElmSize * IOVecs[I].NumElm;\n    memcpy(*Buffer, IOVecs[I].Data, Length);\n    *Buffer += Length;\n  }\n  return 0;\n}\n\nCOMPILER_RT_VISIBILITY int __llvm_profile_write_buffer(char *Buffer) {\n  return llvmWriteProfData(bufferWriter, Buffer, 0, 0);\n}\n\nCOMPILER_RT_VISIBILITY int __llvm_profile_write_buffer_internal(\n    char *Buffer, const __llvm_profile_data *DataBegin,\n    const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin,\n    const uint64_t *CountersEnd, const char *NamesBegin, const char *NamesEnd) {\n  return llvmWriteProfDataImpl(bufferWriter, Buffer, DataBegin, DataEnd,\n                               CountersBegin, CountersEnd, 0, 0, NamesBegin,\n                               NamesEnd);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfilingFile.c",
    "content": "/*===- InstrProfilingFile.c - Write instrumentation to a file -------------===*\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|*\n\\*===----------------------------------------------------------------------===*/\n\n#include \"InstrProfiling.h\"\n#include \"InstrProfilingInternal.h\"\n#include \"InstrProfilingUtil.h\"\n#include <errno.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#define UNCONST(ptr) ((void *)(uintptr_t)(ptr))\n\n/* Return 1 if there is an error, otherwise return  0.  */\nstatic uint32_t fileWriter(ProfDataIOVec *IOVecs, uint32_t NumIOVecs,\n                           void **WriterCtx) {\n  uint32_t I;\n  FILE *File = (FILE *)*WriterCtx;\n  for (I = 0; I < NumIOVecs; I++) {\n    if (fwrite(IOVecs[I].Data, IOVecs[I].ElmSize, IOVecs[I].NumElm, File) !=\n        IOVecs[I].NumElm)\n      return 1;\n  }\n  return 0;\n}\n\nstatic int writeFile(FILE *File) {\n  uint8_t *ValueDataBegin = NULL;\n  const uint64_t ValueDataSize =\n      __llvm_profile_gather_value_data(&ValueDataBegin);\n  int r = llvmWriteProfData(fileWriter, File, ValueDataBegin, ValueDataSize);\n  free(ValueDataBegin);\n  return r;\n}\n\nstatic int writeFileWithName(const char *OutputName) {\n  int RetVal;\n  FILE *OutputFile;\n  if (!OutputName || !OutputName[0])\n    return -1;\n\n  /* Append to the file to support profiling multiple shared objects. */\n  OutputFile = fopen(OutputName, \"ab\");\n  if (!OutputFile)\n    return -1;\n\n  RetVal = writeFile(OutputFile);\n\n  fclose(OutputFile);\n  return RetVal;\n}\n\nCOMPILER_RT_WEAK int __llvm_profile_OwnsFilename = 0;\nCOMPILER_RT_WEAK const char *__llvm_profile_CurrentFilename = NULL;\n\nstatic void truncateCurrentFile(void) {\n  const char *Filename;\n  FILE *File;\n\n  Filename = __llvm_profile_CurrentFilename;\n  if (!Filename || !Filename[0])\n    return;\n\n  /* Create the directory holding the file, if needed. */\n  if (strchr(Filename, '/')) {\n    char *Copy = malloc(strlen(Filename) + 1);\n    strcpy(Copy, Filename);\n    __llvm_profile_recursive_mkdir(Copy);\n    free(Copy);\n  }\n\n  /* Truncate the file.  Later we'll reopen and append. */\n  File = fopen(Filename, \"w\");\n  if (!File)\n    return;\n  fclose(File);\n}\n\nstatic void setFilename(const char *Filename, int OwnsFilename) {\n  /* Check if this is a new filename and therefore needs truncation. */\n  int NewFile = !__llvm_profile_CurrentFilename ||\n      (Filename && strcmp(Filename, __llvm_profile_CurrentFilename));\n  if (__llvm_profile_OwnsFilename)\n    free(UNCONST(__llvm_profile_CurrentFilename));\n\n  __llvm_profile_CurrentFilename = Filename;\n  __llvm_profile_OwnsFilename = OwnsFilename;\n\n  /* If not a new file, append to support profiling multiple shared objects. */\n  if (NewFile)\n    truncateCurrentFile();\n}\n\nstatic void resetFilenameToDefault(void) { setFilename(\"default.profraw\", 0); }\n\nint getpid(void);\nstatic int setFilenamePossiblyWithPid(const char *Filename) {\n#define MAX_PID_SIZE 16\n  char PidChars[MAX_PID_SIZE] = {0};\n  int NumPids = 0, PidLength = 0;\n  char *Allocated;\n  int I, J;\n\n  /* Reset filename on NULL, except with env var which is checked by caller. */\n  if (!Filename) {\n    resetFilenameToDefault();\n    return 0;\n  }\n\n  /* Check the filename for \"%p\", which indicates a pid-substitution. */\n  for (I = 0; Filename[I]; ++I)\n    if (Filename[I] == '%' && Filename[++I] == 'p')\n      if (!NumPids++) {\n        PidLength = snprintf(PidChars, MAX_PID_SIZE, \"%d\", getpid());\n        if (PidLength <= 0)\n          return -1;\n      }\n  if (!NumPids) {\n    setFilename(Filename, 0);\n    return 0;\n  }\n\n  /* Allocate enough space for the substituted filename. */\n  Allocated = malloc(I + NumPids*(PidLength - 2) + 1);\n  if (!Allocated)\n    return -1;\n\n  /* Construct the new filename. */\n  for (I = 0, J = 0; Filename[I]; ++I)\n    if (Filename[I] == '%') {\n      if (Filename[++I] == 'p') {\n        memcpy(Allocated + J, PidChars, PidLength);\n        J += PidLength;\n      }\n      /* Drop any unknown substitutions. */\n    } else\n      Allocated[J++] = Filename[I];\n  Allocated[J] = 0;\n\n  /* Use the computed name. */\n  setFilename(Allocated, 1);\n  return 0;\n}\n\nstatic int setFilenameFromEnvironment(void) {\n  const char *Filename = getenv(\"LLVM_PROFILE_FILE\");\n\n  if (!Filename || !Filename[0])\n    return -1;\n\n  return setFilenamePossiblyWithPid(Filename);\n}\n\nstatic void setFilenameAutomatically(void) {\n  if (!setFilenameFromEnvironment())\n    return;\n\n  resetFilenameToDefault();\n}\n\nCOMPILER_RT_VISIBILITY\nvoid __llvm_profile_initialize_file(void) {\n  /* Check if the filename has been initialized. */\n  if (__llvm_profile_CurrentFilename)\n    return;\n\n  /* Detect the filename and truncate. */\n  setFilenameAutomatically();\n}\n\nCOMPILER_RT_VISIBILITY\nvoid __llvm_profile_set_filename(const char *Filename) {\n  setFilenamePossiblyWithPid(Filename);\n}\n\nCOMPILER_RT_VISIBILITY\nvoid __llvm_profile_override_default_filename(const char *Filename) {\n  /* If the env var is set, skip setting filename from argument. */\n  const char *Env_Filename = getenv(\"LLVM_PROFILE_FILE\");\n  if (Env_Filename && Env_Filename[0])\n    return;\n  setFilenamePossiblyWithPid(Filename);\n}\n\nCOMPILER_RT_VISIBILITY\nint __llvm_profile_write_file(void) {\n  int rc;\n\n  GetEnvHook = &getenv;\n  /* Check the filename. */\n  if (!__llvm_profile_CurrentFilename) {\n    PROF_ERR(\"LLVM Profile: Failed to write file : %s\\n\", \"Filename not set\");\n    return -1;\n  }\n\n  /* Write the file. */\n  rc = writeFileWithName(__llvm_profile_CurrentFilename);\n  if (rc)\n    PROF_ERR(\"LLVM Profile: Failed to write file \\\"%s\\\": %s\\n\",\n            __llvm_profile_CurrentFilename, strerror(errno));\n  return rc;\n}\n\nstatic void writeFileWithoutReturn(void) { __llvm_profile_write_file(); }\n\nCOMPILER_RT_VISIBILITY\nint __llvm_profile_register_write_file_atexit(void) {\n  static int HasBeenRegistered = 0;\n\n  if (HasBeenRegistered)\n    return 0;\n\n  HasBeenRegistered = 1;\n  return atexit(writeFileWithoutReturn);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfilingInternal.h",
    "content": "/*===- InstrProfiling.h- Support library for PGO instrumentation ----------===*\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|*\n\\*===----------------------------------------------------------------------===*/\n\n#ifndef PROFILE_INSTRPROFILING_INTERNALH_\n#define PROFILE_INSTRPROFILING_INTERNALH_\n\n#include \"InstrProfiling.h\"\n#include \"stddef.h\"\n\n/*!\n * \\brief Write instrumentation data to the given buffer, given explicit\n * pointers to the live data in memory.  This function is probably not what you\n * want.  Use __llvm_profile_get_size_for_buffer instead.  Use this function if\n * your program has a custom memory layout.\n */\nuint64_t __llvm_profile_get_size_for_buffer_internal(\n    const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd,\n    const uint64_t *CountersBegin, const uint64_t *CountersEnd,\n    const char *NamesBegin, const char *NamesEnd);\n\n/*!\n * \\brief Write instrumentation data to the given buffer, given explicit\n * pointers to the live data in memory.  This function is probably not what you\n * want.  Use __llvm_profile_write_buffer instead.  Use this function if your\n * program has a custom memory layout.\n *\n * \\pre \\c Buffer is the start of a buffer at least as big as \\a\n * __llvm_profile_get_size_for_buffer_internal().\n */\nint __llvm_profile_write_buffer_internal(\n    char *Buffer, const __llvm_profile_data *DataBegin,\n    const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin,\n    const uint64_t *CountersEnd, const char *NamesBegin, const char *NamesEnd);\n\n/*!\n * This is an internal function not intended to be used externally.\n */\ntypedef struct ProfDataIOVec {\n  const void *Data;\n  size_t ElmSize;\n  size_t NumElm;\n} ProfDataIOVec;\n\ntypedef uint32_t (*WriterCallback)(ProfDataIOVec *, uint32_t NumIOVecs,\n                                   void **WriterCtx);\nint llvmWriteProfData(WriterCallback Writer, void *WriterCtx,\n                      const uint8_t *ValueDataBegin,\n                      const uint64_t ValueDataSize);\nint llvmWriteProfDataImpl(WriterCallback Writer, void *WriterCtx,\n                          const __llvm_profile_data *DataBegin,\n                          const __llvm_profile_data *DataEnd,\n                          const uint64_t *CountersBegin,\n                          const uint64_t *CountersEnd,\n                          const uint8_t *ValueDataBegin,\n                          const uint64_t ValueDataSize, const char *NamesBegin,\n                          const char *NamesEnd);\n\nextern char *(*GetEnvHook)(const char *);\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfilingPlatformDarwin.c",
    "content": "/*===- InstrProfilingPlatformDarwin.c - Profile data on Darwin ------------===*\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|*\n\\*===----------------------------------------------------------------------===*/\n\n#include \"InstrProfiling.h\"\n\n#if defined(__APPLE__)\n/* Use linker magic to find the bounds of the Data section. */\nCOMPILER_RT_VISIBILITY\nextern __llvm_profile_data\n    DataStart __asm(\"section$start$__DATA$\" INSTR_PROF_DATA_SECT_NAME_STR);\nCOMPILER_RT_VISIBILITY\nextern __llvm_profile_data\n    DataEnd __asm(\"section$end$__DATA$\" INSTR_PROF_DATA_SECT_NAME_STR);\nCOMPILER_RT_VISIBILITY\nextern char\n    NamesStart __asm(\"section$start$__DATA$\" INSTR_PROF_NAME_SECT_NAME_STR);\nCOMPILER_RT_VISIBILITY\nextern char NamesEnd __asm(\"section$end$__DATA$\" INSTR_PROF_NAME_SECT_NAME_STR);\nCOMPILER_RT_VISIBILITY\nextern uint64_t\n    CountersStart __asm(\"section$start$__DATA$\" INSTR_PROF_CNTS_SECT_NAME_STR);\nCOMPILER_RT_VISIBILITY\nextern uint64_t\n    CountersEnd __asm(\"section$end$__DATA$\" INSTR_PROF_CNTS_SECT_NAME_STR);\n\nCOMPILER_RT_VISIBILITY\nconst __llvm_profile_data *__llvm_profile_begin_data(void) {\n  return &DataStart;\n}\nCOMPILER_RT_VISIBILITY\nconst __llvm_profile_data *__llvm_profile_end_data(void) { return &DataEnd; }\nCOMPILER_RT_VISIBILITY\nconst char *__llvm_profile_begin_names(void) { return &NamesStart; }\nCOMPILER_RT_VISIBILITY\nconst char *__llvm_profile_end_names(void) { return &NamesEnd; }\nCOMPILER_RT_VISIBILITY\nuint64_t *__llvm_profile_begin_counters(void) { return &CountersStart; }\nCOMPILER_RT_VISIBILITY\nuint64_t *__llvm_profile_end_counters(void) { return &CountersEnd; }\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c",
    "content": "/*===- InstrProfilingPlatformLinux.c - Profile data Linux platform ------===*\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|*\n\\*===----------------------------------------------------------------------===*/\n\n#include \"InstrProfiling.h\"\n\n#if defined(__linux__) || defined(__FreeBSD__)\n#include <stdlib.h>\n\n#define PROF_DATA_START INSTR_PROF_SECT_START(INSTR_PROF_DATA_SECT_NAME)\n#define PROF_DATA_STOP INSTR_PROF_SECT_STOP(INSTR_PROF_DATA_SECT_NAME)\n#define PROF_NAME_START INSTR_PROF_SECT_START(INSTR_PROF_NAME_SECT_NAME)\n#define PROF_NAME_STOP INSTR_PROF_SECT_STOP(INSTR_PROF_NAME_SECT_NAME)\n#define PROF_CNTS_START INSTR_PROF_SECT_START(INSTR_PROF_CNTS_SECT_NAME)\n#define PROF_CNTS_STOP INSTR_PROF_SECT_STOP(INSTR_PROF_CNTS_SECT_NAME)\n\n/* Declare section start and stop symbols for various sections\n * generated by compiler instrumentation.\n */\nextern __llvm_profile_data PROF_DATA_START COMPILER_RT_VISIBILITY;\nextern __llvm_profile_data PROF_DATA_STOP COMPILER_RT_VISIBILITY;\nextern uint64_t PROF_CNTS_START COMPILER_RT_VISIBILITY;\nextern uint64_t PROF_CNTS_STOP COMPILER_RT_VISIBILITY;\nextern char PROF_NAME_START COMPILER_RT_VISIBILITY;\nextern char PROF_NAME_STOP COMPILER_RT_VISIBILITY;\n\n/* Add dummy data to ensure the section is always created. */\n__llvm_profile_data\n    __prof_data_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_DATA_SECT_NAME_STR);\nuint64_t\n    __prof_cnts_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_CNTS_SECT_NAME_STR);\nchar __prof_nms_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_NAME_SECT_NAME_STR);\n\nCOMPILER_RT_VISIBILITY const __llvm_profile_data *\n__llvm_profile_begin_data(void) {\n  return &PROF_DATA_START;\n}\nCOMPILER_RT_VISIBILITY const __llvm_profile_data *\n__llvm_profile_end_data(void) {\n  return &PROF_DATA_STOP;\n}\nCOMPILER_RT_VISIBILITY const char *__llvm_profile_begin_names(void) {\n  return &PROF_NAME_START;\n}\nCOMPILER_RT_VISIBILITY const char *__llvm_profile_end_names(void) {\n  return &PROF_NAME_STOP;\n}\nCOMPILER_RT_VISIBILITY uint64_t *__llvm_profile_begin_counters(void) {\n  return &PROF_CNTS_START;\n}\nCOMPILER_RT_VISIBILITY uint64_t *__llvm_profile_end_counters(void) {\n  return &PROF_CNTS_STOP;\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfilingPlatformOther.c",
    "content": "/*===- InstrProfilingPlatformOther.c - Profile data default platform ------===*\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|*\n\\*===----------------------------------------------------------------------===*/\n\n#include \"InstrProfiling.h\"\n\n#if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__)\n#include <stdlib.h>\n\nstatic const __llvm_profile_data *DataFirst = NULL;\nstatic const __llvm_profile_data *DataLast = NULL;\nstatic const char *NamesFirst = NULL;\nstatic const char *NamesLast = NULL;\nstatic uint64_t *CountersFirst = NULL;\nstatic uint64_t *CountersLast = NULL;\n\n/*!\n * \\brief Register an instrumented function.\n *\n * Calls to this are emitted by clang with -fprofile-instr-generate.  Such\n * calls are only required (and only emitted) on targets where we haven't\n * implemented linker magic to find the bounds of the sections.\n */\nCOMPILER_RT_VISIBILITY\nvoid __llvm_profile_register_function(void *Data_) {\n  /* TODO: Only emit this function if we can't use linker magic. */\n  const __llvm_profile_data *Data = (__llvm_profile_data *)Data_;\n  if (!DataFirst) {\n    DataFirst = Data;\n    DataLast = Data + 1;\n    NamesFirst = Data->NamePtr;\n    NamesLast = (const char *)Data->NamePtr + Data->NameSize;\n    CountersFirst = Data->CounterPtr;\n    CountersLast = (uint64_t *)Data->CounterPtr + Data->NumCounters;\n    return;\n  }\n\n#define UPDATE_FIRST(First, New) First = New < First ? New : First\n  UPDATE_FIRST(DataFirst, Data);\n  UPDATE_FIRST(NamesFirst, (const char *)Data->NamePtr);\n  UPDATE_FIRST(CountersFirst, (uint64_t *)Data->CounterPtr);\n#undef UPDATE_FIRST\n\n#define UPDATE_LAST(Last, New) Last = New > Last ? New : Last\n  UPDATE_LAST(DataLast, Data + 1);\n  UPDATE_LAST(NamesLast, (const char *)Data->NamePtr + Data->NameSize);\n  UPDATE_LAST(CountersLast, (uint64_t *)Data->CounterPtr + Data->NumCounters);\n#undef UPDATE_LAST\n}\n\nCOMPILER_RT_VISIBILITY\nconst __llvm_profile_data *__llvm_profile_begin_data(void) { return DataFirst; }\nCOMPILER_RT_VISIBILITY\nconst __llvm_profile_data *__llvm_profile_end_data(void) { return DataLast; }\nCOMPILER_RT_VISIBILITY\nconst char *__llvm_profile_begin_names(void) { return NamesFirst; }\nCOMPILER_RT_VISIBILITY\nconst char *__llvm_profile_end_names(void) { return NamesLast; }\nCOMPILER_RT_VISIBILITY\nuint64_t *__llvm_profile_begin_counters(void) { return CountersFirst; }\nCOMPILER_RT_VISIBILITY\nuint64_t *__llvm_profile_end_counters(void) { return CountersLast; }\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfilingPort.h",
    "content": "/*===- InstrProfilingPort.h- Support library for PGO instrumentation ------===*\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|*\n\\*===----------------------------------------------------------------------===*/\n\n#ifndef PROFILE_INSTRPROFILING_PORT_H_\n#define PROFILE_INSTRPROFILING_PORT_H_\n\n#ifdef _MSC_VER\n#define COMPILER_RT_ALIGNAS(x) __declspec(align(x))\n#define COMPILER_RT_VISIBILITY\n#define COMPILER_RT_WEAK __declspec(selectany)\n#elif __GNUC__\n#define COMPILER_RT_ALIGNAS(x) __attribute__((aligned(x)))\n#define COMPILER_RT_VISIBILITY __attribute__((visibility(\"hidden\")))\n#define COMPILER_RT_WEAK __attribute__((weak))\n#endif\n\n#define COMPILER_RT_SECTION(Sect) __attribute__((section(Sect)))\n\n#if COMPILER_RT_HAS_ATOMICS == 1\n#ifdef _MSC_VER\n#include <windows.h>\n#if defined(_WIN64)\n#define COMPILER_RT_BOOL_CMPXCHG(Ptr, OldV, NewV)                              \\\n  (InterlockedCompareExchange64((LONGLONG volatile *)Ptr, (LONGLONG)NewV,      \\\n                                (LONGLONG)OldV) == (LONGLONG)OldV)\n#else\n#define COMPILER_RT_BOOL_CMPXCHG(Ptr, OldV, NewV)                              \\\n  (InterlockedCompareExchange((LONG volatile *)Ptr, (LONG)NewV, (LONG)OldV) == \\\n   (LONG)OldV)\n#endif\n#else\n#define COMPILER_RT_BOOL_CMPXCHG(Ptr, OldV, NewV)                              \\\n  __sync_bool_compare_and_swap(Ptr, OldV, NewV)\n#endif\n#else\n#define COMPILER_RT_BOOL_CMPXCHG(Ptr, OldV, NewV)                              \\\n  BoolCmpXchg((void **)Ptr, OldV, NewV)\n#endif\n\n#define PROF_ERR(Format, ...)                                                  \\\n  if (GetEnvHook && GetEnvHook(\"LLVM_PROFILE_VERBOSE_ERRORS\"))                 \\\n    fprintf(stderr, Format, __VA_ARGS__);\n\n#if defined(__FreeBSD__) && defined(__i386__)\n\n/* System headers define 'size_t' incorrectly on x64 FreeBSD (prior to\n * FreeBSD 10, r232261) when compiled in 32-bit mode.\n */\n#define PRIu64 \"llu\"\ntypedef unsigned char uint8_t;\ntypedef unsigned short uint16_t;\ntypedef unsigned int uint32_t;\ntypedef unsigned long long uint64_t;\ntypedef uint32_t uintptr_t;\n#elif defined(__FreeBSD__) && defined(__x86_64__)\n#define PRIu64 \"lu\"\ntypedef unsigned char uint8_t;\ntypedef unsigned short uint16_t;\ntypedef unsigned int uint32_t;\ntypedef unsigned long long uint64_t;\ntypedef unsigned long int uintptr_t;\n\n#else /* defined(__FreeBSD__) && defined(__i386__) */\n\n#include <inttypes.h>\n#include <stdint.h>\n\n#endif /* defined(__FreeBSD__) && defined(__i386__) */\n\n#endif /* PROFILE_INSTRPROFILING_PORT_H_ */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfilingRuntime.cc",
    "content": "//===- InstrProfilingRuntime.cpp - PGO runtime initialization -------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\nextern \"C\" {\n\n#include \"InstrProfiling.h\"\n\nCOMPILER_RT_VISIBILITY int __llvm_profile_runtime;\n}\n\nnamespace {\n\nclass RegisterRuntime {\npublic:\n  RegisterRuntime() {\n    __llvm_profile_register_write_file_atexit();\n    __llvm_profile_initialize_file();\n  }\n};\n\nRegisterRuntime Registration;\n\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfilingUtil.c",
    "content": "/*===- InstrProfilingUtil.c - Support library for PGO instrumentation -----===*\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|*\n\\*===----------------------------------------------------------------------===*/\n\n#include \"InstrProfilingUtil.h\"\n#include \"InstrProfiling.h\"\n\n#ifdef _WIN32\n#include <direct.h>\n#elif I386_FREEBSD\nint mkdir(const char*, unsigned short);\n#else\n#include <sys/stat.h>\n#include <sys/types.h>\n#endif\n\nCOMPILER_RT_VISIBILITY\nvoid __llvm_profile_recursive_mkdir(char *path) {\n  int i;\n\n  for (i = 1; path[i] != '\\0'; ++i) {\n    if (path[i] != '/') continue;\n    path[i] = '\\0';\n#ifdef _WIN32\n    _mkdir(path);\n#else\n    mkdir(path, 0755);  /* Some of these will fail, ignore it. */\n#endif\n    path[i] = '/';\n  }\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfilingUtil.h",
    "content": "/*===- InstrProfilingUtil.h - Support library for PGO instrumentation -----===*\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|*\n\\*===----------------------------------------------------------------------===*/\n\n#ifndef PROFILE_INSTRPROFILINGUTIL_H\n#define PROFILE_INSTRPROFILINGUTIL_H\n\n/*! \\brief Create a directory tree. */\nvoid __llvm_profile_recursive_mkdir(char *Pathname);\n\n#endif  /* PROFILE_INSTRPROFILINGUTIL_H */\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfilingValue.c",
    "content": "/*===- InstrProfilingValue.c - Support library for PGO instrumentation ----===*\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|*\n\\*===----------------------------------------------------------------------===*/\n\n#include \"InstrProfiling.h\"\n#include \"InstrProfilingInternal.h\"\n#include <limits.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#define INSTR_PROF_VALUE_PROF_DATA\n#define INSTR_PROF_COMMON_API_IMPL\n#include \"InstrProfData.inc\"\n\n#define PROF_OOM(Msg) PROF_ERR(Msg \":%s\\n\", \"Out of memory\");\n#define PROF_OOM_RETURN(Msg)                                                   \\\n  {                                                                            \\\n    PROF_OOM(Msg)                                                              \\\n    return 0;                                                                  \\\n  }\n\n#if COMPILER_RT_HAS_ATOMICS != 1\nCOMPILER_RT_VISIBILITY\nuint32_t BoolCmpXchg(void **Ptr, void *OldV, void *NewV) {\n  void *R = *Ptr;\n  if (R == OldV) {\n    *Ptr = NewV;\n    return 1;\n  }\n  return 0;\n}\n#endif\n\n/* This method is only used in value profiler mock testing.  */\nCOMPILER_RT_VISIBILITY void\n__llvm_profile_set_num_value_sites(__llvm_profile_data *Data,\n                                   uint32_t ValueKind, uint16_t NumValueSites) {\n  *((uint16_t *)&Data->NumValueSites[ValueKind]) = NumValueSites;\n}\n\n/* This method is only used in value profiler mock testing.  */\nCOMPILER_RT_VISIBILITY const __llvm_profile_data *\n__llvm_profile_iterate_data(const __llvm_profile_data *Data) {\n  return Data + 1;\n}\n\n/* This method is only used in value profiler mock testing.  */\nCOMPILER_RT_VISIBILITY void *\n__llvm_get_function_addr(const __llvm_profile_data *Data) {\n  return Data->FunctionPointer;\n}\n\n/* Allocate an array that holds the pointers to the linked lists of\n * value profile counter nodes. The number of element of the array\n * is the total number of value profile sites instrumented. Returns\n * 0 if allocation fails.\n */\n\nstatic int allocateValueProfileCounters(__llvm_profile_data *Data) {\n  uint64_t NumVSites = 0;\n  uint32_t VKI;\n  for (VKI = IPVK_First; VKI <= IPVK_Last; ++VKI)\n    NumVSites += Data->NumValueSites[VKI];\n\n  ValueProfNode **Mem =\n      (ValueProfNode **)calloc(NumVSites, sizeof(ValueProfNode *));\n  if (!Mem)\n    return 0;\n  if (!COMPILER_RT_BOOL_CMPXCHG(&Data->Values, 0, Mem)) {\n    free(Mem);\n    return 0;\n  }\n  return 1;\n}\n\nstatic void deallocateValueProfileCounters(__llvm_profile_data *Data) {\n  uint64_t NumVSites = 0, I;\n  uint32_t VKI;\n  if (!Data->Values)\n    return;\n  for (VKI = IPVK_First; VKI <= IPVK_Last; ++VKI)\n    NumVSites += Data->NumValueSites[VKI];\n  for (I = 0; I < NumVSites; I++) {\n    ValueProfNode *Node = ((ValueProfNode **)Data->Values)[I];\n    while (Node) {\n      ValueProfNode *Next = Node->Next;\n      free(Node);\n      Node = Next;\n    }\n  }\n  free(Data->Values);\n}\n\nCOMPILER_RT_VISIBILITY void\n__llvm_profile_instrument_target(uint64_t TargetValue, void *Data,\n                                 uint32_t CounterIndex) {\n\n  __llvm_profile_data *PData = (__llvm_profile_data *)Data;\n  if (!PData)\n    return;\n\n  if (!PData->Values) {\n    if (!allocateValueProfileCounters(PData))\n      return;\n  }\n\n  ValueProfNode **ValueCounters = (ValueProfNode **)PData->Values;\n  ValueProfNode *PrevVNode = NULL;\n  ValueProfNode *CurrentVNode = ValueCounters[CounterIndex];\n\n  uint8_t VDataCount = 0;\n  while (CurrentVNode) {\n    if (TargetValue == CurrentVNode->VData.Value) {\n      CurrentVNode->VData.Count++;\n      return;\n    }\n    PrevVNode = CurrentVNode;\n    CurrentVNode = CurrentVNode->Next;\n    ++VDataCount;\n  }\n\n  if (VDataCount >= UCHAR_MAX)\n    return;\n\n  CurrentVNode = (ValueProfNode *)calloc(1, sizeof(ValueProfNode));\n  if (!CurrentVNode)\n    return;\n\n  CurrentVNode->VData.Value = TargetValue;\n  CurrentVNode->VData.Count++;\n\n  uint32_t Success = 0;\n  if (!ValueCounters[CounterIndex])\n    Success =\n        COMPILER_RT_BOOL_CMPXCHG(&ValueCounters[CounterIndex], 0, CurrentVNode);\n  else if (PrevVNode && !PrevVNode->Next)\n    Success = COMPILER_RT_BOOL_CMPXCHG(&(PrevVNode->Next), 0, CurrentVNode);\n\n  if (!Success) {\n    free(CurrentVNode);\n    return;\n  }\n}\n\n/* For multi-threaded programs, while the profile is being dumped, other\n   threads may still be updating the value profile data and creating new\n   value entries. To accommadate this, we need to add extra bytes to the\n   data buffer. The size of the extra space is controlled by an environment\n   variable. */\nstatic unsigned getVprofExtraBytes() {\n  const char *ExtraStr =\n      GetEnvHook ? GetEnvHook(\"LLVM_VALUE_PROF_BUFFER_EXTRA\") : 0;\n  if (!ExtraStr || !ExtraStr[0])\n    return 1024;\n  return (unsigned)atoi(ExtraStr);\n}\n\n/* Extract the value profile data info from the runtime. */\n#define DEF_VALUE_RECORD(R, NS, V)                                             \\\n  ValueProfRuntimeRecord R;                                                    \\\n  if (initializeValueProfRuntimeRecord(&R, NS, V))                             \\\n    PROF_OOM_RETURN(\"Failed to write value profile data \");\n\n#define DTOR_VALUE_RECORD(R) finalizeValueProfRuntimeRecord(&R);\n\nCOMPILER_RT_VISIBILITY uint64_t\n__llvm_profile_gather_value_data(uint8_t **VDataArray) {\n  size_t S = 0, RealSize = 0, BufferCapacity = 0, Extra = 0;\n  __llvm_profile_data *I;\n  if (!VDataArray)\n    PROF_OOM_RETURN(\"Failed to write value profile data \");\n\n  const __llvm_profile_data *DataEnd = __llvm_profile_end_data();\n  const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();\n\n  /*\n   * Compute the total Size of the buffer to hold ValueProfData\n   * structures for functions with value profile data.\n   */\n  for (I = (__llvm_profile_data *)DataBegin; I != DataEnd; ++I) {\n\n    DEF_VALUE_RECORD(R, I->NumValueSites, I->Values);\n\n    /* Compute the size of ValueProfData from this runtime record.  */\n    if (getNumValueKindsRT(&R) != 0)\n      S += getValueProfDataSizeRT(&R);\n\n    DTOR_VALUE_RECORD(R);\n  }\n  /* No value sites or no value profile data is collected. */\n  if (!S)\n    return 0;\n\n  Extra = getVprofExtraBytes();\n  BufferCapacity = S + Extra;\n  *VDataArray = calloc(BufferCapacity, sizeof(uint8_t));\n  if (!*VDataArray)\n    PROF_OOM_RETURN(\"Failed to write value profile data \");\n\n  ValueProfData *VD = (ValueProfData *)(*VDataArray);\n  /*\n   * Extract value profile data and write into ValueProfData structure\n   * one by one. Note that new value profile data added to any value\n   * site (from another thread) after the ValueProfRuntimeRecord is\n   * initialized (when the profile data snapshot is taken) won't be\n   * collected. This is not a problem as those dropped value will have\n   * very low taken count.\n   */\n  for (I = (__llvm_profile_data *)DataBegin; I != DataEnd; ++I) {\n    DEF_VALUE_RECORD(R, I->NumValueSites, I->Values);\n    if (getNumValueKindsRT(&R) == 0)\n      continue;\n\n    /* Record R has taken a snapshot of the VP data at this point. Newly\n       added VP data for this function will be dropped.  */\n    /* Check if there is enough space.  */\n    if (BufferCapacity - RealSize < getValueProfDataSizeRT(&R)) {\n      PROF_ERR(\"Value profile data is dropped :%s \\n\",\n               \"Out of buffer space. Use environment \"\n               \" LLVM_VALUE_PROF_BUFFER_EXTRA to allocate more\");\n      I->Values = 0;\n    }\n\n    serializeValueProfDataFromRT(&R, VD);\n    deallocateValueProfileCounters(I);\n    I->Values = VD;\n    RealSize += VD->TotalSize;\n    VD = (ValueProfData *)((char *)VD + VD->TotalSize);\n    DTOR_VALUE_RECORD(R);\n  }\n\n  return RealSize;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/InstrProfilingWriter.c",
    "content": "/*===- InstrProfilingWriter.c - Write instrumentation to a file or buffer -===*\\\n|*\n|*                     The LLVM Compiler Infrastructure\n|*\n|* This file is distributed under the University of Illinois Open Source\n|* License. See LICENSE.TXT for details.\n|*\n\\*===----------------------------------------------------------------------===*/\n\n#include \"InstrProfiling.h\"\n#include \"InstrProfilingInternal.h\"\n\nCOMPILER_RT_VISIBILITY int llvmWriteProfData(WriterCallback Writer,\n                                             void *WriterCtx,\n                                             const uint8_t *ValueDataBegin,\n                                             const uint64_t ValueDataSize) {\n  /* Match logic in __llvm_profile_write_buffer(). */\n  const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();\n  const __llvm_profile_data *DataEnd = __llvm_profile_end_data();\n  const uint64_t *CountersBegin = __llvm_profile_begin_counters();\n  const uint64_t *CountersEnd = __llvm_profile_end_counters();\n  const char *NamesBegin = __llvm_profile_begin_names();\n  const char *NamesEnd = __llvm_profile_end_names();\n  return llvmWriteProfDataImpl(Writer, WriterCtx, DataBegin, DataEnd,\n                               CountersBegin, CountersEnd, ValueDataBegin,\n                               ValueDataSize, NamesBegin, NamesEnd);\n}\n\nCOMPILER_RT_VISIBILITY int llvmWriteProfDataImpl(\n    WriterCallback Writer, void *WriterCtx,\n    const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd,\n    const uint64_t *CountersBegin, const uint64_t *CountersEnd,\n    const uint8_t *ValueDataBegin, const uint64_t ValueDataSize,\n    const char *NamesBegin, const char *NamesEnd) {\n\n  /* Calculate size of sections. */\n  const uint64_t DataSize = DataEnd - DataBegin;\n  const uint64_t CountersSize = CountersEnd - CountersBegin;\n  const uint64_t NamesSize = NamesEnd - NamesBegin;\n  const uint64_t Padding = __llvm_profile_get_num_padding_bytes(NamesSize);\n\n  /* Enough zeroes for padding. */\n  const char Zeroes[sizeof(uint64_t)] = {0};\n\n  /* Create the header. */\n  __llvm_profile_header Header;\n\n  if (!DataSize)\n    return 0;\n\n  /* Initialize header struture.  */\n#define INSTR_PROF_RAW_HEADER(Type, Name, Init) Header.Name = Init;\n#include \"InstrProfData.inc\"\n\n  /* Write the data. */\n  ProfDataIOVec IOVec[] = {\n      {&Header, sizeof(__llvm_profile_header), 1},\n      {DataBegin, sizeof(__llvm_profile_data), DataSize},\n      {CountersBegin, sizeof(uint64_t), CountersSize},\n      {NamesBegin, sizeof(char), NamesSize},\n      {Zeroes, sizeof(char), Padding}};\n  if (Writer(IOVec, sizeof(IOVec) / sizeof(*IOVec), &WriterCtx))\n    return -1;\n  if (ValueDataBegin) {\n    ProfDataIOVec IOVec2[] = {{ValueDataBegin, sizeof(char), ValueDataSize}};\n    if (Writer(IOVec2, sizeof(IOVec2) / sizeof(*IOVec2), &WriterCtx))\n      return -1;\n  }\n  return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/profile/Makefile.mk",
    "content": "#===- lib/profile/Makefile.mk ------------------------------*- Makefile -*--===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\nModuleName := profile\nSubDirs :=\n\nSources := $(foreach file,$(wildcard $(Dir)/*.c $(Dir)/*.cc),$(notdir $(file)))\nObjNames := $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(Sources)))\nImplementation := Generic\n\n# FIXME: use automatic dependencies?\nDependencies := $(wildcard $(Dir)/*.h)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/safestack/.clang-format",
    "content": "BasedOnStyle: Google\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/safestack/CMakeLists.txt",
    "content": "add_custom_target(safestack)\n\nset(SAFESTACK_SOURCES safestack.cc)\n\ninclude_directories(..)\n\nset(SAFESTACK_CFLAGS ${SANITIZER_COMMON_CFLAGS})\n\nif(APPLE)\n  # Build universal binary on APPLE.\n  add_compiler_rt_runtime(clang_rt.safestack\n    STATIC\n    OS osx\n    ARCHS ${SAFESTACK_SUPPORTED_ARCH}\n    SOURCES ${SAFESTACK_SOURCES}\n            $<TARGET_OBJECTS:RTInterception.osx>\n            $<TARGET_OBJECTS:RTSanitizerCommon.osx>\n            $<TARGET_OBJECTS:RTSanitizerCommonNoLibc.osx>\n    CFLAGS ${SAFESTACK_CFLAGS}\n    PARENT_TARGET safestack)\nelse()\n  # Otherwise, build separate libraries for each target.\n  foreach(arch ${SAFESTACK_SUPPORTED_ARCH})\n    add_compiler_rt_runtime(clang_rt.safestack\n      STATIC\n      ARCHS ${arch}\n      SOURCES ${SAFESTACK_SOURCES}\n              $<TARGET_OBJECTS:RTInterception.${arch}>\n              $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>\n              $<TARGET_OBJECTS:RTSanitizerCommonNoLibc.${arch}>\n      CFLAGS ${SAFESTACK_CFLAGS}\n      PARENT_TARGET safestack)\n  endforeach()\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/safestack/safestack.cc",
    "content": "//===-- safestack.cc ------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file implements the runtime support for the safe stack protection\n// mechanism. The runtime manages allocation/deallocation of the unsafe stack\n// for the main thread, as well as all pthreads that are created/destroyed\n// during program execution.\n//\n//===----------------------------------------------------------------------===//\n\n#include <limits.h>\n#include <pthread.h>\n#include <stddef.h>\n#include <stdint.h>\n#include <unistd.h>\n#include <sys/resource.h>\n#include <sys/types.h>\n#include <sys/user.h>\n\n#include \"interception/interception.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n\n// TODO: The runtime library does not currently protect the safe stack beyond\n// relying on the system-enforced ASLR. The protection of the (safe) stack can\n// be provided by three alternative features:\n//\n// 1) Protection via hardware segmentation on x86-32 and some x86-64\n// architectures: the (safe) stack segment (implicitly accessed via the %ss\n// segment register) can be separated from the data segment (implicitly\n// accessed via the %ds segment register). Dereferencing a pointer to the safe\n// segment would result in a segmentation fault.\n//\n// 2) Protection via software fault isolation: memory writes that are not meant\n// to access the safe stack can be prevented from doing so through runtime\n// instrumentation. One way to do it is to allocate the safe stack(s) in the\n// upper half of the userspace and bitmask the corresponding upper bit of the\n// memory addresses of memory writes that are not meant to access the safe\n// stack.\n//\n// 3) Protection via information hiding on 64 bit architectures: the location\n// of the safe stack(s) can be randomized through secure mechanisms, and the\n// leakage of the stack pointer can be prevented. Currently, libc can leak the\n// stack pointer in several ways (e.g. in longjmp, signal handling, user-level\n// context switching related functions, etc.). These can be fixed in libc and\n// in other low-level libraries, by either eliminating the escaping/dumping of\n// the stack pointer (i.e., %rsp) when that's possible, or by using\n// encryption/PTR_MANGLE (XOR-ing the dumped stack pointer with another secret\n// we control and protect better, as is already done for setjmp in glibc.)\n// Furthermore, a static machine code level verifier can be ran after code\n// generation to make sure that the stack pointer is never written to memory,\n// or if it is, its written on the safe stack.\n//\n// Finally, while the Unsafe Stack pointer is currently stored in a thread\n// local variable, with libc support it could be stored in the TCB (thread\n// control block) as well, eliminating another level of indirection and making\n// such accesses faster. Alternatively, dedicating a separate register for\n// storing it would also be possible.\n\n/// Minimum stack alignment for the unsafe stack.\nconst unsigned kStackAlign = 16;\n\n/// Default size of the unsafe stack. This value is only used if the stack\n/// size rlimit is set to infinity.\nconst unsigned kDefaultUnsafeStackSize = 0x2800000;\n\n/// Runtime page size obtained through sysconf\nstatic unsigned pageSize;\n\n// TODO: To make accessing the unsafe stack pointer faster, we plan to\n// eventually store it directly in the thread control block data structure on\n// platforms where this structure is pointed to by %fs or %gs. This is exactly\n// the same mechanism as currently being used by the traditional stack\n// protector pass to store the stack guard (see getStackCookieLocation()\n// function above). Doing so requires changing the tcbhead_t struct in glibc\n// on Linux and tcb struct in libc on FreeBSD.\n//\n// For now, store it in a thread-local variable.\nextern \"C\" {\n__attribute__((visibility(\n    \"default\"))) __thread void *__safestack_unsafe_stack_ptr = nullptr;\n}\n\n// Per-thread unsafe stack information. It's not frequently accessed, so there\n// it can be kept out of the tcb in normal thread-local variables.\nstatic __thread void *unsafe_stack_start = nullptr;\nstatic __thread size_t unsafe_stack_size = 0;\nstatic __thread size_t unsafe_stack_guard = 0;\n\nstatic inline void *unsafe_stack_alloc(size_t size, size_t guard) {\n  CHECK_GE(size + guard, size);\n  void *addr = MmapOrDie(size + guard, \"unsafe_stack_alloc\");\n  MprotectNoAccess((uptr)addr, (uptr)guard);\n  return (char *)addr + guard;\n}\n\nstatic inline void unsafe_stack_setup(void *start, size_t size, size_t guard) {\n  CHECK_GE((char *)start + size, (char *)start);\n  CHECK_GE((char *)start + guard, (char *)start);\n  void *stack_ptr = (char *)start + size;\n  CHECK_EQ((((size_t)stack_ptr) & (kStackAlign - 1)), 0);\n\n  __safestack_unsafe_stack_ptr = stack_ptr;\n  unsafe_stack_start = start;\n  unsafe_stack_size = size;\n  unsafe_stack_guard = guard;\n}\n\nstatic void unsafe_stack_free() {\n  if (unsafe_stack_start) {\n    UnmapOrDie((char *)unsafe_stack_start - unsafe_stack_guard,\n               unsafe_stack_size + unsafe_stack_guard);\n  }\n  unsafe_stack_start = nullptr;\n}\n\n/// Thread data for the cleanup handler\nstatic pthread_key_t thread_cleanup_key;\n\n/// Safe stack per-thread information passed to the thread_start function\nstruct tinfo {\n  void *(*start_routine)(void *);\n  void *start_routine_arg;\n\n  void *unsafe_stack_start;\n  size_t unsafe_stack_size;\n  size_t unsafe_stack_guard;\n};\n\n/// Wrap the thread function in order to deallocate the unsafe stack when the\n/// thread terminates by returning from its main function.\nstatic void *thread_start(void *arg) {\n  struct tinfo *tinfo = (struct tinfo *)arg;\n\n  void *(*start_routine)(void *) = tinfo->start_routine;\n  void *start_routine_arg = tinfo->start_routine_arg;\n\n  // Setup the unsafe stack; this will destroy tinfo content\n  unsafe_stack_setup(tinfo->unsafe_stack_start, tinfo->unsafe_stack_size,\n                     tinfo->unsafe_stack_guard);\n\n  // Make sure out thread-specific destructor will be called\n  // FIXME: we can do this only any other specific key is set by\n  // intercepting the pthread_setspecific function itself\n  pthread_setspecific(thread_cleanup_key, (void *)1);\n\n  return start_routine(start_routine_arg);\n}\n\n/// Thread-specific data destructor\nstatic void thread_cleanup_handler(void *_iter) {\n  // We want to free the unsafe stack only after all other destructors\n  // have already run. We force this function to be called multiple times.\n  // User destructors that might run more then PTHREAD_DESTRUCTOR_ITERATIONS-1\n  // times might still end up executing after the unsafe stack is deallocated.\n  size_t iter = (size_t)_iter;\n  if (iter < PTHREAD_DESTRUCTOR_ITERATIONS) {\n    pthread_setspecific(thread_cleanup_key, (void *)(iter + 1));\n  } else {\n    // This is the last iteration\n    unsafe_stack_free();\n  }\n}\n\n/// Intercept thread creation operation to allocate and setup the unsafe stack\nINTERCEPTOR(int, pthread_create, pthread_t *thread,\n            const pthread_attr_t *attr,\n            void *(*start_routine)(void*), void *arg) {\n\n  size_t size = 0;\n  size_t guard = 0;\n\n  if (attr) {\n    pthread_attr_getstacksize(attr, &size);\n    pthread_attr_getguardsize(attr, &guard);\n  } else {\n    // get pthread default stack size\n    pthread_attr_t tmpattr;\n    pthread_attr_init(&tmpattr);\n    pthread_attr_getstacksize(&tmpattr, &size);\n    pthread_attr_getguardsize(&tmpattr, &guard);\n    pthread_attr_destroy(&tmpattr);\n  }\n\n  CHECK_NE(size, 0);\n  CHECK_EQ((size & (kStackAlign - 1)), 0);\n  CHECK_EQ((guard & (pageSize - 1)), 0);\n\n  void *addr = unsafe_stack_alloc(size, guard);\n  struct tinfo *tinfo =\n      (struct tinfo *)(((char *)addr) + size - sizeof(struct tinfo));\n  tinfo->start_routine = start_routine;\n  tinfo->start_routine_arg = arg;\n  tinfo->unsafe_stack_start = addr;\n  tinfo->unsafe_stack_size = size;\n  tinfo->unsafe_stack_guard = guard;\n\n  return REAL(pthread_create)(thread, attr, thread_start, tinfo);\n}\n\nextern \"C\" __attribute__((visibility(\"default\")))\n#if !SANITIZER_CAN_USE_PREINIT_ARRAY\n// On ELF platforms, the constructor is invoked using .preinit_array (see below)\n__attribute__((constructor(0)))\n#endif\nvoid __safestack_init() {\n  // Determine the stack size for the main thread.\n  size_t size = kDefaultUnsafeStackSize;\n  size_t guard = 4096;\n\n  struct rlimit limit;\n  if (getrlimit(RLIMIT_STACK, &limit) == 0 && limit.rlim_cur != RLIM_INFINITY)\n    size = limit.rlim_cur;\n\n  // Allocate unsafe stack for main thread\n  void *addr = unsafe_stack_alloc(size, guard);\n\n  unsafe_stack_setup(addr, size, guard);\n  pageSize = sysconf(_SC_PAGESIZE);\n\n  // Initialize pthread interceptors for thread allocation\n  INTERCEPT_FUNCTION(pthread_create);\n\n  // Setup the cleanup handler\n  pthread_key_create(&thread_cleanup_key, thread_cleanup_handler);\n}\n\n#if SANITIZER_CAN_USE_PREINIT_ARRAY\n// On ELF platforms, run safestack initialization before any other constructors.\n// On other platforms we use the constructor attribute to arrange to run our\n// initialization early.\nextern \"C\" {\n__attribute__((section(\".preinit_array\"),\n               used)) void (*__safestack_preinit)(void) = __safestack_init;\n}\n#endif\n\nextern \"C\"\n    __attribute__((visibility(\"default\"))) void *__get_unsafe_stack_start() {\n  return unsafe_stack_start;\n}\n\nextern \"C\"\n    __attribute__((visibility(\"default\"))) void *__get_unsafe_stack_ptr() {\n  return __safestack_unsafe_stack_ptr;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/.clang-format",
    "content": "BasedOnStyle: Google\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/Android.mk",
    "content": "#\n# Copyright (C) 2015 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n#\n\nLOCAL_PATH:= $(call my-dir)\n\nsan_rtl_files := \\\n    sanitizer_allocator.cc \\\n    sanitizer_common.cc \\\n    sanitizer_deadlock_detector1.cc \\\n    sanitizer_deadlock_detector2.cc \\\n    sanitizer_flags.cc \\\n    sanitizer_flag_parser.cc \\\n    sanitizer_libc.cc \\\n    sanitizer_libignore.cc \\\n    sanitizer_linux.cc \\\n    sanitizer_mac.cc \\\n    sanitizer_persistent_allocator.cc \\\n    sanitizer_platform_limits_linux.cc \\\n    sanitizer_platform_limits_posix.cc \\\n    sanitizer_posix.cc \\\n    sanitizer_printf.cc \\\n    sanitizer_procmaps_common.cc \\\n    sanitizer_procmaps_freebsd.cc \\\n    sanitizer_procmaps_linux.cc \\\n    sanitizer_procmaps_mac.cc \\\n    sanitizer_stackdepot.cc \\\n    sanitizer_stacktrace.cc \\\n    sanitizer_stacktrace_printer.cc \\\n    sanitizer_suppressions.cc \\\n    sanitizer_symbolizer.cc \\\n    sanitizer_symbolizer_libbacktrace.cc \\\n    sanitizer_symbolizer_win.cc \\\n    sanitizer_tls_get_addr.cc \\\n    sanitizer_thread_registry.cc \\\n    sanitizer_win.cc \\\n\nsan_cdep_files := \\\n    sanitizer_common_libcdep.cc \\\n    sanitizer_coverage_libcdep.cc \\\n    sanitizer_coverage_mapping_libcdep.cc \\\n    sanitizer_linux_libcdep.cc \\\n    sanitizer_posix_libcdep.cc \\\n    sanitizer_stacktrace_libcdep.cc \\\n    sanitizer_stoptheworld_linux_libcdep.cc \\\n    sanitizer_symbolizer_libcdep.cc \\\n    sanitizer_symbolizer_posix_libcdep.cc \\\n    sanitizer_unwind_linux_libcdep.cc \\\n\nsan_rtl_cppflags := \\\n    -fvisibility=hidden \\\n    -fno-exceptions \\\n    -std=c++11 \\\n    -Wall \\\n    -Werror \\\n    -Wno-unused-parameter \\\n\nsan_rtl_c_includes := \\\n    external/compiler-rt/lib \\\n\n################################################################################\n# Host modules\n\nifneq ($(HOST_OS),darwin)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libsan\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_C_INCLUDES := $(san_rtl_c_includes)\nLOCAL_CPPFLAGS := $(san_rtl_cppflags)\nLOCAL_SRC_FILES := $(san_rtl_files) $(san_cdep_files)\nLOCAL_CXX_STL := none\nLOCAL_SANITIZE := never\nLOCAL_MULTILIB := both\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\nendif\n\nifndef SANITIZE_HOST\ninclude $(LOCAL_PATH)/tests/Android.mk\nendif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/CMakeLists.txt",
    "content": "# Build system for the common Sanitizer runtime support library components.\n# These components are shared between AddressSanitizer and ThreadSanitizer.\n\nset(SANITIZER_SOURCES\n  sanitizer_allocator.cc\n  sanitizer_common.cc\n  sanitizer_deadlock_detector1.cc\n  sanitizer_deadlock_detector2.cc\n  sanitizer_flags.cc\n  sanitizer_flag_parser.cc\n  sanitizer_libc.cc\n  sanitizer_libignore.cc\n  sanitizer_linux.cc\n  sanitizer_mac.cc\n  sanitizer_persistent_allocator.cc\n  sanitizer_platform_limits_linux.cc\n  sanitizer_platform_limits_posix.cc\n  sanitizer_posix.cc\n  sanitizer_printf.cc\n  sanitizer_procmaps_common.cc\n  sanitizer_procmaps_freebsd.cc\n  sanitizer_procmaps_linux.cc\n  sanitizer_procmaps_mac.cc\n  sanitizer_stackdepot.cc\n  sanitizer_stacktrace.cc\n  sanitizer_stacktrace_printer.cc\n  sanitizer_suppressions.cc\n  sanitizer_symbolizer.cc\n  sanitizer_symbolizer_libbacktrace.cc\n  sanitizer_symbolizer_mac.cc\n  sanitizer_symbolizer_win.cc\n  sanitizer_tls_get_addr.cc\n  sanitizer_thread_registry.cc\n  sanitizer_win.cc)\n\n# Libc functions stubs. These sources should be linked instead of\n# SANITIZER_LIBCDEP_SOURCES when sanitizer_common library must not depend on\n# libc.\nset(SANITIZER_NOLIBC_SOURCES\n  sanitizer_common_nolibc.cc)\n\nset(SANITIZER_LIBCDEP_SOURCES\n  sanitizer_common_libcdep.cc\n  sanitizer_coverage_libcdep.cc\n  sanitizer_coverage_mapping_libcdep.cc\n  sanitizer_linux_libcdep.cc\n  sanitizer_posix_libcdep.cc\n  sanitizer_stacktrace_libcdep.cc\n  sanitizer_stoptheworld_linux_libcdep.cc\n  sanitizer_symbolizer_libcdep.cc\n  sanitizer_symbolizer_posix_libcdep.cc\n  sanitizer_unwind_linux_libcdep.cc)\n\n# Explicitly list all sanitizer_common headers. Not all of these are\n# included in sanitizer_common source files, but we need to depend on\n# headers when building our custom unit tests.\nset(SANITIZER_HEADERS\n  sanitizer_addrhashmap.h\n  sanitizer_allocator.h\n  sanitizer_allocator_interface.h\n  sanitizer_allocator_internal.h\n  sanitizer_atomic.h\n  sanitizer_atomic_clang.h\n  sanitizer_atomic_msvc.h\n  sanitizer_bitvector.h\n  sanitizer_bvgraph.h\n  sanitizer_common.h\n  sanitizer_common_interceptors.inc\n  sanitizer_common_interceptors_ioctl.inc\n  sanitizer_common_interceptors_format.inc\n  sanitizer_common_syscalls.inc\n  sanitizer_deadlock_detector.h\n  sanitizer_deadlock_detector_interface.h\n  sanitizer_flag_parser.h\n  sanitizer_flags.h\n  sanitizer_flags.inc\n  sanitizer_interface_internal.h\n  sanitizer_internal_defs.h\n  sanitizer_lfstack.h\n  sanitizer_libc.h\n  sanitizer_libignore.h\n  sanitizer_linux.h\n  sanitizer_list.h\n  sanitizer_mac.h\n  sanitizer_mutex.h\n  sanitizer_persistent_allocator.h\n  sanitizer_placement_new.h\n  sanitizer_platform.h\n  sanitizer_platform_interceptors.h\n  sanitizer_platform_limits_posix.h\n  sanitizer_posix.h\n  sanitizer_procmaps.h\n  sanitizer_quarantine.h\n  sanitizer_report_decorator.h\n  sanitizer_stackdepot.h\n  sanitizer_stackdepotbase.h\n  sanitizer_stacktrace.h\n  sanitizer_stacktrace_printer.h\n  sanitizer_stoptheworld.h\n  sanitizer_suppressions.h\n  sanitizer_symbolizer.h\n  sanitizer_symbolizer_internal.h\n  sanitizer_symbolizer_libbacktrace.h\n  sanitizer_symbolizer_mac.h\n  sanitizer_syscall_generic.inc\n  sanitizer_syscall_linux_x86_64.inc\n  sanitizer_syscall_linux_aarch64.inc\n  sanitizer_thread_registry.h)\n\nset(SANITIZER_COMMON_DEFINITIONS)\n\nif(MSVC)\n  list(APPEND SANITIZER_COMMON_DEFINITIONS\n    SANITIZER_NEEDS_SEGV=0)\nelse()\n  list(APPEND SANITIZER_COMMON_DEFINITIONS\n    SANITIZER_NEEDS_SEGV=1)\nendif()\n\ninclude(CheckIncludeFile)\nappend_have_file_definition(rpc/xdr.h HAVE_RPC_XDR_H SANITIZER_COMMON_DEFINITIONS)\nappend_have_file_definition(tirpc/rpc/xdr.h HAVE_TIRPC_RPC_XDR_H SANITIZER_COMMON_DEFINITIONS)\n\nset(SANITIZER_CFLAGS ${SANITIZER_COMMON_CFLAGS})\nappend_no_rtti_flag(SANITIZER_CFLAGS)\n\nappend_list_if(SANITIZER_LIMIT_FRAME_SIZE -Wframe-larger-than=570\n               SANITIZER_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_WGLOBAL_CONSTRUCTORS_FLAG -Wglobal-constructors\n               SANITIZER_CFLAGS)\n\nif(APPLE)\n  set(OS_OPTION OS ${SANITIZER_COMMON_SUPPORTED_OS})\nendif()\n\nadd_compiler_rt_object_libraries(RTSanitizerCommon\n  ${OS_OPTION}\n  ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}\n  SOURCES ${SANITIZER_SOURCES}\n  CFLAGS ${SANITIZER_CFLAGS}\n  DEFS ${SANITIZER_COMMON_DEFINITIONS})\nadd_compiler_rt_object_libraries(RTSanitizerCommonNoLibc\n  ${OS_OPTION}\n  ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}\n  SOURCES ${SANITIZER_NOLIBC_SOURCES}\n  CFLAGS ${SANITIZER_CFLAGS}\n  DEFS ${SANITIZER_COMMON_DEFINITIONS})\nadd_compiler_rt_object_libraries(RTSanitizerCommonLibc\n  ${OS_OPTION}\n  ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}\n  SOURCES ${SANITIZER_LIBCDEP_SOURCES}\n  CFLAGS ${SANITIZER_CFLAGS}\n  DEFS ${SANITIZER_COMMON_DEFINITIONS})\n\n# Unit tests for common sanitizer runtime.\nif(COMPILER_RT_INCLUDE_TESTS)\n  add_subdirectory(tests)\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/Makefile.mk",
    "content": "#===- lib/sanitizer_common/Makefile.mk ---------------------*- Makefile -*--===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\nModuleName := sanitizer_common\nSubDirs :=\n\nSources := $(foreach file,$(wildcard $(Dir)/*.cc),$(notdir $(file)))\nNolibcSources := $(foreach file,$(wildcard $(Dir)/*_nolibc.cc),$(notdir $(file)))\nSources := $(filter-out $(NolibcSources),$(Sources))\nObjNames := $(Sources:%.cc=%.o)\n\nImplementation := Generic\n\n# FIXME: use automatic dependencies?\nDependencies := $(wildcard $(Dir)/*.h)\n\n# Define a convenience variable for all the sanitizer_common functions.\nSanitizerCommonFunctions := $(Sources:%.cc=%)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_addrhashmap.h",
    "content": "//===-- sanitizer_addrhashmap.h ---------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Concurrent uptr->T hashmap.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_ADDRHASHMAP_H\n#define SANITIZER_ADDRHASHMAP_H\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_mutex.h\"\n#include \"sanitizer_atomic.h\"\n#include \"sanitizer_allocator_internal.h\"\n\nnamespace __sanitizer {\n\n// Concurrent uptr->T hashmap.\n// T must be a POD type, kSize is preferably a prime but can be any number.\n// Usage example:\n//\n// typedef AddrHashMap<uptr, 11> Map;\n// Map m;\n// {\n//   Map::Handle h(&m, addr);\n//   use h.operator->() to access the data\n//   if h.created() then the element was just created, and the current thread\n//     has exclusive access to it\n//   otherwise the current thread has only read access to the data\n// }\n// {\n//   Map::Handle h(&m, addr, true);\n//   this will remove the data from the map in Handle dtor\n//   the current thread has exclusive access to the data\n//   if !h.exists() then the element never existed\n// }\ntemplate<typename T, uptr kSize>\nclass AddrHashMap {\n private:\n  struct Cell {\n    atomic_uintptr_t addr;\n    T                val;\n  };\n\n  struct AddBucket {\n    uptr cap;\n    uptr size;\n    Cell cells[1];  // variable len\n  };\n\n  static const uptr kBucketSize = 3;\n\n  struct Bucket {\n    RWMutex          mtx;\n    atomic_uintptr_t add;\n    Cell             cells[kBucketSize];\n  };\n\n public:\n  AddrHashMap();\n\n  class Handle {\n   public:\n    Handle(AddrHashMap<T, kSize> *map, uptr addr);\n    Handle(AddrHashMap<T, kSize> *map, uptr addr, bool remove);\n    Handle(AddrHashMap<T, kSize> *map, uptr addr, bool remove, bool create);\n\n    ~Handle();\n    T *operator->();\n    bool created() const;\n    bool exists() const;\n\n   private:\n    friend AddrHashMap<T, kSize>;\n    AddrHashMap<T, kSize> *map_;\n    Bucket                *bucket_;\n    Cell                  *cell_;\n    uptr                   addr_;\n    uptr                   addidx_;\n    bool                   created_;\n    bool                   remove_;\n    bool                   create_;\n  };\n\n private:\n  friend class Handle;\n  Bucket *table_;\n\n  void acquire(Handle *h);\n  void release(Handle *h);\n  uptr calcHash(uptr addr);\n};\n\ntemplate<typename T, uptr kSize>\nAddrHashMap<T, kSize>::Handle::Handle(AddrHashMap<T, kSize> *map, uptr addr) {\n  map_ = map;\n  addr_ = addr;\n  remove_ = false;\n  create_ = true;\n  map_->acquire(this);\n}\n\ntemplate<typename T, uptr kSize>\nAddrHashMap<T, kSize>::Handle::Handle(AddrHashMap<T, kSize> *map, uptr addr,\n    bool remove) {\n  map_ = map;\n  addr_ = addr;\n  remove_ = remove;\n  create_ = true;\n  map_->acquire(this);\n}\n\ntemplate<typename T, uptr kSize>\nAddrHashMap<T, kSize>::Handle::Handle(AddrHashMap<T, kSize> *map, uptr addr,\n    bool remove, bool create) {\n  map_ = map;\n  addr_ = addr;\n  remove_ = remove;\n  create_ = create;\n  map_->acquire(this);\n}\n\ntemplate<typename T, uptr kSize>\nAddrHashMap<T, kSize>::Handle::~Handle() {\n  map_->release(this);\n}\n\ntemplate <typename T, uptr kSize>\nT *AddrHashMap<T, kSize>::Handle::operator->() {\n  return &cell_->val;\n}\n\ntemplate<typename T, uptr kSize>\nbool AddrHashMap<T, kSize>::Handle::created() const {\n  return created_;\n}\n\ntemplate<typename T, uptr kSize>\nbool AddrHashMap<T, kSize>::Handle::exists() const {\n  return cell_ != nullptr;\n}\n\ntemplate<typename T, uptr kSize>\nAddrHashMap<T, kSize>::AddrHashMap() {\n  table_ = (Bucket*)MmapOrDie(kSize * sizeof(table_[0]), \"AddrHashMap\");\n}\n\ntemplate<typename T, uptr kSize>\nvoid AddrHashMap<T, kSize>::acquire(Handle *h) {\n  uptr addr = h->addr_;\n  uptr hash = calcHash(addr);\n  Bucket *b = &table_[hash];\n\n  h->created_ = false;\n  h->addidx_ = -1U;\n  h->bucket_ = b;\n  h->cell_ = nullptr;\n\n  // If we want to remove the element, we need exclusive access to the bucket,\n  // so skip the lock-free phase.\n  if (h->remove_)\n    goto locked;\n\n retry:\n  // First try to find an existing element w/o read mutex.\n  CHECK(!h->remove_);\n  // Check the embed cells.\n  for (uptr i = 0; i < kBucketSize; i++) {\n    Cell *c = &b->cells[i];\n    uptr addr1 = atomic_load(&c->addr, memory_order_acquire);\n    if (addr1 == addr) {\n      h->cell_ = c;\n      return;\n    }\n  }\n\n  // Check the add cells with read lock.\n  if (atomic_load(&b->add, memory_order_relaxed)) {\n    b->mtx.ReadLock();\n    AddBucket *add = (AddBucket*)atomic_load(&b->add, memory_order_relaxed);\n    for (uptr i = 0; i < add->size; i++) {\n      Cell *c = &add->cells[i];\n      uptr addr1 = atomic_load(&c->addr, memory_order_relaxed);\n      if (addr1 == addr) {\n        h->addidx_ = i;\n        h->cell_ = c;\n        return;\n      }\n    }\n    b->mtx.ReadUnlock();\n  }\n\n locked:\n  // Re-check existence under write lock.\n  // Embed cells.\n  b->mtx.Lock();\n  for (uptr i = 0; i < kBucketSize; i++) {\n    Cell *c = &b->cells[i];\n    uptr addr1 = atomic_load(&c->addr, memory_order_relaxed);\n    if (addr1 == addr) {\n      if (h->remove_) {\n        h->cell_ = c;\n        return;\n      }\n      b->mtx.Unlock();\n      goto retry;\n    }\n  }\n\n  // Add cells.\n  AddBucket *add = (AddBucket*)atomic_load(&b->add, memory_order_relaxed);\n  if (add) {\n    for (uptr i = 0; i < add->size; i++) {\n      Cell *c = &add->cells[i];\n      uptr addr1 = atomic_load(&c->addr, memory_order_relaxed);\n      if (addr1 == addr) {\n        if (h->remove_) {\n          h->addidx_ = i;\n          h->cell_ = c;\n          return;\n        }\n        b->mtx.Unlock();\n        goto retry;\n      }\n    }\n  }\n\n  // The element does not exist, no need to create it if we want to remove.\n  if (h->remove_ || !h->create_) {\n    b->mtx.Unlock();\n    return;\n  }\n\n  // Now try to create it under the mutex.\n  h->created_ = true;\n  // See if we have a free embed cell.\n  for (uptr i = 0; i < kBucketSize; i++) {\n    Cell *c = &b->cells[i];\n    uptr addr1 = atomic_load(&c->addr, memory_order_relaxed);\n    if (addr1 == 0) {\n      h->cell_ = c;\n      return;\n    }\n  }\n\n  // Store in the add cells.\n  if (!add) {\n    // Allocate a new add array.\n    const uptr kInitSize = 64;\n    add = (AddBucket*)InternalAlloc(kInitSize);\n    internal_memset(add, 0, kInitSize);\n    add->cap = (kInitSize - sizeof(*add)) / sizeof(add->cells[0]) + 1;\n    add->size = 0;\n    atomic_store(&b->add, (uptr)add, memory_order_relaxed);\n  }\n  if (add->size == add->cap) {\n    // Grow existing add array.\n    uptr oldsize = sizeof(*add) + (add->cap - 1) * sizeof(add->cells[0]);\n    uptr newsize = oldsize * 2;\n    AddBucket *add1 = (AddBucket*)InternalAlloc(newsize);\n    internal_memset(add1, 0, newsize);\n    add1->cap = (newsize - sizeof(*add)) / sizeof(add->cells[0]) + 1;\n    add1->size = add->size;\n    internal_memcpy(add1->cells, add->cells, add->size * sizeof(add->cells[0]));\n    InternalFree(add);\n    atomic_store(&b->add, (uptr)add1, memory_order_relaxed);\n    add = add1;\n  }\n  // Store.\n  uptr i = add->size++;\n  Cell *c = &add->cells[i];\n  CHECK_EQ(atomic_load(&c->addr, memory_order_relaxed), 0);\n  h->addidx_ = i;\n  h->cell_ = c;\n}\n\ntemplate<typename T, uptr kSize>\nvoid AddrHashMap<T, kSize>::release(Handle *h) {\n  if (!h->cell_)\n    return;\n  Bucket *b = h->bucket_;\n  Cell *c = h->cell_;\n  uptr addr1 = atomic_load(&c->addr, memory_order_relaxed);\n  if (h->created_) {\n    // Denote completion of insertion.\n    CHECK_EQ(addr1, 0);\n    // After the following store, the element becomes available\n    // for lock-free reads.\n    atomic_store(&c->addr, h->addr_, memory_order_release);\n    b->mtx.Unlock();\n  } else if (h->remove_) {\n    // Denote that the cell is empty now.\n    CHECK_EQ(addr1, h->addr_);\n    atomic_store(&c->addr, 0, memory_order_release);\n    // See if we need to compact the bucket.\n    AddBucket *add = (AddBucket*)atomic_load(&b->add, memory_order_relaxed);\n    if (h->addidx_ == -1U) {\n      // Removed from embed array, move an add element into the freed cell.\n      if (add && add->size != 0) {\n        uptr last = --add->size;\n        Cell *c1 = &add->cells[last];\n        c->val = c1->val;\n        uptr addr1 = atomic_load(&c1->addr, memory_order_relaxed);\n        atomic_store(&c->addr, addr1, memory_order_release);\n        atomic_store(&c1->addr, 0, memory_order_release);\n      }\n    } else {\n      // Removed from add array, compact it.\n      uptr last = --add->size;\n      Cell *c1 = &add->cells[last];\n      if (c != c1) {\n        *c = *c1;\n        atomic_store(&c1->addr, 0, memory_order_relaxed);\n      }\n    }\n    if (add && add->size == 0) {\n      // FIXME(dvyukov): free add?\n    }\n    b->mtx.Unlock();\n  } else {\n    CHECK_EQ(addr1, h->addr_);\n    if (h->addidx_ != -1U)\n      b->mtx.ReadUnlock();\n  }\n}\n\ntemplate<typename T, uptr kSize>\nuptr AddrHashMap<T, kSize>::calcHash(uptr addr) {\n  addr += addr << 10;\n  addr ^= addr >> 6;\n  return addr % kSize;\n}\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_ADDRHASHMAP_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc",
    "content": "//===-- sanitizer_allocator.cc --------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n// This allocator is used inside run-times.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_allocator.h\"\n#include \"sanitizer_allocator_internal.h\"\n#include \"sanitizer_common.h\"\n\nnamespace __sanitizer {\n\n// ThreadSanitizer for Go uses libc malloc/free.\n#if defined(SANITIZER_GO) || defined(SANITIZER_USE_MALLOC)\n# if SANITIZER_LINUX && !SANITIZER_ANDROID\nextern \"C\" void *__libc_malloc(uptr size);\nextern \"C\" void __libc_free(void *ptr);\n#  define LIBC_MALLOC __libc_malloc\n#  define LIBC_FREE __libc_free\n# else\n#  include <stdlib.h>\n#  define LIBC_MALLOC malloc\n#  define LIBC_FREE free\n# endif\n\nstatic void *RawInternalAlloc(uptr size, InternalAllocatorCache *cache) {\n  (void)cache;\n  return LIBC_MALLOC(size);\n}\n\nstatic void RawInternalFree(void *ptr, InternalAllocatorCache *cache) {\n  (void)cache;\n  LIBC_FREE(ptr);\n}\n\nInternalAllocator *internal_allocator() {\n  return 0;\n}\n\n#else // SANITIZER_GO\n\nstatic ALIGNED(64) char internal_alloc_placeholder[sizeof(InternalAllocator)];\nstatic atomic_uint8_t internal_allocator_initialized;\nstatic StaticSpinMutex internal_alloc_init_mu;\n\nstatic InternalAllocatorCache internal_allocator_cache;\nstatic StaticSpinMutex internal_allocator_cache_mu;\n\nInternalAllocator *internal_allocator() {\n  InternalAllocator *internal_allocator_instance =\n      reinterpret_cast<InternalAllocator *>(&internal_alloc_placeholder);\n  if (atomic_load(&internal_allocator_initialized, memory_order_acquire) == 0) {\n    SpinMutexLock l(&internal_alloc_init_mu);\n    if (atomic_load(&internal_allocator_initialized, memory_order_relaxed) ==\n        0) {\n      internal_allocator_instance->Init(/* may_return_null*/ false);\n      atomic_store(&internal_allocator_initialized, 1, memory_order_release);\n    }\n  }\n  return internal_allocator_instance;\n}\n\nstatic void *RawInternalAlloc(uptr size, InternalAllocatorCache *cache) {\n  if (cache == 0) {\n    SpinMutexLock l(&internal_allocator_cache_mu);\n    return internal_allocator()->Allocate(&internal_allocator_cache, size, 8,\n                                          false);\n  }\n  return internal_allocator()->Allocate(cache, size, 8, false);\n}\n\nstatic void RawInternalFree(void *ptr, InternalAllocatorCache *cache) {\n  if (!cache) {\n    SpinMutexLock l(&internal_allocator_cache_mu);\n    return internal_allocator()->Deallocate(&internal_allocator_cache, ptr);\n  }\n  internal_allocator()->Deallocate(cache, ptr);\n}\n\n#endif // SANITIZER_GO\n\nconst u64 kBlockMagic = 0x6A6CB03ABCEBC041ull;\n\nvoid *InternalAlloc(uptr size, InternalAllocatorCache *cache) {\n  if (size + sizeof(u64) < size)\n    return nullptr;\n  void *p = RawInternalAlloc(size + sizeof(u64), cache);\n  if (!p)\n    return nullptr;\n  ((u64*)p)[0] = kBlockMagic;\n  return (char*)p + sizeof(u64);\n}\n\nvoid InternalFree(void *addr, InternalAllocatorCache *cache) {\n  if (!addr)\n    return;\n  addr = (char*)addr - sizeof(u64);\n  CHECK_EQ(kBlockMagic, ((u64*)addr)[0]);\n  ((u64*)addr)[0] = 0;\n  RawInternalFree(addr, cache);\n}\n\n// LowLevelAllocator\nstatic LowLevelAllocateCallback low_level_alloc_callback;\n\nvoid *LowLevelAllocator::Allocate(uptr size) {\n  // Align allocation size.\n  size = RoundUpTo(size, 8);\n  if (allocated_end_ - allocated_current_ < (sptr)size) {\n    uptr size_to_allocate = Max(size, GetPageSizeCached());\n    allocated_current_ =\n        (char*)MmapOrDie(size_to_allocate, __func__);\n    allocated_end_ = allocated_current_ + size_to_allocate;\n    if (low_level_alloc_callback) {\n      low_level_alloc_callback((uptr)allocated_current_,\n                               size_to_allocate);\n    }\n  }\n  CHECK(allocated_end_ - allocated_current_ >= (sptr)size);\n  void *res = allocated_current_;\n  allocated_current_ += size;\n  return res;\n}\n\nvoid SetLowLevelAllocateCallback(LowLevelAllocateCallback callback) {\n  low_level_alloc_callback = callback;\n}\n\nbool CallocShouldReturnNullDueToOverflow(uptr size, uptr n) {\n  if (!size) return false;\n  uptr max = (uptr)-1L;\n  return (max / size) < n;\n}\n\nvoid NORETURN ReportAllocatorCannotReturnNull() {\n  Report(\"%s's allocator is terminating the process instead of returning 0\\n\",\n         SanitizerToolName);\n  Report(\"If you don't like this behavior set allocator_may_return_null=1\\n\");\n  CHECK(0);\n  Die();\n}\n\n} // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_allocator.h",
    "content": "//===-- sanitizer_allocator.h -----------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Specialized memory allocator for ThreadSanitizer, MemorySanitizer, etc.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_ALLOCATOR_H\n#define SANITIZER_ALLOCATOR_H\n\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_common.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_list.h\"\n#include \"sanitizer_mutex.h\"\n#include \"sanitizer_lfstack.h\"\n\nnamespace __sanitizer {\n\n// Prints error message and kills the program.\nvoid NORETURN ReportAllocatorCannotReturnNull();\n\n// SizeClassMap maps allocation sizes into size classes and back.\n// Class 0 corresponds to size 0.\n// Classes 1 - 16 correspond to sizes 16 to 256 (size = class_id * 16).\n// Next 4 classes: 256 + i * 64  (i = 1 to 4).\n// Next 4 classes: 512 + i * 128 (i = 1 to 4).\n// ...\n// Next 4 classes: 2^k + i * 2^(k-2) (i = 1 to 4).\n// Last class corresponds to kMaxSize = 1 << kMaxSizeLog.\n//\n// This structure of the size class map gives us:\n//   - Efficient table-free class-to-size and size-to-class functions.\n//   - Difference between two consequent size classes is betweed 14% and 25%\n//\n// This class also gives a hint to a thread-caching allocator about the amount\n// of chunks that need to be cached per-thread:\n//  - kMaxNumCached is the maximal number of chunks per size class.\n//  - (1 << kMaxBytesCachedLog) is the maximal number of bytes per size class.\n//\n// Part of output of SizeClassMap::Print():\n// c00 => s: 0 diff: +0 00% l 0 cached: 0 0; id 0\n// c01 => s: 16 diff: +16 00% l 4 cached: 256 4096; id 1\n// c02 => s: 32 diff: +16 100% l 5 cached: 256 8192; id 2\n// c03 => s: 48 diff: +16 50% l 5 cached: 256 12288; id 3\n// c04 => s: 64 diff: +16 33% l 6 cached: 256 16384; id 4\n// c05 => s: 80 diff: +16 25% l 6 cached: 256 20480; id 5\n// c06 => s: 96 diff: +16 20% l 6 cached: 256 24576; id 6\n// c07 => s: 112 diff: +16 16% l 6 cached: 256 28672; id 7\n//\n// c08 => s: 128 diff: +16 14% l 7 cached: 256 32768; id 8\n// c09 => s: 144 diff: +16 12% l 7 cached: 256 36864; id 9\n// c10 => s: 160 diff: +16 11% l 7 cached: 256 40960; id 10\n// c11 => s: 176 diff: +16 10% l 7 cached: 256 45056; id 11\n// c12 => s: 192 diff: +16 09% l 7 cached: 256 49152; id 12\n// c13 => s: 208 diff: +16 08% l 7 cached: 256 53248; id 13\n// c14 => s: 224 diff: +16 07% l 7 cached: 256 57344; id 14\n// c15 => s: 240 diff: +16 07% l 7 cached: 256 61440; id 15\n//\n// c16 => s: 256 diff: +16 06% l 8 cached: 256 65536; id 16\n// c17 => s: 320 diff: +64 25% l 8 cached: 204 65280; id 17\n// c18 => s: 384 diff: +64 20% l 8 cached: 170 65280; id 18\n// c19 => s: 448 diff: +64 16% l 8 cached: 146 65408; id 19\n//\n// c20 => s: 512 diff: +64 14% l 9 cached: 128 65536; id 20\n// c21 => s: 640 diff: +128 25% l 9 cached: 102 65280; id 21\n// c22 => s: 768 diff: +128 20% l 9 cached: 85 65280; id 22\n// c23 => s: 896 diff: +128 16% l 9 cached: 73 65408; id 23\n//\n// c24 => s: 1024 diff: +128 14% l 10 cached: 64 65536; id 24\n// c25 => s: 1280 diff: +256 25% l 10 cached: 51 65280; id 25\n// c26 => s: 1536 diff: +256 20% l 10 cached: 42 64512; id 26\n// c27 => s: 1792 diff: +256 16% l 10 cached: 36 64512; id 27\n//\n// ...\n//\n// c48 => s: 65536 diff: +8192 14% l 16 cached: 1 65536; id 48\n// c49 => s: 81920 diff: +16384 25% l 16 cached: 1 81920; id 49\n// c50 => s: 98304 diff: +16384 20% l 16 cached: 1 98304; id 50\n// c51 => s: 114688 diff: +16384 16% l 16 cached: 1 114688; id 51\n//\n// c52 => s: 131072 diff: +16384 14% l 17 cached: 1 131072; id 52\n\ntemplate <uptr kMaxSizeLog, uptr kMaxNumCachedT, uptr kMaxBytesCachedLog>\nclass SizeClassMap {\n  static const uptr kMinSizeLog = 4;\n  static const uptr kMidSizeLog = kMinSizeLog + 4;\n  static const uptr kMinSize = 1 << kMinSizeLog;\n  static const uptr kMidSize = 1 << kMidSizeLog;\n  static const uptr kMidClass = kMidSize / kMinSize;\n  static const uptr S = 2;\n  static const uptr M = (1 << S) - 1;\n\n public:\n  static const uptr kMaxNumCached = kMaxNumCachedT;\n  // We transfer chunks between central and thread-local free lists in batches.\n  // For small size classes we allocate batches separately.\n  // For large size classes we use one of the chunks to store the batch.\n  struct TransferBatch {\n    TransferBatch *next;\n    uptr count;\n    void *batch[kMaxNumCached];\n  };\n\n  static const uptr kMaxSize = 1UL << kMaxSizeLog;\n  static const uptr kNumClasses =\n      kMidClass + ((kMaxSizeLog - kMidSizeLog) << S) + 1;\n  COMPILER_CHECK(kNumClasses >= 32 && kNumClasses <= 256);\n  static const uptr kNumClassesRounded =\n      kNumClasses == 32  ? 32 :\n      kNumClasses <= 64  ? 64 :\n      kNumClasses <= 128 ? 128 : 256;\n\n  static uptr Size(uptr class_id) {\n    if (class_id <= kMidClass)\n      return kMinSize * class_id;\n    class_id -= kMidClass;\n    uptr t = kMidSize << (class_id >> S);\n    return t + (t >> S) * (class_id & M);\n  }\n\n  static uptr ClassID(uptr size) {\n    if (size <= kMidSize)\n      return (size + kMinSize - 1) >> kMinSizeLog;\n    if (size > kMaxSize) return 0;\n    uptr l = MostSignificantSetBitIndex(size);\n    uptr hbits = (size >> (l - S)) & M;\n    uptr lbits = size & ((1 << (l - S)) - 1);\n    uptr l1 = l - kMidSizeLog;\n    return kMidClass + (l1 << S) + hbits + (lbits > 0);\n  }\n\n  static uptr MaxCached(uptr class_id) {\n    if (class_id == 0) return 0;\n    uptr n = (1UL << kMaxBytesCachedLog) / Size(class_id);\n    return Max<uptr>(1, Min(kMaxNumCached, n));\n  }\n\n  static void Print() {\n    uptr prev_s = 0;\n    uptr total_cached = 0;\n    for (uptr i = 0; i < kNumClasses; i++) {\n      uptr s = Size(i);\n      if (s >= kMidSize / 2 && (s & (s - 1)) == 0)\n        Printf(\"\\n\");\n      uptr d = s - prev_s;\n      uptr p = prev_s ? (d * 100 / prev_s) : 0;\n      uptr l = s ? MostSignificantSetBitIndex(s) : 0;\n      uptr cached = MaxCached(i) * s;\n      Printf(\"c%02zd => s: %zd diff: +%zd %02zd%% l %zd \"\n             \"cached: %zd %zd; id %zd\\n\",\n             i, Size(i), d, p, l, MaxCached(i), cached, ClassID(s));\n      total_cached += cached;\n      prev_s = s;\n    }\n    Printf(\"Total cached: %zd\\n\", total_cached);\n  }\n\n  static bool SizeClassRequiresSeparateTransferBatch(uptr class_id) {\n    return Size(class_id) < sizeof(TransferBatch) -\n        sizeof(uptr) * (kMaxNumCached - MaxCached(class_id));\n  }\n\n  static void Validate() {\n    for (uptr c = 1; c < kNumClasses; c++) {\n      // Printf(\"Validate: c%zd\\n\", c);\n      uptr s = Size(c);\n      CHECK_NE(s, 0U);\n      CHECK_EQ(ClassID(s), c);\n      if (c != kNumClasses - 1)\n        CHECK_EQ(ClassID(s + 1), c + 1);\n      CHECK_EQ(ClassID(s - 1), c);\n      if (c)\n        CHECK_GT(Size(c), Size(c-1));\n    }\n    CHECK_EQ(ClassID(kMaxSize + 1), 0);\n\n    for (uptr s = 1; s <= kMaxSize; s++) {\n      uptr c = ClassID(s);\n      // Printf(\"s%zd => c%zd\\n\", s, c);\n      CHECK_LT(c, kNumClasses);\n      CHECK_GE(Size(c), s);\n      if (c > 0)\n        CHECK_LT(Size(c-1), s);\n    }\n  }\n};\n\ntypedef SizeClassMap<17, 128, 16> DefaultSizeClassMap;\ntypedef SizeClassMap<17, 64,  14> CompactSizeClassMap;\ntemplate<class SizeClassAllocator> struct SizeClassAllocatorLocalCache;\n\n// Memory allocator statistics\nenum AllocatorStat {\n  AllocatorStatAllocated,\n  AllocatorStatMapped,\n  AllocatorStatCount\n};\n\ntypedef uptr AllocatorStatCounters[AllocatorStatCount];\n\n// Per-thread stats, live in per-thread cache.\nclass AllocatorStats {\n public:\n  void Init() {\n    internal_memset(this, 0, sizeof(*this));\n  }\n  void InitLinkerInitialized() {}\n\n  void Add(AllocatorStat i, uptr v) {\n    v += atomic_load(&stats_[i], memory_order_relaxed);\n    atomic_store(&stats_[i], v, memory_order_relaxed);\n  }\n\n  void Sub(AllocatorStat i, uptr v) {\n    v = atomic_load(&stats_[i], memory_order_relaxed) - v;\n    atomic_store(&stats_[i], v, memory_order_relaxed);\n  }\n\n  void Set(AllocatorStat i, uptr v) {\n    atomic_store(&stats_[i], v, memory_order_relaxed);\n  }\n\n  uptr Get(AllocatorStat i) const {\n    return atomic_load(&stats_[i], memory_order_relaxed);\n  }\n\n private:\n  friend class AllocatorGlobalStats;\n  AllocatorStats *next_;\n  AllocatorStats *prev_;\n  atomic_uintptr_t stats_[AllocatorStatCount];\n};\n\n// Global stats, used for aggregation and querying.\nclass AllocatorGlobalStats : public AllocatorStats {\n public:\n  void InitLinkerInitialized() {\n    next_ = this;\n    prev_ = this;\n  }\n  void Init() {\n    internal_memset(this, 0, sizeof(*this));\n    InitLinkerInitialized();\n  }\n\n  void Register(AllocatorStats *s) {\n    SpinMutexLock l(&mu_);\n    s->next_ = next_;\n    s->prev_ = this;\n    next_->prev_ = s;\n    next_ = s;\n  }\n\n  void Unregister(AllocatorStats *s) {\n    SpinMutexLock l(&mu_);\n    s->prev_->next_ = s->next_;\n    s->next_->prev_ = s->prev_;\n    for (int i = 0; i < AllocatorStatCount; i++)\n      Add(AllocatorStat(i), s->Get(AllocatorStat(i)));\n  }\n\n  void Get(AllocatorStatCounters s) const {\n    internal_memset(s, 0, AllocatorStatCount * sizeof(uptr));\n    SpinMutexLock l(&mu_);\n    const AllocatorStats *stats = this;\n    for (;;) {\n      for (int i = 0; i < AllocatorStatCount; i++)\n        s[i] += stats->Get(AllocatorStat(i));\n      stats = stats->next_;\n      if (stats == this)\n        break;\n    }\n    // All stats must be non-negative.\n    for (int i = 0; i < AllocatorStatCount; i++)\n      s[i] = ((sptr)s[i]) >= 0 ? s[i] : 0;\n  }\n\n private:\n  mutable SpinMutex mu_;\n};\n\n// Allocators call these callbacks on mmap/munmap.\nstruct NoOpMapUnmapCallback {\n  void OnMap(uptr p, uptr size) const { }\n  void OnUnmap(uptr p, uptr size) const { }\n};\n\n// Callback type for iterating over chunks.\ntypedef void (*ForEachChunkCallback)(uptr chunk, void *arg);\n\n// SizeClassAllocator64 -- allocator for 64-bit address space.\n//\n// Space: a portion of address space of kSpaceSize bytes starting at\n// a fixed address (kSpaceBeg). Both constants are powers of two and\n// kSpaceBeg is kSpaceSize-aligned.\n// At the beginning the entire space is mprotect-ed, then small parts of it\n// are mapped on demand.\n//\n// Region: a part of Space dedicated to a single size class.\n// There are kNumClasses Regions of equal size.\n//\n// UserChunk: a piece of memory returned to user.\n// MetaChunk: kMetadataSize bytes of metadata associated with a UserChunk.\n//\n// A Region looks like this:\n// UserChunk1 ... UserChunkN <gap> MetaChunkN ... MetaChunk1\ntemplate <const uptr kSpaceBeg, const uptr kSpaceSize,\n          const uptr kMetadataSize, class SizeClassMap,\n          class MapUnmapCallback = NoOpMapUnmapCallback>\nclass SizeClassAllocator64 {\n public:\n  typedef typename SizeClassMap::TransferBatch Batch;\n  typedef SizeClassAllocator64<kSpaceBeg, kSpaceSize, kMetadataSize,\n      SizeClassMap, MapUnmapCallback> ThisT;\n  typedef SizeClassAllocatorLocalCache<ThisT> AllocatorCache;\n\n  void Init() {\n    CHECK_EQ(kSpaceBeg,\n             reinterpret_cast<uptr>(MmapNoAccess(kSpaceBeg, kSpaceSize)));\n    MapWithCallback(kSpaceEnd, AdditionalSize());\n  }\n\n  void MapWithCallback(uptr beg, uptr size) {\n    CHECK_EQ(beg, reinterpret_cast<uptr>(MmapFixedOrDie(beg, size)));\n    MapUnmapCallback().OnMap(beg, size);\n  }\n\n  void UnmapWithCallback(uptr beg, uptr size) {\n    MapUnmapCallback().OnUnmap(beg, size);\n    UnmapOrDie(reinterpret_cast<void *>(beg), size);\n  }\n\n  static bool CanAllocate(uptr size, uptr alignment) {\n    return size <= SizeClassMap::kMaxSize &&\n      alignment <= SizeClassMap::kMaxSize;\n  }\n\n  NOINLINE Batch* AllocateBatch(AllocatorStats *stat, AllocatorCache *c,\n                                uptr class_id) {\n    CHECK_LT(class_id, kNumClasses);\n    RegionInfo *region = GetRegionInfo(class_id);\n    Batch *b = region->free_list.Pop();\n    if (!b)\n      b = PopulateFreeList(stat, c, class_id, region);\n    region->n_allocated += b->count;\n    return b;\n  }\n\n  NOINLINE void DeallocateBatch(AllocatorStats *stat, uptr class_id, Batch *b) {\n    RegionInfo *region = GetRegionInfo(class_id);\n    CHECK_GT(b->count, 0);\n    region->free_list.Push(b);\n    region->n_freed += b->count;\n  }\n\n  static bool PointerIsMine(const void *p) {\n    return reinterpret_cast<uptr>(p) / kSpaceSize == kSpaceBeg / kSpaceSize;\n  }\n\n  static uptr GetSizeClass(const void *p) {\n    return (reinterpret_cast<uptr>(p) / kRegionSize) % kNumClassesRounded;\n  }\n\n  void *GetBlockBegin(const void *p) {\n    uptr class_id = GetSizeClass(p);\n    uptr size = SizeClassMap::Size(class_id);\n    if (!size) return nullptr;\n    uptr chunk_idx = GetChunkIdx((uptr)p, size);\n    uptr reg_beg = (uptr)p & ~(kRegionSize - 1);\n    uptr beg = chunk_idx * size;\n    uptr next_beg = beg + size;\n    if (class_id >= kNumClasses) return nullptr;\n    RegionInfo *region = GetRegionInfo(class_id);\n    if (region->mapped_user >= next_beg)\n      return reinterpret_cast<void*>(reg_beg + beg);\n    return nullptr;\n  }\n\n  static uptr GetActuallyAllocatedSize(void *p) {\n    CHECK(PointerIsMine(p));\n    return SizeClassMap::Size(GetSizeClass(p));\n  }\n\n  uptr ClassID(uptr size) { return SizeClassMap::ClassID(size); }\n\n  void *GetMetaData(const void *p) {\n    uptr class_id = GetSizeClass(p);\n    uptr size = SizeClassMap::Size(class_id);\n    uptr chunk_idx = GetChunkIdx(reinterpret_cast<uptr>(p), size);\n    return reinterpret_cast<void*>(kSpaceBeg + (kRegionSize * (class_id + 1)) -\n                                   (1 + chunk_idx) * kMetadataSize);\n  }\n\n  uptr TotalMemoryUsed() {\n    uptr res = 0;\n    for (uptr i = 0; i < kNumClasses; i++)\n      res += GetRegionInfo(i)->allocated_user;\n    return res;\n  }\n\n  // Test-only.\n  void TestOnlyUnmap() {\n    UnmapWithCallback(kSpaceBeg, kSpaceSize + AdditionalSize());\n  }\n\n  void PrintStats() {\n    uptr total_mapped = 0;\n    uptr n_allocated = 0;\n    uptr n_freed = 0;\n    for (uptr class_id = 1; class_id < kNumClasses; class_id++) {\n      RegionInfo *region = GetRegionInfo(class_id);\n      total_mapped += region->mapped_user;\n      n_allocated += region->n_allocated;\n      n_freed += region->n_freed;\n    }\n    Printf(\"Stats: SizeClassAllocator64: %zdM mapped in %zd allocations; \"\n           \"remains %zd\\n\",\n           total_mapped >> 20, n_allocated, n_allocated - n_freed);\n    for (uptr class_id = 1; class_id < kNumClasses; class_id++) {\n      RegionInfo *region = GetRegionInfo(class_id);\n      if (region->mapped_user == 0) continue;\n      Printf(\"  %02zd (%zd): total: %zd K allocs: %zd remains: %zd\\n\",\n             class_id,\n             SizeClassMap::Size(class_id),\n             region->mapped_user >> 10,\n             region->n_allocated,\n             region->n_allocated - region->n_freed);\n    }\n  }\n\n  // ForceLock() and ForceUnlock() are needed to implement Darwin malloc zone\n  // introspection API.\n  void ForceLock() {\n    for (uptr i = 0; i < kNumClasses; i++) {\n      GetRegionInfo(i)->mutex.Lock();\n    }\n  }\n\n  void ForceUnlock() {\n    for (int i = (int)kNumClasses - 1; i >= 0; i--) {\n      GetRegionInfo(i)->mutex.Unlock();\n    }\n  }\n\n  // Iterate over all existing chunks.\n  // The allocator must be locked when calling this function.\n  void ForEachChunk(ForEachChunkCallback callback, void *arg) {\n    for (uptr class_id = 1; class_id < kNumClasses; class_id++) {\n      RegionInfo *region = GetRegionInfo(class_id);\n      uptr chunk_size = SizeClassMap::Size(class_id);\n      uptr region_beg = kSpaceBeg + class_id * kRegionSize;\n      for (uptr chunk = region_beg;\n           chunk < region_beg + region->allocated_user;\n           chunk += chunk_size) {\n        // Too slow: CHECK_EQ((void *)chunk, GetBlockBegin((void *)chunk));\n        callback(chunk, arg);\n      }\n    }\n  }\n\n  static uptr AdditionalSize() {\n    return RoundUpTo(sizeof(RegionInfo) * kNumClassesRounded,\n                     GetPageSizeCached());\n  }\n\n  typedef SizeClassMap SizeClassMapT;\n  static const uptr kNumClasses = SizeClassMap::kNumClasses;\n  static const uptr kNumClassesRounded = SizeClassMap::kNumClassesRounded;\n\n private:\n  static const uptr kRegionSize = kSpaceSize / kNumClassesRounded;\n  static const uptr kSpaceEnd = kSpaceBeg + kSpaceSize;\n  COMPILER_CHECK(kSpaceBeg % kSpaceSize == 0);\n  // kRegionSize must be >= 2^32.\n  COMPILER_CHECK((kRegionSize) >= (1ULL << (SANITIZER_WORDSIZE / 2)));\n  // Populate the free list with at most this number of bytes at once\n  // or with one element if its size is greater.\n  static const uptr kPopulateSize = 1 << 14;\n  // Call mmap for user memory with at least this size.\n  static const uptr kUserMapSize = 1 << 16;\n  // Call mmap for metadata memory with at least this size.\n  static const uptr kMetaMapSize = 1 << 16;\n\n  struct RegionInfo {\n    BlockingMutex mutex;\n    LFStack<Batch> free_list;\n    uptr allocated_user;  // Bytes allocated for user memory.\n    uptr allocated_meta;  // Bytes allocated for metadata.\n    uptr mapped_user;  // Bytes mapped for user memory.\n    uptr mapped_meta;  // Bytes mapped for metadata.\n    uptr n_allocated, n_freed;  // Just stats.\n  };\n  COMPILER_CHECK(sizeof(RegionInfo) >= kCacheLineSize);\n\n  RegionInfo *GetRegionInfo(uptr class_id) {\n    CHECK_LT(class_id, kNumClasses);\n    RegionInfo *regions = reinterpret_cast<RegionInfo*>(kSpaceBeg + kSpaceSize);\n    return &regions[class_id];\n  }\n\n  static uptr GetChunkIdx(uptr chunk, uptr size) {\n    uptr offset = chunk % kRegionSize;\n    // Here we divide by a non-constant. This is costly.\n    // size always fits into 32-bits. If the offset fits too, use 32-bit div.\n    if (offset >> (SANITIZER_WORDSIZE / 2))\n      return offset / size;\n    return (u32)offset / (u32)size;\n  }\n\n  NOINLINE Batch* PopulateFreeList(AllocatorStats *stat, AllocatorCache *c,\n                                   uptr class_id, RegionInfo *region) {\n    BlockingMutexLock l(&region->mutex);\n    Batch *b = region->free_list.Pop();\n    if (b)\n      return b;\n    uptr size = SizeClassMap::Size(class_id);\n    uptr count = size < kPopulateSize ? SizeClassMap::MaxCached(class_id) : 1;\n    uptr beg_idx = region->allocated_user;\n    uptr end_idx = beg_idx + count * size;\n    uptr region_beg = kSpaceBeg + kRegionSize * class_id;\n    if (end_idx + size > region->mapped_user) {\n      // Do the mmap for the user memory.\n      uptr map_size = kUserMapSize;\n      while (end_idx + size > region->mapped_user + map_size)\n        map_size += kUserMapSize;\n      CHECK_GE(region->mapped_user + map_size, end_idx);\n      MapWithCallback(region_beg + region->mapped_user, map_size);\n      stat->Add(AllocatorStatMapped, map_size);\n      region->mapped_user += map_size;\n    }\n    uptr total_count = (region->mapped_user - beg_idx - size)\n        / size / count * count;\n    region->allocated_meta += total_count * kMetadataSize;\n    if (region->allocated_meta > region->mapped_meta) {\n      uptr map_size = kMetaMapSize;\n      while (region->allocated_meta > region->mapped_meta + map_size)\n        map_size += kMetaMapSize;\n      // Do the mmap for the metadata.\n      CHECK_GE(region->mapped_meta + map_size, region->allocated_meta);\n      MapWithCallback(region_beg + kRegionSize -\n                      region->mapped_meta - map_size, map_size);\n      region->mapped_meta += map_size;\n    }\n    CHECK_LE(region->allocated_meta, region->mapped_meta);\n    if (region->mapped_user + region->mapped_meta > kRegionSize) {\n      Printf(\"%s: Out of memory. Dying. \", SanitizerToolName);\n      Printf(\"The process has exhausted %zuMB for size class %zu.\\n\",\n          kRegionSize / 1024 / 1024, size);\n      Die();\n    }\n    for (;;) {\n      if (SizeClassMap::SizeClassRequiresSeparateTransferBatch(class_id))\n        b = (Batch*)c->Allocate(this, SizeClassMap::ClassID(sizeof(Batch)));\n      else\n        b = (Batch*)(region_beg + beg_idx);\n      b->count = count;\n      for (uptr i = 0; i < count; i++)\n        b->batch[i] = (void*)(region_beg + beg_idx + i * size);\n      region->allocated_user += count * size;\n      CHECK_LE(region->allocated_user, region->mapped_user);\n      beg_idx += count * size;\n      if (beg_idx + count * size + size > region->mapped_user)\n        break;\n      CHECK_GT(b->count, 0);\n      region->free_list.Push(b);\n    }\n    return b;\n  }\n};\n\n// Maps integers in rage [0, kSize) to u8 values.\ntemplate<u64 kSize>\nclass FlatByteMap {\n public:\n  void TestOnlyInit() {\n    internal_memset(map_, 0, sizeof(map_));\n  }\n\n  void set(uptr idx, u8 val) {\n    CHECK_LT(idx, kSize);\n    CHECK_EQ(0U, map_[idx]);\n    map_[idx] = val;\n  }\n  u8 operator[] (uptr idx) {\n    CHECK_LT(idx, kSize);\n    // FIXME: CHECK may be too expensive here.\n    return map_[idx];\n  }\n private:\n  u8 map_[kSize];\n};\n\n// TwoLevelByteMap maps integers in range [0, kSize1*kSize2) to u8 values.\n// It is implemented as a two-dimensional array: array of kSize1 pointers\n// to kSize2-byte arrays. The secondary arrays are mmaped on demand.\n// Each value is initially zero and can be set to something else only once.\n// Setting and getting values from multiple threads is safe w/o extra locking.\ntemplate <u64 kSize1, u64 kSize2, class MapUnmapCallback = NoOpMapUnmapCallback>\nclass TwoLevelByteMap {\n public:\n  void TestOnlyInit() {\n    internal_memset(map1_, 0, sizeof(map1_));\n    mu_.Init();\n  }\n\n  void TestOnlyUnmap() {\n    for (uptr i = 0; i < kSize1; i++) {\n      u8 *p = Get(i);\n      if (!p) continue;\n      MapUnmapCallback().OnUnmap(reinterpret_cast<uptr>(p), kSize2);\n      UnmapOrDie(p, kSize2);\n    }\n  }\n\n  uptr size() const { return kSize1 * kSize2; }\n  uptr size1() const { return kSize1; }\n  uptr size2() const { return kSize2; }\n\n  void set(uptr idx, u8 val) {\n    CHECK_LT(idx, kSize1 * kSize2);\n    u8 *map2 = GetOrCreate(idx / kSize2);\n    CHECK_EQ(0U, map2[idx % kSize2]);\n    map2[idx % kSize2] = val;\n  }\n\n  u8 operator[] (uptr idx) const {\n    CHECK_LT(idx, kSize1 * kSize2);\n    u8 *map2 = Get(idx / kSize2);\n    if (!map2) return 0;\n    return map2[idx % kSize2];\n  }\n\n private:\n  u8 *Get(uptr idx) const {\n    CHECK_LT(idx, kSize1);\n    return reinterpret_cast<u8 *>(\n        atomic_load(&map1_[idx], memory_order_acquire));\n  }\n\n  u8 *GetOrCreate(uptr idx) {\n    u8 *res = Get(idx);\n    if (!res) {\n      SpinMutexLock l(&mu_);\n      if (!(res = Get(idx))) {\n        res = (u8*)MmapOrDie(kSize2, \"TwoLevelByteMap\");\n        MapUnmapCallback().OnMap(reinterpret_cast<uptr>(res), kSize2);\n        atomic_store(&map1_[idx], reinterpret_cast<uptr>(res),\n                     memory_order_release);\n      }\n    }\n    return res;\n  }\n\n  atomic_uintptr_t map1_[kSize1];\n  StaticSpinMutex mu_;\n};\n\n// SizeClassAllocator32 -- allocator for 32-bit address space.\n// This allocator can theoretically be used on 64-bit arch, but there it is less\n// efficient than SizeClassAllocator64.\n//\n// [kSpaceBeg, kSpaceBeg + kSpaceSize) is the range of addresses which can\n// be returned by MmapOrDie().\n//\n// Region:\n//   a result of a single call to MmapAlignedOrDie(kRegionSize, kRegionSize).\n// Since the regions are aligned by kRegionSize, there are exactly\n// kNumPossibleRegions possible regions in the address space and so we keep\n// a ByteMap possible_regions to store the size classes of each Region.\n// 0 size class means the region is not used by the allocator.\n//\n// One Region is used to allocate chunks of a single size class.\n// A Region looks like this:\n// UserChunk1 .. UserChunkN <gap> MetaChunkN .. MetaChunk1\n//\n// In order to avoid false sharing the objects of this class should be\n// chache-line aligned.\ntemplate <const uptr kSpaceBeg, const u64 kSpaceSize,\n          const uptr kMetadataSize, class SizeClassMap,\n          const uptr kRegionSizeLog,\n          class ByteMap,\n          class MapUnmapCallback = NoOpMapUnmapCallback>\nclass SizeClassAllocator32 {\n public:\n  typedef typename SizeClassMap::TransferBatch Batch;\n  typedef SizeClassAllocator32<kSpaceBeg, kSpaceSize, kMetadataSize,\n      SizeClassMap, kRegionSizeLog, ByteMap, MapUnmapCallback> ThisT;\n  typedef SizeClassAllocatorLocalCache<ThisT> AllocatorCache;\n\n  void Init() {\n    possible_regions.TestOnlyInit();\n    internal_memset(size_class_info_array, 0, sizeof(size_class_info_array));\n  }\n\n  void *MapWithCallback(uptr size) {\n    size = RoundUpTo(size, GetPageSizeCached());\n    void *res = MmapOrDie(size, \"SizeClassAllocator32\");\n    MapUnmapCallback().OnMap((uptr)res, size);\n    return res;\n  }\n\n  void UnmapWithCallback(uptr beg, uptr size) {\n    MapUnmapCallback().OnUnmap(beg, size);\n    UnmapOrDie(reinterpret_cast<void *>(beg), size);\n  }\n\n  static bool CanAllocate(uptr size, uptr alignment) {\n    return size <= SizeClassMap::kMaxSize &&\n      alignment <= SizeClassMap::kMaxSize;\n  }\n\n  void *GetMetaData(const void *p) {\n    CHECK(PointerIsMine(p));\n    uptr mem = reinterpret_cast<uptr>(p);\n    uptr beg = ComputeRegionBeg(mem);\n    uptr size = SizeClassMap::Size(GetSizeClass(p));\n    u32 offset = mem - beg;\n    uptr n = offset / (u32)size;  // 32-bit division\n    uptr meta = (beg + kRegionSize) - (n + 1) * kMetadataSize;\n    return reinterpret_cast<void*>(meta);\n  }\n\n  NOINLINE Batch* AllocateBatch(AllocatorStats *stat, AllocatorCache *c,\n                                uptr class_id) {\n    CHECK_LT(class_id, kNumClasses);\n    SizeClassInfo *sci = GetSizeClassInfo(class_id);\n    SpinMutexLock l(&sci->mutex);\n    if (sci->free_list.empty())\n      PopulateFreeList(stat, c, sci, class_id);\n    CHECK(!sci->free_list.empty());\n    Batch *b = sci->free_list.front();\n    sci->free_list.pop_front();\n    return b;\n  }\n\n  NOINLINE void DeallocateBatch(AllocatorStats *stat, uptr class_id, Batch *b) {\n    CHECK_LT(class_id, kNumClasses);\n    SizeClassInfo *sci = GetSizeClassInfo(class_id);\n    SpinMutexLock l(&sci->mutex);\n    CHECK_GT(b->count, 0);\n    sci->free_list.push_front(b);\n  }\n\n  bool PointerIsMine(const void *p) {\n    return GetSizeClass(p) != 0;\n  }\n\n  uptr GetSizeClass(const void *p) {\n    return possible_regions[ComputeRegionId(reinterpret_cast<uptr>(p))];\n  }\n\n  void *GetBlockBegin(const void *p) {\n    CHECK(PointerIsMine(p));\n    uptr mem = reinterpret_cast<uptr>(p);\n    uptr beg = ComputeRegionBeg(mem);\n    uptr size = SizeClassMap::Size(GetSizeClass(p));\n    u32 offset = mem - beg;\n    u32 n = offset / (u32)size;  // 32-bit division\n    uptr res = beg + (n * (u32)size);\n    return reinterpret_cast<void*>(res);\n  }\n\n  uptr GetActuallyAllocatedSize(void *p) {\n    CHECK(PointerIsMine(p));\n    return SizeClassMap::Size(GetSizeClass(p));\n  }\n\n  uptr ClassID(uptr size) { return SizeClassMap::ClassID(size); }\n\n  uptr TotalMemoryUsed() {\n    // No need to lock here.\n    uptr res = 0;\n    for (uptr i = 0; i < kNumPossibleRegions; i++)\n      if (possible_regions[i])\n        res += kRegionSize;\n    return res;\n  }\n\n  void TestOnlyUnmap() {\n    for (uptr i = 0; i < kNumPossibleRegions; i++)\n      if (possible_regions[i])\n        UnmapWithCallback((i * kRegionSize), kRegionSize);\n  }\n\n  // ForceLock() and ForceUnlock() are needed to implement Darwin malloc zone\n  // introspection API.\n  void ForceLock() {\n    for (uptr i = 0; i < kNumClasses; i++) {\n      GetSizeClassInfo(i)->mutex.Lock();\n    }\n  }\n\n  void ForceUnlock() {\n    for (int i = kNumClasses - 1; i >= 0; i--) {\n      GetSizeClassInfo(i)->mutex.Unlock();\n    }\n  }\n\n  // Iterate over all existing chunks.\n  // The allocator must be locked when calling this function.\n  void ForEachChunk(ForEachChunkCallback callback, void *arg) {\n    for (uptr region = 0; region < kNumPossibleRegions; region++)\n      if (possible_regions[region]) {\n        uptr chunk_size = SizeClassMap::Size(possible_regions[region]);\n        uptr max_chunks_in_region = kRegionSize / (chunk_size + kMetadataSize);\n        uptr region_beg = region * kRegionSize;\n        for (uptr chunk = region_beg;\n             chunk < region_beg + max_chunks_in_region * chunk_size;\n             chunk += chunk_size) {\n          // Too slow: CHECK_EQ((void *)chunk, GetBlockBegin((void *)chunk));\n          callback(chunk, arg);\n        }\n      }\n  }\n\n  void PrintStats() {\n  }\n\n  static uptr AdditionalSize() {\n    return 0;\n  }\n\n  typedef SizeClassMap SizeClassMapT;\n  static const uptr kNumClasses = SizeClassMap::kNumClasses;\n\n private:\n  static const uptr kRegionSize = 1 << kRegionSizeLog;\n  static const uptr kNumPossibleRegions = kSpaceSize / kRegionSize;\n\n  struct SizeClassInfo {\n    SpinMutex mutex;\n    IntrusiveList<Batch> free_list;\n    char padding[kCacheLineSize - sizeof(uptr) - sizeof(IntrusiveList<Batch>)];\n  };\n  COMPILER_CHECK(sizeof(SizeClassInfo) == kCacheLineSize);\n\n  uptr ComputeRegionId(uptr mem) {\n    uptr res = mem >> kRegionSizeLog;\n    CHECK_LT(res, kNumPossibleRegions);\n    return res;\n  }\n\n  uptr ComputeRegionBeg(uptr mem) {\n    return mem & ~(kRegionSize - 1);\n  }\n\n  uptr AllocateRegion(AllocatorStats *stat, uptr class_id) {\n    CHECK_LT(class_id, kNumClasses);\n    uptr res = reinterpret_cast<uptr>(MmapAlignedOrDie(kRegionSize, kRegionSize,\n                                      \"SizeClassAllocator32\"));\n    MapUnmapCallback().OnMap(res, kRegionSize);\n    stat->Add(AllocatorStatMapped, kRegionSize);\n    CHECK_EQ(0U, (res & (kRegionSize - 1)));\n    possible_regions.set(ComputeRegionId(res), static_cast<u8>(class_id));\n    return res;\n  }\n\n  SizeClassInfo *GetSizeClassInfo(uptr class_id) {\n    CHECK_LT(class_id, kNumClasses);\n    return &size_class_info_array[class_id];\n  }\n\n  void PopulateFreeList(AllocatorStats *stat, AllocatorCache *c,\n                        SizeClassInfo *sci, uptr class_id) {\n    uptr size = SizeClassMap::Size(class_id);\n    uptr reg = AllocateRegion(stat, class_id);\n    uptr n_chunks = kRegionSize / (size + kMetadataSize);\n    uptr max_count = SizeClassMap::MaxCached(class_id);\n    Batch *b = nullptr;\n    for (uptr i = reg; i < reg + n_chunks * size; i += size) {\n      if (!b) {\n        if (SizeClassMap::SizeClassRequiresSeparateTransferBatch(class_id))\n          b = (Batch*)c->Allocate(this, SizeClassMap::ClassID(sizeof(Batch)));\n        else\n          b = (Batch*)i;\n        b->count = 0;\n      }\n      b->batch[b->count++] = (void*)i;\n      if (b->count == max_count) {\n        CHECK_GT(b->count, 0);\n        sci->free_list.push_back(b);\n        b = nullptr;\n      }\n    }\n    if (b) {\n      CHECK_GT(b->count, 0);\n      sci->free_list.push_back(b);\n    }\n  }\n\n  ByteMap possible_regions;\n  SizeClassInfo size_class_info_array[kNumClasses];\n};\n\n// Objects of this type should be used as local caches for SizeClassAllocator64\n// or SizeClassAllocator32. Since the typical use of this class is to have one\n// object per thread in TLS, is has to be POD.\ntemplate<class SizeClassAllocator>\nstruct SizeClassAllocatorLocalCache {\n  typedef SizeClassAllocator Allocator;\n  static const uptr kNumClasses = SizeClassAllocator::kNumClasses;\n\n  void Init(AllocatorGlobalStats *s) {\n    stats_.Init();\n    if (s)\n      s->Register(&stats_);\n  }\n\n  void Destroy(SizeClassAllocator *allocator, AllocatorGlobalStats *s) {\n    Drain(allocator);\n    if (s)\n      s->Unregister(&stats_);\n  }\n\n  void *Allocate(SizeClassAllocator *allocator, uptr class_id) {\n    CHECK_NE(class_id, 0UL);\n    CHECK_LT(class_id, kNumClasses);\n    stats_.Add(AllocatorStatAllocated, SizeClassMap::Size(class_id));\n    PerClass *c = &per_class_[class_id];\n    if (UNLIKELY(c->count == 0))\n      Refill(allocator, class_id);\n    void *res = c->batch[--c->count];\n    PREFETCH(c->batch[c->count - 1]);\n    return res;\n  }\n\n  void Deallocate(SizeClassAllocator *allocator, uptr class_id, void *p) {\n    CHECK_NE(class_id, 0UL);\n    CHECK_LT(class_id, kNumClasses);\n    // If the first allocator call on a new thread is a deallocation, then\n    // max_count will be zero, leading to check failure.\n    InitCache();\n    stats_.Sub(AllocatorStatAllocated, SizeClassMap::Size(class_id));\n    PerClass *c = &per_class_[class_id];\n    CHECK_NE(c->max_count, 0UL);\n    if (UNLIKELY(c->count == c->max_count))\n      Drain(allocator, class_id);\n    c->batch[c->count++] = p;\n  }\n\n  void Drain(SizeClassAllocator *allocator) {\n    for (uptr class_id = 0; class_id < kNumClasses; class_id++) {\n      PerClass *c = &per_class_[class_id];\n      while (c->count > 0)\n        Drain(allocator, class_id);\n    }\n  }\n\n  // private:\n  typedef typename SizeClassAllocator::SizeClassMapT SizeClassMap;\n  typedef typename SizeClassMap::TransferBatch Batch;\n  struct PerClass {\n    uptr count;\n    uptr max_count;\n    void *batch[2 * SizeClassMap::kMaxNumCached];\n  };\n  PerClass per_class_[kNumClasses];\n  AllocatorStats stats_;\n\n  void InitCache() {\n    if (per_class_[1].max_count)\n      return;\n    for (uptr i = 0; i < kNumClasses; i++) {\n      PerClass *c = &per_class_[i];\n      c->max_count = 2 * SizeClassMap::MaxCached(i);\n    }\n  }\n\n  NOINLINE void Refill(SizeClassAllocator *allocator, uptr class_id) {\n    InitCache();\n    PerClass *c = &per_class_[class_id];\n    Batch *b = allocator->AllocateBatch(&stats_, this, class_id);\n    CHECK_GT(b->count, 0);\n    for (uptr i = 0; i < b->count; i++)\n      c->batch[i] = b->batch[i];\n    c->count = b->count;\n    if (SizeClassMap::SizeClassRequiresSeparateTransferBatch(class_id))\n      Deallocate(allocator, SizeClassMap::ClassID(sizeof(Batch)), b);\n  }\n\n  NOINLINE void Drain(SizeClassAllocator *allocator, uptr class_id) {\n    InitCache();\n    PerClass *c = &per_class_[class_id];\n    Batch *b;\n    if (SizeClassMap::SizeClassRequiresSeparateTransferBatch(class_id))\n      b = (Batch*)Allocate(allocator, SizeClassMap::ClassID(sizeof(Batch)));\n    else\n      b = (Batch*)c->batch[0];\n    uptr cnt = Min(c->max_count / 2, c->count);\n    for (uptr i = 0; i < cnt; i++) {\n      b->batch[i] = c->batch[i];\n      c->batch[i] = c->batch[i + c->max_count / 2];\n    }\n    b->count = cnt;\n    c->count -= cnt;\n    CHECK_GT(b->count, 0);\n    allocator->DeallocateBatch(&stats_, class_id, b);\n  }\n};\n\n// This class can (de)allocate only large chunks of memory using mmap/unmap.\n// The main purpose of this allocator is to cover large and rare allocation\n// sizes not covered by more efficient allocators (e.g. SizeClassAllocator64).\ntemplate <class MapUnmapCallback = NoOpMapUnmapCallback>\nclass LargeMmapAllocator {\n public:\n  void InitLinkerInitialized(bool may_return_null) {\n    page_size_ = GetPageSizeCached();\n    atomic_store(&may_return_null_, may_return_null, memory_order_relaxed);\n  }\n\n  void Init(bool may_return_null) {\n    internal_memset(this, 0, sizeof(*this));\n    InitLinkerInitialized(may_return_null);\n  }\n\n  void *Allocate(AllocatorStats *stat, uptr size, uptr alignment) {\n    CHECK(IsPowerOfTwo(alignment));\n    uptr map_size = RoundUpMapSize(size);\n    if (alignment > page_size_)\n      map_size += alignment;\n    // Overflow.\n    if (map_size < size)\n      return ReturnNullOrDie();\n    uptr map_beg = reinterpret_cast<uptr>(\n        MmapOrDie(map_size, \"LargeMmapAllocator\"));\n    CHECK(IsAligned(map_beg, page_size_));\n    MapUnmapCallback().OnMap(map_beg, map_size);\n    uptr map_end = map_beg + map_size;\n    uptr res = map_beg + page_size_;\n    if (res & (alignment - 1))  // Align.\n      res += alignment - (res & (alignment - 1));\n    CHECK(IsAligned(res, alignment));\n    CHECK(IsAligned(res, page_size_));\n    CHECK_GE(res + size, map_beg);\n    CHECK_LE(res + size, map_end);\n    Header *h = GetHeader(res);\n    h->size = size;\n    h->map_beg = map_beg;\n    h->map_size = map_size;\n    uptr size_log = MostSignificantSetBitIndex(map_size);\n    CHECK_LT(size_log, ARRAY_SIZE(stats.by_size_log));\n    {\n      SpinMutexLock l(&mutex_);\n      uptr idx = n_chunks_++;\n      chunks_sorted_ = false;\n      CHECK_LT(idx, kMaxNumChunks);\n      h->chunk_idx = idx;\n      chunks_[idx] = h;\n      stats.n_allocs++;\n      stats.currently_allocated += map_size;\n      stats.max_allocated = Max(stats.max_allocated, stats.currently_allocated);\n      stats.by_size_log[size_log]++;\n      stat->Add(AllocatorStatAllocated, map_size);\n      stat->Add(AllocatorStatMapped, map_size);\n    }\n    return reinterpret_cast<void*>(res);\n  }\n\n  void *ReturnNullOrDie() {\n    if (atomic_load(&may_return_null_, memory_order_acquire))\n      return nullptr;\n    ReportAllocatorCannotReturnNull();\n  }\n\n  void SetMayReturnNull(bool may_return_null) {\n    atomic_store(&may_return_null_, may_return_null, memory_order_release);\n  }\n\n  void Deallocate(AllocatorStats *stat, void *p) {\n    Header *h = GetHeader(p);\n    {\n      SpinMutexLock l(&mutex_);\n      uptr idx = h->chunk_idx;\n      CHECK_EQ(chunks_[idx], h);\n      CHECK_LT(idx, n_chunks_);\n      chunks_[idx] = chunks_[n_chunks_ - 1];\n      chunks_[idx]->chunk_idx = idx;\n      n_chunks_--;\n      chunks_sorted_ = false;\n      stats.n_frees++;\n      stats.currently_allocated -= h->map_size;\n      stat->Sub(AllocatorStatAllocated, h->map_size);\n      stat->Sub(AllocatorStatMapped, h->map_size);\n    }\n    MapUnmapCallback().OnUnmap(h->map_beg, h->map_size);\n    UnmapOrDie(reinterpret_cast<void*>(h->map_beg), h->map_size);\n  }\n\n  uptr TotalMemoryUsed() {\n    SpinMutexLock l(&mutex_);\n    uptr res = 0;\n    for (uptr i = 0; i < n_chunks_; i++) {\n      Header *h = chunks_[i];\n      CHECK_EQ(h->chunk_idx, i);\n      res += RoundUpMapSize(h->size);\n    }\n    return res;\n  }\n\n  bool PointerIsMine(const void *p) {\n    return GetBlockBegin(p) != nullptr;\n  }\n\n  uptr GetActuallyAllocatedSize(void *p) {\n    return RoundUpTo(GetHeader(p)->size, page_size_);\n  }\n\n  // At least page_size_/2 metadata bytes is available.\n  void *GetMetaData(const void *p) {\n    // Too slow: CHECK_EQ(p, GetBlockBegin(p));\n    if (!IsAligned(reinterpret_cast<uptr>(p), page_size_)) {\n      Printf(\"%s: bad pointer %p\\n\", SanitizerToolName, p);\n      CHECK(IsAligned(reinterpret_cast<uptr>(p), page_size_));\n    }\n    return GetHeader(p) + 1;\n  }\n\n  void *GetBlockBegin(const void *ptr) {\n    uptr p = reinterpret_cast<uptr>(ptr);\n    SpinMutexLock l(&mutex_);\n    uptr nearest_chunk = 0;\n    // Cache-friendly linear search.\n    for (uptr i = 0; i < n_chunks_; i++) {\n      uptr ch = reinterpret_cast<uptr>(chunks_[i]);\n      if (p < ch) continue;  // p is at left to this chunk, skip it.\n      if (p - ch < p - nearest_chunk)\n        nearest_chunk = ch;\n    }\n    if (!nearest_chunk)\n      return nullptr;\n    Header *h = reinterpret_cast<Header *>(nearest_chunk);\n    CHECK_GE(nearest_chunk, h->map_beg);\n    CHECK_LT(nearest_chunk, h->map_beg + h->map_size);\n    CHECK_LE(nearest_chunk, p);\n    if (h->map_beg + h->map_size <= p)\n      return nullptr;\n    return GetUser(h);\n  }\n\n  // This function does the same as GetBlockBegin, but is much faster.\n  // Must be called with the allocator locked.\n  void *GetBlockBeginFastLocked(void *ptr) {\n    mutex_.CheckLocked();\n    uptr p = reinterpret_cast<uptr>(ptr);\n    uptr n = n_chunks_;\n    if (!n) return nullptr;\n    if (!chunks_sorted_) {\n      // Do one-time sort. chunks_sorted_ is reset in Allocate/Deallocate.\n      SortArray(reinterpret_cast<uptr*>(chunks_), n);\n      for (uptr i = 0; i < n; i++)\n        chunks_[i]->chunk_idx = i;\n      chunks_sorted_ = true;\n      min_mmap_ = reinterpret_cast<uptr>(chunks_[0]);\n      max_mmap_ = reinterpret_cast<uptr>(chunks_[n - 1]) +\n          chunks_[n - 1]->map_size;\n    }\n    if (p < min_mmap_ || p >= max_mmap_)\n      return nullptr;\n    uptr beg = 0, end = n - 1;\n    // This loop is a log(n) lower_bound. It does not check for the exact match\n    // to avoid expensive cache-thrashing loads.\n    while (end - beg >= 2) {\n      uptr mid = (beg + end) / 2;  // Invariant: mid >= beg + 1\n      if (p < reinterpret_cast<uptr>(chunks_[mid]))\n        end = mid - 1;  // We are not interested in chunks_[mid].\n      else\n        beg = mid;  // chunks_[mid] may still be what we want.\n    }\n\n    if (beg < end) {\n      CHECK_EQ(beg + 1, end);\n      // There are 2 chunks left, choose one.\n      if (p >= reinterpret_cast<uptr>(chunks_[end]))\n        beg = end;\n    }\n\n    Header *h = chunks_[beg];\n    if (h->map_beg + h->map_size <= p || p < h->map_beg)\n      return nullptr;\n    return GetUser(h);\n  }\n\n  void PrintStats() {\n    Printf(\"Stats: LargeMmapAllocator: allocated %zd times, \"\n           \"remains %zd (%zd K) max %zd M; by size logs: \",\n           stats.n_allocs, stats.n_allocs - stats.n_frees,\n           stats.currently_allocated >> 10, stats.max_allocated >> 20);\n    for (uptr i = 0; i < ARRAY_SIZE(stats.by_size_log); i++) {\n      uptr c = stats.by_size_log[i];\n      if (!c) continue;\n      Printf(\"%zd:%zd; \", i, c);\n    }\n    Printf(\"\\n\");\n  }\n\n  // ForceLock() and ForceUnlock() are needed to implement Darwin malloc zone\n  // introspection API.\n  void ForceLock() {\n    mutex_.Lock();\n  }\n\n  void ForceUnlock() {\n    mutex_.Unlock();\n  }\n\n  // Iterate over all existing chunks.\n  // The allocator must be locked when calling this function.\n  void ForEachChunk(ForEachChunkCallback callback, void *arg) {\n    for (uptr i = 0; i < n_chunks_; i++)\n      callback(reinterpret_cast<uptr>(GetUser(chunks_[i])), arg);\n  }\n\n private:\n  static const int kMaxNumChunks = 1 << FIRST_32_SECOND_64(15, 18);\n  struct Header {\n    uptr map_beg;\n    uptr map_size;\n    uptr size;\n    uptr chunk_idx;\n  };\n\n  Header *GetHeader(uptr p) {\n    CHECK(IsAligned(p, page_size_));\n    return reinterpret_cast<Header*>(p - page_size_);\n  }\n  Header *GetHeader(const void *p) {\n    return GetHeader(reinterpret_cast<uptr>(p));\n  }\n\n  void *GetUser(Header *h) {\n    CHECK(IsAligned((uptr)h, page_size_));\n    return reinterpret_cast<void*>(reinterpret_cast<uptr>(h) + page_size_);\n  }\n\n  uptr RoundUpMapSize(uptr size) {\n    return RoundUpTo(size, page_size_) + page_size_;\n  }\n\n  uptr page_size_;\n  Header *chunks_[kMaxNumChunks];\n  uptr n_chunks_;\n  uptr min_mmap_, max_mmap_;\n  bool chunks_sorted_;\n  struct Stats {\n    uptr n_allocs, n_frees, currently_allocated, max_allocated, by_size_log[64];\n  } stats;\n  atomic_uint8_t may_return_null_;\n  SpinMutex mutex_;\n};\n\n// This class implements a complete memory allocator by using two\n// internal allocators:\n// PrimaryAllocator is efficient, but may not allocate some sizes (alignments).\n//  When allocating 2^x bytes it should return 2^x aligned chunk.\n// PrimaryAllocator is used via a local AllocatorCache.\n// SecondaryAllocator can allocate anything, but is not efficient.\ntemplate <class PrimaryAllocator, class AllocatorCache,\n          class SecondaryAllocator>  // NOLINT\nclass CombinedAllocator {\n public:\n  void InitCommon(bool may_return_null) {\n    primary_.Init();\n    atomic_store(&may_return_null_, may_return_null, memory_order_relaxed);\n  }\n\n  void InitLinkerInitialized(bool may_return_null) {\n    secondary_.InitLinkerInitialized(may_return_null);\n    stats_.InitLinkerInitialized();\n    InitCommon(may_return_null);\n  }\n\n  void Init(bool may_return_null) {\n    secondary_.Init(may_return_null);\n    stats_.Init();\n    InitCommon(may_return_null);\n  }\n\n  void *Allocate(AllocatorCache *cache, uptr size, uptr alignment,\n                 bool cleared = false, bool check_rss_limit = false) {\n    // Returning 0 on malloc(0) may break a lot of code.\n    if (size == 0)\n      size = 1;\n    if (size + alignment < size)\n      return ReturnNullOrDie();\n    if (check_rss_limit && RssLimitIsExceeded())\n      return ReturnNullOrDie();\n    if (alignment > 8)\n      size = RoundUpTo(size, alignment);\n    void *res;\n    bool from_primary = primary_.CanAllocate(size, alignment);\n    if (from_primary)\n      res = cache->Allocate(&primary_, primary_.ClassID(size));\n    else\n      res = secondary_.Allocate(&stats_, size, alignment);\n    if (alignment > 8)\n      CHECK_EQ(reinterpret_cast<uptr>(res) & (alignment - 1), 0);\n    if (cleared && res && from_primary)\n      internal_bzero_aligned16(res, RoundUpTo(size, 16));\n    return res;\n  }\n\n  bool MayReturnNull() const {\n    return atomic_load(&may_return_null_, memory_order_acquire);\n  }\n\n  void *ReturnNullOrDie() {\n    if (MayReturnNull())\n      return nullptr;\n    ReportAllocatorCannotReturnNull();\n  }\n\n  void SetMayReturnNull(bool may_return_null) {\n    secondary_.SetMayReturnNull(may_return_null);\n    atomic_store(&may_return_null_, may_return_null, memory_order_release);\n  }\n\n  bool RssLimitIsExceeded() {\n    return atomic_load(&rss_limit_is_exceeded_, memory_order_acquire);\n  }\n\n  void SetRssLimitIsExceeded(bool rss_limit_is_exceeded) {\n    atomic_store(&rss_limit_is_exceeded_, rss_limit_is_exceeded,\n                 memory_order_release);\n  }\n\n  void Deallocate(AllocatorCache *cache, void *p) {\n    if (!p) return;\n    if (primary_.PointerIsMine(p))\n      cache->Deallocate(&primary_, primary_.GetSizeClass(p), p);\n    else\n      secondary_.Deallocate(&stats_, p);\n  }\n\n  void *Reallocate(AllocatorCache *cache, void *p, uptr new_size,\n                   uptr alignment) {\n    if (!p)\n      return Allocate(cache, new_size, alignment);\n    if (!new_size) {\n      Deallocate(cache, p);\n      return nullptr;\n    }\n    CHECK(PointerIsMine(p));\n    uptr old_size = GetActuallyAllocatedSize(p);\n    uptr memcpy_size = Min(new_size, old_size);\n    void *new_p = Allocate(cache, new_size, alignment);\n    if (new_p)\n      internal_memcpy(new_p, p, memcpy_size);\n    Deallocate(cache, p);\n    return new_p;\n  }\n\n  bool PointerIsMine(void *p) {\n    if (primary_.PointerIsMine(p))\n      return true;\n    return secondary_.PointerIsMine(p);\n  }\n\n  bool FromPrimary(void *p) {\n    return primary_.PointerIsMine(p);\n  }\n\n  void *GetMetaData(const void *p) {\n    if (primary_.PointerIsMine(p))\n      return primary_.GetMetaData(p);\n    return secondary_.GetMetaData(p);\n  }\n\n  void *GetBlockBegin(const void *p) {\n    if (primary_.PointerIsMine(p))\n      return primary_.GetBlockBegin(p);\n    return secondary_.GetBlockBegin(p);\n  }\n\n  // This function does the same as GetBlockBegin, but is much faster.\n  // Must be called with the allocator locked.\n  void *GetBlockBeginFastLocked(void *p) {\n    if (primary_.PointerIsMine(p))\n      return primary_.GetBlockBegin(p);\n    return secondary_.GetBlockBeginFastLocked(p);\n  }\n\n  uptr GetActuallyAllocatedSize(void *p) {\n    if (primary_.PointerIsMine(p))\n      return primary_.GetActuallyAllocatedSize(p);\n    return secondary_.GetActuallyAllocatedSize(p);\n  }\n\n  uptr TotalMemoryUsed() {\n    return primary_.TotalMemoryUsed() + secondary_.TotalMemoryUsed();\n  }\n\n  void TestOnlyUnmap() { primary_.TestOnlyUnmap(); }\n\n  void InitCache(AllocatorCache *cache) {\n    cache->Init(&stats_);\n  }\n\n  void DestroyCache(AllocatorCache *cache) {\n    cache->Destroy(&primary_, &stats_);\n  }\n\n  void SwallowCache(AllocatorCache *cache) {\n    cache->Drain(&primary_);\n  }\n\n  void GetStats(AllocatorStatCounters s) const {\n    stats_.Get(s);\n  }\n\n  void PrintStats() {\n    primary_.PrintStats();\n    secondary_.PrintStats();\n  }\n\n  // ForceLock() and ForceUnlock() are needed to implement Darwin malloc zone\n  // introspection API.\n  void ForceLock() {\n    primary_.ForceLock();\n    secondary_.ForceLock();\n  }\n\n  void ForceUnlock() {\n    secondary_.ForceUnlock();\n    primary_.ForceUnlock();\n  }\n\n  // Iterate over all existing chunks.\n  // The allocator must be locked when calling this function.\n  void ForEachChunk(ForEachChunkCallback callback, void *arg) {\n    primary_.ForEachChunk(callback, arg);\n    secondary_.ForEachChunk(callback, arg);\n  }\n\n private:\n  PrimaryAllocator primary_;\n  SecondaryAllocator secondary_;\n  AllocatorGlobalStats stats_;\n  atomic_uint8_t may_return_null_;\n  atomic_uint8_t rss_limit_is_exceeded_;\n};\n\n// Returns true if calloc(size, n) should return 0 due to overflow in size*n.\nbool CallocShouldReturnNullDueToOverflow(uptr size, uptr n);\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_ALLOCATOR_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_allocator_interface.h",
    "content": "//===-- sanitizer_allocator_interface.h ------------------------- C++ -----===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Re-declaration of functions from public sanitizer allocator interface.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_ALLOCATOR_INTERFACE_H\n#define SANITIZER_ALLOCATOR_INTERFACE_H\n\n#include \"sanitizer_internal_defs.h\"\n\nusing __sanitizer::uptr;\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE\nuptr __sanitizer_get_estimated_allocated_size(uptr size);\nSANITIZER_INTERFACE_ATTRIBUTE int __sanitizer_get_ownership(const void *p);\nSANITIZER_INTERFACE_ATTRIBUTE uptr\n__sanitizer_get_allocated_size(const void *p);\nSANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_current_allocated_bytes();\nSANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_heap_size();\nSANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_free_bytes();\nSANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_unmapped_bytes();\n\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\n    /* OPTIONAL */ void __sanitizer_malloc_hook(void *ptr, uptr size);\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\n    /* OPTIONAL */ void __sanitizer_free_hook(void *ptr);\n}  // extern \"C\"\n\n#endif  // SANITIZER_ALLOCATOR_INTERFACE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h",
    "content": "//===-- sanitizer_allocator_internal.h --------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This allocator is used inside run-times.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_ALLOCATOR_INTERNAL_H\n#define SANITIZER_ALLOCATOR_INTERNAL_H\n\n#include \"sanitizer_allocator.h\"\n#include \"sanitizer_internal_defs.h\"\n\nnamespace __sanitizer {\n\n// FIXME: Check if we may use even more compact size class map for internal\n// purposes.\ntypedef CompactSizeClassMap InternalSizeClassMap;\n\nstatic const uptr kInternalAllocatorSpace = 0;\nstatic const u64 kInternalAllocatorSize = SANITIZER_MMAP_RANGE_SIZE;\nstatic const uptr kInternalAllocatorRegionSizeLog = 20;\n#if SANITIZER_WORDSIZE == 32\nstatic const uptr kInternalAllocatorNumRegions =\n    kInternalAllocatorSize >> kInternalAllocatorRegionSizeLog;\ntypedef FlatByteMap<kInternalAllocatorNumRegions> ByteMap;\n#else\nstatic const uptr kInternalAllocatorNumRegions =\n    kInternalAllocatorSize >> kInternalAllocatorRegionSizeLog;\ntypedef TwoLevelByteMap<(kInternalAllocatorNumRegions >> 12), 1 << 12> ByteMap;\n#endif\ntypedef SizeClassAllocator32<\n    kInternalAllocatorSpace, kInternalAllocatorSize, 0, InternalSizeClassMap,\n    kInternalAllocatorRegionSizeLog, ByteMap> PrimaryInternalAllocator;\n\ntypedef SizeClassAllocatorLocalCache<PrimaryInternalAllocator>\n    InternalAllocatorCache;\n\ntypedef CombinedAllocator<PrimaryInternalAllocator, InternalAllocatorCache,\n                          LargeMmapAllocator<> > InternalAllocator;\n\nvoid *InternalAlloc(uptr size, InternalAllocatorCache *cache = nullptr);\nvoid InternalFree(void *p, InternalAllocatorCache *cache = nullptr);\nInternalAllocator *internal_allocator();\n\nenum InternalAllocEnum {\n  INTERNAL_ALLOC\n};\n\n} // namespace __sanitizer\n\ninline void *operator new(__sanitizer::operator_new_size_type size,\n                          InternalAllocEnum) {\n  return InternalAlloc(size);\n}\n\n#endif // SANITIZER_ALLOCATOR_INTERNAL_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_asm.h",
    "content": "//===-- sanitizer_asm.h -----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Various support for assemebler.\n//\n//===----------------------------------------------------------------------===//\n\n// Some toolchains do not support .cfi asm directives, so we have to hide\n// them inside macros.\n#if defined(__clang__) ||                                                      \\\n    (defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM))\n  // GCC defined __GCC_HAVE_DWARF2_CFI_ASM if it supports CFI.\n  // Clang seems to support CFI by default (or not?).\n  // We need two versions of macros: for inline asm and standalone asm files.\n# define CFI_INL_ADJUST_CFA_OFFSET(n) \".cfi_adjust_cfa_offset \" #n \";\"\n\n# define CFI_STARTPROC .cfi_startproc\n# define CFI_ENDPROC .cfi_endproc\n# define CFI_ADJUST_CFA_OFFSET(n) .cfi_adjust_cfa_offset n\n# define CFI_DEF_CFA_OFFSET(n) .cfi_def_cfa_offset n\n# define CFI_REL_OFFSET(reg, n) .cfi_rel_offset reg, n\n# define CFI_OFFSET(reg, n) .cfi_offset reg, n\n# define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg\n# define CFI_DEF_CFA(reg, n) .cfi_def_cfa reg, n\n# define CFI_RESTORE(reg) .cfi_restore reg\n\n#else  // No CFI\n# define CFI_INL_ADJUST_CFA_OFFSET(n)\n# define CFI_STARTPROC\n# define CFI_ENDPROC\n# define CFI_ADJUST_CFA_OFFSET(n)\n# define CFI_DEF_CFA_OFFSET(n)\n# define CFI_REL_OFFSET(reg, n)\n# define CFI_OFFSET(reg, n)\n# define CFI_DEF_CFA_REGISTER(reg)\n# define CFI_DEF_CFA(reg, n)\n# define CFI_RESTORE(reg)\n#endif\n\n#if !defined(__APPLE__)\n# define ASM_HIDDEN(symbol) .hidden symbol\n# define ASM_TYPE_FUNCTION(symbol) .type symbol, @function\n# define ASM_SIZE(symbol) .size symbol, .-symbol\n# define ASM_TSAN_SYMBOL(symbol) symbol\n# define ASM_TSAN_SYMBOL_INTERCEPTOR(symbol) symbol\n#else\n# define ASM_HIDDEN(symbol)\n# define ASM_TYPE_FUNCTION(symbol)\n# define ASM_SIZE(symbol)\n# define ASM_TSAN_SYMBOL(symbol) _##symbol\n# define ASM_TSAN_SYMBOL_INTERCEPTOR(symbol) _wrap_##symbol\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_atomic.h",
    "content": "//===-- sanitizer_atomic.h --------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_ATOMIC_H\n#define SANITIZER_ATOMIC_H\n\n#include \"sanitizer_internal_defs.h\"\n\nnamespace __sanitizer {\n\nenum memory_order {\n  memory_order_relaxed = 1 << 0,\n  memory_order_consume = 1 << 1,\n  memory_order_acquire = 1 << 2,\n  memory_order_release = 1 << 3,\n  memory_order_acq_rel = 1 << 4,\n  memory_order_seq_cst = 1 << 5\n};\n\nstruct atomic_uint8_t {\n  typedef u8 Type;\n  volatile Type val_dont_use;\n};\n\nstruct atomic_uint16_t {\n  typedef u16 Type;\n  volatile Type val_dont_use;\n};\n\nstruct atomic_uint32_t {\n  typedef u32 Type;\n  volatile Type val_dont_use;\n};\n\nstruct atomic_uint64_t {\n  typedef u64 Type;\n  // On 32-bit platforms u64 is not necessary aligned on 8 bytes.\n  volatile ALIGNED(8) Type val_dont_use;\n};\n\nstruct atomic_uintptr_t {\n  typedef uptr Type;\n  volatile Type val_dont_use;\n};\n\n}  // namespace __sanitizer\n\n#if defined(__clang__) || defined(__GNUC__)\n# include \"sanitizer_atomic_clang.h\"\n#elif defined(_MSC_VER)\n# include \"sanitizer_atomic_msvc.h\"\n#else\n# error \"Unsupported compiler\"\n#endif\n\nnamespace __sanitizer {\n\n// Clutter-reducing helpers.\n\ntemplate<typename T>\nINLINE typename T::Type atomic_load_relaxed(const volatile T *a) {\n  return atomic_load(a, memory_order_relaxed);\n}\n\ntemplate<typename T>\nINLINE void atomic_store_relaxed(volatile T *a, typename T::Type v) {\n  atomic_store(a, v, memory_order_relaxed);\n}\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_ATOMIC_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h",
    "content": "//===-- sanitizer_atomic_clang.h --------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n// Not intended for direct inclusion. Include sanitizer_atomic.h.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_ATOMIC_CLANG_H\n#define SANITIZER_ATOMIC_CLANG_H\n\n#if defined(__i386__) || defined(__x86_64__)\n# include \"sanitizer_atomic_clang_x86.h\"\n#else\n# include \"sanitizer_atomic_clang_other.h\"\n#endif\n\nnamespace __sanitizer {\n\n// We would like to just use compiler builtin atomic operations\n// for loads and stores, but they are mostly broken in clang:\n// - they lead to vastly inefficient code generation\n// (http://llvm.org/bugs/show_bug.cgi?id=17281)\n// - 64-bit atomic operations are not implemented on x86_32\n// (http://llvm.org/bugs/show_bug.cgi?id=15034)\n// - they are not implemented on ARM\n// error: undefined reference to '__atomic_load_4'\n\n// See http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html\n// for mappings of the memory model to different processors.\n\nINLINE void atomic_signal_fence(memory_order) {\n  __asm__ __volatile__(\"\" ::: \"memory\");\n}\n\nINLINE void atomic_thread_fence(memory_order) {\n  __sync_synchronize();\n}\n\ntemplate<typename T>\nINLINE typename T::Type atomic_fetch_add(volatile T *a,\n    typename T::Type v, memory_order mo) {\n  (void)mo;\n  DCHECK(!((uptr)a % sizeof(*a)));\n  return __sync_fetch_and_add(&a->val_dont_use, v);\n}\n\ntemplate<typename T>\nINLINE typename T::Type atomic_fetch_sub(volatile T *a,\n    typename T::Type v, memory_order mo) {\n  (void)mo;\n  DCHECK(!((uptr)a % sizeof(*a)));\n  return __sync_fetch_and_add(&a->val_dont_use, -v);\n}\n\ntemplate<typename T>\nINLINE typename T::Type atomic_exchange(volatile T *a,\n    typename T::Type v, memory_order mo) {\n  DCHECK(!((uptr)a % sizeof(*a)));\n  if (mo & (memory_order_release | memory_order_acq_rel | memory_order_seq_cst))\n    __sync_synchronize();\n  v = __sync_lock_test_and_set(&a->val_dont_use, v);\n  if (mo == memory_order_seq_cst)\n    __sync_synchronize();\n  return v;\n}\n\ntemplate<typename T>\nINLINE bool atomic_compare_exchange_strong(volatile T *a,\n                                           typename T::Type *cmp,\n                                           typename T::Type xchg,\n                                           memory_order mo) {\n  typedef typename T::Type Type;\n  Type cmpv = *cmp;\n  Type prev = __sync_val_compare_and_swap(&a->val_dont_use, cmpv, xchg);\n  if (prev == cmpv)\n    return true;\n  *cmp = prev;\n  return false;\n}\n\ntemplate<typename T>\nINLINE bool atomic_compare_exchange_weak(volatile T *a,\n                                         typename T::Type *cmp,\n                                         typename T::Type xchg,\n                                         memory_order mo) {\n  return atomic_compare_exchange_strong(a, cmp, xchg, mo);\n}\n\n}  // namespace __sanitizer\n\n#undef ATOMIC_ORDER\n\n#endif  // SANITIZER_ATOMIC_CLANG_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang_other.h",
    "content": "//===-- sanitizer_atomic_clang_other.h --------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n// Not intended for direct inclusion. Include sanitizer_atomic.h.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_ATOMIC_CLANG_OTHER_H\n#define SANITIZER_ATOMIC_CLANG_OTHER_H\n\nnamespace __sanitizer {\n\nINLINE void proc_yield(int cnt) {\n  __asm__ __volatile__(\"\" ::: \"memory\");\n}\n\ntemplate<typename T>\nINLINE typename T::Type atomic_load(\n    const volatile T *a, memory_order mo) {\n  DCHECK(mo & (memory_order_relaxed | memory_order_consume\n      | memory_order_acquire | memory_order_seq_cst));\n  DCHECK(!((uptr)a % sizeof(*a)));\n  typename T::Type v;\n\n  if (sizeof(*a) < 8 || sizeof(void*) == 8) {\n    // Assume that aligned loads are atomic.\n    if (mo == memory_order_relaxed) {\n      v = a->val_dont_use;\n    } else if (mo == memory_order_consume) {\n      // Assume that processor respects data dependencies\n      // (and that compiler won't break them).\n      __asm__ __volatile__(\"\" ::: \"memory\");\n      v = a->val_dont_use;\n      __asm__ __volatile__(\"\" ::: \"memory\");\n    } else if (mo == memory_order_acquire) {\n      __asm__ __volatile__(\"\" ::: \"memory\");\n      v = a->val_dont_use;\n      __sync_synchronize();\n    } else {  // seq_cst\n      // E.g. on POWER we need a hw fence even before the store.\n      __sync_synchronize();\n      v = a->val_dont_use;\n      __sync_synchronize();\n    }\n  } else {\n    // 64-bit load on 32-bit platform.\n    // Gross, but simple and reliable.\n    // Assume that it is not in read-only memory.\n    v = __sync_fetch_and_add(\n        const_cast<typename T::Type volatile *>(&a->val_dont_use), 0);\n  }\n  return v;\n}\n\ntemplate<typename T>\nINLINE void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {\n  DCHECK(mo & (memory_order_relaxed | memory_order_release\n      | memory_order_seq_cst));\n  DCHECK(!((uptr)a % sizeof(*a)));\n\n  if (sizeof(*a) < 8 || sizeof(void*) == 8) {\n    // Assume that aligned loads are atomic.\n    if (mo == memory_order_relaxed) {\n      a->val_dont_use = v;\n    } else if (mo == memory_order_release) {\n      __sync_synchronize();\n      a->val_dont_use = v;\n      __asm__ __volatile__(\"\" ::: \"memory\");\n    } else {  // seq_cst\n      __sync_synchronize();\n      a->val_dont_use = v;\n      __sync_synchronize();\n    }\n  } else {\n    // 64-bit store on 32-bit platform.\n    // Gross, but simple and reliable.\n    typename T::Type cmp = a->val_dont_use;\n    typename T::Type cur;\n    for (;;) {\n      cur = __sync_val_compare_and_swap(&a->val_dont_use, cmp, v);\n      if (cmp == v)\n        break;\n      cmp = cur;\n    }\n  }\n}\n\n}  // namespace __sanitizer\n\n#endif  // #ifndef SANITIZER_ATOMIC_CLANG_OTHER_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang_x86.h",
    "content": "//===-- sanitizer_atomic_clang_x86.h ----------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n// Not intended for direct inclusion. Include sanitizer_atomic.h.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_ATOMIC_CLANG_X86_H\n#define SANITIZER_ATOMIC_CLANG_X86_H\n\nnamespace __sanitizer {\n\nINLINE void proc_yield(int cnt) {\n  __asm__ __volatile__(\"\" ::: \"memory\");\n  for (int i = 0; i < cnt; i++)\n    __asm__ __volatile__(\"pause\");\n  __asm__ __volatile__(\"\" ::: \"memory\");\n}\n\ntemplate<typename T>\nINLINE typename T::Type atomic_load(\n    const volatile T *a, memory_order mo) {\n  DCHECK(mo & (memory_order_relaxed | memory_order_consume\n      | memory_order_acquire | memory_order_seq_cst));\n  DCHECK(!((uptr)a % sizeof(*a)));\n  typename T::Type v;\n\n  if (sizeof(*a) < 8 || sizeof(void*) == 8) {\n    // Assume that aligned loads are atomic.\n    if (mo == memory_order_relaxed) {\n      v = a->val_dont_use;\n    } else if (mo == memory_order_consume) {\n      // Assume that processor respects data dependencies\n      // (and that compiler won't break them).\n      __asm__ __volatile__(\"\" ::: \"memory\");\n      v = a->val_dont_use;\n      __asm__ __volatile__(\"\" ::: \"memory\");\n    } else if (mo == memory_order_acquire) {\n      __asm__ __volatile__(\"\" ::: \"memory\");\n      v = a->val_dont_use;\n      // On x86 loads are implicitly acquire.\n      __asm__ __volatile__(\"\" ::: \"memory\");\n    } else {  // seq_cst\n      // On x86 plain MOV is enough for seq_cst store.\n      __asm__ __volatile__(\"\" ::: \"memory\");\n      v = a->val_dont_use;\n      __asm__ __volatile__(\"\" ::: \"memory\");\n    }\n  } else {\n    // 64-bit load on 32-bit platform.\n    __asm__ __volatile__(\n        \"movq %1, %%mm0;\"  // Use mmx reg for 64-bit atomic moves\n        \"movq %%mm0, %0;\"  // (ptr could be read-only)\n        \"emms;\"            // Empty mmx state/Reset FP regs\n        : \"=m\" (v)\n        : \"m\" (a->val_dont_use)\n        : // mark the FP stack and mmx registers as clobbered\n          \"st\", \"st(1)\", \"st(2)\", \"st(3)\", \"st(4)\", \"st(5)\", \"st(6)\", \"st(7)\",\n#ifdef __MMX__\n          \"mm0\", \"mm1\", \"mm2\", \"mm3\", \"mm4\", \"mm5\", \"mm6\", \"mm7\",\n#endif  // #ifdef __MMX__\n          \"memory\");\n  }\n  return v;\n}\n\ntemplate<typename T>\nINLINE void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {\n  DCHECK(mo & (memory_order_relaxed | memory_order_release\n      | memory_order_seq_cst));\n  DCHECK(!((uptr)a % sizeof(*a)));\n\n  if (sizeof(*a) < 8 || sizeof(void*) == 8) {\n    // Assume that aligned loads are atomic.\n    if (mo == memory_order_relaxed) {\n      a->val_dont_use = v;\n    } else if (mo == memory_order_release) {\n      // On x86 stores are implicitly release.\n      __asm__ __volatile__(\"\" ::: \"memory\");\n      a->val_dont_use = v;\n      __asm__ __volatile__(\"\" ::: \"memory\");\n    } else {  // seq_cst\n      // On x86 stores are implicitly release.\n      __asm__ __volatile__(\"\" ::: \"memory\");\n      a->val_dont_use = v;\n      __sync_synchronize();\n    }\n  } else {\n    // 64-bit store on 32-bit platform.\n    __asm__ __volatile__(\n        \"movq %1, %%mm0;\"  // Use mmx reg for 64-bit atomic moves\n        \"movq %%mm0, %0;\"\n        \"emms;\"            // Empty mmx state/Reset FP regs\n        : \"=m\" (a->val_dont_use)\n        : \"m\" (v)\n        : // mark the FP stack and mmx registers as clobbered\n          \"st\", \"st(1)\", \"st(2)\", \"st(3)\", \"st(4)\", \"st(5)\", \"st(6)\", \"st(7)\",\n#ifdef __MMX__\n          \"mm0\", \"mm1\", \"mm2\", \"mm3\", \"mm4\", \"mm5\", \"mm6\", \"mm7\",\n#endif  // #ifdef __MMX__\n          \"memory\");\n    if (mo == memory_order_seq_cst)\n      __sync_synchronize();\n  }\n}\n\n}  // namespace __sanitizer\n\n#endif  // #ifndef SANITIZER_ATOMIC_CLANG_X86_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_atomic_msvc.h",
    "content": "//===-- sanitizer_atomic_msvc.h ---------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n// Not intended for direct inclusion. Include sanitizer_atomic.h.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_ATOMIC_MSVC_H\n#define SANITIZER_ATOMIC_MSVC_H\n\nextern \"C\" void _ReadWriteBarrier();\n#pragma intrinsic(_ReadWriteBarrier)\nextern \"C\" void _mm_mfence();\n#pragma intrinsic(_mm_mfence)\nextern \"C\" void _mm_pause();\n#pragma intrinsic(_mm_pause)\nextern \"C\" char _InterlockedExchange8(   // NOLINT\n    char volatile *Addend, char Value);  // NOLINT\n#pragma intrinsic(_InterlockedExchange8)\nextern \"C\" short _InterlockedExchange16(   // NOLINT\n    short volatile *Addend, short Value);  // NOLINT\n#pragma intrinsic(_InterlockedExchange16)\nextern \"C\" long _InterlockedExchange(    // NOLINT\n    long volatile *Addend, long Value);  // NOLINT\n#pragma intrinsic(_InterlockedExchange)\nextern \"C\" long _InterlockedExchangeAdd(  // NOLINT\n    long volatile * Addend, long Value);  // NOLINT\n#pragma intrinsic(_InterlockedExchangeAdd)\nextern \"C\" short _InterlockedCompareExchange16(  // NOLINT\n    short volatile *Destination,                 // NOLINT\n    short Exchange, short Comparand);            // NOLINT\n#pragma intrinsic(_InterlockedCompareExchange16)\nextern \"C\"\nlong long _InterlockedCompareExchange64(  // NOLINT\n    long long volatile *Destination,              // NOLINT\n    long long Exchange, long long Comparand);     // NOLINT\n#pragma intrinsic(_InterlockedCompareExchange64)\nextern \"C\" void *_InterlockedCompareExchangePointer(\n    void *volatile *Destination,\n    void *Exchange, void *Comparand);\n#pragma intrinsic(_InterlockedCompareExchangePointer)\nextern \"C\"\nlong __cdecl _InterlockedCompareExchange(  // NOLINT\n    long volatile *Destination,            // NOLINT\n    long Exchange, long Comparand);        // NOLINT\n#pragma intrinsic(_InterlockedCompareExchange)\n\n#ifdef _WIN64\nextern \"C\" long long _InterlockedExchangeAdd64(     // NOLINT\n    long long volatile * Addend, long long Value);  // NOLINT\n#pragma intrinsic(_InterlockedExchangeAdd64)\n#endif\n\nnamespace __sanitizer {\n\nINLINE void atomic_signal_fence(memory_order) {\n  _ReadWriteBarrier();\n}\n\nINLINE void atomic_thread_fence(memory_order) {\n  _mm_mfence();\n}\n\nINLINE void proc_yield(int cnt) {\n  for (int i = 0; i < cnt; i++)\n    _mm_pause();\n}\n\ntemplate<typename T>\nINLINE typename T::Type atomic_load(\n    const volatile T *a, memory_order mo) {\n  DCHECK(mo & (memory_order_relaxed | memory_order_consume\n      | memory_order_acquire | memory_order_seq_cst));\n  DCHECK(!((uptr)a % sizeof(*a)));\n  typename T::Type v;\n  // FIXME(dvyukov): 64-bit load is not atomic on 32-bits.\n  if (mo == memory_order_relaxed) {\n    v = a->val_dont_use;\n  } else {\n    atomic_signal_fence(memory_order_seq_cst);\n    v = a->val_dont_use;\n    atomic_signal_fence(memory_order_seq_cst);\n  }\n  return v;\n}\n\ntemplate<typename T>\nINLINE void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {\n  DCHECK(mo & (memory_order_relaxed | memory_order_release\n      | memory_order_seq_cst));\n  DCHECK(!((uptr)a % sizeof(*a)));\n  // FIXME(dvyukov): 64-bit store is not atomic on 32-bits.\n  if (mo == memory_order_relaxed) {\n    a->val_dont_use = v;\n  } else {\n    atomic_signal_fence(memory_order_seq_cst);\n    a->val_dont_use = v;\n    atomic_signal_fence(memory_order_seq_cst);\n  }\n  if (mo == memory_order_seq_cst)\n    atomic_thread_fence(memory_order_seq_cst);\n}\n\nINLINE u32 atomic_fetch_add(volatile atomic_uint32_t *a,\n    u32 v, memory_order mo) {\n  (void)mo;\n  DCHECK(!((uptr)a % sizeof(*a)));\n  return (u32)_InterlockedExchangeAdd(\n      (volatile long*)&a->val_dont_use, (long)v);  // NOLINT\n}\n\nINLINE uptr atomic_fetch_add(volatile atomic_uintptr_t *a,\n    uptr v, memory_order mo) {\n  (void)mo;\n  DCHECK(!((uptr)a % sizeof(*a)));\n#ifdef _WIN64\n  return (uptr)_InterlockedExchangeAdd64(\n      (volatile long long*)&a->val_dont_use, (long long)v);  // NOLINT\n#else\n  return (uptr)_InterlockedExchangeAdd(\n      (volatile long*)&a->val_dont_use, (long)v);  // NOLINT\n#endif\n}\n\nINLINE u32 atomic_fetch_sub(volatile atomic_uint32_t *a,\n    u32 v, memory_order mo) {\n  (void)mo;\n  DCHECK(!((uptr)a % sizeof(*a)));\n  return (u32)_InterlockedExchangeAdd(\n      (volatile long*)&a->val_dont_use, -(long)v);  // NOLINT\n}\n\nINLINE uptr atomic_fetch_sub(volatile atomic_uintptr_t *a,\n    uptr v, memory_order mo) {\n  (void)mo;\n  DCHECK(!((uptr)a % sizeof(*a)));\n#ifdef _WIN64\n  return (uptr)_InterlockedExchangeAdd64(\n      (volatile long long*)&a->val_dont_use, -(long long)v);  // NOLINT\n#else\n  return (uptr)_InterlockedExchangeAdd(\n      (volatile long*)&a->val_dont_use, -(long)v);  // NOLINT\n#endif\n}\n\nINLINE u8 atomic_exchange(volatile atomic_uint8_t *a,\n    u8 v, memory_order mo) {\n  (void)mo;\n  DCHECK(!((uptr)a % sizeof(*a)));\n  return (u8)_InterlockedExchange8((volatile char*)&a->val_dont_use, v);\n}\n\nINLINE u16 atomic_exchange(volatile atomic_uint16_t *a,\n    u16 v, memory_order mo) {\n  (void)mo;\n  DCHECK(!((uptr)a % sizeof(*a)));\n  return (u16)_InterlockedExchange16((volatile short*)&a->val_dont_use, v);\n}\n\nINLINE u32 atomic_exchange(volatile atomic_uint32_t *a,\n    u32 v, memory_order mo) {\n  (void)mo;\n  DCHECK(!((uptr)a % sizeof(*a)));\n  return (u32)_InterlockedExchange((volatile long*)&a->val_dont_use, v);\n}\n\n#ifndef _WIN64\n\nINLINE bool atomic_compare_exchange_strong(volatile atomic_uint8_t *a,\n                                           u8 *cmp,\n                                           u8 xchgv,\n                                           memory_order mo) {\n  (void)mo;\n  DCHECK(!((uptr)a % sizeof(*a)));\n  u8 cmpv = *cmp;\n  u8 prev;\n  __asm {\n    mov al, cmpv\n    mov ecx, a\n    mov dl, xchgv\n    lock cmpxchg [ecx], dl\n    mov prev, al\n  }\n  if (prev == cmpv)\n    return true;\n  *cmp = prev;\n  return false;\n}\n\n#endif\n\nINLINE bool atomic_compare_exchange_strong(volatile atomic_uintptr_t *a,\n                                           uptr *cmp,\n                                           uptr xchg,\n                                           memory_order mo) {\n  uptr cmpv = *cmp;\n  uptr prev = (uptr)_InterlockedCompareExchangePointer(\n      (void*volatile*)&a->val_dont_use, (void*)xchg, (void*)cmpv);\n  if (prev == cmpv)\n    return true;\n  *cmp = prev;\n  return false;\n}\n\nINLINE bool atomic_compare_exchange_strong(volatile atomic_uint16_t *a,\n                                           u16 *cmp,\n                                           u16 xchg,\n                                           memory_order mo) {\n  u16 cmpv = *cmp;\n  u16 prev = (u16)_InterlockedCompareExchange16(\n      (volatile short*)&a->val_dont_use, (short)xchg, (short)cmpv);\n  if (prev == cmpv)\n    return true;\n  *cmp = prev;\n  return false;\n}\n\nINLINE bool atomic_compare_exchange_strong(volatile atomic_uint32_t *a,\n                                           u32 *cmp,\n                                           u32 xchg,\n                                           memory_order mo) {\n  u32 cmpv = *cmp;\n  u32 prev = (u32)_InterlockedCompareExchange(\n      (volatile long*)&a->val_dont_use, (long)xchg, (long)cmpv);\n  if (prev == cmpv)\n    return true;\n  *cmp = prev;\n  return false;\n}\n\nINLINE bool atomic_compare_exchange_strong(volatile atomic_uint64_t *a,\n                                           u64 *cmp,\n                                           u64 xchg,\n                                           memory_order mo) {\n  u64 cmpv = *cmp;\n  u64 prev = (u64)_InterlockedCompareExchange64(\n      (volatile long long*)&a->val_dont_use, (long long)xchg, (long long)cmpv);\n  if (prev == cmpv)\n    return true;\n  *cmp = prev;\n  return false;\n}\n\ntemplate<typename T>\nINLINE bool atomic_compare_exchange_weak(volatile T *a,\n                                         typename T::Type *cmp,\n                                         typename T::Type xchg,\n                                         memory_order mo) {\n  return atomic_compare_exchange_strong(a, cmp, xchg, mo);\n}\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_ATOMIC_CLANG_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_bitvector.h",
    "content": "//===-- sanitizer_bitvector.h -----------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Specializer BitVector implementation.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_BITVECTOR_H\n#define SANITIZER_BITVECTOR_H\n\n#include \"sanitizer_common.h\"\n\nnamespace __sanitizer {\n\n// Fixed size bit vector based on a single basic integer.\ntemplate <class basic_int_t = uptr>\nclass BasicBitVector {\n public:\n  enum SizeEnum { kSize = sizeof(basic_int_t) * 8 };\n\n  uptr size() const { return kSize; }\n  // No CTOR.\n  void clear() { bits_ = 0; }\n  void setAll() { bits_ = ~(basic_int_t)0; }\n  bool empty() const { return bits_ == 0; }\n\n  // Returns true if the bit has changed from 0 to 1.\n  bool setBit(uptr idx) {\n    basic_int_t old = bits_;\n    bits_ |= mask(idx);\n    return bits_ != old;\n  }\n\n  // Returns true if the bit has changed from 1 to 0.\n  bool clearBit(uptr idx) {\n    basic_int_t old = bits_;\n    bits_ &= ~mask(idx);\n    return bits_ != old;\n  }\n\n  bool getBit(uptr idx) const { return (bits_ & mask(idx)) != 0; }\n\n  uptr getAndClearFirstOne() {\n    CHECK(!empty());\n    uptr idx = LeastSignificantSetBitIndex(bits_);\n    clearBit(idx);\n    return idx;\n  }\n\n  // Do \"this |= v\" and return whether new bits have been added.\n  bool setUnion(const BasicBitVector &v) {\n    basic_int_t old = bits_;\n    bits_ |= v.bits_;\n    return bits_ != old;\n  }\n\n  // Do \"this &= v\" and return whether any bits have been removed.\n  bool setIntersection(const BasicBitVector &v) {\n    basic_int_t old = bits_;\n    bits_ &= v.bits_;\n    return bits_ != old;\n  }\n\n  // Do \"this &= ~v\" and return whether any bits have been removed.\n  bool setDifference(const BasicBitVector &v) {\n    basic_int_t old = bits_;\n    bits_ &= ~v.bits_;\n    return bits_ != old;\n  }\n\n  void copyFrom(const BasicBitVector &v) { bits_ = v.bits_; }\n\n  // Returns true if 'this' intersects with 'v'.\n  bool intersectsWith(const BasicBitVector &v) const {\n    return (bits_ & v.bits_) != 0;\n  }\n\n  // for (BasicBitVector<>::Iterator it(bv); it.hasNext();) {\n  //   uptr idx = it.next();\n  //   use(idx);\n  // }\n  class Iterator {\n   public:\n    Iterator() { }\n    explicit Iterator(const BasicBitVector &bv) : bv_(bv) {}\n    bool hasNext() const { return !bv_.empty(); }\n    uptr next() { return bv_.getAndClearFirstOne(); }\n    void clear() { bv_.clear(); }\n   private:\n    BasicBitVector bv_;\n  };\n\n private:\n  basic_int_t mask(uptr idx) const {\n    CHECK_LT(idx, size());\n    return (basic_int_t)1UL << idx;\n  }\n  basic_int_t bits_;\n};\n\n// Fixed size bit vector of (kLevel1Size*BV::kSize**2) bits.\n// The implementation is optimized for better performance on\n// sparse bit vectors, i.e. the those with few set bits.\ntemplate <uptr kLevel1Size = 1, class BV = BasicBitVector<> >\nclass TwoLevelBitVector {\n  // This is essentially a 2-level bit vector.\n  // Set bit in the first level BV indicates that there are set bits\n  // in the corresponding BV of the second level.\n  // This structure allows O(kLevel1Size) time for clear() and empty(),\n  // as well fast handling of sparse BVs.\n public:\n  enum SizeEnum { kSize = BV::kSize * BV::kSize * kLevel1Size };\n  // No CTOR.\n\n  uptr size() const { return kSize; }\n\n  void clear() {\n    for (uptr i = 0; i < kLevel1Size; i++)\n      l1_[i].clear();\n  }\n\n  void setAll() {\n    for (uptr i0 = 0; i0 < kLevel1Size; i0++) {\n      l1_[i0].setAll();\n      for (uptr i1 = 0; i1 < BV::kSize; i1++)\n        l2_[i0][i1].setAll();\n    }\n  }\n\n  bool empty() const {\n    for (uptr i = 0; i < kLevel1Size; i++)\n      if (!l1_[i].empty())\n        return false;\n    return true;\n  }\n\n  // Returns true if the bit has changed from 0 to 1.\n  bool setBit(uptr idx) {\n    check(idx);\n    uptr i0 = idx0(idx);\n    uptr i1 = idx1(idx);\n    uptr i2 = idx2(idx);\n    if (!l1_[i0].getBit(i1)) {\n      l1_[i0].setBit(i1);\n      l2_[i0][i1].clear();\n    }\n    bool res = l2_[i0][i1].setBit(i2);\n    // Printf(\"%s: %zd => %zd %zd %zd; %d\\n\", __func__,\n    // idx, i0, i1, i2, res);\n    return res;\n  }\n\n  bool clearBit(uptr idx) {\n    check(idx);\n    uptr i0 = idx0(idx);\n    uptr i1 = idx1(idx);\n    uptr i2 = idx2(idx);\n    bool res = false;\n    if (l1_[i0].getBit(i1)) {\n      res = l2_[i0][i1].clearBit(i2);\n      if (l2_[i0][i1].empty())\n        l1_[i0].clearBit(i1);\n    }\n    return res;\n  }\n\n  bool getBit(uptr idx) const {\n    check(idx);\n    uptr i0 = idx0(idx);\n    uptr i1 = idx1(idx);\n    uptr i2 = idx2(idx);\n    // Printf(\"%s: %zd => %zd %zd %zd\\n\", __func__, idx, i0, i1, i2);\n    return l1_[i0].getBit(i1) && l2_[i0][i1].getBit(i2);\n  }\n\n  uptr getAndClearFirstOne() {\n    for (uptr i0 = 0; i0 < kLevel1Size; i0++) {\n      if (l1_[i0].empty()) continue;\n      uptr i1 = l1_[i0].getAndClearFirstOne();\n      uptr i2 = l2_[i0][i1].getAndClearFirstOne();\n      if (!l2_[i0][i1].empty())\n        l1_[i0].setBit(i1);\n      uptr res = i0 * BV::kSize * BV::kSize + i1 * BV::kSize + i2;\n      // Printf(\"getAndClearFirstOne: %zd %zd %zd => %zd\\n\", i0, i1, i2, res);\n      return res;\n    }\n    CHECK(0);\n    return 0;\n  }\n\n  // Do \"this |= v\" and return whether new bits have been added.\n  bool setUnion(const TwoLevelBitVector &v) {\n    bool res = false;\n    for (uptr i0 = 0; i0 < kLevel1Size; i0++) {\n      BV t = v.l1_[i0];\n      while (!t.empty()) {\n        uptr i1 = t.getAndClearFirstOne();\n        if (l1_[i0].setBit(i1))\n          l2_[i0][i1].clear();\n        if (l2_[i0][i1].setUnion(v.l2_[i0][i1]))\n          res = true;\n      }\n    }\n    return res;\n  }\n\n  // Do \"this &= v\" and return whether any bits have been removed.\n  bool setIntersection(const TwoLevelBitVector &v) {\n    bool res = false;\n    for (uptr i0 = 0; i0 < kLevel1Size; i0++) {\n      if (l1_[i0].setIntersection(v.l1_[i0]))\n        res = true;\n      if (!l1_[i0].empty()) {\n        BV t = l1_[i0];\n        while (!t.empty()) {\n          uptr i1 = t.getAndClearFirstOne();\n          if (l2_[i0][i1].setIntersection(v.l2_[i0][i1]))\n            res = true;\n          if (l2_[i0][i1].empty())\n            l1_[i0].clearBit(i1);\n        }\n      }\n    }\n    return res;\n  }\n\n  // Do \"this &= ~v\" and return whether any bits have been removed.\n  bool setDifference(const TwoLevelBitVector &v) {\n    bool res = false;\n    for (uptr i0 = 0; i0 < kLevel1Size; i0++) {\n      BV t = l1_[i0];\n      t.setIntersection(v.l1_[i0]);\n      while (!t.empty()) {\n        uptr i1 = t.getAndClearFirstOne();\n        if (l2_[i0][i1].setDifference(v.l2_[i0][i1]))\n          res = true;\n        if (l2_[i0][i1].empty())\n          l1_[i0].clearBit(i1);\n      }\n    }\n    return res;\n  }\n\n  void copyFrom(const TwoLevelBitVector &v) {\n    clear();\n    setUnion(v);\n  }\n\n  // Returns true if 'this' intersects with 'v'.\n  bool intersectsWith(const TwoLevelBitVector &v) const {\n    for (uptr i0 = 0; i0 < kLevel1Size; i0++) {\n      BV t = l1_[i0];\n      t.setIntersection(v.l1_[i0]);\n      while (!t.empty()) {\n        uptr i1 = t.getAndClearFirstOne();\n        if (!v.l1_[i0].getBit(i1)) continue;\n        if (l2_[i0][i1].intersectsWith(v.l2_[i0][i1]))\n          return true;\n      }\n    }\n    return false;\n  }\n\n  // for (TwoLevelBitVector<>::Iterator it(bv); it.hasNext();) {\n  //   uptr idx = it.next();\n  //   use(idx);\n  // }\n  class Iterator {\n   public:\n    Iterator() { }\n    explicit Iterator(const TwoLevelBitVector &bv) : bv_(bv), i0_(0), i1_(0) {\n      it1_.clear();\n      it2_.clear();\n    }\n\n    bool hasNext() const {\n      if (it1_.hasNext()) return true;\n      for (uptr i = i0_; i < kLevel1Size; i++)\n        if (!bv_.l1_[i].empty()) return true;\n      return false;\n    }\n\n    uptr next() {\n      // Printf(\"++++: %zd %zd; %d %d; size %zd\\n\", i0_, i1_, it1_.hasNext(),\n      //       it2_.hasNext(), kSize);\n      if (!it1_.hasNext() && !it2_.hasNext()) {\n        for (; i0_ < kLevel1Size; i0_++) {\n          if (bv_.l1_[i0_].empty()) continue;\n          it1_ = typename BV::Iterator(bv_.l1_[i0_]);\n          // Printf(\"+i0: %zd %zd; %d %d; size %zd\\n\", i0_, i1_, it1_.hasNext(),\n          //   it2_.hasNext(), kSize);\n          break;\n        }\n      }\n      if (!it2_.hasNext()) {\n        CHECK(it1_.hasNext());\n        i1_ = it1_.next();\n        it2_ = typename BV::Iterator(bv_.l2_[i0_][i1_]);\n        // Printf(\"++i1: %zd %zd; %d %d; size %zd\\n\", i0_, i1_, it1_.hasNext(),\n        //       it2_.hasNext(), kSize);\n      }\n      CHECK(it2_.hasNext());\n      uptr i2 = it2_.next();\n      uptr res = i0_ * BV::kSize * BV::kSize + i1_ * BV::kSize + i2;\n      // Printf(\"+ret: %zd %zd; %d %d; size %zd; res: %zd\\n\", i0_, i1_,\n      //       it1_.hasNext(), it2_.hasNext(), kSize, res);\n      if (!it1_.hasNext() && !it2_.hasNext())\n        i0_++;\n      return res;\n    }\n\n   private:\n    const TwoLevelBitVector &bv_;\n    uptr i0_, i1_;\n    typename BV::Iterator it1_, it2_;\n  };\n\n private:\n  void check(uptr idx) const { CHECK_LE(idx, size()); }\n\n  uptr idx0(uptr idx) const {\n    uptr res = idx / (BV::kSize * BV::kSize);\n    CHECK_LE(res, kLevel1Size);\n    return res;\n  }\n\n  uptr idx1(uptr idx) const {\n    uptr res = (idx / BV::kSize) % BV::kSize;\n    CHECK_LE(res, BV::kSize);\n    return res;\n  }\n\n  uptr idx2(uptr idx) const {\n    uptr res = idx % BV::kSize;\n    CHECK_LE(res, BV::kSize);\n    return res;\n  }\n\n  BV l1_[kLevel1Size];\n  BV l2_[kLevel1Size][BV::kSize];\n};\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_BITVECTOR_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_bvgraph.h",
    "content": "//===-- sanitizer_bvgraph.h -------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of Sanitizer runtime.\n// BVGraph -- a directed graph.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_BVGRAPH_H\n#define SANITIZER_BVGRAPH_H\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_bitvector.h\"\n\nnamespace __sanitizer {\n\n// Directed graph of fixed size implemented as an array of bit vectors.\n// Not thread-safe, all accesses should be protected by an external lock.\ntemplate<class BV>\nclass BVGraph {\n public:\n  enum SizeEnum { kSize = BV::kSize };\n  uptr size() const { return kSize; }\n  // No CTOR.\n  void clear() {\n    for (uptr i = 0; i < size(); i++)\n      v[i].clear();\n  }\n\n  bool empty() const {\n    for (uptr i = 0; i < size(); i++)\n      if (!v[i].empty())\n        return false;\n    return true;\n  }\n\n  // Returns true if a new edge was added.\n  bool addEdge(uptr from, uptr to) {\n    check(from, to);\n    return v[from].setBit(to);\n  }\n\n  // Returns true if at least one new edge was added.\n  uptr addEdges(const BV &from, uptr to, uptr added_edges[],\n                uptr max_added_edges) {\n    uptr res = 0;\n    t1.copyFrom(from);\n    while (!t1.empty()) {\n      uptr node = t1.getAndClearFirstOne();\n      if (v[node].setBit(to))\n        if (res < max_added_edges)\n          added_edges[res++] = node;\n    }\n    return res;\n  }\n\n  // *EXPERIMENTAL*\n  // Returns true if an edge from=>to exist.\n  // This function does not use any global state except for 'this' itself,\n  // and thus can be called from different threads w/o locking.\n  // This would be racy.\n  // FIXME: investigate how much we can prove about this race being \"benign\".\n  bool hasEdge(uptr from, uptr to) { return v[from].getBit(to); }\n\n  // Returns true if the edge from=>to was removed.\n  bool removeEdge(uptr from, uptr to) {\n    return v[from].clearBit(to);\n  }\n\n  // Returns true if at least one edge *=>to was removed.\n  bool removeEdgesTo(const BV &to) {\n    bool res = 0;\n    for (uptr from = 0; from < size(); from++) {\n      if (v[from].setDifference(to))\n        res = true;\n    }\n    return res;\n  }\n\n  // Returns true if at least one edge from=>* was removed.\n  bool removeEdgesFrom(const BV &from) {\n    bool res = false;\n    t1.copyFrom(from);\n    while (!t1.empty()) {\n      uptr idx = t1.getAndClearFirstOne();\n      if (!v[idx].empty()) {\n        v[idx].clear();\n        res = true;\n      }\n    }\n    return res;\n  }\n\n  void removeEdgesFrom(uptr from) {\n    return v[from].clear();\n  }\n\n  bool hasEdge(uptr from, uptr to) const {\n    check(from, to);\n    return v[from].getBit(to);\n  }\n\n  // Returns true if there is a path from the node 'from'\n  // to any of the nodes in 'targets'.\n  bool isReachable(uptr from, const BV &targets) {\n    BV &to_visit = t1,\n       &visited = t2;\n    to_visit.copyFrom(v[from]);\n    visited.clear();\n    visited.setBit(from);\n    while (!to_visit.empty()) {\n      uptr idx = to_visit.getAndClearFirstOne();\n      if (visited.setBit(idx))\n        to_visit.setUnion(v[idx]);\n    }\n    return targets.intersectsWith(visited);\n  }\n\n  // Finds a path from 'from' to one of the nodes in 'target',\n  // stores up to 'path_size' items of the path into 'path',\n  // returns the path length, or 0 if there is no path of size 'path_size'.\n  uptr findPath(uptr from, const BV &targets, uptr *path, uptr path_size) {\n    if (path_size == 0)\n      return 0;\n    path[0] = from;\n    if (targets.getBit(from))\n      return 1;\n    // The function is recursive, so we don't want to create BV on stack.\n    // Instead of a getAndClearFirstOne loop we use the slower iterator.\n    for (typename BV::Iterator it(v[from]); it.hasNext(); ) {\n      uptr idx = it.next();\n      if (uptr res = findPath(idx, targets, path + 1, path_size - 1))\n        return res + 1;\n    }\n    return 0;\n  }\n\n  // Same as findPath, but finds a shortest path.\n  uptr findShortestPath(uptr from, const BV &targets, uptr *path,\n                        uptr path_size) {\n    for (uptr p = 1; p <= path_size; p++)\n      if (findPath(from, targets, path, p) == p)\n        return p;\n    return 0;\n  }\n\n private:\n  void check(uptr idx1, uptr idx2) const {\n    CHECK_LT(idx1, size());\n    CHECK_LT(idx2, size());\n  }\n  BV v[kSize];\n  // Keep temporary vectors here since we can not create large objects on stack.\n  BV t1, t2;\n};\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_BVGRAPH_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_common.cc",
    "content": "//===-- sanitizer_common.cc -----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_allocator_internal.h\"\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_placement_new.h\"\n#include \"sanitizer_stacktrace_printer.h\"\n#include \"sanitizer_symbolizer.h\"\n\nnamespace __sanitizer {\n\nconst char *SanitizerToolName = \"SanitizerTool\";\n\natomic_uint32_t current_verbosity;\n\nuptr GetPageSizeCached() {\n  static uptr PageSize;\n  if (!PageSize)\n    PageSize = GetPageSize();\n  return PageSize;\n}\n\nStaticSpinMutex report_file_mu;\nReportFile report_file = {&report_file_mu, kStderrFd, \"\", \"\", 0};\n\nvoid RawWrite(const char *buffer) {\n  report_file.Write(buffer, internal_strlen(buffer));\n}\n\nvoid ReportFile::ReopenIfNecessary() {\n  mu->CheckLocked();\n  if (fd == kStdoutFd || fd == kStderrFd) return;\n\n  uptr pid = internal_getpid();\n  // If in tracer, use the parent's file.\n  if (pid == stoptheworld_tracer_pid)\n    pid = stoptheworld_tracer_ppid;\n  if (fd != kInvalidFd) {\n    // If the report file is already opened by the current process,\n    // do nothing. Otherwise the report file was opened by the parent\n    // process, close it now.\n    if (fd_pid == pid)\n      return;\n    else\n      CloseFile(fd);\n  }\n\n  const char *exe_name = GetProcessName();\n  if (common_flags()->log_exe_name && exe_name) {\n    internal_snprintf(full_path, kMaxPathLength, \"%s.%s.%zu\", path_prefix,\n                      exe_name, pid);\n  } else {\n    internal_snprintf(full_path, kMaxPathLength, \"%s.%zu\", path_prefix, pid);\n  }\n  fd = OpenFile(full_path, WrOnly);\n  if (fd == kInvalidFd) {\n    const char *ErrorMsgPrefix = \"ERROR: Can't open file: \";\n    WriteToFile(kStderrFd, ErrorMsgPrefix, internal_strlen(ErrorMsgPrefix));\n    WriteToFile(kStderrFd, full_path, internal_strlen(full_path));\n    Die();\n  }\n  fd_pid = pid;\n}\n\nvoid ReportFile::SetReportPath(const char *path) {\n  if (!path)\n    return;\n  uptr len = internal_strlen(path);\n  if (len > sizeof(path_prefix) - 100) {\n    Report(\"ERROR: Path is too long: %c%c%c%c%c%c%c%c...\\n\",\n           path[0], path[1], path[2], path[3],\n           path[4], path[5], path[6], path[7]);\n    Die();\n  }\n\n  SpinMutexLock l(mu);\n  if (fd != kStdoutFd && fd != kStderrFd && fd != kInvalidFd)\n    CloseFile(fd);\n  fd = kInvalidFd;\n  if (internal_strcmp(path, \"stdout\") == 0) {\n    fd = kStdoutFd;\n  } else if (internal_strcmp(path, \"stderr\") == 0) {\n    fd = kStderrFd;\n  } else {\n    internal_snprintf(path_prefix, kMaxPathLength, \"%s\", path);\n  }\n}\n\n// PID of the tracer task in StopTheWorld. It shares the address space with the\n// main process, but has a different PID and thus requires special handling.\nuptr stoptheworld_tracer_pid = 0;\n// Cached pid of parent process - if the parent process dies, we want to keep\n// writing to the same log file.\nuptr stoptheworld_tracer_ppid = 0;\n\nstatic const int kMaxNumOfInternalDieCallbacks = 5;\nstatic DieCallbackType InternalDieCallbacks[kMaxNumOfInternalDieCallbacks];\n\nbool AddDieCallback(DieCallbackType callback) {\n  for (int i = 0; i < kMaxNumOfInternalDieCallbacks; i++) {\n    if (InternalDieCallbacks[i] == nullptr) {\n      InternalDieCallbacks[i] = callback;\n      return true;\n    }\n  }\n  return false;\n}\n\nbool RemoveDieCallback(DieCallbackType callback) {\n  for (int i = 0; i < kMaxNumOfInternalDieCallbacks; i++) {\n    if (InternalDieCallbacks[i] == callback) {\n      internal_memmove(&InternalDieCallbacks[i], &InternalDieCallbacks[i + 1],\n                       sizeof(InternalDieCallbacks[0]) *\n                           (kMaxNumOfInternalDieCallbacks - i - 1));\n      InternalDieCallbacks[kMaxNumOfInternalDieCallbacks - 1] = nullptr;\n      return true;\n    }\n  }\n  return false;\n}\n\nstatic DieCallbackType UserDieCallback;\nvoid SetUserDieCallback(DieCallbackType callback) {\n  UserDieCallback = callback;\n}\n\nvoid NORETURN Die() {\n  if (UserDieCallback)\n    UserDieCallback();\n  for (int i = kMaxNumOfInternalDieCallbacks - 1; i >= 0; i--) {\n    if (InternalDieCallbacks[i])\n      InternalDieCallbacks[i]();\n  }\n  if (common_flags()->abort_on_error)\n    Abort();\n  internal__exit(common_flags()->exitcode);\n}\n\nstatic CheckFailedCallbackType CheckFailedCallback;\nvoid SetCheckFailedCallback(CheckFailedCallbackType callback) {\n  CheckFailedCallback = callback;\n}\n\nvoid NORETURN CheckFailed(const char *file, int line, const char *cond,\n                          u64 v1, u64 v2) {\n  if (CheckFailedCallback) {\n    CheckFailedCallback(file, line, cond, v1, v2);\n  }\n  Report(\"Sanitizer CHECK failed: %s:%d %s (%lld, %lld)\\n\", file, line, cond,\n                                                            v1, v2);\n  Die();\n}\n\nvoid NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type,\n                                      const char *mmap_type, error_t err,\n                                      bool raw_report) {\n  static int recursion_count;\n  if (raw_report || recursion_count) {\n    // If raw report is requested or we went into recursion, just die.\n    // The Report() and CHECK calls below may call mmap recursively and fail.\n    RawWrite(\"ERROR: Failed to mmap\\n\");\n    Die();\n  }\n  recursion_count++;\n  Report(\"ERROR: %s failed to \"\n         \"%s 0x%zx (%zd) bytes of %s (error code: %d)\\n\",\n         SanitizerToolName, mmap_type, size, size, mem_type, err);\n#ifndef SANITIZER_GO\n  DumpProcessMap();\n#endif\n  UNREACHABLE(\"unable to mmap\");\n}\n\nbool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,\n                      uptr *read_len, uptr max_len, error_t *errno_p) {\n  uptr PageSize = GetPageSizeCached();\n  uptr kMinFileLen = PageSize;\n  *buff = nullptr;\n  *buff_size = 0;\n  *read_len = 0;\n  // The files we usually open are not seekable, so try different buffer sizes.\n  for (uptr size = kMinFileLen; size <= max_len; size *= 2) {\n    fd_t fd = OpenFile(file_name, RdOnly, errno_p);\n    if (fd == kInvalidFd) return false;\n    UnmapOrDie(*buff, *buff_size);\n    *buff = (char*)MmapOrDie(size, __func__);\n    *buff_size = size;\n    *read_len = 0;\n    // Read up to one page at a time.\n    bool reached_eof = false;\n    while (*read_len + PageSize <= size) {\n      uptr just_read;\n      if (!ReadFromFile(fd, *buff + *read_len, PageSize, &just_read, errno_p)) {\n        UnmapOrDie(*buff, *buff_size);\n        return false;\n      }\n      if (just_read == 0) {\n        reached_eof = true;\n        break;\n      }\n      *read_len += just_read;\n    }\n    CloseFile(fd);\n    if (reached_eof)  // We've read the whole file.\n      break;\n  }\n  return true;\n}\n\ntypedef bool UptrComparisonFunction(const uptr &a, const uptr &b);\n\ntemplate<class T>\nstatic inline bool CompareLess(const T &a, const T &b) {\n  return a < b;\n}\n\nvoid SortArray(uptr *array, uptr size) {\n  InternalSort<uptr*, UptrComparisonFunction>(&array, size, CompareLess);\n}\n\n// We want to map a chunk of address space aligned to 'alignment'.\n// We do it by maping a bit more and then unmaping redundant pieces.\n// We probably can do it with fewer syscalls in some OS-dependent way.\nvoid *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type) {\n// uptr PageSize = GetPageSizeCached();\n  CHECK(IsPowerOfTwo(size));\n  CHECK(IsPowerOfTwo(alignment));\n  uptr map_size = size + alignment;\n  uptr map_res = (uptr)MmapOrDie(map_size, mem_type);\n  uptr map_end = map_res + map_size;\n  uptr res = map_res;\n  if (res & (alignment - 1))  // Not aligned.\n    res = (map_res + alignment) & ~(alignment - 1);\n  uptr end = res + size;\n  if (res != map_res)\n    UnmapOrDie((void*)map_res, res - map_res);\n  if (end != map_end)\n    UnmapOrDie((void*)end, map_end - end);\n  return (void*)res;\n}\n\nconst char *StripPathPrefix(const char *filepath,\n                            const char *strip_path_prefix) {\n  if (!filepath) return nullptr;\n  if (!strip_path_prefix) return filepath;\n  const char *res = filepath;\n  if (const char *pos = internal_strstr(filepath, strip_path_prefix))\n    res = pos + internal_strlen(strip_path_prefix);\n  if (res[0] == '.' && res[1] == '/')\n    res += 2;\n  return res;\n}\n\nconst char *StripModuleName(const char *module) {\n  if (!module)\n    return nullptr;\n  if (SANITIZER_WINDOWS) {\n    // On Windows, both slash and backslash are possible.\n    // Pick the one that goes last.\n    if (const char *bslash_pos = internal_strrchr(module, '\\\\'))\n      return StripModuleName(bslash_pos + 1);\n  }\n  if (const char *slash_pos = internal_strrchr(module, '/')) {\n    return slash_pos + 1;\n  }\n  return module;\n}\n\nvoid ReportErrorSummary(const char *error_message) {\n  if (!common_flags()->print_summary)\n    return;\n  InternalScopedString buff(kMaxSummaryLength);\n  buff.append(\"SUMMARY: %s: %s\", SanitizerToolName, error_message);\n  __sanitizer_report_error_summary(buff.data());\n}\n\n#ifndef SANITIZER_GO\nvoid ReportErrorSummary(const char *error_type, const AddressInfo &info) {\n  if (!common_flags()->print_summary)\n    return;\n  InternalScopedString buff(kMaxSummaryLength);\n  buff.append(\"%s \", error_type);\n  RenderFrame(&buff, \"%L %F\", 0, info, common_flags()->symbolize_vs_style,\n              common_flags()->strip_path_prefix);\n  ReportErrorSummary(buff.data());\n}\n#endif\n\n// Removes the ANSI escape sequences from the input string (in-place).\nvoid RemoveANSIEscapeSequencesFromString(char *str) {\n  if (!str)\n    return;\n\n  // We are going to remove the escape sequences in place.\n  char *s = str;\n  char *z = str;\n  while (*s != '\\0') {\n    CHECK_GE(s, z);\n    // Skip over ANSI escape sequences with pointer 's'.\n    if (*s == '\\033' && *(s + 1) == '[') {\n      s = internal_strchrnul(s, 'm');\n      if (*s == '\\0') {\n        break;\n      }\n      s++;\n      continue;\n    }\n    // 's' now points at a character we want to keep. Copy over the buffer\n    // content if the escape sequence has been perviously skipped andadvance\n    // both pointers.\n    if (s != z)\n      *z = *s;\n\n    // If we have not seen an escape sequence, just advance both pointers.\n    z++;\n    s++;\n  }\n\n  // Null terminate the string.\n  *z = '\\0';\n}\n\nvoid LoadedModule::set(const char *module_name, uptr base_address) {\n  clear();\n  full_name_ = internal_strdup(module_name);\n  base_address_ = base_address;\n}\n\nvoid LoadedModule::clear() {\n  InternalFree(full_name_);\n  full_name_ = nullptr;\n  while (!ranges_.empty()) {\n    AddressRange *r = ranges_.front();\n    ranges_.pop_front();\n    InternalFree(r);\n  }\n}\n\nvoid LoadedModule::addAddressRange(uptr beg, uptr end, bool executable) {\n  void *mem = InternalAlloc(sizeof(AddressRange));\n  AddressRange *r = new(mem) AddressRange(beg, end, executable);\n  ranges_.push_back(r);\n}\n\nbool LoadedModule::containsAddress(uptr address) const {\n  for (Iterator iter = ranges(); iter.hasNext();) {\n    const AddressRange *r = iter.next();\n    if (r->beg <= address && address < r->end)\n      return true;\n  }\n  return false;\n}\n\nstatic atomic_uintptr_t g_total_mmaped;\n\nvoid IncreaseTotalMmap(uptr size) {\n  if (!common_flags()->mmap_limit_mb) return;\n  uptr total_mmaped =\n      atomic_fetch_add(&g_total_mmaped, size, memory_order_relaxed) + size;\n  // Since for now mmap_limit_mb is not a user-facing flag, just kill\n  // a program. Use RAW_CHECK to avoid extra mmaps in reporting.\n  RAW_CHECK((total_mmaped >> 20) < common_flags()->mmap_limit_mb);\n}\n\nvoid DecreaseTotalMmap(uptr size) {\n  if (!common_flags()->mmap_limit_mb) return;\n  atomic_fetch_sub(&g_total_mmaped, size, memory_order_relaxed);\n}\n\nbool TemplateMatch(const char *templ, const char *str) {\n  if ((!str) || str[0] == 0)\n    return false;\n  bool start = false;\n  if (templ && templ[0] == '^') {\n    start = true;\n    templ++;\n  }\n  bool asterisk = false;\n  while (templ && templ[0]) {\n    if (templ[0] == '*') {\n      templ++;\n      start = false;\n      asterisk = true;\n      continue;\n    }\n    if (templ[0] == '$')\n      return str[0] == 0 || asterisk;\n    if (str[0] == 0)\n      return false;\n    char *tpos = (char*)internal_strchr(templ, '*');\n    char *tpos1 = (char*)internal_strchr(templ, '$');\n    if ((!tpos) || (tpos1 && tpos1 < tpos))\n      tpos = tpos1;\n    if (tpos)\n      tpos[0] = 0;\n    const char *str0 = str;\n    const char *spos = internal_strstr(str, templ);\n    str = spos + internal_strlen(templ);\n    templ = tpos;\n    if (tpos)\n      tpos[0] = tpos == tpos1 ? '$' : '*';\n    if (!spos)\n      return false;\n    if (start && spos != str0)\n      return false;\n    start = false;\n    asterisk = false;\n  }\n  return true;\n}\n\nstatic const char kPathSeparator = SANITIZER_WINDOWS ? ';' : ':';\n\nchar *FindPathToBinary(const char *name) {\n  const char *path = GetEnv(\"PATH\");\n  if (!path)\n    return nullptr;\n  uptr name_len = internal_strlen(name);\n  InternalScopedBuffer<char> buffer(kMaxPathLength);\n  const char *beg = path;\n  while (true) {\n    const char *end = internal_strchrnul(beg, kPathSeparator);\n    uptr prefix_len = end - beg;\n    if (prefix_len + name_len + 2 <= kMaxPathLength) {\n      internal_memcpy(buffer.data(), beg, prefix_len);\n      buffer[prefix_len] = '/';\n      internal_memcpy(&buffer[prefix_len + 1], name, name_len);\n      buffer[prefix_len + 1 + name_len] = '\\0';\n      if (FileExists(buffer.data()))\n        return internal_strdup(buffer.data());\n    }\n    if (*end == '\\0') break;\n    beg = end + 1;\n  }\n  return nullptr;\n}\n\nstatic char binary_name_cache_str[kMaxPathLength];\nstatic char process_name_cache_str[kMaxPathLength];\n\nconst char *GetProcessName() {\n  return process_name_cache_str;\n}\n\nstatic uptr ReadProcessName(/*out*/ char *buf, uptr buf_len) {\n  ReadLongProcessName(buf, buf_len);\n  char *s = const_cast<char *>(StripModuleName(buf));\n  uptr len = internal_strlen(s);\n  if (s != buf) {\n    internal_memmove(buf, s, len);\n    buf[len] = '\\0';\n  }\n  return len;\n}\n\nvoid UpdateProcessName() {\n  ReadProcessName(process_name_cache_str, sizeof(process_name_cache_str));\n}\n\n// Call once to make sure that binary_name_cache_str is initialized\nvoid CacheBinaryName() {\n  if (binary_name_cache_str[0] != '\\0')\n    return;\n  ReadBinaryName(binary_name_cache_str, sizeof(binary_name_cache_str));\n  ReadProcessName(process_name_cache_str, sizeof(process_name_cache_str));\n}\n\nuptr ReadBinaryNameCached(/*out*/char *buf, uptr buf_len) {\n  CacheBinaryName();\n  uptr name_len = internal_strlen(binary_name_cache_str);\n  name_len = (name_len < buf_len - 1) ? name_len : buf_len - 1;\n  if (buf_len == 0)\n    return 0;\n  internal_memcpy(buf, binary_name_cache_str, name_len);\n  buf[name_len] = '\\0';\n  return name_len;\n}\n\n} // namespace __sanitizer\n\nusing namespace __sanitizer;  // NOLINT\n\nextern \"C\" {\nvoid __sanitizer_set_report_path(const char *path) {\n  report_file.SetReportPath(path);\n}\n\nvoid __sanitizer_report_error_summary(const char *error_summary) {\n  Printf(\"%s\\n\", error_summary);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_set_death_callback(void (*callback)(void)) {\n  SetUserDieCallback(callback);\n}\n} // extern \"C\"\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_common.h",
    "content": "//===-- sanitizer_common.h --------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between run-time libraries of sanitizers.\n//\n// It declares common functions and classes that are used in both runtimes.\n// Implementation of some functions are provided in sanitizer_common, while\n// others must be defined by run-time library itself.\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_COMMON_H\n#define SANITIZER_COMMON_H\n\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_interface_internal.h\"\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_list.h\"\n#include \"sanitizer_mutex.h\"\n\n#ifdef _MSC_VER\nextern \"C\" void _ReadWriteBarrier();\n#pragma intrinsic(_ReadWriteBarrier)\n#endif\n\nnamespace __sanitizer {\nstruct StackTrace;\nstruct AddressInfo;\n\n// Constants.\nconst uptr kWordSize = SANITIZER_WORDSIZE / 8;\nconst uptr kWordSizeInBits = 8 * kWordSize;\n\n#if defined(__powerpc__) || defined(__powerpc64__)\n  const uptr kCacheLineSize = 128;\n#else\n  const uptr kCacheLineSize = 64;\n#endif\n\nconst uptr kMaxPathLength = 4096;\n\n// 16K loaded modules should be enough for everyone.\nstatic const uptr kMaxNumberOfModules = 1 << 14;\n\nconst uptr kMaxThreadStackSize = 1 << 30;  // 1Gb\n\nstatic const uptr kErrorMessageBufferSize = 1 << 16;\n\n// Denotes fake PC values that come from JIT/JAVA/etc.\n// For such PC values __tsan_symbolize_external() will be called.\nconst u64 kExternalPCBit = 1ULL << 60;\n\nextern const char *SanitizerToolName;  // Can be changed by the tool.\n\nextern atomic_uint32_t current_verbosity;\nINLINE void SetVerbosity(int verbosity) {\n  atomic_store(&current_verbosity, verbosity, memory_order_relaxed);\n}\nINLINE int Verbosity() {\n  return atomic_load(&current_verbosity, memory_order_relaxed);\n}\n\nuptr GetPageSize();\nuptr GetPageSizeCached();\nuptr GetMmapGranularity();\nuptr GetMaxVirtualAddress();\n// Threads\nuptr GetTid();\nuptr GetThreadSelf();\nvoid GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,\n                                uptr *stack_bottom);\nvoid GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,\n                          uptr *tls_addr, uptr *tls_size);\n\n// Memory management\nvoid *MmapOrDie(uptr size, const char *mem_type, bool raw_report = false);\nINLINE void *MmapOrDieQuietly(uptr size, const char *mem_type) {\n  return MmapOrDie(size, mem_type, /*raw_report*/ true);\n}\nvoid UnmapOrDie(void *addr, uptr size);\nvoid *MmapFixedNoReserve(uptr fixed_addr, uptr size,\n                         const char *name = nullptr);\nvoid *MmapNoReserveOrDie(uptr size, const char *mem_type);\nvoid *MmapFixedOrDie(uptr fixed_addr, uptr size);\nvoid *MmapNoAccess(uptr fixed_addr, uptr size, const char *name = nullptr);\n// Map aligned chunk of address space; size and alignment are powers of two.\nvoid *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type);\n// Disallow access to a memory range.  Use MmapNoAccess to allocate an\n// unaccessible memory.\nbool MprotectNoAccess(uptr addr, uptr size);\n\n// Used to check if we can map shadow memory to a fixed location.\nbool MemoryRangeIsAvailable(uptr range_start, uptr range_end);\nvoid FlushUnneededShadowMemory(uptr addr, uptr size);\nvoid IncreaseTotalMmap(uptr size);\nvoid DecreaseTotalMmap(uptr size);\nuptr GetRSS();\nvoid NoHugePagesInRegion(uptr addr, uptr length);\nvoid DontDumpShadowMemory(uptr addr, uptr length);\n// Check if the built VMA size matches the runtime one.\nvoid CheckVMASize();\n\n// InternalScopedBuffer can be used instead of large stack arrays to\n// keep frame size low.\n// FIXME: use InternalAlloc instead of MmapOrDie once\n// InternalAlloc is made libc-free.\ntemplate<typename T>\nclass InternalScopedBuffer {\n public:\n  explicit InternalScopedBuffer(uptr cnt) {\n    cnt_ = cnt;\n    ptr_ = (T*)MmapOrDie(cnt * sizeof(T), \"InternalScopedBuffer\");\n  }\n  ~InternalScopedBuffer() {\n    UnmapOrDie(ptr_, cnt_ * sizeof(T));\n  }\n  T &operator[](uptr i) { return ptr_[i]; }\n  T *data() { return ptr_; }\n  uptr size() { return cnt_ * sizeof(T); }\n\n private:\n  T *ptr_;\n  uptr cnt_;\n  // Disallow evil constructors.\n  InternalScopedBuffer(const InternalScopedBuffer&);\n  void operator=(const InternalScopedBuffer&);\n};\n\nclass InternalScopedString : public InternalScopedBuffer<char> {\n public:\n  explicit InternalScopedString(uptr max_length)\n      : InternalScopedBuffer<char>(max_length), length_(0) {\n    (*this)[0] = '\\0';\n  }\n  uptr length() { return length_; }\n  void clear() {\n    (*this)[0] = '\\0';\n    length_ = 0;\n  }\n  void append(const char *format, ...);\n\n private:\n  uptr length_;\n};\n\n// Simple low-level (mmap-based) allocator for internal use. Doesn't have\n// constructor, so all instances of LowLevelAllocator should be\n// linker initialized.\nclass LowLevelAllocator {\n public:\n  // Requires an external lock.\n  void *Allocate(uptr size);\n private:\n  char *allocated_end_;\n  char *allocated_current_;\n};\ntypedef void (*LowLevelAllocateCallback)(uptr ptr, uptr size);\n// Allows to register tool-specific callbacks for LowLevelAllocator.\n// Passing NULL removes the callback.\nvoid SetLowLevelAllocateCallback(LowLevelAllocateCallback callback);\n\n// IO\nvoid RawWrite(const char *buffer);\nbool ColorizeReports();\nvoid RemoveANSIEscapeSequencesFromString(char *buffer);\nvoid Printf(const char *format, ...);\nvoid Report(const char *format, ...);\nvoid SetPrintfAndReportCallback(void (*callback)(const char *));\n#define VReport(level, ...)                                              \\\n  do {                                                                   \\\n    if ((uptr)Verbosity() >= (level)) Report(__VA_ARGS__); \\\n  } while (0)\n#define VPrintf(level, ...)                                              \\\n  do {                                                                   \\\n    if ((uptr)Verbosity() >= (level)) Printf(__VA_ARGS__); \\\n  } while (0)\n\n// Can be used to prevent mixing error reports from different sanitizers.\nextern StaticSpinMutex CommonSanitizerReportMutex;\n\nstruct ReportFile {\n  void Write(const char *buffer, uptr length);\n  bool SupportsColors();\n  void SetReportPath(const char *path);\n\n  // Don't use fields directly. They are only declared public to allow\n  // aggregate initialization.\n\n  // Protects fields below.\n  StaticSpinMutex *mu;\n  // Opened file descriptor. Defaults to stderr. It may be equal to\n  // kInvalidFd, in which case new file will be opened when necessary.\n  fd_t fd;\n  // Path prefix of report file, set via __sanitizer_set_report_path.\n  char path_prefix[kMaxPathLength];\n  // Full path to report, obtained as <path_prefix>.PID\n  char full_path[kMaxPathLength];\n  // PID of the process that opened fd. If a fork() occurs,\n  // the PID of child will be different from fd_pid.\n  uptr fd_pid;\n\n private:\n  void ReopenIfNecessary();\n};\nextern ReportFile report_file;\n\nextern uptr stoptheworld_tracer_pid;\nextern uptr stoptheworld_tracer_ppid;\n\nenum FileAccessMode {\n  RdOnly,\n  WrOnly,\n  RdWr\n};\n\n// Returns kInvalidFd on error.\nfd_t OpenFile(const char *filename, FileAccessMode mode,\n              error_t *errno_p = nullptr);\nvoid CloseFile(fd_t);\n\n// Return true on success, false on error.\nbool ReadFromFile(fd_t fd, void *buff, uptr buff_size,\n                  uptr *bytes_read = nullptr, error_t *error_p = nullptr);\nbool WriteToFile(fd_t fd, const void *buff, uptr buff_size,\n                 uptr *bytes_written = nullptr, error_t *error_p = nullptr);\n\nbool RenameFile(const char *oldpath, const char *newpath,\n                error_t *error_p = nullptr);\n\n// Scoped file handle closer.\nstruct FileCloser {\n  explicit FileCloser(fd_t fd) : fd(fd) {}\n  ~FileCloser() { CloseFile(fd); }\n  fd_t fd;\n};\n\nbool SupportsColoredOutput(fd_t fd);\n\n// Opens the file 'file_name\" and reads up to 'max_len' bytes.\n// The resulting buffer is mmaped and stored in '*buff'.\n// The size of the mmaped region is stored in '*buff_size'.\n// The total number of read bytes is stored in '*read_len'.\n// Returns true if file was successfully opened and read.\nbool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,\n                      uptr *read_len, uptr max_len = 1 << 26,\n                      error_t *errno_p = nullptr);\n// Maps given file to virtual memory, and returns pointer to it\n// (or NULL if mapping fails). Stores the size of mmaped region\n// in '*buff_size'.\nvoid *MapFileToMemory(const char *file_name, uptr *buff_size);\nvoid *MapWritableFileToMemory(void *addr, uptr size, fd_t fd, OFF_T offset);\n\nbool IsAccessibleMemoryRange(uptr beg, uptr size);\n\n// Error report formatting.\nconst char *StripPathPrefix(const char *filepath,\n                            const char *strip_file_prefix);\n// Strip the directories from the module name.\nconst char *StripModuleName(const char *module);\n\n// OS\nuptr ReadBinaryName(/*out*/char *buf, uptr buf_len);\nuptr ReadBinaryNameCached(/*out*/char *buf, uptr buf_len);\nuptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len);\nconst char *GetProcessName();\nvoid UpdateProcessName();\nvoid CacheBinaryName();\nvoid DisableCoreDumperIfNecessary();\nvoid DumpProcessMap();\nbool FileExists(const char *filename);\nconst char *GetEnv(const char *name);\nbool SetEnv(const char *name, const char *value);\nconst char *GetPwd();\nchar *FindPathToBinary(const char *name);\nbool IsPathSeparator(const char c);\nbool IsAbsolutePath(const char *path);\n\nu32 GetUid();\nvoid ReExec();\nbool StackSizeIsUnlimited();\nvoid SetStackSizeLimitInBytes(uptr limit);\nbool AddressSpaceIsUnlimited();\nvoid SetAddressSpaceUnlimited();\nvoid AdjustStackSize(void *attr);\nvoid PrepareForSandboxing(__sanitizer_sandbox_arguments *args);\nvoid CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args);\nvoid SetSandboxingCallback(void (*f)());\n\nvoid CoverageUpdateMapping();\nvoid CovBeforeFork();\nvoid CovAfterFork(int child_pid);\n\nvoid InitializeCoverage(bool enabled, const char *coverage_dir);\nvoid ReInitializeCoverage(bool enabled, const char *coverage_dir);\n\nvoid InitTlsSize();\nuptr GetTlsSize();\n\n// Other\nvoid SleepForSeconds(int seconds);\nvoid SleepForMillis(int millis);\nu64 NanoTime();\nint Atexit(void (*function)(void));\nvoid SortArray(uptr *array, uptr size);\nbool TemplateMatch(const char *templ, const char *str);\n\n// Exit\nvoid NORETURN Abort();\nvoid NORETURN Die();\nvoid NORETURN\nCheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2);\nvoid NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type,\n                                      const char *mmap_type, error_t err,\n                                      bool raw_report = false);\n\n// Set the name of the current thread to 'name', return true on succees.\n// The name may be truncated to a system-dependent limit.\nbool SanitizerSetThreadName(const char *name);\n// Get the name of the current thread (no more than max_len bytes),\n// return true on succees. name should have space for at least max_len+1 bytes.\nbool SanitizerGetThreadName(char *name, int max_len);\n\n// Specific tools may override behavior of \"Die\" and \"CheckFailed\" functions\n// to do tool-specific job.\ntypedef void (*DieCallbackType)(void);\n\n// It's possible to add several callbacks that would be run when \"Die\" is\n// called. The callbacks will be run in the opposite order. The tools are\n// strongly recommended to setup all callbacks during initialization, when there\n// is only a single thread.\nbool AddDieCallback(DieCallbackType callback);\nbool RemoveDieCallback(DieCallbackType callback);\n\nvoid SetUserDieCallback(DieCallbackType callback);\n\ntypedef void (*CheckFailedCallbackType)(const char *, int, const char *,\n                                       u64, u64);\nvoid SetCheckFailedCallback(CheckFailedCallbackType callback);\n\n// Callback will be called if soft_rss_limit_mb is given and the limit is\n// exceeded (exceeded==true) or if rss went down below the limit\n// (exceeded==false).\n// The callback should be registered once at the tool init time.\nvoid SetSoftRssLimitExceededCallback(void (*Callback)(bool exceeded));\n\n// Functions related to signal handling.\ntypedef void (*SignalHandlerType)(int, void *, void *);\nbool IsDeadlySignal(int signum);\nvoid InstallDeadlySignalHandlers(SignalHandlerType handler);\n// Alternative signal stack (POSIX-only).\nvoid SetAlternateSignalStack();\nvoid UnsetAlternateSignalStack();\n\n// We don't want a summary too long.\nconst int kMaxSummaryLength = 1024;\n// Construct a one-line string:\n//   SUMMARY: SanitizerToolName: error_message\n// and pass it to __sanitizer_report_error_summary.\nvoid ReportErrorSummary(const char *error_message);\n// Same as above, but construct error_message as:\n//   error_type file:line[:column][ function]\nvoid ReportErrorSummary(const char *error_type, const AddressInfo &info);\n// Same as above, but obtains AddressInfo by symbolizing top stack trace frame.\nvoid ReportErrorSummary(const char *error_type, StackTrace *trace);\n\n// Math\n#if SANITIZER_WINDOWS && !defined(__clang__) && !defined(__GNUC__)\nextern \"C\" {\nunsigned char _BitScanForward(unsigned long *index, unsigned long mask);  // NOLINT\nunsigned char _BitScanReverse(unsigned long *index, unsigned long mask);  // NOLINT\n#if defined(_WIN64)\nunsigned char _BitScanForward64(unsigned long *index, unsigned __int64 mask);  // NOLINT\nunsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask);  // NOLINT\n#endif\n}\n#endif\n\nINLINE uptr MostSignificantSetBitIndex(uptr x) {\n  CHECK_NE(x, 0U);\n  unsigned long up;  // NOLINT\n#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__)\n# ifdef _WIN64\n  up = SANITIZER_WORDSIZE - 1 - __builtin_clzll(x);\n# else\n  up = SANITIZER_WORDSIZE - 1 - __builtin_clzl(x);\n# endif\n#elif defined(_WIN64)\n  _BitScanReverse64(&up, x);\n#else\n  _BitScanReverse(&up, x);\n#endif\n  return up;\n}\n\nINLINE uptr LeastSignificantSetBitIndex(uptr x) {\n  CHECK_NE(x, 0U);\n  unsigned long up;  // NOLINT\n#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__)\n# ifdef _WIN64\n  up = __builtin_ctzll(x);\n# else\n  up = __builtin_ctzl(x);\n# endif\n#elif defined(_WIN64)\n  _BitScanForward64(&up, x);\n#else\n  _BitScanForward(&up, x);\n#endif\n  return up;\n}\n\nINLINE bool IsPowerOfTwo(uptr x) {\n  return (x & (x - 1)) == 0;\n}\n\nINLINE uptr RoundUpToPowerOfTwo(uptr size) {\n  CHECK(size);\n  if (IsPowerOfTwo(size)) return size;\n\n  uptr up = MostSignificantSetBitIndex(size);\n  CHECK(size < (1ULL << (up + 1)));\n  CHECK(size > (1ULL << up));\n  return 1ULL << (up + 1);\n}\n\nINLINE uptr RoundUpTo(uptr size, uptr boundary) {\n  RAW_CHECK(IsPowerOfTwo(boundary));\n  return (size + boundary - 1) & ~(boundary - 1);\n}\n\nINLINE uptr RoundDownTo(uptr x, uptr boundary) {\n  return x & ~(boundary - 1);\n}\n\nINLINE bool IsAligned(uptr a, uptr alignment) {\n  return (a & (alignment - 1)) == 0;\n}\n\nINLINE uptr Log2(uptr x) {\n  CHECK(IsPowerOfTwo(x));\n  return LeastSignificantSetBitIndex(x);\n}\n\n// Don't use std::min, std::max or std::swap, to minimize dependency\n// on libstdc++.\ntemplate<class T> T Min(T a, T b) { return a < b ? a : b; }\ntemplate<class T> T Max(T a, T b) { return a > b ? a : b; }\ntemplate<class T> void Swap(T& a, T& b) {\n  T tmp = a;\n  a = b;\n  b = tmp;\n}\n\n// Char handling\nINLINE bool IsSpace(int c) {\n  return (c == ' ') || (c == '\\n') || (c == '\\t') ||\n         (c == '\\f') || (c == '\\r') || (c == '\\v');\n}\nINLINE bool IsDigit(int c) {\n  return (c >= '0') && (c <= '9');\n}\nINLINE int ToLower(int c) {\n  return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;\n}\n\n// A low-level vector based on mmap. May incur a significant memory overhead for\n// small vectors.\n// WARNING: The current implementation supports only POD types.\ntemplate<typename T>\nclass InternalMmapVectorNoCtor {\n public:\n  void Initialize(uptr initial_capacity) {\n    capacity_ = Max(initial_capacity, (uptr)1);\n    size_ = 0;\n    data_ = (T *)MmapOrDie(capacity_ * sizeof(T), \"InternalMmapVectorNoCtor\");\n  }\n  void Destroy() {\n    UnmapOrDie(data_, capacity_ * sizeof(T));\n  }\n  T &operator[](uptr i) {\n    CHECK_LT(i, size_);\n    return data_[i];\n  }\n  const T &operator[](uptr i) const {\n    CHECK_LT(i, size_);\n    return data_[i];\n  }\n  void push_back(const T &element) {\n    CHECK_LE(size_, capacity_);\n    if (size_ == capacity_) {\n      uptr new_capacity = RoundUpToPowerOfTwo(size_ + 1);\n      Resize(new_capacity);\n    }\n    data_[size_++] = element;\n  }\n  T &back() {\n    CHECK_GT(size_, 0);\n    return data_[size_ - 1];\n  }\n  void pop_back() {\n    CHECK_GT(size_, 0);\n    size_--;\n  }\n  uptr size() const {\n    return size_;\n  }\n  const T *data() const {\n    return data_;\n  }\n  T *data() {\n    return data_;\n  }\n  uptr capacity() const {\n    return capacity_;\n  }\n\n  void clear() { size_ = 0; }\n  bool empty() const { return size() == 0; }\n\n private:\n  void Resize(uptr new_capacity) {\n    CHECK_GT(new_capacity, 0);\n    CHECK_LE(size_, new_capacity);\n    T *new_data = (T *)MmapOrDie(new_capacity * sizeof(T),\n                                 \"InternalMmapVector\");\n    internal_memcpy(new_data, data_, size_ * sizeof(T));\n    T *old_data = data_;\n    data_ = new_data;\n    UnmapOrDie(old_data, capacity_ * sizeof(T));\n    capacity_ = new_capacity;\n  }\n\n  T *data_;\n  uptr capacity_;\n  uptr size_;\n};\n\ntemplate<typename T>\nclass InternalMmapVector : public InternalMmapVectorNoCtor<T> {\n public:\n  explicit InternalMmapVector(uptr initial_capacity) {\n    InternalMmapVectorNoCtor<T>::Initialize(initial_capacity);\n  }\n  ~InternalMmapVector() { InternalMmapVectorNoCtor<T>::Destroy(); }\n  // Disallow evil constructors.\n  InternalMmapVector(const InternalMmapVector&);\n  void operator=(const InternalMmapVector&);\n};\n\n// HeapSort for arrays and InternalMmapVector.\ntemplate<class Container, class Compare>\nvoid InternalSort(Container *v, uptr size, Compare comp) {\n  if (size < 2)\n    return;\n  // Stage 1: insert elements to the heap.\n  for (uptr i = 1; i < size; i++) {\n    uptr j, p;\n    for (j = i; j > 0; j = p) {\n      p = (j - 1) / 2;\n      if (comp((*v)[p], (*v)[j]))\n        Swap((*v)[j], (*v)[p]);\n      else\n        break;\n    }\n  }\n  // Stage 2: swap largest element with the last one,\n  // and sink the new top.\n  for (uptr i = size - 1; i > 0; i--) {\n    Swap((*v)[0], (*v)[i]);\n    uptr j, max_ind;\n    for (j = 0; j < i; j = max_ind) {\n      uptr left = 2 * j + 1;\n      uptr right = 2 * j + 2;\n      max_ind = j;\n      if (left < i && comp((*v)[max_ind], (*v)[left]))\n        max_ind = left;\n      if (right < i && comp((*v)[max_ind], (*v)[right]))\n        max_ind = right;\n      if (max_ind != j)\n        Swap((*v)[j], (*v)[max_ind]);\n      else\n        break;\n    }\n  }\n}\n\ntemplate<class Container, class Value, class Compare>\nuptr InternalBinarySearch(const Container &v, uptr first, uptr last,\n                          const Value &val, Compare comp) {\n  uptr not_found = last + 1;\n  while (last >= first) {\n    uptr mid = (first + last) / 2;\n    if (comp(v[mid], val))\n      first = mid + 1;\n    else if (comp(val, v[mid]))\n      last = mid - 1;\n    else\n      return mid;\n  }\n  return not_found;\n}\n\n// Represents a binary loaded into virtual memory (e.g. this can be an\n// executable or a shared object).\nclass LoadedModule {\n public:\n  LoadedModule() : full_name_(nullptr), base_address_(0) { ranges_.clear(); }\n  void set(const char *module_name, uptr base_address);\n  void clear();\n  void addAddressRange(uptr beg, uptr end, bool executable);\n  bool containsAddress(uptr address) const;\n\n  const char *full_name() const { return full_name_; }\n  uptr base_address() const { return base_address_; }\n\n  struct AddressRange {\n    AddressRange *next;\n    uptr beg;\n    uptr end;\n    bool executable;\n\n    AddressRange(uptr beg, uptr end, bool executable)\n        : next(nullptr), beg(beg), end(end), executable(executable) {}\n  };\n\n  typedef IntrusiveList<AddressRange>::ConstIterator Iterator;\n  Iterator ranges() const { return Iterator(&ranges_); }\n\n private:\n  char *full_name_;  // Owned.\n  uptr base_address_;\n  IntrusiveList<AddressRange> ranges_;\n};\n\n// OS-dependent function that fills array with descriptions of at most\n// \"max_modules\" currently loaded modules. Returns the number of\n// initialized modules. If filter is nonzero, ignores modules for which\n// filter(full_name) is false.\ntypedef bool (*string_predicate_t)(const char *);\nuptr GetListOfModules(LoadedModule *modules, uptr max_modules,\n                      string_predicate_t filter);\n\n// Callback type for iterating over a set of memory ranges.\ntypedef void (*RangeIteratorCallback)(uptr begin, uptr end, void *arg);\n\nenum AndroidApiLevel {\n  ANDROID_NOT_ANDROID = 0,\n  ANDROID_KITKAT = 19,\n  ANDROID_LOLLIPOP_MR1 = 22,\n  ANDROID_POST_LOLLIPOP = 23\n};\n\nvoid WriteToSyslog(const char *buffer);\n\n#if SANITIZER_MAC\nvoid LogFullErrorReport(const char *buffer);\n#else\nINLINE void LogFullErrorReport(const char *buffer) {}\n#endif\n\n#if SANITIZER_LINUX || SANITIZER_MAC\nvoid WriteOneLineToSyslog(const char *s);\n#else\nINLINE void WriteOneLineToSyslog(const char *s) {}\n#endif\n\n#if SANITIZER_LINUX\n// Initialize Android logging. Any writes before this are silently lost.\nvoid AndroidLogInit();\nbool ShouldLogAfterPrintf();\n#else\nINLINE void AndroidLogInit() {}\nINLINE bool ShouldLogAfterPrintf() { return false; }\n#endif\n\n#if SANITIZER_ANDROID\nvoid SanitizerInitializeUnwinder();\nAndroidApiLevel AndroidGetApiLevel();\n#else\nINLINE void AndroidLogWrite(const char *buffer_unused) {}\nINLINE void SanitizerInitializeUnwinder() {}\nINLINE AndroidApiLevel AndroidGetApiLevel() { return ANDROID_NOT_ANDROID; }\n#endif\n\nINLINE uptr GetPthreadDestructorIterations() {\n#if SANITIZER_ANDROID\n  return (AndroidGetApiLevel() == ANDROID_LOLLIPOP_MR1) ? 8 : 4;\n#elif SANITIZER_POSIX\n  return 4;\n#else\n// Unused on Windows.\n  return 0;\n#endif\n}\n\nvoid *internal_start_thread(void(*func)(void*), void *arg);\nvoid internal_join_thread(void *th);\nvoid MaybeStartBackgroudThread();\n\n// Make the compiler think that something is going on there.\n// Use this inside a loop that looks like memset/memcpy/etc to prevent the\n// compiler from recognising it and turning it into an actual call to\n// memset/memcpy/etc.\nstatic inline void SanitizerBreakOptimization(void *arg) {\n#if _MSC_VER && !defined(__clang__)\n  _ReadWriteBarrier();\n#else\n  __asm__ __volatile__(\"\" : : \"r\" (arg) : \"memory\");\n#endif\n}\n\nstruct SignalContext {\n  void *context;\n  uptr addr;\n  uptr pc;\n  uptr sp;\n  uptr bp;\n\n  SignalContext(void *context, uptr addr, uptr pc, uptr sp, uptr bp) :\n      context(context), addr(addr), pc(pc), sp(sp), bp(bp) {\n  }\n\n  // Creates signal context in a platform-specific manner.\n  static SignalContext Create(void *siginfo, void *context);\n};\n\nvoid GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp);\n\nvoid DisableReexec();\nvoid MaybeReexec();\n\n}  // namespace __sanitizer\n\ninline void *operator new(__sanitizer::operator_new_size_type size,\n                          __sanitizer::LowLevelAllocator &alloc) {\n  return alloc.Allocate(size);\n}\n\nstruct StackDepotStats {\n  uptr n_uniq_ids;\n  uptr allocated;\n};\n\n#endif  // SANITIZER_COMMON_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc",
    "content": "//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Common function interceptors for tools like AddressSanitizer,\n// ThreadSanitizer, MemorySanitizer, etc.\n//\n// This file should be included into the tool's interceptor file,\n// which has to define it's own macros:\n//   COMMON_INTERCEPTOR_ENTER\n//   COMMON_INTERCEPTOR_ENTER_NOIGNORE\n//   COMMON_INTERCEPTOR_READ_RANGE\n//   COMMON_INTERCEPTOR_WRITE_RANGE\n//   COMMON_INTERCEPTOR_INITIALIZE_RANGE\n//   COMMON_INTERCEPTOR_DIR_ACQUIRE\n//   COMMON_INTERCEPTOR_FD_ACQUIRE\n//   COMMON_INTERCEPTOR_FD_RELEASE\n//   COMMON_INTERCEPTOR_FD_ACCESS\n//   COMMON_INTERCEPTOR_SET_THREAD_NAME\n//   COMMON_INTERCEPTOR_ON_DLOPEN\n//   COMMON_INTERCEPTOR_ON_EXIT\n//   COMMON_INTERCEPTOR_MUTEX_LOCK\n//   COMMON_INTERCEPTOR_MUTEX_UNLOCK\n//   COMMON_INTERCEPTOR_MUTEX_REPAIR\n//   COMMON_INTERCEPTOR_SET_PTHREAD_NAME\n//   COMMON_INTERCEPTOR_HANDLE_RECVMSG\n//   COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED\n//===----------------------------------------------------------------------===//\n\n#include \"interception/interception.h\"\n#include \"sanitizer_addrhashmap.h\"\n#include \"sanitizer_placement_new.h\"\n#include \"sanitizer_platform_interceptors.h\"\n#include \"sanitizer_tls_get_addr.h\"\n\n#include <stdarg.h>\n\n#if SANITIZER_INTERCEPTOR_HOOKS\n#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)                                     \\\n  do {                                                                         \\\n    if (f)                                                                     \\\n      f(__VA_ARGS__);                                                          \\\n  } while (false);\n#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)                                  \\\n  extern \"C\" {                                                                 \\\n  SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void f(__VA_ARGS__);  \\\n  } // extern \"C\"\n#else\n#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)\n#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)\n\n#endif  // SANITIZER_INTERCEPTOR_HOOKS\n\n#if SANITIZER_WINDOWS && !defined(va_copy)\n#define va_copy(dst, src) ((dst) = (src))\n#endif // _WIN32\n\n#if SANITIZER_FREEBSD\n#define pthread_setname_np pthread_set_name_np\n#define inet_aton __inet_aton\n#define inet_pton __inet_pton\n#define iconv __bsd_iconv\n#endif\n\n#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE\n#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}\n#endif\n\n#ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM\n#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}\n#endif\n\n#ifndef COMMON_INTERCEPTOR_FD_ACCESS\n#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}\n#endif\n\n#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK\n#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {}\n#endif\n\n#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK\n#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}\n#endif\n\n#ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR\n#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {}\n#endif\n\n#ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG\n#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))\n#endif\n\n#ifndef COMMON_INTERCEPTOR_FILE_OPEN\n#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}\n#endif\n\n#ifndef COMMON_INTERCEPTOR_FILE_CLOSE\n#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}\n#endif\n\n#ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED\n#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {}\n#endif\n\n#ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED\n#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}\n#endif\n\n#ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE\n#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \\\n  COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)\n#endif\n\n#ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED\n#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)\n#endif\n\n#define COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, n)       \\\n    COMMON_INTERCEPTOR_READ_RANGE((ctx), (s),                       \\\n      common_flags()->strict_string_checks ? (len) + 1 : (n) )\n\n#define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n)                   \\\n    COMMON_INTERCEPTOR_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n))\n\n#ifndef COMMON_INTERCEPTOR_ON_DLOPEN\n#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) {}\n#endif\n\n#ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE\n#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0;\n#endif\n\n#ifndef COMMON_INTERCEPTOR_ACQUIRE\n#define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {}\n#endif\n\n#ifndef COMMON_INTERCEPTOR_RELEASE\n#define COMMON_INTERCEPTOR_RELEASE(ctx, u) {}\n#endif\n\nstruct FileMetadata {\n  // For open_memstream().\n  char **addr;\n  SIZE_T *size;\n};\n\nstruct CommonInterceptorMetadata {\n  enum {\n    CIMT_INVALID = 0,\n    CIMT_FILE\n  } type;\n  union {\n    FileMetadata file;\n  };\n};\n\ntypedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;\n\nstatic MetadataHashMap *interceptor_metadata_map;\n\n#if SI_NOT_WINDOWS\nUNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,\n                                          const FileMetadata &file) {\n  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);\n  CHECK(h.created());\n  h->type = CommonInterceptorMetadata::CIMT_FILE;\n  h->file = file;\n}\n\nUNUSED static const FileMetadata *GetInterceptorMetadata(\n    __sanitizer_FILE *addr) {\n  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr,\n                            /* remove */ false,\n                            /* create */ false);\n  if (h.exists()) {\n    CHECK(!h.created());\n    CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE);\n    return &h->file;\n  } else {\n    return 0;\n  }\n}\n\nUNUSED static void DeleteInterceptorMetadata(void *addr) {\n  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true);\n  CHECK(h.exists());\n}\n#endif  // SI_NOT_WINDOWS\n\n#if SANITIZER_INTERCEPT_TEXTDOMAIN\nINTERCEPTOR(char*, textdomain, const char *domainname) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname);\n  COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0);\n  char *domain = REAL(textdomain)(domainname);\n  if (domain) {\n    COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1);\n  }\n  return domain;\n}\n#define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain)\n#else\n#define INIT_TEXTDOMAIN\n#endif\n\n#if SANITIZER_INTERCEPT_STRCMP\nstatic inline int CharCmpX(unsigned char c1, unsigned char c2) {\n  return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;\n}\n\nDECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc,\n                              const char *s1, const char *s2)\n\nINTERCEPTOR(int, strcmp, const char *s1, const char *s2) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);\n  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,\n                             s2);\n  unsigned char c1, c2;\n  uptr i;\n  for (i = 0;; i++) {\n    c1 = (unsigned char)s1[i];\n    c2 = (unsigned char)s2[i];\n    if (c1 != c2 || c1 == '\\0') break;\n  }\n  COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);\n  COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);\n  return CharCmpX(c1, c2);\n}\n\nDECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc,\n                              const char *s1, const char *s2, uptr n)\n\nINTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {\n  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)\n    return internal_strncmp(s1, s2, size);\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);\n  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,\n                             s2, size);\n  unsigned char c1 = 0, c2 = 0;\n  uptr i;\n  for (i = 0; i < size; i++) {\n    c1 = (unsigned char)s1[i];\n    c2 = (unsigned char)s2[i];\n    if (c1 != c2 || c1 == '\\0') break;\n  }\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));\n  return CharCmpX(c1, c2);\n}\n\n#define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)\n#define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp)\n#else\n#define INIT_STRCMP\n#define INIT_STRNCMP\n#endif\n\n#if SANITIZER_INTERCEPT_STRCASECMP\nstatic inline int CharCaseCmp(unsigned char c1, unsigned char c2) {\n  int c1_low = ToLower(c1);\n  int c2_low = ToLower(c2);\n  return c1_low - c2_low;\n}\n\nINTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);\n  unsigned char c1 = 0, c2 = 0;\n  uptr i;\n  for (i = 0;; i++) {\n    c1 = (unsigned char)s1[i];\n    c2 = (unsigned char)s2[i];\n    if (CharCaseCmp(c1, c2) != 0 || c1 == '\\0') break;\n  }\n  COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);\n  COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);\n  return CharCaseCmp(c1, c2);\n}\n\nINTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);\n  unsigned char c1 = 0, c2 = 0;\n  uptr i;\n  for (i = 0; i < n; i++) {\n    c1 = (unsigned char)s1[i];\n    c2 = (unsigned char)s2[i];\n    if (CharCaseCmp(c1, c2) != 0 || c1 == '\\0') break;\n  }\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));\n  return CharCaseCmp(c1, c2);\n}\n\n#define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)\n#define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp)\n#else\n#define INIT_STRCASECMP\n#define INIT_STRNCASECMP\n#endif\n\n#if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR\nstatic inline void StrstrCheck(void *ctx, char *r, const char *s1,\n                               const char *s2) {\n    uptr len1 = REAL(strlen)(s1);\n    uptr len2 = REAL(strlen)(s2);\n    COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s1, len1,\n                                          r ? r - s1 + len2 : len1 + 1);\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1);\n}\n#endif\n\n#if SANITIZER_INTERCEPT_STRSTR\nINTERCEPTOR(char*, strstr, const char *s1, const char *s2) {\n  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)\n    return internal_strstr(s1, s2);\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2);\n  char *r = REAL(strstr)(s1, s2);\n  if (common_flags()->intercept_strstr)\n    StrstrCheck(ctx, r, s1, s2);\n  return r;\n}\n\n#define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr);\n#else\n#define INIT_STRSTR\n#endif\n\n#if SANITIZER_INTERCEPT_STRCASESTR\nINTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2);\n  char *r = REAL(strcasestr)(s1, s2);\n  if (common_flags()->intercept_strstr)\n    StrstrCheck(ctx, r, s1, s2);\n  return r;\n}\n\n#define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr);\n#else\n#define INIT_STRCASESTR\n#endif\n\n#if SANITIZER_INTERCEPT_STRSPN\nINTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2);\n  SIZE_T r = REAL(strspn)(s1, s2);\n  if (common_flags()->intercept_strspn) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);\n    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);\n  }\n  return r;\n}\n\nINTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2);\n  SIZE_T r = REAL(strcspn)(s1, s2);\n  if (common_flags()->intercept_strspn) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);\n    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);\n  }\n  return r;\n}\n\n#define INIT_STRSPN \\\n  COMMON_INTERCEPT_FUNCTION(strspn); \\\n  COMMON_INTERCEPT_FUNCTION(strcspn);\n#else\n#define INIT_STRSPN\n#endif\n\n#if SANITIZER_INTERCEPT_STRPBRK\nINTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2);\n  char *r = REAL(strpbrk)(s1, s2);\n  if (common_flags()->intercept_strpbrk) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);\n    COMMON_INTERCEPTOR_READ_STRING(ctx, s1,\n        r ? r - s1 + 1 : REAL(strlen)(s1) + 1);\n  }\n  return r;\n}\n\n#define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk);\n#else\n#define INIT_STRPBRK\n#endif\n\n#if SANITIZER_INTERCEPT_MEMCMP\n\nDECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,\n                              const void *s1, const void *s2, uptr n)\n\nINTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {\n  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)\n    return internal_memcmp(a1, a2, size);\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);\n  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,\n                             a2, size);\n  if (common_flags()->intercept_memcmp) {\n    if (common_flags()->strict_memcmp) {\n      // Check the entire regions even if the first bytes of the buffers are\n      // different.\n      COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size);\n      COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size);\n      // Fallthrough to REAL(memcmp) below.\n    } else {\n      unsigned char c1 = 0, c2 = 0;\n      const unsigned char *s1 = (const unsigned char*)a1;\n      const unsigned char *s2 = (const unsigned char*)a2;\n      uptr i;\n      for (i = 0; i < size; i++) {\n        c1 = s1[i];\n        c2 = s2[i];\n        if (c1 != c2) break;\n      }\n      COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));\n      COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));\n      return CharCmpX(c1, c2);\n    }\n  }\n  return REAL(memcmp(a1, a2, size));\n}\n\n#define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)\n#else\n#define INIT_MEMCMP\n#endif\n\n#if SANITIZER_INTERCEPT_MEMCHR\nINTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {\n  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)\n    return internal_memchr(s, c, n);\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n);\n  void *res = REAL(memchr)(s, c, n);\n  uptr len = res ? (char *)res - (const char *)s + 1 : n;\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len);\n  return res;\n}\n\n#define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr)\n#else\n#define INIT_MEMCHR\n#endif\n\n#if SANITIZER_INTERCEPT_MEMRCHR\nINTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n);\n  return REAL(memrchr)(s, c, n);\n}\n\n#define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr)\n#else\n#define INIT_MEMRCHR\n#endif\n\n#if SANITIZER_INTERCEPT_FREXP\nINTERCEPTOR(double, frexp, double x, int *exp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);\n  // Assuming frexp() always writes to |exp|.\n  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));\n  double res = REAL(frexp)(x, exp);\n  return res;\n}\n\n#define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp);\n#else\n#define INIT_FREXP\n#endif  // SANITIZER_INTERCEPT_FREXP\n\n#if SANITIZER_INTERCEPT_FREXPF_FREXPL\nINTERCEPTOR(float, frexpf, float x, int *exp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  float res = REAL(frexpf)(x, exp);\n  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));\n  return res;\n}\n\nINTERCEPTOR(long double, frexpl, long double x, int *exp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  long double res = REAL(frexpl)(x, exp);\n  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));\n  return res;\n}\n\n#define INIT_FREXPF_FREXPL           \\\n  COMMON_INTERCEPT_FUNCTION(frexpf); \\\n  COMMON_INTERCEPT_FUNCTION(frexpl)\n#else\n#define INIT_FREXPF_FREXPL\n#endif  // SANITIZER_INTERCEPT_FREXPF_FREXPL\n\n#if SI_NOT_WINDOWS\nstatic void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,\n                        SIZE_T iovlen, SIZE_T maxlen) {\n  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {\n    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);\n    maxlen -= sz;\n  }\n}\n\nstatic void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,\n                       SIZE_T iovlen, SIZE_T maxlen) {\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);\n  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {\n    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);\n    maxlen -= sz;\n  }\n}\n#endif\n\n#if SANITIZER_INTERCEPT_READ\nINTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);\n  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SSIZE_T res = REAL(read)(fd, ptr, count);\n  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);\n  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);\n  return res;\n}\n#define INIT_READ COMMON_INTERCEPT_FUNCTION(read)\n#else\n#define INIT_READ\n#endif\n\n#if SANITIZER_INTERCEPT_PREAD\nINTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);\n  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SSIZE_T res = REAL(pread)(fd, ptr, count, offset);\n  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);\n  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);\n  return res;\n}\n#define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread)\n#else\n#define INIT_PREAD\n#endif\n\n#if SANITIZER_INTERCEPT_PREAD64\nINTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);\n  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);\n  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);\n  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);\n  return res;\n}\n#define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64)\n#else\n#define INIT_PREAD64\n#endif\n\n#if SANITIZER_INTERCEPT_READV\nINTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,\n                        int iovcnt) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);\n  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);\n  SSIZE_T res = REAL(readv)(fd, iov, iovcnt);\n  if (res > 0) write_iovec(ctx, iov, iovcnt, res);\n  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);\n  return res;\n}\n#define INIT_READV COMMON_INTERCEPT_FUNCTION(readv)\n#else\n#define INIT_READV\n#endif\n\n#if SANITIZER_INTERCEPT_PREADV\nINTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,\n            OFF_T offset) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);\n  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);\n  SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);\n  if (res > 0) write_iovec(ctx, iov, iovcnt, res);\n  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);\n  return res;\n}\n#define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv)\n#else\n#define INIT_PREADV\n#endif\n\n#if SANITIZER_INTERCEPT_PREADV64\nINTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,\n            OFF64_T offset) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);\n  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);\n  SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);\n  if (res > 0) write_iovec(ctx, iov, iovcnt, res);\n  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);\n  return res;\n}\n#define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64)\n#else\n#define INIT_PREADV64\n#endif\n\n#if SANITIZER_INTERCEPT_WRITE\nINTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);\n  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);\n  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);\n  SSIZE_T res = REAL(write)(fd, ptr, count);\n  // FIXME: this check should be _before_ the call to REAL(write), not after\n  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);\n  return res;\n}\n#define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)\n#else\n#define INIT_WRITE\n#endif\n\n#if SANITIZER_INTERCEPT_PWRITE\nINTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);\n  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);\n  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);\n  SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);\n  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);\n  return res;\n}\n#define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite)\n#else\n#define INIT_PWRITE\n#endif\n\n#if SANITIZER_INTERCEPT_PWRITE64\nINTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,\n            OFF64_T offset) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);\n  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);\n  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);\n  SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);\n  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);\n  return res;\n}\n#define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64)\n#else\n#define INIT_PWRITE64\n#endif\n\n#if SANITIZER_INTERCEPT_WRITEV\nINTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,\n                        int iovcnt) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);\n  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);\n  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);\n  SSIZE_T res = REAL(writev)(fd, iov, iovcnt);\n  if (res > 0) read_iovec(ctx, iov, iovcnt, res);\n  return res;\n}\n#define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev)\n#else\n#define INIT_WRITEV\n#endif\n\n#if SANITIZER_INTERCEPT_PWRITEV\nINTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,\n            OFF_T offset) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);\n  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);\n  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);\n  SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);\n  if (res > 0) read_iovec(ctx, iov, iovcnt, res);\n  return res;\n}\n#define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev)\n#else\n#define INIT_PWRITEV\n#endif\n\n#if SANITIZER_INTERCEPT_PWRITEV64\nINTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,\n            OFF64_T offset) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);\n  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);\n  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);\n  SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);\n  if (res > 0) read_iovec(ctx, iov, iovcnt, res);\n  return res;\n}\n#define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64)\n#else\n#define INIT_PWRITEV64\n#endif\n\n#if SANITIZER_INTERCEPT_PRCTL\nINTERCEPTOR(int, prctl, int option, unsigned long arg2,\n            unsigned long arg3,                        // NOLINT\n            unsigned long arg4, unsigned long arg5) {  // NOLINT\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);\n  static const int PR_SET_NAME = 15;\n  int res = REAL(prctl(option, arg2, arg3, arg4, arg5));\n  if (option == PR_SET_NAME) {\n    char buff[16];\n    internal_strncpy(buff, (char *)arg2, 15);\n    buff[15] = 0;\n    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);\n  }\n  return res;\n}\n#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)\n#else\n#define INIT_PRCTL\n#endif  // SANITIZER_INTERCEPT_PRCTL\n\n#if SANITIZER_INTERCEPT_TIME\nINTERCEPTOR(unsigned long, time, unsigned long *t) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, time, t);\n  unsigned long local_t;\n  unsigned long res = REAL(time)(&local_t);\n  if (t && res != (unsigned long)-1) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));\n    *t = local_t;\n  }\n  return res;\n}\n#define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);\n#else\n#define INIT_TIME\n#endif  // SANITIZER_INTERCEPT_TIME\n\n#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS\nstatic void unpoison_tm(void *ctx, __sanitizer_tm *tm) {\n  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));\n  if (tm->tm_zone) {\n    // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone\n    // can point to shared memory and tsan would report a data race.\n    COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,\n                                        REAL(strlen(tm->tm_zone)) + 1);\n  }\n}\nINTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);\n  __sanitizer_tm *res = REAL(localtime)(timep);\n  if (res) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));\n    unpoison_tm(ctx, res);\n  }\n  return res;\n}\nINTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);\n  __sanitizer_tm *res = REAL(localtime_r)(timep, result);\n  if (res) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));\n    unpoison_tm(ctx, res);\n  }\n  return res;\n}\nINTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);\n  __sanitizer_tm *res = REAL(gmtime)(timep);\n  if (res) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));\n    unpoison_tm(ctx, res);\n  }\n  return res;\n}\nINTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);\n  __sanitizer_tm *res = REAL(gmtime_r)(timep, result);\n  if (res) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));\n    unpoison_tm(ctx, res);\n  }\n  return res;\n}\nINTERCEPTOR(char *, ctime, unsigned long *timep) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char *res = REAL(ctime)(timep);\n  if (res) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);\n  }\n  return res;\n}\nINTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char *res = REAL(ctime_r)(timep, result);\n  if (res) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);\n  }\n  return res;\n}\nINTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char *res = REAL(asctime)(tm);\n  if (res) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);\n  }\n  return res;\n}\nINTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char *res = REAL(asctime_r)(tm, result);\n  if (res) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);\n  }\n  return res;\n}\nINTERCEPTOR(long, mktime, __sanitizer_tm *tm) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));\n  long res = REAL(mktime)(tm);\n  if (res != -1) unpoison_tm(ctx, tm);\n  return res;\n}\n#define INIT_LOCALTIME_AND_FRIENDS        \\\n  COMMON_INTERCEPT_FUNCTION(localtime);   \\\n  COMMON_INTERCEPT_FUNCTION(localtime_r); \\\n  COMMON_INTERCEPT_FUNCTION(gmtime);      \\\n  COMMON_INTERCEPT_FUNCTION(gmtime_r);    \\\n  COMMON_INTERCEPT_FUNCTION(ctime);       \\\n  COMMON_INTERCEPT_FUNCTION(ctime_r);     \\\n  COMMON_INTERCEPT_FUNCTION(asctime);     \\\n  COMMON_INTERCEPT_FUNCTION(asctime_r);   \\\n  COMMON_INTERCEPT_FUNCTION(mktime);\n#else\n#define INIT_LOCALTIME_AND_FRIENDS\n#endif  // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS\n\n#if SANITIZER_INTERCEPT_STRPTIME\nINTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);\n  if (format)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char *res = REAL(strptime)(s, format, tm);\n  COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0);\n  if (res && tm) {\n    // Do not call unpoison_tm here, because strptime does not, in fact,\n    // initialize the entire struct tm. For example, tm_zone pointer is left\n    // uninitialized.\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));\n  }\n  return res;\n}\n#define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);\n#else\n#define INIT_STRPTIME\n#endif\n\n#if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF\n#include \"sanitizer_common_interceptors_format.inc\"\n\n#define FORMAT_INTERCEPTOR_IMPL(name, vname, ...)                              \\\n  {                                                                            \\\n    void *ctx;                                                                 \\\n    va_list ap;                                                                \\\n    va_start(ap, format);                                                      \\\n    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap);                     \\\n    int res = WRAP(vname)(__VA_ARGS__, ap);                                    \\\n    va_end(ap);                                                                \\\n    return res;                                                                \\\n  }\n\n#endif\n\n#if SANITIZER_INTERCEPT_SCANF\n\n#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \\\n  {                                                                            \\\n    void *ctx;                                                                 \\\n    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \\\n    va_list aq;                                                                \\\n    va_copy(aq, ap);                                                           \\\n    int res = REAL(vname)(__VA_ARGS__);                                        \\\n    if (res > 0)                                                               \\\n      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \\\n    va_end(aq);                                                                \\\n    return res;                                                                \\\n  }\n\nINTERCEPTOR(int, vscanf, const char *format, va_list ap)\nVSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)\n\nINTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)\nVSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)\n\nINTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)\nVSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)\n\n#if SANITIZER_INTERCEPT_ISOC99_SCANF\nINTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)\nVSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)\n\nINTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,\n            va_list ap)\nVSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)\n\nINTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)\nVSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)\n#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF\n\nINTERCEPTOR(int, scanf, const char *format, ...)\nFORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)\n\nINTERCEPTOR(int, fscanf, void *stream, const char *format, ...)\nFORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)\n\nINTERCEPTOR(int, sscanf, const char *str, const char *format, ...)\nFORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)\n\n#if SANITIZER_INTERCEPT_ISOC99_SCANF\nINTERCEPTOR(int, __isoc99_scanf, const char *format, ...)\nFORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)\n\nINTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)\nFORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)\n\nINTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)\nFORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)\n#endif\n\n#endif\n\n#if SANITIZER_INTERCEPT_SCANF\n#define INIT_SCANF                    \\\n  COMMON_INTERCEPT_FUNCTION(scanf);   \\\n  COMMON_INTERCEPT_FUNCTION(sscanf);  \\\n  COMMON_INTERCEPT_FUNCTION(fscanf);  \\\n  COMMON_INTERCEPT_FUNCTION(vscanf);  \\\n  COMMON_INTERCEPT_FUNCTION(vsscanf); \\\n  COMMON_INTERCEPT_FUNCTION(vfscanf);\n#else\n#define INIT_SCANF\n#endif\n\n#if SANITIZER_INTERCEPT_ISOC99_SCANF\n#define INIT_ISOC99_SCANF                      \\\n  COMMON_INTERCEPT_FUNCTION(__isoc99_scanf);   \\\n  COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf);  \\\n  COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf);  \\\n  COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf);  \\\n  COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \\\n  COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf);\n#else\n#define INIT_ISOC99_SCANF\n#endif\n\n#if SANITIZER_INTERCEPT_PRINTF\n\n#define VPRINTF_INTERCEPTOR_ENTER(vname, ...)                                  \\\n  void *ctx;                                                                   \\\n  COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                           \\\n  va_list aq;                                                                  \\\n  va_copy(aq, ap);\n\n#define VPRINTF_INTERCEPTOR_RETURN()                                           \\\n  va_end(aq);\n\n#define VPRINTF_INTERCEPTOR_IMPL(vname, ...)                                   \\\n  {                                                                            \\\n    VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__);                             \\\n    if (common_flags()->check_printf)                                          \\\n      printf_common(ctx, format, aq);                                          \\\n    int res = REAL(vname)(__VA_ARGS__);                                        \\\n    VPRINTF_INTERCEPTOR_RETURN();                                              \\\n    return res;                                                                \\\n  }\n\n// FIXME: under ASan the REAL() call below may write to freed memory and\n// corrupt its metadata. See\n// https://github.com/google/sanitizers/issues/321.\n#define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...)                             \\\n  {                                                                            \\\n    VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__)                         \\\n    if (common_flags()->check_printf) {                                        \\\n      printf_common(ctx, format, aq);                                          \\\n    }                                                                          \\\n    int res = REAL(vname)(str, __VA_ARGS__);                                   \\\n    if (res >= 0) {                                                            \\\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1);                       \\\n    }                                                                          \\\n    VPRINTF_INTERCEPTOR_RETURN();                                              \\\n    return res;                                                                \\\n  }\n\n// FIXME: under ASan the REAL() call below may write to freed memory and\n// corrupt its metadata. See\n// https://github.com/google/sanitizers/issues/321.\n#define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...)                      \\\n  {                                                                            \\\n    VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__)                   \\\n    if (common_flags()->check_printf) {                                        \\\n      printf_common(ctx, format, aq);                                          \\\n    }                                                                          \\\n    int res = REAL(vname)(str, size, __VA_ARGS__);                             \\\n    if (res >= 0) {                                                            \\\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1)));  \\\n    }                                                                          \\\n    VPRINTF_INTERCEPTOR_RETURN();                                              \\\n    return res;                                                                \\\n  }\n\n// FIXME: under ASan the REAL() call below may write to freed memory and\n// corrupt its metadata. See\n// https://github.com/google/sanitizers/issues/321.\n#define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...)                           \\\n  {                                                                            \\\n    VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__)                        \\\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *));                 \\\n    if (common_flags()->check_printf) {                                        \\\n      printf_common(ctx, format, aq);                                          \\\n    }                                                                          \\\n    int res = REAL(vname)(strp, __VA_ARGS__);                                  \\\n    if (res >= 0) {                                                            \\\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1);                     \\\n    }                                                                          \\\n    VPRINTF_INTERCEPTOR_RETURN();                                              \\\n    return res;                                                                \\\n  }\n\nINTERCEPTOR(int, vprintf, const char *format, va_list ap)\nVPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)\n\nINTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,\n            va_list ap)\nVPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)\n\nINTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,\n            va_list ap)\nVSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)\n\n#if SANITIZER_INTERCEPT_PRINTF_L\nINTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc,\n            const char *format, va_list ap)\nVSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap)\n\nINTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc,\n            const char *format, ...)\nFORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format)\n#endif  // SANITIZER_INTERCEPT_PRINTF_L\n\nINTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)\nVSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)\n\nINTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)\nVASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)\n\n#if SANITIZER_INTERCEPT_ISOC99_PRINTF\nINTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)\nVPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)\n\nINTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,\n            const char *format, va_list ap)\nVPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)\n\nINTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,\n            va_list ap)\nVSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)\n\nINTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,\n            va_list ap)\nVSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,\n                          ap)\n\n#endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF\n\nINTERCEPTOR(int, printf, const char *format, ...)\nFORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)\n\nINTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)\nFORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)\n\nINTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT\nFORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT\n\nINTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)\nFORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)\n\nINTERCEPTOR(int, asprintf, char **strp, const char *format, ...)\nFORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)\n\n#if SANITIZER_INTERCEPT_ISOC99_PRINTF\nINTERCEPTOR(int, __isoc99_printf, const char *format, ...)\nFORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)\n\nINTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,\n            ...)\nFORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)\n\nINTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)\nFORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)\n\nINTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,\n            const char *format, ...)\nFORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,\n                        format)\n\n#endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF\n\n#endif  // SANITIZER_INTERCEPT_PRINTF\n\n#if SANITIZER_INTERCEPT_PRINTF\n#define INIT_PRINTF                     \\\n  COMMON_INTERCEPT_FUNCTION(printf);    \\\n  COMMON_INTERCEPT_FUNCTION(sprintf);   \\\n  COMMON_INTERCEPT_FUNCTION(snprintf);  \\\n  COMMON_INTERCEPT_FUNCTION(asprintf);  \\\n  COMMON_INTERCEPT_FUNCTION(fprintf);   \\\n  COMMON_INTERCEPT_FUNCTION(vprintf);   \\\n  COMMON_INTERCEPT_FUNCTION(vsprintf);  \\\n  COMMON_INTERCEPT_FUNCTION(vsnprintf); \\\n  COMMON_INTERCEPT_FUNCTION(vasprintf); \\\n  COMMON_INTERCEPT_FUNCTION(vfprintf);\n#else\n#define INIT_PRINTF\n#endif\n\n#if SANITIZER_INTERCEPT_PRINTF_L\n#define INIT_PRINTF_L                     \\\n  COMMON_INTERCEPT_FUNCTION(snprintf_l);  \\\n  COMMON_INTERCEPT_FUNCTION(vsnprintf_l);\n#else\n#define INIT_PRINTF_L\n#endif\n\n#if SANITIZER_INTERCEPT_ISOC99_PRINTF\n#define INIT_ISOC99_PRINTF                       \\\n  COMMON_INTERCEPT_FUNCTION(__isoc99_printf);    \\\n  COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf);   \\\n  COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf);  \\\n  COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf);   \\\n  COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf);   \\\n  COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf);  \\\n  COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \\\n  COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);\n#else\n#define INIT_ISOC99_PRINTF\n#endif\n\n#if SANITIZER_INTERCEPT_IOCTL\n#include \"sanitizer_common_interceptors_ioctl.inc\"\nINTERCEPTOR(int, ioctl, int d, unsigned long request, ...) {\n  // We need a frame pointer, because we call into ioctl_common_[pre|post] which\n  // can trigger a report and we need to be able to unwind through this\n  // function.  On Mac in debug mode we might not have a frame pointer, because\n  // ioctl_common_[pre|post] doesn't get inlined here.\n  ENABLE_FRAME_POINTER;\n\n  void *ctx;\n  va_list ap;\n  va_start(ap, request);\n  void *arg = va_arg(ap, void *);\n  va_end(ap);\n  COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);\n\n  CHECK(ioctl_initialized);\n\n  // Note: TSan does not use common flags, and they are zero-initialized.\n  // This effectively disables ioctl handling in TSan.\n  if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);\n\n  // Although request is unsigned long, the rest of the interceptor uses it\n  // as just \"unsigned\" to save space, because we know that all values fit in\n  // \"unsigned\" - they are compile-time constants.\n\n  const ioctl_desc *desc = ioctl_lookup(request);\n  ioctl_desc decoded_desc;\n  if (!desc) {\n    VPrintf(2, \"Decoding unknown ioctl 0x%x\\n\", request);\n    if (!ioctl_decode(request, &decoded_desc))\n      Printf(\"WARNING: failed decoding unknown ioctl 0x%x\\n\", request);\n    else\n      desc = &decoded_desc;\n  }\n\n  if (desc) ioctl_common_pre(ctx, desc, d, request, arg);\n  int res = REAL(ioctl)(d, request, arg);\n  // FIXME: some ioctls have different return values for success and failure.\n  if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);\n  return res;\n}\n#define INIT_IOCTL \\\n  ioctl_init();    \\\n  COMMON_INTERCEPT_FUNCTION(ioctl);\n#else\n#define INIT_IOCTL\n#endif\n\n#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || \\\n    SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT || \\\n    SANITIZER_INTERCEPT_GETPWENT_R || SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS\nstatic void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {\n  if (pwd) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));\n    if (pwd->pw_name)\n      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_name,\n                                          REAL(strlen)(pwd->pw_name) + 1);\n    if (pwd->pw_passwd)\n      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_passwd,\n                                          REAL(strlen)(pwd->pw_passwd) + 1);\n#if !SANITIZER_ANDROID\n    if (pwd->pw_gecos)\n      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_gecos,\n                                          REAL(strlen)(pwd->pw_gecos) + 1);\n#endif\n#if SANITIZER_MAC\n    if (pwd->pw_class)\n      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_class,\n                                          REAL(strlen)(pwd->pw_class) + 1);\n#endif\n    if (pwd->pw_dir)\n      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_dir,\n                                          REAL(strlen)(pwd->pw_dir) + 1);\n    if (pwd->pw_shell)\n      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_shell,\n                                          REAL(strlen)(pwd->pw_shell) + 1);\n  }\n}\n\nstatic void unpoison_group(void *ctx, __sanitizer_group *grp) {\n  if (grp) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));\n    if (grp->gr_name)\n      COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_name,\n                                          REAL(strlen)(grp->gr_name) + 1);\n    if (grp->gr_passwd)\n      COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_passwd,\n                                          REAL(strlen)(grp->gr_passwd) + 1);\n    char **p = grp->gr_mem;\n    for (; *p; ++p) {\n      COMMON_INTERCEPTOR_INITIALIZE_RANGE(*p, REAL(strlen)(*p) + 1);\n    }\n    COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_mem,\n                                        (p - grp->gr_mem + 1) * sizeof(*p));\n  }\n}\n#endif  // SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS ||\n        // SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT ||\n        // SANITIZER_INTERCEPT_GETPWENT_R ||\n        // SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS\n\n#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS\nINTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);\n  __sanitizer_passwd *res = REAL(getpwnam)(name);\n  if (res) unpoison_passwd(ctx, res);\n  return res;\n}\nINTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);\n  __sanitizer_passwd *res = REAL(getpwuid)(uid);\n  if (res) unpoison_passwd(ctx, res);\n  return res;\n}\nINTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);\n  __sanitizer_group *res = REAL(getgrnam)(name);\n  if (res) unpoison_group(ctx, res);\n  return res;\n}\nINTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);\n  __sanitizer_group *res = REAL(getgrgid)(gid);\n  if (res) unpoison_group(ctx, res);\n  return res;\n}\n#define INIT_GETPWNAM_AND_FRIENDS      \\\n  COMMON_INTERCEPT_FUNCTION(getpwnam); \\\n  COMMON_INTERCEPT_FUNCTION(getpwuid); \\\n  COMMON_INTERCEPT_FUNCTION(getgrnam); \\\n  COMMON_INTERCEPT_FUNCTION(getgrgid);\n#else\n#define INIT_GETPWNAM_AND_FRIENDS\n#endif\n\n#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS\nINTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,\n            char *buf, SIZE_T buflen, __sanitizer_passwd **result) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);\n  if (!res) {\n    if (result && *result) unpoison_passwd(ctx, *result);\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);\n  }\n  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));\n  return res;\n}\nINTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,\n            SIZE_T buflen, __sanitizer_passwd **result) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);\n  if (!res) {\n    if (result && *result) unpoison_passwd(ctx, *result);\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);\n  }\n  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));\n  return res;\n}\nINTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,\n            char *buf, SIZE_T buflen, __sanitizer_group **result) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);\n  if (!res) {\n    if (result && *result) unpoison_group(ctx, *result);\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);\n  }\n  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));\n  return res;\n}\nINTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,\n            SIZE_T buflen, __sanitizer_group **result) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);\n  if (!res) {\n    if (result && *result) unpoison_group(ctx, *result);\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);\n  }\n  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));\n  return res;\n}\n#define INIT_GETPWNAM_R_AND_FRIENDS      \\\n  COMMON_INTERCEPT_FUNCTION(getpwnam_r); \\\n  COMMON_INTERCEPT_FUNCTION(getpwuid_r); \\\n  COMMON_INTERCEPT_FUNCTION(getgrnam_r); \\\n  COMMON_INTERCEPT_FUNCTION(getgrgid_r);\n#else\n#define INIT_GETPWNAM_R_AND_FRIENDS\n#endif\n\n#if SANITIZER_INTERCEPT_GETPWENT\nINTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);\n  __sanitizer_passwd *res = REAL(getpwent)(dummy);\n  if (res) unpoison_passwd(ctx, res);\n  return res;\n}\nINTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);\n  __sanitizer_group *res = REAL(getgrent)(dummy);\n  if (res) unpoison_group(ctx, res);;\n  return res;\n}\n#define INIT_GETPWENT                  \\\n  COMMON_INTERCEPT_FUNCTION(getpwent); \\\n  COMMON_INTERCEPT_FUNCTION(getgrent);\n#else\n#define INIT_GETPWENT\n#endif\n\n#if SANITIZER_INTERCEPT_FGETPWENT\nINTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);\n  __sanitizer_passwd *res = REAL(fgetpwent)(fp);\n  if (res) unpoison_passwd(ctx, res);\n  return res;\n}\nINTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);\n  __sanitizer_group *res = REAL(fgetgrent)(fp);\n  if (res) unpoison_group(ctx, res);\n  return res;\n}\n#define INIT_FGETPWENT                  \\\n  COMMON_INTERCEPT_FUNCTION(fgetpwent); \\\n  COMMON_INTERCEPT_FUNCTION(fgetgrent);\n#else\n#define INIT_FGETPWENT\n#endif\n\n#if SANITIZER_INTERCEPT_GETPWENT_R\nINTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,\n            SIZE_T buflen, __sanitizer_passwd **pwbufp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);\n  if (!res) {\n    if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);\n  }\n  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));\n  return res;\n}\nINTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,\n            SIZE_T buflen, __sanitizer_passwd **pwbufp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);\n  if (!res) {\n    if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);\n  }\n  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));\n  return res;\n}\nINTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,\n            __sanitizer_group **pwbufp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);\n  if (!res) {\n    if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);\n  }\n  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));\n  return res;\n}\nINTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,\n            SIZE_T buflen, __sanitizer_group **pwbufp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);\n  if (!res) {\n    if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);\n  }\n  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));\n  return res;\n}\n#define INIT_GETPWENT_R                   \\\n  COMMON_INTERCEPT_FUNCTION(getpwent_r);  \\\n  COMMON_INTERCEPT_FUNCTION(fgetpwent_r); \\\n  COMMON_INTERCEPT_FUNCTION(getgrent_r);  \\\n  COMMON_INTERCEPT_FUNCTION(fgetgrent_r);\n#else\n#define INIT_GETPWENT_R\n#endif\n\n#if SANITIZER_INTERCEPT_SETPWENT\n// The only thing these interceptors do is disable any nested interceptors.\n// These functions may open nss modules and call uninstrumented functions from\n// them, and we don't want things like strlen() to trigger.\nINTERCEPTOR(void, setpwent, int dummy) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);\n  REAL(setpwent)(dummy);\n}\nINTERCEPTOR(void, endpwent, int dummy) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);\n  REAL(endpwent)(dummy);\n}\nINTERCEPTOR(void, setgrent, int dummy) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);\n  REAL(setgrent)(dummy);\n}\nINTERCEPTOR(void, endgrent, int dummy) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);\n  REAL(endgrent)(dummy);\n}\n#define INIT_SETPWENT                  \\\n  COMMON_INTERCEPT_FUNCTION(setpwent); \\\n  COMMON_INTERCEPT_FUNCTION(endpwent); \\\n  COMMON_INTERCEPT_FUNCTION(setgrent); \\\n  COMMON_INTERCEPT_FUNCTION(endgrent);\n#else\n#define INIT_SETPWENT\n#endif\n\n#if SANITIZER_INTERCEPT_CLOCK_GETTIME\nINTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(clock_getres)(clk_id, tp);\n  if (!res && tp) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);\n  }\n  return res;\n}\nINTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(clock_gettime)(clk_id, tp);\n  if (!res) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);\n  }\n  return res;\n}\nINTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);\n  return REAL(clock_settime)(clk_id, tp);\n}\n#define INIT_CLOCK_GETTIME                  \\\n  COMMON_INTERCEPT_FUNCTION(clock_getres);  \\\n  COMMON_INTERCEPT_FUNCTION(clock_gettime); \\\n  COMMON_INTERCEPT_FUNCTION(clock_settime);\n#else\n#define INIT_CLOCK_GETTIME\n#endif\n\n#if SANITIZER_INTERCEPT_GETITIMER\nINTERCEPTOR(int, getitimer, int which, void *curr_value) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getitimer)(which, curr_value);\n  if (!res && curr_value) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);\n  }\n  return res;\n}\nINTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);\n  if (new_value)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(setitimer)(which, new_value, old_value);\n  if (!res && old_value) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);\n  }\n  return res;\n}\n#define INIT_GETITIMER                  \\\n  COMMON_INTERCEPT_FUNCTION(getitimer); \\\n  COMMON_INTERCEPT_FUNCTION(setitimer);\n#else\n#define INIT_GETITIMER\n#endif\n\n#if SANITIZER_INTERCEPT_GLOB\nstatic void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {\n  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));\n  // +1 for NULL pointer at the end.\n  if (pglob->gl_pathv)\n    COMMON_INTERCEPTOR_WRITE_RANGE(\n        ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));\n  for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {\n    char *p = pglob->gl_pathv[i];\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);\n  }\n}\n\nstatic THREADLOCAL __sanitizer_glob_t *pglob_copy;\n\nstatic void wrapped_gl_closedir(void *dir) {\n  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);\n  pglob_copy->gl_closedir(dir);\n}\n\nstatic void *wrapped_gl_readdir(void *dir) {\n  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);\n  return pglob_copy->gl_readdir(dir);\n}\n\nstatic void *wrapped_gl_opendir(const char *s) {\n  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);\n  return pglob_copy->gl_opendir(s);\n}\n\nstatic int wrapped_gl_lstat(const char *s, void *st) {\n  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);\n  return pglob_copy->gl_lstat(s, st);\n}\n\nstatic int wrapped_gl_stat(const char *s, void *st) {\n  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);\n  return pglob_copy->gl_stat(s, st);\n}\n\nstatic const __sanitizer_glob_t kGlobCopy = {\n      0,                  0,                   0,\n      0,                  wrapped_gl_closedir, wrapped_gl_readdir,\n      wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};\n\nINTERCEPTOR(int, glob, const char *pattern, int flags,\n            int (*errfunc)(const char *epath, int eerrno),\n            __sanitizer_glob_t *pglob) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);\n  COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);\n  __sanitizer_glob_t glob_copy;\n  internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));\n  if (flags & glob_altdirfunc) {\n    Swap(pglob->gl_closedir, glob_copy.gl_closedir);\n    Swap(pglob->gl_readdir, glob_copy.gl_readdir);\n    Swap(pglob->gl_opendir, glob_copy.gl_opendir);\n    Swap(pglob->gl_lstat, glob_copy.gl_lstat);\n    Swap(pglob->gl_stat, glob_copy.gl_stat);\n    pglob_copy = &glob_copy;\n  }\n  int res = REAL(glob)(pattern, flags, errfunc, pglob);\n  if (flags & glob_altdirfunc) {\n    Swap(pglob->gl_closedir, glob_copy.gl_closedir);\n    Swap(pglob->gl_readdir, glob_copy.gl_readdir);\n    Swap(pglob->gl_opendir, glob_copy.gl_opendir);\n    Swap(pglob->gl_lstat, glob_copy.gl_lstat);\n    Swap(pglob->gl_stat, glob_copy.gl_stat);\n  }\n  pglob_copy = 0;\n  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);\n  return res;\n}\n\nINTERCEPTOR(int, glob64, const char *pattern, int flags,\n            int (*errfunc)(const char *epath, int eerrno),\n            __sanitizer_glob_t *pglob) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);\n  COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);\n  __sanitizer_glob_t glob_copy;\n  internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));\n  if (flags & glob_altdirfunc) {\n    Swap(pglob->gl_closedir, glob_copy.gl_closedir);\n    Swap(pglob->gl_readdir, glob_copy.gl_readdir);\n    Swap(pglob->gl_opendir, glob_copy.gl_opendir);\n    Swap(pglob->gl_lstat, glob_copy.gl_lstat);\n    Swap(pglob->gl_stat, glob_copy.gl_stat);\n    pglob_copy = &glob_copy;\n  }\n  int res = REAL(glob64)(pattern, flags, errfunc, pglob);\n  if (flags & glob_altdirfunc) {\n    Swap(pglob->gl_closedir, glob_copy.gl_closedir);\n    Swap(pglob->gl_readdir, glob_copy.gl_readdir);\n    Swap(pglob->gl_opendir, glob_copy.gl_opendir);\n    Swap(pglob->gl_lstat, glob_copy.gl_lstat);\n    Swap(pglob->gl_stat, glob_copy.gl_stat);\n  }\n  pglob_copy = 0;\n  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);\n  return res;\n}\n#define INIT_GLOB                  \\\n  COMMON_INTERCEPT_FUNCTION(glob); \\\n  COMMON_INTERCEPT_FUNCTION(glob64);\n#else  // SANITIZER_INTERCEPT_GLOB\n#define INIT_GLOB\n#endif  // SANITIZER_INTERCEPT_GLOB\n\n#if SANITIZER_INTERCEPT_WAIT\n// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version\n// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for\n// details.\nINTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, wait, status);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(wait)(status);\n  if (res != -1 && status)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));\n  return res;\n}\n// On FreeBSD id_t is always 64-bit wide.\n#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)\nINTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop,\n                        int options) {\n#else\nINTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,\n                        int options) {\n#endif\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(waitid)(idtype, id, infop, options);\n  if (res != -1 && infop)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);\n  return res;\n}\nINTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(waitpid)(pid, status, options);\n  if (res != -1 && status)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));\n  return res;\n}\nINTERCEPTOR(int, wait3, int *status, int options, void *rusage) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(wait3)(status, options, rusage);\n  if (res != -1) {\n    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));\n    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);\n  }\n  return res;\n}\n#if SANITIZER_ANDROID\nINTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(__wait4)(pid, status, options, rusage);\n  if (res != -1) {\n    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));\n    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);\n  }\n  return res;\n}\n#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);\n#else\nINTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(wait4)(pid, status, options, rusage);\n  if (res != -1) {\n    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));\n    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);\n  }\n  return res;\n}\n#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);\n#endif  // SANITIZER_ANDROID\n#define INIT_WAIT                     \\\n  COMMON_INTERCEPT_FUNCTION(wait);    \\\n  COMMON_INTERCEPT_FUNCTION(waitid);  \\\n  COMMON_INTERCEPT_FUNCTION(waitpid); \\\n  COMMON_INTERCEPT_FUNCTION(wait3);\n#else\n#define INIT_WAIT\n#define INIT_WAIT4\n#endif\n\n#if SANITIZER_INTERCEPT_INET\nINTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);\n  uptr sz = __sanitizer_in_addr_sz(af);\n  if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);\n  // FIXME: figure out read size based on the address family.\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char *res = REAL(inet_ntop)(af, src, dst, size);\n  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);\n  return res;\n}\nINTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);\n  COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0);\n  // FIXME: figure out read size based on the address family.\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(inet_pton)(af, src, dst);\n  if (res == 1) {\n    uptr sz = __sanitizer_in_addr_sz(af);\n    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);\n  }\n  return res;\n}\n#define INIT_INET                       \\\n  COMMON_INTERCEPT_FUNCTION(inet_ntop); \\\n  COMMON_INTERCEPT_FUNCTION(inet_pton);\n#else\n#define INIT_INET\n#endif\n\n#if SANITIZER_INTERCEPT_INET\nINTERCEPTOR(int, inet_aton, const char *cp, void *dst) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);\n  if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(inet_aton)(cp, dst);\n  if (res != 0) {\n    uptr sz = __sanitizer_in_addr_sz(af_inet);\n    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);\n  }\n  return res;\n}\n#define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);\n#else\n#define INIT_INET_ATON\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM\nINTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(pthread_getschedparam)(thread, policy, param);\n  if (res == 0) {\n    if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));\n    if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));\n  }\n  return res;\n}\n#define INIT_PTHREAD_GETSCHEDPARAM \\\n  COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);\n#else\n#define INIT_PTHREAD_GETSCHEDPARAM\n#endif\n\n#if SANITIZER_INTERCEPT_GETADDRINFO\nINTERCEPTOR(int, getaddrinfo, char *node, char *service,\n            struct __sanitizer_addrinfo *hints,\n            struct __sanitizer_addrinfo **out) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);\n  if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);\n  if (service)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);\n  if (hints)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getaddrinfo)(node, service, hints, out);\n  if (res == 0 && out) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));\n    struct __sanitizer_addrinfo *p = *out;\n    while (p) {\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));\n      if (p->ai_addr)\n        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);\n      if (p->ai_canonname)\n        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,\n                                       REAL(strlen)(p->ai_canonname) + 1);\n      p = p->ai_next;\n    }\n  }\n  return res;\n}\n#define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);\n#else\n#define INIT_GETADDRINFO\n#endif\n\n#if SANITIZER_INTERCEPT_GETNAMEINFO\nINTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,\n            unsigned hostlen, char *serv, unsigned servlen, int flags) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,\n                           serv, servlen, flags);\n  // FIXME: consider adding READ_RANGE(sockaddr, salen)\n  // There is padding in in_addr that may make this too noisy\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res =\n      REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);\n  if (res == 0) {\n    if (host && hostlen)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);\n    if (serv && servlen)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);\n  }\n  return res;\n}\n#define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);\n#else\n#define INIT_GETNAMEINFO\n#endif\n\n#if SANITIZER_INTERCEPT_GETSOCKNAME\nINTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));\n  int addrlen_in = *addrlen;\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getsockname)(sock_fd, addr, addrlen);\n  if (res == 0) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));\n  }\n  return res;\n}\n#define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);\n#else\n#define INIT_GETSOCKNAME\n#endif\n\n#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R\nstatic void write_hostent(void *ctx, struct __sanitizer_hostent *h) {\n  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));\n  if (h->h_name)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);\n  char **p = h->h_aliases;\n  while (*p) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);\n    ++p;\n  }\n  COMMON_INTERCEPTOR_WRITE_RANGE(\n      ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));\n  p = h->h_addr_list;\n  while (*p) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);\n    ++p;\n  }\n  COMMON_INTERCEPTOR_WRITE_RANGE(\n      ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));\n}\n#endif\n\n#if SANITIZER_INTERCEPT_GETHOSTBYNAME\nINTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);\n  struct __sanitizer_hostent *res = REAL(gethostbyname)(name);\n  if (res) write_hostent(ctx, res);\n  return res;\n}\n\nINTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,\n            int type) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);\n  struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);\n  if (res) write_hostent(ctx, res);\n  return res;\n}\n\nINTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);\n  struct __sanitizer_hostent *res = REAL(gethostent)(fake);\n  if (res) write_hostent(ctx, res);\n  return res;\n}\n\nINTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);\n  struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);\n  if (res) write_hostent(ctx, res);\n  return res;\n}\n#define INIT_GETHOSTBYNAME                  \\\n  COMMON_INTERCEPT_FUNCTION(gethostent);    \\\n  COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \\\n  COMMON_INTERCEPT_FUNCTION(gethostbyname); \\\n  COMMON_INTERCEPT_FUNCTION(gethostbyname2);\n#else\n#define INIT_GETHOSTBYNAME\n#endif\n\n#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R\nINTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,\n            char *buf, SIZE_T buflen, __sanitizer_hostent **result,\n            int *h_errnop) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,\n                           h_errnop);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);\n  if (result) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));\n    if (res == 0 && *result) write_hostent(ctx, *result);\n  }\n  if (h_errnop)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));\n  return res;\n}\n#define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);\n#else\n#define INIT_GETHOSTBYNAME_R\n#endif\n\n#if SANITIZER_INTERCEPT_GETHOSTENT_R\nINTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,\n            SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,\n                           h_errnop);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);\n  if (result) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));\n    if (res == 0 && *result) write_hostent(ctx, *result);\n  }\n  if (h_errnop)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));\n  return res;\n}\n#define INIT_GETHOSTENT_R                  \\\n  COMMON_INTERCEPT_FUNCTION(gethostent_r);\n#else\n#define INIT_GETHOSTENT_R\n#endif\n\n#if SANITIZER_INTERCEPT_GETHOSTBYADDR_R\nINTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,\n            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,\n            __sanitizer_hostent **result, int *h_errnop) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,\n                           buflen, result, h_errnop);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,\n                                  h_errnop);\n  if (result) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));\n    if (res == 0 && *result) write_hostent(ctx, *result);\n  }\n  if (h_errnop)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));\n  return res;\n}\n#define INIT_GETHOSTBYADDR_R                  \\\n  COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);\n#else\n#define INIT_GETHOSTBYADDR_R\n#endif\n\n#if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R\nINTERCEPTOR(int, gethostbyname2_r, char *name, int af,\n            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,\n            __sanitizer_hostent **result, int *h_errnop) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,\n                           result, h_errnop);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res =\n      REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);\n  if (result) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));\n    if (res == 0 && *result) write_hostent(ctx, *result);\n  }\n  if (h_errnop)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));\n  return res;\n}\n#define INIT_GETHOSTBYNAME2_R                  \\\n  COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);\n#else\n#define INIT_GETHOSTBYNAME2_R\n#endif\n\n#if SANITIZER_INTERCEPT_GETSOCKOPT\nINTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,\n            int *optlen) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,\n                           optlen);\n  if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);\n  if (res == 0)\n    if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);\n  return res;\n}\n#define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);\n#else\n#define INIT_GETSOCKOPT\n#endif\n\n#if SANITIZER_INTERCEPT_ACCEPT\nINTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);\n  unsigned addrlen0 = 0;\n  if (addrlen) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));\n    addrlen0 = *addrlen;\n  }\n  int fd2 = REAL(accept)(fd, addr, addrlen);\n  if (fd2 >= 0) {\n    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);\n    if (addr && addrlen)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));\n  }\n  return fd2;\n}\n#define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);\n#else\n#define INIT_ACCEPT\n#endif\n\n#if SANITIZER_INTERCEPT_ACCEPT4\nINTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);\n  unsigned addrlen0 = 0;\n  if (addrlen) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));\n    addrlen0 = *addrlen;\n  }\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int fd2 = REAL(accept4)(fd, addr, addrlen, f);\n  if (fd2 >= 0) {\n    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);\n    if (addr && addrlen)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));\n  }\n  return fd2;\n}\n#define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);\n#else\n#define INIT_ACCEPT4\n#endif\n\n#if SANITIZER_INTERCEPT_MODF\nINTERCEPTOR(double, modf, double x, double *iptr) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  double res = REAL(modf)(x, iptr);\n  if (iptr) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));\n  }\n  return res;\n}\nINTERCEPTOR(float, modff, float x, float *iptr) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  float res = REAL(modff)(x, iptr);\n  if (iptr) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));\n  }\n  return res;\n}\nINTERCEPTOR(long double, modfl, long double x, long double *iptr) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  long double res = REAL(modfl)(x, iptr);\n  if (iptr) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));\n  }\n  return res;\n}\n#define INIT_MODF                   \\\n  COMMON_INTERCEPT_FUNCTION(modf);  \\\n  COMMON_INTERCEPT_FUNCTION(modff); \\\n  COMMON_INTERCEPT_FUNCTION(modfl);\n#else\n#define INIT_MODF\n#endif\n\n#if SANITIZER_INTERCEPT_RECVMSG\nstatic void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,\n                         SSIZE_T maxlen) {\n  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));\n  if (msg->msg_name && msg->msg_namelen)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);\n  if (msg->msg_iov && msg->msg_iovlen)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,\n                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);\n  write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);\n  if (msg->msg_control && msg->msg_controllen)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);\n}\n\nINTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,\n            int flags) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SSIZE_T res = REAL(recvmsg)(fd, msg, flags);\n  if (res >= 0) {\n    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);\n    if (msg) {\n      write_msghdr(ctx, msg, res);\n      COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);\n    }\n  }\n  return res;\n}\n#define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);\n#else\n#define INIT_RECVMSG\n#endif\n\n#if SANITIZER_INTERCEPT_GETPEERNAME\nINTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);\n  unsigned addr_sz;\n  if (addrlen) addr_sz = *addrlen;\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getpeername)(sockfd, addr, addrlen);\n  if (!res && addr && addrlen)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));\n  return res;\n}\n#define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);\n#else\n#define INIT_GETPEERNAME\n#endif\n\n#if SANITIZER_INTERCEPT_SYSINFO\nINTERCEPTOR(int, sysinfo, void *info) {\n  void *ctx;\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);\n  int res = REAL(sysinfo)(info);\n  if (!res && info)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);\n  return res;\n}\n#define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);\n#else\n#define INIT_SYSINFO\n#endif\n\n#if SANITIZER_INTERCEPT_READDIR\nINTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, opendir, path);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n  __sanitizer_dirent *res = REAL(opendir)(path);\n  if (res)\n    COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path);\n  return res;\n}\n\nINTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  __sanitizer_dirent *res = REAL(readdir)(dirp);\n  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);\n  return res;\n}\n\nINTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,\n            __sanitizer_dirent **result) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(readdir_r)(dirp, entry, result);\n  if (!res) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));\n    if (*result)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);\n  }\n  return res;\n}\n\n#define INIT_READDIR                  \\\n  COMMON_INTERCEPT_FUNCTION(opendir); \\\n  COMMON_INTERCEPT_FUNCTION(readdir); \\\n  COMMON_INTERCEPT_FUNCTION(readdir_r);\n#else\n#define INIT_READDIR\n#endif\n\n#if SANITIZER_INTERCEPT_READDIR64\nINTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  __sanitizer_dirent64 *res = REAL(readdir64)(dirp);\n  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);\n  return res;\n}\n\nINTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,\n            __sanitizer_dirent64 **result) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(readdir64_r)(dirp, entry, result);\n  if (!res) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));\n    if (*result)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);\n  }\n  return res;\n}\n#define INIT_READDIR64                  \\\n  COMMON_INTERCEPT_FUNCTION(readdir64); \\\n  COMMON_INTERCEPT_FUNCTION(readdir64_r);\n#else\n#define INIT_READDIR64\n#endif\n\n#if SANITIZER_INTERCEPT_PTRACE\nINTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);\n  __sanitizer_iovec local_iovec;\n\n  if (data) {\n    if (request == ptrace_setregs)\n      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);\n    else if (request == ptrace_setfpregs)\n      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);\n    else if (request == ptrace_setfpxregs)\n      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);\n    else if (request == ptrace_setvfpregs)\n      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz);\n    else if (request == ptrace_setsiginfo)\n      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);\n    // Some kernel might zero the iovec::iov_base in case of invalid\n    // write access.  In this case copy the invalid address for further\n    // inspection.\n    else if (request == ptrace_setregset || request == ptrace_getregset) {\n      __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;\n      COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec));\n      local_iovec = *iovec;\n      if (request == ptrace_setregset)\n        COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len);\n    }\n  }\n\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  uptr res = REAL(ptrace)(request, pid, addr, data);\n\n  if (!res && data) {\n    // Note that PEEK* requests assign different meaning to the return value.\n    // This function does not handle them (nor does it need to).\n    if (request == ptrace_getregs)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);\n    else if (request == ptrace_getfpregs)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);\n    else if (request == ptrace_getfpxregs)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);\n    else if (request == ptrace_getvfpregs)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz);\n    else if (request == ptrace_getsiginfo)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);\n    else if (request == ptrace_geteventmsg)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long));\n    else if (request == ptrace_getregset) {\n      __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec));\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base,\n                                     local_iovec.iov_len);\n    }\n  }\n  return res;\n}\n\n#define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);\n#else\n#define INIT_PTRACE\n#endif\n\n#if SANITIZER_INTERCEPT_SETLOCALE\nINTERCEPTOR(char *, setlocale, int category, char *locale) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);\n  if (locale)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);\n  char *res = REAL(setlocale)(category, locale);\n  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);\n  return res;\n}\n\n#define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);\n#else\n#define INIT_SETLOCALE\n#endif\n\n#if SANITIZER_INTERCEPT_GETCWD\nINTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char *res = REAL(getcwd)(buf, size);\n  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);\n  return res;\n}\n#define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);\n#else\n#define INIT_GETCWD\n#endif\n\n#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME\nINTERCEPTOR(char *, get_current_dir_name, int fake) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char *res = REAL(get_current_dir_name)(fake);\n  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);\n  return res;\n}\n\n#define INIT_GET_CURRENT_DIR_NAME \\\n  COMMON_INTERCEPT_FUNCTION(get_current_dir_name);\n#else\n#define INIT_GET_CURRENT_DIR_NAME\n#endif\n\nUNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {\n  CHECK(endptr);\n  if (nptr == *endptr) {\n    // No digits were found at strtol call, we need to find out the last\n    // symbol accessed by strtoll on our own.\n    // We get this symbol by skipping leading blanks and optional +/- sign.\n    while (IsSpace(*nptr)) nptr++;\n    if (*nptr == '+' || *nptr == '-') nptr++;\n    *endptr = const_cast<char *>(nptr);\n  }\n  CHECK(*endptr >= nptr);\n}\n\nUNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr,\n                             char **endptr, char *real_endptr, int base) {\n  if (endptr) {\n    *endptr = real_endptr;\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));\n  }\n  // If base has unsupported value, strtol can exit with EINVAL\n  // without reading any characters. So do additional checks only\n  // if base is valid.\n  bool is_valid_base = (base == 0) || (2 <= base && base <= 36);\n  if (is_valid_base) {\n    FixRealStrtolEndptr(nptr, &real_endptr);\n  }\n  COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ?\n                                 (real_endptr - nptr) + 1 : 0);\n}\n\n\n#if SANITIZER_INTERCEPT_STRTOIMAX\nINTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char *real_endptr;\n  INTMAX_T res = REAL(strtoimax)(nptr, &real_endptr, base);\n  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);\n  return res;\n}\n\nINTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char *real_endptr;\n  INTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base);\n  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);\n  return res;\n}\n\n#define INIT_STRTOIMAX                  \\\n  COMMON_INTERCEPT_FUNCTION(strtoimax); \\\n  COMMON_INTERCEPT_FUNCTION(strtoumax);\n#else\n#define INIT_STRTOIMAX\n#endif\n\n#if SANITIZER_INTERCEPT_MBSTOWCS\nINTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SIZE_T res = REAL(mbstowcs)(dest, src, len);\n  if (res != (SIZE_T) - 1 && dest) {\n    SIZE_T write_cnt = res + (res < len);\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));\n  }\n  return res;\n}\n\nINTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,\n            void *ps) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);\n  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));\n  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);\n  if (res != (SIZE_T)(-1) && dest && src) {\n    // This function, and several others, may or may not write the terminating\n    // \\0 character. They write it iff they clear *src.\n    SIZE_T write_cnt = res + !*src;\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));\n  }\n  return res;\n}\n\n#define INIT_MBSTOWCS                  \\\n  COMMON_INTERCEPT_FUNCTION(mbstowcs); \\\n  COMMON_INTERCEPT_FUNCTION(mbsrtowcs);\n#else\n#define INIT_MBSTOWCS\n#endif\n\n#if SANITIZER_INTERCEPT_MBSNRTOWCS\nINTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,\n            SIZE_T len, void *ps) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);\n  if (src) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));\n    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);\n  }\n  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);\n  if (res != (SIZE_T)(-1) && dest && src) {\n    SIZE_T write_cnt = res + !*src;\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));\n  }\n  return res;\n}\n\n#define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);\n#else\n#define INIT_MBSNRTOWCS\n#endif\n\n#if SANITIZER_INTERCEPT_WCSTOMBS\nINTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SIZE_T res = REAL(wcstombs)(dest, src, len);\n  if (res != (SIZE_T) - 1 && dest) {\n    SIZE_T write_cnt = res + (res < len);\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);\n  }\n  return res;\n}\n\nINTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,\n            void *ps) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);\n  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));\n  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);\n  if (res != (SIZE_T) - 1 && dest && src) {\n    SIZE_T write_cnt = res + !*src;\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);\n  }\n  return res;\n}\n\n#define INIT_WCSTOMBS                  \\\n  COMMON_INTERCEPT_FUNCTION(wcstombs); \\\n  COMMON_INTERCEPT_FUNCTION(wcsrtombs);\n#else\n#define INIT_WCSTOMBS\n#endif\n\n#if SANITIZER_INTERCEPT_WCSNRTOMBS\nINTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,\n            SIZE_T len, void *ps) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);\n  if (src) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));\n    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);\n  }\n  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);\n  if (res != ((SIZE_T)-1) && dest && src) {\n    SIZE_T write_cnt = res + !*src;\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);\n  }\n  return res;\n}\n\n#define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);\n#else\n#define INIT_WCSNRTOMBS\n#endif\n\n\n#if SANITIZER_INTERCEPT_WCRTOMB\nINTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);\n  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SIZE_T res = REAL(wcrtomb)(dest, src, ps);\n  if (res != ((SIZE_T)-1) && dest) {\n    SIZE_T write_cnt = res;\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);\n  }\n  return res;\n}\n\n#define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb);\n#else\n#define INIT_WCRTOMB\n#endif\n\n#if SANITIZER_INTERCEPT_TCGETATTR\nINTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(tcgetattr)(fd, termios_p);\n  if (!res && termios_p)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);\n  return res;\n}\n\n#define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);\n#else\n#define INIT_TCGETATTR\n#endif\n\n#if SANITIZER_INTERCEPT_REALPATH\nINTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);\n  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n\n  // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest\n  // version of a versioned symbol. For realpath(), this gives us something\n  // (called __old_realpath) that does not handle NULL in the second argument.\n  // Handle it as part of the interceptor.\n  char *allocated_path = nullptr;\n  if (!resolved_path)\n    allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);\n\n  char *res = REAL(realpath)(path, resolved_path);\n  if (allocated_path && !res) WRAP(free)(allocated_path);\n  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);\n  return res;\n}\n#define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);\n#else\n#define INIT_REALPATH\n#endif\n\n#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME\nINTERCEPTOR(char *, canonicalize_file_name, const char *path) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);\n  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n  char *res = REAL(canonicalize_file_name)(path);\n  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);\n  return res;\n}\n#define INIT_CANONICALIZE_FILE_NAME \\\n  COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);\n#else\n#define INIT_CANONICALIZE_FILE_NAME\n#endif\n\n#if SANITIZER_INTERCEPT_CONFSTR\nINTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SIZE_T res = REAL(confstr)(name, buf, len);\n  if (buf && res)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);\n  return res;\n}\n#define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);\n#else\n#define INIT_CONFSTR\n#endif\n\n#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY\nINTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);\n  if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);\n  return res;\n}\n#define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);\n#else\n#define INIT_SCHED_GETAFFINITY\n#endif\n\n#if SANITIZER_INTERCEPT_SCHED_GETPARAM\nINTERCEPTOR(int, sched_getparam, int pid, void *param) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param);\n  int res = REAL(sched_getparam)(pid, param);\n  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz);\n  return res;\n}\n#define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam);\n#else\n#define INIT_SCHED_GETPARAM\n#endif\n\n#if SANITIZER_INTERCEPT_STRERROR\nINTERCEPTOR(char *, strerror, int errnum) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);\n  char *res = REAL(strerror)(errnum);\n  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);\n  return res;\n}\n#define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);\n#else\n#define INIT_STRERROR\n#endif\n\n#if SANITIZER_INTERCEPT_STRERROR_R\nINTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char *res = REAL(strerror_r)(errnum, buf, buflen);\n  // There are 2 versions of strerror_r:\n  //  * POSIX version returns 0 on success, negative error code on failure,\n  //    writes message to buf.\n  //  * GNU version returns message pointer, which points to either buf or some\n  //    static storage.\n  SIZE_T posix_res = (SIZE_T)res;\n  if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) {\n    // POSIX version. Spec is not clear on whether buf is NULL-terminated.\n    // At least on OSX, buf contents are valid even when the call fails.\n    SIZE_T sz = internal_strnlen(buf, buflen);\n    if (sz < buflen) ++sz;\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);\n  } else {\n    // GNU version.\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);\n  }\n  return res;\n}\n#define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);\n#else\n#define INIT_STRERROR_R\n#endif\n\n#if SANITIZER_INTERCEPT_XPG_STRERROR_R\nINTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);\n  // This version always returns a null-terminated string.\n  if (buf && buflen)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);\n  return res;\n}\n#define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);\n#else\n#define INIT_XPG_STRERROR_R\n#endif\n\n#if SANITIZER_INTERCEPT_SCANDIR\ntypedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);\ntypedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,\n                                const struct __sanitizer_dirent **);\n\nstatic THREADLOCAL scandir_filter_f scandir_filter;\nstatic THREADLOCAL scandir_compar_f scandir_compar;\n\nstatic int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {\n  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);\n  return scandir_filter(dir);\n}\n\nstatic int wrapped_scandir_compar(const struct __sanitizer_dirent **a,\n                                  const struct __sanitizer_dirent **b) {\n  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);\n  return scandir_compar(a, b);\n}\n\nINTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,\n            scandir_filter_f filter, scandir_compar_f compar) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);\n  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);\n  scandir_filter = filter;\n  scandir_compar = compar;\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(scandir)(dirp, namelist,\n                          filter ? wrapped_scandir_filter : nullptr,\n                          compar ? wrapped_scandir_compar : nullptr);\n  scandir_filter = nullptr;\n  scandir_compar = nullptr;\n  if (namelist && res > 0) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);\n    for (int i = 0; i < res; ++i)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],\n                                     (*namelist)[i]->d_reclen);\n  }\n  return res;\n}\n#define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);\n#else\n#define INIT_SCANDIR\n#endif\n\n#if SANITIZER_INTERCEPT_SCANDIR64\ntypedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);\ntypedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,\n                                  const struct __sanitizer_dirent64 **);\n\nstatic THREADLOCAL scandir64_filter_f scandir64_filter;\nstatic THREADLOCAL scandir64_compar_f scandir64_compar;\n\nstatic int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {\n  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);\n  return scandir64_filter(dir);\n}\n\nstatic int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,\n                                    const struct __sanitizer_dirent64 **b) {\n  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);\n  return scandir64_compar(a, b);\n}\n\nINTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,\n            scandir64_filter_f filter, scandir64_compar_f compar) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);\n  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);\n  scandir64_filter = filter;\n  scandir64_compar = compar;\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res =\n      REAL(scandir64)(dirp, namelist,\n                      filter ? wrapped_scandir64_filter : nullptr,\n                      compar ? wrapped_scandir64_compar : nullptr);\n  scandir64_filter = nullptr;\n  scandir64_compar = nullptr;\n  if (namelist && res > 0) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);\n    for (int i = 0; i < res; ++i)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],\n                                     (*namelist)[i]->d_reclen);\n  }\n  return res;\n}\n#define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);\n#else\n#define INIT_SCANDIR64\n#endif\n\n#if SANITIZER_INTERCEPT_GETGROUPS\nINTERCEPTOR(int, getgroups, int size, u32 *lst) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getgroups)(size, lst);\n  if (res && lst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));\n  return res;\n}\n#define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);\n#else\n#define INIT_GETGROUPS\n#endif\n\n#if SANITIZER_INTERCEPT_POLL\nstatic void read_pollfd(void *ctx, __sanitizer_pollfd *fds,\n                        __sanitizer_nfds_t nfds) {\n  for (unsigned i = 0; i < nfds; ++i) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));\n  }\n}\n\nstatic void write_pollfd(void *ctx, __sanitizer_pollfd *fds,\n                         __sanitizer_nfds_t nfds) {\n  for (unsigned i = 0; i < nfds; ++i)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,\n                                   sizeof(fds[i].revents));\n}\n\nINTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,\n            int timeout) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);\n  if (fds && nfds) read_pollfd(ctx, fds, nfds);\n  int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);\n  if (fds && nfds) write_pollfd(ctx, fds, nfds);\n  return res;\n}\n#define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);\n#else\n#define INIT_POLL\n#endif\n\n#if SANITIZER_INTERCEPT_PPOLL\nINTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,\n            void *timeout_ts, __sanitizer_sigset_t *sigmask) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);\n  if (fds && nfds) read_pollfd(ctx, fds, nfds);\n  if (timeout_ts)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);\n  // FIXME: read sigmask when all of sigemptyset, etc are intercepted.\n  int res =\n      COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);\n  if (fds && nfds) write_pollfd(ctx, fds, nfds);\n  return res;\n}\n#define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);\n#else\n#define INIT_PPOLL\n#endif\n\n#if SANITIZER_INTERCEPT_WORDEXP\nINTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);\n  if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(wordexp)(s, p, flags);\n  if (!res && p) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));\n    if (p->we_wordc)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,\n                                     sizeof(*p->we_wordv) * p->we_wordc);\n    for (uptr i = 0; i < p->we_wordc; ++i) {\n      char *w = p->we_wordv[i];\n      if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1);\n    }\n  }\n  return res;\n}\n#define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);\n#else\n#define INIT_WORDEXP\n#endif\n\n#if SANITIZER_INTERCEPT_SIGWAIT\nINTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);\n  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(sigwait)(set, sig);\n  if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));\n  return res;\n}\n#define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);\n#else\n#define INIT_SIGWAIT\n#endif\n\n#if SANITIZER_INTERCEPT_SIGWAITINFO\nINTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);\n  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(sigwaitinfo)(set, info);\n  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);\n  return res;\n}\n#define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);\n#else\n#define INIT_SIGWAITINFO\n#endif\n\n#if SANITIZER_INTERCEPT_SIGTIMEDWAIT\nINTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,\n            void *timeout) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);\n  if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);\n  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(sigtimedwait)(set, info, timeout);\n  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);\n  return res;\n}\n#define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);\n#else\n#define INIT_SIGTIMEDWAIT\n#endif\n\n#if SANITIZER_INTERCEPT_SIGSETOPS\nINTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(sigemptyset)(set);\n  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));\n  return res;\n}\n\nINTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(sigfillset)(set);\n  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));\n  return res;\n}\n#define INIT_SIGSETOPS                    \\\n  COMMON_INTERCEPT_FUNCTION(sigemptyset); \\\n  COMMON_INTERCEPT_FUNCTION(sigfillset);\n#else\n#define INIT_SIGSETOPS\n#endif\n\n#if SANITIZER_INTERCEPT_SIGPENDING\nINTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(sigpending)(set);\n  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));\n  return res;\n}\n#define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);\n#else\n#define INIT_SIGPENDING\n#endif\n\n#if SANITIZER_INTERCEPT_SIGPROCMASK\nINTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,\n            __sanitizer_sigset_t *oldset) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);\n  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(sigprocmask)(how, set, oldset);\n  if (!res && oldset)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));\n  return res;\n}\n#define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);\n#else\n#define INIT_SIGPROCMASK\n#endif\n\n#if SANITIZER_INTERCEPT_BACKTRACE\nINTERCEPTOR(int, backtrace, void **buffer, int size) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(backtrace)(buffer, size);\n  if (res && buffer)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));\n  return res;\n}\n\nINTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);\n  if (buffer && size)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char **res = REAL(backtrace_symbols)(buffer, size);\n  if (res && size) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));\n    for (int i = 0; i < size; ++i)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1);\n  }\n  return res;\n}\n#define INIT_BACKTRACE                  \\\n  COMMON_INTERCEPT_FUNCTION(backtrace); \\\n  COMMON_INTERCEPT_FUNCTION(backtrace_symbols);\n#else\n#define INIT_BACKTRACE\n#endif\n\n#if SANITIZER_INTERCEPT__EXIT\nINTERCEPTOR(void, _exit, int status) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);\n  int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);\n  if (status == 0) status = status1;\n  REAL(_exit)(status);\n}\n#define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);\n#else\n#define INIT__EXIT\n#endif\n\n#if SANITIZER_INTERCEPT_PHTREAD_MUTEX\nINTERCEPTOR(int, pthread_mutex_lock, void *m) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);\n  int res = REAL(pthread_mutex_lock)(m);\n  if (res == errno_EOWNERDEAD)\n    COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);\n  if (res == 0 || res == errno_EOWNERDEAD)\n    COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_mutex_unlock, void *m) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);\n  COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);\n  return REAL(pthread_mutex_unlock)(m);\n}\n\n#define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock)\n#define INIT_PTHREAD_MUTEX_UNLOCK \\\n  COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock)\n#else\n#define INIT_PTHREAD_MUTEX_LOCK\n#define INIT_PTHREAD_MUTEX_UNLOCK\n#endif\n\n#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R\nstatic void write_mntent(void *ctx, __sanitizer_mntent *mnt) {\n  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));\n  if (mnt->mnt_fsname)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,\n                                   REAL(strlen)(mnt->mnt_fsname) + 1);\n  if (mnt->mnt_dir)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,\n                                   REAL(strlen)(mnt->mnt_dir) + 1);\n  if (mnt->mnt_type)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,\n                                   REAL(strlen)(mnt->mnt_type) + 1);\n  if (mnt->mnt_opts)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,\n                                   REAL(strlen)(mnt->mnt_opts) + 1);\n}\n#endif\n\n#if SANITIZER_INTERCEPT_GETMNTENT\nINTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);\n  __sanitizer_mntent *res = REAL(getmntent)(fp);\n  if (res) write_mntent(ctx, res);\n  return res;\n}\n#define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);\n#else\n#define INIT_GETMNTENT\n#endif\n\n#if SANITIZER_INTERCEPT_GETMNTENT_R\nINTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,\n            __sanitizer_mntent *mntbuf, char *buf, int buflen) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);\n  __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);\n  if (res) write_mntent(ctx, res);\n  return res;\n}\n#define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);\n#else\n#define INIT_GETMNTENT_R\n#endif\n\n#if SANITIZER_INTERCEPT_STATFS\nINTERCEPTOR(int, statfs, char *path, void *buf) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);\n  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(statfs)(path, buf);\n  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);\n  return res;\n}\nINTERCEPTOR(int, fstatfs, int fd, void *buf) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(fstatfs)(fd, buf);\n  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);\n  return res;\n}\n#define INIT_STATFS                  \\\n  COMMON_INTERCEPT_FUNCTION(statfs); \\\n  COMMON_INTERCEPT_FUNCTION(fstatfs);\n#else\n#define INIT_STATFS\n#endif\n\n#if SANITIZER_INTERCEPT_STATFS64\nINTERCEPTOR(int, statfs64, char *path, void *buf) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);\n  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(statfs64)(path, buf);\n  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);\n  return res;\n}\nINTERCEPTOR(int, fstatfs64, int fd, void *buf) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(fstatfs64)(fd, buf);\n  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);\n  return res;\n}\n#define INIT_STATFS64                  \\\n  COMMON_INTERCEPT_FUNCTION(statfs64); \\\n  COMMON_INTERCEPT_FUNCTION(fstatfs64);\n#else\n#define INIT_STATFS64\n#endif\n\n#if SANITIZER_INTERCEPT_STATVFS\nINTERCEPTOR(int, statvfs, char *path, void *buf) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);\n  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(statvfs)(path, buf);\n  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);\n  return res;\n}\nINTERCEPTOR(int, fstatvfs, int fd, void *buf) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(fstatvfs)(fd, buf);\n  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);\n  return res;\n}\n#define INIT_STATVFS                  \\\n  COMMON_INTERCEPT_FUNCTION(statvfs); \\\n  COMMON_INTERCEPT_FUNCTION(fstatvfs);\n#else\n#define INIT_STATVFS\n#endif\n\n#if SANITIZER_INTERCEPT_STATVFS64\nINTERCEPTOR(int, statvfs64, char *path, void *buf) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);\n  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(statvfs64)(path, buf);\n  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);\n  return res;\n}\nINTERCEPTOR(int, fstatvfs64, int fd, void *buf) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(fstatvfs64)(fd, buf);\n  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);\n  return res;\n}\n#define INIT_STATVFS64                  \\\n  COMMON_INTERCEPT_FUNCTION(statvfs64); \\\n  COMMON_INTERCEPT_FUNCTION(fstatvfs64);\n#else\n#define INIT_STATVFS64\n#endif\n\n#if SANITIZER_INTERCEPT_INITGROUPS\nINTERCEPTOR(int, initgroups, char *user, u32 group) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);\n  if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1);\n  int res = REAL(initgroups)(user, group);\n  return res;\n}\n#define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);\n#else\n#define INIT_INITGROUPS\n#endif\n\n#if SANITIZER_INTERCEPT_ETHER_NTOA_ATON\nINTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);\n  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));\n  char *res = REAL(ether_ntoa)(addr);\n  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);\n  return res;\n}\nINTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);\n  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);\n  __sanitizer_ether_addr *res = REAL(ether_aton)(buf);\n  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));\n  return res;\n}\n#define INIT_ETHER_NTOA_ATON             \\\n  COMMON_INTERCEPT_FUNCTION(ether_ntoa); \\\n  COMMON_INTERCEPT_FUNCTION(ether_aton);\n#else\n#define INIT_ETHER_NTOA_ATON\n#endif\n\n#if SANITIZER_INTERCEPT_ETHER_HOST\nINTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);\n  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(ether_ntohost)(hostname, addr);\n  if (!res && hostname)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);\n  return res;\n}\nINTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);\n  if (hostname)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(ether_hostton)(hostname, addr);\n  if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));\n  return res;\n}\nINTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,\n            char *hostname) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);\n  if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(ether_line)(line, addr, hostname);\n  if (!res) {\n    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));\n    if (hostname)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);\n  }\n  return res;\n}\n#define INIT_ETHER_HOST                     \\\n  COMMON_INTERCEPT_FUNCTION(ether_ntohost); \\\n  COMMON_INTERCEPT_FUNCTION(ether_hostton); \\\n  COMMON_INTERCEPT_FUNCTION(ether_line);\n#else\n#define INIT_ETHER_HOST\n#endif\n\n#if SANITIZER_INTERCEPT_ETHER_R\nINTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);\n  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char *res = REAL(ether_ntoa_r)(addr, buf);\n  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);\n  return res;\n}\nINTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,\n            __sanitizer_ether_addr *addr) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);\n  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);\n  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));\n  return res;\n}\n#define INIT_ETHER_R                       \\\n  COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \\\n  COMMON_INTERCEPT_FUNCTION(ether_aton_r);\n#else\n#define INIT_ETHER_R\n#endif\n\n#if SANITIZER_INTERCEPT_SHMCTL\nINTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(shmctl)(shmid, cmd, buf);\n  if (res >= 0) {\n    unsigned sz = 0;\n    if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)\n      sz = sizeof(__sanitizer_shmid_ds);\n    else if (cmd == shmctl_ipc_info)\n      sz = struct_shminfo_sz;\n    else if (cmd == shmctl_shm_info)\n      sz = struct_shm_info_sz;\n    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);\n  }\n  return res;\n}\n#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);\n#else\n#define INIT_SHMCTL\n#endif\n\n#if SANITIZER_INTERCEPT_RANDOM_R\nINTERCEPTOR(int, random_r, void *buf, u32 *result) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(random_r)(buf, result);\n  if (!res && result)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));\n  return res;\n}\n#define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);\n#else\n#define INIT_RANDOM_R\n#endif\n\n// FIXME: under ASan the REAL() call below may write to freed memory and corrupt\n// its metadata. See\n// https://github.com/google/sanitizers/issues/321.\n#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET ||              \\\n    SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \\\n    SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET ||         \\\n    SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET ||        \\\n    SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET ||          \\\n    SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET\n#define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz)            \\\n  INTERCEPTOR(int, fn, void *attr, void *r) {                  \\\n    void *ctx;                                                 \\\n    COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r);                \\\n    int res = REAL(fn)(attr, r);                               \\\n    if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \\\n    return res;                                                \\\n  }\n#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \\\n  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)\n#define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \\\n  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)\n#define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \\\n  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)\n#define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \\\n  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)\n#define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \\\n  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET\nINTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))\nINTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))\nINTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)\nINTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))\nINTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))\nINTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))\nINTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(pthread_attr_getstack)(attr, addr, size);\n  if (!res) {\n    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));\n    if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));\n  }\n  return res;\n}\n\n// We may need to call the real pthread_attr_getstack from the run-time\n// in sanitizer_common, but we don't want to include the interception headers\n// there. So, just define this function here.\nnamespace __sanitizer {\nextern \"C\" {\nint real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {\n  return REAL(pthread_attr_getstack)(attr, addr, size);\n}\n}  // extern \"C\"\n}  // namespace __sanitizer\n\n#define INIT_PTHREAD_ATTR_GET                             \\\n  COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \\\n  COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize);   \\\n  COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam);  \\\n  COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \\\n  COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope);       \\\n  COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize);   \\\n  COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);\n#else\n#define INIT_PTHREAD_ATTR_GET\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED\nINTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))\n\n#define INIT_PTHREAD_ATTR_GETINHERITSCHED \\\n  COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);\n#else\n#define INIT_PTHREAD_ATTR_GETINHERITSCHED\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP\nINTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,\n            void *cpuset) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,\n                           cpuset);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);\n  if (!res && cpusetsize && cpuset)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);\n  return res;\n}\n\n#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \\\n  COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);\n#else\n#define INIT_PTHREAD_ATTR_GETAFFINITY_NP\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED\nINTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))\n#define INIT_PTHREAD_MUTEXATTR_GETPSHARED \\\n  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);\n#else\n#define INIT_PTHREAD_MUTEXATTR_GETPSHARED\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE\nINTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))\n#define INIT_PTHREAD_MUTEXATTR_GETTYPE \\\n  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);\n#else\n#define INIT_PTHREAD_MUTEXATTR_GETTYPE\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL\nINTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))\n#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \\\n  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);\n#else\n#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING\nINTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))\n#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \\\n  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);\n#else\n#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST\nINTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))\n#define INIT_PTHREAD_MUTEXATTR_GETROBUST \\\n  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);\n#else\n#define INIT_PTHREAD_MUTEXATTR_GETROBUST\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP\nINTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))\n#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \\\n  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);\n#else\n#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED\nINTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))\n#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \\\n  COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);\n#else\n#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP\nINTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))\n#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \\\n  COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);\n#else\n#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED\nINTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))\n#define INIT_PTHREAD_CONDATTR_GETPSHARED \\\n  COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);\n#else\n#define INIT_PTHREAD_CONDATTR_GETPSHARED\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK\nINTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))\n#define INIT_PTHREAD_CONDATTR_GETCLOCK \\\n  COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);\n#else\n#define INIT_PTHREAD_CONDATTR_GETCLOCK\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED\nINTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android\n#define INIT_PTHREAD_BARRIERATTR_GETPSHARED \\\n  COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);\n#else\n#define INIT_PTHREAD_BARRIERATTR_GETPSHARED\n#endif\n\n#if SANITIZER_INTERCEPT_TMPNAM\nINTERCEPTOR(char *, tmpnam, char *s) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);\n  char *res = REAL(tmpnam)(s);\n  if (res) {\n    if (s)\n      // FIXME: under ASan the call below may write to freed memory and corrupt\n      // its metadata. See\n      // https://github.com/google/sanitizers/issues/321.\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);\n    else\n      COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);\n  }\n  return res;\n}\n#define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);\n#else\n#define INIT_TMPNAM\n#endif\n\n#if SANITIZER_INTERCEPT_TMPNAM_R\nINTERCEPTOR(char *, tmpnam_r, char *s) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char *res = REAL(tmpnam_r)(s);\n  if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);\n  return res;\n}\n#define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);\n#else\n#define INIT_TMPNAM_R\n#endif\n\n#if SANITIZER_INTERCEPT_TEMPNAM\nINTERCEPTOR(char *, tempnam, char *dir, char *pfx) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);\n  if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1);\n  if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1);\n  char *res = REAL(tempnam)(dir, pfx);\n  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);\n  return res;\n}\n#define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);\n#else\n#define INIT_TEMPNAM\n#endif\n\n#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP\nINTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);\n  COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);\n  COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);\n  return REAL(pthread_setname_np)(thread, name);\n}\n#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);\n#else\n#define INIT_PTHREAD_SETNAME_NP\n#endif\n\n#if SANITIZER_INTERCEPT_SINCOS\nINTERCEPTOR(void, sincos, double x, double *sin, double *cos) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  REAL(sincos)(x, sin, cos);\n  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));\n  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));\n}\nINTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  REAL(sincosf)(x, sin, cos);\n  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));\n  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));\n}\nINTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  REAL(sincosl)(x, sin, cos);\n  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));\n  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));\n}\n#define INIT_SINCOS                   \\\n  COMMON_INTERCEPT_FUNCTION(sincos);  \\\n  COMMON_INTERCEPT_FUNCTION(sincosf); \\\n  COMMON_INTERCEPT_FUNCTION(sincosl);\n#else\n#define INIT_SINCOS\n#endif\n\n#if SANITIZER_INTERCEPT_REMQUO\nINTERCEPTOR(double, remquo, double x, double y, int *quo) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  double res = REAL(remquo)(x, y, quo);\n  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));\n  return res;\n}\nINTERCEPTOR(float, remquof, float x, float y, int *quo) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  float res = REAL(remquof)(x, y, quo);\n  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));\n  return res;\n}\nINTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  long double res = REAL(remquol)(x, y, quo);\n  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));\n  return res;\n}\n#define INIT_REMQUO                   \\\n  COMMON_INTERCEPT_FUNCTION(remquo);  \\\n  COMMON_INTERCEPT_FUNCTION(remquof); \\\n  COMMON_INTERCEPT_FUNCTION(remquol);\n#else\n#define INIT_REMQUO\n#endif\n\n#if SANITIZER_INTERCEPT_LGAMMA\nextern int signgam;\nINTERCEPTOR(double, lgamma, double x) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);\n  double res = REAL(lgamma)(x);\n  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));\n  return res;\n}\nINTERCEPTOR(float, lgammaf, float x) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);\n  float res = REAL(lgammaf)(x);\n  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));\n  return res;\n}\nINTERCEPTOR(long double, lgammal, long double x) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);\n  long double res = REAL(lgammal)(x);\n  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));\n  return res;\n}\n#define INIT_LGAMMA                   \\\n  COMMON_INTERCEPT_FUNCTION(lgamma);  \\\n  COMMON_INTERCEPT_FUNCTION(lgammaf); \\\n  COMMON_INTERCEPT_FUNCTION(lgammal);\n#else\n#define INIT_LGAMMA\n#endif\n\n#if SANITIZER_INTERCEPT_LGAMMA_R\nINTERCEPTOR(double, lgamma_r, double x, int *signp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  double res = REAL(lgamma_r)(x, signp);\n  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));\n  return res;\n}\nINTERCEPTOR(float, lgammaf_r, float x, int *signp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  float res = REAL(lgammaf_r)(x, signp);\n  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));\n  return res;\n}\n#define INIT_LGAMMA_R                   \\\n  COMMON_INTERCEPT_FUNCTION(lgamma_r);  \\\n  COMMON_INTERCEPT_FUNCTION(lgammaf_r);\n#else\n#define INIT_LGAMMA_R\n#endif\n\n#if SANITIZER_INTERCEPT_LGAMMAL_R\nINTERCEPTOR(long double, lgammal_r, long double x, int *signp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  long double res = REAL(lgammal_r)(x, signp);\n  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));\n  return res;\n}\n#define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION(lgammal_r);\n#else\n#define INIT_LGAMMAL_R\n#endif\n\n#if SANITIZER_INTERCEPT_DRAND48_R\nINTERCEPTOR(int, drand48_r, void *buffer, double *result) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(drand48_r)(buffer, result);\n  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));\n  return res;\n}\nINTERCEPTOR(int, lrand48_r, void *buffer, long *result) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(lrand48_r)(buffer, result);\n  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));\n  return res;\n}\n#define INIT_DRAND48_R                  \\\n  COMMON_INTERCEPT_FUNCTION(drand48_r); \\\n  COMMON_INTERCEPT_FUNCTION(lrand48_r);\n#else\n#define INIT_DRAND48_R\n#endif\n\n#if SANITIZER_INTERCEPT_RAND_R\nINTERCEPTOR(int, rand_r, unsigned *seedp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));\n  return REAL(rand_r)(seedp);\n}\n#define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);\n#else\n#define INIT_RAND_R\n#endif\n\n#if SANITIZER_INTERCEPT_GETLINE\nINTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SSIZE_T res = REAL(getline)(lineptr, n, stream);\n  if (res > 0) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);\n  }\n  return res;\n}\n\n// FIXME: under ASan the call below may write to freed memory and corrupt its\n// metadata. See\n// https://github.com/google/sanitizers/issues/321.\n#define GETDELIM_INTERCEPTOR_IMPL(vname)                                       \\\n  {                                                                            \\\n    void *ctx;                                                                 \\\n    COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream);           \\\n    SSIZE_T res = REAL(vname)(lineptr, n, delim, stream);                      \\\n    if (res > 0) {                                                             \\\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));          \\\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));                      \\\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);                  \\\n    }                                                                          \\\n    return res;                                                                \\\n  }\n\nINTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,\n            void *stream)\nGETDELIM_INTERCEPTOR_IMPL(__getdelim)\n\n// There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor\n// with its own body.\nINTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,\n            void *stream)\nGETDELIM_INTERCEPTOR_IMPL(getdelim)\n\n#define INIT_GETLINE                     \\\n  COMMON_INTERCEPT_FUNCTION(getline);    \\\n  COMMON_INTERCEPT_FUNCTION(__getdelim); \\\n  COMMON_INTERCEPT_FUNCTION(getdelim);\n#else\n#define INIT_GETLINE\n#endif\n\n#if SANITIZER_INTERCEPT_ICONV\nINTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,\n            char **outbuf, SIZE_T *outbytesleft) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,\n                           outbytesleft);\n  if (inbytesleft)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));\n  if (inbuf && inbytesleft)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);\n  if (outbytesleft)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));\n  void *outbuf_orig = outbuf ? *outbuf : nullptr;\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);\n  if (res != (SIZE_T) - 1 && outbuf && *outbuf > outbuf_orig) {\n    SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);\n  }\n  return res;\n}\n#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);\n#else\n#define INIT_ICONV\n#endif\n\n#if SANITIZER_INTERCEPT_TIMES\nINTERCEPTOR(__sanitizer_clock_t, times, void *tms) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, times, tms);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  __sanitizer_clock_t res = REAL(times)(tms);\n  if (res != (__sanitizer_clock_t)-1 && tms)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);\n  return res;\n}\n#define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);\n#else\n#define INIT_TIMES\n#endif\n\n#if SANITIZER_INTERCEPT_TLS_GET_ADDR\n#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)\n// If you see any crashes around this functions, there are 2 known issues with\n// it: 1. __tls_get_addr can be called with mis-aligned stack due to:\n// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066\n// 2. It can be called recursively if sanitizer code uses __tls_get_addr\n// to access thread local variables (it should not happen normally,\n// because sanitizers use initial-exec tls model).\nINTERCEPTOR(void *, __tls_get_addr, void *arg) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);\n  void *res = REAL(__tls_get_addr)(arg);\n  uptr tls_begin, tls_end;\n  COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);\n  DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);\n  if (dtv) {\n    // New DTLS block has been allocated.\n    COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);\n  }\n  return res;\n}\n#else\n#define INIT_TLS_GET_ADDR\n#endif\n\n#if SANITIZER_INTERCEPT_LISTXATTR\nINTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);\n  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SSIZE_T res = REAL(listxattr)(path, list, size);\n  // Here and below, size == 0 is a special case where nothing is written to the\n  // buffer, and res contains the desired buffer size.\n  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);\n  return res;\n}\nINTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);\n  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SSIZE_T res = REAL(llistxattr)(path, list, size);\n  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);\n  return res;\n}\nINTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SSIZE_T res = REAL(flistxattr)(fd, list, size);\n  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);\n  return res;\n}\n#define INIT_LISTXATTR                   \\\n  COMMON_INTERCEPT_FUNCTION(listxattr);  \\\n  COMMON_INTERCEPT_FUNCTION(llistxattr); \\\n  COMMON_INTERCEPT_FUNCTION(flistxattr);\n#else\n#define INIT_LISTXATTR\n#endif\n\n#if SANITIZER_INTERCEPT_GETXATTR\nINTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,\n            SIZE_T size) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);\n  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SSIZE_T res = REAL(getxattr)(path, name, value, size);\n  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);\n  return res;\n}\nINTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,\n            SIZE_T size) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);\n  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SSIZE_T res = REAL(lgetxattr)(path, name, value, size);\n  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);\n  return res;\n}\nINTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,\n            SIZE_T size) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);\n  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);\n  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);\n  return res;\n}\n#define INIT_GETXATTR                   \\\n  COMMON_INTERCEPT_FUNCTION(getxattr);  \\\n  COMMON_INTERCEPT_FUNCTION(lgetxattr); \\\n  COMMON_INTERCEPT_FUNCTION(fgetxattr);\n#else\n#define INIT_GETXATTR\n#endif\n\n#if SANITIZER_INTERCEPT_GETRESID\nINTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getresuid)(ruid, euid, suid);\n  if (res >= 0) {\n    if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);\n    if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);\n    if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);\n  }\n  return res;\n}\nINTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getresgid)(rgid, egid, sgid);\n  if (res >= 0) {\n    if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);\n    if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);\n    if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);\n  }\n  return res;\n}\n#define INIT_GETRESID                   \\\n  COMMON_INTERCEPT_FUNCTION(getresuid); \\\n  COMMON_INTERCEPT_FUNCTION(getresgid);\n#else\n#define INIT_GETRESID\n#endif\n\n#if SANITIZER_INTERCEPT_GETIFADDRS\n// As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to\n// intercept freeifaddrs(). If that ceases to be the case, we might need to\n// intercept it to poison the memory again.\nINTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(getifaddrs)(ifap);\n  if (res == 0 && ifap) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));\n    __sanitizer_ifaddrs *p = *ifap;\n    while (p) {\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));\n      if (p->ifa_name)\n        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,\n                                       REAL(strlen)(p->ifa_name) + 1);\n      if (p->ifa_addr)\n        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);\n      if (p->ifa_netmask)\n        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);\n      // On Linux this is a union, but the other member also points to a\n      // struct sockaddr, so the following is sufficient.\n      if (p->ifa_dstaddr)\n        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);\n      // FIXME(smatveev): Unpoison p->ifa_data as well.\n      p = p->ifa_next;\n    }\n  }\n  return res;\n}\n#define INIT_GETIFADDRS                  \\\n  COMMON_INTERCEPT_FUNCTION(getifaddrs);\n#else\n#define INIT_GETIFADDRS\n#endif\n\n#if SANITIZER_INTERCEPT_IF_INDEXTONAME\nINTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  char *res = REAL(if_indextoname)(ifindex, ifname);\n  if (res && ifname)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);\n  return res;\n}\nINTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);\n  if (ifname)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);\n  return REAL(if_nametoindex)(ifname);\n}\n#define INIT_IF_INDEXTONAME                  \\\n  COMMON_INTERCEPT_FUNCTION(if_indextoname); \\\n  COMMON_INTERCEPT_FUNCTION(if_nametoindex);\n#else\n#define INIT_IF_INDEXTONAME\n#endif\n\n#if SANITIZER_INTERCEPT_CAPGET\nINTERCEPTOR(int, capget, void *hdrp, void *datap) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);\n  if (hdrp)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(capget)(hdrp, datap);\n  if (res == 0 && datap)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz);\n  // We can also return -1 and write to hdrp->version if the version passed in\n  // hdrp->version is unsupported. But that's not a trivial condition to check,\n  // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.\n  return res;\n}\nINTERCEPTOR(int, capset, void *hdrp, const void *datap) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);\n  if (hdrp)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);\n  if (datap)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz);\n  return REAL(capset)(hdrp, datap);\n}\n#define INIT_CAPGET                  \\\n  COMMON_INTERCEPT_FUNCTION(capget); \\\n  COMMON_INTERCEPT_FUNCTION(capset);\n#else\n#define INIT_CAPGET\n#endif\n\n#if SANITIZER_INTERCEPT_AEABI_MEM\nDECLARE_REAL_AND_INTERCEPTOR(void *, memmove, void *, const void *, uptr)\nDECLARE_REAL_AND_INTERCEPTOR(void *, memcpy, void *, const void *, uptr)\nDECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr)\n\nINTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) {\n  return WRAP(memmove)(to, from, size);\n}\nINTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) {\n  return WRAP(memmove)(to, from, size);\n}\nINTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) {\n  return WRAP(memmove)(to, from, size);\n}\nINTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) {\n  return WRAP(memcpy)(to, from, size);\n}\nINTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) {\n  return WRAP(memcpy)(to, from, size);\n}\nINTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) {\n  return WRAP(memcpy)(to, from, size);\n}\n// Note the argument order.\nINTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) {\n  return WRAP(memset)(block, c, size);\n}\nINTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) {\n  return WRAP(memset)(block, c, size);\n}\nINTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) {\n  return WRAP(memset)(block, c, size);\n}\nINTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) {\n  return WRAP(memset)(block, 0, size);\n}\nINTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) {\n  return WRAP(memset)(block, 0, size);\n}\nINTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) {\n  return WRAP(memset)(block, 0, size);\n}\n#define INIT_AEABI_MEM                         \\\n  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove);  \\\n  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \\\n  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \\\n  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy);   \\\n  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4);  \\\n  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8);  \\\n  COMMON_INTERCEPT_FUNCTION(__aeabi_memset);   \\\n  COMMON_INTERCEPT_FUNCTION(__aeabi_memset4);  \\\n  COMMON_INTERCEPT_FUNCTION(__aeabi_memset8);  \\\n  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr);   \\\n  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4);  \\\n  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8);\n#else\n#define INIT_AEABI_MEM\n#endif  // SANITIZER_INTERCEPT_AEABI_MEM\n\n#if SANITIZER_INTERCEPT___BZERO\nDECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr);\n\nINTERCEPTOR(void *, __bzero, void *block, uptr size) {\n  return WRAP(memset)(block, 0, size);\n}\n#define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);\n#else\n#define INIT___BZERO\n#endif  // SANITIZER_INTERCEPT___BZERO\n\n#if SANITIZER_INTERCEPT_FTIME\nINTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(ftime)(tp);\n  if (tp)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));\n  return res;\n}\n#define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);\n#else\n#define INIT_FTIME\n#endif  // SANITIZER_INTERCEPT_FTIME\n\n#if SANITIZER_INTERCEPT_XDR\nINTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,\n            unsigned size, int op) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  REAL(xdrmem_create)(xdrs, addr, size, op);\n  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));\n  if (op == __sanitizer_XDR_ENCODE) {\n    // It's not obvious how much data individual xdr_ routines write.\n    // Simply unpoison the entire target buffer in advance.\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);\n  }\n}\n\nINTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  REAL(xdrstdio_create)(xdrs, file, op);\n  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));\n}\n\n// FIXME: under ASan the call below may write to freed memory and corrupt\n// its metadata. See\n// https://github.com/google/sanitizers/issues/321.\n#define XDR_INTERCEPTOR(F, T)                             \\\n  INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) {      \\\n    void *ctx;                                            \\\n    COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p);            \\\n    if (p && xdrs->x_op == __sanitizer_XDR_ENCODE)        \\\n      COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));  \\\n    int res = REAL(F)(xdrs, p);                           \\\n    if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \\\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \\\n    return res;                                           \\\n  }\n\nXDR_INTERCEPTOR(xdr_short, short)\nXDR_INTERCEPTOR(xdr_u_short, unsigned short)\nXDR_INTERCEPTOR(xdr_int, int)\nXDR_INTERCEPTOR(xdr_u_int, unsigned)\nXDR_INTERCEPTOR(xdr_long, long)\nXDR_INTERCEPTOR(xdr_u_long, unsigned long)\nXDR_INTERCEPTOR(xdr_hyper, long long)\nXDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)\nXDR_INTERCEPTOR(xdr_longlong_t, long long)\nXDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)\nXDR_INTERCEPTOR(xdr_int8_t, u8)\nXDR_INTERCEPTOR(xdr_uint8_t, u8)\nXDR_INTERCEPTOR(xdr_int16_t, u16)\nXDR_INTERCEPTOR(xdr_uint16_t, u16)\nXDR_INTERCEPTOR(xdr_int32_t, u32)\nXDR_INTERCEPTOR(xdr_uint32_t, u32)\nXDR_INTERCEPTOR(xdr_int64_t, u64)\nXDR_INTERCEPTOR(xdr_uint64_t, u64)\nXDR_INTERCEPTOR(xdr_quad_t, long long)\nXDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)\nXDR_INTERCEPTOR(xdr_bool, bool)\nXDR_INTERCEPTOR(xdr_enum, int)\nXDR_INTERCEPTOR(xdr_char, char)\nXDR_INTERCEPTOR(xdr_u_char, unsigned char)\nXDR_INTERCEPTOR(xdr_float, float)\nXDR_INTERCEPTOR(xdr_double, double)\n\n// FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,\n// wrapstring, sizeof\n\nINTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,\n            unsigned maxsize) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);\n  if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);\n  }\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize);\n  if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));\n    if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);\n  }\n  return res;\n}\n\nINTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,\n            unsigned maxsize) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);\n  if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1);\n  }\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  int res = REAL(xdr_string)(xdrs, p, maxsize);\n  if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));\n    if (res && *p)\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);\n  }\n  return res;\n}\n\n#define INIT_XDR                               \\\n  COMMON_INTERCEPT_FUNCTION(xdrmem_create);    \\\n  COMMON_INTERCEPT_FUNCTION(xdrstdio_create);  \\\n  COMMON_INTERCEPT_FUNCTION(xdr_short);        \\\n  COMMON_INTERCEPT_FUNCTION(xdr_u_short);      \\\n  COMMON_INTERCEPT_FUNCTION(xdr_int);          \\\n  COMMON_INTERCEPT_FUNCTION(xdr_u_int);        \\\n  COMMON_INTERCEPT_FUNCTION(xdr_long);         \\\n  COMMON_INTERCEPT_FUNCTION(xdr_u_long);       \\\n  COMMON_INTERCEPT_FUNCTION(xdr_hyper);        \\\n  COMMON_INTERCEPT_FUNCTION(xdr_u_hyper);      \\\n  COMMON_INTERCEPT_FUNCTION(xdr_longlong_t);   \\\n  COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \\\n  COMMON_INTERCEPT_FUNCTION(xdr_int8_t);       \\\n  COMMON_INTERCEPT_FUNCTION(xdr_uint8_t);      \\\n  COMMON_INTERCEPT_FUNCTION(xdr_int16_t);      \\\n  COMMON_INTERCEPT_FUNCTION(xdr_uint16_t);     \\\n  COMMON_INTERCEPT_FUNCTION(xdr_int32_t);      \\\n  COMMON_INTERCEPT_FUNCTION(xdr_uint32_t);     \\\n  COMMON_INTERCEPT_FUNCTION(xdr_int64_t);      \\\n  COMMON_INTERCEPT_FUNCTION(xdr_uint64_t);     \\\n  COMMON_INTERCEPT_FUNCTION(xdr_quad_t);       \\\n  COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t);     \\\n  COMMON_INTERCEPT_FUNCTION(xdr_bool);         \\\n  COMMON_INTERCEPT_FUNCTION(xdr_enum);         \\\n  COMMON_INTERCEPT_FUNCTION(xdr_char);         \\\n  COMMON_INTERCEPT_FUNCTION(xdr_u_char);       \\\n  COMMON_INTERCEPT_FUNCTION(xdr_float);        \\\n  COMMON_INTERCEPT_FUNCTION(xdr_double);       \\\n  COMMON_INTERCEPT_FUNCTION(xdr_bytes);        \\\n  COMMON_INTERCEPT_FUNCTION(xdr_string);\n#else\n#define INIT_XDR\n#endif  // SANITIZER_INTERCEPT_XDR\n\n#if SANITIZER_INTERCEPT_TSEARCH\nINTERCEPTOR(void *, tsearch, void *key, void **rootp,\n            int (*compar)(const void *, const void *)) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  void *res = REAL(tsearch)(key, rootp, compar);\n  if (res && *(void **)res == key)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));\n  return res;\n}\n#define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);\n#else\n#define INIT_TSEARCH\n#endif\n\n#if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \\\n    SANITIZER_INTERCEPT_OPEN_MEMSTREAM\nvoid unpoison_file(__sanitizer_FILE *fp) {\n#if SANITIZER_HAS_STRUCT_FILE\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));\n  if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)\n    COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,\n                                        fp->_IO_read_end - fp->_IO_read_base);\n#endif  // SANITIZER_HAS_STRUCT_FILE\n}\n#endif\n\n#if SANITIZER_INTERCEPT_LIBIO_INTERNALS\n// These guys are called when a .c source is built with -O2.\nINTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);\n  int res = REAL(__uflow)(fp);\n  unpoison_file(fp);\n  return res;\n}\nINTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);\n  int res = REAL(__underflow)(fp);\n  unpoison_file(fp);\n  return res;\n}\nINTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);\n  int res = REAL(__overflow)(fp, ch);\n  unpoison_file(fp);\n  return res;\n}\nINTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);\n  int res = REAL(__wuflow)(fp);\n  unpoison_file(fp);\n  return res;\n}\nINTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);\n  int res = REAL(__wunderflow)(fp);\n  unpoison_file(fp);\n  return res;\n}\nINTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);\n  int res = REAL(__woverflow)(fp, ch);\n  unpoison_file(fp);\n  return res;\n}\n#define INIT_LIBIO_INTERNALS               \\\n  COMMON_INTERCEPT_FUNCTION(__uflow);      \\\n  COMMON_INTERCEPT_FUNCTION(__underflow);  \\\n  COMMON_INTERCEPT_FUNCTION(__overflow);   \\\n  COMMON_INTERCEPT_FUNCTION(__wuflow);     \\\n  COMMON_INTERCEPT_FUNCTION(__wunderflow); \\\n  COMMON_INTERCEPT_FUNCTION(__woverflow);\n#else\n#define INIT_LIBIO_INTERNALS\n#endif\n\n#if SANITIZER_INTERCEPT_FOPEN\nINTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);\n  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);\n  __sanitizer_FILE *res = REAL(fopen)(path, mode);\n  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);\n  if (res) unpoison_file(res);\n  return res;\n}\nINTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);\n  __sanitizer_FILE *res = REAL(fdopen)(fd, mode);\n  if (res) unpoison_file(res);\n  return res;\n}\nINTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,\n            __sanitizer_FILE *fp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);\n  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);\n  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);\n  __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);\n  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);\n  if (res) unpoison_file(res);\n  return res;\n}\n#define INIT_FOPEN                   \\\n  COMMON_INTERCEPT_FUNCTION(fopen);  \\\n  COMMON_INTERCEPT_FUNCTION(fdopen); \\\n  COMMON_INTERCEPT_FUNCTION(freopen);\n#else\n#define INIT_FOPEN\n#endif\n\n#if SANITIZER_INTERCEPT_FOPEN64\nINTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);\n  __sanitizer_FILE *res = REAL(fopen64)(path, mode);\n  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);\n  if (res) unpoison_file(res);\n  return res;\n}\nINTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,\n            __sanitizer_FILE *fp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);\n  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);\n  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);\n  __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);\n  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);\n  if (res) unpoison_file(res);\n  return res;\n}\n#define INIT_FOPEN64                  \\\n  COMMON_INTERCEPT_FUNCTION(fopen64); \\\n  COMMON_INTERCEPT_FUNCTION(freopen64);\n#else\n#define INIT_FOPEN64\n#endif\n\n#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM\nINTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);\n  if (res) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));\n    unpoison_file(res);\n    FileMetadata file = {ptr, sizeloc};\n    SetInterceptorMetadata(res, file);\n  }\n  return res;\n}\nINTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,\n            SIZE_T *sizeloc) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);\n  __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);\n  if (res) {\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));\n    unpoison_file(res);\n    FileMetadata file = {(char **)ptr, sizeloc};\n    SetInterceptorMetadata(res, file);\n  }\n  return res;\n}\nINTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,\n            const char *mode) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);\n  // FIXME: under ASan the call below may write to freed memory and corrupt\n  // its metadata. See\n  // https://github.com/google/sanitizers/issues/321.\n  __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);\n  if (res) unpoison_file(res);\n  return res;\n}\n#define INIT_OPEN_MEMSTREAM                   \\\n  COMMON_INTERCEPT_FUNCTION(open_memstream);  \\\n  COMMON_INTERCEPT_FUNCTION(open_wmemstream); \\\n  COMMON_INTERCEPT_FUNCTION(fmemopen);\n#else\n#define INIT_OPEN_MEMSTREAM\n#endif\n\n#if SANITIZER_INTERCEPT_OBSTACK\nstatic void initialize_obstack(__sanitizer_obstack *obstack) {\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));\n  if (obstack->chunk)\n    COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,\n                                        sizeof(*obstack->chunk));\n}\n\nINTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,\n            int align, void *(*alloc_fn)(uptr arg, uptr sz),\n            void (*free_fn)(uptr arg, void *p)) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,\n                           free_fn);\n  int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);\n  if (res) initialize_obstack(obstack);\n  return res;\n}\nINTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,\n            int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,\n                           free_fn);\n  int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);\n  if (res) initialize_obstack(obstack);\n  return res;\n}\nINTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);\n  REAL(_obstack_newchunk)(obstack, length);\n  if (obstack->chunk)\n    COMMON_INTERCEPTOR_INITIALIZE_RANGE(\n        obstack->chunk, obstack->next_free - (char *)obstack->chunk);\n}\n#define INIT_OBSTACK                           \\\n  COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \\\n  COMMON_INTERCEPT_FUNCTION(_obstack_begin);   \\\n  COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);\n#else\n#define INIT_OBSTACK\n#endif\n\n#if SANITIZER_INTERCEPT_FFLUSH\nINTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);\n  int res = REAL(fflush)(fp);\n  // FIXME: handle fp == NULL\n  if (fp) {\n    const FileMetadata *m = GetInterceptorMetadata(fp);\n    if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);\n  }\n  return res;\n}\n#define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);\n#else\n#define INIT_FFLUSH\n#endif\n\n#if SANITIZER_INTERCEPT_FCLOSE\nINTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);\n  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);\n  const FileMetadata *m = GetInterceptorMetadata(fp);\n  int res = REAL(fclose)(fp);\n  if (m) {\n    COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);\n    DeleteInterceptorMetadata(fp);\n  }\n  return res;\n}\n#define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);\n#else\n#define INIT_FCLOSE\n#endif\n\n#if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE\nINTERCEPTOR(void*, dlopen, const char *filename, int flag) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);\n  if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0);\n  COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag);\n  void *res = REAL(dlopen)(filename, flag);\n  COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);\n  return res;\n}\n\nINTERCEPTOR(int, dlclose, void *handle) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);\n  int res = REAL(dlclose)(handle);\n  COMMON_INTERCEPTOR_LIBRARY_UNLOADED();\n  return res;\n}\n#define INIT_DLOPEN_DLCLOSE          \\\n  COMMON_INTERCEPT_FUNCTION(dlopen); \\\n  COMMON_INTERCEPT_FUNCTION(dlclose);\n#else\n#define INIT_DLOPEN_DLCLOSE\n#endif\n\n#if SANITIZER_INTERCEPT_GETPASS\nINTERCEPTOR(char *, getpass, const char *prompt) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt);\n  if (prompt)\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, REAL(strlen)(prompt)+1);\n  char *res = REAL(getpass)(prompt);\n  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res)+1);\n  return res;\n}\n\n#define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass);\n#else\n#define INIT_GETPASS\n#endif\n\n#if SANITIZER_INTERCEPT_TIMERFD\nINTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value,\n            void *old_value) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value,\n                           old_value);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz);\n  int res = REAL(timerfd_settime)(fd, flags, new_value, old_value);\n  if (res != -1 && old_value)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz);\n  return res;\n}\n\nINTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value);\n  int res = REAL(timerfd_gettime)(fd, curr_value);\n  if (res != -1 && curr_value)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz);\n  return res;\n}\n#define INIT_TIMERFD                          \\\n  COMMON_INTERCEPT_FUNCTION(timerfd_settime); \\\n  COMMON_INTERCEPT_FUNCTION(timerfd_gettime);\n#else\n#define INIT_TIMERFD\n#endif\n\n#if SANITIZER_INTERCEPT_MLOCKX\n// Linux kernel has a bug that leads to kernel deadlock if a process\n// maps TBs of memory and then calls mlock().\nstatic void MlockIsUnsupported() {\n  static atomic_uint8_t printed;\n  if (atomic_exchange(&printed, 1, memory_order_relaxed))\n    return;\n  VPrintf(1, \"%s ignores mlock/mlockall/munlock/munlockall\\n\",\n          SanitizerToolName);\n}\n\nINTERCEPTOR(int, mlock, const void *addr, uptr len) {\n  MlockIsUnsupported();\n  return 0;\n}\n\nINTERCEPTOR(int, munlock, const void *addr, uptr len) {\n  MlockIsUnsupported();\n  return 0;\n}\n\nINTERCEPTOR(int, mlockall, int flags) {\n  MlockIsUnsupported();\n  return 0;\n}\n\nINTERCEPTOR(int, munlockall, void) {\n  MlockIsUnsupported();\n  return 0;\n}\n\n#define INIT_MLOCKX                                                            \\\n  COMMON_INTERCEPT_FUNCTION(mlock);                                            \\\n  COMMON_INTERCEPT_FUNCTION(munlock);                                          \\\n  COMMON_INTERCEPT_FUNCTION(mlockall);                                         \\\n  COMMON_INTERCEPT_FUNCTION(munlockall);\n\n#else\n#define INIT_MLOCKX\n#endif  // SANITIZER_INTERCEPT_MLOCKX\n\n#if SANITIZER_INTERCEPT_FOPENCOOKIE\nstruct WrappedCookie {\n  void *real_cookie;\n  __sanitizer_cookie_io_functions_t real_io_funcs;\n};\n\nstatic uptr wrapped_read(void *cookie, char *buf, uptr size) {\n  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);\n  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;\n  __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read;\n  return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0;\n}\n\nstatic uptr wrapped_write(void *cookie, const char *buf, uptr size) {\n  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);\n  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;\n  __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write;\n  return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size;\n}\n\nstatic int wrapped_seek(void *cookie, u64 *offset, int whence) {\n  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);\n  COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset));\n  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;\n  __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek;\n  return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence)\n                   : -1;\n}\n\nstatic int wrapped_close(void *cookie) {\n  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);\n  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;\n  __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close;\n  int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0;\n  InternalFree(wrapped_cookie);\n  return res;\n}\n\nINTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode,\n            __sanitizer_cookie_io_functions_t io_funcs) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs);\n  WrappedCookie *wrapped_cookie =\n      (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie));\n  wrapped_cookie->real_cookie = cookie;\n  wrapped_cookie->real_io_funcs = io_funcs;\n  __sanitizer_FILE *res =\n      REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write,\n                                               wrapped_seek, wrapped_close});\n  return res;\n}\n\n#define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie);\n#else\n#define INIT_FOPENCOOKIE\n#endif  // SANITIZER_INTERCEPT_FOPENCOOKIE\n\n#if SANITIZER_INTERCEPT_SEM\nINTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value);\n  // Workaround a bug in glibc's \"old\" semaphore implementation by\n  // zero-initializing the sem_t contents. This has to be done here because\n  // interceptors bind to the lowest symbols version by default, hitting the\n  // buggy code path while the non-sanitized build of the same code works fine.\n  REAL(memset)(s, 0, sizeof(*s));\n  int res = REAL(sem_init)(s, pshared, value);\n  return res;\n}\n\nINTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s);\n  int res = REAL(sem_destroy)(s);\n  return res;\n}\n\nINTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s);\n  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s);\n  if (res == 0) {\n    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);\n  }\n  return res;\n}\n\nINTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);\n  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_trywait)(s);\n  if (res == 0) {\n    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);\n  }\n  return res;\n}\n\nINTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime);\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz);\n  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime);\n  if (res == 0) {\n    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);\n  }\n  return res;\n}\n\nINTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s);\n  COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s);\n  int res = REAL(sem_post)(s);\n  return res;\n}\n\nINTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval);\n  int res = REAL(sem_getvalue)(s, sval);\n  if (res == 0) {\n    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval));\n  }\n  return res;\n}\n#define INIT_SEM                                                               \\\n  COMMON_INTERCEPT_FUNCTION(sem_init);                                         \\\n  COMMON_INTERCEPT_FUNCTION(sem_destroy);                                      \\\n  COMMON_INTERCEPT_FUNCTION(sem_wait);                                         \\\n  COMMON_INTERCEPT_FUNCTION(sem_trywait);                                      \\\n  COMMON_INTERCEPT_FUNCTION(sem_timedwait);                                    \\\n  COMMON_INTERCEPT_FUNCTION(sem_post);                                         \\\n  COMMON_INTERCEPT_FUNCTION(sem_getvalue);\n#else\n#define INIT_SEM\n#endif // SANITIZER_INTERCEPT_SEM\n\n#if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL\nINTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate);\n  int res = REAL(pthread_setcancelstate)(state, oldstate);\n  if (res == 0)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate));\n  return res;\n}\n\nINTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype);\n  int res = REAL(pthread_setcanceltype)(type, oldtype);\n  if (res == 0)\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype));\n  return res;\n}\n#define INIT_PTHREAD_SETCANCEL                                                 \\\n  COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate);                           \\\n  COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype);\n#else\n#define INIT_PTHREAD_SETCANCEL\n#endif\n\n#if SANITIZER_INTERCEPT_MINCORE\nINTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec);\n  int res = REAL(mincore)(addr, length, vec);\n  if (res == 0) {\n    uptr page_size = GetPageSizeCached();\n    uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size;\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size);\n  }\n  return res;\n}\n#define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore);\n#else\n#define INIT_MINCORE\n#endif\n\n#if SANITIZER_INTERCEPT_PROCESS_VM_READV\nINTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov,\n            uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,\n            uptr flags) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt,\n                           remote_iov, riovcnt, flags);\n  SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov,\n                                       riovcnt, flags);\n  if (res > 0)\n    write_iovec(ctx, local_iov, liovcnt, res);\n  return res;\n}\n\nINTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov,\n            uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,\n            uptr flags) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt,\n                           remote_iov, riovcnt, flags);\n  SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov,\n                                        riovcnt, flags);\n  if (res > 0)\n    read_iovec(ctx, local_iov, liovcnt, res);\n  return res;\n}\n#define INIT_PROCESS_VM_READV                                                  \\\n  COMMON_INTERCEPT_FUNCTION(process_vm_readv);                                 \\\n  COMMON_INTERCEPT_FUNCTION(process_vm_writev);\n#else\n#define INIT_PROCESS_VM_READV\n#endif\n\n#if SANITIZER_INTERCEPT_CTERMID\nINTERCEPTOR(char *, ctermid, char *s) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s);\n  char *res = REAL(ctermid)(s);\n  if (res) {\n    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);\n  }\n  return res;\n}\n#define INIT_CTERMID COMMON_INTERCEPT_FUNCTION(ctermid);\n#else\n#define INIT_CTERMID\n#endif\n\n#if SANITIZER_INTERCEPT_CTERMID_R\nINTERCEPTOR(char *, ctermid_r, char *s) {\n  void *ctx;\n  COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s);\n  char *res = REAL(ctermid_r)(s);\n  if (res) {\n    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);\n  }\n  return res;\n}\n#define INIT_CTERMID_R COMMON_INTERCEPT_FUNCTION(ctermid_r);\n#else\n#define INIT_CTERMID_R\n#endif\n\nstatic void InitializeCommonInterceptors() {\n  static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];\n  interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();\n\n  INIT_TEXTDOMAIN;\n  INIT_STRCMP;\n  INIT_STRNCMP;\n  INIT_STRCASECMP;\n  INIT_STRNCASECMP;\n  INIT_STRSTR;\n  INIT_STRCASESTR;\n  INIT_STRSPN;\n  INIT_STRPBRK;\n  INIT_MEMCHR;\n  INIT_MEMCMP;\n  INIT_MEMRCHR;\n  INIT_READ;\n  INIT_PREAD;\n  INIT_PREAD64;\n  INIT_READV;\n  INIT_PREADV;\n  INIT_PREADV64;\n  INIT_WRITE;\n  INIT_PWRITE;\n  INIT_PWRITE64;\n  INIT_WRITEV;\n  INIT_PWRITEV;\n  INIT_PWRITEV64;\n  INIT_PRCTL;\n  INIT_LOCALTIME_AND_FRIENDS;\n  INIT_STRPTIME;\n  INIT_SCANF;\n  INIT_ISOC99_SCANF;\n  INIT_PRINTF;\n  INIT_PRINTF_L;\n  INIT_ISOC99_PRINTF;\n  INIT_FREXP;\n  INIT_FREXPF_FREXPL;\n  INIT_GETPWNAM_AND_FRIENDS;\n  INIT_GETPWNAM_R_AND_FRIENDS;\n  INIT_GETPWENT;\n  INIT_FGETPWENT;\n  INIT_GETPWENT_R;\n  INIT_SETPWENT;\n  INIT_CLOCK_GETTIME;\n  INIT_GETITIMER;\n  INIT_TIME;\n  INIT_GLOB;\n  INIT_WAIT;\n  INIT_WAIT4;\n  INIT_INET;\n  INIT_PTHREAD_GETSCHEDPARAM;\n  INIT_GETADDRINFO;\n  INIT_GETNAMEINFO;\n  INIT_GETSOCKNAME;\n  INIT_GETHOSTBYNAME;\n  INIT_GETHOSTBYNAME_R;\n  INIT_GETHOSTBYNAME2_R;\n  INIT_GETHOSTBYADDR_R;\n  INIT_GETHOSTENT_R;\n  INIT_GETSOCKOPT;\n  INIT_ACCEPT;\n  INIT_ACCEPT4;\n  INIT_MODF;\n  INIT_RECVMSG;\n  INIT_GETPEERNAME;\n  INIT_IOCTL;\n  INIT_INET_ATON;\n  INIT_SYSINFO;\n  INIT_READDIR;\n  INIT_READDIR64;\n  INIT_PTRACE;\n  INIT_SETLOCALE;\n  INIT_GETCWD;\n  INIT_GET_CURRENT_DIR_NAME;\n  INIT_STRTOIMAX;\n  INIT_MBSTOWCS;\n  INIT_MBSNRTOWCS;\n  INIT_WCSTOMBS;\n  INIT_WCSNRTOMBS;\n  INIT_WCRTOMB;\n  INIT_TCGETATTR;\n  INIT_REALPATH;\n  INIT_CANONICALIZE_FILE_NAME;\n  INIT_CONFSTR;\n  INIT_SCHED_GETAFFINITY;\n  INIT_SCHED_GETPARAM;\n  INIT_STRERROR;\n  INIT_STRERROR_R;\n  INIT_XPG_STRERROR_R;\n  INIT_SCANDIR;\n  INIT_SCANDIR64;\n  INIT_GETGROUPS;\n  INIT_POLL;\n  INIT_PPOLL;\n  INIT_WORDEXP;\n  INIT_SIGWAIT;\n  INIT_SIGWAITINFO;\n  INIT_SIGTIMEDWAIT;\n  INIT_SIGSETOPS;\n  INIT_SIGPENDING;\n  INIT_SIGPROCMASK;\n  INIT_BACKTRACE;\n  INIT__EXIT;\n  INIT_PTHREAD_MUTEX_LOCK;\n  INIT_PTHREAD_MUTEX_UNLOCK;\n  INIT_GETMNTENT;\n  INIT_GETMNTENT_R;\n  INIT_STATFS;\n  INIT_STATFS64;\n  INIT_STATVFS;\n  INIT_STATVFS64;\n  INIT_INITGROUPS;\n  INIT_ETHER_NTOA_ATON;\n  INIT_ETHER_HOST;\n  INIT_ETHER_R;\n  INIT_SHMCTL;\n  INIT_RANDOM_R;\n  INIT_PTHREAD_ATTR_GET;\n  INIT_PTHREAD_ATTR_GETINHERITSCHED;\n  INIT_PTHREAD_ATTR_GETAFFINITY_NP;\n  INIT_PTHREAD_MUTEXATTR_GETPSHARED;\n  INIT_PTHREAD_MUTEXATTR_GETTYPE;\n  INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;\n  INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;\n  INIT_PTHREAD_MUTEXATTR_GETROBUST;\n  INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;\n  INIT_PTHREAD_RWLOCKATTR_GETPSHARED;\n  INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;\n  INIT_PTHREAD_CONDATTR_GETPSHARED;\n  INIT_PTHREAD_CONDATTR_GETCLOCK;\n  INIT_PTHREAD_BARRIERATTR_GETPSHARED;\n  INIT_TMPNAM;\n  INIT_TMPNAM_R;\n  INIT_TEMPNAM;\n  INIT_PTHREAD_SETNAME_NP;\n  INIT_SINCOS;\n  INIT_REMQUO;\n  INIT_LGAMMA;\n  INIT_LGAMMA_R;\n  INIT_LGAMMAL_R;\n  INIT_DRAND48_R;\n  INIT_RAND_R;\n  INIT_GETLINE;\n  INIT_ICONV;\n  INIT_TIMES;\n  INIT_TLS_GET_ADDR;\n  INIT_LISTXATTR;\n  INIT_GETXATTR;\n  INIT_GETRESID;\n  INIT_GETIFADDRS;\n  INIT_IF_INDEXTONAME;\n  INIT_CAPGET;\n  INIT_AEABI_MEM;\n  INIT___BZERO;\n  INIT_FTIME;\n  INIT_XDR;\n  INIT_TSEARCH;\n  INIT_LIBIO_INTERNALS;\n  INIT_FOPEN;\n  INIT_FOPEN64;\n  INIT_OPEN_MEMSTREAM;\n  INIT_OBSTACK;\n  INIT_FFLUSH;\n  INIT_FCLOSE;\n  INIT_DLOPEN_DLCLOSE;\n  INIT_GETPASS;\n  INIT_TIMERFD;\n  INIT_MLOCKX;\n  INIT_FOPENCOOKIE;\n  INIT_SEM;\n  INIT_PTHREAD_SETCANCEL;\n  INIT_MINCORE;\n  INIT_PROCESS_VM_READV;\n  INIT_CTERMID;\n  INIT_CTERMID_R;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc",
    "content": "//===-- sanitizer_common_interceptors_format.inc ----------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Scanf/printf implementation for use in *Sanitizer interceptors.\n// Follows http://pubs.opengroup.org/onlinepubs/9699919799/functions/fscanf.html\n// and http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html\n// with a few common GNU extensions.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stdarg.h>\n\nstatic const char *parse_number(const char *p, int *out) {\n  *out = internal_atoll(p);\n  while (*p >= '0' && *p <= '9')\n    ++p;\n  return p;\n}\n\nstatic const char *maybe_parse_param_index(const char *p, int *out) {\n  // n$\n  if (*p >= '0' && *p <= '9') {\n    int number;\n    const char *q = parse_number(p, &number);\n    CHECK(q);\n    if (*q == '$') {\n      *out = number;\n      p = q + 1;\n    }\n  }\n\n  // Otherwise, do not change p. This will be re-parsed later as the field\n  // width.\n  return p;\n}\n\nstatic bool char_is_one_of(char c, const char *s) {\n  return !!internal_strchr(s, c);\n}\n\nstatic const char *maybe_parse_length_modifier(const char *p, char ll[2]) {\n  if (char_is_one_of(*p, \"jztLq\")) {\n    ll[0] = *p;\n    ++p;\n  } else if (*p == 'h') {\n    ll[0] = 'h';\n    ++p;\n    if (*p == 'h') {\n      ll[1] = 'h';\n      ++p;\n    }\n  } else if (*p == 'l') {\n    ll[0] = 'l';\n    ++p;\n    if (*p == 'l') {\n      ll[1] = 'l';\n      ++p;\n    }\n  }\n  return p;\n}\n\n// Returns true if the character is an integer conversion specifier.\nstatic bool format_is_integer_conv(char c) {\n  return char_is_one_of(c, \"diouxXn\");\n}\n\n// Returns true if the character is an floating point conversion specifier.\nstatic bool format_is_float_conv(char c) {\n  return char_is_one_of(c, \"aAeEfFgG\");\n}\n\n// Returns string output character size for string-like conversions,\n// or 0 if the conversion is invalid.\nstatic int format_get_char_size(char convSpecifier,\n                                const char lengthModifier[2]) {\n  if (char_is_one_of(convSpecifier, \"CS\")) {\n    return sizeof(wchar_t);\n  }\n\n  if (char_is_one_of(convSpecifier, \"cs[\")) {\n    if (lengthModifier[0] == 'l' && lengthModifier[1] == '\\0')\n      return sizeof(wchar_t);\n    else if (lengthModifier[0] == '\\0')\n      return sizeof(char);\n  }\n\n  return 0;\n}\n\nenum FormatStoreSize {\n  // Store size not known in advance; can be calculated as wcslen() of the\n  // destination buffer.\n  FSS_WCSLEN = -2,\n  // Store size not known in advance; can be calculated as strlen() of the\n  // destination buffer.\n  FSS_STRLEN = -1,\n  // Invalid conversion specifier.\n  FSS_INVALID = 0\n};\n\n// Returns the memory size of a format directive (if >0), or a value of\n// FormatStoreSize.\nstatic int format_get_value_size(char convSpecifier,\n                                 const char lengthModifier[2],\n                                 bool promote_float) {\n  if (format_is_integer_conv(convSpecifier)) {\n    switch (lengthModifier[0]) {\n    case 'h':\n      return lengthModifier[1] == 'h' ? sizeof(char) : sizeof(short);\n    case 'l':\n      return lengthModifier[1] == 'l' ? sizeof(long long) : sizeof(long);\n    case 'q':\n      return sizeof(long long);\n    case 'L':\n      return sizeof(long long);\n    case 'j':\n      return sizeof(INTMAX_T);\n    case 'z':\n      return sizeof(SIZE_T);\n    case 't':\n      return sizeof(PTRDIFF_T);\n    case 0:\n      return sizeof(int);\n    default:\n      return FSS_INVALID;\n    }\n  }\n\n  if (format_is_float_conv(convSpecifier)) {\n    switch (lengthModifier[0]) {\n    case 'L':\n    case 'q':\n      return sizeof(long double);\n    case 'l':\n      return lengthModifier[1] == 'l' ? sizeof(long double)\n                                           : sizeof(double);\n    case 0:\n      // Printf promotes floats to doubles but scanf does not\n      return promote_float ? sizeof(double) : sizeof(float);\n    default:\n      return FSS_INVALID;\n    }\n  }\n\n  if (convSpecifier == 'p') {\n    if (lengthModifier[0] != 0)\n      return FSS_INVALID;\n    return sizeof(void *);\n  }\n\n  return FSS_INVALID;\n}\n\nstruct ScanfDirective {\n  int argIdx; // argument index, or -1 if not specified (\"%n$\")\n  int fieldWidth;\n  const char *begin;\n  const char *end;\n  bool suppressed; // suppress assignment (\"*\")\n  bool allocate;   // allocate space (\"m\")\n  char lengthModifier[2];\n  char convSpecifier;\n  bool maybeGnuMalloc;\n};\n\n// Parse scanf format string. If a valid directive in encountered, it is\n// returned in dir. This function returns the pointer to the first\n// unprocessed character, or 0 in case of error.\n// In case of the end-of-string, a pointer to the closing \\0 is returned.\nstatic const char *scanf_parse_next(const char *p, bool allowGnuMalloc,\n                                    ScanfDirective *dir) {\n  internal_memset(dir, 0, sizeof(*dir));\n  dir->argIdx = -1;\n\n  while (*p) {\n    if (*p != '%') {\n      ++p;\n      continue;\n    }\n    dir->begin = p;\n    ++p;\n    // %%\n    if (*p == '%') {\n      ++p;\n      continue;\n    }\n    if (*p == '\\0') {\n      return nullptr;\n    }\n    // %n$\n    p = maybe_parse_param_index(p, &dir->argIdx);\n    CHECK(p);\n    // *\n    if (*p == '*') {\n      dir->suppressed = true;\n      ++p;\n    }\n    // Field width\n    if (*p >= '0' && *p <= '9') {\n      p = parse_number(p, &dir->fieldWidth);\n      CHECK(p);\n      if (dir->fieldWidth <= 0)  // Width if at all must be non-zero\n        return nullptr;\n    }\n    // m\n    if (*p == 'm') {\n      dir->allocate = true;\n      ++p;\n    }\n    // Length modifier.\n    p = maybe_parse_length_modifier(p, dir->lengthModifier);\n    // Conversion specifier.\n    dir->convSpecifier = *p++;\n    // Consume %[...] expression.\n    if (dir->convSpecifier == '[') {\n      if (*p == '^')\n        ++p;\n      if (*p == ']')\n        ++p;\n      while (*p && *p != ']')\n        ++p;\n      if (*p == 0)\n        return nullptr; // unexpected end of string\n                        // Consume the closing ']'.\n      ++p;\n    }\n    // This is unfortunately ambiguous between old GNU extension\n    // of %as, %aS and %a[...] and newer POSIX %a followed by\n    // letters s, S or [.\n    if (allowGnuMalloc && dir->convSpecifier == 'a' &&\n        !dir->lengthModifier[0]) {\n      if (*p == 's' || *p == 'S') {\n        dir->maybeGnuMalloc = true;\n        ++p;\n      } else if (*p == '[') {\n        // Watch for %a[h-j%d], if % appears in the\n        // [...] range, then we need to give up, we don't know\n        // if scanf will parse it as POSIX %a [h-j %d ] or\n        // GNU allocation of string with range dh-j plus %.\n        const char *q = p + 1;\n        if (*q == '^')\n          ++q;\n        if (*q == ']')\n          ++q;\n        while (*q && *q != ']' && *q != '%')\n          ++q;\n        if (*q == 0 || *q == '%')\n          return nullptr;\n        p = q + 1; // Consume the closing ']'.\n        dir->maybeGnuMalloc = true;\n      }\n    }\n    dir->end = p;\n    break;\n  }\n  return p;\n}\n\nstatic int scanf_get_value_size(ScanfDirective *dir) {\n  if (dir->allocate) {\n    if (!char_is_one_of(dir->convSpecifier, \"cCsS[\"))\n      return FSS_INVALID;\n    return sizeof(char *);\n  }\n\n  if (dir->maybeGnuMalloc) {\n    if (dir->convSpecifier != 'a' || dir->lengthModifier[0])\n      return FSS_INVALID;\n    // This is ambiguous, so check the smaller size of char * (if it is\n    // a GNU extension of %as, %aS or %a[...]) and float (if it is\n    // POSIX %a followed by s, S or [ letters).\n    return sizeof(char *) < sizeof(float) ? sizeof(char *) : sizeof(float);\n  }\n\n  if (char_is_one_of(dir->convSpecifier, \"cCsS[\")) {\n    bool needsTerminator = char_is_one_of(dir->convSpecifier, \"sS[\");\n    unsigned charSize =\n        format_get_char_size(dir->convSpecifier, dir->lengthModifier);\n    if (charSize == 0)\n      return FSS_INVALID;\n    if (dir->fieldWidth == 0) {\n      if (!needsTerminator)\n        return charSize;\n      return (charSize == sizeof(char)) ? FSS_STRLEN : FSS_WCSLEN;\n    }\n    return (dir->fieldWidth + needsTerminator) * charSize;\n  }\n\n  return format_get_value_size(dir->convSpecifier, dir->lengthModifier, false);\n}\n\n// Common part of *scanf interceptors.\n// Process format string and va_list, and report all store ranges.\n// Stops when \"consuming\" n_inputs input items.\nstatic void scanf_common(void *ctx, int n_inputs, bool allowGnuMalloc,\n                         const char *format, va_list aq) {\n  CHECK_GT(n_inputs, 0);\n  const char *p = format;\n\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, format, internal_strlen(format) + 1);\n\n  while (*p) {\n    ScanfDirective dir;\n    p = scanf_parse_next(p, allowGnuMalloc, &dir);\n    if (!p)\n      break;\n    if (dir.convSpecifier == 0) {\n      // This can only happen at the end of the format string.\n      CHECK_EQ(*p, 0);\n      break;\n    }\n    // Here the directive is valid. Do what it says.\n    if (dir.argIdx != -1) {\n      // Unsupported.\n      break;\n    }\n    if (dir.suppressed)\n      continue;\n    int size = scanf_get_value_size(&dir);\n    if (size == FSS_INVALID) {\n      Report(\"WARNING: unexpected format specifier in scanf interceptor: \"\n        \"%.*s\\n\", dir.end - dir.begin, dir.begin);\n      break;\n    }\n    void *argp = va_arg(aq, void *);\n    if (dir.convSpecifier != 'n')\n      --n_inputs;\n    if (n_inputs < 0)\n      break;\n    if (size == FSS_STRLEN) {\n      size = internal_strlen((const char *)argp) + 1;\n    } else if (size == FSS_WCSLEN) {\n      // FIXME: actually use wcslen() to calculate it.\n      size = 0;\n    }\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, argp, size);\n  }\n}\n\n#if SANITIZER_INTERCEPT_PRINTF\n\nstruct PrintfDirective {\n  int fieldWidth;\n  int fieldPrecision;\n  int argIdx; // width argument index, or -1 if not specified (\"%*n$\")\n  int precisionIdx; // precision argument index, or -1 if not specified (\".*n$\")\n  const char *begin;\n  const char *end;\n  bool starredWidth;\n  bool starredPrecision;\n  char lengthModifier[2];\n  char convSpecifier;\n};\n\nstatic const char *maybe_parse_number(const char *p, int *out) {\n  if (*p >= '0' && *p <= '9')\n    p = parse_number(p, out);\n  return p;\n}\n\nstatic const char *maybe_parse_number_or_star(const char *p, int *out,\n                                              bool *star) {\n  if (*p == '*') {\n    *star = true;\n    ++p;\n  } else {\n    *star = false;\n    p = maybe_parse_number(p, out);\n  }\n  return p;\n}\n\n// Parse printf format string. Same as scanf_parse_next.\nstatic const char *printf_parse_next(const char *p, PrintfDirective *dir) {\n  internal_memset(dir, 0, sizeof(*dir));\n  dir->argIdx = -1;\n  dir->precisionIdx = -1;\n\n  while (*p) {\n    if (*p != '%') {\n      ++p;\n      continue;\n    }\n    dir->begin = p;\n    ++p;\n    // %%\n    if (*p == '%') {\n      ++p;\n      continue;\n    }\n    if (*p == '\\0') {\n      return nullptr;\n    }\n    // %n$\n    p = maybe_parse_param_index(p, &dir->precisionIdx);\n    CHECK(p);\n    // Flags\n    while (char_is_one_of(*p, \"'-+ #0\")) {\n      ++p;\n    }\n    // Field width\n    p = maybe_parse_number_or_star(p, &dir->fieldWidth,\n                                   &dir->starredWidth);\n    if (!p)\n      return nullptr;\n    // Precision\n    if (*p == '.') {\n      ++p;\n      // Actual precision is optional (surprise!)\n      p = maybe_parse_number_or_star(p, &dir->fieldPrecision,\n                                     &dir->starredPrecision);\n      if (!p)\n        return nullptr;\n      // m$\n      if (dir->starredPrecision) {\n        p = maybe_parse_param_index(p, &dir->precisionIdx);\n        CHECK(p);\n      }\n    }\n    // Length modifier.\n    p = maybe_parse_length_modifier(p, dir->lengthModifier);\n    // Conversion specifier.\n    dir->convSpecifier = *p++;\n    dir->end = p;\n    break;\n  }\n  return p;\n}\n\nstatic int printf_get_value_size(PrintfDirective *dir) {\n  if (dir->convSpecifier == 'm') {\n    return sizeof(char *);\n  }\n\n  if (char_is_one_of(dir->convSpecifier, \"cCsS\")) {\n    unsigned charSize =\n        format_get_char_size(dir->convSpecifier, dir->lengthModifier);\n    if (charSize == 0)\n      return FSS_INVALID;\n    if (char_is_one_of(dir->convSpecifier, \"sS\")) {\n      return (charSize == sizeof(char)) ? FSS_STRLEN : FSS_WCSLEN;\n    }\n    return charSize;\n  }\n\n  return format_get_value_size(dir->convSpecifier, dir->lengthModifier, true);\n}\n\n#define SKIP_SCALAR_ARG(aq, convSpecifier, size)                   \\\n  do {                                                             \\\n    if (format_is_float_conv(convSpecifier)) {                     \\\n      switch (size) {                                              \\\n      case 8:                                                      \\\n        va_arg(*aq, double);                                       \\\n        break;                                                     \\\n      case 12:                                                     \\\n        va_arg(*aq, long double);                                  \\\n        break;                                                     \\\n      case 16:                                                     \\\n        va_arg(*aq, long double);                                  \\\n        break;                                                     \\\n      default:                                                     \\\n        Report(\"WARNING: unexpected floating-point arg size\"       \\\n               \" in printf interceptor: %d\\n\", size);              \\\n        return;                                                    \\\n      }                                                            \\\n    } else {                                                       \\\n      switch (size) {                                              \\\n      case 1:                                                      \\\n      case 2:                                                      \\\n      case 4:                                                      \\\n        va_arg(*aq, u32);                                          \\\n        break;                                                     \\\n      case 8:                                                      \\\n        va_arg(*aq, u64);                                          \\\n        break;                                                     \\\n      default:                                                     \\\n        Report(\"WARNING: unexpected arg size\"                      \\\n               \" in printf interceptor: %d\\n\", size);              \\\n        return;                                                    \\\n      }                                                            \\\n    }                                                              \\\n  } while (0)\n\n// Common part of *printf interceptors.\n// Process format string and va_list, and report all load ranges.\nstatic void printf_common(void *ctx, const char *format, va_list aq) {\n  COMMON_INTERCEPTOR_READ_RANGE(ctx, format, internal_strlen(format) + 1);\n\n  const char *p = format;\n\n  while (*p) {\n    PrintfDirective dir;\n    p = printf_parse_next(p, &dir);\n    if (!p)\n      break;\n    if (dir.convSpecifier == 0) {\n      // This can only happen at the end of the format string.\n      CHECK_EQ(*p, 0);\n      break;\n    }\n    // Here the directive is valid. Do what it says.\n    if (dir.argIdx != -1 || dir.precisionIdx != -1) {\n      // Unsupported.\n      break;\n    }\n    if (dir.starredWidth) {\n      // Dynamic width\n      SKIP_SCALAR_ARG(&aq, 'd', sizeof(int));\n    }\n    if (dir.starredPrecision) {\n      // Dynamic precision\n      SKIP_SCALAR_ARG(&aq, 'd', sizeof(int));\n    }\n    int size = printf_get_value_size(&dir);\n    if (size == FSS_INVALID) {\n      Report(\"WARNING: unexpected format specifier in printf \"\n             \"interceptor: %.*s\\n\", dir.end - dir.begin, dir.begin);\n      break;\n    }\n    if (dir.convSpecifier == 'n') {\n      void *argp = va_arg(aq, void *);\n      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, argp, size);\n      continue;\n    } else if (size == FSS_STRLEN) {\n      if (void *argp = va_arg(aq, void *)) {\n        if (dir.starredPrecision) {\n          // FIXME: properly support starred precision for strings.\n          size = 0;\n        } else if (dir.fieldPrecision > 0) {\n          // Won't read more than \"precision\" symbols.\n          size = internal_strnlen((const char *)argp, dir.fieldPrecision);\n          if (size < dir.fieldPrecision) size++;\n        } else {\n          // Whole string will be accessed.\n          size = internal_strlen((const char *)argp) + 1;\n        }\n        COMMON_INTERCEPTOR_READ_RANGE(ctx, argp, size);\n      }\n    } else if (size == FSS_WCSLEN) {\n      if (void *argp = va_arg(aq, void *)) {\n        // FIXME: Properly support wide-character strings (via wcsrtombs).\n        size = 0;\n        COMMON_INTERCEPTOR_READ_RANGE(ctx, argp, size);\n      }\n    } else {\n      // Skip non-pointer args\n      SKIP_SCALAR_ARG(&aq, dir.convSpecifier, size);\n    }\n  }\n}\n\n#endif // SANITIZER_INTERCEPT_PRINTF\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc",
    "content": "//===-- sanitizer_common_interceptors_ioctl.inc -----------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Ioctl handling in common sanitizer interceptors.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_flags.h\"\n\nstruct ioctl_desc {\n  unsigned req;\n  // FIXME: support read+write arguments. Currently READWRITE and WRITE do the\n  // same thing.\n  // XXX: The declarations below may use WRITE instead of READWRITE, unless\n  // explicitly noted.\n  enum {\n    NONE,\n    READ,\n    WRITE,\n    READWRITE,\n    CUSTOM\n  } type : 3;\n  unsigned size : 29;\n  const char* name;\n};\n\nconst unsigned ioctl_table_max = 500;\nstatic ioctl_desc ioctl_table[ioctl_table_max];\nstatic unsigned ioctl_table_size = 0;\n\n// This can not be declared as a global, because references to struct_*_sz\n// require a global initializer. And this table must be available before global\n// initializers are run.\nstatic void ioctl_table_fill() {\n#define _(rq, tp, sz)                                    \\\n  if (IOCTL_##rq != IOCTL_NOT_PRESENT) {                 \\\n    CHECK(ioctl_table_size < ioctl_table_max);           \\\n    ioctl_table[ioctl_table_size].req = IOCTL_##rq;      \\\n    ioctl_table[ioctl_table_size].type = ioctl_desc::tp; \\\n    ioctl_table[ioctl_table_size].size = sz;             \\\n    ioctl_table[ioctl_table_size].name = #rq;            \\\n    ++ioctl_table_size;                                  \\\n  }\n\n  _(FIOASYNC, READ, sizeof(int));\n  _(FIOCLEX, NONE, 0);\n  _(FIOGETOWN, WRITE, sizeof(int));\n  _(FIONBIO, READ, sizeof(int));\n  _(FIONCLEX, NONE, 0);\n  _(FIOSETOWN, READ, sizeof(int));\n  _(SIOCADDMULTI, READ, struct_ifreq_sz);\n  _(SIOCATMARK, WRITE, sizeof(int));\n  _(SIOCDELMULTI, READ, struct_ifreq_sz);\n  _(SIOCGIFADDR, WRITE, struct_ifreq_sz);\n  _(SIOCGIFBRDADDR, WRITE, struct_ifreq_sz);\n  _(SIOCGIFCONF, CUSTOM, 0);\n  _(SIOCGIFDSTADDR, WRITE, struct_ifreq_sz);\n  _(SIOCGIFFLAGS, WRITE, struct_ifreq_sz);\n  _(SIOCGIFMETRIC, WRITE, struct_ifreq_sz);\n  _(SIOCGIFMTU, WRITE, struct_ifreq_sz);\n  _(SIOCGIFNETMASK, WRITE, struct_ifreq_sz);\n  _(SIOCGPGRP, WRITE, sizeof(int));\n  _(SIOCSIFADDR, READ, struct_ifreq_sz);\n  _(SIOCSIFBRDADDR, READ, struct_ifreq_sz);\n  _(SIOCSIFDSTADDR, READ, struct_ifreq_sz);\n  _(SIOCSIFFLAGS, READ, struct_ifreq_sz);\n  _(SIOCSIFMETRIC, READ, struct_ifreq_sz);\n  _(SIOCSIFMTU, READ, struct_ifreq_sz);\n  _(SIOCSIFNETMASK, READ, struct_ifreq_sz);\n  _(SIOCSPGRP, READ, sizeof(int));\n  _(TIOCCONS, NONE, 0);\n  _(TIOCEXCL, NONE, 0);\n  _(TIOCGETD, WRITE, sizeof(int));\n  _(TIOCGPGRP, WRITE, pid_t_sz);\n  _(TIOCGWINSZ, WRITE, struct_winsize_sz);\n  _(TIOCMBIC, READ, sizeof(int));\n  _(TIOCMBIS, READ, sizeof(int));\n  _(TIOCMGET, WRITE, sizeof(int));\n  _(TIOCMSET, READ, sizeof(int));\n  _(TIOCNOTTY, NONE, 0);\n  _(TIOCNXCL, NONE, 0);\n  _(TIOCOUTQ, WRITE, sizeof(int));\n  _(TIOCPKT, READ, sizeof(int));\n  _(TIOCSCTTY, NONE, 0);\n  _(TIOCSETD, READ, sizeof(int));\n  _(TIOCSPGRP, READ, pid_t_sz);\n  _(TIOCSTI, READ, sizeof(char));\n  _(TIOCSWINSZ, READ, struct_winsize_sz);\n\n#if (SANITIZER_LINUX && !SANITIZER_ANDROID)\n  _(SIOCGETSGCNT, WRITE, struct_sioc_sg_req_sz);\n  _(SIOCGETVIFCNT, WRITE, struct_sioc_vif_req_sz);\n#endif\n\n#if SANITIZER_LINUX\n  // Conflicting request ids.\n  // _(CDROMAUDIOBUFSIZ, NONE, 0);\n  // _(SNDCTL_TMR_CONTINUE, NONE, 0);\n  // _(SNDCTL_TMR_START, NONE, 0);\n  // _(SNDCTL_TMR_STOP, NONE, 0);\n  // _(SOUND_MIXER_READ_LOUD, WRITE, sizeof(int)); // same as ...READ_ENHANCE\n  // _(SOUND_MIXER_READ_MUTE, WRITE, sizeof(int)); // same as ...READ_ENHANCE\n  // _(SOUND_MIXER_WRITE_LOUD, WRITE, sizeof(int)); // same as ...WRITE_ENHANCE\n  // _(SOUND_MIXER_WRITE_MUTE, WRITE, sizeof(int)); // same as ...WRITE_ENHANCE\n  _(BLKFLSBUF, NONE, 0);\n  _(BLKGETSIZE, WRITE, sizeof(uptr));\n  _(BLKRAGET, WRITE, sizeof(int));\n  _(BLKRASET, NONE, 0);\n  _(BLKROGET, WRITE, sizeof(int));\n  _(BLKROSET, READ, sizeof(int));\n  _(BLKRRPART, NONE, 0);\n  _(CDROMEJECT, NONE, 0);\n  _(CDROMEJECT_SW, NONE, 0);\n  _(CDROMMULTISESSION, WRITE, struct_cdrom_multisession_sz);\n  _(CDROMPAUSE, NONE, 0);\n  _(CDROMPLAYMSF, READ, struct_cdrom_msf_sz);\n  _(CDROMPLAYTRKIND, READ, struct_cdrom_ti_sz);\n  _(CDROMREADAUDIO, READ, struct_cdrom_read_audio_sz);\n  _(CDROMREADCOOKED, READ, struct_cdrom_msf_sz);\n  _(CDROMREADMODE1, READ, struct_cdrom_msf_sz);\n  _(CDROMREADMODE2, READ, struct_cdrom_msf_sz);\n  _(CDROMREADRAW, READ, struct_cdrom_msf_sz);\n  _(CDROMREADTOCENTRY, WRITE, struct_cdrom_tocentry_sz);\n  _(CDROMREADTOCHDR, WRITE, struct_cdrom_tochdr_sz);\n  _(CDROMRESET, NONE, 0);\n  _(CDROMRESUME, NONE, 0);\n  _(CDROMSEEK, READ, struct_cdrom_msf_sz);\n  _(CDROMSTART, NONE, 0);\n  _(CDROMSTOP, NONE, 0);\n  _(CDROMSUBCHNL, WRITE, struct_cdrom_subchnl_sz);\n  _(CDROMVOLCTRL, READ, struct_cdrom_volctrl_sz);\n  _(CDROMVOLREAD, WRITE, struct_cdrom_volctrl_sz);\n  _(CDROM_GET_UPC, WRITE, 8);\n  _(EVIOCGABS, WRITE, struct_input_absinfo_sz); // fixup\n  _(EVIOCGBIT, WRITE, struct_input_id_sz); // fixup\n  _(EVIOCGEFFECTS, WRITE, sizeof(int));\n  _(EVIOCGID, WRITE, struct_input_id_sz);\n  _(EVIOCGKEY, WRITE, 0);\n  _(EVIOCGKEYCODE, WRITE, sizeof(int) * 2);\n  _(EVIOCGLED, WRITE, 0);\n  _(EVIOCGNAME, WRITE, 0);\n  _(EVIOCGPHYS, WRITE, 0);\n  _(EVIOCGRAB, READ, sizeof(int));\n  _(EVIOCGREP, WRITE, sizeof(int) * 2);\n  _(EVIOCGSND, WRITE, 0);\n  _(EVIOCGSW, WRITE, 0);\n  _(EVIOCGUNIQ, WRITE, 0);\n  _(EVIOCGVERSION, WRITE, sizeof(int));\n  _(EVIOCRMFF, READ, sizeof(int));\n  _(EVIOCSABS, READ, struct_input_absinfo_sz); // fixup\n  _(EVIOCSFF, READ, struct_ff_effect_sz);\n  _(EVIOCSKEYCODE, READ, sizeof(int) * 2);\n  _(EVIOCSREP, READ, sizeof(int) * 2);\n  _(FDCLRPRM, NONE, 0);\n  _(FDDEFPRM, READ, struct_floppy_struct_sz);\n  _(FDFLUSH, NONE, 0);\n  _(FDFMTBEG, NONE, 0);\n  _(FDFMTEND, NONE, 0);\n  _(FDFMTTRK, READ, struct_format_descr_sz);\n  _(FDGETDRVPRM, WRITE, struct_floppy_drive_params_sz);\n  _(FDGETDRVSTAT, WRITE, struct_floppy_drive_struct_sz);\n  _(FDGETDRVTYP, WRITE, 16);\n  _(FDGETFDCSTAT, WRITE, struct_floppy_fdc_state_sz);\n  _(FDGETMAXERRS, WRITE, struct_floppy_max_errors_sz);\n  _(FDGETPRM, WRITE, struct_floppy_struct_sz);\n  _(FDMSGOFF, NONE, 0);\n  _(FDMSGON, NONE, 0);\n  _(FDPOLLDRVSTAT, WRITE, struct_floppy_drive_struct_sz);\n  _(FDRAWCMD, WRITE, struct_floppy_raw_cmd_sz);\n  _(FDRESET, NONE, 0);\n  _(FDSETDRVPRM, READ, struct_floppy_drive_params_sz);\n  _(FDSETEMSGTRESH, NONE, 0);\n  _(FDSETMAXERRS, READ, struct_floppy_max_errors_sz);\n  _(FDSETPRM, READ, struct_floppy_struct_sz);\n  _(FDTWADDLE, NONE, 0);\n  _(FDWERRORCLR, NONE, 0);\n  _(FDWERRORGET, WRITE, struct_floppy_write_errors_sz);\n  _(HDIO_DRIVE_CMD, WRITE, sizeof(int));\n  _(HDIO_GETGEO, WRITE, struct_hd_geometry_sz);\n  _(HDIO_GET_32BIT, WRITE, sizeof(int));\n  _(HDIO_GET_DMA, WRITE, sizeof(int));\n  _(HDIO_GET_IDENTITY, WRITE, struct_hd_driveid_sz);\n  _(HDIO_GET_KEEPSETTINGS, WRITE, sizeof(int));\n  _(HDIO_GET_MULTCOUNT, WRITE, sizeof(int));\n  _(HDIO_GET_NOWERR, WRITE, sizeof(int));\n  _(HDIO_GET_UNMASKINTR, WRITE, sizeof(int));\n  _(HDIO_SET_32BIT, NONE, 0);\n  _(HDIO_SET_DMA, NONE, 0);\n  _(HDIO_SET_KEEPSETTINGS, NONE, 0);\n  _(HDIO_SET_MULTCOUNT, NONE, 0);\n  _(HDIO_SET_NOWERR, NONE, 0);\n  _(HDIO_SET_UNMASKINTR, NONE, 0);\n  _(MTIOCGET, WRITE, struct_mtget_sz);\n  _(MTIOCPOS, WRITE, struct_mtpos_sz);\n  _(MTIOCTOP, READ, struct_mtop_sz);\n  _(PPPIOCGASYNCMAP, WRITE, sizeof(int));\n  _(PPPIOCGDEBUG, WRITE, sizeof(int));\n  _(PPPIOCGFLAGS, WRITE, sizeof(int));\n  _(PPPIOCGUNIT, WRITE, sizeof(int));\n  _(PPPIOCGXASYNCMAP, WRITE, sizeof(int) * 8);\n  _(PPPIOCSASYNCMAP, READ, sizeof(int));\n  _(PPPIOCSDEBUG, READ, sizeof(int));\n  _(PPPIOCSFLAGS, READ, sizeof(int));\n  _(PPPIOCSMAXCID, READ, sizeof(int));\n  _(PPPIOCSMRU, READ, sizeof(int));\n  _(PPPIOCSXASYNCMAP, READ, sizeof(int) * 8);\n  _(SIOCADDRT, READ, struct_rtentry_sz);\n  _(SIOCDARP, READ, struct_arpreq_sz);\n  _(SIOCDELRT, READ, struct_rtentry_sz);\n  _(SIOCDRARP, READ, struct_arpreq_sz);\n  _(SIOCGARP, WRITE, struct_arpreq_sz);\n  _(SIOCGIFENCAP, WRITE, sizeof(int));\n  _(SIOCGIFHWADDR, WRITE, struct_ifreq_sz);\n  _(SIOCGIFMAP, WRITE, struct_ifreq_sz);\n  _(SIOCGIFMEM, WRITE, struct_ifreq_sz);\n  _(SIOCGIFNAME, NONE, 0);\n  _(SIOCGIFSLAVE, NONE, 0);\n  _(SIOCGRARP, WRITE, struct_arpreq_sz);\n  _(SIOCGSTAMP, WRITE, timeval_sz);\n  _(SIOCSARP, READ, struct_arpreq_sz);\n  _(SIOCSIFENCAP, READ, sizeof(int));\n  _(SIOCSIFHWADDR, READ, struct_ifreq_sz);\n  _(SIOCSIFLINK, NONE, 0);\n  _(SIOCSIFMAP, READ, struct_ifreq_sz);\n  _(SIOCSIFMEM, READ, struct_ifreq_sz);\n  _(SIOCSIFSLAVE, NONE, 0);\n  _(SIOCSRARP, READ, struct_arpreq_sz);\n  _(SNDCTL_COPR_HALT, WRITE, struct_copr_debug_buf_sz);\n  _(SNDCTL_COPR_LOAD, READ, struct_copr_buffer_sz);\n  _(SNDCTL_COPR_RCODE, WRITE, struct_copr_debug_buf_sz);\n  _(SNDCTL_COPR_RCVMSG, WRITE, struct_copr_msg_sz);\n  _(SNDCTL_COPR_RDATA, WRITE, struct_copr_debug_buf_sz);\n  _(SNDCTL_COPR_RESET, NONE, 0);\n  _(SNDCTL_COPR_RUN, WRITE, struct_copr_debug_buf_sz);\n  _(SNDCTL_COPR_SENDMSG, READ, struct_copr_msg_sz);\n  _(SNDCTL_COPR_WCODE, READ, struct_copr_debug_buf_sz);\n  _(SNDCTL_COPR_WDATA, READ, struct_copr_debug_buf_sz);\n  _(SNDCTL_DSP_GETBLKSIZE, WRITE, sizeof(int));\n  _(SNDCTL_DSP_GETFMTS, WRITE, sizeof(int));\n  _(SNDCTL_DSP_NONBLOCK, NONE, 0);\n  _(SNDCTL_DSP_POST, NONE, 0);\n  _(SNDCTL_DSP_RESET, NONE, 0);\n  _(SNDCTL_DSP_SETFMT, WRITE, sizeof(int));\n  _(SNDCTL_DSP_SETFRAGMENT, WRITE, sizeof(int));\n  _(SNDCTL_DSP_SPEED, WRITE, sizeof(int));\n  _(SNDCTL_DSP_STEREO, WRITE, sizeof(int));\n  _(SNDCTL_DSP_SUBDIVIDE, WRITE, sizeof(int));\n  _(SNDCTL_DSP_SYNC, NONE, 0);\n  _(SNDCTL_FM_4OP_ENABLE, READ, sizeof(int));\n  _(SNDCTL_FM_LOAD_INSTR, READ, struct_sbi_instrument_sz);\n  _(SNDCTL_MIDI_INFO, WRITE, struct_midi_info_sz);\n  _(SNDCTL_MIDI_PRETIME, WRITE, sizeof(int));\n  _(SNDCTL_SEQ_CTRLRATE, WRITE, sizeof(int));\n  _(SNDCTL_SEQ_GETINCOUNT, WRITE, sizeof(int));\n  _(SNDCTL_SEQ_GETOUTCOUNT, WRITE, sizeof(int));\n  _(SNDCTL_SEQ_NRMIDIS, WRITE, sizeof(int));\n  _(SNDCTL_SEQ_NRSYNTHS, WRITE, sizeof(int));\n  _(SNDCTL_SEQ_OUTOFBAND, READ, struct_seq_event_rec_sz);\n  _(SNDCTL_SEQ_PANIC, NONE, 0);\n  _(SNDCTL_SEQ_PERCMODE, NONE, 0);\n  _(SNDCTL_SEQ_RESET, NONE, 0);\n  _(SNDCTL_SEQ_RESETSAMPLES, READ, sizeof(int));\n  _(SNDCTL_SEQ_SYNC, NONE, 0);\n  _(SNDCTL_SEQ_TESTMIDI, READ, sizeof(int));\n  _(SNDCTL_SEQ_THRESHOLD, READ, sizeof(int));\n  _(SNDCTL_SYNTH_INFO, WRITE, struct_synth_info_sz);\n  _(SNDCTL_SYNTH_MEMAVL, WRITE, sizeof(int));\n  _(SNDCTL_TMR_METRONOME, READ, sizeof(int));\n  _(SNDCTL_TMR_SELECT, WRITE, sizeof(int));\n  _(SNDCTL_TMR_SOURCE, WRITE, sizeof(int));\n  _(SNDCTL_TMR_TEMPO, WRITE, sizeof(int));\n  _(SNDCTL_TMR_TIMEBASE, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_ALTPCM, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_BASS, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_CAPS, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_CD, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_DEVMASK, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_ENHANCE, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_IGAIN, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_IMIX, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_LINE, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_LINE1, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_LINE2, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_LINE3, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_MIC, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_OGAIN, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_PCM, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_RECLEV, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_RECMASK, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_RECSRC, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_SPEAKER, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_STEREODEVS, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_SYNTH, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_TREBLE, WRITE, sizeof(int));\n  _(SOUND_MIXER_READ_VOLUME, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_ALTPCM, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_BASS, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_CD, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_ENHANCE, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_IGAIN, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_IMIX, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_LINE, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_LINE1, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_LINE2, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_LINE3, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_MIC, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_OGAIN, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_PCM, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_RECLEV, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_RECSRC, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_SPEAKER, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_SYNTH, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_TREBLE, WRITE, sizeof(int));\n  _(SOUND_MIXER_WRITE_VOLUME, WRITE, sizeof(int));\n  _(SOUND_PCM_READ_BITS, WRITE, sizeof(int));\n  _(SOUND_PCM_READ_CHANNELS, WRITE, sizeof(int));\n  _(SOUND_PCM_READ_FILTER, WRITE, sizeof(int));\n  _(SOUND_PCM_READ_RATE, WRITE, sizeof(int));\n  _(SOUND_PCM_WRITE_CHANNELS, WRITE, sizeof(int));\n  _(SOUND_PCM_WRITE_FILTER, WRITE, sizeof(int));\n  _(TCFLSH, NONE, 0);\n  _(TCGETA, WRITE, struct_termio_sz);\n  _(TCGETS, WRITE, struct_termios_sz);\n  _(TCSBRK, NONE, 0);\n  _(TCSBRKP, NONE, 0);\n  _(TCSETA, READ, struct_termio_sz);\n  _(TCSETAF, READ, struct_termio_sz);\n  _(TCSETAW, READ, struct_termio_sz);\n  _(TCSETS, READ, struct_termios_sz);\n  _(TCSETSF, READ, struct_termios_sz);\n  _(TCSETSW, READ, struct_termios_sz);\n  _(TCXONC, NONE, 0);\n  _(TIOCGLCKTRMIOS, WRITE, struct_termios_sz);\n  _(TIOCGSOFTCAR, WRITE, sizeof(int));\n  _(TIOCINQ, WRITE, sizeof(int));\n  _(TIOCLINUX, READ, sizeof(char));\n  _(TIOCSERCONFIG, NONE, 0);\n  _(TIOCSERGETLSR, WRITE, sizeof(int));\n  _(TIOCSERGWILD, WRITE, sizeof(int));\n  _(TIOCSERSWILD, READ, sizeof(int));\n  _(TIOCSLCKTRMIOS, READ, struct_termios_sz);\n  _(TIOCSSOFTCAR, READ, sizeof(int));\n  _(VT_ACTIVATE, NONE, 0);\n  _(VT_DISALLOCATE, NONE, 0);\n  _(VT_GETMODE, WRITE, struct_vt_mode_sz);\n  _(VT_GETSTATE, WRITE, struct_vt_stat_sz);\n  _(VT_OPENQRY, WRITE, sizeof(int));\n  _(VT_RELDISP, NONE, 0);\n  _(VT_RESIZE, READ, struct_vt_sizes_sz);\n  _(VT_RESIZEX, READ, struct_vt_consize_sz);\n  _(VT_SENDSIG, NONE, 0);\n  _(VT_SETMODE, READ, struct_vt_mode_sz);\n  _(VT_WAITACTIVE, NONE, 0);\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n  // _(SIOCDEVPLIP, WRITE, struct_ifreq_sz); // the same as EQL_ENSLAVE\n  _(CYGETDEFTHRESH, WRITE, sizeof(int));\n  _(CYGETDEFTIMEOUT, WRITE, sizeof(int));\n  _(CYGETMON, WRITE, struct_cyclades_monitor_sz);\n  _(CYGETTHRESH, WRITE, sizeof(int));\n  _(CYGETTIMEOUT, WRITE, sizeof(int));\n  _(CYSETDEFTHRESH, NONE, 0);\n  _(CYSETDEFTIMEOUT, NONE, 0);\n  _(CYSETTHRESH, NONE, 0);\n  _(CYSETTIMEOUT, NONE, 0);\n  _(EQL_EMANCIPATE, WRITE, struct_ifreq_sz);\n  _(EQL_ENSLAVE, WRITE, struct_ifreq_sz);\n  _(EQL_GETMASTRCFG, WRITE, struct_ifreq_sz);\n  _(EQL_GETSLAVECFG, WRITE, struct_ifreq_sz);\n  _(EQL_SETMASTRCFG, WRITE, struct_ifreq_sz);\n  _(EQL_SETSLAVECFG, WRITE, struct_ifreq_sz);\n  _(EVIOCGKEYCODE_V2, WRITE, struct_input_keymap_entry_sz);\n  _(EVIOCGPROP, WRITE, 0);\n  _(EVIOCSKEYCODE_V2, READ, struct_input_keymap_entry_sz);\n  _(FS_IOC_GETFLAGS, WRITE, sizeof(int));\n  _(FS_IOC_GETVERSION, WRITE, sizeof(int));\n  _(FS_IOC_SETFLAGS, READ, sizeof(int));\n  _(FS_IOC_SETVERSION, READ, sizeof(int));\n  _(GIO_CMAP, WRITE, 48);\n  _(GIO_FONT, WRITE, 8192);\n  _(GIO_SCRNMAP, WRITE, e_tabsz);\n  _(GIO_UNIMAP, WRITE, struct_unimapdesc_sz);\n  _(GIO_UNISCRNMAP, WRITE, sizeof(short) * e_tabsz);\n  _(KDADDIO, NONE, 0);\n  _(KDDELIO, NONE, 0);\n  _(KDDISABIO, NONE, 0);\n  _(KDENABIO, NONE, 0);\n  _(KDGETKEYCODE, WRITE, struct_kbkeycode_sz);\n  _(KDGETLED, WRITE, 1);\n  _(KDGETMODE, WRITE, sizeof(int));\n  _(KDGKBDIACR, WRITE, struct_kbdiacrs_sz);\n  _(KDGKBENT, WRITE, struct_kbentry_sz);\n  _(KDGKBLED, WRITE, sizeof(int));\n  _(KDGKBMETA, WRITE, sizeof(int));\n  _(KDGKBMODE, WRITE, sizeof(int));\n  _(KDGKBSENT, WRITE, struct_kbsentry_sz);\n  _(KDGKBTYPE, WRITE, 1);\n  _(KDMAPDISP, NONE, 0);\n  _(KDMKTONE, NONE, 0);\n  _(KDSETKEYCODE, READ, struct_kbkeycode_sz);\n  _(KDSETLED, NONE, 0);\n  _(KDSETMODE, NONE, 0);\n  _(KDSIGACCEPT, NONE, 0);\n  _(KDSKBDIACR, READ, struct_kbdiacrs_sz);\n  _(KDSKBENT, READ, struct_kbentry_sz);\n  _(KDSKBLED, NONE, 0);\n  _(KDSKBMETA, NONE, 0);\n  _(KDSKBMODE, NONE, 0);\n  _(KDSKBSENT, READ, struct_kbsentry_sz);\n  _(KDUNMAPDISP, NONE, 0);\n  _(KIOCSOUND, NONE, 0);\n  _(LPABORT, NONE, 0);\n  _(LPABORTOPEN, NONE, 0);\n  _(LPCAREFUL, NONE, 0);\n  _(LPCHAR, NONE, 0);\n  _(LPGETIRQ, WRITE, sizeof(int));\n  _(LPGETSTATUS, WRITE, sizeof(int));\n  _(LPRESET, NONE, 0);\n  _(LPSETIRQ, NONE, 0);\n  _(LPTIME, NONE, 0);\n  _(LPWAIT, NONE, 0);\n  _(MTIOCGETCONFIG, WRITE, struct_mtconfiginfo_sz);\n  _(MTIOCSETCONFIG, READ, struct_mtconfiginfo_sz);\n  _(PIO_CMAP, NONE, 0);\n  _(PIO_FONT, READ, 8192);\n  _(PIO_SCRNMAP, READ, e_tabsz);\n  _(PIO_UNIMAP, READ, struct_unimapdesc_sz);\n  _(PIO_UNIMAPCLR, READ, struct_unimapinit_sz);\n  _(PIO_UNISCRNMAP, READ, sizeof(short) * e_tabsz);\n  _(SCSI_IOCTL_PROBE_HOST, READ, sizeof(int));\n  _(SCSI_IOCTL_TAGGED_DISABLE, NONE, 0);\n  _(SCSI_IOCTL_TAGGED_ENABLE, NONE, 0);\n  _(SNDCTL_DSP_GETISPACE, WRITE, struct_audio_buf_info_sz);\n  _(SNDCTL_DSP_GETOSPACE, WRITE, struct_audio_buf_info_sz);\n  _(TIOCGSERIAL, WRITE, struct_serial_struct_sz);\n  _(TIOCSERGETMULTI, WRITE, struct_serial_multiport_struct_sz);\n  _(TIOCSERSETMULTI, READ, struct_serial_multiport_struct_sz);\n  _(TIOCSSERIAL, READ, struct_serial_struct_sz);\n\n  // The following ioctl requests are shared between AX25, IPX, netrom and\n  // mrouted.\n  // _(SIOCAIPXITFCRT, READ, sizeof(char));\n  // _(SIOCAX25GETUID, READ, struct_sockaddr_ax25_sz);\n  // _(SIOCNRGETPARMS, WRITE, struct_nr_parms_struct_sz);\n  // _(SIOCAIPXPRISLT, READ, sizeof(char));\n  // _(SIOCNRSETPARMS, READ, struct_nr_parms_struct_sz);\n  // _(SIOCAX25ADDUID, READ, struct_sockaddr_ax25_sz);\n  // _(SIOCNRDECOBS, NONE, 0);\n  // _(SIOCAX25DELUID, READ, struct_sockaddr_ax25_sz);\n  // _(SIOCIPXCFGDATA, WRITE, struct_ipx_config_data_sz);\n  // _(SIOCAX25NOUID, READ, sizeof(int));\n  // _(SIOCNRRTCTL, READ, sizeof(int));\n  // _(SIOCAX25DIGCTL, READ, sizeof(int));\n  // _(SIOCAX25GETPARMS, WRITE, struct_ax25_parms_struct_sz);\n  // _(SIOCAX25SETPARMS, READ, struct_ax25_parms_struct_sz);\n#endif\n#undef _\n}\n\nstatic bool ioctl_initialized = false;\n\nstruct ioctl_desc_compare {\n  bool operator()(const ioctl_desc& left, const ioctl_desc& right) const {\n    return left.req < right.req;\n  }\n};\n\nstatic void ioctl_init() {\n  ioctl_table_fill();\n  InternalSort(&ioctl_table, ioctl_table_size, ioctl_desc_compare());\n\n  bool bad = false;\n  for (unsigned i = 0; i < ioctl_table_size - 1; ++i) {\n    if (ioctl_table[i].req >= ioctl_table[i + 1].req) {\n      Printf(\"Duplicate or unsorted ioctl request id %x >= %x (%s vs %s)\\n\",\n             ioctl_table[i].req, ioctl_table[i + 1].req, ioctl_table[i].name,\n             ioctl_table[i + 1].name);\n      bad = true;\n    }\n  }\n\n  if (bad) Die();\n\n  ioctl_initialized = true;\n}\n\n// Handle the most evil ioctls that encode argument value as part of request id.\nstatic unsigned ioctl_request_fixup(unsigned req) {\n#if SANITIZER_LINUX\n  // Strip size and event number.\n  const unsigned kEviocgbitMask =\n      (IOC_SIZEMASK << IOC_SIZESHIFT) | EVIOC_EV_MAX;\n  if ((req & ~kEviocgbitMask) == IOCTL_EVIOCGBIT)\n    return IOCTL_EVIOCGBIT;\n  // Strip absolute axis number.\n  if ((req & ~EVIOC_ABS_MAX) == IOCTL_EVIOCGABS)\n    return IOCTL_EVIOCGABS;\n  if ((req & ~EVIOC_ABS_MAX) == IOCTL_EVIOCSABS)\n    return IOCTL_EVIOCSABS;\n#endif\n  return req;\n}\n\nstatic const ioctl_desc *ioctl_table_lookup(unsigned req) {\n  int left = 0;\n  int right = ioctl_table_size;\n  while (left < right) {\n    int mid = (left + right) / 2;\n    if (ioctl_table[mid].req < req)\n      left = mid + 1;\n    else\n      right = mid;\n  }\n  if (left == right && ioctl_table[left].req == req)\n    return ioctl_table + left;\n  else\n    return nullptr;\n}\n\nstatic bool ioctl_decode(unsigned req, ioctl_desc *desc) {\n  CHECK(desc);\n  desc->req = req;\n  desc->name = \"<DECODED_IOCTL>\";\n  desc->size = IOC_SIZE(req);\n  // Sanity check.\n  if (desc->size > 0xFFFF) return false;\n  unsigned dir = IOC_DIR(req);\n  switch (dir) {\n    case IOC_NONE:\n      desc->type = ioctl_desc::NONE;\n      break;\n    case IOC_READ | IOC_WRITE:\n      desc->type = ioctl_desc::READWRITE;\n      break;\n    case IOC_READ:\n      desc->type = ioctl_desc::WRITE;\n      break;\n    case IOC_WRITE:\n      desc->type = ioctl_desc::READ;\n      break;\n    default:\n      return false;\n  }\n  // Size can be 0 iff type is NONE.\n  if ((desc->type == IOC_NONE) != (desc->size == 0)) return false;\n  // Sanity check.\n  if (IOC_TYPE(req) == 0) return false;\n  return true;\n}\n\nstatic const ioctl_desc *ioctl_lookup(unsigned req) {\n  req = ioctl_request_fixup(req);\n  const ioctl_desc *desc = ioctl_table_lookup(req);\n  if (desc) return desc;\n\n  // Try stripping access size from the request id.\n  desc = ioctl_table_lookup(req & ~(IOC_SIZEMASK << IOC_SIZESHIFT));\n  // Sanity check: requests that encode access size are either read or write and\n  // have size of 0 in the table.\n  if (desc && desc->size == 0 &&\n      (desc->type == ioctl_desc::READWRITE || desc->type == ioctl_desc::WRITE ||\n       desc->type == ioctl_desc::READ))\n    return desc;\n  return nullptr;\n}\n\nstatic void ioctl_common_pre(void *ctx, const ioctl_desc *desc, int d,\n                             unsigned request, void *arg) {\n  if (desc->type == ioctl_desc::READ || desc->type == ioctl_desc::READWRITE) {\n    unsigned size = desc->size ? desc->size : IOC_SIZE(request);\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, arg, size);\n  }\n  if (desc->type != ioctl_desc::CUSTOM)\n    return;\n  if (request == IOCTL_SIOCGIFCONF) {\n    struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg;\n    COMMON_INTERCEPTOR_READ_RANGE(ctx, &ifc->ifc_len, sizeof(ifc->ifc_len));\n  }\n}\n\nstatic void ioctl_common_post(void *ctx, const ioctl_desc *desc, int res, int d,\n                              unsigned request, void *arg) {\n  if (desc->type == ioctl_desc::WRITE || desc->type == ioctl_desc::READWRITE) {\n    // FIXME: add verbose output\n    unsigned size = desc->size ? desc->size : IOC_SIZE(request);\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, arg, size);\n  }\n  if (desc->type != ioctl_desc::CUSTOM)\n    return;\n  if (request == IOCTL_SIOCGIFCONF) {\n    struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg;\n    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifc->ifc_ifcu.ifcu_req, ifc->ifc_len);\n  }\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cc",
    "content": "//===-- sanitizer_common_libcdep.cc ---------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common.h\"\n\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_stackdepot.h\"\n#include \"sanitizer_stacktrace.h\"\n#include \"sanitizer_symbolizer.h\"\n\n#if SANITIZER_POSIX\n#include \"sanitizer_posix.h\"\n#endif\n\nnamespace __sanitizer {\n\nbool ReportFile::SupportsColors() {\n  SpinMutexLock l(mu);\n  ReopenIfNecessary();\n  return SupportsColoredOutput(fd);\n}\n\nbool ColorizeReports() {\n  // FIXME: Add proper Windows support to AnsiColorDecorator and re-enable color\n  // printing on Windows.\n  if (SANITIZER_WINDOWS)\n    return false;\n\n  const char *flag = common_flags()->color;\n  return internal_strcmp(flag, \"always\") == 0 ||\n         (internal_strcmp(flag, \"auto\") == 0 && report_file.SupportsColors());\n}\n\nstatic void (*sandboxing_callback)();\nvoid SetSandboxingCallback(void (*f)()) {\n  sandboxing_callback = f;\n}\n\nvoid ReportErrorSummary(const char *error_type, StackTrace *stack) {\n#if !SANITIZER_GO\n  if (!common_flags()->print_summary)\n    return;\n  if (stack->size == 0) {\n    ReportErrorSummary(error_type);\n    return;\n  }\n  // Currently, we include the first stack frame into the report summary.\n  // Maybe sometimes we need to choose another frame (e.g. skip memcpy/etc).\n  uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]);\n  SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc);\n  ReportErrorSummary(error_type, frame->info);\n  frame->ClearAll();\n#endif\n}\n\nstatic void (*SoftRssLimitExceededCallback)(bool exceeded);\nvoid SetSoftRssLimitExceededCallback(void (*Callback)(bool exceeded)) {\n  CHECK_EQ(SoftRssLimitExceededCallback, nullptr);\n  SoftRssLimitExceededCallback = Callback;\n}\n\nvoid BackgroundThread(void *arg) {\n  uptr hard_rss_limit_mb = common_flags()->hard_rss_limit_mb;\n  uptr soft_rss_limit_mb = common_flags()->soft_rss_limit_mb;\n  uptr prev_reported_rss = 0;\n  uptr prev_reported_stack_depot_size = 0;\n  bool reached_soft_rss_limit = false;\n  while (true) {\n    SleepForMillis(100);\n    uptr current_rss_mb = GetRSS() >> 20;\n    if (Verbosity()) {\n      // If RSS has grown 10% since last time, print some information.\n      if (prev_reported_rss * 11 / 10 < current_rss_mb) {\n        Printf(\"%s: RSS: %zdMb\\n\", SanitizerToolName, current_rss_mb);\n        prev_reported_rss = current_rss_mb;\n      }\n      // If stack depot has grown 10% since last time, print it too.\n      StackDepotStats *stack_depot_stats = StackDepotGetStats();\n      if (prev_reported_stack_depot_size * 11 / 10 <\n          stack_depot_stats->allocated) {\n        Printf(\"%s: StackDepot: %zd ids; %zdM allocated\\n\",\n               SanitizerToolName,\n               stack_depot_stats->n_uniq_ids,\n               stack_depot_stats->allocated >> 20);\n        prev_reported_stack_depot_size = stack_depot_stats->allocated;\n      }\n    }\n    // Check RSS against the limit.\n    if (hard_rss_limit_mb && hard_rss_limit_mb < current_rss_mb) {\n      Report(\"%s: hard rss limit exhausted (%zdMb vs %zdMb)\\n\",\n             SanitizerToolName, hard_rss_limit_mb, current_rss_mb);\n      DumpProcessMap();\n      Die();\n    }\n    if (soft_rss_limit_mb) {\n      if (soft_rss_limit_mb < current_rss_mb && !reached_soft_rss_limit) {\n        reached_soft_rss_limit = true;\n        Report(\"%s: soft rss limit exhausted (%zdMb vs %zdMb)\\n\",\n               SanitizerToolName, soft_rss_limit_mb, current_rss_mb);\n        if (SoftRssLimitExceededCallback)\n          SoftRssLimitExceededCallback(true);\n      } else if (soft_rss_limit_mb >= current_rss_mb &&\n                 reached_soft_rss_limit) {\n        reached_soft_rss_limit = false;\n        if (SoftRssLimitExceededCallback)\n          SoftRssLimitExceededCallback(false);\n      }\n    }\n  }\n}\n\nvoid WriteToSyslog(const char *msg) {\n  InternalScopedString msg_copy(kErrorMessageBufferSize);\n  msg_copy.append(\"%s\", msg);\n  char *p = msg_copy.data();\n  char *q;\n\n  // Remove color sequences since syslogs cannot print them.\n  RemoveANSIEscapeSequencesFromString(p);\n\n  // Print one line at a time.\n  // syslog, at least on Android, has an implicit message length limit.\n  do {\n    q = internal_strchr(p, '\\n');\n    if (q)\n      *q = '\\0';\n    WriteOneLineToSyslog(p);\n    if (q)\n      p = q + 1;\n  } while (q);\n}\n\nvoid MaybeStartBackgroudThread() {\n#if SANITIZER_LINUX && \\\n    !SANITIZER_GO  // Need to implement/test on other platforms.\n  // Start the background thread if one of the rss limits is given.\n  if (!common_flags()->hard_rss_limit_mb &&\n      !common_flags()->soft_rss_limit_mb) return;\n  if (!&real_pthread_create) return;  // Can't spawn the thread anyway.\n  internal_start_thread(BackgroundThread, nullptr);\n#endif\n}\n\n}  // namespace __sanitizer\n\nvoid NOINLINE\n__sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args) {\n  PrepareForSandboxing(args);\n  if (sandboxing_callback)\n    sandboxing_callback();\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_common_nolibc.cc",
    "content": "//===-- sanitizer_common_nolibc.cc ----------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file contains stubs for libc function to facilitate optional use of\n// libc in no-libcdep sources.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n#include \"sanitizer_common.h\"\n#include \"sanitizer_libc.h\"\n\nnamespace __sanitizer {\n\n#if SANITIZER_LINUX\nbool ShouldLogAfterPrintf() { return false; }\n#endif\nvoid WriteToSyslog(const char *buffer) {}\nvoid Abort() { internal__exit(1); }\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc",
    "content": "//===-- sanitizer_common_syscalls.inc ---------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Common syscalls handlers for tools like AddressSanitizer,\n// ThreadSanitizer, MemorySanitizer, etc.\n//\n// This file should be included into the tool's interceptor file,\n// which has to define it's own macros:\n//   COMMON_SYSCALL_PRE_READ_RANGE\n//          Called in prehook for regions that will be read by the kernel and\n//          must be initialized.\n//   COMMON_SYSCALL_PRE_WRITE_RANGE\n//          Called in prehook for regions that will be written to by the kernel\n//          and must be addressable. The actual write range may be smaller than\n//          reported in the prehook. See POST_WRITE_RANGE.\n//   COMMON_SYSCALL_POST_READ_RANGE\n//          Called in posthook for regions that were read by the kernel. Does\n//          not make much sense.\n//   COMMON_SYSCALL_POST_WRITE_RANGE\n//          Called in posthook for regions that were written to by the kernel\n//          and are now initialized.\n//   COMMON_SYSCALL_ACQUIRE(addr)\n//          Acquire memory visibility from addr.\n//   COMMON_SYSCALL_RELEASE(addr)\n//          Release memory visibility to addr.\n//   COMMON_SYSCALL_FD_CLOSE(fd)\n//          Called before closing file descriptor fd.\n//   COMMON_SYSCALL_FD_ACQUIRE(fd)\n//          Acquire memory visibility from fd.\n//   COMMON_SYSCALL_FD_RELEASE(fd)\n//          Release memory visibility to fd.\n//   COMMON_SYSCALL_PRE_FORK()\n//          Called before fork syscall.\n//   COMMON_SYSCALL_POST_FORK(long res)\n//          Called after fork syscall.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n#if SANITIZER_LINUX\n\n#include \"sanitizer_libc.h\"\n\n#define PRE_SYSCALL(name)                                                      \\\n  SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_pre_impl_##name\n#define PRE_READ(p, s) COMMON_SYSCALL_PRE_READ_RANGE(p, s)\n#define PRE_WRITE(p, s) COMMON_SYSCALL_PRE_WRITE_RANGE(p, s)\n\n#define POST_SYSCALL(name)                                                     \\\n  SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_post_impl_##name\n#define POST_READ(p, s) COMMON_SYSCALL_POST_READ_RANGE(p, s)\n#define POST_WRITE(p, s) COMMON_SYSCALL_POST_WRITE_RANGE(p, s)\n\n#ifndef COMMON_SYSCALL_ACQUIRE\n# define COMMON_SYSCALL_ACQUIRE(addr) ((void)(addr))\n#endif\n\n#ifndef COMMON_SYSCALL_RELEASE\n# define COMMON_SYSCALL_RELEASE(addr) ((void)(addr))\n#endif\n\n#ifndef COMMON_SYSCALL_FD_CLOSE\n# define COMMON_SYSCALL_FD_CLOSE(fd) ((void)(fd))\n#endif\n\n#ifndef COMMON_SYSCALL_FD_ACQUIRE\n# define COMMON_SYSCALL_FD_ACQUIRE(fd) ((void)(fd))\n#endif\n\n#ifndef COMMON_SYSCALL_FD_RELEASE\n# define COMMON_SYSCALL_FD_RELEASE(fd) ((void)(fd))\n#endif\n\n#ifndef COMMON_SYSCALL_PRE_FORK\n# define COMMON_SYSCALL_PRE_FORK() {}\n#endif\n\n#ifndef COMMON_SYSCALL_POST_FORK\n# define COMMON_SYSCALL_POST_FORK(res) {}\n#endif\n\n// FIXME: do some kind of PRE_READ for all syscall arguments (int(s) and such).\n\nextern \"C\" {\nstruct sanitizer_kernel_iovec {\n  void *iov_base;\n  unsigned long iov_len;\n};\n\nstruct sanitizer_kernel_msghdr {\n  void *msg_name;\n  int msg_namelen;\n  struct sanitizer_kernel_iovec *msg_iov;\n  unsigned long msg_iovlen;\n  void *msg_control;\n  unsigned long msg_controllen;\n  unsigned msg_flags;\n};\n\nstruct sanitizer_kernel_mmsghdr {\n  struct sanitizer_kernel_msghdr msg_hdr;\n  unsigned msg_len;\n};\n\nstruct sanitizer_kernel_timespec {\n  long tv_sec;\n  long tv_nsec;\n};\n\nstruct sanitizer_kernel_timeval {\n  long tv_sec;\n  long tv_usec;\n};\n\nstruct sanitizer_kernel_rusage {\n  struct sanitizer_kernel_timeval ru_timeval[2];\n  long ru_long[14];\n};\n\nstruct sanitizer_kernel_sockaddr {\n  unsigned short sa_family;\n  char sa_data[14];\n};\n\n// Real sigset size is always passed as a syscall argument.\n// Declare it \"void\" to catch sizeof(kernel_sigset_t).\ntypedef void kernel_sigset_t;\n\nstatic void kernel_write_iovec(const __sanitizer_iovec *iovec,\n                        SIZE_T iovlen, SIZE_T maxlen) {\n  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {\n    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);\n    POST_WRITE(iovec[i].iov_base, sz);\n    maxlen -= sz;\n  }\n}\n\n// This functions uses POST_READ, because it needs to run after syscall to know\n// the real read range.\nstatic void kernel_read_iovec(const __sanitizer_iovec *iovec,\n                       SIZE_T iovlen, SIZE_T maxlen) {\n  POST_READ(iovec, sizeof(*iovec) * iovlen);\n  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {\n    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);\n    POST_READ(iovec[i].iov_base, sz);\n    maxlen -= sz;\n  }\n}\n\nPRE_SYSCALL(recvmsg)(long sockfd, sanitizer_kernel_msghdr *msg, long flags) {\n  PRE_READ(msg, sizeof(*msg));\n}\n\nPOST_SYSCALL(recvmsg)(long res, long sockfd, sanitizer_kernel_msghdr *msg,\n                      long flags) {\n  if (res >= 0) {\n    if (msg) {\n      for (unsigned long i = 0; i < msg->msg_iovlen; ++i) {\n        POST_WRITE(msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len);\n      }\n      POST_WRITE(msg->msg_control, msg->msg_controllen);\n    }\n  }\n}\n\nPRE_SYSCALL(recvmmsg)(long fd, sanitizer_kernel_mmsghdr *msg, long vlen,\n                      long flags, void *timeout) {\n  PRE_READ(msg, vlen * sizeof(*msg));\n}\n\nPOST_SYSCALL(recvmmsg)(long res, long fd, sanitizer_kernel_mmsghdr *msg,\n                       long vlen, long flags, void *timeout) {\n  if (res >= 0) {\n    if (msg) {\n      for (unsigned long i = 0; i < msg->msg_hdr.msg_iovlen; ++i) {\n        POST_WRITE(msg->msg_hdr.msg_iov[i].iov_base,\n                   msg->msg_hdr.msg_iov[i].iov_len);\n      }\n      POST_WRITE(msg->msg_hdr.msg_control, msg->msg_hdr.msg_controllen);\n      POST_WRITE(&msg->msg_len, sizeof(msg->msg_len));\n    }\n    if (timeout) POST_WRITE(timeout, struct_timespec_sz);\n  }\n}\n\nPRE_SYSCALL(read)(long fd, void *buf, uptr count) {\n  if (buf) {\n    PRE_WRITE(buf, count);\n  }\n}\n\nPOST_SYSCALL(read)(long res, long fd, void *buf, uptr count) {\n  if (res > 0 && buf) {\n    POST_WRITE(buf, res);\n  }\n}\n\nPRE_SYSCALL(time)(void *tloc) {}\n\nPOST_SYSCALL(time)(long res, void *tloc) {\n  if (res >= 0) {\n    if (tloc) POST_WRITE(tloc, sizeof(long));\n  }\n}\n\nPRE_SYSCALL(stime)(void *tptr) {}\n\nPOST_SYSCALL(stime)(long res, void *tptr) {\n  if (res >= 0) {\n    if (tptr) POST_WRITE(tptr, sizeof(long));\n  }\n}\n\nPRE_SYSCALL(gettimeofday)(void *tv, void *tz) {}\n\nPOST_SYSCALL(gettimeofday)(long res, void *tv, void *tz) {\n  if (res >= 0) {\n    if (tv) POST_WRITE(tv, timeval_sz);\n    if (tz) POST_WRITE(tz, struct_timezone_sz);\n  }\n}\n\nPRE_SYSCALL(settimeofday)(void *tv, void *tz) {}\n\nPOST_SYSCALL(settimeofday)(long res, void *tv, void *tz) {\n  if (res >= 0) {\n    if (tv) POST_WRITE(tv, timeval_sz);\n    if (tz) POST_WRITE(tz, struct_timezone_sz);\n  }\n}\n\n#if !SANITIZER_ANDROID\nPRE_SYSCALL(adjtimex)(void *txc_p) {}\n\nPOST_SYSCALL(adjtimex)(long res, void *txc_p) {\n  if (res >= 0) {\n    if (txc_p) POST_WRITE(txc_p, struct_timex_sz);\n  }\n}\n#endif\n\nPRE_SYSCALL(times)(void *tbuf) {}\n\nPOST_SYSCALL(times)(long res, void *tbuf) {\n  if (res >= 0) {\n    if (tbuf) POST_WRITE(tbuf, struct_tms_sz);\n  }\n}\n\nPRE_SYSCALL(gettid)() {}\n\nPOST_SYSCALL(gettid)(long res) {}\n\nPRE_SYSCALL(nanosleep)(void *rqtp, void *rmtp) {}\n\nPOST_SYSCALL(nanosleep)(long res, void *rqtp, void *rmtp) {\n  if (res >= 0) {\n    if (rqtp) POST_WRITE(rqtp, struct_timespec_sz);\n    if (rmtp) POST_WRITE(rmtp, struct_timespec_sz);\n  }\n}\n\nPRE_SYSCALL(alarm)(long seconds) {}\n\nPOST_SYSCALL(alarm)(long res, long seconds) {}\n\nPRE_SYSCALL(getpid)() {}\n\nPOST_SYSCALL(getpid)(long res) {}\n\nPRE_SYSCALL(getppid)() {}\n\nPOST_SYSCALL(getppid)(long res) {}\n\nPRE_SYSCALL(getuid)() {}\n\nPOST_SYSCALL(getuid)(long res) {}\n\nPRE_SYSCALL(geteuid)() {}\n\nPOST_SYSCALL(geteuid)(long res) {}\n\nPRE_SYSCALL(getgid)() {}\n\nPOST_SYSCALL(getgid)(long res) {}\n\nPRE_SYSCALL(getegid)() {}\n\nPOST_SYSCALL(getegid)(long res) {}\n\nPRE_SYSCALL(getresuid)(void *ruid, void *euid, void *suid) {}\n\nPOST_SYSCALL(getresuid)(long res, void *ruid, void *euid, void *suid) {\n  if (res >= 0) {\n    if (ruid) POST_WRITE(ruid, sizeof(unsigned));\n    if (euid) POST_WRITE(euid, sizeof(unsigned));\n    if (suid) POST_WRITE(suid, sizeof(unsigned));\n  }\n}\n\nPRE_SYSCALL(getresgid)(void *rgid, void *egid, void *sgid) {}\n\nPOST_SYSCALL(getresgid)(long res, void *rgid, void *egid, void *sgid) {\n  if (res >= 0) {\n    if (rgid) POST_WRITE(rgid, sizeof(unsigned));\n    if (egid) POST_WRITE(egid, sizeof(unsigned));\n    if (sgid) POST_WRITE(sgid, sizeof(unsigned));\n  }\n}\n\nPRE_SYSCALL(getpgid)(long pid) {}\n\nPOST_SYSCALL(getpgid)(long res, long pid) {}\n\nPRE_SYSCALL(getpgrp)() {}\n\nPOST_SYSCALL(getpgrp)(long res) {}\n\nPRE_SYSCALL(getsid)(long pid) {}\n\nPOST_SYSCALL(getsid)(long res, long pid) {}\n\nPRE_SYSCALL(getgroups)(long gidsetsize, void *grouplist) {}\n\nPOST_SYSCALL(getgroups)(long res, long gidsetsize,\n                        __sanitizer___kernel_gid_t *grouplist) {\n  if (res >= 0) {\n    if (grouplist) POST_WRITE(grouplist, res * sizeof(*grouplist));\n  }\n}\n\nPRE_SYSCALL(setregid)(long rgid, long egid) {}\n\nPOST_SYSCALL(setregid)(long res, long rgid, long egid) {}\n\nPRE_SYSCALL(setgid)(long gid) {}\n\nPOST_SYSCALL(setgid)(long res, long gid) {}\n\nPRE_SYSCALL(setreuid)(long ruid, long euid) {}\n\nPOST_SYSCALL(setreuid)(long res, long ruid, long euid) {}\n\nPRE_SYSCALL(setuid)(long uid) {}\n\nPOST_SYSCALL(setuid)(long res, long uid) {}\n\nPRE_SYSCALL(setresuid)(long ruid, long euid, long suid) {}\n\nPOST_SYSCALL(setresuid)(long res, long ruid, long euid, long suid) {}\n\nPRE_SYSCALL(setresgid)(long rgid, long egid, long sgid) {}\n\nPOST_SYSCALL(setresgid)(long res, long rgid, long egid, long sgid) {}\n\nPRE_SYSCALL(setfsuid)(long uid) {}\n\nPOST_SYSCALL(setfsuid)(long res, long uid) {}\n\nPRE_SYSCALL(setfsgid)(long gid) {}\n\nPOST_SYSCALL(setfsgid)(long res, long gid) {}\n\nPRE_SYSCALL(setpgid)(long pid, long pgid) {}\n\nPOST_SYSCALL(setpgid)(long res, long pid, long pgid) {}\n\nPRE_SYSCALL(setsid)() {}\n\nPOST_SYSCALL(setsid)(long res) {}\n\nPRE_SYSCALL(setgroups)(long gidsetsize, __sanitizer___kernel_gid_t *grouplist) {\n  if (grouplist) POST_WRITE(grouplist, gidsetsize * sizeof(*grouplist));\n}\n\nPOST_SYSCALL(setgroups)(long res, long gidsetsize,\n                        __sanitizer___kernel_gid_t *grouplist) {}\n\nPRE_SYSCALL(acct)(const void *name) {\n  if (name)\n    PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1);\n}\n\nPOST_SYSCALL(acct)(long res, const void *name) {}\n\nPRE_SYSCALL(capget)(void *header, void *dataptr) {\n  if (header) PRE_READ(header, __user_cap_header_struct_sz);\n}\n\nPOST_SYSCALL(capget)(long res, void *header, void *dataptr) {\n  if (res >= 0)\n    if (dataptr) POST_WRITE(dataptr, __user_cap_data_struct_sz);\n}\n\nPRE_SYSCALL(capset)(void *header, const void *data) {\n  if (header) PRE_READ(header, __user_cap_header_struct_sz);\n  if (data) PRE_READ(data, __user_cap_data_struct_sz);\n}\n\nPOST_SYSCALL(capset)(long res, void *header, const void *data) {}\n\nPRE_SYSCALL(personality)(long personality) {}\n\nPOST_SYSCALL(personality)(long res, long personality) {}\n\nPRE_SYSCALL(sigpending)(void *set) {}\n\nPOST_SYSCALL(sigpending)(long res, void *set) {\n  if (res >= 0) {\n    if (set) POST_WRITE(set, old_sigset_t_sz);\n  }\n}\n\nPRE_SYSCALL(sigprocmask)(long how, void *set, void *oset) {}\n\nPOST_SYSCALL(sigprocmask)(long res, long how, void *set, void *oset) {\n  if (res >= 0) {\n    if (set) POST_WRITE(set, old_sigset_t_sz);\n    if (oset) POST_WRITE(oset, old_sigset_t_sz);\n  }\n}\n\nPRE_SYSCALL(getitimer)(long which, void *value) {}\n\nPOST_SYSCALL(getitimer)(long res, long which, void *value) {\n  if (res >= 0) {\n    if (value) POST_WRITE(value, struct_itimerval_sz);\n  }\n}\n\nPRE_SYSCALL(setitimer)(long which, void *value, void *ovalue) {}\n\nPOST_SYSCALL(setitimer)(long res, long which, void *value, void *ovalue) {\n  if (res >= 0) {\n    if (value) POST_WRITE(value, struct_itimerval_sz);\n    if (ovalue) POST_WRITE(ovalue, struct_itimerval_sz);\n  }\n}\n\nPRE_SYSCALL(timer_create)(long which_clock, void *timer_event_spec,\n                          void *created_timer_id) {}\n\nPOST_SYSCALL(timer_create)(long res, long which_clock, void *timer_event_spec,\n                           void *created_timer_id) {\n  if (res >= 0) {\n    if (timer_event_spec) POST_WRITE(timer_event_spec, struct_sigevent_sz);\n    if (created_timer_id) POST_WRITE(created_timer_id, sizeof(long));\n  }\n}\n\nPRE_SYSCALL(timer_gettime)(long timer_id, void *setting) {}\n\nPOST_SYSCALL(timer_gettime)(long res, long timer_id, void *setting) {\n  if (res >= 0) {\n    if (setting) POST_WRITE(setting, struct_itimerspec_sz);\n  }\n}\n\nPRE_SYSCALL(timer_getoverrun)(long timer_id) {}\n\nPOST_SYSCALL(timer_getoverrun)(long res, long timer_id) {}\n\nPRE_SYSCALL(timer_settime)(long timer_id, long flags, const void *new_setting,\n                           void *old_setting) {\n  if (new_setting) PRE_READ(new_setting, struct_itimerspec_sz);\n}\n\nPOST_SYSCALL(timer_settime)(long res, long timer_id, long flags,\n                            const void *new_setting, void *old_setting) {\n  if (res >= 0) {\n    if (old_setting) POST_WRITE(old_setting, struct_itimerspec_sz);\n  }\n}\n\nPRE_SYSCALL(timer_delete)(long timer_id) {}\n\nPOST_SYSCALL(timer_delete)(long res, long timer_id) {}\n\nPRE_SYSCALL(clock_settime)(long which_clock, const void *tp) {\n  if (tp) PRE_READ(tp, struct_timespec_sz);\n}\n\nPOST_SYSCALL(clock_settime)(long res, long which_clock, const void *tp) {}\n\nPRE_SYSCALL(clock_gettime)(long which_clock, void *tp) {}\n\nPOST_SYSCALL(clock_gettime)(long res, long which_clock, void *tp) {\n  if (res >= 0) {\n    if (tp) POST_WRITE(tp, struct_timespec_sz);\n  }\n}\n\n#if !SANITIZER_ANDROID\nPRE_SYSCALL(clock_adjtime)(long which_clock, void *tx) {}\n\nPOST_SYSCALL(clock_adjtime)(long res, long which_clock, void *tx) {\n  if (res >= 0) {\n    if (tx) POST_WRITE(tx, struct_timex_sz);\n  }\n}\n#endif\n\nPRE_SYSCALL(clock_getres)(long which_clock, void *tp) {}\n\nPOST_SYSCALL(clock_getres)(long res, long which_clock, void *tp) {\n  if (res >= 0) {\n    if (tp) POST_WRITE(tp, struct_timespec_sz);\n  }\n}\n\nPRE_SYSCALL(clock_nanosleep)(long which_clock, long flags, const void *rqtp,\n                             void *rmtp) {\n  if (rqtp) PRE_READ(rqtp, struct_timespec_sz);\n}\n\nPOST_SYSCALL(clock_nanosleep)(long res, long which_clock, long flags,\n                              const void *rqtp, void *rmtp) {\n  if (res >= 0) {\n    if (rmtp) POST_WRITE(rmtp, struct_timespec_sz);\n  }\n}\n\nPRE_SYSCALL(nice)(long increment) {}\n\nPOST_SYSCALL(nice)(long res, long increment) {}\n\nPRE_SYSCALL(sched_setscheduler)(long pid, long policy, void *param) {}\n\nPOST_SYSCALL(sched_setscheduler)(long res, long pid, long policy, void *param) {\n  if (res >= 0) {\n    if (param) POST_WRITE(param, struct_sched_param_sz);\n  }\n}\n\nPRE_SYSCALL(sched_setparam)(long pid, void *param) {\n  if (param) PRE_READ(param, struct_sched_param_sz);\n}\n\nPOST_SYSCALL(sched_setparam)(long res, long pid, void *param) {}\n\nPRE_SYSCALL(sched_getscheduler)(long pid) {}\n\nPOST_SYSCALL(sched_getscheduler)(long res, long pid) {}\n\nPRE_SYSCALL(sched_getparam)(long pid, void *param) {}\n\nPOST_SYSCALL(sched_getparam)(long res, long pid, void *param) {\n  if (res >= 0) {\n    if (param) POST_WRITE(param, struct_sched_param_sz);\n  }\n}\n\nPRE_SYSCALL(sched_setaffinity)(long pid, long len, void *user_mask_ptr) {\n  if (user_mask_ptr) PRE_READ(user_mask_ptr, len);\n}\n\nPOST_SYSCALL(sched_setaffinity)(long res, long pid, long len,\n                                void *user_mask_ptr) {}\n\nPRE_SYSCALL(sched_getaffinity)(long pid, long len, void *user_mask_ptr) {}\n\nPOST_SYSCALL(sched_getaffinity)(long res, long pid, long len,\n                                void *user_mask_ptr) {\n  if (res >= 0) {\n    if (user_mask_ptr) POST_WRITE(user_mask_ptr, len);\n  }\n}\n\nPRE_SYSCALL(sched_yield)() {}\n\nPOST_SYSCALL(sched_yield)(long res) {}\n\nPRE_SYSCALL(sched_get_priority_max)(long policy) {}\n\nPOST_SYSCALL(sched_get_priority_max)(long res, long policy) {}\n\nPRE_SYSCALL(sched_get_priority_min)(long policy) {}\n\nPOST_SYSCALL(sched_get_priority_min)(long res, long policy) {}\n\nPRE_SYSCALL(sched_rr_get_interval)(long pid, void *interval) {}\n\nPOST_SYSCALL(sched_rr_get_interval)(long res, long pid, void *interval) {\n  if (res >= 0) {\n    if (interval) POST_WRITE(interval, struct_timespec_sz);\n  }\n}\n\nPRE_SYSCALL(setpriority)(long which, long who, long niceval) {}\n\nPOST_SYSCALL(setpriority)(long res, long which, long who, long niceval) {}\n\nPRE_SYSCALL(getpriority)(long which, long who) {}\n\nPOST_SYSCALL(getpriority)(long res, long which, long who) {}\n\nPRE_SYSCALL(shutdown)(long arg0, long arg1) {}\n\nPOST_SYSCALL(shutdown)(long res, long arg0, long arg1) {}\n\nPRE_SYSCALL(reboot)(long magic1, long magic2, long cmd, void *arg) {}\n\nPOST_SYSCALL(reboot)(long res, long magic1, long magic2, long cmd, void *arg) {}\n\nPRE_SYSCALL(restart_syscall)() {}\n\nPOST_SYSCALL(restart_syscall)(long res) {}\n\nPRE_SYSCALL(kexec_load)(long entry, long nr_segments, void *segments,\n                        long flags) {}\n\nPOST_SYSCALL(kexec_load)(long res, long entry, long nr_segments, void *segments,\n                         long flags) {\n  if (res >= 0) {\n    if (segments) POST_WRITE(segments, struct_kexec_segment_sz);\n  }\n}\n\nPRE_SYSCALL(exit)(long error_code) {}\n\nPOST_SYSCALL(exit)(long res, long error_code) {}\n\nPRE_SYSCALL(exit_group)(long error_code) {}\n\nPOST_SYSCALL(exit_group)(long res, long error_code) {}\n\nPRE_SYSCALL(wait4)(long pid, void *stat_addr, long options, void *ru) {}\n\nPOST_SYSCALL(wait4)(long res, long pid, void *stat_addr, long options,\n                    void *ru) {\n  if (res >= 0) {\n    if (stat_addr) POST_WRITE(stat_addr, sizeof(int));\n    if (ru) POST_WRITE(ru, struct_rusage_sz);\n  }\n}\n\nPRE_SYSCALL(waitid)(long which, long pid, void *infop, long options, void *ru) {\n}\n\nPOST_SYSCALL(waitid)(long res, long which, long pid, void *infop, long options,\n                     void *ru) {\n  if (res >= 0) {\n    if (infop) POST_WRITE(infop, siginfo_t_sz);\n    if (ru) POST_WRITE(ru, struct_rusage_sz);\n  }\n}\n\nPRE_SYSCALL(waitpid)(long pid, void *stat_addr, long options) {}\n\nPOST_SYSCALL(waitpid)(long res, long pid, void *stat_addr, long options) {\n  if (res >= 0) {\n    if (stat_addr) POST_WRITE(stat_addr, sizeof(int));\n  }\n}\n\nPRE_SYSCALL(set_tid_address)(void *tidptr) {}\n\nPOST_SYSCALL(set_tid_address)(long res, void *tidptr) {\n  if (res >= 0) {\n    if (tidptr) POST_WRITE(tidptr, sizeof(int));\n  }\n}\n\nPRE_SYSCALL(init_module)(void *umod, long len, const void *uargs) {\n  if (uargs)\n    PRE_READ(uargs, __sanitizer::internal_strlen((const char *)uargs) + 1);\n}\n\nPOST_SYSCALL(init_module)(long res, void *umod, long len, const void *uargs) {}\n\nPRE_SYSCALL(delete_module)(const void *name_user, long flags) {\n  if (name_user)\n    PRE_READ(name_user,\n             __sanitizer::internal_strlen((const char *)name_user) + 1);\n}\n\nPOST_SYSCALL(delete_module)(long res, const void *name_user, long flags) {}\n\nPRE_SYSCALL(rt_sigprocmask)(long how, void *set, void *oset, long sigsetsize) {}\n\nPOST_SYSCALL(rt_sigprocmask)(long res, long how, kernel_sigset_t *set,\n                             kernel_sigset_t *oset, long sigsetsize) {\n  if (res >= 0) {\n    if (set) POST_WRITE(set, sigsetsize);\n    if (oset) POST_WRITE(oset, sigsetsize);\n  }\n}\n\nPRE_SYSCALL(rt_sigpending)(void *set, long sigsetsize) {}\n\nPOST_SYSCALL(rt_sigpending)(long res, kernel_sigset_t *set, long sigsetsize) {\n  if (res >= 0) {\n    if (set) POST_WRITE(set, sigsetsize);\n  }\n}\n\nPRE_SYSCALL(rt_sigtimedwait)(const kernel_sigset_t *uthese, void *uinfo,\n                             const void *uts, long sigsetsize) {\n  if (uthese) PRE_READ(uthese, sigsetsize);\n  if (uts) PRE_READ(uts, struct_timespec_sz);\n}\n\nPOST_SYSCALL(rt_sigtimedwait)(long res, const void *uthese, void *uinfo,\n                              const void *uts, long sigsetsize) {\n  if (res >= 0) {\n    if (uinfo) POST_WRITE(uinfo, siginfo_t_sz);\n  }\n}\n\nPRE_SYSCALL(rt_tgsigqueueinfo)(long tgid, long pid, long sig, void *uinfo) {}\n\nPOST_SYSCALL(rt_tgsigqueueinfo)(long res, long tgid, long pid, long sig,\n                                void *uinfo) {\n  if (res >= 0) {\n    if (uinfo) POST_WRITE(uinfo, siginfo_t_sz);\n  }\n}\n\nPRE_SYSCALL(kill)(long pid, long sig) {}\n\nPOST_SYSCALL(kill)(long res, long pid, long sig) {}\n\nPRE_SYSCALL(tgkill)(long tgid, long pid, long sig) {}\n\nPOST_SYSCALL(tgkill)(long res, long tgid, long pid, long sig) {}\n\nPRE_SYSCALL(tkill)(long pid, long sig) {}\n\nPOST_SYSCALL(tkill)(long res, long pid, long sig) {}\n\nPRE_SYSCALL(rt_sigqueueinfo)(long pid, long sig, void *uinfo) {}\n\nPOST_SYSCALL(rt_sigqueueinfo)(long res, long pid, long sig, void *uinfo) {\n  if (res >= 0) {\n    if (uinfo) POST_WRITE(uinfo, siginfo_t_sz);\n  }\n}\n\nPRE_SYSCALL(sgetmask)() {}\n\nPOST_SYSCALL(sgetmask)(long res) {}\n\nPRE_SYSCALL(ssetmask)(long newmask) {}\n\nPOST_SYSCALL(ssetmask)(long res, long newmask) {}\n\nPRE_SYSCALL(signal)(long sig, long handler) {}\n\nPOST_SYSCALL(signal)(long res, long sig, long handler) {}\n\nPRE_SYSCALL(pause)() {}\n\nPOST_SYSCALL(pause)(long res) {}\n\nPRE_SYSCALL(sync)() {}\n\nPOST_SYSCALL(sync)(long res) {}\n\nPRE_SYSCALL(fsync)(long fd) {}\n\nPOST_SYSCALL(fsync)(long res, long fd) {}\n\nPRE_SYSCALL(fdatasync)(long fd) {}\n\nPOST_SYSCALL(fdatasync)(long res, long fd) {}\n\nPRE_SYSCALL(bdflush)(long func, long data) {}\n\nPOST_SYSCALL(bdflush)(long res, long func, long data) {}\n\nPRE_SYSCALL(mount)(void *dev_name, void *dir_name, void *type, long flags,\n                   void *data) {}\n\nPOST_SYSCALL(mount)(long res, void *dev_name, void *dir_name, void *type,\n                    long flags, void *data) {\n  if (res >= 0) {\n    if (dev_name)\n      POST_WRITE(dev_name,\n                 __sanitizer::internal_strlen((const char *)dev_name) + 1);\n    if (dir_name)\n      POST_WRITE(dir_name,\n                 __sanitizer::internal_strlen((const char *)dir_name) + 1);\n    if (type)\n      POST_WRITE(type, __sanitizer::internal_strlen((const char *)type) + 1);\n  }\n}\n\nPRE_SYSCALL(umount)(void *name, long flags) {}\n\nPOST_SYSCALL(umount)(long res, void *name, long flags) {\n  if (res >= 0) {\n    if (name)\n      POST_WRITE(name, __sanitizer::internal_strlen((const char *)name) + 1);\n  }\n}\n\nPRE_SYSCALL(oldumount)(void *name) {}\n\nPOST_SYSCALL(oldumount)(long res, void *name) {\n  if (res >= 0) {\n    if (name)\n      POST_WRITE(name, __sanitizer::internal_strlen((const char *)name) + 1);\n  }\n}\n\nPRE_SYSCALL(truncate)(const void *path, long length) {\n  if (path)\n    PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1);\n}\n\nPOST_SYSCALL(truncate)(long res, const void *path, long length) {}\n\nPRE_SYSCALL(ftruncate)(long fd, long length) {}\n\nPOST_SYSCALL(ftruncate)(long res, long fd, long length) {}\n\nPRE_SYSCALL(stat)(const void *filename, void *statbuf) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(stat)(long res, const void *filename, void *statbuf) {\n  if (res >= 0) {\n    if (statbuf) POST_WRITE(statbuf, struct___old_kernel_stat_sz);\n  }\n}\n\n#if !SANITIZER_ANDROID\nPRE_SYSCALL(statfs)(const void *path, void *buf) {\n  if (path)\n    PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1);\n}\n\nPOST_SYSCALL(statfs)(long res, const void *path, void *buf) {\n  if (res >= 0) {\n    if (buf) POST_WRITE(buf, struct_statfs_sz);\n  }\n}\n\nPRE_SYSCALL(statfs64)(const void *path, long sz, void *buf) {\n  if (path)\n    PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1);\n}\n\nPOST_SYSCALL(statfs64)(long res, const void *path, long sz, void *buf) {\n  if (res >= 0) {\n    if (buf) POST_WRITE(buf, struct_statfs64_sz);\n  }\n}\n\nPRE_SYSCALL(fstatfs)(long fd, void *buf) {}\n\nPOST_SYSCALL(fstatfs)(long res, long fd, void *buf) {\n  if (res >= 0) {\n    if (buf) POST_WRITE(buf, struct_statfs_sz);\n  }\n}\n\nPRE_SYSCALL(fstatfs64)(long fd, long sz, void *buf) {}\n\nPOST_SYSCALL(fstatfs64)(long res, long fd, long sz, void *buf) {\n  if (res >= 0) {\n    if (buf) POST_WRITE(buf, struct_statfs64_sz);\n  }\n}\n#endif // !SANITIZER_ANDROID\n\nPRE_SYSCALL(lstat)(const void *filename, void *statbuf) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(lstat)(long res, const void *filename, void *statbuf) {\n  if (res >= 0) {\n    if (statbuf) POST_WRITE(statbuf, struct___old_kernel_stat_sz);\n  }\n}\n\nPRE_SYSCALL(fstat)(long fd, void *statbuf) {}\n\nPOST_SYSCALL(fstat)(long res, long fd, void *statbuf) {\n  if (res >= 0) {\n    if (statbuf) POST_WRITE(statbuf, struct___old_kernel_stat_sz);\n  }\n}\n\nPRE_SYSCALL(newstat)(const void *filename, void *statbuf) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(newstat)(long res, const void *filename, void *statbuf) {\n  if (res >= 0) {\n    if (statbuf) POST_WRITE(statbuf, struct_kernel_stat_sz);\n  }\n}\n\nPRE_SYSCALL(newlstat)(const void *filename, void *statbuf) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(newlstat)(long res, const void *filename, void *statbuf) {\n  if (res >= 0) {\n    if (statbuf) POST_WRITE(statbuf, struct_kernel_stat_sz);\n  }\n}\n\nPRE_SYSCALL(newfstat)(long fd, void *statbuf) {}\n\nPOST_SYSCALL(newfstat)(long res, long fd, void *statbuf) {\n  if (res >= 0) {\n    if (statbuf) POST_WRITE(statbuf, struct_kernel_stat_sz);\n  }\n}\n\n#if !SANITIZER_ANDROID\nPRE_SYSCALL(ustat)(long dev, void *ubuf) {}\n\nPOST_SYSCALL(ustat)(long res, long dev, void *ubuf) {\n  if (res >= 0) {\n    if (ubuf) POST_WRITE(ubuf, struct_ustat_sz);\n  }\n}\n#endif  // !SANITIZER_ANDROID\n\nPRE_SYSCALL(stat64)(const void *filename, void *statbuf) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(stat64)(long res, const void *filename, void *statbuf) {\n  if (res >= 0) {\n    if (statbuf) POST_WRITE(statbuf, struct_kernel_stat64_sz);\n  }\n}\n\nPRE_SYSCALL(fstat64)(long fd, void *statbuf) {}\n\nPOST_SYSCALL(fstat64)(long res, long fd, void *statbuf) {\n  if (res >= 0) {\n    if (statbuf) POST_WRITE(statbuf, struct_kernel_stat64_sz);\n  }\n}\n\nPRE_SYSCALL(lstat64)(const void *filename, void *statbuf) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(lstat64)(long res, const void *filename, void *statbuf) {\n  if (res >= 0) {\n    if (statbuf) POST_WRITE(statbuf, struct_kernel_stat64_sz);\n  }\n}\n\nPRE_SYSCALL(setxattr)(const void *path, const void *name, const void *value,\n                      long size, long flags) {\n  if (path)\n    PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1);\n  if (name)\n    PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1);\n  if (value) PRE_READ(value, size);\n}\n\nPOST_SYSCALL(setxattr)(long res, const void *path, const void *name,\n                       const void *value, long size, long flags) {}\n\nPRE_SYSCALL(lsetxattr)(const void *path, const void *name, const void *value,\n                       long size, long flags) {\n  if (path)\n    PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1);\n  if (name)\n    PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1);\n  if (value) PRE_READ(value, size);\n}\n\nPOST_SYSCALL(lsetxattr)(long res, const void *path, const void *name,\n                        const void *value, long size, long flags) {}\n\nPRE_SYSCALL(fsetxattr)(long fd, const void *name, const void *value, long size,\n                       long flags) {\n  if (name)\n    PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1);\n  if (value) PRE_READ(value, size);\n}\n\nPOST_SYSCALL(fsetxattr)(long res, long fd, const void *name, const void *value,\n                        long size, long flags) {}\n\nPRE_SYSCALL(getxattr)(const void *path, const void *name, void *value,\n                      long size) {\n  if (path)\n    PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1);\n  if (name)\n    PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1);\n}\n\nPOST_SYSCALL(getxattr)(long res, const void *path, const void *name,\n                       void *value, long size) {\n  if (size && res > 0) {\n    if (value) POST_WRITE(value, res);\n  }\n}\n\nPRE_SYSCALL(lgetxattr)(const void *path, const void *name, void *value,\n                       long size) {\n  if (path)\n    PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1);\n  if (name)\n    PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1);\n}\n\nPOST_SYSCALL(lgetxattr)(long res, const void *path, const void *name,\n                        void *value, long size) {\n  if (size && res > 0) {\n    if (value) POST_WRITE(value, res);\n  }\n}\n\nPRE_SYSCALL(fgetxattr)(long fd, const void *name, void *value, long size) {\n  if (name)\n    PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1);\n}\n\nPOST_SYSCALL(fgetxattr)(long res, long fd, const void *name, void *value,\n                        long size) {\n  if (size && res > 0) {\n    if (value) POST_WRITE(value, res);\n  }\n}\n\nPRE_SYSCALL(listxattr)(const void *path, void *list, long size) {\n  if (path)\n    PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1);\n}\n\nPOST_SYSCALL(listxattr)(long res, const void *path, void *list, long size) {\n  if (size && res > 0) {\n    if (list) POST_WRITE(list, res);\n  }\n}\n\nPRE_SYSCALL(llistxattr)(const void *path, void *list, long size) {\n  if (path)\n    PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1);\n}\n\nPOST_SYSCALL(llistxattr)(long res, const void *path, void *list, long size) {\n  if (size && res > 0) {\n    if (list) POST_WRITE(list, res);\n  }\n}\n\nPRE_SYSCALL(flistxattr)(long fd, void *list, long size) {}\n\nPOST_SYSCALL(flistxattr)(long res, long fd, void *list, long size) {\n  if (size && res > 0) {\n    if (list) POST_WRITE(list, res);\n  }\n}\n\nPRE_SYSCALL(removexattr)(const void *path, const void *name) {\n  if (path)\n    PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1);\n  if (name)\n    PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1);\n}\n\nPOST_SYSCALL(removexattr)(long res, const void *path, const void *name) {}\n\nPRE_SYSCALL(lremovexattr)(const void *path, const void *name) {\n  if (path)\n    PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1);\n  if (name)\n    PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1);\n}\n\nPOST_SYSCALL(lremovexattr)(long res, const void *path, const void *name) {}\n\nPRE_SYSCALL(fremovexattr)(long fd, const void *name) {\n  if (name)\n    PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1);\n}\n\nPOST_SYSCALL(fremovexattr)(long res, long fd, const void *name) {}\n\nPRE_SYSCALL(brk)(long brk) {}\n\nPOST_SYSCALL(brk)(long res, long brk) {}\n\nPRE_SYSCALL(mprotect)(long start, long len, long prot) {}\n\nPOST_SYSCALL(mprotect)(long res, long start, long len, long prot) {}\n\nPRE_SYSCALL(mremap)(long addr, long old_len, long new_len, long flags,\n                    long new_addr) {}\n\nPOST_SYSCALL(mremap)(long res, long addr, long old_len, long new_len,\n                     long flags, long new_addr) {}\n\nPRE_SYSCALL(remap_file_pages)(long start, long size, long prot, long pgoff,\n                              long flags) {}\n\nPOST_SYSCALL(remap_file_pages)(long res, long start, long size, long prot,\n                               long pgoff, long flags) {}\n\nPRE_SYSCALL(msync)(long start, long len, long flags) {}\n\nPOST_SYSCALL(msync)(long res, long start, long len, long flags) {}\n\nPRE_SYSCALL(munmap)(long addr, long len) {}\n\nPOST_SYSCALL(munmap)(long res, long addr, long len) {}\n\nPRE_SYSCALL(mlock)(long start, long len) {}\n\nPOST_SYSCALL(mlock)(long res, long start, long len) {}\n\nPRE_SYSCALL(munlock)(long start, long len) {}\n\nPOST_SYSCALL(munlock)(long res, long start, long len) {}\n\nPRE_SYSCALL(mlockall)(long flags) {}\n\nPOST_SYSCALL(mlockall)(long res, long flags) {}\n\nPRE_SYSCALL(munlockall)() {}\n\nPOST_SYSCALL(munlockall)(long res) {}\n\nPRE_SYSCALL(madvise)(long start, long len, long behavior) {}\n\nPOST_SYSCALL(madvise)(long res, long start, long len, long behavior) {}\n\nPRE_SYSCALL(mincore)(long start, long len, void *vec) {}\n\nPOST_SYSCALL(mincore)(long res, long start, long len, void *vec) {\n  if (res >= 0) {\n    if (vec) {\n      POST_WRITE(vec, (len + GetPageSizeCached() - 1) / GetPageSizeCached());\n    }\n  }\n}\n\nPRE_SYSCALL(pivot_root)(const void *new_root, const void *put_old) {\n  if (new_root)\n    PRE_READ(new_root,\n             __sanitizer::internal_strlen((const char *)new_root) + 1);\n  if (put_old)\n    PRE_READ(put_old, __sanitizer::internal_strlen((const char *)put_old) + 1);\n}\n\nPOST_SYSCALL(pivot_root)(long res, const void *new_root, const void *put_old) {}\n\nPRE_SYSCALL(chroot)(const void *filename) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(chroot)(long res, const void *filename) {}\n\nPRE_SYSCALL(mknod)(const void *filename, long mode, long dev) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(mknod)(long res, const void *filename, long mode, long dev) {}\n\nPRE_SYSCALL(link)(const void *oldname, const void *newname) {\n  if (oldname)\n    PRE_READ(oldname, __sanitizer::internal_strlen((const char *)oldname) + 1);\n  if (newname)\n    PRE_READ(newname, __sanitizer::internal_strlen((const char *)newname) + 1);\n}\n\nPOST_SYSCALL(link)(long res, const void *oldname, const void *newname) {}\n\nPRE_SYSCALL(symlink)(const void *old, const void *new_) {\n  if (old) PRE_READ(old, __sanitizer::internal_strlen((const char *)old) + 1);\n  if (new_)\n    PRE_READ(new_, __sanitizer::internal_strlen((const char *)new_) + 1);\n}\n\nPOST_SYSCALL(symlink)(long res, const void *old, const void *new_) {}\n\nPRE_SYSCALL(unlink)(const void *pathname) {\n  if (pathname)\n    PRE_READ(pathname,\n             __sanitizer::internal_strlen((const char *)pathname) + 1);\n}\n\nPOST_SYSCALL(unlink)(long res, const void *pathname) {}\n\nPRE_SYSCALL(rename)(const void *oldname, const void *newname) {\n  if (oldname)\n    PRE_READ(oldname, __sanitizer::internal_strlen((const char *)oldname) + 1);\n  if (newname)\n    PRE_READ(newname, __sanitizer::internal_strlen((const char *)newname) + 1);\n}\n\nPOST_SYSCALL(rename)(long res, const void *oldname, const void *newname) {}\n\nPRE_SYSCALL(chmod)(const void *filename, long mode) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(chmod)(long res, const void *filename, long mode) {}\n\nPRE_SYSCALL(fchmod)(long fd, long mode) {}\n\nPOST_SYSCALL(fchmod)(long res, long fd, long mode) {}\n\nPRE_SYSCALL(fcntl)(long fd, long cmd, long arg) {}\n\nPOST_SYSCALL(fcntl)(long res, long fd, long cmd, long arg) {}\n\nPRE_SYSCALL(fcntl64)(long fd, long cmd, long arg) {}\n\nPOST_SYSCALL(fcntl64)(long res, long fd, long cmd, long arg) {}\n\nPRE_SYSCALL(pipe)(void *fildes) {}\n\nPOST_SYSCALL(pipe)(long res, void *fildes) {\n  if (res >= 0) {\n    if (fildes) POST_WRITE(fildes, sizeof(int));\n  }\n}\n\nPRE_SYSCALL(pipe2)(void *fildes, long flags) {}\n\nPOST_SYSCALL(pipe2)(long res, void *fildes, long flags) {\n  if (res >= 0) {\n    if (fildes) POST_WRITE(fildes, sizeof(int));\n  }\n}\n\nPRE_SYSCALL(dup)(long fildes) {}\n\nPOST_SYSCALL(dup)(long res, long fildes) {}\n\nPRE_SYSCALL(dup2)(long oldfd, long newfd) {}\n\nPOST_SYSCALL(dup2)(long res, long oldfd, long newfd) {}\n\nPRE_SYSCALL(dup3)(long oldfd, long newfd, long flags) {}\n\nPOST_SYSCALL(dup3)(long res, long oldfd, long newfd, long flags) {}\n\nPRE_SYSCALL(ioperm)(long from, long num, long on) {}\n\nPOST_SYSCALL(ioperm)(long res, long from, long num, long on) {}\n\nPRE_SYSCALL(ioctl)(long fd, long cmd, long arg) {}\n\nPOST_SYSCALL(ioctl)(long res, long fd, long cmd, long arg) {}\n\nPRE_SYSCALL(flock)(long fd, long cmd) {}\n\nPOST_SYSCALL(flock)(long res, long fd, long cmd) {}\n\nPRE_SYSCALL(io_setup)(long nr_reqs, void **ctx) {\n  if (ctx) PRE_WRITE(ctx, sizeof(*ctx));\n}\n\nPOST_SYSCALL(io_setup)(long res, long nr_reqs, void **ctx) {\n  if (res >= 0) {\n    if (ctx) POST_WRITE(ctx, sizeof(*ctx));\n    // (*ctx) is actually a pointer to a kernel mapped page, and there are\n    // people out there who are crazy enough to peek into that page's 32-byte\n    // header.\n    if (*ctx) POST_WRITE(*ctx, 32);\n  }\n}\n\nPRE_SYSCALL(io_destroy)(long ctx) {}\n\nPOST_SYSCALL(io_destroy)(long res, long ctx) {}\n\nPRE_SYSCALL(io_getevents)(long ctx_id, long min_nr, long nr,\n                          __sanitizer_io_event *ioevpp, void *timeout) {\n  if (timeout) PRE_READ(timeout, struct_timespec_sz);\n}\n\nPOST_SYSCALL(io_getevents)(long res, long ctx_id, long min_nr, long nr,\n                           __sanitizer_io_event *ioevpp, void *timeout) {\n  if (res >= 0) {\n    if (ioevpp) POST_WRITE(ioevpp, res * sizeof(*ioevpp));\n    if (timeout) POST_WRITE(timeout, struct_timespec_sz);\n  }\n  for (long i = 0; i < res; i++) {\n    // We synchronize io_submit -> io_getevents/io_cancel using the\n    // user-provided data context. Data is not necessary a pointer, it can be\n    // an int, 0 or whatever; acquire/release will correctly handle this.\n    // This scheme can lead to false negatives, e.g. when all operations\n    // synchronize on 0. But there does not seem to be a better solution\n    // (except wrapping all operations in own context, which is unreliable).\n    // We can not reliably extract fildes in io_getevents.\n    COMMON_SYSCALL_ACQUIRE((void*)ioevpp[i].data);\n  }\n}\n\nPRE_SYSCALL(io_submit)(long ctx_id, long nr, __sanitizer_iocb **iocbpp) {\n  for (long i = 0; i < nr; ++i) {\n    uptr op = iocbpp[i]->aio_lio_opcode;\n    void *data = (void*)iocbpp[i]->aio_data;\n    void *buf = (void*)iocbpp[i]->aio_buf;\n    uptr len = (uptr)iocbpp[i]->aio_nbytes;\n    if (op == iocb_cmd_pwrite && buf && len) {\n      PRE_READ(buf, len);\n    } else if (op == iocb_cmd_pread && buf && len) {\n      POST_WRITE(buf, len);\n    } else if (op == iocb_cmd_pwritev) {\n      __sanitizer_iovec *iovec = (__sanitizer_iovec*)buf;\n      for (uptr v = 0; v < len; v++)\n        PRE_READ(iovec[v].iov_base, iovec[v].iov_len);\n    } else if (op == iocb_cmd_preadv) {\n      __sanitizer_iovec *iovec = (__sanitizer_iovec*)buf;\n      for (uptr v = 0; v < len; v++)\n        POST_WRITE(iovec[v].iov_base, iovec[v].iov_len);\n    }\n    // See comment in io_getevents.\n    COMMON_SYSCALL_RELEASE(data);\n  }\n}\n\nPOST_SYSCALL(io_submit)(long res, long ctx_id, long nr,\n    __sanitizer_iocb **iocbpp) {}\n\nPRE_SYSCALL(io_cancel)(long ctx_id, __sanitizer_iocb *iocb,\n    __sanitizer_io_event *result) {\n}\n\nPOST_SYSCALL(io_cancel)(long res, long ctx_id, __sanitizer_iocb *iocb,\n    __sanitizer_io_event *result) {\n  if (res == 0) {\n    if (result) {\n      // See comment in io_getevents.\n      COMMON_SYSCALL_ACQUIRE((void*)result->data);\n      POST_WRITE(result, sizeof(*result));\n    }\n    if (iocb)\n      POST_WRITE(iocb, sizeof(*iocb));\n  }\n}\n\nPRE_SYSCALL(sendfile)(long out_fd, long in_fd, void *offset, long count) {}\n\nPOST_SYSCALL(sendfile)(long res, long out_fd, long in_fd,\n                       __sanitizer___kernel_off_t *offset, long count) {\n  if (res >= 0) {\n    if (offset) POST_WRITE(offset, sizeof(*offset));\n  }\n}\n\nPRE_SYSCALL(sendfile64)(long out_fd, long in_fd, void *offset, long count) {}\n\nPOST_SYSCALL(sendfile64)(long res, long out_fd, long in_fd,\n                         __sanitizer___kernel_loff_t *offset, long count) {\n  if (res >= 0) {\n    if (offset) POST_WRITE(offset, sizeof(*offset));\n  }\n}\n\nPRE_SYSCALL(readlink)(const void *path, void *buf, long bufsiz) {\n  if (path)\n    PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1);\n}\n\nPOST_SYSCALL(readlink)(long res, const void *path, void *buf, long bufsiz) {\n  if (res >= 0) {\n    if (buf)\n      POST_WRITE(buf, __sanitizer::internal_strlen((const char *)buf) + 1);\n  }\n}\n\nPRE_SYSCALL(creat)(const void *pathname, long mode) {\n  if (pathname)\n    PRE_READ(pathname,\n             __sanitizer::internal_strlen((const char *)pathname) + 1);\n}\n\nPOST_SYSCALL(creat)(long res, const void *pathname, long mode) {}\n\nPRE_SYSCALL(open)(const void *filename, long flags, long mode) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(open)(long res, const void *filename, long flags, long mode) {}\n\nPRE_SYSCALL(close)(long fd) {\n  COMMON_SYSCALL_FD_CLOSE((int)fd);\n}\n\nPOST_SYSCALL(close)(long res, long fd) {}\n\nPRE_SYSCALL(access)(const void *filename, long mode) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(access)(long res, const void *filename, long mode) {}\n\nPRE_SYSCALL(vhangup)() {}\n\nPOST_SYSCALL(vhangup)(long res) {}\n\nPRE_SYSCALL(chown)(const void *filename, long user, long group) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(chown)(long res, const void *filename, long user, long group) {}\n\nPRE_SYSCALL(lchown)(const void *filename, long user, long group) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(lchown)(long res, const void *filename, long user, long group) {}\n\nPRE_SYSCALL(fchown)(long fd, long user, long group) {}\n\nPOST_SYSCALL(fchown)(long res, long fd, long user, long group) {}\n\n#if SANITIZER_USES_UID16_SYSCALLS\nPRE_SYSCALL(chown16)(const void *filename, long user, long group) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(chown16)(long res, const void *filename, long user, long group) {}\n\nPRE_SYSCALL(lchown16)(const void *filename, long user, long group) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(lchown16)(long res, const void *filename, long user, long group) {}\n\nPRE_SYSCALL(fchown16)(long fd, long user, long group) {}\n\nPOST_SYSCALL(fchown16)(long res, long fd, long user, long group) {}\n\nPRE_SYSCALL(setregid16)(long rgid, long egid) {}\n\nPOST_SYSCALL(setregid16)(long res, long rgid, long egid) {}\n\nPRE_SYSCALL(setgid16)(long gid) {}\n\nPOST_SYSCALL(setgid16)(long res, long gid) {}\n\nPRE_SYSCALL(setreuid16)(long ruid, long euid) {}\n\nPOST_SYSCALL(setreuid16)(long res, long ruid, long euid) {}\n\nPRE_SYSCALL(setuid16)(long uid) {}\n\nPOST_SYSCALL(setuid16)(long res, long uid) {}\n\nPRE_SYSCALL(setresuid16)(long ruid, long euid, long suid) {}\n\nPOST_SYSCALL(setresuid16)(long res, long ruid, long euid, long suid) {}\n\nPRE_SYSCALL(getresuid16)(void *ruid, void *euid, void *suid) {}\n\nPOST_SYSCALL(getresuid16)(long res, __sanitizer___kernel_old_uid_t *ruid,\n                          __sanitizer___kernel_old_uid_t *euid,\n                          __sanitizer___kernel_old_uid_t *suid) {\n  if (res >= 0) {\n    if (ruid) POST_WRITE(ruid, sizeof(*ruid));\n    if (euid) POST_WRITE(euid, sizeof(*euid));\n    if (suid) POST_WRITE(suid, sizeof(*suid));\n  }\n}\n\nPRE_SYSCALL(setresgid16)(long rgid, long egid, long sgid) {}\n\nPOST_SYSCALL(setresgid16)(long res, long rgid, long egid, long sgid) {}\n\nPRE_SYSCALL(getresgid16)(void *rgid, void *egid, void *sgid) {}\n\nPOST_SYSCALL(getresgid16)(long res, __sanitizer___kernel_old_gid_t *rgid,\n                          __sanitizer___kernel_old_gid_t *egid,\n                          __sanitizer___kernel_old_gid_t *sgid) {\n  if (res >= 0) {\n    if (rgid) POST_WRITE(rgid, sizeof(*rgid));\n    if (egid) POST_WRITE(egid, sizeof(*egid));\n    if (sgid) POST_WRITE(sgid, sizeof(*sgid));\n  }\n}\n\nPRE_SYSCALL(setfsuid16)(long uid) {}\n\nPOST_SYSCALL(setfsuid16)(long res, long uid) {}\n\nPRE_SYSCALL(setfsgid16)(long gid) {}\n\nPOST_SYSCALL(setfsgid16)(long res, long gid) {}\n\nPRE_SYSCALL(getgroups16)(long gidsetsize,\n                         __sanitizer___kernel_old_gid_t *grouplist) {}\n\nPOST_SYSCALL(getgroups16)(long res, long gidsetsize,\n                          __sanitizer___kernel_old_gid_t *grouplist) {\n  if (res >= 0) {\n    if (grouplist) POST_WRITE(grouplist, res * sizeof(*grouplist));\n  }\n}\n\nPRE_SYSCALL(setgroups16)(long gidsetsize,\n                         __sanitizer___kernel_old_gid_t *grouplist) {\n  if (grouplist) POST_WRITE(grouplist, gidsetsize * sizeof(*grouplist));\n}\n\nPOST_SYSCALL(setgroups16)(long res, long gidsetsize,\n                          __sanitizer___kernel_old_gid_t *grouplist) {}\n\nPRE_SYSCALL(getuid16)() {}\n\nPOST_SYSCALL(getuid16)(long res) {}\n\nPRE_SYSCALL(geteuid16)() {}\n\nPOST_SYSCALL(geteuid16)(long res) {}\n\nPRE_SYSCALL(getgid16)() {}\n\nPOST_SYSCALL(getgid16)(long res) {}\n\nPRE_SYSCALL(getegid16)() {}\n\nPOST_SYSCALL(getegid16)(long res) {}\n#endif // SANITIZER_USES_UID16_SYSCALLS\n\nPRE_SYSCALL(utime)(void *filename, void *times) {}\n\nPOST_SYSCALL(utime)(long res, void *filename, void *times) {\n  if (res >= 0) {\n    if (filename)\n      POST_WRITE(filename,\n                 __sanitizer::internal_strlen((const char *)filename) + 1);\n    if (times) POST_WRITE(times, struct_utimbuf_sz);\n  }\n}\n\nPRE_SYSCALL(utimes)(void *filename, void *utimes) {}\n\nPOST_SYSCALL(utimes)(long res, void *filename, void *utimes) {\n  if (res >= 0) {\n    if (filename)\n      POST_WRITE(filename,\n                 __sanitizer::internal_strlen((const char *)filename) + 1);\n    if (utimes) POST_WRITE(utimes, timeval_sz);\n  }\n}\n\nPRE_SYSCALL(lseek)(long fd, long offset, long origin) {}\n\nPOST_SYSCALL(lseek)(long res, long fd, long offset, long origin) {}\n\nPRE_SYSCALL(llseek)(long fd, long offset_high, long offset_low, void *result,\n                    long origin) {}\n\nPOST_SYSCALL(llseek)(long res, long fd, long offset_high, long offset_low,\n                     void *result, long origin) {\n  if (res >= 0) {\n    if (result) POST_WRITE(result, sizeof(long long));\n  }\n}\n\nPRE_SYSCALL(readv)(long fd, const __sanitizer_iovec *vec, long vlen) {}\n\nPOST_SYSCALL(readv)(long res, long fd, const __sanitizer_iovec *vec,\n                    long vlen) {\n  if (res >= 0) {\n    if (vec) kernel_write_iovec(vec, vlen, res);\n  }\n}\n\nPRE_SYSCALL(write)(long fd, const void *buf, long count) {\n  if (buf) PRE_READ(buf, count);\n}\n\nPOST_SYSCALL(write)(long res, long fd, const void *buf, long count) {}\n\nPRE_SYSCALL(writev)(long fd, const __sanitizer_iovec *vec, long vlen) {}\n\nPOST_SYSCALL(writev)(long res, long fd, const __sanitizer_iovec *vec,\n                     long vlen) {\n  if (res >= 0) {\n    if (vec) kernel_read_iovec(vec, vlen, res);\n  }\n}\n\n#ifdef _LP64\nPRE_SYSCALL(pread64)(long fd, void *buf, long count, long pos) {}\n\nPOST_SYSCALL(pread64)(long res, long fd, void *buf, long count, long pos) {\n  if (res >= 0) {\n    if (buf) POST_WRITE(buf, res);\n  }\n}\n\nPRE_SYSCALL(pwrite64)(long fd, const void *buf, long count, long pos) {\n  if (buf) PRE_READ(buf, count);\n}\n\nPOST_SYSCALL(pwrite64)(long res, long fd, const void *buf, long count,\n                       long pos) {}\n#else\nPRE_SYSCALL(pread64)(long fd, void *buf, long count, long pos0, long pos1) {}\n\nPOST_SYSCALL(pread64)(long res, long fd, void *buf, long count, long pos0,\n                      long pos1) {\n  if (res >= 0) {\n    if (buf) POST_WRITE(buf, res);\n  }\n}\n\nPRE_SYSCALL(pwrite64)(long fd, const void *buf, long count, long pos0,\n                      long pos1) {\n  if (buf) PRE_READ(buf, count);\n}\n\nPOST_SYSCALL(pwrite64)(long res, long fd, const void *buf, long count,\n                       long pos0, long pos1) {}\n#endif\n\nPRE_SYSCALL(preadv)(long fd, const __sanitizer_iovec *vec, long vlen,\n                    long pos_l, long pos_h) {}\n\nPOST_SYSCALL(preadv)(long res, long fd, const __sanitizer_iovec *vec, long vlen,\n                     long pos_l, long pos_h) {\n  if (res >= 0) {\n    if (vec) kernel_write_iovec(vec, vlen, res);\n  }\n}\n\nPRE_SYSCALL(pwritev)(long fd, const __sanitizer_iovec *vec, long vlen,\n                     long pos_l, long pos_h) {}\n\nPOST_SYSCALL(pwritev)(long res, long fd, const __sanitizer_iovec *vec,\n                      long vlen, long pos_l, long pos_h) {\n  if (res >= 0) {\n    if (vec) kernel_read_iovec(vec, vlen, res);\n  }\n}\n\nPRE_SYSCALL(getcwd)(void *buf, long size) {}\n\nPOST_SYSCALL(getcwd)(long res, void *buf, long size) {\n  if (res >= 0) {\n    if (buf)\n      POST_WRITE(buf, __sanitizer::internal_strlen((const char *)buf) + 1);\n  }\n}\n\nPRE_SYSCALL(mkdir)(const void *pathname, long mode) {\n  if (pathname)\n    PRE_READ(pathname,\n             __sanitizer::internal_strlen((const char *)pathname) + 1);\n}\n\nPOST_SYSCALL(mkdir)(long res, const void *pathname, long mode) {}\n\nPRE_SYSCALL(chdir)(const void *filename) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(chdir)(long res, const void *filename) {}\n\nPRE_SYSCALL(fchdir)(long fd) {}\n\nPOST_SYSCALL(fchdir)(long res, long fd) {}\n\nPRE_SYSCALL(rmdir)(const void *pathname) {\n  if (pathname)\n    PRE_READ(pathname,\n             __sanitizer::internal_strlen((const char *)pathname) + 1);\n}\n\nPOST_SYSCALL(rmdir)(long res, const void *pathname) {}\n\nPRE_SYSCALL(lookup_dcookie)(u64 cookie64, void *buf, long len) {}\n\nPOST_SYSCALL(lookup_dcookie)(long res, u64 cookie64, void *buf, long len) {\n  if (res >= 0) {\n    if (buf)\n      POST_WRITE(buf, __sanitizer::internal_strlen((const char *)buf) + 1);\n  }\n}\n\nPRE_SYSCALL(quotactl)(long cmd, const void *special, long id, void *addr) {\n  if (special)\n    PRE_READ(special, __sanitizer::internal_strlen((const char *)special) + 1);\n}\n\nPOST_SYSCALL(quotactl)(long res, long cmd, const void *special, long id,\n                       void *addr) {}\n\nPRE_SYSCALL(getdents)(long fd, void *dirent, long count) {}\n\nPOST_SYSCALL(getdents)(long res, long fd, void *dirent, long count) {\n  if (res >= 0) {\n    if (dirent) POST_WRITE(dirent, res);\n  }\n}\n\nPRE_SYSCALL(getdents64)(long fd, void *dirent, long count) {}\n\nPOST_SYSCALL(getdents64)(long res, long fd, void *dirent, long count) {\n  if (res >= 0) {\n    if (dirent) POST_WRITE(dirent, res);\n  }\n}\n\nPRE_SYSCALL(setsockopt)(long fd, long level, long optname, void *optval,\n                        long optlen) {}\n\nPOST_SYSCALL(setsockopt)(long res, long fd, long level, long optname,\n                         void *optval, long optlen) {\n  if (res >= 0) {\n    if (optval)\n      POST_WRITE(optval,\n                 __sanitizer::internal_strlen((const char *)optval) + 1);\n  }\n}\n\nPRE_SYSCALL(getsockopt)(long fd, long level, long optname, void *optval,\n                        void *optlen) {}\n\nPOST_SYSCALL(getsockopt)(long res, long fd, long level, long optname,\n                         void *optval, void *optlen) {\n  if (res >= 0) {\n    if (optval)\n      POST_WRITE(optval,\n                 __sanitizer::internal_strlen((const char *)optval) + 1);\n    if (optlen) POST_WRITE(optlen, sizeof(int));\n  }\n}\n\nPRE_SYSCALL(bind)(long arg0, sanitizer_kernel_sockaddr *arg1, long arg2) {}\n\nPOST_SYSCALL(bind)(long res, long arg0, sanitizer_kernel_sockaddr *arg1,\n                   long arg2) {\n  if (res >= 0) {\n    if (arg1) POST_WRITE(arg1, sizeof(*arg1));\n  }\n}\n\nPRE_SYSCALL(connect)(long arg0, sanitizer_kernel_sockaddr *arg1, long arg2) {}\n\nPOST_SYSCALL(connect)(long res, long arg0, sanitizer_kernel_sockaddr *arg1,\n                      long arg2) {\n  if (res >= 0) {\n    if (arg1) POST_WRITE(arg1, sizeof(*arg1));\n  }\n}\n\nPRE_SYSCALL(accept)(long arg0, sanitizer_kernel_sockaddr *arg1, void *arg2) {}\n\nPOST_SYSCALL(accept)(long res, long arg0, sanitizer_kernel_sockaddr *arg1,\n                     void *arg2) {\n  if (res >= 0) {\n    if (arg1) POST_WRITE(arg1, sizeof(*arg1));\n    if (arg2) POST_WRITE(arg2, sizeof(unsigned));\n  }\n}\n\nPRE_SYSCALL(accept4)(long arg0, sanitizer_kernel_sockaddr *arg1, void *arg2,\n                     long arg3) {}\n\nPOST_SYSCALL(accept4)(long res, long arg0, sanitizer_kernel_sockaddr *arg1,\n                      void *arg2, long arg3) {\n  if (res >= 0) {\n    if (arg1) POST_WRITE(arg1, sizeof(*arg1));\n    if (arg2) POST_WRITE(arg2, sizeof(unsigned));\n  }\n}\n\nPRE_SYSCALL(getsockname)(long arg0, sanitizer_kernel_sockaddr *arg1,\n                         void *arg2) {}\n\nPOST_SYSCALL(getsockname)(long res, long arg0, sanitizer_kernel_sockaddr *arg1,\n                          void *arg2) {\n  if (res >= 0) {\n    if (arg1) POST_WRITE(arg1, sizeof(*arg1));\n    if (arg2) POST_WRITE(arg2, sizeof(unsigned));\n  }\n}\n\nPRE_SYSCALL(getpeername)(long arg0, sanitizer_kernel_sockaddr *arg1,\n                         void *arg2) {}\n\nPOST_SYSCALL(getpeername)(long res, long arg0, sanitizer_kernel_sockaddr *arg1,\n                          void *arg2) {\n  if (res >= 0) {\n    if (arg1) POST_WRITE(arg1, sizeof(*arg1));\n    if (arg2) POST_WRITE(arg2, sizeof(unsigned));\n  }\n}\n\nPRE_SYSCALL(send)(long arg0, void *arg1, long arg2, long arg3) {}\n\nPOST_SYSCALL(send)(long res, long arg0, void *arg1, long arg2, long arg3) {\n  if (res) {\n    if (arg1) POST_READ(arg1, res);\n  }\n}\n\nPRE_SYSCALL(sendto)(long arg0, void *arg1, long arg2, long arg3,\n                    sanitizer_kernel_sockaddr *arg4, long arg5) {}\n\nPOST_SYSCALL(sendto)(long res, long arg0, void *arg1, long arg2, long arg3,\n                     sanitizer_kernel_sockaddr *arg4, long arg5) {\n  if (res >= 0) {\n    if (arg1) POST_READ(arg1, res);\n    if (arg4) POST_WRITE(arg4, sizeof(*arg4));\n  }\n}\n\nPRE_SYSCALL(sendmsg)(long fd, void *msg, long flags) {}\n\nPOST_SYSCALL(sendmsg)(long res, long fd, void *msg, long flags) {\n  // FIXME: POST_READ\n}\n\nPRE_SYSCALL(sendmmsg)(long fd, void *msg, long vlen, long flags) {}\n\nPOST_SYSCALL(sendmmsg)(long res, long fd, void *msg, long vlen, long flags) {\n  // FIXME: POST_READ\n}\n\nPRE_SYSCALL(recv)(long arg0, void *buf, long len, long flags) {}\n\nPOST_SYSCALL(recv)(long res, void *buf, long len, long flags) {\n  if (res >= 0) {\n    if (buf) POST_WRITE(buf, res);\n  }\n}\n\nPRE_SYSCALL(recvfrom)(long arg0, void *buf, long len, long flags,\n                      sanitizer_kernel_sockaddr *arg4, void *arg5) {}\n\nPOST_SYSCALL(recvfrom)(long res, long arg0, void *buf, long len, long flags,\n                       sanitizer_kernel_sockaddr *arg4, void *arg5) {\n  if (res >= 0) {\n    if (buf) POST_WRITE(buf, res);\n    if (arg4) POST_WRITE(arg4, sizeof(*arg4));\n    if (arg5) POST_WRITE(arg5, sizeof(int));\n  }\n}\n\nPRE_SYSCALL(socket)(long arg0, long arg1, long arg2) {}\n\nPOST_SYSCALL(socket)(long res, long arg0, long arg1, long arg2) {}\n\nPRE_SYSCALL(socketpair)(long arg0, long arg1, long arg2, void *arg3) {}\n\nPOST_SYSCALL(socketpair)(long res, long arg0, long arg1, long arg2,\n                         void *arg3) {\n  if (res >= 0) {\n    if (arg3) POST_WRITE(arg3, sizeof(int));\n  }\n}\n\nPRE_SYSCALL(socketcall)(long call, void *args) {}\n\nPOST_SYSCALL(socketcall)(long res, long call, void *args) {\n  if (res >= 0) {\n    if (args) POST_WRITE(args, sizeof(long));\n  }\n}\n\nPRE_SYSCALL(listen)(long arg0, long arg1) {}\n\nPOST_SYSCALL(listen)(long res, long arg0, long arg1) {}\n\nPRE_SYSCALL(poll)(void *ufds, long nfds, long timeout) {}\n\nPOST_SYSCALL(poll)(long res, __sanitizer_pollfd *ufds, long nfds,\n                   long timeout) {\n  if (res >= 0) {\n    if (ufds) POST_WRITE(ufds, nfds * sizeof(*ufds));\n  }\n}\n\nPRE_SYSCALL(select)(long n, __sanitizer___kernel_fd_set *inp,\n                    __sanitizer___kernel_fd_set *outp,\n                    __sanitizer___kernel_fd_set *exp, void *tvp) {}\n\nPOST_SYSCALL(select)(long res, long n, __sanitizer___kernel_fd_set *inp,\n                     __sanitizer___kernel_fd_set *outp,\n                     __sanitizer___kernel_fd_set *exp, void *tvp) {\n  if (res >= 0) {\n    if (inp) POST_WRITE(inp, sizeof(*inp));\n    if (outp) POST_WRITE(outp, sizeof(*outp));\n    if (exp) POST_WRITE(exp, sizeof(*exp));\n    if (tvp) POST_WRITE(tvp, timeval_sz);\n  }\n}\n\nPRE_SYSCALL(old_select)(void *arg) {}\n\nPOST_SYSCALL(old_select)(long res, void *arg) {}\n\nPRE_SYSCALL(epoll_create)(long size) {}\n\nPOST_SYSCALL(epoll_create)(long res, long size) {}\n\nPRE_SYSCALL(epoll_create1)(long flags) {}\n\nPOST_SYSCALL(epoll_create1)(long res, long flags) {}\n\nPRE_SYSCALL(epoll_ctl)(long epfd, long op, long fd, void *event) {}\n\nPOST_SYSCALL(epoll_ctl)(long res, long epfd, long op, long fd, void *event) {\n  if (res >= 0) {\n    if (event) POST_WRITE(event, struct_epoll_event_sz);\n  }\n}\n\nPRE_SYSCALL(epoll_wait)(long epfd, void *events, long maxevents, long timeout) {\n}\n\nPOST_SYSCALL(epoll_wait)(long res, long epfd, void *events, long maxevents,\n                         long timeout) {\n  if (res >= 0) {\n    if (events) POST_WRITE(events, struct_epoll_event_sz);\n  }\n}\n\nPRE_SYSCALL(epoll_pwait)(long epfd, void *events, long maxevents, long timeout,\n                         const kernel_sigset_t *sigmask, long sigsetsize) {\n  if (sigmask) PRE_READ(sigmask, sigsetsize);\n}\n\nPOST_SYSCALL(epoll_pwait)(long res, long epfd, void *events, long maxevents,\n                          long timeout, const void *sigmask, long sigsetsize) {\n  if (res >= 0) {\n    if (events) POST_WRITE(events, struct_epoll_event_sz);\n  }\n}\n\nPRE_SYSCALL(gethostname)(void *name, long len) {}\n\nPOST_SYSCALL(gethostname)(long res, void *name, long len) {\n  if (res >= 0) {\n    if (name)\n      POST_WRITE(name, __sanitizer::internal_strlen((const char *)name) + 1);\n  }\n}\n\nPRE_SYSCALL(sethostname)(void *name, long len) {}\n\nPOST_SYSCALL(sethostname)(long res, void *name, long len) {\n  if (res >= 0) {\n    if (name)\n      POST_WRITE(name, __sanitizer::internal_strlen((const char *)name) + 1);\n  }\n}\n\nPRE_SYSCALL(setdomainname)(void *name, long len) {}\n\nPOST_SYSCALL(setdomainname)(long res, void *name, long len) {\n  if (res >= 0) {\n    if (name)\n      POST_WRITE(name, __sanitizer::internal_strlen((const char *)name) + 1);\n  }\n}\n\nPRE_SYSCALL(newuname)(void *name) {}\n\nPOST_SYSCALL(newuname)(long res, void *name) {\n  if (res >= 0) {\n    if (name) POST_WRITE(name, struct_new_utsname_sz);\n  }\n}\n\nPRE_SYSCALL(uname)(void *arg0) {}\n\nPOST_SYSCALL(uname)(long res, void *arg0) {\n  if (res >= 0) {\n    if (arg0) POST_WRITE(arg0, struct_old_utsname_sz);\n  }\n}\n\nPRE_SYSCALL(olduname)(void *arg0) {}\n\nPOST_SYSCALL(olduname)(long res, void *arg0) {\n  if (res >= 0) {\n    if (arg0) POST_WRITE(arg0, struct_oldold_utsname_sz);\n  }\n}\n\nPRE_SYSCALL(getrlimit)(long resource, void *rlim) {}\n\nPOST_SYSCALL(getrlimit)(long res, long resource, void *rlim) {\n  if (res >= 0) {\n    if (rlim) POST_WRITE(rlim, struct_rlimit_sz);\n  }\n}\n\nPRE_SYSCALL(old_getrlimit)(long resource, void *rlim) {}\n\nPOST_SYSCALL(old_getrlimit)(long res, long resource, void *rlim) {\n  if (res >= 0) {\n    if (rlim) POST_WRITE(rlim, struct_rlimit_sz);\n  }\n}\n\nPRE_SYSCALL(setrlimit)(long resource, void *rlim) {}\n\nPOST_SYSCALL(setrlimit)(long res, long resource, void *rlim) {\n  if (res >= 0) {\n    if (rlim) POST_WRITE(rlim, struct_rlimit_sz);\n  }\n}\n\n#if !SANITIZER_ANDROID\nPRE_SYSCALL(prlimit64)(long pid, long resource, const void *new_rlim,\n                       void *old_rlim) {\n  if (new_rlim) PRE_READ(new_rlim, struct_rlimit64_sz);\n}\n\nPOST_SYSCALL(prlimit64)(long res, long pid, long resource, const void *new_rlim,\n                        void *old_rlim) {\n  if (res >= 0) {\n    if (old_rlim) POST_WRITE(old_rlim, struct_rlimit64_sz);\n  }\n}\n#endif\n\nPRE_SYSCALL(getrusage)(long who, void *ru) {}\n\nPOST_SYSCALL(getrusage)(long res, long who, void *ru) {\n  if (res >= 0) {\n    if (ru) POST_WRITE(ru, struct_rusage_sz);\n  }\n}\n\nPRE_SYSCALL(umask)(long mask) {}\n\nPOST_SYSCALL(umask)(long res, long mask) {}\n\nPRE_SYSCALL(msgget)(long key, long msgflg) {}\n\nPOST_SYSCALL(msgget)(long res, long key, long msgflg) {}\n\nPRE_SYSCALL(msgsnd)(long msqid, void *msgp, long msgsz, long msgflg) {\n  if (msgp) PRE_READ(msgp, msgsz);\n}\n\nPOST_SYSCALL(msgsnd)(long res, long msqid, void *msgp, long msgsz,\n                     long msgflg) {}\n\nPRE_SYSCALL(msgrcv)(long msqid, void *msgp, long msgsz, long msgtyp,\n                    long msgflg) {}\n\nPOST_SYSCALL(msgrcv)(long res, long msqid, void *msgp, long msgsz, long msgtyp,\n                     long msgflg) {\n  if (res >= 0) {\n    if (msgp) POST_WRITE(msgp, res);\n  }\n}\n\n#if !SANITIZER_ANDROID\nPRE_SYSCALL(msgctl)(long msqid, long cmd, void *buf) {}\n\nPOST_SYSCALL(msgctl)(long res, long msqid, long cmd, void *buf) {\n  if (res >= 0) {\n    if (buf) POST_WRITE(buf, struct_msqid_ds_sz);\n  }\n}\n#endif\n\nPRE_SYSCALL(semget)(long key, long nsems, long semflg) {}\n\nPOST_SYSCALL(semget)(long res, long key, long nsems, long semflg) {}\n\nPRE_SYSCALL(semop)(long semid, void *sops, long nsops) {}\n\nPOST_SYSCALL(semop)(long res, long semid, void *sops, long nsops) {}\n\nPRE_SYSCALL(semctl)(long semid, long semnum, long cmd, void *arg) {}\n\nPOST_SYSCALL(semctl)(long res, long semid, long semnum, long cmd, void *arg) {}\n\nPRE_SYSCALL(semtimedop)(long semid, void *sops, long nsops,\n                        const void *timeout) {\n  if (timeout) PRE_READ(timeout, struct_timespec_sz);\n}\n\nPOST_SYSCALL(semtimedop)(long res, long semid, void *sops, long nsops,\n                         const void *timeout) {}\n\nPRE_SYSCALL(shmat)(long shmid, void *shmaddr, long shmflg) {}\n\nPOST_SYSCALL(shmat)(long res, long shmid, void *shmaddr, long shmflg) {\n  if (res >= 0) {\n    if (shmaddr)\n      POST_WRITE(shmaddr,\n                 __sanitizer::internal_strlen((const char *)shmaddr) + 1);\n  }\n}\n\nPRE_SYSCALL(shmget)(long key, long size, long flag) {}\n\nPOST_SYSCALL(shmget)(long res, long key, long size, long flag) {}\n\nPRE_SYSCALL(shmdt)(void *shmaddr) {}\n\nPOST_SYSCALL(shmdt)(long res, void *shmaddr) {\n  if (res >= 0) {\n    if (shmaddr)\n      POST_WRITE(shmaddr,\n                 __sanitizer::internal_strlen((const char *)shmaddr) + 1);\n  }\n}\n\nPRE_SYSCALL(ipc)(long call, long first, long second, long third, void *ptr,\n                 long fifth) {}\n\nPOST_SYSCALL(ipc)(long res, long call, long first, long second, long third,\n                  void *ptr, long fifth) {}\n\n#if !SANITIZER_ANDROID\nPRE_SYSCALL(shmctl)(long shmid, long cmd, void *buf) {}\n\nPOST_SYSCALL(shmctl)(long res, long shmid, long cmd, void *buf) {\n  if (res >= 0) {\n    if (buf) POST_WRITE(buf, sizeof(__sanitizer_shmid_ds));\n  }\n}\n\nPRE_SYSCALL(mq_open)(const void *name, long oflag, long mode, void *attr) {\n  if (name)\n    PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1);\n}\n\nPOST_SYSCALL(mq_open)(long res, const void *name, long oflag, long mode,\n                      void *attr) {\n  if (res >= 0) {\n    if (attr) POST_WRITE(attr, struct_mq_attr_sz);\n  }\n}\n\nPRE_SYSCALL(mq_unlink)(const void *name) {\n  if (name)\n    PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1);\n}\n\nPOST_SYSCALL(mq_unlink)(long res, const void *name) {}\n\nPRE_SYSCALL(mq_timedsend)(long mqdes, const void *msg_ptr, long msg_len,\n                          long msg_prio, const void *abs_timeout) {\n  if (msg_ptr) PRE_READ(msg_ptr, msg_len);\n  if (abs_timeout) PRE_READ(abs_timeout, struct_timespec_sz);\n}\n\nPOST_SYSCALL(mq_timedsend)(long res, long mqdes, const void *msg_ptr,\n                           long msg_len, long msg_prio,\n                           const void *abs_timeout) {}\n\nPRE_SYSCALL(mq_timedreceive)(long mqdes, void *msg_ptr, long msg_len,\n                             void *msg_prio, const void *abs_timeout) {\n  if (abs_timeout) PRE_READ(abs_timeout, struct_timespec_sz);\n}\n\nPOST_SYSCALL(mq_timedreceive)(long res, long mqdes, void *msg_ptr, long msg_len,\n                              int *msg_prio, const void *abs_timeout) {\n  if (res >= 0) {\n    if (msg_ptr) POST_WRITE(msg_ptr, res);\n    if (msg_prio) POST_WRITE(msg_prio, sizeof(*msg_prio));\n  }\n}\n\nPRE_SYSCALL(mq_notify)(long mqdes, const void *notification) {\n  if (notification) PRE_READ(notification, struct_sigevent_sz);\n}\n\nPOST_SYSCALL(mq_notify)(long res, long mqdes, const void *notification) {}\n\nPRE_SYSCALL(mq_getsetattr)(long mqdes, const void *mqstat, void *omqstat) {\n  if (mqstat) PRE_READ(mqstat, struct_mq_attr_sz);\n}\n\nPOST_SYSCALL(mq_getsetattr)(long res, long mqdes, const void *mqstat,\n                            void *omqstat) {\n  if (res >= 0) {\n    if (omqstat) POST_WRITE(omqstat, struct_mq_attr_sz);\n  }\n}\n#endif  // SANITIZER_ANDROID\n\nPRE_SYSCALL(pciconfig_iobase)(long which, long bus, long devfn) {}\n\nPOST_SYSCALL(pciconfig_iobase)(long res, long which, long bus, long devfn) {}\n\nPRE_SYSCALL(pciconfig_read)(long bus, long dfn, long off, long len, void *buf) {\n}\n\nPOST_SYSCALL(pciconfig_read)(long res, long bus, long dfn, long off, long len,\n                             void *buf) {}\n\nPRE_SYSCALL(pciconfig_write)(long bus, long dfn, long off, long len,\n                             void *buf) {}\n\nPOST_SYSCALL(pciconfig_write)(long res, long bus, long dfn, long off, long len,\n                              void *buf) {}\n\nPRE_SYSCALL(swapon)(const void *specialfile, long swap_flags) {\n  if (specialfile)\n    PRE_READ(specialfile,\n             __sanitizer::internal_strlen((const char *)specialfile) + 1);\n}\n\nPOST_SYSCALL(swapon)(long res, const void *specialfile, long swap_flags) {}\n\nPRE_SYSCALL(swapoff)(const void *specialfile) {\n  if (specialfile)\n    PRE_READ(specialfile,\n             __sanitizer::internal_strlen((const char *)specialfile) + 1);\n}\n\nPOST_SYSCALL(swapoff)(long res, const void *specialfile) {}\n\nPRE_SYSCALL(sysctl)(__sanitizer___sysctl_args *args) {\n  if (args) {\n    if (args->name) PRE_READ(args->name, args->nlen * sizeof(*args->name));\n    if (args->newval) PRE_READ(args->name, args->newlen);\n  }\n}\n\nPOST_SYSCALL(sysctl)(long res, __sanitizer___sysctl_args *args) {\n  if (res >= 0) {\n    if (args && args->oldval && args->oldlenp) {\n      POST_WRITE(args->oldlenp, sizeof(*args->oldlenp));\n      POST_WRITE(args->oldval, *args->oldlenp);\n    }\n  }\n}\n\nPRE_SYSCALL(sysinfo)(void *info) {}\n\nPOST_SYSCALL(sysinfo)(long res, void *info) {\n  if (res >= 0) {\n    if (info) POST_WRITE(info, struct_sysinfo_sz);\n  }\n}\n\nPRE_SYSCALL(sysfs)(long option, long arg1, long arg2) {}\n\nPOST_SYSCALL(sysfs)(long res, long option, long arg1, long arg2) {}\n\nPRE_SYSCALL(syslog)(long type, void *buf, long len) {}\n\nPOST_SYSCALL(syslog)(long res, long type, void *buf, long len) {\n  if (res >= 0) {\n    if (buf)\n      POST_WRITE(buf, __sanitizer::internal_strlen((const char *)buf) + 1);\n  }\n}\n\nPRE_SYSCALL(uselib)(const void *library) {\n  if (library)\n    PRE_READ(library, __sanitizer::internal_strlen((const char *)library) + 1);\n}\n\nPOST_SYSCALL(uselib)(long res, const void *library) {}\n\nPRE_SYSCALL(ni_syscall)() {}\n\nPOST_SYSCALL(ni_syscall)(long res) {}\n\nPRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) {\n#if !SANITIZER_ANDROID && \\\n    (defined(__i386) || defined(__x86_64) || defined(__mips64) || \\\n     defined(__powerpc64__) || defined(__aarch64__))\n  if (data) {\n    if (request == ptrace_setregs) {\n      PRE_READ((void *)data, struct_user_regs_struct_sz);\n    } else if (request == ptrace_setfpregs) {\n      PRE_READ((void *)data, struct_user_fpregs_struct_sz);\n    } else if (request == ptrace_setfpxregs) {\n      PRE_READ((void *)data, struct_user_fpxregs_struct_sz);\n    } else if (request == ptrace_setsiginfo) {\n      PRE_READ((void *)data, siginfo_t_sz);\n    } else if (request == ptrace_setregset) {\n      __sanitizer_iovec *iov = (__sanitizer_iovec *)data;\n      PRE_READ(iov->iov_base, iov->iov_len);\n    }\n  }\n#endif\n}\n\nPOST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) {\n#if !SANITIZER_ANDROID && \\\n    (defined(__i386) || defined(__x86_64) || defined(__mips64) || \\\n     defined(__powerpc64__) || defined(__aarch64__))\n  if (res >= 0 && data) {\n    // Note that this is different from the interceptor in\n    // sanitizer_common_interceptors.inc.\n    // PEEK* requests return resulting values through data pointer.\n    if (request == ptrace_getregs) {\n      POST_WRITE((void *)data, struct_user_regs_struct_sz);\n    } else if (request == ptrace_getfpregs) {\n      POST_WRITE((void *)data, struct_user_fpregs_struct_sz);\n    } else if (request == ptrace_getfpxregs) {\n      POST_WRITE((void *)data, struct_user_fpxregs_struct_sz);\n    } else if (request == ptrace_getsiginfo) {\n      POST_WRITE((void *)data, siginfo_t_sz);\n    } else if (request == ptrace_getregset) {\n      __sanitizer_iovec *iov = (__sanitizer_iovec *)data;\n      POST_WRITE(iov->iov_base, iov->iov_len);\n    } else if (request == ptrace_peekdata || request == ptrace_peektext ||\n               request == ptrace_peekuser) {\n      POST_WRITE((void *)data, sizeof(void *));\n    }\n  }\n#endif\n}\n\nPRE_SYSCALL(add_key)(const void *_type, const void *_description,\n                     const void *_payload, long plen, long destringid) {\n  if (_type)\n    PRE_READ(_type, __sanitizer::internal_strlen((const char *)_type) + 1);\n  if (_description)\n    PRE_READ(_description,\n             __sanitizer::internal_strlen((const char *)_description) + 1);\n}\n\nPOST_SYSCALL(add_key)(long res, const void *_type, const void *_description,\n                      const void *_payload, long plen, long destringid) {}\n\nPRE_SYSCALL(request_key)(const void *_type, const void *_description,\n                         const void *_callout_info, long destringid) {\n  if (_type)\n    PRE_READ(_type, __sanitizer::internal_strlen((const char *)_type) + 1);\n  if (_description)\n    PRE_READ(_description,\n             __sanitizer::internal_strlen((const char *)_description) + 1);\n  if (_callout_info)\n    PRE_READ(_callout_info,\n             __sanitizer::internal_strlen((const char *)_callout_info) + 1);\n}\n\nPOST_SYSCALL(request_key)(long res, const void *_type, const void *_description,\n                          const void *_callout_info, long destringid) {}\n\nPRE_SYSCALL(keyctl)(long cmd, long arg2, long arg3, long arg4, long arg5) {}\n\nPOST_SYSCALL(keyctl)(long res, long cmd, long arg2, long arg3, long arg4,\n                     long arg5) {}\n\nPRE_SYSCALL(ioprio_set)(long which, long who, long ioprio) {}\n\nPOST_SYSCALL(ioprio_set)(long res, long which, long who, long ioprio) {}\n\nPRE_SYSCALL(ioprio_get)(long which, long who) {}\n\nPOST_SYSCALL(ioprio_get)(long res, long which, long who) {}\n\nPRE_SYSCALL(set_mempolicy)(long mode, void *nmask, long maxnode) {}\n\nPOST_SYSCALL(set_mempolicy)(long res, long mode, void *nmask, long maxnode) {\n  if (res >= 0) {\n    if (nmask) POST_WRITE(nmask, sizeof(long));\n  }\n}\n\nPRE_SYSCALL(migrate_pages)(long pid, long maxnode, const void *from,\n                           const void *to) {\n  if (from) PRE_READ(from, sizeof(long));\n  if (to) PRE_READ(to, sizeof(long));\n}\n\nPOST_SYSCALL(migrate_pages)(long res, long pid, long maxnode, const void *from,\n                            const void *to) {}\n\nPRE_SYSCALL(move_pages)(long pid, long nr_pages, const void **pages,\n                        const int *nodes, int *status, long flags) {\n  if (pages) PRE_READ(pages, nr_pages * sizeof(*pages));\n  if (nodes) PRE_READ(nodes, nr_pages * sizeof(*nodes));\n}\n\nPOST_SYSCALL(move_pages)(long res, long pid, long nr_pages, const void **pages,\n                         const int *nodes, int *status, long flags) {\n  if (res >= 0) {\n    if (status) POST_WRITE(status, nr_pages * sizeof(*status));\n  }\n}\n\nPRE_SYSCALL(mbind)(long start, long len, long mode, void *nmask, long maxnode,\n                   long flags) {}\n\nPOST_SYSCALL(mbind)(long res, long start, long len, long mode, void *nmask,\n                    long maxnode, long flags) {\n  if (res >= 0) {\n    if (nmask) POST_WRITE(nmask, sizeof(long));\n  }\n}\n\nPRE_SYSCALL(get_mempolicy)(void *policy, void *nmask, long maxnode, long addr,\n                           long flags) {}\n\nPOST_SYSCALL(get_mempolicy)(long res, void *policy, void *nmask, long maxnode,\n                            long addr, long flags) {\n  if (res >= 0) {\n    if (policy) POST_WRITE(policy, sizeof(int));\n    if (nmask) POST_WRITE(nmask, sizeof(long));\n  }\n}\n\nPRE_SYSCALL(inotify_init)() {}\n\nPOST_SYSCALL(inotify_init)(long res) {}\n\nPRE_SYSCALL(inotify_init1)(long flags) {}\n\nPOST_SYSCALL(inotify_init1)(long res, long flags) {}\n\nPRE_SYSCALL(inotify_add_watch)(long fd, const void *path, long mask) {\n  if (path)\n    PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1);\n}\n\nPOST_SYSCALL(inotify_add_watch)(long res, long fd, const void *path,\n                                long mask) {}\n\nPRE_SYSCALL(inotify_rm_watch)(long fd, long wd) {}\n\nPOST_SYSCALL(inotify_rm_watch)(long res, long fd, long wd) {}\n\nPRE_SYSCALL(spu_run)(long fd, void *unpc, void *ustatus) {}\n\nPOST_SYSCALL(spu_run)(long res, long fd, unsigned *unpc, unsigned *ustatus) {\n  if (res >= 0) {\n    if (unpc) POST_WRITE(unpc, sizeof(*unpc));\n    if (ustatus) POST_WRITE(ustatus, sizeof(*ustatus));\n  }\n}\n\nPRE_SYSCALL(spu_create)(const void *name, long flags, long mode, long fd) {\n  if (name)\n    PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1);\n}\n\nPOST_SYSCALL(spu_create)(long res, const void *name, long flags, long mode,\n                         long fd) {}\n\nPRE_SYSCALL(mknodat)(long dfd, const void *filename, long mode, long dev) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(mknodat)(long res, long dfd, const void *filename, long mode,\n                      long dev) {}\n\nPRE_SYSCALL(mkdirat)(long dfd, const void *pathname, long mode) {\n  if (pathname)\n    PRE_READ(pathname,\n             __sanitizer::internal_strlen((const char *)pathname) + 1);\n}\n\nPOST_SYSCALL(mkdirat)(long res, long dfd, const void *pathname, long mode) {}\n\nPRE_SYSCALL(unlinkat)(long dfd, const void *pathname, long flag) {\n  if (pathname)\n    PRE_READ(pathname,\n             __sanitizer::internal_strlen((const char *)pathname) + 1);\n}\n\nPOST_SYSCALL(unlinkat)(long res, long dfd, const void *pathname, long flag) {}\n\nPRE_SYSCALL(symlinkat)(const void *oldname, long newdfd, const void *newname) {\n  if (oldname)\n    PRE_READ(oldname, __sanitizer::internal_strlen((const char *)oldname) + 1);\n  if (newname)\n    PRE_READ(newname, __sanitizer::internal_strlen((const char *)newname) + 1);\n}\n\nPOST_SYSCALL(symlinkat)(long res, const void *oldname, long newdfd,\n                        const void *newname) {}\n\nPRE_SYSCALL(linkat)(long olddfd, const void *oldname, long newdfd,\n                    const void *newname, long flags) {\n  if (oldname)\n    PRE_READ(oldname, __sanitizer::internal_strlen((const char *)oldname) + 1);\n  if (newname)\n    PRE_READ(newname, __sanitizer::internal_strlen((const char *)newname) + 1);\n}\n\nPOST_SYSCALL(linkat)(long res, long olddfd, const void *oldname, long newdfd,\n                     const void *newname, long flags) {}\n\nPRE_SYSCALL(renameat)(long olddfd, const void *oldname, long newdfd,\n                      const void *newname) {\n  if (oldname)\n    PRE_READ(oldname, __sanitizer::internal_strlen((const char *)oldname) + 1);\n  if (newname)\n    PRE_READ(newname, __sanitizer::internal_strlen((const char *)newname) + 1);\n}\n\nPOST_SYSCALL(renameat)(long res, long olddfd, const void *oldname, long newdfd,\n                       const void *newname) {}\n\nPRE_SYSCALL(futimesat)(long dfd, const void *filename, void *utimes) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(futimesat)(long res, long dfd, const void *filename,\n                        void *utimes) {\n  if (res >= 0) {\n    if (utimes) POST_WRITE(utimes, timeval_sz);\n  }\n}\n\nPRE_SYSCALL(faccessat)(long dfd, const void *filename, long mode) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(faccessat)(long res, long dfd, const void *filename, long mode) {}\n\nPRE_SYSCALL(fchmodat)(long dfd, const void *filename, long mode) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(fchmodat)(long res, long dfd, const void *filename, long mode) {}\n\nPRE_SYSCALL(fchownat)(long dfd, const void *filename, long user, long group,\n                      long flag) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(fchownat)(long res, long dfd, const void *filename, long user,\n                       long group, long flag) {}\n\nPRE_SYSCALL(openat)(long dfd, const void *filename, long flags, long mode) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(openat)(long res, long dfd, const void *filename, long flags,\n                     long mode) {}\n\nPRE_SYSCALL(newfstatat)(long dfd, const void *filename, void *statbuf,\n                        long flag) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(newfstatat)(long res, long dfd, const void *filename,\n                         void *statbuf, long flag) {\n  if (res >= 0) {\n    if (statbuf) POST_WRITE(statbuf, struct_kernel_stat_sz);\n  }\n}\n\nPRE_SYSCALL(fstatat64)(long dfd, const void *filename, void *statbuf,\n                       long flag) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(fstatat64)(long res, long dfd, const void *filename, void *statbuf,\n                        long flag) {\n  if (res >= 0) {\n    if (statbuf) POST_WRITE(statbuf, struct_kernel_stat64_sz);\n  }\n}\n\nPRE_SYSCALL(readlinkat)(long dfd, const void *path, void *buf, long bufsiz) {\n  if (path)\n    PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1);\n}\n\nPOST_SYSCALL(readlinkat)(long res, long dfd, const void *path, void *buf,\n                         long bufsiz) {\n  if (res >= 0) {\n    if (buf)\n      POST_WRITE(buf, __sanitizer::internal_strlen((const char *)buf) + 1);\n  }\n}\n\nPRE_SYSCALL(utimensat)(long dfd, const void *filename, void *utimes,\n                       long flags) {\n  if (filename)\n    PRE_READ(filename,\n             __sanitizer::internal_strlen((const char *)filename) + 1);\n}\n\nPOST_SYSCALL(utimensat)(long res, long dfd, const void *filename, void *utimes,\n                        long flags) {\n  if (res >= 0) {\n    if (utimes) POST_WRITE(utimes, struct_timespec_sz);\n  }\n}\n\nPRE_SYSCALL(unshare)(long unshare_flags) {}\n\nPOST_SYSCALL(unshare)(long res, long unshare_flags) {}\n\nPRE_SYSCALL(splice)(long fd_in, void *off_in, long fd_out, void *off_out,\n                    long len, long flags) {}\n\nPOST_SYSCALL(splice)(long res, long fd_in, void *off_in, long fd_out,\n                     void *off_out, long len, long flags) {\n  if (res >= 0) {\n    if (off_in) POST_WRITE(off_in, sizeof(long long));\n    if (off_out) POST_WRITE(off_out, sizeof(long long));\n  }\n}\n\nPRE_SYSCALL(vmsplice)(long fd, const __sanitizer_iovec *iov, long nr_segs,\n                      long flags) {}\n\nPOST_SYSCALL(vmsplice)(long res, long fd, const __sanitizer_iovec *iov,\n                       long nr_segs, long flags) {\n  if (res >= 0) {\n    if (iov) kernel_read_iovec(iov, nr_segs, res);\n  }\n}\n\nPRE_SYSCALL(tee)(long fdin, long fdout, long len, long flags) {}\n\nPOST_SYSCALL(tee)(long res, long fdin, long fdout, long len, long flags) {}\n\nPRE_SYSCALL(get_robust_list)(long pid, void *head_ptr, void *len_ptr) {}\n\nPOST_SYSCALL(get_robust_list)(long res, long pid, void *head_ptr,\n                              void *len_ptr) {}\n\nPRE_SYSCALL(set_robust_list)(void *head, long len) {}\n\nPOST_SYSCALL(set_robust_list)(long res, void *head, long len) {}\n\nPRE_SYSCALL(getcpu)(void *cpu, void *node, void *cache) {}\n\nPOST_SYSCALL(getcpu)(long res, void *cpu, void *node, void *cache) {\n  if (res >= 0) {\n    if (cpu) POST_WRITE(cpu, sizeof(unsigned));\n    if (node) POST_WRITE(node, sizeof(unsigned));\n    // The third argument to this system call is nowadays unused.\n  }\n}\n\nPRE_SYSCALL(signalfd)(long ufd, void *user_mask, long sizemask) {}\n\nPOST_SYSCALL(signalfd)(long res, long ufd, kernel_sigset_t *user_mask,\n                       long sizemask) {\n  if (res >= 0) {\n    if (user_mask) POST_WRITE(user_mask, sizemask);\n  }\n}\n\nPRE_SYSCALL(signalfd4)(long ufd, void *user_mask, long sizemask, long flags) {}\n\nPOST_SYSCALL(signalfd4)(long res, long ufd, kernel_sigset_t *user_mask,\n                        long sizemask, long flags) {\n  if (res >= 0) {\n    if (user_mask) POST_WRITE(user_mask, sizemask);\n  }\n}\n\nPRE_SYSCALL(timerfd_create)(long clockid, long flags) {}\n\nPOST_SYSCALL(timerfd_create)(long res, long clockid, long flags) {}\n\nPRE_SYSCALL(timerfd_settime)(long ufd, long flags, const void *utmr,\n                             void *otmr) {\n  if (utmr) PRE_READ(utmr, struct_itimerspec_sz);\n}\n\nPOST_SYSCALL(timerfd_settime)(long res, long ufd, long flags, const void *utmr,\n                              void *otmr) {\n  if (res >= 0) {\n    if (otmr) POST_WRITE(otmr, struct_itimerspec_sz);\n  }\n}\n\nPRE_SYSCALL(timerfd_gettime)(long ufd, void *otmr) {}\n\nPOST_SYSCALL(timerfd_gettime)(long res, long ufd, void *otmr) {\n  if (res >= 0) {\n    if (otmr) POST_WRITE(otmr, struct_itimerspec_sz);\n  }\n}\n\nPRE_SYSCALL(eventfd)(long count) {}\n\nPOST_SYSCALL(eventfd)(long res, long count) {}\n\nPRE_SYSCALL(eventfd2)(long count, long flags) {}\n\nPOST_SYSCALL(eventfd2)(long res, long count, long flags) {}\n\nPRE_SYSCALL(old_readdir)(long arg0, void *arg1, long arg2) {}\n\nPOST_SYSCALL(old_readdir)(long res, long arg0, void *arg1, long arg2) {\n  // Missing definition of 'struct old_linux_dirent'.\n}\n\nPRE_SYSCALL(pselect6)(long arg0, __sanitizer___kernel_fd_set *arg1,\n                      __sanitizer___kernel_fd_set *arg2,\n                      __sanitizer___kernel_fd_set *arg3, void *arg4,\n                      void *arg5) {}\n\nPOST_SYSCALL(pselect6)(long res, long arg0, __sanitizer___kernel_fd_set *arg1,\n                       __sanitizer___kernel_fd_set *arg2,\n                       __sanitizer___kernel_fd_set *arg3, void *arg4,\n                       void *arg5) {\n  if (res >= 0) {\n    if (arg1) POST_WRITE(arg1, sizeof(*arg1));\n    if (arg2) POST_WRITE(arg2, sizeof(*arg2));\n    if (arg3) POST_WRITE(arg3, sizeof(*arg3));\n    if (arg4) POST_WRITE(arg4, struct_timespec_sz);\n  }\n}\n\nPRE_SYSCALL(ppoll)(__sanitizer_pollfd *arg0, long arg1, void *arg2,\n                   const kernel_sigset_t *arg3, long arg4) {\n  if (arg3) PRE_READ(arg3, arg4);\n}\n\nPOST_SYSCALL(ppoll)(long res, __sanitizer_pollfd *arg0, long arg1, void *arg2,\n                    const void *arg3, long arg4) {\n  if (res >= 0) {\n    if (arg0) POST_WRITE(arg0, sizeof(*arg0));\n    if (arg2) POST_WRITE(arg2, struct_timespec_sz);\n  }\n}\n\nPRE_SYSCALL(syncfs)(long fd) {}\n\nPOST_SYSCALL(syncfs)(long res, long fd) {}\n\nPRE_SYSCALL(perf_event_open)(__sanitizer_perf_event_attr *attr_uptr, long pid,\n                             long cpu, long group_fd, long flags) {\n  if (attr_uptr) PRE_READ(attr_uptr, attr_uptr->size);\n}\n\nPOST_SYSCALL(perf_event_open)(long res, __sanitizer_perf_event_attr *attr_uptr,\n                              long pid, long cpu, long group_fd, long flags) {}\n\nPRE_SYSCALL(mmap_pgoff)(long addr, long len, long prot, long flags, long fd,\n                        long pgoff) {}\n\nPOST_SYSCALL(mmap_pgoff)(long res, long addr, long len, long prot, long flags,\n                         long fd, long pgoff) {}\n\nPRE_SYSCALL(old_mmap)(void *arg) {}\n\nPOST_SYSCALL(old_mmap)(long res, void *arg) {}\n\nPRE_SYSCALL(name_to_handle_at)(long dfd, const void *name, void *handle,\n                               void *mnt_id, long flag) {}\n\nPOST_SYSCALL(name_to_handle_at)(long res, long dfd, const void *name,\n                                void *handle, void *mnt_id, long flag) {}\n\nPRE_SYSCALL(open_by_handle_at)(long mountdirfd, void *handle, long flags) {}\n\nPOST_SYSCALL(open_by_handle_at)(long res, long mountdirfd, void *handle,\n                                long flags) {}\n\nPRE_SYSCALL(setns)(long fd, long nstype) {}\n\nPOST_SYSCALL(setns)(long res, long fd, long nstype) {}\n\nPRE_SYSCALL(process_vm_readv)(long pid, const __sanitizer_iovec *lvec,\n                              long liovcnt, const void *rvec, long riovcnt,\n                              long flags) {}\n\nPOST_SYSCALL(process_vm_readv)(long res, long pid,\n                               const __sanitizer_iovec *lvec, long liovcnt,\n                               const void *rvec, long riovcnt, long flags) {\n  if (res >= 0) {\n    if (lvec) kernel_write_iovec(lvec, liovcnt, res);\n  }\n}\n\nPRE_SYSCALL(process_vm_writev)(long pid, const __sanitizer_iovec *lvec,\n                               long liovcnt, const void *rvec, long riovcnt,\n                               long flags) {}\n\nPOST_SYSCALL(process_vm_writev)(long res, long pid,\n                                const __sanitizer_iovec *lvec, long liovcnt,\n                                const void *rvec, long riovcnt, long flags) {\n  if (res >= 0) {\n    if (lvec) kernel_read_iovec(lvec, liovcnt, res);\n  }\n}\n\nPRE_SYSCALL(fork)() {\n  COMMON_SYSCALL_PRE_FORK();\n}\n\nPOST_SYSCALL(fork)(long res) {\n  COMMON_SYSCALL_POST_FORK(res);\n}\n\nPRE_SYSCALL(vfork)() {\n  COMMON_SYSCALL_PRE_FORK();\n}\n\nPOST_SYSCALL(vfork)(long res) {\n  COMMON_SYSCALL_POST_FORK(res);\n}\n}  // extern \"C\"\n\n#undef PRE_SYSCALL\n#undef PRE_READ\n#undef PRE_WRITE\n#undef POST_SYSCALL\n#undef POST_READ\n#undef POST_WRITE\n\n#endif  // SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc",
    "content": "//===-- sanitizer_coverage.cc ---------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Sanitizer Coverage.\n// This file implements run-time support for a poor man's coverage tool.\n//\n// Compiler instrumentation:\n// For every interesting basic block the compiler injects the following code:\n// if (Guard < 0) {\n//    __sanitizer_cov(&Guard);\n// }\n// At the module start up time __sanitizer_cov_module_init sets the guards\n// to consecutive negative numbers (-1, -2, -3, ...).\n// It's fine to call __sanitizer_cov more than once for a given block.\n//\n// Run-time:\n//  - __sanitizer_cov(): record that we've executed the PC (GET_CALLER_PC).\n//    and atomically set Guard to -Guard.\n//  - __sanitizer_cov_dump: dump the coverage data to disk.\n//  For every module of the current process that has coverage data\n//  this will create a file module_name.PID.sancov.\n//\n// The file format is simple: the first 8 bytes is the magic,\n// one of 0xC0BFFFFFFFFFFF64 and 0xC0BFFFFFFFFFFF32. The last byte of the\n// magic defines the size of the following offsets.\n// The rest of the data is the offsets in the module.\n//\n// Eventually, this coverage implementation should be obsoleted by a more\n// powerful general purpose Clang/LLVM coverage instrumentation.\n// Consider this implementation as prototype.\n//\n// FIXME: support (or at least test with) dlclose.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_allocator_internal.h\"\n#include \"sanitizer_common.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_mutex.h\"\n#include \"sanitizer_procmaps.h\"\n#include \"sanitizer_stacktrace.h\"\n#include \"sanitizer_symbolizer.h\"\n#include \"sanitizer_flags.h\"\n\nstatic const u64 kMagic64 = 0xC0BFFFFFFFFFFF64ULL;\nstatic const u64 kMagic32 = 0xC0BFFFFFFFFFFF32ULL;\n\nstatic atomic_uint32_t dump_once_guard;  // Ensure that CovDump runs only once.\n\nstatic atomic_uintptr_t coverage_counter;\nstatic atomic_uintptr_t caller_callee_counter;\n\nstatic void ResetGlobalCounters() {\n  return atomic_store(&coverage_counter, 0, memory_order_relaxed);\n  return atomic_store(&caller_callee_counter, 0, memory_order_relaxed);\n}\n\n// pc_array is the array containing the covered PCs.\n// To make the pc_array thread- and async-signal-safe it has to be large enough.\n// 128M counters \"ought to be enough for anybody\" (4M on 32-bit).\n\n// With coverage_direct=1 in ASAN_OPTIONS, pc_array memory is mapped to a file.\n// In this mode, __sanitizer_cov_dump does nothing, and CovUpdateMapping()\n// dump current memory layout to another file.\n\nstatic bool cov_sandboxed = false;\nstatic fd_t cov_fd = kInvalidFd;\nstatic unsigned int cov_max_block_size = 0;\nstatic bool coverage_enabled = false;\nstatic const char *coverage_dir;\n\nnamespace __sanitizer {\n\nclass CoverageData {\n public:\n  void Init();\n  void Enable();\n  void Disable();\n  void ReInit();\n  void BeforeFork();\n  void AfterFork(int child_pid);\n  void Extend(uptr npcs);\n  void Add(uptr pc, u32 *guard);\n  void IndirCall(uptr caller, uptr callee, uptr callee_cache[],\n                 uptr cache_size);\n  void DumpCallerCalleePairs();\n  void DumpTrace();\n  void DumpAsBitSet();\n  void DumpCounters();\n  void DumpOffsets();\n  void DumpAll();\n\n  ALWAYS_INLINE\n  void TraceBasicBlock(u32 *id);\n\n  void InitializeGuardArray(s32 *guards);\n  void InitializeGuards(s32 *guards, uptr n, const char *module_name,\n                        uptr caller_pc);\n  void InitializeCounters(u8 *counters, uptr n);\n  void ReinitializeGuards();\n  uptr GetNumberOf8bitCounters();\n  uptr Update8bitCounterBitsetAndClearCounters(u8 *bitset);\n\n  uptr *data();\n  uptr size();\n\n private:\n  void DirectOpen();\n  void UpdateModuleNameVec(uptr caller_pc, uptr range_beg, uptr range_end);\n\n  // Maximal size pc array may ever grow.\n  // We MmapNoReserve this space to ensure that the array is contiguous.\n  static const uptr kPcArrayMaxSize = FIRST_32_SECOND_64(\n      1 << (SANITIZER_ANDROID ? 24 : (SANITIZER_WINDOWS ? 27 : 26)),\n      1 << 27);\n  // The amount file mapping for the pc array is grown by.\n  static const uptr kPcArrayMmapSize = 64 * 1024;\n\n  // pc_array is allocated with MmapNoReserveOrDie and so it uses only as\n  // much RAM as it really needs.\n  uptr *pc_array;\n  // Index of the first available pc_array slot.\n  atomic_uintptr_t pc_array_index;\n  // Array size.\n  atomic_uintptr_t pc_array_size;\n  // Current file mapped size of the pc array.\n  uptr pc_array_mapped_size;\n  // Descriptor of the file mapped pc array.\n  fd_t pc_fd;\n\n  // Vector of coverage guard arrays, protected by mu.\n  InternalMmapVectorNoCtor<s32*> guard_array_vec;\n\n  struct NamedPcRange {\n    const char *copied_module_name;\n    uptr beg, end; // elements [beg,end) in pc_array.\n  };\n\n  // Vector of module and compilation unit pc ranges.\n  InternalMmapVectorNoCtor<NamedPcRange> comp_unit_name_vec;\n  InternalMmapVectorNoCtor<NamedPcRange> module_name_vec;\n\n  struct CounterAndSize {\n    u8 *counters;\n    uptr n;\n  };\n\n  InternalMmapVectorNoCtor<CounterAndSize> counters_vec;\n  uptr num_8bit_counters;\n\n  // Caller-Callee (cc) array, size and current index.\n  static const uptr kCcArrayMaxSize = FIRST_32_SECOND_64(1 << 18, 1 << 24);\n  uptr **cc_array;\n  atomic_uintptr_t cc_array_index;\n  atomic_uintptr_t cc_array_size;\n\n  // Tracing event array, size and current pointer.\n  // We record all events (basic block entries) in a global buffer of u32\n  // values. Each such value is the index in pc_array.\n  // So far the tracing is highly experimental:\n  //   - not thread-safe;\n  //   - does not support long traces;\n  //   - not tuned for performance.\n  static const uptr kTrEventArrayMaxSize = FIRST_32_SECOND_64(1 << 22, 1 << 30);\n  u32 *tr_event_array;\n  uptr tr_event_array_size;\n  u32 *tr_event_pointer;\n  static const uptr kTrPcArrayMaxSize    = FIRST_32_SECOND_64(1 << 22, 1 << 27);\n\n  StaticSpinMutex mu;\n};\n\nstatic CoverageData coverage_data;\n\nvoid CovUpdateMapping(const char *path, uptr caller_pc = 0);\n\nvoid CoverageData::DirectOpen() {\n  InternalScopedString path(kMaxPathLength);\n  internal_snprintf((char *)path.data(), path.size(), \"%s/%zd.sancov.raw\",\n                    coverage_dir, internal_getpid());\n  pc_fd = OpenFile(path.data(), RdWr);\n  if (pc_fd == kInvalidFd) {\n    Report(\"Coverage: failed to open %s for reading/writing\\n\", path.data());\n    Die();\n  }\n\n  pc_array_mapped_size = 0;\n  CovUpdateMapping(coverage_dir);\n}\n\nvoid CoverageData::Init() {\n  pc_fd = kInvalidFd;\n}\n\nvoid CoverageData::Enable() {\n  if (pc_array)\n    return;\n  pc_array = reinterpret_cast<uptr *>(\n      MmapNoReserveOrDie(sizeof(uptr) * kPcArrayMaxSize, \"CovInit\"));\n  atomic_store(&pc_array_index, 0, memory_order_relaxed);\n  if (common_flags()->coverage_direct) {\n    atomic_store(&pc_array_size, 0, memory_order_relaxed);\n  } else {\n    atomic_store(&pc_array_size, kPcArrayMaxSize, memory_order_relaxed);\n  }\n\n  cc_array = reinterpret_cast<uptr **>(MmapNoReserveOrDie(\n      sizeof(uptr *) * kCcArrayMaxSize, \"CovInit::cc_array\"));\n  atomic_store(&cc_array_size, kCcArrayMaxSize, memory_order_relaxed);\n  atomic_store(&cc_array_index, 0, memory_order_relaxed);\n\n  // Allocate tr_event_array with a guard page at the end.\n  tr_event_array = reinterpret_cast<u32 *>(MmapNoReserveOrDie(\n      sizeof(tr_event_array[0]) * kTrEventArrayMaxSize + GetMmapGranularity(),\n      \"CovInit::tr_event_array\"));\n  MprotectNoAccess(\n      reinterpret_cast<uptr>(&tr_event_array[kTrEventArrayMaxSize]),\n      GetMmapGranularity());\n  tr_event_array_size = kTrEventArrayMaxSize;\n  tr_event_pointer = tr_event_array;\n\n  num_8bit_counters = 0;\n}\n\nvoid CoverageData::InitializeGuardArray(s32 *guards) {\n  Enable();  // Make sure coverage is enabled at this point.\n  s32 n = guards[0];\n  for (s32 j = 1; j <= n; j++) {\n    uptr idx = atomic_load_relaxed(&pc_array_index);\n    atomic_store_relaxed(&pc_array_index, idx + 1);\n    guards[j] = -static_cast<s32>(idx + 1);\n  }\n}\n\nvoid CoverageData::Disable() {\n  if (pc_array) {\n    UnmapOrDie(pc_array, sizeof(uptr) * kPcArrayMaxSize);\n    pc_array = nullptr;\n  }\n  if (cc_array) {\n    UnmapOrDie(cc_array, sizeof(uptr *) * kCcArrayMaxSize);\n    cc_array = nullptr;\n  }\n  if (tr_event_array) {\n    UnmapOrDie(tr_event_array,\n               sizeof(tr_event_array[0]) * kTrEventArrayMaxSize +\n                   GetMmapGranularity());\n    tr_event_array = nullptr;\n    tr_event_pointer = nullptr;\n  }\n  if (pc_fd != kInvalidFd) {\n    CloseFile(pc_fd);\n    pc_fd = kInvalidFd;\n  }\n}\n\nvoid CoverageData::ReinitializeGuards() {\n  // Assuming single thread.\n  atomic_store(&pc_array_index, 0, memory_order_relaxed);\n  for (uptr i = 0; i < guard_array_vec.size(); i++)\n    InitializeGuardArray(guard_array_vec[i]);\n}\n\nvoid CoverageData::ReInit() {\n  Disable();\n  if (coverage_enabled) {\n    if (common_flags()->coverage_direct) {\n      // In memory-mapped mode we must extend the new file to the known array\n      // size.\n      uptr size = atomic_load(&pc_array_size, memory_order_relaxed);\n      uptr npcs = size / sizeof(uptr);\n      Enable();\n      if (size) Extend(npcs);\n      if (coverage_enabled) CovUpdateMapping(coverage_dir);\n    } else {\n      Enable();\n    }\n  }\n  // Re-initialize the guards.\n  // We are single-threaded now, no need to grab any lock.\n  CHECK_EQ(atomic_load(&pc_array_index, memory_order_relaxed), 0);\n  ReinitializeGuards();\n}\n\nvoid CoverageData::BeforeFork() {\n  mu.Lock();\n}\n\nvoid CoverageData::AfterFork(int child_pid) {\n  // We are single-threaded so it's OK to release the lock early.\n  mu.Unlock();\n  if (child_pid == 0) ReInit();\n}\n\n// Extend coverage PC array to fit additional npcs elements.\nvoid CoverageData::Extend(uptr npcs) {\n  if (!common_flags()->coverage_direct) return;\n  SpinMutexLock l(&mu);\n\n  uptr size = atomic_load(&pc_array_size, memory_order_relaxed);\n  size += npcs * sizeof(uptr);\n\n  if (coverage_enabled && size > pc_array_mapped_size) {\n    if (pc_fd == kInvalidFd) DirectOpen();\n    CHECK_NE(pc_fd, kInvalidFd);\n\n    uptr new_mapped_size = pc_array_mapped_size;\n    while (size > new_mapped_size) new_mapped_size += kPcArrayMmapSize;\n    CHECK_LE(new_mapped_size, sizeof(uptr) * kPcArrayMaxSize);\n\n    // Extend the file and map the new space at the end of pc_array.\n    uptr res = internal_ftruncate(pc_fd, new_mapped_size);\n    int err;\n    if (internal_iserror(res, &err)) {\n      Printf(\"failed to extend raw coverage file: %d\\n\", err);\n      Die();\n    }\n\n    uptr next_map_base = ((uptr)pc_array) + pc_array_mapped_size;\n    void *p = MapWritableFileToMemory((void *)next_map_base,\n                                      new_mapped_size - pc_array_mapped_size,\n                                      pc_fd, pc_array_mapped_size);\n    CHECK_EQ((uptr)p, next_map_base);\n    pc_array_mapped_size = new_mapped_size;\n  }\n\n  atomic_store(&pc_array_size, size, memory_order_release);\n}\n\nvoid CoverageData::InitializeCounters(u8 *counters, uptr n) {\n  if (!counters) return;\n  CHECK_EQ(reinterpret_cast<uptr>(counters) % 16, 0);\n  n = RoundUpTo(n, 16); // The compiler must ensure that counters is 16-aligned.\n  SpinMutexLock l(&mu);\n  counters_vec.push_back({counters, n});\n  num_8bit_counters += n;\n}\n\nvoid CoverageData::UpdateModuleNameVec(uptr caller_pc, uptr range_beg,\n                                       uptr range_end) {\n  auto sym = Symbolizer::GetOrInit();\n  if (!sym)\n    return;\n  const char *module_name = sym->GetModuleNameForPc(caller_pc);\n  if (!module_name) return;\n  if (module_name_vec.empty() ||\n      module_name_vec.back().copied_module_name != module_name)\n    module_name_vec.push_back({module_name, range_beg, range_end});\n  else\n    module_name_vec.back().end = range_end;\n}\n\nvoid CoverageData::InitializeGuards(s32 *guards, uptr n,\n                                    const char *comp_unit_name,\n                                    uptr caller_pc) {\n  // The array 'guards' has n+1 elements, we use the element zero\n  // to store 'n'.\n  CHECK_LT(n, 1 << 30);\n  guards[0] = static_cast<s32>(n);\n  InitializeGuardArray(guards);\n  SpinMutexLock l(&mu);\n  uptr range_end = atomic_load(&pc_array_index, memory_order_relaxed);\n  uptr range_beg = range_end - n;\n  comp_unit_name_vec.push_back({comp_unit_name, range_beg, range_end});\n  guard_array_vec.push_back(guards);\n  UpdateModuleNameVec(caller_pc, range_beg, range_end);\n}\n\nstatic const uptr kBundleCounterBits = 16;\n\n// When coverage_order_pcs==true and SANITIZER_WORDSIZE==64\n// we insert the global counter into the first 16 bits of the PC.\nuptr BundlePcAndCounter(uptr pc, uptr counter) {\n  if (SANITIZER_WORDSIZE != 64 || !common_flags()->coverage_order_pcs)\n    return pc;\n  static const uptr kMaxCounter = (1 << kBundleCounterBits) - 1;\n  if (counter > kMaxCounter)\n    counter = kMaxCounter;\n  CHECK_EQ(0, pc >> (SANITIZER_WORDSIZE - kBundleCounterBits));\n  return pc | (counter << (SANITIZER_WORDSIZE - kBundleCounterBits));\n}\n\nuptr UnbundlePc(uptr bundle) {\n  if (SANITIZER_WORDSIZE != 64 || !common_flags()->coverage_order_pcs)\n    return bundle;\n  return (bundle << kBundleCounterBits) >> kBundleCounterBits;\n}\n\nuptr UnbundleCounter(uptr bundle) {\n  if (SANITIZER_WORDSIZE != 64 || !common_flags()->coverage_order_pcs)\n    return 0;\n  return bundle >> (SANITIZER_WORDSIZE - kBundleCounterBits);\n}\n\n// If guard is negative, atomically set it to -guard and store the PC in\n// pc_array.\nvoid CoverageData::Add(uptr pc, u32 *guard) {\n  atomic_uint32_t *atomic_guard = reinterpret_cast<atomic_uint32_t*>(guard);\n  s32 guard_value = atomic_load(atomic_guard, memory_order_relaxed);\n  if (guard_value >= 0) return;\n\n  atomic_store(atomic_guard, -guard_value, memory_order_relaxed);\n  if (!pc_array) return;\n\n  uptr idx = -guard_value - 1;\n  if (idx >= atomic_load(&pc_array_index, memory_order_acquire))\n    return;  // May happen after fork when pc_array_index becomes 0.\n  CHECK_LT(idx * sizeof(uptr),\n           atomic_load(&pc_array_size, memory_order_acquire));\n  uptr counter = atomic_fetch_add(&coverage_counter, 1, memory_order_relaxed);\n  pc_array[idx] = BundlePcAndCounter(pc, counter);\n}\n\n// Registers a pair caller=>callee.\n// When a given caller is seen for the first time, the callee_cache is added\n// to the global array cc_array, callee_cache[0] is set to caller and\n// callee_cache[1] is set to cache_size.\n// Then we are trying to add callee to callee_cache [2,cache_size) if it is\n// not there yet.\n// If the cache is full we drop the callee (may want to fix this later).\nvoid CoverageData::IndirCall(uptr caller, uptr callee, uptr callee_cache[],\n                             uptr cache_size) {\n  if (!cc_array) return;\n  atomic_uintptr_t *atomic_callee_cache =\n      reinterpret_cast<atomic_uintptr_t *>(callee_cache);\n  uptr zero = 0;\n  if (atomic_compare_exchange_strong(&atomic_callee_cache[0], &zero, caller,\n                                     memory_order_seq_cst)) {\n    uptr idx = atomic_fetch_add(&cc_array_index, 1, memory_order_relaxed);\n    CHECK_LT(idx * sizeof(uptr),\n             atomic_load(&cc_array_size, memory_order_acquire));\n    callee_cache[1] = cache_size;\n    cc_array[idx] = callee_cache;\n  }\n  CHECK_EQ(atomic_load(&atomic_callee_cache[0], memory_order_relaxed), caller);\n  for (uptr i = 2; i < cache_size; i++) {\n    uptr was = 0;\n    if (atomic_compare_exchange_strong(&atomic_callee_cache[i], &was, callee,\n                                       memory_order_seq_cst)) {\n      atomic_fetch_add(&caller_callee_counter, 1, memory_order_relaxed);\n      return;\n    }\n    if (was == callee)  // Already have this callee.\n      return;\n  }\n}\n\nuptr CoverageData::GetNumberOf8bitCounters() {\n  return num_8bit_counters;\n}\n\n// Map every 8bit counter to a 8-bit bitset and clear the counter.\nuptr CoverageData::Update8bitCounterBitsetAndClearCounters(u8 *bitset) {\n  uptr num_new_bits = 0;\n  uptr cur = 0;\n  // For better speed we map 8 counters to 8 bytes of bitset at once.\n  static const uptr kBatchSize = 8;\n  CHECK_EQ(reinterpret_cast<uptr>(bitset) % kBatchSize, 0);\n  for (uptr i = 0, len = counters_vec.size(); i < len; i++) {\n    u8 *c = counters_vec[i].counters;\n    uptr n = counters_vec[i].n;\n    CHECK_EQ(n % 16, 0);\n    CHECK_EQ(cur % kBatchSize, 0);\n    CHECK_EQ(reinterpret_cast<uptr>(c) % kBatchSize, 0);\n    if (!bitset) {\n      internal_bzero_aligned16(c, n);\n      cur += n;\n      continue;\n    }\n    for (uptr j = 0; j < n; j += kBatchSize, cur += kBatchSize) {\n      CHECK_LT(cur, num_8bit_counters);\n      u64 *pc64 = reinterpret_cast<u64*>(c + j);\n      u64 *pb64 = reinterpret_cast<u64*>(bitset + cur);\n      u64 c64 = *pc64;\n      u64 old_bits_64 = *pb64;\n      u64 new_bits_64 = old_bits_64;\n      if (c64) {\n        *pc64 = 0;\n        for (uptr k = 0; k < kBatchSize; k++) {\n          u64 x = (c64 >> (8 * k)) & 0xff;\n          if (x) {\n            u64 bit = 0;\n            /**/ if (x >= 128) bit = 128;\n            else if (x >= 32) bit = 64;\n            else if (x >= 16) bit = 32;\n            else if (x >= 8) bit = 16;\n            else if (x >= 4) bit = 8;\n            else if (x >= 3) bit = 4;\n            else if (x >= 2) bit = 2;\n            else if (x >= 1) bit = 1;\n            u64 mask = bit << (8 * k);\n            if (!(new_bits_64 & mask)) {\n              num_new_bits++;\n              new_bits_64 |= mask;\n            }\n          }\n        }\n        *pb64 = new_bits_64;\n      }\n    }\n  }\n  CHECK_EQ(cur, num_8bit_counters);\n  return num_new_bits;\n}\n\nuptr *CoverageData::data() {\n  return pc_array;\n}\n\nuptr CoverageData::size() {\n  return atomic_load(&pc_array_index, memory_order_relaxed);\n}\n\n// Block layout for packed file format: header, followed by module name (no\n// trailing zero), followed by data blob.\nstruct CovHeader {\n  int pid;\n  unsigned int module_name_length;\n  unsigned int data_length;\n};\n\nstatic void CovWritePacked(int pid, const char *module, const void *blob,\n                           unsigned int blob_size) {\n  if (cov_fd == kInvalidFd) return;\n  unsigned module_name_length = internal_strlen(module);\n  CovHeader header = {pid, module_name_length, blob_size};\n\n  if (cov_max_block_size == 0) {\n    // Writing to a file. Just go ahead.\n    WriteToFile(cov_fd, &header, sizeof(header));\n    WriteToFile(cov_fd, module, module_name_length);\n    WriteToFile(cov_fd, blob, blob_size);\n  } else {\n    // Writing to a socket. We want to split the data into appropriately sized\n    // blocks.\n    InternalScopedBuffer<char> block(cov_max_block_size);\n    CHECK_EQ((uptr)block.data(), (uptr)(CovHeader *)block.data());\n    uptr header_size_with_module = sizeof(header) + module_name_length;\n    CHECK_LT(header_size_with_module, cov_max_block_size);\n    unsigned int max_payload_size =\n        cov_max_block_size - header_size_with_module;\n    char *block_pos = block.data();\n    internal_memcpy(block_pos, &header, sizeof(header));\n    block_pos += sizeof(header);\n    internal_memcpy(block_pos, module, module_name_length);\n    block_pos += module_name_length;\n    char *block_data_begin = block_pos;\n    const char *blob_pos = (const char *)blob;\n    while (blob_size > 0) {\n      unsigned int payload_size = Min(blob_size, max_payload_size);\n      blob_size -= payload_size;\n      internal_memcpy(block_data_begin, blob_pos, payload_size);\n      blob_pos += payload_size;\n      ((CovHeader *)block.data())->data_length = payload_size;\n      WriteToFile(cov_fd, block.data(), header_size_with_module + payload_size);\n    }\n  }\n}\n\n// If packed = false: <name>.<pid>.<sancov> (name = module name).\n// If packed = true and name == 0: <pid>.<sancov>.<packed>.\n// If packed = true and name != 0: <name>.<sancov>.<packed> (name is\n// user-supplied).\nstatic fd_t CovOpenFile(InternalScopedString *path, bool packed,\n                       const char *name, const char *extension = \"sancov\") {\n  path->clear();\n  if (!packed) {\n    CHECK(name);\n    path->append(\"%s/%s.%zd.%s\", coverage_dir, name, internal_getpid(),\n                extension);\n  } else {\n    if (!name)\n      path->append(\"%s/%zd.%s.packed\", coverage_dir, internal_getpid(),\n                  extension);\n    else\n      path->append(\"%s/%s.%s.packed\", coverage_dir, name, extension);\n  }\n  error_t err;\n  fd_t fd = OpenFile(path->data(), WrOnly, &err);\n  if (fd == kInvalidFd)\n    Report(\"SanitizerCoverage: failed to open %s for writing (reason: %d)\\n\",\n           path->data(), err);\n  return fd;\n}\n\n// Dump trace PCs and trace events into two separate files.\nvoid CoverageData::DumpTrace() {\n  uptr max_idx = tr_event_pointer - tr_event_array;\n  if (!max_idx) return;\n  auto sym = Symbolizer::GetOrInit();\n  if (!sym)\n    return;\n  InternalScopedString out(32 << 20);\n  for (uptr i = 0, n = size(); i < n; i++) {\n    const char *module_name = \"<unknown>\";\n    uptr module_address = 0;\n    sym->GetModuleNameAndOffsetForPC(UnbundlePc(pc_array[i]), &module_name,\n                                     &module_address);\n    out.append(\"%s 0x%zx\\n\", module_name, module_address);\n  }\n  InternalScopedString path(kMaxPathLength);\n  fd_t fd = CovOpenFile(&path, false, \"trace-points\");\n  if (fd == kInvalidFd) return;\n  WriteToFile(fd, out.data(), out.length());\n  CloseFile(fd);\n\n  fd = CovOpenFile(&path, false, \"trace-compunits\");\n  if (fd == kInvalidFd) return;\n  out.clear();\n  for (uptr i = 0; i < comp_unit_name_vec.size(); i++)\n    out.append(\"%s\\n\", comp_unit_name_vec[i].copied_module_name);\n  WriteToFile(fd, out.data(), out.length());\n  CloseFile(fd);\n\n  fd = CovOpenFile(&path, false, \"trace-events\");\n  if (fd == kInvalidFd) return;\n  uptr bytes_to_write = max_idx * sizeof(tr_event_array[0]);\n  u8 *event_bytes = reinterpret_cast<u8*>(tr_event_array);\n  // The trace file could be huge, and may not be written with a single syscall.\n  while (bytes_to_write) {\n    uptr actually_written;\n    if (WriteToFile(fd, event_bytes, bytes_to_write, &actually_written) &&\n        actually_written <= bytes_to_write) {\n      bytes_to_write -= actually_written;\n      event_bytes += actually_written;\n    } else {\n      break;\n    }\n  }\n  CloseFile(fd);\n  VReport(1, \" CovDump: Trace: %zd PCs written\\n\", size());\n  VReport(1, \" CovDump: Trace: %zd Events written\\n\", max_idx);\n}\n\n// This function dumps the caller=>callee pairs into a file as a sequence of\n// lines like \"module_name offset\".\nvoid CoverageData::DumpCallerCalleePairs() {\n  uptr max_idx = atomic_load(&cc_array_index, memory_order_relaxed);\n  if (!max_idx) return;\n  auto sym = Symbolizer::GetOrInit();\n  if (!sym)\n    return;\n  InternalScopedString out(32 << 20);\n  uptr total = 0;\n  for (uptr i = 0; i < max_idx; i++) {\n    uptr *cc_cache = cc_array[i];\n    CHECK(cc_cache);\n    uptr caller = cc_cache[0];\n    uptr n_callees = cc_cache[1];\n    const char *caller_module_name = \"<unknown>\";\n    uptr caller_module_address = 0;\n    sym->GetModuleNameAndOffsetForPC(caller, &caller_module_name,\n                                     &caller_module_address);\n    for (uptr j = 2; j < n_callees; j++) {\n      uptr callee = cc_cache[j];\n      if (!callee) break;\n      total++;\n      const char *callee_module_name = \"<unknown>\";\n      uptr callee_module_address = 0;\n      sym->GetModuleNameAndOffsetForPC(callee, &callee_module_name,\n                                       &callee_module_address);\n      out.append(\"%s 0x%zx\\n%s 0x%zx\\n\", caller_module_name,\n                 caller_module_address, callee_module_name,\n                 callee_module_address);\n    }\n  }\n  InternalScopedString path(kMaxPathLength);\n  fd_t fd = CovOpenFile(&path, false, \"caller-callee\");\n  if (fd == kInvalidFd) return;\n  WriteToFile(fd, out.data(), out.length());\n  CloseFile(fd);\n  VReport(1, \" CovDump: %zd caller-callee pairs written\\n\", total);\n}\n\n// Record the current PC into the event buffer.\n// Every event is a u32 value (index in tr_pc_array_index) so we compute\n// it once and then cache in the provided 'cache' storage.\n//\n// This function will eventually be inlined by the compiler.\nvoid CoverageData::TraceBasicBlock(u32 *id) {\n  // Will trap here if\n  //  1. coverage is not enabled at run-time.\n  //  2. The array tr_event_array is full.\n  *tr_event_pointer = *id - 1;\n  tr_event_pointer++;\n}\n\nvoid CoverageData::DumpCounters() {\n  if (!common_flags()->coverage_counters) return;\n  uptr n = coverage_data.GetNumberOf8bitCounters();\n  if (!n) return;\n  InternalScopedBuffer<u8> bitset(n);\n  coverage_data.Update8bitCounterBitsetAndClearCounters(bitset.data());\n  InternalScopedString path(kMaxPathLength);\n\n  for (uptr m = 0; m < module_name_vec.size(); m++) {\n    auto r = module_name_vec[m];\n    CHECK(r.copied_module_name);\n    CHECK_LE(r.beg, r.end);\n    CHECK_LE(r.end, size());\n    const char *base_name = StripModuleName(r.copied_module_name);\n    fd_t fd =\n        CovOpenFile(&path, /* packed */ false, base_name, \"counters-sancov\");\n    if (fd == kInvalidFd) return;\n    WriteToFile(fd, bitset.data() + r.beg, r.end - r.beg);\n    CloseFile(fd);\n    VReport(1, \" CovDump: %zd counters written for '%s'\\n\", r.end - r.beg,\n            base_name);\n  }\n}\n\nvoid CoverageData::DumpAsBitSet() {\n  if (!common_flags()->coverage_bitset) return;\n  if (!size()) return;\n  InternalScopedBuffer<char> out(size());\n  InternalScopedString path(kMaxPathLength);\n  for (uptr m = 0; m < module_name_vec.size(); m++) {\n    uptr n_set_bits = 0;\n    auto r = module_name_vec[m];\n    CHECK(r.copied_module_name);\n    CHECK_LE(r.beg, r.end);\n    CHECK_LE(r.end, size());\n    for (uptr i = r.beg; i < r.end; i++) {\n      uptr pc = UnbundlePc(pc_array[i]);\n      out[i] = pc ? '1' : '0';\n      if (pc)\n        n_set_bits++;\n    }\n    const char *base_name = StripModuleName(r.copied_module_name);\n    fd_t fd = CovOpenFile(&path, /* packed */false, base_name, \"bitset-sancov\");\n    if (fd == kInvalidFd) return;\n    WriteToFile(fd, out.data() + r.beg, r.end - r.beg);\n    CloseFile(fd);\n    VReport(1,\n            \" CovDump: bitset of %zd bits written for '%s', %zd bits are set\\n\",\n            r.end - r.beg, base_name, n_set_bits);\n  }\n}\n\nvoid CoverageData::DumpOffsets() {\n  auto sym = Symbolizer::GetOrInit();\n  if (!common_flags()->coverage_pcs) return;\n  CHECK_NE(sym, nullptr);\n  InternalMmapVector<uptr> offsets(0);\n  InternalScopedString path(kMaxPathLength);\n  for (uptr m = 0; m < module_name_vec.size(); m++) {\n    offsets.clear();\n    uptr num_words_for_magic = SANITIZER_WORDSIZE == 64 ? 1 : 2;\n    for (uptr i = 0; i < num_words_for_magic; i++)\n      offsets.push_back(0);\n    auto r = module_name_vec[m];\n    CHECK(r.copied_module_name);\n    CHECK_LE(r.beg, r.end);\n    CHECK_LE(r.end, size());\n    for (uptr i = r.beg; i < r.end; i++) {\n      uptr pc = UnbundlePc(pc_array[i]);\n      uptr counter = UnbundleCounter(pc_array[i]);\n      if (!pc) continue; // Not visited.\n      uptr offset = 0;\n      sym->GetModuleNameAndOffsetForPC(pc, nullptr, &offset);\n      offsets.push_back(BundlePcAndCounter(offset, counter));\n    }\n\n    CHECK_GE(offsets.size(), num_words_for_magic);\n    SortArray(offsets.data(), offsets.size());\n    for (uptr i = 0; i < offsets.size(); i++)\n      offsets[i] = UnbundlePc(offsets[i]);\n\n    uptr num_offsets = offsets.size() - num_words_for_magic;\n    u64 *magic_p = reinterpret_cast<u64*>(offsets.data());\n    CHECK_EQ(*magic_p, 0ULL);\n    // FIXME: we may want to write 32-bit offsets even in 64-mode\n    // if all the offsets are small enough.\n    *magic_p = SANITIZER_WORDSIZE == 64 ? kMagic64 : kMagic32;\n\n    const char *module_name = StripModuleName(r.copied_module_name);\n    if (cov_sandboxed) {\n      if (cov_fd != kInvalidFd) {\n        CovWritePacked(internal_getpid(), module_name, offsets.data(),\n                       offsets.size() * sizeof(offsets[0]));\n        VReport(1, \" CovDump: %zd PCs written to packed file\\n\", num_offsets);\n      }\n    } else {\n      // One file per module per process.\n      fd_t fd = CovOpenFile(&path, false /* packed */, module_name);\n      if (fd == kInvalidFd) continue;\n      WriteToFile(fd, offsets.data(), offsets.size() * sizeof(offsets[0]));\n      CloseFile(fd);\n      VReport(1, \" CovDump: %s: %zd PCs written\\n\", path.data(), num_offsets);\n    }\n  }\n  if (cov_fd != kInvalidFd)\n    CloseFile(cov_fd);\n}\n\nvoid CoverageData::DumpAll() {\n  if (!coverage_enabled || common_flags()->coverage_direct) return;\n  if (atomic_fetch_add(&dump_once_guard, 1, memory_order_relaxed))\n    return;\n  DumpAsBitSet();\n  DumpCounters();\n  DumpTrace();\n  DumpOffsets();\n  DumpCallerCalleePairs();\n}\n\nvoid CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {\n  if (!args) return;\n  if (!coverage_enabled) return;\n  cov_sandboxed = args->coverage_sandboxed;\n  if (!cov_sandboxed) return;\n  cov_max_block_size = args->coverage_max_block_size;\n  if (args->coverage_fd >= 0) {\n    cov_fd = (fd_t)args->coverage_fd;\n  } else {\n    InternalScopedString path(kMaxPathLength);\n    // Pre-open the file now. The sandbox won't allow us to do it later.\n    cov_fd = CovOpenFile(&path, true /* packed */, nullptr);\n  }\n}\n\nfd_t MaybeOpenCovFile(const char *name) {\n  CHECK(name);\n  if (!coverage_enabled) return kInvalidFd;\n  InternalScopedString path(kMaxPathLength);\n  return CovOpenFile(&path, true /* packed */, name);\n}\n\nvoid CovBeforeFork() {\n  coverage_data.BeforeFork();\n}\n\nvoid CovAfterFork(int child_pid) {\n  coverage_data.AfterFork(child_pid);\n}\n\nstatic void MaybeDumpCoverage() {\n  if (common_flags()->coverage)\n    __sanitizer_cov_dump();\n}\n\nvoid InitializeCoverage(bool enabled, const char *dir) {\n  if (coverage_enabled)\n    return;  // May happen if two sanitizer enable coverage in the same process.\n  coverage_enabled = enabled;\n  coverage_dir = dir;\n  coverage_data.Init();\n  if (enabled) coverage_data.Enable();\n  if (!common_flags()->coverage_direct) Atexit(__sanitizer_cov_dump);\n  AddDieCallback(MaybeDumpCoverage);\n}\n\nvoid ReInitializeCoverage(bool enabled, const char *dir) {\n  coverage_enabled = enabled;\n  coverage_dir = dir;\n  coverage_data.ReInit();\n}\n\nvoid CoverageUpdateMapping() {\n  if (coverage_enabled)\n    CovUpdateMapping(coverage_dir);\n}\n\n} // namespace __sanitizer\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov(u32 *guard) {\n  coverage_data.Add(StackTrace::GetPreviousInstructionPc(GET_CALLER_PC()),\n                    guard);\n}\nSANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_with_check(u32 *guard) {\n  atomic_uint32_t *atomic_guard = reinterpret_cast<atomic_uint32_t*>(guard);\n  if (static_cast<s32>(\n          __sanitizer::atomic_load(atomic_guard, memory_order_relaxed)) < 0)\n    __sanitizer_cov(guard);\n}\nSANITIZER_INTERFACE_ATTRIBUTE void\n__sanitizer_cov_indir_call16(uptr callee, uptr callee_cache16[]) {\n  coverage_data.IndirCall(StackTrace::GetPreviousInstructionPc(GET_CALLER_PC()),\n                          callee, callee_cache16, 16);\n}\nSANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_init() {\n  coverage_enabled = true;\n  coverage_dir = common_flags()->coverage_dir;\n  coverage_data.Init();\n}\nSANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump() {\n  coverage_data.DumpAll();\n}\nSANITIZER_INTERFACE_ATTRIBUTE void\n__sanitizer_cov_module_init(s32 *guards, uptr npcs, u8 *counters,\n                            const char *comp_unit_name) {\n  coverage_data.InitializeGuards(guards, npcs, comp_unit_name, GET_CALLER_PC());\n  coverage_data.InitializeCounters(counters, npcs);\n  if (!common_flags()->coverage_direct) return;\n  if (SANITIZER_ANDROID && coverage_enabled) {\n    // dlopen/dlclose interceptors do not work on Android, so we rely on\n    // Extend() calls to update .sancov.map.\n    CovUpdateMapping(coverage_dir, GET_CALLER_PC());\n  }\n  coverage_data.Extend(npcs);\n}\nSANITIZER_INTERFACE_ATTRIBUTE\nsptr __sanitizer_maybe_open_cov_file(const char *name) {\n  return (sptr)MaybeOpenCovFile(name);\n}\nSANITIZER_INTERFACE_ATTRIBUTE\nuptr __sanitizer_get_total_unique_coverage() {\n  return atomic_load(&coverage_counter, memory_order_relaxed);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nuptr __sanitizer_get_total_unique_caller_callee_pairs() {\n  return atomic_load(&caller_callee_counter, memory_order_relaxed);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_cov_trace_func_enter(u32 *id) {\n  __sanitizer_cov_with_check(id);\n  coverage_data.TraceBasicBlock(id);\n}\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_cov_trace_basic_block(u32 *id) {\n  __sanitizer_cov_with_check(id);\n  coverage_data.TraceBasicBlock(id);\n}\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_reset_coverage() {\n  ResetGlobalCounters();\n  coverage_data.ReinitializeGuards();\n  internal_bzero_aligned16(\n      coverage_data.data(),\n      RoundUpTo(coverage_data.size() * sizeof(coverage_data.data()[0]), 16));\n}\nSANITIZER_INTERFACE_ATTRIBUTE\nuptr __sanitizer_get_coverage_guards(uptr **data) {\n  *data = coverage_data.data();\n  return coverage_data.size();\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nuptr __sanitizer_get_number_of_counters() {\n  return coverage_data.GetNumberOf8bitCounters();\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nuptr __sanitizer_update_counter_bitset_and_clear_counters(u8 *bitset) {\n  return coverage_data.Update8bitCounterBitsetAndClearCounters(bitset);\n}\n// Default empty implementations (weak). Users should redefine them.\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nvoid __sanitizer_cov_trace_cmp() {}\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nvoid __sanitizer_cov_trace_switch() {}\n} // extern \"C\"\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc",
    "content": "//===-- sanitizer_coverage_mapping.cc -------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Mmap-based implementation of sanitizer coverage.\n//\n// This is part of the implementation of code coverage that does not require\n// __sanitizer_cov_dump() call. Data is stored in 2 files per process.\n//\n// $pid.sancov.map describes process memory layout in the following text-based\n// format:\n// <pointer size in bits>  // 1 line, 32 or 64\n// <mapping start> <mapping end> <base address> <dso name> // repeated\n// ...\n// Mapping lines are NOT sorted. This file is updated every time memory layout\n// is changed (i.e. in dlopen() and dlclose() interceptors).\n//\n// $pid.sancov.raw is a binary dump of PC values, sizeof(uptr) each. Again, not\n// sorted. This file is extended by 64Kb at a time and mapped into memory. It\n// contains one or more 0 words at the end, up to the next 64Kb aligned offset.\n//\n// To convert these 2 files to the usual .sancov format, run sancov.py rawunpack\n// $pid.sancov.raw.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_allocator_internal.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_procmaps.h\"\n\nnamespace __sanitizer {\n\nstatic const uptr kMaxTextSize = 64 * 1024;\n\nstruct CachedMapping {\n public:\n  bool NeedsUpdate(uptr pc) {\n    int new_pid = internal_getpid();\n    if (last_pid == new_pid && pc && pc >= last_range_start &&\n        pc < last_range_end)\n      return false;\n    last_pid = new_pid;\n    return true;\n  }\n\n  void SetModuleRange(uptr start, uptr end) {\n    last_range_start = start;\n    last_range_end = end;\n  }\n\n private:\n  uptr last_range_start, last_range_end;\n  int last_pid;\n};\n\nstatic CachedMapping cached_mapping;\nstatic StaticSpinMutex mapping_mu;\n\nvoid CovUpdateMapping(const char *coverage_dir, uptr caller_pc) {\n  if (!common_flags()->coverage_direct) return;\n\n  SpinMutexLock l(&mapping_mu);\n\n  if (!cached_mapping.NeedsUpdate(caller_pc))\n    return;\n\n  InternalScopedString text(kMaxTextSize);\n\n  {\n    InternalScopedBuffer<LoadedModule> modules(kMaxNumberOfModules);\n    CHECK(modules.data());\n    int n_modules = GetListOfModules(modules.data(), kMaxNumberOfModules,\n                                     /* filter */ nullptr);\n\n    text.append(\"%d\\n\", sizeof(uptr) * 8);\n    for (int i = 0; i < n_modules; ++i) {\n      const char *module_name = StripModuleName(modules[i].full_name());\n      uptr base = modules[i].base_address();\n      for (auto iter = modules[i].ranges(); iter.hasNext();) {\n        const auto *range = iter.next();\n        if (range->executable) {\n          uptr start = range->beg;\n          uptr end = range->end;\n          text.append(\"%zx %zx %zx %s\\n\", start, end, base, module_name);\n          if (caller_pc && caller_pc >= start && caller_pc < end)\n            cached_mapping.SetModuleRange(start, end);\n        }\n      }\n      modules[i].clear();\n    }\n  }\n\n  error_t err;\n  InternalScopedString tmp_path(64 + internal_strlen(coverage_dir));\n  uptr res = internal_snprintf((char *)tmp_path.data(), tmp_path.size(),\n                               \"%s/%zd.sancov.map.tmp\", coverage_dir,\n                               internal_getpid());\n  CHECK_LE(res, tmp_path.size());\n  fd_t map_fd = OpenFile(tmp_path.data(), WrOnly, &err);\n  if (map_fd == kInvalidFd) {\n    Report(\"Coverage: failed to open %s for writing: %d\\n\", tmp_path.data(),\n           err);\n    Die();\n  }\n\n  if (!WriteToFile(map_fd, text.data(), text.length(), nullptr, &err)) {\n    Printf(\"sancov.map write failed: %d\\n\", err);\n    Die();\n  }\n  CloseFile(map_fd);\n\n  InternalScopedString path(64 + internal_strlen(coverage_dir));\n  res = internal_snprintf((char *)path.data(), path.size(), \"%s/%zd.sancov.map\",\n                          coverage_dir, internal_getpid());\n  CHECK_LE(res, path.size());\n  if (!RenameFile(tmp_path.data(), path.data(), &err)) {\n    Printf(\"sancov.map rename failed: %d\\n\", err);\n    Die();\n  }\n}\n\n} // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector.h",
    "content": "//===-- sanitizer_deadlock_detector.h ---------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of Sanitizer runtime.\n// The deadlock detector maintains a directed graph of lock acquisitions.\n// When a lock event happens, the detector checks if the locks already held by\n// the current thread are reachable from the newly acquired lock.\n//\n// The detector can handle only a fixed amount of simultaneously live locks\n// (a lock is alive if it has been locked at least once and has not been\n// destroyed). When the maximal number of locks is reached the entire graph\n// is flushed and the new lock epoch is started. The node ids from the old\n// epochs can not be used with any of the detector methods except for\n// nodeBelongsToCurrentEpoch().\n//\n// FIXME: this is work in progress, nothing really works yet.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_DEADLOCK_DETECTOR_H\n#define SANITIZER_DEADLOCK_DETECTOR_H\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_bvgraph.h\"\n\nnamespace __sanitizer {\n\n// Thread-local state for DeadlockDetector.\n// It contains the locks currently held by the owning thread.\ntemplate <class BV>\nclass DeadlockDetectorTLS {\n public:\n  // No CTOR.\n  void clear() {\n    bv_.clear();\n    epoch_ = 0;\n    n_recursive_locks = 0;\n    n_all_locks_ = 0;\n  }\n\n  bool empty() const { return bv_.empty(); }\n\n  void ensureCurrentEpoch(uptr current_epoch) {\n    if (epoch_ == current_epoch) return;\n    bv_.clear();\n    epoch_ = current_epoch;\n    n_recursive_locks = 0;\n    n_all_locks_ = 0;\n  }\n\n  uptr getEpoch() const { return epoch_; }\n\n  // Returns true if this is the first (non-recursive) acquisition of this lock.\n  bool addLock(uptr lock_id, uptr current_epoch, u32 stk) {\n    // Printf(\"addLock: %zx %zx stk %u\\n\", lock_id, current_epoch, stk);\n    CHECK_EQ(epoch_, current_epoch);\n    if (!bv_.setBit(lock_id)) {\n      // The lock is already held by this thread, it must be recursive.\n      CHECK_LT(n_recursive_locks, ARRAY_SIZE(recursive_locks));\n      recursive_locks[n_recursive_locks++] = lock_id;\n      return false;\n    }\n    CHECK_LT(n_all_locks_, ARRAY_SIZE(all_locks_with_contexts_));\n    // lock_id < BV::kSize, can cast to a smaller int.\n    u32 lock_id_short = static_cast<u32>(lock_id);\n    LockWithContext l = {lock_id_short, stk};\n    all_locks_with_contexts_[n_all_locks_++] = l;\n    return true;\n  }\n\n  void removeLock(uptr lock_id) {\n    if (n_recursive_locks) {\n      for (sptr i = n_recursive_locks - 1; i >= 0; i--) {\n        if (recursive_locks[i] == lock_id) {\n          n_recursive_locks--;\n          Swap(recursive_locks[i], recursive_locks[n_recursive_locks]);\n          return;\n        }\n      }\n    }\n    // Printf(\"remLock: %zx %zx\\n\", lock_id, epoch_);\n    if (!bv_.clearBit(lock_id))\n      return;  // probably addLock happened before flush\n    if (n_all_locks_) {\n      for (sptr i = n_all_locks_ - 1; i >= 0; i--) {\n        if (all_locks_with_contexts_[i].lock == static_cast<u32>(lock_id)) {\n          Swap(all_locks_with_contexts_[i],\n               all_locks_with_contexts_[n_all_locks_ - 1]);\n          n_all_locks_--;\n          break;\n        }\n      }\n    }\n  }\n\n  u32 findLockContext(uptr lock_id) {\n    for (uptr i = 0; i < n_all_locks_; i++)\n      if (all_locks_with_contexts_[i].lock == static_cast<u32>(lock_id))\n        return all_locks_with_contexts_[i].stk;\n    return 0;\n  }\n\n  const BV &getLocks(uptr current_epoch) const {\n    CHECK_EQ(epoch_, current_epoch);\n    return bv_;\n  }\n\n  uptr getNumLocks() const { return n_all_locks_; }\n  uptr getLock(uptr idx) const { return all_locks_with_contexts_[idx].lock; }\n\n private:\n  BV bv_;\n  uptr epoch_;\n  uptr recursive_locks[64];\n  uptr n_recursive_locks;\n  struct LockWithContext {\n    u32 lock;\n    u32 stk;\n  };\n  LockWithContext all_locks_with_contexts_[64];\n  uptr n_all_locks_;\n};\n\n// DeadlockDetector.\n// For deadlock detection to work we need one global DeadlockDetector object\n// and one DeadlockDetectorTLS object per evey thread.\n// This class is not thread safe, all concurrent accesses should be guarded\n// by an external lock.\n// Most of the methods of this class are not thread-safe (i.e. should\n// be protected by an external lock) unless explicitly told otherwise.\ntemplate <class BV>\nclass DeadlockDetector {\n public:\n  typedef BV BitVector;\n\n  uptr size() const { return g_.size(); }\n\n  // No CTOR.\n  void clear() {\n    current_epoch_ = 0;\n    available_nodes_.clear();\n    recycled_nodes_.clear();\n    g_.clear();\n    n_edges_ = 0;\n  }\n\n  // Allocate new deadlock detector node.\n  // If we are out of available nodes first try to recycle some.\n  // If there is nothing to recycle, flush the graph and increment the epoch.\n  // Associate 'data' (opaque user's object) with the new node.\n  uptr newNode(uptr data) {\n    if (!available_nodes_.empty())\n      return getAvailableNode(data);\n    if (!recycled_nodes_.empty()) {\n      // Printf(\"recycling: n_edges_ %zd\\n\", n_edges_);\n      for (sptr i = n_edges_ - 1; i >= 0; i--) {\n        if (recycled_nodes_.getBit(edges_[i].from) ||\n            recycled_nodes_.getBit(edges_[i].to)) {\n          Swap(edges_[i], edges_[n_edges_ - 1]);\n          n_edges_--;\n        }\n      }\n      CHECK(available_nodes_.empty());\n      // removeEdgesFrom was called in removeNode.\n      g_.removeEdgesTo(recycled_nodes_);\n      available_nodes_.setUnion(recycled_nodes_);\n      recycled_nodes_.clear();\n      return getAvailableNode(data);\n    }\n    // We are out of vacant nodes. Flush and increment the current_epoch_.\n    current_epoch_ += size();\n    recycled_nodes_.clear();\n    available_nodes_.setAll();\n    g_.clear();\n    n_edges_ = 0;\n    return getAvailableNode(data);\n  }\n\n  // Get data associated with the node created by newNode().\n  uptr getData(uptr node) const { return data_[nodeToIndex(node)]; }\n\n  bool nodeBelongsToCurrentEpoch(uptr node) {\n    return node && (node / size() * size()) == current_epoch_;\n  }\n\n  void removeNode(uptr node) {\n    uptr idx = nodeToIndex(node);\n    CHECK(!available_nodes_.getBit(idx));\n    CHECK(recycled_nodes_.setBit(idx));\n    g_.removeEdgesFrom(idx);\n  }\n\n  void ensureCurrentEpoch(DeadlockDetectorTLS<BV> *dtls) {\n    dtls->ensureCurrentEpoch(current_epoch_);\n  }\n\n  // Returns true if there is a cycle in the graph after this lock event.\n  // Ideally should be called before the lock is acquired so that we can\n  // report a deadlock before a real deadlock happens.\n  bool onLockBefore(DeadlockDetectorTLS<BV> *dtls, uptr cur_node) {\n    ensureCurrentEpoch(dtls);\n    uptr cur_idx = nodeToIndex(cur_node);\n    return g_.isReachable(cur_idx, dtls->getLocks(current_epoch_));\n  }\n\n  u32 findLockContext(DeadlockDetectorTLS<BV> *dtls, uptr node) {\n    return dtls->findLockContext(nodeToIndex(node));\n  }\n\n  // Add cur_node to the set of locks held currently by dtls.\n  void onLockAfter(DeadlockDetectorTLS<BV> *dtls, uptr cur_node, u32 stk = 0) {\n    ensureCurrentEpoch(dtls);\n    uptr cur_idx = nodeToIndex(cur_node);\n    dtls->addLock(cur_idx, current_epoch_, stk);\n  }\n\n  // Experimental *racy* fast path function.\n  // Returns true if all edges from the currently held locks to cur_node exist.\n  bool hasAllEdges(DeadlockDetectorTLS<BV> *dtls, uptr cur_node) {\n    uptr local_epoch = dtls->getEpoch();\n    // Read from current_epoch_ is racy.\n    if (cur_node && local_epoch == current_epoch_ &&\n        local_epoch == nodeToEpoch(cur_node)) {\n      uptr cur_idx = nodeToIndexUnchecked(cur_node);\n      for (uptr i = 0, n = dtls->getNumLocks(); i < n; i++) {\n        if (!g_.hasEdge(dtls->getLock(i), cur_idx))\n          return false;\n      }\n      return true;\n    }\n    return false;\n  }\n\n  // Adds edges from currently held locks to cur_node,\n  // returns the number of added edges, and puts the sources of added edges\n  // into added_edges[].\n  // Should be called before onLockAfter.\n  uptr addEdges(DeadlockDetectorTLS<BV> *dtls, uptr cur_node, u32 stk,\n                int unique_tid) {\n    ensureCurrentEpoch(dtls);\n    uptr cur_idx = nodeToIndex(cur_node);\n    uptr added_edges[40];\n    uptr n_added_edges = g_.addEdges(dtls->getLocks(current_epoch_), cur_idx,\n                                     added_edges, ARRAY_SIZE(added_edges));\n    for (uptr i = 0; i < n_added_edges; i++) {\n      if (n_edges_ < ARRAY_SIZE(edges_)) {\n        Edge e = {(u16)added_edges[i], (u16)cur_idx,\n                  dtls->findLockContext(added_edges[i]), stk,\n                  unique_tid};\n        edges_[n_edges_++] = e;\n      }\n      // Printf(\"Edge%zd: %u %zd=>%zd in T%d\\n\",\n      //        n_edges_, stk, added_edges[i], cur_idx, unique_tid);\n    }\n    return n_added_edges;\n  }\n\n  bool findEdge(uptr from_node, uptr to_node, u32 *stk_from, u32 *stk_to,\n                int *unique_tid) {\n    uptr from_idx = nodeToIndex(from_node);\n    uptr to_idx = nodeToIndex(to_node);\n    for (uptr i = 0; i < n_edges_; i++) {\n      if (edges_[i].from == from_idx && edges_[i].to == to_idx) {\n        *stk_from = edges_[i].stk_from;\n        *stk_to = edges_[i].stk_to;\n        *unique_tid = edges_[i].unique_tid;\n        return true;\n      }\n    }\n    return false;\n  }\n\n  // Test-only function. Handles the before/after lock events,\n  // returns true if there is a cycle.\n  bool onLock(DeadlockDetectorTLS<BV> *dtls, uptr cur_node, u32 stk = 0) {\n    ensureCurrentEpoch(dtls);\n    bool is_reachable = !isHeld(dtls, cur_node) && onLockBefore(dtls, cur_node);\n    addEdges(dtls, cur_node, stk, 0);\n    onLockAfter(dtls, cur_node, stk);\n    return is_reachable;\n  }\n\n  // Handles the try_lock event, returns false.\n  // When a try_lock event happens (i.e. a try_lock call succeeds) we need\n  // to add this lock to the currently held locks, but we should not try to\n  // change the lock graph or to detect a cycle.  We may want to investigate\n  // whether a more aggressive strategy is possible for try_lock.\n  bool onTryLock(DeadlockDetectorTLS<BV> *dtls, uptr cur_node, u32 stk = 0) {\n    ensureCurrentEpoch(dtls);\n    uptr cur_idx = nodeToIndex(cur_node);\n    dtls->addLock(cur_idx, current_epoch_, stk);\n    return false;\n  }\n\n  // Returns true iff dtls is empty (no locks are currently held) and we can\n  // add the node to the currently held locks w/o chanding the global state.\n  // This operation is thread-safe as it only touches the dtls.\n  bool onFirstLock(DeadlockDetectorTLS<BV> *dtls, uptr node, u32 stk = 0) {\n    if (!dtls->empty()) return false;\n    if (dtls->getEpoch() && dtls->getEpoch() == nodeToEpoch(node)) {\n      dtls->addLock(nodeToIndexUnchecked(node), nodeToEpoch(node), stk);\n      return true;\n    }\n    return false;\n  }\n\n  // Finds a path between the lock 'cur_node' (currently not held in dtls)\n  // and some currently held lock, returns the length of the path\n  // or 0 on failure.\n  uptr findPathToLock(DeadlockDetectorTLS<BV> *dtls, uptr cur_node, uptr *path,\n                      uptr path_size) {\n    tmp_bv_.copyFrom(dtls->getLocks(current_epoch_));\n    uptr idx = nodeToIndex(cur_node);\n    CHECK(!tmp_bv_.getBit(idx));\n    uptr res = g_.findShortestPath(idx, tmp_bv_, path, path_size);\n    for (uptr i = 0; i < res; i++)\n      path[i] = indexToNode(path[i]);\n    if (res)\n      CHECK_EQ(path[0], cur_node);\n    return res;\n  }\n\n  // Handle the unlock event.\n  // This operation is thread-safe as it only touches the dtls.\n  void onUnlock(DeadlockDetectorTLS<BV> *dtls, uptr node) {\n    if (dtls->getEpoch() == nodeToEpoch(node))\n      dtls->removeLock(nodeToIndexUnchecked(node));\n  }\n\n  // Tries to handle the lock event w/o writing to global state.\n  // Returns true on success.\n  // This operation is thread-safe as it only touches the dtls\n  // (modulo racy nature of hasAllEdges).\n  bool onLockFast(DeadlockDetectorTLS<BV> *dtls, uptr node, u32 stk = 0) {\n    if (hasAllEdges(dtls, node)) {\n      dtls->addLock(nodeToIndexUnchecked(node), nodeToEpoch(node), stk);\n      return true;\n    }\n    return false;\n  }\n\n  bool isHeld(DeadlockDetectorTLS<BV> *dtls, uptr node) const {\n    return dtls->getLocks(current_epoch_).getBit(nodeToIndex(node));\n  }\n\n  uptr testOnlyGetEpoch() const { return current_epoch_; }\n  bool testOnlyHasEdge(uptr l1, uptr l2) {\n    return g_.hasEdge(nodeToIndex(l1), nodeToIndex(l2));\n  }\n  // idx1 and idx2 are raw indices to g_, not lock IDs.\n  bool testOnlyHasEdgeRaw(uptr idx1, uptr idx2) {\n    return g_.hasEdge(idx1, idx2);\n  }\n\n  void Print() {\n    for (uptr from = 0; from < size(); from++)\n      for (uptr to = 0; to < size(); to++)\n        if (g_.hasEdge(from, to))\n          Printf(\"  %zx => %zx\\n\", from, to);\n  }\n\n private:\n  void check_idx(uptr idx) const { CHECK_LT(idx, size()); }\n\n  void check_node(uptr node) const {\n    CHECK_GE(node, size());\n    CHECK_EQ(current_epoch_, nodeToEpoch(node));\n  }\n\n  uptr indexToNode(uptr idx) const {\n    check_idx(idx);\n    return idx + current_epoch_;\n  }\n\n  uptr nodeToIndexUnchecked(uptr node) const { return node % size(); }\n\n  uptr nodeToIndex(uptr node) const {\n    check_node(node);\n    return nodeToIndexUnchecked(node);\n  }\n\n  uptr nodeToEpoch(uptr node) const { return node / size() * size(); }\n\n  uptr getAvailableNode(uptr data) {\n    uptr idx = available_nodes_.getAndClearFirstOne();\n    data_[idx] = data;\n    return indexToNode(idx);\n  }\n\n  struct Edge {\n    u16 from;\n    u16 to;\n    u32 stk_from;\n    u32 stk_to;\n    int unique_tid;\n  };\n\n  uptr current_epoch_;\n  BV available_nodes_;\n  BV recycled_nodes_;\n  BV tmp_bv_;\n  BVGraph<BV> g_;\n  uptr data_[BV::kSize];\n  Edge edges_[BV::kSize * 32];\n  uptr n_edges_;\n};\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_DEADLOCK_DETECTOR_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector1.cc",
    "content": "//===-- sanitizer_deadlock_detector1.cc -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Deadlock detector implementation based on NxN adjacency bit matrix.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_deadlock_detector_interface.h\"\n#include \"sanitizer_deadlock_detector.h\"\n#include \"sanitizer_allocator_internal.h\"\n#include \"sanitizer_placement_new.h\"\n#include \"sanitizer_mutex.h\"\n\n#if SANITIZER_DEADLOCK_DETECTOR_VERSION == 1\n\nnamespace __sanitizer {\n\ntypedef TwoLevelBitVector<> DDBV;  // DeadlockDetector's bit vector.\n\nstruct DDPhysicalThread {\n};\n\nstruct DDLogicalThread {\n  u64 ctx;\n  DeadlockDetectorTLS<DDBV> dd;\n  DDReport rep;\n  bool report_pending;\n};\n\nstruct DD : public DDetector {\n  SpinMutex mtx;\n  DeadlockDetector<DDBV> dd;\n  DDFlags flags;\n\n  explicit DD(const DDFlags *flags);\n\n  DDPhysicalThread *CreatePhysicalThread() override;\n  void DestroyPhysicalThread(DDPhysicalThread *pt) override;\n\n  DDLogicalThread *CreateLogicalThread(u64 ctx) override;\n  void DestroyLogicalThread(DDLogicalThread *lt) override;\n\n  void MutexInit(DDCallback *cb, DDMutex *m) override;\n  void MutexBeforeLock(DDCallback *cb, DDMutex *m, bool wlock) override;\n  void MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock,\n                      bool trylock) override;\n  void MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) override;\n  void MutexDestroy(DDCallback *cb, DDMutex *m) override;\n\n  DDReport *GetReport(DDCallback *cb) override;\n\n  void MutexEnsureID(DDLogicalThread *lt, DDMutex *m);\n  void ReportDeadlock(DDCallback *cb, DDMutex *m);\n};\n\nDDetector *DDetector::Create(const DDFlags *flags) {\n  (void)flags;\n  void *mem = MmapOrDie(sizeof(DD), \"deadlock detector\");\n  return new(mem) DD(flags);\n}\n\nDD::DD(const DDFlags *flags)\n    : flags(*flags) {\n  dd.clear();\n}\n\nDDPhysicalThread* DD::CreatePhysicalThread() {\n  return nullptr;\n}\n\nvoid DD::DestroyPhysicalThread(DDPhysicalThread *pt) {\n}\n\nDDLogicalThread* DD::CreateLogicalThread(u64 ctx) {\n  DDLogicalThread *lt = (DDLogicalThread*)InternalAlloc(sizeof(*lt));\n  lt->ctx = ctx;\n  lt->dd.clear();\n  lt->report_pending = false;\n  return lt;\n}\n\nvoid DD::DestroyLogicalThread(DDLogicalThread *lt) {\n  lt->~DDLogicalThread();\n  InternalFree(lt);\n}\n\nvoid DD::MutexInit(DDCallback *cb, DDMutex *m) {\n  m->id = 0;\n  m->stk = cb->Unwind();\n}\n\nvoid DD::MutexEnsureID(DDLogicalThread *lt, DDMutex *m) {\n  if (!dd.nodeBelongsToCurrentEpoch(m->id))\n    m->id = dd.newNode(reinterpret_cast<uptr>(m));\n  dd.ensureCurrentEpoch(&lt->dd);\n}\n\nvoid DD::MutexBeforeLock(DDCallback *cb,\n    DDMutex *m, bool wlock) {\n  DDLogicalThread *lt = cb->lt;\n  if (lt->dd.empty()) return;  // This will be the first lock held by lt.\n  if (dd.hasAllEdges(&lt->dd, m->id)) return;  // We already have all edges.\n  SpinMutexLock lk(&mtx);\n  MutexEnsureID(lt, m);\n  if (dd.isHeld(&lt->dd, m->id))\n    return;  // FIXME: allow this only for recursive locks.\n  if (dd.onLockBefore(&lt->dd, m->id)) {\n    // Actually add this edge now so that we have all the stack traces.\n    dd.addEdges(&lt->dd, m->id, cb->Unwind(), cb->UniqueTid());\n    ReportDeadlock(cb, m);\n  }\n}\n\nvoid DD::ReportDeadlock(DDCallback *cb, DDMutex *m) {\n  DDLogicalThread *lt = cb->lt;\n  uptr path[10];\n  uptr len = dd.findPathToLock(&lt->dd, m->id, path, ARRAY_SIZE(path));\n  CHECK_GT(len, 0U);  // Hm.. cycle of 10 locks? I'd like to see that.\n  CHECK_EQ(m->id, path[0]);\n  lt->report_pending = true;\n  DDReport *rep = &lt->rep;\n  rep->n = len;\n  for (uptr i = 0; i < len; i++) {\n    uptr from = path[i];\n    uptr to = path[(i + 1) % len];\n    DDMutex *m0 = (DDMutex*)dd.getData(from);\n    DDMutex *m1 = (DDMutex*)dd.getData(to);\n\n    u32 stk_from = -1U, stk_to = -1U;\n    int unique_tid = 0;\n    dd.findEdge(from, to, &stk_from, &stk_to, &unique_tid);\n    // Printf(\"Edge: %zd=>%zd: %u/%u T%d\\n\", from, to, stk_from, stk_to,\n    //    unique_tid);\n    rep->loop[i].thr_ctx = unique_tid;\n    rep->loop[i].mtx_ctx0 = m0->ctx;\n    rep->loop[i].mtx_ctx1 = m1->ctx;\n    rep->loop[i].stk[0] = stk_to;\n    rep->loop[i].stk[1] = stk_from;\n  }\n}\n\nvoid DD::MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock, bool trylock) {\n  DDLogicalThread *lt = cb->lt;\n  u32 stk = 0;\n  if (flags.second_deadlock_stack)\n    stk = cb->Unwind();\n  // Printf(\"T%p MutexLock:   %zx stk %u\\n\", lt, m->id, stk);\n  if (dd.onFirstLock(&lt->dd, m->id, stk))\n    return;\n  if (dd.onLockFast(&lt->dd, m->id, stk))\n    return;\n\n  SpinMutexLock lk(&mtx);\n  MutexEnsureID(lt, m);\n  if (wlock)  // Only a recursive rlock may be held.\n    CHECK(!dd.isHeld(&lt->dd, m->id));\n  if (!trylock)\n    dd.addEdges(&lt->dd, m->id, stk ? stk : cb->Unwind(), cb->UniqueTid());\n  dd.onLockAfter(&lt->dd, m->id, stk);\n}\n\nvoid DD::MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) {\n  // Printf(\"T%p MutexUnLock: %zx\\n\", cb->lt, m->id);\n  dd.onUnlock(&cb->lt->dd, m->id);\n}\n\nvoid DD::MutexDestroy(DDCallback *cb,\n    DDMutex *m) {\n  if (!m->id) return;\n  SpinMutexLock lk(&mtx);\n  if (dd.nodeBelongsToCurrentEpoch(m->id))\n    dd.removeNode(m->id);\n  m->id = 0;\n}\n\nDDReport *DD::GetReport(DDCallback *cb) {\n  if (!cb->lt->report_pending)\n    return nullptr;\n  cb->lt->report_pending = false;\n  return &cb->lt->rep;\n}\n\n} // namespace __sanitizer\n#endif // #if SANITIZER_DEADLOCK_DETECTOR_VERSION == 1\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector2.cc",
    "content": "//===-- sanitizer_deadlock_detector2.cc -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Deadlock detector implementation based on adjacency lists.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_deadlock_detector_interface.h\"\n#include \"sanitizer_common.h\"\n#include \"sanitizer_allocator_internal.h\"\n#include \"sanitizer_placement_new.h\"\n#include \"sanitizer_mutex.h\"\n\n#if SANITIZER_DEADLOCK_DETECTOR_VERSION == 2\n\nnamespace __sanitizer {\n\nconst int kMaxNesting = 64;\nconst u32 kNoId = -1;\nconst u32 kEndId = -2;\nconst int kMaxLink = 8;\nconst int kL1Size = 1024;\nconst int kL2Size = 1024;\nconst int kMaxMutex = kL1Size * kL2Size;\n\nstruct Id {\n  u32 id;\n  u32 seq;\n\n  explicit Id(u32 id = 0, u32 seq = 0)\n      : id(id)\n      , seq(seq) {\n  }\n};\n\nstruct Link {\n  u32 id;\n  u32 seq;\n  u32 tid;\n  u32 stk0;\n  u32 stk1;\n\n  explicit Link(u32 id = 0, u32 seq = 0, u32 tid = 0, u32 s0 = 0, u32 s1 = 0)\n      : id(id)\n      , seq(seq)\n      , tid(tid)\n      , stk0(s0)\n      , stk1(s1) {\n  }\n};\n\nstruct DDPhysicalThread {\n  DDReport rep;\n  bool report_pending;\n  bool visited[kMaxMutex];\n  Link pending[kMaxMutex];\n  Link path[kMaxMutex];\n};\n\nstruct ThreadMutex {\n  u32 id;\n  u32 stk;\n};\n\nstruct DDLogicalThread {\n  u64         ctx;\n  ThreadMutex locked[kMaxNesting];\n  int         nlocked;\n};\n\nstruct Mutex {\n  StaticSpinMutex mtx;\n  u32 seq;\n  int nlink;\n  Link link[kMaxLink];\n};\n\nstruct DD : public DDetector {\n  explicit DD(const DDFlags *flags);\n\n  DDPhysicalThread* CreatePhysicalThread();\n  void DestroyPhysicalThread(DDPhysicalThread *pt);\n\n  DDLogicalThread* CreateLogicalThread(u64 ctx);\n  void DestroyLogicalThread(DDLogicalThread *lt);\n\n  void MutexInit(DDCallback *cb, DDMutex *m);\n  void MutexBeforeLock(DDCallback *cb, DDMutex *m, bool wlock);\n  void MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock,\n      bool trylock);\n  void MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock);\n  void MutexDestroy(DDCallback *cb, DDMutex *m);\n\n  DDReport *GetReport(DDCallback *cb);\n\n  void CycleCheck(DDPhysicalThread *pt, DDLogicalThread *lt, DDMutex *mtx);\n  void Report(DDPhysicalThread *pt, DDLogicalThread *lt, int npath);\n  u32 allocateId(DDCallback *cb);\n  Mutex *getMutex(u32 id);\n  u32 getMutexId(Mutex *m);\n\n  DDFlags flags;\n\n  Mutex* mutex[kL1Size];\n\n  SpinMutex mtx;\n  InternalMmapVector<u32> free_id;\n  int id_gen;\n};\n\nDDetector *DDetector::Create(const DDFlags *flags) {\n  (void)flags;\n  void *mem = MmapOrDie(sizeof(DD), \"deadlock detector\");\n  return new(mem) DD(flags);\n}\n\nDD::DD(const DDFlags *flags)\n    : flags(*flags)\n    , free_id(1024) {\n  id_gen = 0;\n}\n\nDDPhysicalThread* DD::CreatePhysicalThread() {\n  DDPhysicalThread *pt = (DDPhysicalThread*)MmapOrDie(sizeof(DDPhysicalThread),\n      \"deadlock detector (physical thread)\");\n  return pt;\n}\n\nvoid DD::DestroyPhysicalThread(DDPhysicalThread *pt) {\n  pt->~DDPhysicalThread();\n  UnmapOrDie(pt, sizeof(DDPhysicalThread));\n}\n\nDDLogicalThread* DD::CreateLogicalThread(u64 ctx) {\n  DDLogicalThread *lt = (DDLogicalThread*)InternalAlloc(\n      sizeof(DDLogicalThread));\n  lt->ctx = ctx;\n  lt->nlocked = 0;\n  return lt;\n}\n\nvoid DD::DestroyLogicalThread(DDLogicalThread *lt) {\n  lt->~DDLogicalThread();\n  InternalFree(lt);\n}\n\nvoid DD::MutexInit(DDCallback *cb, DDMutex *m) {\n  VPrintf(2, \"#%llu: DD::MutexInit(%p)\\n\", cb->lt->ctx, m);\n  m->id = kNoId;\n  m->recursion = 0;\n  atomic_store(&m->owner, 0, memory_order_relaxed);\n}\n\nMutex *DD::getMutex(u32 id) {\n  return &mutex[id / kL2Size][id % kL2Size];\n}\n\nu32 DD::getMutexId(Mutex *m) {\n  for (int i = 0; i < kL1Size; i++) {\n    Mutex *tab = mutex[i];\n    if (tab == 0)\n      break;\n    if (m >= tab && m < tab + kL2Size)\n      return i * kL2Size + (m - tab);\n  }\n  return -1;\n}\n\nu32 DD::allocateId(DDCallback *cb) {\n  u32 id = -1;\n  SpinMutexLock l(&mtx);\n  if (free_id.size() > 0) {\n    id = free_id.back();\n    free_id.pop_back();\n  } else {\n    CHECK_LT(id_gen, kMaxMutex);\n    if ((id_gen % kL2Size) == 0) {\n      mutex[id_gen / kL2Size] = (Mutex*)MmapOrDie(kL2Size * sizeof(Mutex),\n          \"deadlock detector (mutex table)\");\n    }\n    id = id_gen++;\n  }\n  CHECK_LE(id, kMaxMutex);\n  VPrintf(3, \"#%llu: DD::allocateId assign id %d\\n\", cb->lt->ctx, id);\n  return id;\n}\n\nvoid DD::MutexBeforeLock(DDCallback *cb, DDMutex *m, bool wlock) {\n  VPrintf(2, \"#%llu: DD::MutexBeforeLock(%p, wlock=%d) nlocked=%d\\n\",\n      cb->lt->ctx, m, wlock, cb->lt->nlocked);\n  DDPhysicalThread *pt = cb->pt;\n  DDLogicalThread *lt = cb->lt;\n\n  uptr owner = atomic_load(&m->owner, memory_order_relaxed);\n  if (owner == (uptr)cb->lt) {\n    VPrintf(3, \"#%llu: DD::MutexBeforeLock recursive\\n\",\n        cb->lt->ctx);\n    return;\n  }\n\n  CHECK_LE(lt->nlocked, kMaxNesting);\n\n  // FIXME(dvyukov): don't allocate id if lt->nlocked == 0?\n  if (m->id == kNoId)\n    m->id = allocateId(cb);\n\n  ThreadMutex *tm = &lt->locked[lt->nlocked++];\n  tm->id = m->id;\n  if (flags.second_deadlock_stack)\n    tm->stk = cb->Unwind();\n  if (lt->nlocked == 1) {\n    VPrintf(3, \"#%llu: DD::MutexBeforeLock first mutex\\n\",\n        cb->lt->ctx);\n    return;\n  }\n\n  bool added = false;\n  Mutex *mtx = getMutex(m->id);\n  for (int i = 0; i < lt->nlocked - 1; i++) {\n    u32 id1 = lt->locked[i].id;\n    u32 stk1 = lt->locked[i].stk;\n    Mutex *mtx1 = getMutex(id1);\n    SpinMutexLock l(&mtx1->mtx);\n    if (mtx1->nlink == kMaxLink) {\n      // FIXME(dvyukov): check stale links\n      continue;\n    }\n    int li = 0;\n    for (; li < mtx1->nlink; li++) {\n      Link *link = &mtx1->link[li];\n      if (link->id == m->id) {\n        if (link->seq != mtx->seq) {\n          link->seq = mtx->seq;\n          link->tid = lt->ctx;\n          link->stk0 = stk1;\n          link->stk1 = cb->Unwind();\n          added = true;\n          VPrintf(3, \"#%llu: DD::MutexBeforeLock added %d->%d link\\n\",\n              cb->lt->ctx, getMutexId(mtx1), m->id);\n        }\n        break;\n      }\n    }\n    if (li == mtx1->nlink) {\n      // FIXME(dvyukov): check stale links\n      Link *link = &mtx1->link[mtx1->nlink++];\n      link->id = m->id;\n      link->seq = mtx->seq;\n      link->tid = lt->ctx;\n      link->stk0 = stk1;\n      link->stk1 = cb->Unwind();\n      added = true;\n      VPrintf(3, \"#%llu: DD::MutexBeforeLock added %d->%d link\\n\",\n          cb->lt->ctx, getMutexId(mtx1), m->id);\n    }\n  }\n\n  if (!added || mtx->nlink == 0) {\n    VPrintf(3, \"#%llu: DD::MutexBeforeLock don't check\\n\",\n        cb->lt->ctx);\n    return;\n  }\n\n  CycleCheck(pt, lt, m);\n}\n\nvoid DD::MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock,\n    bool trylock) {\n  VPrintf(2, \"#%llu: DD::MutexAfterLock(%p, wlock=%d, try=%d) nlocked=%d\\n\",\n      cb->lt->ctx, m, wlock, trylock, cb->lt->nlocked);\n  DDLogicalThread *lt = cb->lt;\n\n  uptr owner = atomic_load(&m->owner, memory_order_relaxed);\n  if (owner == (uptr)cb->lt) {\n    VPrintf(3, \"#%llu: DD::MutexAfterLock recursive\\n\", cb->lt->ctx);\n    CHECK(wlock);\n    m->recursion++;\n    return;\n  }\n  CHECK_EQ(owner, 0);\n  if (wlock) {\n    VPrintf(3, \"#%llu: DD::MutexAfterLock set owner\\n\", cb->lt->ctx);\n    CHECK_EQ(m->recursion, 0);\n    m->recursion = 1;\n    atomic_store(&m->owner, (uptr)cb->lt, memory_order_relaxed);\n  }\n\n  if (!trylock)\n    return;\n\n  CHECK_LE(lt->nlocked, kMaxNesting);\n  if (m->id == kNoId)\n    m->id = allocateId(cb);\n  ThreadMutex *tm = &lt->locked[lt->nlocked++];\n  tm->id = m->id;\n  if (flags.second_deadlock_stack)\n    tm->stk = cb->Unwind();\n}\n\nvoid DD::MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) {\n  VPrintf(2, \"#%llu: DD::MutexBeforeUnlock(%p, wlock=%d) nlocked=%d\\n\",\n      cb->lt->ctx, m, wlock, cb->lt->nlocked);\n  DDLogicalThread *lt = cb->lt;\n\n  uptr owner = atomic_load(&m->owner, memory_order_relaxed);\n  if (owner == (uptr)cb->lt) {\n    VPrintf(3, \"#%llu: DD::MutexBeforeUnlock recursive\\n\", cb->lt->ctx);\n    if (--m->recursion > 0)\n      return;\n    VPrintf(3, \"#%llu: DD::MutexBeforeUnlock reset owner\\n\", cb->lt->ctx);\n    atomic_store(&m->owner, 0, memory_order_relaxed);\n  }\n  CHECK_NE(m->id, kNoId);\n  int last = lt->nlocked - 1;\n  for (int i = last; i >= 0; i--) {\n    if (cb->lt->locked[i].id == m->id) {\n      lt->locked[i] = lt->locked[last];\n      lt->nlocked--;\n      break;\n    }\n  }\n}\n\nvoid DD::MutexDestroy(DDCallback *cb, DDMutex *m) {\n  VPrintf(2, \"#%llu: DD::MutexDestroy(%p)\\n\",\n      cb->lt->ctx, m);\n  DDLogicalThread *lt = cb->lt;\n\n  if (m->id == kNoId)\n    return;\n\n  // Remove the mutex from lt->locked if there.\n  int last = lt->nlocked - 1;\n  for (int i = last; i >= 0; i--) {\n    if (lt->locked[i].id == m->id) {\n      lt->locked[i] = lt->locked[last];\n      lt->nlocked--;\n      break;\n    }\n  }\n\n  // Clear and invalidate the mutex descriptor.\n  {\n    Mutex *mtx = getMutex(m->id);\n    SpinMutexLock l(&mtx->mtx);\n    mtx->seq++;\n    mtx->nlink = 0;\n  }\n\n  // Return id to cache.\n  {\n    SpinMutexLock l(&mtx);\n    free_id.push_back(m->id);\n  }\n}\n\nvoid DD::CycleCheck(DDPhysicalThread *pt, DDLogicalThread *lt,\n    DDMutex *m) {\n  internal_memset(pt->visited, 0, sizeof(pt->visited));\n  int npath = 0;\n  int npending = 0;\n  {\n    Mutex *mtx = getMutex(m->id);\n    SpinMutexLock l(&mtx->mtx);\n    for (int li = 0; li < mtx->nlink; li++)\n      pt->pending[npending++] = mtx->link[li];\n  }\n  while (npending > 0) {\n    Link link = pt->pending[--npending];\n    if (link.id == kEndId) {\n      npath--;\n      continue;\n    }\n    if (pt->visited[link.id])\n      continue;\n    Mutex *mtx1 = getMutex(link.id);\n    SpinMutexLock l(&mtx1->mtx);\n    if (mtx1->seq != link.seq)\n      continue;\n    pt->visited[link.id] = true;\n    if (mtx1->nlink == 0)\n      continue;\n    pt->path[npath++] = link;\n    pt->pending[npending++] = Link(kEndId);\n    if (link.id == m->id)\n      return Report(pt, lt, npath);  // Bingo!\n    for (int li = 0; li < mtx1->nlink; li++) {\n      Link *link1 = &mtx1->link[li];\n      // Mutex *mtx2 = getMutex(link->id);\n      // FIXME(dvyukov): fast seq check\n      // FIXME(dvyukov): fast nlink != 0 check\n      // FIXME(dvyukov): fast pending check?\n      // FIXME(dvyukov): npending can be larger than kMaxMutex\n      pt->pending[npending++] = *link1;\n    }\n  }\n}\n\nvoid DD::Report(DDPhysicalThread *pt, DDLogicalThread *lt, int npath) {\n  DDReport *rep = &pt->rep;\n  rep->n = npath;\n  for (int i = 0; i < npath; i++) {\n    Link *link = &pt->path[i];\n    Link *link0 = &pt->path[i ? i - 1 : npath - 1];\n    rep->loop[i].thr_ctx = link->tid;\n    rep->loop[i].mtx_ctx0 = link0->id;\n    rep->loop[i].mtx_ctx1 = link->id;\n    rep->loop[i].stk[0] = flags.second_deadlock_stack ? link->stk0 : 0;\n    rep->loop[i].stk[1] = link->stk1;\n  }\n  pt->report_pending = true;\n}\n\nDDReport *DD::GetReport(DDCallback *cb) {\n  if (!cb->pt->report_pending)\n    return 0;\n  cb->pt->report_pending = false;\n  return &cb->pt->rep;\n}\n\n}  // namespace __sanitizer\n#endif  // #if SANITIZER_DEADLOCK_DETECTOR_VERSION == 2\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h",
    "content": "//===-- sanitizer_deadlock_detector_interface.h -----------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of Sanitizer runtime.\n// Abstract deadlock detector interface.\n// FIXME: this is work in progress, nothing really works yet.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H\n#define SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H\n\n#ifndef SANITIZER_DEADLOCK_DETECTOR_VERSION\n# define SANITIZER_DEADLOCK_DETECTOR_VERSION 1\n#endif\n\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_atomic.h\"\n\nnamespace __sanitizer {\n\n// dd - deadlock detector.\n// lt - logical (user) thread.\n// pt - physical (OS) thread.\n\nstruct DDPhysicalThread;\nstruct DDLogicalThread;\n\nstruct DDMutex {\n#if SANITIZER_DEADLOCK_DETECTOR_VERSION == 1\n  uptr id;\n  u32  stk;  // creation stack\n#elif SANITIZER_DEADLOCK_DETECTOR_VERSION == 2\n  u32              id;\n  u32              recursion;\n  atomic_uintptr_t owner;\n#else\n# error \"BAD SANITIZER_DEADLOCK_DETECTOR_VERSION\"\n#endif\n  u64  ctx;\n};\n\nstruct DDFlags {\n  bool second_deadlock_stack;\n};\n\nstruct DDReport {\n  enum { kMaxLoopSize = 8 };\n  int n;  // number of entries in loop\n  struct {\n    u64 thr_ctx;   // user thread context\n    u64 mtx_ctx0;  // user mutex context, start of the edge\n    u64 mtx_ctx1;  // user mutex context, end of the edge\n    u32 stk[2];  // stack ids for the edge\n  } loop[kMaxLoopSize];\n};\n\nstruct DDCallback {\n  DDPhysicalThread *pt;\n  DDLogicalThread  *lt;\n\n  virtual u32 Unwind() { return 0; }\n  virtual int UniqueTid() { return 0; }\n};\n\nstruct DDetector {\n  static DDetector *Create(const DDFlags *flags);\n\n  virtual DDPhysicalThread* CreatePhysicalThread() { return nullptr; }\n  virtual void DestroyPhysicalThread(DDPhysicalThread *pt) {}\n\n  virtual DDLogicalThread* CreateLogicalThread(u64 ctx) { return nullptr; }\n  virtual void DestroyLogicalThread(DDLogicalThread *lt) {}\n\n  virtual void MutexInit(DDCallback *cb, DDMutex *m) {}\n  virtual void MutexBeforeLock(DDCallback *cb, DDMutex *m, bool wlock) {}\n  virtual void MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock,\n      bool trylock) {}\n  virtual void MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) {}\n  virtual void MutexDestroy(DDCallback *cb, DDMutex *m) {}\n\n  virtual DDReport *GetReport(DDCallback *cb) { return nullptr; }\n};\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cc",
    "content": "//===-- sanitizer_flag_parser.cc ------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_flag_parser.h\"\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_flag_parser.h\"\n\nnamespace __sanitizer {\n\nLowLevelAllocator FlagParser::Alloc;\n\nclass UnknownFlags {\n  static const int kMaxUnknownFlags = 20;\n  const char *unknown_flags_[kMaxUnknownFlags];\n  int n_unknown_flags_;\n\n public:\n  void Add(const char *name) {\n    CHECK_LT(n_unknown_flags_, kMaxUnknownFlags);\n    unknown_flags_[n_unknown_flags_++] = name;\n  }\n\n  void Report() {\n    if (!n_unknown_flags_) return;\n    Printf(\"WARNING: found %d unrecognized flag(s):\\n\", n_unknown_flags_);\n    for (int i = 0; i < n_unknown_flags_; ++i)\n      Printf(\"    %s\\n\", unknown_flags_[i]);\n    n_unknown_flags_ = 0;\n  }\n};\n\nUnknownFlags unknown_flags;\n\nvoid ReportUnrecognizedFlags() {\n  unknown_flags.Report();\n}\n\nchar *FlagParser::ll_strndup(const char *s, uptr n) {\n  uptr len = internal_strnlen(s, n);\n  char *s2 = (char*)Alloc.Allocate(len + 1);\n  internal_memcpy(s2, s, len);\n  s2[len] = 0;\n  return s2;\n}\n\nvoid FlagParser::PrintFlagDescriptions() {\n  Printf(\"Available flags for %s:\\n\", SanitizerToolName);\n  for (int i = 0; i < n_flags_; ++i)\n    Printf(\"\\t%s\\n\\t\\t- %s\\n\", flags_[i].name, flags_[i].desc);\n}\n\nvoid FlagParser::fatal_error(const char *err) {\n  Printf(\"ERROR: %s\\n\", err);\n  Die();\n}\n\nbool FlagParser::is_space(char c) {\n  return c == ' ' || c == ',' || c == ':' || c == '\\n' || c == '\\t' ||\n         c == '\\r';\n}\n\nvoid FlagParser::skip_whitespace() {\n  while (is_space(buf_[pos_])) ++pos_;\n}\n\nvoid FlagParser::parse_flag() {\n  uptr name_start = pos_;\n  while (buf_[pos_] != 0 && buf_[pos_] != '=' && !is_space(buf_[pos_])) ++pos_;\n  if (buf_[pos_] != '=') fatal_error(\"expected '='\");\n  char *name = ll_strndup(buf_ + name_start, pos_ - name_start);\n\n  uptr value_start = ++pos_;\n  char *value;\n  if (buf_[pos_] == '\\'' || buf_[pos_] == '\"') {\n    char quote = buf_[pos_++];\n    while (buf_[pos_] != 0 && buf_[pos_] != quote) ++pos_;\n    if (buf_[pos_] == 0) fatal_error(\"unterminated string\");\n    value = ll_strndup(buf_ + value_start + 1, pos_ - value_start - 1);\n    ++pos_; // consume the closing quote\n  } else {\n    while (buf_[pos_] != 0 && !is_space(buf_[pos_])) ++pos_;\n    if (buf_[pos_] != 0 && !is_space(buf_[pos_]))\n      fatal_error(\"expected separator or eol\");\n    value = ll_strndup(buf_ + value_start, pos_ - value_start);\n  }\n\n  bool res = run_handler(name, value);\n  if (!res) fatal_error(\"Flag parsing failed.\");\n}\n\nvoid FlagParser::parse_flags() {\n  while (true) {\n    skip_whitespace();\n    if (buf_[pos_] == 0) break;\n    parse_flag();\n  }\n\n  // Do a sanity check for certain flags.\n  if (common_flags_dont_use.malloc_context_size < 1)\n    common_flags_dont_use.malloc_context_size = 1;\n}\n\nvoid FlagParser::ParseString(const char *s) {\n  if (!s) return;\n  // Backup current parser state to allow nested ParseString() calls.\n  const char *old_buf_ = buf_;\n  uptr old_pos_ = pos_;\n  buf_ = s;\n  pos_ = 0;\n\n  parse_flags();\n\n  buf_ = old_buf_;\n  pos_ = old_pos_;\n}\n\nbool FlagParser::ParseFile(const char *path, bool ignore_missing) {\n  static const uptr kMaxIncludeSize = 1 << 15;\n  char *data;\n  uptr data_mapped_size;\n  error_t err;\n  uptr len;\n  if (!ReadFileToBuffer(path, &data, &data_mapped_size, &len,\n                        Max(kMaxIncludeSize, GetPageSizeCached()), &err)) {\n    if (ignore_missing)\n      return true;\n    Printf(\"Failed to read options from '%s': error %d\\n\", path, err);\n    return false;\n  }\n  ParseString(data);\n  UnmapOrDie(data, data_mapped_size);\n  return true;\n}\n\nbool FlagParser::run_handler(const char *name, const char *value) {\n  for (int i = 0; i < n_flags_; ++i) {\n    if (internal_strcmp(name, flags_[i].name) == 0)\n      return flags_[i].handler->Parse(value);\n  }\n  // Unrecognized flag. This is not a fatal error, we may print a warning later.\n  unknown_flags.Add(name);\n  return true;\n}\n\nvoid FlagParser::RegisterHandler(const char *name, FlagHandlerBase *handler,\n                                 const char *desc) {\n  CHECK_LT(n_flags_, kMaxFlags);\n  flags_[n_flags_].name = name;\n  flags_[n_flags_].desc = desc;\n  flags_[n_flags_].handler = handler;\n  ++n_flags_;\n}\n\nFlagParser::FlagParser() : n_flags_(0), buf_(nullptr), pos_(0) {\n  flags_ = (Flag *)Alloc.Allocate(sizeof(Flag) * kMaxFlags);\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h",
    "content": "//===-- sanitizer_flag_parser.h ---------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_FLAG_REGISTRY_H\n#define SANITIZER_FLAG_REGISTRY_H\n\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_common.h\"\n\nnamespace __sanitizer {\n\nclass FlagHandlerBase {\n public:\n  virtual bool Parse(const char *value) { return false; }\n};\n\ntemplate <typename T>\nclass FlagHandler : public FlagHandlerBase {\n  T *t_;\n\n public:\n  explicit FlagHandler(T *t) : t_(t) {}\n  bool Parse(const char *value) final;\n};\n\ntemplate <>\ninline bool FlagHandler<bool>::Parse(const char *value) {\n  if (internal_strcmp(value, \"0\") == 0 ||\n      internal_strcmp(value, \"no\") == 0 ||\n      internal_strcmp(value, \"false\") == 0) {\n    *t_ = false;\n    return true;\n  }\n  if (internal_strcmp(value, \"1\") == 0 ||\n      internal_strcmp(value, \"yes\") == 0 ||\n      internal_strcmp(value, \"true\") == 0) {\n    *t_ = true;\n    return true;\n  }\n  Printf(\"ERROR: Invalid value for bool option: '%s'\\n\", value);\n  return false;\n}\n\ntemplate <>\ninline bool FlagHandler<const char *>::Parse(const char *value) {\n  *t_ = internal_strdup(value);\n  return true;\n}\n\ntemplate <>\ninline bool FlagHandler<int>::Parse(const char *value) {\n  char *value_end;\n  *t_ = internal_simple_strtoll(value, &value_end, 10);\n  bool ok = *value_end == 0;\n  if (!ok) Printf(\"ERROR: Invalid value for int option: '%s'\\n\", value);\n  return ok;\n}\n\ntemplate <>\ninline bool FlagHandler<uptr>::Parse(const char *value) {\n  char *value_end;\n  *t_ = internal_simple_strtoll(value, &value_end, 10);\n  bool ok = *value_end == 0;\n  if (!ok) Printf(\"ERROR: Invalid value for uptr option: '%s'\\n\", value);\n  return ok;\n}\n\nclass FlagParser {\n  static const int kMaxFlags = 200;\n  struct Flag {\n    const char *name;\n    const char *desc;\n    FlagHandlerBase *handler;\n  } *flags_;\n  int n_flags_;\n\n  const char *buf_;\n  uptr pos_;\n\n public:\n  FlagParser();\n  void RegisterHandler(const char *name, FlagHandlerBase *handler,\n                       const char *desc);\n  void ParseString(const char *s);\n  bool ParseFile(const char *path, bool ignore_missing);\n  void PrintFlagDescriptions();\n\n  static LowLevelAllocator Alloc;\n\n private:\n  void fatal_error(const char *err);\n  bool is_space(char c);\n  void skip_whitespace();\n  void parse_flags();\n  void parse_flag();\n  bool run_handler(const char *name, const char *value);\n  char *ll_strndup(const char *s, uptr n);\n};\n\ntemplate <typename T>\nstatic void RegisterFlag(FlagParser *parser, const char *name, const char *desc,\n                         T *var) {\n  FlagHandler<T> *fh = new (FlagParser::Alloc) FlagHandler<T>(var);  // NOLINT\n  parser->RegisterHandler(name, fh, desc);\n}\n\nvoid ReportUnrecognizedFlags();\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_FLAG_REGISTRY_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_flags.cc",
    "content": "//===-- sanitizer_flags.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_flags.h\"\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_list.h\"\n#include \"sanitizer_flag_parser.h\"\n\nnamespace __sanitizer {\n\nCommonFlags common_flags_dont_use;\n\nstruct FlagDescription {\n  const char *name;\n  const char *description;\n  FlagDescription *next;\n};\n\nIntrusiveList<FlagDescription> flag_descriptions;\n\n// If set, the tool will install its own SEGV signal handler by default.\n#ifndef SANITIZER_NEEDS_SEGV\n# define SANITIZER_NEEDS_SEGV 1\n#endif\n\nvoid CommonFlags::SetDefaults() {\n#define COMMON_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;\n#include \"sanitizer_flags.inc\"\n#undef COMMON_FLAG\n}\n\nvoid CommonFlags::CopyFrom(const CommonFlags &other) {\n  internal_memcpy(this, &other, sizeof(*this));\n}\n\n// Copy the string from \"s\" to \"out\", replacing \"%b\" with the binary basename.\nstatic void SubstituteBinaryName(const char *s, char *out, uptr out_size) {\n  char *out_end = out + out_size;\n  while (*s && out < out_end - 1) {\n    if (s[0] != '%' || s[1] != 'b') { *out++ = *s++; continue; }\n    const char *base = GetProcessName();\n    CHECK(base);\n    while (*base && out < out_end - 1)\n      *out++ = *base++;\n    s += 2; // skip \"%b\"\n  }\n  *out = '\\0';\n}\n\nclass FlagHandlerInclude : public FlagHandlerBase {\n  FlagParser *parser_;\n  bool ignore_missing_;\n\n public:\n  explicit FlagHandlerInclude(FlagParser *parser, bool ignore_missing)\n      : parser_(parser), ignore_missing_(ignore_missing) {}\n  bool Parse(const char *value) final {\n    if (internal_strchr(value, '%')) {\n      char *buf = (char *)MmapOrDie(kMaxPathLength, \"FlagHandlerInclude\");\n      SubstituteBinaryName(value, buf, kMaxPathLength);\n      bool res = parser_->ParseFile(buf, ignore_missing_);\n      UnmapOrDie(buf, kMaxPathLength);\n      return res;\n    }\n    return parser_->ParseFile(value, ignore_missing_);\n  }\n};\n\nvoid RegisterIncludeFlags(FlagParser *parser, CommonFlags *cf) {\n  FlagHandlerInclude *fh_include = new (FlagParser::Alloc) // NOLINT\n      FlagHandlerInclude(parser, /*ignore_missing*/ false);\n  parser->RegisterHandler(\"include\", fh_include,\n                          \"read more options from the given file\");\n  FlagHandlerInclude *fh_include_if_exists = new (FlagParser::Alloc) // NOLINT\n      FlagHandlerInclude(parser, /*ignore_missing*/ true);\n  parser->RegisterHandler(\n      \"include_if_exists\", fh_include_if_exists,\n      \"read more options from the given file (if it exists)\");\n}\n\nvoid RegisterCommonFlags(FlagParser *parser, CommonFlags *cf) {\n#define COMMON_FLAG(Type, Name, DefaultValue, Description) \\\n  RegisterFlag(parser, #Name, Description, &cf->Name);\n#include \"sanitizer_flags.inc\"\n#undef COMMON_FLAG\n\n  RegisterIncludeFlags(parser, cf);\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_flags.h",
    "content": "//===-- sanitizer_flags.h ---------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_FLAGS_H\n#define SANITIZER_FLAGS_H\n\n#include \"sanitizer_internal_defs.h\"\n\nnamespace __sanitizer {\n\nstruct CommonFlags {\n#define COMMON_FLAG(Type, Name, DefaultValue, Description) Type Name;\n#include \"sanitizer_flags.inc\"\n#undef COMMON_FLAG\n\n  void SetDefaults();\n  void CopyFrom(const CommonFlags &other);\n};\n\n// Functions to get/set global CommonFlags shared by all sanitizer runtimes:\nextern CommonFlags common_flags_dont_use;\ninline const CommonFlags *common_flags() {\n  return &common_flags_dont_use;\n}\n\ninline void SetCommonFlagsDefaults() {\n  common_flags_dont_use.SetDefaults();\n}\n\n// This function can only be used to setup tool-specific overrides for\n// CommonFlags defaults. Generally, it should only be used right after\n// SetCommonFlagsDefaults(), but before ParseCommonFlagsFromString(), and\n// only during the flags initialization (i.e. before they are used for\n// the first time).\ninline void OverrideCommonFlags(const CommonFlags &cf) {\n  common_flags_dont_use.CopyFrom(cf);\n}\n\nclass FlagParser;\nvoid RegisterCommonFlags(FlagParser *parser,\n                         CommonFlags *cf = &common_flags_dont_use);\nvoid RegisterIncludeFlags(FlagParser *parser, CommonFlags *cf);\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_FLAGS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc",
    "content": "//===-- sanitizer_flags.h ---------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file describes common flags available in all sanitizers.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef COMMON_FLAG\n#error \"Define COMMON_FLAG prior to including this file!\"\n#endif\n\n// COMMON_FLAG(Type, Name, DefaultValue, Description)\n// Supported types: bool, const char *, int, uptr.\n// Default value must be a compile-time constant.\n// Description must be a string literal.\n\nCOMMON_FLAG(\n    bool, symbolize, true,\n    \"If set, use the online symbolizer from common sanitizer runtime to turn \"\n    \"virtual addresses to file/line locations.\")\nCOMMON_FLAG(\n    const char *, external_symbolizer_path, nullptr,\n    \"Path to external symbolizer. If empty, the tool will search $PATH for \"\n    \"the symbolizer.\")\nCOMMON_FLAG(\n    bool, allow_addr2line, false,\n    \"If set, allows online symbolizer to run addr2line binary to symbolize \"\n    \"stack traces (addr2line will only be used if llvm-symbolizer binary is \"\n    \"unavailable.\")\nCOMMON_FLAG(const char *, strip_path_prefix, \"\",\n            \"Strips this prefix from file paths in error reports.\")\nCOMMON_FLAG(bool, fast_unwind_on_check, false,\n            \"If available, use the fast frame-pointer-based unwinder on \"\n            \"internal CHECK failures.\")\nCOMMON_FLAG(bool, fast_unwind_on_fatal, false,\n            \"If available, use the fast frame-pointer-based unwinder on fatal \"\n            \"errors.\")\nCOMMON_FLAG(bool, fast_unwind_on_malloc, true,\n            \"If available, use the fast frame-pointer-based unwinder on \"\n            \"malloc/free.\")\nCOMMON_FLAG(bool, handle_ioctl, false, \"Intercept and handle ioctl requests.\")\nCOMMON_FLAG(int, malloc_context_size, 1,\n            \"Max number of stack frames kept for each allocation/deallocation.\")\nCOMMON_FLAG(\n    const char *, log_path, \"stderr\",\n    \"Write logs to \\\"log_path.pid\\\". The special values are \\\"stdout\\\" and \"\n    \"\\\"stderr\\\". The default is \\\"stderr\\\".\")\nCOMMON_FLAG(\n    bool, log_exe_name, false,\n    \"Mention name of executable when reporting error and \"\n    \"append executable name to logs (as in \\\"log_path.exe_name.pid\\\").\")\nCOMMON_FLAG(\n    bool, log_to_syslog, SANITIZER_ANDROID || SANITIZER_MAC,\n    \"Write all sanitizer output to syslog in addition to other means of \"\n    \"logging.\")\nCOMMON_FLAG(\n    int, verbosity, 0,\n    \"Verbosity level (0 - silent, 1 - a bit of output, 2+ - more output).\")\nCOMMON_FLAG(bool, detect_leaks, true, \"Enable memory leak detection.\")\nCOMMON_FLAG(\n    bool, leak_check_at_exit, true,\n    \"Invoke leak checking in an atexit handler. Has no effect if \"\n    \"detect_leaks=false, or if __lsan_do_leak_check() is called before the \"\n    \"handler has a chance to run.\")\nCOMMON_FLAG(bool, allocator_may_return_null, false,\n            \"If false, the allocator will crash instead of returning 0 on \"\n            \"out-of-memory.\")\nCOMMON_FLAG(bool, print_summary, true,\n            \"If false, disable printing error summaries in addition to error \"\n            \"reports.\")\nCOMMON_FLAG(bool, check_printf, true, \"Check printf arguments.\")\nCOMMON_FLAG(bool, handle_segv, SANITIZER_NEEDS_SEGV,\n            \"If set, registers the tool's custom SIGSEGV/SIGBUS handler.\")\nCOMMON_FLAG(bool, handle_abort, false,\n            \"If set, registers the tool's custom SIGABRT handler.\")\nCOMMON_FLAG(bool, handle_sigill, false,\n            \"If set, registers the tool's custom SIGILL handler.\")\nCOMMON_FLAG(bool, handle_sigfpe, true,\n            \"If set, registers the tool's custom SIGFPE handler.\")\nCOMMON_FLAG(bool, allow_user_segv_handler, false,\n            \"If set, allows user to register a SEGV handler even if the tool \"\n            \"registers one.\")\nCOMMON_FLAG(bool, use_sigaltstack, true,\n            \"If set, uses alternate stack for signal handling.\")\nCOMMON_FLAG(bool, detect_deadlocks, false,\n            \"If set, deadlock detection is enabled.\")\nCOMMON_FLAG(\n    uptr, clear_shadow_mmap_threshold, 64 * 1024,\n    \"Large shadow regions are zero-filled using mmap(NORESERVE) instead of \"\n    \"memset(). This is the threshold size in bytes.\")\nCOMMON_FLAG(const char *, color, \"auto\",\n            \"Colorize reports: (always|never|auto).\")\nCOMMON_FLAG(\n    bool, legacy_pthread_cond, false,\n    \"Enables support for dynamic libraries linked with libpthread 2.2.5.\")\nCOMMON_FLAG(bool, intercept_tls_get_addr, false, \"Intercept __tls_get_addr.\")\nCOMMON_FLAG(bool, help, false, \"Print the flag descriptions.\")\nCOMMON_FLAG(uptr, mmap_limit_mb, 0,\n            \"Limit the amount of mmap-ed memory (excluding shadow) in Mb; \"\n            \"not a user-facing flag, used mosly for testing the tools\")\nCOMMON_FLAG(uptr, hard_rss_limit_mb, 0,\n            \"Hard RSS limit in Mb.\"\n            \" If non-zero, a background thread is spawned at startup\"\n            \" which periodically reads RSS and aborts the process if the\"\n            \" limit is reached\")\nCOMMON_FLAG(uptr, soft_rss_limit_mb, 0,\n            \"Soft RSS limit in Mb.\"\n            \" If non-zero, a background thread is spawned at startup\"\n            \" which periodically reads RSS. If the limit is reached\"\n            \" all subsequent malloc/new calls will fail or return NULL\"\n            \" (depending on the value of allocator_may_return_null)\"\n            \" until the RSS goes below the soft limit.\"\n            \" This limit does not affect memory allocations other than\"\n            \" malloc/new.\")\nCOMMON_FLAG(bool, can_use_proc_maps_statm, true,\n            \"If false, do not attempt to read /proc/maps/statm.\"\n            \" Mostly useful for testing sanitizers.\")\nCOMMON_FLAG(\n    bool, coverage, false,\n    \"If set, coverage information will be dumped at program shutdown (if the \"\n    \"coverage instrumentation was enabled at compile time).\")\nCOMMON_FLAG(bool, coverage_pcs, true,\n            \"If set (and if 'coverage' is set too), the coverage information \"\n            \"will be dumped as a set of PC offsets for every module.\")\nCOMMON_FLAG(bool, coverage_order_pcs, false,\n             \"If true, the PCs will be dumped in the order they've\"\n             \" appeared during the execution.\")\nCOMMON_FLAG(bool, coverage_bitset, false,\n            \"If set (and if 'coverage' is set too), the coverage information \"\n            \"will also be dumped as a bitset to a separate file.\")\nCOMMON_FLAG(bool, coverage_counters, false,\n            \"If set (and if 'coverage' is set too), the bitmap that corresponds\"\n            \" to coverage counters will be dumped.\")\nCOMMON_FLAG(bool, coverage_direct, SANITIZER_ANDROID,\n            \"If set, coverage information will be dumped directly to a memory \"\n            \"mapped file. This way data is not lost even if the process is \"\n            \"suddenly killed.\")\nCOMMON_FLAG(const char *, coverage_dir, \".\",\n            \"Target directory for coverage dumps. Defaults to the current \"\n            \"directory.\")\nCOMMON_FLAG(bool, full_address_space, false,\n            \"Sanitize complete address space; \"\n            \"by default kernel area on 32-bit platforms will not be sanitized\")\nCOMMON_FLAG(bool, print_suppressions, true,\n            \"Print matched suppressions at exit.\")\nCOMMON_FLAG(\n    bool, disable_coredump, (SANITIZER_WORDSIZE == 64),\n    \"Disable core dumping. By default, disable_core=1 on 64-bit to avoid \"\n    \"dumping a 16T+ core file. Ignored on OSes that don't dump core by\"\n    \"default and for sanitizers that don't reserve lots of virtual memory.\")\nCOMMON_FLAG(bool, use_madv_dontdump, true,\n          \"If set, instructs kernel to not store the (huge) shadow \"\n          \"in core file.\")\nCOMMON_FLAG(bool, symbolize_inline_frames, true,\n            \"Print inlined frames in stacktraces. Defaults to true.\")\nCOMMON_FLAG(bool, symbolize_vs_style, false,\n            \"Print file locations in Visual Studio style (e.g: \"\n            \" file(10,42): ...\")\nCOMMON_FLAG(const char *, stack_trace_format, \"DEFAULT\",\n            \"Format string used to render stack frames. \"\n            \"See sanitizer_stacktrace_printer.h for the format description. \"\n            \"Use DEFAULT to get default format.\")\nCOMMON_FLAG(bool, no_huge_pages_for_shadow, true,\n            \"If true, the shadow is not allowed to use huge pages. \")\nCOMMON_FLAG(bool, strict_string_checks, false,\n            \"If set check that string arguments are properly null-terminated\")\nCOMMON_FLAG(bool, intercept_strstr, true,\n            \"If set, uses custom wrappers for strstr and strcasestr functions \"\n            \"to find more errors.\")\nCOMMON_FLAG(bool, intercept_strspn, true,\n            \"If set, uses custom wrappers for strspn and strcspn function \"\n            \"to find more errors.\")\nCOMMON_FLAG(bool, intercept_strpbrk, true,\n            \"If set, uses custom wrappers for strpbrk function \"\n            \"to find more errors.\")\nCOMMON_FLAG(bool, intercept_memcmp, true,\n            \"If set, uses custom wrappers for memcmp function \"\n            \"to find more errors.\")\nCOMMON_FLAG(bool, strict_memcmp, true,\n          \"If true, assume that memcmp(p1, p2, n) always reads n bytes before \"\n          \"comparing p1 and p2.\")\nCOMMON_FLAG(bool, decorate_proc_maps, false, \"If set, decorate sanitizer \"\n                                             \"mappings in /proc/self/maps with \"\n                                             \"user-readable names\")\nCOMMON_FLAG(int, exitcode, 1, \"Override the program exit status if the tool \"\n                              \"found an error\")\nCOMMON_FLAG(\n    bool, abort_on_error, SANITIZER_MAC,\n    \"If set, the tool calls abort() instead of _exit() after printing the \"\n    \"error report.\")\nCOMMON_FLAG(bool, suppress_equal_pcs, true,\n            \"Deduplicate multiple reports for single source location in \"\n            \"halt_on_error=false mode (asan only).\")\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_freebsd.h",
    "content": "//===-- sanitizer_freebsd.h -------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of Sanitizer runtime. It contains FreeBSD-specific\n// definitions.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_FREEBSD_H\n#define SANITIZER_FREEBSD_H\n\n#include \"sanitizer_internal_defs.h\"\n\n// x86-64 FreeBSD 9.2 and older define 'ucontext_t' incorrectly in\n// 32-bit mode.\n#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)\n# include <osreldate.h>\n# if __FreeBSD_version <= 902001  // v9.2\n#  include <link.h>\n#  include <sys/param.h>\n#  include <ucontext.h>\n\nnamespace __sanitizer {\n\ntypedef unsigned long long __xuint64_t;\n\ntypedef __int32_t __xregister_t;\n\ntypedef struct __xmcontext {\n  __xregister_t mc_onstack;\n  __xregister_t mc_gs;\n  __xregister_t mc_fs;\n  __xregister_t mc_es;\n  __xregister_t mc_ds;\n  __xregister_t mc_edi;\n  __xregister_t mc_esi;\n  __xregister_t mc_ebp;\n  __xregister_t mc_isp;\n  __xregister_t mc_ebx;\n  __xregister_t mc_edx;\n  __xregister_t mc_ecx;\n  __xregister_t mc_eax;\n  __xregister_t mc_trapno;\n  __xregister_t mc_err;\n  __xregister_t mc_eip;\n  __xregister_t mc_cs;\n  __xregister_t mc_eflags;\n  __xregister_t mc_esp;\n  __xregister_t mc_ss;\n\n  int mc_len;\n  int mc_fpformat;\n  int mc_ownedfp;\n  __xregister_t mc_flags;\n\n  int mc_fpstate[128] __aligned(16);\n  __xregister_t mc_fsbase;\n  __xregister_t mc_gsbase;\n  __xregister_t mc_xfpustate;\n  __xregister_t mc_xfpustate_len;\n\n  int mc_spare2[4];\n} xmcontext_t;\n\ntypedef struct __xucontext {\n  sigset_t  uc_sigmask;\n  xmcontext_t  uc_mcontext;\n\n  struct __ucontext *uc_link;\n  stack_t uc_stack;\n  int uc_flags;\n  int __spare__[4];\n} xucontext_t;\n\nstruct xkinfo_vmentry {\n  int kve_structsize;\n  int kve_type;\n  __xuint64_t kve_start;\n  __xuint64_t kve_end;\n  __xuint64_t kve_offset;\n  __xuint64_t kve_vn_fileid;\n  __uint32_t kve_vn_fsid;\n  int kve_flags;\n  int kve_resident;\n  int kve_private_resident;\n  int kve_protection;\n  int kve_ref_count;\n  int kve_shadow_count;\n  int kve_vn_type;\n  __xuint64_t kve_vn_size;\n  __uint32_t kve_vn_rdev;\n  __uint16_t kve_vn_mode;\n  __uint16_t kve_status;\n  int _kve_ispare[12];\n  char kve_path[PATH_MAX];\n};\n\ntypedef struct {\n  __uint32_t p_type;\n  __uint32_t p_offset;\n  __uint32_t p_vaddr;\n  __uint32_t p_paddr;\n  __uint32_t p_filesz;\n  __uint32_t p_memsz;\n  __uint32_t p_flags;\n  __uint32_t p_align;\n} XElf32_Phdr;\n\nstruct xdl_phdr_info {\n  Elf_Addr dlpi_addr;\n  const char *dlpi_name;\n  const XElf32_Phdr *dlpi_phdr;\n  Elf_Half dlpi_phnum;\n  unsigned long long int dlpi_adds;\n  unsigned long long int dlpi_subs;\n  size_t dlpi_tls_modid;\n  void *dlpi_tls_data;\n};\n\ntypedef int (*__xdl_iterate_hdr_callback)(struct xdl_phdr_info*, size_t, void*);\ntypedef int xdl_iterate_phdr_t(__xdl_iterate_hdr_callback, void*);\n\n#define xdl_iterate_phdr(callback, param) \\\n  (((xdl_iterate_phdr_t*) dl_iterate_phdr)((callback), (param)))\n\n}  // namespace __sanitizer\n\n# endif  // __FreeBSD_version <= 902001\n#endif  // SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)\n\n#endif  // SANITIZER_FREEBSD_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h",
    "content": "//===-- sanitizer_interface_internal.h --------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between run-time libraries of sanitizers.\n//\n// This header declares the sanitizer runtime interface functions.\n// The runtime library has to define these functions so the instrumented program\n// could call them.\n//\n// See also include/sanitizer/common_interface_defs.h\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_INTERFACE_INTERNAL_H\n#define SANITIZER_INTERFACE_INTERNAL_H\n\n#include \"sanitizer_internal_defs.h\"\n\nextern \"C\" {\n  // Tell the tools to write their reports to \"path.<pid>\" instead of stderr.\n  // The special values are \"stdout\" and \"stderr\".\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __sanitizer_set_report_path(const char *path);\n\n  typedef struct {\n      int coverage_sandboxed;\n      __sanitizer::sptr coverage_fd;\n      unsigned int coverage_max_block_size;\n  } __sanitizer_sandbox_arguments;\n\n  // Notify the tools that the sandbox is going to be turned on.\n  SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void\n      __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);\n\n  // This function is called by the tool when it has just finished reporting\n  // an error. 'error_summary' is a one-line string that summarizes\n  // the error message. This function can be overridden by the client.\n  SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\n  void __sanitizer_report_error_summary(const char *error_summary);\n\n  SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump();\n  SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_init();\n  SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov(__sanitizer::u32 *guard);\n  SANITIZER_INTERFACE_ATTRIBUTE\n  void __sanitizer_annotate_contiguous_container(const void *beg,\n                                                 const void *end,\n                                                 const void *old_mid,\n                                                 const void *new_mid);\n  SANITIZER_INTERFACE_ATTRIBUTE\n  int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,\n                                              const void *end);\n  SANITIZER_INTERFACE_ATTRIBUTE\n  const void *__sanitizer_contiguous_container_find_bad_address(\n      const void *beg, const void *mid, const void *end);\n  } // extern \"C\"\n\n#endif  // SANITIZER_INTERFACE_INTERNAL_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h",
    "content": "//===-- sanitizer_internal_defs.h -------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer.\n// It contains macro used in run-time libraries code.\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_DEFS_H\n#define SANITIZER_DEFS_H\n\n#include \"sanitizer_platform.h\"\n\n#ifndef SANITIZER_DEBUG\n# define SANITIZER_DEBUG 0\n#endif\n\n// Only use SANITIZER_*ATTRIBUTE* before the function return type!\n#if SANITIZER_WINDOWS\n# define SANITIZER_INTERFACE_ATTRIBUTE __declspec(dllexport)\n// FIXME find out what we need on Windows, if anything.\n# define SANITIZER_WEAK_ATTRIBUTE\n#elif defined(SANITIZER_GO)\n# define SANITIZER_INTERFACE_ATTRIBUTE\n# define SANITIZER_WEAK_ATTRIBUTE\n#else\n# define SANITIZER_INTERFACE_ATTRIBUTE __attribute__((visibility(\"default\")))\n# define SANITIZER_WEAK_ATTRIBUTE  __attribute__((weak))\n#endif\n\n#if (SANITIZER_LINUX || SANITIZER_WINDOWS) && !defined(SANITIZER_GO)\n# define SANITIZER_SUPPORTS_WEAK_HOOKS 1\n#else\n# define SANITIZER_SUPPORTS_WEAK_HOOKS 0\n#endif\n\n// We can use .preinit_array section on Linux to call sanitizer initialization\n// functions very early in the process startup (unless PIC macro is defined).\n// FIXME: do we have anything like this on Mac?\n#if SANITIZER_LINUX && !SANITIZER_ANDROID && !defined(PIC)\n# define SANITIZER_CAN_USE_PREINIT_ARRAY 1\n#else\n# define SANITIZER_CAN_USE_PREINIT_ARRAY 0\n#endif\n\n// GCC does not understand __has_feature\n#if !defined(__has_feature)\n# define __has_feature(x) 0\n#endif\n\n// For portability reasons we do not include stddef.h, stdint.h or any other\n// system header, but we do need some basic types that are not defined\n// in a portable way by the language itself.\nnamespace __sanitizer {\n\n#if defined(_WIN64)\n// 64-bit Windows uses LLP64 data model.\ntypedef unsigned long long uptr;  // NOLINT\ntypedef signed   long long sptr;  // NOLINT\n#else\ntypedef unsigned long uptr;  // NOLINT\ntypedef signed   long sptr;  // NOLINT\n#endif  // defined(_WIN64)\n#if defined(__x86_64__)\n// Since x32 uses ILP32 data model in 64-bit hardware mode, we must use\n// 64-bit pointer to unwind stack frame.\ntypedef unsigned long long uhwptr;  // NOLINT\n#else\ntypedef uptr uhwptr;   // NOLINT\n#endif\ntypedef unsigned char u8;\ntypedef unsigned short u16;  // NOLINT\ntypedef unsigned int u32;\ntypedef unsigned long long u64;  // NOLINT\ntypedef signed   char s8;\ntypedef signed   short s16;  // NOLINT\ntypedef signed   int s32;\ntypedef signed   long long s64;  // NOLINT\n#if SANITIZER_WINDOWS\n// On Windows, files are HANDLE, which is a synonim of void*.\n// Use void* to avoid including <windows.h> everywhere.\ntypedef void* fd_t;\ntypedef unsigned error_t;\n#else\ntypedef int fd_t;\ntypedef int error_t;\n#endif\n\n// WARNING: OFF_T may be different from OS type off_t, depending on the value of\n// _FILE_OFFSET_BITS. This definition of OFF_T matches the ABI of system calls\n// like pread and mmap, as opposed to pread64 and mmap64.\n// FreeBSD, Mac and Linux/x86-64 are special.\n#if SANITIZER_FREEBSD || SANITIZER_MAC || \\\n  (SANITIZER_LINUX && defined(__x86_64__))\ntypedef u64 OFF_T;\n#else\ntypedef uptr OFF_T;\n#endif\ntypedef u64  OFF64_T;\n\n#if (SANITIZER_WORDSIZE == 64) || SANITIZER_MAC\ntypedef uptr operator_new_size_type;\n#else\ntypedef u32 operator_new_size_type;\n#endif\n}  // namespace __sanitizer\n\n\nusing namespace __sanitizer;  // NOLINT\n// ----------- ATTENTION -------------\n// This header should NOT include any other headers to avoid portability issues.\n\n// Common defs.\n#define INLINE inline\n#define INTERFACE_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE\n#define SANITIZER_WEAK_DEFAULT_IMPL \\\n  extern \"C\" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE NOINLINE\n#define SANITIZER_WEAK_CXX_DEFAULT_IMPL \\\n  extern \"C++\" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE NOINLINE\n\n// Platform-specific defs.\n#if defined(_MSC_VER)\n# define ALWAYS_INLINE __forceinline\n// FIXME(timurrrr): do we need this on Windows?\n# define ALIAS(x)\n# define ALIGNED(x) __declspec(align(x))\n# define FORMAT(f, a)\n# define NOINLINE __declspec(noinline)\n# define NORETURN __declspec(noreturn)\n# define THREADLOCAL   __declspec(thread)\n# define LIKELY(x) (x)\n# define UNLIKELY(x) (x)\n# define PREFETCH(x) /* _mm_prefetch(x, _MM_HINT_NTA) */\n#else  // _MSC_VER\n# define ALWAYS_INLINE inline __attribute__((always_inline))\n# define ALIAS(x) __attribute__((alias(x)))\n// Please only use the ALIGNED macro before the type.\n// Using ALIGNED after the variable declaration is not portable!\n# define ALIGNED(x) __attribute__((aligned(x)))\n# define FORMAT(f, a)  __attribute__((format(printf, f, a)))\n# define NOINLINE __attribute__((noinline))\n# define NORETURN  __attribute__((noreturn))\n# define THREADLOCAL   __thread\n# define LIKELY(x)     __builtin_expect(!!(x), 1)\n# define UNLIKELY(x)   __builtin_expect(!!(x), 0)\n# if defined(__i386__) || defined(__x86_64__)\n// __builtin_prefetch(x) generates prefetchnt0 on x86\n#  define PREFETCH(x) __asm__(\"prefetchnta (%0)\" : : \"r\" (x))\n# else\n#  define PREFETCH(x) __builtin_prefetch(x)\n# endif\n#endif  // _MSC_VER\n\n#if !defined(_MSC_VER) || defined(__clang__)\n# define UNUSED __attribute__((unused))\n# define USED __attribute__((used))\n#else\n# define UNUSED\n# define USED\n#endif\n\n#if !defined(_MSC_VER) || defined(__clang__) || MSC_PREREQ(1900)\n# define NOEXCEPT noexcept\n#else\n# define NOEXCEPT throw()\n#endif\n\n// Unaligned versions of basic types.\ntypedef ALIGNED(1) u16 uu16;\ntypedef ALIGNED(1) u32 uu32;\ntypedef ALIGNED(1) u64 uu64;\ntypedef ALIGNED(1) s16 us16;\ntypedef ALIGNED(1) s32 us32;\ntypedef ALIGNED(1) s64 us64;\n\n#if SANITIZER_WINDOWS\ntypedef unsigned long DWORD;  // NOLINT\ntypedef DWORD thread_return_t;\n# define THREAD_CALLING_CONV __stdcall\n#else  // _WIN32\ntypedef void* thread_return_t;\n# define THREAD_CALLING_CONV\n#endif  // _WIN32\ntypedef thread_return_t (THREAD_CALLING_CONV *thread_callback_t)(void* arg);\n\n// NOTE: Functions below must be defined in each run-time.\nnamespace __sanitizer {\nvoid NORETURN Die();\n\n// FIXME: No, this shouldn't be in the sanitizer interface.\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid NORETURN CheckFailed(const char *file, int line, const char *cond,\n                          u64 v1, u64 v2);\n}  // namespace __sanitizer\n\n// Check macro\n#define RAW_CHECK_MSG(expr, msg) do { \\\n  if (UNLIKELY(!(expr))) { \\\n    RawWrite(msg); \\\n    Die(); \\\n  } \\\n} while (0)\n\n#define RAW_CHECK(expr) RAW_CHECK_MSG(expr, #expr)\n\n#define CHECK_IMPL(c1, op, c2) \\\n  do { \\\n    __sanitizer::u64 v1 = (u64)(c1); \\\n    __sanitizer::u64 v2 = (u64)(c2); \\\n    if (UNLIKELY(!(v1 op v2))) \\\n      __sanitizer::CheckFailed(__FILE__, __LINE__, \\\n        \"(\" #c1 \") \" #op \" (\" #c2 \")\", v1, v2); \\\n  } while (false) \\\n/**/\n\n#define CHECK(a)       CHECK_IMPL((a), !=, 0)\n#define CHECK_EQ(a, b) CHECK_IMPL((a), ==, (b))\n#define CHECK_NE(a, b) CHECK_IMPL((a), !=, (b))\n#define CHECK_LT(a, b) CHECK_IMPL((a), <,  (b))\n#define CHECK_LE(a, b) CHECK_IMPL((a), <=, (b))\n#define CHECK_GT(a, b) CHECK_IMPL((a), >,  (b))\n#define CHECK_GE(a, b) CHECK_IMPL((a), >=, (b))\n\n#if SANITIZER_DEBUG\n#define DCHECK(a)       CHECK(a)\n#define DCHECK_EQ(a, b) CHECK_EQ(a, b)\n#define DCHECK_NE(a, b) CHECK_NE(a, b)\n#define DCHECK_LT(a, b) CHECK_LT(a, b)\n#define DCHECK_LE(a, b) CHECK_LE(a, b)\n#define DCHECK_GT(a, b) CHECK_GT(a, b)\n#define DCHECK_GE(a, b) CHECK_GE(a, b)\n#else\n#define DCHECK(a)\n#define DCHECK_EQ(a, b)\n#define DCHECK_NE(a, b)\n#define DCHECK_LT(a, b)\n#define DCHECK_LE(a, b)\n#define DCHECK_GT(a, b)\n#define DCHECK_GE(a, b)\n#endif\n\n#define UNREACHABLE(msg) do { \\\n  CHECK(0 && msg); \\\n  Die(); \\\n} while (0)\n\n#define UNIMPLEMENTED() UNREACHABLE(\"unimplemented\")\n\n#define COMPILER_CHECK(pred) IMPL_COMPILER_ASSERT(pred, __LINE__)\n\n#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))\n\n#define IMPL_PASTE(a, b) a##b\n#define IMPL_COMPILER_ASSERT(pred, line) \\\n    typedef char IMPL_PASTE(assertion_failed_##_, line)[2*(int)(pred)-1]\n\n// Limits for integral types. We have to redefine it in case we don't\n// have stdint.h (like in Visual Studio 9).\n#undef __INT64_C\n#undef __UINT64_C\n#if SANITIZER_WORDSIZE == 64\n# define __INT64_C(c)  c ## L\n# define __UINT64_C(c) c ## UL\n#else\n# define __INT64_C(c)  c ## LL\n# define __UINT64_C(c) c ## ULL\n#endif  // SANITIZER_WORDSIZE == 64\n#undef INT32_MIN\n#define INT32_MIN              (-2147483647-1)\n#undef INT32_MAX\n#define INT32_MAX              (2147483647)\n#undef UINT32_MAX\n#define UINT32_MAX             (4294967295U)\n#undef INT64_MIN\n#define INT64_MIN              (-__INT64_C(9223372036854775807)-1)\n#undef INT64_MAX\n#define INT64_MAX              (__INT64_C(9223372036854775807))\n#undef UINT64_MAX\n#define UINT64_MAX             (__UINT64_C(18446744073709551615))\n\nenum LinkerInitialized { LINKER_INITIALIZED = 0 };\n\n#if !defined(_MSC_VER) || defined(__clang__)\n# define GET_CALLER_PC() (uptr)__builtin_return_address(0)\n# define GET_CURRENT_FRAME() (uptr)__builtin_frame_address(0)\n#else\nextern \"C\" void* _ReturnAddress(void);\n# pragma intrinsic(_ReturnAddress)\n# define GET_CALLER_PC() (uptr)_ReturnAddress()\n// CaptureStackBackTrace doesn't need to know BP on Windows.\n// FIXME: This macro is still used when printing error reports though it's not\n// clear if the BP value is needed in the ASan reports on Windows.\n# define GET_CURRENT_FRAME() (uptr)0xDEADBEEF\n#endif\n\n#define HANDLE_EINTR(res, f)                                       \\\n  {                                                                \\\n    int rverrno;                                                   \\\n    do {                                                           \\\n      res = (f);                                                   \\\n    } while (internal_iserror(res, &rverrno) && rverrno == EINTR); \\\n  }\n\n// Forces the compiler to generate a frame pointer in the function.\n#define ENABLE_FRAME_POINTER                                       \\\n  do {                                                             \\\n    volatile uptr enable_fp;                                       \\\n    enable_fp = GET_CURRENT_FRAME();                               \\\n    (void)enable_fp;                                               \\\n  } while (0)\n\n#endif  // SANITIZER_DEFS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_lfstack.h",
    "content": "//===-- sanitizer_lfstack.h -=-----------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Lock-free stack.\n// Uses 32/17 bits as ABA-counter on 32/64-bit platforms.\n// The memory passed to Push() must not be ever munmap'ed.\n// The type T must contain T *next field.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_LFSTACK_H\n#define SANITIZER_LFSTACK_H\n\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_common.h\"\n#include \"sanitizer_atomic.h\"\n\nnamespace __sanitizer {\n\ntemplate<typename T>\nstruct LFStack {\n  void Clear() {\n    atomic_store(&head_, 0, memory_order_relaxed);\n  }\n\n  bool Empty() const {\n    return (atomic_load(&head_, memory_order_relaxed) & kPtrMask) == 0;\n  }\n\n  void Push(T *p) {\n    u64 cmp = atomic_load(&head_, memory_order_relaxed);\n    for (;;) {\n      u64 cnt = (cmp & kCounterMask) + kCounterInc;\n      u64 xch = (u64)(uptr)p | cnt;\n      p->next = (T*)(uptr)(cmp & kPtrMask);\n      if (atomic_compare_exchange_weak(&head_, &cmp, xch,\n                                       memory_order_release))\n        break;\n    }\n  }\n\n  T *Pop() {\n    u64 cmp = atomic_load(&head_, memory_order_acquire);\n    for (;;) {\n      T *cur = (T*)(uptr)(cmp & kPtrMask);\n      if (!cur)\n        return nullptr;\n      T *nxt = cur->next;\n      u64 cnt = (cmp & kCounterMask);\n      u64 xch = (u64)(uptr)nxt | cnt;\n      if (atomic_compare_exchange_weak(&head_, &cmp, xch,\n                                       memory_order_acquire))\n        return cur;\n    }\n  }\n\n  // private:\n  static const int kCounterBits = FIRST_32_SECOND_64(32, 17);\n  static const u64 kPtrMask = ((u64)-1) >> kCounterBits;\n  static const u64 kCounterMask = ~kPtrMask;\n  static const u64 kCounterInc = kPtrMask + 1;\n\n  atomic_uint64_t head_;\n};\n} // namespace __sanitizer\n\n#endif // SANITIZER_LFSTACK_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_libc.cc",
    "content": "//===-- sanitizer_libc.cc -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries. See sanitizer_libc.h for details.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_allocator_internal.h\"\n#include \"sanitizer_common.h\"\n#include \"sanitizer_libc.h\"\n\nnamespace __sanitizer {\n\ns64 internal_atoll(const char *nptr) {\n  return internal_simple_strtoll(nptr, nullptr, 10);\n}\n\nvoid *internal_memchr(const void *s, int c, uptr n) {\n  const char *t = (const char *)s;\n  for (uptr i = 0; i < n; ++i, ++t)\n    if (*t == c)\n      return reinterpret_cast<void *>(const_cast<char *>(t));\n  return nullptr;\n}\n\nvoid *internal_memrchr(const void *s, int c, uptr n) {\n  const char *t = (const char *)s;\n  void *res = nullptr;\n  for (uptr i = 0; i < n; ++i, ++t) {\n    if (*t == c) res = reinterpret_cast<void *>(const_cast<char *>(t));\n  }\n  return res;\n}\n\nint internal_memcmp(const void* s1, const void* s2, uptr n) {\n  const char *t1 = (const char *)s1;\n  const char *t2 = (const char *)s2;\n  for (uptr i = 0; i < n; ++i, ++t1, ++t2)\n    if (*t1 != *t2)\n      return *t1 < *t2 ? -1 : 1;\n  return 0;\n}\n\nvoid *internal_memcpy(void *dest, const void *src, uptr n) {\n  char *d = (char*)dest;\n  const char *s = (const char *)src;\n  for (uptr i = 0; i < n; ++i)\n    d[i] = s[i];\n  return dest;\n}\n\nvoid *internal_memmove(void *dest, const void *src, uptr n) {\n  char *d = (char*)dest;\n  const char *s = (const char *)src;\n  sptr i, signed_n = (sptr)n;\n  CHECK_GE(signed_n, 0);\n  if (d < s) {\n    for (i = 0; i < signed_n; ++i)\n      d[i] = s[i];\n  } else {\n    if (d > s && signed_n > 0)\n      for (i = signed_n - 1; i >= 0 ; --i) {\n        d[i] = s[i];\n      }\n  }\n  return dest;\n}\n\n// Semi-fast bzero for 16-aligned data. Still far from peak performance.\nvoid internal_bzero_aligned16(void *s, uptr n) {\n  struct S16 { u64 a, b; } ALIGNED(16);\n  CHECK_EQ((reinterpret_cast<uptr>(s) | n) & 15, 0);\n  for (S16 *p = reinterpret_cast<S16*>(s), *end = p + n / 16; p < end; p++) {\n    p->a = p->b = 0;\n    // Make sure this does not become memset.\n    SanitizerBreakOptimization(nullptr);\n  }\n}\n\nvoid *internal_memset(void* s, int c, uptr n) {\n  // The next line prevents Clang from making a call to memset() instead of the\n  // loop below.\n  // FIXME: building the runtime with -ffreestanding is a better idea. However\n  // there currently are linktime problems due to PR12396.\n  char volatile *t = (char*)s;\n  for (uptr i = 0; i < n; ++i, ++t) {\n    *t = c;\n  }\n  return s;\n}\n\nuptr internal_strcspn(const char *s, const char *reject) {\n  uptr i;\n  for (i = 0; s[i]; i++) {\n    if (internal_strchr(reject, s[i]))\n      return i;\n  }\n  return i;\n}\n\nchar* internal_strdup(const char *s) {\n  uptr len = internal_strlen(s);\n  char *s2 = (char*)InternalAlloc(len + 1);\n  internal_memcpy(s2, s, len);\n  s2[len] = 0;\n  return s2;\n}\n\nchar* internal_strndup(const char *s, uptr n) {\n  uptr len = internal_strnlen(s, n);\n  char *s2 = (char*)InternalAlloc(len + 1);\n  internal_memcpy(s2, s, len);\n  s2[len] = 0;\n  return s2;\n}\n\nint internal_strcmp(const char *s1, const char *s2) {\n  while (true) {\n    unsigned c1 = *s1;\n    unsigned c2 = *s2;\n    if (c1 != c2) return (c1 < c2) ? -1 : 1;\n    if (c1 == 0) break;\n    s1++;\n    s2++;\n  }\n  return 0;\n}\n\nint internal_strncmp(const char *s1, const char *s2, uptr n) {\n  for (uptr i = 0; i < n; i++) {\n    unsigned c1 = *s1;\n    unsigned c2 = *s2;\n    if (c1 != c2) return (c1 < c2) ? -1 : 1;\n    if (c1 == 0) break;\n    s1++;\n    s2++;\n  }\n  return 0;\n}\n\nchar* internal_strchr(const char *s, int c) {\n  while (true) {\n    if (*s == (char)c)\n      return const_cast<char *>(s);\n    if (*s == 0)\n      return nullptr;\n    s++;\n  }\n}\n\nchar *internal_strchrnul(const char *s, int c) {\n  char *res = internal_strchr(s, c);\n  if (!res)\n    res = const_cast<char *>(s) + internal_strlen(s);\n  return res;\n}\n\nchar *internal_strrchr(const char *s, int c) {\n  const char *res = nullptr;\n  for (uptr i = 0; s[i]; i++) {\n    if (s[i] == c) res = s + i;\n  }\n  return const_cast<char *>(res);\n}\n\nuptr internal_strlen(const char *s) {\n  uptr i = 0;\n  while (s[i]) i++;\n  return i;\n}\n\nuptr internal_strlcat(char *dst, const char *src, uptr maxlen) {\n  const uptr srclen = internal_strlen(src);\n  const uptr dstlen = internal_strnlen(dst, maxlen);\n  if (dstlen == maxlen) return maxlen + srclen;\n  if (srclen < maxlen - dstlen) {\n    internal_memmove(dst + dstlen, src, srclen + 1);\n  } else {\n    internal_memmove(dst + dstlen, src, maxlen - dstlen - 1);\n    dst[maxlen - 1] = '\\0';\n  }\n  return dstlen + srclen;\n}\n\nchar *internal_strncat(char *dst, const char *src, uptr n) {\n  uptr len = internal_strlen(dst);\n  uptr i;\n  for (i = 0; i < n && src[i]; i++)\n    dst[len + i] = src[i];\n  dst[len + i] = 0;\n  return dst;\n}\n\nuptr internal_strlcpy(char *dst, const char *src, uptr maxlen) {\n  const uptr srclen = internal_strlen(src);\n  if (srclen < maxlen) {\n    internal_memmove(dst, src, srclen + 1);\n  } else if (maxlen != 0) {\n    internal_memmove(dst, src, maxlen - 1);\n    dst[maxlen - 1] = '\\0';\n  }\n  return srclen;\n}\n\nchar *internal_strncpy(char *dst, const char *src, uptr n) {\n  uptr i;\n  for (i = 0; i < n && src[i]; i++)\n    dst[i] = src[i];\n  internal_memset(dst + i, '\\0', n - i);\n  return dst;\n}\n\nuptr internal_strnlen(const char *s, uptr maxlen) {\n  uptr i = 0;\n  while (i < maxlen && s[i]) i++;\n  return i;\n}\n\nchar *internal_strstr(const char *haystack, const char *needle) {\n  // This is O(N^2), but we are not using it in hot places.\n  uptr len1 = internal_strlen(haystack);\n  uptr len2 = internal_strlen(needle);\n  if (len1 < len2) return nullptr;\n  for (uptr pos = 0; pos <= len1 - len2; pos++) {\n    if (internal_memcmp(haystack + pos, needle, len2) == 0)\n      return const_cast<char *>(haystack) + pos;\n  }\n  return nullptr;\n}\n\ns64 internal_simple_strtoll(const char *nptr, char **endptr, int base) {\n  CHECK_EQ(base, 10);\n  while (IsSpace(*nptr)) nptr++;\n  int sgn = 1;\n  u64 res = 0;\n  bool have_digits = false;\n  char *old_nptr = const_cast<char *>(nptr);\n  if (*nptr == '+') {\n    sgn = 1;\n    nptr++;\n  } else if (*nptr == '-') {\n    sgn = -1;\n    nptr++;\n  }\n  while (IsDigit(*nptr)) {\n    res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX;\n    int digit = ((*nptr) - '0');\n    res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX;\n    have_digits = true;\n    nptr++;\n  }\n  if (endptr) {\n    *endptr = (have_digits) ? const_cast<char *>(nptr) : old_nptr;\n  }\n  if (sgn > 0) {\n    return (s64)(Min((u64)INT64_MAX, res));\n  } else {\n    return (res > INT64_MAX) ? INT64_MIN : ((s64)res * -1);\n  }\n}\n\nbool mem_is_zero(const char *beg, uptr size) {\n  CHECK_LE(size, 1ULL << FIRST_32_SECOND_64(30, 40));  // Sanity check.\n  const char *end = beg + size;\n  uptr *aligned_beg = (uptr *)RoundUpTo((uptr)beg, sizeof(uptr));\n  uptr *aligned_end = (uptr *)RoundDownTo((uptr)end, sizeof(uptr));\n  uptr all = 0;\n  // Prologue.\n  for (const char *mem = beg; mem < (char*)aligned_beg && mem < end; mem++)\n    all |= *mem;\n  // Aligned loop.\n  for (; aligned_beg < aligned_end; aligned_beg++)\n    all |= *aligned_beg;\n  // Epilogue.\n  if ((char*)aligned_end >= beg)\n    for (const char *mem = (char*)aligned_end; mem < end; mem++)\n      all |= *mem;\n  return all == 0;\n}\n\n} // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_libc.h",
    "content": "//===-- sanitizer_libc.h ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n// These tools can not use some of the libc functions directly because those\n// functions are intercepted. Instead, we implement a tiny subset of libc here.\n// FIXME: Some of functions declared in this file are in fact POSIX, not libc.\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_LIBC_H\n#define SANITIZER_LIBC_H\n\n// ----------- ATTENTION -------------\n// This header should NOT include any other headers from sanitizer runtime.\n#include \"sanitizer_internal_defs.h\"\n\nnamespace __sanitizer {\n\n// internal_X() is a custom implementation of X() for use in RTL.\n\n// String functions\ns64 internal_atoll(const char *nptr);\nvoid *internal_memchr(const void *s, int c, uptr n);\nvoid *internal_memrchr(const void *s, int c, uptr n);\nint internal_memcmp(const void* s1, const void* s2, uptr n);\nvoid *internal_memcpy(void *dest, const void *src, uptr n);\nvoid *internal_memmove(void *dest, const void *src, uptr n);\n// Set [s, s + n) to 0. Both s and n should be 16-aligned.\nvoid internal_bzero_aligned16(void *s, uptr n);\n// Should not be used in performance-critical places.\nvoid *internal_memset(void *s, int c, uptr n);\nchar* internal_strchr(const char *s, int c);\nchar *internal_strchrnul(const char *s, int c);\nint internal_strcmp(const char *s1, const char *s2);\nuptr internal_strcspn(const char *s, const char *reject);\nchar *internal_strdup(const char *s);\nchar *internal_strndup(const char *s, uptr n);\nuptr internal_strlen(const char *s);\nuptr internal_strlcat(char *dst, const char *src, uptr maxlen);\nchar *internal_strncat(char *dst, const char *src, uptr n);\nint internal_strncmp(const char *s1, const char *s2, uptr n);\nuptr internal_strlcpy(char *dst, const char *src, uptr maxlen);\nchar *internal_strncpy(char *dst, const char *src, uptr n);\nuptr internal_strnlen(const char *s, uptr maxlen);\nchar *internal_strrchr(const char *s, int c);\n// This is O(N^2), but we are not using it in hot places.\nchar *internal_strstr(const char *haystack, const char *needle);\n// Works only for base=10 and doesn't set errno.\ns64 internal_simple_strtoll(const char *nptr, char **endptr, int base);\nint internal_snprintf(char *buffer, uptr length, const char *format, ...);\n\n// Return true if all bytes in [mem, mem+size) are zero.\n// Optimized for the case when the result is true.\nbool mem_is_zero(const char *mem, uptr size);\n\n// I/O\nconst fd_t kInvalidFd = (fd_t)-1;\nconst fd_t kStdinFd = 0;\nconst fd_t kStdoutFd = (fd_t)1;\nconst fd_t kStderrFd = (fd_t)2;\n\nuptr internal_ftruncate(fd_t fd, uptr size);\n\n// OS\nvoid NORETURN internal__exit(int exitcode);\n\nuptr internal_getpid();\nuptr internal_getppid();\n\n// Threading\nuptr internal_sched_yield();\n\n// Error handling\nbool internal_iserror(uptr retval, int *rverrno = nullptr);\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_LIBC_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cc",
    "content": "//===-- sanitizer_libignore.cc --------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n\n#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC\n\n#include \"sanitizer_libignore.h\"\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_posix.h\"\n#include \"sanitizer_procmaps.h\"\n\nnamespace __sanitizer {\n\nLibIgnore::LibIgnore(LinkerInitialized) {\n}\n\nvoid LibIgnore::AddIgnoredLibrary(const char *name_templ) {\n  BlockingMutexLock lock(&mutex_);\n  if (count_ >= kMaxLibs) {\n    Report(\"%s: too many ignored libraries (max: %d)\\n\", SanitizerToolName,\n           kMaxLibs);\n    Die();\n  }\n  Lib *lib = &libs_[count_++];\n  lib->templ = internal_strdup(name_templ);\n  lib->name = nullptr;\n  lib->real_name = nullptr;\n  lib->loaded = false;\n}\n\nvoid LibIgnore::OnLibraryLoaded(const char *name) {\n  BlockingMutexLock lock(&mutex_);\n  // Try to match suppressions with symlink target.\n  InternalScopedString buf(kMaxPathLength);\n  if (name && internal_readlink(name, buf.data(), buf.size() - 1) > 0 &&\n      buf[0]) {\n    for (uptr i = 0; i < count_; i++) {\n      Lib *lib = &libs_[i];\n      if (!lib->loaded && (!lib->real_name) &&\n          TemplateMatch(lib->templ, name))\n        lib->real_name = internal_strdup(buf.data());\n    }\n  }\n\n  // Scan suppressions list and find newly loaded and unloaded libraries.\n  MemoryMappingLayout proc_maps(/*cache_enabled*/false);\n  InternalScopedString module(kMaxPathLength);\n  for (uptr i = 0; i < count_; i++) {\n    Lib *lib = &libs_[i];\n    bool loaded = false;\n    proc_maps.Reset();\n    uptr b, e, off, prot;\n    while (proc_maps.Next(&b, &e, &off, module.data(), module.size(), &prot)) {\n      if ((prot & MemoryMappingLayout::kProtectionExecute) == 0)\n        continue;\n      if (TemplateMatch(lib->templ, module.data()) ||\n          (lib->real_name &&\n          internal_strcmp(lib->real_name, module.data()) == 0)) {\n        if (loaded) {\n          Report(\"%s: called_from_lib suppression '%s' is matched against\"\n                 \" 2 libraries: '%s' and '%s'\\n\",\n                 SanitizerToolName, lib->templ, lib->name, module.data());\n          Die();\n        }\n        loaded = true;\n        if (lib->loaded)\n          continue;\n        VReport(1,\n                \"Matched called_from_lib suppression '%s' against library\"\n                \" '%s'\\n\",\n                lib->templ, module.data());\n        lib->loaded = true;\n        lib->name = internal_strdup(module.data());\n        const uptr idx = atomic_load(&loaded_count_, memory_order_relaxed);\n        code_ranges_[idx].begin = b;\n        code_ranges_[idx].end = e;\n        atomic_store(&loaded_count_, idx + 1, memory_order_release);\n      }\n    }\n    if (lib->loaded && !loaded) {\n      Report(\"%s: library '%s' that was matched against called_from_lib\"\n             \" suppression '%s' is unloaded\\n\",\n             SanitizerToolName, lib->name, lib->templ);\n      Die();\n    }\n  }\n}\n\nvoid LibIgnore::OnLibraryUnloaded() {\n  OnLibraryLoaded(nullptr);\n}\n\n} // namespace __sanitizer\n\n#endif // #if SANITIZER_FREEBSD || SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h",
    "content": "//===-- sanitizer_libignore.h -----------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// LibIgnore allows to ignore all interceptors called from a particular set\n// of dynamic libraries. LibIgnore can be initialized with several templates\n// of names of libraries to be ignored. It finds code ranges for the libraries;\n// and checks whether the provided PC value belongs to the code ranges.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_LIBIGNORE_H\n#define SANITIZER_LIBIGNORE_H\n\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_common.h\"\n#include \"sanitizer_atomic.h\"\n#include \"sanitizer_mutex.h\"\n\nnamespace __sanitizer {\n\nclass LibIgnore {\n public:\n  explicit LibIgnore(LinkerInitialized);\n\n  // Must be called during initialization.\n  void AddIgnoredLibrary(const char *name_templ);\n\n  // Must be called after a new dynamic library is loaded.\n  void OnLibraryLoaded(const char *name);\n\n  // Must be called after a dynamic library is unloaded.\n  void OnLibraryUnloaded();\n\n  // Checks whether the provided PC belongs to one of the ignored libraries.\n  bool IsIgnored(uptr pc) const;\n\n private:\n  struct Lib {\n    char *templ;\n    char *name;\n    char *real_name;  // target of symlink\n    bool loaded;\n  };\n\n  struct LibCodeRange {\n    uptr begin;\n    uptr end;\n  };\n\n  static const uptr kMaxLibs = 128;\n\n  // Hot part:\n  atomic_uintptr_t loaded_count_;\n  LibCodeRange code_ranges_[kMaxLibs];\n\n  // Cold part:\n  BlockingMutex mutex_;\n  uptr count_;\n  Lib libs_[kMaxLibs];\n\n  // Disallow copying of LibIgnore objects.\n  LibIgnore(const LibIgnore&);  // not implemented\n  void operator = (const LibIgnore&);  // not implemented\n};\n\ninline bool LibIgnore::IsIgnored(uptr pc) const {\n  const uptr n = atomic_load(&loaded_count_, memory_order_acquire);\n  for (uptr i = 0; i < n; i++) {\n    if (pc >= code_ranges_[i].begin && pc < code_ranges_[i].end)\n      return true;\n  }\n  return false;\n}\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_LIBIGNORE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc",
    "content": "//===-- sanitizer_linux.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries and implements linux-specific functions from\n// sanitizer_libc.h.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n\n#if SANITIZER_FREEBSD || SANITIZER_LINUX\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_linux.h\"\n#include \"sanitizer_mutex.h\"\n#include \"sanitizer_placement_new.h\"\n#include \"sanitizer_procmaps.h\"\n#include \"sanitizer_stacktrace.h\"\n#include \"sanitizer_symbolizer.h\"\n\n#if !SANITIZER_FREEBSD\n#include <asm/param.h>\n#endif\n\n// For mips64, syscall(__NR_stat) fills the buffer in the 'struct kernel_stat'\n// format. Struct kernel_stat is defined as 'struct stat' in asm/stat.h. To\n// access stat from asm/stat.h, without conflicting with definition in\n// sys/stat.h, we use this trick.\n#if defined(__mips64)\n#include <asm/unistd.h>\n#include <sys/types.h>\n#define stat kernel_stat\n#include <asm/stat.h>\n#undef stat\n#endif\n\n#include <dlfcn.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <link.h>\n#include <pthread.h>\n#include <sched.h>\n#include <sys/mman.h>\n#include <sys/ptrace.h>\n#include <sys/resource.h>\n#include <sys/stat.h>\n#include <sys/syscall.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <ucontext.h>\n#include <unistd.h>\n\n#if SANITIZER_FREEBSD\n#include <sys/sysctl.h>\n#include <machine/atomic.h>\nextern \"C\" {\n// <sys/umtx.h> must be included after <errno.h> and <sys/types.h> on\n// FreeBSD 9.2 and 10.0.\n#include <sys/umtx.h>\n}\nextern char **environ;  // provided by crt1\n#endif  // SANITIZER_FREEBSD\n\n#if !SANITIZER_ANDROID\n#include <sys/signal.h>\n#endif\n\n#if SANITIZER_LINUX\n// <linux/time.h>\nstruct kernel_timeval {\n  long tv_sec;\n  long tv_usec;\n};\n\n// <linux/futex.h> is broken on some linux distributions.\nconst int FUTEX_WAIT = 0;\nconst int FUTEX_WAKE = 1;\n#endif  // SANITIZER_LINUX\n\n// Are we using 32-bit or 64-bit Linux syscalls?\n// x32 (which defines __x86_64__) has SANITIZER_WORDSIZE == 32\n// but it still needs to use 64-bit syscalls.\n#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__powerpc64__) || \\\n    SANITIZER_WORDSIZE == 64)\n# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 1\n#else\n# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0\n#endif\n\nnamespace __sanitizer {\n\n#if SANITIZER_LINUX && defined(__x86_64__)\n#include \"sanitizer_syscall_linux_x86_64.inc\"\n#elif SANITIZER_LINUX && defined(__aarch64__)\n#include \"sanitizer_syscall_linux_aarch64.inc\"\n#else\n#include \"sanitizer_syscall_generic.inc\"\n#endif\n\n// --------------- sanitizer_libc.h\nuptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,\n                   OFF_T offset) {\n#if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS\n  return internal_syscall(SYSCALL(mmap), (uptr)addr, length, prot, flags, fd,\n                          offset);\n#else\n  // mmap2 specifies file offset in 4096-byte units.\n  CHECK(IsAligned(offset, 4096));\n  return internal_syscall(SYSCALL(mmap2), addr, length, prot, flags, fd,\n                          offset / 4096);\n#endif\n}\n\nuptr internal_munmap(void *addr, uptr length) {\n  return internal_syscall(SYSCALL(munmap), (uptr)addr, length);\n}\n\nint internal_mprotect(void *addr, uptr length, int prot) {\n  return internal_syscall(SYSCALL(mprotect), (uptr)addr, length, prot);\n}\n\nuptr internal_close(fd_t fd) {\n  return internal_syscall(SYSCALL(close), fd);\n}\n\nuptr internal_open(const char *filename, int flags) {\n#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS\n  return internal_syscall(SYSCALL(openat), AT_FDCWD, (uptr)filename, flags);\n#else\n  return internal_syscall(SYSCALL(open), (uptr)filename, flags);\n#endif\n}\n\nuptr internal_open(const char *filename, int flags, u32 mode) {\n#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS\n  return internal_syscall(SYSCALL(openat), AT_FDCWD, (uptr)filename, flags,\n                          mode);\n#else\n  return internal_syscall(SYSCALL(open), (uptr)filename, flags, mode);\n#endif\n}\n\nuptr internal_read(fd_t fd, void *buf, uptr count) {\n  sptr res;\n  HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(read), fd, (uptr)buf,\n               count));\n  return res;\n}\n\nuptr internal_write(fd_t fd, const void *buf, uptr count) {\n  sptr res;\n  HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(write), fd, (uptr)buf,\n               count));\n  return res;\n}\n\nuptr internal_ftruncate(fd_t fd, uptr size) {\n  sptr res;\n  HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(ftruncate), fd,\n               (OFF_T)size));\n  return res;\n}\n\n#if !SANITIZER_LINUX_USES_64BIT_SYSCALLS && !SANITIZER_FREEBSD\nstatic void stat64_to_stat(struct stat64 *in, struct stat *out) {\n  internal_memset(out, 0, sizeof(*out));\n  out->st_dev = in->st_dev;\n  out->st_ino = in->st_ino;\n  out->st_mode = in->st_mode;\n  out->st_nlink = in->st_nlink;\n  out->st_uid = in->st_uid;\n  out->st_gid = in->st_gid;\n  out->st_rdev = in->st_rdev;\n  out->st_size = in->st_size;\n  out->st_blksize = in->st_blksize;\n  out->st_blocks = in->st_blocks;\n  out->st_atime = in->st_atime;\n  out->st_mtime = in->st_mtime;\n  out->st_ctime = in->st_ctime;\n  out->st_ino = in->st_ino;\n}\n#endif\n\n#if defined(__mips64)\nstatic void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) {\n  internal_memset(out, 0, sizeof(*out));\n  out->st_dev = in->st_dev;\n  out->st_ino = in->st_ino;\n  out->st_mode = in->st_mode;\n  out->st_nlink = in->st_nlink;\n  out->st_uid = in->st_uid;\n  out->st_gid = in->st_gid;\n  out->st_rdev = in->st_rdev;\n  out->st_size = in->st_size;\n  out->st_blksize = in->st_blksize;\n  out->st_blocks = in->st_blocks;\n  out->st_atime = in->st_atime_nsec;\n  out->st_mtime = in->st_mtime_nsec;\n  out->st_ctime = in->st_ctime_nsec;\n  out->st_ino = in->st_ino;\n}\n#endif\n\nuptr internal_stat(const char *path, void *buf) {\n#if SANITIZER_FREEBSD\n  return internal_syscall(SYSCALL(stat), path, buf);\n#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS\n  return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path,\n                          (uptr)buf, 0);\n#elif SANITIZER_LINUX_USES_64BIT_SYSCALLS\n# if defined(__mips64)\n  // For mips64, stat syscall fills buffer in the format of kernel_stat\n  struct kernel_stat kbuf;\n  int res = internal_syscall(SYSCALL(stat), path, &kbuf);\n  kernel_stat_to_stat(&kbuf, (struct stat *)buf);\n  return res;\n# else\n  return internal_syscall(SYSCALL(stat), (uptr)path, (uptr)buf);\n# endif\n#else\n  struct stat64 buf64;\n  int res = internal_syscall(SYSCALL(stat64), path, &buf64);\n  stat64_to_stat(&buf64, (struct stat *)buf);\n  return res;\n#endif\n}\n\nuptr internal_lstat(const char *path, void *buf) {\n#if SANITIZER_FREEBSD\n  return internal_syscall(SYSCALL(lstat), path, buf);\n#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS\n  return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path,\n                         (uptr)buf, AT_SYMLINK_NOFOLLOW);\n#elif SANITIZER_LINUX_USES_64BIT_SYSCALLS\n  return internal_syscall(SYSCALL(lstat), (uptr)path, (uptr)buf);\n#else\n  struct stat64 buf64;\n  int res = internal_syscall(SYSCALL(lstat64), path, &buf64);\n  stat64_to_stat(&buf64, (struct stat *)buf);\n  return res;\n#endif\n}\n\nuptr internal_fstat(fd_t fd, void *buf) {\n#if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS\n  return internal_syscall(SYSCALL(fstat), fd, (uptr)buf);\n#else\n  struct stat64 buf64;\n  int res = internal_syscall(SYSCALL(fstat64), fd, &buf64);\n  stat64_to_stat(&buf64, (struct stat *)buf);\n  return res;\n#endif\n}\n\nuptr internal_filesize(fd_t fd) {\n  struct stat st;\n  if (internal_fstat(fd, &st))\n    return -1;\n  return (uptr)st.st_size;\n}\n\nuptr internal_dup2(int oldfd, int newfd) {\n#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS\n  return internal_syscall(SYSCALL(dup3), oldfd, newfd, 0);\n#else\n  return internal_syscall(SYSCALL(dup2), oldfd, newfd);\n#endif\n}\n\nuptr internal_readlink(const char *path, char *buf, uptr bufsize) {\n#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS\n  return internal_syscall(SYSCALL(readlinkat), AT_FDCWD,\n                          (uptr)path, (uptr)buf, bufsize);\n#else\n  return internal_syscall(SYSCALL(readlink), (uptr)path, (uptr)buf, bufsize);\n#endif\n}\n\nuptr internal_unlink(const char *path) {\n#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS\n  return internal_syscall(SYSCALL(unlinkat), AT_FDCWD, (uptr)path, 0);\n#else\n  return internal_syscall(SYSCALL(unlink), (uptr)path);\n#endif\n}\n\nuptr internal_rename(const char *oldpath, const char *newpath) {\n#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS\n  return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD,\n                          (uptr)newpath);\n#else\n  return internal_syscall(SYSCALL(rename), (uptr)oldpath, (uptr)newpath);\n#endif\n}\n\nuptr internal_sched_yield() {\n  return internal_syscall(SYSCALL(sched_yield));\n}\n\nvoid internal__exit(int exitcode) {\n#if SANITIZER_FREEBSD\n  internal_syscall(SYSCALL(exit), exitcode);\n#else\n  internal_syscall(SYSCALL(exit_group), exitcode);\n#endif\n  Die();  // Unreachable.\n}\n\nuptr internal_execve(const char *filename, char *const argv[],\n                     char *const envp[]) {\n  return internal_syscall(SYSCALL(execve), (uptr)filename, (uptr)argv,\n                          (uptr)envp);\n}\n\n// ----------------- sanitizer_common.h\nbool FileExists(const char *filename) {\n  struct stat st;\n#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS\n  if (internal_syscall(SYSCALL(newfstatat), AT_FDCWD, filename, &st, 0))\n#else\n  if (internal_stat(filename, &st))\n#endif\n    return false;\n  // Sanity check: filename is a regular file.\n  return S_ISREG(st.st_mode);\n}\n\nuptr GetTid() {\n#if SANITIZER_FREEBSD\n  return (uptr)pthread_self();\n#else\n  return internal_syscall(SYSCALL(gettid));\n#endif\n}\n\nu64 NanoTime() {\n#if SANITIZER_FREEBSD\n  timeval tv;\n#else\n  kernel_timeval tv;\n#endif\n  internal_memset(&tv, 0, sizeof(tv));\n  internal_syscall(SYSCALL(gettimeofday), (uptr)&tv, 0);\n  return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000;\n}\n\n// Like getenv, but reads env directly from /proc (on Linux) or parses the\n// 'environ' array (on FreeBSD) and does not use libc. This function should be\n// called first inside __asan_init.\nconst char *GetEnv(const char *name) {\n#if SANITIZER_FREEBSD\n  if (::environ != 0) {\n    uptr NameLen = internal_strlen(name);\n    for (char **Env = ::environ; *Env != 0; Env++) {\n      if (internal_strncmp(*Env, name, NameLen) == 0 && (*Env)[NameLen] == '=')\n        return (*Env) + NameLen + 1;\n    }\n  }\n  return 0;  // Not found.\n#elif SANITIZER_LINUX\n  static char *environ;\n  static uptr len;\n  static bool inited;\n  if (!inited) {\n    inited = true;\n    uptr environ_size;\n    if (!ReadFileToBuffer(\"/proc/self/environ\", &environ, &environ_size, &len))\n      environ = nullptr;\n  }\n  if (!environ || len == 0) return nullptr;\n  uptr namelen = internal_strlen(name);\n  const char *p = environ;\n  while (*p != '\\0') {  // will happen at the \\0\\0 that terminates the buffer\n    // proc file has the format NAME=value\\0NAME=value\\0NAME=value\\0...\n    const char* endp =\n        (char*)internal_memchr(p, '\\0', len - (p - environ));\n    if (!endp)  // this entry isn't NUL terminated\n      return nullptr;\n    else if (!internal_memcmp(p, name, namelen) && p[namelen] == '=')  // Match.\n      return p + namelen + 1;  // point after =\n    p = endp + 1;\n  }\n  return nullptr;  // Not found.\n#else\n#error \"Unsupported platform\"\n#endif\n}\n\nextern \"C\" {\n  SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end;\n}\n\n#if !SANITIZER_GO\nstatic void ReadNullSepFileToArray(const char *path, char ***arr,\n                                   int arr_size) {\n  char *buff;\n  uptr buff_size;\n  uptr buff_len;\n  *arr = (char **)MmapOrDie(arr_size * sizeof(char *), \"NullSepFileArray\");\n  if (!ReadFileToBuffer(path, &buff, &buff_size, &buff_len, 1024 * 1024)) {\n    (*arr)[0] = nullptr;\n    return;\n  }\n  (*arr)[0] = buff;\n  int count, i;\n  for (count = 1, i = 1; ; i++) {\n    if (buff[i] == 0) {\n      if (buff[i+1] == 0) break;\n      (*arr)[count] = &buff[i+1];\n      CHECK_LE(count, arr_size - 1);  // FIXME: make this more flexible.\n      count++;\n    }\n  }\n  (*arr)[count] = nullptr;\n}\n#endif\n\nstatic void GetArgsAndEnv(char*** argv, char*** envp) {\n#if !SANITIZER_GO\n  if (&__libc_stack_end) {\n#endif\n    uptr* stack_end = (uptr*)__libc_stack_end;\n    int argc = *stack_end;\n    *argv = (char**)(stack_end + 1);\n    *envp = (char**)(stack_end + argc + 2);\n#if !SANITIZER_GO\n  } else {\n    static const int kMaxArgv = 2000, kMaxEnvp = 2000;\n    ReadNullSepFileToArray(\"/proc/self/cmdline\", argv, kMaxArgv);\n    ReadNullSepFileToArray(\"/proc/self/environ\", envp, kMaxEnvp);\n  }\n#endif\n}\n\nvoid ReExec() {\n  char **argv, **envp;\n  GetArgsAndEnv(&argv, &envp);\n  uptr rv = internal_execve(\"/proc/self/exe\", argv, envp);\n  int rverrno;\n  CHECK_EQ(internal_iserror(rv, &rverrno), true);\n  Printf(\"execve failed, errno %d\\n\", rverrno);\n  Die();\n}\n\nenum MutexState {\n  MtxUnlocked = 0,\n  MtxLocked = 1,\n  MtxSleeping = 2\n};\n\nBlockingMutex::BlockingMutex() {\n  internal_memset(this, 0, sizeof(*this));\n}\n\nvoid BlockingMutex::Lock() {\n  CHECK_EQ(owner_, 0);\n  atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);\n  if (atomic_exchange(m, MtxLocked, memory_order_acquire) == MtxUnlocked)\n    return;\n  while (atomic_exchange(m, MtxSleeping, memory_order_acquire) != MtxUnlocked) {\n#if SANITIZER_FREEBSD\n    _umtx_op(m, UMTX_OP_WAIT_UINT, MtxSleeping, 0, 0);\n#else\n    internal_syscall(SYSCALL(futex), (uptr)m, FUTEX_WAIT, MtxSleeping, 0, 0, 0);\n#endif\n  }\n}\n\nvoid BlockingMutex::Unlock() {\n  atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);\n  u32 v = atomic_exchange(m, MtxUnlocked, memory_order_relaxed);\n  CHECK_NE(v, MtxUnlocked);\n  if (v == MtxSleeping) {\n#if SANITIZER_FREEBSD\n    _umtx_op(m, UMTX_OP_WAKE, 1, 0, 0);\n#else\n    internal_syscall(SYSCALL(futex), (uptr)m, FUTEX_WAKE, 1, 0, 0, 0);\n#endif\n  }\n}\n\nvoid BlockingMutex::CheckLocked() {\n  atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);\n  CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed));\n}\n\n// ----------------- sanitizer_linux.h\n// The actual size of this structure is specified by d_reclen.\n// Note that getdents64 uses a different structure format. We only provide the\n// 32-bit syscall here.\nstruct linux_dirent {\n#if SANITIZER_X32 || defined(__aarch64__)\n  u64 d_ino;\n  u64 d_off;\n#else\n  unsigned long      d_ino;\n  unsigned long      d_off;\n#endif\n  unsigned short     d_reclen;\n#ifdef __aarch64__\n  unsigned char      d_type;\n#endif\n  char               d_name[256];\n};\n\n// Syscall wrappers.\nuptr internal_ptrace(int request, int pid, void *addr, void *data) {\n  return internal_syscall(SYSCALL(ptrace), request, pid, (uptr)addr,\n                          (uptr)data);\n}\n\nuptr internal_waitpid(int pid, int *status, int options) {\n  return internal_syscall(SYSCALL(wait4), pid, (uptr)status, options,\n                          0 /* rusage */);\n}\n\nuptr internal_getpid() {\n  return internal_syscall(SYSCALL(getpid));\n}\n\nuptr internal_getppid() {\n  return internal_syscall(SYSCALL(getppid));\n}\n\nuptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) {\n#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS\n  return internal_syscall(SYSCALL(getdents64), fd, (uptr)dirp, count);\n#else\n  return internal_syscall(SYSCALL(getdents), fd, (uptr)dirp, count);\n#endif\n}\n\nuptr internal_lseek(fd_t fd, OFF_T offset, int whence) {\n  return internal_syscall(SYSCALL(lseek), fd, offset, whence);\n}\n\n#if SANITIZER_LINUX\nuptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) {\n  return internal_syscall(SYSCALL(prctl), option, arg2, arg3, arg4, arg5);\n}\n#endif\n\nuptr internal_sigaltstack(const struct sigaltstack *ss,\n                         struct sigaltstack *oss) {\n  return internal_syscall(SYSCALL(sigaltstack), (uptr)ss, (uptr)oss);\n}\n\nint internal_fork() {\n#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS\n  return internal_syscall(SYSCALL(clone), SIGCHLD, 0);\n#else\n  return internal_syscall(SYSCALL(fork));\n#endif\n}\n\n#if SANITIZER_LINUX\n#define SA_RESTORER 0x04000000\n// Doesn't set sa_restorer, use with caution (see below).\nint internal_sigaction_norestorer(int signum, const void *act, void *oldact) {\n  __sanitizer_kernel_sigaction_t k_act, k_oldact;\n  internal_memset(&k_act, 0, sizeof(__sanitizer_kernel_sigaction_t));\n  internal_memset(&k_oldact, 0, sizeof(__sanitizer_kernel_sigaction_t));\n  const __sanitizer_sigaction *u_act = (const __sanitizer_sigaction *)act;\n  __sanitizer_sigaction *u_oldact = (__sanitizer_sigaction *)oldact;\n  if (u_act) {\n    k_act.handler = u_act->handler;\n    k_act.sigaction = u_act->sigaction;\n    internal_memcpy(&k_act.sa_mask, &u_act->sa_mask,\n                    sizeof(__sanitizer_kernel_sigset_t));\n    // Without SA_RESTORER kernel ignores the calls (probably returns EINVAL).\n    k_act.sa_flags = u_act->sa_flags | SA_RESTORER;\n    // FIXME: most often sa_restorer is unset, however the kernel requires it\n    // to point to a valid signal restorer that calls the rt_sigreturn syscall.\n    // If sa_restorer passed to the kernel is NULL, the program may crash upon\n    // signal delivery or fail to unwind the stack in the signal handler.\n    // libc implementation of sigaction() passes its own restorer to\n    // rt_sigaction, so we need to do the same (we'll need to reimplement the\n    // restorers; for x86_64 the restorer address can be obtained from\n    // oldact->sa_restorer upon a call to sigaction(xxx, NULL, oldact).\n    k_act.sa_restorer = u_act->sa_restorer;\n  }\n\n  uptr result = internal_syscall(SYSCALL(rt_sigaction), (uptr)signum,\n      (uptr)(u_act ? &k_act : nullptr),\n      (uptr)(u_oldact ? &k_oldact : nullptr),\n      (uptr)sizeof(__sanitizer_kernel_sigset_t));\n\n  if ((result == 0) && u_oldact) {\n    u_oldact->handler = k_oldact.handler;\n    u_oldact->sigaction = k_oldact.sigaction;\n    internal_memcpy(&u_oldact->sa_mask, &k_oldact.sa_mask,\n                    sizeof(__sanitizer_kernel_sigset_t));\n    u_oldact->sa_flags = k_oldact.sa_flags;\n    u_oldact->sa_restorer = k_oldact.sa_restorer;\n  }\n  return result;\n}\n#endif  // SANITIZER_LINUX\n\nuptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,\n    __sanitizer_sigset_t *oldset) {\n#if SANITIZER_FREEBSD\n  return internal_syscall(SYSCALL(sigprocmask), how, set, oldset);\n#else\n  __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;\n  __sanitizer_kernel_sigset_t *k_oldset = (__sanitizer_kernel_sigset_t *)oldset;\n  return internal_syscall(SYSCALL(rt_sigprocmask), (uptr)how,\n                          (uptr)&k_set->sig[0], (uptr)&k_oldset->sig[0],\n                          sizeof(__sanitizer_kernel_sigset_t));\n#endif\n}\n\nvoid internal_sigfillset(__sanitizer_sigset_t *set) {\n  internal_memset(set, 0xff, sizeof(*set));\n}\n\n#if SANITIZER_LINUX\nvoid internal_sigdelset(__sanitizer_sigset_t *set, int signum) {\n  signum -= 1;\n  CHECK_GE(signum, 0);\n  CHECK_LT(signum, sizeof(*set) * 8);\n  __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;\n  const uptr idx = signum / (sizeof(k_set->sig[0]) * 8);\n  const uptr bit = signum % (sizeof(k_set->sig[0]) * 8);\n  k_set->sig[idx] &= ~(1 << bit);\n}\n#endif  // SANITIZER_LINUX\n\n// ThreadLister implementation.\nThreadLister::ThreadLister(int pid)\n  : pid_(pid),\n    descriptor_(-1),\n    buffer_(4096),\n    error_(true),\n    entry_((struct linux_dirent *)buffer_.data()),\n    bytes_read_(0) {\n  char task_directory_path[80];\n  internal_snprintf(task_directory_path, sizeof(task_directory_path),\n                    \"/proc/%d/task/\", pid);\n  uptr openrv = internal_open(task_directory_path, O_RDONLY | O_DIRECTORY);\n  if (internal_iserror(openrv)) {\n    error_ = true;\n    Report(\"Can't open /proc/%d/task for reading.\\n\", pid);\n  } else {\n    error_ = false;\n    descriptor_ = openrv;\n  }\n}\n\nint ThreadLister::GetNextTID() {\n  int tid = -1;\n  do {\n    if (error_)\n      return -1;\n    if ((char *)entry_ >= &buffer_[bytes_read_] && !GetDirectoryEntries())\n      return -1;\n    if (entry_->d_ino != 0 && entry_->d_name[0] >= '0' &&\n        entry_->d_name[0] <= '9') {\n      // Found a valid tid.\n      tid = (int)internal_atoll(entry_->d_name);\n    }\n    entry_ = (struct linux_dirent *)(((char *)entry_) + entry_->d_reclen);\n  } while (tid < 0);\n  return tid;\n}\n\nvoid ThreadLister::Reset() {\n  if (error_ || descriptor_ < 0)\n    return;\n  internal_lseek(descriptor_, 0, SEEK_SET);\n}\n\nThreadLister::~ThreadLister() {\n  if (descriptor_ >= 0)\n    internal_close(descriptor_);\n}\n\nbool ThreadLister::error() { return error_; }\n\nbool ThreadLister::GetDirectoryEntries() {\n  CHECK_GE(descriptor_, 0);\n  CHECK_NE(error_, true);\n  bytes_read_ = internal_getdents(descriptor_,\n                                  (struct linux_dirent *)buffer_.data(),\n                                  buffer_.size());\n  if (internal_iserror(bytes_read_)) {\n    Report(\"Can't read directory entries from /proc/%d/task.\\n\", pid_);\n    error_ = true;\n    return false;\n  } else if (bytes_read_ == 0) {\n    return false;\n  }\n  entry_ = (struct linux_dirent *)buffer_.data();\n  return true;\n}\n\nuptr GetPageSize() {\n#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__i386__))\n  return EXEC_PAGESIZE;\n#else\n  return sysconf(_SC_PAGESIZE);  // EXEC_PAGESIZE may not be trustworthy.\n#endif\n}\n\nuptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {\n#if SANITIZER_FREEBSD\n  const int Mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };\n  const char *default_module_name = \"kern.proc.pathname\";\n  size_t Size = buf_len;\n  bool IsErr = (sysctl(Mib, ARRAY_SIZE(Mib), buf, &Size, NULL, 0) != 0);\n  int readlink_error = IsErr ? errno : 0;\n  uptr module_name_len = Size;\n#else\n  const char *default_module_name = \"/proc/self/exe\";\n  uptr module_name_len = internal_readlink(\n      default_module_name, buf, buf_len);\n  int readlink_error;\n  bool IsErr = internal_iserror(module_name_len, &readlink_error);\n#endif\n  if (IsErr) {\n    // We can't read binary name for some reason, assume it's unknown.\n    Report(\"WARNING: reading executable name failed with errno %d, \"\n           \"some stack frames may not be symbolized\\n\", readlink_error);\n    module_name_len = internal_snprintf(buf, buf_len, \"%s\",\n                                        default_module_name);\n    CHECK_LT(module_name_len, buf_len);\n  }\n  return module_name_len;\n}\n\nuptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) {\n#if SANITIZER_LINUX\n  char *tmpbuf;\n  uptr tmpsize;\n  uptr tmplen;\n  if (ReadFileToBuffer(\"/proc/self/cmdline\", &tmpbuf, &tmpsize, &tmplen,\n                       1024 * 1024)) {\n    internal_strncpy(buf, tmpbuf, buf_len);\n    UnmapOrDie(tmpbuf, tmpsize);\n    return internal_strlen(buf);\n  }\n#endif\n  return ReadBinaryName(buf, buf_len);\n}\n\n// Match full names of the form /path/to/base_name{-,.}*\nbool LibraryNameIs(const char *full_name, const char *base_name) {\n  const char *name = full_name;\n  // Strip path.\n  while (*name != '\\0') name++;\n  while (name > full_name && *name != '/') name--;\n  if (*name == '/') name++;\n  uptr base_name_length = internal_strlen(base_name);\n  if (internal_strncmp(name, base_name, base_name_length)) return false;\n  return (name[base_name_length] == '-' || name[base_name_length] == '.');\n}\n\n#if !SANITIZER_ANDROID\n// Call cb for each region mapped by map.\nvoid ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)) {\n  CHECK_NE(map, nullptr);\n#if !SANITIZER_FREEBSD\n  typedef ElfW(Phdr) Elf_Phdr;\n  typedef ElfW(Ehdr) Elf_Ehdr;\n#endif  // !SANITIZER_FREEBSD\n  char *base = (char *)map->l_addr;\n  Elf_Ehdr *ehdr = (Elf_Ehdr *)base;\n  char *phdrs = base + ehdr->e_phoff;\n  char *phdrs_end = phdrs + ehdr->e_phnum * ehdr->e_phentsize;\n\n  // Find the segment with the minimum base so we can \"relocate\" the p_vaddr\n  // fields.  Typically ET_DYN objects (DSOs) have base of zero and ET_EXEC\n  // objects have a non-zero base.\n  uptr preferred_base = (uptr)-1;\n  for (char *iter = phdrs; iter != phdrs_end; iter += ehdr->e_phentsize) {\n    Elf_Phdr *phdr = (Elf_Phdr *)iter;\n    if (phdr->p_type == PT_LOAD && preferred_base > (uptr)phdr->p_vaddr)\n      preferred_base = (uptr)phdr->p_vaddr;\n  }\n\n  // Compute the delta from the real base to get a relocation delta.\n  sptr delta = (uptr)base - preferred_base;\n  // Now we can figure out what the loader really mapped.\n  for (char *iter = phdrs; iter != phdrs_end; iter += ehdr->e_phentsize) {\n    Elf_Phdr *phdr = (Elf_Phdr *)iter;\n    if (phdr->p_type == PT_LOAD) {\n      uptr seg_start = phdr->p_vaddr + delta;\n      uptr seg_end = seg_start + phdr->p_memsz;\n      // None of these values are aligned.  We consider the ragged edges of the\n      // load command as defined, since they are mapped from the file.\n      seg_start = RoundDownTo(seg_start, GetPageSizeCached());\n      seg_end = RoundUpTo(seg_end, GetPageSizeCached());\n      cb((void *)seg_start, seg_end - seg_start);\n    }\n  }\n}\n#endif\n\n#if defined(__x86_64__) && SANITIZER_LINUX\n// We cannot use glibc's clone wrapper, because it messes with the child\n// task's TLS. It writes the PID and TID of the child task to its thread\n// descriptor, but in our case the child task shares the thread descriptor with\n// the parent (because we don't know how to allocate a new thread\n// descriptor to keep glibc happy). So the stock version of clone(), when\n// used with CLONE_VM, would end up corrupting the parent's thread descriptor.\nuptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,\n                    int *parent_tidptr, void *newtls, int *child_tidptr) {\n  long long res;\n  if (!fn || !child_stack)\n    return -EINVAL;\n  CHECK_EQ(0, (uptr)child_stack % 16);\n  child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);\n  ((unsigned long long *)child_stack)[0] = (uptr)fn;\n  ((unsigned long long *)child_stack)[1] = (uptr)arg;\n  register void *r8 __asm__(\"r8\") = newtls;\n  register int *r10 __asm__(\"r10\") = child_tidptr;\n  __asm__ __volatile__(\n                       /* %rax = syscall(%rax = SYSCALL(clone),\n                        *                %rdi = flags,\n                        *                %rsi = child_stack,\n                        *                %rdx = parent_tidptr,\n                        *                %r8  = new_tls,\n                        *                %r10 = child_tidptr)\n                        */\n                       \"syscall\\n\"\n\n                       /* if (%rax != 0)\n                        *   return;\n                        */\n                       \"testq  %%rax,%%rax\\n\"\n                       \"jnz    1f\\n\"\n\n                       /* In the child. Terminate unwind chain. */\n                       // XXX: We should also terminate the CFI unwind chain\n                       // here. Unfortunately clang 3.2 doesn't support the\n                       // necessary CFI directives, so we skip that part.\n                       \"xorq   %%rbp,%%rbp\\n\"\n\n                       /* Call \"fn(arg)\". */\n                       \"popq   %%rax\\n\"\n                       \"popq   %%rdi\\n\"\n                       \"call   *%%rax\\n\"\n\n                       /* Call _exit(%rax). */\n                       \"movq   %%rax,%%rdi\\n\"\n                       \"movq   %2,%%rax\\n\"\n                       \"syscall\\n\"\n\n                       /* Return to parent. */\n                     \"1:\\n\"\n                       : \"=a\" (res)\n                       : \"a\"(SYSCALL(clone)), \"i\"(SYSCALL(exit)),\n                         \"S\"(child_stack),\n                         \"D\"(flags),\n                         \"d\"(parent_tidptr),\n                         \"r\"(r8),\n                         \"r\"(r10)\n                       : \"rsp\", \"memory\", \"r11\", \"rcx\");\n  return res;\n}\n#elif defined(__mips__)\nuptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,\n                    int *parent_tidptr, void *newtls, int *child_tidptr) {\n  long long res;\n  if (!fn || !child_stack)\n    return -EINVAL;\n  CHECK_EQ(0, (uptr)child_stack % 16);\n  child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);\n  ((unsigned long long *)child_stack)[0] = (uptr)fn;\n  ((unsigned long long *)child_stack)[1] = (uptr)arg;\n  register void *a3 __asm__(\"$7\") = newtls;\n  register int *a4 __asm__(\"$8\") = child_tidptr;\n  // We don't have proper CFI directives here because it requires alot of code\n  // for very marginal benefits.\n  __asm__ __volatile__(\n                       /* $v0 = syscall($v0 = __NR_clone,\n                        * $a0 = flags,\n                        * $a1 = child_stack,\n                        * $a2 = parent_tidptr,\n                        * $a3 = new_tls,\n                        * $a4 = child_tidptr)\n                        */\n                       \".cprestore 16;\\n\"\n                       \"move $4,%1;\\n\"\n                       \"move $5,%2;\\n\"\n                       \"move $6,%3;\\n\"\n                       \"move $7,%4;\\n\"\n                       /* Store the fifth argument on stack\n                        * if we are using 32-bit abi.\n                        */\n#if SANITIZER_WORDSIZE == 32\n                       \"lw %5,16($29);\\n\"\n#else\n                       \"move $8,%5;\\n\"\n#endif\n                       \"li $2,%6;\\n\"\n                       \"syscall;\\n\"\n\n                       /* if ($v0 != 0)\n                        * return;\n                        */\n                       \"bnez $2,1f;\\n\"\n\n                       /* Call \"fn(arg)\". */\n                       \"ld $25,0($29);\\n\"\n                       \"ld $4,8($29);\\n\"\n                       \"jal $25;\\n\"\n\n                       /* Call _exit($v0). */\n                       \"move $4,$2;\\n\"\n                       \"li $2,%7;\\n\"\n                       \"syscall;\\n\"\n\n                       /* Return to parent. */\n                     \"1:\\n\"\n                       : \"=r\" (res)\n                       : \"r\"(flags),\n                         \"r\"(child_stack),\n                         \"r\"(parent_tidptr),\n                         \"r\"(a3),\n                         \"r\"(a4),\n                         \"i\"(__NR_clone),\n                         \"i\"(__NR_exit)\n                       : \"memory\", \"$29\" );\n  return res;\n}\n#elif defined(__aarch64__)\nuptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,\n                    int *parent_tidptr, void *newtls, int *child_tidptr) {\n  long long res;\n  if (!fn || !child_stack)\n    return -EINVAL;\n  CHECK_EQ(0, (uptr)child_stack % 16);\n  child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);\n  ((unsigned long long *)child_stack)[0] = (uptr)fn;\n  ((unsigned long long *)child_stack)[1] = (uptr)arg;\n\n  register int (*__fn)(void *)  __asm__(\"x0\") = fn;\n  register void *__stack __asm__(\"x1\") = child_stack;\n  register int   __flags __asm__(\"x2\") = flags;\n  register void *__arg   __asm__(\"x3\") = arg;\n  register int  *__ptid  __asm__(\"x4\") = parent_tidptr;\n  register void *__tls   __asm__(\"x5\") = newtls;\n  register int  *__ctid  __asm__(\"x6\") = child_tidptr;\n\n  __asm__ __volatile__(\n                       \"mov x0,x2\\n\" /* flags  */\n                       \"mov x2,x4\\n\" /* ptid  */\n                       \"mov x3,x5\\n\" /* tls  */\n                       \"mov x4,x6\\n\" /* ctid  */\n                       \"mov x8,%9\\n\" /* clone  */\n\n                       \"svc 0x0\\n\"\n\n                       /* if (%r0 != 0)\n                        *   return %r0;\n                        */\n                       \"cmp x0, #0\\n\"\n                       \"bne 1f\\n\"\n\n                       /* In the child, now. Call \"fn(arg)\". */\n                       \"ldp x1, x0, [sp], #16\\n\"\n                       \"blr x1\\n\"\n\n                       /* Call _exit(%r0).  */\n                       \"mov x8, %10\\n\"\n                       \"svc 0x0\\n\"\n                     \"1:\\n\"\n\n                       : \"=r\" (res)\n                       : \"i\"(-EINVAL),\n                         \"r\"(__fn), \"r\"(__stack), \"r\"(__flags), \"r\"(__arg),\n                         \"r\"(__ptid), \"r\"(__tls), \"r\"(__ctid),\n                         \"i\"(__NR_clone), \"i\"(__NR_exit)\n                       : \"x30\", \"memory\");\n  return res;\n}\n#elif defined(__powerpc64__)\nuptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,\n                   int *parent_tidptr, void *newtls, int *child_tidptr) {\n  long long res;\n/* Stack frame offsets.  */\n#if _CALL_ELF != 2\n#define FRAME_MIN_SIZE         112\n#define FRAME_TOC_SAVE         40\n#else\n#define FRAME_MIN_SIZE         32\n#define FRAME_TOC_SAVE         24\n#endif\n  if (!fn || !child_stack)\n    return -EINVAL;\n  CHECK_EQ(0, (uptr)child_stack % 16);\n  child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);\n  ((unsigned long long *)child_stack)[0] = (uptr)fn;\n  ((unsigned long long *)child_stack)[1] = (uptr)arg;\n\n  register int (*__fn)(void *) __asm__(\"r3\") = fn;\n  register void *__cstack      __asm__(\"r4\") = child_stack;\n  register int __flags         __asm__(\"r5\") = flags;\n  register void * __arg        __asm__(\"r6\") = arg;\n  register int * __ptidptr     __asm__(\"r7\") = parent_tidptr;\n  register void * __newtls     __asm__(\"r8\") = newtls;\n  register int * __ctidptr     __asm__(\"r9\") = child_tidptr;\n\n __asm__ __volatile__(\n           /* fn, arg, child_stack are saved acrVoss the syscall */\n           \"mr 28, %5\\n\\t\"\n           \"mr 29, %6\\n\\t\"\n           \"mr 27, %8\\n\\t\"\n\n           /* syscall\n             r3 == flags\n             r4 == child_stack\n             r5 == parent_tidptr\n             r6 == newtls\n             r7 == child_tidptr */\n           \"mr 3, %7\\n\\t\"\n           \"mr 5, %9\\n\\t\"\n           \"mr 6, %10\\n\\t\"\n           \"mr 7, %11\\n\\t\"\n           \"li 0, %3\\n\\t\"\n           \"sc\\n\\t\"\n\n           /* Test if syscall was successful */\n           \"cmpdi  cr1, 3, 0\\n\\t\"\n           \"crandc cr1*4+eq, cr1*4+eq, cr0*4+so\\n\\t\"\n           \"bne-   cr1, 1f\\n\\t\"\n\n           /* Do the function call */\n           \"std   2, %13(1)\\n\\t\"\n#if _CALL_ELF != 2\n           \"ld    0, 0(28)\\n\\t\"\n           \"ld    2, 8(28)\\n\\t\"\n           \"mtctr 0\\n\\t\"\n#else\n           \"mr    12, 28\\n\\t\"\n           \"mtctr 12\\n\\t\"\n#endif\n           \"mr    3, 27\\n\\t\"\n           \"bctrl\\n\\t\"\n           \"ld    2, %13(1)\\n\\t\"\n\n           /* Call _exit(r3) */\n           \"li 0, %4\\n\\t\"\n           \"sc\\n\\t\"\n\n           /* Return to parent */\n           \"1:\\n\\t\"\n           \"mr %0, 3\\n\\t\"\n             : \"=r\" (res)\n             : \"0\" (-1), \"i\" (EINVAL),\n               \"i\" (__NR_clone), \"i\" (__NR_exit),\n               \"r\" (__fn), \"r\" (__cstack), \"r\" (__flags),\n               \"r\" (__arg), \"r\" (__ptidptr), \"r\" (__newtls),\n               \"r\" (__ctidptr), \"i\" (FRAME_MIN_SIZE), \"i\" (FRAME_TOC_SAVE)\n             : \"cr0\", \"cr1\", \"memory\", \"ctr\",\n               \"r0\", \"r29\", \"r27\", \"r28\");\n  return res;\n}\n#endif  // defined(__x86_64__) && SANITIZER_LINUX\n\n#if SANITIZER_ANDROID\n#if __ANDROID_API__ < 21\nextern \"C\" __attribute__((weak)) int dl_iterate_phdr(\n    int (*)(struct dl_phdr_info *, size_t, void *), void *);\n#endif\n\nstatic int dl_iterate_phdr_test_cb(struct dl_phdr_info *info, size_t size,\n                                   void *data) {\n  // Any name starting with \"lib\" indicates a bug in L where library base names\n  // are returned instead of paths.\n  if (info->dlpi_name && info->dlpi_name[0] == 'l' &&\n      info->dlpi_name[1] == 'i' && info->dlpi_name[2] == 'b') {\n    *(bool *)data = true;\n    return 1;\n  }\n  return 0;\n}\n\nstatic atomic_uint32_t android_api_level;\n\nstatic AndroidApiLevel AndroidDetectApiLevel() {\n  if (!&dl_iterate_phdr)\n    return ANDROID_KITKAT; // K or lower\n  bool base_name_seen = false;\n  dl_iterate_phdr(dl_iterate_phdr_test_cb, &base_name_seen);\n  if (base_name_seen)\n    return ANDROID_LOLLIPOP_MR1; // L MR1\n  return ANDROID_POST_LOLLIPOP;   // post-L\n  // Plain L (API level 21) is completely broken wrt ASan and not very\n  // interesting to detect.\n}\n\nAndroidApiLevel AndroidGetApiLevel() {\n  AndroidApiLevel level =\n      (AndroidApiLevel)atomic_load(&android_api_level, memory_order_relaxed);\n  if (level) return level;\n  level = AndroidDetectApiLevel();\n  atomic_store(&android_api_level, level, memory_order_relaxed);\n  return level;\n}\n\n#endif\n\nbool IsDeadlySignal(int signum) {\n  if (common_flags()->handle_abort && signum == SIGABRT)\n    return true;\n  if (common_flags()->handle_sigill && signum == SIGILL)\n    return true;\n  if (common_flags()->handle_sigfpe && signum == SIGFPE)\n    return true;\n  return (signum == SIGSEGV || signum == SIGBUS) && common_flags()->handle_segv;\n}\n\n#ifndef SANITIZER_GO\nvoid *internal_start_thread(void(*func)(void *arg), void *arg) {\n  // Start the thread with signals blocked, otherwise it can steal user signals.\n  __sanitizer_sigset_t set, old;\n  internal_sigfillset(&set);\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n  // Glibc uses SIGSETXID signal during setuid call. If this signal is blocked\n  // on any thread, setuid call hangs (see test/tsan/setuid.c).\n  internal_sigdelset(&set, 33);\n#endif\n  internal_sigprocmask(SIG_SETMASK, &set, &old);\n  void *th;\n  real_pthread_create(&th, nullptr, (void*(*)(void *arg))func, arg);\n  internal_sigprocmask(SIG_SETMASK, &old, nullptr);\n  return th;\n}\n\nvoid internal_join_thread(void *th) {\n  real_pthread_join(th, nullptr);\n}\n#else\nvoid *internal_start_thread(void (*func)(void *), void *arg) { return 0; }\n\nvoid internal_join_thread(void *th) {}\n#endif\n\nvoid GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {\n#if defined(__arm__)\n  ucontext_t *ucontext = (ucontext_t*)context;\n  *pc = ucontext->uc_mcontext.arm_pc;\n  *bp = ucontext->uc_mcontext.arm_fp;\n  *sp = ucontext->uc_mcontext.arm_sp;\n#elif defined(__aarch64__)\n  ucontext_t *ucontext = (ucontext_t*)context;\n  *pc = ucontext->uc_mcontext.pc;\n  *bp = ucontext->uc_mcontext.regs[29];\n  *sp = ucontext->uc_mcontext.sp;\n#elif defined(__hppa__)\n  ucontext_t *ucontext = (ucontext_t*)context;\n  *pc = ucontext->uc_mcontext.sc_iaoq[0];\n  /* GCC uses %r3 whenever a frame pointer is needed.  */\n  *bp = ucontext->uc_mcontext.sc_gr[3];\n  *sp = ucontext->uc_mcontext.sc_gr[30];\n#elif defined(__x86_64__)\n# if SANITIZER_FREEBSD\n  ucontext_t *ucontext = (ucontext_t*)context;\n  *pc = ucontext->uc_mcontext.mc_rip;\n  *bp = ucontext->uc_mcontext.mc_rbp;\n  *sp = ucontext->uc_mcontext.mc_rsp;\n# else\n  ucontext_t *ucontext = (ucontext_t*)context;\n  *pc = ucontext->uc_mcontext.gregs[REG_RIP];\n  *bp = ucontext->uc_mcontext.gregs[REG_RBP];\n  *sp = ucontext->uc_mcontext.gregs[REG_RSP];\n# endif\n#elif defined(__i386__)\n# if SANITIZER_FREEBSD\n  ucontext_t *ucontext = (ucontext_t*)context;\n  *pc = ucontext->uc_mcontext.mc_eip;\n  *bp = ucontext->uc_mcontext.mc_ebp;\n  *sp = ucontext->uc_mcontext.mc_esp;\n# else\n  ucontext_t *ucontext = (ucontext_t*)context;\n  *pc = ucontext->uc_mcontext.gregs[REG_EIP];\n  *bp = ucontext->uc_mcontext.gregs[REG_EBP];\n  *sp = ucontext->uc_mcontext.gregs[REG_ESP];\n# endif\n#elif defined(__powerpc__) || defined(__powerpc64__)\n  ucontext_t *ucontext = (ucontext_t*)context;\n  *pc = ucontext->uc_mcontext.regs->nip;\n  *sp = ucontext->uc_mcontext.regs->gpr[PT_R1];\n  // The powerpc{,64}-linux ABIs do not specify r31 as the frame\n  // pointer, but GCC always uses r31 when we need a frame pointer.\n  *bp = ucontext->uc_mcontext.regs->gpr[PT_R31];\n#elif defined(__sparc__)\n  ucontext_t *ucontext = (ucontext_t*)context;\n  uptr *stk_ptr;\n# if defined (__arch64__)\n  *pc = ucontext->uc_mcontext.mc_gregs[MC_PC];\n  *sp = ucontext->uc_mcontext.mc_gregs[MC_O6];\n  stk_ptr = (uptr *) (*sp + 2047);\n  *bp = stk_ptr[15];\n# else\n  *pc = ucontext->uc_mcontext.gregs[REG_PC];\n  *sp = ucontext->uc_mcontext.gregs[REG_O6];\n  stk_ptr = (uptr *) *sp;\n  *bp = stk_ptr[15];\n# endif\n#elif defined(__mips__)\n  ucontext_t *ucontext = (ucontext_t*)context;\n  *pc = ucontext->uc_mcontext.pc;\n  *bp = ucontext->uc_mcontext.gregs[30];\n  *sp = ucontext->uc_mcontext.gregs[29];\n#else\n# error \"Unsupported arch\"\n#endif\n}\n\nvoid DisableReexec() {\n  // No need to re-exec on Linux.\n}\n\nvoid MaybeReexec() {\n  // No need to re-exec on Linux.\n}\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_FREEBSD || SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_linux.h",
    "content": "//===-- sanitizer_linux.h ---------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Linux-specific syscall wrappers and classes.\n//\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_LINUX_H\n#define SANITIZER_LINUX_H\n\n#include \"sanitizer_platform.h\"\n#if SANITIZER_FREEBSD || SANITIZER_LINUX\n#include \"sanitizer_common.h\"\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_posix.h\"\n#include \"sanitizer_platform_limits_posix.h\"\n\nstruct link_map;  // Opaque type returned by dlopen().\nstruct sigaltstack;\n\nnamespace __sanitizer {\n// Dirent structure for getdents(). Note that this structure is different from\n// the one in <dirent.h>, which is used by readdir().\nstruct linux_dirent;\n\n// Syscall wrappers.\nuptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count);\nuptr internal_sigaltstack(const struct sigaltstack* ss,\n                          struct sigaltstack* oss);\nuptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,\n    __sanitizer_sigset_t *oldset);\nvoid internal_sigfillset(__sanitizer_sigset_t *set);\n\n// Linux-only syscalls.\n#if SANITIZER_LINUX\nuptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5);\n// Used only by sanitizer_stoptheworld. Signal handlers that are actually used\n// (like the process-wide error reporting SEGV handler) must use\n// internal_sigaction instead.\nint internal_sigaction_norestorer(int signum, const void *act, void *oldact);\nvoid internal_sigdelset(__sanitizer_sigset_t *set, int signum);\n#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) \\\n  || defined(__powerpc64__)\nuptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,\n                    int *parent_tidptr, void *newtls, int *child_tidptr);\n#endif\n#endif  // SANITIZER_LINUX\n\n// This class reads thread IDs from /proc/<pid>/task using only syscalls.\nclass ThreadLister {\n public:\n  explicit ThreadLister(int pid);\n  ~ThreadLister();\n  // GetNextTID returns -1 if the list of threads is exhausted, or if there has\n  // been an error.\n  int GetNextTID();\n  void Reset();\n  bool error();\n\n private:\n  bool GetDirectoryEntries();\n\n  int pid_;\n  int descriptor_;\n  InternalScopedBuffer<char> buffer_;\n  bool error_;\n  struct linux_dirent* entry_;\n  int bytes_read_;\n};\n\n// Exposed for testing.\nuptr ThreadDescriptorSize();\nuptr ThreadSelf();\nuptr ThreadSelfOffset();\n\n// Matches a library's file name against a base name (stripping path and version\n// information).\nbool LibraryNameIs(const char *full_name, const char *base_name);\n\n// Call cb for each region mapped by map.\nvoid ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX\n#endif  // SANITIZER_LINUX_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc",
    "content": "//===-- sanitizer_linux_libcdep.cc ----------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries and implements linux-specific functions from\n// sanitizer_libc.h.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n\n#if SANITIZER_FREEBSD || SANITIZER_LINUX\n\n#include \"sanitizer_allocator_internal.h\"\n#include \"sanitizer_atomic.h\"\n#include \"sanitizer_common.h\"\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_freebsd.h\"\n#include \"sanitizer_linux.h\"\n#include \"sanitizer_placement_new.h\"\n#include \"sanitizer_procmaps.h\"\n#include \"sanitizer_stacktrace.h\"\n\n#if SANITIZER_ANDROID || SANITIZER_FREEBSD\n#include <dlfcn.h>  // for dlsym()\n#endif\n\n#include <link.h>\n#include <pthread.h>\n#include <signal.h>\n#include <sys/resource.h>\n\n#if SANITIZER_FREEBSD\n#include <pthread_np.h>\n#include <osreldate.h>\n#define pthread_getattr_np pthread_attr_get_np\n#endif\n\n#if SANITIZER_LINUX\n#include <sys/prctl.h>\n#endif\n\n#if SANITIZER_ANDROID\n#include <android/api-level.h>\n#endif\n\n#if SANITIZER_ANDROID && __ANDROID_API__ < 21\n#include <android/log.h>\n#else\n#include <syslog.h>\n#endif\n\n#if !SANITIZER_ANDROID\n#include <elf.h>\n#include <unistd.h>\n#endif\n\nnamespace __sanitizer {\n\nSANITIZER_WEAK_ATTRIBUTE int\nreal_sigaction(int signum, const void *act, void *oldact);\n\nint internal_sigaction(int signum, const void *act, void *oldact) {\n#if !SANITIZER_GO\n  if (&real_sigaction)\n    return real_sigaction(signum, act, oldact);\n#endif\n  return sigaction(signum, (const struct sigaction *)act,\n                   (struct sigaction *)oldact);\n}\n\nvoid GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,\n                                uptr *stack_bottom) {\n  CHECK(stack_top);\n  CHECK(stack_bottom);\n  if (at_initialization) {\n    // This is the main thread. Libpthread may not be initialized yet.\n    struct rlimit rl;\n    CHECK_EQ(getrlimit(RLIMIT_STACK, &rl), 0);\n\n    // Find the mapping that contains a stack variable.\n    MemoryMappingLayout proc_maps(/*cache_enabled*/true);\n    uptr start, end, offset;\n    uptr prev_end = 0;\n    while (proc_maps.Next(&start, &end, &offset, nullptr, 0,\n          /* protection */nullptr)) {\n      if ((uptr)&rl < end)\n        break;\n      prev_end = end;\n    }\n    CHECK((uptr)&rl >= start && (uptr)&rl < end);\n\n    // Get stacksize from rlimit, but clip it so that it does not overlap\n    // with other mappings.\n    uptr stacksize = rl.rlim_cur;\n    if (stacksize > end - prev_end)\n      stacksize = end - prev_end;\n    // When running with unlimited stack size, we still want to set some limit.\n    // The unlimited stack size is caused by 'ulimit -s unlimited'.\n    // Also, for some reason, GNU make spawns subprocesses with unlimited stack.\n    if (stacksize > kMaxThreadStackSize)\n      stacksize = kMaxThreadStackSize;\n    *stack_top = end;\n    *stack_bottom = end - stacksize;\n    return;\n  }\n  pthread_attr_t attr;\n  pthread_attr_init(&attr);\n  CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0);\n  uptr stacksize = 0;\n  void *stackaddr = nullptr;\n  my_pthread_attr_getstack(&attr, &stackaddr, &stacksize);\n  pthread_attr_destroy(&attr);\n\n  CHECK_LE(stacksize, kMaxThreadStackSize);  // Sanity check.\n  *stack_top = (uptr)stackaddr + stacksize;\n  *stack_bottom = (uptr)stackaddr;\n}\n\n#if !SANITIZER_GO\nbool SetEnv(const char *name, const char *value) {\n  void *f = dlsym(RTLD_NEXT, \"setenv\");\n  if (!f)\n    return false;\n  typedef int(*setenv_ft)(const char *name, const char *value, int overwrite);\n  setenv_ft setenv_f;\n  CHECK_EQ(sizeof(setenv_f), sizeof(f));\n  internal_memcpy(&setenv_f, &f, sizeof(f));\n  return setenv_f(name, value, 1) == 0;\n}\n#endif\n\nbool SanitizerSetThreadName(const char *name) {\n#ifdef PR_SET_NAME\n  return 0 == prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);  // NOLINT\n#else\n  return false;\n#endif\n}\n\nbool SanitizerGetThreadName(char *name, int max_len) {\n#ifdef PR_GET_NAME\n  char buff[17];\n  if (prctl(PR_GET_NAME, (unsigned long)buff, 0, 0, 0))  // NOLINT\n    return false;\n  internal_strncpy(name, buff, max_len);\n  name[max_len] = 0;\n  return true;\n#else\n  return false;\n#endif\n}\n\n#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO\nstatic uptr g_tls_size;\n#endif\n\n#ifdef __i386__\n# define DL_INTERNAL_FUNCTION __attribute__((regparm(3), stdcall))\n#else\n# define DL_INTERNAL_FUNCTION\n#endif\n\n#if defined(__mips__) || defined(__powerpc64__)\n// TlsPreTcbSize includes size of struct pthread_descr and size of tcb\n// head structure. It lies before the static tls blocks.\nstatic uptr TlsPreTcbSize() {\n# if defined(__mips__)\n  const uptr kTcbHead = 16; // sizeof (tcbhead_t)\n# elif defined(__powerpc64__)\n  const uptr kTcbHead = 88; // sizeof (tcbhead_t)\n# endif\n  const uptr kTlsAlign = 16;\n  const uptr kTlsPreTcbSize =\n    (ThreadDescriptorSize() + kTcbHead + kTlsAlign - 1) & ~(kTlsAlign - 1);\n  InitTlsSize();\n  g_tls_size = (g_tls_size + kTlsPreTcbSize + kTlsAlign -1) & ~(kTlsAlign - 1);\n  return kTlsPreTcbSize;\n}\n#endif\n\nvoid InitTlsSize() {\n#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO\n// all current supported platforms have 16 bytes stack alignment\n  const size_t kStackAlign = 16;\n  typedef void (*get_tls_func)(size_t*, size_t*) DL_INTERNAL_FUNCTION;\n  get_tls_func get_tls;\n  void *get_tls_static_info_ptr = dlsym(RTLD_NEXT, \"_dl_get_tls_static_info\");\n  CHECK_EQ(sizeof(get_tls), sizeof(get_tls_static_info_ptr));\n  internal_memcpy(&get_tls, &get_tls_static_info_ptr,\n                  sizeof(get_tls_static_info_ptr));\n  CHECK_NE(get_tls, 0);\n  size_t tls_size = 0;\n  size_t tls_align = 0;\n  get_tls(&tls_size, &tls_align);\n  if (tls_align < kStackAlign)\n    tls_align = kStackAlign;\n  g_tls_size = RoundUpTo(tls_size, tls_align);\n#endif  // !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO\n}\n\n#if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) \\\n    || defined(__aarch64__) || defined(__powerpc64__)) \\\n    && SANITIZER_LINUX && !SANITIZER_ANDROID\n// sizeof(struct pthread) from glibc.\nstatic atomic_uintptr_t kThreadDescriptorSize;\n\nuptr ThreadDescriptorSize() {\n  uptr val = atomic_load(&kThreadDescriptorSize, memory_order_relaxed);\n  if (val)\n    return val;\n#if defined(__x86_64__) || defined(__i386__)\n#ifdef _CS_GNU_LIBC_VERSION\n  char buf[64];\n  uptr len = confstr(_CS_GNU_LIBC_VERSION, buf, sizeof(buf));\n  if (len < sizeof(buf) && internal_strncmp(buf, \"glibc 2.\", 8) == 0) {\n    char *end;\n    int minor = internal_simple_strtoll(buf + 8, &end, 10);\n    if (end != buf + 8 && (*end == '\\0' || *end == '.')) {\n      /* sizeof(struct pthread) values from various glibc versions.  */\n      if (SANITIZER_X32)\n        val = 1728;  // Assume only one particular version for x32.\n      else if (minor <= 3)\n        val = FIRST_32_SECOND_64(1104, 1696);\n      else if (minor == 4)\n        val = FIRST_32_SECOND_64(1120, 1728);\n      else if (minor == 5)\n        val = FIRST_32_SECOND_64(1136, 1728);\n      else if (minor <= 9)\n        val = FIRST_32_SECOND_64(1136, 1712);\n      else if (minor == 10)\n        val = FIRST_32_SECOND_64(1168, 1776);\n      else if (minor <= 12)\n        val = FIRST_32_SECOND_64(1168, 2288);\n      else if (minor == 13)\n        val = FIRST_32_SECOND_64(1168, 2304);\n      else\n        val = FIRST_32_SECOND_64(1216, 2304);\n    }\n    if (val)\n      atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed);\n    return val;\n  }\n#endif\n#elif defined(__mips__)\n  // TODO(sagarthakur): add more values as per different glibc versions.\n  val = FIRST_32_SECOND_64(1152, 1776);\n  if (val)\n    atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed);\n  return val;\n#elif defined(__aarch64__)\n  // The sizeof (struct pthread) is the same from GLIBC 2.17 to 2.22.\n  val = 1776;\n  atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed);\n  return val;\n#elif defined(__powerpc64__)\n  val = 1776; // from glibc.ppc64le 2.20-8.fc21\n  atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed);\n  return val;\n#endif\n  return 0;\n}\n\n// The offset at which pointer to self is located in the thread descriptor.\nconst uptr kThreadSelfOffset = FIRST_32_SECOND_64(8, 16);\n\nuptr ThreadSelfOffset() {\n  return kThreadSelfOffset;\n}\n\nuptr ThreadSelf() {\n  uptr descr_addr;\n# if defined(__i386__)\n  asm(\"mov %%gs:%c1,%0\" : \"=r\"(descr_addr) : \"i\"(kThreadSelfOffset));\n# elif defined(__x86_64__)\n  asm(\"mov %%fs:%c1,%0\" : \"=r\"(descr_addr) : \"i\"(kThreadSelfOffset));\n# elif defined(__mips__)\n  // MIPS uses TLS variant I. The thread pointer (in hardware register $29)\n  // points to the end of the TCB + 0x7000. The pthread_descr structure is\n  // immediately in front of the TCB. TlsPreTcbSize() includes the size of the\n  // TCB and the size of pthread_descr.\n  const uptr kTlsTcbOffset = 0x7000;\n  uptr thread_pointer;\n  asm volatile(\".set push;\\\n                .set mips64r2;\\\n                rdhwr %0,$29;\\\n                .set pop\" : \"=r\" (thread_pointer));\n  descr_addr = thread_pointer - kTlsTcbOffset - TlsPreTcbSize();\n# elif defined(__aarch64__)\n  descr_addr = reinterpret_cast<uptr>(__builtin_thread_pointer());\n# elif defined(__powerpc64__)\n  // PPC64LE uses TLS variant I. The thread pointer (in GPR 13)\n  // points to the end of the TCB + 0x7000. The pthread_descr structure is\n  // immediately in front of the TCB. TlsPreTcbSize() includes the size of the\n  // TCB and the size of pthread_descr.\n  const uptr kTlsTcbOffset = 0x7000;\n  uptr thread_pointer;\n  asm(\"addi %0,13,%1\" : \"=r\"(thread_pointer) : \"I\"(-kTlsTcbOffset));\n  descr_addr = thread_pointer - TlsPreTcbSize();\n# else\n#  error \"unsupported CPU arch\"\n# endif\n  return descr_addr;\n}\n#endif  // (x86_64 || i386 || MIPS) && SANITIZER_LINUX\n\n#if SANITIZER_FREEBSD\nstatic void **ThreadSelfSegbase() {\n  void **segbase = 0;\n# if defined(__i386__)\n  // sysarch(I386_GET_GSBASE, segbase);\n  __asm __volatile(\"mov %%gs:0, %0\" : \"=r\" (segbase));\n# elif defined(__x86_64__)\n  // sysarch(AMD64_GET_FSBASE, segbase);\n  __asm __volatile(\"movq %%fs:0, %0\" : \"=r\" (segbase));\n# else\n#  error \"unsupported CPU arch for FreeBSD platform\"\n# endif\n  return segbase;\n}\n\nuptr ThreadSelf() {\n  return (uptr)ThreadSelfSegbase()[2];\n}\n#endif  // SANITIZER_FREEBSD\n\n#if !SANITIZER_GO\nstatic void GetTls(uptr *addr, uptr *size) {\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n# if defined(__x86_64__) || defined(__i386__)\n  *addr = ThreadSelf();\n  *size = GetTlsSize();\n  *addr -= *size;\n  *addr += ThreadDescriptorSize();\n# elif defined(__mips__) || defined(__aarch64__) || defined(__powerpc64__)\n  *addr = ThreadSelf();\n  *size = GetTlsSize();\n# else\n  *addr = 0;\n  *size = 0;\n# endif\n#elif SANITIZER_FREEBSD\n  void** segbase = ThreadSelfSegbase();\n  *addr = 0;\n  *size = 0;\n  if (segbase != 0) {\n    // tcbalign = 16\n    // tls_size = round(tls_static_space, tcbalign);\n    // dtv = segbase[1];\n    // dtv[2] = segbase - tls_static_space;\n    void **dtv = (void**) segbase[1];\n    *addr = (uptr) dtv[2];\n    *size = (*addr == 0) ? 0 : ((uptr) segbase[0] - (uptr) dtv[2]);\n  }\n#elif SANITIZER_ANDROID\n  *addr = 0;\n  *size = 0;\n#else\n# error \"Unknown OS\"\n#endif\n}\n#endif\n\n#if !SANITIZER_GO\nuptr GetTlsSize() {\n#if SANITIZER_FREEBSD || SANITIZER_ANDROID\n  uptr addr, size;\n  GetTls(&addr, &size);\n  return size;\n#else\n  return g_tls_size;\n#endif\n}\n#endif\n\nvoid GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,\n                          uptr *tls_addr, uptr *tls_size) {\n#if SANITIZER_GO\n  // Stub implementation for Go.\n  *stk_addr = *stk_size = *tls_addr = *tls_size = 0;\n#else\n  GetTls(tls_addr, tls_size);\n\n  uptr stack_top, stack_bottom;\n  GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);\n  *stk_addr = stack_bottom;\n  *stk_size = stack_top - stack_bottom;\n\n  if (!main) {\n    // If stack and tls intersect, make them non-intersecting.\n    if (*tls_addr > *stk_addr && *tls_addr < *stk_addr + *stk_size) {\n      CHECK_GT(*tls_addr + *tls_size, *stk_addr);\n      CHECK_LE(*tls_addr + *tls_size, *stk_addr + *stk_size);\n      *stk_size -= *tls_size;\n      *tls_addr = *stk_addr + *stk_size;\n    }\n  }\n#endif\n}\n\n# if !SANITIZER_FREEBSD\ntypedef ElfW(Phdr) Elf_Phdr;\n# elif SANITIZER_WORDSIZE == 32 && __FreeBSD_version <= 902001  // v9.2\n#  define Elf_Phdr XElf32_Phdr\n#  define dl_phdr_info xdl_phdr_info\n#  define dl_iterate_phdr(c, b) xdl_iterate_phdr((c), (b))\n# endif\n\nstruct DlIteratePhdrData {\n  LoadedModule *modules;\n  uptr current_n;\n  bool first;\n  uptr max_n;\n  string_predicate_t filter;\n};\n\nstatic int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {\n  DlIteratePhdrData *data = (DlIteratePhdrData*)arg;\n  if (data->current_n == data->max_n)\n    return 0;\n  InternalScopedString module_name(kMaxPathLength);\n  if (data->first) {\n    data->first = false;\n    // First module is the binary itself.\n    ReadBinaryNameCached(module_name.data(), module_name.size());\n  } else if (info->dlpi_name) {\n    module_name.append(\"%s\", info->dlpi_name);\n  }\n  if (module_name[0] == '\\0')\n    return 0;\n  if (data->filter && !data->filter(module_name.data()))\n    return 0;\n  LoadedModule *cur_module = &data->modules[data->current_n];\n  cur_module->set(module_name.data(), info->dlpi_addr);\n  data->current_n++;\n  for (int i = 0; i < info->dlpi_phnum; i++) {\n    const Elf_Phdr *phdr = &info->dlpi_phdr[i];\n    if (phdr->p_type == PT_LOAD) {\n      uptr cur_beg = info->dlpi_addr + phdr->p_vaddr;\n      uptr cur_end = cur_beg + phdr->p_memsz;\n      bool executable = phdr->p_flags & PF_X;\n      cur_module->addAddressRange(cur_beg, cur_end, executable);\n    }\n  }\n  return 0;\n}\n\n#if SANITIZER_ANDROID && __ANDROID_API__ < 21\nextern \"C\" __attribute__((weak)) int dl_iterate_phdr(\n    int (*)(struct dl_phdr_info *, size_t, void *), void *);\n#endif\n\nuptr GetListOfModules(LoadedModule *modules, uptr max_modules,\n                      string_predicate_t filter) {\n#if SANITIZER_ANDROID && __ANDROID_API__ <= 22\n  u32 api_level = AndroidGetApiLevel();\n  // Fall back to /proc/maps if dl_iterate_phdr is unavailable or broken.\n  // The runtime check allows the same library to work with\n  // both K and L (and future) Android releases.\n  if (api_level <= ANDROID_LOLLIPOP_MR1) { // L or earlier\n    MemoryMappingLayout memory_mapping(false);\n    return memory_mapping.DumpListOfModules(modules, max_modules, filter);\n  }\n#endif\n  CHECK(modules);\n  DlIteratePhdrData data = {modules, 0, true, max_modules, filter};\n  dl_iterate_phdr(dl_iterate_phdr_cb, &data);\n  return data.current_n;\n}\n\n// getrusage does not give us the current RSS, only the max RSS.\n// Still, this is better than nothing if /proc/self/statm is not available\n// for some reason, e.g. due to a sandbox.\nstatic uptr GetRSSFromGetrusage() {\n  struct rusage usage;\n  if (getrusage(RUSAGE_SELF, &usage))  // Failed, probably due to a sandbox.\n    return 0;\n  return usage.ru_maxrss << 10;  // ru_maxrss is in Kb.\n}\n\nuptr GetRSS() {\n  if (!common_flags()->can_use_proc_maps_statm)\n    return GetRSSFromGetrusage();\n  fd_t fd = OpenFile(\"/proc/self/statm\", RdOnly);\n  if (fd == kInvalidFd)\n    return GetRSSFromGetrusage();\n  char buf[64];\n  uptr len = internal_read(fd, buf, sizeof(buf) - 1);\n  internal_close(fd);\n  if ((sptr)len <= 0)\n    return 0;\n  buf[len] = 0;\n  // The format of the file is:\n  // 1084 89 69 11 0 79 0\n  // We need the second number which is RSS in pages.\n  char *pos = buf;\n  // Skip the first number.\n  while (*pos >= '0' && *pos <= '9')\n    pos++;\n  // Skip whitespaces.\n  while (!(*pos >= '0' && *pos <= '9') && *pos != 0)\n    pos++;\n  // Read the number.\n  uptr rss = 0;\n  while (*pos >= '0' && *pos <= '9')\n    rss = rss * 10 + *pos++ - '0';\n  return rss * GetPageSizeCached();\n}\n\n// 64-bit Android targets don't provide the deprecated __android_log_write.\n// Starting with the L release, syslog() works and is preferable to\n// __android_log_write.\n#if SANITIZER_LINUX\n\n#if SANITIZER_ANDROID\nstatic atomic_uint8_t android_log_initialized;\n\nvoid AndroidLogInit() {\n  atomic_store(&android_log_initialized, 1, memory_order_release);\n}\n\nbool ShouldLogAfterPrintf() {\n  return atomic_load(&android_log_initialized, memory_order_acquire);\n}\n#else\nvoid AndroidLogInit() {}\n\nbool ShouldLogAfterPrintf() { return true; }\n#endif  // SANITIZER_ANDROID\n\nvoid WriteOneLineToSyslog(const char *s) {\n#if SANITIZER_ANDROID &&__ANDROID_API__ < 21\n  __android_log_write(ANDROID_LOG_INFO, NULL, s);\n#else\n  syslog(LOG_INFO, \"%s\", s);\n#endif\n}\n\n#endif // SANITIZER_LINUX\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_FREEBSD || SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_list.h",
    "content": "//===-- sanitizer_list.h ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file contains implementation of a list class to be used by\n// ThreadSanitizer, etc run-times.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_LIST_H\n#define SANITIZER_LIST_H\n\n#include \"sanitizer_internal_defs.h\"\n\nnamespace __sanitizer {\n\n// Intrusive singly-linked list with size(), push_back(), push_front()\n// pop_front(), append_front() and append_back().\n// This class should be a POD (so that it can be put into TLS)\n// and an object with all zero fields should represent a valid empty list.\n// This class does not have a CTOR, so clear() should be called on all\n// non-zero-initialized objects before using.\ntemplate<class Item>\nstruct IntrusiveList {\n  friend class Iterator;\n\n  void clear() {\n    first_ = last_ = nullptr;\n    size_ = 0;\n  }\n\n  bool empty() const { return size_ == 0; }\n  uptr size() const { return size_; }\n\n  void push_back(Item *x) {\n    if (empty()) {\n      x->next = nullptr;\n      first_ = last_ = x;\n      size_ = 1;\n    } else {\n      x->next = nullptr;\n      last_->next = x;\n      last_ = x;\n      size_++;\n    }\n  }\n\n  void push_front(Item *x) {\n    if (empty()) {\n      x->next = nullptr;\n      first_ = last_ = x;\n      size_ = 1;\n    } else {\n      x->next = first_;\n      first_ = x;\n      size_++;\n    }\n  }\n\n  void pop_front() {\n    CHECK(!empty());\n    first_ = first_->next;\n    if (!first_)\n      last_ = nullptr;\n    size_--;\n  }\n\n  Item *front() { return first_; }\n  Item *back() { return last_; }\n\n  void append_front(IntrusiveList<Item> *l) {\n    CHECK_NE(this, l);\n    if (l->empty())\n      return;\n    if (empty()) {\n      *this = *l;\n    } else if (!l->empty()) {\n      l->last_->next = first_;\n      first_ = l->first_;\n      size_ += l->size();\n    }\n    l->clear();\n  }\n\n  void append_back(IntrusiveList<Item> *l) {\n    CHECK_NE(this, l);\n    if (l->empty())\n      return;\n    if (empty()) {\n      *this = *l;\n    } else {\n      last_->next = l->first_;\n      last_ = l->last_;\n      size_ += l->size();\n    }\n    l->clear();\n  }\n\n  void CheckConsistency() {\n    if (size_ == 0) {\n      CHECK_EQ(first_, 0);\n      CHECK_EQ(last_, 0);\n    } else {\n      uptr count = 0;\n      for (Item *i = first_; ; i = i->next) {\n        count++;\n        if (i == last_) break;\n      }\n      CHECK_EQ(size(), count);\n      CHECK_EQ(last_->next, 0);\n    }\n  }\n\n  template<class ListTy, class ItemTy>\n  class IteratorBase {\n   public:\n    explicit IteratorBase(ListTy *list)\n        : list_(list), current_(list->first_) { }\n    ItemTy *next() {\n      ItemTy *ret = current_;\n      if (current_) current_ = current_->next;\n      return ret;\n    }\n    bool hasNext() const { return current_ != nullptr; }\n   private:\n    ListTy *list_;\n    ItemTy *current_;\n  };\n\n  typedef IteratorBase<IntrusiveList<Item>, Item> Iterator;\n  typedef IteratorBase<const IntrusiveList<Item>, const Item> ConstIterator;\n\n// private, don't use directly.\n  uptr size_;\n  Item *first_;\n  Item *last_;\n};\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_LIST_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc",
    "content": "//===-- sanitizer_mac.cc --------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between various sanitizers' runtime libraries and\n// implements OSX-specific functions.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n#if SANITIZER_MAC\n#include \"sanitizer_mac.h\"\n\n// Use 64-bit inodes in file operations. ASan does not support OS X 10.5, so\n// the clients will most certainly use 64-bit ones as well.\n#ifndef _DARWIN_USE_64_BIT_INODE\n#define _DARWIN_USE_64_BIT_INODE 1\n#endif\n#include <stdio.h>\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_placement_new.h\"\n#include \"sanitizer_platform_limits_posix.h\"\n#include \"sanitizer_procmaps.h\"\n\n#if !SANITIZER_IOS\n#include <crt_externs.h>  // for _NSGetEnviron\n#else\nextern char **environ;\n#endif\n\n#if defined(__has_include) && __has_include(<os/trace.h>)\n#define SANITIZER_OS_TRACE 1\n#include <os/trace.h>\n#else\n#define SANITIZER_OS_TRACE 0\n#endif\n\n#if !SANITIZER_IOS\n#include <crt_externs.h>  // for _NSGetArgv and _NSGetEnviron\n#else\nextern \"C\" {\n  extern char ***_NSGetArgv(void);\n}\n#endif\n\n#include <asl.h>\n#include <dlfcn.h>  // for dladdr()\n#include <errno.h>\n#include <fcntl.h>\n#include <libkern/OSAtomic.h>\n#include <mach-o/dyld.h>\n#include <mach/mach.h>\n#include <mach/vm_statistics.h>\n#include <pthread.h>\n#include <sched.h>\n#include <signal.h>\n#include <stdlib.h>\n#include <sys/mman.h>\n#include <sys/resource.h>\n#include <sys/stat.h>\n#include <sys/sysctl.h>\n#include <sys/types.h>\n#include <unistd.h>\n#include <util.h>\n\nnamespace __sanitizer {\n\n#include \"sanitizer_syscall_generic.inc\"\n\n// ---------------------- sanitizer_libc.h\nuptr internal_mmap(void *addr, size_t length, int prot, int flags,\n                   int fd, u64 offset) {\n  if (fd == -1) fd = VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL);\n  return (uptr)mmap(addr, length, prot, flags, fd, offset);\n}\n\nuptr internal_munmap(void *addr, uptr length) {\n  return munmap(addr, length);\n}\n\nint internal_mprotect(void *addr, uptr length, int prot) {\n  return mprotect(addr, length, prot);\n}\n\nuptr internal_close(fd_t fd) {\n  return close(fd);\n}\n\nuptr internal_open(const char *filename, int flags) {\n  return open(filename, flags);\n}\n\nuptr internal_open(const char *filename, int flags, u32 mode) {\n  return open(filename, flags, mode);\n}\n\nuptr internal_read(fd_t fd, void *buf, uptr count) {\n  return read(fd, buf, count);\n}\n\nuptr internal_write(fd_t fd, const void *buf, uptr count) {\n  return write(fd, buf, count);\n}\n\nuptr internal_stat(const char *path, void *buf) {\n  return stat(path, (struct stat *)buf);\n}\n\nuptr internal_lstat(const char *path, void *buf) {\n  return lstat(path, (struct stat *)buf);\n}\n\nuptr internal_fstat(fd_t fd, void *buf) {\n  return fstat(fd, (struct stat *)buf);\n}\n\nuptr internal_filesize(fd_t fd) {\n  struct stat st;\n  if (internal_fstat(fd, &st))\n    return -1;\n  return (uptr)st.st_size;\n}\n\nuptr internal_dup2(int oldfd, int newfd) {\n  return dup2(oldfd, newfd);\n}\n\nuptr internal_readlink(const char *path, char *buf, uptr bufsize) {\n  return readlink(path, buf, bufsize);\n}\n\nuptr internal_unlink(const char *path) {\n  return unlink(path);\n}\n\nuptr internal_sched_yield() {\n  return sched_yield();\n}\n\nvoid internal__exit(int exitcode) {\n  _exit(exitcode);\n}\n\nuptr internal_getpid() {\n  return getpid();\n}\n\nint internal_sigaction(int signum, const void *act, void *oldact) {\n  return sigaction(signum,\n                   (struct sigaction *)act, (struct sigaction *)oldact);\n}\n\nvoid internal_sigfillset(__sanitizer_sigset_t *set) { sigfillset(set); }\n\nuptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,\n                          __sanitizer_sigset_t *oldset) {\n  return sigprocmask(how, set, oldset);\n}\n\n// Doesn't call pthread_atfork() handlers.\nextern \"C\" pid_t __fork(void);\n\nint internal_fork() {\n  return __fork();\n}\n\nint internal_forkpty(int *amaster) {\n  int master, slave;\n  if (openpty(&master, &slave, nullptr, nullptr, nullptr) == -1) return -1;\n  int pid = __fork();\n  if (pid == -1) {\n    close(master);\n    close(slave);\n    return -1;\n  }\n  if (pid == 0) {\n    close(master);\n    CHECK_EQ(login_tty(slave), 0);\n  } else {\n    *amaster = master;\n    close(slave);\n  }\n  return pid;\n}\n\nuptr internal_rename(const char *oldpath, const char *newpath) {\n  return rename(oldpath, newpath);\n}\n\nuptr internal_ftruncate(fd_t fd, uptr size) {\n  return ftruncate(fd, size);\n}\n\n// ----------------- sanitizer_common.h\nbool FileExists(const char *filename) {\n  struct stat st;\n  if (stat(filename, &st))\n    return false;\n  // Sanity check: filename is a regular file.\n  return S_ISREG(st.st_mode);\n}\n\nuptr GetTid() {\n  return reinterpret_cast<uptr>(pthread_self());\n}\n\nvoid GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,\n                                uptr *stack_bottom) {\n  CHECK(stack_top);\n  CHECK(stack_bottom);\n  uptr stacksize = pthread_get_stacksize_np(pthread_self());\n  // pthread_get_stacksize_np() returns an incorrect stack size for the main\n  // thread on Mavericks. See\n  // https://github.com/google/sanitizers/issues/261\n  if ((GetMacosVersion() >= MACOS_VERSION_MAVERICKS) && at_initialization &&\n      stacksize == (1 << 19))  {\n    struct rlimit rl;\n    CHECK_EQ(getrlimit(RLIMIT_STACK, &rl), 0);\n    // Most often rl.rlim_cur will be the desired 8M.\n    if (rl.rlim_cur < kMaxThreadStackSize) {\n      stacksize = rl.rlim_cur;\n    } else {\n      stacksize = kMaxThreadStackSize;\n    }\n  }\n  void *stackaddr = pthread_get_stackaddr_np(pthread_self());\n  *stack_top = (uptr)stackaddr;\n  *stack_bottom = *stack_top - stacksize;\n}\n\nchar **GetEnviron() {\n#if !SANITIZER_IOS\n  char ***env_ptr = _NSGetEnviron();\n  if (!env_ptr) {\n    Report(\"_NSGetEnviron() returned NULL. Please make sure __asan_init() is \"\n           \"called after libSystem_initializer().\\n\");\n    CHECK(env_ptr);\n  }\n  char **environ = *env_ptr;\n#endif\n  CHECK(environ);\n  return environ;\n}\n\nconst char *GetEnv(const char *name) {\n  char **env = GetEnviron();\n  uptr name_len = internal_strlen(name);\n  while (*env != 0) {\n    uptr len = internal_strlen(*env);\n    if (len > name_len) {\n      const char *p = *env;\n      if (!internal_memcmp(p, name, name_len) &&\n          p[name_len] == '=') {  // Match.\n        return *env + name_len + 1;  // String starting after =.\n      }\n    }\n    env++;\n  }\n  return 0;\n}\n\nuptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {\n  CHECK_LE(kMaxPathLength, buf_len);\n\n  // On OS X the executable path is saved to the stack by dyld. Reading it\n  // from there is much faster than calling dladdr, especially for large\n  // binaries with symbols.\n  InternalScopedString exe_path(kMaxPathLength);\n  uint32_t size = exe_path.size();\n  if (_NSGetExecutablePath(exe_path.data(), &size) == 0 &&\n      realpath(exe_path.data(), buf) != 0) {\n    return internal_strlen(buf);\n  }\n  return 0;\n}\n\nuptr ReadLongProcessName(/*out*/char *buf, uptr buf_len) {\n  return ReadBinaryName(buf, buf_len);\n}\n\nvoid ReExec() {\n  UNIMPLEMENTED();\n}\n\nuptr GetPageSize() {\n  return sysconf(_SC_PAGESIZE);\n}\n\nBlockingMutex::BlockingMutex() {\n  internal_memset(this, 0, sizeof(*this));\n}\n\nvoid BlockingMutex::Lock() {\n  CHECK(sizeof(OSSpinLock) <= sizeof(opaque_storage_));\n  CHECK_EQ(OS_SPINLOCK_INIT, 0);\n  CHECK_NE(owner_, (uptr)pthread_self());\n  OSSpinLockLock((OSSpinLock*)&opaque_storage_);\n  CHECK(!owner_);\n  owner_ = (uptr)pthread_self();\n}\n\nvoid BlockingMutex::Unlock() {\n  CHECK(owner_ == (uptr)pthread_self());\n  owner_ = 0;\n  OSSpinLockUnlock((OSSpinLock*)&opaque_storage_);\n}\n\nvoid BlockingMutex::CheckLocked() {\n  CHECK_EQ((uptr)pthread_self(), owner_);\n}\n\nu64 NanoTime() {\n  return 0;\n}\n\nuptr GetTlsSize() {\n  return 0;\n}\n\nvoid InitTlsSize() {\n}\n\nvoid GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,\n                          uptr *tls_addr, uptr *tls_size) {\n#ifndef SANITIZER_GO\n  uptr stack_top, stack_bottom;\n  GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);\n  *stk_addr = stack_bottom;\n  *stk_size = stack_top - stack_bottom;\n  *tls_addr = 0;\n  *tls_size = 0;\n#else\n  *stk_addr = 0;\n  *stk_size = 0;\n  *tls_addr = 0;\n  *tls_size = 0;\n#endif\n}\n\nuptr GetListOfModules(LoadedModule *modules, uptr max_modules,\n                      string_predicate_t filter) {\n  MemoryMappingLayout memory_mapping(false);\n  return memory_mapping.DumpListOfModules(modules, max_modules, filter);\n}\n\nbool IsDeadlySignal(int signum) {\n  return (signum == SIGSEGV || signum == SIGBUS) && common_flags()->handle_segv;\n}\n\nMacosVersion cached_macos_version = MACOS_VERSION_UNINITIALIZED;\n\nMacosVersion GetMacosVersionInternal() {\n  int mib[2] = { CTL_KERN, KERN_OSRELEASE };\n  char version[100];\n  uptr len = 0, maxlen = sizeof(version) / sizeof(version[0]);\n  for (uptr i = 0; i < maxlen; i++) version[i] = '\\0';\n  // Get the version length.\n  CHECK_NE(sysctl(mib, 2, 0, &len, 0, 0), -1);\n  CHECK_LT(len, maxlen);\n  CHECK_NE(sysctl(mib, 2, version, &len, 0, 0), -1);\n  switch (version[0]) {\n    case '9': return MACOS_VERSION_LEOPARD;\n    case '1': {\n      switch (version[1]) {\n        case '0': return MACOS_VERSION_SNOW_LEOPARD;\n        case '1': return MACOS_VERSION_LION;\n        case '2': return MACOS_VERSION_MOUNTAIN_LION;\n        case '3': return MACOS_VERSION_MAVERICKS;\n        case '4': return MACOS_VERSION_YOSEMITE;\n        default:\n          if (IsDigit(version[1]))\n            return MACOS_VERSION_UNKNOWN_NEWER;\n          else\n            return MACOS_VERSION_UNKNOWN;\n      }\n    }\n    default: return MACOS_VERSION_UNKNOWN;\n  }\n}\n\nMacosVersion GetMacosVersion() {\n  atomic_uint32_t *cache =\n      reinterpret_cast<atomic_uint32_t*>(&cached_macos_version);\n  MacosVersion result =\n      static_cast<MacosVersion>(atomic_load(cache, memory_order_acquire));\n  if (result == MACOS_VERSION_UNINITIALIZED) {\n    result = GetMacosVersionInternal();\n    atomic_store(cache, result, memory_order_release);\n  }\n  return result;\n}\n\nuptr GetRSS() {\n  struct task_basic_info info;\n  unsigned count = TASK_BASIC_INFO_COUNT;\n  kern_return_t result =\n      task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &count);\n  if (UNLIKELY(result != KERN_SUCCESS)) {\n    Report(\"Cannot get task info. Error: %d\\n\", result);\n    Die();\n  }\n  return info.resident_size;\n}\n\nvoid *internal_start_thread(void(*func)(void *arg), void *arg) {\n  // Start the thread with signals blocked, otherwise it can steal user signals.\n  __sanitizer_sigset_t set, old;\n  internal_sigfillset(&set);\n  internal_sigprocmask(SIG_SETMASK, &set, &old);\n  pthread_t th;\n  pthread_create(&th, 0, (void*(*)(void *arg))func, arg);\n  internal_sigprocmask(SIG_SETMASK, &old, 0);\n  return th;\n}\n\nvoid internal_join_thread(void *th) { pthread_join((pthread_t)th, 0); }\n\nstatic BlockingMutex syslog_lock(LINKER_INITIALIZED);\n\nvoid WriteOneLineToSyslog(const char *s) {\n  syslog_lock.CheckLocked();\n  asl_log(nullptr, nullptr, ASL_LEVEL_ERR, \"%s\", s);\n}\n\nvoid LogFullErrorReport(const char *buffer) {\n  // Log with os_trace. This will make it into the crash log.\n#if SANITIZER_OS_TRACE\n  if (GetMacosVersion() >= MACOS_VERSION_YOSEMITE) {\n    // os_trace requires the message (format parameter) to be a string literal.\n    if (internal_strncmp(SanitizerToolName, \"AddressSanitizer\",\n                         sizeof(\"AddressSanitizer\") - 1) == 0)\n      os_trace(\"Address Sanitizer reported a failure.\");\n    else if (internal_strncmp(SanitizerToolName, \"UndefinedBehaviorSanitizer\",\n                              sizeof(\"UndefinedBehaviorSanitizer\") - 1) == 0)\n      os_trace(\"Undefined Behavior Sanitizer reported a failure.\");\n    else if (internal_strncmp(SanitizerToolName, \"ThreadSanitizer\",\n                              sizeof(\"ThreadSanitizer\") - 1) == 0)\n      os_trace(\"Thread Sanitizer reported a failure.\");\n    else\n      os_trace(\"Sanitizer tool reported a failure.\");\n\n    if (common_flags()->log_to_syslog)\n      os_trace(\"Consult syslog for more information.\");\n  }\n#endif\n\n  // Log to syslog.\n  // The logging on OS X may call pthread_create so we need the threading\n  // environment to be fully initialized. Also, this should never be called when\n  // holding the thread registry lock since that may result in a deadlock. If\n  // the reporting thread holds the thread registry mutex, and asl_log waits\n  // for GCD to dispatch a new thread, the process will deadlock, because the\n  // pthread_create wrapper needs to acquire the lock as well.\n  BlockingMutexLock l(&syslog_lock);\n  if (common_flags()->log_to_syslog)\n    WriteToSyslog(buffer);\n\n  // Log to CrashLog.\n  if (common_flags()->abort_on_error)\n    CRSetCrashLogMessage(buffer);\n}\n\nvoid GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {\n  ucontext_t *ucontext = (ucontext_t*)context;\n# if defined(__aarch64__)\n  *pc = ucontext->uc_mcontext->__ss.__pc;\n#   if defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0\n  *bp = ucontext->uc_mcontext->__ss.__fp;\n#   else\n  *bp = ucontext->uc_mcontext->__ss.__lr;\n#   endif\n  *sp = ucontext->uc_mcontext->__ss.__sp;\n# elif defined(__x86_64__)\n  *pc = ucontext->uc_mcontext->__ss.__rip;\n  *bp = ucontext->uc_mcontext->__ss.__rbp;\n  *sp = ucontext->uc_mcontext->__ss.__rsp;\n# elif defined(__arm__)\n  *pc = ucontext->uc_mcontext->__ss.__pc;\n  *bp = ucontext->uc_mcontext->__ss.__r[7];\n  *sp = ucontext->uc_mcontext->__ss.__sp;\n# elif defined(__i386__)\n  *pc = ucontext->uc_mcontext->__ss.__eip;\n  *bp = ucontext->uc_mcontext->__ss.__ebp;\n  *sp = ucontext->uc_mcontext->__ss.__esp;\n# else\n# error \"Unknown architecture\"\n# endif\n}\n\nstatic const char kDyldInsertLibraries[] = \"DYLD_INSERT_LIBRARIES\";\nLowLevelAllocator allocator_for_env;\n\n// Change the value of the env var |name|, leaking the original value.\n// If |name_value| is NULL, the variable is deleted from the environment,\n// otherwise the corresponding \"NAME=value\" string is replaced with\n// |name_value|.\nvoid LeakyResetEnv(const char *name, const char *name_value) {\n  char **env = GetEnviron();\n  uptr name_len = internal_strlen(name);\n  while (*env != 0) {\n    uptr len = internal_strlen(*env);\n    if (len > name_len) {\n      const char *p = *env;\n      if (!internal_memcmp(p, name, name_len) && p[name_len] == '=') {\n        // Match.\n        if (name_value) {\n          // Replace the old value with the new one.\n          *env = const_cast<char*>(name_value);\n        } else {\n          // Shift the subsequent pointers back.\n          char **del = env;\n          do {\n            del[0] = del[1];\n          } while (*del++);\n        }\n      }\n    }\n    env++;\n  }\n}\n\nstatic bool reexec_disabled = false;\n\nvoid DisableReexec() {\n  reexec_disabled = true;\n}\n\nextern \"C\" double dyldVersionNumber;\nstatic const double kMinDyldVersionWithAutoInterposition = 360.0;\n\nbool DyldNeedsEnvVariable() {\n  // If running on OS X 10.11+ or iOS 9.0+, dyld will interpose even if\n  // DYLD_INSERT_LIBRARIES is not set. However, checking OS version via\n  // GetMacosVersion() doesn't work for the simulator. Let's instead check\n  // `dyldVersionNumber`, which is exported by dyld, against a known version\n  // number from the first OS release where this appeared.\n  return dyldVersionNumber < kMinDyldVersionWithAutoInterposition;\n}\n\nvoid MaybeReexec() {\n  if (reexec_disabled) return;\n\n  // Make sure the dynamic runtime library is preloaded so that the\n  // wrappers work. If it is not, set DYLD_INSERT_LIBRARIES and re-exec\n  // ourselves.\n  Dl_info info;\n  CHECK(dladdr((void*)((uptr)&__sanitizer_report_error_summary), &info));\n  char *dyld_insert_libraries =\n      const_cast<char*>(GetEnv(kDyldInsertLibraries));\n  uptr old_env_len = dyld_insert_libraries ?\n      internal_strlen(dyld_insert_libraries) : 0;\n  uptr fname_len = internal_strlen(info.dli_fname);\n  const char *dylib_name = StripModuleName(info.dli_fname);\n  uptr dylib_name_len = internal_strlen(dylib_name);\n\n  bool lib_is_in_env = dyld_insert_libraries &&\n                       internal_strstr(dyld_insert_libraries, dylib_name);\n  if (DyldNeedsEnvVariable() && !lib_is_in_env) {\n    // DYLD_INSERT_LIBRARIES is not set or does not contain the runtime\n    // library.\n    InternalScopedString program_name(1024);\n    uint32_t buf_size = program_name.size();\n    _NSGetExecutablePath(program_name.data(), &buf_size);\n    char *new_env = const_cast<char*>(info.dli_fname);\n    if (dyld_insert_libraries) {\n      // Append the runtime dylib name to the existing value of\n      // DYLD_INSERT_LIBRARIES.\n      new_env = (char*)allocator_for_env.Allocate(old_env_len + fname_len + 2);\n      internal_strncpy(new_env, dyld_insert_libraries, old_env_len);\n      new_env[old_env_len] = ':';\n      // Copy fname_len and add a trailing zero.\n      internal_strncpy(new_env + old_env_len + 1, info.dli_fname,\n                       fname_len + 1);\n      // Ok to use setenv() since the wrappers don't depend on the value of\n      // asan_inited.\n      setenv(kDyldInsertLibraries, new_env, /*overwrite*/1);\n    } else {\n      // Set DYLD_INSERT_LIBRARIES equal to the runtime dylib name.\n      setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0);\n    }\n    VReport(1, \"exec()-ing the program with\\n\");\n    VReport(1, \"%s=%s\\n\", kDyldInsertLibraries, new_env);\n    VReport(1, \"to enable wrappers.\\n\");\n    execv(program_name.data(), *_NSGetArgv());\n\n    // We get here only if execv() failed.\n    Report(\"ERROR: The process is launched without DYLD_INSERT_LIBRARIES, \"\n           \"which is required for the sanitizer to work. We tried to set the \"\n           \"environment variable and re-execute itself, but execv() failed, \"\n           \"possibly because of sandbox restrictions. Make sure to launch the \"\n           \"executable with:\\n%s=%s\\n\", kDyldInsertLibraries, new_env);\n    CHECK(\"execv failed\" && 0);\n  }\n\n  if (!lib_is_in_env)\n    return;\n\n  // DYLD_INSERT_LIBRARIES is set and contains the runtime library. Let's remove\n  // the dylib from the environment variable, because interceptors are installed\n  // and we don't want our children to inherit the variable.\n\n  uptr env_name_len = internal_strlen(kDyldInsertLibraries);\n  // Allocate memory to hold the previous env var name, its value, the '='\n  // sign and the '\\0' char.\n  char *new_env = (char*)allocator_for_env.Allocate(\n      old_env_len + 2 + env_name_len);\n  CHECK(new_env);\n  internal_memset(new_env, '\\0', old_env_len + 2 + env_name_len);\n  internal_strncpy(new_env, kDyldInsertLibraries, env_name_len);\n  new_env[env_name_len] = '=';\n  char *new_env_pos = new_env + env_name_len + 1;\n\n  // Iterate over colon-separated pieces of |dyld_insert_libraries|.\n  char *piece_start = dyld_insert_libraries;\n  char *piece_end = NULL;\n  char *old_env_end = dyld_insert_libraries + old_env_len;\n  do {\n    if (piece_start[0] == ':') piece_start++;\n    piece_end = internal_strchr(piece_start, ':');\n    if (!piece_end) piece_end = dyld_insert_libraries + old_env_len;\n    if ((uptr)(piece_start - dyld_insert_libraries) > old_env_len) break;\n    uptr piece_len = piece_end - piece_start;\n\n    char *filename_start =\n        (char *)internal_memrchr(piece_start, '/', piece_len);\n    uptr filename_len = piece_len;\n    if (filename_start) {\n      filename_start += 1;\n      filename_len = piece_len - (filename_start - piece_start);\n    } else {\n      filename_start = piece_start;\n    }\n\n    // If the current piece isn't the runtime library name,\n    // append it to new_env.\n    if ((dylib_name_len != filename_len) ||\n        (internal_memcmp(filename_start, dylib_name, dylib_name_len) != 0)) {\n      if (new_env_pos != new_env + env_name_len + 1) {\n        new_env_pos[0] = ':';\n        new_env_pos++;\n      }\n      internal_strncpy(new_env_pos, piece_start, piece_len);\n      new_env_pos += piece_len;\n    }\n    // Move on to the next piece.\n    piece_start = piece_end;\n  } while (piece_start < old_env_end);\n\n  // Can't use setenv() here, because it requires the allocator to be\n  // initialized.\n  // FIXME: instead of filtering DYLD_INSERT_LIBRARIES here, do it in\n  // a separate function called after InitializeAllocator().\n  if (new_env_pos == new_env + env_name_len + 1) new_env = NULL;\n  LeakyResetEnv(kDyldInsertLibraries, new_env);\n}\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_MAC\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_mac.h",
    "content": "//===-- sanitizer_mac.h -----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between various sanitizers' runtime libraries and\n// provides definitions for OSX-specific functions.\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_MAC_H\n#define SANITIZER_MAC_H\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_platform.h\"\n#if SANITIZER_MAC\n#include \"sanitizer_posix.h\"\n\nnamespace __sanitizer {\n\nenum MacosVersion {\n  MACOS_VERSION_UNINITIALIZED = 0,\n  MACOS_VERSION_UNKNOWN,\n  MACOS_VERSION_LEOPARD,\n  MACOS_VERSION_SNOW_LEOPARD,\n  MACOS_VERSION_LION,\n  MACOS_VERSION_MOUNTAIN_LION,\n  MACOS_VERSION_MAVERICKS,\n  MACOS_VERSION_YOSEMITE,\n  MACOS_VERSION_UNKNOWN_NEWER\n};\n\nMacosVersion GetMacosVersion();\n\nchar **GetEnviron();\n\n}  // namespace __sanitizer\n\nextern \"C\" {\nstatic char __crashreporter_info_buff__[kErrorMessageBufferSize] = {};\nstatic const char *__crashreporter_info__ __attribute__((__used__)) =\n  &__crashreporter_info_buff__[0];\nasm(\".desc ___crashreporter_info__, 0x10\");\n} // extern \"C\"\n\nINLINE void CRSetCrashLogMessage(const char *msg) {\n  internal_strlcpy(__crashreporter_info_buff__, msg,\n                   sizeof(__crashreporter_info_buff__)); }\n\n#endif  // SANITIZER_MAC\n#endif  // SANITIZER_MAC_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc",
    "content": "//===-- sanitizer_malloc_mac.inc --------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file contains Mac-specific malloc interceptors and a custom zone\n// implementation, which together replace the system allocator.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if !SANITIZER_MAC\n#error \"This file should only be compiled on Darwin.\"\n#endif\n\n#include <AvailabilityMacros.h>\n#include <CoreFoundation/CFBase.h>\n#include <dlfcn.h>\n#include <malloc/malloc.h>\n#include <sys/mman.h>\n\n#include \"interception/interception.h\"\n#include \"sanitizer_common/sanitizer_mac.h\"\n\n// Similar code is used in Google Perftools,\n// https://github.com/gperftools/gperftools.\n\nstatic malloc_zone_t sanitizer_zone;\n\nINTERCEPTOR(malloc_zone_t *, malloc_create_zone,\n                             vm_size_t start_size, unsigned zone_flags) {\n  COMMON_MALLOC_ENTER();\n  uptr page_size = GetPageSizeCached();\n  uptr allocated_size = RoundUpTo(sizeof(sanitizer_zone), page_size);\n  COMMON_MALLOC_MEMALIGN(page_size, allocated_size);\n  malloc_zone_t *new_zone = (malloc_zone_t *)p;\n  internal_memcpy(new_zone, &sanitizer_zone, sizeof(sanitizer_zone));\n  new_zone->zone_name = NULL;  // The name will be changed anyway.\n  if (GetMacosVersion() >= MACOS_VERSION_LION) {\n    // Prevent the client app from overwriting the zone contents.\n    // Library functions that need to modify the zone will set PROT_WRITE on it.\n    // This matches the behavior of malloc_create_zone() on OSX 10.7 and higher.\n    mprotect(new_zone, allocated_size, PROT_READ);\n  }\n  return new_zone;\n}\n\nINTERCEPTOR(malloc_zone_t *, malloc_default_zone, void) {\n  COMMON_MALLOC_ENTER();\n  return &sanitizer_zone;\n}\n\nINTERCEPTOR(malloc_zone_t *, malloc_default_purgeable_zone, void) {\n  // FIXME: ASan should support purgeable allocations.\n  // https://github.com/google/sanitizers/issues/139\n  COMMON_MALLOC_ENTER();\n  return &sanitizer_zone;\n}\n\nINTERCEPTOR(void, malloc_make_purgeable, void *ptr) {\n  // FIXME: ASan should support purgeable allocations. Ignoring them is fine\n  // for now.\n  COMMON_MALLOC_ENTER();\n}\n\nINTERCEPTOR(int, malloc_make_nonpurgeable, void *ptr) {\n  // FIXME: ASan should support purgeable allocations. Ignoring them is fine\n  // for now.\n  COMMON_MALLOC_ENTER();\n  // Must return 0 if the contents were not purged since the last call to\n  // malloc_make_purgeable().\n  return 0;\n}\n\nINTERCEPTOR(void, malloc_set_zone_name, malloc_zone_t *zone, const char *name) {\n  COMMON_MALLOC_ENTER();\n  // Allocate |sizeof(COMMON_MALLOC_ZONE_NAME \"-\") + internal_strlen(name)|\n  // bytes.\n  size_t buflen =\n      sizeof(COMMON_MALLOC_ZONE_NAME \"-\") + (name ? internal_strlen(name) : 0);\n  InternalScopedString new_name(buflen);\n  if (name && zone->introspect == sanitizer_zone.introspect) {\n    new_name.append(COMMON_MALLOC_ZONE_NAME \"-%s\", name);\n    name = new_name.data();\n  }\n\n  // Call the system malloc's implementation for both external and our zones,\n  // since that appropriately changes VM region protections on the zone.\n  REAL(malloc_set_zone_name)(zone, name);\n}\n\nINTERCEPTOR(void *, malloc, size_t size) {\n  COMMON_MALLOC_ENTER();\n  COMMON_MALLOC_MALLOC(size);\n  return p;\n}\n\nINTERCEPTOR(void, free, void *ptr) {\n  COMMON_MALLOC_ENTER();\n  if (!ptr) return;\n  COMMON_MALLOC_FREE(ptr);\n}\n\nINTERCEPTOR(void *, realloc, void *ptr, size_t size) {\n  COMMON_MALLOC_ENTER();\n  COMMON_MALLOC_REALLOC(ptr, size);\n  return p;\n}\n\nINTERCEPTOR(void *, calloc, size_t nmemb, size_t size) {\n  COMMON_MALLOC_ENTER();\n  COMMON_MALLOC_CALLOC(nmemb, size);\n  return p;\n}\n\nINTERCEPTOR(void *, valloc, size_t size) {\n  COMMON_MALLOC_ENTER();\n  COMMON_MALLOC_VALLOC(size);\n  return p;\n}\n\nINTERCEPTOR(size_t, malloc_good_size, size_t size) {\n  COMMON_MALLOC_ENTER();\n  return sanitizer_zone.introspect->good_size(&sanitizer_zone, size);\n}\n\nINTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) {\n  COMMON_MALLOC_ENTER();\n  CHECK(memptr);\n  COMMON_MALLOC_MEMALIGN(alignment, size);\n  if (p) {\n    *memptr = p;\n    return 0;\n  }\n  return -1;\n}\n\nnamespace {\n\n// TODO(glider): the __sanitizer_mz_* functions should be united with the Linux\n// wrappers, as they are basically copied from there.\nextern \"C\"\nSANITIZER_INTERFACE_ATTRIBUTE\nsize_t __sanitizer_mz_size(malloc_zone_t* zone, const void* ptr) {\n  COMMON_MALLOC_SIZE(ptr);\n  return size;\n}\n\nextern \"C\"\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid *__sanitizer_mz_malloc(malloc_zone_t *zone, uptr size) {\n  COMMON_MALLOC_ENTER();\n  COMMON_MALLOC_MALLOC(size);\n  return p;\n}\n\nextern \"C\"\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid *__sanitizer_mz_calloc(malloc_zone_t *zone, size_t nmemb, size_t size) {\n  if (UNLIKELY(!COMMON_MALLOC_SANITIZER_INITIALIZED)) {\n    // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.\n    const size_t kCallocPoolSize = 1024;\n    static uptr calloc_memory_for_dlsym[kCallocPoolSize];\n    static size_t allocated;\n    size_t size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;\n    void *mem = (void*)&calloc_memory_for_dlsym[allocated];\n    allocated += size_in_words;\n    CHECK(allocated < kCallocPoolSize);\n    return mem;\n  }\n  COMMON_MALLOC_CALLOC(nmemb, size);\n  return p;\n}\n\nextern \"C\"\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid *__sanitizer_mz_valloc(malloc_zone_t *zone, size_t size) {\n  COMMON_MALLOC_ENTER();\n  COMMON_MALLOC_VALLOC(size);\n  return p;\n}\n\n// TODO(glider): the allocation callbacks need to be refactored.\nextern \"C\"\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_mz_free(malloc_zone_t *zone, void *ptr) {\n  if (!ptr) return;\n  COMMON_MALLOC_FREE(ptr);\n}\n\n#define GET_ZONE_FOR_PTR(ptr) \\\n  malloc_zone_t *zone_ptr = malloc_zone_from_ptr(ptr); \\\n  const char *zone_name = (zone_ptr == 0) ? 0 : zone_ptr->zone_name\n\nextern \"C\"\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid *__sanitizer_mz_realloc(malloc_zone_t *zone, void *ptr, size_t new_size) {\n  if (!ptr) {\n    COMMON_MALLOC_MALLOC(new_size);\n    return p;\n  } else {\n    COMMON_MALLOC_SIZE(ptr);\n    if (size) {\n      COMMON_MALLOC_REALLOC(ptr, new_size);\n      return p;\n    } else {\n      // We can't recover from reallocating an unknown address, because\n      // this would require reading at most |new_size| bytes from\n      // potentially unaccessible memory.\n      GET_ZONE_FOR_PTR(ptr);\n      COMMON_MALLOC_REPORT_UNKNOWN_REALLOC(ptr, zone_ptr, zone_name);\n      return nullptr;\n    }\n  }\n}\n\nextern \"C\"\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_mz_destroy(malloc_zone_t* zone) {\n  // A no-op -- we will not be destroyed!\n  Report(\"__sanitizer_mz_destroy() called -- ignoring\\n\");\n}\n\nextern \"C\"\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid *__sanitizer_mz_memalign(malloc_zone_t *zone, size_t align, size_t size) {\n  COMMON_MALLOC_ENTER();\n  COMMON_MALLOC_MEMALIGN(align, size);\n  return p;\n}\n\n// This function is currently unused, and we build with -Werror.\n#if 0\nvoid __sanitizer_mz_free_definite_size(\n    malloc_zone_t* zone, void *ptr, size_t size) {\n  // TODO(glider): check that |size| is valid.\n  UNIMPLEMENTED();\n}\n#endif\n\nkern_return_t mi_enumerator(task_t task, void *,\n                            unsigned type_mask, vm_address_t zone_address,\n                            memory_reader_t reader,\n                            vm_range_recorder_t recorder) {\n  // Should enumerate all the pointers we have.  Seems like a lot of work.\n  return KERN_FAILURE;\n}\n\nsize_t mi_good_size(malloc_zone_t *zone, size_t size) {\n  // I think it's always safe to return size, but we maybe could do better.\n  return size;\n}\n\nboolean_t mi_check(malloc_zone_t *zone) {\n  UNIMPLEMENTED();\n}\n\nvoid mi_print(malloc_zone_t *zone, boolean_t verbose) {\n  UNIMPLEMENTED();\n}\n\nvoid mi_log(malloc_zone_t *zone, void *address) {\n  // I don't think we support anything like this\n}\n\nvoid mi_force_lock(malloc_zone_t *zone) {\n  COMMON_MALLOC_FORCE_LOCK();\n}\n\nvoid mi_force_unlock(malloc_zone_t *zone) {\n  COMMON_MALLOC_FORCE_UNLOCK();\n}\n\nvoid mi_statistics(malloc_zone_t *zone, malloc_statistics_t *stats) {\n  COMMON_MALLOC_FILL_STATS(zone, stats);\n}\n\nboolean_t mi_zone_locked(malloc_zone_t *zone) {\n  // UNIMPLEMENTED();\n  return false;\n}\n\n}  // unnamed namespace\n\nnamespace COMMON_MALLOC_NAMESPACE {\n\nvoid ReplaceSystemMalloc() {\n  static malloc_introspection_t sanitizer_zone_introspection;\n  // Ok to use internal_memset, these places are not performance-critical.\n  internal_memset(&sanitizer_zone_introspection, 0,\n                  sizeof(sanitizer_zone_introspection));\n\n  sanitizer_zone_introspection.enumerator = &mi_enumerator;\n  sanitizer_zone_introspection.good_size = &mi_good_size;\n  sanitizer_zone_introspection.check = &mi_check;\n  sanitizer_zone_introspection.print = &mi_print;\n  sanitizer_zone_introspection.log = &mi_log;\n  sanitizer_zone_introspection.force_lock = &mi_force_lock;\n  sanitizer_zone_introspection.force_unlock = &mi_force_unlock;\n  sanitizer_zone_introspection.statistics = &mi_statistics;\n  sanitizer_zone_introspection.zone_locked = &mi_zone_locked;\n\n  internal_memset(&sanitizer_zone, 0, sizeof(malloc_zone_t));\n\n  // Use version 6 for OSX >= 10.6.\n  sanitizer_zone.version = 6;\n  sanitizer_zone.zone_name = COMMON_MALLOC_ZONE_NAME;\n  sanitizer_zone.size = &__sanitizer_mz_size;\n  sanitizer_zone.malloc = &__sanitizer_mz_malloc;\n  sanitizer_zone.calloc = &__sanitizer_mz_calloc;\n  sanitizer_zone.valloc = &__sanitizer_mz_valloc;\n  sanitizer_zone.free = &__sanitizer_mz_free;\n  sanitizer_zone.realloc = &__sanitizer_mz_realloc;\n  sanitizer_zone.destroy = &__sanitizer_mz_destroy;\n  sanitizer_zone.batch_malloc = 0;\n  sanitizer_zone.batch_free = 0;\n  sanitizer_zone.free_definite_size = 0;\n  sanitizer_zone.memalign = &__sanitizer_mz_memalign;\n  sanitizer_zone.introspect = &sanitizer_zone_introspection;\n\n  // Register the zone.\n  malloc_zone_register(&sanitizer_zone);\n}\n\n}  // namespace COMMON_MALLOC_NAMESPACE\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h",
    "content": "//===-- sanitizer_mutex.h ---------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_MUTEX_H\n#define SANITIZER_MUTEX_H\n\n#include \"sanitizer_atomic.h\"\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_libc.h\"\n\nnamespace __sanitizer {\n\nclass StaticSpinMutex {\n public:\n  void Init() {\n    atomic_store(&state_, 0, memory_order_relaxed);\n  }\n\n  void Lock() {\n    if (TryLock())\n      return;\n    LockSlow();\n  }\n\n  bool TryLock() {\n    return atomic_exchange(&state_, 1, memory_order_acquire) == 0;\n  }\n\n  void Unlock() {\n    atomic_store(&state_, 0, memory_order_release);\n  }\n\n  void CheckLocked() {\n    CHECK_EQ(atomic_load(&state_, memory_order_relaxed), 1);\n  }\n\n private:\n  atomic_uint8_t state_;\n\n  void NOINLINE LockSlow() {\n    for (int i = 0;; i++) {\n      if (i < 10)\n        proc_yield(10);\n      else\n        internal_sched_yield();\n      if (atomic_load(&state_, memory_order_relaxed) == 0\n          && atomic_exchange(&state_, 1, memory_order_acquire) == 0)\n        return;\n    }\n  }\n};\n\nclass SpinMutex : public StaticSpinMutex {\n public:\n  SpinMutex() {\n    Init();\n  }\n\n private:\n  SpinMutex(const SpinMutex&);\n  void operator=(const SpinMutex&);\n};\n\nclass BlockingMutex {\n public:\n#if SANITIZER_WINDOWS\n  // Windows does not currently support LinkerInitialized\n  explicit BlockingMutex(LinkerInitialized);\n#else\n  explicit constexpr BlockingMutex(LinkerInitialized)\n      : opaque_storage_ {0, }, owner_(0) {}\n#endif\n  BlockingMutex();\n  void Lock();\n  void Unlock();\n  void CheckLocked();\n private:\n  uptr opaque_storage_[10];\n  uptr owner_;  // for debugging\n};\n\n// Reader-writer spin mutex.\nclass RWMutex {\n public:\n  RWMutex() {\n    atomic_store(&state_, kUnlocked, memory_order_relaxed);\n  }\n\n  ~RWMutex() {\n    CHECK_EQ(atomic_load(&state_, memory_order_relaxed), kUnlocked);\n  }\n\n  void Lock() {\n    u32 cmp = kUnlocked;\n    if (atomic_compare_exchange_strong(&state_, &cmp, kWriteLock,\n                                       memory_order_acquire))\n      return;\n    LockSlow();\n  }\n\n  void Unlock() {\n    u32 prev = atomic_fetch_sub(&state_, kWriteLock, memory_order_release);\n    DCHECK_NE(prev & kWriteLock, 0);\n    (void)prev;\n  }\n\n  void ReadLock() {\n    u32 prev = atomic_fetch_add(&state_, kReadLock, memory_order_acquire);\n    if ((prev & kWriteLock) == 0)\n      return;\n    ReadLockSlow();\n  }\n\n  void ReadUnlock() {\n    u32 prev = atomic_fetch_sub(&state_, kReadLock, memory_order_release);\n    DCHECK_EQ(prev & kWriteLock, 0);\n    DCHECK_GT(prev & ~kWriteLock, 0);\n    (void)prev;\n  }\n\n  void CheckLocked() {\n    CHECK_NE(atomic_load(&state_, memory_order_relaxed), kUnlocked);\n  }\n\n private:\n  atomic_uint32_t state_;\n\n  enum {\n    kUnlocked = 0,\n    kWriteLock = 1,\n    kReadLock = 2\n  };\n\n  void NOINLINE LockSlow() {\n    for (int i = 0;; i++) {\n      if (i < 10)\n        proc_yield(10);\n      else\n        internal_sched_yield();\n      u32 cmp = atomic_load(&state_, memory_order_relaxed);\n      if (cmp == kUnlocked &&\n          atomic_compare_exchange_weak(&state_, &cmp, kWriteLock,\n                                       memory_order_acquire))\n          return;\n    }\n  }\n\n  void NOINLINE ReadLockSlow() {\n    for (int i = 0;; i++) {\n      if (i < 10)\n        proc_yield(10);\n      else\n        internal_sched_yield();\n      u32 prev = atomic_load(&state_, memory_order_acquire);\n      if ((prev & kWriteLock) == 0)\n        return;\n    }\n  }\n\n  RWMutex(const RWMutex&);\n  void operator = (const RWMutex&);\n};\n\ntemplate<typename MutexType>\nclass GenericScopedLock {\n public:\n  explicit GenericScopedLock(MutexType *mu)\n      : mu_(mu) {\n    mu_->Lock();\n  }\n\n  ~GenericScopedLock() {\n    mu_->Unlock();\n  }\n\n private:\n  MutexType *mu_;\n\n  GenericScopedLock(const GenericScopedLock&);\n  void operator=(const GenericScopedLock&);\n};\n\ntemplate<typename MutexType>\nclass GenericScopedReadLock {\n public:\n  explicit GenericScopedReadLock(MutexType *mu)\n      : mu_(mu) {\n    mu_->ReadLock();\n  }\n\n  ~GenericScopedReadLock() {\n    mu_->ReadUnlock();\n  }\n\n private:\n  MutexType *mu_;\n\n  GenericScopedReadLock(const GenericScopedReadLock&);\n  void operator=(const GenericScopedReadLock&);\n};\n\ntypedef GenericScopedLock<StaticSpinMutex> SpinMutexLock;\ntypedef GenericScopedLock<BlockingMutex> BlockingMutexLock;\ntypedef GenericScopedLock<RWMutex> RWMutexLock;\ntypedef GenericScopedReadLock<RWMutex> RWMutexReadLock;\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_MUTEX_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.cc",
    "content": "//===-- sanitizer_persistent_allocator.cc -----------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_persistent_allocator.h\"\n\nnamespace __sanitizer {\n\nPersistentAllocator thePersistentAllocator;\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h",
    "content": "//===-- sanitizer_persistent_allocator.h ------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// A fast memory allocator that does not support free() nor realloc().\n// All allocations are forever.\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_PERSISTENT_ALLOCATOR_H\n#define SANITIZER_PERSISTENT_ALLOCATOR_H\n\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_mutex.h\"\n#include \"sanitizer_atomic.h\"\n#include \"sanitizer_common.h\"\n\nnamespace __sanitizer {\n\nclass PersistentAllocator {\n public:\n  void *alloc(uptr size);\n\n private:\n  void *tryAlloc(uptr size);\n  StaticSpinMutex mtx;  // Protects alloc of new blocks for region allocator.\n  atomic_uintptr_t region_pos;  // Region allocator for Node's.\n  atomic_uintptr_t region_end;\n};\n\ninline void *PersistentAllocator::tryAlloc(uptr size) {\n  // Optimisic lock-free allocation, essentially try to bump the region ptr.\n  for (;;) {\n    uptr cmp = atomic_load(&region_pos, memory_order_acquire);\n    uptr end = atomic_load(&region_end, memory_order_acquire);\n    if (cmp == 0 || cmp + size > end) return nullptr;\n    if (atomic_compare_exchange_weak(&region_pos, &cmp, cmp + size,\n                                     memory_order_acquire))\n      return (void *)cmp;\n  }\n}\n\ninline void *PersistentAllocator::alloc(uptr size) {\n  // First, try to allocate optimisitically.\n  void *s = tryAlloc(size);\n  if (s) return s;\n  // If failed, lock, retry and alloc new superblock.\n  SpinMutexLock l(&mtx);\n  for (;;) {\n    s = tryAlloc(size);\n    if (s) return s;\n    atomic_store(&region_pos, 0, memory_order_relaxed);\n    uptr allocsz = 64 * 1024;\n    if (allocsz < size) allocsz = size;\n    uptr mem = (uptr)MmapOrDie(allocsz, \"stack depot\");\n    atomic_store(&region_end, mem + allocsz, memory_order_release);\n    atomic_store(&region_pos, mem, memory_order_release);\n  }\n}\n\nextern PersistentAllocator thePersistentAllocator;\ninline void *PersistentAlloc(uptr sz) {\n  return thePersistentAllocator.alloc(sz);\n}\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_PERSISTENT_ALLOCATOR_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_placement_new.h",
    "content": "//===-- sanitizer_placement_new.h -------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n//\n// The file provides 'placement new'.\n// Do not include it into header files, only into source files.\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_PLACEMENT_NEW_H\n#define SANITIZER_PLACEMENT_NEW_H\n\n#include \"sanitizer_internal_defs.h\"\n\ninline void *operator new(__sanitizer::operator_new_size_type sz, void *p) {\n  return p;\n}\n\n#endif  // SANITIZER_PLACEMENT_NEW_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_platform.h",
    "content": "//===-- sanitizer_platform.h ------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Common platform macros.\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_PLATFORM_H\n#define SANITIZER_PLATFORM_H\n\n#if !defined(__linux__) && !defined(__FreeBSD__) && \\\n  !defined(__APPLE__) && !defined(_WIN32)\n# error \"This operating system is not supported\"\n#endif\n\n#if defined(__linux__)\n# define SANITIZER_LINUX   1\n#else\n# define SANITIZER_LINUX   0\n#endif\n\n#if defined(__FreeBSD__)\n# define SANITIZER_FREEBSD 1\n#else\n# define SANITIZER_FREEBSD 0\n#endif\n\n#if defined(__APPLE__)\n# define SANITIZER_MAC     1\n# include <TargetConditionals.h>\n# if TARGET_OS_IPHONE\n#  define SANITIZER_IOS    1\n# else\n#  define SANITIZER_IOS    0\n# endif\n# if TARGET_IPHONE_SIMULATOR\n#  define SANITIZER_IOSSIM 1\n# else\n#  define SANITIZER_IOSSIM 0\n# endif\n#else\n# define SANITIZER_MAC     0\n# define SANITIZER_IOS     0\n# define SANITIZER_IOSSIM  0\n#endif\n\n#if defined(_WIN32)\n# define SANITIZER_WINDOWS 1\n#else\n# define SANITIZER_WINDOWS 0\n#endif\n\n#if defined(__ANDROID__)\n# define SANITIZER_ANDROID 1\n#else\n# define SANITIZER_ANDROID 0\n#endif\n\n#define SANITIZER_POSIX (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC)\n\n#if __LP64__ || defined(_WIN64)\n#  define SANITIZER_WORDSIZE 64\n#else\n#  define SANITIZER_WORDSIZE 32\n#endif\n\n#if SANITIZER_WORDSIZE == 64\n# define FIRST_32_SECOND_64(a, b) (b)\n#else\n# define FIRST_32_SECOND_64(a, b) (a)\n#endif\n\n#if defined(__x86_64__) && !defined(_LP64)\n# define SANITIZER_X32 1\n#else\n# define SANITIZER_X32 0\n#endif\n\n// By default we allow to use SizeClassAllocator64 on 64-bit platform.\n// But in some cases (e.g. AArch64's 39-bit address space) SizeClassAllocator64\n// does not work well and we need to fallback to SizeClassAllocator32.\n// For such platforms build this code with -DSANITIZER_CAN_USE_ALLOCATOR64=0 or\n// change the definition of SANITIZER_CAN_USE_ALLOCATOR64 here.\n#ifndef SANITIZER_CAN_USE_ALLOCATOR64\n# if defined(__mips64) || defined(__aarch64__)\n#  define SANITIZER_CAN_USE_ALLOCATOR64 0\n# else\n#  define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64)\n# endif\n#endif\n\n// The range of addresses which can be returned my mmap.\n// FIXME: this value should be different on different platforms.  Larger values\n// will still work but will consume more memory for TwoLevelByteMap.\n#if defined(__mips__)\n# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40)\n#else\n# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)\n#endif\n\n// The AArch64 linux port uses the canonical syscall set as mandated by\n// the upstream linux community for all new ports. Other ports may still\n// use legacy syscalls.\n#ifndef SANITIZER_USES_CANONICAL_LINUX_SYSCALLS\n# if defined(__aarch64__) && SANITIZER_LINUX\n# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1\n# else\n# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0\n# endif\n#endif\n\n// udi16 syscalls can only be used when the following conditions are\n// met:\n// * target is one of arm32, x86-32, sparc32, sh or m68k\n// * libc version is libc5, glibc-2.0, glibc-2.1 or glibc-2.2 to 2.15\n//   built against > linux-2.2 kernel headers\n// Since we don't want to include libc headers here, we check the\n// target only.\n#if defined(__arm__) || SANITIZER_X32 || defined(__sparc__)\n#define SANITIZER_USES_UID16_SYSCALLS 1\n#else\n#define SANITIZER_USES_UID16_SYSCALLS 0\n#endif\n\n#if defined(__mips__)\n# define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 10)\n#else\n# define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 12)\n#endif\n\n// Assume obsolete RPC headers are available by default\n#if !defined(HAVE_RPC_XDR_H) && !defined(HAVE_TIRPC_RPC_XDR_H)\n# define HAVE_RPC_XDR_H (SANITIZER_LINUX && !SANITIZER_ANDROID)\n# define HAVE_TIRPC_RPC_XDR_H 0\n#endif\n\n/// \\macro MSC_PREREQ\n/// \\brief Is the compiler MSVC of at least the specified version?\n/// The common \\param version values to check for are:\n///  * 1800: Microsoft Visual Studio 2013 / 12.0\n///  * 1900: Microsoft Visual Studio 2015 / 14.0\n#ifdef _MSC_VER\n# define MSC_PREREQ(version) (_MSC_VER >= (version))\n#else\n# define MSC_PREREQ(version) 0\n#endif\n\n#endif // SANITIZER_PLATFORM_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h",
    "content": "//===-- sanitizer_platform_interceptors.h -----------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file defines macro telling whether sanitizer tools can/should intercept\n// given library functions on a given platform.\n//\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_PLATFORM_INTERCEPTORS_H\n#define SANITIZER_PLATFORM_INTERCEPTORS_H\n\n#include \"sanitizer_internal_defs.h\"\n\n#if !SANITIZER_WINDOWS\n# define SI_NOT_WINDOWS 1\n# include \"sanitizer_platform_limits_posix.h\"\n#else\n# define SI_NOT_WINDOWS 0\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n# define SI_LINUX_NOT_ANDROID 1\n#else\n# define SI_LINUX_NOT_ANDROID 0\n#endif\n\n#if SANITIZER_FREEBSD\n# define SI_FREEBSD 1\n#else\n# define SI_FREEBSD 0\n#endif\n\n#if SANITIZER_LINUX\n# define SI_LINUX 1\n#else\n# define SI_LINUX 0\n#endif\n\n#if SANITIZER_MAC\n# define SI_MAC 1\n#else\n# define SI_MAC 0\n#endif\n\n#if SANITIZER_IOS\n# define SI_IOS 1\n#else\n# define SI_IOS 0\n#endif\n\n#define SANITIZER_INTERCEPT_STRCMP 1\n#define SANITIZER_INTERCEPT_STRSTR 1\n#define SANITIZER_INTERCEPT_STRCASESTR SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_STRSPN 1\n#define SANITIZER_INTERCEPT_STRPBRK 1\n#define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_STRCASECMP SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_MEMCMP 1\n#define SANITIZER_INTERCEPT_MEMCHR 1\n#define SANITIZER_INTERCEPT_MEMRCHR SI_FREEBSD || SI_LINUX\n\n#define SANITIZER_INTERCEPT_READ   SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_PREAD  SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_WRITE  SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_PWRITE SI_NOT_WINDOWS\n\n#define SANITIZER_INTERCEPT_PREAD64 SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_PWRITE64 SI_LINUX_NOT_ANDROID\n\n#define SANITIZER_INTERCEPT_READV SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_WRITEV SI_NOT_WINDOWS\n\n#define SANITIZER_INTERCEPT_PREADV SI_FREEBSD || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_PWRITEV SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_PREADV64 SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_PWRITEV64 SI_LINUX_NOT_ANDROID\n\n#define SANITIZER_INTERCEPT_PRCTL   SI_LINUX\n\n#define SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_STRPTIME SI_NOT_WINDOWS\n\n#define SANITIZER_INTERCEPT_SCANF SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_ISOC99_SCANF SI_LINUX_NOT_ANDROID\n\n#ifndef SANITIZER_INTERCEPT_PRINTF\n# define SANITIZER_INTERCEPT_PRINTF SI_NOT_WINDOWS\n# define SANITIZER_INTERCEPT_PRINTF_L SI_FREEBSD\n# define SANITIZER_INTERCEPT_ISOC99_PRINTF SI_LINUX_NOT_ANDROID\n#endif\n\n#define SANITIZER_INTERCEPT_FREXP 1\n#define SANITIZER_INTERCEPT_FREXPF_FREXPL SI_NOT_WINDOWS\n\n#define SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS \\\n  SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_GETPWENT \\\n  SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_FGETPWENT SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_GETPWENT_R SI_FREEBSD || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_SETPWENT SI_MAC || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_CLOCK_GETTIME SI_FREEBSD || SI_LINUX\n#define SANITIZER_INTERCEPT_GETITIMER SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_TIME SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_GLOB SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_WAIT SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_INET SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_GETADDRINFO SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_GETNAMEINFO SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_GETSOCKNAME SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_GETHOSTBYNAME SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_GETHOSTBYNAME_R SI_FREEBSD || SI_LINUX\n#define SANITIZER_INTERCEPT_GETHOSTBYNAME2_R SI_FREEBSD || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_GETHOSTBYADDR_R SI_FREEBSD || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_GETHOSTENT_R SI_FREEBSD || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_GETSOCKOPT SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_ACCEPT SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_ACCEPT4 SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_MODF SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_RECVMSG SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_GETPEERNAME SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_IOCTL SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_INET_ATON SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_SYSINFO SI_LINUX\n#define SANITIZER_INTERCEPT_READDIR SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_PTRACE SI_LINUX_NOT_ANDROID && \\\n  (defined(__i386) || defined(__x86_64) || defined(__mips64) || \\\n    defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__))\n#define SANITIZER_INTERCEPT_SETLOCALE SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_GETCWD SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_STRTOIMAX SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_MBSTOWCS SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_MBSNRTOWCS SI_MAC || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_WCSTOMBS SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_WCSNRTOMBS \\\n  SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_WCRTOMB \\\n  SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_REALPATH SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_CONFSTR \\\n  SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_SCHED_GETAFFINITY SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_SCHED_GETPARAM SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_STRERROR SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_STRERROR_R SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_XPG_STRERROR_R SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_SCANDIR \\\n  SI_FREEBSD || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_SCANDIR64 SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_GETGROUPS SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_POLL SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_PPOLL SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_WORDEXP \\\n  SI_FREEBSD || (SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_SIGWAIT SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_SIGWAITINFO SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_SIGTIMEDWAIT SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_SIGSETOPS \\\n  SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_SIGPENDING SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_SIGPROCMASK SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_BACKTRACE SI_FREEBSD || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_GETMNTENT SI_LINUX\n#define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_STATFS SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_STATFS64 \\\n  (SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_STATVFS SI_FREEBSD || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_STATVFS64 SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_INITGROUPS SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_ETHER_NTOA_ATON SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_ETHER_HOST \\\n  SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_ETHER_R SI_FREEBSD || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_SHMCTL \\\n  ((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && SANITIZER_WORDSIZE == 64)\n#define SANITIZER_INTERCEPT_RANDOM_R SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED \\\n  SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL \\\n  SI_MAC || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING \\\n  SI_MAC || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_TMPNAM SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_TMPNAM_R SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_TEMPNAM SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_SINCOS SI_LINUX\n#define SANITIZER_INTERCEPT_REMQUO SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_LGAMMA SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_LGAMMA_R SI_FREEBSD || SI_LINUX\n#define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_DRAND48_R SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_RAND_R \\\n  SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_ICONV SI_FREEBSD || SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_TIMES SI_NOT_WINDOWS\n\n// FIXME: getline seems to be available on OSX 10.7\n#define SANITIZER_INTERCEPT_GETLINE SI_FREEBSD || SI_LINUX_NOT_ANDROID\n\n#define SANITIZER_INTERCEPT__EXIT SI_LINUX || SI_FREEBSD || SI_MAC\n\n#define SANITIZER_INTERCEPT_PHTREAD_MUTEX SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP \\\n  SI_FREEBSD || SI_LINUX_NOT_ANDROID\n\n#define SANITIZER_INTERCEPT_TLS_GET_ADDR \\\n  SI_FREEBSD || SI_LINUX_NOT_ANDROID\n\n#define SANITIZER_INTERCEPT_LISTXATTR SI_LINUX\n#define SANITIZER_INTERCEPT_GETXATTR SI_LINUX\n#define SANITIZER_INTERCEPT_GETRESID SI_LINUX\n#define SANITIZER_INTERCEPT_GETIFADDRS \\\n  SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_MAC\n#define SANITIZER_INTERCEPT_IF_INDEXTONAME \\\n  SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_MAC\n#define SANITIZER_INTERCEPT_CAPGET SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_AEABI_MEM SI_LINUX && defined(__arm__)\n#define SANITIZER_INTERCEPT___BZERO SI_MAC\n#define SANITIZER_INTERCEPT_FTIME !SI_FREEBSD && SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_XDR SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_TSEARCH SI_LINUX_NOT_ANDROID || SI_MAC\n#define SANITIZER_INTERCEPT_LIBIO_INTERNALS SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_FOPEN SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_FOPEN64 SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_OPEN_MEMSTREAM SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_OBSTACK SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_FFLUSH SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_FCLOSE SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_DLOPEN_DLCLOSE \\\n    SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_MAC\n#define SANITIZER_INTERCEPT_GETPASS SI_LINUX_NOT_ANDROID || SI_MAC\n#define SANITIZER_INTERCEPT_TIMERFD SI_LINUX_NOT_ANDROID\n\n#define SANITIZER_INTERCEPT_MLOCKX SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_FOPENCOOKIE SI_LINUX_NOT_ANDROID\n#define SANITIZER_INTERCEPT_SEM SI_LINUX || SI_FREEBSD\n#define SANITIZER_INTERCEPT_PTHREAD_SETCANCEL SI_NOT_WINDOWS\n#define SANITIZER_INTERCEPT_MINCORE SI_LINUX\n#define SANITIZER_INTERCEPT_PROCESS_VM_READV SI_LINUX\n#define SANITIZER_INTERCEPT_CTERMID SI_LINUX || SI_MAC || SI_FREEBSD\n#define SANITIZER_INTERCEPT_CTERMID_R SI_MAC || SI_FREEBSD\n\n#define SANITIZER_INTERCEPTOR_HOOKS SI_LINUX\n\n#endif  // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cc",
    "content": "//===-- sanitizer_platform_limits_linux.cc --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of Sanitizer common code.\n//\n// Sizes and layouts of linux kernel data structures.\n//===----------------------------------------------------------------------===//\n\n// This is a separate compilation unit for linux headers that conflict with\n// userspace headers.\n// Most \"normal\" includes go in sanitizer_platform_limits_posix.cc\n\n#include \"sanitizer_platform.h\"\n#if SANITIZER_LINUX\n\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_platform_limits_posix.h\"\n\n// For offsetof -> __builtin_offsetof definition.\n#include <stddef.h>\n\n// With old kernels (and even new kernels on powerpc) asm/stat.h uses types that\n// are not defined anywhere in userspace headers. Fake them. This seems to work\n// fine with newer headers, too.\n#include <asm/posix_types.h>\n#if defined(__x86_64__) ||  defined(__mips__)\n#include <sys/stat.h>\n#else\n#define ino_t __kernel_ino_t\n#define mode_t __kernel_mode_t\n#define nlink_t __kernel_nlink_t\n#define uid_t __kernel_uid_t\n#define gid_t __kernel_gid_t\n#define off_t __kernel_off_t\n// This header seems to contain the definitions of _kernel_ stat* structs.\n#include <asm/stat.h>\n#undef ino_t\n#undef mode_t\n#undef nlink_t\n#undef uid_t\n#undef gid_t\n#undef off_t\n#endif\n\n#include <linux/aio_abi.h>\n\n#if !SANITIZER_ANDROID\n#include <sys/statfs.h>\n#include <linux/perf_event.h>\n#endif\n\nnamespace __sanitizer {\n#if !SANITIZER_ANDROID\n  unsigned struct_statfs64_sz = sizeof(struct statfs64);\n#endif\n}  // namespace __sanitizer\n\n#if !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__aarch64__)\\\n                            && !defined(__mips__)\nCOMPILER_CHECK(struct___old_kernel_stat_sz == sizeof(struct __old_kernel_stat));\n#endif\n\nCOMPILER_CHECK(struct_kernel_stat_sz == sizeof(struct stat));\n\n#if defined(__i386__)\nCOMPILER_CHECK(struct_kernel_stat64_sz == sizeof(struct stat64));\n#endif\n\nCHECK_TYPE_SIZE(io_event);\nCHECK_SIZE_AND_OFFSET(io_event, data);\nCHECK_SIZE_AND_OFFSET(io_event, obj);\nCHECK_SIZE_AND_OFFSET(io_event, res);\nCHECK_SIZE_AND_OFFSET(io_event, res2);\n\n#if !SANITIZER_ANDROID\nCOMPILER_CHECK(sizeof(struct __sanitizer_perf_event_attr) <=\n               sizeof(struct perf_event_attr));\nCHECK_SIZE_AND_OFFSET(perf_event_attr, type);\nCHECK_SIZE_AND_OFFSET(perf_event_attr, size);\n#endif\n\nCOMPILER_CHECK(iocb_cmd_pread == IOCB_CMD_PREAD);\nCOMPILER_CHECK(iocb_cmd_pwrite == IOCB_CMD_PWRITE);\n#if !SANITIZER_ANDROID\nCOMPILER_CHECK(iocb_cmd_preadv == IOCB_CMD_PREADV);\nCOMPILER_CHECK(iocb_cmd_pwritev == IOCB_CMD_PWRITEV);\n#endif\n\nCHECK_TYPE_SIZE(iocb);\nCHECK_SIZE_AND_OFFSET(iocb, aio_data);\n// Skip aio_key, it's weird.\nCHECK_SIZE_AND_OFFSET(iocb, aio_lio_opcode);\nCHECK_SIZE_AND_OFFSET(iocb, aio_reqprio);\nCHECK_SIZE_AND_OFFSET(iocb, aio_fildes);\nCHECK_SIZE_AND_OFFSET(iocb, aio_buf);\nCHECK_SIZE_AND_OFFSET(iocb, aio_nbytes);\nCHECK_SIZE_AND_OFFSET(iocb, aio_offset);\n\n#endif  // SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc",
    "content": "//===-- sanitizer_platform_limits_posix.cc --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of Sanitizer common code.\n//\n// Sizes and layouts of platform-specific POSIX data structures.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n\n#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_MAC\n// Tests in this file assume that off_t-dependent data structures match the\n// libc ABI. For example, struct dirent here is what readdir() function (as\n// exported from libc) returns, and not the user-facing \"dirent\", which\n// depends on _FILE_OFFSET_BITS setting.\n// To get this \"true\" dirent definition, we undefine _FILE_OFFSET_BITS below.\n#ifdef _FILE_OFFSET_BITS\n#undef _FILE_OFFSET_BITS\n#endif\n#if SANITIZER_FREEBSD\n#define _WANT_RTENTRY\n#include <sys/param.h>\n#include <sys/socketvar.h>\n#endif\n#include <arpa/inet.h>\n#include <dirent.h>\n#include <errno.h>\n#include <grp.h>\n#include <limits.h>\n#include <net/if.h>\n#include <netdb.h>\n#include <poll.h>\n#include <pthread.h>\n#include <pwd.h>\n#include <signal.h>\n#include <stddef.h>\n#include <sys/mman.h>\n#include <sys/resource.h>\n#include <sys/socket.h>\n#include <sys/stat.h>\n#include <sys/time.h>\n#include <sys/times.h>\n#include <sys/types.h>\n#include <sys/utsname.h>\n#include <termios.h>\n#include <time.h>\n#include <wchar.h>\n\n#if !SANITIZER_IOS\n#include <net/route.h>\n#endif\n\n#if !SANITIZER_ANDROID\n#include <sys/mount.h>\n#include <sys/timeb.h>\n#endif\n\n#if SANITIZER_LINUX\n#include <malloc.h>\n#include <mntent.h>\n#include <netinet/ether.h>\n#include <sys/sysinfo.h>\n#include <sys/vt.h>\n#include <linux/cdrom.h>\n#include <linux/fd.h>\n#include <linux/fs.h>\n#include <linux/hdreg.h>\n#include <linux/input.h>\n#include <linux/ioctl.h>\n#include <linux/soundcard.h>\n#include <linux/sysctl.h>\n#include <linux/utsname.h>\n#include <linux/posix_types.h>\n#include <net/if_arp.h>\n#endif\n\n#if SANITIZER_FREEBSD\n# include <sys/mount.h>\n# include <sys/sockio.h>\n# include <sys/socket.h>\n# include <sys/filio.h>\n# include <sys/signal.h>\n# include <sys/timespec.h>\n# include <sys/timex.h>\n# include <sys/mqueue.h>\n# include <sys/msg.h>\n# include <sys/ipc.h>\n# include <sys/msg.h>\n# include <sys/statvfs.h>\n# include <sys/soundcard.h>\n# include <sys/mtio.h>\n# include <sys/consio.h>\n# include <sys/kbio.h>\n# include <sys/link_elf.h>\n# include <netinet/ip_mroute.h>\n# include <netinet/in.h>\n# include <net/ethernet.h>\n# include <net/ppp_defs.h>\n# include <glob.h>\n# include <term.h>\n\n#define _KERNEL  // to declare 'shminfo' structure\n# include <sys/shm.h>\n#undef _KERNEL\n\n#undef INLINE  // to avoid clashes with sanitizers' definitions\n#endif\n\n#if SANITIZER_FREEBSD || SANITIZER_IOS\n#undef IOC_DIRMASK\n#endif\n\n#if SANITIZER_LINUX || SANITIZER_FREEBSD\n# include <utime.h>\n# include <sys/ptrace.h>\n# if defined(__mips64) || defined(__aarch64__) || defined(__arm__)\n#  include <asm/ptrace.h>\n#  ifdef __arm__\ntypedef struct user_fpregs elf_fpregset_t;\n#   define ARM_VFPREGS_SIZE_ASAN (32 * 8 /*fpregs*/ + 4 /*fpscr*/)\n#   if !defined(ARM_VFPREGS_SIZE)\n#     define ARM_VFPREGS_SIZE ARM_VFPREGS_SIZE_ASAN\n#   endif\n#  endif\n# endif\n# include <semaphore.h>\n#endif\n\n#if !SANITIZER_ANDROID\n#include <ifaddrs.h>\n#include <sys/ucontext.h>\n#include <wordexp.h>\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n#include <glob.h>\n#include <obstack.h>\n#include <mqueue.h>\n#include <net/if_ppp.h>\n#include <netax25/ax25.h>\n#include <netipx/ipx.h>\n#include <netrom/netrom.h>\n#if HAVE_RPC_XDR_H\n# include <rpc/xdr.h>\n#elif HAVE_TIRPC_RPC_XDR_H\n# include <tirpc/rpc/xdr.h>\n#endif\n#include <scsi/scsi.h>\n#include <sys/mtio.h>\n#include <sys/kd.h>\n#include <sys/shm.h>\n#include <sys/statvfs.h>\n#include <sys/timex.h>\n#if defined(__mips64)\n# include <sys/procfs.h>\n#endif\n#include <sys/user.h>\n#include <sys/ustat.h>\n#include <linux/cyclades.h>\n#include <linux/if_eql.h>\n#include <linux/if_plip.h>\n#include <linux/lp.h>\n#include <linux/mroute.h>\n#include <linux/mroute6.h>\n#include <linux/scc.h>\n#include <linux/serial.h>\n#include <sys/msg.h>\n#include <sys/ipc.h>\n#endif // SANITIZER_LINUX && !SANITIZER_ANDROID\n\n#if SANITIZER_ANDROID\n#include <linux/kd.h>\n#include <linux/mtio.h>\n#include <linux/ppp_defs.h>\n#include <linux/if_ppp.h>\n#endif\n\n#if SANITIZER_LINUX\n#include <link.h>\n#include <sys/vfs.h>\n#include <sys/epoll.h>\n#include <linux/capability.h>\n#endif // SANITIZER_LINUX\n\n#if SANITIZER_MAC\n#include <net/ethernet.h>\n#include <sys/filio.h>\n#include <sys/sockio.h>\n#endif\n\n// Include these after system headers to avoid name clashes and ambiguities.\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_platform_limits_posix.h\"\n\nnamespace __sanitizer {\n  unsigned struct_utsname_sz = sizeof(struct utsname);\n  unsigned struct_stat_sz = sizeof(struct stat);\n#if !SANITIZER_IOS && !SANITIZER_FREEBSD\n  unsigned struct_stat64_sz = sizeof(struct stat64);\n#endif // !SANITIZER_IOS && !SANITIZER_FREEBSD\n  unsigned struct_rusage_sz = sizeof(struct rusage);\n  unsigned struct_tm_sz = sizeof(struct tm);\n  unsigned struct_passwd_sz = sizeof(struct passwd);\n  unsigned struct_group_sz = sizeof(struct group);\n  unsigned siginfo_t_sz = sizeof(siginfo_t);\n  unsigned struct_sigaction_sz = sizeof(struct sigaction);\n  unsigned struct_itimerval_sz = sizeof(struct itimerval);\n  unsigned pthread_t_sz = sizeof(pthread_t);\n  unsigned pthread_cond_t_sz = sizeof(pthread_cond_t);\n  unsigned pid_t_sz = sizeof(pid_t);\n  unsigned timeval_sz = sizeof(timeval);\n  unsigned uid_t_sz = sizeof(uid_t);\n  unsigned gid_t_sz = sizeof(gid_t);\n  unsigned mbstate_t_sz = sizeof(mbstate_t);\n  unsigned sigset_t_sz = sizeof(sigset_t);\n  unsigned struct_timezone_sz = sizeof(struct timezone);\n  unsigned struct_tms_sz = sizeof(struct tms);\n  unsigned struct_sigevent_sz = sizeof(struct sigevent);\n  unsigned struct_sched_param_sz = sizeof(struct sched_param);\n\n\n#if SANITIZER_MAC && !SANITIZER_IOS\n  unsigned struct_statfs64_sz = sizeof(struct statfs64);\n#endif // SANITIZER_MAC && !SANITIZER_IOS\n\n#if !SANITIZER_ANDROID\n  unsigned struct_statfs_sz = sizeof(struct statfs);\n  unsigned struct_sockaddr_sz = sizeof(struct sockaddr);\n  unsigned ucontext_t_sz = sizeof(ucontext_t);\n#endif // !SANITIZER_ANDROID\n\n#if SANITIZER_LINUX\n  unsigned struct_epoll_event_sz = sizeof(struct epoll_event);\n  unsigned struct_sysinfo_sz = sizeof(struct sysinfo);\n  unsigned __user_cap_header_struct_sz =\n      sizeof(struct __user_cap_header_struct);\n  unsigned __user_cap_data_struct_sz = sizeof(struct __user_cap_data_struct);\n  unsigned struct_new_utsname_sz = sizeof(struct new_utsname);\n  unsigned struct_old_utsname_sz = sizeof(struct old_utsname);\n  unsigned struct_oldold_utsname_sz = sizeof(struct oldold_utsname);\n#endif // SANITIZER_LINUX\n\n#if SANITIZER_LINUX || SANITIZER_FREEBSD\n  unsigned struct_rlimit_sz = sizeof(struct rlimit);\n  unsigned struct_timespec_sz = sizeof(struct timespec);\n  unsigned struct_utimbuf_sz = sizeof(struct utimbuf);\n  unsigned struct_itimerspec_sz = sizeof(struct itimerspec);\n#endif // SANITIZER_LINUX || SANITIZER_FREEBSD\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n  unsigned struct_ustat_sz = sizeof(struct ustat);\n  unsigned struct_rlimit64_sz = sizeof(struct rlimit64);\n  unsigned struct_statvfs64_sz = sizeof(struct statvfs64);\n#endif // SANITIZER_LINUX && !SANITIZER_ANDROID\n\n#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n  unsigned struct_timex_sz = sizeof(struct timex);\n  unsigned struct_msqid_ds_sz = sizeof(struct msqid_ds);\n  unsigned struct_mq_attr_sz = sizeof(struct mq_attr);\n  unsigned struct_statvfs_sz = sizeof(struct statvfs);\n#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n\n  uptr sig_ign = (uptr)SIG_IGN;\n  uptr sig_dfl = (uptr)SIG_DFL;\n  uptr sa_siginfo = (uptr)SA_SIGINFO;\n\n#if SANITIZER_LINUX\n  int e_tabsz = (int)E_TABSZ;\n#endif\n\n\n#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n  unsigned struct_shminfo_sz = sizeof(struct shminfo);\n  unsigned struct_shm_info_sz = sizeof(struct shm_info);\n  int shmctl_ipc_stat = (int)IPC_STAT;\n  int shmctl_ipc_info = (int)IPC_INFO;\n  int shmctl_shm_info = (int)SHM_INFO;\n  int shmctl_shm_stat = (int)SHM_STAT;\n#endif\n\n  int map_fixed = MAP_FIXED;\n\n  int af_inet = (int)AF_INET;\n  int af_inet6 = (int)AF_INET6;\n\n  uptr __sanitizer_in_addr_sz(int af) {\n    if (af == AF_INET)\n      return sizeof(struct in_addr);\n    else if (af == AF_INET6)\n      return sizeof(struct in6_addr);\n    else\n      return 0;\n  }\n\n#if SANITIZER_LINUX\nunsigned struct_ElfW_Phdr_sz = sizeof(ElfW(Phdr));\n#elif SANITIZER_FREEBSD\nunsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);\n#endif\n\n#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n  int glob_nomatch = GLOB_NOMATCH;\n  int glob_altdirfunc = GLOB_ALTDIRFUNC;\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID && \\\n    (defined(__i386) || defined(__x86_64) || defined(__mips64) || \\\n      defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__))\n#if defined(__mips64) || defined(__powerpc64__) || defined(__arm__)\n  unsigned struct_user_regs_struct_sz = sizeof(struct pt_regs);\n  unsigned struct_user_fpregs_struct_sz = sizeof(elf_fpregset_t);\n#elif defined(__aarch64__)\n  unsigned struct_user_regs_struct_sz = sizeof(struct user_pt_regs);\n  unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpsimd_state);\n#else\n  unsigned struct_user_regs_struct_sz = sizeof(struct user_regs_struct);\n  unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpregs_struct);\n#endif // __mips64 || __powerpc64__ || __aarch64__\n#if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__) || \\\n    defined(__aarch64__) || defined(__arm__)\n  unsigned struct_user_fpxregs_struct_sz = 0;\n#else\n  unsigned struct_user_fpxregs_struct_sz = sizeof(struct user_fpxregs_struct);\n#endif // __x86_64 || __mips64 || __powerpc64__ || __aarch64__ || __arm__\n#ifdef __arm__\n  unsigned struct_user_vfpregs_struct_sz = ARM_VFPREGS_SIZE;\n#else\n  unsigned struct_user_vfpregs_struct_sz = 0;\n#endif\n\n  int ptrace_peektext = PTRACE_PEEKTEXT;\n  int ptrace_peekdata = PTRACE_PEEKDATA;\n  int ptrace_peekuser = PTRACE_PEEKUSER;\n#if (defined(PTRACE_GETREGS) && defined(PTRACE_SETREGS)) || \\\n    (defined(PT_GETREGS) && defined(PT_SETREGS))\n  int ptrace_getregs = PTRACE_GETREGS;\n  int ptrace_setregs = PTRACE_SETREGS;\n#else\n  int ptrace_getregs = -1;\n  int ptrace_setregs = -1;\n#endif\n#if (defined(PTRACE_GETFPREGS) && defined(PTRACE_SETFPREGS)) || \\\n    (defined(PT_GETFPREGS) && defined(PT_SETFPREGS))\n  int ptrace_getfpregs = PTRACE_GETFPREGS;\n  int ptrace_setfpregs = PTRACE_SETFPREGS;\n#else\n  int ptrace_getfpregs = -1;\n  int ptrace_setfpregs = -1;\n#endif\n#if (defined(PTRACE_GETFPXREGS) && defined(PTRACE_SETFPXREGS)) || \\\n    (defined(PT_GETFPXREGS) && defined(PT_SETFPXREGS))\n  int ptrace_getfpxregs = PTRACE_GETFPXREGS;\n  int ptrace_setfpxregs = PTRACE_SETFPXREGS;\n#else\n  int ptrace_getfpxregs = -1;\n  int ptrace_setfpxregs = -1;\n#endif // PTRACE_GETFPXREGS/PTRACE_SETFPXREGS\n#if defined(PTRACE_GETVFPREGS) && defined(PTRACE_SETVFPREGS)\n  int ptrace_getvfpregs = PTRACE_GETVFPREGS;\n  int ptrace_setvfpregs = PTRACE_SETVFPREGS;\n#else\n  int ptrace_getvfpregs = -1;\n  int ptrace_setvfpregs = -1;\n#endif\n  int ptrace_geteventmsg = PTRACE_GETEVENTMSG;\n#if (defined(PTRACE_GETSIGINFO) && defined(PTRACE_SETSIGINFO)) ||              \\\n    (defined(PT_GETSIGINFO) && defined(PT_SETSIGINFO))\n  int ptrace_getsiginfo = PTRACE_GETSIGINFO;\n  int ptrace_setsiginfo = PTRACE_SETSIGINFO;\n#else\n  int ptrace_getsiginfo = -1;\n  int ptrace_setsiginfo = -1;\n#endif // PTRACE_GETSIGINFO/PTRACE_SETSIGINFO\n#if defined(PTRACE_GETREGSET) && defined(PTRACE_SETREGSET)\n  int ptrace_getregset = PTRACE_GETREGSET;\n  int ptrace_setregset = PTRACE_SETREGSET;\n#else\n  int ptrace_getregset = -1;\n  int ptrace_setregset = -1;\n#endif // PTRACE_GETREGSET/PTRACE_SETREGSET\n#endif\n\n  unsigned path_max = PATH_MAX;\n\n  // ioctl arguments\n  unsigned struct_ifreq_sz = sizeof(struct ifreq);\n  unsigned struct_termios_sz = sizeof(struct termios);\n  unsigned struct_winsize_sz = sizeof(struct winsize);\n\n#if SANITIZER_LINUX\n  unsigned struct_arpreq_sz = sizeof(struct arpreq);\n  unsigned struct_cdrom_msf_sz = sizeof(struct cdrom_msf);\n  unsigned struct_cdrom_multisession_sz = sizeof(struct cdrom_multisession);\n  unsigned struct_cdrom_read_audio_sz = sizeof(struct cdrom_read_audio);\n  unsigned struct_cdrom_subchnl_sz = sizeof(struct cdrom_subchnl);\n  unsigned struct_cdrom_ti_sz = sizeof(struct cdrom_ti);\n  unsigned struct_cdrom_tocentry_sz = sizeof(struct cdrom_tocentry);\n  unsigned struct_cdrom_tochdr_sz = sizeof(struct cdrom_tochdr);\n  unsigned struct_cdrom_volctrl_sz = sizeof(struct cdrom_volctrl);\n  unsigned struct_ff_effect_sz = sizeof(struct ff_effect);\n  unsigned struct_floppy_drive_params_sz = sizeof(struct floppy_drive_params);\n  unsigned struct_floppy_drive_struct_sz = sizeof(struct floppy_drive_struct);\n  unsigned struct_floppy_fdc_state_sz = sizeof(struct floppy_fdc_state);\n  unsigned struct_floppy_max_errors_sz = sizeof(struct floppy_max_errors);\n  unsigned struct_floppy_raw_cmd_sz = sizeof(struct floppy_raw_cmd);\n  unsigned struct_floppy_struct_sz = sizeof(struct floppy_struct);\n  unsigned struct_floppy_write_errors_sz = sizeof(struct floppy_write_errors);\n  unsigned struct_format_descr_sz = sizeof(struct format_descr);\n  unsigned struct_hd_driveid_sz = sizeof(struct hd_driveid);\n  unsigned struct_hd_geometry_sz = sizeof(struct hd_geometry);\n  unsigned struct_input_absinfo_sz = sizeof(struct input_absinfo);\n  unsigned struct_input_id_sz = sizeof(struct input_id);\n  unsigned struct_mtpos_sz = sizeof(struct mtpos);\n  unsigned struct_termio_sz = sizeof(struct termio);\n  unsigned struct_vt_consize_sz = sizeof(struct vt_consize);\n  unsigned struct_vt_sizes_sz = sizeof(struct vt_sizes);\n  unsigned struct_vt_stat_sz = sizeof(struct vt_stat);\n#endif // SANITIZER_LINUX\n\n#if SANITIZER_LINUX || SANITIZER_FREEBSD\n#if SOUND_VERSION >= 0x040000\n  unsigned struct_copr_buffer_sz = 0;\n  unsigned struct_copr_debug_buf_sz = 0;\n  unsigned struct_copr_msg_sz = 0;\n#else\n  unsigned struct_copr_buffer_sz = sizeof(struct copr_buffer);\n  unsigned struct_copr_debug_buf_sz = sizeof(struct copr_debug_buf);\n  unsigned struct_copr_msg_sz = sizeof(struct copr_msg);\n#endif\n  unsigned struct_midi_info_sz = sizeof(struct midi_info);\n  unsigned struct_mtget_sz = sizeof(struct mtget);\n  unsigned struct_mtop_sz = sizeof(struct mtop);\n  unsigned struct_rtentry_sz = sizeof(struct rtentry);\n  unsigned struct_sbi_instrument_sz = sizeof(struct sbi_instrument);\n  unsigned struct_seq_event_rec_sz = sizeof(struct seq_event_rec);\n  unsigned struct_synth_info_sz = sizeof(struct synth_info);\n  unsigned struct_vt_mode_sz = sizeof(struct vt_mode);\n#endif // SANITIZER_LINUX || SANITIZER_FREEBSD\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n  unsigned struct_ax25_parms_struct_sz = sizeof(struct ax25_parms_struct);\n  unsigned struct_cyclades_monitor_sz = sizeof(struct cyclades_monitor);\n#if EV_VERSION > (0x010000)\n  unsigned struct_input_keymap_entry_sz = sizeof(struct input_keymap_entry);\n#else\n  unsigned struct_input_keymap_entry_sz = 0;\n#endif\n  unsigned struct_ipx_config_data_sz = sizeof(struct ipx_config_data);\n  unsigned struct_kbdiacrs_sz = sizeof(struct kbdiacrs);\n  unsigned struct_kbentry_sz = sizeof(struct kbentry);\n  unsigned struct_kbkeycode_sz = sizeof(struct kbkeycode);\n  unsigned struct_kbsentry_sz = sizeof(struct kbsentry);\n  unsigned struct_mtconfiginfo_sz = sizeof(struct mtconfiginfo);\n  unsigned struct_nr_parms_struct_sz = sizeof(struct nr_parms_struct);\n  unsigned struct_scc_modem_sz = sizeof(struct scc_modem);\n  unsigned struct_scc_stat_sz = sizeof(struct scc_stat);\n  unsigned struct_serial_multiport_struct_sz\n      = sizeof(struct serial_multiport_struct);\n  unsigned struct_serial_struct_sz = sizeof(struct serial_struct);\n  unsigned struct_sockaddr_ax25_sz = sizeof(struct sockaddr_ax25);\n  unsigned struct_unimapdesc_sz = sizeof(struct unimapdesc);\n  unsigned struct_unimapinit_sz = sizeof(struct unimapinit);\n#endif // SANITIZER_LINUX && !SANITIZER_ANDROID\n\n#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n  unsigned struct_audio_buf_info_sz = sizeof(struct audio_buf_info);\n  unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats);\n#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n\n#if !SANITIZER_ANDROID && !SANITIZER_MAC\n  unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req);\n  unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req);\n#endif\n\n  const unsigned IOCTL_NOT_PRESENT = 0;\n\n  unsigned IOCTL_FIOASYNC = FIOASYNC;\n  unsigned IOCTL_FIOCLEX = FIOCLEX;\n  unsigned IOCTL_FIOGETOWN = FIOGETOWN;\n  unsigned IOCTL_FIONBIO = FIONBIO;\n  unsigned IOCTL_FIONCLEX = FIONCLEX;\n  unsigned IOCTL_FIOSETOWN = FIOSETOWN;\n  unsigned IOCTL_SIOCADDMULTI = SIOCADDMULTI;\n  unsigned IOCTL_SIOCATMARK = SIOCATMARK;\n  unsigned IOCTL_SIOCDELMULTI = SIOCDELMULTI;\n  unsigned IOCTL_SIOCGIFADDR = SIOCGIFADDR;\n  unsigned IOCTL_SIOCGIFBRDADDR = SIOCGIFBRDADDR;\n  unsigned IOCTL_SIOCGIFCONF = SIOCGIFCONF;\n  unsigned IOCTL_SIOCGIFDSTADDR = SIOCGIFDSTADDR;\n  unsigned IOCTL_SIOCGIFFLAGS = SIOCGIFFLAGS;\n  unsigned IOCTL_SIOCGIFMETRIC = SIOCGIFMETRIC;\n  unsigned IOCTL_SIOCGIFMTU = SIOCGIFMTU;\n  unsigned IOCTL_SIOCGIFNETMASK = SIOCGIFNETMASK;\n  unsigned IOCTL_SIOCGPGRP = SIOCGPGRP;\n  unsigned IOCTL_SIOCSIFADDR = SIOCSIFADDR;\n  unsigned IOCTL_SIOCSIFBRDADDR = SIOCSIFBRDADDR;\n  unsigned IOCTL_SIOCSIFDSTADDR = SIOCSIFDSTADDR;\n  unsigned IOCTL_SIOCSIFFLAGS = SIOCSIFFLAGS;\n  unsigned IOCTL_SIOCSIFMETRIC = SIOCSIFMETRIC;\n  unsigned IOCTL_SIOCSIFMTU = SIOCSIFMTU;\n  unsigned IOCTL_SIOCSIFNETMASK = SIOCSIFNETMASK;\n  unsigned IOCTL_SIOCSPGRP = SIOCSPGRP;\n  unsigned IOCTL_TIOCCONS = TIOCCONS;\n  unsigned IOCTL_TIOCEXCL = TIOCEXCL;\n  unsigned IOCTL_TIOCGETD = TIOCGETD;\n  unsigned IOCTL_TIOCGPGRP = TIOCGPGRP;\n  unsigned IOCTL_TIOCGWINSZ = TIOCGWINSZ;\n  unsigned IOCTL_TIOCMBIC = TIOCMBIC;\n  unsigned IOCTL_TIOCMBIS = TIOCMBIS;\n  unsigned IOCTL_TIOCMGET = TIOCMGET;\n  unsigned IOCTL_TIOCMSET = TIOCMSET;\n  unsigned IOCTL_TIOCNOTTY = TIOCNOTTY;\n  unsigned IOCTL_TIOCNXCL = TIOCNXCL;\n  unsigned IOCTL_TIOCOUTQ = TIOCOUTQ;\n  unsigned IOCTL_TIOCPKT = TIOCPKT;\n  unsigned IOCTL_TIOCSCTTY = TIOCSCTTY;\n  unsigned IOCTL_TIOCSETD = TIOCSETD;\n  unsigned IOCTL_TIOCSPGRP = TIOCSPGRP;\n  unsigned IOCTL_TIOCSTI = TIOCSTI;\n  unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ;\n#if ((SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID)\n  unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT;\n  unsigned IOCTL_SIOCGETVIFCNT = SIOCGETVIFCNT;\n#endif\n\n#if SANITIZER_LINUX\n  unsigned IOCTL_EVIOCGABS = EVIOCGABS(0);\n  unsigned IOCTL_EVIOCGBIT = EVIOCGBIT(0, 0);\n  unsigned IOCTL_EVIOCGEFFECTS = EVIOCGEFFECTS;\n  unsigned IOCTL_EVIOCGID = EVIOCGID;\n  unsigned IOCTL_EVIOCGKEY = EVIOCGKEY(0);\n  unsigned IOCTL_EVIOCGKEYCODE = EVIOCGKEYCODE;\n  unsigned IOCTL_EVIOCGLED = EVIOCGLED(0);\n  unsigned IOCTL_EVIOCGNAME = EVIOCGNAME(0);\n  unsigned IOCTL_EVIOCGPHYS = EVIOCGPHYS(0);\n  unsigned IOCTL_EVIOCGRAB = EVIOCGRAB;\n  unsigned IOCTL_EVIOCGREP = EVIOCGREP;\n  unsigned IOCTL_EVIOCGSND = EVIOCGSND(0);\n  unsigned IOCTL_EVIOCGSW = EVIOCGSW(0);\n  unsigned IOCTL_EVIOCGUNIQ = EVIOCGUNIQ(0);\n  unsigned IOCTL_EVIOCGVERSION = EVIOCGVERSION;\n  unsigned IOCTL_EVIOCRMFF = EVIOCRMFF;\n  unsigned IOCTL_EVIOCSABS = EVIOCSABS(0);\n  unsigned IOCTL_EVIOCSFF = EVIOCSFF;\n  unsigned IOCTL_EVIOCSKEYCODE = EVIOCSKEYCODE;\n  unsigned IOCTL_EVIOCSREP = EVIOCSREP;\n  unsigned IOCTL_BLKFLSBUF = BLKFLSBUF;\n  unsigned IOCTL_BLKGETSIZE = BLKGETSIZE;\n  unsigned IOCTL_BLKRAGET = BLKRAGET;\n  unsigned IOCTL_BLKRASET = BLKRASET;\n  unsigned IOCTL_BLKROGET = BLKROGET;\n  unsigned IOCTL_BLKROSET = BLKROSET;\n  unsigned IOCTL_BLKRRPART = BLKRRPART;\n  unsigned IOCTL_CDROMAUDIOBUFSIZ = CDROMAUDIOBUFSIZ;\n  unsigned IOCTL_CDROMEJECT = CDROMEJECT;\n  unsigned IOCTL_CDROMEJECT_SW = CDROMEJECT_SW;\n  unsigned IOCTL_CDROMMULTISESSION = CDROMMULTISESSION;\n  unsigned IOCTL_CDROMPAUSE = CDROMPAUSE;\n  unsigned IOCTL_CDROMPLAYMSF = CDROMPLAYMSF;\n  unsigned IOCTL_CDROMPLAYTRKIND = CDROMPLAYTRKIND;\n  unsigned IOCTL_CDROMREADAUDIO = CDROMREADAUDIO;\n  unsigned IOCTL_CDROMREADCOOKED = CDROMREADCOOKED;\n  unsigned IOCTL_CDROMREADMODE1 = CDROMREADMODE1;\n  unsigned IOCTL_CDROMREADMODE2 = CDROMREADMODE2;\n  unsigned IOCTL_CDROMREADRAW = CDROMREADRAW;\n  unsigned IOCTL_CDROMREADTOCENTRY = CDROMREADTOCENTRY;\n  unsigned IOCTL_CDROMREADTOCHDR = CDROMREADTOCHDR;\n  unsigned IOCTL_CDROMRESET = CDROMRESET;\n  unsigned IOCTL_CDROMRESUME = CDROMRESUME;\n  unsigned IOCTL_CDROMSEEK = CDROMSEEK;\n  unsigned IOCTL_CDROMSTART = CDROMSTART;\n  unsigned IOCTL_CDROMSTOP = CDROMSTOP;\n  unsigned IOCTL_CDROMSUBCHNL = CDROMSUBCHNL;\n  unsigned IOCTL_CDROMVOLCTRL = CDROMVOLCTRL;\n  unsigned IOCTL_CDROMVOLREAD = CDROMVOLREAD;\n  unsigned IOCTL_CDROM_GET_UPC = CDROM_GET_UPC;\n  unsigned IOCTL_FDCLRPRM = FDCLRPRM;\n  unsigned IOCTL_FDDEFPRM = FDDEFPRM;\n  unsigned IOCTL_FDFLUSH = FDFLUSH;\n  unsigned IOCTL_FDFMTBEG = FDFMTBEG;\n  unsigned IOCTL_FDFMTEND = FDFMTEND;\n  unsigned IOCTL_FDFMTTRK = FDFMTTRK;\n  unsigned IOCTL_FDGETDRVPRM = FDGETDRVPRM;\n  unsigned IOCTL_FDGETDRVSTAT = FDGETDRVSTAT;\n  unsigned IOCTL_FDGETDRVTYP = FDGETDRVTYP;\n  unsigned IOCTL_FDGETFDCSTAT = FDGETFDCSTAT;\n  unsigned IOCTL_FDGETMAXERRS = FDGETMAXERRS;\n  unsigned IOCTL_FDGETPRM = FDGETPRM;\n  unsigned IOCTL_FDMSGOFF = FDMSGOFF;\n  unsigned IOCTL_FDMSGON = FDMSGON;\n  unsigned IOCTL_FDPOLLDRVSTAT = FDPOLLDRVSTAT;\n  unsigned IOCTL_FDRAWCMD = FDRAWCMD;\n  unsigned IOCTL_FDRESET = FDRESET;\n  unsigned IOCTL_FDSETDRVPRM = FDSETDRVPRM;\n  unsigned IOCTL_FDSETEMSGTRESH = FDSETEMSGTRESH;\n  unsigned IOCTL_FDSETMAXERRS = FDSETMAXERRS;\n  unsigned IOCTL_FDSETPRM = FDSETPRM;\n  unsigned IOCTL_FDTWADDLE = FDTWADDLE;\n  unsigned IOCTL_FDWERRORCLR = FDWERRORCLR;\n  unsigned IOCTL_FDWERRORGET = FDWERRORGET;\n  unsigned IOCTL_HDIO_DRIVE_CMD = HDIO_DRIVE_CMD;\n  unsigned IOCTL_HDIO_GETGEO = HDIO_GETGEO;\n  unsigned IOCTL_HDIO_GET_32BIT = HDIO_GET_32BIT;\n  unsigned IOCTL_HDIO_GET_DMA = HDIO_GET_DMA;\n  unsigned IOCTL_HDIO_GET_IDENTITY = HDIO_GET_IDENTITY;\n  unsigned IOCTL_HDIO_GET_KEEPSETTINGS = HDIO_GET_KEEPSETTINGS;\n  unsigned IOCTL_HDIO_GET_MULTCOUNT = HDIO_GET_MULTCOUNT;\n  unsigned IOCTL_HDIO_GET_NOWERR = HDIO_GET_NOWERR;\n  unsigned IOCTL_HDIO_GET_UNMASKINTR = HDIO_GET_UNMASKINTR;\n  unsigned IOCTL_HDIO_SET_32BIT = HDIO_SET_32BIT;\n  unsigned IOCTL_HDIO_SET_DMA = HDIO_SET_DMA;\n  unsigned IOCTL_HDIO_SET_KEEPSETTINGS = HDIO_SET_KEEPSETTINGS;\n  unsigned IOCTL_HDIO_SET_MULTCOUNT = HDIO_SET_MULTCOUNT;\n  unsigned IOCTL_HDIO_SET_NOWERR = HDIO_SET_NOWERR;\n  unsigned IOCTL_HDIO_SET_UNMASKINTR = HDIO_SET_UNMASKINTR;\n  unsigned IOCTL_MTIOCPOS = MTIOCPOS;\n  unsigned IOCTL_PPPIOCGASYNCMAP = PPPIOCGASYNCMAP;\n  unsigned IOCTL_PPPIOCGDEBUG = PPPIOCGDEBUG;\n  unsigned IOCTL_PPPIOCGFLAGS = PPPIOCGFLAGS;\n  unsigned IOCTL_PPPIOCGUNIT = PPPIOCGUNIT;\n  unsigned IOCTL_PPPIOCGXASYNCMAP = PPPIOCGXASYNCMAP;\n  unsigned IOCTL_PPPIOCSASYNCMAP = PPPIOCSASYNCMAP;\n  unsigned IOCTL_PPPIOCSDEBUG = PPPIOCSDEBUG;\n  unsigned IOCTL_PPPIOCSFLAGS = PPPIOCSFLAGS;\n  unsigned IOCTL_PPPIOCSMAXCID = PPPIOCSMAXCID;\n  unsigned IOCTL_PPPIOCSMRU = PPPIOCSMRU;\n  unsigned IOCTL_PPPIOCSXASYNCMAP = PPPIOCSXASYNCMAP;\n  unsigned IOCTL_SIOCADDRT = SIOCADDRT;\n  unsigned IOCTL_SIOCDARP = SIOCDARP;\n  unsigned IOCTL_SIOCDELRT = SIOCDELRT;\n  unsigned IOCTL_SIOCDRARP = SIOCDRARP;\n  unsigned IOCTL_SIOCGARP = SIOCGARP;\n  unsigned IOCTL_SIOCGIFENCAP = SIOCGIFENCAP;\n  unsigned IOCTL_SIOCGIFHWADDR = SIOCGIFHWADDR;\n  unsigned IOCTL_SIOCGIFMAP = SIOCGIFMAP;\n  unsigned IOCTL_SIOCGIFMEM = SIOCGIFMEM;\n  unsigned IOCTL_SIOCGIFNAME = SIOCGIFNAME;\n  unsigned IOCTL_SIOCGIFSLAVE = SIOCGIFSLAVE;\n  unsigned IOCTL_SIOCGRARP = SIOCGRARP;\n  unsigned IOCTL_SIOCGSTAMP = SIOCGSTAMP;\n  unsigned IOCTL_SIOCSARP = SIOCSARP;\n  unsigned IOCTL_SIOCSIFENCAP = SIOCSIFENCAP;\n  unsigned IOCTL_SIOCSIFHWADDR = SIOCSIFHWADDR;\n  unsigned IOCTL_SIOCSIFLINK = SIOCSIFLINK;\n  unsigned IOCTL_SIOCSIFMAP = SIOCSIFMAP;\n  unsigned IOCTL_SIOCSIFMEM = SIOCSIFMEM;\n  unsigned IOCTL_SIOCSIFSLAVE = SIOCSIFSLAVE;\n  unsigned IOCTL_SIOCSRARP = SIOCSRARP;\n# if SOUND_VERSION >= 0x040000\n  unsigned IOCTL_SNDCTL_COPR_HALT = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SNDCTL_COPR_LOAD = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SNDCTL_COPR_RCODE = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SNDCTL_COPR_RCVMSG = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SNDCTL_COPR_RDATA = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SNDCTL_COPR_RESET = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SNDCTL_COPR_RUN = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SNDCTL_COPR_SENDMSG = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SNDCTL_COPR_WCODE = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SNDCTL_COPR_WDATA = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SOUND_PCM_READ_BITS = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SOUND_PCM_READ_CHANNELS = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SOUND_PCM_READ_FILTER = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SOUND_PCM_READ_RATE = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SOUND_PCM_WRITE_CHANNELS = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_SOUND_PCM_WRITE_FILTER = IOCTL_NOT_PRESENT;\n# else  // SOUND_VERSION\n  unsigned IOCTL_SNDCTL_COPR_HALT = SNDCTL_COPR_HALT;\n  unsigned IOCTL_SNDCTL_COPR_LOAD = SNDCTL_COPR_LOAD;\n  unsigned IOCTL_SNDCTL_COPR_RCODE = SNDCTL_COPR_RCODE;\n  unsigned IOCTL_SNDCTL_COPR_RCVMSG = SNDCTL_COPR_RCVMSG;\n  unsigned IOCTL_SNDCTL_COPR_RDATA = SNDCTL_COPR_RDATA;\n  unsigned IOCTL_SNDCTL_COPR_RESET = SNDCTL_COPR_RESET;\n  unsigned IOCTL_SNDCTL_COPR_RUN = SNDCTL_COPR_RUN;\n  unsigned IOCTL_SNDCTL_COPR_SENDMSG = SNDCTL_COPR_SENDMSG;\n  unsigned IOCTL_SNDCTL_COPR_WCODE = SNDCTL_COPR_WCODE;\n  unsigned IOCTL_SNDCTL_COPR_WDATA = SNDCTL_COPR_WDATA;\n  unsigned IOCTL_SOUND_PCM_READ_BITS = SOUND_PCM_READ_BITS;\n  unsigned IOCTL_SOUND_PCM_READ_CHANNELS = SOUND_PCM_READ_CHANNELS;\n  unsigned IOCTL_SOUND_PCM_READ_FILTER = SOUND_PCM_READ_FILTER;\n  unsigned IOCTL_SOUND_PCM_READ_RATE = SOUND_PCM_READ_RATE;\n  unsigned IOCTL_SOUND_PCM_WRITE_CHANNELS = SOUND_PCM_WRITE_CHANNELS;\n  unsigned IOCTL_SOUND_PCM_WRITE_FILTER = SOUND_PCM_WRITE_FILTER;\n#endif // SOUND_VERSION\n  unsigned IOCTL_TCFLSH = TCFLSH;\n  unsigned IOCTL_TCGETA = TCGETA;\n  unsigned IOCTL_TCGETS = TCGETS;\n  unsigned IOCTL_TCSBRK = TCSBRK;\n  unsigned IOCTL_TCSBRKP = TCSBRKP;\n  unsigned IOCTL_TCSETA = TCSETA;\n  unsigned IOCTL_TCSETAF = TCSETAF;\n  unsigned IOCTL_TCSETAW = TCSETAW;\n  unsigned IOCTL_TCSETS = TCSETS;\n  unsigned IOCTL_TCSETSF = TCSETSF;\n  unsigned IOCTL_TCSETSW = TCSETSW;\n  unsigned IOCTL_TCXONC = TCXONC;\n  unsigned IOCTL_TIOCGLCKTRMIOS = TIOCGLCKTRMIOS;\n  unsigned IOCTL_TIOCGSOFTCAR = TIOCGSOFTCAR;\n  unsigned IOCTL_TIOCINQ = TIOCINQ;\n  unsigned IOCTL_TIOCLINUX = TIOCLINUX;\n  unsigned IOCTL_TIOCSERCONFIG = TIOCSERCONFIG;\n  unsigned IOCTL_TIOCSERGETLSR = TIOCSERGETLSR;\n  unsigned IOCTL_TIOCSERGWILD = TIOCSERGWILD;\n  unsigned IOCTL_TIOCSERSWILD = TIOCSERSWILD;\n  unsigned IOCTL_TIOCSLCKTRMIOS = TIOCSLCKTRMIOS;\n  unsigned IOCTL_TIOCSSOFTCAR = TIOCSSOFTCAR;\n  unsigned IOCTL_VT_DISALLOCATE = VT_DISALLOCATE;\n  unsigned IOCTL_VT_GETSTATE = VT_GETSTATE;\n  unsigned IOCTL_VT_RESIZE = VT_RESIZE;\n  unsigned IOCTL_VT_RESIZEX = VT_RESIZEX;\n  unsigned IOCTL_VT_SENDSIG = VT_SENDSIG;\n#endif // SANITIZER_LINUX\n\n#if SANITIZER_LINUX || SANITIZER_FREEBSD\n  unsigned IOCTL_MTIOCGET = MTIOCGET;\n  unsigned IOCTL_MTIOCTOP = MTIOCTOP;\n  unsigned IOCTL_SNDCTL_DSP_GETBLKSIZE = SNDCTL_DSP_GETBLKSIZE;\n  unsigned IOCTL_SNDCTL_DSP_GETFMTS = SNDCTL_DSP_GETFMTS;\n  unsigned IOCTL_SNDCTL_DSP_NONBLOCK = SNDCTL_DSP_NONBLOCK;\n  unsigned IOCTL_SNDCTL_DSP_POST = SNDCTL_DSP_POST;\n  unsigned IOCTL_SNDCTL_DSP_RESET = SNDCTL_DSP_RESET;\n  unsigned IOCTL_SNDCTL_DSP_SETFMT = SNDCTL_DSP_SETFMT;\n  unsigned IOCTL_SNDCTL_DSP_SETFRAGMENT = SNDCTL_DSP_SETFRAGMENT;\n  unsigned IOCTL_SNDCTL_DSP_SPEED = SNDCTL_DSP_SPEED;\n  unsigned IOCTL_SNDCTL_DSP_STEREO = SNDCTL_DSP_STEREO;\n  unsigned IOCTL_SNDCTL_DSP_SUBDIVIDE = SNDCTL_DSP_SUBDIVIDE;\n  unsigned IOCTL_SNDCTL_DSP_SYNC = SNDCTL_DSP_SYNC;\n  unsigned IOCTL_SNDCTL_FM_4OP_ENABLE = SNDCTL_FM_4OP_ENABLE;\n  unsigned IOCTL_SNDCTL_FM_LOAD_INSTR = SNDCTL_FM_LOAD_INSTR;\n  unsigned IOCTL_SNDCTL_MIDI_INFO = SNDCTL_MIDI_INFO;\n  unsigned IOCTL_SNDCTL_MIDI_PRETIME = SNDCTL_MIDI_PRETIME;\n  unsigned IOCTL_SNDCTL_SEQ_CTRLRATE = SNDCTL_SEQ_CTRLRATE;\n  unsigned IOCTL_SNDCTL_SEQ_GETINCOUNT = SNDCTL_SEQ_GETINCOUNT;\n  unsigned IOCTL_SNDCTL_SEQ_GETOUTCOUNT = SNDCTL_SEQ_GETOUTCOUNT;\n  unsigned IOCTL_SNDCTL_SEQ_NRMIDIS = SNDCTL_SEQ_NRMIDIS;\n  unsigned IOCTL_SNDCTL_SEQ_NRSYNTHS = SNDCTL_SEQ_NRSYNTHS;\n  unsigned IOCTL_SNDCTL_SEQ_OUTOFBAND = SNDCTL_SEQ_OUTOFBAND;\n  unsigned IOCTL_SNDCTL_SEQ_PANIC = SNDCTL_SEQ_PANIC;\n  unsigned IOCTL_SNDCTL_SEQ_PERCMODE = SNDCTL_SEQ_PERCMODE;\n  unsigned IOCTL_SNDCTL_SEQ_RESET = SNDCTL_SEQ_RESET;\n  unsigned IOCTL_SNDCTL_SEQ_RESETSAMPLES = SNDCTL_SEQ_RESETSAMPLES;\n  unsigned IOCTL_SNDCTL_SEQ_SYNC = SNDCTL_SEQ_SYNC;\n  unsigned IOCTL_SNDCTL_SEQ_TESTMIDI = SNDCTL_SEQ_TESTMIDI;\n  unsigned IOCTL_SNDCTL_SEQ_THRESHOLD = SNDCTL_SEQ_THRESHOLD;\n  unsigned IOCTL_SNDCTL_SYNTH_INFO = SNDCTL_SYNTH_INFO;\n  unsigned IOCTL_SNDCTL_SYNTH_MEMAVL = SNDCTL_SYNTH_MEMAVL;\n  unsigned IOCTL_SNDCTL_TMR_CONTINUE = SNDCTL_TMR_CONTINUE;\n  unsigned IOCTL_SNDCTL_TMR_METRONOME = SNDCTL_TMR_METRONOME;\n  unsigned IOCTL_SNDCTL_TMR_SELECT = SNDCTL_TMR_SELECT;\n  unsigned IOCTL_SNDCTL_TMR_SOURCE = SNDCTL_TMR_SOURCE;\n  unsigned IOCTL_SNDCTL_TMR_START = SNDCTL_TMR_START;\n  unsigned IOCTL_SNDCTL_TMR_STOP = SNDCTL_TMR_STOP;\n  unsigned IOCTL_SNDCTL_TMR_TEMPO = SNDCTL_TMR_TEMPO;\n  unsigned IOCTL_SNDCTL_TMR_TIMEBASE = SNDCTL_TMR_TIMEBASE;\n  unsigned IOCTL_SOUND_MIXER_READ_ALTPCM = SOUND_MIXER_READ_ALTPCM;\n  unsigned IOCTL_SOUND_MIXER_READ_BASS = SOUND_MIXER_READ_BASS;\n  unsigned IOCTL_SOUND_MIXER_READ_CAPS = SOUND_MIXER_READ_CAPS;\n  unsigned IOCTL_SOUND_MIXER_READ_CD = SOUND_MIXER_READ_CD;\n  unsigned IOCTL_SOUND_MIXER_READ_DEVMASK = SOUND_MIXER_READ_DEVMASK;\n  unsigned IOCTL_SOUND_MIXER_READ_ENHANCE = SOUND_MIXER_READ_ENHANCE;\n  unsigned IOCTL_SOUND_MIXER_READ_IGAIN = SOUND_MIXER_READ_IGAIN;\n  unsigned IOCTL_SOUND_MIXER_READ_IMIX = SOUND_MIXER_READ_IMIX;\n  unsigned IOCTL_SOUND_MIXER_READ_LINE = SOUND_MIXER_READ_LINE;\n  unsigned IOCTL_SOUND_MIXER_READ_LINE1 = SOUND_MIXER_READ_LINE1;\n  unsigned IOCTL_SOUND_MIXER_READ_LINE2 = SOUND_MIXER_READ_LINE2;\n  unsigned IOCTL_SOUND_MIXER_READ_LINE3 = SOUND_MIXER_READ_LINE3;\n  unsigned IOCTL_SOUND_MIXER_READ_LOUD = SOUND_MIXER_READ_LOUD;\n  unsigned IOCTL_SOUND_MIXER_READ_MIC = SOUND_MIXER_READ_MIC;\n  unsigned IOCTL_SOUND_MIXER_READ_MUTE = SOUND_MIXER_READ_MUTE;\n  unsigned IOCTL_SOUND_MIXER_READ_OGAIN = SOUND_MIXER_READ_OGAIN;\n  unsigned IOCTL_SOUND_MIXER_READ_PCM = SOUND_MIXER_READ_PCM;\n  unsigned IOCTL_SOUND_MIXER_READ_RECLEV = SOUND_MIXER_READ_RECLEV;\n  unsigned IOCTL_SOUND_MIXER_READ_RECMASK = SOUND_MIXER_READ_RECMASK;\n  unsigned IOCTL_SOUND_MIXER_READ_RECSRC = SOUND_MIXER_READ_RECSRC;\n  unsigned IOCTL_SOUND_MIXER_READ_SPEAKER = SOUND_MIXER_READ_SPEAKER;\n  unsigned IOCTL_SOUND_MIXER_READ_STEREODEVS = SOUND_MIXER_READ_STEREODEVS;\n  unsigned IOCTL_SOUND_MIXER_READ_SYNTH = SOUND_MIXER_READ_SYNTH;\n  unsigned IOCTL_SOUND_MIXER_READ_TREBLE = SOUND_MIXER_READ_TREBLE;\n  unsigned IOCTL_SOUND_MIXER_READ_VOLUME = SOUND_MIXER_READ_VOLUME;\n  unsigned IOCTL_SOUND_MIXER_WRITE_ALTPCM = SOUND_MIXER_WRITE_ALTPCM;\n  unsigned IOCTL_SOUND_MIXER_WRITE_BASS = SOUND_MIXER_WRITE_BASS;\n  unsigned IOCTL_SOUND_MIXER_WRITE_CD = SOUND_MIXER_WRITE_CD;\n  unsigned IOCTL_SOUND_MIXER_WRITE_ENHANCE = SOUND_MIXER_WRITE_ENHANCE;\n  unsigned IOCTL_SOUND_MIXER_WRITE_IGAIN = SOUND_MIXER_WRITE_IGAIN;\n  unsigned IOCTL_SOUND_MIXER_WRITE_IMIX = SOUND_MIXER_WRITE_IMIX;\n  unsigned IOCTL_SOUND_MIXER_WRITE_LINE = SOUND_MIXER_WRITE_LINE;\n  unsigned IOCTL_SOUND_MIXER_WRITE_LINE1 = SOUND_MIXER_WRITE_LINE1;\n  unsigned IOCTL_SOUND_MIXER_WRITE_LINE2 = SOUND_MIXER_WRITE_LINE2;\n  unsigned IOCTL_SOUND_MIXER_WRITE_LINE3 = SOUND_MIXER_WRITE_LINE3;\n  unsigned IOCTL_SOUND_MIXER_WRITE_LOUD = SOUND_MIXER_WRITE_LOUD;\n  unsigned IOCTL_SOUND_MIXER_WRITE_MIC = SOUND_MIXER_WRITE_MIC;\n  unsigned IOCTL_SOUND_MIXER_WRITE_MUTE = SOUND_MIXER_WRITE_MUTE;\n  unsigned IOCTL_SOUND_MIXER_WRITE_OGAIN = SOUND_MIXER_WRITE_OGAIN;\n  unsigned IOCTL_SOUND_MIXER_WRITE_PCM = SOUND_MIXER_WRITE_PCM;\n  unsigned IOCTL_SOUND_MIXER_WRITE_RECLEV = SOUND_MIXER_WRITE_RECLEV;\n  unsigned IOCTL_SOUND_MIXER_WRITE_RECSRC = SOUND_MIXER_WRITE_RECSRC;\n  unsigned IOCTL_SOUND_MIXER_WRITE_SPEAKER = SOUND_MIXER_WRITE_SPEAKER;\n  unsigned IOCTL_SOUND_MIXER_WRITE_SYNTH = SOUND_MIXER_WRITE_SYNTH;\n  unsigned IOCTL_SOUND_MIXER_WRITE_TREBLE = SOUND_MIXER_WRITE_TREBLE;\n  unsigned IOCTL_SOUND_MIXER_WRITE_VOLUME = SOUND_MIXER_WRITE_VOLUME;\n  unsigned IOCTL_VT_ACTIVATE = VT_ACTIVATE;\n  unsigned IOCTL_VT_GETMODE = VT_GETMODE;\n  unsigned IOCTL_VT_OPENQRY = VT_OPENQRY;\n  unsigned IOCTL_VT_RELDISP = VT_RELDISP;\n  unsigned IOCTL_VT_SETMODE = VT_SETMODE;\n  unsigned IOCTL_VT_WAITACTIVE = VT_WAITACTIVE;\n#endif // SANITIZER_LINUX || SANITIZER_FREEBSD\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n  unsigned IOCTL_CYGETDEFTHRESH = CYGETDEFTHRESH;\n  unsigned IOCTL_CYGETDEFTIMEOUT = CYGETDEFTIMEOUT;\n  unsigned IOCTL_CYGETMON = CYGETMON;\n  unsigned IOCTL_CYGETTHRESH = CYGETTHRESH;\n  unsigned IOCTL_CYGETTIMEOUT = CYGETTIMEOUT;\n  unsigned IOCTL_CYSETDEFTHRESH = CYSETDEFTHRESH;\n  unsigned IOCTL_CYSETDEFTIMEOUT = CYSETDEFTIMEOUT;\n  unsigned IOCTL_CYSETTHRESH = CYSETTHRESH;\n  unsigned IOCTL_CYSETTIMEOUT = CYSETTIMEOUT;\n  unsigned IOCTL_EQL_EMANCIPATE = EQL_EMANCIPATE;\n  unsigned IOCTL_EQL_ENSLAVE = EQL_ENSLAVE;\n  unsigned IOCTL_EQL_GETMASTRCFG = EQL_GETMASTRCFG;\n  unsigned IOCTL_EQL_GETSLAVECFG = EQL_GETSLAVECFG;\n  unsigned IOCTL_EQL_SETMASTRCFG = EQL_SETMASTRCFG;\n  unsigned IOCTL_EQL_SETSLAVECFG = EQL_SETSLAVECFG;\n#if EV_VERSION > (0x010000)\n  unsigned IOCTL_EVIOCGKEYCODE_V2 = EVIOCGKEYCODE_V2;\n  unsigned IOCTL_EVIOCGPROP = EVIOCGPROP(0);\n  unsigned IOCTL_EVIOCSKEYCODE_V2 = EVIOCSKEYCODE_V2;\n#else\n  unsigned IOCTL_EVIOCGKEYCODE_V2 = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_EVIOCGPROP = IOCTL_NOT_PRESENT;\n  unsigned IOCTL_EVIOCSKEYCODE_V2 = IOCTL_NOT_PRESENT;\n#endif\n  unsigned IOCTL_FS_IOC_GETFLAGS = FS_IOC_GETFLAGS;\n  unsigned IOCTL_FS_IOC_GETVERSION = FS_IOC_GETVERSION;\n  unsigned IOCTL_FS_IOC_SETFLAGS = FS_IOC_SETFLAGS;\n  unsigned IOCTL_FS_IOC_SETVERSION = FS_IOC_SETVERSION;\n  unsigned IOCTL_GIO_CMAP = GIO_CMAP;\n  unsigned IOCTL_GIO_FONT = GIO_FONT;\n  unsigned IOCTL_GIO_UNIMAP = GIO_UNIMAP;\n  unsigned IOCTL_GIO_UNISCRNMAP = GIO_UNISCRNMAP;\n  unsigned IOCTL_KDADDIO = KDADDIO;\n  unsigned IOCTL_KDDELIO = KDDELIO;\n  unsigned IOCTL_KDGETKEYCODE = KDGETKEYCODE;\n  unsigned IOCTL_KDGKBDIACR = KDGKBDIACR;\n  unsigned IOCTL_KDGKBENT = KDGKBENT;\n  unsigned IOCTL_KDGKBLED = KDGKBLED;\n  unsigned IOCTL_KDGKBMETA = KDGKBMETA;\n  unsigned IOCTL_KDGKBSENT = KDGKBSENT;\n  unsigned IOCTL_KDMAPDISP = KDMAPDISP;\n  unsigned IOCTL_KDSETKEYCODE = KDSETKEYCODE;\n  unsigned IOCTL_KDSIGACCEPT = KDSIGACCEPT;\n  unsigned IOCTL_KDSKBDIACR = KDSKBDIACR;\n  unsigned IOCTL_KDSKBENT = KDSKBENT;\n  unsigned IOCTL_KDSKBLED = KDSKBLED;\n  unsigned IOCTL_KDSKBMETA = KDSKBMETA;\n  unsigned IOCTL_KDSKBSENT = KDSKBSENT;\n  unsigned IOCTL_KDUNMAPDISP = KDUNMAPDISP;\n  unsigned IOCTL_LPABORT = LPABORT;\n  unsigned IOCTL_LPABORTOPEN = LPABORTOPEN;\n  unsigned IOCTL_LPCAREFUL = LPCAREFUL;\n  unsigned IOCTL_LPCHAR = LPCHAR;\n  unsigned IOCTL_LPGETIRQ = LPGETIRQ;\n  unsigned IOCTL_LPGETSTATUS = LPGETSTATUS;\n  unsigned IOCTL_LPRESET = LPRESET;\n  unsigned IOCTL_LPSETIRQ = LPSETIRQ;\n  unsigned IOCTL_LPTIME = LPTIME;\n  unsigned IOCTL_LPWAIT = LPWAIT;\n  unsigned IOCTL_MTIOCGETCONFIG = MTIOCGETCONFIG;\n  unsigned IOCTL_MTIOCSETCONFIG = MTIOCSETCONFIG;\n  unsigned IOCTL_PIO_CMAP = PIO_CMAP;\n  unsigned IOCTL_PIO_FONT = PIO_FONT;\n  unsigned IOCTL_PIO_UNIMAP = PIO_UNIMAP;\n  unsigned IOCTL_PIO_UNIMAPCLR = PIO_UNIMAPCLR;\n  unsigned IOCTL_PIO_UNISCRNMAP = PIO_UNISCRNMAP;\n  unsigned IOCTL_SCSI_IOCTL_GET_IDLUN = SCSI_IOCTL_GET_IDLUN;\n  unsigned IOCTL_SCSI_IOCTL_PROBE_HOST = SCSI_IOCTL_PROBE_HOST;\n  unsigned IOCTL_SCSI_IOCTL_TAGGED_DISABLE = SCSI_IOCTL_TAGGED_DISABLE;\n  unsigned IOCTL_SCSI_IOCTL_TAGGED_ENABLE = SCSI_IOCTL_TAGGED_ENABLE;\n  unsigned IOCTL_SIOCAIPXITFCRT = SIOCAIPXITFCRT;\n  unsigned IOCTL_SIOCAIPXPRISLT = SIOCAIPXPRISLT;\n  unsigned IOCTL_SIOCAX25ADDUID = SIOCAX25ADDUID;\n  unsigned IOCTL_SIOCAX25DELUID = SIOCAX25DELUID;\n  unsigned IOCTL_SIOCAX25GETPARMS = SIOCAX25GETPARMS;\n  unsigned IOCTL_SIOCAX25GETUID = SIOCAX25GETUID;\n  unsigned IOCTL_SIOCAX25NOUID = SIOCAX25NOUID;\n  unsigned IOCTL_SIOCAX25SETPARMS = SIOCAX25SETPARMS;\n  unsigned IOCTL_SIOCDEVPLIP = SIOCDEVPLIP;\n  unsigned IOCTL_SIOCIPXCFGDATA = SIOCIPXCFGDATA;\n  unsigned IOCTL_SIOCNRDECOBS = SIOCNRDECOBS;\n  unsigned IOCTL_SIOCNRGETPARMS = SIOCNRGETPARMS;\n  unsigned IOCTL_SIOCNRRTCTL = SIOCNRRTCTL;\n  unsigned IOCTL_SIOCNRSETPARMS = SIOCNRSETPARMS;\n  unsigned IOCTL_TIOCGSERIAL = TIOCGSERIAL;\n  unsigned IOCTL_TIOCSERGETMULTI = TIOCSERGETMULTI;\n  unsigned IOCTL_TIOCSERSETMULTI = TIOCSERSETMULTI;\n  unsigned IOCTL_TIOCSSERIAL = TIOCSSERIAL;\n#endif // SANITIZER_LINUX && !SANITIZER_ANDROID\n\n#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n  unsigned IOCTL_GIO_SCRNMAP = GIO_SCRNMAP;\n  unsigned IOCTL_KDDISABIO = KDDISABIO;\n  unsigned IOCTL_KDENABIO = KDENABIO;\n  unsigned IOCTL_KDGETLED = KDGETLED;\n  unsigned IOCTL_KDGETMODE = KDGETMODE;\n  unsigned IOCTL_KDGKBMODE = KDGKBMODE;\n  unsigned IOCTL_KDGKBTYPE = KDGKBTYPE;\n  unsigned IOCTL_KDMKTONE = KDMKTONE;\n  unsigned IOCTL_KDSETLED = KDSETLED;\n  unsigned IOCTL_KDSETMODE = KDSETMODE;\n  unsigned IOCTL_KDSKBMODE = KDSKBMODE;\n  unsigned IOCTL_KIOCSOUND = KIOCSOUND;\n  unsigned IOCTL_PIO_SCRNMAP = PIO_SCRNMAP;\n  unsigned IOCTL_SNDCTL_DSP_GETISPACE = SNDCTL_DSP_GETISPACE;\n  unsigned IOCTL_SNDCTL_DSP_GETOSPACE = SNDCTL_DSP_GETOSPACE;\n#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n\n  const int errno_EINVAL = EINVAL;\n// EOWNERDEAD is not present in some older platforms.\n#if defined(EOWNERDEAD)\n  const int errno_EOWNERDEAD = EOWNERDEAD;\n#else\n  const int errno_EOWNERDEAD = -1;\n#endif\n\n  const int si_SEGV_MAPERR = SEGV_MAPERR;\n  const int si_SEGV_ACCERR = SEGV_ACCERR;\n} // namespace __sanitizer\n\nCOMPILER_CHECK(sizeof(__sanitizer_pthread_attr_t) >= sizeof(pthread_attr_t));\n\nCOMPILER_CHECK(sizeof(socklen_t) == sizeof(unsigned));\nCHECK_TYPE_SIZE(pthread_key_t);\n\n#if SANITIZER_LINUX\n// FIXME: We define those on Linux and Mac, but only check on Linux.\nCOMPILER_CHECK(IOC_NRBITS == _IOC_NRBITS);\nCOMPILER_CHECK(IOC_TYPEBITS == _IOC_TYPEBITS);\nCOMPILER_CHECK(IOC_SIZEBITS == _IOC_SIZEBITS);\nCOMPILER_CHECK(IOC_DIRBITS == _IOC_DIRBITS);\nCOMPILER_CHECK(IOC_NRMASK == _IOC_NRMASK);\nCOMPILER_CHECK(IOC_TYPEMASK == _IOC_TYPEMASK);\nCOMPILER_CHECK(IOC_SIZEMASK == _IOC_SIZEMASK);\nCOMPILER_CHECK(IOC_DIRMASK == _IOC_DIRMASK);\nCOMPILER_CHECK(IOC_NRSHIFT == _IOC_NRSHIFT);\nCOMPILER_CHECK(IOC_TYPESHIFT == _IOC_TYPESHIFT);\nCOMPILER_CHECK(IOC_SIZESHIFT == _IOC_SIZESHIFT);\nCOMPILER_CHECK(IOC_DIRSHIFT == _IOC_DIRSHIFT);\nCOMPILER_CHECK(IOC_NONE == _IOC_NONE);\nCOMPILER_CHECK(IOC_WRITE == _IOC_WRITE);\nCOMPILER_CHECK(IOC_READ == _IOC_READ);\nCOMPILER_CHECK(EVIOC_ABS_MAX == ABS_MAX);\nCOMPILER_CHECK(EVIOC_EV_MAX == EV_MAX);\nCOMPILER_CHECK(IOC_SIZE(0x12345678) == _IOC_SIZE(0x12345678));\nCOMPILER_CHECK(IOC_DIR(0x12345678) == _IOC_DIR(0x12345678));\nCOMPILER_CHECK(IOC_NR(0x12345678) == _IOC_NR(0x12345678));\nCOMPILER_CHECK(IOC_TYPE(0x12345678) == _IOC_TYPE(0x12345678));\n#endif // SANITIZER_LINUX\n\n#if SANITIZER_LINUX || SANITIZER_FREEBSD\n// There are more undocumented fields in dl_phdr_info that we are not interested\n// in.\nCOMPILER_CHECK(sizeof(__sanitizer_dl_phdr_info) <= sizeof(dl_phdr_info));\nCHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_addr);\nCHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_name);\nCHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phdr);\nCHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phnum);\n#endif // SANITIZER_LINUX || SANITIZER_FREEBSD\n\n#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\nCHECK_TYPE_SIZE(glob_t);\nCHECK_SIZE_AND_OFFSET(glob_t, gl_pathc);\nCHECK_SIZE_AND_OFFSET(glob_t, gl_pathv);\nCHECK_SIZE_AND_OFFSET(glob_t, gl_offs);\nCHECK_SIZE_AND_OFFSET(glob_t, gl_flags);\nCHECK_SIZE_AND_OFFSET(glob_t, gl_closedir);\nCHECK_SIZE_AND_OFFSET(glob_t, gl_readdir);\nCHECK_SIZE_AND_OFFSET(glob_t, gl_opendir);\nCHECK_SIZE_AND_OFFSET(glob_t, gl_lstat);\nCHECK_SIZE_AND_OFFSET(glob_t, gl_stat);\n#endif\n\nCHECK_TYPE_SIZE(addrinfo);\nCHECK_SIZE_AND_OFFSET(addrinfo, ai_flags);\nCHECK_SIZE_AND_OFFSET(addrinfo, ai_family);\nCHECK_SIZE_AND_OFFSET(addrinfo, ai_socktype);\nCHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol);\nCHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol);\nCHECK_SIZE_AND_OFFSET(addrinfo, ai_addrlen);\nCHECK_SIZE_AND_OFFSET(addrinfo, ai_canonname);\nCHECK_SIZE_AND_OFFSET(addrinfo, ai_addr);\n\nCHECK_TYPE_SIZE(hostent);\nCHECK_SIZE_AND_OFFSET(hostent, h_name);\nCHECK_SIZE_AND_OFFSET(hostent, h_aliases);\nCHECK_SIZE_AND_OFFSET(hostent, h_addrtype);\nCHECK_SIZE_AND_OFFSET(hostent, h_length);\nCHECK_SIZE_AND_OFFSET(hostent, h_addr_list);\n\nCHECK_TYPE_SIZE(iovec);\nCHECK_SIZE_AND_OFFSET(iovec, iov_base);\nCHECK_SIZE_AND_OFFSET(iovec, iov_len);\n\nCHECK_TYPE_SIZE(msghdr);\nCHECK_SIZE_AND_OFFSET(msghdr, msg_name);\nCHECK_SIZE_AND_OFFSET(msghdr, msg_namelen);\nCHECK_SIZE_AND_OFFSET(msghdr, msg_iov);\nCHECK_SIZE_AND_OFFSET(msghdr, msg_iovlen);\nCHECK_SIZE_AND_OFFSET(msghdr, msg_control);\nCHECK_SIZE_AND_OFFSET(msghdr, msg_controllen);\nCHECK_SIZE_AND_OFFSET(msghdr, msg_flags);\n\nCHECK_TYPE_SIZE(cmsghdr);\nCHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_len);\nCHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_level);\nCHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_type);\n\nCOMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent));\nCHECK_SIZE_AND_OFFSET(dirent, d_ino);\n#if SANITIZER_MAC\nCHECK_SIZE_AND_OFFSET(dirent, d_seekoff);\n#elif SANITIZER_FREEBSD\n// There is no 'd_off' field on FreeBSD.\n#else\nCHECK_SIZE_AND_OFFSET(dirent, d_off);\n#endif\nCHECK_SIZE_AND_OFFSET(dirent, d_reclen);\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nCOMPILER_CHECK(sizeof(__sanitizer_dirent64) <= sizeof(dirent64));\nCHECK_SIZE_AND_OFFSET(dirent64, d_ino);\nCHECK_SIZE_AND_OFFSET(dirent64, d_off);\nCHECK_SIZE_AND_OFFSET(dirent64, d_reclen);\n#endif\n\nCHECK_TYPE_SIZE(ifconf);\nCHECK_SIZE_AND_OFFSET(ifconf, ifc_len);\nCHECK_SIZE_AND_OFFSET(ifconf, ifc_ifcu);\n\nCHECK_TYPE_SIZE(pollfd);\nCHECK_SIZE_AND_OFFSET(pollfd, fd);\nCHECK_SIZE_AND_OFFSET(pollfd, events);\nCHECK_SIZE_AND_OFFSET(pollfd, revents);\n\nCHECK_TYPE_SIZE(nfds_t);\n\nCHECK_TYPE_SIZE(sigset_t);\n\nCOMPILER_CHECK(sizeof(__sanitizer_sigaction) == sizeof(struct sigaction));\n// Can't write checks for sa_handler and sa_sigaction due to them being\n// preprocessor macros.\nCHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask);\nCHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_flags);\n#if SANITIZER_LINUX\nCHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_restorer);\n#endif\n\n#if SANITIZER_LINUX\nCHECK_TYPE_SIZE(__sysctl_args);\nCHECK_SIZE_AND_OFFSET(__sysctl_args, name);\nCHECK_SIZE_AND_OFFSET(__sysctl_args, nlen);\nCHECK_SIZE_AND_OFFSET(__sysctl_args, oldval);\nCHECK_SIZE_AND_OFFSET(__sysctl_args, oldlenp);\nCHECK_SIZE_AND_OFFSET(__sysctl_args, newval);\nCHECK_SIZE_AND_OFFSET(__sysctl_args, newlen);\n\nCHECK_TYPE_SIZE(__kernel_uid_t);\nCHECK_TYPE_SIZE(__kernel_gid_t);\n\n#if SANITIZER_USES_UID16_SYSCALLS\nCHECK_TYPE_SIZE(__kernel_old_uid_t);\nCHECK_TYPE_SIZE(__kernel_old_gid_t);\n#endif\n\nCHECK_TYPE_SIZE(__kernel_off_t);\nCHECK_TYPE_SIZE(__kernel_loff_t);\nCHECK_TYPE_SIZE(__kernel_fd_set);\n#endif\n\n#if !SANITIZER_ANDROID\nCHECK_TYPE_SIZE(wordexp_t);\nCHECK_SIZE_AND_OFFSET(wordexp_t, we_wordc);\nCHECK_SIZE_AND_OFFSET(wordexp_t, we_wordv);\nCHECK_SIZE_AND_OFFSET(wordexp_t, we_offs);\n#endif\n\nCHECK_TYPE_SIZE(tm);\nCHECK_SIZE_AND_OFFSET(tm, tm_sec);\nCHECK_SIZE_AND_OFFSET(tm, tm_min);\nCHECK_SIZE_AND_OFFSET(tm, tm_hour);\nCHECK_SIZE_AND_OFFSET(tm, tm_mday);\nCHECK_SIZE_AND_OFFSET(tm, tm_mon);\nCHECK_SIZE_AND_OFFSET(tm, tm_year);\nCHECK_SIZE_AND_OFFSET(tm, tm_wday);\nCHECK_SIZE_AND_OFFSET(tm, tm_yday);\nCHECK_SIZE_AND_OFFSET(tm, tm_isdst);\nCHECK_SIZE_AND_OFFSET(tm, tm_gmtoff);\nCHECK_SIZE_AND_OFFSET(tm, tm_zone);\n\n#if SANITIZER_LINUX\nCHECK_TYPE_SIZE(mntent);\nCHECK_SIZE_AND_OFFSET(mntent, mnt_fsname);\nCHECK_SIZE_AND_OFFSET(mntent, mnt_dir);\nCHECK_SIZE_AND_OFFSET(mntent, mnt_type);\nCHECK_SIZE_AND_OFFSET(mntent, mnt_opts);\nCHECK_SIZE_AND_OFFSET(mntent, mnt_freq);\nCHECK_SIZE_AND_OFFSET(mntent, mnt_passno);\n#endif\n\nCHECK_TYPE_SIZE(ether_addr);\n\n#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\nCHECK_TYPE_SIZE(ipc_perm);\n# if SANITIZER_FREEBSD\nCHECK_SIZE_AND_OFFSET(ipc_perm, key);\nCHECK_SIZE_AND_OFFSET(ipc_perm, seq);\n# else\nCHECK_SIZE_AND_OFFSET(ipc_perm, __key);\nCHECK_SIZE_AND_OFFSET(ipc_perm, __seq);\n# endif\nCHECK_SIZE_AND_OFFSET(ipc_perm, uid);\nCHECK_SIZE_AND_OFFSET(ipc_perm, gid);\nCHECK_SIZE_AND_OFFSET(ipc_perm, cuid);\nCHECK_SIZE_AND_OFFSET(ipc_perm, cgid);\n#ifndef __GLIBC_PREREQ\n#define __GLIBC_PREREQ(x, y) 0\n#endif\n#if !defined(__aarch64__) || !SANITIZER_LINUX || __GLIBC_PREREQ (2, 21)\n/* On aarch64 glibc 2.20 and earlier provided incorrect mode field.  */\nCHECK_SIZE_AND_OFFSET(ipc_perm, mode);\n#endif\n\nCHECK_TYPE_SIZE(shmid_ds);\nCHECK_SIZE_AND_OFFSET(shmid_ds, shm_perm);\nCHECK_SIZE_AND_OFFSET(shmid_ds, shm_segsz);\nCHECK_SIZE_AND_OFFSET(shmid_ds, shm_atime);\nCHECK_SIZE_AND_OFFSET(shmid_ds, shm_dtime);\nCHECK_SIZE_AND_OFFSET(shmid_ds, shm_ctime);\nCHECK_SIZE_AND_OFFSET(shmid_ds, shm_cpid);\nCHECK_SIZE_AND_OFFSET(shmid_ds, shm_lpid);\nCHECK_SIZE_AND_OFFSET(shmid_ds, shm_nattch);\n#endif\n\nCHECK_TYPE_SIZE(clock_t);\n\n#if SANITIZER_LINUX\nCHECK_TYPE_SIZE(clockid_t);\n#endif\n\n#if !SANITIZER_ANDROID\nCHECK_TYPE_SIZE(ifaddrs);\nCHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next);\nCHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name);\nCHECK_SIZE_AND_OFFSET(ifaddrs, ifa_addr);\nCHECK_SIZE_AND_OFFSET(ifaddrs, ifa_netmask);\n#if SANITIZER_LINUX || SANITIZER_FREEBSD\n// Compare against the union, because we can't reach into the union in a\n// compliant way.\n#ifdef ifa_dstaddr\n#undef ifa_dstaddr\n#endif\n# if SANITIZER_FREEBSD\nCHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr);\n# else\nCOMPILER_CHECK(sizeof(((__sanitizer_ifaddrs *)nullptr)->ifa_dstaddr) ==\n               sizeof(((ifaddrs *)nullptr)->ifa_ifu));\nCOMPILER_CHECK(offsetof(__sanitizer_ifaddrs, ifa_dstaddr) ==\n               offsetof(ifaddrs, ifa_ifu));\n# endif // SANITIZER_FREEBSD\n#else\nCHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr);\n#endif // SANITIZER_LINUX\nCHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data);\n#endif\n\n#if SANITIZER_LINUX\nCOMPILER_CHECK(sizeof(__sanitizer_mallinfo) == sizeof(struct mallinfo));\n#endif\n\n#if !SANITIZER_ANDROID\nCHECK_TYPE_SIZE(timeb);\nCHECK_SIZE_AND_OFFSET(timeb, time);\nCHECK_SIZE_AND_OFFSET(timeb, millitm);\nCHECK_SIZE_AND_OFFSET(timeb, timezone);\nCHECK_SIZE_AND_OFFSET(timeb, dstflag);\n#endif\n\nCHECK_TYPE_SIZE(passwd);\nCHECK_SIZE_AND_OFFSET(passwd, pw_name);\nCHECK_SIZE_AND_OFFSET(passwd, pw_passwd);\nCHECK_SIZE_AND_OFFSET(passwd, pw_uid);\nCHECK_SIZE_AND_OFFSET(passwd, pw_gid);\nCHECK_SIZE_AND_OFFSET(passwd, pw_dir);\nCHECK_SIZE_AND_OFFSET(passwd, pw_shell);\n\n#if !SANITIZER_ANDROID\nCHECK_SIZE_AND_OFFSET(passwd, pw_gecos);\n#endif\n\n#if SANITIZER_MAC\nCHECK_SIZE_AND_OFFSET(passwd, pw_change);\nCHECK_SIZE_AND_OFFSET(passwd, pw_expire);\nCHECK_SIZE_AND_OFFSET(passwd, pw_class);\n#endif\n\n\nCHECK_TYPE_SIZE(group);\nCHECK_SIZE_AND_OFFSET(group, gr_name);\nCHECK_SIZE_AND_OFFSET(group, gr_passwd);\nCHECK_SIZE_AND_OFFSET(group, gr_gid);\nCHECK_SIZE_AND_OFFSET(group, gr_mem);\n\n#if HAVE_RPC_XDR_H || HAVE_TIRPC_RPC_XDR_H\nCHECK_TYPE_SIZE(XDR);\nCHECK_SIZE_AND_OFFSET(XDR, x_op);\nCHECK_SIZE_AND_OFFSET(XDR, x_ops);\nCHECK_SIZE_AND_OFFSET(XDR, x_public);\nCHECK_SIZE_AND_OFFSET(XDR, x_private);\nCHECK_SIZE_AND_OFFSET(XDR, x_base);\nCHECK_SIZE_AND_OFFSET(XDR, x_handy);\nCOMPILER_CHECK(__sanitizer_XDR_ENCODE == XDR_ENCODE);\nCOMPILER_CHECK(__sanitizer_XDR_DECODE == XDR_DECODE);\nCOMPILER_CHECK(__sanitizer_XDR_FREE == XDR_FREE);\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nCOMPILER_CHECK(sizeof(__sanitizer_FILE) <= sizeof(FILE));\nCHECK_SIZE_AND_OFFSET(FILE, _flags);\nCHECK_SIZE_AND_OFFSET(FILE, _IO_read_ptr);\nCHECK_SIZE_AND_OFFSET(FILE, _IO_read_end);\nCHECK_SIZE_AND_OFFSET(FILE, _IO_read_base);\nCHECK_SIZE_AND_OFFSET(FILE, _IO_write_ptr);\nCHECK_SIZE_AND_OFFSET(FILE, _IO_write_end);\nCHECK_SIZE_AND_OFFSET(FILE, _IO_write_base);\nCHECK_SIZE_AND_OFFSET(FILE, _IO_buf_base);\nCHECK_SIZE_AND_OFFSET(FILE, _IO_buf_end);\nCHECK_SIZE_AND_OFFSET(FILE, _IO_save_base);\nCHECK_SIZE_AND_OFFSET(FILE, _IO_backup_base);\nCHECK_SIZE_AND_OFFSET(FILE, _IO_save_end);\nCHECK_SIZE_AND_OFFSET(FILE, _markers);\nCHECK_SIZE_AND_OFFSET(FILE, _chain);\nCHECK_SIZE_AND_OFFSET(FILE, _fileno);\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nCOMPILER_CHECK(sizeof(__sanitizer__obstack_chunk) <= sizeof(_obstack_chunk));\nCHECK_SIZE_AND_OFFSET(_obstack_chunk, limit);\nCHECK_SIZE_AND_OFFSET(_obstack_chunk, prev);\nCHECK_TYPE_SIZE(obstack);\nCHECK_SIZE_AND_OFFSET(obstack, chunk_size);\nCHECK_SIZE_AND_OFFSET(obstack, chunk);\nCHECK_SIZE_AND_OFFSET(obstack, object_base);\nCHECK_SIZE_AND_OFFSET(obstack, next_free);\n\nCHECK_TYPE_SIZE(cookie_io_functions_t);\nCHECK_SIZE_AND_OFFSET(cookie_io_functions_t, read);\nCHECK_SIZE_AND_OFFSET(cookie_io_functions_t, write);\nCHECK_SIZE_AND_OFFSET(cookie_io_functions_t, seek);\nCHECK_SIZE_AND_OFFSET(cookie_io_functions_t, close);\n#endif\n\n#if SANITIZER_LINUX || SANITIZER_FREEBSD\nCHECK_TYPE_SIZE(sem_t);\n#endif\n\n#if SANITIZER_LINUX && defined(__arm__)\nCOMPILER_CHECK(ARM_VFPREGS_SIZE == ARM_VFPREGS_SIZE_ASAN);\n#endif\n\n#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_MAC\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h",
    "content": "//===-- sanitizer_platform_limits_posix.h ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of Sanitizer common code.\n//\n// Sizes and layouts of platform-specific POSIX data structures.\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_PLATFORM_LIMITS_POSIX_H\n#define SANITIZER_PLATFORM_LIMITS_POSIX_H\n\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_platform.h\"\n\n#if SANITIZER_FREEBSD\n// FreeBSD's dlopen() returns a pointer to an Obj_Entry structure that\n// incroporates the map structure.\n# define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \\\n    ((link_map*)((handle) == nullptr ? nullptr : ((char*)(handle) + 544)))\n#else\n# define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) ((link_map*)(handle))\n#endif  // !SANITIZER_FREEBSD\n\nnamespace __sanitizer {\n  extern unsigned struct_utsname_sz;\n  extern unsigned struct_stat_sz;\n#if !SANITIZER_FREEBSD && !SANITIZER_IOS\n  extern unsigned struct_stat64_sz;\n#endif\n  extern unsigned struct_rusage_sz;\n  extern unsigned siginfo_t_sz;\n  extern unsigned struct_itimerval_sz;\n  extern unsigned pthread_t_sz;\n  extern unsigned pthread_cond_t_sz;\n  extern unsigned pid_t_sz;\n  extern unsigned timeval_sz;\n  extern unsigned uid_t_sz;\n  extern unsigned gid_t_sz;\n  extern unsigned mbstate_t_sz;\n  extern unsigned struct_timezone_sz;\n  extern unsigned struct_tms_sz;\n  extern unsigned struct_itimerspec_sz;\n  extern unsigned struct_sigevent_sz;\n  extern unsigned struct_sched_param_sz;\n  extern unsigned struct_statfs64_sz;\n\n#if !SANITIZER_ANDROID\n  extern unsigned struct_statfs_sz;\n  extern unsigned struct_sockaddr_sz;\n  extern unsigned ucontext_t_sz;\n#endif // !SANITIZER_ANDROID\n\n#if SANITIZER_LINUX\n\n#if defined(__x86_64__)\n  const unsigned struct_kernel_stat_sz = 144;\n  const unsigned struct_kernel_stat64_sz = 0;\n#elif defined(__i386__)\n  const unsigned struct_kernel_stat_sz = 64;\n  const unsigned struct_kernel_stat64_sz = 96;\n#elif defined(__arm__)\n  const unsigned struct_kernel_stat_sz = 64;\n  const unsigned struct_kernel_stat64_sz = 104;\n#elif defined(__aarch64__)\n  const unsigned struct_kernel_stat_sz = 128;\n  const unsigned struct_kernel_stat64_sz = 104;\n#elif defined(__powerpc__) && !defined(__powerpc64__)\n  const unsigned struct_kernel_stat_sz = 72;\n  const unsigned struct_kernel_stat64_sz = 104;\n#elif defined(__powerpc64__)\n  const unsigned struct_kernel_stat_sz = 144;\n  const unsigned struct_kernel_stat64_sz = 104;\n#elif defined(__mips__)\n  #if SANITIZER_WORDSIZE == 64\n  const unsigned struct_kernel_stat_sz = 216;\n  #else\n  const unsigned struct_kernel_stat_sz = 144;\n  #endif\n  const unsigned struct_kernel_stat64_sz = 104;\n#endif\n  struct __sanitizer_perf_event_attr {\n    unsigned type;\n    unsigned size;\n    // More fields that vary with the kernel version.\n  };\n\n  extern unsigned struct_epoll_event_sz;\n  extern unsigned struct_sysinfo_sz;\n  extern unsigned __user_cap_header_struct_sz;\n  extern unsigned __user_cap_data_struct_sz;\n  extern unsigned struct_new_utsname_sz;\n  extern unsigned struct_old_utsname_sz;\n  extern unsigned struct_oldold_utsname_sz;\n\n  const unsigned struct_kexec_segment_sz = 4 * sizeof(unsigned long);\n#endif  // SANITIZER_LINUX\n\n#if SANITIZER_LINUX || SANITIZER_FREEBSD\n\n#if defined(__powerpc64__)\n  const unsigned struct___old_kernel_stat_sz = 0;\n#else\n  const unsigned struct___old_kernel_stat_sz = 32;\n#endif\n\n  extern unsigned struct_rlimit_sz;\n  extern unsigned struct_utimbuf_sz;\n  extern unsigned struct_timespec_sz;\n\n  struct __sanitizer_iocb {\n    u64   aio_data;\n    u32   aio_key_or_aio_reserved1; // Simply crazy.\n    u32   aio_reserved1_or_aio_key; // Luckily, we don't need these.\n    u16   aio_lio_opcode;\n    s16   aio_reqprio;\n    u32   aio_fildes;\n    u64   aio_buf;\n    u64   aio_nbytes;\n    s64   aio_offset;\n    u64   aio_reserved2;\n    u64   aio_reserved3;\n  };\n\n  struct __sanitizer_io_event {\n    u64 data;\n    u64 obj;\n    u64 res;\n    u64 res2;\n  };\n\n  const unsigned iocb_cmd_pread = 0;\n  const unsigned iocb_cmd_pwrite = 1;\n  const unsigned iocb_cmd_preadv = 7;\n  const unsigned iocb_cmd_pwritev = 8;\n\n  struct __sanitizer___sysctl_args {\n    int *name;\n    int nlen;\n    void *oldval;\n    uptr *oldlenp;\n    void *newval;\n    uptr newlen;\n    unsigned long ___unused[4];\n  };\n\n  const unsigned old_sigset_t_sz = sizeof(unsigned long);\n\n  struct __sanitizer_sem_t {\n#if SANITIZER_ANDROID && defined(_LP64)\n    int data[4];\n#elif SANITIZER_ANDROID && !defined(_LP64)\n    int data;\n#elif SANITIZER_LINUX\n    uptr data[4];\n#elif SANITIZER_FREEBSD\n    u32 data[4];\n#endif\n  };\n#endif // SANITIZER_LINUX || SANITIZER_FREEBSD\n\n#if SANITIZER_ANDROID\n  struct __sanitizer_mallinfo {\n    uptr v[10];\n  };\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n  struct __sanitizer_mallinfo {\n    int v[10];\n  };\n\n  extern unsigned struct_ustat_sz;\n  extern unsigned struct_rlimit64_sz;\n  extern unsigned struct_statvfs64_sz;\n\n  struct __sanitizer_ipc_perm {\n    int __key;\n    int uid;\n    int gid;\n    int cuid;\n    int cgid;\n#ifdef __powerpc__\n    unsigned mode;\n    unsigned __seq;\n    u64 __unused1;\n    u64 __unused2;\n#elif defined(__mips__) || defined(__aarch64__)\n    unsigned int mode;\n    unsigned short __seq;\n    unsigned short __pad1;\n    unsigned long __unused1;\n    unsigned long __unused2;\n#else\n    unsigned short mode;\n    unsigned short __pad1;\n    unsigned short __seq;\n    unsigned short __pad2;\n#if defined(__x86_64__) && !defined(_LP64)\n    u64 __unused1;\n    u64 __unused2;\n#else\n    unsigned long __unused1;\n    unsigned long __unused2;\n#endif\n#endif\n  };\n\n  struct __sanitizer_shmid_ds {\n    __sanitizer_ipc_perm shm_perm;\n  #ifndef __powerpc__\n    uptr shm_segsz;\n  #elif !defined(__powerpc64__)\n    uptr __unused0;\n  #endif\n  #if defined(__x86_64__) && !defined(_LP64)\n    u64 shm_atime;\n    u64 shm_dtime;\n    u64 shm_ctime;\n  #else\n    uptr shm_atime;\n  #if !defined(_LP64) && !defined(__mips__)\n    uptr __unused1;\n  #endif\n    uptr shm_dtime;\n  #if !defined(_LP64) && !defined(__mips__)\n    uptr __unused2;\n  #endif\n    uptr shm_ctime;\n  #if !defined(_LP64) && !defined(__mips__)\n    uptr __unused3;\n  #endif\n  #endif\n  #ifdef __powerpc__\n    uptr shm_segsz;\n  #endif\n    int shm_cpid;\n    int shm_lpid;\n  #if defined(__x86_64__) && !defined(_LP64)\n    u64 shm_nattch;\n    u64 __unused4;\n    u64 __unused5;\n  #else\n    uptr shm_nattch;\n    uptr __unused4;\n    uptr __unused5;\n  #endif\n  };\n#elif SANITIZER_FREEBSD\n  struct __sanitizer_ipc_perm {\n    unsigned int cuid;\n    unsigned int cgid;\n    unsigned int uid;\n    unsigned int gid;\n    unsigned short mode;\n    unsigned short seq;\n    long key;\n  };\n\n  struct __sanitizer_shmid_ds {\n    __sanitizer_ipc_perm shm_perm;\n    unsigned long shm_segsz;\n    unsigned int shm_lpid;\n    unsigned int shm_cpid;\n    int shm_nattch;\n    unsigned long shm_atime;\n    unsigned long shm_dtime;\n    unsigned long shm_ctime;\n  };\n#endif\n\n#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n  extern unsigned struct_msqid_ds_sz;\n  extern unsigned struct_mq_attr_sz;\n  extern unsigned struct_timex_sz;\n  extern unsigned struct_statvfs_sz;\n#endif  // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n\n  struct __sanitizer_iovec {\n    void *iov_base;\n    uptr iov_len;\n  };\n\n#if !SANITIZER_ANDROID\n  struct __sanitizer_ifaddrs {\n    struct __sanitizer_ifaddrs *ifa_next;\n    char *ifa_name;\n    unsigned int ifa_flags;\n    void *ifa_addr;    // (struct sockaddr *)\n    void *ifa_netmask; // (struct sockaddr *)\n    // This is a union on Linux.\n# ifdef ifa_dstaddr\n# undef ifa_dstaddr\n# endif\n    void *ifa_dstaddr; // (struct sockaddr *)\n    void *ifa_data;\n  };\n#endif  // !SANITIZER_ANDROID\n\n#if SANITIZER_MAC\n  typedef unsigned long __sanitizer_pthread_key_t;\n#else\n  typedef unsigned __sanitizer_pthread_key_t;\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n\n  struct __sanitizer_XDR {\n    int x_op;\n    void *x_ops;\n    uptr x_public;\n    uptr x_private;\n    uptr x_base;\n    unsigned x_handy;\n  };\n\n  const int __sanitizer_XDR_ENCODE = 0;\n  const int __sanitizer_XDR_DECODE = 1;\n  const int __sanitizer_XDR_FREE = 2;\n#endif\n\n  struct __sanitizer_passwd {\n    char *pw_name;\n    char *pw_passwd;\n    int pw_uid;\n    int pw_gid;\n#if SANITIZER_MAC || SANITIZER_FREEBSD\n    long pw_change;\n    char *pw_class;\n#endif\n#if !(SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32))\n    char *pw_gecos;\n#endif\n    char *pw_dir;\n    char *pw_shell;\n#if SANITIZER_MAC || SANITIZER_FREEBSD\n    long pw_expire;\n#endif\n#if SANITIZER_FREEBSD\n    int pw_fields;\n#endif\n  };\n\n  struct __sanitizer_group {\n    char *gr_name;\n    char *gr_passwd;\n    int gr_gid;\n    char **gr_mem;\n  };\n\n#if defined(__x86_64__) && !defined(_LP64)\n  typedef long long __sanitizer_time_t;\n#else\n  typedef long __sanitizer_time_t;\n#endif\n\n  struct __sanitizer_timeb {\n    __sanitizer_time_t time;\n    unsigned short millitm;\n    short timezone;\n    short dstflag;\n  };\n\n  struct __sanitizer_ether_addr {\n    u8 octet[6];\n  };\n\n  struct __sanitizer_tm {\n    int tm_sec;\n    int tm_min;\n    int tm_hour;\n    int tm_mday;\n    int tm_mon;\n    int tm_year;\n    int tm_wday;\n    int tm_yday;\n    int tm_isdst;\n    long int tm_gmtoff;\n    const char *tm_zone;\n  };\n\n#if SANITIZER_LINUX\n  struct __sanitizer_mntent {\n    char *mnt_fsname;\n    char *mnt_dir;\n    char *mnt_type;\n    char *mnt_opts;\n    int mnt_freq;\n    int mnt_passno;\n  };\n#endif\n\n#if SANITIZER_MAC || SANITIZER_FREEBSD\n  struct __sanitizer_msghdr {\n    void *msg_name;\n    unsigned msg_namelen;\n    struct __sanitizer_iovec *msg_iov;\n    unsigned msg_iovlen;\n    void *msg_control;\n    unsigned msg_controllen;\n    int msg_flags;\n  };\n  struct __sanitizer_cmsghdr {\n    unsigned cmsg_len;\n    int cmsg_level;\n    int cmsg_type;\n  };\n#else\n  struct __sanitizer_msghdr {\n    void *msg_name;\n    unsigned msg_namelen;\n    struct __sanitizer_iovec *msg_iov;\n    uptr msg_iovlen;\n    void *msg_control;\n    uptr msg_controllen;\n    int msg_flags;\n  };\n  struct __sanitizer_cmsghdr {\n    uptr cmsg_len;\n    int cmsg_level;\n    int cmsg_type;\n  };\n#endif\n\n#if SANITIZER_MAC\n  struct __sanitizer_dirent {\n    unsigned long long d_ino;\n    unsigned long long d_seekoff;\n    unsigned short d_reclen;\n    // more fields that we don't care about\n  };\n#elif SANITIZER_FREEBSD\n  struct __sanitizer_dirent {\n    unsigned int d_fileno;\n    unsigned short d_reclen;\n    // more fields that we don't care about\n  };\n#elif SANITIZER_ANDROID || defined(__x86_64__)\n  struct __sanitizer_dirent {\n    unsigned long long d_ino;\n    unsigned long long d_off;\n    unsigned short d_reclen;\n    // more fields that we don't care about\n  };\n#else\n  struct __sanitizer_dirent {\n    uptr d_ino;\n    uptr d_off;\n    unsigned short d_reclen;\n    // more fields that we don't care about\n  };\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n  struct __sanitizer_dirent64 {\n    unsigned long long d_ino;\n    unsigned long long d_off;\n    unsigned short d_reclen;\n    // more fields that we don't care about\n  };\n#endif\n\n// 'clock_t' is 32 bits wide on x64 FreeBSD\n#if SANITIZER_FREEBSD\n  typedef int __sanitizer_clock_t;\n#elif defined(__x86_64__) && !defined(_LP64)\n  typedef long long __sanitizer_clock_t;\n#else\n  typedef long __sanitizer_clock_t;\n#endif\n\n#if SANITIZER_LINUX\n  typedef int __sanitizer_clockid_t;\n#endif\n\n#if SANITIZER_LINUX || SANITIZER_FREEBSD\n#if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__)\\\n                   || defined(__mips__)\n  typedef unsigned __sanitizer___kernel_uid_t;\n  typedef unsigned __sanitizer___kernel_gid_t;\n#else\n  typedef unsigned short __sanitizer___kernel_uid_t;\n  typedef unsigned short __sanitizer___kernel_gid_t;\n#endif\n#if defined(__x86_64__) && !defined(_LP64)\n  typedef long long __sanitizer___kernel_off_t;\n#else\n  typedef long __sanitizer___kernel_off_t;\n#endif\n\n#if defined(__powerpc__) || defined(__mips__)\n  typedef unsigned int __sanitizer___kernel_old_uid_t;\n  typedef unsigned int __sanitizer___kernel_old_gid_t;\n#else\n  typedef unsigned short __sanitizer___kernel_old_uid_t;\n  typedef unsigned short __sanitizer___kernel_old_gid_t;\n#endif\n\n  typedef long long __sanitizer___kernel_loff_t;\n  typedef struct {\n    unsigned long fds_bits[1024 / (8 * sizeof(long))];\n  } __sanitizer___kernel_fd_set;\n#endif\n\n  // This thing depends on the platform. We are only interested in the upper\n  // limit. Verified with a compiler assert in .cc.\n  const int pthread_attr_t_max_sz = 128;\n  union __sanitizer_pthread_attr_t {\n    char size[pthread_attr_t_max_sz]; // NOLINT\n    void *align;\n  };\n\n#if SANITIZER_ANDROID\n  typedef unsigned long __sanitizer_sigset_t;\n#elif SANITIZER_MAC\n  typedef unsigned __sanitizer_sigset_t;\n#elif SANITIZER_LINUX\n  struct __sanitizer_sigset_t {\n    // The size is determined by looking at sizeof of real sigset_t on linux.\n    uptr val[128 / sizeof(uptr)];\n  };\n#elif SANITIZER_FREEBSD\n  struct __sanitizer_sigset_t {\n     // uint32_t * 4\n     unsigned int __bits[4];\n  };\n#endif\n\n  // Linux system headers define the 'sa_handler' and 'sa_sigaction' macros.\n#if SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 64)\n  struct __sanitizer_sigaction {\n    unsigned sa_flags;\n    union {\n      void (*sigaction)(int sig, void *siginfo, void *uctx);\n      void (*handler)(int sig);\n    };\n    __sanitizer_sigset_t sa_mask;\n    void (*sa_restorer)();\n  };\n#elif SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32)\n  struct __sanitizer_sigaction {\n    union {\n      void (*sigaction)(int sig, void *siginfo, void *uctx);\n      void (*handler)(int sig);\n    };\n    __sanitizer_sigset_t sa_mask;\n    uptr sa_flags;\n    void (*sa_restorer)();\n  };\n#else // !SANITIZER_ANDROID\n  struct __sanitizer_sigaction {\n#if defined(__mips__) && !SANITIZER_FREEBSD\n    unsigned int sa_flags;\n#endif\n    union {\n      void (*sigaction)(int sig, void *siginfo, void *uctx);\n      void (*handler)(int sig);\n    };\n#if SANITIZER_FREEBSD\n    int sa_flags;\n    __sanitizer_sigset_t sa_mask;\n#else\n    __sanitizer_sigset_t sa_mask;\n#ifndef __mips__\n    int sa_flags;\n#endif\n#endif\n#if SANITIZER_LINUX\n    void (*sa_restorer)();\n#endif\n#if defined(__mips__) && (SANITIZER_WORDSIZE == 32)\n    int sa_resv[1];\n#endif\n  };\n#endif // !SANITIZER_ANDROID\n\n#if SANITIZER_FREEBSD\n  typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t;\n#elif defined(__mips__)\n  struct __sanitizer_kernel_sigset_t {\n    u8 sig[16];\n  };\n#else\n  struct __sanitizer_kernel_sigset_t {\n    u8 sig[8];\n  };\n#endif\n\n  // Linux system headers define the 'sa_handler' and 'sa_sigaction' macros.\n  struct __sanitizer_kernel_sigaction_t {\n    union {\n      void (*handler)(int signo);\n      void (*sigaction)(int signo, void *info, void *ctx);\n    };\n    unsigned long sa_flags;\n    void (*sa_restorer)(void);\n    __sanitizer_kernel_sigset_t sa_mask;\n  };\n\n  extern uptr sig_ign;\n  extern uptr sig_dfl;\n  extern uptr sa_siginfo;\n\n#if SANITIZER_LINUX\n  extern int e_tabsz;\n#endif\n\n  extern int af_inet;\n  extern int af_inet6;\n  uptr __sanitizer_in_addr_sz(int af);\n\n#if SANITIZER_LINUX || SANITIZER_FREEBSD\n  struct __sanitizer_dl_phdr_info {\n    uptr dlpi_addr;\n    const char *dlpi_name;\n    const void *dlpi_phdr;\n    short dlpi_phnum;\n  };\n\n  extern unsigned struct_ElfW_Phdr_sz;\n#endif\n\n  struct __sanitizer_addrinfo {\n    int ai_flags;\n    int ai_family;\n    int ai_socktype;\n    int ai_protocol;\n#if SANITIZER_ANDROID || SANITIZER_MAC || SANITIZER_FREEBSD\n    unsigned ai_addrlen;\n    char *ai_canonname;\n    void *ai_addr;\n#else // LINUX\n    unsigned ai_addrlen;\n    void *ai_addr;\n    char *ai_canonname;\n#endif\n    struct __sanitizer_addrinfo *ai_next;\n  };\n\n  struct __sanitizer_hostent {\n    char *h_name;\n    char **h_aliases;\n    int h_addrtype;\n    int h_length;\n    char **h_addr_list;\n  };\n\n  struct __sanitizer_pollfd {\n    int fd;\n    short events;\n    short revents;\n  };\n\n#if SANITIZER_ANDROID || SANITIZER_MAC || SANITIZER_FREEBSD\n  typedef unsigned __sanitizer_nfds_t;\n#else\n  typedef unsigned long __sanitizer_nfds_t;\n#endif\n\n#if !SANITIZER_ANDROID\n# if SANITIZER_LINUX\n  struct __sanitizer_glob_t {\n    uptr gl_pathc;\n    char **gl_pathv;\n    uptr gl_offs;\n    int gl_flags;\n\n    void (*gl_closedir)(void *dirp);\n    void *(*gl_readdir)(void *dirp);\n    void *(*gl_opendir)(const char *);\n    int (*gl_lstat)(const char *, void *);\n    int (*gl_stat)(const char *, void *);\n  };\n# elif SANITIZER_FREEBSD\n  struct __sanitizer_glob_t {\n    uptr gl_pathc;\n    uptr gl_matchc;\n    uptr gl_offs;\n    int gl_flags;\n    char **gl_pathv;\n    int (*gl_errfunc)(const char*, int);\n    void (*gl_closedir)(void *dirp);\n    struct dirent *(*gl_readdir)(void *dirp);\n    void *(*gl_opendir)(const char*);\n    int (*gl_lstat)(const char*, void* /* struct stat* */);\n    int (*gl_stat)(const char*, void* /* struct stat* */);\n  };\n# endif  // SANITIZER_FREEBSD\n\n# if SANITIZER_LINUX || SANITIZER_FREEBSD\n  extern int glob_nomatch;\n  extern int glob_altdirfunc;\n# endif\n#endif  // !SANITIZER_ANDROID\n\n  extern unsigned path_max;\n\n  struct __sanitizer_wordexp_t {\n    uptr we_wordc;\n    char **we_wordv;\n    uptr we_offs;\n#if SANITIZER_FREEBSD\n    char *we_strings;\n    uptr we_nbytes;\n#endif\n  };\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n  struct __sanitizer_FILE {\n    int _flags;\n    char *_IO_read_ptr;\n    char *_IO_read_end;\n    char *_IO_read_base;\n    char *_IO_write_base;\n    char *_IO_write_ptr;\n    char *_IO_write_end;\n    char *_IO_buf_base;\n    char *_IO_buf_end;\n    char *_IO_save_base;\n    char *_IO_backup_base;\n    char *_IO_save_end;\n    void *_markers;\n    __sanitizer_FILE *_chain;\n    int _fileno;\n  };\n# define SANITIZER_HAS_STRUCT_FILE 1\n#else\n  typedef void __sanitizer_FILE;\n# define SANITIZER_HAS_STRUCT_FILE 0\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID && \\\n  (defined(__i386) || defined(__x86_64) || defined(__mips64) || \\\n    defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__))\n  extern unsigned struct_user_regs_struct_sz;\n  extern unsigned struct_user_fpregs_struct_sz;\n  extern unsigned struct_user_fpxregs_struct_sz;\n  extern unsigned struct_user_vfpregs_struct_sz;\n\n  extern int ptrace_peektext;\n  extern int ptrace_peekdata;\n  extern int ptrace_peekuser;\n  extern int ptrace_getregs;\n  extern int ptrace_setregs;\n  extern int ptrace_getfpregs;\n  extern int ptrace_setfpregs;\n  extern int ptrace_getfpxregs;\n  extern int ptrace_setfpxregs;\n  extern int ptrace_getvfpregs;\n  extern int ptrace_setvfpregs;\n  extern int ptrace_getsiginfo;\n  extern int ptrace_setsiginfo;\n  extern int ptrace_getregset;\n  extern int ptrace_setregset;\n  extern int ptrace_geteventmsg;\n#endif\n\n#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n  extern unsigned struct_shminfo_sz;\n  extern unsigned struct_shm_info_sz;\n  extern int shmctl_ipc_stat;\n  extern int shmctl_ipc_info;\n  extern int shmctl_shm_info;\n  extern int shmctl_shm_stat;\n#endif\n\n  extern int map_fixed;\n\n  // ioctl arguments\n  struct __sanitizer_ifconf {\n    int ifc_len;\n    union {\n      void *ifcu_req;\n    } ifc_ifcu;\n#if SANITIZER_MAC\n  } __attribute__((packed));\n#else\n  };\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nstruct __sanitizer__obstack_chunk {\n  char *limit;\n  struct __sanitizer__obstack_chunk *prev;\n};\n\nstruct __sanitizer_obstack {\n  long chunk_size;\n  struct __sanitizer__obstack_chunk *chunk;\n  char *object_base;\n  char *next_free;\n  uptr more_fields[7];\n};\n\ntypedef uptr (*__sanitizer_cookie_io_read)(void *cookie, char *buf, uptr size);\ntypedef uptr (*__sanitizer_cookie_io_write)(void *cookie, const char *buf,\n                                            uptr size);\ntypedef int (*__sanitizer_cookie_io_seek)(void *cookie, u64 *offset,\n                                          int whence);\ntypedef int (*__sanitizer_cookie_io_close)(void *cookie);\n\nstruct __sanitizer_cookie_io_functions_t {\n  __sanitizer_cookie_io_read read;\n  __sanitizer_cookie_io_write write;\n  __sanitizer_cookie_io_seek seek;\n  __sanitizer_cookie_io_close close;\n};\n#endif\n\n#define IOC_NRBITS 8\n#define IOC_TYPEBITS 8\n#if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__)\n#define IOC_SIZEBITS 13\n#define IOC_DIRBITS 3\n#define IOC_NONE 1U\n#define IOC_WRITE 4U\n#define IOC_READ 2U\n#else\n#define IOC_SIZEBITS 14\n#define IOC_DIRBITS 2\n#define IOC_NONE 0U\n#define IOC_WRITE 1U\n#define IOC_READ 2U\n#endif\n#define IOC_NRMASK ((1 << IOC_NRBITS) - 1)\n#define IOC_TYPEMASK ((1 << IOC_TYPEBITS) - 1)\n#define IOC_SIZEMASK ((1 << IOC_SIZEBITS) - 1)\n#if defined(IOC_DIRMASK)\n#undef IOC_DIRMASK\n#endif\n#define IOC_DIRMASK ((1 << IOC_DIRBITS) - 1)\n#define IOC_NRSHIFT 0\n#define IOC_TYPESHIFT (IOC_NRSHIFT + IOC_NRBITS)\n#define IOC_SIZESHIFT (IOC_TYPESHIFT + IOC_TYPEBITS)\n#define IOC_DIRSHIFT (IOC_SIZESHIFT + IOC_SIZEBITS)\n#define EVIOC_EV_MAX 0x1f\n#define EVIOC_ABS_MAX 0x3f\n\n#define IOC_DIR(nr) (((nr) >> IOC_DIRSHIFT) & IOC_DIRMASK)\n#define IOC_TYPE(nr) (((nr) >> IOC_TYPESHIFT) & IOC_TYPEMASK)\n#define IOC_NR(nr) (((nr) >> IOC_NRSHIFT) & IOC_NRMASK)\n#define IOC_SIZE(nr) (((nr) >> IOC_SIZESHIFT) & IOC_SIZEMASK)\n\n  extern unsigned struct_ifreq_sz;\n  extern unsigned struct_termios_sz;\n  extern unsigned struct_winsize_sz;\n\n#if SANITIZER_LINUX\n  extern unsigned struct_arpreq_sz;\n  extern unsigned struct_cdrom_msf_sz;\n  extern unsigned struct_cdrom_multisession_sz;\n  extern unsigned struct_cdrom_read_audio_sz;\n  extern unsigned struct_cdrom_subchnl_sz;\n  extern unsigned struct_cdrom_ti_sz;\n  extern unsigned struct_cdrom_tocentry_sz;\n  extern unsigned struct_cdrom_tochdr_sz;\n  extern unsigned struct_cdrom_volctrl_sz;\n  extern unsigned struct_ff_effect_sz;\n  extern unsigned struct_floppy_drive_params_sz;\n  extern unsigned struct_floppy_drive_struct_sz;\n  extern unsigned struct_floppy_fdc_state_sz;\n  extern unsigned struct_floppy_max_errors_sz;\n  extern unsigned struct_floppy_raw_cmd_sz;\n  extern unsigned struct_floppy_struct_sz;\n  extern unsigned struct_floppy_write_errors_sz;\n  extern unsigned struct_format_descr_sz;\n  extern unsigned struct_hd_driveid_sz;\n  extern unsigned struct_hd_geometry_sz;\n  extern unsigned struct_input_absinfo_sz;\n  extern unsigned struct_input_id_sz;\n  extern unsigned struct_mtpos_sz;\n  extern unsigned struct_termio_sz;\n  extern unsigned struct_vt_consize_sz;\n  extern unsigned struct_vt_sizes_sz;\n  extern unsigned struct_vt_stat_sz;\n#endif  // SANITIZER_LINUX\n\n#if SANITIZER_LINUX || SANITIZER_FREEBSD\n  extern unsigned struct_copr_buffer_sz;\n  extern unsigned struct_copr_debug_buf_sz;\n  extern unsigned struct_copr_msg_sz;\n  extern unsigned struct_midi_info_sz;\n  extern unsigned struct_mtget_sz;\n  extern unsigned struct_mtop_sz;\n  extern unsigned struct_rtentry_sz;\n  extern unsigned struct_sbi_instrument_sz;\n  extern unsigned struct_seq_event_rec_sz;\n  extern unsigned struct_synth_info_sz;\n  extern unsigned struct_vt_mode_sz;\n#endif // SANITIZER_LINUX || SANITIZER_FREEBSD\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n  extern unsigned struct_ax25_parms_struct_sz;\n  extern unsigned struct_cyclades_monitor_sz;\n  extern unsigned struct_input_keymap_entry_sz;\n  extern unsigned struct_ipx_config_data_sz;\n  extern unsigned struct_kbdiacrs_sz;\n  extern unsigned struct_kbentry_sz;\n  extern unsigned struct_kbkeycode_sz;\n  extern unsigned struct_kbsentry_sz;\n  extern unsigned struct_mtconfiginfo_sz;\n  extern unsigned struct_nr_parms_struct_sz;\n  extern unsigned struct_scc_modem_sz;\n  extern unsigned struct_scc_stat_sz;\n  extern unsigned struct_serial_multiport_struct_sz;\n  extern unsigned struct_serial_struct_sz;\n  extern unsigned struct_sockaddr_ax25_sz;\n  extern unsigned struct_unimapdesc_sz;\n  extern unsigned struct_unimapinit_sz;\n#endif  // SANITIZER_LINUX && !SANITIZER_ANDROID\n\n#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n  extern unsigned struct_audio_buf_info_sz;\n  extern unsigned struct_ppp_stats_sz;\n#endif  // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n\n#if !SANITIZER_ANDROID && !SANITIZER_MAC\n  extern unsigned struct_sioc_sg_req_sz;\n  extern unsigned struct_sioc_vif_req_sz;\n#endif\n\n  // ioctl request identifiers\n\n  // A special value to mark ioctls that are not present on the target platform,\n  // when it can not be determined without including any system headers.\n  extern const unsigned IOCTL_NOT_PRESENT;\n\n  extern unsigned IOCTL_FIOASYNC;\n  extern unsigned IOCTL_FIOCLEX;\n  extern unsigned IOCTL_FIOGETOWN;\n  extern unsigned IOCTL_FIONBIO;\n  extern unsigned IOCTL_FIONCLEX;\n  extern unsigned IOCTL_FIOSETOWN;\n  extern unsigned IOCTL_SIOCADDMULTI;\n  extern unsigned IOCTL_SIOCATMARK;\n  extern unsigned IOCTL_SIOCDELMULTI;\n  extern unsigned IOCTL_SIOCGIFADDR;\n  extern unsigned IOCTL_SIOCGIFBRDADDR;\n  extern unsigned IOCTL_SIOCGIFCONF;\n  extern unsigned IOCTL_SIOCGIFDSTADDR;\n  extern unsigned IOCTL_SIOCGIFFLAGS;\n  extern unsigned IOCTL_SIOCGIFMETRIC;\n  extern unsigned IOCTL_SIOCGIFMTU;\n  extern unsigned IOCTL_SIOCGIFNETMASK;\n  extern unsigned IOCTL_SIOCGPGRP;\n  extern unsigned IOCTL_SIOCSIFADDR;\n  extern unsigned IOCTL_SIOCSIFBRDADDR;\n  extern unsigned IOCTL_SIOCSIFDSTADDR;\n  extern unsigned IOCTL_SIOCSIFFLAGS;\n  extern unsigned IOCTL_SIOCSIFMETRIC;\n  extern unsigned IOCTL_SIOCSIFMTU;\n  extern unsigned IOCTL_SIOCSIFNETMASK;\n  extern unsigned IOCTL_SIOCSPGRP;\n  extern unsigned IOCTL_TIOCCONS;\n  extern unsigned IOCTL_TIOCEXCL;\n  extern unsigned IOCTL_TIOCGETD;\n  extern unsigned IOCTL_TIOCGPGRP;\n  extern unsigned IOCTL_TIOCGWINSZ;\n  extern unsigned IOCTL_TIOCMBIC;\n  extern unsigned IOCTL_TIOCMBIS;\n  extern unsigned IOCTL_TIOCMGET;\n  extern unsigned IOCTL_TIOCMSET;\n  extern unsigned IOCTL_TIOCNOTTY;\n  extern unsigned IOCTL_TIOCNXCL;\n  extern unsigned IOCTL_TIOCOUTQ;\n  extern unsigned IOCTL_TIOCPKT;\n  extern unsigned IOCTL_TIOCSCTTY;\n  extern unsigned IOCTL_TIOCSETD;\n  extern unsigned IOCTL_TIOCSPGRP;\n  extern unsigned IOCTL_TIOCSTI;\n  extern unsigned IOCTL_TIOCSWINSZ;\n#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n  extern unsigned IOCTL_SIOCGETSGCNT;\n  extern unsigned IOCTL_SIOCGETVIFCNT;\n#endif\n#if SANITIZER_LINUX\n  extern unsigned IOCTL_EVIOCGABS;\n  extern unsigned IOCTL_EVIOCGBIT;\n  extern unsigned IOCTL_EVIOCGEFFECTS;\n  extern unsigned IOCTL_EVIOCGID;\n  extern unsigned IOCTL_EVIOCGKEY;\n  extern unsigned IOCTL_EVIOCGKEYCODE;\n  extern unsigned IOCTL_EVIOCGLED;\n  extern unsigned IOCTL_EVIOCGNAME;\n  extern unsigned IOCTL_EVIOCGPHYS;\n  extern unsigned IOCTL_EVIOCGRAB;\n  extern unsigned IOCTL_EVIOCGREP;\n  extern unsigned IOCTL_EVIOCGSND;\n  extern unsigned IOCTL_EVIOCGSW;\n  extern unsigned IOCTL_EVIOCGUNIQ;\n  extern unsigned IOCTL_EVIOCGVERSION;\n  extern unsigned IOCTL_EVIOCRMFF;\n  extern unsigned IOCTL_EVIOCSABS;\n  extern unsigned IOCTL_EVIOCSFF;\n  extern unsigned IOCTL_EVIOCSKEYCODE;\n  extern unsigned IOCTL_EVIOCSREP;\n  extern unsigned IOCTL_BLKFLSBUF;\n  extern unsigned IOCTL_BLKGETSIZE;\n  extern unsigned IOCTL_BLKRAGET;\n  extern unsigned IOCTL_BLKRASET;\n  extern unsigned IOCTL_BLKROGET;\n  extern unsigned IOCTL_BLKROSET;\n  extern unsigned IOCTL_BLKRRPART;\n  extern unsigned IOCTL_CDROMAUDIOBUFSIZ;\n  extern unsigned IOCTL_CDROMEJECT;\n  extern unsigned IOCTL_CDROMEJECT_SW;\n  extern unsigned IOCTL_CDROMMULTISESSION;\n  extern unsigned IOCTL_CDROMPAUSE;\n  extern unsigned IOCTL_CDROMPLAYMSF;\n  extern unsigned IOCTL_CDROMPLAYTRKIND;\n  extern unsigned IOCTL_CDROMREADAUDIO;\n  extern unsigned IOCTL_CDROMREADCOOKED;\n  extern unsigned IOCTL_CDROMREADMODE1;\n  extern unsigned IOCTL_CDROMREADMODE2;\n  extern unsigned IOCTL_CDROMREADRAW;\n  extern unsigned IOCTL_CDROMREADTOCENTRY;\n  extern unsigned IOCTL_CDROMREADTOCHDR;\n  extern unsigned IOCTL_CDROMRESET;\n  extern unsigned IOCTL_CDROMRESUME;\n  extern unsigned IOCTL_CDROMSEEK;\n  extern unsigned IOCTL_CDROMSTART;\n  extern unsigned IOCTL_CDROMSTOP;\n  extern unsigned IOCTL_CDROMSUBCHNL;\n  extern unsigned IOCTL_CDROMVOLCTRL;\n  extern unsigned IOCTL_CDROMVOLREAD;\n  extern unsigned IOCTL_CDROM_GET_UPC;\n  extern unsigned IOCTL_FDCLRPRM;\n  extern unsigned IOCTL_FDDEFPRM;\n  extern unsigned IOCTL_FDFLUSH;\n  extern unsigned IOCTL_FDFMTBEG;\n  extern unsigned IOCTL_FDFMTEND;\n  extern unsigned IOCTL_FDFMTTRK;\n  extern unsigned IOCTL_FDGETDRVPRM;\n  extern unsigned IOCTL_FDGETDRVSTAT;\n  extern unsigned IOCTL_FDGETDRVTYP;\n  extern unsigned IOCTL_FDGETFDCSTAT;\n  extern unsigned IOCTL_FDGETMAXERRS;\n  extern unsigned IOCTL_FDGETPRM;\n  extern unsigned IOCTL_FDMSGOFF;\n  extern unsigned IOCTL_FDMSGON;\n  extern unsigned IOCTL_FDPOLLDRVSTAT;\n  extern unsigned IOCTL_FDRAWCMD;\n  extern unsigned IOCTL_FDRESET;\n  extern unsigned IOCTL_FDSETDRVPRM;\n  extern unsigned IOCTL_FDSETEMSGTRESH;\n  extern unsigned IOCTL_FDSETMAXERRS;\n  extern unsigned IOCTL_FDSETPRM;\n  extern unsigned IOCTL_FDTWADDLE;\n  extern unsigned IOCTL_FDWERRORCLR;\n  extern unsigned IOCTL_FDWERRORGET;\n  extern unsigned IOCTL_HDIO_DRIVE_CMD;\n  extern unsigned IOCTL_HDIO_GETGEO;\n  extern unsigned IOCTL_HDIO_GET_32BIT;\n  extern unsigned IOCTL_HDIO_GET_DMA;\n  extern unsigned IOCTL_HDIO_GET_IDENTITY;\n  extern unsigned IOCTL_HDIO_GET_KEEPSETTINGS;\n  extern unsigned IOCTL_HDIO_GET_MULTCOUNT;\n  extern unsigned IOCTL_HDIO_GET_NOWERR;\n  extern unsigned IOCTL_HDIO_GET_UNMASKINTR;\n  extern unsigned IOCTL_HDIO_SET_32BIT;\n  extern unsigned IOCTL_HDIO_SET_DMA;\n  extern unsigned IOCTL_HDIO_SET_KEEPSETTINGS;\n  extern unsigned IOCTL_HDIO_SET_MULTCOUNT;\n  extern unsigned IOCTL_HDIO_SET_NOWERR;\n  extern unsigned IOCTL_HDIO_SET_UNMASKINTR;\n  extern unsigned IOCTL_MTIOCPOS;\n  extern unsigned IOCTL_PPPIOCGASYNCMAP;\n  extern unsigned IOCTL_PPPIOCGDEBUG;\n  extern unsigned IOCTL_PPPIOCGFLAGS;\n  extern unsigned IOCTL_PPPIOCGUNIT;\n  extern unsigned IOCTL_PPPIOCGXASYNCMAP;\n  extern unsigned IOCTL_PPPIOCSASYNCMAP;\n  extern unsigned IOCTL_PPPIOCSDEBUG;\n  extern unsigned IOCTL_PPPIOCSFLAGS;\n  extern unsigned IOCTL_PPPIOCSMAXCID;\n  extern unsigned IOCTL_PPPIOCSMRU;\n  extern unsigned IOCTL_PPPIOCSXASYNCMAP;\n  extern unsigned IOCTL_SIOCDARP;\n  extern unsigned IOCTL_SIOCDRARP;\n  extern unsigned IOCTL_SIOCGARP;\n  extern unsigned IOCTL_SIOCGIFENCAP;\n  extern unsigned IOCTL_SIOCGIFHWADDR;\n  extern unsigned IOCTL_SIOCGIFMAP;\n  extern unsigned IOCTL_SIOCGIFMEM;\n  extern unsigned IOCTL_SIOCGIFNAME;\n  extern unsigned IOCTL_SIOCGIFSLAVE;\n  extern unsigned IOCTL_SIOCGRARP;\n  extern unsigned IOCTL_SIOCGSTAMP;\n  extern unsigned IOCTL_SIOCSARP;\n  extern unsigned IOCTL_SIOCSIFENCAP;\n  extern unsigned IOCTL_SIOCSIFHWADDR;\n  extern unsigned IOCTL_SIOCSIFLINK;\n  extern unsigned IOCTL_SIOCSIFMAP;\n  extern unsigned IOCTL_SIOCSIFMEM;\n  extern unsigned IOCTL_SIOCSIFSLAVE;\n  extern unsigned IOCTL_SIOCSRARP;\n  extern unsigned IOCTL_SNDCTL_COPR_HALT;\n  extern unsigned IOCTL_SNDCTL_COPR_LOAD;\n  extern unsigned IOCTL_SNDCTL_COPR_RCODE;\n  extern unsigned IOCTL_SNDCTL_COPR_RCVMSG;\n  extern unsigned IOCTL_SNDCTL_COPR_RDATA;\n  extern unsigned IOCTL_SNDCTL_COPR_RESET;\n  extern unsigned IOCTL_SNDCTL_COPR_RUN;\n  extern unsigned IOCTL_SNDCTL_COPR_SENDMSG;\n  extern unsigned IOCTL_SNDCTL_COPR_WCODE;\n  extern unsigned IOCTL_SNDCTL_COPR_WDATA;\n  extern unsigned IOCTL_TCFLSH;\n  extern unsigned IOCTL_TCGETA;\n  extern unsigned IOCTL_TCGETS;\n  extern unsigned IOCTL_TCSBRK;\n  extern unsigned IOCTL_TCSBRKP;\n  extern unsigned IOCTL_TCSETA;\n  extern unsigned IOCTL_TCSETAF;\n  extern unsigned IOCTL_TCSETAW;\n  extern unsigned IOCTL_TCSETS;\n  extern unsigned IOCTL_TCSETSF;\n  extern unsigned IOCTL_TCSETSW;\n  extern unsigned IOCTL_TCXONC;\n  extern unsigned IOCTL_TIOCGLCKTRMIOS;\n  extern unsigned IOCTL_TIOCGSOFTCAR;\n  extern unsigned IOCTL_TIOCINQ;\n  extern unsigned IOCTL_TIOCLINUX;\n  extern unsigned IOCTL_TIOCSERCONFIG;\n  extern unsigned IOCTL_TIOCSERGETLSR;\n  extern unsigned IOCTL_TIOCSERGWILD;\n  extern unsigned IOCTL_TIOCSERSWILD;\n  extern unsigned IOCTL_TIOCSLCKTRMIOS;\n  extern unsigned IOCTL_TIOCSSOFTCAR;\n  extern unsigned IOCTL_VT_DISALLOCATE;\n  extern unsigned IOCTL_VT_GETSTATE;\n  extern unsigned IOCTL_VT_RESIZE;\n  extern unsigned IOCTL_VT_RESIZEX;\n  extern unsigned IOCTL_VT_SENDSIG;\n#endif  // SANITIZER_LINUX\n#if SANITIZER_LINUX || SANITIZER_FREEBSD\n  extern unsigned IOCTL_MTIOCGET;\n  extern unsigned IOCTL_MTIOCTOP;\n  extern unsigned IOCTL_SIOCADDRT;\n  extern unsigned IOCTL_SIOCDELRT;\n  extern unsigned IOCTL_SNDCTL_DSP_GETBLKSIZE;\n  extern unsigned IOCTL_SNDCTL_DSP_GETFMTS;\n  extern unsigned IOCTL_SNDCTL_DSP_NONBLOCK;\n  extern unsigned IOCTL_SNDCTL_DSP_POST;\n  extern unsigned IOCTL_SNDCTL_DSP_RESET;\n  extern unsigned IOCTL_SNDCTL_DSP_SETFMT;\n  extern unsigned IOCTL_SNDCTL_DSP_SETFRAGMENT;\n  extern unsigned IOCTL_SNDCTL_DSP_SPEED;\n  extern unsigned IOCTL_SNDCTL_DSP_STEREO;\n  extern unsigned IOCTL_SNDCTL_DSP_SUBDIVIDE;\n  extern unsigned IOCTL_SNDCTL_DSP_SYNC;\n  extern unsigned IOCTL_SNDCTL_FM_4OP_ENABLE;\n  extern unsigned IOCTL_SNDCTL_FM_LOAD_INSTR;\n  extern unsigned IOCTL_SNDCTL_MIDI_INFO;\n  extern unsigned IOCTL_SNDCTL_MIDI_PRETIME;\n  extern unsigned IOCTL_SNDCTL_SEQ_CTRLRATE;\n  extern unsigned IOCTL_SNDCTL_SEQ_GETINCOUNT;\n  extern unsigned IOCTL_SNDCTL_SEQ_GETOUTCOUNT;\n  extern unsigned IOCTL_SNDCTL_SEQ_NRMIDIS;\n  extern unsigned IOCTL_SNDCTL_SEQ_NRSYNTHS;\n  extern unsigned IOCTL_SNDCTL_SEQ_OUTOFBAND;\n  extern unsigned IOCTL_SNDCTL_SEQ_PANIC;\n  extern unsigned IOCTL_SNDCTL_SEQ_PERCMODE;\n  extern unsigned IOCTL_SNDCTL_SEQ_RESET;\n  extern unsigned IOCTL_SNDCTL_SEQ_RESETSAMPLES;\n  extern unsigned IOCTL_SNDCTL_SEQ_SYNC;\n  extern unsigned IOCTL_SNDCTL_SEQ_TESTMIDI;\n  extern unsigned IOCTL_SNDCTL_SEQ_THRESHOLD;\n  extern unsigned IOCTL_SNDCTL_SYNTH_INFO;\n  extern unsigned IOCTL_SNDCTL_SYNTH_MEMAVL;\n  extern unsigned IOCTL_SNDCTL_TMR_CONTINUE;\n  extern unsigned IOCTL_SNDCTL_TMR_METRONOME;\n  extern unsigned IOCTL_SNDCTL_TMR_SELECT;\n  extern unsigned IOCTL_SNDCTL_TMR_SOURCE;\n  extern unsigned IOCTL_SNDCTL_TMR_START;\n  extern unsigned IOCTL_SNDCTL_TMR_STOP;\n  extern unsigned IOCTL_SNDCTL_TMR_TEMPO;\n  extern unsigned IOCTL_SNDCTL_TMR_TIMEBASE;\n  extern unsigned IOCTL_SOUND_MIXER_READ_ALTPCM;\n  extern unsigned IOCTL_SOUND_MIXER_READ_BASS;\n  extern unsigned IOCTL_SOUND_MIXER_READ_CAPS;\n  extern unsigned IOCTL_SOUND_MIXER_READ_CD;\n  extern unsigned IOCTL_SOUND_MIXER_READ_DEVMASK;\n  extern unsigned IOCTL_SOUND_MIXER_READ_ENHANCE;\n  extern unsigned IOCTL_SOUND_MIXER_READ_IGAIN;\n  extern unsigned IOCTL_SOUND_MIXER_READ_IMIX;\n  extern unsigned IOCTL_SOUND_MIXER_READ_LINE1;\n  extern unsigned IOCTL_SOUND_MIXER_READ_LINE2;\n  extern unsigned IOCTL_SOUND_MIXER_READ_LINE3;\n  extern unsigned IOCTL_SOUND_MIXER_READ_LINE;\n  extern unsigned IOCTL_SOUND_MIXER_READ_LOUD;\n  extern unsigned IOCTL_SOUND_MIXER_READ_MIC;\n  extern unsigned IOCTL_SOUND_MIXER_READ_MUTE;\n  extern unsigned IOCTL_SOUND_MIXER_READ_OGAIN;\n  extern unsigned IOCTL_SOUND_MIXER_READ_PCM;\n  extern unsigned IOCTL_SOUND_MIXER_READ_RECLEV;\n  extern unsigned IOCTL_SOUND_MIXER_READ_RECMASK;\n  extern unsigned IOCTL_SOUND_MIXER_READ_RECSRC;\n  extern unsigned IOCTL_SOUND_MIXER_READ_SPEAKER;\n  extern unsigned IOCTL_SOUND_MIXER_READ_STEREODEVS;\n  extern unsigned IOCTL_SOUND_MIXER_READ_SYNTH;\n  extern unsigned IOCTL_SOUND_MIXER_READ_TREBLE;\n  extern unsigned IOCTL_SOUND_MIXER_READ_VOLUME;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_ALTPCM;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_BASS;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_CD;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_ENHANCE;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_IGAIN;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_IMIX;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE1;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE2;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE3;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_LOUD;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_MIC;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_MUTE;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_OGAIN;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_PCM;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_RECLEV;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_RECSRC;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_SPEAKER;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_SYNTH;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_TREBLE;\n  extern unsigned IOCTL_SOUND_MIXER_WRITE_VOLUME;\n  extern unsigned IOCTL_SOUND_PCM_READ_BITS;\n  extern unsigned IOCTL_SOUND_PCM_READ_CHANNELS;\n  extern unsigned IOCTL_SOUND_PCM_READ_FILTER;\n  extern unsigned IOCTL_SOUND_PCM_READ_RATE;\n  extern unsigned IOCTL_SOUND_PCM_WRITE_CHANNELS;\n  extern unsigned IOCTL_SOUND_PCM_WRITE_FILTER;\n  extern unsigned IOCTL_VT_ACTIVATE;\n  extern unsigned IOCTL_VT_GETMODE;\n  extern unsigned IOCTL_VT_OPENQRY;\n  extern unsigned IOCTL_VT_RELDISP;\n  extern unsigned IOCTL_VT_SETMODE;\n  extern unsigned IOCTL_VT_WAITACTIVE;\n#endif  // SANITIZER_LINUX || SANITIZER_FREEBSD\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n  extern unsigned IOCTL_CYGETDEFTHRESH;\n  extern unsigned IOCTL_CYGETDEFTIMEOUT;\n  extern unsigned IOCTL_CYGETMON;\n  extern unsigned IOCTL_CYGETTHRESH;\n  extern unsigned IOCTL_CYGETTIMEOUT;\n  extern unsigned IOCTL_CYSETDEFTHRESH;\n  extern unsigned IOCTL_CYSETDEFTIMEOUT;\n  extern unsigned IOCTL_CYSETTHRESH;\n  extern unsigned IOCTL_CYSETTIMEOUT;\n  extern unsigned IOCTL_EQL_EMANCIPATE;\n  extern unsigned IOCTL_EQL_ENSLAVE;\n  extern unsigned IOCTL_EQL_GETMASTRCFG;\n  extern unsigned IOCTL_EQL_GETSLAVECFG;\n  extern unsigned IOCTL_EQL_SETMASTRCFG;\n  extern unsigned IOCTL_EQL_SETSLAVECFG;\n  extern unsigned IOCTL_EVIOCGKEYCODE_V2;\n  extern unsigned IOCTL_EVIOCGPROP;\n  extern unsigned IOCTL_EVIOCSKEYCODE_V2;\n  extern unsigned IOCTL_FS_IOC_GETFLAGS;\n  extern unsigned IOCTL_FS_IOC_GETVERSION;\n  extern unsigned IOCTL_FS_IOC_SETFLAGS;\n  extern unsigned IOCTL_FS_IOC_SETVERSION;\n  extern unsigned IOCTL_GIO_CMAP;\n  extern unsigned IOCTL_GIO_FONT;\n  extern unsigned IOCTL_GIO_UNIMAP;\n  extern unsigned IOCTL_GIO_UNISCRNMAP;\n  extern unsigned IOCTL_KDADDIO;\n  extern unsigned IOCTL_KDDELIO;\n  extern unsigned IOCTL_KDGETKEYCODE;\n  extern unsigned IOCTL_KDGKBDIACR;\n  extern unsigned IOCTL_KDGKBENT;\n  extern unsigned IOCTL_KDGKBLED;\n  extern unsigned IOCTL_KDGKBMETA;\n  extern unsigned IOCTL_KDGKBSENT;\n  extern unsigned IOCTL_KDMAPDISP;\n  extern unsigned IOCTL_KDSETKEYCODE;\n  extern unsigned IOCTL_KDSIGACCEPT;\n  extern unsigned IOCTL_KDSKBDIACR;\n  extern unsigned IOCTL_KDSKBENT;\n  extern unsigned IOCTL_KDSKBLED;\n  extern unsigned IOCTL_KDSKBMETA;\n  extern unsigned IOCTL_KDSKBSENT;\n  extern unsigned IOCTL_KDUNMAPDISP;\n  extern unsigned IOCTL_LPABORT;\n  extern unsigned IOCTL_LPABORTOPEN;\n  extern unsigned IOCTL_LPCAREFUL;\n  extern unsigned IOCTL_LPCHAR;\n  extern unsigned IOCTL_LPGETIRQ;\n  extern unsigned IOCTL_LPGETSTATUS;\n  extern unsigned IOCTL_LPRESET;\n  extern unsigned IOCTL_LPSETIRQ;\n  extern unsigned IOCTL_LPTIME;\n  extern unsigned IOCTL_LPWAIT;\n  extern unsigned IOCTL_MTIOCGETCONFIG;\n  extern unsigned IOCTL_MTIOCSETCONFIG;\n  extern unsigned IOCTL_PIO_CMAP;\n  extern unsigned IOCTL_PIO_FONT;\n  extern unsigned IOCTL_PIO_UNIMAP;\n  extern unsigned IOCTL_PIO_UNIMAPCLR;\n  extern unsigned IOCTL_PIO_UNISCRNMAP;\n  extern unsigned IOCTL_SCSI_IOCTL_GET_IDLUN;\n  extern unsigned IOCTL_SCSI_IOCTL_PROBE_HOST;\n  extern unsigned IOCTL_SCSI_IOCTL_TAGGED_DISABLE;\n  extern unsigned IOCTL_SCSI_IOCTL_TAGGED_ENABLE;\n  extern unsigned IOCTL_SIOCAIPXITFCRT;\n  extern unsigned IOCTL_SIOCAIPXPRISLT;\n  extern unsigned IOCTL_SIOCAX25ADDUID;\n  extern unsigned IOCTL_SIOCAX25DELUID;\n  extern unsigned IOCTL_SIOCAX25GETPARMS;\n  extern unsigned IOCTL_SIOCAX25GETUID;\n  extern unsigned IOCTL_SIOCAX25NOUID;\n  extern unsigned IOCTL_SIOCAX25SETPARMS;\n  extern unsigned IOCTL_SIOCDEVPLIP;\n  extern unsigned IOCTL_SIOCIPXCFGDATA;\n  extern unsigned IOCTL_SIOCNRDECOBS;\n  extern unsigned IOCTL_SIOCNRGETPARMS;\n  extern unsigned IOCTL_SIOCNRRTCTL;\n  extern unsigned IOCTL_SIOCNRSETPARMS;\n  extern unsigned IOCTL_SNDCTL_DSP_GETISPACE;\n  extern unsigned IOCTL_SNDCTL_DSP_GETOSPACE;\n  extern unsigned IOCTL_TIOCGSERIAL;\n  extern unsigned IOCTL_TIOCSERGETMULTI;\n  extern unsigned IOCTL_TIOCSERSETMULTI;\n  extern unsigned IOCTL_TIOCSSERIAL;\n#endif  // SANITIZER_LINUX && !SANITIZER_ANDROID\n\n#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID\n  extern unsigned IOCTL_GIO_SCRNMAP;\n  extern unsigned IOCTL_KDDISABIO;\n  extern unsigned IOCTL_KDENABIO;\n  extern unsigned IOCTL_KDGETLED;\n  extern unsigned IOCTL_KDGETMODE;\n  extern unsigned IOCTL_KDGKBMODE;\n  extern unsigned IOCTL_KDGKBTYPE;\n  extern unsigned IOCTL_KDMKTONE;\n  extern unsigned IOCTL_KDSETLED;\n  extern unsigned IOCTL_KDSETMODE;\n  extern unsigned IOCTL_KDSKBMODE;\n  extern unsigned IOCTL_KIOCSOUND;\n  extern unsigned IOCTL_PIO_SCRNMAP;\n#endif\n\n  extern const int errno_EINVAL;\n  extern const int errno_EOWNERDEAD;\n\n  extern const int si_SEGV_MAPERR;\n  extern const int si_SEGV_ACCERR;\n}  // namespace __sanitizer\n\n#define CHECK_TYPE_SIZE(TYPE) \\\n  COMPILER_CHECK(sizeof(__sanitizer_##TYPE) == sizeof(TYPE))\n\n#define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER)                       \\\n  COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *) NULL)->MEMBER) == \\\n                 sizeof(((CLASS *) NULL)->MEMBER));                \\\n  COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) ==          \\\n                 offsetof(CLASS, MEMBER))\n\n// For sigaction, which is a function and struct at the same time,\n// and thus requires explicit \"struct\" in sizeof() expression.\n#define CHECK_STRUCT_SIZE_AND_OFFSET(CLASS, MEMBER)                       \\\n  COMPILER_CHECK(sizeof(((struct __sanitizer_##CLASS *) NULL)->MEMBER) == \\\n                 sizeof(((struct CLASS *) NULL)->MEMBER));                \\\n  COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) ==          \\\n                 offsetof(struct CLASS, MEMBER))\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_posix.cc",
    "content": "//===-- sanitizer_posix.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries and implements POSIX-specific functions from\n// sanitizer_posix.h.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n\n#if SANITIZER_POSIX\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_posix.h\"\n#include \"sanitizer_procmaps.h\"\n#include \"sanitizer_stacktrace.h\"\n\n#include <fcntl.h>\n#include <signal.h>\n#include <sys/mman.h>\n\n#if SANITIZER_LINUX\n#include <sys/utsname.h>\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n#include <sys/personality.h>\n#endif\n\n#if SANITIZER_FREEBSD\n// The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before\n// that, it was never implemented.  So just define it to zero.\n#undef  MAP_NORESERVE\n#define MAP_NORESERVE 0\n#endif\n\nnamespace __sanitizer {\n\n// ------------- sanitizer_common.h\nuptr GetMmapGranularity() {\n  return GetPageSize();\n}\n\n#if SANITIZER_WORDSIZE == 32\n// Take care of unusable kernel area in top gigabyte.\nstatic uptr GetKernelAreaSize() {\n#if SANITIZER_LINUX && !SANITIZER_X32\n  const uptr gbyte = 1UL << 30;\n\n  // Firstly check if there are writable segments\n  // mapped to top gigabyte (e.g. stack).\n  MemoryMappingLayout proc_maps(/*cache_enabled*/true);\n  uptr end, prot;\n  while (proc_maps.Next(/*start*/nullptr, &end,\n                        /*offset*/nullptr, /*filename*/nullptr,\n                        /*filename_size*/0, &prot)) {\n    if ((end >= 3 * gbyte)\n        && (prot & MemoryMappingLayout::kProtectionWrite) != 0)\n      return 0;\n  }\n\n#if !SANITIZER_ANDROID\n  // Even if nothing is mapped, top Gb may still be accessible\n  // if we are running on 64-bit kernel.\n  // Uname may report misleading results if personality type\n  // is modified (e.g. under schroot) so check this as well.\n  struct utsname uname_info;\n  int pers = personality(0xffffffffUL);\n  if (!(pers & PER_MASK)\n      && uname(&uname_info) == 0\n      && internal_strstr(uname_info.machine, \"64\"))\n    return 0;\n#endif  // SANITIZER_ANDROID\n\n  // Top gigabyte is reserved for kernel.\n  return gbyte;\n#else\n  return 0;\n#endif  // SANITIZER_LINUX && !SANITIZER_X32\n}\n#endif  // SANITIZER_WORDSIZE == 32\n\nuptr GetMaxVirtualAddress() {\n#if SANITIZER_WORDSIZE == 64\n# if defined(__powerpc64__) || defined(__aarch64__)\n  // On PowerPC64 we have two different address space layouts: 44- and 46-bit.\n  // We somehow need to figure out which one we are using now and choose\n  // one of 0x00000fffffffffffUL and 0x00003fffffffffffUL.\n  // Note that with 'ulimit -s unlimited' the stack is moved away from the top\n  // of the address space, so simply checking the stack address is not enough.\n  // This should (does) work for both PowerPC64 Endian modes.\n  // Similarly, aarch64 has multiple address space layouts: 39, 42 and 47-bit.\n  return (1ULL << (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1)) - 1;\n# elif defined(__mips64)\n  return (1ULL << 40) - 1;  // 0x000000ffffffffffUL;\n# else\n  return (1ULL << 47) - 1;  // 0x00007fffffffffffUL;\n# endif\n#else  // SANITIZER_WORDSIZE == 32\n  uptr res = (1ULL << 32) - 1;  // 0xffffffff;\n  if (!common_flags()->full_address_space)\n    res -= GetKernelAreaSize();\n  CHECK_LT(reinterpret_cast<uptr>(&res), res);\n  return res;\n#endif  // SANITIZER_WORDSIZE\n}\n\nvoid *MmapOrDie(uptr size, const char *mem_type, bool raw_report) {\n  size = RoundUpTo(size, GetPageSizeCached());\n  uptr res = internal_mmap(nullptr, size,\n                           PROT_READ | PROT_WRITE,\n                           MAP_PRIVATE | MAP_ANON, -1, 0);\n  int reserrno;\n  if (internal_iserror(res, &reserrno))\n    ReportMmapFailureAndDie(size, mem_type, \"allocate\", reserrno, raw_report);\n  IncreaseTotalMmap(size);\n  return (void *)res;\n}\n\nvoid UnmapOrDie(void *addr, uptr size) {\n  if (!addr || !size) return;\n  uptr res = internal_munmap(addr, size);\n  if (internal_iserror(res)) {\n    Report(\"ERROR: %s failed to deallocate 0x%zx (%zd) bytes at address %p\\n\",\n           SanitizerToolName, size, size, addr);\n    CHECK(\"unable to unmap\" && 0);\n  }\n  DecreaseTotalMmap(size);\n}\n\nvoid *MmapNoReserveOrDie(uptr size, const char *mem_type) {\n  uptr PageSize = GetPageSizeCached();\n  uptr p = internal_mmap(nullptr,\n                         RoundUpTo(size, PageSize),\n                         PROT_READ | PROT_WRITE,\n                         MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,\n                         -1, 0);\n  int reserrno;\n  if (internal_iserror(p, &reserrno))\n    ReportMmapFailureAndDie(size, mem_type, \"allocate noreserve\", reserrno);\n  IncreaseTotalMmap(size);\n  return (void *)p;\n}\n\nvoid *MmapFixedOrDie(uptr fixed_addr, uptr size) {\n  uptr PageSize = GetPageSizeCached();\n  uptr p = internal_mmap((void*)(fixed_addr & ~(PageSize - 1)),\n      RoundUpTo(size, PageSize),\n      PROT_READ | PROT_WRITE,\n      MAP_PRIVATE | MAP_ANON | MAP_FIXED,\n      -1, 0);\n  int reserrno;\n  if (internal_iserror(p, &reserrno)) {\n    char mem_type[30];\n    internal_snprintf(mem_type, sizeof(mem_type), \"memory at address 0x%zx\",\n                      fixed_addr);\n    ReportMmapFailureAndDie(size, mem_type, \"allocate\", reserrno);\n  }\n  IncreaseTotalMmap(size);\n  return (void *)p;\n}\n\nbool MprotectNoAccess(uptr addr, uptr size) {\n  return 0 == internal_mprotect((void*)addr, size, PROT_NONE);\n}\n\nfd_t OpenFile(const char *filename, FileAccessMode mode, error_t *errno_p) {\n  int flags;\n  switch (mode) {\n    case RdOnly: flags = O_RDONLY; break;\n    case WrOnly: flags = O_WRONLY | O_CREAT; break;\n    case RdWr: flags = O_RDWR | O_CREAT; break;\n  }\n  fd_t res = internal_open(filename, flags, 0660);\n  if (internal_iserror(res, errno_p))\n    return kInvalidFd;\n  return res;\n}\n\nvoid CloseFile(fd_t fd) {\n  internal_close(fd);\n}\n\nbool ReadFromFile(fd_t fd, void *buff, uptr buff_size, uptr *bytes_read,\n                  error_t *error_p) {\n  uptr res = internal_read(fd, buff, buff_size);\n  if (internal_iserror(res, error_p))\n    return false;\n  if (bytes_read)\n    *bytes_read = res;\n  return true;\n}\n\nbool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written,\n                 error_t *error_p) {\n  uptr res = internal_write(fd, buff, buff_size);\n  if (internal_iserror(res, error_p))\n    return false;\n  if (bytes_written)\n    *bytes_written = res;\n  return true;\n}\n\nbool RenameFile(const char *oldpath, const char *newpath, error_t *error_p) {\n  uptr res = internal_rename(oldpath, newpath);\n  return !internal_iserror(res, error_p);\n}\n\nvoid *MapFileToMemory(const char *file_name, uptr *buff_size) {\n  fd_t fd = OpenFile(file_name, RdOnly);\n  CHECK(fd != kInvalidFd);\n  uptr fsize = internal_filesize(fd);\n  CHECK_NE(fsize, (uptr)-1);\n  CHECK_GT(fsize, 0);\n  *buff_size = RoundUpTo(fsize, GetPageSizeCached());\n  uptr map = internal_mmap(nullptr, *buff_size, PROT_READ, MAP_PRIVATE, fd, 0);\n  return internal_iserror(map) ? nullptr : (void *)map;\n}\n\nvoid *MapWritableFileToMemory(void *addr, uptr size, fd_t fd, OFF_T offset) {\n  uptr flags = MAP_SHARED;\n  if (addr) flags |= MAP_FIXED;\n  uptr p = internal_mmap(addr, size, PROT_READ | PROT_WRITE, flags, fd, offset);\n  int mmap_errno = 0;\n  if (internal_iserror(p, &mmap_errno)) {\n    Printf(\"could not map writable file (%d, %lld, %zu): %zd, errno: %d\\n\",\n           fd, (long long)offset, size, p, mmap_errno);\n    return nullptr;\n  }\n  return (void *)p;\n}\n\nstatic inline bool IntervalsAreSeparate(uptr start1, uptr end1,\n                                        uptr start2, uptr end2) {\n  CHECK(start1 <= end1);\n  CHECK(start2 <= end2);\n  return (end1 < start2) || (end2 < start1);\n}\n\n// FIXME: this is thread-unsafe, but should not cause problems most of the time.\n// When the shadow is mapped only a single thread usually exists (plus maybe\n// several worker threads on Mac, which aren't expected to map big chunks of\n// memory).\nbool MemoryRangeIsAvailable(uptr range_start, uptr range_end) {\n  MemoryMappingLayout proc_maps(/*cache_enabled*/true);\n  uptr start, end;\n  while (proc_maps.Next(&start, &end,\n                        /*offset*/nullptr, /*filename*/nullptr,\n                        /*filename_size*/0, /*protection*/nullptr)) {\n    if (start == end) continue;  // Empty range.\n    CHECK_NE(0, end);\n    if (!IntervalsAreSeparate(start, end - 1, range_start, range_end))\n      return false;\n  }\n  return true;\n}\n\nvoid DumpProcessMap() {\n  MemoryMappingLayout proc_maps(/*cache_enabled*/true);\n  uptr start, end;\n  const sptr kBufSize = 4095;\n  char *filename = (char*)MmapOrDie(kBufSize, __func__);\n  Report(\"Process memory map follows:\\n\");\n  while (proc_maps.Next(&start, &end, /* file_offset */nullptr,\n                        filename, kBufSize, /* protection */nullptr)) {\n    Printf(\"\\t%p-%p\\t%s\\n\", (void*)start, (void*)end, filename);\n  }\n  Report(\"End of process memory map.\\n\");\n  UnmapOrDie(filename, kBufSize);\n}\n\nconst char *GetPwd() {\n  return GetEnv(\"PWD\");\n}\n\nbool IsPathSeparator(const char c) {\n  return c == '/';\n}\n\nbool IsAbsolutePath(const char *path) {\n  return path != nullptr && IsPathSeparator(path[0]);\n}\n\nvoid ReportFile::Write(const char *buffer, uptr length) {\n  SpinMutexLock l(mu);\n  static const char *kWriteError =\n      \"ReportFile::Write() can't output requested buffer!\\n\";\n  ReopenIfNecessary();\n  if (length != internal_write(fd, buffer, length)) {\n    internal_write(fd, kWriteError, internal_strlen(kWriteError));\n    Die();\n  }\n}\n\nbool GetCodeRangeForFile(const char *module, uptr *start, uptr *end) {\n  uptr s, e, off, prot;\n  InternalScopedString buff(kMaxPathLength);\n  MemoryMappingLayout proc_maps(/*cache_enabled*/false);\n  while (proc_maps.Next(&s, &e, &off, buff.data(), buff.size(), &prot)) {\n    if ((prot & MemoryMappingLayout::kProtectionExecute) != 0\n        && internal_strcmp(module, buff.data()) == 0) {\n      *start = s;\n      *end = e;\n      return true;\n    }\n  }\n  return false;\n}\n\nSignalContext SignalContext::Create(void *siginfo, void *context) {\n  uptr addr = (uptr)((siginfo_t*)siginfo)->si_addr;\n  uptr pc, sp, bp;\n  GetPcSpBp(context, &pc, &sp, &bp);\n  return SignalContext(context, addr, pc, sp, bp);\n}\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_POSIX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_posix.h",
    "content": "//===-- sanitizer_posix.h -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries and declares some useful POSIX-specific functions.\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_POSIX_H\n#define SANITIZER_POSIX_H\n\n// ----------- ATTENTION -------------\n// This header should NOT include any other headers from sanitizer runtime.\n#include \"sanitizer_internal_defs.h\"\n\n#if !SANITIZER_POSIX\n// Make it hard to accidentally use any of functions declared in this file:\n#error This file should only be included on POSIX\n#endif\n\nnamespace __sanitizer {\n\n// I/O\n// Don't use directly, use __sanitizer::OpenFile() instead.\nuptr internal_open(const char *filename, int flags);\nuptr internal_open(const char *filename, int flags, u32 mode);\nuptr internal_close(fd_t fd);\n\nuptr internal_read(fd_t fd, void *buf, uptr count);\nuptr internal_write(fd_t fd, const void *buf, uptr count);\n\n// Memory\nuptr internal_mmap(void *addr, uptr length, int prot, int flags,\n                   int fd, OFF_T offset);\nuptr internal_munmap(void *addr, uptr length);\nint internal_mprotect(void *addr, uptr length, int prot);\n\n// OS\nuptr internal_filesize(fd_t fd);  // -1 on error.\nuptr internal_stat(const char *path, void *buf);\nuptr internal_lstat(const char *path, void *buf);\nuptr internal_fstat(fd_t fd, void *buf);\nuptr internal_dup2(int oldfd, int newfd);\nuptr internal_readlink(const char *path, char *buf, uptr bufsize);\nuptr internal_unlink(const char *path);\nuptr internal_rename(const char *oldpath, const char *newpath);\nuptr internal_lseek(fd_t fd, OFF_T offset, int whence);\n\nuptr internal_ptrace(int request, int pid, void *addr, void *data);\nuptr internal_waitpid(int pid, int *status, int options);\n\nint internal_fork();\nint internal_forkpty(int *amaster);\n\n// These functions call appropriate pthread_ functions directly, bypassing\n// the interceptor. They are weak and may not be present in some tools.\nSANITIZER_WEAK_ATTRIBUTE\nint real_pthread_create(void *th, void *attr, void *(*callback)(void *),\n                        void *param);\nSANITIZER_WEAK_ATTRIBUTE\nint real_pthread_join(void *th, void **ret);\n\n#define DEFINE_REAL_PTHREAD_FUNCTIONS                                          \\\n  namespace __sanitizer {                                                      \\\n  int real_pthread_create(void *th, void *attr, void *(*callback)(void *),     \\\n                          void *param) {                                       \\\n    return REAL(pthread_create)(th, attr, callback, param);                    \\\n  }                                                                            \\\n  int real_pthread_join(void *th, void **ret) {                                \\\n    return REAL(pthread_join(th, ret));                                        \\\n  }                                                                            \\\n  }  // namespace __sanitizer\n\nint my_pthread_attr_getstack(void *attr, void **addr, uptr *size);\n\nint internal_sigaction(int signum, const void *act, void *oldact);\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_POSIX_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc",
    "content": "//===-- sanitizer_posix_libcdep.cc ----------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries and implements libc-dependent POSIX-specific functions\n// from sanitizer_libc.h.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n\n#if SANITIZER_POSIX\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_platform_limits_posix.h\"\n#include \"sanitizer_posix.h\"\n#include \"sanitizer_procmaps.h\"\n#include \"sanitizer_stacktrace.h\"\n#include \"sanitizer_symbolizer.h\"\n\n#include <errno.h>\n#include <fcntl.h>\n#include <pthread.h>\n#include <signal.h>\n#include <stdlib.h>\n#include <sys/mman.h>\n#include <sys/resource.h>\n#include <sys/stat.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#if SANITIZER_FREEBSD\n// The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before\n// that, it was never implemented.  So just define it to zero.\n#undef  MAP_NORESERVE\n#define MAP_NORESERVE 0\n#endif\n\nnamespace __sanitizer {\n\nu32 GetUid() {\n  return getuid();\n}\n\nuptr GetThreadSelf() {\n  return (uptr)pthread_self();\n}\n\nvoid FlushUnneededShadowMemory(uptr addr, uptr size) {\n  madvise((void*)addr, size, MADV_DONTNEED);\n}\n\nvoid NoHugePagesInRegion(uptr addr, uptr size) {\n#ifdef MADV_NOHUGEPAGE  // May not be defined on old systems.\n  madvise((void *)addr, size, MADV_NOHUGEPAGE);\n#endif  // MADV_NOHUGEPAGE\n}\n\nvoid DontDumpShadowMemory(uptr addr, uptr length) {\n#ifdef MADV_DONTDUMP\n  madvise((void *)addr, length, MADV_DONTDUMP);\n#endif\n}\n\nstatic rlim_t getlim(int res) {\n  rlimit rlim;\n  CHECK_EQ(0, getrlimit(res, &rlim));\n  return rlim.rlim_cur;\n}\n\nstatic void setlim(int res, rlim_t lim) {\n  // The following magic is to prevent clang from replacing it with memset.\n  volatile struct rlimit rlim;\n  rlim.rlim_cur = lim;\n  rlim.rlim_max = lim;\n  if (setrlimit(res, const_cast<struct rlimit *>(&rlim))) {\n    Report(\"ERROR: %s setrlimit() failed %d\\n\", SanitizerToolName, errno);\n    Die();\n  }\n}\n\nvoid DisableCoreDumperIfNecessary() {\n  if (common_flags()->disable_coredump) {\n    setlim(RLIMIT_CORE, 0);\n  }\n}\n\nbool StackSizeIsUnlimited() {\n  rlim_t stack_size = getlim(RLIMIT_STACK);\n  return (stack_size == RLIM_INFINITY);\n}\n\nvoid SetStackSizeLimitInBytes(uptr limit) {\n  setlim(RLIMIT_STACK, (rlim_t)limit);\n  CHECK(!StackSizeIsUnlimited());\n}\n\nbool AddressSpaceIsUnlimited() {\n  rlim_t as_size = getlim(RLIMIT_AS);\n  return (as_size == RLIM_INFINITY);\n}\n\nvoid SetAddressSpaceUnlimited() {\n  setlim(RLIMIT_AS, RLIM_INFINITY);\n  CHECK(AddressSpaceIsUnlimited());\n}\n\nvoid SleepForSeconds(int seconds) {\n  sleep(seconds);\n}\n\nvoid SleepForMillis(int millis) {\n  usleep(millis * 1000);\n}\n\nvoid Abort() {\n  abort();\n}\n\nint Atexit(void (*function)(void)) {\n#ifndef SANITIZER_GO\n  return atexit(function);\n#else\n  return 0;\n#endif\n}\n\nbool SupportsColoredOutput(fd_t fd) {\n  return isatty(fd) != 0;\n}\n\n#ifndef SANITIZER_GO\n// TODO(glider): different tools may require different altstack size.\nstatic const uptr kAltStackSize = SIGSTKSZ * 4;  // SIGSTKSZ is not enough.\n\nvoid SetAlternateSignalStack() {\n  stack_t altstack, oldstack;\n  CHECK_EQ(0, sigaltstack(nullptr, &oldstack));\n  // If the alternate stack is already in place, do nothing.\n  // Android always sets an alternate stack, but it's too small for us.\n  if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) return;\n  // TODO(glider): the mapped stack should have the MAP_STACK flag in the\n  // future. It is not required by man 2 sigaltstack now (they're using\n  // malloc()).\n  void* base = MmapOrDie(kAltStackSize, __func__);\n  altstack.ss_sp = (char*) base;\n  altstack.ss_flags = 0;\n  altstack.ss_size = kAltStackSize;\n  CHECK_EQ(0, sigaltstack(&altstack, nullptr));\n}\n\nvoid UnsetAlternateSignalStack() {\n  stack_t altstack, oldstack;\n  altstack.ss_sp = nullptr;\n  altstack.ss_flags = SS_DISABLE;\n  altstack.ss_size = kAltStackSize;  // Some sane value required on Darwin.\n  CHECK_EQ(0, sigaltstack(&altstack, &oldstack));\n  UnmapOrDie(oldstack.ss_sp, oldstack.ss_size);\n}\n\ntypedef void (*sa_sigaction_t)(int, siginfo_t *, void *);\nstatic void MaybeInstallSigaction(int signum,\n                                  SignalHandlerType handler) {\n  if (!IsDeadlySignal(signum))\n    return;\n  struct sigaction sigact;\n  internal_memset(&sigact, 0, sizeof(sigact));\n  sigact.sa_sigaction = (sa_sigaction_t)handler;\n  // Do not block the signal from being received in that signal's handler.\n  // Clients are responsible for handling this correctly.\n  sigact.sa_flags = SA_SIGINFO | SA_NODEFER;\n  if (common_flags()->use_sigaltstack) sigact.sa_flags |= SA_ONSTACK;\n  CHECK_EQ(0, internal_sigaction(signum, &sigact, nullptr));\n  VReport(1, \"Installed the sigaction for signal %d\\n\", signum);\n}\n\nvoid InstallDeadlySignalHandlers(SignalHandlerType handler) {\n  // Set the alternate signal stack for the main thread.\n  // This will cause SetAlternateSignalStack to be called twice, but the stack\n  // will be actually set only once.\n  if (common_flags()->use_sigaltstack) SetAlternateSignalStack();\n  MaybeInstallSigaction(SIGSEGV, handler);\n  MaybeInstallSigaction(SIGBUS, handler);\n  MaybeInstallSigaction(SIGABRT, handler);\n  MaybeInstallSigaction(SIGFPE, handler);\n  MaybeInstallSigaction(SIGILL, handler);\n}\n#endif  // SANITIZER_GO\n\nbool IsAccessibleMemoryRange(uptr beg, uptr size) {\n  uptr page_size = GetPageSizeCached();\n  // Checking too large memory ranges is slow.\n  CHECK_LT(size, page_size * 10);\n  int sock_pair[2];\n  if (pipe(sock_pair))\n    return false;\n  uptr bytes_written =\n      internal_write(sock_pair[1], reinterpret_cast<void *>(beg), size);\n  int write_errno;\n  bool result;\n  if (internal_iserror(bytes_written, &write_errno)) {\n    CHECK_EQ(EFAULT, write_errno);\n    result = false;\n  } else {\n    result = (bytes_written == size);\n  }\n  internal_close(sock_pair[0]);\n  internal_close(sock_pair[1]);\n  return result;\n}\n\nvoid PrepareForSandboxing(__sanitizer_sandbox_arguments *args) {\n  // Some kinds of sandboxes may forbid filesystem access, so we won't be able\n  // to read the file mappings from /proc/self/maps. Luckily, neither the\n  // process will be able to load additional libraries, so it's fine to use the\n  // cached mappings.\n  MemoryMappingLayout::CacheMemoryMappings();\n  // Same for /proc/self/exe in the symbolizer.\n#if !SANITIZER_GO\n  Symbolizer::GetOrInit()->PrepareForSandboxing();\n  CovPrepareForSandboxing(args);\n#endif\n}\n\n#if SANITIZER_ANDROID || SANITIZER_GO\nint GetNamedMappingFd(const char *name, uptr size) {\n  return -1;\n}\n#else\nint GetNamedMappingFd(const char *name, uptr size) {\n  if (!common_flags()->decorate_proc_maps)\n    return -1;\n  char shmname[200];\n  CHECK(internal_strlen(name) < sizeof(shmname) - 10);\n  internal_snprintf(shmname, sizeof(shmname), \"%zu [%s]\", internal_getpid(),\n                    name);\n  int fd = shm_open(shmname, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU);\n  CHECK_GE(fd, 0);\n  int res = internal_ftruncate(fd, size);\n  CHECK_EQ(0, res);\n  res = shm_unlink(shmname);\n  CHECK_EQ(0, res);\n  return fd;\n}\n#endif\n\nvoid *MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) {\n  int fd = name ? GetNamedMappingFd(name, size) : -1;\n  unsigned flags = MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE;\n  if (fd == -1) flags |= MAP_ANON;\n\n  uptr PageSize = GetPageSizeCached();\n  uptr p = internal_mmap((void *)(fixed_addr & ~(PageSize - 1)),\n                         RoundUpTo(size, PageSize), PROT_READ | PROT_WRITE,\n                         flags, fd, 0);\n  int reserrno;\n  if (internal_iserror(p, &reserrno))\n    Report(\"ERROR: %s failed to \"\n           \"allocate 0x%zx (%zd) bytes at address %zx (errno: %d)\\n\",\n           SanitizerToolName, size, size, fixed_addr, reserrno);\n  IncreaseTotalMmap(size);\n  return (void *)p;\n}\n\nvoid *MmapNoAccess(uptr fixed_addr, uptr size, const char *name) {\n  int fd = name ? GetNamedMappingFd(name, size) : -1;\n  unsigned flags = MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE;\n  if (fd == -1) flags |= MAP_ANON;\n\n  return (void *)internal_mmap((void *)fixed_addr, size, PROT_NONE, flags, fd,\n                               0);\n}\n\n// This function is defined elsewhere if we intercepted pthread_attr_getstack.\nextern \"C\" {\nSANITIZER_WEAK_ATTRIBUTE int\nreal_pthread_attr_getstack(void *attr, void **addr, size_t *size);\n} // extern \"C\"\n\nint my_pthread_attr_getstack(void *attr, void **addr, uptr *size) {\n#if !SANITIZER_GO && !SANITIZER_MAC\n  if (&real_pthread_attr_getstack)\n    return real_pthread_attr_getstack((pthread_attr_t *)attr, addr,\n                                      (size_t *)size);\n#endif\n  return pthread_attr_getstack((pthread_attr_t *)attr, addr, (size_t *)size);\n}\n\n#if !SANITIZER_GO\nvoid AdjustStackSize(void *attr_) {\n  pthread_attr_t *attr = (pthread_attr_t *)attr_;\n  uptr stackaddr = 0;\n  uptr stacksize = 0;\n  my_pthread_attr_getstack(attr, (void**)&stackaddr, &stacksize);\n  // GLibC will return (0 - stacksize) as the stack address in the case when\n  // stacksize is set, but stackaddr is not.\n  bool stack_set = (stackaddr != 0) && (stackaddr + stacksize != 0);\n  // We place a lot of tool data into TLS, account for that.\n  const uptr minstacksize = GetTlsSize() + 128*1024;\n  if (stacksize < minstacksize) {\n    if (!stack_set) {\n      if (stacksize != 0) {\n        VPrintf(1, \"Sanitizer: increasing stacksize %zu->%zu\\n\", stacksize,\n                minstacksize);\n        pthread_attr_setstacksize(attr, minstacksize);\n      }\n    } else {\n      Printf(\"Sanitizer: pre-allocated stack size is insufficient: \"\n             \"%zu < %zu\\n\", stacksize, minstacksize);\n      Printf(\"Sanitizer: pthread_create is likely to fail.\\n\");\n    }\n  }\n}\n#endif // !SANITIZER_GO\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_POSIX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_printf.cc",
    "content": "//===-- sanitizer_printf.cc -----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer.\n//\n// Internal printf function, used inside run-time libraries.\n// We can't use libc printf because we intercept some of the functions used\n// inside it.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_libc.h\"\n\n#include <stdio.h>\n#include <stdarg.h>\n\n#if SANITIZER_WINDOWS && defined(_MSC_VER) && _MSC_VER < 1800 &&               \\\n      !defined(va_copy)\n# define va_copy(dst, src) ((dst) = (src))\n#endif\n\nnamespace __sanitizer {\n\nStaticSpinMutex CommonSanitizerReportMutex;\n\nstatic int AppendChar(char **buff, const char *buff_end, char c) {\n  if (*buff < buff_end) {\n    **buff = c;\n    (*buff)++;\n  }\n  return 1;\n}\n\n// Appends number in a given base to buffer. If its length is less than\n// |minimal_num_length|, it is padded with leading zeroes or spaces, depending\n// on the value of |pad_with_zero|.\nstatic int AppendNumber(char **buff, const char *buff_end, u64 absolute_value,\n                        u8 base, u8 minimal_num_length, bool pad_with_zero,\n                        bool negative) {\n  uptr const kMaxLen = 30;\n  RAW_CHECK(base == 10 || base == 16);\n  RAW_CHECK(base == 10 || !negative);\n  RAW_CHECK(absolute_value || !negative);\n  RAW_CHECK(minimal_num_length < kMaxLen);\n  int result = 0;\n  if (negative && minimal_num_length)\n    --minimal_num_length;\n  if (negative && pad_with_zero)\n    result += AppendChar(buff, buff_end, '-');\n  uptr num_buffer[kMaxLen];\n  int pos = 0;\n  do {\n    RAW_CHECK_MSG((uptr)pos < kMaxLen, \"AppendNumber buffer overflow\");\n    num_buffer[pos++] = absolute_value % base;\n    absolute_value /= base;\n  } while (absolute_value > 0);\n  if (pos < minimal_num_length) {\n    // Make sure compiler doesn't insert call to memset here.\n    internal_memset(&num_buffer[pos], 0,\n                    sizeof(num_buffer[0]) * (minimal_num_length - pos));\n    pos = minimal_num_length;\n  }\n  RAW_CHECK(pos > 0);\n  pos--;\n  for (; pos >= 0 && num_buffer[pos] == 0; pos--) {\n    char c = (pad_with_zero || pos == 0) ? '0' : ' ';\n    result += AppendChar(buff, buff_end, c);\n  }\n  if (negative && !pad_with_zero) result += AppendChar(buff, buff_end, '-');\n  for (; pos >= 0; pos--) {\n    char digit = static_cast<char>(num_buffer[pos]);\n    result += AppendChar(buff, buff_end, (digit < 10) ? '0' + digit\n                                                      : 'a' + digit - 10);\n  }\n  return result;\n}\n\nstatic int AppendUnsigned(char **buff, const char *buff_end, u64 num, u8 base,\n                          u8 minimal_num_length, bool pad_with_zero) {\n  return AppendNumber(buff, buff_end, num, base, minimal_num_length,\n                      pad_with_zero, false /* negative */);\n}\n\nstatic int AppendSignedDecimal(char **buff, const char *buff_end, s64 num,\n                               u8 minimal_num_length, bool pad_with_zero) {\n  bool negative = (num < 0);\n  return AppendNumber(buff, buff_end, (u64)(negative ? -num : num), 10,\n                      minimal_num_length, pad_with_zero, negative);\n}\n\nstatic int AppendString(char **buff, const char *buff_end, int precision,\n                        const char *s) {\n  if (!s)\n    s = \"<null>\";\n  int result = 0;\n  for (; *s; s++) {\n    if (precision >= 0 && result >= precision)\n      break;\n    result += AppendChar(buff, buff_end, *s);\n  }\n  return result;\n}\n\nstatic int AppendPointer(char **buff, const char *buff_end, u64 ptr_value) {\n  int result = 0;\n  result += AppendString(buff, buff_end, -1, \"0x\");\n  result += AppendUnsigned(buff, buff_end, ptr_value, 16,\n                           SANITIZER_POINTER_FORMAT_LENGTH, true);\n  return result;\n}\n\nint VSNPrintf(char *buff, int buff_length,\n              const char *format, va_list args) {\n  static const char *kPrintfFormatsHelp =\n    \"Supported Printf formats: %([0-9]*)?(z|ll)?{d,u,x}; %p; %(\\\\.\\\\*)?s; %c\\n\";\n  RAW_CHECK(format);\n  RAW_CHECK(buff_length > 0);\n  const char *buff_end = &buff[buff_length - 1];\n  const char *cur = format;\n  int result = 0;\n  for (; *cur; cur++) {\n    if (*cur != '%') {\n      result += AppendChar(&buff, buff_end, *cur);\n      continue;\n    }\n    cur++;\n    bool have_width = (*cur >= '0' && *cur <= '9');\n    bool pad_with_zero = (*cur == '0');\n    int width = 0;\n    if (have_width) {\n      while (*cur >= '0' && *cur <= '9') {\n        width = width * 10 + *cur++ - '0';\n      }\n    }\n    bool have_precision = (cur[0] == '.' && cur[1] == '*');\n    int precision = -1;\n    if (have_precision) {\n      cur += 2;\n      precision = va_arg(args, int);\n    }\n    bool have_z = (*cur == 'z');\n    cur += have_z;\n    bool have_ll = !have_z && (cur[0] == 'l' && cur[1] == 'l');\n    cur += have_ll * 2;\n    s64 dval;\n    u64 uval;\n    bool have_flags = have_width | have_z | have_ll;\n    // Only %s supports precision for now\n    CHECK(!(precision >= 0 && *cur != 's'));\n    switch (*cur) {\n      case 'd': {\n        dval = have_ll ? va_arg(args, s64)\n             : have_z ? va_arg(args, sptr)\n             : va_arg(args, int);\n        result += AppendSignedDecimal(&buff, buff_end, dval, width,\n                                      pad_with_zero);\n        break;\n      }\n      case 'u':\n      case 'x': {\n        uval = have_ll ? va_arg(args, u64)\n             : have_z ? va_arg(args, uptr)\n             : va_arg(args, unsigned);\n        result += AppendUnsigned(&buff, buff_end, uval,\n                                 (*cur == 'u') ? 10 : 16, width, pad_with_zero);\n        break;\n      }\n      case 'p': {\n        RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp);\n        result += AppendPointer(&buff, buff_end, va_arg(args, uptr));\n        break;\n      }\n      case 's': {\n        RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp);\n        result += AppendString(&buff, buff_end, precision, va_arg(args, char*));\n        break;\n      }\n      case 'c': {\n        RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp);\n        result += AppendChar(&buff, buff_end, va_arg(args, int));\n        break;\n      }\n      case '%' : {\n        RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp);\n        result += AppendChar(&buff, buff_end, '%');\n        break;\n      }\n      default: {\n        RAW_CHECK_MSG(false, kPrintfFormatsHelp);\n      }\n    }\n  }\n  RAW_CHECK(buff <= buff_end);\n  AppendChar(&buff, buff_end + 1, '\\0');\n  return result;\n}\n\nstatic void (*PrintfAndReportCallback)(const char *);\nvoid SetPrintfAndReportCallback(void (*callback)(const char *)) {\n  PrintfAndReportCallback = callback;\n}\n\n// Can be overriden in frontend.\n#if SANITIZER_SUPPORTS_WEAK_HOOKS\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nvoid OnPrint(const char *str) {\n  (void)str;\n}\n#elif defined(SANITIZER_GO) && defined(TSAN_EXTERNAL_HOOKS)\nvoid OnPrint(const char *str);\n#else\nvoid OnPrint(const char *str) {\n  (void)str;\n}\n#endif\n\nstatic void CallPrintfAndReportCallback(const char *str) {\n  OnPrint(str);\n  if (PrintfAndReportCallback)\n    PrintfAndReportCallback(str);\n}\n\nstatic void SharedPrintfCode(bool append_pid, const char *format,\n                             va_list args) {\n  va_list args2;\n  va_copy(args2, args);\n  const int kLen = 16 * 1024;\n  // |local_buffer| is small enough not to overflow the stack and/or violate\n  // the stack limit enforced by TSan (-Wframe-larger-than=512). On the other\n  // hand, the bigger the buffer is, the more the chance the error report will\n  // fit into it.\n  char local_buffer[400];\n  int needed_length;\n  char *buffer = local_buffer;\n  int buffer_size = ARRAY_SIZE(local_buffer);\n  // First try to print a message using a local buffer, and then fall back to\n  // mmaped buffer.\n  for (int use_mmap = 0; use_mmap < 2; use_mmap++) {\n    if (use_mmap) {\n      va_end(args);\n      va_copy(args, args2);\n      buffer = (char*)MmapOrDie(kLen, \"Report\");\n      buffer_size = kLen;\n    }\n    needed_length = 0;\n    // Check that data fits into the current buffer.\n#   define CHECK_NEEDED_LENGTH \\\n      if (needed_length >= buffer_size) { \\\n        if (!use_mmap) continue; \\\n        RAW_CHECK_MSG(needed_length < kLen, \\\n                      \"Buffer in Report is too short!\\n\"); \\\n      }\n    if (append_pid) {\n      int pid = internal_getpid();\n      const char *exe_name = GetProcessName();\n      if (common_flags()->log_exe_name && exe_name) {\n        needed_length += internal_snprintf(buffer, buffer_size,\n                                           \"==%s\", exe_name);\n        CHECK_NEEDED_LENGTH\n      }\n      needed_length += internal_snprintf(buffer + needed_length,\n                                         buffer_size - needed_length,\n                                         \"==%d==\", pid);\n      CHECK_NEEDED_LENGTH\n    }\n    needed_length += VSNPrintf(buffer + needed_length,\n                               buffer_size - needed_length, format, args);\n    CHECK_NEEDED_LENGTH\n    // If the message fit into the buffer, print it and exit.\n    break;\n#   undef CHECK_NEEDED_LENGTH\n  }\n  RawWrite(buffer);\n  if (common_flags()->log_to_syslog && ShouldLogAfterPrintf())\n    WriteToSyslog(buffer);\n  CallPrintfAndReportCallback(buffer);\n  // If we had mapped any memory, clean up.\n  if (buffer != local_buffer)\n    UnmapOrDie((void *)buffer, buffer_size);\n  va_end(args2);\n}\n\nFORMAT(1, 2)\nvoid Printf(const char *format, ...) {\n  va_list args;\n  va_start(args, format);\n  SharedPrintfCode(false, format, args);\n  va_end(args);\n}\n\n// Like Printf, but prints the current PID before the output string.\nFORMAT(1, 2)\nvoid Report(const char *format, ...) {\n  va_list args;\n  va_start(args, format);\n  SharedPrintfCode(true, format, args);\n  va_end(args);\n}\n\n// Writes at most \"length\" symbols to \"buffer\" (including trailing '\\0').\n// Returns the number of symbols that should have been written to buffer\n// (not including trailing '\\0'). Thus, the string is truncated\n// iff return value is not less than \"length\".\nFORMAT(3, 4)\nint internal_snprintf(char *buffer, uptr length, const char *format, ...) {\n  va_list args;\n  va_start(args, format);\n  int needed_length = VSNPrintf(buffer, length, format, args);\n  va_end(args);\n  return needed_length;\n}\n\nFORMAT(2, 3)\nvoid InternalScopedString::append(const char *format, ...) {\n  CHECK_LT(length_, size());\n  va_list args;\n  va_start(args, format);\n  VSNPrintf(data() + length_, size() - length_, format, args);\n  va_end(args);\n  length_ += internal_strlen(data() + length_);\n  CHECK_LT(length_, size());\n}\n\n} // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h",
    "content": "//===-- sanitizer_procmaps.h ------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer.\n//\n// Information about the process mappings.\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_PROCMAPS_H\n#define SANITIZER_PROCMAPS_H\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_mutex.h\"\n\nnamespace __sanitizer {\n\n#if SANITIZER_FREEBSD || SANITIZER_LINUX\nstruct ProcSelfMapsBuff {\n  char *data;\n  uptr mmaped_size;\n  uptr len;\n};\n\n// Reads process memory map in an OS-specific way.\nvoid ReadProcMaps(ProcSelfMapsBuff *proc_maps);\n#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX\n\nclass MemoryMappingLayout {\n public:\n  explicit MemoryMappingLayout(bool cache_enabled);\n  ~MemoryMappingLayout();\n  bool Next(uptr *start, uptr *end, uptr *offset,\n            char filename[], uptr filename_size, uptr *protection);\n  void Reset();\n  // In some cases, e.g. when running under a sandbox on Linux, ASan is unable\n  // to obtain the memory mappings. It should fall back to pre-cached data\n  // instead of aborting.\n  static void CacheMemoryMappings();\n\n  // Stores the list of mapped objects into an array.\n  uptr DumpListOfModules(LoadedModule *modules, uptr max_modules,\n                         string_predicate_t filter);\n\n  // Memory protection masks.\n  static const uptr kProtectionRead = 1;\n  static const uptr kProtectionWrite = 2;\n  static const uptr kProtectionExecute = 4;\n  static const uptr kProtectionShared = 8;\n\n private:\n  void LoadFromCache();\n\n  // FIXME: Hide implementation details for different platforms in\n  // platform-specific files.\n# if SANITIZER_FREEBSD || SANITIZER_LINUX\n  ProcSelfMapsBuff proc_self_maps_;\n  const char *current_;\n\n  // Static mappings cache.\n  static ProcSelfMapsBuff cached_proc_self_maps_;\n  static StaticSpinMutex cache_lock_;  // protects cached_proc_self_maps_.\n# elif SANITIZER_MAC\n  template<u32 kLCSegment, typename SegmentCommand>\n  bool NextSegmentLoad(uptr *start, uptr *end, uptr *offset,\n                       char filename[], uptr filename_size,\n                       uptr *protection);\n  int current_image_;\n  u32 current_magic_;\n  u32 current_filetype_;\n  int current_load_cmd_count_;\n  char *current_load_cmd_addr_;\n# endif\n};\n\ntypedef void (*fill_profile_f)(uptr start, uptr rss, bool file,\n                               /*out*/uptr *stats, uptr stats_size);\n\n// Parse the contents of /proc/self/smaps and generate a memory profile.\n// |cb| is a tool-specific callback that fills the |stats| array containing\n// |stats_size| elements.\nvoid GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size);\n\n// Returns code range for the specified module.\nbool GetCodeRangeForFile(const char *module, uptr *start, uptr *end);\n\nbool IsDecimal(char c);\nuptr ParseDecimal(const char **p);\nbool IsHex(char c);\nuptr ParseHex(const char **p);\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_PROCMAPS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cc",
    "content": "//===-- sanitizer_procmaps_common.cc --------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Information about the process mappings (common parts).\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n\n#if SANITIZER_FREEBSD || SANITIZER_LINUX\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_placement_new.h\"\n#include \"sanitizer_procmaps.h\"\n\nnamespace __sanitizer {\n\n// Linker initialized.\nProcSelfMapsBuff MemoryMappingLayout::cached_proc_self_maps_;\nStaticSpinMutex MemoryMappingLayout::cache_lock_;  // Linker initialized.\n\nstatic int TranslateDigit(char c) {\n  if (c >= '0' && c <= '9')\n    return c - '0';\n  if (c >= 'a' && c <= 'f')\n    return c - 'a' + 10;\n  if (c >= 'A' && c <= 'F')\n    return c - 'A' + 10;\n  return -1;\n}\n\n// Parse a number and promote 'p' up to the first non-digit character.\nstatic uptr ParseNumber(const char **p, int base) {\n  uptr n = 0;\n  int d;\n  CHECK(base >= 2 && base <= 16);\n  while ((d = TranslateDigit(**p)) >= 0 && d < base) {\n    n = n * base + d;\n    (*p)++;\n  }\n  return n;\n}\n\nbool IsDecimal(char c) {\n  int d = TranslateDigit(c);\n  return d >= 0 && d < 10;\n}\n\nuptr ParseDecimal(const char **p) {\n  return ParseNumber(p, 10);\n}\n\nbool IsHex(char c) {\n  int d = TranslateDigit(c);\n  return d >= 0 && d < 16;\n}\n\nuptr ParseHex(const char **p) {\n  return ParseNumber(p, 16);\n}\n\nMemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) {\n  ReadProcMaps(&proc_self_maps_);\n  if (cache_enabled) {\n    if (proc_self_maps_.mmaped_size == 0) {\n      LoadFromCache();\n      CHECK_GT(proc_self_maps_.len, 0);\n    }\n  } else {\n    CHECK_GT(proc_self_maps_.mmaped_size, 0);\n  }\n  Reset();\n  // FIXME: in the future we may want to cache the mappings on demand only.\n  if (cache_enabled)\n    CacheMemoryMappings();\n}\n\nMemoryMappingLayout::~MemoryMappingLayout() {\n  // Only unmap the buffer if it is different from the cached one. Otherwise\n  // it will be unmapped when the cache is refreshed.\n  if (proc_self_maps_.data != cached_proc_self_maps_.data) {\n    UnmapOrDie(proc_self_maps_.data, proc_self_maps_.mmaped_size);\n  }\n}\n\nvoid MemoryMappingLayout::Reset() {\n  current_ = proc_self_maps_.data;\n}\n\n// static\nvoid MemoryMappingLayout::CacheMemoryMappings() {\n  SpinMutexLock l(&cache_lock_);\n  // Don't invalidate the cache if the mappings are unavailable.\n  ProcSelfMapsBuff old_proc_self_maps;\n  old_proc_self_maps = cached_proc_self_maps_;\n  ReadProcMaps(&cached_proc_self_maps_);\n  if (cached_proc_self_maps_.mmaped_size == 0) {\n    cached_proc_self_maps_ = old_proc_self_maps;\n  } else {\n    if (old_proc_self_maps.mmaped_size) {\n      UnmapOrDie(old_proc_self_maps.data,\n                 old_proc_self_maps.mmaped_size);\n    }\n  }\n}\n\nvoid MemoryMappingLayout::LoadFromCache() {\n  SpinMutexLock l(&cache_lock_);\n  if (cached_proc_self_maps_.data) {\n    proc_self_maps_ = cached_proc_self_maps_;\n  }\n}\n\nuptr MemoryMappingLayout::DumpListOfModules(LoadedModule *modules,\n                                            uptr max_modules,\n                                            string_predicate_t filter) {\n  Reset();\n  uptr cur_beg, cur_end, cur_offset, prot;\n  InternalScopedString module_name(kMaxPathLength);\n  uptr n_modules = 0;\n  for (uptr i = 0; n_modules < max_modules &&\n                       Next(&cur_beg, &cur_end, &cur_offset, module_name.data(),\n                            module_name.size(), &prot);\n       i++) {\n    const char *cur_name = module_name.data();\n    if (cur_name[0] == '\\0')\n      continue;\n    if (filter && !filter(cur_name))\n      continue;\n    // Don't subtract 'cur_beg' from the first entry:\n    // * If a binary is compiled w/o -pie, then the first entry in\n    //   process maps is likely the binary itself (all dynamic libs\n    //   are mapped higher in address space). For such a binary,\n    //   instruction offset in binary coincides with the actual\n    //   instruction address in virtual memory (as code section\n    //   is mapped to a fixed memory range).\n    // * If a binary is compiled with -pie, all the modules are\n    //   mapped high at address space (in particular, higher than\n    //   shadow memory of the tool), so the module can't be the\n    //   first entry.\n    uptr base_address = (i ? cur_beg : 0) - cur_offset;\n    LoadedModule *cur_module = &modules[n_modules];\n    cur_module->set(cur_name, base_address);\n    cur_module->addAddressRange(cur_beg, cur_end, prot & kProtectionExecute);\n    n_modules++;\n  }\n  return n_modules;\n}\n\nvoid GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size) {\n  char *smaps = nullptr;\n  uptr smaps_cap = 0;\n  uptr smaps_len = 0;\n  if (!ReadFileToBuffer(\"/proc/self/smaps\", &smaps, &smaps_cap, &smaps_len))\n    return;\n  uptr start = 0;\n  bool file = false;\n  const char *pos = smaps;\n  while (pos < smaps + smaps_len) {\n    if (IsHex(pos[0])) {\n      start = ParseHex(&pos);\n      for (; *pos != '/' && *pos > '\\n'; pos++) {}\n      file = *pos == '/';\n    } else if (internal_strncmp(pos, \"Rss:\", 4) == 0) {\n      while (!IsDecimal(*pos)) pos++;\n      uptr rss = ParseDecimal(&pos) * 1024;\n      cb(start, rss, file, stats, stats_size);\n    }\n    while (*pos++ != '\\n') {}\n  }\n  UnmapOrDie(smaps, smaps_cap);\n}\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_FREEBSD || SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_freebsd.cc",
    "content": "//===-- sanitizer_procmaps_freebsd.cc -------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Information about the process mappings (FreeBSD-specific parts).\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n#if SANITIZER_FREEBSD\n#include \"sanitizer_common.h\"\n#include \"sanitizer_freebsd.h\"\n#include \"sanitizer_procmaps.h\"\n\n#include <unistd.h>\n#include <sys/sysctl.h>\n#include <sys/user.h>\n\n// Fix 'kinfo_vmentry' definition on FreeBSD prior v9.2 in 32-bit mode.\n#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)\n# include <osreldate.h>\n# if __FreeBSD_version <= 902001  // v9.2\n#  define kinfo_vmentry xkinfo_vmentry\n# endif\n#endif\n\nnamespace __sanitizer {\n\nvoid ReadProcMaps(ProcSelfMapsBuff *proc_maps) {\n  const int Mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid() };\n  size_t Size = 0;\n  int Err = sysctl(Mib, 4, NULL, &Size, NULL, 0);\n  CHECK_EQ(Err, 0);\n  CHECK_GT(Size, 0);\n\n  size_t MmapedSize = Size * 4 / 3;\n  void *VmMap = MmapOrDie(MmapedSize, \"ReadProcMaps()\");\n  Size = MmapedSize;\n  Err = sysctl(Mib, 4, VmMap, &Size, NULL, 0);\n  CHECK_EQ(Err, 0);\n\n  proc_maps->data = (char*)VmMap;\n  proc_maps->mmaped_size = MmapedSize;\n  proc_maps->len = Size;\n}\n\nbool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset,\n                               char filename[], uptr filename_size,\n                               uptr *protection) {\n  char *last = proc_self_maps_.data + proc_self_maps_.len;\n  if (current_ >= last) return false;\n  uptr dummy;\n  if (!start) start = &dummy;\n  if (!end) end = &dummy;\n  if (!offset) offset = &dummy;\n  if (!protection) protection = &dummy;\n  struct kinfo_vmentry *VmEntry = (struct kinfo_vmentry*)current_;\n\n  *start = (uptr)VmEntry->kve_start;\n  *end = (uptr)VmEntry->kve_end;\n  *offset = (uptr)VmEntry->kve_offset;\n\n  *protection = 0;\n  if ((VmEntry->kve_protection & KVME_PROT_READ) != 0)\n    *protection |= kProtectionRead;\n  if ((VmEntry->kve_protection & KVME_PROT_WRITE) != 0)\n    *protection |= kProtectionWrite;\n  if ((VmEntry->kve_protection & KVME_PROT_EXEC) != 0)\n    *protection |= kProtectionExecute;\n\n  if (filename != NULL && filename_size > 0) {\n    internal_snprintf(filename,\n                      Min(filename_size, (uptr)PATH_MAX),\n                      \"%s\", VmEntry->kve_path);\n  }\n\n  current_ += VmEntry->kve_structsize;\n\n  return true;\n}\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_FREEBSD\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_linux.cc",
    "content": "//===-- sanitizer_procmaps_linux.cc ---------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Information about the process mappings (Linux-specific parts).\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n#if SANITIZER_LINUX\n#include \"sanitizer_common.h\"\n#include \"sanitizer_procmaps.h\"\n\nnamespace __sanitizer {\n\nvoid ReadProcMaps(ProcSelfMapsBuff *proc_maps) {\n  CHECK(ReadFileToBuffer(\"/proc/self/maps\", &proc_maps->data,\n                         &proc_maps->mmaped_size, &proc_maps->len));\n}\n\nstatic bool IsOneOf(char c, char c1, char c2) {\n  return c == c1 || c == c2;\n}\n\nbool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset,\n                               char filename[], uptr filename_size,\n                               uptr *protection) {\n  char *last = proc_self_maps_.data + proc_self_maps_.len;\n  if (current_ >= last) return false;\n  uptr dummy;\n  if (!start) start = &dummy;\n  if (!end) end = &dummy;\n  if (!offset) offset = &dummy;\n  if (!protection) protection = &dummy;\n  char *next_line = (char*)internal_memchr(current_, '\\n', last - current_);\n  if (next_line == 0)\n    next_line = last;\n  // Example: 08048000-08056000 r-xp 00000000 03:0c 64593   /foo/bar\n  *start = ParseHex(&current_);\n  CHECK_EQ(*current_++, '-');\n  *end = ParseHex(&current_);\n  CHECK_EQ(*current_++, ' ');\n  CHECK(IsOneOf(*current_, '-', 'r'));\n  *protection = 0;\n  if (*current_++ == 'r')\n    *protection |= kProtectionRead;\n  CHECK(IsOneOf(*current_, '-', 'w'));\n  if (*current_++ == 'w')\n    *protection |= kProtectionWrite;\n  CHECK(IsOneOf(*current_, '-', 'x'));\n  if (*current_++ == 'x')\n    *protection |= kProtectionExecute;\n  CHECK(IsOneOf(*current_, 's', 'p'));\n  if (*current_++ == 's')\n    *protection |= kProtectionShared;\n  CHECK_EQ(*current_++, ' ');\n  *offset = ParseHex(&current_);\n  CHECK_EQ(*current_++, ' ');\n  ParseHex(&current_);\n  CHECK_EQ(*current_++, ':');\n  ParseHex(&current_);\n  CHECK_EQ(*current_++, ' ');\n  while (IsDecimal(*current_))\n    current_++;\n  // Qemu may lack the trailing space.\n  // https://github.com/google/sanitizers/issues/160\n  // CHECK_EQ(*current_++, ' ');\n  // Skip spaces.\n  while (current_ < next_line && *current_ == ' ')\n    current_++;\n  // Fill in the filename.\n  uptr i = 0;\n  while (current_ < next_line) {\n    if (filename && i < filename_size - 1)\n      filename[i++] = *current_;\n    current_++;\n  }\n  if (filename && i < filename_size)\n    filename[i] = 0;\n  current_ = next_line + 1;\n  return true;\n}\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cc",
    "content": "//===-- sanitizer_procmaps_mac.cc -----------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Information about the process mappings (Mac-specific parts).\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n#if SANITIZER_MAC\n#include \"sanitizer_common.h\"\n#include \"sanitizer_placement_new.h\"\n#include \"sanitizer_procmaps.h\"\n\n#include <mach-o/dyld.h>\n#include <mach-o/loader.h>\n\nnamespace __sanitizer {\n\nMemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) {\n  Reset();\n}\n\nMemoryMappingLayout::~MemoryMappingLayout() {\n}\n\n// More information about Mach-O headers can be found in mach-o/loader.h\n// Each Mach-O image has a header (mach_header or mach_header_64) starting with\n// a magic number, and a list of linker load commands directly following the\n// header.\n// A load command is at least two 32-bit words: the command type and the\n// command size in bytes. We're interested only in segment load commands\n// (LC_SEGMENT and LC_SEGMENT_64), which tell that a part of the file is mapped\n// into the task's address space.\n// The |vmaddr|, |vmsize| and |fileoff| fields of segment_command or\n// segment_command_64 correspond to the memory address, memory size and the\n// file offset of the current memory segment.\n// Because these fields are taken from the images as is, one needs to add\n// _dyld_get_image_vmaddr_slide() to get the actual addresses at runtime.\n\nvoid MemoryMappingLayout::Reset() {\n  // Count down from the top.\n  // TODO(glider): as per man 3 dyld, iterating over the headers with\n  // _dyld_image_count is thread-unsafe. We need to register callbacks for\n  // adding and removing images which will invalidate the MemoryMappingLayout\n  // state.\n  current_image_ = _dyld_image_count();\n  current_load_cmd_count_ = -1;\n  current_load_cmd_addr_ = 0;\n  current_magic_ = 0;\n  current_filetype_ = 0;\n}\n\n// static\nvoid MemoryMappingLayout::CacheMemoryMappings() {\n  // No-op on Mac for now.\n}\n\nvoid MemoryMappingLayout::LoadFromCache() {\n  // No-op on Mac for now.\n}\n\n// Next and NextSegmentLoad were inspired by base/sysinfo.cc in\n// Google Perftools, https://github.com/gperftools/gperftools.\n\n// NextSegmentLoad scans the current image for the next segment load command\n// and returns the start and end addresses and file offset of the corresponding\n// segment.\n// Note that the segment addresses are not necessarily sorted.\ntemplate<u32 kLCSegment, typename SegmentCommand>\nbool MemoryMappingLayout::NextSegmentLoad(\n    uptr *start, uptr *end, uptr *offset,\n    char filename[], uptr filename_size, uptr *protection) {\n  const char* lc = current_load_cmd_addr_;\n  current_load_cmd_addr_ += ((const load_command *)lc)->cmdsize;\n  if (((const load_command *)lc)->cmd == kLCSegment) {\n    const sptr dlloff = _dyld_get_image_vmaddr_slide(current_image_);\n    const SegmentCommand* sc = (const SegmentCommand *)lc;\n    if (start) *start = sc->vmaddr + dlloff;\n    if (protection) {\n      // Return the initial protection.\n      *protection = sc->initprot;\n    }\n    if (end) *end = sc->vmaddr + sc->vmsize + dlloff;\n    if (offset) {\n      if (current_filetype_ == /*MH_EXECUTE*/ 0x2) {\n        *offset = sc->vmaddr;\n      } else {\n        *offset = sc->fileoff;\n      }\n    }\n    if (filename) {\n      internal_strncpy(filename, _dyld_get_image_name(current_image_),\n                       filename_size);\n    }\n    return true;\n  }\n  return false;\n}\n\nbool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset,\n                               char filename[], uptr filename_size,\n                               uptr *protection) {\n  for (; current_image_ >= 0; current_image_--) {\n    const mach_header* hdr = _dyld_get_image_header(current_image_);\n    if (!hdr) continue;\n    if (current_load_cmd_count_ < 0) {\n      // Set up for this image;\n      current_load_cmd_count_ = hdr->ncmds;\n      current_magic_ = hdr->magic;\n      current_filetype_ = hdr->filetype;\n      switch (current_magic_) {\n#ifdef MH_MAGIC_64\n        case MH_MAGIC_64: {\n          current_load_cmd_addr_ = (char*)hdr + sizeof(mach_header_64);\n          break;\n        }\n#endif\n        case MH_MAGIC: {\n          current_load_cmd_addr_ = (char*)hdr + sizeof(mach_header);\n          break;\n        }\n        default: {\n          continue;\n        }\n      }\n    }\n\n    for (; current_load_cmd_count_ >= 0; current_load_cmd_count_--) {\n      switch (current_magic_) {\n        // current_magic_ may be only one of MH_MAGIC, MH_MAGIC_64.\n#ifdef MH_MAGIC_64\n        case MH_MAGIC_64: {\n          if (NextSegmentLoad<LC_SEGMENT_64, struct segment_command_64>(\n                  start, end, offset, filename, filename_size, protection))\n            return true;\n          break;\n        }\n#endif\n        case MH_MAGIC: {\n          if (NextSegmentLoad<LC_SEGMENT, struct segment_command>(\n                  start, end, offset, filename, filename_size, protection))\n            return true;\n          break;\n        }\n      }\n    }\n    // If we get here, no more load_cmd's in this image talk about\n    // segments.  Go on to the next image.\n  }\n  return false;\n}\n\nuptr MemoryMappingLayout::DumpListOfModules(LoadedModule *modules,\n                                            uptr max_modules,\n                                            string_predicate_t filter) {\n  Reset();\n  uptr cur_beg, cur_end, prot;\n  InternalScopedString module_name(kMaxPathLength);\n  uptr n_modules = 0;\n  for (uptr i = 0; n_modules < max_modules &&\n                       Next(&cur_beg, &cur_end, 0, module_name.data(),\n                            module_name.size(), &prot);\n       i++) {\n    const char *cur_name = module_name.data();\n    if (cur_name[0] == '\\0')\n      continue;\n    if (filter && !filter(cur_name))\n      continue;\n    LoadedModule *cur_module = nullptr;\n    if (n_modules > 0 &&\n        0 == internal_strcmp(cur_name, modules[n_modules - 1].full_name())) {\n      cur_module = &modules[n_modules - 1];\n    } else {\n      cur_module = &modules[n_modules];\n      cur_module->set(cur_name, cur_beg);\n      n_modules++;\n    }\n    cur_module->addAddressRange(cur_beg, cur_end, prot & kProtectionExecute);\n  }\n  return n_modules;\n}\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_MAC\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_quarantine.h",
    "content": "//===-- sanitizer_quarantine.h ----------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Memory quarantine for AddressSanitizer and potentially other tools.\n// Quarantine caches some specified amount of memory in per-thread caches,\n// then evicts to global FIFO queue. When the queue reaches specified threshold,\n// oldest memory is recycled.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_QUARANTINE_H\n#define SANITIZER_QUARANTINE_H\n\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_mutex.h\"\n#include \"sanitizer_list.h\"\n\nnamespace __sanitizer {\n\ntemplate<typename Node> class QuarantineCache;\n\nstruct QuarantineBatch {\n  static const uptr kSize = 1021;\n  QuarantineBatch *next;\n  uptr size;\n  uptr count;\n  void *batch[kSize];\n};\n\nCOMPILER_CHECK(sizeof(QuarantineBatch) <= (1 << 13));  // 8Kb.\n\n// The callback interface is:\n// void Callback::Recycle(Node *ptr);\n// void *cb.Allocate(uptr size);\n// void cb.Deallocate(void *ptr);\ntemplate<typename Callback, typename Node>\nclass Quarantine {\n public:\n  typedef QuarantineCache<Callback> Cache;\n\n  explicit Quarantine(LinkerInitialized)\n      : cache_(LINKER_INITIALIZED) {\n  }\n\n  void Init(uptr size, uptr cache_size) {\n    atomic_store(&max_size_, size, memory_order_release);\n    atomic_store(&min_size_, size / 10 * 9,\n                 memory_order_release); // 90% of max size.\n    max_cache_size_ = cache_size;\n  }\n\n  uptr GetSize() const { return atomic_load(&max_size_, memory_order_acquire); }\n\n  void Put(Cache *c, Callback cb, Node *ptr, uptr size) {\n    c->Enqueue(cb, ptr, size);\n    if (c->Size() > max_cache_size_)\n      Drain(c, cb);\n  }\n\n  void NOINLINE Drain(Cache *c, Callback cb) {\n    {\n      SpinMutexLock l(&cache_mutex_);\n      cache_.Transfer(c);\n    }\n    if (cache_.Size() > GetSize() && recycle_mutex_.TryLock())\n      Recycle(cb);\n  }\n\n private:\n  // Read-only data.\n  char pad0_[kCacheLineSize];\n  atomic_uintptr_t max_size_;\n  atomic_uintptr_t min_size_;\n  uptr max_cache_size_;\n  char pad1_[kCacheLineSize];\n  SpinMutex cache_mutex_;\n  SpinMutex recycle_mutex_;\n  Cache cache_;\n  char pad2_[kCacheLineSize];\n\n  void NOINLINE Recycle(Callback cb) {\n    Cache tmp;\n    uptr min_size = atomic_load(&min_size_, memory_order_acquire);\n    {\n      SpinMutexLock l(&cache_mutex_);\n      while (cache_.Size() > min_size) {\n        QuarantineBatch *b = cache_.DequeueBatch();\n        tmp.EnqueueBatch(b);\n      }\n    }\n    recycle_mutex_.Unlock();\n    DoRecycle(&tmp, cb);\n  }\n\n  void NOINLINE DoRecycle(Cache *c, Callback cb) {\n    while (QuarantineBatch *b = c->DequeueBatch()) {\n      const uptr kPrefetch = 16;\n      for (uptr i = 0; i < kPrefetch; i++)\n        PREFETCH(b->batch[i]);\n      for (uptr i = 0; i < b->count; i++) {\n        PREFETCH(b->batch[i + kPrefetch]);\n        cb.Recycle((Node*)b->batch[i]);\n      }\n      cb.Deallocate(b);\n    }\n  }\n};\n\n// Per-thread cache of memory blocks.\ntemplate<typename Callback>\nclass QuarantineCache {\n public:\n  explicit QuarantineCache(LinkerInitialized) {\n  }\n\n  QuarantineCache()\n      : size_() {\n    list_.clear();\n  }\n\n  uptr Size() const {\n    return atomic_load(&size_, memory_order_relaxed);\n  }\n\n  void Enqueue(Callback cb, void *ptr, uptr size) {\n    if (list_.empty() || list_.back()->count == QuarantineBatch::kSize) {\n      AllocBatch(cb);\n      size += sizeof(QuarantineBatch);  // Count the batch in Quarantine size.\n    }\n    QuarantineBatch *b = list_.back();\n    CHECK(b);\n    b->batch[b->count++] = ptr;\n    b->size += size;\n    SizeAdd(size);\n  }\n\n  void Transfer(QuarantineCache *c) {\n    list_.append_back(&c->list_);\n    SizeAdd(c->Size());\n    atomic_store(&c->size_, 0, memory_order_relaxed);\n  }\n\n  void EnqueueBatch(QuarantineBatch *b) {\n    list_.push_back(b);\n    SizeAdd(b->size);\n  }\n\n  QuarantineBatch *DequeueBatch() {\n    if (list_.empty())\n      return nullptr;\n    QuarantineBatch *b = list_.front();\n    list_.pop_front();\n    SizeSub(b->size);\n    return b;\n  }\n\n private:\n  IntrusiveList<QuarantineBatch> list_;\n  atomic_uintptr_t size_;\n\n  void SizeAdd(uptr add) {\n    atomic_store(&size_, Size() + add, memory_order_relaxed);\n  }\n  void SizeSub(uptr sub) {\n    atomic_store(&size_, Size() - sub, memory_order_relaxed);\n  }\n\n  NOINLINE QuarantineBatch* AllocBatch(Callback cb) {\n    QuarantineBatch *b = (QuarantineBatch *)cb.Allocate(sizeof(*b));\n    CHECK(b);\n    b->count = 0;\n    b->size = 0;\n    list_.push_back(b);\n    return b;\n  }\n};\n} // namespace __sanitizer\n\n#endif // SANITIZER_QUARANTINE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_report_decorator.h",
    "content": "//===-- sanitizer_report_decorator.h ----------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Tags to decorate the sanitizer reports.\n// Currently supported tags:\n//   * None.\n//   * ANSI color sequences.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_REPORT_DECORATOR_H\n#define SANITIZER_REPORT_DECORATOR_H\n\n#include \"sanitizer_common.h\"\n\nnamespace __sanitizer {\nclass SanitizerCommonDecorator {\n  // FIXME: This is not portable. It assumes the special strings are printed to\n  // stdout, which is not the case on Windows (see SetConsoleTextAttribute()).\n public:\n  SanitizerCommonDecorator() : ansi_(ColorizeReports()) {}\n  const char *Bold()    const { return ansi_ ? \"\\033[1m\" : \"\"; }\n  const char *Default() const { return ansi_ ? \"\\033[1m\\033[0m\"  : \"\"; }\n  const char *Warning()    { return Red(); }\n  const char *EndWarning() { return Default(); }\n protected:\n  const char *Black()   const { return ansi_ ? \"\\033[1m\\033[30m\" : \"\"; }\n  const char *Red()     const { return ansi_ ? \"\\033[1m\\033[31m\" : \"\"; }\n  const char *Green()   const { return ansi_ ? \"\\033[1m\\033[32m\" : \"\"; }\n  const char *Yellow()  const { return ansi_ ? \"\\033[1m\\033[33m\" : \"\"; }\n  const char *Blue()    const { return ansi_ ? \"\\033[1m\\033[34m\" : \"\"; }\n  const char *Magenta() const { return ansi_ ? \"\\033[1m\\033[35m\" : \"\"; }\n  const char *Cyan()    const { return ansi_ ? \"\\033[1m\\033[36m\" : \"\"; }\n  const char *White()   const { return ansi_ ? \"\\033[1m\\033[37m\" : \"\"; }\n private:\n  bool ansi_;\n};\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_REPORT_DECORATOR_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cc",
    "content": "//===-- sanitizer_stackdepot.cc -------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_stackdepot.h\"\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_stackdepotbase.h\"\n\nnamespace __sanitizer {\n\nstruct StackDepotNode {\n  StackDepotNode *link;\n  u32 id;\n  atomic_uint32_t hash_and_use_count; // hash_bits : 12; use_count : 20;\n  u32 size;\n  u32 tag;\n  uptr stack[1];  // [size]\n\n  static const u32 kTabSizeLog = 20;\n  // Lower kTabSizeLog bits are equal for all items in one bucket.\n  // We use these bits to store the per-stack use counter.\n  static const u32 kUseCountBits = kTabSizeLog;\n  static const u32 kMaxUseCount = 1 << kUseCountBits;\n  static const u32 kUseCountMask = (1 << kUseCountBits) - 1;\n  static const u32 kHashMask = ~kUseCountMask;\n\n  typedef StackTrace args_type;\n  bool eq(u32 hash, const args_type &args) const {\n    u32 hash_bits =\n        atomic_load(&hash_and_use_count, memory_order_relaxed) & kHashMask;\n    if ((hash & kHashMask) != hash_bits || args.size != size || args.tag != tag)\n      return false;\n    uptr i = 0;\n    for (; i < size; i++) {\n      if (stack[i] != args.trace[i]) return false;\n    }\n    return true;\n  }\n  static uptr storage_size(const args_type &args) {\n    return sizeof(StackDepotNode) + (args.size - 1) * sizeof(uptr);\n  }\n  static u32 hash(const args_type &args) {\n    // murmur2\n    const u32 m = 0x5bd1e995;\n    const u32 seed = 0x9747b28c;\n    const u32 r = 24;\n    u32 h = seed ^ (args.size * sizeof(uptr));\n    for (uptr i = 0; i < args.size; i++) {\n      u32 k = args.trace[i];\n      k *= m;\n      k ^= k >> r;\n      k *= m;\n      h *= m;\n      h ^= k;\n    }\n    h ^= h >> 13;\n    h *= m;\n    h ^= h >> 15;\n    return h;\n  }\n  static bool is_valid(const args_type &args) {\n    return args.size > 0 && args.trace;\n  }\n  void store(const args_type &args, u32 hash) {\n    atomic_store(&hash_and_use_count, hash & kHashMask, memory_order_relaxed);\n    size = args.size;\n    tag = args.tag;\n    internal_memcpy(stack, args.trace, size * sizeof(uptr));\n  }\n  args_type load() const {\n    return args_type(&stack[0], size, tag);\n  }\n  StackDepotHandle get_handle() { return StackDepotHandle(this); }\n\n  typedef StackDepotHandle handle_type;\n};\n\nCOMPILER_CHECK(StackDepotNode::kMaxUseCount == (u32)kStackDepotMaxUseCount);\n\nu32 StackDepotHandle::id() { return node_->id; }\nint StackDepotHandle::use_count() {\n  return atomic_load(&node_->hash_and_use_count, memory_order_relaxed) &\n         StackDepotNode::kUseCountMask;\n}\nvoid StackDepotHandle::inc_use_count_unsafe() {\n  u32 prev =\n      atomic_fetch_add(&node_->hash_and_use_count, 1, memory_order_relaxed) &\n      StackDepotNode::kUseCountMask;\n  CHECK_LT(prev + 1, StackDepotNode::kMaxUseCount);\n}\n\n// FIXME(dvyukov): this single reserved bit is used in TSan.\ntypedef StackDepotBase<StackDepotNode, 1, StackDepotNode::kTabSizeLog>\n    StackDepot;\nstatic StackDepot theDepot;\n\nStackDepotStats *StackDepotGetStats() {\n  return theDepot.GetStats();\n}\n\nu32 StackDepotPut(StackTrace stack) {\n  StackDepotHandle h = theDepot.Put(stack);\n  return h.valid() ? h.id() : 0;\n}\n\nStackDepotHandle StackDepotPut_WithHandle(StackTrace stack) {\n  return theDepot.Put(stack);\n}\n\nStackTrace StackDepotGet(u32 id) {\n  return theDepot.Get(id);\n}\n\nvoid StackDepotLockAll() {\n  theDepot.LockAll();\n}\n\nvoid StackDepotUnlockAll() {\n  theDepot.UnlockAll();\n}\n\nbool StackDepotReverseMap::IdDescPair::IdComparator(\n    const StackDepotReverseMap::IdDescPair &a,\n    const StackDepotReverseMap::IdDescPair &b) {\n  return a.id < b.id;\n}\n\nStackDepotReverseMap::StackDepotReverseMap()\n    : map_(StackDepotGetStats()->n_uniq_ids + 100) {\n  for (int idx = 0; idx < StackDepot::kTabSize; idx++) {\n    atomic_uintptr_t *p = &theDepot.tab[idx];\n    uptr v = atomic_load(p, memory_order_consume);\n    StackDepotNode *s = (StackDepotNode*)(v & ~1);\n    for (; s; s = s->link) {\n      IdDescPair pair = {s->id, s};\n      map_.push_back(pair);\n    }\n  }\n  InternalSort(&map_, map_.size(), IdDescPair::IdComparator);\n}\n\nStackTrace StackDepotReverseMap::Get(u32 id) {\n  if (!map_.size())\n    return StackTrace();\n  IdDescPair pair = {id, nullptr};\n  uptr idx = InternalBinarySearch(map_, 0, map_.size(), pair,\n                                  IdDescPair::IdComparator);\n  if (idx > map_.size())\n    return StackTrace();\n  return map_[idx].desc->load();\n}\n\n} // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h",
    "content": "//===-- sanitizer_stackdepot.h ----------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_STACKDEPOT_H\n#define SANITIZER_STACKDEPOT_H\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_stacktrace.h\"\n\nnamespace __sanitizer {\n\n// StackDepot efficiently stores huge amounts of stack traces.\nstruct StackDepotNode;\nstruct StackDepotHandle {\n  StackDepotNode *node_;\n  StackDepotHandle() : node_(nullptr) {}\n  explicit StackDepotHandle(StackDepotNode *node) : node_(node) {}\n  bool valid() { return node_; }\n  u32 id();\n  int use_count();\n  void inc_use_count_unsafe();\n};\n\nconst int kStackDepotMaxUseCount = 1U << 20;\n\nStackDepotStats *StackDepotGetStats();\nu32 StackDepotPut(StackTrace stack);\nStackDepotHandle StackDepotPut_WithHandle(StackTrace stack);\n// Retrieves a stored stack trace by the id.\nStackTrace StackDepotGet(u32 id);\n\nvoid StackDepotLockAll();\nvoid StackDepotUnlockAll();\n\n// Instantiating this class creates a snapshot of StackDepot which can be\n// efficiently queried with StackDepotGet(). You can use it concurrently with\n// StackDepot, but the snapshot is only guaranteed to contain those stack traces\n// which were stored before it was instantiated.\nclass StackDepotReverseMap {\n public:\n  StackDepotReverseMap();\n  StackTrace Get(u32 id);\n\n private:\n  struct IdDescPair {\n    u32 id;\n    StackDepotNode *desc;\n\n    static bool IdComparator(const IdDescPair &a, const IdDescPair &b);\n  };\n\n  InternalMmapVector<IdDescPair> map_;\n\n  // Disallow evil constructors.\n  StackDepotReverseMap(const StackDepotReverseMap&);\n  void operator=(const StackDepotReverseMap&);\n};\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_STACKDEPOT_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h",
    "content": "//===-- sanitizer_stackdepotbase.h ------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Implementation of a mapping from arbitrary values to unique 32-bit\n// identifiers.\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_STACKDEPOTBASE_H\n#define SANITIZER_STACKDEPOTBASE_H\n\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_mutex.h\"\n#include \"sanitizer_atomic.h\"\n#include \"sanitizer_persistent_allocator.h\"\n\nnamespace __sanitizer {\n\ntemplate <class Node, int kReservedBits, int kTabSizeLog>\nclass StackDepotBase {\n public:\n  typedef typename Node::args_type args_type;\n  typedef typename Node::handle_type handle_type;\n  // Maps stack trace to an unique id.\n  handle_type Put(args_type args, bool *inserted = nullptr);\n  // Retrieves a stored stack trace by the id.\n  args_type Get(u32 id);\n\n  StackDepotStats *GetStats() { return &stats; }\n\n  void LockAll();\n  void UnlockAll();\n\n private:\n  static Node *find(Node *s, args_type args, u32 hash);\n  static Node *lock(atomic_uintptr_t *p);\n  static void unlock(atomic_uintptr_t *p, Node *s);\n\n  static const int kTabSize = 1 << kTabSizeLog;  // Hash table size.\n  static const int kPartBits = 8;\n  static const int kPartShift = sizeof(u32) * 8 - kPartBits - kReservedBits;\n  static const int kPartCount =\n      1 << kPartBits;  // Number of subparts in the table.\n  static const int kPartSize = kTabSize / kPartCount;\n  static const int kMaxId = 1 << kPartShift;\n\n  atomic_uintptr_t tab[kTabSize];   // Hash table of Node's.\n  atomic_uint32_t seq[kPartCount];  // Unique id generators.\n\n  StackDepotStats stats;\n\n  friend class StackDepotReverseMap;\n};\n\ntemplate <class Node, int kReservedBits, int kTabSizeLog>\nNode *StackDepotBase<Node, kReservedBits, kTabSizeLog>::find(Node *s,\n                                                             args_type args,\n                                                             u32 hash) {\n  // Searches linked list s for the stack, returns its id.\n  for (; s; s = s->link) {\n    if (s->eq(hash, args)) {\n      return s;\n    }\n  }\n  return nullptr;\n}\n\ntemplate <class Node, int kReservedBits, int kTabSizeLog>\nNode *StackDepotBase<Node, kReservedBits, kTabSizeLog>::lock(\n    atomic_uintptr_t *p) {\n  // Uses the pointer lsb as mutex.\n  for (int i = 0;; i++) {\n    uptr cmp = atomic_load(p, memory_order_relaxed);\n    if ((cmp & 1) == 0 &&\n        atomic_compare_exchange_weak(p, &cmp, cmp | 1, memory_order_acquire))\n      return (Node *)cmp;\n    if (i < 10)\n      proc_yield(10);\n    else\n      internal_sched_yield();\n  }\n}\n\ntemplate <class Node, int kReservedBits, int kTabSizeLog>\nvoid StackDepotBase<Node, kReservedBits, kTabSizeLog>::unlock(\n    atomic_uintptr_t *p, Node *s) {\n  DCHECK_EQ((uptr)s & 1, 0);\n  atomic_store(p, (uptr)s, memory_order_release);\n}\n\ntemplate <class Node, int kReservedBits, int kTabSizeLog>\ntypename StackDepotBase<Node, kReservedBits, kTabSizeLog>::handle_type\nStackDepotBase<Node, kReservedBits, kTabSizeLog>::Put(args_type args,\n                                                      bool *inserted) {\n  if (inserted) *inserted = false;\n  if (!Node::is_valid(args)) return handle_type();\n  uptr h = Node::hash(args);\n  atomic_uintptr_t *p = &tab[h % kTabSize];\n  uptr v = atomic_load(p, memory_order_consume);\n  Node *s = (Node *)(v & ~1);\n  // First, try to find the existing stack.\n  Node *node = find(s, args, h);\n  if (node) return node->get_handle();\n  // If failed, lock, retry and insert new.\n  Node *s2 = lock(p);\n  if (s2 != s) {\n    node = find(s2, args, h);\n    if (node) {\n      unlock(p, s2);\n      return node->get_handle();\n    }\n  }\n  uptr part = (h % kTabSize) / kPartSize;\n  u32 id = atomic_fetch_add(&seq[part], 1, memory_order_relaxed) + 1;\n  stats.n_uniq_ids++;\n  CHECK_LT(id, kMaxId);\n  id |= part << kPartShift;\n  CHECK_NE(id, 0);\n  CHECK_EQ(id & (((u32)-1) >> kReservedBits), id);\n  uptr memsz = Node::storage_size(args);\n  s = (Node *)PersistentAlloc(memsz);\n  stats.allocated += memsz;\n  s->id = id;\n  s->store(args, h);\n  s->link = s2;\n  unlock(p, s);\n  if (inserted) *inserted = true;\n  return s->get_handle();\n}\n\ntemplate <class Node, int kReservedBits, int kTabSizeLog>\ntypename StackDepotBase<Node, kReservedBits, kTabSizeLog>::args_type\nStackDepotBase<Node, kReservedBits, kTabSizeLog>::Get(u32 id) {\n  if (id == 0) {\n    return args_type();\n  }\n  CHECK_EQ(id & (((u32)-1) >> kReservedBits), id);\n  // High kPartBits contain part id, so we need to scan at most kPartSize lists.\n  uptr part = id >> kPartShift;\n  for (int i = 0; i != kPartSize; i++) {\n    uptr idx = part * kPartSize + i;\n    CHECK_LT(idx, kTabSize);\n    atomic_uintptr_t *p = &tab[idx];\n    uptr v = atomic_load(p, memory_order_consume);\n    Node *s = (Node *)(v & ~1);\n    for (; s; s = s->link) {\n      if (s->id == id) {\n        return s->load();\n      }\n    }\n  }\n  return args_type();\n}\n\ntemplate <class Node, int kReservedBits, int kTabSizeLog>\nvoid StackDepotBase<Node, kReservedBits, kTabSizeLog>::LockAll() {\n  for (int i = 0; i < kTabSize; ++i) {\n    lock(&tab[i]);\n  }\n}\n\ntemplate <class Node, int kReservedBits, int kTabSizeLog>\nvoid StackDepotBase<Node, kReservedBits, kTabSizeLog>::UnlockAll() {\n  for (int i = 0; i < kTabSize; ++i) {\n    atomic_uintptr_t *p = &tab[i];\n    uptr s = atomic_load(p, memory_order_relaxed);\n    unlock(p, (Node *)(s & ~1UL));\n  }\n}\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_STACKDEPOTBASE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc",
    "content": "//===-- sanitizer_stacktrace.cc -------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_stacktrace.h\"\n\nnamespace __sanitizer {\n\nuptr StackTrace::GetNextInstructionPc(uptr pc) {\n#if defined(__mips__)\n  return pc + 8;\n#elif defined(__powerpc__)\n  return pc + 4;\n#else\n  return pc + 1;\n#endif\n}\n\nuptr StackTrace::GetCurrentPc() {\n  return GET_CALLER_PC();\n}\n\nvoid BufferedStackTrace::Init(const uptr *pcs, uptr cnt, uptr extra_top_pc) {\n  size = cnt + !!extra_top_pc;\n  CHECK_LE(size, kStackTraceMax);\n  internal_memcpy(trace_buffer, pcs, cnt * sizeof(trace_buffer[0]));\n  if (extra_top_pc)\n    trace_buffer[cnt] = extra_top_pc;\n  top_frame_bp = 0;\n}\n\n// Check if given pointer points into allocated stack area.\nstatic inline bool IsValidFrame(uptr frame, uptr stack_top, uptr stack_bottom) {\n  return frame > stack_bottom && frame < stack_top - 2 * sizeof (uhwptr);\n}\n\n// In GCC on ARM bp points to saved lr, not fp, so we should check the next\n// cell in stack to be a saved frame pointer. GetCanonicFrame returns the\n// pointer to saved frame pointer in any case.\nstatic inline uhwptr *GetCanonicFrame(uptr bp,\n                                      uptr stack_top,\n                                      uptr stack_bottom) {\n#ifdef __arm__\n  if (!IsValidFrame(bp, stack_top, stack_bottom)) return 0;\n  uhwptr *bp_prev = (uhwptr *)bp;\n  if (IsValidFrame((uptr)bp_prev[0], stack_top, stack_bottom)) return bp_prev;\n  // The next frame pointer does not look right. This could be a GCC frame, step\n  // back by 1 word and try again.\n  if (IsValidFrame((uptr)bp_prev[-1], stack_top, stack_bottom))\n    return bp_prev - 1;\n  // Nope, this does not look right either. This means the frame after next does\n  // not have a valid frame pointer, but we can still extract the caller PC.\n  // Unfortunately, there is no way to decide between GCC and LLVM frame\n  // layouts. Assume LLVM.\n  return bp_prev;\n#else\n  return (uhwptr*)bp;\n#endif\n}\n\nvoid BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top,\n                                         uptr stack_bottom, u32 max_depth) {\n  CHECK_GE(max_depth, 2);\n  trace_buffer[0] = pc;\n  size = 1;\n  if (stack_top < 4096) return;  // Sanity check for stack top.\n  uhwptr *frame = GetCanonicFrame(bp, stack_top, stack_bottom);\n  // Lowest possible address that makes sense as the next frame pointer.\n  // Goes up as we walk the stack.\n  uptr bottom = stack_bottom;\n  // Avoid infinite loop when frame == frame[0] by using frame > prev_frame.\n  while (IsValidFrame((uptr)frame, stack_top, bottom) &&\n         IsAligned((uptr)frame, sizeof(*frame)) &&\n         size < max_depth) {\n#ifdef __powerpc__\n    // PowerPC ABIs specify that the return address is saved at offset\n    // 16 of the *caller's* stack frame.  Thus we must dereference the\n    // back chain to find the caller frame before extracting it.\n    uhwptr *caller_frame = (uhwptr*)frame[0];\n    if (!IsValidFrame((uptr)caller_frame, stack_top, bottom) ||\n        !IsAligned((uptr)caller_frame, sizeof(uhwptr)))\n      break;\n    uhwptr pc1 = caller_frame[2];\n#else\n    uhwptr pc1 = frame[1];\n#endif\n    if (pc1 != pc) {\n      trace_buffer[size++] = (uptr) pc1;\n    }\n    bottom = (uptr)frame;\n    frame = GetCanonicFrame((uptr)frame[0], stack_top, bottom);\n  }\n}\n\nstatic bool MatchPc(uptr cur_pc, uptr trace_pc, uptr threshold) {\n  return cur_pc - trace_pc <= threshold || trace_pc - cur_pc <= threshold;\n}\n\nvoid BufferedStackTrace::PopStackFrames(uptr count) {\n  CHECK_LT(count, size);\n  size -= count;\n  for (uptr i = 0; i < size; ++i) {\n    trace_buffer[i] = trace_buffer[i + count];\n  }\n}\n\nuptr BufferedStackTrace::LocatePcInTrace(uptr pc) {\n  // Use threshold to find PC in stack trace, as PC we want to unwind from may\n  // slightly differ from return address in the actual unwinded stack trace.\n  const int kPcThreshold = 320;\n  for (uptr i = 0; i < size; ++i) {\n    if (MatchPc(pc, trace[i], kPcThreshold))\n      return i;\n  }\n  return 0;\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h",
    "content": "//===-- sanitizer_stacktrace.h ----------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_STACKTRACE_H\n#define SANITIZER_STACKTRACE_H\n\n#include \"sanitizer_internal_defs.h\"\n\nnamespace __sanitizer {\n\nstatic const u32 kStackTraceMax = 256;\n\n#if SANITIZER_LINUX &&  (defined(__sparc__) || defined(__mips__))\n# define SANITIZER_CAN_FAST_UNWIND 0\n#elif SANITIZER_WINDOWS\n# define SANITIZER_CAN_FAST_UNWIND 0\n#else\n# define SANITIZER_CAN_FAST_UNWIND 1\n#endif\n\n// Fast unwind is the only option on Mac for now; we will need to\n// revisit this macro when slow unwind works on Mac, see\n// https://github.com/google/sanitizers/issues/137\n#if SANITIZER_MAC\n# define SANITIZER_CAN_SLOW_UNWIND 0\n#else\n# define SANITIZER_CAN_SLOW_UNWIND 1\n#endif\n\nstruct StackTrace {\n  const uptr *trace;\n  u32 size;\n  u32 tag;\n\n  static const int TAG_UNKNOWN = 0;\n  static const int TAG_ALLOC = 1;\n  static const int TAG_DEALLOC = 2;\n  static const int TAG_CUSTOM = 100; // Tool specific tags start here.\n\n  StackTrace() : trace(nullptr), size(0), tag(0) {}\n  StackTrace(const uptr *trace, u32 size) : trace(trace), size(size), tag(0) {}\n  StackTrace(const uptr *trace, u32 size, u32 tag)\n      : trace(trace), size(size), tag(tag) {}\n\n  // Prints a symbolized stacktrace, followed by an empty line.\n  void Print() const;\n\n  static bool WillUseFastUnwind(bool request_fast_unwind) {\n    if (!SANITIZER_CAN_FAST_UNWIND)\n      return false;\n    else if (!SANITIZER_CAN_SLOW_UNWIND)\n      return true;\n    return request_fast_unwind;\n  }\n\n  static uptr GetCurrentPc();\n  static inline uptr GetPreviousInstructionPc(uptr pc);\n  static uptr GetNextInstructionPc(uptr pc);\n  typedef bool (*SymbolizeCallback)(const void *pc, char *out_buffer,\n                                    int out_size);\n};\n\n// Performance-critical, must be in the header.\nALWAYS_INLINE\nuptr StackTrace::GetPreviousInstructionPc(uptr pc) {\n#if defined(__arm__)\n  // Cancel Thumb bit.\n  pc = pc & (~1);\n#endif\n#if defined(__powerpc__) || defined(__powerpc64__)\n  // PCs are always 4 byte aligned.\n  return pc - 4;\n#elif defined(__sparc__) || defined(__mips__)\n  return pc - 8;\n#else\n  return pc - 1;\n#endif\n}\n\n// StackTrace that owns the buffer used to store the addresses.\nstruct BufferedStackTrace : public StackTrace {\n  uptr trace_buffer[kStackTraceMax];\n  uptr top_frame_bp;  // Optional bp of a top frame.\n\n  BufferedStackTrace() : StackTrace(trace_buffer, 0), top_frame_bp(0) {}\n\n  void Init(const uptr *pcs, uptr cnt, uptr extra_top_pc = 0);\n  void Unwind(u32 max_depth, uptr pc, uptr bp, void *context, uptr stack_top,\n              uptr stack_bottom, bool request_fast_unwind);\n\n private:\n  void FastUnwindStack(uptr pc, uptr bp, uptr stack_top, uptr stack_bottom,\n                       u32 max_depth);\n  void SlowUnwindStack(uptr pc, u32 max_depth);\n  void SlowUnwindStackWithContext(uptr pc, void *context,\n                                  u32 max_depth);\n  void PopStackFrames(uptr count);\n  uptr LocatePcInTrace(uptr pc);\n\n  BufferedStackTrace(const BufferedStackTrace &);\n  void operator=(const BufferedStackTrace &);\n};\n\n}  // namespace __sanitizer\n\n// Use this macro if you want to print stack trace with the caller\n// of the current function in the top frame.\n#define GET_CALLER_PC_BP_SP \\\n  uptr bp = GET_CURRENT_FRAME();              \\\n  uptr pc = GET_CALLER_PC();                  \\\n  uptr local_stack;                           \\\n  uptr sp = (uptr)&local_stack\n\n#define GET_CALLER_PC_BP \\\n  uptr bp = GET_CURRENT_FRAME();              \\\n  uptr pc = GET_CALLER_PC();\n\n// Use this macro if you want to print stack trace with the current\n// function in the top frame.\n#define GET_CURRENT_PC_BP_SP \\\n  uptr bp = GET_CURRENT_FRAME();              \\\n  uptr pc = StackTrace::GetCurrentPc();   \\\n  uptr local_stack;                           \\\n  uptr sp = (uptr)&local_stack\n\n\n#endif  // SANITIZER_STACKTRACE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc",
    "content": "//===-- sanitizer_stacktrace_libcdep.cc -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_placement_new.h\"\n#include \"sanitizer_stacktrace.h\"\n#include \"sanitizer_stacktrace_printer.h\"\n#include \"sanitizer_symbolizer.h\"\n\nnamespace __sanitizer {\n\nvoid StackTrace::Print() const {\n  if (trace == nullptr || size == 0) {\n    Printf(\"    <empty stack>\\n\\n\");\n    return;\n  }\n  InternalScopedString frame_desc(GetPageSizeCached() * 2);\n  uptr frame_num = 0;\n  for (uptr i = 0; i < size && trace[i]; i++) {\n    // PCs in stack traces are actually the return addresses, that is,\n    // addresses of the next instructions after the call.\n    uptr pc = GetPreviousInstructionPc(trace[i]);\n    SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(pc);\n    CHECK(frames);\n    for (SymbolizedStack *cur = frames; cur; cur = cur->next) {\n      frame_desc.clear();\n      RenderFrame(&frame_desc, common_flags()->stack_trace_format, frame_num++,\n                  cur->info, common_flags()->symbolize_vs_style,\n                  common_flags()->strip_path_prefix);\n      Printf(\"%s\\n\", frame_desc.data());\n    }\n    frames->ClearAll();\n  }\n  // Always print a trailing empty line after stack trace.\n  Printf(\"\\n\");\n}\n\nvoid BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context,\n                                uptr stack_top, uptr stack_bottom,\n                                bool request_fast_unwind) {\n  top_frame_bp = (max_depth > 0) ? bp : 0;\n  // Avoid doing any work for small max_depth.\n  if (max_depth == 0) {\n    size = 0;\n    return;\n  }\n  if (max_depth == 1) {\n    size = 1;\n    trace_buffer[0] = pc;\n    return;\n  }\n  if (!WillUseFastUnwind(request_fast_unwind)) {\n#if SANITIZER_CAN_SLOW_UNWIND\n    if (context)\n      SlowUnwindStackWithContext(pc, context, max_depth);\n    else\n      SlowUnwindStack(pc, max_depth);\n#else\n    UNREACHABLE(\"slow unwind requested but not available\");\n#endif\n  } else {\n    FastUnwindStack(pc, bp, stack_top, stack_bottom, max_depth);\n  }\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cc",
    "content": "//===-- sanitizer_common.cc -----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between sanitizers' run-time libraries.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_stacktrace_printer.h\"\n\nnamespace __sanitizer {\n\nstatic const char *StripFunctionName(const char *function, const char *prefix) {\n  if (!function) return nullptr;\n  if (!prefix) return function;\n  uptr prefix_len = internal_strlen(prefix);\n  if (0 == internal_strncmp(function, prefix, prefix_len))\n    return function + prefix_len;\n  return function;\n}\n\nstatic const char kDefaultFormat[] = \"    #%n %p %F %L\";\n\nvoid RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,\n                 const AddressInfo &info, bool vs_style,\n                 const char *strip_path_prefix, const char *strip_func_prefix) {\n  if (0 == internal_strcmp(format, \"DEFAULT\"))\n    format = kDefaultFormat;\n  for (const char *p = format; *p != '\\0'; p++) {\n    if (*p != '%') {\n      buffer->append(\"%c\", *p);\n      continue;\n    }\n    p++;\n    switch (*p) {\n    case '%':\n      buffer->append(\"%%\");\n      break;\n    // Frame number and all fields of AddressInfo structure.\n    case 'n':\n      buffer->append(\"%zu\", frame_no);\n      break;\n    case 'p':\n      buffer->append(\"0x%zx\", info.address);\n      break;\n    case 'm':\n      buffer->append(\"%s\", StripPathPrefix(info.module, strip_path_prefix));\n      break;\n    case 'o':\n      buffer->append(\"0x%zx\", info.module_offset);\n      break;\n    case 'f':\n      buffer->append(\"%s\", StripFunctionName(info.function, strip_func_prefix));\n      break;\n    case 'q':\n      buffer->append(\"0x%zx\", info.function_offset != AddressInfo::kUnknown\n                                  ? info.function_offset\n                                  : 0x0);\n      break;\n    case 's':\n      buffer->append(\"%s\", StripPathPrefix(info.file, strip_path_prefix));\n      break;\n    case 'l':\n      buffer->append(\"%d\", info.line);\n      break;\n    case 'c':\n      buffer->append(\"%d\", info.column);\n      break;\n    // Smarter special cases.\n    case 'F':\n      // Function name and offset, if file is unknown.\n      if (info.function) {\n        buffer->append(\"in %s\",\n                       StripFunctionName(info.function, strip_func_prefix));\n        if (!info.file && info.function_offset != AddressInfo::kUnknown)\n          buffer->append(\"+0x%zx\", info.function_offset);\n      }\n      break;\n    case 'S':\n      // File/line information.\n      RenderSourceLocation(buffer, info.file, info.line, info.column, vs_style,\n                           strip_path_prefix);\n      break;\n    case 'L':\n      // Source location, or module location.\n      if (info.file) {\n        RenderSourceLocation(buffer, info.file, info.line, info.column,\n                             vs_style, strip_path_prefix);\n      } else if (info.module) {\n        RenderModuleLocation(buffer, info.module, info.module_offset,\n                             strip_path_prefix);\n      } else {\n        buffer->append(\"(<unknown module>)\");\n      }\n      break;\n    case 'M':\n      // Module basename and offset, or PC.\n      if (info.address & kExternalPCBit)\n        {} // There PCs are not meaningful.\n      else if (info.module)\n        buffer->append(\"(%s+%p)\", StripModuleName(info.module),\n                       (void *)info.module_offset);\n      else\n        buffer->append(\"(%p)\", (void *)info.address);\n      break;\n    default:\n      Report(\"Unsupported specifier in stack frame format: %c (0x%zx)!\\n\", *p,\n             *p);\n      Die();\n    }\n  }\n}\n\nvoid RenderSourceLocation(InternalScopedString *buffer, const char *file,\n                          int line, int column, bool vs_style,\n                          const char *strip_path_prefix) {\n  if (vs_style && line > 0) {\n    buffer->append(\"%s(%d\", StripPathPrefix(file, strip_path_prefix), line);\n    if (column > 0)\n      buffer->append(\",%d\", column);\n    buffer->append(\")\");\n    return;\n  }\n\n  buffer->append(\"%s\", StripPathPrefix(file, strip_path_prefix));\n  if (line > 0) {\n    buffer->append(\":%d\", line);\n    if (column > 0)\n      buffer->append(\":%d\", column);\n  }\n}\n\nvoid RenderModuleLocation(InternalScopedString *buffer, const char *module,\n                          uptr offset, const char *strip_path_prefix) {\n  buffer->append(\"(%s+0x%zx)\", StripPathPrefix(module, strip_path_prefix),\n                 offset);\n}\n\n} // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h",
    "content": "//===-- sanitizer_stacktrace_printer.h --------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between sanitizers' run-time libraries.\n//\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_STACKTRACE_PRINTER_H\n#define SANITIZER_STACKTRACE_PRINTER_H\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_symbolizer.h\"\n\nnamespace __sanitizer {\n\n// Render the contents of \"info\" structure, which represents the contents of\n// stack frame \"frame_no\" and appends it to the \"buffer\". \"format\" is a\n// string with placeholders, which is copied to the output with\n// placeholders substituted with the contents of \"info\". For example,\n// format string\n//   \"  frame %n: function %F at %S\"\n// will be turned into\n//   \"  frame 10: function foo::bar() at my/file.cc:10\"\n// You may additionally pass \"strip_path_prefix\" to strip prefixes of paths to\n// source files and modules, and \"strip_func_prefix\" to strip prefixes of\n// function names.\n// Here's the full list of available placeholders:\n//   %% - represents a '%' character;\n//   %n - frame number (copy of frame_no);\n//   %p - PC in hex format;\n//   %m - path to module (binary or shared object);\n//   %o - offset in the module in hex format;\n//   %f - function name;\n//   %q - offset in the function in hex format (*if available*);\n//   %s - path to source file;\n//   %l - line in the source file;\n//   %c - column in the source file;\n//   %F - if function is known to be <foo>, prints \"in <foo>\", possibly\n//        followed by the offset in this function, but only if source file\n//        is unknown;\n//   %S - prints file/line/column information;\n//   %L - prints location information: file/line/column, if it is known, or\n//        module+offset if it is known, or (<unknown module>) string.\n//   %M - prints module basename and offset, if it is known, or PC.\nvoid RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,\n                 const AddressInfo &info, bool vs_style,\n                 const char *strip_path_prefix = \"\",\n                 const char *strip_func_prefix = \"\");\n\nvoid RenderSourceLocation(InternalScopedString *buffer, const char *file,\n                          int line, int column, bool vs_style,\n                          const char *strip_path_prefix);\n\nvoid RenderModuleLocation(InternalScopedString *buffer, const char *module,\n                          uptr offset, const char *strip_path_prefix);\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_STACKTRACE_PRINTER_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld.h",
    "content": "//===-- sanitizer_stoptheworld.h --------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Defines the StopTheWorld function which suspends the execution of the current\n// process and runs the user-supplied callback in the same address space.\n//\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_STOPTHEWORLD_H\n#define SANITIZER_STOPTHEWORLD_H\n\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_common.h\"\n\nnamespace __sanitizer {\ntypedef int SuspendedThreadID;\n\n// Holds the list of suspended threads and provides an interface to dump their\n// register contexts.\nclass SuspendedThreadsList {\n public:\n  SuspendedThreadsList()\n    : thread_ids_(1024) {}\n  SuspendedThreadID GetThreadID(uptr index) const {\n    CHECK_LT(index, thread_ids_.size());\n    return thread_ids_[index];\n  }\n  int GetRegistersAndSP(uptr index, uptr *buffer, uptr *sp) const;\n  // The buffer in GetRegistersAndSP should be at least this big.\n  static uptr RegisterCount();\n  uptr thread_count() const { return thread_ids_.size(); }\n  bool Contains(SuspendedThreadID thread_id) const {\n    for (uptr i = 0; i < thread_ids_.size(); i++) {\n      if (thread_ids_[i] == thread_id)\n        return true;\n    }\n    return false;\n  }\n  void Append(SuspendedThreadID thread_id) {\n    thread_ids_.push_back(thread_id);\n  }\n\n private:\n  InternalMmapVector<SuspendedThreadID> thread_ids_;\n\n  // Prohibit copy and assign.\n  SuspendedThreadsList(const SuspendedThreadsList&);\n  void operator=(const SuspendedThreadsList&);\n};\n\ntypedef void (*StopTheWorldCallback)(\n    const SuspendedThreadsList &suspended_threads_list,\n    void *argument);\n\n// Suspend all threads in the current process and run the callback on the list\n// of suspended threads. This function will resume the threads before returning.\n// The callback should not call any libc functions. The callback must not call\n// exit() nor _exit() and instead return to the caller.\n// This function should NOT be called from multiple threads simultaneously.\nvoid StopTheWorld(StopTheWorldCallback callback, void *argument);\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_STOPTHEWORLD_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc",
    "content": "//===-- sanitizer_stoptheworld_linux_libcdep.cc ---------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// See sanitizer_stoptheworld.h for details.\n// This implementation was inspired by Markus Gutschke's linuxthreads.cc.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n\n#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__) || \\\n                        defined(__aarch64__) || defined(__powerpc64__))\n\n#include \"sanitizer_stoptheworld.h\"\n\n#include \"sanitizer_platform_limits_posix.h\"\n#include \"sanitizer_atomic.h\"\n\n#include <errno.h>\n#include <sched.h> // for CLONE_* definitions\n#include <stddef.h>\n#include <sys/prctl.h> // for PR_* definitions\n#include <sys/ptrace.h> // for PTRACE_* definitions\n#include <sys/types.h> // for pid_t\n#include <sys/uio.h> // for iovec\n#include <elf.h> // for NT_PRSTATUS\n#if SANITIZER_ANDROID && defined(__arm__)\n# include <linux/user.h>  // for pt_regs\n#else\n# ifdef __aarch64__\n// GLIBC 2.20+ sys/user does not include asm/ptrace.h\n#  include <asm/ptrace.h>\n# endif\n# include <sys/user.h>  // for user_regs_struct\n#endif\n#include <sys/wait.h> // for signal-related stuff\n\n#ifdef sa_handler\n# undef sa_handler\n#endif\n\n#ifdef sa_sigaction\n# undef sa_sigaction\n#endif\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_linux.h\"\n#include \"sanitizer_mutex.h\"\n#include \"sanitizer_placement_new.h\"\n\n// This module works by spawning a Linux task which then attaches to every\n// thread in the caller process with ptrace. This suspends the threads, and\n// PTRACE_GETREGS can then be used to obtain their register state. The callback\n// supplied to StopTheWorld() is run in the tracer task while the threads are\n// suspended.\n// The tracer task must be placed in a different thread group for ptrace to\n// work, so it cannot be spawned as a pthread. Instead, we use the low-level\n// clone() interface (we want to share the address space with the caller\n// process, so we prefer clone() over fork()).\n//\n// We don't use any libc functions, relying instead on direct syscalls. There\n// are two reasons for this:\n// 1. calling a library function while threads are suspended could cause a\n// deadlock, if one of the treads happens to be holding a libc lock;\n// 2. it's generally not safe to call libc functions from the tracer task,\n// because clone() does not set up a thread-local storage for it. Any\n// thread-local variables used by libc will be shared between the tracer task\n// and the thread which spawned it.\n\nCOMPILER_CHECK(sizeof(SuspendedThreadID) == sizeof(pid_t));\n\nnamespace __sanitizer {\n\n// Structure for passing arguments into the tracer thread.\nstruct TracerThreadArgument {\n  StopTheWorldCallback callback;\n  void *callback_argument;\n  // The tracer thread waits on this mutex while the parent finishes its\n  // preparations.\n  BlockingMutex mutex;\n  // Tracer thread signals its completion by setting done.\n  atomic_uintptr_t done;\n  uptr parent_pid;\n};\n\n// This class handles thread suspending/unsuspending in the tracer thread.\nclass ThreadSuspender {\n public:\n  explicit ThreadSuspender(pid_t pid, TracerThreadArgument *arg)\n    : arg(arg)\n    , pid_(pid) {\n      CHECK_GE(pid, 0);\n    }\n  bool SuspendAllThreads();\n  void ResumeAllThreads();\n  void KillAllThreads();\n  SuspendedThreadsList &suspended_threads_list() {\n    return suspended_threads_list_;\n  }\n  TracerThreadArgument *arg;\n private:\n  SuspendedThreadsList suspended_threads_list_;\n  pid_t pid_;\n  bool SuspendThread(SuspendedThreadID thread_id);\n};\n\nbool ThreadSuspender::SuspendThread(SuspendedThreadID tid) {\n  // Are we already attached to this thread?\n  // Currently this check takes linear time, however the number of threads is\n  // usually small.\n  if (suspended_threads_list_.Contains(tid))\n    return false;\n  int pterrno;\n  if (internal_iserror(internal_ptrace(PTRACE_ATTACH, tid, nullptr, nullptr),\n                       &pterrno)) {\n    // Either the thread is dead, or something prevented us from attaching.\n    // Log this event and move on.\n    VReport(1, \"Could not attach to thread %d (errno %d).\\n\", tid, pterrno);\n    return false;\n  } else {\n    VReport(2, \"Attached to thread %d.\\n\", tid);\n    // The thread is not guaranteed to stop before ptrace returns, so we must\n    // wait on it. Note: if the thread receives a signal concurrently,\n    // we can get notification about the signal before notification about stop.\n    // In such case we need to forward the signal to the thread, otherwise\n    // the signal will be missed (as we do PTRACE_DETACH with arg=0) and\n    // any logic relying on signals will break. After forwarding we need to\n    // continue to wait for stopping, because the thread is not stopped yet.\n    // We do ignore delivery of SIGSTOP, because we want to make stop-the-world\n    // as invisible as possible.\n    for (;;) {\n      int status;\n      uptr waitpid_status;\n      HANDLE_EINTR(waitpid_status, internal_waitpid(tid, &status, __WALL));\n      int wperrno;\n      if (internal_iserror(waitpid_status, &wperrno)) {\n        // Got a ECHILD error. I don't think this situation is possible, but it\n        // doesn't hurt to report it.\n        VReport(1, \"Waiting on thread %d failed, detaching (errno %d).\\n\",\n                tid, wperrno);\n        internal_ptrace(PTRACE_DETACH, tid, nullptr, nullptr);\n        return false;\n      }\n      if (WIFSTOPPED(status) && WSTOPSIG(status) != SIGSTOP) {\n        internal_ptrace(PTRACE_CONT, tid, nullptr,\n                        (void*)(uptr)WSTOPSIG(status));\n        continue;\n      }\n      break;\n    }\n    suspended_threads_list_.Append(tid);\n    return true;\n  }\n}\n\nvoid ThreadSuspender::ResumeAllThreads() {\n  for (uptr i = 0; i < suspended_threads_list_.thread_count(); i++) {\n    pid_t tid = suspended_threads_list_.GetThreadID(i);\n    int pterrno;\n    if (!internal_iserror(internal_ptrace(PTRACE_DETACH, tid, nullptr, nullptr),\n                          &pterrno)) {\n      VReport(2, \"Detached from thread %d.\\n\", tid);\n    } else {\n      // Either the thread is dead, or we are already detached.\n      // The latter case is possible, for instance, if this function was called\n      // from a signal handler.\n      VReport(1, \"Could not detach from thread %d (errno %d).\\n\", tid, pterrno);\n    }\n  }\n}\n\nvoid ThreadSuspender::KillAllThreads() {\n  for (uptr i = 0; i < suspended_threads_list_.thread_count(); i++)\n    internal_ptrace(PTRACE_KILL, suspended_threads_list_.GetThreadID(i),\n                    nullptr, nullptr);\n}\n\nbool ThreadSuspender::SuspendAllThreads() {\n  ThreadLister thread_lister(pid_);\n  bool added_threads;\n  do {\n    // Run through the directory entries once.\n    added_threads = false;\n    pid_t tid = thread_lister.GetNextTID();\n    while (tid >= 0) {\n      if (SuspendThread(tid))\n        added_threads = true;\n      tid = thread_lister.GetNextTID();\n    }\n    if (thread_lister.error()) {\n      // Detach threads and fail.\n      ResumeAllThreads();\n      return false;\n    }\n    thread_lister.Reset();\n  } while (added_threads);\n  return true;\n}\n\n// Pointer to the ThreadSuspender instance for use in signal handler.\nstatic ThreadSuspender *thread_suspender_instance = nullptr;\n\n// Synchronous signals that should not be blocked.\nstatic const int kSyncSignals[] = { SIGABRT, SIGILL, SIGFPE, SIGSEGV, SIGBUS,\n                                    SIGXCPU, SIGXFSZ };\n\nstatic void TracerThreadDieCallback() {\n  // Generally a call to Die() in the tracer thread should be fatal to the\n  // parent process as well, because they share the address space.\n  // This really only works correctly if all the threads are suspended at this\n  // point. So we correctly handle calls to Die() from within the callback, but\n  // not those that happen before or after the callback. Hopefully there aren't\n  // a lot of opportunities for that to happen...\n  ThreadSuspender *inst = thread_suspender_instance;\n  if (inst && stoptheworld_tracer_pid == internal_getpid()) {\n    inst->KillAllThreads();\n    thread_suspender_instance = nullptr;\n  }\n}\n\n// Signal handler to wake up suspended threads when the tracer thread dies.\nstatic void TracerThreadSignalHandler(int signum, void *siginfo, void *uctx) {\n  SignalContext ctx = SignalContext::Create(siginfo, uctx);\n  VPrintf(1, \"Tracer caught signal %d: addr=0x%zx pc=0x%zx sp=0x%zx\\n\",\n      signum, ctx.addr, ctx.pc, ctx.sp);\n  ThreadSuspender *inst = thread_suspender_instance;\n  if (inst) {\n    if (signum == SIGABRT)\n      inst->KillAllThreads();\n    else\n      inst->ResumeAllThreads();\n    RAW_CHECK(RemoveDieCallback(TracerThreadDieCallback));\n    thread_suspender_instance = nullptr;\n    atomic_store(&inst->arg->done, 1, memory_order_relaxed);\n  }\n  internal__exit((signum == SIGABRT) ? 1 : 2);\n}\n\n// Size of alternative stack for signal handlers in the tracer thread.\nstatic const int kHandlerStackSize = 4096;\n\n// This function will be run as a cloned task.\nstatic int TracerThread(void* argument) {\n  TracerThreadArgument *tracer_thread_argument =\n      (TracerThreadArgument *)argument;\n\n  internal_prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);\n  // Check if parent is already dead.\n  if (internal_getppid() != tracer_thread_argument->parent_pid)\n    internal__exit(4);\n\n  // Wait for the parent thread to finish preparations.\n  tracer_thread_argument->mutex.Lock();\n  tracer_thread_argument->mutex.Unlock();\n\n  RAW_CHECK(AddDieCallback(TracerThreadDieCallback));\n\n  ThreadSuspender thread_suspender(internal_getppid(), tracer_thread_argument);\n  // Global pointer for the signal handler.\n  thread_suspender_instance = &thread_suspender;\n\n  // Alternate stack for signal handling.\n  InternalScopedBuffer<char> handler_stack_memory(kHandlerStackSize);\n  struct sigaltstack handler_stack;\n  internal_memset(&handler_stack, 0, sizeof(handler_stack));\n  handler_stack.ss_sp = handler_stack_memory.data();\n  handler_stack.ss_size = kHandlerStackSize;\n  internal_sigaltstack(&handler_stack, nullptr);\n\n  // Install our handler for synchronous signals. Other signals should be\n  // blocked by the mask we inherited from the parent thread.\n  for (uptr i = 0; i < ARRAY_SIZE(kSyncSignals); i++) {\n    __sanitizer_sigaction act;\n    internal_memset(&act, 0, sizeof(act));\n    act.sigaction = TracerThreadSignalHandler;\n    act.sa_flags = SA_ONSTACK | SA_SIGINFO;\n    internal_sigaction_norestorer(kSyncSignals[i], &act, 0);\n  }\n\n  int exit_code = 0;\n  if (!thread_suspender.SuspendAllThreads()) {\n    VReport(1, \"Failed suspending threads.\\n\");\n    exit_code = 3;\n  } else {\n    tracer_thread_argument->callback(thread_suspender.suspended_threads_list(),\n                                     tracer_thread_argument->callback_argument);\n    thread_suspender.ResumeAllThreads();\n    exit_code = 0;\n  }\n  RAW_CHECK(RemoveDieCallback(TracerThreadDieCallback));\n  thread_suspender_instance = nullptr;\n  atomic_store(&tracer_thread_argument->done, 1, memory_order_relaxed);\n  return exit_code;\n}\n\nclass ScopedStackSpaceWithGuard {\n public:\n  explicit ScopedStackSpaceWithGuard(uptr stack_size) {\n    stack_size_ = stack_size;\n    guard_size_ = GetPageSizeCached();\n    // FIXME: Omitting MAP_STACK here works in current kernels but might break\n    // in the future.\n    guard_start_ = (uptr)MmapOrDie(stack_size_ + guard_size_,\n                                   \"ScopedStackWithGuard\");\n    CHECK(MprotectNoAccess((uptr)guard_start_, guard_size_));\n  }\n  ~ScopedStackSpaceWithGuard() {\n    UnmapOrDie((void *)guard_start_, stack_size_ + guard_size_);\n  }\n  void *Bottom() const {\n    return (void *)(guard_start_ + stack_size_ + guard_size_);\n  }\n\n private:\n  uptr stack_size_;\n  uptr guard_size_;\n  uptr guard_start_;\n};\n\n// We have a limitation on the stack frame size, so some stuff had to be moved\n// into globals.\nstatic __sanitizer_sigset_t blocked_sigset;\nstatic __sanitizer_sigset_t old_sigset;\n\nclass StopTheWorldScope {\n public:\n  StopTheWorldScope() {\n    // Make this process dumpable. Processes that are not dumpable cannot be\n    // attached to.\n    process_was_dumpable_ = internal_prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);\n    if (!process_was_dumpable_)\n      internal_prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);\n  }\n\n  ~StopTheWorldScope() {\n    // Restore the dumpable flag.\n    if (!process_was_dumpable_)\n      internal_prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);\n  }\n\n private:\n  int process_was_dumpable_;\n};\n\n// When sanitizer output is being redirected to file (i.e. by using log_path),\n// the tracer should write to the parent's log instead of trying to open a new\n// file. Alert the logging code to the fact that we have a tracer.\nstruct ScopedSetTracerPID {\n  explicit ScopedSetTracerPID(uptr tracer_pid) {\n    stoptheworld_tracer_pid = tracer_pid;\n    stoptheworld_tracer_ppid = internal_getpid();\n  }\n  ~ScopedSetTracerPID() {\n    stoptheworld_tracer_pid = 0;\n    stoptheworld_tracer_ppid = 0;\n  }\n};\n\nvoid StopTheWorld(StopTheWorldCallback callback, void *argument) {\n  StopTheWorldScope in_stoptheworld;\n  // Prepare the arguments for TracerThread.\n  struct TracerThreadArgument tracer_thread_argument;\n  tracer_thread_argument.callback = callback;\n  tracer_thread_argument.callback_argument = argument;\n  tracer_thread_argument.parent_pid = internal_getpid();\n  atomic_store(&tracer_thread_argument.done, 0, memory_order_relaxed);\n  const uptr kTracerStackSize = 2 * 1024 * 1024;\n  ScopedStackSpaceWithGuard tracer_stack(kTracerStackSize);\n  // Block the execution of TracerThread until after we have set ptrace\n  // permissions.\n  tracer_thread_argument.mutex.Lock();\n  // Signal handling story.\n  // We don't want async signals to be delivered to the tracer thread,\n  // so we block all async signals before creating the thread. An async signal\n  // handler can temporary modify errno, which is shared with this thread.\n  // We ought to use pthread_sigmask here, because sigprocmask has undefined\n  // behavior in multithreaded programs. However, on linux sigprocmask is\n  // equivalent to pthread_sigmask with the exception that pthread_sigmask\n  // does not allow to block some signals used internally in pthread\n  // implementation. We are fine with blocking them here, we are really not\n  // going to pthread_cancel the thread.\n  // The tracer thread should not raise any synchronous signals. But in case it\n  // does, we setup a special handler for sync signals that properly kills the\n  // parent as well. Note: we don't pass CLONE_SIGHAND to clone, so handlers\n  // in the tracer thread won't interfere with user program. Double note: if a\n  // user does something along the lines of 'kill -11 pid', that can kill the\n  // process even if user setup own handler for SEGV.\n  // Thing to watch out for: this code should not change behavior of user code\n  // in any observable way. In particular it should not override user signal\n  // handlers.\n  internal_sigfillset(&blocked_sigset);\n  for (uptr i = 0; i < ARRAY_SIZE(kSyncSignals); i++)\n    internal_sigdelset(&blocked_sigset, kSyncSignals[i]);\n  int rv = internal_sigprocmask(SIG_BLOCK, &blocked_sigset, &old_sigset);\n  CHECK_EQ(rv, 0);\n  uptr tracer_pid = internal_clone(\n      TracerThread, tracer_stack.Bottom(),\n      CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_UNTRACED,\n      &tracer_thread_argument, nullptr /* parent_tidptr */,\n      nullptr /* newtls */, nullptr /* child_tidptr */);\n  internal_sigprocmask(SIG_SETMASK, &old_sigset, 0);\n  int local_errno = 0;\n  if (internal_iserror(tracer_pid, &local_errno)) {\n    VReport(1, \"Failed spawning a tracer thread (errno %d).\\n\", local_errno);\n    tracer_thread_argument.mutex.Unlock();\n  } else {\n    ScopedSetTracerPID scoped_set_tracer_pid(tracer_pid);\n    // On some systems we have to explicitly declare that we want to be traced\n    // by the tracer thread.\n#ifdef PR_SET_PTRACER\n    internal_prctl(PR_SET_PTRACER, tracer_pid, 0, 0, 0);\n#endif\n    // Allow the tracer thread to start.\n    tracer_thread_argument.mutex.Unlock();\n    // NOTE: errno is shared between this thread and the tracer thread.\n    // internal_waitpid() may call syscall() which can access/spoil errno,\n    // so we can't call it now. Instead we for the tracer thread to finish using\n    // the spin loop below. Man page for sched_yield() says \"In the Linux\n    // implementation, sched_yield() always succeeds\", so let's hope it does not\n    // spoil errno. Note that this spin loop runs only for brief periods before\n    // the tracer thread has suspended us and when it starts unblocking threads.\n    while (atomic_load(&tracer_thread_argument.done, memory_order_relaxed) == 0)\n      sched_yield();\n    // Now the tracer thread is about to exit and does not touch errno,\n    // wait for it.\n    for (;;) {\n      uptr waitpid_status = internal_waitpid(tracer_pid, nullptr, __WALL);\n      if (!internal_iserror(waitpid_status, &local_errno))\n        break;\n      if (local_errno == EINTR)\n        continue;\n      VReport(1, \"Waiting on the tracer thread failed (errno %d).\\n\",\n              local_errno);\n      break;\n    }\n  }\n}\n\n// Platform-specific methods from SuspendedThreadsList.\n#if SANITIZER_ANDROID && defined(__arm__)\ntypedef pt_regs regs_struct;\n#define REG_SP ARM_sp\n\n#elif SANITIZER_LINUX && defined(__arm__)\ntypedef user_regs regs_struct;\n#define REG_SP uregs[13]\n\n#elif defined(__i386__) || defined(__x86_64__)\ntypedef user_regs_struct regs_struct;\n#if defined(__i386__)\n#define REG_SP esp\n#else\n#define REG_SP rsp\n#endif\n\n#elif defined(__powerpc__) || defined(__powerpc64__)\ntypedef pt_regs regs_struct;\n#define REG_SP gpr[PT_R1]\n\n#elif defined(__mips__)\ntypedef struct user regs_struct;\n#define REG_SP regs[EF_REG29]\n\n#elif defined(__aarch64__)\ntypedef struct user_pt_regs regs_struct;\n#define REG_SP sp\n#define ARCH_IOVEC_FOR_GETREGSET\n\n#else\n#error \"Unsupported architecture\"\n#endif // SANITIZER_ANDROID && defined(__arm__)\n\nint SuspendedThreadsList::GetRegistersAndSP(uptr index,\n                                            uptr *buffer,\n                                            uptr *sp) const {\n  pid_t tid = GetThreadID(index);\n  regs_struct regs;\n  int pterrno;\n#ifdef ARCH_IOVEC_FOR_GETREGSET\n  struct iovec regset_io;\n  regset_io.iov_base = &regs;\n  regset_io.iov_len = sizeof(regs_struct);\n  bool isErr = internal_iserror(internal_ptrace(PTRACE_GETREGSET, tid,\n                                (void*)NT_PRSTATUS, (void*)&regset_io),\n                                &pterrno);\n#else\n  bool isErr = internal_iserror(internal_ptrace(PTRACE_GETREGS, tid, nullptr,\n                                &regs), &pterrno);\n#endif\n  if (isErr) {\n    VReport(1, \"Could not get registers from thread %d (errno %d).\\n\", tid,\n            pterrno);\n    return -1;\n  }\n\n  *sp = regs.REG_SP;\n  internal_memcpy(buffer, &regs, sizeof(regs));\n  return 0;\n}\n\nuptr SuspendedThreadsList::RegisterCount() {\n  return sizeof(regs_struct) / sizeof(uptr);\n}\n} // namespace __sanitizer\n\n#endif  // SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__)\n        // || defined(__aarch64__) || defined(__powerpc64__)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.cc",
    "content": "//===-- sanitizer_suppressions.cc -----------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Suppression parsing/matching code.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_suppressions.h\"\n\n#include \"sanitizer_allocator_internal.h\"\n#include \"sanitizer_common.h\"\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_placement_new.h\"\n\nnamespace __sanitizer {\n\nSuppressionContext::SuppressionContext(const char *suppression_types[],\n                                       int suppression_types_num)\n    : suppression_types_(suppression_types),\n      suppression_types_num_(suppression_types_num), suppressions_(1),\n      can_parse_(true) {\n  CHECK_LE(suppression_types_num_, kMaxSuppressionTypes);\n  internal_memset(has_suppression_type_, 0, suppression_types_num_);\n}\n\nstatic bool GetPathAssumingFileIsRelativeToExec(const char *file_path,\n                                                /*out*/char *new_file_path,\n                                                uptr new_file_path_size) {\n  InternalScopedString exec(kMaxPathLength);\n  if (ReadBinaryNameCached(exec.data(), exec.size())) {\n    const char *file_name_pos = StripModuleName(exec.data());\n    uptr path_to_exec_len = file_name_pos - exec.data();\n    internal_strncat(new_file_path, exec.data(),\n                     Min(path_to_exec_len, new_file_path_size - 1));\n    internal_strncat(new_file_path, file_path,\n                     new_file_path_size - internal_strlen(new_file_path) - 1);\n    return true;\n  }\n  return false;\n}\n\nvoid SuppressionContext::ParseFromFile(const char *filename) {\n  if (filename[0] == '\\0')\n    return;\n\n  // If we cannot find the file, check if its location is relative to\n  // the location of the executable.\n  InternalScopedString new_file_path(kMaxPathLength);\n  if (!FileExists(filename) && !IsAbsolutePath(filename) &&\n      GetPathAssumingFileIsRelativeToExec(filename, new_file_path.data(),\n                                          new_file_path.size())) {\n    filename = new_file_path.data();\n  }\n\n  // Read the file.\n  VPrintf(1, \"%s: reading suppressions file at %s\\n\",\n          SanitizerToolName, filename);\n  char *file_contents;\n  uptr buffer_size;\n  uptr contents_size;\n  if (!ReadFileToBuffer(filename, &file_contents, &buffer_size,\n                        &contents_size)) {\n    Printf(\"%s: failed to read suppressions file '%s'\\n\", SanitizerToolName,\n           filename);\n    Die();\n  }\n\n  Parse(file_contents);\n}\n\nbool SuppressionContext::Match(const char *str, const char *type,\n                               Suppression **s) {\n  can_parse_ = false;\n  if (!HasSuppressionType(type))\n    return false;\n  for (uptr i = 0; i < suppressions_.size(); i++) {\n    Suppression &cur = suppressions_[i];\n    if (0 == internal_strcmp(cur.type, type) && TemplateMatch(cur.templ, str)) {\n      *s = &cur;\n      return true;\n    }\n  }\n  return false;\n}\n\nstatic const char *StripPrefix(const char *str, const char *prefix) {\n  while (str && *str == *prefix) {\n    str++;\n    prefix++;\n  }\n  if (!*prefix)\n    return str;\n  return 0;\n}\n\nvoid SuppressionContext::Parse(const char *str) {\n  // Context must not mutate once Match has been called.\n  CHECK(can_parse_);\n  const char *line = str;\n  while (line) {\n    while (line[0] == ' ' || line[0] == '\\t')\n      line++;\n    const char *end = internal_strchr(line, '\\n');\n    if (end == 0)\n      end = line + internal_strlen(line);\n    if (line != end && line[0] != '#') {\n      const char *end2 = end;\n      while (line != end2 &&\n             (end2[-1] == ' ' || end2[-1] == '\\t' || end2[-1] == '\\r'))\n        end2--;\n      int type;\n      for (type = 0; type < suppression_types_num_; type++) {\n        const char *next_char = StripPrefix(line, suppression_types_[type]);\n        if (next_char && *next_char == ':') {\n          line = ++next_char;\n          break;\n        }\n      }\n      if (type == suppression_types_num_) {\n        Printf(\"%s: failed to parse suppressions\\n\", SanitizerToolName);\n        Die();\n      }\n      Suppression s;\n      s.type = suppression_types_[type];\n      s.templ = (char*)InternalAlloc(end2 - line + 1);\n      internal_memcpy(s.templ, line, end2 - line);\n      s.templ[end2 - line] = 0;\n      suppressions_.push_back(s);\n      has_suppression_type_[type] = true;\n    }\n    if (end[0] == 0)\n      break;\n    line = end + 1;\n  }\n}\n\nuptr SuppressionContext::SuppressionCount() const {\n  return suppressions_.size();\n}\n\nbool SuppressionContext::HasSuppressionType(const char *type) const {\n  for (int i = 0; i < suppression_types_num_; i++) {\n    if (0 == internal_strcmp(type, suppression_types_[i]))\n      return has_suppression_type_[i];\n  }\n  return false;\n}\n\nconst Suppression *SuppressionContext::SuppressionAt(uptr i) const {\n  CHECK_LT(i, suppressions_.size());\n  return &suppressions_[i];\n}\n\nvoid SuppressionContext::GetMatched(\n    InternalMmapVector<Suppression *> *matched) {\n  for (uptr i = 0; i < suppressions_.size(); i++)\n    if (atomic_load_relaxed(&suppressions_[i].hit_count))\n      matched->push_back(&suppressions_[i]);\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_suppressions.h",
    "content": "//===-- sanitizer_suppressions.h --------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Suppression parsing/matching code.\n//\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_SUPPRESSIONS_H\n#define SANITIZER_SUPPRESSIONS_H\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_atomic.h\"\n#include \"sanitizer_internal_defs.h\"\n\nnamespace __sanitizer {\n\nstruct Suppression {\n  Suppression() { internal_memset(this, 0, sizeof(*this)); }\n  const char *type;\n  char *templ;\n  atomic_uint32_t hit_count;\n  uptr weight;\n};\n\nclass SuppressionContext {\n public:\n  // Create new SuppressionContext capable of parsing given suppression types.\n  SuppressionContext(const char *supprression_types[],\n                     int suppression_types_num);\n\n  void ParseFromFile(const char *filename);\n  void Parse(const char *str);\n\n  bool Match(const char *str, const char *type, Suppression **s);\n  uptr SuppressionCount() const;\n  bool HasSuppressionType(const char *type) const;\n  const Suppression *SuppressionAt(uptr i) const;\n  void GetMatched(InternalMmapVector<Suppression *> *matched);\n\n private:\n  static const int kMaxSuppressionTypes = 32;\n  const char **const suppression_types_;\n  const int suppression_types_num_;\n\n  InternalMmapVector<Suppression> suppressions_;\n  bool has_suppression_type_[kMaxSuppressionTypes];\n  bool can_parse_;\n};\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_SUPPRESSIONS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cc",
    "content": "//===-- sanitizer_symbolizer.cc -------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_allocator_internal.h\"\n#include \"sanitizer_platform.h\"\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_placement_new.h\"\n#include \"sanitizer_symbolizer_internal.h\"\n\nnamespace __sanitizer {\n\nAddressInfo::AddressInfo() {\n  internal_memset(this, 0, sizeof(AddressInfo));\n  function_offset = kUnknown;\n}\n\nvoid AddressInfo::Clear() {\n  InternalFree(module);\n  InternalFree(function);\n  InternalFree(file);\n  internal_memset(this, 0, sizeof(AddressInfo));\n  function_offset = kUnknown;\n}\n\nvoid AddressInfo::FillModuleInfo(const char *mod_name, uptr mod_offset) {\n  module = internal_strdup(mod_name);\n  module_offset = mod_offset;\n}\n\nSymbolizedStack::SymbolizedStack() : next(nullptr), info() {}\n\nSymbolizedStack *SymbolizedStack::New(uptr addr) {\n  void *mem = InternalAlloc(sizeof(SymbolizedStack));\n  SymbolizedStack *res = new(mem) SymbolizedStack();\n  res->info.address = addr;\n  return res;\n}\n\nvoid SymbolizedStack::ClearAll() {\n  info.Clear();\n  if (next)\n    next->ClearAll();\n  InternalFree(this);\n}\n\nDataInfo::DataInfo() {\n  internal_memset(this, 0, sizeof(DataInfo));\n}\n\nvoid DataInfo::Clear() {\n  InternalFree(module);\n  InternalFree(name);\n  internal_memset(this, 0, sizeof(DataInfo));\n}\n\nSymbolizer *Symbolizer::symbolizer_;\nStaticSpinMutex Symbolizer::init_mu_;\nLowLevelAllocator Symbolizer::symbolizer_allocator_;\n\nvoid Symbolizer::AddHooks(Symbolizer::StartSymbolizationHook start_hook,\n                          Symbolizer::EndSymbolizationHook end_hook) {\n  CHECK(start_hook_ == 0 && end_hook_ == 0);\n  start_hook_ = start_hook;\n  end_hook_ = end_hook;\n}\n\nconst char *Symbolizer::ModuleNameOwner::GetOwnedCopy(const char *str) {\n  mu_->CheckLocked();\n\n  // 'str' will be the same string multiple times in a row, optimize this case.\n  if (last_match_ && !internal_strcmp(last_match_, str))\n    return last_match_;\n\n  // FIXME: this is linear search.\n  // We should optimize this further if this turns out to be a bottleneck later.\n  for (uptr i = 0; i < storage_.size(); ++i) {\n    if (!internal_strcmp(storage_[i], str)) {\n      last_match_ = storage_[i];\n      return last_match_;\n    }\n  }\n  last_match_ = internal_strdup(str);\n  storage_.push_back(last_match_);\n  return last_match_;\n}\n\nSymbolizer::Symbolizer(IntrusiveList<SymbolizerTool> tools)\n    : module_names_(&mu_), n_modules_(0), modules_fresh_(false), tools_(tools),\n      start_hook_(0), end_hook_(0) {}\n\nSymbolizer::SymbolizerScope::SymbolizerScope(const Symbolizer *sym)\n    : sym_(sym) {\n  if (sym_->start_hook_)\n    sym_->start_hook_();\n}\n\nSymbolizer::SymbolizerScope::~SymbolizerScope() {\n  if (sym_->end_hook_)\n    sym_->end_hook_();\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h",
    "content": "//===-- sanitizer_symbolizer.h ----------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Symbolizer is used by sanitizers to map instruction address to a location in\n// source code at run-time. Symbolizer either uses __sanitizer_symbolize_*\n// defined in the program, or (if they are missing) tries to find and\n// launch \"llvm-symbolizer\" commandline tool in a separate process and\n// communicate with it.\n//\n// Generally we should try to avoid calling system library functions during\n// symbolization (and use their replacements from sanitizer_libc.h instead).\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_SYMBOLIZER_H\n#define SANITIZER_SYMBOLIZER_H\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_mutex.h\"\n\nnamespace __sanitizer {\n\nstruct AddressInfo {\n  // Owns all the string members. Storage for them is\n  // (de)allocated using sanitizer internal allocator.\n  uptr address;\n\n  char *module;\n  uptr module_offset;\n\n  static const uptr kUnknown = ~(uptr)0;\n  char *function;\n  uptr function_offset;\n\n  char *file;\n  int line;\n  int column;\n\n  AddressInfo();\n  // Deletes all strings and resets all fields.\n  void Clear();\n  void FillModuleInfo(const char *mod_name, uptr mod_offset);\n};\n\n// Linked list of symbolized frames (each frame is described by AddressInfo).\nstruct SymbolizedStack {\n  SymbolizedStack *next;\n  AddressInfo info;\n  static SymbolizedStack *New(uptr addr);\n  // Deletes current, and all subsequent frames in the linked list.\n  // The object cannot be accessed after the call to this function.\n  void ClearAll();\n\n private:\n  SymbolizedStack();\n};\n\n// For now, DataInfo is used to describe global variable.\nstruct DataInfo {\n  // Owns all the string members. Storage for them is\n  // (de)allocated using sanitizer internal allocator.\n  char *module;\n  uptr module_offset;\n  char *name;\n  uptr start;\n  uptr size;\n\n  DataInfo();\n  void Clear();\n};\n\nclass SymbolizerTool;\n\nclass Symbolizer final {\n public:\n  /// Initialize and return platform-specific implementation of symbolizer\n  /// (if it wasn't already initialized).\n  static Symbolizer *GetOrInit();\n  // Returns a list of symbolized frames for a given address (containing\n  // all inlined functions, if necessary).\n  SymbolizedStack *SymbolizePC(uptr address);\n  bool SymbolizeData(uptr address, DataInfo *info);\n\n  // The module names Symbolizer returns are stable and unique for every given\n  // module.  It is safe to store and compare them as pointers.\n  bool GetModuleNameAndOffsetForPC(uptr pc, const char **module_name,\n                                   uptr *module_address);\n  const char *GetModuleNameForPc(uptr pc) {\n    const char *module_name = nullptr;\n    uptr unused;\n    if (GetModuleNameAndOffsetForPC(pc, &module_name, &unused))\n      return module_name;\n    return nullptr;\n  }\n\n  // Release internal caches (if any).\n  void Flush();\n  // Attempts to demangle the provided C++ mangled name.\n  const char *Demangle(const char *name);\n  void PrepareForSandboxing();\n\n  // Allow user to install hooks that would be called before/after Symbolizer\n  // does the actual file/line info fetching. Specific sanitizers may need this\n  // to distinguish system library calls made in user code from calls made\n  // during in-process symbolization.\n  typedef void (*StartSymbolizationHook)();\n  typedef void (*EndSymbolizationHook)();\n  // May be called at most once.\n  void AddHooks(StartSymbolizationHook start_hook,\n                EndSymbolizationHook end_hook);\n\n private:\n  // GetModuleNameAndOffsetForPC has to return a string to the caller.\n  // Since the corresponding module might get unloaded later, we should create\n  // our owned copies of the strings that we can safely return.\n  // ModuleNameOwner does not provide any synchronization, thus calls to\n  // its method should be protected by |mu_|.\n  class ModuleNameOwner {\n   public:\n    explicit ModuleNameOwner(BlockingMutex *synchronized_by)\n        : storage_(kInitialCapacity), last_match_(nullptr),\n          mu_(synchronized_by) {}\n    const char *GetOwnedCopy(const char *str);\n\n   private:\n    static const uptr kInitialCapacity = 1000;\n    InternalMmapVector<const char*> storage_;\n    const char *last_match_;\n\n    BlockingMutex *mu_;\n  } module_names_;\n\n  /// Platform-specific function for creating a Symbolizer object.\n  static Symbolizer *PlatformInit();\n\n  bool FindModuleNameAndOffsetForAddress(uptr address, const char **module_name,\n                                         uptr *module_offset);\n  LoadedModule *FindModuleForAddress(uptr address);\n  LoadedModule modules_[kMaxNumberOfModules];\n  uptr n_modules_;\n  // If stale, need to reload the modules before looking up addresses.\n  bool modules_fresh_;\n\n  // Platform-specific default demangler, must not return nullptr.\n  const char *PlatformDemangle(const char *name);\n  void PlatformPrepareForSandboxing();\n\n  static Symbolizer *symbolizer_;\n  static StaticSpinMutex init_mu_;\n\n  // Mutex locked from public methods of |Symbolizer|, so that the internals\n  // (including individual symbolizer tools and platform-specific methods) are\n  // always synchronized.\n  BlockingMutex mu_;\n\n  typedef IntrusiveList<SymbolizerTool>::Iterator Iterator;\n  IntrusiveList<SymbolizerTool> tools_;\n\n  explicit Symbolizer(IntrusiveList<SymbolizerTool> tools);\n\n  static LowLevelAllocator symbolizer_allocator_;\n\n  StartSymbolizationHook start_hook_;\n  EndSymbolizationHook end_hook_;\n  class SymbolizerScope {\n   public:\n    explicit SymbolizerScope(const Symbolizer *sym);\n    ~SymbolizerScope();\n   private:\n    const Symbolizer *sym_;\n  };\n};\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_SYMBOLIZER_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h",
    "content": "//===-- sanitizer_symbolizer_internal.h -------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Header for internal classes and functions to be used by implementations of\n// symbolizers.\n//\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_SYMBOLIZER_INTERNAL_H\n#define SANITIZER_SYMBOLIZER_INTERNAL_H\n\n#include \"sanitizer_symbolizer.h\"\n\nnamespace __sanitizer {\n\n// Parsing helpers, 'str' is searched for delimiter(s) and a string or uptr\n// is extracted. When extracting a string, a newly allocated (using\n// InternalAlloc) and null-terminataed buffer is returned. They return a pointer\n// to the next characted after the found delimiter.\nconst char *ExtractToken(const char *str, const char *delims, char **result);\nconst char *ExtractInt(const char *str, const char *delims, int *result);\nconst char *ExtractUptr(const char *str, const char *delims, uptr *result);\nconst char *ExtractTokenUpToDelimiter(const char *str, const char *delimiter,\n                                      char **result);\n\nconst char *DemangleCXXABI(const char *name);\n\n// SymbolizerTool is an interface that is implemented by individual \"tools\"\n// that can perform symbolication (external llvm-symbolizer, libbacktrace,\n// Windows DbgHelp symbolizer, etc.).\nclass SymbolizerTool {\n public:\n  // The main |Symbolizer| class implements a \"fallback chain\" of symbolizer\n  // tools. In a request to symbolize an address, if one tool returns false,\n  // the next tool in the chain will be tried.\n  SymbolizerTool *next;\n\n  SymbolizerTool() : next(nullptr) { }\n\n  // Can't declare pure virtual functions in sanitizer runtimes:\n  // __cxa_pure_virtual might be unavailable.\n\n  // The |stack| parameter is inout. It is pre-filled with the address,\n  // module base and module offset values and is to be used to construct\n  // other stack frames.\n  virtual bool SymbolizePC(uptr addr, SymbolizedStack *stack) {\n    UNIMPLEMENTED();\n  }\n\n  // The |info| parameter is inout. It is pre-filled with the module base\n  // and module offset values.\n  virtual bool SymbolizeData(uptr addr, DataInfo *info) {\n    UNIMPLEMENTED();\n  }\n\n  virtual void Flush() {}\n\n  // Return nullptr to fallback to the default platform-specific demangler.\n  virtual const char *Demangle(const char *name) {\n    return nullptr;\n  }\n};\n\n// SymbolizerProcess encapsulates communication between the tool and\n// external symbolizer program, running in a different subprocess.\n// SymbolizerProcess may not be used from two threads simultaneously.\nclass SymbolizerProcess {\n public:\n  explicit SymbolizerProcess(const char *path, bool use_forkpty = false);\n  const char *SendCommand(const char *command);\n\n protected:\n  virtual bool ReachedEndOfOutput(const char *buffer, uptr length) const {\n    UNIMPLEMENTED();\n  }\n\n  /// The maximum number of arguments required to invoke a tool process.\n  enum { kArgVMax = 6 };\n\n  /// Fill in an argv array to invoke the child process.\n  virtual void GetArgV(const char *path_to_binary,\n                       const char *(&argv)[kArgVMax]) const {\n    UNIMPLEMENTED();\n  }\n\n  virtual bool ReadFromSymbolizer(char *buffer, uptr max_length);\n\n private:\n  bool Restart();\n  const char *SendCommandImpl(const char *command);\n  bool WriteToSymbolizer(const char *buffer, uptr length);\n  bool StartSymbolizerSubprocess();\n\n  const char *path_;\n  fd_t input_fd_;\n  fd_t output_fd_;\n\n  static const uptr kBufferSize = 16 * 1024;\n  char buffer_[kBufferSize];\n\n  static const uptr kMaxTimesRestarted = 5;\n  static const int kSymbolizerStartupTimeMillis = 10;\n  uptr times_restarted_;\n  bool failed_to_start_;\n  bool reported_invalid_path_;\n  bool use_forkpty_;\n};\n\nclass LLVMSymbolizerProcess;\n\n// This tool invokes llvm-symbolizer in a subprocess. It should be as portable\n// as the llvm-symbolizer tool is.\nclass LLVMSymbolizer : public SymbolizerTool {\n public:\n  explicit LLVMSymbolizer(const char *path, LowLevelAllocator *allocator);\n\n  bool SymbolizePC(uptr addr, SymbolizedStack *stack) override;\n\n  bool SymbolizeData(uptr addr, DataInfo *info) override;\n\n private:\n  const char *SendCommand(bool is_data, const char *module_name,\n                          uptr module_offset);\n\n  LLVMSymbolizerProcess *symbolizer_process_;\n  static const uptr kBufferSize = 16 * 1024;\n  char buffer_[kBufferSize];\n};\n\n// Parses one or more two-line strings in the following format:\n//   <function_name>\n//   <file_name>:<line_number>[:<column_number>]\n// Used by LLVMSymbolizer, Addr2LinePool and InternalSymbolizer, since all of\n// them use the same output format.  Returns true if any useful debug\n// information was found.\nvoid ParseSymbolizePCOutput(const char *str, SymbolizedStack *res);\n\n// Parses a two-line string in the following format:\n//   <symbol_name>\n//   <start_address> <size>\n// Used by LLVMSymbolizer and InternalSymbolizer.\nvoid ParseSymbolizeDataOutput(const char *str, DataInfo *info);\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_SYMBOLIZER_INTERNAL_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc",
    "content": "//===-- sanitizer_symbolizer_libbacktrace.cc ------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n// Libbacktrace implementation of symbolizer parts.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_symbolizer.h\"\n#include \"sanitizer_symbolizer_libbacktrace.h\"\n\n#if SANITIZER_LIBBACKTRACE\n# include \"backtrace-supported.h\"\n# if SANITIZER_POSIX && BACKTRACE_SUPPORTED && !BACKTRACE_USES_MALLOC\n#  include \"backtrace.h\"\n#  if SANITIZER_CP_DEMANGLE\n#   undef ARRAY_SIZE\n#   include \"demangle.h\"\n#  endif\n# else\n#  define SANITIZER_LIBBACKTRACE 0\n# endif\n#endif\n\nnamespace __sanitizer {\n\nstatic char *DemangleAlloc(const char *name, bool always_alloc);\n\n#if SANITIZER_LIBBACKTRACE\n\nnamespace {\n\n# if SANITIZER_CP_DEMANGLE\nstruct CplusV3DemangleData {\n  char *buf;\n  uptr size, allocated;\n};\n\nextern \"C\" {\nstatic void CplusV3DemangleCallback(const char *s, size_t l, void *vdata) {\n  CplusV3DemangleData *data = (CplusV3DemangleData *)vdata;\n  uptr needed = data->size + l + 1;\n  if (needed > data->allocated) {\n    data->allocated *= 2;\n    if (needed > data->allocated)\n      data->allocated = needed;\n    char *buf = (char *)InternalAlloc(data->allocated);\n    if (data->buf) {\n      internal_memcpy(buf, data->buf, data->size);\n      InternalFree(data->buf);\n    }\n    data->buf = buf;\n  }\n  internal_memcpy(data->buf + data->size, s, l);\n  data->buf[data->size + l] = '\\0';\n  data->size += l;\n}\n}  // extern \"C\"\n\nchar *CplusV3Demangle(const char *name) {\n  CplusV3DemangleData data;\n  data.buf = 0;\n  data.size = 0;\n  data.allocated = 0;\n  if (cplus_demangle_v3_callback(name, DMGL_PARAMS | DMGL_ANSI,\n                                 CplusV3DemangleCallback, &data)) {\n    if (data.size + 64 > data.allocated)\n      return data.buf;\n    char *buf = internal_strdup(data.buf);\n    InternalFree(data.buf);\n    return buf;\n  }\n  if (data.buf)\n    InternalFree(data.buf);\n  return 0;\n}\n# endif  // SANITIZER_CP_DEMANGLE\n\nstruct SymbolizeCodeCallbackArg {\n  SymbolizedStack *first;\n  SymbolizedStack *last;\n  uptr frames_symbolized;\n\n  AddressInfo *get_new_frame(uintptr_t addr) {\n    CHECK(last);\n    if (frames_symbolized > 0) {\n      SymbolizedStack *cur = SymbolizedStack::New(addr);\n      AddressInfo *info = &cur->info;\n      info->FillModuleInfo(first->info.module, first->info.module_offset);\n      last->next = cur;\n      last = cur;\n    }\n    CHECK_EQ(addr, first->info.address);\n    CHECK_EQ(addr, last->info.address);\n    return &last->info;\n  }\n};\n\nextern \"C\" {\nstatic int SymbolizeCodePCInfoCallback(void *vdata, uintptr_t addr,\n                                       const char *filename, int lineno,\n                                       const char *function) {\n  SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata;\n  if (function) {\n    AddressInfo *info = cdata->get_new_frame(addr);\n    info->function = DemangleAlloc(function, /*always_alloc*/ true);\n    if (filename)\n      info->file = internal_strdup(filename);\n    info->line = lineno;\n    cdata->frames_symbolized++;\n  }\n  return 0;\n}\n\nstatic void SymbolizeCodeCallback(void *vdata, uintptr_t addr,\n                                  const char *symname, uintptr_t, uintptr_t) {\n  SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata;\n  if (symname) {\n    AddressInfo *info = cdata->get_new_frame(addr);\n    info->function = DemangleAlloc(symname, /*always_alloc*/ true);\n    cdata->frames_symbolized++;\n  }\n}\n\nstatic void SymbolizeDataCallback(void *vdata, uintptr_t, const char *symname,\n                                  uintptr_t symval, uintptr_t symsize) {\n  DataInfo *info = (DataInfo *)vdata;\n  if (symname && symval) {\n    info->name = DemangleAlloc(symname, /*always_alloc*/ true);\n    info->start = symval;\n    info->size = symsize;\n  }\n}\n\nstatic void ErrorCallback(void *, const char *, int) {}\n}  // extern \"C\"\n\n}  // namespace\n\nLibbacktraceSymbolizer *LibbacktraceSymbolizer::get(LowLevelAllocator *alloc) {\n  // State created in backtrace_create_state is leaked.\n  void *state = (void *)(backtrace_create_state(\"/proc/self/exe\", 0,\n                                                ErrorCallback, NULL));\n  if (!state)\n    return 0;\n  return new(*alloc) LibbacktraceSymbolizer(state);\n}\n\nbool LibbacktraceSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {\n  SymbolizeCodeCallbackArg data;\n  data.first = stack;\n  data.last = stack;\n  data.frames_symbolized = 0;\n  backtrace_pcinfo((backtrace_state *)state_, addr, SymbolizeCodePCInfoCallback,\n                   ErrorCallback, &data);\n  if (data.frames_symbolized > 0)\n    return true;\n  backtrace_syminfo((backtrace_state *)state_, addr, SymbolizeCodeCallback,\n                    ErrorCallback, &data);\n  return (data.frames_symbolized > 0);\n}\n\nbool LibbacktraceSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {\n  backtrace_syminfo((backtrace_state *)state_, addr, SymbolizeDataCallback,\n                    ErrorCallback, info);\n  return true;\n}\n\n#else  // SANITIZER_LIBBACKTRACE\n\nLibbacktraceSymbolizer *LibbacktraceSymbolizer::get(LowLevelAllocator *alloc) {\n  return 0;\n}\n\nbool LibbacktraceSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {\n  (void)state_;\n  return false;\n}\n\nbool LibbacktraceSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {\n  return false;\n}\n\n#endif  // SANITIZER_LIBBACKTRACE\n\nstatic char *DemangleAlloc(const char *name, bool always_alloc) {\n#if SANITIZER_LIBBACKTRACE && SANITIZER_CP_DEMANGLE\n  if (char *demangled = CplusV3Demangle(name))\n    return demangled;\n#endif\n  if (always_alloc)\n    return internal_strdup(name);\n  return 0;\n}\n\nconst char *LibbacktraceSymbolizer::Demangle(const char *name) {\n  return DemangleAlloc(name, /*always_alloc*/ false);\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h",
    "content": "//===-- sanitizer_symbolizer_libbacktrace.h ---------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n// Header for libbacktrace symbolizer.\n//===----------------------------------------------------------------------===//\n#ifndef SANITIZER_SYMBOLIZER_LIBBACKTRACE_H\n#define SANITIZER_SYMBOLIZER_LIBBACKTRACE_H\n\n#include \"sanitizer_platform.h\"\n#include \"sanitizer_common.h\"\n#include \"sanitizer_allocator_internal.h\"\n#include \"sanitizer_symbolizer_internal.h\"\n\n#ifndef SANITIZER_LIBBACKTRACE\n# define SANITIZER_LIBBACKTRACE 0\n#endif\n\n#ifndef SANITIZER_CP_DEMANGLE\n# define SANITIZER_CP_DEMANGLE 0\n#endif\n\nnamespace __sanitizer {\n\nclass LibbacktraceSymbolizer : public SymbolizerTool {\n public:\n  static LibbacktraceSymbolizer *get(LowLevelAllocator *alloc);\n\n  bool SymbolizePC(uptr addr, SymbolizedStack *stack) override;\n\n  bool SymbolizeData(uptr addr, DataInfo *info) override;\n\n  // May return NULL if demangling failed.\n  const char *Demangle(const char *name) override;\n\n private:\n  explicit LibbacktraceSymbolizer(void *state) : state_(state) {}\n\n  void *state_;  // Leaked.\n};\n\n}  // namespace __sanitizer\n#endif  // SANITIZER_SYMBOLIZER_LIBBACKTRACE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc",
    "content": "//===-- sanitizer_symbolizer_libcdep.cc -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_allocator_internal.h\"\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_symbolizer_internal.h\"\n\nnamespace __sanitizer {\n\nconst char *ExtractToken(const char *str, const char *delims, char **result) {\n  uptr prefix_len = internal_strcspn(str, delims);\n  *result = (char*)InternalAlloc(prefix_len + 1);\n  internal_memcpy(*result, str, prefix_len);\n  (*result)[prefix_len] = '\\0';\n  const char *prefix_end = str + prefix_len;\n  if (*prefix_end != '\\0') prefix_end++;\n  return prefix_end;\n}\n\nconst char *ExtractInt(const char *str, const char *delims, int *result) {\n  char *buff;\n  const char *ret = ExtractToken(str, delims, &buff);\n  if (buff != 0) {\n    *result = (int)internal_atoll(buff);\n  }\n  InternalFree(buff);\n  return ret;\n}\n\nconst char *ExtractUptr(const char *str, const char *delims, uptr *result) {\n  char *buff;\n  const char *ret = ExtractToken(str, delims, &buff);\n  if (buff != 0) {\n    *result = (uptr)internal_atoll(buff);\n  }\n  InternalFree(buff);\n  return ret;\n}\n\nconst char *ExtractTokenUpToDelimiter(const char *str, const char *delimiter,\n                                      char **result) {\n  const char *found_delimiter = internal_strstr(str, delimiter);\n  uptr prefix_len =\n      found_delimiter ? found_delimiter - str : internal_strlen(str);\n  *result = (char *)InternalAlloc(prefix_len + 1);\n  internal_memcpy(*result, str, prefix_len);\n  (*result)[prefix_len] = '\\0';\n  const char *prefix_end = str + prefix_len;\n  if (*prefix_end != '\\0') prefix_end += internal_strlen(delimiter);\n  return prefix_end;\n}\n\nSymbolizedStack *Symbolizer::SymbolizePC(uptr addr) {\n  BlockingMutexLock l(&mu_);\n  const char *module_name;\n  uptr module_offset;\n  SymbolizedStack *res = SymbolizedStack::New(addr);\n  if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset))\n    return res;\n  // Always fill data about module name and offset.\n  res->info.FillModuleInfo(module_name, module_offset);\n  for (auto iter = Iterator(&tools_); iter.hasNext();) {\n    auto *tool = iter.next();\n    SymbolizerScope sym_scope(this);\n    if (tool->SymbolizePC(addr, res)) {\n      return res;\n    }\n  }\n  return res;\n}\n\nbool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) {\n  BlockingMutexLock l(&mu_);\n  const char *module_name;\n  uptr module_offset;\n  if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset))\n    return false;\n  info->Clear();\n  info->module = internal_strdup(module_name);\n  info->module_offset = module_offset;\n  for (auto iter = Iterator(&tools_); iter.hasNext();) {\n    auto *tool = iter.next();\n    SymbolizerScope sym_scope(this);\n    if (tool->SymbolizeData(addr, info)) {\n      return true;\n    }\n  }\n  return true;\n}\n\nbool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name,\n                                             uptr *module_address) {\n  BlockingMutexLock l(&mu_);\n  const char *internal_module_name = nullptr;\n  if (!FindModuleNameAndOffsetForAddress(pc, &internal_module_name,\n                                         module_address))\n    return false;\n\n  if (module_name)\n    *module_name = module_names_.GetOwnedCopy(internal_module_name);\n  return true;\n}\n\nvoid Symbolizer::Flush() {\n  BlockingMutexLock l(&mu_);\n  for (auto iter = Iterator(&tools_); iter.hasNext();) {\n    auto *tool = iter.next();\n    SymbolizerScope sym_scope(this);\n    tool->Flush();\n  }\n}\n\nconst char *Symbolizer::Demangle(const char *name) {\n  BlockingMutexLock l(&mu_);\n  for (auto iter = Iterator(&tools_); iter.hasNext();) {\n    auto *tool = iter.next();\n    SymbolizerScope sym_scope(this);\n    if (const char *demangled = tool->Demangle(name))\n      return demangled;\n  }\n  return PlatformDemangle(name);\n}\n\nvoid Symbolizer::PrepareForSandboxing() {\n  BlockingMutexLock l(&mu_);\n  PlatformPrepareForSandboxing();\n}\n\nbool Symbolizer::FindModuleNameAndOffsetForAddress(uptr address,\n                                                   const char **module_name,\n                                                   uptr *module_offset) {\n  LoadedModule *module = FindModuleForAddress(address);\n  if (module == 0)\n    return false;\n  *module_name = module->full_name();\n  *module_offset = address - module->base_address();\n  return true;\n}\n\nLoadedModule *Symbolizer::FindModuleForAddress(uptr address) {\n  bool modules_were_reloaded = false;\n  if (!modules_fresh_) {\n    for (uptr i = 0; i < n_modules_; i++)\n      modules_[i].clear();\n    n_modules_ =\n        GetListOfModules(modules_, kMaxNumberOfModules, /* filter */ nullptr);\n    CHECK_GT(n_modules_, 0);\n    CHECK_LT(n_modules_, kMaxNumberOfModules);\n    modules_fresh_ = true;\n    modules_were_reloaded = true;\n  }\n  for (uptr i = 0; i < n_modules_; i++) {\n    if (modules_[i].containsAddress(address)) {\n      return &modules_[i];\n    }\n  }\n  // Reload the modules and look up again, if we haven't tried it yet.\n  if (!modules_were_reloaded) {\n    // FIXME: set modules_fresh_ from dlopen()/dlclose() interceptors.\n    // It's too aggressive to reload the list of modules each time we fail\n    // to find a module for a given address.\n    modules_fresh_ = false;\n    return FindModuleForAddress(address);\n  }\n  return 0;\n}\n\nSymbolizer *Symbolizer::GetOrInit() {\n  SpinMutexLock l(&init_mu_);\n  if (symbolizer_)\n    return symbolizer_;\n  symbolizer_ = PlatformInit();\n  CHECK(symbolizer_);\n  return symbolizer_;\n}\n\n// For now we assume the following protocol:\n// For each request of the form\n//   <module_name> <module_offset>\n// passed to STDIN, external symbolizer prints to STDOUT response:\n//   <function_name>\n//   <file_name>:<line_number>:<column_number>\n//   <function_name>\n//   <file_name>:<line_number>:<column_number>\n//   ...\n//   <empty line>\nclass LLVMSymbolizerProcess : public SymbolizerProcess {\n public:\n  explicit LLVMSymbolizerProcess(const char *path) : SymbolizerProcess(path) {}\n\n private:\n  bool ReachedEndOfOutput(const char *buffer, uptr length) const override {\n    // Empty line marks the end of llvm-symbolizer output.\n    return length >= 2 && buffer[length - 1] == '\\n' &&\n           buffer[length - 2] == '\\n';\n  }\n\n  void GetArgV(const char *path_to_binary,\n               const char *(&argv)[kArgVMax]) const override {\n#if defined(__x86_64h__)\n    const char* const kSymbolizerArch = \"--default-arch=x86_64h\";\n#elif defined(__x86_64__)\n    const char* const kSymbolizerArch = \"--default-arch=x86_64\";\n#elif defined(__i386__)\n    const char* const kSymbolizerArch = \"--default-arch=i386\";\n#elif defined(__powerpc64__) && defined(__BIG_ENDIAN__)\n    const char* const kSymbolizerArch = \"--default-arch=powerpc64\";\n#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)\n    const char* const kSymbolizerArch = \"--default-arch=powerpc64le\";\n#else\n    const char* const kSymbolizerArch = \"--default-arch=unknown\";\n#endif\n\n    const char *const inline_flag = common_flags()->symbolize_inline_frames\n                                        ? \"--inlining=true\"\n                                        : \"--inlining=false\";\n    int i = 0;\n    argv[i++] = path_to_binary;\n    argv[i++] = inline_flag;\n    argv[i++] = kSymbolizerArch;\n    argv[i++] = nullptr;\n  }\n};\n\nLLVMSymbolizer::LLVMSymbolizer(const char *path, LowLevelAllocator *allocator)\n    : symbolizer_process_(new(*allocator) LLVMSymbolizerProcess(path)) {}\n\n// Parse a <file>:<line>[:<column>] buffer. The file path may contain colons on\n// Windows, so extract tokens from the right hand side first. The column info is\n// also optional.\nstatic const char *ParseFileLineInfo(AddressInfo *info, const char *str) {\n  char *file_line_info = 0;\n  str = ExtractToken(str, \"\\n\", &file_line_info);\n  CHECK(file_line_info);\n  // Parse the last :<int>, which must be there.\n  char *last_colon = internal_strrchr(file_line_info, ':');\n  CHECK(last_colon);\n  int line_or_column = internal_atoll(last_colon + 1);\n  // Truncate the string at the last colon and find the next-to-last colon.\n  *last_colon = '\\0';\n  last_colon = internal_strrchr(file_line_info, ':');\n  if (last_colon && IsDigit(last_colon[1])) {\n    // If the second-to-last colon is followed by a digit, it must be the line\n    // number, and the previous parsed number was a column.\n    info->line = internal_atoll(last_colon + 1);\n    info->column = line_or_column;\n    *last_colon = '\\0';\n  } else {\n    // Otherwise, we have line info but no column info.\n    info->line = line_or_column;\n    info->column = 0;\n  }\n  ExtractToken(file_line_info, \"\", &info->file);\n  InternalFree(file_line_info);\n  return str;\n}\n\n// Parses one or more two-line strings in the following format:\n//   <function_name>\n//   <file_name>:<line_number>[:<column_number>]\n// Used by LLVMSymbolizer, Addr2LinePool and InternalSymbolizer, since all of\n// them use the same output format.\nvoid ParseSymbolizePCOutput(const char *str, SymbolizedStack *res) {\n  bool top_frame = true;\n  SymbolizedStack *last = res;\n  while (true) {\n    char *function_name = 0;\n    str = ExtractToken(str, \"\\n\", &function_name);\n    CHECK(function_name);\n    if (function_name[0] == '\\0') {\n      // There are no more frames.\n      InternalFree(function_name);\n      break;\n    }\n    SymbolizedStack *cur;\n    if (top_frame) {\n      cur = res;\n      top_frame = false;\n    } else {\n      cur = SymbolizedStack::New(res->info.address);\n      cur->info.FillModuleInfo(res->info.module, res->info.module_offset);\n      last->next = cur;\n      last = cur;\n    }\n\n    AddressInfo *info = &cur->info;\n    info->function = function_name;\n    str = ParseFileLineInfo(info, str);\n\n    // Functions and filenames can be \"??\", in which case we write 0\n    // to address info to mark that names are unknown.\n    if (0 == internal_strcmp(info->function, \"??\")) {\n      InternalFree(info->function);\n      info->function = 0;\n    }\n    if (0 == internal_strcmp(info->file, \"??\")) {\n      InternalFree(info->file);\n      info->file = 0;\n    }\n  }\n}\n\n// Parses a two-line string in the following format:\n//   <symbol_name>\n//   <start_address> <size>\n// Used by LLVMSymbolizer and InternalSymbolizer.\nvoid ParseSymbolizeDataOutput(const char *str, DataInfo *info) {\n  str = ExtractToken(str, \"\\n\", &info->name);\n  str = ExtractUptr(str, \" \", &info->start);\n  str = ExtractUptr(str, \"\\n\", &info->size);\n}\n\nbool LLVMSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {\n  if (const char *buf = SendCommand(/*is_data*/ false, stack->info.module,\n                                    stack->info.module_offset)) {\n    ParseSymbolizePCOutput(buf, stack);\n    return true;\n  }\n  return false;\n}\n\nbool LLVMSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {\n  if (const char *buf =\n          SendCommand(/*is_data*/ true, info->module, info->module_offset)) {\n    ParseSymbolizeDataOutput(buf, info);\n    info->start += (addr - info->module_offset); // Add the base address.\n    return true;\n  }\n  return false;\n}\n\nconst char *LLVMSymbolizer::SendCommand(bool is_data, const char *module_name,\n                                        uptr module_offset) {\n  CHECK(module_name);\n  internal_snprintf(buffer_, kBufferSize, \"%s\\\"%s\\\" 0x%zx\\n\",\n                    is_data ? \"DATA \" : \"\", module_name, module_offset);\n  return symbolizer_process_->SendCommand(buffer_);\n}\n\nSymbolizerProcess::SymbolizerProcess(const char *path, bool use_forkpty)\n    : path_(path),\n      input_fd_(kInvalidFd),\n      output_fd_(kInvalidFd),\n      times_restarted_(0),\n      failed_to_start_(false),\n      reported_invalid_path_(false),\n      use_forkpty_(use_forkpty) {\n  CHECK(path_);\n  CHECK_NE(path_[0], '\\0');\n}\n\nconst char *SymbolizerProcess::SendCommand(const char *command) {\n  for (; times_restarted_ < kMaxTimesRestarted; times_restarted_++) {\n    // Start or restart symbolizer if we failed to send command to it.\n    if (const char *res = SendCommandImpl(command))\n      return res;\n    Restart();\n  }\n  if (!failed_to_start_) {\n    Report(\"WARNING: Failed to use and restart external symbolizer!\\n\");\n    failed_to_start_ = true;\n  }\n  return 0;\n}\n\nconst char *SymbolizerProcess::SendCommandImpl(const char *command) {\n  if (input_fd_ == kInvalidFd || output_fd_ == kInvalidFd)\n      return 0;\n  if (!WriteToSymbolizer(command, internal_strlen(command)))\n      return 0;\n  if (!ReadFromSymbolizer(buffer_, kBufferSize))\n      return 0;\n  return buffer_;\n}\n\nbool SymbolizerProcess::Restart() {\n  if (input_fd_ != kInvalidFd)\n    CloseFile(input_fd_);\n  if (output_fd_ != kInvalidFd)\n    CloseFile(output_fd_);\n  return StartSymbolizerSubprocess();\n}\n\nbool SymbolizerProcess::ReadFromSymbolizer(char *buffer, uptr max_length) {\n  if (max_length == 0)\n    return true;\n  uptr read_len = 0;\n  while (true) {\n    uptr just_read = 0;\n    bool success = ReadFromFile(input_fd_, buffer + read_len,\n                                max_length - read_len - 1, &just_read);\n    // We can't read 0 bytes, as we don't expect external symbolizer to close\n    // its stdout.\n    if (!success || just_read == 0) {\n      Report(\"WARNING: Can't read from symbolizer at fd %d\\n\", input_fd_);\n      return false;\n    }\n    read_len += just_read;\n    if (ReachedEndOfOutput(buffer, read_len))\n      break;\n  }\n  buffer[read_len] = '\\0';\n  return true;\n}\n\nbool SymbolizerProcess::WriteToSymbolizer(const char *buffer, uptr length) {\n  if (length == 0)\n    return true;\n  uptr write_len = 0;\n  bool success = WriteToFile(output_fd_, buffer, length, &write_len);\n  if (!success || write_len != length) {\n    Report(\"WARNING: Can't write to symbolizer at fd %d\\n\", output_fd_);\n    return false;\n  }\n  return true;\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cc",
    "content": "//===-- sanitizer_symbolizer_mac.cc ---------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between various sanitizers' runtime libraries.\n//\n// Implementation of Mac-specific \"atos\" symbolizer.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n#if SANITIZER_MAC\n\n#include \"sanitizer_allocator_internal.h\"\n#include \"sanitizer_mac.h\"\n#include \"sanitizer_symbolizer_mac.h\"\n\nnamespace __sanitizer {\n\n#include <dlfcn.h>\n#include <errno.h>\n#include <stdlib.h>\n#include <sys/wait.h>\n#include <unistd.h>\n#include <util.h>\n\nbool DlAddrSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {\n  Dl_info info;\n  int result = dladdr((const void *)addr, &info);\n  if (!result) return false;\n  const char *demangled = DemangleCXXABI(info.dli_sname);\n  stack->info.function = demangled ? internal_strdup(demangled) : nullptr;\n  return true;\n}\n\nbool DlAddrSymbolizer::SymbolizeData(uptr addr, DataInfo *datainfo) {\n  Dl_info info;\n  int result = dladdr((const void *)addr, &info);\n  if (!result) return false;\n  const char *demangled = DemangleCXXABI(info.dli_sname);\n  datainfo->name = internal_strdup(demangled);\n  datainfo->start = (uptr)info.dli_saddr;\n  return true;\n}\n\nclass AtosSymbolizerProcess : public SymbolizerProcess {\n public:\n  explicit AtosSymbolizerProcess(const char *path, pid_t parent_pid)\n      : SymbolizerProcess(path, /*use_forkpty*/ true) {\n    // Put the string command line argument in the object so that it outlives\n    // the call to GetArgV.\n    internal_snprintf(pid_str_, sizeof(pid_str_), \"%d\", parent_pid);\n  }\n\n private:\n  bool ReachedEndOfOutput(const char *buffer, uptr length) const override {\n    return (length >= 1 && buffer[length - 1] == '\\n');\n  }\n\n  void GetArgV(const char *path_to_binary,\n               const char *(&argv)[kArgVMax]) const override {\n    int i = 0;\n    argv[i++] = path_to_binary;\n    argv[i++] = \"-p\";\n    argv[i++] = &pid_str_[0];\n    if (GetMacosVersion() == MACOS_VERSION_MAVERICKS) {\n      // On Mavericks atos prints a deprecation warning which we suppress by\n      // passing -d. The warning isn't present on other OSX versions, even the\n      // newer ones.\n      argv[i++] = \"-d\";\n    }\n    argv[i++] = nullptr;\n  }\n\n  char pid_str_[16];\n};\n\nstatic const char *kAtosErrorMessages[] = {\n  \"atos cannot examine process\",\n  \"unable to get permission to examine process\",\n  \"An admin user name and password is required\",\n  \"could not load inserted library\",\n  \"architecture mismatch between analysis process\",\n};\n\nstatic bool IsAtosErrorMessage(const char *str) {\n  for (uptr i = 0; i < ARRAY_SIZE(kAtosErrorMessages); i++) {\n    if (internal_strstr(str, kAtosErrorMessages[i])) {\n      return true;\n    }\n  }\n  return false;\n}\n\nstatic bool ParseCommandOutput(const char *str, uptr addr, char **out_name,\n                               char **out_module, char **out_file, uptr *line,\n                               uptr *start_address) {\n  // Trim ending newlines.\n  char *trim;\n  ExtractTokenUpToDelimiter(str, \"\\n\", &trim);\n\n  // The line from `atos` is in one of these formats:\n  //   myfunction (in library.dylib) (sourcefile.c:17)\n  //   myfunction (in library.dylib) + 0x1fe\n  //   myfunction (in library.dylib) + 15\n  //   0xdeadbeef (in library.dylib) + 0x1fe\n  //   0xdeadbeef (in library.dylib) + 15\n  //   0xdeadbeef (in library.dylib)\n  //   0xdeadbeef\n\n  if (IsAtosErrorMessage(trim)) {\n    Report(\"atos returned an error: %s\\n\", trim);\n    InternalFree(trim);\n    return false;\n  }\n\n  const char *rest = trim;\n  char *symbol_name;\n  rest = ExtractTokenUpToDelimiter(rest, \" (in \", &symbol_name);\n  if (rest[0] == '\\0') {\n    InternalFree(symbol_name);\n    InternalFree(trim);\n    return false;\n  }\n\n  if (internal_strncmp(symbol_name, \"0x\", 2) != 0)\n    *out_name = symbol_name;\n  else\n    InternalFree(symbol_name);\n  rest = ExtractTokenUpToDelimiter(rest, \") \", out_module);\n\n  if (rest[0] == '(') {\n    if (out_file) {\n      rest++;\n      rest = ExtractTokenUpToDelimiter(rest, \":\", out_file);\n      char *extracted_line_number;\n      rest = ExtractTokenUpToDelimiter(rest, \")\", &extracted_line_number);\n      if (line) *line = (uptr)internal_atoll(extracted_line_number);\n      InternalFree(extracted_line_number);\n    }\n  } else if (rest[0] == '+') {\n    rest += 2;\n    uptr offset = internal_atoll(rest);\n    if (start_address) *start_address = addr - offset;\n  }\n\n  InternalFree(trim);\n  return true;\n}\n\nAtosSymbolizer::AtosSymbolizer(const char *path, LowLevelAllocator *allocator)\n    : process_(new(*allocator) AtosSymbolizerProcess(path, getpid())) {}\n\nbool AtosSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {\n  if (!process_) return false;\n  char command[32];\n  internal_snprintf(command, sizeof(command), \"0x%zx\\n\", addr);\n  const char *buf = process_->SendCommand(command);\n  if (!buf) return false;\n  uptr line;\n  if (!ParseCommandOutput(buf, addr, &stack->info.function, &stack->info.module,\n                          &stack->info.file, &line, nullptr)) {\n    process_ = nullptr;\n    return false;\n  }\n  stack->info.line = (int)line;\n  return true;\n}\n\nbool AtosSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {\n  if (!process_) return false;\n  char command[32];\n  internal_snprintf(command, sizeof(command), \"0x%zx\\n\", addr);\n  const char *buf = process_->SendCommand(command);\n  if (!buf) return false;\n  if (!ParseCommandOutput(buf, addr, &info->name, &info->module, nullptr,\n                          nullptr, &info->start)) {\n    process_ = nullptr;\n    return false;\n  }\n  return true;\n}\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_MAC\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.h",
    "content": "//===-- sanitizer_symbolizer_mac.h ------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between various sanitizers' runtime libraries.\n//\n// Header for Mac-specific \"atos\" symbolizer.\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_SYMBOLIZER_MAC_H\n#define SANITIZER_SYMBOLIZER_MAC_H\n\n#include \"sanitizer_platform.h\"\n#if SANITIZER_MAC\n\n#include \"sanitizer_symbolizer_internal.h\"\n\nnamespace __sanitizer {\n\nclass DlAddrSymbolizer : public SymbolizerTool {\n public:\n  bool SymbolizePC(uptr addr, SymbolizedStack *stack) override;\n  bool SymbolizeData(uptr addr, DataInfo *info) override;\n};\n\nclass AtosSymbolizerProcess;\n\nclass AtosSymbolizer : public SymbolizerTool {\n public:\n  explicit AtosSymbolizer(const char *path, LowLevelAllocator *allocator);\n\n  bool SymbolizePC(uptr addr, SymbolizedStack *stack) override;\n  bool SymbolizeData(uptr addr, DataInfo *info) override;\n\n private:\n  AtosSymbolizerProcess *process_;\n};\n\n} // namespace __sanitizer\n\n#endif  // SANITIZER_MAC\n\n#endif // SANITIZER_SYMBOLIZER_MAC_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc",
    "content": "//===-- sanitizer_symbolizer_posix_libcdep.cc -----------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n// POSIX-specific implementation of symbolizer parts.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n#if SANITIZER_POSIX\n#include \"sanitizer_allocator_internal.h\"\n#include \"sanitizer_common.h\"\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_internal_defs.h\"\n#include \"sanitizer_linux.h\"\n#include \"sanitizer_placement_new.h\"\n#include \"sanitizer_posix.h\"\n#include \"sanitizer_procmaps.h\"\n#include \"sanitizer_symbolizer_internal.h\"\n#include \"sanitizer_symbolizer_libbacktrace.h\"\n#include \"sanitizer_symbolizer_mac.h\"\n\n#include <errno.h>\n#include <stdlib.h>\n#include <sys/wait.h>\n#include <unistd.h>\n\n#if SANITIZER_MAC\n#include <util.h>  // for forkpty()\n#endif  // SANITIZER_MAC\n\n// C++ demangling function, as required by Itanium C++ ABI. This is weak,\n// because we do not require a C++ ABI library to be linked to a program\n// using sanitizers; if it's not present, we'll just use the mangled name.\nnamespace __cxxabiv1 {\n  extern \"C\" SANITIZER_WEAK_ATTRIBUTE\n  char *__cxa_demangle(const char *mangled, char *buffer,\n                                  size_t *length, int *status);\n}\n\nnamespace __sanitizer {\n\n// Attempts to demangle the name via __cxa_demangle from __cxxabiv1.\nconst char *DemangleCXXABI(const char *name) {\n  // FIXME: __cxa_demangle aggressively insists on allocating memory.\n  // There's not much we can do about that, short of providing our\n  // own demangler (libc++abi's implementation could be adapted so that\n  // it does not allocate). For now, we just call it anyway, and we leak\n  // the returned value.\n  if (__cxxabiv1::__cxa_demangle)\n    if (const char *demangled_name =\n          __cxxabiv1::__cxa_demangle(name, 0, 0, 0))\n      return demangled_name;\n\n  return name;\n}\n\nbool SymbolizerProcess::StartSymbolizerSubprocess() {\n  if (!FileExists(path_)) {\n    if (!reported_invalid_path_) {\n      Report(\"WARNING: invalid path to external symbolizer!\\n\");\n      reported_invalid_path_ = true;\n    }\n    return false;\n  }\n\n  int pid;\n  if (use_forkpty_) {\n#if SANITIZER_MAC\n    fd_t fd = kInvalidFd;\n    // Use forkpty to disable buffering in the new terminal.\n    pid = internal_forkpty(&fd);\n    if (pid == -1) {\n      // forkpty() failed.\n      Report(\"WARNING: failed to fork external symbolizer (errno: %d)\\n\",\n             errno);\n      return false;\n    } else if (pid == 0) {\n      // Child subprocess.\n      const char *argv[kArgVMax];\n      GetArgV(path_, argv);\n      execv(path_, const_cast<char **>(&argv[0]));\n      internal__exit(1);\n    }\n\n    // Continue execution in parent process.\n    input_fd_ = output_fd_ = fd;\n\n    // Disable echo in the new terminal, disable CR.\n    struct termios termflags;\n    tcgetattr(fd, &termflags);\n    termflags.c_oflag &= ~ONLCR;\n    termflags.c_lflag &= ~ECHO;\n    tcsetattr(fd, TCSANOW, &termflags);\n#else  // SANITIZER_MAC\n    UNIMPLEMENTED();\n#endif  // SANITIZER_MAC\n  } else {\n    int *infd = NULL;\n    int *outfd = NULL;\n    // The client program may close its stdin and/or stdout and/or stderr\n    // thus allowing socketpair to reuse file descriptors 0, 1 or 2.\n    // In this case the communication between the forked processes may be\n    // broken if either the parent or the child tries to close or duplicate\n    // these descriptors. The loop below produces two pairs of file\n    // descriptors, each greater than 2 (stderr).\n    int sock_pair[5][2];\n    for (int i = 0; i < 5; i++) {\n      if (pipe(sock_pair[i]) == -1) {\n        for (int j = 0; j < i; j++) {\n          internal_close(sock_pair[j][0]);\n          internal_close(sock_pair[j][1]);\n        }\n        Report(\"WARNING: Can't create a socket pair to start \"\n               \"external symbolizer (errno: %d)\\n\", errno);\n        return false;\n      } else if (sock_pair[i][0] > 2 && sock_pair[i][1] > 2) {\n        if (infd == NULL) {\n          infd = sock_pair[i];\n        } else {\n          outfd = sock_pair[i];\n          for (int j = 0; j < i; j++) {\n            if (sock_pair[j] == infd) continue;\n            internal_close(sock_pair[j][0]);\n            internal_close(sock_pair[j][1]);\n          }\n          break;\n        }\n      }\n    }\n    CHECK(infd);\n    CHECK(outfd);\n\n    // Real fork() may call user callbacks registered with pthread_atfork().\n    pid = internal_fork();\n    if (pid == -1) {\n      // Fork() failed.\n      internal_close(infd[0]);\n      internal_close(infd[1]);\n      internal_close(outfd[0]);\n      internal_close(outfd[1]);\n      Report(\"WARNING: failed to fork external symbolizer \"\n             \" (errno: %d)\\n\", errno);\n      return false;\n    } else if (pid == 0) {\n      // Child subprocess.\n      internal_close(STDOUT_FILENO);\n      internal_close(STDIN_FILENO);\n      internal_dup2(outfd[0], STDIN_FILENO);\n      internal_dup2(infd[1], STDOUT_FILENO);\n      internal_close(outfd[0]);\n      internal_close(outfd[1]);\n      internal_close(infd[0]);\n      internal_close(infd[1]);\n      for (int fd = sysconf(_SC_OPEN_MAX); fd > 2; fd--)\n        internal_close(fd);\n      const char *argv[kArgVMax];\n      GetArgV(path_, argv);\n      execv(path_, const_cast<char **>(&argv[0]));\n      internal__exit(1);\n    }\n\n    // Continue execution in parent process.\n    internal_close(outfd[0]);\n    internal_close(infd[1]);\n    input_fd_ = infd[0];\n    output_fd_ = outfd[1];\n  }\n\n  // Check that symbolizer subprocess started successfully.\n  int pid_status;\n  SleepForMillis(kSymbolizerStartupTimeMillis);\n  int exited_pid = waitpid(pid, &pid_status, WNOHANG);\n  if (exited_pid != 0) {\n    // Either waitpid failed, or child has already exited.\n    Report(\"WARNING: external symbolizer didn't start up correctly!\\n\");\n    return false;\n  }\n\n  return true;\n}\n\nclass Addr2LineProcess : public SymbolizerProcess {\n public:\n  Addr2LineProcess(const char *path, const char *module_name)\n      : SymbolizerProcess(path), module_name_(internal_strdup(module_name)) {}\n\n  const char *module_name() const { return module_name_; }\n\n private:\n  void GetArgV(const char *path_to_binary,\n               const char *(&argv)[kArgVMax]) const override {\n    int i = 0;\n    argv[i++] = path_to_binary;\n    argv[i++] = \"-iCfe\";\n    argv[i++] = module_name_;\n    argv[i++] = nullptr;\n  }\n\n  bool ReachedEndOfOutput(const char *buffer, uptr length) const override;\n\n  bool ReadFromSymbolizer(char *buffer, uptr max_length) override {\n    if (!SymbolizerProcess::ReadFromSymbolizer(buffer, max_length))\n      return false;\n    // We should cut out output_terminator_ at the end of given buffer,\n    // appended by addr2line to mark the end of its meaningful output.\n    // We cannot scan buffer from it's beginning, because it is legal for it\n    // to start with output_terminator_ in case given offset is invalid. So,\n    // scanning from second character.\n    char *garbage = internal_strstr(buffer + 1, output_terminator_);\n    // This should never be NULL since buffer must end up with\n    // output_terminator_.\n    CHECK(garbage);\n    // Trim the buffer.\n    garbage[0] = '\\0';\n    return true;\n  }\n\n  const char *module_name_;  // Owned, leaked.\n  static const char output_terminator_[];\n};\n\nconst char Addr2LineProcess::output_terminator_[] = \"??\\n??:0\\n\";\n\nbool Addr2LineProcess::ReachedEndOfOutput(const char *buffer,\n                                          uptr length) const {\n  const size_t kTerminatorLen = sizeof(output_terminator_) - 1;\n  // Skip, if we read just kTerminatorLen bytes, because Addr2Line output\n  // should consist at least of two pairs of lines:\n  // 1. First one, corresponding to given offset to be symbolized\n  // (may be equal to output_terminator_, if offset is not valid).\n  // 2. Second one for output_terminator_, itself to mark the end of output.\n  if (length <= kTerminatorLen) return false;\n  // Addr2Line output should end up with output_terminator_.\n  return !internal_memcmp(buffer + length - kTerminatorLen,\n                          output_terminator_, kTerminatorLen);\n}\n\nclass Addr2LinePool : public SymbolizerTool {\n public:\n  explicit Addr2LinePool(const char *addr2line_path,\n                         LowLevelAllocator *allocator)\n      : addr2line_path_(addr2line_path), allocator_(allocator),\n        addr2line_pool_(16) {}\n\n  bool SymbolizePC(uptr addr, SymbolizedStack *stack) override {\n    if (const char *buf =\n            SendCommand(stack->info.module, stack->info.module_offset)) {\n      ParseSymbolizePCOutput(buf, stack);\n      return true;\n    }\n    return false;\n  }\n\n  bool SymbolizeData(uptr addr, DataInfo *info) override {\n    return false;\n  }\n\n private:\n  const char *SendCommand(const char *module_name, uptr module_offset) {\n    Addr2LineProcess *addr2line = 0;\n    for (uptr i = 0; i < addr2line_pool_.size(); ++i) {\n      if (0 ==\n          internal_strcmp(module_name, addr2line_pool_[i]->module_name())) {\n        addr2line = addr2line_pool_[i];\n        break;\n      }\n    }\n    if (!addr2line) {\n      addr2line =\n          new(*allocator_) Addr2LineProcess(addr2line_path_, module_name);\n      addr2line_pool_.push_back(addr2line);\n    }\n    CHECK_EQ(0, internal_strcmp(module_name, addr2line->module_name()));\n    char buffer[kBufferSize];\n    internal_snprintf(buffer, kBufferSize, \"0x%zx\\n0x%zx\\n\",\n                      module_offset, dummy_address_);\n    return addr2line->SendCommand(buffer);\n  }\n\n  static const uptr kBufferSize = 64;\n  const char *addr2line_path_;\n  LowLevelAllocator *allocator_;\n  InternalMmapVector<Addr2LineProcess*> addr2line_pool_;\n  static const uptr dummy_address_ =\n      FIRST_32_SECOND_64(UINT32_MAX, UINT64_MAX);\n};\n\n#if SANITIZER_SUPPORTS_WEAK_HOOKS\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nbool __sanitizer_symbolize_code(const char *ModuleName, u64 ModuleOffset,\n                                char *Buffer, int MaxLength);\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nbool __sanitizer_symbolize_data(const char *ModuleName, u64 ModuleOffset,\n                                char *Buffer, int MaxLength);\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nvoid __sanitizer_symbolize_flush();\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nint __sanitizer_symbolize_demangle(const char *Name, char *Buffer,\n                                   int MaxLength);\n}  // extern \"C\"\n\nclass InternalSymbolizer : public SymbolizerTool {\n public:\n  static InternalSymbolizer *get(LowLevelAllocator *alloc) {\n    if (__sanitizer_symbolize_code != 0 &&\n        __sanitizer_symbolize_data != 0) {\n      return new(*alloc) InternalSymbolizer();\n    }\n    return 0;\n  }\n\n  bool SymbolizePC(uptr addr, SymbolizedStack *stack) override {\n    bool result = __sanitizer_symbolize_code(\n        stack->info.module, stack->info.module_offset, buffer_, kBufferSize);\n    if (result) ParseSymbolizePCOutput(buffer_, stack);\n    return result;\n  }\n\n  bool SymbolizeData(uptr addr, DataInfo *info) override {\n    bool result = __sanitizer_symbolize_data(info->module, info->module_offset,\n                                             buffer_, kBufferSize);\n    if (result) {\n      ParseSymbolizeDataOutput(buffer_, info);\n      info->start += (addr - info->module_offset);  // Add the base address.\n    }\n    return result;\n  }\n\n  void Flush() override {\n    if (__sanitizer_symbolize_flush)\n      __sanitizer_symbolize_flush();\n  }\n\n  const char *Demangle(const char *name) override {\n    if (__sanitizer_symbolize_demangle) {\n      for (uptr res_length = 1024;\n           res_length <= InternalSizeClassMap::kMaxSize;) {\n        char *res_buff = static_cast<char*>(InternalAlloc(res_length));\n        uptr req_length =\n            __sanitizer_symbolize_demangle(name, res_buff, res_length);\n        if (req_length > res_length) {\n          res_length = req_length + 1;\n          InternalFree(res_buff);\n          continue;\n        }\n        return res_buff;\n      }\n    }\n    return name;\n  }\n\n private:\n  InternalSymbolizer() { }\n\n  static const int kBufferSize = 16 * 1024;\n  static const int kMaxDemangledNameSize = 1024;\n  char buffer_[kBufferSize];\n};\n#else  // SANITIZER_SUPPORTS_WEAK_HOOKS\n\nclass InternalSymbolizer : public SymbolizerTool {\n public:\n  static InternalSymbolizer *get(LowLevelAllocator *alloc) { return 0; }\n};\n\n#endif  // SANITIZER_SUPPORTS_WEAK_HOOKS\n\nconst char *Symbolizer::PlatformDemangle(const char *name) {\n  return DemangleCXXABI(name);\n}\n\nvoid Symbolizer::PlatformPrepareForSandboxing() {}\n\nstatic SymbolizerTool *ChooseExternalSymbolizer(LowLevelAllocator *allocator) {\n  const char *path = common_flags()->external_symbolizer_path;\n  const char *binary_name = path ? StripModuleName(path) : \"\";\n  if (path && path[0] == '\\0') {\n    VReport(2, \"External symbolizer is explicitly disabled.\\n\");\n    return nullptr;\n  } else if (!internal_strcmp(binary_name, \"llvm-symbolizer\")) {\n    VReport(2, \"Using llvm-symbolizer at user-specified path: %s\\n\", path);\n    return new(*allocator) LLVMSymbolizer(path, allocator);\n  } else if (!internal_strcmp(binary_name, \"atos\")) {\n#if SANITIZER_MAC\n    VReport(2, \"Using atos at user-specified path: %s\\n\", path);\n    return new(*allocator) AtosSymbolizer(path, allocator);\n#else  // SANITIZER_MAC\n    Report(\"ERROR: Using `atos` is only supported on Darwin.\\n\");\n    Die();\n#endif  // SANITIZER_MAC\n  } else if (!internal_strcmp(binary_name, \"addr2line\")) {\n    VReport(2, \"Using addr2line at user-specified path: %s\\n\", path);\n    return new(*allocator) Addr2LinePool(path, allocator);\n  } else if (path) {\n    Report(\"ERROR: External symbolizer path is set to '%s' which isn't \"\n           \"a known symbolizer. Please set the path to the llvm-symbolizer \"\n           \"binary or other known tool.\\n\", path);\n    Die();\n  }\n\n  // Otherwise symbolizer program is unknown, let's search $PATH\n  CHECK(path == nullptr);\n  if (const char *found_path = FindPathToBinary(\"llvm-symbolizer\")) {\n    VReport(2, \"Using llvm-symbolizer found at: %s\\n\", found_path);\n    return new(*allocator) LLVMSymbolizer(found_path, allocator);\n  }\n#if SANITIZER_MAC\n  if (const char *found_path = FindPathToBinary(\"atos\")) {\n    VReport(2, \"Using atos found at: %s\\n\", found_path);\n    return new(*allocator) AtosSymbolizer(found_path, allocator);\n  }\n#endif  // SANITIZER_MAC\n  if (common_flags()->allow_addr2line) {\n    if (const char *found_path = FindPathToBinary(\"addr2line\")) {\n      VReport(2, \"Using addr2line found at: %s\\n\", found_path);\n      return new(*allocator) Addr2LinePool(found_path, allocator);\n    }\n  }\n  return nullptr;\n}\n\nstatic void ChooseSymbolizerTools(IntrusiveList<SymbolizerTool> *list,\n                                  LowLevelAllocator *allocator) {\n  if (!common_flags()->symbolize) {\n    VReport(2, \"Symbolizer is disabled.\\n\");\n    return;\n  }\n  if (SymbolizerTool *tool = InternalSymbolizer::get(allocator)) {\n    VReport(2, \"Using internal symbolizer.\\n\");\n    list->push_back(tool);\n    return;\n  }\n  if (SymbolizerTool *tool = LibbacktraceSymbolizer::get(allocator)) {\n    VReport(2, \"Using libbacktrace symbolizer.\\n\");\n    list->push_back(tool);\n    return;\n  }\n\n  if (SymbolizerTool *tool = ChooseExternalSymbolizer(allocator)) {\n    list->push_back(tool);\n  }\n\n#if SANITIZER_MAC\n  VReport(2, \"Using dladdr symbolizer.\\n\");\n  list->push_back(new(*allocator) DlAddrSymbolizer());\n#endif  // SANITIZER_MAC\n}\n\nSymbolizer *Symbolizer::PlatformInit() {\n  IntrusiveList<SymbolizerTool> list;\n  list.clear();\n  ChooseSymbolizerTools(&list, &symbolizer_allocator_);\n  return new(symbolizer_allocator_) Symbolizer(list);\n}\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_POSIX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_win.cc",
    "content": "//===-- sanitizer_symbolizer_win.cc ---------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries.\n// Windows-specific implementation of symbolizer parts.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n#if SANITIZER_WINDOWS\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n#include <dbghelp.h>\n#pragma comment(lib, \"dbghelp.lib\")\n\n#include \"sanitizer_symbolizer_internal.h\"\n\nnamespace __sanitizer {\n\nnamespace {\n\nclass WinSymbolizerTool : public SymbolizerTool {\n public:\n  bool SymbolizePC(uptr addr, SymbolizedStack *stack) override;\n  bool SymbolizeData(uptr addr, DataInfo *info) override {\n    return false;\n  }\n  const char *Demangle(const char *name) override;\n};\n\nbool is_dbghelp_initialized = false;\n\nbool TrySymInitialize() {\n  SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES);\n  return SymInitialize(GetCurrentProcess(), 0, TRUE);\n  // FIXME: We don't call SymCleanup() on exit yet - should we?\n}\n\n// Initializes DbgHelp library, if it's not yet initialized. Calls to this\n// function should be synchronized with respect to other calls to DbgHelp API\n// (e.g. from WinSymbolizerTool).\nvoid InitializeDbgHelpIfNeeded() {\n  if (is_dbghelp_initialized)\n    return;\n  if (!TrySymInitialize()) {\n    // OK, maybe the client app has called SymInitialize already.\n    // That's a bit unfortunate for us as all the DbgHelp functions are\n    // single-threaded and we can't coordinate with the app.\n    // FIXME: Can we stop the other threads at this point?\n    // Anyways, we have to reconfigure stuff to make sure that SymInitialize\n    // has all the appropriate options set.\n    // Cross our fingers and reinitialize DbgHelp.\n    Report(\"*** WARNING: Failed to initialize DbgHelp!              ***\\n\");\n    Report(\"*** Most likely this means that the app is already      ***\\n\");\n    Report(\"*** using DbgHelp, possibly with incompatible flags.    ***\\n\");\n    Report(\"*** Due to technical reasons, symbolization might crash ***\\n\");\n    Report(\"*** or produce wrong results.                           ***\\n\");\n    SymCleanup(GetCurrentProcess());\n    TrySymInitialize();\n  }\n  is_dbghelp_initialized = true;\n\n  // When an executable is run from a location different from the one where it\n  // was originally built, we may not see the nearby PDB files.\n  // To work around this, let's append the directory of the main module\n  // to the symbol search path.  All the failures below are not fatal.\n  const size_t kSymPathSize = 2048;\n  static wchar_t path_buffer[kSymPathSize + 1 + MAX_PATH];\n  if (!SymGetSearchPathW(GetCurrentProcess(), path_buffer, kSymPathSize)) {\n    Report(\"*** WARNING: Failed to SymGetSearchPathW ***\\n\");\n    return;\n  }\n  size_t sz = wcslen(path_buffer);\n  if (sz) {\n    CHECK_EQ(0, wcscat_s(path_buffer, L\";\"));\n    sz++;\n  }\n  DWORD res = GetModuleFileNameW(NULL, path_buffer + sz, MAX_PATH);\n  if (res == 0 || res == MAX_PATH) {\n    Report(\"*** WARNING: Failed to getting the EXE directory ***\\n\");\n    return;\n  }\n  // Write the zero character in place of the last backslash to get the\n  // directory of the main module at the end of path_buffer.\n  wchar_t *last_bslash = wcsrchr(path_buffer + sz, L'\\\\');\n  CHECK_NE(last_bslash, 0);\n  *last_bslash = L'\\0';\n  if (!SymSetSearchPathW(GetCurrentProcess(), path_buffer)) {\n    Report(\"*** WARNING: Failed to SymSetSearchPathW\\n\");\n    return;\n  }\n}\n\n}  // namespace\n\nbool WinSymbolizerTool::SymbolizePC(uptr addr, SymbolizedStack *frame) {\n  InitializeDbgHelpIfNeeded();\n\n  // See http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx\n  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR)];\n  PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;\n  symbol->SizeOfStruct = sizeof(SYMBOL_INFO);\n  symbol->MaxNameLen = MAX_SYM_NAME;\n  DWORD64 offset = 0;\n  BOOL got_objname = SymFromAddr(GetCurrentProcess(),\n                                 (DWORD64)addr, &offset, symbol);\n  if (!got_objname)\n    return false;\n\n  DWORD unused;\n  IMAGEHLP_LINE64 line_info;\n  line_info.SizeOfStruct = sizeof(IMAGEHLP_LINE64);\n  BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(), (DWORD64)addr,\n                                           &unused, &line_info);\n  frame->info.function = internal_strdup(symbol->Name);\n  frame->info.function_offset = (uptr)offset;\n  if (got_fileline) {\n    frame->info.file = internal_strdup(line_info.FileName);\n    frame->info.line = line_info.LineNumber;\n  }\n  // Only consider this a successful symbolization attempt if we got file info.\n  // Otherwise, try llvm-symbolizer.\n  return got_fileline;\n}\n\nconst char *WinSymbolizerTool::Demangle(const char *name) {\n  CHECK(is_dbghelp_initialized);\n  static char demangle_buffer[1000];\n  if (name[0] == '\\01' &&\n      UnDecorateSymbolName(name + 1, demangle_buffer, sizeof(demangle_buffer),\n                           UNDNAME_NAME_ONLY))\n    return demangle_buffer;\n  else\n    return name;\n}\n\nconst char *Symbolizer::PlatformDemangle(const char *name) {\n  return name;\n}\n\nvoid Symbolizer::PlatformPrepareForSandboxing() {\n  // Do nothing.\n}\n\nnamespace {\nstruct ScopedHandle {\n  ScopedHandle() : h_(nullptr) {}\n  explicit ScopedHandle(HANDLE h) : h_(h) {}\n  ~ScopedHandle() {\n    if (h_)\n      ::CloseHandle(h_);\n  }\n  HANDLE get() { return h_; }\n  HANDLE *receive() { return &h_; }\n  HANDLE release() {\n    HANDLE h = h_;\n    h_ = nullptr;\n    return h;\n  }\n  HANDLE h_;\n};\n} // namespace\n\nbool SymbolizerProcess::StartSymbolizerSubprocess() {\n  // Create inherited pipes for stdin and stdout.\n  ScopedHandle stdin_read, stdin_write;\n  ScopedHandle stdout_read, stdout_write;\n  SECURITY_ATTRIBUTES attrs;\n  attrs.nLength = sizeof(SECURITY_ATTRIBUTES);\n  attrs.bInheritHandle = TRUE;\n  attrs.lpSecurityDescriptor = nullptr;\n  if (!::CreatePipe(stdin_read.receive(), stdin_write.receive(), &attrs, 0) ||\n      !::CreatePipe(stdout_read.receive(), stdout_write.receive(), &attrs, 0)) {\n    VReport(2, \"WARNING: %s CreatePipe failed (error code: %d)\\n\",\n            SanitizerToolName, path_, GetLastError());\n    return false;\n  }\n\n  // Don't inherit the writing end of stdin or the reading end of stdout.\n  if (!SetHandleInformation(stdin_write.get(), HANDLE_FLAG_INHERIT, 0) ||\n      !SetHandleInformation(stdout_read.get(), HANDLE_FLAG_INHERIT, 0)) {\n    VReport(2, \"WARNING: %s SetHandleInformation failed (error code: %d)\\n\",\n            SanitizerToolName, path_, GetLastError());\n    return false;\n  }\n\n  // Compute the command line. Wrap double quotes around everything.\n  const char *argv[kArgVMax];\n  GetArgV(path_, argv);\n  InternalScopedString command_line(kMaxPathLength * 3);\n  for (int i = 0; argv[i]; i++) {\n    const char *arg = argv[i];\n    int arglen = internal_strlen(arg);\n    // Check that tool command lines are simple and that complete escaping is\n    // unnecessary.\n    CHECK(!internal_strchr(arg, '\"') && \"quotes in args unsupported\");\n    CHECK(!internal_strstr(arg, \"\\\\\\\\\") &&\n          \"double backslashes in args unsupported\");\n    CHECK(arglen > 0 && arg[arglen - 1] != '\\\\' &&\n          \"args ending in backslash and empty args unsupported\");\n    command_line.append(\"\\\"%s\\\" \", arg);\n  }\n  VReport(3, \"Launching symbolizer command: %s\\n\", command_line.data());\n\n  // Launch llvm-symbolizer with stdin and stdout redirected.\n  STARTUPINFOA si;\n  memset(&si, 0, sizeof(si));\n  si.cb = sizeof(si);\n  si.dwFlags |= STARTF_USESTDHANDLES;\n  si.hStdInput = stdin_read.get();\n  si.hStdOutput = stdout_write.get();\n  PROCESS_INFORMATION pi;\n  memset(&pi, 0, sizeof(pi));\n  if (!CreateProcessA(path_,               // Executable\n                      command_line.data(), // Command line\n                      nullptr,             // Process handle not inheritable\n                      nullptr,             // Thread handle not inheritable\n                      TRUE,                // Set handle inheritance to TRUE\n                      0,                   // Creation flags\n                      nullptr,             // Use parent's environment block\n                      nullptr,             // Use parent's starting directory\n                      &si, &pi)) {\n    VReport(2, \"WARNING: %s failed to create process for %s (error code: %d)\\n\",\n            SanitizerToolName, path_, GetLastError());\n    return false;\n  }\n\n  // Process creation succeeded, so transfer handle ownership into the fields.\n  input_fd_ = stdout_read.release();\n  output_fd_ = stdin_write.release();\n\n  // The llvm-symbolizer process is responsible for quitting itself when the\n  // stdin pipe is closed, so we don't need these handles. Close them to prevent\n  // leaks. If we ever want to try to kill the symbolizer process from the\n  // parent, we'll want to hang on to these handles.\n  CloseHandle(pi.hProcess);\n  CloseHandle(pi.hThread);\n  return true;\n}\n\nstatic void ChooseSymbolizerTools(IntrusiveList<SymbolizerTool> *list,\n                                  LowLevelAllocator *allocator) {\n  if (!common_flags()->symbolize) {\n    VReport(2, \"Symbolizer is disabled.\\n\");\n    return;\n  }\n\n  // Add llvm-symbolizer in case the binary has dwarf.\n  const char *user_path = common_flags()->external_symbolizer_path;\n  const char *path =\n      user_path ? user_path : FindPathToBinary(\"llvm-symbolizer.exe\");\n  if (path) {\n    VReport(2, \"Using llvm-symbolizer at %spath: %s\\n\",\n            user_path ? \"user-specified \" : \"\", path);\n    list->push_back(new(*allocator) LLVMSymbolizer(path, allocator));\n  } else {\n    if (user_path && user_path[0] == '\\0') {\n      VReport(2, \"External symbolizer is explicitly disabled.\\n\");\n    } else {\n      VReport(2, \"External symbolizer is not present.\\n\");\n    }\n  }\n\n  // Add the dbghelp based symbolizer.\n  list->push_back(new(*allocator) WinSymbolizerTool());\n}\n\nSymbolizer *Symbolizer::PlatformInit() {\n  IntrusiveList<SymbolizerTool> list;\n  list.clear();\n  ChooseSymbolizerTools(&list, &symbolizer_allocator_);\n\n  return new(symbolizer_allocator_) Symbolizer(list);\n}\n\n}  // namespace __sanitizer\n\n#endif  // _WIN32\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_syscall_generic.inc",
    "content": "//===-- sanitizer_syscall_generic.inc ---------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Generic implementations of internal_syscall and internal_iserror.\n//\n//===----------------------------------------------------------------------===//\n\n#if SANITIZER_FREEBSD || SANITIZER_MAC\n# define SYSCALL(name) SYS_ ## name\n#else\n# define SYSCALL(name) __NR_ ## name\n#endif\n\n#if (SANITIZER_FREEBSD || SANITIZER_MAC) && defined(__x86_64__)\n# define internal_syscall __syscall\n# else\n# define internal_syscall syscall\n#endif\n\nbool internal_iserror(uptr retval, int *rverrno) {\n  if (retval == (uptr)-1) {\n    if (rverrno)\n      *rverrno = errno;\n    return true;\n  } else {\n    return false;\n  }\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_syscall_linux_aarch64.inc",
    "content": "//===-- sanitizer_syscall_linux_aarch64.inc --------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Implementations of internal_syscall and internal_iserror for Linux/aarch64.\n//\n//===----------------------------------------------------------------------===//\n\n#define SYSCALL(name) __NR_ ## name\n\nstatic uptr __internal_syscall(u64 nr) {\n  register u64 x8 asm(\"x8\") = nr;\n  register u64 x0 asm(\"x0\");\n  asm volatile(\"svc 0\"\n               : \"=r\"(x0)\n               : \"r\"(x8)\n               : \"memory\", \"cc\");\n  return x0;\n}\n#define __internal_syscall0(n) \\\n  (__internal_syscall)(n)\n\nstatic uptr __internal_syscall(u64 nr, u64 arg1) {\n  register u64 x8 asm(\"x8\") = nr;\n  register u64 x0 asm(\"x0\") = arg1;\n  asm volatile(\"svc 0\"\n               : \"=r\"(x0)\n               : \"r\"(x8), \"0\"(x0)\n               : \"memory\", \"cc\");\n  return x0;\n}\n#define __internal_syscall1(n, a1) \\\n  (__internal_syscall)(n, (u64)(a1))\n\nstatic uptr __internal_syscall(u64 nr, u64 arg1, long arg2) {\n  register u64 x8 asm(\"x8\") = nr;\n  register u64 x0 asm(\"x0\") = arg1;\n  register u64 x1 asm(\"x1\") = arg2;\n  asm volatile(\"svc 0\"\n               : \"=r\"(x0)\n               : \"r\"(x8), \"0\"(x0), \"r\"(x1)\n               : \"memory\", \"cc\");\n  return x0;\n}\n#define __internal_syscall2(n, a1, a2) \\\n  (__internal_syscall)(n, (u64)(a1), (long)(a2))\n\nstatic uptr __internal_syscall(u64 nr, u64 arg1, long arg2, long arg3) {\n  register u64 x8 asm(\"x8\") = nr;\n  register u64 x0 asm(\"x0\") = arg1;\n  register u64 x1 asm(\"x1\") = arg2;\n  register u64 x2 asm(\"x2\") = arg3;\n  asm volatile(\"svc 0\"\n               : \"=r\"(x0)\n               : \"r\"(x8), \"0\"(x0), \"r\"(x1), \"r\"(x2)\n               : \"memory\", \"cc\");\n  return x0;\n}\n#define __internal_syscall3(n, a1, a2, a3) \\\n  (__internal_syscall)(n, (u64)(a1), (long)(a2), (long)(a3))\n\nstatic uptr __internal_syscall(u64 nr, u64 arg1, long arg2, long arg3,\n                               u64 arg4) {\n  register u64 x8 asm(\"x8\") = nr;\n  register u64 x0 asm(\"x0\") = arg1;\n  register u64 x1 asm(\"x1\") = arg2;\n  register u64 x2 asm(\"x2\") = arg3;\n  register u64 x3 asm(\"x3\") = arg4;\n  asm volatile(\"svc 0\"\n               : \"=r\"(x0)\n               : \"r\"(x8), \"0\"(x0), \"r\"(x1), \"r\"(x2), \"r\"(x3)\n               : \"memory\", \"cc\");\n  return x0;\n}\n#define __internal_syscall4(n, a1, a2, a3, a4) \\\n  (__internal_syscall)(n, (u64)(a1), (long)(a2), (long)(a3), (long)(a4))\n\nstatic uptr __internal_syscall(u64 nr, u64 arg1, long arg2, long arg3,\n                               u64 arg4, long arg5) {\n  register u64 x8 asm(\"x8\") = nr;\n  register u64 x0 asm(\"x0\") = arg1;\n  register u64 x1 asm(\"x1\") = arg2;\n  register u64 x2 asm(\"x2\") = arg3;\n  register u64 x3 asm(\"x3\") = arg4;\n  register u64 x4 asm(\"x4\") = arg5;\n  asm volatile(\"svc 0\"\n               : \"=r\"(x0)\n               : \"r\"(x8), \"0\"(x0), \"r\"(x1), \"r\"(x2), \"r\"(x3), \"r\"(x4)\n               : \"memory\", \"cc\");\n  return x0;\n}\n#define __internal_syscall5(n, a1, a2, a3, a4, a5) \\\n  (__internal_syscall)(n, (u64)(a1), (long)(a2), (long)(a3), (long)(a4), \\\n                       (u64)(a5))\n\nstatic uptr __internal_syscall(u64 nr, u64 arg1, long arg2, long arg3,\n                               u64 arg4, long arg5, long arg6) {\n  register u64 x8 asm(\"x8\") = nr;\n  register u64 x0 asm(\"x0\") = arg1;\n  register u64 x1 asm(\"x1\") = arg2;\n  register u64 x2 asm(\"x2\") = arg3;\n  register u64 x3 asm(\"x3\") = arg4;\n  register u64 x4 asm(\"x4\") = arg5;\n  register u64 x5 asm(\"x5\") = arg6;\n  asm volatile(\"svc 0\"\n               : \"=r\"(x0)\n               : \"r\"(x8), \"0\"(x0), \"r\"(x1), \"r\"(x2), \"r\"(x3), \"r\"(x4), \"r\"(x5)\n               : \"memory\", \"cc\");\n  return x0;\n}\n#define __internal_syscall6(n, a1, a2, a3, a4, a5, a6) \\\n  (__internal_syscall)(n, (u64)(a1), (long)(a2), (long)(a3), (long)(a4), \\\n                       (u64)(a5), (long)(a6))\n\n#define __SYSCALL_NARGS_X(a1, a2, a3, a4, a5, a6, a7, a8, n, ...) n\n#define __SYSCALL_NARGS(...) \\\n  __SYSCALL_NARGS_X(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0, )\n#define __SYSCALL_CONCAT_X(a, b) a##b\n#define __SYSCALL_CONCAT(a, b) __SYSCALL_CONCAT_X(a, b)\n#define __SYSCALL_DISP(b, ...) \\\n  __SYSCALL_CONCAT(b, __SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)\n\n#define internal_syscall(...) __SYSCALL_DISP(__internal_syscall, __VA_ARGS__)\n\n// Helper function used to avoid cobbler errno.\nbool internal_iserror(uptr retval, int *rverrno) {\n  if (retval >= (uptr)-4095) {\n    if (rverrno)\n      *rverrno = -retval;\n    return true;\n  }\n  return false;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_syscall_linux_x86_64.inc",
    "content": "//===-- sanitizer_syscall_linux_x86_64.inc ----------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Implementations of internal_syscall and internal_iserror for Linux/x86_64.\n//\n//===----------------------------------------------------------------------===//\n\n#define SYSCALL(name) __NR_ ## name\n\nstatic uptr internal_syscall(u64 nr) {\n  u64 retval;\n  asm volatile(\"syscall\" : \"=a\"(retval) : \"a\"(nr) : \"rcx\", \"r11\",\n               \"memory\", \"cc\");\n  return retval;\n}\n\ntemplate <typename T1>\nstatic uptr internal_syscall(u64 nr, T1 arg1) {\n  u64 retval;\n  asm volatile(\"syscall\" : \"=a\"(retval) : \"a\"(nr), \"D\"((u64)arg1) :\n               \"rcx\", \"r11\", \"memory\", \"cc\");\n  return retval;\n}\n\ntemplate <typename T1, typename T2>\nstatic uptr internal_syscall(u64 nr, T1 arg1, T2 arg2) {\n  u64 retval;\n  asm volatile(\"syscall\" : \"=a\"(retval) : \"a\"(nr), \"D\"((u64)arg1),\n               \"S\"((u64)arg2) : \"rcx\", \"r11\", \"memory\", \"cc\");\n  return retval;\n}\n\ntemplate <typename T1, typename T2, typename T3>\nstatic uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3) {\n  u64 retval;\n  asm volatile(\"syscall\" : \"=a\"(retval) : \"a\"(nr), \"D\"((u64)arg1),\n               \"S\"((u64)arg2), \"d\"((u64)arg3) : \"rcx\", \"r11\", \"memory\", \"cc\");\n  return retval;\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4>\nstatic uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4) {\n  u64 retval;\n  asm volatile(\"mov %5, %%r10;\"\n               \"syscall\" : \"=a\"(retval) : \"a\"(nr), \"D\"((u64)arg1),\n               \"S\"((u64)arg2), \"d\"((u64)arg3), \"r\"((u64)arg4) :\n               \"rcx\", \"r11\", \"r10\", \"memory\", \"cc\");\n  return retval;\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5>\nstatic uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4,\n                             T5 arg5) {\n  u64 retval;\n  asm volatile(\"mov %5, %%r10;\"\n               \"mov %6, %%r8;\"\n               \"syscall\" : \"=a\"(retval) : \"a\"(nr), \"D\"((u64)arg1),\n               \"S\"((u64)arg2), \"d\"((u64)arg3), \"r\"((u64)arg4), \"r\"((u64)arg5) :\n               \"rcx\", \"r11\", \"r10\", \"r8\", \"memory\", \"cc\");\n  return retval;\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n          typename T6>\nstatic uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4,\n                             T5 arg5, T6 arg6) {\n  u64 retval;\n  asm volatile(\"mov %5, %%r10;\"\n               \"mov %6, %%r8;\"\n               \"mov %7, %%r9;\"\n               \"syscall\" : \"=a\"(retval) : \"a\"(nr), \"D\"((u64)arg1),\n               \"S\"((u64)arg2), \"d\"((u64)arg3), \"r\"((u64)arg4), \"r\"((u64)arg5),\n               \"r\"((u64)arg6) : \"rcx\", \"r11\", \"r10\", \"r8\", \"r9\",\n               \"memory\", \"cc\");\n  return retval;\n}\n\nbool internal_iserror(uptr retval, int *rverrno) {\n  if (retval >= (uptr)-4095) {\n    if (rverrno)\n      *rverrno = -retval;\n    return true;\n  }\n  return false;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cc",
    "content": "//===-- sanitizer_thread_registry.cc --------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between sanitizer tools.\n//\n// General thread bookkeeping functionality.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_thread_registry.h\"\n\nnamespace __sanitizer {\n\nThreadContextBase::ThreadContextBase(u32 tid)\n    : tid(tid), unique_id(0), reuse_count(), os_id(0), user_id(0),\n      status(ThreadStatusInvalid),\n      detached(false), parent_tid(0), next(0) {\n  name[0] = '\\0';\n}\n\nThreadContextBase::~ThreadContextBase() {\n  // ThreadContextBase should never be deleted.\n  CHECK(0);\n}\n\nvoid ThreadContextBase::SetName(const char *new_name) {\n  name[0] = '\\0';\n  if (new_name) {\n    internal_strncpy(name, new_name, sizeof(name));\n    name[sizeof(name) - 1] = '\\0';\n  }\n}\n\nvoid ThreadContextBase::SetDead() {\n  CHECK(status == ThreadStatusRunning ||\n        status == ThreadStatusFinished);\n  status = ThreadStatusDead;\n  user_id = 0;\n  OnDead();\n}\n\nvoid ThreadContextBase::SetJoined(void *arg) {\n  // FIXME(dvyukov): print message and continue (it's user error).\n  CHECK_EQ(false, detached);\n  CHECK_EQ(ThreadStatusFinished, status);\n  status = ThreadStatusDead;\n  user_id = 0;\n  OnJoined(arg);\n}\n\nvoid ThreadContextBase::SetFinished() {\n  if (!detached)\n    status = ThreadStatusFinished;\n  OnFinished();\n}\n\nvoid ThreadContextBase::SetStarted(uptr _os_id, void *arg) {\n  status = ThreadStatusRunning;\n  os_id = _os_id;\n  OnStarted(arg);\n}\n\nvoid ThreadContextBase::SetCreated(uptr _user_id, u64 _unique_id,\n                                   bool _detached, u32 _parent_tid, void *arg) {\n  status = ThreadStatusCreated;\n  user_id = _user_id;\n  unique_id = _unique_id;\n  detached = _detached;\n  // Parent tid makes no sense for the main thread.\n  if (tid != 0)\n    parent_tid = _parent_tid;\n  OnCreated(arg);\n}\n\nvoid ThreadContextBase::Reset() {\n  status = ThreadStatusInvalid;\n  SetName(0);\n  OnReset();\n}\n\n// ThreadRegistry implementation.\n\nconst u32 ThreadRegistry::kUnknownTid = ~0U;\n\nThreadRegistry::ThreadRegistry(ThreadContextFactory factory, u32 max_threads,\n                               u32 thread_quarantine_size, u32 max_reuse)\n    : context_factory_(factory),\n      max_threads_(max_threads),\n      thread_quarantine_size_(thread_quarantine_size),\n      max_reuse_(max_reuse),\n      mtx_(),\n      n_contexts_(0),\n      total_threads_(0),\n      alive_threads_(0),\n      max_alive_threads_(0),\n      running_threads_(0) {\n  threads_ = (ThreadContextBase **)MmapOrDie(max_threads_ * sizeof(threads_[0]),\n                                             \"ThreadRegistry\");\n  dead_threads_.clear();\n  invalid_threads_.clear();\n}\n\nvoid ThreadRegistry::GetNumberOfThreads(uptr *total, uptr *running,\n                                        uptr *alive) {\n  BlockingMutexLock l(&mtx_);\n  if (total) *total = n_contexts_;\n  if (running) *running = running_threads_;\n  if (alive) *alive = alive_threads_;\n}\n\nuptr ThreadRegistry::GetMaxAliveThreads() {\n  BlockingMutexLock l(&mtx_);\n  return max_alive_threads_;\n}\n\nu32 ThreadRegistry::CreateThread(uptr user_id, bool detached, u32 parent_tid,\n                                 void *arg) {\n  BlockingMutexLock l(&mtx_);\n  u32 tid = kUnknownTid;\n  ThreadContextBase *tctx = QuarantinePop();\n  if (tctx) {\n    tid = tctx->tid;\n  } else if (n_contexts_ < max_threads_) {\n    // Allocate new thread context and tid.\n    tid = n_contexts_++;\n    tctx = context_factory_(tid);\n    threads_[tid] = tctx;\n  } else {\n#ifndef SANITIZER_GO\n    Report(\"%s: Thread limit (%u threads) exceeded. Dying.\\n\",\n           SanitizerToolName, max_threads_);\n#else\n    Printf(\"race: limit on %u simultaneously alive goroutines is exceeded,\"\n        \" dying\\n\", max_threads_);\n#endif\n    Die();\n  }\n  CHECK_NE(tctx, 0);\n  CHECK_NE(tid, kUnknownTid);\n  CHECK_LT(tid, max_threads_);\n  CHECK_EQ(tctx->status, ThreadStatusInvalid);\n  alive_threads_++;\n  if (max_alive_threads_ < alive_threads_) {\n    max_alive_threads_++;\n    CHECK_EQ(alive_threads_, max_alive_threads_);\n  }\n  tctx->SetCreated(user_id, total_threads_++, detached,\n                   parent_tid, arg);\n  return tid;\n}\n\nvoid ThreadRegistry::RunCallbackForEachThreadLocked(ThreadCallback cb,\n                                                    void *arg) {\n  CheckLocked();\n  for (u32 tid = 0; tid < n_contexts_; tid++) {\n    ThreadContextBase *tctx = threads_[tid];\n    if (tctx == 0)\n      continue;\n    cb(tctx, arg);\n  }\n}\n\nu32 ThreadRegistry::FindThread(FindThreadCallback cb, void *arg) {\n  BlockingMutexLock l(&mtx_);\n  for (u32 tid = 0; tid < n_contexts_; tid++) {\n    ThreadContextBase *tctx = threads_[tid];\n    if (tctx != 0 && cb(tctx, arg))\n      return tctx->tid;\n  }\n  return kUnknownTid;\n}\n\nThreadContextBase *\nThreadRegistry::FindThreadContextLocked(FindThreadCallback cb, void *arg) {\n  CheckLocked();\n  for (u32 tid = 0; tid < n_contexts_; tid++) {\n    ThreadContextBase *tctx = threads_[tid];\n    if (tctx != 0 && cb(tctx, arg))\n      return tctx;\n  }\n  return 0;\n}\n\nstatic bool FindThreadContextByOsIdCallback(ThreadContextBase *tctx,\n                                            void *arg) {\n  return (tctx->os_id == (uptr)arg && tctx->status != ThreadStatusInvalid &&\n      tctx->status != ThreadStatusDead);\n}\n\nThreadContextBase *ThreadRegistry::FindThreadContextByOsIDLocked(uptr os_id) {\n  return FindThreadContextLocked(FindThreadContextByOsIdCallback,\n                                 (void *)os_id);\n}\n\nvoid ThreadRegistry::SetThreadName(u32 tid, const char *name) {\n  BlockingMutexLock l(&mtx_);\n  CHECK_LT(tid, n_contexts_);\n  ThreadContextBase *tctx = threads_[tid];\n  CHECK_NE(tctx, 0);\n  CHECK_EQ(ThreadStatusRunning, tctx->status);\n  tctx->SetName(name);\n}\n\nvoid ThreadRegistry::SetThreadNameByUserId(uptr user_id, const char *name) {\n  BlockingMutexLock l(&mtx_);\n  for (u32 tid = 0; tid < n_contexts_; tid++) {\n    ThreadContextBase *tctx = threads_[tid];\n    if (tctx != 0 && tctx->user_id == user_id &&\n        tctx->status != ThreadStatusInvalid) {\n      tctx->SetName(name);\n      return;\n    }\n  }\n}\n\nvoid ThreadRegistry::DetachThread(u32 tid, void *arg) {\n  BlockingMutexLock l(&mtx_);\n  CHECK_LT(tid, n_contexts_);\n  ThreadContextBase *tctx = threads_[tid];\n  CHECK_NE(tctx, 0);\n  if (tctx->status == ThreadStatusInvalid) {\n    Report(\"%s: Detach of non-existent thread\\n\", SanitizerToolName);\n    return;\n  }\n  tctx->OnDetached(arg);\n  if (tctx->status == ThreadStatusFinished) {\n    tctx->SetDead();\n    QuarantinePush(tctx);\n  } else {\n    tctx->detached = true;\n  }\n}\n\nvoid ThreadRegistry::JoinThread(u32 tid, void *arg) {\n  BlockingMutexLock l(&mtx_);\n  CHECK_LT(tid, n_contexts_);\n  ThreadContextBase *tctx = threads_[tid];\n  CHECK_NE(tctx, 0);\n  if (tctx->status == ThreadStatusInvalid) {\n    Report(\"%s: Join of non-existent thread\\n\", SanitizerToolName);\n    return;\n  }\n  tctx->SetJoined(arg);\n  QuarantinePush(tctx);\n}\n\nvoid ThreadRegistry::FinishThread(u32 tid) {\n  BlockingMutexLock l(&mtx_);\n  CHECK_GT(alive_threads_, 0);\n  alive_threads_--;\n  CHECK_GT(running_threads_, 0);\n  running_threads_--;\n  CHECK_LT(tid, n_contexts_);\n  ThreadContextBase *tctx = threads_[tid];\n  CHECK_NE(tctx, 0);\n  CHECK_EQ(ThreadStatusRunning, tctx->status);\n  tctx->SetFinished();\n  if (tctx->detached) {\n    tctx->SetDead();\n    QuarantinePush(tctx);\n  }\n}\n\nvoid ThreadRegistry::StartThread(u32 tid, uptr os_id, void *arg) {\n  BlockingMutexLock l(&mtx_);\n  running_threads_++;\n  CHECK_LT(tid, n_contexts_);\n  ThreadContextBase *tctx = threads_[tid];\n  CHECK_NE(tctx, 0);\n  CHECK_EQ(ThreadStatusCreated, tctx->status);\n  tctx->SetStarted(os_id, arg);\n}\n\nvoid ThreadRegistry::QuarantinePush(ThreadContextBase *tctx) {\n  dead_threads_.push_back(tctx);\n  if (dead_threads_.size() <= thread_quarantine_size_)\n    return;\n  tctx = dead_threads_.front();\n  dead_threads_.pop_front();\n  CHECK_EQ(tctx->status, ThreadStatusDead);\n  tctx->Reset();\n  tctx->reuse_count++;\n  if (max_reuse_ > 0 && tctx->reuse_count >= max_reuse_)\n    return;\n  invalid_threads_.push_back(tctx);\n}\n\nThreadContextBase *ThreadRegistry::QuarantinePop() {\n  if (invalid_threads_.size() == 0)\n    return 0;\n  ThreadContextBase *tctx = invalid_threads_.front();\n  invalid_threads_.pop_front();\n  return tctx;\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h",
    "content": "//===-- sanitizer_thread_registry.h -----------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between sanitizer tools.\n//\n// General thread bookkeeping functionality.\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_THREAD_REGISTRY_H\n#define SANITIZER_THREAD_REGISTRY_H\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_list.h\"\n#include \"sanitizer_mutex.h\"\n\nnamespace __sanitizer {\n\nenum ThreadStatus {\n  ThreadStatusInvalid,   // Non-existent thread, data is invalid.\n  ThreadStatusCreated,   // Created but not yet running.\n  ThreadStatusRunning,   // The thread is currently running.\n  ThreadStatusFinished,  // Joinable thread is finished but not yet joined.\n  ThreadStatusDead       // Joined, but some info is still available.\n};\n\n// Generic thread context. Specific sanitizer tools may inherit from it.\n// If thread is dead, context may optionally be reused for a new thread.\nclass ThreadContextBase {\n public:\n  explicit ThreadContextBase(u32 tid);\n  ~ThreadContextBase();  // Should never be called.\n\n  const u32 tid;  // Thread ID. Main thread should have tid = 0.\n  u64 unique_id;  // Unique thread ID.\n  u32 reuse_count;  // Number of times this tid was reused.\n  uptr os_id;     // PID (used for reporting).\n  uptr user_id;   // Some opaque user thread id (e.g. pthread_t).\n  char name[64];  // As annotated by user.\n\n  ThreadStatus status;\n  bool detached;\n\n  u32 parent_tid;\n  ThreadContextBase *next;  // For storing thread contexts in a list.\n\n  void SetName(const char *new_name);\n\n  void SetDead();\n  void SetJoined(void *arg);\n  void SetFinished();\n  void SetStarted(uptr _os_id, void *arg);\n  void SetCreated(uptr _user_id, u64 _unique_id, bool _detached,\n                  u32 _parent_tid, void *arg);\n  void Reset();\n\n  // The following methods may be overriden by subclasses.\n  // Some of them take opaque arg that may be optionally be used\n  // by subclasses.\n  virtual void OnDead() {}\n  virtual void OnJoined(void *arg) {}\n  virtual void OnFinished() {}\n  virtual void OnStarted(void *arg) {}\n  virtual void OnCreated(void *arg) {}\n  virtual void OnReset() {}\n  virtual void OnDetached(void *arg) {}\n};\n\ntypedef ThreadContextBase* (*ThreadContextFactory)(u32 tid);\n\nclass ThreadRegistry {\n public:\n  static const u32 kUnknownTid;\n\n  ThreadRegistry(ThreadContextFactory factory, u32 max_threads,\n                 u32 thread_quarantine_size, u32 max_reuse = 0);\n  void GetNumberOfThreads(uptr *total = nullptr, uptr *running = nullptr,\n                          uptr *alive = nullptr);\n  uptr GetMaxAliveThreads();\n\n  void Lock() { mtx_.Lock(); }\n  void CheckLocked() { mtx_.CheckLocked(); }\n  void Unlock() { mtx_.Unlock(); }\n\n  // Should be guarded by ThreadRegistryLock.\n  ThreadContextBase *GetThreadLocked(u32 tid) {\n    DCHECK_LT(tid, n_contexts_);\n    return threads_[tid];\n  }\n\n  u32 CreateThread(uptr user_id, bool detached, u32 parent_tid, void *arg);\n\n  typedef void (*ThreadCallback)(ThreadContextBase *tctx, void *arg);\n  // Invokes callback with a specified arg for each thread context.\n  // Should be guarded by ThreadRegistryLock.\n  void RunCallbackForEachThreadLocked(ThreadCallback cb, void *arg);\n\n  typedef bool (*FindThreadCallback)(ThreadContextBase *tctx, void *arg);\n  // Finds a thread using the provided callback. Returns kUnknownTid if no\n  // thread is found.\n  u32 FindThread(FindThreadCallback cb, void *arg);\n  // Should be guarded by ThreadRegistryLock. Return 0 if no thread\n  // is found.\n  ThreadContextBase *FindThreadContextLocked(FindThreadCallback cb,\n                                             void *arg);\n  ThreadContextBase *FindThreadContextByOsIDLocked(uptr os_id);\n\n  void SetThreadName(u32 tid, const char *name);\n  void SetThreadNameByUserId(uptr user_id, const char *name);\n  void DetachThread(u32 tid, void *arg);\n  void JoinThread(u32 tid, void *arg);\n  void FinishThread(u32 tid);\n  void StartThread(u32 tid, uptr os_id, void *arg);\n\n private:\n  const ThreadContextFactory context_factory_;\n  const u32 max_threads_;\n  const u32 thread_quarantine_size_;\n  const u32 max_reuse_;\n\n  BlockingMutex mtx_;\n\n  u32 n_contexts_;      // Number of created thread contexts,\n                        // at most max_threads_.\n  u64 total_threads_;   // Total number of created threads. May be greater than\n                        // max_threads_ if contexts were reused.\n  uptr alive_threads_;  // Created or running.\n  uptr max_alive_threads_;\n  uptr running_threads_;\n\n  ThreadContextBase **threads_;  // Array of thread contexts is leaked.\n  IntrusiveList<ThreadContextBase> dead_threads_;\n  IntrusiveList<ThreadContextBase> invalid_threads_;\n\n  void QuarantinePush(ThreadContextBase *tctx);\n  ThreadContextBase *QuarantinePop();\n};\n\ntypedef GenericScopedLock<ThreadRegistry> ThreadRegistryLock;\n\n} // namespace __sanitizer\n\n#endif // SANITIZER_THREAD_REGISTRY_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cc",
    "content": "//===-- sanitizer_tls_get_addr.cc -----------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Handle the __tls_get_addr call.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_tls_get_addr.h\"\n\n#include \"sanitizer_flags.h\"\n#include \"sanitizer_platform_interceptors.h\"\n\nnamespace __sanitizer {\n#if SANITIZER_INTERCEPT_TLS_GET_ADDR\n\n// The actual parameter that comes to __tls_get_addr\n// is a pointer to a struct with two words in it:\nstruct TlsGetAddrParam {\n  uptr dso_id;\n  uptr offset;\n};\n\n// Glibc starting from 2.19 allocates tls using __signal_safe_memalign,\n// which has such header.\nstruct Glibc_2_19_tls_header {\n  uptr size;\n  uptr start;\n};\n\n// This must be static TLS\n__attribute__((tls_model(\"initial-exec\")))\nstatic __thread DTLS dtls;\n\n// Make sure we properly destroy the DTLS objects:\n// this counter should never get too large.\nstatic atomic_uintptr_t number_of_live_dtls;\n\nstatic const uptr kDestroyedThread = -1;\n\nstatic inline void DTLS_Deallocate(DTLS::DTV *dtv, uptr size) {\n  if (!size) return;\n  VPrintf(2, \"__tls_get_addr: DTLS_Deallocate %p %zd\\n\", dtv, size);\n  UnmapOrDie(dtv, size * sizeof(DTLS::DTV));\n  atomic_fetch_sub(&number_of_live_dtls, 1, memory_order_relaxed);\n}\n\nstatic inline void DTLS_Resize(uptr new_size) {\n  if (dtls.dtv_size >= new_size) return;\n  new_size = RoundUpToPowerOfTwo(new_size);\n  new_size = Max(new_size, 4096UL / sizeof(DTLS::DTV));\n  DTLS::DTV *new_dtv =\n      (DTLS::DTV *)MmapOrDie(new_size * sizeof(DTLS::DTV), \"DTLS_Resize\");\n  uptr num_live_dtls =\n      atomic_fetch_add(&number_of_live_dtls, 1, memory_order_relaxed);\n  VPrintf(2, \"__tls_get_addr: DTLS_Resize %p %zd\\n\", &dtls, num_live_dtls);\n  CHECK_LT(num_live_dtls, 1 << 20);\n  uptr old_dtv_size = dtls.dtv_size;\n  DTLS::DTV *old_dtv = dtls.dtv;\n  if (old_dtv_size)\n    internal_memcpy(new_dtv, dtls.dtv, dtls.dtv_size * sizeof(DTLS::DTV));\n  dtls.dtv = new_dtv;\n  dtls.dtv_size = new_size;\n  if (old_dtv_size)\n    DTLS_Deallocate(old_dtv, old_dtv_size);\n}\n\nvoid DTLS_Destroy() {\n  if (!common_flags()->intercept_tls_get_addr) return;\n  VPrintf(2, \"__tls_get_addr: DTLS_Destroy %p %zd\\n\", &dtls, dtls.dtv_size);\n  uptr s = dtls.dtv_size;\n  dtls.dtv_size = kDestroyedThread;  // Do this before unmap for AS-safety.\n  DTLS_Deallocate(dtls.dtv, s);\n}\n\n#if defined(__powerpc64__)\n// This is glibc's TLS_DTV_OFFSET:\n// \"Dynamic thread vector pointers point 0x8000 past the start of each\n//  TLS block.\"\nstatic const uptr kDtvOffset = 0x8000;\n#else\nstatic const uptr kDtvOffset = 0;\n#endif\n\nDTLS::DTV *DTLS_on_tls_get_addr(void *arg_void, void *res,\n                                uptr static_tls_begin, uptr static_tls_end) {\n  if (!common_flags()->intercept_tls_get_addr) return 0;\n  TlsGetAddrParam *arg = reinterpret_cast<TlsGetAddrParam *>(arg_void);\n  uptr dso_id = arg->dso_id;\n  if (dtls.dtv_size == kDestroyedThread) return 0;\n  DTLS_Resize(dso_id + 1);\n  if (dtls.dtv[dso_id].beg) return 0;\n  uptr tls_size = 0;\n  uptr tls_beg = reinterpret_cast<uptr>(res) - arg->offset - kDtvOffset;\n  VPrintf(2, \"__tls_get_addr: %p {%p,%p} => %p; tls_beg: %p; sp: %p \"\n             \"num_live_dtls %zd\\n\",\n          arg, arg->dso_id, arg->offset, res, tls_beg, &tls_beg,\n          atomic_load(&number_of_live_dtls, memory_order_relaxed));\n  if (dtls.last_memalign_ptr == tls_beg) {\n    tls_size = dtls.last_memalign_size;\n    VPrintf(2, \"__tls_get_addr: glibc <=2.18 suspected; tls={%p,%p}\\n\",\n        tls_beg, tls_size);\n  } else if (tls_beg >= static_tls_begin && tls_beg < static_tls_end) {\n    // This is the static TLS block which was initialized / unpoisoned at thread\n    // creation.\n    VPrintf(2, \"__tls_get_addr: static tls: %p\\n\", tls_beg);\n    tls_size = 0;\n  } else if ((tls_beg % 4096) == sizeof(Glibc_2_19_tls_header)) {\n    // We may want to check gnu_get_libc_version().\n    Glibc_2_19_tls_header *header = (Glibc_2_19_tls_header *)tls_beg - 1;\n    tls_size = header->size;\n    tls_beg = header->start;\n    VPrintf(2, \"__tls_get_addr: glibc >=2.19 suspected; tls={%p %p}\\n\",\n        tls_beg, tls_size);\n  } else {\n    VPrintf(2, \"__tls_get_addr: Can't guess glibc version\\n\");\n    // This may happen inside the DTOR of main thread, so just ignore it.\n    tls_size = 0;\n  }\n  dtls.dtv[dso_id].beg = tls_beg;\n  dtls.dtv[dso_id].size = tls_size;\n  return dtls.dtv + dso_id;\n}\n\nvoid DTLS_on_libc_memalign(void *ptr, uptr size) {\n  if (!common_flags()->intercept_tls_get_addr) return;\n  VPrintf(2, \"DTLS_on_libc_memalign: %p %p\\n\", ptr, size);\n  dtls.last_memalign_ptr = reinterpret_cast<uptr>(ptr);\n  dtls.last_memalign_size = size;\n}\n\nDTLS *DTLS_Get() { return &dtls; }\n\n#else\nvoid DTLS_on_libc_memalign(void *ptr, uptr size) {}\nDTLS::DTV *DTLS_on_tls_get_addr(void *arg, void *res) { return 0; }\nDTLS *DTLS_Get() { return 0; }\nvoid DTLS_Destroy() {}\n#endif  // SANITIZER_INTERCEPT_TLS_GET_ADDR\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.h",
    "content": "//===-- sanitizer_tls_get_addr.h --------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Handle the __tls_get_addr call.\n//\n// All this magic is specific to glibc and is required to workaround\n// the lack of interface that would tell us about the Dynamic TLS (DTLS).\n// https://sourceware.org/bugzilla/show_bug.cgi?id=16291\n//\n// The matters get worse because the glibc implementation changed between\n// 2.18 and 2.19:\n// https://groups.google.com/forum/#!topic/address-sanitizer/BfwYD8HMxTM\n//\n// Before 2.19, every DTLS chunk is allocated with __libc_memalign,\n// which we intercept and thus know where is the DTLS.\n// Since 2.19, DTLS chunks are allocated with __signal_safe_memalign,\n// which is an internal function that wraps a mmap call, neither of which\n// we can intercept. Luckily, __signal_safe_memalign has a simple parseable\n// header which we can use.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_TLS_GET_ADDR_H\n#define SANITIZER_TLS_GET_ADDR_H\n\n#include \"sanitizer_common.h\"\n\nnamespace __sanitizer {\n\nstruct DTLS {\n  // Array of DTLS chunks for the current Thread.\n  // If beg == 0, the chunk is unused.\n  struct DTV {\n    uptr beg, size;\n  };\n\n  uptr dtv_size;\n  DTV *dtv;  // dtv_size elements, allocated by MmapOrDie.\n\n  // Auxiliary fields, don't access them outside sanitizer_tls_get_addr.cc\n  uptr last_memalign_size;\n  uptr last_memalign_ptr;\n};\n\n// Returns pointer and size of a linker-allocated TLS block.\n// Each block is returned exactly once.\nDTLS::DTV *DTLS_on_tls_get_addr(void *arg, void *res, uptr static_tls_begin,\n                                uptr static_tls_end);\nvoid DTLS_on_libc_memalign(void *ptr, uptr size);\nDTLS *DTLS_Get();\nvoid DTLS_Destroy();  // Make sure to call this before the thread is destroyed.\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_TLS_GET_ADDR_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc",
    "content": "//===-- sanitizer_unwind_linux_libcdep.cc ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file contains the unwind.h-based (aka \"slow\") stack unwinding routines\n// available to the tools on Linux, Android, and FreeBSD.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n#if SANITIZER_FREEBSD || SANITIZER_LINUX\n#include \"sanitizer_common.h\"\n#include \"sanitizer_stacktrace.h\"\n\n#if SANITIZER_ANDROID\n#include <dlfcn.h>  // for dlopen()\n#endif\n\n#if SANITIZER_FREEBSD\n#define _GNU_SOURCE  // to declare _Unwind_Backtrace() from <unwind.h>\n#endif\n#include <unwind.h>\n\nnamespace __sanitizer {\n\n//------------------------- SlowUnwindStack -----------------------------------\n\ntypedef struct {\n  uptr absolute_pc;\n  uptr stack_top;\n  uptr stack_size;\n} backtrace_frame_t;\n\nextern \"C\" {\ntypedef void *(*acquire_my_map_info_list_func)();\ntypedef void (*release_my_map_info_list_func)(void *map);\ntypedef sptr (*unwind_backtrace_signal_arch_func)(\n    void *siginfo, void *sigcontext, void *map_info_list,\n    backtrace_frame_t *backtrace, uptr ignore_depth, uptr max_depth);\nacquire_my_map_info_list_func acquire_my_map_info_list;\nrelease_my_map_info_list_func release_my_map_info_list;\nunwind_backtrace_signal_arch_func unwind_backtrace_signal_arch;\n} // extern \"C\"\n\n#if SANITIZER_ANDROID\nvoid SanitizerInitializeUnwinder() {\n  void *p = dlopen(\"libcorkscrew.so\", RTLD_LAZY);\n  if (!p) {\n    VReport(1,\n            \"Failed to open libcorkscrew.so. You may see broken stack traces \"\n            \"in SEGV reports.\");\n    return;\n  }\n  acquire_my_map_info_list =\n      (acquire_my_map_info_list_func)(uptr)dlsym(p, \"acquire_my_map_info_list\");\n  release_my_map_info_list =\n      (release_my_map_info_list_func)(uptr)dlsym(p, \"release_my_map_info_list\");\n  unwind_backtrace_signal_arch = (unwind_backtrace_signal_arch_func)(uptr)dlsym(\n      p, \"unwind_backtrace_signal_arch\");\n  if (!acquire_my_map_info_list || !release_my_map_info_list ||\n      !unwind_backtrace_signal_arch) {\n    VReport(1,\n            \"Failed to find one of the required symbols in libcorkscrew.so. \"\n            \"You may see broken stack traces in SEGV reports.\");\n    acquire_my_map_info_list = 0;\n    unwind_backtrace_signal_arch = 0;\n    release_my_map_info_list = 0;\n  }\n}\n#endif\n\n#ifdef __arm__\n#define UNWIND_STOP _URC_END_OF_STACK\n#define UNWIND_CONTINUE _URC_NO_REASON\n#else\n#define UNWIND_STOP _URC_NORMAL_STOP\n#define UNWIND_CONTINUE _URC_NO_REASON\n#endif\n\nuptr Unwind_GetIP(struct _Unwind_Context *ctx) {\n#if defined(__arm__) && !SANITIZER_MAC\n  uptr val;\n  _Unwind_VRS_Result res = _Unwind_VRS_Get(ctx, _UVRSC_CORE,\n      15 /* r15 = PC */, _UVRSD_UINT32, &val);\n  CHECK(res == _UVRSR_OK && \"_Unwind_VRS_Get failed\");\n  // Clear the Thumb bit.\n  return val & ~(uptr)1;\n#else\n  return _Unwind_GetIP(ctx);\n#endif\n}\n\nstruct UnwindTraceArg {\n  BufferedStackTrace *stack;\n  u32 max_depth;\n};\n\n_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {\n  UnwindTraceArg *arg = (UnwindTraceArg*)param;\n  CHECK_LT(arg->stack->size, arg->max_depth);\n  uptr pc = Unwind_GetIP(ctx);\n  arg->stack->trace_buffer[arg->stack->size++] = pc;\n  if (arg->stack->size == arg->max_depth) return UNWIND_STOP;\n  return UNWIND_CONTINUE;\n}\n\nvoid BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) {\n  CHECK_GE(max_depth, 2);\n  size = 0;\n  UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)};\n  _Unwind_Backtrace(Unwind_Trace, &arg);\n  // We need to pop a few frames so that pc is on top.\n  uptr to_pop = LocatePcInTrace(pc);\n  // trace_buffer[0] belongs to the current function so we always pop it,\n  // unless there is only 1 frame in the stack trace (1 frame is always better\n  // than 0!).\n  // 1-frame stacks don't normally happen, but this depends on the actual\n  // unwinder implementation (libgcc, libunwind, etc) which is outside of our\n  // control.\n  if (to_pop == 0 && size > 1)\n    to_pop = 1;\n  PopStackFrames(to_pop);\n  trace_buffer[0] = pc;\n}\n\nvoid BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context,\n                                                    u32 max_depth) {\n  CHECK_GE(max_depth, 2);\n  if (!unwind_backtrace_signal_arch) {\n    SlowUnwindStack(pc, max_depth);\n    return;\n  }\n\n  void *map = acquire_my_map_info_list();\n  CHECK(map);\n  InternalScopedBuffer<backtrace_frame_t> frames(kStackTraceMax);\n  // siginfo argument appears to be unused.\n  sptr res = unwind_backtrace_signal_arch(/* siginfo */ 0, context, map,\n                                          frames.data(),\n                                          /* ignore_depth */ 0, max_depth);\n  release_my_map_info_list(map);\n  if (res < 0) return;\n  CHECK_LE((uptr)res, kStackTraceMax);\n\n  size = 0;\n  // +2 compensate for libcorkscrew unwinder returning addresses of call\n  // instructions instead of raw return addresses.\n  for (sptr i = 0; i < res; ++i)\n    trace_buffer[size++] = frames[i].absolute_pc + 2;\n}\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/sanitizer_win.cc",
    "content": "//===-- sanitizer_win.cc --------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is shared between AddressSanitizer and ThreadSanitizer\n// run-time libraries and implements windows-specific functions from\n// sanitizer_libc.h.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_platform.h\"\n#if SANITIZER_WINDOWS\n\n#define WIN32_LEAN_AND_MEAN\n#define NOGDI\n#include <windows.h>\n#include <dbghelp.h>\n#include <io.h>\n#include <psapi.h>\n#include <stdlib.h>\n\n#include \"sanitizer_common.h\"\n#include \"sanitizer_libc.h\"\n#include \"sanitizer_mutex.h\"\n#include \"sanitizer_placement_new.h\"\n#include \"sanitizer_stacktrace.h\"\n\nnamespace __sanitizer {\n\n#include \"sanitizer_syscall_generic.inc\"\n\n// --------------------- sanitizer_common.h\nuptr GetPageSize() {\n  // FIXME: there is an API for getting the system page size (GetSystemInfo or\n  // GetNativeSystemInfo), but if we use it here we get test failures elsewhere.\n  return 1U << 14;\n}\n\nuptr GetMmapGranularity() {\n  return 1U << 16;  // FIXME: is this configurable?\n}\n\nuptr GetMaxVirtualAddress() {\n  SYSTEM_INFO si;\n  GetSystemInfo(&si);\n  return (uptr)si.lpMaximumApplicationAddress;\n}\n\nbool FileExists(const char *filename) {\n  return ::GetFileAttributesA(filename) != INVALID_FILE_ATTRIBUTES;\n}\n\nuptr internal_getpid() {\n  return GetProcessId(GetCurrentProcess());\n}\n\n// In contrast to POSIX, on Windows GetCurrentThreadId()\n// returns a system-unique identifier.\nuptr GetTid() {\n  return GetCurrentThreadId();\n}\n\nuptr GetThreadSelf() {\n  return GetTid();\n}\n\n#if !SANITIZER_GO\nvoid GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,\n                                uptr *stack_bottom) {\n  CHECK(stack_top);\n  CHECK(stack_bottom);\n  MEMORY_BASIC_INFORMATION mbi;\n  CHECK_NE(VirtualQuery(&mbi /* on stack */, &mbi, sizeof(mbi)), 0);\n  // FIXME: is it possible for the stack to not be a single allocation?\n  // Are these values what ASan expects to get (reserved, not committed;\n  // including stack guard page) ?\n  *stack_top = (uptr)mbi.BaseAddress + mbi.RegionSize;\n  *stack_bottom = (uptr)mbi.AllocationBase;\n}\n#endif  // #if !SANITIZER_GO\n\nvoid *MmapOrDie(uptr size, const char *mem_type, bool raw_report) {\n  void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);\n  if (rv == 0)\n    ReportMmapFailureAndDie(size, mem_type, \"allocate\",\n                            GetLastError(), raw_report);\n  return rv;\n}\n\nvoid UnmapOrDie(void *addr, uptr size) {\n  if (!size || !addr)\n    return;\n\n  if (VirtualFree(addr, size, MEM_DECOMMIT) == 0) {\n    Report(\"ERROR: %s failed to \"\n           \"deallocate 0x%zx (%zd) bytes at address %p (error code: %d)\\n\",\n           SanitizerToolName, size, size, addr, GetLastError());\n    CHECK(\"unable to unmap\" && 0);\n  }\n}\n\nvoid *MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) {\n  // FIXME: is this really \"NoReserve\"? On Win32 this does not matter much,\n  // but on Win64 it does.\n  (void)name; // unsupported\n  void *p = VirtualAlloc((LPVOID)fixed_addr, size,\n      MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);\n  if (p == 0)\n    Report(\"ERROR: %s failed to \"\n           \"allocate %p (%zd) bytes at %p (error code: %d)\\n\",\n           SanitizerToolName, size, size, fixed_addr, GetLastError());\n  return p;\n}\n\nvoid *MmapFixedOrDie(uptr fixed_addr, uptr size) {\n  return MmapFixedNoReserve(fixed_addr, size);\n}\n\nvoid *MmapNoReserveOrDie(uptr size, const char *mem_type) {\n  // FIXME: make this really NoReserve?\n  return MmapOrDie(size, mem_type);\n}\n\nvoid *MmapNoAccess(uptr fixed_addr, uptr size, const char *name) {\n  (void)name; // unsupported\n  void *res = VirtualAlloc((LPVOID)fixed_addr, size,\n                           MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS);\n  if (res == 0)\n    Report(\"WARNING: %s failed to \"\n           \"mprotect %p (%zd) bytes at %p (error code: %d)\\n\",\n           SanitizerToolName, size, size, fixed_addr, GetLastError());\n  return res;\n}\n\nbool MprotectNoAccess(uptr addr, uptr size) {\n  DWORD old_protection;\n  return VirtualProtect((LPVOID)addr, size, PAGE_NOACCESS, &old_protection);\n}\n\n\nvoid FlushUnneededShadowMemory(uptr addr, uptr size) {\n  // This is almost useless on 32-bits.\n  // FIXME: add madvise-analog when we move to 64-bits.\n}\n\nvoid NoHugePagesInRegion(uptr addr, uptr size) {\n  // FIXME: probably similar to FlushUnneededShadowMemory.\n}\n\nvoid DontDumpShadowMemory(uptr addr, uptr length) {\n  // This is almost useless on 32-bits.\n  // FIXME: add madvise-analog when we move to 64-bits.\n}\n\nbool MemoryRangeIsAvailable(uptr range_start, uptr range_end) {\n  MEMORY_BASIC_INFORMATION mbi;\n  CHECK(VirtualQuery((void *)range_start, &mbi, sizeof(mbi)));\n  return mbi.Protect == PAGE_NOACCESS &&\n         (uptr)mbi.BaseAddress + mbi.RegionSize >= range_end;\n}\n\nvoid *MapFileToMemory(const char *file_name, uptr *buff_size) {\n  UNIMPLEMENTED();\n}\n\nvoid *MapWritableFileToMemory(void *addr, uptr size, fd_t fd, OFF_T offset) {\n  UNIMPLEMENTED();\n}\n\nstatic const int kMaxEnvNameLength = 128;\nstatic const DWORD kMaxEnvValueLength = 32767;\n\nnamespace {\n\nstruct EnvVariable {\n  char name[kMaxEnvNameLength];\n  char value[kMaxEnvValueLength];\n};\n\n}  // namespace\n\nstatic const int kEnvVariables = 5;\nstatic EnvVariable env_vars[kEnvVariables];\nstatic int num_env_vars;\n\nconst char *GetEnv(const char *name) {\n  // Note: this implementation caches the values of the environment variables\n  // and limits their quantity.\n  for (int i = 0; i < num_env_vars; i++) {\n    if (0 == internal_strcmp(name, env_vars[i].name))\n      return env_vars[i].value;\n  }\n  CHECK_LT(num_env_vars, kEnvVariables);\n  DWORD rv = GetEnvironmentVariableA(name, env_vars[num_env_vars].value,\n                                     kMaxEnvValueLength);\n  if (rv > 0 && rv < kMaxEnvValueLength) {\n    CHECK_LT(internal_strlen(name), kMaxEnvNameLength);\n    internal_strncpy(env_vars[num_env_vars].name, name, kMaxEnvNameLength);\n    num_env_vars++;\n    return env_vars[num_env_vars - 1].value;\n  }\n  return 0;\n}\n\nconst char *GetPwd() {\n  UNIMPLEMENTED();\n}\n\nu32 GetUid() {\n  UNIMPLEMENTED();\n}\n\nnamespace {\nstruct ModuleInfo {\n  const char *filepath;\n  uptr base_address;\n  uptr end_address;\n};\n\n#ifndef SANITIZER_GO\nint CompareModulesBase(const void *pl, const void *pr) {\n  const ModuleInfo *l = (ModuleInfo *)pl, *r = (ModuleInfo *)pr;\n  if (l->base_address < r->base_address)\n    return -1;\n  return l->base_address > r->base_address;\n}\n#endif\n}  // namespace\n\n#ifndef SANITIZER_GO\nvoid DumpProcessMap() {\n  Report(\"Dumping process modules:\\n\");\n  InternalScopedBuffer<LoadedModule> modules(kMaxNumberOfModules);\n  uptr num_modules =\n      GetListOfModules(modules.data(), kMaxNumberOfModules, nullptr);\n\n  InternalScopedBuffer<ModuleInfo> module_infos(num_modules);\n  for (size_t i = 0; i < num_modules; ++i) {\n    module_infos[i].filepath = modules[i].full_name();\n    module_infos[i].base_address = modules[i].base_address();\n    module_infos[i].end_address = modules[i].ranges().next()->end;\n  }\n  qsort(module_infos.data(), num_modules, sizeof(ModuleInfo),\n        CompareModulesBase);\n\n  for (size_t i = 0; i < num_modules; ++i) {\n    const ModuleInfo &mi = module_infos[i];\n    if (mi.end_address != 0) {\n      Printf(\"\\t%p-%p %s\\n\", mi.base_address, mi.end_address,\n             mi.filepath[0] ? mi.filepath : \"[no name]\");\n    } else if (mi.filepath[0]) {\n      Printf(\"\\t??\\?-??? %s\\n\", mi.filepath);\n    } else {\n      Printf(\"\\t???\\n\");\n    }\n  }\n}\n#endif\n\nvoid DisableCoreDumperIfNecessary() {\n  // Do nothing.\n}\n\nvoid ReExec() {\n  UNIMPLEMENTED();\n}\n\nvoid PrepareForSandboxing(__sanitizer_sandbox_arguments *args) {\n#if !SANITIZER_GO\n  CovPrepareForSandboxing(args);\n#endif\n}\n\nbool StackSizeIsUnlimited() {\n  UNIMPLEMENTED();\n}\n\nvoid SetStackSizeLimitInBytes(uptr limit) {\n  UNIMPLEMENTED();\n}\n\nbool AddressSpaceIsUnlimited() {\n  UNIMPLEMENTED();\n}\n\nvoid SetAddressSpaceUnlimited() {\n  UNIMPLEMENTED();\n}\n\nbool IsPathSeparator(const char c) {\n  return c == '\\\\' || c == '/';\n}\n\nbool IsAbsolutePath(const char *path) {\n  UNIMPLEMENTED();\n}\n\nvoid SleepForSeconds(int seconds) {\n  Sleep(seconds * 1000);\n}\n\nvoid SleepForMillis(int millis) {\n  Sleep(millis);\n}\n\nu64 NanoTime() {\n  return 0;\n}\n\nvoid Abort() {\n  if (::IsDebuggerPresent())\n    __debugbreak();\n  internal__exit(3);\n}\n\n// Read the file to extract the ImageBase field from the PE header. If ASLR is\n// disabled and this virtual address is available, the loader will typically\n// load the image at this address. Therefore, we call it the preferred base. Any\n// addresses in the DWARF typically assume that the object has been loaded at\n// this address.\nstatic uptr GetPreferredBase(const char *modname) {\n  fd_t fd = OpenFile(modname, RdOnly, nullptr);\n  if (fd == kInvalidFd)\n    return 0;\n  FileCloser closer(fd);\n\n  // Read just the DOS header.\n  IMAGE_DOS_HEADER dos_header;\n  uptr bytes_read;\n  if (!ReadFromFile(fd, &dos_header, sizeof(dos_header), &bytes_read) ||\n      bytes_read != sizeof(dos_header))\n    return 0;\n\n  // The file should start with the right signature.\n  if (dos_header.e_magic != IMAGE_DOS_SIGNATURE)\n    return 0;\n\n  // The layout at e_lfanew is:\n  // \"PE\\0\\0\"\n  // IMAGE_FILE_HEADER\n  // IMAGE_OPTIONAL_HEADER\n  // Seek to e_lfanew and read all that data.\n  char buf[4 + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_OPTIONAL_HEADER)];\n  if (::SetFilePointer(fd, dos_header.e_lfanew, nullptr, FILE_BEGIN) ==\n      INVALID_SET_FILE_POINTER)\n    return 0;\n  if (!ReadFromFile(fd, &buf[0], sizeof(buf), &bytes_read) ||\n      bytes_read != sizeof(buf))\n    return 0;\n\n  // Check for \"PE\\0\\0\" before the PE header.\n  char *pe_sig = &buf[0];\n  if (internal_memcmp(pe_sig, \"PE\\0\\0\", 4) != 0)\n    return 0;\n\n  // Skip over IMAGE_FILE_HEADER. We could do more validation here if we wanted.\n  IMAGE_OPTIONAL_HEADER *pe_header =\n      (IMAGE_OPTIONAL_HEADER *)(pe_sig + 4 + sizeof(IMAGE_FILE_HEADER));\n\n  // Check for more magic in the PE header.\n  if (pe_header->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)\n    return 0;\n\n  // Finally, return the ImageBase.\n  return (uptr)pe_header->ImageBase;\n}\n\n#ifndef SANITIZER_GO\nuptr GetListOfModules(LoadedModule *modules, uptr max_modules,\n                      string_predicate_t filter) {\n  HANDLE cur_process = GetCurrentProcess();\n\n  // Query the list of modules.  Start by assuming there are no more than 256\n  // modules and retry if that's not sufficient.\n  HMODULE *hmodules = 0;\n  uptr modules_buffer_size = sizeof(HMODULE) * 256;\n  DWORD bytes_required;\n  while (!hmodules) {\n    hmodules = (HMODULE *)MmapOrDie(modules_buffer_size, __FUNCTION__);\n    CHECK(EnumProcessModules(cur_process, hmodules, modules_buffer_size,\n                             &bytes_required));\n    if (bytes_required > modules_buffer_size) {\n      // Either there turned out to be more than 256 hmodules, or new hmodules\n      // could have loaded since the last try.  Retry.\n      UnmapOrDie(hmodules, modules_buffer_size);\n      hmodules = 0;\n      modules_buffer_size = bytes_required;\n    }\n  }\n\n  // |num_modules| is the number of modules actually present,\n  // |count| is the number of modules we return.\n  size_t nun_modules = bytes_required / sizeof(HMODULE),\n         count = 0;\n  for (size_t i = 0; i < nun_modules && count < max_modules; ++i) {\n    HMODULE handle = hmodules[i];\n    MODULEINFO mi;\n    if (!GetModuleInformation(cur_process, handle, &mi, sizeof(mi)))\n      continue;\n\n    // Get the UTF-16 path and convert to UTF-8.\n    wchar_t modname_utf16[kMaxPathLength];\n    int modname_utf16_len =\n        GetModuleFileNameW(handle, modname_utf16, kMaxPathLength);\n    if (modname_utf16_len == 0)\n      modname_utf16[0] = '\\0';\n    char module_name[kMaxPathLength];\n    int module_name_len =\n        ::WideCharToMultiByte(CP_UTF8, 0, modname_utf16, modname_utf16_len + 1,\n                              &module_name[0], kMaxPathLength, NULL, NULL);\n    module_name[module_name_len] = '\\0';\n\n    if (filter && !filter(module_name))\n      continue;\n\n    uptr base_address = (uptr)mi.lpBaseOfDll;\n    uptr end_address = (uptr)mi.lpBaseOfDll + mi.SizeOfImage;\n\n    // Adjust the base address of the module so that we get a VA instead of an\n    // RVA when computing the module offset. This helps llvm-symbolizer find the\n    // right DWARF CU. In the common case that the image is loaded at it's\n    // preferred address, we will now print normal virtual addresses.\n    uptr preferred_base = GetPreferredBase(&module_name[0]);\n    uptr adjusted_base = base_address - preferred_base;\n\n    LoadedModule *cur_module = &modules[count];\n    cur_module->set(module_name, adjusted_base);\n    // We add the whole module as one single address range.\n    cur_module->addAddressRange(base_address, end_address, /*executable*/ true);\n    count++;\n  }\n  UnmapOrDie(hmodules, modules_buffer_size);\n\n  return count;\n};\n\n// We can't use atexit() directly at __asan_init time as the CRT is not fully\n// initialized at this point.  Place the functions into a vector and use\n// atexit() as soon as it is ready for use (i.e. after .CRT$XIC initializers).\nInternalMmapVectorNoCtor<void (*)(void)> atexit_functions;\n\nint Atexit(void (*function)(void)) {\n  atexit_functions.push_back(function);\n  return 0;\n}\n\nstatic int RunAtexit() {\n  int ret = 0;\n  for (uptr i = 0; i < atexit_functions.size(); ++i) {\n    ret |= atexit(atexit_functions[i]);\n  }\n  return ret;\n}\n\n#pragma section(\".CRT$XID\", long, read)  // NOLINT\n__declspec(allocate(\".CRT$XID\")) int (*__run_atexit)() = RunAtexit;\n#endif\n\n// ------------------ sanitizer_libc.h\nfd_t OpenFile(const char *filename, FileAccessMode mode, error_t *last_error) {\n  fd_t res;\n  if (mode == RdOnly) {\n    res = CreateFile(filename, GENERIC_READ,\n                     FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,\n                     nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);\n  } else if (mode == WrOnly) {\n    res = CreateFile(filename, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS,\n                     FILE_ATTRIBUTE_NORMAL, nullptr);\n  } else {\n    UNIMPLEMENTED();\n  }\n  CHECK(res != kStdoutFd || kStdoutFd == kInvalidFd);\n  CHECK(res != kStderrFd || kStderrFd == kInvalidFd);\n  if (res == kInvalidFd && last_error)\n    *last_error = GetLastError();\n  return res;\n}\n\nvoid CloseFile(fd_t fd) {\n  CloseHandle(fd);\n}\n\nbool ReadFromFile(fd_t fd, void *buff, uptr buff_size, uptr *bytes_read,\n                  error_t *error_p) {\n  CHECK(fd != kInvalidFd);\n\n  // bytes_read can't be passed directly to ReadFile:\n  // uptr is unsigned long long on 64-bit Windows.\n  unsigned long num_read_long;\n\n  bool success = ::ReadFile(fd, buff, buff_size, &num_read_long, nullptr);\n  if (!success && error_p)\n    *error_p = GetLastError();\n  if (bytes_read)\n    *bytes_read = num_read_long;\n  return success;\n}\n\nbool SupportsColoredOutput(fd_t fd) {\n  // FIXME: support colored output.\n  return false;\n}\n\nbool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written,\n                 error_t *error_p) {\n  CHECK(fd != kInvalidFd);\n\n  // Handle null optional parameters.\n  error_t dummy_error;\n  error_p = error_p ? error_p : &dummy_error;\n  uptr dummy_bytes_written;\n  bytes_written = bytes_written ? bytes_written : &dummy_bytes_written;\n\n  // Initialize output parameters in case we fail.\n  *error_p = 0;\n  *bytes_written = 0;\n\n  // Map the conventional Unix fds 1 and 2 to Windows handles. They might be\n  // closed, in which case this will fail.\n  if (fd == kStdoutFd || fd == kStderrFd) {\n    fd = GetStdHandle(fd == kStdoutFd ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);\n    if (fd == 0) {\n      *error_p = ERROR_INVALID_HANDLE;\n      return false;\n    }\n  }\n\n  DWORD bytes_written_32;\n  if (!WriteFile(fd, buff, buff_size, &bytes_written_32, 0)) {\n    *error_p = GetLastError();\n    return false;\n  } else {\n    *bytes_written = bytes_written_32;\n    return true;\n  }\n}\n\nbool RenameFile(const char *oldpath, const char *newpath, error_t *error_p) {\n  UNIMPLEMENTED();\n}\n\nuptr internal_sched_yield() {\n  Sleep(0);\n  return 0;\n}\n\nvoid internal__exit(int exitcode) {\n  ExitProcess(exitcode);\n}\n\nuptr internal_ftruncate(fd_t fd, uptr size) {\n  UNIMPLEMENTED();\n}\n\nuptr GetRSS() {\n  return 0;\n}\n\nvoid *internal_start_thread(void (*func)(void *arg), void *arg) { return 0; }\nvoid internal_join_thread(void *th) { }\n\n// ---------------------- BlockingMutex ---------------- {{{1\nconst uptr LOCK_UNINITIALIZED = 0;\nconst uptr LOCK_READY = (uptr)-1;\n\nBlockingMutex::BlockingMutex(LinkerInitialized li) {\n  // FIXME: see comments in BlockingMutex::Lock() for the details.\n  CHECK(li == LINKER_INITIALIZED || owner_ == LOCK_UNINITIALIZED);\n\n  CHECK(sizeof(CRITICAL_SECTION) <= sizeof(opaque_storage_));\n  InitializeCriticalSection((LPCRITICAL_SECTION)opaque_storage_);\n  owner_ = LOCK_READY;\n}\n\nBlockingMutex::BlockingMutex() {\n  CHECK(sizeof(CRITICAL_SECTION) <= sizeof(opaque_storage_));\n  InitializeCriticalSection((LPCRITICAL_SECTION)opaque_storage_);\n  owner_ = LOCK_READY;\n}\n\nvoid BlockingMutex::Lock() {\n  if (owner_ == LOCK_UNINITIALIZED) {\n    // FIXME: hm, global BlockingMutex objects are not initialized?!?\n    // This might be a side effect of the clang+cl+link Frankenbuild...\n    new(this) BlockingMutex((LinkerInitialized)(LINKER_INITIALIZED + 1));\n\n    // FIXME: If it turns out the linker doesn't invoke our\n    // constructors, we should probably manually Lock/Unlock all the global\n    // locks while we're starting in one thread to avoid double-init races.\n  }\n  EnterCriticalSection((LPCRITICAL_SECTION)opaque_storage_);\n  CHECK_EQ(owner_, LOCK_READY);\n  owner_ = GetThreadSelf();\n}\n\nvoid BlockingMutex::Unlock() {\n  CHECK_EQ(owner_, GetThreadSelf());\n  owner_ = LOCK_READY;\n  LeaveCriticalSection((LPCRITICAL_SECTION)opaque_storage_);\n}\n\nvoid BlockingMutex::CheckLocked() {\n  CHECK_EQ(owner_, GetThreadSelf());\n}\n\nuptr GetTlsSize() {\n  return 0;\n}\n\nvoid InitTlsSize() {\n}\n\nvoid GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,\n                          uptr *tls_addr, uptr *tls_size) {\n#ifdef SANITIZER_GO\n  *stk_addr = 0;\n  *stk_size = 0;\n  *tls_addr = 0;\n  *tls_size = 0;\n#else\n  uptr stack_top, stack_bottom;\n  GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);\n  *stk_addr = stack_bottom;\n  *stk_size = stack_top - stack_bottom;\n  *tls_addr = 0;\n  *tls_size = 0;\n#endif\n}\n\n#if !SANITIZER_GO\nvoid BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) {\n  CHECK_GE(max_depth, 2);\n  // FIXME: CaptureStackBackTrace might be too slow for us.\n  // FIXME: Compare with StackWalk64.\n  // FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc\n  size = CaptureStackBackTrace(2, Min(max_depth, kStackTraceMax),\n                               (void**)trace, 0);\n  if (size == 0)\n    return;\n\n  // Skip the RTL frames by searching for the PC in the stacktrace.\n  uptr pc_location = LocatePcInTrace(pc);\n  PopStackFrames(pc_location);\n}\n\nvoid BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context,\n                                                    u32 max_depth) {\n  CONTEXT ctx = *(CONTEXT *)context;\n  STACKFRAME64 stack_frame;\n  memset(&stack_frame, 0, sizeof(stack_frame));\n  size = 0;\n#if defined(_WIN64)\n  int machine_type = IMAGE_FILE_MACHINE_AMD64;\n  stack_frame.AddrPC.Offset = ctx.Rip;\n  stack_frame.AddrFrame.Offset = ctx.Rbp;\n  stack_frame.AddrStack.Offset = ctx.Rsp;\n#else\n  int machine_type = IMAGE_FILE_MACHINE_I386;\n  stack_frame.AddrPC.Offset = ctx.Eip;\n  stack_frame.AddrFrame.Offset = ctx.Ebp;\n  stack_frame.AddrStack.Offset = ctx.Esp;\n#endif\n  stack_frame.AddrPC.Mode = AddrModeFlat;\n  stack_frame.AddrFrame.Mode = AddrModeFlat;\n  stack_frame.AddrStack.Mode = AddrModeFlat;\n  while (StackWalk64(machine_type, GetCurrentProcess(), GetCurrentThread(),\n                     &stack_frame, &ctx, NULL, &SymFunctionTableAccess64,\n                     &SymGetModuleBase64, NULL) &&\n         size < Min(max_depth, kStackTraceMax)) {\n    trace_buffer[size++] = (uptr)stack_frame.AddrPC.Offset;\n  }\n}\n#endif  // #if !SANITIZER_GO\n\nvoid ReportFile::Write(const char *buffer, uptr length) {\n  SpinMutexLock l(mu);\n  ReopenIfNecessary();\n  if (!WriteToFile(fd, buffer, length)) {\n    // stderr may be closed, but we may be able to print to the debugger\n    // instead.  This is the case when launching a program from Visual Studio,\n    // and the following routine should write to its console.\n    OutputDebugStringA(buffer);\n  }\n}\n\nvoid SetAlternateSignalStack() {\n  // FIXME: Decide what to do on Windows.\n}\n\nvoid UnsetAlternateSignalStack() {\n  // FIXME: Decide what to do on Windows.\n}\n\nvoid InstallDeadlySignalHandlers(SignalHandlerType handler) {\n  (void)handler;\n  // FIXME: Decide what to do on Windows.\n}\n\nbool IsDeadlySignal(int signum) {\n  // FIXME: Decide what to do on Windows.\n  return false;\n}\n\nbool IsAccessibleMemoryRange(uptr beg, uptr size) {\n  SYSTEM_INFO si;\n  GetNativeSystemInfo(&si);\n  uptr page_size = si.dwPageSize;\n  uptr page_mask = ~(page_size - 1);\n\n  for (uptr page = beg & page_mask, end = (beg + size - 1) & page_mask;\n       page <= end;) {\n    MEMORY_BASIC_INFORMATION info;\n    if (VirtualQuery((LPCVOID)page, &info, sizeof(info)) != sizeof(info))\n      return false;\n\n    if (info.Protect == 0 || info.Protect == PAGE_NOACCESS ||\n        info.Protect == PAGE_EXECUTE)\n      return false;\n\n    if (info.RegionSize == 0)\n      return false;\n\n    page += info.RegionSize;\n  }\n\n  return true;\n}\n\nSignalContext SignalContext::Create(void *siginfo, void *context) {\n  EXCEPTION_RECORD *exception_record = (EXCEPTION_RECORD*)siginfo;\n  CONTEXT *context_record = (CONTEXT*)context;\n\n  uptr pc = (uptr)exception_record->ExceptionAddress;\n#ifdef _WIN64\n  uptr bp = (uptr)context_record->Rbp;\n  uptr sp = (uptr)context_record->Rsp;\n#else\n  uptr bp = (uptr)context_record->Ebp;\n  uptr sp = (uptr)context_record->Esp;\n#endif\n  uptr access_addr = exception_record->ExceptionInformation[1];\n\n  return SignalContext(context, access_addr, pc, sp, bp);\n}\n\nuptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {\n  // FIXME: Actually implement this function.\n  CHECK_GT(buf_len, 0);\n  buf[0] = 0;\n  return 0;\n}\n\nuptr ReadLongProcessName(/*out*/char *buf, uptr buf_len) {\n  return ReadBinaryName(buf, buf_len);\n}\n\nvoid CheckVMASize() {\n  // Do nothing.\n}\n\nvoid DisableReexec() {\n  // No need to re-exec on Windows.\n}\n\nvoid MaybeReexec() {\n  // No need to re-exec on Windows.\n}\n\n}  // namespace __sanitizer\n\n#endif  // _WIN32\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/scripts/check_lint.sh",
    "content": "#!/bin/sh\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\n# Guess path to LLVM_CHECKOUT if not provided\nif [ \"${LLVM_CHECKOUT}\" = \"\" ]; then\n  LLVM_CHECKOUT=\"${SCRIPT_DIR}/../../../../../\"\nfi\n\n# python tools setup\nCPPLINT=${SCRIPT_DIR}/cpplint.py\nLITLINT=${SCRIPT_DIR}/litlint.py\nif [ \"${PYTHON_EXECUTABLE}\" != \"\" ]; then\n  CPPLINT=\"${PYTHON_EXECUTABLE} ${CPPLINT}\"\n  LITLINT=\"${PYTHON_EXECUTABLE} ${LITLINT}\"\nfi\n\n# Filters\n# TODO: remove some of these filters\nCOMMON_LINT_FILTER=-build/include,-build/header_guard,-legal/copyright,-whitespace/comments,-readability/casting,\\\n-build/namespaces\nASAN_RTL_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/int\nASAN_TEST_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/sizeof,-runtime/int,-runtime/printf,-runtime/threadsafe_fn\nASAN_LIT_TEST_LINT_FILTER=${ASAN_TEST_LINT_FILTER},-whitespace/line_length\nTSAN_RTL_LINT_FILTER=${COMMON_LINT_FILTER}\nTSAN_TEST_LINT_FILTER=${TSAN_RTL_LINT_FILTER},-runtime/threadsafe_fn,-runtime/int\nTSAN_LIT_TEST_LINT_FILTER=${TSAN_TEST_LINT_FILTER},-whitespace/line_length\nMSAN_RTL_LINT_FILTER=${COMMON_LINT_FILTER}\nLSAN_RTL_LINT_FILTER=${COMMON_LINT_FILTER}\nLSAN_LIT_TEST_LINT_FILTER=${LSAN_RTL_LINT_FILTER},-whitespace/line_length\nDFSAN_RTL_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/int,-runtime/printf,-runtime/references,-readability/function\nCOMMON_RTL_INC_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/int,-runtime/sizeof,-runtime/printf,-readability/fn_size\nSANITIZER_INCLUDES_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/int\n\nMKTEMP_DIR=$(mktemp -qd /tmp/check_lint.XXXXXXXXXX)\nMKTEMP=\"mktemp -q ${MKTEMP_DIR}/tmp.XXXXXXXXXX\"\ncleanup() {\n  rm -rf $MKTEMP_DIR\n}\ntrap cleanup EXIT\n\ncd ${LLVM_CHECKOUT}\n\nEXITSTATUS=0\nERROR_LOG=$(${MKTEMP})\n\nrun_lint() {\n  FILTER=$1\n  shift\n  TASK_LOG=$(${MKTEMP})\n  ${CPPLINT} --filter=${FILTER} \"$@\" 2>$TASK_LOG\n  if [ \"$?\" != \"0\" ]; then\n    cat $TASK_LOG | grep -v \"Done processing\" | grep -v \"Total errors found\" \\\n      | grep -v \"Skipping input\" >> $ERROR_LOG\n  fi\n  if [ \"${SILENT}\" != \"1\" ]; then\n    cat $TASK_LOG\n  fi\n  ${LITLINT} \"$@\" 2>>$ERROR_LOG\n}\n\nif [ \"${COMPILER_RT}\" = \"\" ]; then\n  COMPILER_RT=projects/compiler-rt\nfi\nLIT_TESTS=${COMPILER_RT}/test\n# Headers\nSANITIZER_INCLUDES=${COMPILER_RT}/include/sanitizer\nrun_lint ${SANITIZER_INCLUDES_LINT_FILTER} ${SANITIZER_INCLUDES}/*.h &\n\n# Sanitizer_common\nCOMMON_RTL=${COMPILER_RT}/lib/sanitizer_common\nrun_lint ${COMMON_RTL_INC_LINT_FILTER} ${COMMON_RTL}/*.cc \\\n                                       ${COMMON_RTL}/*.h \\\n                                       ${COMMON_RTL}/tests/*.cc &\n\n# Interception\nINTERCEPTION=${COMPILER_RT}/lib/interception\nrun_lint ${ASAN_RTL_LINT_FILTER} ${INTERCEPTION}/*.cc \\\n                                 ${INTERCEPTION}/*.h &\n\n# ASan\nASAN_RTL=${COMPILER_RT}/lib/asan\nrun_lint ${ASAN_RTL_LINT_FILTER} ${ASAN_RTL}/*.cc \\\n                                 ${ASAN_RTL}/*.h &\nrun_lint ${ASAN_TEST_LINT_FILTER} ${ASAN_RTL}/tests/*.cc \\\n                                  ${ASAN_RTL}/tests/*.h &\nrun_lint ${ASAN_LIT_TEST_LINT_FILTER} ${LIT_TESTS}/asan/*/*.cc &\n\n# TSan\nTSAN_RTL=${COMPILER_RT}/lib/tsan\nrun_lint ${TSAN_RTL_LINT_FILTER} ${TSAN_RTL}/rtl/*.cc \\\n                                 ${TSAN_RTL}/rtl/*.h &\nrun_lint ${TSAN_TEST_LINT_FILTER} ${TSAN_RTL}/tests/rtl/*.cc \\\n                                  ${TSAN_RTL}/tests/rtl/*.h \\\n                                  ${TSAN_RTL}/tests/unit/*.cc &\nrun_lint ${TSAN_LIT_TEST_LINT_FILTER} ${LIT_TESTS}/tsan/*.cc &\n\n# MSan\nMSAN_RTL=${COMPILER_RT}/lib/msan\nrun_lint ${MSAN_RTL_LINT_FILTER} ${MSAN_RTL}/*.cc \\\n                                 ${MSAN_RTL}/*.h &\n\n# LSan\nLSAN_RTL=${COMPILER_RT}/lib/lsan\nrun_lint ${LSAN_RTL_LINT_FILTER} ${LSAN_RTL}/*.cc \\\n                                 ${LSAN_RTL}/*.h &\nrun_lint ${LSAN_LIT_TEST_LINT_FILTER} ${LIT_TESTS}/lsan/*/*.cc &\n\n# DFSan\nDFSAN_RTL=${COMPILER_RT}/lib/dfsan\nrun_lint ${DFSAN_RTL_LINT_FILTER} ${DFSAN_RTL}/*.cc \\\n                                  ${DFSAN_RTL}/*.h &\n${DFSAN_RTL}/scripts/check_custom_wrappers.sh >> $ERROR_LOG\n\n# Misc files\nFILES=${COMMON_RTL}/*.inc\nTMPFILES=\"\"\nfor FILE in $FILES; do\n  TMPFILE=\"$(${MKTEMP}).$(basename ${FILE}).cc\"\n  cp -f $FILE $TMPFILE\n  run_lint ${COMMON_RTL_INC_LINT_FILTER} $TMPFILE &\n  TMPFILES=\"$TMPFILES $TMPFILE\"\ndone\n\nwait\n\nfor temp in $TMPFILES; do\n  rm -f $temp\ndone\n\nif [ -s $ERROR_LOG ]; then\n  cat $ERROR_LOG\n  exit 1\nfi\n\nexit 0\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/scripts/cpplint.py",
    "content": "#!/usr/bin/env python\n#\n# Copyright (c) 2009 Google Inc. All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are\n# met:\n#\n#    * Redistributions of source code must retain the above copyright\n# notice, this list of conditions and the following disclaimer.\n#    * Redistributions in binary form must reproduce the above\n# copyright notice, this list of conditions and the following disclaimer\n# in the documentation and/or other materials provided with the\n# distribution.\n#    * Neither the name of Google Inc. nor the names of its\n# contributors may be used to endorse or promote products derived from\n# this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n# Here are some issues that I've had people identify in my code during reviews,\n# that I think are possible to flag automatically in a lint tool.  If these were\n# caught by lint, it would save time both for myself and that of my reviewers.\n# Most likely, some of these are beyond the scope of the current lint framework,\n# but I think it is valuable to retain these wish-list items even if they cannot\n# be immediately implemented.\n#\n#  Suggestions\n#  -----------\n#  - Check for no 'explicit' for multi-arg ctor\n#  - Check for boolean assign RHS in parens\n#  - Check for ctor initializer-list colon position and spacing\n#  - Check that if there's a ctor, there should be a dtor\n#  - Check accessors that return non-pointer member variables are\n#    declared const\n#  - Check accessors that return non-const pointer member vars are\n#    *not* declared const\n#  - Check for using public includes for testing\n#  - Check for spaces between brackets in one-line inline method\n#  - Check for no assert()\n#  - Check for spaces surrounding operators\n#  - Check for 0 in pointer context (should be NULL)\n#  - Check for 0 in char context (should be '\\0')\n#  - Check for camel-case method name conventions for methods\n#    that are not simple inline getters and setters\n#  - Do not indent namespace contents\n#  - Avoid inlining non-trivial constructors in header files\n#  - Check for old-school (void) cast for call-sites of functions\n#    ignored return value\n#  - Check gUnit usage of anonymous namespace\n#  - Check for class declaration order (typedefs, consts, enums,\n#    ctor(s?), dtor, friend declarations, methods, member vars)\n#\n\n\"\"\"Does google-lint on c++ files.\n\nThe goal of this script is to identify places in the code that *may*\nbe in non-compliance with google style.  It does not attempt to fix\nup these problems -- the point is to educate.  It does also not\nattempt to find all problems, or to ensure that everything it does\nfind is legitimately a problem.\n\nIn particular, we can get very confused by /* and // inside strings!\nWe do a small hack, which is to ignore //'s with \"'s after them on the\nsame line, but it is far from perfect (in either direction).\n\"\"\"\n\nimport codecs\nimport copy\nimport getopt\nimport math  # for log\nimport os\nimport re\nimport sre_compile\nimport string\nimport sys\nimport unicodedata\n\n\n_USAGE = \"\"\"\nSyntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]\n                   [--counting=total|toplevel|detailed]\n        <file> [file] ...\n\n  The style guidelines this tries to follow are those in\n    http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml\n\n  Every problem is given a confidence score from 1-5, with 5 meaning we are\n  certain of the problem, and 1 meaning it could be a legitimate construct.\n  This will miss some errors, and is not a substitute for a code review.\n\n  To suppress false-positive errors of a certain category, add a\n  'NOLINT(category)' comment to the line.  NOLINT or NOLINT(*)\n  suppresses errors of all categories on that line.\n\n  The files passed in will be linted; at least one file must be provided.\n  Linted extensions are .cc, .cpp, and .h.  Other file types will be ignored.\n\n  Flags:\n\n    output=vs7\n      By default, the output is formatted to ease emacs parsing.  Visual Studio\n      compatible output (vs7) may also be used.  Other formats are unsupported.\n\n    verbose=#\n      Specify a number 0-5 to restrict errors to certain verbosity levels.\n\n    filter=-x,+y,...\n      Specify a comma-separated list of category-filters to apply: only\n      error messages whose category names pass the filters will be printed.\n      (Category names are printed with the message and look like\n      \"[whitespace/indent]\".)  Filters are evaluated left to right.\n      \"-FOO\" and \"FOO\" means \"do not print categories that start with FOO\".\n      \"+FOO\" means \"do print categories that start with FOO\".\n\n      Examples: --filter=-whitespace,+whitespace/braces\n                --filter=whitespace,runtime/printf,+runtime/printf_format\n                --filter=-,+build/include_what_you_use\n\n      To see a list of all the categories used in cpplint, pass no arg:\n         --filter=\n\n    counting=total|toplevel|detailed\n      The total number of errors found is always printed. If\n      'toplevel' is provided, then the count of errors in each of\n      the top-level categories like 'build' and 'whitespace' will\n      also be printed. If 'detailed' is provided, then a count\n      is provided for each category like 'build/class'.\n\n    root=subdir\n      The root directory used for deriving header guard CPP variable.\n      By default, the header guard CPP variable is calculated as the relative\n      path to the directory that contains .git, .hg, or .svn.  When this flag\n      is specified, the relative path is calculated from the specified\n      directory. If the specified directory does not exist, this flag is\n      ignored.\n\n      Examples:\n        Assuing that src/.git exists, the header guard CPP variables for\n        src/chrome/browser/ui/browser.h are:\n\n        No flag => CHROME_BROWSER_UI_BROWSER_H_\n        --root=chrome => BROWSER_UI_BROWSER_H_\n        --root=chrome/browser => UI_BROWSER_H_\n\"\"\"\n\n# We categorize each error message we print.  Here are the categories.\n# We want an explicit list so we can list them all in cpplint --filter=.\n# If you add a new error message with a new category, add it to the list\n# here!  cpplint_unittest.py should tell you if you forget to do this.\n# \\ used for clearer layout -- pylint: disable-msg=C6013\n_ERROR_CATEGORIES = [\n  'build/class',\n  'build/deprecated',\n  'build/endif_comment',\n  'build/explicit_make_pair',\n  'build/forward_decl',\n  'build/header_guard',\n  'build/include',\n  'build/include_alpha',\n  'build/include_order',\n  'build/include_what_you_use',\n  'build/namespaces',\n  'build/printf_format',\n  'build/storage_class',\n  'legal/copyright',\n  'readability/alt_tokens',\n  'readability/braces',\n  'readability/casting',\n  'readability/check',\n  'readability/constructors',\n  'readability/fn_size',\n  'readability/function',\n  'readability/multiline_comment',\n  'readability/multiline_string',\n  'readability/namespace',\n  'readability/nolint',\n  'readability/streams',\n  'readability/todo',\n  'readability/utf8',\n  'runtime/arrays',\n  'runtime/casting',\n  'runtime/explicit',\n  'runtime/int',\n  'runtime/init',\n  'runtime/invalid_increment',\n  'runtime/member_string_references',\n  'runtime/memset',\n  'runtime/operator',\n  'runtime/printf',\n  'runtime/printf_format',\n  'runtime/references',\n  'runtime/rtti',\n  'runtime/sizeof',\n  'runtime/string',\n  'runtime/threadsafe_fn',\n  'whitespace/blank_line',\n  'whitespace/braces',\n  'whitespace/comma',\n  'whitespace/comments',\n  'whitespace/empty_loop_body',\n  'whitespace/end_of_line',\n  'whitespace/ending_newline',\n  'whitespace/forcolon',\n  'whitespace/indent',\n  'whitespace/labels',\n  'whitespace/line_length',\n  'whitespace/newline',\n  'whitespace/operators',\n  'whitespace/parens',\n  'whitespace/semicolon',\n  'whitespace/tab',\n  'whitespace/todo'\n  ]\n\n# The default state of the category filter. This is overrided by the --filter=\n# flag. By default all errors are on, so only add here categories that should be\n# off by default (i.e., categories that must be enabled by the --filter= flags).\n# All entries here should start with a '-' or '+', as in the --filter= flag.\n_DEFAULT_FILTERS = ['-build/include_alpha']\n\n# We used to check for high-bit characters, but after much discussion we\n# decided those were OK, as long as they were in UTF-8 and didn't represent\n# hard-coded international strings, which belong in a separate i18n file.\n\n# Headers that we consider STL headers.\n_STL_HEADERS = frozenset([\n    'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception',\n    'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set',\n    'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'new',\n    'pair.h', 'pthread_alloc', 'queue', 'set', 'set.h', 'sstream', 'stack',\n    'stl_alloc.h', 'stl_relops.h', 'type_traits.h',\n    'utility', 'vector', 'vector.h',\n    ])\n\n\n# Non-STL C++ system headers.\n_CPP_HEADERS = frozenset([\n    'algo.h', 'builtinbuf.h', 'bvector.h', 'cassert', 'cctype',\n    'cerrno', 'cfloat', 'ciso646', 'climits', 'clocale', 'cmath',\n    'complex', 'complex.h', 'csetjmp', 'csignal', 'cstdarg', 'cstddef',\n    'cstdio', 'cstdlib', 'cstring', 'ctime', 'cwchar', 'cwctype',\n    'defalloc.h', 'deque.h', 'editbuf.h', 'exception', 'fstream',\n    'fstream.h', 'hashtable.h', 'heap.h', 'indstream.h', 'iomanip',\n    'iomanip.h', 'ios', 'iosfwd', 'iostream', 'iostream.h', 'istream',\n    'istream.h', 'iterator.h', 'limits', 'map.h', 'multimap.h', 'multiset.h',\n    'numeric', 'ostream', 'ostream.h', 'parsestream.h', 'pfstream.h',\n    'PlotFile.h', 'procbuf.h', 'pthread_alloc.h', 'rope', 'rope.h',\n    'ropeimpl.h', 'SFile.h', 'slist', 'slist.h', 'stack.h', 'stdexcept',\n    'stdiostream.h', 'streambuf', 'streambuf.h', 'stream.h', 'strfile.h',\n    'string', 'strstream', 'strstream.h', 'tempbuf.h', 'tree.h', 'typeinfo',\n    'valarray',\n    ])\n\n\n# Assertion macros.  These are defined in base/logging.h and\n# testing/base/gunit.h.  Note that the _M versions need to come first\n# for substring matching to work.\n_CHECK_MACROS = [\n    'DCHECK', 'CHECK',\n    'EXPECT_TRUE_M', 'EXPECT_TRUE',\n    'ASSERT_TRUE_M', 'ASSERT_TRUE',\n    'EXPECT_FALSE_M', 'EXPECT_FALSE',\n    'ASSERT_FALSE_M', 'ASSERT_FALSE',\n    ]\n\n# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE\n_CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS])\n\nfor op, replacement in [('==', 'EQ'), ('!=', 'NE'),\n                        ('>=', 'GE'), ('>', 'GT'),\n                        ('<=', 'LE'), ('<', 'LT')]:\n  _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement\n  _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement\n  _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement\n  _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement\n  _CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement\n  _CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement\n\nfor op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'),\n                            ('>=', 'LT'), ('>', 'LE'),\n                            ('<=', 'GT'), ('<', 'GE')]:\n  _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement\n  _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement\n  _CHECK_REPLACEMENT['EXPECT_FALSE_M'][op] = 'EXPECT_%s_M' % inv_replacement\n  _CHECK_REPLACEMENT['ASSERT_FALSE_M'][op] = 'ASSERT_%s_M' % inv_replacement\n\n# Alternative tokens and their replacements.  For full list, see section 2.5\n# Alternative tokens [lex.digraph] in the C++ standard.\n#\n# Digraphs (such as '%:') are not included here since it's a mess to\n# match those on a word boundary.\n_ALT_TOKEN_REPLACEMENT = {\n    'and': '&&',\n    'bitor': '|',\n    'or': '||',\n    'xor': '^',\n    'compl': '~',\n    'bitand': '&',\n    'and_eq': '&=',\n    'or_eq': '|=',\n    'xor_eq': '^=',\n    'not': '!',\n    'not_eq': '!='\n    }\n\n# Compile regular expression that matches all the above keywords.  The \"[ =()]\"\n# bit is meant to avoid matching these keywords outside of boolean expressions.\n#\n# False positives include C-style multi-line comments (http://go/nsiut )\n# and multi-line strings (http://go/beujw ), but those have always been\n# troublesome for cpplint.\n_ALT_TOKEN_REPLACEMENT_PATTERN = re.compile(\n    r'[ =()](' + ('|'.join(_ALT_TOKEN_REPLACEMENT.keys())) + r')(?=[ (]|$)')\n\n\n# These constants define types of headers for use with\n# _IncludeState.CheckNextIncludeOrder().\n_C_SYS_HEADER = 1\n_CPP_SYS_HEADER = 2\n_LIKELY_MY_HEADER = 3\n_POSSIBLE_MY_HEADER = 4\n_OTHER_HEADER = 5\n\n# These constants define the current inline assembly state\n_NO_ASM = 0       # Outside of inline assembly block\n_INSIDE_ASM = 1   # Inside inline assembly block\n_END_ASM = 2      # Last line of inline assembly block\n_BLOCK_ASM = 3    # The whole block is an inline assembly block\n\n# Match start of assembly blocks\n_MATCH_ASM = re.compile(r'^\\s*(?:asm|_asm|__asm|__asm__)'\n                        r'(?:\\s+(volatile|__volatile__))?'\n                        r'\\s*[{(]')\n\n\n_regexp_compile_cache = {}\n\n# Finds occurrences of NOLINT or NOLINT(...).\n_RE_SUPPRESSION = re.compile(r'\\bNOLINT\\b(\\([^)]*\\))?')\n\n# {str, set(int)}: a map from error categories to sets of linenumbers\n# on which those errors are expected and should be suppressed.\n_error_suppressions = {}\n\n# The root directory used for deriving header guard CPP variable.\n# This is set by --root flag.\n_root = None\n\ndef ParseNolintSuppressions(filename, raw_line, linenum, error):\n  \"\"\"Updates the global list of error-suppressions.\n\n  Parses any NOLINT comments on the current line, updating the global\n  error_suppressions store.  Reports an error if the NOLINT comment\n  was malformed.\n\n  Args:\n    filename: str, the name of the input file.\n    raw_line: str, the line of input text, with comments.\n    linenum: int, the number of the current line.\n    error: function, an error handler.\n  \"\"\"\n  # FIXME(adonovan): \"NOLINT(\" is misparsed as NOLINT(*).\n  matched = _RE_SUPPRESSION.search(raw_line)\n  if matched:\n    category = matched.group(1)\n    if category in (None, '(*)'):  # => \"suppress all\"\n      _error_suppressions.setdefault(None, set()).add(linenum)\n    else:\n      if category.startswith('(') and category.endswith(')'):\n        category = category[1:-1]\n        if category in _ERROR_CATEGORIES:\n          _error_suppressions.setdefault(category, set()).add(linenum)\n        else:\n          error(filename, linenum, 'readability/nolint', 5,\n                'Unknown NOLINT error category: %s' % category)\n\n\ndef ResetNolintSuppressions():\n  \"Resets the set of NOLINT suppressions to empty.\"\n  _error_suppressions.clear()\n\n\ndef IsErrorSuppressedByNolint(category, linenum):\n  \"\"\"Returns true if the specified error category is suppressed on this line.\n\n  Consults the global error_suppressions map populated by\n  ParseNolintSuppressions/ResetNolintSuppressions.\n\n  Args:\n    category: str, the category of the error.\n    linenum: int, the current line number.\n  Returns:\n    bool, True iff the error should be suppressed due to a NOLINT comment.\n  \"\"\"\n  return (linenum in _error_suppressions.get(category, set()) or\n          linenum in _error_suppressions.get(None, set()))\n\ndef Match(pattern, s):\n  \"\"\"Matches the string with the pattern, caching the compiled regexp.\"\"\"\n  # The regexp compilation caching is inlined in both Match and Search for\n  # performance reasons; factoring it out into a separate function turns out\n  # to be noticeably expensive.\n  if not pattern in _regexp_compile_cache:\n    _regexp_compile_cache[pattern] = sre_compile.compile(pattern)\n  return _regexp_compile_cache[pattern].match(s)\n\n\ndef Search(pattern, s):\n  \"\"\"Searches the string for the pattern, caching the compiled regexp.\"\"\"\n  if not pattern in _regexp_compile_cache:\n    _regexp_compile_cache[pattern] = sre_compile.compile(pattern)\n  return _regexp_compile_cache[pattern].search(s)\n\n\nclass _IncludeState(dict):\n  \"\"\"Tracks line numbers for includes, and the order in which includes appear.\n\n  As a dict, an _IncludeState object serves as a mapping between include\n  filename and line number on which that file was included.\n\n  Call CheckNextIncludeOrder() once for each header in the file, passing\n  in the type constants defined above. Calls in an illegal order will\n  raise an _IncludeError with an appropriate error message.\n\n  \"\"\"\n  # self._section will move monotonically through this set. If it ever\n  # needs to move backwards, CheckNextIncludeOrder will raise an error.\n  _INITIAL_SECTION = 0\n  _MY_H_SECTION = 1\n  _C_SECTION = 2\n  _CPP_SECTION = 3\n  _OTHER_H_SECTION = 4\n\n  _TYPE_NAMES = {\n      _C_SYS_HEADER: 'C system header',\n      _CPP_SYS_HEADER: 'C++ system header',\n      _LIKELY_MY_HEADER: 'header this file implements',\n      _POSSIBLE_MY_HEADER: 'header this file may implement',\n      _OTHER_HEADER: 'other header',\n      }\n  _SECTION_NAMES = {\n      _INITIAL_SECTION: \"... nothing. (This can't be an error.)\",\n      _MY_H_SECTION: 'a header this file implements',\n      _C_SECTION: 'C system header',\n      _CPP_SECTION: 'C++ system header',\n      _OTHER_H_SECTION: 'other header',\n      }\n\n  def __init__(self):\n    dict.__init__(self)\n    # The name of the current section.\n    self._section = self._INITIAL_SECTION\n    # The path of last found header.\n    self._last_header = ''\n\n  def CanonicalizeAlphabeticalOrder(self, header_path):\n    \"\"\"Returns a path canonicalized for alphabetical comparison.\n\n    - replaces \"-\" with \"_\" so they both cmp the same.\n    - removes '-inl' since we don't require them to be after the main header.\n    - lowercase everything, just in case.\n\n    Args:\n      header_path: Path to be canonicalized.\n\n    Returns:\n      Canonicalized path.\n    \"\"\"\n    return header_path.replace('-inl.h', '.h').replace('-', '_').lower()\n\n  def IsInAlphabeticalOrder(self, header_path):\n    \"\"\"Check if a header is in alphabetical order with the previous header.\n\n    Args:\n      header_path: Header to be checked.\n\n    Returns:\n      Returns true if the header is in alphabetical order.\n    \"\"\"\n    canonical_header = self.CanonicalizeAlphabeticalOrder(header_path)\n    if self._last_header > canonical_header:\n      return False\n    self._last_header = canonical_header\n    return True\n\n  def CheckNextIncludeOrder(self, header_type):\n    \"\"\"Returns a non-empty error message if the next header is out of order.\n\n    This function also updates the internal state to be ready to check\n    the next include.\n\n    Args:\n      header_type: One of the _XXX_HEADER constants defined above.\n\n    Returns:\n      The empty string if the header is in the right order, or an\n      error message describing what's wrong.\n\n    \"\"\"\n    error_message = ('Found %s after %s' %\n                     (self._TYPE_NAMES[header_type],\n                      self._SECTION_NAMES[self._section]))\n\n    last_section = self._section\n\n    if header_type == _C_SYS_HEADER:\n      if self._section <= self._C_SECTION:\n        self._section = self._C_SECTION\n      else:\n        self._last_header = ''\n        return error_message\n    elif header_type == _CPP_SYS_HEADER:\n      if self._section <= self._CPP_SECTION:\n        self._section = self._CPP_SECTION\n      else:\n        self._last_header = ''\n        return error_message\n    elif header_type == _LIKELY_MY_HEADER:\n      if self._section <= self._MY_H_SECTION:\n        self._section = self._MY_H_SECTION\n      else:\n        self._section = self._OTHER_H_SECTION\n    elif header_type == _POSSIBLE_MY_HEADER:\n      if self._section <= self._MY_H_SECTION:\n        self._section = self._MY_H_SECTION\n      else:\n        # This will always be the fallback because we're not sure\n        # enough that the header is associated with this file.\n        self._section = self._OTHER_H_SECTION\n    else:\n      assert header_type == _OTHER_HEADER\n      self._section = self._OTHER_H_SECTION\n\n    if last_section != self._section:\n      self._last_header = ''\n\n    return ''\n\n\nclass _CppLintState(object):\n  \"\"\"Maintains module-wide state..\"\"\"\n\n  def __init__(self):\n    self.verbose_level = 1  # global setting.\n    self.error_count = 0    # global count of reported errors\n    # filters to apply when emitting error messages\n    self.filters = _DEFAULT_FILTERS[:]\n    self.counting = 'total'  # In what way are we counting errors?\n    self.errors_by_category = {}  # string to int dict storing error counts\n\n    # output format:\n    # \"emacs\" - format that emacs can parse (default)\n    # \"vs7\" - format that Microsoft Visual Studio 7 can parse\n    self.output_format = 'emacs'\n\n  def SetOutputFormat(self, output_format):\n    \"\"\"Sets the output format for errors.\"\"\"\n    self.output_format = output_format\n\n  def SetVerboseLevel(self, level):\n    \"\"\"Sets the module's verbosity, and returns the previous setting.\"\"\"\n    last_verbose_level = self.verbose_level\n    self.verbose_level = level\n    return last_verbose_level\n\n  def SetCountingStyle(self, counting_style):\n    \"\"\"Sets the module's counting options.\"\"\"\n    self.counting = counting_style\n\n  def SetFilters(self, filters):\n    \"\"\"Sets the error-message filters.\n\n    These filters are applied when deciding whether to emit a given\n    error message.\n\n    Args:\n      filters: A string of comma-separated filters (eg \"+whitespace/indent\").\n               Each filter should start with + or -; else we die.\n\n    Raises:\n      ValueError: The comma-separated filters did not all start with '+' or '-'.\n                  E.g. \"-,+whitespace,-whitespace/indent,whitespace/badfilter\"\n    \"\"\"\n    # Default filters always have less priority than the flag ones.\n    self.filters = _DEFAULT_FILTERS[:]\n    for filt in filters.split(','):\n      clean_filt = filt.strip()\n      if clean_filt:\n        self.filters.append(clean_filt)\n    for filt in self.filters:\n      if not (filt.startswith('+') or filt.startswith('-')):\n        raise ValueError('Every filter in --filters must start with + or -'\n                         ' (%s does not)' % filt)\n\n  def ResetErrorCounts(self):\n    \"\"\"Sets the module's error statistic back to zero.\"\"\"\n    self.error_count = 0\n    self.errors_by_category = {}\n\n  def IncrementErrorCount(self, category):\n    \"\"\"Bumps the module's error statistic.\"\"\"\n    self.error_count += 1\n    if self.counting in ('toplevel', 'detailed'):\n      if self.counting != 'detailed':\n        category = category.split('/')[0]\n      if category not in self.errors_by_category:\n        self.errors_by_category[category] = 0\n      self.errors_by_category[category] += 1\n\n  def PrintErrorCounts(self):\n    \"\"\"Print a summary of errors by category, and the total.\"\"\"\n    for category, count in self.errors_by_category.iteritems():\n      sys.stderr.write('Category \\'%s\\' errors found: %d\\n' %\n                       (category, count))\n    sys.stderr.write('Total errors found: %d\\n' % self.error_count)\n\n_cpplint_state = _CppLintState()\n\n\ndef _OutputFormat():\n  \"\"\"Gets the module's output format.\"\"\"\n  return _cpplint_state.output_format\n\n\ndef _SetOutputFormat(output_format):\n  \"\"\"Sets the module's output format.\"\"\"\n  _cpplint_state.SetOutputFormat(output_format)\n\n\ndef _VerboseLevel():\n  \"\"\"Returns the module's verbosity setting.\"\"\"\n  return _cpplint_state.verbose_level\n\n\ndef _SetVerboseLevel(level):\n  \"\"\"Sets the module's verbosity, and returns the previous setting.\"\"\"\n  return _cpplint_state.SetVerboseLevel(level)\n\n\ndef _SetCountingStyle(level):\n  \"\"\"Sets the module's counting options.\"\"\"\n  _cpplint_state.SetCountingStyle(level)\n\n\ndef _Filters():\n  \"\"\"Returns the module's list of output filters, as a list.\"\"\"\n  return _cpplint_state.filters\n\n\ndef _SetFilters(filters):\n  \"\"\"Sets the module's error-message filters.\n\n  These filters are applied when deciding whether to emit a given\n  error message.\n\n  Args:\n    filters: A string of comma-separated filters (eg \"whitespace/indent\").\n             Each filter should start with + or -; else we die.\n  \"\"\"\n  _cpplint_state.SetFilters(filters)\n\n\nclass _FunctionState(object):\n  \"\"\"Tracks current function name and the number of lines in its body.\"\"\"\n\n  _NORMAL_TRIGGER = 250  # for --v=0, 500 for --v=1, etc.\n  _TEST_TRIGGER = 400    # about 50% more than _NORMAL_TRIGGER.\n\n  def __init__(self):\n    self.in_a_function = False\n    self.lines_in_function = 0\n    self.current_function = ''\n\n  def Begin(self, function_name):\n    \"\"\"Start analyzing function body.\n\n    Args:\n      function_name: The name of the function being tracked.\n    \"\"\"\n    self.in_a_function = True\n    self.lines_in_function = 0\n    self.current_function = function_name\n\n  def Count(self):\n    \"\"\"Count line in current function body.\"\"\"\n    if self.in_a_function:\n      self.lines_in_function += 1\n\n  def Check(self, error, filename, linenum):\n    \"\"\"Report if too many lines in function body.\n\n    Args:\n      error: The function to call with any errors found.\n      filename: The name of the current file.\n      linenum: The number of the line to check.\n    \"\"\"\n    if Match(r'T(EST|est)', self.current_function):\n      base_trigger = self._TEST_TRIGGER\n    else:\n      base_trigger = self._NORMAL_TRIGGER\n    trigger = base_trigger * 2**_VerboseLevel()\n\n    if self.lines_in_function > trigger:\n      error_level = int(math.log(self.lines_in_function / base_trigger, 2))\n      # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ...\n      if error_level > 5:\n        error_level = 5\n      error(filename, linenum, 'readability/fn_size', error_level,\n            'Small and focused functions are preferred:'\n            ' %s has %d non-comment lines'\n            ' (error triggered by exceeding %d lines).'  % (\n                self.current_function, self.lines_in_function, trigger))\n\n  def End(self):\n    \"\"\"Stop analyzing function body.\"\"\"\n    self.in_a_function = False\n\n\nclass _IncludeError(Exception):\n  \"\"\"Indicates a problem with the include order in a file.\"\"\"\n  pass\n\n\nclass FileInfo:\n  \"\"\"Provides utility functions for filenames.\n\n  FileInfo provides easy access to the components of a file's path\n  relative to the project root.\n  \"\"\"\n\n  def __init__(self, filename):\n    self._filename = filename\n\n  def FullName(self):\n    \"\"\"Make Windows paths like Unix.\"\"\"\n    return os.path.abspath(self._filename).replace('\\\\', '/')\n\n  def RepositoryName(self):\n    \"\"\"FullName after removing the local path to the repository.\n\n    If we have a real absolute path name here we can try to do something smart:\n    detecting the root of the checkout and truncating /path/to/checkout from\n    the name so that we get header guards that don't include things like\n    \"C:\\Documents and Settings\\...\" or \"/home/username/...\" in them and thus\n    people on different computers who have checked the source out to different\n    locations won't see bogus errors.\n    \"\"\"\n    fullname = self.FullName()\n\n    if os.path.exists(fullname):\n      project_dir = os.path.dirname(fullname)\n\n      if os.path.exists(os.path.join(project_dir, \".svn\")):\n        # If there's a .svn file in the current directory, we recursively look\n        # up the directory tree for the top of the SVN checkout\n        root_dir = project_dir\n        one_up_dir = os.path.dirname(root_dir)\n        while os.path.exists(os.path.join(one_up_dir, \".svn\")):\n          root_dir = os.path.dirname(root_dir)\n          one_up_dir = os.path.dirname(one_up_dir)\n\n        prefix = os.path.commonprefix([root_dir, project_dir])\n        return fullname[len(prefix) + 1:]\n\n      # Not SVN <= 1.6? Try to find a git, hg, or svn top level directory by\n      # searching up from the current path.\n      root_dir = os.path.dirname(fullname)\n      while (root_dir != os.path.dirname(root_dir) and\n             not os.path.exists(os.path.join(root_dir, \".git\")) and\n             not os.path.exists(os.path.join(root_dir, \".hg\")) and\n             not os.path.exists(os.path.join(root_dir, \".svn\"))):\n        root_dir = os.path.dirname(root_dir)\n\n      if (os.path.exists(os.path.join(root_dir, \".git\")) or\n          os.path.exists(os.path.join(root_dir, \".hg\")) or\n          os.path.exists(os.path.join(root_dir, \".svn\"))):\n        prefix = os.path.commonprefix([root_dir, project_dir])\n        return fullname[len(prefix) + 1:]\n\n    # Don't know what to do; header guard warnings may be wrong...\n    return fullname\n\n  def Split(self):\n    \"\"\"Splits the file into the directory, basename, and extension.\n\n    For 'chrome/browser/browser.cc', Split() would\n    return ('chrome/browser', 'browser', '.cc')\n\n    Returns:\n      A tuple of (directory, basename, extension).\n    \"\"\"\n\n    googlename = self.RepositoryName()\n    project, rest = os.path.split(googlename)\n    return (project,) + os.path.splitext(rest)\n\n  def BaseName(self):\n    \"\"\"File base name - text after the final slash, before the final period.\"\"\"\n    return self.Split()[1]\n\n  def Extension(self):\n    \"\"\"File extension - text following the final period.\"\"\"\n    return self.Split()[2]\n\n  def NoExtension(self):\n    \"\"\"File has no source file extension.\"\"\"\n    return '/'.join(self.Split()[0:2])\n\n  def IsSource(self):\n    \"\"\"File has a source file extension.\"\"\"\n    return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx')\n\n\ndef _ShouldPrintError(category, confidence, linenum):\n  \"\"\"If confidence >= verbose, category passes filter and is not suppressed.\"\"\"\n\n  # There are three ways we might decide not to print an error message:\n  # a \"NOLINT(category)\" comment appears in the source,\n  # the verbosity level isn't high enough, or the filters filter it out.\n  if IsErrorSuppressedByNolint(category, linenum):\n    return False\n  if confidence < _cpplint_state.verbose_level:\n    return False\n\n  is_filtered = False\n  for one_filter in _Filters():\n    if one_filter.startswith('-'):\n      if category.startswith(one_filter[1:]):\n        is_filtered = True\n    elif one_filter.startswith('+'):\n      if category.startswith(one_filter[1:]):\n        is_filtered = False\n    else:\n      assert False  # should have been checked for in SetFilter.\n  if is_filtered:\n    return False\n\n  return True\n\n\ndef Error(filename, linenum, category, confidence, message):\n  \"\"\"Logs the fact we've found a lint error.\n\n  We log where the error was found, and also our confidence in the error,\n  that is, how certain we are this is a legitimate style regression, and\n  not a misidentification or a use that's sometimes justified.\n\n  False positives can be suppressed by the use of\n  \"cpplint(category)\"  comments on the offending line.  These are\n  parsed into _error_suppressions.\n\n  Args:\n    filename: The name of the file containing the error.\n    linenum: The number of the line containing the error.\n    category: A string used to describe the \"category\" this bug\n      falls under: \"whitespace\", say, or \"runtime\".  Categories\n      may have a hierarchy separated by slashes: \"whitespace/indent\".\n    confidence: A number from 1-5 representing a confidence score for\n      the error, with 5 meaning that we are certain of the problem,\n      and 1 meaning that it could be a legitimate construct.\n    message: The error message.\n  \"\"\"\n  if _ShouldPrintError(category, confidence, linenum):\n    _cpplint_state.IncrementErrorCount(category)\n    if _cpplint_state.output_format == 'vs7':\n      sys.stderr.write('%s(%s):  %s  [%s] [%d]\\n' % (\n          filename, linenum, message, category, confidence))\n    elif _cpplint_state.output_format == 'eclipse':\n      sys.stderr.write('%s:%s: warning: %s  [%s] [%d]\\n' % (\n          filename, linenum, message, category, confidence))\n    else:\n      sys.stderr.write('%s:%s:  %s  [%s] [%d]\\n' % (\n          filename, linenum, message, category, confidence))\n\n\n# Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard.\n_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile(\n    r'\\\\([abfnrtv?\"\\\\\\']|\\d+|x[0-9a-fA-F]+)')\n# Matches strings.  Escape codes should already be removed by ESCAPES.\n_RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'\"[^\"]*\"')\n# Matches characters.  Escape codes should already be removed by ESCAPES.\n_RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r\"'.'\")\n# Matches multi-line C++ comments.\n# This RE is a little bit more complicated than one might expect, because we\n# have to take care of space removals tools so we can handle comments inside\n# statements better.\n# The current rule is: We only clear spaces from both sides when we're at the\n# end of the line. Otherwise, we try to remove spaces from the right side,\n# if this doesn't work we try on left side but only if there's a non-character\n# on the right.\n_RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile(\n    r\"\"\"(\\s*/\\*.*\\*/\\s*$|\n            /\\*.*\\*/\\s+|\n         \\s+/\\*.*\\*/(?=\\W)|\n            /\\*.*\\*/)\"\"\", re.VERBOSE)\n\n\ndef IsCppString(line):\n  \"\"\"Does line terminate so, that the next symbol is in string constant.\n\n  This function does not consider single-line nor multi-line comments.\n\n  Args:\n    line: is a partial line of code starting from the 0..n.\n\n  Returns:\n    True, if next character appended to 'line' is inside a\n    string constant.\n  \"\"\"\n\n  line = line.replace(r'\\\\', 'XX')  # after this, \\\\\" does not match to \\\"\n  return ((line.count('\"') - line.count(r'\\\"') - line.count(\"'\\\"'\")) & 1) == 1\n\n\ndef FindNextMultiLineCommentStart(lines, lineix):\n  \"\"\"Find the beginning marker for a multiline comment.\"\"\"\n  while lineix < len(lines):\n    if lines[lineix].strip().startswith('/*'):\n      # Only return this marker if the comment goes beyond this line\n      if lines[lineix].strip().find('*/', 2) < 0:\n        return lineix\n    lineix += 1\n  return len(lines)\n\n\ndef FindNextMultiLineCommentEnd(lines, lineix):\n  \"\"\"We are inside a comment, find the end marker.\"\"\"\n  while lineix < len(lines):\n    if lines[lineix].strip().endswith('*/'):\n      return lineix\n    lineix += 1\n  return len(lines)\n\n\ndef RemoveMultiLineCommentsFromRange(lines, begin, end):\n  \"\"\"Clears a range of lines for multi-line comments.\"\"\"\n  # Having // dummy comments makes the lines non-empty, so we will not get\n  # unnecessary blank line warnings later in the code.\n  for i in range(begin, end):\n    lines[i] = '// dummy'\n\n\ndef RemoveMultiLineComments(filename, lines, error):\n  \"\"\"Removes multiline (c-style) comments from lines.\"\"\"\n  lineix = 0\n  while lineix < len(lines):\n    lineix_begin = FindNextMultiLineCommentStart(lines, lineix)\n    if lineix_begin >= len(lines):\n      return\n    lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin)\n    if lineix_end >= len(lines):\n      error(filename, lineix_begin + 1, 'readability/multiline_comment', 5,\n            'Could not find end of multi-line comment')\n      return\n    RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1)\n    lineix = lineix_end + 1\n\n\ndef CleanseComments(line):\n  \"\"\"Removes //-comments and single-line C-style /* */ comments.\n\n  Args:\n    line: A line of C++ source.\n\n  Returns:\n    The line with single-line comments removed.\n  \"\"\"\n  commentpos = line.find('//')\n  if commentpos != -1 and not IsCppString(line[:commentpos]):\n    line = line[:commentpos].rstrip()\n  # get rid of /* ... */\n  return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line)\n\n\nclass CleansedLines(object):\n  \"\"\"Holds 3 copies of all lines with different preprocessing applied to them.\n\n  1) elided member contains lines without strings and comments,\n  2) lines member contains lines without comments, and\n  3) raw_lines member contains all the lines without processing.\n  All these three members are of <type 'list'>, and of the same length.\n  \"\"\"\n\n  def __init__(self, lines):\n    self.elided = []\n    self.lines = []\n    self.raw_lines = lines\n    self.num_lines = len(lines)\n    for linenum in range(len(lines)):\n      self.lines.append(CleanseComments(lines[linenum]))\n      elided = self._CollapseStrings(lines[linenum])\n      self.elided.append(CleanseComments(elided))\n\n  def NumLines(self):\n    \"\"\"Returns the number of lines represented.\"\"\"\n    return self.num_lines\n\n  @staticmethod\n  def _CollapseStrings(elided):\n    \"\"\"Collapses strings and chars on a line to simple \"\" or '' blocks.\n\n    We nix strings first so we're not fooled by text like '\"http://\"'\n\n    Args:\n      elided: The line being processed.\n\n    Returns:\n      The line with collapsed strings.\n    \"\"\"\n    if not _RE_PATTERN_INCLUDE.match(elided):\n      # Remove escaped characters first to make quote/single quote collapsing\n      # basic.  Things that look like escaped characters shouldn't occur\n      # outside of strings and chars.\n      elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided)\n      elided = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub(\"''\", elided)\n      elided = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub('\"\"', elided)\n    return elided\n\n\ndef FindEndOfExpressionInLine(line, startpos, depth, startchar, endchar):\n  \"\"\"Find the position just after the matching endchar.\n\n  Args:\n    line: a CleansedLines line.\n    startpos: start searching at this position.\n    depth: nesting level at startpos.\n    startchar: expression opening character.\n    endchar: expression closing character.\n\n  Returns:\n    Index just after endchar.\n  \"\"\"\n  for i in xrange(startpos, len(line)):\n    if line[i] == startchar:\n      depth += 1\n    elif line[i] == endchar:\n      depth -= 1\n      if depth == 0:\n        return i + 1\n  return -1\n\n\ndef CloseExpression(clean_lines, linenum, pos):\n  \"\"\"If input points to ( or { or [, finds the position that closes it.\n\n  If lines[linenum][pos] points to a '(' or '{' or '[', finds the\n  linenum/pos that correspond to the closing of the expression.\n\n  Args:\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    pos: A position on the line.\n\n  Returns:\n    A tuple (line, linenum, pos) pointer *past* the closing brace, or\n    (line, len(lines), -1) if we never find a close.  Note we ignore\n    strings and comments when matching; and the line we return is the\n    'cleansed' line at linenum.\n  \"\"\"\n\n  line = clean_lines.elided[linenum]\n  startchar = line[pos]\n  if startchar not in '({[':\n    return (line, clean_lines.NumLines(), -1)\n  if startchar == '(': endchar = ')'\n  if startchar == '[': endchar = ']'\n  if startchar == '{': endchar = '}'\n\n  # Check first line\n  end_pos = FindEndOfExpressionInLine(line, pos, 0, startchar, endchar)\n  if end_pos > -1:\n    return (line, linenum, end_pos)\n  tail = line[pos:]\n  num_open = tail.count(startchar) - tail.count(endchar)\n  while linenum < clean_lines.NumLines() - 1:\n    linenum += 1\n    line = clean_lines.elided[linenum]\n    delta = line.count(startchar) - line.count(endchar)\n    if num_open + delta <= 0:\n      return (line, linenum,\n              FindEndOfExpressionInLine(line, 0, num_open, startchar, endchar))\n    num_open += delta\n\n  # Did not find endchar before end of file, give up\n  return (line, clean_lines.NumLines(), -1)\n\ndef CheckForCopyright(filename, lines, error):\n  \"\"\"Logs an error if no Copyright message appears at the top of the file.\"\"\"\n\n  # We'll say it should occur by line 10. Don't forget there's a\n  # dummy line at the front.\n  for line in xrange(1, min(len(lines), 11)):\n    if re.search(r'Copyright', lines[line], re.I): break\n  else:                       # means no copyright line was found\n    error(filename, 0, 'legal/copyright', 5,\n          'No copyright message found.  '\n          'You should have a line: \"Copyright [year] <Copyright Owner>\"')\n\n\ndef GetHeaderGuardCPPVariable(filename):\n  \"\"\"Returns the CPP variable that should be used as a header guard.\n\n  Args:\n    filename: The name of a C++ header file.\n\n  Returns:\n    The CPP variable that should be used as a header guard in the\n    named file.\n\n  \"\"\"\n\n  # Restores original filename in case that cpplint is invoked from Emacs's\n  # flymake.\n  filename = re.sub(r'_flymake\\.h$', '.h', filename)\n  filename = re.sub(r'/\\.flymake/([^/]*)$', r'/\\1', filename)\n\n  fileinfo = FileInfo(filename)\n  file_path_from_root = fileinfo.RepositoryName()\n  if _root:\n    file_path_from_root = re.sub('^' + _root + os.sep, '', file_path_from_root)\n  return re.sub(r'[-./\\s]', '_', file_path_from_root).upper() + '_'\n\n\ndef CheckForHeaderGuard(filename, lines, error):\n  \"\"\"Checks that the file contains a header guard.\n\n  Logs an error if no #ifndef header guard is present.  For other\n  headers, checks that the full pathname is used.\n\n  Args:\n    filename: The name of the C++ header file.\n    lines: An array of strings, each representing a line of the file.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  cppvar = GetHeaderGuardCPPVariable(filename)\n\n  ifndef = None\n  ifndef_linenum = 0\n  define = None\n  endif = None\n  endif_linenum = 0\n  for linenum, line in enumerate(lines):\n    linesplit = line.split()\n    if len(linesplit) >= 2:\n      # find the first occurrence of #ifndef and #define, save arg\n      if not ifndef and linesplit[0] == '#ifndef':\n        # set ifndef to the header guard presented on the #ifndef line.\n        ifndef = linesplit[1]\n        ifndef_linenum = linenum\n      if not define and linesplit[0] == '#define':\n        define = linesplit[1]\n    # find the last occurrence of #endif, save entire line\n    if line.startswith('#endif'):\n      endif = line\n      endif_linenum = linenum\n\n  if not ifndef:\n    error(filename, 0, 'build/header_guard', 5,\n          'No #ifndef header guard found, suggested CPP variable is: %s' %\n          cppvar)\n    return\n\n  if not define:\n    error(filename, 0, 'build/header_guard', 5,\n          'No #define header guard found, suggested CPP variable is: %s' %\n          cppvar)\n    return\n\n  # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__\n  # for backward compatibility.\n  if ifndef != cppvar:\n    error_level = 0\n    if ifndef != cppvar + '_':\n      error_level = 5\n\n    ParseNolintSuppressions(filename, lines[ifndef_linenum], ifndef_linenum,\n                            error)\n    error(filename, ifndef_linenum, 'build/header_guard', error_level,\n          '#ifndef header guard has wrong style, please use: %s' % cppvar)\n\n  if define != ifndef:\n    error(filename, 0, 'build/header_guard', 5,\n          '#ifndef and #define don\\'t match, suggested CPP variable is: %s' %\n          cppvar)\n    return\n\n  if endif != ('#endif  // %s' % cppvar):\n    error_level = 0\n    if endif != ('#endif  // %s' % (cppvar + '_')):\n      error_level = 5\n\n    ParseNolintSuppressions(filename, lines[endif_linenum], endif_linenum,\n                            error)\n    error(filename, endif_linenum, 'build/header_guard', error_level,\n          '#endif line should be \"#endif  // %s\"' % cppvar)\n\n\ndef CheckForUnicodeReplacementCharacters(filename, lines, error):\n  \"\"\"Logs an error for each line containing Unicode replacement characters.\n\n  These indicate that either the file contained invalid UTF-8 (likely)\n  or Unicode replacement characters (which it shouldn't).  Note that\n  it's possible for this to throw off line numbering if the invalid\n  UTF-8 occurred adjacent to a newline.\n\n  Args:\n    filename: The name of the current file.\n    lines: An array of strings, each representing a line of the file.\n    error: The function to call with any errors found.\n  \"\"\"\n  for linenum, line in enumerate(lines):\n    if u'\\ufffd' in line:\n      error(filename, linenum, 'readability/utf8', 5,\n            'Line contains invalid UTF-8 (or Unicode replacement character).')\n\n\ndef CheckForNewlineAtEOF(filename, lines, error):\n  \"\"\"Logs an error if there is no newline char at the end of the file.\n\n  Args:\n    filename: The name of the current file.\n    lines: An array of strings, each representing a line of the file.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  # The array lines() was created by adding two newlines to the\n  # original file (go figure), then splitting on \\n.\n  # To verify that the file ends in \\n, we just have to make sure the\n  # last-but-two element of lines() exists and is empty.\n  if len(lines) < 3 or lines[-2]:\n    error(filename, len(lines) - 2, 'whitespace/ending_newline', 5,\n          'Could not find a newline character at the end of the file.')\n\n\ndef CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error):\n  \"\"\"Logs an error if we see /* ... */ or \"...\" that extend past one line.\n\n  /* ... */ comments are legit inside macros, for one line.\n  Otherwise, we prefer // comments, so it's ok to warn about the\n  other.  Likewise, it's ok for strings to extend across multiple\n  lines, as long as a line continuation character (backslash)\n  terminates each line. Although not currently prohibited by the C++\n  style guide, it's ugly and unnecessary. We don't do well with either\n  in this lint program, so we warn about both.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n\n  # Remove all \\\\ (escaped backslashes) from the line. They are OK, and the\n  # second (escaped) slash may trigger later \\\" detection erroneously.\n  line = line.replace('\\\\\\\\', '')\n\n  if line.count('/*') > line.count('*/'):\n    error(filename, linenum, 'readability/multiline_comment', 5,\n          'Complex multi-line /*...*/-style comment found. '\n          'Lint may give bogus warnings.  '\n          'Consider replacing these with //-style comments, '\n          'with #if 0...#endif, '\n          'or with more clearly structured multi-line comments.')\n\n  if (line.count('\"') - line.count('\\\\\"')) % 2:\n    error(filename, linenum, 'readability/multiline_string', 5,\n          'Multi-line string (\"...\") found.  This lint script doesn\\'t '\n          'do well with such strings, and may give bogus warnings.  They\\'re '\n          'ugly and unnecessary, and you should use concatenation instead\".')\n\n\nthreading_list = (\n    ('asctime(', 'asctime_r('),\n    ('ctime(', 'ctime_r('),\n    ('getgrgid(', 'getgrgid_r('),\n    ('getgrnam(', 'getgrnam_r('),\n    ('getlogin(', 'getlogin_r('),\n    ('getpwnam(', 'getpwnam_r('),\n    ('getpwuid(', 'getpwuid_r('),\n    ('gmtime(', 'gmtime_r('),\n    ('localtime(', 'localtime_r('),\n    ('rand(', 'rand_r('),\n    ('readdir(', 'readdir_r('),\n    ('strtok(', 'strtok_r('),\n    ('ttyname(', 'ttyname_r('),\n    )\n\n\ndef CheckPosixThreading(filename, clean_lines, linenum, error):\n  \"\"\"Checks for calls to thread-unsafe functions.\n\n  Much code has been originally written without consideration of\n  multi-threading. Also, engineers are relying on their old experience;\n  they have learned posix before threading extensions were added. These\n  tests guide the engineers to use thread-safe functions (when using\n  posix directly).\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n  for single_thread_function, multithread_safe_function in threading_list:\n    ix = line.find(single_thread_function)\n    # Comparisons made explicit for clarity -- pylint: disable-msg=C6403\n    if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and\n                                line[ix - 1] not in ('_', '.', '>'))):\n      error(filename, linenum, 'runtime/threadsafe_fn', 2,\n            'Consider using ' + multithread_safe_function +\n            '...) instead of ' + single_thread_function +\n            '...) for improved thread safety.')\n\n\n# Matches invalid increment: *count++, which moves pointer instead of\n# incrementing a value.\n_RE_PATTERN_INVALID_INCREMENT = re.compile(\n    r'^\\s*\\*\\w+(\\+\\+|--);')\n\n\ndef CheckInvalidIncrement(filename, clean_lines, linenum, error):\n  \"\"\"Checks for invalid increment *count++.\n\n  For example following function:\n  void increment_counter(int* count) {\n    *count++;\n  }\n  is invalid, because it effectively does count++, moving pointer, and should\n  be replaced with ++*count, (*count)++ or *count += 1.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n  if _RE_PATTERN_INVALID_INCREMENT.match(line):\n    error(filename, linenum, 'runtime/invalid_increment', 5,\n          'Changing pointer instead of value (or unused value of operator*).')\n\n\nclass _BlockInfo(object):\n  \"\"\"Stores information about a generic block of code.\"\"\"\n\n  def __init__(self, seen_open_brace):\n    self.seen_open_brace = seen_open_brace\n    self.open_parentheses = 0\n    self.inline_asm = _NO_ASM\n\n  def CheckBegin(self, filename, clean_lines, linenum, error):\n    \"\"\"Run checks that applies to text up to the opening brace.\n\n    This is mostly for checking the text after the class identifier\n    and the \"{\", usually where the base class is specified.  For other\n    blocks, there isn't much to check, so we always pass.\n\n    Args:\n      filename: The name of the current file.\n      clean_lines: A CleansedLines instance containing the file.\n      linenum: The number of the line to check.\n      error: The function to call with any errors found.\n    \"\"\"\n    pass\n\n  def CheckEnd(self, filename, clean_lines, linenum, error):\n    \"\"\"Run checks that applies to text after the closing brace.\n\n    This is mostly used for checking end of namespace comments.\n\n    Args:\n      filename: The name of the current file.\n      clean_lines: A CleansedLines instance containing the file.\n      linenum: The number of the line to check.\n      error: The function to call with any errors found.\n    \"\"\"\n    pass\n\n\nclass _ClassInfo(_BlockInfo):\n  \"\"\"Stores information about a class.\"\"\"\n\n  def __init__(self, name, class_or_struct, clean_lines, linenum):\n    _BlockInfo.__init__(self, False)\n    self.name = name\n    self.starting_linenum = linenum\n    self.is_derived = False\n    if class_or_struct == 'struct':\n      self.access = 'public'\n    else:\n      self.access = 'private'\n\n    # Try to find the end of the class.  This will be confused by things like:\n    #   class A {\n    #   } *x = { ...\n    #\n    # But it's still good enough for CheckSectionSpacing.\n    self.last_line = 0\n    depth = 0\n    for i in range(linenum, clean_lines.NumLines()):\n      line = clean_lines.elided[i]\n      depth += line.count('{') - line.count('}')\n      if not depth:\n        self.last_line = i\n        break\n\n  def CheckBegin(self, filename, clean_lines, linenum, error):\n    # Look for a bare ':'\n    if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]):\n      self.is_derived = True\n\n\nclass _NamespaceInfo(_BlockInfo):\n  \"\"\"Stores information about a namespace.\"\"\"\n\n  def __init__(self, name, linenum):\n    _BlockInfo.__init__(self, False)\n    self.name = name or ''\n    self.starting_linenum = linenum\n\n  def CheckEnd(self, filename, clean_lines, linenum, error):\n    \"\"\"Check end of namespace comments.\"\"\"\n    line = clean_lines.raw_lines[linenum]\n\n    # Check how many lines is enclosed in this namespace.  Don't issue\n    # warning for missing namespace comments if there aren't enough\n    # lines.  However, do apply checks if there is already an end of\n    # namespace comment and it's incorrect.\n    #\n    # TODO(unknown): We always want to check end of namespace comments\n    # if a namespace is large, but sometimes we also want to apply the\n    # check if a short namespace contained nontrivial things (something\n    # other than forward declarations).  There is currently no logic on\n    # deciding what these nontrivial things are, so this check is\n    # triggered by namespace size only, which works most of the time.\n    if (linenum - self.starting_linenum < 10\n        and not Match(r'};*\\s*(//|/\\*).*\\bnamespace\\b', line)):\n      return\n\n    # Look for matching comment at end of namespace.\n    #\n    # Note that we accept C style \"/* */\" comments for terminating\n    # namespaces, so that code that terminate namespaces inside\n    # preprocessor macros can be cpplint clean.  Example: http://go/nxpiz\n    #\n    # We also accept stuff like \"// end of namespace <name>.\" with the\n    # period at the end.\n    #\n    # Besides these, we don't accept anything else, otherwise we might\n    # get false negatives when existing comment is a substring of the\n    # expected namespace.  Example: http://go/ldkdc, http://cl/23548205\n    if self.name:\n      # Named namespace\n      if not Match((r'};*\\s*(//|/\\*).*\\bnamespace\\s+' + re.escape(self.name) +\n                    r'[\\*/\\.\\\\\\s]*$'),\n                   line):\n        error(filename, linenum, 'readability/namespace', 5,\n              'Namespace should be terminated with \"// namespace %s\"' %\n              self.name)\n    else:\n      # Anonymous namespace\n      if not Match(r'};*\\s*(//|/\\*).*\\bnamespace[\\*/\\.\\\\\\s]*$', line):\n        error(filename, linenum, 'readability/namespace', 5,\n              'Namespace should be terminated with \"// namespace\"')\n\n\nclass _PreprocessorInfo(object):\n  \"\"\"Stores checkpoints of nesting stacks when #if/#else is seen.\"\"\"\n\n  def __init__(self, stack_before_if):\n    # The entire nesting stack before #if\n    self.stack_before_if = stack_before_if\n\n    # The entire nesting stack up to #else\n    self.stack_before_else = []\n\n    # Whether we have already seen #else or #elif\n    self.seen_else = False\n\n\nclass _NestingState(object):\n  \"\"\"Holds states related to parsing braces.\"\"\"\n\n  def __init__(self):\n    # Stack for tracking all braces.  An object is pushed whenever we\n    # see a \"{\", and popped when we see a \"}\".  Only 3 types of\n    # objects are possible:\n    # - _ClassInfo: a class or struct.\n    # - _NamespaceInfo: a namespace.\n    # - _BlockInfo: some other type of block.\n    self.stack = []\n\n    # Stack of _PreprocessorInfo objects.\n    self.pp_stack = []\n\n  def SeenOpenBrace(self):\n    \"\"\"Check if we have seen the opening brace for the innermost block.\n\n    Returns:\n      True if we have seen the opening brace, False if the innermost\n      block is still expecting an opening brace.\n    \"\"\"\n    return (not self.stack) or self.stack[-1].seen_open_brace\n\n  def InNamespaceBody(self):\n    \"\"\"Check if we are currently one level inside a namespace body.\n\n    Returns:\n      True if top of the stack is a namespace block, False otherwise.\n    \"\"\"\n    return self.stack and isinstance(self.stack[-1], _NamespaceInfo)\n\n  def UpdatePreprocessor(self, line):\n    \"\"\"Update preprocessor stack.\n\n    We need to handle preprocessors due to classes like this:\n      #ifdef SWIG\n      struct ResultDetailsPageElementExtensionPoint {\n      #else\n      struct ResultDetailsPageElementExtensionPoint : public Extension {\n      #endif\n    (see http://go/qwddn for original example)\n\n    We make the following assumptions (good enough for most files):\n    - Preprocessor condition evaluates to true from #if up to first\n      #else/#elif/#endif.\n\n    - Preprocessor condition evaluates to false from #else/#elif up\n      to #endif.  We still perform lint checks on these lines, but\n      these do not affect nesting stack.\n\n    Args:\n      line: current line to check.\n    \"\"\"\n    if Match(r'^\\s*#\\s*(if|ifdef|ifndef)\\b', line):\n      # Beginning of #if block, save the nesting stack here.  The saved\n      # stack will allow us to restore the parsing state in the #else case.\n      self.pp_stack.append(_PreprocessorInfo(copy.deepcopy(self.stack)))\n    elif Match(r'^\\s*#\\s*(else|elif)\\b', line):\n      # Beginning of #else block\n      if self.pp_stack:\n        if not self.pp_stack[-1].seen_else:\n          # This is the first #else or #elif block.  Remember the\n          # whole nesting stack up to this point.  This is what we\n          # keep after the #endif.\n          self.pp_stack[-1].seen_else = True\n          self.pp_stack[-1].stack_before_else = copy.deepcopy(self.stack)\n\n        # Restore the stack to how it was before the #if\n        self.stack = copy.deepcopy(self.pp_stack[-1].stack_before_if)\n      else:\n        # TODO(unknown): unexpected #else, issue warning?\n        pass\n    elif Match(r'^\\s*#\\s*endif\\b', line):\n      # End of #if or #else blocks.\n      if self.pp_stack:\n        # If we saw an #else, we will need to restore the nesting\n        # stack to its former state before the #else, otherwise we\n        # will just continue from where we left off.\n        if self.pp_stack[-1].seen_else:\n          # Here we can just use a shallow copy since we are the last\n          # reference to it.\n          self.stack = self.pp_stack[-1].stack_before_else\n        # Drop the corresponding #if\n        self.pp_stack.pop()\n      else:\n        # TODO(unknown): unexpected #endif, issue warning?\n        pass\n\n  def Update(self, filename, clean_lines, linenum, error):\n    \"\"\"Update nesting state with current line.\n\n    Args:\n      filename: The name of the current file.\n      clean_lines: A CleansedLines instance containing the file.\n      linenum: The number of the line to check.\n      error: The function to call with any errors found.\n    \"\"\"\n    line = clean_lines.elided[linenum]\n\n    # Update pp_stack first\n    self.UpdatePreprocessor(line)\n\n    # Count parentheses.  This is to avoid adding struct arguments to\n    # the nesting stack.\n    if self.stack:\n      inner_block = self.stack[-1]\n      depth_change = line.count('(') - line.count(')')\n      inner_block.open_parentheses += depth_change\n\n      # Also check if we are starting or ending an inline assembly block.\n      if inner_block.inline_asm in (_NO_ASM, _END_ASM):\n        if (depth_change != 0 and\n            inner_block.open_parentheses == 1 and\n            _MATCH_ASM.match(line)):\n          # Enter assembly block\n          inner_block.inline_asm = _INSIDE_ASM\n        else:\n          # Not entering assembly block.  If previous line was _END_ASM,\n          # we will now shift to _NO_ASM state.\n          inner_block.inline_asm = _NO_ASM\n      elif (inner_block.inline_asm == _INSIDE_ASM and\n            inner_block.open_parentheses == 0):\n        # Exit assembly block\n        inner_block.inline_asm = _END_ASM\n\n    # Consume namespace declaration at the beginning of the line.  Do\n    # this in a loop so that we catch same line declarations like this:\n    #   namespace proto2 { namespace bridge { class MessageSet; } }\n    while True:\n      # Match start of namespace.  The \"\\b\\s*\" below catches namespace\n      # declarations even if it weren't followed by a whitespace, this\n      # is so that we don't confuse our namespace checker.  The\n      # missing spaces will be flagged by CheckSpacing.\n      namespace_decl_match = Match(r'^\\s*namespace\\b\\s*([:\\w]+)?(.*)$', line)\n      if not namespace_decl_match:\n        break\n\n      new_namespace = _NamespaceInfo(namespace_decl_match.group(1), linenum)\n      self.stack.append(new_namespace)\n\n      line = namespace_decl_match.group(2)\n      if line.find('{') != -1:\n        new_namespace.seen_open_brace = True\n        line = line[line.find('{') + 1:]\n\n    # Look for a class declaration in whatever is left of the line\n    # after parsing namespaces.  The regexp accounts for decorated classes\n    # such as in:\n    #   class LOCKABLE API Object {\n    #   };\n    #\n    # Templates with class arguments may confuse the parser, for example:\n    #   template <class T\n    #             class Comparator = less<T>,\n    #             class Vector = vector<T> >\n    #   class HeapQueue {\n    #\n    # Because this parser has no nesting state about templates, by the\n    # time it saw \"class Comparator\", it may think that it's a new class.\n    # Nested templates have a similar problem:\n    #   template <\n    #       typename ExportedType,\n    #       typename TupleType,\n    #       template <typename, typename> class ImplTemplate>\n    #\n    # To avoid these cases, we ignore classes that are followed by '=' or '>'\n    class_decl_match = Match(\n        r'\\s*(template\\s*<[\\w\\s<>,:]*>\\s*)?'\n        '(class|struct)\\s+([A-Z_]+\\s+)*(\\w+(?:::\\w+)*)'\n        '(([^=>]|<[^<>]*>)*)$', line)\n    if (class_decl_match and\n        (not self.stack or self.stack[-1].open_parentheses == 0)):\n      self.stack.append(_ClassInfo(\n          class_decl_match.group(4), class_decl_match.group(2),\n          clean_lines, linenum))\n      line = class_decl_match.group(5)\n\n    # If we have not yet seen the opening brace for the innermost block,\n    # run checks here.\n    if not self.SeenOpenBrace():\n      self.stack[-1].CheckBegin(filename, clean_lines, linenum, error)\n\n    # Update access control if we are inside a class/struct\n    if self.stack and isinstance(self.stack[-1], _ClassInfo):\n      access_match = Match(r'\\s*(public|private|protected)\\s*:', line)\n      if access_match:\n        self.stack[-1].access = access_match.group(1)\n\n    # Consume braces or semicolons from what's left of the line\n    while True:\n      # Match first brace, semicolon, or closed parenthesis.\n      matched = Match(r'^[^{;)}]*([{;)}])(.*)$', line)\n      if not matched:\n        break\n\n      token = matched.group(1)\n      if token == '{':\n        # If namespace or class hasn't seen a opening brace yet, mark\n        # namespace/class head as complete.  Push a new block onto the\n        # stack otherwise.\n        if not self.SeenOpenBrace():\n          self.stack[-1].seen_open_brace = True\n        else:\n          self.stack.append(_BlockInfo(True))\n          if _MATCH_ASM.match(line):\n            self.stack[-1].inline_asm = _BLOCK_ASM\n      elif token == ';' or token == ')':\n        # If we haven't seen an opening brace yet, but we already saw\n        # a semicolon, this is probably a forward declaration.  Pop\n        # the stack for these.\n        #\n        # Similarly, if we haven't seen an opening brace yet, but we\n        # already saw a closing parenthesis, then these are probably\n        # function arguments with extra \"class\" or \"struct\" keywords.\n        # Also pop these stack for these.\n        if not self.SeenOpenBrace():\n          self.stack.pop()\n      else:  # token == '}'\n        # Perform end of block checks and pop the stack.\n        if self.stack:\n          self.stack[-1].CheckEnd(filename, clean_lines, linenum, error)\n          self.stack.pop()\n      line = matched.group(2)\n\n  def InnermostClass(self):\n    \"\"\"Get class info on the top of the stack.\n\n    Returns:\n      A _ClassInfo object if we are inside a class, or None otherwise.\n    \"\"\"\n    for i in range(len(self.stack), 0, -1):\n      classinfo = self.stack[i - 1]\n      if isinstance(classinfo, _ClassInfo):\n        return classinfo\n    return None\n\n  def CheckClassFinished(self, filename, error):\n    \"\"\"Checks that all classes have been completely parsed.\n\n    Call this when all lines in a file have been processed.\n    Args:\n      filename: The name of the current file.\n      error: The function to call with any errors found.\n    \"\"\"\n    # Note: This test can result in false positives if #ifdef constructs\n    # get in the way of brace matching. See the testBuildClass test in\n    # cpplint_unittest.py for an example of this.\n    for obj in self.stack:\n      if isinstance(obj, _ClassInfo):\n        error(filename, obj.starting_linenum, 'build/class', 5,\n              'Failed to find complete declaration of class %s' %\n              obj.name)\n\n\ndef CheckForNonStandardConstructs(filename, clean_lines, linenum,\n                                  nesting_state, error):\n  \"\"\"Logs an error if we see certain non-ANSI constructs ignored by gcc-2.\n\n  Complain about several constructs which gcc-2 accepts, but which are\n  not standard C++.  Warning about these in lint is one way to ease the\n  transition to new compilers.\n  - put storage class first (e.g. \"static const\" instead of \"const static\").\n  - \"%lld\" instead of %qd\" in printf-type functions.\n  - \"%1$d\" is non-standard in printf-type functions.\n  - \"\\%\" is an undefined character escape sequence.\n  - text after #endif is not allowed.\n  - invalid inner-style forward declaration.\n  - >? and <? operators, and their >?= and <?= cousins.\n\n  Additionally, check for constructor/destructor style violations and reference\n  members, as it is very convenient to do so while checking for\n  gcc-2 compliance.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    nesting_state: A _NestingState instance which maintains information about\n                   the current stack of nested blocks being parsed.\n    error: A callable to which errors are reported, which takes 4 arguments:\n           filename, line number, error level, and message\n  \"\"\"\n\n  # Remove comments from the line, but leave in strings for now.\n  line = clean_lines.lines[linenum]\n\n  if Search(r'printf\\s*\\(.*\".*%[-+ ]?\\d*q', line):\n    error(filename, linenum, 'runtime/printf_format', 3,\n          '%q in format strings is deprecated.  Use %ll instead.')\n\n  if Search(r'printf\\s*\\(.*\".*%\\d+\\$', line):\n    error(filename, linenum, 'runtime/printf_format', 2,\n          '%N$ formats are unconventional.  Try rewriting to avoid them.')\n\n  # Remove escaped backslashes before looking for undefined escapes.\n  line = line.replace('\\\\\\\\', '')\n\n  if Search(r'(\"|\\').*\\\\(%|\\[|\\(|{)', line):\n    error(filename, linenum, 'build/printf_format', 3,\n          '%, [, (, and { are undefined character escapes.  Unescape them.')\n\n  # For the rest, work with both comments and strings removed.\n  line = clean_lines.elided[linenum]\n\n  if Search(r'\\b(const|volatile|void|char|short|int|long'\n            r'|float|double|signed|unsigned'\n            r'|schar|u?int8|u?int16|u?int32|u?int64)'\n            r'\\s+(register|static|extern|typedef)\\b',\n            line):\n    error(filename, linenum, 'build/storage_class', 5,\n          'Storage class (static, extern, typedef, etc) should be first.')\n\n  if Match(r'\\s*#\\s*endif\\s*[^/\\s]+', line):\n    error(filename, linenum, 'build/endif_comment', 5,\n          'Uncommented text after #endif is non-standard.  Use a comment.')\n\n  if Match(r'\\s*class\\s+(\\w+\\s*::\\s*)+\\w+\\s*;', line):\n    error(filename, linenum, 'build/forward_decl', 5,\n          'Inner-style forward declarations are invalid.  Remove this line.')\n\n  if Search(r'(\\w+|[+-]?\\d+(\\.\\d*)?)\\s*(<|>)\\?=?\\s*(\\w+|[+-]?\\d+)(\\.\\d*)?',\n            line):\n    error(filename, linenum, 'build/deprecated', 3,\n          '>? and <? (max and min) operators are non-standard and deprecated.')\n\n  if Search(r'^\\s*const\\s*string\\s*&\\s*\\w+\\s*;', line):\n    # TODO(unknown): Could it be expanded safely to arbitrary references,\n    # without triggering too many false positives? The first\n    # attempt triggered 5 warnings for mostly benign code in the regtest, hence\n    # the restriction.\n    # Here's the original regexp, for the reference:\n    # type_name = r'\\w+((\\s*::\\s*\\w+)|(\\s*<\\s*\\w+?\\s*>))?'\n    # r'\\s*const\\s*' + type_name + '\\s*&\\s*\\w+\\s*;'\n    error(filename, linenum, 'runtime/member_string_references', 2,\n          'const string& members are dangerous. It is much better to use '\n          'alternatives, such as pointers or simple constants.')\n\n  # Everything else in this function operates on class declarations.\n  # Return early if the top of the nesting stack is not a class, or if\n  # the class head is not completed yet.\n  classinfo = nesting_state.InnermostClass()\n  if not classinfo or not classinfo.seen_open_brace:\n    return\n\n  # The class may have been declared with namespace or classname qualifiers.\n  # The constructor and destructor will not have those qualifiers.\n  base_classname = classinfo.name.split('::')[-1]\n\n  # Look for single-argument constructors that aren't marked explicit.\n  # Technically a valid construct, but against style.\n  args = Match(r'\\s+(?:inline\\s+)?%s\\s*\\(([^,()]+)\\)'\n               % re.escape(base_classname),\n               line)\n  if (args and\n      args.group(1) != 'void' and\n      not Match(r'(const\\s+)?%s\\s*(?:<\\w+>\\s*)?&' % re.escape(base_classname),\n                args.group(1).strip())):\n    error(filename, linenum, 'runtime/explicit', 5,\n          'Single-argument constructors should be marked explicit.')\n\n\ndef CheckSpacingForFunctionCall(filename, line, linenum, error):\n  \"\"\"Checks for the correctness of various spacing around function calls.\n\n  Args:\n    filename: The name of the current file.\n    line: The text of the line to check.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  # Since function calls often occur inside if/for/while/switch\n  # expressions - which have their own, more liberal conventions - we\n  # first see if we should be looking inside such an expression for a\n  # function call, to which we can apply more strict standards.\n  fncall = line    # if there's no control flow construct, look at whole line\n  for pattern in (r'\\bif\\s*\\((.*)\\)\\s*{',\n                  r'\\bfor\\s*\\((.*)\\)\\s*{',\n                  r'\\bwhile\\s*\\((.*)\\)\\s*[{;]',\n                  r'\\bswitch\\s*\\((.*)\\)\\s*{'):\n    match = Search(pattern, line)\n    if match:\n      fncall = match.group(1)    # look inside the parens for function calls\n      break\n\n  # Except in if/for/while/switch, there should never be space\n  # immediately inside parens (eg \"f( 3, 4 )\").  We make an exception\n  # for nested parens ( (a+b) + c ).  Likewise, there should never be\n  # a space before a ( when it's a function argument.  I assume it's a\n  # function argument when the char before the whitespace is legal in\n  # a function name (alnum + _) and we're not starting a macro. Also ignore\n  # pointers and references to arrays and functions coz they're too tricky:\n  # we use a very simple way to recognize these:\n  # \" (something)(maybe-something)\" or\n  # \" (something)(maybe-something,\" or\n  # \" (something)[something]\"\n  # Note that we assume the contents of [] to be short enough that\n  # they'll never need to wrap.\n  if (  # Ignore control structures.\n      not Search(r'\\b(if|for|while|switch|return|delete)\\b', fncall) and\n      # Ignore pointers/references to functions.\n      not Search(r' \\([^)]+\\)\\([^)]*(\\)|,$)', fncall) and\n      # Ignore pointers/references to arrays.\n      not Search(r' \\([^)]+\\)\\[[^\\]]+\\]', fncall)):\n    if Search(r'\\w\\s*\\(\\s(?!\\s*\\\\$)', fncall):      # a ( used for a fn call\n      error(filename, linenum, 'whitespace/parens', 4,\n            'Extra space after ( in function call')\n    elif Search(r'\\(\\s+(?!(\\s*\\\\)|\\()', fncall):\n      error(filename, linenum, 'whitespace/parens', 2,\n            'Extra space after (')\n    if (Search(r'\\w\\s+\\(', fncall) and\n        not Search(r'#\\s*define|typedef', fncall) and\n        not Search(r'\\w\\s+\\((\\w+::)?\\*\\w+\\)\\(', fncall)):\n      error(filename, linenum, 'whitespace/parens', 4,\n            'Extra space before ( in function call')\n    # If the ) is followed only by a newline or a { + newline, assume it's\n    # part of a control statement (if/while/etc), and don't complain\n    if Search(r'[^)]\\s+\\)\\s*[^{\\s]', fncall):\n      # If the closing parenthesis is preceded by only whitespaces,\n      # try to give a more descriptive error message.\n      if Search(r'^\\s+\\)', fncall):\n        error(filename, linenum, 'whitespace/parens', 2,\n              'Closing ) should be moved to the previous line')\n      else:\n        error(filename, linenum, 'whitespace/parens', 2,\n              'Extra space before )')\n\n\ndef IsBlankLine(line):\n  \"\"\"Returns true if the given line is blank.\n\n  We consider a line to be blank if the line is empty or consists of\n  only white spaces.\n\n  Args:\n    line: A line of a string.\n\n  Returns:\n    True, if the given line is blank.\n  \"\"\"\n  return not line or line.isspace()\n\n\ndef CheckForFunctionLengths(filename, clean_lines, linenum,\n                            function_state, error):\n  \"\"\"Reports for long function bodies.\n\n  For an overview why this is done, see:\n  http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions\n\n  Uses a simplistic algorithm assuming other style guidelines\n  (especially spacing) are followed.\n  Only checks unindented functions, so class members are unchecked.\n  Trivial bodies are unchecked, so constructors with huge initializer lists\n  may be missed.\n  Blank/comment lines are not counted so as to avoid encouraging the removal\n  of vertical space and comments just to get through a lint check.\n  NOLINT *on the last line of a function* disables this check.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    function_state: Current function name and lines in body so far.\n    error: The function to call with any errors found.\n  \"\"\"\n  lines = clean_lines.lines\n  line = lines[linenum]\n  raw = clean_lines.raw_lines\n  raw_line = raw[linenum]\n  joined_line = ''\n\n  starting_func = False\n  regexp = r'(\\w(\\w|::|\\*|\\&|\\s)*)\\('  # decls * & space::name( ...\n  match_result = Match(regexp, line)\n  if match_result:\n    # If the name is all caps and underscores, figure it's a macro and\n    # ignore it, unless it's TEST or TEST_F.\n    function_name = match_result.group(1).split()[-1]\n    if function_name == 'TEST' or function_name == 'TEST_F' or (\n        not Match(r'[A-Z_]+$', function_name)):\n      starting_func = True\n\n  if starting_func:\n    body_found = False\n    for start_linenum in xrange(linenum, clean_lines.NumLines()):\n      start_line = lines[start_linenum]\n      joined_line += ' ' + start_line.lstrip()\n      if Search(r'(;|})', start_line):  # Declarations and trivial functions\n        body_found = True\n        break                              # ... ignore\n      elif Search(r'{', start_line):\n        body_found = True\n        function = Search(r'((\\w|:)*)\\(', line).group(1)\n        if Match(r'TEST', function):    # Handle TEST... macros\n          parameter_regexp = Search(r'(\\(.*\\))', joined_line)\n          if parameter_regexp:             # Ignore bad syntax\n            function += parameter_regexp.group(1)\n        else:\n          function += '()'\n        function_state.Begin(function)\n        break\n    if not body_found:\n      # No body for the function (or evidence of a non-function) was found.\n      error(filename, linenum, 'readability/fn_size', 5,\n            'Lint failed to find start of function body.')\n  elif Match(r'^\\}\\s*$', line):  # function end\n    function_state.Check(error, filename, linenum)\n    function_state.End()\n  elif not Match(r'^\\s*$', line):\n    function_state.Count()  # Count non-blank/non-comment lines.\n\n\n_RE_PATTERN_TODO = re.compile(r'^//(\\s*)TODO(\\(.+?\\))?:?(\\s|$)?')\n\n\ndef CheckComment(comment, filename, linenum, error):\n  \"\"\"Checks for common mistakes in TODO comments.\n\n  Args:\n    comment: The text of the comment from the line in question.\n    filename: The name of the current file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  match = _RE_PATTERN_TODO.match(comment)\n  if match:\n    # One whitespace is correct; zero whitespace is handled elsewhere.\n    leading_whitespace = match.group(1)\n    if len(leading_whitespace) > 1:\n      error(filename, linenum, 'whitespace/todo', 2,\n            'Too many spaces before TODO')\n\n    username = match.group(2)\n    if not username:\n      error(filename, linenum, 'readability/todo', 2,\n            'Missing username in TODO; it should look like '\n            '\"// TODO(my_username): Stuff.\"')\n\n    middle_whitespace = match.group(3)\n    # Comparisons made explicit for correctness -- pylint: disable-msg=C6403\n    if middle_whitespace != ' ' and middle_whitespace != '':\n      error(filename, linenum, 'whitespace/todo', 2,\n            'TODO(my_username) should be followed by a space')\n\ndef CheckAccess(filename, clean_lines, linenum, nesting_state, error):\n  \"\"\"Checks for improper use of DISALLOW* macros.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    nesting_state: A _NestingState instance which maintains information about\n                   the current stack of nested blocks being parsed.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]  # get rid of comments and strings\n\n  matched = Match((r'\\s*(DISALLOW_COPY_AND_ASSIGN|'\n                   r'DISALLOW_EVIL_CONSTRUCTORS|'\n                   r'DISALLOW_IMPLICIT_CONSTRUCTORS)'), line)\n  if not matched:\n    return\n  if nesting_state.stack and isinstance(nesting_state.stack[-1], _ClassInfo):\n    if nesting_state.stack[-1].access != 'private':\n      error(filename, linenum, 'readability/constructors', 3,\n            '%s must be in the private: section' % matched.group(1))\n\n  else:\n    # Found DISALLOW* macro outside a class declaration, or perhaps it\n    # was used inside a function when it should have been part of the\n    # class declaration.  We could issue a warning here, but it\n    # probably resulted in a compiler error already.\n    pass\n\n\ndef FindNextMatchingAngleBracket(clean_lines, linenum, init_suffix):\n  \"\"\"Find the corresponding > to close a template.\n\n  Args:\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: Current line number.\n    init_suffix: Remainder of the current line after the initial <.\n\n  Returns:\n    True if a matching bracket exists.\n  \"\"\"\n  line = init_suffix\n  nesting_stack = ['<']\n  while True:\n    # Find the next operator that can tell us whether < is used as an\n    # opening bracket or as a less-than operator.  We only want to\n    # warn on the latter case.\n    #\n    # We could also check all other operators and terminate the search\n    # early, e.g. if we got something like this \"a<b+c\", the \"<\" is\n    # most likely a less-than operator, but then we will get false\n    # positives for default arguments (e.g. http://go/prccd) and\n    # other template expressions (e.g. http://go/oxcjq).\n    match = Search(r'^[^<>(),;\\[\\]]*([<>(),;\\[\\]])(.*)$', line)\n    if match:\n      # Found an operator, update nesting stack\n      operator = match.group(1)\n      line = match.group(2)\n\n      if nesting_stack[-1] == '<':\n        # Expecting closing angle bracket\n        if operator in ('<', '(', '['):\n          nesting_stack.append(operator)\n        elif operator == '>':\n          nesting_stack.pop()\n          if not nesting_stack:\n            # Found matching angle bracket\n            return True\n        elif operator == ',':\n          # Got a comma after a bracket, this is most likely a template\n          # argument.  We have not seen a closing angle bracket yet, but\n          # it's probably a few lines later if we look for it, so just\n          # return early here.\n          return True\n        else:\n          # Got some other operator.\n          return False\n\n      else:\n        # Expecting closing parenthesis or closing bracket\n        if operator in ('<', '(', '['):\n          nesting_stack.append(operator)\n        elif operator in (')', ']'):\n          # We don't bother checking for matching () or [].  If we got\n          # something like (] or [), it would have been a syntax error.\n          nesting_stack.pop()\n\n    else:\n      # Scan the next line\n      linenum += 1\n      if linenum >= len(clean_lines.elided):\n        break\n      line = clean_lines.elided[linenum]\n\n  # Exhausted all remaining lines and still no matching angle bracket.\n  # Most likely the input was incomplete, otherwise we should have\n  # seen a semicolon and returned early.\n  return True\n\n\ndef FindPreviousMatchingAngleBracket(clean_lines, linenum, init_prefix):\n  \"\"\"Find the corresponding < that started a template.\n\n  Args:\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: Current line number.\n    init_prefix: Part of the current line before the initial >.\n\n  Returns:\n    True if a matching bracket exists.\n  \"\"\"\n  line = init_prefix\n  nesting_stack = ['>']\n  while True:\n    # Find the previous operator\n    match = Search(r'^(.*)([<>(),;\\[\\]])[^<>(),;\\[\\]]*$', line)\n    if match:\n      # Found an operator, update nesting stack\n      operator = match.group(2)\n      line = match.group(1)\n\n      if nesting_stack[-1] == '>':\n        # Expecting opening angle bracket\n        if operator in ('>', ')', ']'):\n          nesting_stack.append(operator)\n        elif operator == '<':\n          nesting_stack.pop()\n          if not nesting_stack:\n            # Found matching angle bracket\n            return True\n        elif operator == ',':\n          # Got a comma before a bracket, this is most likely a\n          # template argument.  The opening angle bracket is probably\n          # there if we look for it, so just return early here.\n          return True\n        else:\n          # Got some other operator.\n          return False\n\n      else:\n        # Expecting opening parenthesis or opening bracket\n        if operator in ('>', ')', ']'):\n          nesting_stack.append(operator)\n        elif operator in ('(', '['):\n          nesting_stack.pop()\n\n    else:\n      # Scan the previous line\n      linenum -= 1\n      if linenum < 0:\n        break\n      line = clean_lines.elided[linenum]\n\n  # Exhausted all earlier lines and still no matching angle bracket.\n  return False\n\n\ndef CheckSpacing(filename, clean_lines, linenum, nesting_state, error):\n  \"\"\"Checks for the correctness of various spacing issues in the code.\n\n  Things we check for: spaces around operators, spaces after\n  if/for/while/switch, no spaces around parens in function calls, two\n  spaces between code and comment, don't start a block with a blank\n  line, don't end a function with a blank line, don't add a blank line\n  after public/protected/private, don't have too many blank lines in a row.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    nesting_state: A _NestingState instance which maintains information about\n                   the current stack of nested blocks being parsed.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  raw = clean_lines.raw_lines\n  line = raw[linenum]\n\n  # Before nixing comments, check if the line is blank for no good\n  # reason.  This includes the first line after a block is opened, and\n  # blank lines at the end of a function (ie, right before a line like '}'\n  #\n  # Skip all the blank line checks if we are immediately inside a\n  # namespace body.  In other words, don't issue blank line warnings\n  # for this block:\n  #   namespace {\n  #\n  #   }\n  #\n  # A warning about missing end of namespace comments will be issued instead.\n  if IsBlankLine(line) and not nesting_state.InNamespaceBody():\n    elided = clean_lines.elided\n    prev_line = elided[linenum - 1]\n    prevbrace = prev_line.rfind('{')\n    # TODO(unknown): Don't complain if line before blank line, and line after,\n    #                both start with alnums and are indented the same amount.\n    #                This ignores whitespace at the start of a namespace block\n    #                because those are not usually indented.\n    if prevbrace != -1 and prev_line[prevbrace:].find('}') == -1:\n      # OK, we have a blank line at the start of a code block.  Before we\n      # complain, we check if it is an exception to the rule: The previous\n      # non-empty line has the parameters of a function header that are indented\n      # 4 spaces (because they did not fit in a 80 column line when placed on\n      # the same line as the function name).  We also check for the case where\n      # the previous line is indented 6 spaces, which may happen when the\n      # initializers of a constructor do not fit into a 80 column line.\n      exception = False\n      if Match(r' {6}\\w', prev_line):  # Initializer list?\n        # We are looking for the opening column of initializer list, which\n        # should be indented 4 spaces to cause 6 space indentation afterwards.\n        search_position = linenum-2\n        while (search_position >= 0\n               and Match(r' {6}\\w', elided[search_position])):\n          search_position -= 1\n        exception = (search_position >= 0\n                     and elided[search_position][:5] == '    :')\n      else:\n        # Search for the function arguments or an initializer list.  We use a\n        # simple heuristic here: If the line is indented 4 spaces; and we have a\n        # closing paren, without the opening paren, followed by an opening brace\n        # or colon (for initializer lists) we assume that it is the last line of\n        # a function header.  If we have a colon indented 4 spaces, it is an\n        # initializer list.\n        exception = (Match(r' {4}\\w[^\\(]*\\)\\s*(const\\s*)?(\\{\\s*$|:)',\n                           prev_line)\n                     or Match(r' {4}:', prev_line))\n\n      if not exception:\n        error(filename, linenum, 'whitespace/blank_line', 2,\n              'Blank line at the start of a code block.  Is this needed?')\n    # Ignore blank lines at the end of a block in a long if-else\n    # chain, like this:\n    #   if (condition1) {\n    #     // Something followed by a blank line\n    #\n    #   } else if (condition2) {\n    #     // Something else\n    #   }\n    if linenum + 1 < clean_lines.NumLines():\n      next_line = raw[linenum + 1]\n      if (next_line\n          and Match(r'\\s*}', next_line)\n          and next_line.find('} else ') == -1):\n        error(filename, linenum, 'whitespace/blank_line', 3,\n              'Blank line at the end of a code block.  Is this needed?')\n\n    matched = Match(r'\\s*(public|protected|private):', prev_line)\n    if matched:\n      error(filename, linenum, 'whitespace/blank_line', 3,\n            'Do not leave a blank line after \"%s:\"' % matched.group(1))\n\n  # Next, we complain if there's a comment too near the text\n  commentpos = line.find('//')\n  if commentpos != -1:\n    # Check if the // may be in quotes.  If so, ignore it\n    # Comparisons made explicit for clarity -- pylint: disable-msg=C6403\n    if (line.count('\"', 0, commentpos) -\n        line.count('\\\\\"', 0, commentpos)) % 2 == 0:   # not in quotes\n      # Allow one space for new scopes, two spaces otherwise:\n      if (not Match(r'^\\s*{ //', line) and\n          ((commentpos >= 1 and\n            line[commentpos-1] not in string.whitespace) or\n           (commentpos >= 2 and\n            line[commentpos-2] not in string.whitespace))):\n        error(filename, linenum, 'whitespace/comments', 2,\n              'At least two spaces is best between code and comments')\n      # There should always be a space between the // and the comment\n      commentend = commentpos + 2\n      if commentend < len(line) and not line[commentend] == ' ':\n        # but some lines are exceptions -- e.g. if they're big\n        # comment delimiters like:\n        # //----------------------------------------------------------\n        # or are an empty C++ style Doxygen comment, like:\n        # ///\n        # or they begin with multiple slashes followed by a space:\n        # //////// Header comment\n        match = (Search(r'[=/-]{4,}\\s*$', line[commentend:]) or\n                 Search(r'^/$', line[commentend:]) or\n                 Search(r'^/+ ', line[commentend:]))\n        if not match:\n          error(filename, linenum, 'whitespace/comments', 4,\n                'Should have a space between // and comment')\n      CheckComment(line[commentpos:], filename, linenum, error)\n\n  line = clean_lines.elided[linenum]  # get rid of comments and strings\n\n  # Don't try to do spacing checks for operator methods\n  line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\\(', 'operator\\(', line)\n\n  # We allow no-spaces around = within an if: \"if ( (a=Foo()) == 0 )\".\n  # Otherwise not.  Note we only check for non-spaces on *both* sides;\n  # sometimes people put non-spaces on one side when aligning ='s among\n  # many lines (not that this is behavior that I approve of...)\n  if Search(r'[\\w.]=[\\w.]', line) and not Search(r'\\b(if|while) ', line):\n    error(filename, linenum, 'whitespace/operators', 4,\n          'Missing spaces around =')\n\n  # It's ok not to have spaces around binary operators like + - * /, but if\n  # there's too little whitespace, we get concerned.  It's hard to tell,\n  # though, so we punt on this one for now.  TODO.\n\n  # You should always have whitespace around binary operators.\n  #\n  # Check <= and >= first to avoid false positives with < and >, then\n  # check non-include lines for spacing around < and >.\n  match = Search(r'[^<>=!\\s](==|!=|<=|>=)[^<>=!\\s]', line)\n  if match:\n    error(filename, linenum, 'whitespace/operators', 3,\n          'Missing spaces around %s' % match.group(1))\n  # We allow no-spaces around << when used like this: 10<<20, but\n  # not otherwise (particularly, not when used as streams)\n  match = Search(r'(\\S)(?:L|UL|ULL|l|ul|ull)?<<(\\S)', line)\n  if match and not (match.group(1).isdigit() and match.group(2).isdigit()):\n    error(filename, linenum, 'whitespace/operators', 3,\n          'Missing spaces around <<')\n  elif not Match(r'#.*include', line):\n    # Avoid false positives on ->\n    reduced_line = line.replace('->', '')\n\n    # Look for < that is not surrounded by spaces.  This is only\n    # triggered if both sides are missing spaces, even though\n    # technically should should flag if at least one side is missing a\n    # space.  This is done to avoid some false positives with shifts.\n    match = Search(r'[^\\s<]<([^\\s=<].*)', reduced_line)\n    if (match and\n        not FindNextMatchingAngleBracket(clean_lines, linenum, match.group(1))):\n      error(filename, linenum, 'whitespace/operators', 3,\n            'Missing spaces around <')\n\n    # Look for > that is not surrounded by spaces.  Similar to the\n    # above, we only trigger if both sides are missing spaces to avoid\n    # false positives with shifts.\n    match = Search(r'^(.*[^\\s>])>[^\\s=>]', reduced_line)\n    if (match and\n        not FindPreviousMatchingAngleBracket(clean_lines, linenum,\n                                             match.group(1))):\n      error(filename, linenum, 'whitespace/operators', 3,\n            'Missing spaces around >')\n\n  # We allow no-spaces around >> for almost anything.  This is because\n  # C++11 allows \">>\" to close nested templates, which accounts for\n  # most cases when \">>\" is not followed by a space.\n  #\n  # We still warn on \">>\" followed by alpha character, because that is\n  # likely due to \">>\" being used for right shifts, e.g.:\n  #   value >> alpha\n  #\n  # When \">>\" is used to close templates, the alphanumeric letter that\n  # follows would be part of an identifier, and there should still be\n  # a space separating the template type and the identifier.\n  #   type<type<type>> alpha\n  match = Search(r'>>[a-zA-Z_]', line)\n  if match:\n    error(filename, linenum, 'whitespace/operators', 3,\n          'Missing spaces around >>')\n\n  # There shouldn't be space around unary operators\n  match = Search(r'(!\\s|~\\s|[\\s]--[\\s;]|[\\s]\\+\\+[\\s;])', line)\n  if match:\n    error(filename, linenum, 'whitespace/operators', 4,\n          'Extra space for operator %s' % match.group(1))\n\n  # A pet peeve of mine: no spaces after an if, while, switch, or for\n  match = Search(r' (if\\(|for\\(|while\\(|switch\\()', line)\n  if match:\n    error(filename, linenum, 'whitespace/parens', 5,\n          'Missing space before ( in %s' % match.group(1))\n\n  # For if/for/while/switch, the left and right parens should be\n  # consistent about how many spaces are inside the parens, and\n  # there should either be zero or one spaces inside the parens.\n  # We don't want: \"if ( foo)\" or \"if ( foo   )\".\n  # Exception: \"for ( ; foo; bar)\" and \"for (foo; bar; )\" are allowed.\n  match = Search(r'\\b(if|for|while|switch)\\s*'\n                 r'\\(([ ]*)(.).*[^ ]+([ ]*)\\)\\s*{\\s*$',\n                 line)\n  if match:\n    if len(match.group(2)) != len(match.group(4)):\n      if not (match.group(3) == ';' and\n              len(match.group(2)) == 1 + len(match.group(4)) or\n              not match.group(2) and Search(r'\\bfor\\s*\\(.*; \\)', line)):\n        error(filename, linenum, 'whitespace/parens', 5,\n              'Mismatching spaces inside () in %s' % match.group(1))\n    if not len(match.group(2)) in [0, 1]:\n      error(filename, linenum, 'whitespace/parens', 5,\n            'Should have zero or one spaces inside ( and ) in %s' %\n            match.group(1))\n\n  # You should always have a space after a comma (either as fn arg or operator)\n  if Search(r',[^\\s]', line):\n    error(filename, linenum, 'whitespace/comma', 3,\n          'Missing space after ,')\n\n  # You should always have a space after a semicolon\n  # except for few corner cases\n  # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more\n  # space after ;\n  if Search(r';[^\\s};\\\\)/]', line):\n    error(filename, linenum, 'whitespace/semicolon', 3,\n          'Missing space after ;')\n\n  # Next we will look for issues with function calls.\n  CheckSpacingForFunctionCall(filename, line, linenum, error)\n\n  # Except after an opening paren, or after another opening brace (in case of\n  # an initializer list, for instance), you should have spaces before your\n  # braces. And since you should never have braces at the beginning of a line,\n  # this is an easy test.\n  if Search(r'[^ ({]{', line):\n    error(filename, linenum, 'whitespace/braces', 5,\n          'Missing space before {')\n\n  # Make sure '} else {' has spaces.\n  if Search(r'}else', line):\n    error(filename, linenum, 'whitespace/braces', 5,\n          'Missing space before else')\n\n  # You shouldn't have spaces before your brackets, except maybe after\n  # 'delete []' or 'new char * []'.\n  if Search(r'\\w\\s+\\[', line) and not Search(r'delete\\s+\\[', line):\n    error(filename, linenum, 'whitespace/braces', 5,\n          'Extra space before [')\n\n  # You shouldn't have a space before a semicolon at the end of the line.\n  # There's a special case for \"for\" since the style guide allows space before\n  # the semicolon there.\n  if Search(r':\\s*;\\s*$', line):\n    error(filename, linenum, 'whitespace/semicolon', 5,\n          'Semicolon defining empty statement. Use {} instead.')\n  elif Search(r'^\\s*;\\s*$', line):\n    error(filename, linenum, 'whitespace/semicolon', 5,\n          'Line contains only semicolon. If this should be an empty statement, '\n          'use {} instead.')\n  elif (Search(r'\\s+;\\s*$', line) and\n        not Search(r'\\bfor\\b', line)):\n    error(filename, linenum, 'whitespace/semicolon', 5,\n          'Extra space before last semicolon. If this should be an empty '\n          'statement, use {} instead.')\n\n  # In range-based for, we wanted spaces before and after the colon, but\n  # not around \"::\" tokens that might appear.\n  if (Search('for *\\(.*[^:]:[^: ]', line) or\n      Search('for *\\(.*[^: ]:[^:]', line)):\n    error(filename, linenum, 'whitespace/forcolon', 2,\n          'Missing space around colon in range-based for loop')\n\n\ndef CheckSectionSpacing(filename, clean_lines, class_info, linenum, error):\n  \"\"\"Checks for additional blank line issues related to sections.\n\n  Currently the only thing checked here is blank line before protected/private.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    class_info: A _ClassInfo objects.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  # Skip checks if the class is small, where small means 25 lines or less.\n  # 25 lines seems like a good cutoff since that's the usual height of\n  # terminals, and any class that can't fit in one screen can't really\n  # be considered \"small\".\n  #\n  # Also skip checks if we are on the first line.  This accounts for\n  # classes that look like\n  #   class Foo { public: ... };\n  #\n  # If we didn't find the end of the class, last_line would be zero,\n  # and the check will be skipped by the first condition.\n  if (class_info.last_line - class_info.starting_linenum <= 24 or\n      linenum <= class_info.starting_linenum):\n    return\n\n  matched = Match(r'\\s*(public|protected|private):', clean_lines.lines[linenum])\n  if matched:\n    # Issue warning if the line before public/protected/private was\n    # not a blank line, but don't do this if the previous line contains\n    # \"class\" or \"struct\".  This can happen two ways:\n    #  - We are at the beginning of the class.\n    #  - We are forward-declaring an inner class that is semantically\n    #    private, but needed to be public for implementation reasons.\n    # Also ignores cases where the previous line ends with a backslash as can be\n    # common when defining classes in C macros.\n    prev_line = clean_lines.lines[linenum - 1]\n    if (not IsBlankLine(prev_line) and\n        not Search(r'\\b(class|struct)\\b', prev_line) and\n        not Search(r'\\\\$', prev_line)):\n      # Try a bit harder to find the beginning of the class.  This is to\n      # account for multi-line base-specifier lists, e.g.:\n      #   class Derived\n      #       : public Base {\n      end_class_head = class_info.starting_linenum\n      for i in range(class_info.starting_linenum, linenum):\n        if Search(r'\\{\\s*$', clean_lines.lines[i]):\n          end_class_head = i\n          break\n      if end_class_head < linenum - 1:\n        error(filename, linenum, 'whitespace/blank_line', 3,\n              '\"%s:\" should be preceded by a blank line' % matched.group(1))\n\n\ndef GetPreviousNonBlankLine(clean_lines, linenum):\n  \"\"\"Return the most recent non-blank line and its line number.\n\n  Args:\n    clean_lines: A CleansedLines instance containing the file contents.\n    linenum: The number of the line to check.\n\n  Returns:\n    A tuple with two elements.  The first element is the contents of the last\n    non-blank line before the current line, or the empty string if this is the\n    first non-blank line.  The second is the line number of that line, or -1\n    if this is the first non-blank line.\n  \"\"\"\n\n  prevlinenum = linenum - 1\n  while prevlinenum >= 0:\n    prevline = clean_lines.elided[prevlinenum]\n    if not IsBlankLine(prevline):     # if not a blank line...\n      return (prevline, prevlinenum)\n    prevlinenum -= 1\n  return ('', -1)\n\n\ndef CheckBraces(filename, clean_lines, linenum, error):\n  \"\"\"Looks for misplaced braces (e.g. at the end of line).\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  line = clean_lines.elided[linenum]        # get rid of comments and strings\n\n  if Match(r'\\s*{\\s*$', line):\n    # We allow an open brace to start a line in the case where someone\n    # is using braces in a block to explicitly create a new scope,\n    # which is commonly used to control the lifetime of\n    # stack-allocated variables.  We don't detect this perfectly: we\n    # just don't complain if the last non-whitespace character on the\n    # previous non-blank line is ';', ':', '{', or '}', or if the previous\n    # line starts a preprocessor block.\n    prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]\n    if (not Search(r'[;:}{]\\s*$', prevline) and\n        not Match(r'\\s*#', prevline)):\n      error(filename, linenum, 'whitespace/braces', 4,\n            '{ should almost always be at the end of the previous line')\n\n  # An else clause should be on the same line as the preceding closing brace.\n  if Match(r'\\s*else\\s*', line):\n    prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]\n    if Match(r'\\s*}\\s*$', prevline):\n      error(filename, linenum, 'whitespace/newline', 4,\n            'An else should appear on the same line as the preceding }')\n\n  # If braces come on one side of an else, they should be on both.\n  # However, we have to worry about \"else if\" that spans multiple lines!\n  if Search(r'}\\s*else[^{]*$', line) or Match(r'[^}]*else\\s*{', line):\n    if Search(r'}\\s*else if([^{]*)$', line):       # could be multi-line if\n      # find the ( after the if\n      pos = line.find('else if')\n      pos = line.find('(', pos)\n      if pos > 0:\n        (endline, _, endpos) = CloseExpression(clean_lines, linenum, pos)\n        if endline[endpos:].find('{') == -1:    # must be brace after if\n          error(filename, linenum, 'readability/braces', 5,\n                'If an else has a brace on one side, it should have it on both')\n    else:            # common case: else not followed by a multi-line if\n      error(filename, linenum, 'readability/braces', 5,\n            'If an else has a brace on one side, it should have it on both')\n\n  # Likewise, an else should never have the else clause on the same line\n  if Search(r'\\belse [^\\s{]', line) and not Search(r'\\belse if\\b', line):\n    error(filename, linenum, 'whitespace/newline', 4,\n          'Else clause should never be on same line as else (use 2 lines)')\n\n  # In the same way, a do/while should never be on one line\n  if Match(r'\\s*do [^\\s{]', line):\n    error(filename, linenum, 'whitespace/newline', 4,\n          'do/while clauses should not be on a single line')\n\n  # Braces shouldn't be followed by a ; unless they're defining a struct\n  # or initializing an array.\n  # We can't tell in general, but we can for some common cases.\n  prevlinenum = linenum\n  while True:\n    (prevline, prevlinenum) = GetPreviousNonBlankLine(clean_lines, prevlinenum)\n    if Match(r'\\s+{.*}\\s*;', line) and not prevline.count(';'):\n      line = prevline + line\n    else:\n      break\n  if (Search(r'{.*}\\s*;', line) and\n      line.count('{') == line.count('}') and\n      not Search(r'struct|class|enum|\\s*=\\s*{', line)):\n    error(filename, linenum, 'readability/braces', 4,\n          \"You don't need a ; after a }\")\n\n\ndef CheckEmptyLoopBody(filename, clean_lines, linenum, error):\n  \"\"\"Loop for empty loop body with only a single semicolon.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  # Search for loop keywords at the beginning of the line.  Because only\n  # whitespaces are allowed before the keywords, this will also ignore most\n  # do-while-loops, since those lines should start with closing brace.\n  line = clean_lines.elided[linenum]\n  if Match(r'\\s*(for|while)\\s*\\(', line):\n    # Find the end of the conditional expression\n    (end_line, end_linenum, end_pos) = CloseExpression(\n        clean_lines, linenum, line.find('('))\n\n    # Output warning if what follows the condition expression is a semicolon.\n    # No warning for all other cases, including whitespace or newline, since we\n    # have a separate check for semicolons preceded by whitespace.\n    if end_pos >= 0 and Match(r';', end_line[end_pos:]):\n      error(filename, end_linenum, 'whitespace/empty_loop_body', 5,\n            'Empty loop bodies should use {} or continue')\n\n\ndef ReplaceableCheck(operator, macro, line):\n  \"\"\"Determine whether a basic CHECK can be replaced with a more specific one.\n\n  For example suggest using CHECK_EQ instead of CHECK(a == b) and\n  similarly for CHECK_GE, CHECK_GT, CHECK_LE, CHECK_LT, CHECK_NE.\n\n  Args:\n    operator: The C++ operator used in the CHECK.\n    macro: The CHECK or EXPECT macro being called.\n    line: The current source line.\n\n  Returns:\n    True if the CHECK can be replaced with a more specific one.\n  \"\"\"\n\n  # This matches decimal and hex integers, strings, and chars (in that order).\n  match_constant = r'([-+]?(\\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|\".*\"|\\'.*\\')'\n\n  # Expression to match two sides of the operator with something that\n  # looks like a literal, since CHECK(x == iterator) won't compile.\n  # This means we can't catch all the cases where a more specific\n  # CHECK is possible, but it's less annoying than dealing with\n  # extraneous warnings.\n  match_this = (r'\\s*' + macro + r'\\((\\s*' +\n                match_constant + r'\\s*' + operator + r'[^<>].*|'\n                r'.*[^<>]' + operator + r'\\s*' + match_constant +\n                r'\\s*\\))')\n\n  # Don't complain about CHECK(x == NULL) or similar because\n  # CHECK_EQ(x, NULL) won't compile (requires a cast).\n  # Also, don't complain about more complex boolean expressions\n  # involving && or || such as CHECK(a == b || c == d).\n  return Match(match_this, line) and not Search(r'NULL|&&|\\|\\|', line)\n\n\ndef CheckCheck(filename, clean_lines, linenum, error):\n  \"\"\"Checks the use of CHECK and EXPECT macros.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  # Decide the set of replacement macros that should be suggested\n  raw_lines = clean_lines.raw_lines\n  current_macro = ''\n  for macro in _CHECK_MACROS:\n    if raw_lines[linenum].find(macro) >= 0:\n      current_macro = macro\n      break\n  if not current_macro:\n    # Don't waste time here if line doesn't contain 'CHECK' or 'EXPECT'\n    return\n\n  line = clean_lines.elided[linenum]        # get rid of comments and strings\n\n  # Encourage replacing plain CHECKs with CHECK_EQ/CHECK_NE/etc.\n  for operator in ['==', '!=', '>=', '>', '<=', '<']:\n    if ReplaceableCheck(operator, current_macro, line):\n      error(filename, linenum, 'readability/check', 2,\n            'Consider using %s instead of %s(a %s b)' % (\n                _CHECK_REPLACEMENT[current_macro][operator],\n                current_macro, operator))\n      break\n\n\ndef CheckAltTokens(filename, clean_lines, linenum, error):\n  \"\"\"Check alternative keywords being used in boolean expressions.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  line = clean_lines.elided[linenum]\n\n  # Avoid preprocessor lines\n  if Match(r'^\\s*#', line):\n    return\n\n  # Last ditch effort to avoid multi-line comments.  This will not help\n  # if the comment started before the current line or ended after the\n  # current line, but it catches most of the false positives.  At least,\n  # it provides a way to workaround this warning for people who use\n  # multi-line comments in preprocessor macros.\n  #\n  # TODO(unknown): remove this once cpplint has better support for\n  # multi-line comments.\n  if line.find('/*') >= 0 or line.find('*/') >= 0:\n    return\n\n  for match in _ALT_TOKEN_REPLACEMENT_PATTERN.finditer(line):\n    error(filename, linenum, 'readability/alt_tokens', 2,\n          'Use operator %s instead of %s' % (\n              _ALT_TOKEN_REPLACEMENT[match.group(1)], match.group(1)))\n\n\ndef GetLineWidth(line):\n  \"\"\"Determines the width of the line in column positions.\n\n  Args:\n    line: A string, which may be a Unicode string.\n\n  Returns:\n    The width of the line in column positions, accounting for Unicode\n    combining characters and wide characters.\n  \"\"\"\n  if isinstance(line, unicode):\n    width = 0\n    for uc in unicodedata.normalize('NFC', line):\n      if unicodedata.east_asian_width(uc) in ('W', 'F'):\n        width += 2\n      elif not unicodedata.combining(uc):\n        width += 1\n    return width\n  else:\n    return len(line)\n\n\ndef CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,\n               error):\n  \"\"\"Checks rules from the 'C++ style rules' section of cppguide.html.\n\n  Most of these rules are hard to test (naming, comment style), but we\n  do what we can.  In particular we check for 2-space indents, line lengths,\n  tab usage, spaces inside code, etc.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    file_extension: The extension (without the dot) of the filename.\n    nesting_state: A _NestingState instance which maintains information about\n                   the current stack of nested blocks being parsed.\n    error: The function to call with any errors found.\n  \"\"\"\n\n  raw_lines = clean_lines.raw_lines\n  line = raw_lines[linenum]\n\n  if line.find('\\t') != -1:\n    error(filename, linenum, 'whitespace/tab', 1,\n          'Tab found; better to use spaces')\n\n  # One or three blank spaces at the beginning of the line is weird; it's\n  # hard to reconcile that with 2-space indents.\n  # NOTE: here are the conditions rob pike used for his tests.  Mine aren't\n  # as sophisticated, but it may be worth becoming so:  RLENGTH==initial_spaces\n  # if(RLENGTH > 20) complain = 0;\n  # if(match($0, \" +(error|private|public|protected):\")) complain = 0;\n  # if(match(prev, \"&& *$\")) complain = 0;\n  # if(match(prev, \"\\\\|\\\\| *$\")) complain = 0;\n  # if(match(prev, \"[\\\",=><] *$\")) complain = 0;\n  # if(match($0, \" <<\")) complain = 0;\n  # if(match(prev, \" +for \\\\(\")) complain = 0;\n  # if(prevodd && match(prevprev, \" +for \\\\(\")) complain = 0;\n  initial_spaces = 0\n  cleansed_line = clean_lines.elided[linenum]\n  while initial_spaces < len(line) and line[initial_spaces] == ' ':\n    initial_spaces += 1\n  if line and line[-1].isspace():\n    error(filename, linenum, 'whitespace/end_of_line', 4,\n          'Line ends in whitespace.  Consider deleting these extra spaces.')\n  # There are certain situations we allow one space, notably for labels\n  elif ((initial_spaces == 1 or initial_spaces == 3) and\n        not Match(r'\\s*\\w+\\s*:\\s*$', cleansed_line)):\n    error(filename, linenum, 'whitespace/indent', 3,\n          'Weird number of spaces at line-start.  '\n          'Are you using a 2-space indent?')\n  # Labels should always be indented at least one space.\n  elif not initial_spaces and line[:2] != '//' and Search(r'[^:]:\\s*$',\n                                                          line):\n    error(filename, linenum, 'whitespace/labels', 4,\n          'Labels should always be indented at least one space.  '\n          'If this is a member-initializer list in a constructor or '\n          'the base class list in a class definition, the colon should '\n          'be on the following line.')\n\n\n  # Check if the line is a header guard.\n  is_header_guard = False\n  if file_extension == 'h':\n    cppvar = GetHeaderGuardCPPVariable(filename)\n    if (line.startswith('#ifndef %s' % cppvar) or\n        line.startswith('#define %s' % cppvar) or\n        line.startswith('#endif  // %s' % cppvar)):\n      is_header_guard = True\n  # #include lines and header guards can be long, since there's no clean way to\n  # split them.\n  #\n  # URLs can be long too.  It's possible to split these, but it makes them\n  # harder to cut&paste.\n  #\n  # The \"$Id:...$\" comment may also get very long without it being the\n  # developers fault.\n  if (not line.startswith('#include') and not is_header_guard and\n      not Match(r'^\\s*//.*http(s?)://\\S*$', line) and\n      not Match(r'^// \\$Id:.*#[0-9]+ \\$$', line)):\n    line_width = GetLineWidth(line)\n    if line_width > 100:\n      error(filename, linenum, 'whitespace/line_length', 4,\n            'Lines should very rarely be longer than 100 characters')\n    elif line_width > 80:\n      error(filename, linenum, 'whitespace/line_length', 2,\n            'Lines should be <= 80 characters long')\n\n  if (cleansed_line.count(';') > 1 and\n      # for loops are allowed two ;'s (and may run over two lines).\n      cleansed_line.find('for') == -1 and\n      (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or\n       GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and\n      # It's ok to have many commands in a switch case that fits in 1 line\n      not ((cleansed_line.find('case ') != -1 or\n            cleansed_line.find('default:') != -1) and\n           cleansed_line.find('break;') != -1)):\n    error(filename, linenum, 'whitespace/newline', 0,\n          'More than one command on the same line')\n\n  # Some more style checks\n  CheckBraces(filename, clean_lines, linenum, error)\n  CheckEmptyLoopBody(filename, clean_lines, linenum, error)\n  CheckAccess(filename, clean_lines, linenum, nesting_state, error)\n  CheckSpacing(filename, clean_lines, linenum, nesting_state, error)\n  CheckCheck(filename, clean_lines, linenum, error)\n  CheckAltTokens(filename, clean_lines, linenum, error)\n  classinfo = nesting_state.InnermostClass()\n  if classinfo:\n    CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error)\n\n\n_RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +\"[^/]+\\.h\"')\n_RE_PATTERN_INCLUDE = re.compile(r'^\\s*#\\s*include\\s*([<\"])([^>\"]*)[>\"].*$')\n# Matches the first component of a filename delimited by -s and _s. That is:\n#  _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo'\n#  _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo'\n#  _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo'\n#  _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo'\n_RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+')\n\n\ndef _DropCommonSuffixes(filename):\n  \"\"\"Drops common suffixes like _test.cc or -inl.h from filename.\n\n  For example:\n    >>> _DropCommonSuffixes('foo/foo-inl.h')\n    'foo/foo'\n    >>> _DropCommonSuffixes('foo/bar/foo.cc')\n    'foo/bar/foo'\n    >>> _DropCommonSuffixes('foo/foo_internal.h')\n    'foo/foo'\n    >>> _DropCommonSuffixes('foo/foo_unusualinternal.h')\n    'foo/foo_unusualinternal'\n\n  Args:\n    filename: The input filename.\n\n  Returns:\n    The filename with the common suffix removed.\n  \"\"\"\n  for suffix in ('test.cc', 'regtest.cc', 'unittest.cc',\n                 'inl.h', 'impl.h', 'internal.h'):\n    if (filename.endswith(suffix) and len(filename) > len(suffix) and\n        filename[-len(suffix) - 1] in ('-', '_')):\n      return filename[:-len(suffix) - 1]\n  return os.path.splitext(filename)[0]\n\n\ndef _IsTestFilename(filename):\n  \"\"\"Determines if the given filename has a suffix that identifies it as a test.\n\n  Args:\n    filename: The input filename.\n\n  Returns:\n    True if 'filename' looks like a test, False otherwise.\n  \"\"\"\n  if (filename.endswith('_test.cc') or\n      filename.endswith('_unittest.cc') or\n      filename.endswith('_regtest.cc')):\n    return True\n  else:\n    return False\n\n\ndef _ClassifyInclude(fileinfo, include, is_system):\n  \"\"\"Figures out what kind of header 'include' is.\n\n  Args:\n    fileinfo: The current file cpplint is running over. A FileInfo instance.\n    include: The path to a #included file.\n    is_system: True if the #include used <> rather than \"\".\n\n  Returns:\n    One of the _XXX_HEADER constants.\n\n  For example:\n    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True)\n    _C_SYS_HEADER\n    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True)\n    _CPP_SYS_HEADER\n    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False)\n    _LIKELY_MY_HEADER\n    >>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'),\n    ...                  'bar/foo_other_ext.h', False)\n    _POSSIBLE_MY_HEADER\n    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False)\n    _OTHER_HEADER\n  \"\"\"\n  # This is a list of all standard c++ header files, except\n  # those already checked for above.\n  is_stl_h = include in _STL_HEADERS\n  is_cpp_h = is_stl_h or include in _CPP_HEADERS\n\n  if is_system:\n    if is_cpp_h:\n      return _CPP_SYS_HEADER\n    else:\n      return _C_SYS_HEADER\n\n  # If the target file and the include we're checking share a\n  # basename when we drop common extensions, and the include\n  # lives in . , then it's likely to be owned by the target file.\n  target_dir, target_base = (\n      os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName())))\n  include_dir, include_base = os.path.split(_DropCommonSuffixes(include))\n  if target_base == include_base and (\n      include_dir == target_dir or\n      include_dir == os.path.normpath(target_dir + '/../public')):\n    return _LIKELY_MY_HEADER\n\n  # If the target and include share some initial basename\n  # component, it's possible the target is implementing the\n  # include, so it's allowed to be first, but we'll never\n  # complain if it's not there.\n  target_first_component = _RE_FIRST_COMPONENT.match(target_base)\n  include_first_component = _RE_FIRST_COMPONENT.match(include_base)\n  if (target_first_component and include_first_component and\n      target_first_component.group(0) ==\n      include_first_component.group(0)):\n    return _POSSIBLE_MY_HEADER\n\n  return _OTHER_HEADER\n\n\n\ndef CheckIncludeLine(filename, clean_lines, linenum, include_state, error):\n  \"\"\"Check rules that are applicable to #include lines.\n\n  Strings on #include lines are NOT removed from elided line, to make\n  certain tasks easier. However, to prevent false positives, checks\n  applicable to #include lines in CheckLanguage must be put here.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    include_state: An _IncludeState instance in which the headers are inserted.\n    error: The function to call with any errors found.\n  \"\"\"\n  fileinfo = FileInfo(filename)\n\n  line = clean_lines.lines[linenum]\n\n  # \"include\" should use the new style \"foo/bar.h\" instead of just \"bar.h\"\n  if _RE_PATTERN_INCLUDE_NEW_STYLE.search(line):\n    error(filename, linenum, 'build/include', 4,\n          'Include the directory when naming .h files')\n\n  # we shouldn't include a file more than once. actually, there are a\n  # handful of instances where doing so is okay, but in general it's\n  # not.\n  match = _RE_PATTERN_INCLUDE.search(line)\n  if match:\n    include = match.group(2)\n    is_system = (match.group(1) == '<')\n    if include in include_state:\n      error(filename, linenum, 'build/include', 4,\n            '\"%s\" already included at %s:%s' %\n            (include, filename, include_state[include]))\n    else:\n      include_state[include] = linenum\n\n      # We want to ensure that headers appear in the right order:\n      # 1) for foo.cc, foo.h  (preferred location)\n      # 2) c system files\n      # 3) cpp system files\n      # 4) for foo.cc, foo.h  (deprecated location)\n      # 5) other google headers\n      #\n      # We classify each include statement as one of those 5 types\n      # using a number of techniques. The include_state object keeps\n      # track of the highest type seen, and complains if we see a\n      # lower type after that.\n      error_message = include_state.CheckNextIncludeOrder(\n          _ClassifyInclude(fileinfo, include, is_system))\n      if error_message:\n        error(filename, linenum, 'build/include_order', 4,\n              '%s. Should be: %s.h, c system, c++ system, other.' %\n              (error_message, fileinfo.BaseName()))\n      if not include_state.IsInAlphabeticalOrder(include):\n        error(filename, linenum, 'build/include_alpha', 4,\n              'Include \"%s\" not in alphabetical order' % include)\n\n  # Look for any of the stream classes that are part of standard C++.\n  match = _RE_PATTERN_INCLUDE.match(line)\n  if match:\n    include = match.group(2)\n    if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include):\n      # Many unit tests use cout, so we exempt them.\n      if not _IsTestFilename(filename):\n        error(filename, linenum, 'readability/streams', 3,\n              'Streams are highly discouraged.')\n\n\ndef _GetTextInside(text, start_pattern):\n  \"\"\"Retrieves all the text between matching open and close parentheses.\n\n  Given a string of lines and a regular expression string, retrieve all the text\n  following the expression and between opening punctuation symbols like\n  (, [, or {, and the matching close-punctuation symbol. This properly nested\n  occurrences of the punctuations, so for the text like\n    printf(a(), b(c()));\n  a call to _GetTextInside(text, r'printf\\(') will return 'a(), b(c())'.\n  start_pattern must match string having an open punctuation symbol at the end.\n\n  Args:\n    text: The lines to extract text. Its comments and strings must be elided.\n           It can be single line and can span multiple lines.\n    start_pattern: The regexp string indicating where to start extracting\n                   the text.\n  Returns:\n    The extracted text.\n    None if either the opening string or ending punctuation could not be found.\n  \"\"\"\n  # TODO(sugawarayu): Audit cpplint.py to see what places could be profitably\n  # rewritten to use _GetTextInside (and use inferior regexp matching today).\n\n  # Give opening punctuations to get the matching close-punctuations.\n  matching_punctuation = {'(': ')', '{': '}', '[': ']'}\n  closing_punctuation = set(matching_punctuation.itervalues())\n\n  # Find the position to start extracting text.\n  match = re.search(start_pattern, text, re.M)\n  if not match:  # start_pattern not found in text.\n    return None\n  start_position = match.end(0)\n\n  assert start_position > 0, (\n      'start_pattern must ends with an opening punctuation.')\n  assert text[start_position - 1] in matching_punctuation, (\n      'start_pattern must ends with an opening punctuation.')\n  # Stack of closing punctuations we expect to have in text after position.\n  punctuation_stack = [matching_punctuation[text[start_position - 1]]]\n  position = start_position\n  while punctuation_stack and position < len(text):\n    if text[position] == punctuation_stack[-1]:\n      punctuation_stack.pop()\n    elif text[position] in closing_punctuation:\n      # A closing punctuation without matching opening punctuations.\n      return None\n    elif text[position] in matching_punctuation:\n      punctuation_stack.append(matching_punctuation[text[position]])\n    position += 1\n  if punctuation_stack:\n    # Opening punctuations left without matching close-punctuations.\n    return None\n  # punctuations match.\n  return text[start_position:position - 1]\n\n\ndef CheckLanguage(filename, clean_lines, linenum, file_extension, include_state,\n                  error):\n  \"\"\"Checks rules from the 'C++ language rules' section of cppguide.html.\n\n  Some of these rules are hard to test (function overloading, using\n  uint32 inappropriately), but we do the best we can.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    file_extension: The extension (without the dot) of the filename.\n    include_state: An _IncludeState instance in which the headers are inserted.\n    error: The function to call with any errors found.\n  \"\"\"\n  # If the line is empty or consists of entirely a comment, no need to\n  # check it.\n  line = clean_lines.elided[linenum]\n  if not line:\n    return\n\n  match = _RE_PATTERN_INCLUDE.search(line)\n  if match:\n    CheckIncludeLine(filename, clean_lines, linenum, include_state, error)\n    return\n\n  # Create an extended_line, which is the concatenation of the current and\n  # next lines, for more effective checking of code that may span more than one\n  # line.\n  if linenum + 1 < clean_lines.NumLines():\n    extended_line = line + clean_lines.elided[linenum + 1]\n  else:\n    extended_line = line\n\n  # Make Windows paths like Unix.\n  fullname = os.path.abspath(filename).replace('\\\\', '/')\n\n  # TODO(unknown): figure out if they're using default arguments in fn proto.\n\n  # Check for non-const references in functions.  This is tricky because &\n  # is also used to take the address of something.  We allow <> for templates,\n  # (ignoring whatever is between the braces) and : for classes.\n  # These are complicated re's.  They try to capture the following:\n  # paren (for fn-prototype start), typename, &, varname.  For the const\n  # version, we're willing for const to be before typename or after\n  # Don't check the implementation on same line.\n  fnline = line.split('{', 1)[0]\n  if (len(re.findall(r'\\([^()]*\\b(?:[\\w:]|<[^()]*>)+(\\s?&|&\\s?)\\w+', fnline)) >\n      len(re.findall(r'\\([^()]*\\bconst\\s+(?:typename\\s+)?(?:struct\\s+)?'\n                     r'(?:[\\w:]|<[^()]*>)+(\\s?&|&\\s?)\\w+', fnline)) +\n      len(re.findall(r'\\([^()]*\\b(?:[\\w:]|<[^()]*>)+\\s+const(\\s?&|&\\s?)[\\w]+',\n                     fnline))):\n\n    # We allow non-const references in a few standard places, like functions\n    # called \"swap()\" or iostream operators like \"<<\" or \">>\". We also filter\n    # out for loops, which lint otherwise mistakenly thinks are functions.\n    if not Search(\n        r'(for|swap|Swap|operator[<>][<>])\\s*\\(\\s*'\n        r'(?:(?:typename\\s*)?[\\w:]|<.*>)+\\s*&',\n        fnline):\n      error(filename, linenum, 'runtime/references', 2,\n            'Is this a non-const reference? '\n            'If so, make const or use a pointer.')\n\n  # Check to see if they're using an conversion function cast.\n  # I just try to capture the most common basic types, though there are more.\n  # Parameterless conversion functions, such as bool(), are allowed as they are\n  # probably a member operator declaration or default constructor.\n  match = Search(\n      r'(\\bnew\\s+)?\\b'  # Grab 'new' operator, if it's there\n      r'(int|float|double|bool|char|int32|uint32|int64|uint64)\\([^)]', line)\n  if match:\n    # gMock methods are defined using some variant of MOCK_METHODx(name, type)\n    # where type may be float(), int(string), etc.  Without context they are\n    # virtually indistinguishable from int(x) casts. Likewise, gMock's\n    # MockCallback takes a template parameter of the form return_type(arg_type),\n    # which looks much like the cast we're trying to detect.\n    if (match.group(1) is None and  # If new operator, then this isn't a cast\n        not (Match(r'^\\s*MOCK_(CONST_)?METHOD\\d+(_T)?\\(', line) or\n             Match(r'^\\s*MockCallback<.*>', line))):\n      # Try a bit harder to catch gmock lines: the only place where\n      # something looks like an old-style cast is where we declare the\n      # return type of the mocked method, and the only time when we\n      # are missing context is if MOCK_METHOD was split across\n      # multiple lines (for example http://go/hrfhr ), so we only need\n      # to check the previous line for MOCK_METHOD.\n      if (linenum == 0 or\n          not Match(r'^\\s*MOCK_(CONST_)?METHOD\\d+(_T)?\\(\\S+,\\s*$',\n                    clean_lines.elided[linenum - 1])):\n        error(filename, linenum, 'readability/casting', 4,\n              'Using deprecated casting style.  '\n              'Use static_cast<%s>(...) instead' %\n              match.group(2))\n\n  CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],\n                  'static_cast',\n                  r'\\((int|float|double|bool|char|u?int(16|32|64))\\)', error)\n\n  # This doesn't catch all cases. Consider (const char * const)\"hello\".\n  #\n  # (char *) \"foo\" should always be a const_cast (reinterpret_cast won't\n  # compile).\n  if CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],\n                     'const_cast', r'\\((char\\s?\\*+\\s?)\\)\\s*\"', error):\n    pass\n  else:\n    # Check pointer casts for other than string constants\n    CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],\n                    'reinterpret_cast', r'\\((\\w+\\s?\\*+\\s?)\\)', error)\n\n  # In addition, we look for people taking the address of a cast.  This\n  # is dangerous -- casts can assign to temporaries, so the pointer doesn't\n  # point where you think.\n  if Search(\n      r'(&\\([^)]+\\)[\\w(])|(&(static|dynamic|reinterpret)_cast\\b)', line):\n    error(filename, linenum, 'runtime/casting', 4,\n          ('Are you taking an address of a cast?  '\n           'This is dangerous: could be a temp var.  '\n           'Take the address before doing the cast, rather than after'))\n\n  # Check for people declaring static/global STL strings at the top level.\n  # This is dangerous because the C++ language does not guarantee that\n  # globals with constructors are initialized before the first access.\n  match = Match(\n      r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\\b(.*)',\n      line)\n  # Make sure it's not a function.\n  # Function template specialization looks like: \"string foo<Type>(...\".\n  # Class template definitions look like: \"string Foo<Type>::Method(...\".\n  if match and not Match(r'\\s*(<.*>)?(::[a-zA-Z0-9_]+)?\\s*\\(([^\"]|$)',\n                         match.group(3)):\n    error(filename, linenum, 'runtime/string', 4,\n          'For a static/global string constant, use a C style string instead: '\n          '\"%schar %s[]\".' %\n          (match.group(1), match.group(2)))\n\n  # Check that we're not using RTTI outside of testing code.\n  if Search(r'\\bdynamic_cast<', line) and not _IsTestFilename(filename):\n    error(filename, linenum, 'runtime/rtti', 5,\n          'Do not use dynamic_cast<>.  If you need to cast within a class '\n          \"hierarchy, use static_cast<> to upcast.  Google doesn't support \"\n          'RTTI.')\n\n  if Search(r'\\b([A-Za-z0-9_]*_)\\(\\1\\)', line):\n    error(filename, linenum, 'runtime/init', 4,\n          'You seem to be initializing a member variable with itself.')\n\n  if file_extension == 'h':\n    # TODO(unknown): check that 1-arg constructors are explicit.\n    #                How to tell it's a constructor?\n    #                (handled in CheckForNonStandardConstructs for now)\n    # TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS\n    #                (level 1 error)\n    pass\n\n  # Check if people are using the verboten C basic types.  The only exception\n  # we regularly allow is \"unsigned short port\" for port.\n  if Search(r'\\bshort port\\b', line):\n    if not Search(r'\\bunsigned short port\\b', line):\n      error(filename, linenum, 'runtime/int', 4,\n            'Use \"unsigned short\" for ports, not \"short\"')\n  else:\n    match = Search(r'\\b(short|long(?! +double)|long long)\\b', line)\n    if match:\n      error(filename, linenum, 'runtime/int', 4,\n            'Use int16/int64/etc, rather than the C type %s' % match.group(1))\n\n  # When snprintf is used, the second argument shouldn't be a literal.\n  match = Search(r'snprintf\\s*\\(([^,]*),\\s*([0-9]*)\\s*,', line)\n  if match and match.group(2) != '0':\n    # If 2nd arg is zero, snprintf is used to calculate size.\n    error(filename, linenum, 'runtime/printf', 3,\n          'If you can, use sizeof(%s) instead of %s as the 2nd arg '\n          'to snprintf.' % (match.group(1), match.group(2)))\n\n  # Check if some verboten C functions are being used.\n  if Search(r'\\bsprintf\\b', line):\n    error(filename, linenum, 'runtime/printf', 5,\n          'Never use sprintf.  Use snprintf instead.')\n  match = Search(r'\\b(strcpy|strcat)\\b', line)\n  if match:\n    error(filename, linenum, 'runtime/printf', 4,\n          'Almost always, snprintf is better than %s' % match.group(1))\n\n  if Search(r'\\bsscanf\\b', line):\n    error(filename, linenum, 'runtime/printf', 1,\n          'sscanf can be ok, but is slow and can overflow buffers.')\n\n  # Check if some verboten operator overloading is going on\n  # TODO(unknown): catch out-of-line unary operator&:\n  #   class X {};\n  #   int operator&(const X& x) { return 42; }  // unary operator&\n  # The trick is it's hard to tell apart from binary operator&:\n  #   class Y { int operator&(const Y& x) { return 23; } }; // binary operator&\n  if Search(r'\\boperator\\s*&\\s*\\(\\s*\\)', line):\n    error(filename, linenum, 'runtime/operator', 4,\n          'Unary operator& is dangerous.  Do not use it.')\n\n  # Check for suspicious usage of \"if\" like\n  # } if (a == b) {\n  if Search(r'\\}\\s*if\\s*\\(', line):\n    error(filename, linenum, 'readability/braces', 4,\n          'Did you mean \"else if\"? If not, start a new line for \"if\".')\n\n  # Check for potential format string bugs like printf(foo).\n  # We constrain the pattern not to pick things like DocidForPrintf(foo).\n  # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str())\n  # TODO(sugawarayu): Catch the following case. Need to change the calling\n  # convention of the whole function to process multiple line to handle it.\n  #   printf(\n  #       boy_this_is_a_really_long_variable_that_cannot_fit_on_the_prev_line);\n  printf_args = _GetTextInside(line, r'(?i)\\b(string)?printf\\s*\\(')\n  if printf_args:\n    match = Match(r'([\\w.\\->()]+)$', printf_args)\n    if match and match.group(1) != '__VA_ARGS__':\n      function_name = re.search(r'\\b((?:string)?printf)\\s*\\(',\n                                line, re.I).group(1)\n      error(filename, linenum, 'runtime/printf', 4,\n            'Potential format string bug. Do %s(\"%%s\", %s) instead.'\n            % (function_name, match.group(1)))\n\n  # Check for potential memset bugs like memset(buf, sizeof(buf), 0).\n  match = Search(r'memset\\s*\\(([^,]*),\\s*([^,]*),\\s*0\\s*\\)', line)\n  if match and not Match(r\"^''|-?[0-9]+|0x[0-9A-Fa-f]$\", match.group(2)):\n    error(filename, linenum, 'runtime/memset', 4,\n          'Did you mean \"memset(%s, 0, %s)\"?'\n          % (match.group(1), match.group(2)))\n\n  if Search(r'\\busing namespace\\b', line):\n    error(filename, linenum, 'build/namespaces', 5,\n          'Do not use namespace using-directives.  '\n          'Use using-declarations instead.')\n\n  # Detect variable-length arrays.\n  match = Match(r'\\s*(.+::)?(\\w+) [a-z]\\w*\\[(.+)];', line)\n  if (match and match.group(2) != 'return' and match.group(2) != 'delete' and\n      match.group(3).find(']') == -1):\n    # Split the size using space and arithmetic operators as delimiters.\n    # If any of the resulting tokens are not compile time constants then\n    # report the error.\n    tokens = re.split(r'\\s|\\+|\\-|\\*|\\/|<<|>>]', match.group(3))\n    is_const = True\n    skip_next = False\n    for tok in tokens:\n      if skip_next:\n        skip_next = False\n        continue\n\n      if Search(r'sizeof\\(.+\\)', tok): continue\n      if Search(r'arraysize\\(\\w+\\)', tok): continue\n\n      tok = tok.lstrip('(')\n      tok = tok.rstrip(')')\n      if not tok: continue\n      if Match(r'\\d+', tok): continue\n      if Match(r'0[xX][0-9a-fA-F]+', tok): continue\n      if Match(r'k[A-Z0-9]\\w*', tok): continue\n      if Match(r'(.+::)?k[A-Z0-9]\\w*', tok): continue\n      if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue\n      # A catch all for tricky sizeof cases, including 'sizeof expression',\n      # 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)'\n      # requires skipping the next token because we split on ' ' and '*'.\n      if tok.startswith('sizeof'):\n        skip_next = True\n        continue\n      is_const = False\n      break\n    if not is_const:\n      error(filename, linenum, 'runtime/arrays', 1,\n            'Do not use variable-length arrays.  Use an appropriately named '\n            \"('k' followed by CamelCase) compile-time constant for the size.\")\n\n  # If DISALLOW_EVIL_CONSTRUCTORS, DISALLOW_COPY_AND_ASSIGN, or\n  # DISALLOW_IMPLICIT_CONSTRUCTORS is present, then it should be the last thing\n  # in the class declaration.\n  match = Match(\n      (r'\\s*'\n       r'(DISALLOW_(EVIL_CONSTRUCTORS|COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))'\n       r'\\(.*\\);$'),\n      line)\n  if match and linenum + 1 < clean_lines.NumLines():\n    next_line = clean_lines.elided[linenum + 1]\n    # We allow some, but not all, declarations of variables to be present\n    # in the statement that defines the class.  The [\\w\\*,\\s]* fragment of\n    # the regular expression below allows users to declare instances of\n    # the class or pointers to instances, but not less common types such\n    # as function pointers or arrays.  It's a tradeoff between allowing\n    # reasonable code and avoiding trying to parse more C++ using regexps.\n    if not Search(r'^\\s*}[\\w\\*,\\s]*;', next_line):\n      error(filename, linenum, 'readability/constructors', 3,\n            match.group(1) + ' should be the last thing in the class')\n\n  # Check for use of unnamed namespaces in header files.  Registration\n  # macros are typically OK, so we allow use of \"namespace {\" on lines\n  # that end with backslashes.\n  if (file_extension == 'h'\n      and Search(r'\\bnamespace\\s*{', line)\n      and line[-1] != '\\\\'):\n    error(filename, linenum, 'build/namespaces', 4,\n          'Do not use unnamed namespaces in header files.  See '\n          'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'\n          ' for more information.')\n\n\ndef CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern,\n                    error):\n  \"\"\"Checks for a C-style cast by looking for the pattern.\n\n  This also handles sizeof(type) warnings, due to similarity of content.\n\n  Args:\n    filename: The name of the current file.\n    linenum: The number of the line to check.\n    line: The line of code to check.\n    raw_line: The raw line of code to check, with comments.\n    cast_type: The string for the C++ cast to recommend.  This is either\n      reinterpret_cast, static_cast, or const_cast, depending.\n    pattern: The regular expression used to find C-style casts.\n    error: The function to call with any errors found.\n\n  Returns:\n    True if an error was emitted.\n    False otherwise.\n  \"\"\"\n  match = Search(pattern, line)\n  if not match:\n    return False\n\n  # e.g., sizeof(int)\n  sizeof_match = Match(r'.*sizeof\\s*$', line[0:match.start(1) - 1])\n  if sizeof_match:\n    error(filename, linenum, 'runtime/sizeof', 1,\n          'Using sizeof(type).  Use sizeof(varname) instead if possible')\n    return True\n\n  # operator++(int) and operator--(int)\n  if (line[0:match.start(1) - 1].endswith(' operator++') or\n      line[0:match.start(1) - 1].endswith(' operator--')):\n    return False\n\n  remainder = line[match.end(0):]\n\n  # The close paren is for function pointers as arguments to a function.\n  # eg, void foo(void (*bar)(int));\n  # The semicolon check is a more basic function check; also possibly a\n  # function pointer typedef.\n  # eg, void foo(int); or void foo(int) const;\n  # The equals check is for function pointer assignment.\n  # eg, void *(*foo)(int) = ...\n  # The > is for MockCallback<...> ...\n  #\n  # Right now, this will only catch cases where there's a single argument, and\n  # it's unnamed.  It should probably be expanded to check for multiple\n  # arguments with some unnamed.\n  function_match = Match(r'\\s*(\\)|=|(const)?\\s*(;|\\{|throw\\(\\)|>))', remainder)\n  if function_match:\n    if (not function_match.group(3) or\n        function_match.group(3) == ';' or\n        ('MockCallback<' not in raw_line and\n         '/*' not in raw_line)):\n      error(filename, linenum, 'readability/function', 3,\n            'All parameters should be named in a function')\n    return True\n\n  # At this point, all that should be left is actual casts.\n  error(filename, linenum, 'readability/casting', 4,\n        'Using C-style cast.  Use %s<%s>(...) instead' %\n        (cast_type, match.group(1)))\n\n  return True\n\n\n_HEADERS_CONTAINING_TEMPLATES = (\n    ('<deque>', ('deque',)),\n    ('<functional>', ('unary_function', 'binary_function',\n                      'plus', 'minus', 'multiplies', 'divides', 'modulus',\n                      'negate',\n                      'equal_to', 'not_equal_to', 'greater', 'less',\n                      'greater_equal', 'less_equal',\n                      'logical_and', 'logical_or', 'logical_not',\n                      'unary_negate', 'not1', 'binary_negate', 'not2',\n                      'bind1st', 'bind2nd',\n                      'pointer_to_unary_function',\n                      'pointer_to_binary_function',\n                      'ptr_fun',\n                      'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t',\n                      'mem_fun_ref_t',\n                      'const_mem_fun_t', 'const_mem_fun1_t',\n                      'const_mem_fun_ref_t', 'const_mem_fun1_ref_t',\n                      'mem_fun_ref',\n                     )),\n    ('<limits>', ('numeric_limits',)),\n    ('<list>', ('list',)),\n    ('<map>', ('map', 'multimap',)),\n    ('<memory>', ('allocator',)),\n    ('<queue>', ('queue', 'priority_queue',)),\n    ('<set>', ('set', 'multiset',)),\n    ('<stack>', ('stack',)),\n    ('<string>', ('char_traits', 'basic_string',)),\n    ('<utility>', ('pair',)),\n    ('<vector>', ('vector',)),\n\n    # gcc extensions.\n    # Note: std::hash is their hash, ::hash is our hash\n    ('<hash_map>', ('hash_map', 'hash_multimap',)),\n    ('<hash_set>', ('hash_set', 'hash_multiset',)),\n    ('<slist>', ('slist',)),\n    )\n\n_RE_PATTERN_STRING = re.compile(r'\\bstring\\b')\n\n_re_pattern_algorithm_header = []\nfor _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap',\n                  'transform'):\n  # Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or\n  # type::max().\n  _re_pattern_algorithm_header.append(\n      (re.compile(r'[^>.]\\b' + _template + r'(<.*?>)?\\([^\\)]'),\n       _template,\n       '<algorithm>'))\n\n_re_pattern_templates = []\nfor _header, _templates in _HEADERS_CONTAINING_TEMPLATES:\n  for _template in _templates:\n    _re_pattern_templates.append(\n        (re.compile(r'(\\<|\\b)' + _template + r'\\s*\\<'),\n         _template + '<>',\n         _header))\n\n\ndef FilesBelongToSameModule(filename_cc, filename_h):\n  \"\"\"Check if these two filenames belong to the same module.\n\n  The concept of a 'module' here is a as follows:\n  foo.h, foo-inl.h, foo.cc, foo_test.cc and foo_unittest.cc belong to the\n  same 'module' if they are in the same directory.\n  some/path/public/xyzzy and some/path/internal/xyzzy are also considered\n  to belong to the same module here.\n\n  If the filename_cc contains a longer path than the filename_h, for example,\n  '/absolute/path/to/base/sysinfo.cc', and this file would include\n  'base/sysinfo.h', this function also produces the prefix needed to open the\n  header. This is used by the caller of this function to more robustly open the\n  header file. We don't have access to the real include paths in this context,\n  so we need this guesswork here.\n\n  Known bugs: tools/base/bar.cc and base/bar.h belong to the same module\n  according to this implementation. Because of this, this function gives\n  some false positives. This should be sufficiently rare in practice.\n\n  Args:\n    filename_cc: is the path for the .cc file\n    filename_h: is the path for the header path\n\n  Returns:\n    Tuple with a bool and a string:\n    bool: True if filename_cc and filename_h belong to the same module.\n    string: the additional prefix needed to open the header file.\n  \"\"\"\n\n  if not filename_cc.endswith('.cc'):\n    return (False, '')\n  filename_cc = filename_cc[:-len('.cc')]\n  if filename_cc.endswith('_unittest'):\n    filename_cc = filename_cc[:-len('_unittest')]\n  elif filename_cc.endswith('_test'):\n    filename_cc = filename_cc[:-len('_test')]\n  filename_cc = filename_cc.replace('/public/', '/')\n  filename_cc = filename_cc.replace('/internal/', '/')\n\n  if not filename_h.endswith('.h'):\n    return (False, '')\n  filename_h = filename_h[:-len('.h')]\n  if filename_h.endswith('-inl'):\n    filename_h = filename_h[:-len('-inl')]\n  filename_h = filename_h.replace('/public/', '/')\n  filename_h = filename_h.replace('/internal/', '/')\n\n  files_belong_to_same_module = filename_cc.endswith(filename_h)\n  common_path = ''\n  if files_belong_to_same_module:\n    common_path = filename_cc[:-len(filename_h)]\n  return files_belong_to_same_module, common_path\n\n\ndef UpdateIncludeState(filename, include_state, io=codecs):\n  \"\"\"Fill up the include_state with new includes found from the file.\n\n  Args:\n    filename: the name of the header to read.\n    include_state: an _IncludeState instance in which the headers are inserted.\n    io: The io factory to use to read the file. Provided for testability.\n\n  Returns:\n    True if a header was successfully added. False otherwise.\n  \"\"\"\n  headerfile = None\n  try:\n    headerfile = io.open(filename, 'r', 'utf8', 'replace')\n  except IOError:\n    return False\n  linenum = 0\n  for line in headerfile:\n    linenum += 1\n    clean_line = CleanseComments(line)\n    match = _RE_PATTERN_INCLUDE.search(clean_line)\n    if match:\n      include = match.group(2)\n      # The value formatting is cute, but not really used right now.\n      # What matters here is that the key is in include_state.\n      include_state.setdefault(include, '%s:%d' % (filename, linenum))\n  return True\n\n\ndef CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,\n                              io=codecs):\n  \"\"\"Reports for missing stl includes.\n\n  This function will output warnings to make sure you are including the headers\n  necessary for the stl containers and functions that you use. We only give one\n  reason to include a header. For example, if you use both equal_to<> and\n  less<> in a .h file, only one (the latter in the file) of these will be\n  reported as a reason to include the <functional>.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    include_state: An _IncludeState instance.\n    error: The function to call with any errors found.\n    io: The IO factory to use to read the header file. Provided for unittest\n        injection.\n  \"\"\"\n  required = {}  # A map of header name to linenumber and the template entity.\n                 # Example of required: { '<functional>': (1219, 'less<>') }\n\n  for linenum in xrange(clean_lines.NumLines()):\n    line = clean_lines.elided[linenum]\n    if not line or line[0] == '#':\n      continue\n\n    # String is special -- it is a non-templatized type in STL.\n    matched = _RE_PATTERN_STRING.search(line)\n    if matched:\n      # Don't warn about strings in non-STL namespaces:\n      # (We check only the first match per line; good enough.)\n      prefix = line[:matched.start()]\n      if prefix.endswith('std::') or not prefix.endswith('::'):\n        required['<string>'] = (linenum, 'string')\n\n    for pattern, template, header in _re_pattern_algorithm_header:\n      if pattern.search(line):\n        required[header] = (linenum, template)\n\n    # The following function is just a speed up, no semantics are changed.\n    if not '<' in line:  # Reduces the cpu time usage by skipping lines.\n      continue\n\n    for pattern, template, header in _re_pattern_templates:\n      if pattern.search(line):\n        required[header] = (linenum, template)\n\n  # The policy is that if you #include something in foo.h you don't need to\n  # include it again in foo.cc. Here, we will look at possible includes.\n  # Let's copy the include_state so it is only messed up within this function.\n  include_state = include_state.copy()\n\n  # Did we find the header for this file (if any) and successfully load it?\n  header_found = False\n\n  # Use the absolute path so that matching works properly.\n  abs_filename = FileInfo(filename).FullName()\n\n  # For Emacs's flymake.\n  # If cpplint is invoked from Emacs's flymake, a temporary file is generated\n  # by flymake and that file name might end with '_flymake.cc'. In that case,\n  # restore original file name here so that the corresponding header file can be\n  # found.\n  # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h'\n  # instead of 'foo_flymake.h'\n  abs_filename = re.sub(r'_flymake\\.cc$', '.cc', abs_filename)\n\n  # include_state is modified during iteration, so we iterate over a copy of\n  # the keys.\n  header_keys = include_state.keys()\n  for header in header_keys:\n    (same_module, common_path) = FilesBelongToSameModule(abs_filename, header)\n    fullpath = common_path + header\n    if same_module and UpdateIncludeState(fullpath, include_state, io):\n      header_found = True\n\n  # If we can't find the header file for a .cc, assume it's because we don't\n  # know where to look. In that case we'll give up as we're not sure they\n  # didn't include it in the .h file.\n  # TODO(unknown): Do a better job of finding .h files so we are confident that\n  # not having the .h file means there isn't one.\n  if filename.endswith('.cc') and not header_found:\n    return\n\n  # All the lines have been processed, report the errors found.\n  for required_header_unstripped in required:\n    template = required[required_header_unstripped][1]\n    if required_header_unstripped.strip('<>\"') not in include_state:\n      error(filename, required[required_header_unstripped][0],\n            'build/include_what_you_use', 4,\n            'Add #include ' + required_header_unstripped + ' for ' + template)\n\n\n_RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\\bmake_pair\\s*<')\n\n\ndef CheckMakePairUsesDeduction(filename, clean_lines, linenum, error):\n  \"\"\"Check that make_pair's template arguments are deduced.\n\n  G++ 4.6 in C++0x mode fails badly if make_pair's template arguments are\n  specified explicitly, and such use isn't intended in any case.\n\n  Args:\n    filename: The name of the current file.\n    clean_lines: A CleansedLines instance containing the file.\n    linenum: The number of the line to check.\n    error: The function to call with any errors found.\n  \"\"\"\n  raw = clean_lines.raw_lines\n  line = raw[linenum]\n  match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line)\n  if match:\n    error(filename, linenum, 'build/explicit_make_pair',\n          4,  # 4 = high confidence\n          'For C++11-compatibility, omit template arguments from make_pair'\n          ' OR use pair directly OR if appropriate, construct a pair directly')\n\n\ndef ProcessLine(filename, file_extension, clean_lines, line,\n                include_state, function_state, nesting_state, error,\n                extra_check_functions=[]):\n  \"\"\"Processes a single line in the file.\n\n  Args:\n    filename: Filename of the file that is being processed.\n    file_extension: The extension (dot not included) of the file.\n    clean_lines: An array of strings, each representing a line of the file,\n                 with comments stripped.\n    line: Number of line being processed.\n    include_state: An _IncludeState instance in which the headers are inserted.\n    function_state: A _FunctionState instance which counts function lines, etc.\n    nesting_state: A _NestingState instance which maintains information about\n                   the current stack of nested blocks being parsed.\n    error: A callable to which errors are reported, which takes 4 arguments:\n           filename, line number, error level, and message\n    extra_check_functions: An array of additional check functions that will be\n                           run on each source line. Each function takes 4\n                           arguments: filename, clean_lines, line, error\n  \"\"\"\n  raw_lines = clean_lines.raw_lines\n  ParseNolintSuppressions(filename, raw_lines[line], line, error)\n  nesting_state.Update(filename, clean_lines, line, error)\n  if nesting_state.stack and nesting_state.stack[-1].inline_asm != _NO_ASM:\n    return\n  CheckForFunctionLengths(filename, clean_lines, line, function_state, error)\n  CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error)\n  CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error)\n  CheckLanguage(filename, clean_lines, line, file_extension, include_state,\n                error)\n  CheckForNonStandardConstructs(filename, clean_lines, line,\n                                nesting_state, error)\n  CheckPosixThreading(filename, clean_lines, line, error)\n  CheckInvalidIncrement(filename, clean_lines, line, error)\n  CheckMakePairUsesDeduction(filename, clean_lines, line, error)\n  for check_fn in extra_check_functions:\n    check_fn(filename, clean_lines, line, error)\n\ndef ProcessFileData(filename, file_extension, lines, error,\n                    extra_check_functions=[]):\n  \"\"\"Performs lint checks and reports any errors to the given error function.\n\n  Args:\n    filename: Filename of the file that is being processed.\n    file_extension: The extension (dot not included) of the file.\n    lines: An array of strings, each representing a line of the file, with the\n           last element being empty if the file is terminated with a newline.\n    error: A callable to which errors are reported, which takes 4 arguments:\n           filename, line number, error level, and message\n    extra_check_functions: An array of additional check functions that will be\n                           run on each source line. Each function takes 4\n                           arguments: filename, clean_lines, line, error\n  \"\"\"\n  lines = (['// marker so line numbers and indices both start at 1'] + lines +\n           ['// marker so line numbers end in a known way'])\n\n  include_state = _IncludeState()\n  function_state = _FunctionState()\n  nesting_state = _NestingState()\n\n  ResetNolintSuppressions()\n\n  CheckForCopyright(filename, lines, error)\n\n  if file_extension == 'h':\n    CheckForHeaderGuard(filename, lines, error)\n\n  RemoveMultiLineComments(filename, lines, error)\n  clean_lines = CleansedLines(lines)\n  for line in xrange(clean_lines.NumLines()):\n    ProcessLine(filename, file_extension, clean_lines, line,\n                include_state, function_state, nesting_state, error,\n                extra_check_functions)\n  nesting_state.CheckClassFinished(filename, error)\n\n  CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)\n\n  # We check here rather than inside ProcessLine so that we see raw\n  # lines rather than \"cleaned\" lines.\n  CheckForUnicodeReplacementCharacters(filename, lines, error)\n\n  CheckForNewlineAtEOF(filename, lines, error)\n\ndef ProcessFile(filename, vlevel, extra_check_functions=[]):\n  \"\"\"Does google-lint on a single file.\n\n  Args:\n    filename: The name of the file to parse.\n\n    vlevel: The level of errors to report.  Every error of confidence\n    >= verbose_level will be reported.  0 is a good default.\n\n    extra_check_functions: An array of additional check functions that will be\n                           run on each source line. Each function takes 4\n                           arguments: filename, clean_lines, line, error\n  \"\"\"\n\n  _SetVerboseLevel(vlevel)\n\n  try:\n    # Support the UNIX convention of using \"-\" for stdin.  Note that\n    # we are not opening the file with universal newline support\n    # (which codecs doesn't support anyway), so the resulting lines do\n    # contain trailing '\\r' characters if we are reading a file that\n    # has CRLF endings.\n    # If after the split a trailing '\\r' is present, it is removed\n    # below. If it is not expected to be present (i.e. os.linesep !=\n    # '\\r\\n' as in Windows), a warning is issued below if this file\n    # is processed.\n\n    if filename == '-':\n      lines = codecs.StreamReaderWriter(sys.stdin,\n                                        codecs.getreader('utf8'),\n                                        codecs.getwriter('utf8'),\n                                        'replace').read().split('\\n')\n    else:\n      lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\\n')\n\n    carriage_return_found = False\n    # Remove trailing '\\r'.\n    for linenum in range(len(lines)):\n      if lines[linenum].endswith('\\r'):\n        lines[linenum] = lines[linenum].rstrip('\\r')\n        carriage_return_found = True\n\n  except IOError:\n    sys.stderr.write(\n        \"Skipping input '%s': Can't open for reading\\n\" % filename)\n    return\n\n  # Note, if no dot is found, this will give the entire filename as the ext.\n  file_extension = filename[filename.rfind('.') + 1:]\n\n  # When reading from stdin, the extension is unknown, so no cpplint tests\n  # should rely on the extension.\n  if (filename != '-' and file_extension != 'cc' and file_extension != 'h'\n      and file_extension != 'cpp'):\n    sys.stderr.write('Ignoring %s; not a .cc or .h file\\n' % filename)\n  else:\n    ProcessFileData(filename, file_extension, lines, Error,\n                    extra_check_functions)\n    if carriage_return_found and os.linesep != '\\r\\n':\n      # Use 0 for linenum since outputting only one error for potentially\n      # several lines.\n      Error(filename, 0, 'whitespace/newline', 1,\n            'One or more unexpected \\\\r (^M) found;'\n            'better to use only a \\\\n')\n\n  sys.stderr.write('Done processing %s\\n' % filename)\n\n\ndef PrintUsage(message):\n  \"\"\"Prints a brief usage string and exits, optionally with an error message.\n\n  Args:\n    message: The optional error message.\n  \"\"\"\n  sys.stderr.write(_USAGE)\n  if message:\n    sys.exit('\\nFATAL ERROR: ' + message)\n  else:\n    sys.exit(1)\n\n\ndef PrintCategories():\n  \"\"\"Prints a list of all the error-categories used by error messages.\n\n  These are the categories used to filter messages via --filter.\n  \"\"\"\n  sys.stderr.write(''.join('  %s\\n' % cat for cat in _ERROR_CATEGORIES))\n  sys.exit(0)\n\n\ndef ParseArguments(args):\n  \"\"\"Parses the command line arguments.\n\n  This may set the output format and verbosity level as side-effects.\n\n  Args:\n    args: The command line arguments:\n\n  Returns:\n    The list of filenames to lint.\n  \"\"\"\n  try:\n    (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=',\n                                                 'counting=',\n                                                 'filter=',\n                                                 'root='])\n  except getopt.GetoptError:\n    PrintUsage('Invalid arguments.')\n\n  verbosity = _VerboseLevel()\n  output_format = _OutputFormat()\n  filters = ''\n  counting_style = ''\n\n  for (opt, val) in opts:\n    if opt == '--help':\n      PrintUsage(None)\n    elif opt == '--output':\n      if not val in ('emacs', 'vs7', 'eclipse'):\n        PrintUsage('The only allowed output formats are emacs, vs7 and eclipse.')\n      output_format = val\n    elif opt == '--verbose':\n      verbosity = int(val)\n    elif opt == '--filter':\n      filters = val\n      if not filters:\n        PrintCategories()\n    elif opt == '--counting':\n      if val not in ('total', 'toplevel', 'detailed'):\n        PrintUsage('Valid counting options are total, toplevel, and detailed')\n      counting_style = val\n    elif opt == '--root':\n      global _root\n      _root = val\n\n  if not filenames:\n    PrintUsage('No files were specified.')\n\n  _SetOutputFormat(output_format)\n  _SetVerboseLevel(verbosity)\n  _SetFilters(filters)\n  _SetCountingStyle(counting_style)\n\n  return filenames\n\n\ndef main():\n  filenames = ParseArguments(sys.argv[1:])\n\n  # Change stderr to write with replacement characters so we don't die\n  # if we try to print something containing non-ASCII characters.\n  sys.stderr = codecs.StreamReaderWriter(sys.stderr,\n                                         codecs.getreader('utf8'),\n                                         codecs.getwriter('utf8'),\n                                         'replace')\n\n  _cpplint_state.ResetErrorCounts()\n  for filename in filenames:\n    ProcessFile(filename, _cpplint_state.verbose_level)\n  _cpplint_state.PrintErrorCounts()\n\n  sys.exit(_cpplint_state.error_count > 0)\n\n\nif __name__ == '__main__':\n  main()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/scripts/gen_dynamic_list.py",
    "content": "#!/usr/bin/env python\n#===- lib/sanitizer_common/scripts/gen_dynamic_list.py ---------------------===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n#\n# Generates the list of functions that should be exported from sanitizer\n# runtimes. The output format is recognized by --dynamic-list linker option.\n# Usage:\n#   gen_dynamic_list.py libclang_rt.*san*.a [ files ... ]\n#\n#===------------------------------------------------------------------------===#\nimport argparse\nimport os\nimport re\nimport subprocess\nimport sys\n\nnew_delete = set([\n                  '_Znam', '_ZnamRKSt9nothrow_t',    # operator new[](unsigned long)\n                  '_Znwm', '_ZnwmRKSt9nothrow_t',    # operator new(unsigned long)\n                  '_Znaj', '_ZnajRKSt9nothrow_t',    # operator new[](unsigned int)\n                  '_Znwj', '_ZnwjRKSt9nothrow_t',    # operator new(unsigned int)\n                  '_ZdaPv', '_ZdaPvRKSt9nothrow_t',  # operator delete[](void *)\n                  '_ZdlPv', '_ZdlPvRKSt9nothrow_t',  # operator delete(void *)\n                  '_ZdaPvm',                         # operator delete[](void*, unsigned long)\n                  '_ZdlPvm',                         # operator delete(void*, unsigned long)\n                  '_ZdaPvj',                         # operator delete[](void*, unsigned int)\n                  '_ZdlPvj',                         # operator delete(void*, unsigned int)\n                  ])\n\nversioned_functions = set(['memcpy', 'pthread_attr_getaffinity_np',\n                           'pthread_cond_broadcast',\n                           'pthread_cond_destroy', 'pthread_cond_init',\n                           'pthread_cond_signal', 'pthread_cond_timedwait',\n                           'pthread_cond_wait', 'realpath',\n                           'sched_getaffinity'])\n\ndef get_global_functions(library):\n  functions = []\n  nm_proc = subprocess.Popen(['nm', library], stdout=subprocess.PIPE,\n                             stderr=subprocess.PIPE)\n  nm_out = nm_proc.communicate()[0].decode().split('\\n')\n  if nm_proc.returncode != 0:\n    raise subprocess.CalledProcessError(nm_proc.returncode, 'nm')\n  func_symbols = ['T', 'W']\n  # On PowerPC, nm prints function descriptors from .data section.\n  if os.uname()[4] in [\"powerpc\", \"ppc64\"]:\n    func_symbols += ['D']\n  for line in nm_out:\n    cols = line.split(' ')\n    if len(cols) == 3 and cols[1] in func_symbols :\n      functions.append(cols[2])\n  return functions\n\ndef main(argv):\n  parser = argparse.ArgumentParser()\n  parser.add_argument('--version-list', action='store_true')\n  parser.add_argument('--extra', default=[], action='append')\n  parser.add_argument('libraries', default=[], nargs='+')\n  args = parser.parse_args()\n\n  result = []\n\n  all_functions = []\n  for library in args.libraries:\n    all_functions.extend(get_global_functions(library))\n  function_set = set(all_functions)\n  for func in all_functions:\n    # Export new/delete operators.\n    if func in new_delete:\n      result.append(func)\n      continue\n    # Export interceptors.\n    match = re.match('__interceptor_(.*)', func)\n    if match:\n      result.append(func)\n      # We have to avoid exporting the interceptors for versioned library\n      # functions due to gold internal error.\n      orig_name = match.group(1)\n      if orig_name in function_set and (args.version_list or orig_name not in versioned_functions):\n        result.append(orig_name)\n      continue\n    # Export sanitizer interface functions.\n    if re.match('__sanitizer_(.*)', func):\n      result.append(func)\n\n  # Additional exported functions from files.\n  for fname in args.extra:\n    f = open(fname, 'r')\n    for line in f:\n      result.append(line.rstrip())\n  # Print the resulting list in the format recognized by ld.\n  print('{')\n  if args.version_list:\n    print('global:')\n  result.sort()\n  for f in result:\n    print(u'  %s;' % f)\n  if args.version_list:\n    print('local:')\n    print('  *;')\n  print('};')\n\nif __name__ == '__main__':\n  main(sys.argv)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/scripts/litlint.py",
    "content": "#!/usr/bin/env python\n#\n# litlint\n#\n# Ensure RUN commands in lit tests are free of common errors.\n#\n# If any errors are detected, litlint returns a nonzero exit code.\n#\n\nimport optparse\nimport re\nimport sys\n\n# Compile regex once for all files\nrunRegex = re.compile(r'(?<!-o)(?<!%run) %t\\s')\n\ndef LintLine(s):\n  \"\"\" Validate a line\n\n  Args:\n    s: str, the line to validate\n\n  Returns:\n    Returns an error message and a 1-based column number if an error was\n    detected, otherwise (None, None).\n  \"\"\"\n\n  # Check that RUN command can be executed with an emulator\n  m = runRegex.search(s)\n  if m:\n    start, end = m.span()\n    return ('missing %run before %t', start + 2)\n\n  # No errors\n  return (None, None)\n\n\ndef LintFile(p):\n  \"\"\" Check that each RUN command can be executed with an emulator\n\n  Args:\n    p: str, valid path to a file\n\n  Returns:\n    The number of errors detected.\n  \"\"\"\n  errs = 0\n  with open(p, 'r') as f:\n    for i, s in enumerate(f.readlines(), start=1):\n      msg, col = LintLine(s)\n      if msg != None:\n        errs += 1\n        errorMsg = 'litlint: {}:{}:{}: error: {}.\\n{}{}\\n'\n        arrow = (col-1) * ' ' + '^'\n        sys.stderr.write(errorMsg.format(p, i, col, msg, s, arrow))\n  return errs\n\n\nif __name__ == \"__main__\":\n  # Parse args\n  parser = optparse.OptionParser()\n  parser.add_option('--filter')  # ignored\n  (options, filenames) = parser.parse_args()\n\n  # Lint each file\n  errs = 0\n  for p in filenames:\n    errs += LintFile(p)\n\n  # If errors, return nonzero\n  if errs > 0:\n    sys.exit(1)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/scripts/litlint_test.py",
    "content": "#!/usr/bin/python\n\n# Tests for litlint.py\n#\n# Usage: python litlint_test.py\n#\n# Returns nonzero if any test fails\n\nimport litlint\nimport unittest\n\nclass TestLintLine(unittest.TestCase):\n  def test_missing_run(self):\n    f = litlint.LintLine\n    self.assertEqual(f(' %t '),     ('missing %run before %t', 2))\n    self.assertEqual(f(' %t\\n'),    ('missing %run before %t', 2))\n    self.assertEqual(f(' %t.so '),  (None, None))\n    self.assertEqual(f(' %t.o '),   (None, None))\n    self.assertEqual(f('%run %t '), (None, None))\n    self.assertEqual(f('-o %t '),   (None, None))\n\nif __name__ == '__main__':\n  unittest.main()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/scripts/sancov.py",
    "content": "#!/usr/bin/env python\n# Merge or print the coverage data collected by asan's coverage.\n# Input files are sequences of 4-byte integers.\n# We need to merge these integers into a set and then\n# either print them (as hex) or dump them into another file.\nimport array\nimport bisect\nimport glob\nimport os.path\nimport struct\nimport subprocess\nimport sys\n\nprog_name = \"\"\n\ndef Usage():\n  print >> sys.stderr, \"Usage: \\n\" + \\\n      \" \" + prog_name + \" merge FILE [FILE...] > OUTPUT\\n\" \\\n      \" \" + prog_name + \" print FILE [FILE...]\\n\" \\\n      \" \" + prog_name + \" unpack FILE [FILE...]\\n\" \\\n      \" \" + prog_name + \" rawunpack FILE [FILE ...]\\n\" \\\n      \" \" + prog_name + \" missing BINARY < LIST_OF_PCS\\n\"\n  exit(1)\n\ndef CheckBits(bits):\n  if bits != 32 and bits != 64:\n    raise Exception(\"Wrong bitness: %d\" % bits)\n\ndef TypeCodeForBits(bits):\n  CheckBits(bits)\n  return 'L' if bits == 64 else 'I'\n\nkMagic32SecondHalf = 0xFFFFFF32;\nkMagic64SecondHalf = 0xFFFFFF64;\nkMagicFirstHalf    = 0xC0BFFFFF;\n\ndef MagicForBits(bits):\n  CheckBits(bits)\n  if sys.byteorder == 'little':\n    return [kMagic64SecondHalf if bits == 64 else kMagic32SecondHalf, kMagicFirstHalf]\n  else:\n    return [kMagicFirstHalf, kMagic64SecondHalf if bits == 64 else kMagic32SecondHalf]\n\ndef ReadMagicAndReturnBitness(f, path):\n  magic_bytes = f.read(8)\n  magic_words = struct.unpack('II', magic_bytes);\n  bits = 0\n  idx = 1 if sys.byteorder == 'little' else 0\n  if magic_words[idx] == kMagicFirstHalf:\n    if magic_words[1-idx] == kMagic64SecondHalf:\n      bits = 64\n    elif magic_words[1-idx] == kMagic32SecondHalf:\n      bits = 32\n  if bits == 0:\n    raise Exception('Bad magic word in %s' % path)\n  return bits\n\ndef ReadOneFile(path):\n  with open(path, mode=\"rb\") as f:\n    f.seek(0, 2)\n    size = f.tell()\n    f.seek(0, 0)\n    if size < 8:\n      raise Exception('File %s is short (< 8 bytes)' % path)\n    bits = ReadMagicAndReturnBitness(f, path)\n    size -= 8\n    s = array.array(TypeCodeForBits(bits), f.read(size))\n  print >>sys.stderr, \"%s: read %d %d-bit PCs from %s\" % (prog_name, size * 8 / bits, bits, path)\n  return s\n\ndef Merge(files):\n  s = set()\n  for f in files:\n    s = s.union(set(ReadOneFile(f)))\n  print >> sys.stderr, \"%s: %d files merged; %d PCs total\" % \\\n    (prog_name, len(files), len(s))\n  return sorted(s)\n\ndef PrintFiles(files):\n  if len(files) > 1:\n    s = Merge(files)\n  else:  # If there is just on file, print the PCs in order.\n    s = ReadOneFile(files[0])\n    print >> sys.stderr, \"%s: 1 file merged; %d PCs total\" % \\\n      (prog_name, len(s))\n  for i in s:\n    print \"0x%x\" % i\n\ndef MergeAndPrint(files):\n  if sys.stdout.isatty():\n    Usage()\n  s = Merge(files)\n  bits = 32\n  if max(s) > 0xFFFFFFFF:\n    bits = 64\n  array.array('I', MagicForBits(bits)).tofile(sys.stdout)\n  a = array.array(TypeCodeForBits(bits), s)\n  a.tofile(sys.stdout)\n\n\ndef UnpackOneFile(path):\n  with open(path, mode=\"rb\") as f:\n    print >> sys.stderr, \"%s: unpacking %s\" % (prog_name, path)\n    while True:\n      header = f.read(12)\n      if not header: return\n      if len(header) < 12:\n        break\n      pid, module_length, blob_size = struct.unpack('iII', header)\n      module = f.read(module_length)\n      blob = f.read(blob_size)\n      assert(len(module) == module_length)\n      assert(len(blob) == blob_size)\n      extracted_file = \"%s.%d.sancov\" % (module, pid)\n      print >> sys.stderr, \"%s: extracting %s\" % \\\n        (prog_name, extracted_file)\n      # The packed file may contain multiple blobs for the same pid/module\n      # pair. Append to the end of the file instead of overwriting.\n      with open(extracted_file, 'ab') as f2:\n        f2.write(blob)\n    # fail\n    raise Exception('Error reading file %s' % path)\n\n\ndef Unpack(files):\n  for f in files:\n    UnpackOneFile(f)\n\ndef UnpackOneRawFile(path, map_path):\n  mem_map = []\n  with open(map_path, mode=\"rt\") as f_map:\n    print >> sys.stderr, \"%s: reading map %s\" % (prog_name, map_path)\n    bits = int(f_map.readline())\n    if bits != 32 and bits != 64:\n      raise Exception('Wrong bits size in the map')\n    for line in f_map:\n      parts = line.rstrip().split()\n      mem_map.append((int(parts[0], 16),\n                  int(parts[1], 16),\n                  int(parts[2], 16),\n                  ' '.join(parts[3:])))\n  mem_map.sort(key=lambda m : m[0])\n  mem_map_keys = [m[0] for m in mem_map]\n\n  with open(path, mode=\"rb\") as f:\n    print >> sys.stderr, \"%s: unpacking %s\" % (prog_name, path)\n\n    f.seek(0, 2)\n    size = f.tell()\n    f.seek(0, 0)\n    pcs = array.array(TypeCodeForBits(bits), f.read(size))\n    mem_map_pcs = [[] for i in range(0, len(mem_map))]\n\n    for pc in pcs:\n      if pc == 0: continue\n      map_idx = bisect.bisect(mem_map_keys, pc) - 1\n      (start, end, base, module_path) = mem_map[map_idx]\n      assert pc >= start\n      if pc >= end:\n        print >> sys.stderr, \"warning: %s: pc %x outside of any known mapping\" % (prog_name, pc)\n        continue\n      mem_map_pcs[map_idx].append(pc - base)\n\n    for ((start, end, base, module_path), pc_list) in zip(mem_map, mem_map_pcs):\n      if len(pc_list) == 0: continue\n      assert path.endswith('.sancov.raw')\n      dst_path = module_path + '.' + os.path.basename(path)[:-4]\n      print >> sys.stderr, \"%s: writing %d PCs to %s\" % (prog_name, len(pc_list), dst_path)\n      arr = array.array(TypeCodeForBits(bits))\n      arr.fromlist(sorted(pc_list))\n      with open(dst_path, 'ab') as f2:\n        array.array('I', MagicForBits(bits)).tofile(f2)\n        arr.tofile(f2)\n\ndef RawUnpack(files):\n  for f in files:\n    if not f.endswith('.sancov.raw'):\n      raise Exception('Unexpected raw file name %s' % f)\n    f_map = f[:-3] + 'map'\n    UnpackOneRawFile(f, f_map)\n\ndef GetInstrumentedPCs(binary):\n  # This looks scary, but all it does is extract all offsets where we call:\n  # - __sanitizer_cov() or __sanitizer_cov_with_check(),\n  # - with call or callq,\n  # - directly or via PLT.\n  cmd = \"objdump -d %s | \" \\\n        \"grep '^\\s\\+[0-9a-f]\\+:.*\\scall\\(q\\|\\)\\s\\+[0-9a-f]\\+ <__sanitizer_cov\\(_with_check\\|\\)\\(@plt\\|\\)>' | \" \\\n        \"grep '^\\s\\+[0-9a-f]\\+' -o\" % binary\n  proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,\n                          shell=True)\n  proc.stdin.close()\n  # The PCs we get from objdump are off by 4 bytes, as they point to the\n  # beginning of the callq instruction. Empirically this is true on x86 and\n  # x86_64.\n  return set(int(line.strip(), 16) + 4 for line in proc.stdout)\n\ndef PrintMissing(binary):\n  if not os.path.isfile(binary):\n    raise Exception('File not found: %s' % binary)\n  instrumented = GetInstrumentedPCs(binary)\n  print >> sys.stderr, \"%s: found %d instrumented PCs in %s\" % (prog_name,\n                                                                len(instrumented),\n                                                                binary)\n  covered = set(int(line, 16) for line in sys.stdin)\n  print >> sys.stderr, \"%s: read %d PCs from stdin\" % (prog_name, len(covered))\n  missing = instrumented - covered\n  print >> sys.stderr, \"%s: %d PCs missing from coverage\" % (prog_name, len(missing))\n  if (len(missing) > len(instrumented) - len(covered)):\n    print >> sys.stderr, \\\n        \"%s: WARNING: stdin contains PCs not found in binary\" % prog_name\n  for pc in sorted(missing):\n    print \"0x%x\" % pc\n\nif __name__ == '__main__':\n  prog_name = sys.argv[0]\n  if len(sys.argv) <= 2:\n    Usage();\n\n  if sys.argv[1] == \"missing\":\n    if len(sys.argv) != 3:\n      Usage()\n    PrintMissing(sys.argv[2])\n    exit(0)\n\n  file_list = []\n  for f in sys.argv[2:]:\n    file_list += glob.glob(f)\n  if not file_list:\n    Usage()\n\n  if sys.argv[1] == \"print\":\n    PrintFiles(file_list)\n  elif sys.argv[1] == \"merge\":\n    MergeAndPrint(file_list)\n  elif sys.argv[1] == \"unpack\":\n    Unpack(file_list)\n  elif sys.argv[1] == \"rawunpack\":\n    RawUnpack(file_list)\n  else:\n    Usage()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/Android.mk",
    "content": "#\n# Copyright (C) 2015 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n#\n\nLOCAL_PATH:= $(call my-dir)\n\nsan_test_files := \\\n    sanitizer_allocator_test.cc \\\n    sanitizer_atomic_test.cc \\\n    sanitizer_bitvector_test.cc \\\n    sanitizer_bvgraph_test.cc \\\n    sanitizer_common_test.cc \\\n    sanitizer_deadlock_detector_test.cc \\\n    sanitizer_flags_test.cc \\\n    sanitizer_format_interceptor_test.cc \\\n    sanitizer_ioctl_test.cc \\\n    sanitizer_libc_test.cc \\\n    sanitizer_linux_test.cc \\\n    sanitizer_list_test.cc \\\n    sanitizer_mutex_test.cc \\\n    sanitizer_nolibc_test.cc \\\n    sanitizer_posix_test.cc \\\n    sanitizer_printf_test.cc \\\n    sanitizer_procmaps_test.cc \\\n    sanitizer_stackdepot_test.cc \\\n    sanitizer_stacktrace_printer_test.cc \\\n    sanitizer_stacktrace_test.cc \\\n    sanitizer_stoptheworld_test.cc \\\n    sanitizer_suppressions_test.cc \\\n    sanitizer_test_main.cc \\\n    sanitizer_thread_registry_test.cc \\\n\nsan_test_cppflags := \\\n    -fvisibility=hidden \\\n    -fno-exceptions \\\n    -fno-rtti \\\n    -std=c++11 \\\n    -Wall \\\n    -Werror \\\n    -Wno-unused-parameter \\\n    -Wno-non-virtual-dtor \\\n\nsan_test_c_includes := \\\n    external/compiler-rt/lib \\\n\nifneq ($(HOST_OS),darwin)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := san_test\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_C_INCLUDES := $(san_test_c_includes)\nLOCAL_CPPFLAGS := $(san_test_cppflags)\nLOCAL_SRC_FILES := $(san_test_files)\nLOCAL_STATIC_LIBRARIES := libsan\nLOCAL_LDLIBS := -ldl -lrt\nLOCAL_SANITIZE := never\ninclude $(BUILD_HOST_NATIVE_TEST)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := san_test-Nolibc\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_C_INCLUDES := $(san_test_c_includes) external/gtest/include\nLOCAL_CPPFLAGS := $(san_test_cppflags)\nLOCAL_SRC_FILES := sanitizer_nolibc_test_main.cc\nLOCAL_STATIC_LIBRARIES := libsan libgtest_host\nLOCAL_LDFLAGS := -nostdlib -Qunused-arguments\nLOCAL_LDLIBS := -ldl\nLOCAL_SANITIZE := never\ninclude $(BUILD_HOST_EXECUTABLE)\n\nendif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt",
    "content": "include(CompilerRTCompile)\n\nclang_compiler_add_cxx_check()\n\n# FIXME: use SANITIZER_COMMON_SUPPORTED_ARCH here\nfilter_available_targets(SANITIZER_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el)\n\nset(SANITIZER_UNITTESTS\n  sanitizer_allocator_test.cc\n  sanitizer_atomic_test.cc\n  sanitizer_bitvector_test.cc\n  sanitizer_bvgraph_test.cc\n  sanitizer_common_test.cc\n  sanitizer_deadlock_detector_test.cc\n  sanitizer_flags_test.cc\n  sanitizer_format_interceptor_test.cc\n  sanitizer_ioctl_test.cc\n  sanitizer_libc_test.cc\n  sanitizer_linux_test.cc\n  sanitizer_list_test.cc\n  sanitizer_mutex_test.cc\n  sanitizer_nolibc_test.cc\n  sanitizer_posix_test.cc\n  sanitizer_printf_test.cc\n  sanitizer_procmaps_test.cc\n  sanitizer_stackdepot_test.cc\n  sanitizer_stacktrace_printer_test.cc\n  sanitizer_stacktrace_test.cc\n  sanitizer_stoptheworld_test.cc\n  sanitizer_suppressions_test.cc\n  sanitizer_symbolizer_test.cc\n  sanitizer_test_main.cc\n  sanitizer_thread_registry_test.cc)\n\nset(SANITIZER_TEST_HEADERS\n  sanitizer_pthread_wrappers.h\n  sanitizer_test_config.h\n  sanitizer_test_utils.h)\nforeach(header ${SANITIZER_HEADERS})\n  list(APPEND SANITIZER_TEST_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../${header})\nendforeach()\n\nset(SANITIZER_TEST_CFLAGS_COMMON\n  ${COMPILER_RT_TEST_CFLAGS}\n  ${COMPILER_RT_GTEST_CFLAGS}\n  -I${COMPILER_RT_SOURCE_DIR}/include\n  -I${COMPILER_RT_SOURCE_DIR}/lib\n  -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common\n  -fno-rtti\n  -O2\n  -Werror=sign-compare\n  -Wno-non-virtual-dtor)\n\nif(MSVC)\n  # Disable exceptions on Windows until they work reliably.\n  list(APPEND SANITIZER_TEST_CFLAGS_COMMON -fno-exceptions -DGTEST_HAS_SEH=0)\nendif()\n\n# -gline-tables-only must be enough for these tests, so use it if possible.\nif(COMPILER_RT_TEST_COMPILER_ID MATCHES \"Clang\")\n  list(APPEND SANITIZER_TEST_CFLAGS_COMMON -gline-tables-only)\nelse()\n  list(APPEND SANITIZER_TEST_CFLAGS_COMMON -g)\nendif()\n\nif(NOT MSVC)\n  list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON --driver-mode=g++)\nendif()\n\nset(SANITIZER_TEST_LINK_LIBS)\nappend_list_if(ANDROID log SANITIZER_TEST_LINK_LIBS)\n# NDK r10 requires -latomic almost always.\nappend_list_if(ANDROID atomic SANITIZER_TEST_LINK_LIBS)\n\nappend_list_if(COMPILER_RT_HAS_LIBDL -ldl SANITIZER_TEST_LINK_FLAGS_COMMON)\nappend_list_if(COMPILER_RT_HAS_LIBRT -lrt SANITIZER_TEST_LINK_FLAGS_COMMON)\nappend_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread SANITIZER_TEST_LINK_FLAGS_COMMON)\n# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests. Also,\n# 'libm' shall be specified explicitly to build i386 tests.\nif(CMAKE_SYSTEM MATCHES \"FreeBSD-9.2-RELEASE\")\n  list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON \"-lc++ -lm\")\nendif()\n\ninclude_directories(..)\ninclude_directories(../..)\n\n# Adds static library which contains sanitizer_common object file\n# (universal binary on Mac and arch-specific object files on Linux).\nmacro(add_sanitizer_common_lib library)\n  add_library(${library} STATIC ${ARGN})\n  set_target_properties(${library} PROPERTIES\n    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})\nendmacro()\n\nfunction(get_sanitizer_common_lib_for_arch arch lib lib_name)\n  if(APPLE)\n    set(tgt_name \"RTSanitizerCommon.test.osx\")\n  else()\n    set(tgt_name \"RTSanitizerCommon.test.${arch}\")\n  endif()\n  set(${lib} \"${tgt_name}\" PARENT_SCOPE)\n  if(NOT MSVC)\n    set(${lib_name} \"lib${tgt_name}.a\" PARENT_SCOPE)\n  else()\n    set(${lib_name} \"${tgt_name}.lib\" PARENT_SCOPE)\n  endif()\nendfunction()\n\n# Sanitizer_common unit tests testsuite.\nadd_custom_target(SanitizerUnitTests)\nset_target_properties(SanitizerUnitTests PROPERTIES\n  FOLDER \"Sanitizer unittests\")\n\n# Adds sanitizer tests for architecture.\nmacro(add_sanitizer_tests_for_arch arch)\n  get_target_flags_for_arch(${arch} TARGET_FLAGS)\n  set(SANITIZER_TEST_SOURCES ${SANITIZER_UNITTESTS}\n                             ${COMPILER_RT_GTEST_SOURCE})\n  set(SANITIZER_TEST_COMPILE_DEPS ${SANITIZER_TEST_HEADERS})\n  if(NOT COMPILER_RT_STANDALONE_BUILD)\n    list(APPEND SANITIZER_TEST_COMPILE_DEPS gtest)\n  endif()\n  set(SANITIZER_TEST_OBJECTS)\n  foreach(source ${SANITIZER_TEST_SOURCES})\n    get_filename_component(basename ${source} NAME)\n    set(output_obj \"${basename}.${arch}.o\")\n    clang_compile(${output_obj} ${source}\n                  CFLAGS ${SANITIZER_TEST_CFLAGS_COMMON} ${TARGET_FLAGS}\n                  DEPS ${SANITIZER_TEST_COMPILE_DEPS})\n    list(APPEND SANITIZER_TEST_OBJECTS ${output_obj})\n  endforeach()\n  get_sanitizer_common_lib_for_arch(${arch} SANITIZER_COMMON_LIB\n                                    SANITIZER_COMMON_LIB_NAME)\n  # Add unittest target.\n  set(SANITIZER_TEST_NAME \"Sanitizer-${arch}-Test\")\n  add_compiler_rt_test(SanitizerUnitTests ${SANITIZER_TEST_NAME}\n                       OBJECTS ${SANITIZER_TEST_OBJECTS}\n                               ${SANITIZER_COMMON_LIB_NAME}\n                       DEPS ${SANITIZER_TEST_OBJECTS} ${SANITIZER_COMMON_LIB}\n                       LINK_FLAGS ${SANITIZER_TEST_LINK_FLAGS_COMMON}\n                                  ${TARGET_FLAGS})\n\n  if(\"${CMAKE_SYSTEM_NAME}\" STREQUAL \"Linux\" AND \"${arch}\" STREQUAL \"x86_64\")\n    # Test that the libc-independent part of sanitizer_common is indeed\n    # independent of libc, by linking this binary without libc (here) and\n    # executing it (unit test in sanitizer_nolibc_test.cc).\n    clang_compile(sanitizer_nolibc_test_main.${arch}.o\n                  sanitizer_nolibc_test_main.cc\n                  CFLAGS ${SANITIZER_TEST_CFLAGS_COMMON} ${TARGET_FLAGS}\n                  DEPS ${SANITIZER_TEST_COMPILE_DEPS})\n    add_compiler_rt_test(SanitizerUnitTests \"Sanitizer-${arch}-Test-Nolibc\"\n                         OBJECTS sanitizer_nolibc_test_main.${arch}.o\n                                 -Wl,-whole-archive\n                                 libRTSanitizerCommon.test.nolibc.${arch}.a\n                                 -Wl,-no-whole-archive\n                         DEPS sanitizer_nolibc_test_main.${arch}.o\n                              RTSanitizerCommon.test.nolibc.${arch}\n                         LINK_FLAGS -nostdlib ${TARGET_FLAGS})\n  endif()\nendmacro()\n\nif(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)\n  # We use just-built clang to build sanitizer_common unittests, so we must\n  # be sure that produced binaries would work.\n  if(APPLE)\n    add_sanitizer_common_lib(\"RTSanitizerCommon.test.osx\"\n                             $<TARGET_OBJECTS:RTSanitizerCommon.osx>)\n  else()\n    if(CAN_TARGET_x86_64)\n      add_sanitizer_common_lib(\"RTSanitizerCommon.test.nolibc.x86_64\"\n                               $<TARGET_OBJECTS:RTSanitizerCommon.x86_64>)\n    endif()\n    foreach(arch ${SANITIZER_UNITTEST_SUPPORTED_ARCH})\n      add_sanitizer_common_lib(\"RTSanitizerCommon.test.${arch}\"\n                               $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>\n                               $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>)\n    endforeach()\n  endif()\n  foreach(arch ${SANITIZER_UNITTEST_SUPPORTED_ARCH})\n    add_sanitizer_tests_for_arch(${arch})\n  endforeach()\nendif()\n\nif(ANDROID)\n  foreach(arch ${SANITIZER_COMMON_SUPPORTED_ARCH})\n    add_executable(SanitizerTest\n      ${SANITIZER_UNITTESTS}\n      ${COMPILER_RT_GTEST_SOURCE}\n      $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>\n      $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>)\n    set_target_compile_flags(SanitizerTest\n      ${SANITIZER_COMMON_CFLAGS}\n      ${SANITIZER_TEST_CFLAGS_COMMON})\n    # Setup correct output directory and link flags.\n    set_target_properties(SanitizerTest PROPERTIES\n      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})\n    set_target_link_flags(SanitizerTest ${SANITIZER_TEST_LINK_FLAGS_COMMON})\n    target_link_libraries(SanitizerTest ${SANITIZER_TEST_LINK_LIBS})\n    # Add unit test to test suite.\n    add_dependencies(SanitizerUnitTests SanitizerTest)\n  endforeach()\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cc",
    "content": "//===-- sanitizer_allocator_test.cc ---------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n// Tests for sanitizer_allocator.h.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_allocator.h\"\n#include \"sanitizer_common/sanitizer_allocator_internal.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n\n#include \"sanitizer_test_utils.h\"\n#include \"sanitizer_pthread_wrappers.h\"\n\n#include \"gtest/gtest.h\"\n\n#include <stdlib.h>\n#include <algorithm>\n#include <vector>\n#include <set>\n\n// Too slow for debug build\n#if !SANITIZER_DEBUG\n\n#if SANITIZER_CAN_USE_ALLOCATOR64\nstatic const uptr kAllocatorSpace = 0x700000000000ULL;\nstatic const uptr kAllocatorSize  = 0x010000000000ULL;  // 1T.\nstatic const u64 kAddressSpaceSize = 1ULL << 47;\n\ntypedef SizeClassAllocator64<\n  kAllocatorSpace, kAllocatorSize, 16, DefaultSizeClassMap> Allocator64;\n\ntypedef SizeClassAllocator64<\n  kAllocatorSpace, kAllocatorSize, 16, CompactSizeClassMap> Allocator64Compact;\n#elif defined(__mips64)\nstatic const u64 kAddressSpaceSize = 1ULL << 40;\n#else\nstatic const u64 kAddressSpaceSize = 1ULL << 32;\n#endif\n\nstatic const uptr kRegionSizeLog = FIRST_32_SECOND_64(20, 24);\nstatic const uptr kFlatByteMapSize = kAddressSpaceSize >> kRegionSizeLog;\n\ntypedef SizeClassAllocator32<\n  0, kAddressSpaceSize,\n  /*kMetadataSize*/16,\n  CompactSizeClassMap,\n  kRegionSizeLog,\n  FlatByteMap<kFlatByteMapSize> >\n  Allocator32Compact;\n\ntemplate <class SizeClassMap>\nvoid TestSizeClassMap() {\n  typedef SizeClassMap SCMap;\n  // SCMap::Print();\n  SCMap::Validate();\n}\n\nTEST(SanitizerCommon, DefaultSizeClassMap) {\n  TestSizeClassMap<DefaultSizeClassMap>();\n}\n\nTEST(SanitizerCommon, CompactSizeClassMap) {\n  TestSizeClassMap<CompactSizeClassMap>();\n}\n\nTEST(SanitizerCommon, InternalSizeClassMap) {\n  TestSizeClassMap<InternalSizeClassMap>();\n}\n\ntemplate <class Allocator>\nvoid TestSizeClassAllocator() {\n  Allocator *a = new Allocator;\n  a->Init();\n  SizeClassAllocatorLocalCache<Allocator> cache;\n  memset(&cache, 0, sizeof(cache));\n  cache.Init(0);\n\n  static const uptr sizes[] = {1, 16, 30, 40, 100, 1000, 10000,\n    50000, 60000, 100000, 120000, 300000, 500000, 1000000, 2000000};\n\n  std::vector<void *> allocated;\n\n  uptr last_total_allocated = 0;\n  for (int i = 0; i < 3; i++) {\n    // Allocate a bunch of chunks.\n    for (uptr s = 0; s < ARRAY_SIZE(sizes); s++) {\n      uptr size = sizes[s];\n      if (!a->CanAllocate(size, 1)) continue;\n      // printf(\"s = %ld\\n\", size);\n      uptr n_iter = std::max((uptr)6, 8000000 / size);\n      // fprintf(stderr, \"size: %ld iter: %ld\\n\", size, n_iter);\n      for (uptr i = 0; i < n_iter; i++) {\n        uptr class_id0 = Allocator::SizeClassMapT::ClassID(size);\n        char *x = (char*)cache.Allocate(a, class_id0);\n        x[0] = 0;\n        x[size - 1] = 0;\n        x[size / 2] = 0;\n        allocated.push_back(x);\n        CHECK_EQ(x, a->GetBlockBegin(x));\n        CHECK_EQ(x, a->GetBlockBegin(x + size - 1));\n        CHECK(a->PointerIsMine(x));\n        CHECK(a->PointerIsMine(x + size - 1));\n        CHECK(a->PointerIsMine(x + size / 2));\n        CHECK_GE(a->GetActuallyAllocatedSize(x), size);\n        uptr class_id = a->GetSizeClass(x);\n        CHECK_EQ(class_id, Allocator::SizeClassMapT::ClassID(size));\n        uptr *metadata = reinterpret_cast<uptr*>(a->GetMetaData(x));\n        metadata[0] = reinterpret_cast<uptr>(x) + 1;\n        metadata[1] = 0xABCD;\n      }\n    }\n    // Deallocate all.\n    for (uptr i = 0; i < allocated.size(); i++) {\n      void *x = allocated[i];\n      uptr *metadata = reinterpret_cast<uptr*>(a->GetMetaData(x));\n      CHECK_EQ(metadata[0], reinterpret_cast<uptr>(x) + 1);\n      CHECK_EQ(metadata[1], 0xABCD);\n      cache.Deallocate(a, a->GetSizeClass(x), x);\n    }\n    allocated.clear();\n    uptr total_allocated = a->TotalMemoryUsed();\n    if (last_total_allocated == 0)\n      last_total_allocated = total_allocated;\n    CHECK_EQ(last_total_allocated, total_allocated);\n  }\n\n  // Check that GetBlockBegin never crashes.\n  for (uptr x = 0, step = kAddressSpaceSize / 100000;\n       x < kAddressSpaceSize - step; x += step)\n    if (a->PointerIsMine(reinterpret_cast<void *>(x)))\n      Ident(a->GetBlockBegin(reinterpret_cast<void *>(x)));\n\n  a->TestOnlyUnmap();\n  delete a;\n}\n\n#if SANITIZER_CAN_USE_ALLOCATOR64\nTEST(SanitizerCommon, SizeClassAllocator64) {\n  TestSizeClassAllocator<Allocator64>();\n}\n\nTEST(SanitizerCommon, SizeClassAllocator64Compact) {\n  TestSizeClassAllocator<Allocator64Compact>();\n}\n#endif\n\nTEST(SanitizerCommon, SizeClassAllocator32Compact) {\n  TestSizeClassAllocator<Allocator32Compact>();\n}\n\ntemplate <class Allocator>\nvoid SizeClassAllocatorMetadataStress() {\n  Allocator *a = new Allocator;\n  a->Init();\n  SizeClassAllocatorLocalCache<Allocator> cache;\n  memset(&cache, 0, sizeof(cache));\n  cache.Init(0);\n\n  const uptr kNumAllocs = 1 << 13;\n  void *allocated[kNumAllocs];\n  void *meta[kNumAllocs];\n  for (uptr i = 0; i < kNumAllocs; i++) {\n    void *x = cache.Allocate(a, 1 + i % 50);\n    allocated[i] = x;\n    meta[i] = a->GetMetaData(x);\n  }\n  // Get Metadata kNumAllocs^2 times.\n  for (uptr i = 0; i < kNumAllocs * kNumAllocs; i++) {\n    uptr idx = i % kNumAllocs;\n    void *m = a->GetMetaData(allocated[idx]);\n    EXPECT_EQ(m, meta[idx]);\n  }\n  for (uptr i = 0; i < kNumAllocs; i++) {\n    cache.Deallocate(a, 1 + i % 50, allocated[i]);\n  }\n\n  a->TestOnlyUnmap();\n  delete a;\n}\n\n#if SANITIZER_CAN_USE_ALLOCATOR64\nTEST(SanitizerCommon, SizeClassAllocator64MetadataStress) {\n  SizeClassAllocatorMetadataStress<Allocator64>();\n}\n\nTEST(SanitizerCommon, SizeClassAllocator64CompactMetadataStress) {\n  SizeClassAllocatorMetadataStress<Allocator64Compact>();\n}\n#endif  // SANITIZER_CAN_USE_ALLOCATOR64\nTEST(SanitizerCommon, SizeClassAllocator32CompactMetadataStress) {\n  SizeClassAllocatorMetadataStress<Allocator32Compact>();\n}\n\ntemplate <class Allocator>\nvoid SizeClassAllocatorGetBlockBeginStress() {\n  Allocator *a = new Allocator;\n  a->Init();\n  SizeClassAllocatorLocalCache<Allocator> cache;\n  memset(&cache, 0, sizeof(cache));\n  cache.Init(0);\n\n  uptr max_size_class = Allocator::kNumClasses - 1;\n  uptr size = Allocator::SizeClassMapT::Size(max_size_class);\n  u64 G8 = 1ULL << 33;\n  // Make sure we correctly compute GetBlockBegin() w/o overflow.\n  for (size_t i = 0; i <= G8 / size; i++) {\n    void *x = cache.Allocate(a, max_size_class);\n    void *beg = a->GetBlockBegin(x);\n    // if ((i & (i - 1)) == 0)\n    //   fprintf(stderr, \"[%zd] %p %p\\n\", i, x, beg);\n    EXPECT_EQ(x, beg);\n  }\n\n  a->TestOnlyUnmap();\n  delete a;\n}\n\n#if SANITIZER_CAN_USE_ALLOCATOR64\nTEST(SanitizerCommon, SizeClassAllocator64GetBlockBegin) {\n  SizeClassAllocatorGetBlockBeginStress<Allocator64>();\n}\nTEST(SanitizerCommon, SizeClassAllocator64CompactGetBlockBegin) {\n  SizeClassAllocatorGetBlockBeginStress<Allocator64Compact>();\n}\nTEST(SanitizerCommon, SizeClassAllocator32CompactGetBlockBegin) {\n  SizeClassAllocatorGetBlockBeginStress<Allocator32Compact>();\n}\n#endif  // SANITIZER_CAN_USE_ALLOCATOR64\n\nstruct TestMapUnmapCallback {\n  static int map_count, unmap_count;\n  void OnMap(uptr p, uptr size) const { map_count++; }\n  void OnUnmap(uptr p, uptr size) const { unmap_count++; }\n};\nint TestMapUnmapCallback::map_count;\nint TestMapUnmapCallback::unmap_count;\n\n#if SANITIZER_CAN_USE_ALLOCATOR64\nTEST(SanitizerCommon, SizeClassAllocator64MapUnmapCallback) {\n  TestMapUnmapCallback::map_count = 0;\n  TestMapUnmapCallback::unmap_count = 0;\n  typedef SizeClassAllocator64<\n      kAllocatorSpace, kAllocatorSize, 16, DefaultSizeClassMap,\n      TestMapUnmapCallback> Allocator64WithCallBack;\n  Allocator64WithCallBack *a = new Allocator64WithCallBack;\n  a->Init();\n  EXPECT_EQ(TestMapUnmapCallback::map_count, 1);  // Allocator state.\n  SizeClassAllocatorLocalCache<Allocator64WithCallBack> cache;\n  memset(&cache, 0, sizeof(cache));\n  cache.Init(0);\n  AllocatorStats stats;\n  stats.Init();\n  a->AllocateBatch(&stats, &cache, 32);\n  EXPECT_EQ(TestMapUnmapCallback::map_count, 3);  // State + alloc + metadata.\n  a->TestOnlyUnmap();\n  EXPECT_EQ(TestMapUnmapCallback::unmap_count, 1);  // The whole thing.\n  delete a;\n}\n#endif\n\nTEST(SanitizerCommon, SizeClassAllocator32MapUnmapCallback) {\n  TestMapUnmapCallback::map_count = 0;\n  TestMapUnmapCallback::unmap_count = 0;\n  typedef SizeClassAllocator32<\n      0, kAddressSpaceSize,\n      /*kMetadataSize*/16,\n      CompactSizeClassMap,\n      kRegionSizeLog,\n      FlatByteMap<kFlatByteMapSize>,\n      TestMapUnmapCallback>\n    Allocator32WithCallBack;\n  Allocator32WithCallBack *a = new Allocator32WithCallBack;\n  a->Init();\n  EXPECT_EQ(TestMapUnmapCallback::map_count, 0);\n  SizeClassAllocatorLocalCache<Allocator32WithCallBack>  cache;\n  memset(&cache, 0, sizeof(cache));\n  cache.Init(0);\n  AllocatorStats stats;\n  stats.Init();\n  a->AllocateBatch(&stats, &cache, 32);\n  EXPECT_EQ(TestMapUnmapCallback::map_count, 1);\n  a->TestOnlyUnmap();\n  EXPECT_EQ(TestMapUnmapCallback::unmap_count, 1);\n  delete a;\n  // fprintf(stderr, \"Map: %d Unmap: %d\\n\",\n  //         TestMapUnmapCallback::map_count,\n  //         TestMapUnmapCallback::unmap_count);\n}\n\nTEST(SanitizerCommon, LargeMmapAllocatorMapUnmapCallback) {\n  TestMapUnmapCallback::map_count = 0;\n  TestMapUnmapCallback::unmap_count = 0;\n  LargeMmapAllocator<TestMapUnmapCallback> a;\n  a.Init(/* may_return_null */ false);\n  AllocatorStats stats;\n  stats.Init();\n  void *x = a.Allocate(&stats, 1 << 20, 1);\n  EXPECT_EQ(TestMapUnmapCallback::map_count, 1);\n  a.Deallocate(&stats, x);\n  EXPECT_EQ(TestMapUnmapCallback::unmap_count, 1);\n}\n\ntemplate<class Allocator>\nvoid FailInAssertionOnOOM() {\n  Allocator a;\n  a.Init();\n  SizeClassAllocatorLocalCache<Allocator> cache;\n  memset(&cache, 0, sizeof(cache));\n  cache.Init(0);\n  AllocatorStats stats;\n  stats.Init();\n  for (int i = 0; i < 1000000; i++) {\n    a.AllocateBatch(&stats, &cache, 52);\n  }\n\n  a.TestOnlyUnmap();\n}\n\n#if SANITIZER_CAN_USE_ALLOCATOR64\nTEST(SanitizerCommon, SizeClassAllocator64Overflow) {\n  EXPECT_DEATH(FailInAssertionOnOOM<Allocator64>(), \"Out of memory\");\n}\n#endif\n\n#if !defined(_WIN32)  // FIXME: This currently fails on Windows.\nTEST(SanitizerCommon, LargeMmapAllocator) {\n  LargeMmapAllocator<> a;\n  a.Init(/* may_return_null */ false);\n  AllocatorStats stats;\n  stats.Init();\n\n  static const int kNumAllocs = 1000;\n  char *allocated[kNumAllocs];\n  static const uptr size = 4000;\n  // Allocate some.\n  for (int i = 0; i < kNumAllocs; i++) {\n    allocated[i] = (char *)a.Allocate(&stats, size, 1);\n    CHECK(a.PointerIsMine(allocated[i]));\n  }\n  // Deallocate all.\n  CHECK_GT(a.TotalMemoryUsed(), size * kNumAllocs);\n  for (int i = 0; i < kNumAllocs; i++) {\n    char *p = allocated[i];\n    CHECK(a.PointerIsMine(p));\n    a.Deallocate(&stats, p);\n  }\n  // Check that non left.\n  CHECK_EQ(a.TotalMemoryUsed(), 0);\n\n  // Allocate some more, also add metadata.\n  for (int i = 0; i < kNumAllocs; i++) {\n    char *x = (char *)a.Allocate(&stats, size, 1);\n    CHECK_GE(a.GetActuallyAllocatedSize(x), size);\n    uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(x));\n    *meta = i;\n    allocated[i] = x;\n  }\n  for (int i = 0; i < kNumAllocs * kNumAllocs; i++) {\n    char *p = allocated[i % kNumAllocs];\n    CHECK(a.PointerIsMine(p));\n    CHECK(a.PointerIsMine(p + 2000));\n  }\n  CHECK_GT(a.TotalMemoryUsed(), size * kNumAllocs);\n  // Deallocate all in reverse order.\n  for (int i = 0; i < kNumAllocs; i++) {\n    int idx = kNumAllocs - i - 1;\n    char *p = allocated[idx];\n    uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(p));\n    CHECK_EQ(*meta, idx);\n    CHECK(a.PointerIsMine(p));\n    a.Deallocate(&stats, p);\n  }\n  CHECK_EQ(a.TotalMemoryUsed(), 0);\n\n  // Test alignments.\n  uptr max_alignment = SANITIZER_WORDSIZE == 64 ? (1 << 28) : (1 << 24);\n  for (uptr alignment = 8; alignment <= max_alignment; alignment *= 2) {\n    const uptr kNumAlignedAllocs = 100;\n    for (uptr i = 0; i < kNumAlignedAllocs; i++) {\n      uptr size = ((i % 10) + 1) * 4096;\n      char *p = allocated[i] = (char *)a.Allocate(&stats, size, alignment);\n      CHECK_EQ(p, a.GetBlockBegin(p));\n      CHECK_EQ(p, a.GetBlockBegin(p + size - 1));\n      CHECK_EQ(p, a.GetBlockBegin(p + size / 2));\n      CHECK_EQ(0, (uptr)allocated[i] % alignment);\n      p[0] = p[size - 1] = 0;\n    }\n    for (uptr i = 0; i < kNumAlignedAllocs; i++) {\n      a.Deallocate(&stats, allocated[i]);\n    }\n  }\n\n  // Regression test for boundary condition in GetBlockBegin().\n  uptr page_size = GetPageSizeCached();\n  char *p = (char *)a.Allocate(&stats, page_size, 1);\n  CHECK_EQ(p, a.GetBlockBegin(p));\n  CHECK_EQ(p, (char *)a.GetBlockBegin(p + page_size - 1));\n  CHECK_NE(p, (char *)a.GetBlockBegin(p + page_size));\n  a.Deallocate(&stats, p);\n}\n#endif\n\ntemplate\n<class PrimaryAllocator, class SecondaryAllocator, class AllocatorCache>\nvoid TestCombinedAllocator() {\n  typedef\n      CombinedAllocator<PrimaryAllocator, AllocatorCache, SecondaryAllocator>\n      Allocator;\n  Allocator *a = new Allocator;\n  a->Init(/* may_return_null */ true);\n\n  AllocatorCache cache;\n  memset(&cache, 0, sizeof(cache));\n  a->InitCache(&cache);\n\n  EXPECT_EQ(a->Allocate(&cache, -1, 1), (void*)0);\n  EXPECT_EQ(a->Allocate(&cache, -1, 1024), (void*)0);\n  EXPECT_EQ(a->Allocate(&cache, (uptr)-1 - 1024, 1), (void*)0);\n  EXPECT_EQ(a->Allocate(&cache, (uptr)-1 - 1024, 1024), (void*)0);\n  EXPECT_EQ(a->Allocate(&cache, (uptr)-1 - 1023, 1024), (void*)0);\n\n  // Set to false\n  a->SetMayReturnNull(false);\n  EXPECT_DEATH(a->Allocate(&cache, -1, 1),\n               \"allocator is terminating the process\");\n\n  const uptr kNumAllocs = 100000;\n  const uptr kNumIter = 10;\n  for (uptr iter = 0; iter < kNumIter; iter++) {\n    std::vector<void*> allocated;\n    for (uptr i = 0; i < kNumAllocs; i++) {\n      uptr size = (i % (1 << 14)) + 1;\n      if ((i % 1024) == 0)\n        size = 1 << (10 + (i % 14));\n      void *x = a->Allocate(&cache, size, 1);\n      uptr *meta = reinterpret_cast<uptr*>(a->GetMetaData(x));\n      CHECK_EQ(*meta, 0);\n      *meta = size;\n      allocated.push_back(x);\n    }\n\n    random_shuffle(allocated.begin(), allocated.end());\n\n    for (uptr i = 0; i < kNumAllocs; i++) {\n      void *x = allocated[i];\n      uptr *meta = reinterpret_cast<uptr*>(a->GetMetaData(x));\n      CHECK_NE(*meta, 0);\n      CHECK(a->PointerIsMine(x));\n      *meta = 0;\n      a->Deallocate(&cache, x);\n    }\n    allocated.clear();\n    a->SwallowCache(&cache);\n  }\n  a->DestroyCache(&cache);\n  a->TestOnlyUnmap();\n}\n\n#if SANITIZER_CAN_USE_ALLOCATOR64\nTEST(SanitizerCommon, CombinedAllocator64) {\n  TestCombinedAllocator<Allocator64,\n      LargeMmapAllocator<>,\n      SizeClassAllocatorLocalCache<Allocator64> > ();\n}\n\nTEST(SanitizerCommon, CombinedAllocator64Compact) {\n  TestCombinedAllocator<Allocator64Compact,\n      LargeMmapAllocator<>,\n      SizeClassAllocatorLocalCache<Allocator64Compact> > ();\n}\n#endif\n\n#if !defined(_WIN32)  // FIXME: This currently fails on Windows.\nTEST(SanitizerCommon, CombinedAllocator32Compact) {\n  TestCombinedAllocator<Allocator32Compact,\n      LargeMmapAllocator<>,\n      SizeClassAllocatorLocalCache<Allocator32Compact> > ();\n}\n#endif\n\ntemplate <class AllocatorCache>\nvoid TestSizeClassAllocatorLocalCache() {\n  AllocatorCache cache;\n  typedef typename AllocatorCache::Allocator Allocator;\n  Allocator *a = new Allocator();\n\n  a->Init();\n  memset(&cache, 0, sizeof(cache));\n  cache.Init(0);\n\n  const uptr kNumAllocs = 10000;\n  const int kNumIter = 100;\n  uptr saved_total = 0;\n  for (int class_id = 1; class_id <= 5; class_id++) {\n    for (int it = 0; it < kNumIter; it++) {\n      void *allocated[kNumAllocs];\n      for (uptr i = 0; i < kNumAllocs; i++) {\n        allocated[i] = cache.Allocate(a, class_id);\n      }\n      for (uptr i = 0; i < kNumAllocs; i++) {\n        cache.Deallocate(a, class_id, allocated[i]);\n      }\n      cache.Drain(a);\n      uptr total_allocated = a->TotalMemoryUsed();\n      if (it)\n        CHECK_EQ(saved_total, total_allocated);\n      saved_total = total_allocated;\n    }\n  }\n\n  a->TestOnlyUnmap();\n  delete a;\n}\n\n#if SANITIZER_CAN_USE_ALLOCATOR64\nTEST(SanitizerCommon, SizeClassAllocator64LocalCache) {\n  TestSizeClassAllocatorLocalCache<\n      SizeClassAllocatorLocalCache<Allocator64> >();\n}\n\nTEST(SanitizerCommon, SizeClassAllocator64CompactLocalCache) {\n  TestSizeClassAllocatorLocalCache<\n      SizeClassAllocatorLocalCache<Allocator64Compact> >();\n}\n#endif\n\nTEST(SanitizerCommon, SizeClassAllocator32CompactLocalCache) {\n  TestSizeClassAllocatorLocalCache<\n      SizeClassAllocatorLocalCache<Allocator32Compact> >();\n}\n\n#if SANITIZER_CAN_USE_ALLOCATOR64\ntypedef SizeClassAllocatorLocalCache<Allocator64> AllocatorCache;\nstatic AllocatorCache static_allocator_cache;\n\nvoid *AllocatorLeakTestWorker(void *arg) {\n  typedef AllocatorCache::Allocator Allocator;\n  Allocator *a = (Allocator*)(arg);\n  static_allocator_cache.Allocate(a, 10);\n  static_allocator_cache.Drain(a);\n  return 0;\n}\n\nTEST(SanitizerCommon, AllocatorLeakTest) {\n  typedef AllocatorCache::Allocator Allocator;\n  Allocator a;\n  a.Init();\n  uptr total_used_memory = 0;\n  for (int i = 0; i < 100; i++) {\n    pthread_t t;\n    PTHREAD_CREATE(&t, 0, AllocatorLeakTestWorker, &a);\n    PTHREAD_JOIN(t, 0);\n    if (i == 0)\n      total_used_memory = a.TotalMemoryUsed();\n    EXPECT_EQ(a.TotalMemoryUsed(), total_used_memory);\n  }\n\n  a.TestOnlyUnmap();\n}\n\n// Struct which is allocated to pass info to new threads.  The new thread frees\n// it.\nstruct NewThreadParams {\n  AllocatorCache *thread_cache;\n  AllocatorCache::Allocator *allocator;\n  uptr class_id;\n};\n\n// Called in a new thread.  Just frees its argument.\nstatic void *DeallocNewThreadWorker(void *arg) {\n  NewThreadParams *params = reinterpret_cast<NewThreadParams*>(arg);\n  params->thread_cache->Deallocate(params->allocator, params->class_id, params);\n  return NULL;\n}\n\n// The allocator cache is supposed to be POD and zero initialized.  We should be\n// able to call Deallocate on a zeroed cache, and it will self-initialize.\nTEST(Allocator, AllocatorCacheDeallocNewThread) {\n  AllocatorCache::Allocator allocator;\n  allocator.Init();\n  AllocatorCache main_cache;\n  AllocatorCache child_cache;\n  memset(&main_cache, 0, sizeof(main_cache));\n  memset(&child_cache, 0, sizeof(child_cache));\n\n  uptr class_id = DefaultSizeClassMap::ClassID(sizeof(NewThreadParams));\n  NewThreadParams *params = reinterpret_cast<NewThreadParams*>(\n      main_cache.Allocate(&allocator, class_id));\n  params->thread_cache = &child_cache;\n  params->allocator = &allocator;\n  params->class_id = class_id;\n  pthread_t t;\n  PTHREAD_CREATE(&t, 0, DeallocNewThreadWorker, params);\n  PTHREAD_JOIN(t, 0);\n}\n#endif\n\nTEST(Allocator, Basic) {\n  char *p = (char*)InternalAlloc(10);\n  EXPECT_NE(p, (char*)0);\n  char *p2 = (char*)InternalAlloc(20);\n  EXPECT_NE(p2, (char*)0);\n  EXPECT_NE(p2, p);\n  InternalFree(p);\n  InternalFree(p2);\n}\n\nTEST(Allocator, Stress) {\n  const int kCount = 1000;\n  char *ptrs[kCount];\n  unsigned rnd = 42;\n  for (int i = 0; i < kCount; i++) {\n    uptr sz = my_rand_r(&rnd) % 1000;\n    char *p = (char*)InternalAlloc(sz);\n    EXPECT_NE(p, (char*)0);\n    ptrs[i] = p;\n  }\n  for (int i = 0; i < kCount; i++) {\n    InternalFree(ptrs[i]);\n  }\n}\n\nTEST(Allocator, LargeAlloc) {\n  void *p = InternalAlloc(10 << 20);\n  InternalFree(p);\n}\n\nTEST(Allocator, ScopedBuffer) {\n  const int kSize = 512;\n  {\n    InternalScopedBuffer<int> int_buf(kSize);\n    EXPECT_EQ(sizeof(int) * kSize, int_buf.size());  // NOLINT\n  }\n  InternalScopedBuffer<char> char_buf(kSize);\n  EXPECT_EQ(sizeof(char) * kSize, char_buf.size());  // NOLINT\n  internal_memset(char_buf.data(), 'c', kSize);\n  for (int i = 0; i < kSize; i++) {\n    EXPECT_EQ('c', char_buf[i]);\n  }\n}\n\nvoid IterationTestCallback(uptr chunk, void *arg) {\n  reinterpret_cast<std::set<uptr> *>(arg)->insert(chunk);\n}\n\ntemplate <class Allocator>\nvoid TestSizeClassAllocatorIteration() {\n  Allocator *a = new Allocator;\n  a->Init();\n  SizeClassAllocatorLocalCache<Allocator> cache;\n  memset(&cache, 0, sizeof(cache));\n  cache.Init(0);\n\n  static const uptr sizes[] = {1, 16, 30, 40, 100, 1000, 10000,\n    50000, 60000, 100000, 120000, 300000, 500000, 1000000, 2000000};\n\n  std::vector<void *> allocated;\n\n  // Allocate a bunch of chunks.\n  for (uptr s = 0; s < ARRAY_SIZE(sizes); s++) {\n    uptr size = sizes[s];\n    if (!a->CanAllocate(size, 1)) continue;\n    // printf(\"s = %ld\\n\", size);\n    uptr n_iter = std::max((uptr)6, 80000 / size);\n    // fprintf(stderr, \"size: %ld iter: %ld\\n\", size, n_iter);\n    for (uptr j = 0; j < n_iter; j++) {\n      uptr class_id0 = Allocator::SizeClassMapT::ClassID(size);\n      void *x = cache.Allocate(a, class_id0);\n      allocated.push_back(x);\n    }\n  }\n\n  std::set<uptr> reported_chunks;\n  a->ForceLock();\n  a->ForEachChunk(IterationTestCallback, &reported_chunks);\n  a->ForceUnlock();\n\n  for (uptr i = 0; i < allocated.size(); i++) {\n    // Don't use EXPECT_NE. Reporting the first mismatch is enough.\n    ASSERT_NE(reported_chunks.find(reinterpret_cast<uptr>(allocated[i])),\n              reported_chunks.end());\n  }\n\n  a->TestOnlyUnmap();\n  delete a;\n}\n\n#if SANITIZER_CAN_USE_ALLOCATOR64\nTEST(SanitizerCommon, SizeClassAllocator64Iteration) {\n  TestSizeClassAllocatorIteration<Allocator64>();\n}\n#endif\n\nTEST(SanitizerCommon, SizeClassAllocator32Iteration) {\n  TestSizeClassAllocatorIteration<Allocator32Compact>();\n}\n\nTEST(SanitizerCommon, LargeMmapAllocatorIteration) {\n  LargeMmapAllocator<> a;\n  a.Init(/* may_return_null */ false);\n  AllocatorStats stats;\n  stats.Init();\n\n  static const uptr kNumAllocs = 1000;\n  char *allocated[kNumAllocs];\n  static const uptr size = 40;\n  // Allocate some.\n  for (uptr i = 0; i < kNumAllocs; i++)\n    allocated[i] = (char *)a.Allocate(&stats, size, 1);\n\n  std::set<uptr> reported_chunks;\n  a.ForceLock();\n  a.ForEachChunk(IterationTestCallback, &reported_chunks);\n  a.ForceUnlock();\n\n  for (uptr i = 0; i < kNumAllocs; i++) {\n    // Don't use EXPECT_NE. Reporting the first mismatch is enough.\n    ASSERT_NE(reported_chunks.find(reinterpret_cast<uptr>(allocated[i])),\n              reported_chunks.end());\n  }\n  for (uptr i = 0; i < kNumAllocs; i++)\n    a.Deallocate(&stats, allocated[i]);\n}\n\nTEST(SanitizerCommon, LargeMmapAllocatorBlockBegin) {\n  LargeMmapAllocator<> a;\n  a.Init(/* may_return_null */ false);\n  AllocatorStats stats;\n  stats.Init();\n\n  static const uptr kNumAllocs = 1024;\n  static const uptr kNumExpectedFalseLookups = 10000000;\n  char *allocated[kNumAllocs];\n  static const uptr size = 4096;\n  // Allocate some.\n  for (uptr i = 0; i < kNumAllocs; i++) {\n    allocated[i] = (char *)a.Allocate(&stats, size, 1);\n  }\n\n  a.ForceLock();\n  for (uptr i = 0; i < kNumAllocs  * kNumAllocs; i++) {\n    // if ((i & (i - 1)) == 0) fprintf(stderr, \"[%zd]\\n\", i);\n    char *p1 = allocated[i % kNumAllocs];\n    EXPECT_EQ(p1, a.GetBlockBeginFastLocked(p1));\n    EXPECT_EQ(p1, a.GetBlockBeginFastLocked(p1 + size / 2));\n    EXPECT_EQ(p1, a.GetBlockBeginFastLocked(p1 + size - 1));\n    EXPECT_EQ(p1, a.GetBlockBeginFastLocked(p1 - 100));\n  }\n\n  for (uptr i = 0; i < kNumExpectedFalseLookups; i++) {\n    void *p = reinterpret_cast<void *>(i % 1024);\n    EXPECT_EQ((void *)0, a.GetBlockBeginFastLocked(p));\n    p = reinterpret_cast<void *>(~0L - (i % 1024));\n    EXPECT_EQ((void *)0, a.GetBlockBeginFastLocked(p));\n  }\n  a.ForceUnlock();\n\n  for (uptr i = 0; i < kNumAllocs; i++)\n    a.Deallocate(&stats, allocated[i]);\n}\n\n\n#if SANITIZER_CAN_USE_ALLOCATOR64\n// Regression test for out-of-memory condition in PopulateFreeList().\nTEST(SanitizerCommon, SizeClassAllocator64PopulateFreeListOOM) {\n  // In a world where regions are small and chunks are huge...\n  typedef SizeClassMap<63, 128, 16> SpecialSizeClassMap;\n  typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 0,\n                               SpecialSizeClassMap> SpecialAllocator64;\n  const uptr kRegionSize =\n      kAllocatorSize / SpecialSizeClassMap::kNumClassesRounded;\n  SpecialAllocator64 *a = new SpecialAllocator64;\n  a->Init();\n  SizeClassAllocatorLocalCache<SpecialAllocator64> cache;\n  memset(&cache, 0, sizeof(cache));\n  cache.Init(0);\n\n  // ...one man is on a mission to overflow a region with a series of\n  // successive allocations.\n  const uptr kClassID = 107;\n  const uptr kAllocationSize = DefaultSizeClassMap::Size(kClassID);\n  ASSERT_LT(2 * kAllocationSize, kRegionSize);\n  ASSERT_GT(3 * kAllocationSize, kRegionSize);\n  cache.Allocate(a, kClassID);\n  EXPECT_DEATH(cache.Allocate(a, kClassID) && cache.Allocate(a, kClassID),\n               \"The process has exhausted\");\n  a->TestOnlyUnmap();\n  delete a;\n}\n#endif\n\nTEST(SanitizerCommon, TwoLevelByteMap) {\n  const u64 kSize1 = 1 << 6, kSize2 = 1 << 12;\n  const u64 n = kSize1 * kSize2;\n  TwoLevelByteMap<kSize1, kSize2> m;\n  m.TestOnlyInit();\n  for (u64 i = 0; i < n; i += 7) {\n    m.set(i, (i % 100) + 1);\n  }\n  for (u64 j = 0; j < n; j++) {\n    if (j % 7)\n      EXPECT_EQ(m[j], 0);\n    else\n      EXPECT_EQ(m[j], (j % 100) + 1);\n  }\n\n  m.TestOnlyUnmap();\n}\n\n\ntypedef TwoLevelByteMap<1 << 12, 1 << 13, TestMapUnmapCallback> TestByteMap;\n\nstruct TestByteMapParam {\n  TestByteMap *m;\n  size_t shard;\n  size_t num_shards;\n};\n\nvoid *TwoLevelByteMapUserThread(void *param) {\n  TestByteMapParam *p = (TestByteMapParam*)param;\n  for (size_t i = p->shard; i < p->m->size(); i += p->num_shards) {\n    size_t val = (i % 100) + 1;\n    p->m->set(i, val);\n    EXPECT_EQ((*p->m)[i], val);\n  }\n  return 0;\n}\n\nTEST(SanitizerCommon, ThreadedTwoLevelByteMap) {\n  TestByteMap m;\n  m.TestOnlyInit();\n  TestMapUnmapCallback::map_count = 0;\n  TestMapUnmapCallback::unmap_count = 0;\n  static const int kNumThreads = 4;\n  pthread_t t[kNumThreads];\n  TestByteMapParam p[kNumThreads];\n  for (int i = 0; i < kNumThreads; i++) {\n    p[i].m = &m;\n    p[i].shard = i;\n    p[i].num_shards = kNumThreads;\n    PTHREAD_CREATE(&t[i], 0, TwoLevelByteMapUserThread, &p[i]);\n  }\n  for (int i = 0; i < kNumThreads; i++) {\n    PTHREAD_JOIN(t[i], 0);\n  }\n  EXPECT_EQ((uptr)TestMapUnmapCallback::map_count, m.size1());\n  EXPECT_EQ((uptr)TestMapUnmapCallback::unmap_count, 0UL);\n  m.TestOnlyUnmap();\n  EXPECT_EQ((uptr)TestMapUnmapCallback::map_count, m.size1());\n  EXPECT_EQ((uptr)TestMapUnmapCallback::unmap_count, m.size1());\n}\n\n#endif  // #if !SANITIZER_DEBUG\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_testlib.cc",
    "content": "//===-- sanitizer_allocator_testlib.cc ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Malloc replacement library based on CombinedAllocator.\n// The primary purpose of this file is an end-to-end integration test\n// for CombinedAllocator.\n//===----------------------------------------------------------------------===//\n/* Usage:\nclang++ -fno-exceptions  -g -fPIC -I. -I../include -Isanitizer \\\n sanitizer_common/tests/sanitizer_allocator_testlib.cc \\\n sanitizer_common/sanitizer_*.cc -shared -lpthread -o testmalloc.so\nLD_PRELOAD=`pwd`/testmalloc.so /your/app\n*/\n#include \"sanitizer_common/sanitizer_allocator.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include <stddef.h>\n#include <stdio.h>\n#include <unistd.h>\n#include <string.h>\n#include <pthread.h>\n\n#ifndef SANITIZER_MALLOC_HOOK\n# define SANITIZER_MALLOC_HOOK(p, s)\n#endif\n\n#ifndef SANITIZER_FREE_HOOK\n# define SANITIZER_FREE_HOOK(p)\n#endif\n\nnamespace {\nstatic const uptr kAllocatorSpace = 0x600000000000ULL;\nstatic const uptr kAllocatorSize  =  0x10000000000ULL;  // 1T.\n\ntypedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 0,\n  CompactSizeClassMap> PrimaryAllocator;\ntypedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;\ntypedef LargeMmapAllocator<> SecondaryAllocator;\ntypedef CombinedAllocator<PrimaryAllocator, AllocatorCache,\n          SecondaryAllocator> Allocator;\n\nstatic Allocator allocator;\nstatic bool global_inited;\nstatic THREADLOCAL AllocatorCache cache;\nstatic THREADLOCAL bool thread_inited;\nstatic pthread_key_t pkey;\n\nstatic void thread_dtor(void *v) {\n  if ((uptr)v != 3) {\n    pthread_setspecific(pkey, (void*)((uptr)v + 1));\n    return;\n  }\n  allocator.SwallowCache(&cache);\n}\n\nstatic void NOINLINE thread_init() {\n  if (!global_inited) {\n    global_inited = true;\n    allocator.Init();\n    pthread_key_create(&pkey, thread_dtor);\n  }\n  thread_inited = true;\n  pthread_setspecific(pkey, (void*)1);\n  cache.Init();\n}\n}  // namespace\n\nextern \"C\" {\nvoid *malloc(size_t size) {\n  if (UNLIKELY(!thread_inited))\n    thread_init();\n  void *p = allocator.Allocate(&cache, size, 8);\n  SANITIZER_MALLOC_HOOK(p, size);\n  return p;\n}\n\nvoid free(void *p) {\n  if (UNLIKELY(!thread_inited))\n    thread_init();\n  SANITIZER_FREE_HOOK(p);\n  allocator.Deallocate(&cache, p);\n}\n\nvoid *calloc(size_t nmemb, size_t size) {\n  if (UNLIKELY(!thread_inited))\n    thread_init();\n  size *= nmemb;\n  void *p = allocator.Allocate(&cache, size, 8, false);\n  memset(p, 0, size);\n  SANITIZER_MALLOC_HOOK(p, size);\n  return p;\n}\n\nvoid *realloc(void *p, size_t size) {\n  if (UNLIKELY(!thread_inited))\n    thread_init();\n  if (p) {\n    SANITIZER_FREE_HOOK(p);\n  }\n  p = allocator.Reallocate(&cache, p, size, 8);\n  if (p) {\n    SANITIZER_MALLOC_HOOK(p, size);\n  }\n  return p;\n}\n\nvoid *memalign(size_t alignment, size_t size) {\n  if (UNLIKELY(!thread_inited))\n    thread_init();\n  void *p = allocator.Allocate(&cache, size, alignment);\n  SANITIZER_MALLOC_HOOK(p, size);\n  return p;\n}\n\nint posix_memalign(void **memptr, size_t alignment, size_t size) {\n  if (UNLIKELY(!thread_inited))\n    thread_init();\n  *memptr = allocator.Allocate(&cache, size, alignment);\n  SANITIZER_MALLOC_HOOK(*memptr, size);\n  return 0;\n}\n\nvoid *valloc(size_t size) {\n  if (UNLIKELY(!thread_inited))\n    thread_init();\n  if (size == 0)\n    size = GetPageSizeCached();\n  void *p = allocator.Allocate(&cache, size, GetPageSizeCached());\n  SANITIZER_MALLOC_HOOK(p, size);\n  return p;\n}\n\nvoid cfree(void *p) ALIAS(\"free\");\nvoid *pvalloc(size_t size) ALIAS(\"valloc\");\nvoid *__libc_memalign(size_t alignment, size_t size) ALIAS(\"memalign\");\n\nvoid malloc_usable_size() {\n}\n\nvoid mallinfo() {\n}\n\nvoid mallopt() {\n}\n}  // extern \"C\"\n\nnamespace std {\n  struct nothrow_t;\n}\n\nvoid *operator new(size_t size) ALIAS(\"malloc\");\nvoid *operator new[](size_t size) ALIAS(\"malloc\");\nvoid *operator new(size_t size, std::nothrow_t const&) ALIAS(\"malloc\");\nvoid *operator new[](size_t size, std::nothrow_t const&) ALIAS(\"malloc\");\nvoid operator delete(void *ptr) throw() ALIAS(\"free\");\nvoid operator delete[](void *ptr) throw() ALIAS(\"free\");\nvoid operator delete(void *ptr, std::nothrow_t const&) ALIAS(\"free\");\nvoid operator delete[](void *ptr, std::nothrow_t const&) ALIAS(\"free\");\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_atomic_test.cc",
    "content": "//===-- sanitizer_atomic_test.cc ------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"gtest/gtest.h\"\n\nnamespace __sanitizer {\n\ntemplate<typename T>\nstruct ValAndMagic {\n  typename T::Type magic0;\n  T a;\n  typename T::Type magic1;\n\n  static ValAndMagic<T> *sink;\n};\n\ntemplate<typename T>\nValAndMagic<T> *ValAndMagic<T>::sink;\n\ntemplate<typename T, memory_order load_mo, memory_order store_mo>\nvoid CheckStoreLoad() {\n  typedef typename T::Type Type;\n  ValAndMagic<T> val;\n  // Prevent the compiler from scalarizing the struct.\n  ValAndMagic<T>::sink = &val;\n  // Ensure that surrounding memory is not overwritten.\n  val.magic0 = val.magic1 = (Type)-3;\n  for (u64 i = 0; i < 100; i++) {\n    // Generate a value that occupies all bytes of the variable.\n    u64 v = i;\n    v |= v << 8;\n    v |= v << 16;\n    v |= v << 32;\n    val.a.val_dont_use = (Type)v;\n    EXPECT_EQ(atomic_load(&val.a, load_mo), (Type)v);\n    val.a.val_dont_use = (Type)-1;\n    atomic_store(&val.a, (Type)v, store_mo);\n    EXPECT_EQ(val.a.val_dont_use, (Type)v);\n  }\n  EXPECT_EQ(val.magic0, (Type)-3);\n  EXPECT_EQ(val.magic1, (Type)-3);\n}\n\nTEST(SanitizerCommon, AtomicStoreLoad) {\n  CheckStoreLoad<atomic_uint8_t, memory_order_relaxed, memory_order_relaxed>();\n  CheckStoreLoad<atomic_uint8_t, memory_order_consume, memory_order_relaxed>();\n  CheckStoreLoad<atomic_uint8_t, memory_order_acquire, memory_order_relaxed>();\n  CheckStoreLoad<atomic_uint8_t, memory_order_relaxed, memory_order_release>();\n  CheckStoreLoad<atomic_uint8_t, memory_order_seq_cst, memory_order_seq_cst>();\n\n  CheckStoreLoad<atomic_uint16_t, memory_order_relaxed, memory_order_relaxed>();\n  CheckStoreLoad<atomic_uint16_t, memory_order_consume, memory_order_relaxed>();\n  CheckStoreLoad<atomic_uint16_t, memory_order_acquire, memory_order_relaxed>();\n  CheckStoreLoad<atomic_uint16_t, memory_order_relaxed, memory_order_release>();\n  CheckStoreLoad<atomic_uint16_t, memory_order_seq_cst, memory_order_seq_cst>();\n\n  CheckStoreLoad<atomic_uint32_t, memory_order_relaxed, memory_order_relaxed>();\n  CheckStoreLoad<atomic_uint32_t, memory_order_consume, memory_order_relaxed>();\n  CheckStoreLoad<atomic_uint32_t, memory_order_acquire, memory_order_relaxed>();\n  CheckStoreLoad<atomic_uint32_t, memory_order_relaxed, memory_order_release>();\n  CheckStoreLoad<atomic_uint32_t, memory_order_seq_cst, memory_order_seq_cst>();\n\n  CheckStoreLoad<atomic_uint64_t, memory_order_relaxed, memory_order_relaxed>();\n  CheckStoreLoad<atomic_uint64_t, memory_order_consume, memory_order_relaxed>();\n  CheckStoreLoad<atomic_uint64_t, memory_order_acquire, memory_order_relaxed>();\n  CheckStoreLoad<atomic_uint64_t, memory_order_relaxed, memory_order_release>();\n  CheckStoreLoad<atomic_uint64_t, memory_order_seq_cst, memory_order_seq_cst>();\n\n  CheckStoreLoad<atomic_uintptr_t, memory_order_relaxed, memory_order_relaxed>\n      ();\n  CheckStoreLoad<atomic_uintptr_t, memory_order_consume, memory_order_relaxed>\n      ();\n  CheckStoreLoad<atomic_uintptr_t, memory_order_acquire, memory_order_relaxed>\n      ();\n  CheckStoreLoad<atomic_uintptr_t, memory_order_relaxed, memory_order_release>\n      ();\n  CheckStoreLoad<atomic_uintptr_t, memory_order_seq_cst, memory_order_seq_cst>\n      ();\n}\n\n// Clang crashes while compiling this test for Android:\n// http://llvm.org/bugs/show_bug.cgi?id=15587\n#if !SANITIZER_ANDROID\ntemplate<typename T>\nvoid CheckAtomicCompareExchange() {\n  typedef typename T::Type Type;\n  {\n    Type old_val = 42;\n    Type new_val = 24;\n    Type var = old_val;\n    EXPECT_TRUE(atomic_compare_exchange_strong((T*)&var, &old_val, new_val,\n                                               memory_order_relaxed));\n    EXPECT_FALSE(atomic_compare_exchange_strong((T*)&var, &old_val, new_val,\n                                                memory_order_relaxed));\n    EXPECT_EQ(new_val, old_val);\n  }\n  {\n    Type old_val = 42;\n    Type new_val = 24;\n    Type var = old_val;\n    EXPECT_TRUE(atomic_compare_exchange_weak((T*)&var, &old_val, new_val,\n                                             memory_order_relaxed));\n    EXPECT_FALSE(atomic_compare_exchange_weak((T*)&var, &old_val, new_val,\n                                              memory_order_relaxed));\n    EXPECT_EQ(new_val, old_val);\n  }\n}\n\nTEST(SanitizerCommon, AtomicCompareExchangeTest) {\n  CheckAtomicCompareExchange<atomic_uint8_t>();\n  CheckAtomicCompareExchange<atomic_uint16_t>();\n  CheckAtomicCompareExchange<atomic_uint32_t>();\n  CheckAtomicCompareExchange<atomic_uint64_t>();\n  CheckAtomicCompareExchange<atomic_uintptr_t>();\n}\n#endif  //!SANITIZER_ANDROID\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_bitvector_test.cc",
    "content": "//===-- sanitizer_bitvector_test.cc ---------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of Sanitizer runtime.\n// Tests for sanitizer_bitvector.h.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_bitvector.h\"\n\n#include \"sanitizer_test_utils.h\"\n\n#include \"gtest/gtest.h\"\n\n#include <algorithm>\n#include <vector>\n#include <set>\n\nusing namespace __sanitizer;\nusing namespace std;\n\n\n// Check the 'bv' == 's' and that the indexes go in increasing order.\n// Also check the BV::Iterator\ntemplate <class BV>\nstatic void CheckBV(const BV &bv, const set<uptr> &s) {\n  BV t;\n  t.copyFrom(bv);\n  set<uptr> t_s(s);\n  uptr last_idx = bv.size();\n  uptr count = 0;\n  for (typename BV::Iterator it(bv); it.hasNext();) {\n    uptr idx = it.next();\n    count++;\n    if (last_idx != bv.size())\n      EXPECT_LT(last_idx, idx);\n    last_idx = idx;\n    EXPECT_TRUE(s.count(idx));\n  }\n  EXPECT_EQ(count, s.size());\n\n  last_idx = bv.size();\n  while (!t.empty()) {\n    uptr idx = t.getAndClearFirstOne();\n    if (last_idx != bv.size())\n      EXPECT_LT(last_idx, idx);\n    last_idx = idx;\n    EXPECT_TRUE(t_s.erase(idx));\n  }\n  EXPECT_TRUE(t_s.empty());\n}\n\ntemplate <class BV>\nvoid Print(const BV &bv) {\n  BV t;\n  t.copyFrom(bv);\n  while (!t.empty()) {\n    uptr idx = t.getAndClearFirstOne();\n    fprintf(stderr, \"%zd \", idx);\n  }\n  fprintf(stderr, \"\\n\");\n}\n\nvoid Print(const set<uptr> &s) {\n  for (set<uptr>::iterator it = s.begin(); it != s.end(); ++it) {\n    fprintf(stderr, \"%zd \", *it);\n  }\n  fprintf(stderr, \"\\n\");\n}\n\ntemplate <class BV>\nvoid TestBitVector(uptr expected_size) {\n  BV bv, bv1, t_bv;\n  EXPECT_EQ(expected_size, BV::kSize);\n  bv.clear();\n  EXPECT_TRUE(bv.empty());\n  bv.setBit(5);\n  EXPECT_FALSE(bv.empty());\n  EXPECT_FALSE(bv.getBit(4));\n  EXPECT_FALSE(bv.getBit(6));\n  EXPECT_TRUE(bv.getBit(5));\n  bv.clearBit(5);\n  EXPECT_FALSE(bv.getBit(5));\n\n  // test random bits\n  bv.clear();\n  set<uptr> s;\n  for (uptr it = 0; it < 1000; it++) {\n    uptr bit = ((uptr)my_rand() % bv.size());\n    EXPECT_EQ(bv.getBit(bit), s.count(bit) == 1);\n    switch (my_rand() % 2) {\n      case 0:\n        EXPECT_EQ(bv.setBit(bit), s.insert(bit).second);\n        break;\n      case 1:\n        size_t old_size = s.size();\n        s.erase(bit);\n        EXPECT_EQ(bv.clearBit(bit), old_size > s.size());\n        break;\n    }\n    EXPECT_EQ(bv.getBit(bit), s.count(bit) == 1);\n  }\n\n  vector<uptr>bits(bv.size());\n  // Test setUnion, setIntersection, setDifference,\n  // intersectsWith, and getAndClearFirstOne.\n  for (uptr it = 0; it < 30; it++) {\n    // iota\n    for (size_t j = 0; j < bits.size(); j++) bits[j] = j;\n    random_shuffle(bits.begin(), bits.end());\n    set<uptr> s, s1, t_s;\n    bv.clear();\n    bv1.clear();\n    uptr n_bits = ((uptr)my_rand() % bv.size()) + 1;\n    uptr n_bits1 = (uptr)my_rand() % (bv.size() / 2);\n    EXPECT_TRUE(n_bits > 0 && n_bits <= bv.size());\n    EXPECT_TRUE(n_bits1 < bv.size() / 2);\n    for (uptr i = 0; i < n_bits; i++) {\n      bv.setBit(bits[i]);\n      s.insert(bits[i]);\n    }\n    CheckBV(bv, s);\n    for (uptr i = 0; i < n_bits1; i++) {\n      bv1.setBit(bits[bv.size() / 2 + i]);\n      s1.insert(bits[bv.size() / 2 + i]);\n    }\n    CheckBV(bv1, s1);\n\n    vector<uptr> vec;\n    set_intersection(s.begin(), s.end(), s1.begin(), s1.end(),\n                     back_insert_iterator<vector<uptr> >(vec));\n    EXPECT_EQ(bv.intersectsWith(bv1), !vec.empty());\n\n    // setUnion\n    t_s = s;\n    t_bv.copyFrom(bv);\n    t_s.insert(s1.begin(), s1.end());\n    EXPECT_EQ(t_bv.setUnion(bv1), s.size() != t_s.size());\n    CheckBV(t_bv, t_s);\n\n    // setIntersection\n    t_s = set<uptr>(vec.begin(), vec.end());\n    t_bv.copyFrom(bv);\n    EXPECT_EQ(t_bv.setIntersection(bv1), s.size() != t_s.size());\n    CheckBV(t_bv, t_s);\n\n    // setDifference\n    vec.clear();\n    set_difference(s.begin(), s.end(), s1.begin(), s1.end(),\n                     back_insert_iterator<vector<uptr> >(vec));\n    t_s = set<uptr>(vec.begin(), vec.end());\n    t_bv.copyFrom(bv);\n    EXPECT_EQ(t_bv.setDifference(bv1), s.size() != t_s.size());\n    CheckBV(t_bv, t_s);\n  }\n}\n\nTEST(SanitizerCommon, BasicBitVector) {\n  TestBitVector<BasicBitVector<u8> >(8);\n  TestBitVector<BasicBitVector<u16> >(16);\n  TestBitVector<BasicBitVector<> >(SANITIZER_WORDSIZE);\n}\n\nTEST(SanitizerCommon, TwoLevelBitVector) {\n  uptr ws = SANITIZER_WORDSIZE;\n  TestBitVector<TwoLevelBitVector<1, BasicBitVector<u8> > >(8 * 8);\n  TestBitVector<TwoLevelBitVector<> >(ws * ws);\n  TestBitVector<TwoLevelBitVector<2> >(ws * ws * 2);\n  TestBitVector<TwoLevelBitVector<3> >(ws * ws * 3);\n  TestBitVector<TwoLevelBitVector<3, BasicBitVector<u16> > >(16 * 16 * 3);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_bvgraph_test.cc",
    "content": "//===-- sanitizer_bvgraph_test.cc -----------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of Sanitizer runtime.\n// Tests for sanitizer_bvgraph.h.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_bvgraph.h\"\n\n#include \"sanitizer_test_utils.h\"\n\n#include \"gtest/gtest.h\"\n\n#include <algorithm>\n#include <vector>\n#include <set>\n\nusing namespace __sanitizer;\nusing namespace std;\n\ntypedef BasicBitVector<u8> BV1;\ntypedef BasicBitVector<> BV2;\ntypedef TwoLevelBitVector<> BV3;\ntypedef TwoLevelBitVector<3, BasicBitVector<u8> > BV4;\n\ntemplate<class G>\nvoid PrintGraph(const G &g) {\n  for (uptr i = 0; i < g.size(); i++) {\n    for (uptr j = 0; j < g.size(); j++) {\n      fprintf(stderr, \"%d\", g.hasEdge(i, j));\n    }\n    fprintf(stderr, \"\\n\");\n  }\n}\n\n\nclass SimpleGraph {\n public:\n  void clear() { s_.clear(); }\n  bool addEdge(uptr from, uptr to) {\n    return s_.insert(idx(from, to)).second;\n  }\n  bool removeEdge(uptr from, uptr to) {\n    return s_.erase(idx(from, to));\n  }\n  template <class G>\n  void checkSameAs(G *g) {\n    for (set<uptr>::iterator it = s_.begin(); it != s_.end(); ++it) {\n      uptr from = *it >> 16;\n      uptr to = *it & ((1 << 16) - 1);\n      EXPECT_TRUE(g->removeEdge(from, to));\n    }\n    EXPECT_TRUE(g->empty());\n  }\n private:\n  uptr idx(uptr from, uptr to) {\n    CHECK_LE(from|to, 1 << 16);\n    return (from << 16) + to;\n  }\n  set<uptr> s_;\n};\n\ntemplate <class BV>\nvoid BasicTest() {\n  BVGraph<BV> g;\n  g.clear();\n  BV target;\n  SimpleGraph s_g;\n  set<uptr> s;\n  set<uptr> s_target;\n  int num_reachable = 0;\n  for (int it = 0; it < 1000; it++) {\n    target.clear();\n    s_target.clear();\n    for (int t = 0; t < 4; t++) {\n      uptr idx = (uptr)my_rand() % g.size();\n      EXPECT_EQ(target.setBit(idx), s_target.insert(idx).second);\n    }\n    uptr from = my_rand() % g.size();\n    uptr to = my_rand() % g.size();\n    EXPECT_EQ(g.addEdge(from, to), s_g.addEdge(from, to));\n    EXPECT_TRUE(g.hasEdge(from, to));\n    for (int i = 0; i < 10; i++) {\n      from = my_rand() % g.size();\n      bool is_reachable = g.isReachable(from, target);\n      if (is_reachable) {\n        uptr path[BV::kSize];\n        uptr len;\n        for (len = 1; len < BV::kSize; len++) {\n          if (g.findPath(from, target, path, len) == len)\n            break;\n        }\n        EXPECT_LT(len, BV::kSize);\n        EXPECT_TRUE(target.getBit(path[len - 1]));\n        // fprintf(stderr, \"reachable: %zd; path %zd {%zd %zd %zd}\\n\",\n        //        from, len, path[0], path[1], path[2]);\n        num_reachable++;\n      }\n    }\n  }\n  EXPECT_GT(num_reachable, 0);\n}\n\nTEST(BVGraph, BasicTest) {\n  BasicTest<BV1>();\n  BasicTest<BV2>();\n  BasicTest<BV3>();\n  BasicTest<BV4>();\n}\n\ntemplate <class BV>\nvoid RemoveEdges() {\n  SimpleGraph s_g;\n  BVGraph<BV> g;\n  g.clear();\n  BV bv;\n  set<uptr> s;\n  for (int it = 0; it < 100; it++) {\n    s.clear();\n    bv.clear();\n    s_g.clear();\n    g.clear();\n    for (uptr j = 0; j < g.size() * 2; j++) {\n      uptr from = my_rand() % g.size();\n      uptr to = my_rand() % g.size();\n      EXPECT_EQ(g.addEdge(from, to), s_g.addEdge(from, to));\n    }\n    for (uptr j = 0; j < 5; j++) {\n      uptr idx = my_rand() % g.size();\n      s.insert(idx);\n      bv.setBit(idx);\n    }\n\n    if (it % 2) {\n      g.removeEdgesFrom(bv);\n      for (set<uptr>::iterator from = s.begin(); from != s.end(); ++from) {\n        for (uptr to = 0; to < g.size(); to++)\n          s_g.removeEdge(*from, to);\n      }\n    } else {\n      g.removeEdgesTo(bv);\n      for (set<uptr>::iterator to = s.begin(); to != s.end(); ++to) {\n        for (uptr from = 0; from < g.size(); from++)\n          s_g.removeEdge(from, *to);\n      }\n    }\n    s_g.checkSameAs(&g);\n  }\n}\n\nTEST(BVGraph, RemoveEdges) {\n  RemoveEdges<BV1>();\n  RemoveEdges<BV2>();\n  RemoveEdges<BV3>();\n  RemoveEdges<BV4>();\n}\n\ntemplate <class BV>\nvoid Test_isReachable() {\n  uptr path[5];\n  BVGraph<BV> g;\n  g.clear();\n  BV target;\n  target.clear();\n  uptr t0 = 0;\n  uptr t1 = g.size() - 1;\n  target.setBit(t0);\n  target.setBit(t1);\n\n  uptr f0 = 1;\n  uptr f1 = 2;\n  uptr f2 = g.size() / 2;\n  uptr f3 = g.size() - 2;\n\n  EXPECT_FALSE(g.isReachable(f0, target));\n  EXPECT_FALSE(g.isReachable(f1, target));\n  EXPECT_FALSE(g.isReachable(f2, target));\n  EXPECT_FALSE(g.isReachable(f3, target));\n\n  g.addEdge(f0, f1);\n  g.addEdge(f1, f2);\n  g.addEdge(f2, f3);\n  EXPECT_FALSE(g.isReachable(f0, target));\n  EXPECT_FALSE(g.isReachable(f1, target));\n  EXPECT_FALSE(g.isReachable(f2, target));\n  EXPECT_FALSE(g.isReachable(f3, target));\n\n  g.addEdge(f1, t0);\n  EXPECT_TRUE(g.isReachable(f0, target));\n  EXPECT_TRUE(g.isReachable(f1, target));\n  EXPECT_FALSE(g.isReachable(f2, target));\n  EXPECT_FALSE(g.isReachable(f3, target));\n  EXPECT_EQ(g.findPath(f0, target, path, ARRAY_SIZE(path)), 3U);\n  EXPECT_EQ(path[0], f0);\n  EXPECT_EQ(path[1], f1);\n  EXPECT_EQ(path[2], t0);\n  EXPECT_EQ(g.findPath(f1, target, path, ARRAY_SIZE(path)), 2U);\n  EXPECT_EQ(path[0], f1);\n  EXPECT_EQ(path[1], t0);\n\n  g.addEdge(f3, t1);\n  EXPECT_TRUE(g.isReachable(f0, target));\n  EXPECT_TRUE(g.isReachable(f1, target));\n  EXPECT_TRUE(g.isReachable(f2, target));\n  EXPECT_TRUE(g.isReachable(f3, target));\n}\n\nTEST(BVGraph, isReachable) {\n  Test_isReachable<BV1>();\n  Test_isReachable<BV2>();\n  Test_isReachable<BV3>();\n  Test_isReachable<BV4>();\n}\n\ntemplate <class BV>\nvoid LongCycle() {\n  BVGraph<BV> g;\n  g.clear();\n  vector<uptr> path_vec(g.size());\n  uptr *path = path_vec.data();\n  uptr start = 5;\n  for (uptr i = start; i < g.size() - 1; i++) {\n    g.addEdge(i, i + 1);\n    for (uptr j = 0; j < start; j++)\n      g.addEdge(i, j);\n  }\n  //  Bad graph that looks like this:\n  // 00000000000000\n  // 00000000000000\n  // 00000000000000\n  // 00000000000000\n  // 00000000000000\n  // 11111010000000\n  // 11111001000000\n  // 11111000100000\n  // 11111000010000\n  // 11111000001000\n  // 11111000000100\n  // 11111000000010\n  // 11111000000001\n  // if (g.size() <= 64) PrintGraph(g);\n  BV target;\n  for (uptr i = start + 1; i < g.size(); i += 11) {\n    // if ((i & (i - 1)) == 0) fprintf(stderr, \"Path: : %zd\\n\", i);\n    target.clear();\n    target.setBit(i);\n    EXPECT_TRUE(g.isReachable(start, target));\n    EXPECT_EQ(g.findPath(start, target, path, g.size()), i - start + 1);\n  }\n}\n\nTEST(BVGraph, LongCycle) {\n  LongCycle<BV1>();\n  LongCycle<BV2>();\n  LongCycle<BV3>();\n  LongCycle<BV4>();\n}\n\ntemplate <class BV>\nvoid ShortestPath() {\n  uptr path[8];\n  BVGraph<BV> g;\n  g.clear();\n  BV t7;\n  t7.clear();\n  t7.setBit(7);\n  // 1=>2=>3=>4=>5=>6=>7\n  // 1=>7\n  g.addEdge(1, 2);\n  g.addEdge(2, 3);\n  g.addEdge(3, 4);\n  g.addEdge(4, 5);\n  g.addEdge(5, 6);\n  g.addEdge(6, 7);\n  g.addEdge(1, 7);\n  EXPECT_TRUE(g.isReachable(1, t7));\n  // No path of length 1.\n  EXPECT_EQ(0U, g.findPath(1, t7, path, 1));\n  // Trying to find a path of len 2..6 gives path of len 2.\n  EXPECT_EQ(2U, g.findPath(1, t7, path, 2));\n  EXPECT_EQ(2U, g.findPath(1, t7, path, 3));\n  EXPECT_EQ(2U, g.findPath(1, t7, path, 4));\n  EXPECT_EQ(2U, g.findPath(1, t7, path, 5));\n  EXPECT_EQ(2U, g.findPath(1, t7, path, 6));\n  // Trying to find a path of len 7 gives path of len 7, because this is DFS.\n  EXPECT_EQ(7U, g.findPath(1, t7, path, 7));\n  // But findShortestPath will find the shortest path.\n  EXPECT_EQ(2U, g.findShortestPath(1, t7, path, 2));\n  EXPECT_EQ(2U, g.findShortestPath(1, t7, path, 7));\n}\n\nTEST(BVGraph, ShortestPath) {\n  ShortestPath<BV1>();\n  ShortestPath<BV2>();\n  ShortestPath<BV3>();\n  ShortestPath<BV4>();\n}\n\ntemplate <class BV>\nvoid RunAddEdgesTest() {\n  BVGraph<BV> g;\n  BV from;\n  const int kMaxEdges = 10;\n  uptr added_edges[kMaxEdges];\n  g.clear();\n  from.clear();\n  EXPECT_EQ(0U, g.addEdges(from, 0, added_edges, kMaxEdges));\n  EXPECT_EQ(0U, g.addEdges(from, 1, added_edges, kMaxEdges));\n  from.setBit(0);\n  EXPECT_EQ(1U, g.addEdges(from, 1, added_edges, kMaxEdges));\n  EXPECT_EQ(0U, added_edges[0]);\n  EXPECT_EQ(0U, g.addEdges(from, 1, added_edges, kMaxEdges));\n\n  from.clear();\n  from.setBit(1);\n  EXPECT_EQ(1U, g.addEdges(from, 4, added_edges, kMaxEdges));\n  EXPECT_TRUE(g.hasEdge(1, 4));\n  EXPECT_FALSE(g.hasEdge(1, 5));\n  EXPECT_EQ(1U, added_edges[0]);\n  from.setBit(2);\n  from.setBit(3);\n  EXPECT_EQ(2U, g.addEdges(from, 4, added_edges, kMaxEdges));\n  EXPECT_TRUE(g.hasEdge(2, 4));\n  EXPECT_FALSE(g.hasEdge(2, 5));\n  EXPECT_TRUE(g.hasEdge(3, 4));\n  EXPECT_FALSE(g.hasEdge(3, 5));\n  EXPECT_EQ(2U, added_edges[0]);\n  EXPECT_EQ(3U, added_edges[1]);\n}\n\nTEST(BVGraph, AddEdgesTest) {\n  RunAddEdgesTest<BV2>();\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cc",
    "content": "//===-- sanitizer_common_test.cc ------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_allocator_internal.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_platform.h\"\n\n#include \"sanitizer_pthread_wrappers.h\"\n\n#include \"gtest/gtest.h\"\n\nnamespace __sanitizer {\n\nstatic bool IsSorted(const uptr *array, uptr n) {\n  for (uptr i = 1; i < n; i++) {\n    if (array[i] < array[i - 1]) return false;\n  }\n  return true;\n}\n\nTEST(SanitizerCommon, SortTest) {\n  uptr array[100];\n  uptr n = 100;\n  // Already sorted.\n  for (uptr i = 0; i < n; i++) {\n    array[i] = i;\n  }\n  SortArray(array, n);\n  EXPECT_TRUE(IsSorted(array, n));\n  // Reverse order.\n  for (uptr i = 0; i < n; i++) {\n    array[i] = n - 1 - i;\n  }\n  SortArray(array, n);\n  EXPECT_TRUE(IsSorted(array, n));\n  // Mixed order.\n  for (uptr i = 0; i < n; i++) {\n    array[i] = (i % 2 == 0) ? i : n - 1 - i;\n  }\n  SortArray(array, n);\n  EXPECT_TRUE(IsSorted(array, n));\n  // All equal.\n  for (uptr i = 0; i < n; i++) {\n    array[i] = 42;\n  }\n  SortArray(array, n);\n  EXPECT_TRUE(IsSorted(array, n));\n  // All but one sorted.\n  for (uptr i = 0; i < n - 1; i++) {\n    array[i] = i;\n  }\n  array[n - 1] = 42;\n  SortArray(array, n);\n  EXPECT_TRUE(IsSorted(array, n));\n  // Minimal case - sort three elements.\n  array[0] = 1;\n  array[1] = 0;\n  SortArray(array, 2);\n  EXPECT_TRUE(IsSorted(array, 2));\n}\n\nTEST(SanitizerCommon, MmapAlignedOrDie) {\n  uptr PageSize = GetPageSizeCached();\n  for (uptr size = 1; size <= 32; size *= 2) {\n    for (uptr alignment = 1; alignment <= 32; alignment *= 2) {\n      for (int iter = 0; iter < 100; iter++) {\n        uptr res = (uptr)MmapAlignedOrDie(\n            size * PageSize, alignment * PageSize, \"MmapAlignedOrDieTest\");\n        EXPECT_EQ(0U, res % (alignment * PageSize));\n        internal_memset((void*)res, 1, size * PageSize);\n        UnmapOrDie((void*)res, size * PageSize);\n      }\n    }\n  }\n}\n\n#if SANITIZER_LINUX\nTEST(SanitizerCommon, SanitizerSetThreadName) {\n  const char *names[] = {\n    \"0123456789012\",\n    \"01234567890123\",\n    \"012345678901234\",  // Larger names will be truncated on linux.\n  };\n\n  for (size_t i = 0; i < ARRAY_SIZE(names); i++) {\n    EXPECT_TRUE(SanitizerSetThreadName(names[i]));\n    char buff[100];\n    EXPECT_TRUE(SanitizerGetThreadName(buff, sizeof(buff) - 1));\n    EXPECT_EQ(0, internal_strcmp(buff, names[i]));\n  }\n}\n#endif\n\nTEST(SanitizerCommon, InternalMmapVector) {\n  InternalMmapVector<uptr> vector(1);\n  for (uptr i = 0; i < 100; i++) {\n    EXPECT_EQ(i, vector.size());\n    vector.push_back(i);\n  }\n  for (uptr i = 0; i < 100; i++) {\n    EXPECT_EQ(i, vector[i]);\n  }\n  for (int i = 99; i >= 0; i--) {\n    EXPECT_EQ((uptr)i, vector.back());\n    vector.pop_back();\n    EXPECT_EQ((uptr)i, vector.size());\n  }\n  InternalMmapVector<uptr> empty_vector(0);\n  CHECK_GT(empty_vector.capacity(), 0U);\n  CHECK_EQ(0U, empty_vector.size());\n}\n\nvoid TestThreadInfo(bool main) {\n  uptr stk_addr = 0;\n  uptr stk_size = 0;\n  uptr tls_addr = 0;\n  uptr tls_size = 0;\n  GetThreadStackAndTls(main, &stk_addr, &stk_size, &tls_addr, &tls_size);\n\n  int stack_var;\n  EXPECT_NE(stk_addr, (uptr)0);\n  EXPECT_NE(stk_size, (uptr)0);\n  EXPECT_GT((uptr)&stack_var, stk_addr);\n  EXPECT_LT((uptr)&stack_var, stk_addr + stk_size);\n\n#if SANITIZER_LINUX && defined(__x86_64__)\n  static __thread int thread_var;\n  EXPECT_NE(tls_addr, (uptr)0);\n  EXPECT_NE(tls_size, (uptr)0);\n  EXPECT_GT((uptr)&thread_var, tls_addr);\n  EXPECT_LT((uptr)&thread_var, tls_addr + tls_size);\n\n  // Ensure that tls and stack do not intersect.\n  uptr tls_end = tls_addr + tls_size;\n  EXPECT_TRUE(tls_addr < stk_addr || tls_addr >= stk_addr + stk_size);\n  EXPECT_TRUE(tls_end  < stk_addr || tls_end  >=  stk_addr + stk_size);\n  EXPECT_TRUE((tls_addr < stk_addr) == (tls_end  < stk_addr));\n#endif\n}\n\nstatic void *WorkerThread(void *arg) {\n  TestThreadInfo(false);\n  return 0;\n}\n\nTEST(SanitizerCommon, ThreadStackTlsMain) {\n  InitTlsSize();\n  TestThreadInfo(true);\n}\n\nTEST(SanitizerCommon, ThreadStackTlsWorker) {\n  InitTlsSize();\n  pthread_t t;\n  PTHREAD_CREATE(&t, 0, WorkerThread, 0);\n  PTHREAD_JOIN(t, 0);\n}\n\nbool UptrLess(uptr a, uptr b) {\n  return a < b;\n}\n\nTEST(SanitizerCommon, InternalBinarySearch) {\n  static const uptr kSize = 5;\n  uptr arr[kSize];\n  for (uptr i = 0; i < kSize; i++) arr[i] = i * i;\n\n  for (uptr i = 0; i < kSize; i++)\n    ASSERT_EQ(InternalBinarySearch(arr, 0, kSize, i * i, UptrLess), i);\n\n  ASSERT_EQ(InternalBinarySearch(arr, 0, kSize, 7, UptrLess), kSize + 1);\n}\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nTEST(SanitizerCommon, FindPathToBinary) {\n  char *true_path = FindPathToBinary(\"true\");\n  EXPECT_NE((char*)0, internal_strstr(true_path, \"/bin/true\"));\n  InternalFree(true_path);\n  EXPECT_EQ(0, FindPathToBinary(\"unexisting_binary.ergjeorj\"));\n}\n#endif\n\nTEST(SanitizerCommon, StripPathPrefix) {\n  EXPECT_EQ(0, StripPathPrefix(0, \"prefix\"));\n  EXPECT_STREQ(\"foo\", StripPathPrefix(\"foo\", 0));\n  EXPECT_STREQ(\"dir/file.cc\",\n               StripPathPrefix(\"/usr/lib/dir/file.cc\", \"/usr/lib/\"));\n  EXPECT_STREQ(\"/file.cc\", StripPathPrefix(\"/usr/myroot/file.cc\", \"/myroot\"));\n  EXPECT_STREQ(\"file.h\", StripPathPrefix(\"/usr/lib/./file.h\", \"/usr/lib/\"));\n}\n\nTEST(SanitizerCommon, InternalScopedString) {\n  InternalScopedString str(10);\n  EXPECT_EQ(0U, str.length());\n  EXPECT_STREQ(\"\", str.data());\n\n  str.append(\"foo\");\n  EXPECT_EQ(3U, str.length());\n  EXPECT_STREQ(\"foo\", str.data());\n\n  int x = 1234;\n  str.append(\"%d\", x);\n  EXPECT_EQ(7U, str.length());\n  EXPECT_STREQ(\"foo1234\", str.data());\n\n  str.append(\"%d\", x);\n  EXPECT_EQ(9U, str.length());\n  EXPECT_STREQ(\"foo123412\", str.data());\n\n  str.clear();\n  EXPECT_EQ(0U, str.length());\n  EXPECT_STREQ(\"\", str.data());\n\n  str.append(\"0123456789\");\n  EXPECT_EQ(9U, str.length());\n  EXPECT_STREQ(\"012345678\", str.data());\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc",
    "content": "//===-- sanitizer_deadlock_detector_test.cc -------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of Sanitizer runtime.\n// Tests for sanitizer_deadlock_detector.h\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_deadlock_detector.h\"\n\n#include \"sanitizer_test_utils.h\"\n\n#include \"gtest/gtest.h\"\n\n#include <algorithm>\n#include <vector>\n#include <set>\n\nusing namespace __sanitizer;\nusing namespace std;\n\ntypedef BasicBitVector<u8> BV1;\ntypedef BasicBitVector<> BV2;\ntypedef TwoLevelBitVector<> BV3;\ntypedef TwoLevelBitVector<3, BasicBitVector<u8> > BV4;\n\n// Poor man's unique_ptr.\ntemplate<class BV>\nstruct ScopedDD {\n  ScopedDD() {\n    dp = new DeadlockDetector<BV>;\n    dp->clear();\n    dtls.clear();\n  }\n  ~ScopedDD() { delete dp; }\n  DeadlockDetector<BV> *dp;\n  DeadlockDetectorTLS<BV> dtls;\n};\n\ntemplate <class BV>\nvoid RunBasicTest() {\n  uptr path[10];\n  ScopedDD<BV> sdd;\n  DeadlockDetector<BV> &d = *sdd.dp;\n  DeadlockDetectorTLS<BV> &dtls = sdd.dtls;\n  set<uptr> s;\n  for (size_t i = 0; i < d.size() * 3; i++) {\n    uptr node = d.newNode(0);\n    EXPECT_TRUE(s.insert(node).second);\n  }\n\n  d.clear();\n  s.clear();\n  // Add size() nodes.\n  for (size_t i = 0; i < d.size(); i++) {\n    uptr node = d.newNode(0);\n    EXPECT_TRUE(s.insert(node).second);\n  }\n  // Remove all nodes.\n  for (set<uptr>::iterator it = s.begin(); it != s.end(); ++it)\n    d.removeNode(*it);\n  // The nodes should be reused.\n  for (size_t i = 0; i < d.size(); i++) {\n    uptr node = d.newNode(0);\n    EXPECT_FALSE(s.insert(node).second);\n  }\n\n  // Cycle: n1->n2->n1\n  {\n    d.clear();\n    dtls.clear();\n    uptr n1 = d.newNode(1);\n    uptr n2 = d.newNode(2);\n    EXPECT_FALSE(d.onLock(&dtls, n1));\n    EXPECT_FALSE(d.onLock(&dtls, n2));\n    d.onUnlock(&dtls, n2);\n    d.onUnlock(&dtls, n1);\n\n    EXPECT_FALSE(d.onLock(&dtls, n2));\n    EXPECT_EQ(0U, d.findPathToLock(&dtls, n1, path, 1));\n    EXPECT_EQ(2U, d.findPathToLock(&dtls, n1, path, 10));\n    EXPECT_EQ(2U, d.findPathToLock(&dtls, n1, path, 2));\n    EXPECT_TRUE(d.onLock(&dtls, n1));\n    EXPECT_EQ(path[0], n1);\n    EXPECT_EQ(path[1], n2);\n    EXPECT_EQ(d.getData(n1), 1U);\n    EXPECT_EQ(d.getData(n2), 2U);\n    d.onUnlock(&dtls, n1);\n    d.onUnlock(&dtls, n2);\n  }\n\n  // Cycle: n1->n2->n3->n1\n  {\n    d.clear();\n    dtls.clear();\n    uptr n1 = d.newNode(1);\n    uptr n2 = d.newNode(2);\n    uptr n3 = d.newNode(3);\n\n    EXPECT_FALSE(d.onLock(&dtls, n1));\n    EXPECT_FALSE(d.onLock(&dtls, n2));\n    d.onUnlock(&dtls, n2);\n    d.onUnlock(&dtls, n1);\n\n    EXPECT_FALSE(d.onLock(&dtls, n2));\n    EXPECT_FALSE(d.onLock(&dtls, n3));\n    d.onUnlock(&dtls, n3);\n    d.onUnlock(&dtls, n2);\n\n    EXPECT_FALSE(d.onLock(&dtls, n3));\n    EXPECT_EQ(0U, d.findPathToLock(&dtls, n1, path, 2));\n    EXPECT_EQ(3U, d.findPathToLock(&dtls, n1, path, 10));\n    EXPECT_TRUE(d.onLock(&dtls, n1));\n    EXPECT_EQ(path[0], n1);\n    EXPECT_EQ(path[1], n2);\n    EXPECT_EQ(path[2], n3);\n    EXPECT_EQ(d.getData(n1), 1U);\n    EXPECT_EQ(d.getData(n2), 2U);\n    EXPECT_EQ(d.getData(n3), 3U);\n    d.onUnlock(&dtls, n1);\n    d.onUnlock(&dtls, n3);\n  }\n}\n\nTEST(DeadlockDetector, BasicTest) {\n  RunBasicTest<BV1>();\n  RunBasicTest<BV2>();\n  RunBasicTest<BV3>();\n  RunBasicTest<BV4>();\n}\n\ntemplate <class BV>\nvoid RunRemoveNodeTest() {\n  ScopedDD<BV> sdd;\n  DeadlockDetector<BV> &d = *sdd.dp;\n  DeadlockDetectorTLS<BV> &dtls = sdd.dtls;\n\n  uptr l0 = d.newNode(0);\n  uptr l1 = d.newNode(1);\n  uptr l2 = d.newNode(2);\n  uptr l3 = d.newNode(3);\n  uptr l4 = d.newNode(4);\n  uptr l5 = d.newNode(5);\n\n  // l0=>l1=>l2\n  d.onLock(&dtls, l0);\n  d.onLock(&dtls, l1);\n  d.onLock(&dtls, l2);\n  d.onUnlock(&dtls, l1);\n  d.onUnlock(&dtls, l0);\n  d.onUnlock(&dtls, l2);\n  // l3=>l4=>l5\n  d.onLock(&dtls, l3);\n  d.onLock(&dtls, l4);\n  d.onLock(&dtls, l5);\n  d.onUnlock(&dtls, l4);\n  d.onUnlock(&dtls, l3);\n  d.onUnlock(&dtls, l5);\n\n  set<uptr> locks;\n  locks.insert(l0);\n  locks.insert(l1);\n  locks.insert(l2);\n  locks.insert(l3);\n  locks.insert(l4);\n  locks.insert(l5);\n  for (uptr i = 6; i < d.size(); i++) {\n    uptr lt = d.newNode(i);\n    locks.insert(lt);\n    d.onLock(&dtls, lt);\n    d.onUnlock(&dtls, lt);\n    d.removeNode(lt);\n  }\n  EXPECT_EQ(locks.size(), d.size());\n  // l2=>l0\n  EXPECT_FALSE(d.onLock(&dtls, l2));\n  EXPECT_TRUE(d.onLock(&dtls, l0));\n  d.onUnlock(&dtls, l2);\n  d.onUnlock(&dtls, l0);\n  // l4=>l3\n  EXPECT_FALSE(d.onLock(&dtls, l4));\n  EXPECT_TRUE(d.onLock(&dtls, l3));\n  d.onUnlock(&dtls, l4);\n  d.onUnlock(&dtls, l3);\n\n  EXPECT_EQ(d.size(), d.testOnlyGetEpoch());\n\n  d.removeNode(l2);\n  d.removeNode(l3);\n  locks.clear();\n  // make sure no edges from or to l0,l1,l4,l5 left.\n  for (uptr i = 4; i < d.size(); i++) {\n    uptr lt = d.newNode(i);\n    locks.insert(lt);\n    uptr a, b;\n    // l0 => lt?\n    a = l0; b = lt;\n    EXPECT_FALSE(d.onLock(&dtls, a));\n    EXPECT_FALSE(d.onLock(&dtls, b));\n    d.onUnlock(&dtls, a);\n    d.onUnlock(&dtls, b);\n    // l1 => lt?\n    a = l1; b = lt;\n    EXPECT_FALSE(d.onLock(&dtls, a));\n    EXPECT_FALSE(d.onLock(&dtls, b));\n    d.onUnlock(&dtls, a);\n    d.onUnlock(&dtls, b);\n    // lt => l4?\n    a = lt; b = l4;\n    EXPECT_FALSE(d.onLock(&dtls, a));\n    EXPECT_FALSE(d.onLock(&dtls, b));\n    d.onUnlock(&dtls, a);\n    d.onUnlock(&dtls, b);\n    // lt => l5?\n    a = lt; b = l5;\n    EXPECT_FALSE(d.onLock(&dtls, a));\n    EXPECT_FALSE(d.onLock(&dtls, b));\n    d.onUnlock(&dtls, a);\n    d.onUnlock(&dtls, b);\n\n    d.removeNode(lt);\n  }\n  // Still the same epoch.\n  EXPECT_EQ(d.size(), d.testOnlyGetEpoch());\n  EXPECT_EQ(locks.size(), d.size() - 4);\n  // l2 and l3 should have ben reused.\n  EXPECT_EQ(locks.count(l2), 1U);\n  EXPECT_EQ(locks.count(l3), 1U);\n}\n\nTEST(DeadlockDetector, RemoveNodeTest) {\n  RunRemoveNodeTest<BV1>();\n  RunRemoveNodeTest<BV2>();\n  RunRemoveNodeTest<BV3>();\n  RunRemoveNodeTest<BV4>();\n}\n\ntemplate <class BV>\nvoid RunMultipleEpochsTest() {\n  ScopedDD<BV> sdd;\n  DeadlockDetector<BV> &d = *sdd.dp;\n  DeadlockDetectorTLS<BV> &dtls = sdd.dtls;\n\n  set<uptr> locks;\n  for (uptr i = 0; i < d.size(); i++) {\n    EXPECT_TRUE(locks.insert(d.newNode(i)).second);\n  }\n  EXPECT_EQ(d.testOnlyGetEpoch(), d.size());\n  for (uptr i = 0; i < d.size(); i++) {\n    EXPECT_TRUE(locks.insert(d.newNode(i)).second);\n    EXPECT_EQ(d.testOnlyGetEpoch(), d.size() * 2);\n  }\n  locks.clear();\n\n  uptr l0 = d.newNode(0);\n  uptr l1 = d.newNode(0);\n  d.onLock(&dtls, l0);\n  d.onLock(&dtls, l1);\n  d.onUnlock(&dtls, l0);\n  EXPECT_EQ(d.testOnlyGetEpoch(), 3 * d.size());\n  for (uptr i = 0; i < d.size(); i++) {\n    EXPECT_TRUE(locks.insert(d.newNode(i)).second);\n  }\n  EXPECT_EQ(d.testOnlyGetEpoch(), 4 * d.size());\n\n#if !SANITIZER_DEBUG\n  // EXPECT_DEATH clones a thread with 4K stack,\n  // which is overflown by tsan memory accesses functions in debug mode.\n\n  // Can not handle the locks from the previous epoch.\n  // The caller should update the lock id.\n  EXPECT_DEATH(d.onLock(&dtls, l0), \"CHECK failed.*current_epoch_\");\n#endif\n}\n\nTEST(DeadlockDetector, MultipleEpochsTest) {\n  RunMultipleEpochsTest<BV1>();\n  RunMultipleEpochsTest<BV2>();\n  RunMultipleEpochsTest<BV3>();\n  RunMultipleEpochsTest<BV4>();\n}\n\ntemplate <class BV>\nvoid RunCorrectEpochFlush() {\n  ScopedDD<BV> sdd;\n  DeadlockDetector<BV> &d = *sdd.dp;\n  DeadlockDetectorTLS<BV> &dtls = sdd.dtls;\n  vector<uptr> locks1;\n  for (uptr i = 0; i < d.size(); i++)\n    locks1.push_back(d.newNode(i));\n  EXPECT_EQ(d.testOnlyGetEpoch(), d.size());\n  d.onLock(&dtls, locks1[3]);\n  d.onLock(&dtls, locks1[4]);\n  d.onLock(&dtls, locks1[5]);\n\n  // We have a new epoch, old locks in dtls will have to be forgotten.\n  uptr l0 = d.newNode(0);\n  EXPECT_EQ(d.testOnlyGetEpoch(), d.size() * 2);\n  uptr l1 = d.newNode(0);\n  EXPECT_EQ(d.testOnlyGetEpoch(), d.size() * 2);\n  d.onLock(&dtls, l0);\n  d.onLock(&dtls, l1);\n  EXPECT_TRUE(d.testOnlyHasEdgeRaw(0, 1));\n  EXPECT_FALSE(d.testOnlyHasEdgeRaw(1, 0));\n  EXPECT_FALSE(d.testOnlyHasEdgeRaw(3, 0));\n  EXPECT_FALSE(d.testOnlyHasEdgeRaw(4, 0));\n  EXPECT_FALSE(d.testOnlyHasEdgeRaw(5, 0));\n}\n\nTEST(DeadlockDetector, CorrectEpochFlush) {\n  RunCorrectEpochFlush<BV1>();\n  RunCorrectEpochFlush<BV2>();\n}\n\ntemplate <class BV>\nvoid RunTryLockTest() {\n  ScopedDD<BV> sdd;\n  DeadlockDetector<BV> &d = *sdd.dp;\n  DeadlockDetectorTLS<BV> &dtls = sdd.dtls;\n\n  uptr l0 = d.newNode(0);\n  uptr l1 = d.newNode(0);\n  uptr l2 = d.newNode(0);\n  EXPECT_FALSE(d.onLock(&dtls, l0));\n  EXPECT_FALSE(d.onTryLock(&dtls, l1));\n  EXPECT_FALSE(d.onLock(&dtls, l2));\n  EXPECT_TRUE(d.isHeld(&dtls, l0));\n  EXPECT_TRUE(d.isHeld(&dtls, l1));\n  EXPECT_TRUE(d.isHeld(&dtls, l2));\n  EXPECT_FALSE(d.testOnlyHasEdge(l0, l1));\n  EXPECT_TRUE(d.testOnlyHasEdge(l1, l2));\n  d.onUnlock(&dtls, l0);\n  d.onUnlock(&dtls, l1);\n  d.onUnlock(&dtls, l2);\n}\n\nTEST(DeadlockDetector, TryLockTest) {\n  RunTryLockTest<BV1>();\n  RunTryLockTest<BV2>();\n}\n\ntemplate <class BV>\nvoid RunOnFirstLockTest() {\n  ScopedDD<BV> sdd;\n  DeadlockDetector<BV> &d = *sdd.dp;\n  DeadlockDetectorTLS<BV> &dtls = sdd.dtls;\n\n  uptr l0 = d.newNode(0);\n  uptr l1 = d.newNode(0);\n  EXPECT_FALSE(d.onFirstLock(&dtls, l0));  // dtls has old epoch.\n  d.onLock(&dtls, l0);\n  d.onUnlock(&dtls, l0);\n\n  EXPECT_TRUE(d.onFirstLock(&dtls, l0));  // Ok, same ecpoch, first lock.\n  EXPECT_FALSE(d.onFirstLock(&dtls, l1));  // Second lock.\n  d.onLock(&dtls, l1);\n  d.onUnlock(&dtls, l1);\n  d.onUnlock(&dtls, l0);\n\n  EXPECT_TRUE(d.onFirstLock(&dtls, l0));  // Ok\n  d.onUnlock(&dtls, l0);\n\n  vector<uptr> locks1;\n  for (uptr i = 0; i < d.size(); i++)\n    locks1.push_back(d.newNode(i));\n\n  EXPECT_TRUE(d.onFirstLock(&dtls, l0));  // Epoch has changed, but not in dtls.\n\n  uptr l3 = d.newNode(0);\n  d.onLock(&dtls, l3);\n  d.onUnlock(&dtls, l3);\n\n  EXPECT_FALSE(d.onFirstLock(&dtls, l0));  // Epoch has changed in dtls.\n}\n\nTEST(DeadlockDetector, onFirstLockTest) {\n  RunOnFirstLockTest<BV2>();\n}\n\ntemplate <class BV>\nvoid RunRecusriveLockTest() {\n  ScopedDD<BV> sdd;\n  DeadlockDetector<BV> &d = *sdd.dp;\n  DeadlockDetectorTLS<BV> &dtls = sdd.dtls;\n\n  uptr l0 = d.newNode(0);\n  uptr l1 = d.newNode(0);\n  uptr l2 = d.newNode(0);\n  uptr l3 = d.newNode(0);\n\n  EXPECT_FALSE(d.onLock(&dtls, l0));\n  EXPECT_FALSE(d.onLock(&dtls, l1));\n  EXPECT_FALSE(d.onLock(&dtls, l0));  // Recurisve.\n  EXPECT_FALSE(d.onLock(&dtls, l2));\n  d.onUnlock(&dtls, l0);\n  EXPECT_FALSE(d.onLock(&dtls, l3));\n  d.onUnlock(&dtls, l0);\n  d.onUnlock(&dtls, l1);\n  d.onUnlock(&dtls, l2);\n  d.onUnlock(&dtls, l3);\n  EXPECT_TRUE(d.testOnlyHasEdge(l0, l1));\n  EXPECT_TRUE(d.testOnlyHasEdge(l0, l2));\n  EXPECT_TRUE(d.testOnlyHasEdge(l0, l3));\n}\n\nTEST(DeadlockDetector, RecusriveLockTest) {\n  RunRecusriveLockTest<BV2>();\n}\n\ntemplate <class BV>\nvoid RunLockContextTest() {\n  ScopedDD<BV> sdd;\n  DeadlockDetector<BV> &d = *sdd.dp;\n  DeadlockDetectorTLS<BV> &dtls = sdd.dtls;\n\n  uptr l0 = d.newNode(0);\n  uptr l1 = d.newNode(0);\n  uptr l2 = d.newNode(0);\n  uptr l3 = d.newNode(0);\n  uptr l4 = d.newNode(0);\n  EXPECT_FALSE(d.onLock(&dtls, l0, 10));\n  EXPECT_FALSE(d.onLock(&dtls, l1, 11));\n  EXPECT_FALSE(d.onLock(&dtls, l2, 12));\n  EXPECT_FALSE(d.onLock(&dtls, l3, 13));\n  EXPECT_EQ(10U, d.findLockContext(&dtls, l0));\n  EXPECT_EQ(11U, d.findLockContext(&dtls, l1));\n  EXPECT_EQ(12U, d.findLockContext(&dtls, l2));\n  EXPECT_EQ(13U, d.findLockContext(&dtls, l3));\n  d.onUnlock(&dtls, l0);\n  EXPECT_EQ(0U, d.findLockContext(&dtls, l0));\n  EXPECT_EQ(11U, d.findLockContext(&dtls, l1));\n  EXPECT_EQ(12U, d.findLockContext(&dtls, l2));\n  EXPECT_EQ(13U, d.findLockContext(&dtls, l3));\n  d.onUnlock(&dtls, l2);\n  EXPECT_EQ(0U, d.findLockContext(&dtls, l0));\n  EXPECT_EQ(11U, d.findLockContext(&dtls, l1));\n  EXPECT_EQ(0U, d.findLockContext(&dtls, l2));\n  EXPECT_EQ(13U, d.findLockContext(&dtls, l3));\n\n  EXPECT_FALSE(d.onLock(&dtls, l4, 14));\n  EXPECT_EQ(14U, d.findLockContext(&dtls, l4));\n}\n\nTEST(DeadlockDetector, LockContextTest) {\n  RunLockContextTest<BV2>();\n}\n\ntemplate <class BV>\nvoid RunRemoveEdgesTest() {\n  ScopedDD<BV> sdd;\n  DeadlockDetector<BV> &d = *sdd.dp;\n  DeadlockDetectorTLS<BV> &dtls = sdd.dtls;\n  vector<uptr> node(BV::kSize);\n  u32 stk_from = 0, stk_to = 0;\n  int unique_tid = 0;\n  for (size_t i = 0; i < BV::kSize; i++)\n    node[i] = d.newNode(0);\n\n  for (size_t i = 0; i < BV::kSize; i++)\n    EXPECT_FALSE(d.onLock(&dtls, node[i], i + 1));\n  for (size_t i = 0; i < BV::kSize; i++) {\n    for (uptr j = i + 1; j < BV::kSize; j++) {\n      EXPECT_TRUE(\n          d.findEdge(node[i], node[j], &stk_from, &stk_to, &unique_tid));\n      EXPECT_EQ(stk_from, i + 1);\n      EXPECT_EQ(stk_to, j + 1);\n    }\n  }\n  EXPECT_EQ(d.testOnlyGetEpoch(), d.size());\n  // Remove and re-create half of the nodes.\n  for (uptr i = 1; i < BV::kSize; i += 2)\n    d.removeNode(node[i]);\n  for (uptr i = 1; i < BV::kSize; i += 2)\n    node[i] = d.newNode(0);\n  EXPECT_EQ(d.testOnlyGetEpoch(), d.size());\n  // The edges from or to the removed nodes should be gone.\n  for (size_t i = 0; i < BV::kSize; i++) {\n    for (uptr j = i + 1; j < BV::kSize; j++) {\n      if ((i % 2) || (j % 2))\n        EXPECT_FALSE(\n            d.findEdge(node[i], node[j], &stk_from, &stk_to, &unique_tid));\n      else\n        EXPECT_TRUE(\n            d.findEdge(node[i], node[j], &stk_from, &stk_to, &unique_tid));\n    }\n  }\n}\n\nTEST(DeadlockDetector, RemoveEdgesTest) {\n  RunRemoveEdgesTest<BV1>();\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_flags_test.cc",
    "content": "//===-- sanitizer_flags_test.cc -------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_flag_parser.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_allocator_internal.h\"\n#include \"gtest/gtest.h\"\n\n#include <string.h>\n\nnamespace __sanitizer {\n\nstatic const char kFlagName[] = \"flag_name\";\nstatic const char kFlagDesc[] = \"flag description\";\n\ntemplate <typename T>\nstatic void TestFlag(T start_value, const char *env, T final_value) {\n  T flag = start_value;\n\n  FlagParser parser;\n  RegisterFlag(&parser, kFlagName, kFlagDesc, &flag);\n\n  parser.ParseString(env);\n\n  EXPECT_EQ(final_value, flag);\n}\n\ntemplate <>\nvoid TestFlag(const char *start_value, const char *env,\n                     const char *final_value) {\n  const char *flag = start_value;\n\n  FlagParser parser;\n  RegisterFlag(&parser, kFlagName, kFlagDesc, &flag);\n\n  parser.ParseString(env);\n\n  EXPECT_EQ(0, internal_strcmp(final_value, flag));\n}\n\nTEST(SanitizerCommon, BooleanFlags) {\n  TestFlag(false, \"flag_name=1\", true);\n  TestFlag(false, \"flag_name=yes\", true);\n  TestFlag(false, \"flag_name=true\", true);\n  TestFlag(true, \"flag_name=0\", false);\n  TestFlag(true, \"flag_name=no\", false);\n  TestFlag(true, \"flag_name=false\", false);\n}\n\nTEST(SanitizerCommon, IntFlags) {\n  TestFlag(-11, 0, -11);\n  TestFlag(-11, \"flag_name=0\", 0);\n  TestFlag(-11, \"flag_name=42\", 42);\n  TestFlag(-11, \"flag_name=-42\", -42);\n\n  // Unrecognized flags are ignored.\n  TestFlag(-11, \"--flag_name=42\", -11);\n  TestFlag(-11, \"zzzzzzz=42\", -11);\n\n  EXPECT_DEATH(TestFlag(-11, \"flag_name\", 0), \"expected '='\");\n  EXPECT_DEATH(TestFlag(-11, \"flag_name=42U\", 0),\n               \"Invalid value for int option\");\n}\n\nTEST(SanitizerCommon, StrFlags) {\n  TestFlag(\"zzz\", 0, \"zzz\");\n  TestFlag(\"zzz\", \"flag_name=\", \"\");\n  TestFlag(\"zzz\", \"flag_name=abc\", \"abc\");\n  TestFlag(\"\", \"flag_name=abc\", \"abc\");\n  TestFlag(\"\", \"flag_name='abc zxc'\", \"abc zxc\");\n  // TestStrFlag(\"\", \"flag_name=\\\"abc qwe\\\" asd\", \"abc qwe\");\n}\n\nstatic void TestTwoFlags(const char *env, bool expected_flag1,\n                         const char *expected_flag2,\n                         const char *name1 = \"flag1\",\n                         const char *name2 = \"flag2\") {\n  bool flag1 = !expected_flag1;\n  const char *flag2 = \"\";\n\n  FlagParser parser;\n  RegisterFlag(&parser, name1, kFlagDesc, &flag1);\n  RegisterFlag(&parser, name2, kFlagDesc, &flag2);\n\n  parser.ParseString(env);\n\n  EXPECT_EQ(expected_flag1, flag1);\n  EXPECT_EQ(0, internal_strcmp(flag2, expected_flag2));\n}\n\nTEST(SanitizerCommon, MultipleFlags) {\n  TestTwoFlags(\"flag1=1 flag2='zzz'\", true, \"zzz\");\n  TestTwoFlags(\"flag2='qxx' flag1=0\", false, \"qxx\");\n  TestTwoFlags(\"flag1=false:flag2='zzz'\", false, \"zzz\");\n  TestTwoFlags(\"flag2=qxx:flag1=yes\", true, \"qxx\");\n  TestTwoFlags(\"flag2=qxx\\nflag1=yes\", true, \"qxx\");\n  TestTwoFlags(\"flag2=qxx\\r\\nflag1=yes\", true, \"qxx\");\n  TestTwoFlags(\"flag2=qxx\\tflag1=yes\", true, \"qxx\");\n}\n\nTEST(SanitizerCommon, CommonSuffixFlags) {\n  TestTwoFlags(\"flag=1 other_flag='zzz'\", true, \"zzz\", \"flag\", \"other_flag\");\n  TestTwoFlags(\"other_flag='zzz' flag=1\", true, \"zzz\", \"flag\", \"other_flag\");\n  TestTwoFlags(\"other_flag=' flag=0 ' flag=1\", true, \" flag=0 \", \"flag\",\n               \"other_flag\");\n  TestTwoFlags(\"flag=1 other_flag=' flag=0 '\", true, \" flag=0 \", \"flag\",\n               \"other_flag\");\n}\n\nTEST(SanitizerCommon, CommonFlags) {\n  CommonFlags cf;\n  FlagParser parser;\n  RegisterCommonFlags(&parser, &cf);\n\n  cf.SetDefaults();\n  EXPECT_TRUE(cf.symbolize);\n  EXPECT_STREQ(\".\", cf.coverage_dir);\n\n  cf.symbolize = false;\n  cf.coverage = true;\n  cf.coverage_direct = true;\n  cf.log_path = \"path/one\";\n\n  parser.ParseString(\"symbolize=1:coverage_direct=false log_path='path/two'\");\n  EXPECT_TRUE(cf.symbolize);\n  EXPECT_TRUE(cf.coverage);\n  EXPECT_FALSE(cf.coverage_direct);\n  EXPECT_STREQ(\"path/two\", cf.log_path);\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc",
    "content": "//===-- sanitizer_format_interceptor_test.cc ------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Tests for *scanf interceptors implementation in sanitizer_common.\n//\n//===----------------------------------------------------------------------===//\n#include <algorithm>\n#include <vector>\n\n#include \"interception/interception.h\"\n#include \"sanitizer_test_utils.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"gtest/gtest.h\"\n\nusing namespace __sanitizer;\n\n#define COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size)                    \\\n  do {                                                                         \\\n    ((std::vector<unsigned> *)ctx)->push_back(size);                           \\\n    ptr = ptr;                                                                 \\\n  } while (0)\n\n#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size)                          \\\n  COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size)\n\n#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size)                         \\\n  COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size)\n\n#define SANITIZER_INTERCEPT_PRINTF 1\n#include \"sanitizer_common/sanitizer_common_interceptors_format.inc\"\n\nstatic const unsigned I = sizeof(int);\nstatic const unsigned L = sizeof(long);\nstatic const unsigned LL = sizeof(long long);\nstatic const unsigned S = sizeof(short);\nstatic const unsigned C = sizeof(char);\nstatic const unsigned LC = sizeof(wchar_t);\nstatic const unsigned D = sizeof(double);\nstatic const unsigned LD = sizeof(long double);\nstatic const unsigned F = sizeof(float);\nstatic const unsigned P = sizeof(char *);\n\nstatic void verifyFormatResults(const char *format, unsigned n,\n                                const std::vector<unsigned> &computed_sizes,\n                                va_list expected_sizes) {\n  // \"+ 1\" because of format string\n  ASSERT_EQ(n + 1,\n            computed_sizes.size()) << \"Unexpected number of format arguments: '\"\n                                   << format << \"'\";\n  for (unsigned i = 0; i < n; ++i)\n    EXPECT_EQ(va_arg(expected_sizes, unsigned), computed_sizes[i + 1])\n        << \"Unexpect write size for argument \" << i << \", format string '\"\n        << format << \"'\";\n}\n\nstatic const char test_buf[] = \"Test string.\";\nstatic const size_t test_buf_size = sizeof(test_buf);\n\nstatic const unsigned SCANF_ARGS_MAX = 16;\n\nstatic void testScanf3(void *ctx, int result, bool allowGnuMalloc,\n                       const char *format, ...) {\n  va_list ap;\n  va_start(ap, format);\n  scanf_common(ctx, result, allowGnuMalloc, format, ap);\n  va_end(ap);\n}\n\nstatic void testScanf2(const char *format, int scanf_result,\n                       bool allowGnuMalloc, unsigned n,\n                       va_list expected_sizes) {\n  std::vector<unsigned> scanf_sizes;\n  // 16 args should be enough.\n  testScanf3((void *)&scanf_sizes, scanf_result, allowGnuMalloc, format,\n             test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,\n             test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,\n             test_buf, test_buf, test_buf, test_buf);\n  verifyFormatResults(format, n, scanf_sizes, expected_sizes);\n}\n\nstatic void testScanf(const char *format, unsigned n, ...) {\n  va_list ap;\n  va_start(ap, n);\n  testScanf2(format, SCANF_ARGS_MAX, /* allowGnuMalloc */ true, n, ap);\n  va_end(ap);\n}\n\nstatic void testScanfPartial(const char *format, int scanf_result, unsigned n,\n                             ...) {\n  va_list ap;\n  va_start(ap, n);\n  testScanf2(format, scanf_result, /* allowGnuMalloc */ true,  n, ap);\n  va_end(ap);\n}\n\nstatic void testScanfNoGnuMalloc(const char *format, unsigned n, ...) {\n  va_list ap;\n  va_start(ap, n);\n  testScanf2(format, SCANF_ARGS_MAX, /* allowGnuMalloc */ false, n, ap);\n  va_end(ap);\n}\n\nTEST(SanitizerCommonInterceptors, Scanf) {\n  testScanf(\"%d\", 1, I);\n  testScanf(\"%d%d%d\", 3, I, I, I);\n  testScanf(\"ab%u%dc\", 2, I, I);\n  testScanf(\"%ld\", 1, L);\n  testScanf(\"%llu\", 1, LL);\n  testScanf(\"%qd\", 1, LL);\n  testScanf(\"a %hd%hhx\", 2, S, C);\n  testScanf(\"%c\", 1, C);\n  testScanf(\"%lc\", 1, LC);\n\n  testScanf(\"%%\", 0);\n  testScanf(\"a%%\", 0);\n  testScanf(\"a%%b\", 0);\n  testScanf(\"a%%%%b\", 0);\n  testScanf(\"a%%b%%\", 0);\n  testScanf(\"a%%%%%%b\", 0);\n  testScanf(\"a%%%%%b\", 0);\n  testScanf(\"a%%%%%f\", 1, F);\n  testScanf(\"a%%%lxb\", 1, L);\n  testScanf(\"a%lf%%%lxb\", 2, D, L);\n  testScanf(\"%nf\", 1, I);\n\n  testScanf(\"%10s\", 1, 11);\n  testScanf(\"%10c\", 1, 10);\n  testScanf(\"%10ls\", 1, 11 * LC);\n  testScanf(\"%10lc\", 1, 10 * LC);\n  testScanf(\"%%10s\", 0);\n  testScanf(\"%*10s\", 0);\n  testScanf(\"%*d\", 0);\n\n  testScanf(\"%4d%8f%c\", 3, I, F, C);\n  testScanf(\"%s%d\", 2, test_buf_size, I);\n  testScanf(\"%[abc]\", 1, test_buf_size);\n  testScanf(\"%4[bcdef]\", 1, 5);\n  testScanf(\"%[]]\", 1, test_buf_size);\n  testScanf(\"%8[^]%d0-9-]%c\", 2, 9, C);\n\n  testScanf(\"%*[^:]%n:%d:%1[ ]%n\", 4, I, I, 2, I);\n\n  testScanf(\"%*d%u\", 1, I);\n\n  testScanf(\"%c%d\", 2, C, I);\n  testScanf(\"%A%lf\", 2, F, D);\n\n  testScanf(\"%ms %Lf\", 2, P, LD);\n  testScanf(\"s%Las\", 1, LD);\n  testScanf(\"%ar\", 1, F);\n\n  // In the cases with std::min below the format spec can be interpreted as\n  // either floating-something, or (GNU extension) callee-allocated string.\n  // Our conservative implementation reports one of the two possibilities with\n  // the least store range.\n  testScanf(\"%a[\", 0);\n  testScanf(\"%a[]\", 0);\n  testScanf(\"%a[]]\", 1, std::min(F, P));\n  testScanf(\"%a[abc]\", 1, std::min(F, P));\n  testScanf(\"%a[^abc]\", 1, std::min(F, P));\n  testScanf(\"%a[ab%c] %d\", 0);\n  testScanf(\"%a[^ab%c] %d\", 0);\n  testScanf(\"%as\", 1, std::min(F, P));\n  testScanf(\"%aS\", 1, std::min(F, P));\n  testScanf(\"%a13S\", 1, std::min(F, P));\n  testScanf(\"%alS\", 1, std::min(F, P));\n\n  testScanfNoGnuMalloc(\"s%Las\", 1, LD);\n  testScanfNoGnuMalloc(\"%ar\", 1, F);\n  testScanfNoGnuMalloc(\"%a[\", 1, F);\n  testScanfNoGnuMalloc(\"%a[]\", 1, F);\n  testScanfNoGnuMalloc(\"%a[]]\", 1, F);\n  testScanfNoGnuMalloc(\"%a[abc]\", 1, F);\n  testScanfNoGnuMalloc(\"%a[^abc]\", 1, F);\n  testScanfNoGnuMalloc(\"%a[ab%c] %d\", 3, F, C, I);\n  testScanfNoGnuMalloc(\"%a[^ab%c] %d\", 3, F, C, I);\n  testScanfNoGnuMalloc(\"%as\", 1, F);\n  testScanfNoGnuMalloc(\"%aS\", 1, F);\n  testScanfNoGnuMalloc(\"%a13S\", 1, F);\n  testScanfNoGnuMalloc(\"%alS\", 1, F);\n\n  testScanf(\"%5$d\", 0);\n  testScanf(\"%md\", 0);\n  testScanf(\"%m10s\", 0);\n\n  testScanfPartial(\"%d%d%d%d //1\\n\", 1, 1, I);\n  testScanfPartial(\"%d%d%d%d //2\\n\", 2, 2, I, I);\n  testScanfPartial(\"%d%d%d%d //3\\n\", 3, 3, I, I, I);\n  testScanfPartial(\"%d%d%d%d //4\\n\", 4, 4, I, I, I, I);\n\n  testScanfPartial(\"%d%n%n%d //1\\n\", 1, 3, I, I, I);\n  testScanfPartial(\"%d%n%n%d //2\\n\", 2, 4, I, I, I, I);\n\n  testScanfPartial(\"%d%n%n%d %s %s\", 3, 5, I, I, I, I, test_buf_size);\n  testScanfPartial(\"%d%n%n%d %s %s\", 4, 6, I, I, I, I, test_buf_size,\n                   test_buf_size);\n}\n\nstatic void testPrintf3(void *ctx, const char *format, ...) {\n  va_list ap;\n  va_start(ap, format);\n  printf_common(ctx, format, ap);\n  va_end(ap);\n}\n\nstatic void testPrintf2(const char *format, unsigned n,\n                       va_list expected_sizes) {\n  std::vector<unsigned> printf_sizes;\n  // 16 args should be enough.\n  testPrintf3((void *)&printf_sizes, format,\n             test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,\n             test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,\n             test_buf, test_buf, test_buf, test_buf);\n  verifyFormatResults(format, n, printf_sizes, expected_sizes);\n}\n\nstatic void testPrintf(const char *format, unsigned n, ...) {\n  va_list ap;\n  va_start(ap, n);\n  testPrintf2(format, n, ap);\n  va_end(ap);\n}\n\nTEST(SanitizerCommonInterceptors, Printf) {\n  // Only test functionality which differs from scanf\n\n  // Indexed arguments\n  testPrintf(\"%5$d\", 0);\n  testPrintf(\"%.*5$d\", 0);\n\n  // errno\n  testPrintf(\"%0-m\", 0);\n\n  // Dynamic width\n  testPrintf(\"%*n\", 1, I);\n  testPrintf(\"%*.10n\", 1, I);\n\n  // Precision\n  testPrintf(\"%10.10n\", 1, I);\n  testPrintf(\"%.3s\", 1, 3);\n  testPrintf(\"%.20s\", 1, test_buf_size);\n\n  // Dynamic precision\n  testPrintf(\"%.*n\", 1, I);\n  testPrintf(\"%10.*n\", 1, I);\n\n  // Dynamic precision for strings is not implemented yet.\n  testPrintf(\"%.*s\", 1, 0);\n\n  // Checks for wide-character strings are not implemented yet.\n  testPrintf(\"%ls\", 1, 0);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_ioctl_test.cc",
    "content": "//===-- sanitizer_ioctl_test.cc -------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Tests for ioctl interceptor implementation in sanitizer_common.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_LINUX\n\n#include <linux/input.h>\n#include <vector>\n\n#include \"interception/interception.h\"\n#include \"sanitizer_test_utils.h\"\n#include \"sanitizer_common/sanitizer_platform_limits_posix.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"gtest/gtest.h\"\n\n\nusing namespace __sanitizer;\n\n#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, sz) \\\n  do {                                              \\\n    (void) ctx;                                     \\\n    (void) ptr;                                     \\\n    (void) sz;                                      \\\n  } while (0)\n#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sz) \\\n  do {                                               \\\n    (void) ctx;                                      \\\n    (void) ptr;                                      \\\n    (void) sz;                                       \\\n  } while (0)\n\n#include \"sanitizer_common/sanitizer_common_interceptors_ioctl.inc\"\n\nstatic struct IoctlInit {\n  IoctlInit() {\n    ioctl_init();\n    // Avoid unused function warnings.\n    (void)&ioctl_common_pre;\n    (void)&ioctl_common_post;\n    (void)&ioctl_decode;\n  }\n} ioctl_static_initializer;\n\nTEST(SanitizerIoctl, Fixup) {\n  EXPECT_EQ((unsigned)FIONBIO, ioctl_request_fixup(FIONBIO));\n\n  EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(0, 16)));\n  EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(1, 16)));\n  EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(1, 17)));\n  EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(31, 16)));\n  EXPECT_NE(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(32, 16)));\n\n  EXPECT_EQ(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(0)));\n  EXPECT_EQ(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(5)));\n  EXPECT_EQ(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(63)));\n  EXPECT_NE(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(64)));\n\n  EXPECT_EQ(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(0)));\n  EXPECT_EQ(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(5)));\n  EXPECT_EQ(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(63)));\n  EXPECT_NE(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(64)));\n\n  const ioctl_desc *desc = ioctl_lookup(EVIOCGKEY(16));\n  EXPECT_NE((void *)0, desc);\n  EXPECT_EQ(EVIOCGKEY(0), desc->req);\n}\n\n// Test decoding KVM ioctl numbers.\nTEST(SanitizerIoctl, KVM_GET_MP_STATE) {\n  ioctl_desc desc;\n  bool res = ioctl_decode(0x8004ae98U, &desc);\n  EXPECT_TRUE(res);\n  EXPECT_EQ(ioctl_desc::WRITE, desc.type);\n  EXPECT_EQ(4U, desc.size);\n}\n\nTEST(SanitizerIoctl, KVM_GET_LAPIC) {\n  ioctl_desc desc;\n  bool res = ioctl_decode(0x8400ae8eU, &desc);\n  EXPECT_TRUE(res);\n  EXPECT_EQ(ioctl_desc::WRITE, desc.type);\n  EXPECT_EQ(1024U, desc.size);\n}\n\nTEST(SanitizerIoctl, KVM_GET_MSR_INDEX_LIST) {\n  ioctl_desc desc;\n  bool res = ioctl_decode(0xc004ae02U, &desc);\n  EXPECT_TRUE(res);\n  EXPECT_EQ(ioctl_desc::READWRITE, desc.type);\n  EXPECT_EQ(4U, desc.size);\n}\n\n#endif // SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc",
    "content": "//===-- sanitizer_libc_test.cc --------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Tests for sanitizer_libc.h.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_platform.h\"\n#include \"gtest/gtest.h\"\n\n#if SANITIZER_LINUX || SANITIZER_MAC\n# define SANITIZER_TEST_HAS_STAT_H 1\n# include <sys/stat.h>\n# include \"sanitizer_common/sanitizer_posix.h\"\n#else\n# define SANITIZER_TEST_HAS_STAT_H 0\n#endif\n\n// A regression test for internal_memmove() implementation.\nTEST(SanitizerCommon, InternalMemmoveRegression) {\n  char src[] = \"Hello World\";\n  char *dest = src + 6;\n  __sanitizer::internal_memmove(dest, src, 5);\n  EXPECT_EQ(dest[0], src[0]);\n  EXPECT_EQ(dest[4], src[4]);\n}\n\nTEST(SanitizerCommon, mem_is_zero) {\n  size_t size = 128;\n  char *x = new char[size];\n  memset(x, 0, size);\n  for (size_t pos = 0; pos < size; pos++) {\n    x[pos] = 1;\n    for (size_t beg = 0; beg < size; beg++) {\n      for (size_t end = beg; end < size; end++) {\n        // fprintf(stderr, \"pos %zd beg %zd end %zd \\n\", pos, beg, end);\n        if (beg <= pos && pos < end)\n          EXPECT_FALSE(__sanitizer::mem_is_zero(x + beg, end - beg));\n        else\n          EXPECT_TRUE(__sanitizer::mem_is_zero(x + beg, end - beg));\n      }\n    }\n    x[pos] = 0;\n  }\n  delete [] x;\n}\n\nstruct stat_and_more {\n  struct stat st;\n  unsigned char z;\n};\n\nstatic void temp_file_name(char *buf, size_t bufsize, const char *prefix) {\n  const char *tmpdir = \"/tmp\";\n#if SANITIZER_ANDROID\n  // I don't know a way to query temp directory location on Android without\n  // going through Java interfaces. The code below is not ideal, but should\n  // work. May require \"adb root\", but it is needed for almost any use of ASan\n  // on Android already.\n  tmpdir = GetEnv(\"EXTERNAL_STORAGE\");\n#endif\n  u32 uid = GetUid();\n  internal_snprintf(buf, bufsize, \"%s/%s%d\", tmpdir, prefix, uid);\n}\n\n// FIXME: File manipulations are not yet supported on Windows\n#if !defined(_WIN32)\nTEST(SanitizerCommon, FileOps) {\n  const char *str1 = \"qwerty\";\n  uptr len1 = internal_strlen(str1);\n  const char *str2 = \"zxcv\";\n  uptr len2 = internal_strlen(str2);\n\n  char tmpfile[128];\n  temp_file_name(tmpfile, sizeof(tmpfile), \"sanitizer_common.fileops.tmp.\");\n  fd_t fd = OpenFile(tmpfile, WrOnly);\n  ASSERT_NE(fd, kInvalidFd);\n  EXPECT_EQ(len1, internal_write(fd, str1, len1));\n  EXPECT_EQ(len2, internal_write(fd, str2, len2));\n  CloseFile(fd);\n\n  fd = OpenFile(tmpfile, RdOnly);\n  ASSERT_NE(fd, kInvalidFd);\n  uptr fsize = internal_filesize(fd);\n  EXPECT_EQ(len1 + len2, fsize);\n\n#if SANITIZER_TEST_HAS_STAT_H\n  struct stat st1, st2, st3;\n  EXPECT_EQ(0u, internal_stat(tmpfile, &st1));\n  EXPECT_EQ(0u, internal_lstat(tmpfile, &st2));\n  EXPECT_EQ(0u, internal_fstat(fd, &st3));\n  EXPECT_EQ(fsize, (uptr)st3.st_size);\n\n  // Verify that internal_fstat does not write beyond the end of the supplied\n  // buffer.\n  struct stat_and_more sam;\n  memset(&sam, 0xAB, sizeof(sam));\n  EXPECT_EQ(0u, internal_fstat(fd, &sam.st));\n  EXPECT_EQ(0xAB, sam.z);\n  EXPECT_NE(0xAB, sam.st.st_size);\n  EXPECT_NE(0, sam.st.st_size);\n#endif\n\n  char buf[64] = {};\n  EXPECT_EQ(len1, internal_read(fd, buf, len1));\n  EXPECT_EQ(0, internal_memcmp(buf, str1, len1));\n  EXPECT_EQ((char)0, buf[len1 + 1]);\n  internal_memset(buf, 0, len1);\n  EXPECT_EQ(len2, internal_read(fd, buf, len2));\n  EXPECT_EQ(0, internal_memcmp(buf, str2, len2));\n  CloseFile(fd);\n  internal_unlink(tmpfile);\n}\n#endif\n\nTEST(SanitizerCommon, InternalStrFunctions) {\n  const char *haystack = \"haystack\";\n  EXPECT_EQ(haystack + 2, internal_strchr(haystack, 'y'));\n  EXPECT_EQ(haystack + 2, internal_strchrnul(haystack, 'y'));\n  EXPECT_EQ(0, internal_strchr(haystack, 'z'));\n  EXPECT_EQ(haystack + 8, internal_strchrnul(haystack, 'z'));\n}\n\n// FIXME: File manipulations are not yet supported on Windows\n#if !defined(_WIN32) && !SANITIZER_MAC\nTEST(SanitizerCommon, InternalMmapWithOffset) {\n  char tmpfile[128];\n  temp_file_name(tmpfile, sizeof(tmpfile),\n                 \"sanitizer_common.internalmmapwithoffset.tmp.\");\n  fd_t fd = OpenFile(tmpfile, RdWr);\n  ASSERT_NE(fd, kInvalidFd);\n\n  uptr page_size = GetPageSizeCached();\n  uptr res = internal_ftruncate(fd, page_size * 2);\n  ASSERT_FALSE(internal_iserror(res));\n\n  res = internal_lseek(fd, page_size, SEEK_SET);\n  ASSERT_FALSE(internal_iserror(res));\n\n  res = internal_write(fd, \"AB\", 2);\n  ASSERT_FALSE(internal_iserror(res));\n\n  char *p = (char *)MapWritableFileToMemory(nullptr, page_size, fd, page_size);\n  ASSERT_NE(nullptr, p);\n\n  ASSERT_EQ('A', p[0]);\n  ASSERT_EQ('B', p[1]);\n\n  CloseFile(fd);\n  UnmapOrDie(p, page_size);\n  internal_unlink(tmpfile);\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc",
    "content": "//===-- sanitizer_linux_test.cc -------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Tests for sanitizer_linux.h\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_LINUX\n\n#include \"sanitizer_common/sanitizer_linux.h\"\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"gtest/gtest.h\"\n\n#include <pthread.h>\n#include <sched.h>\n#include <stdlib.h>\n\n#include <algorithm>\n#include <vector>\n\nnamespace __sanitizer {\n\nstruct TidReporterArgument {\n  TidReporterArgument() {\n    pthread_mutex_init(&terminate_thread_mutex, NULL);\n    pthread_mutex_init(&tid_reported_mutex, NULL);\n    pthread_cond_init(&terminate_thread_cond, NULL);\n    pthread_cond_init(&tid_reported_cond, NULL);\n    terminate_thread = false;\n  }\n\n  ~TidReporterArgument() {\n    pthread_mutex_destroy(&terminate_thread_mutex);\n    pthread_mutex_destroy(&tid_reported_mutex);\n    pthread_cond_destroy(&terminate_thread_cond);\n    pthread_cond_destroy(&tid_reported_cond);\n  }\n\n  pid_t reported_tid;\n  // For signaling to spawned threads that they should terminate.\n  pthread_cond_t terminate_thread_cond;\n  pthread_mutex_t terminate_thread_mutex;\n  bool terminate_thread;\n  // For signaling to main thread that a child thread has reported its tid.\n  pthread_cond_t tid_reported_cond;\n  pthread_mutex_t tid_reported_mutex;\n\n private:\n  // Disallow evil constructors\n  TidReporterArgument(const TidReporterArgument &);\n  void operator=(const TidReporterArgument &);\n};\n\nclass ThreadListerTest : public ::testing::Test {\n protected:\n  virtual void SetUp() {\n    pthread_t pthread_id;\n    pid_t tid;\n    for (uptr i = 0; i < kThreadCount; i++) {\n      SpawnTidReporter(&pthread_id, &tid);\n      pthread_ids_.push_back(pthread_id);\n      tids_.push_back(tid);\n    }\n  }\n\n  virtual void TearDown() {\n    pthread_mutex_lock(&thread_arg.terminate_thread_mutex);\n    thread_arg.terminate_thread = true;\n    pthread_cond_broadcast(&thread_arg.terminate_thread_cond);\n    pthread_mutex_unlock(&thread_arg.terminate_thread_mutex);\n    for (uptr i = 0; i < pthread_ids_.size(); i++)\n      pthread_join(pthread_ids_[i], NULL);\n  }\n\n  void SpawnTidReporter(pthread_t *pthread_id, pid_t *tid);\n\n  static const uptr kThreadCount = 20;\n\n  std::vector<pthread_t> pthread_ids_;\n  std::vector<pid_t> tids_;\n\n  TidReporterArgument thread_arg;\n};\n\n// Writes its TID once to reported_tid and waits until signaled to terminate.\nvoid *TidReporterThread(void *argument) {\n  TidReporterArgument *arg = reinterpret_cast<TidReporterArgument *>(argument);\n  pthread_mutex_lock(&arg->tid_reported_mutex);\n  arg->reported_tid = GetTid();\n  pthread_cond_broadcast(&arg->tid_reported_cond);\n  pthread_mutex_unlock(&arg->tid_reported_mutex);\n\n  pthread_mutex_lock(&arg->terminate_thread_mutex);\n  while (!arg->terminate_thread)\n    pthread_cond_wait(&arg->terminate_thread_cond,\n                      &arg->terminate_thread_mutex);\n  pthread_mutex_unlock(&arg->terminate_thread_mutex);\n  return NULL;\n}\n\nvoid ThreadListerTest::SpawnTidReporter(pthread_t *pthread_id,\n                                        pid_t *tid) {\n  pthread_mutex_lock(&thread_arg.tid_reported_mutex);\n  thread_arg.reported_tid = -1;\n  ASSERT_EQ(0, pthread_create(pthread_id, NULL,\n                              TidReporterThread,\n                              &thread_arg));\n  while (thread_arg.reported_tid == -1)\n    pthread_cond_wait(&thread_arg.tid_reported_cond,\n                      &thread_arg.tid_reported_mutex);\n  pthread_mutex_unlock(&thread_arg.tid_reported_mutex);\n  *tid = thread_arg.reported_tid;\n}\n\nstatic std::vector<pid_t> ReadTidsToVector(ThreadLister *thread_lister) {\n  std::vector<pid_t> listed_tids;\n  pid_t tid;\n  while ((tid = thread_lister->GetNextTID()) >= 0)\n    listed_tids.push_back(tid);\n  EXPECT_FALSE(thread_lister->error());\n  return listed_tids;\n}\n\nstatic bool Includes(std::vector<pid_t> first, std::vector<pid_t> second) {\n  std::sort(first.begin(), first.end());\n  std::sort(second.begin(), second.end());\n  return std::includes(first.begin(), first.end(),\n                       second.begin(), second.end());\n}\n\nstatic bool HasElement(std::vector<pid_t> vector, pid_t element) {\n  return std::find(vector.begin(), vector.end(), element) != vector.end();\n}\n\n// ThreadLister's output should include the current thread's TID and the TID of\n// every thread we spawned.\nTEST_F(ThreadListerTest, ThreadListerSeesAllSpawnedThreads) {\n  pid_t self_tid = GetTid();\n  ThreadLister thread_lister(getpid());\n  std::vector<pid_t> listed_tids = ReadTidsToVector(&thread_lister);\n  ASSERT_TRUE(HasElement(listed_tids, self_tid));\n  ASSERT_TRUE(Includes(listed_tids, tids_));\n}\n\n// Calling Reset() should not cause ThreadLister to forget any threads it's\n// supposed to know about.\nTEST_F(ThreadListerTest, ResetDoesNotForgetThreads) {\n  ThreadLister thread_lister(getpid());\n\n  // Run the loop body twice, because Reset() might behave differently if called\n  // on a freshly created object.\n  for (uptr i = 0; i < 2; i++) {\n    thread_lister.Reset();\n    std::vector<pid_t> listed_tids = ReadTidsToVector(&thread_lister);\n    ASSERT_TRUE(Includes(listed_tids, tids_));\n  }\n}\n\n// If new threads have spawned during ThreadLister object's lifetime, calling\n// Reset() should cause ThreadLister to recognize their existence.\nTEST_F(ThreadListerTest, ResetMakesNewThreadsKnown) {\n  ThreadLister thread_lister(getpid());\n  std::vector<pid_t> threads_before_extra = ReadTidsToVector(&thread_lister);\n\n  pthread_t extra_pthread_id;\n  pid_t extra_tid;\n  SpawnTidReporter(&extra_pthread_id, &extra_tid);\n  // Register the new thread so it gets terminated in TearDown().\n  pthread_ids_.push_back(extra_pthread_id);\n\n  // It would be very bizarre if the new TID had been listed before we even\n  // spawned that thread, but it would also cause a false success in this test,\n  // so better check for that.\n  ASSERT_FALSE(HasElement(threads_before_extra, extra_tid));\n\n  thread_lister.Reset();\n\n  std::vector<pid_t> threads_after_extra = ReadTidsToVector(&thread_lister);\n  ASSERT_TRUE(HasElement(threads_after_extra, extra_tid));\n}\n\nTEST(SanitizerCommon, SetEnvTest) {\n  const char kEnvName[] = \"ENV_FOO\";\n  SetEnv(kEnvName, \"value\");\n  EXPECT_STREQ(\"value\", getenv(kEnvName));\n  unsetenv(kEnvName);\n  EXPECT_EQ(0, getenv(kEnvName));\n}\n\n#if defined(__x86_64__) || defined(__i386__)\nvoid *thread_self_offset_test_func(void *arg) {\n  bool result =\n      *(uptr *)((char *)ThreadSelf() + ThreadSelfOffset()) == ThreadSelf();\n  return (void *)result;\n}\n\nTEST(SanitizerLinux, ThreadSelfOffset) {\n  EXPECT_TRUE((bool)thread_self_offset_test_func(0));\n  pthread_t tid;\n  void *result;\n  ASSERT_EQ(0, pthread_create(&tid, 0, thread_self_offset_test_func, 0));\n  ASSERT_EQ(0, pthread_join(tid, &result));\n  EXPECT_TRUE((bool)result);\n}\n\n// libpthread puts the thread descriptor at the end of stack space.\nvoid *thread_descriptor_size_test_func(void *arg) {\n  uptr descr_addr = ThreadSelf();\n  pthread_attr_t attr;\n  pthread_getattr_np(pthread_self(), &attr);\n  void *stackaddr;\n  size_t stacksize;\n  pthread_attr_getstack(&attr, &stackaddr, &stacksize);\n  return (void *)((uptr)stackaddr + stacksize - descr_addr);\n}\n\nTEST(SanitizerLinux, ThreadDescriptorSize) {\n  pthread_t tid;\n  void *result;\n  ASSERT_EQ(0, pthread_create(&tid, 0, thread_descriptor_size_test_func, 0));\n  ASSERT_EQ(0, pthread_join(tid, &result));\n  EXPECT_EQ((uptr)result, ThreadDescriptorSize());\n}\n#endif\n\nTEST(SanitizerCommon, LibraryNameIs) {\n  EXPECT_FALSE(LibraryNameIs(\"\", \"\"));\n\n  char full_name[256];\n  const char *paths[] = { \"\", \"/\", \"/path/to/\" };\n  const char *suffixes[] = { \"\", \"-linux\", \".1.2\", \"-linux.1.2\" };\n  const char *base_names[] = { \"lib\", \"lib.0\", \"lib-i386\" };\n  const char *wrong_names[] = { \"\", \"lib.9\", \"lib-x86_64\" };\n  for (uptr i = 0; i < ARRAY_SIZE(paths); i++)\n    for (uptr j = 0; j < ARRAY_SIZE(suffixes); j++) {\n      for (uptr k = 0; k < ARRAY_SIZE(base_names); k++) {\n        internal_snprintf(full_name, ARRAY_SIZE(full_name), \"%s%s%s.so\",\n                          paths[i], base_names[k], suffixes[j]);\n        EXPECT_TRUE(LibraryNameIs(full_name, base_names[k]))\n            << \"Full name \" << full_name\n            << \" doesn't match base name \" << base_names[k];\n        for (uptr m = 0; m < ARRAY_SIZE(wrong_names); m++)\n          EXPECT_FALSE(LibraryNameIs(full_name, wrong_names[m]))\n            << \"Full name \" << full_name\n            << \" matches base name \" << wrong_names[m];\n      }\n    }\n}\n\n#if defined(__mips64)\n// Effectively, this is a test for ThreadDescriptorSize() which is used to\n// compute ThreadSelf().\nTEST(SanitizerLinux, ThreadSelfTest) {\n  ASSERT_EQ(pthread_self(), ThreadSelf());\n}\n#endif\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_list_test.cc",
    "content": "//===-- sanitizer_list_test.cc --------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_list.h\"\n#include \"gtest/gtest.h\"\n\nnamespace __sanitizer {\n\nstruct ListItem {\n  ListItem *next;\n};\n\ntypedef IntrusiveList<ListItem> List;\n\nstatic List static_list;\n\nstatic void SetList(List *l, ListItem *x = 0,\n                    ListItem *y = 0, ListItem *z = 0) {\n  l->clear();\n  if (x) l->push_back(x);\n  if (y) l->push_back(y);\n  if (z) l->push_back(z);\n}\n\nstatic void CheckList(List *l, ListItem *i1, ListItem *i2 = 0, ListItem *i3 = 0,\n                      ListItem *i4 = 0, ListItem *i5 = 0, ListItem *i6 = 0) {\n  if (i1) {\n    CHECK_EQ(l->front(), i1);\n    l->pop_front();\n  }\n  if (i2) {\n    CHECK_EQ(l->front(), i2);\n    l->pop_front();\n  }\n  if (i3) {\n    CHECK_EQ(l->front(), i3);\n    l->pop_front();\n  }\n  if (i4) {\n    CHECK_EQ(l->front(), i4);\n    l->pop_front();\n  }\n  if (i5) {\n    CHECK_EQ(l->front(), i5);\n    l->pop_front();\n  }\n  if (i6) {\n    CHECK_EQ(l->front(), i6);\n    l->pop_front();\n  }\n  CHECK(l->empty());\n}\n\nTEST(SanitizerCommon, IntrusiveList) {\n  ListItem items[6];\n  CHECK_EQ(static_list.size(), 0);\n\n  List l;\n  l.clear();\n\n  ListItem *x = &items[0];\n  ListItem *y = &items[1];\n  ListItem *z = &items[2];\n  ListItem *a = &items[3];\n  ListItem *b = &items[4];\n  ListItem *c = &items[5];\n\n  CHECK_EQ(l.size(), 0);\n  l.push_back(x);\n  CHECK_EQ(l.size(), 1);\n  CHECK_EQ(l.back(), x);\n  CHECK_EQ(l.front(), x);\n  l.pop_front();\n  CHECK(l.empty());\n  l.CheckConsistency();\n\n  l.push_front(x);\n  CHECK_EQ(l.size(), 1);\n  CHECK_EQ(l.back(), x);\n  CHECK_EQ(l.front(), x);\n  l.pop_front();\n  CHECK(l.empty());\n  l.CheckConsistency();\n\n  l.push_front(x);\n  l.push_front(y);\n  l.push_front(z);\n  CHECK_EQ(l.size(), 3);\n  CHECK_EQ(l.front(), z);\n  CHECK_EQ(l.back(), x);\n  l.CheckConsistency();\n\n  l.pop_front();\n  CHECK_EQ(l.size(), 2);\n  CHECK_EQ(l.front(), y);\n  CHECK_EQ(l.back(), x);\n  l.pop_front();\n  l.pop_front();\n  CHECK(l.empty());\n  l.CheckConsistency();\n\n  l.push_back(x);\n  l.push_back(y);\n  l.push_back(z);\n  CHECK_EQ(l.size(), 3);\n  CHECK_EQ(l.front(), x);\n  CHECK_EQ(l.back(), z);\n  l.CheckConsistency();\n\n  l.pop_front();\n  CHECK_EQ(l.size(), 2);\n  CHECK_EQ(l.front(), y);\n  CHECK_EQ(l.back(), z);\n  l.pop_front();\n  l.pop_front();\n  CHECK(l.empty());\n  l.CheckConsistency();\n\n  List l1, l2;\n  l1.clear();\n  l2.clear();\n\n  l1.append_front(&l2);\n  CHECK(l1.empty());\n  CHECK(l2.empty());\n\n  l1.append_back(&l2);\n  CHECK(l1.empty());\n  CHECK(l2.empty());\n\n  SetList(&l1, x);\n  CheckList(&l1, x);\n\n  SetList(&l1, x, y, z);\n  SetList(&l2, a, b, c);\n  l1.append_back(&l2);\n  CheckList(&l1, x, y, z, a, b, c);\n  CHECK(l2.empty());\n\n  SetList(&l1, x, y);\n  SetList(&l2);\n  l1.append_front(&l2);\n  CheckList(&l1, x, y);\n  CHECK(l2.empty());\n}\n\nTEST(SanitizerCommon, IntrusiveListAppendEmpty) {\n  ListItem i;\n  List l;\n  l.clear();\n  l.push_back(&i);\n  List l2;\n  l2.clear();\n  l.append_back(&l2);\n  CHECK_EQ(l.back(), &i);\n  CHECK_EQ(l.front(), &i);\n  CHECK_EQ(l.size(), 1);\n  l.append_front(&l2);\n  CHECK_EQ(l.back(), &i);\n  CHECK_EQ(l.front(), &i);\n  CHECK_EQ(l.size(), 1);\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_mutex_test.cc",
    "content": "//===-- sanitizer_mutex_test.cc -------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_mutex.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n\n#include \"sanitizer_pthread_wrappers.h\"\n\n#include \"gtest/gtest.h\"\n\n#include <string.h>\n\nnamespace __sanitizer {\n\ntemplate<typename MutexType>\nclass TestData {\n public:\n  explicit TestData(MutexType *mtx)\n      : mtx_(mtx) {\n    for (int i = 0; i < kSize; i++)\n      data_[i] = 0;\n  }\n\n  void Write() {\n    Lock l(mtx_);\n    T v0 = data_[0];\n    for (int i = 0; i < kSize; i++) {\n      CHECK_EQ(data_[i], v0);\n      data_[i]++;\n    }\n  }\n\n  void TryWrite() {\n    if (!mtx_->TryLock())\n      return;\n    T v0 = data_[0];\n    for (int i = 0; i < kSize; i++) {\n      CHECK_EQ(data_[i], v0);\n      data_[i]++;\n    }\n    mtx_->Unlock();\n  }\n\n  void Backoff() {\n    volatile T data[kSize] = {};\n    for (int i = 0; i < kSize; i++) {\n      data[i]++;\n      CHECK_EQ(data[i], 1);\n    }\n  }\n\n private:\n  typedef GenericScopedLock<MutexType> Lock;\n  static const int kSize = 64;\n  typedef u64 T;\n  MutexType *mtx_;\n  char pad_[kCacheLineSize];\n  T data_[kSize];\n};\n\nconst int kThreads = 8;\n#if SANITIZER_DEBUG\nconst int kIters = 16*1024;\n#else\nconst int kIters = 64*1024;\n#endif\n\ntemplate<typename MutexType>\nstatic void *lock_thread(void *param) {\n  TestData<MutexType> *data = (TestData<MutexType>*)param;\n  for (int i = 0; i < kIters; i++) {\n    data->Write();\n    data->Backoff();\n  }\n  return 0;\n}\n\ntemplate<typename MutexType>\nstatic void *try_thread(void *param) {\n  TestData<MutexType> *data = (TestData<MutexType>*)param;\n  for (int i = 0; i < kIters; i++) {\n    data->TryWrite();\n    data->Backoff();\n  }\n  return 0;\n}\n\ntemplate<typename MutexType>\nstatic void check_locked(MutexType *mtx) {\n  GenericScopedLock<MutexType> l(mtx);\n  mtx->CheckLocked();\n}\n\nTEST(SanitizerCommon, SpinMutex) {\n  SpinMutex mtx;\n  mtx.Init();\n  TestData<SpinMutex> data(&mtx);\n  pthread_t threads[kThreads];\n  for (int i = 0; i < kThreads; i++)\n    PTHREAD_CREATE(&threads[i], 0, lock_thread<SpinMutex>, &data);\n  for (int i = 0; i < kThreads; i++)\n    PTHREAD_JOIN(threads[i], 0);\n}\n\nTEST(SanitizerCommon, SpinMutexTry) {\n  SpinMutex mtx;\n  mtx.Init();\n  TestData<SpinMutex> data(&mtx);\n  pthread_t threads[kThreads];\n  for (int i = 0; i < kThreads; i++)\n    PTHREAD_CREATE(&threads[i], 0, try_thread<SpinMutex>, &data);\n  for (int i = 0; i < kThreads; i++)\n    PTHREAD_JOIN(threads[i], 0);\n}\n\nTEST(SanitizerCommon, BlockingMutex) {\n  u64 mtxmem[1024] = {};\n  BlockingMutex *mtx = new(mtxmem) BlockingMutex(LINKER_INITIALIZED);\n  TestData<BlockingMutex> data(mtx);\n  pthread_t threads[kThreads];\n  for (int i = 0; i < kThreads; i++)\n    PTHREAD_CREATE(&threads[i], 0, lock_thread<BlockingMutex>, &data);\n  for (int i = 0; i < kThreads; i++)\n    PTHREAD_JOIN(threads[i], 0);\n  check_locked(mtx);\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_nolibc_test.cc",
    "content": "//===-- sanitizer_nolibc_test.cc ------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n// Tests for libc independence of sanitizer_common.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n\n#include \"gtest/gtest.h\"\n\n#include <stdlib.h>\n\nextern const char *argv0;\n\n#if SANITIZER_LINUX && defined(__x86_64__)\nTEST(SanitizerCommon, NolibcMain) {\n  std::string NolibcTestPath = argv0;\n  NolibcTestPath += \"-Nolibc\";\n  int status = system(NolibcTestPath.c_str());\n  EXPECT_EQ(true, WIFEXITED(status));\n  EXPECT_EQ(0, WEXITSTATUS(status));\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_nolibc_test_main.cc",
    "content": "//===-- sanitizer_nolibc_test_main.cc -------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n// Tests for libc independence of sanitizer_common.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_libc.h\"\n\nextern \"C\" void _start() {\n  internal__exit(0);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_posix_test.cc",
    "content": "//===-- sanitizer_posix_test.cc -------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Tests for POSIX-specific code.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_POSIX\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"gtest/gtest.h\"\n\n#include <pthread.h>\n#include <sys/mman.h>\n\nnamespace __sanitizer {\n\nstatic pthread_key_t key;\nstatic bool destructor_executed;\n\nextern \"C\"\nvoid destructor(void *arg) {\n  uptr iter = reinterpret_cast<uptr>(arg);\n  if (iter > 1) {\n    ASSERT_EQ(0, pthread_setspecific(key, reinterpret_cast<void *>(iter - 1)));\n    return;\n  }\n  destructor_executed = true;\n}\n\nextern \"C\"\nvoid *thread_func(void *arg) {\n  return reinterpret_cast<void*>(pthread_setspecific(key, arg));\n}\n\nstatic void SpawnThread(uptr iteration) {\n  destructor_executed = false;\n  pthread_t tid;\n  ASSERT_EQ(0, pthread_create(&tid, 0, &thread_func,\n                              reinterpret_cast<void *>(iteration)));\n  void *retval;\n  ASSERT_EQ(0, pthread_join(tid, &retval));\n  ASSERT_EQ(0, retval);\n}\n\nTEST(SanitizerCommon, PthreadDestructorIterations) {\n  ASSERT_EQ(0, pthread_key_create(&key, &destructor));\n  SpawnThread(kPthreadDestructorIterations);\n  EXPECT_TRUE(destructor_executed);\n  SpawnThread(kPthreadDestructorIterations + 1);\n  EXPECT_FALSE(destructor_executed);\n}\n\nTEST(SanitizerCommon, IsAccessibleMemoryRange) {\n  const int page_size = GetPageSize();\n  uptr mem = (uptr)mmap(0, 3 * page_size, PROT_READ | PROT_WRITE,\n                        MAP_PRIVATE | MAP_ANON, -1, 0);\n  // Protect the middle page.\n  mprotect((void *)(mem + page_size), page_size, PROT_NONE);\n  EXPECT_TRUE(IsAccessibleMemoryRange(mem, page_size - 1));\n  EXPECT_TRUE(IsAccessibleMemoryRange(mem, page_size));\n  EXPECT_FALSE(IsAccessibleMemoryRange(mem, page_size + 1));\n  EXPECT_TRUE(IsAccessibleMemoryRange(mem + page_size - 1, 1));\n  EXPECT_FALSE(IsAccessibleMemoryRange(mem + page_size - 1, 2));\n  EXPECT_FALSE(IsAccessibleMemoryRange(mem + 2 * page_size - 1, 1));\n  EXPECT_TRUE(IsAccessibleMemoryRange(mem + 2 * page_size, page_size));\n  EXPECT_FALSE(IsAccessibleMemoryRange(mem, 3 * page_size));\n  EXPECT_FALSE(IsAccessibleMemoryRange(0x0, 2));\n}\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_POSIX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_printf_test.cc",
    "content": "//===-- sanitizer_printf_test.cc ------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Tests for sanitizer_printf.cc\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"gtest/gtest.h\"\n\n#include <string.h>\n#include <limits.h>\n\nnamespace __sanitizer {\n\nTEST(Printf, Basic) {\n  char buf[1024];\n  uptr len = internal_snprintf(buf, sizeof(buf),\n      \"a%db%zdc%ue%zuf%xh%zxq%pe%sr\",\n      (int)-1, (long)-2, // NOLINT\n      (unsigned)-4, (unsigned long)5, // NOLINT\n      (unsigned)10, (unsigned long)11, // NOLINT\n      (void*)0x123, \"_string_\");\n  EXPECT_EQ(len, strlen(buf));\n\n  std::string expectedString = \"a-1b-2c4294967292e5fahbq0x\";\n  expectedString += std::string(SANITIZER_POINTER_FORMAT_LENGTH - 3, '0');\n  expectedString += \"123e_string_r\";\n  EXPECT_STREQ(expectedString.c_str(), buf);\n}\n\nTEST(Printf, OverflowStr) {\n  char buf[] = \"123456789\";\n  uptr len = internal_snprintf(buf, 4, \"%s\", \"abcdef\");  // NOLINT\n  EXPECT_EQ(len, (uptr)6);\n  EXPECT_STREQ(\"abc\", buf);\n  EXPECT_EQ(buf[3], 0);\n  EXPECT_EQ(buf[4], '5');\n  EXPECT_EQ(buf[5], '6');\n  EXPECT_EQ(buf[6], '7');\n  EXPECT_EQ(buf[7], '8');\n  EXPECT_EQ(buf[8], '9');\n  EXPECT_EQ(buf[9], 0);\n}\n\nTEST(Printf, OverflowInt) {\n  char buf[] = \"123456789\";\n  internal_snprintf(buf, 4, \"%d\", -123456789);  // NOLINT\n  EXPECT_STREQ(\"-12\", buf);\n  EXPECT_EQ(buf[3], 0);\n  EXPECT_EQ(buf[4], '5');\n  EXPECT_EQ(buf[5], '6');\n  EXPECT_EQ(buf[6], '7');\n  EXPECT_EQ(buf[7], '8');\n  EXPECT_EQ(buf[8], '9');\n  EXPECT_EQ(buf[9], 0);\n}\n\nTEST(Printf, OverflowUint) {\n  char buf[] = \"123456789\";\n  uptr val;\n  if (sizeof(val) == 4) {\n    val = (uptr)0x12345678;\n  } else {\n    val = (uptr)0x123456789ULL;\n  }\n  internal_snprintf(buf, 4, \"a%zx\", val);  // NOLINT\n  EXPECT_STREQ(\"a12\", buf);\n  EXPECT_EQ(buf[3], 0);\n  EXPECT_EQ(buf[4], '5');\n  EXPECT_EQ(buf[5], '6');\n  EXPECT_EQ(buf[6], '7');\n  EXPECT_EQ(buf[7], '8');\n  EXPECT_EQ(buf[8], '9');\n  EXPECT_EQ(buf[9], 0);\n}\n\nTEST(Printf, OverflowPtr) {\n  char buf[] = \"123456789\";\n  void *p;\n  if (sizeof(p) == 4) {\n    p = (void*)0x1234567;\n  } else {\n    p = (void*)0x123456789ULL;\n  }\n  internal_snprintf(buf, 4, \"%p\", p);  // NOLINT\n  EXPECT_STREQ(\"0x0\", buf);\n  EXPECT_EQ(buf[3], 0);\n  EXPECT_EQ(buf[4], '5');\n  EXPECT_EQ(buf[5], '6');\n  EXPECT_EQ(buf[6], '7');\n  EXPECT_EQ(buf[7], '8');\n  EXPECT_EQ(buf[8], '9');\n  EXPECT_EQ(buf[9], 0);\n}\n\n#if defined(_WIN32)\n// Oh well, MSVS headers don't define snprintf.\n# define snprintf _snprintf\n#endif\n\ntemplate<typename T>\nstatic void TestAgainstLibc(const char *fmt, T arg1, T arg2) {\n  char buf[1024];\n  uptr len = internal_snprintf(buf, sizeof(buf), fmt, arg1, arg2);\n  char buf2[1024];\n  snprintf(buf2, sizeof(buf2), fmt, arg1, arg2);\n  EXPECT_EQ(len, strlen(buf));\n  EXPECT_STREQ(buf2, buf);\n}\n\nTEST(Printf, MinMax) {\n  TestAgainstLibc<int>(\"%d-%d\", INT_MIN, INT_MAX);  // NOLINT\n  TestAgainstLibc<unsigned>(\"%u-%u\", 0, UINT_MAX);  // NOLINT\n  TestAgainstLibc<unsigned>(\"%x-%x\", 0, UINT_MAX);  // NOLINT\n#if !defined(_WIN32)\n  // %z* format doesn't seem to be supported by MSVS.\n  TestAgainstLibc<long>(\"%zd-%zd\", LONG_MIN, LONG_MAX);  // NOLINT\n  TestAgainstLibc<unsigned long>(\"%zu-%zu\", 0, ULONG_MAX);  // NOLINT\n  TestAgainstLibc<unsigned long>(\"%zx-%zx\", 0, ULONG_MAX);  // NOLINT\n#endif\n}\n\nTEST(Printf, Padding) {\n  TestAgainstLibc<int>(\"%3d - %3d\", 1, 0);\n  TestAgainstLibc<int>(\"%3d - %3d\", -1, 123);\n  TestAgainstLibc<int>(\"%3d - %3d\", -1, -123);\n  TestAgainstLibc<int>(\"%3d - %3d\", 12, 1234);\n  TestAgainstLibc<int>(\"%3d - %3d\", -12, -1234);\n  TestAgainstLibc<int>(\"%03d - %03d\", 1, 0);\n  TestAgainstLibc<int>(\"%03d - %03d\", -1, 123);\n  TestAgainstLibc<int>(\"%03d - %03d\", -1, -123);\n  TestAgainstLibc<int>(\"%03d - %03d\", 12, 1234);\n  TestAgainstLibc<int>(\"%03d - %03d\", -12, -1234);\n}\n\nTEST(Printf, Precision) {\n  char buf[1024];\n  uptr len = internal_snprintf(buf, sizeof(buf), \"%.*s\", 3, \"12345\");\n  EXPECT_EQ(3U, len);\n  EXPECT_STREQ(\"123\", buf);\n  len = internal_snprintf(buf, sizeof(buf), \"%.*s\", 6, \"12345\");\n  EXPECT_EQ(5U, len);\n  EXPECT_STREQ(\"12345\", buf);\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_procmaps_test.cc",
    "content": "//===-- sanitizer_procmaps_test.cc ----------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n#if !defined(_WIN32)  // There are no /proc/maps on Windows.\n\n#include \"sanitizer_common/sanitizer_procmaps.h\"\n#include \"gtest/gtest.h\"\n\n#include <stdlib.h>\n\nstatic void noop() {}\nextern const char *argv0;\n\nnamespace __sanitizer {\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nTEST(MemoryMappingLayout, CodeRange) {\n  uptr start, end;\n  bool res = GetCodeRangeForFile(\"[vdso]\", &start, &end);\n  EXPECT_EQ(res, true);\n  EXPECT_GT(start, 0U);\n  EXPECT_LT(start, end);\n}\n#endif\n\nTEST(MemoryMappingLayout, DumpListOfModules) {\n  const char *last_slash = strrchr(argv0, '/');\n  const char *binary_name = last_slash ? last_slash + 1 : argv0;\n  MemoryMappingLayout memory_mapping(false);\n  const uptr kMaxModules = 100;\n  LoadedModule modules[kMaxModules];\n  uptr n_modules = memory_mapping.DumpListOfModules(modules, kMaxModules, 0);\n  EXPECT_GT(n_modules, 0U);\n  bool found = false;\n  for (uptr i = 0; i < n_modules; ++i) {\n    if (modules[i].containsAddress((uptr)&noop)) {\n      // Verify that the module name is sane.\n      if (strstr(modules[i].full_name(), binary_name) != 0)\n        found = true;\n    }\n    modules[i].clear();\n  }\n  EXPECT_TRUE(found);\n}\n\n}  // namespace __sanitizer\n#endif  // !defined(_WIN32)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_pthread_wrappers.h",
    "content": "//===-- sanitizer_pthread_wrappers.h ----------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of *Sanitizer runtime.\n// It provides handy wrappers for thread manipulation, that:\n//  a) assert on any failure rather than returning an error code\n//  b) defines pthread-like interface on platforms where where <pthread.h>\n//     is not supplied by default.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_PTHREAD_WRAPPERS_H\n#define SANITIZER_PTHREAD_WRAPPERS_H\n\n#include \"sanitizer_test_utils.h\"\n\n#if !defined(_WIN32)\n# include <pthread.h>\n// Simply forward the arguments and check that the pthread functions succeed.\n# define PTHREAD_CREATE(a, b, c, d) ASSERT_EQ(0, pthread_create(a, b, c, d))\n# define PTHREAD_JOIN(a, b) ASSERT_EQ(0, pthread_join(a, b))\n#else\ntypedef HANDLE pthread_t;\n\nstruct PthreadHelperCreateThreadInfo {\n  void *(*start_routine)(void *);\n  void *arg;\n};\n\ninline DWORD WINAPI PthreadHelperThreadProc(void *arg) {\n  PthreadHelperCreateThreadInfo *start_data =\n      reinterpret_cast<PthreadHelperCreateThreadInfo*>(arg);\n  void *ret = (start_data->start_routine)(start_data->arg);\n  delete start_data;\n  return (DWORD)ret;\n}\n\ninline void PTHREAD_CREATE(pthread_t *thread, void *attr,\n                           void *(*start_routine)(void *), void *arg) {\n  ASSERT_EQ(0, attr) << \"Thread attributes are not supported yet.\";\n  PthreadHelperCreateThreadInfo *data = new PthreadHelperCreateThreadInfo;\n  data->start_routine = start_routine;\n  data->arg = arg;\n  *thread = CreateThread(0, 0, PthreadHelperThreadProc, data, 0, 0);\n  ASSERT_NE(nullptr, *thread) << \"Failed to create a thread.\";\n}\n\ninline void PTHREAD_JOIN(pthread_t thread, void **value_ptr) {\n  ASSERT_EQ(0, value_ptr) << \"Nonzero value_ptr is not supported yet.\";\n  ASSERT_EQ(WAIT_OBJECT_0, WaitForSingleObject(thread, INFINITE));\n  ASSERT_NE(0, CloseHandle(thread));\n}\n\ninline void pthread_exit(void *retval) {\n  ASSERT_EQ(0, retval) << \"Nonzero retval is not supported yet.\";\n  ExitThread((DWORD)retval);\n}\n#endif  // _WIN32\n\n#endif  // SANITIZER_PTHREAD_WRAPPERS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cc",
    "content": "//===-- sanitizer_stackdepot_test.cc --------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"gtest/gtest.h\"\n\nnamespace __sanitizer {\n\nTEST(SanitizerCommon, StackDepotBasic) {\n  uptr array[] = {1, 2, 3, 4, 5};\n  StackTrace s1(array, ARRAY_SIZE(array));\n  u32 i1 = StackDepotPut(s1);\n  StackTrace stack = StackDepotGet(i1);\n  EXPECT_NE(stack.trace, (uptr*)0);\n  EXPECT_EQ(ARRAY_SIZE(array), stack.size);\n  EXPECT_EQ(0, internal_memcmp(stack.trace, array, sizeof(array)));\n}\n\nTEST(SanitizerCommon, StackDepotAbsent) {\n  StackTrace stack = StackDepotGet((1 << 30) - 1);\n  EXPECT_EQ((uptr*)0, stack.trace);\n}\n\nTEST(SanitizerCommon, StackDepotEmptyStack) {\n  u32 i1 = StackDepotPut(StackTrace());\n  StackTrace stack = StackDepotGet(i1);\n  EXPECT_EQ((uptr*)0, stack.trace);\n}\n\nTEST(SanitizerCommon, StackDepotZeroId) {\n  StackTrace stack = StackDepotGet(0);\n  EXPECT_EQ((uptr*)0, stack.trace);\n}\n\nTEST(SanitizerCommon, StackDepotSame) {\n  uptr array[] = {1, 2, 3, 4, 6};\n  StackTrace s1(array, ARRAY_SIZE(array));\n  u32 i1 = StackDepotPut(s1);\n  u32 i2 = StackDepotPut(s1);\n  EXPECT_EQ(i1, i2);\n  StackTrace stack = StackDepotGet(i1);\n  EXPECT_NE(stack.trace, (uptr*)0);\n  EXPECT_EQ(ARRAY_SIZE(array), stack.size);\n  EXPECT_EQ(0, internal_memcmp(stack.trace, array, sizeof(array)));\n}\n\nTEST(SanitizerCommon, StackDepotSeveral) {\n  uptr array1[] = {1, 2, 3, 4, 7};\n  StackTrace s1(array1, ARRAY_SIZE(array1));\n  u32 i1 = StackDepotPut(s1);\n  uptr array2[] = {1, 2, 3, 4, 8, 9};\n  StackTrace s2(array2, ARRAY_SIZE(array2));\n  u32 i2 = StackDepotPut(s2);\n  EXPECT_NE(i1, i2);\n}\n\nTEST(SanitizerCommon, StackDepotReverseMap) {\n  uptr array1[] = {1, 2, 3, 4, 5};\n  uptr array2[] = {7, 1, 3, 0};\n  uptr array3[] = {10, 2, 5, 3};\n  uptr array4[] = {1, 3, 2, 5};\n  u32 ids[4] = {0};\n  StackTrace s1(array1, ARRAY_SIZE(array1));\n  StackTrace s2(array2, ARRAY_SIZE(array2));\n  StackTrace s3(array3, ARRAY_SIZE(array3));\n  StackTrace s4(array4, ARRAY_SIZE(array4));\n  ids[0] = StackDepotPut(s1);\n  ids[1] = StackDepotPut(s2);\n  ids[2] = StackDepotPut(s3);\n  ids[3] = StackDepotPut(s4);\n\n  StackDepotReverseMap map;\n\n  for (uptr i = 0; i < 4; i++) {\n    StackTrace stack = StackDepotGet(ids[i]);\n    StackTrace from_map = map.Get(ids[i]);\n    EXPECT_EQ(stack.size, from_map.size);\n    EXPECT_EQ(stack.trace, from_map.trace);\n  }\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc",
    "content": "//===-- sanitizer_common_printer_test.cc ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of sanitizer_common test suite.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_stacktrace_printer.h\"\n\n#include \"gtest/gtest.h\"\n\nnamespace __sanitizer {\n\nTEST(SanitizerStacktracePrinter, RenderSourceLocation) {\n  InternalScopedString str(128);\n  RenderSourceLocation(&str, \"/dir/file.cc\", 10, 5, false, \"\");\n  EXPECT_STREQ(\"/dir/file.cc:10:5\", str.data());\n\n  str.clear();\n  RenderSourceLocation(&str, \"/dir/file.cc\", 11, 0, false, \"\");\n  EXPECT_STREQ(\"/dir/file.cc:11\", str.data());\n\n  str.clear();\n  RenderSourceLocation(&str, \"/dir/file.cc\", 0, 0, false, \"\");\n  EXPECT_STREQ(\"/dir/file.cc\", str.data());\n\n  str.clear();\n  RenderSourceLocation(&str, \"/dir/file.cc\", 10, 5, false, \"/dir/\");\n  EXPECT_STREQ(\"file.cc:10:5\", str.data());\n\n  str.clear();\n  RenderSourceLocation(&str, \"/dir/file.cc\", 10, 5, true, \"\");\n  EXPECT_STREQ(\"/dir/file.cc(10,5)\", str.data());\n\n  str.clear();\n  RenderSourceLocation(&str, \"/dir/file.cc\", 11, 0, true, \"\");\n  EXPECT_STREQ(\"/dir/file.cc(11)\", str.data());\n\n  str.clear();\n  RenderSourceLocation(&str, \"/dir/file.cc\", 0, 0, true, \"\");\n  EXPECT_STREQ(\"/dir/file.cc\", str.data());\n\n  str.clear();\n  RenderSourceLocation(&str, \"/dir/file.cc\", 10, 5, true, \"/dir/\");\n  EXPECT_STREQ(\"file.cc(10,5)\", str.data());\n}\n\nTEST(SanitizerStacktracePrinter, RenderModuleLocation) {\n  InternalScopedString str(128);\n  RenderModuleLocation(&str, \"/dir/exe\", 0x123, \"\");\n  EXPECT_STREQ(\"(/dir/exe+0x123)\", str.data());\n\n  // Check that we strip file prefix if necessary.\n  str.clear();\n  RenderModuleLocation(&str, \"/dir/exe\", 0x123, \"/dir/\");\n  EXPECT_STREQ(\"(exe+0x123)\", str.data());\n}\n\nTEST(SanitizerStacktracePrinter, RenderFrame) {\n  int frame_no = 42;\n  AddressInfo info;\n  info.address = 0x400000;\n  info.module = internal_strdup(\"/path/to/my/module\");\n  info.module_offset = 0x200;\n  info.function = internal_strdup(\"function_foo\");\n  info.function_offset = 0x100;\n  info.file = internal_strdup(\"/path/to/my/source\");\n  info.line = 10;\n  info.column = 5;\n  InternalScopedString str(256);\n\n  // Dump all the AddressInfo fields.\n  RenderFrame(&str, \"%% Frame:%n PC:%p Module:%m ModuleOffset:%o \"\n                    \"Function:%f FunctionOffset:%q Source:%s Line:%l \"\n                    \"Column:%c\",\n              frame_no, info, false, \"/path/to/\", \"function_\");\n  EXPECT_STREQ(\"% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 \"\n               \"Function:foo FunctionOffset:0x100 Source:my/source Line:10 \"\n               \"Column:5\",\n               str.data());\n  info.Clear();\n  str.clear();\n\n  // Test special format specifiers.\n  info.address = 0x400000;\n  RenderFrame(&str, \"%M\", frame_no, info, false);\n  EXPECT_NE(nullptr, internal_strstr(str.data(), \"400000\"));\n  str.clear();\n\n  RenderFrame(&str, \"%L\", frame_no, info, false);\n  EXPECT_STREQ(\"(<unknown module>)\", str.data());\n  str.clear();\n\n  info.module = internal_strdup(\"/path/to/module\");\n  info.module_offset = 0x200;\n  RenderFrame(&str, \"%M\", frame_no, info, false);\n  EXPECT_NE(nullptr, internal_strstr(str.data(), \"(module+0x\"));\n  EXPECT_NE(nullptr, internal_strstr(str.data(), \"200\"));\n  str.clear();\n\n  RenderFrame(&str, \"%L\", frame_no, info, false);\n  EXPECT_STREQ(\"(/path/to/module+0x200)\", str.data());\n  str.clear();\n\n  info.function = internal_strdup(\"my_function\");\n  RenderFrame(&str, \"%F\", frame_no, info, false);\n  EXPECT_STREQ(\"in my_function\", str.data());\n  str.clear();\n\n  info.function_offset = 0x100;\n  RenderFrame(&str, \"%F %S\", frame_no, info, false);\n  EXPECT_STREQ(\"in my_function+0x100 <null>\", str.data());\n  str.clear();\n\n  info.file = internal_strdup(\"my_file\");\n  RenderFrame(&str, \"%F %S\", frame_no, info, false);\n  EXPECT_STREQ(\"in my_function my_file\", str.data());\n  str.clear();\n\n  info.line = 10;\n  RenderFrame(&str, \"%F %S\", frame_no, info, false);\n  EXPECT_STREQ(\"in my_function my_file:10\", str.data());\n  str.clear();\n\n  info.column = 5;\n  RenderFrame(&str, \"%S %L\", frame_no, info, false);\n  EXPECT_STREQ(\"my_file:10:5 my_file:10:5\", str.data());\n  str.clear();\n\n  RenderFrame(&str, \"%S %L\", frame_no, info, true);\n  EXPECT_STREQ(\"my_file(10,5) my_file(10,5)\", str.data());\n  str.clear();\n\n  info.column = 0;\n  RenderFrame(&str, \"%F %S\", frame_no, info, true);\n  EXPECT_STREQ(\"in my_function my_file(10)\", str.data());\n  str.clear();\n\n  info.line = 0;\n  RenderFrame(&str, \"%F %S\", frame_no, info, true);\n  EXPECT_STREQ(\"in my_function my_file\", str.data());\n  str.clear();\n\n  info.Clear();\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc",
    "content": "//===-- sanitizer_stacktrace_test.cc --------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"gtest/gtest.h\"\n\nnamespace __sanitizer {\n\nclass FastUnwindTest : public ::testing::Test {\n protected:\n  virtual void SetUp();\n  virtual void TearDown();\n  bool TryFastUnwind(uptr max_depth) {\n    if (!StackTrace::WillUseFastUnwind(true))\n      return false;\n    trace.Unwind(max_depth, start_pc, (uptr)&fake_stack[0], 0, fake_top,\n                 fake_bottom, true);\n    return true;\n  }\n\n  void *mapping;\n  uhwptr *fake_stack;\n  const uptr fake_stack_size = 10;\n  uhwptr start_pc;\n  uhwptr fake_top;\n  uhwptr fake_bottom;\n  BufferedStackTrace trace;\n};\n\nstatic uptr PC(uptr idx) {\n  return (1<<20) + idx;\n}\n\nvoid FastUnwindTest::SetUp() {\n  size_t ps = GetPageSize();\n  mapping = MmapOrDie(2 * ps, \"FastUnwindTest\");\n  MprotectNoAccess((uptr)mapping, ps);\n\n  // Unwinder may peek 1 word down from the starting FP.\n  fake_stack = (uhwptr *)((uptr)mapping + ps + sizeof(uhwptr));\n\n  // Fill an array of pointers with fake fp+retaddr pairs.  Frame pointers have\n  // even indices.\n  for (uptr i = 0; i + 1 < fake_stack_size; i += 2) {\n    fake_stack[i] = (uptr)&fake_stack[i+2];  // fp\n    fake_stack[i+1] = PC(i + 1); // retaddr\n  }\n  // Mark the last fp point back up to terminate the stack trace.\n  fake_stack[RoundDownTo(fake_stack_size - 1, 2)] = (uhwptr)&fake_stack[0];\n\n  // Top is two slots past the end because FastUnwindStack subtracts two.\n  fake_top = (uhwptr)&fake_stack[fake_stack_size + 2];\n  // Bottom is one slot before the start because FastUnwindStack uses >.\n  fake_bottom = (uhwptr)mapping;\n  start_pc = PC(0);\n}\n\nvoid FastUnwindTest::TearDown() {\n  size_t ps = GetPageSize();\n  UnmapOrDie(mapping, 2 * ps);\n}\n\nTEST_F(FastUnwindTest, Basic) {\n  if (!TryFastUnwind(kStackTraceMax))\n    return;\n  // Should get all on-stack retaddrs and start_pc.\n  EXPECT_EQ(6U, trace.size);\n  EXPECT_EQ(start_pc, trace.trace[0]);\n  for (uptr i = 1; i <= 5; i++) {\n    EXPECT_EQ(PC(i*2 - 1), trace.trace[i]);\n  }\n}\n\n// From: http://code.google.com/p/address-sanitizer/issues/detail?id=162\nTEST_F(FastUnwindTest, FramePointerLoop) {\n  // Make one fp point to itself.\n  fake_stack[4] = (uhwptr)&fake_stack[4];\n  if (!TryFastUnwind(kStackTraceMax))\n    return;\n  // Should get all on-stack retaddrs up to the 4th slot and start_pc.\n  EXPECT_EQ(4U, trace.size);\n  EXPECT_EQ(start_pc, trace.trace[0]);\n  for (uptr i = 1; i <= 3; i++) {\n    EXPECT_EQ(PC(i*2 - 1), trace.trace[i]);\n  }\n}\n\nTEST_F(FastUnwindTest, MisalignedFramePointer) {\n  // Make one fp misaligned.\n  fake_stack[4] += 3;\n  if (!TryFastUnwind(kStackTraceMax))\n    return;\n  // Should get all on-stack retaddrs up to the 4th slot and start_pc.\n  EXPECT_EQ(4U, trace.size);\n  EXPECT_EQ(start_pc, trace.trace[0]);\n  for (uptr i = 1; i < 4U; i++) {\n    EXPECT_EQ(PC(i*2 - 1), trace.trace[i]);\n  }\n}\n\nTEST_F(FastUnwindTest, OneFrameStackTrace) {\n  if (!TryFastUnwind(1))\n    return;\n  EXPECT_EQ(1U, trace.size);\n  EXPECT_EQ(start_pc, trace.trace[0]);\n  EXPECT_EQ((uhwptr)&fake_stack[0], trace.top_frame_bp);\n}\n\nTEST_F(FastUnwindTest, ZeroFramesStackTrace) {\n  if (!TryFastUnwind(0))\n    return;\n  EXPECT_EQ(0U, trace.size);\n  EXPECT_EQ(0U, trace.top_frame_bp);\n}\n\nTEST_F(FastUnwindTest, FPBelowPrevFP) {\n  // The next FP points to unreadable memory inside the stack limits, but below\n  // current FP.\n  fake_stack[0] = (uhwptr)&fake_stack[-50];\n  fake_stack[1] = PC(1);\n  if (!TryFastUnwind(3))\n    return;\n  EXPECT_EQ(2U, trace.size);\n  EXPECT_EQ(PC(0), trace.trace[0]);\n  EXPECT_EQ(PC(1), trace.trace[1]);\n}\n\nTEST(SlowUnwindTest, ShortStackTrace) {\n  if (StackTrace::WillUseFastUnwind(false))\n    return;\n  BufferedStackTrace stack;\n  uptr pc = StackTrace::GetCurrentPc();\n  uptr bp = GET_CURRENT_FRAME();\n  stack.Unwind(0, pc, bp, 0, 0, 0, false);\n  EXPECT_EQ(0U, stack.size);\n  EXPECT_EQ(0U, stack.top_frame_bp);\n  stack.Unwind(1, pc, bp, 0, 0, 0, false);\n  EXPECT_EQ(1U, stack.size);\n  EXPECT_EQ(pc, stack.trace[0]);\n  EXPECT_EQ(bp, stack.top_frame_bp);\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cc",
    "content": "//===-- sanitizer_stoptheworld_test.cc ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Tests for sanitizer_stoptheworld.h\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_LINUX && defined(__x86_64__)\n\n#include \"sanitizer_common/sanitizer_stoptheworld.h\"\n#include \"gtest/gtest.h\"\n\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n\n#include <pthread.h>\n#include <sched.h>\n\nnamespace __sanitizer {\n\nstatic pthread_mutex_t incrementer_thread_exit_mutex;\n\nstruct CallbackArgument {\n  volatile int counter;\n  volatile bool threads_stopped;\n  volatile bool callback_executed;\n  CallbackArgument()\n    : counter(0),\n      threads_stopped(false),\n      callback_executed(false) {}\n};\n\nvoid *IncrementerThread(void *argument) {\n  CallbackArgument *callback_argument = (CallbackArgument *)argument;\n  while (true) {\n    __sync_fetch_and_add(&callback_argument->counter, 1);\n    if (pthread_mutex_trylock(&incrementer_thread_exit_mutex) == 0) {\n      pthread_mutex_unlock(&incrementer_thread_exit_mutex);\n      return NULL;\n    } else {\n      sched_yield();\n    }\n  }\n}\n\n// This callback checks that IncrementerThread is suspended at the time of its\n// execution.\nvoid Callback(const SuspendedThreadsList &suspended_threads_list,\n              void *argument) {\n  CallbackArgument *callback_argument = (CallbackArgument *)argument;\n  callback_argument->callback_executed = true;\n  int counter_at_init = __sync_fetch_and_add(&callback_argument->counter, 0);\n  for (uptr i = 0; i < 1000; i++) {\n    sched_yield();\n    if (__sync_fetch_and_add(&callback_argument->counter, 0) !=\n          counter_at_init) {\n      callback_argument->threads_stopped = false;\n      return;\n    }\n  }\n  callback_argument->threads_stopped = true;\n}\n\nTEST(StopTheWorld, SuspendThreadsSimple) {\n  pthread_mutex_init(&incrementer_thread_exit_mutex, NULL);\n  CallbackArgument argument;\n  pthread_t thread_id;\n  int pthread_create_result;\n  pthread_mutex_lock(&incrementer_thread_exit_mutex);\n  pthread_create_result = pthread_create(&thread_id, NULL, IncrementerThread,\n                                         &argument);\n  ASSERT_EQ(0, pthread_create_result);\n  StopTheWorld(&Callback, &argument);\n  pthread_mutex_unlock(&incrementer_thread_exit_mutex);\n  EXPECT_TRUE(argument.callback_executed);\n  EXPECT_TRUE(argument.threads_stopped);\n  // argument is on stack, so we have to wait for the incrementer thread to\n  // terminate before we can return from this function.\n  ASSERT_EQ(0, pthread_join(thread_id, NULL));\n  pthread_mutex_destroy(&incrementer_thread_exit_mutex);\n}\n\n// A more comprehensive test where we spawn a bunch of threads while executing\n// StopTheWorld in parallel.\nstatic const uptr kThreadCount = 50;\nstatic const uptr kStopWorldAfter = 10; // let this many threads spawn first\n\nstatic pthread_mutex_t advanced_incrementer_thread_exit_mutex;\n\nstruct AdvancedCallbackArgument {\n  volatile uptr thread_index;\n  volatile int counters[kThreadCount];\n  pthread_t thread_ids[kThreadCount];\n  volatile bool threads_stopped;\n  volatile bool callback_executed;\n  volatile bool fatal_error;\n  AdvancedCallbackArgument()\n    : thread_index(0),\n      threads_stopped(false),\n      callback_executed(false),\n      fatal_error(false) {}\n};\n\nvoid *AdvancedIncrementerThread(void *argument) {\n  AdvancedCallbackArgument *callback_argument =\n      (AdvancedCallbackArgument *)argument;\n  uptr this_thread_index = __sync_fetch_and_add(\n      &callback_argument->thread_index, 1);\n  // Spawn the next thread.\n  int pthread_create_result;\n  if (this_thread_index + 1 < kThreadCount) {\n    pthread_create_result =\n        pthread_create(&callback_argument->thread_ids[this_thread_index + 1],\n                       NULL, AdvancedIncrementerThread, argument);\n    // Cannot use ASSERT_EQ in non-void-returning functions. If there's a\n    // problem, defer failing to the main thread.\n    if (pthread_create_result != 0) {\n      callback_argument->fatal_error = true;\n      __sync_fetch_and_add(&callback_argument->thread_index,\n                           kThreadCount - callback_argument->thread_index);\n    }\n  }\n  // Do the actual work.\n  while (true) {\n    __sync_fetch_and_add(&callback_argument->counters[this_thread_index], 1);\n    if (pthread_mutex_trylock(&advanced_incrementer_thread_exit_mutex) == 0) {\n      pthread_mutex_unlock(&advanced_incrementer_thread_exit_mutex);\n      return NULL;\n    } else {\n      sched_yield();\n    }\n  }\n}\n\nvoid AdvancedCallback(const SuspendedThreadsList &suspended_threads_list,\n                             void *argument) {\n  AdvancedCallbackArgument *callback_argument =\n      (AdvancedCallbackArgument *)argument;\n  callback_argument->callback_executed = true;\n\n  int counters_at_init[kThreadCount];\n  for (uptr j = 0; j < kThreadCount; j++)\n    counters_at_init[j] = __sync_fetch_and_add(&callback_argument->counters[j],\n                                               0);\n  for (uptr i = 0; i < 10; i++) {\n    sched_yield();\n    for (uptr j = 0; j < kThreadCount; j++)\n      if (__sync_fetch_and_add(&callback_argument->counters[j], 0) !=\n            counters_at_init[j]) {\n        callback_argument->threads_stopped = false;\n        return;\n      }\n  }\n  callback_argument->threads_stopped = true;\n}\n\nTEST(StopTheWorld, SuspendThreadsAdvanced) {\n  pthread_mutex_init(&advanced_incrementer_thread_exit_mutex, NULL);\n  AdvancedCallbackArgument argument;\n\n  pthread_mutex_lock(&advanced_incrementer_thread_exit_mutex);\n  int pthread_create_result;\n  pthread_create_result = pthread_create(&argument.thread_ids[0], NULL,\n                                         AdvancedIncrementerThread,\n                                         &argument);\n  ASSERT_EQ(0, pthread_create_result);\n  // Wait for several threads to spawn before proceeding.\n  while (__sync_fetch_and_add(&argument.thread_index, 0) < kStopWorldAfter)\n    sched_yield();\n  StopTheWorld(&AdvancedCallback, &argument);\n  EXPECT_TRUE(argument.callback_executed);\n  EXPECT_TRUE(argument.threads_stopped);\n\n  // Wait for all threads to spawn before we start terminating them.\n  while (__sync_fetch_and_add(&argument.thread_index, 0) < kThreadCount)\n    sched_yield();\n  ASSERT_FALSE(argument.fatal_error); // a pthread_create has failed\n  // Signal the threads to terminate.\n  pthread_mutex_unlock(&advanced_incrementer_thread_exit_mutex);\n  for (uptr i = 0; i < kThreadCount; i++)\n    ASSERT_EQ(0, pthread_join(argument.thread_ids[i], NULL));\n  pthread_mutex_destroy(&advanced_incrementer_thread_exit_mutex);\n}\n\nstatic void SegvCallback(const SuspendedThreadsList &suspended_threads_list,\n                         void *argument) {\n  *(volatile int*)0x1234 = 0;\n}\n\nTEST(StopTheWorld, SegvInCallback) {\n  // Test that tracer thread catches SIGSEGV.\n  StopTheWorld(&SegvCallback, NULL);\n}\n\n}  // namespace __sanitizer\n\n#endif  // SANITIZER_LINUX && defined(__x86_64__)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_stoptheworld_testlib.cc",
    "content": "//===-- sanitizer_stoptheworld_testlib.cc ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// Dynamic library to test StopTheWorld functionality.\n// When loaded with LD_PRELOAD, it will periodically suspend all threads.\n//===----------------------------------------------------------------------===//\n/* Usage:\nclang++ -fno-exceptions -g -fPIC -I. \\\n sanitizer_common/tests/sanitizer_stoptheworld_testlib.cc \\\n sanitizer_common/sanitizer_*.cc -shared -lpthread -o teststoptheworld.so\nLD_PRELOAD=`pwd`/teststoptheworld.so /your/app\n*/\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_LINUX\n\n#include <dlfcn.h>\n#include <stddef.h>\n#include <stdio.h>\n#include <pthread.h>\n#include <unistd.h>\n\n#include \"sanitizer_common/sanitizer_stoptheworld.h\"\n\nnamespace {\nconst uptr kSuspendDuration = 3;\nconst uptr kRunDuration = 3;\n\nvoid Callback(const SuspendedThreadsList &suspended_threads_list,\n              void *argument) {\n  sleep(kSuspendDuration);\n}\n\nvoid *SuspenderThread(void *argument) {\n  while (true) {\n    sleep(kRunDuration);\n    StopTheWorld(Callback, NULL);\n  }\n  return NULL;\n}\n\n__attribute__((constructor)) void StopTheWorldTestLibConstructor(void) {\n  pthread_t thread_id;\n  pthread_create(&thread_id, NULL, SuspenderThread, NULL);\n}\n}  // namespace\n\n#endif  // SANITIZER_LINUX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc",
    "content": "//===-- sanitizer_suppressions_test.cc ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_suppressions.h\"\n#include \"gtest/gtest.h\"\n\n#include <string.h>\n\nnamespace __sanitizer {\n\nstatic bool MyMatch(const char *templ, const char *func) {\n  char tmp[1024];\n  strcpy(tmp, templ);  // NOLINT\n  return TemplateMatch(tmp, func);\n}\n\nTEST(Suppressions, Match) {\n  EXPECT_TRUE(MyMatch(\"foobar$\", \"foobar\"));\n\n  EXPECT_TRUE(MyMatch(\"foobar\", \"foobar\"));\n  EXPECT_TRUE(MyMatch(\"*foobar*\", \"foobar\"));\n  EXPECT_TRUE(MyMatch(\"foobar\", \"prefix_foobar_postfix\"));\n  EXPECT_TRUE(MyMatch(\"*foobar*\", \"prefix_foobar_postfix\"));\n  EXPECT_TRUE(MyMatch(\"foo*bar\", \"foo_middle_bar\"));\n  EXPECT_TRUE(MyMatch(\"foo*bar\", \"foobar\"));\n  EXPECT_TRUE(MyMatch(\"foo*bar*baz\", \"foo_middle_bar_another_baz\"));\n  EXPECT_TRUE(MyMatch(\"foo*bar*baz\", \"foo_middle_barbaz\"));\n  EXPECT_TRUE(MyMatch(\"^foobar\", \"foobar\"));\n  EXPECT_TRUE(MyMatch(\"^foobar\", \"foobar_postfix\"));\n  EXPECT_TRUE(MyMatch(\"^*foobar\", \"foobar\"));\n  EXPECT_TRUE(MyMatch(\"^*foobar\", \"prefix_foobar\"));\n  EXPECT_TRUE(MyMatch(\"foobar$\", \"foobar\"));\n  EXPECT_TRUE(MyMatch(\"foobar$\", \"prefix_foobar\"));\n  EXPECT_TRUE(MyMatch(\"*foobar*$\", \"foobar\"));\n  EXPECT_TRUE(MyMatch(\"*foobar*$\", \"foobar_postfix\"));\n  EXPECT_TRUE(MyMatch(\"^foobar$\", \"foobar\"));\n\n  EXPECT_FALSE(MyMatch(\"foo\", \"baz\"));\n  EXPECT_FALSE(MyMatch(\"foobarbaz\", \"foobar\"));\n  EXPECT_FALSE(MyMatch(\"foobarbaz\", \"barbaz\"));\n  EXPECT_FALSE(MyMatch(\"foo*bar\", \"foobaz\"));\n  EXPECT_FALSE(MyMatch(\"foo*bar\", \"foo_baz\"));\n  EXPECT_FALSE(MyMatch(\"^foobar\", \"prefix_foobar\"));\n  EXPECT_FALSE(MyMatch(\"foobar$\", \"foobar_postfix\"));\n  EXPECT_FALSE(MyMatch(\"^foobar$\", \"prefix_foobar\"));\n  EXPECT_FALSE(MyMatch(\"^foobar$\", \"foobar_postfix\"));\n  EXPECT_FALSE(MyMatch(\"foo^bar\", \"foobar\"));\n  EXPECT_FALSE(MyMatch(\"foo$bar\", \"foobar\"));\n  EXPECT_FALSE(MyMatch(\"foo$^bar\", \"foobar\"));\n}\n\nstatic const char *kTestSuppressionTypes[] = {\"race\", \"thread\", \"mutex\",\n                                              \"signal\"};\n\nclass SuppressionContextTest : public ::testing::Test {\n public:\n  SuppressionContextTest()\n      : ctx_(kTestSuppressionTypes, ARRAY_SIZE(kTestSuppressionTypes)) {}\n\n protected:\n  SuppressionContext ctx_;\n\n  void CheckSuppressions(unsigned count, std::vector<const char *> types,\n                         std::vector<const char *> templs) const {\n    EXPECT_EQ(count, ctx_.SuppressionCount());\n    for (unsigned i = 0; i < count; i++) {\n      const Suppression *s = ctx_.SuppressionAt(i);\n      EXPECT_STREQ(types[i], s->type);\n      EXPECT_STREQ(templs[i], s->templ);\n    }\n  }\n};\n\nTEST_F(SuppressionContextTest, Parse) {\n  ctx_.Parse(\"race:foo\\n\"\n             \" \trace:bar\\n\"  // NOLINT\n             \"race:baz\t \\n\" // NOLINT\n             \"# a comment\\n\"\n             \"race:quz\\n\"); // NOLINT\n  CheckSuppressions(4, {\"race\", \"race\", \"race\", \"race\"},\n                    {\"foo\", \"bar\", \"baz\", \"quz\"});\n}\n\nTEST_F(SuppressionContextTest, Parse2) {\n  ctx_.Parse(\n    \"  \t# first line comment\\n\"  // NOLINT\n    \" \trace:bar \t\\n\"  // NOLINT\n    \"race:baz* *baz\\n\"\n    \"# a comment\\n\"\n    \"# last line comment\\n\"\n  );  // NOLINT\n  CheckSuppressions(2, {\"race\", \"race\"}, {\"bar\", \"baz* *baz\"});\n}\n\nTEST_F(SuppressionContextTest, Parse3) {\n  ctx_.Parse(\n    \"# last suppression w/o line-feed\\n\"\n    \"race:foo\\n\"\n    \"race:bar\"\n  );  // NOLINT\n  CheckSuppressions(2, {\"race\", \"race\"}, {\"foo\", \"bar\"});\n}\n\nTEST_F(SuppressionContextTest, ParseType) {\n  ctx_.Parse(\n    \"race:foo\\n\"\n    \"thread:bar\\n\"\n    \"mutex:baz\\n\"\n    \"signal:quz\\n\"\n  );  // NOLINT\n  CheckSuppressions(4, {\"race\", \"thread\", \"mutex\", \"signal\"},\n                    {\"foo\", \"bar\", \"baz\", \"quz\"});\n}\n\nTEST_F(SuppressionContextTest, HasSuppressionType) {\n  ctx_.Parse(\n    \"race:foo\\n\"\n    \"thread:bar\\n\");\n  EXPECT_TRUE(ctx_.HasSuppressionType(\"race\"));\n  EXPECT_TRUE(ctx_.HasSuppressionType(\"thread\"));\n  EXPECT_FALSE(ctx_.HasSuppressionType(\"mutex\"));\n  EXPECT_FALSE(ctx_.HasSuppressionType(\"signal\"));\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc",
    "content": "//===-- sanitizer_symbolizer_test.cc --------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Tests for sanitizer_symbolizer.h and sanitizer_symbolizer_internal.h\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_allocator_internal.h\"\n#include \"sanitizer_common/sanitizer_symbolizer_internal.h\"\n#include \"gtest/gtest.h\"\n\nnamespace __sanitizer {\n\nTEST(Symbolizer, ExtractToken) {\n  char *token;\n  const char *rest;\n\n  rest = ExtractToken(\"a;b;c\", \";\", &token);\n  EXPECT_STREQ(\"a\", token);\n  EXPECT_STREQ(\"b;c\", rest);\n  InternalFree(token);\n\n  rest = ExtractToken(\"aaa-bbb.ccc\", \";.-*\", &token);\n  EXPECT_STREQ(\"aaa\", token);\n  EXPECT_STREQ(\"bbb.ccc\", rest);\n  InternalFree(token);\n}\n\nTEST(Symbolizer, ExtractInt) {\n  int token;\n  const char *rest = ExtractInt(\"123,456;789\", \";,\", &token);\n  EXPECT_EQ(123, token);\n  EXPECT_STREQ(\"456;789\", rest);\n}\n\nTEST(Symbolizer, ExtractUptr) {\n  uptr token;\n  const char *rest = ExtractUptr(\"123,456;789\", \";,\", &token);\n  EXPECT_EQ(123U, token);\n  EXPECT_STREQ(\"456;789\", rest);\n}\n\nTEST(Symbolizer, ExtractTokenUpToDelimiter) {\n  char *token;\n  const char *rest =\n      ExtractTokenUpToDelimiter(\"aaa-+-bbb-+-ccc\", \"-+-\", &token);\n  EXPECT_STREQ(\"aaa\", token);\n  EXPECT_STREQ(\"bbb-+-ccc\", rest);\n  InternalFree(token);\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_test_config.h",
    "content": "//===-- sanitizer_test_config.h ---------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of *Sanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n#if !defined(INCLUDED_FROM_SANITIZER_TEST_UTILS_H)\n# error \"This file should be included into sanitizer_test_utils.h only\"\n#endif\n\n#ifndef SANITIZER_TEST_CONFIG_H\n#define SANITIZER_TEST_CONFIG_H\n\n#include <vector>\n#include <string>\n#include <map>\n\n#if SANITIZER_USE_DEJAGNU_GTEST\n# include \"dejagnu-gtest.h\"\n#else\n# include \"gtest/gtest.h\"\n#endif\n\n#endif  // SANITIZER_TEST_CONFIG_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_test_main.cc",
    "content": "//===-- sanitizer_test_main.cc --------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer/AddressSanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n#include \"gtest/gtest.h\"\n\nconst char *argv0;\n\nint main(int argc, char **argv) {\n  argv0 = argv[0];\n  testing::GTEST_FLAG(death_test_style) = \"threadsafe\";\n  testing::InitGoogleTest(&argc, argv);\n  return RUN_ALL_TESTS();\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_test_utils.h",
    "content": "//===-- sanitizer_test_utils.h ----------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of *Sanitizer runtime.\n// Common unit tests utilities.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef SANITIZER_TEST_UTILS_H\n#define SANITIZER_TEST_UTILS_H\n\n#if defined(_WIN32)\n// <windows.h> should always be the first include on Windows.\n# include <windows.h>\n// MSVS headers define max/min as macros, so std::max/min gets crazy.\n# undef max\n# undef min\n#endif\n\n#if !defined(SANITIZER_EXTERNAL_TEST_CONFIG)\n# define INCLUDED_FROM_SANITIZER_TEST_UTILS_H\n# include \"sanitizer_test_config.h\"\n# undef INCLUDED_FROM_SANITIZER_TEST_UTILS_H\n#endif\n\n#include <stdint.h>\n\n#if defined(_MSC_VER)\n# define NOINLINE __declspec(noinline)\n#else  // defined(_MSC_VER)\n# define NOINLINE __attribute__((noinline))\n#endif  // defined(_MSC_VER)\n\n#if !defined(_MSC_VER) || defined(__clang__)\n# define UNUSED __attribute__((unused))\n# define USED __attribute__((used))\n#else\n# define UNUSED\n# define USED\n#endif\n\n#if !defined(__has_feature)\n#define __has_feature(x) 0\n#endif\n\n#ifndef ATTRIBUTE_NO_SANITIZE_ADDRESS\n# if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)\n#  define ATTRIBUTE_NO_SANITIZE_ADDRESS \\\n    __attribute__((no_sanitize_address))\n# else\n#  define ATTRIBUTE_NO_SANITIZE_ADDRESS\n# endif\n#endif  // ATTRIBUTE_NO_SANITIZE_ADDRESS\n\n#if __LP64__ || defined(_WIN64)\n#  define SANITIZER_WORDSIZE 64\n#else\n#  define SANITIZER_WORDSIZE 32\n#endif\n\n// Make the compiler thinks that something is going on there.\ninline void break_optimization(void *arg) {\n#if !defined(_WIN32) || defined(__clang__)\n  __asm__ __volatile__(\"\" : : \"r\" (arg) : \"memory\");\n#endif\n}\n\n// This function returns its parameter but in such a way that compiler\n// can not prove it.\ntemplate<class T>\nNOINLINE\nstatic T Ident(T t) {\n  T ret = t;\n  break_optimization(&ret);\n  return ret;\n}\n\n// Simple stand-alone pseudorandom number generator.\n// Current algorithm is ANSI C linear congruential PRNG.\nstatic inline uint32_t my_rand_r(uint32_t* state) {\n  return (*state = *state * 1103515245 + 12345) >> 16;\n}\n\nstatic uint32_t global_seed = 0;\n\nstatic inline uint32_t my_rand() {\n  return my_rand_r(&global_seed);\n}\n\n// Set availability of platform-specific functions.\n\n#if !defined(__APPLE__) && !defined(__ANDROID__) && !defined(_WIN32)\n# define SANITIZER_TEST_HAS_POSIX_MEMALIGN 1\n#else\n# define SANITIZER_TEST_HAS_POSIX_MEMALIGN 0\n#endif\n\n#if !defined(__APPLE__) && !defined(__FreeBSD__) && \\\n    !defined(__ANDROID__) && !defined(_WIN32)\n# define SANITIZER_TEST_HAS_MEMALIGN 1\n# define SANITIZER_TEST_HAS_PVALLOC 1\n# define SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE 1\n#else\n# define SANITIZER_TEST_HAS_MEMALIGN 0\n# define SANITIZER_TEST_HAS_PVALLOC 0\n# define SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE 0\n#endif\n\n#if !defined(__APPLE__)\n# define SANITIZER_TEST_HAS_STRNLEN 1\n#else\n# define SANITIZER_TEST_HAS_STRNLEN 0\n#endif\n\n#if defined(__FreeBSD__)\n# define SANITIZER_TEST_HAS_PRINTF_L 1\n#else\n# define SANITIZER_TEST_HAS_PRINTF_L 0\n#endif\n\n#endif  // SANITIZER_TEST_UTILS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/sanitizer_thread_registry_test.cc",
    "content": "//===-- sanitizer_thread_registry_test.cc ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of shared sanitizer runtime.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_thread_registry.h\"\n\n#include \"sanitizer_pthread_wrappers.h\"\n\n#include \"gtest/gtest.h\"\n\n#include <vector>\n\nnamespace __sanitizer {\n\nstatic BlockingMutex tctx_allocator_lock(LINKER_INITIALIZED);\nstatic LowLevelAllocator tctx_allocator;\n\ntemplate<typename TCTX>\nstatic ThreadContextBase *GetThreadContext(u32 tid) {\n  BlockingMutexLock l(&tctx_allocator_lock);\n  return new(tctx_allocator) TCTX(tid);\n}\n\nstatic const u32 kMaxRegistryThreads = 1000;\nstatic const u32 kRegistryQuarantine = 2;\n\nstatic void CheckThreadQuantity(ThreadRegistry *registry, uptr exp_total,\n                                uptr exp_running, uptr exp_alive) {\n  uptr total, running, alive;\n  registry->GetNumberOfThreads(&total, &running, &alive);\n  EXPECT_EQ(exp_total, total);\n  EXPECT_EQ(exp_running, running);\n  EXPECT_EQ(exp_alive, alive);\n}\n\nstatic bool is_detached(u32 tid) {\n  return (tid % 2 == 0);\n}\n\nstatic uptr get_uid(u32 tid) {\n  return tid * 2;\n}\n\nstatic bool HasName(ThreadContextBase *tctx, void *arg) {\n  char *name = (char*)arg;\n  return (0 == internal_strcmp(tctx->name, name));\n}\n\nstatic bool HasUid(ThreadContextBase *tctx, void *arg) {\n  uptr uid = (uptr)arg;\n  return (tctx->user_id == uid);\n}\n\nstatic void MarkUidAsPresent(ThreadContextBase *tctx, void *arg) {\n  bool *arr = (bool*)arg;\n  arr[tctx->tid] = true;\n}\n\nstatic void TestRegistry(ThreadRegistry *registry, bool has_quarantine) {\n  // Create and start a main thread.\n  EXPECT_EQ(0U, registry->CreateThread(get_uid(0), true, -1, 0));\n  registry->StartThread(0, 0, 0);\n  // Create a bunch of threads.\n  for (u32 i = 1; i <= 10; i++) {\n    EXPECT_EQ(i, registry->CreateThread(get_uid(i), is_detached(i), 0, 0));\n  }\n  CheckThreadQuantity(registry, 11, 1, 11);\n  // Start some of them.\n  for (u32 i = 1; i <= 5; i++) {\n    registry->StartThread(i, 0, 0);\n  }\n  CheckThreadQuantity(registry, 11, 6, 11);\n  // Finish, create and start more threads.\n  for (u32 i = 1; i <= 5; i++) {\n    registry->FinishThread(i);\n    if (!is_detached(i))\n      registry->JoinThread(i, 0);\n  }\n  for (u32 i = 6; i <= 10; i++) {\n    registry->StartThread(i, 0, 0);\n  }\n  std::vector<u32> new_tids;\n  for (u32 i = 11; i <= 15; i++) {\n    new_tids.push_back(\n        registry->CreateThread(get_uid(i), is_detached(i), 0, 0));\n  }\n  ASSERT_LE(kRegistryQuarantine, 5U);\n  u32 exp_total = 16 - (has_quarantine ? 5 - kRegistryQuarantine  : 0);\n  CheckThreadQuantity(registry, exp_total, 6, 11);\n  // Test SetThreadName and FindThread.\n  registry->SetThreadName(6, \"six\");\n  registry->SetThreadName(7, \"seven\");\n  EXPECT_EQ(7U, registry->FindThread(HasName, (void*)\"seven\"));\n  EXPECT_EQ(ThreadRegistry::kUnknownTid,\n            registry->FindThread(HasName, (void*)\"none\"));\n  EXPECT_EQ(0U, registry->FindThread(HasUid, (void*)get_uid(0)));\n  EXPECT_EQ(10U, registry->FindThread(HasUid, (void*)get_uid(10)));\n  EXPECT_EQ(ThreadRegistry::kUnknownTid,\n            registry->FindThread(HasUid, (void*)0x1234));\n  // Detach and finish and join remaining threads.\n  for (u32 i = 6; i <= 10; i++) {\n    registry->DetachThread(i, 0);\n    registry->FinishThread(i);\n  }\n  for (u32 i = 0; i < new_tids.size(); i++) {\n    u32 tid = new_tids[i];\n    registry->StartThread(tid, 0, 0);\n    registry->DetachThread(tid, 0);\n    registry->FinishThread(tid);\n  }\n  CheckThreadQuantity(registry, exp_total, 1, 1);\n  // Test methods that require the caller to hold a ThreadRegistryLock.\n  bool has_tid[16];\n  internal_memset(&has_tid[0], 0, sizeof(has_tid));\n  {\n    ThreadRegistryLock l(registry);\n    registry->RunCallbackForEachThreadLocked(MarkUidAsPresent, &has_tid[0]);\n  }\n  for (u32 i = 0; i < exp_total; i++) {\n    EXPECT_TRUE(has_tid[i]);\n  }\n  {\n    ThreadRegistryLock l(registry);\n    registry->CheckLocked();\n    ThreadContextBase *main_thread = registry->GetThreadLocked(0);\n    EXPECT_EQ(main_thread, registry->FindThreadContextLocked(\n        HasUid, (void*)get_uid(0)));\n  }\n  EXPECT_EQ(11U, registry->GetMaxAliveThreads());\n}\n\nTEST(SanitizerCommon, ThreadRegistryTest) {\n  ThreadRegistry quarantine_registry(GetThreadContext<ThreadContextBase>,\n                                     kMaxRegistryThreads,\n                                     kRegistryQuarantine);\n  TestRegistry(&quarantine_registry, true);\n\n  ThreadRegistry no_quarantine_registry(GetThreadContext<ThreadContextBase>,\n                                        kMaxRegistryThreads,\n                                        kMaxRegistryThreads);\n  TestRegistry(&no_quarantine_registry, false);\n}\n\nstatic const int kThreadsPerShard = 20;\nstatic const int kNumShards = 25;\n\nstatic int num_created[kNumShards + 1];\nstatic int num_started[kNumShards + 1];\nstatic int num_joined[kNumShards + 1];\n\nnamespace {\n\nstruct RunThreadArgs {\n  ThreadRegistry *registry;\n  uptr shard;  // started from 1.\n};\n\nclass TestThreadContext : public ThreadContextBase {\n public:\n  explicit TestThreadContext(int tid) : ThreadContextBase(tid) {}\n  void OnJoined(void *arg) {\n    uptr shard = (uptr)arg;\n    num_joined[shard]++;\n  }\n  void OnStarted(void *arg) {\n    uptr shard = (uptr)arg;\n    num_started[shard]++;\n  }\n  void OnCreated(void *arg) {\n    uptr shard = (uptr)arg;\n    num_created[shard]++;\n  }\n};\n\n}  // namespace\n\nvoid *RunThread(void *arg) {\n  RunThreadArgs *args = static_cast<RunThreadArgs*>(arg);\n  std::vector<int> tids;\n  for (int i = 0; i < kThreadsPerShard; i++)\n    tids.push_back(\n        args->registry->CreateThread(0, false, 0, (void*)args->shard));\n  for (int i = 0; i < kThreadsPerShard; i++)\n    args->registry->StartThread(tids[i], 0, (void*)args->shard);\n  for (int i = 0; i < kThreadsPerShard; i++)\n    args->registry->FinishThread(tids[i]);\n  for (int i = 0; i < kThreadsPerShard; i++)\n    args->registry->JoinThread(tids[i], (void*)args->shard);\n  return 0;\n}\n\nstatic void ThreadedTestRegistry(ThreadRegistry *registry) {\n  // Create and start a main thread.\n  EXPECT_EQ(0U, registry->CreateThread(0, true, -1, 0));\n  registry->StartThread(0, 0, 0);\n  pthread_t threads[kNumShards];\n  RunThreadArgs args[kNumShards];\n  for (int i = 0; i < kNumShards; i++) {\n    args[i].registry = registry;\n    args[i].shard = i + 1;\n    PTHREAD_CREATE(&threads[i], 0, RunThread, &args[i]);\n  }\n  for (int i = 0; i < kNumShards; i++) {\n    PTHREAD_JOIN(threads[i], 0);\n  }\n  // Check that each thread created/started/joined correct amount\n  // of \"threads\" in thread_registry.\n  EXPECT_EQ(1, num_created[0]);\n  EXPECT_EQ(1, num_started[0]);\n  EXPECT_EQ(0, num_joined[0]);\n  for (int i = 1; i <= kNumShards; i++) {\n    EXPECT_EQ(kThreadsPerShard, num_created[i]);\n    EXPECT_EQ(kThreadsPerShard, num_started[i]);\n    EXPECT_EQ(kThreadsPerShard, num_joined[i]);\n  }\n}\n\nTEST(SanitizerCommon, ThreadRegistryThreadedTest) {\n  ThreadRegistry registry(GetThreadContext<TestThreadContext>,\n                          kThreadsPerShard * kNumShards + 1, 10);\n  ThreadedTestRegistry(&registry);\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/sanitizer_common/tests/standalone_malloc_test.cc",
    "content": "#include <stdio.h>\n#include <vector>\n#include <pthread.h>\n#include <malloc.h>\n#include <algorithm>\n\nusing namespace std;\n\nconst size_t kNumThreds = 16;\nconst size_t kNumIters = 1 << 23;\n\ninline void break_optimization(void *arg) {\n  __asm__ __volatile__(\"\" : : \"r\" (arg) : \"memory\");\n}\n\n__attribute__((noinline))\nstatic void *MallocThread(void *t) {\n  size_t total_malloced = 0, total_freed = 0;\n  size_t max_in_use = 0;\n  size_t tid = reinterpret_cast<size_t>(t);\n  vector<pair<char *, size_t> > allocated;\n  allocated.reserve(kNumIters);\n  for (size_t i = 1; i < kNumIters; i++) {\n    if ((i % (kNumIters / 4)) == 0 && tid == 0)\n      fprintf(stderr, \"   T[%ld] iter %ld\\n\", tid, i);\n    bool allocate = (i % 5) <= 2;  // 60% malloc, 40% free\n    if (i > kNumIters / 4)\n      allocate = i % 2;  // then switch to 50% malloc, 50% free\n    if (allocate) {\n      size_t size = 1 + (i % 200);\n      if ((i % 10001) == 0)\n        size *= 4096;\n      total_malloced += size;\n      char *x = new char[size];\n      x[0] = x[size - 1] = x[size / 2] = 0;\n      allocated.push_back(make_pair(x, size));\n      max_in_use = max(max_in_use, total_malloced - total_freed);\n    } else {\n      if (allocated.empty()) continue;\n      size_t slot = i % allocated.size();\n      char *p = allocated[slot].first;\n      p[0] = 0;  // emulate last user touch of the block\n      size_t size = allocated[slot].second;\n      total_freed += size;\n      swap(allocated[slot], allocated.back());\n      allocated.pop_back();\n      delete [] p;\n    }\n  }\n  if (tid == 0)\n    fprintf(stderr, \"   T[%ld] total_malloced: %ldM in use %ldM max %ldM\\n\",\n           tid, total_malloced >> 20, (total_malloced - total_freed) >> 20,\n           max_in_use >> 20);\n  for (size_t i = 0; i < allocated.size(); i++)\n    delete [] allocated[i].first;\n  return 0;\n}\n\ntemplate <int depth>\nstruct DeepStack {\n  __attribute__((noinline))\n  static void *run(void *t) {\n    break_optimization(0);\n    DeepStack<depth - 1>::run(t);\n    break_optimization(0);\n    return 0;\n  }\n};\n\ntemplate<>\nstruct DeepStack<0> {\n  static void *run(void *t) {\n    MallocThread(t);\n    return 0;\n  }\n};\n\n// Build with -Dstandalone_malloc_test=main to make it a separate program.\nint standalone_malloc_test() {\n  pthread_t t[kNumThreds];\n  for (size_t i = 0; i < kNumThreds; i++)\n    pthread_create(&t[i], 0, DeepStack<200>::run, reinterpret_cast<void *>(i));\n  for (size_t i = 0; i < kNumThreds; i++)\n    pthread_join(t[i], 0);\n  malloc_stats();\n  return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/.clang-format",
    "content": "BasedOnStyle: Google\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/Android.mk",
    "content": "#\n# Copyright (C) 2015 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n#\n\nLOCAL_PATH:= $(call my-dir)\n\nifeq ($(HOST_OS),linux)\nifeq ($(HOST_ARCH),x86_64)\n\ntsan_rtl_files := \\\n  rtl/tsan_clock.cc \\\n  rtl/tsan_flags.cc \\\n  rtl/tsan_fd.cc \\\n  rtl/tsan_ignoreset.cc \\\n  rtl/tsan_interceptors.cc \\\n  rtl/tsan_interface_ann.cc \\\n  rtl/tsan_interface_atomic.cc \\\n  rtl/tsan_interface.cc \\\n  rtl/tsan_interface_java.cc \\\n  rtl/tsan_md5.cc \\\n  rtl/tsan_mman.cc \\\n  rtl/tsan_mutex.cc \\\n  rtl/tsan_mutexset.cc \\\n  rtl/tsan_report.cc \\\n  rtl/tsan_rtl.cc \\\n  rtl/tsan_rtl_mutex.cc \\\n  rtl/tsan_rtl_report.cc \\\n  rtl/tsan_rtl_thread.cc \\\n  rtl/tsan_stack_trace.cc \\\n  rtl/tsan_stat.cc \\\n  rtl/tsan_suppressions.cc \\\n  rtl/tsan_symbolize.cc \\\n  rtl/tsan_sync.cc \\\n  rtl/tsan_platform_linux.cc \\\n  rtl/tsan_platform_posix.cc \\\n  rtl/tsan_rtl_amd64.S \\\n\ntsan_rtl_cppflags := -std=c++11 -Wall -Werror -Wno-unused-parameter -Wno-non-virtual-dtor \\\n                     -fno-rtti -fno-builtin\n\ntsan_rtl_c_includes := \\\n  $(LOCAL_PATH)/.. \\\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libtsan\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_C_INCLUDES := $(tsan_rtl_c_includes)\nLOCAL_CPPFLAGS := $(tsan_rtl_cppflags)\nLOCAL_SRC_FILES := $(tsan_rtl_files)\nLOCAL_CXX_STL := none\nLOCAL_SANITIZE := never\nLOCAL_MULTILIB := 64\nLOCAL_WHOLE_STATIC_LIBRARIES := libinterception libsan libubsan\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libtsan_cxx\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_C_INCLUDES = $(tsan_rtl_c_includes)\nLOCAL_CPPFLAGS := $(tsan_rtl_cppflags)\nLOCAL_SRC_FILES := rtl/tsan_new_delete.cc\nLOCAL_CXX_STL := none\nLOCAL_SANITIZE := never\nLOCAL_MULTILIB := 64\nLOCAL_WHOLE_STATIC_LIBRARIES := libubsan_cxx\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\ntsan_unit_test_src_files := \\\n  tests/unit/tsan_clock_test.cc \\\n  tests/unit/tsan_dense_alloc_test.cc \\\n  tests/unit/tsan_flags_test.cc \\\n  tests/unit/tsan_mman_test.cc \\\n  tests/unit/tsan_mutex_test.cc \\\n  tests/unit/tsan_mutexset_test.cc \\\n  tests/unit/tsan_shadow_test.cc \\\n  tests/unit/tsan_stack_test.cc \\\n  tests/unit/tsan_sync_test.cc \\\n  tests/unit/tsan_unit_test_main.cc \\\n  tests/unit/tsan_vector_test.cc \\\n\ntsan_unit_test_c_includes := \\\n  $(LOCAL_PATH)/rtl \\\n  $(LOCAL_PATH)/.. \\\n\nifneq (true,$(SKIP_LLVM_TESTS))\nifndef SANITIZE_HOST\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libtsan_unit_test\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_C_INCLUDES := $(tsan_unit_test_c_includes)\nLOCAL_CPPFLAGS := $(tsan_rtl_cppflags)\nLOCAL_SRC_FILES := $(tsan_unit_test_src_files)\nLOCAL_SANITIZE := never\nLOCAL_MULTILIB := 64\nLOCAL_STATIC_LIBRARIES := libtsan libubsan\nLOCAL_LDLIBS := -lrt -ldl\ninclude $(BUILD_HOST_NATIVE_TEST)\n\n\ntsan_rtl_test_src_files := \\\n  tests/rtl/tsan_bench.cc \\\n  tests/rtl/tsan_mop.cc \\\n  tests/rtl/tsan_mutex.cc \\\n  tests/rtl/tsan_posix.cc \\\n  tests/rtl/tsan_string.cc \\\n  tests/rtl/tsan_test_util_posix.cc \\\n  tests/rtl/tsan_test.cc \\\n  tests/rtl/tsan_thread.cc \\\n\ntsan_rtl_test_c_includes := \\\n  $(LOCAL_PATH)/rtl \\\n  $(LOCAL_PATH)/.. \\\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libtsan_rtl_test\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_C_INCLUDES := $(tsan_rtl_test_c_includes)\nLOCAL_CPPFLAGS := $(tsan_rtl_cppflags)\nLOCAL_SRC_FILES := $(tsan_rtl_test_src_files)\nLOCAL_SANITIZE := never\nLOCAL_MULTILIB := 64\nLOCAL_STATIC_LIBRARIES := libtsan libubsan\nLOCAL_LDLIBS := -lrt -ldl\ninclude $(BUILD_HOST_NATIVE_TEST)\n\nendif # SANITIZE_HOST\nendif # SKIP_LLVM_TESTS\n\nendif  # ifeq ($(HOST_ARCH),x86_64)\nendif  # ifeq ($(HOST_OS),linux)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/CMakeLists.txt",
    "content": "# Build for the ThreadSanitizer runtime support library.\n\ninclude_directories(..)\n\nset(TSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})\n# SANITIZER_COMMON_CFLAGS contains -fPIC, but it's performance-critical for\n# TSan runtime to be built with -fPIE to reduce the number of register spills.\nappend_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE TSAN_CFLAGS)\nappend_no_rtti_flag(TSAN_CFLAGS)\n\nif(COMPILER_RT_TSAN_DEBUG_OUTPUT)\n  # Add extra debug information to TSan runtime. This configuration is rarely\n  # used, but we need to support it so that debug output will not bitrot.\n  list(APPEND TSAN_CFLAGS -DTSAN_COLLECT_STATS=1\n                          -DTSAN_DEBUG_OUTPUT=2)\nendif()\n\nset(TSAN_RTL_CFLAGS ${TSAN_CFLAGS})\nappend_list_if(COMPILER_RT_HAS_MSSE3_FLAG -msse3 TSAN_RTL_CFLAGS)\nappend_list_if(SANITIZER_LIMIT_FRAME_SIZE -Wframe-larger-than=512\n               TSAN_RTL_CFLAGS)\nappend_list_if(COMPILER_RT_HAS_WGLOBAL_CONSTRUCTORS_FLAG -Wglobal-constructors\n               TSAN_RTL_CFLAGS)\n\nset(TSAN_SOURCES\n  rtl/tsan_clock.cc\n  rtl/tsan_flags.cc\n  rtl/tsan_fd.cc\n  rtl/tsan_ignoreset.cc\n  rtl/tsan_interceptors.cc\n  rtl/tsan_interface_ann.cc\n  rtl/tsan_interface_atomic.cc\n  rtl/tsan_interface.cc\n  rtl/tsan_interface_java.cc\n  rtl/tsan_malloc_mac.cc\n  rtl/tsan_md5.cc\n  rtl/tsan_mman.cc\n  rtl/tsan_mutex.cc\n  rtl/tsan_mutexset.cc\n  rtl/tsan_report.cc\n  rtl/tsan_rtl.cc\n  rtl/tsan_rtl_mutex.cc\n  rtl/tsan_rtl_report.cc\n  rtl/tsan_rtl_thread.cc\n  rtl/tsan_stack_trace.cc\n  rtl/tsan_stat.cc\n  rtl/tsan_suppressions.cc\n  rtl/tsan_symbolize.cc\n  rtl/tsan_sync.cc)\n\nset(TSAN_CXX_SOURCES\n  rtl/tsan_new_delete.cc)\n\nif(APPLE)\n  list(APPEND TSAN_SOURCES\n    rtl/tsan_interceptors_mac.cc\n    rtl/tsan_libdispatch_mac.cc\n    rtl/tsan_platform_mac.cc\n    rtl/tsan_platform_posix.cc)\nelseif(UNIX)\n  # Assume Linux\n  list(APPEND TSAN_SOURCES\n    rtl/tsan_platform_linux.cc\n    rtl/tsan_platform_posix.cc)\nendif()\n\nset(TSAN_HEADERS\n  rtl/tsan_clock.h\n  rtl/tsan_defs.h\n  rtl/tsan_dense_alloc.h\n  rtl/tsan_fd.h\n  rtl/tsan_flags.h\n  rtl/tsan_flags.inc\n  rtl/tsan_ignoreset.h\n  rtl/tsan_interceptors.h\n  rtl/tsan_interface_ann.h\n  rtl/tsan_interface.h\n  rtl/tsan_interface_inl.h\n  rtl/tsan_interface_java.h\n  rtl/tsan_mman.h\n  rtl/tsan_mutex.h\n  rtl/tsan_mutexset.h\n  rtl/tsan_platform.h\n  rtl/tsan_report.h\n  rtl/tsan_rtl.h\n  rtl/tsan_stack_trace.h\n  rtl/tsan_stat.h\n  rtl/tsan_suppressions.h\n  rtl/tsan_symbolize.h\n  rtl/tsan_sync.h\n  rtl/tsan_trace.h\n  rtl/tsan_update_shadow_word_inl.h\n  rtl/tsan_vector.h)\n\nset(TSAN_RUNTIME_LIBRARIES)\nadd_custom_target(tsan)\n\nif(APPLE)\n  set(TSAN_ASM_SOURCES rtl/tsan_rtl_amd64.S)\n  # Xcode will try to compile this file as C ('clang -x c'), and that will fail.\n  if (${CMAKE_GENERATOR} STREQUAL \"Xcode\")\n    enable_language(ASM)\n  else()\n    # Pass ASM file directly to the C++ compiler.\n    set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES LANGUAGE C)\n  endif()\n  add_compiler_rt_runtime(clang_rt.tsan\n    SHARED\n    OS ${TSAN_SUPPORTED_OS}\n    ARCHS ${TSAN_SUPPORTED_ARCH}\n    SOURCES ${TSAN_SOURCES} ${TSAN_CXX_SOURCES} ${TSAN_ASM_SOURCES}\n    OBJECT_LIBS RTInterception\n                RTSanitizerCommon\n                RTSanitizerCommonLibc\n                RTUbsan\n    CFLAGS ${TSAN_RTL_CFLAGS}\n    PARENT_TARGET tsan)\n  add_compiler_rt_object_libraries(RTTsan_dynamic \n    OS ${TSAN_SUPPORTED_OS}\n    ARCHS ${TSAN_SUPPORTED_ARCH}\n    SOURCES ${TSAN_SOURCES} ${TSAN_CXX_SOURCES} ${TSAN_ASM_SOURCES}\n    CFLAGS ${TSAN_RTL_CFLAGS})\n\n  # Build and check Go runtime.\n  set(BUILDGO_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/go/buildgo.sh)\n  add_custom_target(GotsanRuntimeCheck\n    COMMAND env \"CC=${CMAKE_C_COMPILER} ${OSX_SYSROOT_FLAG}\"\n            IN_TMPDIR=1 SILENT=1 ${BUILDGO_SCRIPT}\n    DEPENDS tsan ${BUILDGO_SCRIPT}\n    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go\n    COMMENT \"Checking TSan Go runtime...\"\n    VERBATIM)\nelse()\n  foreach(arch ${TSAN_SUPPORTED_ARCH})\n    if(arch STREQUAL \"x86_64\")\n      set(TSAN_ASM_SOURCES rtl/tsan_rtl_amd64.S)\n      # Pass ASM file directly to the C++ compiler.\n      set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES\n        LANGUAGE C)\n      # Sanity check for Go runtime.\n      set(BUILDGO_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/go/buildgo.sh)\n      add_custom_target(GotsanRuntimeCheck\n        COMMAND env \"CC=${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}\"\n                IN_TMPDIR=1 SILENT=1 ${BUILDGO_SCRIPT}\n        DEPENDS clang_rt.tsan-${arch} ${BUILDGO_SCRIPT}\n        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go\n        COMMENT \"Checking TSan Go runtime...\"\n        VERBATIM)\n    elseif(arch STREQUAL \"aarch64\")\n      set(TSAN_ASM_SOURCES rtl/tsan_rtl_aarch64.S)\n      # Pass ASM file directly to the C++ compiler.\n      set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES\n        LANGUAGE C)\n   elseif(arch MATCHES \"powerpc64|powerpc64le\")\n     set(TSAN_ASM_SOURCES rtl/tsan_rtl_ppc64.S)\n     # Pass ASM file directly to the C++ compiler.\n     set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES\n       LANGUAGE C)\n    else()\n      set(TSAN_ASM_SOURCES)\n    endif()\n    add_compiler_rt_runtime(clang_rt.tsan\n      STATIC\n      ARCHS ${arch}\n      SOURCES ${TSAN_SOURCES} ${TSAN_ASM_SOURCES}\n              $<TARGET_OBJECTS:RTInterception.${arch}>\n              $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>\n              $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>\n              $<TARGET_OBJECTS:RTUbsan.${arch}>\n      CFLAGS ${TSAN_RTL_CFLAGS})\n    add_compiler_rt_runtime(clang_rt.tsan_cxx\n      STATIC\n      ARCHS ${arch}\n      SOURCES ${TSAN_CXX_SOURCES}\n              $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>\n      CFLAGS ${TSAN_RTL_CFLAGS})\n    list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch}\n                                       clang_rt.tsan_cxx-${arch})\n    add_sanitizer_rt_symbols(clang_rt.tsan\n      ARCHS ${arch}\n      EXTRA rtl/tsan.syms.extra)\n    add_sanitizer_rt_symbols(clang_rt.tsan_cxx\n      ARCHS ${arch}\n      EXTRA rtl/tsan.syms.extra)\n    add_dependencies(tsan clang_rt.tsan-${arch}\n                          clang_rt.tsan_cxx-${arch}\n                          clang_rt.tsan-${arch}-symbols\n                          clang_rt.tsan_cxx-${arch}-symbols)\n  endforeach()\nendif()\n\nadd_dependencies(compiler-rt tsan)\n\n# Make sure that non-platform-specific files don't include any system headers.\nif(COMPILER_RT_HAS_SYSROOT_FLAG)\n  file(GLOB _tsan_generic_sources rtl/tsan*)\n  file(GLOB _tsan_platform_sources rtl/tsan*posix* rtl/tsan*mac*\n                                   rtl/tsan*linux*)\n  list(REMOVE_ITEM _tsan_generic_sources ${_tsan_platform_sources})\n  set_source_files_properties(${_tsan_generic_sources}\n    PROPERTIES COMPILE_FLAGS \"--sysroot=.\")\nendif()\n\n# Build libcxx instrumented with TSan.\nif(COMPILER_RT_HAS_LIBCXX_SOURCES AND\n   COMPILER_RT_TEST_COMPILER_ID STREQUAL \"Clang\")\n  set(LIBCXX_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/libcxx_tsan)\n  add_custom_libcxx(libcxx_tsan ${LIBCXX_PREFIX}\n    DEPS ${TSAN_RUNTIME_LIBRARIES}\n    CFLAGS -fsanitize=thread)\nendif()\n\nif(COMPILER_RT_INCLUDE_TESTS)\n  add_subdirectory(tests)\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/analyze_libtsan.sh",
    "content": "#!/bin/bash\n#\n# Script that prints information about generated code in TSan runtime.\n\nset -e\nset -u\n\nif [[ \"$#\" != 1 ]]; then\n  echo \"Usage: $0 /path/to/binary/built/with/tsan\"\n  exit 1\nfi\n\nget_asm() {\n  grep __tsan_$1.: -A 10000 ${OBJDUMP_CONTENTS} | \\\n    awk \"/[^:]$/ {print;} />:/ {c++; if (c == 2) {exit}}\"\n}\n\nlist=\"write1 \\\n      write2 \\\n      write4 \\\n      write8 \\\n      read1 \\\n      read2 \\\n      read4 \\\n      read8 \\\n      func_entry \\\n      func_exit\"\n\nBIN=$1\nOUTPUT_DIR=$(mktemp -t -d analyze_libtsan_out.XXXXXXXX)\nOBJDUMP_CONTENTS=${OUTPUT_DIR}/libtsan_objdump\nNM_CONTENTS=${OUTPUT_DIR}/libtsan_nm\n\nobjdump -d $BIN  > ${OBJDUMP_CONTENTS}\nnm -S $BIN | grep \"__tsan_\" > ${NM_CONTENTS}\n\nfor f in $list; do\n  file=${OUTPUT_DIR}/asm_$f.s\n  get_asm $f > $file\n  tot=$(wc -l < $file)\n  size=$(grep __tsan_$f$ ${NM_CONTENTS} | awk --non-decimal-data '{print (\"0x\"$2)+0}')\n  rsp=$(grep '(%rsp)' $file | wc -l)\n  push=$(grep 'push' $file | wc -l)\n  pop=$(grep 'pop' $file | wc -l)\n  call=$(grep 'call' $file | wc -l)\n  load=$(egrep 'mov .*\\,.*\\(.*\\)|cmp .*\\,.*\\(.*\\)' $file | wc -l)\n  store=$(egrep 'mov .*\\(.*\\),' $file | wc -l)\n  mov=$(grep 'mov' $file | wc -l)\n  lea=$(grep 'lea' $file | wc -l)\n  sh=$(grep 'shr\\|shl' $file | wc -l)\n  cmp=$(grep 'cmp\\|test' $file | wc -l)\n  printf \"%10s tot %3d; size %4d; rsp %d; push %d; pop %d; call %d; load %2d; store %2d; sh %3d; mov %3d; lea %3d; cmp %3d\\n\" \\\n    $f $tot $size $rsp $push $pop $call $load $store $sh $mov $lea $cmp;\ndone\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/benchmarks/mini_bench_local.cc",
    "content": "// Mini-benchmark for tsan: non-shared memory writes.\n#include <pthread.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <assert.h>\n\nint len;\nint *a;\nconst int kNumIter = 1000;\n\n__attribute__((noinline))\nvoid Run(int idx) {\n  for (int i = 0, n = len; i < n; i++)\n    a[i + idx * n] = i;\n}\n\nvoid *Thread(void *arg) {\n  long idx = (long)arg;\n  printf(\"Thread %ld started\\n\", idx);\n  for (int i = 0; i < kNumIter; i++)\n    Run(idx);\n  printf(\"Thread %ld done\\n\", idx);\n  return 0;\n}\n\nint main(int argc, char **argv) {\n  int n_threads = 0;\n  if (argc != 3) {\n    n_threads = 4;\n    len = 1000000;\n  } else {\n    n_threads = atoi(argv[1]);\n    assert(n_threads > 0 && n_threads <= 32);\n    len = atoi(argv[2]);\n  }\n  printf(\"%s: n_threads=%d len=%d iter=%d\\n\",\n         __FILE__, n_threads, len, kNumIter);\n  a = new int[n_threads * len];\n  pthread_t *t = new pthread_t[n_threads];\n  for (int i = 0; i < n_threads; i++) {\n    pthread_create(&t[i], 0, Thread, (void*)i);\n  }\n  for (int i = 0; i < n_threads; i++) {\n    pthread_join(t[i], 0);\n  }\n  delete [] t;\n  delete [] a;\n  return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/benchmarks/mini_bench_shared.cc",
    "content": "// Mini-benchmark for tsan: shared memory reads.\n#include <pthread.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <assert.h>\n\nint len;\nint *a;\nconst int kNumIter = 1000;\n\n__attribute__((noinline))\nvoid Run(int idx) {\n  for (int i = 0, n = len; i < n; i++)\n    if (a[i] != i) abort();\n}\n\nvoid *Thread(void *arg) {\n  long idx = (long)arg;\n  printf(\"Thread %ld started\\n\", idx);\n  for (int i = 0; i < kNumIter; i++)\n    Run(idx);\n  printf(\"Thread %ld done\\n\", idx);\n  return 0;\n}\n\nint main(int argc, char **argv) {\n  int n_threads = 0;\n  if (argc != 3) {\n    n_threads = 4;\n    len = 1000000;\n  } else {\n    n_threads = atoi(argv[1]);\n    assert(n_threads > 0 && n_threads <= 32);\n    len = atoi(argv[2]);\n  }\n  printf(\"%s: n_threads=%d len=%d iter=%d\\n\",\n         __FILE__, n_threads, len, kNumIter);\n  a = new int[len];\n  for (int i = 0, n = len; i < n; i++)\n    a[i] = i;\n  pthread_t *t = new pthread_t[n_threads];\n  for (int i = 0; i < n_threads; i++) {\n    pthread_create(&t[i], 0, Thread, (void*)i);\n  }\n  for (int i = 0; i < n_threads; i++) {\n    pthread_join(t[i], 0);\n  }\n  delete [] t;\n  delete [] a;\n  return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/benchmarks/start_many_threads.cc",
    "content": "// Mini-benchmark for creating a lot of threads.\n//\n// Some facts:\n// a) clang -O1 takes <15ms to start N=500 threads,\n//    consuming ~4MB more RAM than N=1.\n// b) clang -O1 -ftsan takes ~26s to start N=500 threads,\n//    eats 5GB more RAM than N=1 (which is somewhat expected but still a lot)\n//    but then it consumes ~4GB of extra memory when the threads shut down!\n//        (definitely not in the barrier_wait interceptor)\n//    Also, it takes 26s to run with N=500 vs just 1.1s to run with N=1.\n#include <assert.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n\npthread_barrier_t all_threads_ready;\n\nvoid* Thread(void *unused) {\n  pthread_barrier_wait(&all_threads_ready);\n  return 0;\n}\n\nint main(int argc, char **argv) {\n  int n_threads;\n  if (argc == 1) {\n    n_threads = 100;\n  } else if (argc == 2) {\n    n_threads = atoi(argv[1]);\n  } else {\n    printf(\"Usage: %s n_threads\\n\", argv[0]);\n    return 1;\n  }\n  printf(\"%s: n_threads=%d\\n\", __FILE__, n_threads);\n\n  pthread_barrier_init(&all_threads_ready, NULL, n_threads + 1);\n\n  pthread_t *t = new pthread_t[n_threads];\n  for (int i = 0; i < n_threads; i++) {\n    int status = pthread_create(&t[i], 0, Thread, (void*)i);\n    assert(status == 0);\n  }\n  // sleep(5);  // FIXME: simplify measuring the memory usage.\n  pthread_barrier_wait(&all_threads_ready);\n  for (int i = 0; i < n_threads; i++) {\n    pthread_join(t[i], 0);\n  }\n  // sleep(5);  // FIXME: simplify measuring the memory usage.\n  delete [] t;\n\n  return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/benchmarks/vts_many_threads_bench.cc",
    "content": "// Mini-benchmark for tsan VTS worst case performance\n// Idea:\n// 1) Spawn M + N threads (M >> N)\n//    We'll call the 'M' threads as 'garbage threads'.\n// 2) Make sure all threads have created thus no TIDs were reused\n// 3) Join the garbage threads\n// 4) Do many sync operations on the remaining N threads\n//\n// It turns out that due to O(M+N) VTS complexity the (4) is much slower with\n// when N is large.\n//\n// Some numbers:\n// a) clang++ native O1 with n_iterations=200kk takes\n//      5s regardless of M\n//    clang++ tsanv2 O1 with n_iterations=20kk takes\n//      23.5s with M=200\n//      11.5s with M=1\n//    i.e. tsanv2 is ~23x to ~47x slower than native, depends on M.\n// b) g++ native O1 with n_iterations=200kk takes\n//      5.5s regardless of M\n//    g++ tsanv1 O1 with n_iterations=2kk takes\n//      39.5s with M=200\n//      20.5s with M=1\n//    i.e. tsanv1 is ~370x to ~720x slower than native, depends on M.\n\n#include <assert.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdlib.h>\n\nclass __attribute__((aligned(64))) Mutex {\n public:\n  Mutex()  { pthread_mutex_init(&m_, NULL); }\n  ~Mutex() { pthread_mutex_destroy(&m_); }\n  void Lock() { pthread_mutex_lock(&m_); }\n  void Unlock() { pthread_mutex_unlock(&m_); }\n\n private:\n  pthread_mutex_t m_;\n};\n\nconst int kNumMutexes = 1024;\nMutex mutexes[kNumMutexes];\n\nint n_threads, n_iterations;\n\npthread_barrier_t all_threads_ready, main_threads_ready;\n\nvoid* GarbageThread(void *unused) {\n  pthread_barrier_wait(&all_threads_ready);\n  return 0;\n}\n\nvoid *Thread(void *arg) {\n  long idx = (long)arg;\n  pthread_barrier_wait(&all_threads_ready);\n\n  // Wait for the main thread to join the garbage threads.\n  pthread_barrier_wait(&main_threads_ready);\n\n  printf(\"Thread %ld go!\\n\", idx);\n  int offset = idx * kNumMutexes / n_threads;\n  for (int i = 0; i < n_iterations; i++) {\n    mutexes[(offset + i) % kNumMutexes].Lock();\n    mutexes[(offset + i) % kNumMutexes].Unlock();\n  }\n  printf(\"Thread %ld done\\n\", idx);\n  return 0;\n}\n\nint main(int argc, char **argv) {\n  int n_garbage_threads;\n  if (argc == 1) {\n    n_threads = 2;\n    n_garbage_threads = 200;\n    n_iterations = 20000000;\n  } else if (argc == 4) {\n    n_threads = atoi(argv[1]);\n    assert(n_threads > 0 && n_threads <= 32);\n    n_garbage_threads = atoi(argv[2]);\n    assert(n_garbage_threads > 0 && n_garbage_threads <= 16000);\n    n_iterations = atoi(argv[3]);\n  } else {\n    printf(\"Usage: %s n_threads n_garbage_threads n_iterations\\n\", argv[0]);\n    return 1;\n  }\n  printf(\"%s: n_threads=%d n_garbage_threads=%d n_iterations=%d\\n\",\n         __FILE__, n_threads, n_garbage_threads, n_iterations);\n\n  pthread_barrier_init(&all_threads_ready, NULL, n_garbage_threads + n_threads + 1);\n  pthread_barrier_init(&main_threads_ready, NULL, n_threads + 1);\n\n  pthread_t *t = new pthread_t[n_threads];\n  {\n    pthread_t *g_t = new pthread_t[n_garbage_threads];\n    for (int i = 0; i < n_garbage_threads; i++) {\n      int status = pthread_create(&g_t[i], 0, GarbageThread, NULL);\n      assert(status == 0);\n    }\n    for (int i = 0; i < n_threads; i++) {\n      int status = pthread_create(&t[i], 0, Thread, (void*)i);\n      assert(status == 0);\n    }\n    pthread_barrier_wait(&all_threads_ready);\n    printf(\"All threads started! Killing the garbage threads.\\n\");\n    for (int i = 0; i < n_garbage_threads; i++) {\n      pthread_join(g_t[i], 0);\n    }\n    delete [] g_t;\n  }\n  printf(\"Resuming the main threads.\\n\");\n  pthread_barrier_wait(&main_threads_ready);\n\n\n  for (int i = 0; i < n_threads; i++) {\n    pthread_join(t[i], 0);\n  }\n  delete [] t;\n  return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/check_analyze.sh",
    "content": "#!/bin/bash\n#\n# Script that checks that critical functions in TSan runtime have correct number\n# of push/pop/rsp instructions to verify that runtime is efficient enough.\n\nset -u\n\nif [[ \"$#\" != 1 ]]; then\n  echo \"Usage: $0 /path/to/binary/built/with/tsan\"\n  exit 1\nfi\n\nSCRIPTDIR=$(dirname $0)\nRES=$(${SCRIPTDIR}/analyze_libtsan.sh $1)\nPrintRes() {\n  printf \"%s\\n\" \"$RES\"\n}\n\nPrintRes\n\ncheck() {\n  res=$(PrintRes | egrep \"$1 .* $2 $3; \")\n  if [ \"$res\" == \"\" ]; then\n    echo FAILED $1 must contain $2 $3\n    exit 1\n  fi\n}\n\nfor f in write1; do\n  check $f rsp 1\n  check $f push 2\n  check $f pop 2\ndone\n\nfor f in write2 write4; do\n  check $f rsp 1\n  check $f push 4\n  check $f pop 4\ndone\n\nfor f in write8; do\n  check $f rsp 1\n  check $f push 3\n  check $f pop 3\ndone\n\nfor f in read1 read2 read4 read8; do\n  check $f rsp 1\n  check $f push 5\n  check $f pop 5\ndone\n\nfor f in func_entry func_exit; do\n  check $f rsp 0\n  check $f push 0\n  check $f pop 0\n  check $f call 1  # TraceSwitch()\ndone\n\necho LGTM\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/check_cmake.sh",
    "content": "#!/bin/bash\nset -u\nset -e\n\nROOT=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\nif [ -d \"$ROOT/llvm-build\" ]; then\n  cd $ROOT/llvm-build\nelse\n  mkdir -p $ROOT/llvm-build\n  cd $ROOT/llvm-build\n  CC=clang CXX=clang++ cmake -G Ninja -DLLVM_ENABLE_WERROR=ON -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=ON $ROOT/../../../..\nfi\nninja\nninja check-sanitizer\nninja check-tsan\nninja check-asan\nninja check-msan\nninja check-lsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/dd/CMakeLists.txt",
    "content": "# Build for the experimental deadlock detector runtime library.\n\ninclude_directories(../..)\n\nset(DD_CFLAGS ${SANITIZER_COMMON_CFLAGS})\nappend_no_rtti_flag(DD_CFLAGS)\n\nset(DD_SOURCES\n  dd_rtl.cc\n  dd_interceptors.cc\n)\n\nset(DD_LINKLIBS)\nappend_list_if(COMPILER_RT_HAS_LIBDL dl DD_LINKLIBS)\nappend_list_if(COMPILER_RT_HAS_LIBRT rt DD_LINKLIBS)\nappend_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread DD_LINKLIBS)\n\nadd_custom_target(dd)\n# Deadlock detector is currently supported on 64-bit Linux only.\nif(CAN_TARGET_x86_64 AND UNIX AND NOT APPLE AND NOT ANDROID)\n  set(arch \"x86_64\")\n  add_compiler_rt_runtime(clang_rt.dd\n    STATIC\n    ARCHS ${arch}\n    SOURCES ${DD_SOURCES}\n            $<TARGET_OBJECTS:RTInterception.${arch}>\n            $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>\n            $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>\n    CFLAGS ${DD_CFLAGS}\n    PARENT_TARGET dd)\n\n  add_compiler_rt_object_libraries(RTDD\n    ARCHS ${arch}\n    SOURCES ${DD_SOURCES} CFLAGS ${DD_CFLAGS})\n\n  add_compiler_rt_runtime(clang_rt.dyndd\n    SHARED\n    ARCHS ${arch}\n    SOURCES $<TARGET_OBJECTS:RTDD.${arch}>\n            $<TARGET_OBJECTS:RTInterception.${arch}>\n            $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>\n            $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>\n    LINK_LIBS ${DD_LINKLIBS}\n    PARENT_TARGET dd)\nendif()\n\nadd_dependencies(compiler-rt dd)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/dd/dd_interceptors.cc",
    "content": "//===-- dd_interceptors.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"dd_rtl.h\"\n#include \"interception/interception.h\"\n#include \"sanitizer_common/sanitizer_procmaps.h\"\n#include <pthread.h>\n#include <stdlib.h>\n\nusing namespace __dsan;\n\nextern \"C\" void *__libc_malloc(uptr size);\nextern \"C\" void __libc_free(void *ptr);\n\n__attribute__((tls_model(\"initial-exec\")))\nstatic __thread Thread *thr;\n__attribute__((tls_model(\"initial-exec\")))\nstatic __thread volatile int initing;\nstatic bool inited;\nstatic uptr g_data_start;\nstatic uptr g_data_end;\n\nstatic bool InitThread() {\n  if (initing)\n    return false;\n  if (thr != 0)\n    return true;\n  initing = true;\n  if (!inited) {\n    inited = true;\n    Initialize();\n  }\n  thr = (Thread*)InternalAlloc(sizeof(*thr));\n  internal_memset(thr, 0, sizeof(*thr));\n  ThreadInit(thr);\n  initing = false;\n  return true;\n}\n\nINTERCEPTOR(int, pthread_mutex_destroy, pthread_mutex_t *m) {\n  InitThread();\n  MutexDestroy(thr, (uptr)m);\n  return REAL(pthread_mutex_destroy)(m);\n}\n\nINTERCEPTOR(int, pthread_mutex_lock, pthread_mutex_t *m) {\n  InitThread();\n  MutexBeforeLock(thr, (uptr)m, true);\n  int res = REAL(pthread_mutex_lock)(m);\n  MutexAfterLock(thr, (uptr)m, true, false);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_mutex_trylock, pthread_mutex_t *m) {\n  InitThread();\n  int res = REAL(pthread_mutex_trylock)(m);\n  if (res == 0)\n    MutexAfterLock(thr, (uptr)m, true, true);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_mutex_unlock, pthread_mutex_t *m) {\n  InitThread();\n  MutexBeforeUnlock(thr, (uptr)m, true);\n  return REAL(pthread_mutex_unlock)(m);\n}\n\nINTERCEPTOR(int, pthread_spin_destroy, pthread_spinlock_t *m) {\n  InitThread();\n  int res = REAL(pthread_spin_destroy)(m);\n  MutexDestroy(thr, (uptr)m);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_spin_lock, pthread_spinlock_t *m) {\n  InitThread();\n  MutexBeforeLock(thr, (uptr)m, true);\n  int res = REAL(pthread_spin_lock)(m);\n  MutexAfterLock(thr, (uptr)m, true, false);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_spin_trylock, pthread_spinlock_t *m) {\n  InitThread();\n  int res = REAL(pthread_spin_trylock)(m);\n  if (res == 0)\n    MutexAfterLock(thr, (uptr)m, true, true);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_spin_unlock, pthread_spinlock_t *m) {\n  InitThread();\n  MutexBeforeUnlock(thr, (uptr)m, true);\n  return REAL(pthread_spin_unlock)(m);\n}\n\nINTERCEPTOR(int, pthread_rwlock_destroy, pthread_rwlock_t *m) {\n  InitThread();\n  MutexDestroy(thr, (uptr)m);\n  return REAL(pthread_rwlock_destroy)(m);\n}\n\nINTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *m) {\n  InitThread();\n  MutexBeforeLock(thr, (uptr)m, false);\n  int res = REAL(pthread_rwlock_rdlock)(m);\n  MutexAfterLock(thr, (uptr)m, false, false);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_rwlock_tryrdlock, pthread_rwlock_t *m) {\n  InitThread();\n  int res = REAL(pthread_rwlock_tryrdlock)(m);\n  if (res == 0)\n    MutexAfterLock(thr, (uptr)m, false, true);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_rwlock_timedrdlock, pthread_rwlock_t *m,\n    const timespec *abstime) {\n  InitThread();\n  int res = REAL(pthread_rwlock_timedrdlock)(m, abstime);\n  if (res == 0)\n    MutexAfterLock(thr, (uptr)m, false, true);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *m) {\n  InitThread();\n  MutexBeforeLock(thr, (uptr)m, true);\n  int res = REAL(pthread_rwlock_wrlock)(m);\n  MutexAfterLock(thr, (uptr)m, true, false);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_rwlock_trywrlock, pthread_rwlock_t *m) {\n  InitThread();\n  int res = REAL(pthread_rwlock_trywrlock)(m);\n  if (res == 0)\n    MutexAfterLock(thr, (uptr)m, true, true);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_rwlock_timedwrlock, pthread_rwlock_t *m,\n    const timespec *abstime) {\n  InitThread();\n  int res = REAL(pthread_rwlock_timedwrlock)(m, abstime);\n  if (res == 0)\n    MutexAfterLock(thr, (uptr)m, true, true);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_rwlock_unlock, pthread_rwlock_t *m) {\n  InitThread();\n  MutexBeforeUnlock(thr, (uptr)m, true);  // note: not necessary write unlock\n  return REAL(pthread_rwlock_unlock)(m);\n}\n\nstatic pthread_cond_t *init_cond(pthread_cond_t *c, bool force = false) {\n  atomic_uintptr_t *p = (atomic_uintptr_t*)c;\n  uptr cond = atomic_load(p, memory_order_acquire);\n  if (!force && cond != 0)\n    return (pthread_cond_t*)cond;\n  void *newcond = malloc(sizeof(pthread_cond_t));\n  internal_memset(newcond, 0, sizeof(pthread_cond_t));\n  if (atomic_compare_exchange_strong(p, &cond, (uptr)newcond,\n      memory_order_acq_rel))\n    return (pthread_cond_t*)newcond;\n  free(newcond);\n  return (pthread_cond_t*)cond;\n}\n\nINTERCEPTOR(int, pthread_cond_init, pthread_cond_t *c,\n    const pthread_condattr_t *a) {\n  InitThread();\n  pthread_cond_t *cond = init_cond(c, true);\n  return REAL(pthread_cond_init)(cond, a);\n}\n\nINTERCEPTOR(int, pthread_cond_wait, pthread_cond_t *c, pthread_mutex_t *m) {\n  InitThread();\n  pthread_cond_t *cond = init_cond(c);\n  MutexBeforeUnlock(thr, (uptr)m, true);\n  MutexBeforeLock(thr, (uptr)m, true);\n  int res = REAL(pthread_cond_wait)(cond, m);\n  MutexAfterLock(thr, (uptr)m, true, false);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *c, pthread_mutex_t *m,\n    const timespec *abstime) {\n  InitThread();\n  pthread_cond_t *cond = init_cond(c);\n  MutexBeforeUnlock(thr, (uptr)m, true);\n  MutexBeforeLock(thr, (uptr)m, true);\n  int res = REAL(pthread_cond_timedwait)(cond, m, abstime);\n  MutexAfterLock(thr, (uptr)m, true, false);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *c) {\n  InitThread();\n  pthread_cond_t *cond = init_cond(c);\n  return REAL(pthread_cond_signal)(cond);\n}\n\nINTERCEPTOR(int, pthread_cond_broadcast, pthread_cond_t *c) {\n  InitThread();\n  pthread_cond_t *cond = init_cond(c);\n  return REAL(pthread_cond_broadcast)(cond);\n}\n\nINTERCEPTOR(int, pthread_cond_destroy, pthread_cond_t *c) {\n  InitThread();\n  pthread_cond_t *cond = init_cond(c);\n  int res = REAL(pthread_cond_destroy)(cond);\n  free(cond);\n  atomic_store((atomic_uintptr_t*)c, 0, memory_order_relaxed);\n  return res;\n}\n\n// for symbolizer\nINTERCEPTOR(char*, realpath, const char *path, char *resolved_path) {\n  InitThread();\n  return REAL(realpath)(path, resolved_path);\n}\n\nINTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {\n  InitThread();\n  return REAL(read)(fd, ptr, count);\n}\n\nINTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {\n  InitThread();\n  return REAL(pread)(fd, ptr, count, offset);\n}\n\nextern \"C\" {\nvoid __dsan_before_mutex_lock(uptr m, int writelock) {\n  if (!InitThread())\n    return;\n  MutexBeforeLock(thr, m, writelock);\n}\n\nvoid __dsan_after_mutex_lock(uptr m, int writelock, int trylock) {\n  if (!InitThread())\n    return;\n  MutexAfterLock(thr, m, writelock, trylock);\n}\n\nvoid __dsan_before_mutex_unlock(uptr m, int writelock) {\n  if (!InitThread())\n    return;\n  MutexBeforeUnlock(thr, m, writelock);\n}\n\nvoid __dsan_mutex_destroy(uptr m) {\n  if (!InitThread())\n    return;\n  // if (m >= g_data_start && m < g_data_end)\n  //   return;\n  MutexDestroy(thr, m);\n}\n}  // extern \"C\"\n\nnamespace __dsan {\n\nstatic void InitDataSeg() {\n  MemoryMappingLayout proc_maps(true);\n  uptr start, end, offset;\n  char name[128];\n  bool prev_is_data = false;\n  while (proc_maps.Next(&start, &end, &offset, name, ARRAY_SIZE(name),\n                        /*protection*/ 0)) {\n    bool is_data = offset != 0 && name[0] != 0;\n    // BSS may get merged with [heap] in /proc/self/maps. This is not very\n    // reliable.\n    bool is_bss = offset == 0 &&\n      (name[0] == 0 || internal_strcmp(name, \"[heap]\") == 0) && prev_is_data;\n    if (g_data_start == 0 && is_data)\n      g_data_start = start;\n    if (is_bss)\n      g_data_end = end;\n    prev_is_data = is_data;\n  }\n  VPrintf(1, \"guessed data_start=%p data_end=%p\\n\",  g_data_start, g_data_end);\n  CHECK_LT(g_data_start, g_data_end);\n  CHECK_GE((uptr)&g_data_start, g_data_start);\n  CHECK_LT((uptr)&g_data_start, g_data_end);\n}\n\nvoid InitializeInterceptors() {\n  INTERCEPT_FUNCTION(pthread_mutex_destroy);\n  INTERCEPT_FUNCTION(pthread_mutex_lock);\n  INTERCEPT_FUNCTION(pthread_mutex_trylock);\n  INTERCEPT_FUNCTION(pthread_mutex_unlock);\n\n  INTERCEPT_FUNCTION(pthread_spin_destroy);\n  INTERCEPT_FUNCTION(pthread_spin_lock);\n  INTERCEPT_FUNCTION(pthread_spin_trylock);\n  INTERCEPT_FUNCTION(pthread_spin_unlock);\n\n  INTERCEPT_FUNCTION(pthread_rwlock_destroy);\n  INTERCEPT_FUNCTION(pthread_rwlock_rdlock);\n  INTERCEPT_FUNCTION(pthread_rwlock_tryrdlock);\n  INTERCEPT_FUNCTION(pthread_rwlock_timedrdlock);\n  INTERCEPT_FUNCTION(pthread_rwlock_wrlock);\n  INTERCEPT_FUNCTION(pthread_rwlock_trywrlock);\n  INTERCEPT_FUNCTION(pthread_rwlock_timedwrlock);\n  INTERCEPT_FUNCTION(pthread_rwlock_unlock);\n\n  INTERCEPT_FUNCTION_VER(pthread_cond_init, \"GLIBC_2.3.2\");\n  INTERCEPT_FUNCTION_VER(pthread_cond_signal, \"GLIBC_2.3.2\");\n  INTERCEPT_FUNCTION_VER(pthread_cond_broadcast, \"GLIBC_2.3.2\");\n  INTERCEPT_FUNCTION_VER(pthread_cond_wait, \"GLIBC_2.3.2\");\n  INTERCEPT_FUNCTION_VER(pthread_cond_timedwait, \"GLIBC_2.3.2\");\n  INTERCEPT_FUNCTION_VER(pthread_cond_destroy, \"GLIBC_2.3.2\");\n\n  // for symbolizer\n  INTERCEPT_FUNCTION(realpath);\n  INTERCEPT_FUNCTION(read);\n  INTERCEPT_FUNCTION(pread);\n\n  InitDataSeg();\n}\n\n}  // namespace __dsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/dd/dd_rtl.cc",
    "content": "//===-- dd_rtl.cc ---------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"dd_rtl.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_flag_parser.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n\nnamespace __dsan {\n\nstatic Context *ctx;\n\nstatic u32 CurrentStackTrace(Thread *thr, uptr skip) {\n  BufferedStackTrace stack;\n  thr->ignore_interceptors = true;\n  stack.Unwind(1000, 0, 0, 0, 0, 0, false);\n  thr->ignore_interceptors = false;\n  if (stack.size <= skip)\n    return 0;\n  return StackDepotPut(StackTrace(stack.trace + skip, stack.size - skip));\n}\n\nstatic void PrintStackTrace(Thread *thr, u32 stk) {\n  StackTrace stack = StackDepotGet(stk);\n  thr->ignore_interceptors = true;\n  stack.Print();\n  thr->ignore_interceptors = false;\n}\n\nstatic void ReportDeadlock(Thread *thr, DDReport *rep) {\n  if (rep == 0)\n    return;\n  BlockingMutexLock lock(&ctx->report_mutex);\n  Printf(\"==============================\\n\");\n  Printf(\"WARNING: lock-order-inversion (potential deadlock)\\n\");\n  for (int i = 0; i < rep->n; i++) {\n    Printf(\"Thread %d locks mutex %llu while holding mutex %llu:\\n\",\n      rep->loop[i].thr_ctx, rep->loop[i].mtx_ctx1, rep->loop[i].mtx_ctx0);\n    PrintStackTrace(thr, rep->loop[i].stk[1]);\n    if (rep->loop[i].stk[0]) {\n      Printf(\"Mutex %llu was acquired here:\\n\",\n        rep->loop[i].mtx_ctx0);\n      PrintStackTrace(thr, rep->loop[i].stk[0]);\n    }\n  }\n  Printf(\"==============================\\n\");\n}\n\nCallback::Callback(Thread *thr)\n    : thr(thr) {\n  lt = thr->dd_lt;\n  pt = thr->dd_pt;\n}\n\nu32 Callback::Unwind() {\n  return CurrentStackTrace(thr, 3);\n}\n\nstatic void InitializeFlags() {\n  Flags *f = flags();\n\n  // Default values.\n  f->second_deadlock_stack = false;\n\n  SetCommonFlagsDefaults();\n  {\n    // Override some common flags defaults.\n    CommonFlags cf;\n    cf.CopyFrom(*common_flags());\n    cf.allow_addr2line = true;\n    OverrideCommonFlags(cf);\n  }\n\n  // Override from command line.\n  FlagParser parser;\n  RegisterFlag(&parser, \"second_deadlock_stack\", \"\", &f->second_deadlock_stack);\n  RegisterCommonFlags(&parser);\n  parser.ParseString(GetEnv(\"DSAN_OPTIONS\"));\n  SetVerbosity(common_flags()->verbosity);\n}\n\nvoid Initialize() {\n  static u64 ctx_mem[sizeof(Context) / sizeof(u64) + 1];\n  ctx = new(ctx_mem) Context();\n\n  InitializeInterceptors();\n  InitializeFlags();\n  ctx->dd = DDetector::Create(flags());\n}\n\nvoid ThreadInit(Thread *thr) {\n  static atomic_uintptr_t id_gen;\n  uptr id = atomic_fetch_add(&id_gen, 1, memory_order_relaxed);\n  thr->dd_pt = ctx->dd->CreatePhysicalThread();\n  thr->dd_lt = ctx->dd->CreateLogicalThread(id);\n}\n\nvoid ThreadDestroy(Thread *thr) {\n  ctx->dd->DestroyPhysicalThread(thr->dd_pt);\n  ctx->dd->DestroyLogicalThread(thr->dd_lt);\n}\n\nvoid MutexBeforeLock(Thread *thr, uptr m, bool writelock) {\n  if (thr->ignore_interceptors)\n    return;\n  Callback cb(thr);\n  {\n    MutexHashMap::Handle h(&ctx->mutex_map, m);\n    if (h.created())\n      ctx->dd->MutexInit(&cb, &h->dd);\n    ctx->dd->MutexBeforeLock(&cb, &h->dd, writelock);\n  }\n  ReportDeadlock(thr, ctx->dd->GetReport(&cb));\n}\n\nvoid MutexAfterLock(Thread *thr, uptr m, bool writelock, bool trylock) {\n  if (thr->ignore_interceptors)\n    return;\n  Callback cb(thr);\n  {\n    MutexHashMap::Handle h(&ctx->mutex_map, m);\n    if (h.created())\n      ctx->dd->MutexInit(&cb, &h->dd);\n    ctx->dd->MutexAfterLock(&cb, &h->dd, writelock, trylock);\n  }\n  ReportDeadlock(thr, ctx->dd->GetReport(&cb));\n}\n\nvoid MutexBeforeUnlock(Thread *thr, uptr m, bool writelock) {\n  if (thr->ignore_interceptors)\n    return;\n  Callback cb(thr);\n  {\n    MutexHashMap::Handle h(&ctx->mutex_map, m);\n    ctx->dd->MutexBeforeUnlock(&cb, &h->dd, writelock);\n  }\n  ReportDeadlock(thr, ctx->dd->GetReport(&cb));\n}\n\nvoid MutexDestroy(Thread *thr, uptr m) {\n  if (thr->ignore_interceptors)\n    return;\n  Callback cb(thr);\n  MutexHashMap::Handle h(&ctx->mutex_map, m, true);\n  if (!h.exists())\n    return;\n  ctx->dd->MutexDestroy(&cb, &h->dd);\n}\n\n}  // namespace __dsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/dd/dd_rtl.h",
    "content": "//===-- dd_rtl.h ----------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n#ifndef DD_RTL_H\n#define DD_RTL_H\n\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"sanitizer_common/sanitizer_deadlock_detector_interface.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_allocator_internal.h\"\n#include \"sanitizer_common/sanitizer_addrhashmap.h\"\n#include \"sanitizer_common/sanitizer_mutex.h\"\n\nnamespace __dsan {\n\ntypedef DDFlags Flags;\n\nstruct Mutex {\n  DDMutex dd;\n};\n\nstruct Thread {\n  DDPhysicalThread *dd_pt;\n  DDLogicalThread *dd_lt;\n\n  bool ignore_interceptors;\n};\n\nstruct Callback : DDCallback {\n  Thread *thr;\n\n  Callback(Thread *thr);\n  u32 Unwind() override;\n};\n\ntypedef AddrHashMap<Mutex, 31051> MutexHashMap;\n\nstruct Context {\n  DDetector *dd;\n\n  BlockingMutex report_mutex;\n  MutexHashMap mutex_map;\n};\n\ninline Flags* flags() {\n  static Flags flags;\n  return &flags;\n}\n\nvoid Initialize();\nvoid InitializeInterceptors();\n\nvoid ThreadInit(Thread *thr);\nvoid ThreadDestroy(Thread *thr);\n\nvoid MutexBeforeLock(Thread *thr, uptr m, bool writelock);\nvoid MutexAfterLock(Thread *thr, uptr m, bool writelock, bool trylock);\nvoid MutexBeforeUnlock(Thread *thr, uptr m, bool writelock);\nvoid MutexDestroy(Thread *thr, uptr m);\n\n}  // namespace __dsan\n#endif  // DD_RTL_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/go/build.bat",
    "content": "type tsan_go.cc ..\\rtl\\tsan_interface_atomic.cc ..\\rtl\\tsan_clock.cc ..\\rtl\\tsan_flags.cc ..\\rtl\\tsan_md5.cc ..\\rtl\\tsan_mutex.cc ..\\rtl\\tsan_report.cc ..\\rtl\\tsan_rtl.cc ..\\rtl\\tsan_rtl_mutex.cc ..\\rtl\\tsan_rtl_report.cc ..\\rtl\\tsan_rtl_thread.cc ..\\rtl\\tsan_stat.cc ..\\rtl\\tsan_suppressions.cc ..\\rtl\\tsan_sync.cc ..\\rtl\\tsan_stack_trace.cc ..\\..\\sanitizer_common\\sanitizer_allocator.cc ..\\..\\sanitizer_common\\sanitizer_common.cc ..\\..\\sanitizer_common\\sanitizer_flags.cc ..\\..\\sanitizer_common\\sanitizer_stacktrace.cc ..\\..\\sanitizer_common\\sanitizer_libc.cc ..\\..\\sanitizer_common\\sanitizer_printf.cc ..\\..\\sanitizer_common\\sanitizer_suppressions.cc ..\\..\\sanitizer_common\\sanitizer_thread_registry.cc ..\\rtl\\tsan_platform_windows.cc ..\\..\\sanitizer_common\\sanitizer_win.cc ..\\..\\sanitizer_common\\sanitizer_deadlock_detector1.cc ..\\..\\sanitizer_common\\sanitizer_stackdepot.cc ..\\..\\sanitizer_common\\sanitizer_persistent_allocator.cc ..\\..\\sanitizer_common\\sanitizer_flag_parser.cc ..\\..\\sanitizer_common\\sanitizer_symbolizer.cc > gotsan.cc\n\ngcc -c -o race_windows_amd64.syso gotsan.cc -I..\\rtl -I..\\.. -I..\\..\\sanitizer_common -I..\\..\\..\\include -m64 -Wall -fno-exceptions -fno-rtti -DSANITIZER_GO -Wno-error=attributes -Wno-attributes -Wno-format -Wno-maybe-uninitialized -DSANITIZER_DEBUG=0 -O3 -fomit-frame-pointer -std=c++11\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/go/buildgo.sh",
    "content": "#!/bin/sh\n\nset -e\n\nSRCS=\"\n\ttsan_go.cc\n\t../rtl/tsan_clock.cc\n\t../rtl/tsan_flags.cc\n\t../rtl/tsan_interface_atomic.cc\n\t../rtl/tsan_md5.cc\n\t../rtl/tsan_mutex.cc\n\t../rtl/tsan_report.cc\n\t../rtl/tsan_rtl.cc\n\t../rtl/tsan_rtl_mutex.cc\n\t../rtl/tsan_rtl_report.cc\n\t../rtl/tsan_rtl_thread.cc\n\t../rtl/tsan_stack_trace.cc\n\t../rtl/tsan_stat.cc\n\t../rtl/tsan_suppressions.cc\n\t../rtl/tsan_sync.cc\n\t../../sanitizer_common/sanitizer_allocator.cc\n\t../../sanitizer_common/sanitizer_common.cc\n\t../../sanitizer_common/sanitizer_common_libcdep.cc\n\t../../sanitizer_common/sanitizer_deadlock_detector2.cc\n\t../../sanitizer_common/sanitizer_flag_parser.cc\n\t../../sanitizer_common/sanitizer_flags.cc\n\t../../sanitizer_common/sanitizer_libc.cc\n\t../../sanitizer_common/sanitizer_persistent_allocator.cc\n\t../../sanitizer_common/sanitizer_printf.cc\n\t../../sanitizer_common/sanitizer_suppressions.cc\n\t../../sanitizer_common/sanitizer_thread_registry.cc\n\t../../sanitizer_common/sanitizer_stackdepot.cc\n\t../../sanitizer_common/sanitizer_stacktrace.cc\n\t../../sanitizer_common/sanitizer_symbolizer.cc\n\"\n\nif [ \"`uname -a | grep Linux`\" != \"\" ]; then\n\tSUFFIX=\"linux_amd64\"\n\tOSCFLAGS=\"-fPIC -ffreestanding -Wno-maybe-uninitialized -Wno-unused-const-variable -Werror -Wno-unknown-warning-option\"\n\tOSLDFLAGS=\"-lpthread -fPIC -fpie\"\n\tSRCS=\"\n\t\t$SRCS\n\t\t../rtl/tsan_platform_linux.cc\n\t\t../../sanitizer_common/sanitizer_posix.cc\n\t\t../../sanitizer_common/sanitizer_posix_libcdep.cc\n\t\t../../sanitizer_common/sanitizer_procmaps_common.cc\n\t\t../../sanitizer_common/sanitizer_procmaps_linux.cc\n\t\t../../sanitizer_common/sanitizer_linux.cc\n\t\t../../sanitizer_common/sanitizer_linux_libcdep.cc\n\t\t../../sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc\n\t\"\nelif [ \"`uname -a | grep FreeBSD`\" != \"\" ]; then\n        SUFFIX=\"freebsd_amd64\"\n        OSCFLAGS=\"-fno-strict-aliasing -fPIC -Werror\"\n        OSLDFLAGS=\"-lpthread -fPIC -fpie\"\n        SRCS=\"\n                $SRCS\n                ../rtl/tsan_platform_linux.cc\n                ../../sanitizer_common/sanitizer_posix.cc\n                ../../sanitizer_common/sanitizer_posix_libcdep.cc\n                ../../sanitizer_common/sanitizer_procmaps_common.cc\n                ../../sanitizer_common/sanitizer_procmaps_freebsd.cc\n                ../../sanitizer_common/sanitizer_linux.cc\n                ../../sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc\n        \"\nelif [ \"`uname -a | grep Darwin`\" != \"\" ]; then\n\tSUFFIX=\"darwin_amd64\"\n\tOSCFLAGS=\"-fPIC -Wno-unused-const-variable -Wno-unknown-warning-option\"\n\tOSLDFLAGS=\"-lpthread -fPIC -fpie\"\n\tSRCS=\"\n\t\t$SRCS\n\t\t../rtl/tsan_platform_mac.cc\n\t\t../../sanitizer_common/sanitizer_mac.cc\n\t\t../../sanitizer_common/sanitizer_posix.cc\n\t\t../../sanitizer_common/sanitizer_posix_libcdep.cc\n\t\t../../sanitizer_common/sanitizer_procmaps_mac.cc\n\t\"\nelif [ \"`uname -a | grep MINGW`\" != \"\" ]; then\n\tSUFFIX=\"windows_amd64\"\n\tOSCFLAGS=\"-Wno-error=attributes -Wno-attributes -Wno-unused-const-variable -Wno-unknown-warning-option\"\n\tOSLDFLAGS=\"\"\n\tSRCS=\"\n\t\t$SRCS\n\t\t../rtl/tsan_platform_windows.cc\n\t\t../../sanitizer_common/sanitizer_win.cc\n\t\"\nelse\n\techo Unknown platform\n\texit 1\nfi\n\nCC=${CC:-gcc}\nIN_TMPDIR=${IN_TMPDIR:-0}\nSILENT=${SILENT:-0}\n\nif [ $IN_TMPDIR != \"0\" ]; then\n  DIR=$(mktemp -qd /tmp/gotsan.XXXXXXXXXX)\n  cleanup() {\n    rm -rf $DIR\n  }\n  trap cleanup EXIT\nelse\n  DIR=.\nfi\n\nSRCS=\"$SRCS $ADD_SRCS\"\n\nrm -f $DIR/gotsan.cc\nfor F in $SRCS; do\n\tcat $F >> $DIR/gotsan.cc\ndone\n\nFLAGS=\" -I../rtl -I../.. -I../../sanitizer_common -I../../../include -std=c++11 -m64 -Wall -fno-exceptions -fno-rtti -DSANITIZER_GO -DSANITIZER_DEADLOCK_DETECTOR_VERSION=2 $OSCFLAGS\"\nif [ \"$DEBUG\" = \"\" ]; then\n\tFLAGS=\"$FLAGS -DSANITIZER_DEBUG=0 -O3 -msse3 -fomit-frame-pointer\"\nelse\n\tFLAGS=\"$FLAGS -DSANITIZER_DEBUG=1 -g\"\nfi\n\nif [ \"$SILENT\" != \"1\" ]; then\n  echo $CC gotsan.cc -c -o $DIR/race_$SUFFIX.syso $FLAGS $CFLAGS\nfi\n$CC $DIR/gotsan.cc -c -o $DIR/race_$SUFFIX.syso $FLAGS $CFLAGS\n\n$CC test.c $DIR/race_$SUFFIX.syso -m64 -o $DIR/test $OSLDFLAGS\n\nexport GORACE=\"exitcode=0 atexit_sleep_ms=0\"\nif [ \"$SILENT\" != \"1\" ]; then\n  $DIR/test\nelse\n  $DIR/test 2>/dev/null\nfi\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/go/test.c",
    "content": "//===-- test.c ------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Sanity test for Go runtime.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stdio.h>\n\nvoid __tsan_init(void **thr, void (*cb)(void*));\nvoid __tsan_fini();\nvoid __tsan_map_shadow(void *addr, unsigned long size);\nvoid __tsan_go_start(void *thr, void **chthr, void *pc);\nvoid __tsan_go_end(void *thr);\nvoid __tsan_read(void *thr, void *addr, void *pc);\nvoid __tsan_write(void *thr, void *addr, void *pc);\nvoid __tsan_func_enter(void *thr, void *pc);\nvoid __tsan_func_exit(void *thr);\nvoid __tsan_malloc(void *p, unsigned long sz);\nvoid __tsan_acquire(void *thr, void *addr);\nvoid __tsan_release(void *thr, void *addr);\nvoid __tsan_release_merge(void *thr, void *addr);\n\nvoid symbolize_cb(void *ctx) {}\n\nchar buf0[100<<10];\n\nvoid foobar() {}\nvoid barfoo() {}\n\nint main(void) {\n  void *thr0 = 0;\n  char *buf = (char*)((unsigned long)buf0 + (64<<10) - 1 & ~((64<<10) - 1));\n  __tsan_malloc(buf, 10);\n  __tsan_init(&thr0, symbolize_cb);\n  __tsan_map_shadow(buf, 4096);\n  __tsan_func_enter(thr0, (char*)&main + 1);\n  __tsan_malloc(buf, 10);\n  __tsan_release(thr0, buf);\n  __tsan_release_merge(thr0, buf);\n  void *thr1 = 0;\n  __tsan_go_start(thr0, &thr1, (char*)&barfoo + 1);\n  void *thr2 = 0;\n  __tsan_go_start(thr0, &thr2, (char*)&barfoo + 1);\n  __tsan_func_enter(thr1, (char*)&foobar + 1);\n  __tsan_func_enter(thr1, (char*)&foobar + 1);\n  __tsan_write(thr1, buf, (char*)&barfoo + 1);\n  __tsan_acquire(thr1, buf);\n  __tsan_func_exit(thr1);\n  __tsan_func_exit(thr1);\n  __tsan_go_end(thr1);\n  __tsan_func_enter(thr2, (char*)&foobar + 1);\n  __tsan_read(thr2, buf, (char*)&barfoo + 1);\n  __tsan_func_exit(thr2);\n  __tsan_go_end(thr2);\n  __tsan_func_exit(thr0);\n  __tsan_fini();\n  return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/go/tsan_go.cc",
    "content": "//===-- tsan_go.cc --------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// ThreadSanitizer runtime for Go language.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"tsan_rtl.h\"\n#include \"tsan_symbolize.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include <stdlib.h>\n\nnamespace __tsan {\n\nvoid InitializeInterceptors() {\n}\n\nvoid InitializeDynamicAnnotations() {\n}\n\nbool IsExpectedReport(uptr addr, uptr size) {\n  return false;\n}\n\nReportLocation *SymbolizeData(uptr addr) {\n  return 0;\n}\n\nvoid *internal_alloc(MBlockType typ, uptr sz) {\n  return InternalAlloc(sz);\n}\n\nvoid internal_free(void *p) {\n  InternalFree(p);\n}\n\nstruct SymbolizeContext {\n  uptr pc;\n  char *func;\n  char *file;\n  uptr line;\n  uptr off;\n  uptr res;\n};\n\n// Callback into Go.\nstatic void (*symbolize_cb)(SymbolizeContext *ctx);\n\nSymbolizedStack *SymbolizeCode(uptr addr) {\n  SymbolizedStack *s = SymbolizedStack::New(addr);\n  SymbolizeContext ctx;\n  internal_memset(&ctx, 0, sizeof(ctx));\n  ctx.pc = addr;\n  symbolize_cb(&ctx);\n  if (ctx.res) {\n    AddressInfo &info = s->info;\n    info.module_offset = ctx.off;\n    info.function = internal_strdup(ctx.func ? ctx.func : \"??\");\n    info.file = internal_strdup(ctx.file ? ctx.file : \"-\");\n    info.line = ctx.line;\n    info.column = 0;\n  }\n  return s;\n}\n\nextern \"C\" {\n\nstatic ThreadState *main_thr;\nstatic bool inited;\n\nstatic ThreadState *AllocGoroutine() {\n  ThreadState *thr = (ThreadState*)internal_alloc(MBlockThreadContex,\n      sizeof(ThreadState));\n  internal_memset(thr, 0, sizeof(*thr));\n  return thr;\n}\n\nvoid __tsan_init(ThreadState **thrp, void (*cb)(SymbolizeContext *cb)) {\n  symbolize_cb = cb;\n  ThreadState *thr = AllocGoroutine();\n  main_thr = *thrp = thr;\n  Initialize(thr);\n  inited = true;\n}\n\nvoid __tsan_fini() {\n  // FIXME: Not necessary thread 0.\n  ThreadState *thr = main_thr;\n  int res = Finalize(thr);\n  exit(res);\n}\n\nvoid __tsan_map_shadow(uptr addr, uptr size) {\n  MapShadow(addr, size);\n}\n\nvoid __tsan_read(ThreadState *thr, void *addr, void *pc) {\n  MemoryRead(thr, (uptr)pc, (uptr)addr, kSizeLog1);\n}\n\nvoid __tsan_read_pc(ThreadState *thr, void *addr, uptr callpc, uptr pc) {\n  if (callpc != 0)\n    FuncEntry(thr, callpc);\n  MemoryRead(thr, (uptr)pc, (uptr)addr, kSizeLog1);\n  if (callpc != 0)\n    FuncExit(thr);\n}\n\nvoid __tsan_write(ThreadState *thr, void *addr, void *pc) {\n  MemoryWrite(thr, (uptr)pc, (uptr)addr, kSizeLog1);\n}\n\nvoid __tsan_write_pc(ThreadState *thr, void *addr, uptr callpc, uptr pc) {\n  if (callpc != 0)\n    FuncEntry(thr, callpc);\n  MemoryWrite(thr, (uptr)pc, (uptr)addr, kSizeLog1);\n  if (callpc != 0)\n    FuncExit(thr);\n}\n\nvoid __tsan_read_range(ThreadState *thr, void *addr, uptr size, uptr pc) {\n  MemoryAccessRange(thr, (uptr)pc, (uptr)addr, size, false);\n}\n\nvoid __tsan_write_range(ThreadState *thr, void *addr, uptr size, uptr pc) {\n  MemoryAccessRange(thr, (uptr)pc, (uptr)addr, size, true);\n}\n\nvoid __tsan_func_enter(ThreadState *thr, void *pc) {\n  FuncEntry(thr, (uptr)pc);\n}\n\nvoid __tsan_func_exit(ThreadState *thr) {\n  FuncExit(thr);\n}\n\nvoid __tsan_malloc(void *p, uptr sz) {\n  if (!inited)\n    return;\n  MemoryResetRange(0, 0, (uptr)p, sz);\n}\n\nvoid __tsan_go_start(ThreadState *parent, ThreadState **pthr, void *pc) {\n  ThreadState *thr = AllocGoroutine();\n  *pthr = thr;\n  int goid = ThreadCreate(parent, (uptr)pc, 0, true);\n  ThreadStart(thr, goid, 0);\n}\n\nvoid __tsan_go_end(ThreadState *thr) {\n  ThreadFinish(thr);\n  internal_free(thr);\n}\n\nvoid __tsan_acquire(ThreadState *thr, void *addr) {\n  Acquire(thr, 0, (uptr)addr);\n}\n\nvoid __tsan_release(ThreadState *thr, void *addr) {\n  ReleaseStore(thr, 0, (uptr)addr);\n}\n\nvoid __tsan_release_merge(ThreadState *thr, void *addr) {\n  Release(thr, 0, (uptr)addr);\n}\n\nvoid __tsan_finalizer_goroutine(ThreadState *thr) {\n  AcquireGlobal(thr, 0);\n}\n\nvoid __tsan_mutex_before_lock(ThreadState *thr, uptr addr, uptr write) {\n}\n\nvoid __tsan_mutex_after_lock(ThreadState *thr, uptr addr, uptr write) {\n  if (write)\n    MutexLock(thr, 0, addr);\n  else\n    MutexReadLock(thr, 0, addr);\n}\n\nvoid __tsan_mutex_before_unlock(ThreadState *thr, uptr addr, uptr write) {\n  if (write)\n    MutexUnlock(thr, 0, addr);\n  else\n    MutexReadUnlock(thr, 0, addr);\n}\n\nvoid __tsan_go_ignore_sync_begin(ThreadState *thr) {\n  ThreadIgnoreSyncBegin(thr, 0);\n}\n\nvoid __tsan_go_ignore_sync_end(ThreadState *thr) {\n  ThreadIgnoreSyncEnd(thr, 0);\n}\n\n}  // extern \"C\"\n}  // namespace __tsan\n\nnamespace __sanitizer {\n\nvoid SymbolizerPrepareForSandboxing() {\n  // Nothing to do here for Go.\n}\n\n}  // namespace __sanitizer\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan.syms.extra",
    "content": "__tsan_init\n__tsan_read*\n__tsan_write*\n__tsan_vptr*\n__tsan_func*\n__tsan_atomic*\n__tsan_java*\n__tsan_unaligned*\n__tsan_release\n__tsan_acquire\n__ubsan_*\nAnnotate*\nWTFAnnotate*\nRunningOnValgrind\nValgrindSlowdown\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_clock.cc",
    "content": "//===-- tsan_clock.cc -----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_clock.h\"\n#include \"tsan_rtl.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n\n// SyncClock and ThreadClock implement vector clocks for sync variables\n// (mutexes, atomic variables, file descriptors, etc) and threads, respectively.\n// ThreadClock contains fixed-size vector clock for maximum number of threads.\n// SyncClock contains growable vector clock for currently necessary number of\n// threads.\n// Together they implement very simple model of operations, namely:\n//\n//   void ThreadClock::acquire(const SyncClock *src) {\n//     for (int i = 0; i < kMaxThreads; i++)\n//       clock[i] = max(clock[i], src->clock[i]);\n//   }\n//\n//   void ThreadClock::release(SyncClock *dst) const {\n//     for (int i = 0; i < kMaxThreads; i++)\n//       dst->clock[i] = max(dst->clock[i], clock[i]);\n//   }\n//\n//   void ThreadClock::ReleaseStore(SyncClock *dst) const {\n//     for (int i = 0; i < kMaxThreads; i++)\n//       dst->clock[i] = clock[i];\n//   }\n//\n//   void ThreadClock::acq_rel(SyncClock *dst) {\n//     acquire(dst);\n//     release(dst);\n//   }\n//\n// Conformance to this model is extensively verified in tsan_clock_test.cc.\n// However, the implementation is significantly more complex. The complexity\n// allows to implement important classes of use cases in O(1) instead of O(N).\n//\n// The use cases are:\n// 1. Singleton/once atomic that has a single release-store operation followed\n//    by zillions of acquire-loads (the acquire-load is O(1)).\n// 2. Thread-local mutex (both lock and unlock can be O(1)).\n// 3. Leaf mutex (unlock is O(1)).\n// 4. A mutex shared by 2 threads (both lock and unlock can be O(1)).\n// 5. An atomic with a single writer (writes can be O(1)).\n// The implementation dynamically adopts to workload. So if an atomic is in\n// read-only phase, these reads will be O(1); if it later switches to read/write\n// phase, the implementation will correctly handle that by switching to O(N).\n//\n// Thread-safety note: all const operations on SyncClock's are conducted under\n// a shared lock; all non-const operations on SyncClock's are conducted under\n// an exclusive lock; ThreadClock's are private to respective threads and so\n// do not need any protection.\n//\n// Description of ThreadClock state:\n// clk_ - fixed size vector clock.\n// nclk_ - effective size of the vector clock (the rest is zeros).\n// tid_ - index of the thread associated with he clock (\"current thread\").\n// last_acquire_ - current thread time when it acquired something from\n//   other threads.\n//\n// Description of SyncClock state:\n// clk_ - variable size vector clock, low kClkBits hold timestamp,\n//   the remaining bits hold \"acquired\" flag (the actual value is thread's\n//   reused counter);\n//   if acquried == thr->reused_, then the respective thread has already\n//   acquired this clock (except possibly dirty_tids_).\n// dirty_tids_ - holds up to two indeces in the vector clock that other threads\n//   need to acquire regardless of \"acquired\" flag value;\n// release_store_tid_ - denotes that the clock state is a result of\n//   release-store operation by the thread with release_store_tid_ index.\n// release_store_reused_ - reuse count of release_store_tid_.\n\n// We don't have ThreadState in these methods, so this is an ugly hack that\n// works only in C++.\n#ifndef SANITIZER_GO\n# define CPP_STAT_INC(typ) StatInc(cur_thread(), typ)\n#else\n# define CPP_STAT_INC(typ) (void)0\n#endif\n\nnamespace __tsan {\n\nThreadClock::ThreadClock(unsigned tid, unsigned reused)\n    : tid_(tid)\n    , reused_(reused + 1) {  // 0 has special meaning\n  CHECK_LT(tid, kMaxTidInClock);\n  CHECK_EQ(reused_, ((u64)reused_ << kClkBits) >> kClkBits);\n  nclk_ = tid_ + 1;\n  last_acquire_ = 0;\n  internal_memset(clk_, 0, sizeof(clk_));\n  clk_[tid_].reused = reused_;\n}\n\nvoid ThreadClock::acquire(ClockCache *c, const SyncClock *src) {\n  DCHECK_LE(nclk_, kMaxTid);\n  DCHECK_LE(src->size_, kMaxTid);\n  CPP_STAT_INC(StatClockAcquire);\n\n  // Check if it's empty -> no need to do anything.\n  const uptr nclk = src->size_;\n  if (nclk == 0) {\n    CPP_STAT_INC(StatClockAcquireEmpty);\n    return;\n  }\n\n  // Check if we've already acquired src after the last release operation on src\n  bool acquired = false;\n  if (nclk > tid_) {\n    CPP_STAT_INC(StatClockAcquireLarge);\n    if (src->elem(tid_).reused == reused_) {\n      CPP_STAT_INC(StatClockAcquireRepeat);\n      for (unsigned i = 0; i < kDirtyTids; i++) {\n        unsigned tid = src->dirty_tids_[i];\n        if (tid != kInvalidTid) {\n          u64 epoch = src->elem(tid).epoch;\n          if (clk_[tid].epoch < epoch) {\n            clk_[tid].epoch = epoch;\n            acquired = true;\n          }\n        }\n      }\n      if (acquired) {\n        CPP_STAT_INC(StatClockAcquiredSomething);\n        last_acquire_ = clk_[tid_].epoch;\n      }\n      return;\n    }\n  }\n\n  // O(N) acquire.\n  CPP_STAT_INC(StatClockAcquireFull);\n  nclk_ = max(nclk_, nclk);\n  for (uptr i = 0; i < nclk; i++) {\n    u64 epoch = src->elem(i).epoch;\n    if (clk_[i].epoch < epoch) {\n      clk_[i].epoch = epoch;\n      acquired = true;\n    }\n  }\n\n  // Remember that this thread has acquired this clock.\n  if (nclk > tid_)\n    src->elem(tid_).reused = reused_;\n\n  if (acquired) {\n    CPP_STAT_INC(StatClockAcquiredSomething);\n    last_acquire_ = clk_[tid_].epoch;\n  }\n}\n\nvoid ThreadClock::release(ClockCache *c, SyncClock *dst) const {\n  DCHECK_LE(nclk_, kMaxTid);\n  DCHECK_LE(dst->size_, kMaxTid);\n\n  if (dst->size_ == 0) {\n    // ReleaseStore will correctly set release_store_tid_,\n    // which can be important for future operations.\n    ReleaseStore(c, dst);\n    return;\n  }\n\n  CPP_STAT_INC(StatClockRelease);\n  // Check if we need to resize dst.\n  if (dst->size_ < nclk_)\n    dst->Resize(c, nclk_);\n\n  // Check if we had not acquired anything from other threads\n  // since the last release on dst. If so, we need to update\n  // only dst->elem(tid_).\n  if (dst->elem(tid_).epoch > last_acquire_) {\n    UpdateCurrentThread(dst);\n    if (dst->release_store_tid_ != tid_ ||\n        dst->release_store_reused_ != reused_)\n      dst->release_store_tid_ = kInvalidTid;\n    return;\n  }\n\n  // O(N) release.\n  CPP_STAT_INC(StatClockReleaseFull);\n  // First, remember whether we've acquired dst.\n  bool acquired = IsAlreadyAcquired(dst);\n  if (acquired)\n    CPP_STAT_INC(StatClockReleaseAcquired);\n  // Update dst->clk_.\n  for (uptr i = 0; i < nclk_; i++) {\n    ClockElem &ce = dst->elem(i);\n    ce.epoch = max(ce.epoch, clk_[i].epoch);\n    ce.reused = 0;\n  }\n  // Clear 'acquired' flag in the remaining elements.\n  if (nclk_ < dst->size_)\n    CPP_STAT_INC(StatClockReleaseClearTail);\n  for (uptr i = nclk_; i < dst->size_; i++)\n    dst->elem(i).reused = 0;\n  for (unsigned i = 0; i < kDirtyTids; i++)\n    dst->dirty_tids_[i] = kInvalidTid;\n  dst->release_store_tid_ = kInvalidTid;\n  dst->release_store_reused_ = 0;\n  // If we've acquired dst, remember this fact,\n  // so that we don't need to acquire it on next acquire.\n  if (acquired)\n    dst->elem(tid_).reused = reused_;\n}\n\nvoid ThreadClock::ReleaseStore(ClockCache *c, SyncClock *dst) const {\n  DCHECK_LE(nclk_, kMaxTid);\n  DCHECK_LE(dst->size_, kMaxTid);\n  CPP_STAT_INC(StatClockStore);\n\n  // Check if we need to resize dst.\n  if (dst->size_ < nclk_)\n    dst->Resize(c, nclk_);\n\n  if (dst->release_store_tid_ == tid_ &&\n      dst->release_store_reused_ == reused_ &&\n      dst->elem(tid_).epoch > last_acquire_) {\n    CPP_STAT_INC(StatClockStoreFast);\n    UpdateCurrentThread(dst);\n    return;\n  }\n\n  // O(N) release-store.\n  CPP_STAT_INC(StatClockStoreFull);\n  for (uptr i = 0; i < nclk_; i++) {\n    ClockElem &ce = dst->elem(i);\n    ce.epoch = clk_[i].epoch;\n    ce.reused = 0;\n  }\n  // Clear the tail of dst->clk_.\n  if (nclk_ < dst->size_) {\n    for (uptr i = nclk_; i < dst->size_; i++) {\n      ClockElem &ce = dst->elem(i);\n      ce.epoch = 0;\n      ce.reused = 0;\n    }\n    CPP_STAT_INC(StatClockStoreTail);\n  }\n  for (unsigned i = 0; i < kDirtyTids; i++)\n    dst->dirty_tids_[i] = kInvalidTid;\n  dst->release_store_tid_ = tid_;\n  dst->release_store_reused_ = reused_;\n  // Rememeber that we don't need to acquire it in future.\n  dst->elem(tid_).reused = reused_;\n}\n\nvoid ThreadClock::acq_rel(ClockCache *c, SyncClock *dst) {\n  CPP_STAT_INC(StatClockAcquireRelease);\n  acquire(c, dst);\n  ReleaseStore(c, dst);\n}\n\n// Updates only single element related to the current thread in dst->clk_.\nvoid ThreadClock::UpdateCurrentThread(SyncClock *dst) const {\n  // Update the threads time, but preserve 'acquired' flag.\n  dst->elem(tid_).epoch = clk_[tid_].epoch;\n\n  for (unsigned i = 0; i < kDirtyTids; i++) {\n    if (dst->dirty_tids_[i] == tid_) {\n      CPP_STAT_INC(StatClockReleaseFast1);\n      return;\n    }\n    if (dst->dirty_tids_[i] == kInvalidTid) {\n      CPP_STAT_INC(StatClockReleaseFast2);\n      dst->dirty_tids_[i] = tid_;\n      return;\n    }\n  }\n  // Reset all 'acquired' flags, O(N).\n  CPP_STAT_INC(StatClockReleaseSlow);\n  for (uptr i = 0; i < dst->size_; i++)\n    dst->elem(i).reused = 0;\n  for (unsigned i = 0; i < kDirtyTids; i++)\n    dst->dirty_tids_[i] = kInvalidTid;\n}\n\n// Checks whether the current threads has already acquired src.\nbool ThreadClock::IsAlreadyAcquired(const SyncClock *src) const {\n  if (src->elem(tid_).reused != reused_)\n    return false;\n  for (unsigned i = 0; i < kDirtyTids; i++) {\n    unsigned tid = src->dirty_tids_[i];\n    if (tid != kInvalidTid) {\n      if (clk_[tid].epoch < src->elem(tid).epoch)\n        return false;\n    }\n  }\n  return true;\n}\n\nvoid SyncClock::Resize(ClockCache *c, uptr nclk) {\n  CPP_STAT_INC(StatClockReleaseResize);\n  if (RoundUpTo(nclk, ClockBlock::kClockCount) <=\n      RoundUpTo(size_, ClockBlock::kClockCount)) {\n    // Growing within the same block.\n    // Memory is already allocated, just increase the size.\n    size_ = nclk;\n    return;\n  }\n  if (nclk <= ClockBlock::kClockCount) {\n    // Grow from 0 to one-level table.\n    CHECK_EQ(size_, 0);\n    CHECK_EQ(tab_, 0);\n    CHECK_EQ(tab_idx_, 0);\n    size_ = nclk;\n    tab_idx_ = ctx->clock_alloc.Alloc(c);\n    tab_ = ctx->clock_alloc.Map(tab_idx_);\n    internal_memset(tab_, 0, sizeof(*tab_));\n    return;\n  }\n  // Growing two-level table.\n  if (size_ == 0) {\n    // Allocate first level table.\n    tab_idx_ = ctx->clock_alloc.Alloc(c);\n    tab_ = ctx->clock_alloc.Map(tab_idx_);\n    internal_memset(tab_, 0, sizeof(*tab_));\n  } else if (size_ <= ClockBlock::kClockCount) {\n    // Transform one-level table to two-level table.\n    u32 old = tab_idx_;\n    tab_idx_ = ctx->clock_alloc.Alloc(c);\n    tab_ = ctx->clock_alloc.Map(tab_idx_);\n    internal_memset(tab_, 0, sizeof(*tab_));\n    tab_->table[0] = old;\n  }\n  // At this point we have first level table allocated.\n  // Add second level tables as necessary.\n  for (uptr i = RoundUpTo(size_, ClockBlock::kClockCount);\n      i < nclk; i += ClockBlock::kClockCount) {\n    u32 idx = ctx->clock_alloc.Alloc(c);\n    ClockBlock *cb = ctx->clock_alloc.Map(idx);\n    internal_memset(cb, 0, sizeof(*cb));\n    CHECK_EQ(tab_->table[i/ClockBlock::kClockCount], 0);\n    tab_->table[i/ClockBlock::kClockCount] = idx;\n  }\n  size_ = nclk;\n}\n\n// Sets a single element in the vector clock.\n// This function is called only from weird places like AcquireGlobal.\nvoid ThreadClock::set(unsigned tid, u64 v) {\n  DCHECK_LT(tid, kMaxTid);\n  DCHECK_GE(v, clk_[tid].epoch);\n  clk_[tid].epoch = v;\n  if (nclk_ <= tid)\n    nclk_ = tid + 1;\n  last_acquire_ = clk_[tid_].epoch;\n}\n\nvoid ThreadClock::DebugDump(int(*printf)(const char *s, ...)) {\n  printf(\"clock=[\");\n  for (uptr i = 0; i < nclk_; i++)\n    printf(\"%s%llu\", i == 0 ? \"\" : \",\", clk_[i].epoch);\n  printf(\"] reused=[\");\n  for (uptr i = 0; i < nclk_; i++)\n    printf(\"%s%llu\", i == 0 ? \"\" : \",\", clk_[i].reused);\n  printf(\"] tid=%u/%u last_acq=%llu\",\n      tid_, reused_, last_acquire_);\n}\n\nSyncClock::SyncClock()\n    : release_store_tid_(kInvalidTid)\n    , release_store_reused_()\n    , tab_()\n    , tab_idx_()\n    , size_() {\n  for (uptr i = 0; i < kDirtyTids; i++)\n    dirty_tids_[i] = kInvalidTid;\n}\n\nSyncClock::~SyncClock() {\n  // Reset must be called before dtor.\n  CHECK_EQ(size_, 0);\n  CHECK_EQ(tab_, 0);\n  CHECK_EQ(tab_idx_, 0);\n}\n\nvoid SyncClock::Reset(ClockCache *c) {\n  if (size_ == 0) {\n    // nothing\n  } else if (size_ <= ClockBlock::kClockCount) {\n    // One-level table.\n    ctx->clock_alloc.Free(c, tab_idx_);\n  } else {\n    // Two-level table.\n    for (uptr i = 0; i < size_; i += ClockBlock::kClockCount)\n      ctx->clock_alloc.Free(c, tab_->table[i / ClockBlock::kClockCount]);\n    ctx->clock_alloc.Free(c, tab_idx_);\n  }\n  tab_ = 0;\n  tab_idx_ = 0;\n  size_ = 0;\n  release_store_tid_ = kInvalidTid;\n  release_store_reused_ = 0;\n  for (uptr i = 0; i < kDirtyTids; i++)\n    dirty_tids_[i] = kInvalidTid;\n}\n\nClockElem &SyncClock::elem(unsigned tid) const {\n  DCHECK_LT(tid, size_);\n  if (size_ <= ClockBlock::kClockCount)\n    return tab_->clock[tid];\n  u32 idx = tab_->table[tid / ClockBlock::kClockCount];\n  ClockBlock *cb = ctx->clock_alloc.Map(idx);\n  return cb->clock[tid % ClockBlock::kClockCount];\n}\n\nvoid SyncClock::DebugDump(int(*printf)(const char *s, ...)) {\n  printf(\"clock=[\");\n  for (uptr i = 0; i < size_; i++)\n    printf(\"%s%llu\", i == 0 ? \"\" : \",\", elem(i).epoch);\n  printf(\"] reused=[\");\n  for (uptr i = 0; i < size_; i++)\n    printf(\"%s%llu\", i == 0 ? \"\" : \",\", elem(i).reused);\n  printf(\"] release_store_tid=%d/%d dirty_tids=%d/%d\",\n      release_store_tid_, release_store_reused_,\n      dirty_tids_[0], dirty_tids_[1]);\n}\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_clock.h",
    "content": "//===-- tsan_clock.h --------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_CLOCK_H\n#define TSAN_CLOCK_H\n\n#include \"tsan_defs.h\"\n#include \"tsan_dense_alloc.h\"\n\nnamespace __tsan {\n\nstruct ClockElem {\n  u64 epoch  : kClkBits;\n  u64 reused : 64 - kClkBits;\n};\n\nstruct ClockBlock {\n  static const uptr kSize = 512;\n  static const uptr kTableSize = kSize / sizeof(u32);\n  static const uptr kClockCount = kSize / sizeof(ClockElem);\n\n  union {\n    u32       table[kTableSize];\n    ClockElem clock[kClockCount];\n  };\n\n  ClockBlock() {\n  }\n};\n\ntypedef DenseSlabAlloc<ClockBlock, 1<<16, 1<<10> ClockAlloc;\ntypedef DenseSlabAllocCache ClockCache;\n\n// The clock that lives in sync variables (mutexes, atomics, etc).\nclass SyncClock {\n public:\n  SyncClock();\n  ~SyncClock();\n\n  uptr size() const {\n    return size_;\n  }\n\n  u64 get(unsigned tid) const {\n    return elem(tid).epoch;\n  }\n\n  void Resize(ClockCache *c, uptr nclk);\n  void Reset(ClockCache *c);\n\n  void DebugDump(int(*printf)(const char *s, ...));\n\n private:\n  friend struct ThreadClock;\n  static const uptr kDirtyTids = 2;\n\n  unsigned release_store_tid_;\n  unsigned release_store_reused_;\n  unsigned dirty_tids_[kDirtyTids];\n  // tab_ contains indirect pointer to a 512b block using DenseSlabAlloc.\n  // If size_ <= 64, then tab_ points to an array with 64 ClockElem's.\n  // Otherwise, tab_ points to an array with 128 u32 elements,\n  // each pointing to the second-level 512b block with 64 ClockElem's.\n  ClockBlock *tab_;\n  u32 tab_idx_;\n  u32 size_;\n\n  ClockElem &elem(unsigned tid) const;\n};\n\n// The clock that lives in threads.\nstruct ThreadClock {\n public:\n  typedef DenseSlabAllocCache Cache;\n\n  explicit ThreadClock(unsigned tid, unsigned reused = 0);\n\n  u64 get(unsigned tid) const {\n    DCHECK_LT(tid, kMaxTidInClock);\n    return clk_[tid].epoch;\n  }\n\n  void set(unsigned tid, u64 v);\n\n  void set(u64 v) {\n    DCHECK_GE(v, clk_[tid_].epoch);\n    clk_[tid_].epoch = v;\n  }\n\n  void tick() {\n    clk_[tid_].epoch++;\n  }\n\n  uptr size() const {\n    return nclk_;\n  }\n\n  void acquire(ClockCache *c, const SyncClock *src);\n  void release(ClockCache *c, SyncClock *dst) const;\n  void acq_rel(ClockCache *c, SyncClock *dst);\n  void ReleaseStore(ClockCache *c, SyncClock *dst) const;\n\n  void DebugReset();\n  void DebugDump(int(*printf)(const char *s, ...));\n\n private:\n  static const uptr kDirtyTids = SyncClock::kDirtyTids;\n  const unsigned tid_;\n  const unsigned reused_;\n  u64 last_acquire_;\n  uptr nclk_;\n  ClockElem clk_[kMaxTidInClock];\n\n  bool IsAlreadyAcquired(const SyncClock *src) const;\n  void UpdateCurrentThread(SyncClock *dst) const;\n};\n\n}  // namespace __tsan\n\n#endif  // TSAN_CLOCK_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_defs.h",
    "content": "//===-- tsan_defs.h ---------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef TSAN_DEFS_H\n#define TSAN_DEFS_H\n\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"tsan_stat.h\"\n#include \"ubsan/ubsan_platform.h\"\n\n// Setup defaults for compile definitions.\n#ifndef TSAN_NO_HISTORY\n# define TSAN_NO_HISTORY 0\n#endif\n\n#ifndef TSAN_COLLECT_STATS\n# define TSAN_COLLECT_STATS 0\n#endif\n\n#ifndef TSAN_CONTAINS_UBSAN\n# define TSAN_CONTAINS_UBSAN (CAN_SANITIZE_UB && !defined(SANITIZER_GO))\n#endif\n\nnamespace __tsan {\n\n#ifdef SANITIZER_GO\nconst bool kGoMode = true;\nconst bool kCppMode = false;\nconst char *const kTsanOptionsEnv = \"GORACE\";\n#else\nconst bool kGoMode = false;\nconst bool kCppMode = true;\nconst char *const kTsanOptionsEnv = \"TSAN_OPTIONS\";\n#endif\n\nconst int kTidBits = 13;\nconst unsigned kMaxTid = 1 << kTidBits;\n#ifndef SANITIZER_GO\nconst unsigned kMaxTidInClock = kMaxTid * 2;  // This includes msb 'freed' bit.\n#else\nconst unsigned kMaxTidInClock = kMaxTid;  // Go does not track freed memory.\n#endif\nconst int kClkBits = 42;\nconst unsigned kMaxTidReuse = (1 << (64 - kClkBits)) - 1;\nconst uptr kShadowStackSize = 64 * 1024;\n\n// Count of shadow values in a shadow cell.\nconst uptr kShadowCnt = 4;\n\n// That many user bytes are mapped onto a single shadow cell.\nconst uptr kShadowCell = 8;\n\n// Size of a single shadow value (u64).\nconst uptr kShadowSize = 8;\n\n// Shadow memory is kShadowMultiplier times larger than user memory.\nconst uptr kShadowMultiplier = kShadowSize * kShadowCnt / kShadowCell;\n\n// That many user bytes are mapped onto a single meta shadow cell.\n// Must be less or equal to minimal memory allocator alignment.\nconst uptr kMetaShadowCell = 8;\n\n// Size of a single meta shadow value (u32).\nconst uptr kMetaShadowSize = 4;\n\n#if TSAN_NO_HISTORY\nconst bool kCollectHistory = false;\n#else\nconst bool kCollectHistory = true;\n#endif\n\nconst unsigned kInvalidTid = (unsigned)-1;\n\n// The following \"build consistency\" machinery ensures that all source files\n// are built in the same configuration. Inconsistent builds lead to\n// hard to debug crashes.\n#if SANITIZER_DEBUG\nvoid build_consistency_debug();\n#else\nvoid build_consistency_release();\n#endif\n\n#if TSAN_COLLECT_STATS\nvoid build_consistency_stats();\n#else\nvoid build_consistency_nostats();\n#endif\n\nstatic inline void USED build_consistency() {\n#if SANITIZER_DEBUG\n  build_consistency_debug();\n#else\n  build_consistency_release();\n#endif\n#if TSAN_COLLECT_STATS\n  build_consistency_stats();\n#else\n  build_consistency_nostats();\n#endif\n}\n\ntemplate<typename T>\nT min(T a, T b) {\n  return a < b ? a : b;\n}\n\ntemplate<typename T>\nT max(T a, T b) {\n  return a > b ? a : b;\n}\n\ntemplate<typename T>\nT RoundUp(T p, u64 align) {\n  DCHECK_EQ(align & (align - 1), 0);\n  return (T)(((u64)p + align - 1) & ~(align - 1));\n}\n\ntemplate<typename T>\nT RoundDown(T p, u64 align) {\n  DCHECK_EQ(align & (align - 1), 0);\n  return (T)((u64)p & ~(align - 1));\n}\n\n// Zeroizes high part, returns 'bits' lsb bits.\ntemplate<typename T>\nT GetLsb(T v, int bits) {\n  return (T)((u64)v & ((1ull << bits) - 1));\n}\n\nstruct MD5Hash {\n  u64 hash[2];\n  bool operator==(const MD5Hash &other) const;\n};\n\nMD5Hash md5_hash(const void *data, uptr size);\n\nstruct ThreadState;\nclass ThreadContext;\nstruct Context;\nstruct ReportStack;\nclass ReportDesc;\nclass RegionAlloc;\n\n// Descriptor of user's memory block.\nstruct MBlock {\n  u64  siz;\n  u32  stk;\n  u16  tid;\n};\n\nCOMPILER_CHECK(sizeof(MBlock) == 16);\n\n}  // namespace __tsan\n\n#endif  // TSAN_DEFS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_dense_alloc.h",
    "content": "//===-- tsan_dense_alloc.h --------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// A DenseSlabAlloc is a freelist-based allocator of fixed-size objects.\n// DenseSlabAllocCache is a thread-local cache for DenseSlabAlloc.\n// The only difference with traditional slab allocators is that DenseSlabAlloc\n// allocates/free indices of objects and provide a functionality to map\n// the index onto the real pointer. The index is u32, that is, 2 times smaller\n// than uptr (hense the Dense prefix).\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_DENSE_ALLOC_H\n#define TSAN_DENSE_ALLOC_H\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"tsan_defs.h\"\n#include \"tsan_mutex.h\"\n\nnamespace __tsan {\n\nclass DenseSlabAllocCache {\n  static const uptr kSize = 128;\n  typedef u32 IndexT;\n  uptr pos;\n  IndexT cache[kSize];\n  template<typename T, uptr kL1Size, uptr kL2Size> friend class DenseSlabAlloc;\n};\n\ntemplate<typename T, uptr kL1Size, uptr kL2Size>\nclass DenseSlabAlloc {\n public:\n  typedef DenseSlabAllocCache Cache;\n  typedef typename Cache::IndexT IndexT;\n\n  DenseSlabAlloc() {\n    // Check that kL1Size and kL2Size are sane.\n    CHECK_EQ(kL1Size & (kL1Size - 1), 0);\n    CHECK_EQ(kL2Size & (kL2Size - 1), 0);\n    CHECK_GE(1ull << (sizeof(IndexT) * 8), kL1Size * kL2Size);\n    // Check that it makes sense to use the dense alloc.\n    CHECK_GE(sizeof(T), sizeof(IndexT));\n    internal_memset(map_, 0, sizeof(map_));\n    freelist_ = 0;\n    fillpos_ = 0;\n  }\n\n  ~DenseSlabAlloc() {\n    for (uptr i = 0; i < kL1Size; i++) {\n      if (map_[i] != 0)\n        UnmapOrDie(map_[i], kL2Size * sizeof(T));\n    }\n  }\n\n  IndexT Alloc(Cache *c) {\n    if (c->pos == 0)\n      Refill(c);\n    return c->cache[--c->pos];\n  }\n\n  void Free(Cache *c, IndexT idx) {\n    DCHECK_NE(idx, 0);\n    if (c->pos == Cache::kSize)\n      Drain(c);\n    c->cache[c->pos++] = idx;\n  }\n\n  T *Map(IndexT idx) {\n    DCHECK_NE(idx, 0);\n    DCHECK_LE(idx, kL1Size * kL2Size);\n    return &map_[idx / kL2Size][idx % kL2Size];\n  }\n\n  void FlushCache(Cache *c) {\n    SpinMutexLock lock(&mtx_);\n    while (c->pos) {\n      IndexT idx = c->cache[--c->pos];\n      *(IndexT*)Map(idx) = freelist_;\n      freelist_ = idx;\n    }\n  }\n\n  void InitCache(Cache *c) {\n    c->pos = 0;\n    internal_memset(c->cache, 0, sizeof(c->cache));\n  }\n\n private:\n  T *map_[kL1Size];\n  SpinMutex mtx_;\n  IndexT freelist_;\n  uptr fillpos_;\n\n  void Refill(Cache *c) {\n    SpinMutexLock lock(&mtx_);\n    if (freelist_ == 0) {\n      if (fillpos_ == kL1Size) {\n        Printf(\"ThreadSanitizer: DenseSlabAllocator overflow. Dying.\\n\");\n        Die();\n      }\n      T *batch = (T*)MmapOrDie(kL2Size * sizeof(T), \"DenseSlabAllocator\");\n      // Reserve 0 as invalid index.\n      IndexT start = fillpos_ == 0 ? 1 : 0;\n      for (IndexT i = start; i < kL2Size; i++) {\n        new(batch + i) T;\n        *(IndexT*)(batch + i) = i + 1 + fillpos_ * kL2Size;\n      }\n      *(IndexT*)(batch + kL2Size - 1) = 0;\n      freelist_ = fillpos_ * kL2Size + start;\n      map_[fillpos_++] = batch;\n    }\n    for (uptr i = 0; i < Cache::kSize / 2 && freelist_ != 0; i++) {\n      IndexT idx = freelist_;\n      c->cache[c->pos++] = idx;\n      freelist_ = *(IndexT*)Map(idx);\n    }\n  }\n\n  void Drain(Cache *c) {\n    SpinMutexLock lock(&mtx_);\n    for (uptr i = 0; i < Cache::kSize / 2; i++) {\n      IndexT idx = c->cache[--c->pos];\n      *(IndexT*)Map(idx) = freelist_;\n      freelist_ = idx;\n    }\n  }\n};\n\n}  // namespace __tsan\n\n#endif  // TSAN_DENSE_ALLOC_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_fd.cc",
    "content": "//===-- tsan_fd.cc --------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"tsan_fd.h\"\n#include \"tsan_rtl.h\"\n#include <sanitizer_common/sanitizer_atomic.h>\n\nnamespace __tsan {\n\nconst int kTableSizeL1 = 1024;\nconst int kTableSizeL2 = 1024;\nconst int kTableSize = kTableSizeL1 * kTableSizeL2;\n\nstruct FdSync {\n  atomic_uint64_t rc;\n};\n\nstruct FdDesc {\n  FdSync *sync;\n  int creation_tid;\n  u32 creation_stack;\n};\n\nstruct FdContext {\n  atomic_uintptr_t tab[kTableSizeL1];\n  // Addresses used for synchronization.\n  FdSync globsync;\n  FdSync filesync;\n  FdSync socksync;\n  u64 connectsync;\n};\n\nstatic FdContext fdctx;\n\nstatic bool bogusfd(int fd) {\n  // Apparently a bogus fd value.\n  return fd < 0 || fd >= kTableSize;\n}\n\nstatic FdSync *allocsync(ThreadState *thr, uptr pc) {\n  FdSync *s = (FdSync*)user_alloc(thr, pc, sizeof(FdSync), kDefaultAlignment,\n      false);\n  atomic_store(&s->rc, 1, memory_order_relaxed);\n  return s;\n}\n\nstatic FdSync *ref(FdSync *s) {\n  if (s && atomic_load(&s->rc, memory_order_relaxed) != (u64)-1)\n    atomic_fetch_add(&s->rc, 1, memory_order_relaxed);\n  return s;\n}\n\nstatic void unref(ThreadState *thr, uptr pc, FdSync *s) {\n  if (s && atomic_load(&s->rc, memory_order_relaxed) != (u64)-1) {\n    if (atomic_fetch_sub(&s->rc, 1, memory_order_acq_rel) == 1) {\n      CHECK_NE(s, &fdctx.globsync);\n      CHECK_NE(s, &fdctx.filesync);\n      CHECK_NE(s, &fdctx.socksync);\n      user_free(thr, pc, s, false);\n    }\n  }\n}\n\nstatic FdDesc *fddesc(ThreadState *thr, uptr pc, int fd) {\n  CHECK_GE(fd, 0);\n  CHECK_LT(fd, kTableSize);\n  atomic_uintptr_t *pl1 = &fdctx.tab[fd / kTableSizeL2];\n  uptr l1 = atomic_load(pl1, memory_order_consume);\n  if (l1 == 0) {\n    uptr size = kTableSizeL2 * sizeof(FdDesc);\n    // We need this to reside in user memory to properly catch races on it.\n    void *p = user_alloc(thr, pc, size, kDefaultAlignment, false);\n    internal_memset(p, 0, size);\n    MemoryResetRange(thr, (uptr)&fddesc, (uptr)p, size);\n    if (atomic_compare_exchange_strong(pl1, &l1, (uptr)p, memory_order_acq_rel))\n      l1 = (uptr)p;\n    else\n      user_free(thr, pc, p, false);\n  }\n  return &((FdDesc*)l1)[fd % kTableSizeL2];  // NOLINT\n}\n\n// pd must be already ref'ed.\nstatic void init(ThreadState *thr, uptr pc, int fd, FdSync *s,\n    bool write = true) {\n  FdDesc *d = fddesc(thr, pc, fd);\n  // As a matter of fact, we don't intercept all close calls.\n  // See e.g. libc __res_iclose().\n  if (d->sync) {\n    unref(thr, pc, d->sync);\n    d->sync = 0;\n  }\n  if (flags()->io_sync == 0) {\n    unref(thr, pc, s);\n  } else if (flags()->io_sync == 1) {\n    d->sync = s;\n  } else if (flags()->io_sync == 2) {\n    unref(thr, pc, s);\n    d->sync = &fdctx.globsync;\n  }\n  d->creation_tid = thr->tid;\n  d->creation_stack = CurrentStackId(thr, pc);\n  if (write) {\n    // To catch races between fd usage and open.\n    MemoryRangeImitateWrite(thr, pc, (uptr)d, 8);\n  } else {\n    // See the dup-related comment in FdClose.\n    MemoryRead(thr, pc, (uptr)d, kSizeLog8);\n  }\n}\n\nvoid FdInit() {\n  atomic_store(&fdctx.globsync.rc, (u64)-1, memory_order_relaxed);\n  atomic_store(&fdctx.filesync.rc, (u64)-1, memory_order_relaxed);\n  atomic_store(&fdctx.socksync.rc, (u64)-1, memory_order_relaxed);\n}\n\nvoid FdOnFork(ThreadState *thr, uptr pc) {\n  // On fork() we need to reset all fd's, because the child is going\n  // close all them, and that will cause races between previous read/write\n  // and the close.\n  for (int l1 = 0; l1 < kTableSizeL1; l1++) {\n    FdDesc *tab = (FdDesc*)atomic_load(&fdctx.tab[l1], memory_order_relaxed);\n    if (tab == 0)\n      break;\n    for (int l2 = 0; l2 < kTableSizeL2; l2++) {\n      FdDesc *d = &tab[l2];\n      MemoryResetRange(thr, pc, (uptr)d, 8);\n    }\n  }\n}\n\nbool FdLocation(uptr addr, int *fd, int *tid, u32 *stack) {\n  for (int l1 = 0; l1 < kTableSizeL1; l1++) {\n    FdDesc *tab = (FdDesc*)atomic_load(&fdctx.tab[l1], memory_order_relaxed);\n    if (tab == 0)\n      break;\n    if (addr >= (uptr)tab && addr < (uptr)(tab + kTableSizeL2)) {\n      int l2 = (addr - (uptr)tab) / sizeof(FdDesc);\n      FdDesc *d = &tab[l2];\n      *fd = l1 * kTableSizeL1 + l2;\n      *tid = d->creation_tid;\n      *stack = d->creation_stack;\n      return true;\n    }\n  }\n  return false;\n}\n\nvoid FdAcquire(ThreadState *thr, uptr pc, int fd) {\n  if (bogusfd(fd))\n    return;\n  FdDesc *d = fddesc(thr, pc, fd);\n  FdSync *s = d->sync;\n  DPrintf(\"#%d: FdAcquire(%d) -> %p\\n\", thr->tid, fd, s);\n  MemoryRead(thr, pc, (uptr)d, kSizeLog8);\n  if (s)\n    Acquire(thr, pc, (uptr)s);\n}\n\nvoid FdRelease(ThreadState *thr, uptr pc, int fd) {\n  if (bogusfd(fd))\n    return;\n  FdDesc *d = fddesc(thr, pc, fd);\n  FdSync *s = d->sync;\n  DPrintf(\"#%d: FdRelease(%d) -> %p\\n\", thr->tid, fd, s);\n  MemoryRead(thr, pc, (uptr)d, kSizeLog8);\n  if (s)\n    Release(thr, pc, (uptr)s);\n}\n\nvoid FdAccess(ThreadState *thr, uptr pc, int fd) {\n  DPrintf(\"#%d: FdAccess(%d)\\n\", thr->tid, fd);\n  if (bogusfd(fd))\n    return;\n  FdDesc *d = fddesc(thr, pc, fd);\n  MemoryRead(thr, pc, (uptr)d, kSizeLog8);\n}\n\nvoid FdClose(ThreadState *thr, uptr pc, int fd, bool write) {\n  DPrintf(\"#%d: FdClose(%d)\\n\", thr->tid, fd);\n  if (bogusfd(fd))\n    return;\n  FdDesc *d = fddesc(thr, pc, fd);\n  if (write) {\n    // To catch races between fd usage and close.\n    MemoryWrite(thr, pc, (uptr)d, kSizeLog8);\n  } else {\n    // This path is used only by dup2/dup3 calls.\n    // We do read instead of write because there is a number of legitimate\n    // cases where write would lead to false positives:\n    // 1. Some software dups a closed pipe in place of a socket before closing\n    //    the socket (to prevent races actually).\n    // 2. Some daemons dup /dev/null in place of stdin/stdout.\n    // On the other hand we have not seen cases when write here catches real\n    // bugs.\n    MemoryRead(thr, pc, (uptr)d, kSizeLog8);\n  }\n  // We need to clear it, because if we do not intercept any call out there\n  // that creates fd, we will hit false postives.\n  MemoryResetRange(thr, pc, (uptr)d, 8);\n  unref(thr, pc, d->sync);\n  d->sync = 0;\n  d->creation_tid = 0;\n  d->creation_stack = 0;\n}\n\nvoid FdFileCreate(ThreadState *thr, uptr pc, int fd) {\n  DPrintf(\"#%d: FdFileCreate(%d)\\n\", thr->tid, fd);\n  if (bogusfd(fd))\n    return;\n  init(thr, pc, fd, &fdctx.filesync);\n}\n\nvoid FdDup(ThreadState *thr, uptr pc, int oldfd, int newfd, bool write) {\n  DPrintf(\"#%d: FdDup(%d, %d)\\n\", thr->tid, oldfd, newfd);\n  if (bogusfd(oldfd) || bogusfd(newfd))\n    return;\n  // Ignore the case when user dups not yet connected socket.\n  FdDesc *od = fddesc(thr, pc, oldfd);\n  MemoryRead(thr, pc, (uptr)od, kSizeLog8);\n  FdClose(thr, pc, newfd, write);\n  init(thr, pc, newfd, ref(od->sync), write);\n}\n\nvoid FdPipeCreate(ThreadState *thr, uptr pc, int rfd, int wfd) {\n  DPrintf(\"#%d: FdCreatePipe(%d, %d)\\n\", thr->tid, rfd, wfd);\n  FdSync *s = allocsync(thr, pc);\n  init(thr, pc, rfd, ref(s));\n  init(thr, pc, wfd, ref(s));\n  unref(thr, pc, s);\n}\n\nvoid FdEventCreate(ThreadState *thr, uptr pc, int fd) {\n  DPrintf(\"#%d: FdEventCreate(%d)\\n\", thr->tid, fd);\n  if (bogusfd(fd))\n    return;\n  init(thr, pc, fd, allocsync(thr, pc));\n}\n\nvoid FdSignalCreate(ThreadState *thr, uptr pc, int fd) {\n  DPrintf(\"#%d: FdSignalCreate(%d)\\n\", thr->tid, fd);\n  if (bogusfd(fd))\n    return;\n  init(thr, pc, fd, 0);\n}\n\nvoid FdInotifyCreate(ThreadState *thr, uptr pc, int fd) {\n  DPrintf(\"#%d: FdInotifyCreate(%d)\\n\", thr->tid, fd);\n  if (bogusfd(fd))\n    return;\n  init(thr, pc, fd, 0);\n}\n\nvoid FdPollCreate(ThreadState *thr, uptr pc, int fd) {\n  DPrintf(\"#%d: FdPollCreate(%d)\\n\", thr->tid, fd);\n  if (bogusfd(fd))\n    return;\n  init(thr, pc, fd, allocsync(thr, pc));\n}\n\nvoid FdSocketCreate(ThreadState *thr, uptr pc, int fd) {\n  DPrintf(\"#%d: FdSocketCreate(%d)\\n\", thr->tid, fd);\n  if (bogusfd(fd))\n    return;\n  // It can be a UDP socket.\n  init(thr, pc, fd, &fdctx.socksync);\n}\n\nvoid FdSocketAccept(ThreadState *thr, uptr pc, int fd, int newfd) {\n  DPrintf(\"#%d: FdSocketAccept(%d, %d)\\n\", thr->tid, fd, newfd);\n  if (bogusfd(fd))\n    return;\n  // Synchronize connect->accept.\n  Acquire(thr, pc, (uptr)&fdctx.connectsync);\n  init(thr, pc, newfd, &fdctx.socksync);\n}\n\nvoid FdSocketConnecting(ThreadState *thr, uptr pc, int fd) {\n  DPrintf(\"#%d: FdSocketConnecting(%d)\\n\", thr->tid, fd);\n  if (bogusfd(fd))\n    return;\n  // Synchronize connect->accept.\n  Release(thr, pc, (uptr)&fdctx.connectsync);\n}\n\nvoid FdSocketConnect(ThreadState *thr, uptr pc, int fd) {\n  DPrintf(\"#%d: FdSocketConnect(%d)\\n\", thr->tid, fd);\n  if (bogusfd(fd))\n    return;\n  init(thr, pc, fd, &fdctx.socksync);\n}\n\nuptr File2addr(const char *path) {\n  (void)path;\n  static u64 addr;\n  return (uptr)&addr;\n}\n\nuptr Dir2addr(const char *path) {\n  (void)path;\n  static u64 addr;\n  return (uptr)&addr;\n}\n\n}  //  namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_fd.h",
    "content": "//===-- tsan_fd.h -----------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// This file handles synchronization via IO.\n// People use IO for synchronization along the lines of:\n//\n// int X;\n// int client_socket;  // initialized elsewhere\n// int server_socket;  // initialized elsewhere\n//\n// Thread 1:\n// X = 42;\n// send(client_socket, ...);\n//\n// Thread 2:\n// if (recv(server_socket, ...) > 0)\n//   assert(X == 42);\n//\n// This file determines the scope of the file descriptor (pipe, socket,\n// all local files, etc) and executes acquire and release operations on\n// the scope as necessary.  Some scopes are very fine grained (e.g. pipe\n// operations synchronize only with operations on the same pipe), while\n// others are corse-grained (e.g. all operations on local files synchronize\n// with each other).\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_FD_H\n#define TSAN_FD_H\n\n#include \"tsan_rtl.h\"\n\nnamespace __tsan {\n\nvoid FdInit();\nvoid FdAcquire(ThreadState *thr, uptr pc, int fd);\nvoid FdRelease(ThreadState *thr, uptr pc, int fd);\nvoid FdAccess(ThreadState *thr, uptr pc, int fd);\nvoid FdClose(ThreadState *thr, uptr pc, int fd, bool write = true);\nvoid FdFileCreate(ThreadState *thr, uptr pc, int fd);\nvoid FdDup(ThreadState *thr, uptr pc, int oldfd, int newfd, bool write);\nvoid FdPipeCreate(ThreadState *thr, uptr pc, int rfd, int wfd);\nvoid FdEventCreate(ThreadState *thr, uptr pc, int fd);\nvoid FdSignalCreate(ThreadState *thr, uptr pc, int fd);\nvoid FdInotifyCreate(ThreadState *thr, uptr pc, int fd);\nvoid FdPollCreate(ThreadState *thr, uptr pc, int fd);\nvoid FdSocketCreate(ThreadState *thr, uptr pc, int fd);\nvoid FdSocketAccept(ThreadState *thr, uptr pc, int fd, int newfd);\nvoid FdSocketConnecting(ThreadState *thr, uptr pc, int fd);\nvoid FdSocketConnect(ThreadState *thr, uptr pc, int fd);\nbool FdLocation(uptr addr, int *fd, int *tid, u32 *stack);\nvoid FdOnFork(ThreadState *thr, uptr pc);\n\nuptr File2addr(const char *path);\nuptr Dir2addr(const char *path);\n\n}  // namespace __tsan\n\n#endif  // TSAN_INTERFACE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_flags.cc",
    "content": "//===-- tsan_flags.cc -----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_flag_parser.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"tsan_flags.h\"\n#include \"tsan_rtl.h\"\n#include \"tsan_mman.h\"\n#include \"ubsan/ubsan_flags.h\"\n\nnamespace __tsan {\n\nFlags *flags() {\n  return &ctx->flags;\n}\n\n// Can be overriden in frontend.\n#ifdef TSAN_EXTERNAL_HOOKS\nextern \"C\" const char* __tsan_default_options();\n#else\nSANITIZER_WEAK_DEFAULT_IMPL\nconst char *__tsan_default_options() {\n  return \"\";\n}\n#endif\n\nvoid Flags::SetDefaults() {\n#define TSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;\n#include \"tsan_flags.inc\"\n#undef TSAN_FLAG\n  // DDFlags\n  second_deadlock_stack = false;\n}\n\nvoid RegisterTsanFlags(FlagParser *parser, Flags *f) {\n#define TSAN_FLAG(Type, Name, DefaultValue, Description) \\\n  RegisterFlag(parser, #Name, Description, &f->Name);\n#include \"tsan_flags.inc\"\n#undef TSAN_FLAG\n  // DDFlags\n  RegisterFlag(parser, \"second_deadlock_stack\",\n      \"Report where each mutex is locked in deadlock reports\",\n      &f->second_deadlock_stack);\n}\n\nvoid InitializeFlags(Flags *f, const char *env) {\n  SetCommonFlagsDefaults();\n  {\n    // Override some common flags defaults.\n    CommonFlags cf;\n    cf.CopyFrom(*common_flags());\n    cf.allow_addr2line = true;\n    if (kGoMode) {\n      // Does not work as expected for Go: runtime handles SIGABRT and crashes.\n      cf.abort_on_error = false;\n      // Go does not have mutexes.\n    } else {\n      cf.detect_deadlocks = true;\n    }\n    cf.print_suppressions = false;\n    cf.stack_trace_format = \"    #%n %f %S %M\";\n    cf.exitcode = 66;\n    OverrideCommonFlags(cf);\n  }\n\n  f->SetDefaults();\n\n  FlagParser parser;\n  RegisterTsanFlags(&parser, f);\n  RegisterCommonFlags(&parser);\n\n#if TSAN_CONTAINS_UBSAN\n  __ubsan::Flags *uf = __ubsan::flags();\n  uf->SetDefaults();\n\n  FlagParser ubsan_parser;\n  __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);\n  RegisterCommonFlags(&ubsan_parser);\n#endif\n\n  // Let a frontend override.\n  parser.ParseString(__tsan_default_options());\n#if TSAN_CONTAINS_UBSAN\n  const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();\n  ubsan_parser.ParseString(ubsan_default_options);\n#endif\n  // Override from command line.\n  parser.ParseString(env);\n#if TSAN_CONTAINS_UBSAN\n  ubsan_parser.ParseString(GetEnv(\"UBSAN_OPTIONS\"));\n#endif\n\n  // Sanity check.\n  if (!f->report_bugs) {\n    f->report_thread_leaks = false;\n    f->report_destroy_locked = false;\n    f->report_signal_unsafe = false;\n  }\n\n  SetVerbosity(common_flags()->verbosity);\n\n  if (Verbosity()) ReportUnrecognizedFlags();\n\n  if (common_flags()->help) parser.PrintFlagDescriptions();\n\n  if (f->history_size < 0 || f->history_size > 7) {\n    Printf(\"ThreadSanitizer: incorrect value for history_size\"\n           \" (must be [0..7])\\n\");\n    Die();\n  }\n\n  if (f->io_sync < 0 || f->io_sync > 2) {\n    Printf(\"ThreadSanitizer: incorrect value for io_sync\"\n           \" (must be [0..2])\\n\");\n    Die();\n  }\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_flags.h",
    "content": "//===-- tsan_flags.h --------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n// NOTE: This file may be included into user code.\n//===----------------------------------------------------------------------===//\n\n#ifndef TSAN_FLAGS_H\n#define TSAN_FLAGS_H\n\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_deadlock_detector_interface.h\"\n\nnamespace __tsan {\n\nstruct Flags : DDFlags {\n#define TSAN_FLAG(Type, Name, DefaultValue, Description) Type Name;\n#include \"tsan_flags.inc\"\n#undef TSAN_FLAG\n\n  void SetDefaults();\n  void ParseFromString(const char *str);\n};\n\nFlags *flags();\nvoid InitializeFlags(Flags *flags, const char *env);\n}  // namespace __tsan\n\n#endif  // TSAN_FLAGS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_flags.inc",
    "content": "//===-- tsan_flags.inc ------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// TSan runtime flags.\n//\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_FLAG\n# error \"Define TSAN_FLAG prior to including this file!\"\n#endif\n\n// TSAN_FLAG(Type, Name, DefaultValue, Description)\n// See COMMON_FLAG in sanitizer_flags.inc for more details.\n\nTSAN_FLAG(bool, enable_annotations, true,\n          \"Enable dynamic annotations, otherwise they are no-ops.\")\n// Suppress a race report if we've already output another race report\n// with the same stack.\nTSAN_FLAG(bool, suppress_equal_stacks, true,\n          \"Suppress a race report if we've already output another race report \"\n          \"with the same stack.\")\nTSAN_FLAG(bool, suppress_equal_addresses, true,\n          \"Suppress a race report if we've already output another race report \"\n          \"on the same address.\")\n\nTSAN_FLAG(bool, report_bugs, true,\n          \"Turns off bug reporting entirely (useful for benchmarking).\")\nTSAN_FLAG(bool, report_thread_leaks, true, \"Report thread leaks at exit?\")\nTSAN_FLAG(bool, report_destroy_locked, true,\n          \"Report destruction of a locked mutex?\")\nTSAN_FLAG(bool, report_mutex_bugs, true,\n          \"Report incorrect usages of mutexes and mutex annotations?\")\nTSAN_FLAG(bool, report_signal_unsafe, true,\n          \"Report violations of async signal-safety \"\n          \"(e.g. malloc() call from a signal handler).\")\nTSAN_FLAG(bool, report_atomic_races, true,\n          \"Report races between atomic and plain memory accesses.\")\nTSAN_FLAG(\n    bool, force_seq_cst_atomics, false,\n    \"If set, all atomics are effectively sequentially consistent (seq_cst), \"\n    \"regardless of what user actually specified.\")\nTSAN_FLAG(bool, print_benign, false, \"Print matched \\\"benign\\\" races at exit.\")\nTSAN_FLAG(bool, halt_on_error, false, \"Exit after first reported error.\")\nTSAN_FLAG(int, atexit_sleep_ms, 1000,\n          \"Sleep in main thread before exiting for that many ms \"\n          \"(useful to catch \\\"at exit\\\" races).\")\nTSAN_FLAG(const char *, profile_memory, \"\",\n          \"If set, periodically write memory profile to that file.\")\nTSAN_FLAG(int, flush_memory_ms, 0, \"Flush shadow memory every X ms.\")\nTSAN_FLAG(int, flush_symbolizer_ms, 5000, \"Flush symbolizer caches every X ms.\")\nTSAN_FLAG(\n    int, memory_limit_mb, 0,\n    \"Resident memory limit in MB to aim at.\"\n    \"If the process consumes more memory, then TSan will flush shadow memory.\")\nTSAN_FLAG(bool, stop_on_start, false,\n          \"Stops on start until __tsan_resume() is called (for debugging).\")\nTSAN_FLAG(bool, running_on_valgrind, false,\n          \"Controls whether RunningOnValgrind() returns true or false.\")\nTSAN_FLAG(\n    int, history_size, kGoMode ? 1 : 3, // There are a lot of goroutines in Go.\n    \"Per-thread history size, controls how many previous memory accesses \"\n    \"are remembered per thread.  Possible values are [0..7]. \"\n    \"history_size=0 amounts to 32K memory accesses.  Each next value doubles \"\n    \"the amount of memory accesses, up to history_size=7 that amounts to \"\n    \"4M memory accesses.  The default value is 2 (128K memory accesses).\")\nTSAN_FLAG(int, io_sync, 1,\n          \"Controls level of synchronization implied by IO operations. \"\n          \"0 - no synchronization \"\n          \"1 - reasonable level of synchronization (write->read)\"\n          \"2 - global synchronization of all IO operations.\")\nTSAN_FLAG(bool, die_after_fork, true,\n          \"Die after multi-threaded fork if the child creates new threads.\")\nTSAN_FLAG(const char *, suppressions, \"\", \"Suppressions file name.\")\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_ignoreset.cc",
    "content": "//===-- tsan_ignoreset.cc -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_ignoreset.h\"\n\nnamespace __tsan {\n\nconst uptr IgnoreSet::kMaxSize;\n\nIgnoreSet::IgnoreSet()\n    : size_() {\n}\n\nvoid IgnoreSet::Add(u32 stack_id) {\n  if (size_ == kMaxSize)\n    return;\n  for (uptr i = 0; i < size_; i++) {\n    if (stacks_[i] == stack_id)\n      return;\n  }\n  stacks_[size_++] = stack_id;\n}\n\nvoid IgnoreSet::Reset() {\n  size_ = 0;\n}\n\nuptr IgnoreSet::Size() const {\n  return size_;\n}\n\nu32 IgnoreSet::At(uptr i) const {\n  CHECK_LT(i, size_);\n  CHECK_LE(size_, kMaxSize);\n  return stacks_[i];\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_ignoreset.h",
    "content": "//===-- tsan_ignoreset.h ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// IgnoreSet holds a set of stack traces where ignores were enabled.\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_IGNORESET_H\n#define TSAN_IGNORESET_H\n\n#include \"tsan_defs.h\"\n\nnamespace __tsan {\n\nclass IgnoreSet {\n public:\n  static const uptr kMaxSize = 16;\n\n  IgnoreSet();\n  void Add(u32 stack_id);\n  void Reset();\n  uptr Size() const;\n  u32 At(uptr i) const;\n\n private:\n  uptr size_;\n  u32 stacks_[kMaxSize];\n};\n\n}  // namespace __tsan\n\n#endif  // TSAN_IGNORESET_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc",
    "content": "//===-- tsan_interceptors.cc ----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// FIXME: move as many interceptors as possible into\n// sanitizer_common/sanitizer_common_interceptors.inc\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_linux.h\"\n#include \"sanitizer_common/sanitizer_platform_limits_posix.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"interception/interception.h\"\n#include \"tsan_interceptors.h\"\n#include \"tsan_interface.h\"\n#include \"tsan_platform.h\"\n#include \"tsan_suppressions.h\"\n#include \"tsan_rtl.h\"\n#include \"tsan_mman.h\"\n#include \"tsan_fd.h\"\n\n#if SANITIZER_POSIX\n#include \"sanitizer_common/sanitizer_posix.h\"\n#endif\n\nusing namespace __tsan;  // NOLINT\n\n#if SANITIZER_FREEBSD || SANITIZER_MAC\n#define __errno_location __error\n#define stdout __stdoutp\n#define stderr __stderrp\n#endif\n\n#if SANITIZER_FREEBSD\n#define __libc_realloc __realloc\n#define __libc_calloc __calloc\n#elif SANITIZER_MAC\n#define __libc_malloc REAL(malloc)\n#define __libc_realloc REAL(realloc)\n#define __libc_calloc REAL(calloc)\n#define __libc_free REAL(free)\n#elif SANITIZER_ANDROID\n#define __errno_location __errno\n#define __libc_malloc REAL(malloc)\n#define __libc_realloc REAL(realloc)\n#define __libc_calloc REAL(calloc)\n#define __libc_free REAL(free)\n#define mallopt(a, b)\n#endif\n\n#if SANITIZER_LINUX || SANITIZER_FREEBSD\n#define PTHREAD_CREATE_DETACHED 1\n#elif SANITIZER_MAC\n#define PTHREAD_CREATE_DETACHED 2\n#endif\n\n\n#ifdef __mips__\nconst int kSigCount = 129;\n#else\nconst int kSigCount = 65;\n#endif\n\nstruct my_siginfo_t {\n  // The size is determined by looking at sizeof of real siginfo_t on linux.\n  u64 opaque[128 / sizeof(u64)];\n};\n\n#ifdef __mips__\nstruct ucontext_t {\n  u64 opaque[768 / sizeof(u64) + 1];\n};\n#else\nstruct ucontext_t {\n  // The size is determined by looking at sizeof of real ucontext_t on linux.\n  u64 opaque[936 / sizeof(u64) + 1];\n};\n#endif\n\n#if defined(__x86_64__) || defined(__mips__) \\\n  || (defined(__powerpc64__) && defined(__BIG_ENDIAN__))\n#define PTHREAD_ABI_BASE  \"GLIBC_2.3.2\"\n#elif defined(__aarch64__) || (defined(__powerpc64__) \\\n  && defined(__LITTLE_ENDIAN__))\n#define PTHREAD_ABI_BASE  \"GLIBC_2.17\"\n#endif\n\nextern \"C\" int pthread_attr_init(void *attr);\nextern \"C\" int pthread_attr_destroy(void *attr);\nDECLARE_REAL(int, pthread_attr_getdetachstate, void *, void *)\nextern \"C\" int pthread_attr_setstacksize(void *attr, uptr stacksize);\nextern \"C\" int pthread_key_create(unsigned *key, void (*destructor)(void* v));\nextern \"C\" int pthread_setspecific(unsigned key, const void *v);\nDECLARE_REAL(int, pthread_mutexattr_gettype, void *, void *)\nextern \"C\" int pthread_sigmask(int how, const __sanitizer_sigset_t *set,\n                               __sanitizer_sigset_t *oldset);\n// REAL(sigfillset) defined in common interceptors.\nDECLARE_REAL(int, sigfillset, __sanitizer_sigset_t *set)\nDECLARE_REAL(int, fflush, __sanitizer_FILE *fp)\nDECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr size)\nDECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr)\nextern \"C\" void *pthread_self();\nextern \"C\" void _exit(int status);\nextern \"C\" int *__errno_location();\nextern \"C\" int fileno_unlocked(void *stream);\n#if !SANITIZER_ANDROID\nextern \"C\" void *__libc_calloc(uptr size, uptr n);\nextern \"C\" void *__libc_realloc(void *ptr, uptr size);\n#endif\nextern \"C\" int dirfd(void *dirp);\n#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID\nextern \"C\" int mallopt(int param, int value);\n#endif\nextern __sanitizer_FILE *stdout, *stderr;\nconst int PTHREAD_MUTEX_RECURSIVE = 1;\nconst int PTHREAD_MUTEX_RECURSIVE_NP = 1;\nconst int EINVAL = 22;\nconst int EBUSY = 16;\nconst int EOWNERDEAD = 130;\n#if !SANITIZER_MAC\nconst int EPOLL_CTL_ADD = 1;\n#endif\nconst int SIGILL = 4;\nconst int SIGABRT = 6;\nconst int SIGFPE = 8;\nconst int SIGSEGV = 11;\nconst int SIGPIPE = 13;\nconst int SIGTERM = 15;\n#if defined(__mips__) || SANITIZER_MAC\nconst int SIGBUS = 10;\nconst int SIGSYS = 12;\n#else\nconst int SIGBUS = 7;\nconst int SIGSYS = 31;\n#endif\nvoid *const MAP_FAILED = (void*)-1;\n#if !SANITIZER_MAC\nconst int PTHREAD_BARRIER_SERIAL_THREAD = -1;\n#endif\nconst int MAP_FIXED = 0x10;\ntypedef long long_t;  // NOLINT\n\n// From /usr/include/unistd.h\n# define F_ULOCK 0      /* Unlock a previously locked region.  */\n# define F_LOCK  1      /* Lock a region for exclusive use.  */\n# define F_TLOCK 2      /* Test and lock a region for exclusive use.  */\n# define F_TEST  3      /* Test a region for other processes locks.  */\n\n#define errno (*__errno_location())\n\ntypedef void (*sighandler_t)(int sig);\ntypedef void (*sigactionhandler_t)(int sig, my_siginfo_t *siginfo, void *uctx);\n\n#if SANITIZER_ANDROID\nstruct sigaction_t {\n  u32 sa_flags;\n  union {\n    sighandler_t sa_handler;\n    sigactionhandler_t sa_sgiaction;\n  };\n  __sanitizer_sigset_t sa_mask;\n  void (*sa_restorer)();\n};\n#else\nstruct sigaction_t {\n#ifdef __mips__\n  u32 sa_flags;\n#endif\n  union {\n    sighandler_t sa_handler;\n    sigactionhandler_t sa_sigaction;\n  };\n#if SANITIZER_FREEBSD\n  int sa_flags;\n  __sanitizer_sigset_t sa_mask;\n#elif SANITIZER_MAC\n  __sanitizer_sigset_t sa_mask;\n  int sa_flags;\n#else\n  __sanitizer_sigset_t sa_mask;\n#ifndef __mips__\n  int sa_flags;\n#endif\n  void (*sa_restorer)();\n#endif\n};\n#endif\n\nconst sighandler_t SIG_DFL = (sighandler_t)0;\nconst sighandler_t SIG_IGN = (sighandler_t)1;\nconst sighandler_t SIG_ERR = (sighandler_t)-1;\n#if SANITIZER_FREEBSD || SANITIZER_MAC\nconst int SA_SIGINFO = 0x40;\nconst int SIG_SETMASK = 3;\n#elif defined(__mips__)\nconst int SA_SIGINFO = 8;\nconst int SIG_SETMASK = 3;\n#else\nconst int SA_SIGINFO = 4;\nconst int SIG_SETMASK = 2;\n#endif\n\n#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED \\\n  (!cur_thread()->is_inited)\n\nstatic sigaction_t sigactions[kSigCount];\n\nnamespace __tsan {\nstruct SignalDesc {\n  bool armed;\n  bool sigaction;\n  my_siginfo_t siginfo;\n  ucontext_t ctx;\n};\n\nstruct ThreadSignalContext {\n  int int_signal_send;\n  atomic_uintptr_t in_blocking_func;\n  atomic_uintptr_t have_pending_signals;\n  SignalDesc pending_signals[kSigCount];\n  // emptyset and oldset are too big for stack.\n  __sanitizer_sigset_t emptyset;\n  __sanitizer_sigset_t oldset;\n};\n\n// The object is 64-byte aligned, because we want hot data to be located in\n// a single cache line if possible (it's accessed in every interceptor).\nstatic ALIGNED(64) char libignore_placeholder[sizeof(LibIgnore)];\nstatic LibIgnore *libignore() {\n  return reinterpret_cast<LibIgnore*>(&libignore_placeholder[0]);\n}\n\nvoid InitializeLibIgnore() {\n  const SuppressionContext &supp = *Suppressions();\n  const uptr n = supp.SuppressionCount();\n  for (uptr i = 0; i < n; i++) {\n    const Suppression *s = supp.SuppressionAt(i);\n    if (0 == internal_strcmp(s->type, kSuppressionLib))\n      libignore()->AddIgnoredLibrary(s->templ);\n  }\n  libignore()->OnLibraryLoaded(0);\n}\n\n}  // namespace __tsan\n\nstatic ThreadSignalContext *SigCtx(ThreadState *thr) {\n  ThreadSignalContext *ctx = (ThreadSignalContext*)thr->signal_ctx;\n  if (ctx == 0 && !thr->is_dead) {\n    ctx = (ThreadSignalContext*)MmapOrDie(sizeof(*ctx), \"ThreadSignalContext\");\n    MemoryResetRange(thr, (uptr)&SigCtx, (uptr)ctx, sizeof(*ctx));\n    thr->signal_ctx = ctx;\n  }\n  return ctx;\n}\n\n#if !SANITIZER_MAC\nstatic unsigned g_thread_finalize_key;\n#endif\n\nScopedInterceptor::ScopedInterceptor(ThreadState *thr, const char *fname,\n                                     uptr pc)\n    : thr_(thr)\n    , pc_(pc)\n    , in_ignored_lib_(false) {\n  if (!thr_->ignore_interceptors) {\n    Initialize(thr);\n    FuncEntry(thr, pc);\n  }\n  DPrintf(\"#%d: intercept %s()\\n\", thr_->tid, fname);\n  if (!thr_->in_ignored_lib && libignore()->IsIgnored(pc)) {\n    in_ignored_lib_ = true;\n    thr_->in_ignored_lib = true;\n    ThreadIgnoreBegin(thr_, pc_);\n  }\n}\n\nScopedInterceptor::~ScopedInterceptor() {\n  if (in_ignored_lib_) {\n    thr_->in_ignored_lib = false;\n    ThreadIgnoreEnd(thr_, pc_);\n  }\n  if (!thr_->ignore_interceptors) {\n    ProcessPendingSignals(thr_);\n    FuncExit(thr_);\n    CheckNoLocks(thr_);\n  }\n}\n\nvoid ScopedInterceptor::UserCallbackStart() {\n  if (in_ignored_lib_) {\n    thr_->in_ignored_lib = false;\n    ThreadIgnoreEnd(thr_, pc_);\n  }\n}\n\nvoid ScopedInterceptor::UserCallbackEnd() {\n  if (in_ignored_lib_) {\n    thr_->in_ignored_lib = true;\n    ThreadIgnoreBegin(thr_, pc_);\n  }\n}\n\n#define TSAN_INTERCEPT(func) INTERCEPT_FUNCTION(func)\n#if SANITIZER_FREEBSD\n# define TSAN_INTERCEPT_VER(func, ver) INTERCEPT_FUNCTION(func)\n#else\n# define TSAN_INTERCEPT_VER(func, ver) INTERCEPT_FUNCTION_VER(func, ver)\n#endif\n\n#define READ_STRING_OF_LEN(thr, pc, s, len, n)                 \\\n  MemoryAccessRange((thr), (pc), (uptr)(s),                         \\\n    common_flags()->strict_string_checks ? (len) + 1 : (n), false)\n\n#define READ_STRING(thr, pc, s, n)                             \\\n    READ_STRING_OF_LEN((thr), (pc), (s), internal_strlen(s), (n))\n\n#define BLOCK_REAL(name) (BlockingCall(thr), REAL(name))\n\nstruct BlockingCall {\n  explicit BlockingCall(ThreadState *thr)\n      : thr(thr)\n      , ctx(SigCtx(thr)) {\n    for (;;) {\n      atomic_store(&ctx->in_blocking_func, 1, memory_order_relaxed);\n      if (atomic_load(&ctx->have_pending_signals, memory_order_relaxed) == 0)\n        break;\n      atomic_store(&ctx->in_blocking_func, 0, memory_order_relaxed);\n      ProcessPendingSignals(thr);\n    }\n    // When we are in a \"blocking call\", we process signals asynchronously\n    // (right when they arrive). In this context we do not expect to be\n    // executing any user/runtime code. The known interceptor sequence when\n    // this is not true is: pthread_join -> munmap(stack). It's fine\n    // to ignore munmap in this case -- we handle stack shadow separately.\n    thr->ignore_interceptors++;\n  }\n\n  ~BlockingCall() {\n    thr->ignore_interceptors--;\n    atomic_store(&ctx->in_blocking_func, 0, memory_order_relaxed);\n  }\n\n  ThreadState *thr;\n  ThreadSignalContext *ctx;\n};\n\nTSAN_INTERCEPTOR(unsigned, sleep, unsigned sec) {\n  SCOPED_TSAN_INTERCEPTOR(sleep, sec);\n  unsigned res = BLOCK_REAL(sleep)(sec);\n  AfterSleep(thr, pc);\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, usleep, long_t usec) {\n  SCOPED_TSAN_INTERCEPTOR(usleep, usec);\n  int res = BLOCK_REAL(usleep)(usec);\n  AfterSleep(thr, pc);\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, nanosleep, void *req, void *rem) {\n  SCOPED_TSAN_INTERCEPTOR(nanosleep, req, rem);\n  int res = BLOCK_REAL(nanosleep)(req, rem);\n  AfterSleep(thr, pc);\n  return res;\n}\n\n// The sole reason tsan wraps atexit callbacks is to establish synchronization\n// between callback setup and callback execution.\nstruct AtExitCtx {\n  void (*f)();\n  void *arg;\n};\n\nstatic void at_exit_wrapper(void *arg) {\n  ThreadState *thr = cur_thread();\n  uptr pc = 0;\n  Acquire(thr, pc, (uptr)arg);\n  AtExitCtx *ctx = (AtExitCtx*)arg;\n  ((void(*)(void *arg))ctx->f)(ctx->arg);\n  __libc_free(ctx);\n}\n\nstatic int setup_at_exit_wrapper(ThreadState *thr, uptr pc, void(*f)(),\n      void *arg, void *dso);\n\n#if !SANITIZER_ANDROID\nTSAN_INTERCEPTOR(int, atexit, void (*f)()) {\n  if (cur_thread()->in_symbolizer)\n    return 0;\n  // We want to setup the atexit callback even if we are in ignored lib\n  // or after fork.\n  SCOPED_INTERCEPTOR_RAW(atexit, f);\n  return setup_at_exit_wrapper(thr, pc, (void(*)())f, 0, 0);\n}\n#endif\n\nTSAN_INTERCEPTOR(int, __cxa_atexit, void (*f)(void *a), void *arg, void *dso) {\n  if (cur_thread()->in_symbolizer)\n    return 0;\n  SCOPED_TSAN_INTERCEPTOR(__cxa_atexit, f, arg, dso);\n  return setup_at_exit_wrapper(thr, pc, (void(*)())f, arg, dso);\n}\n\nstatic int setup_at_exit_wrapper(ThreadState *thr, uptr pc, void(*f)(),\n      void *arg, void *dso) {\n  AtExitCtx *ctx = (AtExitCtx*)__libc_malloc(sizeof(AtExitCtx));\n  ctx->f = f;\n  ctx->arg = arg;\n  Release(thr, pc, (uptr)ctx);\n  // Memory allocation in __cxa_atexit will race with free during exit,\n  // because we do not see synchronization around atexit callback list.\n  ThreadIgnoreBegin(thr, pc);\n  int res = REAL(__cxa_atexit)(at_exit_wrapper, ctx, dso);\n  ThreadIgnoreEnd(thr, pc);\n  return res;\n}\n\n#if !SANITIZER_MAC\nstatic void on_exit_wrapper(int status, void *arg) {\n  ThreadState *thr = cur_thread();\n  uptr pc = 0;\n  Acquire(thr, pc, (uptr)arg);\n  AtExitCtx *ctx = (AtExitCtx*)arg;\n  ((void(*)(int status, void *arg))ctx->f)(status, ctx->arg);\n  __libc_free(ctx);\n}\n\nTSAN_INTERCEPTOR(int, on_exit, void(*f)(int, void*), void *arg) {\n  if (cur_thread()->in_symbolizer)\n    return 0;\n  SCOPED_TSAN_INTERCEPTOR(on_exit, f, arg);\n  AtExitCtx *ctx = (AtExitCtx*)__libc_malloc(sizeof(AtExitCtx));\n  ctx->f = (void(*)())f;\n  ctx->arg = arg;\n  Release(thr, pc, (uptr)ctx);\n  // Memory allocation in __cxa_atexit will race with free during exit,\n  // because we do not see synchronization around atexit callback list.\n  ThreadIgnoreBegin(thr, pc);\n  int res = REAL(on_exit)(on_exit_wrapper, ctx);\n  ThreadIgnoreEnd(thr, pc);\n  return res;\n}\n#endif\n\n// Cleanup old bufs.\nstatic void JmpBufGarbageCollect(ThreadState *thr, uptr sp) {\n  for (uptr i = 0; i < thr->jmp_bufs.Size(); i++) {\n    JmpBuf *buf = &thr->jmp_bufs[i];\n    if (buf->sp <= sp) {\n      uptr sz = thr->jmp_bufs.Size();\n      internal_memcpy(buf, &thr->jmp_bufs[sz - 1], sizeof(*buf));\n      thr->jmp_bufs.PopBack();\n      i--;\n    }\n  }\n}\n\nstatic void SetJmp(ThreadState *thr, uptr sp, uptr mangled_sp) {\n  if (!thr->is_inited)  // called from libc guts during bootstrap\n    return;\n  // Cleanup old bufs.\n  JmpBufGarbageCollect(thr, sp);\n  // Remember the buf.\n  JmpBuf *buf = thr->jmp_bufs.PushBack();\n  buf->sp = sp;\n  buf->mangled_sp = mangled_sp;\n  buf->shadow_stack_pos = thr->shadow_stack_pos;\n  ThreadSignalContext *sctx = SigCtx(thr);\n  buf->int_signal_send = sctx ? sctx->int_signal_send : 0;\n  buf->in_blocking_func = sctx ?\n      atomic_load(&sctx->in_blocking_func, memory_order_relaxed) :\n      false;\n  buf->in_signal_handler = atomic_load(&thr->in_signal_handler,\n      memory_order_relaxed);\n}\n\nstatic void LongJmp(ThreadState *thr, uptr *env) {\n#ifdef __powerpc__\n  uptr mangled_sp = env[0];\n#elif SANITIZER_FREEBSD || SANITIZER_MAC\n  uptr mangled_sp = env[2];\n#elif defined(SANITIZER_LINUX)\n# ifdef __aarch64__\n  uptr mangled_sp = env[13];\n# else\n  uptr mangled_sp = env[6];\n# endif\n#endif\n  // Find the saved buf by mangled_sp.\n  for (uptr i = 0; i < thr->jmp_bufs.Size(); i++) {\n    JmpBuf *buf = &thr->jmp_bufs[i];\n    if (buf->mangled_sp == mangled_sp) {\n      CHECK_GE(thr->shadow_stack_pos, buf->shadow_stack_pos);\n      // Unwind the stack.\n      while (thr->shadow_stack_pos > buf->shadow_stack_pos)\n        FuncExit(thr);\n      ThreadSignalContext *sctx = SigCtx(thr);\n      if (sctx) {\n        sctx->int_signal_send = buf->int_signal_send;\n        atomic_store(&sctx->in_blocking_func, buf->in_blocking_func,\n            memory_order_relaxed);\n      }\n      atomic_store(&thr->in_signal_handler, buf->in_signal_handler,\n          memory_order_relaxed);\n      JmpBufGarbageCollect(thr, buf->sp - 1);  // do not collect buf->sp\n      return;\n    }\n  }\n  Printf(\"ThreadSanitizer: can't find longjmp buf\\n\");\n  CHECK(0);\n}\n\n// FIXME: put everything below into a common extern \"C\" block?\nextern \"C\" void __tsan_setjmp(uptr sp, uptr mangled_sp) {\n  SetJmp(cur_thread(), sp, mangled_sp);\n}\n\n#if SANITIZER_MAC\nTSAN_INTERCEPTOR(int, setjmp, void *env);\nTSAN_INTERCEPTOR(int, _setjmp, void *env);\nTSAN_INTERCEPTOR(int, sigsetjmp, void *env);\n#else  // SANITIZER_MAC\n// Not called.  Merely to satisfy TSAN_INTERCEPT().\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nint __interceptor_setjmp(void *env);\nextern \"C\" int __interceptor_setjmp(void *env) {\n  CHECK(0);\n  return 0;\n}\n\n// FIXME: any reason to have a separate declaration?\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nint __interceptor__setjmp(void *env);\nextern \"C\" int __interceptor__setjmp(void *env) {\n  CHECK(0);\n  return 0;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nint __interceptor_sigsetjmp(void *env);\nextern \"C\" int __interceptor_sigsetjmp(void *env) {\n  CHECK(0);\n  return 0;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nint __interceptor___sigsetjmp(void *env);\nextern \"C\" int __interceptor___sigsetjmp(void *env) {\n  CHECK(0);\n  return 0;\n}\n\nextern \"C\" int setjmp(void *env);\nextern \"C\" int _setjmp(void *env);\nextern \"C\" int sigsetjmp(void *env);\nextern \"C\" int __sigsetjmp(void *env);\nDEFINE_REAL(int, setjmp, void *env)\nDEFINE_REAL(int, _setjmp, void *env)\nDEFINE_REAL(int, sigsetjmp, void *env)\nDEFINE_REAL(int, __sigsetjmp, void *env)\n#endif  // SANITIZER_MAC\n\nTSAN_INTERCEPTOR(void, longjmp, uptr *env, int val) {\n  {\n    SCOPED_TSAN_INTERCEPTOR(longjmp, env, val);\n  }\n  LongJmp(cur_thread(), env);\n  REAL(longjmp)(env, val);\n}\n\nTSAN_INTERCEPTOR(void, siglongjmp, uptr *env, int val) {\n  {\n    SCOPED_TSAN_INTERCEPTOR(siglongjmp, env, val);\n  }\n  LongJmp(cur_thread(), env);\n  REAL(siglongjmp)(env, val);\n}\n\n#if !SANITIZER_MAC\nTSAN_INTERCEPTOR(void*, malloc, uptr size) {\n  if (cur_thread()->in_symbolizer)\n    return __libc_malloc(size);\n  void *p = 0;\n  {\n    SCOPED_INTERCEPTOR_RAW(malloc, size);\n    p = user_alloc(thr, pc, size);\n  }\n  invoke_malloc_hook(p, size);\n  return p;\n}\n\nTSAN_INTERCEPTOR(void*, __libc_memalign, uptr align, uptr sz) {\n  SCOPED_TSAN_INTERCEPTOR(__libc_memalign, align, sz);\n  return user_alloc(thr, pc, sz, align);\n}\n\nTSAN_INTERCEPTOR(void*, calloc, uptr size, uptr n) {\n  if (cur_thread()->in_symbolizer)\n    return __libc_calloc(size, n);\n  void *p = 0;\n  {\n    SCOPED_INTERCEPTOR_RAW(calloc, size, n);\n    p = user_calloc(thr, pc, size, n);\n  }\n  invoke_malloc_hook(p, n * size);\n  return p;\n}\n\nTSAN_INTERCEPTOR(void*, realloc, void *p, uptr size) {\n  if (cur_thread()->in_symbolizer)\n    return __libc_realloc(p, size);\n  if (p)\n    invoke_free_hook(p);\n  {\n    SCOPED_INTERCEPTOR_RAW(realloc, p, size);\n    p = user_realloc(thr, pc, p, size);\n  }\n  invoke_malloc_hook(p, size);\n  return p;\n}\n\nTSAN_INTERCEPTOR(void, free, void *p) {\n  if (p == 0)\n    return;\n  if (cur_thread()->in_symbolizer)\n    return __libc_free(p);\n  invoke_free_hook(p);\n  SCOPED_INTERCEPTOR_RAW(free, p);\n  user_free(thr, pc, p);\n}\n\nTSAN_INTERCEPTOR(void, cfree, void *p) {\n  if (p == 0)\n    return;\n  if (cur_thread()->in_symbolizer)\n    return __libc_free(p);\n  invoke_free_hook(p);\n  SCOPED_INTERCEPTOR_RAW(cfree, p);\n  user_free(thr, pc, p);\n}\n\nTSAN_INTERCEPTOR(uptr, malloc_usable_size, void *p) {\n  SCOPED_INTERCEPTOR_RAW(malloc_usable_size, p);\n  return user_alloc_usable_size(p);\n}\n#endif\n\nTSAN_INTERCEPTOR(uptr, strlen, const char *s) {\n  SCOPED_TSAN_INTERCEPTOR(strlen, s);\n  uptr len = internal_strlen(s);\n  MemoryAccessRange(thr, pc, (uptr)s, len + 1, false);\n  return len;\n}\n\nTSAN_INTERCEPTOR(void*, memset, void *dst, int v, uptr size) {\n  // On FreeBSD we get here from libthr internals on thread initialization.\n  if (!COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {\n    SCOPED_TSAN_INTERCEPTOR(memset, dst, v, size);\n    MemoryAccessRange(thr, pc, (uptr)dst, size, true);\n  }\n  return internal_memset(dst, v, size);\n}\n\nTSAN_INTERCEPTOR(void*, memcpy, void *dst, const void *src, uptr size) {\n  // On FreeBSD we get here from libthr internals on thread initialization.\n  if (!COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {\n    SCOPED_TSAN_INTERCEPTOR(memcpy, dst, src, size);\n    MemoryAccessRange(thr, pc, (uptr)dst, size, true);\n    MemoryAccessRange(thr, pc, (uptr)src, size, false);\n  }\n  // On OS X, calling internal_memcpy here will cause memory corruptions,\n  // because memcpy and memmove are actually aliases of the same implementation.\n  // We need to use internal_memmove here.\n  return internal_memmove(dst, src, size);\n}\n\nTSAN_INTERCEPTOR(void*, memmove, void *dst, void *src, uptr n) {\n  if (!COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {\n    SCOPED_TSAN_INTERCEPTOR(memmove, dst, src, n);\n    MemoryAccessRange(thr, pc, (uptr)dst, n, true);\n    MemoryAccessRange(thr, pc, (uptr)src, n, false);\n  }\n  return REAL(memmove)(dst, src, n);\n}\n\nTSAN_INTERCEPTOR(char*, strchr, char *s, int c) {\n  SCOPED_TSAN_INTERCEPTOR(strchr, s, c);\n  char *res = REAL(strchr)(s, c);\n  uptr len = internal_strlen(s);\n  uptr n = res ? (char*)res - (char*)s + 1 : len + 1;\n  READ_STRING_OF_LEN(thr, pc, s, len, n);\n  return res;\n}\n\n#if !SANITIZER_MAC\nTSAN_INTERCEPTOR(char*, strchrnul, char *s, int c) {\n  SCOPED_TSAN_INTERCEPTOR(strchrnul, s, c);\n  char *res = REAL(strchrnul)(s, c);\n  uptr len = (char*)res - (char*)s + 1;\n  READ_STRING(thr, pc, s, len);\n  return res;\n}\n#endif\n\nTSAN_INTERCEPTOR(char*, strrchr, char *s, int c) {\n  SCOPED_TSAN_INTERCEPTOR(strrchr, s, c);\n  MemoryAccessRange(thr, pc, (uptr)s, internal_strlen(s) + 1, false);\n  return REAL(strrchr)(s, c);\n}\n\nTSAN_INTERCEPTOR(char*, strcpy, char *dst, const char *src) {  // NOLINT\n  SCOPED_TSAN_INTERCEPTOR(strcpy, dst, src);  // NOLINT\n  uptr srclen = internal_strlen(src);\n  MemoryAccessRange(thr, pc, (uptr)dst, srclen + 1, true);\n  MemoryAccessRange(thr, pc, (uptr)src, srclen + 1, false);\n  return REAL(strcpy)(dst, src);  // NOLINT\n}\n\nTSAN_INTERCEPTOR(char*, strncpy, char *dst, char *src, uptr n) {\n  SCOPED_TSAN_INTERCEPTOR(strncpy, dst, src, n);\n  uptr srclen = internal_strnlen(src, n);\n  MemoryAccessRange(thr, pc, (uptr)dst, n, true);\n  MemoryAccessRange(thr, pc, (uptr)src, min(srclen + 1, n), false);\n  return REAL(strncpy)(dst, src, n);\n}\n\nTSAN_INTERCEPTOR(char*, strdup, const char *str) {\n  SCOPED_TSAN_INTERCEPTOR(strdup, str);\n  // strdup will call malloc, so no instrumentation is required here.\n  return REAL(strdup)(str);\n}\n\nstatic bool fix_mmap_addr(void **addr, long_t sz, int flags) {\n  if (*addr) {\n    if (!IsAppMem((uptr)*addr) || !IsAppMem((uptr)*addr + sz - 1)) {\n      if (flags & MAP_FIXED) {\n        errno = EINVAL;\n        return false;\n      } else {\n        *addr = 0;\n      }\n    }\n  }\n  return true;\n}\n\nTSAN_INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags,\n                 int fd, OFF_T off) {\n  SCOPED_TSAN_INTERCEPTOR(mmap, addr, sz, prot, flags, fd, off);\n  if (!fix_mmap_addr(&addr, sz, flags))\n    return MAP_FAILED;\n  void *res = REAL(mmap)(addr, sz, prot, flags, fd, off);\n  if (res != MAP_FAILED) {\n    if (fd > 0)\n      FdAccess(thr, pc, fd);\n    MemoryRangeImitateWrite(thr, pc, (uptr)res, sz);\n  }\n  return res;\n}\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags,\n                 int fd, OFF64_T off) {\n  SCOPED_TSAN_INTERCEPTOR(mmap64, addr, sz, prot, flags, fd, off);\n  if (!fix_mmap_addr(&addr, sz, flags))\n    return MAP_FAILED;\n  void *res = REAL(mmap64)(addr, sz, prot, flags, fd, off);\n  if (res != MAP_FAILED) {\n    if (fd > 0)\n      FdAccess(thr, pc, fd);\n    MemoryRangeImitateWrite(thr, pc, (uptr)res, sz);\n  }\n  return res;\n}\n#define TSAN_MAYBE_INTERCEPT_MMAP64 TSAN_INTERCEPT(mmap64)\n#else\n#define TSAN_MAYBE_INTERCEPT_MMAP64\n#endif\n\nTSAN_INTERCEPTOR(int, munmap, void *addr, long_t sz) {\n  SCOPED_TSAN_INTERCEPTOR(munmap, addr, sz);\n  if (sz != 0) {\n    // If sz == 0, munmap will return EINVAL and don't unmap any memory.\n    DontNeedShadowFor((uptr)addr, sz);\n    ctx->metamap.ResetRange(thr, pc, (uptr)addr, (uptr)sz);\n  }\n  int res = REAL(munmap)(addr, sz);\n  return res;\n}\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(void*, memalign, uptr align, uptr sz) {\n  SCOPED_INTERCEPTOR_RAW(memalign, align, sz);\n  return user_alloc(thr, pc, sz, align);\n}\n#define TSAN_MAYBE_INTERCEPT_MEMALIGN TSAN_INTERCEPT(memalign)\n#else\n#define TSAN_MAYBE_INTERCEPT_MEMALIGN\n#endif\n\n#if !SANITIZER_MAC\nTSAN_INTERCEPTOR(void*, aligned_alloc, uptr align, uptr sz) {\n  SCOPED_INTERCEPTOR_RAW(memalign, align, sz);\n  return user_alloc(thr, pc, sz, align);\n}\n\nTSAN_INTERCEPTOR(void*, valloc, uptr sz) {\n  SCOPED_INTERCEPTOR_RAW(valloc, sz);\n  return user_alloc(thr, pc, sz, GetPageSizeCached());\n}\n#endif\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(void*, pvalloc, uptr sz) {\n  SCOPED_INTERCEPTOR_RAW(pvalloc, sz);\n  sz = RoundUp(sz, GetPageSizeCached());\n  return user_alloc(thr, pc, sz, GetPageSizeCached());\n}\n#define TSAN_MAYBE_INTERCEPT_PVALLOC TSAN_INTERCEPT(pvalloc)\n#else\n#define TSAN_MAYBE_INTERCEPT_PVALLOC\n#endif\n\n#if !SANITIZER_MAC\nTSAN_INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr sz) {\n  SCOPED_INTERCEPTOR_RAW(posix_memalign, memptr, align, sz);\n  *memptr = user_alloc(thr, pc, sz, align);\n  return 0;\n}\n#endif\n\n// __cxa_guard_acquire and friends need to be intercepted in a special way -\n// regular interceptors will break statically-linked libstdc++. Linux\n// interceptors are especially defined as weak functions (so that they don't\n// cause link errors when user defines them as well). So they silently\n// auto-disable themselves when such symbol is already present in the binary. If\n// we link libstdc++ statically, it will bring own __cxa_guard_acquire which\n// will silently replace our interceptor.  That's why on Linux we simply export\n// these interceptors with INTERFACE_ATTRIBUTE.\n// On OS X, we don't support statically linking, so we just use a regular\n// interceptor.\n#if SANITIZER_MAC\n#define STDCXX_INTERCEPTOR TSAN_INTERCEPTOR\n#else\n#define STDCXX_INTERCEPTOR(rettype, name, ...) \\\n  extern \"C\" rettype INTERFACE_ATTRIBUTE name(__VA_ARGS__)\n#endif\n\n// Used in thread-safe function static initialization.\nSTDCXX_INTERCEPTOR(int, __cxa_guard_acquire, atomic_uint32_t *g) {\n  SCOPED_INTERCEPTOR_RAW(__cxa_guard_acquire, g);\n  for (;;) {\n    u32 cmp = atomic_load(g, memory_order_acquire);\n    if (cmp == 0) {\n      if (atomic_compare_exchange_strong(g, &cmp, 1<<16, memory_order_relaxed))\n        return 1;\n    } else if (cmp == 1) {\n      Acquire(thr, pc, (uptr)g);\n      return 0;\n    } else {\n      internal_sched_yield();\n    }\n  }\n}\n\nSTDCXX_INTERCEPTOR(void, __cxa_guard_release, atomic_uint32_t *g) {\n  SCOPED_INTERCEPTOR_RAW(__cxa_guard_release, g);\n  Release(thr, pc, (uptr)g);\n  atomic_store(g, 1, memory_order_release);\n}\n\nSTDCXX_INTERCEPTOR(void, __cxa_guard_abort, atomic_uint32_t *g) {\n  SCOPED_INTERCEPTOR_RAW(__cxa_guard_abort, g);\n  atomic_store(g, 0, memory_order_relaxed);\n}\n\nnamespace __tsan {\nvoid DestroyThreadState() {\n  ThreadState *thr = cur_thread();\n  ThreadFinish(thr);\n  ThreadSignalContext *sctx = thr->signal_ctx;\n  if (sctx) {\n    thr->signal_ctx = 0;\n    UnmapOrDie(sctx, sizeof(*sctx));\n  }\n  cur_thread_finalize();\n}\n}  // namespace __tsan\n\n#if !SANITIZER_MAC\nstatic void thread_finalize(void *v) {\n  uptr iter = (uptr)v;\n  if (iter > 1) {\n    if (pthread_setspecific(g_thread_finalize_key, (void*)(iter - 1))) {\n      Printf(\"ThreadSanitizer: failed to set thread key\\n\");\n      Die();\n    }\n    return;\n  }\n  DestroyThreadState();\n}\n#endif\n\n\nstruct ThreadParam {\n  void* (*callback)(void *arg);\n  void *param;\n  atomic_uintptr_t tid;\n};\n\nextern \"C\" void *__tsan_thread_start_func(void *arg) {\n  ThreadParam *p = (ThreadParam*)arg;\n  void* (*callback)(void *arg) = p->callback;\n  void *param = p->param;\n  int tid = 0;\n  {\n    ThreadState *thr = cur_thread();\n    // Thread-local state is not initialized yet.\n    ScopedIgnoreInterceptors ignore;\n#if !SANITIZER_MAC\n    ThreadIgnoreBegin(thr, 0);\n    if (pthread_setspecific(g_thread_finalize_key,\n                            (void *)GetPthreadDestructorIterations())) {\n      Printf(\"ThreadSanitizer: failed to set thread key\\n\");\n      Die();\n    }\n    ThreadIgnoreEnd(thr, 0);\n#endif\n    while ((tid = atomic_load(&p->tid, memory_order_acquire)) == 0)\n      internal_sched_yield();\n    ThreadStart(thr, tid, GetTid());\n    atomic_store(&p->tid, 0, memory_order_release);\n  }\n  void *res = callback(param);\n  // Prevent the callback from being tail called,\n  // it mixes up stack traces.\n  volatile int foo = 42;\n  foo++;\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_create,\n    void *th, void *attr, void *(*callback)(void*), void * param) {\n  SCOPED_INTERCEPTOR_RAW(pthread_create, th, attr, callback, param);\n  if (ctx->after_multithreaded_fork) {\n    if (flags()->die_after_fork) {\n      Report(\"ThreadSanitizer: starting new threads after multi-threaded \"\n          \"fork is not supported. Dying (set die_after_fork=0 to override)\\n\");\n      Die();\n    } else {\n      VPrintf(1, \"ThreadSanitizer: starting new threads after multi-threaded \"\n          \"fork is not supported (pid %d). Continuing because of \"\n          \"die_after_fork=0, but you are on your own\\n\", internal_getpid());\n    }\n  }\n  __sanitizer_pthread_attr_t myattr;\n  if (attr == 0) {\n    pthread_attr_init(&myattr);\n    attr = &myattr;\n  }\n  int detached = 0;\n  REAL(pthread_attr_getdetachstate)(attr, &detached);\n  AdjustStackSize(attr);\n\n  ThreadParam p;\n  p.callback = callback;\n  p.param = param;\n  atomic_store(&p.tid, 0, memory_order_relaxed);\n  int res = -1;\n  {\n    // Otherwise we see false positives in pthread stack manipulation.\n    ScopedIgnoreInterceptors ignore;\n    ThreadIgnoreBegin(thr, pc);\n    res = REAL(pthread_create)(th, attr, __tsan_thread_start_func, &p);\n    ThreadIgnoreEnd(thr, pc);\n  }\n  if (res == 0) {\n    int tid = ThreadCreate(thr, pc, *(uptr*)th,\n                           detached == PTHREAD_CREATE_DETACHED);\n    CHECK_NE(tid, 0);\n    // Synchronization on p.tid serves two purposes:\n    // 1. ThreadCreate must finish before the new thread starts.\n    //    Otherwise the new thread can call pthread_detach, but the pthread_t\n    //    identifier is not yet registered in ThreadRegistry by ThreadCreate.\n    // 2. ThreadStart must finish before this thread continues.\n    //    Otherwise, this thread can call pthread_detach and reset thr->sync\n    //    before the new thread got a chance to acquire from it in ThreadStart.\n    atomic_store(&p.tid, tid, memory_order_release);\n    while (atomic_load(&p.tid, memory_order_acquire) != 0)\n      internal_sched_yield();\n  }\n  if (attr == &myattr)\n    pthread_attr_destroy(&myattr);\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) {\n  SCOPED_INTERCEPTOR_RAW(pthread_join, th, ret);\n  int tid = ThreadTid(thr, pc, (uptr)th);\n  ThreadIgnoreBegin(thr, pc);\n  int res = BLOCK_REAL(pthread_join)(th, ret);\n  ThreadIgnoreEnd(thr, pc);\n  if (res == 0) {\n    ThreadJoin(thr, pc, tid);\n  }\n  return res;\n}\n\nDEFINE_REAL_PTHREAD_FUNCTIONS\n\nTSAN_INTERCEPTOR(int, pthread_detach, void *th) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_detach, th);\n  int tid = ThreadTid(thr, pc, (uptr)th);\n  int res = REAL(pthread_detach)(th);\n  if (res == 0) {\n    ThreadDetach(thr, pc, tid);\n  }\n  return res;\n}\n\n// Problem:\n// NPTL implementation of pthread_cond has 2 versions (2.2.5 and 2.3.2).\n// pthread_cond_t has different size in the different versions.\n// If call new REAL functions for old pthread_cond_t, they will corrupt memory\n// after pthread_cond_t (old cond is smaller).\n// If we call old REAL functions for new pthread_cond_t, we will lose  some\n// functionality (e.g. old functions do not support waiting against\n// CLOCK_REALTIME).\n// Proper handling would require to have 2 versions of interceptors as well.\n// But this is messy, in particular requires linker scripts when sanitizer\n// runtime is linked into a shared library.\n// Instead we assume we don't have dynamic libraries built against old\n// pthread (2.2.5 is dated by 2002). And provide legacy_pthread_cond flag\n// that allows to work with old libraries (but this mode does not support\n// some features, e.g. pthread_condattr_getpshared).\nstatic void *init_cond(void *c, bool force = false) {\n  // sizeof(pthread_cond_t) >= sizeof(uptr) in both versions.\n  // So we allocate additional memory on the side large enough to hold\n  // any pthread_cond_t object. Always call new REAL functions, but pass\n  // the aux object to them.\n  // Note: the code assumes that PTHREAD_COND_INITIALIZER initializes\n  // first word of pthread_cond_t to zero.\n  // It's all relevant only for linux.\n  if (!common_flags()->legacy_pthread_cond)\n    return c;\n  atomic_uintptr_t *p = (atomic_uintptr_t*)c;\n  uptr cond = atomic_load(p, memory_order_acquire);\n  if (!force && cond != 0)\n    return (void*)cond;\n  void *newcond = WRAP(malloc)(pthread_cond_t_sz);\n  internal_memset(newcond, 0, pthread_cond_t_sz);\n  if (atomic_compare_exchange_strong(p, &cond, (uptr)newcond,\n      memory_order_acq_rel))\n    return newcond;\n  WRAP(free)(newcond);\n  return (void*)cond;\n}\n\nstruct CondMutexUnlockCtx {\n  ScopedInterceptor *si;\n  ThreadState *thr;\n  uptr pc;\n  void *m;\n};\n\nstatic void cond_mutex_unlock(CondMutexUnlockCtx *arg) {\n  // pthread_cond_wait interceptor has enabled async signal delivery\n  // (see BlockingCall below). Disable async signals since we are running\n  // tsan code. Also ScopedInterceptor and BlockingCall destructors won't run\n  // since the thread is cancelled, so we have to manually execute them\n  // (the thread still can run some user code due to pthread_cleanup_push).\n  ThreadSignalContext *ctx = SigCtx(arg->thr);\n  CHECK_EQ(atomic_load(&ctx->in_blocking_func, memory_order_relaxed), 1);\n  atomic_store(&ctx->in_blocking_func, 0, memory_order_relaxed);\n  MutexLock(arg->thr, arg->pc, (uptr)arg->m);\n  // Undo BlockingCall ctor effects.\n  arg->thr->ignore_interceptors--;\n  arg->si->~ScopedInterceptor();\n}\n\nINTERCEPTOR(int, pthread_cond_init, void *c, void *a) {\n  void *cond = init_cond(c, true);\n  SCOPED_TSAN_INTERCEPTOR(pthread_cond_init, cond, a);\n  MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), true);\n  return REAL(pthread_cond_init)(cond, a);\n}\n\nINTERCEPTOR(int, pthread_cond_wait, void *c, void *m) {\n  void *cond = init_cond(c);\n  SCOPED_TSAN_INTERCEPTOR(pthread_cond_wait, cond, m);\n  MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false);\n  MutexUnlock(thr, pc, (uptr)m);\n  CondMutexUnlockCtx arg = {&si, thr, pc, m};\n  int res = 0;\n  // This ensures that we handle mutex lock even in case of pthread_cancel.\n  // See test/tsan/cond_cancel.cc.\n  {\n    // Enable signal delivery while the thread is blocked.\n    BlockingCall bc(thr);\n    res = call_pthread_cancel_with_cleanup(\n        (int(*)(void *c, void *m, void *abstime))REAL(pthread_cond_wait),\n        cond, m, 0, (void(*)(void *arg))cond_mutex_unlock, &arg);\n  }\n  if (res == errno_EOWNERDEAD)\n    MutexRepair(thr, pc, (uptr)m);\n  MutexLock(thr, pc, (uptr)m);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_cond_timedwait, void *c, void *m, void *abstime) {\n  void *cond = init_cond(c);\n  SCOPED_TSAN_INTERCEPTOR(pthread_cond_timedwait, cond, m, abstime);\n  MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false);\n  MutexUnlock(thr, pc, (uptr)m);\n  CondMutexUnlockCtx arg = {&si, thr, pc, m};\n  int res = 0;\n  // This ensures that we handle mutex lock even in case of pthread_cancel.\n  // See test/tsan/cond_cancel.cc.\n  {\n    BlockingCall bc(thr);\n    res = call_pthread_cancel_with_cleanup(\n        REAL(pthread_cond_timedwait), cond, m, abstime,\n        (void(*)(void *arg))cond_mutex_unlock, &arg);\n  }\n  if (res == errno_EOWNERDEAD)\n    MutexRepair(thr, pc, (uptr)m);\n  MutexLock(thr, pc, (uptr)m);\n  return res;\n}\n\nINTERCEPTOR(int, pthread_cond_signal, void *c) {\n  void *cond = init_cond(c);\n  SCOPED_TSAN_INTERCEPTOR(pthread_cond_signal, cond);\n  MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false);\n  return REAL(pthread_cond_signal)(cond);\n}\n\nINTERCEPTOR(int, pthread_cond_broadcast, void *c) {\n  void *cond = init_cond(c);\n  SCOPED_TSAN_INTERCEPTOR(pthread_cond_broadcast, cond);\n  MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false);\n  return REAL(pthread_cond_broadcast)(cond);\n}\n\nINTERCEPTOR(int, pthread_cond_destroy, void *c) {\n  void *cond = init_cond(c);\n  SCOPED_TSAN_INTERCEPTOR(pthread_cond_destroy, cond);\n  MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), true);\n  int res = REAL(pthread_cond_destroy)(cond);\n  if (common_flags()->legacy_pthread_cond) {\n    // Free our aux cond and zero the pointer to not leave dangling pointers.\n    WRAP(free)(cond);\n    atomic_store((atomic_uintptr_t*)c, 0, memory_order_relaxed);\n  }\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_mutex_init, void *m, void *a) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_mutex_init, m, a);\n  int res = REAL(pthread_mutex_init)(m, a);\n  if (res == 0) {\n    bool recursive = false;\n    if (a) {\n      int type = 0;\n      if (REAL(pthread_mutexattr_gettype)(a, &type) == 0)\n        recursive = (type == PTHREAD_MUTEX_RECURSIVE\n            || type == PTHREAD_MUTEX_RECURSIVE_NP);\n    }\n    MutexCreate(thr, pc, (uptr)m, false, recursive, false);\n  }\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_mutex_destroy, void *m) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_mutex_destroy, m);\n  int res = REAL(pthread_mutex_destroy)(m);\n  if (res == 0 || res == EBUSY) {\n    MutexDestroy(thr, pc, (uptr)m);\n  }\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_mutex_trylock, void *m) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_mutex_trylock, m);\n  int res = REAL(pthread_mutex_trylock)(m);\n  if (res == EOWNERDEAD)\n    MutexRepair(thr, pc, (uptr)m);\n  if (res == 0 || res == EOWNERDEAD)\n    MutexLock(thr, pc, (uptr)m, /*rec=*/1, /*try_lock=*/true);\n  return res;\n}\n\n#if !SANITIZER_MAC\nTSAN_INTERCEPTOR(int, pthread_mutex_timedlock, void *m, void *abstime) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_mutex_timedlock, m, abstime);\n  int res = REAL(pthread_mutex_timedlock)(m, abstime);\n  if (res == 0) {\n    MutexLock(thr, pc, (uptr)m);\n  }\n  return res;\n}\n#endif\n\n#if !SANITIZER_MAC\nTSAN_INTERCEPTOR(int, pthread_spin_init, void *m, int pshared) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_spin_init, m, pshared);\n  int res = REAL(pthread_spin_init)(m, pshared);\n  if (res == 0) {\n    MutexCreate(thr, pc, (uptr)m, false, false, false);\n  }\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_spin_destroy, void *m) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_spin_destroy, m);\n  int res = REAL(pthread_spin_destroy)(m);\n  if (res == 0) {\n    MutexDestroy(thr, pc, (uptr)m);\n  }\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_spin_lock, void *m) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_spin_lock, m);\n  int res = REAL(pthread_spin_lock)(m);\n  if (res == 0) {\n    MutexLock(thr, pc, (uptr)m);\n  }\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_spin_trylock, void *m) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_spin_trylock, m);\n  int res = REAL(pthread_spin_trylock)(m);\n  if (res == 0) {\n    MutexLock(thr, pc, (uptr)m, /*rec=*/1, /*try_lock=*/true);\n  }\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_spin_unlock, void *m) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_spin_unlock, m);\n  MutexUnlock(thr, pc, (uptr)m);\n  int res = REAL(pthread_spin_unlock)(m);\n  return res;\n}\n#endif\n\nTSAN_INTERCEPTOR(int, pthread_rwlock_init, void *m, void *a) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_init, m, a);\n  int res = REAL(pthread_rwlock_init)(m, a);\n  if (res == 0) {\n    MutexCreate(thr, pc, (uptr)m, true, false, false);\n  }\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_rwlock_destroy, void *m) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_destroy, m);\n  int res = REAL(pthread_rwlock_destroy)(m);\n  if (res == 0) {\n    MutexDestroy(thr, pc, (uptr)m);\n  }\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_rwlock_rdlock, void *m) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_rdlock, m);\n  int res = REAL(pthread_rwlock_rdlock)(m);\n  if (res == 0) {\n    MutexReadLock(thr, pc, (uptr)m);\n  }\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_rwlock_tryrdlock, void *m) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_tryrdlock, m);\n  int res = REAL(pthread_rwlock_tryrdlock)(m);\n  if (res == 0) {\n    MutexReadLock(thr, pc, (uptr)m, /*try_lock=*/true);\n  }\n  return res;\n}\n\n#if !SANITIZER_MAC\nTSAN_INTERCEPTOR(int, pthread_rwlock_timedrdlock, void *m, void *abstime) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedrdlock, m, abstime);\n  int res = REAL(pthread_rwlock_timedrdlock)(m, abstime);\n  if (res == 0) {\n    MutexReadLock(thr, pc, (uptr)m);\n  }\n  return res;\n}\n#endif\n\nTSAN_INTERCEPTOR(int, pthread_rwlock_wrlock, void *m) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_wrlock, m);\n  int res = REAL(pthread_rwlock_wrlock)(m);\n  if (res == 0) {\n    MutexLock(thr, pc, (uptr)m);\n  }\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_rwlock_trywrlock, void *m) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_trywrlock, m);\n  int res = REAL(pthread_rwlock_trywrlock)(m);\n  if (res == 0) {\n    MutexLock(thr, pc, (uptr)m, /*rec=*/1, /*try_lock=*/true);\n  }\n  return res;\n}\n\n#if !SANITIZER_MAC\nTSAN_INTERCEPTOR(int, pthread_rwlock_timedwrlock, void *m, void *abstime) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedwrlock, m, abstime);\n  int res = REAL(pthread_rwlock_timedwrlock)(m, abstime);\n  if (res == 0) {\n    MutexLock(thr, pc, (uptr)m);\n  }\n  return res;\n}\n#endif\n\nTSAN_INTERCEPTOR(int, pthread_rwlock_unlock, void *m) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_unlock, m);\n  MutexReadOrWriteUnlock(thr, pc, (uptr)m);\n  int res = REAL(pthread_rwlock_unlock)(m);\n  return res;\n}\n\n#if !SANITIZER_MAC\nTSAN_INTERCEPTOR(int, pthread_barrier_init, void *b, void *a, unsigned count) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_barrier_init, b, a, count);\n  MemoryWrite(thr, pc, (uptr)b, kSizeLog1);\n  int res = REAL(pthread_barrier_init)(b, a, count);\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_barrier_destroy, void *b) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_barrier_destroy, b);\n  MemoryWrite(thr, pc, (uptr)b, kSizeLog1);\n  int res = REAL(pthread_barrier_destroy)(b);\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_barrier_wait, void *b) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_barrier_wait, b);\n  Release(thr, pc, (uptr)b);\n  MemoryRead(thr, pc, (uptr)b, kSizeLog1);\n  int res = REAL(pthread_barrier_wait)(b);\n  MemoryRead(thr, pc, (uptr)b, kSizeLog1);\n  if (res == 0 || res == PTHREAD_BARRIER_SERIAL_THREAD) {\n    Acquire(thr, pc, (uptr)b);\n  }\n  return res;\n}\n#endif\n\nTSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) {\n  SCOPED_INTERCEPTOR_RAW(pthread_once, o, f);\n  if (o == 0 || f == 0)\n    return EINVAL;\n  atomic_uint32_t *a;\n  if (!SANITIZER_MAC)\n    a = static_cast<atomic_uint32_t*>(o);\n  else  // On OS X, pthread_once_t has a header with a long-sized signature.\n    a = static_cast<atomic_uint32_t*>((void *)((char *)o + sizeof(long_t)));\n  u32 v = atomic_load(a, memory_order_acquire);\n  if (v == 0 && atomic_compare_exchange_strong(a, &v, 1,\n                                               memory_order_relaxed)) {\n    (*f)();\n    if (!thr->in_ignored_lib)\n      Release(thr, pc, (uptr)o);\n    atomic_store(a, 2, memory_order_release);\n  } else {\n    while (v != 2) {\n      internal_sched_yield();\n      v = atomic_load(a, memory_order_acquire);\n    }\n    if (!thr->in_ignored_lib)\n      Acquire(thr, pc, (uptr)o);\n  }\n  return 0;\n}\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nTSAN_INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) {\n  SCOPED_TSAN_INTERCEPTOR(__xstat, version, path, buf);\n  READ_STRING(thr, pc, path, 0);\n  return REAL(__xstat)(version, path, buf);\n}\n#define TSAN_MAYBE_INTERCEPT___XSTAT TSAN_INTERCEPT(__xstat)\n#else\n#define TSAN_MAYBE_INTERCEPT___XSTAT\n#endif\n\nTSAN_INTERCEPTOR(int, stat, const char *path, void *buf) {\n#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_ANDROID\n  SCOPED_TSAN_INTERCEPTOR(stat, path, buf);\n  READ_STRING(thr, pc, path, 0);\n  return REAL(stat)(path, buf);\n#else\n  SCOPED_TSAN_INTERCEPTOR(__xstat, 0, path, buf);\n  READ_STRING(thr, pc, path, 0);\n  return REAL(__xstat)(0, path, buf);\n#endif\n}\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nTSAN_INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) {\n  SCOPED_TSAN_INTERCEPTOR(__xstat64, version, path, buf);\n  READ_STRING(thr, pc, path, 0);\n  return REAL(__xstat64)(version, path, buf);\n}\n#define TSAN_MAYBE_INTERCEPT___XSTAT64 TSAN_INTERCEPT(__xstat64)\n#else\n#define TSAN_MAYBE_INTERCEPT___XSTAT64\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nTSAN_INTERCEPTOR(int, stat64, const char *path, void *buf) {\n  SCOPED_TSAN_INTERCEPTOR(__xstat64, 0, path, buf);\n  READ_STRING(thr, pc, path, 0);\n  return REAL(__xstat64)(0, path, buf);\n}\n#define TSAN_MAYBE_INTERCEPT_STAT64 TSAN_INTERCEPT(stat64)\n#else\n#define TSAN_MAYBE_INTERCEPT_STAT64\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nTSAN_INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) {\n  SCOPED_TSAN_INTERCEPTOR(__lxstat, version, path, buf);\n  READ_STRING(thr, pc, path, 0);\n  return REAL(__lxstat)(version, path, buf);\n}\n#define TSAN_MAYBE_INTERCEPT___LXSTAT TSAN_INTERCEPT(__lxstat)\n#else\n#define TSAN_MAYBE_INTERCEPT___LXSTAT\n#endif\n\nTSAN_INTERCEPTOR(int, lstat, const char *path, void *buf) {\n#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_ANDROID\n  SCOPED_TSAN_INTERCEPTOR(lstat, path, buf);\n  READ_STRING(thr, pc, path, 0);\n  return REAL(lstat)(path, buf);\n#else\n  SCOPED_TSAN_INTERCEPTOR(__lxstat, 0, path, buf);\n  READ_STRING(thr, pc, path, 0);\n  return REAL(__lxstat)(0, path, buf);\n#endif\n}\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nTSAN_INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) {\n  SCOPED_TSAN_INTERCEPTOR(__lxstat64, version, path, buf);\n  READ_STRING(thr, pc, path, 0);\n  return REAL(__lxstat64)(version, path, buf);\n}\n#define TSAN_MAYBE_INTERCEPT___LXSTAT64 TSAN_INTERCEPT(__lxstat64)\n#else\n#define TSAN_MAYBE_INTERCEPT___LXSTAT64\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nTSAN_INTERCEPTOR(int, lstat64, const char *path, void *buf) {\n  SCOPED_TSAN_INTERCEPTOR(__lxstat64, 0, path, buf);\n  READ_STRING(thr, pc, path, 0);\n  return REAL(__lxstat64)(0, path, buf);\n}\n#define TSAN_MAYBE_INTERCEPT_LSTAT64 TSAN_INTERCEPT(lstat64)\n#else\n#define TSAN_MAYBE_INTERCEPT_LSTAT64\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nTSAN_INTERCEPTOR(int, __fxstat, int version, int fd, void *buf) {\n  SCOPED_TSAN_INTERCEPTOR(__fxstat, version, fd, buf);\n  if (fd > 0)\n    FdAccess(thr, pc, fd);\n  return REAL(__fxstat)(version, fd, buf);\n}\n#define TSAN_MAYBE_INTERCEPT___FXSTAT TSAN_INTERCEPT(__fxstat)\n#else\n#define TSAN_MAYBE_INTERCEPT___FXSTAT\n#endif\n\nTSAN_INTERCEPTOR(int, fstat, int fd, void *buf) {\n#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_ANDROID\n  SCOPED_TSAN_INTERCEPTOR(fstat, fd, buf);\n  if (fd > 0)\n    FdAccess(thr, pc, fd);\n  return REAL(fstat)(fd, buf);\n#else\n  SCOPED_TSAN_INTERCEPTOR(__fxstat, 0, fd, buf);\n  if (fd > 0)\n    FdAccess(thr, pc, fd);\n  return REAL(__fxstat)(0, fd, buf);\n#endif\n}\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nTSAN_INTERCEPTOR(int, __fxstat64, int version, int fd, void *buf) {\n  SCOPED_TSAN_INTERCEPTOR(__fxstat64, version, fd, buf);\n  if (fd > 0)\n    FdAccess(thr, pc, fd);\n  return REAL(__fxstat64)(version, fd, buf);\n}\n#define TSAN_MAYBE_INTERCEPT___FXSTAT64 TSAN_INTERCEPT(__fxstat64)\n#else\n#define TSAN_MAYBE_INTERCEPT___FXSTAT64\n#endif\n\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nTSAN_INTERCEPTOR(int, fstat64, int fd, void *buf) {\n  SCOPED_TSAN_INTERCEPTOR(__fxstat64, 0, fd, buf);\n  if (fd > 0)\n    FdAccess(thr, pc, fd);\n  return REAL(__fxstat64)(0, fd, buf);\n}\n#define TSAN_MAYBE_INTERCEPT_FSTAT64 TSAN_INTERCEPT(fstat64)\n#else\n#define TSAN_MAYBE_INTERCEPT_FSTAT64\n#endif\n\nTSAN_INTERCEPTOR(int, open, const char *name, int flags, int mode) {\n  SCOPED_TSAN_INTERCEPTOR(open, name, flags, mode);\n  READ_STRING(thr, pc, name, 0);\n  int fd = REAL(open)(name, flags, mode);\n  if (fd >= 0)\n    FdFileCreate(thr, pc, fd);\n  return fd;\n}\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(int, open64, const char *name, int flags, int mode) {\n  SCOPED_TSAN_INTERCEPTOR(open64, name, flags, mode);\n  READ_STRING(thr, pc, name, 0);\n  int fd = REAL(open64)(name, flags, mode);\n  if (fd >= 0)\n    FdFileCreate(thr, pc, fd);\n  return fd;\n}\n#define TSAN_MAYBE_INTERCEPT_OPEN64 TSAN_INTERCEPT(open64)\n#else\n#define TSAN_MAYBE_INTERCEPT_OPEN64\n#endif\n\nTSAN_INTERCEPTOR(int, creat, const char *name, int mode) {\n  SCOPED_TSAN_INTERCEPTOR(creat, name, mode);\n  READ_STRING(thr, pc, name, 0);\n  int fd = REAL(creat)(name, mode);\n  if (fd >= 0)\n    FdFileCreate(thr, pc, fd);\n  return fd;\n}\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(int, creat64, const char *name, int mode) {\n  SCOPED_TSAN_INTERCEPTOR(creat64, name, mode);\n  READ_STRING(thr, pc, name, 0);\n  int fd = REAL(creat64)(name, mode);\n  if (fd >= 0)\n    FdFileCreate(thr, pc, fd);\n  return fd;\n}\n#define TSAN_MAYBE_INTERCEPT_CREAT64 TSAN_INTERCEPT(creat64)\n#else\n#define TSAN_MAYBE_INTERCEPT_CREAT64\n#endif\n\nTSAN_INTERCEPTOR(int, dup, int oldfd) {\n  SCOPED_TSAN_INTERCEPTOR(dup, oldfd);\n  int newfd = REAL(dup)(oldfd);\n  if (oldfd >= 0 && newfd >= 0 && newfd != oldfd)\n    FdDup(thr, pc, oldfd, newfd, true);\n  return newfd;\n}\n\nTSAN_INTERCEPTOR(int, dup2, int oldfd, int newfd) {\n  SCOPED_TSAN_INTERCEPTOR(dup2, oldfd, newfd);\n  int newfd2 = REAL(dup2)(oldfd, newfd);\n  if (oldfd >= 0 && newfd2 >= 0 && newfd2 != oldfd)\n    FdDup(thr, pc, oldfd, newfd2, false);\n  return newfd2;\n}\n\n#if !SANITIZER_MAC\nTSAN_INTERCEPTOR(int, dup3, int oldfd, int newfd, int flags) {\n  SCOPED_TSAN_INTERCEPTOR(dup3, oldfd, newfd, flags);\n  int newfd2 = REAL(dup3)(oldfd, newfd, flags);\n  if (oldfd >= 0 && newfd2 >= 0 && newfd2 != oldfd)\n    FdDup(thr, pc, oldfd, newfd2, false);\n  return newfd2;\n}\n#endif\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(int, eventfd, unsigned initval, int flags) {\n  SCOPED_TSAN_INTERCEPTOR(eventfd, initval, flags);\n  int fd = REAL(eventfd)(initval, flags);\n  if (fd >= 0)\n    FdEventCreate(thr, pc, fd);\n  return fd;\n}\n#define TSAN_MAYBE_INTERCEPT_EVENTFD TSAN_INTERCEPT(eventfd)\n#else\n#define TSAN_MAYBE_INTERCEPT_EVENTFD\n#endif\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(int, signalfd, int fd, void *mask, int flags) {\n  SCOPED_TSAN_INTERCEPTOR(signalfd, fd, mask, flags);\n  if (fd >= 0)\n    FdClose(thr, pc, fd);\n  fd = REAL(signalfd)(fd, mask, flags);\n  if (fd >= 0)\n    FdSignalCreate(thr, pc, fd);\n  return fd;\n}\n#define TSAN_MAYBE_INTERCEPT_SIGNALFD TSAN_INTERCEPT(signalfd)\n#else\n#define TSAN_MAYBE_INTERCEPT_SIGNALFD\n#endif\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(int, inotify_init, int fake) {\n  SCOPED_TSAN_INTERCEPTOR(inotify_init, fake);\n  int fd = REAL(inotify_init)(fake);\n  if (fd >= 0)\n    FdInotifyCreate(thr, pc, fd);\n  return fd;\n}\n#define TSAN_MAYBE_INTERCEPT_INOTIFY_INIT TSAN_INTERCEPT(inotify_init)\n#else\n#define TSAN_MAYBE_INTERCEPT_INOTIFY_INIT\n#endif\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(int, inotify_init1, int flags) {\n  SCOPED_TSAN_INTERCEPTOR(inotify_init1, flags);\n  int fd = REAL(inotify_init1)(flags);\n  if (fd >= 0)\n    FdInotifyCreate(thr, pc, fd);\n  return fd;\n}\n#define TSAN_MAYBE_INTERCEPT_INOTIFY_INIT1 TSAN_INTERCEPT(inotify_init1)\n#else\n#define TSAN_MAYBE_INTERCEPT_INOTIFY_INIT1\n#endif\n\nTSAN_INTERCEPTOR(int, socket, int domain, int type, int protocol) {\n  SCOPED_TSAN_INTERCEPTOR(socket, domain, type, protocol);\n  int fd = REAL(socket)(domain, type, protocol);\n  if (fd >= 0)\n    FdSocketCreate(thr, pc, fd);\n  return fd;\n}\n\nTSAN_INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int *fd) {\n  SCOPED_TSAN_INTERCEPTOR(socketpair, domain, type, protocol, fd);\n  int res = REAL(socketpair)(domain, type, protocol, fd);\n  if (res == 0 && fd[0] >= 0 && fd[1] >= 0)\n    FdPipeCreate(thr, pc, fd[0], fd[1]);\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, connect, int fd, void *addr, unsigned addrlen) {\n  SCOPED_TSAN_INTERCEPTOR(connect, fd, addr, addrlen);\n  FdSocketConnecting(thr, pc, fd);\n  int res = REAL(connect)(fd, addr, addrlen);\n  if (res == 0 && fd >= 0)\n    FdSocketConnect(thr, pc, fd);\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, bind, int fd, void *addr, unsigned addrlen) {\n  SCOPED_TSAN_INTERCEPTOR(bind, fd, addr, addrlen);\n  int res = REAL(bind)(fd, addr, addrlen);\n  if (fd > 0 && res == 0)\n    FdAccess(thr, pc, fd);\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, listen, int fd, int backlog) {\n  SCOPED_TSAN_INTERCEPTOR(listen, fd, backlog);\n  int res = REAL(listen)(fd, backlog);\n  if (fd > 0 && res == 0)\n    FdAccess(thr, pc, fd);\n  return res;\n}\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(int, epoll_create, int size) {\n  SCOPED_TSAN_INTERCEPTOR(epoll_create, size);\n  int fd = REAL(epoll_create)(size);\n  if (fd >= 0)\n    FdPollCreate(thr, pc, fd);\n  return fd;\n}\n#define TSAN_MAYBE_INTERCEPT_EPOLL_CREATE TSAN_INTERCEPT(epoll_create)\n#else\n#define TSAN_MAYBE_INTERCEPT_EPOLL_CREATE\n#endif\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(int, epoll_create1, int flags) {\n  SCOPED_TSAN_INTERCEPTOR(epoll_create1, flags);\n  int fd = REAL(epoll_create1)(flags);\n  if (fd >= 0)\n    FdPollCreate(thr, pc, fd);\n  return fd;\n}\n#define TSAN_MAYBE_INTERCEPT_EPOLL_CREATE1 TSAN_INTERCEPT(epoll_create1)\n#else\n#define TSAN_MAYBE_INTERCEPT_EPOLL_CREATE1\n#endif\n\nTSAN_INTERCEPTOR(int, close, int fd) {\n  SCOPED_TSAN_INTERCEPTOR(close, fd);\n  if (fd >= 0)\n    FdClose(thr, pc, fd);\n  return REAL(close)(fd);\n}\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(int, __close, int fd) {\n  SCOPED_TSAN_INTERCEPTOR(__close, fd);\n  if (fd >= 0)\n    FdClose(thr, pc, fd);\n  return REAL(__close)(fd);\n}\n#define TSAN_MAYBE_INTERCEPT___CLOSE TSAN_INTERCEPT(__close)\n#else\n#define TSAN_MAYBE_INTERCEPT___CLOSE\n#endif\n\n// glibc guts\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\nTSAN_INTERCEPTOR(void, __res_iclose, void *state, bool free_addr) {\n  SCOPED_TSAN_INTERCEPTOR(__res_iclose, state, free_addr);\n  int fds[64];\n  int cnt = ExtractResolvFDs(state, fds, ARRAY_SIZE(fds));\n  for (int i = 0; i < cnt; i++) {\n    if (fds[i] > 0)\n      FdClose(thr, pc, fds[i]);\n  }\n  REAL(__res_iclose)(state, free_addr);\n}\n#define TSAN_MAYBE_INTERCEPT___RES_ICLOSE TSAN_INTERCEPT(__res_iclose)\n#else\n#define TSAN_MAYBE_INTERCEPT___RES_ICLOSE\n#endif\n\nTSAN_INTERCEPTOR(int, pipe, int *pipefd) {\n  SCOPED_TSAN_INTERCEPTOR(pipe, pipefd);\n  int res = REAL(pipe)(pipefd);\n  if (res == 0 && pipefd[0] >= 0 && pipefd[1] >= 0)\n    FdPipeCreate(thr, pc, pipefd[0], pipefd[1]);\n  return res;\n}\n\n#if !SANITIZER_MAC\nTSAN_INTERCEPTOR(int, pipe2, int *pipefd, int flags) {\n  SCOPED_TSAN_INTERCEPTOR(pipe2, pipefd, flags);\n  int res = REAL(pipe2)(pipefd, flags);\n  if (res == 0 && pipefd[0] >= 0 && pipefd[1] >= 0)\n    FdPipeCreate(thr, pc, pipefd[0], pipefd[1]);\n  return res;\n}\n#endif\n\nTSAN_INTERCEPTOR(long_t, send, int fd, void *buf, long_t len, int flags) {\n  SCOPED_TSAN_INTERCEPTOR(send, fd, buf, len, flags);\n  if (fd >= 0) {\n    FdAccess(thr, pc, fd);\n    FdRelease(thr, pc, fd);\n  }\n  int res = REAL(send)(fd, buf, len, flags);\n  return res;\n}\n\nTSAN_INTERCEPTOR(long_t, sendmsg, int fd, void *msg, int flags) {\n  SCOPED_TSAN_INTERCEPTOR(sendmsg, fd, msg, flags);\n  if (fd >= 0) {\n    FdAccess(thr, pc, fd);\n    FdRelease(thr, pc, fd);\n  }\n  int res = REAL(sendmsg)(fd, msg, flags);\n  return res;\n}\n\nTSAN_INTERCEPTOR(long_t, recv, int fd, void *buf, long_t len, int flags) {\n  SCOPED_TSAN_INTERCEPTOR(recv, fd, buf, len, flags);\n  if (fd >= 0)\n    FdAccess(thr, pc, fd);\n  int res = REAL(recv)(fd, buf, len, flags);\n  if (res >= 0 && fd >= 0) {\n    FdAcquire(thr, pc, fd);\n  }\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, unlink, char *path) {\n  SCOPED_TSAN_INTERCEPTOR(unlink, path);\n  Release(thr, pc, File2addr(path));\n  int res = REAL(unlink)(path);\n  return res;\n}\n\nTSAN_INTERCEPTOR(void*, tmpfile, int fake) {\n  SCOPED_TSAN_INTERCEPTOR(tmpfile, fake);\n  void *res = REAL(tmpfile)(fake);\n  if (res) {\n    int fd = fileno_unlocked(res);\n    if (fd >= 0)\n      FdFileCreate(thr, pc, fd);\n  }\n  return res;\n}\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(void*, tmpfile64, int fake) {\n  SCOPED_TSAN_INTERCEPTOR(tmpfile64, fake);\n  void *res = REAL(tmpfile64)(fake);\n  if (res) {\n    int fd = fileno_unlocked(res);\n    if (fd >= 0)\n      FdFileCreate(thr, pc, fd);\n  }\n  return res;\n}\n#define TSAN_MAYBE_INTERCEPT_TMPFILE64 TSAN_INTERCEPT(tmpfile64)\n#else\n#define TSAN_MAYBE_INTERCEPT_TMPFILE64\n#endif\n\nTSAN_INTERCEPTOR(uptr, fread, void *ptr, uptr size, uptr nmemb, void *f) {\n  // libc file streams can call user-supplied functions, see fopencookie.\n  {\n    SCOPED_TSAN_INTERCEPTOR(fread, ptr, size, nmemb, f);\n    MemoryAccessRange(thr, pc, (uptr)ptr, size * nmemb, true);\n  }\n  return REAL(fread)(ptr, size, nmemb, f);\n}\n\nTSAN_INTERCEPTOR(uptr, fwrite, const void *p, uptr size, uptr nmemb, void *f) {\n  // libc file streams can call user-supplied functions, see fopencookie.\n  {\n    SCOPED_TSAN_INTERCEPTOR(fwrite, p, size, nmemb, f);\n    MemoryAccessRange(thr, pc, (uptr)p, size * nmemb, false);\n  }\n  return REAL(fwrite)(p, size, nmemb, f);\n}\n\nstatic void FlushStreams() {\n  // Flushing all the streams here may freeze the process if a child thread is\n  // performing file stream operations at the same time.\n  REAL(fflush)(stdout);\n  REAL(fflush)(stderr);\n}\n\nTSAN_INTERCEPTOR(void, abort, int fake) {\n  SCOPED_TSAN_INTERCEPTOR(abort, fake);\n  FlushStreams();\n  REAL(abort)(fake);\n}\n\nTSAN_INTERCEPTOR(int, puts, const char *s) {\n  SCOPED_TSAN_INTERCEPTOR(puts, s);\n  MemoryAccessRange(thr, pc, (uptr)s, internal_strlen(s), false);\n  return REAL(puts)(s);\n}\n\nTSAN_INTERCEPTOR(int, rmdir, char *path) {\n  SCOPED_TSAN_INTERCEPTOR(rmdir, path);\n  Release(thr, pc, Dir2addr(path));\n  int res = REAL(rmdir)(path);\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, closedir, void *dirp) {\n  SCOPED_TSAN_INTERCEPTOR(closedir, dirp);\n  int fd = dirfd(dirp);\n  FdClose(thr, pc, fd);\n  return REAL(closedir)(dirp);\n}\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(int, epoll_ctl, int epfd, int op, int fd, void *ev) {\n  SCOPED_TSAN_INTERCEPTOR(epoll_ctl, epfd, op, fd, ev);\n  if (epfd >= 0)\n    FdAccess(thr, pc, epfd);\n  if (epfd >= 0 && fd >= 0)\n    FdAccess(thr, pc, fd);\n  if (op == EPOLL_CTL_ADD && epfd >= 0)\n    FdRelease(thr, pc, epfd);\n  int res = REAL(epoll_ctl)(epfd, op, fd, ev);\n  return res;\n}\n#define TSAN_MAYBE_INTERCEPT_EPOLL_CTL TSAN_INTERCEPT(epoll_ctl)\n#else\n#define TSAN_MAYBE_INTERCEPT_EPOLL_CTL\n#endif\n\n#if SANITIZER_LINUX\nTSAN_INTERCEPTOR(int, epoll_wait, int epfd, void *ev, int cnt, int timeout) {\n  SCOPED_TSAN_INTERCEPTOR(epoll_wait, epfd, ev, cnt, timeout);\n  if (epfd >= 0)\n    FdAccess(thr, pc, epfd);\n  int res = BLOCK_REAL(epoll_wait)(epfd, ev, cnt, timeout);\n  if (res > 0 && epfd >= 0)\n    FdAcquire(thr, pc, epfd);\n  return res;\n}\n#define TSAN_MAYBE_INTERCEPT_EPOLL_WAIT TSAN_INTERCEPT(epoll_wait)\n#else\n#define TSAN_MAYBE_INTERCEPT_EPOLL_WAIT\n#endif\n\nnamespace __tsan {\n\nstatic void CallUserSignalHandler(ThreadState *thr, bool sync, bool acquire,\n    bool sigact, int sig, my_siginfo_t *info, void *uctx) {\n  if (acquire)\n    Acquire(thr, 0, (uptr)&sigactions[sig]);\n  // Ensure that the handler does not spoil errno.\n  const int saved_errno = errno;\n  errno = 99;\n  // This code races with sigaction. Be careful to not read sa_sigaction twice.\n  // Also need to remember pc for reporting before the call,\n  // because the handler can reset it.\n  volatile uptr pc = sigact ?\n     (uptr)sigactions[sig].sa_sigaction :\n     (uptr)sigactions[sig].sa_handler;\n  if (pc != (uptr)SIG_DFL && pc != (uptr)SIG_IGN) {\n    if (sigact)\n      ((sigactionhandler_t)pc)(sig, info, uctx);\n    else\n      ((sighandler_t)pc)(sig);\n  }\n  // We do not detect errno spoiling for SIGTERM,\n  // because some SIGTERM handlers do spoil errno but reraise SIGTERM,\n  // tsan reports false positive in such case.\n  // It's difficult to properly detect this situation (reraise),\n  // because in async signal processing case (when handler is called directly\n  // from rtl_generic_sighandler) we have not yet received the reraised\n  // signal; and it looks too fragile to intercept all ways to reraise a signal.\n  if (flags()->report_bugs && !sync && sig != SIGTERM && errno != 99) {\n    VarSizeStackTrace stack;\n    // StackTrace::GetNestInstructionPc(pc) is used because return address is\n    // expected, OutputReport() will undo this.\n    ObtainCurrentStack(thr, StackTrace::GetNextInstructionPc(pc), &stack);\n    ThreadRegistryLock l(ctx->thread_registry);\n    ScopedReport rep(ReportTypeErrnoInSignal);\n    if (!IsFiredSuppression(ctx, ReportTypeErrnoInSignal, stack)) {\n      rep.AddStack(stack, true);\n      OutputReport(thr, rep);\n    }\n  }\n  errno = saved_errno;\n}\n\nvoid ProcessPendingSignals(ThreadState *thr) {\n  ThreadSignalContext *sctx = SigCtx(thr);\n  if (sctx == 0 ||\n      atomic_load(&sctx->have_pending_signals, memory_order_relaxed) == 0)\n    return;\n  atomic_store(&sctx->have_pending_signals, 0, memory_order_relaxed);\n  atomic_fetch_add(&thr->in_signal_handler, 1, memory_order_relaxed);\n  CHECK_EQ(0, REAL(sigfillset)(&sctx->emptyset));\n  CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sctx->emptyset, &sctx->oldset));\n  for (int sig = 0; sig < kSigCount; sig++) {\n    SignalDesc *signal = &sctx->pending_signals[sig];\n    if (signal->armed) {\n      signal->armed = false;\n      CallUserSignalHandler(thr, false, true, signal->sigaction, sig,\n          &signal->siginfo, &signal->ctx);\n    }\n  }\n  CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sctx->oldset, 0));\n  atomic_fetch_add(&thr->in_signal_handler, -1, memory_order_relaxed);\n}\n\n}  // namespace __tsan\n\nstatic bool is_sync_signal(ThreadSignalContext *sctx, int sig) {\n  return sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||\n      sig == SIGABRT || sig == SIGFPE || sig == SIGPIPE || sig == SIGSYS ||\n      // If we are sending signal to ourselves, we must process it now.\n      (sctx && sig == sctx->int_signal_send);\n}\n\nvoid ALWAYS_INLINE rtl_generic_sighandler(bool sigact, int sig,\n    my_siginfo_t *info, void *ctx) {\n  ThreadState *thr = cur_thread();\n  ThreadSignalContext *sctx = SigCtx(thr);\n  if (sig < 0 || sig >= kSigCount) {\n    VPrintf(1, \"ThreadSanitizer: ignoring signal %d\\n\", sig);\n    return;\n  }\n  // Don't mess with synchronous signals.\n  const bool sync = is_sync_signal(sctx, sig);\n  if (sync ||\n      // If we are in blocking function, we can safely process it now\n      // (but check if we are in a recursive interceptor,\n      // i.e. pthread_join()->munmap()).\n      (sctx && atomic_load(&sctx->in_blocking_func, memory_order_relaxed))) {\n    atomic_fetch_add(&thr->in_signal_handler, 1, memory_order_relaxed);\n    if (sctx && atomic_load(&sctx->in_blocking_func, memory_order_relaxed)) {\n      // We ignore interceptors in blocking functions,\n      // temporary enbled them again while we are calling user function.\n      int const i = thr->ignore_interceptors;\n      thr->ignore_interceptors = 0;\n      atomic_store(&sctx->in_blocking_func, 0, memory_order_relaxed);\n      CallUserSignalHandler(thr, sync, true, sigact, sig, info, ctx);\n      thr->ignore_interceptors = i;\n      atomic_store(&sctx->in_blocking_func, 1, memory_order_relaxed);\n    } else {\n      // Be very conservative with when we do acquire in this case.\n      // It's unsafe to do acquire in async handlers, because ThreadState\n      // can be in inconsistent state.\n      // SIGSYS looks relatively safe -- it's synchronous and can actually\n      // need some global state.\n      bool acq = (sig == SIGSYS);\n      CallUserSignalHandler(thr, sync, acq, sigact, sig, info, ctx);\n    }\n    atomic_fetch_add(&thr->in_signal_handler, -1, memory_order_relaxed);\n    return;\n  }\n\n  if (sctx == 0)\n    return;\n  SignalDesc *signal = &sctx->pending_signals[sig];\n  if (signal->armed == false) {\n    signal->armed = true;\n    signal->sigaction = sigact;\n    if (info)\n      internal_memcpy(&signal->siginfo, info, sizeof(*info));\n    if (ctx)\n      internal_memcpy(&signal->ctx, ctx, sizeof(signal->ctx));\n    atomic_store(&sctx->have_pending_signals, 1, memory_order_relaxed);\n  }\n}\n\nstatic void rtl_sighandler(int sig) {\n  rtl_generic_sighandler(false, sig, 0, 0);\n}\n\nstatic void rtl_sigaction(int sig, my_siginfo_t *info, void *ctx) {\n  rtl_generic_sighandler(true, sig, info, ctx);\n}\n\nTSAN_INTERCEPTOR(int, sigaction, int sig, sigaction_t *act, sigaction_t *old) {\n  SCOPED_TSAN_INTERCEPTOR(sigaction, sig, act, old);\n  if (old)\n    internal_memcpy(old, &sigactions[sig], sizeof(*old));\n  if (act == 0)\n    return 0;\n  // Copy act into sigactions[sig].\n  // Can't use struct copy, because compiler can emit call to memcpy.\n  // Can't use internal_memcpy, because it copies byte-by-byte,\n  // and signal handler reads the sa_handler concurrently. It it can read\n  // some bytes from old value and some bytes from new value.\n  // Use volatile to prevent insertion of memcpy.\n  sigactions[sig].sa_handler = *(volatile sighandler_t*)&act->sa_handler;\n  sigactions[sig].sa_flags = *(volatile int*)&act->sa_flags;\n  internal_memcpy(&sigactions[sig].sa_mask, &act->sa_mask,\n      sizeof(sigactions[sig].sa_mask));\n#if !SANITIZER_FREEBSD && !SANITIZER_MAC\n  sigactions[sig].sa_restorer = act->sa_restorer;\n#endif\n  sigaction_t newact;\n  internal_memcpy(&newact, act, sizeof(newact));\n  REAL(sigfillset)(&newact.sa_mask);\n  if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL) {\n    if (newact.sa_flags & SA_SIGINFO)\n      newact.sa_sigaction = rtl_sigaction;\n    else\n      newact.sa_handler = rtl_sighandler;\n  }\n  ReleaseStore(thr, pc, (uptr)&sigactions[sig]);\n  int res = REAL(sigaction)(sig, &newact, 0);\n  return res;\n}\n\nTSAN_INTERCEPTOR(sighandler_t, signal, int sig, sighandler_t h) {\n  sigaction_t act;\n  act.sa_handler = h;\n  REAL(memset)(&act.sa_mask, -1, sizeof(act.sa_mask));\n  act.sa_flags = 0;\n  sigaction_t old;\n  int res = sigaction(sig, &act, &old);\n  if (res)\n    return SIG_ERR;\n  return old.sa_handler;\n}\n\nTSAN_INTERCEPTOR(int, sigsuspend, const __sanitizer_sigset_t *mask) {\n  SCOPED_TSAN_INTERCEPTOR(sigsuspend, mask);\n  return REAL(sigsuspend)(mask);\n}\n\nTSAN_INTERCEPTOR(int, raise, int sig) {\n  SCOPED_TSAN_INTERCEPTOR(raise, sig);\n  ThreadSignalContext *sctx = SigCtx(thr);\n  CHECK_NE(sctx, 0);\n  int prev = sctx->int_signal_send;\n  sctx->int_signal_send = sig;\n  int res = REAL(raise)(sig);\n  CHECK_EQ(sctx->int_signal_send, sig);\n  sctx->int_signal_send = prev;\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, kill, int pid, int sig) {\n  SCOPED_TSAN_INTERCEPTOR(kill, pid, sig);\n  ThreadSignalContext *sctx = SigCtx(thr);\n  CHECK_NE(sctx, 0);\n  int prev = sctx->int_signal_send;\n  if (pid == (int)internal_getpid()) {\n    sctx->int_signal_send = sig;\n  }\n  int res = REAL(kill)(pid, sig);\n  if (pid == (int)internal_getpid()) {\n    CHECK_EQ(sctx->int_signal_send, sig);\n    sctx->int_signal_send = prev;\n  }\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, pthread_kill, void *tid, int sig) {\n  SCOPED_TSAN_INTERCEPTOR(pthread_kill, tid, sig);\n  ThreadSignalContext *sctx = SigCtx(thr);\n  CHECK_NE(sctx, 0);\n  int prev = sctx->int_signal_send;\n  if (tid == pthread_self()) {\n    sctx->int_signal_send = sig;\n  }\n  int res = REAL(pthread_kill)(tid, sig);\n  if (tid == pthread_self()) {\n    CHECK_EQ(sctx->int_signal_send, sig);\n    sctx->int_signal_send = prev;\n  }\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, gettimeofday, void *tv, void *tz) {\n  SCOPED_TSAN_INTERCEPTOR(gettimeofday, tv, tz);\n  // It's intercepted merely to process pending signals.\n  return REAL(gettimeofday)(tv, tz);\n}\n\nTSAN_INTERCEPTOR(int, getaddrinfo, void *node, void *service,\n    void *hints, void *rv) {\n  SCOPED_TSAN_INTERCEPTOR(getaddrinfo, node, service, hints, rv);\n  // We miss atomic synchronization in getaddrinfo,\n  // and can report false race between malloc and free\n  // inside of getaddrinfo. So ignore memory accesses.\n  ThreadIgnoreBegin(thr, pc);\n  int res = REAL(getaddrinfo)(node, service, hints, rv);\n  ThreadIgnoreEnd(thr, pc);\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, fork, int fake) {\n  if (cur_thread()->in_symbolizer)\n    return REAL(fork)(fake);\n  SCOPED_INTERCEPTOR_RAW(fork, fake);\n  ForkBefore(thr, pc);\n  int pid = REAL(fork)(fake);\n  if (pid == 0) {\n    // child\n    ForkChildAfter(thr, pc);\n    FdOnFork(thr, pc);\n  } else if (pid > 0) {\n    // parent\n    ForkParentAfter(thr, pc);\n  } else {\n    // error\n    ForkParentAfter(thr, pc);\n  }\n  return pid;\n}\n\nTSAN_INTERCEPTOR(int, vfork, int fake) {\n  // Some programs (e.g. openjdk) call close for all file descriptors\n  // in the child process. Under tsan it leads to false positives, because\n  // address space is shared, so the parent process also thinks that\n  // the descriptors are closed (while they are actually not).\n  // This leads to false positives due to missed synchronization.\n  // Strictly saying this is undefined behavior, because vfork child is not\n  // allowed to call any functions other than exec/exit. But this is what\n  // openjdk does, so we want to handle it.\n  // We could disable interceptors in the child process. But it's not possible\n  // to simply intercept and wrap vfork, because vfork child is not allowed\n  // to return from the function that calls vfork, and that's exactly what\n  // we would do. So this would require some assembly trickery as well.\n  // Instead we simply turn vfork into fork.\n  return WRAP(fork)(fake);\n}\n\n#if !SANITIZER_MAC && !SANITIZER_ANDROID\ntypedef int (*dl_iterate_phdr_cb_t)(__sanitizer_dl_phdr_info *info, SIZE_T size,\n                                    void *data);\nstruct dl_iterate_phdr_data {\n  ThreadState *thr;\n  uptr pc;\n  dl_iterate_phdr_cb_t cb;\n  void *data;\n};\n\nstatic bool IsAppNotRodata(uptr addr) {\n  return IsAppMem(addr) && *(u64*)MemToShadow(addr) != kShadowRodata;\n}\n\nstatic int dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,\n                              void *data) {\n  dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;\n  // dlopen/dlclose allocate/free dynamic-linker-internal memory, which is later\n  // accessible in dl_iterate_phdr callback. But we don't see synchronization\n  // inside of dynamic linker, so we \"unpoison\" it here in order to not\n  // produce false reports. Ignoring malloc/free in dlopen/dlclose is not enough\n  // because some libc functions call __libc_dlopen.\n  if (info && IsAppNotRodata((uptr)info->dlpi_name))\n    MemoryResetRange(cbdata->thr, cbdata->pc, (uptr)info->dlpi_name,\n                     internal_strlen(info->dlpi_name));\n  int res = cbdata->cb(info, size, cbdata->data);\n  // Perform the check one more time in case info->dlpi_name was overwritten\n  // by user callback.\n  if (info && IsAppNotRodata((uptr)info->dlpi_name))\n    MemoryResetRange(cbdata->thr, cbdata->pc, (uptr)info->dlpi_name,\n                     internal_strlen(info->dlpi_name));\n  return res;\n}\n\nTSAN_INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb_t cb, void *data) {\n  SCOPED_TSAN_INTERCEPTOR(dl_iterate_phdr, cb, data);\n  dl_iterate_phdr_data cbdata;\n  cbdata.thr = thr;\n  cbdata.pc = pc;\n  cbdata.cb = cb;\n  cbdata.data = data;\n  int res = REAL(dl_iterate_phdr)(dl_iterate_phdr_cb, &cbdata);\n  return res;\n}\n#endif\n\nstatic int OnExit(ThreadState *thr) {\n  int status = Finalize(thr);\n  FlushStreams();\n  return status;\n}\n\nstruct TsanInterceptorContext {\n  ThreadState *thr;\n  const uptr caller_pc;\n  const uptr pc;\n};\n\n#if !SANITIZER_MAC\nstatic void HandleRecvmsg(ThreadState *thr, uptr pc,\n    __sanitizer_msghdr *msg) {\n  int fds[64];\n  int cnt = ExtractRecvmsgFDs(msg, fds, ARRAY_SIZE(fds));\n  for (int i = 0; i < cnt; i++)\n    FdEventCreate(thr, pc, fds[i]);\n}\n#endif\n\n#include \"sanitizer_common/sanitizer_platform_interceptors.h\"\n// Causes interceptor recursion (getaddrinfo() and fopen())\n#undef SANITIZER_INTERCEPT_GETADDRINFO\n// There interceptors do not seem to be strictly necessary for tsan.\n// But we see cases where the interceptors consume 70% of execution time.\n// Memory blocks passed to fgetgrent_r are \"written to\" by tsan several times.\n// First, there is some recursion (getgrnam_r calls fgetgrent_r), and each\n// function \"writes to\" the buffer. Then, the same memory is \"written to\"\n// twice, first as buf and then as pwbufp (both of them refer to the same\n// addresses).\n#undef SANITIZER_INTERCEPT_GETPWENT\n#undef SANITIZER_INTERCEPT_GETPWENT_R\n#undef SANITIZER_INTERCEPT_FGETPWENT\n#undef SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS\n#undef SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS\n// __tls_get_addr can be called with mis-aligned stack due to:\n// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066\n// There are two potential issues:\n// 1. Sanitizer code contains a MOVDQA spill (it does not seem to be the case\n// right now). or 2. ProcessPendingSignal calls user handler which contains\n// MOVDQA spill (this happens right now).\n// Since the interceptor only initializes memory for msan, the simplest solution\n// is to disable the interceptor in tsan (other sanitizers do not call\n// signal handlers from COMMON_INTERCEPTOR_ENTER).\n#undef SANITIZER_INTERCEPT_TLS_GET_ADDR\n\n#define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)\n\n#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size)                    \\\n  MemoryAccessRange(((TsanInterceptorContext *)ctx)->thr,                 \\\n                    ((TsanInterceptorContext *)ctx)->pc, (uptr)ptr, size, \\\n                    true)\n\n#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size)                       \\\n  MemoryAccessRange(((TsanInterceptorContext *) ctx)->thr,                  \\\n                    ((TsanInterceptorContext *) ctx)->pc, (uptr) ptr, size, \\\n                    false)\n\n#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)      \\\n  SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__);         \\\n  TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \\\n  ctx = (void *)&_ctx;                                \\\n  (void) ctx;\n\n#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, func, ...) \\\n  SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__);              \\\n  TsanInterceptorContext _ctx = {thr, caller_pc, pc};     \\\n  ctx = (void *)&_ctx;                                    \\\n  (void) ctx;\n\n#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) \\\n  Acquire(thr, pc, File2addr(path));                  \\\n  if (file) {                                         \\\n    int fd = fileno_unlocked(file);                   \\\n    if (fd >= 0) FdFileCreate(thr, pc, fd);           \\\n  }\n\n#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) \\\n  if (file) {                                    \\\n    int fd = fileno_unlocked(file);              \\\n    if (fd >= 0) FdClose(thr, pc, fd);           \\\n  }\n\n#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \\\n  libignore()->OnLibraryLoaded(filename)\n\n#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() \\\n  libignore()->OnLibraryUnloaded()\n\n#define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) \\\n  Acquire(((TsanInterceptorContext *) ctx)->thr, pc, u)\n\n#define COMMON_INTERCEPTOR_RELEASE(ctx, u) \\\n  Release(((TsanInterceptorContext *) ctx)->thr, pc, u)\n\n#define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \\\n  Acquire(((TsanInterceptorContext *) ctx)->thr, pc, Dir2addr(path))\n\n#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \\\n  FdAcquire(((TsanInterceptorContext *) ctx)->thr, pc, fd)\n\n#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \\\n  FdRelease(((TsanInterceptorContext *) ctx)->thr, pc, fd)\n\n#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) \\\n  FdAccess(((TsanInterceptorContext *) ctx)->thr, pc, fd)\n\n#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \\\n  FdSocketAccept(((TsanInterceptorContext *) ctx)->thr, pc, fd, newfd)\n\n#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \\\n  ThreadSetName(((TsanInterceptorContext *) ctx)->thr, name)\n\n#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \\\n  __tsan::ctx->thread_registry->SetThreadNameByUserId(thread, name)\n\n#define COMMON_INTERCEPTOR_BLOCK_REAL(name) BLOCK_REAL(name)\n\n#define COMMON_INTERCEPTOR_ON_EXIT(ctx) \\\n  OnExit(((TsanInterceptorContext *) ctx)->thr)\n\n#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) \\\n  MutexLock(((TsanInterceptorContext *)ctx)->thr, \\\n            ((TsanInterceptorContext *)ctx)->pc, (uptr)m)\n\n#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) \\\n  MutexUnlock(((TsanInterceptorContext *)ctx)->thr, \\\n            ((TsanInterceptorContext *)ctx)->pc, (uptr)m)\n\n#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) \\\n  MutexRepair(((TsanInterceptorContext *)ctx)->thr, \\\n            ((TsanInterceptorContext *)ctx)->pc, (uptr)m)\n\n#if !SANITIZER_MAC\n#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) \\\n  HandleRecvmsg(((TsanInterceptorContext *)ctx)->thr, \\\n      ((TsanInterceptorContext *)ctx)->pc, msg)\n#endif\n\n#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end)                           \\\n  if (TsanThread *t = GetCurrentThread()) {                                    \\\n    *begin = t->tls_begin();                                                   \\\n    *end = t->tls_end();                                                       \\\n  } else {                                                                     \\\n    *begin = *end = 0;                                                         \\\n  }\n\n#include \"sanitizer_common/sanitizer_common_interceptors.inc\"\n\n#define TSAN_SYSCALL() \\\n  ThreadState *thr = cur_thread(); \\\n  if (thr->ignore_interceptors) \\\n    return; \\\n  ScopedSyscall scoped_syscall(thr) \\\n/**/\n\nstruct ScopedSyscall {\n  ThreadState *thr;\n\n  explicit ScopedSyscall(ThreadState *thr)\n      : thr(thr) {\n    Initialize(thr);\n  }\n\n  ~ScopedSyscall() {\n    ProcessPendingSignals(thr);\n  }\n};\n\n#if !SANITIZER_MAC\nstatic void syscall_access_range(uptr pc, uptr p, uptr s, bool write) {\n  TSAN_SYSCALL();\n  MemoryAccessRange(thr, pc, p, s, write);\n}\n\nstatic void syscall_acquire(uptr pc, uptr addr) {\n  TSAN_SYSCALL();\n  Acquire(thr, pc, addr);\n  DPrintf(\"syscall_acquire(%p)\\n\", addr);\n}\n\nstatic void syscall_release(uptr pc, uptr addr) {\n  TSAN_SYSCALL();\n  DPrintf(\"syscall_release(%p)\\n\", addr);\n  Release(thr, pc, addr);\n}\n\nstatic void syscall_fd_close(uptr pc, int fd) {\n  TSAN_SYSCALL();\n  FdClose(thr, pc, fd);\n}\n\nstatic USED void syscall_fd_acquire(uptr pc, int fd) {\n  TSAN_SYSCALL();\n  FdAcquire(thr, pc, fd);\n  DPrintf(\"syscall_fd_acquire(%p)\\n\", fd);\n}\n\nstatic USED void syscall_fd_release(uptr pc, int fd) {\n  TSAN_SYSCALL();\n  DPrintf(\"syscall_fd_release(%p)\\n\", fd);\n  FdRelease(thr, pc, fd);\n}\n\nstatic void syscall_pre_fork(uptr pc) {\n  TSAN_SYSCALL();\n  ForkBefore(thr, pc);\n}\n\nstatic void syscall_post_fork(uptr pc, int pid) {\n  TSAN_SYSCALL();\n  if (pid == 0) {\n    // child\n    ForkChildAfter(thr, pc);\n    FdOnFork(thr, pc);\n  } else if (pid > 0) {\n    // parent\n    ForkParentAfter(thr, pc);\n  } else {\n    // error\n    ForkParentAfter(thr, pc);\n  }\n}\n#endif\n\n#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) \\\n  syscall_access_range(GET_CALLER_PC(), (uptr)(p), (uptr)(s), false)\n\n#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \\\n  syscall_access_range(GET_CALLER_PC(), (uptr)(p), (uptr)(s), true)\n\n#define COMMON_SYSCALL_POST_READ_RANGE(p, s) \\\n  do {                                       \\\n    (void)(p);                               \\\n    (void)(s);                               \\\n  } while (false)\n\n#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \\\n  do {                                        \\\n    (void)(p);                                \\\n    (void)(s);                                \\\n  } while (false)\n\n#define COMMON_SYSCALL_ACQUIRE(addr) \\\n    syscall_acquire(GET_CALLER_PC(), (uptr)(addr))\n\n#define COMMON_SYSCALL_RELEASE(addr) \\\n    syscall_release(GET_CALLER_PC(), (uptr)(addr))\n\n#define COMMON_SYSCALL_FD_CLOSE(fd) syscall_fd_close(GET_CALLER_PC(), fd)\n\n#define COMMON_SYSCALL_FD_ACQUIRE(fd) syscall_fd_acquire(GET_CALLER_PC(), fd)\n\n#define COMMON_SYSCALL_FD_RELEASE(fd) syscall_fd_release(GET_CALLER_PC(), fd)\n\n#define COMMON_SYSCALL_PRE_FORK() \\\n  syscall_pre_fork(GET_CALLER_PC())\n\n#define COMMON_SYSCALL_POST_FORK(res) \\\n  syscall_post_fork(GET_CALLER_PC(), res)\n\n#include \"sanitizer_common/sanitizer_common_syscalls.inc\"\n\nnamespace __tsan {\n\nstatic void finalize(void *arg) {\n  ThreadState *thr = cur_thread();\n  int status = Finalize(thr);\n  // Make sure the output is not lost.\n  FlushStreams();\n  if (status)\n    Die();\n}\n\n#if !SANITIZER_MAC && !SANITIZER_ANDROID\nstatic void unreachable() {\n  Report(\"FATAL: ThreadSanitizer: unreachable called\\n\");\n  Die();\n}\n#endif\n\nvoid InitializeInterceptors() {\n#if !SANITIZER_MAC\n  // We need to setup it early, because functions like dlsym() can call it.\n  REAL(memset) = internal_memset;\n  REAL(memcpy) = internal_memcpy;\n#endif\n\n  // Instruct libc malloc to consume less memory.\n#if SANITIZER_LINUX\n  mallopt(1, 0);  // M_MXFAST\n  mallopt(-3, 32*1024);  // M_MMAP_THRESHOLD\n#endif\n\n  InitializeCommonInterceptors();\n\n#if !SANITIZER_MAC\n  // We can not use TSAN_INTERCEPT to get setjmp addr,\n  // because it does &setjmp and setjmp is not present in some versions of libc.\n  using __interception::GetRealFunctionAddress;\n  GetRealFunctionAddress(\"setjmp\", (uptr*)&REAL(setjmp), 0, 0);\n  GetRealFunctionAddress(\"_setjmp\", (uptr*)&REAL(_setjmp), 0, 0);\n  GetRealFunctionAddress(\"sigsetjmp\", (uptr*)&REAL(sigsetjmp), 0, 0);\n  GetRealFunctionAddress(\"__sigsetjmp\", (uptr*)&REAL(__sigsetjmp), 0, 0);\n#endif\n\n  TSAN_INTERCEPT(longjmp);\n  TSAN_INTERCEPT(siglongjmp);\n\n  TSAN_INTERCEPT(malloc);\n  TSAN_INTERCEPT(__libc_memalign);\n  TSAN_INTERCEPT(calloc);\n  TSAN_INTERCEPT(realloc);\n  TSAN_INTERCEPT(free);\n  TSAN_INTERCEPT(cfree);\n  TSAN_INTERCEPT(mmap);\n  TSAN_MAYBE_INTERCEPT_MMAP64;\n  TSAN_INTERCEPT(munmap);\n  TSAN_MAYBE_INTERCEPT_MEMALIGN;\n  TSAN_INTERCEPT(valloc);\n  TSAN_MAYBE_INTERCEPT_PVALLOC;\n  TSAN_INTERCEPT(posix_memalign);\n\n  TSAN_INTERCEPT(strlen);\n  TSAN_INTERCEPT(memset);\n  TSAN_INTERCEPT(memcpy);\n  TSAN_INTERCEPT(memmove);\n  TSAN_INTERCEPT(strchr);\n  TSAN_INTERCEPT(strchrnul);\n  TSAN_INTERCEPT(strrchr);\n  TSAN_INTERCEPT(strcpy);  // NOLINT\n  TSAN_INTERCEPT(strncpy);\n  TSAN_INTERCEPT(strdup);\n\n  TSAN_INTERCEPT(pthread_create);\n  TSAN_INTERCEPT(pthread_join);\n  TSAN_INTERCEPT(pthread_detach);\n\n  TSAN_INTERCEPT_VER(pthread_cond_init, PTHREAD_ABI_BASE);\n  TSAN_INTERCEPT_VER(pthread_cond_signal, PTHREAD_ABI_BASE);\n  TSAN_INTERCEPT_VER(pthread_cond_broadcast, PTHREAD_ABI_BASE);\n  TSAN_INTERCEPT_VER(pthread_cond_wait, PTHREAD_ABI_BASE);\n  TSAN_INTERCEPT_VER(pthread_cond_timedwait, PTHREAD_ABI_BASE);\n  TSAN_INTERCEPT_VER(pthread_cond_destroy, PTHREAD_ABI_BASE);\n\n  TSAN_INTERCEPT(pthread_mutex_init);\n  TSAN_INTERCEPT(pthread_mutex_destroy);\n  TSAN_INTERCEPT(pthread_mutex_trylock);\n  TSAN_INTERCEPT(pthread_mutex_timedlock);\n\n  TSAN_INTERCEPT(pthread_spin_init);\n  TSAN_INTERCEPT(pthread_spin_destroy);\n  TSAN_INTERCEPT(pthread_spin_lock);\n  TSAN_INTERCEPT(pthread_spin_trylock);\n  TSAN_INTERCEPT(pthread_spin_unlock);\n\n  TSAN_INTERCEPT(pthread_rwlock_init);\n  TSAN_INTERCEPT(pthread_rwlock_destroy);\n  TSAN_INTERCEPT(pthread_rwlock_rdlock);\n  TSAN_INTERCEPT(pthread_rwlock_tryrdlock);\n  TSAN_INTERCEPT(pthread_rwlock_timedrdlock);\n  TSAN_INTERCEPT(pthread_rwlock_wrlock);\n  TSAN_INTERCEPT(pthread_rwlock_trywrlock);\n  TSAN_INTERCEPT(pthread_rwlock_timedwrlock);\n  TSAN_INTERCEPT(pthread_rwlock_unlock);\n\n  TSAN_INTERCEPT(pthread_barrier_init);\n  TSAN_INTERCEPT(pthread_barrier_destroy);\n  TSAN_INTERCEPT(pthread_barrier_wait);\n\n  TSAN_INTERCEPT(pthread_once);\n\n  TSAN_INTERCEPT(stat);\n  TSAN_MAYBE_INTERCEPT___XSTAT;\n  TSAN_MAYBE_INTERCEPT_STAT64;\n  TSAN_MAYBE_INTERCEPT___XSTAT64;\n  TSAN_INTERCEPT(lstat);\n  TSAN_MAYBE_INTERCEPT___LXSTAT;\n  TSAN_MAYBE_INTERCEPT_LSTAT64;\n  TSAN_MAYBE_INTERCEPT___LXSTAT64;\n  TSAN_INTERCEPT(fstat);\n  TSAN_MAYBE_INTERCEPT___FXSTAT;\n  TSAN_MAYBE_INTERCEPT_FSTAT64;\n  TSAN_MAYBE_INTERCEPT___FXSTAT64;\n  TSAN_INTERCEPT(open);\n  TSAN_MAYBE_INTERCEPT_OPEN64;\n  TSAN_INTERCEPT(creat);\n  TSAN_MAYBE_INTERCEPT_CREAT64;\n  TSAN_INTERCEPT(dup);\n  TSAN_INTERCEPT(dup2);\n  TSAN_INTERCEPT(dup3);\n  TSAN_MAYBE_INTERCEPT_EVENTFD;\n  TSAN_MAYBE_INTERCEPT_SIGNALFD;\n  TSAN_MAYBE_INTERCEPT_INOTIFY_INIT;\n  TSAN_MAYBE_INTERCEPT_INOTIFY_INIT1;\n  TSAN_INTERCEPT(socket);\n  TSAN_INTERCEPT(socketpair);\n  TSAN_INTERCEPT(connect);\n  TSAN_INTERCEPT(bind);\n  TSAN_INTERCEPT(listen);\n  TSAN_MAYBE_INTERCEPT_EPOLL_CREATE;\n  TSAN_MAYBE_INTERCEPT_EPOLL_CREATE1;\n  TSAN_INTERCEPT(close);\n  TSAN_MAYBE_INTERCEPT___CLOSE;\n  TSAN_MAYBE_INTERCEPT___RES_ICLOSE;\n  TSAN_INTERCEPT(pipe);\n  TSAN_INTERCEPT(pipe2);\n\n  TSAN_INTERCEPT(send);\n  TSAN_INTERCEPT(sendmsg);\n  TSAN_INTERCEPT(recv);\n\n  TSAN_INTERCEPT(unlink);\n  TSAN_INTERCEPT(tmpfile);\n  TSAN_MAYBE_INTERCEPT_TMPFILE64;\n  TSAN_INTERCEPT(fread);\n  TSAN_INTERCEPT(fwrite);\n  TSAN_INTERCEPT(abort);\n  TSAN_INTERCEPT(puts);\n  TSAN_INTERCEPT(rmdir);\n  TSAN_INTERCEPT(closedir);\n\n  TSAN_MAYBE_INTERCEPT_EPOLL_CTL;\n  TSAN_MAYBE_INTERCEPT_EPOLL_WAIT;\n\n  TSAN_INTERCEPT(sigaction);\n  TSAN_INTERCEPT(signal);\n  TSAN_INTERCEPT(sigsuspend);\n  TSAN_INTERCEPT(raise);\n  TSAN_INTERCEPT(kill);\n  TSAN_INTERCEPT(pthread_kill);\n  TSAN_INTERCEPT(sleep);\n  TSAN_INTERCEPT(usleep);\n  TSAN_INTERCEPT(nanosleep);\n  TSAN_INTERCEPT(gettimeofday);\n  TSAN_INTERCEPT(getaddrinfo);\n\n  TSAN_INTERCEPT(fork);\n  TSAN_INTERCEPT(vfork);\n#if !SANITIZER_ANDROID\n  TSAN_INTERCEPT(dl_iterate_phdr);\n#endif\n  TSAN_INTERCEPT(on_exit);\n  TSAN_INTERCEPT(__cxa_atexit);\n  TSAN_INTERCEPT(_exit);\n\n#if !SANITIZER_MAC && !SANITIZER_ANDROID\n  // Need to setup it, because interceptors check that the function is resolved.\n  // But atexit is emitted directly into the module, so can't be resolved.\n  REAL(atexit) = (int(*)(void(*)()))unreachable;\n#endif\n\n  if (REAL(__cxa_atexit)(&finalize, 0, 0)) {\n    Printf(\"ThreadSanitizer: failed to setup atexit callback\\n\");\n    Die();\n  }\n\n#if !SANITIZER_MAC\n  if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) {\n    Printf(\"ThreadSanitizer: failed to create thread key\\n\");\n    Die();\n  }\n#endif\n\n  FdInit();\n}\n\n}  // namespace __tsan\n\n// Invisible barrier for tests.\n// There were several unsuccessful iterations for this functionality:\n// 1. Initially it was implemented in user code using\n//    REAL(pthread_barrier_wait). But pthread_barrier_wait is not supported on\n//    MacOS. Futexes are linux-specific for this matter.\n// 2. Then we switched to atomics+usleep(10). But usleep produced parasitic\n//    \"as-if synchronized via sleep\" messages in reports which failed some\n//    output tests.\n// 3. Then we switched to atomics+sched_yield. But this produced tons of tsan-\n//    visible events, which lead to \"failed to restore stack trace\" failures.\n// Note that no_sanitize_thread attribute does not turn off atomic interception\n// so attaching it to the function defined in user code does not help.\n// That's why we now have what we have.\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_testonly_barrier_init(u64 *barrier, u32 count) {\n  if (count >= (1 << 8)) {\n      Printf(\"barrier_init: count is too large (%d)\\n\", count);\n      Die();\n  }\n  // 8 lsb is thread count, the remaining are count of entered threads.\n  *barrier = count;\n}\n\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_testonly_barrier_wait(u64 *barrier) {\n  unsigned old = __atomic_fetch_add(barrier, 1 << 8, __ATOMIC_RELAXED);\n  unsigned old_epoch = (old >> 8) / (old & 0xff);\n  for (;;) {\n    unsigned cur = __atomic_load_n(barrier, __ATOMIC_RELAXED);\n    unsigned cur_epoch = (cur >> 8) / (cur & 0xff);\n    if (cur_epoch != old_epoch)\n      return;\n    internal_sched_yield();\n  }\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_interceptors.h",
    "content": "#ifndef TSAN_INTERCEPTORS_H\n#define TSAN_INTERCEPTORS_H\n\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"tsan_rtl.h\"\n\nnamespace __tsan {\n\nclass ScopedInterceptor {\n public:\n  ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc);\n  ~ScopedInterceptor();\n  void UserCallbackStart();\n  void UserCallbackEnd();\n private:\n  ThreadState *const thr_;\n  const uptr pc_;\n  bool in_ignored_lib_;\n};\n\n}  // namespace __tsan\n\n#define SCOPED_INTERCEPTOR_RAW(func, ...) \\\n    ThreadState *thr = cur_thread(); \\\n    const uptr caller_pc = GET_CALLER_PC(); \\\n    ScopedInterceptor si(thr, #func, caller_pc); \\\n    const uptr pc = StackTrace::GetCurrentPc(); \\\n    (void)pc; \\\n/**/\n\n#define SCOPED_TSAN_INTERCEPTOR(func, ...) \\\n    SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \\\n    if (REAL(func) == 0) { \\\n      Report(\"FATAL: ThreadSanitizer: failed to intercept %s\\n\", #func); \\\n      Die(); \\\n    }                                                    \\\n    if (thr->ignore_interceptors || thr->in_ignored_lib) \\\n      return REAL(func)(__VA_ARGS__); \\\n/**/\n\n#define SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START() \\\n    si.UserCallbackStart();\n\n#define SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END() \\\n    si.UserCallbackEnd();\n\n#define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__)\n\n#if SANITIZER_FREEBSD\n#define __libc_free __free\n#define __libc_malloc __malloc\n#endif\n\nextern \"C\" void __libc_free(void *ptr);\nextern \"C\" void *__libc_malloc(uptr size);\n\n#endif  // TSAN_INTERCEPTORS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cc",
    "content": "//===-- tsan_interceptors_mac.cc ------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Mac-specific interceptors.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_MAC\n\n#include \"interception/interception.h\"\n#include \"tsan_interceptors.h\"\n\n#include <libkern/OSAtomic.h>\n\nnamespace __tsan {\n\nTSAN_INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) {\n  CHECK(!cur_thread()->is_dead);\n  if (!cur_thread()->is_inited) {\n    return REAL(OSSpinLockLock)(lock);\n  }\n  SCOPED_TSAN_INTERCEPTOR(OSSpinLockLock, lock);\n  REAL(OSSpinLockLock)(lock);\n  Acquire(thr, pc, (uptr)lock);\n}\n\nTSAN_INTERCEPTOR(bool, OSSpinLockTry, volatile OSSpinLock *lock) {\n  CHECK(!cur_thread()->is_dead);\n  if (!cur_thread()->is_inited) {\n    return REAL(OSSpinLockTry)(lock);\n  }\n  SCOPED_TSAN_INTERCEPTOR(OSSpinLockTry, lock);\n  bool result = REAL(OSSpinLockTry)(lock);\n  if (result)\n    Acquire(thr, pc, (uptr)lock);\n  return result;\n}\n\nTSAN_INTERCEPTOR(void, OSSpinLockUnlock, volatile OSSpinLock *lock) {\n  CHECK(!cur_thread()->is_dead);\n  if (!cur_thread()->is_inited) {\n    return REAL(OSSpinLockUnlock)(lock);\n  }\n  SCOPED_TSAN_INTERCEPTOR(OSSpinLockUnlock, lock);\n  Release(thr, pc, (uptr)lock);\n  REAL(OSSpinLockUnlock)(lock);\n}\n\nTSAN_INTERCEPTOR(void, os_lock_lock, void *lock) {\n  CHECK(!cur_thread()->is_dead);\n  if (!cur_thread()->is_inited) {\n    return REAL(os_lock_lock)(lock);\n  }\n  SCOPED_TSAN_INTERCEPTOR(os_lock_lock, lock);\n  REAL(os_lock_lock)(lock);\n  Acquire(thr, pc, (uptr)lock);\n}\n\nTSAN_INTERCEPTOR(bool, os_lock_trylock, void *lock) {\n  CHECK(!cur_thread()->is_dead);\n  if (!cur_thread()->is_inited) {\n    return REAL(os_lock_trylock)(lock);\n  }\n  SCOPED_TSAN_INTERCEPTOR(os_lock_trylock, lock);\n  bool result = REAL(os_lock_trylock)(lock);\n  if (result)\n    Acquire(thr, pc, (uptr)lock);\n  return result;\n}\n\nTSAN_INTERCEPTOR(void, os_lock_unlock, void *lock) {\n  CHECK(!cur_thread()->is_dead);\n  if (!cur_thread()->is_inited) {\n    return REAL(os_lock_unlock)(lock);\n  }\n  SCOPED_TSAN_INTERCEPTOR(os_lock_unlock, lock);\n  Release(thr, pc, (uptr)lock);\n  REAL(os_lock_unlock)(lock);\n}\n\n}  // namespace __tsan\n\n#endif  // SANITIZER_MAC\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_interface.cc",
    "content": "//===-- tsan_interface.cc -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"tsan_interface.h\"\n#include \"tsan_interface_ann.h\"\n#include \"tsan_rtl.h\"\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n\n#define CALLERPC ((uptr)__builtin_return_address(0))\n\nusing namespace __tsan;  // NOLINT\n\ntypedef u16 uint16_t;\ntypedef u32 uint32_t;\ntypedef u64 uint64_t;\n\nvoid __tsan_init() {\n  Initialize(cur_thread());\n}\n\nvoid __tsan_read16(void *addr) {\n  MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8);\n  MemoryRead(cur_thread(), CALLERPC, (uptr)addr + 8, kSizeLog8);\n}\n\nvoid __tsan_write16(void *addr) {\n  MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8);\n  MemoryWrite(cur_thread(), CALLERPC, (uptr)addr + 8, kSizeLog8);\n}\n\nvoid __tsan_read16_pc(void *addr, void *pc) {\n  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);\n  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr + 8, kSizeLog8);\n}\n\nvoid __tsan_write16_pc(void *addr, void *pc) {\n  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);\n  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr + 8, kSizeLog8);\n}\n\n// __tsan_unaligned_read/write calls are emitted by compiler.\n\nvoid __tsan_unaligned_read2(const void *addr) {\n  UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, false, false);\n}\n\nvoid __tsan_unaligned_read4(const void *addr) {\n  UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, false, false);\n}\n\nvoid __tsan_unaligned_read8(const void *addr) {\n  UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, false, false);\n}\n\nvoid __tsan_unaligned_read16(const void *addr) {\n  UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 16, false, false);\n}\n\nvoid __tsan_unaligned_write2(void *addr) {\n  UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, true, false);\n}\n\nvoid __tsan_unaligned_write4(void *addr) {\n  UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, true, false);\n}\n\nvoid __tsan_unaligned_write8(void *addr) {\n  UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, true, false);\n}\n\nvoid __tsan_unaligned_write16(void *addr) {\n  UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 16, true, false);\n}\n\n// __sanitizer_unaligned_load/store are for user instrumentation.\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE\nu16 __sanitizer_unaligned_load16(const uu16 *addr) {\n  __tsan_unaligned_read2(addr);\n  return *addr;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nu32 __sanitizer_unaligned_load32(const uu32 *addr) {\n  __tsan_unaligned_read4(addr);\n  return *addr;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nu64 __sanitizer_unaligned_load64(const uu64 *addr) {\n  __tsan_unaligned_read8(addr);\n  return *addr;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_unaligned_store16(uu16 *addr, u16 v) {\n  __tsan_unaligned_write2(addr);\n  *addr = v;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_unaligned_store32(uu32 *addr, u32 v) {\n  __tsan_unaligned_write4(addr);\n  *addr = v;\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_unaligned_store64(uu64 *addr, u64 v) {\n  __tsan_unaligned_write8(addr);\n  *addr = v;\n}\n}  // extern \"C\"\n\nvoid __tsan_acquire(void *addr) {\n  Acquire(cur_thread(), CALLERPC, (uptr)addr);\n}\n\nvoid __tsan_release(void *addr) {\n  Release(cur_thread(), CALLERPC, (uptr)addr);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_interface.h",
    "content": "//===-- tsan_interface.h ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// The functions declared in this header will be inserted by the instrumentation\n// module.\n// This header can be included by the instrumented program or by TSan tests.\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_INTERFACE_H\n#define TSAN_INTERFACE_H\n\n#include <sanitizer_common/sanitizer_internal_defs.h>\n\n// This header should NOT include any other headers.\n// All functions in this header are extern \"C\" and start with __tsan_.\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// This function should be called at the very beginning of the process,\n// before any instrumented code is executed and before any call to malloc.\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_init();\n\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_read1(void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_read2(void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_read4(void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_read8(void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_read16(void *addr);\n\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_write1(void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_write2(void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_write4(void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_write8(void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_write16(void *addr);\n\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_read2(const void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_read4(const void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_read8(const void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_read16(const void *addr);\n\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_write2(void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_write4(void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_write8(void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_write16(void *addr);\n\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_read1_pc(void *addr, void *pc);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_read2_pc(void *addr, void *pc);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_read4_pc(void *addr, void *pc);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_read8_pc(void *addr, void *pc);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_read16_pc(void *addr, void *pc);\n\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_write1_pc(void *addr, void *pc);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_write2_pc(void *addr, void *pc);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_write4_pc(void *addr, void *pc);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_write8_pc(void *addr, void *pc);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_write16_pc(void *addr, void *pc);\n\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_vptr_read(void **vptr_p);\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_vptr_update(void **vptr_p, void *new_val);\n\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_func_entry(void *call_pc);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_func_exit();\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_read_range(void *addr, unsigned long size);  // NOLINT\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_write_range(void *addr, unsigned long size);  // NOLINT\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#endif  // TSAN_INTERFACE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cc",
    "content": "//===-- tsan_interface_ann.cc ---------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"tsan_interface_ann.h\"\n#include \"tsan_mutex.h\"\n#include \"tsan_report.h\"\n#include \"tsan_rtl.h\"\n#include \"tsan_mman.h\"\n#include \"tsan_flags.h\"\n#include \"tsan_platform.h\"\n#include \"tsan_vector.h\"\n\n#define CALLERPC ((uptr)__builtin_return_address(0))\n\nusing namespace __tsan;  // NOLINT\n\nnamespace __tsan {\n\nclass ScopedAnnotation {\n public:\n  ScopedAnnotation(ThreadState *thr, const char *aname, const char *f, int l,\n                   uptr pc)\n      : thr_(thr) {\n    FuncEntry(thr_, pc);\n    DPrintf(\"#%d: annotation %s() %s:%d\\n\", thr_->tid, aname, f, l);\n  }\n\n  ~ScopedAnnotation() {\n    FuncExit(thr_);\n    CheckNoLocks(thr_);\n  }\n private:\n  ThreadState *const thr_;\n};\n\n#define SCOPED_ANNOTATION(typ) \\\n    if (!flags()->enable_annotations) \\\n      return; \\\n    ThreadState *thr = cur_thread(); \\\n    const uptr caller_pc = (uptr)__builtin_return_address(0); \\\n    StatInc(thr, StatAnnotation); \\\n    StatInc(thr, Stat##typ); \\\n    ScopedAnnotation sa(thr, __func__, f, l, caller_pc); \\\n    const uptr pc = StackTrace::GetCurrentPc(); \\\n    (void)pc; \\\n/**/\n\nstatic const int kMaxDescLen = 128;\n\nstruct ExpectRace {\n  ExpectRace *next;\n  ExpectRace *prev;\n  atomic_uintptr_t hitcount;\n  atomic_uintptr_t addcount;\n  uptr addr;\n  uptr size;\n  char *file;\n  int line;\n  char desc[kMaxDescLen];\n};\n\nstruct DynamicAnnContext {\n  Mutex mtx;\n  ExpectRace expect;\n  ExpectRace benign;\n\n  DynamicAnnContext()\n    : mtx(MutexTypeAnnotations, StatMtxAnnotations) {\n  }\n};\n\nstatic DynamicAnnContext *dyn_ann_ctx;\nstatic char dyn_ann_ctx_placeholder[sizeof(DynamicAnnContext)] ALIGNED(64);\n\nstatic void AddExpectRace(ExpectRace *list,\n    char *f, int l, uptr addr, uptr size, char *desc) {\n  ExpectRace *race = list->next;\n  for (; race != list; race = race->next) {\n    if (race->addr == addr && race->size == size) {\n      atomic_store_relaxed(&race->addcount,\n          atomic_load_relaxed(&race->addcount) + 1);\n      return;\n    }\n  }\n  race = (ExpectRace*)internal_alloc(MBlockExpectRace, sizeof(ExpectRace));\n  race->addr = addr;\n  race->size = size;\n  race->file = f;\n  race->line = l;\n  race->desc[0] = 0;\n  atomic_store_relaxed(&race->hitcount, 0);\n  atomic_store_relaxed(&race->addcount, 1);\n  if (desc) {\n    int i = 0;\n    for (; i < kMaxDescLen - 1 && desc[i]; i++)\n      race->desc[i] = desc[i];\n    race->desc[i] = 0;\n  }\n  race->prev = list;\n  race->next = list->next;\n  race->next->prev = race;\n  list->next = race;\n}\n\nstatic ExpectRace *FindRace(ExpectRace *list, uptr addr, uptr size) {\n  for (ExpectRace *race = list->next; race != list; race = race->next) {\n    uptr maxbegin = max(race->addr, addr);\n    uptr minend = min(race->addr + race->size, addr + size);\n    if (maxbegin < minend)\n      return race;\n  }\n  return 0;\n}\n\nstatic bool CheckContains(ExpectRace *list, uptr addr, uptr size) {\n  ExpectRace *race = FindRace(list, addr, size);\n  if (race == 0)\n    return false;\n  DPrintf(\"Hit expected/benign race: %s addr=%zx:%d %s:%d\\n\",\n      race->desc, race->addr, (int)race->size, race->file, race->line);\n  atomic_fetch_add(&race->hitcount, 1, memory_order_relaxed);\n  return true;\n}\n\nstatic void InitList(ExpectRace *list) {\n  list->next = list;\n  list->prev = list;\n}\n\nvoid InitializeDynamicAnnotations() {\n  dyn_ann_ctx = new(dyn_ann_ctx_placeholder) DynamicAnnContext;\n  InitList(&dyn_ann_ctx->expect);\n  InitList(&dyn_ann_ctx->benign);\n}\n\nbool IsExpectedReport(uptr addr, uptr size) {\n  ReadLock lock(&dyn_ann_ctx->mtx);\n  if (CheckContains(&dyn_ann_ctx->expect, addr, size))\n    return true;\n  if (CheckContains(&dyn_ann_ctx->benign, addr, size))\n    return true;\n  return false;\n}\n\nstatic void CollectMatchedBenignRaces(Vector<ExpectRace> *matched,\n    int *unique_count, int *hit_count, atomic_uintptr_t ExpectRace::*counter) {\n  ExpectRace *list = &dyn_ann_ctx->benign;\n  for (ExpectRace *race = list->next; race != list; race = race->next) {\n    (*unique_count)++;\n    const uptr cnt = atomic_load_relaxed(&(race->*counter));\n    if (cnt == 0)\n      continue;\n    *hit_count += cnt;\n    uptr i = 0;\n    for (; i < matched->Size(); i++) {\n      ExpectRace *race0 = &(*matched)[i];\n      if (race->line == race0->line\n          && internal_strcmp(race->file, race0->file) == 0\n          && internal_strcmp(race->desc, race0->desc) == 0) {\n        atomic_fetch_add(&(race0->*counter), cnt, memory_order_relaxed);\n        break;\n      }\n    }\n    if (i == matched->Size())\n      matched->PushBack(*race);\n  }\n}\n\nvoid PrintMatchedBenignRaces() {\n  Lock lock(&dyn_ann_ctx->mtx);\n  int unique_count = 0;\n  int hit_count = 0;\n  int add_count = 0;\n  Vector<ExpectRace> hit_matched(MBlockScopedBuf);\n  CollectMatchedBenignRaces(&hit_matched, &unique_count, &hit_count,\n      &ExpectRace::hitcount);\n  Vector<ExpectRace> add_matched(MBlockScopedBuf);\n  CollectMatchedBenignRaces(&add_matched, &unique_count, &add_count,\n      &ExpectRace::addcount);\n  if (hit_matched.Size()) {\n    Printf(\"ThreadSanitizer: Matched %d \\\"benign\\\" races (pid=%d):\\n\",\n        hit_count, (int)internal_getpid());\n    for (uptr i = 0; i < hit_matched.Size(); i++) {\n      Printf(\"%d %s:%d %s\\n\",\n          atomic_load_relaxed(&hit_matched[i].hitcount),\n          hit_matched[i].file, hit_matched[i].line, hit_matched[i].desc);\n    }\n  }\n  if (hit_matched.Size()) {\n    Printf(\"ThreadSanitizer: Annotated %d \\\"benign\\\" races, %d unique\"\n           \" (pid=%d):\\n\",\n        add_count, unique_count, (int)internal_getpid());\n    for (uptr i = 0; i < add_matched.Size(); i++) {\n      Printf(\"%d %s:%d %s\\n\",\n          atomic_load_relaxed(&add_matched[i].addcount),\n          add_matched[i].file, add_matched[i].line, add_matched[i].desc);\n    }\n  }\n}\n\nstatic void ReportMissedExpectedRace(ExpectRace *race) {\n  Printf(\"==================\\n\");\n  Printf(\"WARNING: ThreadSanitizer: missed expected data race\\n\");\n  Printf(\"  %s addr=%zx %s:%d\\n\",\n      race->desc, race->addr, race->file, race->line);\n  Printf(\"==================\\n\");\n}\n}  // namespace __tsan\n\nusing namespace __tsan;  // NOLINT\n\nextern \"C\" {\nvoid INTERFACE_ATTRIBUTE AnnotateHappensBefore(char *f, int l, uptr addr) {\n  SCOPED_ANNOTATION(AnnotateHappensBefore);\n  Release(thr, pc, addr);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateHappensAfter(char *f, int l, uptr addr) {\n  SCOPED_ANNOTATION(AnnotateHappensAfter);\n  Acquire(thr, pc, addr);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateCondVarSignal(char *f, int l, uptr cv) {\n  SCOPED_ANNOTATION(AnnotateCondVarSignal);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateCondVarSignalAll(char *f, int l, uptr cv) {\n  SCOPED_ANNOTATION(AnnotateCondVarSignalAll);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateMutexIsNotPHB(char *f, int l, uptr mu) {\n  SCOPED_ANNOTATION(AnnotateMutexIsNotPHB);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateCondVarWait(char *f, int l, uptr cv,\n                                             uptr lock) {\n  SCOPED_ANNOTATION(AnnotateCondVarWait);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateRWLockCreate(char *f, int l, uptr m) {\n  SCOPED_ANNOTATION(AnnotateRWLockCreate);\n  MutexCreate(thr, pc, m, true, true, false);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateRWLockCreateStatic(char *f, int l, uptr m) {\n  SCOPED_ANNOTATION(AnnotateRWLockCreateStatic);\n  MutexCreate(thr, pc, m, true, true, true);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateRWLockDestroy(char *f, int l, uptr m) {\n  SCOPED_ANNOTATION(AnnotateRWLockDestroy);\n  MutexDestroy(thr, pc, m);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateRWLockAcquired(char *f, int l, uptr m,\n                                                uptr is_w) {\n  SCOPED_ANNOTATION(AnnotateRWLockAcquired);\n  if (is_w)\n    MutexLock(thr, pc, m);\n  else\n    MutexReadLock(thr, pc, m);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateRWLockReleased(char *f, int l, uptr m,\n                                                uptr is_w) {\n  SCOPED_ANNOTATION(AnnotateRWLockReleased);\n  if (is_w)\n    MutexUnlock(thr, pc, m);\n  else\n    MutexReadUnlock(thr, pc, m);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateTraceMemory(char *f, int l, uptr mem) {\n  SCOPED_ANNOTATION(AnnotateTraceMemory);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateFlushState(char *f, int l) {\n  SCOPED_ANNOTATION(AnnotateFlushState);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateNewMemory(char *f, int l, uptr mem,\n                                           uptr size) {\n  SCOPED_ANNOTATION(AnnotateNewMemory);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateNoOp(char *f, int l, uptr mem) {\n  SCOPED_ANNOTATION(AnnotateNoOp);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateFlushExpectedRaces(char *f, int l) {\n  SCOPED_ANNOTATION(AnnotateFlushExpectedRaces);\n  Lock lock(&dyn_ann_ctx->mtx);\n  while (dyn_ann_ctx->expect.next != &dyn_ann_ctx->expect) {\n    ExpectRace *race = dyn_ann_ctx->expect.next;\n    if (atomic_load_relaxed(&race->hitcount) == 0) {\n      ctx->nmissed_expected++;\n      ReportMissedExpectedRace(race);\n    }\n    race->prev->next = race->next;\n    race->next->prev = race->prev;\n    internal_free(race);\n  }\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateEnableRaceDetection(\n    char *f, int l, int enable) {\n  SCOPED_ANNOTATION(AnnotateEnableRaceDetection);\n  // FIXME: Reconsider this functionality later. It may be irrelevant.\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateMutexIsUsedAsCondVar(\n    char *f, int l, uptr mu) {\n  SCOPED_ANNOTATION(AnnotateMutexIsUsedAsCondVar);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotatePCQGet(\n    char *f, int l, uptr pcq) {\n  SCOPED_ANNOTATION(AnnotatePCQGet);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotatePCQPut(\n    char *f, int l, uptr pcq) {\n  SCOPED_ANNOTATION(AnnotatePCQPut);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotatePCQDestroy(\n    char *f, int l, uptr pcq) {\n  SCOPED_ANNOTATION(AnnotatePCQDestroy);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotatePCQCreate(\n    char *f, int l, uptr pcq) {\n  SCOPED_ANNOTATION(AnnotatePCQCreate);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateExpectRace(\n    char *f, int l, uptr mem, char *desc) {\n  SCOPED_ANNOTATION(AnnotateExpectRace);\n  Lock lock(&dyn_ann_ctx->mtx);\n  AddExpectRace(&dyn_ann_ctx->expect,\n                f, l, mem, 1, desc);\n  DPrintf(\"Add expected race: %s addr=%zx %s:%d\\n\", desc, mem, f, l);\n}\n\nstatic void BenignRaceImpl(\n    char *f, int l, uptr mem, uptr size, char *desc) {\n  Lock lock(&dyn_ann_ctx->mtx);\n  AddExpectRace(&dyn_ann_ctx->benign,\n                f, l, mem, size, desc);\n  DPrintf(\"Add benign race: %s addr=%zx %s:%d\\n\", desc, mem, f, l);\n}\n\n// FIXME: Turn it off later. WTF is benign race?1?? Go talk to Hans Boehm.\nvoid INTERFACE_ATTRIBUTE AnnotateBenignRaceSized(\n    char *f, int l, uptr mem, uptr size, char *desc) {\n  SCOPED_ANNOTATION(AnnotateBenignRaceSized);\n  BenignRaceImpl(f, l, mem, size, desc);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateBenignRace(\n    char *f, int l, uptr mem, char *desc) {\n  SCOPED_ANNOTATION(AnnotateBenignRace);\n  BenignRaceImpl(f, l, mem, 1, desc);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateIgnoreReadsBegin(char *f, int l) {\n  SCOPED_ANNOTATION(AnnotateIgnoreReadsBegin);\n  ThreadIgnoreBegin(thr, pc);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateIgnoreReadsEnd(char *f, int l) {\n  SCOPED_ANNOTATION(AnnotateIgnoreReadsEnd);\n  ThreadIgnoreEnd(thr, pc);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateIgnoreWritesBegin(char *f, int l) {\n  SCOPED_ANNOTATION(AnnotateIgnoreWritesBegin);\n  ThreadIgnoreBegin(thr, pc);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateIgnoreWritesEnd(char *f, int l) {\n  SCOPED_ANNOTATION(AnnotateIgnoreWritesEnd);\n  ThreadIgnoreEnd(thr, pc);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateIgnoreSyncBegin(char *f, int l) {\n  SCOPED_ANNOTATION(AnnotateIgnoreSyncBegin);\n  ThreadIgnoreSyncBegin(thr, pc);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateIgnoreSyncEnd(char *f, int l) {\n  SCOPED_ANNOTATION(AnnotateIgnoreSyncEnd);\n  ThreadIgnoreSyncEnd(thr, pc);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotatePublishMemoryRange(\n    char *f, int l, uptr addr, uptr size) {\n  SCOPED_ANNOTATION(AnnotatePublishMemoryRange);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateUnpublishMemoryRange(\n    char *f, int l, uptr addr, uptr size) {\n  SCOPED_ANNOTATION(AnnotateUnpublishMemoryRange);\n}\n\nvoid INTERFACE_ATTRIBUTE AnnotateThreadName(\n    char *f, int l, char *name) {\n  SCOPED_ANNOTATION(AnnotateThreadName);\n  ThreadSetName(thr, name);\n}\n\n// We deliberately omit the implementation of WTFAnnotateHappensBefore() and\n// WTFAnnotateHappensAfter(). Those are being used by Webkit to annotate\n// atomic operations, which should be handled by ThreadSanitizer correctly.\nvoid INTERFACE_ATTRIBUTE WTFAnnotateHappensBefore(char *f, int l, uptr addr) {\n  SCOPED_ANNOTATION(AnnotateHappensBefore);\n}\n\nvoid INTERFACE_ATTRIBUTE WTFAnnotateHappensAfter(char *f, int l, uptr addr) {\n  SCOPED_ANNOTATION(AnnotateHappensAfter);\n}\n\nvoid INTERFACE_ATTRIBUTE WTFAnnotateBenignRaceSized(\n    char *f, int l, uptr mem, uptr sz, char *desc) {\n  SCOPED_ANNOTATION(AnnotateBenignRaceSized);\n  BenignRaceImpl(f, l, mem, sz, desc);\n}\n\nint INTERFACE_ATTRIBUTE RunningOnValgrind() {\n  return flags()->running_on_valgrind;\n}\n\ndouble __attribute__((weak)) INTERFACE_ATTRIBUTE ValgrindSlowdown(void) {\n  return 10.0;\n}\n\nconst char INTERFACE_ATTRIBUTE* ThreadSanitizerQuery(const char *query) {\n  if (internal_strcmp(query, \"pure_happens_before\") == 0)\n    return \"1\";\n  else\n    return \"0\";\n}\n\nvoid INTERFACE_ATTRIBUTE\nAnnotateMemoryIsInitialized(char *f, int l, uptr mem, uptr sz) {}\nvoid INTERFACE_ATTRIBUTE\nAnnotateMemoryIsUninitialized(char *f, int l, uptr mem, uptr sz) {}\n}  // extern \"C\"\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_interface_ann.h",
    "content": "//===-- tsan_interface_ann.h ------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Interface for dynamic annotations.\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_INTERFACE_ANN_H\n#define TSAN_INTERFACE_ANN_H\n\n#include <sanitizer_common/sanitizer_internal_defs.h>\n\n// This header should NOT include any other headers.\n// All functions in this header are extern \"C\" and start with __tsan_.\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_acquire(void *addr);\nSANITIZER_INTERFACE_ATTRIBUTE void __tsan_release(void *addr);\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#endif  // TSAN_INTERFACE_ANN_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cc",
    "content": "//===-- tsan_interface_atomic.cc ------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n\n// ThreadSanitizer atomic operations are based on C++11/C1x standards.\n// For background see C++11 standard.  A slightly older, publicly\n// available draft of the standard (not entirely up-to-date, but close enough\n// for casual browsing) is available here:\n// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf\n// The following page contains more background information:\n// http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/\n\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"sanitizer_common/sanitizer_mutex.h\"\n#include \"tsan_flags.h\"\n#include \"tsan_rtl.h\"\n\nusing namespace __tsan;  // NOLINT\n\n// These should match declarations from public tsan_interface_atomic.h header.\ntypedef unsigned char      a8;\ntypedef unsigned short     a16;  // NOLINT\ntypedef unsigned int       a32;\ntypedef unsigned long long a64;  // NOLINT\n#if !defined(SANITIZER_GO) && (defined(__SIZEOF_INT128__) \\\n    || (__clang_major__ * 100 + __clang_minor__ >= 302)) && !defined(__mips64)\n__extension__ typedef __int128 a128;\n# define __TSAN_HAS_INT128 1\n#else\n# define __TSAN_HAS_INT128 0\n#endif\n\n#if !defined(SANITIZER_GO) && __TSAN_HAS_INT128\n// Protects emulation of 128-bit atomic operations.\nstatic StaticSpinMutex mutex128;\n#endif\n\n// Part of ABI, do not change.\n// http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/atomic?view=markup\ntypedef enum {\n  mo_relaxed,\n  mo_consume,\n  mo_acquire,\n  mo_release,\n  mo_acq_rel,\n  mo_seq_cst\n} morder;\n\nstatic bool IsLoadOrder(morder mo) {\n  return mo == mo_relaxed || mo == mo_consume\n      || mo == mo_acquire || mo == mo_seq_cst;\n}\n\nstatic bool IsStoreOrder(morder mo) {\n  return mo == mo_relaxed || mo == mo_release || mo == mo_seq_cst;\n}\n\nstatic bool IsReleaseOrder(morder mo) {\n  return mo == mo_release || mo == mo_acq_rel || mo == mo_seq_cst;\n}\n\nstatic bool IsAcquireOrder(morder mo) {\n  return mo == mo_consume || mo == mo_acquire\n      || mo == mo_acq_rel || mo == mo_seq_cst;\n}\n\nstatic bool IsAcqRelOrder(morder mo) {\n  return mo == mo_acq_rel || mo == mo_seq_cst;\n}\n\ntemplate<typename T> T func_xchg(volatile T *v, T op) {\n  T res = __sync_lock_test_and_set(v, op);\n  // __sync_lock_test_and_set does not contain full barrier.\n  __sync_synchronize();\n  return res;\n}\n\ntemplate<typename T> T func_add(volatile T *v, T op) {\n  return __sync_fetch_and_add(v, op);\n}\n\ntemplate<typename T> T func_sub(volatile T *v, T op) {\n  return __sync_fetch_and_sub(v, op);\n}\n\ntemplate<typename T> T func_and(volatile T *v, T op) {\n  return __sync_fetch_and_and(v, op);\n}\n\ntemplate<typename T> T func_or(volatile T *v, T op) {\n  return __sync_fetch_and_or(v, op);\n}\n\ntemplate<typename T> T func_xor(volatile T *v, T op) {\n  return __sync_fetch_and_xor(v, op);\n}\n\ntemplate<typename T> T func_nand(volatile T *v, T op) {\n  // clang does not support __sync_fetch_and_nand.\n  T cmp = *v;\n  for (;;) {\n    T newv = ~(cmp & op);\n    T cur = __sync_val_compare_and_swap(v, cmp, newv);\n    if (cmp == cur)\n      return cmp;\n    cmp = cur;\n  }\n}\n\ntemplate<typename T> T func_cas(volatile T *v, T cmp, T xch) {\n  return __sync_val_compare_and_swap(v, cmp, xch);\n}\n\n// clang does not support 128-bit atomic ops.\n// Atomic ops are executed under tsan internal mutex,\n// here we assume that the atomic variables are not accessed\n// from non-instrumented code.\n#if !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) && !defined(SANITIZER_GO) \\\n    && __TSAN_HAS_INT128\na128 func_xchg(volatile a128 *v, a128 op) {\n  SpinMutexLock lock(&mutex128);\n  a128 cmp = *v;\n  *v = op;\n  return cmp;\n}\n\na128 func_add(volatile a128 *v, a128 op) {\n  SpinMutexLock lock(&mutex128);\n  a128 cmp = *v;\n  *v = cmp + op;\n  return cmp;\n}\n\na128 func_sub(volatile a128 *v, a128 op) {\n  SpinMutexLock lock(&mutex128);\n  a128 cmp = *v;\n  *v = cmp - op;\n  return cmp;\n}\n\na128 func_and(volatile a128 *v, a128 op) {\n  SpinMutexLock lock(&mutex128);\n  a128 cmp = *v;\n  *v = cmp & op;\n  return cmp;\n}\n\na128 func_or(volatile a128 *v, a128 op) {\n  SpinMutexLock lock(&mutex128);\n  a128 cmp = *v;\n  *v = cmp | op;\n  return cmp;\n}\n\na128 func_xor(volatile a128 *v, a128 op) {\n  SpinMutexLock lock(&mutex128);\n  a128 cmp = *v;\n  *v = cmp ^ op;\n  return cmp;\n}\n\na128 func_nand(volatile a128 *v, a128 op) {\n  SpinMutexLock lock(&mutex128);\n  a128 cmp = *v;\n  *v = ~(cmp & op);\n  return cmp;\n}\n\na128 func_cas(volatile a128 *v, a128 cmp, a128 xch) {\n  SpinMutexLock lock(&mutex128);\n  a128 cur = *v;\n  if (cur == cmp)\n    *v = xch;\n  return cur;\n}\n#endif\n\ntemplate<typename T>\nstatic int SizeLog() {\n  if (sizeof(T) <= 1)\n    return kSizeLog1;\n  else if (sizeof(T) <= 2)\n    return kSizeLog2;\n  else if (sizeof(T) <= 4)\n    return kSizeLog4;\n  else\n    return kSizeLog8;\n  // For 16-byte atomics we also use 8-byte memory access,\n  // this leads to false negatives only in very obscure cases.\n}\n\n#ifndef SANITIZER_GO\nstatic atomic_uint8_t *to_atomic(const volatile a8 *a) {\n  return reinterpret_cast<atomic_uint8_t *>(const_cast<a8 *>(a));\n}\n\nstatic atomic_uint16_t *to_atomic(const volatile a16 *a) {\n  return reinterpret_cast<atomic_uint16_t *>(const_cast<a16 *>(a));\n}\n#endif\n\nstatic atomic_uint32_t *to_atomic(const volatile a32 *a) {\n  return reinterpret_cast<atomic_uint32_t *>(const_cast<a32 *>(a));\n}\n\nstatic atomic_uint64_t *to_atomic(const volatile a64 *a) {\n  return reinterpret_cast<atomic_uint64_t *>(const_cast<a64 *>(a));\n}\n\nstatic memory_order to_mo(morder mo) {\n  switch (mo) {\n  case mo_relaxed: return memory_order_relaxed;\n  case mo_consume: return memory_order_consume;\n  case mo_acquire: return memory_order_acquire;\n  case mo_release: return memory_order_release;\n  case mo_acq_rel: return memory_order_acq_rel;\n  case mo_seq_cst: return memory_order_seq_cst;\n  }\n  CHECK(0);\n  return memory_order_seq_cst;\n}\n\ntemplate<typename T>\nstatic T NoTsanAtomicLoad(const volatile T *a, morder mo) {\n  return atomic_load(to_atomic(a), to_mo(mo));\n}\n\n#if __TSAN_HAS_INT128 && !defined(SANITIZER_GO)\nstatic a128 NoTsanAtomicLoad(const volatile a128 *a, morder mo) {\n  SpinMutexLock lock(&mutex128);\n  return *a;\n}\n#endif\n\ntemplate<typename T>\nstatic T AtomicLoad(ThreadState *thr, uptr pc, const volatile T *a,\n    morder mo) {\n  CHECK(IsLoadOrder(mo));\n  // This fast-path is critical for performance.\n  // Assume the access is atomic.\n  if (!IsAcquireOrder(mo)) {\n    MemoryReadAtomic(thr, pc, (uptr)a, SizeLog<T>());\n    return NoTsanAtomicLoad(a, mo);\n  }\n  SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, (uptr)a, false);\n  AcquireImpl(thr, pc, &s->clock);\n  T v = NoTsanAtomicLoad(a, mo);\n  s->mtx.ReadUnlock();\n  MemoryReadAtomic(thr, pc, (uptr)a, SizeLog<T>());\n  return v;\n}\n\ntemplate<typename T>\nstatic void NoTsanAtomicStore(volatile T *a, T v, morder mo) {\n  atomic_store(to_atomic(a), v, to_mo(mo));\n}\n\n#if __TSAN_HAS_INT128 && !defined(SANITIZER_GO)\nstatic void NoTsanAtomicStore(volatile a128 *a, a128 v, morder mo) {\n  SpinMutexLock lock(&mutex128);\n  *a = v;\n}\n#endif\n\ntemplate<typename T>\nstatic void AtomicStore(ThreadState *thr, uptr pc, volatile T *a, T v,\n    morder mo) {\n  CHECK(IsStoreOrder(mo));\n  MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog<T>());\n  // This fast-path is critical for performance.\n  // Assume the access is atomic.\n  // Strictly saying even relaxed store cuts off release sequence,\n  // so must reset the clock.\n  if (!IsReleaseOrder(mo)) {\n    NoTsanAtomicStore(a, v, mo);\n    return;\n  }\n  __sync_synchronize();\n  SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, (uptr)a, true);\n  thr->fast_state.IncrementEpoch();\n  // Can't increment epoch w/o writing to the trace as well.\n  TraceAddEvent(thr, thr->fast_state, EventTypeMop, 0);\n  ReleaseImpl(thr, pc, &s->clock);\n  NoTsanAtomicStore(a, v, mo);\n  s->mtx.Unlock();\n}\n\ntemplate<typename T, T (*F)(volatile T *v, T op)>\nstatic T AtomicRMW(ThreadState *thr, uptr pc, volatile T *a, T v, morder mo) {\n  MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog<T>());\n  SyncVar *s = 0;\n  if (mo != mo_relaxed) {\n    s = ctx->metamap.GetOrCreateAndLock(thr, pc, (uptr)a, true);\n    thr->fast_state.IncrementEpoch();\n    // Can't increment epoch w/o writing to the trace as well.\n    TraceAddEvent(thr, thr->fast_state, EventTypeMop, 0);\n    if (IsAcqRelOrder(mo))\n      AcquireReleaseImpl(thr, pc, &s->clock);\n    else if (IsReleaseOrder(mo))\n      ReleaseImpl(thr, pc, &s->clock);\n    else if (IsAcquireOrder(mo))\n      AcquireImpl(thr, pc, &s->clock);\n  }\n  v = F(a, v);\n  if (s)\n    s->mtx.Unlock();\n  return v;\n}\n\ntemplate<typename T>\nstatic T NoTsanAtomicExchange(volatile T *a, T v, morder mo) {\n  return func_xchg(a, v);\n}\n\ntemplate<typename T>\nstatic T NoTsanAtomicFetchAdd(volatile T *a, T v, morder mo) {\n  return func_add(a, v);\n}\n\ntemplate<typename T>\nstatic T NoTsanAtomicFetchSub(volatile T *a, T v, morder mo) {\n  return func_sub(a, v);\n}\n\ntemplate<typename T>\nstatic T NoTsanAtomicFetchAnd(volatile T *a, T v, morder mo) {\n  return func_and(a, v);\n}\n\ntemplate<typename T>\nstatic T NoTsanAtomicFetchOr(volatile T *a, T v, morder mo) {\n  return func_or(a, v);\n}\n\ntemplate<typename T>\nstatic T NoTsanAtomicFetchXor(volatile T *a, T v, morder mo) {\n  return func_xor(a, v);\n}\n\ntemplate<typename T>\nstatic T NoTsanAtomicFetchNand(volatile T *a, T v, morder mo) {\n  return func_nand(a, v);\n}\n\ntemplate<typename T>\nstatic T AtomicExchange(ThreadState *thr, uptr pc, volatile T *a, T v,\n    morder mo) {\n  return AtomicRMW<T, func_xchg>(thr, pc, a, v, mo);\n}\n\ntemplate<typename T>\nstatic T AtomicFetchAdd(ThreadState *thr, uptr pc, volatile T *a, T v,\n    morder mo) {\n  return AtomicRMW<T, func_add>(thr, pc, a, v, mo);\n}\n\ntemplate<typename T>\nstatic T AtomicFetchSub(ThreadState *thr, uptr pc, volatile T *a, T v,\n    morder mo) {\n  return AtomicRMW<T, func_sub>(thr, pc, a, v, mo);\n}\n\ntemplate<typename T>\nstatic T AtomicFetchAnd(ThreadState *thr, uptr pc, volatile T *a, T v,\n    morder mo) {\n  return AtomicRMW<T, func_and>(thr, pc, a, v, mo);\n}\n\ntemplate<typename T>\nstatic T AtomicFetchOr(ThreadState *thr, uptr pc, volatile T *a, T v,\n    morder mo) {\n  return AtomicRMW<T, func_or>(thr, pc, a, v, mo);\n}\n\ntemplate<typename T>\nstatic T AtomicFetchXor(ThreadState *thr, uptr pc, volatile T *a, T v,\n    morder mo) {\n  return AtomicRMW<T, func_xor>(thr, pc, a, v, mo);\n}\n\ntemplate<typename T>\nstatic T AtomicFetchNand(ThreadState *thr, uptr pc, volatile T *a, T v,\n    morder mo) {\n  return AtomicRMW<T, func_nand>(thr, pc, a, v, mo);\n}\n\ntemplate<typename T>\nstatic bool NoTsanAtomicCAS(volatile T *a, T *c, T v, morder mo, morder fmo) {\n  return atomic_compare_exchange_strong(to_atomic(a), c, v, to_mo(mo));\n}\n\n#if __TSAN_HAS_INT128\nstatic bool NoTsanAtomicCAS(volatile a128 *a, a128 *c, a128 v,\n    morder mo, morder fmo) {\n  a128 old = *c;\n  a128 cur = func_cas(a, old, v);\n  if (cur == old)\n    return true;\n  *c = cur;\n  return false;\n}\n#endif\n\ntemplate<typename T>\nstatic T NoTsanAtomicCAS(volatile T *a, T c, T v, morder mo, morder fmo) {\n  NoTsanAtomicCAS(a, &c, v, mo, fmo);\n  return c;\n}\n\ntemplate<typename T>\nstatic bool AtomicCAS(ThreadState *thr, uptr pc,\n    volatile T *a, T *c, T v, morder mo, morder fmo) {\n  (void)fmo;  // Unused because llvm does not pass it yet.\n  MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog<T>());\n  SyncVar *s = 0;\n  bool write_lock = mo != mo_acquire && mo != mo_consume;\n  if (mo != mo_relaxed) {\n    s = ctx->metamap.GetOrCreateAndLock(thr, pc, (uptr)a, write_lock);\n    thr->fast_state.IncrementEpoch();\n    // Can't increment epoch w/o writing to the trace as well.\n    TraceAddEvent(thr, thr->fast_state, EventTypeMop, 0);\n    if (IsAcqRelOrder(mo))\n      AcquireReleaseImpl(thr, pc, &s->clock);\n    else if (IsReleaseOrder(mo))\n      ReleaseImpl(thr, pc, &s->clock);\n    else if (IsAcquireOrder(mo))\n      AcquireImpl(thr, pc, &s->clock);\n  }\n  T cc = *c;\n  T pr = func_cas(a, cc, v);\n  if (s) {\n    if (write_lock)\n      s->mtx.Unlock();\n    else\n      s->mtx.ReadUnlock();\n  }\n  if (pr == cc)\n    return true;\n  *c = pr;\n  return false;\n}\n\ntemplate<typename T>\nstatic T AtomicCAS(ThreadState *thr, uptr pc,\n    volatile T *a, T c, T v, morder mo, morder fmo) {\n  AtomicCAS(thr, pc, a, &c, v, mo, fmo);\n  return c;\n}\n\n#ifndef SANITIZER_GO\nstatic void NoTsanAtomicFence(morder mo) {\n  __sync_synchronize();\n}\n\nstatic void AtomicFence(ThreadState *thr, uptr pc, morder mo) {\n  // FIXME(dvyukov): not implemented.\n  __sync_synchronize();\n}\n#endif\n\n// Interface functions follow.\n#ifndef SANITIZER_GO\n\n// C/C++\n\n#define SCOPED_ATOMIC(func, ...) \\\n    const uptr callpc = (uptr)__builtin_return_address(0); \\\n    uptr pc = StackTrace::GetCurrentPc(); \\\n    mo = flags()->force_seq_cst_atomics ? (morder)mo_seq_cst : mo; \\\n    ThreadState *const thr = cur_thread(); \\\n    if (thr->ignore_interceptors) \\\n      return NoTsanAtomic##func(__VA_ARGS__); \\\n    AtomicStatInc(thr, sizeof(*a), mo, StatAtomic##func); \\\n    ScopedAtomic sa(thr, callpc, a, mo, __func__); \\\n    return Atomic##func(thr, pc, __VA_ARGS__); \\\n/**/\n\nclass ScopedAtomic {\n public:\n  ScopedAtomic(ThreadState *thr, uptr pc, const volatile void *a,\n               morder mo, const char *func)\n      : thr_(thr) {\n    FuncEntry(thr_, pc);\n    DPrintf(\"#%d: %s(%p, %d)\\n\", thr_->tid, func, a, mo);\n  }\n  ~ScopedAtomic() {\n    ProcessPendingSignals(thr_);\n    FuncExit(thr_);\n  }\n private:\n  ThreadState *thr_;\n};\n\nstatic void AtomicStatInc(ThreadState *thr, uptr size, morder mo, StatType t) {\n  StatInc(thr, StatAtomic);\n  StatInc(thr, t);\n  StatInc(thr, size == 1 ? StatAtomic1\n             : size == 2 ? StatAtomic2\n             : size == 4 ? StatAtomic4\n             : size == 8 ? StatAtomic8\n             :             StatAtomic16);\n  StatInc(thr, mo == mo_relaxed ? StatAtomicRelaxed\n             : mo == mo_consume ? StatAtomicConsume\n             : mo == mo_acquire ? StatAtomicAcquire\n             : mo == mo_release ? StatAtomicRelease\n             : mo == mo_acq_rel ? StatAtomicAcq_Rel\n             :                    StatAtomicSeq_Cst);\n}\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE\na8 __tsan_atomic8_load(const volatile a8 *a, morder mo) {\n  SCOPED_ATOMIC(Load, a, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na16 __tsan_atomic16_load(const volatile a16 *a, morder mo) {\n  SCOPED_ATOMIC(Load, a, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na32 __tsan_atomic32_load(const volatile a32 *a, morder mo) {\n  SCOPED_ATOMIC(Load, a, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na64 __tsan_atomic64_load(const volatile a64 *a, morder mo) {\n  SCOPED_ATOMIC(Load, a, mo);\n}\n\n#if __TSAN_HAS_INT128\nSANITIZER_INTERFACE_ATTRIBUTE\na128 __tsan_atomic128_load(const volatile a128 *a, morder mo) {\n  SCOPED_ATOMIC(Load, a, mo);\n}\n#endif\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_atomic8_store(volatile a8 *a, a8 v, morder mo) {\n  SCOPED_ATOMIC(Store, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_atomic16_store(volatile a16 *a, a16 v, morder mo) {\n  SCOPED_ATOMIC(Store, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_atomic32_store(volatile a32 *a, a32 v, morder mo) {\n  SCOPED_ATOMIC(Store, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_atomic64_store(volatile a64 *a, a64 v, morder mo) {\n  SCOPED_ATOMIC(Store, a, v, mo);\n}\n\n#if __TSAN_HAS_INT128\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_atomic128_store(volatile a128 *a, a128 v, morder mo) {\n  SCOPED_ATOMIC(Store, a, v, mo);\n}\n#endif\n\nSANITIZER_INTERFACE_ATTRIBUTE\na8 __tsan_atomic8_exchange(volatile a8 *a, a8 v, morder mo) {\n  SCOPED_ATOMIC(Exchange, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na16 __tsan_atomic16_exchange(volatile a16 *a, a16 v, morder mo) {\n  SCOPED_ATOMIC(Exchange, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na32 __tsan_atomic32_exchange(volatile a32 *a, a32 v, morder mo) {\n  SCOPED_ATOMIC(Exchange, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na64 __tsan_atomic64_exchange(volatile a64 *a, a64 v, morder mo) {\n  SCOPED_ATOMIC(Exchange, a, v, mo);\n}\n\n#if __TSAN_HAS_INT128\nSANITIZER_INTERFACE_ATTRIBUTE\na128 __tsan_atomic128_exchange(volatile a128 *a, a128 v, morder mo) {\n  SCOPED_ATOMIC(Exchange, a, v, mo);\n}\n#endif\n\nSANITIZER_INTERFACE_ATTRIBUTE\na8 __tsan_atomic8_fetch_add(volatile a8 *a, a8 v, morder mo) {\n  SCOPED_ATOMIC(FetchAdd, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na16 __tsan_atomic16_fetch_add(volatile a16 *a, a16 v, morder mo) {\n  SCOPED_ATOMIC(FetchAdd, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na32 __tsan_atomic32_fetch_add(volatile a32 *a, a32 v, morder mo) {\n  SCOPED_ATOMIC(FetchAdd, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na64 __tsan_atomic64_fetch_add(volatile a64 *a, a64 v, morder mo) {\n  SCOPED_ATOMIC(FetchAdd, a, v, mo);\n}\n\n#if __TSAN_HAS_INT128\nSANITIZER_INTERFACE_ATTRIBUTE\na128 __tsan_atomic128_fetch_add(volatile a128 *a, a128 v, morder mo) {\n  SCOPED_ATOMIC(FetchAdd, a, v, mo);\n}\n#endif\n\nSANITIZER_INTERFACE_ATTRIBUTE\na8 __tsan_atomic8_fetch_sub(volatile a8 *a, a8 v, morder mo) {\n  SCOPED_ATOMIC(FetchSub, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na16 __tsan_atomic16_fetch_sub(volatile a16 *a, a16 v, morder mo) {\n  SCOPED_ATOMIC(FetchSub, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na32 __tsan_atomic32_fetch_sub(volatile a32 *a, a32 v, morder mo) {\n  SCOPED_ATOMIC(FetchSub, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na64 __tsan_atomic64_fetch_sub(volatile a64 *a, a64 v, morder mo) {\n  SCOPED_ATOMIC(FetchSub, a, v, mo);\n}\n\n#if __TSAN_HAS_INT128\nSANITIZER_INTERFACE_ATTRIBUTE\na128 __tsan_atomic128_fetch_sub(volatile a128 *a, a128 v, morder mo) {\n  SCOPED_ATOMIC(FetchSub, a, v, mo);\n}\n#endif\n\nSANITIZER_INTERFACE_ATTRIBUTE\na8 __tsan_atomic8_fetch_and(volatile a8 *a, a8 v, morder mo) {\n  SCOPED_ATOMIC(FetchAnd, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na16 __tsan_atomic16_fetch_and(volatile a16 *a, a16 v, morder mo) {\n  SCOPED_ATOMIC(FetchAnd, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na32 __tsan_atomic32_fetch_and(volatile a32 *a, a32 v, morder mo) {\n  SCOPED_ATOMIC(FetchAnd, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na64 __tsan_atomic64_fetch_and(volatile a64 *a, a64 v, morder mo) {\n  SCOPED_ATOMIC(FetchAnd, a, v, mo);\n}\n\n#if __TSAN_HAS_INT128\nSANITIZER_INTERFACE_ATTRIBUTE\na128 __tsan_atomic128_fetch_and(volatile a128 *a, a128 v, morder mo) {\n  SCOPED_ATOMIC(FetchAnd, a, v, mo);\n}\n#endif\n\nSANITIZER_INTERFACE_ATTRIBUTE\na8 __tsan_atomic8_fetch_or(volatile a8 *a, a8 v, morder mo) {\n  SCOPED_ATOMIC(FetchOr, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na16 __tsan_atomic16_fetch_or(volatile a16 *a, a16 v, morder mo) {\n  SCOPED_ATOMIC(FetchOr, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na32 __tsan_atomic32_fetch_or(volatile a32 *a, a32 v, morder mo) {\n  SCOPED_ATOMIC(FetchOr, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na64 __tsan_atomic64_fetch_or(volatile a64 *a, a64 v, morder mo) {\n  SCOPED_ATOMIC(FetchOr, a, v, mo);\n}\n\n#if __TSAN_HAS_INT128\nSANITIZER_INTERFACE_ATTRIBUTE\na128 __tsan_atomic128_fetch_or(volatile a128 *a, a128 v, morder mo) {\n  SCOPED_ATOMIC(FetchOr, a, v, mo);\n}\n#endif\n\nSANITIZER_INTERFACE_ATTRIBUTE\na8 __tsan_atomic8_fetch_xor(volatile a8 *a, a8 v, morder mo) {\n  SCOPED_ATOMIC(FetchXor, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na16 __tsan_atomic16_fetch_xor(volatile a16 *a, a16 v, morder mo) {\n  SCOPED_ATOMIC(FetchXor, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na32 __tsan_atomic32_fetch_xor(volatile a32 *a, a32 v, morder mo) {\n  SCOPED_ATOMIC(FetchXor, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na64 __tsan_atomic64_fetch_xor(volatile a64 *a, a64 v, morder mo) {\n  SCOPED_ATOMIC(FetchXor, a, v, mo);\n}\n\n#if __TSAN_HAS_INT128\nSANITIZER_INTERFACE_ATTRIBUTE\na128 __tsan_atomic128_fetch_xor(volatile a128 *a, a128 v, morder mo) {\n  SCOPED_ATOMIC(FetchXor, a, v, mo);\n}\n#endif\n\nSANITIZER_INTERFACE_ATTRIBUTE\na8 __tsan_atomic8_fetch_nand(volatile a8 *a, a8 v, morder mo) {\n  SCOPED_ATOMIC(FetchNand, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na16 __tsan_atomic16_fetch_nand(volatile a16 *a, a16 v, morder mo) {\n  SCOPED_ATOMIC(FetchNand, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na32 __tsan_atomic32_fetch_nand(volatile a32 *a, a32 v, morder mo) {\n  SCOPED_ATOMIC(FetchNand, a, v, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na64 __tsan_atomic64_fetch_nand(volatile a64 *a, a64 v, morder mo) {\n  SCOPED_ATOMIC(FetchNand, a, v, mo);\n}\n\n#if __TSAN_HAS_INT128\nSANITIZER_INTERFACE_ATTRIBUTE\na128 __tsan_atomic128_fetch_nand(volatile a128 *a, a128 v, morder mo) {\n  SCOPED_ATOMIC(FetchNand, a, v, mo);\n}\n#endif\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __tsan_atomic8_compare_exchange_strong(volatile a8 *a, a8 *c, a8 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __tsan_atomic16_compare_exchange_strong(volatile a16 *a, a16 *c, a16 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __tsan_atomic32_compare_exchange_strong(volatile a32 *a, a32 *c, a32 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __tsan_atomic64_compare_exchange_strong(volatile a64 *a, a64 *c, a64 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n\n#if __TSAN_HAS_INT128\nSANITIZER_INTERFACE_ATTRIBUTE\nint __tsan_atomic128_compare_exchange_strong(volatile a128 *a, a128 *c, a128 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n#endif\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __tsan_atomic8_compare_exchange_weak(volatile a8 *a, a8 *c, a8 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __tsan_atomic16_compare_exchange_weak(volatile a16 *a, a16 *c, a16 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __tsan_atomic32_compare_exchange_weak(volatile a32 *a, a32 *c, a32 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nint __tsan_atomic64_compare_exchange_weak(volatile a64 *a, a64 *c, a64 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n\n#if __TSAN_HAS_INT128\nSANITIZER_INTERFACE_ATTRIBUTE\nint __tsan_atomic128_compare_exchange_weak(volatile a128 *a, a128 *c, a128 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n#endif\n\nSANITIZER_INTERFACE_ATTRIBUTE\na8 __tsan_atomic8_compare_exchange_val(volatile a8 *a, a8 c, a8 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na16 __tsan_atomic16_compare_exchange_val(volatile a16 *a, a16 c, a16 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na32 __tsan_atomic32_compare_exchange_val(volatile a32 *a, a32 c, a32 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\na64 __tsan_atomic64_compare_exchange_val(volatile a64 *a, a64 c, a64 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n\n#if __TSAN_HAS_INT128\nSANITIZER_INTERFACE_ATTRIBUTE\na128 __tsan_atomic128_compare_exchange_val(volatile a128 *a, a128 c, a128 v,\n    morder mo, morder fmo) {\n  SCOPED_ATOMIC(CAS, a, c, v, mo, fmo);\n}\n#endif\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_atomic_thread_fence(morder mo) {\n  char* a = 0;\n  SCOPED_ATOMIC(Fence, mo);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_atomic_signal_fence(morder mo) {\n}\n}  // extern \"C\"\n\n#else  // #ifndef SANITIZER_GO\n\n// Go\n\n#define ATOMIC(func, ...) \\\n    if (thr->ignore_sync) { \\\n      NoTsanAtomic##func(__VA_ARGS__); \\\n    } else { \\\n      FuncEntry(thr, cpc); \\\n      Atomic##func(thr, pc, __VA_ARGS__); \\\n      FuncExit(thr); \\\n    } \\\n/**/\n\n#define ATOMIC_RET(func, ret, ...) \\\n    if (thr->ignore_sync) { \\\n      (ret) = NoTsanAtomic##func(__VA_ARGS__); \\\n    } else { \\\n      FuncEntry(thr, cpc); \\\n      (ret) = Atomic##func(thr, pc, __VA_ARGS__); \\\n      FuncExit(thr); \\\n    } \\\n/**/\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_go_atomic32_load(ThreadState *thr, uptr cpc, uptr pc, u8 *a) {\n  ATOMIC_RET(Load, *(a32*)(a+8), *(a32**)a, mo_acquire);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_go_atomic64_load(ThreadState *thr, uptr cpc, uptr pc, u8 *a) {\n  ATOMIC_RET(Load, *(a64*)(a+8), *(a64**)a, mo_acquire);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_go_atomic32_store(ThreadState *thr, uptr cpc, uptr pc, u8 *a) {\n  ATOMIC(Store, *(a32**)a, *(a32*)(a+8), mo_release);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_go_atomic64_store(ThreadState *thr, uptr cpc, uptr pc, u8 *a) {\n  ATOMIC(Store, *(a64**)a, *(a64*)(a+8), mo_release);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_go_atomic32_fetch_add(ThreadState *thr, uptr cpc, uptr pc, u8 *a) {\n  ATOMIC_RET(FetchAdd, *(a32*)(a+16), *(a32**)a, *(a32*)(a+8), mo_acq_rel);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_go_atomic64_fetch_add(ThreadState *thr, uptr cpc, uptr pc, u8 *a) {\n  ATOMIC_RET(FetchAdd, *(a64*)(a+16), *(a64**)a, *(a64*)(a+8), mo_acq_rel);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_go_atomic32_exchange(ThreadState *thr, uptr cpc, uptr pc, u8 *a) {\n  ATOMIC_RET(Exchange, *(a32*)(a+16), *(a32**)a, *(a32*)(a+8), mo_acq_rel);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_go_atomic64_exchange(ThreadState *thr, uptr cpc, uptr pc, u8 *a) {\n  ATOMIC_RET(Exchange, *(a64*)(a+16), *(a64**)a, *(a64*)(a+8), mo_acq_rel);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_go_atomic32_compare_exchange(\n    ThreadState *thr, uptr cpc, uptr pc, u8 *a) {\n  a32 cur = 0;\n  a32 cmp = *(a32*)(a+8);\n  ATOMIC_RET(CAS, cur, *(a32**)a, cmp, *(a32*)(a+12), mo_acq_rel, mo_acquire);\n  *(bool*)(a+16) = (cur == cmp);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __tsan_go_atomic64_compare_exchange(\n    ThreadState *thr, uptr cpc, uptr pc, u8 *a) {\n  a64 cur = 0;\n  a64 cmp = *(a64*)(a+8);\n  ATOMIC_RET(CAS, cur, *(a64**)a, cmp, *(a64*)(a+16), mo_acq_rel, mo_acquire);\n  *(bool*)(a+24) = (cur == cmp);\n}\n}  // extern \"C\"\n#endif  // #ifndef SANITIZER_GO\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_interface_inl.h",
    "content": "//===-- tsan_interface_inl.h ------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"tsan_interface.h\"\n#include \"tsan_rtl.h\"\n\n#define CALLERPC ((uptr)__builtin_return_address(0))\n\nusing namespace __tsan;  // NOLINT\n\nvoid __tsan_read1(void *addr) {\n  MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog1);\n}\n\nvoid __tsan_read2(void *addr) {\n  MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog2);\n}\n\nvoid __tsan_read4(void *addr) {\n  MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog4);\n}\n\nvoid __tsan_read8(void *addr) {\n  MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8);\n}\n\nvoid __tsan_write1(void *addr) {\n  MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog1);\n}\n\nvoid __tsan_write2(void *addr) {\n  MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog2);\n}\n\nvoid __tsan_write4(void *addr) {\n  MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog4);\n}\n\nvoid __tsan_write8(void *addr) {\n  MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8);\n}\n\nvoid __tsan_read1_pc(void *addr, void *pc) {\n  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog1);\n}\n\nvoid __tsan_read2_pc(void *addr, void *pc) {\n  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog2);\n}\n\nvoid __tsan_read4_pc(void *addr, void *pc) {\n  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog4);\n}\n\nvoid __tsan_read8_pc(void *addr, void *pc) {\n  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);\n}\n\nvoid __tsan_write1_pc(void *addr, void *pc) {\n  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog1);\n}\n\nvoid __tsan_write2_pc(void *addr, void *pc) {\n  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog2);\n}\n\nvoid __tsan_write4_pc(void *addr, void *pc) {\n  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog4);\n}\n\nvoid __tsan_write8_pc(void *addr, void *pc) {\n  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);\n}\n\nvoid __tsan_vptr_update(void **vptr_p, void *new_val) {\n  CHECK_EQ(sizeof(vptr_p), 8);\n  if (*vptr_p != new_val) {\n    ThreadState *thr = cur_thread();\n    thr->is_vptr_access = true;\n    MemoryWrite(thr, CALLERPC, (uptr)vptr_p, kSizeLog8);\n    thr->is_vptr_access = false;\n  }\n}\n\nvoid __tsan_vptr_read(void **vptr_p) {\n  CHECK_EQ(sizeof(vptr_p), 8);\n  ThreadState *thr = cur_thread();\n  thr->is_vptr_access = true;\n  MemoryRead(thr, CALLERPC, (uptr)vptr_p, kSizeLog8);\n  thr->is_vptr_access = false;\n}\n\nvoid __tsan_func_entry(void *pc) {\n  FuncEntry(cur_thread(), (uptr)pc);\n}\n\nvoid __tsan_func_exit() {\n  FuncExit(cur_thread());\n}\n\nvoid __tsan_read_range(void *addr, uptr size) {\n  MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, false);\n}\n\nvoid __tsan_write_range(void *addr, uptr size) {\n  MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, true);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_interface_java.cc",
    "content": "//===-- tsan_interface_java.cc --------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"tsan_interface_java.h\"\n#include \"tsan_rtl.h\"\n#include \"tsan_mutex.h\"\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"sanitizer_common/sanitizer_procmaps.h\"\n\nusing namespace __tsan;  // NOLINT\n\nconst jptr kHeapAlignment = 8;\n\nnamespace __tsan {\n\nstruct JavaContext {\n  const uptr heap_begin;\n  const uptr heap_size;\n\n  JavaContext(jptr heap_begin, jptr heap_size)\n      : heap_begin(heap_begin)\n      , heap_size(heap_size) {\n  }\n};\n\nclass ScopedJavaFunc {\n public:\n  ScopedJavaFunc(ThreadState *thr, uptr pc)\n      : thr_(thr) {\n    Initialize(thr_);\n    FuncEntry(thr, pc);\n  }\n\n  ~ScopedJavaFunc() {\n    FuncExit(thr_);\n    // FIXME(dvyukov): process pending signals.\n  }\n\n private:\n  ThreadState *thr_;\n};\n\nstatic u64 jctx_buf[sizeof(JavaContext) / sizeof(u64) + 1];\nstatic JavaContext *jctx;\n\n}  // namespace __tsan\n\n#define SCOPED_JAVA_FUNC(func) \\\n  ThreadState *thr = cur_thread(); \\\n  const uptr caller_pc = GET_CALLER_PC(); \\\n  const uptr pc = StackTrace::GetCurrentPc(); \\\n  (void)pc; \\\n  ScopedJavaFunc scoped(thr, caller_pc); \\\n/**/\n\nvoid __tsan_java_init(jptr heap_begin, jptr heap_size) {\n  SCOPED_JAVA_FUNC(__tsan_java_init);\n  DPrintf(\"#%d: java_init(%p, %p)\\n\", thr->tid, heap_begin, heap_size);\n  CHECK_EQ(jctx, 0);\n  CHECK_GT(heap_begin, 0);\n  CHECK_GT(heap_size, 0);\n  CHECK_EQ(heap_begin % kHeapAlignment, 0);\n  CHECK_EQ(heap_size % kHeapAlignment, 0);\n  CHECK_LT(heap_begin, heap_begin + heap_size);\n  jctx = new(jctx_buf) JavaContext(heap_begin, heap_size);\n}\n\nint  __tsan_java_fini() {\n  SCOPED_JAVA_FUNC(__tsan_java_fini);\n  DPrintf(\"#%d: java_fini()\\n\", thr->tid);\n  CHECK_NE(jctx, 0);\n  // FIXME(dvyukov): this does not call atexit() callbacks.\n  int status = Finalize(thr);\n  DPrintf(\"#%d: java_fini() = %d\\n\", thr->tid, status);\n  return status;\n}\n\nvoid __tsan_java_alloc(jptr ptr, jptr size) {\n  SCOPED_JAVA_FUNC(__tsan_java_alloc);\n  DPrintf(\"#%d: java_alloc(%p, %p)\\n\", thr->tid, ptr, size);\n  CHECK_NE(jctx, 0);\n  CHECK_NE(size, 0);\n  CHECK_EQ(ptr % kHeapAlignment, 0);\n  CHECK_EQ(size % kHeapAlignment, 0);\n  CHECK_GE(ptr, jctx->heap_begin);\n  CHECK_LE(ptr + size, jctx->heap_begin + jctx->heap_size);\n\n  OnUserAlloc(thr, pc, ptr, size, false);\n}\n\nvoid __tsan_java_free(jptr ptr, jptr size) {\n  SCOPED_JAVA_FUNC(__tsan_java_free);\n  DPrintf(\"#%d: java_free(%p, %p)\\n\", thr->tid, ptr, size);\n  CHECK_NE(jctx, 0);\n  CHECK_NE(size, 0);\n  CHECK_EQ(ptr % kHeapAlignment, 0);\n  CHECK_EQ(size % kHeapAlignment, 0);\n  CHECK_GE(ptr, jctx->heap_begin);\n  CHECK_LE(ptr + size, jctx->heap_begin + jctx->heap_size);\n\n  ctx->metamap.FreeRange(thr, pc, ptr, size);\n}\n\nvoid __tsan_java_move(jptr src, jptr dst, jptr size) {\n  SCOPED_JAVA_FUNC(__tsan_java_move);\n  DPrintf(\"#%d: java_move(%p, %p, %p)\\n\", thr->tid, src, dst, size);\n  CHECK_NE(jctx, 0);\n  CHECK_NE(size, 0);\n  CHECK_EQ(src % kHeapAlignment, 0);\n  CHECK_EQ(dst % kHeapAlignment, 0);\n  CHECK_EQ(size % kHeapAlignment, 0);\n  CHECK_GE(src, jctx->heap_begin);\n  CHECK_LE(src + size, jctx->heap_begin + jctx->heap_size);\n  CHECK_GE(dst, jctx->heap_begin);\n  CHECK_LE(dst + size, jctx->heap_begin + jctx->heap_size);\n  CHECK_NE(dst, src);\n  CHECK_NE(size, 0);\n\n  // Assuming it's not running concurrently with threads that do\n  // memory accesses and mutex operations (stop-the-world phase).\n  ctx->metamap.MoveMemory(src, dst, size);\n\n  // Move shadow.\n  u64 *s = (u64*)MemToShadow(src);\n  u64 *d = (u64*)MemToShadow(dst);\n  u64 *send = (u64*)MemToShadow(src + size);\n  uptr inc = 1;\n  if (dst > src) {\n    s = (u64*)MemToShadow(src + size) - 1;\n    d = (u64*)MemToShadow(dst + size) - 1;\n    send = (u64*)MemToShadow(src) - 1;\n    inc = -1;\n  }\n  for (; s != send; s += inc, d += inc) {\n    *d = *s;\n    *s = 0;\n  }\n}\n\nvoid __tsan_java_finalize() {\n  SCOPED_JAVA_FUNC(__tsan_java_finalize);\n  DPrintf(\"#%d: java_mutex_finalize()\\n\", thr->tid);\n  AcquireGlobal(thr, 0);\n}\n\nvoid __tsan_java_mutex_lock(jptr addr) {\n  SCOPED_JAVA_FUNC(__tsan_java_mutex_lock);\n  DPrintf(\"#%d: java_mutex_lock(%p)\\n\", thr->tid, addr);\n  CHECK_NE(jctx, 0);\n  CHECK_GE(addr, jctx->heap_begin);\n  CHECK_LT(addr, jctx->heap_begin + jctx->heap_size);\n\n  MutexCreate(thr, pc, addr, true, true, true);\n  MutexLock(thr, pc, addr);\n}\n\nvoid __tsan_java_mutex_unlock(jptr addr) {\n  SCOPED_JAVA_FUNC(__tsan_java_mutex_unlock);\n  DPrintf(\"#%d: java_mutex_unlock(%p)\\n\", thr->tid, addr);\n  CHECK_NE(jctx, 0);\n  CHECK_GE(addr, jctx->heap_begin);\n  CHECK_LT(addr, jctx->heap_begin + jctx->heap_size);\n\n  MutexUnlock(thr, pc, addr);\n}\n\nvoid __tsan_java_mutex_read_lock(jptr addr) {\n  SCOPED_JAVA_FUNC(__tsan_java_mutex_read_lock);\n  DPrintf(\"#%d: java_mutex_read_lock(%p)\\n\", thr->tid, addr);\n  CHECK_NE(jctx, 0);\n  CHECK_GE(addr, jctx->heap_begin);\n  CHECK_LT(addr, jctx->heap_begin + jctx->heap_size);\n\n  MutexCreate(thr, pc, addr, true, true, true);\n  MutexReadLock(thr, pc, addr);\n}\n\nvoid __tsan_java_mutex_read_unlock(jptr addr) {\n  SCOPED_JAVA_FUNC(__tsan_java_mutex_read_unlock);\n  DPrintf(\"#%d: java_mutex_read_unlock(%p)\\n\", thr->tid, addr);\n  CHECK_NE(jctx, 0);\n  CHECK_GE(addr, jctx->heap_begin);\n  CHECK_LT(addr, jctx->heap_begin + jctx->heap_size);\n\n  MutexReadUnlock(thr, pc, addr);\n}\n\nvoid __tsan_java_mutex_lock_rec(jptr addr, int rec) {\n  SCOPED_JAVA_FUNC(__tsan_java_mutex_lock_rec);\n  DPrintf(\"#%d: java_mutex_lock_rec(%p, %d)\\n\", thr->tid, addr, rec);\n  CHECK_NE(jctx, 0);\n  CHECK_GE(addr, jctx->heap_begin);\n  CHECK_LT(addr, jctx->heap_begin + jctx->heap_size);\n  CHECK_GT(rec, 0);\n\n  MutexCreate(thr, pc, addr, true, true, true);\n  MutexLock(thr, pc, addr, rec);\n}\n\nint __tsan_java_mutex_unlock_rec(jptr addr) {\n  SCOPED_JAVA_FUNC(__tsan_java_mutex_unlock_rec);\n  DPrintf(\"#%d: java_mutex_unlock_rec(%p)\\n\", thr->tid, addr);\n  CHECK_NE(jctx, 0);\n  CHECK_GE(addr, jctx->heap_begin);\n  CHECK_LT(addr, jctx->heap_begin + jctx->heap_size);\n\n  return MutexUnlock(thr, pc, addr, true);\n}\n\nvoid __tsan_java_acquire(jptr addr) {\n  SCOPED_JAVA_FUNC(__tsan_java_acquire);\n  DPrintf(\"#%d: java_acquire(%p)\\n\", thr->tid, addr);\n  CHECK_NE(jctx, 0);\n  CHECK_GE(addr, jctx->heap_begin);\n  CHECK_LT(addr, jctx->heap_begin + jctx->heap_size);\n\n  Acquire(thr, caller_pc, addr);\n}\n\nvoid __tsan_java_release(jptr addr) {\n  SCOPED_JAVA_FUNC(__tsan_java_release);\n  DPrintf(\"#%d: java_release(%p)\\n\", thr->tid, addr);\n  CHECK_NE(jctx, 0);\n  CHECK_GE(addr, jctx->heap_begin);\n  CHECK_LT(addr, jctx->heap_begin + jctx->heap_size);\n\n  Release(thr, caller_pc, addr);\n}\n\nvoid __tsan_java_release_store(jptr addr) {\n  SCOPED_JAVA_FUNC(__tsan_java_release);\n  DPrintf(\"#%d: java_release_store(%p)\\n\", thr->tid, addr);\n  CHECK_NE(jctx, 0);\n  CHECK_GE(addr, jctx->heap_begin);\n  CHECK_LT(addr, jctx->heap_begin + jctx->heap_size);\n\n  ReleaseStore(thr, caller_pc, addr);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_interface_java.h",
    "content": "//===-- tsan_interface_java.h -----------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Interface for verification of Java or mixed Java/C++ programs.\n// The interface is intended to be used from within a JVM and notify TSan\n// about such events like Java locks and GC memory compaction.\n//\n// For plain memory accesses and function entry/exit a JVM is intended to use\n// C++ interfaces: __tsan_readN/writeN and __tsan_func_enter/exit.\n//\n// For volatile memory accesses and atomic operations JVM is intended to use\n// standard atomics API: __tsan_atomicN_load/store/etc.\n//\n// For usage examples see lit_tests/java_*.cc\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_INTERFACE_JAVA_H\n#define TSAN_INTERFACE_JAVA_H\n\n#ifndef INTERFACE_ATTRIBUTE\n# define INTERFACE_ATTRIBUTE __attribute__((visibility(\"default\")))\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef unsigned long jptr;  // NOLINT\n\n// Must be called before any other callback from Java.\nvoid __tsan_java_init(jptr heap_begin, jptr heap_size) INTERFACE_ATTRIBUTE;\n// Must be called when the application exits.\n// Not necessary the last callback (concurrently running threads are OK).\n// Returns exit status or 0 if tsan does not want to override it.\nint  __tsan_java_fini() INTERFACE_ATTRIBUTE;\n\n// Callback for memory allocations.\n// May be omitted for allocations that are not subject to data races\n// nor contain synchronization objects (e.g. String).\nvoid __tsan_java_alloc(jptr ptr, jptr size) INTERFACE_ATTRIBUTE;\n// Callback for memory free.\n// Can be aggregated for several objects (preferably).\nvoid __tsan_java_free(jptr ptr, jptr size) INTERFACE_ATTRIBUTE;\n// Callback for memory move by GC.\n// Can be aggregated for several objects (preferably).\n// The ranges can overlap.\nvoid __tsan_java_move(jptr src, jptr dst, jptr size) INTERFACE_ATTRIBUTE;\n// This function must be called on the finalizer thread\n// before executing a batch of finalizers.\n// It ensures necessary synchronization between\n// java object creation and finalization.\nvoid __tsan_java_finalize() INTERFACE_ATTRIBUTE;\n\n// Mutex lock.\n// Addr is any unique address associated with the mutex.\n// Can be called on recursive reentry.\nvoid __tsan_java_mutex_lock(jptr addr) INTERFACE_ATTRIBUTE;\n// Mutex unlock.\nvoid __tsan_java_mutex_unlock(jptr addr) INTERFACE_ATTRIBUTE;\n// Mutex read lock.\nvoid __tsan_java_mutex_read_lock(jptr addr) INTERFACE_ATTRIBUTE;\n// Mutex read unlock.\nvoid __tsan_java_mutex_read_unlock(jptr addr) INTERFACE_ATTRIBUTE;\n// Recursive mutex lock, intended for handling of Object.wait().\n// The 'rec' value must be obtained from the previous\n// __tsan_java_mutex_unlock_rec().\nvoid __tsan_java_mutex_lock_rec(jptr addr, int rec) INTERFACE_ATTRIBUTE;\n// Recursive mutex unlock, intended for handling of Object.wait().\n// The return value says how many times this thread called lock()\n// w/o a pairing unlock() (i.e. how many recursive levels it unlocked).\n// It must be passed back to __tsan_java_mutex_lock_rec() to restore\n// the same recursion level.\nint __tsan_java_mutex_unlock_rec(jptr addr) INTERFACE_ATTRIBUTE;\n\n// Raw acquire/release primitives.\n// Can be used to establish happens-before edges on volatile/final fields,\n// in atomic operations, etc. release_store is the same as release, but it\n// breaks release sequence on addr (see C++ standard 1.10/7 for details).\nvoid __tsan_java_acquire(jptr addr) INTERFACE_ATTRIBUTE;\nvoid __tsan_java_release(jptr addr) INTERFACE_ATTRIBUTE;\nvoid __tsan_java_release_store(jptr addr) INTERFACE_ATTRIBUTE;\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#undef INTERFACE_ATTRIBUTE\n\n#endif  // #ifndef TSAN_INTERFACE_JAVA_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_libdispatch_mac.cc",
    "content": "//===-- tsan_libdispatch_mac.cc -------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Mac-specific libdispatch (GCD) support.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_MAC\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"interception/interception.h\"\n#include \"tsan_interceptors.h\"\n#include \"tsan_platform.h\"\n#include \"tsan_rtl.h\"\n\n#include <Block.h>\n#include <dispatch/dispatch.h>\n#include <pthread.h>\n\ntypedef long long_t;  // NOLINT\n\nnamespace __tsan {\n\ntypedef struct {\n  dispatch_queue_t queue;\n  void *orig_context;\n  dispatch_function_t orig_work;\n  uptr object_to_acquire;\n  dispatch_object_t object_to_release;\n} tsan_block_context_t;\n\n// The offsets of different fields of the dispatch_queue_t structure, exported\n// by libdispatch.dylib.\nextern \"C\" struct dispatch_queue_offsets_s {\n  const uint16_t dqo_version;\n  const uint16_t dqo_label;\n  const uint16_t dqo_label_size;\n  const uint16_t dqo_flags;\n  const uint16_t dqo_flags_size;\n  const uint16_t dqo_serialnum;\n  const uint16_t dqo_serialnum_size;\n  const uint16_t dqo_width;\n  const uint16_t dqo_width_size;\n  const uint16_t dqo_running;\n  const uint16_t dqo_running_size;\n  const uint16_t dqo_suspend_cnt;\n  const uint16_t dqo_suspend_cnt_size;\n  const uint16_t dqo_target_queue;\n  const uint16_t dqo_target_queue_size;\n  const uint16_t dqo_priority;\n  const uint16_t dqo_priority_size;\n} dispatch_queue_offsets;\n\nstatic bool IsQueueSerial(dispatch_queue_t q) {\n  CHECK_EQ(dispatch_queue_offsets.dqo_width_size, 2);\n  uptr width = *(uint16_t *)(((uptr)q) + dispatch_queue_offsets.dqo_width);\n  CHECK_NE(width, 0);\n  return width == 1;\n}\n\nstatic tsan_block_context_t *AllocContext(ThreadState *thr, uptr pc,\n                                          dispatch_queue_t queue,\n                                          void *orig_context,\n                                          dispatch_function_t orig_work) {\n  tsan_block_context_t *new_context =\n      (tsan_block_context_t *)user_alloc(thr, pc, sizeof(tsan_block_context_t));\n  new_context->queue = queue;\n  new_context->orig_context = orig_context;\n  new_context->orig_work = orig_work;\n  new_context->object_to_acquire = (uptr)new_context;\n  new_context->object_to_release = nullptr;\n  return new_context;\n}\n\nstatic void dispatch_callback_wrap_acquire(void *param) {\n  SCOPED_INTERCEPTOR_RAW(dispatch_async_f_callback_wrap);\n  tsan_block_context_t *context = (tsan_block_context_t *)param;\n  Acquire(thr, pc, context->object_to_acquire);\n\n  // Extra retain/release is required for dispatch groups. We use the group\n  // itself to synchronize, but in a notification (dispatch_group_notify\n  // callback), it may be disposed already. To solve this, we retain the group\n  // and release it here.\n  if (context->object_to_release) dispatch_release(context->object_to_release);\n\n  // In serial queues, work items can be executed on different threads, we need\n  // to explicitly synchronize on the queue itself.\n  if (IsQueueSerial(context->queue)) Acquire(thr, pc, (uptr)context->queue);\n  SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();\n  context->orig_work(context->orig_context);\n  SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();\n  if (IsQueueSerial(context->queue)) Release(thr, pc, (uptr)context->queue);\n  user_free(thr, pc, context);\n}\n\nstatic void invoke_and_release_block(void *param) {\n  dispatch_block_t block = (dispatch_block_t)param;\n  block();\n  Block_release(block);\n}\n\n#define DISPATCH_INTERCEPT_B(name)                                           \\\n  TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, dispatch_block_t block) { \\\n    SCOPED_TSAN_INTERCEPTOR(name, q, block);                                 \\\n    SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \\\n    dispatch_block_t heap_block = Block_copy(block);                         \\\n    SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); \\\n    tsan_block_context_t *new_context =                                      \\\n        AllocContext(thr, pc, q, heap_block, &invoke_and_release_block);     \\\n    Release(thr, pc, (uptr)new_context);                                     \\\n    SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \\\n    REAL(name##_f)(q, new_context, dispatch_callback_wrap_acquire);          \\\n    SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); \\\n  }\n\n#define DISPATCH_INTERCEPT_F(name)                                \\\n  TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, void *context, \\\n                   dispatch_function_t work) {                    \\\n    SCOPED_TSAN_INTERCEPTOR(name, q, context, work);              \\\n    tsan_block_context_t *new_context =                           \\\n        AllocContext(thr, pc, q, context, work);                  \\\n    Release(thr, pc, (uptr)new_context);                          \\\n    SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \\\n    REAL(name)(q, new_context, dispatch_callback_wrap_acquire);   \\\n    SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); \\\n  }\n\n// We wrap dispatch_async, dispatch_sync and friends where we allocate a new\n// context, which is used to synchronize (we release the context before\n// submitting, and the callback acquires it before executing the original\n// callback).\nDISPATCH_INTERCEPT_B(dispatch_async)\nDISPATCH_INTERCEPT_B(dispatch_barrier_async)\nDISPATCH_INTERCEPT_F(dispatch_async_f)\nDISPATCH_INTERCEPT_F(dispatch_barrier_async_f)\nDISPATCH_INTERCEPT_B(dispatch_sync)\nDISPATCH_INTERCEPT_B(dispatch_barrier_sync)\nDISPATCH_INTERCEPT_F(dispatch_sync_f)\nDISPATCH_INTERCEPT_F(dispatch_barrier_sync_f)\n\n// GCD's dispatch_once implementation has a fast path that contains a racy read\n// and it's inlined into user's code. Furthermore, this fast path doesn't\n// establish a proper happens-before relations between the initialization and\n// code following the call to dispatch_once. We could deal with this in\n// instrumented code, but there's not much we can do about it in system\n// libraries. Let's disable the fast path (by never storing the value ~0 to\n// predicate), so the interceptor is always called, and let's add proper release\n// and acquire semantics. Since TSan does not see its own atomic stores, the\n// race on predicate won't be reported - the only accesses to it that TSan sees\n// are the loads on the fast path. Loads don't race. Secondly, dispatch_once is\n// both a macro and a real function, we want to intercept the function, so we\n// need to undefine the macro.\n#undef dispatch_once\nTSAN_INTERCEPTOR(void, dispatch_once, dispatch_once_t *predicate,\n                 dispatch_block_t block) {\n  SCOPED_TSAN_INTERCEPTOR(dispatch_once, predicate, block);\n  atomic_uint32_t *a = reinterpret_cast<atomic_uint32_t *>(predicate);\n  u32 v = atomic_load(a, memory_order_acquire);\n  if (v == 0 &&\n      atomic_compare_exchange_strong(a, &v, 1, memory_order_relaxed)) {\n    SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();\n    block();\n    SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();\n    Release(thr, pc, (uptr)a);\n    atomic_store(a, 2, memory_order_release);\n  } else {\n    while (v != 2) {\n      internal_sched_yield();\n      v = atomic_load(a, memory_order_acquire);\n    }\n    Acquire(thr, pc, (uptr)a);\n  }\n}\n\n#undef dispatch_once_f\nTSAN_INTERCEPTOR(void, dispatch_once_f, dispatch_once_t *predicate,\n                 void *context, dispatch_function_t function) {\n  SCOPED_TSAN_INTERCEPTOR(dispatch_once_f, predicate, context, function);\n  SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();\n  WRAP(dispatch_once)(predicate, ^(void) {\n    function(context);\n  });\n  SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();\n}\n\nTSAN_INTERCEPTOR(long_t, dispatch_semaphore_signal,\n                 dispatch_semaphore_t dsema) {\n  SCOPED_TSAN_INTERCEPTOR(dispatch_semaphore_signal, dsema);\n  Release(thr, pc, (uptr)dsema);\n  return REAL(dispatch_semaphore_signal)(dsema);\n}\n\nTSAN_INTERCEPTOR(long_t, dispatch_semaphore_wait, dispatch_semaphore_t dsema,\n                 dispatch_time_t timeout) {\n  SCOPED_TSAN_INTERCEPTOR(dispatch_semaphore_wait, dsema, timeout);\n  long_t result = REAL(dispatch_semaphore_wait)(dsema, timeout);\n  if (result == 0) Acquire(thr, pc, (uptr)dsema);\n  return result;\n}\n\nTSAN_INTERCEPTOR(long_t, dispatch_group_wait, dispatch_group_t group,\n                 dispatch_time_t timeout) {\n  SCOPED_TSAN_INTERCEPTOR(dispatch_group_wait, group, timeout);\n  long_t result = REAL(dispatch_group_wait)(group, timeout);\n  if (result == 0) Acquire(thr, pc, (uptr)group);\n  return result;\n}\n\nTSAN_INTERCEPTOR(void, dispatch_group_leave, dispatch_group_t group) {\n  SCOPED_TSAN_INTERCEPTOR(dispatch_group_leave, group);\n  Release(thr, pc, (uptr)group);\n  REAL(dispatch_group_leave)(group);\n}\n\nTSAN_INTERCEPTOR(void, dispatch_group_async, dispatch_group_t group,\n                 dispatch_queue_t queue, dispatch_block_t block) {\n  SCOPED_TSAN_INTERCEPTOR(dispatch_group_async, group, queue, block);\n  dispatch_retain(group);\n  dispatch_group_enter(group);\n  WRAP(dispatch_async)(queue, ^(void) {\n    block();\n    WRAP(dispatch_group_leave)(group);\n    dispatch_release(group);\n  });\n}\n\nTSAN_INTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group,\n                 dispatch_queue_t queue, void *context,\n                 dispatch_function_t work) {\n  SCOPED_TSAN_INTERCEPTOR(dispatch_group_async_f, group, queue, context, work);\n  dispatch_retain(group);\n  dispatch_group_enter(group);\n  WRAP(dispatch_async)(queue, ^(void) {\n    work(context);\n    WRAP(dispatch_group_leave)(group);\n    dispatch_release(group);\n  });\n}\n\nTSAN_INTERCEPTOR(void, dispatch_group_notify, dispatch_group_t group,\n                 dispatch_queue_t q, dispatch_block_t block) {\n  SCOPED_TSAN_INTERCEPTOR(dispatch_group_notify, group, q, block);\n  SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();\n  dispatch_block_t heap_block = Block_copy(block);\n  SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();\n  tsan_block_context_t *new_context =\n      AllocContext(thr, pc, q, heap_block, &invoke_and_release_block);\n  new_context->object_to_acquire = (uptr)group;\n\n  // Will be released in dispatch_callback_wrap_acquire.\n  new_context->object_to_release = group;\n  dispatch_retain(group);\n\n  Release(thr, pc, (uptr)group);\n  REAL(dispatch_group_notify_f)(group, q, new_context,\n                                dispatch_callback_wrap_acquire);\n}\n\nTSAN_INTERCEPTOR(void, dispatch_group_notify_f, dispatch_group_t group,\n                 dispatch_queue_t q, void *context, dispatch_function_t work) {\n  SCOPED_TSAN_INTERCEPTOR(dispatch_group_notify_f, group, q, context, work);\n  tsan_block_context_t *new_context = AllocContext(thr, pc, q, context, work);\n  new_context->object_to_acquire = (uptr)group;\n\n  // Will be released in dispatch_callback_wrap_acquire.\n  new_context->object_to_release = group;\n  dispatch_retain(group);\n\n  Release(thr, pc, (uptr)group);\n  REAL(dispatch_group_notify_f)(group, q, new_context,\n                                dispatch_callback_wrap_acquire);\n}\n\n}  // namespace __tsan\n\n#endif  // SANITIZER_MAC\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_malloc_mac.cc",
    "content": "//===-- tsan_malloc_mac.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Mac-specific malloc interception.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_MAC\n\n#include \"tsan_interceptors.h\"\n#include \"tsan_stack_trace.h\"\n\nusing namespace __tsan;\n#define COMMON_MALLOC_ZONE_NAME \"tsan\"\n#define COMMON_MALLOC_ENTER()\n#define COMMON_MALLOC_SANITIZER_INITIALIZED (cur_thread()->is_inited)\n#define COMMON_MALLOC_FORCE_LOCK()\n#define COMMON_MALLOC_FORCE_UNLOCK()\n#define COMMON_MALLOC_MEMALIGN(alignment, size) \\\n  void *p =                                     \\\n      user_alloc(cur_thread(), StackTrace::GetCurrentPc(), size, alignment)\n#define COMMON_MALLOC_MALLOC(size)      \\\n  if (cur_thread()->in_symbolizer)      \\\n    return REAL(malloc)(size);          \\\n  SCOPED_INTERCEPTOR_RAW(malloc, size); \\\n  void *p = user_alloc(thr, pc, size)\n#define COMMON_MALLOC_REALLOC(ptr, size)      \\\n  if (cur_thread()->in_symbolizer)            \\\n    return REAL(realloc)(ptr, size);          \\\n  SCOPED_INTERCEPTOR_RAW(realloc, ptr, size); \\\n  void *p = user_realloc(thr, pc, ptr, size)\n#define COMMON_MALLOC_CALLOC(count, size)      \\\n  if (cur_thread()->in_symbolizer)             \\\n    return REAL(calloc)(count, size);          \\\n  SCOPED_INTERCEPTOR_RAW(calloc, size, count); \\\n  void *p = user_calloc(thr, pc, size, count)\n#define COMMON_MALLOC_VALLOC(size)                          \\\n  if (cur_thread()->in_symbolizer)                          \\\n    return REAL(valloc)(size);                              \\\n  SCOPED_INTERCEPTOR_RAW(valloc, size);                     \\\n  void *p = user_alloc(thr, pc, size, GetPageSizeCached())\n#define COMMON_MALLOC_FREE(ptr)      \\\n  if (cur_thread()->in_symbolizer)   \\\n    return REAL(free)(ptr);          \\\n  SCOPED_INTERCEPTOR_RAW(free, ptr); \\\n  user_free(thr, pc, ptr)\n#define COMMON_MALLOC_SIZE(ptr) \\\n  uptr size = user_alloc_usable_size(ptr);\n#define COMMON_MALLOC_FILL_STATS(zone, stats)\n#define COMMON_MALLOC_REPORT_UNKNOWN_REALLOC(ptr, zone_ptr, zone_name) \\\n  (void)zone_name; \\\n  Report(\"mz_realloc(%p) -- attempting to realloc unallocated memory.\\n\", ptr);\n#define COMMON_MALLOC_NAMESPACE __tsan\n\n#include \"sanitizer_common/sanitizer_malloc_mac.inc\"\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_md5.cc",
    "content": "//===-- tsan_md5.cc -------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_defs.h\"\n\nnamespace __tsan {\n\n#define F(x, y, z)      ((z) ^ ((x) & ((y) ^ (z))))\n#define G(x, y, z)      ((y) ^ ((z) & ((x) ^ (y))))\n#define H(x, y, z)      ((x) ^ (y) ^ (z))\n#define I(x, y, z)      ((y) ^ ((x) | ~(z)))\n\n#define STEP(f, a, b, c, d, x, t, s) \\\n  (a) += f((b), (c), (d)) + (x) + (t); \\\n  (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \\\n  (a) += (b);\n\n#define SET(n) \\\n  (*(const MD5_u32plus *)&ptr[(n) * 4])\n#define GET(n) \\\n  SET(n)\n\ntypedef unsigned int MD5_u32plus;\ntypedef unsigned long ulong_t;  // NOLINT\n\ntypedef struct {\n  MD5_u32plus lo, hi;\n  MD5_u32plus a, b, c, d;\n  unsigned char buffer[64];\n  MD5_u32plus block[16];\n} MD5_CTX;\n\nstatic const void *body(MD5_CTX *ctx, const void *data, ulong_t size) {\n  const unsigned char *ptr = (const unsigned char *)data;\n  MD5_u32plus a, b, c, d;\n  MD5_u32plus saved_a, saved_b, saved_c, saved_d;\n\n  a = ctx->a;\n  b = ctx->b;\n  c = ctx->c;\n  d = ctx->d;\n\n  do {\n    saved_a = a;\n    saved_b = b;\n    saved_c = c;\n    saved_d = d;\n\n    STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)\n    STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)\n    STEP(F, c, d, a, b, SET(2), 0x242070db, 17)\n    STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)\n    STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)\n    STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)\n    STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)\n    STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)\n    STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)\n    STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)\n    STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)\n    STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)\n    STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)\n    STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)\n    STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)\n    STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)\n\n    STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)\n    STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)\n    STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)\n    STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)\n    STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)\n    STEP(G, d, a, b, c, GET(10), 0x02441453, 9)\n    STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)\n    STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)\n    STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)\n    STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)\n    STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)\n    STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)\n    STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)\n    STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)\n    STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)\n    STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)\n\n    STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)\n    STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)\n    STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)\n    STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)\n    STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)\n    STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)\n    STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)\n    STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)\n    STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)\n    STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)\n    STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)\n    STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)\n    STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)\n    STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)\n    STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)\n    STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)\n\n    STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)\n    STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)\n    STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)\n    STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)\n    STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)\n    STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)\n    STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)\n    STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)\n    STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)\n    STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)\n    STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)\n    STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)\n    STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)\n    STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)\n    STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)\n    STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)\n\n    a += saved_a;\n    b += saved_b;\n    c += saved_c;\n    d += saved_d;\n\n    ptr += 64;\n  } while (size -= 64);\n\n  ctx->a = a;\n  ctx->b = b;\n  ctx->c = c;\n  ctx->d = d;\n\n  return ptr;\n}\n\nvoid MD5_Init(MD5_CTX *ctx) {\n  ctx->a = 0x67452301;\n  ctx->b = 0xefcdab89;\n  ctx->c = 0x98badcfe;\n  ctx->d = 0x10325476;\n\n  ctx->lo = 0;\n  ctx->hi = 0;\n}\n\nvoid MD5_Update(MD5_CTX *ctx, const void *data, ulong_t size) {\n  MD5_u32plus saved_lo;\n  ulong_t used, free;\n\n  saved_lo = ctx->lo;\n  if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)\n    ctx->hi++;\n  ctx->hi += size >> 29;\n\n  used = saved_lo & 0x3f;\n\n  if (used) {\n    free = 64 - used;\n\n    if (size < free) {\n      internal_memcpy(&ctx->buffer[used], data, size);\n      return;\n    }\n\n    internal_memcpy(&ctx->buffer[used], data, free);\n    data = (const unsigned char *)data + free;\n    size -= free;\n    body(ctx, ctx->buffer, 64);\n  }\n\n  if (size >= 64) {\n    data = body(ctx, data, size & ~(ulong_t)0x3f);\n    size &= 0x3f;\n  }\n\n  internal_memcpy(ctx->buffer, data, size);\n}\n\nvoid MD5_Final(unsigned char *result, MD5_CTX *ctx) {\n  ulong_t used, free;\n\n  used = ctx->lo & 0x3f;\n\n  ctx->buffer[used++] = 0x80;\n\n  free = 64 - used;\n\n  if (free < 8) {\n    internal_memset(&ctx->buffer[used], 0, free);\n    body(ctx, ctx->buffer, 64);\n    used = 0;\n    free = 64;\n  }\n\n  internal_memset(&ctx->buffer[used], 0, free - 8);\n\n  ctx->lo <<= 3;\n  ctx->buffer[56] = ctx->lo;\n  ctx->buffer[57] = ctx->lo >> 8;\n  ctx->buffer[58] = ctx->lo >> 16;\n  ctx->buffer[59] = ctx->lo >> 24;\n  ctx->buffer[60] = ctx->hi;\n  ctx->buffer[61] = ctx->hi >> 8;\n  ctx->buffer[62] = ctx->hi >> 16;\n  ctx->buffer[63] = ctx->hi >> 24;\n\n  body(ctx, ctx->buffer, 64);\n\n  result[0] = ctx->a;\n  result[1] = ctx->a >> 8;\n  result[2] = ctx->a >> 16;\n  result[3] = ctx->a >> 24;\n  result[4] = ctx->b;\n  result[5] = ctx->b >> 8;\n  result[6] = ctx->b >> 16;\n  result[7] = ctx->b >> 24;\n  result[8] = ctx->c;\n  result[9] = ctx->c >> 8;\n  result[10] = ctx->c >> 16;\n  result[11] = ctx->c >> 24;\n  result[12] = ctx->d;\n  result[13] = ctx->d >> 8;\n  result[14] = ctx->d >> 16;\n  result[15] = ctx->d >> 24;\n\n  internal_memset(ctx, 0, sizeof(*ctx));\n}\n\nMD5Hash md5_hash(const void *data, uptr size) {\n  MD5Hash res;\n  MD5_CTX ctx;\n  MD5_Init(&ctx);\n  MD5_Update(&ctx, data, size);\n  MD5_Final((unsigned char*)&res.hash[0], &ctx);\n  return res;\n}\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_mman.cc",
    "content": "//===-- tsan_mman.cc ------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_allocator_interface.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"tsan_mman.h\"\n#include \"tsan_rtl.h\"\n#include \"tsan_report.h\"\n#include \"tsan_flags.h\"\n\n// May be overriden by front-end.\nSANITIZER_WEAK_DEFAULT_IMPL\nvoid __sanitizer_malloc_hook(void *ptr, uptr size) {\n  (void)ptr;\n  (void)size;\n}\n\nSANITIZER_WEAK_DEFAULT_IMPL\nvoid __sanitizer_free_hook(void *ptr) {\n  (void)ptr;\n}\n\nnamespace __tsan {\n\nstruct MapUnmapCallback {\n  void OnMap(uptr p, uptr size) const { }\n  void OnUnmap(uptr p, uptr size) const {\n    // We are about to unmap a chunk of user memory.\n    // Mark the corresponding shadow memory as not needed.\n    DontNeedShadowFor(p, size);\n    // Mark the corresponding meta shadow memory as not needed.\n    // Note the block does not contain any meta info at this point\n    // (this happens after free).\n    const uptr kMetaRatio = kMetaShadowCell / kMetaShadowSize;\n    const uptr kPageSize = GetPageSizeCached() * kMetaRatio;\n    // Block came from LargeMmapAllocator, so must be large.\n    // We rely on this in the calculations below.\n    CHECK_GE(size, 2 * kPageSize);\n    uptr diff = RoundUp(p, kPageSize) - p;\n    if (diff != 0) {\n      p += diff;\n      size -= diff;\n    }\n    diff = p + size - RoundDown(p + size, kPageSize);\n    if (diff != 0)\n      size -= diff;\n    FlushUnneededShadowMemory((uptr)MemToMeta(p), size / kMetaRatio);\n  }\n};\n\nstatic char allocator_placeholder[sizeof(Allocator)] ALIGNED(64);\nAllocator *allocator() {\n  return reinterpret_cast<Allocator*>(&allocator_placeholder);\n}\n\nvoid InitializeAllocator() {\n  allocator()->Init(common_flags()->allocator_may_return_null);\n}\n\nvoid AllocatorThreadStart(ThreadState *thr) {\n  allocator()->InitCache(&thr->alloc_cache);\n  internal_allocator()->InitCache(&thr->internal_alloc_cache);\n}\n\nvoid AllocatorThreadFinish(ThreadState *thr) {\n  allocator()->DestroyCache(&thr->alloc_cache);\n  internal_allocator()->DestroyCache(&thr->internal_alloc_cache);\n}\n\nvoid AllocatorPrintStats() {\n  allocator()->PrintStats();\n}\n\nstatic void SignalUnsafeCall(ThreadState *thr, uptr pc) {\n  if (atomic_load_relaxed(&thr->in_signal_handler) == 0 ||\n      !flags()->report_signal_unsafe)\n    return;\n  VarSizeStackTrace stack;\n  ObtainCurrentStack(thr, pc, &stack);\n  if (IsFiredSuppression(ctx, ReportTypeSignalUnsafe, stack))\n    return;\n  ThreadRegistryLock l(ctx->thread_registry);\n  ScopedReport rep(ReportTypeSignalUnsafe);\n  rep.AddStack(stack, true);\n  OutputReport(thr, rep);\n}\n\nvoid *user_alloc(ThreadState *thr, uptr pc, uptr sz, uptr align, bool signal) {\n  if ((sz >= (1ull << 40)) || (align >= (1ull << 40)))\n    return allocator()->ReturnNullOrDie();\n  void *p = allocator()->Allocate(&thr->alloc_cache, sz, align);\n  if (p == 0)\n    return 0;\n  if (ctx && ctx->initialized)\n    OnUserAlloc(thr, pc, (uptr)p, sz, true);\n  if (signal)\n    SignalUnsafeCall(thr, pc);\n  return p;\n}\n\nvoid *user_calloc(ThreadState *thr, uptr pc, uptr size, uptr n) {\n  if (CallocShouldReturnNullDueToOverflow(size, n))\n    return allocator()->ReturnNullOrDie();\n  void *p = user_alloc(thr, pc, n * size);\n  if (p)\n    internal_memset(p, 0, n * size);\n  return p;\n}\n\nvoid user_free(ThreadState *thr, uptr pc, void *p, bool signal) {\n  if (ctx && ctx->initialized)\n    OnUserFree(thr, pc, (uptr)p, true);\n  allocator()->Deallocate(&thr->alloc_cache, p);\n  if (signal)\n    SignalUnsafeCall(thr, pc);\n}\n\nvoid OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write) {\n  DPrintf(\"#%d: alloc(%zu) = %p\\n\", thr->tid, sz, p);\n  ctx->metamap.AllocBlock(thr, pc, p, sz);\n  if (write && thr->ignore_reads_and_writes == 0)\n    MemoryRangeImitateWrite(thr, pc, (uptr)p, sz);\n  else\n    MemoryResetRange(thr, pc, (uptr)p, sz);\n}\n\nvoid OnUserFree(ThreadState *thr, uptr pc, uptr p, bool write) {\n  CHECK_NE(p, (void*)0);\n  uptr sz = ctx->metamap.FreeBlock(thr, pc, p);\n  DPrintf(\"#%d: free(%p, %zu)\\n\", thr->tid, p, sz);\n  if (write && thr->ignore_reads_and_writes == 0)\n    MemoryRangeFreed(thr, pc, (uptr)p, sz);\n}\n\nvoid *user_realloc(ThreadState *thr, uptr pc, void *p, uptr sz) {\n  void *p2 = 0;\n  // FIXME: Handle \"shrinking\" more efficiently,\n  // it seems that some software actually does this.\n  if (sz) {\n    p2 = user_alloc(thr, pc, sz);\n    if (p2 == 0)\n      return 0;\n    if (p) {\n      uptr oldsz = user_alloc_usable_size(p);\n      internal_memcpy(p2, p, min(oldsz, sz));\n    }\n  }\n  if (p)\n    user_free(thr, pc, p);\n  return p2;\n}\n\nuptr user_alloc_usable_size(const void *p) {\n  if (p == 0)\n    return 0;\n  MBlock *b = ctx->metamap.GetBlock((uptr)p);\n  return b ? b->siz : 0;\n}\n\nvoid invoke_malloc_hook(void *ptr, uptr size) {\n  ThreadState *thr = cur_thread();\n  if (ctx == 0 || !ctx->initialized || thr->ignore_interceptors)\n    return;\n  __sanitizer_malloc_hook(ptr, size);\n}\n\nvoid invoke_free_hook(void *ptr) {\n  ThreadState *thr = cur_thread();\n  if (ctx == 0 || !ctx->initialized || thr->ignore_interceptors)\n    return;\n  __sanitizer_free_hook(ptr);\n}\n\nvoid *internal_alloc(MBlockType typ, uptr sz) {\n  ThreadState *thr = cur_thread();\n  if (thr->nomalloc) {\n    thr->nomalloc = 0;  // CHECK calls internal_malloc().\n    CHECK(0);\n  }\n  return InternalAlloc(sz, &thr->internal_alloc_cache);\n}\n\nvoid internal_free(void *p) {\n  ThreadState *thr = cur_thread();\n  if (thr->nomalloc) {\n    thr->nomalloc = 0;  // CHECK calls internal_malloc().\n    CHECK(0);\n  }\n  InternalFree(p, &thr->internal_alloc_cache);\n}\n\n}  // namespace __tsan\n\nusing namespace __tsan;\n\nextern \"C\" {\nuptr __sanitizer_get_current_allocated_bytes() {\n  uptr stats[AllocatorStatCount];\n  allocator()->GetStats(stats);\n  return stats[AllocatorStatAllocated];\n}\n\nuptr __sanitizer_get_heap_size() {\n  uptr stats[AllocatorStatCount];\n  allocator()->GetStats(stats);\n  return stats[AllocatorStatMapped];\n}\n\nuptr __sanitizer_get_free_bytes() {\n  return 1;\n}\n\nuptr __sanitizer_get_unmapped_bytes() {\n  return 1;\n}\n\nuptr __sanitizer_get_estimated_allocated_size(uptr size) {\n  return size;\n}\n\nint __sanitizer_get_ownership(const void *p) {\n  return allocator()->GetBlockBegin(p) != 0;\n}\n\nuptr __sanitizer_get_allocated_size(const void *p) {\n  return user_alloc_usable_size(p);\n}\n\nvoid __tsan_on_thread_idle() {\n  ThreadState *thr = cur_thread();\n  allocator()->SwallowCache(&thr->alloc_cache);\n  internal_allocator()->SwallowCache(&thr->internal_alloc_cache);\n  ctx->metamap.OnThreadIdle(thr);\n}\n}  // extern \"C\"\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_mman.h",
    "content": "//===-- tsan_mman.h ---------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_MMAN_H\n#define TSAN_MMAN_H\n\n#include \"tsan_defs.h\"\n\nnamespace __tsan {\n\nconst uptr kDefaultAlignment = 16;\n\nvoid InitializeAllocator();\nvoid ReplaceSystemMalloc();\nvoid AllocatorThreadStart(ThreadState *thr);\nvoid AllocatorThreadFinish(ThreadState *thr);\nvoid AllocatorPrintStats();\n\n// For user allocations.\nvoid *user_alloc(ThreadState *thr, uptr pc, uptr sz,\n                 uptr align = kDefaultAlignment, bool signal = true);\nvoid *user_calloc(ThreadState *thr, uptr pc, uptr sz, uptr n);\n// Does not accept NULL.\nvoid user_free(ThreadState *thr, uptr pc, void *p, bool signal = true);\nvoid *user_realloc(ThreadState *thr, uptr pc, void *p, uptr sz);\nvoid *user_alloc_aligned(ThreadState *thr, uptr pc, uptr sz, uptr align);\nuptr user_alloc_usable_size(const void *p);\n\n// Invoking malloc/free hooks that may be installed by the user.\nvoid invoke_malloc_hook(void *ptr, uptr size);\nvoid invoke_free_hook(void *ptr);\n\nenum MBlockType {\n  MBlockScopedBuf,\n  MBlockString,\n  MBlockStackTrace,\n  MBlockShadowStack,\n  MBlockSync,\n  MBlockClock,\n  MBlockThreadContex,\n  MBlockDeadInfo,\n  MBlockRacyStacks,\n  MBlockRacyAddresses,\n  MBlockAtExit,\n  MBlockFlag,\n  MBlockReport,\n  MBlockReportMop,\n  MBlockReportThread,\n  MBlockReportMutex,\n  MBlockReportLoc,\n  MBlockReportStack,\n  MBlockSuppression,\n  MBlockExpectRace,\n  MBlockSignal,\n  MBlockJmpBuf,\n\n  // This must be the last.\n  MBlockTypeCount\n};\n\n// For internal data structures.\nvoid *internal_alloc(MBlockType typ, uptr sz);\nvoid internal_free(void *p);\n\ntemplate<typename T>\nvoid DestroyAndFree(T *&p) {\n  p->~T();\n  internal_free(p);\n  p = 0;\n}\n\n}  // namespace __tsan\n#endif  // TSAN_MMAN_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_mutex.cc",
    "content": "//===-- tsan_mutex.cc -----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"tsan_mutex.h\"\n#include \"tsan_platform.h\"\n#include \"tsan_rtl.h\"\n\nnamespace __tsan {\n\n// Simple reader-writer spin-mutex. Optimized for not-so-contended case.\n// Readers have preference, can possibly starvate writers.\n\n// The table fixes what mutexes can be locked under what mutexes.\n// E.g. if the row for MutexTypeThreads contains MutexTypeReport,\n// then Report mutex can be locked while under Threads mutex.\n// The leaf mutexes can be locked under any other mutexes.\n// Recursive locking is not supported.\n#if SANITIZER_DEBUG && !SANITIZER_GO\nconst MutexType MutexTypeLeaf = (MutexType)-1;\nstatic MutexType CanLockTab[MutexTypeCount][MutexTypeCount] = {\n  /*0  MutexTypeInvalid*/     {},\n  /*1  MutexTypeTrace*/       {MutexTypeLeaf},\n  /*2  MutexTypeThreads*/     {MutexTypeReport},\n  /*3  MutexTypeReport*/      {MutexTypeSyncVar,\n                               MutexTypeMBlock, MutexTypeJavaMBlock},\n  /*4  MutexTypeSyncVar*/     {MutexTypeDDetector},\n  /*5  MutexTypeSyncTab*/     {},  // unused\n  /*6  MutexTypeSlab*/        {MutexTypeLeaf},\n  /*7  MutexTypeAnnotations*/ {},\n  /*8  MutexTypeAtExit*/      {MutexTypeSyncVar},\n  /*9  MutexTypeMBlock*/      {MutexTypeSyncVar},\n  /*10 MutexTypeJavaMBlock*/  {MutexTypeSyncVar},\n  /*11 MutexTypeDDetector*/   {},\n  /*12 MutexTypeFired*/       {MutexTypeLeaf},\n  /*13 MutexTypeRacy*/        {MutexTypeLeaf},\n};\n\nstatic bool CanLockAdj[MutexTypeCount][MutexTypeCount];\n#endif\n\nvoid InitializeMutex() {\n#if SANITIZER_DEBUG && !SANITIZER_GO\n  // Build the \"can lock\" adjacency matrix.\n  // If [i][j]==true, then one can lock mutex j while under mutex i.\n  const int N = MutexTypeCount;\n  int cnt[N] = {};\n  bool leaf[N] = {};\n  for (int i = 1; i < N; i++) {\n    for (int j = 0; j < N; j++) {\n      MutexType z = CanLockTab[i][j];\n      if (z == MutexTypeInvalid)\n        continue;\n      if (z == MutexTypeLeaf) {\n        CHECK(!leaf[i]);\n        leaf[i] = true;\n        continue;\n      }\n      CHECK(!CanLockAdj[i][(int)z]);\n      CanLockAdj[i][(int)z] = true;\n      cnt[i]++;\n    }\n  }\n  for (int i = 0; i < N; i++) {\n    CHECK(!leaf[i] || cnt[i] == 0);\n  }\n  // Add leaf mutexes.\n  for (int i = 0; i < N; i++) {\n    if (!leaf[i])\n      continue;\n    for (int j = 0; j < N; j++) {\n      if (i == j || leaf[j] || j == MutexTypeInvalid)\n        continue;\n      CHECK(!CanLockAdj[j][i]);\n      CanLockAdj[j][i] = true;\n    }\n  }\n  // Build the transitive closure.\n  bool CanLockAdj2[MutexTypeCount][MutexTypeCount];\n  for (int i = 0; i < N; i++) {\n    for (int j = 0; j < N; j++) {\n      CanLockAdj2[i][j] = CanLockAdj[i][j];\n    }\n  }\n  for (int k = 0; k < N; k++) {\n    for (int i = 0; i < N; i++) {\n      for (int j = 0; j < N; j++) {\n        if (CanLockAdj2[i][k] && CanLockAdj2[k][j]) {\n          CanLockAdj2[i][j] = true;\n        }\n      }\n    }\n  }\n#if 0\n  Printf(\"Can lock graph:\\n\");\n  for (int i = 0; i < N; i++) {\n    for (int j = 0; j < N; j++) {\n      Printf(\"%d \", CanLockAdj[i][j]);\n    }\n    Printf(\"\\n\");\n  }\n  Printf(\"Can lock graph closure:\\n\");\n  for (int i = 0; i < N; i++) {\n    for (int j = 0; j < N; j++) {\n      Printf(\"%d \", CanLockAdj2[i][j]);\n    }\n    Printf(\"\\n\");\n  }\n#endif\n  // Verify that the graph is acyclic.\n  for (int i = 0; i < N; i++) {\n    if (CanLockAdj2[i][i]) {\n      Printf(\"Mutex %d participates in a cycle\\n\", i);\n      Die();\n    }\n  }\n#endif\n}\n\nInternalDeadlockDetector::InternalDeadlockDetector() {\n  // Rely on zero initialization because some mutexes can be locked before ctor.\n}\n\n#if SANITIZER_DEBUG && !SANITIZER_GO\nvoid InternalDeadlockDetector::Lock(MutexType t) {\n  // Printf(\"LOCK %d @%zu\\n\", t, seq_ + 1);\n  CHECK_GT(t, MutexTypeInvalid);\n  CHECK_LT(t, MutexTypeCount);\n  u64 max_seq = 0;\n  u64 max_idx = MutexTypeInvalid;\n  for (int i = 0; i != MutexTypeCount; i++) {\n    if (locked_[i] == 0)\n      continue;\n    CHECK_NE(locked_[i], max_seq);\n    if (max_seq < locked_[i]) {\n      max_seq = locked_[i];\n      max_idx = i;\n    }\n  }\n  locked_[t] = ++seq_;\n  if (max_idx == MutexTypeInvalid)\n    return;\n  // Printf(\"  last %d @%zu\\n\", max_idx, max_seq);\n  if (!CanLockAdj[max_idx][t]) {\n    Printf(\"ThreadSanitizer: internal deadlock detected\\n\");\n    Printf(\"ThreadSanitizer: can't lock %d while under %zu\\n\",\n               t, (uptr)max_idx);\n    CHECK(0);\n  }\n}\n\nvoid InternalDeadlockDetector::Unlock(MutexType t) {\n  // Printf(\"UNLO %d @%zu #%zu\\n\", t, seq_, locked_[t]);\n  CHECK(locked_[t]);\n  locked_[t] = 0;\n}\n\nvoid InternalDeadlockDetector::CheckNoLocks() {\n  for (int i = 0; i != MutexTypeCount; i++) {\n    CHECK_EQ(locked_[i], 0);\n  }\n}\n#endif\n\nvoid CheckNoLocks(ThreadState *thr) {\n#if SANITIZER_DEBUG && !SANITIZER_GO\n  thr->internal_deadlock_detector.CheckNoLocks();\n#endif\n}\n\nconst uptr kUnlocked = 0;\nconst uptr kWriteLock = 1;\nconst uptr kReadLock = 2;\n\nclass Backoff {\n public:\n  Backoff()\n    : iter_() {\n  }\n\n  bool Do() {\n    if (iter_++ < kActiveSpinIters)\n      proc_yield(kActiveSpinCnt);\n    else\n      internal_sched_yield();\n    return true;\n  }\n\n  u64 Contention() const {\n    u64 active = iter_ % kActiveSpinIters;\n    u64 passive = iter_ - active;\n    return active + 10 * passive;\n  }\n\n private:\n  int iter_;\n  static const int kActiveSpinIters = 10;\n  static const int kActiveSpinCnt = 20;\n};\n\nMutex::Mutex(MutexType type, StatType stat_type) {\n  CHECK_GT(type, MutexTypeInvalid);\n  CHECK_LT(type, MutexTypeCount);\n#if SANITIZER_DEBUG\n  type_ = type;\n#endif\n#if TSAN_COLLECT_STATS\n  stat_type_ = stat_type;\n#endif\n  atomic_store(&state_, kUnlocked, memory_order_relaxed);\n}\n\nMutex::~Mutex() {\n  CHECK_EQ(atomic_load(&state_, memory_order_relaxed), kUnlocked);\n}\n\nvoid Mutex::Lock() {\n#if SANITIZER_DEBUG && !SANITIZER_GO\n  cur_thread()->internal_deadlock_detector.Lock(type_);\n#endif\n  uptr cmp = kUnlocked;\n  if (atomic_compare_exchange_strong(&state_, &cmp, kWriteLock,\n                                     memory_order_acquire))\n    return;\n  for (Backoff backoff; backoff.Do();) {\n    if (atomic_load(&state_, memory_order_relaxed) == kUnlocked) {\n      cmp = kUnlocked;\n      if (atomic_compare_exchange_weak(&state_, &cmp, kWriteLock,\n                                       memory_order_acquire)) {\n#if TSAN_COLLECT_STATS && !SANITIZER_GO\n        StatInc(cur_thread(), stat_type_, backoff.Contention());\n#endif\n        return;\n      }\n    }\n  }\n}\n\nvoid Mutex::Unlock() {\n  uptr prev = atomic_fetch_sub(&state_, kWriteLock, memory_order_release);\n  (void)prev;\n  DCHECK_NE(prev & kWriteLock, 0);\n#if SANITIZER_DEBUG && !SANITIZER_GO\n  cur_thread()->internal_deadlock_detector.Unlock(type_);\n#endif\n}\n\nvoid Mutex::ReadLock() {\n#if SANITIZER_DEBUG && !SANITIZER_GO\n  cur_thread()->internal_deadlock_detector.Lock(type_);\n#endif\n  uptr prev = atomic_fetch_add(&state_, kReadLock, memory_order_acquire);\n  if ((prev & kWriteLock) == 0)\n    return;\n  for (Backoff backoff; backoff.Do();) {\n    prev = atomic_load(&state_, memory_order_acquire);\n    if ((prev & kWriteLock) == 0) {\n#if TSAN_COLLECT_STATS && !SANITIZER_GO\n      StatInc(cur_thread(), stat_type_, backoff.Contention());\n#endif\n      return;\n    }\n  }\n}\n\nvoid Mutex::ReadUnlock() {\n  uptr prev = atomic_fetch_sub(&state_, kReadLock, memory_order_release);\n  (void)prev;\n  DCHECK_EQ(prev & kWriteLock, 0);\n  DCHECK_GT(prev & ~kWriteLock, 0);\n#if SANITIZER_DEBUG && !SANITIZER_GO\n  cur_thread()->internal_deadlock_detector.Unlock(type_);\n#endif\n}\n\nvoid Mutex::CheckLocked() {\n  CHECK_NE(atomic_load(&state_, memory_order_relaxed), 0);\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_mutex.h",
    "content": "//===-- tsan_mutex.h --------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_MUTEX_H\n#define TSAN_MUTEX_H\n\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"sanitizer_common/sanitizer_mutex.h\"\n#include \"tsan_defs.h\"\n\nnamespace __tsan {\n\nenum MutexType {\n  MutexTypeInvalid,\n  MutexTypeTrace,\n  MutexTypeThreads,\n  MutexTypeReport,\n  MutexTypeSyncVar,\n  MutexTypeSyncTab,\n  MutexTypeSlab,\n  MutexTypeAnnotations,\n  MutexTypeAtExit,\n  MutexTypeMBlock,\n  MutexTypeJavaMBlock,\n  MutexTypeDDetector,\n  MutexTypeFired,\n  MutexTypeRacy,\n\n  // This must be the last.\n  MutexTypeCount\n};\n\nclass Mutex {\n public:\n  explicit Mutex(MutexType type, StatType stat_type);\n  ~Mutex();\n\n  void Lock();\n  void Unlock();\n\n  void ReadLock();\n  void ReadUnlock();\n\n  void CheckLocked();\n\n private:\n  atomic_uintptr_t state_;\n#if SANITIZER_DEBUG\n  MutexType type_;\n#endif\n#if TSAN_COLLECT_STATS\n  StatType stat_type_;\n#endif\n\n  Mutex(const Mutex&);\n  void operator = (const Mutex&);\n};\n\ntypedef GenericScopedLock<Mutex> Lock;\ntypedef GenericScopedReadLock<Mutex> ReadLock;\n\nclass InternalDeadlockDetector {\n public:\n  InternalDeadlockDetector();\n  void Lock(MutexType t);\n  void Unlock(MutexType t);\n  void CheckNoLocks();\n private:\n  u64 seq_;\n  u64 locked_[MutexTypeCount];\n};\n\nvoid InitializeMutex();\n\n// Checks that the current thread does not hold any runtime locks\n// (e.g. when returning from an interceptor).\nvoid CheckNoLocks(ThreadState *thr);\n\n}  // namespace __tsan\n\n#endif  // TSAN_MUTEX_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_mutexset.cc",
    "content": "//===-- tsan_mutexset.cc --------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_mutexset.h\"\n#include \"tsan_rtl.h\"\n\nnamespace __tsan {\n\nconst uptr MutexSet::kMaxSize;\n\nMutexSet::MutexSet() {\n  size_ = 0;\n  internal_memset(&descs_, 0, sizeof(descs_));\n}\n\nvoid MutexSet::Add(u64 id, bool write, u64 epoch) {\n  // Look up existing mutex with the same id.\n  for (uptr i = 0; i < size_; i++) {\n    if (descs_[i].id == id) {\n      descs_[i].count++;\n      descs_[i].epoch = epoch;\n      return;\n    }\n  }\n  // On overflow, find the oldest mutex and drop it.\n  if (size_ == kMaxSize) {\n    u64 minepoch = (u64)-1;\n    u64 mini = (u64)-1;\n    for (uptr i = 0; i < size_; i++) {\n      if (descs_[i].epoch < minepoch) {\n        minepoch = descs_[i].epoch;\n        mini = i;\n      }\n    }\n    RemovePos(mini);\n    CHECK_EQ(size_, kMaxSize - 1);\n  }\n  // Add new mutex descriptor.\n  descs_[size_].id = id;\n  descs_[size_].write = write;\n  descs_[size_].epoch = epoch;\n  descs_[size_].count = 1;\n  size_++;\n}\n\nvoid MutexSet::Del(u64 id, bool write) {\n  for (uptr i = 0; i < size_; i++) {\n    if (descs_[i].id == id) {\n      if (--descs_[i].count == 0)\n        RemovePos(i);\n      return;\n    }\n  }\n}\n\nvoid MutexSet::Remove(u64 id) {\n  for (uptr i = 0; i < size_; i++) {\n    if (descs_[i].id == id) {\n      RemovePos(i);\n      return;\n    }\n  }\n}\n\nvoid MutexSet::RemovePos(uptr i) {\n  CHECK_LT(i, size_);\n  descs_[i] = descs_[size_ - 1];\n  size_--;\n}\n\nuptr MutexSet::Size() const {\n  return size_;\n}\n\nMutexSet::Desc MutexSet::Get(uptr i) const {\n  CHECK_LT(i, size_);\n  return descs_[i];\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_mutexset.h",
    "content": "//===-- tsan_mutexset.h -----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// MutexSet holds the set of mutexes currently held by a thread.\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_MUTEXSET_H\n#define TSAN_MUTEXSET_H\n\n#include \"tsan_defs.h\"\n\nnamespace __tsan {\n\nclass MutexSet {\n public:\n  // Holds limited number of mutexes.\n  // The oldest mutexes are discarded on overflow.\n  static const uptr kMaxSize = 16;\n  struct Desc {\n    u64 id;\n    u64 epoch;\n    int count;\n    bool write;\n  };\n\n  MutexSet();\n  // The 'id' is obtained from SyncVar::GetId().\n  void Add(u64 id, bool write, u64 epoch);\n  void Del(u64 id, bool write);\n  void Remove(u64 id);  // Removes the mutex completely (if it's destroyed).\n  uptr Size() const;\n  Desc Get(uptr i) const;\n\n  void operator=(const MutexSet &other) {\n    internal_memcpy(this, &other, sizeof(*this));\n  }\n\n private:\n#ifndef SANITIZER_GO\n  uptr size_;\n  Desc descs_[kMaxSize];\n#endif\n\n  void RemovePos(uptr i);\n  MutexSet(const MutexSet&);\n};\n\n// Go does not have mutexes, so do not spend memory and time.\n// (Go sync.Mutex is actually a semaphore -- can be unlocked\n// in different goroutine).\n#ifdef SANITIZER_GO\nMutexSet::MutexSet() {}\nvoid MutexSet::Add(u64 id, bool write, u64 epoch) {}\nvoid MutexSet::Del(u64 id, bool write) {}\nvoid MutexSet::Remove(u64 id) {}\nvoid MutexSet::RemovePos(uptr i) {}\nuptr MutexSet::Size() const { return 0; }\nMutexSet::Desc MutexSet::Get(uptr i) const { return Desc(); }\n#endif\n\n}  // namespace __tsan\n\n#endif  // TSAN_MUTEXSET_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_new_delete.cc",
    "content": "//===-- tsan_new_delete.cc ----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Interceptors for operators new and delete.\n//===----------------------------------------------------------------------===//\n#include \"interception/interception.h\"\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"tsan_interceptors.h\"\n\nusing namespace __tsan;  // NOLINT\n\nnamespace std {\nstruct nothrow_t {};\n}  // namespace std\n\nDECLARE_REAL(void *, malloc, uptr size)\nDECLARE_REAL(void, free, void *ptr)\n#if SANITIZER_MAC || SANITIZER_ANDROID\n#define __libc_malloc REAL(malloc)\n#define __libc_free REAL(free)\n#endif\n\n#define OPERATOR_NEW_BODY(mangled_name) \\\n  if (cur_thread()->in_symbolizer) \\\n    return __libc_malloc(size); \\\n  void *p = 0; \\\n  {  \\\n    SCOPED_INTERCEPTOR_RAW(mangled_name, size); \\\n    p = user_alloc(thr, pc, size); \\\n  }  \\\n  invoke_malloc_hook(p, size);  \\\n  return p;\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid *operator new(__sanitizer::uptr size);\nvoid *operator new(__sanitizer::uptr size) {\n  OPERATOR_NEW_BODY(_Znwm);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid *operator new[](__sanitizer::uptr size);\nvoid *operator new[](__sanitizer::uptr size) {\n  OPERATOR_NEW_BODY(_Znam);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid *operator new(__sanitizer::uptr size, std::nothrow_t const&);\nvoid *operator new(__sanitizer::uptr size, std::nothrow_t const&) {\n  OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid *operator new[](__sanitizer::uptr size, std::nothrow_t const&);\nvoid *operator new[](__sanitizer::uptr size, std::nothrow_t const&) {\n  OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t);\n}\n\n#define OPERATOR_DELETE_BODY(mangled_name) \\\n  if (ptr == 0) return;  \\\n  if (cur_thread()->in_symbolizer) \\\n    return __libc_free(ptr); \\\n  invoke_free_hook(ptr);  \\\n  SCOPED_INTERCEPTOR_RAW(mangled_name, ptr);  \\\n  user_free(thr, pc, ptr);\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid operator delete(void *ptr) NOEXCEPT;\nvoid operator delete(void *ptr) NOEXCEPT {\n  OPERATOR_DELETE_BODY(_ZdlPv);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid operator delete[](void *ptr) NOEXCEPT;\nvoid operator delete[](void *ptr) NOEXCEPT {\n  OPERATOR_DELETE_BODY(_ZdaPv);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid operator delete(void *ptr, std::nothrow_t const&);\nvoid operator delete(void *ptr, std::nothrow_t const&) {\n  OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t);\n}\n\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid operator delete[](void *ptr, std::nothrow_t const&);\nvoid operator delete[](void *ptr, std::nothrow_t const&) {\n  OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_platform.h",
    "content": "//===-- tsan_platform.h -----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Platform-specific code.\n//===----------------------------------------------------------------------===//\n\n#ifndef TSAN_PLATFORM_H\n#define TSAN_PLATFORM_H\n\n#if !defined(__LP64__) && !defined(_WIN64)\n# error \"Only 64-bit is supported\"\n#endif\n\n#include \"tsan_defs.h\"\n#include \"tsan_trace.h\"\n\nnamespace __tsan {\n\n#if !defined(SANITIZER_GO)\n\n#if defined(__x86_64__)\n/*\nC/C++ on linux/x86_64 and freebsd/x86_64\n0000 0000 1000 - 0100 0000 0000: main binary and/or MAP_32BIT mappings\n0100 0000 0000 - 0200 0000 0000: -\n0200 0000 0000 - 1000 0000 0000: shadow\n1000 0000 0000 - 3000 0000 0000: -\n3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)\n4000 0000 0000 - 6000 0000 0000: -\n6000 0000 0000 - 6200 0000 0000: traces\n6200 0000 0000 - 7d00 0000 0000: -\n7d00 0000 0000 - 7e00 0000 0000: heap\n7e00 0000 0000 - 7e80 0000 0000: -\n7e80 0000 0000 - 8000 0000 0000: modules and main thread stack\n*/\nstruct Mapping {\n  static const uptr kMetaShadowBeg = 0x300000000000ull;\n  static const uptr kMetaShadowEnd = 0x400000000000ull;\n  static const uptr kTraceMemBeg   = 0x600000000000ull;\n  static const uptr kTraceMemEnd   = 0x620000000000ull;\n  static const uptr kShadowBeg     = 0x020000000000ull;\n  static const uptr kShadowEnd     = 0x100000000000ull;\n  static const uptr kHeapMemBeg    = 0x7d0000000000ull;\n  static const uptr kHeapMemEnd    = 0x7e0000000000ull;\n  static const uptr kLoAppMemBeg   = 0x000000001000ull;\n  static const uptr kLoAppMemEnd   = 0x010000000000ull;\n  static const uptr kHiAppMemBeg   = 0x7e8000000000ull;\n  static const uptr kHiAppMemEnd   = 0x800000000000ull;\n  static const uptr kAppMemMsk     = 0x7c0000000000ull;\n  static const uptr kAppMemXor     = 0x020000000000ull;\n  static const uptr kVdsoBeg       = 0xf000000000000000ull;\n};\n#elif defined(__mips64)\n/*\nC/C++ on linux/mips64\n0100 0000 00 - 0200 0000 00: main binary\n0200 0000 00 - 1400 0000 00: -\n1400 0000 00 - 2400 0000 00: shadow\n2400 0000 00 - 3000 0000 00: -\n3000 0000 00 - 4000 0000 00: metainfo (memory blocks and sync objects)\n4000 0000 00 - 6000 0000 00: -\n6000 0000 00 - 6200 0000 00: traces\n6200 0000 00 - fe00 0000 00: -\nfe00 0000 00 - ff00 0000 00: heap\nff00 0000 00 - ff80 0000 00: -\nff80 0000 00 - ffff ffff ff: modules and main thread stack\n*/\nstruct Mapping {\n  static const uptr kMetaShadowBeg = 0x3000000000ull;\n  static const uptr kMetaShadowEnd = 0x4000000000ull;\n  static const uptr kTraceMemBeg   = 0x6000000000ull;\n  static const uptr kTraceMemEnd   = 0x6200000000ull;\n  static const uptr kShadowBeg     = 0x1400000000ull;\n  static const uptr kShadowEnd     = 0x2400000000ull;\n  static const uptr kHeapMemBeg    = 0xfe00000000ull;\n  static const uptr kHeapMemEnd    = 0xff00000000ull;\n  static const uptr kLoAppMemBeg   = 0x0100000000ull;\n  static const uptr kLoAppMemEnd   = 0x0200000000ull;\n  static const uptr kHiAppMemBeg   = 0xff80000000ull;\n  static const uptr kHiAppMemEnd   = 0xffffffffffull;\n  static const uptr kAppMemMsk     = 0xfc00000000ull;\n  static const uptr kAppMemXor     = 0x0400000000ull;\n  static const uptr kVdsoBeg       = 0xfffff00000ull;\n};\n#elif defined(__aarch64__)\n// AArch64 supports multiple VMA which leads to multiple address transformation\n// functions.  To support these multiple VMAS transformations and mappings TSAN\n// runtime for AArch64 uses an external memory read (vmaSize) to select which\n// mapping to use.  Although slower, it make a same instrumented binary run on\n// multiple kernels.\n\n/*\nC/C++ on linux/aarch64 (39-bit VMA)\n0000 0010 00 - 0100 0000 00: main binary\n0100 0000 00 - 0800 0000 00: -\n0800 0000 00 - 2000 0000 00: shadow memory\n2000 0000 00 - 3100 0000 00: -\n3100 0000 00 - 3400 0000 00: metainfo\n3400 0000 00 - 5500 0000 00: -\n5500 0000 00 - 5600 0000 00: main binary (PIE)\n5600 0000 00 - 6000 0000 00: -\n6000 0000 00 - 6200 0000 00: traces\n6200 0000 00 - 7d00 0000 00: -\n7c00 0000 00 - 7d00 0000 00: heap\n7d00 0000 00 - 7fff ffff ff: modules and main thread stack\n*/\nstruct Mapping39 {\n  static const uptr kLoAppMemBeg   = 0x0000001000ull;\n  static const uptr kLoAppMemEnd   = 0x0100000000ull;\n  static const uptr kShadowBeg     = 0x0800000000ull;\n  static const uptr kShadowEnd     = 0x2000000000ull;\n  static const uptr kMetaShadowBeg = 0x3100000000ull;\n  static const uptr kMetaShadowEnd = 0x3400000000ull;\n  static const uptr kMidAppMemBeg  = 0x5500000000ull;\n  static const uptr kMidAppMemEnd  = 0x5600000000ull;\n  static const uptr kMidShadowOff  = 0x5000000000ull;\n  static const uptr kTraceMemBeg   = 0x6000000000ull;\n  static const uptr kTraceMemEnd   = 0x6200000000ull;\n  static const uptr kHeapMemBeg    = 0x7c00000000ull;\n  static const uptr kHeapMemEnd    = 0x7d00000000ull;\n  static const uptr kHiAppMemBeg   = 0x7e00000000ull;\n  static const uptr kHiAppMemEnd   = 0x7fffffffffull;\n  static const uptr kAppMemMsk     = 0x7800000000ull;\n  static const uptr kAppMemXor     = 0x0200000000ull;\n  static const uptr kVdsoBeg       = 0x7f00000000ull;\n};\n\n/*\nC/C++ on linux/aarch64 (42-bit VMA)\n00000 0010 00 - 01000 0000 00: main binary\n01000 0000 00 - 10000 0000 00: -\n10000 0000 00 - 20000 0000 00: shadow memory\n20000 0000 00 - 26000 0000 00: -\n26000 0000 00 - 28000 0000 00: metainfo\n28000 0000 00 - 2aa00 0000 00: -\n2aa00 0000 00 - 2ab00 0000 00: main binary (PIE)\n2ab00 0000 00 - 36200 0000 00: -\n36200 0000 00 - 36240 0000 00: traces\n36240 0000 00 - 3e000 0000 00: -\n3e000 0000 00 - 3f000 0000 00: heap\n3f000 0000 00 - 3ffff ffff ff: modules and main thread stack\n*/\nstruct Mapping42 {\n  static const uptr kLoAppMemBeg   = 0x00000001000ull;\n  static const uptr kLoAppMemEnd   = 0x01000000000ull;\n  static const uptr kShadowBeg     = 0x10000000000ull;\n  static const uptr kShadowEnd     = 0x20000000000ull;\n  static const uptr kMetaShadowBeg = 0x26000000000ull;\n  static const uptr kMetaShadowEnd = 0x28000000000ull;\n  static const uptr kMidAppMemBeg  = 0x2aa00000000ull;\n  static const uptr kMidAppMemEnd  = 0x2ab00000000ull;\n  static const uptr kMidShadowOff  = 0x28000000000ull;\n  static const uptr kTraceMemBeg   = 0x36200000000ull;\n  static const uptr kTraceMemEnd   = 0x36400000000ull;\n  static const uptr kHeapMemBeg    = 0x3e000000000ull;\n  static const uptr kHeapMemEnd    = 0x3f000000000ull;\n  static const uptr kHiAppMemBeg   = 0x3f000000000ull;\n  static const uptr kHiAppMemEnd   = 0x3ffffffffffull;\n  static const uptr kAppMemMsk     = 0x3c000000000ull;\n  static const uptr kAppMemXor     = 0x04000000000ull;\n  static const uptr kVdsoBeg       = 0x37f00000000ull;\n};\n\n// Indicates the runtime will define the memory regions at runtime.\n#define TSAN_RUNTIME_VMA 1\n// Indicates that mapping defines a mid range memory segment.\n#define TSAN_MID_APP_RANGE 1\n#elif defined(__powerpc64__)\n// PPC64 supports multiple VMA which leads to multiple address transformation\n// functions.  To support these multiple VMAS transformations and mappings TSAN\n// runtime for PPC64 uses an external memory read (vmaSize) to select which\n// mapping to use.  Although slower, it make a same instrumented binary run on\n// multiple kernels.\n\n/*\nC/C++ on linux/powerpc64 (44-bit VMA)\n0000 0000 0100 - 0001 0000 0000: main binary\n0001 0000 0000 - 0001 0000 0000: -\n0001 0000 0000 - 0b00 0000 0000: shadow\n0b00 0000 0000 - 0b00 0000 0000: -\n0b00 0000 0000 - 0d00 0000 0000: metainfo (memory blocks and sync objects)\n0d00 0000 0000 - 0d00 0000 0000: -\n0d00 0000 0000 - 0f00 0000 0000: traces\n0f00 0000 0000 - 0f00 0000 0000: -\n0f00 0000 0000 - 0f50 0000 0000: heap\n0f50 0000 0000 - 0f60 0000 0000: -\n0f60 0000 0000 - 1000 0000 0000: modules and main thread stack\n*/\nstruct Mapping44 {\n  static const uptr kMetaShadowBeg = 0x0b0000000000ull;\n  static const uptr kMetaShadowEnd = 0x0d0000000000ull;\n  static const uptr kTraceMemBeg   = 0x0d0000000000ull;\n  static const uptr kTraceMemEnd   = 0x0f0000000000ull;\n  static const uptr kShadowBeg     = 0x000100000000ull;\n  static const uptr kShadowEnd     = 0x0b0000000000ull;\n  static const uptr kLoAppMemBeg   = 0x000000000100ull;\n  static const uptr kLoAppMemEnd   = 0x000100000000ull;\n  static const uptr kHeapMemBeg    = 0x0f0000000000ull;\n  static const uptr kHeapMemEnd    = 0x0f5000000000ull;\n  static const uptr kHiAppMemBeg   = 0x0f6000000000ull;\n  static const uptr kHiAppMemEnd   = 0x100000000000ull; // 44 bits\n  static const uptr kAppMemMsk     = 0x0f0000000000ull;\n  static const uptr kAppMemXor     = 0x002100000000ull;\n  static const uptr kVdsoBeg       = 0x3c0000000000000ull;\n};\n\n/*\nC/C++ on linux/powerpc64 (46-bit VMA)\n0000 0000 1000 - 0100 0000 0000: main binary\n0100 0000 0000 - 0200 0000 0000: -\n0100 0000 0000 - 1000 0000 0000: shadow\n1000 0000 0000 - 1000 0000 0000: -\n1000 0000 0000 - 2000 0000 0000: metainfo (memory blocks and sync objects)\n2000 0000 0000 - 2000 0000 0000: -\n2000 0000 0000 - 2200 0000 0000: traces\n2200 0000 0000 - 3d00 0000 0000: -\n3d00 0000 0000 - 3e00 0000 0000: heap\n3e00 0000 0000 - 3e80 0000 0000: -\n3e80 0000 0000 - 4000 0000 0000: modules and main thread stack\n*/\nstruct Mapping46 {\n  static const uptr kMetaShadowBeg = 0x100000000000ull;\n  static const uptr kMetaShadowEnd = 0x200000000000ull;\n  static const uptr kTraceMemBeg   = 0x200000000000ull;\n  static const uptr kTraceMemEnd   = 0x220000000000ull;\n  static const uptr kShadowBeg     = 0x010000000000ull;\n  static const uptr kShadowEnd     = 0x100000000000ull;\n  static const uptr kHeapMemBeg    = 0x3d0000000000ull;\n  static const uptr kHeapMemEnd    = 0x3e0000000000ull;\n  static const uptr kLoAppMemBeg   = 0x000000001000ull;\n  static const uptr kLoAppMemEnd   = 0x010000000000ull;\n  static const uptr kHiAppMemBeg   = 0x3e8000000000ull;\n  static const uptr kHiAppMemEnd   = 0x400000000000ull; // 46 bits\n  static const uptr kAppMemMsk     = 0x3c0000000000ull;\n  static const uptr kAppMemXor     = 0x020000000000ull;\n  static const uptr kVdsoBeg       = 0x7800000000000000ull;\n};\n\n// Indicates the runtime will define the memory regions at runtime.\n#define TSAN_RUNTIME_VMA 1\n#endif\n\n#elif defined(SANITIZER_GO) && !SANITIZER_WINDOWS\n\n/* Go on linux, darwin and freebsd\n0000 0000 1000 - 0000 1000 0000: executable\n0000 1000 0000 - 00c0 0000 0000: -\n00c0 0000 0000 - 00e0 0000 0000: heap\n00e0 0000 0000 - 2000 0000 0000: -\n2000 0000 0000 - 2380 0000 0000: shadow\n2380 0000 0000 - 3000 0000 0000: -\n3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)\n4000 0000 0000 - 6000 0000 0000: -\n6000 0000 0000 - 6200 0000 0000: traces\n6200 0000 0000 - 8000 0000 0000: -\n*/\n\nstruct Mapping {\n  static const uptr kMetaShadowBeg = 0x300000000000ull;\n  static const uptr kMetaShadowEnd = 0x400000000000ull;\n  static const uptr kTraceMemBeg   = 0x600000000000ull;\n  static const uptr kTraceMemEnd   = 0x620000000000ull;\n  static const uptr kShadowBeg     = 0x200000000000ull;\n  static const uptr kShadowEnd     = 0x238000000000ull;\n  static const uptr kAppMemBeg     = 0x000000001000ull;\n  static const uptr kAppMemEnd     = 0x00e000000000ull;\n};\n\n#elif defined(SANITIZER_GO) && SANITIZER_WINDOWS\n\n/* Go on windows\n0000 0000 1000 - 0000 1000 0000: executable\n0000 1000 0000 - 00f8 0000 0000: -\n00c0 0000 0000 - 00e0 0000 0000: heap\n00e0 0000 0000 - 0100 0000 0000: -\n0100 0000 0000 - 0500 0000 0000: shadow\n0500 0000 0000 - 0560 0000 0000: -\n0560 0000 0000 - 0760 0000 0000: traces\n0760 0000 0000 - 07d0 0000 0000: metainfo (memory blocks and sync objects)\n07d0 0000 0000 - 8000 0000 0000: -\n*/\n\nstruct Mapping {\n  static const uptr kMetaShadowBeg = 0x076000000000ull;\n  static const uptr kMetaShadowEnd = 0x07d000000000ull;\n  static const uptr kTraceMemBeg   = 0x056000000000ull;\n  static const uptr kTraceMemEnd   = 0x076000000000ull;\n  static const uptr kShadowBeg     = 0x010000000000ull;\n  static const uptr kShadowEnd     = 0x050000000000ull;\n  static const uptr kAppMemBeg     = 0x000000001000ull;\n  static const uptr kAppMemEnd     = 0x00e000000000ull;\n}\n\n#else\n# error \"Unknown platform\"\n#endif\n\n\n#ifdef TSAN_RUNTIME_VMA\nextern uptr vmaSize;\n#endif\n\n\nenum MappingType {\n  MAPPING_LO_APP_BEG,\n  MAPPING_LO_APP_END,\n  MAPPING_HI_APP_BEG,\n  MAPPING_HI_APP_END,\n#ifdef TSAN_MID_APP_RANGE\n  MAPPING_MID_APP_BEG,\n  MAPPING_MID_APP_END,\n#endif\n  MAPPING_HEAP_BEG,\n  MAPPING_HEAP_END,\n  MAPPING_APP_BEG,\n  MAPPING_APP_END,\n  MAPPING_SHADOW_BEG,\n  MAPPING_SHADOW_END,\n  MAPPING_META_SHADOW_BEG,\n  MAPPING_META_SHADOW_END,\n  MAPPING_TRACE_BEG,\n  MAPPING_TRACE_END,\n  MAPPING_VDSO_BEG,\n};\n\ntemplate<typename Mapping, int Type>\nuptr MappingImpl(void) {\n  switch (Type) {\n#ifndef SANITIZER_GO\n    case MAPPING_LO_APP_BEG: return Mapping::kLoAppMemBeg;\n    case MAPPING_LO_APP_END: return Mapping::kLoAppMemEnd;\n# ifdef TSAN_MID_APP_RANGE\n    case MAPPING_MID_APP_BEG: return Mapping::kMidAppMemBeg;\n    case MAPPING_MID_APP_END: return Mapping::kMidAppMemEnd;\n# endif\n    case MAPPING_HI_APP_BEG: return Mapping::kHiAppMemBeg;\n    case MAPPING_HI_APP_END: return Mapping::kHiAppMemEnd;\n    case MAPPING_HEAP_BEG: return Mapping::kHeapMemBeg;\n    case MAPPING_HEAP_END: return Mapping::kHeapMemEnd;\n    case MAPPING_VDSO_BEG: return Mapping::kVdsoBeg;\n#else\n    case MAPPING_APP_BEG: return Mapping::kAppMemBeg;\n    case MAPPING_APP_END: return Mapping::kAppMemEnd;\n#endif\n    case MAPPING_SHADOW_BEG: return Mapping::kShadowBeg;\n    case MAPPING_SHADOW_END: return Mapping::kShadowEnd;\n    case MAPPING_META_SHADOW_BEG: return Mapping::kMetaShadowBeg;\n    case MAPPING_META_SHADOW_END: return Mapping::kMetaShadowEnd;\n    case MAPPING_TRACE_BEG: return Mapping::kTraceMemBeg;\n    case MAPPING_TRACE_END: return Mapping::kTraceMemEnd;\n  }\n}\n\ntemplate<int Type>\nuptr MappingArchImpl(void) {\n#ifdef __aarch64__\n  if (vmaSize == 39)\n    return MappingImpl<Mapping39, Type>();\n  else\n    return MappingImpl<Mapping42, Type>();\n  DCHECK(0);\n#elif defined(__powerpc64__)\n  if (vmaSize == 44)\n    return MappingImpl<Mapping44, Type>();\n  else\n    return MappingImpl<Mapping46, Type>();\n  DCHECK(0);\n#else\n  return MappingImpl<Mapping, Type>();\n#endif\n}\n\n#ifndef SANITIZER_GO\nALWAYS_INLINE\nuptr LoAppMemBeg(void) {\n  return MappingArchImpl<MAPPING_LO_APP_BEG>();\n}\nALWAYS_INLINE\nuptr LoAppMemEnd(void) {\n  return MappingArchImpl<MAPPING_LO_APP_END>();\n}\n\n#ifdef TSAN_MID_APP_RANGE\nALWAYS_INLINE\nuptr MidAppMemBeg(void) {\n  return MappingArchImpl<MAPPING_MID_APP_BEG>();\n}\nALWAYS_INLINE\nuptr MidAppMemEnd(void) {\n  return MappingArchImpl<MAPPING_MID_APP_END>();\n}\n#endif\n\nALWAYS_INLINE\nuptr HeapMemBeg(void) {\n  return MappingArchImpl<MAPPING_HEAP_BEG>();\n}\nALWAYS_INLINE\nuptr HeapMemEnd(void) {\n  return MappingArchImpl<MAPPING_HEAP_END>();\n}\n\nALWAYS_INLINE\nuptr HiAppMemBeg(void) {\n  return MappingArchImpl<MAPPING_HI_APP_BEG>();\n}\nALWAYS_INLINE\nuptr HiAppMemEnd(void) {\n  return MappingArchImpl<MAPPING_HI_APP_END>();\n}\n\nALWAYS_INLINE\nuptr VdsoBeg(void) {\n  return MappingArchImpl<MAPPING_VDSO_BEG>();\n}\n\n#else\n\nALWAYS_INLINE\nuptr AppMemBeg(void) {\n  return MappingArchImpl<MAPPING_APP_BEG>();\n}\nALWAYS_INLINE\nuptr AppMemEnd(void) {\n  return MappingArchImpl<MAPPING_APP_END>();\n}\n\n#endif\n\nstatic inline\nbool GetUserRegion(int i, uptr *start, uptr *end) {\n  switch (i) {\n  default:\n    return false;\n#ifndef SANITIZER_GO\n  case 0:\n    *start = LoAppMemBeg();\n    *end = LoAppMemEnd();\n    return true;\n  case 1:\n    *start = HiAppMemBeg();\n    *end = HiAppMemEnd();\n    return true;\n  case 2:\n    *start = HeapMemBeg();\n    *end = HeapMemEnd();\n    return true;\n# ifdef TSAN_MID_APP_RANGE\n  case 3:\n    *start = MidAppMemBeg();\n    *end = MidAppMemEnd();\n    return true;\n# endif\n#else\n  case 0:\n    *start = AppMemBeg();\n    *end = AppMemEnd();\n    return true;\n#endif\n  }\n}\n\nALWAYS_INLINE\nuptr ShadowBeg(void) {\n  return MappingArchImpl<MAPPING_SHADOW_BEG>();\n}\nALWAYS_INLINE\nuptr ShadowEnd(void) {\n  return MappingArchImpl<MAPPING_SHADOW_END>();\n}\n\nALWAYS_INLINE\nuptr MetaShadowBeg(void) {\n  return MappingArchImpl<MAPPING_META_SHADOW_BEG>();\n}\nALWAYS_INLINE\nuptr MetaShadowEnd(void) {\n  return MappingArchImpl<MAPPING_META_SHADOW_END>();\n}\n\nALWAYS_INLINE\nuptr TraceMemBeg(void) {\n  return MappingArchImpl<MAPPING_TRACE_BEG>();\n}\nALWAYS_INLINE\nuptr TraceMemEnd(void) {\n  return MappingArchImpl<MAPPING_TRACE_END>();\n}\n\n\ntemplate<typename Mapping>\nbool IsAppMemImpl(uptr mem) {\n#ifndef SANITIZER_GO\n  return (mem >= Mapping::kHeapMemBeg && mem < Mapping::kHeapMemEnd) ||\n# ifdef TSAN_MID_APP_RANGE\n         (mem >= Mapping::kMidAppMemBeg && mem < Mapping::kMidAppMemEnd) ||\n# endif\n         (mem >= Mapping::kLoAppMemBeg && mem < Mapping::kLoAppMemEnd) ||\n         (mem >= Mapping::kHiAppMemBeg && mem < Mapping::kHiAppMemEnd);\n#else\n  return mem >= Mapping::kAppMemBeg && mem < Mapping::kAppMemEnd;\n#endif\n}\n\nALWAYS_INLINE\nbool IsAppMem(uptr mem) {\n#ifdef __aarch64__\n  if (vmaSize == 39)\n    return IsAppMemImpl<Mapping39>(mem);\n  else\n    return IsAppMemImpl<Mapping42>(mem);\n  DCHECK(0);\n#elif defined(__powerpc64__)\n  if (vmaSize == 44)\n    return IsAppMemImpl<Mapping44>(mem);\n  else\n    return IsAppMemImpl<Mapping46>(mem);\n  DCHECK(0);\n#else\n  return IsAppMemImpl<Mapping>(mem);\n#endif\n}\n\n\ntemplate<typename Mapping>\nbool IsShadowMemImpl(uptr mem) {\n  return mem >= Mapping::kShadowBeg && mem <= Mapping::kShadowEnd;\n}\n\nALWAYS_INLINE\nbool IsShadowMem(uptr mem) {\n#ifdef __aarch64__\n  if (vmaSize == 39)\n    return IsShadowMemImpl<Mapping39>(mem);\n  else\n    return IsShadowMemImpl<Mapping42>(mem);\n  DCHECK(0);\n#elif defined(__powerpc64__)\n  if (vmaSize == 44)\n    return IsShadowMemImpl<Mapping44>(mem);\n  else\n    return IsShadowMemImpl<Mapping46>(mem);\n  DCHECK(0);\n#else\n  return IsShadowMemImpl<Mapping>(mem);\n#endif\n}\n\n\ntemplate<typename Mapping>\nbool IsMetaMemImpl(uptr mem) {\n  return mem >= Mapping::kMetaShadowBeg && mem <= Mapping::kMetaShadowEnd;\n}\n\nALWAYS_INLINE\nbool IsMetaMem(uptr mem) {\n#ifdef __aarch64__\n  if (vmaSize == 39)\n    return IsMetaMemImpl<Mapping39>(mem);\n  else\n    return IsMetaMemImpl<Mapping42>(mem);\n  DCHECK(0);\n#elif defined(__powerpc64__)\n  if (vmaSize == 44)\n    return IsMetaMemImpl<Mapping44>(mem);\n  else\n    return IsMetaMemImpl<Mapping46>(mem);\n  DCHECK(0);\n#else\n  return IsMetaMemImpl<Mapping>(mem);\n#endif\n}\n\n\ntemplate<typename Mapping>\nuptr MemToShadowImpl(uptr x) {\n  DCHECK(IsAppMem(x));\n#ifndef SANITIZER_GO\n  return (((x) & ~(Mapping::kAppMemMsk | (kShadowCell - 1)))\n      ^ Mapping::kAppMemXor) * kShadowCnt;\n#else\n  return ((x & ~(kShadowCell - 1)) * kShadowCnt) | Mapping::kShadowBeg;\n#endif\n}\n\nALWAYS_INLINE\nuptr MemToShadow(uptr x) {\n#ifdef __aarch64__\n  if (vmaSize == 39)\n    return MemToShadowImpl<Mapping39>(x);\n  else\n    return MemToShadowImpl<Mapping42>(x);\n  DCHECK(0);\n#elif defined(__powerpc64__)\n  if (vmaSize == 44)\n    return MemToShadowImpl<Mapping44>(x);\n  else\n    return MemToShadowImpl<Mapping46>(x);\n  DCHECK(0);\n#else\n  return MemToShadowImpl<Mapping>(x);\n#endif\n}\n\n\ntemplate<typename Mapping>\nu32 *MemToMetaImpl(uptr x) {\n  DCHECK(IsAppMem(x));\n#ifndef SANITIZER_GO\n  return (u32*)(((((x) & ~(Mapping::kAppMemMsk | (kMetaShadowCell - 1)))\n        ^ Mapping::kAppMemXor) / kMetaShadowCell * kMetaShadowSize)\n          | Mapping::kMetaShadowBeg);\n#else\n  return (u32*)(((x & ~(kMetaShadowCell - 1)) / \\\n      kMetaShadowCell * kMetaShadowSize) | Mapping::kMetaShadowBeg);\n#endif\n}\n\nALWAYS_INLINE\nu32 *MemToMeta(uptr x) {\n#ifdef __aarch64__\n  if (vmaSize == 39)\n    return MemToMetaImpl<Mapping39>(x);\n  else\n    return MemToMetaImpl<Mapping42>(x);\n  DCHECK(0);\n#elif defined(__powerpc64__)\n  if (vmaSize == 44)\n    return MemToMetaImpl<Mapping44>(x);\n  else\n    return MemToMetaImpl<Mapping46>(x);\n  DCHECK(0);\n#else\n  return MemToMetaImpl<Mapping>(x);\n#endif\n}\n\n\ntemplate<typename Mapping>\nuptr ShadowToMemImpl(uptr s) {\n  DCHECK(IsShadowMem(s));\n#ifndef SANITIZER_GO\n  if (s >= MemToShadow(Mapping::kLoAppMemBeg)\n      && s <= MemToShadow(Mapping::kLoAppMemEnd - 1))\n    return (s / kShadowCnt) ^ Mapping::kAppMemXor;\n# ifdef TSAN_MID_APP_RANGE\n  if (s >= MemToShadow(Mapping::kMidAppMemBeg)\n      && s <= MemToShadow(Mapping::kMidAppMemEnd - 1))\n    return ((s / kShadowCnt) ^ Mapping::kAppMemXor) + Mapping::kMidShadowOff;\n# endif\n  else\n    return ((s / kShadowCnt) ^ Mapping::kAppMemXor) | Mapping::kAppMemMsk;\n#else\n# ifndef SANITIZER_WINDOWS\n  return (s & ~Mapping::kShadowBeg) / kShadowCnt;\n# else\n  // FIXME(dvyukov): this is most likely wrong as the mapping is not bijection.\n  return (s - Mapping::kShadowBeg) / kShadowCnt;\n# endif // SANITIZER_WINDOWS\n#endif\n}\n\nALWAYS_INLINE\nuptr ShadowToMem(uptr s) {\n#ifdef __aarch64__\n  if (vmaSize == 39)\n    return ShadowToMemImpl<Mapping39>(s);\n  else\n    return ShadowToMemImpl<Mapping42>(s);\n  DCHECK(0);\n#elif defined(__powerpc64__)\n  if (vmaSize == 44)\n    return ShadowToMemImpl<Mapping44>(s);\n  else\n    return ShadowToMemImpl<Mapping46>(s);\n  DCHECK(0);\n#else\n  return ShadowToMemImpl<Mapping>(s);\n#endif\n}\n\n\n\n// The additional page is to catch shadow stack overflow as paging fault.\n// Windows wants 64K alignment for mmaps.\nconst uptr kTotalTraceSize = (kTraceSize * sizeof(Event) + sizeof(Trace)\n    + (64 << 10) + (64 << 10) - 1) & ~((64 << 10) - 1);\n\ntemplate<typename Mapping>\nuptr GetThreadTraceImpl(int tid) {\n  uptr p = Mapping::kTraceMemBeg + (uptr)tid * kTotalTraceSize;\n  DCHECK_LT(p, Mapping::kTraceMemEnd);\n  return p;\n}\n\nALWAYS_INLINE\nuptr GetThreadTrace(int tid) {\n#ifdef __aarch64__\n  if (vmaSize == 39)\n    return GetThreadTraceImpl<Mapping39>(tid);\n  else\n    return GetThreadTraceImpl<Mapping42>(tid);\n  DCHECK(0);\n#elif defined(__powerpc64__)\n  if (vmaSize == 44)\n    return GetThreadTraceImpl<Mapping44>(tid);\n  else\n    return GetThreadTraceImpl<Mapping46>(tid);\n  DCHECK(0);\n#else\n  return GetThreadTraceImpl<Mapping>(tid);\n#endif\n}\n\n\ntemplate<typename Mapping>\nuptr GetThreadTraceHeaderImpl(int tid) {\n  uptr p = Mapping::kTraceMemBeg + (uptr)tid * kTotalTraceSize\n      + kTraceSize * sizeof(Event);\n  DCHECK_LT(p, Mapping::kTraceMemEnd);\n  return p;\n}\n\nALWAYS_INLINE\nuptr GetThreadTraceHeader(int tid) {\n#ifdef __aarch64__\n  if (vmaSize == 39)\n    return GetThreadTraceHeaderImpl<Mapping39>(tid);\n  else\n    return GetThreadTraceHeaderImpl<Mapping42>(tid);\n  DCHECK(0);\n#elif defined(__powerpc64__)\n  if (vmaSize == 44)\n    return GetThreadTraceHeaderImpl<Mapping44>(tid);\n  else\n    return GetThreadTraceHeaderImpl<Mapping46>(tid);\n  DCHECK(0);\n#else\n  return GetThreadTraceHeaderImpl<Mapping>(tid);\n#endif\n}\n\nvoid InitializePlatform();\nvoid InitializePlatformEarly();\nvoid CheckAndProtect();\nvoid InitializeShadowMemoryPlatform();\nvoid FlushShadowMemory();\nvoid WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive);\n\n// Says whether the addr relates to a global var.\n// Guesses with high probability, may yield both false positives and negatives.\nbool IsGlobalVar(uptr addr);\nint ExtractResolvFDs(void *state, int *fds, int nfd);\nint ExtractRecvmsgFDs(void *msg, int *fds, int nfd);\n\nint call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,\n    void *abstime), void *c, void *m, void *abstime,\n    void(*cleanup)(void *arg), void *arg);\n\nvoid DestroyThreadState();\n\n}  // namespace __tsan\n\n#endif  // TSAN_PLATFORM_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc",
    "content": "//===-- tsan_platform_linux.cc --------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Linux- and FreeBSD-specific code.\n//===----------------------------------------------------------------------===//\n\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_LINUX || SANITIZER_FREEBSD\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_posix.h\"\n#include \"sanitizer_common/sanitizer_procmaps.h\"\n#include \"sanitizer_common/sanitizer_stoptheworld.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n#include \"tsan_platform.h\"\n#include \"tsan_rtl.h\"\n#include \"tsan_flags.h\"\n\n#include <fcntl.h>\n#include <pthread.h>\n#include <signal.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdarg.h>\n#include <sys/mman.h>\n#include <sys/syscall.h>\n#include <sys/socket.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <sys/resource.h>\n#include <sys/stat.h>\n#include <unistd.h>\n#include <errno.h>\n#include <sched.h>\n#include <dlfcn.h>\n#if SANITIZER_LINUX\n#define __need_res_state\n#include <resolv.h>\n#endif\n\n#ifdef sa_handler\n# undef sa_handler\n#endif\n\n#ifdef sa_sigaction\n# undef sa_sigaction\n#endif\n\n#if SANITIZER_FREEBSD\nextern \"C\" void *__libc_stack_end;\nvoid *__libc_stack_end = 0;\n#endif\n\nnamespace __tsan {\n\nstatic uptr g_data_start;\nstatic uptr g_data_end;\n\n#ifdef TSAN_RUNTIME_VMA\n// Runtime detected VMA size.\nuptr vmaSize;\n#endif\n\nenum {\n  MemTotal  = 0,\n  MemShadow = 1,\n  MemMeta   = 2,\n  MemFile   = 3,\n  MemMmap   = 4,\n  MemTrace  = 5,\n  MemHeap   = 6,\n  MemOther  = 7,\n  MemCount  = 8,\n};\n\nvoid FillProfileCallback(uptr p, uptr rss, bool file,\n                         uptr *mem, uptr stats_size) {\n  mem[MemTotal] += rss;\n  if (p >= ShadowBeg() && p < ShadowEnd())\n    mem[MemShadow] += rss;\n  else if (p >= MetaShadowBeg() && p < MetaShadowEnd())\n    mem[MemMeta] += rss;\n#ifndef SANITIZER_GO\n  else if (p >= HeapMemBeg() && p < HeapMemEnd())\n    mem[MemHeap] += rss;\n  else if (p >= LoAppMemBeg() && p < LoAppMemEnd())\n    mem[file ? MemFile : MemMmap] += rss;\n  else if (p >= HiAppMemBeg() && p < HiAppMemEnd())\n    mem[file ? MemFile : MemMmap] += rss;\n#else\n  else if (p >= AppMemBeg() && p < AppMemEnd())\n    mem[file ? MemFile : MemMmap] += rss;\n#endif\n  else if (p >= TraceMemBeg() && p < TraceMemEnd())\n    mem[MemTrace] += rss;\n  else\n    mem[MemOther] += rss;\n}\n\nvoid WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive) {\n  uptr mem[MemCount];\n  internal_memset(mem, 0, sizeof(mem[0]) * MemCount);\n  __sanitizer::GetMemoryProfile(FillProfileCallback, mem, 7);\n  StackDepotStats *stacks = StackDepotGetStats();\n  internal_snprintf(buf, buf_size,\n      \"RSS %zd MB: shadow:%zd meta:%zd file:%zd mmap:%zd\"\n      \" trace:%zd heap:%zd other:%zd stacks=%zd[%zd] nthr=%zd/%zd\\n\",\n      mem[MemTotal] >> 20, mem[MemShadow] >> 20, mem[MemMeta] >> 20,\n      mem[MemFile] >> 20, mem[MemMmap] >> 20, mem[MemTrace] >> 20,\n      mem[MemHeap] >> 20, mem[MemOther] >> 20,\n      stacks->allocated >> 20, stacks->n_uniq_ids,\n      nlive, nthread);\n}\n\n#if SANITIZER_LINUX\nvoid FlushShadowMemoryCallback(\n    const SuspendedThreadsList &suspended_threads_list,\n    void *argument) {\n  FlushUnneededShadowMemory(ShadowBeg(), ShadowEnd() - ShadowBeg());\n}\n#endif\n\nvoid FlushShadowMemory() {\n#if SANITIZER_LINUX\n  StopTheWorld(FlushShadowMemoryCallback, 0);\n#endif\n}\n\n#ifndef SANITIZER_GO\n// Mark shadow for .rodata sections with the special kShadowRodata marker.\n// Accesses to .rodata can't race, so this saves time, memory and trace space.\nstatic void MapRodata() {\n  // First create temp file.\n  const char *tmpdir = GetEnv(\"TMPDIR\");\n  if (tmpdir == 0)\n    tmpdir = GetEnv(\"TEST_TMPDIR\");\n#ifdef P_tmpdir\n  if (tmpdir == 0)\n    tmpdir = P_tmpdir;\n#endif\n  if (tmpdir == 0)\n    return;\n  char name[256];\n  internal_snprintf(name, sizeof(name), \"%s/tsan.rodata.%d\",\n                    tmpdir, (int)internal_getpid());\n  uptr openrv = internal_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);\n  if (internal_iserror(openrv))\n    return;\n  internal_unlink(name);  // Unlink it now, so that we can reuse the buffer.\n  fd_t fd = openrv;\n  // Fill the file with kShadowRodata.\n  const uptr kMarkerSize = 512 * 1024 / sizeof(u64);\n  InternalScopedBuffer<u64> marker(kMarkerSize);\n  // volatile to prevent insertion of memset\n  for (volatile u64 *p = marker.data(); p < marker.data() + kMarkerSize; p++)\n    *p = kShadowRodata;\n  internal_write(fd, marker.data(), marker.size());\n  // Map the file into memory.\n  uptr page = internal_mmap(0, GetPageSizeCached(), PROT_READ | PROT_WRITE,\n                            MAP_PRIVATE | MAP_ANONYMOUS, fd, 0);\n  if (internal_iserror(page)) {\n    internal_close(fd);\n    return;\n  }\n  // Map the file into shadow of .rodata sections.\n  MemoryMappingLayout proc_maps(/*cache_enabled*/true);\n  uptr start, end, offset, prot;\n  // Reusing the buffer 'name'.\n  while (proc_maps.Next(&start, &end, &offset, name, ARRAY_SIZE(name), &prot)) {\n    if (name[0] != 0 && name[0] != '['\n        && (prot & MemoryMappingLayout::kProtectionRead)\n        && (prot & MemoryMappingLayout::kProtectionExecute)\n        && !(prot & MemoryMappingLayout::kProtectionWrite)\n        && IsAppMem(start)) {\n      // Assume it's .rodata\n      char *shadow_start = (char*)MemToShadow(start);\n      char *shadow_end = (char*)MemToShadow(end);\n      for (char *p = shadow_start; p < shadow_end; p += marker.size()) {\n        internal_mmap(p, Min<uptr>(marker.size(), shadow_end - p),\n                      PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, 0);\n      }\n    }\n  }\n  internal_close(fd);\n}\n\nvoid InitializeShadowMemoryPlatform() {\n  MapRodata();\n}\n\nstatic void InitDataSeg() {\n  MemoryMappingLayout proc_maps(true);\n  uptr start, end, offset;\n  char name[128];\n#if SANITIZER_FREEBSD\n  // On FreeBSD BSS is usually the last block allocated within the\n  // low range and heap is the last block allocated within the range\n  // 0x800000000-0x8ffffffff.\n  while (proc_maps.Next(&start, &end, &offset, name, ARRAY_SIZE(name),\n                        /*protection*/ 0)) {\n    DPrintf(\"%p-%p %p %s\\n\", start, end, offset, name);\n    if ((start & 0xffff00000000ULL) == 0 && (end & 0xffff00000000ULL) == 0 &&\n        name[0] == '\\0') {\n      g_data_start = start;\n      g_data_end = end;\n    }\n  }\n#else\n  bool prev_is_data = false;\n  while (proc_maps.Next(&start, &end, &offset, name, ARRAY_SIZE(name),\n                        /*protection*/ 0)) {\n    DPrintf(\"%p-%p %p %s\\n\", start, end, offset, name);\n    bool is_data = offset != 0 && name[0] != 0;\n    // BSS may get merged with [heap] in /proc/self/maps. This is not very\n    // reliable.\n    bool is_bss = offset == 0 &&\n      (name[0] == 0 || internal_strcmp(name, \"[heap]\") == 0) && prev_is_data;\n    if (g_data_start == 0 && is_data)\n      g_data_start = start;\n    if (is_bss)\n      g_data_end = end;\n    prev_is_data = is_data;\n  }\n#endif\n  DPrintf(\"guessed data_start=%p data_end=%p\\n\",  g_data_start, g_data_end);\n  CHECK_LT(g_data_start, g_data_end);\n  CHECK_GE((uptr)&g_data_start, g_data_start);\n  CHECK_LT((uptr)&g_data_start, g_data_end);\n}\n\n#endif  // #ifndef SANITIZER_GO\n\nvoid InitializePlatformEarly() {\n#ifdef TSAN_RUNTIME_VMA\n  vmaSize =\n    (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1);\n#if defined(__aarch64__)\n  if (vmaSize != 39 && vmaSize != 42) {\n    Printf(\"FATAL: ThreadSanitizer: unsupported VMA range\\n\");\n    Printf(\"FATAL: Found %d - Supported 39 and 42\\n\", vmaSize);\n    Die();\n  }\n#elif defined(__powerpc64__)\n  if (vmaSize != 44 && vmaSize != 46) {\n    Printf(\"FATAL: ThreadSanitizer: unsupported VMA range\\n\");\n    Printf(\"FATAL: Found %d - Supported 44 and 46\\n\", vmaSize);\n    Die();\n  }\n#endif\n#endif\n}\n\nvoid InitializePlatform() {\n  DisableCoreDumperIfNecessary();\n\n  // Go maps shadow memory lazily and works fine with limited address space.\n  // Unlimited stack is not a problem as well, because the executable\n  // is not compiled with -pie.\n  if (kCppMode) {\n    bool reexec = false;\n    // TSan doesn't play well with unlimited stack size (as stack\n    // overlaps with shadow memory). If we detect unlimited stack size,\n    // we re-exec the program with limited stack size as a best effort.\n    if (StackSizeIsUnlimited()) {\n      const uptr kMaxStackSize = 32 * 1024 * 1024;\n      VReport(1, \"Program is run with unlimited stack size, which wouldn't \"\n                 \"work with ThreadSanitizer.\\n\"\n                 \"Re-execing with stack size limited to %zd bytes.\\n\",\n              kMaxStackSize);\n      SetStackSizeLimitInBytes(kMaxStackSize);\n      reexec = true;\n    }\n\n    if (!AddressSpaceIsUnlimited()) {\n      Report(\"WARNING: Program is run with limited virtual address space,\"\n             \" which wouldn't work with ThreadSanitizer.\\n\");\n      Report(\"Re-execing with unlimited virtual address space.\\n\");\n      SetAddressSpaceUnlimited();\n      reexec = true;\n    }\n    if (reexec)\n      ReExec();\n  }\n\n#ifndef SANITIZER_GO\n  CheckAndProtect();\n  InitTlsSize();\n  InitDataSeg();\n#endif\n}\n\nbool IsGlobalVar(uptr addr) {\n  return g_data_start && addr >= g_data_start && addr < g_data_end;\n}\n\n#ifndef SANITIZER_GO\n// Extract file descriptors passed to glibc internal __res_iclose function.\n// This is required to properly \"close\" the fds, because we do not see internal\n// closes within glibc. The code is a pure hack.\nint ExtractResolvFDs(void *state, int *fds, int nfd) {\n#if SANITIZER_LINUX && !SANITIZER_ANDROID\n  int cnt = 0;\n  __res_state *statp = (__res_state*)state;\n  for (int i = 0; i < MAXNS && cnt < nfd; i++) {\n    if (statp->_u._ext.nsaddrs[i] && statp->_u._ext.nssocks[i] != -1)\n      fds[cnt++] = statp->_u._ext.nssocks[i];\n  }\n  return cnt;\n#else\n  return 0;\n#endif\n}\n\n// Extract file descriptors passed via UNIX domain sockets.\n// This is requried to properly handle \"open\" of these fds.\n// see 'man recvmsg' and 'man 3 cmsg'.\nint ExtractRecvmsgFDs(void *msgp, int *fds, int nfd) {\n  int res = 0;\n  msghdr *msg = (msghdr*)msgp;\n  struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);\n  for (; cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {\n    if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS)\n      continue;\n    int n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(fds[0]);\n    for (int i = 0; i < n; i++) {\n      fds[res++] = ((int*)CMSG_DATA(cmsg))[i];\n      if (res == nfd)\n        return res;\n    }\n  }\n  return res;\n}\n\n// Note: this function runs with async signals enabled,\n// so it must not touch any tsan state.\nint call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,\n    void *abstime), void *c, void *m, void *abstime,\n    void(*cleanup)(void *arg), void *arg) {\n  // pthread_cleanup_push/pop are hardcore macros mess.\n  // We can't intercept nor call them w/o including pthread.h.\n  int res;\n  pthread_cleanup_push(cleanup, arg);\n  res = fn(c, m, abstime);\n  pthread_cleanup_pop(0);\n  return res;\n}\n#endif\n\n#ifndef SANITIZER_GO\nvoid ReplaceSystemMalloc() { }\n#endif\n\n}  // namespace __tsan\n\n#endif  // SANITIZER_LINUX || SANITIZER_FREEBSD\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cc",
    "content": "//===-- tsan_platform_mac.cc ----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Mac-specific code.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_MAC\n\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_posix.h\"\n#include \"sanitizer_common/sanitizer_procmaps.h\"\n#include \"tsan_platform.h\"\n#include \"tsan_rtl.h\"\n#include \"tsan_flags.h\"\n\n#include <pthread.h>\n#include <signal.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdarg.h>\n#include <sys/mman.h>\n#include <sys/syscall.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <sys/resource.h>\n#include <sys/stat.h>\n#include <unistd.h>\n#include <errno.h>\n#include <sched.h>\n\nnamespace __tsan {\n\n#ifndef SANITIZER_GO\nstatic void *SignalSafeGetOrAllocate(uptr *dst, uptr size) {\n  atomic_uintptr_t *a = (atomic_uintptr_t *)dst;\n  void *val = (void *)atomic_load_relaxed(a);\n  atomic_signal_fence(memory_order_acquire);  // Turns the previous load into\n                                              // acquire wrt signals.\n  if (UNLIKELY(val == nullptr)) {\n    val = (void *)internal_mmap(nullptr, size, PROT_READ | PROT_WRITE,\n                                MAP_PRIVATE | MAP_ANON, -1, 0);\n    CHECK(val);\n    void *cmp = nullptr;\n    if (!atomic_compare_exchange_strong(a, (uintptr_t *)&cmp, (uintptr_t)val,\n                                        memory_order_acq_rel)) {\n      internal_munmap(val, size);\n      val = cmp;\n    }\n  }\n  return val;\n}\n\n// On OS X, accessing TLVs via __thread or manually by using pthread_key_* is\n// problematic, because there are several places where interceptors are called\n// when TLVs are not accessible (early process startup, thread cleanup, ...).\n// The following provides a \"poor man's TLV\" implementation, where we use the\n// shadow memory of the pointer returned by pthread_self() to store a pointer to\n// the ThreadState object. The main thread's ThreadState pointer is stored\n// separately in a static variable, because we need to access it even before the\n// shadow memory is set up.\nstatic uptr main_thread_identity = 0;\nstatic ThreadState *main_thread_state = nullptr;\n\nThreadState *cur_thread() {\n  ThreadState **fake_tls;\n  uptr thread_identity = (uptr)pthread_self();\n  if (thread_identity == main_thread_identity || main_thread_identity == 0) {\n    fake_tls = &main_thread_state;\n  } else {\n    fake_tls = (ThreadState **)MemToShadow(thread_identity);\n  }\n  ThreadState *thr = (ThreadState *)SignalSafeGetOrAllocate(\n      (uptr *)fake_tls, sizeof(ThreadState));\n  return thr;\n}\n\n// TODO(kuba.brecka): This is not async-signal-safe. In particular, we call\n// munmap first and then clear `fake_tls`; if we receive a signal in between,\n// handler will try to access the unmapped ThreadState.\nvoid cur_thread_finalize() {\n  uptr thread_identity = (uptr)pthread_self();\n  CHECK_NE(thread_identity, main_thread_identity);\n  ThreadState **fake_tls = (ThreadState **)MemToShadow(thread_identity);\n  internal_munmap(*fake_tls, sizeof(ThreadState));\n  *fake_tls = nullptr;\n}\n#endif\n\nuptr GetShadowMemoryConsumption() {\n  return 0;\n}\n\nvoid FlushShadowMemory() {\n}\n\nvoid WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive) {\n}\n\n#ifndef SANITIZER_GO\nvoid InitializeShadowMemoryPlatform() { }\n\n// On OS X, GCD worker threads are created without a call to pthread_create. We\n// need to properly register these threads with ThreadCreate and ThreadStart.\n// These threads don't have a parent thread, as they are created \"spuriously\".\n// We're using a libpthread API that notifies us about a newly created thread.\n// The `thread == pthread_self()` check indicates this is actually a worker\n// thread. If it's just a regular thread, this hook is called on the parent\n// thread.\ntypedef void (*pthread_introspection_hook_t)(unsigned int event,\n                                             pthread_t thread, void *addr,\n                                             size_t size);\nextern \"C\" pthread_introspection_hook_t pthread_introspection_hook_install(\n    pthread_introspection_hook_t hook);\nstatic const uptr PTHREAD_INTROSPECTION_THREAD_CREATE = 1;\nstatic const uptr PTHREAD_INTROSPECTION_THREAD_TERMINATE = 3;\nstatic pthread_introspection_hook_t prev_pthread_introspection_hook;\nstatic void my_pthread_introspection_hook(unsigned int event, pthread_t thread,\n                                          void *addr, size_t size) {\n  if (event == PTHREAD_INTROSPECTION_THREAD_CREATE) {\n    if (thread == pthread_self()) {\n      // The current thread is a newly created GCD worker thread.\n      ThreadState *parent_thread_state = nullptr;  // No parent.\n      int tid = ThreadCreate(parent_thread_state, 0, (uptr)thread, true);\n      CHECK_NE(tid, 0);\n      ThreadState *thr = cur_thread();\n      ThreadStart(thr, tid, GetTid());\n    }\n  } else if (event == PTHREAD_INTROSPECTION_THREAD_TERMINATE) {\n    if (thread == pthread_self()) {\n      ThreadState *thr = cur_thread();\n      if (thr->tctx) {\n        DestroyThreadState();\n      }\n    }\n  }\n\n  if (prev_pthread_introspection_hook != nullptr)\n    prev_pthread_introspection_hook(event, thread, addr, size);\n}\n#endif\n\nvoid InitializePlatformEarly() {\n}\n\nvoid InitializePlatform() {\n  DisableCoreDumperIfNecessary();\n#ifndef SANITIZER_GO\n  CheckAndProtect();\n\n  CHECK_EQ(main_thread_identity, 0);\n  main_thread_identity = (uptr)pthread_self();\n\n  prev_pthread_introspection_hook =\n      pthread_introspection_hook_install(&my_pthread_introspection_hook);\n#endif\n}\n\n#ifndef SANITIZER_GO\n// Note: this function runs with async signals enabled,\n// so it must not touch any tsan state.\nint call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,\n    void *abstime), void *c, void *m, void *abstime,\n    void(*cleanup)(void *arg), void *arg) {\n  // pthread_cleanup_push/pop are hardcore macros mess.\n  // We can't intercept nor call them w/o including pthread.h.\n  int res;\n  pthread_cleanup_push(cleanup, arg);\n  res = fn(c, m, abstime);\n  pthread_cleanup_pop(0);\n  return res;\n}\n#endif\n\nbool IsGlobalVar(uptr addr) {\n  return false;\n}\n\n}  // namespace __tsan\n\n#endif  // SANITIZER_MAC\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_platform_posix.cc",
    "content": "//===-- tsan_platform_posix.cc --------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// POSIX-specific code.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_POSIX\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_procmaps.h\"\n#include \"tsan_platform.h\"\n#include \"tsan_rtl.h\"\n\nnamespace __tsan {\n\n#ifndef SANITIZER_GO\nvoid InitializeShadowMemory() {\n  // Map memory shadow.\n  uptr shadow =\n      (uptr)MmapFixedNoReserve(ShadowBeg(), ShadowEnd() - ShadowBeg(),\n                               \"shadow\");\n  if (shadow != ShadowBeg()) {\n    Printf(\"FATAL: ThreadSanitizer can not mmap the shadow memory\\n\");\n    Printf(\"FATAL: Make sure to compile with -fPIE and \"\n               \"to link with -pie (%p, %p).\\n\", shadow, ShadowBeg());\n    Die();\n  }\n  // This memory range is used for thread stacks and large user mmaps.\n  // Frequently a thread uses only a small part of stack and similarly\n  // a program uses a small part of large mmap. On some programs\n  // we see 20% memory usage reduction without huge pages for this range.\n  // FIXME: don't use constants here.\n#if defined(__x86_64__)\n  const uptr kMadviseRangeBeg  = 0x7f0000000000ull;\n  const uptr kMadviseRangeSize = 0x010000000000ull;\n#elif defined(__mips64)\n  const uptr kMadviseRangeBeg  = 0xff00000000ull;\n  const uptr kMadviseRangeSize = 0x0100000000ull;\n#elif defined(__aarch64__)\n  uptr kMadviseRangeBeg = 0;\n  uptr kMadviseRangeSize = 0;\n  if (vmaSize == 39) {\n    kMadviseRangeBeg  = 0x7d00000000ull;\n    kMadviseRangeSize = 0x0300000000ull;\n  } else if (vmaSize == 42) {\n    kMadviseRangeBeg  = 0x3f000000000ull;\n    kMadviseRangeSize = 0x01000000000ull;\n  } else {\n    DCHECK(0);\n  }\n#elif defined(__powerpc64__)\n  uptr kMadviseRangeBeg = 0;\n  uptr kMadviseRangeSize = 0;\n  if (vmaSize == 44) {\n    kMadviseRangeBeg  = 0x0f60000000ull;\n    kMadviseRangeSize = 0x0010000000ull;\n  } else if (vmaSize == 46) {\n    kMadviseRangeBeg  = 0x3f0000000000ull;\n    kMadviseRangeSize = 0x010000000000ull;\n  } else {\n    DCHECK(0);\n  }\n#endif\n  NoHugePagesInRegion(MemToShadow(kMadviseRangeBeg),\n                      kMadviseRangeSize * kShadowMultiplier);\n  // Meta shadow is compressing and we don't flush it,\n  // so it makes sense to mark it as NOHUGEPAGE to not over-allocate memory.\n  // On one program it reduces memory consumption from 5GB to 2.5GB.\n  NoHugePagesInRegion(MetaShadowBeg(), MetaShadowEnd() - MetaShadowBeg());\n  if (common_flags()->use_madv_dontdump)\n    DontDumpShadowMemory(ShadowBeg(), ShadowEnd() - ShadowBeg());\n  DPrintf(\"memory shadow: %zx-%zx (%zuGB)\\n\",\n      ShadowBeg(), ShadowEnd(),\n      (ShadowEnd() - ShadowBeg()) >> 30);\n\n  // Map meta shadow.\n  uptr meta_size = MetaShadowEnd() - MetaShadowBeg();\n  uptr meta =\n      (uptr)MmapFixedNoReserve(MetaShadowBeg(), meta_size, \"meta shadow\");\n  if (meta != MetaShadowBeg()) {\n    Printf(\"FATAL: ThreadSanitizer can not mmap the shadow memory\\n\");\n    Printf(\"FATAL: Make sure to compile with -fPIE and \"\n               \"to link with -pie (%p, %p).\\n\", meta, MetaShadowBeg());\n    Die();\n  }\n  if (common_flags()->use_madv_dontdump)\n    DontDumpShadowMemory(meta, meta_size);\n  DPrintf(\"meta shadow: %zx-%zx (%zuGB)\\n\",\n      meta, meta + meta_size, meta_size >> 30);\n\n  InitializeShadowMemoryPlatform();\n}\n\nstatic void ProtectRange(uptr beg, uptr end) {\n  CHECK_LE(beg, end);\n  if (beg == end)\n    return;\n  if (beg != (uptr)MmapNoAccess(beg, end - beg)) {\n    Printf(\"FATAL: ThreadSanitizer can not protect [%zx,%zx]\\n\", beg, end);\n    Printf(\"FATAL: Make sure you are not using unlimited stack\\n\");\n    Die();\n  }\n}\n\nvoid CheckAndProtect() {\n  // Ensure that the binary is indeed compiled with -pie.\n  MemoryMappingLayout proc_maps(true);\n  uptr p, end, prot;\n  while (proc_maps.Next(&p, &end, 0, 0, 0, &prot)) {\n    if (IsAppMem(p))\n      continue;\n    if (p >= HeapMemEnd() &&\n        p < HeapEnd())\n      continue;\n    if (prot == 0)  // Zero page or mprotected.\n      continue;\n    if (p >= VdsoBeg())  // vdso\n      break;\n    Printf(\"FATAL: ThreadSanitizer: unexpected memory mapping %p-%p\\n\", p, end);\n    Die();\n  }\n\n  ProtectRange(LoAppMemEnd(), ShadowBeg());\n  ProtectRange(ShadowEnd(), MetaShadowBeg());\n#ifdef TSAN_MID_APP_RANGE\n  ProtectRange(MetaShadowEnd(), MidAppMemBeg());\n  ProtectRange(MidAppMemEnd(), TraceMemBeg());\n#else\n  ProtectRange(MetaShadowEnd(), TraceMemBeg());\n#endif\n  // Memory for traces is mapped lazily in MapThreadTrace.\n  // Protect the whole range for now, so that user does not map something here.\n  ProtectRange(TraceMemBeg(), TraceMemEnd());\n  ProtectRange(TraceMemEnd(), HeapMemBeg());\n  ProtectRange(HeapEnd(), HiAppMemBeg());\n}\n#endif\n\n}  // namespace __tsan\n\n#endif  // SANITIZER_POSIX\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_platform_windows.cc",
    "content": "//===-- tsan_platform_windows.cc ------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Windows-specific code.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#if SANITIZER_WINDOWS\n\n#include \"tsan_platform.h\"\n\n#include <stdlib.h>\n\nnamespace __tsan {\n\nuptr GetShadowMemoryConsumption() {\n  return 0;\n}\n\nvoid FlushShadowMemory() {\n}\n\nvoid WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive) {\n}\n\nvoid InitializePlatformEarly() {\n}\n\nvoid InitializePlatform() {\n}\n\n}  // namespace __tsan\n\n#endif  // SANITIZER_WINDOWS\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_ppc_regs.h",
    "content": "#define r0 0\n#define r1 1\n#define r2 2\n#define r3 3\n#define r4 4\n#define r5 5\n#define r6 6\n#define r7 7\n#define r8 8\n#define r9 9\n#define r10 10\n#define r11 11\n#define r12 12\n#define r13 13\n#define r14 14\n#define r15 15\n#define r16 16\n#define r17 17\n#define r18 18\n#define r19 19\n#define r20 20\n#define r21 21\n#define r22 22\n#define r23 23\n#define r24 24\n#define r25 25\n#define r26 26\n#define r27 27\n#define r28 28\n#define r29 29\n#define r30 30\n#define r31 31\n#define f0 0\n#define f1 1\n#define f2 2\n#define f3 3\n#define f4 4\n#define f5 5\n#define f6 6\n#define f7 7\n#define f8 8\n#define f9 9\n#define f10 10\n#define f11 11\n#define f12 12\n#define f13 13\n#define f14 14\n#define f15 15\n#define f16 16\n#define f17 17\n#define f18 18\n#define f19 19\n#define f20 20\n#define f21 21\n#define f22 22\n#define f23 23\n#define f24 24\n#define f25 25\n#define f26 26\n#define f27 27\n#define f28 28\n#define f29 29\n#define f30 30\n#define f31 31\n#define v0 0\n#define v1 1\n#define v2 2\n#define v3 3\n#define v4 4\n#define v5 5\n#define v6 6\n#define v7 7\n#define v8 8\n#define v9 9\n#define v10 10\n#define v11 11\n#define v12 12\n#define v13 13\n#define v14 14\n#define v15 15\n#define v16 16\n#define v17 17\n#define v18 18\n#define v19 19\n#define v20 20\n#define v21 21\n#define v22 22\n#define v23 23\n#define v24 24\n#define v25 25\n#define v26 26\n#define v27 27\n#define v28 28\n#define v29 29\n#define v30 30\n#define v31 31\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_report.cc",
    "content": "//===-- tsan_report.cc ----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_report.h\"\n#include \"tsan_platform.h\"\n#include \"tsan_rtl.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_report_decorator.h\"\n#include \"sanitizer_common/sanitizer_stacktrace_printer.h\"\n\nnamespace __tsan {\n\nReportStack::ReportStack() : frames(nullptr), suppressable(false) {}\n\nReportStack *ReportStack::New() {\n  void *mem = internal_alloc(MBlockReportStack, sizeof(ReportStack));\n  return new(mem) ReportStack();\n}\n\nReportLocation::ReportLocation(ReportLocationType type)\n    : type(type), global(), heap_chunk_start(0), heap_chunk_size(0), tid(0),\n      fd(0), suppressable(false), stack(nullptr) {}\n\nReportLocation *ReportLocation::New(ReportLocationType type) {\n  void *mem = internal_alloc(MBlockReportStack, sizeof(ReportLocation));\n  return new(mem) ReportLocation(type);\n}\n\nclass Decorator: public __sanitizer::SanitizerCommonDecorator {\n public:\n  Decorator() : SanitizerCommonDecorator() { }\n  const char *Warning()    { return Red(); }\n  const char *EndWarning() { return Default(); }\n  const char *Access()     { return Blue(); }\n  const char *EndAccess()  { return Default(); }\n  const char *ThreadDescription()    { return Cyan(); }\n  const char *EndThreadDescription() { return Default(); }\n  const char *Location()   { return Green(); }\n  const char *EndLocation() { return Default(); }\n  const char *Sleep()   { return Yellow(); }\n  const char *EndSleep() { return Default(); }\n  const char *Mutex()   { return Magenta(); }\n  const char *EndMutex() { return Default(); }\n};\n\nReportDesc::ReportDesc()\n    : stacks(MBlockReportStack)\n    , mops(MBlockReportMop)\n    , locs(MBlockReportLoc)\n    , mutexes(MBlockReportMutex)\n    , threads(MBlockReportThread)\n    , unique_tids(MBlockReportThread)\n    , sleep()\n    , count() {\n}\n\nReportMop::ReportMop()\n    : mset(MBlockReportMutex) {\n}\n\nReportDesc::~ReportDesc() {\n  // FIXME(dvyukov): it must be leaking a lot of memory.\n}\n\n#ifndef SANITIZER_GO\n\nconst int kThreadBufSize = 32;\nconst char *thread_name(char *buf, int tid) {\n  if (tid == 0)\n    return \"main thread\";\n  internal_snprintf(buf, kThreadBufSize, \"thread T%d\", tid);\n  return buf;\n}\n\nstatic const char *ReportTypeString(ReportType typ) {\n  if (typ == ReportTypeRace)\n    return \"data race\";\n  if (typ == ReportTypeVptrRace)\n    return \"data race on vptr (ctor/dtor vs virtual call)\";\n  if (typ == ReportTypeUseAfterFree)\n    return \"heap-use-after-free\";\n  if (typ == ReportTypeVptrUseAfterFree)\n    return \"heap-use-after-free (virtual call vs free)\";\n  if (typ == ReportTypeThreadLeak)\n    return \"thread leak\";\n  if (typ == ReportTypeMutexDestroyLocked)\n    return \"destroy of a locked mutex\";\n  if (typ == ReportTypeMutexDoubleLock)\n    return \"double lock of a mutex\";\n  if (typ == ReportTypeMutexBadUnlock)\n    return \"unlock of an unlocked mutex (or by a wrong thread)\";\n  if (typ == ReportTypeMutexBadReadLock)\n    return \"read lock of a write locked mutex\";\n  if (typ == ReportTypeMutexBadReadUnlock)\n    return \"read unlock of a write locked mutex\";\n  if (typ == ReportTypeSignalUnsafe)\n    return \"signal-unsafe call inside of a signal\";\n  if (typ == ReportTypeErrnoInSignal)\n    return \"signal handler spoils errno\";\n  if (typ == ReportTypeDeadlock)\n    return \"lock-order-inversion (potential deadlock)\";\n  return \"\";\n}\n\n#if SANITIZER_MAC\nstatic const char *const kInterposedFunctionPrefix = \"wrap_\";\n#else\nstatic const char *const kInterposedFunctionPrefix = \"__interceptor_\";\n#endif\n\nvoid PrintStack(const ReportStack *ent) {\n  if (ent == 0 || ent->frames == 0) {\n    Printf(\"    [failed to restore the stack]\\n\\n\");\n    return;\n  }\n  SymbolizedStack *frame = ent->frames;\n  for (int i = 0; frame && frame->info.address; frame = frame->next, i++) {\n    InternalScopedString res(2 * GetPageSizeCached());\n    RenderFrame(&res, common_flags()->stack_trace_format, i, frame->info,\n                common_flags()->symbolize_vs_style,\n                common_flags()->strip_path_prefix, kInterposedFunctionPrefix);\n    Printf(\"%s\\n\", res.data());\n  }\n  Printf(\"\\n\");\n}\n\nstatic void PrintMutexSet(Vector<ReportMopMutex> const& mset) {\n  for (uptr i = 0; i < mset.Size(); i++) {\n    if (i == 0)\n      Printf(\" (mutexes:\");\n    const ReportMopMutex m = mset[i];\n    Printf(\" %s M%llu\", m.write ? \"write\" : \"read\", m.id);\n    Printf(i == mset.Size() - 1 ? \")\" : \",\");\n  }\n}\n\nstatic const char *MopDesc(bool first, bool write, bool atomic) {\n  return atomic ? (first ? (write ? \"Atomic write\" : \"Atomic read\")\n                : (write ? \"Previous atomic write\" : \"Previous atomic read\"))\n                : (first ? (write ? \"Write\" : \"Read\")\n                : (write ? \"Previous write\" : \"Previous read\"));\n}\n\nstatic void PrintMop(const ReportMop *mop, bool first) {\n  Decorator d;\n  char thrbuf[kThreadBufSize];\n  Printf(\"%s\", d.Access());\n  Printf(\"  %s of size %d at %p by %s\",\n      MopDesc(first, mop->write, mop->atomic),\n      mop->size, (void*)mop->addr,\n      thread_name(thrbuf, mop->tid));\n  PrintMutexSet(mop->mset);\n  Printf(\":\\n\");\n  Printf(\"%s\", d.EndAccess());\n  PrintStack(mop->stack);\n}\n\nstatic void PrintLocation(const ReportLocation *loc) {\n  Decorator d;\n  char thrbuf[kThreadBufSize];\n  bool print_stack = false;\n  Printf(\"%s\", d.Location());\n  if (loc->type == ReportLocationGlobal) {\n    const DataInfo &global = loc->global;\n    if (global.size != 0)\n      Printf(\"  Location is global '%s' of size %zu at %p (%s+%p)\\n\\n\",\n             global.name, global.size, global.start,\n             StripModuleName(global.module), global.module_offset);\n    else\n      Printf(\"  Location is global '%s' at %p (%s+%p)\\n\\n\", global.name,\n             global.start, StripModuleName(global.module),\n             global.module_offset);\n  } else if (loc->type == ReportLocationHeap) {\n    char thrbuf[kThreadBufSize];\n    Printf(\"  Location is heap block of size %zu at %p allocated by %s:\\n\",\n           loc->heap_chunk_size, loc->heap_chunk_start,\n           thread_name(thrbuf, loc->tid));\n    print_stack = true;\n  } else if (loc->type == ReportLocationStack) {\n    Printf(\"  Location is stack of %s.\\n\\n\", thread_name(thrbuf, loc->tid));\n  } else if (loc->type == ReportLocationTLS) {\n    Printf(\"  Location is TLS of %s.\\n\\n\", thread_name(thrbuf, loc->tid));\n  } else if (loc->type == ReportLocationFD) {\n    Printf(\"  Location is file descriptor %d created by %s at:\\n\",\n        loc->fd, thread_name(thrbuf, loc->tid));\n    print_stack = true;\n  }\n  Printf(\"%s\", d.EndLocation());\n  if (print_stack)\n    PrintStack(loc->stack);\n}\n\nstatic void PrintMutexShort(const ReportMutex *rm, const char *after) {\n  Decorator d;\n  Printf(\"%sM%zd%s%s\", d.Mutex(), rm->id, d.EndMutex(), after);\n}\n\nstatic void PrintMutexShortWithAddress(const ReportMutex *rm,\n                                       const char *after) {\n  Decorator d;\n  Printf(\"%sM%zd (%p)%s%s\", d.Mutex(), rm->id, rm->addr, d.EndMutex(), after);\n}\n\nstatic void PrintMutex(const ReportMutex *rm) {\n  Decorator d;\n  if (rm->destroyed) {\n    Printf(\"%s\", d.Mutex());\n    Printf(\"  Mutex M%llu is already destroyed.\\n\\n\", rm->id);\n    Printf(\"%s\", d.EndMutex());\n  } else {\n    Printf(\"%s\", d.Mutex());\n    Printf(\"  Mutex M%llu (%p) created at:\\n\", rm->id, rm->addr);\n    Printf(\"%s\", d.EndMutex());\n    PrintStack(rm->stack);\n  }\n}\n\nstatic void PrintThread(const ReportThread *rt) {\n  Decorator d;\n  if (rt->id == 0)  // Little sense in describing the main thread.\n    return;\n  Printf(\"%s\", d.ThreadDescription());\n  Printf(\"  Thread T%d\", rt->id);\n  if (rt->name && rt->name[0] != '\\0')\n    Printf(\" '%s'\", rt->name);\n  char thrbuf[kThreadBufSize];\n  Printf(\" (tid=%zu, %s) created by %s\",\n    rt->pid, rt->running ? \"running\" : \"finished\",\n    thread_name(thrbuf, rt->parent_tid));\n  if (rt->stack)\n    Printf(\" at:\");\n  Printf(\"\\n\");\n  Printf(\"%s\", d.EndThreadDescription());\n  PrintStack(rt->stack);\n}\n\nstatic void PrintSleep(const ReportStack *s) {\n  Decorator d;\n  Printf(\"%s\", d.Sleep());\n  Printf(\"  As if synchronized via sleep:\\n\");\n  Printf(\"%s\", d.EndSleep());\n  PrintStack(s);\n}\n\nstatic ReportStack *ChooseSummaryStack(const ReportDesc *rep) {\n  if (rep->mops.Size())\n    return rep->mops[0]->stack;\n  if (rep->stacks.Size())\n    return rep->stacks[0];\n  if (rep->mutexes.Size())\n    return rep->mutexes[0]->stack;\n  if (rep->threads.Size())\n    return rep->threads[0]->stack;\n  return 0;\n}\n\nstatic bool FrameIsInternal(const SymbolizedStack *frame) {\n  if (frame == 0)\n    return false;\n  const char *file = frame->info.file;\n  const char *module = frame->info.module;\n  if (file != 0 &&\n      (internal_strstr(file, \"tsan_interceptors.cc\") ||\n       internal_strstr(file, \"sanitizer_common_interceptors.inc\") ||\n       internal_strstr(file, \"tsan_interface_\")))\n    return true;\n  if (module != 0 && (internal_strstr(module, \"libclang_rt.tsan_\")))\n    return true;\n  return false;\n}\n\nstatic SymbolizedStack *SkipTsanInternalFrames(SymbolizedStack *frames) {\n  while (FrameIsInternal(frames) && frames->next)\n    frames = frames->next;\n  return frames;\n}\n\nvoid PrintReport(const ReportDesc *rep) {\n  Decorator d;\n  Printf(\"==================\\n\");\n  const char *rep_typ_str = ReportTypeString(rep->typ);\n  Printf(\"%s\", d.Warning());\n  Printf(\"WARNING: ThreadSanitizer: %s (pid=%d)\\n\", rep_typ_str,\n         (int)internal_getpid());\n  Printf(\"%s\", d.EndWarning());\n\n  if (rep->typ == ReportTypeDeadlock) {\n    char thrbuf[kThreadBufSize];\n    Printf(\"  Cycle in lock order graph: \");\n    for (uptr i = 0; i < rep->mutexes.Size(); i++)\n      PrintMutexShortWithAddress(rep->mutexes[i], \" => \");\n    PrintMutexShort(rep->mutexes[0], \"\\n\\n\");\n    CHECK_GT(rep->mutexes.Size(), 0U);\n    CHECK_EQ(rep->mutexes.Size() * (flags()->second_deadlock_stack ? 2 : 1),\n             rep->stacks.Size());\n    for (uptr i = 0; i < rep->mutexes.Size(); i++) {\n      Printf(\"  Mutex \");\n      PrintMutexShort(rep->mutexes[(i + 1) % rep->mutexes.Size()],\n                      \" acquired here while holding mutex \");\n      PrintMutexShort(rep->mutexes[i], \" in \");\n      Printf(\"%s\", d.ThreadDescription());\n      Printf(\"%s:\\n\", thread_name(thrbuf, rep->unique_tids[i]));\n      Printf(\"%s\", d.EndThreadDescription());\n      if (flags()->second_deadlock_stack) {\n        PrintStack(rep->stacks[2*i]);\n        Printf(\"  Mutex \");\n        PrintMutexShort(rep->mutexes[i],\n                        \" previously acquired by the same thread here:\\n\");\n        PrintStack(rep->stacks[2*i+1]);\n      } else {\n        PrintStack(rep->stacks[i]);\n        if (i == 0)\n          Printf(\"    Hint: use TSAN_OPTIONS=second_deadlock_stack=1 \"\n                 \"to get more informative warning message\\n\\n\");\n      }\n    }\n  } else {\n    for (uptr i = 0; i < rep->stacks.Size(); i++) {\n      if (i)\n        Printf(\"  and:\\n\");\n      PrintStack(rep->stacks[i]);\n    }\n  }\n\n  for (uptr i = 0; i < rep->mops.Size(); i++)\n    PrintMop(rep->mops[i], i == 0);\n\n  if (rep->sleep)\n    PrintSleep(rep->sleep);\n\n  for (uptr i = 0; i < rep->locs.Size(); i++)\n    PrintLocation(rep->locs[i]);\n\n  if (rep->typ != ReportTypeDeadlock) {\n    for (uptr i = 0; i < rep->mutexes.Size(); i++)\n      PrintMutex(rep->mutexes[i]);\n  }\n\n  for (uptr i = 0; i < rep->threads.Size(); i++)\n    PrintThread(rep->threads[i]);\n\n  if (rep->typ == ReportTypeThreadLeak && rep->count > 1)\n    Printf(\"  And %d more similar thread leaks.\\n\\n\", rep->count - 1);\n\n  if (ReportStack *stack = ChooseSummaryStack(rep)) {\n    if (SymbolizedStack *frame = SkipTsanInternalFrames(stack->frames))\n      ReportErrorSummary(rep_typ_str, frame->info);\n  }\n\n  Printf(\"==================\\n\");\n}\n\n#else  // #ifndef SANITIZER_GO\n\nconst int kMainThreadId = 1;\n\nvoid PrintStack(const ReportStack *ent) {\n  if (ent == 0 || ent->frames == 0) {\n    Printf(\"  [failed to restore the stack]\\n\");\n    return;\n  }\n  SymbolizedStack *frame = ent->frames;\n  for (int i = 0; frame; frame = frame->next, i++) {\n    const AddressInfo &info = frame->info;\n    Printf(\"  %s()\\n      %s:%d +0x%zx\\n\", info.function,\n        StripPathPrefix(info.file, common_flags()->strip_path_prefix),\n        info.line, (void *)info.module_offset);\n  }\n}\n\nstatic void PrintMop(const ReportMop *mop, bool first) {\n  Printf(\"\\n\");\n  Printf(\"%s by \",\n      (first ? (mop->write ? \"Write\" : \"Read\")\n             : (mop->write ? \"Previous write\" : \"Previous read\")));\n  if (mop->tid == kMainThreadId)\n    Printf(\"main goroutine:\\n\");\n  else\n    Printf(\"goroutine %d:\\n\", mop->tid);\n  PrintStack(mop->stack);\n}\n\nstatic void PrintThread(const ReportThread *rt) {\n  if (rt->id == kMainThreadId)\n    return;\n  Printf(\"\\n\");\n  Printf(\"Goroutine %d (%s) created at:\\n\",\n    rt->id, rt->running ? \"running\" : \"finished\");\n  PrintStack(rt->stack);\n}\n\nvoid PrintReport(const ReportDesc *rep) {\n  Printf(\"==================\\n\");\n  if (rep->typ == ReportTypeRace) {\n    Printf(\"WARNING: DATA RACE\");\n    for (uptr i = 0; i < rep->mops.Size(); i++)\n      PrintMop(rep->mops[i], i == 0);\n    for (uptr i = 0; i < rep->threads.Size(); i++)\n      PrintThread(rep->threads[i]);\n  } else if (rep->typ == ReportTypeDeadlock) {\n    Printf(\"WARNING: DEADLOCK\\n\");\n    for (uptr i = 0; i < rep->mutexes.Size(); i++) {\n      Printf(\"Goroutine %d lock mutex %d while holding mutex %d:\\n\",\n          999, rep->mutexes[i]->id,\n          rep->mutexes[(i+1) % rep->mutexes.Size()]->id);\n      PrintStack(rep->stacks[2*i]);\n      Printf(\"\\n\");\n      Printf(\"Mutex %d was previously locked here:\\n\",\n          rep->mutexes[(i+1) % rep->mutexes.Size()]->id);\n      PrintStack(rep->stacks[2*i + 1]);\n      Printf(\"\\n\");\n    }\n  }\n  Printf(\"==================\\n\");\n}\n\n#endif\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_report.h",
    "content": "//===-- tsan_report.h -------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_REPORT_H\n#define TSAN_REPORT_H\n\n#include \"sanitizer_common/sanitizer_symbolizer.h\"\n#include \"tsan_defs.h\"\n#include \"tsan_vector.h\"\n\nnamespace __tsan {\n\nenum ReportType {\n  ReportTypeRace,\n  ReportTypeVptrRace,\n  ReportTypeUseAfterFree,\n  ReportTypeVptrUseAfterFree,\n  ReportTypeThreadLeak,\n  ReportTypeMutexDestroyLocked,\n  ReportTypeMutexDoubleLock,\n  ReportTypeMutexBadUnlock,\n  ReportTypeMutexBadReadLock,\n  ReportTypeMutexBadReadUnlock,\n  ReportTypeSignalUnsafe,\n  ReportTypeErrnoInSignal,\n  ReportTypeDeadlock\n};\n\nstruct ReportStack {\n  SymbolizedStack *frames;\n  bool suppressable;\n  static ReportStack *New();\n\n private:\n  ReportStack();\n};\n\nstruct ReportMopMutex {\n  u64 id;\n  bool write;\n};\n\nstruct ReportMop {\n  int tid;\n  uptr addr;\n  int size;\n  bool write;\n  bool atomic;\n  Vector<ReportMopMutex> mset;\n  ReportStack *stack;\n\n  ReportMop();\n};\n\nenum ReportLocationType {\n  ReportLocationGlobal,\n  ReportLocationHeap,\n  ReportLocationStack,\n  ReportLocationTLS,\n  ReportLocationFD\n};\n\nstruct ReportLocation {\n  ReportLocationType type;\n  DataInfo global;\n  uptr heap_chunk_start;\n  uptr heap_chunk_size;\n  int tid;\n  int fd;\n  bool suppressable;\n  ReportStack *stack;\n\n  static ReportLocation *New(ReportLocationType type);\n private:\n  explicit ReportLocation(ReportLocationType type);\n};\n\nstruct ReportThread {\n  int id;\n  uptr pid;\n  bool running;\n  char *name;\n  int parent_tid;\n  ReportStack *stack;\n};\n\nstruct ReportMutex {\n  u64 id;\n  uptr addr;\n  bool destroyed;\n  ReportStack *stack;\n};\n\nclass ReportDesc {\n public:\n  ReportType typ;\n  Vector<ReportStack*> stacks;\n  Vector<ReportMop*> mops;\n  Vector<ReportLocation*> locs;\n  Vector<ReportMutex*> mutexes;\n  Vector<ReportThread*> threads;\n  Vector<int> unique_tids;\n  ReportStack *sleep;\n  int count;\n\n  ReportDesc();\n  ~ReportDesc();\n\n private:\n  ReportDesc(const ReportDesc&);\n  void operator = (const ReportDesc&);\n};\n\n// Format and output the report to the console/log. No additional logic.\nvoid PrintReport(const ReportDesc *rep);\nvoid PrintStack(const ReportStack *stack);\n\n}  // namespace __tsan\n\n#endif  // TSAN_REPORT_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_rtl.cc",
    "content": "//===-- tsan_rtl.cc -------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Main file (entry points) for the TSan run-time.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_symbolizer.h\"\n#include \"tsan_defs.h\"\n#include \"tsan_platform.h\"\n#include \"tsan_rtl.h\"\n#include \"tsan_mman.h\"\n#include \"tsan_suppressions.h\"\n#include \"tsan_symbolize.h\"\n#include \"ubsan/ubsan_init.h\"\n\n#ifdef __SSE3__\n// <emmintrin.h> transitively includes <stdlib.h>,\n// and it's prohibited to include std headers into tsan runtime.\n// So we do this dirty trick.\n#define _MM_MALLOC_H_INCLUDED\n#define __MM_MALLOC_H\n#include <emmintrin.h>\ntypedef __m128i m128;\n#endif\n\nvolatile int __tsan_resumed = 0;\n\nextern \"C\" void __tsan_resume() {\n  __tsan_resumed = 1;\n}\n\nnamespace __tsan {\n\n#if !defined(SANITIZER_GO) && !SANITIZER_MAC\nTHREADLOCAL char cur_thread_placeholder[sizeof(ThreadState)] ALIGNED(64);\n#endif\nstatic char ctx_placeholder[sizeof(Context)] ALIGNED(64);\nContext *ctx;\n\n// Can be overriden by a front-end.\n#ifdef TSAN_EXTERNAL_HOOKS\nbool OnFinalize(bool failed);\nvoid OnInitialize();\n#else\nSANITIZER_WEAK_CXX_DEFAULT_IMPL\nbool OnFinalize(bool failed) {\n  return failed;\n}\nSANITIZER_WEAK_CXX_DEFAULT_IMPL\nvoid OnInitialize() {}\n#endif\n\nstatic char thread_registry_placeholder[sizeof(ThreadRegistry)];\n\nstatic ThreadContextBase *CreateThreadContext(u32 tid) {\n  // Map thread trace when context is created.\n  char name[50];\n  internal_snprintf(name, sizeof(name), \"trace %u\", tid);\n  MapThreadTrace(GetThreadTrace(tid), TraceSize() * sizeof(Event), name);\n  const uptr hdr = GetThreadTraceHeader(tid);\n  internal_snprintf(name, sizeof(name), \"trace header %u\", tid);\n  MapThreadTrace(hdr, sizeof(Trace), name);\n  new((void*)hdr) Trace();\n  // We are going to use only a small part of the trace with the default\n  // value of history_size. However, the constructor writes to the whole trace.\n  // Unmap the unused part.\n  uptr hdr_end = hdr + sizeof(Trace);\n  hdr_end -= sizeof(TraceHeader) * (kTraceParts - TraceParts());\n  hdr_end = RoundUp(hdr_end, GetPageSizeCached());\n  if (hdr_end < hdr + sizeof(Trace))\n    UnmapOrDie((void*)hdr_end, hdr + sizeof(Trace) - hdr_end);\n  void *mem = internal_alloc(MBlockThreadContex, sizeof(ThreadContext));\n  return new(mem) ThreadContext(tid);\n}\n\n#ifndef SANITIZER_GO\nstatic const u32 kThreadQuarantineSize = 16;\n#else\nstatic const u32 kThreadQuarantineSize = 64;\n#endif\n\nContext::Context()\n  : initialized()\n  , report_mtx(MutexTypeReport, StatMtxReport)\n  , nreported()\n  , nmissed_expected()\n  , thread_registry(new(thread_registry_placeholder) ThreadRegistry(\n      CreateThreadContext, kMaxTid, kThreadQuarantineSize, kMaxTidReuse))\n  , racy_mtx(MutexTypeRacy, StatMtxRacy)\n  , racy_stacks(MBlockRacyStacks)\n  , racy_addresses(MBlockRacyAddresses)\n  , fired_suppressions_mtx(MutexTypeFired, StatMtxFired)\n  , fired_suppressions(8) {\n}\n\n// The objects are allocated in TLS, so one may rely on zero-initialization.\nThreadState::ThreadState(Context *ctx, int tid, int unique_id, u64 epoch,\n                         unsigned reuse_count,\n                         uptr stk_addr, uptr stk_size,\n                         uptr tls_addr, uptr tls_size)\n  : fast_state(tid, epoch)\n  // Do not touch these, rely on zero initialization,\n  // they may be accessed before the ctor.\n  // , ignore_reads_and_writes()\n  // , ignore_interceptors()\n  , clock(tid, reuse_count)\n#ifndef SANITIZER_GO\n  , jmp_bufs(MBlockJmpBuf)\n#endif\n  , tid(tid)\n  , unique_id(unique_id)\n  , stk_addr(stk_addr)\n  , stk_size(stk_size)\n  , tls_addr(tls_addr)\n  , tls_size(tls_size)\n#ifndef SANITIZER_GO\n  , last_sleep_clock(tid)\n#endif\n{\n}\n\n#ifndef SANITIZER_GO\nstatic void MemoryProfiler(Context *ctx, fd_t fd, int i) {\n  uptr n_threads;\n  uptr n_running_threads;\n  ctx->thread_registry->GetNumberOfThreads(&n_threads, &n_running_threads);\n  InternalScopedBuffer<char> buf(4096);\n  WriteMemoryProfile(buf.data(), buf.size(), n_threads, n_running_threads);\n  WriteToFile(fd, buf.data(), internal_strlen(buf.data()));\n}\n\nstatic void BackgroundThread(void *arg) {\n  // This is a non-initialized non-user thread, nothing to see here.\n  // We don't use ScopedIgnoreInterceptors, because we want ignores to be\n  // enabled even when the thread function exits (e.g. during pthread thread\n  // shutdown code).\n  cur_thread()->ignore_interceptors++;\n  const u64 kMs2Ns = 1000 * 1000;\n\n  fd_t mprof_fd = kInvalidFd;\n  if (flags()->profile_memory && flags()->profile_memory[0]) {\n    if (internal_strcmp(flags()->profile_memory, \"stdout\") == 0) {\n      mprof_fd = 1;\n    } else if (internal_strcmp(flags()->profile_memory, \"stderr\") == 0) {\n      mprof_fd = 2;\n    } else {\n      InternalScopedString filename(kMaxPathLength);\n      filename.append(\"%s.%d\", flags()->profile_memory, (int)internal_getpid());\n      fd_t fd = OpenFile(filename.data(), WrOnly);\n      if (fd == kInvalidFd) {\n        Printf(\"ThreadSanitizer: failed to open memory profile file '%s'\\n\",\n            &filename[0]);\n      } else {\n        mprof_fd = fd;\n      }\n    }\n  }\n\n  u64 last_flush = NanoTime();\n  uptr last_rss = 0;\n  for (int i = 0;\n      atomic_load(&ctx->stop_background_thread, memory_order_relaxed) == 0;\n      i++) {\n    SleepForMillis(100);\n    u64 now = NanoTime();\n\n    // Flush memory if requested.\n    if (flags()->flush_memory_ms > 0) {\n      if (last_flush + flags()->flush_memory_ms * kMs2Ns < now) {\n        VPrintf(1, \"ThreadSanitizer: periodic memory flush\\n\");\n        FlushShadowMemory();\n        last_flush = NanoTime();\n      }\n    }\n    // GetRSS can be expensive on huge programs, so don't do it every 100ms.\n    if (flags()->memory_limit_mb > 0) {\n      uptr rss = GetRSS();\n      uptr limit = uptr(flags()->memory_limit_mb) << 20;\n      VPrintf(1, \"ThreadSanitizer: memory flush check\"\n                 \" RSS=%llu LAST=%llu LIMIT=%llu\\n\",\n              (u64)rss >> 20, (u64)last_rss >> 20, (u64)limit >> 20);\n      if (2 * rss > limit + last_rss) {\n        VPrintf(1, \"ThreadSanitizer: flushing memory due to RSS\\n\");\n        FlushShadowMemory();\n        rss = GetRSS();\n        VPrintf(1, \"ThreadSanitizer: memory flushed RSS=%llu\\n\", (u64)rss>>20);\n      }\n      last_rss = rss;\n    }\n\n    // Write memory profile if requested.\n    if (mprof_fd != kInvalidFd)\n      MemoryProfiler(ctx, mprof_fd, i);\n\n    // Flush symbolizer cache if requested.\n    if (flags()->flush_symbolizer_ms > 0) {\n      u64 last = atomic_load(&ctx->last_symbolize_time_ns,\n                             memory_order_relaxed);\n      if (last != 0 && last + flags()->flush_symbolizer_ms * kMs2Ns < now) {\n        Lock l(&ctx->report_mtx);\n        SpinMutexLock l2(&CommonSanitizerReportMutex);\n        SymbolizeFlush();\n        atomic_store(&ctx->last_symbolize_time_ns, 0, memory_order_relaxed);\n      }\n    }\n  }\n}\n\nstatic void StartBackgroundThread() {\n  ctx->background_thread = internal_start_thread(&BackgroundThread, 0);\n}\n\n#ifndef __mips__\nstatic void StopBackgroundThread() {\n  atomic_store(&ctx->stop_background_thread, 1, memory_order_relaxed);\n  internal_join_thread(ctx->background_thread);\n  ctx->background_thread = 0;\n}\n#endif\n#endif\n\nvoid DontNeedShadowFor(uptr addr, uptr size) {\n  uptr shadow_beg = MemToShadow(addr);\n  uptr shadow_end = MemToShadow(addr + size);\n  FlushUnneededShadowMemory(shadow_beg, shadow_end - shadow_beg);\n}\n\nvoid MapShadow(uptr addr, uptr size) {\n  // Global data is not 64K aligned, but there are no adjacent mappings,\n  // so we can get away with unaligned mapping.\n  // CHECK_EQ(addr, addr & ~((64 << 10) - 1));  // windows wants 64K alignment\n  MmapFixedNoReserve(MemToShadow(addr), size * kShadowMultiplier, \"shadow\");\n\n  // Meta shadow is 2:1, so tread carefully.\n  static bool data_mapped = false;\n  static uptr mapped_meta_end = 0;\n  uptr meta_begin = (uptr)MemToMeta(addr);\n  uptr meta_end = (uptr)MemToMeta(addr + size);\n  meta_begin = RoundDownTo(meta_begin, 64 << 10);\n  meta_end = RoundUpTo(meta_end, 64 << 10);\n  if (!data_mapped) {\n    // First call maps data+bss.\n    data_mapped = true;\n    MmapFixedNoReserve(meta_begin, meta_end - meta_begin, \"meta shadow\");\n  } else {\n    // Mapping continous heap.\n    // Windows wants 64K alignment.\n    meta_begin = RoundDownTo(meta_begin, 64 << 10);\n    meta_end = RoundUpTo(meta_end, 64 << 10);\n    if (meta_end <= mapped_meta_end)\n      return;\n    if (meta_begin < mapped_meta_end)\n      meta_begin = mapped_meta_end;\n    MmapFixedNoReserve(meta_begin, meta_end - meta_begin, \"meta shadow\");\n    mapped_meta_end = meta_end;\n  }\n  VPrintf(2, \"mapped meta shadow for (%p-%p) at (%p-%p)\\n\",\n      addr, addr+size, meta_begin, meta_end);\n}\n\nvoid MapThreadTrace(uptr addr, uptr size, const char *name) {\n  DPrintf(\"#0: Mapping trace at %p-%p(0x%zx)\\n\", addr, addr + size, size);\n  CHECK_GE(addr, TraceMemBeg());\n  CHECK_LE(addr + size, TraceMemEnd());\n  CHECK_EQ(addr, addr & ~((64 << 10) - 1));  // windows wants 64K alignment\n  uptr addr1 = (uptr)MmapFixedNoReserve(addr, size, name);\n  if (addr1 != addr) {\n    Printf(\"FATAL: ThreadSanitizer can not mmap thread trace (%p/%p->%p)\\n\",\n        addr, size, addr1);\n    Die();\n  }\n}\n\nstatic void CheckShadowMapping() {\n  uptr beg, end;\n  for (int i = 0; GetUserRegion(i, &beg, &end); i++) {\n    VPrintf(3, \"checking shadow region %p-%p\\n\", beg, end);\n    for (uptr p0 = beg; p0 <= end; p0 += (end - beg) / 4) {\n      for (int x = -1; x <= 1; x++) {\n        const uptr p = p0 + x;\n        if (p < beg || p >= end)\n          continue;\n        const uptr s = MemToShadow(p);\n        const uptr m = (uptr)MemToMeta(p);\n        VPrintf(3, \"  checking pointer %p: shadow=%p meta=%p\\n\", p, s, m);\n        CHECK(IsAppMem(p));\n        CHECK(IsShadowMem(s));\n        CHECK_EQ(p & ~(kShadowCell - 1), ShadowToMem(s));\n        CHECK(IsMetaMem(m));\n      }\n    }\n  }\n}\n\nvoid Initialize(ThreadState *thr) {\n  // Thread safe because done before all threads exist.\n  static bool is_initialized = false;\n  if (is_initialized)\n    return;\n  is_initialized = true;\n  // We are not ready to handle interceptors yet.\n  ScopedIgnoreInterceptors ignore;\n  SanitizerToolName = \"ThreadSanitizer\";\n  // Install tool-specific callbacks in sanitizer_common.\n  SetCheckFailedCallback(TsanCheckFailed);\n\n  ctx = new(ctx_placeholder) Context;\n  const char *options = GetEnv(kTsanOptionsEnv);\n  CacheBinaryName();\n  InitializeFlags(&ctx->flags, options);\n  InitializePlatformEarly();\n#ifndef SANITIZER_GO\n  // Re-exec ourselves if we need to set additional env or command line args.\n  MaybeReexec();\n\n  InitializeAllocator();\n  ReplaceSystemMalloc();\n#endif\n  InitializeInterceptors();\n  CheckShadowMapping();\n  InitializePlatform();\n  InitializeMutex();\n  InitializeDynamicAnnotations();\n#ifndef SANITIZER_GO\n  InitializeShadowMemory();\n#endif\n  // Setup correct file descriptor for error reports.\n  __sanitizer_set_report_path(common_flags()->log_path);\n  InitializeSuppressions();\n#ifndef SANITIZER_GO\n  InitializeLibIgnore();\n  Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer);\n  // On MIPS, TSan initialization is run before\n  // __pthread_initialize_minimal_internal() is finished, so we can not spawn\n  // new threads.\n#ifndef __mips__\n  StartBackgroundThread();\n  SetSandboxingCallback(StopBackgroundThread);\n#endif\n#endif\n  if (common_flags()->detect_deadlocks)\n    ctx->dd = DDetector::Create(flags());\n\n  VPrintf(1, \"***** Running under ThreadSanitizer v2 (pid %d) *****\\n\",\n          (int)internal_getpid());\n\n  // Initialize thread 0.\n  int tid = ThreadCreate(thr, 0, 0, true);\n  CHECK_EQ(tid, 0);\n  ThreadStart(thr, tid, internal_getpid());\n#if TSAN_CONTAINS_UBSAN\n  __ubsan::InitAsPlugin();\n#endif\n  ctx->initialized = true;\n\n  if (flags()->stop_on_start) {\n    Printf(\"ThreadSanitizer is suspended at startup (pid %d).\"\n           \" Call __tsan_resume().\\n\",\n           (int)internal_getpid());\n    while (__tsan_resumed == 0) {}\n  }\n\n  OnInitialize();\n}\n\nint Finalize(ThreadState *thr) {\n  bool failed = false;\n\n  if (flags()->atexit_sleep_ms > 0 && ThreadCount(thr) > 1)\n    SleepForMillis(flags()->atexit_sleep_ms);\n\n  // Wait for pending reports.\n  ctx->report_mtx.Lock();\n  CommonSanitizerReportMutex.Lock();\n  CommonSanitizerReportMutex.Unlock();\n  ctx->report_mtx.Unlock();\n\n#ifndef SANITIZER_GO\n  if (Verbosity()) AllocatorPrintStats();\n#endif\n\n  ThreadFinalize(thr);\n\n  if (ctx->nreported) {\n    failed = true;\n#ifndef SANITIZER_GO\n    Printf(\"ThreadSanitizer: reported %d warnings\\n\", ctx->nreported);\n#else\n    Printf(\"Found %d data race(s)\\n\", ctx->nreported);\n#endif\n  }\n\n  if (ctx->nmissed_expected) {\n    failed = true;\n    Printf(\"ThreadSanitizer: missed %d expected races\\n\",\n        ctx->nmissed_expected);\n  }\n\n  if (common_flags()->print_suppressions)\n    PrintMatchedSuppressions();\n#ifndef SANITIZER_GO\n  if (flags()->print_benign)\n    PrintMatchedBenignRaces();\n#endif\n\n  failed = OnFinalize(failed);\n\n#if TSAN_COLLECT_STATS\n  StatAggregate(ctx->stat, thr->stat);\n  StatOutput(ctx->stat);\n#endif\n\n  return failed ? common_flags()->exitcode : 0;\n}\n\n#ifndef SANITIZER_GO\nvoid ForkBefore(ThreadState *thr, uptr pc) {\n  ctx->thread_registry->Lock();\n  ctx->report_mtx.Lock();\n}\n\nvoid ForkParentAfter(ThreadState *thr, uptr pc) {\n  ctx->report_mtx.Unlock();\n  ctx->thread_registry->Unlock();\n}\n\nvoid ForkChildAfter(ThreadState *thr, uptr pc) {\n  ctx->report_mtx.Unlock();\n  ctx->thread_registry->Unlock();\n\n  uptr nthread = 0;\n  ctx->thread_registry->GetNumberOfThreads(0, 0, &nthread /* alive threads */);\n  VPrintf(1, \"ThreadSanitizer: forked new process with pid %d,\"\n      \" parent had %d threads\\n\", (int)internal_getpid(), (int)nthread);\n  if (nthread == 1) {\n    StartBackgroundThread();\n  } else {\n    // We've just forked a multi-threaded process. We cannot reasonably function\n    // after that (some mutexes may be locked before fork). So just enable\n    // ignores for everything in the hope that we will exec soon.\n    ctx->after_multithreaded_fork = true;\n    thr->ignore_interceptors++;\n    ThreadIgnoreBegin(thr, pc);\n    ThreadIgnoreSyncBegin(thr, pc);\n  }\n}\n#endif\n\n#ifdef SANITIZER_GO\nNOINLINE\nvoid GrowShadowStack(ThreadState *thr) {\n  const int sz = thr->shadow_stack_end - thr->shadow_stack;\n  const int newsz = 2 * sz;\n  uptr *newstack = (uptr*)internal_alloc(MBlockShadowStack,\n      newsz * sizeof(uptr));\n  internal_memcpy(newstack, thr->shadow_stack, sz * sizeof(uptr));\n  internal_free(thr->shadow_stack);\n  thr->shadow_stack = newstack;\n  thr->shadow_stack_pos = newstack + sz;\n  thr->shadow_stack_end = newstack + newsz;\n}\n#endif\n\nu32 CurrentStackId(ThreadState *thr, uptr pc) {\n  if (!thr->is_inited)  // May happen during bootstrap.\n    return 0;\n  if (pc != 0) {\n#ifndef SANITIZER_GO\n    DCHECK_LT(thr->shadow_stack_pos, thr->shadow_stack_end);\n#else\n    if (thr->shadow_stack_pos == thr->shadow_stack_end)\n      GrowShadowStack(thr);\n#endif\n    thr->shadow_stack_pos[0] = pc;\n    thr->shadow_stack_pos++;\n  }\n  u32 id = StackDepotPut(\n      StackTrace(thr->shadow_stack, thr->shadow_stack_pos - thr->shadow_stack));\n  if (pc != 0)\n    thr->shadow_stack_pos--;\n  return id;\n}\n\nvoid TraceSwitch(ThreadState *thr) {\n  thr->nomalloc++;\n  Trace *thr_trace = ThreadTrace(thr->tid);\n  Lock l(&thr_trace->mtx);\n  unsigned trace = (thr->fast_state.epoch() / kTracePartSize) % TraceParts();\n  TraceHeader *hdr = &thr_trace->headers[trace];\n  hdr->epoch0 = thr->fast_state.epoch();\n  ObtainCurrentStack(thr, 0, &hdr->stack0);\n  hdr->mset0 = thr->mset;\n  thr->nomalloc--;\n}\n\nTrace *ThreadTrace(int tid) {\n  return (Trace*)GetThreadTraceHeader(tid);\n}\n\nuptr TraceTopPC(ThreadState *thr) {\n  Event *events = (Event*)GetThreadTrace(thr->tid);\n  uptr pc = events[thr->fast_state.GetTracePos()];\n  return pc;\n}\n\nuptr TraceSize() {\n  return (uptr)(1ull << (kTracePartSizeBits + flags()->history_size + 1));\n}\n\nuptr TraceParts() {\n  return TraceSize() / kTracePartSize;\n}\n\n#ifndef SANITIZER_GO\nextern \"C\" void __tsan_trace_switch() {\n  TraceSwitch(cur_thread());\n}\n\nextern \"C\" void __tsan_report_race() {\n  ReportRace(cur_thread());\n}\n#endif\n\nALWAYS_INLINE\nShadow LoadShadow(u64 *p) {\n  u64 raw = atomic_load((atomic_uint64_t*)p, memory_order_relaxed);\n  return Shadow(raw);\n}\n\nALWAYS_INLINE\nvoid StoreShadow(u64 *sp, u64 s) {\n  atomic_store((atomic_uint64_t*)sp, s, memory_order_relaxed);\n}\n\nALWAYS_INLINE\nvoid StoreIfNotYetStored(u64 *sp, u64 *s) {\n  StoreShadow(sp, *s);\n  *s = 0;\n}\n\nALWAYS_INLINE\nvoid HandleRace(ThreadState *thr, u64 *shadow_mem,\n                              Shadow cur, Shadow old) {\n  thr->racy_state[0] = cur.raw();\n  thr->racy_state[1] = old.raw();\n  thr->racy_shadow_addr = shadow_mem;\n#ifndef SANITIZER_GO\n  HACKY_CALL(__tsan_report_race);\n#else\n  ReportRace(thr);\n#endif\n}\n\nstatic inline bool HappensBefore(Shadow old, ThreadState *thr) {\n  return thr->clock.get(old.TidWithIgnore()) >= old.epoch();\n}\n\nALWAYS_INLINE\nvoid MemoryAccessImpl1(ThreadState *thr, uptr addr,\n    int kAccessSizeLog, bool kAccessIsWrite, bool kIsAtomic,\n    u64 *shadow_mem, Shadow cur) {\n  StatInc(thr, StatMop);\n  StatInc(thr, kAccessIsWrite ? StatMopWrite : StatMopRead);\n  StatInc(thr, (StatType)(StatMop1 + kAccessSizeLog));\n\n  // This potentially can live in an MMX/SSE scratch register.\n  // The required intrinsics are:\n  // __m128i _mm_move_epi64(__m128i*);\n  // _mm_storel_epi64(u64*, __m128i);\n  u64 store_word = cur.raw();\n\n  // scan all the shadow values and dispatch to 4 categories:\n  // same, replace, candidate and race (see comments below).\n  // we consider only 3 cases regarding access sizes:\n  // equal, intersect and not intersect. initially I considered\n  // larger and smaller as well, it allowed to replace some\n  // 'candidates' with 'same' or 'replace', but I think\n  // it's just not worth it (performance- and complexity-wise).\n\n  Shadow old(0);\n\n  // It release mode we manually unroll the loop,\n  // because empirically gcc generates better code this way.\n  // However, we can't afford unrolling in debug mode, because the function\n  // consumes almost 4K of stack. Gtest gives only 4K of stack to death test\n  // threads, which is not enough for the unrolled loop.\n#if SANITIZER_DEBUG\n  for (int idx = 0; idx < 4; idx++) {\n#include \"tsan_update_shadow_word_inl.h\"\n  }\n#else\n  int idx = 0;\n#include \"tsan_update_shadow_word_inl.h\"\n  idx = 1;\n#include \"tsan_update_shadow_word_inl.h\"\n  idx = 2;\n#include \"tsan_update_shadow_word_inl.h\"\n  idx = 3;\n#include \"tsan_update_shadow_word_inl.h\"\n#endif\n\n  // we did not find any races and had already stored\n  // the current access info, so we are done\n  if (LIKELY(store_word == 0))\n    return;\n  // choose a random candidate slot and replace it\n  StoreShadow(shadow_mem + (cur.epoch() % kShadowCnt), store_word);\n  StatInc(thr, StatShadowReplace);\n  return;\n RACE:\n  HandleRace(thr, shadow_mem, cur, old);\n  return;\n}\n\nvoid UnalignedMemoryAccess(ThreadState *thr, uptr pc, uptr addr,\n    int size, bool kAccessIsWrite, bool kIsAtomic) {\n  while (size) {\n    int size1 = 1;\n    int kAccessSizeLog = kSizeLog1;\n    if (size >= 8 && (addr & ~7) == ((addr + 7) & ~7)) {\n      size1 = 8;\n      kAccessSizeLog = kSizeLog8;\n    } else if (size >= 4 && (addr & ~7) == ((addr + 3) & ~7)) {\n      size1 = 4;\n      kAccessSizeLog = kSizeLog4;\n    } else if (size >= 2 && (addr & ~7) == ((addr + 1) & ~7)) {\n      size1 = 2;\n      kAccessSizeLog = kSizeLog2;\n    }\n    MemoryAccess(thr, pc, addr, kAccessSizeLog, kAccessIsWrite, kIsAtomic);\n    addr += size1;\n    size -= size1;\n  }\n}\n\nALWAYS_INLINE\nbool ContainsSameAccessSlow(u64 *s, u64 a, u64 sync_epoch, bool is_write) {\n  Shadow cur(a);\n  for (uptr i = 0; i < kShadowCnt; i++) {\n    Shadow old(LoadShadow(&s[i]));\n    if (Shadow::Addr0AndSizeAreEqual(cur, old) &&\n        old.TidWithIgnore() == cur.TidWithIgnore() &&\n        old.epoch() > sync_epoch &&\n        old.IsAtomic() == cur.IsAtomic() &&\n        old.IsRead() <= cur.IsRead())\n      return true;\n  }\n  return false;\n}\n\n#if defined(__SSE3__)\n#define SHUF(v0, v1, i0, i1, i2, i3) _mm_castps_si128(_mm_shuffle_ps( \\\n    _mm_castsi128_ps(v0), _mm_castsi128_ps(v1), \\\n    (i0)*1 + (i1)*4 + (i2)*16 + (i3)*64))\nALWAYS_INLINE\nbool ContainsSameAccessFast(u64 *s, u64 a, u64 sync_epoch, bool is_write) {\n  // This is an optimized version of ContainsSameAccessSlow.\n  // load current access into access[0:63]\n  const m128 access     = _mm_cvtsi64_si128(a);\n  // duplicate high part of access in addr0:\n  // addr0[0:31]        = access[32:63]\n  // addr0[32:63]       = access[32:63]\n  // addr0[64:95]       = access[32:63]\n  // addr0[96:127]      = access[32:63]\n  const m128 addr0      = SHUF(access, access, 1, 1, 1, 1);\n  // load 4 shadow slots\n  const m128 shadow0    = _mm_load_si128((__m128i*)s);\n  const m128 shadow1    = _mm_load_si128((__m128i*)s + 1);\n  // load high parts of 4 shadow slots into addr_vect:\n  // addr_vect[0:31]    = shadow0[32:63]\n  // addr_vect[32:63]   = shadow0[96:127]\n  // addr_vect[64:95]   = shadow1[32:63]\n  // addr_vect[96:127]  = shadow1[96:127]\n  m128 addr_vect        = SHUF(shadow0, shadow1, 1, 3, 1, 3);\n  if (!is_write) {\n    // set IsRead bit in addr_vect\n    const m128 rw_mask1 = _mm_cvtsi64_si128(1<<15);\n    const m128 rw_mask  = SHUF(rw_mask1, rw_mask1, 0, 0, 0, 0);\n    addr_vect           = _mm_or_si128(addr_vect, rw_mask);\n  }\n  // addr0 == addr_vect?\n  const m128 addr_res   = _mm_cmpeq_epi32(addr0, addr_vect);\n  // epoch1[0:63]       = sync_epoch\n  const m128 epoch1     = _mm_cvtsi64_si128(sync_epoch);\n  // epoch[0:31]        = sync_epoch[0:31]\n  // epoch[32:63]       = sync_epoch[0:31]\n  // epoch[64:95]       = sync_epoch[0:31]\n  // epoch[96:127]      = sync_epoch[0:31]\n  const m128 epoch      = SHUF(epoch1, epoch1, 0, 0, 0, 0);\n  // load low parts of shadow cell epochs into epoch_vect:\n  // epoch_vect[0:31]   = shadow0[0:31]\n  // epoch_vect[32:63]  = shadow0[64:95]\n  // epoch_vect[64:95]  = shadow1[0:31]\n  // epoch_vect[96:127] = shadow1[64:95]\n  const m128 epoch_vect = SHUF(shadow0, shadow1, 0, 2, 0, 2);\n  // epoch_vect >= sync_epoch?\n  const m128 epoch_res  = _mm_cmpgt_epi32(epoch_vect, epoch);\n  // addr_res & epoch_res\n  const m128 res        = _mm_and_si128(addr_res, epoch_res);\n  // mask[0] = res[7]\n  // mask[1] = res[15]\n  // ...\n  // mask[15] = res[127]\n  const int mask        = _mm_movemask_epi8(res);\n  return mask != 0;\n}\n#endif\n\nALWAYS_INLINE\nbool ContainsSameAccess(u64 *s, u64 a, u64 sync_epoch, bool is_write) {\n#if defined(__SSE3__)\n  bool res = ContainsSameAccessFast(s, a, sync_epoch, is_write);\n  // NOTE: this check can fail if the shadow is concurrently mutated\n  // by other threads. But it still can be useful if you modify\n  // ContainsSameAccessFast and want to ensure that it's not completely broken.\n  // DCHECK_EQ(res, ContainsSameAccessSlow(s, a, sync_epoch, is_write));\n  return res;\n#else\n  return ContainsSameAccessSlow(s, a, sync_epoch, is_write);\n#endif\n}\n\nALWAYS_INLINE USED\nvoid MemoryAccess(ThreadState *thr, uptr pc, uptr addr,\n    int kAccessSizeLog, bool kAccessIsWrite, bool kIsAtomic) {\n  u64 *shadow_mem = (u64*)MemToShadow(addr);\n  DPrintf2(\"#%d: MemoryAccess: @%p %p size=%d\"\n      \" is_write=%d shadow_mem=%p {%zx, %zx, %zx, %zx}\\n\",\n      (int)thr->fast_state.tid(), (void*)pc, (void*)addr,\n      (int)(1 << kAccessSizeLog), kAccessIsWrite, shadow_mem,\n      (uptr)shadow_mem[0], (uptr)shadow_mem[1],\n      (uptr)shadow_mem[2], (uptr)shadow_mem[3]);\n#if SANITIZER_DEBUG\n  if (!IsAppMem(addr)) {\n    Printf(\"Access to non app mem %zx\\n\", addr);\n    DCHECK(IsAppMem(addr));\n  }\n  if (!IsShadowMem((uptr)shadow_mem)) {\n    Printf(\"Bad shadow addr %p (%zx)\\n\", shadow_mem, addr);\n    DCHECK(IsShadowMem((uptr)shadow_mem));\n  }\n#endif\n\n  if (kCppMode && *shadow_mem == kShadowRodata) {\n    // Access to .rodata section, no races here.\n    // Measurements show that it can be 10-20% of all memory accesses.\n    StatInc(thr, StatMop);\n    StatInc(thr, kAccessIsWrite ? StatMopWrite : StatMopRead);\n    StatInc(thr, (StatType)(StatMop1 + kAccessSizeLog));\n    StatInc(thr, StatMopRodata);\n    return;\n  }\n\n  FastState fast_state = thr->fast_state;\n  if (fast_state.GetIgnoreBit()) {\n    StatInc(thr, StatMop);\n    StatInc(thr, kAccessIsWrite ? StatMopWrite : StatMopRead);\n    StatInc(thr, (StatType)(StatMop1 + kAccessSizeLog));\n    StatInc(thr, StatMopIgnored);\n    return;\n  }\n\n  Shadow cur(fast_state);\n  cur.SetAddr0AndSizeLog(addr & 7, kAccessSizeLog);\n  cur.SetWrite(kAccessIsWrite);\n  cur.SetAtomic(kIsAtomic);\n\n  if (LIKELY(ContainsSameAccess(shadow_mem, cur.raw(),\n      thr->fast_synch_epoch, kAccessIsWrite))) {\n    StatInc(thr, StatMop);\n    StatInc(thr, kAccessIsWrite ? StatMopWrite : StatMopRead);\n    StatInc(thr, (StatType)(StatMop1 + kAccessSizeLog));\n    StatInc(thr, StatMopSame);\n    return;\n  }\n\n  if (kCollectHistory) {\n    fast_state.IncrementEpoch();\n    thr->fast_state = fast_state;\n    TraceAddEvent(thr, fast_state, EventTypeMop, pc);\n    cur.IncrementEpoch();\n  }\n\n  MemoryAccessImpl1(thr, addr, kAccessSizeLog, kAccessIsWrite, kIsAtomic,\n      shadow_mem, cur);\n}\n\n// Called by MemoryAccessRange in tsan_rtl_thread.cc\nALWAYS_INLINE USED\nvoid MemoryAccessImpl(ThreadState *thr, uptr addr,\n    int kAccessSizeLog, bool kAccessIsWrite, bool kIsAtomic,\n    u64 *shadow_mem, Shadow cur) {\n  if (LIKELY(ContainsSameAccess(shadow_mem, cur.raw(),\n      thr->fast_synch_epoch, kAccessIsWrite))) {\n    StatInc(thr, StatMop);\n    StatInc(thr, kAccessIsWrite ? StatMopWrite : StatMopRead);\n    StatInc(thr, (StatType)(StatMop1 + kAccessSizeLog));\n    StatInc(thr, StatMopSame);\n    return;\n  }\n\n  MemoryAccessImpl1(thr, addr, kAccessSizeLog, kAccessIsWrite, kIsAtomic,\n      shadow_mem, cur);\n}\n\nstatic void MemoryRangeSet(ThreadState *thr, uptr pc, uptr addr, uptr size,\n                           u64 val) {\n  (void)thr;\n  (void)pc;\n  if (size == 0)\n    return;\n  // FIXME: fix me.\n  uptr offset = addr % kShadowCell;\n  if (offset) {\n    offset = kShadowCell - offset;\n    if (size <= offset)\n      return;\n    addr += offset;\n    size -= offset;\n  }\n  DCHECK_EQ(addr % 8, 0);\n  // If a user passes some insane arguments (memset(0)),\n  // let it just crash as usual.\n  if (!IsAppMem(addr) || !IsAppMem(addr + size - 1))\n    return;\n  // Don't want to touch lots of shadow memory.\n  // If a program maps 10MB stack, there is no need reset the whole range.\n  size = (size + (kShadowCell - 1)) & ~(kShadowCell - 1);\n  // UnmapOrDie/MmapFixedNoReserve does not work on Windows,\n  // so we do it only for C/C++.\n  if (kGoMode || size < common_flags()->clear_shadow_mmap_threshold) {\n    u64 *p = (u64*)MemToShadow(addr);\n    CHECK(IsShadowMem((uptr)p));\n    CHECK(IsShadowMem((uptr)(p + size * kShadowCnt / kShadowCell - 1)));\n    // FIXME: may overwrite a part outside the region\n    for (uptr i = 0; i < size / kShadowCell * kShadowCnt;) {\n      p[i++] = val;\n      for (uptr j = 1; j < kShadowCnt; j++)\n        p[i++] = 0;\n    }\n  } else {\n    // The region is big, reset only beginning and end.\n    const uptr kPageSize = GetPageSizeCached();\n    u64 *begin = (u64*)MemToShadow(addr);\n    u64 *end = begin + size / kShadowCell * kShadowCnt;\n    u64 *p = begin;\n    // Set at least first kPageSize/2 to page boundary.\n    while ((p < begin + kPageSize / kShadowSize / 2) || ((uptr)p % kPageSize)) {\n      *p++ = val;\n      for (uptr j = 1; j < kShadowCnt; j++)\n        *p++ = 0;\n    }\n    // Reset middle part.\n    u64 *p1 = p;\n    p = RoundDown(end, kPageSize);\n    UnmapOrDie((void*)p1, (uptr)p - (uptr)p1);\n    MmapFixedNoReserve((uptr)p1, (uptr)p - (uptr)p1);\n    // Set the ending.\n    while (p < end) {\n      *p++ = val;\n      for (uptr j = 1; j < kShadowCnt; j++)\n        *p++ = 0;\n    }\n  }\n}\n\nvoid MemoryResetRange(ThreadState *thr, uptr pc, uptr addr, uptr size) {\n  MemoryRangeSet(thr, pc, addr, size, 0);\n}\n\nvoid MemoryRangeFreed(ThreadState *thr, uptr pc, uptr addr, uptr size) {\n  // Processing more than 1k (4k of shadow) is expensive,\n  // can cause excessive memory consumption (user does not necessary touch\n  // the whole range) and most likely unnecessary.\n  if (size > 1024)\n    size = 1024;\n  CHECK_EQ(thr->is_freeing, false);\n  thr->is_freeing = true;\n  MemoryAccessRange(thr, pc, addr, size, true);\n  thr->is_freeing = false;\n  if (kCollectHistory) {\n    thr->fast_state.IncrementEpoch();\n    TraceAddEvent(thr, thr->fast_state, EventTypeMop, pc);\n  }\n  Shadow s(thr->fast_state);\n  s.ClearIgnoreBit();\n  s.MarkAsFreed();\n  s.SetWrite(true);\n  s.SetAddr0AndSizeLog(0, 3);\n  MemoryRangeSet(thr, pc, addr, size, s.raw());\n}\n\nvoid MemoryRangeImitateWrite(ThreadState *thr, uptr pc, uptr addr, uptr size) {\n  if (kCollectHistory) {\n    thr->fast_state.IncrementEpoch();\n    TraceAddEvent(thr, thr->fast_state, EventTypeMop, pc);\n  }\n  Shadow s(thr->fast_state);\n  s.ClearIgnoreBit();\n  s.SetWrite(true);\n  s.SetAddr0AndSizeLog(0, 3);\n  MemoryRangeSet(thr, pc, addr, size, s.raw());\n}\n\nALWAYS_INLINE USED\nvoid FuncEntry(ThreadState *thr, uptr pc) {\n  StatInc(thr, StatFuncEnter);\n  DPrintf2(\"#%d: FuncEntry %p\\n\", (int)thr->fast_state.tid(), (void*)pc);\n  if (kCollectHistory) {\n    thr->fast_state.IncrementEpoch();\n    TraceAddEvent(thr, thr->fast_state, EventTypeFuncEnter, pc);\n  }\n\n  // Shadow stack maintenance can be replaced with\n  // stack unwinding during trace switch (which presumably must be faster).\n  DCHECK_GE(thr->shadow_stack_pos, thr->shadow_stack);\n#ifndef SANITIZER_GO\n  DCHECK_LT(thr->shadow_stack_pos, thr->shadow_stack_end);\n#else\n  if (thr->shadow_stack_pos == thr->shadow_stack_end)\n    GrowShadowStack(thr);\n#endif\n  thr->shadow_stack_pos[0] = pc;\n  thr->shadow_stack_pos++;\n}\n\nALWAYS_INLINE USED\nvoid FuncExit(ThreadState *thr) {\n  StatInc(thr, StatFuncExit);\n  DPrintf2(\"#%d: FuncExit\\n\", (int)thr->fast_state.tid());\n  if (kCollectHistory) {\n    thr->fast_state.IncrementEpoch();\n    TraceAddEvent(thr, thr->fast_state, EventTypeFuncExit, 0);\n  }\n\n  DCHECK_GT(thr->shadow_stack_pos, thr->shadow_stack);\n#ifndef SANITIZER_GO\n  DCHECK_LT(thr->shadow_stack_pos, thr->shadow_stack_end);\n#endif\n  thr->shadow_stack_pos--;\n}\n\nvoid ThreadIgnoreBegin(ThreadState *thr, uptr pc) {\n  DPrintf(\"#%d: ThreadIgnoreBegin\\n\", thr->tid);\n  thr->ignore_reads_and_writes++;\n  CHECK_GT(thr->ignore_reads_and_writes, 0);\n  thr->fast_state.SetIgnoreBit();\n#ifndef SANITIZER_GO\n  if (!ctx->after_multithreaded_fork)\n    thr->mop_ignore_set.Add(CurrentStackId(thr, pc));\n#endif\n}\n\nvoid ThreadIgnoreEnd(ThreadState *thr, uptr pc) {\n  DPrintf(\"#%d: ThreadIgnoreEnd\\n\", thr->tid);\n  thr->ignore_reads_and_writes--;\n  CHECK_GE(thr->ignore_reads_and_writes, 0);\n  if (thr->ignore_reads_and_writes == 0) {\n    thr->fast_state.ClearIgnoreBit();\n#ifndef SANITIZER_GO\n    thr->mop_ignore_set.Reset();\n#endif\n  }\n}\n\nvoid ThreadIgnoreSyncBegin(ThreadState *thr, uptr pc) {\n  DPrintf(\"#%d: ThreadIgnoreSyncBegin\\n\", thr->tid);\n  thr->ignore_sync++;\n  CHECK_GT(thr->ignore_sync, 0);\n#ifndef SANITIZER_GO\n  if (!ctx->after_multithreaded_fork)\n    thr->sync_ignore_set.Add(CurrentStackId(thr, pc));\n#endif\n}\n\nvoid ThreadIgnoreSyncEnd(ThreadState *thr, uptr pc) {\n  DPrintf(\"#%d: ThreadIgnoreSyncEnd\\n\", thr->tid);\n  thr->ignore_sync--;\n  CHECK_GE(thr->ignore_sync, 0);\n#ifndef SANITIZER_GO\n  if (thr->ignore_sync == 0)\n    thr->sync_ignore_set.Reset();\n#endif\n}\n\nbool MD5Hash::operator==(const MD5Hash &other) const {\n  return hash[0] == other.hash[0] && hash[1] == other.hash[1];\n}\n\n#if SANITIZER_DEBUG\nvoid build_consistency_debug() {}\n#else\nvoid build_consistency_release() {}\n#endif\n\n#if TSAN_COLLECT_STATS\nvoid build_consistency_stats() {}\n#else\nvoid build_consistency_nostats() {}\n#endif\n\n}  // namespace __tsan\n\n#ifndef SANITIZER_GO\n// Must be included in this file to make sure everything is inlined.\n#include \"tsan_interface_inl.h\"\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_rtl.h",
    "content": "//===-- tsan_rtl.h ----------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Main internal TSan header file.\n//\n// Ground rules:\n//   - C++ run-time should not be used (static CTORs, RTTI, exceptions, static\n//     function-scope locals)\n//   - All functions/classes/etc reside in namespace __tsan, except for those\n//     declared in tsan_interface.h.\n//   - Platform-specific files should be used instead of ifdefs (*).\n//   - No system headers included in header files (*).\n//   - Platform specific headres included only into platform-specific files (*).\n//\n//  (*) Except when inlining is critical for performance.\n//===----------------------------------------------------------------------===//\n\n#ifndef TSAN_RTL_H\n#define TSAN_RTL_H\n\n#include \"sanitizer_common/sanitizer_allocator.h\"\n#include \"sanitizer_common/sanitizer_allocator_internal.h\"\n#include \"sanitizer_common/sanitizer_asm.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_deadlock_detector_interface.h\"\n#include \"sanitizer_common/sanitizer_libignore.h\"\n#include \"sanitizer_common/sanitizer_suppressions.h\"\n#include \"sanitizer_common/sanitizer_thread_registry.h\"\n#include \"tsan_clock.h\"\n#include \"tsan_defs.h\"\n#include \"tsan_flags.h\"\n#include \"tsan_sync.h\"\n#include \"tsan_trace.h\"\n#include \"tsan_vector.h\"\n#include \"tsan_report.h\"\n#include \"tsan_platform.h\"\n#include \"tsan_mutexset.h\"\n#include \"tsan_ignoreset.h\"\n#include \"tsan_stack_trace.h\"\n\n#if SANITIZER_WORDSIZE != 64\n# error \"ThreadSanitizer is supported only on 64-bit platforms\"\n#endif\n\nnamespace __tsan {\n\n#ifndef SANITIZER_GO\nstruct MapUnmapCallback;\n#if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__)\nstatic const uptr kAllocatorSpace = 0;\nstatic const uptr kAllocatorSize = SANITIZER_MMAP_RANGE_SIZE;\nstatic const uptr kAllocatorRegionSizeLog = 20;\nstatic const uptr kAllocatorNumRegions =\n    kAllocatorSize >> kAllocatorRegionSizeLog;\ntypedef TwoLevelByteMap<(kAllocatorNumRegions >> 12), 1 << 12,\n    MapUnmapCallback> ByteMap;\ntypedef SizeClassAllocator32<kAllocatorSpace, kAllocatorSize, 0,\n    CompactSizeClassMap, kAllocatorRegionSizeLog, ByteMap,\n    MapUnmapCallback> PrimaryAllocator;\n#else\ntypedef SizeClassAllocator64<Mapping::kHeapMemBeg,\n    Mapping::kHeapMemEnd - Mapping::kHeapMemBeg, 0,\n    DefaultSizeClassMap, MapUnmapCallback> PrimaryAllocator;\n#endif\ntypedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;\ntypedef LargeMmapAllocator<MapUnmapCallback> SecondaryAllocator;\ntypedef CombinedAllocator<PrimaryAllocator, AllocatorCache,\n    SecondaryAllocator> Allocator;\nAllocator *allocator();\n#endif\n\nvoid TsanCheckFailed(const char *file, int line, const char *cond,\n                     u64 v1, u64 v2);\n\nconst u64 kShadowRodata = (u64)-1;  // .rodata shadow marker\n\n// FastState (from most significant bit):\n//   ignore          : 1\n//   tid             : kTidBits\n//   unused          : -\n//   history_size    : 3\n//   epoch           : kClkBits\nclass FastState {\n public:\n  FastState(u64 tid, u64 epoch) {\n    x_ = tid << kTidShift;\n    x_ |= epoch;\n    DCHECK_EQ(tid, this->tid());\n    DCHECK_EQ(epoch, this->epoch());\n    DCHECK_EQ(GetIgnoreBit(), false);\n  }\n\n  explicit FastState(u64 x)\n      : x_(x) {\n  }\n\n  u64 raw() const {\n    return x_;\n  }\n\n  u64 tid() const {\n    u64 res = (x_ & ~kIgnoreBit) >> kTidShift;\n    return res;\n  }\n\n  u64 TidWithIgnore() const {\n    u64 res = x_ >> kTidShift;\n    return res;\n  }\n\n  u64 epoch() const {\n    u64 res = x_ & ((1ull << kClkBits) - 1);\n    return res;\n  }\n\n  void IncrementEpoch() {\n    u64 old_epoch = epoch();\n    x_ += 1;\n    DCHECK_EQ(old_epoch + 1, epoch());\n    (void)old_epoch;\n  }\n\n  void SetIgnoreBit() { x_ |= kIgnoreBit; }\n  void ClearIgnoreBit() { x_ &= ~kIgnoreBit; }\n  bool GetIgnoreBit() const { return (s64)x_ < 0; }\n\n  void SetHistorySize(int hs) {\n    CHECK_GE(hs, 0);\n    CHECK_LE(hs, 7);\n    x_ = (x_ & ~(kHistoryMask << kHistoryShift)) | (u64(hs) << kHistoryShift);\n  }\n\n  ALWAYS_INLINE\n  int GetHistorySize() const {\n    return (int)((x_ >> kHistoryShift) & kHistoryMask);\n  }\n\n  void ClearHistorySize() {\n    SetHistorySize(0);\n  }\n\n  ALWAYS_INLINE\n  u64 GetTracePos() const {\n    const int hs = GetHistorySize();\n    // When hs == 0, the trace consists of 2 parts.\n    const u64 mask = (1ull << (kTracePartSizeBits + hs + 1)) - 1;\n    return epoch() & mask;\n  }\n\n private:\n  friend class Shadow;\n  static const int kTidShift = 64 - kTidBits - 1;\n  static const u64 kIgnoreBit = 1ull << 63;\n  static const u64 kFreedBit = 1ull << 63;\n  static const u64 kHistoryShift = kClkBits;\n  static const u64 kHistoryMask = 7;\n  u64 x_;\n};\n\n// Shadow (from most significant bit):\n//   freed           : 1\n//   tid             : kTidBits\n//   is_atomic       : 1\n//   is_read         : 1\n//   size_log        : 2\n//   addr0           : 3\n//   epoch           : kClkBits\nclass Shadow : public FastState {\n public:\n  explicit Shadow(u64 x)\n      : FastState(x) {\n  }\n\n  explicit Shadow(const FastState &s)\n      : FastState(s.x_) {\n    ClearHistorySize();\n  }\n\n  void SetAddr0AndSizeLog(u64 addr0, unsigned kAccessSizeLog) {\n    DCHECK_EQ((x_ >> kClkBits) & 31, 0);\n    DCHECK_LE(addr0, 7);\n    DCHECK_LE(kAccessSizeLog, 3);\n    x_ |= ((kAccessSizeLog << 3) | addr0) << kClkBits;\n    DCHECK_EQ(kAccessSizeLog, size_log());\n    DCHECK_EQ(addr0, this->addr0());\n  }\n\n  void SetWrite(unsigned kAccessIsWrite) {\n    DCHECK_EQ(x_ & kReadBit, 0);\n    if (!kAccessIsWrite)\n      x_ |= kReadBit;\n    DCHECK_EQ(kAccessIsWrite, IsWrite());\n  }\n\n  void SetAtomic(bool kIsAtomic) {\n    DCHECK(!IsAtomic());\n    if (kIsAtomic)\n      x_ |= kAtomicBit;\n    DCHECK_EQ(IsAtomic(), kIsAtomic);\n  }\n\n  bool IsAtomic() const {\n    return x_ & kAtomicBit;\n  }\n\n  bool IsZero() const {\n    return x_ == 0;\n  }\n\n  static inline bool TidsAreEqual(const Shadow s1, const Shadow s2) {\n    u64 shifted_xor = (s1.x_ ^ s2.x_) >> kTidShift;\n    DCHECK_EQ(shifted_xor == 0, s1.TidWithIgnore() == s2.TidWithIgnore());\n    return shifted_xor == 0;\n  }\n\n  static ALWAYS_INLINE\n  bool Addr0AndSizeAreEqual(const Shadow s1, const Shadow s2) {\n    u64 masked_xor = ((s1.x_ ^ s2.x_) >> kClkBits) & 31;\n    return masked_xor == 0;\n  }\n\n  static ALWAYS_INLINE bool TwoRangesIntersect(Shadow s1, Shadow s2,\n      unsigned kS2AccessSize) {\n    bool res = false;\n    u64 diff = s1.addr0() - s2.addr0();\n    if ((s64)diff < 0) {  // s1.addr0 < s2.addr0  // NOLINT\n      // if (s1.addr0() + size1) > s2.addr0()) return true;\n      if (s1.size() > -diff)\n        res = true;\n    } else {\n      // if (s2.addr0() + kS2AccessSize > s1.addr0()) return true;\n      if (kS2AccessSize > diff)\n        res = true;\n    }\n    DCHECK_EQ(res, TwoRangesIntersectSlow(s1, s2));\n    DCHECK_EQ(res, TwoRangesIntersectSlow(s2, s1));\n    return res;\n  }\n\n  u64 ALWAYS_INLINE addr0() const { return (x_ >> kClkBits) & 7; }\n  u64 ALWAYS_INLINE size() const { return 1ull << size_log(); }\n  bool ALWAYS_INLINE IsWrite() const { return !IsRead(); }\n  bool ALWAYS_INLINE IsRead() const { return x_ & kReadBit; }\n\n  // The idea behind the freed bit is as follows.\n  // When the memory is freed (or otherwise unaccessible) we write to the shadow\n  // values with tid/epoch related to the free and the freed bit set.\n  // During memory accesses processing the freed bit is considered\n  // as msb of tid. So any access races with shadow with freed bit set\n  // (it is as if write from a thread with which we never synchronized before).\n  // This allows us to detect accesses to freed memory w/o additional\n  // overheads in memory access processing and at the same time restore\n  // tid/epoch of free.\n  void MarkAsFreed() {\n     x_ |= kFreedBit;\n  }\n\n  bool IsFreed() const {\n    return x_ & kFreedBit;\n  }\n\n  bool GetFreedAndReset() {\n    bool res = x_ & kFreedBit;\n    x_ &= ~kFreedBit;\n    return res;\n  }\n\n  bool ALWAYS_INLINE IsBothReadsOrAtomic(bool kIsWrite, bool kIsAtomic) const {\n    bool v = x_ & ((u64(kIsWrite ^ 1) << kReadShift)\n        | (u64(kIsAtomic) << kAtomicShift));\n    DCHECK_EQ(v, (!IsWrite() && !kIsWrite) || (IsAtomic() && kIsAtomic));\n    return v;\n  }\n\n  bool ALWAYS_INLINE IsRWNotWeaker(bool kIsWrite, bool kIsAtomic) const {\n    bool v = ((x_ >> kReadShift) & 3)\n        <= u64((kIsWrite ^ 1) | (kIsAtomic << 1));\n    DCHECK_EQ(v, (IsAtomic() < kIsAtomic) ||\n        (IsAtomic() == kIsAtomic && !IsWrite() <= !kIsWrite));\n    return v;\n  }\n\n  bool ALWAYS_INLINE IsRWWeakerOrEqual(bool kIsWrite, bool kIsAtomic) const {\n    bool v = ((x_ >> kReadShift) & 3)\n        >= u64((kIsWrite ^ 1) | (kIsAtomic << 1));\n    DCHECK_EQ(v, (IsAtomic() > kIsAtomic) ||\n        (IsAtomic() == kIsAtomic && !IsWrite() >= !kIsWrite));\n    return v;\n  }\n\n private:\n  static const u64 kReadShift   = 5 + kClkBits;\n  static const u64 kReadBit     = 1ull << kReadShift;\n  static const u64 kAtomicShift = 6 + kClkBits;\n  static const u64 kAtomicBit   = 1ull << kAtomicShift;\n\n  u64 size_log() const { return (x_ >> (3 + kClkBits)) & 3; }\n\n  static bool TwoRangesIntersectSlow(const Shadow s1, const Shadow s2) {\n    if (s1.addr0() == s2.addr0()) return true;\n    if (s1.addr0() < s2.addr0() && s1.addr0() + s1.size() > s2.addr0())\n      return true;\n    if (s2.addr0() < s1.addr0() && s2.addr0() + s2.size() > s1.addr0())\n      return true;\n    return false;\n  }\n};\n\nstruct ThreadSignalContext;\n\nstruct JmpBuf {\n  uptr sp;\n  uptr mangled_sp;\n  int int_signal_send;\n  bool in_blocking_func;\n  uptr in_signal_handler;\n  uptr *shadow_stack_pos;\n};\n\n// This struct is stored in TLS.\nstruct ThreadState {\n  FastState fast_state;\n  // Synch epoch represents the threads's epoch before the last synchronization\n  // action. It allows to reduce number of shadow state updates.\n  // For example, fast_synch_epoch=100, last write to addr X was at epoch=150,\n  // if we are processing write to X from the same thread at epoch=200,\n  // we do nothing, because both writes happen in the same 'synch epoch'.\n  // That is, if another memory access does not race with the former write,\n  // it does not race with the latter as well.\n  // QUESTION: can we can squeeze this into ThreadState::Fast?\n  // E.g. ThreadState::Fast is a 44-bit, 32 are taken by synch_epoch and 12 are\n  // taken by epoch between synchs.\n  // This way we can save one load from tls.\n  u64 fast_synch_epoch;\n  // This is a slow path flag. On fast path, fast_state.GetIgnoreBit() is read.\n  // We do not distinguish beteween ignoring reads and writes\n  // for better performance.\n  int ignore_reads_and_writes;\n  int ignore_sync;\n  // Go does not support ignores.\n#ifndef SANITIZER_GO\n  IgnoreSet mop_ignore_set;\n  IgnoreSet sync_ignore_set;\n#endif\n  // C/C++ uses fixed size shadow stack embed into Trace.\n  // Go uses malloc-allocated shadow stack with dynamic size.\n  uptr *shadow_stack;\n  uptr *shadow_stack_end;\n  uptr *shadow_stack_pos;\n  u64 *racy_shadow_addr;\n  u64 racy_state[2];\n  MutexSet mset;\n  ThreadClock clock;\n#ifndef SANITIZER_GO\n  AllocatorCache alloc_cache;\n  InternalAllocatorCache internal_alloc_cache;\n  Vector<JmpBuf> jmp_bufs;\n  int ignore_interceptors;\n#endif\n#if TSAN_COLLECT_STATS\n  u64 stat[StatCnt];\n#endif\n  const int tid;\n  const int unique_id;\n  bool in_symbolizer;\n  bool in_ignored_lib;\n  bool is_inited;\n  bool is_dead;\n  bool is_freeing;\n  bool is_vptr_access;\n  const uptr stk_addr;\n  const uptr stk_size;\n  const uptr tls_addr;\n  const uptr tls_size;\n  ThreadContext *tctx;\n\n#if SANITIZER_DEBUG && !SANITIZER_GO\n  InternalDeadlockDetector internal_deadlock_detector;\n#endif\n  DDPhysicalThread *dd_pt;\n  DDLogicalThread *dd_lt;\n\n  atomic_uintptr_t in_signal_handler;\n  ThreadSignalContext *signal_ctx;\n\n  DenseSlabAllocCache block_cache;\n  DenseSlabAllocCache sync_cache;\n  DenseSlabAllocCache clock_cache;\n\n#ifndef SANITIZER_GO\n  u32 last_sleep_stack_id;\n  ThreadClock last_sleep_clock;\n#endif\n\n  // Set in regions of runtime that must be signal-safe and fork-safe.\n  // If set, malloc must not be called.\n  int nomalloc;\n\n  explicit ThreadState(Context *ctx, int tid, int unique_id, u64 epoch,\n                       unsigned reuse_count,\n                       uptr stk_addr, uptr stk_size,\n                       uptr tls_addr, uptr tls_size);\n};\n\n#ifndef SANITIZER_GO\n#if SANITIZER_MAC\nThreadState *cur_thread();\nvoid cur_thread_finalize();\n#else\n__attribute__((tls_model(\"initial-exec\")))\nextern THREADLOCAL char cur_thread_placeholder[];\nINLINE ThreadState *cur_thread() {\n  return reinterpret_cast<ThreadState *>(&cur_thread_placeholder);\n}\nINLINE void cur_thread_finalize() { }\n#endif  // SANITIZER_MAC\n#endif  // SANITIZER_GO\n\nclass ThreadContext : public ThreadContextBase {\n public:\n  explicit ThreadContext(int tid);\n  ~ThreadContext();\n  ThreadState *thr;\n  u32 creation_stack_id;\n  SyncClock sync;\n  // Epoch at which the thread had started.\n  // If we see an event from the thread stamped by an older epoch,\n  // the event is from a dead thread that shared tid with this thread.\n  u64 epoch0;\n  u64 epoch1;\n\n  // Override superclass callbacks.\n  void OnDead() override;\n  void OnJoined(void *arg) override;\n  void OnFinished() override;\n  void OnStarted(void *arg) override;\n  void OnCreated(void *arg) override;\n  void OnReset() override;\n  void OnDetached(void *arg) override;\n};\n\nstruct RacyStacks {\n  MD5Hash hash[2];\n  bool operator==(const RacyStacks &other) const {\n    if (hash[0] == other.hash[0] && hash[1] == other.hash[1])\n      return true;\n    if (hash[0] == other.hash[1] && hash[1] == other.hash[0])\n      return true;\n    return false;\n  }\n};\n\nstruct RacyAddress {\n  uptr addr_min;\n  uptr addr_max;\n};\n\nstruct FiredSuppression {\n  ReportType type;\n  uptr pc_or_addr;\n  Suppression *supp;\n};\n\nstruct Context {\n  Context();\n\n  bool initialized;\n  bool after_multithreaded_fork;\n\n  MetaMap metamap;\n\n  Mutex report_mtx;\n  int nreported;\n  int nmissed_expected;\n  atomic_uint64_t last_symbolize_time_ns;\n\n  void *background_thread;\n  atomic_uint32_t stop_background_thread;\n\n  ThreadRegistry *thread_registry;\n\n  Mutex racy_mtx;\n  Vector<RacyStacks> racy_stacks;\n  Vector<RacyAddress> racy_addresses;\n  // Number of fired suppressions may be large enough.\n  Mutex fired_suppressions_mtx;\n  InternalMmapVector<FiredSuppression> fired_suppressions;\n  DDetector *dd;\n\n  ClockAlloc clock_alloc;\n\n  Flags flags;\n\n  u64 stat[StatCnt];\n  u64 int_alloc_cnt[MBlockTypeCount];\n  u64 int_alloc_siz[MBlockTypeCount];\n};\n\nextern Context *ctx;  // The one and the only global runtime context.\n\nstruct ScopedIgnoreInterceptors {\n  ScopedIgnoreInterceptors() {\n#ifndef SANITIZER_GO\n    cur_thread()->ignore_interceptors++;\n#endif\n  }\n\n  ~ScopedIgnoreInterceptors() {\n#ifndef SANITIZER_GO\n    cur_thread()->ignore_interceptors--;\n#endif\n  }\n};\n\nclass ScopedReport {\n public:\n  explicit ScopedReport(ReportType typ);\n  ~ScopedReport();\n\n  void AddMemoryAccess(uptr addr, Shadow s, StackTrace stack,\n                       const MutexSet *mset);\n  void AddStack(StackTrace stack, bool suppressable = false);\n  void AddThread(const ThreadContext *tctx, bool suppressable = false);\n  void AddThread(int unique_tid, bool suppressable = false);\n  void AddUniqueTid(int unique_tid);\n  void AddMutex(const SyncVar *s);\n  u64 AddMutex(u64 id);\n  void AddLocation(uptr addr, uptr size);\n  void AddSleep(u32 stack_id);\n  void SetCount(int count);\n\n  const ReportDesc *GetReport() const;\n\n private:\n  ReportDesc *rep_;\n  // Symbolizer makes lots of intercepted calls. If we try to process them,\n  // at best it will cause deadlocks on internal mutexes.\n  ScopedIgnoreInterceptors ignore_interceptors_;\n\n  void AddDeadMutex(u64 id);\n\n  ScopedReport(const ScopedReport&);\n  void operator = (const ScopedReport&);\n};\n\nvoid RestoreStack(int tid, const u64 epoch, VarSizeStackTrace *stk,\n                  MutexSet *mset);\n\ntemplate<typename StackTraceTy>\nvoid ObtainCurrentStack(ThreadState *thr, uptr toppc, StackTraceTy *stack) {\n  uptr size = thr->shadow_stack_pos - thr->shadow_stack;\n  uptr start = 0;\n  if (size + !!toppc > kStackTraceMax) {\n    start = size + !!toppc - kStackTraceMax;\n    size = kStackTraceMax - !!toppc;\n  }\n  stack->Init(&thr->shadow_stack[start], size, toppc);\n}\n\n\n#if TSAN_COLLECT_STATS\nvoid StatAggregate(u64 *dst, u64 *src);\nvoid StatOutput(u64 *stat);\n#endif\n\nvoid ALWAYS_INLINE StatInc(ThreadState *thr, StatType typ, u64 n = 1) {\n#if TSAN_COLLECT_STATS\n  thr->stat[typ] += n;\n#endif\n}\nvoid ALWAYS_INLINE StatSet(ThreadState *thr, StatType typ, u64 n) {\n#if TSAN_COLLECT_STATS\n  thr->stat[typ] = n;\n#endif\n}\n\nvoid MapShadow(uptr addr, uptr size);\nvoid MapThreadTrace(uptr addr, uptr size, const char *name);\nvoid DontNeedShadowFor(uptr addr, uptr size);\nvoid InitializeShadowMemory();\nvoid InitializeInterceptors();\nvoid InitializeLibIgnore();\nvoid InitializeDynamicAnnotations();\n\nvoid ForkBefore(ThreadState *thr, uptr pc);\nvoid ForkParentAfter(ThreadState *thr, uptr pc);\nvoid ForkChildAfter(ThreadState *thr, uptr pc);\n\nvoid ReportRace(ThreadState *thr);\nbool OutputReport(ThreadState *thr, const ScopedReport &srep);\nbool IsFiredSuppression(Context *ctx, ReportType type, StackTrace trace);\nbool IsExpectedReport(uptr addr, uptr size);\nvoid PrintMatchedBenignRaces();\n\n#if defined(TSAN_DEBUG_OUTPUT) && TSAN_DEBUG_OUTPUT >= 1\n# define DPrintf Printf\n#else\n# define DPrintf(...)\n#endif\n\n#if defined(TSAN_DEBUG_OUTPUT) && TSAN_DEBUG_OUTPUT >= 2\n# define DPrintf2 Printf\n#else\n# define DPrintf2(...)\n#endif\n\nu32 CurrentStackId(ThreadState *thr, uptr pc);\nReportStack *SymbolizeStackId(u32 stack_id);\nvoid PrintCurrentStack(ThreadState *thr, uptr pc);\nvoid PrintCurrentStackSlow(uptr pc);  // uses libunwind\n\nvoid Initialize(ThreadState *thr);\nint Finalize(ThreadState *thr);\n\nvoid OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write);\nvoid OnUserFree(ThreadState *thr, uptr pc, uptr p, bool write);\n\nvoid MemoryAccess(ThreadState *thr, uptr pc, uptr addr,\n    int kAccessSizeLog, bool kAccessIsWrite, bool kIsAtomic);\nvoid MemoryAccessImpl(ThreadState *thr, uptr addr,\n    int kAccessSizeLog, bool kAccessIsWrite, bool kIsAtomic,\n    u64 *shadow_mem, Shadow cur);\nvoid MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr,\n    uptr size, bool is_write);\nvoid MemoryAccessRangeStep(ThreadState *thr, uptr pc, uptr addr,\n    uptr size, uptr step, bool is_write);\nvoid UnalignedMemoryAccess(ThreadState *thr, uptr pc, uptr addr,\n    int size, bool kAccessIsWrite, bool kIsAtomic);\n\nconst int kSizeLog1 = 0;\nconst int kSizeLog2 = 1;\nconst int kSizeLog4 = 2;\nconst int kSizeLog8 = 3;\n\nvoid ALWAYS_INLINE MemoryRead(ThreadState *thr, uptr pc,\n                                     uptr addr, int kAccessSizeLog) {\n  MemoryAccess(thr, pc, addr, kAccessSizeLog, false, false);\n}\n\nvoid ALWAYS_INLINE MemoryWrite(ThreadState *thr, uptr pc,\n                                      uptr addr, int kAccessSizeLog) {\n  MemoryAccess(thr, pc, addr, kAccessSizeLog, true, false);\n}\n\nvoid ALWAYS_INLINE MemoryReadAtomic(ThreadState *thr, uptr pc,\n                                           uptr addr, int kAccessSizeLog) {\n  MemoryAccess(thr, pc, addr, kAccessSizeLog, false, true);\n}\n\nvoid ALWAYS_INLINE MemoryWriteAtomic(ThreadState *thr, uptr pc,\n                                            uptr addr, int kAccessSizeLog) {\n  MemoryAccess(thr, pc, addr, kAccessSizeLog, true, true);\n}\n\nvoid MemoryResetRange(ThreadState *thr, uptr pc, uptr addr, uptr size);\nvoid MemoryRangeFreed(ThreadState *thr, uptr pc, uptr addr, uptr size);\nvoid MemoryRangeImitateWrite(ThreadState *thr, uptr pc, uptr addr, uptr size);\n\nvoid ThreadIgnoreBegin(ThreadState *thr, uptr pc);\nvoid ThreadIgnoreEnd(ThreadState *thr, uptr pc);\nvoid ThreadIgnoreSyncBegin(ThreadState *thr, uptr pc);\nvoid ThreadIgnoreSyncEnd(ThreadState *thr, uptr pc);\n\nvoid FuncEntry(ThreadState *thr, uptr pc);\nvoid FuncExit(ThreadState *thr);\n\nint ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached);\nvoid ThreadStart(ThreadState *thr, int tid, uptr os_id);\nvoid ThreadFinish(ThreadState *thr);\nint ThreadTid(ThreadState *thr, uptr pc, uptr uid);\nvoid ThreadJoin(ThreadState *thr, uptr pc, int tid);\nvoid ThreadDetach(ThreadState *thr, uptr pc, int tid);\nvoid ThreadFinalize(ThreadState *thr);\nvoid ThreadSetName(ThreadState *thr, const char *name);\nint ThreadCount(ThreadState *thr);\nvoid ProcessPendingSignals(ThreadState *thr);\n\nvoid MutexCreate(ThreadState *thr, uptr pc, uptr addr,\n                 bool rw, bool recursive, bool linker_init);\nvoid MutexDestroy(ThreadState *thr, uptr pc, uptr addr);\nvoid MutexLock(ThreadState *thr, uptr pc, uptr addr, int rec = 1,\n               bool try_lock = false);\nint  MutexUnlock(ThreadState *thr, uptr pc, uptr addr, bool all = false);\nvoid MutexReadLock(ThreadState *thr, uptr pc, uptr addr, bool try_lock = false);\nvoid MutexReadUnlock(ThreadState *thr, uptr pc, uptr addr);\nvoid MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr);\nvoid MutexRepair(ThreadState *thr, uptr pc, uptr addr);  // call on EOWNERDEAD\n\nvoid Acquire(ThreadState *thr, uptr pc, uptr addr);\n// AcquireGlobal synchronizes the current thread with all other threads.\n// In terms of happens-before relation, it draws a HB edge from all threads\n// (where they happen to execute right now) to the current thread. We use it to\n// handle Go finalizers. Namely, finalizer goroutine executes AcquireGlobal\n// right before executing finalizers. This provides a coarse, but simple\n// approximation of the actual required synchronization.\nvoid AcquireGlobal(ThreadState *thr, uptr pc);\nvoid Release(ThreadState *thr, uptr pc, uptr addr);\nvoid ReleaseStore(ThreadState *thr, uptr pc, uptr addr);\nvoid AfterSleep(ThreadState *thr, uptr pc);\nvoid AcquireImpl(ThreadState *thr, uptr pc, SyncClock *c);\nvoid ReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c);\nvoid ReleaseStoreImpl(ThreadState *thr, uptr pc, SyncClock *c);\nvoid AcquireReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c);\n\n// The hacky call uses custom calling convention and an assembly thunk.\n// It is considerably faster that a normal call for the caller\n// if it is not executed (it is intended for slow paths from hot functions).\n// The trick is that the call preserves all registers and the compiler\n// does not treat it as a call.\n// If it does not work for you, use normal call.\n#if !SANITIZER_DEBUG && defined(__x86_64__) && !SANITIZER_MAC\n// The caller may not create the stack frame for itself at all,\n// so we create a reserve stack frame for it (1024b must be enough).\n#define HACKY_CALL(f) \\\n  __asm__ __volatile__(\"sub $1024, %%rsp;\" \\\n                       CFI_INL_ADJUST_CFA_OFFSET(1024) \\\n                       \".hidden \" #f \"_thunk;\" \\\n                       \"call \" #f \"_thunk;\" \\\n                       \"add $1024, %%rsp;\" \\\n                       CFI_INL_ADJUST_CFA_OFFSET(-1024) \\\n                       ::: \"memory\", \"cc\");\n#else\n#define HACKY_CALL(f) f()\n#endif\n\nvoid TraceSwitch(ThreadState *thr);\nuptr TraceTopPC(ThreadState *thr);\nuptr TraceSize();\nuptr TraceParts();\nTrace *ThreadTrace(int tid);\n\nextern \"C\" void __tsan_trace_switch();\nvoid ALWAYS_INLINE TraceAddEvent(ThreadState *thr, FastState fs,\n                                        EventType typ, u64 addr) {\n  if (!kCollectHistory)\n    return;\n  DCHECK_GE((int)typ, 0);\n  DCHECK_LE((int)typ, 7);\n  DCHECK_EQ(GetLsb(addr, 61), addr);\n  StatInc(thr, StatEvents);\n  u64 pos = fs.GetTracePos();\n  if (UNLIKELY((pos % kTracePartSize) == 0)) {\n#ifndef SANITIZER_GO\n    HACKY_CALL(__tsan_trace_switch);\n#else\n    TraceSwitch(thr);\n#endif\n  }\n  Event *trace = (Event*)GetThreadTrace(fs.tid());\n  Event *evp = &trace[pos];\n  Event ev = (u64)addr | ((u64)typ << 61);\n  *evp = ev;\n}\n\n#ifndef SANITIZER_GO\nuptr ALWAYS_INLINE HeapEnd() {\n  return HeapMemEnd() + PrimaryAllocator::AdditionalSize();\n}\n#endif\n\n}  // namespace __tsan\n\n#endif  // TSAN_RTL_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_rtl_aarch64.S",
    "content": "#include \"sanitizer_common/sanitizer_asm.h\"\n.section .text\n\n.hidden __tsan_setjmp\n.comm _ZN14__interception11real_setjmpE,8,8\n.type setjmp, @function\nsetjmp:\n  CFI_STARTPROC\n\n  // save env parameters for function call\n  stp     x29, x30, [sp, -32]!\n  CFI_DEF_CFA_OFFSET (32)\n  CFI_OFFSET (29, -32)\n  CFI_OFFSET (30, -24)\n\n  // Adjust the SP for previous frame\n  add     x29, sp, 0\n  CFI_DEF_CFA_REGISTER (29)\n\n  // Save jmp_buf\n  str     x19, [sp, 16]\n  CFI_OFFSET (19, -16)\n  mov     x19, x0\n\n  // SP pointer mangling (see glibc setjmp)\n  adrp    x2, :got:__pointer_chk_guard\n  ldr     x2, [x2, #:got_lo12:__pointer_chk_guard]\n  add     x0, x29, 32\n  ldr     x2, [x2]\n  eor     x1, x2, x0\n\n  // call tsan interceptor\n  bl      __tsan_setjmp\n\n  // restore env parameter\n  mov     x0, x19\n  ldr     x19, [sp, 16]\n  ldp     x29, x30, [sp], 32\n  CFI_RESTORE (30)\n  CFI_RESTORE (19)\n  CFI_DEF_CFA (31, 0)\n\n  // tail jump to libc setjmp\n  adrp    x1, :got:_ZN14__interception11real_setjmpE\n  ldr     x1, [x1, #:got_lo12:_ZN14__interception11real_setjmpE]\n  ldr     x1, [x1]\n  br      x1\n\n  CFI_ENDPROC\n.size setjmp, .-setjmp\n\n.comm _ZN14__interception12real__setjmpE,8,8\n.globl _setjmp\n.type _setjmp, @function\n_setjmp:\n  CFI_STARTPROC\n\n  // save env parameters for function call\n  stp     x29, x30, [sp, -32]!\n  CFI_DEF_CFA_OFFSET (32)\n  CFI_OFFSET (29, -32)\n  CFI_OFFSET (30, -24)\n\n  // Adjust the SP for previous frame\n  add     x29, sp, 0\n  CFI_DEF_CFA_REGISTER (29)\n\n  // Save jmp_buf\n  str     x19, [sp, 16]\n  CFI_OFFSET (19, -16)\n  mov     x19, x0\n\n  // SP pointer mangling (see glibc setjmp)\n  adrp    x2, :got:__pointer_chk_guard\n  ldr     x2, [x2, #:got_lo12:__pointer_chk_guard]\n  add     x0, x29, 32\n  ldr     x2, [x2]\n  eor     x1, x2, x0\n\n  // call tsan interceptor\n  bl      __tsan_setjmp\n\n  // Restore jmp_buf parameter\n  mov     x0, x19\n  ldr     x19, [sp, 16]\n  ldp     x29, x30, [sp], 32\n  CFI_RESTORE (30)\n  CFI_RESTORE (19)\n  CFI_DEF_CFA (31, 0)\n\n  // tail jump to libc setjmp\n  adrp    x1, :got:_ZN14__interception12real__setjmpE\n  ldr     x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE]\n  ldr     x1, [x1]\n  br      x1\n\n  CFI_ENDPROC\n.size _setjmp, .-_setjmp\n\n.comm _ZN14__interception14real_sigsetjmpE,8,8\n.globl sigsetjmp\n.type sigsetjmp, @function\nsigsetjmp:\n  CFI_STARTPROC\n\n  // save env parameters for function call\n  stp     x29, x30, [sp, -32]!\n  CFI_DEF_CFA_OFFSET (32)\n  CFI_OFFSET (29, -32)\n  CFI_OFFSET (30, -24)\n\n  // Adjust the SP for previous frame\n  add     x29, sp, 0\n  CFI_DEF_CFA_REGISTER (29)\n\n  // Save jmp_buf and savesigs\n  stp     x19, x20, [sp, 16]\n  CFI_OFFSET (19, -16)\n  CFI_OFFSET (20, -8)\n  mov     w20, w1\n  mov     x19, x0\n\n  // SP pointer mangling (see glibc setjmp)\n  adrp    x2, :got:__pointer_chk_guard\n  ldr     x2, [x2, #:got_lo12:__pointer_chk_guard]\n  add     x0, x29, 32\n  ldr     x2, [x2]\n  eor     x1, x2, x0\n\n  // call tsan interceptor\n  bl      __tsan_setjmp\n\n  // restore env parameter\n  mov     w1, w20\n  mov     x0, x19\n  ldp     x19, x20, [sp, 16]\n  ldp     x29, x30, [sp], 32\n  CFI_RESTORE (30)\n  CFI_RESTORE (29)\n  CFI_RESTORE (19)\n  CFI_RESTORE (20)\n  CFI_DEF_CFA (31, 0)\n\n  // tail jump to libc sigsetjmp\n  adrp    x2, :got:_ZN14__interception14real_sigsetjmpE\n  ldr     x2, [x2, #:got_lo12:_ZN14__interception14real_sigsetjmpE]\n  ldr     x2, [x2]\n  br      x2\n  CFI_ENDPROC\n.size sigsetjmp, .-sigsetjmp\n\n.comm _ZN14__interception16real___sigsetjmpE,8,8\n.globl __sigsetjmp\n.type __sigsetjmp, @function\n__sigsetjmp:\n  CFI_STARTPROC\n\n  // save env parameters for function call\n  stp     x29, x30, [sp, -32]!\n  CFI_DEF_CFA_OFFSET (32)\n  CFI_OFFSET (29, -32)\n  CFI_OFFSET (30, -24)\n\n  // Adjust the SP for previous frame\n  add     x29, sp, 0\n  CFI_DEF_CFA_REGISTER (29)\n\n  // Save jmp_buf and savesigs\n  stp     x19, x20, [sp, 16]\n  CFI_OFFSET (19, -16)\n  CFI_OFFSET (20, -8)\n  mov     w20, w1\n  mov     x19, x0\n\n  // SP pointer mangling (see glibc setjmp)\n  adrp    x2, :got:__pointer_chk_guard\n  ldr     x2, [x2, #:got_lo12:__pointer_chk_guard]\n  add     x0, x29, 32\n  ldr     x2, [x2]\n  eor     x1, x2, x0\n\n  // call tsan interceptor\n  bl      __tsan_setjmp\n\n  mov     w1, w20\n  mov     x0, x19\n  ldp     x19, x20, [sp, 16]\n  ldp     x29, x30, [sp], 32\n  CFI_RESTORE (30)\n  CFI_RESTORE (29)\n  CFI_RESTORE (19)\n  CFI_RESTORE (20)\n  CFI_DEF_CFA (31, 0)\n\n  // tail jump to libc __sigsetjmp\n  adrp    x2, :got:_ZN14__interception16real___sigsetjmpE\n  ldr     x2, [x2, #:got_lo12:_ZN14__interception16real___sigsetjmpE]\n  ldr     x2, [x2]\n  br      x2\n  CFI_ENDPROC\n.size __sigsetjmp, .-__sigsetjmp\n\n#if defined(__linux__)\n/* We do not need executable stack.  */\n.section        .note.GNU-stack,\"\",@progbits\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_rtl_amd64.S",
    "content": "#include \"sanitizer_common/sanitizer_asm.h\"\n#if !defined(__APPLE__)\n.section .text\n#else\n.section __TEXT,__text\n#endif\n\nASM_HIDDEN(__tsan_trace_switch)\n.globl ASM_TSAN_SYMBOL(__tsan_trace_switch_thunk)\nASM_TSAN_SYMBOL(__tsan_trace_switch_thunk):\n  CFI_STARTPROC\n  # Save scratch registers.\n  push %rax\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rax, 0)\n  push %rcx\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rcx, 0)\n  push %rdx\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rdx, 0)\n  push %rsi\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rsi, 0)\n  push %rdi\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rdi, 0)\n  push %r8\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%r8, 0)\n  push %r9\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%r9, 0)\n  push %r10\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%r10, 0)\n  push %r11\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%r11, 0)\n  # Align stack frame.\n  push %rbx  # non-scratch\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rbx, 0)\n  mov %rsp, %rbx  # save current rsp\n  CFI_DEF_CFA_REGISTER(%rbx)\n  shr $4, %rsp  # clear 4 lsb, align to 16\n  shl $4, %rsp\n\n  call ASM_TSAN_SYMBOL(__tsan_trace_switch)\n\n  # Unalign stack frame back.\n  mov %rbx, %rsp  # restore the original rsp\n  CFI_DEF_CFA_REGISTER(%rsp)\n  pop %rbx\n  CFI_ADJUST_CFA_OFFSET(-8)\n  # Restore scratch registers.\n  pop %r11\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %r10\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %r9\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %r8\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %rdi\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %rsi\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %rdx\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %rcx\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %rax\n  CFI_ADJUST_CFA_OFFSET(-8)\n  CFI_RESTORE(%rax)\n  CFI_RESTORE(%rbx)\n  CFI_RESTORE(%rcx)\n  CFI_RESTORE(%rdx)\n  CFI_RESTORE(%rsi)\n  CFI_RESTORE(%rdi)\n  CFI_RESTORE(%r8)\n  CFI_RESTORE(%r9)\n  CFI_RESTORE(%r10)\n  CFI_RESTORE(%r11)\n  ret\n  CFI_ENDPROC\n\nASM_HIDDEN(__tsan_report_race)\n.globl ASM_TSAN_SYMBOL(__tsan_report_race_thunk)\nASM_TSAN_SYMBOL(__tsan_report_race_thunk):\n  CFI_STARTPROC\n  # Save scratch registers.\n  push %rax\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rax, 0)\n  push %rcx\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rcx, 0)\n  push %rdx\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rdx, 0)\n  push %rsi\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rsi, 0)\n  push %rdi\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rdi, 0)\n  push %r8\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%r8, 0)\n  push %r9\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%r9, 0)\n  push %r10\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%r10, 0)\n  push %r11\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%r11, 0)\n  # Align stack frame.\n  push %rbx  # non-scratch\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rbx, 0)\n  mov %rsp, %rbx  # save current rsp\n  CFI_DEF_CFA_REGISTER(%rbx)\n  shr $4, %rsp  # clear 4 lsb, align to 16\n  shl $4, %rsp\n\n  call ASM_TSAN_SYMBOL(__tsan_report_race)\n\n  # Unalign stack frame back.\n  mov %rbx, %rsp  # restore the original rsp\n  CFI_DEF_CFA_REGISTER(%rsp)\n  pop %rbx\n  CFI_ADJUST_CFA_OFFSET(-8)\n  # Restore scratch registers.\n  pop %r11\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %r10\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %r9\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %r8\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %rdi\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %rsi\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %rdx\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %rcx\n  CFI_ADJUST_CFA_OFFSET(-8)\n  pop %rax\n  CFI_ADJUST_CFA_OFFSET(-8)\n  CFI_RESTORE(%rax)\n  CFI_RESTORE(%rbx)\n  CFI_RESTORE(%rcx)\n  CFI_RESTORE(%rdx)\n  CFI_RESTORE(%rsi)\n  CFI_RESTORE(%rdi)\n  CFI_RESTORE(%r8)\n  CFI_RESTORE(%r9)\n  CFI_RESTORE(%r10)\n  CFI_RESTORE(%r11)\n  ret\n  CFI_ENDPROC\n\nASM_HIDDEN(__tsan_setjmp)\n#if !defined(__APPLE__)\n.comm _ZN14__interception11real_setjmpE,8,8\n#endif\n.globl ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp)\nASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp))\nASM_TSAN_SYMBOL_INTERCEPTOR(setjmp):\n  CFI_STARTPROC\n  // save env parameter\n  push %rdi\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rdi, 0)\n  // obtain %rsp\n#if defined(__FreeBSD__)\n  lea 8(%rsp), %rdi\n  mov %rdi, %rsi\n#elif defined(__APPLE__)\n  lea 16(%rsp), %rdi\n  mov %rdi, %rsi\n#elif defined(__linux__)\n  lea 16(%rsp), %rdi\n  mov %rdi, %rsi\n  xor %fs:0x30, %rsi  // magic mangling of rsp (see libc setjmp)\n  rol $0x11, %rsi\n#else\n# error \"Unknown platform\"\n#endif\n  // call tsan interceptor\n  call ASM_TSAN_SYMBOL(__tsan_setjmp)\n  // restore env parameter\n  pop %rdi\n  CFI_ADJUST_CFA_OFFSET(-8)\n  CFI_RESTORE(%rdi)\n  // tail jump to libc setjmp\n  movl $0, %eax\n#if !defined(__APPLE__)\n  movq _ZN14__interception11real_setjmpE@GOTPCREL(%rip), %rdx\n  jmp *(%rdx)\n#else\n  jmp ASM_TSAN_SYMBOL(setjmp)\n#endif\n  CFI_ENDPROC\nASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp))\n\n.comm _ZN14__interception12real__setjmpE,8,8\n.globl ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp)\nASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp))\nASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp):\n  CFI_STARTPROC\n  // save env parameter\n  push %rdi\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rdi, 0)\n  // obtain %rsp\n#if defined(__FreeBSD__)\n  lea 8(%rsp), %rdi\n  mov %rdi, %rsi\n#elif defined(__APPLE__)\n  lea 16(%rsp), %rdi\n  mov %rdi, %rsi\n#elif defined(__linux__)\n  lea 16(%rsp), %rdi\n  mov %rdi, %rsi\n  xor %fs:0x30, %rsi  // magic mangling of rsp (see libc setjmp)\n  rol $0x11, %rsi\n#else\n# error \"Unknown platform\"\n#endif\n  // call tsan interceptor\n  call ASM_TSAN_SYMBOL(__tsan_setjmp)\n  // restore env parameter\n  pop %rdi\n  CFI_ADJUST_CFA_OFFSET(-8)\n  CFI_RESTORE(%rdi)\n  // tail jump to libc setjmp\n  movl $0, %eax\n#if !defined(__APPLE__)\n  movq _ZN14__interception12real__setjmpE@GOTPCREL(%rip), %rdx\n  jmp *(%rdx)\n#else\n  jmp ASM_TSAN_SYMBOL(_setjmp)\n#endif\n  CFI_ENDPROC\nASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp))\n\n.comm _ZN14__interception14real_sigsetjmpE,8,8\n.globl ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp)\nASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp))\nASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp):\n  CFI_STARTPROC\n  // save env parameter\n  push %rdi\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rdi, 0)\n  // save savesigs parameter\n  push %rsi\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rsi, 0)\n  // align stack frame\n  sub $8, %rsp\n  CFI_ADJUST_CFA_OFFSET(8)\n  // obtain %rsp\n#if defined(__FreeBSD__)\n  lea 24(%rsp), %rdi\n  mov %rdi, %rsi\n#elif defined(__APPLE__)\n  lea 32(%rsp), %rdi\n  mov %rdi, %rsi\n#elif defined(__linux__)\n  lea 32(%rsp), %rdi\n  mov %rdi, %rsi\n  xor %fs:0x30, %rsi  // magic mangling of rsp (see libc setjmp)\n  rol $0x11, %rsi\n#else\n# error \"Unknown platform\"\n#endif\n  // call tsan interceptor\n  call ASM_TSAN_SYMBOL(__tsan_setjmp)\n  // unalign stack frame\n  add $8, %rsp\n  CFI_ADJUST_CFA_OFFSET(-8)\n  // restore savesigs parameter\n  pop %rsi\n  CFI_ADJUST_CFA_OFFSET(-8)\n  CFI_RESTORE(%rsi)\n  // restore env parameter\n  pop %rdi\n  CFI_ADJUST_CFA_OFFSET(-8)\n  CFI_RESTORE(%rdi)\n  // tail jump to libc sigsetjmp\n  movl $0, %eax\n#if !defined(__APPLE__)\n  movq _ZN14__interception14real_sigsetjmpE@GOTPCREL(%rip), %rdx\n  jmp *(%rdx)\n#else\n  jmp ASM_TSAN_SYMBOL(sigsetjmp)\n#endif\n  CFI_ENDPROC\nASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp))\n\n#if !defined(__APPLE__)\n.comm _ZN14__interception16real___sigsetjmpE,8,8\n.globl ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp)\nASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp))\nASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp):\n  CFI_STARTPROC\n  // save env parameter\n  push %rdi\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rdi, 0)\n  // save savesigs parameter\n  push %rsi\n  CFI_ADJUST_CFA_OFFSET(8)\n  CFI_REL_OFFSET(%rsi, 0)\n  // align stack frame\n  sub $8, %rsp\n  CFI_ADJUST_CFA_OFFSET(8)\n  // obtain %rsp\n#if defined(__FreeBSD__)\n  lea 24(%rsp), %rdi\n  mov %rdi, %rsi\n#else\n  lea 32(%rsp), %rdi\n  mov %rdi, %rsi\n  xor %fs:0x30, %rsi  // magic mangling of rsp (see libc setjmp)\n  rol $0x11, %rsi\n#endif\n  // call tsan interceptor\n  call ASM_TSAN_SYMBOL(__tsan_setjmp)\n  // unalign stack frame\n  add $8, %rsp\n  CFI_ADJUST_CFA_OFFSET(-8)\n  // restore savesigs parameter\n  pop %rsi\n  CFI_ADJUST_CFA_OFFSET(-8)\n  CFI_RESTORE(%rsi)\n  // restore env parameter\n  pop %rdi\n  CFI_ADJUST_CFA_OFFSET(-8)\n  CFI_RESTORE(%rdi)\n  // tail jump to libc sigsetjmp\n  movl $0, %eax\n  movq _ZN14__interception16real___sigsetjmpE@GOTPCREL(%rip), %rdx\n  jmp *(%rdx)\n  CFI_ENDPROC\nASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp))\n#endif  // !defined(__APPLE__)\n\n#if defined(__FreeBSD__) || defined(__linux__)\n/* We do not need executable stack.  */\n.section        .note.GNU-stack,\"\",@progbits\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc",
    "content": "//===-- tsan_rtl_mutex.cc -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n\n#include <sanitizer_common/sanitizer_deadlock_detector_interface.h>\n#include <sanitizer_common/sanitizer_stackdepot.h>\n\n#include \"tsan_rtl.h\"\n#include \"tsan_flags.h\"\n#include \"tsan_sync.h\"\n#include \"tsan_report.h\"\n#include \"tsan_symbolize.h\"\n#include \"tsan_platform.h\"\n\nnamespace __tsan {\n\nvoid ReportDeadlock(ThreadState *thr, uptr pc, DDReport *r);\n\nstruct Callback : DDCallback {\n  ThreadState *thr;\n  uptr pc;\n\n  Callback(ThreadState *thr, uptr pc)\n      : thr(thr)\n      , pc(pc) {\n    DDCallback::pt = thr->dd_pt;\n    DDCallback::lt = thr->dd_lt;\n  }\n\n  u32 Unwind() override { return CurrentStackId(thr, pc); }\n  int UniqueTid() override { return thr->unique_id; }\n};\n\nvoid DDMutexInit(ThreadState *thr, uptr pc, SyncVar *s) {\n  Callback cb(thr, pc);\n  ctx->dd->MutexInit(&cb, &s->dd);\n  s->dd.ctx = s->GetId();\n}\n\nstatic void ReportMutexMisuse(ThreadState *thr, uptr pc, ReportType typ,\n    uptr addr, u64 mid) {\n  // In Go, these misuses are either impossible, or detected by std lib,\n  // or false positives (e.g. unlock in a different thread).\n  if (kGoMode)\n    return;\n  ThreadRegistryLock l(ctx->thread_registry);\n  ScopedReport rep(typ);\n  rep.AddMutex(mid);\n  VarSizeStackTrace trace;\n  ObtainCurrentStack(thr, pc, &trace);\n  rep.AddStack(trace, true);\n  rep.AddLocation(addr, 1);\n  OutputReport(thr, rep);\n}\n\nvoid MutexCreate(ThreadState *thr, uptr pc, uptr addr,\n                 bool rw, bool recursive, bool linker_init) {\n  DPrintf(\"#%d: MutexCreate %zx\\n\", thr->tid, addr);\n  StatInc(thr, StatMutexCreate);\n  if (!linker_init && IsAppMem(addr)) {\n    CHECK(!thr->is_freeing);\n    thr->is_freeing = true;\n    MemoryWrite(thr, pc, addr, kSizeLog1);\n    thr->is_freeing = false;\n  }\n  SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true);\n  s->is_rw = rw;\n  s->is_recursive = recursive;\n  s->is_linker_init = linker_init;\n  if (kCppMode && s->creation_stack_id == 0)\n    s->creation_stack_id = CurrentStackId(thr, pc);\n  s->mtx.Unlock();\n}\n\nvoid MutexDestroy(ThreadState *thr, uptr pc, uptr addr) {\n  DPrintf(\"#%d: MutexDestroy %zx\\n\", thr->tid, addr);\n  StatInc(thr, StatMutexDestroy);\n#ifndef SANITIZER_GO\n  // Global mutexes not marked as LINKER_INITIALIZED\n  // cause tons of not interesting reports, so just ignore it.\n  if (IsGlobalVar(addr))\n    return;\n#endif\n  if (IsAppMem(addr)) {\n    CHECK(!thr->is_freeing);\n    thr->is_freeing = true;\n    MemoryWrite(thr, pc, addr, kSizeLog1);\n    thr->is_freeing = false;\n  }\n  SyncVar *s = ctx->metamap.GetIfExistsAndLock(addr);\n  if (s == 0)\n    return;\n  if (common_flags()->detect_deadlocks) {\n    Callback cb(thr, pc);\n    ctx->dd->MutexDestroy(&cb, &s->dd);\n    ctx->dd->MutexInit(&cb, &s->dd);\n  }\n  bool unlock_locked = false;\n  if (flags()->report_destroy_locked\n      && s->owner_tid != SyncVar::kInvalidTid\n      && !s->is_broken) {\n    s->is_broken = true;\n    unlock_locked = true;\n  }\n  u64 mid = s->GetId();\n  u32 last_lock = s->last_lock;\n  if (!unlock_locked)\n    s->Reset(thr);  // must not reset it before the report is printed\n  s->mtx.Unlock();\n  if (unlock_locked) {\n    ThreadRegistryLock l(ctx->thread_registry);\n    ScopedReport rep(ReportTypeMutexDestroyLocked);\n    rep.AddMutex(mid);\n    VarSizeStackTrace trace;\n    ObtainCurrentStack(thr, pc, &trace);\n    rep.AddStack(trace);\n    FastState last(last_lock);\n    RestoreStack(last.tid(), last.epoch(), &trace, 0);\n    rep.AddStack(trace, true);\n    rep.AddLocation(addr, 1);\n    OutputReport(thr, rep);\n  }\n  if (unlock_locked) {\n    SyncVar *s = ctx->metamap.GetIfExistsAndLock(addr);\n    if (s != 0) {\n      s->Reset(thr);\n      s->mtx.Unlock();\n    }\n  }\n  thr->mset.Remove(mid);\n  // s will be destroyed and freed in MetaMap::FreeBlock.\n}\n\nvoid MutexLock(ThreadState *thr, uptr pc, uptr addr, int rec, bool try_lock) {\n  DPrintf(\"#%d: MutexLock %zx rec=%d\\n\", thr->tid, addr, rec);\n  CHECK_GT(rec, 0);\n  if (IsAppMem(addr))\n    MemoryReadAtomic(thr, pc, addr, kSizeLog1);\n  SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true);\n  thr->fast_state.IncrementEpoch();\n  TraceAddEvent(thr, thr->fast_state, EventTypeLock, s->GetId());\n  bool report_double_lock = false;\n  if (s->owner_tid == SyncVar::kInvalidTid) {\n    CHECK_EQ(s->recursion, 0);\n    s->owner_tid = thr->tid;\n    s->last_lock = thr->fast_state.raw();\n  } else if (s->owner_tid == thr->tid) {\n    CHECK_GT(s->recursion, 0);\n  } else if (flags()->report_mutex_bugs && !s->is_broken) {\n    s->is_broken = true;\n    report_double_lock = true;\n  }\n  if (s->recursion == 0) {\n    StatInc(thr, StatMutexLock);\n    AcquireImpl(thr, pc, &s->clock);\n    AcquireImpl(thr, pc, &s->read_clock);\n  } else if (!s->is_recursive) {\n    StatInc(thr, StatMutexRecLock);\n  }\n  s->recursion += rec;\n  thr->mset.Add(s->GetId(), true, thr->fast_state.epoch());\n  if (common_flags()->detect_deadlocks && (s->recursion - rec) == 0) {\n    Callback cb(thr, pc);\n    if (!try_lock)\n      ctx->dd->MutexBeforeLock(&cb, &s->dd, true);\n    ctx->dd->MutexAfterLock(&cb, &s->dd, true, try_lock);\n  }\n  u64 mid = s->GetId();\n  s->mtx.Unlock();\n  // Can't touch s after this point.\n  if (report_double_lock)\n    ReportMutexMisuse(thr, pc, ReportTypeMutexDoubleLock, addr, mid);\n  if (common_flags()->detect_deadlocks) {\n    Callback cb(thr, pc);\n    ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));\n  }\n}\n\nint MutexUnlock(ThreadState *thr, uptr pc, uptr addr, bool all) {\n  DPrintf(\"#%d: MutexUnlock %zx all=%d\\n\", thr->tid, addr, all);\n  if (IsAppMem(addr))\n    MemoryReadAtomic(thr, pc, addr, kSizeLog1);\n  SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true);\n  thr->fast_state.IncrementEpoch();\n  TraceAddEvent(thr, thr->fast_state, EventTypeUnlock, s->GetId());\n  int rec = 0;\n  bool report_bad_unlock = false;\n  if (kCppMode && (s->recursion == 0 || s->owner_tid != thr->tid)) {\n    if (flags()->report_mutex_bugs && !s->is_broken) {\n      s->is_broken = true;\n      report_bad_unlock = true;\n    }\n  } else {\n    rec = all ? s->recursion : 1;\n    s->recursion -= rec;\n    if (s->recursion == 0) {\n      StatInc(thr, StatMutexUnlock);\n      s->owner_tid = SyncVar::kInvalidTid;\n      ReleaseStoreImpl(thr, pc, &s->clock);\n    } else {\n      StatInc(thr, StatMutexRecUnlock);\n    }\n  }\n  thr->mset.Del(s->GetId(), true);\n  if (common_flags()->detect_deadlocks && s->recursion == 0 &&\n      !report_bad_unlock) {\n    Callback cb(thr, pc);\n    ctx->dd->MutexBeforeUnlock(&cb, &s->dd, true);\n  }\n  u64 mid = s->GetId();\n  s->mtx.Unlock();\n  // Can't touch s after this point.\n  if (report_bad_unlock)\n    ReportMutexMisuse(thr, pc, ReportTypeMutexBadUnlock, addr, mid);\n  if (common_flags()->detect_deadlocks && !report_bad_unlock) {\n    Callback cb(thr, pc);\n    ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));\n  }\n  return rec;\n}\n\nvoid MutexReadLock(ThreadState *thr, uptr pc, uptr addr, bool trylock) {\n  DPrintf(\"#%d: MutexReadLock %zx\\n\", thr->tid, addr);\n  StatInc(thr, StatMutexReadLock);\n  if (IsAppMem(addr))\n    MemoryReadAtomic(thr, pc, addr, kSizeLog1);\n  SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, false);\n  thr->fast_state.IncrementEpoch();\n  TraceAddEvent(thr, thr->fast_state, EventTypeRLock, s->GetId());\n  bool report_bad_lock = false;\n  if (s->owner_tid != SyncVar::kInvalidTid) {\n    if (flags()->report_mutex_bugs && !s->is_broken) {\n      s->is_broken = true;\n      report_bad_lock = true;\n    }\n  }\n  AcquireImpl(thr, pc, &s->clock);\n  s->last_lock = thr->fast_state.raw();\n  thr->mset.Add(s->GetId(), false, thr->fast_state.epoch());\n  if (common_flags()->detect_deadlocks && s->recursion == 0) {\n    Callback cb(thr, pc);\n    if (!trylock)\n      ctx->dd->MutexBeforeLock(&cb, &s->dd, false);\n    ctx->dd->MutexAfterLock(&cb, &s->dd, false, trylock);\n  }\n  u64 mid = s->GetId();\n  s->mtx.ReadUnlock();\n  // Can't touch s after this point.\n  if (report_bad_lock)\n    ReportMutexMisuse(thr, pc, ReportTypeMutexBadReadLock, addr, mid);\n  if (common_flags()->detect_deadlocks) {\n    Callback cb(thr, pc);\n    ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));\n  }\n}\n\nvoid MutexReadUnlock(ThreadState *thr, uptr pc, uptr addr) {\n  DPrintf(\"#%d: MutexReadUnlock %zx\\n\", thr->tid, addr);\n  StatInc(thr, StatMutexReadUnlock);\n  if (IsAppMem(addr))\n    MemoryReadAtomic(thr, pc, addr, kSizeLog1);\n  SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true);\n  thr->fast_state.IncrementEpoch();\n  TraceAddEvent(thr, thr->fast_state, EventTypeRUnlock, s->GetId());\n  bool report_bad_unlock = false;\n  if (s->owner_tid != SyncVar::kInvalidTid) {\n    if (flags()->report_mutex_bugs && !s->is_broken) {\n      s->is_broken = true;\n      report_bad_unlock = true;\n    }\n  }\n  ReleaseImpl(thr, pc, &s->read_clock);\n  if (common_flags()->detect_deadlocks && s->recursion == 0) {\n    Callback cb(thr, pc);\n    ctx->dd->MutexBeforeUnlock(&cb, &s->dd, false);\n  }\n  u64 mid = s->GetId();\n  s->mtx.Unlock();\n  // Can't touch s after this point.\n  thr->mset.Del(mid, false);\n  if (report_bad_unlock)\n    ReportMutexMisuse(thr, pc, ReportTypeMutexBadReadUnlock, addr, mid);\n  if (common_flags()->detect_deadlocks) {\n    Callback cb(thr, pc);\n    ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));\n  }\n}\n\nvoid MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr) {\n  DPrintf(\"#%d: MutexReadOrWriteUnlock %zx\\n\", thr->tid, addr);\n  if (IsAppMem(addr))\n    MemoryReadAtomic(thr, pc, addr, kSizeLog1);\n  SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true);\n  bool write = true;\n  bool report_bad_unlock = false;\n  if (s->owner_tid == SyncVar::kInvalidTid) {\n    // Seems to be read unlock.\n    write = false;\n    StatInc(thr, StatMutexReadUnlock);\n    thr->fast_state.IncrementEpoch();\n    TraceAddEvent(thr, thr->fast_state, EventTypeRUnlock, s->GetId());\n    ReleaseImpl(thr, pc, &s->read_clock);\n  } else if (s->owner_tid == thr->tid) {\n    // Seems to be write unlock.\n    thr->fast_state.IncrementEpoch();\n    TraceAddEvent(thr, thr->fast_state, EventTypeUnlock, s->GetId());\n    CHECK_GT(s->recursion, 0);\n    s->recursion--;\n    if (s->recursion == 0) {\n      StatInc(thr, StatMutexUnlock);\n      s->owner_tid = SyncVar::kInvalidTid;\n      ReleaseImpl(thr, pc, &s->clock);\n    } else {\n      StatInc(thr, StatMutexRecUnlock);\n    }\n  } else if (!s->is_broken) {\n    s->is_broken = true;\n    report_bad_unlock = true;\n  }\n  thr->mset.Del(s->GetId(), write);\n  if (common_flags()->detect_deadlocks && s->recursion == 0) {\n    Callback cb(thr, pc);\n    ctx->dd->MutexBeforeUnlock(&cb, &s->dd, write);\n  }\n  u64 mid = s->GetId();\n  s->mtx.Unlock();\n  // Can't touch s after this point.\n  if (report_bad_unlock)\n    ReportMutexMisuse(thr, pc, ReportTypeMutexBadUnlock, addr, mid);\n  if (common_flags()->detect_deadlocks) {\n    Callback cb(thr, pc);\n    ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));\n  }\n}\n\nvoid MutexRepair(ThreadState *thr, uptr pc, uptr addr) {\n  DPrintf(\"#%d: MutexRepair %zx\\n\", thr->tid, addr);\n  SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true);\n  s->owner_tid = SyncVar::kInvalidTid;\n  s->recursion = 0;\n  s->mtx.Unlock();\n}\n\nvoid Acquire(ThreadState *thr, uptr pc, uptr addr) {\n  DPrintf(\"#%d: Acquire %zx\\n\", thr->tid, addr);\n  if (thr->ignore_sync)\n    return;\n  SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, false);\n  AcquireImpl(thr, pc, &s->clock);\n  s->mtx.ReadUnlock();\n}\n\nstatic void UpdateClockCallback(ThreadContextBase *tctx_base, void *arg) {\n  ThreadState *thr = reinterpret_cast<ThreadState*>(arg);\n  ThreadContext *tctx = static_cast<ThreadContext*>(tctx_base);\n  if (tctx->status == ThreadStatusRunning)\n    thr->clock.set(tctx->tid, tctx->thr->fast_state.epoch());\n  else\n    thr->clock.set(tctx->tid, tctx->epoch1);\n}\n\nvoid AcquireGlobal(ThreadState *thr, uptr pc) {\n  DPrintf(\"#%d: AcquireGlobal\\n\", thr->tid);\n  if (thr->ignore_sync)\n    return;\n  ThreadRegistryLock l(ctx->thread_registry);\n  ctx->thread_registry->RunCallbackForEachThreadLocked(\n      UpdateClockCallback, thr);\n}\n\nvoid Release(ThreadState *thr, uptr pc, uptr addr) {\n  DPrintf(\"#%d: Release %zx\\n\", thr->tid, addr);\n  if (thr->ignore_sync)\n    return;\n  SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true);\n  thr->fast_state.IncrementEpoch();\n  // Can't increment epoch w/o writing to the trace as well.\n  TraceAddEvent(thr, thr->fast_state, EventTypeMop, 0);\n  ReleaseImpl(thr, pc, &s->clock);\n  s->mtx.Unlock();\n}\n\nvoid ReleaseStore(ThreadState *thr, uptr pc, uptr addr) {\n  DPrintf(\"#%d: ReleaseStore %zx\\n\", thr->tid, addr);\n  if (thr->ignore_sync)\n    return;\n  SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true);\n  thr->fast_state.IncrementEpoch();\n  // Can't increment epoch w/o writing to the trace as well.\n  TraceAddEvent(thr, thr->fast_state, EventTypeMop, 0);\n  ReleaseStoreImpl(thr, pc, &s->clock);\n  s->mtx.Unlock();\n}\n\n#ifndef SANITIZER_GO\nstatic void UpdateSleepClockCallback(ThreadContextBase *tctx_base, void *arg) {\n  ThreadState *thr = reinterpret_cast<ThreadState*>(arg);\n  ThreadContext *tctx = static_cast<ThreadContext*>(tctx_base);\n  if (tctx->status == ThreadStatusRunning)\n    thr->last_sleep_clock.set(tctx->tid, tctx->thr->fast_state.epoch());\n  else\n    thr->last_sleep_clock.set(tctx->tid, tctx->epoch1);\n}\n\nvoid AfterSleep(ThreadState *thr, uptr pc) {\n  DPrintf(\"#%d: AfterSleep %zx\\n\", thr->tid);\n  if (thr->ignore_sync)\n    return;\n  thr->last_sleep_stack_id = CurrentStackId(thr, pc);\n  ThreadRegistryLock l(ctx->thread_registry);\n  ctx->thread_registry->RunCallbackForEachThreadLocked(\n      UpdateSleepClockCallback, thr);\n}\n#endif\n\nvoid AcquireImpl(ThreadState *thr, uptr pc, SyncClock *c) {\n  if (thr->ignore_sync)\n    return;\n  thr->clock.set(thr->fast_state.epoch());\n  thr->clock.acquire(&thr->clock_cache, c);\n  StatInc(thr, StatSyncAcquire);\n}\n\nvoid ReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c) {\n  if (thr->ignore_sync)\n    return;\n  thr->clock.set(thr->fast_state.epoch());\n  thr->fast_synch_epoch = thr->fast_state.epoch();\n  thr->clock.release(&thr->clock_cache, c);\n  StatInc(thr, StatSyncRelease);\n}\n\nvoid ReleaseStoreImpl(ThreadState *thr, uptr pc, SyncClock *c) {\n  if (thr->ignore_sync)\n    return;\n  thr->clock.set(thr->fast_state.epoch());\n  thr->fast_synch_epoch = thr->fast_state.epoch();\n  thr->clock.ReleaseStore(&thr->clock_cache, c);\n  StatInc(thr, StatSyncRelease);\n}\n\nvoid AcquireReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c) {\n  if (thr->ignore_sync)\n    return;\n  thr->clock.set(thr->fast_state.epoch());\n  thr->fast_synch_epoch = thr->fast_state.epoch();\n  thr->clock.acq_rel(&thr->clock_cache, c);\n  StatInc(thr, StatSyncAcquire);\n  StatInc(thr, StatSyncRelease);\n}\n\nvoid ReportDeadlock(ThreadState *thr, uptr pc, DDReport *r) {\n  if (r == 0)\n    return;\n  ThreadRegistryLock l(ctx->thread_registry);\n  ScopedReport rep(ReportTypeDeadlock);\n  for (int i = 0; i < r->n; i++) {\n    rep.AddMutex(r->loop[i].mtx_ctx0);\n    rep.AddUniqueTid((int)r->loop[i].thr_ctx);\n    rep.AddThread((int)r->loop[i].thr_ctx);\n  }\n  uptr dummy_pc = 0x42;\n  for (int i = 0; i < r->n; i++) {\n    for (int j = 0; j < (flags()->second_deadlock_stack ? 2 : 1); j++) {\n      u32 stk = r->loop[i].stk[j];\n      if (stk && stk != 0xffffffff) {\n        rep.AddStack(StackDepotGet(stk), true);\n      } else {\n        // Sometimes we fail to extract the stack trace (FIXME: investigate),\n        // but we should still produce some stack trace in the report.\n        rep.AddStack(StackTrace(&dummy_pc, 1), true);\n      }\n    }\n  }\n  OutputReport(thr, rep);\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_rtl_ppc64.S",
    "content": "#include \"tsan_ppc_regs.h\"\n\n        .section .text\n        .hidden __tsan_setjmp\n        .globl _setjmp\n        .type _setjmp, @function\n        .align 4\n#if _CALL_ELF == 2\n_setjmp:\n#else\n\t.section \".opd\",\"aw\"\n\t.align 3\n_setjmp:\n\t.quad   .L._setjmp,.TOC.@tocbase,0\n\t.previous\n#endif\n.L._setjmp:\n        mflr    r0\n        stdu    r1,-48(r1)\n        std     r2,24(r1)\n        std     r3,32(r1)\n        std     r0,40(r1)\n        // r3 is the original stack pointer.\n        addi    r3,r1,48\n        // r4 is the mangled stack pointer (see glibc)\n        ld      r4,-28696(r13)\n        xor     r4,r3,r4\n        // Materialize a TOC in case we were called from libc.\n        // For big-endian, we load the TOC from the OPD.  For little-\n        // endian, we use the .TOC. symbol to find it.\n        nop\n        bcl     20,31,0f\n0:\n        mflr    r2\n#if _CALL_ELF == 2\n        addis   r2,r2,.TOC.-0b@ha\n        addi    r2,r2,.TOC.-0b@l\n#else\n        addis   r2,r2,_setjmp-0b@ha\n        addi    r2,r2,_setjmp-0b@l\n        ld      r2,8(r2)\n#endif\n        // Call the interceptor.\n        bl      __tsan_setjmp\n        nop\n        // Restore regs needed for setjmp.\n        ld      r3,32(r1)\n        ld      r0,40(r1)\n        // Emulate the real setjmp function.  We do this because we can't\n        // perform a sibcall:  The real setjmp function trashes the TOC\n        // pointer, and with a sibcall we have no way to restore it.\n        // This way we can make sure our caller's stack pointer and\n        // link register are saved correctly in the jmpbuf.\n        ld      r6,-28696(r13)\n        addi    r5,r1,48  // original stack ptr of caller\n        xor     r5,r6,r5\n        std     r5,0(r3)  // mangled stack ptr of caller\n        ld      r5,24(r1)\n        std     r5,8(r3)  // caller's saved TOC pointer\n        xor     r0,r6,r0\n        std     r0,16(r3) // caller's mangled return address\n        mfcr    r0\n        // Nonvolatiles.\n        std     r14,24(r3)\n        stfd    f14,176(r3)\n        stw     r0,172(r3) // CR\n        std     r15,32(r3)\n        stfd    f15,184(r3)\n        std     r16,40(r3)\n        stfd    f16,192(r3)\n        std     r17,48(r3)\n        stfd    f17,200(r3)\n        std     r18,56(r3)\n        stfd    f18,208(r3)\n        std     r19,64(r3)\n        stfd    f19,216(r3)\n        std     r20,72(r3)\n        stfd    f20,224(r3)\n        std     r21,80(r3)\n        stfd    f21,232(r3)\n        std     r22,88(r3)\n        stfd    f22,240(r3)\n        std     r23,96(r3)\n        stfd    f23,248(r3)\n        std     r24,104(r3)\n        stfd    f24,256(r3)\n        std     r25,112(r3)\n        stfd    f25,264(r3)\n        std     r26,120(r3)\n        stfd    f26,272(r3)\n        std     r27,128(r3)\n        stfd    f27,280(r3)\n        std     r28,136(r3)\n        stfd    f28,288(r3)\n        std     r29,144(r3)\n        stfd    f29,296(r3)\n        std     r30,152(r3)\n        stfd    f30,304(r3)\n        std     r31,160(r3)\n        stfd    f31,312(r3)\n        addi    r5,r3,320\n        mfspr   r0,256\n        stw     r0,168(r3)  // VRSAVE\n        addi    r6,r5,16\n        stvx    v20,0,r5\n        addi    r5,r5,32\n        stvx    v21,0,r6\n        addi    r6,r6,32\n        stvx    v22,0,r5\n        addi    r5,r5,32\n        stvx    v23,0,r6\n        addi    r6,r6,32\n        stvx    v24,0,r5\n        addi    r5,r5,32\n        stvx    v25,0,r6\n        addi    r6,r6,32\n        stvx    v26,0,r5\n        addi    r5,r5,32\n        stvx    v27,0,r6\n        addi    r6,r6,32\n        stvx    v28,0,r5\n        addi    r5,r5,32\n        stvx    v29,0,r6\n        addi    r6,r6,32\n        stvx    v30,0,r5\n        stvx    v31,0,r6\n        // Clear the \"mask-saved\" slot.\n        li      r4,0\n        stw     r4,512(r3)\n        // Restore TOC, LR, and stack and return to caller.\n        ld      r2,24(r1)\n        ld      r0,40(r1)\n        addi    r1,r1,48\n        li      r3,0  // This is the setjmp return path\n        mtlr    r0\n        blr\n        .size _setjmp, .-.L._setjmp\n\n        .globl setjmp\n        .type setjmp, @function\n        .align 4\nsetjmp:\n        b       _setjmp\n        .size setjmp, .-setjmp\n\n        // sigsetjmp is like setjmp, except that the mask in r4 needs\n        // to be saved at offset 512 of the jump buffer.\n        .globl __sigsetjmp\n        .type __sigsetjmp, @function\n        .align 4\n#if _CALL_ELF == 2\n__sigsetjmp:\n#else\n\t.section \".opd\",\"aw\"\n\t.align 3\n__sigsetjmp:\n\t.quad   .L.__sigsetjmp,.TOC.@tocbase,0\n\t.previous\n#endif\n.L.__sigsetjmp:\n        mflr    r0\n        stdu    r1,-64(r1)\n        std     r2,24(r1)\n        std     r3,32(r1)\n        std     r4,40(r1)\n        std     r0,48(r1)\n        // r3 is the original stack pointer.\n        addi    r3,r1,64\n        // r4 is the mangled stack pointer (see glibc)\n        ld      r4,-28696(r13)\n        xor     r4,r3,r4\n        // Materialize a TOC in case we were called from libc.\n        // For big-endian, we load the TOC from the OPD.  For little-\n        // endian, we use the .TOC. symbol to find it.\n        nop\n        bcl     20,31,1f\n1:\n        mflr    r2\n#if _CALL_ELF == 2\n        addis   r2,r2,.TOC.-1b@ha\n        addi    r2,r2,.TOC.-1b@l\n#else\n        addis   r2,r2,_setjmp-1b@ha\n        addi    r2,r2,_setjmp-1b@l\n        ld      r2,8(r2)\n#endif\n        // Call the interceptor.\n        bl      __tsan_setjmp\n        nop\n        // Restore regs needed for __sigsetjmp.\n        ld      r3,32(r1)\n        ld      r4,40(r1)\n        ld      r0,48(r1)\n        // Emulate the real sigsetjmp function.  We do this because we can't\n        // perform a sibcall:  The real sigsetjmp function trashes the TOC\n        // pointer, and with a sibcall we have no way to restore it.\n        // This way we can make sure our caller's stack pointer and\n        // link register are saved correctly in the jmpbuf.\n        ld      r6,-28696(r13)\n        addi    r5,r1,64  // original stack ptr of caller\n        xor     r5,r6,r5\n        std     r5,0(r3)  // mangled stack ptr of caller\n        ld      r5,24(r1)\n        std     r5,8(r3)  // caller's saved TOC pointer\n        xor     r0,r6,r0\n        std     r0,16(r3) // caller's mangled return address\n        mfcr    r0\n        // Nonvolatiles.\n        std     r14,24(r3)\n        stfd    f14,176(r3)\n        stw     r0,172(r3) // CR\n        std     r15,32(r3)\n        stfd    f15,184(r3)\n        std     r16,40(r3)\n        stfd    f16,192(r3)\n        std     r17,48(r3)\n        stfd    f17,200(r3)\n        std     r18,56(r3)\n        stfd    f18,208(r3)\n        std     r19,64(r3)\n        stfd    f19,216(r3)\n        std     r20,72(r3)\n        stfd    f20,224(r3)\n        std     r21,80(r3)\n        stfd    f21,232(r3)\n        std     r22,88(r3)\n        stfd    f22,240(r3)\n        std     r23,96(r3)\n        stfd    f23,248(r3)\n        std     r24,104(r3)\n        stfd    f24,256(r3)\n        std     r25,112(r3)\n        stfd    f25,264(r3)\n        std     r26,120(r3)\n        stfd    f26,272(r3)\n        std     r27,128(r3)\n        stfd    f27,280(r3)\n        std     r28,136(r3)\n        stfd    f28,288(r3)\n        std     r29,144(r3)\n        stfd    f29,296(r3)\n        std     r30,152(r3)\n        stfd    f30,304(r3)\n        std     r31,160(r3)\n        stfd    f31,312(r3)\n        addi    r5,r3,320\n        mfspr   r0,256\n        stw     r0,168(r3) // VRSAVE\n        addi    r6,r5,16\n        stvx    v20,0,r5\n        addi    r5,r5,32\n        stvx    v21,0,r6\n        addi    r6,r6,32\n        stvx    v22,0,r5\n        addi    r5,r5,32\n        stvx    v23,0,r6\n        addi    r6,r6,32\n        stvx    v24,0,r5\n        addi    r5,r5,32\n        stvx    v25,0,r6\n        addi    r6,r6,32\n        stvx    v26,0,r5\n        addi    r5,r5,32\n        stvx    v27,0,r6\n        addi    r6,r6,32\n        stvx    v28,0,r5\n        addi    r5,r5,32\n        stvx    v29,0,r6\n        addi    r6,r6,32\n        stvx    v30,0,r5\n        stvx    v31,0,r6\n        // Save into the \"mask-saved\" slot.\n        stw     r4,512(r3)\n        // Restore TOC, LR, and stack and return to caller.\n        ld      r2,24(r1)\n        ld      r0,48(r1)\n        addi    r1,r1,64\n        li      r3,0  // This is the sigsetjmp return path\n        mtlr    r0\n        blr\n        .size __sigsetjmp, .-.L.__sigsetjmp\n\n        .globl sigsetjmp\n        .type sigsetjmp, @function\n        .align 4\nsigsetjmp:\n        b       __sigsetjmp\n        .size sigsetjmp, .-sigsetjmp\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc",
    "content": "//===-- tsan_rtl_report.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_stackdepot.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"tsan_platform.h\"\n#include \"tsan_rtl.h\"\n#include \"tsan_suppressions.h\"\n#include \"tsan_symbolize.h\"\n#include \"tsan_report.h\"\n#include \"tsan_sync.h\"\n#include \"tsan_mman.h\"\n#include \"tsan_flags.h\"\n#include \"tsan_fd.h\"\n\nnamespace __tsan {\n\nusing namespace __sanitizer;  // NOLINT\n\nstatic ReportStack *SymbolizeStack(StackTrace trace);\n\nvoid TsanCheckFailed(const char *file, int line, const char *cond,\n                     u64 v1, u64 v2) {\n  // There is high probability that interceptors will check-fail as well,\n  // on the other hand there is no sense in processing interceptors\n  // since we are going to die soon.\n  ScopedIgnoreInterceptors ignore;\n  Printf(\"FATAL: ThreadSanitizer CHECK failed: \"\n         \"%s:%d \\\"%s\\\" (0x%zx, 0x%zx)\\n\",\n         file, line, cond, (uptr)v1, (uptr)v2);\n  PrintCurrentStackSlow(StackTrace::GetCurrentPc());\n  Die();\n}\n\n// Can be overriden by an application/test to intercept reports.\n#ifdef TSAN_EXTERNAL_HOOKS\nbool OnReport(const ReportDesc *rep, bool suppressed);\n#else\nSANITIZER_WEAK_CXX_DEFAULT_IMPL\nbool OnReport(const ReportDesc *rep, bool suppressed) {\n  (void)rep;\n  return suppressed;\n}\n#endif\n\nstatic void StackStripMain(SymbolizedStack *frames) {\n  SymbolizedStack *last_frame = nullptr;\n  SymbolizedStack *last_frame2 = nullptr;\n  for (SymbolizedStack *cur = frames; cur; cur = cur->next) {\n    last_frame2 = last_frame;\n    last_frame = cur;\n  }\n\n  if (last_frame2 == 0)\n    return;\n#ifndef SANITIZER_GO\n  const char *last = last_frame->info.function;\n  const char *last2 = last_frame2->info.function;\n  // Strip frame above 'main'\n  if (last2 && 0 == internal_strcmp(last2, \"main\")) {\n    last_frame->ClearAll();\n    last_frame2->next = nullptr;\n  // Strip our internal thread start routine.\n  } else if (last && 0 == internal_strcmp(last, \"__tsan_thread_start_func\")) {\n    last_frame->ClearAll();\n    last_frame2->next = nullptr;\n  // Strip global ctors init.\n  } else if (last && 0 == internal_strcmp(last, \"__do_global_ctors_aux\")) {\n    last_frame->ClearAll();\n    last_frame2->next = nullptr;\n  // If both are 0, then we probably just failed to symbolize.\n  } else if (last || last2) {\n    // Ensure that we recovered stack completely. Trimmed stack\n    // can actually happen if we do not instrument some code,\n    // so it's only a debug print. However we must try hard to not miss it\n    // due to our fault.\n    DPrintf(\"Bottom stack frame is missed\\n\");\n  }\n#else\n  // The last frame always point into runtime (gosched0, goexit0, runtime.main).\n  last_frame->ClearAll();\n  last_frame2->next = nullptr;\n#endif\n}\n\nReportStack *SymbolizeStackId(u32 stack_id) {\n  if (stack_id == 0)\n    return 0;\n  StackTrace stack = StackDepotGet(stack_id);\n  if (stack.trace == nullptr)\n    return nullptr;\n  return SymbolizeStack(stack);\n}\n\nstatic ReportStack *SymbolizeStack(StackTrace trace) {\n  if (trace.size == 0)\n    return 0;\n  SymbolizedStack *top = nullptr;\n  for (uptr si = 0; si < trace.size; si++) {\n    const uptr pc = trace.trace[si];\n    uptr pc1 = pc;\n    // We obtain the return address, but we're interested in the previous\n    // instruction.\n    if ((pc & kExternalPCBit) == 0)\n      pc1 = StackTrace::GetPreviousInstructionPc(pc);\n    SymbolizedStack *ent = SymbolizeCode(pc1);\n    CHECK_NE(ent, 0);\n    SymbolizedStack *last = ent;\n    while (last->next) {\n      last->info.address = pc;  // restore original pc for report\n      last = last->next;\n    }\n    last->info.address = pc;  // restore original pc for report\n    last->next = top;\n    top = ent;\n  }\n  StackStripMain(top);\n\n  ReportStack *stack = ReportStack::New();\n  stack->frames = top;\n  return stack;\n}\n\nScopedReport::ScopedReport(ReportType typ) {\n  ctx->thread_registry->CheckLocked();\n  void *mem = internal_alloc(MBlockReport, sizeof(ReportDesc));\n  rep_ = new(mem) ReportDesc;\n  rep_->typ = typ;\n  ctx->report_mtx.Lock();\n  CommonSanitizerReportMutex.Lock();\n}\n\nScopedReport::~ScopedReport() {\n  CommonSanitizerReportMutex.Unlock();\n  ctx->report_mtx.Unlock();\n  DestroyAndFree(rep_);\n}\n\nvoid ScopedReport::AddStack(StackTrace stack, bool suppressable) {\n  ReportStack **rs = rep_->stacks.PushBack();\n  *rs = SymbolizeStack(stack);\n  (*rs)->suppressable = suppressable;\n}\n\nvoid ScopedReport::AddMemoryAccess(uptr addr, Shadow s, StackTrace stack,\n                                   const MutexSet *mset) {\n  void *mem = internal_alloc(MBlockReportMop, sizeof(ReportMop));\n  ReportMop *mop = new(mem) ReportMop;\n  rep_->mops.PushBack(mop);\n  mop->tid = s.tid();\n  mop->addr = addr + s.addr0();\n  mop->size = s.size();\n  mop->write = s.IsWrite();\n  mop->atomic = s.IsAtomic();\n  mop->stack = SymbolizeStack(stack);\n  if (mop->stack)\n    mop->stack->suppressable = true;\n  for (uptr i = 0; i < mset->Size(); i++) {\n    MutexSet::Desc d = mset->Get(i);\n    u64 mid = this->AddMutex(d.id);\n    ReportMopMutex mtx = {mid, d.write};\n    mop->mset.PushBack(mtx);\n  }\n}\n\nvoid ScopedReport::AddUniqueTid(int unique_tid) {\n  rep_->unique_tids.PushBack(unique_tid);\n}\n\nvoid ScopedReport::AddThread(const ThreadContext *tctx, bool suppressable) {\n  for (uptr i = 0; i < rep_->threads.Size(); i++) {\n    if ((u32)rep_->threads[i]->id == tctx->tid)\n      return;\n  }\n  void *mem = internal_alloc(MBlockReportThread, sizeof(ReportThread));\n  ReportThread *rt = new(mem) ReportThread;\n  rep_->threads.PushBack(rt);\n  rt->id = tctx->tid;\n  rt->pid = tctx->os_id;\n  rt->running = (tctx->status == ThreadStatusRunning);\n  rt->name = internal_strdup(tctx->name);\n  rt->parent_tid = tctx->parent_tid;\n  rt->stack = 0;\n  rt->stack = SymbolizeStackId(tctx->creation_stack_id);\n  if (rt->stack)\n    rt->stack->suppressable = suppressable;\n}\n\n#ifndef SANITIZER_GO\nstatic bool FindThreadByUidLockedCallback(ThreadContextBase *tctx, void *arg) {\n  int unique_id = *(int *)arg;\n  return tctx->unique_id == (u32)unique_id;\n}\n\nstatic ThreadContext *FindThreadByUidLocked(int unique_id) {\n  ctx->thread_registry->CheckLocked();\n  return static_cast<ThreadContext *>(\n      ctx->thread_registry->FindThreadContextLocked(\n          FindThreadByUidLockedCallback, &unique_id));\n}\n\nstatic ThreadContext *FindThreadByTidLocked(int tid) {\n  ctx->thread_registry->CheckLocked();\n  return static_cast<ThreadContext*>(\n      ctx->thread_registry->GetThreadLocked(tid));\n}\n\nstatic bool IsInStackOrTls(ThreadContextBase *tctx_base, void *arg) {\n  uptr addr = (uptr)arg;\n  ThreadContext *tctx = static_cast<ThreadContext*>(tctx_base);\n  if (tctx->status != ThreadStatusRunning)\n    return false;\n  ThreadState *thr = tctx->thr;\n  CHECK(thr);\n  return ((addr >= thr->stk_addr && addr < thr->stk_addr + thr->stk_size) ||\n          (addr >= thr->tls_addr && addr < thr->tls_addr + thr->tls_size));\n}\n\nThreadContext *IsThreadStackOrTls(uptr addr, bool *is_stack) {\n  ctx->thread_registry->CheckLocked();\n  ThreadContext *tctx = static_cast<ThreadContext*>(\n      ctx->thread_registry->FindThreadContextLocked(IsInStackOrTls,\n                                                    (void*)addr));\n  if (!tctx)\n    return 0;\n  ThreadState *thr = tctx->thr;\n  CHECK(thr);\n  *is_stack = (addr >= thr->stk_addr && addr < thr->stk_addr + thr->stk_size);\n  return tctx;\n}\n#endif\n\nvoid ScopedReport::AddThread(int unique_tid, bool suppressable) {\n#ifndef SANITIZER_GO\n  if (const ThreadContext *tctx = FindThreadByUidLocked(unique_tid))\n    AddThread(tctx, suppressable);\n#endif\n}\n\nvoid ScopedReport::AddMutex(const SyncVar *s) {\n  for (uptr i = 0; i < rep_->mutexes.Size(); i++) {\n    if (rep_->mutexes[i]->id == s->uid)\n      return;\n  }\n  void *mem = internal_alloc(MBlockReportMutex, sizeof(ReportMutex));\n  ReportMutex *rm = new(mem) ReportMutex;\n  rep_->mutexes.PushBack(rm);\n  rm->id = s->uid;\n  rm->addr = s->addr;\n  rm->destroyed = false;\n  rm->stack = SymbolizeStackId(s->creation_stack_id);\n}\n\nu64 ScopedReport::AddMutex(u64 id) {\n  u64 uid = 0;\n  u64 mid = id;\n  uptr addr = SyncVar::SplitId(id, &uid);\n  SyncVar *s = ctx->metamap.GetIfExistsAndLock(addr);\n  // Check that the mutex is still alive.\n  // Another mutex can be created at the same address,\n  // so check uid as well.\n  if (s && s->CheckId(uid)) {\n    mid = s->uid;\n    AddMutex(s);\n  } else {\n    AddDeadMutex(id);\n  }\n  if (s)\n    s->mtx.Unlock();\n  return mid;\n}\n\nvoid ScopedReport::AddDeadMutex(u64 id) {\n  for (uptr i = 0; i < rep_->mutexes.Size(); i++) {\n    if (rep_->mutexes[i]->id == id)\n      return;\n  }\n  void *mem = internal_alloc(MBlockReportMutex, sizeof(ReportMutex));\n  ReportMutex *rm = new(mem) ReportMutex;\n  rep_->mutexes.PushBack(rm);\n  rm->id = id;\n  rm->addr = 0;\n  rm->destroyed = true;\n  rm->stack = 0;\n}\n\nvoid ScopedReport::AddLocation(uptr addr, uptr size) {\n  if (addr == 0)\n    return;\n#ifndef SANITIZER_GO\n  int fd = -1;\n  int creat_tid = -1;\n  u32 creat_stack = 0;\n  if (FdLocation(addr, &fd, &creat_tid, &creat_stack)) {\n    ReportLocation *loc = ReportLocation::New(ReportLocationFD);\n    loc->fd = fd;\n    loc->tid = creat_tid;\n    loc->stack = SymbolizeStackId(creat_stack);\n    rep_->locs.PushBack(loc);\n    ThreadContext *tctx = FindThreadByUidLocked(creat_tid);\n    if (tctx)\n      AddThread(tctx);\n    return;\n  }\n  MBlock *b = 0;\n  Allocator *a = allocator();\n  if (a->PointerIsMine((void*)addr)) {\n    void *block_begin = a->GetBlockBegin((void*)addr);\n    if (block_begin)\n      b = ctx->metamap.GetBlock((uptr)block_begin);\n  }\n  if (b != 0) {\n    ThreadContext *tctx = FindThreadByTidLocked(b->tid);\n    ReportLocation *loc = ReportLocation::New(ReportLocationHeap);\n    loc->heap_chunk_start = (uptr)allocator()->GetBlockBegin((void *)addr);\n    loc->heap_chunk_size = b->siz;\n    loc->tid = tctx ? tctx->tid : b->tid;\n    loc->stack = SymbolizeStackId(b->stk);\n    rep_->locs.PushBack(loc);\n    if (tctx)\n      AddThread(tctx);\n    return;\n  }\n  bool is_stack = false;\n  if (ThreadContext *tctx = IsThreadStackOrTls(addr, &is_stack)) {\n    ReportLocation *loc =\n        ReportLocation::New(is_stack ? ReportLocationStack : ReportLocationTLS);\n    loc->tid = tctx->tid;\n    rep_->locs.PushBack(loc);\n    AddThread(tctx);\n  }\n  if (ReportLocation *loc = SymbolizeData(addr)) {\n    loc->suppressable = true;\n    rep_->locs.PushBack(loc);\n    return;\n  }\n#endif\n}\n\n#ifndef SANITIZER_GO\nvoid ScopedReport::AddSleep(u32 stack_id) {\n  rep_->sleep = SymbolizeStackId(stack_id);\n}\n#endif\n\nvoid ScopedReport::SetCount(int count) {\n  rep_->count = count;\n}\n\nconst ReportDesc *ScopedReport::GetReport() const {\n  return rep_;\n}\n\nvoid RestoreStack(int tid, const u64 epoch, VarSizeStackTrace *stk,\n                  MutexSet *mset) {\n  // This function restores stack trace and mutex set for the thread/epoch.\n  // It does so by getting stack trace and mutex set at the beginning of\n  // trace part, and then replaying the trace till the given epoch.\n  Trace* trace = ThreadTrace(tid);\n  ReadLock l(&trace->mtx);\n  const int partidx = (epoch / kTracePartSize) % TraceParts();\n  TraceHeader* hdr = &trace->headers[partidx];\n  if (epoch < hdr->epoch0 || epoch >= hdr->epoch0 + kTracePartSize)\n    return;\n  CHECK_EQ(RoundDown(epoch, kTracePartSize), hdr->epoch0);\n  const u64 epoch0 = RoundDown(epoch, TraceSize());\n  const u64 eend = epoch % TraceSize();\n  const u64 ebegin = RoundDown(eend, kTracePartSize);\n  DPrintf(\"#%d: RestoreStack epoch=%zu ebegin=%zu eend=%zu partidx=%d\\n\",\n          tid, (uptr)epoch, (uptr)ebegin, (uptr)eend, partidx);\n  Vector<uptr> stack(MBlockReportStack);\n  stack.Resize(hdr->stack0.size + 64);\n  for (uptr i = 0; i < hdr->stack0.size; i++) {\n    stack[i] = hdr->stack0.trace[i];\n    DPrintf2(\"  #%02zu: pc=%zx\\n\", i, stack[i]);\n  }\n  if (mset)\n    *mset = hdr->mset0;\n  uptr pos = hdr->stack0.size;\n  Event *events = (Event*)GetThreadTrace(tid);\n  for (uptr i = ebegin; i <= eend; i++) {\n    Event ev = events[i];\n    EventType typ = (EventType)(ev >> 61);\n    uptr pc = (uptr)(ev & ((1ull << 61) - 1));\n    DPrintf2(\"  %zu typ=%d pc=%zx\\n\", i, typ, pc);\n    if (typ == EventTypeMop) {\n      stack[pos] = pc;\n    } else if (typ == EventTypeFuncEnter) {\n      if (stack.Size() < pos + 2)\n        stack.Resize(pos + 2);\n      stack[pos++] = pc;\n    } else if (typ == EventTypeFuncExit) {\n      if (pos > 0)\n        pos--;\n    }\n    if (mset) {\n      if (typ == EventTypeLock) {\n        mset->Add(pc, true, epoch0 + i);\n      } else if (typ == EventTypeUnlock) {\n        mset->Del(pc, true);\n      } else if (typ == EventTypeRLock) {\n        mset->Add(pc, false, epoch0 + i);\n      } else if (typ == EventTypeRUnlock) {\n        mset->Del(pc, false);\n      }\n    }\n    for (uptr j = 0; j <= pos; j++)\n      DPrintf2(\"      #%zu: %zx\\n\", j, stack[j]);\n  }\n  if (pos == 0 && stack[0] == 0)\n    return;\n  pos++;\n  stk->Init(&stack[0], pos);\n}\n\nstatic bool HandleRacyStacks(ThreadState *thr, VarSizeStackTrace traces[2],\n                             uptr addr_min, uptr addr_max) {\n  bool equal_stack = false;\n  RacyStacks hash;\n  bool equal_address = false;\n  RacyAddress ra0 = {addr_min, addr_max};\n  {\n    ReadLock lock(&ctx->racy_mtx);\n    if (flags()->suppress_equal_stacks) {\n      hash.hash[0] = md5_hash(traces[0].trace, traces[0].size * sizeof(uptr));\n      hash.hash[1] = md5_hash(traces[1].trace, traces[1].size * sizeof(uptr));\n      for (uptr i = 0; i < ctx->racy_stacks.Size(); i++) {\n        if (hash == ctx->racy_stacks[i]) {\n          VPrintf(2,\n              \"ThreadSanitizer: suppressing report as doubled (stack)\\n\");\n          equal_stack = true;\n          break;\n        }\n      }\n    }\n    if (flags()->suppress_equal_addresses) {\n      for (uptr i = 0; i < ctx->racy_addresses.Size(); i++) {\n        RacyAddress ra2 = ctx->racy_addresses[i];\n        uptr maxbeg = max(ra0.addr_min, ra2.addr_min);\n        uptr minend = min(ra0.addr_max, ra2.addr_max);\n        if (maxbeg < minend) {\n          VPrintf(2, \"ThreadSanitizer: suppressing report as doubled (addr)\\n\");\n          equal_address = true;\n          break;\n        }\n      }\n    }\n  }\n  if (!equal_stack && !equal_address)\n    return false;\n  if (!equal_stack) {\n    Lock lock(&ctx->racy_mtx);\n    ctx->racy_stacks.PushBack(hash);\n  }\n  if (!equal_address) {\n    Lock lock(&ctx->racy_mtx);\n    ctx->racy_addresses.PushBack(ra0);\n  }\n  return true;\n}\n\nstatic void AddRacyStacks(ThreadState *thr, VarSizeStackTrace traces[2],\n                          uptr addr_min, uptr addr_max) {\n  Lock lock(&ctx->racy_mtx);\n  if (flags()->suppress_equal_stacks) {\n    RacyStacks hash;\n    hash.hash[0] = md5_hash(traces[0].trace, traces[0].size * sizeof(uptr));\n    hash.hash[1] = md5_hash(traces[1].trace, traces[1].size * sizeof(uptr));\n    ctx->racy_stacks.PushBack(hash);\n  }\n  if (flags()->suppress_equal_addresses) {\n    RacyAddress ra0 = {addr_min, addr_max};\n    ctx->racy_addresses.PushBack(ra0);\n  }\n}\n\nbool OutputReport(ThreadState *thr, const ScopedReport &srep) {\n  if (!flags()->report_bugs)\n    return false;\n  atomic_store_relaxed(&ctx->last_symbolize_time_ns, NanoTime());\n  const ReportDesc *rep = srep.GetReport();\n  Suppression *supp = 0;\n  uptr pc_or_addr = 0;\n  for (uptr i = 0; pc_or_addr == 0 && i < rep->mops.Size(); i++)\n    pc_or_addr = IsSuppressed(rep->typ, rep->mops[i]->stack, &supp);\n  for (uptr i = 0; pc_or_addr == 0 && i < rep->stacks.Size(); i++)\n    pc_or_addr = IsSuppressed(rep->typ, rep->stacks[i], &supp);\n  for (uptr i = 0; pc_or_addr == 0 && i < rep->threads.Size(); i++)\n    pc_or_addr = IsSuppressed(rep->typ, rep->threads[i]->stack, &supp);\n  for (uptr i = 0; pc_or_addr == 0 && i < rep->locs.Size(); i++)\n    pc_or_addr = IsSuppressed(rep->typ, rep->locs[i], &supp);\n  if (pc_or_addr != 0) {\n    Lock lock(&ctx->fired_suppressions_mtx);\n    FiredSuppression s = {srep.GetReport()->typ, pc_or_addr, supp};\n    ctx->fired_suppressions.push_back(s);\n  }\n  {\n    bool old_is_freeing = thr->is_freeing;\n    thr->is_freeing = false;\n    bool suppressed = OnReport(rep, pc_or_addr != 0);\n    thr->is_freeing = old_is_freeing;\n    if (suppressed)\n      return false;\n  }\n  PrintReport(rep);\n  ctx->nreported++;\n  if (flags()->halt_on_error)\n    Die();\n  return true;\n}\n\nbool IsFiredSuppression(Context *ctx, ReportType type, StackTrace trace) {\n  ReadLock lock(&ctx->fired_suppressions_mtx);\n  for (uptr k = 0; k < ctx->fired_suppressions.size(); k++) {\n    if (ctx->fired_suppressions[k].type != type)\n      continue;\n    for (uptr j = 0; j < trace.size; j++) {\n      FiredSuppression *s = &ctx->fired_suppressions[k];\n      if (trace.trace[j] == s->pc_or_addr) {\n        if (s->supp)\n          atomic_fetch_add(&s->supp->hit_count, 1, memory_order_relaxed);\n        return true;\n      }\n    }\n  }\n  return false;\n}\n\nstatic bool IsFiredSuppression(Context *ctx, ReportType type, uptr addr) {\n  ReadLock lock(&ctx->fired_suppressions_mtx);\n  for (uptr k = 0; k < ctx->fired_suppressions.size(); k++) {\n    if (ctx->fired_suppressions[k].type != type)\n      continue;\n    FiredSuppression *s = &ctx->fired_suppressions[k];\n    if (addr == s->pc_or_addr) {\n      if (s->supp)\n        atomic_fetch_add(&s->supp->hit_count, 1, memory_order_relaxed);\n      return true;\n    }\n  }\n  return false;\n}\n\nstatic bool RaceBetweenAtomicAndFree(ThreadState *thr) {\n  Shadow s0(thr->racy_state[0]);\n  Shadow s1(thr->racy_state[1]);\n  CHECK(!(s0.IsAtomic() && s1.IsAtomic()));\n  if (!s0.IsAtomic() && !s1.IsAtomic())\n    return true;\n  if (s0.IsAtomic() && s1.IsFreed())\n    return true;\n  if (s1.IsAtomic() && thr->is_freeing)\n    return true;\n  return false;\n}\n\nvoid ReportRace(ThreadState *thr) {\n  CheckNoLocks(thr);\n\n  // Symbolizer makes lots of intercepted calls. If we try to process them,\n  // at best it will cause deadlocks on internal mutexes.\n  ScopedIgnoreInterceptors ignore;\n\n  if (!flags()->report_bugs)\n    return;\n  if (!flags()->report_atomic_races && !RaceBetweenAtomicAndFree(thr))\n    return;\n\n  bool freed = false;\n  {\n    Shadow s(thr->racy_state[1]);\n    freed = s.GetFreedAndReset();\n    thr->racy_state[1] = s.raw();\n  }\n\n  uptr addr = ShadowToMem((uptr)thr->racy_shadow_addr);\n  uptr addr_min = 0;\n  uptr addr_max = 0;\n  {\n    uptr a0 = addr + Shadow(thr->racy_state[0]).addr0();\n    uptr a1 = addr + Shadow(thr->racy_state[1]).addr0();\n    uptr e0 = a0 + Shadow(thr->racy_state[0]).size();\n    uptr e1 = a1 + Shadow(thr->racy_state[1]).size();\n    addr_min = min(a0, a1);\n    addr_max = max(e0, e1);\n    if (IsExpectedReport(addr_min, addr_max - addr_min))\n      return;\n  }\n\n  ReportType typ = ReportTypeRace;\n  if (thr->is_vptr_access && freed)\n    typ = ReportTypeVptrUseAfterFree;\n  else if (thr->is_vptr_access)\n    typ = ReportTypeVptrRace;\n  else if (freed)\n    typ = ReportTypeUseAfterFree;\n\n  if (IsFiredSuppression(ctx, typ, addr))\n    return;\n\n  const uptr kMop = 2;\n  VarSizeStackTrace traces[kMop];\n  const uptr toppc = TraceTopPC(thr);\n  ObtainCurrentStack(thr, toppc, &traces[0]);\n  if (IsFiredSuppression(ctx, typ, traces[0]))\n    return;\n\n  // MutexSet is too large to live on stack.\n  Vector<u64> mset_buffer(MBlockScopedBuf);\n  mset_buffer.Resize(sizeof(MutexSet) / sizeof(u64) + 1);\n  MutexSet *mset2 = new(&mset_buffer[0]) MutexSet();\n\n  Shadow s2(thr->racy_state[1]);\n  RestoreStack(s2.tid(), s2.epoch(), &traces[1], mset2);\n  if (IsFiredSuppression(ctx, typ, traces[1]))\n    return;\n\n  if (HandleRacyStacks(thr, traces, addr_min, addr_max))\n    return;\n\n  ThreadRegistryLock l0(ctx->thread_registry);\n  ScopedReport rep(typ);\n  for (uptr i = 0; i < kMop; i++) {\n    Shadow s(thr->racy_state[i]);\n    rep.AddMemoryAccess(addr, s, traces[i], i == 0 ? &thr->mset : mset2);\n  }\n\n  for (uptr i = 0; i < kMop; i++) {\n    FastState s(thr->racy_state[i]);\n    ThreadContext *tctx = static_cast<ThreadContext*>(\n        ctx->thread_registry->GetThreadLocked(s.tid()));\n    if (s.epoch() < tctx->epoch0 || s.epoch() > tctx->epoch1)\n      continue;\n    rep.AddThread(tctx);\n  }\n\n  rep.AddLocation(addr_min, addr_max - addr_min);\n\n#ifndef SANITIZER_GO\n  {  // NOLINT\n    Shadow s(thr->racy_state[1]);\n    if (s.epoch() <= thr->last_sleep_clock.get(s.tid()))\n      rep.AddSleep(thr->last_sleep_stack_id);\n  }\n#endif\n\n  if (!OutputReport(thr, rep))\n    return;\n\n  AddRacyStacks(thr, traces, addr_min, addr_max);\n}\n\nvoid PrintCurrentStack(ThreadState *thr, uptr pc) {\n  VarSizeStackTrace trace;\n  ObtainCurrentStack(thr, pc, &trace);\n  PrintStack(SymbolizeStack(trace));\n}\n\nvoid PrintCurrentStackSlow(uptr pc) {\n#ifndef SANITIZER_GO\n  BufferedStackTrace *ptrace =\n      new(internal_alloc(MBlockStackTrace, sizeof(BufferedStackTrace)))\n          BufferedStackTrace();\n  ptrace->Unwind(kStackTraceMax, pc, 0, 0, 0, 0, false);\n  for (uptr i = 0; i < ptrace->size / 2; i++) {\n    uptr tmp = ptrace->trace_buffer[i];\n    ptrace->trace_buffer[i] = ptrace->trace_buffer[ptrace->size - i - 1];\n    ptrace->trace_buffer[ptrace->size - i - 1] = tmp;\n  }\n  PrintStack(SymbolizeStack(*ptrace));\n#endif\n}\n\n}  // namespace __tsan\n\nusing namespace __tsan;\n\nextern \"C\" {\nSANITIZER_INTERFACE_ATTRIBUTE\nvoid __sanitizer_print_stack_trace() {\n  PrintCurrentStackSlow(StackTrace::GetCurrentPc());\n}\n}  // extern \"C\"\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc",
    "content": "//===-- tsan_rtl_thread.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"tsan_rtl.h\"\n#include \"tsan_mman.h\"\n#include \"tsan_platform.h\"\n#include \"tsan_report.h\"\n#include \"tsan_sync.h\"\n\nnamespace __tsan {\n\n// ThreadContext implementation.\n\nThreadContext::ThreadContext(int tid)\n  : ThreadContextBase(tid)\n  , thr()\n  , sync()\n  , epoch0()\n  , epoch1() {\n}\n\n#ifndef SANITIZER_GO\nThreadContext::~ThreadContext() {\n}\n#endif\n\nvoid ThreadContext::OnDead() {\n  CHECK_EQ(sync.size(), 0);\n}\n\nvoid ThreadContext::OnJoined(void *arg) {\n  ThreadState *caller_thr = static_cast<ThreadState *>(arg);\n  AcquireImpl(caller_thr, 0, &sync);\n  sync.Reset(&caller_thr->clock_cache);\n}\n\nstruct OnCreatedArgs {\n  ThreadState *thr;\n  uptr pc;\n};\n\nvoid ThreadContext::OnCreated(void *arg) {\n  thr = 0;\n  if (tid == 0)\n    return;\n  OnCreatedArgs *args = static_cast<OnCreatedArgs *>(arg);\n  if (!args->thr)  // GCD workers don't have a parent thread.\n    return;\n  args->thr->fast_state.IncrementEpoch();\n  // Can't increment epoch w/o writing to the trace as well.\n  TraceAddEvent(args->thr, args->thr->fast_state, EventTypeMop, 0);\n  ReleaseImpl(args->thr, 0, &sync);\n  creation_stack_id = CurrentStackId(args->thr, args->pc);\n  if (reuse_count == 0)\n    StatInc(args->thr, StatThreadMaxTid);\n}\n\nvoid ThreadContext::OnReset() {\n  CHECK_EQ(sync.size(), 0);\n  FlushUnneededShadowMemory(GetThreadTrace(tid), TraceSize() * sizeof(Event));\n  //!!! FlushUnneededShadowMemory(GetThreadTraceHeader(tid), sizeof(Trace));\n}\n\nvoid ThreadContext::OnDetached(void *arg) {\n  ThreadState *thr1 = static_cast<ThreadState*>(arg);\n  sync.Reset(&thr1->clock_cache);\n}\n\nstruct OnStartedArgs {\n  ThreadState *thr;\n  uptr stk_addr;\n  uptr stk_size;\n  uptr tls_addr;\n  uptr tls_size;\n};\n\nvoid ThreadContext::OnStarted(void *arg) {\n  OnStartedArgs *args = static_cast<OnStartedArgs*>(arg);\n  thr = args->thr;\n  // RoundUp so that one trace part does not contain events\n  // from different threads.\n  epoch0 = RoundUp(epoch1 + 1, kTracePartSize);\n  epoch1 = (u64)-1;\n  new(thr) ThreadState(ctx, tid, unique_id, epoch0, reuse_count,\n      args->stk_addr, args->stk_size, args->tls_addr, args->tls_size);\n#ifndef SANITIZER_GO\n  thr->shadow_stack = &ThreadTrace(thr->tid)->shadow_stack[0];\n  thr->shadow_stack_pos = thr->shadow_stack;\n  thr->shadow_stack_end = thr->shadow_stack + kShadowStackSize;\n#else\n  // Setup dynamic shadow stack.\n  const int kInitStackSize = 8;\n  thr->shadow_stack = (uptr*)internal_alloc(MBlockShadowStack,\n      kInitStackSize * sizeof(uptr));\n  thr->shadow_stack_pos = thr->shadow_stack;\n  thr->shadow_stack_end = thr->shadow_stack + kInitStackSize;\n#endif\n#ifndef SANITIZER_GO\n  AllocatorThreadStart(thr);\n#endif\n  if (common_flags()->detect_deadlocks) {\n    thr->dd_pt = ctx->dd->CreatePhysicalThread();\n    thr->dd_lt = ctx->dd->CreateLogicalThread(unique_id);\n  }\n  thr->fast_state.SetHistorySize(flags()->history_size);\n  // Commit switch to the new part of the trace.\n  // TraceAddEvent will reset stack0/mset0 in the new part for us.\n  TraceAddEvent(thr, thr->fast_state, EventTypeMop, 0);\n\n  thr->fast_synch_epoch = epoch0;\n  AcquireImpl(thr, 0, &sync);\n  StatInc(thr, StatSyncAcquire);\n  sync.Reset(&thr->clock_cache);\n  thr->is_inited = true;\n  DPrintf(\"#%d: ThreadStart epoch=%zu stk_addr=%zx stk_size=%zx \"\n          \"tls_addr=%zx tls_size=%zx\\n\",\n          tid, (uptr)epoch0, args->stk_addr, args->stk_size,\n          args->tls_addr, args->tls_size);\n}\n\nvoid ThreadContext::OnFinished() {\n  if (!detached) {\n    thr->fast_state.IncrementEpoch();\n    // Can't increment epoch w/o writing to the trace as well.\n    TraceAddEvent(thr, thr->fast_state, EventTypeMop, 0);\n    ReleaseImpl(thr, 0, &sync);\n  }\n  epoch1 = thr->fast_state.epoch();\n\n  if (common_flags()->detect_deadlocks) {\n    ctx->dd->DestroyPhysicalThread(thr->dd_pt);\n    ctx->dd->DestroyLogicalThread(thr->dd_lt);\n  }\n  ctx->clock_alloc.FlushCache(&thr->clock_cache);\n  ctx->metamap.OnThreadIdle(thr);\n#ifndef SANITIZER_GO\n  AllocatorThreadFinish(thr);\n#endif\n  thr->~ThreadState();\n#if TSAN_COLLECT_STATS\n  StatAggregate(ctx->stat, thr->stat);\n#endif\n  thr = 0;\n}\n\n#ifndef SANITIZER_GO\nstruct ThreadLeak {\n  ThreadContext *tctx;\n  int count;\n};\n\nstatic void MaybeReportThreadLeak(ThreadContextBase *tctx_base, void *arg) {\n  Vector<ThreadLeak> &leaks = *(Vector<ThreadLeak>*)arg;\n  ThreadContext *tctx = static_cast<ThreadContext*>(tctx_base);\n  if (tctx->detached || tctx->status != ThreadStatusFinished)\n    return;\n  for (uptr i = 0; i < leaks.Size(); i++) {\n    if (leaks[i].tctx->creation_stack_id == tctx->creation_stack_id) {\n      leaks[i].count++;\n      return;\n    }\n  }\n  ThreadLeak leak = {tctx, 1};\n  leaks.PushBack(leak);\n}\n#endif\n\n#ifndef SANITIZER_GO\nstatic void ReportIgnoresEnabled(ThreadContext *tctx, IgnoreSet *set) {\n  if (tctx->tid == 0) {\n    Printf(\"ThreadSanitizer: main thread finished with ignores enabled\\n\");\n  } else {\n    Printf(\"ThreadSanitizer: thread T%d %s finished with ignores enabled,\"\n      \" created at:\\n\", tctx->tid, tctx->name);\n    PrintStack(SymbolizeStackId(tctx->creation_stack_id));\n  }\n  Printf(\"  One of the following ignores was not ended\"\n      \" (in order of probability)\\n\");\n  for (uptr i = 0; i < set->Size(); i++) {\n    Printf(\"  Ignore was enabled at:\\n\");\n    PrintStack(SymbolizeStackId(set->At(i)));\n  }\n  Die();\n}\n\nstatic void ThreadCheckIgnore(ThreadState *thr) {\n  if (ctx->after_multithreaded_fork)\n    return;\n  if (thr->ignore_reads_and_writes)\n    ReportIgnoresEnabled(thr->tctx, &thr->mop_ignore_set);\n  if (thr->ignore_sync)\n    ReportIgnoresEnabled(thr->tctx, &thr->sync_ignore_set);\n}\n#else\nstatic void ThreadCheckIgnore(ThreadState *thr) {}\n#endif\n\nvoid ThreadFinalize(ThreadState *thr) {\n  ThreadCheckIgnore(thr);\n#ifndef SANITIZER_GO\n  if (!flags()->report_thread_leaks)\n    return;\n  ThreadRegistryLock l(ctx->thread_registry);\n  Vector<ThreadLeak> leaks(MBlockScopedBuf);\n  ctx->thread_registry->RunCallbackForEachThreadLocked(\n      MaybeReportThreadLeak, &leaks);\n  for (uptr i = 0; i < leaks.Size(); i++) {\n    ScopedReport rep(ReportTypeThreadLeak);\n    rep.AddThread(leaks[i].tctx, true);\n    rep.SetCount(leaks[i].count);\n    OutputReport(thr, rep);\n  }\n#endif\n}\n\nint ThreadCount(ThreadState *thr) {\n  uptr result;\n  ctx->thread_registry->GetNumberOfThreads(0, 0, &result);\n  return (int)result;\n}\n\nint ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) {\n  StatInc(thr, StatThreadCreate);\n  OnCreatedArgs args = { thr, pc };\n  u32 parent_tid = thr ? thr->tid : kInvalidTid;  // No parent for GCD workers.\n  int tid =\n      ctx->thread_registry->CreateThread(uid, detached, parent_tid, &args);\n  DPrintf(\"#%d: ThreadCreate tid=%d uid=%zu\\n\", parent_tid, tid, uid);\n  StatSet(thr, StatThreadMaxAlive, ctx->thread_registry->GetMaxAliveThreads());\n  return tid;\n}\n\nvoid ThreadStart(ThreadState *thr, int tid, uptr os_id) {\n  uptr stk_addr = 0;\n  uptr stk_size = 0;\n  uptr tls_addr = 0;\n  uptr tls_size = 0;\n#ifndef SANITIZER_GO\n  GetThreadStackAndTls(tid == 0, &stk_addr, &stk_size, &tls_addr, &tls_size);\n\n  if (tid) {\n    if (stk_addr && stk_size)\n      MemoryRangeImitateWrite(thr, /*pc=*/ 1, stk_addr, stk_size);\n\n    if (tls_addr && tls_size) {\n      // Check that the thr object is in tls;\n      const uptr thr_beg = (uptr)thr;\n      const uptr thr_end = (uptr)thr + sizeof(*thr);\n      CHECK_GE(thr_beg, tls_addr);\n      CHECK_LE(thr_beg, tls_addr + tls_size);\n      CHECK_GE(thr_end, tls_addr);\n      CHECK_LE(thr_end, tls_addr + tls_size);\n      // Since the thr object is huge, skip it.\n      MemoryRangeImitateWrite(thr, /*pc=*/ 2, tls_addr, thr_beg - tls_addr);\n      MemoryRangeImitateWrite(thr, /*pc=*/ 2,\n          thr_end, tls_addr + tls_size - thr_end);\n    }\n  }\n#endif\n\n  ThreadRegistry *tr = ctx->thread_registry;\n  OnStartedArgs args = { thr, stk_addr, stk_size, tls_addr, tls_size };\n  tr->StartThread(tid, os_id, &args);\n\n  tr->Lock();\n  thr->tctx = (ThreadContext*)tr->GetThreadLocked(tid);\n  tr->Unlock();\n\n#ifndef SANITIZER_GO\n  if (ctx->after_multithreaded_fork) {\n    thr->ignore_interceptors++;\n    ThreadIgnoreBegin(thr, 0);\n    ThreadIgnoreSyncBegin(thr, 0);\n  }\n#endif\n}\n\nvoid ThreadFinish(ThreadState *thr) {\n  ThreadCheckIgnore(thr);\n  StatInc(thr, StatThreadFinish);\n  if (thr->stk_addr && thr->stk_size)\n    DontNeedShadowFor(thr->stk_addr, thr->stk_size);\n  if (thr->tls_addr && thr->tls_size)\n    DontNeedShadowFor(thr->tls_addr, thr->tls_size);\n  thr->is_dead = true;\n  ctx->thread_registry->FinishThread(thr->tid);\n}\n\nstatic bool FindThreadByUid(ThreadContextBase *tctx, void *arg) {\n  uptr uid = (uptr)arg;\n  if (tctx->user_id == uid && tctx->status != ThreadStatusInvalid) {\n    tctx->user_id = 0;\n    return true;\n  }\n  return false;\n}\n\nint ThreadTid(ThreadState *thr, uptr pc, uptr uid) {\n  int res = ctx->thread_registry->FindThread(FindThreadByUid, (void*)uid);\n  DPrintf(\"#%d: ThreadTid uid=%zu tid=%d\\n\", thr->tid, uid, res);\n  return res;\n}\n\nvoid ThreadJoin(ThreadState *thr, uptr pc, int tid) {\n  CHECK_GT(tid, 0);\n  CHECK_LT(tid, kMaxTid);\n  DPrintf(\"#%d: ThreadJoin tid=%d\\n\", thr->tid, tid);\n  ctx->thread_registry->JoinThread(tid, thr);\n}\n\nvoid ThreadDetach(ThreadState *thr, uptr pc, int tid) {\n  CHECK_GT(tid, 0);\n  CHECK_LT(tid, kMaxTid);\n  ctx->thread_registry->DetachThread(tid, thr);\n}\n\nvoid ThreadSetName(ThreadState *thr, const char *name) {\n  ctx->thread_registry->SetThreadName(thr->tid, name);\n}\n\nvoid MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr,\n                       uptr size, bool is_write) {\n  if (size == 0)\n    return;\n\n  u64 *shadow_mem = (u64*)MemToShadow(addr);\n  DPrintf2(\"#%d: MemoryAccessRange: @%p %p size=%d is_write=%d\\n\",\n      thr->tid, (void*)pc, (void*)addr,\n      (int)size, is_write);\n\n#if SANITIZER_DEBUG\n  if (!IsAppMem(addr)) {\n    Printf(\"Access to non app mem %zx\\n\", addr);\n    DCHECK(IsAppMem(addr));\n  }\n  if (!IsAppMem(addr + size - 1)) {\n    Printf(\"Access to non app mem %zx\\n\", addr + size - 1);\n    DCHECK(IsAppMem(addr + size - 1));\n  }\n  if (!IsShadowMem((uptr)shadow_mem)) {\n    Printf(\"Bad shadow addr %p (%zx)\\n\", shadow_mem, addr);\n    DCHECK(IsShadowMem((uptr)shadow_mem));\n  }\n  if (!IsShadowMem((uptr)(shadow_mem + size * kShadowCnt / 8 - 1))) {\n    Printf(\"Bad shadow addr %p (%zx)\\n\",\n               shadow_mem + size * kShadowCnt / 8 - 1, addr + size - 1);\n    DCHECK(IsShadowMem((uptr)(shadow_mem + size * kShadowCnt / 8 - 1)));\n  }\n#endif\n\n  StatInc(thr, StatMopRange);\n\n  if (*shadow_mem == kShadowRodata) {\n    // Access to .rodata section, no races here.\n    // Measurements show that it can be 10-20% of all memory accesses.\n    StatInc(thr, StatMopRangeRodata);\n    return;\n  }\n\n  FastState fast_state = thr->fast_state;\n  if (fast_state.GetIgnoreBit())\n    return;\n\n  fast_state.IncrementEpoch();\n  thr->fast_state = fast_state;\n  TraceAddEvent(thr, fast_state, EventTypeMop, pc);\n\n  bool unaligned = (addr % kShadowCell) != 0;\n\n  // Handle unaligned beginning, if any.\n  for (; addr % kShadowCell && size; addr++, size--) {\n    int const kAccessSizeLog = 0;\n    Shadow cur(fast_state);\n    cur.SetWrite(is_write);\n    cur.SetAddr0AndSizeLog(addr & (kShadowCell - 1), kAccessSizeLog);\n    MemoryAccessImpl(thr, addr, kAccessSizeLog, is_write, false,\n        shadow_mem, cur);\n  }\n  if (unaligned)\n    shadow_mem += kShadowCnt;\n  // Handle middle part, if any.\n  for (; size >= kShadowCell; addr += kShadowCell, size -= kShadowCell) {\n    int const kAccessSizeLog = 3;\n    Shadow cur(fast_state);\n    cur.SetWrite(is_write);\n    cur.SetAddr0AndSizeLog(0, kAccessSizeLog);\n    MemoryAccessImpl(thr, addr, kAccessSizeLog, is_write, false,\n        shadow_mem, cur);\n    shadow_mem += kShadowCnt;\n  }\n  // Handle ending, if any.\n  for (; size; addr++, size--) {\n    int const kAccessSizeLog = 0;\n    Shadow cur(fast_state);\n    cur.SetWrite(is_write);\n    cur.SetAddr0AndSizeLog(addr & (kShadowCell - 1), kAccessSizeLog);\n    MemoryAccessImpl(thr, addr, kAccessSizeLog, is_write, false,\n        shadow_mem, cur);\n  }\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_stack_trace.cc",
    "content": "//===-- tsan_stack_trace.cc -----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_stack_trace.h\"\n#include \"tsan_rtl.h\"\n#include \"tsan_mman.h\"\n\nnamespace __tsan {\n\nVarSizeStackTrace::VarSizeStackTrace()\n    : StackTrace(nullptr, 0), trace_buffer(nullptr) {}\n\nVarSizeStackTrace::~VarSizeStackTrace() {\n  ResizeBuffer(0);\n}\n\nvoid VarSizeStackTrace::ResizeBuffer(uptr new_size) {\n  if (trace_buffer) {\n    internal_free(trace_buffer);\n  }\n  trace_buffer =\n      (new_size > 0)\n          ? (uptr *)internal_alloc(MBlockStackTrace,\n                                   new_size * sizeof(trace_buffer[0]))\n          : nullptr;\n  trace = trace_buffer;\n  size = new_size;\n}\n\nvoid VarSizeStackTrace::Init(const uptr *pcs, uptr cnt, uptr extra_top_pc) {\n  ResizeBuffer(cnt + !!extra_top_pc);\n  internal_memcpy(trace_buffer, pcs, cnt * sizeof(trace_buffer[0]));\n  if (extra_top_pc)\n    trace_buffer[cnt] = extra_top_pc;\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_stack_trace.h",
    "content": "//===-- tsan_stack_trace.h --------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_STACK_TRACE_H\n#define TSAN_STACK_TRACE_H\n\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"tsan_defs.h\"\n\nnamespace __tsan {\n\n// StackTrace which calls malloc/free to allocate the buffer for\n// addresses in stack traces.\nstruct VarSizeStackTrace : public StackTrace {\n  uptr *trace_buffer;  // Owned.\n\n  VarSizeStackTrace();\n  ~VarSizeStackTrace();\n  void Init(const uptr *pcs, uptr cnt, uptr extra_top_pc = 0);\n\n private:\n  void ResizeBuffer(uptr new_size);\n\n  VarSizeStackTrace(const VarSizeStackTrace &);\n  void operator=(const VarSizeStackTrace &);\n};\n\n}  // namespace __tsan\n\n#endif  // TSAN_STACK_TRACE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_stat.cc",
    "content": "//===-- tsan_stat.cc ------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_stat.h\"\n#include \"tsan_rtl.h\"\n\nnamespace __tsan {\n\n#if TSAN_COLLECT_STATS\n\nvoid StatAggregate(u64 *dst, u64 *src) {\n  for (int i = 0; i < StatCnt; i++)\n    dst[i] += src[i];\n}\n\nvoid StatOutput(u64 *stat) {\n  stat[StatShadowNonZero] = stat[StatShadowProcessed] - stat[StatShadowZero];\n\n  static const char *name[StatCnt] = {};\n  name[StatMop]                          = \"Memory accesses                   \";\n  name[StatMopRead]                      = \"  Including reads                 \";\n  name[StatMopWrite]                     = \"            writes                \";\n  name[StatMop1]                         = \"  Including size 1                \";\n  name[StatMop2]                         = \"            size 2                \";\n  name[StatMop4]                         = \"            size 4                \";\n  name[StatMop8]                         = \"            size 8                \";\n  name[StatMopSame]                      = \"  Including same                  \";\n  name[StatMopIgnored]                   = \"  Including ignored               \";\n  name[StatMopRange]                     = \"  Including range                 \";\n  name[StatMopRodata]                    = \"  Including .rodata               \";\n  name[StatMopRangeRodata]               = \"  Including .rodata range         \";\n  name[StatShadowProcessed]              = \"Shadow processed                  \";\n  name[StatShadowZero]                   = \"  Including empty                 \";\n  name[StatShadowNonZero]                = \"  Including non empty             \";\n  name[StatShadowSameSize]               = \"  Including same size             \";\n  name[StatShadowIntersect]              = \"            intersect             \";\n  name[StatShadowNotIntersect]           = \"            not intersect         \";\n  name[StatShadowSameThread]             = \"  Including same thread           \";\n  name[StatShadowAnotherThread]          = \"            another thread        \";\n  name[StatShadowReplace]                = \"  Including evicted               \";\n\n  name[StatFuncEnter]                    = \"Function entries                  \";\n  name[StatFuncExit]                     = \"Function exits                    \";\n  name[StatEvents]                       = \"Events collected                  \";\n\n  name[StatThreadCreate]                 = \"Total threads created             \";\n  name[StatThreadFinish]                 = \"  threads finished                \";\n  name[StatThreadReuse]                  = \"  threads reused                  \";\n  name[StatThreadMaxTid]                 = \"  max tid                         \";\n  name[StatThreadMaxAlive]               = \"  max alive threads               \";\n\n  name[StatMutexCreate]                  = \"Mutexes created                   \";\n  name[StatMutexDestroy]                 = \"  destroyed                       \";\n  name[StatMutexLock]                    = \"  lock                            \";\n  name[StatMutexUnlock]                  = \"  unlock                          \";\n  name[StatMutexRecLock]                 = \"  recursive lock                  \";\n  name[StatMutexRecUnlock]               = \"  recursive unlock                \";\n  name[StatMutexReadLock]                = \"  read lock                       \";\n  name[StatMutexReadUnlock]              = \"  read unlock                     \";\n\n  name[StatSyncCreated]                  = \"Sync objects created              \";\n  name[StatSyncDestroyed]                = \"             destroyed            \";\n  name[StatSyncAcquire]                  = \"             acquired             \";\n  name[StatSyncRelease]                  = \"             released             \";\n\n  name[StatClockAcquire]                 = \"Clock acquire                     \";\n  name[StatClockAcquireEmpty]            = \"  empty clock                     \";\n  name[StatClockAcquireFastRelease]      = \"  fast from release-store         \";\n  name[StatClockAcquireLarge]            = \"  contains my tid                 \";\n  name[StatClockAcquireRepeat]           = \"  repeated (fast)                 \";\n  name[StatClockAcquireFull]             = \"  full (slow)                     \";\n  name[StatClockAcquiredSomething]       = \"  acquired something              \";\n  name[StatClockRelease]                 = \"Clock release                     \";\n  name[StatClockReleaseResize]           = \"  resize                          \";\n  name[StatClockReleaseFast1]            = \"  fast1                           \";\n  name[StatClockReleaseFast2]            = \"  fast2                           \";\n  name[StatClockReleaseSlow]             = \"  dirty overflow (slow)           \";\n  name[StatClockReleaseFull]             = \"  full (slow)                     \";\n  name[StatClockReleaseAcquired]         = \"  was acquired                    \";\n  name[StatClockReleaseClearTail]        = \"  clear tail                      \";\n  name[StatClockStore]                   = \"Clock release store               \";\n  name[StatClockStoreResize]             = \"  resize                          \";\n  name[StatClockStoreFast]               = \"  fast                            \";\n  name[StatClockStoreFull]               = \"  slow                            \";\n  name[StatClockStoreTail]               = \"  clear tail                      \";\n  name[StatClockAcquireRelease]          = \"Clock acquire-release             \";\n\n  name[StatAtomic]                       = \"Atomic operations                 \";\n  name[StatAtomicLoad]                   = \"  Including load                  \";\n  name[StatAtomicStore]                  = \"            store                 \";\n  name[StatAtomicExchange]               = \"            exchange              \";\n  name[StatAtomicFetchAdd]               = \"            fetch_add             \";\n  name[StatAtomicFetchSub]               = \"            fetch_sub             \";\n  name[StatAtomicFetchAnd]               = \"            fetch_and             \";\n  name[StatAtomicFetchOr]                = \"            fetch_or              \";\n  name[StatAtomicFetchXor]               = \"            fetch_xor             \";\n  name[StatAtomicFetchNand]              = \"            fetch_nand            \";\n  name[StatAtomicCAS]                    = \"            compare_exchange      \";\n  name[StatAtomicFence]                  = \"            fence                 \";\n  name[StatAtomicRelaxed]                = \"  Including relaxed               \";\n  name[StatAtomicConsume]                = \"            consume               \";\n  name[StatAtomicAcquire]                = \"            acquire               \";\n  name[StatAtomicRelease]                = \"            release               \";\n  name[StatAtomicAcq_Rel]                = \"            acq_rel               \";\n  name[StatAtomicSeq_Cst]                = \"            seq_cst               \";\n  name[StatAtomic1]                      = \"  Including size 1                \";\n  name[StatAtomic2]                      = \"            size 2                \";\n  name[StatAtomic4]                      = \"            size 4                \";\n  name[StatAtomic8]                      = \"            size 8                \";\n  name[StatAtomic16]                     = \"            size 16               \";\n\n  name[StatAnnotation]                   = \"Dynamic annotations               \";\n  name[StatAnnotateHappensBefore]        = \"  HappensBefore                   \";\n  name[StatAnnotateHappensAfter]         = \"  HappensAfter                    \";\n  name[StatAnnotateCondVarSignal]        = \"  CondVarSignal                   \";\n  name[StatAnnotateCondVarSignalAll]     = \"  CondVarSignalAll                \";\n  name[StatAnnotateMutexIsNotPHB]        = \"  MutexIsNotPHB                   \";\n  name[StatAnnotateCondVarWait]          = \"  CondVarWait                     \";\n  name[StatAnnotateRWLockCreate]         = \"  RWLockCreate                    \";\n  name[StatAnnotateRWLockCreateStatic]   = \"  StatAnnotateRWLockCreateStatic  \";\n  name[StatAnnotateRWLockDestroy]        = \"  RWLockDestroy                   \";\n  name[StatAnnotateRWLockAcquired]       = \"  RWLockAcquired                  \";\n  name[StatAnnotateRWLockReleased]       = \"  RWLockReleased                  \";\n  name[StatAnnotateTraceMemory]          = \"  TraceMemory                     \";\n  name[StatAnnotateFlushState]           = \"  FlushState                      \";\n  name[StatAnnotateNewMemory]            = \"  NewMemory                       \";\n  name[StatAnnotateNoOp]                 = \"  NoOp                            \";\n  name[StatAnnotateFlushExpectedRaces]   = \"  FlushExpectedRaces              \";\n  name[StatAnnotateEnableRaceDetection]  = \"  EnableRaceDetection             \";\n  name[StatAnnotateMutexIsUsedAsCondVar] = \"  MutexIsUsedAsCondVar            \";\n  name[StatAnnotatePCQGet]               = \"  PCQGet                          \";\n  name[StatAnnotatePCQPut]               = \"  PCQPut                          \";\n  name[StatAnnotatePCQDestroy]           = \"  PCQDestroy                      \";\n  name[StatAnnotatePCQCreate]            = \"  PCQCreate                       \";\n  name[StatAnnotateExpectRace]           = \"  ExpectRace                      \";\n  name[StatAnnotateBenignRaceSized]      = \"  BenignRaceSized                 \";\n  name[StatAnnotateBenignRace]           = \"  BenignRace                      \";\n  name[StatAnnotateIgnoreReadsBegin]     = \"  IgnoreReadsBegin                \";\n  name[StatAnnotateIgnoreReadsEnd]       = \"  IgnoreReadsEnd                  \";\n  name[StatAnnotateIgnoreWritesBegin]    = \"  IgnoreWritesBegin               \";\n  name[StatAnnotateIgnoreWritesEnd]      = \"  IgnoreWritesEnd                 \";\n  name[StatAnnotateIgnoreSyncBegin]      = \"  IgnoreSyncBegin                 \";\n  name[StatAnnotateIgnoreSyncEnd]        = \"  IgnoreSyncEnd                   \";\n  name[StatAnnotatePublishMemoryRange]   = \"  PublishMemoryRange              \";\n  name[StatAnnotateUnpublishMemoryRange] = \"  UnpublishMemoryRange            \";\n  name[StatAnnotateThreadName]           = \"  ThreadName                      \";\n\n  name[StatMtxTotal]                     = \"Contentionz                       \";\n  name[StatMtxTrace]                     = \"  Trace                           \";\n  name[StatMtxThreads]                   = \"  Threads                         \";\n  name[StatMtxReport]                    = \"  Report                          \";\n  name[StatMtxSyncVar]                   = \"  SyncVar                         \";\n  name[StatMtxSyncTab]                   = \"  SyncTab                         \";\n  name[StatMtxSlab]                      = \"  Slab                            \";\n  name[StatMtxAtExit]                    = \"  Atexit                          \";\n  name[StatMtxAnnotations]               = \"  Annotations                     \";\n  name[StatMtxMBlock]                    = \"  MBlock                          \";\n  name[StatMtxDeadlockDetector]          = \"  DeadlockDetector                \";\n  name[StatMtxFired]                     = \"  FiredSuppressions               \";\n  name[StatMtxRacy]                      = \"  RacyStacks                      \";\n  name[StatMtxFD]                        = \"  FD                              \";\n\n  Printf(\"Statistics:\\n\");\n  for (int i = 0; i < StatCnt; i++)\n    Printf(\"%s: %16zu\\n\", name[i], (uptr)stat[i]);\n}\n\n#endif\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_stat.h",
    "content": "//===-- tsan_stat.h ---------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef TSAN_STAT_H\n#define TSAN_STAT_H\n\nnamespace __tsan {\n\nenum StatType {\n  // Memory access processing related stuff.\n  StatMop,\n  StatMopRead,\n  StatMopWrite,\n  StatMop1,  // These must be consequtive.\n  StatMop2,\n  StatMop4,\n  StatMop8,\n  StatMopSame,\n  StatMopIgnored,\n  StatMopRange,\n  StatMopRodata,\n  StatMopRangeRodata,\n  StatShadowProcessed,\n  StatShadowZero,\n  StatShadowNonZero,  // Derived.\n  StatShadowSameSize,\n  StatShadowIntersect,\n  StatShadowNotIntersect,\n  StatShadowSameThread,\n  StatShadowAnotherThread,\n  StatShadowReplace,\n\n  // Func processing.\n  StatFuncEnter,\n  StatFuncExit,\n\n  // Trace processing.\n  StatEvents,\n\n  // Threads.\n  StatThreadCreate,\n  StatThreadFinish,\n  StatThreadReuse,\n  StatThreadMaxTid,\n  StatThreadMaxAlive,\n\n  // Mutexes.\n  StatMutexCreate,\n  StatMutexDestroy,\n  StatMutexLock,\n  StatMutexUnlock,\n  StatMutexRecLock,\n  StatMutexRecUnlock,\n  StatMutexReadLock,\n  StatMutexReadUnlock,\n\n  // Synchronization.\n  StatSyncCreated,\n  StatSyncDestroyed,\n  StatSyncAcquire,\n  StatSyncRelease,\n\n  // Clocks - acquire.\n  StatClockAcquire,\n  StatClockAcquireEmpty,\n  StatClockAcquireFastRelease,\n  StatClockAcquireLarge,\n  StatClockAcquireRepeat,\n  StatClockAcquireFull,\n  StatClockAcquiredSomething,\n  // Clocks - release.\n  StatClockRelease,\n  StatClockReleaseResize,\n  StatClockReleaseFast1,\n  StatClockReleaseFast2,\n  StatClockReleaseSlow,\n  StatClockReleaseFull,\n  StatClockReleaseAcquired,\n  StatClockReleaseClearTail,\n  // Clocks - release store.\n  StatClockStore,\n  StatClockStoreResize,\n  StatClockStoreFast,\n  StatClockStoreFull,\n  StatClockStoreTail,\n  // Clocks - acquire-release.\n  StatClockAcquireRelease,\n\n  // Atomics.\n  StatAtomic,\n  StatAtomicLoad,\n  StatAtomicStore,\n  StatAtomicExchange,\n  StatAtomicFetchAdd,\n  StatAtomicFetchSub,\n  StatAtomicFetchAnd,\n  StatAtomicFetchOr,\n  StatAtomicFetchXor,\n  StatAtomicFetchNand,\n  StatAtomicCAS,\n  StatAtomicFence,\n  StatAtomicRelaxed,\n  StatAtomicConsume,\n  StatAtomicAcquire,\n  StatAtomicRelease,\n  StatAtomicAcq_Rel,\n  StatAtomicSeq_Cst,\n  StatAtomic1,\n  StatAtomic2,\n  StatAtomic4,\n  StatAtomic8,\n  StatAtomic16,\n\n  // Dynamic annotations.\n  StatAnnotation,\n  StatAnnotateHappensBefore,\n  StatAnnotateHappensAfter,\n  StatAnnotateCondVarSignal,\n  StatAnnotateCondVarSignalAll,\n  StatAnnotateMutexIsNotPHB,\n  StatAnnotateCondVarWait,\n  StatAnnotateRWLockCreate,\n  StatAnnotateRWLockCreateStatic,\n  StatAnnotateRWLockDestroy,\n  StatAnnotateRWLockAcquired,\n  StatAnnotateRWLockReleased,\n  StatAnnotateTraceMemory,\n  StatAnnotateFlushState,\n  StatAnnotateNewMemory,\n  StatAnnotateNoOp,\n  StatAnnotateFlushExpectedRaces,\n  StatAnnotateEnableRaceDetection,\n  StatAnnotateMutexIsUsedAsCondVar,\n  StatAnnotatePCQGet,\n  StatAnnotatePCQPut,\n  StatAnnotatePCQDestroy,\n  StatAnnotatePCQCreate,\n  StatAnnotateExpectRace,\n  StatAnnotateBenignRaceSized,\n  StatAnnotateBenignRace,\n  StatAnnotateIgnoreReadsBegin,\n  StatAnnotateIgnoreReadsEnd,\n  StatAnnotateIgnoreWritesBegin,\n  StatAnnotateIgnoreWritesEnd,\n  StatAnnotateIgnoreSyncBegin,\n  StatAnnotateIgnoreSyncEnd,\n  StatAnnotatePublishMemoryRange,\n  StatAnnotateUnpublishMemoryRange,\n  StatAnnotateThreadName,\n\n  // Internal mutex contentionz.\n  StatMtxTotal,\n  StatMtxTrace,\n  StatMtxThreads,\n  StatMtxReport,\n  StatMtxSyncVar,\n  StatMtxSyncTab,\n  StatMtxSlab,\n  StatMtxAnnotations,\n  StatMtxAtExit,\n  StatMtxMBlock,\n  StatMtxDeadlockDetector,\n  StatMtxFired,\n  StatMtxRacy,\n  StatMtxFD,\n\n  // This must be the last.\n  StatCnt\n};\n\n}  // namespace __tsan\n\n#endif  // TSAN_STAT_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_suppressions.cc",
    "content": "//===-- tsan_suppressions.cc ----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_suppressions.h\"\n#include \"tsan_suppressions.h\"\n#include \"tsan_rtl.h\"\n#include \"tsan_flags.h\"\n#include \"tsan_mman.h\"\n#include \"tsan_platform.h\"\n\n#ifndef SANITIZER_GO\n// Suppressions for true/false positives in standard libraries.\nstatic const char *const std_suppressions =\n// Libstdc++ 4.4 has data races in std::string.\n// See http://crbug.com/181502 for an example.\n\"race:^_M_rep$\\n\"\n\"race:^_M_is_leaked$\\n\"\n// False positive when using std <thread>.\n// Happens because we miss atomic synchronization in libstdc++.\n// See http://llvm.org/bugs/show_bug.cgi?id=17066 for details.\n\"race:std::_Sp_counted_ptr_inplace<std::thread::_Impl\\n\";\n\n// Can be overriden in frontend.\nSANITIZER_WEAK_DEFAULT_IMPL\nconst char *__tsan_default_suppressions() {\n  return 0;\n}\n#endif\n\nnamespace __tsan {\n\nALIGNED(64) static char suppression_placeholder[sizeof(SuppressionContext)];\nstatic SuppressionContext *suppression_ctx = nullptr;\nstatic const char *kSuppressionTypes[] = {\n    kSuppressionRace,   kSuppressionRaceTop, kSuppressionMutex,\n    kSuppressionThread, kSuppressionSignal, kSuppressionLib,\n    kSuppressionDeadlock};\n\nvoid InitializeSuppressions() {\n  CHECK_EQ(nullptr, suppression_ctx);\n  suppression_ctx = new (suppression_placeholder) // NOLINT\n      SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes));\n  suppression_ctx->ParseFromFile(flags()->suppressions);\n#ifndef SANITIZER_GO\n  suppression_ctx->Parse(__tsan_default_suppressions());\n  suppression_ctx->Parse(std_suppressions);\n#endif\n}\n\nSuppressionContext *Suppressions() {\n  CHECK(suppression_ctx);\n  return suppression_ctx;\n}\n\nstatic const char *conv(ReportType typ) {\n  if (typ == ReportTypeRace)\n    return kSuppressionRace;\n  else if (typ == ReportTypeVptrRace)\n    return kSuppressionRace;\n  else if (typ == ReportTypeUseAfterFree)\n    return kSuppressionRace;\n  else if (typ == ReportTypeVptrUseAfterFree)\n    return kSuppressionRace;\n  else if (typ == ReportTypeThreadLeak)\n    return kSuppressionThread;\n  else if (typ == ReportTypeMutexDestroyLocked)\n    return kSuppressionMutex;\n  else if (typ == ReportTypeMutexDoubleLock)\n    return kSuppressionMutex;\n  else if (typ == ReportTypeMutexBadUnlock)\n    return kSuppressionMutex;\n  else if (typ == ReportTypeMutexBadReadLock)\n    return kSuppressionMutex;\n  else if (typ == ReportTypeMutexBadReadUnlock)\n    return kSuppressionMutex;\n  else if (typ == ReportTypeSignalUnsafe)\n    return kSuppressionSignal;\n  else if (typ == ReportTypeErrnoInSignal)\n    return kSuppressionNone;\n  else if (typ == ReportTypeDeadlock)\n    return kSuppressionDeadlock;\n  Printf(\"ThreadSanitizer: unknown report type %d\\n\", typ),\n  Die();\n}\n\nstatic uptr IsSuppressed(const char *stype, const AddressInfo &info,\n    Suppression **sp) {\n  if (suppression_ctx->Match(info.function, stype, sp) ||\n      suppression_ctx->Match(info.file, stype, sp) ||\n      suppression_ctx->Match(info.module, stype, sp)) {\n    VPrintf(2, \"ThreadSanitizer: matched suppression '%s'\\n\", (*sp)->templ);\n    atomic_fetch_add(&(*sp)->hit_count, 1, memory_order_relaxed);\n    return info.address;\n  }\n  return 0;\n}\n\nuptr IsSuppressed(ReportType typ, const ReportStack *stack, Suppression **sp) {\n  CHECK(suppression_ctx);\n  if (!suppression_ctx->SuppressionCount() || stack == 0 ||\n      !stack->suppressable)\n    return 0;\n  const char *stype = conv(typ);\n  if (0 == internal_strcmp(stype, kSuppressionNone))\n    return 0;\n  for (const SymbolizedStack *frame = stack->frames; frame;\n      frame = frame->next) {\n    uptr pc = IsSuppressed(stype, frame->info, sp);\n    if (pc != 0)\n      return pc;\n  }\n  if (0 == internal_strcmp(stype, kSuppressionRace) && stack->frames != nullptr)\n    return IsSuppressed(kSuppressionRaceTop, stack->frames->info, sp);\n  return 0;\n}\n\nuptr IsSuppressed(ReportType typ, const ReportLocation *loc, Suppression **sp) {\n  CHECK(suppression_ctx);\n  if (!suppression_ctx->SuppressionCount() || loc == 0 ||\n      loc->type != ReportLocationGlobal || !loc->suppressable)\n    return 0;\n  const char *stype = conv(typ);\n  if (0 == internal_strcmp(stype, kSuppressionNone))\n    return 0;\n  Suppression *s;\n  const DataInfo &global = loc->global;\n  if (suppression_ctx->Match(global.name, stype, &s) ||\n      suppression_ctx->Match(global.module, stype, &s)) {\n      VPrintf(2, \"ThreadSanitizer: matched suppression '%s'\\n\", s->templ);\n      atomic_fetch_add(&s->hit_count, 1, memory_order_relaxed);\n      *sp = s;\n      return global.start;\n  }\n  return 0;\n}\n\nvoid PrintMatchedSuppressions() {\n  InternalMmapVector<Suppression *> matched(1);\n  CHECK(suppression_ctx);\n  suppression_ctx->GetMatched(&matched);\n  if (!matched.size())\n    return;\n  int hit_count = 0;\n  for (uptr i = 0; i < matched.size(); i++)\n    hit_count += atomic_load_relaxed(&matched[i]->hit_count);\n  Printf(\"ThreadSanitizer: Matched %d suppressions (pid=%d):\\n\", hit_count,\n         (int)internal_getpid());\n  for (uptr i = 0; i < matched.size(); i++) {\n    Printf(\"%d %s:%s\\n\", matched[i]->hit_count, matched[i]->type,\n           matched[i]->templ);\n  }\n}\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_suppressions.h",
    "content": "//===-- tsan_suppressions.h -------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_SUPPRESSIONS_H\n#define TSAN_SUPPRESSIONS_H\n\n#include \"sanitizer_common/sanitizer_suppressions.h\"\n#include \"tsan_report.h\"\n\nnamespace __tsan {\n\nconst char kSuppressionNone[] = \"none\";\nconst char kSuppressionRace[] = \"race\";\nconst char kSuppressionRaceTop[] = \"race_top\";\nconst char kSuppressionMutex[] = \"mutex\";\nconst char kSuppressionThread[] = \"thread\";\nconst char kSuppressionSignal[] = \"signal\";\nconst char kSuppressionLib[] = \"called_from_lib\";\nconst char kSuppressionDeadlock[] = \"deadlock\";\n\nvoid InitializeSuppressions();\nSuppressionContext *Suppressions();\nvoid PrintMatchedSuppressions();\nuptr IsSuppressed(ReportType typ, const ReportStack *stack, Suppression **sp);\nuptr IsSuppressed(ReportType typ, const ReportLocation *loc, Suppression **sp);\n\n}  // namespace __tsan\n\n#endif  // TSAN_SUPPRESSIONS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_symbolize.cc",
    "content": "//===-- tsan_symbolize.cc -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"tsan_symbolize.h\"\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_symbolizer.h\"\n#include \"tsan_flags.h\"\n#include \"tsan_report.h\"\n#include \"tsan_rtl.h\"\n\nnamespace __tsan {\n\nvoid EnterSymbolizer() {\n  ThreadState *thr = cur_thread();\n  CHECK(!thr->in_symbolizer);\n  thr->in_symbolizer = true;\n  thr->ignore_interceptors++;\n}\n\nvoid ExitSymbolizer() {\n  ThreadState *thr = cur_thread();\n  CHECK(thr->in_symbolizer);\n  thr->in_symbolizer = false;\n  thr->ignore_interceptors--;\n}\n\n// May be overriden by JIT/JAVA/etc,\n// whatever produces PCs marked with kExternalPCBit.\nSANITIZER_WEAK_DEFAULT_IMPL\nbool __tsan_symbolize_external(uptr pc, char *func_buf, uptr func_siz,\n                               char *file_buf, uptr file_siz, int *line,\n                               int *col) {\n  return false;\n}\n\nSymbolizedStack *SymbolizeCode(uptr addr) {\n  // Check if PC comes from non-native land.\n  if (addr & kExternalPCBit) {\n    // Declare static to not consume too much stack space.\n    // We symbolize reports in a single thread, so this is fine.\n    static char func_buf[1024];\n    static char file_buf[1024];\n    int line, col;\n    SymbolizedStack *frame = SymbolizedStack::New(addr);\n    if (__tsan_symbolize_external(addr, func_buf, sizeof(func_buf), file_buf,\n                                  sizeof(file_buf), &line, &col)) {\n      frame->info.function = internal_strdup(func_buf);\n      frame->info.file = internal_strdup(file_buf);\n      frame->info.line = line;\n      frame->info.column = col;\n    }\n    return frame;\n  }\n  return Symbolizer::GetOrInit()->SymbolizePC(addr);\n}\n\nReportLocation *SymbolizeData(uptr addr) {\n  DataInfo info;\n  if (!Symbolizer::GetOrInit()->SymbolizeData(addr, &info))\n    return 0;\n  ReportLocation *ent = ReportLocation::New(ReportLocationGlobal);\n  internal_memcpy(&ent->global, &info, sizeof(info));\n  return ent;\n}\n\nvoid SymbolizeFlush() {\n  Symbolizer::GetOrInit()->Flush();\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_symbolize.h",
    "content": "//===-- tsan_symbolize.h ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_SYMBOLIZE_H\n#define TSAN_SYMBOLIZE_H\n\n#include \"tsan_defs.h\"\n#include \"tsan_report.h\"\n\nnamespace __tsan {\n\nvoid EnterSymbolizer();\nvoid ExitSymbolizer();\nSymbolizedStack *SymbolizeCode(uptr addr);\nReportLocation *SymbolizeData(uptr addr);\nvoid SymbolizeFlush();\n\nReportStack *NewReportStackEntry(uptr addr);\n\n}  // namespace __tsan\n\n#endif  // TSAN_SYMBOLIZE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_sync.cc",
    "content": "//===-- tsan_sync.cc ------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"tsan_sync.h\"\n#include \"tsan_rtl.h\"\n#include \"tsan_mman.h\"\n\nnamespace __tsan {\n\nvoid DDMutexInit(ThreadState *thr, uptr pc, SyncVar *s);\n\nSyncVar::SyncVar()\n    : mtx(MutexTypeSyncVar, StatMtxSyncVar) {\n  Reset(0);\n}\n\nvoid SyncVar::Init(ThreadState *thr, uptr pc, uptr addr, u64 uid) {\n  this->addr = addr;\n  this->uid = uid;\n  this->next = 0;\n\n  creation_stack_id = 0;\n  if (kCppMode)  // Go does not use them\n    creation_stack_id = CurrentStackId(thr, pc);\n  if (common_flags()->detect_deadlocks)\n    DDMutexInit(thr, pc, this);\n}\n\nvoid SyncVar::Reset(ThreadState *thr) {\n  uid = 0;\n  creation_stack_id = 0;\n  owner_tid = kInvalidTid;\n  last_lock = 0;\n  recursion = 0;\n  is_rw = 0;\n  is_recursive = 0;\n  is_broken = 0;\n  is_linker_init = 0;\n\n  if (thr == 0) {\n    CHECK_EQ(clock.size(), 0);\n    CHECK_EQ(read_clock.size(), 0);\n  } else {\n    clock.Reset(&thr->clock_cache);\n    read_clock.Reset(&thr->clock_cache);\n  }\n}\n\nMetaMap::MetaMap() {\n  atomic_store(&uid_gen_, 0, memory_order_relaxed);\n}\n\nvoid MetaMap::AllocBlock(ThreadState *thr, uptr pc, uptr p, uptr sz) {\n  u32 idx = block_alloc_.Alloc(&thr->block_cache);\n  MBlock *b = block_alloc_.Map(idx);\n  b->siz = sz;\n  b->tid = thr->tid;\n  b->stk = CurrentStackId(thr, pc);\n  u32 *meta = MemToMeta(p);\n  DCHECK_EQ(*meta, 0);\n  *meta = idx | kFlagBlock;\n}\n\nuptr MetaMap::FreeBlock(ThreadState *thr, uptr pc, uptr p) {\n  MBlock* b = GetBlock(p);\n  if (b == 0)\n    return 0;\n  uptr sz = RoundUpTo(b->siz, kMetaShadowCell);\n  FreeRange(thr, pc, p, sz);\n  return sz;\n}\n\nbool MetaMap::FreeRange(ThreadState *thr, uptr pc, uptr p, uptr sz) {\n  bool has_something = false;\n  u32 *meta = MemToMeta(p);\n  u32 *end = MemToMeta(p + sz);\n  if (end == meta)\n    end++;\n  for (; meta < end; meta++) {\n    u32 idx = *meta;\n    if (idx == 0) {\n      // Note: don't write to meta in this case -- the block can be huge.\n      continue;\n    }\n    *meta = 0;\n    has_something = true;\n    while (idx != 0) {\n      if (idx & kFlagBlock) {\n        block_alloc_.Free(&thr->block_cache, idx & ~kFlagMask);\n        break;\n      } else if (idx & kFlagSync) {\n        DCHECK(idx & kFlagSync);\n        SyncVar *s = sync_alloc_.Map(idx & ~kFlagMask);\n        u32 next = s->next;\n        s->Reset(thr);\n        sync_alloc_.Free(&thr->sync_cache, idx & ~kFlagMask);\n        idx = next;\n      } else {\n        CHECK(0);\n      }\n    }\n  }\n  return has_something;\n}\n\n// ResetRange removes all meta objects from the range.\n// It is called for large mmap-ed regions. The function is best-effort wrt\n// freeing of meta objects, because we don't want to page in the whole range\n// which can be huge. The function probes pages one-by-one until it finds a page\n// without meta objects, at this point it stops freeing meta objects. Because\n// thread stacks grow top-down, we do the same starting from end as well.\nvoid MetaMap::ResetRange(ThreadState *thr, uptr pc, uptr p, uptr sz) {\n  const uptr kMetaRatio = kMetaShadowCell / kMetaShadowSize;\n  const uptr kPageSize = GetPageSizeCached() * kMetaRatio;\n  if (sz <= 4 * kPageSize) {\n    // If the range is small, just do the normal free procedure.\n    FreeRange(thr, pc, p, sz);\n    return;\n  }\n  // First, round both ends of the range to page size.\n  uptr diff = RoundUp(p, kPageSize) - p;\n  if (diff != 0) {\n    FreeRange(thr, pc, p, diff);\n    p += diff;\n    sz -= diff;\n  }\n  diff = p + sz - RoundDown(p + sz, kPageSize);\n  if (diff != 0) {\n    FreeRange(thr, pc, p + sz - diff, diff);\n    sz -= diff;\n  }\n  // Now we must have a non-empty page-aligned range.\n  CHECK_GT(sz, 0);\n  CHECK_EQ(p, RoundUp(p, kPageSize));\n  CHECK_EQ(sz, RoundUp(sz, kPageSize));\n  const uptr p0 = p;\n  const uptr sz0 = sz;\n  // Probe start of the range.\n  while (sz > 0) {\n    bool has_something = FreeRange(thr, pc, p, kPageSize);\n    p += kPageSize;\n    sz -= kPageSize;\n    if (!has_something)\n      break;\n  }\n  // Probe end of the range.\n  while (sz > 0) {\n    bool has_something = FreeRange(thr, pc, p - kPageSize, kPageSize);\n    sz -= kPageSize;\n    if (!has_something)\n      break;\n  }\n  // Finally, page out the whole range (including the parts that we've just\n  // freed). Note: we can't simply madvise, because we need to leave a zeroed\n  // range (otherwise __tsan_java_move can crash if it encounters a left-over\n  // meta objects in java heap).\n  uptr metap = (uptr)MemToMeta(p0);\n  uptr metasz = sz0 / kMetaRatio;\n  UnmapOrDie((void*)metap, metasz);\n  MmapFixedNoReserve(metap, metasz);\n}\n\nMBlock* MetaMap::GetBlock(uptr p) {\n  u32 *meta = MemToMeta(p);\n  u32 idx = *meta;\n  for (;;) {\n    if (idx == 0)\n      return 0;\n    if (idx & kFlagBlock)\n      return block_alloc_.Map(idx & ~kFlagMask);\n    DCHECK(idx & kFlagSync);\n    SyncVar * s = sync_alloc_.Map(idx & ~kFlagMask);\n    idx = s->next;\n  }\n}\n\nSyncVar* MetaMap::GetOrCreateAndLock(ThreadState *thr, uptr pc,\n                              uptr addr, bool write_lock) {\n  return GetAndLock(thr, pc, addr, write_lock, true);\n}\n\nSyncVar* MetaMap::GetIfExistsAndLock(uptr addr) {\n  return GetAndLock(0, 0, addr, true, false);\n}\n\nSyncVar* MetaMap::GetAndLock(ThreadState *thr, uptr pc,\n                             uptr addr, bool write_lock, bool create) {\n  u32 *meta = MemToMeta(addr);\n  u32 idx0 = *meta;\n  u32 myidx = 0;\n  SyncVar *mys = 0;\n  for (;;) {\n    u32 idx = idx0;\n    for (;;) {\n      if (idx == 0)\n        break;\n      if (idx & kFlagBlock)\n        break;\n      DCHECK(idx & kFlagSync);\n      SyncVar * s = sync_alloc_.Map(idx & ~kFlagMask);\n      if (s->addr == addr) {\n        if (myidx != 0) {\n          mys->Reset(thr);\n          sync_alloc_.Free(&thr->sync_cache, myidx);\n        }\n        if (write_lock)\n          s->mtx.Lock();\n        else\n          s->mtx.ReadLock();\n        return s;\n      }\n      idx = s->next;\n    }\n    if (!create)\n      return 0;\n    if (*meta != idx0) {\n      idx0 = *meta;\n      continue;\n    }\n\n    if (myidx == 0) {\n      const u64 uid = atomic_fetch_add(&uid_gen_, 1, memory_order_relaxed);\n      myidx = sync_alloc_.Alloc(&thr->sync_cache);\n      mys = sync_alloc_.Map(myidx);\n      mys->Init(thr, pc, addr, uid);\n    }\n    mys->next = idx0;\n    if (atomic_compare_exchange_strong((atomic_uint32_t*)meta, &idx0,\n        myidx | kFlagSync, memory_order_release)) {\n      if (write_lock)\n        mys->mtx.Lock();\n      else\n        mys->mtx.ReadLock();\n      return mys;\n    }\n  }\n}\n\nvoid MetaMap::MoveMemory(uptr src, uptr dst, uptr sz) {\n  // src and dst can overlap,\n  // there are no concurrent accesses to the regions (e.g. stop-the-world).\n  CHECK_NE(src, dst);\n  CHECK_NE(sz, 0);\n  uptr diff = dst - src;\n  u32 *src_meta = MemToMeta(src);\n  u32 *dst_meta = MemToMeta(dst);\n  u32 *src_meta_end = MemToMeta(src + sz);\n  uptr inc = 1;\n  if (dst > src) {\n    src_meta = MemToMeta(src + sz) - 1;\n    dst_meta = MemToMeta(dst + sz) - 1;\n    src_meta_end = MemToMeta(src) - 1;\n    inc = -1;\n  }\n  for (; src_meta != src_meta_end; src_meta += inc, dst_meta += inc) {\n    CHECK_EQ(*dst_meta, 0);\n    u32 idx = *src_meta;\n    *src_meta = 0;\n    *dst_meta = idx;\n    // Patch the addresses in sync objects.\n    while (idx != 0) {\n      if (idx & kFlagBlock)\n        break;\n      CHECK(idx & kFlagSync);\n      SyncVar *s = sync_alloc_.Map(idx & ~kFlagMask);\n      s->addr += diff;\n      idx = s->next;\n    }\n  }\n}\n\nvoid MetaMap::OnThreadIdle(ThreadState *thr) {\n  block_alloc_.FlushCache(&thr->block_cache);\n  sync_alloc_.FlushCache(&thr->sync_cache);\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_sync.h",
    "content": "//===-- tsan_sync.h ---------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_SYNC_H\n#define TSAN_SYNC_H\n\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_deadlock_detector_interface.h\"\n#include \"tsan_defs.h\"\n#include \"tsan_clock.h\"\n#include \"tsan_mutex.h\"\n#include \"tsan_dense_alloc.h\"\n\nnamespace __tsan {\n\nstruct SyncVar {\n  SyncVar();\n\n  static const int kInvalidTid = -1;\n\n  uptr addr;  // overwritten by DenseSlabAlloc freelist\n  Mutex mtx;\n  u64 uid;  // Globally unique id.\n  u32 creation_stack_id;\n  int owner_tid;  // Set only by exclusive owners.\n  u64 last_lock;\n  int recursion;\n  bool is_rw;\n  bool is_recursive;\n  bool is_broken;\n  bool is_linker_init;\n  u32 next;  // in MetaMap\n  DDMutex dd;\n  SyncClock read_clock;  // Used for rw mutexes only.\n  // The clock is placed last, so that it is situated on a different cache line\n  // with the mtx. This reduces contention for hot sync objects.\n  SyncClock clock;\n\n  void Init(ThreadState *thr, uptr pc, uptr addr, u64 uid);\n  void Reset(ThreadState *thr);\n\n  u64 GetId() const {\n    // 47 lsb is addr, then 14 bits is low part of uid, then 3 zero bits.\n    return GetLsb((u64)addr | (uid << 47), 61);\n  }\n  bool CheckId(u64 uid) const {\n    CHECK_EQ(uid, GetLsb(uid, 14));\n    return GetLsb(this->uid, 14) == uid;\n  }\n  static uptr SplitId(u64 id, u64 *uid) {\n    *uid = id >> 47;\n    return (uptr)GetLsb(id, 47);\n  }\n};\n\n/* MetaMap allows to map arbitrary user pointers onto various descriptors.\n   Currently it maps pointers to heap block descriptors and sync var descs.\n   It uses 1/2 direct shadow, see tsan_platform.h.\n*/\nclass MetaMap {\n public:\n  MetaMap();\n\n  void AllocBlock(ThreadState *thr, uptr pc, uptr p, uptr sz);\n  uptr FreeBlock(ThreadState *thr, uptr pc, uptr p);\n  bool FreeRange(ThreadState *thr, uptr pc, uptr p, uptr sz);\n  void ResetRange(ThreadState *thr, uptr pc, uptr p, uptr sz);\n  MBlock* GetBlock(uptr p);\n\n  SyncVar* GetOrCreateAndLock(ThreadState *thr, uptr pc,\n                              uptr addr, bool write_lock);\n  SyncVar* GetIfExistsAndLock(uptr addr);\n\n  void MoveMemory(uptr src, uptr dst, uptr sz);\n\n  void OnThreadIdle(ThreadState *thr);\n\n private:\n  static const u32 kFlagMask  = 3u << 30;\n  static const u32 kFlagBlock = 1u << 30;\n  static const u32 kFlagSync  = 2u << 30;\n  typedef DenseSlabAlloc<MBlock, 1<<16, 1<<12> BlockAlloc;\n  typedef DenseSlabAlloc<SyncVar, 1<<16, 1<<10> SyncAlloc;\n  BlockAlloc block_alloc_;\n  SyncAlloc sync_alloc_;\n  atomic_uint64_t uid_gen_;\n\n  SyncVar* GetAndLock(ThreadState *thr, uptr pc, uptr addr, bool write_lock,\n                      bool create);\n};\n\n}  // namespace __tsan\n\n#endif  // TSAN_SYNC_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_trace.h",
    "content": "//===-- tsan_trace.h --------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_TRACE_H\n#define TSAN_TRACE_H\n\n#include \"tsan_defs.h\"\n#include \"tsan_mutex.h\"\n#include \"tsan_stack_trace.h\"\n#include \"tsan_mutexset.h\"\n\nnamespace __tsan {\n\nconst int kTracePartSizeBits = 13;\nconst int kTracePartSize = 1 << kTracePartSizeBits;\nconst int kTraceParts = 2 * 1024 * 1024 / kTracePartSize;\nconst int kTraceSize = kTracePartSize * kTraceParts;\n\n// Must fit into 3 bits.\nenum EventType {\n  EventTypeMop,\n  EventTypeFuncEnter,\n  EventTypeFuncExit,\n  EventTypeLock,\n  EventTypeUnlock,\n  EventTypeRLock,\n  EventTypeRUnlock\n};\n\n// Represents a thread event (from most significant bit):\n// u64 typ  : 3;   // EventType.\n// u64 addr : 61;  // Associated pc.\ntypedef u64 Event;\n\nstruct TraceHeader {\n#ifndef SANITIZER_GO\n  BufferedStackTrace stack0;  // Start stack for the trace.\n#else\n  VarSizeStackTrace stack0;\n#endif\n  u64        epoch0;  // Start epoch for the trace.\n  MutexSet   mset0;\n\n  TraceHeader() : stack0(), epoch0() {}\n};\n\nstruct Trace {\n  Mutex mtx;\n#ifndef SANITIZER_GO\n  // Must be last to catch overflow as paging fault.\n  // Go shadow stack is dynamically allocated.\n  uptr shadow_stack[kShadowStackSize];\n#endif\n  // Must be the last field, because we unmap the unused part in\n  // CreateThreadContext.\n  TraceHeader headers[kTraceParts];\n\n  Trace()\n    : mtx(MutexTypeTrace, StatMtxTrace) {\n  }\n};\n\n}  // namespace __tsan\n\n#endif  // TSAN_TRACE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_update_shadow_word_inl.h",
    "content": "//===-- tsan_update_shadow_word_inl.h ---------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Body of the hottest inner loop.\n// If we wrap this body into a function, compilers (both gcc and clang)\n// produce sligtly less efficient code.\n//===----------------------------------------------------------------------===//\ndo {\n  StatInc(thr, StatShadowProcessed);\n  const unsigned kAccessSize = 1 << kAccessSizeLog;\n  u64 *sp = &shadow_mem[idx];\n  old = LoadShadow(sp);\n  if (old.IsZero()) {\n    StatInc(thr, StatShadowZero);\n    if (store_word)\n      StoreIfNotYetStored(sp, &store_word);\n    // The above StoreIfNotYetStored could be done unconditionally\n    // and it even shows 4% gain on synthetic benchmarks (r4307).\n    break;\n  }\n  // is the memory access equal to the previous?\n  if (Shadow::Addr0AndSizeAreEqual(cur, old)) {\n    StatInc(thr, StatShadowSameSize);\n    // same thread?\n    if (Shadow::TidsAreEqual(old, cur)) {\n      StatInc(thr, StatShadowSameThread);\n      if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))\n        StoreIfNotYetStored(sp, &store_word);\n      break;\n    }\n    StatInc(thr, StatShadowAnotherThread);\n    if (HappensBefore(old, thr)) {\n      if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))\n        StoreIfNotYetStored(sp, &store_word);\n      break;\n    }\n    if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic))\n      break;\n    goto RACE;\n  }\n  // Do the memory access intersect?\n  if (Shadow::TwoRangesIntersect(old, cur, kAccessSize)) {\n    StatInc(thr, StatShadowIntersect);\n    if (Shadow::TidsAreEqual(old, cur)) {\n      StatInc(thr, StatShadowSameThread);\n      break;\n    }\n    StatInc(thr, StatShadowAnotherThread);\n    if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic))\n      break;\n    if (HappensBefore(old, thr))\n      break;\n    goto RACE;\n  }\n  // The accesses do not intersect.\n  StatInc(thr, StatShadowNotIntersect);\n  break;\n} while (0);\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/rtl/tsan_vector.h",
    "content": "//===-- tsan_vector.h -------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n\n// Low-fat STL-like vector container.\n\n#ifndef TSAN_VECTOR_H\n#define TSAN_VECTOR_H\n\n#include \"tsan_defs.h\"\n#include \"tsan_mman.h\"\n\nnamespace __tsan {\n\ntemplate<typename T>\nclass Vector {\n public:\n  explicit Vector(MBlockType typ)\n      : typ_(typ)\n      , begin_()\n      , end_()\n      , last_() {\n  }\n\n  ~Vector() {\n    if (begin_)\n      internal_free(begin_);\n  }\n\n  void Reset() {\n    if (begin_)\n      internal_free(begin_);\n    begin_ = 0;\n    end_ = 0;\n    last_ = 0;\n  }\n\n  uptr Size() const {\n    return end_ - begin_;\n  }\n\n  T &operator[](uptr i) {\n    DCHECK_LT(i, end_ - begin_);\n    return begin_[i];\n  }\n\n  const T &operator[](uptr i) const {\n    DCHECK_LT(i, end_ - begin_);\n    return begin_[i];\n  }\n\n  T *PushBack() {\n    EnsureSize(Size() + 1);\n    T *p = &end_[-1];\n    internal_memset(p, 0, sizeof(*p));\n    return p;\n  }\n\n  T *PushBack(const T& v) {\n    EnsureSize(Size() + 1);\n    T *p = &end_[-1];\n    internal_memcpy(p, &v, sizeof(*p));\n    return p;\n  }\n\n  void PopBack() {\n    DCHECK_GT(end_, begin_);\n    end_--;\n  }\n\n  void Resize(uptr size) {\n    if (size == 0) {\n      end_ = begin_;\n      return;\n    }\n    uptr old_size = Size();\n    EnsureSize(size);\n    if (old_size < size) {\n      for (uptr i = old_size; i < size; i++)\n        internal_memset(&begin_[i], 0, sizeof(begin_[i]));\n    }\n  }\n\n private:\n  const MBlockType typ_;\n  T *begin_;\n  T *end_;\n  T *last_;\n\n  void EnsureSize(uptr size) {\n    if (size <= Size())\n      return;\n    if (size <= (uptr)(last_ - begin_)) {\n      end_ = begin_ + size;\n      return;\n    }\n    uptr cap0 = last_ - begin_;\n    uptr cap = cap0 * 5 / 4;  // 25% growth\n    if (cap == 0)\n      cap = 16;\n    if (cap < size)\n      cap = size;\n    T *p = (T*)internal_alloc(typ_, cap * sizeof(T));\n    if (cap0) {\n      internal_memcpy(p, begin_, cap0 * sizeof(T));\n      internal_free(begin_);\n    }\n    begin_ = p;\n    end_ = begin_ + size;\n    last_ = begin_ + cap;\n  }\n\n  Vector(const Vector&);\n  void operator=(const Vector&);\n};\n}  // namespace __tsan\n\n#endif  // #ifndef TSAN_VECTOR_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/CMakeLists.txt",
    "content": "include_directories(../rtl)\n\nadd_custom_target(TsanUnitTests)\nset_target_properties(TsanUnitTests PROPERTIES\n  FOLDER \"TSan unittests\")\n\nset(TSAN_UNITTEST_CFLAGS\n  ${TSAN_CFLAGS}\n  ${COMPILER_RT_TEST_CFLAGS}\n  ${COMPILER_RT_GTEST_CFLAGS}\n  -I${COMPILER_RT_SOURCE_DIR}/lib\n  -I${COMPILER_RT_SOURCE_DIR}/lib/tsan/rtl\n  -DGTEST_HAS_RTTI=0)\n\nset(TSAN_RTL_HEADERS)\nforeach (header ${TSAN_HEADERS})\n  list(APPEND TSAN_RTL_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../${header})\nendforeach()\n\n# tsan_compile(obj_list, source, arch, {headers})\nmacro(tsan_compile obj_list source arch)\n  get_filename_component(basename ${source} NAME)\n  set(output_obj \"${basename}.${arch}.o\")\n  get_target_flags_for_arch(${arch} TARGET_CFLAGS)\n  set(COMPILE_DEPS ${TSAN_RTL_HEADERS} ${ARGN})\n  if(NOT COMPILER_RT_STANDALONE_BUILD)\n    list(APPEND COMPILE_DEPS gtest tsan)\n  endif()\n  clang_compile(${output_obj} ${source}\n          CFLAGS ${TSAN_UNITTEST_CFLAGS} ${TARGET_CFLAGS}\n          DEPS ${COMPILE_DEPS})\n  list(APPEND ${obj_list} ${output_obj})\nendmacro()\n\nmacro(add_tsan_unittest testname)\n  # Build unit tests only for 64-bit Linux.\n  if(UNIX AND NOT APPLE)\n    foreach(arch ${TSAN_SUPPORTED_ARCH})\n      parse_arguments(TEST \"SOURCES;HEADERS\" \"\" ${ARGN})\n      set(TEST_OBJECTS)\n      foreach(SOURCE ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE})\n        tsan_compile(TEST_OBJECTS ${SOURCE} ${arch} ${TEST_HEADERS})\n      endforeach()\n      get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)\n      set(TEST_DEPS ${TEST_OBJECTS})\n      if(NOT COMPILER_RT_STANDALONE_BUILD)\n        list(APPEND TEST_DEPS tsan)\n      endif()\n      # FIXME: Looks like we should link TSan with just-built runtime,\n      # and not rely on -fsanitize=thread, as these tests are essentially\n      # unit tests.\n      add_compiler_rt_test(TsanUnitTests ${testname}\n              OBJECTS ${TEST_OBJECTS}\n              DEPS ${TEST_DEPS}\n              LINK_FLAGS ${TARGET_LINK_FLAGS}\n                         -fsanitize=thread\n                         -lstdc++ -lm)\n    endforeach()\n  endif()\nendmacro()\n\nif(COMPILER_RT_CAN_EXECUTE_TESTS)\n  add_subdirectory(rtl)\n  add_subdirectory(unit)\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/rtl/CMakeLists.txt",
    "content": "set(TSAN_RTL_TEST_SOURCES\n  tsan_bench.cc\n  tsan_mop.cc\n  tsan_mutex.cc\n  tsan_posix.cc\n  tsan_string.cc\n  tsan_test.cc\n  tsan_thread.cc)\n\nif(UNIX AND NOT APPLE)\n  list(APPEND TSAN_RTL_TEST_SOURCES tsan_test_util_linux.cc)\nendif()\n\nset(TSAN_RTL_TEST_HEADERS\n  tsan_test_util.h)\n\nadd_tsan_unittest(TsanRtlTest\n  SOURCES ${TSAN_RTL_TEST_SOURCES}\n  HEADERS ${TSAN_RTL_TEST_HEADERS})\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/rtl/tsan_bench.cc",
    "content": "//===-- tsan_bench.cc -----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_test_util.h\"\n#include \"tsan_interface.h\"\n#include \"tsan_defs.h\"\n#include \"gtest/gtest.h\"\n#include <stdint.h>\n\nconst int kSize = 128;\nconst int kRepeat = 2*1024*1024;\n\nvoid noinstr(void *p) {}\n\ntemplate<typename T, void(*__tsan_mop)(void *p)>\nstatic void Benchmark() {\n  volatile T data[kSize];\n  for (int i = 0; i < kRepeat; i++) {\n    for (int j = 0; j < kSize; j++) {\n      __tsan_mop((void*)&data[j]);\n      data[j]++;\n    }\n  }\n}\n\nTEST(DISABLED_BENCH, Mop1) {\n  Benchmark<uint8_t, noinstr>();\n}\n\nTEST(DISABLED_BENCH, Mop1Read) {\n  Benchmark<uint8_t, __tsan_read1>();\n}\n\nTEST(DISABLED_BENCH, Mop1Write) {\n  Benchmark<uint8_t, __tsan_write1>();\n}\n\nTEST(DISABLED_BENCH, Mop2) {\n  Benchmark<uint16_t, noinstr>();\n}\n\nTEST(DISABLED_BENCH, Mop2Read) {\n  Benchmark<uint16_t, __tsan_read2>();\n}\n\nTEST(DISABLED_BENCH, Mop2Write) {\n  Benchmark<uint16_t, __tsan_write2>();\n}\n\nTEST(DISABLED_BENCH, Mop4) {\n  Benchmark<uint32_t, noinstr>();\n}\n\nTEST(DISABLED_BENCH, Mop4Read) {\n  Benchmark<uint32_t, __tsan_read4>();\n}\n\nTEST(DISABLED_BENCH, Mop4Write) {\n  Benchmark<uint32_t, __tsan_write4>();\n}\n\nTEST(DISABLED_BENCH, Mop8) {\n  Benchmark<uint8_t, noinstr>();\n}\n\nTEST(DISABLED_BENCH, Mop8Read) {\n  Benchmark<uint64_t, __tsan_read8>();\n}\n\nTEST(DISABLED_BENCH, Mop8Write) {\n  Benchmark<uint64_t, __tsan_write8>();\n}\n\nTEST(DISABLED_BENCH, FuncCall) {\n  for (int i = 0; i < kRepeat; i++) {\n    for (int j = 0; j < kSize; j++)\n      __tsan_func_entry((void*)(uintptr_t)j);\n    for (int j = 0; j < kSize; j++)\n      __tsan_func_exit();\n  }\n}\n\nTEST(DISABLED_BENCH, MutexLocal) {\n  Mutex m;\n  ScopedThread().Create(m);\n  for (int i = 0; i < 50; i++) {\n    ScopedThread t;\n    t.Lock(m);\n    t.Unlock(m);\n  }\n  for (int i = 0; i < 16*1024*1024; i++) {\n    m.Lock();\n    m.Unlock();\n  }\n  ScopedThread().Destroy(m);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/rtl/tsan_mop.cc",
    "content": "//===-- tsan_mop.cc -------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_interface.h\"\n#include \"tsan_test_util.h\"\n#include \"gtest/gtest.h\"\n#include <stddef.h>\n#include <stdint.h>\n\nTEST(ThreadSanitizer, SimpleWrite) {\n  ScopedThread t;\n  MemLoc l;\n  t.Write1(l);\n}\n\nTEST(ThreadSanitizer, SimpleWriteWrite) {\n  ScopedThread t1, t2;\n  MemLoc l1, l2;\n  t1.Write1(l1);\n  t2.Write1(l2);\n}\n\nTEST(ThreadSanitizer, WriteWriteRace) {\n  ScopedThread t1, t2;\n  MemLoc l;\n  t1.Write1(l);\n  t2.Write1(l, true);\n}\n\nTEST(ThreadSanitizer, ReadWriteRace) {\n  ScopedThread t1, t2;\n  MemLoc l;\n  t1.Read1(l);\n  t2.Write1(l, true);\n}\n\nTEST(ThreadSanitizer, WriteReadRace) {\n  ScopedThread t1, t2;\n  MemLoc l;\n  t1.Write1(l);\n  t2.Read1(l, true);\n}\n\nTEST(ThreadSanitizer, ReadReadNoRace) {\n  ScopedThread t1, t2;\n  MemLoc l;\n  t1.Read1(l);\n  t2.Read1(l);\n}\n\nTEST(ThreadSanitizer, WriteThenRead) {\n  MemLoc l;\n  ScopedThread t1, t2;\n  t1.Write1(l);\n  t1.Read1(l);\n  t2.Read1(l, true);\n}\n\nTEST(ThreadSanitizer, WriteThenLockedRead) {\n  Mutex m(Mutex::RW);\n  MainThread t0;\n  t0.Create(m);\n  MemLoc l;\n  {\n    ScopedThread t1, t2;\n\n    t1.Write8(l);\n\n    t1.Lock(m);\n    t1.Read8(l);\n    t1.Unlock(m);\n\n    t2.Read8(l, true);\n  }\n  t0.Destroy(m);\n}\n\nTEST(ThreadSanitizer, LockedWriteThenRead) {\n  Mutex m(Mutex::RW);\n  MainThread t0;\n  t0.Create(m);\n  MemLoc l;\n  {\n    ScopedThread t1, t2;\n\n    t1.Lock(m);\n    t1.Write8(l);\n    t1.Unlock(m);\n\n    t1.Read8(l);\n\n    t2.Read8(l, true);\n  }\n  t0.Destroy(m);\n}\n\n\nTEST(ThreadSanitizer, RaceWithOffset) {\n  ScopedThread t1, t2;\n  {\n    MemLoc l;\n    t1.Access(l.loc(), true, 8, false);\n    t2.Access((char*)l.loc() + 4, true, 4, true);\n  }\n  {\n    MemLoc l;\n    t1.Access(l.loc(), true, 8, false);\n    t2.Access((char*)l.loc() + 7, true, 1, true);\n  }\n  {\n    MemLoc l;\n    t1.Access((char*)l.loc() + 4, true, 4, false);\n    t2.Access((char*)l.loc() + 4, true, 2, true);\n  }\n  {\n    MemLoc l;\n    t1.Access((char*)l.loc() + 4, true, 4, false);\n    t2.Access((char*)l.loc() + 6, true, 2, true);\n  }\n  {\n    MemLoc l;\n    t1.Access((char*)l.loc() + 3, true, 2, false);\n    t2.Access((char*)l.loc() + 4, true, 1, true);\n  }\n  {\n    MemLoc l;\n    t1.Access((char*)l.loc() + 1, true, 8, false);\n    t2.Access((char*)l.loc() + 3, true, 1, true);\n  }\n}\n\nTEST(ThreadSanitizer, RaceWithOffset2) {\n  ScopedThread t1, t2;\n  {\n    MemLoc l;\n    t1.Access((char*)l.loc(), true, 4, false);\n    t2.Access((char*)l.loc() + 2, true, 1, true);\n  }\n  {\n    MemLoc l;\n    t1.Access((char*)l.loc() + 2, true, 1, false);\n    t2.Access((char*)l.loc(), true, 4, true);\n  }\n}\n\nTEST(ThreadSanitizer, NoRaceWithOffset) {\n  ScopedThread t1, t2;\n  {\n    MemLoc l;\n    t1.Access(l.loc(), true, 4, false);\n    t2.Access((char*)l.loc() + 4, true, 4, false);\n  }\n  {\n    MemLoc l;\n    t1.Access((char*)l.loc() + 3, true, 2, false);\n    t2.Access((char*)l.loc() + 1, true, 2, false);\n    t2.Access((char*)l.loc() + 5, true, 2, false);\n  }\n}\n\nTEST(ThreadSanitizer, RaceWithDeadThread) {\n  MemLoc l;\n  ScopedThread t;\n  ScopedThread().Write1(l);\n  t.Write1(l, true);\n}\n\nTEST(ThreadSanitizer, BenignRaceOnVptr) {\n  void *vptr_storage;\n  MemLoc vptr(&vptr_storage), val;\n  vptr_storage = val.loc();\n  ScopedThread t1, t2;\n  t1.VptrUpdate(vptr, val);\n  t2.Read8(vptr);\n}\n\nTEST(ThreadSanitizer, HarmfulRaceOnVptr) {\n  void *vptr_storage;\n  MemLoc vptr(&vptr_storage), val1, val2;\n  vptr_storage = val1.loc();\n  ScopedThread t1, t2;\n  t1.VptrUpdate(vptr, val2);\n  t2.Read8(vptr, true);\n}\n\nstatic void foo() {\n  volatile int x = 42;\n  int x2 = x;\n  (void)x2;\n}\n\nstatic void bar() {\n  volatile int x = 43;\n  int x2 = x;\n  (void)x2;\n}\n\nTEST(ThreadSanitizer, ReportDeadThread) {\n  MemLoc l;\n  ScopedThread t1;\n  {\n    ScopedThread t2;\n    t2.Call(&foo);\n    t2.Call(&bar);\n    t2.Write1(l);\n  }\n  t1.Write1(l, true);\n}\n\nstruct ClassWithStatic {\n  static int Data[4];\n};\n\nint ClassWithStatic::Data[4];\n\nstatic void foobarbaz() {}\n\nTEST(ThreadSanitizer, ReportRace) {\n  ScopedThread t1;\n  MainThread().Access(&ClassWithStatic::Data, true, 4, false);\n  t1.Call(&foobarbaz);\n  t1.Access(&ClassWithStatic::Data, true, 2, true);\n  t1.Return();\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/rtl/tsan_mutex.cc",
    "content": "//===-- tsan_mutex.cc -----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"tsan_interface.h\"\n#include \"tsan_interface_ann.h\"\n#include \"tsan_test_util.h\"\n#include \"gtest/gtest.h\"\n#include <stdint.h>\n\nnamespace __tsan {\n\nTEST(ThreadSanitizer, BasicMutex) {\n  ScopedThread t;\n  Mutex m;\n  t.Create(m);\n\n  t.Lock(m);\n  t.Unlock(m);\n\n  CHECK(t.TryLock(m));\n  t.Unlock(m);\n\n  t.Lock(m);\n  CHECK(!t.TryLock(m));\n  t.Unlock(m);\n\n  t.Destroy(m);\n}\n\nTEST(ThreadSanitizer, BasicSpinMutex) {\n  ScopedThread t;\n  Mutex m(Mutex::Spin);\n  t.Create(m);\n\n  t.Lock(m);\n  t.Unlock(m);\n\n  CHECK(t.TryLock(m));\n  t.Unlock(m);\n\n  t.Lock(m);\n  CHECK(!t.TryLock(m));\n  t.Unlock(m);\n\n  t.Destroy(m);\n}\n\nTEST(ThreadSanitizer, BasicRwMutex) {\n  ScopedThread t;\n  Mutex m(Mutex::RW);\n  t.Create(m);\n\n  t.Lock(m);\n  t.Unlock(m);\n\n  CHECK(t.TryLock(m));\n  t.Unlock(m);\n\n  t.Lock(m);\n  CHECK(!t.TryLock(m));\n  t.Unlock(m);\n\n  t.ReadLock(m);\n  t.ReadUnlock(m);\n\n  CHECK(t.TryReadLock(m));\n  t.ReadUnlock(m);\n\n  t.Lock(m);\n  CHECK(!t.TryReadLock(m));\n  t.Unlock(m);\n\n  t.ReadLock(m);\n  CHECK(!t.TryLock(m));\n  t.ReadUnlock(m);\n\n  t.ReadLock(m);\n  CHECK(t.TryReadLock(m));\n  t.ReadUnlock(m);\n  t.ReadUnlock(m);\n\n  t.Destroy(m);\n}\n\nTEST(ThreadSanitizer, Mutex) {\n  Mutex m;\n  MainThread t0;\n  t0.Create(m);\n\n  ScopedThread t1, t2;\n  MemLoc l;\n  t1.Lock(m);\n  t1.Write1(l);\n  t1.Unlock(m);\n  t2.Lock(m);\n  t2.Write1(l);\n  t2.Unlock(m);\n  t2.Destroy(m);\n}\n\nTEST(ThreadSanitizer, SpinMutex) {\n  Mutex m(Mutex::Spin);\n  MainThread t0;\n  t0.Create(m);\n\n  ScopedThread t1, t2;\n  MemLoc l;\n  t1.Lock(m);\n  t1.Write1(l);\n  t1.Unlock(m);\n  t2.Lock(m);\n  t2.Write1(l);\n  t2.Unlock(m);\n  t2.Destroy(m);\n}\n\nTEST(ThreadSanitizer, RwMutex) {\n  Mutex m(Mutex::RW);\n  MainThread t0;\n  t0.Create(m);\n\n  ScopedThread t1, t2, t3;\n  MemLoc l;\n  t1.Lock(m);\n  t1.Write1(l);\n  t1.Unlock(m);\n  t2.Lock(m);\n  t2.Write1(l);\n  t2.Unlock(m);\n  t1.ReadLock(m);\n  t3.ReadLock(m);\n  t1.Read1(l);\n  t3.Read1(l);\n  t1.ReadUnlock(m);\n  t3.ReadUnlock(m);\n  t2.Lock(m);\n  t2.Write1(l);\n  t2.Unlock(m);\n  t2.Destroy(m);\n}\n\nTEST(ThreadSanitizer, StaticMutex) {\n  // Emulates statically initialized mutex.\n  Mutex m;\n  m.StaticInit();\n  {\n    ScopedThread t1, t2;\n    t1.Lock(m);\n    t1.Unlock(m);\n    t2.Lock(m);\n    t2.Unlock(m);\n  }\n  MainThread().Destroy(m);\n}\n\nstatic void *singleton_thread(void *param) {\n  atomic_uintptr_t *singleton = (atomic_uintptr_t *)param;\n  for (int i = 0; i < 4*1024*1024; i++) {\n    int *val = (int *)atomic_load(singleton, memory_order_acquire);\n    __tsan_acquire(singleton);\n    __tsan_read4(val);\n    CHECK_EQ(*val, 42);\n  }\n  return 0;\n}\n\nTEST(DISABLED_BENCH_ThreadSanitizer, Singleton) {\n  const int kClockSize = 100;\n  const int kThreadCount = 8;\n\n  // Puff off thread's clock.\n  for (int i = 0; i < kClockSize; i++) {\n    ScopedThread t1;\n    (void)t1;\n  }\n  // Create the singleton.\n  int val = 42;\n  __tsan_write4(&val);\n  atomic_uintptr_t singleton;\n  __tsan_release(&singleton);\n  atomic_store(&singleton, (uintptr_t)&val, memory_order_release);\n  // Create reader threads.\n  pthread_t threads[kThreadCount];\n  for (int t = 0; t < kThreadCount; t++)\n    pthread_create(&threads[t], 0, singleton_thread, &singleton);\n  for (int t = 0; t < kThreadCount; t++)\n    pthread_join(threads[t], 0);\n}\n\nTEST(DISABLED_BENCH_ThreadSanitizer, StopFlag) {\n  const int kClockSize = 100;\n  const int kIters = 16*1024*1024;\n\n  // Puff off thread's clock.\n  for (int i = 0; i < kClockSize; i++) {\n    ScopedThread t1;\n    (void)t1;\n  }\n  // Create the stop flag.\n  atomic_uintptr_t flag;\n  __tsan_release(&flag);\n  atomic_store(&flag, 0, memory_order_release);\n  // Read it a lot.\n  for (int i = 0; i < kIters; i++) {\n    uptr v = atomic_load(&flag, memory_order_acquire);\n    __tsan_acquire(&flag);\n    CHECK_EQ(v, 0);\n  }\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/rtl/tsan_posix.cc",
    "content": "//===-- tsan_posix.cc -----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_interface.h\"\n#include \"tsan_test_util.h\"\n#include \"gtest/gtest.h\"\n#include <pthread.h>\n\nstruct thread_key {\n  pthread_key_t key;\n  pthread_mutex_t *mtx;\n  int val;\n  int *cnt;\n  thread_key(pthread_key_t key, pthread_mutex_t *mtx, int val, int *cnt)\n    : key(key)\n    , mtx(mtx)\n    , val(val)\n    , cnt(cnt) {\n  }\n};\n\nstatic void thread_secific_dtor(void *v) {\n  thread_key *k = (thread_key *)v;\n  EXPECT_EQ(pthread_mutex_lock(k->mtx), 0);\n  (*k->cnt)++;\n  __tsan_write4(&k->cnt);\n  EXPECT_EQ(pthread_mutex_unlock(k->mtx), 0);\n  if (k->val == 42) {\n    delete k;\n  } else if (k->val == 43 || k->val == 44) {\n    k->val--;\n    EXPECT_EQ(pthread_setspecific(k->key, k), 0);\n  } else {\n    ASSERT_TRUE(false);\n  }\n}\n\nstatic void *dtors_thread(void *p) {\n  thread_key *k = (thread_key *)p;\n  EXPECT_EQ(pthread_setspecific(k->key, k), 0);\n  return 0;\n}\n\nTEST(Posix, ThreadSpecificDtors) {\n  int cnt = 0;\n  pthread_key_t key;\n  EXPECT_EQ(pthread_key_create(&key, thread_secific_dtor), 0);\n  pthread_mutex_t mtx;\n  EXPECT_EQ(pthread_mutex_init(&mtx, 0), 0);\n  pthread_t th[3];\n  thread_key *k[3];\n  k[0] = new thread_key(key, &mtx, 42, &cnt);\n  k[1] = new thread_key(key, &mtx, 43, &cnt);\n  k[2] = new thread_key(key, &mtx, 44, &cnt);\n  EXPECT_EQ(pthread_create(&th[0], 0, dtors_thread, k[0]), 0);\n  EXPECT_EQ(pthread_create(&th[1], 0, dtors_thread, k[1]), 0);\n  EXPECT_EQ(pthread_join(th[0], 0), 0);\n  EXPECT_EQ(pthread_create(&th[2], 0, dtors_thread, k[2]), 0);\n  EXPECT_EQ(pthread_join(th[1], 0), 0);\n  EXPECT_EQ(pthread_join(th[2], 0), 0);\n  EXPECT_EQ(pthread_key_delete(key), 0);\n  EXPECT_EQ(6, cnt);\n}\n\nstatic __thread int local_var;\n\nstatic void *local_thread(void *p) {\n  __tsan_write1(&local_var);\n  __tsan_write1(&p);\n  if (p == 0)\n    return 0;\n  const int kThreads = 4;\n  pthread_t th[kThreads];\n  for (int i = 0; i < kThreads; i++)\n    EXPECT_EQ(pthread_create(&th[i], 0, local_thread,\n              (void*)((long)p - 1)), 0);  // NOLINT\n  for (int i = 0; i < kThreads; i++)\n    EXPECT_EQ(pthread_join(th[i], 0), 0);\n  return 0;\n}\n\nTEST(Posix, ThreadLocalAccesses) {\n  local_thread((void*)2);\n}\n\nstruct CondContext {\n  pthread_mutex_t m;\n  pthread_cond_t c;\n  int data;\n};\n\nstatic void *cond_thread(void *p) {\n  CondContext &ctx = *static_cast<CondContext*>(p);\n\n  EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0);\n  EXPECT_EQ(ctx.data, 0);\n  ctx.data = 1;\n  EXPECT_EQ(pthread_cond_signal(&ctx.c), 0);\n  EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0);\n\n  EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0);\n  while (ctx.data != 2)\n    EXPECT_EQ(pthread_cond_wait(&ctx.c, &ctx.m), 0);\n  EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0);\n\n  EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0);\n  ctx.data = 3;\n  EXPECT_EQ(pthread_cond_broadcast(&ctx.c), 0);\n  EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0);\n\n  return 0;\n}\n\nTEST(Posix, CondBasic) {\n  CondContext ctx;\n  EXPECT_EQ(pthread_mutex_init(&ctx.m, 0), 0);\n  EXPECT_EQ(pthread_cond_init(&ctx.c, 0), 0);\n  ctx.data = 0;\n  pthread_t th;\n  EXPECT_EQ(pthread_create(&th, 0, cond_thread, &ctx), 0);\n\n  EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0);\n  while (ctx.data != 1)\n    EXPECT_EQ(pthread_cond_wait(&ctx.c, &ctx.m), 0);\n  ctx.data = 2;\n  EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0);\n  EXPECT_EQ(pthread_cond_broadcast(&ctx.c), 0);\n\n  EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0);\n  while (ctx.data != 3)\n    EXPECT_EQ(pthread_cond_wait(&ctx.c, &ctx.m), 0);\n  EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0);\n\n  EXPECT_EQ(pthread_join(th, 0), 0);\n  EXPECT_EQ(pthread_cond_destroy(&ctx.c), 0);\n  EXPECT_EQ(pthread_mutex_destroy(&ctx.m), 0);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/rtl/tsan_string.cc",
    "content": "//===-- tsan_string.cc ----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_test_util.h\"\n#include \"gtest/gtest.h\"\n#include <string.h>\n\nnamespace __tsan {\n\nTEST(ThreadSanitizer, Memcpy) {\n  char data0[7] = {1, 2, 3, 4, 5, 6, 7};\n  char data[7] = {42, 42, 42, 42, 42, 42, 42};\n  MainThread().Memcpy(data+1, data0+1, 5);\n  EXPECT_EQ(data[0], 42);\n  EXPECT_EQ(data[1], 2);\n  EXPECT_EQ(data[2], 3);\n  EXPECT_EQ(data[3], 4);\n  EXPECT_EQ(data[4], 5);\n  EXPECT_EQ(data[5], 6);\n  EXPECT_EQ(data[6], 42);\n  MainThread().Memset(data+1, 13, 5);\n  EXPECT_EQ(data[0], 42);\n  EXPECT_EQ(data[1], 13);\n  EXPECT_EQ(data[2], 13);\n  EXPECT_EQ(data[3], 13);\n  EXPECT_EQ(data[4], 13);\n  EXPECT_EQ(data[5], 13);\n  EXPECT_EQ(data[6], 42);\n}\n\nTEST(ThreadSanitizer, MemcpyRace1) {\n  char *data = new char[10];\n  char *data1 = new char[10];\n  char *data2 = new char[10];\n  ScopedThread t1, t2;\n  t1.Memcpy(data, data1, 10);\n  t2.Memcpy(data, data2, 10, true);\n}\n\nTEST(ThreadSanitizer, MemcpyRace2) {\n  char *data = new char[10];\n  char *data1 = new char[10];\n  char *data2 = new char[10];\n  ScopedThread t1, t2;\n  t1.Memcpy(data+5, data1, 1);\n  t2.Memcpy(data+3, data2, 4, true);\n}\n\nTEST(ThreadSanitizer, MemcpyRace3) {\n  char *data = new char[10];\n  char *data1 = new char[10];\n  char *data2 = new char[10];\n  ScopedThread t1, t2;\n  t1.Memcpy(data, data1, 10);\n  t2.Memcpy(data1, data2, 10, true);\n}\n\nTEST(ThreadSanitizer, MemcpyStack) {\n  char *data = new char[10];\n  char *data1 = new char[10];\n  ScopedThread t1, t2;\n  t1.Memcpy(data, data1, 10);\n  t2.Memcpy(data, data1, 10, true);\n}\n\nTEST(ThreadSanitizer, MemsetRace1) {\n  char *data = new char[10];\n  ScopedThread t1, t2;\n  t1.Memset(data, 1, 10);\n  t2.Memset(data, 2, 10, true);\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/rtl/tsan_test.cc",
    "content": "//===-- tsan_test.cc ------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_interface.h\"\n#include \"tsan_test_util.h\"\n#include \"gtest/gtest.h\"\n\nstatic void foo() {}\nstatic void bar() {}\n\nTEST(ThreadSanitizer, FuncCall) {\n  ScopedThread t1, t2;\n  MemLoc l;\n  t1.Write1(l);\n  t2.Call(foo);\n  t2.Call(bar);\n  t2.Write1(l, true);\n  t2.Return();\n  t2.Return();\n}\n\n// We use this function instead of main, as ISO C++ forbids taking the address\n// of main, which we need to pass inside __tsan_func_entry.\nint run_tests(int argc, char **argv) {\n  TestMutexBeforeInit();  // Mutexes must be usable before __tsan_init();\n  __tsan_init();\n  __tsan_func_entry(__builtin_return_address(0));\n  __tsan_func_entry((void*)((intptr_t)&run_tests + 1));\n\n  testing::GTEST_FLAG(death_test_style) = \"threadsafe\";\n  testing::InitGoogleTest(&argc, argv);\n  int res = RUN_ALL_TESTS();\n\n  __tsan_func_exit();\n  __tsan_func_exit();\n  return res;\n}\n\nconst char *argv0;\n\nint main(int argc, char **argv) {\n  argv0 = argv[0];\n  return run_tests(argc, argv);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/rtl/tsan_test_util.h",
    "content": "//===-- tsan_test_util.h ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Test utils.\n//===----------------------------------------------------------------------===//\n#ifndef TSAN_TEST_UTIL_H\n#define TSAN_TEST_UTIL_H\n\nvoid TestMutexBeforeInit();\n\n// A location of memory on which a race may be detected.\nclass MemLoc {\n public:\n  explicit MemLoc(int offset_from_aligned = 0);\n  explicit MemLoc(void *const real_addr) : loc_(real_addr) { }\n  ~MemLoc();\n  void *loc() const { return loc_; }\n private:\n  void *const loc_;\n  MemLoc(const MemLoc&);\n  void operator = (const MemLoc&);\n};\n\nclass Mutex {\n public:\n  enum Type { Normal, Spin, RW };\n\n  explicit Mutex(Type type = Normal);\n  ~Mutex();\n\n  void Init();\n  void StaticInit();  // Emulates static initialization (tsan invisible).\n  void Destroy();\n  void Lock();\n  bool TryLock();\n  void Unlock();\n  void ReadLock();\n  bool TryReadLock();\n  void ReadUnlock();\n\n private:\n  // Placeholder for pthread_mutex_t, CRITICAL_SECTION or whatever.\n  void *mtx_[128];\n  bool alive_;\n  const Type type_;\n\n  Mutex(const Mutex&);\n  void operator = (const Mutex&);\n};\n\n// A thread is started in CTOR and joined in DTOR.\nclass ScopedThread {\n public:\n  explicit ScopedThread(bool detached = false, bool main = false);\n  ~ScopedThread();\n  void Detach();\n\n  void Access(void *addr, bool is_write, int size, bool expect_race);\n  void Read(const MemLoc &ml, int size, bool expect_race = false) {\n    Access(ml.loc(), false, size, expect_race);\n  }\n  void Write(const MemLoc &ml, int size, bool expect_race = false) {\n    Access(ml.loc(), true, size, expect_race);\n  }\n  void Read1(const MemLoc &ml, bool expect_race = false) {\n    Read(ml, 1, expect_race); }\n  void Read2(const MemLoc &ml, bool expect_race = false) {\n    Read(ml, 2, expect_race); }\n  void Read4(const MemLoc &ml, bool expect_race = false) {\n    Read(ml, 4, expect_race); }\n  void Read8(const MemLoc &ml, bool expect_race = false) {\n    Read(ml, 8, expect_race); }\n  void Write1(const MemLoc &ml, bool expect_race = false) {\n    Write(ml, 1, expect_race); }\n  void Write2(const MemLoc &ml, bool expect_race = false) {\n    Write(ml, 2, expect_race); }\n  void Write4(const MemLoc &ml, bool expect_race = false) {\n    Write(ml, 4, expect_race); }\n  void Write8(const MemLoc &ml, bool expect_race = false) {\n    Write(ml, 8, expect_race); }\n\n  void VptrUpdate(const MemLoc &vptr, const MemLoc &new_val,\n                  bool expect_race = false);\n\n  void Call(void(*pc)());\n  void Return();\n\n  void Create(const Mutex &m);\n  void Destroy(const Mutex &m);\n  void Lock(const Mutex &m);\n  bool TryLock(const Mutex &m);\n  void Unlock(const Mutex &m);\n  void ReadLock(const Mutex &m);\n  bool TryReadLock(const Mutex &m);\n  void ReadUnlock(const Mutex &m);\n\n  void Memcpy(void *dst, const void *src, int size, bool expect_race = false);\n  void Memset(void *dst, int val, int size, bool expect_race = false);\n\n private:\n  struct Impl;\n  Impl *impl_;\n  ScopedThread(const ScopedThread&);  // Not implemented.\n  void operator = (const ScopedThread&);  // Not implemented.\n};\n\nclass MainThread : public ScopedThread {\n public:\n  MainThread()\n    : ScopedThread(false, true) {\n  }\n};\n\n#endif  // #ifndef TSAN_TEST_UTIL_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/rtl/tsan_test_util_linux.cc",
    "content": "\n//===-- tsan_test_util_linux.cc -------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n// Test utils, Linux and FreeBSD implementation.\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"tsan_interface.h\"\n#include \"tsan_test_util.h\"\n#include \"tsan_report.h\"\n\n#include \"gtest/gtest.h\"\n\n#include <assert.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <string.h>\n#include <unistd.h>\n#include <errno.h>\n\nusing namespace __tsan;  // NOLINT\n\nstatic __thread bool expect_report;\nstatic __thread bool expect_report_reported;\nstatic __thread ReportType expect_report_type;\n\nextern \"C\" void *__interceptor_memcpy(void*, const void*, uptr);\nextern \"C\" void *__interceptor_memset(void*, int, uptr);\n\nstatic void *BeforeInitThread(void *param) {\n  (void)param;\n  return 0;\n}\n\nstatic void AtExit() {\n}\n\nvoid TestMutexBeforeInit() {\n  // Mutexes must be usable before __tsan_init();\n  pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;\n  pthread_mutex_lock(&mtx);\n  pthread_mutex_unlock(&mtx);\n  pthread_mutex_destroy(&mtx);\n  pthread_t thr;\n  pthread_create(&thr, 0, BeforeInitThread, 0);\n  pthread_join(thr, 0);\n  atexit(AtExit);\n}\n\nnamespace __tsan {\nbool OnReport(const ReportDesc *rep, bool suppressed) {\n  if (expect_report) {\n    if (rep->typ != expect_report_type) {\n      printf(\"Expected report of type %d, got type %d\\n\",\n             (int)expect_report_type, (int)rep->typ);\n      EXPECT_FALSE(\"Wrong report type\");\n      return false;\n    }\n  } else {\n    EXPECT_FALSE(\"Unexpected report\");\n    return false;\n  }\n  expect_report_reported = true;\n  return true;\n}\n}  // namespace __tsan\n\nstatic void* allocate_addr(int size, int offset_from_aligned = 0) {\n  static uintptr_t foo;\n  static atomic_uintptr_t uniq = {(uintptr_t)&foo};  // Some real address.\n  const int kAlign = 16;\n  CHECK(offset_from_aligned < kAlign);\n  size = (size + 2 * kAlign) & ~(kAlign - 1);\n  uintptr_t addr = atomic_fetch_add(&uniq, size, memory_order_relaxed);\n  return (void*)(addr + offset_from_aligned);\n}\n\nMemLoc::MemLoc(int offset_from_aligned)\n  : loc_(allocate_addr(16, offset_from_aligned)) {\n}\n\nMemLoc::~MemLoc() {\n}\n\nMutex::Mutex(Type type)\n  : alive_()\n  , type_(type) {\n}\n\nMutex::~Mutex() {\n  CHECK(!alive_);\n}\n\nvoid Mutex::Init() {\n  CHECK(!alive_);\n  alive_ = true;\n  if (type_ == Normal)\n    CHECK_EQ(pthread_mutex_init((pthread_mutex_t*)mtx_, 0), 0);\n  else if (type_ == Spin)\n    CHECK_EQ(pthread_spin_init((pthread_spinlock_t*)mtx_, 0), 0);\n  else if (type_ == RW)\n    CHECK_EQ(pthread_rwlock_init((pthread_rwlock_t*)mtx_, 0), 0);\n  else\n    CHECK(0);\n}\n\nvoid Mutex::StaticInit() {\n  CHECK(!alive_);\n  CHECK(type_ == Normal);\n  alive_ = true;\n  pthread_mutex_t tmp = PTHREAD_MUTEX_INITIALIZER;\n  memcpy(mtx_, &tmp, sizeof(tmp));\n}\n\nvoid Mutex::Destroy() {\n  CHECK(alive_);\n  alive_ = false;\n  if (type_ == Normal)\n    CHECK_EQ(pthread_mutex_destroy((pthread_mutex_t*)mtx_), 0);\n  else if (type_ == Spin)\n    CHECK_EQ(pthread_spin_destroy((pthread_spinlock_t*)mtx_), 0);\n  else if (type_ == RW)\n    CHECK_EQ(pthread_rwlock_destroy((pthread_rwlock_t*)mtx_), 0);\n}\n\nvoid Mutex::Lock() {\n  CHECK(alive_);\n  if (type_ == Normal)\n    CHECK_EQ(pthread_mutex_lock((pthread_mutex_t*)mtx_), 0);\n  else if (type_ == Spin)\n    CHECK_EQ(pthread_spin_lock((pthread_spinlock_t*)mtx_), 0);\n  else if (type_ == RW)\n    CHECK_EQ(pthread_rwlock_wrlock((pthread_rwlock_t*)mtx_), 0);\n}\n\nbool Mutex::TryLock() {\n  CHECK(alive_);\n  if (type_ == Normal)\n    return pthread_mutex_trylock((pthread_mutex_t*)mtx_) == 0;\n  else if (type_ == Spin)\n    return pthread_spin_trylock((pthread_spinlock_t*)mtx_) == 0;\n  else if (type_ == RW)\n    return pthread_rwlock_trywrlock((pthread_rwlock_t*)mtx_) == 0;\n  return false;\n}\n\nvoid Mutex::Unlock() {\n  CHECK(alive_);\n  if (type_ == Normal)\n    CHECK_EQ(pthread_mutex_unlock((pthread_mutex_t*)mtx_), 0);\n  else if (type_ == Spin)\n    CHECK_EQ(pthread_spin_unlock((pthread_spinlock_t*)mtx_), 0);\n  else if (type_ == RW)\n    CHECK_EQ(pthread_rwlock_unlock((pthread_rwlock_t*)mtx_), 0);\n}\n\nvoid Mutex::ReadLock() {\n  CHECK(alive_);\n  CHECK(type_ == RW);\n  CHECK_EQ(pthread_rwlock_rdlock((pthread_rwlock_t*)mtx_), 0);\n}\n\nbool Mutex::TryReadLock() {\n  CHECK(alive_);\n  CHECK(type_ == RW);\n  return pthread_rwlock_tryrdlock((pthread_rwlock_t*)mtx_) ==  0;\n}\n\nvoid Mutex::ReadUnlock() {\n  CHECK(alive_);\n  CHECK(type_ == RW);\n  CHECK_EQ(pthread_rwlock_unlock((pthread_rwlock_t*)mtx_), 0);\n}\n\nstruct Event {\n  enum Type {\n    SHUTDOWN,\n    READ,\n    WRITE,\n    VPTR_UPDATE,\n    CALL,\n    RETURN,\n    MUTEX_CREATE,\n    MUTEX_DESTROY,\n    MUTEX_LOCK,\n    MUTEX_TRYLOCK,\n    MUTEX_UNLOCK,\n    MUTEX_READLOCK,\n    MUTEX_TRYREADLOCK,\n    MUTEX_READUNLOCK,\n    MEMCPY,\n    MEMSET\n  };\n  Type type;\n  void *ptr;\n  uptr arg;\n  uptr arg2;\n  bool res;\n  bool expect_report;\n  ReportType report_type;\n\n  Event(Type type, const void *ptr = 0, uptr arg = 0, uptr arg2 = 0)\n    : type(type)\n    , ptr(const_cast<void*>(ptr))\n    , arg(arg)\n    , arg2(arg2)\n    , res()\n    , expect_report()\n    , report_type() {\n  }\n\n  void ExpectReport(ReportType type) {\n    expect_report = true;\n    report_type = type;\n  }\n};\n\nstruct ScopedThread::Impl {\n  pthread_t thread;\n  bool main;\n  bool detached;\n  atomic_uintptr_t event;  // Event*\n\n  static void *ScopedThreadCallback(void *arg);\n  void send(Event *ev);\n  void HandleEvent(Event *ev);\n};\n\nvoid ScopedThread::Impl::HandleEvent(Event *ev) {\n  CHECK_EQ(expect_report, false);\n  expect_report = ev->expect_report;\n  expect_report_reported = false;\n  expect_report_type = ev->report_type;\n  switch (ev->type) {\n  case Event::READ:\n  case Event::WRITE: {\n    void (*tsan_mop)(void *addr) = 0;\n    if (ev->type == Event::READ) {\n      switch (ev->arg /*size*/) {\n        case 1: tsan_mop = __tsan_read1; break;\n        case 2: tsan_mop = __tsan_read2; break;\n        case 4: tsan_mop = __tsan_read4; break;\n        case 8: tsan_mop = __tsan_read8; break;\n        case 16: tsan_mop = __tsan_read16; break;\n      }\n    } else {\n      switch (ev->arg /*size*/) {\n        case 1: tsan_mop = __tsan_write1; break;\n        case 2: tsan_mop = __tsan_write2; break;\n        case 4: tsan_mop = __tsan_write4; break;\n        case 8: tsan_mop = __tsan_write8; break;\n        case 16: tsan_mop = __tsan_write16; break;\n      }\n    }\n    CHECK_NE(tsan_mop, 0);\n#if defined(__FreeBSD__)\n    const int ErrCode = ESOCKTNOSUPPORT;\n#else\n    const int ErrCode = ECHRNG;\n#endif\n    errno = ErrCode;\n    tsan_mop(ev->ptr);\n    CHECK_EQ(ErrCode, errno);  // In no case must errno be changed.\n    break;\n  }\n  case Event::VPTR_UPDATE:\n    __tsan_vptr_update((void**)ev->ptr, (void*)ev->arg);\n    break;\n  case Event::CALL:\n    __tsan_func_entry((void*)((uptr)ev->ptr));\n    break;\n  case Event::RETURN:\n    __tsan_func_exit();\n    break;\n  case Event::MUTEX_CREATE:\n    static_cast<Mutex*>(ev->ptr)->Init();\n    break;\n  case Event::MUTEX_DESTROY:\n    static_cast<Mutex*>(ev->ptr)->Destroy();\n    break;\n  case Event::MUTEX_LOCK:\n    static_cast<Mutex*>(ev->ptr)->Lock();\n    break;\n  case Event::MUTEX_TRYLOCK:\n    ev->res = static_cast<Mutex*>(ev->ptr)->TryLock();\n    break;\n  case Event::MUTEX_UNLOCK:\n    static_cast<Mutex*>(ev->ptr)->Unlock();\n    break;\n  case Event::MUTEX_READLOCK:\n    static_cast<Mutex*>(ev->ptr)->ReadLock();\n    break;\n  case Event::MUTEX_TRYREADLOCK:\n    ev->res = static_cast<Mutex*>(ev->ptr)->TryReadLock();\n    break;\n  case Event::MUTEX_READUNLOCK:\n    static_cast<Mutex*>(ev->ptr)->ReadUnlock();\n    break;\n  case Event::MEMCPY:\n    __interceptor_memcpy(ev->ptr, (void*)ev->arg, ev->arg2);\n    break;\n  case Event::MEMSET:\n    __interceptor_memset(ev->ptr, ev->arg, ev->arg2);\n    break;\n  default: CHECK(0);\n  }\n  if (expect_report && !expect_report_reported) {\n    printf(\"Missed expected report of type %d\\n\", (int)ev->report_type);\n    EXPECT_FALSE(\"Missed expected race\");\n  }\n  expect_report = false;\n}\n\nvoid *ScopedThread::Impl::ScopedThreadCallback(void *arg) {\n  __tsan_func_entry(__builtin_return_address(0));\n  Impl *impl = (Impl*)arg;\n  for (;;) {\n    Event* ev = (Event*)atomic_load(&impl->event, memory_order_acquire);\n    if (ev == 0) {\n      pthread_yield();\n      continue;\n    }\n    if (ev->type == Event::SHUTDOWN) {\n      atomic_store(&impl->event, 0, memory_order_release);\n      break;\n    }\n    impl->HandleEvent(ev);\n    atomic_store(&impl->event, 0, memory_order_release);\n  }\n  __tsan_func_exit();\n  return 0;\n}\n\nvoid ScopedThread::Impl::send(Event *e) {\n  if (main) {\n    HandleEvent(e);\n  } else {\n    CHECK_EQ(atomic_load(&event, memory_order_relaxed), 0);\n    atomic_store(&event, (uintptr_t)e, memory_order_release);\n    while (atomic_load(&event, memory_order_acquire) != 0)\n      pthread_yield();\n  }\n}\n\nScopedThread::ScopedThread(bool detached, bool main) {\n  impl_ = new Impl;\n  impl_->main = main;\n  impl_->detached = detached;\n  atomic_store(&impl_->event, 0, memory_order_relaxed);\n  if (!main) {\n    pthread_attr_t attr;\n    pthread_attr_init(&attr);\n    pthread_attr_setdetachstate(&attr, detached);\n    pthread_attr_setstacksize(&attr, 64*1024);\n    pthread_create(&impl_->thread, &attr,\n        ScopedThread::Impl::ScopedThreadCallback, impl_);\n  }\n}\n\nScopedThread::~ScopedThread() {\n  if (!impl_->main) {\n    Event event(Event::SHUTDOWN);\n    impl_->send(&event);\n    if (!impl_->detached)\n      pthread_join(impl_->thread, 0);\n  }\n  delete impl_;\n}\n\nvoid ScopedThread::Detach() {\n  CHECK(!impl_->main);\n  CHECK(!impl_->detached);\n  impl_->detached = true;\n  pthread_detach(impl_->thread);\n}\n\nvoid ScopedThread::Access(void *addr, bool is_write,\n                          int size, bool expect_race) {\n  Event event(is_write ? Event::WRITE : Event::READ, addr, size);\n  if (expect_race)\n    event.ExpectReport(ReportTypeRace);\n  impl_->send(&event);\n}\n\nvoid ScopedThread::VptrUpdate(const MemLoc &vptr,\n                              const MemLoc &new_val,\n                              bool expect_race) {\n  Event event(Event::VPTR_UPDATE, vptr.loc(), (uptr)new_val.loc());\n  if (expect_race)\n    event.ExpectReport(ReportTypeRace);\n  impl_->send(&event);\n}\n\nvoid ScopedThread::Call(void(*pc)()) {\n  Event event(Event::CALL, (void*)((uintptr_t)pc));\n  impl_->send(&event);\n}\n\nvoid ScopedThread::Return() {\n  Event event(Event::RETURN);\n  impl_->send(&event);\n}\n\nvoid ScopedThread::Create(const Mutex &m) {\n  Event event(Event::MUTEX_CREATE, &m);\n  impl_->send(&event);\n}\n\nvoid ScopedThread::Destroy(const Mutex &m) {\n  Event event(Event::MUTEX_DESTROY, &m);\n  impl_->send(&event);\n}\n\nvoid ScopedThread::Lock(const Mutex &m) {\n  Event event(Event::MUTEX_LOCK, &m);\n  impl_->send(&event);\n}\n\nbool ScopedThread::TryLock(const Mutex &m) {\n  Event event(Event::MUTEX_TRYLOCK, &m);\n  impl_->send(&event);\n  return event.res;\n}\n\nvoid ScopedThread::Unlock(const Mutex &m) {\n  Event event(Event::MUTEX_UNLOCK, &m);\n  impl_->send(&event);\n}\n\nvoid ScopedThread::ReadLock(const Mutex &m) {\n  Event event(Event::MUTEX_READLOCK, &m);\n  impl_->send(&event);\n}\n\nbool ScopedThread::TryReadLock(const Mutex &m) {\n  Event event(Event::MUTEX_TRYREADLOCK, &m);\n  impl_->send(&event);\n  return event.res;\n}\n\nvoid ScopedThread::ReadUnlock(const Mutex &m) {\n  Event event(Event::MUTEX_READUNLOCK, &m);\n  impl_->send(&event);\n}\n\nvoid ScopedThread::Memcpy(void *dst, const void *src, int size,\n                          bool expect_race) {\n  Event event(Event::MEMCPY, dst, (uptr)src, size);\n  if (expect_race)\n    event.ExpectReport(ReportTypeRace);\n  impl_->send(&event);\n}\n\nvoid ScopedThread::Memset(void *dst, int val, int size,\n                          bool expect_race) {\n  Event event(Event::MEMSET, dst, val, size);\n  if (expect_race)\n    event.ExpectReport(ReportTypeRace);\n  impl_->send(&event);\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/rtl/tsan_thread.cc",
    "content": "//===-- tsan_thread.cc ----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_test_util.h\"\n#include \"gtest/gtest.h\"\n\nTEST(ThreadSanitizer, ThreadSync) {\n  MainThread t0;\n  MemLoc l;\n  t0.Write1(l);\n  {\n    ScopedThread t1;\n    t1.Write1(l);\n  }\n  t0.Write1(l);\n}\n\nTEST(ThreadSanitizer, ThreadDetach1) {\n  ScopedThread t1(true);\n  MemLoc l;\n  t1.Write1(l);\n}\n\nTEST(ThreadSanitizer, ThreadDetach2) {\n  ScopedThread t1;\n  MemLoc l;\n  t1.Write1(l);\n  t1.Detach();\n}\n\nstatic void *thread_alot_func(void *arg) {\n  (void)arg;\n  int usleep(unsigned);\n  usleep(50);\n  return 0;\n}\n\nTEST(DISABLED_SLOW_ThreadSanitizer, ThreadALot) {\n  const int kThreads = 70000;\n  const int kAlive = 1000;\n  pthread_t threads[kAlive] = {};\n  for (int i = 0; i < kThreads; i++) {\n    if (threads[i % kAlive])\n      pthread_join(threads[i % kAlive], 0);\n    pthread_create(&threads[i % kAlive], 0, thread_alot_func, 0);\n  }\n  for (int i = 0; i < kAlive; i++) {\n    pthread_join(threads[i], 0);\n  }\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/unit/CMakeLists.txt",
    "content": "set(TSAN_UNIT_TEST_SOURCES\n  tsan_clock_test.cc\n  tsan_flags_test.cc\n  tsan_mman_test.cc\n  tsan_mutex_test.cc\n  tsan_shadow_test.cc\n  tsan_stack_test.cc\n  tsan_sync_test.cc\n  tsan_unit_test_main.cc\n  tsan_vector_test.cc)\n\nadd_tsan_unittest(TsanUnitTest\n  SOURCES ${TSAN_UNIT_TEST_SOURCES})\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/unit/tsan_clock_test.cc",
    "content": "//===-- tsan_clock_test.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_clock.h\"\n#include \"tsan_rtl.h\"\n#include \"gtest/gtest.h\"\n#include <time.h>\n\nnamespace __tsan {\n\nClockCache cache;\n\nTEST(Clock, VectorBasic) {\n  ThreadClock clk(0);\n  ASSERT_EQ(clk.size(), 1U);\n  clk.tick();\n  ASSERT_EQ(clk.size(), 1U);\n  ASSERT_EQ(clk.get(0), 1U);\n  clk.set(3, clk.get(3) + 1);\n  ASSERT_EQ(clk.size(), 4U);\n  ASSERT_EQ(clk.get(0), 1U);\n  ASSERT_EQ(clk.get(1), 0U);\n  ASSERT_EQ(clk.get(2), 0U);\n  ASSERT_EQ(clk.get(3), 1U);\n  clk.set(3, clk.get(3) + 1);\n  ASSERT_EQ(clk.get(3), 2U);\n}\n\nTEST(Clock, ChunkedBasic) {\n  ThreadClock vector(0);\n  SyncClock chunked;\n  ASSERT_EQ(vector.size(), 1U);\n  ASSERT_EQ(chunked.size(), 0U);\n  vector.acquire(&cache, &chunked);\n  ASSERT_EQ(vector.size(), 1U);\n  ASSERT_EQ(chunked.size(), 0U);\n  vector.release(&cache, &chunked);\n  ASSERT_EQ(vector.size(), 1U);\n  ASSERT_EQ(chunked.size(), 1U);\n  vector.acq_rel(&cache, &chunked);\n  ASSERT_EQ(vector.size(), 1U);\n  ASSERT_EQ(chunked.size(), 1U);\n  chunked.Reset(&cache);\n}\n\nTEST(Clock, AcquireRelease) {\n  ThreadClock vector1(100);\n  vector1.tick();\n  SyncClock chunked;\n  vector1.release(&cache, &chunked);\n  ASSERT_EQ(chunked.size(), 101U);\n  ThreadClock vector2(0);\n  vector2.acquire(&cache, &chunked);\n  ASSERT_EQ(vector2.size(), 101U);\n  ASSERT_EQ(vector2.get(0), 0U);\n  ASSERT_EQ(vector2.get(1), 0U);\n  ASSERT_EQ(vector2.get(99), 0U);\n  ASSERT_EQ(vector2.get(100), 1U);\n  chunked.Reset(&cache);\n}\n\nTEST(Clock, RepeatedAcquire) {\n  ThreadClock thr1(1);\n  thr1.tick();\n  ThreadClock thr2(2);\n  thr2.tick();\n\n  SyncClock sync;\n  thr1.ReleaseStore(&cache, &sync);\n\n  thr2.acquire(&cache, &sync);\n  thr2.acquire(&cache, &sync);\n\n  sync.Reset(&cache);\n}\n\nTEST(Clock, ManyThreads) {\n  SyncClock chunked;\n  for (unsigned i = 0; i < 100; i++) {\n    ThreadClock vector(0);\n    vector.tick();\n    vector.set(i, 1);\n    vector.release(&cache, &chunked);\n    ASSERT_EQ(i + 1, chunked.size());\n    vector.acquire(&cache, &chunked);\n    ASSERT_EQ(i + 1, vector.size());\n  }\n\n  for (unsigned i = 0; i < 100; i++)\n    ASSERT_EQ(1U, chunked.get(i));\n\n  ThreadClock vector(1);\n  vector.acquire(&cache, &chunked);\n  ASSERT_EQ(100U, vector.size());\n  for (unsigned i = 0; i < 100; i++)\n    ASSERT_EQ(1U, vector.get(i));\n\n  chunked.Reset(&cache);\n}\n\nTEST(Clock, DifferentSizes) {\n  {\n    ThreadClock vector1(10);\n    vector1.tick();\n    ThreadClock vector2(20);\n    vector2.tick();\n    {\n      SyncClock chunked;\n      vector1.release(&cache, &chunked);\n      ASSERT_EQ(chunked.size(), 11U);\n      vector2.release(&cache, &chunked);\n      ASSERT_EQ(chunked.size(), 21U);\n      chunked.Reset(&cache);\n    }\n    {\n      SyncClock chunked;\n      vector2.release(&cache, &chunked);\n      ASSERT_EQ(chunked.size(), 21U);\n      vector1.release(&cache, &chunked);\n      ASSERT_EQ(chunked.size(), 21U);\n      chunked.Reset(&cache);\n    }\n    {\n      SyncClock chunked;\n      vector1.release(&cache, &chunked);\n      vector2.acquire(&cache, &chunked);\n      ASSERT_EQ(vector2.size(), 21U);\n      chunked.Reset(&cache);\n    }\n    {\n      SyncClock chunked;\n      vector2.release(&cache, &chunked);\n      vector1.acquire(&cache, &chunked);\n      ASSERT_EQ(vector1.size(), 21U);\n      chunked.Reset(&cache);\n    }\n  }\n}\n\nTEST(Clock, Growth) {\n  {\n    ThreadClock vector(10);\n    vector.tick();\n    vector.set(5, 42);\n    SyncClock sync;\n    vector.release(&cache, &sync);\n    ASSERT_EQ(sync.size(), 11U);\n    ASSERT_EQ(sync.get(0), 0ULL);\n    ASSERT_EQ(sync.get(1), 0ULL);\n    ASSERT_EQ(sync.get(5), 42ULL);\n    ASSERT_EQ(sync.get(9), 0ULL);\n    ASSERT_EQ(sync.get(10), 1ULL);\n    sync.Reset(&cache);\n  }\n  {\n    ThreadClock vector1(10);\n    vector1.tick();\n    ThreadClock vector2(20);\n    vector2.tick();\n    SyncClock sync;\n    vector1.release(&cache, &sync);\n    vector2.release(&cache, &sync);\n    ASSERT_EQ(sync.size(), 21U);\n    ASSERT_EQ(sync.get(0), 0ULL);\n    ASSERT_EQ(sync.get(10), 1ULL);\n    ASSERT_EQ(sync.get(19), 0ULL);\n    ASSERT_EQ(sync.get(20), 1ULL);\n    sync.Reset(&cache);\n  }\n  {\n    ThreadClock vector(100);\n    vector.tick();\n    vector.set(5, 42);\n    vector.set(90, 84);\n    SyncClock sync;\n    vector.release(&cache, &sync);\n    ASSERT_EQ(sync.size(), 101U);\n    ASSERT_EQ(sync.get(0), 0ULL);\n    ASSERT_EQ(sync.get(1), 0ULL);\n    ASSERT_EQ(sync.get(5), 42ULL);\n    ASSERT_EQ(sync.get(60), 0ULL);\n    ASSERT_EQ(sync.get(70), 0ULL);\n    ASSERT_EQ(sync.get(90), 84ULL);\n    ASSERT_EQ(sync.get(99), 0ULL);\n    ASSERT_EQ(sync.get(100), 1ULL);\n    sync.Reset(&cache);\n  }\n  {\n    ThreadClock vector1(10);\n    vector1.tick();\n    ThreadClock vector2(100);\n    vector2.tick();\n    SyncClock sync;\n    vector1.release(&cache, &sync);\n    vector2.release(&cache, &sync);\n    ASSERT_EQ(sync.size(), 101U);\n    ASSERT_EQ(sync.get(0), 0ULL);\n    ASSERT_EQ(sync.get(10), 1ULL);\n    ASSERT_EQ(sync.get(99), 0ULL);\n    ASSERT_EQ(sync.get(100), 1ULL);\n    sync.Reset(&cache);\n  }\n}\n\nconst uptr kThreads = 4;\nconst uptr kClocks = 4;\n\n// SimpleSyncClock and SimpleThreadClock implement the same thing as\n// SyncClock and ThreadClock, but in a very simple way.\nstruct SimpleSyncClock {\n  u64 clock[kThreads];\n  uptr size;\n\n  SimpleSyncClock() {\n    Reset();\n  }\n\n  void Reset() {\n    size = 0;\n    for (uptr i = 0; i < kThreads; i++)\n      clock[i] = 0;\n  }\n\n  bool verify(const SyncClock *other) const {\n    for (uptr i = 0; i < min(size, other->size()); i++) {\n      if (clock[i] != other->get(i))\n        return false;\n    }\n    for (uptr i = min(size, other->size()); i < max(size, other->size()); i++) {\n      if (i < size && clock[i] != 0)\n        return false;\n      if (i < other->size() && other->get(i) != 0)\n        return false;\n    }\n    return true;\n  }\n};\n\nstruct SimpleThreadClock {\n  u64 clock[kThreads];\n  uptr size;\n  unsigned tid;\n\n  explicit SimpleThreadClock(unsigned tid) {\n    this->tid = tid;\n    size = tid + 1;\n    for (uptr i = 0; i < kThreads; i++)\n      clock[i] = 0;\n  }\n\n  void tick() {\n    clock[tid]++;\n  }\n\n  void acquire(const SimpleSyncClock *src) {\n    if (size < src->size)\n      size = src->size;\n    for (uptr i = 0; i < kThreads; i++)\n      clock[i] = max(clock[i], src->clock[i]);\n  }\n\n  void release(SimpleSyncClock *dst) const {\n    if (dst->size < size)\n      dst->size = size;\n    for (uptr i = 0; i < kThreads; i++)\n      dst->clock[i] = max(dst->clock[i], clock[i]);\n  }\n\n  void acq_rel(SimpleSyncClock *dst) {\n    acquire(dst);\n    release(dst);\n  }\n\n  void ReleaseStore(SimpleSyncClock *dst) const {\n    if (dst->size < size)\n      dst->size = size;\n    for (uptr i = 0; i < kThreads; i++)\n      dst->clock[i] = clock[i];\n  }\n\n  bool verify(const ThreadClock *other) const {\n    for (uptr i = 0; i < min(size, other->size()); i++) {\n      if (clock[i] != other->get(i))\n        return false;\n    }\n    for (uptr i = min(size, other->size()); i < max(size, other->size()); i++) {\n      if (i < size && clock[i] != 0)\n        return false;\n      if (i < other->size() && other->get(i) != 0)\n        return false;\n    }\n    return true;\n  }\n};\n\nstatic bool ClockFuzzer(bool printing) {\n  // Create kThreads thread clocks.\n  SimpleThreadClock *thr0[kThreads];\n  ThreadClock *thr1[kThreads];\n  unsigned reused[kThreads];\n  for (unsigned i = 0; i < kThreads; i++) {\n    reused[i] = 0;\n    thr0[i] = new SimpleThreadClock(i);\n    thr1[i] = new ThreadClock(i, reused[i]);\n  }\n\n  // Create kClocks sync clocks.\n  SimpleSyncClock *sync0[kClocks];\n  SyncClock *sync1[kClocks];\n  for (unsigned i = 0; i < kClocks; i++) {\n    sync0[i] = new SimpleSyncClock();\n    sync1[i] = new SyncClock();\n  }\n\n  // Do N random operations (acquire, release, etc) and compare results\n  // for SimpleThread/SyncClock and real Thread/SyncClock.\n  for (int i = 0; i < 10000; i++) {\n    unsigned tid = rand() % kThreads;\n    unsigned cid = rand() % kClocks;\n    thr0[tid]->tick();\n    thr1[tid]->tick();\n\n    switch (rand() % 6) {\n    case 0:\n      if (printing)\n        printf(\"acquire thr%d <- clk%d\\n\", tid, cid);\n      thr0[tid]->acquire(sync0[cid]);\n      thr1[tid]->acquire(&cache, sync1[cid]);\n      break;\n    case 1:\n      if (printing)\n        printf(\"release thr%d -> clk%d\\n\", tid, cid);\n      thr0[tid]->release(sync0[cid]);\n      thr1[tid]->release(&cache, sync1[cid]);\n      break;\n    case 2:\n      if (printing)\n        printf(\"acq_rel thr%d <> clk%d\\n\", tid, cid);\n      thr0[tid]->acq_rel(sync0[cid]);\n      thr1[tid]->acq_rel(&cache, sync1[cid]);\n      break;\n    case 3:\n      if (printing)\n        printf(\"rel_str thr%d >> clk%d\\n\", tid, cid);\n      thr0[tid]->ReleaseStore(sync0[cid]);\n      thr1[tid]->ReleaseStore(&cache, sync1[cid]);\n      break;\n    case 4:\n      if (printing)\n        printf(\"reset clk%d\\n\", cid);\n      sync0[cid]->Reset();\n      sync1[cid]->Reset(&cache);\n      break;\n    case 5:\n      if (printing)\n        printf(\"reset thr%d\\n\", tid);\n      u64 epoch = thr0[tid]->clock[tid] + 1;\n      reused[tid]++;\n      delete thr0[tid];\n      thr0[tid] = new SimpleThreadClock(tid);\n      thr0[tid]->clock[tid] = epoch;\n      delete thr1[tid];\n      thr1[tid] = new ThreadClock(tid, reused[tid]);\n      thr1[tid]->set(epoch);\n      break;\n    }\n\n    if (printing) {\n      for (unsigned i = 0; i < kThreads; i++) {\n        printf(\"thr%d: \", i);\n        thr1[i]->DebugDump(printf);\n        printf(\"\\n\");\n      }\n      for (unsigned i = 0; i < kClocks; i++) {\n        printf(\"clk%d: \", i);\n        sync1[i]->DebugDump(printf);\n        printf(\"\\n\");\n      }\n\n      printf(\"\\n\");\n    }\n\n    if (!thr0[tid]->verify(thr1[tid]) || !sync0[cid]->verify(sync1[cid])) {\n      if (!printing)\n        return false;\n      printf(\"differs with model:\\n\");\n      for (unsigned i = 0; i < kThreads; i++) {\n        printf(\"thr%d: clock=[\", i);\n        for (uptr j = 0; j < thr0[i]->size; j++)\n          printf(\"%s%llu\", j == 0 ? \"\" : \",\", thr0[i]->clock[j]);\n        printf(\"]\\n\");\n      }\n      for (unsigned i = 0; i < kClocks; i++) {\n        printf(\"clk%d: clock=[\", i);\n        for (uptr j = 0; j < sync0[i]->size; j++)\n          printf(\"%s%llu\", j == 0 ? \"\" : \",\", sync0[i]->clock[j]);\n        printf(\"]\\n\");\n      }\n      return false;\n    }\n  }\n\n  for (unsigned i = 0; i < kClocks; i++) {\n    sync1[i]->Reset(&cache);\n  }\n  return true;\n}\n\nTEST(Clock, Fuzzer) {\n  timespec ts;\n  clock_gettime(CLOCK_MONOTONIC, &ts);\n  int seed = ts.tv_sec + ts.tv_nsec;\n  printf(\"seed=%d\\n\", seed);\n  srand(seed);\n  if (!ClockFuzzer(false)) {\n    // Redo the test with the same seed, but logging operations.\n    srand(seed);\n    ClockFuzzer(true);\n    ASSERT_TRUE(false);\n  }\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/unit/tsan_dense_alloc_test.cc",
    "content": "//===-- tsan_dense_alloc_test.cc ------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_dense_alloc.h\"\n#include \"tsan_rtl.h\"\n#include \"tsan_mman.h\"\n#include \"gtest/gtest.h\"\n\n#include <stdlib.h>\n#include <stdint.h>\n#include <map>\n\nnamespace __tsan {\n\nTEST(DenseSlabAlloc, Basic) {\n  typedef DenseSlabAlloc<int, 128, 128> Alloc;\n  typedef Alloc::Cache Cache;\n  typedef Alloc::IndexT IndexT;\n  const int N = 1000;\n\n  Alloc alloc;\n  Cache cache;\n  alloc.InitCache(&cache);\n\n  IndexT blocks[N];\n  for (int ntry = 0; ntry < 3; ntry++) {\n    for (int i = 0; i < N; i++) {\n      IndexT idx = alloc.Alloc(&cache);\n      blocks[i] = idx;\n      EXPECT_NE(idx, 0U);\n      int *v = alloc.Map(idx);\n      *v = i;\n    }\n\n    for (int i = 0; i < N; i++) {\n      IndexT idx = blocks[i];\n      int *v = alloc.Map(idx);\n      EXPECT_EQ(*v, i);\n      alloc.Free(&cache, idx);\n    }\n\n    alloc.FlushCache(&cache);\n  }\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/unit/tsan_flags_test.cc",
    "content": "//===-- tsan_flags_test.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_flags.h\"\n#include \"tsan_rtl.h\"\n#include \"gtest/gtest.h\"\n#include <string>\n\nnamespace __tsan {\n\nTEST(Flags, Basic) {\n  // At least should not crash.\n  Flags f;\n  InitializeFlags(&f, 0);\n  InitializeFlags(&f, \"\");\n}\n\nTEST(Flags, DefaultValues) {\n  Flags f;\n\n  f.enable_annotations = false;\n  f.exitcode = -11;\n  InitializeFlags(&f, \"\");\n  EXPECT_EQ(66, f.exitcode);\n  EXPECT_EQ(true, f.enable_annotations);\n}\n\nstatic const char *options1 =\n  \" enable_annotations=0\"\n  \" suppress_equal_stacks=0\"\n  \" suppress_equal_addresses=0\"\n  \" report_bugs=0\"\n  \" report_thread_leaks=0\"\n  \" report_destroy_locked=0\"\n  \" report_mutex_bugs=0\"\n  \" report_signal_unsafe=0\"\n  \" report_atomic_races=0\"\n  \" force_seq_cst_atomics=0\"\n  \" print_benign=0\"\n  \" exitcode=111\"\n  \" halt_on_error=0\"\n  \" atexit_sleep_ms=222\"\n  \" profile_memory=qqq\"\n  \" flush_memory_ms=444\"\n  \" flush_symbolizer_ms=555\"\n  \" memory_limit_mb=666\"\n  \" stop_on_start=0\"\n  \" running_on_valgrind=0\"\n  \" history_size=5\"\n  \" io_sync=1\"\n  \" die_after_fork=true\"\n  \"\";\n\nstatic const char *options2 =\n  \" enable_annotations=true\"\n  \" suppress_equal_stacks=true\"\n  \" suppress_equal_addresses=true\"\n  \" report_bugs=true\"\n  \" report_thread_leaks=true\"\n  \" report_destroy_locked=true\"\n  \" report_mutex_bugs=true\"\n  \" report_signal_unsafe=true\"\n  \" report_atomic_races=true\"\n  \" force_seq_cst_atomics=true\"\n  \" print_benign=true\"\n  \" exitcode=222\"\n  \" halt_on_error=true\"\n  \" atexit_sleep_ms=123\"\n  \" profile_memory=bbbbb\"\n  \" flush_memory_ms=234\"\n  \" flush_symbolizer_ms=345\"\n  \" memory_limit_mb=456\"\n  \" stop_on_start=true\"\n  \" running_on_valgrind=true\"\n  \" history_size=6\"\n  \" io_sync=2\"\n  \" die_after_fork=false\"\n  \"\";\n\nvoid VerifyOptions1(Flags *f) {\n  EXPECT_EQ(f->enable_annotations, 0);\n  EXPECT_EQ(f->suppress_equal_stacks, 0);\n  EXPECT_EQ(f->suppress_equal_addresses, 0);\n  EXPECT_EQ(f->report_bugs, 0);\n  EXPECT_EQ(f->report_thread_leaks, 0);\n  EXPECT_EQ(f->report_destroy_locked, 0);\n  EXPECT_EQ(f->report_mutex_bugs, 0);\n  EXPECT_EQ(f->report_signal_unsafe, 0);\n  EXPECT_EQ(f->report_atomic_races, 0);\n  EXPECT_EQ(f->force_seq_cst_atomics, 0);\n  EXPECT_EQ(f->print_benign, 0);\n  EXPECT_EQ(f->exitcode, 111);\n  EXPECT_EQ(f->halt_on_error, 0);\n  EXPECT_EQ(f->atexit_sleep_ms, 222);\n  EXPECT_EQ(f->profile_memory, std::string(\"qqq\"));\n  EXPECT_EQ(f->flush_memory_ms, 444);\n  EXPECT_EQ(f->flush_symbolizer_ms, 555);\n  EXPECT_EQ(f->memory_limit_mb, 666);\n  EXPECT_EQ(f->stop_on_start, 0);\n  EXPECT_EQ(f->running_on_valgrind, 0);\n  EXPECT_EQ(f->history_size, 5);\n  EXPECT_EQ(f->io_sync, 1);\n  EXPECT_EQ(f->die_after_fork, true);\n}\n\nvoid VerifyOptions2(Flags *f) {\n  EXPECT_EQ(f->enable_annotations, true);\n  EXPECT_EQ(f->suppress_equal_stacks, true);\n  EXPECT_EQ(f->suppress_equal_addresses, true);\n  EXPECT_EQ(f->report_bugs, true);\n  EXPECT_EQ(f->report_thread_leaks, true);\n  EXPECT_EQ(f->report_destroy_locked, true);\n  EXPECT_EQ(f->report_mutex_bugs, true);\n  EXPECT_EQ(f->report_signal_unsafe, true);\n  EXPECT_EQ(f->report_atomic_races, true);\n  EXPECT_EQ(f->force_seq_cst_atomics, true);\n  EXPECT_EQ(f->print_benign, true);\n  EXPECT_EQ(f->exitcode, 222);\n  EXPECT_EQ(f->halt_on_error, true);\n  EXPECT_EQ(f->atexit_sleep_ms, 123);\n  EXPECT_EQ(f->profile_memory, std::string(\"bbbbb\"));\n  EXPECT_EQ(f->flush_memory_ms, 234);\n  EXPECT_EQ(f->flush_symbolizer_ms, 345);\n  EXPECT_EQ(f->memory_limit_mb, 456);\n  EXPECT_EQ(f->stop_on_start, true);\n  EXPECT_EQ(f->running_on_valgrind, true);\n  EXPECT_EQ(f->history_size, 6);\n  EXPECT_EQ(f->io_sync, 2);\n  EXPECT_EQ(f->die_after_fork, false);\n}\n\nstatic const char *test_default_options;\nextern \"C\" const char *__tsan_default_options() {\n  return test_default_options;\n}\n\nTEST(Flags, ParseDefaultOptions) {\n  Flags f;\n\n  test_default_options = options1;\n  InitializeFlags(&f, \"\");\n  VerifyOptions1(&f);\n\n  test_default_options = options2;\n  InitializeFlags(&f, \"\");\n  VerifyOptions2(&f);\n}\n\nTEST(Flags, ParseEnvOptions) {\n  Flags f;\n\n  InitializeFlags(&f, options1);\n  VerifyOptions1(&f);\n\n  InitializeFlags(&f, options2);\n  VerifyOptions2(&f);\n}\n\nTEST(Flags, ParsePriority) {\n  Flags f;\n\n  test_default_options = options2;\n  InitializeFlags(&f, options1);\n  VerifyOptions1(&f);\n\n  test_default_options = options1;\n  InitializeFlags(&f, options2);\n  VerifyOptions2(&f);\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/unit/tsan_mman_test.cc",
    "content": "//===-- tsan_mman_test.cc -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include <limits>\n#include <sanitizer/allocator_interface.h>\n#include \"tsan_mman.h\"\n#include \"tsan_rtl.h\"\n#include \"gtest/gtest.h\"\n\nnamespace __tsan {\n\nTEST(Mman, Internal) {\n  char *p = (char*)internal_alloc(MBlockScopedBuf, 10);\n  EXPECT_NE(p, (char*)0);\n  char *p2 = (char*)internal_alloc(MBlockScopedBuf, 20);\n  EXPECT_NE(p2, (char*)0);\n  EXPECT_NE(p2, p);\n  for (int i = 0; i < 10; i++) {\n    p[i] = 42;\n  }\n  for (int i = 0; i < 20; i++) {\n    ((char*)p2)[i] = 42;\n  }\n  internal_free(p);\n  internal_free(p2);\n}\n\nTEST(Mman, User) {\n  ThreadState *thr = cur_thread();\n  uptr pc = 0;\n  char *p = (char*)user_alloc(thr, pc, 10);\n  EXPECT_NE(p, (char*)0);\n  char *p2 = (char*)user_alloc(thr, pc, 20);\n  EXPECT_NE(p2, (char*)0);\n  EXPECT_NE(p2, p);\n  EXPECT_EQ(10U, user_alloc_usable_size(p));\n  EXPECT_EQ(20U, user_alloc_usable_size(p2));\n  user_free(thr, pc, p);\n  user_free(thr, pc, p2);\n}\n\nTEST(Mman, UserRealloc) {\n  ThreadState *thr = cur_thread();\n  uptr pc = 0;\n  {\n    void *p = user_realloc(thr, pc, 0, 0);\n    // Strictly saying this is incorrect, realloc(NULL, N) is equivalent to\n    // malloc(N), thus must return non-NULL pointer.\n    EXPECT_EQ(p, (void*)0);\n  }\n  {\n    void *p = user_realloc(thr, pc, 0, 100);\n    EXPECT_NE(p, (void*)0);\n    memset(p, 0xde, 100);\n    user_free(thr, pc, p);\n  }\n  {\n    void *p = user_alloc(thr, pc, 100);\n    EXPECT_NE(p, (void*)0);\n    memset(p, 0xde, 100);\n    void *p2 = user_realloc(thr, pc, p, 0);\n    EXPECT_EQ(p2, (void*)0);\n  }\n  {\n    void *p = user_realloc(thr, pc, 0, 100);\n    EXPECT_NE(p, (void*)0);\n    memset(p, 0xde, 100);\n    void *p2 = user_realloc(thr, pc, p, 10000);\n    EXPECT_NE(p2, (void*)0);\n    for (int i = 0; i < 100; i++)\n      EXPECT_EQ(((char*)p2)[i], (char)0xde);\n    memset(p2, 0xde, 10000);\n    user_free(thr, pc, p2);\n  }\n  {\n    void *p = user_realloc(thr, pc, 0, 10000);\n    EXPECT_NE(p, (void*)0);\n    memset(p, 0xde, 10000);\n    void *p2 = user_realloc(thr, pc, p, 10);\n    EXPECT_NE(p2, (void*)0);\n    for (int i = 0; i < 10; i++)\n      EXPECT_EQ(((char*)p2)[i], (char)0xde);\n    user_free(thr, pc, p2);\n  }\n}\n\nTEST(Mman, UsableSize) {\n  ThreadState *thr = cur_thread();\n  uptr pc = 0;\n  char *p = (char*)user_alloc(thr, pc, 10);\n  char *p2 = (char*)user_alloc(thr, pc, 20);\n  EXPECT_EQ(0U, user_alloc_usable_size(NULL));\n  EXPECT_EQ(10U, user_alloc_usable_size(p));\n  EXPECT_EQ(20U, user_alloc_usable_size(p2));\n  user_free(thr, pc, p);\n  user_free(thr, pc, p2);\n  EXPECT_EQ(0U, user_alloc_usable_size((void*)0x4123));\n}\n\nTEST(Mman, Stats) {\n  ThreadState *thr = cur_thread();\n\n  uptr alloc0 = __sanitizer_get_current_allocated_bytes();\n  uptr heap0 = __sanitizer_get_heap_size();\n  uptr free0 = __sanitizer_get_free_bytes();\n  uptr unmapped0 = __sanitizer_get_unmapped_bytes();\n\n  EXPECT_EQ(10U, __sanitizer_get_estimated_allocated_size(10));\n  EXPECT_EQ(20U, __sanitizer_get_estimated_allocated_size(20));\n  EXPECT_EQ(100U, __sanitizer_get_estimated_allocated_size(100));\n\n  char *p = (char*)user_alloc(thr, 0, 10);\n  EXPECT_TRUE(__sanitizer_get_ownership(p));\n  EXPECT_EQ(10U, __sanitizer_get_allocated_size(p));\n\n  EXPECT_EQ(alloc0 + 16, __sanitizer_get_current_allocated_bytes());\n  EXPECT_GE(__sanitizer_get_heap_size(), heap0);\n  EXPECT_EQ(free0, __sanitizer_get_free_bytes());\n  EXPECT_EQ(unmapped0, __sanitizer_get_unmapped_bytes());\n\n  user_free(thr, 0, p);\n\n  EXPECT_EQ(alloc0, __sanitizer_get_current_allocated_bytes());\n  EXPECT_GE(__sanitizer_get_heap_size(), heap0);\n  EXPECT_EQ(free0, __sanitizer_get_free_bytes());\n  EXPECT_EQ(unmapped0, __sanitizer_get_unmapped_bytes());\n}\n\nTEST(Mman, CallocOverflow) {\n#if SANITIZER_DEBUG\n  // EXPECT_DEATH clones a thread with 4K stack,\n  // which is overflown by tsan memory accesses functions in debug mode.\n  return;\n#endif\n  size_t kArraySize = 4096;\n  volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max();\n  volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10;\n  volatile void *p = NULL;\n  EXPECT_DEATH(p = calloc(kArraySize, kArraySize2),\n               \"allocator is terminating the process instead of returning 0\");\n  EXPECT_EQ(0L, p);\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/unit/tsan_mutex_test.cc",
    "content": "//===-- tsan_mutex_test.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_mutex.h\"\n#include \"tsan_mutex.h\"\n#include \"gtest/gtest.h\"\n\nnamespace __tsan {\n\ntemplate<typename MutexType>\nclass TestData {\n public:\n  explicit TestData(MutexType *mtx)\n    : mtx_(mtx) {\n    for (int i = 0; i < kSize; i++)\n      data_[i] = 0;\n  }\n\n  void Write() {\n    Lock l(mtx_);\n    T v0 = data_[0];\n    for (int i = 0; i < kSize; i++) {\n      CHECK_EQ(data_[i], v0);\n      data_[i]++;\n    }\n  }\n\n  void Read() {\n    ReadLock l(mtx_);\n    T v0 = data_[0];\n    for (int i = 0; i < kSize; i++) {\n      CHECK_EQ(data_[i], v0);\n    }\n  }\n\n  void Backoff() {\n    volatile T data[kSize] = {};\n    for (int i = 0; i < kSize; i++) {\n      data[i]++;\n      CHECK_EQ(data[i], 1);\n    }\n  }\n\n private:\n  typedef GenericScopedLock<MutexType> Lock;\n  static const int kSize = 64;\n  typedef u64 T;\n  MutexType *mtx_;\n  char pad_[kCacheLineSize];\n  T data_[kSize];\n};\n\nconst int kThreads = 8;\nconst int kWriteRate = 1024;\n#if SANITIZER_DEBUG\nconst int kIters = 16*1024;\n#else\nconst int kIters = 64*1024;\n#endif\n\ntemplate<typename MutexType>\nstatic void *write_mutex_thread(void *param) {\n  TestData<MutexType> *data = (TestData<MutexType>*)param;\n  for (int i = 0; i < kIters; i++) {\n    data->Write();\n    data->Backoff();\n  }\n  return 0;\n}\n\ntemplate<typename MutexType>\nstatic void *read_mutex_thread(void *param) {\n  TestData<MutexType> *data = (TestData<MutexType>*)param;\n  for (int i = 0; i < kIters; i++) {\n    if ((i % kWriteRate) == 0)\n      data->Write();\n    else\n      data->Read();\n    data->Backoff();\n  }\n  return 0;\n}\n\nTEST(Mutex, Write) {\n  Mutex mtx(MutexTypeAnnotations, StatMtxAnnotations);\n  TestData<Mutex> data(&mtx);\n  pthread_t threads[kThreads];\n  for (int i = 0; i < kThreads; i++)\n    pthread_create(&threads[i], 0, write_mutex_thread<Mutex>, &data);\n  for (int i = 0; i < kThreads; i++)\n    pthread_join(threads[i], 0);\n}\n\nTEST(Mutex, ReadWrite) {\n  Mutex mtx(MutexTypeAnnotations, StatMtxAnnotations);\n  TestData<Mutex> data(&mtx);\n  pthread_t threads[kThreads];\n  for (int i = 0; i < kThreads; i++)\n    pthread_create(&threads[i], 0, read_mutex_thread<Mutex>, &data);\n  for (int i = 0; i < kThreads; i++)\n    pthread_join(threads[i], 0);\n}\n\nTEST(Mutex, SpinWrite) {\n  SpinMutex mtx;\n  TestData<SpinMutex> data(&mtx);\n  pthread_t threads[kThreads];\n  for (int i = 0; i < kThreads; i++)\n    pthread_create(&threads[i], 0, write_mutex_thread<SpinMutex>, &data);\n  for (int i = 0; i < kThreads; i++)\n    pthread_join(threads[i], 0);\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/unit/tsan_mutexset_test.cc",
    "content": "//===-- tsan_mutexset_test.cc ---------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_mutexset.h\"\n#include \"gtest/gtest.h\"\n\nnamespace __tsan {\n\nstatic void Expect(const MutexSet &mset, uptr i, u64 id, bool write, u64 epoch,\n    int count) {\n  MutexSet::Desc d = mset.Get(i);\n  EXPECT_EQ(id, d.id);\n  EXPECT_EQ(write, d.write);\n  EXPECT_EQ(epoch, d.epoch);\n  EXPECT_EQ(count, d.count);\n}\n\nTEST(MutexSet, Basic) {\n  MutexSet mset;\n  EXPECT_EQ(mset.Size(), (uptr)0);\n\n  mset.Add(1, true, 2);\n  EXPECT_EQ(mset.Size(), (uptr)1);\n  Expect(mset, 0, 1, true, 2, 1);\n  mset.Del(1, true);\n  EXPECT_EQ(mset.Size(), (uptr)0);\n\n  mset.Add(3, true, 4);\n  mset.Add(5, false, 6);\n  EXPECT_EQ(mset.Size(), (uptr)2);\n  Expect(mset, 0, 3, true, 4, 1);\n  Expect(mset, 1, 5, false, 6, 1);\n  mset.Del(3, true);\n  EXPECT_EQ(mset.Size(), (uptr)1);\n  mset.Del(5, false);\n  EXPECT_EQ(mset.Size(), (uptr)0);\n}\n\nTEST(MutexSet, DoubleAdd) {\n  MutexSet mset;\n  mset.Add(1, true, 2);\n  EXPECT_EQ(mset.Size(), (uptr)1);\n  Expect(mset, 0, 1, true, 2, 1);\n\n  mset.Add(1, true, 2);\n  EXPECT_EQ(mset.Size(), (uptr)1);\n  Expect(mset, 0, 1, true, 2, 2);\n\n  mset.Del(1, true);\n  EXPECT_EQ(mset.Size(), (uptr)1);\n  Expect(mset, 0, 1, true, 2, 1);\n\n  mset.Del(1, true);\n  EXPECT_EQ(mset.Size(), (uptr)0);\n}\n\nTEST(MutexSet, DoubleDel) {\n  MutexSet mset;\n  mset.Add(1, true, 2);\n  EXPECT_EQ(mset.Size(), (uptr)1);\n  mset.Del(1, true);\n  EXPECT_EQ(mset.Size(), (uptr)0);\n  mset.Del(1, true);\n  EXPECT_EQ(mset.Size(), (uptr)0);\n}\n\nTEST(MutexSet, Remove) {\n  MutexSet mset;\n  mset.Add(1, true, 2);\n  mset.Add(1, true, 2);\n  mset.Add(3, true, 4);\n  mset.Add(3, true, 4);\n  EXPECT_EQ(mset.Size(), (uptr)2);\n\n  mset.Remove(1);\n  EXPECT_EQ(mset.Size(), (uptr)1);\n  Expect(mset, 0, 3, true, 4, 2);\n}\n\nTEST(MutexSet, Full) {\n  MutexSet mset;\n  for (uptr i = 0; i < MutexSet::kMaxSize; i++) {\n    mset.Add(i, true, i + 1);\n  }\n  EXPECT_EQ(mset.Size(), MutexSet::kMaxSize);\n  for (uptr i = 0; i < MutexSet::kMaxSize; i++) {\n    Expect(mset, i, i, true, i + 1, 1);\n  }\n\n  for (uptr i = 0; i < MutexSet::kMaxSize; i++) {\n    mset.Add(i, true, i + 1);\n  }\n  EXPECT_EQ(mset.Size(), MutexSet::kMaxSize);\n  for (uptr i = 0; i < MutexSet::kMaxSize; i++) {\n    Expect(mset, i, i, true, i + 1, 2);\n  }\n}\n\nTEST(MutexSet, Overflow) {\n  MutexSet mset;\n  for (uptr i = 0; i < MutexSet::kMaxSize; i++) {\n    mset.Add(i, true, i + 1);\n    mset.Add(i, true, i + 1);\n  }\n  mset.Add(100, true, 200);\n  EXPECT_EQ(mset.Size(), MutexSet::kMaxSize);\n  for (uptr i = 0; i < MutexSet::kMaxSize; i++) {\n    if (i == 0)\n      Expect(mset, i, MutexSet::kMaxSize - 1,\n             true, MutexSet::kMaxSize, 2);\n    else if (i == MutexSet::kMaxSize - 1)\n      Expect(mset, i, 100, true, 200, 1);\n    else\n      Expect(mset, i, i, true, i + 1, 2);\n  }\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/unit/tsan_shadow_test.cc",
    "content": "//===-- tsan_shadow_test.cc -----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_platform.h\"\n#include \"tsan_rtl.h\"\n#include \"gtest/gtest.h\"\n\nnamespace __tsan {\n\nTEST(Shadow, FastState) {\n  Shadow s(FastState(11, 22));\n  EXPECT_EQ(s.tid(), (u64)11);\n  EXPECT_EQ(s.epoch(), (u64)22);\n  EXPECT_EQ(s.GetIgnoreBit(), false);\n  EXPECT_EQ(s.GetFreedAndReset(), false);\n  EXPECT_EQ(s.GetHistorySize(), 0);\n  EXPECT_EQ(s.addr0(), (u64)0);\n  EXPECT_EQ(s.size(), (u64)1);\n  EXPECT_EQ(s.IsWrite(), true);\n\n  s.IncrementEpoch();\n  EXPECT_EQ(s.epoch(), (u64)23);\n  s.IncrementEpoch();\n  EXPECT_EQ(s.epoch(), (u64)24);\n\n  s.SetIgnoreBit();\n  EXPECT_EQ(s.GetIgnoreBit(), true);\n  s.ClearIgnoreBit();\n  EXPECT_EQ(s.GetIgnoreBit(), false);\n\n  for (int i = 0; i < 8; i++) {\n    s.SetHistorySize(i);\n    EXPECT_EQ(s.GetHistorySize(), i);\n  }\n  s.SetHistorySize(2);\n  s.ClearHistorySize();\n  EXPECT_EQ(s.GetHistorySize(), 0);\n}\n\nTEST(Shadow, Mapping) {\n  static int global;\n  int stack;\n  void *heap = malloc(0);\n  free(heap);\n\n  CHECK(IsAppMem((uptr)&global));\n  CHECK(IsAppMem((uptr)&stack));\n  CHECK(IsAppMem((uptr)heap));\n\n  CHECK(IsShadowMem(MemToShadow((uptr)&global)));\n  CHECK(IsShadowMem(MemToShadow((uptr)&stack)));\n  CHECK(IsShadowMem(MemToShadow((uptr)heap)));\n}\n\nTEST(Shadow, Celling) {\n  u64 aligned_data[4];\n  char *data = (char*)aligned_data;\n  CHECK_EQ((uptr)data % kShadowSize, 0);\n  uptr s0 = MemToShadow((uptr)&data[0]);\n  CHECK_EQ(s0 % kShadowSize, 0);\n  for (unsigned i = 1; i < kShadowCell; i++)\n    CHECK_EQ(s0, MemToShadow((uptr)&data[i]));\n  for (unsigned i = kShadowCell; i < 2*kShadowCell; i++)\n    CHECK_EQ(s0 + kShadowSize*kShadowCnt, MemToShadow((uptr)&data[i]));\n  for (unsigned i = 2*kShadowCell; i < 3*kShadowCell; i++)\n    CHECK_EQ(s0 + 2*kShadowSize*kShadowCnt, MemToShadow((uptr)&data[i]));\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/unit/tsan_stack_test.cc",
    "content": "//===-- tsan_stack_test.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_sync.h\"\n#include \"tsan_rtl.h\"\n#include \"gtest/gtest.h\"\n#include <string.h>\n\nnamespace __tsan {\n\ntemplate <typename StackTraceTy>\nstatic void TestStackTrace(StackTraceTy *trace) {\n  ThreadState thr(0, 0, 0, 0, 0, 0, 0, 0, 0);\n  uptr stack[128];\n  thr.shadow_stack = &stack[0];\n  thr.shadow_stack_pos = &stack[0];\n  thr.shadow_stack_end = &stack[128];\n\n  ObtainCurrentStack(&thr, 0, trace);\n  EXPECT_EQ(0U, trace->size);\n\n  ObtainCurrentStack(&thr, 42, trace);\n  EXPECT_EQ(1U, trace->size);\n  EXPECT_EQ(42U, trace->trace[0]);\n\n  *thr.shadow_stack_pos++ = 100;\n  *thr.shadow_stack_pos++ = 101;\n  ObtainCurrentStack(&thr, 0, trace);\n  EXPECT_EQ(2U, trace->size);\n  EXPECT_EQ(100U, trace->trace[0]);\n  EXPECT_EQ(101U, trace->trace[1]);\n\n  ObtainCurrentStack(&thr, 42, trace);\n  EXPECT_EQ(3U, trace->size);\n  EXPECT_EQ(100U, trace->trace[0]);\n  EXPECT_EQ(101U, trace->trace[1]);\n  EXPECT_EQ(42U, trace->trace[2]);\n}\n\ntemplate<typename StackTraceTy>\nstatic void TestTrim(StackTraceTy *trace) {\n  ThreadState thr(0, 0, 0, 0, 0, 0, 0, 0, 0);\n  const uptr kShadowStackSize = 2 * kStackTraceMax;\n  uptr stack[kShadowStackSize];\n  thr.shadow_stack = &stack[0];\n  thr.shadow_stack_pos = &stack[0];\n  thr.shadow_stack_end = &stack[kShadowStackSize];\n\n  for (uptr i = 0; i < kShadowStackSize; ++i)\n    *thr.shadow_stack_pos++ = 100 + i;\n\n  ObtainCurrentStack(&thr, 0, trace);\n  EXPECT_EQ(kStackTraceMax, trace->size);\n  for (uptr i = 0; i < kStackTraceMax; i++) {\n    EXPECT_EQ(100 + kStackTraceMax + i, trace->trace[i]);\n  }\n\n  ObtainCurrentStack(&thr, 42, trace);\n  EXPECT_EQ(kStackTraceMax, trace->size);\n  for (uptr i = 0; i < kStackTraceMax - 1; i++) {\n    EXPECT_EQ(101 + kStackTraceMax + i, trace->trace[i]);\n  }\n  EXPECT_EQ(42U, trace->trace[kStackTraceMax - 1]);\n}\n\nTEST(StackTrace, BasicVarSize) {\n  VarSizeStackTrace trace;\n  TestStackTrace(&trace);\n}\n\nTEST(StackTrace, BasicBuffered) {\n  BufferedStackTrace trace;\n  TestStackTrace(&trace);\n}\n\nTEST(StackTrace, TrimVarSize) {\n  VarSizeStackTrace trace;\n  TestTrim(&trace);\n}\n\nTEST(StackTrace, TrimBuffered) {\n  BufferedStackTrace trace;\n  TestTrim(&trace);\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/unit/tsan_sync_test.cc",
    "content": "//===-- tsan_sync_test.cc -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_sync.h\"\n#include \"tsan_rtl.h\"\n#include \"gtest/gtest.h\"\n\nnamespace __tsan {\n\nTEST(MetaMap, Basic) {\n  ThreadState *thr = cur_thread();\n  MetaMap *m = &ctx->metamap;\n  u64 block[1] = {};  // fake malloc block\n  m->AllocBlock(thr, 0, (uptr)&block[0], 1 * sizeof(u64));\n  MBlock *mb = m->GetBlock((uptr)&block[0]);\n  EXPECT_NE(mb, (MBlock*)0);\n  EXPECT_EQ(mb->siz, 1 * sizeof(u64));\n  EXPECT_EQ(mb->tid, thr->tid);\n  uptr sz = m->FreeBlock(thr, 0, (uptr)&block[0]);\n  EXPECT_EQ(sz, 1 * sizeof(u64));\n  mb = m->GetBlock((uptr)&block[0]);\n  EXPECT_EQ(mb, (MBlock*)0);\n}\n\nTEST(MetaMap, FreeRange) {\n  ThreadState *thr = cur_thread();\n  MetaMap *m = &ctx->metamap;\n  u64 block[4] = {};  // fake malloc block\n  m->AllocBlock(thr, 0, (uptr)&block[0], 1 * sizeof(u64));\n  m->AllocBlock(thr, 0, (uptr)&block[1], 3 * sizeof(u64));\n  MBlock *mb1 = m->GetBlock((uptr)&block[0]);\n  EXPECT_EQ(mb1->siz, 1 * sizeof(u64));\n  MBlock *mb2 = m->GetBlock((uptr)&block[1]);\n  EXPECT_EQ(mb2->siz, 3 * sizeof(u64));\n  m->FreeRange(thr, 0, (uptr)&block[0], 4 * sizeof(u64));\n  mb1 = m->GetBlock((uptr)&block[0]);\n  EXPECT_EQ(mb1, (MBlock*)0);\n  mb2 = m->GetBlock((uptr)&block[1]);\n  EXPECT_EQ(mb2, (MBlock*)0);\n}\n\nTEST(MetaMap, Sync) {\n  ThreadState *thr = cur_thread();\n  MetaMap *m = &ctx->metamap;\n  u64 block[4] = {};  // fake malloc block\n  m->AllocBlock(thr, 0, (uptr)&block[0], 4 * sizeof(u64));\n  SyncVar *s1 = m->GetIfExistsAndLock((uptr)&block[0]);\n  EXPECT_EQ(s1, (SyncVar*)0);\n  s1 = m->GetOrCreateAndLock(thr, 0, (uptr)&block[0], true);\n  EXPECT_NE(s1, (SyncVar*)0);\n  EXPECT_EQ(s1->addr, (uptr)&block[0]);\n  s1->mtx.Unlock();\n  SyncVar *s2 = m->GetOrCreateAndLock(thr, 0, (uptr)&block[1], false);\n  EXPECT_NE(s2, (SyncVar*)0);\n  EXPECT_EQ(s2->addr, (uptr)&block[1]);\n  s2->mtx.ReadUnlock();\n  m->FreeBlock(thr, 0, (uptr)&block[0]);\n  s1 = m->GetIfExistsAndLock((uptr)&block[0]);\n  EXPECT_EQ(s1, (SyncVar*)0);\n  s2 = m->GetIfExistsAndLock((uptr)&block[1]);\n  EXPECT_EQ(s2, (SyncVar*)0);\n  m->OnThreadIdle(thr);\n}\n\nTEST(MetaMap, MoveMemory) {\n  ThreadState *thr = cur_thread();\n  MetaMap *m = &ctx->metamap;\n  u64 block1[4] = {};  // fake malloc block\n  u64 block2[4] = {};  // fake malloc block\n  m->AllocBlock(thr, 0, (uptr)&block1[0], 3 * sizeof(u64));\n  m->AllocBlock(thr, 0, (uptr)&block1[3], 1 * sizeof(u64));\n  SyncVar *s1 = m->GetOrCreateAndLock(thr, 0, (uptr)&block1[0], true);\n  s1->mtx.Unlock();\n  SyncVar *s2 = m->GetOrCreateAndLock(thr, 0, (uptr)&block1[1], true);\n  s2->mtx.Unlock();\n  m->MoveMemory((uptr)&block1[0], (uptr)&block2[0], 4 * sizeof(u64));\n  MBlock *mb1 = m->GetBlock((uptr)&block1[0]);\n  EXPECT_EQ(mb1, (MBlock*)0);\n  MBlock *mb2 = m->GetBlock((uptr)&block1[3]);\n  EXPECT_EQ(mb2, (MBlock*)0);\n  mb1 = m->GetBlock((uptr)&block2[0]);\n  EXPECT_NE(mb1, (MBlock*)0);\n  EXPECT_EQ(mb1->siz, 3 * sizeof(u64));\n  mb2 = m->GetBlock((uptr)&block2[3]);\n  EXPECT_NE(mb2, (MBlock*)0);\n  EXPECT_EQ(mb2->siz, 1 * sizeof(u64));\n  s1 = m->GetIfExistsAndLock((uptr)&block1[0]);\n  EXPECT_EQ(s1, (SyncVar*)0);\n  s2 = m->GetIfExistsAndLock((uptr)&block1[1]);\n  EXPECT_EQ(s2, (SyncVar*)0);\n  s1 = m->GetIfExistsAndLock((uptr)&block2[0]);\n  EXPECT_NE(s1, (SyncVar*)0);\n  EXPECT_EQ(s1->addr, (uptr)&block2[0]);\n  s1->mtx.Unlock();\n  s2 = m->GetIfExistsAndLock((uptr)&block2[1]);\n  EXPECT_NE(s2, (SyncVar*)0);\n  EXPECT_EQ(s2->addr, (uptr)&block2[1]);\n  s2->mtx.Unlock();\n  m->FreeRange(thr, 0, (uptr)&block2[0], 4 * sizeof(u64));\n}\n\nTEST(MetaMap, ResetSync) {\n  ThreadState *thr = cur_thread();\n  MetaMap *m = &ctx->metamap;\n  u64 block[1] = {};  // fake malloc block\n  m->AllocBlock(thr, 0, (uptr)&block[0], 1 * sizeof(u64));\n  SyncVar *s = m->GetOrCreateAndLock(thr, 0, (uptr)&block[0], true);\n  s->Reset(thr);\n  s->mtx.Unlock();\n  uptr sz = m->FreeBlock(thr, 0, (uptr)&block[0]);\n  EXPECT_EQ(sz, 1 * sizeof(u64));\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/unit/tsan_unit_test_main.cc",
    "content": "//===-- tsan_unit_test_main.cc --------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"gtest/gtest.h\"\n\nint main(int argc, char **argv) {\n  testing::GTEST_FLAG(death_test_style) = \"threadsafe\";\n  testing::InitGoogleTest(&argc, argv);\n  return RUN_ALL_TESTS();\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/tsan/tests/unit/tsan_vector_test.cc",
    "content": "//===-- tsan_vector_test.cc -----------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// This file is a part of ThreadSanitizer (TSan), a race detector.\n//\n//===----------------------------------------------------------------------===//\n#include \"tsan_vector.h\"\n#include \"tsan_rtl.h\"\n#include \"gtest/gtest.h\"\n\nnamespace __tsan {\n\nTEST(Vector, Basic) {\n  Vector<int> v(MBlockScopedBuf);\n  EXPECT_EQ(v.Size(), (uptr)0);\n  v.PushBack(42);\n  EXPECT_EQ(v.Size(), (uptr)1);\n  EXPECT_EQ(v[0], 42);\n  v.PushBack(43);\n  EXPECT_EQ(v.Size(), (uptr)2);\n  EXPECT_EQ(v[0], 42);\n  EXPECT_EQ(v[1], 43);\n}\n\nTEST(Vector, Stride) {\n  Vector<int> v(MBlockScopedBuf);\n  for (int i = 0; i < 1000; i++) {\n    v.PushBack(i);\n    EXPECT_EQ(v.Size(), (uptr)(i + 1));\n    EXPECT_EQ(v[i], i);\n  }\n  for (int i = 0; i < 1000; i++) {\n    EXPECT_EQ(v[i], i);\n  }\n}\n\n}  // namespace __tsan\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/Android.mk",
    "content": "#\n# Copyright (C) 2015 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n#\n\nLOCAL_PATH:= $(call my-dir)\n\nubsan_rtl_files := \\\n    ubsan_diag.cc \\\n    ubsan_init.cc \\\n    ubsan_flags.cc \\\n    ubsan_handlers.cc \\\n    ubsan_value.cc \\\n\nubsan_cxx_rtl_files := \\\n    ubsan_handlers_cxx.cc \\\n    ubsan_type_hash.cc \\\n    ubsan_type_hash_itanium.cc \\\n    ubsan_type_hash_win.cc \\\n\nubsan_rtl_cppflags := \\\n    -fvisibility=hidden \\\n    -fno-exceptions \\\n    -std=c++11 \\\n    -Wall \\\n    -Werror \\\n    -Wno-unused-parameter \\\n    -Wno-non-virtual-dtor \\\n\nubsan_rtl_c_includes := \\\n    external/compiler-rt/lib \\\n\n################################################################################\n# Target modules\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libubsan\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_C_INCLUDES := $(ubsan_rtl_c_includes)\nLOCAL_CPPFLAGS := $(ubsan_rtl_cppflags)\nLOCAL_SRC_FILES := $(ubsan_rtl_files)\nLOCAL_NDK_STL_VARIANT := none\nLOCAL_SDK_VERSION := 19\nLOCAL_SANITIZE := never\nLOCAL_MODULE_TARGET_ARCH := arm arm64 x86\nLOCAL_MULTILIB := both\ninclude $(BUILD_STATIC_LIBRARY)\n\n################################################################################\n# Host modules\n\nifneq ($(HOST_OS),darwin)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libubsan\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_C_INCLUDES := $(ubsan_rtl_c_includes)\nLOCAL_CPPFLAGS := $(ubsan_rtl_cppflags) -fno-rtti\nLOCAL_SRC_FILES := $(ubsan_rtl_files)\nLOCAL_CXX_STL := none\nLOCAL_SANITIZE := never\nLOCAL_MULTILIB := both\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libubsan_standalone\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_C_INCLUDES := $(ubsan_rtl_c_includes)\nLOCAL_CPPFLAGS := $(ubsan_rtl_cppflags) -fno-rtti\nLOCAL_SRC_FILES := $(ubsan_rtl_files)\nLOCAL_WHOLE_STATIC_LIBRARIES := libsan\nLOCAL_CXX_STL := none\nLOCAL_SANITIZE := never\nLOCAL_MULTILIB := both\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libubsan_cxx\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_C_INCLUDES := $(ubsan_rtl_c_includes)\nLOCAL_CPPFLAGS := $(ubsan_rtl_cppflags)\nLOCAL_SRC_FILES := $(ubsan_cxx_rtl_files)\nLOCAL_SANITIZE := never\nLOCAL_MULTILIB := both\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libubsan_standalone_cxx\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_C_INCLUDES := $(ubsan_rtl_c_includes)\nLOCAL_CPPFLAGS := $(ubsan_rtl_cppflags)\nLOCAL_SRC_FILES := $(ubsan_cxx_rtl_files)\nLOCAL_SANITIZE := never\nLOCAL_MULTILIB := both\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\nendif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/CMakeLists.txt",
    "content": "# Build for the undefined behavior sanitizer runtime support library.\n\nset(UBSAN_SOURCES\n  ubsan_diag.cc\n  ubsan_init.cc\n  ubsan_flags.cc\n  ubsan_handlers.cc\n  ubsan_value.cc\n  )\n\nset(UBSAN_STANDALONE_SOURCES\n  ubsan_init_standalone.cc\n  )\n\nset(UBSAN_CXX_SOURCES\n  ubsan_handlers_cxx.cc\n  ubsan_type_hash.cc\n  ubsan_type_hash_itanium.cc\n  ubsan_type_hash_win.cc\n  )\n\ninclude_directories(..)\n\nset(UBSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})\nappend_no_rtti_flag(UBSAN_CFLAGS)\nset(UBSAN_STANDALONE_CFLAGS ${SANITIZER_COMMON_CFLAGS})\nappend_no_rtti_flag(UBSAN_STANDALONE_CFLAGS)\nset(UBSAN_CXXFLAGS ${SANITIZER_COMMON_CFLAGS})\n\nadd_custom_target(ubsan)\n\nif(APPLE)\n  set(UBSAN_COMMON_SOURCES ${UBSAN_SOURCES})\n  if(SANITIZER_CAN_USE_CXXABI)\n    list(APPEND UBSAN_COMMON_SOURCES ${UBSAN_CXX_SOURCES})\n  endif()\n\n  # Common parts of UBSan runtime.\n  add_compiler_rt_object_libraries(RTUbsan\n    OS ${SANITIZER_COMMON_SUPPORTED_OS}\n    ARCHS ${UBSAN_COMMON_SUPPORTED_ARCH}\n    SOURCES ${UBSAN_COMMON_SOURCES}\n    CFLAGS ${UBSAN_CXXFLAGS})\n\n  if(COMPILER_RT_HAS_UBSAN)\n    # Initializer of standalone UBSan runtime.\n    add_compiler_rt_object_libraries(RTUbsan_standalone\n      OS ${SANITIZER_COMMON_SUPPORTED_OS}\n      ARCHS ${UBSAN_SUPPORTED_ARCH}\n      SOURCES ${UBSAN_STANDALONE_SOURCES}\n      CFLAGS ${UBSAN_STANDALONE_CFLAGS})\n\n    add_compiler_rt_runtime(clang_rt.ubsan\n      SHARED\n      OS ${SANITIZER_COMMON_SUPPORTED_OS}\n      ARCHS ${UBSAN_SUPPORTED_ARCH}\n      OBJECT_LIBS RTUbsan\n                  RTUbsan_standalone\n                  RTSanitizerCommon\n                  RTSanitizerCommonLibc\n      PARENT_TARGET ubsan)\n  endif()\n\nelse()\n  # Common parts of UBSan runtime.\n  add_compiler_rt_object_libraries(RTUbsan\n    ARCHS ${UBSAN_COMMON_SUPPORTED_ARCH}\n    SOURCES ${UBSAN_SOURCES} CFLAGS ${UBSAN_CFLAGS})\n  # C++-specific parts of UBSan runtime. Requires a C++ ABI library.\n  add_compiler_rt_object_libraries(RTUbsan_cxx\n    ARCHS ${UBSAN_COMMON_SUPPORTED_ARCH}\n    SOURCES ${UBSAN_CXX_SOURCES} CFLAGS ${UBSAN_CXXFLAGS})\n\n  if(COMPILER_RT_HAS_UBSAN)\n    # Initializer of standalone UBSan runtime.\n    add_compiler_rt_object_libraries(RTUbsan_standalone\n      ARCHS ${UBSAN_SUPPORTED_ARCH}\n      SOURCES ${UBSAN_STANDALONE_SOURCES} CFLAGS ${UBSAN_STANDALONE_CFLAGS})\n    \n    # Standalone UBSan runtimes.\n    add_compiler_rt_runtime(clang_rt.ubsan_standalone\n      STATIC\n      ARCHS ${UBSAN_SUPPORTED_ARCH}\n      OBJECT_LIBS RTSanitizerCommon\n              RTSanitizerCommonLibc\n              RTUbsan\n              RTUbsan_standalone\n      CFLAGS ${UBSAN_CFLAGS}\n      PARENT_TARGET ubsan)\n    \n    add_compiler_rt_runtime(clang_rt.ubsan_standalone_cxx\n      STATIC\n      ARCHS ${UBSAN_SUPPORTED_ARCH}\n      OBJECT_LIBS RTUbsan_cxx\n      CFLAGS ${UBSAN_CXXFLAGS}\n      PARENT_TARGET ubsan)\n\n    if (UNIX)\n      set(ARCHS_FOR_SYMBOLS ${UBSAN_SUPPORTED_ARCH})\n      list(REMOVE_ITEM ARCHS_FOR_SYMBOLS i386 i686)\n      add_sanitizer_rt_symbols(clang_rt.ubsan_standalone\n        ARCHS ${ARCHS_FOR_SYMBOLS}\n        PARENT_TARGET ubsan\n        EXTRA ubsan.syms.extra)\n      add_sanitizer_rt_symbols(clang_rt.ubsan_standalone_cxx\n        ARCHS ${ARCHS_FOR_SYMBOLS}\n        PARENT_TARGET ubsan\n        EXTRA ubsan.syms.extra)\n    endif()\n  endif()\nendif()\n\nadd_dependencies(compiler-rt ubsan)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/Makefile.mk",
    "content": "#===- lib/ubsan/Makefile.mk ---------------------------------*- Makefile -*--===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\nModuleName := ubsan\nSubDirs :=\n\nSources := $(foreach file,$(wildcard $(Dir)/*.cc),$(notdir $(file)))\nStandaloneSources := ubsan_init_standalone.cc\nCXXSources := ubsan_type_hash.cc ubsan_handlers_cxx.cc\nCSources := $(filter-out $(StandaloneSources),$(filter-out $(CXXSources),$(Sources)))\nObjNames := $(Sources:%.cc=%.o)\n\nImplementation := Generic\n\n# FIXME: use automatic dependencies?\nDependencies := $(wildcard $(Dir)/*.h)\nDependencies += $(wildcard $(Dir)/../sanitizer_common/*.h)\n\n# Define a convenience variable for all the ubsan functions.\nUbsanFunctions := $(CSources:%.cc=%)\nUbsanCXXFunctions := $(CXXSources:%.cc=%)\nUbsanStandaloneFunctions := $(StandaloneSources:%.cc=%)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan.syms.extra",
    "content": "__ubsan_*\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_checks.inc",
    "content": "//===-- ubsan_checks.inc ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// List of checks handled by UBSan runtime.\n//\n//===----------------------------------------------------------------------===//\n#ifndef UBSAN_CHECK\n# error \"Define UBSAN_CHECK prior to including this file!\"\n#endif\n\n// UBSAN_CHECK(Name, SummaryKind, FSanitizeFlagName)\n// SummaryKind and FSanitizeFlagName should be string literals.\n\nUBSAN_CHECK(GenericUB, \"undefined-behavior\", \"undefined\")\nUBSAN_CHECK(NullPointerUse, \"null-pointer-use\", \"null\")\nUBSAN_CHECK(MisalignedPointerUse, \"misaligned-pointer-use\", \"alignment\")\nUBSAN_CHECK(InsufficientObjectSize, \"insufficient-object-size\", \"object-size\")\nUBSAN_CHECK(SignedIntegerOverflow, \"signed-integer-overflow\",\n            \"signed-integer-overflow\")\nUBSAN_CHECK(UnsignedIntegerOverflow, \"unsigned-integer-overflow\",\n            \"unsigned-integer-overflow\")\nUBSAN_CHECK(IntegerDivideByZero, \"integer-divide-by-zero\",\n            \"integer-divide-by-zero\")\nUBSAN_CHECK(FloatDivideByZero, \"float-divide-by-zero\", \"float-divide-by-zero\")\nUBSAN_CHECK(InvalidShiftBase, \"invalid-shift-base\", \"shift-base\")\nUBSAN_CHECK(InvalidShiftExponent, \"invalid-shift-exponent\", \"shift-exponent\")\nUBSAN_CHECK(OutOfBoundsIndex, \"out-of-bounds-index\", \"bounds\")\nUBSAN_CHECK(UnreachableCall, \"unreachable-call\", \"unreachable\")\nUBSAN_CHECK(MissingReturn, \"missing-return\", \"return\")\nUBSAN_CHECK(NonPositiveVLAIndex, \"non-positive-vla-index\", \"vla-bound\")\nUBSAN_CHECK(FloatCastOverflow, \"float-cast-overflow\", \"float-cast-overflow\")\nUBSAN_CHECK(InvalidBoolLoad, \"invalid-bool-load\", \"bool\")\nUBSAN_CHECK(InvalidEnumLoad, \"invalid-enum-load\", \"enum\")\nUBSAN_CHECK(FunctionTypeMismatch, \"function-type-mismatch\", \"function\")\nUBSAN_CHECK(InvalidNullReturn, \"invalid-null-return\",\n            \"returns-nonnull-attribute\")\nUBSAN_CHECK(InvalidNullArgument, \"invalid-null-argument\", \"nonnull-attribute\")\nUBSAN_CHECK(DynamicTypeMismatch, \"dynamic-type-mismatch\", \"vptr\")\nUBSAN_CHECK(CFIBadType, \"cfi-bad-type\", \"cfi\")\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_diag.cc",
    "content": "//===-- ubsan_diag.cc -----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Diagnostic reporting for the UBSan runtime.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"ubsan_platform.h\"\n#if CAN_SANITIZE_UB\n#include \"ubsan_diag.h\"\n#include \"ubsan_init.h\"\n#include \"ubsan_flags.h\"\n#include \"sanitizer_common/sanitizer_placement_new.h\"\n#include \"sanitizer_common/sanitizer_report_decorator.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"sanitizer_common/sanitizer_stacktrace_printer.h\"\n#include \"sanitizer_common/sanitizer_suppressions.h\"\n#include \"sanitizer_common/sanitizer_symbolizer.h\"\n#include <stdio.h>\n\nusing namespace __ubsan;\n\nstatic void MaybePrintStackTrace(uptr pc, uptr bp) {\n  // We assume that flags are already parsed, as UBSan runtime\n  // will definitely be called when we print the first diagnostics message.\n  if (!flags()->print_stacktrace)\n    return;\n  // We can only use slow unwind, as we don't have any information about stack\n  // top/bottom.\n  // FIXME: It's better to respect \"fast_unwind_on_fatal\" runtime flag and\n  // fetch stack top/bottom information if we have it (e.g. if we're running\n  // under ASan).\n  if (StackTrace::WillUseFastUnwind(false))\n    return;\n  BufferedStackTrace stack;\n  stack.Unwind(kStackTraceMax, pc, bp, 0, 0, 0, false);\n  stack.Print();\n}\n\nstatic const char *ConvertTypeToString(ErrorType Type) {\n  switch (Type) {\n#define UBSAN_CHECK(Name, SummaryKind, FSanitizeFlagName)                      \\\n  case ErrorType::Name:                                                        \\\n    return SummaryKind;\n#include \"ubsan_checks.inc\"\n#undef UBSAN_CHECK\n  }\n  UNREACHABLE(\"unknown ErrorType!\");\n}\n\nstatic const char *ConvertTypeToFlagName(ErrorType Type) {\n  switch (Type) {\n#define UBSAN_CHECK(Name, SummaryKind, FSanitizeFlagName)                      \\\n  case ErrorType::Name:                                                        \\\n    return FSanitizeFlagName;\n#include \"ubsan_checks.inc\"\n#undef UBSAN_CHECK\n  }\n  UNREACHABLE(\"unknown ErrorType!\");\n}\n\nstatic void MaybeReportErrorSummary(Location Loc, ErrorType Type) {\n  if (!common_flags()->print_summary)\n    return;\n  if (!flags()->report_error_type)\n    Type = ErrorType::GenericUB;\n  const char *ErrorKind = ConvertTypeToString(Type);\n  if (Loc.isSourceLocation()) {\n    SourceLocation SLoc = Loc.getSourceLocation();\n    if (!SLoc.isInvalid()) {\n      AddressInfo AI;\n      AI.file = internal_strdup(SLoc.getFilename());\n      AI.line = SLoc.getLine();\n      AI.column = SLoc.getColumn();\n      AI.function = internal_strdup(\"\");  // Avoid printing ?? as function name.\n      ReportErrorSummary(ErrorKind, AI);\n      AI.Clear();\n      return;\n    }\n  } else if (Loc.isSymbolizedStack()) {\n    const AddressInfo &AI = Loc.getSymbolizedStack()->info;\n    ReportErrorSummary(ErrorKind, AI);\n    return;\n  }\n  ReportErrorSummary(ErrorKind);\n}\n\nnamespace {\nclass Decorator : public SanitizerCommonDecorator {\n public:\n  Decorator() : SanitizerCommonDecorator() {}\n  const char *Highlight() const { return Green(); }\n  const char *EndHighlight() const { return Default(); }\n  const char *Note() const { return Black(); }\n  const char *EndNote() const { return Default(); }\n};\n}\n\nSymbolizedStack *__ubsan::getSymbolizedLocation(uptr PC) {\n  InitAsStandaloneIfNecessary();\n  return Symbolizer::GetOrInit()->SymbolizePC(PC);\n}\n\nDiag &Diag::operator<<(const TypeDescriptor &V) {\n  return AddArg(V.getTypeName());\n}\n\nDiag &Diag::operator<<(const Value &V) {\n  if (V.getType().isSignedIntegerTy())\n    AddArg(V.getSIntValue());\n  else if (V.getType().isUnsignedIntegerTy())\n    AddArg(V.getUIntValue());\n  else if (V.getType().isFloatTy())\n    AddArg(V.getFloatValue());\n  else\n    AddArg(\"<unknown>\");\n  return *this;\n}\n\n/// Hexadecimal printing for numbers too large for Printf to handle directly.\nstatic void PrintHex(UIntMax Val) {\n#if HAVE_INT128_T\n  Printf(\"0x%08x%08x%08x%08x\",\n          (unsigned int)(Val >> 96),\n          (unsigned int)(Val >> 64),\n          (unsigned int)(Val >> 32),\n          (unsigned int)(Val));\n#else\n  UNREACHABLE(\"long long smaller than 64 bits?\");\n#endif\n}\n\nstatic void renderLocation(Location Loc) {\n  InternalScopedString LocBuffer(1024);\n  switch (Loc.getKind()) {\n  case Location::LK_Source: {\n    SourceLocation SLoc = Loc.getSourceLocation();\n    if (SLoc.isInvalid())\n      LocBuffer.append(\"<unknown>\");\n    else\n      RenderSourceLocation(&LocBuffer, SLoc.getFilename(), SLoc.getLine(),\n                           SLoc.getColumn(), common_flags()->symbolize_vs_style,\n                           common_flags()->strip_path_prefix);\n    break;\n  }\n  case Location::LK_Memory:\n    LocBuffer.append(\"%p\", Loc.getMemoryLocation());\n    break;\n  case Location::LK_Symbolized: {\n    const AddressInfo &Info = Loc.getSymbolizedStack()->info;\n    if (Info.file) {\n      RenderSourceLocation(&LocBuffer, Info.file, Info.line, Info.column,\n                           common_flags()->symbolize_vs_style,\n                           common_flags()->strip_path_prefix);\n    } else if (Info.module) {\n      RenderModuleLocation(&LocBuffer, Info.module, Info.module_offset,\n                           common_flags()->strip_path_prefix);\n    } else {\n      LocBuffer.append(\"%p\", Info.address);\n    }\n    break;\n  }\n  case Location::LK_Null:\n    LocBuffer.append(\"<unknown>\");\n    break;\n  }\n  Printf(\"%s:\", LocBuffer.data());\n}\n\nstatic void renderText(const char *Message, const Diag::Arg *Args) {\n  for (const char *Msg = Message; *Msg; ++Msg) {\n    if (*Msg != '%') {\n      char Buffer[64];\n      unsigned I;\n      for (I = 0; Msg[I] && Msg[I] != '%' && I != 63; ++I)\n        Buffer[I] = Msg[I];\n      Buffer[I] = '\\0';\n      Printf(Buffer);\n      Msg += I - 1;\n    } else {\n      const Diag::Arg &A = Args[*++Msg - '0'];\n      switch (A.Kind) {\n      case Diag::AK_String:\n        Printf(\"%s\", A.String);\n        break;\n      case Diag::AK_TypeName: {\n        if (SANITIZER_WINDOWS)\n          // The Windows implementation demangles names early.\n          Printf(\"'%s'\", A.String);\n        else\n          Printf(\"'%s'\", Symbolizer::GetOrInit()->Demangle(A.String));\n        break;\n      }\n      case Diag::AK_SInt:\n        // 'long long' is guaranteed to be at least 64 bits wide.\n        if (A.SInt >= INT64_MIN && A.SInt <= INT64_MAX)\n          Printf(\"%lld\", (long long)A.SInt);\n        else\n          PrintHex(A.SInt);\n        break;\n      case Diag::AK_UInt:\n        if (A.UInt <= UINT64_MAX)\n          Printf(\"%llu\", (unsigned long long)A.UInt);\n        else\n          PrintHex(A.UInt);\n        break;\n      case Diag::AK_Float: {\n        // FIXME: Support floating-point formatting in sanitizer_common's\n        //        printf, and stop using snprintf here.\n        char Buffer[32];\n#if SANITIZER_WINDOWS\n        sprintf_s(Buffer, sizeof(Buffer), \"%Lg\", (long double)A.Float);\n#else\n        snprintf(Buffer, sizeof(Buffer), \"%Lg\", (long double)A.Float);\n#endif\n        Printf(\"%s\", Buffer);\n        break;\n      }\n      case Diag::AK_Pointer:\n        Printf(\"%p\", A.Pointer);\n        break;\n      }\n    }\n  }\n}\n\n/// Find the earliest-starting range in Ranges which ends after Loc.\nstatic Range *upperBound(MemoryLocation Loc, Range *Ranges,\n                         unsigned NumRanges) {\n  Range *Best = 0;\n  for (unsigned I = 0; I != NumRanges; ++I)\n    if (Ranges[I].getEnd().getMemoryLocation() > Loc &&\n        (!Best ||\n         Best->getStart().getMemoryLocation() >\n         Ranges[I].getStart().getMemoryLocation()))\n      Best = &Ranges[I];\n  return Best;\n}\n\nstatic inline uptr subtractNoOverflow(uptr LHS, uptr RHS) {\n  return (LHS < RHS) ? 0 : LHS - RHS;\n}\n\nstatic inline uptr addNoOverflow(uptr LHS, uptr RHS) {\n  const uptr Limit = (uptr)-1;\n  return (LHS > Limit - RHS) ? Limit : LHS + RHS;\n}\n\n/// Render a snippet of the address space near a location.\nstatic void renderMemorySnippet(const Decorator &Decor, MemoryLocation Loc,\n                                Range *Ranges, unsigned NumRanges,\n                                const Diag::Arg *Args) {\n  // Show at least the 8 bytes surrounding Loc.\n  const unsigned MinBytesNearLoc = 4;\n  MemoryLocation Min = subtractNoOverflow(Loc, MinBytesNearLoc);\n  MemoryLocation Max = addNoOverflow(Loc, MinBytesNearLoc);\n  MemoryLocation OrigMin = Min;\n  for (unsigned I = 0; I < NumRanges; ++I) {\n    Min = __sanitizer::Min(Ranges[I].getStart().getMemoryLocation(), Min);\n    Max = __sanitizer::Max(Ranges[I].getEnd().getMemoryLocation(), Max);\n  }\n\n  // If we have too many interesting bytes, prefer to show bytes after Loc.\n  const unsigned BytesToShow = 32;\n  if (Max - Min > BytesToShow)\n    Min = __sanitizer::Min(Max - BytesToShow, OrigMin);\n  Max = addNoOverflow(Min, BytesToShow);\n\n  if (!IsAccessibleMemoryRange(Min, Max - Min)) {\n    Printf(\"<memory cannot be printed>\\n\");\n    return;\n  }\n\n  // Emit data.\n  for (uptr P = Min; P != Max; ++P) {\n    unsigned char C = *reinterpret_cast<const unsigned char*>(P);\n    Printf(\"%s%02x\", (P % 8 == 0) ? \"  \" : \" \", C);\n  }\n  Printf(\"\\n\");\n\n  // Emit highlights.\n  Printf(Decor.Highlight());\n  Range *InRange = upperBound(Min, Ranges, NumRanges);\n  for (uptr P = Min; P != Max; ++P) {\n    char Pad = ' ', Byte = ' ';\n    if (InRange && InRange->getEnd().getMemoryLocation() == P)\n      InRange = upperBound(P, Ranges, NumRanges);\n    if (!InRange && P > Loc)\n      break;\n    if (InRange && InRange->getStart().getMemoryLocation() < P)\n      Pad = '~';\n    if (InRange && InRange->getStart().getMemoryLocation() <= P)\n      Byte = '~';\n    char Buffer[] = { Pad, Pad, P == Loc ? '^' : Byte, Byte, 0 };\n    Printf((P % 8 == 0) ? Buffer : &Buffer[1]);\n  }\n  Printf(\"%s\\n\", Decor.EndHighlight());\n\n  // Go over the line again, and print names for the ranges.\n  InRange = 0;\n  unsigned Spaces = 0;\n  for (uptr P = Min; P != Max; ++P) {\n    if (!InRange || InRange->getEnd().getMemoryLocation() == P)\n      InRange = upperBound(P, Ranges, NumRanges);\n    if (!InRange)\n      break;\n\n    Spaces += (P % 8) == 0 ? 2 : 1;\n\n    if (InRange && InRange->getStart().getMemoryLocation() == P) {\n      while (Spaces--)\n        Printf(\" \");\n      renderText(InRange->getText(), Args);\n      Printf(\"\\n\");\n      // FIXME: We only support naming one range for now!\n      break;\n    }\n\n    Spaces += 2;\n  }\n\n  // FIXME: Print names for anything we can identify within the line:\n  //\n  //  * If we can identify the memory itself as belonging to a particular\n  //    global, stack variable, or dynamic allocation, then do so.\n  //\n  //  * If we have a pointer-size, pointer-aligned range highlighted,\n  //    determine whether the value of that range is a pointer to an\n  //    entity which we can name, and if so, print that name.\n  //\n  // This needs an external symbolizer, or (preferably) ASan instrumentation.\n}\n\nDiag::~Diag() {\n  // All diagnostics should be printed under report mutex.\n  CommonSanitizerReportMutex.CheckLocked();\n  Decorator Decor;\n  Printf(Decor.Bold());\n\n  renderLocation(Loc);\n\n  switch (Level) {\n  case DL_Error:\n    Printf(\"%s runtime error: %s%s\",\n           Decor.Warning(), Decor.EndWarning(), Decor.Bold());\n    break;\n\n  case DL_Note:\n    Printf(\"%s note: %s\", Decor.Note(), Decor.EndNote());\n    break;\n  }\n\n  renderText(Message, Args);\n\n  Printf(\"%s\\n\", Decor.Default());\n\n  if (Loc.isMemoryLocation())\n    renderMemorySnippet(Decor, Loc.getMemoryLocation(), Ranges,\n                        NumRanges, Args);\n}\n\nScopedReport::ScopedReport(ReportOptions Opts, Location SummaryLoc,\n                           ErrorType Type)\n    : Opts(Opts), SummaryLoc(SummaryLoc), Type(Type) {\n  InitAsStandaloneIfNecessary();\n  CommonSanitizerReportMutex.Lock();\n}\n\nScopedReport::~ScopedReport() {\n  MaybePrintStackTrace(Opts.pc, Opts.bp);\n  MaybeReportErrorSummary(SummaryLoc, Type);\n  CommonSanitizerReportMutex.Unlock();\n  if (flags()->halt_on_error)\n    Die();\n}\n\nALIGNED(64) static char suppression_placeholder[sizeof(SuppressionContext)];\nstatic SuppressionContext *suppression_ctx = nullptr;\nstatic const char kVptrCheck[] = \"vptr_check\";\nstatic const char *kSuppressionTypes[] = {\n#define UBSAN_CHECK(Name, SummaryKind, FSanitizeFlagName) FSanitizeFlagName,\n#include \"ubsan_checks.inc\"\n#undef UBSAN_CHECK\n    kVptrCheck,\n};\n\nvoid __ubsan::InitializeSuppressions() {\n  CHECK_EQ(nullptr, suppression_ctx);\n  suppression_ctx = new (suppression_placeholder) // NOLINT\n      SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes));\n  suppression_ctx->ParseFromFile(flags()->suppressions);\n}\n\nbool __ubsan::IsVptrCheckSuppressed(const char *TypeName) {\n  InitAsStandaloneIfNecessary();\n  CHECK(suppression_ctx);\n  Suppression *s;\n  return suppression_ctx->Match(TypeName, kVptrCheck, &s);\n}\n\nbool __ubsan::IsPCSuppressed(ErrorType ET, uptr PC, const char *Filename) {\n  InitAsStandaloneIfNecessary();\n  CHECK(suppression_ctx);\n  const char *SuppType = ConvertTypeToFlagName(ET);\n  // Fast path: don't symbolize PC if there is no suppressions for given UB\n  // type.\n  if (!suppression_ctx->HasSuppressionType(SuppType))\n    return false;\n  Suppression *s = nullptr;\n  // Suppress by file name known to runtime.\n  if (Filename != nullptr && suppression_ctx->Match(Filename, SuppType, &s))\n    return true;\n  // Suppress by module name.\n  if (const char *Module = Symbolizer::GetOrInit()->GetModuleNameForPc(PC)) {\n    if (suppression_ctx->Match(Module, SuppType, &s))\n      return true;\n  }\n  // Suppress by function or source file name from debug info.\n  SymbolizedStackHolder Stack(Symbolizer::GetOrInit()->SymbolizePC(PC));\n  const AddressInfo &AI = Stack.get()->info;\n  return suppression_ctx->Match(AI.function, SuppType, &s) ||\n         suppression_ctx->Match(AI.file, SuppType, &s);\n}\n\n#endif  // CAN_SANITIZE_UB\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_diag.h",
    "content": "//===-- ubsan_diag.h --------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Diagnostics emission for Clang's undefined behavior sanitizer.\n//\n//===----------------------------------------------------------------------===//\n#ifndef UBSAN_DIAG_H\n#define UBSAN_DIAG_H\n\n#include \"ubsan_value.h\"\n#include \"sanitizer_common/sanitizer_stacktrace.h\"\n#include \"sanitizer_common/sanitizer_symbolizer.h\"\n\nnamespace __ubsan {\n\nclass SymbolizedStackHolder {\n  SymbolizedStack *Stack;\n\n  void clear() {\n    if (Stack)\n      Stack->ClearAll();\n  }\n\npublic:\n  explicit SymbolizedStackHolder(SymbolizedStack *Stack = nullptr)\n      : Stack(Stack) {}\n  ~SymbolizedStackHolder() { clear(); }\n  void reset(SymbolizedStack *S) {\n    if (Stack != S)\n      clear();\n    Stack = S;\n  }\n  const SymbolizedStack *get() const { return Stack; }\n};\n\nSymbolizedStack *getSymbolizedLocation(uptr PC);\n\ninline SymbolizedStack *getCallerLocation(uptr CallerPC) {\n  CHECK(CallerPC);\n  uptr PC = StackTrace::GetPreviousInstructionPc(CallerPC);\n  return getSymbolizedLocation(PC);\n}\n\n/// A location of some data within the program's address space.\ntypedef uptr MemoryLocation;\n\n/// \\brief Location at which a diagnostic can be emitted. Either a\n/// SourceLocation, a MemoryLocation, or a SymbolizedStack.\nclass Location {\npublic:\n  enum LocationKind { LK_Null, LK_Source, LK_Memory, LK_Symbolized };\n\nprivate:\n  LocationKind Kind;\n  // FIXME: In C++11, wrap these in an anonymous union.\n  SourceLocation SourceLoc;\n  MemoryLocation MemoryLoc;\n  const SymbolizedStack *SymbolizedLoc;  // Not owned.\n\npublic:\n  Location() : Kind(LK_Null) {}\n  Location(SourceLocation Loc) :\n    Kind(LK_Source), SourceLoc(Loc) {}\n  Location(MemoryLocation Loc) :\n    Kind(LK_Memory), MemoryLoc(Loc) {}\n  // SymbolizedStackHolder must outlive Location object.\n  Location(const SymbolizedStackHolder &Stack) :\n    Kind(LK_Symbolized), SymbolizedLoc(Stack.get()) {}\n\n  LocationKind getKind() const { return Kind; }\n\n  bool isSourceLocation() const { return Kind == LK_Source; }\n  bool isMemoryLocation() const { return Kind == LK_Memory; }\n  bool isSymbolizedStack() const { return Kind == LK_Symbolized; }\n\n  SourceLocation getSourceLocation() const {\n    CHECK(isSourceLocation());\n    return SourceLoc;\n  }\n  MemoryLocation getMemoryLocation() const {\n    CHECK(isMemoryLocation());\n    return MemoryLoc;\n  }\n  const SymbolizedStack *getSymbolizedStack() const {\n    CHECK(isSymbolizedStack());\n    return SymbolizedLoc;\n  }\n};\n\n/// A diagnostic severity level.\nenum DiagLevel {\n  DL_Error, ///< An error.\n  DL_Note   ///< A note, attached to a prior diagnostic.\n};\n\n/// \\brief Annotation for a range of locations in a diagnostic.\nclass Range {\n  Location Start, End;\n  const char *Text;\n\npublic:\n  Range() : Start(), End(), Text() {}\n  Range(MemoryLocation Start, MemoryLocation End, const char *Text)\n    : Start(Start), End(End), Text(Text) {}\n  Location getStart() const { return Start; }\n  Location getEnd() const { return End; }\n  const char *getText() const { return Text; }\n};\n\n/// \\brief A C++ type name. Really just a strong typedef for 'const char*'.\nclass TypeName {\n  const char *Name;\npublic:\n  TypeName(const char *Name) : Name(Name) {}\n  const char *getName() const { return Name; }\n};\n\n/// \\brief Representation of an in-flight diagnostic.\n///\n/// Temporary \\c Diag instances are created by the handler routines to\n/// accumulate arguments for a diagnostic. The destructor emits the diagnostic\n/// message.\nclass Diag {\n  /// The location at which the problem occurred.\n  Location Loc;\n\n  /// The diagnostic level.\n  DiagLevel Level;\n\n  /// The message which will be emitted, with %0, %1, ... placeholders for\n  /// arguments.\n  const char *Message;\n\npublic:\n  /// Kinds of arguments, corresponding to members of \\c Arg's union.\n  enum ArgKind {\n    AK_String, ///< A string argument, displayed as-is.\n    AK_TypeName,///< A C++ type name, possibly demangled before display.\n    AK_UInt,   ///< An unsigned integer argument.\n    AK_SInt,   ///< A signed integer argument.\n    AK_Float,  ///< A floating-point argument.\n    AK_Pointer ///< A pointer argument, displayed in hexadecimal.\n  };\n\n  /// An individual diagnostic message argument.\n  struct Arg {\n    Arg() {}\n    Arg(const char *String) : Kind(AK_String), String(String) {}\n    Arg(TypeName TN) : Kind(AK_TypeName), String(TN.getName()) {}\n    Arg(UIntMax UInt) : Kind(AK_UInt), UInt(UInt) {}\n    Arg(SIntMax SInt) : Kind(AK_SInt), SInt(SInt) {}\n    Arg(FloatMax Float) : Kind(AK_Float), Float(Float) {}\n    Arg(const void *Pointer) : Kind(AK_Pointer), Pointer(Pointer) {}\n\n    ArgKind Kind;\n    union {\n      const char *String;\n      UIntMax UInt;\n      SIntMax SInt;\n      FloatMax Float;\n      const void *Pointer;\n    };\n  };\n\nprivate:\n  static const unsigned MaxArgs = 5;\n  static const unsigned MaxRanges = 1;\n\n  /// The arguments which have been added to this diagnostic so far.\n  Arg Args[MaxArgs];\n  unsigned NumArgs;\n\n  /// The ranges which have been added to this diagnostic so far.\n  Range Ranges[MaxRanges];\n  unsigned NumRanges;\n\n  Diag &AddArg(Arg A) {\n    CHECK(NumArgs != MaxArgs);\n    Args[NumArgs++] = A;\n    return *this;\n  }\n\n  Diag &AddRange(Range A) {\n    CHECK(NumRanges != MaxRanges);\n    Ranges[NumRanges++] = A;\n    return *this;\n  }\n\n  /// \\c Diag objects are not copyable.\n  Diag(const Diag &); // NOT IMPLEMENTED\n  Diag &operator=(const Diag &);\n\npublic:\n  Diag(Location Loc, DiagLevel Level, const char *Message)\n    : Loc(Loc), Level(Level), Message(Message), NumArgs(0), NumRanges(0) {}\n  ~Diag();\n\n  Diag &operator<<(const char *Str) { return AddArg(Str); }\n  Diag &operator<<(TypeName TN) { return AddArg(TN); }\n  Diag &operator<<(unsigned long long V) { return AddArg(UIntMax(V)); }\n  Diag &operator<<(const void *V) { return AddArg(V); }\n  Diag &operator<<(const TypeDescriptor &V);\n  Diag &operator<<(const Value &V);\n  Diag &operator<<(const Range &R) { return AddRange(R); }\n};\n\nstruct ReportOptions {\n  // If FromUnrecoverableHandler is specified, UBSan runtime handler is not\n  // expected to return.\n  bool FromUnrecoverableHandler;\n  /// pc/bp are used to unwind the stack trace.\n  uptr pc;\n  uptr bp;\n};\n\nenum class ErrorType {\n#define UBSAN_CHECK(Name, SummaryKind, FSanitizeFlagName) Name,\n#include \"ubsan_checks.inc\"\n#undef UBSAN_CHECK\n};\n\nbool ignoreReport(SourceLocation SLoc, ReportOptions Opts, ErrorType ET);\n\n#define GET_REPORT_OPTIONS(unrecoverable_handler) \\\n    GET_CALLER_PC_BP; \\\n    ReportOptions Opts = {unrecoverable_handler, pc, bp}\n\n/// \\brief Instantiate this class before printing diagnostics in the error\n/// report. This class ensures that reports from different threads and from\n/// different sanitizers won't be mixed.\nclass ScopedReport {\n  ReportOptions Opts;\n  Location SummaryLoc;\n  ErrorType Type;\n\npublic:\n  ScopedReport(ReportOptions Opts, Location SummaryLoc, ErrorType Type);\n  ~ScopedReport();\n};\n\nvoid InitializeSuppressions();\nbool IsVptrCheckSuppressed(const char *TypeName);\n// Sometimes UBSan runtime can know filename from handlers arguments, even if\n// debug info is missing.\nbool IsPCSuppressed(ErrorType ET, uptr PC, const char *Filename);\n\n} // namespace __ubsan\n\n#endif // UBSAN_DIAG_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_flags.cc",
    "content": "//===-- ubsan_flags.cc ----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Runtime flags for UndefinedBehaviorSanitizer.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"ubsan_platform.h\"\n#if CAN_SANITIZE_UB\n#include \"ubsan_flags.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_flags.h\"\n#include \"sanitizer_common/sanitizer_flag_parser.h\"\n\nnamespace __ubsan {\n\nconst char *MaybeCallUbsanDefaultOptions() {\n  return (&__ubsan_default_options) ? __ubsan_default_options() : \"\";\n}\n\nFlags ubsan_flags;\n\nvoid Flags::SetDefaults() {\n#define UBSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;\n#include \"ubsan_flags.inc\"\n#undef UBSAN_FLAG\n}\n\nvoid RegisterUbsanFlags(FlagParser *parser, Flags *f) {\n#define UBSAN_FLAG(Type, Name, DefaultValue, Description) \\\n  RegisterFlag(parser, #Name, Description, &f->Name);\n#include \"ubsan_flags.inc\"\n#undef UBSAN_FLAG\n}\n\nvoid InitializeFlags() {\n  SetCommonFlagsDefaults();\n  {\n    CommonFlags cf;\n    cf.CopyFrom(*common_flags());\n    cf.print_summary = false;\n    OverrideCommonFlags(cf);\n  }\n\n  Flags *f = flags();\n  f->SetDefaults();\n\n  FlagParser parser;\n  RegisterCommonFlags(&parser);\n  RegisterUbsanFlags(&parser, f);\n\n  // Override from user-specified string.\n  parser.ParseString(MaybeCallUbsanDefaultOptions());\n  // Override from environment variable.\n  parser.ParseString(GetEnv(\"UBSAN_OPTIONS\"));\n  SetVerbosity(common_flags()->verbosity);\n  if (Verbosity()) ReportUnrecognizedFlags();\n\n  if (common_flags()->help) parser.PrintFlagDescriptions();\n}\n\n}  // namespace __ubsan\n\nextern \"C\" {\n\n#if !SANITIZER_SUPPORTS_WEAK_HOOKS\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nconst char *__ubsan_default_options() { return \"\"; }\n#endif\n\n#if SANITIZER_WINDOWS\nconst char *__ubsan_default_default_options() { return \"\"; }\n# ifdef _WIN64\n#  pragma comment(linker, \"/alternatename:__ubsan_default_options=__ubsan_default_default_options\")\n# else\n#  pragma comment(linker, \"/alternatename:___ubsan_default_options=___ubsan_default_default_options\")\n# endif\n#endif\n\n}  // extern \"C\"\n\n#endif  // CAN_SANITIZE_UB\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_flags.h",
    "content": "//===-- ubsan_flags.h -------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Runtime flags for UndefinedBehaviorSanitizer.\n//\n//===----------------------------------------------------------------------===//\n#ifndef UBSAN_FLAGS_H\n#define UBSAN_FLAGS_H\n\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n\nnamespace __sanitizer {\nclass FlagParser;\n}\n\nnamespace __ubsan {\n\nstruct Flags {\n#define UBSAN_FLAG(Type, Name, DefaultValue, Description) Type Name;\n#include \"ubsan_flags.inc\"\n#undef UBSAN_FLAG\n\n  void SetDefaults();\n};\n\nextern Flags ubsan_flags;\ninline Flags *flags() { return &ubsan_flags; }\n\nvoid InitializeFlags();\nvoid RegisterUbsanFlags(FlagParser *parser, Flags *f);\n\nconst char *MaybeCallUbsanDefaultOptions();\n\n}  // namespace __ubsan\n\nextern \"C\" {\n// Users may provide their own implementation of __ubsan_default_options to\n// override the default flag values.\nSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE\nconst char *__ubsan_default_options();\n}  // extern \"C\"\n\n#endif  // UBSAN_FLAGS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_flags.inc",
    "content": "//===-- ubsan_flags.inc -----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// UBSan runtime flags.\n//\n//===----------------------------------------------------------------------===//\n#ifndef UBSAN_FLAG\n# error \"Define UBSAN_FLAG prior to including this file!\"\n#endif\n\n// UBSAN_FLAG(Type, Name, DefaultValue, Description)\n// See COMMON_FLAG in sanitizer_flags.inc for more details.\n\nUBSAN_FLAG(bool, halt_on_error, false,\n           \"Crash the program after printing the first error report\")\nUBSAN_FLAG(bool, print_stacktrace, false,\n           \"Include full stacktrace into an error report\")\nUBSAN_FLAG(const char *, suppressions, \"\", \"Suppressions file name.\")\nUBSAN_FLAG(bool, report_error_type, false,\n        \"Print specific error type instead of 'undefined-behavior' in summary.\")\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_handlers.cc",
    "content": "//===-- ubsan_handlers.cc -------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Error logging entry points for the UBSan runtime.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"ubsan_platform.h\"\n#if CAN_SANITIZE_UB\n#include \"ubsan_handlers.h\"\n#include \"ubsan_diag.h\"\n\n#include \"sanitizer_common/sanitizer_common.h\"\n\nusing namespace __sanitizer;\nusing namespace __ubsan;\n\nnamespace __ubsan {\nbool ignoreReport(SourceLocation SLoc, ReportOptions Opts, ErrorType ET) {\n  // We are not allowed to skip error report: if we are in unrecoverable\n  // handler, we have to terminate the program right now, and therefore\n  // have to print some diagnostic.\n  //\n  // Even if source location is disabled, it doesn't mean that we have\n  // already report an error to the user: some concurrently running\n  // thread could have acquired it, but not yet printed the report.\n  if (Opts.FromUnrecoverableHandler)\n    return false;\n  return SLoc.isDisabled() || IsPCSuppressed(ET, Opts.pc, SLoc.getFilename());\n}\n\nconst char *TypeCheckKinds[] = {\n    \"load of\", \"store to\", \"reference binding to\", \"member access within\",\n    \"member call on\", \"constructor call on\", \"downcast of\", \"downcast of\",\n    \"upcast of\", \"cast to virtual base of\"};\n}\n\nstatic void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer,\n                                   ReportOptions Opts) {\n  Location Loc = Data->Loc.acquire();\n\n  ErrorType ET;\n  if (!Pointer)\n    ET = ErrorType::NullPointerUse;\n  else if (Data->Alignment && (Pointer & (Data->Alignment - 1)))\n    ET = ErrorType::MisalignedPointerUse;\n  else\n    ET = ErrorType::InsufficientObjectSize;\n\n  // Use the SourceLocation from Data to track deduplication, even if it's\n  // invalid.\n  if (ignoreReport(Loc.getSourceLocation(), Opts, ET))\n    return;\n\n  SymbolizedStackHolder FallbackLoc;\n  if (Data->Loc.isInvalid()) {\n    FallbackLoc.reset(getCallerLocation(Opts.pc));\n    Loc = FallbackLoc;\n  }\n\n  ScopedReport R(Opts, Loc, ET);\n\n  switch (ET) {\n  case ErrorType::NullPointerUse:\n    Diag(Loc, DL_Error, \"%0 null pointer of type %1\")\n        << TypeCheckKinds[Data->TypeCheckKind] << Data->Type;\n    break;\n  case ErrorType::MisalignedPointerUse:\n    Diag(Loc, DL_Error, \"%0 misaligned address %1 for type %3, \"\n                        \"which requires %2 byte alignment\")\n        << TypeCheckKinds[Data->TypeCheckKind] << (void *)Pointer\n        << Data->Alignment << Data->Type;\n    break;\n  case ErrorType::InsufficientObjectSize:\n    Diag(Loc, DL_Error, \"%0 address %1 with insufficient space \"\n                        \"for an object of type %2\")\n        << TypeCheckKinds[Data->TypeCheckKind] << (void *)Pointer << Data->Type;\n    break;\n  default:\n    UNREACHABLE(\"unexpected error type!\");\n  }\n\n  if (Pointer)\n    Diag(Pointer, DL_Note, \"pointer points here\");\n}\n\nvoid __ubsan::__ubsan_handle_type_mismatch(TypeMismatchData *Data,\n                                           ValueHandle Pointer) {\n  GET_REPORT_OPTIONS(false);\n  handleTypeMismatchImpl(Data, Pointer, Opts);\n}\nvoid __ubsan::__ubsan_handle_type_mismatch_abort(TypeMismatchData *Data,\n                                                 ValueHandle Pointer) {\n  GET_REPORT_OPTIONS(true);\n  handleTypeMismatchImpl(Data, Pointer, Opts);\n  Die();\n}\n\n/// \\brief Common diagnostic emission for various forms of integer overflow.\ntemplate <typename T>\nstatic void handleIntegerOverflowImpl(OverflowData *Data, ValueHandle LHS,\n                                      const char *Operator, T RHS,\n                                      ReportOptions Opts) {\n  SourceLocation Loc = Data->Loc.acquire();\n  bool IsSigned = Data->Type.isSignedIntegerTy();\n  ErrorType ET = IsSigned ? ErrorType::SignedIntegerOverflow\n                          : ErrorType::UnsignedIntegerOverflow;\n\n  if (ignoreReport(Loc, Opts, ET))\n    return;\n\n  ScopedReport R(Opts, Loc, ET);\n\n  Diag(Loc, DL_Error, \"%0 integer overflow: \"\n                      \"%1 %2 %3 cannot be represented in type %4\")\n    << (IsSigned ? \"signed\" : \"unsigned\")\n    << Value(Data->Type, LHS) << Operator << RHS << Data->Type;\n}\n\n#define UBSAN_OVERFLOW_HANDLER(handler_name, op, unrecoverable)                \\\n  void __ubsan::handler_name(OverflowData *Data, ValueHandle LHS,              \\\n                             ValueHandle RHS) {                                \\\n    GET_REPORT_OPTIONS(unrecoverable);                                         \\\n    handleIntegerOverflowImpl(Data, LHS, op, Value(Data->Type, RHS), Opts);    \\\n    if (unrecoverable)                                                         \\\n      Die();                                                                   \\\n  }\n\nUBSAN_OVERFLOW_HANDLER(__ubsan_handle_add_overflow, \"+\", false)\nUBSAN_OVERFLOW_HANDLER(__ubsan_handle_add_overflow_abort, \"+\", true)\nUBSAN_OVERFLOW_HANDLER(__ubsan_handle_sub_overflow, \"-\", false)\nUBSAN_OVERFLOW_HANDLER(__ubsan_handle_sub_overflow_abort, \"-\", true)\nUBSAN_OVERFLOW_HANDLER(__ubsan_handle_mul_overflow, \"*\", false)\nUBSAN_OVERFLOW_HANDLER(__ubsan_handle_mul_overflow_abort, \"*\", true)\n\nstatic void handleNegateOverflowImpl(OverflowData *Data, ValueHandle OldVal,\n                                     ReportOptions Opts) {\n  SourceLocation Loc = Data->Loc.acquire();\n  bool IsSigned = Data->Type.isSignedIntegerTy();\n  ErrorType ET = IsSigned ? ErrorType::SignedIntegerOverflow\n                          : ErrorType::UnsignedIntegerOverflow;\n\n  if (ignoreReport(Loc, Opts, ET))\n    return;\n\n  ScopedReport R(Opts, Loc, ET);\n\n  if (IsSigned)\n    Diag(Loc, DL_Error,\n         \"negation of %0 cannot be represented in type %1; \"\n         \"cast to an unsigned type to negate this value to itself\")\n        << Value(Data->Type, OldVal) << Data->Type;\n  else\n    Diag(Loc, DL_Error, \"negation of %0 cannot be represented in type %1\")\n        << Value(Data->Type, OldVal) << Data->Type;\n}\n\nvoid __ubsan::__ubsan_handle_negate_overflow(OverflowData *Data,\n                                             ValueHandle OldVal) {\n  GET_REPORT_OPTIONS(false);\n  handleNegateOverflowImpl(Data, OldVal, Opts);\n}\nvoid __ubsan::__ubsan_handle_negate_overflow_abort(OverflowData *Data,\n                                                    ValueHandle OldVal) {\n  GET_REPORT_OPTIONS(true);\n  handleNegateOverflowImpl(Data, OldVal, Opts);\n  Die();\n}\n\nstatic void handleDivremOverflowImpl(OverflowData *Data, ValueHandle LHS,\n                                     ValueHandle RHS, ReportOptions Opts) {\n  SourceLocation Loc = Data->Loc.acquire();\n  Value LHSVal(Data->Type, LHS);\n  Value RHSVal(Data->Type, RHS);\n\n  ErrorType ET;\n  if (RHSVal.isMinusOne())\n    ET = ErrorType::SignedIntegerOverflow;\n  else if (Data->Type.isIntegerTy())\n    ET = ErrorType::IntegerDivideByZero;\n  else\n    ET = ErrorType::FloatDivideByZero;\n\n  if (ignoreReport(Loc, Opts, ET))\n    return;\n\n  ScopedReport R(Opts, Loc, ET);\n\n  switch (ET) {\n  case ErrorType::SignedIntegerOverflow:\n    Diag(Loc, DL_Error, \"division of %0 by -1 cannot be represented in type %1\")\n        << LHSVal << Data->Type;\n    break;\n  default:\n    Diag(Loc, DL_Error, \"division by zero\");\n    break;\n  }\n}\n\nvoid __ubsan::__ubsan_handle_divrem_overflow(OverflowData *Data,\n                                             ValueHandle LHS, ValueHandle RHS) {\n  GET_REPORT_OPTIONS(false);\n  handleDivremOverflowImpl(Data, LHS, RHS, Opts);\n}\nvoid __ubsan::__ubsan_handle_divrem_overflow_abort(OverflowData *Data,\n                                                    ValueHandle LHS,\n                                                    ValueHandle RHS) {\n  GET_REPORT_OPTIONS(true);\n  handleDivremOverflowImpl(Data, LHS, RHS, Opts);\n  Die();\n}\n\nstatic void handleShiftOutOfBoundsImpl(ShiftOutOfBoundsData *Data,\n                                       ValueHandle LHS, ValueHandle RHS,\n                                       ReportOptions Opts) {\n  SourceLocation Loc = Data->Loc.acquire();\n  Value LHSVal(Data->LHSType, LHS);\n  Value RHSVal(Data->RHSType, RHS);\n\n  ErrorType ET;\n  if (RHSVal.isNegative() ||\n      RHSVal.getPositiveIntValue() >= Data->LHSType.getIntegerBitWidth())\n    ET = ErrorType::InvalidShiftExponent;\n  else\n    ET = ErrorType::InvalidShiftBase;\n\n  if (ignoreReport(Loc, Opts, ET))\n    return;\n\n  ScopedReport R(Opts, Loc, ET);\n\n  if (ET == ErrorType::InvalidShiftExponent) {\n    if (RHSVal.isNegative())\n      Diag(Loc, DL_Error, \"shift exponent %0 is negative\") << RHSVal;\n    else\n      Diag(Loc, DL_Error, \"shift exponent %0 is too large for %1-bit type %2\")\n          << RHSVal << Data->LHSType.getIntegerBitWidth() << Data->LHSType;\n  } else {\n    if (LHSVal.isNegative())\n      Diag(Loc, DL_Error, \"left shift of negative value %0\") << LHSVal;\n    else\n      Diag(Loc, DL_Error,\n           \"left shift of %0 by %1 places cannot be represented in type %2\")\n          << LHSVal << RHSVal << Data->LHSType;\n  }\n}\n\nvoid __ubsan::__ubsan_handle_shift_out_of_bounds(ShiftOutOfBoundsData *Data,\n                                                 ValueHandle LHS,\n                                                 ValueHandle RHS) {\n  GET_REPORT_OPTIONS(false);\n  handleShiftOutOfBoundsImpl(Data, LHS, RHS, Opts);\n}\nvoid __ubsan::__ubsan_handle_shift_out_of_bounds_abort(\n                                                     ShiftOutOfBoundsData *Data,\n                                                     ValueHandle LHS,\n                                                     ValueHandle RHS) {\n  GET_REPORT_OPTIONS(true);\n  handleShiftOutOfBoundsImpl(Data, LHS, RHS, Opts);\n  Die();\n}\n\nstatic void handleOutOfBoundsImpl(OutOfBoundsData *Data, ValueHandle Index,\n                                  ReportOptions Opts) {\n  SourceLocation Loc = Data->Loc.acquire();\n  ErrorType ET = ErrorType::OutOfBoundsIndex;\n\n  if (ignoreReport(Loc, Opts, ET))\n    return;\n\n  ScopedReport R(Opts, Loc, ET);\n\n  Value IndexVal(Data->IndexType, Index);\n  Diag(Loc, DL_Error, \"index %0 out of bounds for type %1\")\n    << IndexVal << Data->ArrayType;\n}\n\nvoid __ubsan::__ubsan_handle_out_of_bounds(OutOfBoundsData *Data,\n                                           ValueHandle Index) {\n  GET_REPORT_OPTIONS(false);\n  handleOutOfBoundsImpl(Data, Index, Opts);\n}\nvoid __ubsan::__ubsan_handle_out_of_bounds_abort(OutOfBoundsData *Data,\n                                                 ValueHandle Index) {\n  GET_REPORT_OPTIONS(true);\n  handleOutOfBoundsImpl(Data, Index, Opts);\n  Die();\n}\n\nstatic void handleBuiltinUnreachableImpl(UnreachableData *Data,\n                                         ReportOptions Opts) {\n  ScopedReport R(Opts, Data->Loc, ErrorType::UnreachableCall);\n  Diag(Data->Loc, DL_Error, \"execution reached a __builtin_unreachable() call\");\n}\n\nvoid __ubsan::__ubsan_handle_builtin_unreachable(UnreachableData *Data) {\n  GET_REPORT_OPTIONS(true);\n  handleBuiltinUnreachableImpl(Data, Opts);\n  Die();\n}\n\nstatic void handleMissingReturnImpl(UnreachableData *Data, ReportOptions Opts) {\n  ScopedReport R(Opts, Data->Loc, ErrorType::MissingReturn);\n  Diag(Data->Loc, DL_Error,\n       \"execution reached the end of a value-returning function \"\n       \"without returning a value\");\n}\n\nvoid __ubsan::__ubsan_handle_missing_return(UnreachableData *Data) {\n  GET_REPORT_OPTIONS(true);\n  handleMissingReturnImpl(Data, Opts);\n  Die();\n}\n\nstatic void handleVLABoundNotPositive(VLABoundData *Data, ValueHandle Bound,\n                                      ReportOptions Opts) {\n  SourceLocation Loc = Data->Loc.acquire();\n  ErrorType ET = ErrorType::NonPositiveVLAIndex;\n\n  if (ignoreReport(Loc, Opts, ET))\n    return;\n\n  ScopedReport R(Opts, Loc, ET);\n\n  Diag(Loc, DL_Error, \"variable length array bound evaluates to \"\n                      \"non-positive value %0\")\n    << Value(Data->Type, Bound);\n}\n\nvoid __ubsan::__ubsan_handle_vla_bound_not_positive(VLABoundData *Data,\n                                                    ValueHandle Bound) {\n  GET_REPORT_OPTIONS(false);\n  handleVLABoundNotPositive(Data, Bound, Opts);\n}\nvoid __ubsan::__ubsan_handle_vla_bound_not_positive_abort(VLABoundData *Data,\n                                                          ValueHandle Bound) {\n  GET_REPORT_OPTIONS(true);\n  handleVLABoundNotPositive(Data, Bound, Opts);\n  Die();\n}\n\nstatic bool looksLikeFloatCastOverflowDataV1(void *Data) {\n  // First field is either a pointer to filename or a pointer to a\n  // TypeDescriptor.\n  u8 *FilenameOrTypeDescriptor;\n  internal_memcpy(&FilenameOrTypeDescriptor, Data,\n                  sizeof(FilenameOrTypeDescriptor));\n\n  // Heuristic: For float_cast_overflow, the TypeKind will be either TK_Integer\n  // (0x0), TK_Float (0x1) or TK_Unknown (0xff). If both types are known,\n  // adding both bytes will be 0 or 1 (for BE or LE). If it were a filename,\n  // adding two printable characters will not yield such a value. Otherwise,\n  // if one of them is 0xff, this is most likely TK_Unknown type descriptor.\n  u16 MaybeFromTypeKind =\n      FilenameOrTypeDescriptor[0] + FilenameOrTypeDescriptor[1];\n  return MaybeFromTypeKind < 2 || FilenameOrTypeDescriptor[0] == 0xff ||\n         FilenameOrTypeDescriptor[1] == 0xff;\n}\n\nstatic void handleFloatCastOverflow(void *DataPtr, ValueHandle From,\n                                    ReportOptions Opts) {\n  SymbolizedStackHolder CallerLoc;\n  Location Loc;\n  const TypeDescriptor *FromType, *ToType;\n  ErrorType ET = ErrorType::FloatCastOverflow;\n\n  if (looksLikeFloatCastOverflowDataV1(DataPtr)) {\n    auto Data = reinterpret_cast<FloatCastOverflowData *>(DataPtr);\n    CallerLoc.reset(getCallerLocation(Opts.pc));\n    Loc = CallerLoc;\n    FromType = &Data->FromType;\n    ToType = &Data->ToType;\n  } else {\n    auto Data = reinterpret_cast<FloatCastOverflowDataV2 *>(DataPtr);\n    SourceLocation SLoc = Data->Loc.acquire();\n    if (ignoreReport(SLoc, Opts, ET))\n      return;\n    Loc = SLoc;\n    FromType = &Data->FromType;\n    ToType = &Data->ToType;\n  }\n\n  ScopedReport R(Opts, Loc, ET);\n\n  Diag(Loc, DL_Error,\n       \"value %0 is outside the range of representable values of type %2\")\n      << Value(*FromType, From) << *FromType << *ToType;\n}\n\nvoid __ubsan::__ubsan_handle_float_cast_overflow(void *Data, ValueHandle From) {\n  GET_REPORT_OPTIONS(false);\n  handleFloatCastOverflow(Data, From, Opts);\n}\nvoid __ubsan::__ubsan_handle_float_cast_overflow_abort(void *Data,\n                                                       ValueHandle From) {\n  GET_REPORT_OPTIONS(true);\n  handleFloatCastOverflow(Data, From, Opts);\n  Die();\n}\n\nstatic void handleLoadInvalidValue(InvalidValueData *Data, ValueHandle Val,\n                                   ReportOptions Opts) {\n  SourceLocation Loc = Data->Loc.acquire();\n  // This check could be more precise if we used different handlers for\n  // -fsanitize=bool and -fsanitize=enum.\n  bool IsBool = (0 == internal_strcmp(Data->Type.getTypeName(), \"'bool'\"));\n  ErrorType ET =\n      IsBool ? ErrorType::InvalidBoolLoad : ErrorType::InvalidEnumLoad;\n\n  if (ignoreReport(Loc, Opts, ET))\n    return;\n\n  ScopedReport R(Opts, Loc, ET);\n\n  Diag(Loc, DL_Error,\n       \"load of value %0, which is not a valid value for type %1\")\n    << Value(Data->Type, Val) << Data->Type;\n}\n\nvoid __ubsan::__ubsan_handle_load_invalid_value(InvalidValueData *Data,\n                                                ValueHandle Val) {\n  GET_REPORT_OPTIONS(false);\n  handleLoadInvalidValue(Data, Val, Opts);\n}\nvoid __ubsan::__ubsan_handle_load_invalid_value_abort(InvalidValueData *Data,\n                                                      ValueHandle Val) {\n  GET_REPORT_OPTIONS(true);\n  handleLoadInvalidValue(Data, Val, Opts);\n  Die();\n}\n\nstatic void handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,\n                                       ValueHandle Function,\n                                       ReportOptions Opts) {\n  SourceLocation CallLoc = Data->Loc.acquire();\n  ErrorType ET = ErrorType::FunctionTypeMismatch;\n\n  if (ignoreReport(CallLoc, Opts, ET))\n    return;\n\n  ScopedReport R(Opts, CallLoc, ET);\n\n  SymbolizedStackHolder FLoc(getSymbolizedLocation(Function));\n  const char *FName = FLoc.get()->info.function;\n  if (!FName)\n    FName = \"(unknown)\";\n\n  Diag(CallLoc, DL_Error,\n       \"call to function %0 through pointer to incorrect function type %1\")\n      << FName << Data->Type;\n  Diag(FLoc, DL_Note, \"%0 defined here\") << FName;\n}\n\nvoid\n__ubsan::__ubsan_handle_function_type_mismatch(FunctionTypeMismatchData *Data,\n                                               ValueHandle Function) {\n  GET_REPORT_OPTIONS(false);\n  handleFunctionTypeMismatch(Data, Function, Opts);\n}\n\nvoid __ubsan::__ubsan_handle_function_type_mismatch_abort(\n    FunctionTypeMismatchData *Data, ValueHandle Function) {\n  GET_REPORT_OPTIONS(true);\n  handleFunctionTypeMismatch(Data, Function, Opts);\n  Die();\n}\n\nstatic void handleNonNullReturn(NonNullReturnData *Data, ReportOptions Opts) {\n  SourceLocation Loc = Data->Loc.acquire();\n  ErrorType ET = ErrorType::InvalidNullReturn;\n\n  if (ignoreReport(Loc, Opts, ET))\n    return;\n\n  ScopedReport R(Opts, Loc, ET);\n\n  Diag(Loc, DL_Error, \"null pointer returned from function declared to never \"\n                      \"return null\");\n  if (!Data->AttrLoc.isInvalid())\n    Diag(Data->AttrLoc, DL_Note, \"returns_nonnull attribute specified here\");\n}\n\nvoid __ubsan::__ubsan_handle_nonnull_return(NonNullReturnData *Data) {\n  GET_REPORT_OPTIONS(false);\n  handleNonNullReturn(Data, Opts);\n}\n\nvoid __ubsan::__ubsan_handle_nonnull_return_abort(NonNullReturnData *Data) {\n  GET_REPORT_OPTIONS(true);\n  handleNonNullReturn(Data, Opts);\n  Die();\n}\n\nstatic void handleNonNullArg(NonNullArgData *Data, ReportOptions Opts) {\n  SourceLocation Loc = Data->Loc.acquire();\n  ErrorType ET = ErrorType::InvalidNullArgument;\n\n  if (ignoreReport(Loc, Opts, ET))\n    return;\n\n  ScopedReport R(Opts, Loc, ET);\n\n  Diag(Loc, DL_Error, \"null pointer passed as argument %0, which is declared to \"\n       \"never be null\") << Data->ArgIndex;\n  if (!Data->AttrLoc.isInvalid())\n    Diag(Data->AttrLoc, DL_Note, \"nonnull attribute specified here\");\n}\n\nvoid __ubsan::__ubsan_handle_nonnull_arg(NonNullArgData *Data) {\n  GET_REPORT_OPTIONS(false);\n  handleNonNullArg(Data, Opts);\n}\n\nvoid __ubsan::__ubsan_handle_nonnull_arg_abort(NonNullArgData *Data) {\n  GET_REPORT_OPTIONS(true);\n  handleNonNullArg(Data, Opts);\n  Die();\n}\n\nstatic void handleCFIBadIcall(CFIBadIcallData *Data, ValueHandle Function,\n                              ReportOptions Opts) {\n  SourceLocation Loc = Data->Loc.acquire();\n  ErrorType ET = ErrorType::CFIBadType;\n\n  if (ignoreReport(Loc, Opts, ET))\n    return;\n\n  ScopedReport R(Opts, Loc, ET);\n\n  Diag(Loc, DL_Error, \"control flow integrity check for type %0 failed during \"\n                      \"indirect function call\")\n      << Data->Type;\n\n  SymbolizedStackHolder FLoc(getSymbolizedLocation(Function));\n  const char *FName = FLoc.get()->info.function;\n  if (!FName)\n    FName = \"(unknown)\";\n  Diag(FLoc, DL_Note, \"%0 defined here\") << FName;\n}\n\nvoid __ubsan::__ubsan_handle_cfi_bad_icall(CFIBadIcallData *Data,\n                                           ValueHandle Function) {\n  GET_REPORT_OPTIONS(false);\n  handleCFIBadIcall(Data, Function, Opts);\n}\n\nvoid __ubsan::__ubsan_handle_cfi_bad_icall_abort(CFIBadIcallData *Data,\n                                                 ValueHandle Function) {\n  GET_REPORT_OPTIONS(true);\n  handleCFIBadIcall(Data, Function, Opts);\n  Die();\n}\n\n#endif  // CAN_SANITIZE_UB\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_handlers.h",
    "content": "//===-- ubsan_handlers.h ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Entry points to the runtime library for Clang's undefined behavior sanitizer.\n//\n//===----------------------------------------------------------------------===//\n#ifndef UBSAN_HANDLERS_H\n#define UBSAN_HANDLERS_H\n\n#include \"ubsan_value.h\"\n\nnamespace __ubsan {\n\nstruct TypeMismatchData {\n  SourceLocation Loc;\n  const TypeDescriptor &Type;\n  uptr Alignment;\n  unsigned char TypeCheckKind;\n};\n\n#define UNRECOVERABLE(checkname, ...) \\\n  extern \"C\" SANITIZER_INTERFACE_ATTRIBUTE NORETURN \\\n    void __ubsan_handle_ ## checkname( __VA_ARGS__ );\n\n#define RECOVERABLE(checkname, ...) \\\n  extern \"C\" SANITIZER_INTERFACE_ATTRIBUTE \\\n    void __ubsan_handle_ ## checkname( __VA_ARGS__ ); \\\n  extern \"C\" SANITIZER_INTERFACE_ATTRIBUTE NORETURN \\\n    void __ubsan_handle_ ## checkname ## _abort( __VA_ARGS__ );\n\n/// \\brief Handle a runtime type check failure, caused by either a misaligned\n/// pointer, a null pointer, or a pointer to insufficient storage for the\n/// type.\nRECOVERABLE(type_mismatch, TypeMismatchData *Data, ValueHandle Pointer)\n\nstruct OverflowData {\n  SourceLocation Loc;\n  const TypeDescriptor &Type;\n};\n\n/// \\brief Handle an integer addition overflow.\nRECOVERABLE(add_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)\n\n/// \\brief Handle an integer subtraction overflow.\nRECOVERABLE(sub_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)\n\n/// \\brief Handle an integer multiplication overflow.\nRECOVERABLE(mul_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)\n\n/// \\brief Handle a signed integer overflow for a unary negate operator.\nRECOVERABLE(negate_overflow, OverflowData *Data, ValueHandle OldVal)\n\n/// \\brief Handle an INT_MIN/-1 overflow or division by zero.\nRECOVERABLE(divrem_overflow, OverflowData *Data,\n            ValueHandle LHS, ValueHandle RHS)\n\nstruct ShiftOutOfBoundsData {\n  SourceLocation Loc;\n  const TypeDescriptor &LHSType;\n  const TypeDescriptor &RHSType;\n};\n\n/// \\brief Handle a shift where the RHS is out of bounds or a left shift where\n/// the LHS is negative or overflows.\nRECOVERABLE(shift_out_of_bounds, ShiftOutOfBoundsData *Data,\n            ValueHandle LHS, ValueHandle RHS)\n\nstruct OutOfBoundsData {\n  SourceLocation Loc;\n  const TypeDescriptor &ArrayType;\n  const TypeDescriptor &IndexType;\n};\n\n/// \\brief Handle an array index out of bounds error.\nRECOVERABLE(out_of_bounds, OutOfBoundsData *Data, ValueHandle Index)\n\nstruct UnreachableData {\n  SourceLocation Loc;\n};\n\n/// \\brief Handle a __builtin_unreachable which is reached.\nUNRECOVERABLE(builtin_unreachable, UnreachableData *Data)\n/// \\brief Handle reaching the end of a value-returning function.\nUNRECOVERABLE(missing_return, UnreachableData *Data)\n\nstruct VLABoundData {\n  SourceLocation Loc;\n  const TypeDescriptor &Type;\n};\n\n/// \\brief Handle a VLA with a non-positive bound.\nRECOVERABLE(vla_bound_not_positive, VLABoundData *Data, ValueHandle Bound)\n\n// Keeping this around for binary compatibility with (sanitized) programs\n// compiled with older compilers.\nstruct FloatCastOverflowData {\n  const TypeDescriptor &FromType;\n  const TypeDescriptor &ToType;\n};\n\nstruct FloatCastOverflowDataV2 {\n  SourceLocation Loc;\n  const TypeDescriptor &FromType;\n  const TypeDescriptor &ToType;\n};\n\n/// Handle overflow in a conversion to or from a floating-point type.\n/// void *Data is one of FloatCastOverflowData* or FloatCastOverflowDataV2*\nRECOVERABLE(float_cast_overflow, void *Data, ValueHandle From)\n\nstruct InvalidValueData {\n  SourceLocation Loc;\n  const TypeDescriptor &Type;\n};\n\n/// \\brief Handle a load of an invalid value for the type.\nRECOVERABLE(load_invalid_value, InvalidValueData *Data, ValueHandle Val)\n\nstruct FunctionTypeMismatchData {\n  SourceLocation Loc;\n  const TypeDescriptor &Type;\n};\n\nRECOVERABLE(function_type_mismatch,\n            FunctionTypeMismatchData *Data,\n            ValueHandle Val)\n\nstruct NonNullReturnData {\n  SourceLocation Loc;\n  SourceLocation AttrLoc;\n};\n\n/// \\brief Handle returning null from function with returns_nonnull attribute.\nRECOVERABLE(nonnull_return, NonNullReturnData *Data)\n\nstruct NonNullArgData {\n  SourceLocation Loc;\n  SourceLocation AttrLoc;\n  int ArgIndex;\n};\n\n/// \\brief Handle passing null pointer to function with nonnull attribute.\nRECOVERABLE(nonnull_arg, NonNullArgData *Data)\n\nstruct CFIBadIcallData {\n  SourceLocation Loc;\n  const TypeDescriptor &Type;\n};\n\n/// \\brief Handle control flow integrity failure for indirect function calls.\nRECOVERABLE(cfi_bad_icall, CFIBadIcallData *Data, ValueHandle Function)\n\n}\n\n#endif // UBSAN_HANDLERS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc",
    "content": "//===-- ubsan_handlers_cxx.cc ---------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Error logging entry points for the UBSan runtime, which are only used for C++\n// compilations. This file is permitted to use language features which require\n// linking against a C++ ABI library.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"ubsan_platform.h\"\n#if CAN_SANITIZE_UB\n#include \"ubsan_handlers_cxx.h\"\n#include \"ubsan_diag.h\"\n#include \"ubsan_type_hash.h\"\n\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_suppressions.h\"\n\nusing namespace __sanitizer;\nusing namespace __ubsan;\n\nnamespace __ubsan {\n  extern const char *TypeCheckKinds[];\n}\n\n// Returns true if UBSan has printed an error report.\nstatic bool HandleDynamicTypeCacheMiss(\n    DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash,\n    ReportOptions Opts) {\n  if (checkDynamicType((void*)Pointer, Data->TypeInfo, Hash))\n    // Just a cache miss. The type matches after all.\n    return false;\n\n  // Check if error report should be suppressed.\n  DynamicTypeInfo DTI = getDynamicTypeInfoFromObject((void*)Pointer);\n  if (DTI.isValid() && IsVptrCheckSuppressed(DTI.getMostDerivedTypeName()))\n    return false;\n\n  SourceLocation Loc = Data->Loc.acquire();\n  ErrorType ET = ErrorType::DynamicTypeMismatch;\n  if (ignoreReport(Loc, Opts, ET))\n    return false;\n\n  ScopedReport R(Opts, Loc, ET);\n\n  Diag(Loc, DL_Error,\n       \"%0 address %1 which does not point to an object of type %2\")\n    << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;\n\n  // If possible, say what type it actually points to.\n  if (!DTI.isValid())\n    Diag(Pointer, DL_Note, \"object has invalid vptr\")\n        << TypeName(DTI.getMostDerivedTypeName())\n        << Range(Pointer, Pointer + sizeof(uptr), \"invalid vptr\");\n  else if (!DTI.getOffset())\n    Diag(Pointer, DL_Note, \"object is of type %0\")\n        << TypeName(DTI.getMostDerivedTypeName())\n        << Range(Pointer, Pointer + sizeof(uptr), \"vptr for %0\");\n  else\n    // FIXME: Find the type at the specified offset, and include that\n    //        in the note.\n    Diag(Pointer - DTI.getOffset(), DL_Note,\n         \"object is base class subobject at offset %0 within object of type %1\")\n        << DTI.getOffset() << TypeName(DTI.getMostDerivedTypeName())\n        << TypeName(DTI.getSubobjectTypeName())\n        << Range(Pointer, Pointer + sizeof(uptr),\n                 \"vptr for %2 base class of %1\");\n  return true;\n}\n\nvoid __ubsan::__ubsan_handle_dynamic_type_cache_miss(\n    DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash) {\n  GET_REPORT_OPTIONS(false);\n  HandleDynamicTypeCacheMiss(Data, Pointer, Hash, Opts);\n}\nvoid __ubsan::__ubsan_handle_dynamic_type_cache_miss_abort(\n    DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash) {\n  // Note: -fsanitize=vptr is always recoverable.\n  GET_REPORT_OPTIONS(false);\n  if (HandleDynamicTypeCacheMiss(Data, Pointer, Hash, Opts))\n    Die();\n}\n\nstatic void HandleCFIBadType(CFIBadTypeData *Data, ValueHandle Vtable,\n                             ReportOptions Opts) {\n  SourceLocation Loc = Data->Loc.acquire();\n  ErrorType ET = ErrorType::CFIBadType;\n\n  if (ignoreReport(Loc, Opts, ET))\n    return;\n\n  ScopedReport R(Opts, Loc, ET);\n  DynamicTypeInfo DTI = getDynamicTypeInfoFromVtable((void*)Vtable);\n\n  static const char *TypeCheckKinds[] = {\n    \"virtual call\",\n    \"non-virtual call\",\n    \"base-to-derived cast\",\n    \"cast to unrelated type\",\n  };\n\n  Diag(Loc, DL_Error, \"control flow integrity check for type %0 failed during \"\n                      \"%1 (vtable address %2)\")\n      << Data->Type << TypeCheckKinds[Data->TypeCheckKind] << (void *)Vtable;\n\n  // If possible, say what type it actually points to.\n  if (!DTI.isValid())\n    Diag(Vtable, DL_Note, \"invalid vtable\");\n  else\n    Diag(Vtable, DL_Note, \"vtable is of type %0\")\n        << TypeName(DTI.getMostDerivedTypeName());\n}\n\nvoid __ubsan::__ubsan_handle_cfi_bad_type(CFIBadTypeData *Data,\n                                          ValueHandle Vtable) {\n  GET_REPORT_OPTIONS(false);\n  HandleCFIBadType(Data, Vtable, Opts);\n}\n\nvoid __ubsan::__ubsan_handle_cfi_bad_type_abort(CFIBadTypeData *Data,\n                                                ValueHandle Vtable) {\n  GET_REPORT_OPTIONS(true);\n  HandleCFIBadType(Data, Vtable, Opts);\n  Die();\n}\n\n#endif  // CAN_SANITIZE_UB\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_handlers_cxx.h",
    "content": "//===-- ubsan_handlers_cxx.h ------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Entry points to the runtime library for Clang's undefined behavior sanitizer,\n// for C++-specific checks. This code is not linked into C binaries.\n//\n//===----------------------------------------------------------------------===//\n#ifndef UBSAN_HANDLERS_CXX_H\n#define UBSAN_HANDLERS_CXX_H\n\n#include \"ubsan_value.h\"\n\nnamespace __ubsan {\n\nstruct DynamicTypeCacheMissData {\n  SourceLocation Loc;\n  const TypeDescriptor &Type;\n  void *TypeInfo;\n  unsigned char TypeCheckKind;\n};\n\nstruct CFIBadTypeData {\n  SourceLocation Loc;\n  const TypeDescriptor &Type;\n  unsigned char TypeCheckKind;\n};\n\n/// \\brief Handle a runtime type check failure, caused by an incorrect vptr.\n/// When this handler is called, all we know is that the type was not in the\n/// cache; this does not necessarily imply the existence of a bug.\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nvoid __ubsan_handle_dynamic_type_cache_miss(\n  DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash);\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nvoid __ubsan_handle_dynamic_type_cache_miss_abort(\n  DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash);\n\n/// \\brief Handle a control flow integrity check failure by printing a\n/// diagnostic.\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE void\n__ubsan_handle_cfi_bad_type(CFIBadTypeData *Data, ValueHandle Vtable);\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE void\n__ubsan_handle_cfi_bad_type_abort(CFIBadTypeData *Data, ValueHandle Vtable);\n\n}\n\n#endif // UBSAN_HANDLERS_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_init.cc",
    "content": "//===-- ubsan_init.cc -----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Initialization of UBSan runtime.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"ubsan_platform.h\"\n#if CAN_SANITIZE_UB\n#include \"ubsan_diag.h\"\n#include \"ubsan_init.h\"\n#include \"ubsan_flags.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n#include \"sanitizer_common/sanitizer_mutex.h\"\n#include \"sanitizer_common/sanitizer_symbolizer.h\"\n\nusing namespace __ubsan;\n\nstatic enum {\n  UBSAN_MODE_UNKNOWN = 0,\n  UBSAN_MODE_STANDALONE,\n  UBSAN_MODE_PLUGIN\n} ubsan_mode;\nstatic StaticSpinMutex ubsan_init_mu;\n\nstatic void CommonInit() {\n  InitializeSuppressions();\n}\n\nstatic void CommonStandaloneInit() {\n  SanitizerToolName = \"UndefinedBehaviorSanitizer\";\n  InitializeFlags();\n  CacheBinaryName();\n  __sanitizer_set_report_path(common_flags()->log_path);\n  InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);\n  CommonInit();\n  ubsan_mode = UBSAN_MODE_STANDALONE;\n}\n\nvoid __ubsan::InitAsStandalone() {\n  if (SANITIZER_CAN_USE_PREINIT_ARRAY) {\n    CHECK_EQ(UBSAN_MODE_UNKNOWN, ubsan_mode);\n    CommonStandaloneInit();\n    return;\n  }\n  SpinMutexLock l(&ubsan_init_mu);\n  CHECK_NE(UBSAN_MODE_PLUGIN, ubsan_mode);\n  if (ubsan_mode == UBSAN_MODE_UNKNOWN)\n    CommonStandaloneInit();\n}\n\nvoid __ubsan::InitAsStandaloneIfNecessary() {\n  if (SANITIZER_CAN_USE_PREINIT_ARRAY) {\n    CHECK_NE(UBSAN_MODE_UNKNOWN, ubsan_mode);\n    return;\n  }\n  SpinMutexLock l(&ubsan_init_mu);\n  if (ubsan_mode == UBSAN_MODE_UNKNOWN)\n    CommonStandaloneInit();\n}\n\nvoid __ubsan::InitAsPlugin() {\n#if !SANITIZER_CAN_USE_PREINIT_ARRAY\n  SpinMutexLock l(&ubsan_init_mu);\n#endif\n  CHECK_EQ(UBSAN_MODE_UNKNOWN, ubsan_mode);\n  CommonInit();\n  ubsan_mode = UBSAN_MODE_PLUGIN;\n}\n\n#endif  // CAN_SANITIZE_UB\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_init.h",
    "content": "//===-- ubsan_init.h --------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Initialization function for UBSan runtime.\n//\n//===----------------------------------------------------------------------===//\n#ifndef UBSAN_INIT_H\n#define UBSAN_INIT_H\n\nnamespace __ubsan {\n\n// Initialize UBSan as a standalone tool. Typically should be called early\n// during initialization.\nvoid InitAsStandalone();\n\n// Initialize UBSan as a standalone tool, if it hasn't been initialized before.\nvoid InitAsStandaloneIfNecessary();\n\n// Initializes UBSan as a plugin tool. This function should be called once\n// from \"parent tool\" (e.g. ASan) initialization.\nvoid InitAsPlugin();\n\n}  // namespace __ubsan\n\n#endif  // UBSAN_INIT_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_init_standalone.cc",
    "content": "//===-- ubsan_init_standalone.cc ------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Initialization of standalone UBSan runtime.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"ubsan_platform.h\"\n#if !CAN_SANITIZE_UB\n# error \"UBSan is not supported on this platform!\"\n#endif\n\n#include \"sanitizer_common/sanitizer_internal_defs.h\"\n#include \"ubsan_init.h\"\n\n#if SANITIZER_CAN_USE_PREINIT_ARRAY\n__attribute__((section(\".preinit_array\"), used))\nvoid (*__local_ubsan_preinit)(void) = __ubsan::InitAsStandalone;\n#else\n// Use a dynamic initializer.\nclass UbsanStandaloneInitializer {\n public:\n  UbsanStandaloneInitializer() {\n    __ubsan::InitAsStandalone();\n  }\n};\nstatic UbsanStandaloneInitializer ubsan_standalone_initializer;\n#endif  // SANITIZER_CAN_USE_PREINIT_ARRAY\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_platform.h",
    "content": "//===-- ubsan_platform.h ----------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Defines the platforms which UBSan is supported at.\n//\n//===----------------------------------------------------------------------===//\n#ifndef UBSAN_PLATFORM_H\n#define UBSAN_PLATFORM_H\n\n// Other platforms should be easy to add, and probably work as-is.\n#if (defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)) && \\\n    (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || \\\n     defined(__aarch64__) || defined(__mips__) || defined(__powerpc64__))\n# define CAN_SANITIZE_UB 1\n#elif defined(_WIN32)\n# define CAN_SANITIZE_UB 1\n#else\n# define CAN_SANITIZE_UB 0\n#endif\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_type_hash.cc",
    "content": "//===-- ubsan_type_hash.cc ------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Implementation of a hash table for fast checking of inheritance\n// relationships. This file is only linked into C++ compilations, and is\n// permitted to use language features which require a C++ ABI library.\n//\n// Most of the implementation lives in an ABI-specific source file\n// (ubsan_type_hash_{itanium,win}.cc).\n//\n//===----------------------------------------------------------------------===//\n\n#include \"ubsan_platform.h\"\n#if CAN_SANITIZE_UB\n#include \"ubsan_type_hash.h\"\n\n#include \"sanitizer_common/sanitizer_common.h\"\n\n/// A cache of recently-checked hashes. Mini hash table with \"random\" evictions.\n__ubsan::HashValue\n__ubsan::__ubsan_vptr_type_cache[__ubsan::VptrTypeCacheSize];\n\n__ubsan::DynamicTypeInfo __ubsan::getDynamicTypeInfoFromObject(void *Object) {\n  void *VtablePtr = *reinterpret_cast<void **>(Object);\n  return getDynamicTypeInfoFromVtable(VtablePtr);\n}\n\n#endif  // CAN_SANITIZE_UB\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_type_hash.h",
    "content": "//===-- ubsan_type_hash.h ---------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Hashing of types for Clang's undefined behavior checker.\n//\n//===----------------------------------------------------------------------===//\n#ifndef UBSAN_TYPE_HASH_H\n#define UBSAN_TYPE_HASH_H\n\n#include \"sanitizer_common/sanitizer_common.h\"\n\nnamespace __ubsan {\n\ntypedef uptr HashValue;\n\n/// \\brief Information about the dynamic type of an object (extracted from its\n/// vptr).\nclass DynamicTypeInfo {\n  const char *MostDerivedTypeName;\n  sptr Offset;\n  const char *SubobjectTypeName;\n\npublic:\n  DynamicTypeInfo(const char *MDTN, sptr Offset, const char *STN)\n    : MostDerivedTypeName(MDTN), Offset(Offset), SubobjectTypeName(STN) {}\n\n  /// Determine whether the object had a valid dynamic type.\n  bool isValid() const { return MostDerivedTypeName; }\n  /// Get the name of the most-derived type of the object.\n  const char *getMostDerivedTypeName() const { return MostDerivedTypeName; }\n  /// Get the offset from the most-derived type to this base class.\n  sptr getOffset() const { return Offset; }\n  /// Get the name of the most-derived type at the specified offset.\n  const char *getSubobjectTypeName() const { return SubobjectTypeName; }\n};\n\n/// \\brief Get information about the dynamic type of an object.\nDynamicTypeInfo getDynamicTypeInfoFromObject(void *Object);\n\n/// \\brief Get information about the dynamic type of an object from its vtable.\nDynamicTypeInfo getDynamicTypeInfoFromVtable(void *Vtable);\n\n/// \\brief Check whether the dynamic type of \\p Object has a \\p Type subobject\n/// at offset 0.\n/// \\return \\c true if the type matches, \\c false if not.\nbool checkDynamicType(void *Object, void *Type, HashValue Hash);\n\nconst unsigned VptrTypeCacheSize = 128;\n\n/// \\brief A cache of the results of checkDynamicType. \\c checkDynamicType would\n/// return \\c true (modulo hash collisions) if\n/// \\code\n///   __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] == Hash\n/// \\endcode\nextern \"C\" SANITIZER_INTERFACE_ATTRIBUTE\nHashValue __ubsan_vptr_type_cache[VptrTypeCacheSize];\n\n} // namespace __ubsan\n\n#endif // UBSAN_TYPE_HASH_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc",
    "content": "//===-- ubsan_type_hash_itanium.cc ----------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Implementation of type hashing/lookup for Itanium C++ ABI.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#include \"ubsan_platform.h\"\n#if CAN_SANITIZE_UB && !SANITIZER_WINDOWS\n#include \"ubsan_type_hash.h\"\n\n#include \"sanitizer_common/sanitizer_common.h\"\n\n// The following are intended to be binary compatible with the definitions\n// given in the Itanium ABI. We make no attempt to be ODR-compatible with\n// those definitions, since existing ABI implementations aren't.\n\nnamespace std {\n  class type_info {\n  public:\n    virtual ~type_info();\n\n    const char *__type_name;\n  };\n}\n\nnamespace __cxxabiv1 {\n\n/// Type info for classes with no bases, and base class for type info for\n/// classes with bases.\nclass __class_type_info : public std::type_info {\n  ~__class_type_info() override;\n};\n\n/// Type info for classes with simple single public inheritance.\nclass __si_class_type_info : public __class_type_info {\npublic:\n  ~__si_class_type_info() override;\n\n  const __class_type_info *__base_type;\n};\n\nclass __base_class_type_info {\npublic:\n  const __class_type_info *__base_type;\n  long __offset_flags;\n\n  enum __offset_flags_masks {\n    __virtual_mask = 0x1,\n    __public_mask = 0x2,\n    __offset_shift = 8\n  };\n};\n\n/// Type info for classes with multiple, virtual, or non-public inheritance.\nclass __vmi_class_type_info : public __class_type_info {\npublic:\n  ~__vmi_class_type_info() override;\n\n  unsigned int flags;\n  unsigned int base_count;\n  __base_class_type_info base_info[1];\n};\n\n}\n\nnamespace abi = __cxxabiv1;\n\n// We implement a simple two-level cache for type-checking results. For each\n// (vptr,type) pair, a hash is computed. This hash is assumed to be globally\n// unique; if it collides, we will get false negatives, but:\n//  * such a collision would have to occur on the *first* bad access,\n//  * the probability of such a collision is low (and for a 64-bit target, is\n//    negligible), and\n//  * the vptr, and thus the hash, can be affected by ASLR, so multiple runs\n//    give better coverage.\n//\n// The first caching layer is a small hash table with no chaining; buckets are\n// reused as needed. The second caching layer is a large hash table with open\n// chaining. We can freely evict from either layer since this is just a cache.\n//\n// FIXME: Make these hash table accesses thread-safe. The races here are benign:\n//        assuming the unsequenced loads and stores don't misbehave too badly,\n//        the worst case is false negatives or poor cache behavior, not false\n//        positives or crashes.\n\n/// Find a bucket to store the given hash value in.\nstatic __ubsan::HashValue *getTypeCacheHashTableBucket(__ubsan::HashValue V) {\n  static const unsigned HashTableSize = 65537;\n  static __ubsan::HashValue __ubsan_vptr_hash_set[HashTableSize];\n\n  unsigned First = (V & 65535) ^ 1;\n  unsigned Probe = First;\n  for (int Tries = 5; Tries; --Tries) {\n    if (!__ubsan_vptr_hash_set[Probe] || __ubsan_vptr_hash_set[Probe] == V)\n      return &__ubsan_vptr_hash_set[Probe];\n    Probe += ((V >> 16) & 65535) + 1;\n    if (Probe >= HashTableSize)\n      Probe -= HashTableSize;\n  }\n  // FIXME: Pick a random entry from the probe sequence to evict rather than\n  //        just taking the first.\n  return &__ubsan_vptr_hash_set[First];\n}\n\n/// \\brief Determine whether \\p Derived has a \\p Base base class subobject at\n/// offset \\p Offset.\nstatic bool isDerivedFromAtOffset(const abi::__class_type_info *Derived,\n                                  const abi::__class_type_info *Base,\n                                  sptr Offset) {\n  if (Derived->__type_name == Base->__type_name)\n    return Offset == 0;\n\n  if (const abi::__si_class_type_info *SI =\n        dynamic_cast<const abi::__si_class_type_info*>(Derived))\n    return isDerivedFromAtOffset(SI->__base_type, Base, Offset);\n\n  const abi::__vmi_class_type_info *VTI =\n    dynamic_cast<const abi::__vmi_class_type_info*>(Derived);\n  if (!VTI)\n    // No base class subobjects.\n    return false;\n\n  // Look for a base class which is derived from \\p Base at the right offset.\n  for (unsigned int base = 0; base != VTI->base_count; ++base) {\n    // FIXME: Curtail the recursion if this base can't possibly contain the\n    //        given offset.\n    sptr OffsetHere = VTI->base_info[base].__offset_flags >>\n                      abi::__base_class_type_info::__offset_shift;\n    if (VTI->base_info[base].__offset_flags &\n          abi::__base_class_type_info::__virtual_mask)\n      // For now, just punt on virtual bases and say 'yes'.\n      // FIXME: OffsetHere is the offset in the vtable of the virtual base\n      //        offset. Read the vbase offset out of the vtable and use it.\n      return true;\n    if (isDerivedFromAtOffset(VTI->base_info[base].__base_type,\n                              Base, Offset - OffsetHere))\n      return true;\n  }\n\n  return false;\n}\n\n/// \\brief Find the derived-most dynamic base class of \\p Derived at offset\n/// \\p Offset.\nstatic const abi::__class_type_info *findBaseAtOffset(\n    const abi::__class_type_info *Derived, sptr Offset) {\n  if (!Offset)\n    return Derived;\n\n  if (const abi::__si_class_type_info *SI =\n        dynamic_cast<const abi::__si_class_type_info*>(Derived))\n    return findBaseAtOffset(SI->__base_type, Offset);\n\n  const abi::__vmi_class_type_info *VTI =\n    dynamic_cast<const abi::__vmi_class_type_info*>(Derived);\n  if (!VTI)\n    // No base class subobjects.\n    return 0;\n\n  for (unsigned int base = 0; base != VTI->base_count; ++base) {\n    sptr OffsetHere = VTI->base_info[base].__offset_flags >>\n                      abi::__base_class_type_info::__offset_shift;\n    if (VTI->base_info[base].__offset_flags &\n          abi::__base_class_type_info::__virtual_mask)\n      // FIXME: Can't handle virtual bases yet.\n      continue;\n    if (const abi::__class_type_info *Base =\n          findBaseAtOffset(VTI->base_info[base].__base_type,\n                           Offset - OffsetHere))\n      return Base;\n  }\n\n  return 0;\n}\n\nnamespace {\n\nstruct VtablePrefix {\n  /// The offset from the vptr to the start of the most-derived object.\n  /// This will only be greater than zero in some virtual base class vtables\n  /// used during object con-/destruction, and will usually be exactly zero.\n  sptr Offset;\n  /// The type_info object describing the most-derived class type.\n  std::type_info *TypeInfo;\n};\nVtablePrefix *getVtablePrefix(void *Vtable) {\n  VtablePrefix *Vptr = reinterpret_cast<VtablePrefix*>(Vtable);\n  if (!Vptr)\n    return 0;\n  VtablePrefix *Prefix = Vptr - 1;\n  if (!Prefix->TypeInfo)\n    // This can't possibly be a valid vtable.\n    return 0;\n  return Prefix;\n}\n\n}\n\nbool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) {\n  // A crash anywhere within this function probably means the vptr is corrupted.\n  // FIXME: Perform these checks more cautiously.\n\n  // Check whether this is something we've evicted from the cache.\n  HashValue *Bucket = getTypeCacheHashTableBucket(Hash);\n  if (*Bucket == Hash) {\n    __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;\n    return true;\n  }\n\n  void *VtablePtr = *reinterpret_cast<void **>(Object);\n  VtablePrefix *Vtable = getVtablePrefix(VtablePtr);\n  if (!Vtable)\n    return false;\n\n  // Check that this is actually a type_info object for a class type.\n  abi::__class_type_info *Derived =\n    dynamic_cast<abi::__class_type_info*>(Vtable->TypeInfo);\n  if (!Derived)\n    return false;\n\n  abi::__class_type_info *Base = (abi::__class_type_info*)Type;\n  if (!isDerivedFromAtOffset(Derived, Base, -Vtable->Offset))\n    return false;\n\n  // Success. Cache this result.\n  __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;\n  *Bucket = Hash;\n  return true;\n}\n\n__ubsan::DynamicTypeInfo\n__ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) {\n  VtablePrefix *Vtable = getVtablePrefix(VtablePtr);\n  if (!Vtable)\n    return DynamicTypeInfo(0, 0, 0);\n  const abi::__class_type_info *ObjectType = findBaseAtOffset(\n    static_cast<const abi::__class_type_info*>(Vtable->TypeInfo),\n    -Vtable->Offset);\n  return DynamicTypeInfo(Vtable->TypeInfo->__type_name, -Vtable->Offset,\n                         ObjectType ? ObjectType->__type_name : \"<unknown>\");\n}\n\n#endif  // CAN_SANITIZE_UB && !SANITIZER_WINDOWS\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_type_hash_win.cc",
    "content": "//===-- ubsan_type_hash_win.cc --------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Implementation of type hashing/lookup for Microsoft C++ ABI.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"sanitizer_common/sanitizer_platform.h\"\n#include \"ubsan_platform.h\"\n#if CAN_SANITIZE_UB && SANITIZER_WINDOWS\n#include \"ubsan_type_hash.h\"\n\n#include \"sanitizer_common/sanitizer_common.h\"\n\n#include <typeinfo>\n\nstruct CompleteObjectLocator {\n  int is_image_relative;\n  int offset_to_top;\n  int vfptr_offset;\n  int rtti_addr;\n  int chd_addr;\n  int obj_locator_addr;\n};\n\nstruct CompleteObjectLocatorAbs {\n  int is_image_relative;\n  int offset_to_top;\n  int vfptr_offset;\n  std::type_info *rtti_addr;\n  void *chd_addr;\n  CompleteObjectLocator *obj_locator_addr;\n};\n\nbool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) {\n  // FIXME: Implement.\n  return false;\n}\n\n__ubsan::DynamicTypeInfo\n__ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) {\n  // The virtual table may not have a complete object locator if the object\n  // was compiled without RTTI (i.e. we might be reading from some other global\n  // laid out before the virtual table), so we need to carefully validate each\n  // pointer dereference and perform sanity checks.\n  CompleteObjectLocator **obj_locator_ptr =\n    ((CompleteObjectLocator**)VtablePtr)-1;\n  if (!IsAccessibleMemoryRange((uptr)obj_locator_ptr, sizeof(void*)))\n    return DynamicTypeInfo(0, 0, 0);\n\n  CompleteObjectLocator *obj_locator = *obj_locator_ptr;\n  if (!IsAccessibleMemoryRange((uptr)obj_locator,\n                               sizeof(CompleteObjectLocator)))\n    return DynamicTypeInfo(0, 0, 0);\n\n  std::type_info *tinfo;\n  if (obj_locator->is_image_relative == 1) {\n    char *image_base = ((char *)obj_locator) - obj_locator->obj_locator_addr;\n    tinfo = (std::type_info *)(image_base + obj_locator->rtti_addr);\n  } else if (obj_locator->is_image_relative == 0)\n    tinfo = ((CompleteObjectLocatorAbs *)obj_locator)->rtti_addr;\n  else\n    // Probably not a complete object locator.\n    return DynamicTypeInfo(0, 0, 0);\n\n  if (!IsAccessibleMemoryRange((uptr)tinfo, sizeof(std::type_info)))\n    return DynamicTypeInfo(0, 0, 0);\n\n  // Okay, this is probably a std::type_info. Request its name.\n  // FIXME: Implement a base class search like we do for Itanium.\n  return DynamicTypeInfo(tinfo->name(), obj_locator->offset_to_top,\n                         \"<unknown>\");\n}\n\n#endif  // CAN_SANITIZE_UB && SANITIZER_WINDOWS\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_value.cc",
    "content": "//===-- ubsan_value.cc ----------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Representation of a runtime value, as marshaled from the generated code to\n// the ubsan runtime.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"ubsan_platform.h\"\n#if CAN_SANITIZE_UB\n#include \"ubsan_value.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n#include \"sanitizer_common/sanitizer_libc.h\"\n\nusing namespace __ubsan;\n\nSIntMax Value::getSIntValue() const {\n  CHECK(getType().isSignedIntegerTy());\n  if (isInlineInt()) {\n    // Val was zero-extended to ValueHandle. Sign-extend from original width\n    // to SIntMax.\n    const unsigned ExtraBits =\n      sizeof(SIntMax) * 8 - getType().getIntegerBitWidth();\n    return SIntMax(Val) << ExtraBits >> ExtraBits;\n  }\n  if (getType().getIntegerBitWidth() == 64)\n    return *reinterpret_cast<s64*>(Val);\n#if HAVE_INT128_T\n  if (getType().getIntegerBitWidth() == 128)\n    return *reinterpret_cast<s128*>(Val);\n#else\n  if (getType().getIntegerBitWidth() == 128)\n    UNREACHABLE(\"libclang_rt.ubsan was built without __int128 support\");\n#endif\n  UNREACHABLE(\"unexpected bit width\");\n}\n\nUIntMax Value::getUIntValue() const {\n  CHECK(getType().isUnsignedIntegerTy());\n  if (isInlineInt())\n    return Val;\n  if (getType().getIntegerBitWidth() == 64)\n    return *reinterpret_cast<u64*>(Val);\n#if HAVE_INT128_T\n  if (getType().getIntegerBitWidth() == 128)\n    return *reinterpret_cast<u128*>(Val);\n#else\n  if (getType().getIntegerBitWidth() == 128)\n    UNREACHABLE(\"libclang_rt.ubsan was built without __int128 support\");\n#endif\n  UNREACHABLE(\"unexpected bit width\");\n}\n\nUIntMax Value::getPositiveIntValue() const {\n  if (getType().isUnsignedIntegerTy())\n    return getUIntValue();\n  SIntMax Val = getSIntValue();\n  CHECK(Val >= 0);\n  return Val;\n}\n\n/// Get the floating-point value of this object, extended to a long double.\n/// These are always passed by address (our calling convention doesn't allow\n/// them to be passed in floating-point registers, so this has little cost).\nFloatMax Value::getFloatValue() const {\n  CHECK(getType().isFloatTy());\n  if (isInlineFloat()) {\n    switch (getType().getFloatBitWidth()) {\n#if 0\n      // FIXME: OpenCL / NEON 'half' type. LLVM can't lower the conversion\n      //        from '__fp16' to 'long double'.\n      case 16: {\n        __fp16 Value;\n        internal_memcpy(&Value, &Val, 4);\n        return Value;\n      }\n#endif\n      case 32: {\n        float Value;\n#if defined(__BIG_ENDIAN__)\n       // For big endian the float value is in the last 4 bytes.\n       // On some targets we may only have 4 bytes so we count backwards from\n       // the end of Val to account for both the 32-bit and 64-bit cases.\n       internal_memcpy(&Value, ((const char*)(&Val + 1)) - 4, 4);\n#else \n       internal_memcpy(&Value, &Val, 4);\n#endif\n        return Value;\n      }\n      case 64: {\n        double Value;\n        internal_memcpy(&Value, &Val, 8);\n        return Value;\n      }\n    }\n  } else {\n    switch (getType().getFloatBitWidth()) {\n    case 64: return *reinterpret_cast<double*>(Val);\n    case 80: return *reinterpret_cast<long double*>(Val);\n    case 96: return *reinterpret_cast<long double*>(Val);\n    case 128: return *reinterpret_cast<long double*>(Val);\n    }\n  }\n  UNREACHABLE(\"unexpected floating point bit width\");\n}\n\n#endif  // CAN_SANITIZE_UB\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/lib/ubsan/ubsan_value.h",
    "content": "//===-- ubsan_value.h -------------------------------------------*- C++ -*-===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n// Representation of data which is passed from the compiler-generated calls into\n// the ubsan runtime.\n//\n//===----------------------------------------------------------------------===//\n#ifndef UBSAN_VALUE_H\n#define UBSAN_VALUE_H\n\n#include \"sanitizer_common/sanitizer_atomic.h\"\n#include \"sanitizer_common/sanitizer_common.h\"\n\n// FIXME: Move this out to a config header.\n#if __SIZEOF_INT128__\n__extension__ typedef __int128 s128;\n__extension__ typedef unsigned __int128 u128;\n#define HAVE_INT128_T 1\n#else\n#define HAVE_INT128_T 0\n#endif\n\nnamespace __ubsan {\n\n/// \\brief Largest integer types we support.\n#if HAVE_INT128_T\ntypedef s128 SIntMax;\ntypedef u128 UIntMax;\n#else\ntypedef s64 SIntMax;\ntypedef u64 UIntMax;\n#endif\n\n/// \\brief Largest floating-point type we support.\ntypedef long double FloatMax;\n\n/// \\brief A description of a source location. This corresponds to Clang's\n/// \\c PresumedLoc type.\nclass SourceLocation {\n  const char *Filename;\n  u32 Line;\n  u32 Column;\n\npublic:\n  SourceLocation() : Filename(), Line(), Column() {}\n  SourceLocation(const char *Filename, unsigned Line, unsigned Column)\n    : Filename(Filename), Line(Line), Column(Column) {}\n\n  /// \\brief Determine whether the source location is known.\n  bool isInvalid() const { return !Filename; }\n\n  /// \\brief Atomically acquire a copy, disabling original in-place.\n  /// Exactly one call to acquire() returns a copy that isn't disabled.\n  SourceLocation acquire() {\n    u32 OldColumn = __sanitizer::atomic_exchange(\n                        (__sanitizer::atomic_uint32_t *)&Column, ~u32(0),\n                        __sanitizer::memory_order_relaxed);\n    return SourceLocation(Filename, Line, OldColumn);\n  }\n\n  /// \\brief Determine if this Location has been disabled.\n  /// Disabled SourceLocations are invalid to use.\n  bool isDisabled() {\n    return Column == ~u32(0);\n  }\n\n  /// \\brief Get the presumed filename for the source location.\n  const char *getFilename() const { return Filename; }\n  /// \\brief Get the presumed line number.\n  unsigned getLine() const { return Line; }\n  /// \\brief Get the column within the presumed line.\n  unsigned getColumn() const { return Column; }\n};\n\n\n/// \\brief A description of a type.\nclass TypeDescriptor {\n  /// A value from the \\c Kind enumeration, specifying what flavor of type we\n  /// have.\n  u16 TypeKind;\n\n  /// A \\c Type-specific value providing information which allows us to\n  /// interpret the meaning of a ValueHandle of this type.\n  u16 TypeInfo;\n\n  /// The name of the type follows, in a format suitable for including in\n  /// diagnostics.\n  char TypeName[1];\n\npublic:\n  enum Kind {\n    /// An integer type. Lowest bit is 1 for a signed value, 0 for an unsigned\n    /// value. Remaining bits are log_2(bit width). The value representation is\n    /// the integer itself if it fits into a ValueHandle, and a pointer to the\n    /// integer otherwise.\n    TK_Integer = 0x0000,\n    /// A floating-point type. Low 16 bits are bit width. The value\n    /// representation is that of bitcasting the floating-point value to an\n    /// integer type.\n    TK_Float = 0x0001,\n    /// Any other type. The value representation is unspecified.\n    TK_Unknown = 0xffff\n  };\n\n  const char *getTypeName() const { return TypeName; }\n\n  Kind getKind() const {\n    return static_cast<Kind>(TypeKind);\n  }\n\n  bool isIntegerTy() const { return getKind() == TK_Integer; }\n  bool isSignedIntegerTy() const {\n    return isIntegerTy() && (TypeInfo & 1);\n  }\n  bool isUnsignedIntegerTy() const {\n    return isIntegerTy() && !(TypeInfo & 1);\n  }\n  unsigned getIntegerBitWidth() const {\n    CHECK(isIntegerTy());\n    return 1 << (TypeInfo >> 1);\n  }\n\n  bool isFloatTy() const { return getKind() == TK_Float; }\n  unsigned getFloatBitWidth() const {\n    CHECK(isFloatTy());\n    return TypeInfo;\n  }\n};\n\n/// \\brief An opaque handle to a value.\ntypedef uptr ValueHandle;\n\n\n/// \\brief Representation of an operand value provided by the instrumented code.\n///\n/// This is a combination of a TypeDescriptor (which is emitted as constant data\n/// as an operand to a handler function) and a ValueHandle (which is passed at\n/// runtime when a check failure occurs).\nclass Value {\n  /// The type of the value.\n  const TypeDescriptor &Type;\n  /// The encoded value itself.\n  ValueHandle Val;\n\n  /// Is \\c Val a (zero-extended) integer?\n  bool isInlineInt() const {\n    CHECK(getType().isIntegerTy());\n    const unsigned InlineBits = sizeof(ValueHandle) * 8;\n    const unsigned Bits = getType().getIntegerBitWidth();\n    return Bits <= InlineBits;\n  }\n\n  /// Is \\c Val a (zero-extended) integer representation of a float?\n  bool isInlineFloat() const {\n    CHECK(getType().isFloatTy());\n    const unsigned InlineBits = sizeof(ValueHandle) * 8;\n    const unsigned Bits = getType().getFloatBitWidth();\n    return Bits <= InlineBits;\n  }\n\npublic:\n  Value(const TypeDescriptor &Type, ValueHandle Val) : Type(Type), Val(Val) {}\n\n  const TypeDescriptor &getType() const { return Type; }\n\n  /// \\brief Get this value as a signed integer.\n  SIntMax getSIntValue() const;\n\n  /// \\brief Get this value as an unsigned integer.\n  UIntMax getUIntValue() const;\n\n  /// \\brief Decode this value, which must be a positive or unsigned integer.\n  UIntMax getPositiveIntValue() const;\n\n  /// Is this an integer with value -1?\n  bool isMinusOne() const {\n    return getType().isSignedIntegerTy() && getSIntValue() == -1;\n  }\n\n  /// Is this a negative integer?\n  bool isNegative() const {\n    return getType().isSignedIntegerTy() && getSIntValue() < 0;\n  }\n\n  /// \\brief Get this value as a floating-point quantity.\n  FloatMax getFloatValue() const;\n};\n\n} // namespace __ubsan\n\n#endif // UBSAN_VALUE_H\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/AppleBI.mk",
    "content": "\n#\n# Make rules to build compiler_rt in Apple B&I infrastructure\n#\n\n# set ProjSrcRoot appropriately\nProjSrcRoot := $(SRCROOT)\n# set ProjObjRoot appropriately\nifdef OBJROOT\n  ProjObjRoot := $(OBJROOT)\nelse\n  ProjObjRoot := $(ProjSrcRoot)\nendif\n\nifeq (,$(RC_PURPLE))\n\tINSTALL_TARGET = install-MacOSX\nelse\n  ifeq (,$(RC_INDIGO))\n    INSTALL_TARGET = install-iOS\n  else\n    INSTALL_TARGET = install-iOS-Simulator\n  endif\nendif\n\n\n\n# Log full compile lines in B&I logs and omit summary lines.\nVerb :=\nSummary := @true\n\n# List of functions needed for each architecture.\n\n# Copies any public headers to DSTROOT.\ninstallhdrs:\n\n\n# Copies source code to SRCROOT.\ninstallsrc:\n\tcp -r . $(SRCROOT)\n\n\ninstall:  $(INSTALL_TARGET)\n\n# Copy results to DSTROOT.\ninstall-MacOSX : $(SYMROOT)/libcompiler_rt.dylib \\\n                 $(SYMROOT)/libcompiler_rt-dyld.a \n\tmkdir -p $(DSTROOT)/usr/local/lib/dyld\n\tcp $(SYMROOT)/libcompiler_rt-dyld.a  \\\n\t\t\t\t    $(DSTROOT)/usr/local/lib/dyld/libcompiler_rt.a\n\tmkdir -p $(DSTROOT)/usr/lib/system\n\t$(call GetCNAVar,STRIP,Platform.darwin_bni,Release,) -S $(SYMROOT)/libcompiler_rt.dylib \\\n\t    -o $(DSTROOT)/usr/lib/system/libcompiler_rt.dylib\n\tcd $(DSTROOT)/usr/lib/system; \\\n\t    ln -s libcompiler_rt.dylib libcompiler_rt_profile.dylib; \\\n\t    ln -s libcompiler_rt.dylib libcompiler_rt_debug.dylib\n\n# Rule to make each dylib slice\n$(OBJROOT)/libcompiler_rt-%.dylib : $(OBJROOT)/darwin_bni/Release/%/libcompiler_rt.a\n\techo \"const char vers[] = \\\"@(#) $(RC_ProjectName)-$(RC_ProjectSourceVersion)\\\"; \" > $(OBJROOT)/version.c\n\t$(call GetCNAVar,CC,Platform.darwin_bni,Release,$*) \\\n\t   $(OBJROOT)/version.c -arch $* -dynamiclib \\\n\t   -install_name /usr/lib/system/libcompiler_rt.dylib \\\n\t   -compatibility_version 1 -current_version $(RC_ProjectSourceVersion) \\\n\t   -nodefaultlibs -umbrella System -dead_strip \\\n\t   -Wl,-upward-lunwind \\\n\t   -Wl,-upward-lsystem_m \\\n\t   -Wl,-upward-lsystem_c \\\n\t   -Wl,-upward-lsystem_kernel \\\n\t   -Wl,-upward-lsystem_platform \\\n\t   -Wl,-ldyld \\\n\t   -L$(SDKROOT)/usr/lib/system \\\n\t   $(DYLIB_FLAGS) -Wl,-force_load,$^ -o $@ \n\n# Rule to make fat dylib\n$(SYMROOT)/libcompiler_rt.dylib: $(foreach arch,$(filter-out armv4t,$(RC_ARCHS)), \\\n                                        $(OBJROOT)/libcompiler_rt-$(arch).dylib)\n\t$(call GetCNAVar,LIPO,Platform.darwin_bni,Release,) -create $^ -o  $@\n\t$(call GetCNAVar,DSYMUTIL,Platform.darwin_bni,Release,) $@\n\n\n# Copy results to DSTROOT.\ninstall-iOS: $(SYMROOT)/libcompiler_rt-static.a \\\n             $(SYMROOT)/libcompiler_rt-dyld.a \\\n             $(SYMROOT)/libcompiler_rt.dylib\n\tmkdir -p $(DSTROOT)/usr/local/lib\n\tcp $(SYMROOT)/libcompiler_rt-static.a  \\\n\t\t\t\t    $(DSTROOT)/usr/local/lib/libcompiler_rt-static.a\n\tmkdir -p $(DSTROOT)/usr/local/lib/dyld\n\tcp $(SYMROOT)/libcompiler_rt-dyld.a  \\\n\t\t\t\t    $(DSTROOT)/usr/local/lib/dyld/libcompiler_rt.a\n\tmkdir -p $(DSTROOT)/usr/lib/system\n\t$(call GetCNAVar,STRIP,Platform.darwin_bni,Release,) -S $(SYMROOT)/libcompiler_rt.dylib \\\n\t    -o $(DSTROOT)/usr/lib/system/libcompiler_rt.dylib\n\n# Rule to make fat archive\n$(SYMROOT)/libcompiler_rt-static.a : $(foreach arch,$(RC_ARCHS), \\\n                         $(OBJROOT)/darwin_bni/Static/$(arch)/libcompiler_rt.a)\n\t$(call GetCNAVar,LIPO,Platform.darwin_bni,Release,) -create $^ -o  $@\n\n# rule to make each archive slice for dyld (which removes a few archive members)\n$(OBJROOT)/libcompiler_rt-dyld-%.a : $(OBJROOT)/darwin_bni/Release/%/libcompiler_rt.a\n\tcp $^ $@\n\tDEL_LIST=`$(AR)  -t $@ | egrep 'apple_versioning|gcc_personality_v0|eprintf' | xargs echo` ; \\\n\tif [ -n \"$${DEL_LIST}\" ] ; \\\n\tthen  \\\n\t\t$(call GetCNAVar,AR,Platform.darwin_bni,Release,) -d $@ $${DEL_LIST}; \\\n\t\t$(call GetCNAVar,RANLIB,Platform.darwin_bni,Release,) $@ ; \\\n\tfi\n\n# rule to make make archive for dyld\n$(SYMROOT)/libcompiler_rt-dyld.a : $(foreach arch,$(RC_ARCHS), \\\n                         $(OBJROOT)/libcompiler_rt-dyld-$(arch).a)\n\t$(call GetCNAVar,LIPO,Platform.darwin_bni,Release,) -create $^ -o  $@\n\n\n\n# Copy results to DSTROOT.\ninstall-iOS-Simulator: $(SYMROOT)/libcompiler_rt_sim.dylib \\\n                       $(SYMROOT)/libcompiler_rt-dyld.a\n\tmkdir -p $(DSTROOT)/$(SDKROOT)/usr/lib/system\n\t$(call GetCNAVar,STRIP,Platform.darwin_bni,Release,) -S $(SYMROOT)/libcompiler_rt_sim.dylib \\\n\t    -o $(DSTROOT)/$(SDKROOT)/usr/lib/system/libcompiler_rt_sim.dylib\n\tmkdir -p $(DSTROOT)/$(SDKROOT)/usr/local/lib/dyld\n\tcp $(SYMROOT)/libcompiler_rt-dyld.a  \\\n\t\t\t\t    $(DSTROOT)/$(SDKROOT)/usr/local/lib/dyld/libcompiler_rt.a\n  \n# Rule to make fat dylib\n$(SYMROOT)/libcompiler_rt_sim.dylib: $(foreach arch,$(RC_ARCHS), \\\n                                        $(OBJROOT)/libcompiler_rt_sim-$(arch).dylib)\n\t$(call GetCNAVar,LIPO,Platform.darwin_bni,Release,) -create $^ -o  $@\n\t$(call GetCNAVar,DSYMUTIL,Platform.darwin_bni,Release,) $@\n\n# Rule to make each dylib slice\n$(OBJROOT)/libcompiler_rt_sim-%.dylib : $(OBJROOT)/darwin_bni/Release/%/libcompiler_rt.a\n\techo \"const char vers[] = \\\"@(#) $(RC_ProjectName)-$(RC_ProjectSourceVersion)\\\"; \" > $(OBJROOT)/version.c\n\t$(call GetCNAVar,CC,Platform.darwin_bni,Release,$*) \\\n\t   $(OBJROOT)/version.c -arch $* -dynamiclib \\\n\t   -install_name /usr/lib/system/libcompiler_rt_sim.dylib \\\n\t   -compatibility_version 1 -current_version $(RC_ProjectSourceVersion) \\\n     -Wl,-unexported_symbol,___enable_execute_stack \\\n\t   -nostdlib \\\n\t   -Wl,-upward-lunwind_sim \\\n\t   -Wl,-upward-lsystem_sim_m \\\n\t   -Wl,-upward-lsystem_sim_c \\\n\t   -ldyld_sim \\\n\t   -Wl,-upward-lSystem \\\n\t   -umbrella System -Wl,-no_implicit_dylibs -L$(SDKROOT)/usr/lib/system -dead_strip \\\n\t   $(DYLIB_FLAGS) -Wl,-force_load,$^ -o $@ \n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/config.mk",
    "content": "###\n# Configuration variables.\n\nOS := $(shell uname)\n\n# Assume make is always run from top-level of source directory. Note than an\n# Apple style build overrides these variables later in the makefile.\nProjSrcRoot := $(shell pwd)\nProjObjRoot := $(ProjSrcRoot)\n\n# The list of modules which are required to be built into every library. This\n# should only be used for internal utilities which could be used in any other\n# module. Any other cases the platform should be allowed to opt-in to.\nAlwaysRequiredModules := int_util\n\n###\n# Tool configuration variables.\n\n# FIXME: LLVM uses autoconf/mkinstalldirs ?\nMKDIR := mkdir -p\nDATE := date\nLIPO := lipo\nCP := cp\nDSYMUTIL := dsymutil\n\nVERBOSE := 0\nDEBUGMAKE :=\n\n###\n# Automatic and derived variables.\n\n# Adjust settings for verbose mode\nifneq ($(VERBOSE),1)\n  Verb := @\nelse\n  Verb :=\nendif\n\nEcho := @echo\nifndef Summary\n  Summary = $(Echo)\nendif\n\n###\n# Common compiler options\nCOMMON_INCLUDES=-I${ProjSrcRoot}/lib -I${ProjSrcRoot}/include\nCOMMON_CXXFLAGS=-std=c++11 -fno-exceptions -fPIC -funwind-tables $(COMMON_INCLUDES)\nCOMMON_CFLAGS=-fPIC $(COMMON_INCLUDES)\nCOMMON_ASMFLAGS=$(COMMON_INCLUDES)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/filter-inputs",
    "content": "#!/usr/bin/env python\n\n#===- make/filter-inputs ---------------------------------------------------===#\n#\n#                     The LLVM Compiler Infrastructure\n#\n# This file is distributed under the University of Illinois Open Source\n# License. See LICENSE.TXT for details.\n#\n#===------------------------------------------------------------------------===#\n\n# Given a list of files, return a new list of files taking only the\n# first file for any particular filename.\ndef main():\n    import os,sys\n    \n    seen = set()\n    for file in sys.argv[1:]:\n        base = os.path.basename(file)\n        if base not in seen:\n            seen.add(base)\n            print file\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/lib_info.mk",
    "content": "# compiler-rt Library Info\n#\n# This should be included once the subdirectory information has been loaded, and\n# uses the utilities in 'util.mk'.\n#\n# This defines the following variables describing compiler-rt:\n#   AvailableFunctions   - The entire list of function names (unmangled) the\n#                          library can provide.\n#   CommonFunctions      - The list of generic functions available.\n#   ArchFunctions.<arch> - The list of functions commonly available for\n#                          'arch'. This does not include any config specific\n#                          functions.\n#\n#   AvailableIn.<function> - The list of subdir keys where 'function' is\n#                            defined.\n\n# Determine the set of available modules.\nAvailableModules := $(sort $(foreach key,$(SubDirKeys),\\\n\t$($(key).ModuleName)))\n\n# Build a per-module map of subdir keys.\n$(foreach key,$(SubDirKeys),\\\n\t$(call Append,ModuleSubDirKeys.$($(key).ModuleName),$(key)))\n\nAvailableArchs := $(sort $(foreach key,$(SubDirKeys),\\\n\t$($(key).OnlyArchs)))\n\nAvailableFunctions := $(sort $(foreach key,$(SubDirKeys),\\\n\t$(basename $($(key).ObjNames))))\n\nCommonFunctions := $(sort\\\n  $(foreach key,$(ModuleSubDirKeys.builtins),\\\n    $(if $(call strneq,,$(strip $($(key).OnlyArchs) $($(key).OnlyConfigs))),,\\\n         $(basename $($(key).ObjNames)))))\n\n# Compute common arch functions.\n$(foreach key,$(ModuleSubDirKeys.builtins),\\\n  $(if $(call strneq,,$($(key).OnlyConfigs)),,\\\n    $(foreach arch,$($(key).OnlyArchs),\\\n      $(call Append,ArchFunctions.$(arch),$(sort \\\n        $(basename $($(key).ObjNames)))))))\n\n# Compute arch only functions.\n$(foreach arch,$(AvailableArchs),\\\n  $(call Set,ArchFunctions.$(arch),$(sort $(ArchFunctions.$(arch))))\\\n  $(call Set,ArchOnlyFunctions.$(arch),\\\n    $(call set_difference,$(ArchFunctions.$(arch)),$(CommonFunctions))))\n\n# Compute lists of where each function is available.\n$(foreach key,$(SubDirKeys),\\\n  $(foreach fn,$(basename $($(key).ObjNames)),\\\n    $(call Append,AvailableIn.$(fn),$(key))))\n\n# The names of all the available options.\nAvailableOptions := AR ARFLAGS \\\n                    CC CFLAGS LDFLAGS FUNCTIONS OPTIMIZED \\\n                    RANLIB RANLIBFLAGS \\\n                    VISIBILITY_HIDDEN KERNEL_USE \\\n                    SHARED_LIBRARY SHARED_LIBRARY_SUFFIX STRIP LIPO DSYMUTIL\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/lib_platforms.mk",
    "content": "# compiler-rt Configuration Support\n#\n# This should be included following 'lib_util.mk'.\n\n# The simple variables configurations can define.\nPlainConfigVariables := Configs Description\nPerConfigVariables := UniversalArchs Arch $(AvailableOptions)\nRequiredConfigVariables := Configs Description\n\n###\n# Load Platforms\n\n# Template: subdir_traverse_template subdir\ndefine load_platform_template\n$(call Set,PlatformName,$(basename $(notdir $(1))))\nifneq ($(DEBUGMAKE),)\n  $$(info MAKE: $(PlatformName): Loading platform)\nendif\n\n# Construct the variable key for this directory.\n$(call Set,PlatformKey,Platform.$(PlatformName))\n$(call Append,PlatformKeys,$(PlatformKey))\n$(call Set,$(PlatformKey).Name,$(PlatformName))\n$(call Set,$(PlatformKey).Path,$(1))\n\n# Reset platform specific variables to sentinel value.\n$$(foreach var,$(PlainConfigVariables) $(PerConfigVariables),\\\n  $$(call Set,$$(var),UNDEFINED))\n$$(foreach var,$(PerConfigVariables),\\\n  $$(foreach config,$$(Configs),\\\n    $$(call Set,$$(var).$$(config),UNDEFINED)))\n$$(foreach var,$(PerConfigVariables),\\\n  $$(foreach arch,$(AvailableArchs),\\\n    $$(call Set,$$(var).$$(arch),UNDEFINED)))\n\n# Get the platform variables.\ninclude make/options.mk\ninclude $(1)\n\n# Check for undefined required variables.\n$$(foreach var,$(RequiredConfigVariables),\\\n  $$(if $$(call strneq,UNDEFINED,$$($$(var))),, \\\n\t$$(error $(Dir): variable '$$(var)' was not undefined)))\n\n# Check that exactly one of UniversalArchs or Arch was defined.\n$$(if $$(and $$(call strneq,UNDEFINED,$$(UniversalArchs)),\\\n             $$(call strneq,UNDEFINED,$$(Arch))),\\\n    $$(error '$(1)': cannot define both 'UniversalArchs' and 'Arch'))\n$$(if $$(or $$(call strneq,UNDEFINED,$$(UniversalArchs)),\\\n            $$(call strneq,UNDEFINED,$$(Arch))),,\\\n    $$(error '$(1)': must define one of 'UniversalArchs' and 'Arch'))\n\n# Collect all the platform variables for subsequent use.\n$$(foreach var,$(PlainConfigVariables) $(PerConfigVariables),\\\n  $$(if $$(call strneq,UNDEFINED,$$($$(var))),\\\n    $$(call CopyVariable,$$(var),$(PlatformKey).$$(var))))\n$$(foreach var,$(PerConfigVariables),\\\n  $$(foreach config,$$(Configs),\\\n    $$(if $$(call strneq,UNDEFINED,$$($$(var).$$(config))),\\\n      $$(call CopyVariable,$$(var).$$(config),$(PlatformKey).$$(var).$$(config))))\\\n  $$(foreach arch,$(AvailableArchs),\\\n    $$(if $$(call strneq,UNDEFINED,$$($$(var).$$(arch))),\\\n      $$(call CopyVariable,$$(var).$$(arch),$(PlatformKey).$$(var).$$(arch))))\\\n  $$(foreach config,$$(Configs),\\\n    $$(foreach arch,$(AvailableArchs),\\\n      $$(if $$(call strneq,UNDEFINED,$$($$(var).$$(config).$$(arch))),\\\n        $$(call CopyVariable,$$(var).$$(config).$$(arch),\\\n                $(PlatformKey).$$(var).$$(config).$$(arch))))))\n\nifneq ($(DEBUGMAKE),)\n  $$(info MAKE: $(PlatformName): Done loading platform)\nendif\nendef\n\n# Evaluate this now so we do not have to worry about order of evaluation.\nPlatformFiles := $(wildcard make/platform/*.mk)\nifneq ($(DEBUGMAKE),)\n $(info MAKE: Loading platforms: $(PlatformFiles))\nendif\n\n$(foreach file,$(PlatformFiles),\\\n  $(eval $(call load_platform_template,$(file))))\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/lib_util.mk",
    "content": "# Library Utility Functions\n#\n# This should be included following 'lib_info.mk'.\n\n# Function: GetCNAVar variable-name platform-key config arch\n#\n# Get a per-config-and-arch variable value.\nGetCNAVar = $(strip \\\n  $(or $($(2).$(1).$(3).$(4)), \\\n       $($(2).$(1).$(3)), \\\n       $($(2).$(1).$(4)), \\\n       $($(2).$(1))))\n\n# Function: SelectFunctionDir config arch function-name optimized\n#\n# Choose the appropriate implementation directory to use for 'function-name' in\n# the configuration 'config' and on given arch.\nSelectFunctionDir = $(strip \\\n  $(call Set,Tmp.SelectFunctionDir,$(call SelectFunctionDirs,$(1),$(2),$(3),$(4)))\\\n  $(if $(call streq,1,$(words $(Tmp.SelectFunctionDir))),\\\n       $(Tmp.SelectFunctionDir),\\\n       $(error SelectFunctionDir: invalid function name \"$(3)\" ($(strip\\\n               $(if $(call streq,0,$(words $(Tmp.SelectFunctionDir))),\\\n                    no such function,\\\n                    function implemented in multiple directories!!!))))))\n\n# Helper functions that select the entire list of subdirs where a function is\n# defined with a certain specificity.\nSelectFunctionDirs_Opt_ConfigAndArch = $(strip \\\n  $(foreach key,$(AvailableIn.$(3)),\\\n    $(if $(and $(call streq,Optimized,$($(key).Implementation)),\\\n               $(call contains,$($(key).OnlyConfigs),$(1)),\\\n               $(call contains,$($(key).OnlyArchs),$(2))),$(key),)))\nSelectFunctionDirs_Opt_Config = $(strip \\\n  $(foreach key,$(AvailableIn.$(3)),\\\n    $(if $(and $(call streq,Optimized,$($(key).Implementation)),\\\n               $(call contains,$($(key).OnlyConfigs),$(1))),$(key),)))\nSelectFunctionDirs_Opt_Arch = $(strip \\\n  $(foreach key,$(AvailableIn.$(3)),\\\n    $(if $(and $(call streq,Optimized,$($(key).Implementation)),\\\n               $(call contains,$($(key).OnlyArchs),$(2))),$(key),)))\nSelectFunctionDirs_Gen = $(strip \\\n  $(foreach key,$(AvailableIn.$(3)),\\\n    $(if $(call streq,Generic,$($(key).Implementation)),$(key))))\n\n# Helper function to select the right set of dirs in generic priority order.\nSelectFunctions_Gen = \\\n  $(or $(call SelectFunctionDirs_Gen,$(1),$(2),$(3)),\\\n       $(call SelectFunctionDirs_Opt_ConfigAndArch,$(1),$(2),$(3)), \\\n       $(call SelectFunctionDirs_Opt_Config,$(1),$(2),$(3)), \\\n       $(call SelectFunctionDirs_Opt_Arch,$(1),$(2),$(3)))\n\n# Helper function to select the right set of dirs in optimized priority order.\nSelectFunctions_Opt = \\\n  $(or $(call SelectFunctionDirs_Opt_ConfigAndArch,$(1),$(2),$(3)), \\\n       $(call SelectFunctionDirs_Opt_Config,$(1),$(2),$(3)), \\\n       $(call SelectFunctionDirs_Opt_Arch,$(1),$(2),$(3)), \\\n       $(call SelectFunctionDirs_Gen,$(1),$(2),$(3)))\n\n# Helper function to select the right set of dirs (which should be exactly one)\n# for a function.\nSelectFunctionDirs = \\\n  $(if $(call streq,1,$(4)),\\\n       $(call SelectFunctions_Opt,$(1),$(2),$(3)),\\\n       $(call SelectFunctions_Gen,$(1),$(2),$(3)))\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/options.mk",
    "content": "# Options which may be overriden for platforms, etc.\n#\n# This list of such variables should be kept up to date with AvailableOptions in\n# 'make/lib_info.mk'.\n\n# The compiler to use.\nCC := gcc\n\n# The compiler flags to use.\nCFLAGS := -Wall -Werror\n\n# The list of functions to include in the library.\nFUNCTIONS :=\n\n# Whether optimized function implementations should be used.\nOPTIMIZED := 1\n\n# Whether function definitions should use hidden visibility. This adds the\n# -fvisibility=hidden compiler option and uses .private_extern annotations in\n# assembly files.\n#\n# FIXME: Make this more portable. When that is done, it should probably be the\n# default.\nVISIBILITY_HIDDEN := 0\n\n# Whether the library is being built for kernel use.\nKERNEL_USE := 0\n\n# Whether the library should be built as a shared object.\nSHARED_LIBRARY := 0\n\n# Miscellaneous tools.\n\nAR := ar\n# FIXME: Remove these pipes once ranlib errors are fixed.\nARFLAGS := cru 2> /dev/null\n\nLDFLAGS :=\n\nRANLIB := ranlib\n# FIXME: Remove these pipes once ranlib errors are fixed.\nRANLIBFLAGS := 2> /dev/null\n\nSTRIP := strip\nLIPO := lipo\nDSYMUTIL := dsymutil\n\nSHARED_LIBRARY_SUFFIX := so\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/platform/clang_darwin.mk",
    "content": "# These are the functions which clang needs when it is targeting a previous\n# version of the OS. The issue is that the backend may use functions which were\n# not present in the libgcc that shipped on the platform. In such cases, we link\n# with a version of the library which contains private_extern definitions of all\n# the extra functions which might be referenced.\n\nDescription := Static runtime libraries for clang/Darwin.\n\n# A function that ensures we don't try to build for architectures and SDKs\n# that we don't have working toolchains for. Arguments:\n# (1): List of architectures\n# (2): Library name\n# (3): SDK path\n# The result is a possibly empty subset of the architectures from argument 1.\nCheckArches = \\\n  $(shell \\\n    result=\"\"; \\\n    if [ \"X$(3)\" != X ]; then \\\n      for arch in $(1); do \\\n        if $(LD) -v 2>&1 | grep \"configured to support\" \\\n             | tr ' ' '\\n' | grep \"^$$arch$$\" >/dev/null 2>/dev/null; then \\\n          if $(CC) -arch $$arch \\\n            -integrated-as \\\n            $(ProjSrcRoot)/make/platform/clang_darwin_test_input.c \\\n            -isysroot $(3) \\\n            -o /dev/null > /dev/null 2> /dev/null; then \\\n              result=\"$$result$$arch \"; \\\n          else \\\n            printf 1>&2 \\\n             \"warning: clang_darwin.mk: dropping arch '$$arch' from lib '$(2)'\"; \\\n            printf 1>&2 \" (clang or system libraries do not support it)\\n\"; \\\n          fi; \\\n        else \\\n          printf 1>&2 \\\n            \"warning: clang_darwin.mk: dropping arch '$$arch' from lib '$(2)'\";\\\n          printf 1>&2 \" (ld does not support it)\\n\"; \\\n        fi; \\\n      done; \\\n    fi; \\\n    echo $$result)\n\nXCRun = \\\n  $(shell \\\n    result=`xcrun -find $(1) 2> /dev/null`; \\\n    if [ \"$$?\" != \"0\" ]; then result=$(1); fi; \\\n    echo $$result)\n# Prefer building with the internal SDKs.\nXCRunSdkPath = \\\n  $(shell \\\n    result=`xcrun --sdk $(1).internal --show-sdk-path 2> /dev/null`; \\\n    if [ \"$$?\" != \"0\" ]; then \\\n      result=`xcrun --sdk $(1) --show-sdk-path 2> /dev/null`; \\\n      if [ \"$$?\" != \"0\" ]; then result=\"\"; fi; \\\n    fi; \\\n    echo $$result)\n###\n\nCC       := $(call XCRun,clang)\nLD       := $(shell $(CC) -print-prog-name=ld)\nAR       := $(call XCRun,ar)\nRANLIB   := $(call XCRun,ranlib)\nSTRIP    := $(call XCRun,strip)\nLIPO     := $(call XCRun,lipo)\nDSYMUTIL := $(call XCRun,dsymutil)\n\nOSX_SDK := $(call XCRunSdkPath,macosx)\nIOS_SDK := $(call XCRunSdkPath,iphoneos)\nIOSSIM_SDK := $(call XCRunSdkPath,iphonesimulator)\n\nConfigs :=\nUniversalArchs :=\n\n# Configuration solely for providing access to an eprintf symbol, which may\n# still be referenced from Darwin system headers. This symbol is only ever\n# needed on i386.\nConfigs += eprintf\nUniversalArchs.eprintf := $(call CheckArches,i386,eprintf,$(OSX_SDK))\n\n# Configuration for targeting 10.4. We need a few functions missing from\n# libgcc_s.10.4.dylib. We only build x86 slices since clang doesn't really\n# support targeting PowerPC.\nConfigs += 10.4\nUniversalArchs.10.4 := $(call CheckArches,i386 x86_64,10.4,$(OSX_SDK))\n\n# Configuration for targeting iOS for a couple of functions that didn't\n# make it into libSystem.\nConfigs += ios\nUniversalArchs.ios := $(call CheckArches,i386 x86_64,ios,$(IOSSIM_SDK))\nUniversalArchs.ios += $(call CheckArches,armv7 arm64,ios,$(IOS_SDK))\n\n# Configuration for targeting OSX. These functions may not be in libSystem\n# so we should provide our own.\nConfigs += osx\nUniversalArchs.osx := $(call CheckArches,i386 x86_64 x86_64h,osx,$(OSX_SDK))\n\n# Configuration for use with kernel/kexts.\nConfigs += cc_kext\nUniversalArchs.cc_kext := $(call CheckArches,i386 x86_64 x86_64h,cc_kext,$(OSX_SDK))\n\n# Configuration for use with iOS kernel/kexts\nConfigs += cc_kext_ios\nUniversalArchs.cc_kext_ios += $(call CheckArches,armv7,cc_kext_ios,$(IOS_SDK))\n\n# Configurations which define the profiling support functions.\nConfigs += profile_osx\nUniversalArchs.profile_osx := $(call CheckArches,i386 x86_64 x86_64h,profile_osx,$(OSX_SDK))\nConfigs += profile_ios\nUniversalArchs.profile_ios := $(call CheckArches,i386 x86_64,profile_ios,$(IOSSIM_SDK))\nUniversalArchs.profile_ios += $(call CheckArches,armv7 arm64,profile_ios,$(IOS_SDK))\n\n# Configurations which define the ASAN support functions.\nConfigs += asan_osx_dynamic\nUniversalArchs.asan_osx_dynamic := $(call CheckArches,i386 x86_64 x86_64h,asan_osx_dynamic,$(OSX_SDK))\n\nConfigs += asan_iossim_dynamic\nUniversalArchs.asan_iossim_dynamic := $(call CheckArches,i386 x86_64,asan_iossim_dynamic,$(IOSSIM_SDK))\n\nConfigs += ubsan_osx_dynamic\nUniversalArchs.ubsan_osx_dynamic := $(call CheckArches,i386 x86_64 x86_64h,ubsan_osx_dynamic,$(OSX_SDK))\n\nConfigs += ubsan_iossim_dynamic\nUniversalArchs.ubsan_iossim_dynamic := $(call CheckArches,i386 x86_64,ubsan_iossim_dynamic,$(IOSSIM_SDK))\n\n# Darwin 10.6 has a bug in cctools that makes it unable to use ranlib on our ARM\n# object files. If we are on that platform, strip out all ARM archs. We still\n# build the libraries themselves so that Clang can find them where it expects\n# them, even though they might not have an expected slice.\nifneq ($(shell test -x /usr/bin/sw_vers && sw_vers -productVersion | grep 10.6),)\nUniversalArchs.ios := $(filter-out armv7, $(UniversalArchs.ios))\nUniversalArchs.cc_kext_ios := $(filter-out armv7, $(UniversalArchs.cc_kext_ios))\nUniversalArchs.profile_ios := $(filter-out armv7, $(UniversalArchs.profile_ios))\nendif\n\n# If RC_SUPPORTED_ARCHS is defined, treat it as a list of the architectures we\n# are intended to support and limit what we try to build to that.\nifneq ($(RC_SUPPORTED_ARCHS),)\n$(foreach config,$(Configs),\\\n  $(call Set,UniversalArchs.$(config),\\\n\t$(filter $(RC_SUPPORTED_ARCHS),$(UniversalArchs.$(config)))))\nendif\n\n# Remove empty configs if we end up dropping all the requested\n# archs for a particular config.\n$(foreach config,$(Configs),\\\n  $(if $(strip $(UniversalArchs.$(config))),,\\\n\t$(call Set,Configs,$(filter-out $(config),$(Configs)))))\n\n###\n\n# Forcibly strip off any -arch, as that totally breaks our universal support.\noverride CC := $(subst -arch ,-arch_,$(CC))\noverride CC := $(patsubst -arch_%,,$(CC))\n\nCFLAGS := -Wall -Werror -O3 -fomit-frame-pointer\n\n# Always set deployment target arguments for every build, these libraries should\n# never depend on the environmental overrides. We simply set them to minimum\n# supported deployment target -- nothing in the compiler-rt libraries should\n# actually depend on the deployment target.\nOSX_DEPLOYMENT_ARGS := -mmacosx-version-min=10.4\nIOS_DEPLOYMENT_ARGS := -mios-version-min=1.0\nIOS6_DEPLOYMENT_ARGS := -mios-version-min=6.0\nIOSSIM_DEPLOYMENT_ARGS := -mios-simulator-version-min=1.0\n\nOSX_DEPLOYMENT_ARGS += -isysroot $(OSX_SDK)\nIOS_DEPLOYMENT_ARGS += -isysroot $(IOS_SDK)\nIOS6_DEPLOYMENT_ARGS += -isysroot $(IOS_SDK)\nIOSSIM_DEPLOYMENT_ARGS += -isysroot $(IOSSIM_SDK)\n\nCFLAGS.eprintf\t\t:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)\nCFLAGS.10.4\t\t:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)\n\nSANITIZER_MACOSX_DEPLOYMENT_ARGS := -mmacosx-version-min=10.7\nSANITIZER_IOSSIM_DEPLOYMENT_ARGS := -mios-simulator-version-min=7.0 \\\n  -isysroot $(IOSSIM_SDK)\nSANITIZER_CFLAGS := -fno-builtin -gline-tables-only -stdlib=libc++\n\nCFLAGS.asan_osx_dynamic := \\\n\t$(CFLAGS) $(SANITIZER_MACOSX_DEPLOYMENT_ARGS) \\\n\t$(SANITIZER_CFLAGS) \\\n\t-DMAC_INTERPOSE_FUNCTIONS=1 \\\n\t-DASAN_DYNAMIC=1\n\nCFLAGS.asan_iossim_dynamic := \\\n\t$(CFLAGS) $(SANITIZER_IOSSIM_DEPLOYMENT_ARGS) \\\n\t$(SANITIZER_CFLAGS) \\\n\t-DMAC_INTERPOSE_FUNCTIONS=1 \\\n\t-DASAN_DYNAMIC=1\n\nCFLAGS.ubsan_osx_dynamic := \\\n\t$(CFLAGS) $(SANITIZER_MACOSX_DEPLOYMENT_ARGS) \\\n\t$(SANITIZER_CFLAGS)\n\nCFLAGS.ubsan_iossim_dynamic := \\\n\t$(CFLAGS) $(SANITIZER_IOSSIM_DEPLOYMENT_ARGS) \\\n\t$(SANITIZER_CFLAGS)\n\n\nCFLAGS.ios.i386\t\t:= $(CFLAGS) $(IOSSIM_DEPLOYMENT_ARGS)\nCFLAGS.ios.x86_64\t:= $(CFLAGS) $(IOSSIM_DEPLOYMENT_ARGS)\nCFLAGS.ios.armv7\t:= $(CFLAGS) $(IOS_DEPLOYMENT_ARGS)\nCFLAGS.ios.armv7k\t:= $(CFLAGS) $(IOS_DEPLOYMENT_ARGS)\nCFLAGS.ios.armv7s\t:= $(CFLAGS) $(IOS_DEPLOYMENT_ARGS)\nCFLAGS.ios.arm64\t:= $(CFLAGS) $(IOS6_DEPLOYMENT_ARGS)\nCFLAGS.osx.i386\t\t:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)\nCFLAGS.osx.x86_64\t:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)\nCFLAGS.osx.x86_64h\t:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)\nCFLAGS.cc_kext.i386\t:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)\nCFLAGS.cc_kext.x86_64\t:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)\nCFLAGS.cc_kext.x86_64h\t:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)\nCFLAGS.cc_kext_ios.armv7\t:= $(CFLAGS) $(IOS6_DEPLOYMENT_ARGS)\nCFLAGS.cc_kext_ios.armv7k\t:= $(CFLAGS) $(IOS6_DEPLOYMENT_ARGS)\nCFLAGS.cc_kext_ios.armv7s\t:= $(CFLAGS) $(IOS6_DEPLOYMENT_ARGS)\nCFLAGS.cc_kext_ios.arm64\t:= $(CFLAGS) $(IOS6_DEPLOYMENT_ARGS)\nCFLAGS.profile_osx.i386    := $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)\nCFLAGS.profile_osx.x86_64  := $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)\nCFLAGS.profile_osx.x86_64h := $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)\nCFLAGS.profile_ios.i386    := $(CFLAGS) $(IOSSIM_DEPLOYMENT_ARGS)\nCFLAGS.profile_ios.x86_64  := $(CFLAGS) $(IOSSIM_DEPLOYMENT_ARGS)\nCFLAGS.profile_ios.armv7  := $(CFLAGS) $(IOS_DEPLOYMENT_ARGS)\nCFLAGS.profile_ios.armv7k := $(CFLAGS) $(IOS_DEPLOYMENT_ARGS)\nCFLAGS.profile_ios.armv7s := $(CFLAGS) $(IOS_DEPLOYMENT_ARGS)\nCFLAGS.profile_ios.arm64  := $(CFLAGS) $(IOS6_DEPLOYMENT_ARGS)\n\nSANITIZER_LDFLAGS := -stdlib=libc++ -lc++ -lc++abi\n\nSHARED_LIBRARY.asan_osx_dynamic := 1\nLDFLAGS.asan_osx_dynamic := $(SANITIZER_LDFLAGS) -install_name @rpath/libclang_rt.asan_osx_dynamic.dylib \\\n  $(SANITIZER_MACOSX_DEPLOYMENT_ARGS)\n\nSHARED_LIBRARY.asan_iossim_dynamic := 1\nLDFLAGS.asan_iossim_dynamic := $(SANITIZER_LDFLAGS) -install_name @rpath/libclang_rt.asan_iossim_dynamic.dylib \\\n  -Wl,-ios_simulator_version_min,7.0.0 $(SANITIZER_IOSSIM_DEPLOYMENT_ARGS)\n\nSHARED_LIBRARY.ubsan_osx_dynamic := 1\nLDFLAGS.ubsan_osx_dynamic := $(SANITIZER_LDFLAGS) -install_name @rpath/libclang_rt.ubsan_osx_dynamic.dylib \\\n  $(SANITIZER_MACOSX_DEPLOYMENT_ARGS)\n\nSHARED_LIBRARY.ubsan_iossim_dynamic := 1\nLDFLAGS.ubsan_iossim_dynamic := $(SANITIZER_LDFLAGS) -install_name @rpath/libclang_rt.ubsan_iossim_dynamic.dylib \\\n  -Wl,-ios_simulator_version_min,7.0.0 $(SANITIZER_IOSSIM_DEPLOYMENT_ARGS)\n\nifneq ($(OSX_SDK),)\nCFLAGS.asan_osx_dynamic += -isysroot $(OSX_SDK)\nLDFLAGS.asan_osx_dynamic += -isysroot $(OSX_SDK)\nCFLAGS.ubsan_osx_dynamic += -isysroot $(OSX_SDK)\nLDFLAGS.ubsan_osx_dynamic += -isysroot $(OSX_SDK)\nendif\n\nATOMIC_FUNCTIONS := \\\n\tatomic_flag_clear \\\n\tatomic_flag_clear_explicit \\\n\tatomic_flag_test_and_set \\\n\tatomic_flag_test_and_set_explicit \\\n\tatomic_signal_fence \\\n\tatomic_thread_fence\n\nFP16_FUNCTIONS := \\\n\textendhfsf2 \\\n\ttruncdfhf2 \\\n\ttruncsfhf2\n\nFUNCTIONS.eprintf := eprintf\nFUNCTIONS.10.4 := eprintf floatundidf floatundisf floatundixf\n\nFUNCTIONS.ios\t    := divmodsi4 udivmodsi4 mulosi4 mulodi4 muloti4 \\\n                       $(ATOMIC_FUNCTIONS) $(FP16_FUNCTIONS)\n# On x86, the divmod functions reference divsi.\nFUNCTIONS.ios.i386    := $(FUNCTIONS.ios) \\\n                         divsi3 udivsi3\nFUNCTIONS.ios.x86_64  := $(FUNCTIONS.ios.i386)\nFUNCTIONS.ios.arm64   := mulsc3 muldc3 divsc3 divdc3 udivti3 umodti3 \\\n                         $(ATOMIC_FUNCTIONS)\n\nFUNCTIONS.osx\t:= mulosi4 mulodi4 muloti4 $(ATOMIC_FUNCTIONS) $(FP16_FUNCTIONS)\n\nFUNCTIONS.profile_osx := GCDAProfiling InstrProfiling InstrProfilingBuffer \\\n                         InstrProfilingFile InstrProfilingPlatformDarwin \\\n                         InstrProfilingRuntime InstrProfilingUtil \\\n                         InstrProfilingWriter InstrProfilingValue\nFUNCTIONS.profile_ios := $(FUNCTIONS.profile_osx)\n\nFUNCTIONS.asan_osx_dynamic := $(AsanFunctions) $(AsanCXXFunctions) \\\n                              $(InterceptionFunctions) \\\n                              $(SanitizerCommonFunctions) \\\n                              $(AsanDynamicFunctions) \\\n                              $(UbsanFunctions) $(UbsanCXXFunctions)\n\nFUNCTIONS.asan_iossim_dynamic := $(AsanFunctions) $(AsanCXXFunctions) \\\n                                 $(InterceptionFunctions) \\\n                                 $(SanitizerCommonFunctions) \\\n                                 $(AsanDynamicFunctions) \\\n                                 $(UbsanFunctions) $(UbsanCXXFunctions)\n\nFUNCTIONS.ubsan_osx_dynamic := $(UbsanFunctions) $(UbsanCXXFunctions) \\\n                               $(SanitizerCommonFunctions) \\\n                               $(UbsanStandaloneFunctions)\n\nFUNCTIONS.ubsan_iossim_dynamic := $(UbsanFunctions) $(UbsanCXXFunctions) \\\n                                  $(SanitizerCommonFunctions) \\\n                                  $(UbsanStandaloneFunctions)\n\nCCKEXT_PROFILE_FUNCTIONS := \\\n\tInstrProfiling \\\n\tInstrProfilingBuffer \\\n\tInstrProfilingPlatformDarwin\n\nCCKEXT_COMMON_FUNCTIONS := \\\n\t$(CCKEXT_PROFILE_FUNCTIONS) \\\n\tabsvdi2 \\\n\tabsvsi2 \\\n\taddvdi3 \\\n\taddvsi3 \\\n\tashldi3 \\\n\tashrdi3 \\\n\tbswapdi2 \\\n\tbswapsi2 \\\n\tclzdi2 \\\n\tclzsi2 \\\n\tcmpdi2 \\\n\tctzdi2 \\\n\tctzsi2 \\\n\tdivdc3 \\\n\tdivdi3 \\\n\tdivsc3 \\\n\tdivmodsi4 \\\n\tudivmodsi4 \\\n\tdo_global_dtors \\\n\teprintf \\\n\textendhfsf2 \\\n\tffsdi2 \\\n\tfixdfdi \\\n\tfixsfdi \\\n\tfixunsdfdi \\\n\tfixunsdfsi \\\n\tfixunssfdi \\\n\tfixunssfsi \\\n\tfloatdidf \\\n\tfloatdisf \\\n\tfloatundidf \\\n\tfloatundisf \\\n\tgcc_bcmp \\\n\tlshrdi3 \\\n\tmoddi3 \\\n\tmuldc3 \\\n\tmuldi3 \\\n\tmulsc3 \\\n\tmulvdi3 \\\n\tmulvsi3 \\\n\tnegdi2 \\\n\tnegvdi2 \\\n\tnegvsi2 \\\n\tparitydi2 \\\n\tparitysi2 \\\n\tpopcountdi2 \\\n\tpopcountsi2 \\\n\tpowidf2 \\\n\tpowisf2 \\\n\tsubvdi3 \\\n\tsubvsi3 \\\n\ttruncdfhf2 \\\n\ttruncsfhf2 \\\n\tucmpdi2 \\\n\tudiv_w_sdiv \\\n\tudivdi3 \\\n\tudivmoddi4 \\\n\tumoddi3\n\nCCKEXT_ARM_FUNCTIONS := $(CCKEXT_COMMON_FUNCTIONS) \\\n\tadddf3 \\\n\taddsf3 \\\n\taeabi_cdcmpeq \\\n\taeabi_cdrcmple \\\n\taeabi_cfcmpeq \\\n\taeabi_cfrcmple \\\n\taeabi_dcmpeq \\\n\taeabi_dcmpge \\\n\taeabi_dcmpgt \\\n\taeabi_dcmple \\\n\taeabi_dcmplt \\\n\taeabi_drsub \\\n\taeabi_fcmpeq \\\n\taeabi_fcmpge \\\n\taeabi_fcmpgt \\\n\taeabi_fcmple \\\n\taeabi_fcmplt \\\n\taeabi_frsub \\\n\taeabi_idivmod \\\n\taeabi_uidivmod \\\n\tcmpdf2 \\\n\tcmpsf2 \\\n\tdiv0 \\\n\tdivdf3 \\\n\tdivsf3 \\\n\tdivsi3 \\\n\textendsfdf2 \\\n\tffssi2 \\\n\tfixdfsi \\\n\tfixsfsi \\\n\tfloatsidf \\\n\tfloatsisf \\\n\tfloatunsidf \\\n\tfloatunsisf \\\n\tcomparedf2 \\\n\tcomparesf2 \\\n\tmodsi3 \\\n\tmuldf3 \\\n\tmulsf3 \\\n\tmulodi4 \\\n\tnegdf2 \\\n\tnegsf2 \\\n\tsubdf3 \\\n\tsubsf3 \\\n\tswitch16 \\\n\tswitch32 \\\n\tswitch8 \\\n\tswitchu8 \\\n\ttruncdfsf2 \\\n\tudivsi3 \\\n\tumodsi3 \\\n\tunorddf2 \\\n\tunordsf2\n\nCCKEXT_ARMVFP_FUNCTIONS := $(CCKEXT_ARM_FUNCTIONS) \\\n\tadddf3vfp \\\n\taddsf3vfp \\\n\tdivdf3vfp \\\n\tdivsf3vfp \\\n\teqdf2vfp \\\n\teqsf2vfp \\\n\textendsfdf2vfp \\\n\tfixdfsivfp \\\n\tfixsfsivfp \\\n\tfixunsdfsivfp \\\n\tfixunssfsivfp \\\n\tfloatsidfvfp \\\n\tfloatsisfvfp \\\n\tfloatunssidfvfp \\\n\tfloatunssisfvfp \\\n\tgedf2vfp \\\n\tgesf2vfp \\\n\tgtdf2vfp \\\n\tgtsf2vfp \\\n\tledf2vfp \\\n\tlesf2vfp \\\n\tltdf2vfp \\\n\tltsf2vfp \\\n\tmuldf3vfp \\\n\tmulsf3vfp \\\n\tnedf2vfp \\\n\tnesf2vfp \\\n\tsubdf3vfp \\\n\tsubsf3vfp \\\n\ttruncdfsf2vfp \\\n\tunorddf2vfp \\\n\tunordsf2vfp\n\nCCKEXT_ARM64_FUNCTIONS := \\\n\t$(CCKEXT_PROFILE_FUNCTIONS) \\\n\tdivdc3 \\\n\tdivsc3 \\\n\tmuldc3 \\\n\tmulsc3 \\\n\tudivti3 \\\n\tumodti3\n\nFUNCTIONS.cc_kext_ios.armv7 := $(CCKEXT_ARMVFP_FUNCTIONS)\nFUNCTIONS.cc_kext_ios.armv7k := $(CCKEXT_ARMVFP_FUNCTIONS)\nFUNCTIONS.cc_kext_ios.armv7s := $(CCKEXT_ARMVFP_FUNCTIONS)\nFUNCTIONS.cc_kext_ios.arm64 := $(CCKEXT_ARM64_FUNCTIONS)\n\nCCKEXT_X86_FUNCTIONS := $(CCKEXT_COMMON_FUNCTIONS) \\\n\tdivxc3 \\\n\tfixunsxfdi \\\n\tfixunsxfsi \\\n\tfixxfdi \\\n\tfloatdixf \\\n\tfloatundixf \\\n\tmulxc3 \\\n\tpowixf2\n\nFUNCTIONS.cc_kext.i386 := $(CCKEXT_X86_FUNCTIONS) \\\n\tffssi2 \\\n\ti686.get_pc_thunk.eax \\\n\ti686.get_pc_thunk.ebp \\\n\ti686.get_pc_thunk.ebx \\\n\ti686.get_pc_thunk.ecx \\\n\ti686.get_pc_thunk.edi \\\n\ti686.get_pc_thunk.edx \\\n\ti686.get_pc_thunk.esi\n\nFUNCTIONS.cc_kext.x86_64 := $(CCKEXT_X86_FUNCTIONS) \\\n\tabsvti2 \\\n\taddvti3 \\\n\tashlti3 \\\n\tashrti3 \\\n\tclzti2 \\\n\tcmpti2 \\\n\tctzti2 \\\n\tdivti3 \\\n\tffsti2 \\\n\tfixdfti \\\n\tfixsfti \\\n\tfixunsdfti \\\n\tfixunssfti \\\n\tfixunsxfti \\\n\tfixxfti \\\n\tfloattidf \\\n\tfloattisf \\\n\tfloattixf \\\n\tfloatuntidf \\\n\tfloatuntisf \\\n\tfloatuntixf \\\n\tlshrti3 \\\n\tmodti3 \\\n\tmulti3 \\\n\tmulvti3 \\\n\tnegti2 \\\n\tnegvti2 \\\n\tparityti2 \\\n\tpopcountti2 \\\n\tsubvti3 \\\n\tucmpti2 \\\n\tudivmodti4 \\\n\tudivti3 \\\n\tumodti3\n\nFUNCTIONS.cc_kext.x86_64h := $(FUNCTIONS.cc_kext.x86_64)\n\n# FIXME: Currently, compiler-rt is missing implementations for a number of the\n# functions that need to go into libcc_kext.a. Filter them out for now.\nCCKEXT_MISSING_FUNCTIONS := \\\n\tcmpdf2 cmpsf2 div0 \\\n\tffssi2 \\\n\tudiv_w_sdiv unorddf2 unordsf2 bswapdi2 \\\n\tbswapsi2 \\\n\tgcc_bcmp \\\n\tdo_global_dtors \\\n\ti686.get_pc_thunk.eax i686.get_pc_thunk.ebp i686.get_pc_thunk.ebx \\\n\ti686.get_pc_thunk.ecx i686.get_pc_thunk.edi i686.get_pc_thunk.edx \\\n\ti686.get_pc_thunk.esi \\\n\taeabi_cdcmpeq aeabi_cdrcmple aeabi_cfcmpeq aeabi_cfrcmple aeabi_dcmpeq \\\n\taeabi_dcmpge aeabi_dcmpgt aeabi_dcmple aeabi_dcmplt aeabi_drsub aeabi_fcmpeq \\\n\taeabi_fcmpge aeabi_fcmpgt aeabi_fcmple aeabi_fcmplt aeabi_frsub aeabi_idivmod \\\n\taeabi_uidivmod\n\nFUNCTIONS.cc_kext_ios.armv7 := \\\n\t$(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext_ios.armv7))\nFUNCTIONS.cc_kext_ios.armv7k := \\\n\t$(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext_ios.armv7k))\nFUNCTIONS.cc_kext_ios.armv7s := \\\n\t$(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext_ios.armv7s))\nFUNCTIONS.cc_kext_ios.arm64 := \\\n\t$(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext_ios.arm64))\nFUNCTIONS.cc_kext.i386 := \\\n\t$(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext.i386))\nFUNCTIONS.cc_kext.x86_64 := \\\n\t$(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext.x86_64))\nFUNCTIONS.cc_kext.x86_64h := \\\n\t$(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext.x86_64h))\n\nKERNEL_USE.cc_kext := 1\nKERNEL_USE.cc_kext_ios := 1\n\nVISIBILITY_HIDDEN := 1\n\nSHARED_LIBRARY_SUFFIX := dylib\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/platform/clang_darwin_test_input.c",
    "content": "/* Include the headers we use in int_lib.h, to verify that they work. */\n\n#include <limits.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n\n// Force us to link at least one symbol in a system library\n// to detect systems where we don't have those for a given\n// architecture.\nint main(int argc, const char **argv) {\n    int x;\n    memcpy(&x,&argc,sizeof(int));\n}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/platform/clang_linux.mk",
    "content": "Description := Static runtime libraries for clang/Linux.\n\n###\n\nCC := clang\nArch := unknown\nConfigs :=\n\n# We don't currently have any general purpose way to target architectures other\n# than the compiler defaults (because there is no generalized way to invoke\n# cross compilers). For now, we just find the target architecture of the\n# compiler and only define configurations we know that compiler can generate.\nCompilerTargetTriple := $(shell \\\n\tLANG=C $(CC) -v 2>&1 | grep 'Target:' | cut -d' ' -f2)\nifeq ($(CompilerTargetTriple),)\n$(error \"unable to infer compiler target triple for $(CC)\")\nendif\n\n# Only define configs if we detected a linux target.\nifneq ($(findstring -linux-,$(CompilerTargetTriple)),)\n\n# Define configs only if arch in triple is i386 or x86_64\nCompilerTargetArch := $(firstword $(subst -, ,$(CompilerTargetTriple)))\nifeq ($(call contains,i386 x86_64,$(CompilerTargetArch)),true)\n\n# TryCompile compiler source flags\n# Returns exit code of running a compiler invocation.\nTryCompile = \\\n  $(shell \\\n    cflags=\"\"; \\\n    for flag in $(3); do \\\n      cflags=\"$$cflags $$flag\"; \\\n    done; \\\n    $(1) $$cflags $(2) -o /dev/null > /dev/null 2> /dev/null ; \\\n    echo $$?)\n\ntest_source = $(ProjSrcRoot)/make/platform/clang_linux_test_input.c\nifeq ($(CompilerTargetArch),i386)\n  SupportedArches := i386\n  ifeq ($(call TryCompile,$(CC),$(test_source),-m64),0)\n    SupportedArches += x86_64\n  endif\nelse\n  SupportedArches := x86_64\n  ifeq ($(call TryCompile,$(CC),$(test_source),-m32),0)\n    SupportedArches += i386\n  endif\nendif\n\n# Build runtime libraries for i386.\nifeq ($(call contains,$(SupportedArches),i386),true)\nConfigs += builtins-i386 profile-i386\nArch.builtins-i386 := i386\nArch.profile-i386 := i386\nendif\n\n# Build runtime libraries for x86_64.\nifeq ($(call contains,$(SupportedArches),x86_64),true)\nConfigs += builtins-x86_64 profile-x86_64\nArch.builtins-x86_64 := x86_64\nArch.profile-x86_64 := x86_64\nendif\n\nendif\n\nendif\n\n###\n\nCFLAGS := -Wall -Werror -O3 -fomit-frame-pointer\n\nCFLAGS.builtins-i386 := $(CFLAGS) -m32\nCFLAGS.builtins-x86_64 := $(CFLAGS) -m64\nCFLAGS.profile-i386 := $(CFLAGS) -m32\nCFLAGS.profile-x86_64 := $(CFLAGS) -m64\n\nFUNCTIONS.builtins-i386 := $(CommonFunctions) $(ArchFunctions.i386)\nFUNCTIONS.builtins-x86_64 := $(CommonFunctions) $(ArchFunctions.x86_64)\nFUNCTIONS.profile-i386 := GCDAProfiling InstrProfiling InstrProfilingBuffer \\\n                          InstrProfilingFile InstrProfilingPlatformOther \\\n                          InstrProfilingRuntime InstrProfilingUtil \\\n                          InstrProfilingWriter InstrProfilingValue\nFUNCTIONS.profile-x86_64 := $(FUNCTIONS.profile-i386)\n\n# Always use optimized variants.\nOPTIMIZED := 1\n\n# We don't need to use visibility hidden on Linux.\nVISIBILITY_HIDDEN := 0\n\nSHARED_LIBRARY_SUFFIX := so\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/platform/clang_linux_test_input.c",
    "content": "// This file is used to check if we can produce working executables\n// for i386 and x86_64 archs on Linux.\n#include <stdlib.h>\nint main(){}\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/platform/clang_macho_embedded.mk",
    "content": "# These are the functions which clang needs when it is targeting a previous\n# version of the OS. The issue is that the backend may use functions which were\n# not present in the libgcc that shipped on the platform. In such cases, we link\n# with a version of the library which contains private_extern definitions of all\n# the extra functions which might be referenced.\n\nDescription := Static runtime libraries for embedded clang/Darwin\n\n# A function that ensures we don't try to build for architectures that we\n# don't have working toolchains for.\nCheckArches = \\\n  $(shell \\\n    result=\"\"; \\\n    for arch in $(1); do \\\n      if $(CC) -arch $$arch -c \\\n\t  -integrated-as \\\n\t  $(ProjSrcRoot)/make/platform/clang_macho_embedded_test_input.c \\\n\t  -o /dev/null > /dev/null 2> /dev/null; then \\\n        result=\"$$result$$arch \"; \\\n      else \\\n\tprintf 1>&2 \\\n\t  \"warning: clang_macho_embedded.mk: dropping arch '$$arch' from lib '$(2)'\\n\"; \\\n      fi; \\\n    done; \\\n    echo $$result)\n\nXCRun = \\\n  $(shell \\\n    result=`xcrun -find $(1) 2> /dev/null`; \\\n    if [ \"$$?\" != \"0\" ]; then result=$(1); fi; \\\n    echo $$result)\n\n###\n\nCC       := $(call XCRun,clang)\nAR       := $(call XCRun,ar)\nRANLIB   := $(call XCRun,ranlib)\nSTRIP    := $(call XCRun,strip)\nLIPO     := $(call XCRun,lipo)\nDSYMUTIL := $(call XCRun,dsymutil)\n\nConfigs :=\nUniversalArchs :=\n\n# Soft-float version of the runtime. No floating-point instructions will be used\n# and the ABI (out of necessity) passes floating values in normal registers:\n# non-VFP variant of the AAPCS.\nUniversalArchs.soft_static := $(call CheckArches,armv6m armv7m armv7em armv7,soft_static)\nConfigs += $(if $(UniversalArchs.soft_static),soft_static)\n\n# Hard-float version of the runtime. On ARM VFP instructions and registers are\n# allowed, and floating point values get passed in them. VFP variant of the\n# AAPCS.\nUniversalArchs.hard_static := $(call CheckArches,armv7em armv7 i386 x86_64,hard_static)\nConfigs += $(if $(UniversalArchs.hard_static),hard_static)\n\nUniversalArchs.soft_pic := $(call CheckArches,armv6m armv7m armv7em armv7,soft_pic)\nConfigs += $(if $(UniversalArchs.soft_pic),soft_pic)\n\nUniversalArchs.hard_pic := $(call CheckArches,armv7em armv7 i386 x86_64,hard_pic)\nConfigs += $(if $(UniversalArchs.hard_pic),hard_pic)\n\nCFLAGS := -Wall -Werror -Oz -fomit-frame-pointer -ffreestanding\n\nPIC_CFLAGS := -fPIC\nSTATIC_CFLAGS := -static\n\nCFLAGS_SOFT := -mfloat-abi=soft\nCFLAGS_HARD := -mfloat-abi=hard\n\nCFLAGS_ARMV7 := -target thumbv7-apple-darwin-eabi\nCFLAGS_I386  := -march=pentium\n\nCFLAGS.soft_static := $(CFLAGS) $(STATIC_CFLAGS) $(CFLAGS_SOFT)\nCFLAGS.hard_static := $(CFLAGS) $(STATIC_CFLAGS) $(CFLAGS_HARD)\nCFLAGS.soft_pic    := $(CFLAGS) $(PIC_CFLAGS) $(CFLAGS_SOFT)\nCFLAGS.hard_pic    := $(CFLAGS) $(PIC_CFLAGS) $(CFLAGS_HARD)\n\nCFLAGS.soft_static.armv7 := $(CFLAGS.soft_static) $(CFLAGS_ARMV7)\nCFLAGS.hard_static.armv7 := $(CFLAGS.hard_static) $(CFLAGS_ARMV7)\nCFLAGS.soft_pic.armv7    := $(CFLAGS.soft_pic) $(CFLAGS_ARMV7)\nCFLAGS.hard_pic.armv7    := $(CFLAGS.hard_pic) $(CFLAGS_ARMV7)\n\n# x86 platforms ignore -mfloat-abi options and complain about doing so. Despite\n# this they're hard-float.\nCFLAGS.hard_static.i386   := $(CFLAGS) $(STATIC_CFLAGS) $(CFLAGS_I386)\nCFLAGS.hard_pic.i386      := $(CFLAGS) $(PIC_CFLAGS) $(CFLAGS_I386)\nCFLAGS.hard_static.x86_64 := $(CFLAGS) $(STATIC_CFLAGS)\nCFLAGS.hard_pic.x86_64    := $(CFLAGS) $(PIC_CFLAGS)\n\n# Functions not wanted:\n#   + eprintf is obsolete anyway\n#   + *vfp: designed for Thumb1 CPUs with VFPv2\n\nCOMMON_FUNCTIONS := \\\n\tabsvdi2 \\\n\tabsvsi2 \\\n\taddvdi3 \\\n\taddvsi3 \\\n\tashldi3 \\\n\tashrdi3 \\\n\tbswapdi2 \\\n\tbswapsi2 \\\n\tclzdi2 \\\n\tclzsi2 \\\n\tcmpdi2 \\\n\tctzdi2 \\\n\tctzsi2 \\\n\tdivdc3 \\\n\tdivdi3 \\\n\tdivsc3 \\\n\tdivmodsi4 \\\n\tudivmodsi4 \\\n\tdo_global_dtors \\\n\tffsdi2 \\\n\tfixdfdi \\\n\tfixsfdi \\\n\tfixunsdfdi \\\n\tfixunsdfsi \\\n\tfixunssfdi \\\n\tfixunssfsi \\\n\tfloatdidf \\\n\tfloatdisf \\\n\tfloatundidf \\\n\tfloatundisf \\\n\tgcc_bcmp \\\n\tlshrdi3 \\\n\tmoddi3 \\\n\tmuldc3 \\\n\tmuldi3 \\\n\tmulsc3 \\\n\tmulvdi3 \\\n\tmulvsi3 \\\n\tnegdi2 \\\n\tnegvdi2 \\\n\tnegvsi2 \\\n\tparitydi2 \\\n\tparitysi2 \\\n\tpopcountdi2 \\\n\tpopcountsi2 \\\n\tpowidf2 \\\n\tpowisf2 \\\n\tsubvdi3 \\\n\tsubvsi3 \\\n\tucmpdi2 \\\n\tudiv_w_sdiv \\\n\tudivdi3 \\\n\tudivmoddi4 \\\n\tumoddi3 \\\n\tadddf3 \\\n\taddsf3 \\\n\tcmpdf2 \\\n\tcmpsf2 \\\n\tdiv0 \\\n\tdivdf3 \\\n\tdivsf3 \\\n\tdivsi3 \\\n\textendsfdf2 \\\n\textendhfsf2 \\\n\tffssi2 \\\n\tfixdfsi \\\n\tfixsfsi \\\n\tfloatsidf \\\n\tfloatsisf \\\n\tfloatunsidf \\\n\tfloatunsisf \\\n\tcomparedf2 \\\n\tcomparesf2 \\\n\tmodsi3 \\\n\tmuldf3 \\\n\tmulsf3 \\\n\tnegdf2 \\\n\tnegsf2 \\\n\tsubdf3 \\\n\tsubsf3 \\\n\ttruncdfhf2 \\\n\ttruncdfsf2 \\\n\ttruncsfhf2 \\\n\tudivsi3 \\\n\tumodsi3 \\\n\tunorddf2 \\\n\tunordsf2 \\\n\tatomic_flag_clear \\\n\tatomic_flag_clear_explicit \\\n\tatomic_flag_test_and_set \\\n\tatomic_flag_test_and_set_explicit \\\n\tatomic_signal_fence \\\n\tatomic_thread_fence\n\nARM_FUNCTIONS := \\\n\taeabi_cdcmpeq \\\n\taeabi_cdrcmple \\\n\taeabi_cfcmpeq \\\n\taeabi_cfrcmple \\\n\taeabi_dcmpeq \\\n\taeabi_dcmpge \\\n\taeabi_dcmpgt \\\n\taeabi_dcmple \\\n\taeabi_dcmplt \\\n\taeabi_drsub \\\n\taeabi_fcmpeq \\\n\taeabi_fcmpge \\\n\taeabi_fcmpgt \\\n\taeabi_fcmple \\\n\taeabi_fcmplt \\\n\taeabi_frsub \\\n\taeabi_idivmod \\\n\taeabi_uidivmod \\\n\n# ARM Assembly implementation which requires Thumb2 (i.e. won't work on v6M).\nTHUMB2_FUNCTIONS := \\\n\tswitch16 \\\n\tswitch32 \\\n\tswitch8 \\\n\tswitchu8 \\\n\tsync_fetch_and_add_4 \\\n\tsync_fetch_and_sub_4 \\\n\tsync_fetch_and_and_4 \\\n\tsync_fetch_and_or_4 \\\n\tsync_fetch_and_xor_4 \\\n\tsync_fetch_and_nand_4 \\\n\tsync_fetch_and_max_4 \\\n\tsync_fetch_and_umax_4 \\\n\tsync_fetch_and_min_4 \\\n\tsync_fetch_and_umin_4 \\\n\tsync_fetch_and_add_8 \\\n\tsync_fetch_and_sub_8 \\\n\tsync_fetch_and_and_8 \\\n\tsync_fetch_and_or_8 \\\n\tsync_fetch_and_xor_8 \\\n\tsync_fetch_and_nand_8 \\\n\tsync_fetch_and_max_8 \\\n\tsync_fetch_and_umax_8 \\\n\tsync_fetch_and_min_8 \\\n\tsync_fetch_and_umin_8\n\nI386_FUNCTIONS :=  \\\n\ti686.get_pc_thunk.eax \\\n\ti686.get_pc_thunk.ebp \\\n\ti686.get_pc_thunk.ebx \\\n\ti686.get_pc_thunk.ecx \\\n\ti686.get_pc_thunk.edi \\\n\ti686.get_pc_thunk.edx \\\n\ti686.get_pc_thunk.esi\n\n# FIXME: Currently, compiler-rt is missing implementations for a number of the\n# functions. Filter them out for now.\nMISSING_FUNCTIONS := \\\n\tcmpdf2 cmpsf2 div0 \\\n\tffssi2 \\\n\tudiv_w_sdiv unorddf2 unordsf2 bswapdi2 \\\n\tbswapsi2 \\\n\tgcc_bcmp \\\n\tdo_global_dtors \\\n\ti686.get_pc_thunk.eax i686.get_pc_thunk.ebp i686.get_pc_thunk.ebx \\\n\ti686.get_pc_thunk.ecx i686.get_pc_thunk.edi i686.get_pc_thunk.edx \\\n\ti686.get_pc_thunk.esi \\\n\taeabi_cdcmpeq aeabi_cdrcmple aeabi_cfcmpeq aeabi_cfrcmple aeabi_dcmpeq \\\n\taeabi_dcmpge aeabi_dcmpgt aeabi_dcmple aeabi_dcmplt aeabi_drsub \\\n\taeabi_fcmpeq \\ aeabi_fcmpge aeabi_fcmpgt aeabi_fcmple aeabi_fcmplt \\\n\taeabi_frsub aeabi_idivmod aeabi_uidivmod\n\nFUNCTIONS_ARMV6M  := $(COMMON_FUNCTIONS) $(ARM_FUNCTIONS)\nFUNCTIONS_ARM_ALL := $(COMMON_FUNCTIONS) $(ARM_FUNCTIONS) $(THUMB2_FUNCTIONS)\nFUNCTIONS_I386    := $(COMMON_FUNCTIONS) $(I386_FUNCTIONS)\nFUNCTIONS_X86_64  := $(COMMON_FUNCTIONS)\n\nFUNCTIONS_ARMV6M := \\\n\t$(filter-out $(MISSING_FUNCTIONS),$(FUNCTIONS_ARMV6M))\nFUNCTIONS_ARM_ALL := \\\n\t$(filter-out $(MISSING_FUNCTIONS),$(FUNCTIONS_ARM_ALL))\nFUNCTIONS_I386 := \\\n\t$(filter-out $(MISSING_FUNCTIONS),$(FUNCTIONS_I386))\nFUNCTIONS_X86_64 := \\\n\t$(filter-out $(MISSING_FUNCTIONS),$(FUNCTIONS_X86_64))\n\nFUNCTIONS.soft_static.armv6m := $(FUNCTIONS_ARMV6M)\nFUNCTIONS.soft_pic.armv6m    := $(FUNCTIONS_ARMV6M)\n\nFUNCTIONS.soft_static.armv7m := $(FUNCTIONS_ARM_ALL)\nFUNCTIONS.soft_pic.armv7m    := $(FUNCTIONS_ARM_ALL)\n\nFUNCTIONS.soft_static.armv7em := $(FUNCTIONS_ARM_ALL)\nFUNCTIONS.hard_static.armv7em := $(FUNCTIONS_ARM_ALL)\nFUNCTIONS.soft_pic.armv7em    := $(FUNCTIONS_ARM_ALL)\nFUNCTIONS.hard_pic.armv7em    := $(FUNCTIONS_ARM_ALL)\n\nFUNCTIONS.soft_static.armv7 := $(FUNCTIONS_ARM_ALL)\nFUNCTIONS.hard_static.armv7 := $(FUNCTIONS_ARM_ALL)\nFUNCTIONS.soft_pic.armv7    := $(FUNCTIONS_ARM_ALL)\nFUNCTIONS.hard_pic.armv7    := $(FUNCTIONS_ARM_ALL)\n\nFUNCTIONS.hard_static.i386 := $(FUNCTIONS_I386)\nFUNCTIONS.hard_pic.i386    := $(FUNCTIONS_I386)\n\nFUNCTIONS.hard_static.x86_64 := $(FUNCTIONS_X86_64)\nFUNCTIONS.hard_pic.x86_64    := $(FUNCTIONS_X86_64)\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/platform/clang_macho_embedded_test_input.c",
    "content": ""
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/platform/clang_mingw.mk",
    "content": "Description := Static runtime libraries for mingw-w64\n\n###\n\nCC ?= cc\nAR ?= ar\n\nArch := unknown\nConfigs :=\n\nSupportedArches := x86_64 i386 arm\n\nConfigs += builtins-x86_64 builtins-i386 builtins-arm\nArch.builtins-x86_64 := x86_64\nArch.builtins-i386 := i386\nArch.builtins-arm := arm\n\n###\n\nCFLAGS := -Wall -O3 -fomit-frame-pointer\nCFLAGS.builtins-x86_64 := -target x86_64-windows-gnu $(CFLAGS)\nCFLAGS.builtins-i386 := -target i686-windows-gnu $(CFLAGS)\nCFLAGS.builtins-arm := -target armv7-windows-gnu $(CFLAGS)\n\nFUNCTIONS.builtins-x86_64 := $(CommonFunctions) $(ArchFunctions.x86_64)\nFUNCTIONS.builtins-i386 := $(CommonFunctions) $(ArchFunctions.i386)\nFUNCTIONS.builtins-arm := $(CommonFunctions) $(ArchFunctions.arm)\n\n# Always use optimized variants.\nOPTIMIZED := 1\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/platform/darwin_bni.mk",
    "content": "\nDescription := Target for Darwin using an Apple-style build.\n\nConfigs := Debug Release Profile Static\n\n# We override this with RC_ARCHS because B&I may want to build on an ARCH we\n# haven't explicitly defined support for. If all goes well, this will just work\n# and the resulting lib will just have generic versions for anything unknown.\nUniversalArchs := $(RC_ARCHS)\n\nifneq (,$(SDKROOT))\n\toverride CC := $(shell xcrun -sdk $(SDKROOT) -find clang || echo \"false\") \n\tAR := $(shell xcrun -sdk $(SDKROOT) -find ar || echo \"false\") \n\tRANLIB := $(shell xcrun -sdk $(SDKROOT) -find ranlib || echo \"false\") \n\tSTRIP := $(shell xcrun -sdk $(SDKROOT) -find strip || echo \"false\") \n\tLIPO := $(shell xcrun -sdk $(SDKROOT) -find lipo || echo \"false\")\n\tDSYMUTIL := $(shell xcrun -sdk $(SDKROOT) -find dsymutil || echo \"false\")\nendif\n\nifneq ($(IPHONEOS_DEPLOYMENT_TARGET),)\n\tDEPLOYMENT_FLAGS := -miphoneos-version-min=$(IPHONEOS_DEPLOYMENT_TARGET) \nelse\n\tifneq ($(MACOSX_DEPLOYMENT_TARGET),)\n\t\tDEPLOYMENT_FLAGS := -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) \n\tendif\nendif\n\nifneq (,$(SDKROOT))\n\tDEPLOYMENT_FLAGS += -isysroot $(SDKROOT)\nendif\n\nCFLAGS := -Wall -Os -fomit-frame-pointer -g $(DEPLOYMENT_FLAGS)\nCFLAGS.Static := $(CFLAGS) -static  \nDYLIB_FLAGS := $(DEPLOYMENT_FLAGS) \\\n\t\t-Xarch_arm -Wl,-alias_list,$(SRCROOT)/lib/builtins/arm/softfloat-alias.list\n\nVISIBILITY_HIDDEN := 0\nVISIBILITY_HIDDEN.Static  := 1\n\n\nFUNCTIONS := absvdi2 absvsi2 addvdi3 addvsi3 ashldi3 ashrdi3 \\\n             clzdi2 clzsi2 cmpdi2 ctzdi2 ctzsi2 \\\n             divdc3 divdi3 divsc3 ffsdi2 \\\n             fixdfdi fixsfdi fixunsdfdi fixunsdfsi fixunssfdi \\\n             fixunssfsi floatdidf floatdisf floatundidf floatundisf \\\n             gcc_personality_v0 lshrdi3 moddi3 muldc3 muldi3 mulosi4 \\\n             mulodi4 muloti4 mulsc3 mulvdi3 mulvsi3 negdi2 negvdi2 negvsi2 \\\n             paritydi2 paritysi2 popcountdi2 popcountsi2 powidf2 \\\n             powisf2 subvdi3 subvsi3 ucmpdi2 udivdi3 \\\n             udivmoddi4 umoddi3 apple_versioning eprintf atomic \\\n             atomic_flag_clear atomic_flag_clear_explicit \\\n             atomic_flag_test_and_set atomic_flag_test_and_set_explicit \\\n             atomic_signal_fence atomic_thread_fence \\\n             extendhfsf2 truncdfhf2 truncsfhf2 \n\nFUNCTIONS.i386 := $(FUNCTIONS) \\\n                divxc3 fixunsxfdi fixunsxfsi fixxfdi floatdixf \\\n                floatundixf mulxc3 powixf2 clear_cache \\\n                enable_execute_stack\nFUNCTIONS.ppc := $(FUNCTIONS) \\\n                divtc3 fixtfdi fixunstfdi floatditf floatunditf \\\n                gcc_qadd gcc_qdiv gcc_qmul gcc_qsub multc3 \\\n                powitf2 restFP saveFP trampoline_setup \\\n                clear_cache enable_execute_stack\nFUNCTIONS.x86_64 := $(FUNCTIONS) \\\n                absvti2 addvti3 ashlti3 ashrti3 clzti2 cmpti2 \\\n                ctzti2 divti3 divxc3 ffsti2 fixdfti fixsfti \\\n                fixunsdfti fixunssfti fixunsxfdi fixunsxfsi \\\n                fixunsxfti fixxfdi fixxfti floatdixf floattidf \\\n                floattisf floattixf floatundixf floatuntidf \\\n                floatuntisf floatuntixf lshrti3 modti3 multi3 \\\n                muloti4 mulvti3 mulxc3 negti2 negvti2 parityti2 \\\n                popcountti2 powixf2 subvti3 ucmpti2 udivmodti4 \\\n                udivti3 umodti3 clear_cache enable_execute_stack\n\nFUNCTIONS.armv4t := $(FUNCTIONS) \n\nFUNCTIONS.armv5 := $(FUNCTIONS) \\\n                adddf3 addsf3 bswapdi2 bswapsi2  \\\n                comparedf2 comparesf2 extendsfdf2 \\\n                divdf3 divsf3 \\\n                fixdfsi fixsfsi fixunsdfsi fixunssfsi \\\n                floatsidf floatsisf floatunsidf floatunsisf \\\n                muldf3 mulsf3 \\\n                negdf2 negsf2 \\\n                truncdfsf2  \\\n                modsi3 umodsi3 udivsi3 divsi3 udivmodsi4 divmodsi4 \\\n                switch8 switchu8 switch16 switch32 \\\n                sync_synchronize\n\nFUNCTIONS.armv6 := $(FUNCTIONS) \\\n\t\t\t\tcomparedf2 comparesf2 \\\n                adddf3vfp addsf3vfp bswapdi2 bswapsi2 divdf3vfp \\\n                divsf3vfp eqdf2vfp eqsf2vfp extendsfdf2vfp \\\n                fixdfsivfp fixsfsivfp fixunsdfsivfp fixunssfsivfp \\\n                floatsidfvfp floatsisfvfp floatunssidfvfp floatunssisfvfp \\\n                gedf2vfp gesf2vfp gtdf2vfp gtsf2vfp \\\n                ledf2vfp lesf2vfp ltdf2vfp ltsf2vfp \\\n                muldf3vfp mulsf3vfp \\\n                nedf2vfp nesf2vfp \\\n                subdf3vfp subsf3vfp truncdfsf2vfp unorddf2vfp unordsf2vfp \\\n                modsi3 umodsi3 udivsi3 divsi3 udivmodsi4 divmodsi4 \\\n                switch8 switchu8 switch16 switch32 \\\n                restore_vfp_d8_d15_regs save_vfp_d8_d15_regs \\\n                sync_synchronize\n\nFUNCTIONS.armv7 := $(FUNCTIONS) \\\n\t\t\t\tcomparedf2 comparesf2 \\\n                adddf3vfp addsf3vfp bswapdi2 bswapsi2 divdf3vfp \\\n                divsf3vfp eqdf2vfp eqsf2vfp extendsfdf2vfp \\\n                fixdfsivfp fixsfsivfp fixunsdfsivfp fixunssfsivfp \\\n                floatsidfvfp floatsisfvfp floatunssidfvfp floatunssisfvfp \\\n                gedf2vfp gesf2vfp gtdf2vfp gtsf2vfp \\\n                ledf2vfp lesf2vfp ltdf2vfp ltsf2vfp \\\n                muldf3vfp mulsf3vfp \\\n                nedf2vfp nesf2vfp \\\n                subdf3vfp subsf3vfp truncdfsf2vfp unorddf2vfp unordsf2vfp \\\n                modsi3 umodsi3 udivsi3 divsi3 udivmodsi4 divmodsi4\n\nFUNCTIONS.armv7s := $(FUNCTIONS.armv7)\n\nFUNCTIONS.arm64 :=  divti3 modti3 \\\n\t\t\t\t\tudivmodti4 \\\n\t\t\t\t\tudivti3 umodti3 \\\n\t\t\t\t\tmulsc3 muldc3 \\\n\t\t\t\t\tpowisf2 powidf2 \\\n\t\t\t\t\tclzti2 \\\n\t\t\t\t\tfixdfti fixsfti \\\n\t\t\t\t\tfixunsdfti fixunssfti fixunssfti \\\n\t\t\t\t\tfloattidf floattisf floatuntidf floatuntisf \\\n\t\t\t\t\tgcc_personality_v0 atomic \\\n\t\t\t\t\tatomic_flag_clear atomic_flag_clear_explicit \\\n\t\t\t\t\tatomic_flag_test_and_set \\\n\t\t\t\t\tatomic_flag_test_and_set_explicit \\\n\t\t\t\t\tatomic_signal_fence atomic_thread_fence\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/platform/multi_arch.mk",
    "content": "Description := Example configuration for build two libraries for separate \\\narchitectures.\n\nConfigs := m32 m64\nArch := i386\nArch.m64 := x86_64\n\nCC := clang\n\nCFLAGS := -Wall -Werror\nCFLAGS.m32 := $(CFLAGS) -m32 -O3\nCFLAGS.m64 := $(CFLAGS) -m64 -O3\n\nFUNCTIONS := moddi3 floatundixf udivdi3\nFUNCTIONS.m64 := $(FUNCTIONS) lshrdi3\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/subdir.mk",
    "content": "# This file is intended to be included from each subdirectory makefile.\n#\n# Subdirectory makefiles must define:\n#   SubDirs - The subdirectories to traverse.\n#\n# Subdirectory makefiles may define:\n#   ModuleName - The library name for objects in that directory.\n#   ObjNames - The objects available in that directory.\n#   Implementation - The library configuration the objects should go in (Generic\n#                    or Optimized)\n#   Dependencies - Any dependences for the object files.\n#   OnlyArchs - Only build the objects for the listed archs.\n#   OnlyConfigs - Only build the objects for the listed configurations.\n\nifeq ($(Dir),)\n  $(error \"No Dir variable defined.\")\nendif\n\n###\n# Include child makefile fragments\n\n# The list of variables which are intended to be overridden in a subdirectory\n# makefile.\nRequiredSubdirVariables := SubDirs \nOptionalSubdirVariables := ModuleName OnlyArchs OnlyConfigs \\\n\tObjNames Implementation Dependencies\n\n# Template: subdir_traverse_template subdir\ndefine subdir_traverse_template\n$(call Set,Dir,$(1))\nifneq ($(DEBUGMAKE),)\n  $$(info MAKE: $(Dir): Processing subdirectory)\nendif\n\n# Construct the variable key for this directory.\n$(call Set,DirKey,SubDir.$(subst .,,$(subst /,__,$(1))))\n$(call Append,SubDirKeys,$(DirKey))\n$(call Set,$(DirKey).Dir,$(Dir))\n\n# Reset subdirectory specific variables to sentinel value.\n$$(foreach var,$$(RequiredSubdirVariables) $$(OptionalSubdirVariables),\\\n  $$(call Set,$$(var),UNDEFINED))\n\n# Get the subdirectory variables.\ninclude $(1)/Makefile.mk\n\nifeq ($(DEBUGMAKE),2)\n$$(foreach var,$(RequiredSubdirVariables) $(OptionalSubdirVariables),\\\n  $$(if $$(call strneq,UNDEFINED,$$($$(var))), \\\n\t$$(info MAKE: $(Dir): $$(var) is defined), \\\n\t$$(info MAKE: $(Dir): $$(var) is undefined)))\nendif\n\n# Check for undefined required variables, and unset sentinel value from optional\n# variables.\n$$(foreach var,$(RequiredSubdirVariables),\\\n  $$(if $$(call strneq,UNDEFINED,$$($$(var))),, \\\n\t$$(error $(Dir): variable '$$(var)' was not undefined)))\n$$(foreach var,$(OptionalSubdirVariables),\\\n  $$(if $$(call strneq,UNDEFINED,$$($$(var))),, \\\n\t$$(call Set,$$(var),)))\n\n# Collect all subdirectory variables for subsequent use.\n$$(foreach var,$(RequiredSubdirVariables) $(OptionalSubdirVariables),\\\n  $$(call Set,$(DirKey).$$(var),$$($$(var))))\n\n# Recurse.\ninclude make/subdir.mk\n\n# Restore directory variable, for cleanliness.\n$$(call Set,Dir,$(1))\n\nifneq ($(DEBUGMAKE),)\n  $$(info MAKE: $$(Dir): Done processing subdirectory)\nendif\nendef\n\n# Evaluate this now so we do not have to worry about order of evaluation.\n\nSubDirsList := $(strip \\\n  $(if $(call streq,.,$(Dir)),\\\n       $(SubDirs),\\\n       $(SubDirs:%=$(Dir)/%)))\nifeq ($(SubDirsList),)\nelse\n  ifneq ($(DEBUGMAKE),)\n    $(info MAKE: Descending into subdirs: $(SubDirsList))\n  endif\n\n  $(foreach subdir,$(SubDirsList),\\\n\t$(eval $(call subdir_traverse_template,$(subdir))))\nendif\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/test/test-util.mk",
    "content": "include make/util.mk\n\nstreq_t0 = $(call streq,,)\n$(call AssertEqual,streq_t0,true)\nstreq_t1 = $(call streq,b,)\n$(call AssertEqual,streq_t1,)\nstreq_t2 = $(call streq,,b)\n$(call AssertEqual,streq_t2,)\nstreq_t3 = $(call streq,b,b)\n$(call AssertEqual,streq_t3,true)\nstreq_t4 = $(call streq,bb,b)\n$(call AssertEqual,streq_t4,)\nstreq_t5 = $(call streq,b,bb)\n$(call AssertEqual,streq_t5,)\nstreq_t6 = $(call streq,bb,bb)\n$(call AssertEqual,streq_t6,true)\n\nstrneq_t7 = $(call strneq,,)\n$(call AssertEqual,strneq_t7,)\nstrneq_t8 = $(call strneq,b,)\n$(call AssertEqual,strneq_t8,true)\nstrneq_t9 = $(call strneq,,b)\n$(call AssertEqual,strneq_t9,true)\nstrneq_t10 = $(call strneq,b,b)\n$(call AssertEqual,strneq_t10,)\nstrneq_t11 = $(call strneq,bb,b)\n$(call AssertEqual,strneq_t11,true)\nstrneq_t12 = $(call strneq,b,bb)\n$(call AssertEqual,strneq_t12,true)\nstrneq_t13 = $(call strneq,bb,bb)\n$(call AssertEqual,strneq_t13,)\n\ncontains_t0 = $(call contains,a b b c,a)\n$(call AssertEqual,contains_t0,true)\ncontains_t1 = $(call contains,a b b c,b)\n$(call AssertEqual,contains_t1,true)\ncontains_t2 = $(call contains,a b b c,c)\n$(call AssertEqual,contains_t2,true)\ncontains_t3 = $(call contains,a b b c,d)\n$(call AssertEqual,contains_t3,)\n\nisdefined_t0_defined_var := 0\nisdefined_t0 = $(call IsDefined,isdefined_t0_defined_var)\n$(call AssertEqual,isdefined_t0,true)\nisdefined_t1 = $(call IsDefined,isdefined_t1_never_defined_var)\n$(call AssertEqual,isdefined_t1,)\n\nvarordefault_t0_var := 1\nvarordefault_t0 = $(call VarOrDefault,varordefault_t0_var.opt,$(varordefault_t0_var))\n$(call AssertEqual,varordefault_t0,1)\nvarordefault_t1_var := 1\nvarordefault_t1_var.opt := 2\nvarordefault_t1 = $(call VarOrDefault,varordefault_t1_var.opt,$(varordefault_t1_var))\n$(call AssertEqual,varordefault_t1,2)\n\n$(call CopyVariable,copyvariable_t0_src,copyvariable_t0_dst)\ncopyvariable_t0 = $(call IsUndefined,copyvariable_t0_dst)\n$(call AssertEqual,copyvariable_t0,true)\ncopyvariable_t1_src = 1\n$(call CopyVariable,copyvariable_t1_src,copyvariable_t1)\n$(call AssertEqual,copyvariable_t1,1)\n\nall:\n\t@true\n.PHONY: all\n\n"
  },
  {
    "path": "atlas-aapt/external/compiler-rt/make/util.mk",
    "content": "# Generic Makefile Utilities\n\n###\n# Utility functions\n\n# Function: streq LHS RHS\n#\n# Return \"true\" if LHS == RHS, otherwise \"\".\n#\n# LHS == RHS <=> (LHS subst RHS is empty) and (RHS subst LHS is empty)\nstreq = $(if $(1),$(if $(subst $(1),,$(2))$(subst $(2),,$(1)),,true),$(if $(2),,true))\n\n# Function: strneq LHS RHS\n#\n# Return \"true\" if LHS != RHS, otherwise \"\".\nstrneq = $(if $(call streq,$(1),$(2)),,true)\n\n# Function: contains list item\n#\n# Return \"true\" if 'list' contains the value 'item'.\ncontains = $(if $(strip $(foreach i,$(1),$(if $(call streq,$(2),$(i)),T,))),true,)\n\n# Function: is_subset a b\n# Return \"true\" if 'a' is a subset of 'b'.\nis_subset = $(if $(strip $(set_difference $(1),$(2))),,true)\n\n# Function: set_difference a b\n# Return a - b.\nset_difference = $(foreach i,$(1),$(if $(call contains,$(2),$(i)),,$(i)))\n\n# Function: Set variable value\n#\n# Set the given make variable to the given value.\nSet = $(eval $(1) := $(2))\n\n# Function: Append variable value\n#\n# Append the given value to the given make variable.\nAppend = $(eval $(1) += $(2))\n\n# Function: IsDefined variable\n#\n# Check whether the given variable is defined.\nIsDefined = $(call strneq,undefined,$(flavor $(1)))\n\n# Function: IsUndefined variable\n#\n# Check whether the given variable is undefined.\nIsUndefined = $(call streq,undefined,$(flavor $(1)))\n\n# Function: VarOrDefault variable default-value\n#\n# Get the value of the given make variable, or the default-value if the variable\n# is undefined.\nVarOrDefault = $(if $(call IsDefined,$(1)),$($(1)),$(2))\n\n# Function: CheckValue variable\n#\n# Print the name, definition, and value of a variable, for testing make\n# utilities.\n#\n# Example:\n#   foo = $(call streq,a,a)\n#   $(call CheckValue,foo)\n# Example Output:\n#   CHECKVALUE: foo: $(call streq,,) - true\nCheckValue = $(info CHECKVALUE: $(1): $(value $(1)) - $($(1)))\n\n# Function: CopyVariable src dst\n#\n# Copy the value of the variable 'src' to 'dst', taking care to not define 'dst'\n# if 'src' is undefined. The destination variable must be undefined.\nCopyVariable = \\\n  $(call AssertValue,$(call IsUndefined,$(2)),destination is already defined)\\\n  $(if $(call IsUndefined,$(1)),,\\\n       $(call Set,$(2),$($(1))))\n\n# Function: Assert value message\n#\n# Check that a value is true, or give an error including the given message\nAssert = $(if $(1),,\\\n           $(error Assertion failed: $(2)))\n\n# Function: AssertEqual variable expected-value\n#\n# Check that the value of a variable is 'expected-value'.\nAssertEqual = \\\n  $(if $(call streq,$($(1)),$(2)),,\\\n       $(error Assertion failed: $(1): $(value $(1)) - $($(1)) != $(2)))\n\n# Function: CheckCommandLineOverrides list\n#\n# Check that all command line variables are in the given list. This routine is\n# useful for validating that users aren't trying to override something which\n# will not work.\nCheckCommandLineOverrides = \\\n  $(foreach arg,$(MAKEOVERRIDES),\\\n    $(call Set,varname,$(firstword $(subst =, ,$(arg)))) \\\n    $(if $(call contains,$(1),$(varname)),,\\\n      $(error \"Invalid command line override: $(1) $(varname) (not supported)\")))\n\n###\n# Clean up make behavior\n\n# Cancel all suffix rules. We don't want no stinking suffix rules.\n.SUFFIXES:\n\n###\n# Debugging\n\n# General debugging rule, use 'make print-XXX' to print the definition, value\n# and origin of XXX.\nmake-print-%:\n\t$(error PRINT: $(value $*) = \"$($*)\" (from $(origin $*)))\n"
  },
  {
    "path": "atlas-aapt/external/expat/Android.mk",
    "content": "LOCAL_PATH:= $(call my-dir)\n\n# We need to build this for both the device (as a shared library)\n# and the host (as a static library for tools to use).\n\ncommon_SRC_FILES := \\\n\tlib/xmlparse.c \\\n\tlib/xmlrole.c \\\n\tlib/xmltok.c\n\ncommon_CFLAGS := \\\n    -Wall \\\n    -Wmissing-prototypes -Wstrict-prototypes \\\n    -Wno-unused-parameter -Wno-missing-field-initializers \\\n    -fexceptions \\\n    -DHAVE_EXPAT_CONFIG_H\n\ncommon_C_INCLUDES += \\\n\t$(LOCAL_PATH)/lib\n\n# For the host\n# =====================================================\n\n# Host static library\ninclude $(CLEAR_VARS)\n\nLOCAL_SRC_FILES := $(common_SRC_FILES)\nLOCAL_CFLAGS += $(common_CFLAGS)\nLOCAL_C_INCLUDES += $(common_C_INCLUDES)\n\nLOCAL_CFLAGS_darwin += -fno-common\n\nLOCAL_MODULE:= libexpat\nLOCAL_MODULE_HOST_OS := darwin linux windows\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/lib\n\nLOCAL_MULTILIB := both\n\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\n# Host shared library\ninclude $(CLEAR_VARS)\n\nLOCAL_SRC_FILES := $(common_SRC_FILES)\nLOCAL_CFLAGS += $(common_CFLAGS)\nLOCAL_C_INCLUDES += $(common_C_INCLUDES)\n\nLOCAL_CFLAGS_darwin += -fno-common\n\nLOCAL_MODULE:= libexpat-host\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/lib\nLOCAL_MULTILIB := both\n\ninclude $(BUILD_HOST_SHARED_LIBRARY)\n\n\n# For the device\n# =====================================================\n\n# Device static library\ninclude $(CLEAR_VARS)\n\nifeq ($(TARGET_ARCH),arm)\n    LOCAL_SDK_VERSION := 8\nelse\n    LOCAL_SDK_VERSION := 9\nendif\n\nLOCAL_SRC_FILES := $(common_SRC_FILES)\nLOCAL_CFLAGS += $(common_CFLAGS)\nLOCAL_C_INCLUDES += $(common_C_INCLUDES)\n\nLOCAL_MODULE:= libexpat_static\nLOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk\nLOCAL_MODULE_TAGS := optional\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/lib\n\ninclude $(BUILD_STATIC_LIBRARY)\n\n# Device shared library\ninclude $(CLEAR_VARS)\n\nifeq ($(TARGET_ARCH),arm)\n    LOCAL_SDK_VERSION := 8\nelse\n    LOCAL_SDK_VERSION := 9\nendif\n\nLOCAL_SYSTEM_SHARED_LIBRARIES := libc\nLOCAL_SRC_FILES := $(common_SRC_FILES)\nLOCAL_CFLAGS += $(common_CFLAGS)\nLOCAL_C_INCLUDES += $(common_C_INCLUDES)\n\nLOCAL_MODULE:= libexpat\nLOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk\nLOCAL_MODULE_TAGS := optional\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/lib\n\ninclude $(BUILD_SHARED_LIBRARY)\n"
  },
  {
    "path": "atlas-aapt/external/expat/Changes",
    "content": "Release 2.1.1 Sat March 12 2016\n        Security fixes:\n            #582: CVE-2015-1283 - Multiple integer overflows in XML_GetBuffer\n\n        Bug fixes:\n            #502: Fix potential null pointer dereference\n            #520: Symbol XML_SetHashSalt was not exported\n            Output of \"xmlwf -h\" was incomplete\n\n        Other changes\n            #503: Document behavior of calling XML_SetHashSalt with salt 0\n            Minor improvements to man page xmlwf(1)\n            Improvements to the experimental CMake build system\n            libtool now invoked with --verbose\n\nRelease 2.1.0 Sat March 24 2012\n        - Bug Fixes:\n          #1742315: Harmful XML_ParserCreateNS suggestion.\n          #2895533: CVE-2012-1147 - Resource leak in readfilemap.c.\n          #1785430: Expat build fails on linux-amd64 with gcc version>=4.1 -O3.\n          #1983953, 2517952, 2517962, 2649838: \n                Build modifications using autoreconf instead of buildconf.sh.\n          #2815947, #2884086: OBJEXT and EXEEXT support while building.\n          #1990430: CVE-2009-3720 - Parser crash with special UTF-8 sequences.\n          #2517938: xmlwf should return non-zero exit status if not well-formed.\n          #2517946: Wrong statement about XMLDecl in xmlwf.1 and xmlwf.sgml.\n          #2855609: Dangling positionPtr after error.\n          #2894085: CVE-2009-3560 - Buffer over-read and crash in big2_toUtf8().\n          #2958794: CVE-2012-1148 - Memory leak in poolGrow.\n          #2990652: CMake support.\n          #3010819: UNEXPECTED_STATE with a trailing \"%\" in entity value.\n          #3206497: Unitialized memory returned from XML_Parse.\n          #3287849: make check fails on mingw-w64.\n          #3496608: CVE-2012-0876 - Hash DOS attack.\n        - Patches:\n          #1749198: pkg-config support.\n          #3010222: Fix for bug #3010819.\n          #3312568: CMake support.\n          #3446384: Report byte offsets for attr names and values.\n        - New Features / API changes:\n          Added new API member XML_SetHashSalt() that allows setting an initial\n                value (salt) for hash calculations. This is part of the fix for\n                bug #3496608 to randomize hash parameters.\n          When compiled with XML_ATTR_INFO defined, adds new API member\n                XML_GetAttributeInfo() that allows retrieving the byte\n                offsets for attribute names and values (patch #3446384).\n          Added CMake build system.\n                See bug #2990652 and patch #3312568.\n          Added run-benchmark target to Makefile.in - relies on testdata module\n                present in the same relative location as in the repository.\n          \nRelease 2.0.1 Tue June 5 2007\n        - Fixed bugs #1515266, #1515600: The character data handler's calling\n          of XML_StopParser() was not handled properly; if the parser was\n          stopped and the handler set to NULL, the parser would segfault.\n        - Fixed bug #1690883: Expat failed on EBCDIC systems as it assumed\n          some character constants to be ASCII encoded.\n        - Minor cleanups of the test harness.\n        - Fixed xmlwf bug #1513566: \"out of memory\" error on file size zero.\n        - Fixed outline.c bug #1543233: missing a final XML_ParserFree() call.\n        - Fixes and improvements for Windows platform:\n          bugs #1409451, #1476160, #1548182, #1602769, #1717322.\n        - Build fixes for various platforms:\n          HP-UX, Tru64, Solaris 9: patch #1437840, bug #1196180.\n          All Unix: #1554618 (refreshed config.sub/config.guess).\n                    #1490371, #1613457: support both, DESTDIR and INSTALL_ROOT,\n                    without relying on GNU-Make specific features.\n          #1647805: Patched configure.in to work better with Intel compiler.\n        - Fixes to Makefile.in to have make check work correctly:\n          bugs #1408143, #1535603, #1536684.\n        - Added Open Watcom support: patch #1523242.\n\nRelease 2.0.0 Wed Jan 11 2006\n        - We no longer use the \"check\" library for C unit testing; we\n          always use the (partial) internal implementation of the API.\n        - Report XML_NS setting via XML_GetFeatureList().\n        - Fixed headers for use from C++.\n        - XML_GetCurrentLineNumber() and  XML_GetCurrentColumnNumber()\n          now return unsigned integers.\n        - Added XML_LARGE_SIZE switch to enable 64-bit integers for\n          byte indexes and line/column numbers.\n        - Updated to use libtool 1.5.22 (the most recent).\n        - Added support for AmigaOS.\n        - Some mostly minor bug fixes. SF issues include: #1006708,\n          #1021776, #1023646, #1114960, #1156398, #1221160, #1271642.\n\nRelease 1.95.8 Fri Jul 23 2004\n        - Major new feature: suspend/resume.  Handlers can now request\n          that a parse be suspended for later resumption or aborted\n          altogether.  See \"Temporarily Stopping Parsing\" in the\n          documentation for more details.\n        - Some mostly minor bug fixes, but compilation should no\n          longer generate warnings on most platforms.  SF issues\n          include: #827319, #840173, #846309, #888329, #896188, #923913,\n          #928113, #961698, #985192.\n\nRelease 1.95.7 Mon Oct 20 2003\n        - Fixed enum XML_Status issue (reported on SourceForge many\n          times), so compilers that are properly picky will be happy.\n        - Introduced an XMLCALL macro to control the calling\n          convention used by the Expat API; this macro should be used\n          to annotate prototypes and definitions of callback\n          implementations in code compiled with a calling convention\n          other than the default convention for the host platform.\n        - Improved ability to build without the configure-generated\n          expat_config.h header.  This is useful for applications\n          which embed Expat rather than linking in the library.\n        - Fixed a variety of bugs: see SF issues #458907, #609603,\n          #676844, #679754, #692878, #692964, #695401, #699323, #699487,\n          #820946.\n        - Improved hash table lookups.\n        - Added more regression tests and improved documentation.\n\nRelease 1.95.6 Tue Jan 28 2003\n        - Added XML_FreeContentModel().\n        - Added XML_MemMalloc(), XML_MemRealloc(), XML_MemFree().\n        - Fixed a variety of bugs: see SF issues #615606, #616863,\n          #618199, #653180, #673791.\n        - Enhanced the regression test suite.\n        - Man page improvements: includes SF issue #632146.\n\nRelease 1.95.5 Fri Sep 6 2002\n        - Added XML_UseForeignDTD() for improved SAX2 support.\n        - Added XML_GetFeatureList().\n        - Defined XML_Bool type and the values XML_TRUE and XML_FALSE.\n        - Use an incomplete struct instead of a void* for the parser\n          (may not retain).\n        - Fixed UTF-8 decoding bug that caused legal UTF-8 to be rejected.\n        - Finally fixed bug where default handler would report DTD\n          events that were already handled by another handler.\n          Initial patch contributed by Darryl Miles.\n        - Removed unnecessary DllMain() function that caused static\n          linking into a DLL to be difficult.\n        - Added VC++ projects for building static libraries.\n        - Reduced line-length for all source code and headers to be\n          no longer than 80 characters, to help with AS/400 support.\n        - Reduced memory copying during parsing (SF patch #600964).\n        - Fixed a variety of bugs: see SF issues #580793, #434664,\n          #483514, #580503, #581069, #584041, #584183, #584832, #585537,\n          #596555, #596678, #598352, #598944, #599715, #600479, #600971.\n\nRelease 1.95.4 Fri Jul 12 2002\n        - Added support for VMS, contributed by Craig Berry.  See\n          vms/README.vms for more information.\n        - Added Mac OS (classic) support, with a makefile for MPW,\n          contributed by Thomas Wegner and Daryle Walker.\n        - Added Borland C++ Builder 5 / BCC 5.5 support, contributed\n          by Patrick McConnell (SF patch #538032).\n        - Fixed a variety of bugs: see SF issues #441449, #563184,\n          #564342, #566334, #566901, #569461, #570263, #575168, #579196.\n        - Made skippedEntityHandler conform to SAX2 (see source comment)\n        - Re-implemented WFC: Entity Declared from XML 1.0 spec and\n          added a new error \"entity declared in parameter entity\":\n          see SF bug report #569461 and SF patch #578161\n        - Re-implemented section 5.1 from XML 1.0 spec:\n          see SF bug report #570263 and SF patch #578161\n\nRelease 1.95.3 Mon Jun 3 2002\n        - Added a project to the MSVC workspace to create a wchar_t\n          version of the library; the DLLs are named libexpatw.dll.\n        - Changed the name of the Windows DLLs from expat.dll to\n          libexpat.dll; this fixes SF bug #432456.\n        - Added the XML_ParserReset() API function.\n        - Fixed XML_SetReturnNSTriplet() to work for element names.\n        - Made the XML_UNICODE builds usable (thanks, Karl!).\n        - Allow xmlwf to read from standard input.\n        - Install a man page for xmlwf on Unix systems.\n        - Fixed many bugs; see SF bug reports #231864, #461380, #464837,\n          #466885, #469226, #477667, #484419, #487840, #494749, #496505,\n          #547350.  Other bugs which we can't test as easily may also\n          have been fixed, especially in the area of build support.\n\nRelease 1.95.2 Fri Jul 27 2001\n        - More changes to make MSVC happy with the build; add a single\n          workspace to support both the library and xmlwf application.\n        - Added a Windows installer for Windows users; includes\n          xmlwf.exe.\n        - Added compile-time constants that can be used to determine the\n          Expat version\n        - Removed a lot of GNU-specific dependencies to aide portability\n          among the various Unix flavors.\n        - Fix the UTF-8 BOM bug.\n        - Cleaned up warning messages for several compilers.\n        - Added the -Wall, -Wstrict-prototypes options for GCC.\n\nRelease 1.95.1 Sun Oct 22 15:11:36 EDT 2000\n        - Changes to get expat to build under Microsoft compiler\n        - Removed all aborts and instead return an UNEXPECTED_STATE error.\n        - Fixed a bug where a stray '%' in an entity value would cause an\n          abort.\n        - Defined XML_SetEndNamespaceDeclHandler. Thanks to Darryl Miles for\n          finding this oversight.\n        - Changed default patterns in lib/Makefile.in to fit non-GNU makes\n          Thanks to robin@unrated.net for reporting and providing an\n          account to test on.\n        - The reference had the wrong label for XML_SetStartNamespaceDecl.\n          Reported by an anonymous user.\n\nRelease 1.95.0 Fri Sep 29 2000\n        - XML_ParserCreate_MM\n                Allows you to set a memory management suite to replace the\n                standard malloc,realloc, and free.\n        - XML_SetReturnNSTriplet\n                If you turn this feature on when namespace processing is in\n                effect, then qualified, prefixed element and attribute names\n                are returned as \"uri|name|prefix\" where '|' is whatever\n                separator character is used in namespace processing.\n        - Merged in features from perl-expat\n                o XML_SetElementDeclHandler\n                o XML_SetAttlistDeclHandler\n                o XML_SetXmlDeclHandler\n                o XML_SetEntityDeclHandler\n                o StartDoctypeDeclHandler takes 3 additional parameters:\n                        sysid, pubid, has_internal_subset\n                o Many paired handler setters (like XML_SetElementHandler)\n                  now have corresponding individual handler setters\n                o XML_GetInputContext for getting the input context of\n                  the current parse position.\n        - Added reference material\n        - Packaged into a distribution that builds a sharable library\n"
  },
  {
    "path": "atlas-aapt/external/expat/CleanSpec.mk",
    "content": "# Copyright (C) 2007 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n# If you don't need to do a full clean build but would like to touch\n# a file or delete some intermediate files, add a clean step to the end\n# of the list.  These steps will only be run once, if they haven't been\n# run before.\n#\n# E.g.:\n#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)\n#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)\n#\n# Always use \"touch -c\" and \"rm -f\" or \"rm -rf\" to gracefully deal with\n# files that are missing or have been moved.\n#\n# Use $(PRODUCT_OUT) to get to the \"out/target/product/blah/\" directory.\n# Use $(OUT_DIR) to refer to the \"out\" directory.\n#\n# If you need to re-do something that's already mentioned, just copy\n# the command and add it to the bottom of the list.  E.g., if a change\n# that you made last week required touching a file and a change you\n# made today requires touching the same file, just copy the old\n# touch step and add it to the end of the list.\n#\n# ************************************************\n# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST\n# ************************************************\n\n# For example:\n#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)\n#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)\n#$(call add-clean-step, find $(OUT_DIR) -type f -name \"IGTalkSession*\" -print0 | xargs -0 rm -f)\n#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)\n\n# ************************************************\n# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST\n# ************************************************\n"
  },
  {
    "path": "atlas-aapt/external/expat/MODULE_LICENSE_BSD_LIKE",
    "content": ""
  },
  {
    "path": "atlas-aapt/external/expat/NOTICE",
    "content": "Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd\n                               and Clark Cooper\nCopyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "atlas-aapt/external/expat/README",
    "content": "\n                        Expat, Release 2.1.1\n\nThis is Expat, a C library for parsing XML, written by James Clark.\nExpat is a stream-oriented XML parser.  This means that you register\nhandlers with the parser before starting the parse.  These handlers\nare called when the parser discovers the associated structures in the\ndocument being parsed.  A start tag is an example of the kind of\nstructures for which you may register handlers.\n\nWindows users should use the expat_win32bin package, which includes\nboth precompiled libraries and executables, and source code for\ndevelopers.\n\nExpat is free software.  You may copy, distribute, and modify it under\nthe terms of the License contained in the file COPYING distributed\nwith this package.  This license is the same as the MIT/X Consortium\nlicense.\n\nVersions of Expat that have an odd minor version (the middle number in\nthe release above), are development releases and should be considered\nas beta software.  Releases with even minor version numbers are\nintended to be production grade software.\n\nIf you are building Expat from a check-out from the CVS repository,\nyou need to run a script that generates the configure script using the\nGNU autoconf and libtool tools.  To do this, you need to have\nautoconf 2.58 or newer. Run the script like this:\n\n        ./buildconf.sh\n\nOnce this has been done, follow the same instructions as for building\nfrom a source distribution.\n\nTo build Expat from a source distribution, you first run the\nconfiguration shell script in the top level distribution directory:\n\n        ./configure\n\nThere are many options which you may provide to configure (which you\ncan discover by running configure with the --help option).  But the\none of most interest is the one that sets the installation directory.\nBy default, the configure script will set things up to install\nlibexpat into /usr/local/lib, expat.h into /usr/local/include, and\nxmlwf into /usr/local/bin.  If, for example, you'd prefer to install\ninto /home/me/mystuff/lib, /home/me/mystuff/include, and\n/home/me/mystuff/bin, you can tell configure about that with:\n\n        ./configure --prefix=/home/me/mystuff\n        \nAnother interesting option is to enable 64-bit integer support for\nline and column numbers and the over-all byte index:\n\n        ./configure CPPFLAGS=-DXML_LARGE_SIZE\n        \nHowever, such a modification would be a breaking change to the ABI\nand is therefore not recommended for general use - e.g. as part of\na Linux distribution - but rather for builds with special requirements.\n\nAfter running the configure script, the \"make\" command will build\nthings and \"make install\" will install things into their proper\nlocation.  Have a look at the \"Makefile\" to learn about additional\n\"make\" options.  Note that you need to have write permission into\nthe directories into which things will be installed.\n\nIf you are interested in building Expat to provide document\ninformation in UTF-16 encoding rather than the default UTF-8, follow\nthese instructions (after having run \"make distclean\"):\n\n        1. For UTF-16 output as unsigned short (and version/error\n           strings as char), run:\n\n               ./configure CPPFLAGS=-DXML_UNICODE\n\n           For UTF-16 output as wchar_t (incl. version/error strings),\n           run:\n\n               ./configure CFLAGS=\"-g -O2 -fshort-wchar\" \\\n                           CPPFLAGS=-DXML_UNICODE_WCHAR_T\n\n        2. Edit the MakeFile, changing:\n\n               LIBRARY = libexpat.la\n\n           to:\n\n               LIBRARY = libexpatw.la\n\n           (Note the additional \"w\" in the library name.)\n\n        3. Run \"make buildlib\" (which builds the library only).\n           Or, to save step 2, run \"make buildlib LIBRARY=libexpatw.la\".\n\n        4. Run \"make installlib\" (which installs the library only).\n           Or, if step 2 was omitted, run \"make installlib LIBRARY=libexpatw.la\".\n           \nUsing DESTDIR or INSTALL_ROOT is enabled, with INSTALL_ROOT being the default\nvalue for DESTDIR, and the rest of the make file using only DESTDIR.\nIt works as follows:\n   $ make install DESTDIR=/path/to/image\noverrides the in-makefile set DESTDIR, while both\n   $ INSTALL_ROOT=/path/to/image make install\n   $ make install INSTALL_ROOT=/path/to/image\nuse DESTDIR=$(INSTALL_ROOT), even if DESTDIR eventually is defined in the\nenvironment, because variable-setting priority is\n1) commandline\n2) in-makefile\n3) environment  \n\nNote: This only applies to the Expat library itself, building UTF-16 versions\nof xmlwf and the tests is currently not supported.         \n\nNote for Solaris users:  The \"ar\" command is usually located in\n\"/usr/ccs/bin\", which is not in the default PATH.  You will need to\nadd this to your path for the \"make\" command, and probably also switch\nto GNU make (the \"make\" found in /usr/ccs/bin does not seem to work\nproperly -- appearantly it does not understand .PHONY directives).  If\nyou're using ksh or bash, use this command to build:\n\n        PATH=/usr/ccs/bin:$PATH make\n\nWhen using Expat with a project using autoconf for configuration, you\ncan use the probing macro in conftools/expat.m4 to determine how to\ninclude Expat.  See the comments at the top of that file for more\ninformation.\n\nA reference manual is available in the file doc/reference.html in this\ndistribution.\n\nThe homepage for this project is http://www.libexpat.org/.  There\nare links there to connect you to the bug reports page.  If you need\nto report a bug when you don't have access to a browser, you may also\nsend a bug report by email to expat-bugs@mail.libexpat.org.\n\nDiscussion related to the direction of future expat development takes\nplace on expat-discuss@mail.libexpat.org.  Archives of this list and\nother Expat-related lists may be found at:\n\n        http://mail.libexpat.org/mailman/listinfo/\n"
  },
  {
    "path": "atlas-aapt/external/expat/README.android",
    "content": "Please use ./import_expat.sh to update. For example to import from a tar and rebuild:\n\n    (croot && cd external/expat && ./import_expat.sh ~/Downloads/expat-2.1.1.tar.bz2 && mma -j32 -B)\n\nWhen updating to new versions, please remove any unnecessary build\nfiles to make the diff of what we are using clearer. It is reasonable\nto keep new docs, examples, and tests for reference.\n"
  },
  {
    "path": "atlas-aapt/external/expat/README.version",
    "content": "URL: http://sourceforge.net/projects/expat/files/expat/2.1.0/expat-2.1.0.tar.gz/download\nVersion: 2.1.0\nBugComponent: 24949\n"
  },
  {
    "path": "atlas-aapt/external/expat/expat_config.h",
    "content": "/* expat_config.h.  Generated from expat_config.h.in by configure.  */\n/* expat_config.h.in.  Generated from configure.in by autoheader.  */\n\n/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */\n#define BYTEORDER 1234\n\n/* Define to 1 if you have the `bcopy' function. */\n#define HAVE_BCOPY 1\n\n/* Define to 1 if you have the <dlfcn.h> header file. */\n#define HAVE_DLFCN_H 1\n\n/* Define to 1 if you have the <fcntl.h> header file. */\n#define HAVE_FCNTL_H 1\n\n/* Define to 1 if you have the `getpagesize' function. */\n#define HAVE_GETPAGESIZE 1\n\n/* Define to 1 if you have the <inttypes.h> header file. */\n#define HAVE_INTTYPES_H 1\n\n/* Define to 1 if you have the `memmove' function. */\n#define HAVE_MEMMOVE 1\n\n/* Define to 1 if you have the <memory.h> header file. */\n#define HAVE_MEMORY_H 1\n\n/* Define to 1 if you have a working `mmap' system call. */\n#define HAVE_MMAP 1\n\n/* Define to 1 if you have the <stdint.h> header file. */\n#define HAVE_STDINT_H 1\n\n/* Define to 1 if you have the <stdlib.h> header file. */\n#define HAVE_STDLIB_H 1\n\n/* Define to 1 if you have the <strings.h> header file. */\n#define HAVE_STRINGS_H 1\n\n/* Define to 1 if you have the <string.h> header file. */\n#define HAVE_STRING_H 1\n\n/* Define to 1 if you have the <sys/param.h> header file. */\n#define HAVE_SYS_PARAM_H 1\n\n/* Define to 1 if you have the <sys/stat.h> header file. */\n#define HAVE_SYS_STAT_H 1\n\n/* Define to 1 if you have the <sys/types.h> header file. */\n#define HAVE_SYS_TYPES_H 1\n\n/* Define to 1 if you have the <unistd.h> header file. */\n#define HAVE_UNISTD_H 1\n\n/* Define to the sub-directory in which libtool stores uninstalled libraries.\n   */\n#define LT_OBJDIR \".libs/\"\n\n/* Define to the address where bug reports for this package should be sent. */\n#define PACKAGE_BUGREPORT \"expat-bugs@libexpat.org\"\n\n/* Define to the full name of this package. */\n#define PACKAGE_NAME \"expat\"\n\n/* Define to the full name and version of this package. */\n#define PACKAGE_STRING \"expat 2.1.0\"\n\n/* Define to the one symbol short name of this package. */\n#define PACKAGE_TARNAME \"expat\"\n\n/* Define to the home page for this package. */\n#define PACKAGE_URL \"\"\n\n/* Define to the version of this package. */\n#define PACKAGE_VERSION \"2.1.0\"\n\n/* Define to 1 if you have the ANSI C header files. */\n#define STDC_HEADERS 1\n\n/* whether byteorder is bigendian */\n/* #undef WORDS_BIGENDIAN */\n\n/* Define to specify how much context to retain around the current parse\n   point. */\n#define XML_CONTEXT_BYTES 1024\n\n/* Define to make parameter entity parsing functionality available. */\n#define XML_DTD 1\n\n/* Define to make XML Namespaces functionality available. */\n#define XML_NS 1\n\n/* Define to __FUNCTION__ or \"\" if `__func__' does not conform to ANSI C. */\n/* #undef __func__ */\n\n/* Define to empty if `const' does not conform to ANSI C. */\n/* #undef const */\n\n/* Define to `long int' if <sys/types.h> does not define. */\n/* #undef off_t */\n\n/* Define to `unsigned int' if <sys/types.h> does not define. */\n/* #undef size_t */\n"
  },
  {
    "path": "atlas-aapt/external/expat/import_expat.sh",
    "content": "#!/bin/sh\n\nset -e\n\nif [ \"$1\" = \"\" ]; then\n   echo \"usage: $0 expat.tar.bz2\"\n   exit 1\nfi\n\necho \"Extracting $1\"\ntar --extract --bzip2 --strip-components=1 --file $1\n\necho \"Saving COPYING to NOTICE\"\ntouch MODULE_LICENSE_BSD_LIKE\nmv COPYING NOTICE\n\necho \"Removing unnecessary files\"\nrm CMake.README\nrm CMakeLists.txt\nrm ConfigureChecks.cmake\nrm MANIFEST\nrm Makefile.in\nrm aclocal.m4\nrm configure\nrm configure.ac\nrm examples/elements.dsp\nrm examples/outline.dsp\nrm expat.dsw\nrm expat.pc.in\nrm expat_config.h.cmake\nrm expat_config.h.in\nrm lib/Makefile.MPW\nrm lib/amigaconfig.h\nrm lib/expat.dsp\nrm lib/expat_static.dsp\nrm lib/expatw.dsp\nrm lib/expatw_static.dsp\nrm lib/libexpat.def\nrm lib/libexpatw.def\nrm lib/macconfig.h\nrm lib/winconfig.h\nrm tests/benchmark/benchmark.dsp\nrm tests/benchmark/benchmark.dsw\n\nrm -rf amiga\nrm -rf bcb5\nrm -rf conftools\nrm -rf m4\nrm -rf vms\nrm -rf win32\nrm -rf xmlwf\n\necho \"Import complete\"\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/ascii.h",
    "content": "/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd\n   See the file COPYING for copying permission.\n*/\n\n#define ASCII_A 0x41\n#define ASCII_B 0x42\n#define ASCII_C 0x43\n#define ASCII_D 0x44\n#define ASCII_E 0x45\n#define ASCII_F 0x46\n#define ASCII_G 0x47\n#define ASCII_H 0x48\n#define ASCII_I 0x49\n#define ASCII_J 0x4A\n#define ASCII_K 0x4B\n#define ASCII_L 0x4C\n#define ASCII_M 0x4D\n#define ASCII_N 0x4E\n#define ASCII_O 0x4F\n#define ASCII_P 0x50\n#define ASCII_Q 0x51\n#define ASCII_R 0x52\n#define ASCII_S 0x53\n#define ASCII_T 0x54\n#define ASCII_U 0x55\n#define ASCII_V 0x56\n#define ASCII_W 0x57\n#define ASCII_X 0x58\n#define ASCII_Y 0x59\n#define ASCII_Z 0x5A\n\n#define ASCII_a 0x61\n#define ASCII_b 0x62\n#define ASCII_c 0x63\n#define ASCII_d 0x64\n#define ASCII_e 0x65\n#define ASCII_f 0x66\n#define ASCII_g 0x67\n#define ASCII_h 0x68\n#define ASCII_i 0x69\n#define ASCII_j 0x6A\n#define ASCII_k 0x6B\n#define ASCII_l 0x6C\n#define ASCII_m 0x6D\n#define ASCII_n 0x6E\n#define ASCII_o 0x6F\n#define ASCII_p 0x70\n#define ASCII_q 0x71\n#define ASCII_r 0x72\n#define ASCII_s 0x73\n#define ASCII_t 0x74\n#define ASCII_u 0x75\n#define ASCII_v 0x76\n#define ASCII_w 0x77\n#define ASCII_x 0x78\n#define ASCII_y 0x79\n#define ASCII_z 0x7A\n\n#define ASCII_0 0x30\n#define ASCII_1 0x31\n#define ASCII_2 0x32\n#define ASCII_3 0x33\n#define ASCII_4 0x34\n#define ASCII_5 0x35\n#define ASCII_6 0x36\n#define ASCII_7 0x37\n#define ASCII_8 0x38\n#define ASCII_9 0x39\n\n#define ASCII_TAB 0x09\n#define ASCII_SPACE 0x20\n#define ASCII_EXCL 0x21\n#define ASCII_QUOT 0x22\n#define ASCII_AMP 0x26\n#define ASCII_APOS 0x27\n#define ASCII_MINUS 0x2D\n#define ASCII_PERIOD 0x2E\n#define ASCII_COLON 0x3A\n#define ASCII_SEMI 0x3B\n#define ASCII_LT 0x3C\n#define ASCII_EQUALS 0x3D\n#define ASCII_GT 0x3E\n#define ASCII_LSQB 0x5B\n#define ASCII_RSQB 0x5D\n#define ASCII_UNDERSCORE 0x5F\n#define ASCII_LPAREN 0x28\n#define ASCII_RPAREN 0x29\n#define ASCII_FF 0x0C\n#define ASCII_SLASH 0x2F\n#define ASCII_HASH 0x23\n#define ASCII_PIPE 0x7C\n#define ASCII_COMMA 0x2C\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/asciitab.h",
    "content": "/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd\n   See the file COPYING for copying permission.\n*/\n\n/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,\n/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,\n/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,\n/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,\n/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,\n/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,\n/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,\n/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,\n/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,\n/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,\n/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,\n/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,\n/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,\n/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,\n/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,\n/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,\n/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,\n/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,\n/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,\n/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,\n/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,\n/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,\n/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,\n/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/expat.h",
    "content": "/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd\n   See the file COPYING for copying permission.\n*/\n\n#ifndef Expat_INCLUDED\n#define Expat_INCLUDED 1\n\n#ifdef __VMS\n/*      0        1         2         3      0        1         2         3\n        1234567890123456789012345678901     1234567890123456789012345678901 */\n#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler\n#define XML_SetUnparsedEntityDeclHandler    XML_SetUnparsedEntDeclHandler\n#define XML_SetStartNamespaceDeclHandler    XML_SetStartNamespcDeclHandler\n#define XML_SetExternalEntityRefHandlerArg  XML_SetExternalEntRefHandlerArg\n#endif\n\n#include <stdlib.h>\n#include \"expat_external.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct XML_ParserStruct;\ntypedef struct XML_ParserStruct *XML_Parser;\n\n/* Should this be defined using stdbool.h when C99 is available? */\ntypedef unsigned char XML_Bool;\n#define XML_TRUE   ((XML_Bool) 1)\n#define XML_FALSE  ((XML_Bool) 0)\n\n/* The XML_Status enum gives the possible return values for several\n   API functions.  The preprocessor #defines are included so this\n   stanza can be added to code that still needs to support older\n   versions of Expat 1.95.x:\n\n   #ifndef XML_STATUS_OK\n   #define XML_STATUS_OK    1\n   #define XML_STATUS_ERROR 0\n   #endif\n\n   Otherwise, the #define hackery is quite ugly and would have been\n   dropped.\n*/\nenum XML_Status {\n  XML_STATUS_ERROR = 0,\n#define XML_STATUS_ERROR XML_STATUS_ERROR\n  XML_STATUS_OK = 1,\n#define XML_STATUS_OK XML_STATUS_OK\n  XML_STATUS_SUSPENDED = 2\n#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED\n};\n\nenum XML_Error {\n  XML_ERROR_NONE,\n  XML_ERROR_NO_MEMORY,\n  XML_ERROR_SYNTAX,\n  XML_ERROR_NO_ELEMENTS,\n  XML_ERROR_INVALID_TOKEN,\n  XML_ERROR_UNCLOSED_TOKEN,\n  XML_ERROR_PARTIAL_CHAR,\n  XML_ERROR_TAG_MISMATCH,\n  XML_ERROR_DUPLICATE_ATTRIBUTE,\n  XML_ERROR_JUNK_AFTER_DOC_ELEMENT,\n  XML_ERROR_PARAM_ENTITY_REF,\n  XML_ERROR_UNDEFINED_ENTITY,\n  XML_ERROR_RECURSIVE_ENTITY_REF,\n  XML_ERROR_ASYNC_ENTITY,\n  XML_ERROR_BAD_CHAR_REF,\n  XML_ERROR_BINARY_ENTITY_REF,\n  XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,\n  XML_ERROR_MISPLACED_XML_PI,\n  XML_ERROR_UNKNOWN_ENCODING,\n  XML_ERROR_INCORRECT_ENCODING,\n  XML_ERROR_UNCLOSED_CDATA_SECTION,\n  XML_ERROR_EXTERNAL_ENTITY_HANDLING,\n  XML_ERROR_NOT_STANDALONE,\n  XML_ERROR_UNEXPECTED_STATE,\n  XML_ERROR_ENTITY_DECLARED_IN_PE,\n  XML_ERROR_FEATURE_REQUIRES_XML_DTD,\n  XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING,\n  /* Added in 1.95.7. */\n  XML_ERROR_UNBOUND_PREFIX,\n  /* Added in 1.95.8. */\n  XML_ERROR_UNDECLARING_PREFIX,\n  XML_ERROR_INCOMPLETE_PE,\n  XML_ERROR_XML_DECL,\n  XML_ERROR_TEXT_DECL,\n  XML_ERROR_PUBLICID,\n  XML_ERROR_SUSPENDED,\n  XML_ERROR_NOT_SUSPENDED,\n  XML_ERROR_ABORTED,\n  XML_ERROR_FINISHED,\n  XML_ERROR_SUSPEND_PE,\n  /* Added in 2.0. */\n  XML_ERROR_RESERVED_PREFIX_XML,\n  XML_ERROR_RESERVED_PREFIX_XMLNS,\n  XML_ERROR_RESERVED_NAMESPACE_URI\n};\n\nenum XML_Content_Type {\n  XML_CTYPE_EMPTY = 1,\n  XML_CTYPE_ANY,\n  XML_CTYPE_MIXED,\n  XML_CTYPE_NAME,\n  XML_CTYPE_CHOICE,\n  XML_CTYPE_SEQ\n};\n\nenum XML_Content_Quant {\n  XML_CQUANT_NONE,\n  XML_CQUANT_OPT,\n  XML_CQUANT_REP,\n  XML_CQUANT_PLUS\n};\n\n/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be\n   XML_CQUANT_NONE, and the other fields will be zero or NULL.\n   If type == XML_CTYPE_MIXED, then quant will be NONE or REP and\n   numchildren will contain number of elements that may be mixed in\n   and children point to an array of XML_Content cells that will be\n   all of XML_CTYPE_NAME type with no quantification.\n\n   If type == XML_CTYPE_NAME, then the name points to the name, and\n   the numchildren field will be zero and children will be NULL. The\n   quant fields indicates any quantifiers placed on the name.\n\n   CHOICE and SEQ will have name NULL, the number of children in\n   numchildren and children will point, recursively, to an array\n   of XML_Content cells.\n\n   The EMPTY, ANY, and MIXED types will only occur at top level.\n*/\n\ntypedef struct XML_cp XML_Content;\n\nstruct XML_cp {\n  enum XML_Content_Type         type;\n  enum XML_Content_Quant        quant;\n  XML_Char *                    name;\n  unsigned int                  numchildren;\n  XML_Content *                 children;\n};\n\n\n/* This is called for an element declaration. See above for\n   description of the model argument. It's the caller's responsibility\n   to free model when finished with it.\n*/\ntypedef void (XMLCALL *XML_ElementDeclHandler) (void *userData,\n                                                const XML_Char *name,\n                                                XML_Content *model);\n\nXMLPARSEAPI(void)\nXML_SetElementDeclHandler(XML_Parser parser,\n                          XML_ElementDeclHandler eldecl);\n\n/* The Attlist declaration handler is called for *each* attribute. So\n   a single Attlist declaration with multiple attributes declared will\n   generate multiple calls to this handler. The \"default\" parameter\n   may be NULL in the case of the \"#IMPLIED\" or \"#REQUIRED\"\n   keyword. The \"isrequired\" parameter will be true and the default\n   value will be NULL in the case of \"#REQUIRED\". If \"isrequired\" is\n   true and default is non-NULL, then this is a \"#FIXED\" default.\n*/\ntypedef void (XMLCALL *XML_AttlistDeclHandler) (\n                                    void            *userData,\n                                    const XML_Char  *elname,\n                                    const XML_Char  *attname,\n                                    const XML_Char  *att_type,\n                                    const XML_Char  *dflt,\n                                    int              isrequired);\n\nXMLPARSEAPI(void)\nXML_SetAttlistDeclHandler(XML_Parser parser,\n                          XML_AttlistDeclHandler attdecl);\n\n/* The XML declaration handler is called for *both* XML declarations\n   and text declarations. The way to distinguish is that the version\n   parameter will be NULL for text declarations. The encoding\n   parameter may be NULL for XML declarations. The standalone\n   parameter will be -1, 0, or 1 indicating respectively that there\n   was no standalone parameter in the declaration, that it was given\n   as no, or that it was given as yes.\n*/\ntypedef void (XMLCALL *XML_XmlDeclHandler) (void           *userData,\n                                            const XML_Char *version,\n                                            const XML_Char *encoding,\n                                            int             standalone);\n\nXMLPARSEAPI(void)\nXML_SetXmlDeclHandler(XML_Parser parser,\n                      XML_XmlDeclHandler xmldecl);\n\n\ntypedef struct {\n  void *(*malloc_fcn)(size_t size);\n  void *(*realloc_fcn)(void *ptr, size_t size);\n  void (*free_fcn)(void *ptr);\n} XML_Memory_Handling_Suite;\n\n/* Constructs a new parser; encoding is the encoding specified by the\n   external protocol or NULL if there is none specified.\n*/\nXMLPARSEAPI(XML_Parser)\nXML_ParserCreate(const XML_Char *encoding);\n\n/* Constructs a new parser and namespace processor.  Element type\n   names and attribute names that belong to a namespace will be\n   expanded; unprefixed attribute names are never expanded; unprefixed\n   element type names are expanded only if there is a default\n   namespace. The expanded name is the concatenation of the namespace\n   URI, the namespace separator character, and the local part of the\n   name.  If the namespace separator is '\\0' then the namespace URI\n   and the local part will be concatenated without any separator.\n   It is a programming error to use the separator '\\0' with namespace\n   triplets (see XML_SetReturnNSTriplet).\n*/\nXMLPARSEAPI(XML_Parser)\nXML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);\n\n\n/* Constructs a new parser using the memory management suite referred to\n   by memsuite. If memsuite is NULL, then use the standard library memory\n   suite. If namespaceSeparator is non-NULL it creates a parser with\n   namespace processing as described above. The character pointed at\n   will serve as the namespace separator.\n\n   All further memory operations used for the created parser will come from\n   the given suite.\n*/\nXMLPARSEAPI(XML_Parser)\nXML_ParserCreate_MM(const XML_Char *encoding,\n                    const XML_Memory_Handling_Suite *memsuite,\n                    const XML_Char *namespaceSeparator);\n\n/* Prepare a parser object to be re-used.  This is particularly\n   valuable when memory allocation overhead is disproportionatly high,\n   such as when a large number of small documnents need to be parsed.\n   All handlers are cleared from the parser, except for the\n   unknownEncodingHandler. The parser's external state is re-initialized\n   except for the values of ns and ns_triplets.\n\n   Added in Expat 1.95.3.\n*/\nXMLPARSEAPI(XML_Bool)\nXML_ParserReset(XML_Parser parser, const XML_Char *encoding);\n\n/* atts is array of name/value pairs, terminated by 0;\n   names and values are 0 terminated.\n*/\ntypedef void (XMLCALL *XML_StartElementHandler) (void *userData,\n                                                 const XML_Char *name,\n                                                 const XML_Char **atts);\n\ntypedef void (XMLCALL *XML_EndElementHandler) (void *userData,\n                                               const XML_Char *name);\n\n\n/* s is not 0 terminated. */\ntypedef void (XMLCALL *XML_CharacterDataHandler) (void *userData,\n                                                  const XML_Char *s,\n                                                  int len);\n\n/* target and data are 0 terminated */\ntypedef void (XMLCALL *XML_ProcessingInstructionHandler) (\n                                                void *userData,\n                                                const XML_Char *target,\n                                                const XML_Char *data);\n\n/* data is 0 terminated */\ntypedef void (XMLCALL *XML_CommentHandler) (void *userData,\n                                            const XML_Char *data);\n\ntypedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData);\ntypedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);\n\n/* This is called for any characters in the XML document for which\n   there is no applicable handler.  This includes both characters that\n   are part of markup which is of a kind that is not reported\n   (comments, markup declarations), or characters that are part of a\n   construct which could be reported but for which no handler has been\n   supplied. The characters are passed exactly as they were in the XML\n   document except that they will be encoded in UTF-8 or UTF-16.\n   Line boundaries are not normalized. Note that a byte order mark\n   character is not passed to the default handler. There are no\n   guarantees about how characters are divided between calls to the\n   default handler: for example, a comment might be split between\n   multiple calls.\n*/\ntypedef void (XMLCALL *XML_DefaultHandler) (void *userData,\n                                            const XML_Char *s,\n                                            int len);\n\n/* This is called for the start of the DOCTYPE declaration, before\n   any DTD or internal subset is parsed.\n*/\ntypedef void (XMLCALL *XML_StartDoctypeDeclHandler) (\n                                            void *userData,\n                                            const XML_Char *doctypeName,\n                                            const XML_Char *sysid,\n                                            const XML_Char *pubid,\n                                            int has_internal_subset);\n\n/* This is called for the start of the DOCTYPE declaration when the\n   closing > is encountered, but after processing any external\n   subset.\n*/\ntypedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);\n\n/* This is called for entity declarations. The is_parameter_entity\n   argument will be non-zero if the entity is a parameter entity, zero\n   otherwise.\n\n   For internal entities (<!ENTITY foo \"bar\">), value will\n   be non-NULL and systemId, publicID, and notationName will be NULL.\n   The value string is NOT nul-terminated; the length is provided in\n   the value_length argument. Since it is legal to have zero-length\n   values, do not use this argument to test for internal entities.\n\n   For external entities, value will be NULL and systemId will be\n   non-NULL. The publicId argument will be NULL unless a public\n   identifier was provided. The notationName argument will have a\n   non-NULL value only for unparsed entity declarations.\n\n   Note that is_parameter_entity can't be changed to XML_Bool, since\n   that would break binary compatibility.\n*/\ntypedef void (XMLCALL *XML_EntityDeclHandler) (\n                              void *userData,\n                              const XML_Char *entityName,\n                              int is_parameter_entity,\n                              const XML_Char *value,\n                              int value_length,\n                              const XML_Char *base,\n                              const XML_Char *systemId,\n                              const XML_Char *publicId,\n                              const XML_Char *notationName);\n\nXMLPARSEAPI(void)\nXML_SetEntityDeclHandler(XML_Parser parser,\n                         XML_EntityDeclHandler handler);\n\n/* OBSOLETE -- OBSOLETE -- OBSOLETE\n   This handler has been superceded by the EntityDeclHandler above.\n   It is provided here for backward compatibility.\n\n   This is called for a declaration of an unparsed (NDATA) entity.\n   The base argument is whatever was set by XML_SetBase. The\n   entityName, systemId and notationName arguments will never be\n   NULL. The other arguments may be.\n*/\ntypedef void (XMLCALL *XML_UnparsedEntityDeclHandler) (\n                                    void *userData,\n                                    const XML_Char *entityName,\n                                    const XML_Char *base,\n                                    const XML_Char *systemId,\n                                    const XML_Char *publicId,\n                                    const XML_Char *notationName);\n\n/* This is called for a declaration of notation.  The base argument is\n   whatever was set by XML_SetBase. The notationName will never be\n   NULL.  The other arguments can be.\n*/\ntypedef void (XMLCALL *XML_NotationDeclHandler) (\n                                    void *userData,\n                                    const XML_Char *notationName,\n                                    const XML_Char *base,\n                                    const XML_Char *systemId,\n                                    const XML_Char *publicId);\n\n/* When namespace processing is enabled, these are called once for\n   each namespace declaration. The call to the start and end element\n   handlers occur between the calls to the start and end namespace\n   declaration handlers. For an xmlns attribute, prefix will be\n   NULL.  For an xmlns=\"\" attribute, uri will be NULL.\n*/\ntypedef void (XMLCALL *XML_StartNamespaceDeclHandler) (\n                                    void *userData,\n                                    const XML_Char *prefix,\n                                    const XML_Char *uri);\n\ntypedef void (XMLCALL *XML_EndNamespaceDeclHandler) (\n                                    void *userData,\n                                    const XML_Char *prefix);\n\n/* This is called if the document is not standalone, that is, it has an\n   external subset or a reference to a parameter entity, but does not\n   have standalone=\"yes\". If this handler returns XML_STATUS_ERROR,\n   then processing will not continue, and the parser will return a\n   XML_ERROR_NOT_STANDALONE error.\n   If parameter entity parsing is enabled, then in addition to the\n   conditions above this handler will only be called if the referenced\n   entity was actually read.\n*/\ntypedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);\n\n/* This is called for a reference to an external parsed general\n   entity.  The referenced entity is not automatically parsed.  The\n   application can parse it immediately or later using\n   XML_ExternalEntityParserCreate.\n\n   The parser argument is the parser parsing the entity containing the\n   reference; it can be passed as the parser argument to\n   XML_ExternalEntityParserCreate.  The systemId argument is the\n   system identifier as specified in the entity declaration; it will\n   not be NULL.\n\n   The base argument is the system identifier that should be used as\n   the base for resolving systemId if systemId was relative; this is\n   set by XML_SetBase; it may be NULL.\n\n   The publicId argument is the public identifier as specified in the\n   entity declaration, or NULL if none was specified; the whitespace\n   in the public identifier will have been normalized as required by\n   the XML spec.\n\n   The context argument specifies the parsing context in the format\n   expected by the context argument to XML_ExternalEntityParserCreate;\n   context is valid only until the handler returns, so if the\n   referenced entity is to be parsed later, it must be copied.\n   context is NULL only when the entity is a parameter entity.\n\n   The handler should return XML_STATUS_ERROR if processing should not\n   continue because of a fatal error in the handling of the external\n   entity.  In this case the calling parser will return an\n   XML_ERROR_EXTERNAL_ENTITY_HANDLING error.\n\n   Note that unlike other handlers the first argument is the parser,\n   not userData.\n*/\ntypedef int (XMLCALL *XML_ExternalEntityRefHandler) (\n                                    XML_Parser parser,\n                                    const XML_Char *context,\n                                    const XML_Char *base,\n                                    const XML_Char *systemId,\n                                    const XML_Char *publicId);\n\n/* This is called in two situations:\n   1) An entity reference is encountered for which no declaration\n      has been read *and* this is not an error.\n   2) An internal entity reference is read, but not expanded, because\n      XML_SetDefaultHandler has been called.\n   Note: skipped parameter entities in declarations and skipped general\n         entities in attribute values cannot be reported, because\n         the event would be out of sync with the reporting of the\n         declarations or attribute values\n*/\ntypedef void (XMLCALL *XML_SkippedEntityHandler) (\n                                    void *userData,\n                                    const XML_Char *entityName,\n                                    int is_parameter_entity);\n\n/* This structure is filled in by the XML_UnknownEncodingHandler to\n   provide information to the parser about encodings that are unknown\n   to the parser.\n\n   The map[b] member gives information about byte sequences whose\n   first byte is b.\n\n   If map[b] is c where c is >= 0, then b by itself encodes the\n   Unicode scalar value c.\n\n   If map[b] is -1, then the byte sequence is malformed.\n\n   If map[b] is -n, where n >= 2, then b is the first byte of an\n   n-byte sequence that encodes a single Unicode scalar value.\n\n   The data member will be passed as the first argument to the convert\n   function.\n\n   The convert function is used to convert multibyte sequences; s will\n   point to a n-byte sequence where map[(unsigned char)*s] == -n.  The\n   convert function must return the Unicode scalar value represented\n   by this byte sequence or -1 if the byte sequence is malformed.\n\n   The convert function may be NULL if the encoding is a single-byte\n   encoding, that is if map[b] >= -1 for all bytes b.\n\n   When the parser is finished with the encoding, then if release is\n   not NULL, it will call release passing it the data member; once\n   release has been called, the convert function will not be called\n   again.\n\n   Expat places certain restrictions on the encodings that are supported\n   using this mechanism.\n\n   1. Every ASCII character that can appear in a well-formed XML document,\n      other than the characters\n\n      $@\\^`{}~\n\n      must be represented by a single byte, and that byte must be the\n      same byte that represents that character in ASCII.\n\n   2. No character may require more than 4 bytes to encode.\n\n   3. All characters encoded must have Unicode scalar values <=\n      0xFFFF, (i.e., characters that would be encoded by surrogates in\n      UTF-16 are  not allowed).  Note that this restriction doesn't\n      apply to the built-in support for UTF-8 and UTF-16.\n\n   4. No Unicode character may be encoded by more than one distinct\n      sequence of bytes.\n*/\ntypedef struct {\n  int map[256];\n  void *data;\n  int (XMLCALL *convert)(void *data, const char *s);\n  void (XMLCALL *release)(void *data);\n} XML_Encoding;\n\n/* This is called for an encoding that is unknown to the parser.\n\n   The encodingHandlerData argument is that which was passed as the\n   second argument to XML_SetUnknownEncodingHandler.\n\n   The name argument gives the name of the encoding as specified in\n   the encoding declaration.\n\n   If the callback can provide information about the encoding, it must\n   fill in the XML_Encoding structure, and return XML_STATUS_OK.\n   Otherwise it must return XML_STATUS_ERROR.\n\n   If info does not describe a suitable encoding, then the parser will\n   return an XML_UNKNOWN_ENCODING error.\n*/\ntypedef int (XMLCALL *XML_UnknownEncodingHandler) (\n                                    void *encodingHandlerData,\n                                    const XML_Char *name,\n                                    XML_Encoding *info);\n\nXMLPARSEAPI(void)\nXML_SetElementHandler(XML_Parser parser,\n                      XML_StartElementHandler start,\n                      XML_EndElementHandler end);\n\nXMLPARSEAPI(void)\nXML_SetStartElementHandler(XML_Parser parser,\n                           XML_StartElementHandler handler);\n\nXMLPARSEAPI(void)\nXML_SetEndElementHandler(XML_Parser parser,\n                         XML_EndElementHandler handler);\n\nXMLPARSEAPI(void)\nXML_SetCharacterDataHandler(XML_Parser parser,\n                            XML_CharacterDataHandler handler);\n\nXMLPARSEAPI(void)\nXML_SetProcessingInstructionHandler(XML_Parser parser,\n                                    XML_ProcessingInstructionHandler handler);\nXMLPARSEAPI(void)\nXML_SetCommentHandler(XML_Parser parser,\n                      XML_CommentHandler handler);\n\nXMLPARSEAPI(void)\nXML_SetCdataSectionHandler(XML_Parser parser,\n                           XML_StartCdataSectionHandler start,\n                           XML_EndCdataSectionHandler end);\n\nXMLPARSEAPI(void)\nXML_SetStartCdataSectionHandler(XML_Parser parser,\n                                XML_StartCdataSectionHandler start);\n\nXMLPARSEAPI(void)\nXML_SetEndCdataSectionHandler(XML_Parser parser,\n                              XML_EndCdataSectionHandler end);\n\n/* This sets the default handler and also inhibits expansion of\n   internal entities. These entity references will be passed to the\n   default handler, or to the skipped entity handler, if one is set.\n*/\nXMLPARSEAPI(void)\nXML_SetDefaultHandler(XML_Parser parser,\n                      XML_DefaultHandler handler);\n\n/* This sets the default handler but does not inhibit expansion of\n   internal entities.  The entity reference will not be passed to the\n   default handler.\n*/\nXMLPARSEAPI(void)\nXML_SetDefaultHandlerExpand(XML_Parser parser,\n                            XML_DefaultHandler handler);\n\nXMLPARSEAPI(void)\nXML_SetDoctypeDeclHandler(XML_Parser parser,\n                          XML_StartDoctypeDeclHandler start,\n                          XML_EndDoctypeDeclHandler end);\n\nXMLPARSEAPI(void)\nXML_SetStartDoctypeDeclHandler(XML_Parser parser,\n                               XML_StartDoctypeDeclHandler start);\n\nXMLPARSEAPI(void)\nXML_SetEndDoctypeDeclHandler(XML_Parser parser,\n                             XML_EndDoctypeDeclHandler end);\n\nXMLPARSEAPI(void)\nXML_SetUnparsedEntityDeclHandler(XML_Parser parser,\n                                 XML_UnparsedEntityDeclHandler handler);\n\nXMLPARSEAPI(void)\nXML_SetNotationDeclHandler(XML_Parser parser,\n                           XML_NotationDeclHandler handler);\n\nXMLPARSEAPI(void)\nXML_SetNamespaceDeclHandler(XML_Parser parser,\n                            XML_StartNamespaceDeclHandler start,\n                            XML_EndNamespaceDeclHandler end);\n\nXMLPARSEAPI(void)\nXML_SetStartNamespaceDeclHandler(XML_Parser parser,\n                                 XML_StartNamespaceDeclHandler start);\n\nXMLPARSEAPI(void)\nXML_SetEndNamespaceDeclHandler(XML_Parser parser,\n                               XML_EndNamespaceDeclHandler end);\n\nXMLPARSEAPI(void)\nXML_SetNotStandaloneHandler(XML_Parser parser,\n                            XML_NotStandaloneHandler handler);\n\nXMLPARSEAPI(void)\nXML_SetExternalEntityRefHandler(XML_Parser parser,\n                                XML_ExternalEntityRefHandler handler);\n\n/* If a non-NULL value for arg is specified here, then it will be\n   passed as the first argument to the external entity ref handler\n   instead of the parser object.\n*/\nXMLPARSEAPI(void)\nXML_SetExternalEntityRefHandlerArg(XML_Parser parser,\n                                   void *arg);\n\nXMLPARSEAPI(void)\nXML_SetSkippedEntityHandler(XML_Parser parser,\n                            XML_SkippedEntityHandler handler);\n\nXMLPARSEAPI(void)\nXML_SetUnknownEncodingHandler(XML_Parser parser,\n                              XML_UnknownEncodingHandler handler,\n                              void *encodingHandlerData);\n\n/* This can be called within a handler for a start element, end\n   element, processing instruction or character data.  It causes the\n   corresponding markup to be passed to the default handler.\n*/\nXMLPARSEAPI(void)\nXML_DefaultCurrent(XML_Parser parser);\n\n/* If do_nst is non-zero, and namespace processing is in effect, and\n   a name has a prefix (i.e. an explicit namespace qualifier) then\n   that name is returned as a triplet in a single string separated by\n   the separator character specified when the parser was created: URI\n   + sep + local_name + sep + prefix.\n\n   If do_nst is zero, then namespace information is returned in the\n   default manner (URI + sep + local_name) whether or not the name\n   has a prefix.\n\n   Note: Calling XML_SetReturnNSTriplet after XML_Parse or\n     XML_ParseBuffer has no effect.\n*/\n\nXMLPARSEAPI(void)\nXML_SetReturnNSTriplet(XML_Parser parser, int do_nst);\n\n/* This value is passed as the userData argument to callbacks. */\nXMLPARSEAPI(void)\nXML_SetUserData(XML_Parser parser, void *userData);\n\n/* Returns the last value set by XML_SetUserData or NULL. */\n#define XML_GetUserData(parser) (*(void **)(parser))\n\n/* This is equivalent to supplying an encoding argument to\n   XML_ParserCreate. On success XML_SetEncoding returns non-zero,\n   zero otherwise.\n   Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer\n     has no effect and returns XML_STATUS_ERROR.\n*/\nXMLPARSEAPI(enum XML_Status)\nXML_SetEncoding(XML_Parser parser, const XML_Char *encoding);\n\n/* If this function is called, then the parser will be passed as the\n   first argument to callbacks instead of userData.  The userData will\n   still be accessible using XML_GetUserData.\n*/\nXMLPARSEAPI(void)\nXML_UseParserAsHandlerArg(XML_Parser parser);\n\n/* If useDTD == XML_TRUE is passed to this function, then the parser\n   will assume that there is an external subset, even if none is\n   specified in the document. In such a case the parser will call the\n   externalEntityRefHandler with a value of NULL for the systemId\n   argument (the publicId and context arguments will be NULL as well).\n   Note: For the purpose of checking WFC: Entity Declared, passing\n     useDTD == XML_TRUE will make the parser behave as if the document\n     had a DTD with an external subset.\n   Note: If this function is called, then this must be done before\n     the first call to XML_Parse or XML_ParseBuffer, since it will\n     have no effect after that.  Returns\n     XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.\n   Note: If the document does not have a DOCTYPE declaration at all,\n     then startDoctypeDeclHandler and endDoctypeDeclHandler will not\n     be called, despite an external subset being parsed.\n   Note: If XML_DTD is not defined when Expat is compiled, returns\n     XML_ERROR_FEATURE_REQUIRES_XML_DTD.\n*/\nXMLPARSEAPI(enum XML_Error)\nXML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);\n\n\n/* Sets the base to be used for resolving relative URIs in system\n   identifiers in declarations.  Resolving relative identifiers is\n   left to the application: this value will be passed through as the\n   base argument to the XML_ExternalEntityRefHandler,\n   XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base\n   argument will be copied.  Returns XML_STATUS_ERROR if out of memory,\n   XML_STATUS_OK otherwise.\n*/\nXMLPARSEAPI(enum XML_Status)\nXML_SetBase(XML_Parser parser, const XML_Char *base);\n\nXMLPARSEAPI(const XML_Char *)\nXML_GetBase(XML_Parser parser);\n\n/* Returns the number of the attribute/value pairs passed in last call\n   to the XML_StartElementHandler that were specified in the start-tag\n   rather than defaulted. Each attribute/value pair counts as 2; thus\n   this correspondds to an index into the atts array passed to the\n   XML_StartElementHandler.\n*/\nXMLPARSEAPI(int)\nXML_GetSpecifiedAttributeCount(XML_Parser parser);\n\n/* Returns the index of the ID attribute passed in the last call to\n   XML_StartElementHandler, or -1 if there is no ID attribute.  Each\n   attribute/value pair counts as 2; thus this correspondds to an\n   index into the atts array passed to the XML_StartElementHandler.\n*/\nXMLPARSEAPI(int)\nXML_GetIdAttributeIndex(XML_Parser parser);\n\n#ifdef XML_ATTR_INFO\n/* Source file byte offsets for the start and end of attribute names and values.\n   The value indices are exclusive of surrounding quotes; thus in a UTF-8 source\n   file an attribute value of \"blah\" will yield:\n   info->valueEnd - info->valueStart = 4 bytes.\n*/\ntypedef struct {\n  XML_Index  nameStart;  /* Offset to beginning of the attribute name. */\n  XML_Index  nameEnd;    /* Offset after the attribute name's last byte. */\n  XML_Index  valueStart; /* Offset to beginning of the attribute value. */\n  XML_Index  valueEnd;   /* Offset after the attribute value's last byte. */\n} XML_AttrInfo;\n\n/* Returns an array of XML_AttrInfo structures for the attribute/value pairs\n   passed in last call to the XML_StartElementHandler that were specified\n   in the start-tag rather than defaulted. Each attribute/value pair counts\n   as 1; thus the number of entries in the array is\n   XML_GetSpecifiedAttributeCount(parser) / 2.\n*/\nXMLPARSEAPI(const XML_AttrInfo *)\nXML_GetAttributeInfo(XML_Parser parser);\n#endif\n\n/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is\n   detected.  The last call to XML_Parse must have isFinal true; len\n   may be zero for this call (or any other).\n\n   Though the return values for these functions has always been\n   described as a Boolean value, the implementation, at least for the\n   1.95.x series, has always returned exactly one of the XML_Status\n   values.\n*/\nXMLPARSEAPI(enum XML_Status)\nXML_Parse(XML_Parser parser, const char *s, int len, int isFinal);\n\nXMLPARSEAPI(void *)\nXML_GetBuffer(XML_Parser parser, int len);\n\nXMLPARSEAPI(enum XML_Status)\nXML_ParseBuffer(XML_Parser parser, int len, int isFinal);\n\n/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return.\n   Must be called from within a call-back handler, except when aborting\n   (resumable = 0) an already suspended parser. Some call-backs may\n   still follow because they would otherwise get lost. Examples:\n   - endElementHandler() for empty elements when stopped in\n     startElementHandler(), \n   - endNameSpaceDeclHandler() when stopped in endElementHandler(), \n   and possibly others.\n\n   Can be called from most handlers, including DTD related call-backs,\n   except when parsing an external parameter entity and resumable != 0.\n   Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise.\n   Possible error codes: \n   - XML_ERROR_SUSPENDED: when suspending an already suspended parser.\n   - XML_ERROR_FINISHED: when the parser has already finished.\n   - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE.\n\n   When resumable != 0 (true) then parsing is suspended, that is, \n   XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. \n   Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer()\n   return XML_STATUS_ERROR with error code XML_ERROR_ABORTED.\n\n   *Note*:\n   This will be applied to the current parser instance only, that is, if\n   there is a parent parser then it will continue parsing when the\n   externalEntityRefHandler() returns. It is up to the implementation of\n   the externalEntityRefHandler() to call XML_StopParser() on the parent\n   parser (recursively), if one wants to stop parsing altogether.\n\n   When suspended, parsing can be resumed by calling XML_ResumeParser(). \n*/\nXMLPARSEAPI(enum XML_Status)\nXML_StopParser(XML_Parser parser, XML_Bool resumable);\n\n/* Resumes parsing after it has been suspended with XML_StopParser().\n   Must not be called from within a handler call-back. Returns same\n   status codes as XML_Parse() or XML_ParseBuffer().\n   Additional error code XML_ERROR_NOT_SUSPENDED possible.   \n\n   *Note*:\n   This must be called on the most deeply nested child parser instance\n   first, and on its parent parser only after the child parser has finished,\n   to be applied recursively until the document entity's parser is restarted.\n   That is, the parent parser will not resume by itself and it is up to the\n   application to call XML_ResumeParser() on it at the appropriate moment.\n*/\nXMLPARSEAPI(enum XML_Status)\nXML_ResumeParser(XML_Parser parser);\n\nenum XML_Parsing {\n  XML_INITIALIZED,\n  XML_PARSING,\n  XML_FINISHED,\n  XML_SUSPENDED\n};\n\ntypedef struct {\n  enum XML_Parsing parsing;\n  XML_Bool finalBuffer;\n} XML_ParsingStatus;\n\n/* Returns status of parser with respect to being initialized, parsing,\n   finished, or suspended and processing the final buffer.\n   XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus,\n   XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED\n*/\nXMLPARSEAPI(void)\nXML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status);\n\n/* Creates an XML_Parser object that can parse an external general\n   entity; context is a '\\0'-terminated string specifying the parse\n   context; encoding is a '\\0'-terminated string giving the name of\n   the externally specified encoding, or NULL if there is no\n   externally specified encoding.  The context string consists of a\n   sequence of tokens separated by formfeeds (\\f); a token consisting\n   of a name specifies that the general entity of the name is open; a\n   token of the form prefix=uri specifies the namespace for a\n   particular prefix; a token of the form =uri specifies the default\n   namespace.  This can be called at any point after the first call to\n   an ExternalEntityRefHandler so longer as the parser has not yet\n   been freed.  The new parser is completely independent and may\n   safely be used in a separate thread.  The handlers and userData are\n   initialized from the parser argument.  Returns NULL if out of memory.\n   Otherwise returns a new XML_Parser object.\n*/\nXMLPARSEAPI(XML_Parser)\nXML_ExternalEntityParserCreate(XML_Parser parser,\n                               const XML_Char *context,\n                               const XML_Char *encoding);\n\nenum XML_ParamEntityParsing {\n  XML_PARAM_ENTITY_PARSING_NEVER,\n  XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,\n  XML_PARAM_ENTITY_PARSING_ALWAYS\n};\n\n/* Controls parsing of parameter entities (including the external DTD\n   subset). If parsing of parameter entities is enabled, then\n   references to external parameter entities (including the external\n   DTD subset) will be passed to the handler set with\n   XML_SetExternalEntityRefHandler.  The context passed will be 0.\n\n   Unlike external general entities, external parameter entities can\n   only be parsed synchronously.  If the external parameter entity is\n   to be parsed, it must be parsed during the call to the external\n   entity ref handler: the complete sequence of\n   XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and\n   XML_ParserFree calls must be made during this call.  After\n   XML_ExternalEntityParserCreate has been called to create the parser\n   for the external parameter entity (context must be 0 for this\n   call), it is illegal to make any calls on the old parser until\n   XML_ParserFree has been called on the newly created parser.\n   If the library has been compiled without support for parameter\n   entity parsing (ie without XML_DTD being defined), then\n   XML_SetParamEntityParsing will return 0 if parsing of parameter\n   entities is requested; otherwise it will return non-zero.\n   Note: If XML_SetParamEntityParsing is called after XML_Parse or\n      XML_ParseBuffer, then it has no effect and will always return 0.\n*/\nXMLPARSEAPI(int)\nXML_SetParamEntityParsing(XML_Parser parser,\n                          enum XML_ParamEntityParsing parsing);\n\n/* Sets the hash salt to use for internal hash calculations.\n   Helps in preventing DoS attacks based on predicting hash\n   function behavior. This must be called before parsing is started.\n   Returns 1 if successful, 0 when called after parsing has started.\n*/\nXMLPARSEAPI(int)\nXML_SetHashSalt(XML_Parser parser,\n                unsigned long hash_salt);\n\n/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then\n   XML_GetErrorCode returns information about the error.\n*/\nXMLPARSEAPI(enum XML_Error)\nXML_GetErrorCode(XML_Parser parser);\n\n/* These functions return information about the current parse\n   location.  They may be called from any callback called to report\n   some parse event; in this case the location is the location of the\n   first of the sequence of characters that generated the event.  When\n   called from callbacks generated by declarations in the document\n   prologue, the location identified isn't as neatly defined, but will\n   be within the relevant markup.  When called outside of the callback\n   functions, the position indicated will be just past the last parse\n   event (regardless of whether there was an associated callback).\n   \n   They may also be called after returning from a call to XML_Parse\n   or XML_ParseBuffer.  If the return value is XML_STATUS_ERROR then\n   the location is the location of the character at which the error\n   was detected; otherwise the location is the location of the last\n   parse event, as described above.\n*/\nXMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);\nXMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);\nXMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);\n\n/* Return the number of bytes in the current event.\n   Returns 0 if the event is in an internal entity.\n*/\nXMLPARSEAPI(int)\nXML_GetCurrentByteCount(XML_Parser parser);\n\n/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets\n   the integer pointed to by offset to the offset within this buffer\n   of the current parse position, and sets the integer pointed to by size\n   to the size of this buffer (the number of input bytes). Otherwise\n   returns a NULL pointer. Also returns a NULL pointer if a parse isn't\n   active.\n\n   NOTE: The character pointer returned should not be used outside\n   the handler that makes the call.\n*/\nXMLPARSEAPI(const char *)\nXML_GetInputContext(XML_Parser parser,\n                    int *offset,\n                    int *size);\n\n/* For backwards compatibility with previous versions. */\n#define XML_GetErrorLineNumber   XML_GetCurrentLineNumber\n#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber\n#define XML_GetErrorByteIndex    XML_GetCurrentByteIndex\n\n/* Frees the content model passed to the element declaration handler */\nXMLPARSEAPI(void)\nXML_FreeContentModel(XML_Parser parser, XML_Content *model);\n\n/* Exposing the memory handling functions used in Expat */\nXMLPARSEAPI(void *)\nXML_MemMalloc(XML_Parser parser, size_t size);\n\nXMLPARSEAPI(void *)\nXML_MemRealloc(XML_Parser parser, void *ptr, size_t size);\n\nXMLPARSEAPI(void)\nXML_MemFree(XML_Parser parser, void *ptr);\n\n/* Frees memory used by the parser. */\nXMLPARSEAPI(void)\nXML_ParserFree(XML_Parser parser);\n\n/* Returns a string describing the error. */\nXMLPARSEAPI(const XML_LChar *)\nXML_ErrorString(enum XML_Error code);\n\n/* Return a string containing the version number of this expat */\nXMLPARSEAPI(const XML_LChar *)\nXML_ExpatVersion(void);\n\ntypedef struct {\n  int major;\n  int minor;\n  int micro;\n} XML_Expat_Version;\n\n/* Return an XML_Expat_Version structure containing numeric version\n   number information for this version of expat.\n*/\nXMLPARSEAPI(XML_Expat_Version)\nXML_ExpatVersionInfo(void);\n\n/* Added in Expat 1.95.5. */\nenum XML_FeatureEnum {\n  XML_FEATURE_END = 0,\n  XML_FEATURE_UNICODE,\n  XML_FEATURE_UNICODE_WCHAR_T,\n  XML_FEATURE_DTD,\n  XML_FEATURE_CONTEXT_BYTES,\n  XML_FEATURE_MIN_SIZE,\n  XML_FEATURE_SIZEOF_XML_CHAR,\n  XML_FEATURE_SIZEOF_XML_LCHAR,\n  XML_FEATURE_NS,\n  XML_FEATURE_LARGE_SIZE,\n  XML_FEATURE_ATTR_INFO\n  /* Additional features must be added to the end of this enum. */\n};\n\ntypedef struct {\n  enum XML_FeatureEnum  feature;\n  const XML_LChar       *name;\n  long int              value;\n} XML_Feature;\n\nXMLPARSEAPI(const XML_Feature *)\nXML_GetFeatureList(void);\n\n\n/* Expat follows the GNU/Linux convention of odd number minor version for\n   beta/development releases and even number minor version for stable\n   releases. Micro is bumped with each release, and set to 0 with each\n   change to major or minor version.\n*/\n#define XML_MAJOR_VERSION 2\n#define XML_MINOR_VERSION 1\n#define XML_MICRO_VERSION 1\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* not Expat_INCLUDED */\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/expat_external.h",
    "content": "/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd\n   See the file COPYING for copying permission.\n*/\n\n#ifndef Expat_External_INCLUDED\n#define Expat_External_INCLUDED 1\n\n/* External API definitions */\n\n#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)\n#define XML_USE_MSC_EXTENSIONS 1\n#endif\n\n/* Expat tries very hard to make the API boundary very specifically\n   defined.  There are two macros defined to control this boundary;\n   each of these can be defined before including this header to\n   achieve some different behavior, but doing so it not recommended or\n   tested frequently.\n\n   XMLCALL    - The calling convention to use for all calls across the\n                \"library boundary.\"  This will default to cdecl, and\n                try really hard to tell the compiler that's what we\n                want.\n\n   XMLIMPORT  - Whatever magic is needed to note that a function is\n                to be imported from a dynamically loaded library\n                (.dll, .so, or .sl, depending on your platform).\n\n   The XMLCALL macro was added in Expat 1.95.7.  The only one which is\n   expected to be directly useful in client code is XMLCALL.\n\n   Note that on at least some Unix versions, the Expat library must be\n   compiled with the cdecl calling convention as the default since\n   system headers may assume the cdecl convention.\n*/\n#ifndef XMLCALL\n#if defined(_MSC_VER)\n#define XMLCALL __cdecl\n#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)\n#define XMLCALL __attribute__((cdecl))\n#else\n/* For any platform which uses this definition and supports more than\n   one calling convention, we need to extend this definition to\n   declare the convention used on that platform, if it's possible to\n   do so.\n\n   If this is the case for your platform, please file a bug report\n   with information on how to identify your platform via the C\n   pre-processor and how to specify the same calling convention as the\n   platform's malloc() implementation.\n*/\n#define XMLCALL\n#endif\n#endif  /* not defined XMLCALL */\n\n\n#if !defined(XML_STATIC) && !defined(XMLIMPORT)\n#ifndef XML_BUILDING_EXPAT\n/* using Expat from an application */\n\n#ifdef XML_USE_MSC_EXTENSIONS\n#define XMLIMPORT __declspec(dllimport)\n#endif\n\n#endif\n#endif  /* not defined XML_STATIC */\n\n\n/* If we didn't define it above, define it away: */\n#ifndef XMLIMPORT\n#define XMLIMPORT\n#endif\n\n\n#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifdef XML_UNICODE_WCHAR_T\n#define XML_UNICODE\n#endif\n\n#ifdef XML_UNICODE     /* Information is UTF-16 encoded. */\n#ifdef XML_UNICODE_WCHAR_T\ntypedef wchar_t XML_Char;\ntypedef wchar_t XML_LChar;\n#else\ntypedef unsigned short XML_Char;\ntypedef char XML_LChar;\n#endif /* XML_UNICODE_WCHAR_T */\n#else                  /* Information is UTF-8 encoded. */\ntypedef char XML_Char;\ntypedef char XML_LChar;\n#endif /* XML_UNICODE */\n\n#ifdef XML_LARGE_SIZE  /* Use large integers for file/stream positions. */\n#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400\ntypedef __int64 XML_Index; \ntypedef unsigned __int64 XML_Size;\n#else\ntypedef long long XML_Index;\ntypedef unsigned long long XML_Size;\n#endif\n#else\ntypedef long XML_Index;\ntypedef unsigned long XML_Size;\n#endif /* XML_LARGE_SIZE */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* not Expat_External_INCLUDED */\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/iasciitab.h",
    "content": "/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd\n   See the file COPYING for copying permission.\n*/\n\n/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */\n/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,\n/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,\n/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,\n/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,\n/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,\n/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,\n/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,\n/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,\n/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,\n/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,\n/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,\n/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,\n/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,\n/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,\n/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,\n/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,\n/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,\n/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,\n/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,\n/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,\n/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,\n/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,\n/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,\n/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/internal.h",
    "content": "/* internal.h\n\n   Internal definitions used by Expat.  This is not needed to compile\n   client code.\n\n   The following calling convention macros are defined for frequently\n   called functions:\n\n   FASTCALL    - Used for those internal functions that have a simple\n                 body and a low number of arguments and local variables.\n\n   PTRCALL     - Used for functions called though function pointers.\n\n   PTRFASTCALL - Like PTRCALL, but for low number of arguments.\n\n   inline      - Used for selected internal functions for which inlining\n                 may improve performance on some platforms.\n\n   Note: Use of these macros is based on judgement, not hard rules,\n         and therefore subject to change.\n*/\n\n#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__)\n/* We'll use this version by default only where we know it helps.\n\n   regparm() generates warnings on Solaris boxes.   See SF bug #692878.\n\n   Instability reported with egcs on a RedHat Linux 7.3.\n   Let's comment out:\n   #define FASTCALL __attribute__((stdcall, regparm(3)))\n   and let's try this:\n*/\n#define FASTCALL __attribute__((regparm(3)))\n#define PTRFASTCALL __attribute__((regparm(3)))\n#endif\n\n/* Using __fastcall seems to have an unexpected negative effect under\n   MS VC++, especially for function pointers, so we won't use it for\n   now on that platform. It may be reconsidered for a future release\n   if it can be made more effective.\n   Likely reason: __fastcall on Windows is like stdcall, therefore\n   the compiler cannot perform stack optimizations for call clusters.\n*/\n\n/* Make sure all of these are defined if they aren't already. */\n\n#ifndef FASTCALL\n#define FASTCALL\n#endif\n\n#ifndef PTRCALL\n#define PTRCALL\n#endif\n\n#ifndef PTRFASTCALL\n#define PTRFASTCALL\n#endif\n\n#ifndef XML_MIN_SIZE\n#if !defined(__cplusplus) && !defined(inline)\n#ifdef __GNUC__\n#define inline __inline\n#endif /* __GNUC__ */\n#endif\n#endif /* XML_MIN_SIZE */\n\n#ifdef __cplusplus\n#define inline inline\n#else\n#ifndef inline\n#define inline\n#endif\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/latin1tab.h",
    "content": "/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd\n   See the file COPYING for copying permission.\n*/\n\n/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,\n/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,\n/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,\n/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,\n/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,\n/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,\n/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,\n/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,\n/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,\n/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,\n/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,\n/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,\n/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,\n/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,\n/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,\n/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,\n/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,\n/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,\n/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/nametab.h",
    "content": "static const unsigned namingBitmap[] = {\n0x00000000, 0x00000000, 0x00000000, 0x00000000,\n0x00000000, 0x00000000, 0x00000000, 0x00000000,\n0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,\n0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,\n0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,\n0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,\n0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,\n0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,\n0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,\n0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,\n0x00000000, 0x00000000, 0x00000000, 0x00000000,\n0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,\n0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,\n0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,\n0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,\n0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,\n0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,\n0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,\n0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,\n0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,\n0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,\n0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,\n0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,\n0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,\n0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,\n0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,\n0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,\n0x00000000, 0x00000000, 0x00000000, 0x00000000,\n0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,\n0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,\n0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,\n0x00000000, 0x00000000, 0x00000000, 0x00000000,\n0x00000000, 0x00000000, 0x00000000, 0x00000000,\n0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,\n0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,\n0x40000000, 0xF580C900, 0x00000007, 0x02010800,\n0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,\n0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,\n0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,\n0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,\n0x00000000, 0x00004C40, 0x00000000, 0x00000000,\n0x00000007, 0x00000000, 0x00000000, 0x00000000,\n0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,\n0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,\n0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,\n0x00000000, 0x00000000, 0x00000000, 0x00000000,\n0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,\n0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,\n0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,\n0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,\n0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,\n0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,\n0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,\n0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,\n0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,\n0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,\n0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,\n0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,\n0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,\n0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,\n0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,\n0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,\n0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,\n0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,\n0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,\n0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,\n0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,\n0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,\n0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,\n0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,\n0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,\n0x00000000, 0x00000000, 0x00000000, 0x00000000,\n0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,\n0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,\n0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,\n0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,\n0x00000000, 0x00000000, 0x00000000, 0x00000000,\n0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,\n0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,\n0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,\n};\nstatic const unsigned char nmstrtPages[] = {\n0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,\n0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,\n0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,\n0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n};\nstatic const unsigned char namePages[] = {\n0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,\n0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,\n0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,\n0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n};\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/utf8tab.h",
    "content": "/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd\n   See the file COPYING for copying permission.\n*/\n\n\n/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,\n/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,\n/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,\n/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,\n/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,\n/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,\n/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,\n/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,\n/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,\n/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,\n/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,\n/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,\n/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,\n/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,\n/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,\n/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,\n/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/xmlparse.c",
    "content": "/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd\n   See the file COPYING for copying permission.\n*/\n\n#include <stddef.h>\n#include <string.h>                     /* memset(), memcpy() */\n#include <assert.h>\n#include <limits.h>                     /* UINT_MAX */\n#include <time.h>                       /* time() */\n\n#define XML_BUILDING_EXPAT 1\n\n#ifdef COMPILED_FROM_DSP\n#include \"winconfig.h\"\n#elif defined(MACOS_CLASSIC)\n#include \"macconfig.h\"\n#elif defined(__amigaos__)\n#include \"amigaconfig.h\"\n#elif defined(__WATCOMC__)\n#include \"watcomconfig.h\"\n#elif defined(HAVE_EXPAT_CONFIG_H)\n#include <expat_config.h>\n#endif /* ndef COMPILED_FROM_DSP */\n\n#include \"ascii.h\"\n#include \"expat.h\"\n\n#ifdef XML_UNICODE\n#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX\n#define XmlConvert XmlUtf16Convert\n#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding\n#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS\n#define XmlEncode XmlUtf16Encode\n/* Using pointer subtraction to convert to integer type. */\n#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))\ntypedef unsigned short ICHAR;\n#else\n#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX\n#define XmlConvert XmlUtf8Convert\n#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding\n#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS\n#define XmlEncode XmlUtf8Encode\n#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)\ntypedef char ICHAR;\n#endif\n\n\n#ifndef XML_NS\n\n#define XmlInitEncodingNS XmlInitEncoding\n#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding\n#undef XmlGetInternalEncodingNS\n#define XmlGetInternalEncodingNS XmlGetInternalEncoding\n#define XmlParseXmlDeclNS XmlParseXmlDecl\n\n#endif\n\n#ifdef XML_UNICODE\n\n#ifdef XML_UNICODE_WCHAR_T\n#define XML_T(x) (const wchar_t)x\n#define XML_L(x) L ## x\n#else\n#define XML_T(x) (const unsigned short)x\n#define XML_L(x) x\n#endif\n\n#else\n\n#define XML_T(x) x\n#define XML_L(x) x\n\n#endif\n\n/* Round up n to be a multiple of sz, where sz is a power of 2. */\n#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))\n\n/* Handle the case where memmove() doesn't exist. */\n#ifndef HAVE_MEMMOVE\n#ifdef HAVE_BCOPY\n#define memmove(d,s,l) bcopy((s),(d),(l))\n#else\n#error memmove does not exist on this platform, nor is a substitute available\n#endif /* HAVE_BCOPY */\n#endif /* HAVE_MEMMOVE */\n\n#include \"internal.h\"\n#include \"xmltok.h\"\n#include \"xmlrole.h\"\n\ntypedef const XML_Char *KEY;\n\ntypedef struct {\n  KEY name;\n} NAMED;\n\ntypedef struct {\n  NAMED **v;\n  unsigned char power;\n  size_t size;\n  size_t used;\n  const XML_Memory_Handling_Suite *mem;\n} HASH_TABLE;\n\n/* Basic character hash algorithm, taken from Python's string hash:\n   h = h * 1000003 ^ character, the constant being a prime number.\n\n*/\n#ifdef XML_UNICODE\n#define CHAR_HASH(h, c) \\\n  (((h) * 0xF4243) ^ (unsigned short)(c))\n#else\n#define CHAR_HASH(h, c) \\\n  (((h) * 0xF4243) ^ (unsigned char)(c))\n#endif\n\n/* For probing (after a collision) we need a step size relative prime\n   to the hash table size, which is a power of 2. We use double-hashing,\n   since we can calculate a second hash value cheaply by taking those bits\n   of the first hash value that were discarded (masked out) when the table\n   index was calculated: index = hash & mask, where mask = table->size - 1.\n   We limit the maximum step size to table->size / 4 (mask >> 2) and make\n   it odd, since odd numbers are always relative prime to a power of 2.\n*/\n#define SECOND_HASH(hash, mask, power) \\\n  ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))\n#define PROBE_STEP(hash, mask, power) \\\n  ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))\n\ntypedef struct {\n  NAMED **p;\n  NAMED **end;\n} HASH_TABLE_ITER;\n\n#define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */\n#define INIT_DATA_BUF_SIZE 1024\n#define INIT_ATTS_SIZE 16\n#define INIT_ATTS_VERSION 0xFFFFFFFF\n#define INIT_BLOCK_SIZE 1024\n#define INIT_BUFFER_SIZE 1024\n\n#define EXPAND_SPARE 24\n\ntypedef struct binding {\n  struct prefix *prefix;\n  struct binding *nextTagBinding;\n  struct binding *prevPrefixBinding;\n  const struct attribute_id *attId;\n  XML_Char *uri;\n  int uriLen;\n  int uriAlloc;\n} BINDING;\n\ntypedef struct prefix {\n  const XML_Char *name;\n  BINDING *binding;\n} PREFIX;\n\ntypedef struct {\n  const XML_Char *str;\n  const XML_Char *localPart;\n  const XML_Char *prefix;\n  int strLen;\n  int uriLen;\n  int prefixLen;\n} TAG_NAME;\n\n/* TAG represents an open element.\n   The name of the element is stored in both the document and API\n   encodings.  The memory buffer 'buf' is a separately-allocated\n   memory area which stores the name.  During the XML_Parse()/\n   XMLParseBuffer() when the element is open, the memory for the 'raw'\n   version of the name (in the document encoding) is shared with the\n   document buffer.  If the element is open across calls to\n   XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to\n   contain the 'raw' name as well.\n\n   A parser re-uses these structures, maintaining a list of allocated\n   TAG objects in a free list.\n*/\ntypedef struct tag {\n  struct tag *parent;           /* parent of this element */\n  const char *rawName;          /* tagName in the original encoding */\n  int rawNameLength;\n  TAG_NAME name;                /* tagName in the API encoding */\n  char *buf;                    /* buffer for name components */\n  char *bufEnd;                 /* end of the buffer */\n  BINDING *bindings;\n} TAG;\n\ntypedef struct {\n  const XML_Char *name;\n  const XML_Char *textPtr;\n  int textLen;                  /* length in XML_Chars */\n  int processed;                /* # of processed bytes - when suspended */\n  const XML_Char *systemId;\n  const XML_Char *base;\n  const XML_Char *publicId;\n  const XML_Char *notation;\n  XML_Bool open;\n  XML_Bool is_param;\n  XML_Bool is_internal; /* true if declared in internal subset outside PE */\n} ENTITY;\n\ntypedef struct {\n  enum XML_Content_Type         type;\n  enum XML_Content_Quant        quant;\n  const XML_Char *              name;\n  int                           firstchild;\n  int                           lastchild;\n  int                           childcnt;\n  int                           nextsib;\n} CONTENT_SCAFFOLD;\n\n#define INIT_SCAFFOLD_ELEMENTS 32\n\ntypedef struct block {\n  struct block *next;\n  int size;\n  XML_Char s[1];\n} BLOCK;\n\ntypedef struct {\n  BLOCK *blocks;\n  BLOCK *freeBlocks;\n  const XML_Char *end;\n  XML_Char *ptr;\n  XML_Char *start;\n  const XML_Memory_Handling_Suite *mem;\n} STRING_POOL;\n\n/* The XML_Char before the name is used to determine whether\n   an attribute has been specified. */\ntypedef struct attribute_id {\n  XML_Char *name;\n  PREFIX *prefix;\n  XML_Bool maybeTokenized;\n  XML_Bool xmlns;\n} ATTRIBUTE_ID;\n\ntypedef struct {\n  const ATTRIBUTE_ID *id;\n  XML_Bool isCdata;\n  const XML_Char *value;\n} DEFAULT_ATTRIBUTE;\n\ntypedef struct {\n  unsigned long version;\n  unsigned long hash;\n  const XML_Char *uriName;\n} NS_ATT;\n\ntypedef struct {\n  const XML_Char *name;\n  PREFIX *prefix;\n  const ATTRIBUTE_ID *idAtt;\n  int nDefaultAtts;\n  int allocDefaultAtts;\n  DEFAULT_ATTRIBUTE *defaultAtts;\n} ELEMENT_TYPE;\n\ntypedef struct {\n  HASH_TABLE generalEntities;\n  HASH_TABLE elementTypes;\n  HASH_TABLE attributeIds;\n  HASH_TABLE prefixes;\n  STRING_POOL pool;\n  STRING_POOL entityValuePool;\n  /* false once a parameter entity reference has been skipped */\n  XML_Bool keepProcessing;\n  /* true once an internal or external PE reference has been encountered;\n     this includes the reference to an external subset */\n  XML_Bool hasParamEntityRefs;\n  XML_Bool standalone;\n#ifdef XML_DTD\n  /* indicates if external PE has been read */\n  XML_Bool paramEntityRead;\n  HASH_TABLE paramEntities;\n#endif /* XML_DTD */\n  PREFIX defaultPrefix;\n  /* === scaffolding for building content model === */\n  XML_Bool in_eldecl;\n  CONTENT_SCAFFOLD *scaffold;\n  unsigned contentStringLen;\n  unsigned scaffSize;\n  unsigned scaffCount;\n  int scaffLevel;\n  int *scaffIndex;\n} DTD;\n\ntypedef struct open_internal_entity {\n  const char *internalEventPtr;\n  const char *internalEventEndPtr;\n  struct open_internal_entity *next;\n  ENTITY *entity;\n  int startTagLevel;\n  XML_Bool betweenDecl; /* WFC: PE Between Declarations */\n} OPEN_INTERNAL_ENTITY;\n\ntypedef enum XML_Error PTRCALL Processor(XML_Parser parser,\n                                         const char *start,\n                                         const char *end,\n                                         const char **endPtr);\n\nstatic Processor prologProcessor;\nstatic Processor prologInitProcessor;\nstatic Processor contentProcessor;\nstatic Processor cdataSectionProcessor;\n#ifdef XML_DTD\nstatic Processor ignoreSectionProcessor;\nstatic Processor externalParEntProcessor;\nstatic Processor externalParEntInitProcessor;\nstatic Processor entityValueProcessor;\nstatic Processor entityValueInitProcessor;\n#endif /* XML_DTD */\nstatic Processor epilogProcessor;\nstatic Processor errorProcessor;\nstatic Processor externalEntityInitProcessor;\nstatic Processor externalEntityInitProcessor2;\nstatic Processor externalEntityInitProcessor3;\nstatic Processor externalEntityContentProcessor;\nstatic Processor internalEntityProcessor;\n\nstatic enum XML_Error\nhandleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);\nstatic enum XML_Error\nprocessXmlDecl(XML_Parser parser, int isGeneralTextEntity,\n               const char *s, const char *next);\nstatic enum XML_Error\ninitializeEncoding(XML_Parser parser);\nstatic enum XML_Error\ndoProlog(XML_Parser parser, const ENCODING *enc, const char *s,\n         const char *end, int tok, const char *next, const char **nextPtr,\n         XML_Bool haveMore);\nstatic enum XML_Error\nprocessInternalEntity(XML_Parser parser, ENTITY *entity,\n                      XML_Bool betweenDecl);\nstatic enum XML_Error\ndoContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,\n          const char *start, const char *end, const char **endPtr,\n          XML_Bool haveMore);\nstatic enum XML_Error\ndoCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,\n               const char *end, const char **nextPtr, XML_Bool haveMore);\n#ifdef XML_DTD\nstatic enum XML_Error\ndoIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,\n                const char *end, const char **nextPtr, XML_Bool haveMore);\n#endif /* XML_DTD */\n\nstatic enum XML_Error\nstoreAtts(XML_Parser parser, const ENCODING *, const char *s,\n          TAG_NAME *tagNamePtr, BINDING **bindingsPtr);\nstatic enum XML_Error\naddBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,\n           const XML_Char *uri, BINDING **bindingsPtr);\nstatic int\ndefineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,\n                XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);\nstatic enum XML_Error\nstoreAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,\n                    const char *, const char *, STRING_POOL *);\nstatic enum XML_Error\nappendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,\n                     const char *, const char *, STRING_POOL *);\nstatic ATTRIBUTE_ID *\ngetAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,\n               const char *end);\nstatic int\nsetElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);\nstatic enum XML_Error\nstoreEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,\n                 const char *end);\nstatic int\nreportProcessingInstruction(XML_Parser parser, const ENCODING *enc,\n                            const char *start, const char *end);\nstatic int\nreportComment(XML_Parser parser, const ENCODING *enc, const char *start,\n              const char *end);\nstatic void\nreportDefault(XML_Parser parser, const ENCODING *enc, const char *start,\n              const char *end);\n\nstatic const XML_Char * getContext(XML_Parser parser);\nstatic XML_Bool\nsetContext(XML_Parser parser, const XML_Char *context);\n\nstatic void FASTCALL normalizePublicId(XML_Char *s);\n\nstatic DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);\n/* do not call if parentParser != NULL */\nstatic void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);\nstatic void\ndtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);\nstatic int\ndtdCopy(XML_Parser oldParser,\n        DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);\nstatic int\ncopyEntityTable(XML_Parser oldParser,\n                HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);\nstatic NAMED *\nlookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);\nstatic void FASTCALL\nhashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);\nstatic void FASTCALL hashTableClear(HASH_TABLE *);\nstatic void FASTCALL hashTableDestroy(HASH_TABLE *);\nstatic void FASTCALL\nhashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);\nstatic NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);\n\nstatic void FASTCALL\npoolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);\nstatic void FASTCALL poolClear(STRING_POOL *);\nstatic void FASTCALL poolDestroy(STRING_POOL *);\nstatic XML_Char *\npoolAppend(STRING_POOL *pool, const ENCODING *enc,\n           const char *ptr, const char *end);\nstatic XML_Char *\npoolStoreString(STRING_POOL *pool, const ENCODING *enc,\n                const char *ptr, const char *end);\nstatic XML_Bool FASTCALL poolGrow(STRING_POOL *pool);\nstatic const XML_Char * FASTCALL\npoolCopyString(STRING_POOL *pool, const XML_Char *s);\nstatic const XML_Char *\npoolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);\nstatic const XML_Char * FASTCALL\npoolAppendString(STRING_POOL *pool, const XML_Char *s);\n\nstatic int FASTCALL nextScaffoldPart(XML_Parser parser);\nstatic XML_Content * build_model(XML_Parser parser);\nstatic ELEMENT_TYPE *\ngetElementType(XML_Parser parser, const ENCODING *enc,\n               const char *ptr, const char *end);\n\nstatic unsigned long generate_hash_secret_salt(void);\nstatic XML_Bool startParsing(XML_Parser parser);\n\nstatic XML_Parser\nparserCreate(const XML_Char *encodingName,\n             const XML_Memory_Handling_Suite *memsuite,\n             const XML_Char *nameSep,\n             DTD *dtd);\n\nstatic void\nparserInit(XML_Parser parser, const XML_Char *encodingName);\n\n#define poolStart(pool) ((pool)->start)\n#define poolEnd(pool) ((pool)->ptr)\n#define poolLength(pool) ((pool)->ptr - (pool)->start)\n#define poolChop(pool) ((void)--(pool->ptr))\n#define poolLastChar(pool) (((pool)->ptr)[-1])\n#define poolDiscard(pool) ((pool)->ptr = (pool)->start)\n#define poolFinish(pool) ((pool)->start = (pool)->ptr)\n#define poolAppendChar(pool, c) \\\n  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \\\n   ? 0 \\\n   : ((*((pool)->ptr)++ = c), 1))\n\nstruct XML_ParserStruct {\n  /* The first member must be userData so that the XML_GetUserData\n     macro works. */\n  void *m_userData;\n  void *m_handlerArg;\n  char *m_buffer;\n  const XML_Memory_Handling_Suite m_mem;\n  /* first character to be parsed */\n  const char *m_bufferPtr;\n  /* past last character to be parsed */\n  char *m_bufferEnd;\n  /* allocated end of buffer */\n  const char *m_bufferLim;\n  XML_Index m_parseEndByteIndex;\n  const char *m_parseEndPtr;\n  XML_Char *m_dataBuf;\n  XML_Char *m_dataBufEnd;\n  XML_StartElementHandler m_startElementHandler;\n  XML_EndElementHandler m_endElementHandler;\n  XML_CharacterDataHandler m_characterDataHandler;\n  XML_ProcessingInstructionHandler m_processingInstructionHandler;\n  XML_CommentHandler m_commentHandler;\n  XML_StartCdataSectionHandler m_startCdataSectionHandler;\n  XML_EndCdataSectionHandler m_endCdataSectionHandler;\n  XML_DefaultHandler m_defaultHandler;\n  XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;\n  XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;\n  XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;\n  XML_NotationDeclHandler m_notationDeclHandler;\n  XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;\n  XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;\n  XML_NotStandaloneHandler m_notStandaloneHandler;\n  XML_ExternalEntityRefHandler m_externalEntityRefHandler;\n  XML_Parser m_externalEntityRefHandlerArg;\n  XML_SkippedEntityHandler m_skippedEntityHandler;\n  XML_UnknownEncodingHandler m_unknownEncodingHandler;\n  XML_ElementDeclHandler m_elementDeclHandler;\n  XML_AttlistDeclHandler m_attlistDeclHandler;\n  XML_EntityDeclHandler m_entityDeclHandler;\n  XML_XmlDeclHandler m_xmlDeclHandler;\n  const ENCODING *m_encoding;\n  INIT_ENCODING m_initEncoding;\n  const ENCODING *m_internalEncoding;\n  const XML_Char *m_protocolEncodingName;\n  XML_Bool m_ns;\n  XML_Bool m_ns_triplets;\n  void *m_unknownEncodingMem;\n  void *m_unknownEncodingData;\n  void *m_unknownEncodingHandlerData;\n  void (XMLCALL *m_unknownEncodingRelease)(void *);\n  PROLOG_STATE m_prologState;\n  Processor *m_processor;\n  enum XML_Error m_errorCode;\n  const char *m_eventPtr;\n  const char *m_eventEndPtr;\n  const char *m_positionPtr;\n  OPEN_INTERNAL_ENTITY *m_openInternalEntities;\n  OPEN_INTERNAL_ENTITY *m_freeInternalEntities;\n  XML_Bool m_defaultExpandInternalEntities;\n  int m_tagLevel;\n  ENTITY *m_declEntity;\n  const XML_Char *m_doctypeName;\n  const XML_Char *m_doctypeSysid;\n  const XML_Char *m_doctypePubid;\n  const XML_Char *m_declAttributeType;\n  const XML_Char *m_declNotationName;\n  const XML_Char *m_declNotationPublicId;\n  ELEMENT_TYPE *m_declElementType;\n  ATTRIBUTE_ID *m_declAttributeId;\n  XML_Bool m_declAttributeIsCdata;\n  XML_Bool m_declAttributeIsId;\n  DTD *m_dtd;\n  const XML_Char *m_curBase;\n  TAG *m_tagStack;\n  TAG *m_freeTagList;\n  BINDING *m_inheritedBindings;\n  BINDING *m_freeBindingList;\n  int m_attsSize;\n  int m_nSpecifiedAtts;\n  int m_idAttIndex;\n  ATTRIBUTE *m_atts;\n  NS_ATT *m_nsAtts;\n  unsigned long m_nsAttsVersion;\n  unsigned char m_nsAttsPower;\n#ifdef XML_ATTR_INFO\n  XML_AttrInfo *m_attInfo;\n#endif\n  POSITION m_position;\n  STRING_POOL m_tempPool;\n  STRING_POOL m_temp2Pool;\n  char *m_groupConnector;\n  unsigned int m_groupSize;\n  XML_Char m_namespaceSeparator;\n  XML_Parser m_parentParser;\n  XML_ParsingStatus m_parsingStatus;\n#ifdef XML_DTD\n  XML_Bool m_isParamEntity;\n  XML_Bool m_useForeignDTD;\n  enum XML_ParamEntityParsing m_paramEntityParsing;\n#endif\n  unsigned long m_hash_secret_salt;\n};\n\n#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))\n#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))\n#define FREE(p) (parser->m_mem.free_fcn((p)))\n\n#define userData (parser->m_userData)\n#define handlerArg (parser->m_handlerArg)\n#define startElementHandler (parser->m_startElementHandler)\n#define endElementHandler (parser->m_endElementHandler)\n#define characterDataHandler (parser->m_characterDataHandler)\n#define processingInstructionHandler \\\n        (parser->m_processingInstructionHandler)\n#define commentHandler (parser->m_commentHandler)\n#define startCdataSectionHandler \\\n        (parser->m_startCdataSectionHandler)\n#define endCdataSectionHandler (parser->m_endCdataSectionHandler)\n#define defaultHandler (parser->m_defaultHandler)\n#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)\n#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)\n#define unparsedEntityDeclHandler \\\n        (parser->m_unparsedEntityDeclHandler)\n#define notationDeclHandler (parser->m_notationDeclHandler)\n#define startNamespaceDeclHandler \\\n        (parser->m_startNamespaceDeclHandler)\n#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)\n#define notStandaloneHandler (parser->m_notStandaloneHandler)\n#define externalEntityRefHandler \\\n        (parser->m_externalEntityRefHandler)\n#define externalEntityRefHandlerArg \\\n        (parser->m_externalEntityRefHandlerArg)\n#define internalEntityRefHandler \\\n        (parser->m_internalEntityRefHandler)\n#define skippedEntityHandler (parser->m_skippedEntityHandler)\n#define unknownEncodingHandler (parser->m_unknownEncodingHandler)\n#define elementDeclHandler (parser->m_elementDeclHandler)\n#define attlistDeclHandler (parser->m_attlistDeclHandler)\n#define entityDeclHandler (parser->m_entityDeclHandler)\n#define xmlDeclHandler (parser->m_xmlDeclHandler)\n#define encoding (parser->m_encoding)\n#define initEncoding (parser->m_initEncoding)\n#define internalEncoding (parser->m_internalEncoding)\n#define unknownEncodingMem (parser->m_unknownEncodingMem)\n#define unknownEncodingData (parser->m_unknownEncodingData)\n#define unknownEncodingHandlerData \\\n  (parser->m_unknownEncodingHandlerData)\n#define unknownEncodingRelease (parser->m_unknownEncodingRelease)\n#define protocolEncodingName (parser->m_protocolEncodingName)\n#define ns (parser->m_ns)\n#define ns_triplets (parser->m_ns_triplets)\n#define prologState (parser->m_prologState)\n#define processor (parser->m_processor)\n#define errorCode (parser->m_errorCode)\n#define eventPtr (parser->m_eventPtr)\n#define eventEndPtr (parser->m_eventEndPtr)\n#define positionPtr (parser->m_positionPtr)\n#define position (parser->m_position)\n#define openInternalEntities (parser->m_openInternalEntities)\n#define freeInternalEntities (parser->m_freeInternalEntities)\n#define defaultExpandInternalEntities \\\n        (parser->m_defaultExpandInternalEntities)\n#define tagLevel (parser->m_tagLevel)\n#define buffer (parser->m_buffer)\n#define bufferPtr (parser->m_bufferPtr)\n#define bufferEnd (parser->m_bufferEnd)\n#define parseEndByteIndex (parser->m_parseEndByteIndex)\n#define parseEndPtr (parser->m_parseEndPtr)\n#define bufferLim (parser->m_bufferLim)\n#define dataBuf (parser->m_dataBuf)\n#define dataBufEnd (parser->m_dataBufEnd)\n#define _dtd (parser->m_dtd)\n#define curBase (parser->m_curBase)\n#define declEntity (parser->m_declEntity)\n#define doctypeName (parser->m_doctypeName)\n#define doctypeSysid (parser->m_doctypeSysid)\n#define doctypePubid (parser->m_doctypePubid)\n#define declAttributeType (parser->m_declAttributeType)\n#define declNotationName (parser->m_declNotationName)\n#define declNotationPublicId (parser->m_declNotationPublicId)\n#define declElementType (parser->m_declElementType)\n#define declAttributeId (parser->m_declAttributeId)\n#define declAttributeIsCdata (parser->m_declAttributeIsCdata)\n#define declAttributeIsId (parser->m_declAttributeIsId)\n#define freeTagList (parser->m_freeTagList)\n#define freeBindingList (parser->m_freeBindingList)\n#define inheritedBindings (parser->m_inheritedBindings)\n#define tagStack (parser->m_tagStack)\n#define atts (parser->m_atts)\n#define attsSize (parser->m_attsSize)\n#define nSpecifiedAtts (parser->m_nSpecifiedAtts)\n#define idAttIndex (parser->m_idAttIndex)\n#define nsAtts (parser->m_nsAtts)\n#define nsAttsVersion (parser->m_nsAttsVersion)\n#define nsAttsPower (parser->m_nsAttsPower)\n#define attInfo (parser->m_attInfo)\n#define tempPool (parser->m_tempPool)\n#define temp2Pool (parser->m_temp2Pool)\n#define groupConnector (parser->m_groupConnector)\n#define groupSize (parser->m_groupSize)\n#define namespaceSeparator (parser->m_namespaceSeparator)\n#define parentParser (parser->m_parentParser)\n#define ps_parsing (parser->m_parsingStatus.parsing)\n#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)\n#ifdef XML_DTD\n#define isParamEntity (parser->m_isParamEntity)\n#define useForeignDTD (parser->m_useForeignDTD)\n#define paramEntityParsing (parser->m_paramEntityParsing)\n#endif /* XML_DTD */\n#define hash_secret_salt (parser->m_hash_secret_salt)\n\nXML_Parser XMLCALL\nXML_ParserCreate(const XML_Char *encodingName)\n{\n  return XML_ParserCreate_MM(encodingName, NULL, NULL);\n}\n\nXML_Parser XMLCALL\nXML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)\n{\n  XML_Char tmp[2];\n  *tmp = nsSep;\n  return XML_ParserCreate_MM(encodingName, NULL, tmp);\n}\n\nstatic const XML_Char implicitContext[] = {\n  ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,\n  ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,\n  ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,\n  ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,\n  ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,\n  ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\\0'\n};\n\nstatic unsigned long\ngenerate_hash_secret_salt(void)\n{\n  unsigned int seed = time(NULL) % UINT_MAX;\n  srand(seed);\n  return rand();\n}\n\nstatic XML_Bool  /* only valid for root parser */\nstartParsing(XML_Parser parser)\n{\n    /* hash functions must be initialized before setContext() is called */\n    if (hash_secret_salt == 0)\n      hash_secret_salt = generate_hash_secret_salt();\n    if (ns) {\n      /* implicit context only set for root parser, since child\n         parsers (i.e. external entity parsers) will inherit it\n      */\n      return setContext(parser, implicitContext);\n    }\n    return XML_TRUE;\n}\n\nXML_Parser XMLCALL\nXML_ParserCreate_MM(const XML_Char *encodingName,\n                    const XML_Memory_Handling_Suite *memsuite,\n                    const XML_Char *nameSep)\n{\n  return parserCreate(encodingName, memsuite, nameSep, NULL);\n}\n\nstatic XML_Parser\nparserCreate(const XML_Char *encodingName,\n             const XML_Memory_Handling_Suite *memsuite,\n             const XML_Char *nameSep,\n             DTD *dtd)\n{\n  XML_Parser parser;\n\n  if (memsuite) {\n    XML_Memory_Handling_Suite *mtemp;\n    parser = (XML_Parser)\n      memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));\n    if (parser != NULL) {\n      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);\n      mtemp->malloc_fcn = memsuite->malloc_fcn;\n      mtemp->realloc_fcn = memsuite->realloc_fcn;\n      mtemp->free_fcn = memsuite->free_fcn;\n    }\n  }\n  else {\n    XML_Memory_Handling_Suite *mtemp;\n    parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));\n    if (parser != NULL) {\n      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);\n      mtemp->malloc_fcn = malloc;\n      mtemp->realloc_fcn = realloc;\n      mtemp->free_fcn = free;\n    }\n  }\n\n  if (!parser)\n    return parser;\n\n  buffer = NULL;\n  bufferLim = NULL;\n\n  attsSize = INIT_ATTS_SIZE;\n  atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));\n  if (atts == NULL) {\n    FREE(parser);\n    return NULL;\n  }\n#ifdef XML_ATTR_INFO\n  attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo));\n  if (attInfo == NULL) {\n    FREE(atts);\n    FREE(parser);\n    return NULL;\n  }\n#endif\n  dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));\n  if (dataBuf == NULL) {\n    FREE(atts);\n#ifdef XML_ATTR_INFO\n    FREE(attInfo);\n#endif\n    FREE(parser);\n    return NULL;\n  }\n  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;\n\n  if (dtd)\n    _dtd = dtd;\n  else {\n    _dtd = dtdCreate(&parser->m_mem);\n    if (_dtd == NULL) {\n      FREE(dataBuf);\n      FREE(atts);\n#ifdef XML_ATTR_INFO\n      FREE(attInfo);\n#endif\n      FREE(parser);\n      return NULL;\n    }\n  }\n\n  freeBindingList = NULL;\n  freeTagList = NULL;\n  freeInternalEntities = NULL;\n\n  groupSize = 0;\n  groupConnector = NULL;\n\n  unknownEncodingHandler = NULL;\n  unknownEncodingHandlerData = NULL;\n\n  namespaceSeparator = ASCII_EXCL;\n  ns = XML_FALSE;\n  ns_triplets = XML_FALSE;\n\n  nsAtts = NULL;\n  nsAttsVersion = 0;\n  nsAttsPower = 0;\n\n  poolInit(&tempPool, &(parser->m_mem));\n  poolInit(&temp2Pool, &(parser->m_mem));\n  parserInit(parser, encodingName);\n\n  if (encodingName && !protocolEncodingName) {\n    XML_ParserFree(parser);\n    return NULL;\n  }\n\n  if (nameSep) {\n    ns = XML_TRUE;\n    internalEncoding = XmlGetInternalEncodingNS();\n    namespaceSeparator = *nameSep;\n  }\n  else {\n    internalEncoding = XmlGetInternalEncoding();\n  }\n\n  return parser;\n}\n\nstatic void\nparserInit(XML_Parser parser, const XML_Char *encodingName)\n{\n  processor = prologInitProcessor;\n  XmlPrologStateInit(&prologState);\n  protocolEncodingName = (encodingName != NULL\n                          ? poolCopyString(&tempPool, encodingName)\n                          : NULL);\n  curBase = NULL;\n  XmlInitEncoding(&initEncoding, &encoding, 0);\n  userData = NULL;\n  handlerArg = NULL;\n  startElementHandler = NULL;\n  endElementHandler = NULL;\n  characterDataHandler = NULL;\n  processingInstructionHandler = NULL;\n  commentHandler = NULL;\n  startCdataSectionHandler = NULL;\n  endCdataSectionHandler = NULL;\n  defaultHandler = NULL;\n  startDoctypeDeclHandler = NULL;\n  endDoctypeDeclHandler = NULL;\n  unparsedEntityDeclHandler = NULL;\n  notationDeclHandler = NULL;\n  startNamespaceDeclHandler = NULL;\n  endNamespaceDeclHandler = NULL;\n  notStandaloneHandler = NULL;\n  externalEntityRefHandler = NULL;\n  externalEntityRefHandlerArg = parser;\n  skippedEntityHandler = NULL;\n  elementDeclHandler = NULL;\n  attlistDeclHandler = NULL;\n  entityDeclHandler = NULL;\n  xmlDeclHandler = NULL;\n  bufferPtr = buffer;\n  bufferEnd = buffer;\n  parseEndByteIndex = 0;\n  parseEndPtr = NULL;\n  declElementType = NULL;\n  declAttributeId = NULL;\n  declEntity = NULL;\n  doctypeName = NULL;\n  doctypeSysid = NULL;\n  doctypePubid = NULL;\n  declAttributeType = NULL;\n  declNotationName = NULL;\n  declNotationPublicId = NULL;\n  declAttributeIsCdata = XML_FALSE;\n  declAttributeIsId = XML_FALSE;\n  memset(&position, 0, sizeof(POSITION));\n  errorCode = XML_ERROR_NONE;\n  eventPtr = NULL;\n  eventEndPtr = NULL;\n  positionPtr = NULL;\n  openInternalEntities = NULL;\n  defaultExpandInternalEntities = XML_TRUE;\n  tagLevel = 0;\n  tagStack = NULL;\n  inheritedBindings = NULL;\n  nSpecifiedAtts = 0;\n  unknownEncodingMem = NULL;\n  unknownEncodingRelease = NULL;\n  unknownEncodingData = NULL;\n  parentParser = NULL;\n  ps_parsing = XML_INITIALIZED;\n#ifdef XML_DTD\n  isParamEntity = XML_FALSE;\n  useForeignDTD = XML_FALSE;\n  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;\n#endif\n  hash_secret_salt = 0;\n}\n\n/* moves list of bindings to freeBindingList */\nstatic void FASTCALL\nmoveToFreeBindingList(XML_Parser parser, BINDING *bindings)\n{\n  while (bindings) {\n    BINDING *b = bindings;\n    bindings = bindings->nextTagBinding;\n    b->nextTagBinding = freeBindingList;\n    freeBindingList = b;\n  }\n}\n\nXML_Bool XMLCALL\nXML_ParserReset(XML_Parser parser, const XML_Char *encodingName)\n{\n  TAG *tStk;\n  OPEN_INTERNAL_ENTITY *openEntityList;\n  if (parentParser)\n    return XML_FALSE;\n  /* move tagStack to freeTagList */\n  tStk = tagStack;\n  while (tStk) {\n    TAG *tag = tStk;\n    tStk = tStk->parent;\n    tag->parent = freeTagList;\n    moveToFreeBindingList(parser, tag->bindings);\n    tag->bindings = NULL;\n    freeTagList = tag;\n  }\n  /* move openInternalEntities to freeInternalEntities */\n  openEntityList = openInternalEntities;\n  while (openEntityList) {\n    OPEN_INTERNAL_ENTITY *openEntity = openEntityList;\n    openEntityList = openEntity->next;\n    openEntity->next = freeInternalEntities;\n    freeInternalEntities = openEntity;\n  }\n  moveToFreeBindingList(parser, inheritedBindings);\n  FREE(unknownEncodingMem);\n  if (unknownEncodingRelease)\n    unknownEncodingRelease(unknownEncodingData);\n  poolClear(&tempPool);\n  poolClear(&temp2Pool);\n  parserInit(parser, encodingName);\n  dtdReset(_dtd, &parser->m_mem);\n  return XML_TRUE;\n}\n\nenum XML_Status XMLCALL\nXML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)\n{\n  /* Block after XML_Parse()/XML_ParseBuffer() has been called.\n     XXX There's no way for the caller to determine which of the\n     XXX possible error cases caused the XML_STATUS_ERROR return.\n  */\n  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)\n    return XML_STATUS_ERROR;\n  if (encodingName == NULL)\n    protocolEncodingName = NULL;\n  else {\n    protocolEncodingName = poolCopyString(&tempPool, encodingName);\n    if (!protocolEncodingName)\n      return XML_STATUS_ERROR;\n  }\n  return XML_STATUS_OK;\n}\n\nXML_Parser XMLCALL\nXML_ExternalEntityParserCreate(XML_Parser oldParser,\n                               const XML_Char *context,\n                               const XML_Char *encodingName)\n{\n  XML_Parser parser = oldParser;\n  DTD *newDtd = NULL;\n  DTD *oldDtd = _dtd;\n  XML_StartElementHandler oldStartElementHandler = startElementHandler;\n  XML_EndElementHandler oldEndElementHandler = endElementHandler;\n  XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;\n  XML_ProcessingInstructionHandler oldProcessingInstructionHandler\n      = processingInstructionHandler;\n  XML_CommentHandler oldCommentHandler = commentHandler;\n  XML_StartCdataSectionHandler oldStartCdataSectionHandler\n      = startCdataSectionHandler;\n  XML_EndCdataSectionHandler oldEndCdataSectionHandler\n      = endCdataSectionHandler;\n  XML_DefaultHandler oldDefaultHandler = defaultHandler;\n  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler\n      = unparsedEntityDeclHandler;\n  XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;\n  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler\n      = startNamespaceDeclHandler;\n  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler\n      = endNamespaceDeclHandler;\n  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;\n  XML_ExternalEntityRefHandler oldExternalEntityRefHandler\n      = externalEntityRefHandler;\n  XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;\n  XML_UnknownEncodingHandler oldUnknownEncodingHandler\n      = unknownEncodingHandler;\n  XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;\n  XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;\n  XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;\n  XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;\n  ELEMENT_TYPE * oldDeclElementType = declElementType;\n\n  void *oldUserData = userData;\n  void *oldHandlerArg = handlerArg;\n  XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;\n  XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;\n#ifdef XML_DTD\n  enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;\n  int oldInEntityValue = prologState.inEntityValue;\n#endif\n  XML_Bool oldns_triplets = ns_triplets;\n  /* Note that the new parser shares the same hash secret as the old\n     parser, so that dtdCopy and copyEntityTable can lookup values\n     from hash tables associated with either parser without us having\n     to worry which hash secrets each table has.\n  */\n  unsigned long oldhash_secret_salt = hash_secret_salt;\n\n#ifdef XML_DTD\n  if (!context)\n    newDtd = oldDtd;\n#endif /* XML_DTD */\n\n  /* Note that the magical uses of the pre-processor to make field\n     access look more like C++ require that `parser' be overwritten\n     here.  This makes this function more painful to follow than it\n     would be otherwise.\n  */\n  if (ns) {\n    XML_Char tmp[2];\n    *tmp = namespaceSeparator;\n    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);\n  }\n  else {\n    parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);\n  }\n\n  if (!parser)\n    return NULL;\n\n  startElementHandler = oldStartElementHandler;\n  endElementHandler = oldEndElementHandler;\n  characterDataHandler = oldCharacterDataHandler;\n  processingInstructionHandler = oldProcessingInstructionHandler;\n  commentHandler = oldCommentHandler;\n  startCdataSectionHandler = oldStartCdataSectionHandler;\n  endCdataSectionHandler = oldEndCdataSectionHandler;\n  defaultHandler = oldDefaultHandler;\n  unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;\n  notationDeclHandler = oldNotationDeclHandler;\n  startNamespaceDeclHandler = oldStartNamespaceDeclHandler;\n  endNamespaceDeclHandler = oldEndNamespaceDeclHandler;\n  notStandaloneHandler = oldNotStandaloneHandler;\n  externalEntityRefHandler = oldExternalEntityRefHandler;\n  skippedEntityHandler = oldSkippedEntityHandler;\n  unknownEncodingHandler = oldUnknownEncodingHandler;\n  elementDeclHandler = oldElementDeclHandler;\n  attlistDeclHandler = oldAttlistDeclHandler;\n  entityDeclHandler = oldEntityDeclHandler;\n  xmlDeclHandler = oldXmlDeclHandler;\n  declElementType = oldDeclElementType;\n  userData = oldUserData;\n  if (oldUserData == oldHandlerArg)\n    handlerArg = userData;\n  else\n    handlerArg = parser;\n  if (oldExternalEntityRefHandlerArg != oldParser)\n    externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;\n  defaultExpandInternalEntities = oldDefaultExpandInternalEntities;\n  ns_triplets = oldns_triplets;\n  hash_secret_salt = oldhash_secret_salt;\n  parentParser = oldParser;\n#ifdef XML_DTD\n  paramEntityParsing = oldParamEntityParsing;\n  prologState.inEntityValue = oldInEntityValue;\n  if (context) {\n#endif /* XML_DTD */\n    if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)\n      || !setContext(parser, context)) {\n      XML_ParserFree(parser);\n      return NULL;\n    }\n    processor = externalEntityInitProcessor;\n#ifdef XML_DTD\n  }\n  else {\n    /* The DTD instance referenced by _dtd is shared between the document's\n       root parser and external PE parsers, therefore one does not need to\n       call setContext. In addition, one also *must* not call setContext,\n       because this would overwrite existing prefix->binding pointers in\n       _dtd with ones that get destroyed with the external PE parser.\n       This would leave those prefixes with dangling pointers.\n    */\n    isParamEntity = XML_TRUE;\n    XmlPrologStateInitExternalEntity(&prologState);\n    processor = externalParEntInitProcessor;\n  }\n#endif /* XML_DTD */\n  return parser;\n}\n\nstatic void FASTCALL\ndestroyBindings(BINDING *bindings, XML_Parser parser)\n{\n  for (;;) {\n    BINDING *b = bindings;\n    if (!b)\n      break;\n    bindings = b->nextTagBinding;\n    FREE(b->uri);\n    FREE(b);\n  }\n}\n\nvoid XMLCALL\nXML_ParserFree(XML_Parser parser)\n{\n  TAG *tagList;\n  OPEN_INTERNAL_ENTITY *entityList;\n  if (parser == NULL)\n    return;\n  /* free tagStack and freeTagList */\n  tagList = tagStack;\n  for (;;) {\n    TAG *p;\n    if (tagList == NULL) {\n      if (freeTagList == NULL)\n        break;\n      tagList = freeTagList;\n      freeTagList = NULL;\n    }\n    p = tagList;\n    tagList = tagList->parent;\n    FREE(p->buf);\n    destroyBindings(p->bindings, parser);\n    FREE(p);\n  }\n  /* free openInternalEntities and freeInternalEntities */\n  entityList = openInternalEntities;\n  for (;;) {\n    OPEN_INTERNAL_ENTITY *openEntity;\n    if (entityList == NULL) {\n      if (freeInternalEntities == NULL)\n        break;\n      entityList = freeInternalEntities;\n      freeInternalEntities = NULL;\n    }\n    openEntity = entityList;\n    entityList = entityList->next;\n    FREE(openEntity);\n  }\n\n  destroyBindings(freeBindingList, parser);\n  destroyBindings(inheritedBindings, parser);\n  poolDestroy(&tempPool);\n  poolDestroy(&temp2Pool);\n#ifdef XML_DTD\n  /* external parameter entity parsers share the DTD structure\n     parser->m_dtd with the root parser, so we must not destroy it\n  */\n  if (!isParamEntity && _dtd)\n#else\n  if (_dtd)\n#endif /* XML_DTD */\n    dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);\n  FREE((void *)atts);\n#ifdef XML_ATTR_INFO\n  FREE((void *)attInfo);\n#endif\n  FREE(groupConnector);\n  FREE(buffer);\n  FREE(dataBuf);\n  FREE(nsAtts);\n  FREE(unknownEncodingMem);\n  if (unknownEncodingRelease)\n    unknownEncodingRelease(unknownEncodingData);\n  FREE(parser);\n}\n\nvoid XMLCALL\nXML_UseParserAsHandlerArg(XML_Parser parser)\n{\n  handlerArg = parser;\n}\n\nenum XML_Error XMLCALL\nXML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)\n{\n#ifdef XML_DTD\n  /* block after XML_Parse()/XML_ParseBuffer() has been called */\n  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)\n    return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;\n  useForeignDTD = useDTD;\n  return XML_ERROR_NONE;\n#else\n  return XML_ERROR_FEATURE_REQUIRES_XML_DTD;\n#endif\n}\n\nvoid XMLCALL\nXML_SetReturnNSTriplet(XML_Parser parser, int do_nst)\n{\n  /* block after XML_Parse()/XML_ParseBuffer() has been called */\n  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)\n    return;\n  ns_triplets = do_nst ? XML_TRUE : XML_FALSE;\n}\n\nvoid XMLCALL\nXML_SetUserData(XML_Parser parser, void *p)\n{\n  if (handlerArg == userData)\n    handlerArg = userData = p;\n  else\n    userData = p;\n}\n\nenum XML_Status XMLCALL\nXML_SetBase(XML_Parser parser, const XML_Char *p)\n{\n  if (p) {\n    p = poolCopyString(&_dtd->pool, p);\n    if (!p)\n      return XML_STATUS_ERROR;\n    curBase = p;\n  }\n  else\n    curBase = NULL;\n  return XML_STATUS_OK;\n}\n\nconst XML_Char * XMLCALL\nXML_GetBase(XML_Parser parser)\n{\n  return curBase;\n}\n\nint XMLCALL\nXML_GetSpecifiedAttributeCount(XML_Parser parser)\n{\n  return nSpecifiedAtts;\n}\n\nint XMLCALL\nXML_GetIdAttributeIndex(XML_Parser parser)\n{\n  return idAttIndex;\n}\n\n#ifdef XML_ATTR_INFO\nconst XML_AttrInfo * XMLCALL\nXML_GetAttributeInfo(XML_Parser parser)\n{\n  return attInfo;\n}\n#endif\n\nvoid XMLCALL\nXML_SetElementHandler(XML_Parser parser,\n                      XML_StartElementHandler start,\n                      XML_EndElementHandler end)\n{\n  startElementHandler = start;\n  endElementHandler = end;\n}\n\nvoid XMLCALL\nXML_SetStartElementHandler(XML_Parser parser,\n                           XML_StartElementHandler start) {\n  startElementHandler = start;\n}\n\nvoid XMLCALL\nXML_SetEndElementHandler(XML_Parser parser,\n                         XML_EndElementHandler end) {\n  endElementHandler = end;\n}\n\nvoid XMLCALL\nXML_SetCharacterDataHandler(XML_Parser parser,\n                            XML_CharacterDataHandler handler)\n{\n  characterDataHandler = handler;\n}\n\nvoid XMLCALL\nXML_SetProcessingInstructionHandler(XML_Parser parser,\n                                    XML_ProcessingInstructionHandler handler)\n{\n  processingInstructionHandler = handler;\n}\n\nvoid XMLCALL\nXML_SetCommentHandler(XML_Parser parser,\n                      XML_CommentHandler handler)\n{\n  commentHandler = handler;\n}\n\nvoid XMLCALL\nXML_SetCdataSectionHandler(XML_Parser parser,\n                           XML_StartCdataSectionHandler start,\n                           XML_EndCdataSectionHandler end)\n{\n  startCdataSectionHandler = start;\n  endCdataSectionHandler = end;\n}\n\nvoid XMLCALL\nXML_SetStartCdataSectionHandler(XML_Parser parser,\n                                XML_StartCdataSectionHandler start) {\n  startCdataSectionHandler = start;\n}\n\nvoid XMLCALL\nXML_SetEndCdataSectionHandler(XML_Parser parser,\n                              XML_EndCdataSectionHandler end) {\n  endCdataSectionHandler = end;\n}\n\nvoid XMLCALL\nXML_SetDefaultHandler(XML_Parser parser,\n                      XML_DefaultHandler handler)\n{\n  defaultHandler = handler;\n  defaultExpandInternalEntities = XML_FALSE;\n}\n\nvoid XMLCALL\nXML_SetDefaultHandlerExpand(XML_Parser parser,\n                            XML_DefaultHandler handler)\n{\n  defaultHandler = handler;\n  defaultExpandInternalEntities = XML_TRUE;\n}\n\nvoid XMLCALL\nXML_SetDoctypeDeclHandler(XML_Parser parser,\n                          XML_StartDoctypeDeclHandler start,\n                          XML_EndDoctypeDeclHandler end)\n{\n  startDoctypeDeclHandler = start;\n  endDoctypeDeclHandler = end;\n}\n\nvoid XMLCALL\nXML_SetStartDoctypeDeclHandler(XML_Parser parser,\n                               XML_StartDoctypeDeclHandler start) {\n  startDoctypeDeclHandler = start;\n}\n\nvoid XMLCALL\nXML_SetEndDoctypeDeclHandler(XML_Parser parser,\n                             XML_EndDoctypeDeclHandler end) {\n  endDoctypeDeclHandler = end;\n}\n\nvoid XMLCALL\nXML_SetUnparsedEntityDeclHandler(XML_Parser parser,\n                                 XML_UnparsedEntityDeclHandler handler)\n{\n  unparsedEntityDeclHandler = handler;\n}\n\nvoid XMLCALL\nXML_SetNotationDeclHandler(XML_Parser parser,\n                           XML_NotationDeclHandler handler)\n{\n  notationDeclHandler = handler;\n}\n\nvoid XMLCALL\nXML_SetNamespaceDeclHandler(XML_Parser parser,\n                            XML_StartNamespaceDeclHandler start,\n                            XML_EndNamespaceDeclHandler end)\n{\n  startNamespaceDeclHandler = start;\n  endNamespaceDeclHandler = end;\n}\n\nvoid XMLCALL\nXML_SetStartNamespaceDeclHandler(XML_Parser parser,\n                                 XML_StartNamespaceDeclHandler start) {\n  startNamespaceDeclHandler = start;\n}\n\nvoid XMLCALL\nXML_SetEndNamespaceDeclHandler(XML_Parser parser,\n                               XML_EndNamespaceDeclHandler end) {\n  endNamespaceDeclHandler = end;\n}\n\nvoid XMLCALL\nXML_SetNotStandaloneHandler(XML_Parser parser,\n                            XML_NotStandaloneHandler handler)\n{\n  notStandaloneHandler = handler;\n}\n\nvoid XMLCALL\nXML_SetExternalEntityRefHandler(XML_Parser parser,\n                                XML_ExternalEntityRefHandler handler)\n{\n  externalEntityRefHandler = handler;\n}\n\nvoid XMLCALL\nXML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)\n{\n  if (arg)\n    externalEntityRefHandlerArg = (XML_Parser)arg;\n  else\n    externalEntityRefHandlerArg = parser;\n}\n\nvoid XMLCALL\nXML_SetSkippedEntityHandler(XML_Parser parser,\n                            XML_SkippedEntityHandler handler)\n{\n  skippedEntityHandler = handler;\n}\n\nvoid XMLCALL\nXML_SetUnknownEncodingHandler(XML_Parser parser,\n                              XML_UnknownEncodingHandler handler,\n                              void *data)\n{\n  unknownEncodingHandler = handler;\n  unknownEncodingHandlerData = data;\n}\n\nvoid XMLCALL\nXML_SetElementDeclHandler(XML_Parser parser,\n                          XML_ElementDeclHandler eldecl)\n{\n  elementDeclHandler = eldecl;\n}\n\nvoid XMLCALL\nXML_SetAttlistDeclHandler(XML_Parser parser,\n                          XML_AttlistDeclHandler attdecl)\n{\n  attlistDeclHandler = attdecl;\n}\n\nvoid XMLCALL\nXML_SetEntityDeclHandler(XML_Parser parser,\n                         XML_EntityDeclHandler handler)\n{\n  entityDeclHandler = handler;\n}\n\nvoid XMLCALL\nXML_SetXmlDeclHandler(XML_Parser parser,\n                      XML_XmlDeclHandler handler) {\n  xmlDeclHandler = handler;\n}\n\nint XMLCALL\nXML_SetParamEntityParsing(XML_Parser parser,\n                          enum XML_ParamEntityParsing peParsing)\n{\n  /* block after XML_Parse()/XML_ParseBuffer() has been called */\n  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)\n    return 0;\n#ifdef XML_DTD\n  paramEntityParsing = peParsing;\n  return 1;\n#else\n  return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;\n#endif\n}\n\nint XMLCALL\nXML_SetHashSalt(XML_Parser parser,\n                unsigned long hash_salt)\n{\n  /* block after XML_Parse()/XML_ParseBuffer() has been called */\n  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)\n    return 0;\n  hash_secret_salt = hash_salt;\n  return 1;\n}\n\nenum XML_Status XMLCALL\nXML_Parse(XML_Parser parser, const char *s, int len, int isFinal)\n{\n  switch (ps_parsing) {\n  case XML_SUSPENDED:\n    errorCode = XML_ERROR_SUSPENDED;\n    return XML_STATUS_ERROR;\n  case XML_FINISHED:\n    errorCode = XML_ERROR_FINISHED;\n    return XML_STATUS_ERROR;\n  case XML_INITIALIZED:\n    if (parentParser == NULL && !startParsing(parser)) {\n      errorCode = XML_ERROR_NO_MEMORY;\n      return XML_STATUS_ERROR;\n    }\n  default:\n    ps_parsing = XML_PARSING;\n  }\n\n  if (len == 0) {\n    ps_finalBuffer = (XML_Bool)isFinal;\n    if (!isFinal)\n      return XML_STATUS_OK;\n    positionPtr = bufferPtr;\n    parseEndPtr = bufferEnd;\n\n    /* If data are left over from last buffer, and we now know that these\n       data are the final chunk of input, then we have to check them again\n       to detect errors based on that fact.\n    */\n    errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);\n\n    if (errorCode == XML_ERROR_NONE) {\n      switch (ps_parsing) {\n      case XML_SUSPENDED:\n        XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);\n        positionPtr = bufferPtr;\n        return XML_STATUS_SUSPENDED;\n      case XML_INITIALIZED:\n      case XML_PARSING:\n        ps_parsing = XML_FINISHED;\n        /* fall through */\n      default:\n        return XML_STATUS_OK;\n      }\n    }\n    eventEndPtr = eventPtr;\n    processor = errorProcessor;\n    return XML_STATUS_ERROR;\n  }\n#ifndef XML_CONTEXT_BYTES\n  else if (bufferPtr == bufferEnd) {\n    const char *end;\n    int nLeftOver;\n    enum XML_Status result;\n    parseEndByteIndex += len;\n    positionPtr = s;\n    ps_finalBuffer = (XML_Bool)isFinal;\n\n    errorCode = processor(parser, s, parseEndPtr = s + len, &end);\n\n    if (errorCode != XML_ERROR_NONE) {\n      eventEndPtr = eventPtr;\n      processor = errorProcessor;\n      return XML_STATUS_ERROR;\n    }\n    else {\n      switch (ps_parsing) {\n      case XML_SUSPENDED:\n        result = XML_STATUS_SUSPENDED;\n        break;\n      case XML_INITIALIZED:\n      case XML_PARSING:\n        if (isFinal) {\n          ps_parsing = XML_FINISHED;\n          return XML_STATUS_OK;\n        }\n      /* fall through */\n      default:\n        result = XML_STATUS_OK;\n      }\n    }\n\n    XmlUpdatePosition(encoding, positionPtr, end, &position);\n    nLeftOver = s + len - end;\n    if (nLeftOver) {\n      if (buffer == NULL || nLeftOver > bufferLim - buffer) {\n        /* FIXME avoid integer overflow */\n        char *temp;\n        temp = (buffer == NULL\n                ? (char *)MALLOC(len * 2)\n                : (char *)REALLOC(buffer, len * 2));\n        if (temp == NULL) {\n          errorCode = XML_ERROR_NO_MEMORY;\n          eventPtr = eventEndPtr = NULL;\n          processor = errorProcessor;\n          return XML_STATUS_ERROR;\n        }\n        buffer = temp;\n        bufferLim = buffer + len * 2;\n      }\n      memcpy(buffer, end, nLeftOver);\n    }\n    bufferPtr = buffer;\n    bufferEnd = buffer + nLeftOver;\n    positionPtr = bufferPtr;\n    parseEndPtr = bufferEnd;\n    eventPtr = bufferPtr;\n    eventEndPtr = bufferPtr;\n    return result;\n  }\n#endif  /* not defined XML_CONTEXT_BYTES */\n  else {\n    void *buff = XML_GetBuffer(parser, len);\n    if (buff == NULL)\n      return XML_STATUS_ERROR;\n    else {\n      memcpy(buff, s, len);\n      return XML_ParseBuffer(parser, len, isFinal);\n    }\n  }\n}\n\nenum XML_Status XMLCALL\nXML_ParseBuffer(XML_Parser parser, int len, int isFinal)\n{\n  const char *start;\n  enum XML_Status result = XML_STATUS_OK;\n\n  switch (ps_parsing) {\n  case XML_SUSPENDED:\n    errorCode = XML_ERROR_SUSPENDED;\n    return XML_STATUS_ERROR;\n  case XML_FINISHED:\n    errorCode = XML_ERROR_FINISHED;\n    return XML_STATUS_ERROR;\n  case XML_INITIALIZED:\n    if (parentParser == NULL && !startParsing(parser)) {\n      errorCode = XML_ERROR_NO_MEMORY;\n      return XML_STATUS_ERROR;\n    }\n  default:\n    ps_parsing = XML_PARSING;\n  }\n\n  start = bufferPtr;\n  positionPtr = start;\n  bufferEnd += len;\n  parseEndPtr = bufferEnd;\n  parseEndByteIndex += len;\n  ps_finalBuffer = (XML_Bool)isFinal;\n\n  errorCode = processor(parser, start, parseEndPtr, &bufferPtr);\n\n  if (errorCode != XML_ERROR_NONE) {\n    eventEndPtr = eventPtr;\n    processor = errorProcessor;\n    return XML_STATUS_ERROR;\n  }\n  else {\n    switch (ps_parsing) {\n    case XML_SUSPENDED:\n      result = XML_STATUS_SUSPENDED;\n      break;\n    case XML_INITIALIZED:\n    case XML_PARSING:\n      if (isFinal) {\n        ps_parsing = XML_FINISHED;\n        return result;\n      }\n    default: ;  /* should not happen */\n    }\n  }\n\n  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);\n  positionPtr = bufferPtr;\n  return result;\n}\n\nvoid * XMLCALL\nXML_GetBuffer(XML_Parser parser, int len)\n{\n  if (len < 0) {\n    errorCode = XML_ERROR_NO_MEMORY;\n    return NULL;\n  }\n  switch (ps_parsing) {\n  case XML_SUSPENDED:\n    errorCode = XML_ERROR_SUSPENDED;\n    return NULL;\n  case XML_FINISHED:\n    errorCode = XML_ERROR_FINISHED;\n    return NULL;\n  default: ;\n  }\n\n  if (len > bufferLim - bufferEnd) {\n    int neededSize = len + (int)(bufferEnd - bufferPtr);\n    if (neededSize < 0) {\n      errorCode = XML_ERROR_NO_MEMORY;\n      return NULL;\n    }\n#ifdef XML_CONTEXT_BYTES\n    int keep = (int)(bufferPtr - buffer);\n\n    if (keep > XML_CONTEXT_BYTES)\n      keep = XML_CONTEXT_BYTES;\n    neededSize += keep;\n#endif  /* defined XML_CONTEXT_BYTES */\n    if (neededSize  <= bufferLim - buffer) {\n#ifdef XML_CONTEXT_BYTES\n      if (keep < bufferPtr - buffer) {\n        int offset = (int)(bufferPtr - buffer) - keep;\n        memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);\n        bufferEnd -= offset;\n        bufferPtr -= offset;\n      }\n#else\n      memmove(buffer, bufferPtr, bufferEnd - bufferPtr);\n      bufferEnd = buffer + (bufferEnd - bufferPtr);\n      bufferPtr = buffer;\n#endif  /* not defined XML_CONTEXT_BYTES */\n    }\n    else {\n      char *newBuf;\n      int bufferSize = (int)(bufferLim - bufferPtr);\n      if (bufferSize == 0)\n        bufferSize = INIT_BUFFER_SIZE;\n      do {\n        bufferSize *= 2;\n      } while (bufferSize < neededSize && bufferSize > 0);\n      if (bufferSize <= 0) {\n        errorCode = XML_ERROR_NO_MEMORY;\n        return NULL;\n      }\n      newBuf = (char *)MALLOC(bufferSize);\n      if (newBuf == 0) {\n        errorCode = XML_ERROR_NO_MEMORY;\n        return NULL;\n      }\n      bufferLim = newBuf + bufferSize;\n#ifdef XML_CONTEXT_BYTES\n      if (bufferPtr) {\n        int keep = (int)(bufferPtr - buffer);\n        if (keep > XML_CONTEXT_BYTES)\n          keep = XML_CONTEXT_BYTES;\n        memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);\n        FREE(buffer);\n        buffer = newBuf;\n        bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;\n        bufferPtr = buffer + keep;\n      }\n      else {\n        bufferEnd = newBuf + (bufferEnd - bufferPtr);\n        bufferPtr = buffer = newBuf;\n      }\n#else\n      if (bufferPtr) {\n        memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);\n        FREE(buffer);\n      }\n      bufferEnd = newBuf + (bufferEnd - bufferPtr);\n      bufferPtr = buffer = newBuf;\n#endif  /* not defined XML_CONTEXT_BYTES */\n    }\n    eventPtr = eventEndPtr = NULL;\n    positionPtr = NULL;\n  }\n  return bufferEnd;\n}\n\nenum XML_Status XMLCALL\nXML_StopParser(XML_Parser parser, XML_Bool resumable)\n{\n  switch (ps_parsing) {\n  case XML_SUSPENDED:\n    if (resumable) {\n      errorCode = XML_ERROR_SUSPENDED;\n      return XML_STATUS_ERROR;\n    }\n    ps_parsing = XML_FINISHED;\n    break;\n  case XML_FINISHED:\n    errorCode = XML_ERROR_FINISHED;\n    return XML_STATUS_ERROR;\n  default:\n    if (resumable) {\n#ifdef XML_DTD\n      if (isParamEntity) {\n        errorCode = XML_ERROR_SUSPEND_PE;\n        return XML_STATUS_ERROR;\n      }\n#endif\n      ps_parsing = XML_SUSPENDED;\n    }\n    else\n      ps_parsing = XML_FINISHED;\n  }\n  return XML_STATUS_OK;\n}\n\nenum XML_Status XMLCALL\nXML_ResumeParser(XML_Parser parser)\n{\n  enum XML_Status result = XML_STATUS_OK;\n\n  if (ps_parsing != XML_SUSPENDED) {\n    errorCode = XML_ERROR_NOT_SUSPENDED;\n    return XML_STATUS_ERROR;\n  }\n  ps_parsing = XML_PARSING;\n\n  errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);\n\n  if (errorCode != XML_ERROR_NONE) {\n    eventEndPtr = eventPtr;\n    processor = errorProcessor;\n    return XML_STATUS_ERROR;\n  }\n  else {\n    switch (ps_parsing) {\n    case XML_SUSPENDED:\n      result = XML_STATUS_SUSPENDED;\n      break;\n    case XML_INITIALIZED:\n    case XML_PARSING:\n      if (ps_finalBuffer) {\n        ps_parsing = XML_FINISHED;\n        return result;\n      }\n    default: ;\n    }\n  }\n\n  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);\n  positionPtr = bufferPtr;\n  return result;\n}\n\nvoid XMLCALL\nXML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)\n{\n  assert(status != NULL);\n  *status = parser->m_parsingStatus;\n}\n\nenum XML_Error XMLCALL\nXML_GetErrorCode(XML_Parser parser)\n{\n  return errorCode;\n}\n\nXML_Index XMLCALL\nXML_GetCurrentByteIndex(XML_Parser parser)\n{\n  if (eventPtr)\n    return parseEndByteIndex - (parseEndPtr - eventPtr);\n  return -1;\n}\n\nint XMLCALL\nXML_GetCurrentByteCount(XML_Parser parser)\n{\n  if (eventEndPtr && eventPtr)\n    return (int)(eventEndPtr - eventPtr);\n  return 0;\n}\n\nconst char * XMLCALL\nXML_GetInputContext(XML_Parser parser, int *offset, int *size)\n{\n#ifdef XML_CONTEXT_BYTES\n  if (eventPtr && buffer) {\n    *offset = (int)(eventPtr - buffer);\n    *size   = (int)(bufferEnd - buffer);\n    return buffer;\n  }\n#endif /* defined XML_CONTEXT_BYTES */\n  return (char *) 0;\n}\n\nXML_Size XMLCALL\nXML_GetCurrentLineNumber(XML_Parser parser)\n{\n  if (eventPtr && eventPtr >= positionPtr) {\n    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);\n    positionPtr = eventPtr;\n  }\n  return position.lineNumber + 1;\n}\n\nXML_Size XMLCALL\nXML_GetCurrentColumnNumber(XML_Parser parser)\n{\n  if (eventPtr && eventPtr >= positionPtr) {\n    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);\n    positionPtr = eventPtr;\n  }\n  return position.columnNumber;\n}\n\nvoid XMLCALL\nXML_FreeContentModel(XML_Parser parser, XML_Content *model)\n{\n  FREE(model);\n}\n\nvoid * XMLCALL\nXML_MemMalloc(XML_Parser parser, size_t size)\n{\n  return MALLOC(size);\n}\n\nvoid * XMLCALL\nXML_MemRealloc(XML_Parser parser, void *ptr, size_t size)\n{\n  return REALLOC(ptr, size);\n}\n\nvoid XMLCALL\nXML_MemFree(XML_Parser parser, void *ptr)\n{\n  FREE(ptr);\n}\n\nvoid XMLCALL\nXML_DefaultCurrent(XML_Parser parser)\n{\n  if (defaultHandler) {\n    if (openInternalEntities)\n      reportDefault(parser,\n                    internalEncoding,\n                    openInternalEntities->internalEventPtr,\n                    openInternalEntities->internalEventEndPtr);\n    else\n      reportDefault(parser, encoding, eventPtr, eventEndPtr);\n  }\n}\n\nconst XML_LChar * XMLCALL\nXML_ErrorString(enum XML_Error code)\n{\n  static const XML_LChar* const message[] = {\n    0,\n    XML_L(\"out of memory\"),\n    XML_L(\"syntax error\"),\n    XML_L(\"no element found\"),\n    XML_L(\"not well-formed (invalid token)\"),\n    XML_L(\"unclosed token\"),\n    XML_L(\"partial character\"),\n    XML_L(\"mismatched tag\"),\n    XML_L(\"duplicate attribute\"),\n    XML_L(\"junk after document element\"),\n    XML_L(\"illegal parameter entity reference\"),\n    XML_L(\"undefined entity\"),\n    XML_L(\"recursive entity reference\"),\n    XML_L(\"asynchronous entity\"),\n    XML_L(\"reference to invalid character number\"),\n    XML_L(\"reference to binary entity\"),\n    XML_L(\"reference to external entity in attribute\"),\n    XML_L(\"XML or text declaration not at start of entity\"),\n    XML_L(\"unknown encoding\"),\n    XML_L(\"encoding specified in XML declaration is incorrect\"),\n    XML_L(\"unclosed CDATA section\"),\n    XML_L(\"error in processing external entity reference\"),\n    XML_L(\"document is not standalone\"),\n    XML_L(\"unexpected parser state - please send a bug report\"),\n    XML_L(\"entity declared in parameter entity\"),\n    XML_L(\"requested feature requires XML_DTD support in Expat\"),\n    XML_L(\"cannot change setting once parsing has begun\"),\n    XML_L(\"unbound prefix\"),\n    XML_L(\"must not undeclare prefix\"),\n    XML_L(\"incomplete markup in parameter entity\"),\n    XML_L(\"XML declaration not well-formed\"),\n    XML_L(\"text declaration not well-formed\"),\n    XML_L(\"illegal character(s) in public id\"),\n    XML_L(\"parser suspended\"),\n    XML_L(\"parser not suspended\"),\n    XML_L(\"parsing aborted\"),\n    XML_L(\"parsing finished\"),\n    XML_L(\"cannot suspend in external parameter entity\"),\n    XML_L(\"reserved prefix (xml) must not be undeclared or bound to another namespace name\"),\n    XML_L(\"reserved prefix (xmlns) must not be declared or undeclared\"),\n    XML_L(\"prefix must not be bound to one of the reserved namespace names\")\n  };\n  if (code > 0 && code < sizeof(message)/sizeof(message[0]))\n    return message[code];\n  return NULL;\n}\n\nconst XML_LChar * XMLCALL\nXML_ExpatVersion(void) {\n\n  /* V1 is used to string-ize the version number. However, it would\n     string-ize the actual version macro *names* unless we get them\n     substituted before being passed to V1. CPP is defined to expand\n     a macro, then rescan for more expansions. Thus, we use V2 to expand\n     the version macros, then CPP will expand the resulting V1() macro\n     with the correct numerals. */\n  /* ### I'm assuming cpp is portable in this respect... */\n\n#define V1(a,b,c) XML_L(#a)XML_L(\".\")XML_L(#b)XML_L(\".\")XML_L(#c)\n#define V2(a,b,c) XML_L(\"expat_\")V1(a,b,c)\n\n  return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);\n\n#undef V1\n#undef V2\n}\n\nXML_Expat_Version XMLCALL\nXML_ExpatVersionInfo(void)\n{\n  XML_Expat_Version version;\n\n  version.major = XML_MAJOR_VERSION;\n  version.minor = XML_MINOR_VERSION;\n  version.micro = XML_MICRO_VERSION;\n\n  return version;\n}\n\nconst XML_Feature * XMLCALL\nXML_GetFeatureList(void)\n{\n  static const XML_Feature features[] = {\n    {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L(\"sizeof(XML_Char)\"),\n     sizeof(XML_Char)},\n    {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L(\"sizeof(XML_LChar)\"),\n     sizeof(XML_LChar)},\n#ifdef XML_UNICODE\n    {XML_FEATURE_UNICODE,          XML_L(\"XML_UNICODE\"), 0},\n#endif\n#ifdef XML_UNICODE_WCHAR_T\n    {XML_FEATURE_UNICODE_WCHAR_T,  XML_L(\"XML_UNICODE_WCHAR_T\"), 0},\n#endif\n#ifdef XML_DTD\n    {XML_FEATURE_DTD,              XML_L(\"XML_DTD\"), 0},\n#endif\n#ifdef XML_CONTEXT_BYTES\n    {XML_FEATURE_CONTEXT_BYTES,    XML_L(\"XML_CONTEXT_BYTES\"),\n     XML_CONTEXT_BYTES},\n#endif\n#ifdef XML_MIN_SIZE\n    {XML_FEATURE_MIN_SIZE,         XML_L(\"XML_MIN_SIZE\"), 0},\n#endif\n#ifdef XML_NS\n    {XML_FEATURE_NS,               XML_L(\"XML_NS\"), 0},\n#endif\n#ifdef XML_LARGE_SIZE\n    {XML_FEATURE_LARGE_SIZE,       XML_L(\"XML_LARGE_SIZE\"), 0},\n#endif\n#ifdef XML_ATTR_INFO\n    {XML_FEATURE_ATTR_INFO,        XML_L(\"XML_ATTR_INFO\"), 0},\n#endif\n    {XML_FEATURE_END,              NULL, 0}\n  };\n\n  return features;\n}\n\n/* Initially tag->rawName always points into the parse buffer;\n   for those TAG instances opened while the current parse buffer was\n   processed, and not yet closed, we need to store tag->rawName in a more\n   permanent location, since the parse buffer is about to be discarded.\n*/\nstatic XML_Bool\nstoreRawNames(XML_Parser parser)\n{\n  TAG *tag = tagStack;\n  while (tag) {\n    int bufSize;\n    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);\n    char *rawNameBuf = tag->buf + nameLen;\n    /* Stop if already stored.  Since tagStack is a stack, we can stop\n       at the first entry that has already been copied; everything\n       below it in the stack is already been accounted for in a\n       previous call to this function.\n    */\n    if (tag->rawName == rawNameBuf)\n      break;\n    /* For re-use purposes we need to ensure that the\n       size of tag->buf is a multiple of sizeof(XML_Char).\n    */\n    bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));\n    if (bufSize > tag->bufEnd - tag->buf) {\n      char *temp = (char *)REALLOC(tag->buf, bufSize);\n      if (temp == NULL)\n        return XML_FALSE;\n      /* if tag->name.str points to tag->buf (only when namespace\n         processing is off) then we have to update it\n      */\n      if (tag->name.str == (XML_Char *)tag->buf)\n        tag->name.str = (XML_Char *)temp;\n      /* if tag->name.localPart is set (when namespace processing is on)\n         then update it as well, since it will always point into tag->buf\n      */\n      if (tag->name.localPart)\n        tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -\n                                                  (XML_Char *)tag->buf);\n      tag->buf = temp;\n      tag->bufEnd = temp + bufSize;\n      rawNameBuf = temp + nameLen;\n    }\n    memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);\n    tag->rawName = rawNameBuf;\n    tag = tag->parent;\n  }\n  return XML_TRUE;\n}\n\nstatic enum XML_Error PTRCALL\ncontentProcessor(XML_Parser parser,\n                 const char *start,\n                 const char *end,\n                 const char **endPtr)\n{\n  enum XML_Error result = doContent(parser, 0, encoding, start, end,\n                                    endPtr, (XML_Bool)!ps_finalBuffer);\n  if (result == XML_ERROR_NONE) {\n    if (!storeRawNames(parser))\n      return XML_ERROR_NO_MEMORY;\n  }\n  return result;\n}\n\nstatic enum XML_Error PTRCALL\nexternalEntityInitProcessor(XML_Parser parser,\n                            const char *start,\n                            const char *end,\n                            const char **endPtr)\n{\n  enum XML_Error result = initializeEncoding(parser);\n  if (result != XML_ERROR_NONE)\n    return result;\n  processor = externalEntityInitProcessor2;\n  return externalEntityInitProcessor2(parser, start, end, endPtr);\n}\n\nstatic enum XML_Error PTRCALL\nexternalEntityInitProcessor2(XML_Parser parser,\n                             const char *start,\n                             const char *end,\n                             const char **endPtr)\n{\n  const char *next = start; /* XmlContentTok doesn't always set the last arg */\n  int tok = XmlContentTok(encoding, start, end, &next);\n  switch (tok) {\n  case XML_TOK_BOM:\n    /* If we are at the end of the buffer, this would cause the next stage,\n       i.e. externalEntityInitProcessor3, to pass control directly to\n       doContent (by detecting XML_TOK_NONE) without processing any xml text\n       declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.\n    */\n    if (next == end && !ps_finalBuffer) {\n      *endPtr = next;\n      return XML_ERROR_NONE;\n    }\n    start = next;\n    break;\n  case XML_TOK_PARTIAL:\n    if (!ps_finalBuffer) {\n      *endPtr = start;\n      return XML_ERROR_NONE;\n    }\n    eventPtr = start;\n    return XML_ERROR_UNCLOSED_TOKEN;\n  case XML_TOK_PARTIAL_CHAR:\n    if (!ps_finalBuffer) {\n      *endPtr = start;\n      return XML_ERROR_NONE;\n    }\n    eventPtr = start;\n    return XML_ERROR_PARTIAL_CHAR;\n  }\n  processor = externalEntityInitProcessor3;\n  return externalEntityInitProcessor3(parser, start, end, endPtr);\n}\n\nstatic enum XML_Error PTRCALL\nexternalEntityInitProcessor3(XML_Parser parser,\n                             const char *start,\n                             const char *end,\n                             const char **endPtr)\n{\n  int tok;\n  const char *next = start; /* XmlContentTok doesn't always set the last arg */\n  eventPtr = start;\n  tok = XmlContentTok(encoding, start, end, &next);\n  eventEndPtr = next;\n\n  switch (tok) {\n  case XML_TOK_XML_DECL:\n    {\n      enum XML_Error result;\n      result = processXmlDecl(parser, 1, start, next);\n      if (result != XML_ERROR_NONE)\n        return result;\n      switch (ps_parsing) {\n      case XML_SUSPENDED:\n        *endPtr = next;\n        return XML_ERROR_NONE;\n      case XML_FINISHED:\n        return XML_ERROR_ABORTED;\n      default:\n        start = next;\n      }\n    }\n    break;\n  case XML_TOK_PARTIAL:\n    if (!ps_finalBuffer) {\n      *endPtr = start;\n      return XML_ERROR_NONE;\n    }\n    return XML_ERROR_UNCLOSED_TOKEN;\n  case XML_TOK_PARTIAL_CHAR:\n    if (!ps_finalBuffer) {\n      *endPtr = start;\n      return XML_ERROR_NONE;\n    }\n    return XML_ERROR_PARTIAL_CHAR;\n  }\n  processor = externalEntityContentProcessor;\n  tagLevel = 1;\n  return externalEntityContentProcessor(parser, start, end, endPtr);\n}\n\nstatic enum XML_Error PTRCALL\nexternalEntityContentProcessor(XML_Parser parser,\n                               const char *start,\n                               const char *end,\n                               const char **endPtr)\n{\n  enum XML_Error result = doContent(parser, 1, encoding, start, end,\n                                    endPtr, (XML_Bool)!ps_finalBuffer);\n  if (result == XML_ERROR_NONE) {\n    if (!storeRawNames(parser))\n      return XML_ERROR_NO_MEMORY;\n  }\n  return result;\n}\n\nstatic enum XML_Error\ndoContent(XML_Parser parser,\n          int startTagLevel,\n          const ENCODING *enc,\n          const char *s,\n          const char *end,\n          const char **nextPtr,\n          XML_Bool haveMore)\n{\n  /* save one level of indirection */\n  DTD * const dtd = _dtd;\n\n  const char **eventPP;\n  const char **eventEndPP;\n  if (enc == encoding) {\n    eventPP = &eventPtr;\n    eventEndPP = &eventEndPtr;\n  }\n  else {\n    eventPP = &(openInternalEntities->internalEventPtr);\n    eventEndPP = &(openInternalEntities->internalEventEndPtr);\n  }\n  *eventPP = s;\n\n  for (;;) {\n    const char *next = s; /* XmlContentTok doesn't always set the last arg */\n    int tok = XmlContentTok(enc, s, end, &next);\n    *eventEndPP = next;\n    switch (tok) {\n    case XML_TOK_TRAILING_CR:\n      if (haveMore) {\n        *nextPtr = s;\n        return XML_ERROR_NONE;\n      }\n      *eventEndPP = end;\n      if (characterDataHandler) {\n        XML_Char c = 0xA;\n        characterDataHandler(handlerArg, &c, 1);\n      }\n      else if (defaultHandler)\n        reportDefault(parser, enc, s, end);\n      /* We are at the end of the final buffer, should we check for\n         XML_SUSPENDED, XML_FINISHED?\n      */\n      if (startTagLevel == 0)\n        return XML_ERROR_NO_ELEMENTS;\n      if (tagLevel != startTagLevel)\n        return XML_ERROR_ASYNC_ENTITY;\n      *nextPtr = end;\n      return XML_ERROR_NONE;\n    case XML_TOK_NONE:\n      if (haveMore) {\n        *nextPtr = s;\n        return XML_ERROR_NONE;\n      }\n      if (startTagLevel > 0) {\n        if (tagLevel != startTagLevel)\n          return XML_ERROR_ASYNC_ENTITY;\n        *nextPtr = s;\n        return XML_ERROR_NONE;\n      }\n      return XML_ERROR_NO_ELEMENTS;\n    case XML_TOK_INVALID:\n      *eventPP = next;\n      return XML_ERROR_INVALID_TOKEN;\n    case XML_TOK_PARTIAL:\n      if (haveMore) {\n        *nextPtr = s;\n        return XML_ERROR_NONE;\n      }\n      return XML_ERROR_UNCLOSED_TOKEN;\n    case XML_TOK_PARTIAL_CHAR:\n      if (haveMore) {\n        *nextPtr = s;\n        return XML_ERROR_NONE;\n      }\n      return XML_ERROR_PARTIAL_CHAR;\n    case XML_TOK_ENTITY_REF:\n      {\n        const XML_Char *name;\n        ENTITY *entity;\n        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,\n                                              s + enc->minBytesPerChar,\n                                              next - enc->minBytesPerChar);\n        if (ch) {\n          if (characterDataHandler)\n            characterDataHandler(handlerArg, &ch, 1);\n          else if (defaultHandler)\n            reportDefault(parser, enc, s, next);\n          break;\n        }\n        name = poolStoreString(&dtd->pool, enc,\n                                s + enc->minBytesPerChar,\n                                next - enc->minBytesPerChar);\n        if (!name)\n          return XML_ERROR_NO_MEMORY;\n        entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);\n        poolDiscard(&dtd->pool);\n        /* First, determine if a check for an existing declaration is needed;\n           if yes, check that the entity exists, and that it is internal,\n           otherwise call the skipped entity or default handler.\n        */\n        if (!dtd->hasParamEntityRefs || dtd->standalone) {\n          if (!entity)\n            return XML_ERROR_UNDEFINED_ENTITY;\n          else if (!entity->is_internal)\n            return XML_ERROR_ENTITY_DECLARED_IN_PE;\n        }\n        else if (!entity) {\n          if (skippedEntityHandler)\n            skippedEntityHandler(handlerArg, name, 0);\n          else if (defaultHandler)\n            reportDefault(parser, enc, s, next);\n          break;\n        }\n        if (entity->open)\n          return XML_ERROR_RECURSIVE_ENTITY_REF;\n        if (entity->notation)\n          return XML_ERROR_BINARY_ENTITY_REF;\n        if (entity->textPtr) {\n          enum XML_Error result;\n          if (!defaultExpandInternalEntities) {\n            if (skippedEntityHandler)\n              skippedEntityHandler(handlerArg, entity->name, 0);\n            else if (defaultHandler)\n              reportDefault(parser, enc, s, next);\n            break;\n          }\n          result = processInternalEntity(parser, entity, XML_FALSE);\n          if (result != XML_ERROR_NONE)\n            return result;\n        }\n        else if (externalEntityRefHandler) {\n          const XML_Char *context;\n          entity->open = XML_TRUE;\n          context = getContext(parser);\n          entity->open = XML_FALSE;\n          if (!context)\n            return XML_ERROR_NO_MEMORY;\n          if (!externalEntityRefHandler(externalEntityRefHandlerArg,\n                                        context,\n                                        entity->base,\n                                        entity->systemId,\n                                        entity->publicId))\n            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;\n          poolDiscard(&tempPool);\n        }\n        else if (defaultHandler)\n          reportDefault(parser, enc, s, next);\n        break;\n      }\n    case XML_TOK_START_TAG_NO_ATTS:\n      /* fall through */\n    case XML_TOK_START_TAG_WITH_ATTS:\n      {\n        TAG *tag;\n        enum XML_Error result;\n        XML_Char *toPtr;\n        if (freeTagList) {\n          tag = freeTagList;\n          freeTagList = freeTagList->parent;\n        }\n        else {\n          tag = (TAG *)MALLOC(sizeof(TAG));\n          if (!tag)\n            return XML_ERROR_NO_MEMORY;\n          tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);\n          if (!tag->buf) {\n            FREE(tag);\n            return XML_ERROR_NO_MEMORY;\n          }\n          tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;\n        }\n        tag->bindings = NULL;\n        tag->parent = tagStack;\n        tagStack = tag;\n        tag->name.localPart = NULL;\n        tag->name.prefix = NULL;\n        tag->rawName = s + enc->minBytesPerChar;\n        tag->rawNameLength = XmlNameLength(enc, tag->rawName);\n        ++tagLevel;\n        {\n          const char *rawNameEnd = tag->rawName + tag->rawNameLength;\n          const char *fromPtr = tag->rawName;\n          toPtr = (XML_Char *)tag->buf;\n          for (;;) {\n            int bufSize;\n            int convLen;\n            const enum XML_Convert_Result convert_res = XmlConvert(enc,\n                       &fromPtr, rawNameEnd,\n                       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);\n            convLen = (int)(toPtr - (XML_Char *)tag->buf);\n            if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {\n              tag->name.strLen = convLen;\n              break;\n            }\n            bufSize = (int)(tag->bufEnd - tag->buf) << 1;\n            {\n              char *temp = (char *)REALLOC(tag->buf, bufSize);\n              if (temp == NULL)\n                return XML_ERROR_NO_MEMORY;\n              tag->buf = temp;\n              tag->bufEnd = temp + bufSize;\n              toPtr = (XML_Char *)temp + convLen;\n            }\n          }\n        }\n        tag->name.str = (XML_Char *)tag->buf;\n        *toPtr = XML_T('\\0');\n        result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));\n        if (result)\n          return result;\n        if (startElementHandler)\n          startElementHandler(handlerArg, tag->name.str,\n                              (const XML_Char **)atts);\n        else if (defaultHandler)\n          reportDefault(parser, enc, s, next);\n        poolClear(&tempPool);\n        break;\n      }\n    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:\n      /* fall through */\n    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:\n      {\n        const char *rawName = s + enc->minBytesPerChar;\n        enum XML_Error result;\n        BINDING *bindings = NULL;\n        XML_Bool noElmHandlers = XML_TRUE;\n        TAG_NAME name;\n        name.str = poolStoreString(&tempPool, enc, rawName,\n                                   rawName + XmlNameLength(enc, rawName));\n        if (!name.str)\n          return XML_ERROR_NO_MEMORY;\n        poolFinish(&tempPool);\n        result = storeAtts(parser, enc, s, &name, &bindings);\n        if (result)\n          return result;\n        poolFinish(&tempPool);\n        if (startElementHandler) {\n          startElementHandler(handlerArg, name.str, (const XML_Char **)atts);\n          noElmHandlers = XML_FALSE;\n        }\n        if (endElementHandler) {\n          if (startElementHandler)\n            *eventPP = *eventEndPP;\n          endElementHandler(handlerArg, name.str);\n          noElmHandlers = XML_FALSE;\n        }\n        if (noElmHandlers && defaultHandler)\n          reportDefault(parser, enc, s, next);\n        poolClear(&tempPool);\n        while (bindings) {\n          BINDING *b = bindings;\n          if (endNamespaceDeclHandler)\n            endNamespaceDeclHandler(handlerArg, b->prefix->name);\n          bindings = bindings->nextTagBinding;\n          b->nextTagBinding = freeBindingList;\n          freeBindingList = b;\n          b->prefix->binding = b->prevPrefixBinding;\n        }\n      }\n      if (tagLevel == 0)\n        return epilogProcessor(parser, next, end, nextPtr);\n      break;\n    case XML_TOK_END_TAG:\n      if (tagLevel == startTagLevel)\n        return XML_ERROR_ASYNC_ENTITY;\n      else {\n        int len;\n        const char *rawName;\n        TAG *tag = tagStack;\n        tagStack = tag->parent;\n        tag->parent = freeTagList;\n        freeTagList = tag;\n        rawName = s + enc->minBytesPerChar*2;\n        len = XmlNameLength(enc, rawName);\n        if (len != tag->rawNameLength\n            || memcmp(tag->rawName, rawName, len) != 0) {\n          *eventPP = rawName;\n          return XML_ERROR_TAG_MISMATCH;\n        }\n        --tagLevel;\n        if (endElementHandler) {\n          const XML_Char *localPart;\n          const XML_Char *prefix;\n          XML_Char *uri;\n          localPart = tag->name.localPart;\n          if (ns && localPart) {\n            /* localPart and prefix may have been overwritten in\n               tag->name.str, since this points to the binding->uri\n               buffer which gets re-used; so we have to add them again\n            */\n            uri = (XML_Char *)tag->name.str + tag->name.uriLen;\n            /* don't need to check for space - already done in storeAtts() */\n            while (*localPart) *uri++ = *localPart++;\n            prefix = (XML_Char *)tag->name.prefix;\n            if (ns_triplets && prefix) {\n              *uri++ = namespaceSeparator;\n              while (*prefix) *uri++ = *prefix++;\n             }\n            *uri = XML_T('\\0');\n          }\n          endElementHandler(handlerArg, tag->name.str);\n        }\n        else if (defaultHandler)\n          reportDefault(parser, enc, s, next);\n        while (tag->bindings) {\n          BINDING *b = tag->bindings;\n          if (endNamespaceDeclHandler)\n            endNamespaceDeclHandler(handlerArg, b->prefix->name);\n          tag->bindings = tag->bindings->nextTagBinding;\n          b->nextTagBinding = freeBindingList;\n          freeBindingList = b;\n          b->prefix->binding = b->prevPrefixBinding;\n        }\n        if (tagLevel == 0)\n          return epilogProcessor(parser, next, end, nextPtr);\n      }\n      break;\n    case XML_TOK_CHAR_REF:\n      {\n        int n = XmlCharRefNumber(enc, s);\n        if (n < 0)\n          return XML_ERROR_BAD_CHAR_REF;\n        if (characterDataHandler) {\n          XML_Char buf[XML_ENCODE_MAX];\n          characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));\n        }\n        else if (defaultHandler)\n          reportDefault(parser, enc, s, next);\n      }\n      break;\n    case XML_TOK_XML_DECL:\n      return XML_ERROR_MISPLACED_XML_PI;\n    case XML_TOK_DATA_NEWLINE:\n      if (characterDataHandler) {\n        XML_Char c = 0xA;\n        characterDataHandler(handlerArg, &c, 1);\n      }\n      else if (defaultHandler)\n        reportDefault(parser, enc, s, next);\n      break;\n    case XML_TOK_CDATA_SECT_OPEN:\n      {\n        enum XML_Error result;\n        if (startCdataSectionHandler)\n          startCdataSectionHandler(handlerArg);\n#if 0\n        /* Suppose you doing a transformation on a document that involves\n           changing only the character data.  You set up a defaultHandler\n           and a characterDataHandler.  The defaultHandler simply copies\n           characters through.  The characterDataHandler does the\n           transformation and writes the characters out escaping them as\n           necessary.  This case will fail to work if we leave out the\n           following two lines (because & and < inside CDATA sections will\n           be incorrectly escaped).\n\n           However, now we have a start/endCdataSectionHandler, so it seems\n           easier to let the user deal with this.\n        */\n        else if (characterDataHandler)\n          characterDataHandler(handlerArg, dataBuf, 0);\n#endif\n        else if (defaultHandler)\n          reportDefault(parser, enc, s, next);\n        result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);\n        if (result != XML_ERROR_NONE)\n          return result;\n        else if (!next) {\n          processor = cdataSectionProcessor;\n          return result;\n        }\n      }\n      break;\n    case XML_TOK_TRAILING_RSQB:\n      if (haveMore) {\n        *nextPtr = s;\n        return XML_ERROR_NONE;\n      }\n      if (characterDataHandler) {\n        if (MUST_CONVERT(enc, s)) {\n          ICHAR *dataPtr = (ICHAR *)dataBuf;\n          XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);\n          characterDataHandler(handlerArg, dataBuf,\n                               (int)(dataPtr - (ICHAR *)dataBuf));\n        }\n        else\n          characterDataHandler(handlerArg,\n                               (XML_Char *)s,\n                               (int)((XML_Char *)end - (XML_Char *)s));\n      }\n      else if (defaultHandler)\n        reportDefault(parser, enc, s, end);\n      /* We are at the end of the final buffer, should we check for\n         XML_SUSPENDED, XML_FINISHED?\n      */\n      if (startTagLevel == 0) {\n        *eventPP = end;\n        return XML_ERROR_NO_ELEMENTS;\n      }\n      if (tagLevel != startTagLevel) {\n        *eventPP = end;\n        return XML_ERROR_ASYNC_ENTITY;\n      }\n      *nextPtr = end;\n      return XML_ERROR_NONE;\n    case XML_TOK_DATA_CHARS:\n      {\n        XML_CharacterDataHandler charDataHandler = characterDataHandler;\n        if (charDataHandler) {\n          if (MUST_CONVERT(enc, s)) {\n            for (;;) {\n              ICHAR *dataPtr = (ICHAR *)dataBuf;\n              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);\n              *eventEndPP = s;\n              charDataHandler(handlerArg, dataBuf,\n                              (int)(dataPtr - (ICHAR *)dataBuf));\n              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))\n                break;\n              *eventPP = s;\n            }\n          }\n          else\n            charDataHandler(handlerArg,\n                            (XML_Char *)s,\n                            (int)((XML_Char *)next - (XML_Char *)s));\n        }\n        else if (defaultHandler)\n          reportDefault(parser, enc, s, next);\n      }\n      break;\n    case XML_TOK_PI:\n      if (!reportProcessingInstruction(parser, enc, s, next))\n        return XML_ERROR_NO_MEMORY;\n      break;\n    case XML_TOK_COMMENT:\n      if (!reportComment(parser, enc, s, next))\n        return XML_ERROR_NO_MEMORY;\n      break;\n    default:\n      if (defaultHandler)\n        reportDefault(parser, enc, s, next);\n      break;\n    }\n    *eventPP = s = next;\n    switch (ps_parsing) {\n    case XML_SUSPENDED:\n      *nextPtr = next;\n      return XML_ERROR_NONE;\n    case XML_FINISHED:\n      return XML_ERROR_ABORTED;\n    default: ;\n    }\n  }\n  /* not reached */\n}\n\n/* Precondition: all arguments must be non-NULL;\n   Purpose:\n   - normalize attributes\n   - check attributes for well-formedness\n   - generate namespace aware attribute names (URI, prefix)\n   - build list of attributes for startElementHandler\n   - default attributes\n   - process namespace declarations (check and report them)\n   - generate namespace aware element name (URI, prefix)\n*/\nstatic enum XML_Error\nstoreAtts(XML_Parser parser, const ENCODING *enc,\n          const char *attStr, TAG_NAME *tagNamePtr,\n          BINDING **bindingsPtr)\n{\n  DTD * const dtd = _dtd;  /* save one level of indirection */\n  ELEMENT_TYPE *elementType;\n  int nDefaultAtts;\n  const XML_Char **appAtts;   /* the attribute list for the application */\n  int attIndex = 0;\n  int prefixLen;\n  int i;\n  int n;\n  XML_Char *uri;\n  int nPrefixes = 0;\n  BINDING *binding;\n  const XML_Char *localPart;\n\n  /* lookup the element type name */\n  elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);\n  if (!elementType) {\n    const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);\n    if (!name)\n      return XML_ERROR_NO_MEMORY;\n    elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,\n                                         sizeof(ELEMENT_TYPE));\n    if (!elementType)\n      return XML_ERROR_NO_MEMORY;\n    if (ns && !setElementTypePrefix(parser, elementType))\n      return XML_ERROR_NO_MEMORY;\n  }\n  nDefaultAtts = elementType->nDefaultAtts;\n\n  /* get the attributes from the tokenizer */\n  n = XmlGetAttributes(enc, attStr, attsSize, atts);\n  if (n + nDefaultAtts > attsSize) {\n    int oldAttsSize = attsSize;\n    ATTRIBUTE *temp;\n#ifdef XML_ATTR_INFO\n    XML_AttrInfo *temp2;\n#endif\n    attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;\n    temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));\n    if (temp == NULL)\n      return XML_ERROR_NO_MEMORY;\n    atts = temp;\n#ifdef XML_ATTR_INFO\n    temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));\n    if (temp2 == NULL)\n      return XML_ERROR_NO_MEMORY;\n    attInfo = temp2;\n#endif\n    if (n > oldAttsSize)\n      XmlGetAttributes(enc, attStr, n, atts);\n  }\n\n  appAtts = (const XML_Char **)atts;\n  for (i = 0; i < n; i++) {\n    ATTRIBUTE *currAtt = &atts[i];\n#ifdef XML_ATTR_INFO\n    XML_AttrInfo *currAttInfo = &attInfo[i];\n#endif\n    /* add the name and value to the attribute list */\n    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,\n                                         currAtt->name\n                                         + XmlNameLength(enc, currAtt->name));\n    if (!attId)\n      return XML_ERROR_NO_MEMORY;\n#ifdef XML_ATTR_INFO\n    currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name);\n    currAttInfo->nameEnd = currAttInfo->nameStart +\n                           XmlNameLength(enc, currAtt->name);\n    currAttInfo->valueStart = parseEndByteIndex -\n                            (parseEndPtr - currAtt->valuePtr);\n    currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd);\n#endif\n    /* Detect duplicate attributes by their QNames. This does not work when\n       namespace processing is turned on and different prefixes for the same\n       namespace are used. For this case we have a check further down.\n    */\n    if ((attId->name)[-1]) {\n      if (enc == encoding)\n        eventPtr = atts[i].name;\n      return XML_ERROR_DUPLICATE_ATTRIBUTE;\n    }\n    (attId->name)[-1] = 1;\n    appAtts[attIndex++] = attId->name;\n    if (!atts[i].normalized) {\n      enum XML_Error result;\n      XML_Bool isCdata = XML_TRUE;\n\n      /* figure out whether declared as other than CDATA */\n      if (attId->maybeTokenized) {\n        int j;\n        for (j = 0; j < nDefaultAtts; j++) {\n          if (attId == elementType->defaultAtts[j].id) {\n            isCdata = elementType->defaultAtts[j].isCdata;\n            break;\n          }\n        }\n      }\n\n      /* normalize the attribute value */\n      result = storeAttributeValue(parser, enc, isCdata,\n                                   atts[i].valuePtr, atts[i].valueEnd,\n                                   &tempPool);\n      if (result)\n        return result;\n      appAtts[attIndex] = poolStart(&tempPool);\n      poolFinish(&tempPool);\n    }\n    else {\n      /* the value did not need normalizing */\n      appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,\n                                          atts[i].valueEnd);\n      if (appAtts[attIndex] == 0)\n        return XML_ERROR_NO_MEMORY;\n      poolFinish(&tempPool);\n    }\n    /* handle prefixed attribute names */\n    if (attId->prefix) {\n      if (attId->xmlns) {\n        /* deal with namespace declarations here */\n        enum XML_Error result = addBinding(parser, attId->prefix, attId,\n                                           appAtts[attIndex], bindingsPtr);\n        if (result)\n          return result;\n        --attIndex;\n      }\n      else {\n        /* deal with other prefixed names later */\n        attIndex++;\n        nPrefixes++;\n        (attId->name)[-1] = 2;\n      }\n    }\n    else\n      attIndex++;\n  }\n\n  /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */\n  nSpecifiedAtts = attIndex;\n  if (elementType->idAtt && (elementType->idAtt->name)[-1]) {\n    for (i = 0; i < attIndex; i += 2)\n      if (appAtts[i] == elementType->idAtt->name) {\n        idAttIndex = i;\n        break;\n      }\n  }\n  else\n    idAttIndex = -1;\n\n  /* do attribute defaulting */\n  for (i = 0; i < nDefaultAtts; i++) {\n    const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;\n    if (!(da->id->name)[-1] && da->value) {\n      if (da->id->prefix) {\n        if (da->id->xmlns) {\n          enum XML_Error result = addBinding(parser, da->id->prefix, da->id,\n                                             da->value, bindingsPtr);\n          if (result)\n            return result;\n        }\n        else {\n          (da->id->name)[-1] = 2;\n          nPrefixes++;\n          appAtts[attIndex++] = da->id->name;\n          appAtts[attIndex++] = da->value;\n        }\n      }\n      else {\n        (da->id->name)[-1] = 1;\n        appAtts[attIndex++] = da->id->name;\n        appAtts[attIndex++] = da->value;\n      }\n    }\n  }\n  appAtts[attIndex] = 0;\n\n  /* expand prefixed attribute names, check for duplicates,\n     and clear flags that say whether attributes were specified */\n  i = 0;\n  if (nPrefixes) {\n    int j;  /* hash table index */\n    unsigned long version = nsAttsVersion;\n    int nsAttsSize = (int)1 << nsAttsPower;\n    /* size of hash table must be at least 2 * (# of prefixed attributes) */\n    if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */\n      NS_ATT *temp;\n      /* hash table size must also be a power of 2 and >= 8 */\n      while (nPrefixes >> nsAttsPower++);\n      if (nsAttsPower < 3)\n        nsAttsPower = 3;\n      nsAttsSize = (int)1 << nsAttsPower;\n      temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));\n      if (!temp)\n        return XML_ERROR_NO_MEMORY;\n      nsAtts = temp;\n      version = 0;  /* force re-initialization of nsAtts hash table */\n    }\n    /* using a version flag saves us from initializing nsAtts every time */\n    if (!version) {  /* initialize version flags when version wraps around */\n      version = INIT_ATTS_VERSION;\n      for (j = nsAttsSize; j != 0; )\n        nsAtts[--j].version = version;\n    }\n    nsAttsVersion = --version;\n\n    /* expand prefixed names and check for duplicates */\n    for (; i < attIndex; i += 2) {\n      const XML_Char *s = appAtts[i];\n      if (s[-1] == 2) {  /* prefixed */\n        ATTRIBUTE_ID *id;\n        const BINDING *b;\n        unsigned long uriHash = hash_secret_salt;\n        ((XML_Char *)s)[-1] = 0;  /* clear flag */\n        id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);\n        if (!id || !id->prefix)\n          return XML_ERROR_NO_MEMORY;\n        b = id->prefix->binding;\n        if (!b)\n          return XML_ERROR_UNBOUND_PREFIX;\n\n        /* as we expand the name we also calculate its hash value */\n        for (j = 0; j < b->uriLen; j++) {\n          const XML_Char c = b->uri[j];\n          if (!poolAppendChar(&tempPool, c))\n            return XML_ERROR_NO_MEMORY;\n          uriHash = CHAR_HASH(uriHash, c);\n        }\n        while (*s++ != XML_T(ASCII_COLON))\n          ;\n        do {  /* copies null terminator */\n          const XML_Char c = *s;\n          if (!poolAppendChar(&tempPool, *s))\n            return XML_ERROR_NO_MEMORY;\n          uriHash = CHAR_HASH(uriHash, c);\n        } while (*s++);\n\n        { /* Check hash table for duplicate of expanded name (uriName).\n             Derived from code in lookup(parser, HASH_TABLE *table, ...).\n          */\n          unsigned char step = 0;\n          unsigned long mask = nsAttsSize - 1;\n          j = uriHash & mask;  /* index into hash table */\n          while (nsAtts[j].version == version) {\n            /* for speed we compare stored hash values first */\n            if (uriHash == nsAtts[j].hash) {\n              const XML_Char *s1 = poolStart(&tempPool);\n              const XML_Char *s2 = nsAtts[j].uriName;\n              /* s1 is null terminated, but not s2 */\n              for (; *s1 == *s2 && *s1 != 0; s1++, s2++);\n              if (*s1 == 0)\n                return XML_ERROR_DUPLICATE_ATTRIBUTE;\n            }\n            if (!step)\n              step = PROBE_STEP(uriHash, mask, nsAttsPower);\n            j < step ? (j += nsAttsSize - step) : (j -= step);\n          }\n        }\n\n        if (ns_triplets) {  /* append namespace separator and prefix */\n          tempPool.ptr[-1] = namespaceSeparator;\n          s = b->prefix->name;\n          do {\n            if (!poolAppendChar(&tempPool, *s))\n              return XML_ERROR_NO_MEMORY;\n          } while (*s++);\n        }\n\n        /* store expanded name in attribute list */\n        s = poolStart(&tempPool);\n        poolFinish(&tempPool);\n        appAtts[i] = s;\n\n        /* fill empty slot with new version, uriName and hash value */\n        nsAtts[j].version = version;\n        nsAtts[j].hash = uriHash;\n        nsAtts[j].uriName = s;\n\n        if (!--nPrefixes) {\n          i += 2;\n          break;\n        }\n      }\n      else  /* not prefixed */\n        ((XML_Char *)s)[-1] = 0;  /* clear flag */\n    }\n  }\n  /* clear flags for the remaining attributes */\n  for (; i < attIndex; i += 2)\n    ((XML_Char *)(appAtts[i]))[-1] = 0;\n  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)\n    binding->attId->name[-1] = 0;\n\n  if (!ns)\n    return XML_ERROR_NONE;\n\n  /* expand the element type name */\n  if (elementType->prefix) {\n    binding = elementType->prefix->binding;\n    if (!binding)\n      return XML_ERROR_UNBOUND_PREFIX;\n    localPart = tagNamePtr->str;\n    while (*localPart++ != XML_T(ASCII_COLON))\n      ;\n  }\n  else if (dtd->defaultPrefix.binding) {\n    binding = dtd->defaultPrefix.binding;\n    localPart = tagNamePtr->str;\n  }\n  else\n    return XML_ERROR_NONE;\n  prefixLen = 0;\n  if (ns_triplets && binding->prefix->name) {\n    for (; binding->prefix->name[prefixLen++];)\n      ;  /* prefixLen includes null terminator */\n  }\n  tagNamePtr->localPart = localPart;\n  tagNamePtr->uriLen = binding->uriLen;\n  tagNamePtr->prefix = binding->prefix->name;\n  tagNamePtr->prefixLen = prefixLen;\n  for (i = 0; localPart[i++];)\n    ;  /* i includes null terminator */\n  n = i + binding->uriLen + prefixLen;\n  if (n > binding->uriAlloc) {\n    TAG *p;\n    uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));\n    if (!uri)\n      return XML_ERROR_NO_MEMORY;\n    binding->uriAlloc = n + EXPAND_SPARE;\n    memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));\n    for (p = tagStack; p; p = p->parent)\n      if (p->name.str == binding->uri)\n        p->name.str = uri;\n    FREE(binding->uri);\n    binding->uri = uri;\n  }\n  /* if namespaceSeparator != '\\0' then uri includes it already */\n  uri = binding->uri + binding->uriLen;\n  memcpy(uri, localPart, i * sizeof(XML_Char));\n  /* we always have a namespace separator between localPart and prefix */\n  if (prefixLen) {\n    uri += i - 1;\n    *uri = namespaceSeparator;  /* replace null terminator */\n    memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));\n  }\n  tagNamePtr->str = binding->uri;\n  return XML_ERROR_NONE;\n}\n\n/* addBinding() overwrites the value of prefix->binding without checking.\n   Therefore one must keep track of the old value outside of addBinding().\n*/\nstatic enum XML_Error\naddBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,\n           const XML_Char *uri, BINDING **bindingsPtr)\n{\n  static const XML_Char xmlNamespace[] = {\n    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,\n    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,\n    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,\n    ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,\n    ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,\n    ASCII_e, '\\0'\n  };\n  static const int xmlLen =\n    (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;\n  static const XML_Char xmlnsNamespace[] = {\n    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,\n    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,\n    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,\n    ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,\n    ASCII_SLASH, '\\0'\n  };\n  static const int xmlnsLen =\n    (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;\n\n  XML_Bool mustBeXML = XML_FALSE;\n  XML_Bool isXML = XML_TRUE;\n  XML_Bool isXMLNS = XML_TRUE;\n\n  BINDING *b;\n  int len;\n\n  /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */\n  if (*uri == XML_T('\\0') && prefix->name)\n    return XML_ERROR_UNDECLARING_PREFIX;\n\n  if (prefix->name\n      && prefix->name[0] == XML_T(ASCII_x)\n      && prefix->name[1] == XML_T(ASCII_m)\n      && prefix->name[2] == XML_T(ASCII_l)) {\n\n    /* Not allowed to bind xmlns */\n    if (prefix->name[3] == XML_T(ASCII_n)\n        && prefix->name[4] == XML_T(ASCII_s)\n        && prefix->name[5] == XML_T('\\0'))\n      return XML_ERROR_RESERVED_PREFIX_XMLNS;\n\n    if (prefix->name[3] == XML_T('\\0'))\n      mustBeXML = XML_TRUE;\n  }\n\n  for (len = 0; uri[len]; len++) {\n    if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))\n      isXML = XML_FALSE;\n\n    if (!mustBeXML && isXMLNS\n        && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))\n      isXMLNS = XML_FALSE;\n  }\n  isXML = isXML && len == xmlLen;\n  isXMLNS = isXMLNS && len == xmlnsLen;\n\n  if (mustBeXML != isXML)\n    return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML\n                     : XML_ERROR_RESERVED_NAMESPACE_URI;\n\n  if (isXMLNS)\n    return XML_ERROR_RESERVED_NAMESPACE_URI;\n\n  if (namespaceSeparator)\n    len++;\n  if (freeBindingList) {\n    b = freeBindingList;\n    if (len > b->uriAlloc) {\n      XML_Char *temp = (XML_Char *)REALLOC(b->uri,\n                          sizeof(XML_Char) * (len + EXPAND_SPARE));\n      if (temp == NULL)\n        return XML_ERROR_NO_MEMORY;\n      b->uri = temp;\n      b->uriAlloc = len + EXPAND_SPARE;\n    }\n    freeBindingList = b->nextTagBinding;\n  }\n  else {\n    b = (BINDING *)MALLOC(sizeof(BINDING));\n    if (!b)\n      return XML_ERROR_NO_MEMORY;\n    b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));\n    if (!b->uri) {\n      FREE(b);\n      return XML_ERROR_NO_MEMORY;\n    }\n    b->uriAlloc = len + EXPAND_SPARE;\n  }\n  b->uriLen = len;\n  memcpy(b->uri, uri, len * sizeof(XML_Char));\n  if (namespaceSeparator)\n    b->uri[len - 1] = namespaceSeparator;\n  b->prefix = prefix;\n  b->attId = attId;\n  b->prevPrefixBinding = prefix->binding;\n  /* NULL binding when default namespace undeclared */\n  if (*uri == XML_T('\\0') && prefix == &_dtd->defaultPrefix)\n    prefix->binding = NULL;\n  else\n    prefix->binding = b;\n  b->nextTagBinding = *bindingsPtr;\n  *bindingsPtr = b;\n  /* if attId == NULL then we are not starting a namespace scope */\n  if (attId && startNamespaceDeclHandler)\n    startNamespaceDeclHandler(handlerArg, prefix->name,\n                              prefix->binding ? uri : 0);\n  return XML_ERROR_NONE;\n}\n\n/* The idea here is to avoid using stack for each CDATA section when\n   the whole file is parsed with one call.\n*/\nstatic enum XML_Error PTRCALL\ncdataSectionProcessor(XML_Parser parser,\n                      const char *start,\n                      const char *end,\n                      const char **endPtr)\n{\n  enum XML_Error result = doCdataSection(parser, encoding, &start, end,\n                                         endPtr, (XML_Bool)!ps_finalBuffer);\n  if (result != XML_ERROR_NONE)\n    return result;\n  if (start) {\n    if (parentParser) {  /* we are parsing an external entity */\n      processor = externalEntityContentProcessor;\n      return externalEntityContentProcessor(parser, start, end, endPtr);\n    }\n    else {\n      processor = contentProcessor;\n      return contentProcessor(parser, start, end, endPtr);\n    }\n  }\n  return result;\n}\n\n/* startPtr gets set to non-null if the section is closed, and to null if\n   the section is not yet closed.\n*/\nstatic enum XML_Error\ndoCdataSection(XML_Parser parser,\n               const ENCODING *enc,\n               const char **startPtr,\n               const char *end,\n               const char **nextPtr,\n               XML_Bool haveMore)\n{\n  const char *s = *startPtr;\n  const char **eventPP;\n  const char **eventEndPP;\n  if (enc == encoding) {\n    eventPP = &eventPtr;\n    *eventPP = s;\n    eventEndPP = &eventEndPtr;\n  }\n  else {\n    eventPP = &(openInternalEntities->internalEventPtr);\n    eventEndPP = &(openInternalEntities->internalEventEndPtr);\n  }\n  *eventPP = s;\n  *startPtr = NULL;\n\n  for (;;) {\n    const char *next;\n    int tok = XmlCdataSectionTok(enc, s, end, &next);\n    *eventEndPP = next;\n    switch (tok) {\n    case XML_TOK_CDATA_SECT_CLOSE:\n      if (endCdataSectionHandler)\n        endCdataSectionHandler(handlerArg);\n#if 0\n      /* see comment under XML_TOK_CDATA_SECT_OPEN */\n      else if (characterDataHandler)\n        characterDataHandler(handlerArg, dataBuf, 0);\n#endif\n      else if (defaultHandler)\n        reportDefault(parser, enc, s, next);\n      *startPtr = next;\n      *nextPtr = next;\n      if (ps_parsing == XML_FINISHED)\n        return XML_ERROR_ABORTED;\n      else\n        return XML_ERROR_NONE;\n    case XML_TOK_DATA_NEWLINE:\n      if (characterDataHandler) {\n        XML_Char c = 0xA;\n        characterDataHandler(handlerArg, &c, 1);\n      }\n      else if (defaultHandler)\n        reportDefault(parser, enc, s, next);\n      break;\n    case XML_TOK_DATA_CHARS:\n      {\n        XML_CharacterDataHandler charDataHandler = characterDataHandler;\n        if (charDataHandler) {\n          if (MUST_CONVERT(enc, s)) {\n            for (;;) {\n              ICHAR *dataPtr = (ICHAR *)dataBuf;\n              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);\n              *eventEndPP = next;\n              charDataHandler(handlerArg, dataBuf,\n                              (int)(dataPtr - (ICHAR *)dataBuf));\n              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))\n                break;\n              *eventPP = s;\n            }\n          }\n          else\n            charDataHandler(handlerArg,\n                            (XML_Char *)s,\n                            (int)((XML_Char *)next - (XML_Char *)s));\n        }\n        else if (defaultHandler)\n          reportDefault(parser, enc, s, next);\n      }\n      break;\n    case XML_TOK_INVALID:\n      *eventPP = next;\n      return XML_ERROR_INVALID_TOKEN;\n    case XML_TOK_PARTIAL_CHAR:\n      if (haveMore) {\n        *nextPtr = s;\n        return XML_ERROR_NONE;\n      }\n      return XML_ERROR_PARTIAL_CHAR;\n    case XML_TOK_PARTIAL:\n    case XML_TOK_NONE:\n      if (haveMore) {\n        *nextPtr = s;\n        return XML_ERROR_NONE;\n      }\n      return XML_ERROR_UNCLOSED_CDATA_SECTION;\n    default:\n      *eventPP = next;\n      return XML_ERROR_UNEXPECTED_STATE;\n    }\n\n    *eventPP = s = next;\n    switch (ps_parsing) {\n    case XML_SUSPENDED:\n      *nextPtr = next;\n      return XML_ERROR_NONE;\n    case XML_FINISHED:\n      return XML_ERROR_ABORTED;\n    default: ;\n    }\n  }\n  /* not reached */\n}\n\n#ifdef XML_DTD\n\n/* The idea here is to avoid using stack for each IGNORE section when\n   the whole file is parsed with one call.\n*/\nstatic enum XML_Error PTRCALL\nignoreSectionProcessor(XML_Parser parser,\n                       const char *start,\n                       const char *end,\n                       const char **endPtr)\n{\n  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,\n                                          endPtr, (XML_Bool)!ps_finalBuffer);\n  if (result != XML_ERROR_NONE)\n    return result;\n  if (start) {\n    processor = prologProcessor;\n    return prologProcessor(parser, start, end, endPtr);\n  }\n  return result;\n}\n\n/* startPtr gets set to non-null is the section is closed, and to null\n   if the section is not yet closed.\n*/\nstatic enum XML_Error\ndoIgnoreSection(XML_Parser parser,\n                const ENCODING *enc,\n                const char **startPtr,\n                const char *end,\n                const char **nextPtr,\n                XML_Bool haveMore)\n{\n  const char *next;\n  int tok;\n  const char *s = *startPtr;\n  const char **eventPP;\n  const char **eventEndPP;\n  if (enc == encoding) {\n    eventPP = &eventPtr;\n    *eventPP = s;\n    eventEndPP = &eventEndPtr;\n  }\n  else {\n    eventPP = &(openInternalEntities->internalEventPtr);\n    eventEndPP = &(openInternalEntities->internalEventEndPtr);\n  }\n  *eventPP = s;\n  *startPtr = NULL;\n  tok = XmlIgnoreSectionTok(enc, s, end, &next);\n  *eventEndPP = next;\n  switch (tok) {\n  case XML_TOK_IGNORE_SECT:\n    if (defaultHandler)\n      reportDefault(parser, enc, s, next);\n    *startPtr = next;\n    *nextPtr = next;\n    if (ps_parsing == XML_FINISHED)\n      return XML_ERROR_ABORTED;\n    else\n      return XML_ERROR_NONE;\n  case XML_TOK_INVALID:\n    *eventPP = next;\n    return XML_ERROR_INVALID_TOKEN;\n  case XML_TOK_PARTIAL_CHAR:\n    if (haveMore) {\n      *nextPtr = s;\n      return XML_ERROR_NONE;\n    }\n    return XML_ERROR_PARTIAL_CHAR;\n  case XML_TOK_PARTIAL:\n  case XML_TOK_NONE:\n    if (haveMore) {\n      *nextPtr = s;\n      return XML_ERROR_NONE;\n    }\n    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */\n  default:\n    *eventPP = next;\n    return XML_ERROR_UNEXPECTED_STATE;\n  }\n  /* not reached */\n}\n\n#endif /* XML_DTD */\n\nstatic enum XML_Error\ninitializeEncoding(XML_Parser parser)\n{\n  const char *s;\n#ifdef XML_UNICODE\n  char encodingBuf[128];\n  if (!protocolEncodingName)\n    s = NULL;\n  else {\n    int i;\n    for (i = 0; protocolEncodingName[i]; i++) {\n      if (i == sizeof(encodingBuf) - 1\n          || (protocolEncodingName[i] & ~0x7f) != 0) {\n        encodingBuf[0] = '\\0';\n        break;\n      }\n      encodingBuf[i] = (char)protocolEncodingName[i];\n    }\n    encodingBuf[i] = '\\0';\n    s = encodingBuf;\n  }\n#else\n  s = protocolEncodingName;\n#endif\n  if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))\n    return XML_ERROR_NONE;\n  return handleUnknownEncoding(parser, protocolEncodingName);\n}\n\nstatic enum XML_Error\nprocessXmlDecl(XML_Parser parser, int isGeneralTextEntity,\n               const char *s, const char *next)\n{\n  const char *encodingName = NULL;\n  const XML_Char *storedEncName = NULL;\n  const ENCODING *newEncoding = NULL;\n  const char *version = NULL;\n  const char *versionend;\n  const XML_Char *storedversion = NULL;\n  int standalone = -1;\n  if (!(ns\n        ? XmlParseXmlDeclNS\n        : XmlParseXmlDecl)(isGeneralTextEntity,\n                           encoding,\n                           s,\n                           next,\n                           &eventPtr,\n                           &version,\n                           &versionend,\n                           &encodingName,\n                           &newEncoding,\n                           &standalone)) {\n    if (isGeneralTextEntity)\n      return XML_ERROR_TEXT_DECL;\n    else\n      return XML_ERROR_XML_DECL;\n  }\n  if (!isGeneralTextEntity && standalone == 1) {\n    _dtd->standalone = XML_TRUE;\n#ifdef XML_DTD\n    if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)\n      paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;\n#endif /* XML_DTD */\n  }\n  if (xmlDeclHandler) {\n    if (encodingName != NULL) {\n      storedEncName = poolStoreString(&temp2Pool,\n                                      encoding,\n                                      encodingName,\n                                      encodingName\n                                      + XmlNameLength(encoding, encodingName));\n      if (!storedEncName)\n              return XML_ERROR_NO_MEMORY;\n      poolFinish(&temp2Pool);\n    }\n    if (version) {\n      storedversion = poolStoreString(&temp2Pool,\n                                      encoding,\n                                      version,\n                                      versionend - encoding->minBytesPerChar);\n      if (!storedversion)\n        return XML_ERROR_NO_MEMORY;\n    }\n    xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);\n  }\n  else if (defaultHandler)\n    reportDefault(parser, encoding, s, next);\n  if (protocolEncodingName == NULL) {\n    if (newEncoding) {\n      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {\n        eventPtr = encodingName;\n        return XML_ERROR_INCORRECT_ENCODING;\n      }\n      encoding = newEncoding;\n    }\n    else if (encodingName) {\n      enum XML_Error result;\n      if (!storedEncName) {\n        storedEncName = poolStoreString(\n          &temp2Pool, encoding, encodingName,\n          encodingName + XmlNameLength(encoding, encodingName));\n        if (!storedEncName)\n          return XML_ERROR_NO_MEMORY;\n      }\n      result = handleUnknownEncoding(parser, storedEncName);\n      poolClear(&temp2Pool);\n      if (result == XML_ERROR_UNKNOWN_ENCODING)\n        eventPtr = encodingName;\n      return result;\n    }\n  }\n\n  if (storedEncName || storedversion)\n    poolClear(&temp2Pool);\n\n  return XML_ERROR_NONE;\n}\n\nstatic enum XML_Error\nhandleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)\n{\n  if (unknownEncodingHandler) {\n    XML_Encoding info;\n    int i;\n    for (i = 0; i < 256; i++)\n      info.map[i] = -1;\n    info.convert = NULL;\n    info.data = NULL;\n    info.release = NULL;\n    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,\n                               &info)) {\n      ENCODING *enc;\n      unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());\n      if (!unknownEncodingMem) {\n        if (info.release)\n          info.release(info.data);\n        return XML_ERROR_NO_MEMORY;\n      }\n      enc = (ns\n             ? XmlInitUnknownEncodingNS\n             : XmlInitUnknownEncoding)(unknownEncodingMem,\n                                       info.map,\n                                       info.convert,\n                                       info.data);\n      if (enc) {\n        unknownEncodingData = info.data;\n        unknownEncodingRelease = info.release;\n        encoding = enc;\n        return XML_ERROR_NONE;\n      }\n    }\n    if (info.release != NULL)\n      info.release(info.data);\n  }\n  return XML_ERROR_UNKNOWN_ENCODING;\n}\n\nstatic enum XML_Error PTRCALL\nprologInitProcessor(XML_Parser parser,\n                    const char *s,\n                    const char *end,\n                    const char **nextPtr)\n{\n  enum XML_Error result = initializeEncoding(parser);\n  if (result != XML_ERROR_NONE)\n    return result;\n  processor = prologProcessor;\n  return prologProcessor(parser, s, end, nextPtr);\n}\n\n#ifdef XML_DTD\n\nstatic enum XML_Error PTRCALL\nexternalParEntInitProcessor(XML_Parser parser,\n                            const char *s,\n                            const char *end,\n                            const char **nextPtr)\n{\n  enum XML_Error result = initializeEncoding(parser);\n  if (result != XML_ERROR_NONE)\n    return result;\n\n  /* we know now that XML_Parse(Buffer) has been called,\n     so we consider the external parameter entity read */\n  _dtd->paramEntityRead = XML_TRUE;\n\n  if (prologState.inEntityValue) {\n    processor = entityValueInitProcessor;\n    return entityValueInitProcessor(parser, s, end, nextPtr);\n  }\n  else {\n    processor = externalParEntProcessor;\n    return externalParEntProcessor(parser, s, end, nextPtr);\n  }\n}\n\nstatic enum XML_Error PTRCALL\nentityValueInitProcessor(XML_Parser parser,\n                         const char *s,\n                         const char *end,\n                         const char **nextPtr)\n{\n  int tok;\n  const char *start = s;\n  const char *next = start;\n  eventPtr = start;\n\n  for (;;) {\n    tok = XmlPrologTok(encoding, start, end, &next);\n    eventEndPtr = next;\n    if (tok <= 0) {\n      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {\n        *nextPtr = s;\n        return XML_ERROR_NONE;\n      }\n      switch (tok) {\n      case XML_TOK_INVALID:\n        return XML_ERROR_INVALID_TOKEN;\n      case XML_TOK_PARTIAL:\n        return XML_ERROR_UNCLOSED_TOKEN;\n      case XML_TOK_PARTIAL_CHAR:\n        return XML_ERROR_PARTIAL_CHAR;\n      case XML_TOK_NONE:   /* start == end */\n      default:\n        break;\n      }\n      /* found end of entity value - can store it now */\n      return storeEntityValue(parser, encoding, s, end);\n    }\n    else if (tok == XML_TOK_XML_DECL) {\n      enum XML_Error result;\n      result = processXmlDecl(parser, 0, start, next);\n      if (result != XML_ERROR_NONE)\n        return result;\n      switch (ps_parsing) {\n      case XML_SUSPENDED:\n        *nextPtr = next;\n        return XML_ERROR_NONE;\n      case XML_FINISHED:\n        return XML_ERROR_ABORTED;\n      default:\n        *nextPtr = next;\n      }\n      /* stop scanning for text declaration - we found one */\n      processor = entityValueProcessor;\n      return entityValueProcessor(parser, next, end, nextPtr);\n    }\n    /* If we are at the end of the buffer, this would cause XmlPrologTok to\n       return XML_TOK_NONE on the next call, which would then cause the\n       function to exit with *nextPtr set to s - that is what we want for other\n       tokens, but not for the BOM - we would rather like to skip it;\n       then, when this routine is entered the next time, XmlPrologTok will\n       return XML_TOK_INVALID, since the BOM is still in the buffer\n    */\n    else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {\n      *nextPtr = next;\n      return XML_ERROR_NONE;\n    }\n    start = next;\n    eventPtr = start;\n  }\n}\n\nstatic enum XML_Error PTRCALL\nexternalParEntProcessor(XML_Parser parser,\n                        const char *s,\n                        const char *end,\n                        const char **nextPtr)\n{\n  const char *next = s;\n  int tok;\n\n  tok = XmlPrologTok(encoding, s, end, &next);\n  if (tok <= 0) {\n    if (!ps_finalBuffer && tok != XML_TOK_INVALID) {\n      *nextPtr = s;\n      return XML_ERROR_NONE;\n    }\n    switch (tok) {\n    case XML_TOK_INVALID:\n      return XML_ERROR_INVALID_TOKEN;\n    case XML_TOK_PARTIAL:\n      return XML_ERROR_UNCLOSED_TOKEN;\n    case XML_TOK_PARTIAL_CHAR:\n      return XML_ERROR_PARTIAL_CHAR;\n    case XML_TOK_NONE:   /* start == end */\n    default:\n      break;\n    }\n  }\n  /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.\n     However, when parsing an external subset, doProlog will not accept a BOM\n     as valid, and report a syntax error, so we have to skip the BOM\n  */\n  else if (tok == XML_TOK_BOM) {\n    s = next;\n    tok = XmlPrologTok(encoding, s, end, &next);\n  }\n\n  processor = prologProcessor;\n  return doProlog(parser, encoding, s, end, tok, next,\n                  nextPtr, (XML_Bool)!ps_finalBuffer);\n}\n\nstatic enum XML_Error PTRCALL\nentityValueProcessor(XML_Parser parser,\n                     const char *s,\n                     const char *end,\n                     const char **nextPtr)\n{\n  const char *start = s;\n  const char *next = s;\n  const ENCODING *enc = encoding;\n  int tok;\n\n  for (;;) {\n    tok = XmlPrologTok(enc, start, end, &next);\n    if (tok <= 0) {\n      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {\n        *nextPtr = s;\n        return XML_ERROR_NONE;\n      }\n      switch (tok) {\n      case XML_TOK_INVALID:\n        return XML_ERROR_INVALID_TOKEN;\n      case XML_TOK_PARTIAL:\n        return XML_ERROR_UNCLOSED_TOKEN;\n      case XML_TOK_PARTIAL_CHAR:\n        return XML_ERROR_PARTIAL_CHAR;\n      case XML_TOK_NONE:   /* start == end */\n      default:\n        break;\n      }\n      /* found end of entity value - can store it now */\n      return storeEntityValue(parser, enc, s, end);\n    }\n    start = next;\n  }\n}\n\n#endif /* XML_DTD */\n\nstatic enum XML_Error PTRCALL\nprologProcessor(XML_Parser parser,\n                const char *s,\n                const char *end,\n                const char **nextPtr)\n{\n  const char *next = s;\n  int tok = XmlPrologTok(encoding, s, end, &next);\n  return doProlog(parser, encoding, s, end, tok, next,\n                  nextPtr, (XML_Bool)!ps_finalBuffer);\n}\n\nstatic enum XML_Error\ndoProlog(XML_Parser parser,\n         const ENCODING *enc,\n         const char *s,\n         const char *end,\n         int tok,\n         const char *next,\n         const char **nextPtr,\n         XML_Bool haveMore)\n{\n#ifdef XML_DTD\n  static const XML_Char externalSubsetName[] = { ASCII_HASH , '\\0' };\n#endif /* XML_DTD */\n  static const XML_Char atypeCDATA[] =\n      { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\\0' };\n  static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\\0' };\n  static const XML_Char atypeIDREF[] =\n      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\\0' };\n  static const XML_Char atypeIDREFS[] =\n      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\\0' };\n  static const XML_Char atypeENTITY[] =\n      { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\\0' };\n  static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,\n      ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\\0' };\n  static const XML_Char atypeNMTOKEN[] = {\n      ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\\0' };\n  static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,\n      ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\\0' };\n  static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,\n      ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\\0' };\n  static const XML_Char enumValueSep[] = { ASCII_PIPE, '\\0' };\n  static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\\0' };\n\n  /* save one level of indirection */\n  DTD * const dtd = _dtd;\n\n  const char **eventPP;\n  const char **eventEndPP;\n  enum XML_Content_Quant quant;\n\n  if (enc == encoding) {\n    eventPP = &eventPtr;\n    eventEndPP = &eventEndPtr;\n  }\n  else {\n    eventPP = &(openInternalEntities->internalEventPtr);\n    eventEndPP = &(openInternalEntities->internalEventEndPtr);\n  }\n\n  for (;;) {\n    int role;\n    XML_Bool handleDefault = XML_TRUE;\n    *eventPP = s;\n    *eventEndPP = next;\n    if (tok <= 0) {\n      if (haveMore && tok != XML_TOK_INVALID) {\n        *nextPtr = s;\n        return XML_ERROR_NONE;\n      }\n      switch (tok) {\n      case XML_TOK_INVALID:\n        *eventPP = next;\n        return XML_ERROR_INVALID_TOKEN;\n      case XML_TOK_PARTIAL:\n        return XML_ERROR_UNCLOSED_TOKEN;\n      case XML_TOK_PARTIAL_CHAR:\n        return XML_ERROR_PARTIAL_CHAR;\n      case -XML_TOK_PROLOG_S:\n        tok = -tok;\n        break;\n      case XML_TOK_NONE:\n#ifdef XML_DTD\n        /* for internal PE NOT referenced between declarations */\n        if (enc != encoding && !openInternalEntities->betweenDecl) {\n          *nextPtr = s;\n          return XML_ERROR_NONE;\n        }\n        /* WFC: PE Between Declarations - must check that PE contains\n           complete markup, not only for external PEs, but also for\n           internal PEs if the reference occurs between declarations.\n        */\n        if (isParamEntity || enc != encoding) {\n          if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)\n              == XML_ROLE_ERROR)\n            return XML_ERROR_INCOMPLETE_PE;\n          *nextPtr = s;\n          return XML_ERROR_NONE;\n        }\n#endif /* XML_DTD */\n        return XML_ERROR_NO_ELEMENTS;\n      default:\n        tok = -tok;\n        next = end;\n        break;\n      }\n    }\n    role = XmlTokenRole(&prologState, tok, s, next, enc);\n    switch (role) {\n    case XML_ROLE_XML_DECL:\n      {\n        enum XML_Error result = processXmlDecl(parser, 0, s, next);\n        if (result != XML_ERROR_NONE)\n          return result;\n        enc = encoding;\n        handleDefault = XML_FALSE;\n      }\n      break;\n    case XML_ROLE_DOCTYPE_NAME:\n      if (startDoctypeDeclHandler) {\n        doctypeName = poolStoreString(&tempPool, enc, s, next);\n        if (!doctypeName)\n          return XML_ERROR_NO_MEMORY;\n        poolFinish(&tempPool);\n        doctypePubid = NULL;\n        handleDefault = XML_FALSE;\n      }\n      doctypeSysid = NULL; /* always initialize to NULL */\n      break;\n    case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:\n      if (startDoctypeDeclHandler) {\n        startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,\n                                doctypePubid, 1);\n        doctypeName = NULL;\n        poolClear(&tempPool);\n        handleDefault = XML_FALSE;\n      }\n      break;\n#ifdef XML_DTD\n    case XML_ROLE_TEXT_DECL:\n      {\n        enum XML_Error result = processXmlDecl(parser, 1, s, next);\n        if (result != XML_ERROR_NONE)\n          return result;\n        enc = encoding;\n        handleDefault = XML_FALSE;\n      }\n      break;\n#endif /* XML_DTD */\n    case XML_ROLE_DOCTYPE_PUBLIC_ID:\n#ifdef XML_DTD\n      useForeignDTD = XML_FALSE;\n      declEntity = (ENTITY *)lookup(parser,\n                                    &dtd->paramEntities,\n                                    externalSubsetName,\n                                    sizeof(ENTITY));\n      if (!declEntity)\n        return XML_ERROR_NO_MEMORY;\n#endif /* XML_DTD */\n      dtd->hasParamEntityRefs = XML_TRUE;\n      if (startDoctypeDeclHandler) {\n        XML_Char *pubId;\n        if (!XmlIsPublicId(enc, s, next, eventPP))\n          return XML_ERROR_PUBLICID;\n        pubId = poolStoreString(&tempPool, enc,\n                                s + enc->minBytesPerChar,\n                                next - enc->minBytesPerChar);\n        if (!pubId)\n          return XML_ERROR_NO_MEMORY;\n        normalizePublicId(pubId);\n        poolFinish(&tempPool);\n        doctypePubid = pubId;\n        handleDefault = XML_FALSE;\n        goto alreadyChecked;\n      }\n      /* fall through */\n    case XML_ROLE_ENTITY_PUBLIC_ID:\n      if (!XmlIsPublicId(enc, s, next, eventPP))\n        return XML_ERROR_PUBLICID;\n    alreadyChecked:\n      if (dtd->keepProcessing && declEntity) {\n        XML_Char *tem = poolStoreString(&dtd->pool,\n                                        enc,\n                                        s + enc->minBytesPerChar,\n                                        next - enc->minBytesPerChar);\n        if (!tem)\n          return XML_ERROR_NO_MEMORY;\n        normalizePublicId(tem);\n        declEntity->publicId = tem;\n        poolFinish(&dtd->pool);\n        if (entityDeclHandler)\n          handleDefault = XML_FALSE;\n      }\n      break;\n    case XML_ROLE_DOCTYPE_CLOSE:\n      if (doctypeName) {\n        startDoctypeDeclHandler(handlerArg, doctypeName,\n                                doctypeSysid, doctypePubid, 0);\n        poolClear(&tempPool);\n        handleDefault = XML_FALSE;\n      }\n      /* doctypeSysid will be non-NULL in the case of a previous\n         XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler\n         was not set, indicating an external subset\n      */\n#ifdef XML_DTD\n      if (doctypeSysid || useForeignDTD) {\n        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;\n        dtd->hasParamEntityRefs = XML_TRUE;\n        if (paramEntityParsing && externalEntityRefHandler) {\n          ENTITY *entity = (ENTITY *)lookup(parser,\n                                            &dtd->paramEntities,\n                                            externalSubsetName,\n                                            sizeof(ENTITY));\n          if (!entity)\n            return XML_ERROR_NO_MEMORY;\n          if (useForeignDTD)\n            entity->base = curBase;\n          dtd->paramEntityRead = XML_FALSE;\n          if (!externalEntityRefHandler(externalEntityRefHandlerArg,\n                                        0,\n                                        entity->base,\n                                        entity->systemId,\n                                        entity->publicId))\n            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;\n          if (dtd->paramEntityRead) {\n            if (!dtd->standalone &&\n                notStandaloneHandler &&\n                !notStandaloneHandler(handlerArg))\n              return XML_ERROR_NOT_STANDALONE;\n          }\n          /* if we didn't read the foreign DTD then this means that there\n             is no external subset and we must reset dtd->hasParamEntityRefs\n          */\n          else if (!doctypeSysid)\n            dtd->hasParamEntityRefs = hadParamEntityRefs;\n          /* end of DTD - no need to update dtd->keepProcessing */\n        }\n        useForeignDTD = XML_FALSE;\n      }\n#endif /* XML_DTD */\n      if (endDoctypeDeclHandler) {\n        endDoctypeDeclHandler(handlerArg);\n        handleDefault = XML_FALSE;\n      }\n      break;\n    case XML_ROLE_INSTANCE_START:\n#ifdef XML_DTD\n      /* if there is no DOCTYPE declaration then now is the\n         last chance to read the foreign DTD\n      */\n      if (useForeignDTD) {\n        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;\n        dtd->hasParamEntityRefs = XML_TRUE;\n        if (paramEntityParsing && externalEntityRefHandler) {\n          ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,\n                                            externalSubsetName,\n                                            sizeof(ENTITY));\n          if (!entity)\n            return XML_ERROR_NO_MEMORY;\n          entity->base = curBase;\n          dtd->paramEntityRead = XML_FALSE;\n          if (!externalEntityRefHandler(externalEntityRefHandlerArg,\n                                        0,\n                                        entity->base,\n                                        entity->systemId,\n                                        entity->publicId))\n            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;\n          if (dtd->paramEntityRead) {\n            if (!dtd->standalone &&\n                notStandaloneHandler &&\n                !notStandaloneHandler(handlerArg))\n              return XML_ERROR_NOT_STANDALONE;\n          }\n          /* if we didn't read the foreign DTD then this means that there\n             is no external subset and we must reset dtd->hasParamEntityRefs\n          */\n          else\n            dtd->hasParamEntityRefs = hadParamEntityRefs;\n          /* end of DTD - no need to update dtd->keepProcessing */\n        }\n      }\n#endif /* XML_DTD */\n      processor = contentProcessor;\n      return contentProcessor(parser, s, end, nextPtr);\n    case XML_ROLE_ATTLIST_ELEMENT_NAME:\n      declElementType = getElementType(parser, enc, s, next);\n      if (!declElementType)\n        return XML_ERROR_NO_MEMORY;\n      goto checkAttListDeclHandler;\n    case XML_ROLE_ATTRIBUTE_NAME:\n      declAttributeId = getAttributeId(parser, enc, s, next);\n      if (!declAttributeId)\n        return XML_ERROR_NO_MEMORY;\n      declAttributeIsCdata = XML_FALSE;\n      declAttributeType = NULL;\n      declAttributeIsId = XML_FALSE;\n      goto checkAttListDeclHandler;\n    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:\n      declAttributeIsCdata = XML_TRUE;\n      declAttributeType = atypeCDATA;\n      goto checkAttListDeclHandler;\n    case XML_ROLE_ATTRIBUTE_TYPE_ID:\n      declAttributeIsId = XML_TRUE;\n      declAttributeType = atypeID;\n      goto checkAttListDeclHandler;\n    case XML_ROLE_ATTRIBUTE_TYPE_IDREF:\n      declAttributeType = atypeIDREF;\n      goto checkAttListDeclHandler;\n    case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:\n      declAttributeType = atypeIDREFS;\n      goto checkAttListDeclHandler;\n    case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:\n      declAttributeType = atypeENTITY;\n      goto checkAttListDeclHandler;\n    case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:\n      declAttributeType = atypeENTITIES;\n      goto checkAttListDeclHandler;\n    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:\n      declAttributeType = atypeNMTOKEN;\n      goto checkAttListDeclHandler;\n    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:\n      declAttributeType = atypeNMTOKENS;\n    checkAttListDeclHandler:\n      if (dtd->keepProcessing && attlistDeclHandler)\n        handleDefault = XML_FALSE;\n      break;\n    case XML_ROLE_ATTRIBUTE_ENUM_VALUE:\n    case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:\n      if (dtd->keepProcessing && attlistDeclHandler) {\n        const XML_Char *prefix;\n        if (declAttributeType) {\n          prefix = enumValueSep;\n        }\n        else {\n          prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE\n                    ? notationPrefix\n                    : enumValueStart);\n        }\n        if (!poolAppendString(&tempPool, prefix))\n          return XML_ERROR_NO_MEMORY;\n        if (!poolAppend(&tempPool, enc, s, next))\n          return XML_ERROR_NO_MEMORY;\n        declAttributeType = tempPool.start;\n        handleDefault = XML_FALSE;\n      }\n      break;\n    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:\n    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:\n      if (dtd->keepProcessing) {\n        if (!defineAttribute(declElementType, declAttributeId,\n                             declAttributeIsCdata, declAttributeIsId,\n                             0, parser))\n          return XML_ERROR_NO_MEMORY;\n        if (attlistDeclHandler && declAttributeType) {\n          if (*declAttributeType == XML_T(ASCII_LPAREN)\n              || (*declAttributeType == XML_T(ASCII_N)\n                  && declAttributeType[1] == XML_T(ASCII_O))) {\n            /* Enumerated or Notation type */\n            if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))\n                || !poolAppendChar(&tempPool, XML_T('\\0')))\n              return XML_ERROR_NO_MEMORY;\n            declAttributeType = tempPool.start;\n            poolFinish(&tempPool);\n          }\n          *eventEndPP = s;\n          attlistDeclHandler(handlerArg, declElementType->name,\n                             declAttributeId->name, declAttributeType,\n                             0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);\n          poolClear(&tempPool);\n          handleDefault = XML_FALSE;\n        }\n      }\n      break;\n    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:\n    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:\n      if (dtd->keepProcessing) {\n        const XML_Char *attVal;\n        enum XML_Error result =\n          storeAttributeValue(parser, enc, declAttributeIsCdata,\n                              s + enc->minBytesPerChar,\n                              next - enc->minBytesPerChar,\n                              &dtd->pool);\n        if (result)\n          return result;\n        attVal = poolStart(&dtd->pool);\n        poolFinish(&dtd->pool);\n        /* ID attributes aren't allowed to have a default */\n        if (!defineAttribute(declElementType, declAttributeId,\n                             declAttributeIsCdata, XML_FALSE, attVal, parser))\n          return XML_ERROR_NO_MEMORY;\n        if (attlistDeclHandler && declAttributeType) {\n          if (*declAttributeType == XML_T(ASCII_LPAREN)\n              || (*declAttributeType == XML_T(ASCII_N)\n                  && declAttributeType[1] == XML_T(ASCII_O))) {\n            /* Enumerated or Notation type */\n            if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))\n                || !poolAppendChar(&tempPool, XML_T('\\0')))\n              return XML_ERROR_NO_MEMORY;\n            declAttributeType = tempPool.start;\n            poolFinish(&tempPool);\n          }\n          *eventEndPP = s;\n          attlistDeclHandler(handlerArg, declElementType->name,\n                             declAttributeId->name, declAttributeType,\n                             attVal,\n                             role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);\n          poolClear(&tempPool);\n          handleDefault = XML_FALSE;\n        }\n      }\n      break;\n    case XML_ROLE_ENTITY_VALUE:\n      if (dtd->keepProcessing) {\n        enum XML_Error result = storeEntityValue(parser, enc,\n                                            s + enc->minBytesPerChar,\n                                            next - enc->minBytesPerChar);\n        if (declEntity) {\n          declEntity->textPtr = poolStart(&dtd->entityValuePool);\n          declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));\n          poolFinish(&dtd->entityValuePool);\n          if (entityDeclHandler) {\n            *eventEndPP = s;\n            entityDeclHandler(handlerArg,\n                              declEntity->name,\n                              declEntity->is_param,\n                              declEntity->textPtr,\n                              declEntity->textLen,\n                              curBase, 0, 0, 0);\n            handleDefault = XML_FALSE;\n          }\n        }\n        else\n          poolDiscard(&dtd->entityValuePool);\n        if (result != XML_ERROR_NONE)\n          return result;\n      }\n      break;\n    case XML_ROLE_DOCTYPE_SYSTEM_ID:\n#ifdef XML_DTD\n      useForeignDTD = XML_FALSE;\n#endif /* XML_DTD */\n      dtd->hasParamEntityRefs = XML_TRUE;\n      if (startDoctypeDeclHandler) {\n        doctypeSysid = poolStoreString(&tempPool, enc,\n                                       s + enc->minBytesPerChar,\n                                       next - enc->minBytesPerChar);\n        if (doctypeSysid == NULL)\n          return XML_ERROR_NO_MEMORY;\n        poolFinish(&tempPool);\n        handleDefault = XML_FALSE;\n      }\n#ifdef XML_DTD\n      else\n        /* use externalSubsetName to make doctypeSysid non-NULL\n           for the case where no startDoctypeDeclHandler is set */\n        doctypeSysid = externalSubsetName;\n#endif /* XML_DTD */\n      if (!dtd->standalone\n#ifdef XML_DTD\n          && !paramEntityParsing\n#endif /* XML_DTD */\n          && notStandaloneHandler\n          && !notStandaloneHandler(handlerArg))\n        return XML_ERROR_NOT_STANDALONE;\n#ifndef XML_DTD\n      break;\n#else /* XML_DTD */\n      if (!declEntity) {\n        declEntity = (ENTITY *)lookup(parser,\n                                      &dtd->paramEntities,\n                                      externalSubsetName,\n                                      sizeof(ENTITY));\n        if (!declEntity)\n          return XML_ERROR_NO_MEMORY;\n        declEntity->publicId = NULL;\n      }\n      /* fall through */\n#endif /* XML_DTD */\n    case XML_ROLE_ENTITY_SYSTEM_ID:\n      if (dtd->keepProcessing && declEntity) {\n        declEntity->systemId = poolStoreString(&dtd->pool, enc,\n                                               s + enc->minBytesPerChar,\n                                               next - enc->minBytesPerChar);\n        if (!declEntity->systemId)\n          return XML_ERROR_NO_MEMORY;\n        declEntity->base = curBase;\n        poolFinish(&dtd->pool);\n        if (entityDeclHandler)\n          handleDefault = XML_FALSE;\n      }\n      break;\n    case XML_ROLE_ENTITY_COMPLETE:\n      if (dtd->keepProcessing && declEntity && entityDeclHandler) {\n        *eventEndPP = s;\n        entityDeclHandler(handlerArg,\n                          declEntity->name,\n                          declEntity->is_param,\n                          0,0,\n                          declEntity->base,\n                          declEntity->systemId,\n                          declEntity->publicId,\n                          0);\n        handleDefault = XML_FALSE;\n      }\n      break;\n    case XML_ROLE_ENTITY_NOTATION_NAME:\n      if (dtd->keepProcessing && declEntity) {\n        declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);\n        if (!declEntity->notation)\n          return XML_ERROR_NO_MEMORY;\n        poolFinish(&dtd->pool);\n        if (unparsedEntityDeclHandler) {\n          *eventEndPP = s;\n          unparsedEntityDeclHandler(handlerArg,\n                                    declEntity->name,\n                                    declEntity->base,\n                                    declEntity->systemId,\n                                    declEntity->publicId,\n                                    declEntity->notation);\n          handleDefault = XML_FALSE;\n        }\n        else if (entityDeclHandler) {\n          *eventEndPP = s;\n          entityDeclHandler(handlerArg,\n                            declEntity->name,\n                            0,0,0,\n                            declEntity->base,\n                            declEntity->systemId,\n                            declEntity->publicId,\n                            declEntity->notation);\n          handleDefault = XML_FALSE;\n        }\n      }\n      break;\n    case XML_ROLE_GENERAL_ENTITY_NAME:\n      {\n        if (XmlPredefinedEntityName(enc, s, next)) {\n          declEntity = NULL;\n          break;\n        }\n        if (dtd->keepProcessing) {\n          const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);\n          if (!name)\n            return XML_ERROR_NO_MEMORY;\n          declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,\n                                        sizeof(ENTITY));\n          if (!declEntity)\n            return XML_ERROR_NO_MEMORY;\n          if (declEntity->name != name) {\n            poolDiscard(&dtd->pool);\n            declEntity = NULL;\n          }\n          else {\n            poolFinish(&dtd->pool);\n            declEntity->publicId = NULL;\n            declEntity->is_param = XML_FALSE;\n            /* if we have a parent parser or are reading an internal parameter\n               entity, then the entity declaration is not considered \"internal\"\n            */\n            declEntity->is_internal = !(parentParser || openInternalEntities);\n            if (entityDeclHandler)\n              handleDefault = XML_FALSE;\n          }\n        }\n        else {\n          poolDiscard(&dtd->pool);\n          declEntity = NULL;\n        }\n      }\n      break;\n    case XML_ROLE_PARAM_ENTITY_NAME:\n#ifdef XML_DTD\n      if (dtd->keepProcessing) {\n        const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);\n        if (!name)\n          return XML_ERROR_NO_MEMORY;\n        declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,\n                                           name, sizeof(ENTITY));\n        if (!declEntity)\n          return XML_ERROR_NO_MEMORY;\n        if (declEntity->name != name) {\n          poolDiscard(&dtd->pool);\n          declEntity = NULL;\n        }\n        else {\n          poolFinish(&dtd->pool);\n          declEntity->publicId = NULL;\n          declEntity->is_param = XML_TRUE;\n          /* if we have a parent parser or are reading an internal parameter\n             entity, then the entity declaration is not considered \"internal\"\n          */\n          declEntity->is_internal = !(parentParser || openInternalEntities);\n          if (entityDeclHandler)\n            handleDefault = XML_FALSE;\n        }\n      }\n      else {\n        poolDiscard(&dtd->pool);\n        declEntity = NULL;\n      }\n#else /* not XML_DTD */\n      declEntity = NULL;\n#endif /* XML_DTD */\n      break;\n    case XML_ROLE_NOTATION_NAME:\n      declNotationPublicId = NULL;\n      declNotationName = NULL;\n      if (notationDeclHandler) {\n        declNotationName = poolStoreString(&tempPool, enc, s, next);\n        if (!declNotationName)\n          return XML_ERROR_NO_MEMORY;\n        poolFinish(&tempPool);\n        handleDefault = XML_FALSE;\n      }\n      break;\n    case XML_ROLE_NOTATION_PUBLIC_ID:\n      if (!XmlIsPublicId(enc, s, next, eventPP))\n        return XML_ERROR_PUBLICID;\n      if (declNotationName) {  /* means notationDeclHandler != NULL */\n        XML_Char *tem = poolStoreString(&tempPool,\n                                        enc,\n                                        s + enc->minBytesPerChar,\n                                        next - enc->minBytesPerChar);\n        if (!tem)\n          return XML_ERROR_NO_MEMORY;\n        normalizePublicId(tem);\n        declNotationPublicId = tem;\n        poolFinish(&tempPool);\n        handleDefault = XML_FALSE;\n      }\n      break;\n    case XML_ROLE_NOTATION_SYSTEM_ID:\n      if (declNotationName && notationDeclHandler) {\n        const XML_Char *systemId\n          = poolStoreString(&tempPool, enc,\n                            s + enc->minBytesPerChar,\n                            next - enc->minBytesPerChar);\n        if (!systemId)\n          return XML_ERROR_NO_MEMORY;\n        *eventEndPP = s;\n        notationDeclHandler(handlerArg,\n                            declNotationName,\n                            curBase,\n                            systemId,\n                            declNotationPublicId);\n        handleDefault = XML_FALSE;\n      }\n      poolClear(&tempPool);\n      break;\n    case XML_ROLE_NOTATION_NO_SYSTEM_ID:\n      if (declNotationPublicId && notationDeclHandler) {\n        *eventEndPP = s;\n        notationDeclHandler(handlerArg,\n                            declNotationName,\n                            curBase,\n                            0,\n                            declNotationPublicId);\n        handleDefault = XML_FALSE;\n      }\n      poolClear(&tempPool);\n      break;\n    case XML_ROLE_ERROR:\n      switch (tok) {\n      case XML_TOK_PARAM_ENTITY_REF:\n        /* PE references in internal subset are\n           not allowed within declarations. */\n        return XML_ERROR_PARAM_ENTITY_REF;\n      case XML_TOK_XML_DECL:\n        return XML_ERROR_MISPLACED_XML_PI;\n      default:\n        return XML_ERROR_SYNTAX;\n      }\n#ifdef XML_DTD\n    case XML_ROLE_IGNORE_SECT:\n      {\n        enum XML_Error result;\n        if (defaultHandler)\n          reportDefault(parser, enc, s, next);\n        handleDefault = XML_FALSE;\n        result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);\n        if (result != XML_ERROR_NONE)\n          return result;\n        else if (!next) {\n          processor = ignoreSectionProcessor;\n          return result;\n        }\n      }\n      break;\n#endif /* XML_DTD */\n    case XML_ROLE_GROUP_OPEN:\n      if (prologState.level >= groupSize) {\n        if (groupSize) {\n          char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);\n          if (temp == NULL)\n            return XML_ERROR_NO_MEMORY;\n          groupConnector = temp;\n          if (dtd->scaffIndex) {\n            int *temp = (int *)REALLOC(dtd->scaffIndex,\n                          groupSize * sizeof(int));\n            if (temp == NULL)\n              return XML_ERROR_NO_MEMORY;\n            dtd->scaffIndex = temp;\n          }\n        }\n        else {\n          groupConnector = (char *)MALLOC(groupSize = 32);\n          if (!groupConnector)\n            return XML_ERROR_NO_MEMORY;\n        }\n      }\n      groupConnector[prologState.level] = 0;\n      if (dtd->in_eldecl) {\n        int myindex = nextScaffoldPart(parser);\n        if (myindex < 0)\n          return XML_ERROR_NO_MEMORY;\n        dtd->scaffIndex[dtd->scaffLevel] = myindex;\n        dtd->scaffLevel++;\n        dtd->scaffold[myindex].type = XML_CTYPE_SEQ;\n        if (elementDeclHandler)\n          handleDefault = XML_FALSE;\n      }\n      break;\n    case XML_ROLE_GROUP_SEQUENCE:\n      if (groupConnector[prologState.level] == ASCII_PIPE)\n        return XML_ERROR_SYNTAX;\n      groupConnector[prologState.level] = ASCII_COMMA;\n      if (dtd->in_eldecl && elementDeclHandler)\n        handleDefault = XML_FALSE;\n      break;\n    case XML_ROLE_GROUP_CHOICE:\n      if (groupConnector[prologState.level] == ASCII_COMMA)\n        return XML_ERROR_SYNTAX;\n      if (dtd->in_eldecl\n          && !groupConnector[prologState.level]\n          && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type\n              != XML_CTYPE_MIXED)\n          ) {\n        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type\n            = XML_CTYPE_CHOICE;\n        if (elementDeclHandler)\n          handleDefault = XML_FALSE;\n      }\n      groupConnector[prologState.level] = ASCII_PIPE;\n      break;\n    case XML_ROLE_PARAM_ENTITY_REF:\n#ifdef XML_DTD\n    case XML_ROLE_INNER_PARAM_ENTITY_REF:\n      dtd->hasParamEntityRefs = XML_TRUE;\n      if (!paramEntityParsing)\n        dtd->keepProcessing = dtd->standalone;\n      else {\n        const XML_Char *name;\n        ENTITY *entity;\n        name = poolStoreString(&dtd->pool, enc,\n                                s + enc->minBytesPerChar,\n                                next - enc->minBytesPerChar);\n        if (!name)\n          return XML_ERROR_NO_MEMORY;\n        entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);\n        poolDiscard(&dtd->pool);\n        /* first, determine if a check for an existing declaration is needed;\n           if yes, check that the entity exists, and that it is internal,\n           otherwise call the skipped entity handler\n        */\n        if (prologState.documentEntity &&\n            (dtd->standalone\n             ? !openInternalEntities\n             : !dtd->hasParamEntityRefs)) {\n          if (!entity)\n            return XML_ERROR_UNDEFINED_ENTITY;\n          else if (!entity->is_internal)\n            return XML_ERROR_ENTITY_DECLARED_IN_PE;\n        }\n        else if (!entity) {\n          dtd->keepProcessing = dtd->standalone;\n          /* cannot report skipped entities in declarations */\n          if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {\n            skippedEntityHandler(handlerArg, name, 1);\n            handleDefault = XML_FALSE;\n          }\n          break;\n        }\n        if (entity->open)\n          return XML_ERROR_RECURSIVE_ENTITY_REF;\n        if (entity->textPtr) {\n          enum XML_Error result;\n          XML_Bool betweenDecl =\n            (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);\n          result = processInternalEntity(parser, entity, betweenDecl);\n          if (result != XML_ERROR_NONE)\n            return result;\n          handleDefault = XML_FALSE;\n          break;\n        }\n        if (externalEntityRefHandler) {\n          dtd->paramEntityRead = XML_FALSE;\n          entity->open = XML_TRUE;\n          if (!externalEntityRefHandler(externalEntityRefHandlerArg,\n                                        0,\n                                        entity->base,\n                                        entity->systemId,\n                                        entity->publicId)) {\n            entity->open = XML_FALSE;\n            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;\n          }\n          entity->open = XML_FALSE;\n          handleDefault = XML_FALSE;\n          if (!dtd->paramEntityRead) {\n            dtd->keepProcessing = dtd->standalone;\n            break;\n          }\n        }\n        else {\n          dtd->keepProcessing = dtd->standalone;\n          break;\n        }\n      }\n#endif /* XML_DTD */\n      if (!dtd->standalone &&\n          notStandaloneHandler &&\n          !notStandaloneHandler(handlerArg))\n        return XML_ERROR_NOT_STANDALONE;\n      break;\n\n    /* Element declaration stuff */\n\n    case XML_ROLE_ELEMENT_NAME:\n      if (elementDeclHandler) {\n        declElementType = getElementType(parser, enc, s, next);\n        if (!declElementType)\n          return XML_ERROR_NO_MEMORY;\n        dtd->scaffLevel = 0;\n        dtd->scaffCount = 0;\n        dtd->in_eldecl = XML_TRUE;\n        handleDefault = XML_FALSE;\n      }\n      break;\n\n    case XML_ROLE_CONTENT_ANY:\n    case XML_ROLE_CONTENT_EMPTY:\n      if (dtd->in_eldecl) {\n        if (elementDeclHandler) {\n          XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));\n          if (!content)\n            return XML_ERROR_NO_MEMORY;\n          content->quant = XML_CQUANT_NONE;\n          content->name = NULL;\n          content->numchildren = 0;\n          content->children = NULL;\n          content->type = ((role == XML_ROLE_CONTENT_ANY) ?\n                           XML_CTYPE_ANY :\n                           XML_CTYPE_EMPTY);\n          *eventEndPP = s;\n          elementDeclHandler(handlerArg, declElementType->name, content);\n          handleDefault = XML_FALSE;\n        }\n        dtd->in_eldecl = XML_FALSE;\n      }\n      break;\n\n    case XML_ROLE_CONTENT_PCDATA:\n      if (dtd->in_eldecl) {\n        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type\n            = XML_CTYPE_MIXED;\n        if (elementDeclHandler)\n          handleDefault = XML_FALSE;\n      }\n      break;\n\n    case XML_ROLE_CONTENT_ELEMENT:\n      quant = XML_CQUANT_NONE;\n      goto elementContent;\n    case XML_ROLE_CONTENT_ELEMENT_OPT:\n      quant = XML_CQUANT_OPT;\n      goto elementContent;\n    case XML_ROLE_CONTENT_ELEMENT_REP:\n      quant = XML_CQUANT_REP;\n      goto elementContent;\n    case XML_ROLE_CONTENT_ELEMENT_PLUS:\n      quant = XML_CQUANT_PLUS;\n    elementContent:\n      if (dtd->in_eldecl) {\n        ELEMENT_TYPE *el;\n        const XML_Char *name;\n        int nameLen;\n        const char *nxt = (quant == XML_CQUANT_NONE\n                           ? next\n                           : next - enc->minBytesPerChar);\n        int myindex = nextScaffoldPart(parser);\n        if (myindex < 0)\n          return XML_ERROR_NO_MEMORY;\n        dtd->scaffold[myindex].type = XML_CTYPE_NAME;\n        dtd->scaffold[myindex].quant = quant;\n        el = getElementType(parser, enc, s, nxt);\n        if (!el)\n          return XML_ERROR_NO_MEMORY;\n        name = el->name;\n        dtd->scaffold[myindex].name = name;\n        nameLen = 0;\n        for (; name[nameLen++]; );\n        dtd->contentStringLen +=  nameLen;\n        if (elementDeclHandler)\n          handleDefault = XML_FALSE;\n      }\n      break;\n\n    case XML_ROLE_GROUP_CLOSE:\n      quant = XML_CQUANT_NONE;\n      goto closeGroup;\n    case XML_ROLE_GROUP_CLOSE_OPT:\n      quant = XML_CQUANT_OPT;\n      goto closeGroup;\n    case XML_ROLE_GROUP_CLOSE_REP:\n      quant = XML_CQUANT_REP;\n      goto closeGroup;\n    case XML_ROLE_GROUP_CLOSE_PLUS:\n      quant = XML_CQUANT_PLUS;\n    closeGroup:\n      if (dtd->in_eldecl) {\n        if (elementDeclHandler)\n          handleDefault = XML_FALSE;\n        dtd->scaffLevel--;\n        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;\n        if (dtd->scaffLevel == 0) {\n          if (!handleDefault) {\n            XML_Content *model = build_model(parser);\n            if (!model)\n              return XML_ERROR_NO_MEMORY;\n            *eventEndPP = s;\n            elementDeclHandler(handlerArg, declElementType->name, model);\n          }\n          dtd->in_eldecl = XML_FALSE;\n          dtd->contentStringLen = 0;\n        }\n      }\n      break;\n      /* End element declaration stuff */\n\n    case XML_ROLE_PI:\n      if (!reportProcessingInstruction(parser, enc, s, next))\n        return XML_ERROR_NO_MEMORY;\n      handleDefault = XML_FALSE;\n      break;\n    case XML_ROLE_COMMENT:\n      if (!reportComment(parser, enc, s, next))\n        return XML_ERROR_NO_MEMORY;\n      handleDefault = XML_FALSE;\n      break;\n    case XML_ROLE_NONE:\n      switch (tok) {\n      case XML_TOK_BOM:\n        handleDefault = XML_FALSE;\n        break;\n      }\n      break;\n    case XML_ROLE_DOCTYPE_NONE:\n      if (startDoctypeDeclHandler)\n        handleDefault = XML_FALSE;\n      break;\n    case XML_ROLE_ENTITY_NONE:\n      if (dtd->keepProcessing && entityDeclHandler)\n        handleDefault = XML_FALSE;\n      break;\n    case XML_ROLE_NOTATION_NONE:\n      if (notationDeclHandler)\n        handleDefault = XML_FALSE;\n      break;\n    case XML_ROLE_ATTLIST_NONE:\n      if (dtd->keepProcessing && attlistDeclHandler)\n        handleDefault = XML_FALSE;\n      break;\n    case XML_ROLE_ELEMENT_NONE:\n      if (elementDeclHandler)\n        handleDefault = XML_FALSE;\n      break;\n    } /* end of big switch */\n\n    if (handleDefault && defaultHandler)\n      reportDefault(parser, enc, s, next);\n\n    switch (ps_parsing) {\n    case XML_SUSPENDED:\n      *nextPtr = next;\n      return XML_ERROR_NONE;\n    case XML_FINISHED:\n      return XML_ERROR_ABORTED;\n    default:\n      s = next;\n      tok = XmlPrologTok(enc, s, end, &next);\n    }\n  }\n  /* not reached */\n}\n\nstatic enum XML_Error PTRCALL\nepilogProcessor(XML_Parser parser,\n                const char *s,\n                const char *end,\n                const char **nextPtr)\n{\n  processor = epilogProcessor;\n  eventPtr = s;\n  for (;;) {\n    const char *next = NULL;\n    int tok = XmlPrologTok(encoding, s, end, &next);\n    eventEndPtr = next;\n    switch (tok) {\n    /* report partial linebreak - it might be the last token */\n    case -XML_TOK_PROLOG_S:\n      if (defaultHandler) {\n        reportDefault(parser, encoding, s, next);\n        if (ps_parsing == XML_FINISHED)\n          return XML_ERROR_ABORTED;\n      }\n      *nextPtr = next;\n      return XML_ERROR_NONE;\n    case XML_TOK_NONE:\n      *nextPtr = s;\n      return XML_ERROR_NONE;\n    case XML_TOK_PROLOG_S:\n      if (defaultHandler)\n        reportDefault(parser, encoding, s, next);\n      break;\n    case XML_TOK_PI:\n      if (!reportProcessingInstruction(parser, encoding, s, next))\n        return XML_ERROR_NO_MEMORY;\n      break;\n    case XML_TOK_COMMENT:\n      if (!reportComment(parser, encoding, s, next))\n        return XML_ERROR_NO_MEMORY;\n      break;\n    case XML_TOK_INVALID:\n      eventPtr = next;\n      return XML_ERROR_INVALID_TOKEN;\n    case XML_TOK_PARTIAL:\n      if (!ps_finalBuffer) {\n        *nextPtr = s;\n        return XML_ERROR_NONE;\n      }\n      return XML_ERROR_UNCLOSED_TOKEN;\n    case XML_TOK_PARTIAL_CHAR:\n      if (!ps_finalBuffer) {\n        *nextPtr = s;\n        return XML_ERROR_NONE;\n      }\n      return XML_ERROR_PARTIAL_CHAR;\n    default:\n      return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;\n    }\n    eventPtr = s = next;\n    switch (ps_parsing) {\n    case XML_SUSPENDED:\n      *nextPtr = next;\n      return XML_ERROR_NONE;\n    case XML_FINISHED:\n      return XML_ERROR_ABORTED;\n    default: ;\n    }\n  }\n}\n\nstatic enum XML_Error\nprocessInternalEntity(XML_Parser parser, ENTITY *entity,\n                      XML_Bool betweenDecl)\n{\n  const char *textStart, *textEnd;\n  const char *next;\n  enum XML_Error result;\n  OPEN_INTERNAL_ENTITY *openEntity;\n\n  if (freeInternalEntities) {\n    openEntity = freeInternalEntities;\n    freeInternalEntities = openEntity->next;\n  }\n  else {\n    openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));\n    if (!openEntity)\n      return XML_ERROR_NO_MEMORY;\n  }\n  entity->open = XML_TRUE;\n  entity->processed = 0;\n  openEntity->next = openInternalEntities;\n  openInternalEntities = openEntity;\n  openEntity->entity = entity;\n  openEntity->startTagLevel = tagLevel;\n  openEntity->betweenDecl = betweenDecl;\n  openEntity->internalEventPtr = NULL;\n  openEntity->internalEventEndPtr = NULL;\n  textStart = (char *)entity->textPtr;\n  textEnd = (char *)(entity->textPtr + entity->textLen);\n\n#ifdef XML_DTD\n  if (entity->is_param) {\n    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);\n    result = doProlog(parser, internalEncoding, textStart, textEnd, tok,\n                      next, &next, XML_FALSE);\n  }\n  else\n#endif /* XML_DTD */\n    result = doContent(parser, tagLevel, internalEncoding, textStart,\n                       textEnd, &next, XML_FALSE);\n\n  if (result == XML_ERROR_NONE) {\n    if (textEnd != next && ps_parsing == XML_SUSPENDED) {\n      entity->processed = (int)(next - textStart);\n      processor = internalEntityProcessor;\n    }\n    else {\n      entity->open = XML_FALSE;\n      openInternalEntities = openEntity->next;\n      /* put openEntity back in list of free instances */\n      openEntity->next = freeInternalEntities;\n      freeInternalEntities = openEntity;\n    }\n  }\n  return result;\n}\n\nstatic enum XML_Error PTRCALL\ninternalEntityProcessor(XML_Parser parser,\n                        const char *s,\n                        const char *end,\n                        const char **nextPtr)\n{\n  ENTITY *entity;\n  const char *textStart, *textEnd;\n  const char *next;\n  enum XML_Error result;\n  OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;\n  if (!openEntity)\n    return XML_ERROR_UNEXPECTED_STATE;\n\n  entity = openEntity->entity;\n  textStart = ((char *)entity->textPtr) + entity->processed;\n  textEnd = (char *)(entity->textPtr + entity->textLen);\n\n#ifdef XML_DTD\n  if (entity->is_param) {\n    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);\n    result = doProlog(parser, internalEncoding, textStart, textEnd, tok,\n                      next, &next, XML_FALSE);\n  }\n  else\n#endif /* XML_DTD */\n    result = doContent(parser, openEntity->startTagLevel, internalEncoding,\n                       textStart, textEnd, &next, XML_FALSE);\n\n  if (result != XML_ERROR_NONE)\n    return result;\n  else if (textEnd != next && ps_parsing == XML_SUSPENDED) {\n    entity->processed = (int)(next - (char *)entity->textPtr);\n    return result;\n  }\n  else {\n    entity->open = XML_FALSE;\n    openInternalEntities = openEntity->next;\n    /* put openEntity back in list of free instances */\n    openEntity->next = freeInternalEntities;\n    freeInternalEntities = openEntity;\n  }\n\n#ifdef XML_DTD\n  if (entity->is_param) {\n    int tok;\n    processor = prologProcessor;\n    tok = XmlPrologTok(encoding, s, end, &next);\n    return doProlog(parser, encoding, s, end, tok, next, nextPtr,\n                    (XML_Bool)!ps_finalBuffer);\n  }\n  else\n#endif /* XML_DTD */\n  {\n    processor = contentProcessor;\n    /* see externalEntityContentProcessor vs contentProcessor */\n    return doContent(parser, parentParser ? 1 : 0, encoding, s, end,\n                     nextPtr, (XML_Bool)!ps_finalBuffer);\n  }\n}\n\nstatic enum XML_Error PTRCALL\nerrorProcessor(XML_Parser parser,\n               const char *s,\n               const char *end,\n               const char **nextPtr)\n{\n  return errorCode;\n}\n\nstatic enum XML_Error\nstoreAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,\n                    const char *ptr, const char *end,\n                    STRING_POOL *pool)\n{\n  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,\n                                               end, pool);\n  if (result)\n    return result;\n  if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)\n    poolChop(pool);\n  if (!poolAppendChar(pool, XML_T('\\0')))\n    return XML_ERROR_NO_MEMORY;\n  return XML_ERROR_NONE;\n}\n\nstatic enum XML_Error\nappendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,\n                     const char *ptr, const char *end,\n                     STRING_POOL *pool)\n{\n  DTD * const dtd = _dtd;  /* save one level of indirection */\n  for (;;) {\n    const char *next;\n    int tok = XmlAttributeValueTok(enc, ptr, end, &next);\n    switch (tok) {\n    case XML_TOK_NONE:\n      return XML_ERROR_NONE;\n    case XML_TOK_INVALID:\n      if (enc == encoding)\n        eventPtr = next;\n      return XML_ERROR_INVALID_TOKEN;\n    case XML_TOK_PARTIAL:\n      if (enc == encoding)\n        eventPtr = ptr;\n      return XML_ERROR_INVALID_TOKEN;\n    case XML_TOK_CHAR_REF:\n      {\n        XML_Char buf[XML_ENCODE_MAX];\n        int i;\n        int n = XmlCharRefNumber(enc, ptr);\n        if (n < 0) {\n          if (enc == encoding)\n            eventPtr = ptr;\n          return XML_ERROR_BAD_CHAR_REF;\n        }\n        if (!isCdata\n            && n == 0x20 /* space */\n            && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))\n          break;\n        n = XmlEncode(n, (ICHAR *)buf);\n        if (!n) {\n          if (enc == encoding)\n            eventPtr = ptr;\n          return XML_ERROR_BAD_CHAR_REF;\n        }\n        for (i = 0; i < n; i++) {\n          if (!poolAppendChar(pool, buf[i]))\n            return XML_ERROR_NO_MEMORY;\n        }\n      }\n      break;\n    case XML_TOK_DATA_CHARS:\n      if (!poolAppend(pool, enc, ptr, next))\n        return XML_ERROR_NO_MEMORY;\n      break;\n    case XML_TOK_TRAILING_CR:\n      next = ptr + enc->minBytesPerChar;\n      /* fall through */\n    case XML_TOK_ATTRIBUTE_VALUE_S:\n    case XML_TOK_DATA_NEWLINE:\n      if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))\n        break;\n      if (!poolAppendChar(pool, 0x20))\n        return XML_ERROR_NO_MEMORY;\n      break;\n    case XML_TOK_ENTITY_REF:\n      {\n        const XML_Char *name;\n        ENTITY *entity;\n        char checkEntityDecl;\n        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,\n                                              ptr + enc->minBytesPerChar,\n                                              next - enc->minBytesPerChar);\n        if (ch) {\n          if (!poolAppendChar(pool, ch))\n                return XML_ERROR_NO_MEMORY;\n          break;\n        }\n        name = poolStoreString(&temp2Pool, enc,\n                               ptr + enc->minBytesPerChar,\n                               next - enc->minBytesPerChar);\n        if (!name)\n          return XML_ERROR_NO_MEMORY;\n        entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);\n        poolDiscard(&temp2Pool);\n        /* First, determine if a check for an existing declaration is needed;\n           if yes, check that the entity exists, and that it is internal.\n        */\n        if (pool == &dtd->pool)  /* are we called from prolog? */\n          checkEntityDecl =\n#ifdef XML_DTD\n              prologState.documentEntity &&\n#endif /* XML_DTD */\n              (dtd->standalone\n               ? !openInternalEntities\n               : !dtd->hasParamEntityRefs);\n        else /* if (pool == &tempPool): we are called from content */\n          checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;\n        if (checkEntityDecl) {\n          if (!entity)\n            return XML_ERROR_UNDEFINED_ENTITY;\n          else if (!entity->is_internal)\n            return XML_ERROR_ENTITY_DECLARED_IN_PE;\n        }\n        else if (!entity) {\n          /* Cannot report skipped entity here - see comments on\n             skippedEntityHandler.\n          if (skippedEntityHandler)\n            skippedEntityHandler(handlerArg, name, 0);\n          */\n          /* Cannot call the default handler because this would be\n             out of sync with the call to the startElementHandler.\n          if ((pool == &tempPool) && defaultHandler)\n            reportDefault(parser, enc, ptr, next);\n          */\n          break;\n        }\n        if (entity->open) {\n          if (enc == encoding)\n            eventPtr = ptr;\n          return XML_ERROR_RECURSIVE_ENTITY_REF;\n        }\n        if (entity->notation) {\n          if (enc == encoding)\n            eventPtr = ptr;\n          return XML_ERROR_BINARY_ENTITY_REF;\n        }\n        if (!entity->textPtr) {\n          if (enc == encoding)\n            eventPtr = ptr;\n          return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;\n        }\n        else {\n          enum XML_Error result;\n          const XML_Char *textEnd = entity->textPtr + entity->textLen;\n          entity->open = XML_TRUE;\n          result = appendAttributeValue(parser, internalEncoding, isCdata,\n                                        (char *)entity->textPtr,\n                                        (char *)textEnd, pool);\n          entity->open = XML_FALSE;\n          if (result)\n            return result;\n        }\n      }\n      break;\n    default:\n      if (enc == encoding)\n        eventPtr = ptr;\n      return XML_ERROR_UNEXPECTED_STATE;\n    }\n    ptr = next;\n  }\n  /* not reached */\n}\n\nstatic enum XML_Error\nstoreEntityValue(XML_Parser parser,\n                 const ENCODING *enc,\n                 const char *entityTextPtr,\n                 const char *entityTextEnd)\n{\n  DTD * const dtd = _dtd;  /* save one level of indirection */\n  STRING_POOL *pool = &(dtd->entityValuePool);\n  enum XML_Error result = XML_ERROR_NONE;\n#ifdef XML_DTD\n  int oldInEntityValue = prologState.inEntityValue;\n  prologState.inEntityValue = 1;\n#endif /* XML_DTD */\n  /* never return Null for the value argument in EntityDeclHandler,\n     since this would indicate an external entity; therefore we\n     have to make sure that entityValuePool.start is not null */\n  if (!pool->blocks) {\n    if (!poolGrow(pool))\n      return XML_ERROR_NO_MEMORY;\n  }\n\n  for (;;) {\n    const char *next;\n    int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);\n    switch (tok) {\n    case XML_TOK_PARAM_ENTITY_REF:\n#ifdef XML_DTD\n      if (isParamEntity || enc != encoding) {\n        const XML_Char *name;\n        ENTITY *entity;\n        name = poolStoreString(&tempPool, enc,\n                               entityTextPtr + enc->minBytesPerChar,\n                               next - enc->minBytesPerChar);\n        if (!name) {\n          result = XML_ERROR_NO_MEMORY;\n          goto endEntityValue;\n        }\n        entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);\n        poolDiscard(&tempPool);\n        if (!entity) {\n          /* not a well-formedness error - see XML 1.0: WFC Entity Declared */\n          /* cannot report skipped entity here - see comments on\n             skippedEntityHandler\n          if (skippedEntityHandler)\n            skippedEntityHandler(handlerArg, name, 0);\n          */\n          dtd->keepProcessing = dtd->standalone;\n          goto endEntityValue;\n        }\n        if (entity->open) {\n          if (enc == encoding)\n            eventPtr = entityTextPtr;\n          result = XML_ERROR_RECURSIVE_ENTITY_REF;\n          goto endEntityValue;\n        }\n        if (entity->systemId) {\n          if (externalEntityRefHandler) {\n            dtd->paramEntityRead = XML_FALSE;\n            entity->open = XML_TRUE;\n            if (!externalEntityRefHandler(externalEntityRefHandlerArg,\n                                          0,\n                                          entity->base,\n                                          entity->systemId,\n                                          entity->publicId)) {\n              entity->open = XML_FALSE;\n              result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;\n              goto endEntityValue;\n            }\n            entity->open = XML_FALSE;\n            if (!dtd->paramEntityRead)\n              dtd->keepProcessing = dtd->standalone;\n          }\n          else\n            dtd->keepProcessing = dtd->standalone;\n        }\n        else {\n          entity->open = XML_TRUE;\n          result = storeEntityValue(parser,\n                                    internalEncoding,\n                                    (char *)entity->textPtr,\n                                    (char *)(entity->textPtr\n                                             + entity->textLen));\n          entity->open = XML_FALSE;\n          if (result)\n            goto endEntityValue;\n        }\n        break;\n      }\n#endif /* XML_DTD */\n      /* In the internal subset, PE references are not legal\n         within markup declarations, e.g entity values in this case. */\n      eventPtr = entityTextPtr;\n      result = XML_ERROR_PARAM_ENTITY_REF;\n      goto endEntityValue;\n    case XML_TOK_NONE:\n      result = XML_ERROR_NONE;\n      goto endEntityValue;\n    case XML_TOK_ENTITY_REF:\n    case XML_TOK_DATA_CHARS:\n      if (!poolAppend(pool, enc, entityTextPtr, next)) {\n        result = XML_ERROR_NO_MEMORY;\n        goto endEntityValue;\n      }\n      break;\n    case XML_TOK_TRAILING_CR:\n      next = entityTextPtr + enc->minBytesPerChar;\n      /* fall through */\n    case XML_TOK_DATA_NEWLINE:\n      if (pool->end == pool->ptr && !poolGrow(pool)) {\n              result = XML_ERROR_NO_MEMORY;\n        goto endEntityValue;\n      }\n      *(pool->ptr)++ = 0xA;\n      break;\n    case XML_TOK_CHAR_REF:\n      {\n        XML_Char buf[XML_ENCODE_MAX];\n        int i;\n        int n = XmlCharRefNumber(enc, entityTextPtr);\n        if (n < 0) {\n          if (enc == encoding)\n            eventPtr = entityTextPtr;\n          result = XML_ERROR_BAD_CHAR_REF;\n          goto endEntityValue;\n        }\n        n = XmlEncode(n, (ICHAR *)buf);\n        if (!n) {\n          if (enc == encoding)\n            eventPtr = entityTextPtr;\n          result = XML_ERROR_BAD_CHAR_REF;\n          goto endEntityValue;\n        }\n        for (i = 0; i < n; i++) {\n          if (pool->end == pool->ptr && !poolGrow(pool)) {\n            result = XML_ERROR_NO_MEMORY;\n            goto endEntityValue;\n          }\n          *(pool->ptr)++ = buf[i];\n        }\n      }\n      break;\n    case XML_TOK_PARTIAL:\n      if (enc == encoding)\n        eventPtr = entityTextPtr;\n      result = XML_ERROR_INVALID_TOKEN;\n      goto endEntityValue;\n    case XML_TOK_INVALID:\n      if (enc == encoding)\n        eventPtr = next;\n      result = XML_ERROR_INVALID_TOKEN;\n      goto endEntityValue;\n    default:\n      if (enc == encoding)\n        eventPtr = entityTextPtr;\n      result = XML_ERROR_UNEXPECTED_STATE;\n      goto endEntityValue;\n    }\n    entityTextPtr = next;\n  }\nendEntityValue:\n#ifdef XML_DTD\n  prologState.inEntityValue = oldInEntityValue;\n#endif /* XML_DTD */\n  return result;\n}\n\nstatic void FASTCALL\nnormalizeLines(XML_Char *s)\n{\n  XML_Char *p;\n  for (;; s++) {\n    if (*s == XML_T('\\0'))\n      return;\n    if (*s == 0xD)\n      break;\n  }\n  p = s;\n  do {\n    if (*s == 0xD) {\n      *p++ = 0xA;\n      if (*++s == 0xA)\n        s++;\n    }\n    else\n      *p++ = *s++;\n  } while (*s);\n  *p = XML_T('\\0');\n}\n\nstatic int\nreportProcessingInstruction(XML_Parser parser, const ENCODING *enc,\n                            const char *start, const char *end)\n{\n  const XML_Char *target;\n  XML_Char *data;\n  const char *tem;\n  if (!processingInstructionHandler) {\n    if (defaultHandler)\n      reportDefault(parser, enc, start, end);\n    return 1;\n  }\n  start += enc->minBytesPerChar * 2;\n  tem = start + XmlNameLength(enc, start);\n  target = poolStoreString(&tempPool, enc, start, tem);\n  if (!target)\n    return 0;\n  poolFinish(&tempPool);\n  data = poolStoreString(&tempPool, enc,\n                        XmlSkipS(enc, tem),\n                        end - enc->minBytesPerChar*2);\n  if (!data)\n    return 0;\n  normalizeLines(data);\n  processingInstructionHandler(handlerArg, target, data);\n  poolClear(&tempPool);\n  return 1;\n}\n\nstatic int\nreportComment(XML_Parser parser, const ENCODING *enc,\n              const char *start, const char *end)\n{\n  XML_Char *data;\n  if (!commentHandler) {\n    if (defaultHandler)\n      reportDefault(parser, enc, start, end);\n    return 1;\n  }\n  data = poolStoreString(&tempPool,\n                         enc,\n                         start + enc->minBytesPerChar * 4,\n                         end - enc->minBytesPerChar * 3);\n  if (!data)\n    return 0;\n  normalizeLines(data);\n  commentHandler(handlerArg, data);\n  poolClear(&tempPool);\n  return 1;\n}\n\nstatic void\nreportDefault(XML_Parser parser, const ENCODING *enc,\n              const char *s, const char *end)\n{\n  if (MUST_CONVERT(enc, s)) {\n    enum XML_Convert_Result convert_res;\n    const char **eventPP;\n    const char **eventEndPP;\n    if (enc == encoding) {\n      eventPP = &eventPtr;\n      eventEndPP = &eventEndPtr;\n    }\n    else {\n      eventPP = &(openInternalEntities->internalEventPtr);\n      eventEndPP = &(openInternalEntities->internalEventEndPtr);\n    }\n    do {\n      ICHAR *dataPtr = (ICHAR *)dataBuf;\n      convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);\n      *eventEndPP = s;\n      defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));\n      *eventPP = s;\n    } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));\n  }\n  else\n    defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));\n}\n\n\nstatic int\ndefineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,\n                XML_Bool isId, const XML_Char *value, XML_Parser parser)\n{\n  DEFAULT_ATTRIBUTE *att;\n  if (value || isId) {\n    /* The handling of default attributes gets messed up if we have\n       a default which duplicates a non-default. */\n    int i;\n    for (i = 0; i < type->nDefaultAtts; i++)\n      if (attId == type->defaultAtts[i].id)\n        return 1;\n    if (isId && !type->idAtt && !attId->xmlns)\n      type->idAtt = attId;\n  }\n  if (type->nDefaultAtts == type->allocDefaultAtts) {\n    if (type->allocDefaultAtts == 0) {\n      type->allocDefaultAtts = 8;\n      type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts\n                            * sizeof(DEFAULT_ATTRIBUTE));\n      if (!type->defaultAtts)\n        return 0;\n    }\n    else {\n      DEFAULT_ATTRIBUTE *temp;\n      int count = type->allocDefaultAtts * 2;\n      temp = (DEFAULT_ATTRIBUTE *)\n        REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));\n      if (temp == NULL)\n        return 0;\n      type->allocDefaultAtts = count;\n      type->defaultAtts = temp;\n    }\n  }\n  att = type->defaultAtts + type->nDefaultAtts;\n  att->id = attId;\n  att->value = value;\n  att->isCdata = isCdata;\n  if (!isCdata)\n    attId->maybeTokenized = XML_TRUE;\n  type->nDefaultAtts += 1;\n  return 1;\n}\n\nstatic int\nsetElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)\n{\n  DTD * const dtd = _dtd;  /* save one level of indirection */\n  const XML_Char *name;\n  for (name = elementType->name; *name; name++) {\n    if (*name == XML_T(ASCII_COLON)) {\n      PREFIX *prefix;\n      const XML_Char *s;\n      for (s = elementType->name; s != name; s++) {\n        if (!poolAppendChar(&dtd->pool, *s))\n          return 0;\n      }\n      if (!poolAppendChar(&dtd->pool, XML_T('\\0')))\n        return 0;\n      prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),\n                                sizeof(PREFIX));\n      if (!prefix)\n        return 0;\n      if (prefix->name == poolStart(&dtd->pool))\n        poolFinish(&dtd->pool);\n      else\n        poolDiscard(&dtd->pool);\n      elementType->prefix = prefix;\n\n    }\n  }\n  return 1;\n}\n\nstatic ATTRIBUTE_ID *\ngetAttributeId(XML_Parser parser, const ENCODING *enc,\n               const char *start, const char *end)\n{\n  DTD * const dtd = _dtd;  /* save one level of indirection */\n  ATTRIBUTE_ID *id;\n  const XML_Char *name;\n  if (!poolAppendChar(&dtd->pool, XML_T('\\0')))\n    return NULL;\n  name = poolStoreString(&dtd->pool, enc, start, end);\n  if (!name)\n    return NULL;\n  /* skip quotation mark - its storage will be re-used (like in name[-1]) */\n  ++name;\n  id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));\n  if (!id)\n    return NULL;\n  if (id->name != name)\n    poolDiscard(&dtd->pool);\n  else {\n    poolFinish(&dtd->pool);\n    if (!ns)\n      ;\n    else if (name[0] == XML_T(ASCII_x)\n        && name[1] == XML_T(ASCII_m)\n        && name[2] == XML_T(ASCII_l)\n        && name[3] == XML_T(ASCII_n)\n        && name[4] == XML_T(ASCII_s)\n        && (name[5] == XML_T('\\0') || name[5] == XML_T(ASCII_COLON))) {\n      if (name[5] == XML_T('\\0'))\n        id->prefix = &dtd->defaultPrefix;\n      else\n        id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));\n      id->xmlns = XML_TRUE;\n    }\n    else {\n      int i;\n      for (i = 0; name[i]; i++) {\n        /* attributes without prefix are *not* in the default namespace */\n        if (name[i] == XML_T(ASCII_COLON)) {\n          int j;\n          for (j = 0; j < i; j++) {\n            if (!poolAppendChar(&dtd->pool, name[j]))\n              return NULL;\n          }\n          if (!poolAppendChar(&dtd->pool, XML_T('\\0')))\n            return NULL;\n          id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),\n                                        sizeof(PREFIX));\n          if (!id->prefix)\n            return NULL;\n          if (id->prefix->name == poolStart(&dtd->pool))\n            poolFinish(&dtd->pool);\n          else\n            poolDiscard(&dtd->pool);\n          break;\n        }\n      }\n    }\n  }\n  return id;\n}\n\n#define CONTEXT_SEP XML_T(ASCII_FF)\n\nstatic const XML_Char *\ngetContext(XML_Parser parser)\n{\n  DTD * const dtd = _dtd;  /* save one level of indirection */\n  HASH_TABLE_ITER iter;\n  XML_Bool needSep = XML_FALSE;\n\n  if (dtd->defaultPrefix.binding) {\n    int i;\n    int len;\n    if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))\n      return NULL;\n    len = dtd->defaultPrefix.binding->uriLen;\n    if (namespaceSeparator)\n      len--;\n    for (i = 0; i < len; i++)\n      if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))\n        return NULL;\n    needSep = XML_TRUE;\n  }\n\n  hashTableIterInit(&iter, &(dtd->prefixes));\n  for (;;) {\n    int i;\n    int len;\n    const XML_Char *s;\n    PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);\n    if (!prefix)\n      break;\n    if (!prefix->binding)\n      continue;\n    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))\n      return NULL;\n    for (s = prefix->name; *s; s++)\n      if (!poolAppendChar(&tempPool, *s))\n        return NULL;\n    if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))\n      return NULL;\n    len = prefix->binding->uriLen;\n    if (namespaceSeparator)\n      len--;\n    for (i = 0; i < len; i++)\n      if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))\n        return NULL;\n    needSep = XML_TRUE;\n  }\n\n\n  hashTableIterInit(&iter, &(dtd->generalEntities));\n  for (;;) {\n    const XML_Char *s;\n    ENTITY *e = (ENTITY *)hashTableIterNext(&iter);\n    if (!e)\n      break;\n    if (!e->open)\n      continue;\n    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))\n      return NULL;\n    for (s = e->name; *s; s++)\n      if (!poolAppendChar(&tempPool, *s))\n        return 0;\n    needSep = XML_TRUE;\n  }\n\n  if (!poolAppendChar(&tempPool, XML_T('\\0')))\n    return NULL;\n  return tempPool.start;\n}\n\nstatic XML_Bool\nsetContext(XML_Parser parser, const XML_Char *context)\n{\n  DTD * const dtd = _dtd;  /* save one level of indirection */\n  const XML_Char *s = context;\n\n  while (*context != XML_T('\\0')) {\n    if (*s == CONTEXT_SEP || *s == XML_T('\\0')) {\n      ENTITY *e;\n      if (!poolAppendChar(&tempPool, XML_T('\\0')))\n        return XML_FALSE;\n      e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);\n      if (e)\n        e->open = XML_TRUE;\n      if (*s != XML_T('\\0'))\n        s++;\n      context = s;\n      poolDiscard(&tempPool);\n    }\n    else if (*s == XML_T(ASCII_EQUALS)) {\n      PREFIX *prefix;\n      if (poolLength(&tempPool) == 0)\n        prefix = &dtd->defaultPrefix;\n      else {\n        if (!poolAppendChar(&tempPool, XML_T('\\0')))\n          return XML_FALSE;\n        prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),\n                                  sizeof(PREFIX));\n        if (!prefix)\n          return XML_FALSE;\n        if (prefix->name == poolStart(&tempPool)) {\n          prefix->name = poolCopyString(&dtd->pool, prefix->name);\n          if (!prefix->name)\n            return XML_FALSE;\n        }\n        poolDiscard(&tempPool);\n      }\n      for (context = s + 1;\n           *context != CONTEXT_SEP && *context != XML_T('\\0');\n           context++)\n        if (!poolAppendChar(&tempPool, *context))\n          return XML_FALSE;\n      if (!poolAppendChar(&tempPool, XML_T('\\0')))\n        return XML_FALSE;\n      if (addBinding(parser, prefix, NULL, poolStart(&tempPool),\n                     &inheritedBindings) != XML_ERROR_NONE)\n        return XML_FALSE;\n      poolDiscard(&tempPool);\n      if (*context != XML_T('\\0'))\n        ++context;\n      s = context;\n    }\n    else {\n      if (!poolAppendChar(&tempPool, *s))\n        return XML_FALSE;\n      s++;\n    }\n  }\n  return XML_TRUE;\n}\n\nstatic void FASTCALL\nnormalizePublicId(XML_Char *publicId)\n{\n  XML_Char *p = publicId;\n  XML_Char *s;\n  for (s = publicId; *s; s++) {\n    switch (*s) {\n    case 0x20:\n    case 0xD:\n    case 0xA:\n      if (p != publicId && p[-1] != 0x20)\n        *p++ = 0x20;\n      break;\n    default:\n      *p++ = *s;\n    }\n  }\n  if (p != publicId && p[-1] == 0x20)\n    --p;\n  *p = XML_T('\\0');\n}\n\nstatic DTD *\ndtdCreate(const XML_Memory_Handling_Suite *ms)\n{\n  DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));\n  if (p == NULL)\n    return p;\n  poolInit(&(p->pool), ms);\n  poolInit(&(p->entityValuePool), ms);\n  hashTableInit(&(p->generalEntities), ms);\n  hashTableInit(&(p->elementTypes), ms);\n  hashTableInit(&(p->attributeIds), ms);\n  hashTableInit(&(p->prefixes), ms);\n#ifdef XML_DTD\n  p->paramEntityRead = XML_FALSE;\n  hashTableInit(&(p->paramEntities), ms);\n#endif /* XML_DTD */\n  p->defaultPrefix.name = NULL;\n  p->defaultPrefix.binding = NULL;\n\n  p->in_eldecl = XML_FALSE;\n  p->scaffIndex = NULL;\n  p->scaffold = NULL;\n  p->scaffLevel = 0;\n  p->scaffSize = 0;\n  p->scaffCount = 0;\n  p->contentStringLen = 0;\n\n  p->keepProcessing = XML_TRUE;\n  p->hasParamEntityRefs = XML_FALSE;\n  p->standalone = XML_FALSE;\n  return p;\n}\n\nstatic void\ndtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)\n{\n  HASH_TABLE_ITER iter;\n  hashTableIterInit(&iter, &(p->elementTypes));\n  for (;;) {\n    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);\n    if (!e)\n      break;\n    if (e->allocDefaultAtts != 0)\n      ms->free_fcn(e->defaultAtts);\n  }\n  hashTableClear(&(p->generalEntities));\n#ifdef XML_DTD\n  p->paramEntityRead = XML_FALSE;\n  hashTableClear(&(p->paramEntities));\n#endif /* XML_DTD */\n  hashTableClear(&(p->elementTypes));\n  hashTableClear(&(p->attributeIds));\n  hashTableClear(&(p->prefixes));\n  poolClear(&(p->pool));\n  poolClear(&(p->entityValuePool));\n  p->defaultPrefix.name = NULL;\n  p->defaultPrefix.binding = NULL;\n\n  p->in_eldecl = XML_FALSE;\n\n  ms->free_fcn(p->scaffIndex);\n  p->scaffIndex = NULL;\n  ms->free_fcn(p->scaffold);\n  p->scaffold = NULL;\n\n  p->scaffLevel = 0;\n  p->scaffSize = 0;\n  p->scaffCount = 0;\n  p->contentStringLen = 0;\n\n  p->keepProcessing = XML_TRUE;\n  p->hasParamEntityRefs = XML_FALSE;\n  p->standalone = XML_FALSE;\n}\n\nstatic void\ndtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)\n{\n  HASH_TABLE_ITER iter;\n  hashTableIterInit(&iter, &(p->elementTypes));\n  for (;;) {\n    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);\n    if (!e)\n      break;\n    if (e->allocDefaultAtts != 0)\n      ms->free_fcn(e->defaultAtts);\n  }\n  hashTableDestroy(&(p->generalEntities));\n#ifdef XML_DTD\n  hashTableDestroy(&(p->paramEntities));\n#endif /* XML_DTD */\n  hashTableDestroy(&(p->elementTypes));\n  hashTableDestroy(&(p->attributeIds));\n  hashTableDestroy(&(p->prefixes));\n  poolDestroy(&(p->pool));\n  poolDestroy(&(p->entityValuePool));\n  if (isDocEntity) {\n    ms->free_fcn(p->scaffIndex);\n    ms->free_fcn(p->scaffold);\n  }\n  ms->free_fcn(p);\n}\n\n/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.\n   The new DTD has already been initialized.\n*/\nstatic int\ndtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)\n{\n  HASH_TABLE_ITER iter;\n\n  /* Copy the prefix table. */\n\n  hashTableIterInit(&iter, &(oldDtd->prefixes));\n  for (;;) {\n    const XML_Char *name;\n    const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);\n    if (!oldP)\n      break;\n    name = poolCopyString(&(newDtd->pool), oldP->name);\n    if (!name)\n      return 0;\n    if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))\n      return 0;\n  }\n\n  hashTableIterInit(&iter, &(oldDtd->attributeIds));\n\n  /* Copy the attribute id table. */\n\n  for (;;) {\n    ATTRIBUTE_ID *newA;\n    const XML_Char *name;\n    const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);\n\n    if (!oldA)\n      break;\n    /* Remember to allocate the scratch byte before the name. */\n    if (!poolAppendChar(&(newDtd->pool), XML_T('\\0')))\n      return 0;\n    name = poolCopyString(&(newDtd->pool), oldA->name);\n    if (!name)\n      return 0;\n    ++name;\n    newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,\n                                  sizeof(ATTRIBUTE_ID));\n    if (!newA)\n      return 0;\n    newA->maybeTokenized = oldA->maybeTokenized;\n    if (oldA->prefix) {\n      newA->xmlns = oldA->xmlns;\n      if (oldA->prefix == &oldDtd->defaultPrefix)\n        newA->prefix = &newDtd->defaultPrefix;\n      else\n        newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),\n                                        oldA->prefix->name, 0);\n    }\n  }\n\n  /* Copy the element type table. */\n\n  hashTableIterInit(&iter, &(oldDtd->elementTypes));\n\n  for (;;) {\n    int i;\n    ELEMENT_TYPE *newE;\n    const XML_Char *name;\n    const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);\n    if (!oldE)\n      break;\n    name = poolCopyString(&(newDtd->pool), oldE->name);\n    if (!name)\n      return 0;\n    newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,\n                                  sizeof(ELEMENT_TYPE));\n    if (!newE)\n      return 0;\n    if (oldE->nDefaultAtts) {\n      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)\n          ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));\n      if (!newE->defaultAtts) {\n        ms->free_fcn(newE);\n        return 0;\n      }\n    }\n    if (oldE->idAtt)\n      newE->idAtt = (ATTRIBUTE_ID *)\n          lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);\n    newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;\n    if (oldE->prefix)\n      newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),\n                                      oldE->prefix->name, 0);\n    for (i = 0; i < newE->nDefaultAtts; i++) {\n      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)\n          lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);\n      newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;\n      if (oldE->defaultAtts[i].value) {\n        newE->defaultAtts[i].value\n            = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);\n        if (!newE->defaultAtts[i].value)\n          return 0;\n      }\n      else\n        newE->defaultAtts[i].value = NULL;\n    }\n  }\n\n  /* Copy the entity tables. */\n  if (!copyEntityTable(oldParser,\n                       &(newDtd->generalEntities),\n                       &(newDtd->pool),\n                       &(oldDtd->generalEntities)))\n      return 0;\n\n#ifdef XML_DTD\n  if (!copyEntityTable(oldParser,\n                       &(newDtd->paramEntities),\n                       &(newDtd->pool),\n                       &(oldDtd->paramEntities)))\n      return 0;\n  newDtd->paramEntityRead = oldDtd->paramEntityRead;\n#endif /* XML_DTD */\n\n  newDtd->keepProcessing = oldDtd->keepProcessing;\n  newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;\n  newDtd->standalone = oldDtd->standalone;\n\n  /* Don't want deep copying for scaffolding */\n  newDtd->in_eldecl = oldDtd->in_eldecl;\n  newDtd->scaffold = oldDtd->scaffold;\n  newDtd->contentStringLen = oldDtd->contentStringLen;\n  newDtd->scaffSize = oldDtd->scaffSize;\n  newDtd->scaffLevel = oldDtd->scaffLevel;\n  newDtd->scaffIndex = oldDtd->scaffIndex;\n\n  return 1;\n}  /* End dtdCopy */\n\nstatic int\ncopyEntityTable(XML_Parser oldParser,\n                HASH_TABLE *newTable,\n                STRING_POOL *newPool,\n                const HASH_TABLE *oldTable)\n{\n  HASH_TABLE_ITER iter;\n  const XML_Char *cachedOldBase = NULL;\n  const XML_Char *cachedNewBase = NULL;\n\n  hashTableIterInit(&iter, oldTable);\n\n  for (;;) {\n    ENTITY *newE;\n    const XML_Char *name;\n    const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);\n    if (!oldE)\n      break;\n    name = poolCopyString(newPool, oldE->name);\n    if (!name)\n      return 0;\n    newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));\n    if (!newE)\n      return 0;\n    if (oldE->systemId) {\n      const XML_Char *tem = poolCopyString(newPool, oldE->systemId);\n      if (!tem)\n        return 0;\n      newE->systemId = tem;\n      if (oldE->base) {\n        if (oldE->base == cachedOldBase)\n          newE->base = cachedNewBase;\n        else {\n          cachedOldBase = oldE->base;\n          tem = poolCopyString(newPool, cachedOldBase);\n          if (!tem)\n            return 0;\n          cachedNewBase = newE->base = tem;\n        }\n      }\n      if (oldE->publicId) {\n        tem = poolCopyString(newPool, oldE->publicId);\n        if (!tem)\n          return 0;\n        newE->publicId = tem;\n      }\n    }\n    else {\n      const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,\n                                            oldE->textLen);\n      if (!tem)\n        return 0;\n      newE->textPtr = tem;\n      newE->textLen = oldE->textLen;\n    }\n    if (oldE->notation) {\n      const XML_Char *tem = poolCopyString(newPool, oldE->notation);\n      if (!tem)\n        return 0;\n      newE->notation = tem;\n    }\n    newE->is_param = oldE->is_param;\n    newE->is_internal = oldE->is_internal;\n  }\n  return 1;\n}\n\n#define INIT_POWER 6\n\nstatic XML_Bool FASTCALL\nkeyeq(KEY s1, KEY s2)\n{\n  for (; *s1 == *s2; s1++, s2++)\n    if (*s1 == 0)\n      return XML_TRUE;\n  return XML_FALSE;\n}\n\nstatic unsigned long FASTCALL\nhash(XML_Parser parser, KEY s)\n{\n  unsigned long h = hash_secret_salt;\n  while (*s)\n    h = CHAR_HASH(h, *s++);\n  return h;\n}\n\nstatic NAMED *\nlookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)\n{\n  size_t i;\n  if (table->size == 0) {\n    size_t tsize;\n    if (!createSize)\n      return NULL;\n    table->power = INIT_POWER;\n    /* table->size is a power of 2 */\n    table->size = (size_t)1 << INIT_POWER;\n    tsize = table->size * sizeof(NAMED *);\n    table->v = (NAMED **)table->mem->malloc_fcn(tsize);\n    if (!table->v) {\n      table->size = 0;\n      return NULL;\n    }\n    memset(table->v, 0, tsize);\n    i = hash(parser, name) & ((unsigned long)table->size - 1);\n  }\n  else {\n    unsigned long h = hash(parser, name);\n    unsigned long mask = (unsigned long)table->size - 1;\n    unsigned char step = 0;\n    i = h & mask;\n    while (table->v[i]) {\n      if (keyeq(name, table->v[i]->name))\n        return table->v[i];\n      if (!step)\n        step = PROBE_STEP(h, mask, table->power);\n      i < step ? (i += table->size - step) : (i -= step);\n    }\n    if (!createSize)\n      return NULL;\n\n    /* check for overflow (table is half full) */\n    if (table->used >> (table->power - 1)) {\n      unsigned char newPower = table->power + 1;\n      size_t newSize = (size_t)1 << newPower;\n      unsigned long newMask = (unsigned long)newSize - 1;\n      size_t tsize = newSize * sizeof(NAMED *);\n      NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);\n      if (!newV)\n        return NULL;\n      memset(newV, 0, tsize);\n      for (i = 0; i < table->size; i++)\n        if (table->v[i]) {\n          unsigned long newHash = hash(parser, table->v[i]->name);\n          size_t j = newHash & newMask;\n          step = 0;\n          while (newV[j]) {\n            if (!step)\n              step = PROBE_STEP(newHash, newMask, newPower);\n            j < step ? (j += newSize - step) : (j -= step);\n          }\n          newV[j] = table->v[i];\n        }\n      table->mem->free_fcn(table->v);\n      table->v = newV;\n      table->power = newPower;\n      table->size = newSize;\n      i = h & newMask;\n      step = 0;\n      while (table->v[i]) {\n        if (!step)\n          step = PROBE_STEP(h, newMask, newPower);\n        i < step ? (i += newSize - step) : (i -= step);\n      }\n    }\n  }\n  table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);\n  if (!table->v[i])\n    return NULL;\n  memset(table->v[i], 0, createSize);\n  table->v[i]->name = name;\n  (table->used)++;\n  return table->v[i];\n}\n\nstatic void FASTCALL\nhashTableClear(HASH_TABLE *table)\n{\n  size_t i;\n  for (i = 0; i < table->size; i++) {\n    table->mem->free_fcn(table->v[i]);\n    table->v[i] = NULL;\n  }\n  table->used = 0;\n}\n\nstatic void FASTCALL\nhashTableDestroy(HASH_TABLE *table)\n{\n  size_t i;\n  for (i = 0; i < table->size; i++)\n    table->mem->free_fcn(table->v[i]);\n  table->mem->free_fcn(table->v);\n}\n\nstatic void FASTCALL\nhashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)\n{\n  p->power = 0;\n  p->size = 0;\n  p->used = 0;\n  p->v = NULL;\n  p->mem = ms;\n}\n\nstatic void FASTCALL\nhashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)\n{\n  iter->p = table->v;\n  iter->end = iter->p + table->size;\n}\n\nstatic NAMED * FASTCALL\nhashTableIterNext(HASH_TABLE_ITER *iter)\n{\n  while (iter->p != iter->end) {\n    NAMED *tem = *(iter->p)++;\n    if (tem)\n      return tem;\n  }\n  return NULL;\n}\n\nstatic void FASTCALL\npoolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)\n{\n  pool->blocks = NULL;\n  pool->freeBlocks = NULL;\n  pool->start = NULL;\n  pool->ptr = NULL;\n  pool->end = NULL;\n  pool->mem = ms;\n}\n\nstatic void FASTCALL\npoolClear(STRING_POOL *pool)\n{\n  if (!pool->freeBlocks)\n    pool->freeBlocks = pool->blocks;\n  else {\n    BLOCK *p = pool->blocks;\n    while (p) {\n      BLOCK *tem = p->next;\n      p->next = pool->freeBlocks;\n      pool->freeBlocks = p;\n      p = tem;\n    }\n  }\n  pool->blocks = NULL;\n  pool->start = NULL;\n  pool->ptr = NULL;\n  pool->end = NULL;\n}\n\nstatic void FASTCALL\npoolDestroy(STRING_POOL *pool)\n{\n  BLOCK *p = pool->blocks;\n  while (p) {\n    BLOCK *tem = p->next;\n    pool->mem->free_fcn(p);\n    p = tem;\n  }\n  p = pool->freeBlocks;\n  while (p) {\n    BLOCK *tem = p->next;\n    pool->mem->free_fcn(p);\n    p = tem;\n  }\n}\n\nstatic XML_Char *\npoolAppend(STRING_POOL *pool, const ENCODING *enc,\n           const char *ptr, const char *end)\n{\n  if (!pool->ptr && !poolGrow(pool))\n    return NULL;\n  for (;;) {\n    const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);\n    if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))\n      break;\n    if (!poolGrow(pool))\n      return NULL;\n  }\n  return pool->start;\n}\n\nstatic const XML_Char * FASTCALL\npoolCopyString(STRING_POOL *pool, const XML_Char *s)\n{\n  do {\n    if (!poolAppendChar(pool, *s))\n      return NULL;\n  } while (*s++);\n  s = pool->start;\n  poolFinish(pool);\n  return s;\n}\n\nstatic const XML_Char *\npoolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)\n{\n  if (!pool->ptr && !poolGrow(pool))\n    return NULL;\n  for (; n > 0; --n, s++) {\n    if (!poolAppendChar(pool, *s))\n      return NULL;\n  }\n  s = pool->start;\n  poolFinish(pool);\n  return s;\n}\n\nstatic const XML_Char * FASTCALL\npoolAppendString(STRING_POOL *pool, const XML_Char *s)\n{\n  while (*s) {\n    if (!poolAppendChar(pool, *s))\n      return NULL;\n    s++;\n  }\n  return pool->start;\n}\n\nstatic XML_Char *\npoolStoreString(STRING_POOL *pool, const ENCODING *enc,\n                const char *ptr, const char *end)\n{\n  if (!poolAppend(pool, enc, ptr, end))\n    return NULL;\n  if (pool->ptr == pool->end && !poolGrow(pool))\n    return NULL;\n  *(pool->ptr)++ = 0;\n  return pool->start;\n}\n\nstatic XML_Bool FASTCALL\npoolGrow(STRING_POOL *pool)\n{\n  if (pool->freeBlocks) {\n    if (pool->start == 0) {\n      pool->blocks = pool->freeBlocks;\n      pool->freeBlocks = pool->freeBlocks->next;\n      pool->blocks->next = NULL;\n      pool->start = pool->blocks->s;\n      pool->end = pool->start + pool->blocks->size;\n      pool->ptr = pool->start;\n      return XML_TRUE;\n    }\n    if (pool->end - pool->start < pool->freeBlocks->size) {\n      BLOCK *tem = pool->freeBlocks->next;\n      pool->freeBlocks->next = pool->blocks;\n      pool->blocks = pool->freeBlocks;\n      pool->freeBlocks = tem;\n      memcpy(pool->blocks->s, pool->start,\n             (pool->end - pool->start) * sizeof(XML_Char));\n      pool->ptr = pool->blocks->s + (pool->ptr - pool->start);\n      pool->start = pool->blocks->s;\n      pool->end = pool->start + pool->blocks->size;\n      return XML_TRUE;\n    }\n  }\n  if (pool->blocks && pool->start == pool->blocks->s) {\n    BLOCK *temp;\n    int blockSize = (int)(pool->end - pool->start)*2;\n\n    if (blockSize < 0)\n      return XML_FALSE;\n\n    temp = (BLOCK *)\n      pool->mem->realloc_fcn(pool->blocks,\n                             (offsetof(BLOCK, s)\n                              + blockSize * sizeof(XML_Char)));\n    if (temp == NULL)\n      return XML_FALSE;\n    pool->blocks = temp;\n    pool->blocks->size = blockSize;\n    pool->ptr = pool->blocks->s + (pool->ptr - pool->start);\n    pool->start = pool->blocks->s;\n    pool->end = pool->start + blockSize;\n  }\n  else {\n    BLOCK *tem;\n    int blockSize = (int)(pool->end - pool->start);\n\n    if (blockSize < 0)\n      return XML_FALSE;\n\n    if (blockSize < INIT_BLOCK_SIZE)\n      blockSize = INIT_BLOCK_SIZE;\n    else\n      blockSize *= 2;\n    tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)\n                                        + blockSize * sizeof(XML_Char));\n    if (!tem)\n      return XML_FALSE;\n    tem->size = blockSize;\n    tem->next = pool->blocks;\n    pool->blocks = tem;\n    if (pool->ptr != pool->start)\n      memcpy(tem->s, pool->start,\n             (pool->ptr - pool->start) * sizeof(XML_Char));\n    pool->ptr = tem->s + (pool->ptr - pool->start);\n    pool->start = tem->s;\n    pool->end = tem->s + blockSize;\n  }\n  return XML_TRUE;\n}\n\nstatic int FASTCALL\nnextScaffoldPart(XML_Parser parser)\n{\n  DTD * const dtd = _dtd;  /* save one level of indirection */\n  CONTENT_SCAFFOLD * me;\n  int next;\n\n  if (!dtd->scaffIndex) {\n    dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));\n    if (!dtd->scaffIndex)\n      return -1;\n    dtd->scaffIndex[0] = 0;\n  }\n\n  if (dtd->scaffCount >= dtd->scaffSize) {\n    CONTENT_SCAFFOLD *temp;\n    if (dtd->scaffold) {\n      temp = (CONTENT_SCAFFOLD *)\n        REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));\n      if (temp == NULL)\n        return -1;\n      dtd->scaffSize *= 2;\n    }\n    else {\n      temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS\n                                        * sizeof(CONTENT_SCAFFOLD));\n      if (temp == NULL)\n        return -1;\n      dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;\n    }\n    dtd->scaffold = temp;\n  }\n  next = dtd->scaffCount++;\n  me = &dtd->scaffold[next];\n  if (dtd->scaffLevel) {\n    CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];\n    if (parent->lastchild) {\n      dtd->scaffold[parent->lastchild].nextsib = next;\n    }\n    if (!parent->childcnt)\n      parent->firstchild = next;\n    parent->lastchild = next;\n    parent->childcnt++;\n  }\n  me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;\n  return next;\n}\n\nstatic void\nbuild_node(XML_Parser parser,\n           int src_node,\n           XML_Content *dest,\n           XML_Content **contpos,\n           XML_Char **strpos)\n{\n  DTD * const dtd = _dtd;  /* save one level of indirection */\n  dest->type = dtd->scaffold[src_node].type;\n  dest->quant = dtd->scaffold[src_node].quant;\n  if (dest->type == XML_CTYPE_NAME) {\n    const XML_Char *src;\n    dest->name = *strpos;\n    src = dtd->scaffold[src_node].name;\n    for (;;) {\n      *(*strpos)++ = *src;\n      if (!*src)\n        break;\n      src++;\n    }\n    dest->numchildren = 0;\n    dest->children = NULL;\n  }\n  else {\n    unsigned int i;\n    int cn;\n    dest->numchildren = dtd->scaffold[src_node].childcnt;\n    dest->children = *contpos;\n    *contpos += dest->numchildren;\n    for (i = 0, cn = dtd->scaffold[src_node].firstchild;\n         i < dest->numchildren;\n         i++, cn = dtd->scaffold[cn].nextsib) {\n      build_node(parser, cn, &(dest->children[i]), contpos, strpos);\n    }\n    dest->name = NULL;\n  }\n}\n\nstatic XML_Content *\nbuild_model (XML_Parser parser)\n{\n  DTD * const dtd = _dtd;  /* save one level of indirection */\n  XML_Content *ret;\n  XML_Content *cpos;\n  XML_Char * str;\n  int allocsize = (dtd->scaffCount * sizeof(XML_Content)\n                   + (dtd->contentStringLen * sizeof(XML_Char)));\n\n  ret = (XML_Content *)MALLOC(allocsize);\n  if (!ret)\n    return NULL;\n\n  str =  (XML_Char *) (&ret[dtd->scaffCount]);\n  cpos = &ret[1];\n\n  build_node(parser, 0, ret, &cpos, &str);\n  return ret;\n}\n\nstatic ELEMENT_TYPE *\ngetElementType(XML_Parser parser,\n               const ENCODING *enc,\n               const char *ptr,\n               const char *end)\n{\n  DTD * const dtd = _dtd;  /* save one level of indirection */\n  const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);\n  ELEMENT_TYPE *ret;\n\n  if (!name)\n    return NULL;\n  ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));\n  if (!ret)\n    return NULL;\n  if (ret->name != name)\n    poolDiscard(&dtd->pool);\n  else {\n    poolFinish(&dtd->pool);\n    if (!setElementTypePrefix(parser, ret))\n      return NULL;\n  }\n  return ret;\n}\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/xmlrole.c",
    "content": "/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd\n   See the file COPYING for copying permission.\n*/\n\n#include <stddef.h>\n\n#ifdef COMPILED_FROM_DSP\n#include \"winconfig.h\"\n#elif defined(MACOS_CLASSIC)\n#include \"macconfig.h\"\n#elif defined(__amigaos__)\n#include \"amigaconfig.h\"\n#elif defined(__WATCOMC__)\n#include \"watcomconfig.h\"\n#else\n#ifdef HAVE_EXPAT_CONFIG_H\n#include <expat_config.h>\n#endif\n#endif /* ndef COMPILED_FROM_DSP */\n\n#include \"expat_external.h\"\n#include \"internal.h\"\n#include \"xmlrole.h\"\n#include \"ascii.h\"\n\n/* Doesn't check:\n\n that ,| are not mixed in a model group\n content of literals\n\n*/\n\nstatic const char KW_ANY[] = {\n    ASCII_A, ASCII_N, ASCII_Y, '\\0' };\nstatic const char KW_ATTLIST[] = {\n    ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\\0' };\nstatic const char KW_CDATA[] = {\n    ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\\0' };\nstatic const char KW_DOCTYPE[] = {\n    ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\\0' };\nstatic const char KW_ELEMENT[] = {\n    ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\\0' };\nstatic const char KW_EMPTY[] = {\n    ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\\0' };\nstatic const char KW_ENTITIES[] = {\n    ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S,\n    '\\0' };\nstatic const char KW_ENTITY[] = {\n    ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\\0' };\nstatic const char KW_FIXED[] = {\n    ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\\0' };\nstatic const char KW_ID[] = {\n    ASCII_I, ASCII_D, '\\0' };\nstatic const char KW_IDREF[] = {\n    ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\\0' };\nstatic const char KW_IDREFS[] = {\n    ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\\0' };\n#ifdef XML_DTD\nstatic const char KW_IGNORE[] = {\n    ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\\0' };\n#endif\nstatic const char KW_IMPLIED[] = {\n    ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\\0' };\n#ifdef XML_DTD\nstatic const char KW_INCLUDE[] = {\n    ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\\0' };\n#endif\nstatic const char KW_NDATA[] = {\n    ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\\0' };\nstatic const char KW_NMTOKEN[] = {\n    ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\\0' };\nstatic const char KW_NMTOKENS[] = {\n    ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S,\n    '\\0' };\nstatic const char KW_NOTATION[] =\n    { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N,\n      '\\0' };\nstatic const char KW_PCDATA[] = {\n    ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\\0' };\nstatic const char KW_PUBLIC[] = {\n    ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\\0' };\nstatic const char KW_REQUIRED[] = {\n    ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D,\n    '\\0' };\nstatic const char KW_SYSTEM[] = {\n    ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\\0' };\n\n#ifndef MIN_BYTES_PER_CHAR\n#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)\n#endif\n\n#ifdef XML_DTD\n#define setTopLevel(state) \\\n  ((state)->handler = ((state)->documentEntity \\\n                       ? internalSubset \\\n                       : externalSubset1))\n#else /* not XML_DTD */\n#define setTopLevel(state) ((state)->handler = internalSubset)\n#endif /* not XML_DTD */\n\ntypedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state,\n                                   int tok,\n                                   const char *ptr,\n                                   const char *end,\n                                   const ENCODING *enc);\n\nstatic PROLOG_HANDLER\n  prolog0, prolog1, prolog2,\n  doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,\n  internalSubset,\n  entity0, entity1, entity2, entity3, entity4, entity5, entity6,\n  entity7, entity8, entity9, entity10,\n  notation0, notation1, notation2, notation3, notation4,\n  attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,\n  attlist7, attlist8, attlist9,\n  element0, element1, element2, element3, element4, element5, element6,\n  element7,\n#ifdef XML_DTD\n  externalSubset0, externalSubset1,\n  condSect0, condSect1, condSect2,\n#endif /* XML_DTD */\n  declClose,\n  error;\n\nstatic int FASTCALL common(PROLOG_STATE *state, int tok);\n\nstatic int PTRCALL\nprolog0(PROLOG_STATE *state,\n        int tok,\n        const char *ptr,\n        const char *end,\n        const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    state->handler = prolog1;\n    return XML_ROLE_NONE;\n  case XML_TOK_XML_DECL:\n    state->handler = prolog1;\n    return XML_ROLE_XML_DECL;\n  case XML_TOK_PI:\n    state->handler = prolog1;\n    return XML_ROLE_PI;\n  case XML_TOK_COMMENT:\n    state->handler = prolog1;\n    return XML_ROLE_COMMENT;\n  case XML_TOK_BOM:\n    return XML_ROLE_NONE;\n  case XML_TOK_DECL_OPEN:\n    if (!XmlNameMatchesAscii(enc,\n                             ptr + 2 * MIN_BYTES_PER_CHAR(enc),\n                             end,\n                             KW_DOCTYPE))\n      break;\n    state->handler = doctype0;\n    return XML_ROLE_DOCTYPE_NONE;\n  case XML_TOK_INSTANCE_START:\n    state->handler = error;\n    return XML_ROLE_INSTANCE_START;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nprolog1(PROLOG_STATE *state,\n        int tok,\n        const char *ptr,\n        const char *end,\n        const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_NONE;\n  case XML_TOK_PI:\n    return XML_ROLE_PI;\n  case XML_TOK_COMMENT:\n    return XML_ROLE_COMMENT;\n  case XML_TOK_BOM:\n    return XML_ROLE_NONE;\n  case XML_TOK_DECL_OPEN:\n    if (!XmlNameMatchesAscii(enc,\n                             ptr + 2 * MIN_BYTES_PER_CHAR(enc),\n                             end,\n                             KW_DOCTYPE))\n      break;\n    state->handler = doctype0;\n    return XML_ROLE_DOCTYPE_NONE;\n  case XML_TOK_INSTANCE_START:\n    state->handler = error;\n    return XML_ROLE_INSTANCE_START;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nprolog2(PROLOG_STATE *state,\n        int tok,\n        const char *ptr,\n        const char *end,\n        const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_NONE;\n  case XML_TOK_PI:\n    return XML_ROLE_PI;\n  case XML_TOK_COMMENT:\n    return XML_ROLE_COMMENT;\n  case XML_TOK_INSTANCE_START:\n    state->handler = error;\n    return XML_ROLE_INSTANCE_START;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\ndoctype0(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_DOCTYPE_NONE;\n  case XML_TOK_NAME:\n  case XML_TOK_PREFIXED_NAME:\n    state->handler = doctype1;\n    return XML_ROLE_DOCTYPE_NAME;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\ndoctype1(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_DOCTYPE_NONE;\n  case XML_TOK_OPEN_BRACKET:\n    state->handler = internalSubset;\n    return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;\n  case XML_TOK_DECL_CLOSE:\n    state->handler = prolog2;\n    return XML_ROLE_DOCTYPE_CLOSE;\n  case XML_TOK_NAME:\n    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {\n      state->handler = doctype3;\n      return XML_ROLE_DOCTYPE_NONE;\n    }\n    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {\n      state->handler = doctype2;\n      return XML_ROLE_DOCTYPE_NONE;\n    }\n    break;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\ndoctype2(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_DOCTYPE_NONE;\n  case XML_TOK_LITERAL:\n    state->handler = doctype3;\n    return XML_ROLE_DOCTYPE_PUBLIC_ID;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\ndoctype3(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_DOCTYPE_NONE;\n  case XML_TOK_LITERAL:\n    state->handler = doctype4;\n    return XML_ROLE_DOCTYPE_SYSTEM_ID;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\ndoctype4(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_DOCTYPE_NONE;\n  case XML_TOK_OPEN_BRACKET:\n    state->handler = internalSubset;\n    return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;\n  case XML_TOK_DECL_CLOSE:\n    state->handler = prolog2;\n    return XML_ROLE_DOCTYPE_CLOSE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\ndoctype5(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_DOCTYPE_NONE;\n  case XML_TOK_DECL_CLOSE:\n    state->handler = prolog2;\n    return XML_ROLE_DOCTYPE_CLOSE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\ninternalSubset(PROLOG_STATE *state,\n               int tok,\n               const char *ptr,\n               const char *end,\n               const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_NONE;\n  case XML_TOK_DECL_OPEN:\n    if (XmlNameMatchesAscii(enc,\n                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),\n                            end,\n                            KW_ENTITY)) {\n      state->handler = entity0;\n      return XML_ROLE_ENTITY_NONE;\n    }\n    if (XmlNameMatchesAscii(enc,\n                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),\n                            end,\n                            KW_ATTLIST)) {\n      state->handler = attlist0;\n      return XML_ROLE_ATTLIST_NONE;\n    }\n    if (XmlNameMatchesAscii(enc,\n                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),\n                            end,\n                            KW_ELEMENT)) {\n      state->handler = element0;\n      return XML_ROLE_ELEMENT_NONE;\n    }\n    if (XmlNameMatchesAscii(enc,\n                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),\n                            end,\n                            KW_NOTATION)) {\n      state->handler = notation0;\n      return XML_ROLE_NOTATION_NONE;\n    }\n    break;\n  case XML_TOK_PI:\n    return XML_ROLE_PI;\n  case XML_TOK_COMMENT:\n    return XML_ROLE_COMMENT;\n  case XML_TOK_PARAM_ENTITY_REF:\n    return XML_ROLE_PARAM_ENTITY_REF;\n  case XML_TOK_CLOSE_BRACKET:\n    state->handler = doctype5;\n    return XML_ROLE_DOCTYPE_NONE;\n  case XML_TOK_NONE:\n    return XML_ROLE_NONE;\n  }\n  return common(state, tok);\n}\n\n#ifdef XML_DTD\n\nstatic int PTRCALL\nexternalSubset0(PROLOG_STATE *state,\n                int tok,\n                const char *ptr,\n                const char *end,\n                const ENCODING *enc)\n{\n  state->handler = externalSubset1;\n  if (tok == XML_TOK_XML_DECL)\n    return XML_ROLE_TEXT_DECL;\n  return externalSubset1(state, tok, ptr, end, enc);\n}\n\nstatic int PTRCALL\nexternalSubset1(PROLOG_STATE *state,\n                int tok,\n                const char *ptr,\n                const char *end,\n                const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_COND_SECT_OPEN:\n    state->handler = condSect0;\n    return XML_ROLE_NONE;\n  case XML_TOK_COND_SECT_CLOSE:\n    if (state->includeLevel == 0)\n      break;\n    state->includeLevel -= 1;\n    return XML_ROLE_NONE;\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_NONE;\n  case XML_TOK_CLOSE_BRACKET:\n    break;\n  case XML_TOK_NONE:\n    if (state->includeLevel)\n      break;\n    return XML_ROLE_NONE;\n  default:\n    return internalSubset(state, tok, ptr, end, enc);\n  }\n  return common(state, tok);\n}\n\n#endif /* XML_DTD */\n\nstatic int PTRCALL\nentity0(PROLOG_STATE *state,\n        int tok,\n        const char *ptr,\n        const char *end,\n        const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ENTITY_NONE;\n  case XML_TOK_PERCENT:\n    state->handler = entity1;\n    return XML_ROLE_ENTITY_NONE;\n  case XML_TOK_NAME:\n    state->handler = entity2;\n    return XML_ROLE_GENERAL_ENTITY_NAME;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nentity1(PROLOG_STATE *state,\n        int tok,\n        const char *ptr,\n        const char *end,\n        const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ENTITY_NONE;\n  case XML_TOK_NAME:\n    state->handler = entity7;\n    return XML_ROLE_PARAM_ENTITY_NAME;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nentity2(PROLOG_STATE *state,\n        int tok,\n        const char *ptr,\n        const char *end,\n        const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ENTITY_NONE;\n  case XML_TOK_NAME:\n    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {\n      state->handler = entity4;\n      return XML_ROLE_ENTITY_NONE;\n    }\n    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {\n      state->handler = entity3;\n      return XML_ROLE_ENTITY_NONE;\n    }\n    break;\n  case XML_TOK_LITERAL:\n    state->handler = declClose;\n    state->role_none = XML_ROLE_ENTITY_NONE;\n    return XML_ROLE_ENTITY_VALUE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nentity3(PROLOG_STATE *state,\n        int tok,\n        const char *ptr,\n        const char *end,\n        const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ENTITY_NONE;\n  case XML_TOK_LITERAL:\n    state->handler = entity4;\n    return XML_ROLE_ENTITY_PUBLIC_ID;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nentity4(PROLOG_STATE *state,\n        int tok,\n        const char *ptr,\n        const char *end,\n        const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ENTITY_NONE;\n  case XML_TOK_LITERAL:\n    state->handler = entity5;\n    return XML_ROLE_ENTITY_SYSTEM_ID;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nentity5(PROLOG_STATE *state,\n        int tok,\n        const char *ptr,\n        const char *end,\n        const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ENTITY_NONE;\n  case XML_TOK_DECL_CLOSE:\n    setTopLevel(state);\n    return XML_ROLE_ENTITY_COMPLETE;\n  case XML_TOK_NAME:\n    if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) {\n      state->handler = entity6;\n      return XML_ROLE_ENTITY_NONE;\n    }\n    break;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nentity6(PROLOG_STATE *state,\n        int tok,\n        const char *ptr,\n        const char *end,\n        const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ENTITY_NONE;\n  case XML_TOK_NAME:\n    state->handler = declClose;\n    state->role_none = XML_ROLE_ENTITY_NONE;\n    return XML_ROLE_ENTITY_NOTATION_NAME;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nentity7(PROLOG_STATE *state,\n        int tok,\n        const char *ptr,\n        const char *end,\n        const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ENTITY_NONE;\n  case XML_TOK_NAME:\n    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {\n      state->handler = entity9;\n      return XML_ROLE_ENTITY_NONE;\n    }\n    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {\n      state->handler = entity8;\n      return XML_ROLE_ENTITY_NONE;\n    }\n    break;\n  case XML_TOK_LITERAL:\n    state->handler = declClose;\n    state->role_none = XML_ROLE_ENTITY_NONE;\n    return XML_ROLE_ENTITY_VALUE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nentity8(PROLOG_STATE *state,\n        int tok,\n        const char *ptr,\n        const char *end,\n        const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ENTITY_NONE;\n  case XML_TOK_LITERAL:\n    state->handler = entity9;\n    return XML_ROLE_ENTITY_PUBLIC_ID;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nentity9(PROLOG_STATE *state,\n        int tok,\n        const char *ptr,\n        const char *end,\n        const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ENTITY_NONE;\n  case XML_TOK_LITERAL:\n    state->handler = entity10;\n    return XML_ROLE_ENTITY_SYSTEM_ID;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nentity10(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ENTITY_NONE;\n  case XML_TOK_DECL_CLOSE:\n    setTopLevel(state);\n    return XML_ROLE_ENTITY_COMPLETE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nnotation0(PROLOG_STATE *state,\n          int tok,\n          const char *ptr,\n          const char *end,\n          const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_NOTATION_NONE;\n  case XML_TOK_NAME:\n    state->handler = notation1;\n    return XML_ROLE_NOTATION_NAME;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nnotation1(PROLOG_STATE *state,\n          int tok,\n          const char *ptr,\n          const char *end,\n          const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_NOTATION_NONE;\n  case XML_TOK_NAME:\n    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {\n      state->handler = notation3;\n      return XML_ROLE_NOTATION_NONE;\n    }\n    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {\n      state->handler = notation2;\n      return XML_ROLE_NOTATION_NONE;\n    }\n    break;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nnotation2(PROLOG_STATE *state,\n          int tok,\n          const char *ptr,\n          const char *end,\n          const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_NOTATION_NONE;\n  case XML_TOK_LITERAL:\n    state->handler = notation4;\n    return XML_ROLE_NOTATION_PUBLIC_ID;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nnotation3(PROLOG_STATE *state,\n          int tok,\n          const char *ptr,\n          const char *end,\n          const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_NOTATION_NONE;\n  case XML_TOK_LITERAL:\n    state->handler = declClose;\n    state->role_none = XML_ROLE_NOTATION_NONE;\n    return XML_ROLE_NOTATION_SYSTEM_ID;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nnotation4(PROLOG_STATE *state,\n          int tok,\n          const char *ptr,\n          const char *end,\n          const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_NOTATION_NONE;\n  case XML_TOK_LITERAL:\n    state->handler = declClose;\n    state->role_none = XML_ROLE_NOTATION_NONE;\n    return XML_ROLE_NOTATION_SYSTEM_ID;\n  case XML_TOK_DECL_CLOSE:\n    setTopLevel(state);\n    return XML_ROLE_NOTATION_NO_SYSTEM_ID;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nattlist0(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ATTLIST_NONE;\n  case XML_TOK_NAME:\n  case XML_TOK_PREFIXED_NAME:\n    state->handler = attlist1;\n    return XML_ROLE_ATTLIST_ELEMENT_NAME;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nattlist1(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ATTLIST_NONE;\n  case XML_TOK_DECL_CLOSE:\n    setTopLevel(state);\n    return XML_ROLE_ATTLIST_NONE;\n  case XML_TOK_NAME:\n  case XML_TOK_PREFIXED_NAME:\n    state->handler = attlist2;\n    return XML_ROLE_ATTRIBUTE_NAME;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nattlist2(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ATTLIST_NONE;\n  case XML_TOK_NAME:\n    {\n      static const char * const types[] = {\n        KW_CDATA,\n        KW_ID,\n        KW_IDREF,\n        KW_IDREFS,\n        KW_ENTITY,\n        KW_ENTITIES,\n        KW_NMTOKEN,\n        KW_NMTOKENS,\n      };\n      int i;\n      for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)\n        if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {\n          state->handler = attlist8;\n          return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;\n        }\n    }\n    if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {\n      state->handler = attlist5;\n      return XML_ROLE_ATTLIST_NONE;\n    }\n    break;\n  case XML_TOK_OPEN_PAREN:\n    state->handler = attlist3;\n    return XML_ROLE_ATTLIST_NONE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nattlist3(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ATTLIST_NONE;\n  case XML_TOK_NMTOKEN:\n  case XML_TOK_NAME:\n  case XML_TOK_PREFIXED_NAME:\n    state->handler = attlist4;\n    return XML_ROLE_ATTRIBUTE_ENUM_VALUE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nattlist4(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ATTLIST_NONE;\n  case XML_TOK_CLOSE_PAREN:\n    state->handler = attlist8;\n    return XML_ROLE_ATTLIST_NONE;\n  case XML_TOK_OR:\n    state->handler = attlist3;\n    return XML_ROLE_ATTLIST_NONE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nattlist5(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ATTLIST_NONE;\n  case XML_TOK_OPEN_PAREN:\n    state->handler = attlist6;\n    return XML_ROLE_ATTLIST_NONE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nattlist6(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ATTLIST_NONE;\n  case XML_TOK_NAME:\n    state->handler = attlist7;\n    return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nattlist7(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ATTLIST_NONE;\n  case XML_TOK_CLOSE_PAREN:\n    state->handler = attlist8;\n    return XML_ROLE_ATTLIST_NONE;\n  case XML_TOK_OR:\n    state->handler = attlist6;\n    return XML_ROLE_ATTLIST_NONE;\n  }\n  return common(state, tok);\n}\n\n/* default value */\nstatic int PTRCALL\nattlist8(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ATTLIST_NONE;\n  case XML_TOK_POUND_NAME:\n    if (XmlNameMatchesAscii(enc,\n                            ptr + MIN_BYTES_PER_CHAR(enc),\n                            end,\n                            KW_IMPLIED)) {\n      state->handler = attlist1;\n      return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;\n    }\n    if (XmlNameMatchesAscii(enc,\n                            ptr + MIN_BYTES_PER_CHAR(enc),\n                            end,\n                            KW_REQUIRED)) {\n      state->handler = attlist1;\n      return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;\n    }\n    if (XmlNameMatchesAscii(enc,\n                            ptr + MIN_BYTES_PER_CHAR(enc),\n                            end,\n                            KW_FIXED)) {\n      state->handler = attlist9;\n      return XML_ROLE_ATTLIST_NONE;\n    }\n    break;\n  case XML_TOK_LITERAL:\n    state->handler = attlist1;\n    return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nattlist9(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ATTLIST_NONE;\n  case XML_TOK_LITERAL:\n    state->handler = attlist1;\n    return XML_ROLE_FIXED_ATTRIBUTE_VALUE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nelement0(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ELEMENT_NONE;\n  case XML_TOK_NAME:\n  case XML_TOK_PREFIXED_NAME:\n    state->handler = element1;\n    return XML_ROLE_ELEMENT_NAME;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nelement1(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ELEMENT_NONE;\n  case XML_TOK_NAME:\n    if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) {\n      state->handler = declClose;\n      state->role_none = XML_ROLE_ELEMENT_NONE;\n      return XML_ROLE_CONTENT_EMPTY;\n    }\n    if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) {\n      state->handler = declClose;\n      state->role_none = XML_ROLE_ELEMENT_NONE;\n      return XML_ROLE_CONTENT_ANY;\n    }\n    break;\n  case XML_TOK_OPEN_PAREN:\n    state->handler = element2;\n    state->level = 1;\n    return XML_ROLE_GROUP_OPEN;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nelement2(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ELEMENT_NONE;\n  case XML_TOK_POUND_NAME:\n    if (XmlNameMatchesAscii(enc,\n                            ptr + MIN_BYTES_PER_CHAR(enc),\n                            end,\n                            KW_PCDATA)) {\n      state->handler = element3;\n      return XML_ROLE_CONTENT_PCDATA;\n    }\n    break;\n  case XML_TOK_OPEN_PAREN:\n    state->level = 2;\n    state->handler = element6;\n    return XML_ROLE_GROUP_OPEN;\n  case XML_TOK_NAME:\n  case XML_TOK_PREFIXED_NAME:\n    state->handler = element7;\n    return XML_ROLE_CONTENT_ELEMENT;\n  case XML_TOK_NAME_QUESTION:\n    state->handler = element7;\n    return XML_ROLE_CONTENT_ELEMENT_OPT;\n  case XML_TOK_NAME_ASTERISK:\n    state->handler = element7;\n    return XML_ROLE_CONTENT_ELEMENT_REP;\n  case XML_TOK_NAME_PLUS:\n    state->handler = element7;\n    return XML_ROLE_CONTENT_ELEMENT_PLUS;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nelement3(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ELEMENT_NONE;\n  case XML_TOK_CLOSE_PAREN:\n    state->handler = declClose;\n    state->role_none = XML_ROLE_ELEMENT_NONE;\n    return XML_ROLE_GROUP_CLOSE;\n  case XML_TOK_CLOSE_PAREN_ASTERISK:\n    state->handler = declClose;\n    state->role_none = XML_ROLE_ELEMENT_NONE;\n    return XML_ROLE_GROUP_CLOSE_REP;\n  case XML_TOK_OR:\n    state->handler = element4;\n    return XML_ROLE_ELEMENT_NONE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nelement4(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ELEMENT_NONE;\n  case XML_TOK_NAME:\n  case XML_TOK_PREFIXED_NAME:\n    state->handler = element5;\n    return XML_ROLE_CONTENT_ELEMENT;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nelement5(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ELEMENT_NONE;\n  case XML_TOK_CLOSE_PAREN_ASTERISK:\n    state->handler = declClose;\n    state->role_none = XML_ROLE_ELEMENT_NONE;\n    return XML_ROLE_GROUP_CLOSE_REP;\n  case XML_TOK_OR:\n    state->handler = element4;\n    return XML_ROLE_ELEMENT_NONE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nelement6(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ELEMENT_NONE;\n  case XML_TOK_OPEN_PAREN:\n    state->level += 1;\n    return XML_ROLE_GROUP_OPEN;\n  case XML_TOK_NAME:\n  case XML_TOK_PREFIXED_NAME:\n    state->handler = element7;\n    return XML_ROLE_CONTENT_ELEMENT;\n  case XML_TOK_NAME_QUESTION:\n    state->handler = element7;\n    return XML_ROLE_CONTENT_ELEMENT_OPT;\n  case XML_TOK_NAME_ASTERISK:\n    state->handler = element7;\n    return XML_ROLE_CONTENT_ELEMENT_REP;\n  case XML_TOK_NAME_PLUS:\n    state->handler = element7;\n    return XML_ROLE_CONTENT_ELEMENT_PLUS;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nelement7(PROLOG_STATE *state,\n         int tok,\n         const char *ptr,\n         const char *end,\n         const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_ELEMENT_NONE;\n  case XML_TOK_CLOSE_PAREN:\n    state->level -= 1;\n    if (state->level == 0) {\n      state->handler = declClose;\n      state->role_none = XML_ROLE_ELEMENT_NONE;\n    }\n    return XML_ROLE_GROUP_CLOSE;\n  case XML_TOK_CLOSE_PAREN_ASTERISK:\n    state->level -= 1;\n    if (state->level == 0) {\n      state->handler = declClose;\n      state->role_none = XML_ROLE_ELEMENT_NONE;\n    }\n    return XML_ROLE_GROUP_CLOSE_REP;\n  case XML_TOK_CLOSE_PAREN_QUESTION:\n    state->level -= 1;\n    if (state->level == 0) {\n      state->handler = declClose;\n      state->role_none = XML_ROLE_ELEMENT_NONE;\n    }\n    return XML_ROLE_GROUP_CLOSE_OPT;\n  case XML_TOK_CLOSE_PAREN_PLUS:\n    state->level -= 1;\n    if (state->level == 0) {\n      state->handler = declClose;\n      state->role_none = XML_ROLE_ELEMENT_NONE;\n    }\n    return XML_ROLE_GROUP_CLOSE_PLUS;\n  case XML_TOK_COMMA:\n    state->handler = element6;\n    return XML_ROLE_GROUP_SEQUENCE;\n  case XML_TOK_OR:\n    state->handler = element6;\n    return XML_ROLE_GROUP_CHOICE;\n  }\n  return common(state, tok);\n}\n\n#ifdef XML_DTD\n\nstatic int PTRCALL\ncondSect0(PROLOG_STATE *state,\n          int tok,\n          const char *ptr,\n          const char *end,\n          const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_NONE;\n  case XML_TOK_NAME:\n    if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) {\n      state->handler = condSect1;\n      return XML_ROLE_NONE;\n    }\n    if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) {\n      state->handler = condSect2;\n      return XML_ROLE_NONE;\n    }\n    break;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\ncondSect1(PROLOG_STATE *state,\n          int tok,\n          const char *ptr,\n          const char *end,\n          const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_NONE;\n  case XML_TOK_OPEN_BRACKET:\n    state->handler = externalSubset1;\n    state->includeLevel += 1;\n    return XML_ROLE_NONE;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\ncondSect2(PROLOG_STATE *state,\n          int tok,\n          const char *ptr,\n          const char *end,\n          const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return XML_ROLE_NONE;\n  case XML_TOK_OPEN_BRACKET:\n    state->handler = externalSubset1;\n    return XML_ROLE_IGNORE_SECT;\n  }\n  return common(state, tok);\n}\n\n#endif /* XML_DTD */\n\nstatic int PTRCALL\ndeclClose(PROLOG_STATE *state,\n          int tok,\n          const char *ptr,\n          const char *end,\n          const ENCODING *enc)\n{\n  switch (tok) {\n  case XML_TOK_PROLOG_S:\n    return state->role_none;\n  case XML_TOK_DECL_CLOSE:\n    setTopLevel(state);\n    return state->role_none;\n  }\n  return common(state, tok);\n}\n\nstatic int PTRCALL\nerror(PROLOG_STATE *state,\n      int tok,\n      const char *ptr,\n      const char *end,\n      const ENCODING *enc)\n{\n  return XML_ROLE_NONE;\n}\n\nstatic int FASTCALL\ncommon(PROLOG_STATE *state, int tok)\n{\n#ifdef XML_DTD\n  if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)\n    return XML_ROLE_INNER_PARAM_ENTITY_REF;\n#endif\n  state->handler = error;\n  return XML_ROLE_ERROR;\n}\n\nvoid\nXmlPrologStateInit(PROLOG_STATE *state)\n{\n  state->handler = prolog0;\n#ifdef XML_DTD\n  state->documentEntity = 1;\n  state->includeLevel = 0;\n  state->inEntityValue = 0;\n#endif /* XML_DTD */\n}\n\n#ifdef XML_DTD\n\nvoid\nXmlPrologStateInitExternalEntity(PROLOG_STATE *state)\n{\n  state->handler = externalSubset0;\n  state->documentEntity = 0;\n  state->includeLevel = 0;\n}\n\n#endif /* XML_DTD */\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/xmlrole.h",
    "content": "/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd\n   See the file COPYING for copying permission.\n*/\n\n#ifndef XmlRole_INCLUDED\n#define XmlRole_INCLUDED 1\n\n#ifdef __VMS\n/*      0        1         2         3      0        1         2         3\n        1234567890123456789012345678901     1234567890123456789012345678901 */\n#define XmlPrologStateInitExternalEntity    XmlPrologStateInitExternalEnt\n#endif\n\n#include \"xmltok.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nenum {\n  XML_ROLE_ERROR = -1,\n  XML_ROLE_NONE = 0,\n  XML_ROLE_XML_DECL,\n  XML_ROLE_INSTANCE_START,\n  XML_ROLE_DOCTYPE_NONE,\n  XML_ROLE_DOCTYPE_NAME,\n  XML_ROLE_DOCTYPE_SYSTEM_ID,\n  XML_ROLE_DOCTYPE_PUBLIC_ID,\n  XML_ROLE_DOCTYPE_INTERNAL_SUBSET,\n  XML_ROLE_DOCTYPE_CLOSE,\n  XML_ROLE_GENERAL_ENTITY_NAME,\n  XML_ROLE_PARAM_ENTITY_NAME,\n  XML_ROLE_ENTITY_NONE,\n  XML_ROLE_ENTITY_VALUE,\n  XML_ROLE_ENTITY_SYSTEM_ID,\n  XML_ROLE_ENTITY_PUBLIC_ID,\n  XML_ROLE_ENTITY_COMPLETE,\n  XML_ROLE_ENTITY_NOTATION_NAME,\n  XML_ROLE_NOTATION_NONE,\n  XML_ROLE_NOTATION_NAME,\n  XML_ROLE_NOTATION_SYSTEM_ID,\n  XML_ROLE_NOTATION_NO_SYSTEM_ID,\n  XML_ROLE_NOTATION_PUBLIC_ID,\n  XML_ROLE_ATTRIBUTE_NAME,\n  XML_ROLE_ATTRIBUTE_TYPE_CDATA,\n  XML_ROLE_ATTRIBUTE_TYPE_ID,\n  XML_ROLE_ATTRIBUTE_TYPE_IDREF,\n  XML_ROLE_ATTRIBUTE_TYPE_IDREFS,\n  XML_ROLE_ATTRIBUTE_TYPE_ENTITY,\n  XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,\n  XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,\n  XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,\n  XML_ROLE_ATTRIBUTE_ENUM_VALUE,\n  XML_ROLE_ATTRIBUTE_NOTATION_VALUE,\n  XML_ROLE_ATTLIST_NONE,\n  XML_ROLE_ATTLIST_ELEMENT_NAME,\n  XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,\n  XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,\n  XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,\n  XML_ROLE_FIXED_ATTRIBUTE_VALUE,\n  XML_ROLE_ELEMENT_NONE,\n  XML_ROLE_ELEMENT_NAME,\n  XML_ROLE_CONTENT_ANY,\n  XML_ROLE_CONTENT_EMPTY,\n  XML_ROLE_CONTENT_PCDATA,\n  XML_ROLE_GROUP_OPEN,\n  XML_ROLE_GROUP_CLOSE,\n  XML_ROLE_GROUP_CLOSE_REP,\n  XML_ROLE_GROUP_CLOSE_OPT,\n  XML_ROLE_GROUP_CLOSE_PLUS,\n  XML_ROLE_GROUP_CHOICE,\n  XML_ROLE_GROUP_SEQUENCE,\n  XML_ROLE_CONTENT_ELEMENT,\n  XML_ROLE_CONTENT_ELEMENT_REP,\n  XML_ROLE_CONTENT_ELEMENT_OPT,\n  XML_ROLE_CONTENT_ELEMENT_PLUS,\n  XML_ROLE_PI,\n  XML_ROLE_COMMENT,\n#ifdef XML_DTD\n  XML_ROLE_TEXT_DECL,\n  XML_ROLE_IGNORE_SECT,\n  XML_ROLE_INNER_PARAM_ENTITY_REF,\n#endif /* XML_DTD */\n  XML_ROLE_PARAM_ENTITY_REF\n};\n\ntypedef struct prolog_state {\n  int (PTRCALL *handler) (struct prolog_state *state,\n                          int tok,\n                          const char *ptr,\n                          const char *end,\n                          const ENCODING *enc);\n  unsigned level;\n  int role_none;\n#ifdef XML_DTD\n  unsigned includeLevel;\n  int documentEntity;\n  int inEntityValue;\n#endif /* XML_DTD */\n} PROLOG_STATE;\n\nvoid XmlPrologStateInit(PROLOG_STATE *);\n#ifdef XML_DTD\nvoid XmlPrologStateInitExternalEntity(PROLOG_STATE *);\n#endif /* XML_DTD */\n\n#define XmlTokenRole(state, tok, ptr, end, enc) \\\n (((state)->handler)(state, tok, ptr, end, enc))\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* not XmlRole_INCLUDED */\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/xmltok.c",
    "content": "/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd\n   See the file COPYING for copying permission.\n*/\n\n#include <stddef.h>\n\n#ifdef COMPILED_FROM_DSP\n#include \"winconfig.h\"\n#elif defined(MACOS_CLASSIC)\n#include \"macconfig.h\"\n#elif defined(__amigaos__)\n#include \"amigaconfig.h\"\n#elif defined(__WATCOMC__)\n#include \"watcomconfig.h\"\n#else\n#ifdef HAVE_EXPAT_CONFIG_H\n#include <expat_config.h>\n#endif\n#endif /* ndef COMPILED_FROM_DSP */\n\n#include \"expat_external.h\"\n#include \"internal.h\"\n#include \"xmltok.h\"\n#include \"nametab.h\"\n\n#ifdef XML_DTD\n#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)\n#else\n#define IGNORE_SECTION_TOK_VTABLE /* as nothing */\n#endif\n\n#define VTABLE1 \\\n  { PREFIX(prologTok), PREFIX(contentTok), \\\n    PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \\\n  { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \\\n  PREFIX(sameName), \\\n  PREFIX(nameMatchesAscii), \\\n  PREFIX(nameLength), \\\n  PREFIX(skipS), \\\n  PREFIX(getAtts), \\\n  PREFIX(charRefNumber), \\\n  PREFIX(predefinedEntityName), \\\n  PREFIX(updatePosition), \\\n  PREFIX(isPublicId)\n\n#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)\n\n#define UCS2_GET_NAMING(pages, hi, lo) \\\n   (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))\n\n/* A 2 byte UTF-8 representation splits the characters 11 bits between\n   the bottom 5 and 6 bits of the bytes.  We need 8 bits to index into\n   pages, 3 bits to add to that index and 5 bits to generate the mask.\n*/\n#define UTF8_GET_NAMING2(pages, byte) \\\n    (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \\\n                      + ((((byte)[0]) & 3) << 1) \\\n                      + ((((byte)[1]) >> 5) & 1)] \\\n         & (1 << (((byte)[1]) & 0x1F)))\n\n/* A 3 byte UTF-8 representation splits the characters 16 bits between\n   the bottom 4, 6 and 6 bits of the bytes.  We need 8 bits to index\n   into pages, 3 bits to add to that index and 5 bits to generate the\n   mask.\n*/\n#define UTF8_GET_NAMING3(pages, byte) \\\n  (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \\\n                             + ((((byte)[1]) >> 2) & 0xF)] \\\n                       << 3) \\\n                      + ((((byte)[1]) & 3) << 1) \\\n                      + ((((byte)[2]) >> 5) & 1)] \\\n         & (1 << (((byte)[2]) & 0x1F)))\n\n#define UTF8_GET_NAMING(pages, p, n) \\\n  ((n) == 2 \\\n  ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \\\n  : ((n) == 3 \\\n     ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \\\n     : 0))\n\n/* Detection of invalid UTF-8 sequences is based on Table 3.1B\n   of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/\n   with the additional restriction of not allowing the Unicode\n   code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE).\n   Implementation details:\n     (A & 0x80) == 0     means A < 0x80\n   and\n     (A & 0xC0) == 0xC0  means A > 0xBF\n*/\n\n#define UTF8_INVALID2(p) \\\n  ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)\n\n#define UTF8_INVALID3(p) \\\n  (((p)[2] & 0x80) == 0 \\\n  || \\\n  ((*p) == 0xEF && (p)[1] == 0xBF \\\n    ? \\\n    (p)[2] > 0xBD \\\n    : \\\n    ((p)[2] & 0xC0) == 0xC0) \\\n  || \\\n  ((*p) == 0xE0 \\\n    ? \\\n    (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \\\n    : \\\n    ((p)[1] & 0x80) == 0 \\\n    || \\\n    ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))\n\n#define UTF8_INVALID4(p) \\\n  (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \\\n  || \\\n  ((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \\\n  || \\\n  ((*p) == 0xF0 \\\n    ? \\\n    (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \\\n    : \\\n    ((p)[1] & 0x80) == 0 \\\n    || \\\n    ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))\n\nstatic int PTRFASTCALL\nisNever(const ENCODING *enc, const char *p)\n{\n  return 0;\n}\n\nstatic int PTRFASTCALL\nutf8_isName2(const ENCODING *enc, const char *p)\n{\n  return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);\n}\n\nstatic int PTRFASTCALL\nutf8_isName3(const ENCODING *enc, const char *p)\n{\n  return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);\n}\n\n#define utf8_isName4 isNever\n\nstatic int PTRFASTCALL\nutf8_isNmstrt2(const ENCODING *enc, const char *p)\n{\n  return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);\n}\n\nstatic int PTRFASTCALL\nutf8_isNmstrt3(const ENCODING *enc, const char *p)\n{\n  return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);\n}\n\n#define utf8_isNmstrt4 isNever\n\nstatic int PTRFASTCALL\nutf8_isInvalid2(const ENCODING *enc, const char *p)\n{\n  return UTF8_INVALID2((const unsigned char *)p);\n}\n\nstatic int PTRFASTCALL\nutf8_isInvalid3(const ENCODING *enc, const char *p)\n{\n  return UTF8_INVALID3((const unsigned char *)p);\n}\n\nstatic int PTRFASTCALL\nutf8_isInvalid4(const ENCODING *enc, const char *p)\n{\n  return UTF8_INVALID4((const unsigned char *)p);\n}\n\nstruct normal_encoding {\n  ENCODING enc;\n  unsigned char type[256];\n#ifdef XML_MIN_SIZE\n  int (PTRFASTCALL *byteType)(const ENCODING *, const char *);\n  int (PTRFASTCALL *isNameMin)(const ENCODING *, const char *);\n  int (PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);\n  int (PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);\n  int (PTRCALL *charMatches)(const ENCODING *, const char *, int);\n#endif /* XML_MIN_SIZE */\n  int (PTRFASTCALL *isName2)(const ENCODING *, const char *);\n  int (PTRFASTCALL *isName3)(const ENCODING *, const char *);\n  int (PTRFASTCALL *isName4)(const ENCODING *, const char *);\n  int (PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);\n  int (PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);\n  int (PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);\n  int (PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);\n  int (PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);\n  int (PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);\n};\n\n#define AS_NORMAL_ENCODING(enc)   ((const struct normal_encoding *) (enc))\n\n#ifdef XML_MIN_SIZE\n\n#define STANDARD_VTABLE(E) \\\n E ## byteType, \\\n E ## isNameMin, \\\n E ## isNmstrtMin, \\\n E ## byteToAscii, \\\n E ## charMatches,\n\n#else\n\n#define STANDARD_VTABLE(E) /* as nothing */\n\n#endif\n\n#define NORMAL_VTABLE(E) \\\n E ## isName2, \\\n E ## isName3, \\\n E ## isName4, \\\n E ## isNmstrt2, \\\n E ## isNmstrt3, \\\n E ## isNmstrt4, \\\n E ## isInvalid2, \\\n E ## isInvalid3, \\\n E ## isInvalid4\n\nstatic int FASTCALL checkCharRefNumber(int);\n\n#include \"xmltok_impl.h\"\n#include \"ascii.h\"\n\n#ifdef XML_MIN_SIZE\n#define sb_isNameMin isNever\n#define sb_isNmstrtMin isNever\n#endif\n\n#ifdef XML_MIN_SIZE\n#define MINBPC(enc) ((enc)->minBytesPerChar)\n#else\n/* minimum bytes per character */\n#define MINBPC(enc) 1\n#endif\n\n#define SB_BYTE_TYPE(enc, p) \\\n  (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])\n\n#ifdef XML_MIN_SIZE\nstatic int PTRFASTCALL\nsb_byteType(const ENCODING *enc, const char *p)\n{\n  return SB_BYTE_TYPE(enc, p);\n}\n#define BYTE_TYPE(enc, p) \\\n (AS_NORMAL_ENCODING(enc)->byteType(enc, p))\n#else\n#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)\n#endif\n\n#ifdef XML_MIN_SIZE\n#define BYTE_TO_ASCII(enc, p) \\\n (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))\nstatic int PTRFASTCALL\nsb_byteToAscii(const ENCODING *enc, const char *p)\n{\n  return *p;\n}\n#else\n#define BYTE_TO_ASCII(enc, p) (*(p))\n#endif\n\n#define IS_NAME_CHAR(enc, p, n) \\\n (AS_NORMAL_ENCODING(enc)->isName ## n(enc, p))\n#define IS_NMSTRT_CHAR(enc, p, n) \\\n (AS_NORMAL_ENCODING(enc)->isNmstrt ## n(enc, p))\n#define IS_INVALID_CHAR(enc, p, n) \\\n (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p))\n\n#ifdef XML_MIN_SIZE\n#define IS_NAME_CHAR_MINBPC(enc, p) \\\n (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))\n#define IS_NMSTRT_CHAR_MINBPC(enc, p) \\\n (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p))\n#else\n#define IS_NAME_CHAR_MINBPC(enc, p) (0)\n#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)\n#endif\n\n#ifdef XML_MIN_SIZE\n#define CHAR_MATCHES(enc, p, c) \\\n (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))\nstatic int PTRCALL\nsb_charMatches(const ENCODING *enc, const char *p, int c)\n{\n  return *p == c;\n}\n#else\n/* c is an ASCII character */\n#define CHAR_MATCHES(enc, p, c) (*(p) == c)\n#endif\n\n#define PREFIX(ident) normal_ ## ident\n#define XML_TOK_IMPL_C\n#include \"xmltok_impl.c\"\n#undef XML_TOK_IMPL_C\n\n#undef MINBPC\n#undef BYTE_TYPE\n#undef BYTE_TO_ASCII\n#undef CHAR_MATCHES\n#undef IS_NAME_CHAR\n#undef IS_NAME_CHAR_MINBPC\n#undef IS_NMSTRT_CHAR\n#undef IS_NMSTRT_CHAR_MINBPC\n#undef IS_INVALID_CHAR\n\nenum {  /* UTF8_cvalN is value of masked first byte of N byte sequence */\n  UTF8_cval1 = 0x00,\n  UTF8_cval2 = 0xc0,\n  UTF8_cval3 = 0xe0,\n  UTF8_cval4 = 0xf0\n};\n\nstatic enum XML_Convert_Result PTRCALL\nutf8_toUtf8(const ENCODING *enc,\n            const char **fromP, const char *fromLim,\n            char **toP, const char *toLim)\n{\n  enum XML_Convert_Result res = XML_CONVERT_COMPLETED;\n  char *to;\n  const char *from;\n  if (fromLim - *fromP > toLim - *toP) {\n    /* Avoid copying partial characters. */\n    res = XML_CONVERT_OUTPUT_EXHAUSTED;\n    for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)\n      if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)\n        break;\n  }\n  for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++)\n    *to = *from;\n  *fromP = from;\n  *toP = to;\n\n  if ((to == toLim) && (from < fromLim))\n    return XML_CONVERT_OUTPUT_EXHAUSTED;\n  else\n    return res;\n}\n\nstatic enum XML_Convert_Result PTRCALL\nutf8_toUtf16(const ENCODING *enc,\n             const char **fromP, const char *fromLim,\n             unsigned short **toP, const unsigned short *toLim)\n{\n  enum XML_Convert_Result res = XML_CONVERT_COMPLETED;\n  unsigned short *to = *toP;\n  const char *from = *fromP;\n  while (from < fromLim && to < toLim) {\n    switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {\n    case BT_LEAD2:\n      if (fromLim - from < 2) {\n        res = XML_CONVERT_INPUT_INCOMPLETE;\n        break;\n      }\n      *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));\n      from += 2;\n      break;\n    case BT_LEAD3:\n      if (fromLim - from < 3) {\n        res = XML_CONVERT_INPUT_INCOMPLETE;\n        break;\n      }\n      *to++ = (unsigned short)(((from[0] & 0xf) << 12)\n                               | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));\n      from += 3;\n      break;\n    case BT_LEAD4:\n      {\n        unsigned long n;\n        if (toLim - to < 2) {\n          res = XML_CONVERT_OUTPUT_EXHAUSTED;\n          goto after;\n        }\n        if (fromLim - from < 4) {\n          res = XML_CONVERT_INPUT_INCOMPLETE;\n          goto after;\n        }\n        n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)\n            | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);\n        n -= 0x10000;\n        to[0] = (unsigned short)((n >> 10) | 0xD800);\n        to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);\n        to += 2;\n        from += 4;\n      }\n      break;\n    default:\n      *to++ = *from++;\n      break;\n    }\n  }\nafter:\n  *fromP = from;\n  *toP = to;\n  return res;\n}\n\n#ifdef XML_NS\nstatic const struct normal_encoding utf8_encoding_ns = {\n  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },\n  {\n#include \"asciitab.h\"\n#include \"utf8tab.h\"\n  },\n  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)\n};\n#endif\n\nstatic const struct normal_encoding utf8_encoding = {\n  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },\n  {\n#define BT_COLON BT_NMSTRT\n#include \"asciitab.h\"\n#undef BT_COLON\n#include \"utf8tab.h\"\n  },\n  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)\n};\n\n#ifdef XML_NS\n\nstatic const struct normal_encoding internal_utf8_encoding_ns = {\n  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },\n  {\n#include \"iasciitab.h\"\n#include \"utf8tab.h\"\n  },\n  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)\n};\n\n#endif\n\nstatic const struct normal_encoding internal_utf8_encoding = {\n  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },\n  {\n#define BT_COLON BT_NMSTRT\n#include \"iasciitab.h\"\n#undef BT_COLON\n#include \"utf8tab.h\"\n  },\n  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)\n};\n\nstatic enum XML_Convert_Result PTRCALL\nlatin1_toUtf8(const ENCODING *enc,\n              const char **fromP, const char *fromLim,\n              char **toP, const char *toLim)\n{\n  for (;;) {\n    unsigned char c;\n    if (*fromP == fromLim)\n      return XML_CONVERT_COMPLETED;\n    c = (unsigned char)**fromP;\n    if (c & 0x80) {\n      if (toLim - *toP < 2)\n        return XML_CONVERT_OUTPUT_EXHAUSTED;\n      *(*toP)++ = (char)((c >> 6) | UTF8_cval2);\n      *(*toP)++ = (char)((c & 0x3f) | 0x80);\n      (*fromP)++;\n    }\n    else {\n      if (*toP == toLim)\n        return XML_CONVERT_OUTPUT_EXHAUSTED;\n      *(*toP)++ = *(*fromP)++;\n    }\n  }\n}\n\nstatic enum XML_Convert_Result PTRCALL\nlatin1_toUtf16(const ENCODING *enc,\n               const char **fromP, const char *fromLim,\n               unsigned short **toP, const unsigned short *toLim)\n{\n  while (*fromP < fromLim && *toP < toLim)\n    *(*toP)++ = (unsigned char)*(*fromP)++;\n\n  if ((*toP == toLim) && (*fromP < fromLim))\n    return XML_CONVERT_OUTPUT_EXHAUSTED;\n  else\n    return XML_CONVERT_COMPLETED;\n}\n\n#ifdef XML_NS\n\nstatic const struct normal_encoding latin1_encoding_ns = {\n  { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },\n  {\n#include \"asciitab.h\"\n#include \"latin1tab.h\"\n  },\n  STANDARD_VTABLE(sb_)\n};\n\n#endif\n\nstatic const struct normal_encoding latin1_encoding = {\n  { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },\n  {\n#define BT_COLON BT_NMSTRT\n#include \"asciitab.h\"\n#undef BT_COLON\n#include \"latin1tab.h\"\n  },\n  STANDARD_VTABLE(sb_)\n};\n\nstatic enum XML_Convert_Result PTRCALL\nascii_toUtf8(const ENCODING *enc,\n             const char **fromP, const char *fromLim,\n             char **toP, const char *toLim)\n{\n  while (*fromP < fromLim && *toP < toLim)\n    *(*toP)++ = *(*fromP)++;\n\n  if ((*toP == toLim) && (*fromP < fromLim))\n    return XML_CONVERT_OUTPUT_EXHAUSTED;\n  else\n    return XML_CONVERT_COMPLETED;\n}\n\n#ifdef XML_NS\n\nstatic const struct normal_encoding ascii_encoding_ns = {\n  { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },\n  {\n#include \"asciitab.h\"\n/* BT_NONXML == 0 */\n  },\n  STANDARD_VTABLE(sb_)\n};\n\n#endif\n\nstatic const struct normal_encoding ascii_encoding = {\n  { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },\n  {\n#define BT_COLON BT_NMSTRT\n#include \"asciitab.h\"\n#undef BT_COLON\n/* BT_NONXML == 0 */\n  },\n  STANDARD_VTABLE(sb_)\n};\n\nstatic int PTRFASTCALL\nunicode_byte_type(char hi, char lo)\n{\n  switch ((unsigned char)hi) {\n  case 0xD8: case 0xD9: case 0xDA: case 0xDB:\n    return BT_LEAD4;\n  case 0xDC: case 0xDD: case 0xDE: case 0xDF:\n    return BT_TRAIL;\n  case 0xFF:\n    switch ((unsigned char)lo) {\n    case 0xFF:\n    case 0xFE:\n      return BT_NONXML;\n    }\n    break;\n  }\n  return BT_NONASCII;\n}\n\n#define DEFINE_UTF16_TO_UTF8(E) \\\nstatic enum XML_Convert_Result  PTRCALL \\\nE ## toUtf8(const ENCODING *enc, \\\n            const char **fromP, const char *fromLim, \\\n            char **toP, const char *toLim) \\\n{ \\\n  const char *from = *fromP; \\\n  fromLim = from + (((fromLim - from) >> 1) << 1);  /* shrink to even */ \\\n  for (; from < fromLim; from += 2) { \\\n    int plane; \\\n    unsigned char lo2; \\\n    unsigned char lo = GET_LO(from); \\\n    unsigned char hi = GET_HI(from); \\\n    switch (hi) { \\\n    case 0: \\\n      if (lo < 0x80) { \\\n        if (*toP == toLim) { \\\n          *fromP = from; \\\n          return XML_CONVERT_OUTPUT_EXHAUSTED; \\\n        } \\\n        *(*toP)++ = lo; \\\n        break; \\\n      } \\\n      /* fall through */ \\\n    case 0x1: case 0x2: case 0x3: \\\n    case 0x4: case 0x5: case 0x6: case 0x7: \\\n      if (toLim -  *toP < 2) { \\\n        *fromP = from; \\\n        return XML_CONVERT_OUTPUT_EXHAUSTED; \\\n      } \\\n      *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); \\\n      *(*toP)++ = ((lo & 0x3f) | 0x80); \\\n      break; \\\n    default: \\\n      if (toLim -  *toP < 3)  { \\\n        *fromP = from; \\\n        return XML_CONVERT_OUTPUT_EXHAUSTED; \\\n      } \\\n      /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \\\n      *(*toP)++ = ((hi >> 4) | UTF8_cval3); \\\n      *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \\\n      *(*toP)++ = ((lo & 0x3f) | 0x80); \\\n      break; \\\n    case 0xD8: case 0xD9: case 0xDA: case 0xDB: \\\n      if (toLim -  *toP < 4) { \\\n        *fromP = from; \\\n        return XML_CONVERT_OUTPUT_EXHAUSTED; \\\n      } \\\n      if (fromLim - from < 4) { \\\n        *fromP = from; \\\n        return XML_CONVERT_INPUT_INCOMPLETE; \\\n      } \\\n      plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \\\n      *(*toP)++ = ((plane >> 2) | UTF8_cval4); \\\n      *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \\\n      from += 2; \\\n      lo2 = GET_LO(from); \\\n      *(*toP)++ = (((lo & 0x3) << 4) \\\n                   | ((GET_HI(from) & 0x3) << 2) \\\n                   | (lo2 >> 6) \\\n                   | 0x80); \\\n      *(*toP)++ = ((lo2 & 0x3f) | 0x80); \\\n      break; \\\n    } \\\n  } \\\n  *fromP = from; \\\n  if (from < fromLim) \\\n    return XML_CONVERT_INPUT_INCOMPLETE; \\\n  else \\\n    return XML_CONVERT_COMPLETED; \\\n}\n\n#define DEFINE_UTF16_TO_UTF16(E) \\\nstatic enum XML_Convert_Result  PTRCALL \\\nE ## toUtf16(const ENCODING *enc, \\\n             const char **fromP, const char *fromLim, \\\n             unsigned short **toP, const unsigned short *toLim) \\\n{ \\\n  enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \\\n  fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1);  /* shrink to even */ \\\n  /* Avoid copying first half only of surrogate */ \\\n  if (fromLim - *fromP > ((toLim - *toP) << 1) \\\n      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \\\n    fromLim -= 2; \\\n    res = XML_CONVERT_INPUT_INCOMPLETE; \\\n  } \\\n  for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \\\n    *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \\\n  if ((*toP == toLim) && (*fromP < fromLim)) \\\n    return XML_CONVERT_OUTPUT_EXHAUSTED; \\\n  else \\\n    return res; \\\n}\n\n#define SET2(ptr, ch) \\\n  (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))\n#define GET_LO(ptr) ((unsigned char)(ptr)[0])\n#define GET_HI(ptr) ((unsigned char)(ptr)[1])\n\nDEFINE_UTF16_TO_UTF8(little2_)\nDEFINE_UTF16_TO_UTF16(little2_)\n\n#undef SET2\n#undef GET_LO\n#undef GET_HI\n\n#define SET2(ptr, ch) \\\n  (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))\n#define GET_LO(ptr) ((unsigned char)(ptr)[1])\n#define GET_HI(ptr) ((unsigned char)(ptr)[0])\n\nDEFINE_UTF16_TO_UTF8(big2_)\nDEFINE_UTF16_TO_UTF16(big2_)\n\n#undef SET2\n#undef GET_LO\n#undef GET_HI\n\n#define LITTLE2_BYTE_TYPE(enc, p) \\\n ((p)[1] == 0 \\\n  ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \\\n  : unicode_byte_type((p)[1], (p)[0]))\n#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)\n#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)\n#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \\\n  UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])\n#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \\\n  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])\n\n#ifdef XML_MIN_SIZE\n\nstatic int PTRFASTCALL\nlittle2_byteType(const ENCODING *enc, const char *p)\n{\n  return LITTLE2_BYTE_TYPE(enc, p);\n}\n\nstatic int PTRFASTCALL\nlittle2_byteToAscii(const ENCODING *enc, const char *p)\n{\n  return LITTLE2_BYTE_TO_ASCII(enc, p);\n}\n\nstatic int PTRCALL\nlittle2_charMatches(const ENCODING *enc, const char *p, int c)\n{\n  return LITTLE2_CHAR_MATCHES(enc, p, c);\n}\n\nstatic int PTRFASTCALL\nlittle2_isNameMin(const ENCODING *enc, const char *p)\n{\n  return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);\n}\n\nstatic int PTRFASTCALL\nlittle2_isNmstrtMin(const ENCODING *enc, const char *p)\n{\n  return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);\n}\n\n#undef VTABLE\n#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16\n\n#else /* not XML_MIN_SIZE */\n\n#undef PREFIX\n#define PREFIX(ident) little2_ ## ident\n#define MINBPC(enc) 2\n/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */\n#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)\n#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p)\n#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)\n#define IS_NAME_CHAR(enc, p, n) 0\n#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)\n#define IS_NMSTRT_CHAR(enc, p, n) (0)\n#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)\n\n#define XML_TOK_IMPL_C\n#include \"xmltok_impl.c\"\n#undef XML_TOK_IMPL_C\n\n#undef MINBPC\n#undef BYTE_TYPE\n#undef BYTE_TO_ASCII\n#undef CHAR_MATCHES\n#undef IS_NAME_CHAR\n#undef IS_NAME_CHAR_MINBPC\n#undef IS_NMSTRT_CHAR\n#undef IS_NMSTRT_CHAR_MINBPC\n#undef IS_INVALID_CHAR\n\n#endif /* not XML_MIN_SIZE */\n\n#ifdef XML_NS\n\nstatic const struct normal_encoding little2_encoding_ns = {\n  { VTABLE, 2, 0,\n#if BYTEORDER == 1234\n    1\n#else\n    0\n#endif\n  },\n  {\n#include \"asciitab.h\"\n#include \"latin1tab.h\"\n  },\n  STANDARD_VTABLE(little2_)\n};\n\n#endif\n\nstatic const struct normal_encoding little2_encoding = {\n  { VTABLE, 2, 0,\n#if BYTEORDER == 1234\n    1\n#else\n    0\n#endif\n  },\n  {\n#define BT_COLON BT_NMSTRT\n#include \"asciitab.h\"\n#undef BT_COLON\n#include \"latin1tab.h\"\n  },\n  STANDARD_VTABLE(little2_)\n};\n\n#if BYTEORDER != 4321\n\n#ifdef XML_NS\n\nstatic const struct normal_encoding internal_little2_encoding_ns = {\n  { VTABLE, 2, 0, 1 },\n  {\n#include \"iasciitab.h\"\n#include \"latin1tab.h\"\n  },\n  STANDARD_VTABLE(little2_)\n};\n\n#endif\n\nstatic const struct normal_encoding internal_little2_encoding = {\n  { VTABLE, 2, 0, 1 },\n  {\n#define BT_COLON BT_NMSTRT\n#include \"iasciitab.h\"\n#undef BT_COLON\n#include \"latin1tab.h\"\n  },\n  STANDARD_VTABLE(little2_)\n};\n\n#endif\n\n\n#define BIG2_BYTE_TYPE(enc, p) \\\n ((p)[0] == 0 \\\n  ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \\\n  : unicode_byte_type((p)[0], (p)[1]))\n#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)\n#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)\n#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \\\n  UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])\n#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \\\n  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])\n\n#ifdef XML_MIN_SIZE\n\nstatic int PTRFASTCALL\nbig2_byteType(const ENCODING *enc, const char *p)\n{\n  return BIG2_BYTE_TYPE(enc, p);\n}\n\nstatic int PTRFASTCALL\nbig2_byteToAscii(const ENCODING *enc, const char *p)\n{\n  return BIG2_BYTE_TO_ASCII(enc, p);\n}\n\nstatic int PTRCALL\nbig2_charMatches(const ENCODING *enc, const char *p, int c)\n{\n  return BIG2_CHAR_MATCHES(enc, p, c);\n}\n\nstatic int PTRFASTCALL\nbig2_isNameMin(const ENCODING *enc, const char *p)\n{\n  return BIG2_IS_NAME_CHAR_MINBPC(enc, p);\n}\n\nstatic int PTRFASTCALL\nbig2_isNmstrtMin(const ENCODING *enc, const char *p)\n{\n  return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);\n}\n\n#undef VTABLE\n#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16\n\n#else /* not XML_MIN_SIZE */\n\n#undef PREFIX\n#define PREFIX(ident) big2_ ## ident\n#define MINBPC(enc) 2\n/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */\n#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)\n#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p)\n#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)\n#define IS_NAME_CHAR(enc, p, n) 0\n#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)\n#define IS_NMSTRT_CHAR(enc, p, n) (0)\n#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)\n\n#define XML_TOK_IMPL_C\n#include \"xmltok_impl.c\"\n#undef XML_TOK_IMPL_C\n\n#undef MINBPC\n#undef BYTE_TYPE\n#undef BYTE_TO_ASCII\n#undef CHAR_MATCHES\n#undef IS_NAME_CHAR\n#undef IS_NAME_CHAR_MINBPC\n#undef IS_NMSTRT_CHAR\n#undef IS_NMSTRT_CHAR_MINBPC\n#undef IS_INVALID_CHAR\n\n#endif /* not XML_MIN_SIZE */\n\n#ifdef XML_NS\n\nstatic const struct normal_encoding big2_encoding_ns = {\n  { VTABLE, 2, 0,\n#if BYTEORDER == 4321\n  1\n#else\n  0\n#endif\n  },\n  {\n#include \"asciitab.h\"\n#include \"latin1tab.h\"\n  },\n  STANDARD_VTABLE(big2_)\n};\n\n#endif\n\nstatic const struct normal_encoding big2_encoding = {\n  { VTABLE, 2, 0,\n#if BYTEORDER == 4321\n  1\n#else\n  0\n#endif\n  },\n  {\n#define BT_COLON BT_NMSTRT\n#include \"asciitab.h\"\n#undef BT_COLON\n#include \"latin1tab.h\"\n  },\n  STANDARD_VTABLE(big2_)\n};\n\n#if BYTEORDER != 1234\n\n#ifdef XML_NS\n\nstatic const struct normal_encoding internal_big2_encoding_ns = {\n  { VTABLE, 2, 0, 1 },\n  {\n#include \"iasciitab.h\"\n#include \"latin1tab.h\"\n  },\n  STANDARD_VTABLE(big2_)\n};\n\n#endif\n\nstatic const struct normal_encoding internal_big2_encoding = {\n  { VTABLE, 2, 0, 1 },\n  {\n#define BT_COLON BT_NMSTRT\n#include \"iasciitab.h\"\n#undef BT_COLON\n#include \"latin1tab.h\"\n  },\n  STANDARD_VTABLE(big2_)\n};\n\n#endif\n\n#undef PREFIX\n\nstatic int FASTCALL\nstreqci(const char *s1, const char *s2)\n{\n  for (;;) {\n    char c1 = *s1++;\n    char c2 = *s2++;\n    if (ASCII_a <= c1 && c1 <= ASCII_z)\n      c1 += ASCII_A - ASCII_a;\n    if (ASCII_a <= c2 && c2 <= ASCII_z)\n      c2 += ASCII_A - ASCII_a;\n    if (c1 != c2)\n      return 0;\n    if (!c1)\n      break;\n  }\n  return 1;\n}\n\nstatic void PTRCALL\ninitUpdatePosition(const ENCODING *enc, const char *ptr,\n                   const char *end, POSITION *pos)\n{\n  normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);\n}\n\nstatic int\ntoAscii(const ENCODING *enc, const char *ptr, const char *end)\n{\n  char buf[1];\n  char *p = buf;\n  XmlUtf8Convert(enc, &ptr, end, &p, p + 1);\n  if (p == buf)\n    return -1;\n  else\n    return buf[0];\n}\n\nstatic int FASTCALL\nisSpace(int c)\n{\n  switch (c) {\n  case 0x20:\n  case 0xD:\n  case 0xA:\n  case 0x9:\n    return 1;\n  }\n  return 0;\n}\n\n/* Return 1 if there's just optional white space or there's an S\n   followed by name=val.\n*/\nstatic int\nparsePseudoAttribute(const ENCODING *enc,\n                     const char *ptr,\n                     const char *end,\n                     const char **namePtr,\n                     const char **nameEndPtr,\n                     const char **valPtr,\n                     const char **nextTokPtr)\n{\n  int c;\n  char open;\n  if (ptr == end) {\n    *namePtr = NULL;\n    return 1;\n  }\n  if (!isSpace(toAscii(enc, ptr, end))) {\n    *nextTokPtr = ptr;\n    return 0;\n  }\n  do {\n    ptr += enc->minBytesPerChar;\n  } while (isSpace(toAscii(enc, ptr, end)));\n  if (ptr == end) {\n    *namePtr = NULL;\n    return 1;\n  }\n  *namePtr = ptr;\n  for (;;) {\n    c = toAscii(enc, ptr, end);\n    if (c == -1) {\n      *nextTokPtr = ptr;\n      return 0;\n    }\n    if (c == ASCII_EQUALS) {\n      *nameEndPtr = ptr;\n      break;\n    }\n    if (isSpace(c)) {\n      *nameEndPtr = ptr;\n      do {\n        ptr += enc->minBytesPerChar;\n      } while (isSpace(c = toAscii(enc, ptr, end)));\n      if (c != ASCII_EQUALS) {\n        *nextTokPtr = ptr;\n        return 0;\n      }\n      break;\n    }\n    ptr += enc->minBytesPerChar;\n  }\n  if (ptr == *namePtr) {\n    *nextTokPtr = ptr;\n    return 0;\n  }\n  ptr += enc->minBytesPerChar;\n  c = toAscii(enc, ptr, end);\n  while (isSpace(c)) {\n    ptr += enc->minBytesPerChar;\n    c = toAscii(enc, ptr, end);\n  }\n  if (c != ASCII_QUOT && c != ASCII_APOS) {\n    *nextTokPtr = ptr;\n    return 0;\n  }\n  open = (char)c;\n  ptr += enc->minBytesPerChar;\n  *valPtr = ptr;\n  for (;; ptr += enc->minBytesPerChar) {\n    c = toAscii(enc, ptr, end);\n    if (c == open)\n      break;\n    if (!(ASCII_a <= c && c <= ASCII_z)\n        && !(ASCII_A <= c && c <= ASCII_Z)\n        && !(ASCII_0 <= c && c <= ASCII_9)\n        && c != ASCII_PERIOD\n        && c != ASCII_MINUS\n        && c != ASCII_UNDERSCORE) {\n      *nextTokPtr = ptr;\n      return 0;\n    }\n  }\n  *nextTokPtr = ptr + enc->minBytesPerChar;\n  return 1;\n}\n\nstatic const char KW_version[] = {\n  ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\\0'\n};\n\nstatic const char KW_encoding[] = {\n  ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\\0'\n};\n\nstatic const char KW_standalone[] = {\n  ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o,\n  ASCII_n, ASCII_e, '\\0'\n};\n\nstatic const char KW_yes[] = {\n  ASCII_y, ASCII_e, ASCII_s,  '\\0'\n};\n\nstatic const char KW_no[] = {\n  ASCII_n, ASCII_o,  '\\0'\n};\n\nstatic int\ndoParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,\n                                                 const char *,\n                                                 const char *),\n               int isGeneralTextEntity,\n               const ENCODING *enc,\n               const char *ptr,\n               const char *end,\n               const char **badPtr,\n               const char **versionPtr,\n               const char **versionEndPtr,\n               const char **encodingName,\n               const ENCODING **encoding,\n               int *standalone)\n{\n  const char *val = NULL;\n  const char *name = NULL;\n  const char *nameEnd = NULL;\n  ptr += 5 * enc->minBytesPerChar;\n  end -= 2 * enc->minBytesPerChar;\n  if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)\n      || !name) {\n    *badPtr = ptr;\n    return 0;\n  }\n  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {\n    if (!isGeneralTextEntity) {\n      *badPtr = name;\n      return 0;\n    }\n  }\n  else {\n    if (versionPtr)\n      *versionPtr = val;\n    if (versionEndPtr)\n      *versionEndPtr = ptr;\n    if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {\n      *badPtr = ptr;\n      return 0;\n    }\n    if (!name) {\n      if (isGeneralTextEntity) {\n        /* a TextDecl must have an EncodingDecl */\n        *badPtr = ptr;\n        return 0;\n      }\n      return 1;\n    }\n  }\n  if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {\n    int c = toAscii(enc, val, end);\n    if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) {\n      *badPtr = val;\n      return 0;\n    }\n    if (encodingName)\n      *encodingName = val;\n    if (encoding)\n      *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);\n    if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {\n      *badPtr = ptr;\n      return 0;\n    }\n    if (!name)\n      return 1;\n  }\n  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone)\n      || isGeneralTextEntity) {\n    *badPtr = name;\n    return 0;\n  }\n  if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {\n    if (standalone)\n      *standalone = 1;\n  }\n  else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {\n    if (standalone)\n      *standalone = 0;\n  }\n  else {\n    *badPtr = val;\n    return 0;\n  }\n  while (isSpace(toAscii(enc, ptr, end)))\n    ptr += enc->minBytesPerChar;\n  if (ptr != end) {\n    *badPtr = ptr;\n    return 0;\n  }\n  return 1;\n}\n\nstatic int FASTCALL\ncheckCharRefNumber(int result)\n{\n  switch (result >> 8) {\n  case 0xD8: case 0xD9: case 0xDA: case 0xDB:\n  case 0xDC: case 0xDD: case 0xDE: case 0xDF:\n    return -1;\n  case 0:\n    if (latin1_encoding.type[result] == BT_NONXML)\n      return -1;\n    break;\n  case 0xFF:\n    if (result == 0xFFFE || result == 0xFFFF)\n      return -1;\n    break;\n  }\n  return result;\n}\n\nint FASTCALL\nXmlUtf8Encode(int c, char *buf)\n{\n  enum {\n    /* minN is minimum legal resulting value for N byte sequence */\n    min2 = 0x80,\n    min3 = 0x800,\n    min4 = 0x10000\n  };\n\n  if (c < 0)\n    return 0;\n  if (c < min2) {\n    buf[0] = (char)(c | UTF8_cval1);\n    return 1;\n  }\n  if (c < min3) {\n    buf[0] = (char)((c >> 6) | UTF8_cval2);\n    buf[1] = (char)((c & 0x3f) | 0x80);\n    return 2;\n  }\n  if (c < min4) {\n    buf[0] = (char)((c >> 12) | UTF8_cval3);\n    buf[1] = (char)(((c >> 6) & 0x3f) | 0x80);\n    buf[2] = (char)((c & 0x3f) | 0x80);\n    return 3;\n  }\n  if (c < 0x110000) {\n    buf[0] = (char)((c >> 18) | UTF8_cval4);\n    buf[1] = (char)(((c >> 12) & 0x3f) | 0x80);\n    buf[2] = (char)(((c >> 6) & 0x3f) | 0x80);\n    buf[3] = (char)((c & 0x3f) | 0x80);\n    return 4;\n  }\n  return 0;\n}\n\nint FASTCALL\nXmlUtf16Encode(int charNum, unsigned short *buf)\n{\n  if (charNum < 0)\n    return 0;\n  if (charNum < 0x10000) {\n    buf[0] = (unsigned short)charNum;\n    return 1;\n  }\n  if (charNum < 0x110000) {\n    charNum -= 0x10000;\n    buf[0] = (unsigned short)((charNum >> 10) + 0xD800);\n    buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00);\n    return 2;\n  }\n  return 0;\n}\n\nstruct unknown_encoding {\n  struct normal_encoding normal;\n  CONVERTER convert;\n  void *userData;\n  unsigned short utf16[256];\n  char utf8[256][4];\n};\n\n#define AS_UNKNOWN_ENCODING(enc)  ((const struct unknown_encoding *) (enc))\n\nint\nXmlSizeOfUnknownEncoding(void)\n{\n  return sizeof(struct unknown_encoding);\n}\n\nstatic int PTRFASTCALL\nunknown_isName(const ENCODING *enc, const char *p)\n{\n  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);\n  int c = uenc->convert(uenc->userData, p);\n  if (c & ~0xFFFF)\n    return 0;\n  return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);\n}\n\nstatic int PTRFASTCALL\nunknown_isNmstrt(const ENCODING *enc, const char *p)\n{\n  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);\n  int c = uenc->convert(uenc->userData, p);\n  if (c & ~0xFFFF)\n    return 0;\n  return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);\n}\n\nstatic int PTRFASTCALL\nunknown_isInvalid(const ENCODING *enc, const char *p)\n{\n  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);\n  int c = uenc->convert(uenc->userData, p);\n  return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;\n}\n\nstatic enum XML_Convert_Result PTRCALL\nunknown_toUtf8(const ENCODING *enc,\n               const char **fromP, const char *fromLim,\n               char **toP, const char *toLim)\n{\n  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);\n  char buf[XML_UTF8_ENCODE_MAX];\n  for (;;) {\n    const char *utf8;\n    int n;\n    if (*fromP == fromLim)\n      return XML_CONVERT_COMPLETED;\n    utf8 = uenc->utf8[(unsigned char)**fromP];\n    n = *utf8++;\n    if (n == 0) {\n      int c = uenc->convert(uenc->userData, *fromP);\n      n = XmlUtf8Encode(c, buf);\n      if (n > toLim - *toP)\n        return XML_CONVERT_OUTPUT_EXHAUSTED;\n      utf8 = buf;\n      *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]\n                 - (BT_LEAD2 - 2));\n    }\n    else {\n      if (n > toLim - *toP)\n        return XML_CONVERT_OUTPUT_EXHAUSTED;\n      (*fromP)++;\n    }\n    do {\n      *(*toP)++ = *utf8++;\n    } while (--n != 0);\n  }\n}\n\nstatic enum XML_Convert_Result PTRCALL\nunknown_toUtf16(const ENCODING *enc,\n                const char **fromP, const char *fromLim,\n                unsigned short **toP, const unsigned short *toLim)\n{\n  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);\n  while (*fromP < fromLim && *toP < toLim) {\n    unsigned short c = uenc->utf16[(unsigned char)**fromP];\n    if (c == 0) {\n      c = (unsigned short)\n          uenc->convert(uenc->userData, *fromP);\n      *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]\n                 - (BT_LEAD2 - 2));\n    }\n    else\n      (*fromP)++;\n    *(*toP)++ = c;\n  }\n\n  if ((*toP == toLim) && (*fromP < fromLim))\n    return XML_CONVERT_OUTPUT_EXHAUSTED;\n  else\n    return XML_CONVERT_COMPLETED;\n}\n\nENCODING *\nXmlInitUnknownEncoding(void *mem,\n                       int *table,\n                       CONVERTER convert,\n                       void *userData)\n{\n  int i;\n  struct unknown_encoding *e = (struct unknown_encoding *)mem;\n  for (i = 0; i < (int)sizeof(struct normal_encoding); i++)\n    ((char *)mem)[i] = ((char *)&latin1_encoding)[i];\n  for (i = 0; i < 128; i++)\n    if (latin1_encoding.type[i] != BT_OTHER\n        && latin1_encoding.type[i] != BT_NONXML\n        && table[i] != i)\n      return 0;\n  for (i = 0; i < 256; i++) {\n    int c = table[i];\n    if (c == -1) {\n      e->normal.type[i] = BT_MALFORM;\n      /* This shouldn't really get used. */\n      e->utf16[i] = 0xFFFF;\n      e->utf8[i][0] = 1;\n      e->utf8[i][1] = 0;\n    }\n    else if (c < 0) {\n      if (c < -4)\n        return 0;\n      e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));\n      e->utf8[i][0] = 0;\n      e->utf16[i] = 0;\n    }\n    else if (c < 0x80) {\n      if (latin1_encoding.type[c] != BT_OTHER\n          && latin1_encoding.type[c] != BT_NONXML\n          && c != i)\n        return 0;\n      e->normal.type[i] = latin1_encoding.type[c];\n      e->utf8[i][0] = 1;\n      e->utf8[i][1] = (char)c;\n      e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c);\n    }\n    else if (checkCharRefNumber(c) < 0) {\n      e->normal.type[i] = BT_NONXML;\n      /* This shouldn't really get used. */\n      e->utf16[i] = 0xFFFF;\n      e->utf8[i][0] = 1;\n      e->utf8[i][1] = 0;\n    }\n    else {\n      if (c > 0xFFFF)\n        return 0;\n      if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))\n        e->normal.type[i] = BT_NMSTRT;\n      else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))\n        e->normal.type[i] = BT_NAME;\n      else\n        e->normal.type[i] = BT_OTHER;\n      e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);\n      e->utf16[i] = (unsigned short)c;\n    }\n  }\n  e->userData = userData;\n  e->convert = convert;\n  if (convert) {\n    e->normal.isName2 = unknown_isName;\n    e->normal.isName3 = unknown_isName;\n    e->normal.isName4 = unknown_isName;\n    e->normal.isNmstrt2 = unknown_isNmstrt;\n    e->normal.isNmstrt3 = unknown_isNmstrt;\n    e->normal.isNmstrt4 = unknown_isNmstrt;\n    e->normal.isInvalid2 = unknown_isInvalid;\n    e->normal.isInvalid3 = unknown_isInvalid;\n    e->normal.isInvalid4 = unknown_isInvalid;\n  }\n  e->normal.enc.utf8Convert = unknown_toUtf8;\n  e->normal.enc.utf16Convert = unknown_toUtf16;\n  return &(e->normal.enc);\n}\n\n/* If this enumeration is changed, getEncodingIndex and encodings\nmust also be changed. */\nenum {\n  UNKNOWN_ENC = -1,\n  ISO_8859_1_ENC = 0,\n  US_ASCII_ENC,\n  UTF_8_ENC,\n  UTF_16_ENC,\n  UTF_16BE_ENC,\n  UTF_16LE_ENC,\n  /* must match encodingNames up to here */\n  NO_ENC\n};\n\nstatic const char KW_ISO_8859_1[] = {\n  ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9,\n  ASCII_MINUS, ASCII_1, '\\0'\n};\nstatic const char KW_US_ASCII[] = {\n  ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I,\n  '\\0'\n};\nstatic const char KW_UTF_8[] =  {\n  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\\0'\n};\nstatic const char KW_UTF_16[] = {\n  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\\0'\n};\nstatic const char KW_UTF_16BE[] = {\n  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E,\n  '\\0'\n};\nstatic const char KW_UTF_16LE[] = {\n  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E,\n  '\\0'\n};\n\nstatic int FASTCALL\ngetEncodingIndex(const char *name)\n{\n  static const char * const encodingNames[] = {\n    KW_ISO_8859_1,\n    KW_US_ASCII,\n    KW_UTF_8,\n    KW_UTF_16,\n    KW_UTF_16BE,\n    KW_UTF_16LE,\n  };\n  int i;\n  if (name == NULL)\n    return NO_ENC;\n  for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)\n    if (streqci(name, encodingNames[i]))\n      return i;\n  return UNKNOWN_ENC;\n}\n\n/* For binary compatibility, we store the index of the encoding\n   specified at initialization in the isUtf16 member.\n*/\n\n#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)\n#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)\n\n/* This is what detects the encoding.  encodingTable maps from\n   encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of\n   the external (protocol) specified encoding; state is\n   XML_CONTENT_STATE if we're parsing an external text entity, and\n   XML_PROLOG_STATE otherwise.\n*/\n\n\nstatic int\ninitScan(const ENCODING * const *encodingTable,\n         const INIT_ENCODING *enc,\n         int state,\n         const char *ptr,\n         const char *end,\n         const char **nextTokPtr)\n{\n  const ENCODING **encPtr;\n\n  if (ptr >= end)\n    return XML_TOK_NONE;\n  encPtr = enc->encPtr;\n  if (ptr + 1 == end) {\n    /* only a single byte available for auto-detection */\n#ifndef XML_DTD /* FIXME */\n    /* a well-formed document entity must have more than one byte */\n    if (state != XML_CONTENT_STATE)\n      return XML_TOK_PARTIAL;\n#endif\n    /* so we're parsing an external text entity... */\n    /* if UTF-16 was externally specified, then we need at least 2 bytes */\n    switch (INIT_ENC_INDEX(enc)) {\n    case UTF_16_ENC:\n    case UTF_16LE_ENC:\n    case UTF_16BE_ENC:\n      return XML_TOK_PARTIAL;\n    }\n    switch ((unsigned char)*ptr) {\n    case 0xFE:\n    case 0xFF:\n    case 0xEF: /* possibly first byte of UTF-8 BOM */\n      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC\n          && state == XML_CONTENT_STATE)\n        break;\n      /* fall through */\n    case 0x00:\n    case 0x3C:\n      return XML_TOK_PARTIAL;\n    }\n  }\n  else {\n    switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {\n    case 0xFEFF:\n      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC\n          && state == XML_CONTENT_STATE)\n        break;\n      *nextTokPtr = ptr + 2;\n      *encPtr = encodingTable[UTF_16BE_ENC];\n      return XML_TOK_BOM;\n    /* 00 3C is handled in the default case */\n    case 0x3C00:\n      if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC\n           || INIT_ENC_INDEX(enc) == UTF_16_ENC)\n          && state == XML_CONTENT_STATE)\n        break;\n      *encPtr = encodingTable[UTF_16LE_ENC];\n      return XmlTok(*encPtr, state, ptr, end, nextTokPtr);\n    case 0xFFFE:\n      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC\n          && state == XML_CONTENT_STATE)\n        break;\n      *nextTokPtr = ptr + 2;\n      *encPtr = encodingTable[UTF_16LE_ENC];\n      return XML_TOK_BOM;\n    case 0xEFBB:\n      /* Maybe a UTF-8 BOM (EF BB BF) */\n      /* If there's an explicitly specified (external) encoding\n         of ISO-8859-1 or some flavour of UTF-16\n         and this is an external text entity,\n         don't look for the BOM,\n         because it might be a legal data.\n      */\n      if (state == XML_CONTENT_STATE) {\n        int e = INIT_ENC_INDEX(enc);\n        if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC\n            || e == UTF_16LE_ENC || e == UTF_16_ENC)\n          break;\n      }\n      if (ptr + 2 == end)\n        return XML_TOK_PARTIAL;\n      if ((unsigned char)ptr[2] == 0xBF) {\n        *nextTokPtr = ptr + 3;\n        *encPtr = encodingTable[UTF_8_ENC];\n        return XML_TOK_BOM;\n      }\n      break;\n    default:\n      if (ptr[0] == '\\0') {\n        /* 0 isn't a legal data character. Furthermore a document\n           entity can only start with ASCII characters.  So the only\n           way this can fail to be big-endian UTF-16 if it it's an\n           external parsed general entity that's labelled as\n           UTF-16LE.\n        */\n        if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)\n          break;\n        *encPtr = encodingTable[UTF_16BE_ENC];\n        return XmlTok(*encPtr, state, ptr, end, nextTokPtr);\n      }\n      else if (ptr[1] == '\\0') {\n        /* We could recover here in the case:\n            - parsing an external entity\n            - second byte is 0\n            - no externally specified encoding\n            - no encoding declaration\n           by assuming UTF-16LE.  But we don't, because this would mean when\n           presented just with a single byte, we couldn't reliably determine\n           whether we needed further bytes.\n        */\n        if (state == XML_CONTENT_STATE)\n          break;\n        *encPtr = encodingTable[UTF_16LE_ENC];\n        return XmlTok(*encPtr, state, ptr, end, nextTokPtr);\n      }\n      break;\n    }\n  }\n  *encPtr = encodingTable[INIT_ENC_INDEX(enc)];\n  return XmlTok(*encPtr, state, ptr, end, nextTokPtr);\n}\n\n\n#define NS(x) x\n#define ns(x) x\n#define XML_TOK_NS_C\n#include \"xmltok_ns.c\"\n#undef XML_TOK_NS_C\n#undef NS\n#undef ns\n\n#ifdef XML_NS\n\n#define NS(x) x ## NS\n#define ns(x) x ## _ns\n\n#define XML_TOK_NS_C\n#include \"xmltok_ns.c\"\n#undef XML_TOK_NS_C\n\n#undef NS\n#undef ns\n\nENCODING *\nXmlInitUnknownEncodingNS(void *mem,\n                         int *table,\n                         CONVERTER convert,\n                         void *userData)\n{\n  ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);\n  if (enc)\n    ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;\n  return enc;\n}\n\n#endif /* XML_NS */\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/xmltok.h",
    "content": "/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd\n   See the file COPYING for copying permission.\n*/\n\n#ifndef XmlTok_INCLUDED\n#define XmlTok_INCLUDED 1\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* The following token may be returned by XmlContentTok */\n#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be\n                                    start of illegal ]]> sequence */\n/* The following tokens may be returned by both XmlPrologTok and\n   XmlContentTok.\n*/\n#define XML_TOK_NONE -4          /* The string to be scanned is empty */\n#define XML_TOK_TRAILING_CR -3   /* A CR at the end of the scan;\n                                    might be part of CRLF sequence */\n#define XML_TOK_PARTIAL_CHAR -2  /* only part of a multibyte sequence */\n#define XML_TOK_PARTIAL -1       /* only part of a token */\n#define XML_TOK_INVALID 0\n\n/* The following tokens are returned by XmlContentTok; some are also\n   returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok.\n*/\n#define XML_TOK_START_TAG_WITH_ATTS 1\n#define XML_TOK_START_TAG_NO_ATTS 2\n#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */\n#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4\n#define XML_TOK_END_TAG 5\n#define XML_TOK_DATA_CHARS 6\n#define XML_TOK_DATA_NEWLINE 7\n#define XML_TOK_CDATA_SECT_OPEN 8\n#define XML_TOK_ENTITY_REF 9\n#define XML_TOK_CHAR_REF 10               /* numeric character reference */\n\n/* The following tokens may be returned by both XmlPrologTok and\n   XmlContentTok.\n*/\n#define XML_TOK_PI 11                     /* processing instruction */\n#define XML_TOK_XML_DECL 12               /* XML decl or text decl */\n#define XML_TOK_COMMENT 13\n#define XML_TOK_BOM 14                    /* Byte order mark */\n\n/* The following tokens are returned only by XmlPrologTok */\n#define XML_TOK_PROLOG_S 15\n#define XML_TOK_DECL_OPEN 16              /* <!foo */\n#define XML_TOK_DECL_CLOSE 17             /* > */\n#define XML_TOK_NAME 18\n#define XML_TOK_NMTOKEN 19\n#define XML_TOK_POUND_NAME 20             /* #name */\n#define XML_TOK_OR 21                     /* | */\n#define XML_TOK_PERCENT 22\n#define XML_TOK_OPEN_PAREN 23\n#define XML_TOK_CLOSE_PAREN 24\n#define XML_TOK_OPEN_BRACKET 25\n#define XML_TOK_CLOSE_BRACKET 26\n#define XML_TOK_LITERAL 27\n#define XML_TOK_PARAM_ENTITY_REF 28\n#define XML_TOK_INSTANCE_START 29\n\n/* The following occur only in element type declarations */\n#define XML_TOK_NAME_QUESTION 30          /* name? */\n#define XML_TOK_NAME_ASTERISK 31          /* name* */\n#define XML_TOK_NAME_PLUS 32              /* name+ */\n#define XML_TOK_COND_SECT_OPEN 33         /* <![ */\n#define XML_TOK_COND_SECT_CLOSE 34        /* ]]> */\n#define XML_TOK_CLOSE_PAREN_QUESTION 35   /* )? */\n#define XML_TOK_CLOSE_PAREN_ASTERISK 36   /* )* */\n#define XML_TOK_CLOSE_PAREN_PLUS 37       /* )+ */\n#define XML_TOK_COMMA 38\n\n/* The following token is returned only by XmlAttributeValueTok */\n#define XML_TOK_ATTRIBUTE_VALUE_S 39\n\n/* The following token is returned only by XmlCdataSectionTok */\n#define XML_TOK_CDATA_SECT_CLOSE 40\n\n/* With namespace processing this is returned by XmlPrologTok for a\n   name with a colon.\n*/\n#define XML_TOK_PREFIXED_NAME 41\n\n#ifdef XML_DTD\n#define XML_TOK_IGNORE_SECT 42\n#endif /* XML_DTD */\n\n#ifdef XML_DTD\n#define XML_N_STATES 4\n#else /* not XML_DTD */\n#define XML_N_STATES 3\n#endif /* not XML_DTD */\n\n#define XML_PROLOG_STATE 0\n#define XML_CONTENT_STATE 1\n#define XML_CDATA_SECTION_STATE 2\n#ifdef XML_DTD\n#define XML_IGNORE_SECTION_STATE 3\n#endif /* XML_DTD */\n\n#define XML_N_LITERAL_TYPES 2\n#define XML_ATTRIBUTE_VALUE_LITERAL 0\n#define XML_ENTITY_VALUE_LITERAL 1\n\n/* The size of the buffer passed to XmlUtf8Encode must be at least this. */\n#define XML_UTF8_ENCODE_MAX 4\n/* The size of the buffer passed to XmlUtf16Encode must be at least this. */\n#define XML_UTF16_ENCODE_MAX 2\n\ntypedef struct position {\n  /* first line and first column are 0 not 1 */\n  XML_Size lineNumber;\n  XML_Size columnNumber;\n} POSITION;\n\ntypedef struct {\n  const char *name;\n  const char *valuePtr;\n  const char *valueEnd;\n  char normalized;\n} ATTRIBUTE;\n\nstruct encoding;\ntypedef struct encoding ENCODING;\n\ntypedef int (PTRCALL *SCANNER)(const ENCODING *,\n                               const char *,\n                               const char *,\n                               const char **);\n\nenum XML_Convert_Result {\n  XML_CONVERT_COMPLETED = 0,\n  XML_CONVERT_INPUT_INCOMPLETE = 1,\n  XML_CONVERT_OUTPUT_EXHAUSTED = 2  /* and therefore potentially input remaining as well */\n};\n\nstruct encoding {\n  SCANNER scanners[XML_N_STATES];\n  SCANNER literalScanners[XML_N_LITERAL_TYPES];\n  int (PTRCALL *sameName)(const ENCODING *,\n                          const char *,\n                          const char *);\n  int (PTRCALL *nameMatchesAscii)(const ENCODING *,\n                                  const char *,\n                                  const char *,\n                                  const char *);\n  int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);\n  const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);\n  int (PTRCALL *getAtts)(const ENCODING *enc,\n                         const char *ptr,\n                         int attsMax,\n                         ATTRIBUTE *atts);\n  int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);\n  int (PTRCALL *predefinedEntityName)(const ENCODING *,\n                                      const char *,\n                                      const char *);\n  void (PTRCALL *updatePosition)(const ENCODING *,\n                                 const char *ptr,\n                                 const char *end,\n                                 POSITION *);\n  int (PTRCALL *isPublicId)(const ENCODING *enc,\n                            const char *ptr,\n                            const char *end,\n                            const char **badPtr);\n  enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc,\n                              const char **fromP,\n                              const char *fromLim,\n                              char **toP,\n                              const char *toLim);\n  enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc,\n                               const char **fromP,\n                               const char *fromLim,\n                               unsigned short **toP,\n                               const unsigned short *toLim);\n  int minBytesPerChar;\n  char isUtf8;\n  char isUtf16;\n};\n\n/* Scan the string starting at ptr until the end of the next complete\n   token, but do not scan past eptr.  Return an integer giving the\n   type of token.\n\n   Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.\n\n   Return XML_TOK_PARTIAL when the string does not contain a complete\n   token; nextTokPtr will not be set.\n\n   Return XML_TOK_INVALID when the string does not start a valid\n   token; nextTokPtr will be set to point to the character which made\n   the token invalid.\n\n   Otherwise the string starts with a valid token; nextTokPtr will be\n   set to point to the character following the end of that token.\n\n   Each data character counts as a single token, but adjacent data\n   characters may be returned together.  Similarly for characters in\n   the prolog outside literals, comments and processing instructions.\n*/\n\n\n#define XmlTok(enc, state, ptr, end, nextTokPtr) \\\n  (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))\n\n#define XmlPrologTok(enc, ptr, end, nextTokPtr) \\\n   XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)\n\n#define XmlContentTok(enc, ptr, end, nextTokPtr) \\\n   XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)\n\n#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \\\n   XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)\n\n#ifdef XML_DTD\n\n#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \\\n   XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)\n\n#endif /* XML_DTD */\n\n/* This is used for performing a 2nd-level tokenization on the content\n   of a literal that has already been returned by XmlTok.\n*/\n#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \\\n  (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))\n\n#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \\\n   XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)\n\n#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \\\n   XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)\n\n#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))\n\n#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \\\n  (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))\n\n#define XmlNameLength(enc, ptr) \\\n  (((enc)->nameLength)(enc, ptr))\n\n#define XmlSkipS(enc, ptr) \\\n  (((enc)->skipS)(enc, ptr))\n\n#define XmlGetAttributes(enc, ptr, attsMax, atts) \\\n  (((enc)->getAtts)(enc, ptr, attsMax, atts))\n\n#define XmlCharRefNumber(enc, ptr) \\\n  (((enc)->charRefNumber)(enc, ptr))\n\n#define XmlPredefinedEntityName(enc, ptr, end) \\\n  (((enc)->predefinedEntityName)(enc, ptr, end))\n\n#define XmlUpdatePosition(enc, ptr, end, pos) \\\n  (((enc)->updatePosition)(enc, ptr, end, pos))\n\n#define XmlIsPublicId(enc, ptr, end, badPtr) \\\n  (((enc)->isPublicId)(enc, ptr, end, badPtr))\n\n#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \\\n  (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))\n\n#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \\\n  (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))\n\ntypedef struct {\n  ENCODING initEnc;\n  const ENCODING **encPtr;\n} INIT_ENCODING;\n\nint XmlParseXmlDecl(int isGeneralTextEntity,\n                    const ENCODING *enc,\n                    const char *ptr,\n                    const char *end,\n                    const char **badPtr,\n                    const char **versionPtr,\n                    const char **versionEndPtr,\n                    const char **encodingNamePtr,\n                    const ENCODING **namedEncodingPtr,\n                    int *standalonePtr);\n\nint XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);\nconst ENCODING *XmlGetUtf8InternalEncoding(void);\nconst ENCODING *XmlGetUtf16InternalEncoding(void);\nint FASTCALL XmlUtf8Encode(int charNumber, char *buf);\nint FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);\nint XmlSizeOfUnknownEncoding(void);\n\n\ntypedef int (XMLCALL *CONVERTER) (void *userData, const char *p);\n\nENCODING *\nXmlInitUnknownEncoding(void *mem,\n                       int *table,\n                       CONVERTER convert,\n                       void *userData);\n\nint XmlParseXmlDeclNS(int isGeneralTextEntity,\n                      const ENCODING *enc,\n                      const char *ptr,\n                      const char *end,\n                      const char **badPtr,\n                      const char **versionPtr,\n                      const char **versionEndPtr,\n                      const char **encodingNamePtr,\n                      const ENCODING **namedEncodingPtr,\n                      int *standalonePtr);\n\nint XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);\nconst ENCODING *XmlGetUtf8InternalEncodingNS(void);\nconst ENCODING *XmlGetUtf16InternalEncodingNS(void);\nENCODING *\nXmlInitUnknownEncodingNS(void *mem,\n                         int *table,\n                         CONVERTER convert,\n                         void *userData);\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* not XmlTok_INCLUDED */\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/xmltok_impl.c",
    "content": "/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd\n   See the file COPYING for copying permission.\n*/\n\n/* This file is included! */\n#ifdef XML_TOK_IMPL_C\n\n#ifndef IS_INVALID_CHAR\n#define IS_INVALID_CHAR(enc, ptr, n) (0)\n#endif\n\n#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \\\n    case BT_LEAD ## n: \\\n      if (end - ptr < n) \\\n        return XML_TOK_PARTIAL_CHAR; \\\n      if (IS_INVALID_CHAR(enc, ptr, n)) { \\\n        *(nextTokPtr) = (ptr); \\\n        return XML_TOK_INVALID; \\\n      } \\\n      ptr += n; \\\n      break;\n\n#define INVALID_CASES(ptr, nextTokPtr) \\\n  INVALID_LEAD_CASE(2, ptr, nextTokPtr) \\\n  INVALID_LEAD_CASE(3, ptr, nextTokPtr) \\\n  INVALID_LEAD_CASE(4, ptr, nextTokPtr) \\\n  case BT_NONXML: \\\n  case BT_MALFORM: \\\n  case BT_TRAIL: \\\n    *(nextTokPtr) = (ptr); \\\n    return XML_TOK_INVALID;\n\n#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \\\n   case BT_LEAD ## n: \\\n     if (end - ptr < n) \\\n       return XML_TOK_PARTIAL_CHAR; \\\n     if (!IS_NAME_CHAR(enc, ptr, n)) { \\\n       *nextTokPtr = ptr; \\\n       return XML_TOK_INVALID; \\\n     } \\\n     ptr += n; \\\n     break;\n\n#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \\\n  case BT_NONASCII: \\\n    if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \\\n      *nextTokPtr = ptr; \\\n      return XML_TOK_INVALID; \\\n    } \\\n  case BT_NMSTRT: \\\n  case BT_HEX: \\\n  case BT_DIGIT: \\\n  case BT_NAME: \\\n  case BT_MINUS: \\\n    ptr += MINBPC(enc); \\\n    break; \\\n  CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \\\n  CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \\\n  CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)\n\n#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \\\n   case BT_LEAD ## n: \\\n     if (end - ptr < n) \\\n       return XML_TOK_PARTIAL_CHAR; \\\n     if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \\\n       *nextTokPtr = ptr; \\\n       return XML_TOK_INVALID; \\\n     } \\\n     ptr += n; \\\n     break;\n\n#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \\\n  case BT_NONASCII: \\\n    if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \\\n      *nextTokPtr = ptr; \\\n      return XML_TOK_INVALID; \\\n    } \\\n  case BT_NMSTRT: \\\n  case BT_HEX: \\\n    ptr += MINBPC(enc); \\\n    break; \\\n  CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \\\n  CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \\\n  CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)\n\n#ifndef PREFIX\n#define PREFIX(ident) ident\n#endif\n\n/* ptr points to character following \"<!-\" */\n\nstatic int PTRCALL\nPREFIX(scanComment)(const ENCODING *enc, const char *ptr,\n                    const char *end, const char **nextTokPtr)\n{\n  if (ptr < end) {\n    if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    }\n    ptr += MINBPC(enc);\n    while (ptr < end) {\n      switch (BYTE_TYPE(enc, ptr)) {\n      INVALID_CASES(ptr, nextTokPtr)\n      case BT_MINUS:\n        if ((ptr += MINBPC(enc)) == end)\n          return XML_TOK_PARTIAL;\n        if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {\n          if ((ptr += MINBPC(enc)) == end)\n            return XML_TOK_PARTIAL;\n          if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {\n            *nextTokPtr = ptr;\n            return XML_TOK_INVALID;\n          }\n          *nextTokPtr = ptr + MINBPC(enc);\n          return XML_TOK_COMMENT;\n        }\n        break;\n      default:\n        ptr += MINBPC(enc);\n        break;\n      }\n    }\n  }\n  return XML_TOK_PARTIAL;\n}\n\n/* ptr points to character following \"<!\" */\n\nstatic int PTRCALL\nPREFIX(scanDecl)(const ENCODING *enc, const char *ptr,\n                 const char *end, const char **nextTokPtr)\n{\n  if (ptr == end)\n    return XML_TOK_PARTIAL;\n  switch (BYTE_TYPE(enc, ptr)) {\n  case BT_MINUS:\n    return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);\n  case BT_LSQB:\n    *nextTokPtr = ptr + MINBPC(enc);\n    return XML_TOK_COND_SECT_OPEN;\n  case BT_NMSTRT:\n  case BT_HEX:\n    ptr += MINBPC(enc);\n    break;\n  default:\n    *nextTokPtr = ptr;\n    return XML_TOK_INVALID;\n  }\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n    case BT_PERCNT:\n      if (ptr + MINBPC(enc) == end)\n        return XML_TOK_PARTIAL;\n      /* don't allow <!ENTITY% foo \"whatever\"> */\n      switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {\n      case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:\n        *nextTokPtr = ptr;\n        return XML_TOK_INVALID;\n      }\n      /* fall through */\n    case BT_S: case BT_CR: case BT_LF:\n      *nextTokPtr = ptr;\n      return XML_TOK_DECL_OPEN;\n    case BT_NMSTRT:\n    case BT_HEX:\n      ptr += MINBPC(enc);\n      break;\n    default:\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    }\n  }\n  return XML_TOK_PARTIAL;\n}\n\nstatic int PTRCALL\nPREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr,\n                      const char *end, int *tokPtr)\n{\n  int upper = 0;\n  *tokPtr = XML_TOK_PI;\n  if (end - ptr != MINBPC(enc)*3)\n    return 1;\n  switch (BYTE_TO_ASCII(enc, ptr)) {\n  case ASCII_x:\n    break;\n  case ASCII_X:\n    upper = 1;\n    break;\n  default:\n    return 1;\n  }\n  ptr += MINBPC(enc);\n  switch (BYTE_TO_ASCII(enc, ptr)) {\n  case ASCII_m:\n    break;\n  case ASCII_M:\n    upper = 1;\n    break;\n  default:\n    return 1;\n  }\n  ptr += MINBPC(enc);\n  switch (BYTE_TO_ASCII(enc, ptr)) {\n  case ASCII_l:\n    break;\n  case ASCII_L:\n    upper = 1;\n    break;\n  default:\n    return 1;\n  }\n  if (upper)\n    return 0;\n  *tokPtr = XML_TOK_XML_DECL;\n  return 1;\n}\n\n/* ptr points to character following \"<?\" */\n\nstatic int PTRCALL\nPREFIX(scanPi)(const ENCODING *enc, const char *ptr,\n               const char *end, const char **nextTokPtr)\n{\n  int tok;\n  const char *target = ptr;\n  if (ptr == end)\n    return XML_TOK_PARTIAL;\n  switch (BYTE_TYPE(enc, ptr)) {\n  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)\n  default:\n    *nextTokPtr = ptr;\n    return XML_TOK_INVALID;\n  }\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)\n    case BT_S: case BT_CR: case BT_LF:\n      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {\n        *nextTokPtr = ptr;\n        return XML_TOK_INVALID;\n      }\n      ptr += MINBPC(enc);\n      while (ptr < end) {\n        switch (BYTE_TYPE(enc, ptr)) {\n        INVALID_CASES(ptr, nextTokPtr)\n        case BT_QUEST:\n          ptr += MINBPC(enc);\n          if (ptr == end)\n            return XML_TOK_PARTIAL;\n          if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {\n            *nextTokPtr = ptr + MINBPC(enc);\n            return tok;\n          }\n          break;\n        default:\n          ptr += MINBPC(enc);\n          break;\n        }\n      }\n      return XML_TOK_PARTIAL;\n    case BT_QUEST:\n      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {\n        *nextTokPtr = ptr;\n        return XML_TOK_INVALID;\n      }\n      ptr += MINBPC(enc);\n      if (ptr == end)\n        return XML_TOK_PARTIAL;\n      if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {\n        *nextTokPtr = ptr + MINBPC(enc);\n        return tok;\n      }\n      /* fall through */\n    default:\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    }\n  }\n  return XML_TOK_PARTIAL;\n}\n\nstatic int PTRCALL\nPREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr,\n                         const char *end, const char **nextTokPtr)\n{\n  static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A,\n                                     ASCII_T, ASCII_A, ASCII_LSQB };\n  int i;\n  /* CDATA[ */\n  if (end - ptr < 6 * MINBPC(enc))\n    return XML_TOK_PARTIAL;\n  for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {\n    if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    }\n  }\n  *nextTokPtr = ptr;\n  return XML_TOK_CDATA_SECT_OPEN;\n}\n\nstatic int PTRCALL\nPREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,\n                        const char *end, const char **nextTokPtr)\n{\n  if (ptr >= end)\n    return XML_TOK_NONE;\n  if (MINBPC(enc) > 1) {\n    size_t n = end - ptr;\n    if (n & (MINBPC(enc) - 1)) {\n      n &= ~(MINBPC(enc) - 1);\n      if (n == 0)\n        return XML_TOK_PARTIAL;\n      end = ptr + n;\n    }\n  }\n  switch (BYTE_TYPE(enc, ptr)) {\n  case BT_RSQB:\n    ptr += MINBPC(enc);\n    if (ptr == end)\n      return XML_TOK_PARTIAL;\n    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))\n      break;\n    ptr += MINBPC(enc);\n    if (ptr == end)\n      return XML_TOK_PARTIAL;\n    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {\n      ptr -= MINBPC(enc);\n      break;\n    }\n    *nextTokPtr = ptr + MINBPC(enc);\n    return XML_TOK_CDATA_SECT_CLOSE;\n  case BT_CR:\n    ptr += MINBPC(enc);\n    if (ptr == end)\n      return XML_TOK_PARTIAL;\n    if (BYTE_TYPE(enc, ptr) == BT_LF)\n      ptr += MINBPC(enc);\n    *nextTokPtr = ptr;\n    return XML_TOK_DATA_NEWLINE;\n  case BT_LF:\n    *nextTokPtr = ptr + MINBPC(enc);\n    return XML_TOK_DATA_NEWLINE;\n  INVALID_CASES(ptr, nextTokPtr)\n  default:\n    ptr += MINBPC(enc);\n    break;\n  }\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n#define LEAD_CASE(n) \\\n    case BT_LEAD ## n: \\\n      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \\\n        *nextTokPtr = ptr; \\\n        return XML_TOK_DATA_CHARS; \\\n      } \\\n      ptr += n; \\\n      break;\n    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)\n#undef LEAD_CASE\n    case BT_NONXML:\n    case BT_MALFORM:\n    case BT_TRAIL:\n    case BT_CR:\n    case BT_LF:\n    case BT_RSQB:\n      *nextTokPtr = ptr;\n      return XML_TOK_DATA_CHARS;\n    default:\n      ptr += MINBPC(enc);\n      break;\n    }\n  }\n  *nextTokPtr = ptr;\n  return XML_TOK_DATA_CHARS;\n}\n\n/* ptr points to character following \"</\" */\n\nstatic int PTRCALL\nPREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,\n                   const char *end, const char **nextTokPtr)\n{\n  if (ptr == end)\n    return XML_TOK_PARTIAL;\n  switch (BYTE_TYPE(enc, ptr)) {\n  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)\n  default:\n    *nextTokPtr = ptr;\n    return XML_TOK_INVALID;\n  }\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)\n    case BT_S: case BT_CR: case BT_LF:\n      for (ptr += MINBPC(enc); ptr < end; ptr += MINBPC(enc)) {\n        switch (BYTE_TYPE(enc, ptr)) {\n        case BT_S: case BT_CR: case BT_LF:\n          break;\n        case BT_GT:\n          *nextTokPtr = ptr + MINBPC(enc);\n          return XML_TOK_END_TAG;\n        default:\n          *nextTokPtr = ptr;\n          return XML_TOK_INVALID;\n        }\n      }\n      return XML_TOK_PARTIAL;\n#ifdef XML_NS\n    case BT_COLON:\n      /* no need to check qname syntax here,\n         since end-tag must match exactly */\n      ptr += MINBPC(enc);\n      break;\n#endif\n    case BT_GT:\n      *nextTokPtr = ptr + MINBPC(enc);\n      return XML_TOK_END_TAG;\n    default:\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    }\n  }\n  return XML_TOK_PARTIAL;\n}\n\n/* ptr points to character following \"&#X\" */\n\nstatic int PTRCALL\nPREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,\n                       const char *end, const char **nextTokPtr)\n{\n  if (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n    case BT_DIGIT:\n    case BT_HEX:\n      break;\n    default:\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    }\n    for (ptr += MINBPC(enc); ptr < end; ptr += MINBPC(enc)) {\n      switch (BYTE_TYPE(enc, ptr)) {\n      case BT_DIGIT:\n      case BT_HEX:\n        break;\n      case BT_SEMI:\n        *nextTokPtr = ptr + MINBPC(enc);\n        return XML_TOK_CHAR_REF;\n      default:\n        *nextTokPtr = ptr;\n        return XML_TOK_INVALID;\n      }\n    }\n  }\n  return XML_TOK_PARTIAL;\n}\n\n/* ptr points to character following \"&#\" */\n\nstatic int PTRCALL\nPREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,\n                    const char *end, const char **nextTokPtr)\n{\n  if (ptr < end) {\n    if (CHAR_MATCHES(enc, ptr, ASCII_x))\n      return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);\n    switch (BYTE_TYPE(enc, ptr)) {\n    case BT_DIGIT:\n      break;\n    default:\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    }\n    for (ptr += MINBPC(enc); ptr < end; ptr += MINBPC(enc)) {\n      switch (BYTE_TYPE(enc, ptr)) {\n      case BT_DIGIT:\n        break;\n      case BT_SEMI:\n        *nextTokPtr = ptr + MINBPC(enc);\n        return XML_TOK_CHAR_REF;\n      default:\n        *nextTokPtr = ptr;\n        return XML_TOK_INVALID;\n      }\n    }\n  }\n  return XML_TOK_PARTIAL;\n}\n\n/* ptr points to character following \"&\" */\n\nstatic int PTRCALL\nPREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,\n                const char **nextTokPtr)\n{\n  if (ptr == end)\n    return XML_TOK_PARTIAL;\n  switch (BYTE_TYPE(enc, ptr)) {\n  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)\n  case BT_NUM:\n    return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);\n  default:\n    *nextTokPtr = ptr;\n    return XML_TOK_INVALID;\n  }\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)\n    case BT_SEMI:\n      *nextTokPtr = ptr + MINBPC(enc);\n      return XML_TOK_ENTITY_REF;\n    default:\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    }\n  }\n  return XML_TOK_PARTIAL;\n}\n\n/* ptr points to character following first character of attribute name */\n\nstatic int PTRCALL\nPREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,\n                 const char **nextTokPtr)\n{\n#ifdef XML_NS\n  int hadColon = 0;\n#endif\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)\n#ifdef XML_NS\n    case BT_COLON:\n      if (hadColon) {\n        *nextTokPtr = ptr;\n        return XML_TOK_INVALID;\n      }\n      hadColon = 1;\n      ptr += MINBPC(enc);\n      if (ptr == end)\n        return XML_TOK_PARTIAL;\n      switch (BYTE_TYPE(enc, ptr)) {\n      CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)\n      default:\n        *nextTokPtr = ptr;\n        return XML_TOK_INVALID;\n      }\n      break;\n#endif\n    case BT_S: case BT_CR: case BT_LF:\n      for (;;) {\n        int t;\n\n        ptr += MINBPC(enc);\n        if (ptr == end)\n          return XML_TOK_PARTIAL;\n        t = BYTE_TYPE(enc, ptr);\n        if (t == BT_EQUALS)\n          break;\n        switch (t) {\n        case BT_S:\n        case BT_LF:\n        case BT_CR:\n          break;\n        default:\n          *nextTokPtr = ptr;\n          return XML_TOK_INVALID;\n        }\n      }\n    /* fall through */\n    case BT_EQUALS:\n      {\n        int open;\n#ifdef XML_NS\n        hadColon = 0;\n#endif\n        for (;;) {\n          ptr += MINBPC(enc);\n          if (ptr == end)\n            return XML_TOK_PARTIAL;\n          open = BYTE_TYPE(enc, ptr);\n          if (open == BT_QUOT || open == BT_APOS)\n            break;\n          switch (open) {\n          case BT_S:\n          case BT_LF:\n          case BT_CR:\n            break;\n          default:\n            *nextTokPtr = ptr;\n            return XML_TOK_INVALID;\n          }\n        }\n        ptr += MINBPC(enc);\n        /* in attribute value */\n        for (;;) {\n          int t;\n          if (ptr == end)\n            return XML_TOK_PARTIAL;\n          t = BYTE_TYPE(enc, ptr);\n          if (t == open)\n            break;\n          switch (t) {\n          INVALID_CASES(ptr, nextTokPtr)\n          case BT_AMP:\n            {\n              int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);\n              if (tok <= 0) {\n                if (tok == XML_TOK_INVALID)\n                  *nextTokPtr = ptr;\n                return tok;\n              }\n              break;\n            }\n          case BT_LT:\n            *nextTokPtr = ptr;\n            return XML_TOK_INVALID;\n          default:\n            ptr += MINBPC(enc);\n            break;\n          }\n        }\n        ptr += MINBPC(enc);\n        if (ptr == end)\n          return XML_TOK_PARTIAL;\n        switch (BYTE_TYPE(enc, ptr)) {\n        case BT_S:\n        case BT_CR:\n        case BT_LF:\n          break;\n        case BT_SOL:\n          goto sol;\n        case BT_GT:\n          goto gt;\n        default:\n          *nextTokPtr = ptr;\n          return XML_TOK_INVALID;\n        }\n        /* ptr points to closing quote */\n        for (;;) {\n          ptr += MINBPC(enc);\n          if (ptr == end)\n            return XML_TOK_PARTIAL;\n          switch (BYTE_TYPE(enc, ptr)) {\n          CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)\n          case BT_S: case BT_CR: case BT_LF:\n            continue;\n          case BT_GT:\n          gt:\n            *nextTokPtr = ptr + MINBPC(enc);\n            return XML_TOK_START_TAG_WITH_ATTS;\n          case BT_SOL:\n          sol:\n            ptr += MINBPC(enc);\n            if (ptr == end)\n              return XML_TOK_PARTIAL;\n            if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {\n              *nextTokPtr = ptr;\n              return XML_TOK_INVALID;\n            }\n            *nextTokPtr = ptr + MINBPC(enc);\n            return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;\n          default:\n            *nextTokPtr = ptr;\n            return XML_TOK_INVALID;\n          }\n          break;\n        }\n        break;\n      }\n    default:\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    }\n  }\n  return XML_TOK_PARTIAL;\n}\n\n/* ptr points to character following \"<\" */\n\nstatic int PTRCALL\nPREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,\n               const char **nextTokPtr)\n{\n#ifdef XML_NS\n  int hadColon;\n#endif\n  if (ptr == end)\n    return XML_TOK_PARTIAL;\n  switch (BYTE_TYPE(enc, ptr)) {\n  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)\n  case BT_EXCL:\n    if ((ptr += MINBPC(enc)) == end)\n      return XML_TOK_PARTIAL;\n    switch (BYTE_TYPE(enc, ptr)) {\n    case BT_MINUS:\n      return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);\n    case BT_LSQB:\n      return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc),\n                                      end, nextTokPtr);\n    }\n    *nextTokPtr = ptr;\n    return XML_TOK_INVALID;\n  case BT_QUEST:\n    return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);\n  case BT_SOL:\n    return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);\n  default:\n    *nextTokPtr = ptr;\n    return XML_TOK_INVALID;\n  }\n#ifdef XML_NS\n  hadColon = 0;\n#endif\n  /* we have a start-tag */\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)\n#ifdef XML_NS\n    case BT_COLON:\n      if (hadColon) {\n        *nextTokPtr = ptr;\n        return XML_TOK_INVALID;\n      }\n      hadColon = 1;\n      ptr += MINBPC(enc);\n      if (ptr == end)\n        return XML_TOK_PARTIAL;\n      switch (BYTE_TYPE(enc, ptr)) {\n      CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)\n      default:\n        *nextTokPtr = ptr;\n        return XML_TOK_INVALID;\n      }\n      break;\n#endif\n    case BT_S: case BT_CR: case BT_LF:\n      {\n        ptr += MINBPC(enc);\n        while (ptr < end) {\n          switch (BYTE_TYPE(enc, ptr)) {\n          CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)\n          case BT_GT:\n            goto gt;\n          case BT_SOL:\n            goto sol;\n          case BT_S: case BT_CR: case BT_LF:\n            ptr += MINBPC(enc);\n            continue;\n          default:\n            *nextTokPtr = ptr;\n            return XML_TOK_INVALID;\n          }\n          return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);\n        }\n        return XML_TOK_PARTIAL;\n      }\n    case BT_GT:\n    gt:\n      *nextTokPtr = ptr + MINBPC(enc);\n      return XML_TOK_START_TAG_NO_ATTS;\n    case BT_SOL:\n    sol:\n      ptr += MINBPC(enc);\n      if (ptr == end)\n        return XML_TOK_PARTIAL;\n      if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {\n        *nextTokPtr = ptr;\n        return XML_TOK_INVALID;\n      }\n      *nextTokPtr = ptr + MINBPC(enc);\n      return XML_TOK_EMPTY_ELEMENT_NO_ATTS;\n    default:\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    }\n  }\n  return XML_TOK_PARTIAL;\n}\n\nstatic int PTRCALL\nPREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,\n                   const char **nextTokPtr)\n{\n  if (ptr >= end)\n    return XML_TOK_NONE;\n  if (MINBPC(enc) > 1) {\n    size_t n = end - ptr;\n    if (n & (MINBPC(enc) - 1)) {\n      n &= ~(MINBPC(enc) - 1);\n      if (n == 0)\n        return XML_TOK_PARTIAL;\n      end = ptr + n;\n    }\n  }\n  switch (BYTE_TYPE(enc, ptr)) {\n  case BT_LT:\n    return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);\n  case BT_AMP:\n    return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);\n  case BT_CR:\n    ptr += MINBPC(enc);\n    if (ptr == end)\n      return XML_TOK_TRAILING_CR;\n    if (BYTE_TYPE(enc, ptr) == BT_LF)\n      ptr += MINBPC(enc);\n    *nextTokPtr = ptr;\n    return XML_TOK_DATA_NEWLINE;\n  case BT_LF:\n    *nextTokPtr = ptr + MINBPC(enc);\n    return XML_TOK_DATA_NEWLINE;\n  case BT_RSQB:\n    ptr += MINBPC(enc);\n    if (ptr == end)\n      return XML_TOK_TRAILING_RSQB;\n    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))\n      break;\n    ptr += MINBPC(enc);\n    if (ptr == end)\n      return XML_TOK_TRAILING_RSQB;\n    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {\n      ptr -= MINBPC(enc);\n      break;\n    }\n    *nextTokPtr = ptr;\n    return XML_TOK_INVALID;\n  INVALID_CASES(ptr, nextTokPtr)\n  default:\n    ptr += MINBPC(enc);\n    break;\n  }\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n#define LEAD_CASE(n) \\\n    case BT_LEAD ## n: \\\n      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \\\n        *nextTokPtr = ptr; \\\n        return XML_TOK_DATA_CHARS; \\\n      } \\\n      ptr += n; \\\n      break;\n    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)\n#undef LEAD_CASE\n    case BT_RSQB:\n      if (ptr + MINBPC(enc) != end) {\n         if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {\n           ptr += MINBPC(enc);\n           break;\n         }\n         if (ptr + 2*MINBPC(enc) != end) {\n           if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {\n             ptr += MINBPC(enc);\n             break;\n           }\n           *nextTokPtr = ptr + 2*MINBPC(enc);\n           return XML_TOK_INVALID;\n         }\n      }\n      /* fall through */\n    case BT_AMP:\n    case BT_LT:\n    case BT_NONXML:\n    case BT_MALFORM:\n    case BT_TRAIL:\n    case BT_CR:\n    case BT_LF:\n      *nextTokPtr = ptr;\n      return XML_TOK_DATA_CHARS;\n    default:\n      ptr += MINBPC(enc);\n      break;\n    }\n  }\n  *nextTokPtr = ptr;\n  return XML_TOK_DATA_CHARS;\n}\n\n/* ptr points to character following \"%\" */\n\nstatic int PTRCALL\nPREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,\n                    const char **nextTokPtr)\n{\n  if (ptr == end)\n    return XML_TOK_PARTIAL;\n  switch (BYTE_TYPE(enc, ptr)) {\n  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)\n  case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:\n    *nextTokPtr = ptr;\n    return XML_TOK_PERCENT;\n  default:\n    *nextTokPtr = ptr;\n    return XML_TOK_INVALID;\n  }\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)\n    case BT_SEMI:\n      *nextTokPtr = ptr + MINBPC(enc);\n      return XML_TOK_PARAM_ENTITY_REF;\n    default:\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    }\n  }\n  return XML_TOK_PARTIAL;\n}\n\nstatic int PTRCALL\nPREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,\n                      const char **nextTokPtr)\n{\n  if (ptr == end)\n    return XML_TOK_PARTIAL;\n  switch (BYTE_TYPE(enc, ptr)) {\n  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)\n  default:\n    *nextTokPtr = ptr;\n    return XML_TOK_INVALID;\n  }\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)\n    case BT_CR: case BT_LF: case BT_S:\n    case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:\n      *nextTokPtr = ptr;\n      return XML_TOK_POUND_NAME;\n    default:\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    }\n  }\n  return -XML_TOK_POUND_NAME;\n}\n\nstatic int PTRCALL\nPREFIX(scanLit)(int open, const ENCODING *enc,\n                const char *ptr, const char *end,\n                const char **nextTokPtr)\n{\n  while (ptr < end) {\n    int t = BYTE_TYPE(enc, ptr);\n    switch (t) {\n    INVALID_CASES(ptr, nextTokPtr)\n    case BT_QUOT:\n    case BT_APOS:\n      ptr += MINBPC(enc);\n      if (t != open)\n        break;\n      if (ptr == end)\n        return -XML_TOK_LITERAL;\n      *nextTokPtr = ptr;\n      switch (BYTE_TYPE(enc, ptr)) {\n      case BT_S: case BT_CR: case BT_LF:\n      case BT_GT: case BT_PERCNT: case BT_LSQB:\n        return XML_TOK_LITERAL;\n      default:\n        return XML_TOK_INVALID;\n      }\n    default:\n      ptr += MINBPC(enc);\n      break;\n    }\n  }\n  return XML_TOK_PARTIAL;\n}\n\nstatic int PTRCALL\nPREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,\n                  const char **nextTokPtr)\n{\n  int tok;\n  if (ptr >= end)\n    return XML_TOK_NONE;\n  if (MINBPC(enc) > 1) {\n    size_t n = end - ptr;\n    if (n & (MINBPC(enc) - 1)) {\n      n &= ~(MINBPC(enc) - 1);\n      if (n == 0)\n        return XML_TOK_PARTIAL;\n      end = ptr + n;\n    }\n  }\n  switch (BYTE_TYPE(enc, ptr)) {\n  case BT_QUOT:\n    return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);\n  case BT_APOS:\n    return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);\n  case BT_LT:\n    {\n      ptr += MINBPC(enc);\n      if (ptr == end)\n        return XML_TOK_PARTIAL;\n      switch (BYTE_TYPE(enc, ptr)) {\n      case BT_EXCL:\n        return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);\n      case BT_QUEST:\n        return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);\n      case BT_NMSTRT:\n      case BT_HEX:\n      case BT_NONASCII:\n      case BT_LEAD2:\n      case BT_LEAD3:\n      case BT_LEAD4:\n        *nextTokPtr = ptr - MINBPC(enc);\n        return XML_TOK_INSTANCE_START;\n      }\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    }\n  case BT_CR:\n    if (ptr + MINBPC(enc) == end) {\n      *nextTokPtr = end;\n      /* indicate that this might be part of a CR/LF pair */\n      return -XML_TOK_PROLOG_S;\n    }\n    /* fall through */\n  case BT_S: case BT_LF:\n    for (;;) {\n      ptr += MINBPC(enc);\n      if (ptr == end)\n        break;\n      switch (BYTE_TYPE(enc, ptr)) {\n      case BT_S: case BT_LF:\n        break;\n      case BT_CR:\n        /* don't split CR/LF pair */\n        if (ptr + MINBPC(enc) != end)\n          break;\n        /* fall through */\n      default:\n        *nextTokPtr = ptr;\n        return XML_TOK_PROLOG_S;\n      }\n    }\n    *nextTokPtr = ptr;\n    return XML_TOK_PROLOG_S;\n  case BT_PERCNT:\n    return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);\n  case BT_COMMA:\n    *nextTokPtr = ptr + MINBPC(enc);\n    return XML_TOK_COMMA;\n  case BT_LSQB:\n    *nextTokPtr = ptr + MINBPC(enc);\n    return XML_TOK_OPEN_BRACKET;\n  case BT_RSQB:\n    ptr += MINBPC(enc);\n    if (ptr == end)\n      return -XML_TOK_CLOSE_BRACKET;\n    if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {\n      if (ptr + MINBPC(enc) == end)\n        return XML_TOK_PARTIAL;\n      if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {\n        *nextTokPtr = ptr + 2*MINBPC(enc);\n        return XML_TOK_COND_SECT_CLOSE;\n      }\n    }\n    *nextTokPtr = ptr;\n    return XML_TOK_CLOSE_BRACKET;\n  case BT_LPAR:\n    *nextTokPtr = ptr + MINBPC(enc);\n    return XML_TOK_OPEN_PAREN;\n  case BT_RPAR:\n    ptr += MINBPC(enc);\n    if (ptr == end)\n      return -XML_TOK_CLOSE_PAREN;\n    switch (BYTE_TYPE(enc, ptr)) {\n    case BT_AST:\n      *nextTokPtr = ptr + MINBPC(enc);\n      return XML_TOK_CLOSE_PAREN_ASTERISK;\n    case BT_QUEST:\n      *nextTokPtr = ptr + MINBPC(enc);\n      return XML_TOK_CLOSE_PAREN_QUESTION;\n    case BT_PLUS:\n      *nextTokPtr = ptr + MINBPC(enc);\n      return XML_TOK_CLOSE_PAREN_PLUS;\n    case BT_CR: case BT_LF: case BT_S:\n    case BT_GT: case BT_COMMA: case BT_VERBAR:\n    case BT_RPAR:\n      *nextTokPtr = ptr;\n      return XML_TOK_CLOSE_PAREN;\n    }\n    *nextTokPtr = ptr;\n    return XML_TOK_INVALID;\n  case BT_VERBAR:\n    *nextTokPtr = ptr + MINBPC(enc);\n    return XML_TOK_OR;\n  case BT_GT:\n    *nextTokPtr = ptr + MINBPC(enc);\n    return XML_TOK_DECL_CLOSE;\n  case BT_NUM:\n    return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);\n#define LEAD_CASE(n) \\\n  case BT_LEAD ## n: \\\n    if (end - ptr < n) \\\n      return XML_TOK_PARTIAL_CHAR; \\\n    if (IS_NMSTRT_CHAR(enc, ptr, n)) { \\\n      ptr += n; \\\n      tok = XML_TOK_NAME; \\\n      break; \\\n    } \\\n    if (IS_NAME_CHAR(enc, ptr, n)) { \\\n      ptr += n; \\\n      tok = XML_TOK_NMTOKEN; \\\n      break; \\\n    } \\\n    *nextTokPtr = ptr; \\\n    return XML_TOK_INVALID;\n    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)\n#undef LEAD_CASE\n  case BT_NMSTRT:\n  case BT_HEX:\n    tok = XML_TOK_NAME;\n    ptr += MINBPC(enc);\n    break;\n  case BT_DIGIT:\n  case BT_NAME:\n  case BT_MINUS:\n#ifdef XML_NS\n  case BT_COLON:\n#endif\n    tok = XML_TOK_NMTOKEN;\n    ptr += MINBPC(enc);\n    break;\n  case BT_NONASCII:\n    if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {\n      ptr += MINBPC(enc);\n      tok = XML_TOK_NAME;\n      break;\n    }\n    if (IS_NAME_CHAR_MINBPC(enc, ptr)) {\n      ptr += MINBPC(enc);\n      tok = XML_TOK_NMTOKEN;\n      break;\n    }\n    /* fall through */\n  default:\n    *nextTokPtr = ptr;\n    return XML_TOK_INVALID;\n  }\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)\n    case BT_GT: case BT_RPAR: case BT_COMMA:\n    case BT_VERBAR: case BT_LSQB: case BT_PERCNT:\n    case BT_S: case BT_CR: case BT_LF:\n      *nextTokPtr = ptr;\n      return tok;\n#ifdef XML_NS\n    case BT_COLON:\n      ptr += MINBPC(enc);\n      switch (tok) {\n      case XML_TOK_NAME:\n        if (ptr == end)\n          return XML_TOK_PARTIAL;\n        tok = XML_TOK_PREFIXED_NAME;\n        switch (BYTE_TYPE(enc, ptr)) {\n        CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)\n        default:\n          tok = XML_TOK_NMTOKEN;\n          break;\n        }\n        break;\n      case XML_TOK_PREFIXED_NAME:\n        tok = XML_TOK_NMTOKEN;\n        break;\n      }\n      break;\n#endif\n    case BT_PLUS:\n      if (tok == XML_TOK_NMTOKEN)  {\n        *nextTokPtr = ptr;\n        return XML_TOK_INVALID;\n      }\n      *nextTokPtr = ptr + MINBPC(enc);\n      return XML_TOK_NAME_PLUS;\n    case BT_AST:\n      if (tok == XML_TOK_NMTOKEN)  {\n        *nextTokPtr = ptr;\n        return XML_TOK_INVALID;\n      }\n      *nextTokPtr = ptr + MINBPC(enc);\n      return XML_TOK_NAME_ASTERISK;\n    case BT_QUEST:\n      if (tok == XML_TOK_NMTOKEN)  {\n        *nextTokPtr = ptr;\n        return XML_TOK_INVALID;\n      }\n      *nextTokPtr = ptr + MINBPC(enc);\n      return XML_TOK_NAME_QUESTION;\n    default:\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    }\n  }\n  return -tok;\n}\n\nstatic int PTRCALL\nPREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,\n                          const char *end, const char **nextTokPtr)\n{\n  const char *start;\n  if (ptr >= end)\n    return XML_TOK_NONE;\n  start = ptr;\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n#define LEAD_CASE(n) \\\n    case BT_LEAD ## n: ptr += n; break;\n    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)\n#undef LEAD_CASE\n    case BT_AMP:\n      if (ptr == start)\n        return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);\n      *nextTokPtr = ptr;\n      return XML_TOK_DATA_CHARS;\n    case BT_LT:\n      /* this is for inside entity references */\n      *nextTokPtr = ptr;\n      return XML_TOK_INVALID;\n    case BT_LF:\n      if (ptr == start) {\n        *nextTokPtr = ptr + MINBPC(enc);\n        return XML_TOK_DATA_NEWLINE;\n      }\n      *nextTokPtr = ptr;\n      return XML_TOK_DATA_CHARS;\n    case BT_CR:\n      if (ptr == start) {\n        ptr += MINBPC(enc);\n        if (ptr == end)\n          return XML_TOK_TRAILING_CR;\n        if (BYTE_TYPE(enc, ptr) == BT_LF)\n          ptr += MINBPC(enc);\n        *nextTokPtr = ptr;\n        return XML_TOK_DATA_NEWLINE;\n      }\n      *nextTokPtr = ptr;\n      return XML_TOK_DATA_CHARS;\n    case BT_S:\n      if (ptr == start) {\n        *nextTokPtr = ptr + MINBPC(enc);\n        return XML_TOK_ATTRIBUTE_VALUE_S;\n      }\n      *nextTokPtr = ptr;\n      return XML_TOK_DATA_CHARS;\n    default:\n      ptr += MINBPC(enc);\n      break;\n    }\n  }\n  *nextTokPtr = ptr;\n  return XML_TOK_DATA_CHARS;\n}\n\nstatic int PTRCALL\nPREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,\n                       const char *end, const char **nextTokPtr)\n{\n  const char *start;\n  if (ptr >= end)\n    return XML_TOK_NONE;\n  start = ptr;\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n#define LEAD_CASE(n) \\\n    case BT_LEAD ## n: ptr += n; break;\n    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)\n#undef LEAD_CASE\n    case BT_AMP:\n      if (ptr == start)\n        return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);\n      *nextTokPtr = ptr;\n      return XML_TOK_DATA_CHARS;\n    case BT_PERCNT:\n      if (ptr == start) {\n        int tok =  PREFIX(scanPercent)(enc, ptr + MINBPC(enc),\n                                       end, nextTokPtr);\n        return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;\n      }\n      *nextTokPtr = ptr;\n      return XML_TOK_DATA_CHARS;\n    case BT_LF:\n      if (ptr == start) {\n        *nextTokPtr = ptr + MINBPC(enc);\n        return XML_TOK_DATA_NEWLINE;\n      }\n      *nextTokPtr = ptr;\n      return XML_TOK_DATA_CHARS;\n    case BT_CR:\n      if (ptr == start) {\n        ptr += MINBPC(enc);\n        if (ptr == end)\n          return XML_TOK_TRAILING_CR;\n        if (BYTE_TYPE(enc, ptr) == BT_LF)\n          ptr += MINBPC(enc);\n        *nextTokPtr = ptr;\n        return XML_TOK_DATA_NEWLINE;\n      }\n      *nextTokPtr = ptr;\n      return XML_TOK_DATA_CHARS;\n    default:\n      ptr += MINBPC(enc);\n      break;\n    }\n  }\n  *nextTokPtr = ptr;\n  return XML_TOK_DATA_CHARS;\n}\n\n#ifdef XML_DTD\n\nstatic int PTRCALL\nPREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,\n                         const char *end, const char **nextTokPtr)\n{\n  int level = 0;\n  if (MINBPC(enc) > 1) {\n    size_t n = end - ptr;\n    if (n & (MINBPC(enc) - 1)) {\n      n &= ~(MINBPC(enc) - 1);\n      end = ptr + n;\n    }\n  }\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n    INVALID_CASES(ptr, nextTokPtr)\n    case BT_LT:\n      if ((ptr += MINBPC(enc)) == end)\n        return XML_TOK_PARTIAL;\n      if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {\n        if ((ptr += MINBPC(enc)) == end)\n          return XML_TOK_PARTIAL;\n        if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {\n          ++level;\n          ptr += MINBPC(enc);\n        }\n      }\n      break;\n    case BT_RSQB:\n      if ((ptr += MINBPC(enc)) == end)\n        return XML_TOK_PARTIAL;\n      if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {\n        if ((ptr += MINBPC(enc)) == end)\n          return XML_TOK_PARTIAL;\n        if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {\n          ptr += MINBPC(enc);\n          if (level == 0) {\n            *nextTokPtr = ptr;\n            return XML_TOK_IGNORE_SECT;\n          }\n          --level;\n        }\n      }\n      break;\n    default:\n      ptr += MINBPC(enc);\n      break;\n    }\n  }\n  return XML_TOK_PARTIAL;\n}\n\n#endif /* XML_DTD */\n\nstatic int PTRCALL\nPREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,\n                   const char **badPtr)\n{\n  ptr += MINBPC(enc);\n  end -= MINBPC(enc);\n  for (; ptr < end; ptr += MINBPC(enc)) {\n    switch (BYTE_TYPE(enc, ptr)) {\n    case BT_DIGIT:\n    case BT_HEX:\n    case BT_MINUS:\n    case BT_APOS:\n    case BT_LPAR:\n    case BT_RPAR:\n    case BT_PLUS:\n    case BT_COMMA:\n    case BT_SOL:\n    case BT_EQUALS:\n    case BT_QUEST:\n    case BT_CR:\n    case BT_LF:\n    case BT_SEMI:\n    case BT_EXCL:\n    case BT_AST:\n    case BT_PERCNT:\n    case BT_NUM:\n#ifdef XML_NS\n    case BT_COLON:\n#endif\n      break;\n    case BT_S:\n      if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {\n        *badPtr = ptr;\n        return 0;\n      }\n      break;\n    case BT_NAME:\n    case BT_NMSTRT:\n      if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))\n        break;\n    default:\n      switch (BYTE_TO_ASCII(enc, ptr)) {\n      case 0x24: /* $ */\n      case 0x40: /* @ */\n        break;\n      default:\n        *badPtr = ptr;\n        return 0;\n      }\n      break;\n    }\n  }\n  return 1;\n}\n\n/* This must only be called for a well-formed start-tag or empty\n   element tag.  Returns the number of attributes.  Pointers to the\n   first attsMax attributes are stored in atts.\n*/\n\nstatic int PTRCALL\nPREFIX(getAtts)(const ENCODING *enc, const char *ptr,\n                int attsMax, ATTRIBUTE *atts)\n{\n  enum { other, inName, inValue } state = inName;\n  int nAtts = 0;\n  int open = 0; /* defined when state == inValue;\n                   initialization just to shut up compilers */\n\n  for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {\n    switch (BYTE_TYPE(enc, ptr)) {\n#define START_NAME \\\n      if (state == other) { \\\n        if (nAtts < attsMax) { \\\n          atts[nAtts].name = ptr; \\\n          atts[nAtts].normalized = 1; \\\n        } \\\n        state = inName; \\\n      }\n#define LEAD_CASE(n) \\\n    case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;\n    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)\n#undef LEAD_CASE\n    case BT_NONASCII:\n    case BT_NMSTRT:\n    case BT_HEX:\n      START_NAME\n      break;\n#undef START_NAME\n    case BT_QUOT:\n      if (state != inValue) {\n        if (nAtts < attsMax)\n          atts[nAtts].valuePtr = ptr + MINBPC(enc);\n        state = inValue;\n        open = BT_QUOT;\n      }\n      else if (open == BT_QUOT) {\n        state = other;\n        if (nAtts < attsMax)\n          atts[nAtts].valueEnd = ptr;\n        nAtts++;\n      }\n      break;\n    case BT_APOS:\n      if (state != inValue) {\n        if (nAtts < attsMax)\n          atts[nAtts].valuePtr = ptr + MINBPC(enc);\n        state = inValue;\n        open = BT_APOS;\n      }\n      else if (open == BT_APOS) {\n        state = other;\n        if (nAtts < attsMax)\n          atts[nAtts].valueEnd = ptr;\n        nAtts++;\n      }\n      break;\n    case BT_AMP:\n      if (nAtts < attsMax)\n        atts[nAtts].normalized = 0;\n      break;\n    case BT_S:\n      if (state == inName)\n        state = other;\n      else if (state == inValue\n               && nAtts < attsMax\n               && atts[nAtts].normalized\n               && (ptr == atts[nAtts].valuePtr\n                   || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE\n                   || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE\n                   || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))\n        atts[nAtts].normalized = 0;\n      break;\n    case BT_CR: case BT_LF:\n      /* This case ensures that the first attribute name is counted\n         Apart from that we could just change state on the quote. */\n      if (state == inName)\n        state = other;\n      else if (state == inValue && nAtts < attsMax)\n        atts[nAtts].normalized = 0;\n      break;\n    case BT_GT:\n    case BT_SOL:\n      if (state != inValue)\n        return nAtts;\n      break;\n    default:\n      break;\n    }\n  }\n  /* not reached */\n}\n\nstatic int PTRFASTCALL\nPREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)\n{\n  int result = 0;\n  /* skip &# */\n  ptr += 2*MINBPC(enc);\n  if (CHAR_MATCHES(enc, ptr, ASCII_x)) {\n    for (ptr += MINBPC(enc);\n         !CHAR_MATCHES(enc, ptr, ASCII_SEMI);\n         ptr += MINBPC(enc)) {\n      int c = BYTE_TO_ASCII(enc, ptr);\n      switch (c) {\n      case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:\n      case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:\n        result <<= 4;\n        result |= (c - ASCII_0);\n        break;\n      case ASCII_A: case ASCII_B: case ASCII_C:\n      case ASCII_D: case ASCII_E: case ASCII_F:\n        result <<= 4;\n        result += 10 + (c - ASCII_A);\n        break;\n      case ASCII_a: case ASCII_b: case ASCII_c:\n      case ASCII_d: case ASCII_e: case ASCII_f:\n        result <<= 4;\n        result += 10 + (c - ASCII_a);\n        break;\n      }\n      if (result >= 0x110000)\n        return -1;\n    }\n  }\n  else {\n    for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {\n      int c = BYTE_TO_ASCII(enc, ptr);\n      result *= 10;\n      result += (c - ASCII_0);\n      if (result >= 0x110000)\n        return -1;\n    }\n  }\n  return checkCharRefNumber(result);\n}\n\nstatic int PTRCALL\nPREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,\n                             const char *end)\n{\n  switch ((end - ptr)/MINBPC(enc)) {\n  case 2:\n    if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {\n      switch (BYTE_TO_ASCII(enc, ptr)) {\n      case ASCII_l:\n        return ASCII_LT;\n      case ASCII_g:\n        return ASCII_GT;\n      }\n    }\n    break;\n  case 3:\n    if (CHAR_MATCHES(enc, ptr, ASCII_a)) {\n      ptr += MINBPC(enc);\n      if (CHAR_MATCHES(enc, ptr, ASCII_m)) {\n        ptr += MINBPC(enc);\n        if (CHAR_MATCHES(enc, ptr, ASCII_p))\n          return ASCII_AMP;\n      }\n    }\n    break;\n  case 4:\n    switch (BYTE_TO_ASCII(enc, ptr)) {\n    case ASCII_q:\n      ptr += MINBPC(enc);\n      if (CHAR_MATCHES(enc, ptr, ASCII_u)) {\n        ptr += MINBPC(enc);\n        if (CHAR_MATCHES(enc, ptr, ASCII_o)) {\n          ptr += MINBPC(enc);\n          if (CHAR_MATCHES(enc, ptr, ASCII_t))\n            return ASCII_QUOT;\n        }\n      }\n      break;\n    case ASCII_a:\n      ptr += MINBPC(enc);\n      if (CHAR_MATCHES(enc, ptr, ASCII_p)) {\n        ptr += MINBPC(enc);\n        if (CHAR_MATCHES(enc, ptr, ASCII_o)) {\n          ptr += MINBPC(enc);\n          if (CHAR_MATCHES(enc, ptr, ASCII_s))\n            return ASCII_APOS;\n        }\n      }\n      break;\n    }\n  }\n  return 0;\n}\n\nstatic int PTRCALL\nPREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)\n{\n  for (;;) {\n    switch (BYTE_TYPE(enc, ptr1)) {\n#define LEAD_CASE(n) \\\n    case BT_LEAD ## n: \\\n      if (*ptr1++ != *ptr2++) \\\n        return 0;\n    LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)\n#undef LEAD_CASE\n      /* fall through */\n      if (*ptr1++ != *ptr2++)\n        return 0;\n      break;\n    case BT_NONASCII:\n    case BT_NMSTRT:\n#ifdef XML_NS\n    case BT_COLON:\n#endif\n    case BT_HEX:\n    case BT_DIGIT:\n    case BT_NAME:\n    case BT_MINUS:\n      if (*ptr2++ != *ptr1++)\n        return 0;\n      if (MINBPC(enc) > 1) {\n        if (*ptr2++ != *ptr1++)\n          return 0;\n        if (MINBPC(enc) > 2) {\n          if (*ptr2++ != *ptr1++)\n            return 0;\n          if (MINBPC(enc) > 3) {\n            if (*ptr2++ != *ptr1++)\n              return 0;\n          }\n        }\n      }\n      break;\n    default:\n      if (MINBPC(enc) == 1 && *ptr1 == *ptr2)\n        return 1;\n      switch (BYTE_TYPE(enc, ptr2)) {\n      case BT_LEAD2:\n      case BT_LEAD3:\n      case BT_LEAD4:\n      case BT_NONASCII:\n      case BT_NMSTRT:\n#ifdef XML_NS\n      case BT_COLON:\n#endif\n      case BT_HEX:\n      case BT_DIGIT:\n      case BT_NAME:\n      case BT_MINUS:\n        return 0;\n      default:\n        return 1;\n      }\n    }\n  }\n  /* not reached */\n}\n\nstatic int PTRCALL\nPREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,\n                         const char *end1, const char *ptr2)\n{\n  for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {\n    if (ptr1 == end1)\n      return 0;\n    if (!CHAR_MATCHES(enc, ptr1, *ptr2))\n      return 0;\n  }\n  return ptr1 == end1;\n}\n\nstatic int PTRFASTCALL\nPREFIX(nameLength)(const ENCODING *enc, const char *ptr)\n{\n  const char *start = ptr;\n  for (;;) {\n    switch (BYTE_TYPE(enc, ptr)) {\n#define LEAD_CASE(n) \\\n    case BT_LEAD ## n: ptr += n; break;\n    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)\n#undef LEAD_CASE\n    case BT_NONASCII:\n    case BT_NMSTRT:\n#ifdef XML_NS\n    case BT_COLON:\n#endif\n    case BT_HEX:\n    case BT_DIGIT:\n    case BT_NAME:\n    case BT_MINUS:\n      ptr += MINBPC(enc);\n      break;\n    default:\n      return (int)(ptr - start);\n    }\n  }\n}\n\nstatic const char * PTRFASTCALL\nPREFIX(skipS)(const ENCODING *enc, const char *ptr)\n{\n  for (;;) {\n    switch (BYTE_TYPE(enc, ptr)) {\n    case BT_LF:\n    case BT_CR:\n    case BT_S:\n      ptr += MINBPC(enc);\n      break;\n    default:\n      return ptr;\n    }\n  }\n}\n\nstatic void PTRCALL\nPREFIX(updatePosition)(const ENCODING *enc,\n                       const char *ptr,\n                       const char *end,\n                       POSITION *pos)\n{\n  while (ptr < end) {\n    switch (BYTE_TYPE(enc, ptr)) {\n#define LEAD_CASE(n) \\\n    case BT_LEAD ## n: \\\n      ptr += n; \\\n      break;\n    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)\n#undef LEAD_CASE\n    case BT_LF:\n      pos->columnNumber = (XML_Size)-1;\n      pos->lineNumber++;\n      ptr += MINBPC(enc);\n      break;\n    case BT_CR:\n      pos->lineNumber++;\n      ptr += MINBPC(enc);\n      if (ptr < end && BYTE_TYPE(enc, ptr) == BT_LF)\n        ptr += MINBPC(enc);\n      pos->columnNumber = (XML_Size)-1;\n      break;\n    default:\n      ptr += MINBPC(enc);\n      break;\n    }\n    pos->columnNumber++;\n  }\n}\n\n#undef DO_LEAD_CASE\n#undef MULTIBYTE_CASES\n#undef INVALID_CASES\n#undef CHECK_NAME_CASE\n#undef CHECK_NAME_CASES\n#undef CHECK_NMSTRT_CASE\n#undef CHECK_NMSTRT_CASES\n\n#endif /* XML_TOK_IMPL_C */\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/xmltok_impl.h",
    "content": "/*\nCopyright (c) 1998, 1999 Thai Open Source Software Center Ltd\nSee the file COPYING for copying permission.\n*/\n\nenum {\n  BT_NONXML,\n  BT_MALFORM,\n  BT_LT,\n  BT_AMP,\n  BT_RSQB,\n  BT_LEAD2,\n  BT_LEAD3,\n  BT_LEAD4,\n  BT_TRAIL,\n  BT_CR,\n  BT_LF,\n  BT_GT,\n  BT_QUOT,\n  BT_APOS,\n  BT_EQUALS,\n  BT_QUEST,\n  BT_EXCL,\n  BT_SOL,\n  BT_SEMI,\n  BT_NUM,\n  BT_LSQB,\n  BT_S,\n  BT_NMSTRT,\n  BT_COLON,\n  BT_HEX,\n  BT_DIGIT,\n  BT_NAME,\n  BT_MINUS,\n  BT_OTHER, /* known not to be a name or name start character */\n  BT_NONASCII, /* might be a name or name start character */\n  BT_PERCNT,\n  BT_LPAR,\n  BT_RPAR,\n  BT_AST,\n  BT_PLUS,\n  BT_COMMA,\n  BT_VERBAR\n};\n\n#include <stddef.h>\n"
  },
  {
    "path": "atlas-aapt/external/expat/lib/xmltok_ns.c",
    "content": "/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd\n   See the file COPYING for copying permission.\n*/\n\n/* This file is included! */\n#ifdef XML_TOK_NS_C\n\nconst ENCODING *\nNS(XmlGetUtf8InternalEncoding)(void)\n{\n  return &ns(internal_utf8_encoding).enc;\n}\n\nconst ENCODING *\nNS(XmlGetUtf16InternalEncoding)(void)\n{\n#if BYTEORDER == 1234\n  return &ns(internal_little2_encoding).enc;\n#elif BYTEORDER == 4321\n  return &ns(internal_big2_encoding).enc;\n#else\n  const short n = 1;\n  return (*(const char *)&n\n          ? &ns(internal_little2_encoding).enc\n          : &ns(internal_big2_encoding).enc);\n#endif\n}\n\nstatic const ENCODING * const NS(encodings)[] = {\n  &ns(latin1_encoding).enc,\n  &ns(ascii_encoding).enc,\n  &ns(utf8_encoding).enc,\n  &ns(big2_encoding).enc,\n  &ns(big2_encoding).enc,\n  &ns(little2_encoding).enc,\n  &ns(utf8_encoding).enc /* NO_ENC */\n};\n\nstatic int PTRCALL\nNS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,\n                   const char **nextTokPtr)\n{\n  return initScan(NS(encodings), (const INIT_ENCODING *)enc,\n                  XML_PROLOG_STATE, ptr, end, nextTokPtr);\n}\n\nstatic int PTRCALL\nNS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,\n                    const char **nextTokPtr)\n{\n  return initScan(NS(encodings), (const INIT_ENCODING *)enc,\n                  XML_CONTENT_STATE, ptr, end, nextTokPtr);\n}\n\nint\nNS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,\n                    const char *name)\n{\n  int i = getEncodingIndex(name);\n  if (i == UNKNOWN_ENC)\n    return 0;\n  SET_INIT_ENC_INDEX(p, i);\n  p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);\n  p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);\n  p->initEnc.updatePosition = initUpdatePosition;\n  p->encPtr = encPtr;\n  *encPtr = &(p->initEnc);\n  return 1;\n}\n\nstatic const ENCODING *\nNS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)\n{\n#define ENCODING_MAX 128\n  char buf[ENCODING_MAX];\n  char *p = buf;\n  int i;\n  XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);\n  if (ptr != end)\n    return 0;\n  *p = 0;\n  if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)\n    return enc;\n  i = getEncodingIndex(buf);\n  if (i == UNKNOWN_ENC)\n    return 0;\n  return NS(encodings)[i];\n}\n\nint\nNS(XmlParseXmlDecl)(int isGeneralTextEntity,\n                    const ENCODING *enc,\n                    const char *ptr,\n                    const char *end,\n                    const char **badPtr,\n                    const char **versionPtr,\n                    const char **versionEndPtr,\n                    const char **encodingName,\n                    const ENCODING **encoding,\n                    int *standalone)\n{\n  return doParseXmlDecl(NS(findEncoding),\n                        isGeneralTextEntity,\n                        enc,\n                        ptr,\n                        end,\n                        badPtr,\n                        versionPtr,\n                        versionEndPtr,\n                        encodingName,\n                        encoding,\n                        standalone);\n}\n\n#endif /* XML_TOK_NS_C */\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/.arcconfig",
    "content": "{\n  \"project_id\" : \"libcxx\",\n  \"conduit_uri\" : \"http://reviews.llvm.org/\"\n}\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/.gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nenv/\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n#lib/ # We actually have things checked in to lib/\nlib64/\nparts/\nsdist/\nvar/\n*.egg-info/\n.installed.cfg\n*.egg\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.coverage\n.cache\nnosetests.xml\ncoverage.xml\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/Android.bp",
    "content": "//\n// Copyright (C) 2014 The Android Open Source Project\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// host + device static lib\ncc_library_static {\n    host_supported: true,\n    name: \"libc++_static\",\n    clang: true,\n    srcs: [\n        \"src/algorithm.cpp\",\n        \"src/any.cpp\",\n        \"src/bind.cpp\",\n        \"src/chrono.cpp\",\n        \"src/condition_variable.cpp\",\n        \"src/debug.cpp\",\n        \"src/exception.cpp\",\n        \"src/future.cpp\",\n        \"src/hash.cpp\",\n        \"src/ios.cpp\",\n        \"src/iostream.cpp\",\n        \"src/locale.cpp\",\n        \"src/memory.cpp\",\n        \"src/mutex.cpp\",\n        \"src/new.cpp\",\n        \"src/optional.cpp\",\n        \"src/random.cpp\",\n        \"src/regex.cpp\",\n        \"src/shared_mutex.cpp\",\n        \"src/stdexcept.cpp\",\n        \"src/string.cpp\",\n        \"src/strstream.cpp\",\n        \"src/system_error.cpp\",\n        \"src/thread.cpp\",\n        \"src/typeinfo.cpp\",\n        \"src/utility.cpp\",\n        \"src/valarray.cpp\",\n    ],\n    local_include_dirs: [\"include\"],\n    export_include_dirs: [\"include\"],\n    cppflags: [\n        \"-std=c++14\",\n        \"-nostdinc++\",\n        \"-fexceptions\",\n    ],\n    rtti: true,\n    whole_static_libs: [\n        \"libc++abi\",\n    ],\n    stl: \"none\",\n}\n\n// host + device dynamic lib\ncc_library_shared {\n    host_supported: true,\n    name: \"libc++\",\n    clang: true,\n    whole_static_libs: [\"libc++_static\"],\n    stl: \"none\",\n\n    target: {\n        android: {\n            shared_libs: [\"libdl\"],\n        },\n        android_arm: {\n            static_libs: [\"libunwind_llvm\"],\n            ldflags: [\"-Wl,--exclude-libs,libunwind_llvm.a\"],\n        },\n        host: {\n            ldflags: [\"-nodefaultlibs\"],\n        },\n        darwin: {\n            unexported_symbols_list: \"lib/libc++unexp.exp\",\n            force_symbols_not_weak_list: \"lib/notweak.exp\",\n            force_symbols_weak_list: \"lib/weak.exp\",\n        },\n\n        linux: {\n            host_ldlibs: [\n                \"-lrt\",\n                \"-lpthread\",\n                \"-ldl\",\n            ],\n        },\n    },\n}\n\n\n// ANDROIDMK TRANSLATION ERROR: unsupported conditional\n// ifdef LIBCXX_TESTING\n// ANDROIDMK TRANSLATION ERROR: unsupported include\n// include $(LOCAL_PATH)/buildcmds/Android.mk\n\n// ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional\n// endif\n// TARGET_BUILD_APPS\n\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/Android.mk",
    "content": "#\n# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\nLOCAL_PATH := $(call my-dir)\n\nLIBCXX_SRC_FILES := \\\n    src/algorithm.cpp \\\n    src/any.cpp \\\n    src/bind.cpp \\\n    src/chrono.cpp \\\n    src/condition_variable.cpp \\\n    src/debug.cpp \\\n    src/exception.cpp \\\n    src/future.cpp \\\n    src/hash.cpp \\\n    src/ios.cpp \\\n    src/iostream.cpp \\\n    src/locale.cpp \\\n    src/memory.cpp \\\n    src/mutex.cpp \\\n    src/new.cpp \\\n    src/optional.cpp \\\n    src/random.cpp \\\n    src/regex.cpp \\\n    src/shared_mutex.cpp \\\n    src/stdexcept.cpp \\\n    src/string.cpp \\\n    src/strstream.cpp \\\n    src/system_error.cpp \\\n    src/thread.cpp \\\n    src/typeinfo.cpp \\\n    src/utility.cpp \\\n    src/valarray.cpp \\\n\nLIBCXX_C_INCLUDES := \\\n    $(LOCAL_PATH)/include/ \\\n\nLIBCXX_CPPFLAGS := \\\n    -std=c++14 \\\n    -nostdinc++ \\\n    -fexceptions \\\n\n# target static lib\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libc++_static\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := $(LIBCXX_SRC_FILES)\nLOCAL_C_INCLUDES := $(LIBCXX_C_INCLUDES)\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include external/libcxxabi/include\nLOCAL_CPPFLAGS := $(LIBCXX_CPPFLAGS)\nLOCAL_RTTI_FLAG := -frtti\nLOCAL_WHOLE_STATIC_LIBRARIES := libc++abi\nLOCAL_CXX_STL := none\ninclude $(BUILD_STATIC_LIBRARY)\n\n# target dynamic lib\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libc++\nLOCAL_CLANG := true\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include external/libcxxabi/include\nLOCAL_WHOLE_STATIC_LIBRARIES := libc++_static\nLOCAL_SHARED_LIBRARIES := libdl\nLOCAL_CXX_STL := none\nLOCAL_STATIC_LIBRARIES_arm := libunwind_llvm\nLOCAL_LDFLAGS_arm := -Wl,--exclude-libs,libunwind_llvm.a\ninclude $(BUILD_SHARED_LIBRARY)\n\n# host static lib\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libc++_static\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := $(LIBCXX_SRC_FILES)\nLOCAL_C_INCLUDES := $(LIBCXX_C_INCLUDES)\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include external/libcxxabi/include\nLOCAL_CPPFLAGS := $(LIBCXX_CPPFLAGS)\nLOCAL_RTTI_FLAG := -frtti\nLOCAL_WHOLE_STATIC_LIBRARIES := libc++abi\nLOCAL_MULTILIB := both\nLOCAL_CXX_STL := none\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\n# host dynamic lib\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libc++\nLOCAL_CLANG := true\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include external/libcxxabi/include\nLOCAL_LDFLAGS := -nodefaultlibs\nLOCAL_WHOLE_STATIC_LIBRARIES := libc++_static\nLOCAL_MULTILIB := both\nLOCAL_CXX_STL := none\n\nifeq ($(HOST_OS), darwin)\nLOCAL_LDFLAGS += \\\n            -Wl,-unexported_symbols_list,external/libcxx/lib/libc++unexp.exp  \\\n            -Wl,-force_symbols_not_weak_list,external/libcxx/lib/notweak.exp \\\n            -Wl,-force_symbols_weak_list,external/libcxx/lib/weak.exp\nelse\nLOCAL_LDLIBS += -lrt -lpthread -ldl\nendif\n\ninclude $(BUILD_HOST_SHARED_LIBRARY)\n\nifdef LIBCXX_TESTING\ninclude $(LOCAL_PATH)/buildcmds/Android.mk\nendif\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/CMakeLists.txt",
    "content": "# See www/CMake.html for instructions on how to build libcxx with CMake.\n\n#===============================================================================\n# Setup Project\n#===============================================================================\ncmake_minimum_required(VERSION 2.8)\n\nif(POLICY CMP0042)\n  cmake_policy(SET CMP0042 NEW) # Set MACOSX_RPATH=YES by default\nendif()\nif(POLICY CMP0022)\n  cmake_policy(SET CMP0022 NEW) # Required when interacting with LLVM and Clang\nendif()\n\nproject(libcxx CXX C)\n\nset(PACKAGE_NAME libcxx)\nset(PACKAGE_VERSION trunk-svn)\nset(PACKAGE_STRING \"${PACKAGE_NAME} ${PACKAGE_VERSION}\")\nset(PACKAGE_BUGREPORT \"llvm-bugs@lists.llvm.org\")\n\n# Add path for custom modules\nset(CMAKE_MODULE_PATH\n  \"${CMAKE_CURRENT_SOURCE_DIR}/cmake\"\n  \"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules\"\n  ${CMAKE_MODULE_PATH}\n  )\n\n# Require out of source build.\ninclude(MacroEnsureOutOfSourceBuild)\nMACRO_ENSURE_OUT_OF_SOURCE_BUILD(\n \"${PROJECT_NAME} requires an out of source build. Please create a separate\n build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.\"\n )\n\n# Find the LLVM sources and simulate LLVM CMake options.\ninclude(HandleOutOfTreeLLVM)\nif (LIBCXX_BUILT_STANDALONE AND NOT LLVM_FOUND)\n  message(WARNING \"UNSUPPORTED LIBCXX CONFIGURATION DETECTED: \"\n                  \"llvm-config not found and LLVM_PATH not defined.\\n\"\n                  \"Reconfigure with -DLLVM_CONFIG=path/to/llvm-config \"\n                  \"or -DLLVM_PATH=path/to/llvm-source-root.\")\nendif()\n\n\n#===============================================================================\n# Setup CMake Options\n#===============================================================================\n\n# Basic options ---------------------------------------------------------------\noption(LIBCXX_ENABLE_ASSERTIONS \"Enable assertions independent of build mode.\" ON)\noption(LIBCXX_ENABLE_SHARED \"Build libc++ as a shared library.\" ON)\n\noption(LIBCXX_INCLUDE_TESTS \"Build the libc++ tests.\" ${LLVM_INCLUDE_TESTS})\nset(LIBCXX_LIBDIR_SUFFIX \"${LLVM_LIBDIR_SUFFIX}\" CACHE STRING\n    \"Define suffix of library directory name (32/64)\")\noption(LIBCXX_INSTALL_HEADERS \"Install the libc++ headers.\" ON)\noption(LIBCXX_INSTALL_SUPPORT_HEADERS \"Install libc++ support headers.\" ON)\n\n# ABI Library options ---------------------------------------------------------\nset(LIBCXX_CXX_ABI \"${LIBCXX_CXX_ABI}\" CACHE STRING\n    \"Specify C++ ABI library to use.\" FORCE)\nset(CXXABIS none libcxxabi libcxxrt libstdc++ libsupc++)\nset_property(CACHE LIBCXX_CXX_ABI PROPERTY STRINGS ;${CXXABIS})\n\noption(LIBCXX_ENABLE_STATIC_ABI_LIBRARY \"Statically link the ABI library\" OFF)\n\n# Build libc++abi with libunwind. We need this option to determine whether to\n# link with libunwind or libgcc_s while running the test cases.\noption(LIBCXXABI_USE_LLVM_UNWINDER \"Build and use the LLVM unwinder.\" OFF)\n\n# Target options --------------------------------------------------------------\noption(LIBCXX_BUILD_32_BITS \"Build 32 bit libc++.\" ${LLVM_BUILD_32_BITS})\nset(LIBCXX_SYSROOT \"\" CACHE STRING \"Use alternate sysroot.\")\nset(LIBCXX_GCC_TOOLCHAIN \"\" CACHE STRING \"Use alternate GCC toolchain.\")\n\n# Feature options -------------------------------------------------------------\noption(LIBCXX_ENABLE_EXCEPTIONS \"Use exceptions.\" ON)\noption(LIBCXX_ENABLE_RTTI \"Use run time type information.\" ON)\noption(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE \"Build libc++ with support for the global filesystem namespace.\" ON)\noption(LIBCXX_ENABLE_STDIN \"Build libc++ with support for stdin/std::cin.\" ON)\noption(LIBCXX_ENABLE_STDOUT \"Build libc++ with support for stdout/std::cout.\" ON)\noption(LIBCXX_ENABLE_THREADS \"Build libc++ with support for threads.\" ON)\noption(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS \"Build libc++ with support for thread-unsafe C functions\" ON)\noption(LIBCXX_ENABLE_MONOTONIC_CLOCK\n  \"Build libc++ with support for a monotonic clock.\n   This option may only be used when LIBCXX_ENABLE_THREADS=OFF.\" ON)\n\n# Misc options ----------------------------------------------------------------\noption(LIBCXX_ENABLE_PEDANTIC \"Compile with pedantic enabled.\" ON)\noption(LIBCXX_ENABLE_WERROR \"Fail and stop if a warning is triggered.\" OFF)\n\noption(LIBCXX_GENERATE_COVERAGE \"Enable generating code coverage.\" OFF)\nset(LIBCXX_COVERAGE_LIBRARY \"\" CACHE STRING\n    \"The Profile-rt library used to build with code coverage\")\n\n#===============================================================================\n# Check option configurations\n#===============================================================================\n\n# Ensure LIBCXX_ENABLE_MONOTONIC_CLOCK is set to ON only when\n# LIBCXX_ENABLE_THREADS is on.\nif(LIBCXX_ENABLE_THREADS AND NOT LIBCXX_ENABLE_MONOTONIC_CLOCK)\n  message(FATAL_ERROR \"LIBCXX_ENABLE_MONOTONIC_CLOCK can only be set to OFF\"\n                      \" when LIBCXX_ENABLE_THREADS is also set to OFF.\")\nendif()\n\n# Ensure LLVM_USE_SANITIZER is not specified when LIBCXX_GENERATE_COVERAGE\n# is ON.\nif (LLVM_USE_SANITIZER AND LIBCXX_GENERATE_COVERAGE)\n  message(FATAL_ERROR \"LLVM_USE_SANITIZER cannot be used with LIBCXX_GENERATE_COVERAGE\")\nendif()\n\n# Set LIBCXX_BUILD_32_BITS to (LIBCXX_BUILD_32_BITS OR LLVM_BUILD_32_BITS)\n# and check that we can build with 32 bits if requested.\nif (CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32)\n  if (LIBCXX_BUILD_32_BITS AND NOT LLVM_BUILD_32_BITS) # Don't duplicate the output from LLVM\n    message(STATUS \"Building 32 bits executables and libraries.\")\n  endif()\nelseif(LIBCXX_BUILD_32_BITS)\n  message(FATAL_ERROR \"LIBCXX_BUILD_32_BITS=ON is not supported on this platform.\")\nendif()\n\n# Check that this option is not enabled on Apple and emit a usage warning.\nif (LIBCXX_ENABLE_STATIC_ABI_LIBRARY)\n  if (APPLE)\n    message(FATAL_ERROR \"LIBCXX_ENABLE_STATIC_ABI_LIBRARY is not supported on OS X\")\n  else()\n    message(WARNING \"LIBCXX_ENABLE_STATIC_ABI_LIBRARY is an experimental option\")\n  endif()\nendif()\n\n#===============================================================================\n# Configure System\n#===============================================================================\n\nset(LIBCXX_COMPILER    ${CMAKE_CXX_COMPILER})\nset(LIBCXX_SOURCE_DIR  ${CMAKE_CURRENT_SOURCE_DIR})\nset(LIBCXX_BINARY_DIR  ${CMAKE_CURRENT_BINARY_DIR})\nset(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX})\n\nset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR})\nset(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR})\n\n# Declare libc++ configuration variables.\n# They are intended for use as follows:\n# LIBCXX_CXX_FLAGS: General flags for both the compiler and linker.\n# LIBCXX_COMPILE_FLAGS: Compile only flags.\n# LIBCXX_LINK_FLAGS: Linker only flags.\nset(LIBCXX_COMPILE_FLAGS \"\")\nset(LIBCXX_LINK_FLAGS \"\")\nset(LIBCXX_LIBRARIES \"\")\n\n# Configure compiler.\ninclude(config-ix)\n\n# Configure coverage options.\nif (LIBCXX_GENERATE_COVERAGE)\n  include(CodeCoverage)\n  set(CMAKE_BUILD_TYPE \"COVERAGE\" CACHE STRING \"\" FORCE)\nendif()\n\nstring(TOUPPER \"${CMAKE_BUILD_TYPE}\" uppercase_CMAKE_BUILD_TYPE)\n\n#===============================================================================\n# Setup Compiler Flags\n#===============================================================================\n\ninclude(HandleLibCXXABI) # Steup the ABI library flags\n\n# Include macros for adding and removing libc++ flags.\ninclude(HandleLibcxxFlags)\n\n# Remove flags that may have snuck in.\nremove_flags(-DNDEBUG -UNDEBUG -D_DEBUG\n             -stdlib=libc++ -stdlib=libstdc++ -lc++abi -m32)\n\n# Required flags ==============================================================\nadd_compile_flags_if_supported(-std=c++11)\nif (NOT MSVC AND NOT LIBCXX_SUPPORTS_STD_EQ_CXX11_FLAG)\n  message(FATAL_ERROR \"C++11 is required but the compiler does not support -std=c++11\")\nendif()\n\n# On all systems the system c++ standard library headers need to be excluded.\n# MSVC only has -X, which disables all default includes; including the crt.\n# Thus, we do nothing and hope we don't accidentally include any of the C++\n# headers\nadd_compile_flags_if_supported(-nostdinc++)\n\n# Target flags ================================================================\nadd_flags_if(LIBCXX_BUILD_32_BITS -m32)\nadd_flags_if(LIBCXX_TARGET_TRIPLE \"-target ${LIBCXX_TARGET_TRIPLE}\")\nadd_flags_if(LIBCXX_SYSROOT \"--sysroot ${LIBCXX_SYSROOT}\")\nadd_flags_if(LIBCXX_GCC_TOOLCHAIN \"-gcc-toolchain ${LIBCXX_GCC_TOOLCHAIN}\")\n\n# Warning flags ===============================================================\nadd_definitions(-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\nadd_compile_flags_if_supported(\n    -Wall -W -Wwrite-strings\n    -Wno-unused-parameter -Wno-long-long\n    -Werror=return-type)\nif (LIBCXX_ENABLE_WERROR)\n  add_compile_flags_if_supported(-Werror)\n  add_compile_flags_if_supported(-WX)\nelse()\n  # TODO(EricWF) Remove this. We shouldn't be suppressing errors when -Werror is\n  # added elsewhere.\n  add_compile_flags_if_supported(-Wno-error)\nendif()\nif (LIBCXX_ENABLE_PEDANTIC)\n  add_compile_flags_if_supported(-pedantic)\nendif()\n\n# Exception flags =============================================================\nif (LIBCXX_ENABLE_EXCEPTIONS)\n  # Catches C++ exceptions only and tells the compiler to assume that extern C\n  # functions never throw a C++ exception.\n  add_compile_flags_if_supported(-EHsc)\nelse()\n  add_definitions(-D_LIBCPP_NO_EXCEPTIONS)\n  add_compile_flags_if_supported(-EHs- -EHa-)\n  add_compile_flags_if_supported(-fno-exceptions)\nendif()\n\n# RTTI flags ==================================================================\nif (NOT LIBCXX_ENABLE_RTTI)\n  add_definitions(-D_LIBCPP_NO_RTTI)\n  add_compile_flags_if_supported(-GR-)\n  add_compile_flags_if_supported(-fno-rtti)\nendif()\n\n# Assertion flags =============================================================\ndefine_if(LIBCXX_ENABLE_ASSERTIONS -UNDEBUG)\ndefine_if_not(LIBCXX_ENABLE_ASSERTIONS -DNDEBUG)\nif (LIBCXX_ENABLE_ASSERTIONS)\n  # MSVC doesn't like _DEBUG on release builds. See PR 4379.\n  define_if_not(MSVC -D_DEBUG)\nendif()\n\n# Feature flags ===============================================================\ndefine_if(MSVC -D_CRT_SECURE_NO_WARNINGS)\ndefine_if_not(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE -D_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE)\ndefine_if_not(LIBCXX_ENABLE_STDIN -D_LIBCPP_HAS_NO_STDIN)\ndefine_if_not(LIBCXX_ENABLE_STDOUT -D_LIBCPP_HAS_NO_STDOUT)\ndefine_if_not(LIBCXX_ENABLE_THREADS -D_LIBCPP_HAS_NO_THREADS)\ndefine_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK -D_LIBCPP_HAS_NO_MONOTONIC_CLOCK)\ndefine_if_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS -D_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS)\n\n\n# Sanitizer flags\n\n# Configure for sanitizers. If LIBCXX_BUILT_STANDALONE then we have to do\n# the flag translation ourselves. Othewise LLVM's CMakeList.txt will handle it.\nif (LIBCXX_BUILT_STANDALONE)\n  set(LLVM_USE_SANITIZER \"\" CACHE STRING\n      \"Define the sanitizer used to build the library and tests\")\n  # NOTE: LLVM_USE_SANITIZER checks for a UNIX like system instead of MSVC.\n  # But we don't have LLVM_ON_UNIX so checking for MSVC is the best we can do.\n  if (LLVM_USE_SANITIZER AND NOT MSVC)\n    add_flags_if_supported(\"-fno-omit-frame-pointer\")\n    add_flags_if_supported(\"-gline-tables-only\")\n\n    if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL \"DEBUG\" AND\n        NOT uppercase_CMAKE_BUILD_TYPE STREQUAL \"RELWITHDEBINFO\")\n        add_flags_if_supported(\"-gline-tables-only\")\n    endif()\n    if (LLVM_USE_SANITIZER STREQUAL \"Address\")\n      add_flags(\"-fsanitize=address\")\n    elseif (LLVM_USE_SANITIZER MATCHES \"Memory(WithOrigins)?\")\n      add_flags(-fsanitize=memory)\n      if (LLVM_USE_SANITIZER STREQUAL \"MemoryWithOrigins\")\n        add_flags(\"-fsanitize-memory-track-origins\")\n      endif()\n    elseif (LLVM_USE_SANITIZER STREQUAL \"Undefined\")\n      add_flags(\"-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all\")\n    elseif (LLVM_USE_SANITIZER STREQUAL \"Thread\")\n      add_flags(-fsanitize=thread)\n    else()\n      message(WARNING \"Unsupported value of LLVM_USE_SANITIZER: ${LLVM_USE_SANITIZER}\")\n    endif()\n  elseif(LLVM_USE_SANITIZER AND MSVC)\n    message(WARNING \"LLVM_USE_SANITIZER is not supported on this platform.\")\n  endif()\nendif()\n#===============================================================================\n# Setup Source Code And Tests\n#===============================================================================\ninclude_directories(include)\nadd_subdirectory(include)\nadd_subdirectory(lib)\nif (LIBCXX_INCLUDE_TESTS)\n  add_subdirectory(test)\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/CREDITS.TXT",
    "content": "This file is a partial list of people who have contributed to the LLVM/libc++\nproject.  If you have contributed a patch or made some other contribution to\nLLVM/libc++, please submit a patch to this file to add yourself, and it will be\ndone!\n\nThe list is sorted by surname and formatted to allow easy grepping and\nbeautification by scripts.  The fields are: name (N), email (E), web-address\n(W), PGP key ID and fingerprint (P), description (D), and snail-mail address\n(S).\n\nN: Saleem Abdulrasool\nE: compnerd@compnerd.org\nD: Minor patches and Linux fixes.\n\nN: Dan Albert\nE: danalbert@google.com\nD: Android support and test runner improvements.\n\nN: Dimitry Andric\nE: dimitry@andric.com\nD: Visibility fixes, minor FreeBSD portability patches.\n\nN: Holger Arnold\nE: holgerar@gmail.com\nD: Minor fix.\n\nN: Ruben Van Boxem\nE: vanboxem dot ruben at gmail dot com\nD: Initial Windows patches.\n\nN: David Chisnall\nE: theraven at theravensnest dot org\nD: FreeBSD and Solaris ports, libcxxrt support, some atomics work.\n\nN: Marshall Clow\nE: mclow.lists@gmail.com\nE: marshall@idio.com\nD: C++14 support, patches and bug fixes.\n\nN: Eric Fiselier\nE: eric@efcs.ca\nD: LFTS support, patches and bug fixes.\n\nN: Bill Fisher\nE: william.w.fisher@gmail.com\nD: Regex bug fixes.\n\nN: Matthew Dempsky\nE: matthew@dempsky.org\nD: Minor patches and bug fixes.\n\nN: Google Inc.\nD: Copyright owner and contributor of the CityHash algorithm\n\nN: Howard Hinnant\nE: hhinnant@apple.com\nD: Architect and primary author of libc++\n\nN: Hyeon-bin Jeong\nE: tuhertz@gmail.com\nD: Minor patches and bug fixes.\n\nN: Argyrios Kyrtzidis\nE: kyrtzidis@apple.com\nD: Bug fixes.\n\nN: Bruce Mitchener, Jr.\nE: bruce.mitchener@gmail.com\nD: Emscripten-related changes.\n\nN: Michel Morin\nE: mimomorin@gmail.com\nD: Minor patches to is_convertible.\n\nN: Andrew Morrow\nE: andrew.c.morrow@gmail.com\nD: Minor patches and Linux fixes.\n\nN: Arvid Picciani\nE: aep at exys dot org\nD: Minor patches and musl port.\n\nN: Bjorn Reese\nE: breese@users.sourceforge.net\nD: Initial regex prototype\n\nN: Nico Rieck\nE: nico.rieck@gmail.com\nD: Windows fixes\n\nN: Jon Roelofs\nE: jonathan@codesourcery.com\nD: Remote testing, Newlib port, baremetal/single-threaded support.\n\nN: Jonathan Sauer\nD: Minor patches, mostly related to constexpr\n\nN: Craig Silverstein\nE: csilvers@google.com\nD: Implemented Cityhash as the string hash function on 64-bit machines\n\nN: Richard Smith\nD: Minor patches.\n\nN: Joerg Sonnenberger\nE: joerg@NetBSD.org\nD: NetBSD port.\n\nN: Stephan Tolksdorf\nE: st@quanttec.com\nD: Minor <atomic> fix\n\nN: Michael van der Westhuizen\nE: r1mikey at gmail dot com\n\nN: Larisse Voufo\nD: Minor patches.\n\nN: Klaas de Vries\nE: klaas at klaasgaaf dot nl\nD: Minor bug fix.\n\nN: Zhang Xiongpang\nE: zhangxiongpang@gmail.com\nD: Minor patches and bug fixes.\n\nN: Xing Xue\nE: xingxue@ca.ibm.com\nD: AIX port\n\nN: Zhihao Yuan\nE: lichray@gmail.com\nD: Standard compatibility fixes.\n\nN: Jeffrey Yasskin\nE: jyasskin@gmail.com\nE: jyasskin@google.com\nD: Linux fixes.\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/LICENSE.TXT",
    "content": "==============================================================================\nlibc++ License\n==============================================================================\n\nThe libc++ library is dual licensed under both the University of Illinois\n\"BSD-Like\" license and the MIT license.  As a user of this code you may choose\nto use it under either license.  As a contributor, you agree to allow your code\nto be used under both.\n\nFull text of the relevant licenses is included below.\n\n==============================================================================\n\nUniversity of Illinois/NCSA\nOpen Source License\n\nCopyright (c) 2009-2015 by the contributors listed in CREDITS.TXT\n\nAll rights reserved.\n\nDeveloped by:\n\n    LLVM Team\n\n    University of Illinois at Urbana-Champaign\n\n    http://llvm.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal with\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimers.\n\n    * Redistributions in binary form must reproduce the above copyright notice,\n      this list of conditions and the following disclaimers in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the names of the LLVM Team, University of Illinois at\n      Urbana-Champaign, nor the names of its contributors may be used to\n      endorse or promote products derived from this Software without specific\n      prior written permission.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\nCONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE\nSOFTWARE.\n\n==============================================================================\n\nCopyright (c) 2009-2014 by the contributors listed in CREDITS.TXT\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/MODULE_LICENSE_BSD_LIKE",
    "content": ""
  },
  {
    "path": "atlas-aapt/external/libcxx/Makefile",
    "content": "##\n# libc++ Makefile\n##\n\nSRCDIRS = .\nDESTDIR = $(DSTROOT)\n\nOBJROOT=.\nSYMROOT=.\nexport TRIPLE=-apple-\n\nifeq (,$(RC_INDIGO))\n\tINSTALL_PREFIX=\"\"\nelse\n\tINSTALL_PREFIX=\"$(SDKROOT)\"\nendif\nINSTALL_DIR=$(DSTROOT)/$(INSTALL_PREFIX)\n\n.PHONY: help installsrc clean installheaders install\n\nhelp::\n\t@echo \"Use make install DSTROOT=<destination>\"\n\ninstallsrc:: $(SRCROOT)\n\n\tditto $(SRCDIRS)/include $(SRCROOT)/include\n\tditto $(SRCDIRS)/lib $(SRCROOT)/lib\n\tditto $(SRCDIRS)/src $(SRCROOT)/src\n\tditto $(SRCDIRS)/Makefile $(SRCROOT)/Makefile\n\nclean::\n\n# The installheaders target is used by clang's runtime/libcxx makefile.\ninstallheaders::\n\tmkdir -p $(HEADER_DIR)/c++/v1/ext\n\t(cd $(SRCDIRS)/include && \\\n\t  tar cf - --exclude=\".*\" --exclude=support \\\n\t           --exclude=CMakeLists.txt *) | \\\n\t  (cd $(HEADER_DIR)/c++/v1 && tar xf -)\n\tchmod 755 $(HEADER_DIR)/c++/v1\n\tchmod 644 $(HEADER_DIR)/c++/v1/*\n\tchmod 755 $(HEADER_DIR)/c++/v1/ext\n\tchmod 644 $(HEADER_DIR)/c++/v1/ext/*\n\tchmod 755 $(HEADER_DIR)/c++/v1/experimental\n\tchmod 644 $(HEADER_DIR)/c++/v1/experimental/*\n\ninstall::\n\n\tcd lib && ./buildit\n\tditto lib/libc++.1.dylib $(SYMROOT)/usr/lib/libc++.1.dylib\n\tcd lib && dsymutil -o $(SYMROOT)/libc++.1.dylib.dSYM \\\n\t  $(SYMROOT)/usr/lib/libc++.1.dylib\n\tmkdir -p $(INSTALL_DIR)/usr/lib\n\tstrip -S -o $(INSTALL_DIR)/usr/lib/libc++.1.dylib \\\n\t  $(SYMROOT)/usr/lib/libc++.1.dylib\n\tcd $(INSTALL_DIR)/usr/lib && ln -s libc++.1.dylib libc++.dylib\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/NOTICE",
    "content": "==============================================================================\nlibc++ License\n==============================================================================\n\nThe libc++ library is dual licensed under both the University of Illinois\n\"BSD-Like\" license and the MIT license.  As a user of this code you may choose\nto use it under either license.  As a contributor, you agree to allow your code\nto be used under both.\n\nFull text of the relevant licenses is included below.\n\n==============================================================================\n\nUniversity of Illinois/NCSA\nOpen Source License\n\nCopyright (c) 2009-2014 by the contributors listed in CREDITS.TXT\n\nAll rights reserved.\n\nDeveloped by:\n\n    LLVM Team\n\n    University of Illinois at Urbana-Champaign\n\n    http://llvm.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal with\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimers.\n\n    * Redistributions in binary form must reproduce the above copyright notice,\n      this list of conditions and the following disclaimers in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the names of the LLVM Team, University of Illinois at\n      Urbana-Champaign, nor the names of its contributors may be used to\n      endorse or promote products derived from this Software without specific\n      prior written permission.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\nCONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE\nSOFTWARE.\n\n==============================================================================\n\nCopyright (c) 2009-2014 by the contributors listed in CREDITS.TXT\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/TODO.TXT",
    "content": "This is meant to be a general place to list things that should be done \"someday\"\n\nABI Related Tasks\n=================\n* Explicitly manage and verify symbols exported from the dylib.\n* Explore using namespaces for managing symbol visibility.\n* Introduce and document ABI versioning/evolution policy.\n\nCXX Runtime Library Tasks\n=========================\n* Cleanup #ifdef hell in sources files that supports the different ABI libraries.\n* Fix that CMake always link to /usr/lib/libc++abi.dylib on OS X.\n* Fix selection of ABI symbol list on OS X.\n* Have CMake generate linker scripts for libc++.so that it properly links the\n  runtime library.\n* Look into mirroring libsupc++'s typeinfo vtable layout when libsupc++/libstdc++\n  is used as the runtime library.\n* Audit libraries that CMake links into libc++. Are they all required?\n* Investigate and document interoperability between libc++ and libstdc++ on\n  linux. Do this for every supported c++ runtime library.\n\nAtomic Related Tasks\n====================\n* Support <atomic> in C++03 (needed for internal use).\n* Audit use of libatomic builtins in <atomic> with GCC.\n* future should use <atomic> for synchronization.\n* call_once should use <atomic> for synchronization.\n* Audit shared_ptr use of <atomic>\n\nTest Suite Tasks\n================\n* Get test suite passing in C++03.\n* Move all libc++ specific tests from test/std into test/libcxx.\n* Improve how LIT handles compiler warnings.\n* Improve the quality and portability of the locale test data.\n\nMisc Tasks\n==========\n* Find all sequences of >2 underscores and eradicate them.\n* run clang-tidy on libc++\n* Document the \"conditionally-supported\" bits of libc++\n* Look at basic_string's move assignment operator, re LWG 2063 and POCMA\n* libc++ is missing try_emplace\n* Put a static_assert in std::allocator to deny const/volatile types (LWG 2447)\n* Investigate the effect of using __decltype instead of __typeof__ to provide\n  decltype in C++03. What code could be broken by this change?\n* Convert failure tests to use Clang Verify.\n* Document support (or lack of) for C++11 libraries in C++03.\n* Document supported compilers.\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/buildcmds/.gitignore",
    "content": "cxx_under_test\ncxx.cmds\nlink.cmds\ntestconfig.mk\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/buildcmds/Android.mk",
    "content": "#\n# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\nLOCAL_PATH := $(call my-dir)\n\n# Don't build for unbundled branches\nifeq (,$(TARGET_BUILD_APPS))\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libc++_build_commands_$(ANDROID_DEVICE)\nLOCAL_SRC_FILES := dummy.cpp\nLOCAL_CXX_STL := libc++\nLOCAL_C_INCLUDES := $(LOCAL_PATH)/../test/support\nLOCAL_CPPFLAGS := \\\n    -std=c++14 \\\n    -fsized-deallocation \\\n    -fexceptions \\\n    -UNDEBUG \\\n    -w \\\n    -Wno-error=non-virtual-dtor \\\n\n# Optimization is causing relocation for nothrow new to be thrown away.\n# http://llvm.org/bugs/show_bug.cgi?id=21421\nLOCAL_CPPFLAGS += -O0\n\nLOCAL_RTTI_FLAG := -frtti\ninclude $(LOCAL_PATH)/testconfig.mk\n\nendif\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/buildcmds/buildcmdscc",
    "content": "#!/bin/bash\nCXX=$1\nARGS=${*:2}\nDIR=external/libcxx/buildcmds\necho $ANDROID_BUILD_TOP/$CXX > $DIR/cxx_under_test\n\necho $ARGS | grep -P '\\S+\\.cpp\\b' > /dev/null\nif [ $? -eq 0 ]; then\n  echo $ARGS | perl -ne 's/\\S+\\.cpp\\b/%SOURCE%/; print' \\\n             | perl -ne 's/\\S+\\.o\\b/%OUT%/; print' > $DIR/cxx.cmds\nelse\n  echo $ARGS | perl -ne 's/out\\/\\S+\\/EXECUTABLES\\/\\S+\\.o\\b/%SOURCE%/; print' \\\n             | perl -ne 's/-o\\s+\\S+\\b/-o %OUT%/; print' > $DIR/link.cmds\nfi\n\n$CXX $ARGS\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/buildcmds/dummy.cpp",
    "content": "int main() {\n  return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/cmake/Modules/CodeCoverage.cmake",
    "content": "find_program(CODE_COVERAGE_LCOV lcov)\nif (NOT CODE_COVERAGE_LCOV)\n  message(FATAL_ERROR \"Cannot find lcov...\")\nendif()\n\nfind_program(CODE_COVERAGE_GENHTML genhtml)\nif (NOT CODE_COVERAGE_GENHTML)\n  message(FATAL_ERROR \"Cannot find genhtml...\")\nendif()\n\nset(CMAKE_CXX_FLAGS_COVERAGE \"-g -O0 --coverage\")\n\nfunction(setup_lcov_test_target_coverage target_name output_dir capture_dirs source_dirs)\n  file(MAKE_DIRECTORY ${output_dir})\n\n  set(CAPTURE_DIRS \"\")\n  foreach(cdir ${capture_dirs})\n    list(APPEND CAPTURE_DIRS \"-d;${cdir}\")\n  endforeach()\n\n  set(EXTRACT_DIRS \"\")\n  foreach(sdir ${source_dirs})\n    list(APPEND EXTRACT_DIRS \"'${sdir}/*'\")\n  endforeach()\n\n  message(STATUS \"Capture Directories: ${CAPTURE_DIRS}\")\n  message(STATUS \"Extract Directories: ${EXTRACT_DIRS}\")\n\n  add_custom_target(generate-lib${target_name}-coverage\n        COMMAND ${CODE_COVERAGE_LCOV} --capture ${CAPTURE_DIRS} -o test_coverage.info\n        COMMAND ${CODE_COVERAGE_LCOV} --extract test_coverage.info ${EXTRACT_DIRS} -o test_coverage.info\n        COMMAND ${CODE_COVERAGE_GENHTML} --demangle-cpp test_coverage.info -o test_coverage\n        COMMAND ${CMAKE_COMMAND} -E remove test_coverage.info\n        WORKING_DIRECTORY ${output_dir}\n        COMMENT \"Generating coverage results\")\nendfunction()\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/cmake/Modules/HandleLibCXXABI.cmake",
    "content": "\n#===============================================================================\n# Add an ABI library if appropriate\n#===============================================================================\n\n#\n# _setup_abi: Set up the build to use an ABI library\n#\n# Parameters:\n#   abidefines: A list of defines needed to compile libc++ with the ABI library\n#   abilib    : The ABI library to link against.\n#   abifiles  : A list of files (which may be relative paths) to copy into the\n#               libc++ build tree for the build.  These files will also be\n#               installed alongside the libc++ headers.\n#   abidirs   : A list of relative paths to create under an include directory\n#               in the libc++ build directory.\n#\nmacro(setup_abi_lib abidefines abilib abifiles abidirs)\n  list(APPEND LIBCXX_COMPILE_FLAGS ${abidefines})\n  set(LIBCXX_CXX_ABI_INCLUDE_PATHS \"${LIBCXX_CXX_ABI_INCLUDE_PATHS}\"\n    CACHE PATH\n    \"Paths to C++ ABI header directories separated by ';'.\" FORCE\n    )\n\n  set(LIBCXX_CXX_ABI_LIBRARY ${abilib})\n\n  set(LIBCXX_ABILIB_FILES ${abifiles})\n\n  file(MAKE_DIRECTORY \"${CMAKE_BINARY_DIR}/include\")\n  foreach(_d ${abidirs})\n    file(MAKE_DIRECTORY \"${CMAKE_BINARY_DIR}/include/${_d}\")\n  endforeach()\n\n  foreach(fpath ${LIBCXX_ABILIB_FILES})\n    set(found FALSE)\n    foreach(incpath ${LIBCXX_CXX_ABI_INCLUDE_PATHS})\n      if (EXISTS \"${incpath}/${fpath}\")\n        set(found TRUE)\n        get_filename_component(dstdir ${fpath} PATH)\n        get_filename_component(ifile ${fpath} NAME)\n        file(COPY \"${incpath}/${fpath}\"\n          DESTINATION \"${CMAKE_BINARY_DIR}/include/${dstdir}\"\n          )\n        install(FILES \"${CMAKE_BINARY_DIR}/include/${fpath}\"\n          DESTINATION include/c++/v1/${dstdir}\n          PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ\n          )\n        list(APPEND abilib_headers \"${CMAKE_BINARY_DIR}/include/${fpath}\")\n      endif()\n    endforeach()\n    if (NOT found)\n      message(WARNING \"Failed to find ${fpath}\")\n    endif()\n  endforeach()\n\n  add_custom_target(LIBCXX_CXX_ABI_DEPS DEPENDS ${abilib_headers})\n  include_directories(\"${CMAKE_BINARY_DIR}/include\")\n\nendmacro()\n\n# Setup the default options if LIBCXX_CXX_ABI is not specified.\nif (NOT LIBCXX_CXX_ABI)\n  if (NOT DEFINED LIBCXX_BUILT_STANDALONE AND\n      IS_DIRECTORY \"${CMAKE_SOURCE_DIR}/projects/libcxxabi\")\n    set(LIBCXX_CXX_ABI_LIBNAME \"libcxxabi\")\n    set(LIBCXX_CXX_ABI_INCLUDE_PATHS \"${CMAKE_SOURCE_DIR}/projects/libcxxabi/include\")\n    set(LIBCXX_CXX_ABI_INTREE 1)\n  else ()\n    set(LIBCXX_CXX_ABI_LIBNAME \"none\")\n  endif ()\nelse ()\n  set(LIBCXX_CXX_ABI_LIBNAME \"${LIBCXX_CXX_ABI}\")\nendif ()\n\n# Configure based on the selected ABI library.\nif (\"${LIBCXX_CXX_ABI_LIBNAME}\" STREQUAL \"libstdc++\" OR\n    \"${LIBCXX_CXX_ABI_LIBNAME}\" STREQUAL \"libsupc++\")\n  set(_LIBSUPCXX_INCLUDE_FILES\n    cxxabi.h bits/c++config.h bits/os_defines.h bits/cpu_defines.h\n    bits/cxxabi_tweaks.h bits/cxxabi_forced.h\n    )\n  if (\"${LIBCXX_CXX_ABI_LIBNAME}\" STREQUAL \"libstdc++\")\n    set(_LIBSUPCXX_DEFINES \"-DLIBSTDCXX\")\n    set(_LIBSUPCXX_LIBNAME stdc++)\n  else()\n    set(_LIBSUPCXX_DEFINES \"\")\n    set(_LIBSUPCXX_LIBNAME supc++)\n  endif()\n  setup_abi_lib(\n    \"-D__GLIBCXX__ ${_LIBSUPCXX_DEFINES}\"\n    \"${_LIBSUPCXX_LIBNAME}\" \"${_LIBSUPCXX_INCLUDE_FILES}\" \"bits\"\n    )\nelseif (\"${LIBCXX_CXX_ABI_LIBNAME}\" STREQUAL \"libcxxabi\")\n  if (LIBCXX_CXX_ABI_INTREE)\n    # Link against just-built \"cxxabi\" target.\n    if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY)\n        set(CXXABI_LIBNAME cxxabi_static)\n    else()\n        set(CXXABI_LIBNAME cxxabi_shared)\n    endif()\n    set(LIBCXX_LIBCPPABI_VERSION \"2\" PARENT_SCOPE)\n  else()\n    # Assume c++abi is installed in the system, rely on -lc++abi link flag.\n    set(CXXABI_LIBNAME \"c++abi\")\n  endif()\n  setup_abi_lib(\"-DLIBCXX_BUILDING_LIBCXXABI\"\n    ${CXXABI_LIBNAME} \"cxxabi.h;__cxxabi_config.h\" \"\"\n    )\nelseif (\"${LIBCXX_CXX_ABI_LIBNAME}\" STREQUAL \"libcxxrt\")\n  setup_abi_lib(\"-DLIBCXXRT\"\n    \"cxxrt\" \"cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h\" \"\"\n    )\nelseif (NOT \"${LIBCXX_CXX_ABI_LIBNAME}\" STREQUAL \"none\")\n  message(FATAL_ERROR\n    \"Currently libstdc++, libsupc++, libcxxabi, libcxxrt and none are \"\n    \"supported for c++ abi.\"\n    )\nendif ()\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/cmake/Modules/HandleLibcxxFlags.cmake",
    "content": "# HandleLibcxxFlags - A set of macros used to setup the flags used to compile\n# and link libc++. These macros add flags to the following CMake variables.\n# - LIBCXX_COMPILE_FLAGS: flags used to compile libc++\n# - LIBCXX_LINK_FLAGS: flags used to link libc++\n# - LIBCXX_LIBRARIES: libraries to link libc++ to.\n\ninclude(CheckCXXCompilerFlag)\n\nunset(add_flag_if_supported)\n\n# Mangle the name of a compiler flag into a valid CMake identifier.\n# Ex: --std=c++11 -> STD_EQ_CXX11\nmacro(mangle_name str output)\n  string(STRIP \"${str}\" strippedStr)\n  string(REGEX REPLACE \"^/\" \"\" strippedStr \"${strippedStr}\")\n  string(REGEX REPLACE \"^-+\" \"\" strippedStr \"${strippedStr}\")\n  string(REGEX REPLACE \"-+$\" \"\" strippedStr \"${strippedStr}\")\n  string(REPLACE \"-\" \"_\" strippedStr \"${strippedStr}\")\n  string(REPLACE \"=\" \"_EQ_\" strippedStr \"${strippedStr}\")\n  string(REPLACE \"+\" \"X\" strippedStr \"${strippedStr}\")\n  string(TOUPPER \"${strippedStr}\" ${output})\nendmacro()\n\n# Remove a list of flags from all CMake variables that affect compile flags.\n# This can be used to remove unwanted flags specified on the command line\n# or added in other parts of LLVM's cmake configuration.\nmacro(remove_flags)\n  foreach(var ${ARGN})\n    string(REPLACE \"${var}\" \"\" CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS}\")\n    string(REPLACE \"${var}\" \"\" CMAKE_C_FLAGS \"${CMAKE_C_FLAGS}\")\n    string(REPLACE \"${var}\" \"\" CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS}\")\n    string(REPLACE \"${var}\" \"\" CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_SHARED_LINKER_FLAGS}\")\n    string(REPLACE \"${var}\" \"\" CMAKE_SHARED_MODULE_FLAGS \"${CMAKE_SHARED_MODULE_FLAGS}\")\n    remove_definitions(${var})\n  endforeach()\nendmacro(remove_flags)\n\n# Add a macro definition if condition is true.\nmacro(define_if condition def)\n  if (${condition})\n    add_definitions(${def})\n  endif()\nendmacro()\n\n# Add a macro definition if condition is not true.\nmacro(define_if_not condition def)\n  if (NOT ${condition})\n    add_definitions(${def})\n  endif()\nendmacro()\n\n# Add a specified list of flags to both 'LIBCXX_COMPILE_FLAGS' and\n# 'LIBCXX_LINK_FLAGS'.\nmacro(add_flags)\n  foreach(value ${ARGN})\n    list(APPEND LIBCXX_COMPILE_FLAGS ${value})\n    list(APPEND LIBCXX_LINK_FLAGS ${value})\n  endforeach()\nendmacro()\n\n# If the specified 'condition' is true then add a list of flags to both\n# 'LIBCXX_COMPILE_FLAGS' and 'LIBCXX_LINK_FLAGS'.\nmacro(add_flags_if condition)\n  if (${condition})\n    add_flags(${ARGN})\n  endif()\nendmacro()\n\n# Add each flag in the list to LIBCXX_COMPILE_FLAGS and LIBCXX_LINK_FLAGS\n# if that flag is supported by the current compiler.\nmacro(add_flags_if_supported)\n  foreach(flag ${ARGN})\n      mangle_name(\"${flag}\" flagname)\n      check_cxx_compiler_flag(\"${flag}\" \"LIBCXX_SUPPORTS_${flagname}_FLAG\")\n      add_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag})\n  endforeach()\nendmacro()\n\n# Add a list of flags to 'LIBCXX_COMPILE_FLAGS'.\nmacro(add_compile_flags)\n  foreach(f ${ARGN})\n    list(APPEND LIBCXX_COMPILE_FLAGS ${f})\n  endforeach()\nendmacro()\n\n# If 'condition' is true then add the specified list of flags to\n# 'LIBCXX_COMPILE_FLAGS'\nmacro(add_compile_flags_if condition)\n  if (${condition})\n    add_compile_flags(${ARGN})\n  endif()\nendmacro()\n\n# For each specified flag, add that flag to 'LIBCXX_COMPILE_FLAGS' if the\n# flag is supported by the C++ compiler.\nmacro(add_compile_flags_if_supported)\n  foreach(flag ${ARGN})\n      mangle_name(\"${flag}\" flagname)\n      check_cxx_compiler_flag(\"${flag}\" \"LIBCXX_SUPPORTS_${flagname}_FLAG\")\n      add_compile_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag})\n  endforeach()\nendmacro()\n\n# Add a list of flags to 'LIBCXX_LINK_FLAGS'.\nmacro(add_link_flags)\n  foreach(f ${ARGN})\n    list(APPEND LIBCXX_LINK_FLAGS ${f})\n  endforeach()\nendmacro()\n\n# If 'condition' is true then add the specified list of flags to\n# 'LIBCXX_LINK_FLAGS'\nmacro(add_link_flags_if condition)\n  if (${condition})\n    add_link_flags(${ARGN})\n  endif()\nendmacro()\n\n# For each specified flag, add that flag to 'LIBCXX_LINK_FLAGS' if the\n# flag is supported by the C++ compiler.\nmacro(add_link_flags_if_supported)\n  foreach(flag ${ARGN})\n    mangle_name(\"${flag}\" flagname)\n    check_cxx_compiler_flag(\"${flag}\" \"LIBCXX_SUPPORTS_${flagname}_FLAG\")\n    add_link_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag})\n  endforeach()\nendmacro()\n\n# Add a list of libraries or link flags to 'LIBCXX_LIBRARIES'.\nmacro(add_library_flags)\n  foreach(lib ${ARGN})\n    list(APPEND LIBCXX_LIBRARIES ${lib})\n  endforeach()\nendmacro()\n\n# if 'condition' is true then add the specified list of libraries and flags\n# to 'LIBCXX_LIBRARIES'.\nmacro(add_library_flags_if condition)\n  if(${condition})\n    add_library_flags(${ARGN})\n  endif()\nendmacro()\n\n# Turn a comma separated CMake list into a space separated string.\nmacro(split_list listname)\n  string(REPLACE \";\" \" \" ${listname} \"${${listname}}\")\nendmacro()\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/cmake/Modules/HandleOutOfTreeLLVM.cmake",
    "content": "macro(find_llvm_parts)\n# Rely on llvm-config.\n  set(CONFIG_OUTPUT)\n  find_program(LLVM_CONFIG \"llvm-config\")\n  if(DEFINED LLVM_PATH)\n    set(LLVM_INCLUDE_DIR ${LLVM_INCLUDE_DIR} CACHE PATH \"Path to llvm/include\")\n    set(LLVM_PATH ${LLVM_PATH} CACHE PATH \"Path to LLVM source tree\")\n    set(LLVM_MAIN_SRC_DIR ${LLVM_PATH})\n    set(LLVM_CMAKE_PATH \"${LLVM_PATH}/cmake/modules\")\n  elseif(LLVM_CONFIG)\n    message(STATUS \"Found LLVM_CONFIG as ${LLVM_CONFIG}\")\n    set(CONFIG_COMMAND ${LLVM_CONFIG}\n      \"--includedir\"\n      \"--prefix\"\n      \"--src-root\")\n    execute_process(\n      COMMAND ${CONFIG_COMMAND}\n      RESULT_VARIABLE HAD_ERROR\n      OUTPUT_VARIABLE CONFIG_OUTPUT\n    )\n    if(NOT HAD_ERROR)\n      string(REGEX REPLACE\n        \"[ \\t]*[\\r\\n]+[ \\t]*\" \";\"\n        CONFIG_OUTPUT ${CONFIG_OUTPUT})\n    else()\n      string(REPLACE \";\" \" \" CONFIG_COMMAND_STR \"${CONFIG_COMMAND}\")\n      message(STATUS \"${CONFIG_COMMAND_STR}\")\n      message(FATAL_ERROR \"llvm-config failed with status ${HAD_ERROR}\")\n    endif()\n\n    list(GET CONFIG_OUTPUT 0 INCLUDE_DIR)\n    list(GET CONFIG_OUTPUT 1 LLVM_OBJ_ROOT)\n    list(GET CONFIG_OUTPUT 2 MAIN_SRC_DIR)\n\n    set(LLVM_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH \"Path to llvm/include\")\n    set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH \"Path to LLVM build tree\")\n    set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH \"Path to LLVM source tree\")\n    set(LLVM_CMAKE_PATH \"${LLVM_BINARY_DIR}/share/llvm/cmake\")\n  else()\n    set(LLVM_FOUND OFF)\n    return()\n  endif()\n\n  if (NOT EXISTS ${LLVM_MAIN_SRC_DIR})\n    message(FATAL_ERROR \"Not found: ${LLVM_MAIN_SRC_DIR}\")\n  endif()\n\n  if(NOT EXISTS ${LLVM_CMAKE_PATH})\n    message(FATAL_ERROR \"Not found: ${LLVM_CMAKE_PATH}\")\n  endif()\n\n  list(APPEND CMAKE_MODULE_PATH \"${LLVM_CMAKE_PATH}\")\n  list(APPEND CMAKE_MODULE_PATH \"${LLVM_MAIN_SRC_DIR}/cmake/modules\")\n\n  set(LLVM_FOUND ON)\nendmacro(find_llvm_parts)\n\n\nif (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)\n  set(LIBCXX_BUILT_STANDALONE 1)\n  message(STATUS \"Configuring for standalone build.\")\n\n  find_llvm_parts()\n\n  # LLVM Options --------------------------------------------------------------\n  include(FindPythonInterp)\n  if( NOT PYTHONINTERP_FOUND )\n    message(WARNING \"Failed to find python interpreter. \"\n                    \"The libc++ test suite will be disabled.\")\n    set(LLVM_INCLUDE_TESTS OFF)\n  endif()\n\n  if (NOT DEFINED LLVM_INCLUDE_TESTS)\n    set(LLVM_INCLUDE_TESTS ${LLVM_FOUND})\n  endif()\n\n  # Required LIT Configuration ------------------------------------------------\n  # Define the default arguments to use with 'lit', and an option for the user\n  # to override.\n  set(LIT_ARGS_DEFAULT \"-sv --show-xfail --show-unsupported\")\n  if (MSVC OR XCODE)\n    set(LIT_ARGS_DEFAULT \"${LIT_ARGS_DEFAULT} --no-progress-bar\")\n  endif()\n  set(LLVM_LIT_ARGS \"${LIT_ARGS_DEFAULT}\" CACHE STRING \"Default options for lit\")\n\n  # Make sure we can use the console pool for recent cmake and ninja > 1.5\n  # Needed for add_lit_testsuite\n  if(CMAKE_VERSION VERSION_LESS 3.1.20141117)\n    set(cmake_3_2_USES_TERMINAL)\n  else()\n    set(cmake_3_2_USES_TERMINAL USES_TERMINAL)\n  endif()\n\n  # Add LLVM Functions --------------------------------------------------------\n  include(AddLLVM OPTIONAL)\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake",
    "content": "# MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>)\n\nmacro( MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage )\n\nstring( COMPARE EQUAL \"${CMAKE_SOURCE_DIR}\" \"${CMAKE_BINARY_DIR}\" _insource )\nif( _insource )\n message( SEND_ERROR \"${_errorMessage}\" )\n message( FATAL_ERROR\n \"In-source builds are not allowed.\n CMake would overwrite the makefiles distributed with Compiler-RT.\n Please create a directory and run cmake from there, passing the path\n to this source directory as the last argument.\n This process created the file `CMakeCache.txt' and the directory `CMakeFiles'.\n Please delete them.\"\n )\nendif( _insource )\n\nendmacro( MACRO_ENSURE_OUT_OF_SOURCE_BUILD )\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/cmake/config-ix.cmake",
    "content": "include(CheckLibraryExists)\ninclude(CheckCXXCompilerFlag)\n\n# Check compiler flags\n\ncheck_cxx_compiler_flag(/WX                     LIBCXX_HAS_WX_FLAG)\ncheck_cxx_compiler_flag(/WX-                    LIBCXX_HAS_NO_WX_FLAG)\ncheck_cxx_compiler_flag(/EHsc                   LIBCXX_HAS_EHSC_FLAG)\ncheck_cxx_compiler_flag(/EHs-                   LIBCXX_HAS_NO_EHS_FLAG)\ncheck_cxx_compiler_flag(/EHa-                   LIBCXX_HAS_NO_EHA_FLAG)\ncheck_cxx_compiler_flag(/GR-                    LIBCXX_HAS_NO_GR_FLAG)\n\n\n# Check libraries\ncheck_library_exists(pthread pthread_create \"\" LIBCXX_HAS_PTHREAD_LIB)\ncheck_library_exists(c printf \"\" LIBCXX_HAS_C_LIB)\ncheck_library_exists(m ccos \"\" LIBCXX_HAS_M_LIB)\ncheck_library_exists(rt clock_gettime \"\" LIBCXX_HAS_RT_LIB)\ncheck_library_exists(gcc_s __gcc_personality_v0 \"\" LIBCXX_HAS_GCC_S_LIB)\n\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/CMakeLists.txt",
    "content": "if (NOT LIBCXX_INSTALL_SUPPORT_HEADERS)\n  set(LIBCXX_SUPPORT_HEADER_PATTERN PATTERN \"support\" EXCLUDE)\nendif()\nset(LIBCXX_HEADER_PATTERN\n  PATTERN \"*\"\n  PATTERN \"CMakeLists.txt\" EXCLUDE\n  PATTERN \".svn\" EXCLUDE\n  ${LIBCXX_SUPPORT_HEADER_PATTERN}\n  )\n\nfile(COPY .\n  DESTINATION \"${CMAKE_BINARY_DIR}/include/c++/v1\"\n  FILES_MATCHING\n  ${LIBCXX_HEADER_PATTERN}\n  )\n\nif (LIBCXX_INSTALL_HEADERS)\n  install(DIRECTORY .\n    DESTINATION include/c++/v1\n    FILES_MATCHING\n    ${LIBCXX_HEADER_PATTERN}\n    PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ\n  )\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__bit_reference",
    "content": "// -*- C++ -*-\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP___BIT_REFERENCE\n#define _LIBCPP___BIT_REFERENCE\n\n#include <__config>\n#include <algorithm>\n\n#include <__undef_min_max>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0> class __bit_iterator;\ntemplate <class _Cp> class __bit_const_reference;\n\ntemplate <class _Tp>\nstruct __has_storage_type\n{\n    static const bool value = false;\n};\n\ntemplate <class _Cp, bool = __has_storage_type<_Cp>::value>\nclass __bit_reference\n{\n    typedef typename _Cp::__storage_type    __storage_type;\n    typedef typename _Cp::__storage_pointer __storage_pointer;\n\n    __storage_pointer __seg_;\n    __storage_type    __mask_;\n\n#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)\n    friend typename _Cp::__self;\n#else\n    friend class _Cp::__self;\n#endif\n    friend class __bit_const_reference<_Cp>;\n    friend class __bit_iterator<_Cp, false>;\npublic:\n    _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT\n        {return static_cast<bool>(*__seg_ & __mask_);}\n    _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT\n        {return !static_cast<bool>(*this);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bit_reference& operator=(bool __x) _NOEXCEPT\n    {\n        if (__x)\n            *__seg_ |= __mask_;\n        else\n            *__seg_ &= ~__mask_;\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT\n        {return operator=(static_cast<bool>(__x));}\n\n    _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;}\n    _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, false> operator&() const _NOEXCEPT\n        {return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(__ctz(__mask_)));}\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT\n        : __seg_(__s), __mask_(__m) {}\n};\n\ntemplate <class _Cp>\nclass __bit_reference<_Cp, false>\n{\n};\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT\n{\n    bool __t = __x;\n    __x = __y;\n    __y = __t;\n}\n\ntemplate <class _Cp, class _Dp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT\n{\n    bool __t = __x;\n    __x = __y;\n    __y = __t;\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT\n{\n    bool __t = __x;\n    __x = __y;\n    __y = __t;\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT\n{\n    bool __t = __x;\n    __x = __y;\n    __y = __t;\n}\n\ntemplate <class _Cp>\nclass __bit_const_reference\n{\n    typedef typename _Cp::__storage_type          __storage_type;\n    typedef typename _Cp::__const_storage_pointer __storage_pointer;\n\n    __storage_pointer        __seg_;\n    __storage_type __mask_;\n\n#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)\n    friend typename _Cp::__self;\n#else\n    friend class _Cp::__self;\n#endif\n    friend class __bit_iterator<_Cp, true>;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT\n        : __seg_(__x.__seg_), __mask_(__x.__mask_) {}\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT\n        {return static_cast<bool>(*__seg_ & __mask_);}\n\n    _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, true> operator&() const _NOEXCEPT\n        {return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(__ctz(__mask_)));}\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_CONSTEXPR\n    __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT\n        : __seg_(__s), __mask_(__m) {}\n\n    __bit_const_reference& operator=(const __bit_const_reference& __x);\n};\n\n// find\n\ntemplate <class _Cp, bool _IsConst>\n__bit_iterator<_Cp, _IsConst>\n__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)\n{\n    typedef __bit_iterator<_Cp, _IsConst> _It;\n    typedef typename _It::__storage_type __storage_type;\n    static const unsigned __bits_per_word = _It::__bits_per_word;\n    // do first partial word\n    if (__first.__ctz_ != 0)\n    {\n        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);\n        __storage_type __dn = _VSTD::min(__clz_f, __n);\n        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));\n        __storage_type __b = *__first.__seg_ & __m;\n        if (__b)\n            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));\n        if (__n == __dn)\n            return __first + __n;\n        __n -= __dn;\n        ++__first.__seg_;\n    }\n    // do middle whole words\n    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)\n        if (*__first.__seg_)\n            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(*__first.__seg_)));\n    // do last partial word\n    if (__n > 0)\n    {\n        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);\n        __storage_type __b = *__first.__seg_ & __m;\n        if (__b)\n            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));\n    }\n    return _It(__first.__seg_, static_cast<unsigned>(__n));\n}\n\ntemplate <class _Cp, bool _IsConst>\n__bit_iterator<_Cp, _IsConst>\n__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)\n{\n    typedef __bit_iterator<_Cp, _IsConst> _It;\n    typedef typename _It::__storage_type __storage_type;\n    static const unsigned __bits_per_word = _It::__bits_per_word;\n    // do first partial word\n    if (__first.__ctz_ != 0)\n    {\n        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);\n        __storage_type __dn = _VSTD::min(__clz_f, __n);\n        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));\n        __storage_type __b = ~*__first.__seg_ & __m;\n        if (__b)\n            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));\n        if (__n == __dn)\n            return __first + __n;\n        __n -= __dn;\n        ++__first.__seg_;\n    }\n    // do middle whole words\n    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)\n    {\n        __storage_type __b = ~*__first.__seg_;\n        if (__b)\n            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));\n    }\n    // do last partial word\n    if (__n > 0)\n    {\n        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);\n        __storage_type __b = ~*__first.__seg_ & __m;\n        if (__b)\n            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));\n    }\n    return _It(__first.__seg_, static_cast<unsigned>(__n));\n}\n\ntemplate <class _Cp, bool _IsConst, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n__bit_iterator<_Cp, _IsConst>\nfind(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)\n{\n    if (static_cast<bool>(__value_))\n        return __find_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));\n    return __find_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));\n}\n\n// count\n\ntemplate <class _Cp, bool _IsConst>\ntypename __bit_iterator<_Cp, _IsConst>::difference_type\n__count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)\n{\n    typedef __bit_iterator<_Cp, _IsConst> _It;\n    typedef typename _It::__storage_type __storage_type;\n    typedef typename _It::difference_type difference_type;\n    static const unsigned __bits_per_word = _It::__bits_per_word;\n    difference_type __r = 0;\n    // do first partial word\n    if (__first.__ctz_ != 0)\n    {\n        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);\n        __storage_type __dn = _VSTD::min(__clz_f, __n);\n        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));\n        __r = _VSTD::__pop_count(*__first.__seg_ & __m);\n        __n -= __dn;\n        ++__first.__seg_;\n    }\n    // do middle whole words\n    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)\n        __r += _VSTD::__pop_count(*__first.__seg_);\n    // do last partial word\n    if (__n > 0)\n    {\n        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);\n        __r += _VSTD::__pop_count(*__first.__seg_ & __m);\n    }\n    return __r;\n}\n\ntemplate <class _Cp, bool _IsConst>\ntypename __bit_iterator<_Cp, _IsConst>::difference_type\n__count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)\n{\n    typedef __bit_iterator<_Cp, _IsConst> _It;\n    typedef typename _It::__storage_type __storage_type;\n    typedef typename _It::difference_type difference_type;\n    static const unsigned __bits_per_word = _It::__bits_per_word;\n    difference_type __r = 0;\n    // do first partial word\n    if (__first.__ctz_ != 0)\n    {\n        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);\n        __storage_type __dn = _VSTD::min(__clz_f, __n);\n        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));\n        __r = _VSTD::__pop_count(~*__first.__seg_ & __m);\n        __n -= __dn;\n        ++__first.__seg_;\n    }\n    // do middle whole words\n    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)\n        __r += _VSTD::__pop_count(~*__first.__seg_);\n    // do last partial word\n    if (__n > 0)\n    {\n        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);\n        __r += _VSTD::__pop_count(~*__first.__seg_ & __m);\n    }\n    return __r;\n}\n\ntemplate <class _Cp, bool _IsConst, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __bit_iterator<_Cp, _IsConst>::difference_type\ncount(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)\n{\n    if (static_cast<bool>(__value_))\n        return __count_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));\n    return __count_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));\n}\n\n// fill_n\n\ntemplate <class _Cp>\nvoid\n__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)\n{\n    typedef __bit_iterator<_Cp, false> _It;\n    typedef typename _It::__storage_type __storage_type;\n    static const unsigned __bits_per_word = _It::__bits_per_word;\n    // do first partial word\n    if (__first.__ctz_ != 0)\n    {\n        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);\n        __storage_type __dn = _VSTD::min(__clz_f, __n);\n        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));\n        *__first.__seg_ &= ~__m;\n        __n -= __dn;\n        ++__first.__seg_;\n    }\n    // do middle whole words\n    __storage_type __nw = __n / __bits_per_word;\n    _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), 0, __nw * sizeof(__storage_type));\n    __n -= __nw * __bits_per_word;\n    // do last partial word\n    if (__n > 0)\n    {\n        __first.__seg_ += __nw;\n        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);\n        *__first.__seg_ &= ~__m;\n    }\n}\n\ntemplate <class _Cp>\nvoid\n__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)\n{\n    typedef __bit_iterator<_Cp, false> _It;\n    typedef typename _It::__storage_type __storage_type;\n    static const unsigned __bits_per_word = _It::__bits_per_word;\n    // do first partial word\n    if (__first.__ctz_ != 0)\n    {\n        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);\n        __storage_type __dn = _VSTD::min(__clz_f, __n);\n        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));\n        *__first.__seg_ |= __m;\n        __n -= __dn;\n        ++__first.__seg_;\n    }\n    // do middle whole words\n    __storage_type __nw = __n / __bits_per_word;\n    _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), -1, __nw * sizeof(__storage_type));\n    __n -= __nw * __bits_per_word;\n    // do last partial word\n    if (__n > 0)\n    {\n        __first.__seg_ += __nw;\n        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);\n        *__first.__seg_ |= __m;\n    }\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nfill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value_)\n{\n    if (__n > 0)\n    {\n        if (__value_)\n            __fill_n_true(__first, __n);\n        else\n            __fill_n_false(__first, __n);\n    }\n}\n\n// fill\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nfill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value_)\n{\n    _VSTD::fill_n(__first, static_cast<typename _Cp::size_type>(__last - __first), __value_);\n}\n\n// copy\n\ntemplate <class _Cp, bool _IsConst>\n__bit_iterator<_Cp, false>\n__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,\n                                                     __bit_iterator<_Cp, false> __result)\n{\n    typedef __bit_iterator<_Cp, _IsConst> _In;\n    typedef  typename _In::difference_type difference_type;\n    typedef typename _In::__storage_type __storage_type;\n    static const unsigned __bits_per_word = _In::__bits_per_word;\n    difference_type __n = __last - __first;\n    if (__n > 0)\n    {\n        // do first word\n        if (__first.__ctz_ != 0)\n        {\n            unsigned __clz = __bits_per_word - __first.__ctz_;\n            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);\n            __n -= __dn;\n            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));\n            __storage_type __b = *__first.__seg_ & __m;\n            *__result.__seg_ &= ~__m;\n            *__result.__seg_ |= __b;\n            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;\n            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);\n            ++__first.__seg_;\n            // __first.__ctz_ = 0;\n        }\n        // __first.__ctz_ == 0;\n        // do middle words\n        __storage_type __nw = __n / __bits_per_word;\n        _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),\n                       _VSTD::__to_raw_pointer(__first.__seg_),\n                       __nw * sizeof(__storage_type));\n        __n -= __nw * __bits_per_word;\n        __result.__seg_ += __nw;\n        // do last word\n        if (__n > 0)\n        {\n            __first.__seg_ += __nw;\n            __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);\n            __storage_type __b = *__first.__seg_ & __m;\n            *__result.__seg_ &= ~__m;\n            *__result.__seg_ |= __b;\n            __result.__ctz_ = static_cast<unsigned>(__n);\n        }\n    }\n    return __result;\n}\n\ntemplate <class _Cp, bool _IsConst>\n__bit_iterator<_Cp, false>\n__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,\n                                                       __bit_iterator<_Cp, false> __result)\n{\n    typedef __bit_iterator<_Cp, _IsConst> _In;\n    typedef  typename _In::difference_type difference_type;\n    typedef typename _In::__storage_type __storage_type;\n    static const unsigned __bits_per_word = _In::__bits_per_word;\n    difference_type __n = __last - __first;\n    if (__n > 0)\n    {\n        // do first word\n        if (__first.__ctz_ != 0)\n        {\n            unsigned __clz_f = __bits_per_word - __first.__ctz_;\n            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);\n            __n -= __dn;\n            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));\n            __storage_type __b = *__first.__seg_ & __m;\n            unsigned __clz_r = __bits_per_word - __result.__ctz_;\n            __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);\n            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));\n            *__result.__seg_ &= ~__m;\n            if (__result.__ctz_ > __first.__ctz_)\n                *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);\n            else\n                *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);\n            __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;\n            __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_)  % __bits_per_word);\n            __dn -= __ddn;\n            if (__dn > 0)\n            {\n                __m = ~__storage_type(0) >> (__bits_per_word - __dn);\n                *__result.__seg_ &= ~__m;\n                *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);\n                __result.__ctz_ = static_cast<unsigned>(__dn);\n            }\n            ++__first.__seg_;\n            // __first.__ctz_ = 0;\n        }\n        // __first.__ctz_ == 0;\n        // do middle words\n        unsigned __clz_r = __bits_per_word - __result.__ctz_;\n        __storage_type __m = ~__storage_type(0) << __result.__ctz_;\n        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)\n        {\n            __storage_type __b = *__first.__seg_;\n            *__result.__seg_ &= ~__m;\n            *__result.__seg_ |= __b << __result.__ctz_;\n            ++__result.__seg_;\n            *__result.__seg_ &= __m;\n            *__result.__seg_ |= __b >> __clz_r;\n        }\n        // do last word\n        if (__n > 0)\n        {\n            __m = ~__storage_type(0) >> (__bits_per_word - __n);\n            __storage_type __b = *__first.__seg_ & __m;\n            __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));\n            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));\n            *__result.__seg_ &= ~__m;\n            *__result.__seg_ |= __b << __result.__ctz_;\n            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;\n            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);\n            __n -= __dn;\n            if (__n > 0)\n            {\n                __m = ~__storage_type(0) >> (__bits_per_word - __n);\n                *__result.__seg_ &= ~__m;\n                *__result.__seg_ |= __b >> __dn;\n                __result.__ctz_ = static_cast<unsigned>(__n);\n            }\n        }\n    }\n    return __result;\n}\n\ntemplate <class _Cp, bool _IsConst>\ninline _LIBCPP_INLINE_VISIBILITY\n__bit_iterator<_Cp, false>\ncopy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)\n{\n    if (__first.__ctz_ == __result.__ctz_)\n        return __copy_aligned(__first, __last, __result);\n    return __copy_unaligned(__first, __last, __result);\n}\n\n// copy_backward\n\ntemplate <class _Cp, bool _IsConst>\n__bit_iterator<_Cp, false>\n__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,\n                                                     __bit_iterator<_Cp, false> __result)\n{\n    typedef __bit_iterator<_Cp, _IsConst> _In;\n    typedef  typename _In::difference_type difference_type;\n    typedef typename _In::__storage_type __storage_type;\n    static const unsigned __bits_per_word = _In::__bits_per_word;\n    difference_type __n = __last - __first;\n    if (__n > 0)\n    {\n        // do first word\n        if (__last.__ctz_ != 0)\n        {\n            difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);\n            __n -= __dn;\n            unsigned __clz = __bits_per_word - __last.__ctz_;\n            __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz);\n            __storage_type __b = *__last.__seg_ & __m;\n            *__result.__seg_ &= ~__m;\n            *__result.__seg_ |= __b;\n            __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +\n                                                       __result.__ctz_)  % __bits_per_word);\n            // __last.__ctz_ = 0\n         }\n        // __last.__ctz_ == 0 || __n == 0\n        // __result.__ctz_ == 0 || __n == 0\n        // do middle words\n        __storage_type __nw = __n / __bits_per_word;\n        __result.__seg_ -= __nw;\n        __last.__seg_ -= __nw;\n        _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),\n                       _VSTD::__to_raw_pointer(__last.__seg_),\n                       __nw * sizeof(__storage_type));\n        __n -= __nw * __bits_per_word;\n        // do last word\n        if (__n > 0)\n        {\n            __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n);\n            __storage_type __b = *--__last.__seg_ & __m;\n            *--__result.__seg_ &= ~__m;\n            *__result.__seg_ |= __b;\n            __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));\n        }\n    }\n    return __result;\n}\n\ntemplate <class _Cp, bool _IsConst>\n__bit_iterator<_Cp, false>\n__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,\n                                                       __bit_iterator<_Cp, false> __result)\n{\n    typedef __bit_iterator<_Cp, _IsConst> _In;\n    typedef  typename _In::difference_type difference_type;\n    typedef typename _In::__storage_type __storage_type;\n    static const unsigned __bits_per_word = _In::__bits_per_word;\n    difference_type __n = __last - __first;\n    if (__n > 0)\n    {\n        // do first word\n        if (__last.__ctz_ != 0)\n        {\n            difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);\n            __n -= __dn;\n            unsigned __clz_l = __bits_per_word - __last.__ctz_;\n            __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l);\n            __storage_type __b = *__last.__seg_ & __m;\n            unsigned __clz_r = __bits_per_word - __result.__ctz_;\n            __storage_type __ddn = _VSTD::min(__dn, static_cast<difference_type>(__result.__ctz_));\n            if (__ddn > 0)\n            {\n                __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r);\n                *__result.__seg_ &= ~__m;\n                if (__result.__ctz_ > __last.__ctz_)\n                    *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);\n                else\n                    *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_);\n                __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) +\n                                                         __result.__ctz_)  % __bits_per_word);\n                __dn -= __ddn;\n            }\n            if (__dn > 0)\n            {\n                // __result.__ctz_ == 0\n                --__result.__seg_;\n                __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1));\n                __m = ~__storage_type(0) << __result.__ctz_;\n                *__result.__seg_ &= ~__m;\n                __last.__ctz_ -= __dn + __ddn;\n                *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);\n            }\n            // __last.__ctz_ = 0\n         }\n        // __last.__ctz_ == 0 || __n == 0\n        // __result.__ctz_ != 0 || __n == 0\n        // do middle words\n        unsigned __clz_r = __bits_per_word - __result.__ctz_;\n        __storage_type __m = ~__storage_type(0) >> __clz_r;\n        for (; __n >= __bits_per_word; __n -= __bits_per_word)\n        {\n            __storage_type __b = *--__last.__seg_;\n            *__result.__seg_ &= ~__m;\n            *__result.__seg_ |= __b >> __clz_r;\n            *--__result.__seg_ &= __m;\n            *__result.__seg_ |= __b << __result.__ctz_;\n        }\n        // do last word\n        if (__n > 0)\n        {\n            __m = ~__storage_type(0) << (__bits_per_word - __n);\n            __storage_type __b = *--__last.__seg_ & __m;\n            __clz_r = __bits_per_word - __result.__ctz_;\n            __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__result.__ctz_));\n            __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r);\n            *__result.__seg_ &= ~__m;\n            *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_);\n            __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +\n                                                     __result.__ctz_)  % __bits_per_word);\n            __n -= __dn;\n            if (__n > 0)\n            {\n                // __result.__ctz_ == 0\n                --__result.__seg_;\n                __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));\n                __m = ~__storage_type(0) << __result.__ctz_;\n                *__result.__seg_ &= ~__m;\n                *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn));\n            }\n        }\n    }\n    return __result;\n}\n\ntemplate <class _Cp, bool _IsConst>\ninline _LIBCPP_INLINE_VISIBILITY\n__bit_iterator<_Cp, false>\ncopy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)\n{\n    if (__last.__ctz_ == __result.__ctz_)\n        return __copy_backward_aligned(__first, __last, __result);\n    return __copy_backward_unaligned(__first, __last, __result);\n}\n\n// move\n\ntemplate <class _Cp, bool _IsConst>\ninline _LIBCPP_INLINE_VISIBILITY\n__bit_iterator<_Cp, false>\nmove(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)\n{\n    return _VSTD::copy(__first, __last, __result);\n}\n\n// move_backward\n\ntemplate <class _Cp, bool _IsConst>\ninline _LIBCPP_INLINE_VISIBILITY\n__bit_iterator<_Cp, false>\nmove_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)\n{\n    return _VSTD::copy_backward(__first, __last, __result);\n}\n\n// swap_ranges\n\ntemplate <class __C1, class __C2>\n__bit_iterator<__C2, false>\n__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,\n                      __bit_iterator<__C2, false> __result)\n{\n    typedef __bit_iterator<__C1, false> _I1;\n    typedef  typename _I1::difference_type difference_type;\n    typedef typename _I1::__storage_type __storage_type;\n    static const unsigned __bits_per_word = _I1::__bits_per_word;\n    difference_type __n = __last - __first;\n    if (__n > 0)\n    {\n        // do first word\n        if (__first.__ctz_ != 0)\n        {\n            unsigned __clz = __bits_per_word - __first.__ctz_;\n            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);\n            __n -= __dn;\n            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));\n            __storage_type __b1 = *__first.__seg_ & __m;\n            *__first.__seg_ &= ~__m;\n            __storage_type __b2 = *__result.__seg_ & __m;\n            *__result.__seg_ &= ~__m;\n            *__result.__seg_ |= __b1;\n            *__first.__seg_  |= __b2;\n            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;\n            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);\n            ++__first.__seg_;\n            // __first.__ctz_ = 0;\n        }\n        // __first.__ctz_ == 0;\n        // do middle words\n        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_)\n            swap(*__first.__seg_, *__result.__seg_);\n        // do last word\n        if (__n > 0)\n        {\n            __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);\n            __storage_type __b1 = *__first.__seg_ & __m;\n            *__first.__seg_ &= ~__m;\n            __storage_type __b2 = *__result.__seg_ & __m;\n            *__result.__seg_ &= ~__m;\n            *__result.__seg_ |= __b1;\n            *__first.__seg_  |= __b2;\n            __result.__ctz_ = static_cast<unsigned>(__n);\n        }\n    }\n    return __result;\n}\n\ntemplate <class __C1, class __C2>\n__bit_iterator<__C2, false>\n__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,\n                        __bit_iterator<__C2, false> __result)\n{\n    typedef __bit_iterator<__C1, false> _I1;\n    typedef  typename _I1::difference_type difference_type;\n    typedef typename _I1::__storage_type __storage_type;\n    static const unsigned __bits_per_word = _I1::__bits_per_word;\n    difference_type __n = __last - __first;\n    if (__n > 0)\n    {\n        // do first word\n        if (__first.__ctz_ != 0)\n        {\n            unsigned __clz_f = __bits_per_word - __first.__ctz_;\n            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);\n            __n -= __dn;\n            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));\n            __storage_type __b1 = *__first.__seg_ & __m;\n            *__first.__seg_ &= ~__m;\n            unsigned __clz_r = __bits_per_word - __result.__ctz_;\n            __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);\n            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));\n            __storage_type __b2 = *__result.__seg_ & __m;\n            *__result.__seg_ &= ~__m;\n            if (__result.__ctz_ > __first.__ctz_)\n            {\n                unsigned __s = __result.__ctz_ - __first.__ctz_;\n                *__result.__seg_ |= __b1 << __s;\n                *__first.__seg_  |= __b2 >> __s;\n            }\n            else\n            {\n                unsigned __s = __first.__ctz_ - __result.__ctz_;\n                *__result.__seg_ |= __b1 >> __s;\n                *__first.__seg_  |= __b2 << __s;\n            }\n            __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;\n            __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_)  % __bits_per_word);\n            __dn -= __ddn;\n            if (__dn > 0)\n            {\n                __m = ~__storage_type(0) >> (__bits_per_word - __dn);\n                __b2 = *__result.__seg_ & __m;\n                *__result.__seg_ &= ~__m;\n                unsigned __s = __first.__ctz_ + __ddn;\n                *__result.__seg_ |= __b1 >> __s;\n                *__first.__seg_  |= __b2 << __s;\n                __result.__ctz_ = static_cast<unsigned>(__dn);\n            }\n            ++__first.__seg_;\n            // __first.__ctz_ = 0;\n        }\n        // __first.__ctz_ == 0;\n        // do middle words\n        __storage_type __m = ~__storage_type(0) << __result.__ctz_;\n        unsigned __clz_r = __bits_per_word - __result.__ctz_;\n        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)\n        {\n            __storage_type __b1 = *__first.__seg_;\n            __storage_type __b2 = *__result.__seg_ & __m;\n            *__result.__seg_ &= ~__m;\n            *__result.__seg_ |= __b1 << __result.__ctz_;\n            *__first.__seg_  = __b2 >> __result.__ctz_;\n            ++__result.__seg_;\n            __b2 = *__result.__seg_ & ~__m;\n            *__result.__seg_ &= __m;\n            *__result.__seg_ |= __b1 >> __clz_r;\n            *__first.__seg_  |= __b2 << __clz_r;\n        }\n        // do last word\n        if (__n > 0)\n        {\n            __m = ~__storage_type(0) >> (__bits_per_word - __n);\n            __storage_type __b1 = *__first.__seg_ & __m;\n            *__first.__seg_ &= ~__m;\n            __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r);\n            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));\n            __storage_type __b2 = *__result.__seg_ & __m;\n            *__result.__seg_ &= ~__m;\n            *__result.__seg_ |= __b1 << __result.__ctz_;\n            *__first.__seg_  |= __b2 >> __result.__ctz_;\n            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;\n            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);\n            __n -= __dn;\n            if (__n > 0)\n            {\n                __m = ~__storage_type(0) >> (__bits_per_word - __n);\n                __b2 = *__result.__seg_ & __m;\n                *__result.__seg_ &= ~__m;\n                *__result.__seg_ |= __b1 >> __dn;\n                *__first.__seg_  |= __b2 << __dn;\n                __result.__ctz_ = static_cast<unsigned>(__n);\n            }\n        }\n    }\n    return __result;\n}\n\ntemplate <class __C1, class __C2>\ninline _LIBCPP_INLINE_VISIBILITY\n__bit_iterator<__C2, false>\nswap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1,\n            __bit_iterator<__C2, false> __first2)\n{\n    if (__first1.__ctz_ == __first2.__ctz_)\n        return __swap_ranges_aligned(__first1, __last1, __first2);\n    return __swap_ranges_unaligned(__first1, __last1, __first2);\n}\n\n// rotate\n\ntemplate <class _Cp>\nstruct __bit_array\n{\n    typedef typename _Cp::difference_type difference_type;\n    typedef typename _Cp::__storage_type  __storage_type;\n    typedef typename _Cp::__storage_pointer __storage_pointer;\n    typedef typename _Cp::iterator        iterator;\n    static const unsigned __bits_per_word = _Cp::__bits_per_word;\n    static const unsigned _Np = 4;\n\n    difference_type __size_;\n    __storage_type __word_[_Np];\n\n    _LIBCPP_INLINE_VISIBILITY static difference_type capacity()\n        {return static_cast<difference_type>(_Np * __bits_per_word);}\n    _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {}\n    _LIBCPP_INLINE_VISIBILITY iterator begin()\n    {\n        return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);\n    }\n    _LIBCPP_INLINE_VISIBILITY iterator end()\n    {\n        return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,\n                                                  static_cast<unsigned>(__size_ % __bits_per_word));\n    }\n};\n\ntemplate <class _Cp>\n__bit_iterator<_Cp, false>\nrotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last)\n{\n    typedef __bit_iterator<_Cp, false> _I1;\n    typedef  typename _I1::difference_type difference_type;\n    difference_type __d1 = __middle - __first;\n    difference_type __d2 = __last - __middle;\n    _I1 __r = __first + __d2;\n    while (__d1 != 0 && __d2 != 0)\n    {\n        if (__d1 <= __d2)\n        {\n            if (__d1 <= __bit_array<_Cp>::capacity())\n            {\n                __bit_array<_Cp> __b(__d1);\n                _VSTD::copy(__first, __middle, __b.begin());\n                _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first));\n                break;\n            }\n            else\n            {\n                __bit_iterator<_Cp, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle);\n                __first = __middle;\n                __middle = __mp;\n                __d2 -= __d1;\n            }\n        }\n        else\n        {\n            if (__d2 <= __bit_array<_Cp>::capacity())\n            {\n                __bit_array<_Cp> __b(__d2);\n                _VSTD::copy(__middle, __last, __b.begin());\n                _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last));\n                break;\n            }\n            else\n            {\n                __bit_iterator<_Cp, false> __mp = __first + __d2;\n                _VSTD::swap_ranges(__first, __mp, __middle);\n                __first = __mp;\n                __d1 -= __d2;\n            }\n        }\n    }\n    return __r;\n}\n\n// equal\n\ntemplate <class _Cp, bool _IC1, bool _IC2>\nbool\n__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,\n                  __bit_iterator<_Cp, _IC2> __first2)\n{\n    typedef __bit_iterator<_Cp, _IC1> _It;\n    typedef  typename _It::difference_type difference_type;\n    typedef typename _It::__storage_type __storage_type;\n    static const unsigned __bits_per_word = _It::__bits_per_word;\n    difference_type __n = __last1 - __first1;\n    if (__n > 0)\n    {\n        // do first word\n        if (__first1.__ctz_ != 0)\n        {\n            unsigned __clz_f = __bits_per_word - __first1.__ctz_;\n            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);\n            __n -= __dn;\n            __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));\n            __storage_type __b = *__first1.__seg_ & __m;\n            unsigned __clz_r = __bits_per_word - __first2.__ctz_;\n            __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);\n            __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));\n            if (__first2.__ctz_ > __first1.__ctz_)\n            {\n                if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_)))\n                    return false;\n            }\n            else\n            {\n                if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_)))\n                    return false;\n            }\n            __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word;\n            __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_)  % __bits_per_word);\n            __dn -= __ddn;\n            if (__dn > 0)\n            {\n                __m = ~__storage_type(0) >> (__bits_per_word - __dn);\n                if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn)))\n                    return false;\n                __first2.__ctz_ = static_cast<unsigned>(__dn);\n            }\n            ++__first1.__seg_;\n            // __first1.__ctz_ = 0;\n        }\n        // __first1.__ctz_ == 0;\n        // do middle words\n        unsigned __clz_r = __bits_per_word - __first2.__ctz_;\n        __storage_type __m = ~__storage_type(0) << __first2.__ctz_;\n        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_)\n        {\n            __storage_type __b = *__first1.__seg_;\n            if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))\n                return false;\n            ++__first2.__seg_;\n            if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r))\n                return false;\n        }\n        // do last word\n        if (__n > 0)\n        {\n            __m = ~__storage_type(0) >> (__bits_per_word - __n);\n            __storage_type __b = *__first1.__seg_ & __m;\n            __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));\n            __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));\n            if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))\n                return false;\n            __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word;\n            __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_)  % __bits_per_word);\n            __n -= __dn;\n            if (__n > 0)\n            {\n                __m = ~__storage_type(0) >> (__bits_per_word - __n);\n                if ((*__first2.__seg_ & __m) != (__b >> __dn))\n                    return false;\n            }\n        }\n    }\n    return true;\n}\n\ntemplate <class _Cp, bool _IC1, bool _IC2>\nbool\n__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,\n                __bit_iterator<_Cp, _IC2> __first2)\n{\n    typedef __bit_iterator<_Cp, _IC1> _It;\n    typedef  typename _It::difference_type difference_type;\n    typedef typename _It::__storage_type __storage_type;\n    static const unsigned __bits_per_word = _It::__bits_per_word;\n    difference_type __n = __last1 - __first1;\n    if (__n > 0)\n    {\n        // do first word\n        if (__first1.__ctz_ != 0)\n        {\n            unsigned __clz = __bits_per_word - __first1.__ctz_;\n            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);\n            __n -= __dn;\n            __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn));\n            if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))\n                return false;\n            ++__first2.__seg_;\n            ++__first1.__seg_;\n            // __first1.__ctz_ = 0;\n            // __first2.__ctz_ = 0;\n        }\n        // __first1.__ctz_ == 0;\n        // __first2.__ctz_ == 0;\n        // do middle words\n        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_)\n            if (*__first2.__seg_ != *__first1.__seg_)\n                return false;\n        // do last word\n        if (__n > 0)\n        {\n            __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);\n            if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))\n                return false;\n        }\n    }\n    return true;\n}\n\ntemplate <class _Cp, bool _IC1, bool _IC2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nequal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2)\n{\n    if (__first1.__ctz_ == __first2.__ctz_)\n        return __equal_aligned(__first1, __last1, __first2);\n    return __equal_unaligned(__first1, __last1, __first2);\n}\n\ntemplate <class _Cp, bool _IsConst,\n          typename _Cp::__storage_type>\nclass __bit_iterator\n{\npublic:\n    typedef typename _Cp::difference_type                                                          difference_type;\n    typedef bool                                                                                  value_type;\n    typedef __bit_iterator                                                                        pointer;\n    typedef typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >::type reference;\n    typedef random_access_iterator_tag                                                            iterator_category;\n\nprivate:\n    typedef typename _Cp::__storage_type                                           __storage_type;\n    typedef typename conditional<_IsConst, typename _Cp::__const_storage_pointer,\n                                           typename _Cp::__storage_pointer>::type  __storage_pointer;\n    static const unsigned __bits_per_word = _Cp::__bits_per_word;\n\n    __storage_pointer __seg_;\n    unsigned          __ctz_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT\n#if _LIBCPP_STD_VER > 11\n    : __seg_(nullptr), __ctz_(0)\n#endif\n    {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT\n        : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}\n\n    _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT\n        {return reference(__seg_, __storage_type(1) << __ctz_);}\n\n    _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++()\n    {\n        if (__ctz_ != __bits_per_word-1)\n            ++__ctz_;\n        else\n        {\n            __ctz_ = 0;\n            ++__seg_;\n        }\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY __bit_iterator operator++(int)\n    {\n        __bit_iterator __tmp = *this;\n        ++(*this);\n        return __tmp;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator--()\n    {\n        if (__ctz_ != 0)\n            --__ctz_;\n        else\n        {\n            __ctz_ = __bits_per_word - 1;\n            --__seg_;\n        }\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY __bit_iterator operator--(int)\n    {\n        __bit_iterator __tmp = *this;\n        --(*this);\n        return __tmp;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator+=(difference_type __n)\n    {\n        if (__n >= 0)\n            __seg_ += (__n + __ctz_) / __bits_per_word;\n        else\n            __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1)\n                    / static_cast<difference_type>(__bits_per_word);\n        __n &= (__bits_per_word - 1);\n        __ctz_ = static_cast<unsigned>((__n + __ctz_)  % __bits_per_word);\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator-=(difference_type __n)\n    {\n        return *this += -__n;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY __bit_iterator operator+(difference_type __n) const\n    {\n        __bit_iterator __t(*this);\n        __t += __n;\n        return __t;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY __bit_iterator operator-(difference_type __n) const\n    {\n        __bit_iterator __t(*this);\n        __t -= __n;\n        return __t;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y)\n        {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;}\n\n    _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const {return *(*this + __n);}\n\n    _LIBCPP_INLINE_VISIBILITY friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y)\n        {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;}\n\n    _LIBCPP_INLINE_VISIBILITY friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y)\n        {return !(__x == __y);}\n\n    _LIBCPP_INLINE_VISIBILITY friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y)\n        {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);}\n\n    _LIBCPP_INLINE_VISIBILITY friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y)\n        {return __y < __x;}\n\n    _LIBCPP_INLINE_VISIBILITY friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y)\n        {return !(__y < __x);}\n\n    _LIBCPP_INLINE_VISIBILITY friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y)\n        {return !(__x < __y);}\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT\n        : __seg_(__s), __ctz_(__ctz) {}\n\n#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)\n    friend typename _Cp::__self;\n#else\n    friend class _Cp::__self;\n#endif\n    friend class __bit_reference<_Cp>;\n    friend class __bit_const_reference<_Cp>;\n    friend class __bit_iterator<_Cp, true>;\n    template <class _Dp> friend struct __bit_array;\n    template <class _Dp> friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);\n    template <class _Dp> friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);\n    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first,\n                                                                                  __bit_iterator<_Dp, _IC> __last,\n                                                                                  __bit_iterator<_Dp, false> __result);\n    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first,\n                                                                                    __bit_iterator<_Dp, _IC> __last,\n                                                                                    __bit_iterator<_Dp, false> __result);\n    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first,\n                                                                        __bit_iterator<_Dp, _IC> __last,\n                                                                        __bit_iterator<_Dp, false> __result);\n    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first,\n                                                                                           __bit_iterator<_Dp, _IC> __last,\n                                                                                           __bit_iterator<_Dp, false> __result);\n    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first,\n                                                                                             __bit_iterator<_Dp, _IC> __last,\n                                                                                             __bit_iterator<_Dp, false> __result);\n    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first,\n                                                                                 __bit_iterator<_Dp, _IC> __last,\n                                                                                 __bit_iterator<_Dp, false> __result);\n    template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>,\n                                                                                           __bit_iterator<__C1, false>,\n                                                                                           __bit_iterator<__C2, false>);\n    template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>,\n                                                                                             __bit_iterator<__C1, false>,\n                                                                                             __bit_iterator<__C2, false>);\n    template <class __C1, class __C2>friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>,\n                                                                                 __bit_iterator<__C1, false>,\n                                                                                 __bit_iterator<__C2, false>);\n    template <class _Dp> friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>,\n                                                                __bit_iterator<_Dp, false>,\n                                                                __bit_iterator<_Dp, false>);\n    template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>,\n                                                    __bit_iterator<_Dp, _IC1>,\n                                                    __bit_iterator<_Dp, _IC2>);\n    template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>,\n                                                      __bit_iterator<_Dp, _IC1>,\n                                                      __bit_iterator<_Dp, _IC2>);\n    template <class _Dp, bool _IC1, bool _IC2> friend bool equal(__bit_iterator<_Dp, _IC1>,\n                                                                __bit_iterator<_Dp, _IC1>,\n                                                                __bit_iterator<_Dp, _IC2>);\n    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>,\n                                                                          typename _Dp::size_type);\n    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>,\n                                                                           typename _Dp::size_type);\n    template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type\n                   __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);\n    template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type\n                   __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);\n};\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP___BIT_REFERENCE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__config",
    "content": "// -*- C++ -*-\n//===--------------------------- __config ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CONFIG\n#define _LIBCPP_CONFIG\n\n#if !defined(_MSC_VER) || defined(__clang__)\n#pragma GCC system_header\n#endif\n\n#ifdef __GNUC__\n#define _GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__)\n#else\n#define _GNUC_VER 0\n#endif\n\n#define _LIBCPP_VERSION 3800\n\n#define _LIBCPP_ABI_VERSION 1\n\n#define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y\n#define _LIBCPP_CONCAT(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y)\n\n#define _LIBCPP_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION)\n\n\n#ifndef __has_attribute\n#define __has_attribute(__x) 0\n#endif\n#ifndef __has_builtin\n#define __has_builtin(__x) 0\n#endif\n#ifndef __has_feature\n#define __has_feature(__x) 0\n#endif\n// '__is_identifier' returns '0' if '__x' is a reserved identifier provided by\n// the compiler and '1' otherwise.\n#ifndef __is_identifier\n#define __is_identifier(__x) 1\n#endif\n\n\n#ifdef __LITTLE_ENDIAN__\n#if __LITTLE_ENDIAN__\n#define _LIBCPP_LITTLE_ENDIAN 1\n#define _LIBCPP_BIG_ENDIAN    0\n#endif  // __LITTLE_ENDIAN__\n#endif  // __LITTLE_ENDIAN__\n\n#ifdef __BIG_ENDIAN__\n#if __BIG_ENDIAN__\n#define _LIBCPP_LITTLE_ENDIAN 0\n#define _LIBCPP_BIG_ENDIAN    1\n#endif  // __BIG_ENDIAN__\n#endif  // __BIG_ENDIAN__\n\n#ifdef __FreeBSD__\n# include <sys/endian.h>\n#  if _BYTE_ORDER == _LITTLE_ENDIAN\n#   define _LIBCPP_LITTLE_ENDIAN 1\n#   define _LIBCPP_BIG_ENDIAN    0\n# else  // _BYTE_ORDER == _LITTLE_ENDIAN\n#   define _LIBCPP_LITTLE_ENDIAN 0\n#   define _LIBCPP_BIG_ENDIAN    1\n# endif  // _BYTE_ORDER == _LITTLE_ENDIAN\n# ifndef __LONG_LONG_SUPPORTED\n#  define _LIBCPP_HAS_NO_LONG_LONG\n# endif  // __LONG_LONG_SUPPORTED\n#endif  // __FreeBSD__\n\n#ifdef __NetBSD__\n# include <sys/endian.h>\n#  if _BYTE_ORDER == _LITTLE_ENDIAN\n#   define _LIBCPP_LITTLE_ENDIAN 1\n#   define _LIBCPP_BIG_ENDIAN    0\n# else  // _BYTE_ORDER == _LITTLE_ENDIAN\n#   define _LIBCPP_LITTLE_ENDIAN 0\n#   define _LIBCPP_BIG_ENDIAN    1\n# endif  // _BYTE_ORDER == _LITTLE_ENDIAN\n# define _LIBCPP_HAS_QUICK_EXIT\n#endif  // __NetBSD__\n\n#ifdef _WIN32\n#  define _LIBCPP_LITTLE_ENDIAN 1\n#  define _LIBCPP_BIG_ENDIAN    0\n// Compiler intrinsics (MSVC)\n#if defined(_MSC_VER) && _MSC_VER >= 1400\n#    define _LIBCPP_HAS_IS_BASE_OF\n#  endif\n#  if defined(_MSC_VER) && !defined(__clang__)\n#    define _LIBCPP_MSVC // Using Microsoft Visual C++ compiler\n#    define _LIBCPP_TOSTRING2(x) #x\n#    define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)\n#    define _LIBCPP_WARNING(x) __pragma(message(__FILE__ \"(\" _LIBCPP_TOSTRING(__LINE__) \") : warning note: \" x))\n#  endif\n#  // If mingw not explicitly detected, assume using MS C runtime only.\n#  ifndef __MINGW32__\n#    define _LIBCPP_MSVCRT // Using Microsoft's C Runtime library\n#  endif\n#endif  // _WIN32\n\n#ifdef __sun__\n# include <sys/isa_defs.h>\n# ifdef _LITTLE_ENDIAN\n#   define _LIBCPP_LITTLE_ENDIAN 1\n#   define _LIBCPP_BIG_ENDIAN    0\n# else\n#   define _LIBCPP_LITTLE_ENDIAN 0\n#   define _LIBCPP_BIG_ENDIAN    1\n# endif\n#endif // __sun__\n\n#if defined(__CloudABI__)\n  // Certain architectures provide arc4random(). Prefer using\n  // arc4random() over /dev/{u,}random to make it possible to obtain\n  // random data even when using sandboxing mechanisms such as chroots,\n  // Capsicum, etc.\n# define _LIBCPP_USING_ARC4_RANDOM\n#elif defined(__native_client__)\n  // NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access,\n  // including accesses to the special files under /dev. C++11's\n  // std::random_device is instead exposed through a NaCl syscall.\n# define _LIBCPP_USING_NACL_RANDOM\n#elif defined(_WIN32)\n# define _LIBCPP_USING_WIN32_RANDOM\n#else\n# define _LIBCPP_USING_DEV_RANDOM\n#endif\n\n#if !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN)\n# include <endian.h>\n# if __BYTE_ORDER == __LITTLE_ENDIAN\n#  define _LIBCPP_LITTLE_ENDIAN 1\n#  define _LIBCPP_BIG_ENDIAN    0\n# elif __BYTE_ORDER == __BIG_ENDIAN\n#  define _LIBCPP_LITTLE_ENDIAN 0\n#  define _LIBCPP_BIG_ENDIAN    1\n# else  // __BYTE_ORDER == __BIG_ENDIAN\n#  error unable to determine endian\n# endif\n#endif  // !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN)\n\n#ifdef _WIN32\n\n// only really useful for a DLL\n#ifdef _LIBCPP_DLL // this should be a compiler builtin define ideally...\n# ifdef cxx_EXPORTS\n#  define _LIBCPP_HIDDEN\n#  define _LIBCPP_FUNC_VIS __declspec(dllexport)\n#  define _LIBCPP_TYPE_VIS __declspec(dllexport)\n# else\n#  define _LIBCPP_HIDDEN\n#  define _LIBCPP_FUNC_VIS __declspec(dllimport)\n#  define _LIBCPP_TYPE_VIS __declspec(dllimport)\n# endif\n#else\n# define _LIBCPP_HIDDEN\n# define _LIBCPP_FUNC_VIS\n# define _LIBCPP_TYPE_VIS\n#endif\n\n#define _LIBCPP_TYPE_VIS_ONLY\n#define _LIBCPP_FUNC_VIS_ONLY\n\n#ifndef _LIBCPP_INLINE_VISIBILITY\n# ifdef _LIBCPP_MSVC\n#  define _LIBCPP_INLINE_VISIBILITY __forceinline\n# else // MinGW GCC and Clang\n#  define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__always_inline__))\n# endif\n#endif\n\n#ifndef _LIBCPP_EXCEPTION_ABI\n#define _LIBCPP_EXCEPTION_ABI _LIBCPP_TYPE_VIS\n#endif\n\n#ifndef _LIBCPP_ALWAYS_INLINE\n# ifdef _LIBCPP_MSVC\n#  define _LIBCPP_ALWAYS_INLINE __forceinline\n# endif\n#endif\n\n#endif // _WIN32\n\n#ifndef _LIBCPP_HIDDEN\n#define _LIBCPP_HIDDEN __attribute__ ((__visibility__(\"hidden\")))\n#endif\n\n#ifndef _LIBCPP_FUNC_VIS\n#define _LIBCPP_FUNC_VIS __attribute__ ((__visibility__(\"default\")))\n#endif\n\n#ifndef _LIBCPP_TYPE_VIS\n#  if __has_attribute(__type_visibility__)\n#    define _LIBCPP_TYPE_VIS __attribute__ ((__type_visibility__(\"default\")))\n#  else\n#    define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__(\"default\")))\n#  endif\n#endif\n\n#ifndef _LIBCPP_TYPE_VIS_ONLY\n# define _LIBCPP_TYPE_VIS_ONLY _LIBCPP_TYPE_VIS\n#endif\n\n#ifndef _LIBCPP_FUNC_VIS_ONLY\n# define _LIBCPP_FUNC_VIS_ONLY _LIBCPP_FUNC_VIS\n#endif\n\n#ifndef _LIBCPP_INLINE_VISIBILITY\n#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__(\"hidden\"), __always_inline__))\n#endif\n\n#ifndef _LIBCPP_EXCEPTION_ABI\n#define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__(\"default\")))\n#endif\n\n#ifndef _LIBCPP_ALWAYS_INLINE\n#define _LIBCPP_ALWAYS_INLINE  __attribute__ ((__visibility__(\"hidden\"), __always_inline__))\n#endif\n\n#if defined(__clang__)\n\n#if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) &&        \\\n    !defined(__arm__)\n#define _LIBCPP_ALTERNATE_STRING_LAYOUT\n#endif\n\n#if __has_feature(cxx_alignas)\n#  define _ALIGNAS_TYPE(x) alignas(x)\n#  define _ALIGNAS(x) alignas(x)\n#else\n#  define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))\n#  define _ALIGNAS(x) __attribute__((__aligned__(x)))\n#endif\n\n#if !__has_feature(cxx_alias_templates)\n#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n#endif\n\n#if __cplusplus < 201103L\ntypedef __char16_t char16_t;\ntypedef __char32_t char32_t;\n#endif\n\n#if !(__has_feature(cxx_exceptions))\n#define _LIBCPP_NO_EXCEPTIONS\n#endif\n\n#if !(__has_feature(cxx_rtti))\n#define _LIBCPP_NO_RTTI\n#endif\n\n#if !(__has_feature(cxx_strong_enums))\n#define _LIBCPP_HAS_NO_STRONG_ENUMS\n#endif\n\n#if !(__has_feature(cxx_decltype))\n#define _LIBCPP_HAS_NO_DECLTYPE\n#endif\n\n#if __has_feature(cxx_attributes)\n#  define _LIBCPP_NORETURN [[noreturn]]\n#else\n#  define _LIBCPP_NORETURN __attribute__ ((noreturn))\n#endif\n\n#define _LIBCPP_UNUSED __attribute__((__unused__))\n\n#if !(__has_feature(cxx_defaulted_functions))\n#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n#endif  // !(__has_feature(cxx_defaulted_functions))\n\n#if !(__has_feature(cxx_deleted_functions))\n#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n#endif  // !(__has_feature(cxx_deleted_functions))\n\n#if !(__has_feature(cxx_lambdas))\n#define _LIBCPP_HAS_NO_LAMBDAS\n#endif\n\n#if !(__has_feature(cxx_nullptr))\n#define _LIBCPP_HAS_NO_NULLPTR\n#endif\n\n#if !(__has_feature(cxx_rvalue_references))\n#define _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#endif\n\n#if !(__has_feature(cxx_static_assert))\n#define _LIBCPP_HAS_NO_STATIC_ASSERT\n#endif\n\n#if !(__has_feature(cxx_auto_type))\n#define _LIBCPP_HAS_NO_AUTO_TYPE\n#endif\n\n#if !(__has_feature(cxx_access_control_sfinae)) || !__has_feature(cxx_trailing_return)\n#define _LIBCPP_HAS_NO_ADVANCED_SFINAE\n#endif\n\n#if !(__has_feature(cxx_variadic_templates))\n#define _LIBCPP_HAS_NO_VARIADICS\n#endif\n\n#if !(__has_feature(cxx_trailing_return))\n#define _LIBCPP_HAS_NO_TRAILING_RETURN\n#endif\n\n#if !(__has_feature(cxx_generalized_initializers))\n#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n#endif\n\n#if __has_feature(is_base_of)\n#  define _LIBCPP_HAS_IS_BASE_OF\n#endif\n\n#if __has_feature(is_final)\n#  define _LIBCPP_HAS_IS_FINAL\n#endif\n\n// Objective-C++ features (opt-in)\n#if __has_feature(objc_arc)\n#define _LIBCPP_HAS_OBJC_ARC\n#endif\n\n#if __has_feature(objc_arc_weak)\n#define _LIBCPP_HAS_OBJC_ARC_WEAK\n#define _LIBCPP_HAS_NO_STRONG_ENUMS\n#endif\n\n#if !(__has_feature(cxx_constexpr))\n#define _LIBCPP_HAS_NO_CONSTEXPR\n#endif\n\n#if !(__has_feature(cxx_relaxed_constexpr))\n#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR\n#endif\n\n#if !(__has_feature(cxx_variable_templates))\n#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES\n#endif\n\n#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L\n#if defined(__FreeBSD__)\n#define _LIBCPP_HAS_QUICK_EXIT\n#define _LIBCPP_HAS_C11_FEATURES\n#elif defined(__ANDROID__)\n#define _LIBCPP_HAS_QUICK_EXIT\n#elif defined(__linux__)\n#include <features.h>\n#if __GLIBC_PREREQ(2, 15)\n#define _LIBCPP_HAS_QUICK_EXIT\n#endif\n#if __GLIBC_PREREQ(2, 17)\n#define _LIBCPP_HAS_C11_FEATURES\n#endif\n#endif\n#endif\n\n#if (__has_feature(cxx_noexcept))\n#  define _NOEXCEPT noexcept\n#  define _NOEXCEPT_(x) noexcept(x)\n#  define _NOEXCEPT_OR_FALSE(x) noexcept(x)\n#else\n#  define _NOEXCEPT throw()\n#  define _NOEXCEPT_(x)\n#  define _NOEXCEPT_OR_FALSE(x) false\n#endif\n\n#if __has_feature(underlying_type)\n#  define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T)\n#endif\n\n#if __has_feature(is_literal)\n#  define _LIBCPP_IS_LITERAL(T) __is_literal(T)\n#endif\n\n// Inline namespaces are available in Clang regardless of C++ dialect.\n#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE {\n#define _LIBCPP_END_NAMESPACE_STD  } }\n#define _VSTD std::_LIBCPP_NAMESPACE\n\nnamespace std {\n  inline namespace _LIBCPP_NAMESPACE {\n  }\n}\n\n#if !defined(_LIBCPP_HAS_NO_ASAN) && !__has_feature(address_sanitizer)\n#define _LIBCPP_HAS_NO_ASAN\n#endif\n\n#elif defined(__GNUC__)\n\n#define _ALIGNAS(x) __attribute__((__aligned__(x)))\n#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))\n\n#define _LIBCPP_NORETURN __attribute__((noreturn))\n\n#define _LIBCPP_UNUSED __attribute__((__unused__))\n\n#if _GNUC_VER >= 407\n#define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T)\n#define _LIBCPP_IS_LITERAL(T) __is_literal_type(T)\n#define _LIBCPP_HAS_IS_FINAL\n#endif\n\n#if defined(__GNUC__) && _GNUC_VER >= 403\n#  define _LIBCPP_HAS_IS_BASE_OF\n#endif\n\n#if !__EXCEPTIONS\n#define _LIBCPP_NO_EXCEPTIONS\n#endif\n\n#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\n// constexpr was added to GCC in 4.6.\n#if _GNUC_VER < 406\n#define _LIBCPP_HAS_NO_CONSTEXPR\n// Can only use constexpr in c++11 mode.\n#elif !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L\n#define _LIBCPP_HAS_NO_CONSTEXPR\n#endif\n\n// No version of GCC supports relaxed constexpr rules\n#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR\n// GCC 5 will support variable templates\n#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES\n\n#define _NOEXCEPT throw()\n#define _NOEXCEPT_(x)\n#define _NOEXCEPT_OR_FALSE(x) false\n\n#ifndef __GXX_EXPERIMENTAL_CXX0X__\n\n#define _LIBCPP_HAS_NO_ADVANCED_SFINAE\n#define _LIBCPP_HAS_NO_DECLTYPE\n#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n#define _LIBCPP_HAS_NO_NULLPTR\n#define _LIBCPP_HAS_NO_STATIC_ASSERT\n#define _LIBCPP_HAS_NO_UNICODE_CHARS\n#define _LIBCPP_HAS_NO_VARIADICS\n#define _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS\n#define _LIBCPP_HAS_NO_STRONG_ENUMS\n\n#else  // __GXX_EXPERIMENTAL_CXX0X__\n\n#define _LIBCPP_HAS_NO_TRAILING_RETURN\n#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS\n\n#if _GNUC_VER < 403\n#define _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#endif\n\n#if _GNUC_VER < 403\n#define _LIBCPP_HAS_NO_STATIC_ASSERT\n#endif\n\n#if _GNUC_VER < 404\n#define _LIBCPP_HAS_NO_DECLTYPE\n#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n#define _LIBCPP_HAS_NO_UNICODE_CHARS\n#define _LIBCPP_HAS_NO_VARIADICS\n#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n#endif  // _GNUC_VER < 404\n\n#if _GNUC_VER < 406\n#define _LIBCPP_HAS_NO_NULLPTR\n#endif\n\n#if _GNUC_VER < 407\n#define _LIBCPP_HAS_NO_ADVANCED_SFINAE\n#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n#endif\n\n#endif  // __GXX_EXPERIMENTAL_CXX0X__\n\n#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { namespace _LIBCPP_NAMESPACE {\n#define _LIBCPP_END_NAMESPACE_STD  } }\n#define _VSTD std::_LIBCPP_NAMESPACE\n\nnamespace std {\nnamespace _LIBCPP_NAMESPACE {\n}\nusing namespace _LIBCPP_NAMESPACE __attribute__((__strong__));\n}\n\n#if !defined(_LIBCPP_HAS_NO_ASAN) && !defined(__SANITIZE_ADDRESS__)\n#define _LIBCPP_HAS_NO_ASAN\n#endif\n\n#elif defined(_LIBCPP_MSVC)\n\n#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n#define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER\n#define _LIBCPP_HAS_NO_CONSTEXPR\n#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR\n#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES\n#define _LIBCPP_HAS_NO_UNICODE_CHARS\n#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n#define __alignof__ __alignof\n#define _LIBCPP_NORETURN __declspec(noreturn)\n#define _LIBCPP_UNUSED\n#define _ALIGNAS(x) __declspec(align(x))\n#define _LIBCPP_HAS_NO_VARIADICS\n\n#define _NOEXCEPT throw ()\n#define _NOEXCEPT_(x)\n#define _NOEXCEPT_OR_FALSE(x) false\n\n#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {\n#define _LIBCPP_END_NAMESPACE_STD  }\n#define _VSTD std\n\n#  define _LIBCPP_WEAK\nnamespace std {\n}\n\n#define _LIBCPP_HAS_NO_ASAN\n\n#elif defined(__IBMCPP__)\n\n#define _ALIGNAS(x) __attribute__((__aligned__(x)))\n#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))\n#define _ATTRIBUTE(x) __attribute__((x))\n#define _LIBCPP_NORETURN __attribute__((noreturn))\n#define _LIBCPP_UNUSED\n\n#define _NOEXCEPT throw()\n#define _NOEXCEPT_(x)\n#define _NOEXCEPT_OR_FALSE(x) false\n\n#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n#define _LIBCPP_HAS_NO_ADVANCED_SFINAE\n#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS\n#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n#define _LIBCPP_HAS_NO_NULLPTR\n#define _LIBCPP_HAS_NO_UNICODE_CHARS\n#define _LIBCPP_HAS_IS_BASE_OF\n#define _LIBCPP_HAS_IS_FINAL\n#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES\n\n#if defined(_AIX)\n#define __MULTILOCALE_API\n#endif\n\n#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE {\n#define _LIBCPP_END_NAMESPACE_STD  } }\n#define _VSTD std::_LIBCPP_NAMESPACE\n\nnamespace std {\n  inline namespace _LIBCPP_NAMESPACE {\n  }\n}\n\n#define _LIBCPP_HAS_NO_ASAN\n\n#endif // __clang__ || __GNUC__ || _MSC_VER || __IBMCPP__\n\n#ifdef _LIBCPP_HAS_NO_UNICODE_CHARS\ntypedef unsigned short char16_t;\ntypedef unsigned int   char32_t;\n#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS\n\n#ifndef __SIZEOF_INT128__\n#define _LIBCPP_HAS_NO_INT128\n#endif\n\n#ifdef _LIBCPP_HAS_NO_STATIC_ASSERT\n\ntemplate <bool> struct __static_assert_test;\ntemplate <> struct __static_assert_test<true> {};\ntemplate <unsigned> struct __static_assert_check {};\n#define static_assert(__b, __m) \\\n    typedef __static_assert_check<sizeof(__static_assert_test<(__b)>)> \\\n    _LIBCPP_CONCAT(__t, __LINE__)\n\n#endif  // _LIBCPP_HAS_NO_STATIC_ASSERT\n\n#ifdef _LIBCPP_HAS_NO_DECLTYPE\n// GCC 4.6 provides __decltype in all standard modes.\n#if !__is_identifier(__decltype) || _GNUC_VER >= 406\n#  define decltype(__x) __decltype(__x)\n#else\n#  define decltype(__x) __typeof__(__x)\n#endif\n#endif\n\n#ifdef _LIBCPP_HAS_NO_CONSTEXPR\n#define _LIBCPP_CONSTEXPR\n#else\n#define _LIBCPP_CONSTEXPR constexpr\n#endif\n\n#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n#define _LIBCPP_DEFAULT {}\n#else\n#define _LIBCPP_DEFAULT = default;\n#endif\n\n#ifdef __GNUC__\n#define _NOALIAS __attribute__((__malloc__))\n#else\n#define _NOALIAS\n#endif\n\n#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__)\n#   define _LIBCPP_EXPLICIT explicit\n#else\n#   define _LIBCPP_EXPLICIT\n#endif\n\n#if !__has_builtin(__builtin_operator_new) || !__has_builtin(__builtin_operator_delete)\n#   define _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE\n#endif\n\n#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS\n#define _LIBCPP_DECLARE_STRONG_ENUM(x) struct _LIBCPP_TYPE_VIS x { enum __lx\n#define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \\\n    __lx __v_; \\\n    _LIBCPP_ALWAYS_INLINE x(__lx __v) : __v_(__v) {} \\\n    _LIBCPP_ALWAYS_INLINE explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \\\n    _LIBCPP_ALWAYS_INLINE operator int() const {return __v_;} \\\n    };\n#else  // _LIBCPP_HAS_NO_STRONG_ENUMS\n#define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_TYPE_VIS x\n#define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x)\n#endif  // _LIBCPP_HAS_NO_STRONG_ENUMS\n\n#ifdef _LIBCPP_DEBUG\n#   if _LIBCPP_DEBUG == 0\n#       define _LIBCPP_DEBUG_LEVEL 1\n#   elif _LIBCPP_DEBUG == 1\n#       define _LIBCPP_DEBUG_LEVEL 2\n#   else\n#       error Supported values for _LIBCPP_DEBUG are 0 and 1\n#   endif\n#   define _LIBCPP_EXTERN_TEMPLATE(...)\n#endif\n\n#ifndef _LIBCPP_EXTERN_TEMPLATE\n#define _LIBCPP_EXTERN_TEMPLATE(...)\n#endif\n\n#ifndef _LIBCPP_EXTERN_TEMPLATE2\n#define _LIBCPP_EXTERN_TEMPLATE2(...) extern template __VA_ARGS__;\n#endif\n\n#if defined(__APPLE__) && defined(__LP64__) && !defined(__x86_64__)\n#define _LIBCPP_NONUNIQUE_RTTI_BIT (1ULL << 63)\n#endif\n\n#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || \\\n    defined(__sun__) || defined(__NetBSD__) || defined(__CloudABI__)\n#define _LIBCPP_LOCALE__L_EXTENSIONS 1\n#endif\n\n#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(_NEWLIB_VERSION) && \\\n    !defined(__CloudABI__)\n#define _LIBCPP_HAS_CATOPEN 1\n#endif\n\n#ifdef __FreeBSD__\n#define _DECLARE_C99_LDBL_MATH 1\n#endif\n\n#if defined(__APPLE__) || defined(__FreeBSD__)\n#define _LIBCPP_HAS_DEFAULTRUNELOCALE\n#endif\n\n#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__)\n#define _LIBCPP_WCTYPE_IS_MASK\n#endif\n\n#ifndef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR\n#  define _LIBCPP_TRIVIAL_PAIR_COPY_CTOR 1\n#endif\n\n#ifndef _LIBCPP_STD_VER\n#  if  __cplusplus <= 201103L\n#    define _LIBCPP_STD_VER 11\n#  elif __cplusplus <= 201402L\n#    define _LIBCPP_STD_VER 14\n#  else\n#    define _LIBCPP_STD_VER 15  // current year, or date of c++17 ratification\n#  endif\n#endif  // _LIBCPP_STD_VER\n\n#if _LIBCPP_STD_VER > 11\n#define _LIBCPP_DEPRECATED [[deprecated]]\n#else\n#define _LIBCPP_DEPRECATED\n#endif\n\n#if _LIBCPP_STD_VER <= 11\n#define _LIBCPP_EXPLICIT_AFTER_CXX11\n#define _LIBCPP_DEPRECATED_AFTER_CXX11\n#else\n#define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit\n#define _LIBCPP_DEPRECATED_AFTER_CXX11 [[deprecated]]\n#endif\n\n#if _LIBCPP_STD_VER > 11 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR)\n#define _LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr\n#else\n#define _LIBCPP_CONSTEXPR_AFTER_CXX11\n#endif\n\n#ifndef _LIBCPP_HAS_NO_ASAN\nextern \"C\" void __sanitizer_annotate_contiguous_container(\n  const void *, const void *, const void *, const void *);\n#endif\n\n// Try to find out if RTTI is disabled.\n// g++ and cl.exe have RTTI on by default and define a macro when it is.\n// g++ only defines the macro in 4.3.2 and onwards.\n#if !defined(_LIBCPP_NO_RTTI)\n#  if defined(__GNUG__) && ((__GNUC__ >= 5) || (__GNUC__ == 4 && \\\n   (__GNUC_MINOR__ >= 3 || __GNUC_PATCHLEVEL__ >= 2))) && !defined(__GXX_RTTI)\n#    define _LIBCPP_NO_RTTI\n#  elif (defined(_MSC_VER) && !defined(__clang__)) && !defined(_CPPRTTI)\n#    define _LIBCPP_NO_RTTI\n#  endif\n#endif\n\n#ifndef _LIBCPP_WEAK\n#  define _LIBCPP_WEAK __attribute__((__weak__))\n#endif\n\n#if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(_LIBCPP_HAS_NO_THREADS)\n#  error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \\\n         _LIBCPP_HAS_NO_THREADS is defined.\n#endif\n\n// Systems that use capability-based security (FreeBSD with Capsicum,\n// Nuxi CloudABI) may only provide local filesystem access (using *at()).\n// Functions like open(), rename(), unlink() and stat() should not be\n// used, as they attempt to access the global filesystem namespace.\n#ifdef __CloudABI__\n#define _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\n#endif\n\n// CloudABI is intended for running networked services. Processes do not\n// have standard input and output channels.\n#ifdef __CloudABI__\n#define _LIBCPP_HAS_NO_STDIN\n#define _LIBCPP_HAS_NO_STDOUT\n#endif\n\n#if defined(__ANDROID__) || defined(__CloudABI__)\n#define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE\n#endif\n\n// Thread-unsafe functions such as strtok(), mbtowc() and localtime()\n// are not available.\n#ifdef __CloudABI__\n#define _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS\n#endif\n\n#endif  // _LIBCPP_CONFIG\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__debug",
    "content": "// -*- C++ -*-\n//===--------------------------- __debug ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_DEBUG_H\n#define _LIBCPP_DEBUG_H\n\n#include <__config>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#if _LIBCPP_DEBUG_LEVEL >= 1\n#   include <cstdlib>\n#   include <cstdio>\n#   include <cstddef>\n#   ifndef _LIBCPP_ASSERT\n#      define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (_VSTD::fprintf(stderr, \"%s\\n\", m), _VSTD::abort()))\n#   endif\n#endif\n\n#ifndef _LIBCPP_ASSERT\n#   define _LIBCPP_ASSERT(x, m) ((void)0)\n#endif\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nstruct _LIBCPP_TYPE_VIS __c_node;\n\nstruct _LIBCPP_TYPE_VIS __i_node\n{\n    void* __i_;\n    __i_node* __next_;\n    __c_node* __c_;\n\n#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n    __i_node(const __i_node&) = delete;\n    __i_node& operator=(const __i_node&) = delete;\n#else\nprivate:\n    __i_node(const __i_node&);\n    __i_node& operator=(const __i_node&);\npublic:\n#endif\n    _LIBCPP_INLINE_VISIBILITY\n    __i_node(void* __i, __i_node* __next, __c_node* __c)\n        : __i_(__i), __next_(__next), __c_(__c) {}\n    ~__i_node();\n};\n\nstruct _LIBCPP_TYPE_VIS __c_node\n{\n    void* __c_;\n    __c_node* __next_;\n    __i_node** beg_;\n    __i_node** end_;\n    __i_node** cap_;\n\n#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n    __c_node(const __c_node&) = delete;\n    __c_node& operator=(const __c_node&) = delete;\n#else\nprivate:\n    __c_node(const __c_node&);\n    __c_node& operator=(const __c_node&);\npublic:\n#endif\n    _LIBCPP_INLINE_VISIBILITY\n    __c_node(void* __c, __c_node* __next)\n        : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {}\n    virtual ~__c_node();\n\n    virtual bool __dereferenceable(const void*) const = 0;\n    virtual bool __decrementable(const void*) const = 0;\n    virtual bool __addable(const void*, ptrdiff_t) const = 0;\n    virtual bool __subscriptable(const void*, ptrdiff_t) const = 0;\n\n    void __add(__i_node* __i);\n    _LIBCPP_HIDDEN void __remove(__i_node* __i);\n};\n\ntemplate <class _Cont>\nstruct _C_node\n    : public __c_node\n{\n    _C_node(void* __c, __c_node* __n)\n        : __c_node(__c, __n) {}\n\n    virtual bool __dereferenceable(const void*) const;\n    virtual bool __decrementable(const void*) const;\n    virtual bool __addable(const void*, ptrdiff_t) const;\n    virtual bool __subscriptable(const void*, ptrdiff_t) const;\n};\n\ntemplate <class _Cont>\nbool\n_C_node<_Cont>::__dereferenceable(const void* __i) const\n{\n    typedef typename _Cont::const_iterator iterator;\n    const iterator* __j = static_cast<const iterator*>(__i);\n    _Cont* _Cp = static_cast<_Cont*>(__c_);\n    return _Cp->__dereferenceable(__j);\n}\n\ntemplate <class _Cont>\nbool\n_C_node<_Cont>::__decrementable(const void* __i) const\n{\n    typedef typename _Cont::const_iterator iterator;\n    const iterator* __j = static_cast<const iterator*>(__i);\n    _Cont* _Cp = static_cast<_Cont*>(__c_);\n    return _Cp->__decrementable(__j);\n}\n\ntemplate <class _Cont>\nbool\n_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const\n{\n    typedef typename _Cont::const_iterator iterator;\n    const iterator* __j = static_cast<const iterator*>(__i);\n    _Cont* _Cp = static_cast<_Cont*>(__c_);\n    return _Cp->__addable(__j, __n);\n}\n\ntemplate <class _Cont>\nbool\n_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const\n{\n    typedef typename _Cont::const_iterator iterator;\n    const iterator* __j = static_cast<const iterator*>(__i);\n    _Cont* _Cp = static_cast<_Cont*>(__c_);\n    return _Cp->__subscriptable(__j, __n);\n}\n\nclass _LIBCPP_TYPE_VIS __libcpp_db\n{\n    __c_node** __cbeg_;\n    __c_node** __cend_;\n    size_t   __csz_;\n    __i_node** __ibeg_;\n    __i_node** __iend_;\n    size_t   __isz_;\n\n    __libcpp_db();\npublic:\n#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n    __libcpp_db(const __libcpp_db&) = delete;\n    __libcpp_db& operator=(const __libcpp_db&) = delete;\n#else\nprivate:\n    __libcpp_db(const __libcpp_db&);\n    __libcpp_db& operator=(const __libcpp_db&);\npublic:\n#endif\n    ~__libcpp_db();\n\n    class __db_c_iterator;\n    class __db_c_const_iterator;\n    class __db_i_iterator;\n    class __db_i_const_iterator;\n\n    __db_c_const_iterator __c_end() const;\n    __db_i_const_iterator __i_end() const;\n\n    template <class _Cont>\n    _LIBCPP_INLINE_VISIBILITY\n    void __insert_c(_Cont* __c)\n    {\n        __c_node* __n = __insert_c(static_cast<void*>(__c));\n        ::new(__n) _C_node<_Cont>(__n->__c_, __n->__next_);\n    }\n\n    void __insert_i(void* __i);\n    __c_node* __insert_c(void* __c);\n    void __erase_c(void* __c);\n\n    void __insert_ic(void* __i, const void* __c);\n    void __iterator_copy(void* __i, const void* __i0);\n    void __erase_i(void* __i);\n\n    void* __find_c_from_i(void* __i) const;\n    void __invalidate_all(void* __c);\n    __c_node* __find_c_and_lock(void* __c) const;\n    __c_node* __find_c(void* __c) const;\n    void unlock() const;\n\n    void swap(void* __c1, void* __c2);\n\n\n    bool __dereferenceable(const void* __i) const;\n    bool __decrementable(const void* __i) const;\n    bool __addable(const void* __i, ptrdiff_t __n) const;\n    bool __subscriptable(const void* __i, ptrdiff_t __n) const;\n    bool __less_than_comparable(const void* __i, const void* __j) const;\nprivate:\n    _LIBCPP_HIDDEN\n    __i_node* __insert_iterator(void* __i);\n    _LIBCPP_HIDDEN\n    __i_node* __find_iterator(const void* __i) const;\n\n    friend _LIBCPP_FUNC_VIS __libcpp_db* __get_db();\n};\n\n_LIBCPP_FUNC_VIS __libcpp_db* __get_db();\n_LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db();\n\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif\n\n#endif  // _LIBCPP_DEBUG_H\n\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__functional_03",
    "content": "// -*- C++ -*-\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_FUNCTIONAL_03\n#define _LIBCPP_FUNCTIONAL_03\n\n// manual variadic expansion for <functional>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\nnamespace __function {\n\ntemplate<class _Fp> class __base;\n\ntemplate<class _Rp>\nclass __base<_Rp()>\n{\n    __base(const __base&);\n    __base& operator=(const __base&);\npublic:\n    __base() {}\n    virtual ~__base() {}\n    virtual __base* __clone() const = 0;\n    virtual void __clone(__base*) const = 0;\n    virtual void destroy() = 0;\n    virtual void destroy_deallocate() = 0;\n    virtual _Rp operator()() = 0;\n#ifndef _LIBCPP_NO_RTTI\n    virtual const void* target(const type_info&) const = 0;\n    virtual const std::type_info& target_type() const = 0;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _Rp, class _A0>\nclass __base<_Rp(_A0)>\n{\n    __base(const __base&);\n    __base& operator=(const __base&);\npublic:\n    __base() {}\n    virtual ~__base() {}\n    virtual __base* __clone() const = 0;\n    virtual void __clone(__base*) const = 0;\n    virtual void destroy() = 0;\n    virtual void destroy_deallocate() = 0;\n    virtual _Rp operator()(_A0) = 0;\n#ifndef _LIBCPP_NO_RTTI\n    virtual const void* target(const type_info&) const = 0;\n    virtual const std::type_info& target_type() const = 0;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _Rp, class _A0, class _A1>\nclass __base<_Rp(_A0, _A1)>\n{\n    __base(const __base&);\n    __base& operator=(const __base&);\npublic:\n    __base() {}\n    virtual ~__base() {}\n    virtual __base* __clone() const = 0;\n    virtual void __clone(__base*) const = 0;\n    virtual void destroy() = 0;\n    virtual void destroy_deallocate() = 0;\n    virtual _Rp operator()(_A0, _A1) = 0;\n#ifndef _LIBCPP_NO_RTTI\n    virtual const void* target(const type_info&) const = 0;\n    virtual const std::type_info& target_type() const = 0;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\nclass __base<_Rp(_A0, _A1, _A2)>\n{\n    __base(const __base&);\n    __base& operator=(const __base&);\npublic:\n    __base() {}\n    virtual ~__base() {}\n    virtual __base* __clone() const = 0;\n    virtual void __clone(__base*) const = 0;\n    virtual void destroy() = 0;\n    virtual void destroy_deallocate() = 0;\n    virtual _Rp operator()(_A0, _A1, _A2) = 0;\n#ifndef _LIBCPP_NO_RTTI\n    virtual const void* target(const type_info&) const = 0;\n    virtual const std::type_info& target_type() const = 0;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _FD, class _Alloc, class _FB> class __func;\n\ntemplate<class _Fp, class _Alloc, class _Rp>\nclass __func<_Fp, _Alloc, _Rp()>\n    : public  __base<_Rp()>\n{\n    __compressed_pair<_Fp, _Alloc> __f_;\npublic:\n    explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}\n    explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}\n    virtual __base<_Rp()>* __clone() const;\n    virtual void __clone(__base<_Rp()>*) const;\n    virtual void destroy();\n    virtual void destroy_deallocate();\n    virtual _Rp operator()();\n#ifndef _LIBCPP_NO_RTTI\n    virtual const void* target(const type_info&) const;\n    virtual const std::type_info& target_type() const;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _Fp, class _Alloc, class _Rp>\n__base<_Rp()>*\n__func<_Fp, _Alloc, _Rp()>::__clone() const\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;\n    _Ap __a(__f_.second());\n    typedef __allocator_destructor<_Ap> _Dp;\n    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));\n    return __hold.release();\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp>\nvoid\n__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const\n{\n    ::new (__p) __func(__f_.first(), __f_.second());\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp>\nvoid\n__func<_Fp, _Alloc, _Rp()>::destroy()\n{\n    __f_.~__compressed_pair<_Fp, _Alloc>();\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp>\nvoid\n__func<_Fp, _Alloc, _Rp()>::destroy_deallocate()\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;\n    _Ap __a(__f_.second());\n    __f_.~__compressed_pair<_Fp, _Alloc>();\n    __a.deallocate(this, 1);\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp>\n_Rp\n__func<_Fp, _Alloc, _Rp()>::operator()()\n{\n    typedef __invoke_void_return_wrapper<_Rp> _Invoker;\n    return _Invoker::__call(__f_.first());\n}\n\n#ifndef _LIBCPP_NO_RTTI\n\ntemplate<class _Fp, class _Alloc, class _Rp>\nconst void*\n__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const\n{\n    if (__ti == typeid(_Fp))\n        return &__f_.first();\n    return (const void*)0;\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp>\nconst std::type_info&\n__func<_Fp, _Alloc, _Rp()>::target_type() const\n{\n    return typeid(_Fp);\n}\n\n#endif  // _LIBCPP_NO_RTTI\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0>\nclass __func<_Fp, _Alloc, _Rp(_A0)>\n    : public  __base<_Rp(_A0)>\n{\n    __compressed_pair<_Fp, _Alloc> __f_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}\n    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)\n        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}\n    virtual __base<_Rp(_A0)>* __clone() const;\n    virtual void __clone(__base<_Rp(_A0)>*) const;\n    virtual void destroy();\n    virtual void destroy_deallocate();\n    virtual _Rp operator()(_A0);\n#ifndef _LIBCPP_NO_RTTI\n    virtual const void* target(const type_info&) const;\n    virtual const std::type_info& target_type() const;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0>\n__base<_Rp(_A0)>*\n__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;\n    _Ap __a(__f_.second());\n    typedef __allocator_destructor<_Ap> _Dp;\n    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));\n    return __hold.release();\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0>\nvoid\n__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const\n{\n    ::new (__p) __func(__f_.first(), __f_.second());\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0>\nvoid\n__func<_Fp, _Alloc, _Rp(_A0)>::destroy()\n{\n    __f_.~__compressed_pair<_Fp, _Alloc>();\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0>\nvoid\n__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;\n    _Ap __a(__f_.second());\n    __f_.~__compressed_pair<_Fp, _Alloc>();\n    __a.deallocate(this, 1);\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0>\n_Rp\n__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0)\n{\n    typedef __invoke_void_return_wrapper<_Rp> _Invoker;\n    return _Invoker::__call(__f_.first(), __a0);\n}\n\n#ifndef _LIBCPP_NO_RTTI\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0>\nconst void*\n__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const\n{\n    if (__ti == typeid(_Fp))\n        return &__f_.first();\n    return (const void*)0;\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0>\nconst std::type_info&\n__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const\n{\n    return typeid(_Fp);\n}\n\n#endif  // _LIBCPP_NO_RTTI\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>\nclass __func<_Fp, _Alloc, _Rp(_A0, _A1)>\n    : public  __base<_Rp(_A0, _A1)>\n{\n    __compressed_pair<_Fp, _Alloc> __f_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}\n    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)\n        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}\n    virtual __base<_Rp(_A0, _A1)>* __clone() const;\n    virtual void __clone(__base<_Rp(_A0, _A1)>*) const;\n    virtual void destroy();\n    virtual void destroy_deallocate();\n    virtual _Rp operator()(_A0, _A1);\n#ifndef _LIBCPP_NO_RTTI\n    virtual const void* target(const type_info&) const;\n    virtual const std::type_info& target_type() const;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>\n__base<_Rp(_A0, _A1)>*\n__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;\n    _Ap __a(__f_.second());\n    typedef __allocator_destructor<_Ap> _Dp;\n    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));\n    return __hold.release();\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>\nvoid\n__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const\n{\n    ::new (__p) __func(__f_.first(), __f_.second());\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>\nvoid\n__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy()\n{\n    __f_.~__compressed_pair<_Fp, _Alloc>();\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>\nvoid\n__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;\n    _Ap __a(__f_.second());\n    __f_.~__compressed_pair<_Fp, _Alloc>();\n    __a.deallocate(this, 1);\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>\n_Rp\n__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1)\n{\n    typedef __invoke_void_return_wrapper<_Rp> _Invoker;\n    return _Invoker::__call(__f_.first(), __a0, __a1);\n}\n\n#ifndef _LIBCPP_NO_RTTI\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>\nconst void*\n__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const\n{\n    if (__ti == typeid(_Fp))\n        return &__f_.first();\n    return (const void*)0;\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>\nconst std::type_info&\n__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const\n{\n    return typeid(_Fp);\n}\n\n#endif  // _LIBCPP_NO_RTTI\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>\nclass __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>\n    : public  __base<_Rp(_A0, _A1, _A2)>\n{\n    __compressed_pair<_Fp, _Alloc> __f_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}\n    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)\n        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}\n    virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const;\n    virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const;\n    virtual void destroy();\n    virtual void destroy_deallocate();\n    virtual _Rp operator()(_A0, _A1, _A2);\n#ifndef _LIBCPP_NO_RTTI\n    virtual const void* target(const type_info&) const;\n    virtual const std::type_info& target_type() const;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>\n__base<_Rp(_A0, _A1, _A2)>*\n__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;\n    _Ap __a(__f_.second());\n    typedef __allocator_destructor<_Ap> _Dp;\n    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));\n    return __hold.release();\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>\nvoid\n__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const\n{\n    ::new (__p) __func(__f_.first(), __f_.second());\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>\nvoid\n__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy()\n{\n    __f_.~__compressed_pair<_Fp, _Alloc>();\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>\nvoid\n__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;\n    _Ap __a(__f_.second());\n    __f_.~__compressed_pair<_Fp, _Alloc>();\n    __a.deallocate(this, 1);\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>\n_Rp\n__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2)\n{\n    typedef __invoke_void_return_wrapper<_Rp> _Invoker;\n    return _Invoker::__call(__f_.first(), __a0, __a1, __a2);\n}\n\n#ifndef _LIBCPP_NO_RTTI\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>\nconst void*\n__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const\n{\n    if (__ti == typeid(_Fp))\n        return &__f_.first();\n    return (const void*)0;\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>\nconst std::type_info&\n__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const\n{\n    return typeid(_Fp);\n}\n\n#endif  // _LIBCPP_NO_RTTI\n\n}  // __function\n\ntemplate<class _Rp>\nclass _LIBCPP_TYPE_VIS_ONLY function<_Rp()>\n{\n    typedef __function::__base<_Rp()> __base;\n    aligned_storage<3*sizeof(void*)>::type __buf_;\n    __base* __f_;\n\n    template <class _Fp>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(const _Fp&) {return true;}\n    template <class _R2>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (*__p)()) {return __p;}\n    template <class _R2>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(const function<_R2()>& __p) {return __p;}\npublic:\n    typedef _Rp result_type;\n\n    // 20.7.16.2.1, construct/copy/destroy:\n    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}\n    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}\n    function(const function&);\n    template<class _Fp>\n      function(_Fp,\n               typename enable_if<!is_integral<_Fp>::value>::type* = 0);\n\n    template<class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      function(allocator_arg_t, const _Alloc&) : __f_(0) {}\n    template<class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}\n    template<class _Alloc>\n      function(allocator_arg_t, const _Alloc&, const function&);\n    template<class _Fp, class _Alloc>\n      function(allocator_arg_t, const _Alloc& __a, _Fp __f,\n               typename enable_if<!is_integral<_Fp>::value>::type* = 0);\n\n    function& operator=(const function&);\n    function& operator=(nullptr_t);\n    template<class _Fp>\n      typename enable_if\n      <\n        !is_integral<_Fp>::value,\n        function&\n      >::type\n      operator=(_Fp);\n\n    ~function();\n\n    // 20.7.16.2.2, function modifiers:\n    void swap(function&);\n    template<class _Fp, class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      void assign(_Fp __f, const _Alloc& __a)\n        {function(allocator_arg, __a, __f).swap(*this);}\n\n    // 20.7.16.2.3, function capacity:\n    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}\n\nprivate:\n    // deleted overloads close possible hole in the type system\n    template<class _R2>\n      bool operator==(const function<_R2()>&) const;// = delete;\n    template<class _R2>\n      bool operator!=(const function<_R2()>&) const;// = delete;\npublic:\n    // 20.7.16.2.4, function invocation:\n    _Rp operator()() const;\n\n#ifndef _LIBCPP_NO_RTTI\n    // 20.7.16.2.5, function target access:\n    const std::type_info& target_type() const;\n    template <typename _Tp> _Tp* target();\n    template <typename _Tp> const _Tp* target() const;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _Rp>\nfunction<_Rp()>::function(const function& __f)\n{\n    if (__f.__f_ == 0)\n        __f_ = 0;\n    else if (__f.__f_ == (const __base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__clone(__f_);\n    }\n    else\n        __f_ = __f.__f_->__clone();\n}\n\ntemplate<class _Rp>\ntemplate<class _Alloc>\nfunction<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f)\n{\n    if (__f.__f_ == 0)\n        __f_ = 0;\n    else if (__f.__f_ == (const __base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__clone(__f_);\n    }\n    else\n        __f_ = __f.__f_->__clone();\n}\n\ntemplate<class _Rp>\ntemplate <class _Fp>\nfunction<_Rp()>::function(_Fp __f,\n                                     typename enable_if<!is_integral<_Fp>::value>::type*)\n    : __f_(0)\n{\n    if (__not_null(__f))\n    {\n        typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF;\n        if (sizeof(_FF) <= sizeof(__buf_))\n        {\n            __f_ = (__base*)&__buf_;\n            ::new (__f_) _FF(__f);\n        }\n        else\n        {\n            typedef allocator<_FF> _Ap;\n            _Ap __a;\n            typedef __allocator_destructor<_Ap> _Dp;\n            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));\n            __f_ = __hold.release();\n        }\n    }\n}\n\ntemplate<class _Rp>\ntemplate <class _Fp, class _Alloc>\nfunction<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,\n                                     typename enable_if<!is_integral<_Fp>::value>::type*)\n    : __f_(0)\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    if (__not_null(__f))\n    {\n        typedef __function::__func<_Fp, _Alloc, _Rp()> _FF;\n        if (sizeof(_FF) <= sizeof(__buf_))\n        {\n            __f_ = (__base*)&__buf_;\n            ::new (__f_) _FF(__f, __a0);\n        }\n        else\n        {\n            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;\n            _Ap __a(__a0);\n            typedef __allocator_destructor<_Ap> _Dp;\n            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n            ::new (__hold.get()) _FF(__f, _Alloc(__a));\n            __f_ = __hold.release();\n        }\n    }\n}\n\ntemplate<class _Rp>\nfunction<_Rp()>&\nfunction<_Rp()>::operator=(const function& __f)\n{\n    function(__f).swap(*this);\n    return *this;\n}\n\ntemplate<class _Rp>\nfunction<_Rp()>&\nfunction<_Rp()>::operator=(nullptr_t)\n{\n    if (__f_ == (__base*)&__buf_)\n        __f_->destroy();\n    else if (__f_)\n        __f_->destroy_deallocate();\n    __f_ = 0;\n    return *this;\n}\n\ntemplate<class _Rp>\ntemplate <class _Fp>\ntypename enable_if\n<\n    !is_integral<_Fp>::value,\n    function<_Rp()>&\n>::type\nfunction<_Rp()>::operator=(_Fp __f)\n{\n    function(_VSTD::move(__f)).swap(*this);\n    return *this;\n}\n\ntemplate<class _Rp>\nfunction<_Rp()>::~function()\n{\n    if (__f_ == (__base*)&__buf_)\n        __f_->destroy();\n    else if (__f_)\n        __f_->destroy_deallocate();\n}\n\ntemplate<class _Rp>\nvoid\nfunction<_Rp()>::swap(function& __f)\n{\n    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)\n    {\n        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;\n        __base* __t = (__base*)&__tempbuf;\n        __f_->__clone(__t);\n        __f_->destroy();\n        __f_ = 0;\n        __f.__f_->__clone((__base*)&__buf_);\n        __f.__f_->destroy();\n        __f.__f_ = 0;\n        __f_ = (__base*)&__buf_;\n        __t->__clone((__base*)&__f.__buf_);\n        __t->destroy();\n        __f.__f_ = (__base*)&__f.__buf_;\n    }\n    else if (__f_ == (__base*)&__buf_)\n    {\n        __f_->__clone((__base*)&__f.__buf_);\n        __f_->destroy();\n        __f_ = __f.__f_;\n        __f.__f_ = (__base*)&__f.__buf_;\n    }\n    else if (__f.__f_ == (__base*)&__f.__buf_)\n    {\n        __f.__f_->__clone((__base*)&__buf_);\n        __f.__f_->destroy();\n        __f.__f_ = __f_;\n        __f_ = (__base*)&__buf_;\n    }\n    else\n        _VSTD::swap(__f_, __f.__f_);\n}\n\ntemplate<class _Rp>\n_Rp\nfunction<_Rp()>::operator()() const\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__f_ == 0)\n        throw bad_function_call();\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return (*__f_)();\n}\n\n#ifndef _LIBCPP_NO_RTTI\n\ntemplate<class _Rp>\nconst std::type_info&\nfunction<_Rp()>::target_type() const\n{\n    if (__f_ == 0)\n        return typeid(void);\n    return __f_->target_type();\n}\n\ntemplate<class _Rp>\ntemplate <typename _Tp>\n_Tp*\nfunction<_Rp()>::target()\n{\n    if (__f_ == 0)\n        return (_Tp*)0;\n    return (_Tp*)__f_->target(typeid(_Tp));\n}\n\ntemplate<class _Rp>\ntemplate <typename _Tp>\nconst _Tp*\nfunction<_Rp()>::target() const\n{\n    if (__f_ == 0)\n        return (const _Tp*)0;\n    return (const _Tp*)__f_->target(typeid(_Tp));\n}\n\n#endif  // _LIBCPP_NO_RTTI\n\ntemplate<class _Rp, class _A0>\nclass _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0)>\n    : public unary_function<_A0, _Rp>\n{\n    typedef __function::__base<_Rp(_A0)> __base;\n    aligned_storage<3*sizeof(void*)>::type __buf_;\n    __base* __f_;\n\n    template <class _Fp>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(const _Fp&) {return true;}\n    template <class _R2, class _B0>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (*__p)(_B0)) {return __p;}\n    template <class _R2, class _Cp>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)()) {return __p;}\n    template <class _R2, class _Cp>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)() const) {return __p;}\n    template <class _R2, class _Cp>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)() volatile) {return __p;}\n    template <class _R2, class _Cp>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)() const volatile) {return __p;}\n    template <class _R2, class _B0>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(const function<_R2(_B0)>& __p) {return __p;}\npublic:\n    typedef _Rp result_type;\n\n    // 20.7.16.2.1, construct/copy/destroy:\n    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}\n    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}\n    function(const function&);\n    template<class _Fp>\n      function(_Fp,\n               typename enable_if<!is_integral<_Fp>::value>::type* = 0);\n\n    template<class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      function(allocator_arg_t, const _Alloc&) : __f_(0) {}\n    template<class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}\n    template<class _Alloc>\n      function(allocator_arg_t, const _Alloc&, const function&);\n    template<class _Fp, class _Alloc>\n      function(allocator_arg_t, const _Alloc& __a, _Fp __f,\n               typename enable_if<!is_integral<_Fp>::value>::type* = 0);\n\n    function& operator=(const function&);\n    function& operator=(nullptr_t);\n    template<class _Fp>\n      typename enable_if\n      <\n        !is_integral<_Fp>::value,\n        function&\n      >::type\n      operator=(_Fp);\n\n    ~function();\n\n    // 20.7.16.2.2, function modifiers:\n    void swap(function&);\n    template<class _Fp, class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      void assign(_Fp __f, const _Alloc& __a)\n        {function(allocator_arg, __a, __f).swap(*this);}\n\n    // 20.7.16.2.3, function capacity:\n    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}\n\nprivate:\n    // deleted overloads close possible hole in the type system\n    template<class _R2, class _B0>\n      bool operator==(const function<_R2(_B0)>&) const;// = delete;\n    template<class _R2, class _B0>\n      bool operator!=(const function<_R2(_B0)>&) const;// = delete;\npublic:\n    // 20.7.16.2.4, function invocation:\n    _Rp operator()(_A0) const;\n\n#ifndef _LIBCPP_NO_RTTI\n    // 20.7.16.2.5, function target access:\n    const std::type_info& target_type() const;\n    template <typename _Tp> _Tp* target();\n    template <typename _Tp> const _Tp* target() const;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _Rp, class _A0>\nfunction<_Rp(_A0)>::function(const function& __f)\n{\n    if (__f.__f_ == 0)\n        __f_ = 0;\n    else if (__f.__f_ == (const __base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__clone(__f_);\n    }\n    else\n        __f_ = __f.__f_->__clone();\n}\n\ntemplate<class _Rp, class _A0>\ntemplate<class _Alloc>\nfunction<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f)\n{\n    if (__f.__f_ == 0)\n        __f_ = 0;\n    else if (__f.__f_ == (const __base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__clone(__f_);\n    }\n    else\n        __f_ = __f.__f_->__clone();\n}\n\ntemplate<class _Rp, class _A0>\ntemplate <class _Fp>\nfunction<_Rp(_A0)>::function(_Fp __f,\n                                     typename enable_if<!is_integral<_Fp>::value>::type*)\n    : __f_(0)\n{\n    if (__not_null(__f))\n    {\n        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF;\n        if (sizeof(_FF) <= sizeof(__buf_))\n        {\n            __f_ = (__base*)&__buf_;\n            ::new (__f_) _FF(__f);\n        }\n        else\n        {\n            typedef allocator<_FF> _Ap;\n            _Ap __a;\n            typedef __allocator_destructor<_Ap> _Dp;\n            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));\n            __f_ = __hold.release();\n        }\n    }\n}\n\ntemplate<class _Rp, class _A0>\ntemplate <class _Fp, class _Alloc>\nfunction<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,\n                                     typename enable_if<!is_integral<_Fp>::value>::type*)\n    : __f_(0)\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    if (__not_null(__f))\n    {\n        typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF;\n        if (sizeof(_FF) <= sizeof(__buf_))\n        {\n            __f_ = (__base*)&__buf_;\n            ::new (__f_) _FF(__f, __a0);\n        }\n        else\n        {\n            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;\n            _Ap __a(__a0);\n            typedef __allocator_destructor<_Ap> _Dp;\n            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n            ::new (__hold.get()) _FF(__f, _Alloc(__a));\n            __f_ = __hold.release();\n        }\n    }\n}\n\ntemplate<class _Rp, class _A0>\nfunction<_Rp(_A0)>&\nfunction<_Rp(_A0)>::operator=(const function& __f)\n{\n    function(__f).swap(*this);\n    return *this;\n}\n\ntemplate<class _Rp, class _A0>\nfunction<_Rp(_A0)>&\nfunction<_Rp(_A0)>::operator=(nullptr_t)\n{\n    if (__f_ == (__base*)&__buf_)\n        __f_->destroy();\n    else if (__f_)\n        __f_->destroy_deallocate();\n    __f_ = 0;\n    return *this;\n}\n\ntemplate<class _Rp, class _A0>\ntemplate <class _Fp>\ntypename enable_if\n<\n    !is_integral<_Fp>::value,\n    function<_Rp(_A0)>&\n>::type\nfunction<_Rp(_A0)>::operator=(_Fp __f)\n{\n    function(_VSTD::move(__f)).swap(*this);\n    return *this;\n}\n\ntemplate<class _Rp, class _A0>\nfunction<_Rp(_A0)>::~function()\n{\n    if (__f_ == (__base*)&__buf_)\n        __f_->destroy();\n    else if (__f_)\n        __f_->destroy_deallocate();\n}\n\ntemplate<class _Rp, class _A0>\nvoid\nfunction<_Rp(_A0)>::swap(function& __f)\n{\n    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)\n    {\n        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;\n        __base* __t = (__base*)&__tempbuf;\n        __f_->__clone(__t);\n        __f_->destroy();\n        __f_ = 0;\n        __f.__f_->__clone((__base*)&__buf_);\n        __f.__f_->destroy();\n        __f.__f_ = 0;\n        __f_ = (__base*)&__buf_;\n        __t->__clone((__base*)&__f.__buf_);\n        __t->destroy();\n        __f.__f_ = (__base*)&__f.__buf_;\n    }\n    else if (__f_ == (__base*)&__buf_)\n    {\n        __f_->__clone((__base*)&__f.__buf_);\n        __f_->destroy();\n        __f_ = __f.__f_;\n        __f.__f_ = (__base*)&__f.__buf_;\n    }\n    else if (__f.__f_ == (__base*)&__f.__buf_)\n    {\n        __f.__f_->__clone((__base*)&__buf_);\n        __f.__f_->destroy();\n        __f.__f_ = __f_;\n        __f_ = (__base*)&__buf_;\n    }\n    else\n        _VSTD::swap(__f_, __f.__f_);\n}\n\ntemplate<class _Rp, class _A0>\n_Rp\nfunction<_Rp(_A0)>::operator()(_A0 __a0) const\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__f_ == 0)\n        throw bad_function_call();\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return (*__f_)(__a0);\n}\n\n#ifndef _LIBCPP_NO_RTTI\n\ntemplate<class _Rp, class _A0>\nconst std::type_info&\nfunction<_Rp(_A0)>::target_type() const\n{\n    if (__f_ == 0)\n        return typeid(void);\n    return __f_->target_type();\n}\n\ntemplate<class _Rp, class _A0>\ntemplate <typename _Tp>\n_Tp*\nfunction<_Rp(_A0)>::target()\n{\n    if (__f_ == 0)\n        return (_Tp*)0;\n    return (_Tp*)__f_->target(typeid(_Tp));\n}\n\ntemplate<class _Rp, class _A0>\ntemplate <typename _Tp>\nconst _Tp*\nfunction<_Rp(_A0)>::target() const\n{\n    if (__f_ == 0)\n        return (const _Tp*)0;\n    return (const _Tp*)__f_->target(typeid(_Tp));\n}\n\n#endif  // _LIBCPP_NO_RTTI\n\ntemplate<class _Rp, class _A0, class _A1>\nclass _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1)>\n    : public binary_function<_A0, _A1, _Rp>\n{\n    typedef __function::__base<_Rp(_A0, _A1)> __base;\n    aligned_storage<3*sizeof(void*)>::type __buf_;\n    __base* __f_;\n\n    template <class _Fp>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(const _Fp&) {return true;}\n    template <class _R2, class _B0, class _B1>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (*__p)(_B0, _B1)) {return __p;}\n    template <class _R2, class _Cp, class _B1>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)(_B1)) {return __p;}\n    template <class _R2, class _Cp, class _B1>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)(_B1) const) {return __p;}\n    template <class _R2, class _Cp, class _B1>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)(_B1) volatile) {return __p;}\n    template <class _R2, class _Cp, class _B1>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)(_B1) const volatile) {return __p;}\n    template <class _R2, class _B0, class _B1>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(const function<_R2(_B0, _B1)>& __p) {return __p;}\npublic:\n    typedef _Rp result_type;\n\n    // 20.7.16.2.1, construct/copy/destroy:\n    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}\n    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}\n    function(const function&);\n    template<class _Fp>\n      function(_Fp,\n               typename enable_if<!is_integral<_Fp>::value>::type* = 0);\n\n    template<class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      function(allocator_arg_t, const _Alloc&) : __f_(0) {}\n    template<class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}\n    template<class _Alloc>\n      function(allocator_arg_t, const _Alloc&, const function&);\n    template<class _Fp, class _Alloc>\n      function(allocator_arg_t, const _Alloc& __a, _Fp __f,\n               typename enable_if<!is_integral<_Fp>::value>::type* = 0);\n\n    function& operator=(const function&);\n    function& operator=(nullptr_t);\n    template<class _Fp>\n      typename enable_if\n      <\n        !is_integral<_Fp>::value,\n        function&\n      >::type\n      operator=(_Fp);\n\n    ~function();\n\n    // 20.7.16.2.2, function modifiers:\n    void swap(function&);\n    template<class _Fp, class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      void assign(_Fp __f, const _Alloc& __a)\n        {function(allocator_arg, __a, __f).swap(*this);}\n\n    // 20.7.16.2.3, function capacity:\n    operator bool() const {return __f_;}\n\nprivate:\n    // deleted overloads close possible hole in the type system\n    template<class _R2, class _B0, class _B1>\n      bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete;\n    template<class _R2, class _B0, class _B1>\n      bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete;\npublic:\n    // 20.7.16.2.4, function invocation:\n    _Rp operator()(_A0, _A1) const;\n\n#ifndef _LIBCPP_NO_RTTI\n    // 20.7.16.2.5, function target access:\n    const std::type_info& target_type() const;\n    template <typename _Tp> _Tp* target();\n    template <typename _Tp> const _Tp* target() const;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _Rp, class _A0, class _A1>\nfunction<_Rp(_A0, _A1)>::function(const function& __f)\n{\n    if (__f.__f_ == 0)\n        __f_ = 0;\n    else if (__f.__f_ == (const __base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__clone(__f_);\n    }\n    else\n        __f_ = __f.__f_->__clone();\n}\n\ntemplate<class _Rp, class _A0, class _A1>\ntemplate<class _Alloc>\nfunction<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f)\n{\n    if (__f.__f_ == 0)\n        __f_ = 0;\n    else if (__f.__f_ == (const __base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__clone(__f_);\n    }\n    else\n        __f_ = __f.__f_->__clone();\n}\n\ntemplate<class _Rp, class _A0, class _A1>\ntemplate <class _Fp>\nfunction<_Rp(_A0, _A1)>::function(_Fp __f,\n                                 typename enable_if<!is_integral<_Fp>::value>::type*)\n    : __f_(0)\n{\n    if (__not_null(__f))\n    {\n        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF;\n        if (sizeof(_FF) <= sizeof(__buf_))\n        {\n            __f_ = (__base*)&__buf_;\n            ::new (__f_) _FF(__f);\n        }\n        else\n        {\n            typedef allocator<_FF> _Ap;\n            _Ap __a;\n            typedef __allocator_destructor<_Ap> _Dp;\n            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));\n            __f_ = __hold.release();\n        }\n    }\n}\n\ntemplate<class _Rp, class _A0, class _A1>\ntemplate <class _Fp, class _Alloc>\nfunction<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,\n                                 typename enable_if<!is_integral<_Fp>::value>::type*)\n    : __f_(0)\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    if (__not_null(__f))\n    {\n        typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF;\n        if (sizeof(_FF) <= sizeof(__buf_))\n        {\n            __f_ = (__base*)&__buf_;\n            ::new (__f_) _FF(__f, __a0);\n        }\n        else\n        {\n            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;\n            _Ap __a(__a0);\n            typedef __allocator_destructor<_Ap> _Dp;\n            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n            ::new (__hold.get()) _FF(__f, _Alloc(__a));\n            __f_ = __hold.release();\n        }\n    }\n}\n\ntemplate<class _Rp, class _A0, class _A1>\nfunction<_Rp(_A0, _A1)>&\nfunction<_Rp(_A0, _A1)>::operator=(const function& __f)\n{\n    function(__f).swap(*this);\n    return *this;\n}\n\ntemplate<class _Rp, class _A0, class _A1>\nfunction<_Rp(_A0, _A1)>&\nfunction<_Rp(_A0, _A1)>::operator=(nullptr_t)\n{\n    if (__f_ == (__base*)&__buf_)\n        __f_->destroy();\n    else if (__f_)\n        __f_->destroy_deallocate();\n    __f_ = 0;\n    return *this;\n}\n\ntemplate<class _Rp, class _A0, class _A1>\ntemplate <class _Fp>\ntypename enable_if\n<\n    !is_integral<_Fp>::value,\n    function<_Rp(_A0, _A1)>&\n>::type\nfunction<_Rp(_A0, _A1)>::operator=(_Fp __f)\n{\n    function(_VSTD::move(__f)).swap(*this);\n    return *this;\n}\n\ntemplate<class _Rp, class _A0, class _A1>\nfunction<_Rp(_A0, _A1)>::~function()\n{\n    if (__f_ == (__base*)&__buf_)\n        __f_->destroy();\n    else if (__f_)\n        __f_->destroy_deallocate();\n}\n\ntemplate<class _Rp, class _A0, class _A1>\nvoid\nfunction<_Rp(_A0, _A1)>::swap(function& __f)\n{\n    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)\n    {\n        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;\n        __base* __t = (__base*)&__tempbuf;\n        __f_->__clone(__t);\n        __f_->destroy();\n        __f_ = 0;\n        __f.__f_->__clone((__base*)&__buf_);\n        __f.__f_->destroy();\n        __f.__f_ = 0;\n        __f_ = (__base*)&__buf_;\n        __t->__clone((__base*)&__f.__buf_);\n        __t->destroy();\n        __f.__f_ = (__base*)&__f.__buf_;\n    }\n    else if (__f_ == (__base*)&__buf_)\n    {\n        __f_->__clone((__base*)&__f.__buf_);\n        __f_->destroy();\n        __f_ = __f.__f_;\n        __f.__f_ = (__base*)&__f.__buf_;\n    }\n    else if (__f.__f_ == (__base*)&__f.__buf_)\n    {\n        __f.__f_->__clone((__base*)&__buf_);\n        __f.__f_->destroy();\n        __f.__f_ = __f_;\n        __f_ = (__base*)&__buf_;\n    }\n    else\n        _VSTD::swap(__f_, __f.__f_);\n}\n\ntemplate<class _Rp, class _A0, class _A1>\n_Rp\nfunction<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__f_ == 0)\n        throw bad_function_call();\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return (*__f_)(__a0, __a1);\n}\n\n#ifndef _LIBCPP_NO_RTTI\n\ntemplate<class _Rp, class _A0, class _A1>\nconst std::type_info&\nfunction<_Rp(_A0, _A1)>::target_type() const\n{\n    if (__f_ == 0)\n        return typeid(void);\n    return __f_->target_type();\n}\n\ntemplate<class _Rp, class _A0, class _A1>\ntemplate <typename _Tp>\n_Tp*\nfunction<_Rp(_A0, _A1)>::target()\n{\n    if (__f_ == 0)\n        return (_Tp*)0;\n    return (_Tp*)__f_->target(typeid(_Tp));\n}\n\ntemplate<class _Rp, class _A0, class _A1>\ntemplate <typename _Tp>\nconst _Tp*\nfunction<_Rp(_A0, _A1)>::target() const\n{\n    if (__f_ == 0)\n        return (const _Tp*)0;\n    return (const _Tp*)__f_->target(typeid(_Tp));\n}\n\n#endif  // _LIBCPP_NO_RTTI\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\nclass _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1, _A2)>\n{\n    typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;\n    aligned_storage<3*sizeof(void*)>::type __buf_;\n    __base* __f_;\n\n    template <class _Fp>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(const _Fp&) {return true;}\n    template <class _R2, class _B0, class _B1, class _B2>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (*__p)(_B0, _B1, _B2)) {return __p;}\n    template <class _R2, class _Cp, class _B1, class _B2>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2)) {return __p;}\n    template <class _R2, class _Cp, class _B1, class _B2>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) const) {return __p;}\n    template <class _R2, class _Cp, class _B1, class _B2>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) volatile) {return __p;}\n    template <class _R2, class _Cp, class _B1, class _B2>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) const volatile) {return __p;}\n    template <class _R2, class _B0, class _B1, class _B2>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(const function<_R2(_B0, _B1, _B2)>& __p) {return __p;}\npublic:\n    typedef _Rp result_type;\n\n    // 20.7.16.2.1, construct/copy/destroy:\n    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}\n    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}\n    function(const function&);\n    template<class _Fp>\n      function(_Fp,\n               typename enable_if<!is_integral<_Fp>::value>::type* = 0);\n\n    template<class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      function(allocator_arg_t, const _Alloc&) : __f_(0) {}\n    template<class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}\n    template<class _Alloc>\n      function(allocator_arg_t, const _Alloc&, const function&);\n    template<class _Fp, class _Alloc>\n      function(allocator_arg_t, const _Alloc& __a, _Fp __f,\n               typename enable_if<!is_integral<_Fp>::value>::type* = 0);\n\n    function& operator=(const function&);\n    function& operator=(nullptr_t);\n    template<class _Fp>\n      typename enable_if\n      <\n        !is_integral<_Fp>::value,\n        function&\n      >::type\n      operator=(_Fp);\n\n    ~function();\n\n    // 20.7.16.2.2, function modifiers:\n    void swap(function&);\n    template<class _Fp, class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      void assign(_Fp __f, const _Alloc& __a)\n        {function(allocator_arg, __a, __f).swap(*this);}\n\n    // 20.7.16.2.3, function capacity:\n    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}\n\nprivate:\n    // deleted overloads close possible hole in the type system\n    template<class _R2, class _B0, class _B1, class _B2>\n      bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;\n    template<class _R2, class _B0, class _B1, class _B2>\n      bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;\npublic:\n    // 20.7.16.2.4, function invocation:\n    _Rp operator()(_A0, _A1, _A2) const;\n\n#ifndef _LIBCPP_NO_RTTI\n    // 20.7.16.2.5, function target access:\n    const std::type_info& target_type() const;\n    template <typename _Tp> _Tp* target();\n    template <typename _Tp> const _Tp* target() const;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\nfunction<_Rp(_A0, _A1, _A2)>::function(const function& __f)\n{\n    if (__f.__f_ == 0)\n        __f_ = 0;\n    else if (__f.__f_ == (const __base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__clone(__f_);\n    }\n    else\n        __f_ = __f.__f_->__clone();\n}\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\ntemplate<class _Alloc>\nfunction<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&,\n                                      const function& __f)\n{\n    if (__f.__f_ == 0)\n        __f_ = 0;\n    else if (__f.__f_ == (const __base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__clone(__f_);\n    }\n    else\n        __f_ = __f.__f_->__clone();\n}\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\ntemplate <class _Fp>\nfunction<_Rp(_A0, _A1, _A2)>::function(_Fp __f,\n                                     typename enable_if<!is_integral<_Fp>::value>::type*)\n    : __f_(0)\n{\n    if (__not_null(__f))\n    {\n        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF;\n        if (sizeof(_FF) <= sizeof(__buf_))\n        {\n            __f_ = (__base*)&__buf_;\n            ::new (__f_) _FF(__f);\n        }\n        else\n        {\n            typedef allocator<_FF> _Ap;\n            _Ap __a;\n            typedef __allocator_destructor<_Ap> _Dp;\n            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));\n            __f_ = __hold.release();\n        }\n    }\n}\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\ntemplate <class _Fp, class _Alloc>\nfunction<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,\n                                     typename enable_if<!is_integral<_Fp>::value>::type*)\n    : __f_(0)\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    if (__not_null(__f))\n    {\n        typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF;\n        if (sizeof(_FF) <= sizeof(__buf_))\n        {\n            __f_ = (__base*)&__buf_;\n            ::new (__f_) _FF(__f, __a0);\n        }\n        else\n        {\n            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;\n            _Ap __a(__a0);\n            typedef __allocator_destructor<_Ap> _Dp;\n            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n            ::new (__hold.get()) _FF(__f, _Alloc(__a));\n            __f_ = __hold.release();\n        }\n    }\n}\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\nfunction<_Rp(_A0, _A1, _A2)>&\nfunction<_Rp(_A0, _A1, _A2)>::operator=(const function& __f)\n{\n    function(__f).swap(*this);\n    return *this;\n}\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\nfunction<_Rp(_A0, _A1, _A2)>&\nfunction<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t)\n{\n    if (__f_ == (__base*)&__buf_)\n        __f_->destroy();\n    else if (__f_)\n        __f_->destroy_deallocate();\n    __f_ = 0;\n    return *this;\n}\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\ntemplate <class _Fp>\ntypename enable_if\n<\n    !is_integral<_Fp>::value,\n    function<_Rp(_A0, _A1, _A2)>&\n>::type\nfunction<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f)\n{\n    function(_VSTD::move(__f)).swap(*this);\n    return *this;\n}\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\nfunction<_Rp(_A0, _A1, _A2)>::~function()\n{\n    if (__f_ == (__base*)&__buf_)\n        __f_->destroy();\n    else if (__f_)\n        __f_->destroy_deallocate();\n}\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\nvoid\nfunction<_Rp(_A0, _A1, _A2)>::swap(function& __f)\n{\n    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)\n    {\n        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;\n        __base* __t = (__base*)&__tempbuf;\n        __f_->__clone(__t);\n        __f_->destroy();\n        __f_ = 0;\n        __f.__f_->__clone((__base*)&__buf_);\n        __f.__f_->destroy();\n        __f.__f_ = 0;\n        __f_ = (__base*)&__buf_;\n        __t->__clone((__base*)&__f.__buf_);\n        __t->destroy();\n        __f.__f_ = (__base*)&__f.__buf_;\n    }\n    else if (__f_ == (__base*)&__buf_)\n    {\n        __f_->__clone((__base*)&__f.__buf_);\n        __f_->destroy();\n        __f_ = __f.__f_;\n        __f.__f_ = (__base*)&__f.__buf_;\n    }\n    else if (__f.__f_ == (__base*)&__f.__buf_)\n    {\n        __f.__f_->__clone((__base*)&__buf_);\n        __f.__f_->destroy();\n        __f.__f_ = __f_;\n        __f_ = (__base*)&__buf_;\n    }\n    else\n        _VSTD::swap(__f_, __f.__f_);\n}\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\n_Rp\nfunction<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__f_ == 0)\n        throw bad_function_call();\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return (*__f_)(__a0, __a1, __a2);\n}\n\n#ifndef _LIBCPP_NO_RTTI\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\nconst std::type_info&\nfunction<_Rp(_A0, _A1, _A2)>::target_type() const\n{\n    if (__f_ == 0)\n        return typeid(void);\n    return __f_->target_type();\n}\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\ntemplate <typename _Tp>\n_Tp*\nfunction<_Rp(_A0, _A1, _A2)>::target()\n{\n    if (__f_ == 0)\n        return (_Tp*)0;\n    return (_Tp*)__f_->target(typeid(_Tp));\n}\n\ntemplate<class _Rp, class _A0, class _A1, class _A2>\ntemplate <typename _Tp>\nconst _Tp*\nfunction<_Rp(_A0, _A1, _A2)>::target() const\n{\n    if (__f_ == 0)\n        return (const _Tp*)0;\n    return (const _Tp*)__f_->target(typeid(_Tp));\n}\n\n#endif  // _LIBCPP_NO_RTTI\n\ntemplate <class _Fp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const function<_Fp>& __f, nullptr_t) {return !__f;}\n\ntemplate <class _Fp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(nullptr_t, const function<_Fp>& __f) {return !__f;}\n\ntemplate <class _Fp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;}\n\ntemplate <class _Fp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;}\n\ntemplate <class _Fp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(function<_Fp>& __x, function<_Fp>& __y)\n{return __x.swap(__y);}\n\n#endif  // _LIBCPP_FUNCTIONAL_03\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__functional_base",
    "content": "// -*- C++ -*-\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_FUNCTIONAL_BASE\n#define _LIBCPP_FUNCTIONAL_BASE\n\n#include <__config>\n#include <type_traits>\n#include <typeinfo>\n#include <exception>\n#include <new>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Arg, class _Result>\nstruct _LIBCPP_TYPE_VIS_ONLY unary_function\n{\n    typedef _Arg    argument_type;\n    typedef _Result result_type;\n};\n\ntemplate <class _Arg1, class _Arg2, class _Result>\nstruct _LIBCPP_TYPE_VIS_ONLY binary_function\n{\n    typedef _Arg1   first_argument_type;\n    typedef _Arg2   second_argument_type;\n    typedef _Result result_type;\n};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash;\n\ntemplate <class _Tp>\nstruct __has_result_type\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::result_type* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY less : binary_function<_Tp, _Tp, bool>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY \n    bool operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x < __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY less<void>\n{\n    template <class _T1, class _T2> \n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n// addressof\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp*\naddressof(_Tp& __x) _NOEXCEPT\n{\n    return (_Tp*)&reinterpret_cast<const volatile char&>(__x);\n}\n\n#if defined(_LIBCPP_HAS_OBJC_ARC) && !defined(_LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF)\n// Objective-C++ Automatic Reference Counting uses qualified pointers\n// that require special addressof() signatures. When\n// _LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF is defined, the compiler\n// itself is providing these definitions. Otherwise, we provide them.\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n__strong _Tp*\naddressof(__strong _Tp& __x) _NOEXCEPT\n{\n  return &__x;\n}\n\n#ifdef _LIBCPP_HAS_OBJC_ARC_WEAK\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n__weak _Tp*\naddressof(__weak _Tp& __x) _NOEXCEPT\n{\n  return &__x;\n}\n#endif\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n__autoreleasing _Tp*\naddressof(__autoreleasing _Tp& __x) _NOEXCEPT\n{\n  return &__x;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n__unsafe_unretained _Tp*\naddressof(__unsafe_unretained _Tp& __x) _NOEXCEPT\n{\n  return &__x;\n}\n#endif\n\n\n// __weak_result_type\n\ntemplate <class _Tp>\nstruct __derives_from_unary_function\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    static __two __test(...);\n    template <class _Ap, class _Rp>\n        static unary_function<_Ap, _Rp>\n        __test(const volatile unary_function<_Ap, _Rp>*);\npublic:\n    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;\n    typedef decltype(__test((_Tp*)0)) type;\n};\n\ntemplate <class _Tp>\nstruct __derives_from_binary_function\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    static __two __test(...);\n    template <class _A1, class _A2, class _Rp>\n        static binary_function<_A1, _A2, _Rp>\n        __test(const volatile binary_function<_A1, _A2, _Rp>*);\npublic:\n    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;\n    typedef decltype(__test((_Tp*)0)) type;\n};\n\ntemplate <class _Tp, bool = __derives_from_unary_function<_Tp>::value>\nstruct __maybe_derive_from_unary_function  // bool is true\n    : public __derives_from_unary_function<_Tp>::type\n{\n};\n\ntemplate <class _Tp>\nstruct __maybe_derive_from_unary_function<_Tp, false>\n{\n};\n\ntemplate <class _Tp, bool = __derives_from_binary_function<_Tp>::value>\nstruct __maybe_derive_from_binary_function  // bool is true\n    : public __derives_from_binary_function<_Tp>::type\n{\n};\n\ntemplate <class _Tp>\nstruct __maybe_derive_from_binary_function<_Tp, false>\n{\n};\n\ntemplate <class _Tp, bool = __has_result_type<_Tp>::value>\nstruct __weak_result_type_imp // bool is true\n    : public __maybe_derive_from_unary_function<_Tp>,\n      public __maybe_derive_from_binary_function<_Tp>\n{\n    typedef typename _Tp::result_type result_type;\n};\n\ntemplate <class _Tp>\nstruct __weak_result_type_imp<_Tp, false>\n    : public __maybe_derive_from_unary_function<_Tp>,\n      public __maybe_derive_from_binary_function<_Tp>\n{\n};\n\ntemplate <class _Tp>\nstruct __weak_result_type\n    : public __weak_result_type_imp<_Tp>\n{\n};\n\n// 0 argument case\n\ntemplate <class _Rp>\nstruct __weak_result_type<_Rp ()>\n{\n    typedef _Rp result_type;\n};\n\ntemplate <class _Rp>\nstruct __weak_result_type<_Rp (&)()>\n{\n    typedef _Rp result_type;\n};\n\ntemplate <class _Rp>\nstruct __weak_result_type<_Rp (*)()>\n{\n    typedef _Rp result_type;\n};\n\n// 1 argument case\n\ntemplate <class _Rp, class _A1>\nstruct __weak_result_type<_Rp (_A1)>\n    : public unary_function<_A1, _Rp>\n{\n};\n\ntemplate <class _Rp, class _A1>\nstruct __weak_result_type<_Rp (&)(_A1)>\n    : public unary_function<_A1, _Rp>\n{\n};\n\ntemplate <class _Rp, class _A1>\nstruct __weak_result_type<_Rp (*)(_A1)>\n    : public unary_function<_A1, _Rp>\n{\n};\n\ntemplate <class _Rp, class _Cp>\nstruct __weak_result_type<_Rp (_Cp::*)()>\n    : public unary_function<_Cp*, _Rp>\n{\n};\n\ntemplate <class _Rp, class _Cp>\nstruct __weak_result_type<_Rp (_Cp::*)() const>\n    : public unary_function<const _Cp*, _Rp>\n{\n};\n\ntemplate <class _Rp, class _Cp>\nstruct __weak_result_type<_Rp (_Cp::*)() volatile>\n    : public unary_function<volatile _Cp*, _Rp>\n{\n};\n\ntemplate <class _Rp, class _Cp>\nstruct __weak_result_type<_Rp (_Cp::*)() const volatile>\n    : public unary_function<const volatile _Cp*, _Rp>\n{\n};\n\n// 2 argument case\n\ntemplate <class _Rp, class _A1, class _A2>\nstruct __weak_result_type<_Rp (_A1, _A2)>\n    : public binary_function<_A1, _A2, _Rp>\n{\n};\n\ntemplate <class _Rp, class _A1, class _A2>\nstruct __weak_result_type<_Rp (*)(_A1, _A2)>\n    : public binary_function<_A1, _A2, _Rp>\n{\n};\n\ntemplate <class _Rp, class _A1, class _A2>\nstruct __weak_result_type<_Rp (&)(_A1, _A2)>\n    : public binary_function<_A1, _A2, _Rp>\n{\n};\n\ntemplate <class _Rp, class _Cp, class _A1>\nstruct __weak_result_type<_Rp (_Cp::*)(_A1)>\n    : public binary_function<_Cp*, _A1, _Rp>\n{\n};\n\ntemplate <class _Rp, class _Cp, class _A1>\nstruct __weak_result_type<_Rp (_Cp::*)(_A1) const>\n    : public binary_function<const _Cp*, _A1, _Rp>\n{\n};\n\ntemplate <class _Rp, class _Cp, class _A1>\nstruct __weak_result_type<_Rp (_Cp::*)(_A1) volatile>\n    : public binary_function<volatile _Cp*, _A1, _Rp>\n{\n};\n\ntemplate <class _Rp, class _Cp, class _A1>\nstruct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile>\n    : public binary_function<const volatile _Cp*, _A1, _Rp>\n{\n};\n\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n// 3 or more arguments\n\ntemplate <class _Rp, class _A1, class _A2, class _A3, class ..._A4>\nstruct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)>\n{\n    typedef _Rp result_type;\n};\n\ntemplate <class _Rp, class _A1, class _A2, class _A3, class ..._A4>\nstruct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)>\n{\n    typedef _Rp result_type;\n};\n\ntemplate <class _Rp, class _A1, class _A2, class _A3, class ..._A4>\nstruct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)>\n{\n    typedef _Rp result_type;\n};\n\ntemplate <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>\nstruct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)>\n{\n    typedef _Rp result_type;\n};\n\ntemplate <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>\nstruct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const>\n{\n    typedef _Rp result_type;\n};\n\ntemplate <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>\nstruct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile>\n{\n    typedef _Rp result_type;\n};\n\ntemplate <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>\nstruct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile>\n{\n    typedef _Rp result_type;\n};\n\n#endif // _LIBCPP_HAS_NO_VARIADICS\n\n// __invoke\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n// bullets 1 and 2\n\ntemplate <class _Fp, class _A0, class ..._Args,\n            class>\ninline _LIBCPP_INLINE_VISIBILITY\nauto\n__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)\n    -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...))\n{\n    return (_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...);\n}\n\ntemplate <class _Fp, class _A0, class ..._Args,\n            class>\ninline _LIBCPP_INLINE_VISIBILITY\nauto\n__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)\n    -> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...))\n{\n    return ((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...);\n}\n\n// bullets 3 and 4\n\ntemplate <class _Fp, class _A0,\n            class>\ninline _LIBCPP_INLINE_VISIBILITY\nauto\n__invoke(_Fp&& __f, _A0&& __a0)\n    -> decltype(_VSTD::forward<_A0>(__a0).*__f)\n{\n    return _VSTD::forward<_A0>(__a0).*__f;\n}\n\ntemplate <class _Fp, class _A0,\n            class>\ninline _LIBCPP_INLINE_VISIBILITY\nauto\n__invoke(_Fp&& __f, _A0&& __a0)\n    -> decltype((*_VSTD::forward<_A0>(__a0)).*__f)\n{\n    return (*_VSTD::forward<_A0>(__a0)).*__f;\n}\n\n// bullet 5\n\ntemplate <class _Fp, class ..._Args>\ninline _LIBCPP_INLINE_VISIBILITY\nauto\n__invoke(_Fp&& __f, _Args&& ...__args)\n    -> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...))\n{\n    return _VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...);\n}\ntemplate <class _Tp, class ..._Args>\nstruct __invoke_return\n{\n    typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type;\n};\n\n#else // _LIBCPP_HAS_NO_VARIADICS\n\n#include <__functional_base_03>\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n\ntemplate <class _Ret>\nstruct __invoke_void_return_wrapper\n{\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class ..._Args>\n    static _Ret __call(_Args&&... __args) {\n        return __invoke(_VSTD::forward<_Args>(__args)...);\n    }\n#else\n    template <class _Fn>\n    static _Ret __call(_Fn __f) {\n        return __invoke(__f);\n    }\n\n    template <class _Fn, class _A0>\n    static _Ret __call(_Fn __f, _A0& __a0) {\n        return __invoke(__f, __a0);\n    }\n\n    template <class _Fn, class _A0, class _A1>\n    static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) {\n        return __invoke(__f, __a0, __a1);\n    }\n\n    template <class _Fn, class _A0, class _A1, class _A2>\n    static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){\n        return __invoke(__f, __a0, __a1, __a2);\n    }\n#endif\n};\n\ntemplate <>\nstruct __invoke_void_return_wrapper<void>\n{\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class ..._Args>\n    static void __call(_Args&&... __args) {\n        __invoke(_VSTD::forward<_Args>(__args)...);\n    }\n#else\n    template <class _Fn>\n    static void __call(_Fn __f) {\n        __invoke(__f);\n    }\n\n    template <class _Fn, class _A0>\n    static void __call(_Fn __f, _A0& __a0) {\n        __invoke(__f, __a0);\n    }\n\n    template <class _Fn, class _A0, class _A1>\n    static void __call(_Fn __f, _A0& __a0, _A1& __a1) {\n        __invoke(__f, __a0, __a1);\n    }\n\n    template <class _Fn, class _A0, class _A1, class _A2>\n    static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) {\n        __invoke(__f, __a0, __a1, __a2);\n    }\n#endif\n};\n\ntemplate <class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY reference_wrapper\n    : public __weak_result_type<_Tp>\n{\npublic:\n    // types\n    typedef _Tp type;\nprivate:\n    type* __f_;\n\npublic:\n    // construct/copy/destroy\n    _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT\n        : __f_(_VSTD::addressof(__f)) {}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    private: reference_wrapper(type&&); public: // = delete; // do not bind to temps\n#endif\n\n    // access\n    _LIBCPP_INLINE_VISIBILITY operator type&    () const _NOEXCEPT {return *__f_;}\n    _LIBCPP_INLINE_VISIBILITY          type& get() const _NOEXCEPT {return *__f_;}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    // invoke\n    template <class... _ArgTypes>\n       _LIBCPP_INLINE_VISIBILITY\n       typename __invoke_of<type&, _ArgTypes...>::type\n          operator() (_ArgTypes&&... __args) const\n          {\n              return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);\n          }\n#else\n\n    _LIBCPP_INLINE_VISIBILITY\n    typename __invoke_return<type>::type\n       operator() () const\n       {\n           return __invoke(get());\n       }\n\n    template <class _A0>\n       _LIBCPP_INLINE_VISIBILITY\n       typename __invoke_return0<type&, _A0>::type\n          operator() (_A0& __a0) const\n          {\n              return __invoke<type&, _A0>(get(), __a0);\n          }\n\n    template <class _A0, class _A1>\n       _LIBCPP_INLINE_VISIBILITY\n       typename __invoke_return1<type&, _A0, _A1>::type\n          operator() (_A0& __a0, _A1& __a1) const\n          {\n              return __invoke<type&, _A0, _A1>(get(), __a0, __a1);\n          }\n\n    template <class _A0, class _A1, class _A2>\n       _LIBCPP_INLINE_VISIBILITY\n       typename __invoke_return2<type&, _A0, _A1, _A2>::type\n          operator() (_A0& __a0, _A1& __a1, _A2& __a2) const\n          {\n              return __invoke<type&, _A0, _A1, _A2>(get(), __a0, __a1, __a2);\n          }\n#endif // _LIBCPP_HAS_NO_VARIADICS\n};\n\ntemplate <class _Tp> struct __is_reference_wrapper_impl : public false_type {};\ntemplate <class _Tp> struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {};\ntemplate <class _Tp> struct __is_reference_wrapper\n    : public __is_reference_wrapper_impl<typename remove_cv<_Tp>::type> {};\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nreference_wrapper<_Tp>\nref(_Tp& __t) _NOEXCEPT\n{\n    return reference_wrapper<_Tp>(__t);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nreference_wrapper<_Tp>\nref(reference_wrapper<_Tp> __t) _NOEXCEPT\n{\n    return ref(__t.get());\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nreference_wrapper<const _Tp>\ncref(const _Tp& __t) _NOEXCEPT\n{\n    return reference_wrapper<const _Tp>(__t);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nreference_wrapper<const _Tp>\ncref(reference_wrapper<_Tp> __t) _NOEXCEPT\n{\n    return cref(__t.get());\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n\ntemplate <class _Tp> void ref(const _Tp&&) = delete;\ntemplate <class _Tp> void cref(const _Tp&&) = delete;\n\n#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n\ntemplate <class _Tp> void ref(const _Tp&&);// = delete;\ntemplate <class _Tp> void cref(const _Tp&&);// = delete;\n\n#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp1, class _Tp2 = void>\nstruct __is_transparent\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::is_transparent* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp1>(0)) == 1;\n};\n#endif\n\n// allocator_arg_t\n\nstruct _LIBCPP_TYPE_VIS_ONLY allocator_arg_t { };\n\n#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MEMORY)\nextern const allocator_arg_t allocator_arg;\n#else\nconstexpr allocator_arg_t allocator_arg = allocator_arg_t();\n#endif\n\n// uses_allocator\n\ntemplate <class _Tp>\nstruct __has_allocator_type\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::allocator_type* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\ntemplate <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>\nstruct __uses_allocator\n    : public integral_constant<bool,\n        is_convertible<_Alloc, typename _Tp::allocator_type>::value>\n{\n};\n\ntemplate <class _Tp, class _Alloc>\nstruct __uses_allocator<_Tp, _Alloc, false>\n    : public false_type\n{\n};\n\ntemplate <class _Tp, class _Alloc>\nstruct _LIBCPP_TYPE_VIS_ONLY uses_allocator\n    : public __uses_allocator<_Tp, _Alloc>\n{\n};\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n// allocator construction\n\ntemplate <class _Tp, class _Alloc, class ..._Args>\nstruct __uses_alloc_ctor_imp\n{\n    static const bool __ua = uses_allocator<_Tp, _Alloc>::value;\n    static const bool __ic =\n        is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;\n    static const int value = __ua ? 2 - __ic : 0;\n};\n\ntemplate <class _Tp, class _Alloc, class ..._Args>\nstruct __uses_alloc_ctor\n    : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>\n    {};\n\ntemplate <class _Tp, class _Allocator, class... _Args>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args )\n{\n    new (__storage) _Tp (_VSTD::forward<_Args>(__args)...);\n}\n\ntemplate <class _Tp, class _Allocator, class... _Args>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )\n{\n    new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);\n}\n\ntemplate <class _Tp, class _Allocator, class... _Args>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )\n{\n    new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);\n}\n\ntemplate <class _Tp, class _Allocator, class... _Args>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid __user_alloc_construct (_Tp *__storage, const _Allocator &__a, _Args &&... __args)\n{ \n    __user_alloc_construct_impl( \n             __uses_alloc_ctor<_Tp, _Allocator>(), \n             __storage, __a, _VSTD::forward<_Args>(__args)...\n        );\n}\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_FUNCTIONAL_BASE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__functional_base_03",
    "content": "// -*- C++ -*-\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_FUNCTIONAL_BASE_03\n#define _LIBCPP_FUNCTIONAL_BASE_03\n\n// manual variadic expansion for <functional>\n\n// __invoke\n// first bullet\n\ntemplate <class _Rp, class _Tp, class _T1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(), _T1& __t1)\n{\n    return (__t1.*__f)();\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0), _T1& __t1, _A0& __a0)\n{\n    return (__t1.*__f)(__a0);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1), _T1& __t1, _A0& __a0, _A1& __a1)\n{\n    return (__t1.*__f)(__a0, __a1);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2), _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2)\n{\n    return (__t1.*__f)(__a0, __a1, __a2);\n}\n\ntemplate <class _Rp, class _Tp, class _T1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)() const, _T1& __t1)\n{\n    return (__t1.*__f)();\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0) const, _T1& __t1, _A0& __a0)\n{\n    return (__t1.*__f)(__a0);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1) const, _T1& __t1, _A0& __a0, _A1& __a1)\n{\n    return (__t1.*__f)(__a0, __a1);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2)\n{\n    return (__t1.*__f)(__a0, __a1, __a2);\n}\n\ntemplate <class _Rp, class _Tp, class _T1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)() volatile, _T1& __t1)\n{\n    return (__t1.*__f)();\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0) volatile, _T1& __t1, _A0& __a0)\n{\n    return (__t1.*__f)(__a0);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1) volatile, _T1& __t1, _A0& __a0, _A1& __a1)\n{\n    return (__t1.*__f)(__a0, __a1);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) volatile, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2)\n{\n    return (__t1.*__f)(__a0, __a1, __a2);\n}\n\ntemplate <class _Rp, class _Tp, class _T1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)() const volatile, _T1& __t1)\n{\n    return (__t1.*__f)();\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0) const volatile, _T1& __t1, _A0& __a0)\n{\n    return (__t1.*__f)(__a0);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1) const volatile, _T1& __t1, _A0& __a0, _A1& __a1)\n{\n    return (__t1.*__f)(__a0, __a1);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const volatile, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2)\n{\n    return (__t1.*__f)(__a0, __a1, __a2);\n}\n\n// second bullet\n\ntemplate <class _Rp, class _Tp, class _T1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(), _T1 __t1)\n{\n    return ((*__t1).*__f)();\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0), _T1 __t1, _A0& __a0)\n{\n    return ((*__t1).*__f)(__a0);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1), _T1 __t1, _A0& __a0, _A1& __a1)\n{\n    return ((*__t1).*__f)(__a0, __a1);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2), _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2)\n{\n    return ((*__t1).*__f)(__a0, __a1, __a2);\n}\n\ntemplate <class _Rp, class _Tp, class _T1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)() const, _T1 __t1)\n{\n    return ((*__t1).*__f)();\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0) const, _T1 __t1, _A0& __a0)\n{\n    return ((*__t1).*__f)(__a0);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1) const, _T1 __t1, _A0& __a0, _A1& __a1)\n{\n    return ((*__t1).*__f)(__a0, __a1);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const, _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2)\n{\n    return ((*__t1).*__f)(__a0, __a1, __a2);\n}\n\ntemplate <class _Rp, class _Tp, class _T1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)() volatile, _T1 __t1)\n{\n    return ((*__t1).*__f)();\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0) volatile, _T1 __t1, _A0& __a0)\n{\n    return ((*__t1).*__f)(__a0);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1) volatile, _T1 __t1, _A0& __a0, _A1& __a1)\n{\n    return ((*__t1).*__f)(__a0, __a1);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) volatile, _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2)\n{\n    return ((*__t1).*__f)(__a0, __a1, __a2);\n}\n\ntemplate <class _Rp, class _Tp, class _T1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)() const volatile, _T1 __t1)\n{\n    return ((*__t1).*__f)();\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0) const volatile, _T1 __t1, _A0& __a0)\n{\n    return ((*__t1).*__f)(__a0);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1) const volatile, _T1 __t1, _A0& __a0, _A1& __a1)\n{\n    return ((*__t1).*__f)(__a0, __a1);\n}\n\ntemplate <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n    _Rp\n>::type\n__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const volatile, _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2)\n{\n    return ((*__t1).*__f)(__a0, __a1, __a2);\n}\n\n// third bullet\n\ntemplate <class _Rp, class _Tp, class _T1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_member_object_pointer<_Rp _Tp::*>::value &&\n    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,\n   __apply_cv<_T1, _Rp>\n>::type::type&\n__invoke(_Rp _Tp::* __f, _T1& __t1)\n{\n    return __t1.*__f;\n}\n\n\n// forth bullet\n\ntemplate <class _T1, class _Rp, bool>\nstruct __4th_helper\n{\n};\n\ntemplate <class _T1, class _Rp>\nstruct __4th_helper<_T1, _Rp, true>\n{\n    typedef typename __apply_cv<decltype(*_VSTD::declval<_T1&>()), _Rp>::type type;\n};\n\ntemplate <class _Rp, class _Tp, class _T1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __4th_helper<_T1, _Rp,\n    is_member_object_pointer<_Rp _Tp::*>::value &&\n    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value\n>::type&\n__invoke(_Rp _Tp::* __f, _T1& __t1)\n{\n    return (*__t1).*__f;\n}\n\n// fifth bullet\n\ntemplate <class _Fp>\ninline _LIBCPP_INLINE_VISIBILITY\ndecltype(_VSTD::declval<_Fp&>()())\n__invoke(_Fp& __f)\n{\n    return __f();\n}\n\ntemplate <class _Fp, class _A0>\ninline _LIBCPP_INLINE_VISIBILITY\ndecltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>()))\n__invoke(_Fp& __f, _A0& __a0)\n{\n    return __f(__a0);\n}\n\ntemplate <class _Fp, class _A0, class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ndecltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>()))\n__invoke(_Fp& __f, _A0& __a0, _A1& __a1)\n{\n    return __f(__a0, __a1);\n}\n\ntemplate <class _Fp, class _A0, class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ndecltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>(), _VSTD::declval<_A2&>()))\n__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2)\n{\n    return __f(__a0, __a1, __a2);\n}\n\ntemplate <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value>\nstruct __invoke_return\n{\n    typedef typename __weak_result_type<_Fp>::result_type type;\n};\n\ntemplate <class _Fp>\nstruct __invoke_return<_Fp, false>\n{\n    typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type;\n};\n\ntemplate <class _Tp, class _A0, bool = is_member_object_pointer<_Tp>::value>\nstruct __invoke_return0\n{\n    typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type;\n};\n\ntemplate <class _Rp, class _Tp, class _A0>\nstruct __invoke_return0<_Rp _Tp::*, _A0, true>\n{\n    typedef typename __apply_cv<_A0, _Rp>::type& type;\n};\n\ntemplate <class _Rp, class _Tp, class _A0>\nstruct __invoke_return0<_Rp _Tp::*, _A0*, true>\n{\n    typedef typename __apply_cv<_A0, _Rp>::type& type;\n};\n\ntemplate <class _Tp, class _A0, class _A1>\nstruct __invoke_return1\n{\n    typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(),\n                                                     _VSTD::declval<_A1&>())) type;\n};\n\ntemplate <class _Tp, class _A0, class _A1, class _A2>\nstruct __invoke_return2\n{\n    typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(),\n                                                      _VSTD::declval<_A1&>(),\n                                                      _VSTD::declval<_A2&>())) type;\n};\n\n#endif  // _LIBCPP_FUNCTIONAL_BASE_03\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__hash_table",
    "content": "// -*- C++ -*-\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP__HASH_TABLE\n#define _LIBCPP__HASH_TABLE\n\n#include <__config>\n#include <initializer_list>\n#include <memory>\n#include <iterator>\n#include <algorithm>\n#include <cmath>\n\n#include <__undef_min_max>\n#include <__undef___deallocate>\n\n#include <__debug>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n_LIBCPP_FUNC_VIS\nsize_t __next_prime(size_t __n);\n\ntemplate <class _NodePtr>\nstruct __hash_node_base\n{\n    typedef __hash_node_base __first_node;\n\n    _NodePtr    __next_;\n\n    _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {}\n};\n\ntemplate <class _Tp, class _VoidPtr>\nstruct __hash_node\n    : public __hash_node_base\n             <\n                 typename pointer_traits<_VoidPtr>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n                     rebind<__hash_node<_Tp, _VoidPtr> >\n#else\n                     rebind<__hash_node<_Tp, _VoidPtr> >::other\n#endif\n             >\n{\n    typedef _Tp value_type;\n\n    size_t     __hash_;\n    value_type __value_;\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\n__is_hash_power2(size_t __bc)\n{\n    return __bc > 2 && !(__bc & (__bc - 1));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nsize_t\n__constrain_hash(size_t __h, size_t __bc)\n{\n    return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : __h % __bc;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nsize_t\n__next_hash_pow2(size_t __n)\n{\n    return size_t(1) << (std::numeric_limits<size_t>::digits - __clz(__n-1));\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table;\ntemplate <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;\ntemplate <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator;\ntemplate <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\n    class _LIBCPP_TYPE_VIS_ONLY unordered_map;\n\ntemplate <class _NodePtr>\nclass _LIBCPP_TYPE_VIS_ONLY __hash_iterator\n{\n    typedef _NodePtr __node_pointer;\n\n    __node_pointer            __node_;\n\npublic:\n    typedef forward_iterator_tag                         iterator_category;\n    typedef typename pointer_traits<__node_pointer>::element_type::value_type value_type;\n    typedef typename pointer_traits<__node_pointer>::difference_type difference_type;\n    typedef value_type&                                  reference;\n    typedef typename pointer_traits<__node_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n                     rebind<value_type>\n#else\n                     rebind<value_type>::other\n#endif\n                                                         pointer;\n\n    _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT\n#if _LIBCPP_STD_VER > 11\n    : __node_(nullptr)\n#endif\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->__insert_i(this);\n#endif\n    }\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_iterator(const __hash_iterator& __i)\n        : __node_(__i.__node_)\n    {\n        __get_db()->__iterator_copy(this, &__i);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    ~__hash_iterator()\n    {\n        __get_db()->__erase_i(this);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_iterator& operator=(const __hash_iterator& __i)\n    {\n        if (this != &__i)\n        {\n            __get_db()->__iterator_copy(this, &__i);\n            __node_ = __i.__node_;\n        }\n        return *this;\n    }\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\n    _LIBCPP_INLINE_VISIBILITY\n        reference operator*() const\n        {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                           \"Attempted to dereference a non-dereferenceable unordered container iterator\");\n#endif\n            return __node_->__value_;\n        }\n    _LIBCPP_INLINE_VISIBILITY\n        pointer operator->() const\n        {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                           \"Attempted to dereference a non-dereferenceable unordered container iterator\");\n#endif\n            return pointer_traits<pointer>::pointer_to(__node_->__value_);\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_iterator& operator++()\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                       \"Attempted to increment non-incrementable unordered container iterator\");\n#endif\n        __node_ = __node_->__next_;\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_iterator operator++(int)\n    {\n        __hash_iterator __t(*this);\n        ++(*this);\n        return __t;\n    }\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const __hash_iterator& __x, const __hash_iterator& __y)\n    {\n        return __x.__node_ == __y.__node_;\n    }\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y)\n        {return !(__x == __y);}\n\nprivate:\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_iterator(__node_pointer __node, const void* __c) _NOEXCEPT\n        : __node_(__node)\n        {\n            __get_db()->__insert_ic(this, __c);\n        }\n#else\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_iterator(__node_pointer __node) _NOEXCEPT\n        : __node_(__node)\n        {}\n#endif\n\n    template <class, class, class, class> friend class __hash_table;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator;\n    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;\n    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;\n};\n\ntemplate <class _ConstNodePtr>\nclass _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator\n{\n    typedef _ConstNodePtr __node_pointer;\n\n    __node_pointer         __node_;\n\n    typedef typename remove_const<\n        typename pointer_traits<__node_pointer>::element_type\n                                 >::type __node;\n\npublic:\n    typedef forward_iterator_tag                       iterator_category;\n    typedef typename __node::value_type                value_type;\n    typedef typename pointer_traits<__node_pointer>::difference_type difference_type;\n    typedef const value_type&                          reference;\n    typedef typename pointer_traits<__node_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<const value_type>\n#else\n            rebind<const value_type>::other\n#endif\n                                                       pointer;\n    typedef typename pointer_traits<__node_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<__node>\n#else\n            rebind<__node>::other\n#endif\n                                                      __non_const_node_pointer;\n    typedef __hash_iterator<__non_const_node_pointer> __non_const_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT\n#if _LIBCPP_STD_VER > 11\n    : __node_(nullptr)\n#endif\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->__insert_i(this);\n#endif\n    }\n    _LIBCPP_INLINE_VISIBILITY \n    __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT\n        : __node_(__x.__node_)\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->__iterator_copy(this, &__x);\n#endif\n    }\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_const_iterator(const __hash_const_iterator& __i)\n        : __node_(__i.__node_)\n    {\n        __get_db()->__iterator_copy(this, &__i);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    ~__hash_const_iterator()\n    {\n        __get_db()->__erase_i(this);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_const_iterator& operator=(const __hash_const_iterator& __i)\n    {\n        if (this != &__i)\n        {\n            __get_db()->__iterator_copy(this, &__i);\n            __node_ = __i.__node_;\n        }\n        return *this;\n    }\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\n    _LIBCPP_INLINE_VISIBILITY\n        reference operator*() const\n        {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                           \"Attempted to dereference a non-dereferenceable unordered container const_iterator\");\n#endif\n            return __node_->__value_;\n        }\n    _LIBCPP_INLINE_VISIBILITY\n        pointer operator->() const\n        {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                           \"Attempted to dereference a non-dereferenceable unordered container const_iterator\");\n#endif\n            return pointer_traits<pointer>::pointer_to(__node_->__value_);\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_const_iterator& operator++()\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                       \"Attempted to increment non-incrementable unordered container const_iterator\");\n#endif\n        __node_ = __node_->__next_;\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_const_iterator operator++(int)\n    {\n        __hash_const_iterator __t(*this);\n        ++(*this);\n        return __t;\n    }\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y)\n    {\n        return __x.__node_ == __y.__node_;\n    }\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y)\n        {return !(__x == __y);}\n\nprivate:\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_const_iterator(__node_pointer __node, const void* __c) _NOEXCEPT\n        : __node_(__node)\n        {\n            __get_db()->__insert_ic(this, __c);\n        }\n#else\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_const_iterator(__node_pointer __node) _NOEXCEPT\n        : __node_(__node)\n        {}\n#endif\n\n    template <class, class, class, class> friend class __hash_table;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;\n    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;\n    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;\n};\n\ntemplate <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;\n\ntemplate <class _NodePtr>\nclass _LIBCPP_TYPE_VIS_ONLY __hash_local_iterator\n{\n    typedef _NodePtr __node_pointer;\n\n    __node_pointer         __node_;\n    size_t                 __bucket_;\n    size_t                 __bucket_count_;\n\n    typedef pointer_traits<__node_pointer>          __pointer_traits;\npublic:\n    typedef forward_iterator_tag                                iterator_category;\n    typedef typename __pointer_traits::element_type::value_type value_type;\n    typedef typename __pointer_traits::difference_type          difference_type;\n    typedef value_type&                                         reference;\n    typedef typename __pointer_traits::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<value_type>\n#else\n            rebind<value_type>::other\n#endif\n                                                                pointer;\n\n    _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->__insert_i(this);\n#endif\n    }\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_local_iterator(const __hash_local_iterator& __i)\n        : __node_(__i.__node_),\n          __bucket_(__i.__bucket_),\n          __bucket_count_(__i.__bucket_count_)\n    {\n        __get_db()->__iterator_copy(this, &__i);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    ~__hash_local_iterator()\n    {\n        __get_db()->__erase_i(this);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_local_iterator& operator=(const __hash_local_iterator& __i)\n    {\n        if (this != &__i)\n        {\n            __get_db()->__iterator_copy(this, &__i);\n            __node_ = __i.__node_;\n            __bucket_ = __i.__bucket_;\n            __bucket_count_ = __i.__bucket_count_;\n        }\n        return *this;\n    }\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\n    _LIBCPP_INLINE_VISIBILITY\n        reference operator*() const\n        {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                           \"Attempted to dereference a non-dereferenceable unordered container local_iterator\");\n#endif\n            return __node_->__value_;\n        }\n    _LIBCPP_INLINE_VISIBILITY\n        pointer operator->() const\n        {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                           \"Attempted to dereference a non-dereferenceable unordered container local_iterator\");\n#endif\n            return pointer_traits<pointer>::pointer_to(__node_->__value_);\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_local_iterator& operator++()\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                       \"Attempted to increment non-incrementable unordered container local_iterator\");\n#endif\n        __node_ = __node_->__next_;\n        if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_)\n            __node_ = nullptr;\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_local_iterator operator++(int)\n    {\n        __hash_local_iterator __t(*this);\n        ++(*this);\n        return __t;\n    }\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y)\n    {\n        return __x.__node_ == __y.__node_;\n    }\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y)\n        {return !(__x == __y);}\n\nprivate:\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_local_iterator(__node_pointer __node, size_t __bucket,\n                          size_t __bucket_count, const void* __c) _NOEXCEPT\n        : __node_(__node),\n          __bucket_(__bucket),\n          __bucket_count_(__bucket_count)\n        {\n            __get_db()->__insert_ic(this, __c);\n            if (__node_ != nullptr)\n                __node_ = __node_->__next_;\n        }\n#else\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_local_iterator(__node_pointer __node, size_t __bucket,\n                          size_t __bucket_count) _NOEXCEPT\n        : __node_(__node),\n          __bucket_(__bucket),\n          __bucket_count_(__bucket_count)\n        {\n            if (__node_ != nullptr)\n                __node_ = __node_->__next_;\n        }\n#endif\n    template <class, class, class, class> friend class __hash_table;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator;\n};\n\ntemplate <class _ConstNodePtr>\nclass _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator\n{\n    typedef _ConstNodePtr __node_pointer;\n\n    __node_pointer         __node_;\n    size_t                 __bucket_;\n    size_t                 __bucket_count_;\n\n    typedef pointer_traits<__node_pointer>          __pointer_traits;\n    typedef typename __pointer_traits::element_type __node;\n    typedef typename remove_const<__node>::type     __non_const_node;\n    typedef typename pointer_traits<__node_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<__non_const_node>\n#else\n            rebind<__non_const_node>::other\n#endif\n                                                    __non_const_node_pointer;\n    typedef __hash_local_iterator<__non_const_node_pointer>\n                                                    __non_const_iterator;\npublic:\n    typedef forward_iterator_tag                       iterator_category;\n    typedef typename remove_const<\n                        typename __pointer_traits::element_type::value_type\n                     >::type                           value_type;\n    typedef typename __pointer_traits::difference_type difference_type;\n    typedef const value_type&                          reference;\n    typedef typename __pointer_traits::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<const value_type>\n#else\n            rebind<const value_type>::other\n#endif\n                                                       pointer;\n\n    _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->__insert_i(this);\n#endif\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT\n        : __node_(__x.__node_),\n          __bucket_(__x.__bucket_),\n          __bucket_count_(__x.__bucket_count_)\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->__iterator_copy(this, &__x);\n#endif\n    }\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_const_local_iterator(const __hash_const_local_iterator& __i)\n        : __node_(__i.__node_),\n          __bucket_(__i.__bucket_),\n          __bucket_count_(__i.__bucket_count_)\n    {\n        __get_db()->__iterator_copy(this, &__i);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    ~__hash_const_local_iterator()\n    {\n        __get_db()->__erase_i(this);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i)\n    {\n        if (this != &__i)\n        {\n            __get_db()->__iterator_copy(this, &__i);\n            __node_ = __i.__node_;\n            __bucket_ = __i.__bucket_;\n            __bucket_count_ = __i.__bucket_count_;\n        }\n        return *this;\n    }\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\n    _LIBCPP_INLINE_VISIBILITY\n        reference operator*() const\n        {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                           \"Attempted to dereference a non-dereferenceable unordered container const_local_iterator\");\n#endif\n            return __node_->__value_;\n        }\n    _LIBCPP_INLINE_VISIBILITY\n        pointer operator->() const\n        {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                           \"Attempted to dereference a non-dereferenceable unordered container const_local_iterator\");\n#endif\n            return pointer_traits<pointer>::pointer_to(__node_->__value_);\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_const_local_iterator& operator++()\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                       \"Attempted to increment non-incrementable unordered container const_local_iterator\");\n#endif\n        __node_ = __node_->__next_;\n        if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_)\n            __node_ = nullptr;\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_const_local_iterator operator++(int)\n    {\n        __hash_const_local_iterator __t(*this);\n        ++(*this);\n        return __t;\n    }\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)\n    {\n        return __x.__node_ == __y.__node_;\n    }\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)\n        {return !(__x == __y);}\n\nprivate:\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_const_local_iterator(__node_pointer __node, size_t __bucket,\n                                size_t __bucket_count, const void* __c) _NOEXCEPT\n        : __node_(__node),\n          __bucket_(__bucket),\n          __bucket_count_(__bucket_count)\n        {\n            __get_db()->__insert_ic(this, __c);\n            if (__node_ != nullptr)\n                __node_ = __node_->__next_;\n        }\n#else\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_const_local_iterator(__node_pointer __node, size_t __bucket,\n                                size_t __bucket_count) _NOEXCEPT\n        : __node_(__node),\n          __bucket_(__bucket),\n          __bucket_count_(__bucket_count)\n        {\n            if (__node_ != nullptr)\n                __node_ = __node_->__next_;\n        }\n#endif\n    template <class, class, class, class> friend class __hash_table;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;\n};\n\ntemplate <class _Alloc>\nclass __bucket_list_deallocator\n{\n    typedef _Alloc                                          allocator_type;\n    typedef allocator_traits<allocator_type>                __alloc_traits;\n    typedef typename __alloc_traits::size_type              size_type;\n\n    __compressed_pair<size_type, allocator_type> __data_;\npublic:\n    typedef typename __alloc_traits::pointer pointer;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bucket_list_deallocator()\n        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)\n        : __data_(0) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bucket_list_deallocator(const allocator_type& __a, size_type __size)\n        _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)\n        : __data_(__size, __a) {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bucket_list_deallocator(__bucket_list_deallocator&& __x)\n        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)\n        : __data_(_VSTD::move(__x.__data_))\n    {\n        __x.size() = 0;\n    }\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type& size() _NOEXCEPT {return __data_.first();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type  size() const _NOEXCEPT {return __data_.first();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type& __alloc() _NOEXCEPT {return __data_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n    const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void operator()(pointer __p) _NOEXCEPT\n    {\n        __alloc_traits::deallocate(__alloc(), __p, size());\n    }\n};\n\ntemplate <class _Alloc> class __hash_map_node_destructor;\n\ntemplate <class _Alloc>\nclass __hash_node_destructor\n{\n    typedef _Alloc                                          allocator_type;\n    typedef allocator_traits<allocator_type>                __alloc_traits;\n    typedef typename __alloc_traits::value_type::value_type value_type;\npublic:\n    typedef typename __alloc_traits::pointer                pointer;\nprivate:\n\n    allocator_type& __na_;\n\n    __hash_node_destructor& operator=(const __hash_node_destructor&);\n\npublic:\n    bool __value_constructed;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __hash_node_destructor(allocator_type& __na,\n                                    bool __constructed = false) _NOEXCEPT\n        : __na_(__na),\n          __value_constructed(__constructed)\n        {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void operator()(pointer __p) _NOEXCEPT\n    {\n        if (__value_constructed)\n            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_));\n        if (__p)\n            __alloc_traits::deallocate(__na_, __p, 1);\n    }\n\n    template <class> friend class __hash_map_node_destructor;\n};\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\nclass __hash_table\n{\npublic:\n    typedef _Tp    value_type;\n    typedef _Hash  hasher;\n    typedef _Equal key_equal;\n    typedef _Alloc allocator_type;\n\nprivate:\n    typedef allocator_traits<allocator_type> __alloc_traits;\npublic:\n    typedef value_type&                              reference;\n    typedef const value_type&                        const_reference;\n    typedef typename __alloc_traits::pointer         pointer;\n    typedef typename __alloc_traits::const_pointer   const_pointer;\n    typedef typename __alloc_traits::size_type       size_type;\n    typedef typename __alloc_traits::difference_type difference_type;\npublic:\n    // Create __node\n    typedef __hash_node<value_type, typename __alloc_traits::void_pointer> __node;\n    typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;\n    typedef allocator_traits<__node_allocator>       __node_traits;\n    typedef typename __node_traits::pointer          __node_pointer;\n    typedef typename __node_traits::pointer          __node_const_pointer;\n    typedef __hash_node_base<__node_pointer>         __first_node;\n    typedef typename pointer_traits<__node_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<__first_node>\n#else\n            rebind<__first_node>::other\n#endif\n                                                     __node_base_pointer;\n\nprivate:\n\n    typedef typename __rebind_alloc_helper<__node_traits, __node_pointer>::type __pointer_allocator;\n    typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter;\n    typedef unique_ptr<__node_pointer[], __bucket_list_deleter> __bucket_list;\n    typedef allocator_traits<__pointer_allocator>          __pointer_alloc_traits;\n    typedef typename __bucket_list_deleter::pointer __node_pointer_pointer;\n\n    // --- Member data begin ---\n    __bucket_list                                     __bucket_list_;\n    __compressed_pair<__first_node, __node_allocator> __p1_;\n    __compressed_pair<size_type, hasher>              __p2_;\n    __compressed_pair<float, key_equal>               __p3_;\n    // --- Member data end ---\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type& size() _NOEXCEPT {return __p2_.first();}\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    size_type  size() const _NOEXCEPT {return __p2_.first();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    hasher& hash_function() _NOEXCEPT {return __p2_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n    const hasher& hash_function() const _NOEXCEPT {return __p2_.second();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    float& max_load_factor() _NOEXCEPT {return __p3_.first();}\n    _LIBCPP_INLINE_VISIBILITY\n    float  max_load_factor() const _NOEXCEPT {return __p3_.first();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    key_equal& key_eq() _NOEXCEPT {return __p3_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n    const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n    const __node_allocator& __node_alloc() const _NOEXCEPT\n        {return __p1_.second();}\n\npublic:\n    typedef __hash_iterator<__node_pointer>                   iterator;\n    typedef __hash_const_iterator<__node_pointer>             const_iterator;\n    typedef __hash_local_iterator<__node_pointer>             local_iterator;\n    typedef __hash_const_local_iterator<__node_pointer>       const_local_iterator;\n\n    __hash_table()\n        _NOEXCEPT_(\n            is_nothrow_default_constructible<__bucket_list>::value &&\n            is_nothrow_default_constructible<__first_node>::value &&\n            is_nothrow_default_constructible<__node_allocator>::value &&\n            is_nothrow_default_constructible<hasher>::value &&\n            is_nothrow_default_constructible<key_equal>::value);\n    __hash_table(const hasher& __hf, const key_equal& __eql);\n    __hash_table(const hasher& __hf, const key_equal& __eql,\n                 const allocator_type& __a);\n    explicit __hash_table(const allocator_type& __a);\n    __hash_table(const __hash_table& __u);\n    __hash_table(const __hash_table& __u, const allocator_type& __a);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __hash_table(__hash_table&& __u)\n        _NOEXCEPT_(\n            is_nothrow_move_constructible<__bucket_list>::value &&\n            is_nothrow_move_constructible<__first_node>::value &&\n            is_nothrow_move_constructible<__node_allocator>::value &&\n            is_nothrow_move_constructible<hasher>::value &&\n            is_nothrow_move_constructible<key_equal>::value);\n    __hash_table(__hash_table&& __u, const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    ~__hash_table();\n\n    __hash_table& operator=(const __hash_table& __u);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __hash_table& operator=(__hash_table&& __u)\n        _NOEXCEPT_(\n            __node_traits::propagate_on_container_move_assignment::value &&\n            is_nothrow_move_assignable<__node_allocator>::value &&\n            is_nothrow_move_assignable<hasher>::value &&\n            is_nothrow_move_assignable<key_equal>::value);\n#endif\n    template <class _InputIterator>\n        void __assign_unique(_InputIterator __first, _InputIterator __last);\n    template <class _InputIterator>\n        void __assign_multi(_InputIterator __first, _InputIterator __last);\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const _NOEXCEPT\n    {\n        return allocator_traits<__pointer_allocator>::max_size(\n            __bucket_list_.get_deleter().__alloc());\n    }\n\n    pair<iterator, bool> __node_insert_unique(__node_pointer __nd);\n    iterator             __node_insert_multi(__node_pointer __nd);\n    iterator             __node_insert_multi(const_iterator __p,\n                                             __node_pointer __nd);\n\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    template <class... _Args>\n        pair<iterator, bool> __emplace_unique(_Args&&... __args);\n    template <class... _Args>\n        iterator __emplace_multi(_Args&&... __args);\n    template <class... _Args>\n        iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);\n#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _ValueTp>\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, bool> __insert_unique_value(_ValueTp&& __x);\n#else\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, bool> __insert_unique_value(const value_type& __x);\n#endif\n\n    pair<iterator, bool> __insert_unique(const value_type& __x);\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    pair<iterator, bool> __insert_unique(value_type&& __x);\n    template <class _Pp>\n    pair<iterator, bool> __insert_unique(_Pp&& __x);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Pp>\n        iterator __insert_multi(_Pp&& __x);\n    template <class _Pp>\n        iterator __insert_multi(const_iterator __p, _Pp&& __x);\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    iterator __insert_multi(const value_type& __x);\n    iterator __insert_multi(const_iterator __p, const value_type& __x);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    void clear() _NOEXCEPT;\n    void rehash(size_type __n);\n    _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n)\n        {rehash(static_cast<size_type>(ceil(__n / max_load_factor())));}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket_count() const _NOEXCEPT\n    {\n        return __bucket_list_.get_deleter().size();\n    }\n\n    iterator       begin() _NOEXCEPT;\n    iterator       end() _NOEXCEPT;\n    const_iterator begin() const _NOEXCEPT;\n    const_iterator end() const _NOEXCEPT;\n\n    template <class _Key>\n        _LIBCPP_INLINE_VISIBILITY\n        size_type bucket(const _Key& __k) const\n        {\n            _LIBCPP_ASSERT(bucket_count() > 0,\n                \"unordered container::bucket(key) called when bucket_count() == 0\");\n            return __constrain_hash(hash_function()(__k), bucket_count());\n        }\n\n    template <class _Key>\n        iterator       find(const _Key& __x);\n    template <class _Key>\n        const_iterator find(const _Key& __x) const;\n\n    typedef __hash_node_destructor<__node_allocator> _Dp;\n    typedef unique_ptr<__node, _Dp> __node_holder;\n\n    iterator erase(const_iterator __p);\n    iterator erase(const_iterator __first, const_iterator __last);\n    template <class _Key>\n        size_type __erase_unique(const _Key& __k);\n    template <class _Key>\n        size_type __erase_multi(const _Key& __k);\n    __node_holder remove(const_iterator __p) _NOEXCEPT;\n\n    template <class _Key>\n        size_type __count_unique(const _Key& __k) const;\n    template <class _Key>\n        size_type __count_multi(const _Key& __k) const;\n\n    template <class _Key>\n        pair<iterator, iterator>\n        __equal_range_unique(const _Key& __k);\n    template <class _Key>\n        pair<const_iterator, const_iterator>\n        __equal_range_unique(const _Key& __k) const;\n\n    template <class _Key>\n        pair<iterator, iterator>\n        __equal_range_multi(const _Key& __k);\n    template <class _Key>\n        pair<const_iterator, const_iterator>\n        __equal_range_multi(const _Key& __k) const;\n\n    void swap(__hash_table& __u)\n#if _LIBCPP_STD_VER <= 11\n        _NOEXCEPT_(\n            __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value\n            && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value\n                  || __is_nothrow_swappable<__pointer_allocator>::value)\n            && (!__node_traits::propagate_on_container_swap::value\n                  || __is_nothrow_swappable<__node_allocator>::value)\n            );\n#else\n     _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value);\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_bucket_count() const _NOEXCEPT\n        {return __pointer_alloc_traits::max_size(__bucket_list_.get_deleter().__alloc());}\n    size_type bucket_size(size_type __n) const;\n    _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT\n    {\n        size_type __bc = bucket_count();\n        return __bc != 0 ? (float)size() / __bc : 0.f;\n    }\n    _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT\n    {\n        _LIBCPP_ASSERT(__mlf > 0,\n            \"unordered container::max_load_factor(lf) called with lf <= 0\");\n        max_load_factor() = _VSTD::max(__mlf, load_factor());\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    local_iterator\n    begin(size_type __n)\n    {\n        _LIBCPP_ASSERT(__n < bucket_count(),\n            \"unordered container::begin(n) called with n >= bucket_count()\");\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        return local_iterator(__bucket_list_[__n], __n, bucket_count(), this);\n#else\n        return local_iterator(__bucket_list_[__n], __n, bucket_count());\n#endif\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    local_iterator\n    end(size_type __n)\n    {\n        _LIBCPP_ASSERT(__n < bucket_count(),\n            \"unordered container::end(n) called with n >= bucket_count()\");\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        return local_iterator(nullptr, __n, bucket_count(), this);\n#else\n        return local_iterator(nullptr, __n, bucket_count());\n#endif\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator\n    cbegin(size_type __n) const\n    {\n        _LIBCPP_ASSERT(__n < bucket_count(),\n            \"unordered container::cbegin(n) called with n >= bucket_count()\");\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this);\n#else\n        return const_local_iterator(__bucket_list_[__n], __n, bucket_count());\n#endif\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator\n    cend(size_type __n) const\n    {\n        _LIBCPP_ASSERT(__n < bucket_count(),\n            \"unordered container::cend(n) called with n >= bucket_count()\");\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        return const_local_iterator(nullptr, __n, bucket_count(), this);\n#else\n        return const_local_iterator(nullptr, __n, bucket_count());\n#endif\n    }\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n    bool __dereferenceable(const const_iterator* __i) const;\n    bool __decrementable(const const_iterator* __i) const;\n    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;\n    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\nprivate:\n    void __rehash(size_type __n);\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class ..._Args>\n        __node_holder __construct_node(_Args&& ...__args);\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n    __node_holder __construct_node(value_type&& __v, size_t __hash);\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __node_holder __construct_node(const value_type& __v);\n#endif\n    __node_holder __construct_node(const value_type& __v, size_t __hash);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const __hash_table& __u)\n        {__copy_assign_alloc(__u, integral_constant<bool,\n             __node_traits::propagate_on_container_copy_assignment::value>());}\n    void __copy_assign_alloc(const __hash_table& __u, true_type);\n    _LIBCPP_INLINE_VISIBILITY\n        void __copy_assign_alloc(const __hash_table&, false_type) {}\n\n    void __move_assign(__hash_table& __u, false_type);\n    void __move_assign(__hash_table& __u, true_type)\n        _NOEXCEPT_(\n            is_nothrow_move_assignable<__node_allocator>::value &&\n            is_nothrow_move_assignable<hasher>::value &&\n            is_nothrow_move_assignable<key_equal>::value);\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__hash_table& __u)\n        _NOEXCEPT_(\n            !__node_traits::propagate_on_container_move_assignment::value ||\n            (is_nothrow_move_assignable<__pointer_allocator>::value &&\n             is_nothrow_move_assignable<__node_allocator>::value))\n        {__move_assign_alloc(__u, integral_constant<bool,\n             __node_traits::propagate_on_container_move_assignment::value>());}\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__hash_table& __u, true_type)\n        _NOEXCEPT_(\n            is_nothrow_move_assignable<__pointer_allocator>::value &&\n            is_nothrow_move_assignable<__node_allocator>::value)\n    {\n        __bucket_list_.get_deleter().__alloc() =\n                _VSTD::move(__u.__bucket_list_.get_deleter().__alloc());\n        __node_alloc() = _VSTD::move(__u.__node_alloc());\n    }\n    _LIBCPP_INLINE_VISIBILITY\n        void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}\n\n    void __deallocate(__node_pointer __np) _NOEXCEPT;\n    __node_pointer __detach() _NOEXCEPT;\n\n    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;\n    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;\n};\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table()\n    _NOEXCEPT_(\n        is_nothrow_default_constructible<__bucket_list>::value &&\n        is_nothrow_default_constructible<__first_node>::value &&\n        is_nothrow_default_constructible<hasher>::value &&\n        is_nothrow_default_constructible<key_equal>::value)\n    : __p2_(0),\n      __p3_(1.0f)\n{\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,\n                                                       const key_equal& __eql)\n    : __bucket_list_(nullptr, __bucket_list_deleter()),\n      __p1_(),\n      __p2_(0, __hf),\n      __p3_(1.0f, __eql)\n{\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,\n                                                       const key_equal& __eql,\n                                                       const allocator_type& __a)\n    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),\n      __p1_(__node_allocator(__a)),\n      __p2_(0, __hf),\n      __p3_(1.0f, __eql)\n{\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a)\n    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),\n      __p1_(__node_allocator(__a)),\n      __p2_(0),\n      __p3_(1.0f)\n{\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u)\n    : __bucket_list_(nullptr,\n          __bucket_list_deleter(allocator_traits<__pointer_allocator>::\n              select_on_container_copy_construction(\n                  __u.__bucket_list_.get_deleter().__alloc()), 0)),\n      __p1_(allocator_traits<__node_allocator>::\n          select_on_container_copy_construction(__u.__node_alloc())),\n      __p2_(0, __u.hash_function()),\n      __p3_(__u.__p3_)\n{\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u,\n                                                       const allocator_type& __a)\n    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),\n      __p1_(__node_allocator(__a)),\n      __p2_(0, __u.hash_function()),\n      __p3_(__u.__p3_)\n{\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u)\n        _NOEXCEPT_(\n            is_nothrow_move_constructible<__bucket_list>::value &&\n            is_nothrow_move_constructible<__first_node>::value &&\n            is_nothrow_move_constructible<hasher>::value &&\n            is_nothrow_move_constructible<key_equal>::value)\n    : __bucket_list_(_VSTD::move(__u.__bucket_list_)),\n      __p1_(_VSTD::move(__u.__p1_)),\n      __p2_(_VSTD::move(__u.__p2_)),\n      __p3_(_VSTD::move(__u.__p3_))\n{\n    if (size() > 0)\n    {\n        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =\n            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));\n        __u.__p1_.first().__next_ = nullptr;\n        __u.size() = 0;\n    }\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u,\n                                                       const allocator_type& __a)\n    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),\n      __p1_(__node_allocator(__a)),\n      __p2_(0, _VSTD::move(__u.hash_function())),\n      __p3_(_VSTD::move(__u.__p3_))\n{\n    if (__a == allocator_type(__u.__node_alloc()))\n    {\n        __bucket_list_.reset(__u.__bucket_list_.release());\n        __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();\n        __u.__bucket_list_.get_deleter().size() = 0;\n        if (__u.size() > 0)\n        {\n            __p1_.first().__next_ = __u.__p1_.first().__next_;\n            __u.__p1_.first().__next_ = nullptr;\n            __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =\n                static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));\n            size() = __u.size();\n            __u.size() = 0;\n        }\n    }\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table()\n{\n    __deallocate(__p1_.first().__next_);\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__erase_c(this);\n#endif\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\nvoid\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc(\n        const __hash_table& __u, true_type)\n{\n    if (__node_alloc() != __u.__node_alloc())\n    {\n        clear();\n        __bucket_list_.reset();\n        __bucket_list_.get_deleter().size() = 0;\n    }\n    __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc();\n    __node_alloc() = __u.__node_alloc();\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>&\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u)\n{\n    if (this != &__u)\n    {\n        __copy_assign_alloc(__u);\n        hash_function() = __u.hash_function();\n        key_eq() = __u.key_eq();\n        max_load_factor() = __u.max_load_factor();\n        __assign_multi(__u.begin(), __u.end());\n    }\n    return *this;\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\nvoid\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate(__node_pointer __np)\n    _NOEXCEPT\n{\n    __node_allocator& __na = __node_alloc();\n    while (__np != nullptr)\n    {\n        __node_pointer __next = __np->__next_;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __c_node* __c = __get_db()->__find_c_and_lock(this);\n        for (__i_node** __p = __c->end_; __p != __c->beg_; )\n        {\n            --__p;\n            iterator* __i = static_cast<iterator*>((*__p)->__i_);\n            if (__i->__node_ == __np)\n            {\n                (*__p)->__c_ = nullptr;\n                if (--__c->end_ != __p)\n                    memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));\n            }\n        }\n        __get_db()->unlock();\n#endif\n        __node_traits::destroy(__na, _VSTD::addressof(__np->__value_));\n        __node_traits::deallocate(__na, __np, 1);\n        __np = __next;\n    }\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_pointer\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT\n{\n    size_type __bc = bucket_count();\n    for (size_type __i = 0; __i < __bc; ++__i)\n        __bucket_list_[__i] = nullptr;\n    size() = 0;\n    __node_pointer __cache = __p1_.first().__next_;\n    __p1_.first().__next_ = nullptr;\n    return __cache;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\nvoid\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(\n        __hash_table& __u, true_type)\n    _NOEXCEPT_(\n        is_nothrow_move_assignable<__node_allocator>::value &&\n        is_nothrow_move_assignable<hasher>::value &&\n        is_nothrow_move_assignable<key_equal>::value)\n{\n    clear();\n    __bucket_list_.reset(__u.__bucket_list_.release());\n    __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();\n    __u.__bucket_list_.get_deleter().size() = 0;\n    __move_assign_alloc(__u);\n    size() = __u.size();\n    hash_function() = _VSTD::move(__u.hash_function());\n    max_load_factor() = __u.max_load_factor();\n    key_eq() = _VSTD::move(__u.key_eq());\n    __p1_.first().__next_ = __u.__p1_.first().__next_;\n    if (size() > 0)\n    {\n        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =\n            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));\n        __u.__p1_.first().__next_ = nullptr;\n        __u.size() = 0;\n    }\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->swap(this, &__u);\n#endif\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\nvoid\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(\n        __hash_table& __u, false_type)\n{\n    if (__node_alloc() == __u.__node_alloc())\n        __move_assign(__u, true_type());\n    else\n    {\n        hash_function() = _VSTD::move(__u.hash_function());\n        key_eq() = _VSTD::move(__u.key_eq());\n        max_load_factor() = __u.max_load_factor();\n        if (bucket_count() != 0)\n        {\n            __node_pointer __cache = __detach();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            try\n            {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n                const_iterator __i = __u.begin();\n                while (__cache != nullptr && __u.size() != 0)\n                {\n                    __cache->__value_ = _VSTD::move(__u.remove(__i++)->__value_);\n                    __node_pointer __next = __cache->__next_;\n                    __node_insert_multi(__cache);\n                    __cache = __next;\n                }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            }\n            catch (...)\n            {\n                __deallocate(__cache);\n                throw;\n            }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            __deallocate(__cache);\n        }\n        const_iterator __i = __u.begin();\n        while (__u.size() != 0)\n        {\n            __node_holder __h =\n                    __construct_node(_VSTD::move(__u.remove(__i++)->__value_));\n            __node_insert_multi(__h.get());\n            __h.release();\n        }\n    }\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\n__hash_table<_Tp, _Hash, _Equal, _Alloc>&\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u)\n    _NOEXCEPT_(\n        __node_traits::propagate_on_container_move_assignment::value &&\n        is_nothrow_move_assignable<__node_allocator>::value &&\n        is_nothrow_move_assignable<hasher>::value &&\n        is_nothrow_move_assignable<key_equal>::value)\n{\n    __move_assign(__u, integral_constant<bool,\n                  __node_traits::propagate_on_container_move_assignment::value>());\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _InputIterator>\nvoid\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first,\n                                                          _InputIterator __last)\n{\n    if (bucket_count() != 0)\n    {\n        __node_pointer __cache = __detach();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (; __cache != nullptr && __first != __last; ++__first)\n            {\n                __cache->__value_ = *__first;\n                __node_pointer __next = __cache->__next_;\n                __node_insert_unique(__cache);\n                __cache = __next;\n            }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            __deallocate(__cache);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        __deallocate(__cache);\n    }\n    for (; __first != __last; ++__first)\n        __insert_unique(*__first);\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _InputIterator>\nvoid\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first,\n                                                         _InputIterator __last)\n{\n    if (bucket_count() != 0)\n    {\n        __node_pointer __cache = __detach();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (; __cache != nullptr && __first != __last; ++__first)\n            {\n                __cache->__value_ = *__first;\n                __node_pointer __next = __cache->__next_;\n                __node_insert_multi(__cache);\n                __cache = __next;\n            }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            __deallocate(__cache);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        __deallocate(__cache);\n    }\n    for (; __first != __last; ++__first)\n        __insert_multi(*__first);\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return iterator(__p1_.first().__next_, this);\n#else\n    return iterator(__p1_.first().__next_);\n#endif\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return iterator(nullptr, this);\n#else\n    return iterator(nullptr);\n#endif\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return const_iterator(__p1_.first().__next_, this);\n#else\n    return const_iterator(__p1_.first().__next_);\n#endif\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return const_iterator(nullptr, this);\n#else\n    return const_iterator(nullptr);\n#endif\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\nvoid\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT\n{\n    if (size() > 0)\n    {\n        __deallocate(__p1_.first().__next_);\n        __p1_.first().__next_ = nullptr;\n        size_type __bc = bucket_count();\n        for (size_type __i = 0; __i < __bc; ++__i)\n            __bucket_list_[__i] = nullptr;\n        size() = 0;\n    }\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\npair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd)\n{\n    __nd->__hash_ = hash_function()(__nd->__value_);\n    size_type __bc = bucket_count();\n    bool __inserted = false;\n    __node_pointer __ndptr;\n    size_t __chash;\n    if (__bc != 0)\n    {\n        __chash = __constrain_hash(__nd->__hash_, __bc);\n        __ndptr = __bucket_list_[__chash];\n        if (__ndptr != nullptr)\n        {\n            for (__ndptr = __ndptr->__next_; __ndptr != nullptr &&\n                                             __constrain_hash(__ndptr->__hash_, __bc) == __chash;\n                                                     __ndptr = __ndptr->__next_)\n            {\n                if (key_eq()(__ndptr->__value_, __nd->__value_))\n                    goto __done;\n            }\n        }\n    }\n    {\n        if (size()+1 > __bc * max_load_factor() || __bc == 0)\n        {\n            rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),\n                           size_type(ceil(float(size() + 1) / max_load_factor()))));\n            __bc = bucket_count();\n            __chash = __constrain_hash(__nd->__hash_, __bc);\n        }\n        // insert_after __bucket_list_[__chash], or __first_node if bucket is null\n        __node_pointer __pn = __bucket_list_[__chash];\n        if (__pn == nullptr)\n        {\n            __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));\n            __nd->__next_ = __pn->__next_;\n            __pn->__next_ = __nd;\n            // fix up __bucket_list_\n            __bucket_list_[__chash] = __pn;\n            if (__nd->__next_ != nullptr)\n                __bucket_list_[__constrain_hash(__nd->__next_->__hash_, __bc)] = __nd;\n        }\n        else\n        {\n            __nd->__next_ = __pn->__next_;\n            __pn->__next_ = __nd;\n        }\n        __ndptr = __nd;\n        // increment size\n        ++size();\n        __inserted = true;\n    }\n__done:\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return pair<iterator, bool>(iterator(__ndptr, this), __inserted);\n#else\n    return pair<iterator, bool>(iterator(__ndptr), __inserted);\n#endif\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp)\n{\n    __cp->__hash_ = hash_function()(__cp->__value_);\n    size_type __bc = bucket_count();\n    if (size()+1 > __bc * max_load_factor() || __bc == 0)\n    {\n        rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),\n                       size_type(ceil(float(size() + 1) / max_load_factor()))));\n        __bc = bucket_count();\n    }\n    size_t __chash = __constrain_hash(__cp->__hash_, __bc);\n    __node_pointer __pn = __bucket_list_[__chash];\n    if (__pn == nullptr)\n    {\n        __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));\n        __cp->__next_ = __pn->__next_;\n        __pn->__next_ = __cp;\n        // fix up __bucket_list_\n        __bucket_list_[__chash] = __pn;\n        if (__cp->__next_ != nullptr)\n            __bucket_list_[__constrain_hash(__cp->__next_->__hash_, __bc)] = __cp;\n    }\n    else\n    {\n        for (bool __found = false; __pn->__next_ != nullptr &&\n                                   __constrain_hash(__pn->__next_->__hash_, __bc) == __chash;\n                                                           __pn = __pn->__next_)\n        {\n            //      __found    key_eq()     action\n            //      false       false       loop\n            //      true        true        loop\n            //      false       true        set __found to true\n            //      true        false       break\n            if (__found != (__pn->__next_->__hash_ == __cp->__hash_ &&\n                            key_eq()(__pn->__next_->__value_, __cp->__value_)))\n            {\n                if (!__found)\n                    __found = true;\n                else\n                    break;\n            }\n        }\n        __cp->__next_ = __pn->__next_;\n        __pn->__next_ = __cp;\n        if (__cp->__next_ != nullptr)\n        {\n            size_t __nhash = __constrain_hash(__cp->__next_->__hash_, __bc);\n            if (__nhash != __chash)\n                __bucket_list_[__nhash] = __cp;\n        }\n    }\n    ++size();\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return iterator(__cp, this);\n#else\n    return iterator(__cp);\n#endif\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(\n        const_iterator __p, __node_pointer __cp)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n        \"unordered container::emplace_hint(const_iterator, args...) called with an iterator not\"\n        \" referring to this unordered container\");\n#endif\n    if (__p != end() && key_eq()(*__p, __cp->__value_))\n    {\n        __node_pointer __np = __p.__node_;\n        __cp->__hash_ = __np->__hash_;\n        size_type __bc = bucket_count();\n        if (size()+1 > __bc * max_load_factor() || __bc == 0)\n        {\n            rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),\n                           size_type(ceil(float(size() + 1) / max_load_factor()))));\n            __bc = bucket_count();\n        }\n        size_t __chash = __constrain_hash(__cp->__hash_, __bc);\n        __node_pointer __pp = __bucket_list_[__chash];\n        while (__pp->__next_ != __np)\n            __pp = __pp->__next_;\n        __cp->__next_ = __np;\n        __pp->__next_ = __cp;\n        ++size();\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        return iterator(__cp, this);\n#else\n        return iterator(__cp);\n#endif\n    }\n    return __node_insert_multi(__cp);\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\npair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(const value_type& __x)\n{\n    return __insert_unique_value(__x);\n}\n\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _ValueTp>\n_LIBCPP_INLINE_VISIBILITY\npair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique_value(_ValueTp&& __x)\n#else\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\n_LIBCPP_INLINE_VISIBILITY\npair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique_value(const value_type& __x)\n#endif\n{\n#if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n    typedef const value_type& _ValueTp;\n#endif\n    size_t __hash = hash_function()(__x);\n    size_type __bc = bucket_count();\n    bool __inserted = false;\n    __node_pointer __nd;\n    size_t __chash;\n    if (__bc != 0)\n    {\n        __chash = __constrain_hash(__hash, __bc);\n        __nd = __bucket_list_[__chash];\n        if (__nd != nullptr)\n        {\n            for (__nd = __nd->__next_; __nd != nullptr &&\n                                       __constrain_hash(__nd->__hash_, __bc) == __chash;\n                                                           __nd = __nd->__next_)\n            {\n                if (key_eq()(__nd->__value_, __x))\n                    goto __done;\n            }\n        }\n    }\n    {\n        __node_holder __h = __construct_node(_VSTD::forward<_ValueTp>(__x), __hash);\n        if (size()+1 > __bc * max_load_factor() || __bc == 0)\n        {\n            rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),\n                           size_type(ceil(float(size() + 1) / max_load_factor()))));\n            __bc = bucket_count();\n            __chash = __constrain_hash(__hash, __bc);\n        }\n        // insert_after __bucket_list_[__chash], or __first_node if bucket is null\n        __node_pointer __pn = __bucket_list_[__chash];\n        if (__pn == nullptr)\n        {\n            __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));\n            __h->__next_ = __pn->__next_;\n            __pn->__next_ = __h.get();\n            // fix up __bucket_list_\n            __bucket_list_[__chash] = __pn;\n            if (__h->__next_ != nullptr)\n                __bucket_list_[__constrain_hash(__h->__next_->__hash_, __bc)] = __h.get();\n        }\n        else\n        {\n            __h->__next_ = __pn->__next_;\n            __pn->__next_ = __h.get();\n        }\n        __nd = __h.release();\n        // increment size\n        ++size();\n        __inserted = true;\n    }\n__done:\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return pair<iterator, bool>(iterator(__nd, this), __inserted);\n#else\n    return pair<iterator, bool>(iterator(__nd), __inserted);\n#endif\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class... _Args>\npair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique(_Args&&... __args)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);\n    pair<iterator, bool> __r = __node_insert_unique(__h.get());\n    if (__r.second)\n        __h.release();\n    return __r;\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class... _Args>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);\n    iterator __r = __node_insert_multi(__h.get());\n    __h.release();\n    return __r;\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class... _Args>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(\n        const_iterator __p, _Args&&... __args)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n        \"unordered container::emplace_hint(const_iterator, args...) called with an iterator not\"\n        \" referring to this unordered container\");\n#endif\n    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);\n    iterator __r = __node_insert_multi(__p, __h.get());\n    __h.release();\n    return __r;\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\npair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(value_type&& __x)\n{\n    return __insert_unique_value(_VSTD::move(__x));\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _Pp>\npair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(_Pp&& __x)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));\n    pair<iterator, bool> __r = __node_insert_unique(__h.get());\n    if (__r.second)\n        __h.release();\n    return __r;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _Pp>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(_Pp&& __x)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));\n    iterator __r = __node_insert_multi(__h.get());\n    __h.release();\n    return __r;\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _Pp>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p,\n                                                         _Pp&& __x)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n        \"unordered container::insert(const_iterator, rvalue) called with an iterator not\"\n        \" referring to this unordered container\");\n#endif\n    __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));\n    iterator __r = __node_insert_multi(__p, __h.get());\n    __h.release();\n    return __r;\n}\n\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const value_type& __x)\n{\n    __node_holder __h = __construct_node(__x);\n    iterator __r = __node_insert_multi(__h.get());\n    __h.release();\n    return __r;\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p,\n                                                         const value_type& __x)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n        \"unordered container::insert(const_iterator, lvalue) called with an iterator not\"\n        \" referring to this unordered container\");\n#endif\n    __node_holder __h = __construct_node(__x);\n    iterator __r = __node_insert_multi(__p, __h.get());\n    __h.release();\n    return __r;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\nvoid\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n)\n{\n    if (__n == 1)\n        __n = 2;\n    else if (__n & (__n - 1))\n        __n = __next_prime(__n);\n    size_type __bc = bucket_count();\n    if (__n > __bc)\n        __rehash(__n);\n    else if (__n < __bc)\n    {\n        __n = _VSTD::max<size_type>\n              (\n                  __n,\n                  __is_hash_power2(__bc) ? __next_hash_pow2(size_t(ceil(float(size()) / max_load_factor()))) :\n                                           __next_prime(size_t(ceil(float(size()) / max_load_factor())))\n              );\n        if (__n < __bc)\n            __rehash(__n);\n    }\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\nvoid\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__invalidate_all(this);\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n    __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();\n    __bucket_list_.reset(__nbc > 0 ?\n                      __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);\n    __bucket_list_.get_deleter().size() = __nbc;\n    if (__nbc > 0)\n    {\n        for (size_type __i = 0; __i < __nbc; ++__i)\n            __bucket_list_[__i] = nullptr;\n        __node_pointer __pp(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())));\n        __node_pointer __cp = __pp->__next_;\n        if (__cp != nullptr)\n        {\n            size_type __chash = __constrain_hash(__cp->__hash_, __nbc);\n            __bucket_list_[__chash] = __pp;\n            size_type __phash = __chash;\n            for (__pp = __cp, __cp = __cp->__next_; __cp != nullptr;\n                                                           __cp = __pp->__next_)\n            {\n                __chash = __constrain_hash(__cp->__hash_, __nbc);\n                if (__chash == __phash)\n                    __pp = __cp;\n                else\n                {\n                    if (__bucket_list_[__chash] == nullptr)\n                    {\n                        __bucket_list_[__chash] = __pp;\n                        __pp = __cp;\n                        __phash = __chash;\n                    }\n                    else\n                    {\n                        __node_pointer __np = __cp;\n                        for (; __np->__next_ != nullptr &&\n                               key_eq()(__cp->__value_, __np->__next_->__value_);\n                                                           __np = __np->__next_)\n                            ;\n                        __pp->__next_ = __np->__next_;\n                        __np->__next_ = __bucket_list_[__chash]->__next_;\n                        __bucket_list_[__chash]->__next_ = __cp;\n\n                    }\n                }\n            }\n        }\n    }\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _Key>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k)\n{\n    size_t __hash = hash_function()(__k);\n    size_type __bc = bucket_count();\n    if (__bc != 0)\n    {\n        size_t __chash = __constrain_hash(__hash, __bc);\n        __node_pointer __nd = __bucket_list_[__chash];\n        if (__nd != nullptr)\n        {\n            for (__nd = __nd->__next_; __nd != nullptr &&\n                                       __constrain_hash(__nd->__hash_, __bc) == __chash;\n                                                           __nd = __nd->__next_)\n            {\n                if (key_eq()(__nd->__value_, __k))\n#if _LIBCPP_DEBUG_LEVEL >= 2\n                    return iterator(__nd, this);\n#else\n                    return iterator(__nd);\n#endif\n            }\n        }\n    }\n    return end();\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _Key>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const\n{\n    size_t __hash = hash_function()(__k);\n    size_type __bc = bucket_count();\n    if (__bc != 0)\n    {\n        size_t __chash = __constrain_hash(__hash, __bc);\n        __node_const_pointer __nd = __bucket_list_[__chash];\n        if (__nd != nullptr)\n        {\n            for (__nd = __nd->__next_; __nd != nullptr &&\n                                           __constrain_hash(__nd->__hash_, __bc) == __chash;\n                                                           __nd = __nd->__next_)\n            {\n                if (key_eq()(__nd->__value_, __k))\n#if _LIBCPP_DEBUG_LEVEL >= 2\n                    return const_iterator(__nd, this);\n#else\n                    return const_iterator(__nd);\n#endif\n            }\n        }\n\n    }\n    return end();\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class ..._Args>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args)\n{\n    __node_allocator& __na = __node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...);\n    __h.get_deleter().__value_constructed = true;\n    __h->__hash_ = hash_function()(__h->__value_);\n    __h->__next_ = nullptr;\n    return __h;\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(value_type&& __v,\n                                                           size_t __hash)\n{\n    __node_allocator& __na = __node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::move(__v));\n    __h.get_deleter().__value_constructed = true;\n    __h->__hash_ = __hash;\n    __h->__next_ = nullptr;\n    return __h;\n}\n\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const value_type& __v)\n{\n    __node_allocator& __na = __node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v);\n    __h.get_deleter().__value_constructed = true;\n    __h->__hash_ = hash_function()(__h->__value_);\n    __h->__next_ = nullptr;\n    return _VSTD::move(__h);  // explicitly moved for C++03\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const value_type& __v,\n                                                           size_t __hash)\n{\n    __node_allocator& __na = __node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v);\n    __h.get_deleter().__value_constructed = true;\n    __h->__hash_ = __hash;\n    __h->__next_ = nullptr;\n    return _VSTD::move(__h);  // explicitly moved for C++03\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p)\n{\n    __node_pointer __np = __p.__node_;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n        \"unordered container erase(iterator) called with an iterator not\"\n        \" referring to this container\");\n    _LIBCPP_ASSERT(__p != end(),\n        \"unordered container erase(iterator) called with a non-dereferenceable iterator\");\n    iterator __r(__np, this);\n#else\n    iterator __r(__np);\n#endif\n    ++__r;\n    remove(__p);\n    return __r;\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first,\n                                                const_iterator __last)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,\n        \"unodered container::erase(iterator, iterator) called with an iterator not\"\n        \" referring to this unodered container\");\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this,\n        \"unodered container::erase(iterator, iterator) called with an iterator not\"\n        \" referring to this unodered container\");\n#endif\n    for (const_iterator __p = __first; __first != __last; __p = __first)\n    {\n        ++__first;\n        erase(__p);\n    }\n    __node_pointer __np = __last.__node_;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return iterator (__np, this);\n#else\n    return iterator (__np);\n#endif\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _Key>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k)\n{\n    iterator __i = find(__k);\n    if (__i == end())\n        return 0;\n    erase(__i);\n    return 1;\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _Key>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k)\n{\n    size_type __r = 0;\n    iterator __i = find(__k);\n    if (__i != end())\n    {\n        iterator __e = end();\n        do\n        {\n            erase(__i++);\n            ++__r;\n        } while (__i != __e && key_eq()(*__i, __k));\n    }\n    return __r;\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT\n{\n    // current node\n    __node_pointer __cn = __p.__node_;\n    size_type __bc = bucket_count();\n    size_t __chash = __constrain_hash(__cn->__hash_, __bc);\n    // find previous node\n    __node_pointer __pn = __bucket_list_[__chash];\n    for (; __pn->__next_ != __cn; __pn = __pn->__next_)\n        ;\n    // Fix up __bucket_list_\n        // if __pn is not in same bucket (before begin is not in same bucket) &&\n        //    if __cn->__next_ is not in same bucket (nullptr is not in same bucket)\n    if (__pn == static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()))\n                            || __constrain_hash(__pn->__hash_, __bc) != __chash)\n    {\n        if (__cn->__next_ == nullptr || __constrain_hash(__cn->__next_->__hash_, __bc) != __chash)\n            __bucket_list_[__chash] = nullptr;\n    }\n        // if __cn->__next_ is not in same bucket (nullptr is in same bucket)\n    if (__cn->__next_ != nullptr)\n    {\n        size_t __nhash = __constrain_hash(__cn->__next_->__hash_, __bc);\n        if (__nhash != __chash)\n            __bucket_list_[__nhash] = __pn;\n    }\n    // remove __cn\n    __pn->__next_ = __cn->__next_;\n    __cn->__next_ = nullptr;\n    --size();\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __c_node* __c = __get_db()->__find_c_and_lock(this);\n    for (__i_node** __p = __c->end_; __p != __c->beg_; )\n    {\n        --__p;\n        iterator* __i = static_cast<iterator*>((*__p)->__i_);\n        if (__i->__node_ == __cn)\n        {\n            (*__p)->__c_ = nullptr;\n            if (--__c->end_ != __p)\n                memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));\n        }\n    }\n    __get_db()->unlock();\n#endif\n    return __node_holder(__cn, _Dp(__node_alloc(), true));\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _Key>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const\n{\n    return static_cast<size_type>(find(__k) != end());\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _Key>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const\n{\n    size_type __r = 0;\n    const_iterator __i = find(__k);\n    if (__i != end())\n    {\n        const_iterator __e = end();\n        do\n        {\n            ++__i;\n            ++__r;\n        } while (__i != __e && key_eq()(*__i, __k));\n    }\n    return __r;\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _Key>\npair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,\n     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(\n        const _Key& __k)\n{\n    iterator __i = find(__k);\n    iterator __j = __i;\n    if (__i != end())\n        ++__j;\n    return pair<iterator, iterator>(__i, __j);\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _Key>\npair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,\n     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(\n        const _Key& __k) const\n{\n    const_iterator __i = find(__k);\n    const_iterator __j = __i;\n    if (__i != end())\n        ++__j;\n    return pair<const_iterator, const_iterator>(__i, __j);\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _Key>\npair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,\n     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(\n        const _Key& __k)\n{\n    iterator __i = find(__k);\n    iterator __j = __i;\n    if (__i != end())\n    {\n        iterator __e = end();\n        do\n        {\n            ++__j;\n        } while (__j != __e && key_eq()(*__j, __k));\n    }\n    return pair<iterator, iterator>(__i, __j);\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntemplate <class _Key>\npair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,\n     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(\n        const _Key& __k) const\n{\n    const_iterator __i = find(__k);\n    const_iterator __j = __i;\n    if (__i != end())\n    {\n        const_iterator __e = end();\n        do\n        {\n            ++__j;\n        } while (__j != __e && key_eq()(*__j, __k));\n    }\n    return pair<const_iterator, const_iterator>(__i, __j);\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\nvoid\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)\n#if _LIBCPP_STD_VER <= 11\n    _NOEXCEPT_(\n        __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value\n        && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value\n              || __is_nothrow_swappable<__pointer_allocator>::value)\n        && (!__node_traits::propagate_on_container_swap::value\n              || __is_nothrow_swappable<__node_allocator>::value)\n            )\n#else\n  _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value)\n#endif\n{\n    {\n    __node_pointer_pointer __npp = __bucket_list_.release();\n    __bucket_list_.reset(__u.__bucket_list_.release());\n    __u.__bucket_list_.reset(__npp);\n    }\n    _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size());\n    __swap_allocator(__bucket_list_.get_deleter().__alloc(),\n             __u.__bucket_list_.get_deleter().__alloc());\n    __swap_allocator(__node_alloc(), __u.__node_alloc());\n    _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_);\n    __p2_.swap(__u.__p2_);\n    __p3_.swap(__u.__p3_);\n    if (size() > 0)\n        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =\n            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));\n    if (__u.size() > 0)\n        __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash_, __u.bucket_count())] =\n            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__u.__p1_.first()));\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->swap(this, &__u);\n#endif\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ntypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const\n{\n    _LIBCPP_ASSERT(__n < bucket_count(),\n        \"unordered container::bucket_size(n) called with n >= bucket_count()\");\n    __node_const_pointer __np = __bucket_list_[__n];\n    size_type __bc = bucket_count();\n    size_type __r = 0;\n    if (__np != nullptr)\n    {\n        for (__np = __np->__next_; __np != nullptr &&\n                                   __constrain_hash(__np->__hash_, __bc) == __n;\n                                                    __np = __np->__next_, ++__r)\n            ;\n    }\n    return __r;\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x,\n     __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\nbool\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const\n{\n    return __i->__node_ != nullptr;\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\nbool\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const\n{\n    return false;\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\nbool\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const\n{\n    return false;\n}\n\ntemplate <class _Tp, class _Hash, class _Equal, class _Alloc>\nbool\n__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const\n{\n    return false;\n}\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP__HASH_TABLE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__locale",
    "content": "// -*- C++ -*-\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP___LOCALE\n#define _LIBCPP___LOCALE\n\n#include <__config>\n#include <string>\n#include <memory>\n#include <utility>\n#include <mutex>\n#include <cstdint>\n#include <cctype>\n#include <locale.h>\n#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)\n# include <support/win32/locale_win32.h>\n#elif defined(_AIX)\n# include <support/ibm/xlocale.h>\n#elif defined(__ANDROID__)\n// Android gained the locale aware functions in L (API level 21)\n# include <android/api-level.h>\n# if __ANDROID_API__ <= 20\n#  include <support/android/locale_bionic.h>\n# endif\n#elif defined(__sun__)\n# include <xlocale.h>\n# include <support/solaris/xlocale.h>\n#elif defined(_NEWLIB_VERSION)\n# include <support/newlib/xlocale.h>\n#elif (defined(__GLIBC__) || defined(__APPLE__)      || defined(__FreeBSD__) \\\n    || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))\n# include <xlocale.h>\n#endif // __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || __EMSCRIPTEN__ || __IBMCPP__\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nclass _LIBCPP_TYPE_VIS locale;\n\ntemplate <class _Facet>\n_LIBCPP_INLINE_VISIBILITY\nbool\nhas_facet(const locale&) _NOEXCEPT;\n\ntemplate <class _Facet>\n_LIBCPP_INLINE_VISIBILITY\nconst _Facet&\nuse_facet(const locale&);\n\nclass _LIBCPP_TYPE_VIS locale\n{\npublic:\n    // types:\n    class _LIBCPP_TYPE_VIS facet;\n    class _LIBCPP_TYPE_VIS id;\n\n    typedef int category;\n    static const category // values assigned here are for exposition only\n        none     = 0,\n        collate  = LC_COLLATE_MASK,\n        ctype    = LC_CTYPE_MASK,\n        monetary = LC_MONETARY_MASK,\n        numeric  = LC_NUMERIC_MASK,\n        time     = LC_TIME_MASK,\n        messages = LC_MESSAGES_MASK,\n        all = collate | ctype | monetary | numeric | time | messages;\n\n    // construct/copy/destroy:\n    locale()  _NOEXCEPT;\n    locale(const locale&)  _NOEXCEPT;\n    explicit locale(const char*);\n    explicit locale(const string&);\n    locale(const locale&, const char*, category);\n    locale(const locale&, const string&, category);\n    template <class _Facet>\n        _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);\n    locale(const locale&, const locale&, category);\n\n    ~locale();\n\n    const locale& operator=(const locale&)  _NOEXCEPT;\n\n    template <class _Facet> locale combine(const locale&) const;\n\n    // locale operations:\n    string name() const;\n    bool operator==(const locale&) const;\n    bool operator!=(const locale& __y) const {return !(*this == __y);}\n    template <class _CharT, class _Traits, class _Allocator>\n      bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,\n                      const basic_string<_CharT, _Traits, _Allocator>&) const;\n\n    // global locale objects:\n    static locale global(const locale&);\n    static const locale& classic();\n\nprivate:\n    class __imp;\n    __imp* __locale_;\n\n    void __install_ctor(const locale&, facet*, long);\n    static locale& __global();\n    bool has_facet(id&) const;\n    const facet* use_facet(id&) const;\n\n    template <class _Facet> friend bool has_facet(const locale&)  _NOEXCEPT;\n    template <class _Facet> friend const _Facet& use_facet(const locale&);\n};\n\nclass _LIBCPP_TYPE_VIS locale::facet\n    : public __shared_count\n{\nprotected:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit facet(size_t __refs = 0)\n        : __shared_count(static_cast<long>(__refs)-1) {}\n\n    virtual ~facet();\n\n//    facet(const facet&) = delete;     // effectively done in __shared_count\n//    void operator=(const facet&) = delete;\nprivate:\n    virtual void __on_zero_shared() _NOEXCEPT;\n};\n\nclass _LIBCPP_TYPE_VIS locale::id\n{\n    once_flag      __flag_;\n    int32_t        __id_;\n\n    static int32_t __next_id;\npublic:\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {}\nprivate:\n    void __init();\n    void operator=(const id&); // = delete;\n    id(const id&); // = delete;\npublic:  // only needed for tests\n    long __get();\n\n    friend class locale;\n    friend class locale::__imp;\n};\n\ntemplate <class _Facet>\ninline _LIBCPP_INLINE_VISIBILITY\nlocale::locale(const locale& __other, _Facet* __f)\n{\n    __install_ctor(__other, __f, __f ? __f->id.__get() : 0);\n}\n\ntemplate <class _Facet>\nlocale\nlocale::combine(const locale& __other) const\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (!_VSTD::has_facet<_Facet>(__other))\n        throw runtime_error(\"locale::combine: locale missing facet\");\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));\n}\n\ntemplate <class _Facet>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nhas_facet(const locale& __l)  _NOEXCEPT\n{\n    return __l.has_facet(_Facet::id);\n}\n\ntemplate <class _Facet>\ninline _LIBCPP_INLINE_VISIBILITY\nconst _Facet&\nuse_facet(const locale& __l)\n{\n    return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));\n}\n\n// template <class _CharT> class collate;\n\ntemplate <class _CharT>\nclass _LIBCPP_TYPE_VIS_ONLY collate\n    : public locale::facet\n{\npublic:\n    typedef _CharT char_type;\n    typedef basic_string<char_type> string_type;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit collate(size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    int compare(const char_type* __lo1, const char_type* __hi1,\n                const char_type* __lo2, const char_type* __hi2) const\n    {\n        return do_compare(__lo1, __hi1, __lo2, __hi2);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    string_type transform(const char_type* __lo, const char_type* __hi) const\n    {\n        return do_transform(__lo, __hi);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    long hash(const char_type* __lo, const char_type* __hi) const\n    {\n        return do_hash(__lo, __hi);\n    }\n\n    static locale::id id;\n\nprotected:\n    ~collate();\n    virtual int do_compare(const char_type* __lo1, const char_type* __hi1,\n                           const char_type* __lo2, const char_type* __hi2) const;\n    virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const\n        {return string_type(__lo, __hi);}\n    virtual long do_hash(const char_type* __lo, const char_type* __hi) const;\n};\n\ntemplate <class _CharT> locale::id collate<_CharT>::id;\n\ntemplate <class _CharT>\ncollate<_CharT>::~collate()\n{\n}\n\ntemplate <class _CharT>\nint\ncollate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,\n                            const char_type* __lo2, const char_type* __hi2) const\n{\n    for (; __lo2 != __hi2; ++__lo1, ++__lo2)\n    {\n        if (__lo1 == __hi1 || *__lo1 < *__lo2)\n            return -1;\n        if (*__lo2 < *__lo1)\n            return 1;\n    }\n    return __lo1 != __hi1;\n}\n\ntemplate <class _CharT>\nlong\ncollate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const\n{\n    size_t __h = 0;\n    const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;\n    const size_t __mask = size_t(0xF) << (__sr + 4);\n    for(const char_type* __p = __lo; __p != __hi; ++__p)\n    {\n        __h = (__h << 4) + static_cast<size_t>(*__p);\n        size_t __g = __h & __mask;\n        __h ^= __g | (__g >> __sr);\n    }\n    return static_cast<long>(__h);\n}\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<char>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<wchar_t>)\n\n// template <class CharT> class collate_byname;\n\ntemplate <class _CharT> class _LIBCPP_TYPE_VIS_ONLY collate_byname;\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS collate_byname<char>\n    : public collate<char>\n{\n    locale_t __l;\npublic:\n    typedef char char_type;\n    typedef basic_string<char_type> string_type;\n\n    explicit collate_byname(const char* __n, size_t __refs = 0);\n    explicit collate_byname(const string& __n, size_t __refs = 0);\n\nprotected:\n    ~collate_byname();\n    virtual int do_compare(const char_type* __lo1, const char_type* __hi1,\n                           const char_type* __lo2, const char_type* __hi2) const;\n    virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS collate_byname<wchar_t>\n    : public collate<wchar_t>\n{\n    locale_t __l;\npublic:\n    typedef wchar_t char_type;\n    typedef basic_string<char_type> string_type;\n\n    explicit collate_byname(const char* __n, size_t __refs = 0);\n    explicit collate_byname(const string& __n, size_t __refs = 0);\n\nprotected:\n    ~collate_byname();\n\n    virtual int do_compare(const char_type* __lo1, const char_type* __hi1,\n                           const char_type* __lo2, const char_type* __hi2) const;\n    virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;\n};\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbool\nlocale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,\n                   const basic_string<_CharT, _Traits, _Allocator>& __y) const\n{\n    return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(\n                                       __x.data(), __x.data() + __x.size(),\n                                       __y.data(), __y.data() + __y.size()) < 0;\n}\n\n// template <class charT> class ctype\n\nclass _LIBCPP_TYPE_VIS ctype_base\n{\npublic:\n#ifdef __GLIBC__\n    typedef unsigned short mask;\n    static const mask space  = _ISspace;\n    static const mask print  = _ISprint;\n    static const mask cntrl  = _IScntrl;\n    static const mask upper  = _ISupper;\n    static const mask lower  = _ISlower;\n    static const mask alpha  = _ISalpha;\n    static const mask digit  = _ISdigit;\n    static const mask punct  = _ISpunct;\n    static const mask xdigit = _ISxdigit;\n    static const mask blank  = _ISblank;\n#elif defined(_WIN32)\n    typedef unsigned short mask;\n    static const mask space  = _SPACE;\n    static const mask print  = _BLANK|_PUNCT|_ALPHA|_DIGIT;\n    static const mask cntrl  = _CONTROL;\n    static const mask upper  = _UPPER;\n    static const mask lower  = _LOWER;\n    static const mask alpha  = _ALPHA;\n    static const mask digit  = _DIGIT;\n    static const mask punct  = _PUNCT;\n    static const mask xdigit = _HEX;\n    static const mask blank  = _BLANK;\n# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT\n#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)\n# ifdef __APPLE__\n    typedef __uint32_t mask;\n# elif defined(__FreeBSD__)\n    typedef unsigned long mask;\n# elif defined(__EMSCRIPTEN__) ||  defined(__NetBSD__)\n    typedef unsigned short mask;\n# endif\n    static const mask space  = _CTYPE_S;\n    static const mask print  = _CTYPE_R;\n    static const mask cntrl  = _CTYPE_C;\n    static const mask upper  = _CTYPE_U;\n    static const mask lower  = _CTYPE_L;\n    static const mask alpha  = _CTYPE_A;\n    static const mask digit  = _CTYPE_D;\n    static const mask punct  = _CTYPE_P;\n    static const mask xdigit = _CTYPE_X;\n\n# if defined(__NetBSD__)\n    static const mask blank  = _CTYPE_BL;\n# else\n    static const mask blank  = _CTYPE_B;\n# endif\n#elif defined(__sun__) || defined(_AIX)\n    typedef unsigned int mask;\n    static const mask space  = _ISSPACE;\n    static const mask print  = _ISPRINT;\n    static const mask cntrl  = _ISCNTRL;\n    static const mask upper  = _ISUPPER;\n    static const mask lower  = _ISLOWER;\n    static const mask alpha  = _ISALPHA;\n    static const mask digit  = _ISDIGIT;\n    static const mask punct  = _ISPUNCT;\n    static const mask xdigit = _ISXDIGIT;\n    static const mask blank  = _ISBLANK;\n#elif defined(_NEWLIB_VERSION)\n    // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.\n    typedef char mask;\n    static const mask space  = _S;\n    static const mask print  = _P | _U | _L | _N | _B;\n    static const mask cntrl  = _C;\n    static const mask upper  = _U;\n    static const mask lower  = _L;\n    static const mask alpha  = _U | _L;\n    static const mask digit  = _N;\n    static const mask punct  = _P;\n    static const mask xdigit = _X | _N;\n    static const mask blank  = _B;\n# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT\n# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA\n# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT\n#else\n    typedef unsigned long mask;\n    static const mask space  = 1<<0;\n    static const mask print  = 1<<1;\n    static const mask cntrl  = 1<<2;\n    static const mask upper  = 1<<3;\n    static const mask lower  = 1<<4;\n    static const mask alpha  = 1<<5;\n    static const mask digit  = 1<<6;\n    static const mask punct  = 1<<7;\n    static const mask xdigit = 1<<8;\n    static const mask blank  = 1<<9;\n#endif\n    static const mask alnum  = alpha | digit;\n    static const mask graph  = alnum | punct;\n\n    _LIBCPP_ALWAYS_INLINE ctype_base() {}\n};\n\ntemplate <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype;\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS ctype<wchar_t>\n    : public locale::facet,\n      public ctype_base\n{\npublic:\n    typedef wchar_t char_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit ctype(size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    bool is(mask __m, char_type __c) const\n    {\n        return do_is(__m, __c);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const\n    {\n        return do_is(__low, __high, __vec);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const\n    {\n        return do_scan_is(__m, __low, __high);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const\n    {\n        return do_scan_not(__m, __low, __high);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    char_type toupper(char_type __c) const\n    {\n        return do_toupper(__c);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    const char_type* toupper(char_type* __low, const char_type* __high) const\n    {\n        return do_toupper(__low, __high);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    char_type tolower(char_type __c) const\n    {\n        return do_tolower(__c);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    const char_type* tolower(char_type* __low, const char_type* __high) const\n    {\n        return do_tolower(__low, __high);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    char_type widen(char __c) const\n    {\n        return do_widen(__c);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    const char* widen(const char* __low, const char* __high, char_type* __to) const\n    {\n        return do_widen(__low, __high, __to);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    char narrow(char_type __c, char __dfault) const\n    {\n        return do_narrow(__c, __dfault);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const\n    {\n        return do_narrow(__low, __high, __dfault, __to);\n    }\n\n    static locale::id id;\n\nprotected:\n    ~ctype();\n    virtual bool do_is(mask __m, char_type __c) const;\n    virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;\n    virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;\n    virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;\n    virtual char_type do_toupper(char_type) const;\n    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;\n    virtual char_type do_tolower(char_type) const;\n    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;\n    virtual char_type do_widen(char) const;\n    virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;\n    virtual char do_narrow(char_type, char __dfault) const;\n    virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS ctype<char>\n    : public locale::facet, public ctype_base\n{\n    const mask* __tab_;\n    bool        __del_;\npublic:\n    typedef char char_type;\n\n    explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);\n\n    _LIBCPP_ALWAYS_INLINE\n    bool is(mask __m, char_type __c) const\n    {\n        return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const\n    {\n        for (; __low != __high; ++__low, ++__vec)\n            *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;\n        return __low;\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const\n    {\n        for (; __low != __high; ++__low)\n            if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))\n                break;\n        return __low;\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const\n    {\n        for (; __low != __high; ++__low)\n            if (!(isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)))\n                break;\n        return __low;\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    char_type toupper(char_type __c) const\n    {\n        return do_toupper(__c);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    const char_type* toupper(char_type* __low, const char_type* __high) const\n    {\n        return do_toupper(__low, __high);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    char_type tolower(char_type __c) const\n    {\n        return do_tolower(__c);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    const char_type* tolower(char_type* __low, const char_type* __high) const\n    {\n        return do_tolower(__low, __high);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    char_type widen(char __c) const\n    {\n        return do_widen(__c);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    const char* widen(const char* __low, const char* __high, char_type* __to) const\n    {\n        return do_widen(__low, __high, __to);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    char narrow(char_type __c, char __dfault) const\n    {\n        return do_narrow(__c, __dfault);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const\n    {\n        return do_narrow(__low, __high, __dfault, __to);\n    }\n\n    static locale::id id;\n\n#ifdef _CACHED_RUNES\n    static const size_t table_size = _CACHED_RUNES;\n#else\n    static const size_t table_size = 256;  // FIXME: Don't hardcode this.\n#endif\n    _LIBCPP_ALWAYS_INLINE const mask* table() const  _NOEXCEPT {return __tab_;}\n    static const mask* classic_table()  _NOEXCEPT;\n#if defined(__GLIBC__) || defined(__EMSCRIPTEN__)\n    static const int* __classic_upper_table() _NOEXCEPT;\n    static const int* __classic_lower_table() _NOEXCEPT;\n#endif\n#if defined(__NetBSD__)\n    static const short* __classic_upper_table() _NOEXCEPT;\n    static const short* __classic_lower_table() _NOEXCEPT;\n#endif\n\nprotected:\n    ~ctype();\n    virtual char_type do_toupper(char_type __c) const;\n    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;\n    virtual char_type do_tolower(char_type __c) const;\n    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;\n    virtual char_type do_widen(char __c) const;\n    virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;\n    virtual char do_narrow(char_type __c, char __dfault) const;\n    virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;\n};\n\n// template <class CharT> class ctype_byname;\n\ntemplate <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype_byname;\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS ctype_byname<char>\n    : public ctype<char>\n{\n    locale_t __l;\n\npublic:\n    explicit ctype_byname(const char*, size_t = 0);\n    explicit ctype_byname(const string&, size_t = 0);\n\nprotected:\n    ~ctype_byname();\n    virtual char_type do_toupper(char_type) const;\n    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;\n    virtual char_type do_tolower(char_type) const;\n    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS ctype_byname<wchar_t>\n    : public ctype<wchar_t>\n{\n    locale_t __l;\n\npublic:\n    explicit ctype_byname(const char*, size_t = 0);\n    explicit ctype_byname(const string&, size_t = 0);\n\nprotected:\n    ~ctype_byname();\n    virtual bool do_is(mask __m, char_type __c) const;\n    virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;\n    virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;\n    virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;\n    virtual char_type do_toupper(char_type) const;\n    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;\n    virtual char_type do_tolower(char_type) const;\n    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;\n    virtual char_type do_widen(char) const;\n    virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;\n    virtual char do_narrow(char_type, char __dfault) const;\n    virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;\n};\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nisspace(_CharT __c, const locale& __loc)\n{\n    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nisprint(_CharT __c, const locale& __loc)\n{\n    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\niscntrl(_CharT __c, const locale& __loc)\n{\n    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nisupper(_CharT __c, const locale& __loc)\n{\n    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nislower(_CharT __c, const locale& __loc)\n{\n    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nisalpha(_CharT __c, const locale& __loc)\n{\n    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nisdigit(_CharT __c, const locale& __loc)\n{\n    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nispunct(_CharT __c, const locale& __loc)\n{\n    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nisxdigit(_CharT __c, const locale& __loc)\n{\n    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nisalnum(_CharT __c, const locale& __loc)\n{\n    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nisgraph(_CharT __c, const locale& __loc)\n{\n    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\n_CharT\ntoupper(_CharT __c, const locale& __loc)\n{\n    return use_facet<ctype<_CharT> >(__loc).toupper(__c);\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\n_CharT\ntolower(_CharT __c, const locale& __loc)\n{\n    return use_facet<ctype<_CharT> >(__loc).tolower(__c);\n}\n\n// codecvt_base\n\nclass _LIBCPP_TYPE_VIS codecvt_base\n{\npublic:\n    _LIBCPP_ALWAYS_INLINE codecvt_base() {}\n    enum result {ok, partial, error, noconv};\n};\n\n// template <class internT, class externT, class stateT> class codecvt;\n\ntemplate <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TYPE_VIS_ONLY codecvt;\n\n// template <> class codecvt<char, char, mbstate_t>\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t>\n    : public locale::facet,\n      public codecvt_base\n{\npublic:\n    typedef char      intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit codecvt(size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    result out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const\n    {\n        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    result unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const\n    {\n        return do_unshift(__st, __to, __to_end, __to_nxt);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    result in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const\n    {\n        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    int encoding() const  _NOEXCEPT\n    {\n        return do_encoding();\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    bool always_noconv() const  _NOEXCEPT\n    {\n        return do_always_noconv();\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const\n    {\n        return do_length(__st, __frm, __end, __mx);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    int max_length() const  _NOEXCEPT\n    {\n        return do_max_length();\n    }\n\n    static locale::id id;\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    explicit codecvt(const char*, size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    ~codecvt();\n\n    virtual result do_out(state_type& __st,\n                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result do_in(state_type& __st,\n                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result do_unshift(state_type& __st,\n                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const  _NOEXCEPT;\n    virtual bool do_always_noconv() const  _NOEXCEPT;\n    virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;\n    virtual int do_max_length() const  _NOEXCEPT;\n};\n\n// template <> class codecvt<wchar_t, char, mbstate_t>\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t>\n    : public locale::facet,\n      public codecvt_base\n{\n    locale_t __l;\npublic:\n    typedef wchar_t   intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    explicit codecvt(size_t __refs = 0);\n\n    _LIBCPP_ALWAYS_INLINE\n    result out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const\n    {\n        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    result unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const\n    {\n        return do_unshift(__st, __to, __to_end, __to_nxt);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    result in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const\n    {\n        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    int encoding() const  _NOEXCEPT\n    {\n        return do_encoding();\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    bool always_noconv() const  _NOEXCEPT\n    {\n        return do_always_noconv();\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const\n    {\n        return do_length(__st, __frm, __end, __mx);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    int max_length() const  _NOEXCEPT\n    {\n        return do_max_length();\n    }\n\n    static locale::id id;\n\nprotected:\n    explicit codecvt(const char*, size_t __refs = 0);\n\n    ~codecvt();\n\n    virtual result do_out(state_type& __st,\n                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result do_in(state_type& __st,\n                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result do_unshift(state_type& __st,\n                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const  _NOEXCEPT;\n    virtual bool do_always_noconv() const  _NOEXCEPT;\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;\n    virtual int do_max_length() const  _NOEXCEPT;\n};\n\n// template <> class codecvt<char16_t, char, mbstate_t>\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>\n    : public locale::facet,\n      public codecvt_base\n{\npublic:\n    typedef char16_t  intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit codecvt(size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    result out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const\n    {\n        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    result unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const\n    {\n        return do_unshift(__st, __to, __to_end, __to_nxt);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    result in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const\n    {\n        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    int encoding() const  _NOEXCEPT\n    {\n        return do_encoding();\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    bool always_noconv() const  _NOEXCEPT\n    {\n        return do_always_noconv();\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const\n    {\n        return do_length(__st, __frm, __end, __mx);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    int max_length() const  _NOEXCEPT\n    {\n        return do_max_length();\n    }\n\n    static locale::id id;\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    explicit codecvt(const char*, size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    ~codecvt();\n\n    virtual result do_out(state_type& __st,\n                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result do_in(state_type& __st,\n                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result do_unshift(state_type& __st,\n                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const  _NOEXCEPT;\n    virtual bool do_always_noconv() const  _NOEXCEPT;\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;\n    virtual int do_max_length() const  _NOEXCEPT;\n};\n\n// template <> class codecvt<char32_t, char, mbstate_t>\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>\n    : public locale::facet,\n      public codecvt_base\n{\npublic:\n    typedef char32_t  intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit codecvt(size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    result out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const\n    {\n        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    result unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const\n    {\n        return do_unshift(__st, __to, __to_end, __to_nxt);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    result in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const\n    {\n        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    int encoding() const  _NOEXCEPT\n    {\n        return do_encoding();\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    bool always_noconv() const  _NOEXCEPT\n    {\n        return do_always_noconv();\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const\n    {\n        return do_length(__st, __frm, __end, __mx);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    int max_length() const  _NOEXCEPT\n    {\n        return do_max_length();\n    }\n\n    static locale::id id;\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    explicit codecvt(const char*, size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    ~codecvt();\n\n    virtual result do_out(state_type& __st,\n                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result do_in(state_type& __st,\n                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result do_unshift(state_type& __st,\n                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const  _NOEXCEPT;\n    virtual bool do_always_noconv() const  _NOEXCEPT;\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;\n    virtual int do_max_length() const  _NOEXCEPT;\n};\n\n// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname\n\ntemplate <class _InternT, class _ExternT, class _StateT>\nclass _LIBCPP_TYPE_VIS_ONLY codecvt_byname\n    : public codecvt<_InternT, _ExternT, _StateT>\n{\npublic:\n    _LIBCPP_ALWAYS_INLINE\n    explicit codecvt_byname(const char* __nm, size_t __refs = 0)\n        : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}\n    _LIBCPP_ALWAYS_INLINE\n    explicit codecvt_byname(const string& __nm, size_t __refs = 0)\n        : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}\nprotected:\n    ~codecvt_byname();\n};\n\ntemplate <class _InternT, class _ExternT, class _StateT>\ncodecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()\n{\n}\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char, char, mbstate_t>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)\n\n_LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);\n\ntemplate <size_t _Np>\nstruct __narrow_to_utf8\n{\n    template <class _OutputIterator, class _CharT>\n    _OutputIterator\n    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;\n};\n\ntemplate <>\nstruct __narrow_to_utf8<8>\n{\n    template <class _OutputIterator, class _CharT>\n    _LIBCPP_ALWAYS_INLINE\n    _OutputIterator\n    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const\n    {\n        for (; __wb < __we; ++__wb, ++__s)\n            *__s = *__wb;\n        return __s;\n    }\n};\n\ntemplate <>\nstruct __narrow_to_utf8<16>\n    : public codecvt<char16_t, char, mbstate_t>\n{\n    _LIBCPP_ALWAYS_INLINE\n    __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}\n\n    ~__narrow_to_utf8();\n\n    template <class _OutputIterator, class _CharT>\n    _LIBCPP_ALWAYS_INLINE\n    _OutputIterator\n    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const\n    {\n        result __r = ok;\n        mbstate_t __mb;\n        while (__wb < __we && __r != error)\n        {\n            const int __sz = 32;\n            char __buf[__sz];\n            char* __bn;\n            const char16_t* __wn = (const char16_t*)__wb;\n            __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,\n                         __buf, __buf+__sz, __bn);\n            if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)\n                __throw_runtime_error(\"locale not supported\");\n            for (const char* __p = __buf; __p < __bn; ++__p, ++__s)\n                *__s = *__p;\n            __wb = (const _CharT*)__wn;\n        }\n        return __s;\n    }\n};\n\ntemplate <>\nstruct __narrow_to_utf8<32>\n    : public codecvt<char32_t, char, mbstate_t>\n{\n    _LIBCPP_ALWAYS_INLINE\n    __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}\n\n    ~__narrow_to_utf8();\n\n    template <class _OutputIterator, class _CharT>\n    _LIBCPP_ALWAYS_INLINE\n    _OutputIterator\n    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const\n    {\n        result __r = ok;\n        mbstate_t __mb;\n        while (__wb < __we && __r != error)\n        {\n            const int __sz = 32;\n            char __buf[__sz];\n            char* __bn;\n            const char32_t* __wn = (const char32_t*)__wb;\n            __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,\n                         __buf, __buf+__sz, __bn);\n            if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)\n                __throw_runtime_error(\"locale not supported\");\n            for (const char* __p = __buf; __p < __bn; ++__p, ++__s)\n                *__s = *__p;\n            __wb = (const _CharT*)__wn;\n        }\n        return __s;\n    }\n};\n\ntemplate <size_t _Np>\nstruct __widen_from_utf8\n{\n    template <class _OutputIterator>\n    _OutputIterator\n    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;\n};\n\ntemplate <>\nstruct __widen_from_utf8<8>\n{\n    template <class _OutputIterator>\n    _LIBCPP_ALWAYS_INLINE\n    _OutputIterator\n    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const\n    {\n        for (; __nb < __ne; ++__nb, ++__s)\n            *__s = *__nb;\n        return __s;\n    }\n};\n\ntemplate <>\nstruct __widen_from_utf8<16>\n    : public codecvt<char16_t, char, mbstate_t>\n{\n    _LIBCPP_ALWAYS_INLINE\n    __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}\n\n    ~__widen_from_utf8();\n\n    template <class _OutputIterator>\n    _LIBCPP_ALWAYS_INLINE\n    _OutputIterator\n    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const\n    {\n        result __r = ok;\n        mbstate_t __mb;\n        while (__nb < __ne && __r != error)\n        {\n            const int __sz = 32;\n            char16_t __buf[__sz];\n            char16_t* __bn;\n            const char* __nn = __nb;\n            __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,\n                        __buf, __buf+__sz, __bn);\n            if (__r == codecvt_base::error || __nn == __nb)\n                __throw_runtime_error(\"locale not supported\");\n            for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)\n                *__s = (wchar_t)*__p;\n            __nb = __nn;\n        }\n        return __s;\n    }\n};\n\ntemplate <>\nstruct __widen_from_utf8<32>\n    : public codecvt<char32_t, char, mbstate_t>\n{\n    _LIBCPP_ALWAYS_INLINE\n    __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}\n\n    ~__widen_from_utf8();\n\n    template <class _OutputIterator>\n    _LIBCPP_ALWAYS_INLINE\n    _OutputIterator\n    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const\n    {\n        result __r = ok;\n        mbstate_t __mb;\n        while (__nb < __ne && __r != error)\n        {\n            const int __sz = 32;\n            char32_t __buf[__sz];\n            char32_t* __bn;\n            const char* __nn = __nb;\n            __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,\n                        __buf, __buf+__sz, __bn);\n            if (__r == codecvt_base::error || __nn == __nb)\n                __throw_runtime_error(\"locale not supported\");\n            for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)\n                *__s = (wchar_t)*__p;\n            __nb = __nn;\n        }\n        return __s;\n    }\n};\n\n// template <class charT> class numpunct\n\ntemplate <class _CharT> class _LIBCPP_TYPE_VIS_ONLY numpunct;\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS numpunct<char>\n    : public locale::facet\n{\npublic:\n    typedef char char_type;\n    typedef basic_string<char_type> string_type;\n\n    explicit numpunct(size_t __refs = 0);\n\n    _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}\n    _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}\n    _LIBCPP_ALWAYS_INLINE string grouping() const         {return do_grouping();}\n    _LIBCPP_ALWAYS_INLINE string_type truename() const    {return do_truename();}\n    _LIBCPP_ALWAYS_INLINE string_type falsename() const   {return do_falsename();}\n\n    static locale::id id;\n\nprotected:\n    ~numpunct();\n    virtual char_type do_decimal_point() const;\n    virtual char_type do_thousands_sep() const;\n    virtual string do_grouping() const;\n    virtual string_type do_truename() const;\n    virtual string_type do_falsename() const;\n\n    char_type __decimal_point_;\n    char_type __thousands_sep_;\n    string __grouping_;\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS numpunct<wchar_t>\n    : public locale::facet\n{\npublic:\n    typedef wchar_t char_type;\n    typedef basic_string<char_type> string_type;\n\n    explicit numpunct(size_t __refs = 0);\n\n    _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}\n    _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}\n    _LIBCPP_ALWAYS_INLINE string grouping() const         {return do_grouping();}\n    _LIBCPP_ALWAYS_INLINE string_type truename() const    {return do_truename();}\n    _LIBCPP_ALWAYS_INLINE string_type falsename() const   {return do_falsename();}\n\n    static locale::id id;\n\nprotected:\n    ~numpunct();\n    virtual char_type do_decimal_point() const;\n    virtual char_type do_thousands_sep() const;\n    virtual string do_grouping() const;\n    virtual string_type do_truename() const;\n    virtual string_type do_falsename() const;\n\n    char_type __decimal_point_;\n    char_type __thousands_sep_;\n    string __grouping_;\n};\n\n// template <class charT> class numpunct_byname\n\ntemplate <class _CharT> class _LIBCPP_TYPE_VIS_ONLY numpunct_byname;\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS numpunct_byname<char>\n: public numpunct<char>\n{\npublic:\n    typedef char char_type;\n    typedef basic_string<char_type> string_type;\n\n    explicit numpunct_byname(const char* __nm, size_t __refs = 0);\n    explicit numpunct_byname(const string& __nm, size_t __refs = 0);\n\nprotected:\n    ~numpunct_byname();\n\nprivate:\n    void __init(const char*);\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS numpunct_byname<wchar_t>\n: public numpunct<wchar_t>\n{\npublic:\n    typedef wchar_t char_type;\n    typedef basic_string<char_type> string_type;\n\n    explicit numpunct_byname(const char* __nm, size_t __refs = 0);\n    explicit numpunct_byname(const string& __nm, size_t __refs = 0);\n\nprotected:\n    ~numpunct_byname();\n\nprivate:\n    void __init(const char*);\n};\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP___LOCALE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__mutex_base",
    "content": "// -*- C++ -*-\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP___MUTEX_BASE\n#define _LIBCPP___MUTEX_BASE\n\n#include <__config>\n#include <chrono>\n#include <system_error>\n#include <pthread.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n#ifndef _LIBCPP_HAS_NO_THREADS\n\nclass _LIBCPP_TYPE_VIS mutex\n{\n    pthread_mutex_t __m_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n#ifndef _LIBCPP_HAS_NO_CONSTEXPR\n     constexpr mutex() _NOEXCEPT : __m_(PTHREAD_MUTEX_INITIALIZER) {}\n#else\n     mutex() _NOEXCEPT {__m_ = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;}\n#endif\n     ~mutex();\n\nprivate:\n    mutex(const mutex&);// = delete;\n    mutex& operator=(const mutex&);// = delete;\n\npublic:\n    void lock();\n    bool try_lock() _NOEXCEPT;\n    void unlock() _NOEXCEPT;\n\n    typedef pthread_mutex_t* native_handle_type;\n    _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;}\n};\n\nstruct _LIBCPP_TYPE_VIS defer_lock_t {};\nstruct _LIBCPP_TYPE_VIS try_to_lock_t {};\nstruct _LIBCPP_TYPE_VIS adopt_lock_t {};\n\n#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MUTEX)\n\nextern const defer_lock_t  defer_lock;\nextern const try_to_lock_t try_to_lock;\nextern const adopt_lock_t  adopt_lock;\n\n#else\n\nconstexpr defer_lock_t  defer_lock  = defer_lock_t();\nconstexpr try_to_lock_t try_to_lock = try_to_lock_t();\nconstexpr adopt_lock_t  adopt_lock  = adopt_lock_t();\n\n#endif\n\ntemplate <class _Mutex>\nclass _LIBCPP_TYPE_VIS_ONLY lock_guard\n{\npublic:\n    typedef _Mutex mutex_type;\n\nprivate:\n    mutex_type& __m_;\npublic:\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit lock_guard(mutex_type& __m)\n        : __m_(__m) {__m_.lock();}\n    _LIBCPP_INLINE_VISIBILITY\n    lock_guard(mutex_type& __m, adopt_lock_t)\n        : __m_(__m) {}\n    _LIBCPP_INLINE_VISIBILITY\n    ~lock_guard() {__m_.unlock();}\n\nprivate:\n    lock_guard(lock_guard const&);// = delete;\n    lock_guard& operator=(lock_guard const&);// = delete;\n};\n\ntemplate <class _Mutex>\nclass _LIBCPP_TYPE_VIS_ONLY unique_lock\n{\npublic:\n    typedef _Mutex mutex_type;\n\nprivate:\n    mutex_type* __m_;\n    bool __owns_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit unique_lock(mutex_type& __m)\n        : __m_(&__m), __owns_(true) {__m_->lock();}\n    _LIBCPP_INLINE_VISIBILITY\n    unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT\n        : __m_(&__m), __owns_(false) {}\n    _LIBCPP_INLINE_VISIBILITY\n    unique_lock(mutex_type& __m, try_to_lock_t)\n        : __m_(&__m), __owns_(__m.try_lock()) {}\n    _LIBCPP_INLINE_VISIBILITY\n    unique_lock(mutex_type& __m, adopt_lock_t)\n        : __m_(&__m), __owns_(true) {}\n    template <class _Clock, class _Duration>\n    _LIBCPP_INLINE_VISIBILITY\n        unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t)\n            : __m_(&__m), __owns_(__m.try_lock_until(__t)) {}\n    template <class _Rep, class _Period>\n    _LIBCPP_INLINE_VISIBILITY\n        unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d)\n            : __m_(&__m), __owns_(__m.try_lock_for(__d)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    ~unique_lock()\n    {\n        if (__owns_)\n            __m_->unlock();\n    }\n\nprivate:\n    unique_lock(unique_lock const&); // = delete;\n    unique_lock& operator=(unique_lock const&); // = delete;\n\npublic:\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    unique_lock(unique_lock&& __u) _NOEXCEPT\n        : __m_(__u.__m_), __owns_(__u.__owns_)\n        {__u.__m_ = nullptr; __u.__owns_ = false;}\n    _LIBCPP_INLINE_VISIBILITY\n    unique_lock& operator=(unique_lock&& __u) _NOEXCEPT\n        {\n            if (__owns_)\n                __m_->unlock();\n            __m_ = __u.__m_;\n            __owns_ = __u.__owns_;\n            __u.__m_ = nullptr;\n            __u.__owns_ = false;\n            return *this;\n        }\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    void lock();\n    bool try_lock();\n\n    template <class _Rep, class _Period>\n        bool try_lock_for(const chrono::duration<_Rep, _Period>& __d);\n    template <class _Clock, class _Duration>\n        bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);\n\n    void unlock();\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(unique_lock& __u) _NOEXCEPT\n    {\n        _VSTD::swap(__m_, __u.__m_);\n        _VSTD::swap(__owns_, __u.__owns_);\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    mutex_type* release() _NOEXCEPT\n    {\n        mutex_type* __m = __m_;\n        __m_ = nullptr;\n        __owns_ = false;\n        return __m;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool owns_lock() const _NOEXCEPT {return __owns_;}\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_EXPLICIT\n        operator bool () const _NOEXCEPT {return __owns_;}\n    _LIBCPP_INLINE_VISIBILITY\n    mutex_type* mutex() const _NOEXCEPT {return __m_;}\n};\n\ntemplate <class _Mutex>\nvoid\nunique_lock<_Mutex>::lock()\n{\n    if (__m_ == nullptr)\n        __throw_system_error(EPERM, \"unique_lock::lock: references null mutex\");\n    if (__owns_)\n        __throw_system_error(EDEADLK, \"unique_lock::lock: already locked\");\n    __m_->lock();\n    __owns_ = true;\n}\n\ntemplate <class _Mutex>\nbool\nunique_lock<_Mutex>::try_lock()\n{\n    if (__m_ == nullptr)\n        __throw_system_error(EPERM, \"unique_lock::try_lock: references null mutex\");\n    if (__owns_)\n        __throw_system_error(EDEADLK, \"unique_lock::try_lock: already locked\");\n    __owns_ = __m_->try_lock();\n    return __owns_;\n}\n\ntemplate <class _Mutex>\ntemplate <class _Rep, class _Period>\nbool\nunique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d)\n{\n    if (__m_ == nullptr)\n        __throw_system_error(EPERM, \"unique_lock::try_lock_for: references null mutex\");\n    if (__owns_)\n        __throw_system_error(EDEADLK, \"unique_lock::try_lock_for: already locked\");\n    __owns_ = __m_->try_lock_for(__d);\n    return __owns_;\n}\n\ntemplate <class _Mutex>\ntemplate <class _Clock, class _Duration>\nbool\nunique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)\n{\n    if (__m_ == nullptr)\n        __throw_system_error(EPERM, \"unique_lock::try_lock_until: references null mutex\");\n    if (__owns_)\n        __throw_system_error(EDEADLK, \"unique_lock::try_lock_until: already locked\");\n    __owns_ = __m_->try_lock_until(__t);\n    return __owns_;\n}\n\ntemplate <class _Mutex>\nvoid\nunique_lock<_Mutex>::unlock()\n{\n    if (!__owns_)\n        __throw_system_error(EPERM, \"unique_lock::unlock: not locked\");\n    __m_->unlock();\n    __owns_ = false;\n}\n\ntemplate <class _Mutex>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT\n    {__x.swap(__y);}\n\n//enum class cv_status\n_LIBCPP_DECLARE_STRONG_ENUM(cv_status)\n{\n    no_timeout,\n    timeout\n};\n_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status)\n\nclass _LIBCPP_TYPE_VIS condition_variable\n{\n    pthread_cond_t __cv_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n#ifndef _LIBCPP_HAS_NO_CONSTEXPR\n    constexpr condition_variable() : __cv_(PTHREAD_COND_INITIALIZER) {}\n#else\n    condition_variable() {__cv_ = (pthread_cond_t)PTHREAD_COND_INITIALIZER;}\n#endif\n    ~condition_variable();\n\nprivate:\n    condition_variable(const condition_variable&); // = delete;\n    condition_variable& operator=(const condition_variable&); // = delete;\n\npublic:\n    void notify_one() _NOEXCEPT;\n    void notify_all() _NOEXCEPT;\n\n    void wait(unique_lock<mutex>& __lk) _NOEXCEPT;\n    template <class _Predicate>\n        void wait(unique_lock<mutex>& __lk, _Predicate __pred);\n\n    template <class _Clock, class _Duration>\n        cv_status\n        wait_until(unique_lock<mutex>& __lk,\n                   const chrono::time_point<_Clock, _Duration>& __t);\n\n    template <class _Clock, class _Duration, class _Predicate>\n        bool\n        wait_until(unique_lock<mutex>& __lk,\n                   const chrono::time_point<_Clock, _Duration>& __t,\n                   _Predicate __pred);\n\n    template <class _Rep, class _Period>\n        cv_status\n        wait_for(unique_lock<mutex>& __lk,\n                 const chrono::duration<_Rep, _Period>& __d);\n\n    template <class _Rep, class _Period, class _Predicate>\n        bool\n        wait_for(unique_lock<mutex>& __lk,\n                 const chrono::duration<_Rep, _Period>& __d,\n                 _Predicate __pred);\n\n    typedef pthread_cond_t* native_handle_type;\n    _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;}\n\nprivate:\n    void __do_timed_wait(unique_lock<mutex>& __lk,\n       chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;\n};\n#endif // !_LIBCPP_HAS_NO_THREADS\n\ntemplate <class _To, class _Rep, class _Period>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    chrono::__is_duration<_To>::value,\n    _To\n>::type\n__ceil(chrono::duration<_Rep, _Period> __d)\n{\n    using namespace chrono;\n    _To __r = duration_cast<_To>(__d);\n    if (__r < __d)\n        ++__r;\n    return __r;\n}\n\n#ifndef _LIBCPP_HAS_NO_THREADS\ntemplate <class _Predicate>\nvoid\ncondition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred)\n{\n    while (!__pred())\n        wait(__lk);\n}\n\ntemplate <class _Clock, class _Duration>\ncv_status\ncondition_variable::wait_until(unique_lock<mutex>& __lk,\n                               const chrono::time_point<_Clock, _Duration>& __t)\n{\n    using namespace chrono;\n    wait_for(__lk, __t - _Clock::now());\n    return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;\n}\n\ntemplate <class _Clock, class _Duration, class _Predicate>\nbool\ncondition_variable::wait_until(unique_lock<mutex>& __lk,\n                   const chrono::time_point<_Clock, _Duration>& __t,\n                   _Predicate __pred)\n{\n    while (!__pred())\n    {\n        if (wait_until(__lk, __t) == cv_status::timeout)\n            return __pred();\n    }\n    return true;\n}\n\ntemplate <class _Rep, class _Period>\ncv_status\ncondition_variable::wait_for(unique_lock<mutex>& __lk,\n                             const chrono::duration<_Rep, _Period>& __d)\n{\n    using namespace chrono;\n    if (__d <= __d.zero())\n        return cv_status::timeout;\n    typedef time_point<system_clock, duration<long double, nano> > __sys_tpf;\n    typedef time_point<system_clock, nanoseconds> __sys_tpi;\n    __sys_tpf _Max = __sys_tpi::max();\n    system_clock::time_point __s_now = system_clock::now();\n    steady_clock::time_point __c_now = steady_clock::now();\n    if (_Max - __d > __s_now)\n        __do_timed_wait(__lk, __s_now + __ceil<nanoseconds>(__d));\n    else\n        __do_timed_wait(__lk, __sys_tpi::max());\n    return steady_clock::now() - __c_now < __d ? cv_status::no_timeout :\n                                                 cv_status::timeout;\n}\n\ntemplate <class _Rep, class _Period, class _Predicate>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\ncondition_variable::wait_for(unique_lock<mutex>& __lk,\n                             const chrono::duration<_Rep, _Period>& __d,\n                             _Predicate __pred)\n{\n    return wait_until(__lk, chrono::steady_clock::now() + __d,\n                      _VSTD::move(__pred));\n}\n\n#endif // !_LIBCPP_HAS_NO_THREADS\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP___MUTEX_BASE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__refstring",
    "content": "//===------------------------ __refstring ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP___REFSTRING\n#define _LIBCPP___REFSTRING\n\n#include <__config>\n#include <cstddef>\n#include <cstring>\n#ifdef __APPLE__\n#include <dlfcn.h>\n#include <mach-o/dyld.h>\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nclass _LIBCPP_HIDDEN __libcpp_refstring\n{\nprivate:\n    const char* str_;\n\n    typedef int count_t;\n\n    struct _Rep_base\n    {\n        std::size_t len;\n        std::size_t cap;\n        count_t     count;\n    };\n\n    static\n    _Rep_base*\n    rep_from_data(const char *data_) _NOEXCEPT\n    {\n        char *data = const_cast<char *>(data_);\n        return reinterpret_cast<_Rep_base *>(data - sizeof(_Rep_base));\n    }\n    static\n    char *\n    data_from_rep(_Rep_base *rep) _NOEXCEPT\n    {\n        char *data = reinterpret_cast<char *>(rep);\n        return data + sizeof(*rep);\n    }\n\n#ifdef __APPLE__\n    static\n    const char*\n    compute_gcc_empty_string_storage() _NOEXCEPT\n    {\n        void* handle = dlopen(\"/usr/lib/libstdc++.6.dylib\", RTLD_NOLOAD);\n        if (handle == nullptr)\n            return nullptr;\n        void* sym = dlsym(handle, \"_ZNSs4_Rep20_S_empty_rep_storageE\");\n        if (sym == nullptr)\n            return nullptr;\n        return data_from_rep(reinterpret_cast<_Rep_base *>(sym));\n    }\n\n    static\n    const char*\n    get_gcc_empty_string_storage() _NOEXCEPT\n    {\n        static const char* p = compute_gcc_empty_string_storage();\n        return p;\n    }\n\n    bool\n    uses_refcount() const\n    {\n        return str_ != get_gcc_empty_string_storage();\n    }\n#else\n    bool\n    uses_refcount() const\n    {\n        return true;\n    }\n#endif\n\npublic:\n    explicit __libcpp_refstring(const char* msg) {\n        std::size_t len = strlen(msg);\n        _Rep_base* rep = static_cast<_Rep_base *>(::operator new(sizeof(*rep) + len + 1));\n        rep->len = len;\n        rep->cap = len;\n        rep->count = 0;\n        char *data = data_from_rep(rep);\n        std::memcpy(data, msg, len + 1);\n        str_ = data;\n    }\n\n    __libcpp_refstring(const __libcpp_refstring& s) _NOEXCEPT : str_(s.str_)\n    {\n        if (uses_refcount())\n            __sync_add_and_fetch(&rep_from_data(str_)->count, 1);\n    }\n\n    __libcpp_refstring& operator=(const __libcpp_refstring& s) _NOEXCEPT\n    {\n        bool adjust_old_count = uses_refcount();\n        struct _Rep_base *old_rep = rep_from_data(str_);\n        str_ = s.str_;\n        if (uses_refcount())\n            __sync_add_and_fetch(&rep_from_data(str_)->count, 1);\n        if (adjust_old_count)\n        {\n            if (__sync_add_and_fetch(&old_rep->count, count_t(-1)) < 0)\n            {\n                ::operator delete(old_rep);\n            }\n        }\n        return *this;\n    }\n\n    ~__libcpp_refstring()\n    {\n        if (uses_refcount())\n        {\n            _Rep_base* rep = rep_from_data(str_);\n            if (__sync_add_and_fetch(&rep->count, count_t(-1)) < 0)\n            {\n                ::operator delete(rep);\n            }\n        }\n    }\n\n    const char* c_str() const _NOEXCEPT {return str_;}\n};\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif //_LIBCPP___REFSTRING\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__split_buffer",
    "content": "// -*- C++ -*-\n#ifndef _LIBCPP_SPLIT_BUFFER\n#define _LIBCPP_SPLIT_BUFFER\n\n#include <__config>\n#include <type_traits>\n#include <algorithm>\n\n#include <__undef_min_max>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <bool>\nclass __split_buffer_common\n{\nprotected:\n    void __throw_length_error() const;\n    void __throw_out_of_range() const;\n};\n\ntemplate <class _Tp, class _Allocator = allocator<_Tp> >\nstruct __split_buffer\n    : private __split_buffer_common<true>\n{\nprivate:\n    __split_buffer(const __split_buffer&);\n    __split_buffer& operator=(const __split_buffer&);\npublic:\n    typedef _Tp                                             value_type;\n    typedef _Allocator                                      allocator_type;\n    typedef typename remove_reference<allocator_type>::type __alloc_rr;\n    typedef allocator_traits<__alloc_rr>                    __alloc_traits;\n    typedef value_type&                                     reference;\n    typedef const value_type&                               const_reference;\n    typedef typename __alloc_traits::size_type              size_type;\n    typedef typename __alloc_traits::difference_type        difference_type;\n    typedef typename __alloc_traits::pointer                pointer;\n    typedef typename __alloc_traits::const_pointer          const_pointer;\n    typedef pointer                                         iterator;\n    typedef const_pointer                                   const_iterator;\n\n    pointer                                         __first_;\n    pointer                                         __begin_;\n    pointer                                         __end_;\n    __compressed_pair<pointer, allocator_type> __end_cap_;\n\n    typedef typename add_lvalue_reference<allocator_type>::type __alloc_ref;\n    typedef typename add_lvalue_reference<allocator_type>::type __alloc_const_ref;\n\n    _LIBCPP_INLINE_VISIBILITY __alloc_rr&           __alloc() _NOEXCEPT         {return __end_cap_.second();}\n    _LIBCPP_INLINE_VISIBILITY const __alloc_rr&     __alloc() const _NOEXCEPT   {return __end_cap_.second();}\n    _LIBCPP_INLINE_VISIBILITY pointer&              __end_cap() _NOEXCEPT       {return __end_cap_.first();}\n    _LIBCPP_INLINE_VISIBILITY const pointer&        __end_cap() const _NOEXCEPT {return __end_cap_.first();}\n\n    __split_buffer()\n        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);\n    explicit __split_buffer(__alloc_rr& __a);\n    explicit __split_buffer(const __alloc_rr& __a);\n    __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a);\n    ~__split_buffer();\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __split_buffer(__split_buffer&& __c)\n        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);\n    __split_buffer(__split_buffer&& __c, const __alloc_rr& __a);\n    __split_buffer& operator=(__split_buffer&& __c)\n        _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&\n                is_nothrow_move_assignable<allocator_type>::value) ||\n               !__alloc_traits::propagate_on_container_move_assignment::value);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY       iterator begin() _NOEXCEPT       {return __begin_;}\n    _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __begin_;}\n    _LIBCPP_INLINE_VISIBILITY       iterator end() _NOEXCEPT         {return __end_;}\n    _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT   {return __end_;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() _NOEXCEPT\n        {__destruct_at_end(__begin_);}\n    _LIBCPP_INLINE_VISIBILITY size_type size() const {return static_cast<size_type>(__end_ - __begin_);}\n    _LIBCPP_INLINE_VISIBILITY bool empty()     const {return __end_ == __begin_;}\n    _LIBCPP_INLINE_VISIBILITY size_type capacity() const {return static_cast<size_type>(__end_cap() - __first_);}\n    _LIBCPP_INLINE_VISIBILITY size_type __front_spare() const {return static_cast<size_type>(__begin_ - __first_);}\n    _LIBCPP_INLINE_VISIBILITY size_type __back_spare() const {return static_cast<size_type>(__end_cap() - __end_);}\n\n    _LIBCPP_INLINE_VISIBILITY       reference front()       {return *__begin_;}\n    _LIBCPP_INLINE_VISIBILITY const_reference front() const {return *__begin_;}\n    _LIBCPP_INLINE_VISIBILITY       reference back()        {return *(__end_ - 1);}\n    _LIBCPP_INLINE_VISIBILITY const_reference back() const  {return *(__end_ - 1);}\n\n    void reserve(size_type __n);\n    void shrink_to_fit() _NOEXCEPT;\n    void push_front(const_reference __x);\n    _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n    void push_front(value_type&& __x);\n    void push_back(value_type&& __x);\n#if !defined(_LIBCPP_HAS_NO_VARIADICS)\n    template <class... _Args>\n        void emplace_back(_Args&&... __args);\n#endif  // !defined(_LIBCPP_HAS_NO_VARIADICS)\n#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n\n    _LIBCPP_INLINE_VISIBILITY void pop_front() {__destruct_at_begin(__begin_+1);}\n    _LIBCPP_INLINE_VISIBILITY void pop_back() {__destruct_at_end(__end_-1);}\n\n    void __construct_at_end(size_type __n);\n    void __construct_at_end(size_type __n, const_reference __x);\n    template <class _InputIter>\n        typename enable_if\n        <\n            __is_input_iterator<_InputIter>::value &&\n           !__is_forward_iterator<_InputIter>::value,\n            void\n        >::type\n        __construct_at_end(_InputIter __first, _InputIter __last);\n    template <class _ForwardIterator>\n        typename enable_if\n        <\n            __is_forward_iterator<_ForwardIterator>::value,\n            void\n        >::type\n        __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);\n\n    _LIBCPP_INLINE_VISIBILITY void __destruct_at_begin(pointer __new_begin)\n        {__destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());}\n        void __destruct_at_begin(pointer __new_begin, false_type);\n        void __destruct_at_begin(pointer __new_begin, true_type);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __destruct_at_end(pointer __new_last) _NOEXCEPT\n        {__destruct_at_end(__new_last, false_type());}\n    _LIBCPP_INLINE_VISIBILITY\n        void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n        void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT;\n\n    void swap(__split_buffer& __x)\n        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||\n                   __is_nothrow_swappable<__alloc_rr>::value);\n\n    bool __invariants() const;\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__split_buffer& __c, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)\n        {\n            __alloc() = _VSTD::move(__c.__alloc());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT\n        {}\n};\n\ntemplate <class _Tp, class _Allocator>\nbool\n__split_buffer<_Tp, _Allocator>::__invariants() const\n{\n    if (__first_ == nullptr)\n    {\n        if (__begin_ != nullptr)\n            return false;\n        if (__end_ != nullptr)\n            return false;\n        if (__end_cap() != nullptr)\n            return false;\n    }\n    else\n    {\n        if (__begin_ < __first_)\n            return false;\n        if (__end_ < __begin_)\n            return false;\n        if (__end_cap() < __end_)\n            return false;\n    }\n    return true;\n}\n\n//  Default constructs __n objects starting at __end_\n//  throws if construction throws\n//  Precondition:  __n > 0\n//  Precondition:  size() + __n <= capacity()\n//  Postcondition:  size() == size() + __n\ntemplate <class _Tp, class _Allocator>\nvoid\n__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n)\n{\n    __alloc_rr& __a = this->__alloc();\n    do\n    {\n        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));\n        ++this->__end_;\n        --__n;\n    } while (__n > 0);\n}\n\n//  Copy constructs __n objects starting at __end_ from __x\n//  throws if construction throws\n//  Precondition:  __n > 0\n//  Precondition:  size() + __n <= capacity()\n//  Postcondition:  size() == old size() + __n\n//  Postcondition:  [i] == __x for all i in [size() - __n, __n)\ntemplate <class _Tp, class _Allocator>\nvoid\n__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)\n{\n    __alloc_rr& __a = this->__alloc();\n    do\n    {\n        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x);\n        ++this->__end_;\n        --__n;\n    } while (__n > 0);\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _InputIter>\ntypename enable_if\n<\n     __is_input_iterator<_InputIter>::value &&\n    !__is_forward_iterator<_InputIter>::value,\n    void\n>::type\n__split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last)\n{\n    __alloc_rr& __a = this->__alloc();\n    for (; __first != __last; ++__first)\n    {\n        if (__end_ == __end_cap())\n        {\n            size_type __old_cap = __end_cap() - __first_;\n            size_type __new_cap = _VSTD::max<size_type>(2 * __old_cap, 8);\n            __split_buffer __buf(__new_cap, 0, __a);\n            for (pointer __p = __begin_; __p != __end_; ++__p, ++__buf.__end_)\n                __alloc_traits::construct(__buf.__alloc(),\n                        _VSTD::__to_raw_pointer(__buf.__end_), _VSTD::move(*__p));\n            swap(__buf);\n        }\n        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);\n        ++this->__end_;\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _ForwardIterator>\ntypename enable_if\n<\n    __is_forward_iterator<_ForwardIterator>::value,\n    void\n>::type\n__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)\n{\n    __alloc_rr& __a = this->__alloc();\n    for (; __first != __last; ++__first)\n    {\n        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);\n        ++this->__end_;\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type)\n{\n    while (__begin_ != __new_begin)\n        __alloc_traits::destroy(__alloc(), __to_raw_pointer(__begin_++));\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type)\n{\n    __begin_ = __new_begin;\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT\n{\n    while (__new_last != __end_)\n        __alloc_traits::destroy(__alloc(), __to_raw_pointer(--__end_));\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type) _NOEXCEPT\n{\n    __end_ = __new_last;\n}\n\ntemplate <class _Tp, class _Allocator>\n__split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a)\n    : __end_cap_(nullptr, __a)\n{\n    __first_ = __cap != 0 ? __alloc_traits::allocate(__alloc(), __cap) : nullptr;\n    __begin_ = __end_ = __first_ + __start;\n    __end_cap() = __first_ + __cap;\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\n__split_buffer<_Tp, _Allocator>::__split_buffer()\n    _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)\n    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr)\n{\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\n__split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a)\n    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)\n{\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\n__split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a)\n    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)\n{\n}\n\ntemplate <class _Tp, class _Allocator>\n__split_buffer<_Tp, _Allocator>::~__split_buffer()\n{\n    clear();\n    if (__first_)\n        __alloc_traits::deallocate(__alloc(), __first_, capacity());\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\n__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c)\n    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)\n    : __first_(_VSTD::move(__c.__first_)),\n      __begin_(_VSTD::move(__c.__begin_)),\n      __end_(_VSTD::move(__c.__end_)),\n      __end_cap_(_VSTD::move(__c.__end_cap_))\n{\n    __c.__first_ = nullptr;\n    __c.__begin_ = nullptr;\n    __c.__end_ = nullptr;\n    __c.__end_cap() = nullptr;\n}\n\ntemplate <class _Tp, class _Allocator>\n__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a)\n    : __end_cap_(__a)\n{\n    if (__a == __c.__alloc())\n    {\n        __first_ = __c.__first_;\n        __begin_ = __c.__begin_;\n        __end_ = __c.__end_;\n        __end_cap() = __c.__end_cap();\n        __c.__first_ = nullptr;\n        __c.__begin_ = nullptr;\n        __c.__end_ = nullptr;\n        __c.__end_cap() = nullptr;\n    }\n    else\n    {\n        size_type __cap = __c.size();\n        __first_ = __alloc_traits::allocate(__alloc(), __cap);\n        __begin_ = __end_ = __first_;\n        __end_cap() = __first_ + __cap;\n        typedef move_iterator<iterator> _Ip;\n        __construct_at_end(_Ip(__c.begin()), _Ip(__c.end()));\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\n__split_buffer<_Tp, _Allocator>&\n__split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c)\n    _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&\n                is_nothrow_move_assignable<allocator_type>::value) ||\n               !__alloc_traits::propagate_on_container_move_assignment::value)\n{\n    clear();\n    shrink_to_fit();\n    __first_ = __c.__first_;\n    __begin_ = __c.__begin_;\n    __end_ = __c.__end_;\n    __end_cap() = __c.__end_cap();\n    __move_assign_alloc(__c,\n        integral_constant<bool,\n                          __alloc_traits::propagate_on_container_move_assignment::value>());\n    __c.__first_ = __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr;\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\nvoid\n__split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x)\n        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||\n                   __is_nothrow_swappable<__alloc_rr>::value)\n{\n    _VSTD::swap(__first_, __x.__first_);\n    _VSTD::swap(__begin_, __x.__begin_);\n    _VSTD::swap(__end_, __x.__end_);\n    _VSTD::swap(__end_cap(), __x.__end_cap());\n    __swap_allocator(__alloc(), __x.__alloc());\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\n__split_buffer<_Tp, _Allocator>::reserve(size_type __n)\n{\n    if (__n < capacity())\n    {\n        __split_buffer<value_type, __alloc_rr&> __t(__n, 0, __alloc());\n        __t.__construct_at_end(move_iterator<pointer>(__begin_),\n                               move_iterator<pointer>(__end_));\n        _VSTD::swap(__first_, __t.__first_);\n        _VSTD::swap(__begin_, __t.__begin_);\n        _VSTD::swap(__end_, __t.__end_);\n        _VSTD::swap(__end_cap(), __t.__end_cap());\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\n__split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT\n{\n    if (capacity() > size())\n    {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc());\n            __t.__construct_at_end(move_iterator<pointer>(__begin_),\n                                   move_iterator<pointer>(__end_));\n            __t.__end_ = __t.__begin_ + (__end_ - __begin_);\n            _VSTD::swap(__first_, __t.__first_);\n            _VSTD::swap(__begin_, __t.__begin_);\n            _VSTD::swap(__end_, __t.__end_);\n            _VSTD::swap(__end_cap(), __t.__end_cap());\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\n__split_buffer<_Tp, _Allocator>::push_front(const_reference __x)\n{\n    if (__begin_ == __first_)\n    {\n        if (__end_ < __end_cap())\n        {\n            difference_type __d = __end_cap() - __end_;\n            __d = (__d + 1) / 2;\n            __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d);\n            __end_ += __d;\n        }\n        else\n        {\n            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);\n            __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());\n            __t.__construct_at_end(move_iterator<pointer>(__begin_),\n                                   move_iterator<pointer>(__end_));\n            _VSTD::swap(__first_, __t.__first_);\n            _VSTD::swap(__begin_, __t.__begin_);\n            _VSTD::swap(__end_, __t.__end_);\n            _VSTD::swap(__end_cap(), __t.__end_cap());\n        }\n    }\n    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), __x);\n    --__begin_;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\nvoid\n__split_buffer<_Tp, _Allocator>::push_front(value_type&& __x)\n{\n    if (__begin_ == __first_)\n    {\n        if (__end_ < __end_cap())\n        {\n            difference_type __d = __end_cap() - __end_;\n            __d = (__d + 1) / 2;\n            __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d);\n            __end_ += __d;\n        }\n        else\n        {\n            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);\n            __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());\n            __t.__construct_at_end(move_iterator<pointer>(__begin_),\n                                   move_iterator<pointer>(__end_));\n            _VSTD::swap(__first_, __t.__first_);\n            _VSTD::swap(__begin_, __t.__begin_);\n            _VSTD::swap(__end_, __t.__end_);\n            _VSTD::swap(__end_cap(), __t.__end_cap());\n        }\n    }\n    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1),\n            _VSTD::move(__x));\n    --__begin_;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__split_buffer<_Tp, _Allocator>::push_back(const_reference __x)\n{\n    if (__end_ == __end_cap())\n    {\n        if (__begin_ > __first_)\n        {\n            difference_type __d = __begin_ - __first_;\n            __d = (__d + 1) / 2;\n            __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d);\n            __begin_ -= __d;\n        }\n        else\n        {\n            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);\n            __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());\n            __t.__construct_at_end(move_iterator<pointer>(__begin_),\n                                   move_iterator<pointer>(__end_));\n            _VSTD::swap(__first_, __t.__first_);\n            _VSTD::swap(__begin_, __t.__begin_);\n            _VSTD::swap(__end_, __t.__end_);\n            _VSTD::swap(__end_cap(), __t.__end_cap());\n        }\n    }\n    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), __x);\n    ++__end_;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\nvoid\n__split_buffer<_Tp, _Allocator>::push_back(value_type&& __x)\n{\n    if (__end_ == __end_cap())\n    {\n        if (__begin_ > __first_)\n        {\n            difference_type __d = __begin_ - __first_;\n            __d = (__d + 1) / 2;\n            __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d);\n            __begin_ -= __d;\n        }\n        else\n        {\n            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);\n            __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());\n            __t.__construct_at_end(move_iterator<pointer>(__begin_),\n                                   move_iterator<pointer>(__end_));\n            _VSTD::swap(__first_, __t.__first_);\n            _VSTD::swap(__begin_, __t.__begin_);\n            _VSTD::swap(__end_, __t.__end_);\n            _VSTD::swap(__end_cap(), __t.__end_cap());\n        }\n    }\n    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_),\n            _VSTD::move(__x));\n    ++__end_;\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class... _Args>\nvoid\n__split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args)\n{\n    if (__end_ == __end_cap())\n    {\n        if (__begin_ > __first_)\n        {\n            difference_type __d = __begin_ - __first_;\n            __d = (__d + 1) / 2;\n            __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d);\n            __begin_ -= __d;\n        }\n        else\n        {\n            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);\n            __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());\n            __t.__construct_at_end(move_iterator<pointer>(__begin_),\n                                   move_iterator<pointer>(__end_));\n            _VSTD::swap(__first_, __t.__first_);\n            _VSTD::swap(__begin_, __t.__begin_);\n            _VSTD::swap(__end_, __t.__end_);\n            _VSTD::swap(__end_cap(), __t.__end_cap());\n        }\n    }\n    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_),\n                              _VSTD::forward<_Args>(__args)...);\n    ++__end_;\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y)\n        _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_SPLIT_BUFFER\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__sso_allocator",
    "content": "// -*- C++ -*-\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP___SSO_ALLOCATOR\n#define _LIBCPP___SSO_ALLOCATOR\n\n#include <__config>\n#include <type_traits>\n#include <new>\n\n#include <__undef___deallocate>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Tp, size_t _Np> class _LIBCPP_HIDDEN __sso_allocator;\n\ntemplate <size_t _Np>\nclass _LIBCPP_HIDDEN __sso_allocator<void, _Np>\n{\npublic:\n    typedef const void*       const_pointer;\n    typedef void              value_type;\n};\n\ntemplate <class _Tp, size_t _Np>\nclass _LIBCPP_HIDDEN __sso_allocator\n{\n    typename aligned_storage<sizeof(_Tp) * _Np>::type buf_;\n    bool __allocated_;\npublic:\n    typedef size_t            size_type;\n    typedef _Tp*              pointer;\n    typedef _Tp               value_type;\n\n    _LIBCPP_INLINE_VISIBILITY __sso_allocator() throw() : __allocated_(false) {}\n    _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator&) throw() : __allocated_(false) {}\n    template <class _Up> _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator<_Up, _Np>&) throw()\n         : __allocated_(false) {}\nprivate:\n    __sso_allocator& operator=(const __sso_allocator&);\npublic:\n    _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, typename __sso_allocator<void, _Np>::const_pointer = 0)\n    {\n        if (!__allocated_ && __n <= _Np)\n        {\n            __allocated_ = true;\n            return (pointer)&buf_;\n        }\n        return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));\n    }\n    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type)\n    {\n        if (__p == (pointer)&buf_)\n            __allocated_ = false;\n        else\n            _VSTD::__deallocate(__p);\n    }\n    _LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator==(__sso_allocator& __a) const {return &buf_ == &__a.buf_;}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(__sso_allocator& __a) const {return &buf_ != &__a.buf_;}\n};\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP___SSO_ALLOCATOR\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__std_stream",
    "content": "// -*- C++ -*-\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP___STD_STREAM\n#define _LIBCPP___STD_STREAM\n\n#include <__config>\n#include <ostream>\n#include <istream>\n#include <__locale>\n#include <cstdio>\n\n#include <__undef_min_max>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nstatic const int __limit = 8;\n\n// __stdinbuf\n\ntemplate <class _CharT>\nclass _LIBCPP_HIDDEN __stdinbuf\n    : public basic_streambuf<_CharT, char_traits<_CharT> >\n{\npublic:\n    typedef _CharT                           char_type;\n    typedef char_traits<char_type>           traits_type;\n    typedef typename traits_type::int_type   int_type;\n    typedef typename traits_type::pos_type   pos_type;\n    typedef typename traits_type::off_type   off_type;\n    typedef typename traits_type::state_type state_type;\n\n    __stdinbuf(FILE* __fp, state_type* __st);\n\nprotected:\n    virtual int_type underflow();\n    virtual int_type uflow();\n    virtual int_type pbackfail(int_type __c = traits_type::eof());\n    virtual void imbue(const locale& __loc);\n\nprivate:\n\n    FILE* __file_;\n    const codecvt<char_type, char, state_type>* __cv_;\n    state_type* __st_;\n    int __encoding_;\n    int_type __last_consumed_;\n    bool __last_consumed_is_next_;\n    bool __always_noconv_;\n\n    __stdinbuf(const __stdinbuf&);\n    __stdinbuf& operator=(const __stdinbuf&);\n\n    int_type __getchar(bool __consume);\n};\n\ntemplate <class _CharT>\n__stdinbuf<_CharT>::__stdinbuf(FILE* __fp, state_type* __st)\n    : __file_(__fp),\n      __st_(__st),\n      __last_consumed_(traits_type::eof()),\n      __last_consumed_is_next_(false)\n{\n    imbue(this->getloc());\n}\n\ntemplate <class _CharT>\nvoid\n__stdinbuf<_CharT>::imbue(const locale& __loc)\n{\n    __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);\n    __encoding_ = __cv_->encoding();\n    __always_noconv_ = __cv_->always_noconv();\n    if (__encoding_ > __limit)\n        __throw_runtime_error(\"unsupported locale for standard input\");\n}\n\ntemplate <class _CharT>\ntypename __stdinbuf<_CharT>::int_type\n__stdinbuf<_CharT>::underflow()\n{\n    return __getchar(false);\n}\n\ntemplate <class _CharT>\ntypename __stdinbuf<_CharT>::int_type\n__stdinbuf<_CharT>::uflow()\n{\n    return __getchar(true);\n}\n\ntemplate <class _CharT>\ntypename __stdinbuf<_CharT>::int_type\n__stdinbuf<_CharT>::__getchar(bool __consume)\n{\n    if (__last_consumed_is_next_)\n    {\n        int_type __result = __last_consumed_;\n        if (__consume)\n        {\n            __last_consumed_ = traits_type::eof();\n            __last_consumed_is_next_ = false;\n        }\n        return __result;\n    }\n    char __extbuf[__limit];\n    int __nread = _VSTD::max(1, __encoding_);\n    for (int __i = 0; __i < __nread; ++__i)\n    {\n        int __c = getc(__file_);\n        if (__c == EOF)\n            return traits_type::eof();\n        __extbuf[__i] = static_cast<char>(__c);\n    }\n    char_type __1buf;\n    if (__always_noconv_)\n        __1buf = static_cast<char_type>(__extbuf[0]);\n    else\n    {\n        const char* __enxt;\n        char_type* __inxt;\n        codecvt_base::result __r;\n        do\n        {\n            state_type __sv_st = *__st_;\n            __r = __cv_->in(*__st_, __extbuf, __extbuf + __nread, __enxt,\n                                   &__1buf, &__1buf + 1, __inxt);\n            switch (__r)\n            {\n            case _VSTD::codecvt_base::ok:\n                break;\n            case codecvt_base::partial:\n                *__st_ = __sv_st;\n                if (__nread == sizeof(__extbuf))\n                    return traits_type::eof();\n                {\n                    int __c = getc(__file_);\n                    if (__c == EOF)\n                        return traits_type::eof();\n                    __extbuf[__nread] = static_cast<char>(__c);\n                }\n                ++__nread;\n                break;\n            case codecvt_base::error:\n                return traits_type::eof();\n            case _VSTD::codecvt_base::noconv:\n                __1buf = static_cast<char_type>(__extbuf[0]);\n                break;\n            }\n        } while (__r == _VSTD::codecvt_base::partial);\n    }\n    if (!__consume)\n    {\n        for (int __i = __nread; __i > 0;)\n        {\n            if (ungetc(traits_type::to_int_type(__extbuf[--__i]), __file_) == EOF)\n                return traits_type::eof();\n        }\n    }\n    else\n        __last_consumed_ = traits_type::to_int_type(__1buf);\n    return traits_type::to_int_type(__1buf);\n}\n\ntemplate <class _CharT>\ntypename __stdinbuf<_CharT>::int_type\n__stdinbuf<_CharT>::pbackfail(int_type __c)\n{\n    if (traits_type::eq_int_type(__c, traits_type::eof()))\n    {\n        if (!__last_consumed_is_next_)\n        {\n            __c = __last_consumed_;\n            __last_consumed_is_next_ = !traits_type::eq_int_type(__last_consumed_,\n                                                                 traits_type::eof());\n        }\n        return __c;\n    }\n    if (__last_consumed_is_next_)\n    {\n        char __extbuf[__limit];\n        char* __enxt;\n        const char_type __ci = traits_type::to_char_type(__last_consumed_);\n        const char_type* __inxt;\n        switch (__cv_->out(*__st_, &__ci, &__ci + 1, __inxt,\n                                  __extbuf, __extbuf + sizeof(__extbuf), __enxt))\n        {\n        case _VSTD::codecvt_base::ok:\n            break;\n        case _VSTD::codecvt_base::noconv:\n            __extbuf[0] = static_cast<char>(__last_consumed_);\n            __enxt = __extbuf + 1;\n            break;\n        case codecvt_base::partial:\n        case codecvt_base::error:\n            return traits_type::eof();\n        }\n        while (__enxt > __extbuf)\n            if (ungetc(*--__enxt, __file_) == EOF)\n                return traits_type::eof();\n    }\n    __last_consumed_ = __c;\n    __last_consumed_is_next_ = true;\n    return __c;\n}\n\n// __stdoutbuf\n\ntemplate <class _CharT>\nclass _LIBCPP_HIDDEN __stdoutbuf\n    : public basic_streambuf<_CharT, char_traits<_CharT> >\n{\npublic:\n    typedef _CharT                           char_type;\n    typedef char_traits<char_type>           traits_type;\n    typedef typename traits_type::int_type   int_type;\n    typedef typename traits_type::pos_type   pos_type;\n    typedef typename traits_type::off_type   off_type;\n    typedef typename traits_type::state_type state_type;\n\n    __stdoutbuf(FILE* __fp, state_type* __st);\n\nprotected:\n    virtual int_type overflow (int_type __c = traits_type::eof());\n    virtual streamsize xsputn(const char_type* __s, streamsize __n);\n    virtual int sync();\n    virtual void imbue(const locale& __loc);\n\nprivate:\n    FILE* __file_;\n    const codecvt<char_type, char, state_type>* __cv_;\n    state_type* __st_;\n    bool __always_noconv_;\n\n    __stdoutbuf(const __stdoutbuf&);\n    __stdoutbuf& operator=(const __stdoutbuf&);\n};\n\ntemplate <class _CharT>\n__stdoutbuf<_CharT>::__stdoutbuf(FILE* __fp, state_type* __st)\n    : __file_(__fp),\n      __cv_(&use_facet<codecvt<char_type, char, state_type> >(this->getloc())),\n      __st_(__st),\n      __always_noconv_(__cv_->always_noconv())\n{\n}\n\ntemplate <class _CharT>\ntypename __stdoutbuf<_CharT>::int_type\n__stdoutbuf<_CharT>::overflow(int_type __c)\n{\n    char __extbuf[__limit];\n    char_type __1buf;\n    if (!traits_type::eq_int_type(__c, traits_type::eof()))\n    {\n        __1buf = traits_type::to_char_type(__c);\n        if (__always_noconv_)\n        {\n            if (fwrite(&__1buf, sizeof(char_type), 1, __file_) != 1)\n                return traits_type::eof();\n        }\n        else\n        {\n            char* __extbe = __extbuf;\n            codecvt_base::result __r;\n            char_type* pbase = &__1buf;\n            char_type* pptr = pbase + 1;\n            do\n            {\n                const char_type* __e;\n                __r = __cv_->out(*__st_, pbase, pptr, __e,\n                                        __extbuf,\n                                        __extbuf + sizeof(__extbuf),\n                                        __extbe);\n                if (__e == pbase)\n                    return traits_type::eof();\n                if (__r == codecvt_base::noconv)\n                {\n                    if (fwrite(pbase, 1, 1, __file_) != 1)\n                        return traits_type::eof();\n                }\n                else if (__r == codecvt_base::ok || __r == codecvt_base::partial)\n                {\n                    size_t __nmemb = static_cast<size_t>(__extbe - __extbuf);\n                    if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb)\n                        return traits_type::eof();\n                    if (__r == codecvt_base::partial)\n                    {\n                        pbase = (char_type*)__e;\n                    }\n                }\n                else\n                    return traits_type::eof();\n            } while (__r == codecvt_base::partial);\n        }\n    }\n    return traits_type::not_eof(__c);\n}\n\ntemplate <class _CharT>\nstreamsize\n__stdoutbuf<_CharT>::xsputn(const char_type* __s, streamsize __n)\n{\n    if (__always_noconv_)\n        return fwrite(__s, sizeof(char_type), __n, __file_);\n    streamsize __i = 0;\n    for (; __i < __n; ++__i, ++__s)\n        if (overflow(traits_type::to_int_type(*__s)) == traits_type::eof())\n            break;\n    return __i;\n}\n\ntemplate <class _CharT>\nint\n__stdoutbuf<_CharT>::sync()\n{\n    char __extbuf[__limit];\n    codecvt_base::result __r;\n    do\n    {\n        char* __extbe;\n        __r = __cv_->unshift(*__st_, __extbuf,\n                                    __extbuf + sizeof(__extbuf),\n                                    __extbe);\n        size_t __nmemb = static_cast<size_t>(__extbe - __extbuf);\n        if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb)\n            return -1;\n    } while (__r == codecvt_base::partial);\n    if (__r == codecvt_base::error)\n        return -1;\n    if (fflush(__file_))\n        return -1;\n    return 0;\n}\n\ntemplate <class _CharT>\nvoid\n__stdoutbuf<_CharT>::imbue(const locale& __loc)\n{\n    sync();\n    __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);\n    __always_noconv_ = __cv_->always_noconv();\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP___STD_STREAM\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__tree",
    "content": "// -*- C++ -*-\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP___TREE\n#define _LIBCPP___TREE\n\n#include <__config>\n#include <iterator>\n#include <memory>\n#include <stdexcept>\n#include <algorithm>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Tp, class _Compare, class _Allocator> class __tree;\ntemplate <class _Tp, class _NodePtr, class _DiffType>\n    class _LIBCPP_TYPE_VIS_ONLY __tree_iterator;\ntemplate <class _Tp, class _ConstNodePtr, class _DiffType>\n    class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\n    class _LIBCPP_TYPE_VIS_ONLY map;\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\n    class _LIBCPP_TYPE_VIS_ONLY multimap;\ntemplate <class _Key, class _Compare, class _Allocator>\n    class _LIBCPP_TYPE_VIS_ONLY set;\ntemplate <class _Key, class _Compare, class _Allocator>\n    class _LIBCPP_TYPE_VIS_ONLY multiset;\n\n/*\n\n_NodePtr algorithms\n\nThe algorithms taking _NodePtr are red black tree algorithms.  Those\nalgorithms taking a parameter named __root should assume that __root\npoints to a proper red black tree (unless otherwise specified).\n\nEach algorithm herein assumes that __root->__parent_ points to a non-null\nstructure which has a member __left_ which points back to __root.  No other\nmember is read or written to at __root->__parent_.\n\n__root->__parent_ will be referred to below (in comments only) as end_node.\nend_node->__left_ is an externably accessible lvalue for __root, and can be\nchanged by node insertion and removal (without explicit reference to end_node).\n\nAll nodes (with the exception of end_node), even the node referred to as\n__root, have a non-null __parent_ field.\n\n*/\n\n// Returns:  true if __x is a left child of its parent, else false\n// Precondition:  __x != nullptr.\ntemplate <class _NodePtr>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\n__tree_is_left_child(_NodePtr __x) _NOEXCEPT\n{\n    return __x == __x->__parent_->__left_;\n}\n\n// Determintes if the subtree rooted at __x is a proper red black subtree.  If\n//    __x is a proper subtree, returns the black height (null counts as 1).  If\n//    __x is an improper subtree, returns 0.\ntemplate <class _NodePtr>\nunsigned\n__tree_sub_invariant(_NodePtr __x)\n{\n    if (__x == nullptr)\n        return 1;\n    // parent consistency checked by caller\n    // check __x->__left_ consistency\n    if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x)\n        return 0;\n    // check __x->__right_ consistency\n    if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x)\n        return 0;\n    // check __x->__left_ != __x->__right_ unless both are nullptr\n    if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr)\n        return 0;\n    // If this is red, neither child can be red\n    if (!__x->__is_black_)\n    {\n        if (__x->__left_ && !__x->__left_->__is_black_)\n            return 0;\n        if (__x->__right_ && !__x->__right_->__is_black_)\n            return 0;\n    }\n    unsigned __h = __tree_sub_invariant(__x->__left_);\n    if (__h == 0)\n        return 0;  // invalid left subtree\n    if (__h != __tree_sub_invariant(__x->__right_))\n        return 0;  // invalid or different height right subtree\n    return __h + __x->__is_black_;  // return black height of this node\n}\n\n// Determintes if the red black tree rooted at __root is a proper red black tree.\n//    __root == nullptr is a proper tree.  Returns true is __root is a proper\n//    red black tree, else returns false.\ntemplate <class _NodePtr>\nbool\n__tree_invariant(_NodePtr __root)\n{\n    if (__root == nullptr)\n        return true;\n    // check __x->__parent_ consistency\n    if (__root->__parent_ == nullptr)\n        return false;\n    if (!__tree_is_left_child(__root))\n        return false;\n    // root must be black\n    if (!__root->__is_black_)\n        return false;\n    // do normal node checks\n    return __tree_sub_invariant(__root) != 0;\n}\n\n// Returns:  pointer to the left-most node under __x.\n// Precondition:  __x != nullptr.\ntemplate <class _NodePtr>\ninline _LIBCPP_INLINE_VISIBILITY\n_NodePtr\n__tree_min(_NodePtr __x) _NOEXCEPT\n{\n    while (__x->__left_ != nullptr)\n        __x = __x->__left_;\n    return __x;\n}\n\n// Returns:  pointer to the right-most node under __x.\n// Precondition:  __x != nullptr.\ntemplate <class _NodePtr>\ninline _LIBCPP_INLINE_VISIBILITY\n_NodePtr\n__tree_max(_NodePtr __x) _NOEXCEPT\n{\n    while (__x->__right_ != nullptr)\n        __x = __x->__right_;\n    return __x;\n}\n\n// Returns:  pointer to the next in-order node after __x.\n// Precondition:  __x != nullptr.\ntemplate <class _NodePtr>\n_NodePtr\n__tree_next(_NodePtr __x) _NOEXCEPT\n{\n    if (__x->__right_ != nullptr)\n        return __tree_min(__x->__right_);\n    while (!__tree_is_left_child(__x))\n        __x = __x->__parent_;\n    return __x->__parent_;\n}\n\n// Returns:  pointer to the previous in-order node before __x.\n// Precondition:  __x != nullptr.\ntemplate <class _NodePtr>\n_NodePtr\n__tree_prev(_NodePtr __x) _NOEXCEPT\n{\n    if (__x->__left_ != nullptr)\n        return __tree_max(__x->__left_);\n    while (__tree_is_left_child(__x))\n        __x = __x->__parent_;\n    return __x->__parent_;\n}\n\n// Returns:  pointer to a node which has no children\n// Precondition:  __x != nullptr.\ntemplate <class _NodePtr>\n_NodePtr\n__tree_leaf(_NodePtr __x) _NOEXCEPT\n{\n    while (true)\n    {\n        if (__x->__left_ != nullptr)\n        {\n            __x = __x->__left_;\n            continue;\n        }\n        if (__x->__right_ != nullptr)\n        {\n            __x = __x->__right_;\n            continue;\n        }\n        break;\n    }\n    return __x;\n}\n\n// Effects:  Makes __x->__right_ the subtree root with __x as its left child\n//           while preserving in-order order.\n// Precondition:  __x->__right_ != nullptr\ntemplate <class _NodePtr>\nvoid\n__tree_left_rotate(_NodePtr __x) _NOEXCEPT\n{\n    _NodePtr __y = __x->__right_;\n    __x->__right_ = __y->__left_;\n    if (__x->__right_ != nullptr)\n        __x->__right_->__parent_ = __x;\n    __y->__parent_ = __x->__parent_;\n    if (__tree_is_left_child(__x))\n        __x->__parent_->__left_ = __y;\n    else\n        __x->__parent_->__right_ = __y;\n    __y->__left_ = __x;\n    __x->__parent_ = __y;\n}\n\n// Effects:  Makes __x->__left_ the subtree root with __x as its right child\n//           while preserving in-order order.\n// Precondition:  __x->__left_ != nullptr\ntemplate <class _NodePtr>\nvoid\n__tree_right_rotate(_NodePtr __x) _NOEXCEPT\n{\n    _NodePtr __y = __x->__left_;\n    __x->__left_ = __y->__right_;\n    if (__x->__left_ != nullptr)\n        __x->__left_->__parent_ = __x;\n    __y->__parent_ = __x->__parent_;\n    if (__tree_is_left_child(__x))\n        __x->__parent_->__left_ = __y;\n    else\n        __x->__parent_->__right_ = __y;\n    __y->__right_ = __x;\n    __x->__parent_ = __y;\n}\n\n// Effects:  Rebalances __root after attaching __x to a leaf.\n// Precondition:  __root != nulptr && __x != nullptr.\n//                __x has no children.\n//                __x == __root or == a direct or indirect child of __root.\n//                If __x were to be unlinked from __root (setting __root to\n//                  nullptr if __root == __x), __tree_invariant(__root) == true.\n// Postcondition: __tree_invariant(end_node->__left_) == true.  end_node->__left_\n//                may be different than the value passed in as __root.\ntemplate <class _NodePtr>\nvoid\n__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT\n{\n    __x->__is_black_ = __x == __root;\n    while (__x != __root && !__x->__parent_->__is_black_)\n    {\n        // __x->__parent_ != __root because __x->__parent_->__is_black == false\n        if (__tree_is_left_child(__x->__parent_))\n        {\n            _NodePtr __y = __x->__parent_->__parent_->__right_;\n            if (__y != nullptr && !__y->__is_black_)\n            {\n                __x = __x->__parent_;\n                __x->__is_black_ = true;\n                __x = __x->__parent_;\n                __x->__is_black_ = __x == __root;\n                __y->__is_black_ = true;\n            }\n            else\n            {\n                if (!__tree_is_left_child(__x))\n                {\n                    __x = __x->__parent_;\n                    __tree_left_rotate(__x);\n                }\n                __x = __x->__parent_;\n                __x->__is_black_ = true;\n                __x = __x->__parent_;\n                __x->__is_black_ = false;\n                __tree_right_rotate(__x);\n                break;\n            }\n        }\n        else\n        {\n            _NodePtr __y = __x->__parent_->__parent_->__left_;\n            if (__y != nullptr && !__y->__is_black_)\n            {\n                __x = __x->__parent_;\n                __x->__is_black_ = true;\n                __x = __x->__parent_;\n                __x->__is_black_ = __x == __root;\n                __y->__is_black_ = true;\n            }\n            else\n            {\n                if (__tree_is_left_child(__x))\n                {\n                    __x = __x->__parent_;\n                    __tree_right_rotate(__x);\n                }\n                __x = __x->__parent_;\n                __x->__is_black_ = true;\n                __x = __x->__parent_;\n                __x->__is_black_ = false;\n                __tree_left_rotate(__x);\n                break;\n            }\n        }\n    }\n}\n\n// Precondition:  __root != nullptr && __z != nullptr.\n//                __tree_invariant(__root) == true.\n//                __z == __root or == a direct or indirect child of __root.\n// Effects:  unlinks __z from the tree rooted at __root, rebalancing as needed.\n// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_\n//                nor any of its children refer to __z.  end_node->__left_\n//                may be different than the value passed in as __root.\ntemplate <class _NodePtr>\nvoid\n__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT\n{\n    // __z will be removed from the tree.  Client still needs to destruct/deallocate it\n    // __y is either __z, or if __z has two children, __tree_next(__z).\n    // __y will have at most one child.\n    // __y will be the initial hole in the tree (make the hole at a leaf)\n    _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ?\n                    __z : __tree_next(__z);\n    // __x is __y's possibly null single child\n    _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_;\n    // __w is __x's possibly null uncle (will become __x's sibling)\n    _NodePtr __w = nullptr;\n    // link __x to __y's parent, and find __w\n    if (__x != nullptr)\n        __x->__parent_ = __y->__parent_;\n    if (__tree_is_left_child(__y))\n    {\n        __y->__parent_->__left_ = __x;\n        if (__y != __root)\n            __w = __y->__parent_->__right_;\n        else\n            __root = __x;  // __w == nullptr\n    }\n    else\n    {\n        __y->__parent_->__right_ = __x;\n        // __y can't be root if it is a right child\n        __w = __y->__parent_->__left_;\n    }\n    bool __removed_black = __y->__is_black_;\n    // If we didn't remove __z, do so now by splicing in __y for __z,\n    //    but copy __z's color.  This does not impact __x or __w.\n    if (__y != __z)\n    {\n        // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr\n        __y->__parent_ = __z->__parent_;\n        if (__tree_is_left_child(__z))\n            __y->__parent_->__left_ = __y;\n        else\n            __y->__parent_->__right_ = __y;\n        __y->__left_ = __z->__left_;\n        __y->__left_->__parent_ = __y;\n        __y->__right_ = __z->__right_;\n        if (__y->__right_ != nullptr)\n            __y->__right_->__parent_ = __y;\n        __y->__is_black_ = __z->__is_black_;\n        if (__root == __z)\n            __root = __y;\n    }\n    // There is no need to rebalance if we removed a red, or if we removed\n    //     the last node.\n    if (__removed_black && __root != nullptr)\n    {\n        // Rebalance:\n        // __x has an implicit black color (transferred from the removed __y)\n        //    associated with it, no matter what its color is.\n        // If __x is __root (in which case it can't be null), it is supposed\n        //    to be black anyway, and if it is doubly black, then the double\n        //    can just be ignored.\n        // If __x is red (in which case it can't be null), then it can absorb\n        //    the implicit black just by setting its color to black.\n        // Since __y was black and only had one child (which __x points to), __x\n        //   is either red with no children, else null, otherwise __y would have\n        //   different black heights under left and right pointers.\n        // if (__x == __root || __x != nullptr && !__x->__is_black_)\n        if (__x != nullptr)\n            __x->__is_black_ = true;\n        else\n        {\n            //  Else __x isn't root, and is \"doubly black\", even though it may\n            //     be null.  __w can not be null here, else the parent would\n            //     see a black height >= 2 on the __x side and a black height\n            //     of 1 on the __w side (__w must be a non-null black or a red\n            //     with a non-null black child).\n            while (true)\n            {\n                if (!__tree_is_left_child(__w))  // if x is left child\n                {\n                    if (!__w->__is_black_)\n                    {\n                        __w->__is_black_ = true;\n                        __w->__parent_->__is_black_ = false;\n                        __tree_left_rotate(__w->__parent_);\n                        // __x is still valid\n                        // reset __root only if necessary\n                        if (__root == __w->__left_)\n                            __root = __w;\n                        // reset sibling, and it still can't be null\n                        __w = __w->__left_->__right_;\n                    }\n                    // __w->__is_black_ is now true, __w may have null children\n                    if ((__w->__left_  == nullptr || __w->__left_->__is_black_) &&\n                        (__w->__right_ == nullptr || __w->__right_->__is_black_))\n                    {\n                        __w->__is_black_ = false;\n                        __x = __w->__parent_;\n                        // __x can no longer be null\n                        if (__x == __root || !__x->__is_black_)\n                        {\n                            __x->__is_black_ = true;\n                            break;\n                        }\n                        // reset sibling, and it still can't be null\n                        __w = __tree_is_left_child(__x) ?\n                                    __x->__parent_->__right_ :\n                                    __x->__parent_->__left_;\n                        // continue;\n                    }\n                    else  // __w has a red child\n                    {\n                        if (__w->__right_ == nullptr || __w->__right_->__is_black_)\n                        {\n                            // __w left child is non-null and red\n                            __w->__left_->__is_black_ = true;\n                            __w->__is_black_ = false;\n                            __tree_right_rotate(__w);\n                            // __w is known not to be root, so root hasn't changed\n                            // reset sibling, and it still can't be null\n                            __w = __w->__parent_;\n                        }\n                        // __w has a right red child, left child may be null\n                        __w->__is_black_ = __w->__parent_->__is_black_;\n                        __w->__parent_->__is_black_ = true;\n                        __w->__right_->__is_black_ = true;\n                        __tree_left_rotate(__w->__parent_);\n                        break;\n                    }\n                }\n                else\n                {\n                    if (!__w->__is_black_)\n                    {\n                        __w->__is_black_ = true;\n                        __w->__parent_->__is_black_ = false;\n                        __tree_right_rotate(__w->__parent_);\n                        // __x is still valid\n                        // reset __root only if necessary\n                        if (__root == __w->__right_)\n                            __root = __w;\n                        // reset sibling, and it still can't be null\n                        __w = __w->__right_->__left_;\n                    }\n                    // __w->__is_black_ is now true, __w may have null children\n                    if ((__w->__left_  == nullptr || __w->__left_->__is_black_) &&\n                        (__w->__right_ == nullptr || __w->__right_->__is_black_))\n                    {\n                        __w->__is_black_ = false;\n                        __x = __w->__parent_;\n                        // __x can no longer be null\n                        if (!__x->__is_black_ || __x == __root)\n                        {\n                            __x->__is_black_ = true;\n                            break;\n                        }\n                        // reset sibling, and it still can't be null\n                        __w = __tree_is_left_child(__x) ?\n                                    __x->__parent_->__right_ :\n                                    __x->__parent_->__left_;\n                        // continue;\n                    }\n                    else  // __w has a red child\n                    {\n                        if (__w->__left_ == nullptr || __w->__left_->__is_black_)\n                        {\n                            // __w right child is non-null and red\n                            __w->__right_->__is_black_ = true;\n                            __w->__is_black_ = false;\n                            __tree_left_rotate(__w);\n                            // __w is known not to be root, so root hasn't changed\n                            // reset sibling, and it still can't be null\n                            __w = __w->__parent_;\n                        }\n                        // __w has a left red child, right child may be null\n                        __w->__is_black_ = __w->__parent_->__is_black_;\n                        __w->__parent_->__is_black_ = true;\n                        __w->__left_->__is_black_ = true;\n                        __tree_right_rotate(__w->__parent_);\n                        break;\n                    }\n                }\n            }\n        }\n    }\n}\n\ntemplate <class _Allocator> class __map_node_destructor;\n\ntemplate <class _Allocator>\nclass __tree_node_destructor\n{\n    typedef _Allocator                                      allocator_type;\n    typedef allocator_traits<allocator_type>                __alloc_traits;\n    typedef typename __alloc_traits::value_type::value_type value_type;\npublic:\n    typedef typename __alloc_traits::pointer                pointer;\nprivate:\n\n    allocator_type& __na_;\n\n    __tree_node_destructor& operator=(const __tree_node_destructor&);\n\npublic:\n    bool __value_constructed;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT\n        : __na_(__na),\n          __value_constructed(__val)\n        {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void operator()(pointer __p) _NOEXCEPT\n    {\n        if (__value_constructed)\n            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_));\n        if (__p)\n            __alloc_traits::deallocate(__na_, __p, 1);\n    }\n\n    template <class> friend class __map_node_destructor;\n};\n\n// node\n\ntemplate <class _Pointer>\nclass __tree_end_node\n{\npublic:\n    typedef _Pointer pointer;\n    pointer __left_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __tree_end_node() _NOEXCEPT : __left_() {}\n};\n\ntemplate <class _VoidPtr>\nclass __tree_node_base\n    : public __tree_end_node\n             <\n                typename pointer_traits<_VoidPtr>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n                     rebind<__tree_node_base<_VoidPtr> >\n#else\n                     rebind<__tree_node_base<_VoidPtr> >::other\n#endif\n             >\n{\n    __tree_node_base(const __tree_node_base&);\n    __tree_node_base& operator=(const __tree_node_base&);\npublic:\n    typedef typename pointer_traits<_VoidPtr>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<__tree_node_base>\n#else\n            rebind<__tree_node_base>::other\n#endif\n                                                pointer;\n    typedef typename pointer_traits<_VoidPtr>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<const __tree_node_base>\n#else\n            rebind<const __tree_node_base>::other\n#endif\n                                                const_pointer;\n    typedef __tree_end_node<pointer> base;\n\n    pointer __right_;\n    pointer __parent_;\n    bool __is_black_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __tree_node_base() _NOEXCEPT\n        : __right_(), __parent_(), __is_black_(false) {}\n};\n\ntemplate <class _Tp, class _VoidPtr>\nclass __tree_node\n    : public __tree_node_base<_VoidPtr>\n{\npublic:\n    typedef __tree_node_base<_VoidPtr> base;\n    typedef _Tp value_type;\n\n    value_type __value_;\n\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    template <class ..._Args>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit __tree_node(_Args&& ...__args)\n            : __value_(_VSTD::forward<_Args>(__args)...) {}\n#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __tree_node(const value_type& __v)\n            : __value_(__v) {}\n#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n};\n\ntemplate <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_iterator;\ntemplate <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;\n\ntemplate <class _Tp, class _NodePtr, class _DiffType>\nclass _LIBCPP_TYPE_VIS_ONLY __tree_iterator\n{\n    typedef _NodePtr                                              __node_pointer;\n    typedef typename pointer_traits<__node_pointer>::element_type __node;\n\n    __node_pointer __ptr_;\n\n    typedef pointer_traits<__node_pointer> __pointer_traits;\npublic:\n    typedef bidirectional_iterator_tag iterator_category;\n    typedef _Tp                        value_type;\n    typedef _DiffType                  difference_type;\n    typedef value_type&                reference;\n    typedef typename pointer_traits<__node_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<value_type>\n#else\n            rebind<value_type>::other\n#endif\n                                       pointer;\n\n    _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT\n#if _LIBCPP_STD_VER > 11\n    : __ptr_(nullptr)\n#endif\n    {}\n\n    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;}\n    _LIBCPP_INLINE_VISIBILITY pointer operator->() const\n        {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __tree_iterator& operator++() {\n      __ptr_ = static_cast<__node_pointer>(\n          __tree_next(static_cast<typename __node::base::pointer>(__ptr_)));\n      return *this;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    __tree_iterator operator++(int)\n        {__tree_iterator __t(*this); ++(*this); return __t;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __tree_iterator& operator--() {\n      __ptr_ = static_cast<__node_pointer>(\n          __tree_prev(static_cast<typename __node::base::pointer>(__ptr_)));\n      return *this;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    __tree_iterator operator--(int)\n        {__tree_iterator __t(*this); --(*this); return __t;}\n\n    friend _LIBCPP_INLINE_VISIBILITY \n        bool operator==(const __tree_iterator& __x, const __tree_iterator& __y)\n        {return __x.__ptr_ == __y.__ptr_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y)\n        {return !(__x == __y);}\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}\n    template <class, class, class> friend class __tree;\n    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_iterator;\n    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;\n    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;\n    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set;\n    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset;\n};\n\ntemplate <class _Tp, class _ConstNodePtr, class _DiffType>\nclass _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator\n{\n    typedef _ConstNodePtr                                         __node_pointer;\n    typedef typename pointer_traits<__node_pointer>::element_type __node;\n\n    __node_pointer __ptr_;\n\n    typedef pointer_traits<__node_pointer> __pointer_traits;\npublic:\n    typedef bidirectional_iterator_tag       iterator_category;\n    typedef _Tp                              value_type;\n    typedef _DiffType                        difference_type;\n    typedef const value_type&                reference;\n    typedef typename pointer_traits<__node_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<const value_type>\n#else\n            rebind<const value_type>::other\n#endif\n                                       pointer;\n\n    _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT\n#if _LIBCPP_STD_VER > 11\n    : __ptr_(nullptr)\n#endif\n    {}\n\nprivate:\n    typedef typename remove_const<__node>::type  __non_const_node;\n    typedef typename pointer_traits<__node_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<__non_const_node>\n#else\n            rebind<__non_const_node>::other\n#endif\n                                                 __non_const_node_pointer;\n    typedef __tree_iterator<value_type, __non_const_node_pointer, difference_type>\n                                                 __non_const_iterator;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT\n        : __ptr_(__p.__ptr_) {}\n\n    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;}\n    _LIBCPP_INLINE_VISIBILITY pointer operator->() const\n        {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __tree_const_iterator& operator++() {\n      typedef typename pointer_traits<__node_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n          rebind<typename __node::base>\n#else\n          rebind<typename __node::base>::other\n#endif\n              __node_base_pointer;\n\n      __ptr_ = static_cast<__node_pointer>(\n          __tree_next(static_cast<__node_base_pointer>(__ptr_)));\n      return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __tree_const_iterator operator++(int)\n        {__tree_const_iterator __t(*this); ++(*this); return __t;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __tree_const_iterator& operator--() {\n      typedef typename pointer_traits<__node_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n          rebind<typename __node::base>\n#else\n          rebind<typename __node::base>::other\n#endif\n              __node_base_pointer;\n\n      __ptr_ = static_cast<__node_pointer>(\n          __tree_prev(static_cast<__node_base_pointer>(__ptr_)));\n      return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __tree_const_iterator operator--(int)\n        {__tree_const_iterator __t(*this); --(*this); return __t;}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y)\n        {return __x.__ptr_ == __y.__ptr_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y)\n        {return !(__x == __y);}\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT\n        : __ptr_(__p) {}\n    template <class, class, class> friend class __tree;\n    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;\n    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;\n    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set;\n    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;\n};\n\ntemplate <class _Tp, class _Compare, class _Allocator>\nclass __tree\n{\npublic:\n    typedef _Tp                                      value_type;\n    typedef _Compare                                 value_compare;\n    typedef _Allocator                               allocator_type;\n    typedef allocator_traits<allocator_type>         __alloc_traits;\n    typedef typename __alloc_traits::pointer         pointer;\n    typedef typename __alloc_traits::const_pointer   const_pointer;\n    typedef typename __alloc_traits::size_type       size_type;\n    typedef typename __alloc_traits::difference_type difference_type;\n\n    typedef typename __alloc_traits::void_pointer  __void_pointer;\n\n    typedef __tree_node<value_type, __void_pointer> __node;\n    typedef __tree_node_base<__void_pointer>        __node_base;\n    typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;\n    typedef allocator_traits<__node_allocator>       __node_traits;\n    typedef typename __node_traits::pointer          __node_pointer;\n    typedef typename __node_traits::pointer          __node_const_pointer;\n    typedef typename __node_base::pointer            __node_base_pointer;\n    typedef typename __node_base::pointer            __node_base_const_pointer;\nprivate:\n    typedef typename __node_base::base __end_node_t;\n    typedef typename pointer_traits<__node_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<__end_node_t>\n#else\n            rebind<__end_node_t>::other\n#endif\n                                                     __end_node_ptr;\n    typedef typename pointer_traits<__node_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<__end_node_t>\n#else\n            rebind<__end_node_t>::other\n#endif\n                                                     __end_node_const_ptr;\n\n    __node_pointer                                          __begin_node_;\n    __compressed_pair<__end_node_t, __node_allocator>  __pair1_;\n    __compressed_pair<size_type, value_compare>        __pair3_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __node_pointer __end_node() _NOEXCEPT\n    {\n        return static_cast<__node_pointer>\n               (\n                   pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())\n               );\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    __node_const_pointer __end_node() const _NOEXCEPT\n    {\n        return static_cast<__node_const_pointer>\n               (\n                   pointer_traits<__end_node_const_ptr>::pointer_to(const_cast<__end_node_t&>(__pair1_.first()))\n               );\n    }\n    _LIBCPP_INLINE_VISIBILITY\n          __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();}\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    const __node_allocator& __node_alloc() const _NOEXCEPT\n        {return __pair1_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n          __node_pointer& __begin_node() _NOEXCEPT {return __begin_node_;}\n    _LIBCPP_INLINE_VISIBILITY\n    const __node_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;}\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type __alloc() const _NOEXCEPT\n        {return allocator_type(__node_alloc());}\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n          size_type& size() _NOEXCEPT {return __pair3_.first();}\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    const size_type& size() const _NOEXCEPT {return __pair3_.first();}\n    _LIBCPP_INLINE_VISIBILITY\n          value_compare& value_comp() _NOEXCEPT {return __pair3_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n    const value_compare& value_comp() const _NOEXCEPT\n        {return __pair3_.second();}\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __node_pointer __root() _NOEXCEPT\n        {return static_cast<__node_pointer>      (__end_node()->__left_);}\n    _LIBCPP_INLINE_VISIBILITY\n    __node_const_pointer __root() const _NOEXCEPT\n        {return static_cast<__node_const_pointer>(__end_node()->__left_);}\n\n    typedef __tree_iterator<value_type, __node_pointer, difference_type>             iterator;\n    typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;\n\n    explicit __tree(const value_compare& __comp)\n        _NOEXCEPT_(\n            is_nothrow_default_constructible<__node_allocator>::value &&\n            is_nothrow_copy_constructible<value_compare>::value);\n    explicit __tree(const allocator_type& __a);\n    __tree(const value_compare& __comp, const allocator_type& __a);\n    __tree(const __tree& __t);\n    __tree& operator=(const __tree& __t);\n    template <class _InputIterator>\n        void __assign_unique(_InputIterator __first, _InputIterator __last);\n    template <class _InputIterator>\n        void __assign_multi(_InputIterator __first, _InputIterator __last);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __tree(__tree&& __t)\n        _NOEXCEPT_(\n            is_nothrow_move_constructible<__node_allocator>::value &&\n            is_nothrow_move_constructible<value_compare>::value);\n    __tree(__tree&& __t, const allocator_type& __a);\n    __tree& operator=(__tree&& __t)\n        _NOEXCEPT_(\n            __node_traits::propagate_on_container_move_assignment::value &&\n            is_nothrow_move_assignable<value_compare>::value &&\n            is_nothrow_move_assignable<__node_allocator>::value);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    ~__tree();\n\n    _LIBCPP_INLINE_VISIBILITY\n          iterator begin()  _NOEXCEPT {return       iterator(__begin_node());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());}\n    _LIBCPP_INLINE_VISIBILITY\n          iterator end() _NOEXCEPT {return       iterator(__end_node());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const _NOEXCEPT\n        {return __node_traits::max_size(__node_alloc());}\n\n    void clear() _NOEXCEPT;\n\n    void swap(__tree& __t)\n        _NOEXCEPT_(\n            __is_nothrow_swappable<value_compare>::value\n#if _LIBCPP_STD_VER <= 11\n            && (!__node_traits::propagate_on_container_swap::value ||\n                 __is_nothrow_swappable<__node_allocator>::value)\n#endif\n            );\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class... _Args>\n        pair<iterator, bool>\n        __emplace_unique(_Args&&... __args);\n    template <class... _Args>\n        iterator\n        __emplace_multi(_Args&&... __args);\n\n    template <class... _Args>\n        iterator\n        __emplace_hint_unique(const_iterator __p, _Args&&... __args);\n    template <class... _Args>\n        iterator\n        __emplace_hint_multi(const_iterator __p, _Args&&... __args);\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n    template <class _Vp>\n        pair<iterator, bool> __insert_unique(_Vp&& __v);\n    template <class _Vp>\n        iterator __insert_unique(const_iterator __p, _Vp&& __v);\n    template <class _Vp>\n        iterator __insert_multi(_Vp&& __v);\n    template <class _Vp>\n        iterator __insert_multi(const_iterator __p, _Vp&& __v);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    pair<iterator, bool> __insert_unique(const value_type& __v);\n    iterator __insert_unique(const_iterator __p, const value_type& __v);\n    iterator __insert_multi(const value_type& __v);\n    iterator __insert_multi(const_iterator __p, const value_type& __v);\n\n    pair<iterator, bool> __node_insert_unique(__node_pointer __nd);\n    iterator             __node_insert_unique(const_iterator __p,\n                                              __node_pointer __nd);\n\n    iterator __node_insert_multi(__node_pointer __nd);\n    iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);\n\n    iterator erase(const_iterator __p);\n    iterator erase(const_iterator __f, const_iterator __l);\n    template <class _Key>\n        size_type __erase_unique(const _Key& __k);\n    template <class _Key>\n        size_type __erase_multi(const _Key& __k);\n\n    void __insert_node_at(__node_base_pointer __parent,\n                          __node_base_pointer& __child,\n                          __node_base_pointer __new_node);\n\n    template <class _Key>\n        iterator find(const _Key& __v);\n    template <class _Key>\n        const_iterator find(const _Key& __v) const;\n\n    template <class _Key>\n        size_type __count_unique(const _Key& __k) const;\n    template <class _Key>\n        size_type __count_multi(const _Key& __k) const;\n\n    template <class _Key>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator lower_bound(const _Key& __v)\n            {return __lower_bound(__v, __root(), __end_node());}\n    template <class _Key>\n        iterator __lower_bound(const _Key& __v,\n                               __node_pointer __root,\n                               __node_pointer __result);\n    template <class _Key>\n        _LIBCPP_INLINE_VISIBILITY\n        const_iterator lower_bound(const _Key& __v) const\n            {return __lower_bound(__v, __root(), __end_node());}\n    template <class _Key>\n        const_iterator __lower_bound(const _Key& __v,\n                                     __node_const_pointer __root,\n                                     __node_const_pointer __result) const;\n    template <class _Key>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator upper_bound(const _Key& __v)\n            {return __upper_bound(__v, __root(), __end_node());}\n    template <class _Key>\n        iterator __upper_bound(const _Key& __v,\n                               __node_pointer __root,\n                               __node_pointer __result);\n    template <class _Key>\n        _LIBCPP_INLINE_VISIBILITY\n        const_iterator upper_bound(const _Key& __v) const\n            {return __upper_bound(__v, __root(), __end_node());}\n    template <class _Key>\n        const_iterator __upper_bound(const _Key& __v,\n                                     __node_const_pointer __root,\n                                     __node_const_pointer __result) const;\n    template <class _Key>\n        pair<iterator, iterator>\n        __equal_range_unique(const _Key& __k);\n    template <class _Key>\n        pair<const_iterator, const_iterator>\n        __equal_range_unique(const _Key& __k) const;\n\n    template <class _Key>\n        pair<iterator, iterator>\n        __equal_range_multi(const _Key& __k);\n    template <class _Key>\n        pair<const_iterator, const_iterator>\n        __equal_range_multi(const _Key& __k) const;\n\n    typedef __tree_node_destructor<__node_allocator> _Dp;\n    typedef unique_ptr<__node, _Dp> __node_holder;\n\n    __node_holder remove(const_iterator __p) _NOEXCEPT;\nprivate:\n    typename __node_base::pointer&\n        __find_leaf_low(typename __node_base::pointer& __parent, const value_type& __v);\n    typename __node_base::pointer&\n        __find_leaf_high(typename __node_base::pointer& __parent, const value_type& __v);\n    typename __node_base::pointer&\n        __find_leaf(const_iterator __hint,\n                    typename __node_base::pointer& __parent, const value_type& __v);\n    template <class _Key>\n        typename __node_base::pointer&\n        __find_equal(typename __node_base::pointer& __parent, const _Key& __v);\n    template <class _Key>\n        typename __node_base::pointer&\n        __find_equal(const_iterator __hint, typename __node_base::pointer& __parent,\n                     const _Key& __v);\n\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    template <class ..._Args>\n        __node_holder __construct_node(_Args&& ...__args);\n#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n        __node_holder __construct_node(const value_type& __v);\n#endif\n\n    void destroy(__node_pointer __nd) _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const __tree& __t)\n        {__copy_assign_alloc(__t, integral_constant<bool,\n             __node_traits::propagate_on_container_copy_assignment::value>());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const __tree& __t, true_type)\n        {__node_alloc() = __t.__node_alloc();}\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const __tree& __t, false_type) {}\n\n    void __move_assign(__tree& __t, false_type);\n    void __move_assign(__tree& __t, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&\n                   is_nothrow_move_assignable<__node_allocator>::value);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__tree& __t)\n        _NOEXCEPT_(\n            !__node_traits::propagate_on_container_move_assignment::value ||\n            is_nothrow_move_assignable<__node_allocator>::value)\n        {__move_assign_alloc(__t, integral_constant<bool,\n             __node_traits::propagate_on_container_move_assignment::value>());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__tree& __t, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)\n        {__node_alloc() = _VSTD::move(__t.__node_alloc());}\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__tree& __t, false_type) _NOEXCEPT {}\n\n    __node_pointer __detach();\n    static __node_pointer __detach(__node_pointer);\n\n    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;\n    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;\n};\n\ntemplate <class _Tp, class _Compare, class _Allocator>\n__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp)\n        _NOEXCEPT_(\n            is_nothrow_default_constructible<__node_allocator>::value &&\n            is_nothrow_copy_constructible<value_compare>::value)\n    : __pair3_(0, __comp)\n{\n    __begin_node() = __end_node();\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\n__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)\n    : __begin_node_(__node_pointer()),\n      __pair1_(__node_allocator(__a)),\n      __pair3_(0)\n{\n    __begin_node() = __end_node();\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\n__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp,\n                                           const allocator_type& __a)\n    : __begin_node_(__node_pointer()),\n      __pair1_(__node_allocator(__a)),\n      __pair3_(0, __comp)\n{\n    __begin_node() = __end_node();\n}\n\n// Precondition:  size() != 0\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::__node_pointer\n__tree<_Tp, _Compare, _Allocator>::__detach()\n{\n    __node_pointer __cache = __begin_node();\n    __begin_node() = __end_node();\n    __end_node()->__left_->__parent_ = nullptr;\n    __end_node()->__left_ = nullptr;\n    size() = 0;\n    // __cache->__left_ == nullptr\n    if (__cache->__right_ != nullptr)\n        __cache = static_cast<__node_pointer>(__cache->__right_);\n    // __cache->__left_ == nullptr\n    // __cache->__right_ == nullptr\n    return __cache;\n}\n\n// Precondition:  __cache != nullptr\n//    __cache->left_ == nullptr\n//    __cache->right_ == nullptr\n//    This is no longer a red-black tree\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::__node_pointer\n__tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache)\n{\n    if (__cache->__parent_ == nullptr)\n        return nullptr;\n    if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache)))\n    {\n        __cache->__parent_->__left_ = nullptr;\n        __cache = static_cast<__node_pointer>(__cache->__parent_);\n        if (__cache->__right_ == nullptr)\n            return __cache;\n        return static_cast<__node_pointer>(__tree_leaf(__cache->__right_));\n    }\n    // __cache is right child\n    __cache->__parent_->__right_ = nullptr;\n    __cache = static_cast<__node_pointer>(__cache->__parent_);\n    if (__cache->__left_ == nullptr)\n        return __cache;\n    return static_cast<__node_pointer>(__tree_leaf(__cache->__left_));\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\n__tree<_Tp, _Compare, _Allocator>&\n__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t)\n{\n    if (this != &__t)\n    {\n        value_comp() = __t.value_comp();\n        __copy_assign_alloc(__t);\n        __assign_multi(__t.begin(), __t.end());\n    }\n    return *this;\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _InputIterator>\nvoid\n__tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last)\n{\n    if (size() != 0)\n    {\n        __node_pointer __cache = __detach();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (; __cache != nullptr && __first != __last; ++__first)\n            {\n                __cache->__value_ = *__first;\n                __node_pointer __next = __detach(__cache);\n                __node_insert_unique(__cache);\n                __cache = __next;\n            }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            while (__cache->__parent_ != nullptr)\n                __cache = static_cast<__node_pointer>(__cache->__parent_);\n            destroy(__cache);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        if (__cache != nullptr)\n        {\n            while (__cache->__parent_ != nullptr)\n                __cache = static_cast<__node_pointer>(__cache->__parent_);\n            destroy(__cache);\n        }\n    }\n    for (; __first != __last; ++__first)\n        __insert_unique(*__first);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _InputIterator>\nvoid\n__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last)\n{\n    if (size() != 0)\n    {\n        __node_pointer __cache = __detach();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (; __cache != nullptr && __first != __last; ++__first)\n            {\n                __cache->__value_ = *__first;\n                __node_pointer __next = __detach(__cache);\n                __node_insert_multi(__cache);\n                __cache = __next;\n            }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            while (__cache->__parent_ != nullptr)\n                __cache = static_cast<__node_pointer>(__cache->__parent_);\n            destroy(__cache);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        if (__cache != nullptr)\n        {\n            while (__cache->__parent_ != nullptr)\n                __cache = static_cast<__node_pointer>(__cache->__parent_);\n            destroy(__cache);\n        }\n    }\n    for (; __first != __last; ++__first)\n        __insert_multi(*__first);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\n__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)\n    : __begin_node_(__node_pointer()),\n      __pair1_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())),\n      __pair3_(0, __t.value_comp())\n{\n    __begin_node() = __end_node();\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Compare, class _Allocator>\n__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)\n    _NOEXCEPT_(\n        is_nothrow_move_constructible<__node_allocator>::value &&\n        is_nothrow_move_constructible<value_compare>::value)\n    : __begin_node_(_VSTD::move(__t.__begin_node_)),\n      __pair1_(_VSTD::move(__t.__pair1_)),\n      __pair3_(_VSTD::move(__t.__pair3_))\n{\n    if (size() == 0)\n        __begin_node() = __end_node();\n    else\n    {\n        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());\n        __t.__begin_node() = __t.__end_node();\n        __t.__end_node()->__left_ = nullptr;\n        __t.size() = 0;\n    }\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\n__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)\n    : __pair1_(__node_allocator(__a)),\n      __pair3_(0, _VSTD::move(__t.value_comp()))\n{\n    if (__a == __t.__alloc())\n    {\n        if (__t.size() == 0)\n            __begin_node() = __end_node();\n        else\n        {\n            __begin_node() = __t.__begin_node();\n            __end_node()->__left_ = __t.__end_node()->__left_;\n            __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());\n            size() = __t.size();\n            __t.__begin_node() = __t.__end_node();\n            __t.__end_node()->__left_ = nullptr;\n            __t.size() = 0;\n        }\n    }\n    else\n    {\n        __begin_node() = __end_node();\n    }\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\nvoid\n__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)\n    _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&\n               is_nothrow_move_assignable<__node_allocator>::value)\n{\n    destroy(static_cast<__node_pointer>(__end_node()->__left_));\n    __begin_node_ = __t.__begin_node_;\n    __pair1_.first() = __t.__pair1_.first();\n    __move_assign_alloc(__t);\n    __pair3_ = _VSTD::move(__t.__pair3_);\n    if (size() == 0)\n        __begin_node() = __end_node();\n    else\n    {\n        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());\n        __t.__begin_node() = __t.__end_node();\n        __t.__end_node()->__left_ = nullptr;\n        __t.size() = 0;\n    }\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\nvoid\n__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type)\n{\n    if (__node_alloc() == __t.__node_alloc())\n        __move_assign(__t, true_type());\n    else\n    {\n        value_comp() = _VSTD::move(__t.value_comp());\n        const_iterator __e = end();\n        if (size() != 0)\n        {\n            __node_pointer __cache = __detach();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            try\n            {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n                while (__cache != nullptr && __t.size() != 0)\n                {\n                    __cache->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_);\n                    __node_pointer __next = __detach(__cache);\n                    __node_insert_multi(__cache);\n                    __cache = __next;\n                }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            }\n            catch (...)\n            {\n                while (__cache->__parent_ != nullptr)\n                    __cache = static_cast<__node_pointer>(__cache->__parent_);\n                destroy(__cache);\n                throw;\n            }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            if (__cache != nullptr)\n            {\n                while (__cache->__parent_ != nullptr)\n                    __cache = static_cast<__node_pointer>(__cache->__parent_);\n                destroy(__cache);\n            }\n        }\n        while (__t.size() != 0)\n            __insert_multi(__e, _VSTD::move(__t.remove(__t.begin())->__value_));\n    }\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\n__tree<_Tp, _Compare, _Allocator>&\n__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)\n    _NOEXCEPT_(\n        __node_traits::propagate_on_container_move_assignment::value &&\n        is_nothrow_move_assignable<value_compare>::value &&\n        is_nothrow_move_assignable<__node_allocator>::value)\n        \n{\n    __move_assign(__t, integral_constant<bool,\n                  __node_traits::propagate_on_container_move_assignment::value>());\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Compare, class _Allocator>\n__tree<_Tp, _Compare, _Allocator>::~__tree()\n{\n    destroy(__root());\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\nvoid\n__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT\n{\n    if (__nd != nullptr)\n    {\n        destroy(static_cast<__node_pointer>(__nd->__left_));\n        destroy(static_cast<__node_pointer>(__nd->__right_));\n        __node_allocator& __na = __node_alloc();\n        __node_traits::destroy(__na, _VSTD::addressof(__nd->__value_));\n        __node_traits::deallocate(__na, __nd, 1);\n    }\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\nvoid\n__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)\n        _NOEXCEPT_(\n            __is_nothrow_swappable<value_compare>::value\n#if _LIBCPP_STD_VER <= 11\n            && (!__node_traits::propagate_on_container_swap::value ||\n                 __is_nothrow_swappable<__node_allocator>::value)\n#endif\n            )\n{\n    using _VSTD::swap;\n    swap(__begin_node_, __t.__begin_node_);\n    swap(__pair1_.first(), __t.__pair1_.first());\n    __swap_allocator(__node_alloc(), __t.__node_alloc());\n    __pair3_.swap(__t.__pair3_);\n    if (size() == 0)\n        __begin_node() = __end_node();\n    else\n        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());\n    if (__t.size() == 0)\n        __t.__begin_node() = __t.__end_node();\n    else\n        __t.__end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__t.__end_node());\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\nvoid\n__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT\n{\n    destroy(__root());\n    size() = 0;\n    __begin_node() = __end_node();\n    __end_node()->__left_ = nullptr;\n}\n\n// Find lower_bound place to insert\n// Set __parent to parent of null leaf\n// Return reference to null leaf\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&\n__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node_base::pointer& __parent,\n                                                   const value_type& __v)\n{\n    __node_pointer __nd = __root();\n    if (__nd != nullptr)\n    {\n        while (true)\n        {\n            if (value_comp()(__nd->__value_, __v))\n            {\n                if (__nd->__right_ != nullptr)\n                    __nd = static_cast<__node_pointer>(__nd->__right_);\n                else\n                {\n                    __parent = static_cast<__node_base_pointer>(__nd);\n                    return __parent->__right_;\n                }\n            }\n            else\n            {\n                if (__nd->__left_ != nullptr)\n                    __nd = static_cast<__node_pointer>(__nd->__left_);\n                else\n                {\n                    __parent = static_cast<__node_base_pointer>(__nd);\n                    return __parent->__left_;\n                }\n            }\n        }\n    }\n    __parent = static_cast<__node_base_pointer>(__end_node());\n    return __parent->__left_;\n}\n\n// Find upper_bound place to insert\n// Set __parent to parent of null leaf\n// Return reference to null leaf\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&\n__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node_base::pointer& __parent,\n                                                    const value_type& __v)\n{\n    __node_pointer __nd = __root();\n    if (__nd != nullptr)\n    {\n        while (true)\n        {\n            if (value_comp()(__v, __nd->__value_))\n            {\n                if (__nd->__left_ != nullptr)\n                    __nd = static_cast<__node_pointer>(__nd->__left_);\n                else\n                {\n                    __parent = static_cast<__node_base_pointer>(__nd);\n                    return __parent->__left_;\n                }\n            }\n            else\n            {\n                if (__nd->__right_ != nullptr)\n                    __nd = static_cast<__node_pointer>(__nd->__right_);\n                else\n                {\n                    __parent = static_cast<__node_base_pointer>(__nd);\n                    return __parent->__right_;\n                }\n            }\n        }\n    }\n    __parent = static_cast<__node_base_pointer>(__end_node());\n    return __parent->__left_;\n}\n\n// Find leaf place to insert closest to __hint\n// First check prior to __hint.\n// Next check after __hint.\n// Next do O(log N) search.\n// Set __parent to parent of null leaf\n// Return reference to null leaf\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&\n__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint,\n                                               typename __node_base::pointer& __parent,\n                                               const value_type& __v)\n{\n    if (__hint == end() || !value_comp()(*__hint, __v))  // check before\n    {\n        // __v <= *__hint\n        const_iterator __prior = __hint;\n        if (__prior == begin() || !value_comp()(__v, *--__prior))\n        {\n            // *prev(__hint) <= __v <= *__hint\n            if (__hint.__ptr_->__left_ == nullptr)\n            {\n                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);\n                return __parent->__left_;\n            }\n            else\n            {\n                __parent = static_cast<__node_base_pointer>(__prior.__ptr_);\n                return __parent->__right_;\n            }\n        }\n        // __v < *prev(__hint)\n        return __find_leaf_high(__parent, __v);\n    }\n    // else __v > *__hint\n    return __find_leaf_low(__parent, __v);\n}\n\n// Find place to insert if __v doesn't exist\n// Set __parent to parent of null leaf\n// Return reference to null leaf\n// If __v exists, set parent to node of __v and return reference to node of __v\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\ntypename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&\n__tree<_Tp, _Compare, _Allocator>::__find_equal(typename __node_base::pointer& __parent,\n                                                const _Key& __v)\n{\n    __node_pointer __nd = __root();\n    if (__nd != nullptr)\n    {\n        while (true)\n        {\n            if (value_comp()(__v, __nd->__value_))\n            {\n                if (__nd->__left_ != nullptr)\n                    __nd = static_cast<__node_pointer>(__nd->__left_);\n                else\n                {\n                    __parent = static_cast<__node_base_pointer>(__nd);\n                    return __parent->__left_;\n                }\n            }\n            else if (value_comp()(__nd->__value_, __v))\n            {\n                if (__nd->__right_ != nullptr)\n                    __nd = static_cast<__node_pointer>(__nd->__right_);\n                else\n                {\n                    __parent = static_cast<__node_base_pointer>(__nd);\n                    return __parent->__right_;\n                }\n            }\n            else\n            {\n                __parent = static_cast<__node_base_pointer>(__nd);\n                return __parent;\n            }\n        }\n    }\n    __parent = static_cast<__node_base_pointer>(__end_node());\n    return __parent->__left_;\n}\n\n// Find place to insert if __v doesn't exist\n// First check prior to __hint.\n// Next check after __hint.\n// Next do O(log N) search.\n// Set __parent to parent of null leaf\n// Return reference to null leaf\n// If __v exists, set parent to node of __v and return reference to node of __v\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\ntypename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&\n__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,\n                                                typename __node_base::pointer& __parent,\n                                                const _Key& __v)\n{\n    if (__hint == end() || value_comp()(__v, *__hint))  // check before\n    {\n        // __v < *__hint\n        const_iterator __prior = __hint;\n        if (__prior == begin() || value_comp()(*--__prior, __v))\n        {\n            // *prev(__hint) < __v < *__hint\n            if (__hint.__ptr_->__left_ == nullptr)\n            {\n                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);\n                return __parent->__left_;\n            }\n            else\n            {\n                __parent = static_cast<__node_base_pointer>(__prior.__ptr_);\n                return __parent->__right_;\n            }\n        }\n        // __v <= *prev(__hint)\n        return __find_equal(__parent, __v);\n    }\n    else if (value_comp()(*__hint, __v))  // check after\n    {\n        // *__hint < __v\n        const_iterator __next = _VSTD::next(__hint);\n        if (__next == end() || value_comp()(__v, *__next))\n        {\n            // *__hint < __v < *_VSTD::next(__hint)\n            if (__hint.__ptr_->__right_ == nullptr)\n            {\n                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);\n                return __parent->__right_;\n            }\n            else\n            {\n                __parent = static_cast<__node_base_pointer>(__next.__ptr_);\n                return __parent->__left_;\n            }\n        }\n        // *next(__hint) <= __v\n        return __find_equal(__parent, __v);\n    }\n    // else __v == *__hint\n    __parent = static_cast<__node_base_pointer>(__hint.__ptr_);\n    return __parent;\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\nvoid\n__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__node_base_pointer __parent,\n                                                    __node_base_pointer& __child,\n                                                    __node_base_pointer __new_node)\n{\n    __new_node->__left_   = nullptr;\n    __new_node->__right_  = nullptr;\n    __new_node->__parent_ = __parent;\n    __child = __new_node;\n    if (__begin_node()->__left_ != nullptr)\n        __begin_node() = static_cast<__node_pointer>(__begin_node()->__left_);\n    __tree_balance_after_insert(__end_node()->__left_, __child);\n    ++size();\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class ..._Args>\ntypename __tree<_Tp, _Compare, _Allocator>::__node_holder\n__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args)\n{\n    __node_allocator& __na = __node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...);\n    __h.get_deleter().__value_constructed = true;\n    return __h;\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class... _Args>\npair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>\n__tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_equal(__parent, __h->__value_);\n    __node_pointer __r = static_cast<__node_pointer>(__child);\n    bool __inserted = false;\n    if (__child == nullptr)\n    {\n        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));\n        __r = __h.release();\n        __inserted = true;\n    }\n    return pair<iterator, bool>(iterator(__r), __inserted);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class... _Args>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique(const_iterator __p, _Args&&... __args)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_equal(__p, __parent, __h->__value_);\n    __node_pointer __r = static_cast<__node_pointer>(__child);\n    if (__child == nullptr)\n    {\n        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));\n        __r = __h.release();\n    }\n    return iterator(__r);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class... _Args>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);\n    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));\n    return iterator(static_cast<__node_pointer>(__h.release()));\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class... _Args>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p,\n                                                        _Args&&... __args)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);\n    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));\n    return iterator(static_cast<__node_pointer>(__h.release()));\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Vp>\npair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>\n__tree<_Tp, _Compare, _Allocator>::__insert_unique(_Vp&& __v)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v));\n    pair<iterator, bool> __r = __node_insert_unique(__h.get());\n    if (__r.second)\n        __h.release();\n    return __r;\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Vp>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, _Vp&& __v)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v));\n    iterator __r = __node_insert_unique(__p, __h.get());\n    if (__r.__ptr_ == __h.get())\n        __h.release();\n    return __r;\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Vp>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::__insert_multi(_Vp&& __v)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v));\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);\n    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));\n    return iterator(__h.release());\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Vp>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, _Vp&& __v)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v));\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);\n    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));\n    return iterator(__h.release());\n}\n\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::__node_holder\n__tree<_Tp, _Compare, _Allocator>::__construct_node(const value_type& __v)\n{\n    __node_allocator& __na = __node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v);\n    __h.get_deleter().__value_constructed = true;\n    return _VSTD::move(__h);  // explicitly moved for C++03\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Compare, class _Allocator>\npair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>\n__tree<_Tp, _Compare, _Allocator>::__insert_unique(const value_type& __v)\n{\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_equal(__parent, __v);\n    __node_pointer __r = static_cast<__node_pointer>(__child);\n    bool __inserted = false;\n    if (__child == nullptr)\n    {\n        __node_holder __h = __construct_node(__v);\n        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));\n        __r = __h.release();\n        __inserted = true;\n    }\n    return pair<iterator, bool>(iterator(__r), __inserted);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, const value_type& __v)\n{\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_equal(__p, __parent, __v);\n    __node_pointer __r = static_cast<__node_pointer>(__child);\n    if (__child == nullptr)\n    {\n        __node_holder __h = __construct_node(__v);\n        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));\n        __r = __h.release();\n    }\n    return iterator(__r);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::__insert_multi(const value_type& __v)\n{\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_leaf_high(__parent, __v);\n    __node_holder __h = __construct_node(__v);\n    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));\n    return iterator(__h.release());\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const value_type& __v)\n{\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_leaf(__p, __parent, __v);\n    __node_holder __h = __construct_node(__v);\n    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));\n    return iterator(__h.release());\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\npair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>\n__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd)\n{\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_equal(__parent, __nd->__value_);\n    __node_pointer __r = static_cast<__node_pointer>(__child);\n    bool __inserted = false;\n    if (__child == nullptr)\n    {\n        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));\n        __r = __nd;\n        __inserted = true;\n    }\n    return pair<iterator, bool>(iterator(__r), __inserted);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p,\n                                                        __node_pointer __nd)\n{\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_);\n    __node_pointer __r = static_cast<__node_pointer>(__child);\n    if (__child == nullptr)\n    {\n        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));\n        __r = __nd;\n    }\n    return iterator(__r);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)\n{\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_);\n    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));\n    return iterator(__nd);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,\n                                                       __node_pointer __nd)\n{\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_);\n    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));\n    return iterator(__nd);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)\n{\n    __node_pointer __np = __p.__ptr_;\n    iterator __r(__np);\n    ++__r;\n    if (__begin_node() == __np)\n        __begin_node() = __r.__ptr_;\n    --size();\n    __node_allocator& __na = __node_alloc();\n    __tree_remove(__end_node()->__left_,\n                  static_cast<__node_base_pointer>(__np));\n    __node_traits::destroy(__na, const_cast<value_type*>(_VSTD::addressof(*__p)));\n    __node_traits::deallocate(__na, __np, 1);\n    return __r;\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l)\n{\n    while (__f != __l)\n        __f = erase(__f);\n    return iterator(__l.__ptr_);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\ntypename __tree<_Tp, _Compare, _Allocator>::size_type\n__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k)\n{\n    iterator __i = find(__k);\n    if (__i == end())\n        return 0;\n    erase(__i);\n    return 1;\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\ntypename __tree<_Tp, _Compare, _Allocator>::size_type\n__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k)\n{\n    pair<iterator, iterator> __p = __equal_range_multi(__k);\n    size_type __r = 0;\n    for (; __p.first != __p.second; ++__r)\n        __p.first = erase(__p.first);\n    return __r;\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v)\n{\n    iterator __p = __lower_bound(__v, __root(), __end_node());\n    if (__p != end() && !value_comp()(__v, *__p))\n        return __p;\n    return end();\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\ntypename __tree<_Tp, _Compare, _Allocator>::const_iterator\n__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const\n{\n    const_iterator __p = __lower_bound(__v, __root(), __end_node());\n    if (__p != end() && !value_comp()(__v, *__p))\n        return __p;\n    return end();\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\ntypename __tree<_Tp, _Compare, _Allocator>::size_type\n__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const\n{\n    __node_const_pointer __result = __end_node();\n    __node_const_pointer __rt = __root();\n    while (__rt != nullptr)\n    {\n        if (value_comp()(__k, __rt->__value_))\n        {\n            __result = __rt;\n            __rt = static_cast<__node_const_pointer>(__rt->__left_);\n        }\n        else if (value_comp()(__rt->__value_, __k))\n            __rt = static_cast<__node_const_pointer>(__rt->__right_);\n        else\n            return 1;\n    }\n    return 0;\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\ntypename __tree<_Tp, _Compare, _Allocator>::size_type\n__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const\n{\n    __node_const_pointer __result = __end_node();\n    __node_const_pointer __rt = __root();\n    while (__rt != nullptr)\n    {\n        if (value_comp()(__k, __rt->__value_))\n        {\n            __result = __rt;\n            __rt = static_cast<__node_const_pointer>(__rt->__left_);\n        }\n        else if (value_comp()(__rt->__value_, __k))\n            __rt = static_cast<__node_const_pointer>(__rt->__right_);\n        else\n            return _VSTD::distance(\n                __lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt),\n                __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result)\n            );\n    }\n    return 0;\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,\n                                                 __node_pointer __root,\n                                                 __node_pointer __result)\n{\n    while (__root != nullptr)\n    {\n        if (!value_comp()(__root->__value_, __v))\n        {\n            __result = __root;\n            __root = static_cast<__node_pointer>(__root->__left_);\n        }\n        else\n            __root = static_cast<__node_pointer>(__root->__right_);\n    }\n    return iterator(__result);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\ntypename __tree<_Tp, _Compare, _Allocator>::const_iterator\n__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,\n                                                 __node_const_pointer __root,\n                                                 __node_const_pointer __result) const\n{\n    while (__root != nullptr)\n    {\n        if (!value_comp()(__root->__value_, __v))\n        {\n            __result = __root;\n            __root = static_cast<__node_const_pointer>(__root->__left_);\n        }\n        else\n            __root = static_cast<__node_const_pointer>(__root->__right_);\n    }\n    return const_iterator(__result);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\ntypename __tree<_Tp, _Compare, _Allocator>::iterator\n__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,\n                                                 __node_pointer __root,\n                                                 __node_pointer __result)\n{\n    while (__root != nullptr)\n    {\n        if (value_comp()(__v, __root->__value_))\n        {\n            __result = __root;\n            __root = static_cast<__node_pointer>(__root->__left_);\n        }\n        else\n            __root = static_cast<__node_pointer>(__root->__right_);\n    }\n    return iterator(__result);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\ntypename __tree<_Tp, _Compare, _Allocator>::const_iterator\n__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,\n                                                 __node_const_pointer __root,\n                                                 __node_const_pointer __result) const\n{\n    while (__root != nullptr)\n    {\n        if (value_comp()(__v, __root->__value_))\n        {\n            __result = __root;\n            __root = static_cast<__node_const_pointer>(__root->__left_);\n        }\n        else\n            __root = static_cast<__node_const_pointer>(__root->__right_);\n    }\n    return const_iterator(__result);\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\npair<typename __tree<_Tp, _Compare, _Allocator>::iterator,\n     typename __tree<_Tp, _Compare, _Allocator>::iterator>\n__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k)\n{\n    typedef pair<iterator, iterator> _Pp;\n    __node_pointer __result = __end_node();\n    __node_pointer __rt = __root();\n    while (__rt != nullptr)\n    {\n        if (value_comp()(__k, __rt->__value_))\n        {\n            __result = __rt;\n            __rt = static_cast<__node_pointer>(__rt->__left_);\n        }\n        else if (value_comp()(__rt->__value_, __k))\n            __rt = static_cast<__node_pointer>(__rt->__right_);\n        else\n            return _Pp(iterator(__rt),\n                      iterator(\n                          __rt->__right_ != nullptr ?\n                              static_cast<__node_pointer>(__tree_min(__rt->__right_))\n                            : __result));\n    }\n    return _Pp(iterator(__result), iterator(__result));\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\npair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,\n     typename __tree<_Tp, _Compare, _Allocator>::const_iterator>\n__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const\n{\n    typedef pair<const_iterator, const_iterator> _Pp;\n    __node_const_pointer __result = __end_node();\n    __node_const_pointer __rt = __root();\n    while (__rt != nullptr)\n    {\n        if (value_comp()(__k, __rt->__value_))\n        {\n            __result = __rt;\n            __rt = static_cast<__node_const_pointer>(__rt->__left_);\n        }\n        else if (value_comp()(__rt->__value_, __k))\n            __rt = static_cast<__node_const_pointer>(__rt->__right_);\n        else\n            return _Pp(const_iterator(__rt),\n                      const_iterator(\n                          __rt->__right_ != nullptr ?\n                              static_cast<__node_const_pointer>(__tree_min(__rt->__right_))\n                            : __result));\n    }\n    return _Pp(const_iterator(__result), const_iterator(__result));\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\npair<typename __tree<_Tp, _Compare, _Allocator>::iterator,\n     typename __tree<_Tp, _Compare, _Allocator>::iterator>\n__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k)\n{\n    typedef pair<iterator, iterator> _Pp;\n    __node_pointer __result = __end_node();\n    __node_pointer __rt = __root();\n    while (__rt != nullptr)\n    {\n        if (value_comp()(__k, __rt->__value_))\n        {\n            __result = __rt;\n            __rt = static_cast<__node_pointer>(__rt->__left_);\n        }\n        else if (value_comp()(__rt->__value_, __k))\n            __rt = static_cast<__node_pointer>(__rt->__right_);\n        else\n            return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), __rt),\n                      __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));\n    }\n    return _Pp(iterator(__result), iterator(__result));\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntemplate <class _Key>\npair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,\n     typename __tree<_Tp, _Compare, _Allocator>::const_iterator>\n__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const\n{\n    typedef pair<const_iterator, const_iterator> _Pp;\n    __node_const_pointer __result = __end_node();\n    __node_const_pointer __rt = __root();\n    while (__rt != nullptr)\n    {\n        if (value_comp()(__k, __rt->__value_))\n        {\n            __result = __rt;\n            __rt = static_cast<__node_const_pointer>(__rt->__left_);\n        }\n        else if (value_comp()(__rt->__value_, __k))\n            __rt = static_cast<__node_const_pointer>(__rt->__right_);\n        else\n            return _Pp(__lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt),\n                      __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result));\n    }\n    return _Pp(const_iterator(__result), const_iterator(__result));\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ntypename __tree<_Tp, _Compare, _Allocator>::__node_holder\n__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT\n{\n    __node_pointer __np = __p.__ptr_;\n    if (__begin_node() == __np)\n    {\n        if (__np->__right_ != nullptr)\n            __begin_node() = static_cast<__node_pointer>(__np->__right_);\n        else\n            __begin_node() = static_cast<__node_pointer>(__np->__parent_);\n    }\n    --size();\n    __tree_remove(__end_node()->__left_,\n                  static_cast<__node_base_pointer>(__np));\n    return __node_holder(__np, _Dp(__node_alloc(), true));\n}\n\ntemplate <class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(__tree<_Tp, _Compare, _Allocator>& __x,\n     __tree<_Tp, _Compare, _Allocator>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP___TREE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__tuple",
    "content": "// -*- C++ -*-\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP___TUPLE\n#define _LIBCPP___TUPLE\n\n#include <__config>\n#include <cstddef>\n#include <type_traits>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size;\n\ntemplate <class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_size<const _Tp>\n    : public tuple_size<_Tp> {};\n\ntemplate <class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_size<volatile _Tp>\n    : public tuple_size<_Tp> {};\n\ntemplate <class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_size<const volatile _Tp>\n    : public tuple_size<_Tp> {};\n\ntemplate <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_element;\n\ntemplate <size_t _Ip, class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const _Tp>\n{\npublic:\n    typedef typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type;\n};\n\ntemplate <size_t _Ip, class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, volatile _Tp>\n{\npublic:\n    typedef typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type;\n};\n\ntemplate <size_t _Ip, class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const volatile _Tp>\n{\npublic:\n    typedef typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type;\n};\n\ntemplate <class _Tp> struct __tuple_like : false_type {};\n\ntemplate <class _Tp> struct __tuple_like<const _Tp> : public __tuple_like<_Tp> {};\ntemplate <class _Tp> struct __tuple_like<volatile _Tp> : public __tuple_like<_Tp> {};\ntemplate <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_like<_Tp> {};\n\n// tuple specializations\n\n#if !defined(_LIBCPP_HAS_NO_VARIADICS)\ntemplate <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple;\n\ntemplate <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {};\n\ntemplate <size_t _Ip, class ..._Tp>\n_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntypename tuple_element<_Ip, tuple<_Tp...> >::type&\nget(tuple<_Tp...>&) _NOEXCEPT;\n\ntemplate <size_t _Ip, class ..._Tp>\n_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nconst typename tuple_element<_Ip, tuple<_Tp...> >::type&\nget(const tuple<_Tp...>&) _NOEXCEPT;\n\ntemplate <size_t _Ip, class ..._Tp>\n_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntypename tuple_element<_Ip, tuple<_Tp...> >::type&&\nget(tuple<_Tp...>&&) _NOEXCEPT;\n#endif\n\n// pair specializations\n\ntemplate <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair;\n\ntemplate <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {};\n\ntemplate <size_t _Ip, class _T1, class _T2>\n_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntypename tuple_element<_Ip, pair<_T1, _T2> >::type&\nget(pair<_T1, _T2>&) _NOEXCEPT;\n\ntemplate <size_t _Ip, class _T1, class _T2>\n_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nconst typename tuple_element<_Ip, pair<_T1, _T2> >::type&\nget(const pair<_T1, _T2>&) _NOEXCEPT;\n\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\ntemplate <size_t _Ip, class _T1, class _T2>\n_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntypename tuple_element<_Ip, pair<_T1, _T2> >::type&&\nget(pair<_T1, _T2>&&) _NOEXCEPT;\n#endif\n\n// array specializations\n\ntemplate <class _Tp, size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY array;\n\ntemplate <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {};\n\ntemplate <size_t _Ip, class _Tp, size_t _Size>\n_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_Tp&\nget(array<_Tp, _Size>&) _NOEXCEPT;\n\ntemplate <size_t _Ip, class _Tp, size_t _Size>\n_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nconst _Tp&\nget(const array<_Tp, _Size>&) _NOEXCEPT;\n\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\ntemplate <size_t _Ip, class _Tp, size_t _Size>\n_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_Tp&&\nget(array<_Tp, _Size>&&) _NOEXCEPT;\n#endif\n\n#if !defined(_LIBCPP_HAS_NO_VARIADICS)\n\n// __lazy_and\n\ntemplate <bool _Last, class ..._Preds>\nstruct __lazy_and_impl;\n\ntemplate <class ..._Preds>\nstruct __lazy_and_impl<false, _Preds...> : false_type {};\n\ntemplate <>\nstruct __lazy_and_impl<true> : true_type {};\n\ntemplate <class _Pred>\nstruct __lazy_and_impl<true, _Pred> : integral_constant<bool, _Pred::type::value> {};\n\ntemplate <class _Hp, class ..._Tp>\nstruct __lazy_and_impl<true, _Hp, _Tp...> : __lazy_and_impl<_Hp::type::value, _Tp...> {};\n\ntemplate <class _P1, class ..._Pr>\nstruct __lazy_and : __lazy_and_impl<_P1::type::value, _Pr...> {};\n\n// __lazy_not\n\ntemplate <class _Pred>\nstruct __lazy_not : integral_constant<bool, !_Pred::type::value> {};\n\n// __make_tuple_indices\n\ntemplate <size_t...> struct __tuple_indices {};\n\ntemplate <size_t _Sp, class _IntTuple, size_t _Ep>\nstruct __make_indices_imp;\n\ntemplate <size_t _Sp, size_t ..._Indices, size_t _Ep>\nstruct __make_indices_imp<_Sp, __tuple_indices<_Indices...>, _Ep>\n{\n    typedef typename __make_indices_imp<_Sp+1, __tuple_indices<_Indices..., _Sp>, _Ep>::type type;\n};\n\ntemplate <size_t _Ep, size_t ..._Indices>\nstruct __make_indices_imp<_Ep, __tuple_indices<_Indices...>, _Ep>\n{\n    typedef __tuple_indices<_Indices...> type;\n};\n\ntemplate <size_t _Ep, size_t _Sp = 0>\nstruct __make_tuple_indices\n{\n    static_assert(_Sp <= _Ep, \"__make_tuple_indices input error\");\n    typedef typename __make_indices_imp<_Sp, __tuple_indices<>, _Ep>::type type;\n};\n\n// __tuple_types\n\ntemplate <class ..._Tp> struct __tuple_types {};\n\ntemplate <size_t _Ip>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<> >\n{\npublic:\n    static_assert(_Ip == 0, \"tuple_element index out of range\");\n    static_assert(_Ip != 0, \"tuple_element index out of range\");\n};\n\ntemplate <class _Hp, class ..._Tp>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_element<0, __tuple_types<_Hp, _Tp...> >\n{\npublic:\n    typedef _Hp type;\n};\n\ntemplate <size_t _Ip, class _Hp, class ..._Tp>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<_Hp, _Tp...> >\n{\npublic:\n    typedef typename tuple_element<_Ip-1, __tuple_types<_Tp...> >::type type;\n};\n\ntemplate <class ..._Tp>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_size<__tuple_types<_Tp...> >\n    : public integral_constant<size_t, sizeof...(_Tp)>\n{\n};\n\ntemplate <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type {};\n\n// __make_tuple_types\n\n// __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a\n// __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep).\n// _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>.  If _Tuple is a\n// lvalue_reference type, then __tuple_types<_Types&...> is the result.\n\ntemplate <class _TupleTypes, class _Tp, size_t _Sp, size_t _Ep>\nstruct __make_tuple_types_imp;\n\ntemplate <class ..._Types, class _Tp, size_t _Sp, size_t _Ep>\nstruct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Sp, _Ep>\n{\n    typedef typename remove_reference<_Tp>::type _Tpr;\n    typedef typename __make_tuple_types_imp<__tuple_types<_Types...,\n                                            typename conditional<is_lvalue_reference<_Tp>::value,\n                                                typename tuple_element<_Sp, _Tpr>::type&,\n                                                typename tuple_element<_Sp, _Tpr>::type>::type>,\n                                            _Tp, _Sp+1, _Ep>::type type;\n};\n\ntemplate <class ..._Types, class _Tp, size_t _Ep>\nstruct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Ep, _Ep>\n{\n    typedef __tuple_types<_Types...> type;\n};\n\ntemplate <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value, size_t _Sp = 0>\nstruct __make_tuple_types\n{\n    static_assert(_Sp <= _Ep, \"__make_tuple_types input error\");\n    typedef typename __make_tuple_types_imp<__tuple_types<>, _Tp, _Sp, _Ep>::type type;\n};\n\n// __tuple_convertible\n\ntemplate <class, class>\nstruct __tuple_convertible_imp : public false_type {};\n\ntemplate <class _Tp0, class ..._Tp, class _Up0, class ..._Up>\nstruct __tuple_convertible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> >\n    : public integral_constant<bool,\n                               is_convertible<_Tp0, _Up0>::value &&\n                               __tuple_convertible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {};\n\ntemplate <>\nstruct __tuple_convertible_imp<__tuple_types<>, __tuple_types<> >\n    : public true_type {};\n\ntemplate <bool, class, class>\nstruct __tuple_convertible_apply : public false_type {};\n\ntemplate <class _Tp, class _Up>\nstruct __tuple_convertible_apply<true, _Tp, _Up>\n  : public __tuple_convertible_imp<\n      typename __make_tuple_types<_Tp>::type\n    , typename __make_tuple_types<_Up>::type\n    >\n{};\n\ntemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,\n                                bool = __tuple_like<_Up>::value>\nstruct __tuple_convertible\n    : public false_type {};\n\ntemplate <class _Tp, class _Up>\nstruct __tuple_convertible<_Tp, _Up, true, true>\n    : public __tuple_convertible_apply<tuple_size<typename remove_reference<_Tp>::type>::value ==\n                                     tuple_size<_Up>::value, _Tp, _Up>\n{};\n\n// __tuple_constructible\n\ntemplate <class, class>\nstruct __tuple_constructible_imp : public false_type {};\n\ntemplate <class _Tp0, class ..._Tp, class _Up0, class ..._Up>\nstruct __tuple_constructible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> >\n    : public integral_constant<bool,\n                               is_constructible<_Up0, _Tp0>::value &&\n                               __tuple_constructible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {};\n\ntemplate <>\nstruct __tuple_constructible_imp<__tuple_types<>, __tuple_types<> >\n    : public true_type {};\n\ntemplate <bool _SameSize, class, class>\nstruct __tuple_constructible_apply : public false_type {};\n\ntemplate <class _Tp, class _Up>\nstruct __tuple_constructible_apply<true, _Tp, _Up>\n  : public __tuple_constructible_imp<\n      typename __make_tuple_types<_Tp>::type\n    , typename __make_tuple_types<_Up>::type\n    >\n{};\n\ntemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,\n                                bool = __tuple_like<_Up>::value>\nstruct __tuple_constructible\n    : public false_type {};\n\ntemplate <class _Tp, class _Up>\nstruct __tuple_constructible<_Tp, _Up, true, true>\n    : public __tuple_constructible_apply<tuple_size<typename remove_reference<_Tp>::type>::value ==\n                                     tuple_size<_Up>::value, _Tp, _Up>\n{};\n\n// __tuple_assignable\n\ntemplate <class, class>\nstruct __tuple_assignable_imp : public false_type {};\n\ntemplate <class _Tp0, class ..._Tp, class _Up0, class ..._Up>\nstruct __tuple_assignable_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> >\n    : public integral_constant<bool,\n                               is_assignable<_Up0&, _Tp0>::value &&\n                               __tuple_assignable_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {};\n\ntemplate <>\nstruct __tuple_assignable_imp<__tuple_types<>, __tuple_types<> >\n    : public true_type {};\n\ntemplate <bool, class, class>\nstruct __tuple_assignable_apply : public false_type {};\n\ntemplate <class _Tp, class _Up>\nstruct __tuple_assignable_apply<true, _Tp, _Up>\n  : __tuple_assignable_imp<\n      typename __make_tuple_types<_Tp>::type\n    , typename __make_tuple_types<_Up>::type\n    >\n{};\n\ntemplate <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,\n                                bool = __tuple_like<_Up>::value>\nstruct __tuple_assignable\n    : public false_type {};\n\ntemplate <class _Tp, class _Up>\nstruct __tuple_assignable<_Tp, _Up, true, true>\n    : public __tuple_assignable_apply<tuple_size<typename remove_reference<_Tp>::type>::value ==\n                                    tuple_size<_Up>::value, _Tp, _Up>\n{};\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP___TUPLE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__undef___deallocate",
    "content": "// -*- C++ -*-\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifdef __deallocate\n#if defined(_MSC_VER) && !defined(__clang__)\n_LIBCPP_WARNING(\"macro __deallocate is incompatible with C++.  #undefining __deallocate\")\n#else\n#warning: macro __deallocate is incompatible with C++.  #undefining __deallocate\n#endif\n#undef __deallocate\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/__undef_min_max",
    "content": "// -*- C++ -*-\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifdef min\n#if defined(_MSC_VER) && ! defined(__clang__)\n_LIBCPP_WARNING(\"macro min is incompatible with C++.  Try #define NOMINMAX \"\n                \"before any Windows header. #undefing min\")\n#else\n#warning: macro min is incompatible with C++.  #undefing min\n#endif\n#undef min\n#endif\n\n#ifdef max\n#if defined(_MSC_VER) && ! defined(__clang__)\n_LIBCPP_WARNING(\"macro max is incompatible with C++.  Try #define NOMINMAX \"\n                \"before any Windows header. #undefing max\")\n#else\n#warning: macro max is incompatible with C++.  #undefing max\n#endif\n#undef max\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/algorithm",
    "content": "// -*- C++ -*-\n//===-------------------------- algorithm ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_ALGORITHM\n#define _LIBCPP_ALGORITHM\n\n/*\n    algorithm synopsis\n\n#include <initializer_list>\n\nnamespace std\n{\n\ntemplate <class InputIterator, class Predicate>\n    bool\n    all_of(InputIterator first, InputIterator last, Predicate pred);\n\ntemplate <class InputIterator, class Predicate>\n    bool\n    any_of(InputIterator first, InputIterator last, Predicate pred);\n\ntemplate <class InputIterator, class Predicate>\n    bool\n    none_of(InputIterator first, InputIterator last, Predicate pred);\n\ntemplate <class InputIterator, class Function>\n    Function\n    for_each(InputIterator first, InputIterator last, Function f);\n\ntemplate <class InputIterator, class T>\n    InputIterator\n    find(InputIterator first, InputIterator last, const T& value);\n\ntemplate <class InputIterator, class Predicate>\n    InputIterator\n    find_if(InputIterator first, InputIterator last, Predicate pred);\n\ntemplate<class InputIterator, class Predicate>\n    InputIterator\n    find_if_not(InputIterator first, InputIterator last, Predicate pred);\n\ntemplate <class ForwardIterator1, class ForwardIterator2>\n    ForwardIterator1\n    find_end(ForwardIterator1 first1, ForwardIterator1 last1,\n             ForwardIterator2 first2, ForwardIterator2 last2);\n\ntemplate <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>\n    ForwardIterator1\n    find_end(ForwardIterator1 first1, ForwardIterator1 last1,\n             ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);\n\ntemplate <class ForwardIterator1, class ForwardIterator2>\n    ForwardIterator1\n    find_first_of(ForwardIterator1 first1, ForwardIterator1 last1,\n                  ForwardIterator2 first2, ForwardIterator2 last2);\n\ntemplate <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>\n    ForwardIterator1\n    find_first_of(ForwardIterator1 first1, ForwardIterator1 last1,\n                  ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);\n\ntemplate <class ForwardIterator>\n    ForwardIterator\n    adjacent_find(ForwardIterator first, ForwardIterator last);\n\ntemplate <class ForwardIterator, class BinaryPredicate>\n    ForwardIterator\n    adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate pred);\n\ntemplate <class InputIterator, class T>\n    typename iterator_traits<InputIterator>::difference_type\n    count(InputIterator first, InputIterator last, const T& value);\n\ntemplate <class InputIterator, class Predicate>\n    typename iterator_traits<InputIterator>::difference_type\n    count_if(InputIterator first, InputIterator last, Predicate pred);\n\ntemplate <class InputIterator1, class InputIterator2>\n    pair<InputIterator1, InputIterator2>\n    mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);\n\ntemplate <class InputIterator1, class InputIterator2>\n    pair<InputIterator1, InputIterator2>\n    mismatch(InputIterator1 first1, InputIterator1 last1, \n             InputIterator2 first2, InputIterator2 last2); // **C++14**\n\ntemplate <class InputIterator1, class InputIterator2, class BinaryPredicate>\n    pair<InputIterator1, InputIterator2>\n    mismatch(InputIterator1 first1, InputIterator1 last1,\n             InputIterator2 first2, BinaryPredicate pred);\n\ntemplate <class InputIterator1, class InputIterator2, class BinaryPredicate>\n    pair<InputIterator1, InputIterator2>\n    mismatch(InputIterator1 first1, InputIterator1 last1,\n             InputIterator2 first2, InputIterator2 last2,\n             BinaryPredicate pred); // **C++14**\n\ntemplate <class InputIterator1, class InputIterator2>\n    bool\n    equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);\n\ntemplate <class InputIterator1, class InputIterator2>\n    bool\n    equal(InputIterator1 first1, InputIterator1 last1, \n          InputIterator2 first2, InputIterator2 last2); // **C++14**\n\ntemplate <class InputIterator1, class InputIterator2, class BinaryPredicate>\n    bool\n    equal(InputIterator1 first1, InputIterator1 last1,\n          InputIterator2 first2, BinaryPredicate pred);\n\ntemplate <class InputIterator1, class InputIterator2, class BinaryPredicate>\n    bool\n    equal(InputIterator1 first1, InputIterator1 last1,\n          InputIterator2 first2, InputIterator2 last2,\n          BinaryPredicate pred); // **C++14**\n\ntemplate<class ForwardIterator1, class ForwardIterator2>\n    bool\n    is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,\n                   ForwardIterator2 first2);\n\ntemplate<class ForwardIterator1, class ForwardIterator2>\n    bool\n    is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,\n                   ForwardIterator2 first2, ForwardIterator2 last2); // **C++14**\n\ntemplate<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>\n    bool\n    is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,\n                   ForwardIterator2 first2, BinaryPredicate pred);\n\ntemplate<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>\n    bool\n    is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,\n                   ForwardIterator2 first2, ForwardIterator2 last2,\n                   BinaryPredicate pred);  // **C++14**\n\ntemplate <class ForwardIterator1, class ForwardIterator2>\n    ForwardIterator1\n    search(ForwardIterator1 first1, ForwardIterator1 last1,\n           ForwardIterator2 first2, ForwardIterator2 last2);\n\ntemplate <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>\n    ForwardIterator1\n    search(ForwardIterator1 first1, ForwardIterator1 last1,\n           ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);\n\ntemplate <class ForwardIterator, class Size, class T>\n    ForwardIterator\n    search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value);\n\ntemplate <class ForwardIterator, class Size, class T, class BinaryPredicate>\n    ForwardIterator\n    search_n(ForwardIterator first, ForwardIterator last,\n             Size count, const T& value, BinaryPredicate pred);\n\ntemplate <class InputIterator, class OutputIterator>\n    OutputIterator\n    copy(InputIterator first, InputIterator last, OutputIterator result);\n\ntemplate<class InputIterator, class OutputIterator, class Predicate>\n    OutputIterator\n    copy_if(InputIterator first, InputIterator last,\n            OutputIterator result, Predicate pred);\n\ntemplate<class InputIterator, class Size, class OutputIterator>\n    OutputIterator\n    copy_n(InputIterator first, Size n, OutputIterator result);\n\ntemplate <class BidirectionalIterator1, class BidirectionalIterator2>\n    BidirectionalIterator2\n    copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last,\n                  BidirectionalIterator2 result);\n\ntemplate <class ForwardIterator1, class ForwardIterator2>\n    ForwardIterator2\n    swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2);\n\ntemplate <class ForwardIterator1, class ForwardIterator2>\n    void\n    iter_swap(ForwardIterator1 a, ForwardIterator2 b);\n\ntemplate <class InputIterator, class OutputIterator, class UnaryOperation>\n    OutputIterator\n    transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op);\n\ntemplate <class InputIterator1, class InputIterator2, class OutputIterator, class BinaryOperation>\n    OutputIterator\n    transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,\n              OutputIterator result, BinaryOperation binary_op);\n\ntemplate <class ForwardIterator, class T>\n    void\n    replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value);\n\ntemplate <class ForwardIterator, class Predicate, class T>\n    void\n    replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value);\n\ntemplate <class InputIterator, class OutputIterator, class T>\n    OutputIterator\n    replace_copy(InputIterator first, InputIterator last, OutputIterator result,\n                 const T& old_value, const T& new_value);\n\ntemplate <class InputIterator, class OutputIterator, class Predicate, class T>\n    OutputIterator\n    replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value);\n\ntemplate <class ForwardIterator, class T>\n    void\n    fill(ForwardIterator first, ForwardIterator last, const T& value);\n\ntemplate <class OutputIterator, class Size, class T>\n    OutputIterator\n    fill_n(OutputIterator first, Size n, const T& value);\n\ntemplate <class ForwardIterator, class Generator>\n    void\n    generate(ForwardIterator first, ForwardIterator last, Generator gen);\n\ntemplate <class OutputIterator, class Size, class Generator>\n    OutputIterator\n    generate_n(OutputIterator first, Size n, Generator gen);\n\ntemplate <class ForwardIterator, class T>\n    ForwardIterator\n    remove(ForwardIterator first, ForwardIterator last, const T& value);\n\ntemplate <class ForwardIterator, class Predicate>\n    ForwardIterator\n    remove_if(ForwardIterator first, ForwardIterator last, Predicate pred);\n\ntemplate <class InputIterator, class OutputIterator, class T>\n    OutputIterator\n    remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value);\n\ntemplate <class InputIterator, class OutputIterator, class Predicate>\n    OutputIterator\n    remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred);\n\ntemplate <class ForwardIterator>\n    ForwardIterator\n    unique(ForwardIterator first, ForwardIterator last);\n\ntemplate <class ForwardIterator, class BinaryPredicate>\n    ForwardIterator\n    unique(ForwardIterator first, ForwardIterator last, BinaryPredicate pred);\n\ntemplate <class InputIterator, class OutputIterator>\n    OutputIterator\n    unique_copy(InputIterator first, InputIterator last, OutputIterator result);\n\ntemplate <class InputIterator, class OutputIterator, class BinaryPredicate>\n    OutputIterator\n    unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred);\n\ntemplate <class BidirectionalIterator>\n    void\n    reverse(BidirectionalIterator first, BidirectionalIterator last);\n\ntemplate <class BidirectionalIterator, class OutputIterator>\n    OutputIterator\n    reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result);\n\ntemplate <class ForwardIterator>\n    ForwardIterator\n    rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last);\n\ntemplate <class ForwardIterator, class OutputIterator>\n    OutputIterator\n    rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result);\n\ntemplate <class RandomAccessIterator>\n    void\n    random_shuffle(RandomAccessIterator first, RandomAccessIterator last); // deprecated in C++14\n\ntemplate <class RandomAccessIterator, class RandomNumberGenerator>\n    void\n    random_shuffle(RandomAccessIterator first, RandomAccessIterator last,\n                   RandomNumberGenerator& rand);  // deprecated in C++14\n\ntemplate<class RandomAccessIterator, class UniformRandomNumberGenerator>\n    void shuffle(RandomAccessIterator first, RandomAccessIterator last,\n                 UniformRandomNumberGenerator&& g);\n\ntemplate <class InputIterator, class Predicate>\n    bool\n    is_partitioned(InputIterator first, InputIterator last, Predicate pred);\n\ntemplate <class ForwardIterator, class Predicate>\n    ForwardIterator\n    partition(ForwardIterator first, ForwardIterator last, Predicate pred);\n\ntemplate <class InputIterator, class OutputIterator1,\n          class OutputIterator2, class Predicate>\n    pair<OutputIterator1, OutputIterator2>\n    partition_copy(InputIterator first, InputIterator last,\n                   OutputIterator1 out_true, OutputIterator2 out_false,\n                   Predicate pred);\n\ntemplate <class ForwardIterator, class Predicate>\n    ForwardIterator\n    stable_partition(ForwardIterator first, ForwardIterator last, Predicate pred);\n\ntemplate<class ForwardIterator, class Predicate>\n    ForwardIterator\n    partition_point(ForwardIterator first, ForwardIterator last, Predicate pred);\n\ntemplate <class ForwardIterator>\n    bool\n    is_sorted(ForwardIterator first, ForwardIterator last);\n\ntemplate <class ForwardIterator, class Compare>\n    bool\n    is_sorted(ForwardIterator first, ForwardIterator last, Compare comp);\n\ntemplate<class ForwardIterator>\n    ForwardIterator\n    is_sorted_until(ForwardIterator first, ForwardIterator last);\n\ntemplate <class ForwardIterator, class Compare>\n    ForwardIterator\n    is_sorted_until(ForwardIterator first, ForwardIterator last, Compare comp);\n\ntemplate <class RandomAccessIterator>\n    void\n    sort(RandomAccessIterator first, RandomAccessIterator last);\n\ntemplate <class RandomAccessIterator, class Compare>\n    void\n    sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);\n\ntemplate <class RandomAccessIterator>\n    void\n    stable_sort(RandomAccessIterator first, RandomAccessIterator last);\n\ntemplate <class RandomAccessIterator, class Compare>\n    void\n    stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);\n\ntemplate <class RandomAccessIterator>\n    void\n    partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last);\n\ntemplate <class RandomAccessIterator, class Compare>\n    void\n    partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp);\n\ntemplate <class InputIterator, class RandomAccessIterator>\n    RandomAccessIterator\n    partial_sort_copy(InputIterator first, InputIterator last,\n                      RandomAccessIterator result_first, RandomAccessIterator result_last);\n\ntemplate <class InputIterator, class RandomAccessIterator, class Compare>\n    RandomAccessIterator\n    partial_sort_copy(InputIterator first, InputIterator last,\n                      RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp);\n\ntemplate <class RandomAccessIterator>\n    void\n    nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last);\n\ntemplate <class RandomAccessIterator, class Compare>\n    void\n    nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp);\n\ntemplate <class ForwardIterator, class T>\n    ForwardIterator\n    lower_bound(ForwardIterator first, ForwardIterator last, const T& value);\n\ntemplate <class ForwardIterator, class T, class Compare>\n    ForwardIterator\n    lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);\n\ntemplate <class ForwardIterator, class T>\n    ForwardIterator\n    upper_bound(ForwardIterator first, ForwardIterator last, const T& value);\n\ntemplate <class ForwardIterator, class T, class Compare>\n    ForwardIterator\n    upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);\n\ntemplate <class ForwardIterator, class T>\n    pair<ForwardIterator, ForwardIterator>\n    equal_range(ForwardIterator first, ForwardIterator last, const T& value);\n\ntemplate <class ForwardIterator, class T, class Compare>\n    pair<ForwardIterator, ForwardIterator>\n    equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);\n\ntemplate <class ForwardIterator, class T>\n    bool\n    binary_search(ForwardIterator first, ForwardIterator last, const T& value);\n\ntemplate <class ForwardIterator, class T, class Compare>\n    bool\n    binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);\n\ntemplate <class InputIterator1, class InputIterator2, class OutputIterator>\n    OutputIterator\n    merge(InputIterator1 first1, InputIterator1 last1,\n          InputIterator2 first2, InputIterator2 last2, OutputIterator result);\n\ntemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>\n    OutputIterator\n    merge(InputIterator1 first1, InputIterator1 last1,\n          InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);\n\ntemplate <class BidirectionalIterator>\n    void\n    inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last);\n\ntemplate <class BidirectionalIterator, class Compare>\n    void\n    inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp);\n\ntemplate <class InputIterator1, class InputIterator2>\n    bool\n    includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2);\n\ntemplate <class InputIterator1, class InputIterator2, class Compare>\n    bool\n    includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp);\n\ntemplate <class InputIterator1, class InputIterator2, class OutputIterator>\n    OutputIterator\n    set_union(InputIterator1 first1, InputIterator1 last1,\n              InputIterator2 first2, InputIterator2 last2, OutputIterator result);\n\ntemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>\n    OutputIterator\n    set_union(InputIterator1 first1, InputIterator1 last1,\n              InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);\n\ntemplate <class InputIterator1, class InputIterator2, class OutputIterator>\n    OutputIterator\n    set_intersection(InputIterator1 first1, InputIterator1 last1,\n                     InputIterator2 first2, InputIterator2 last2, OutputIterator result);\n\ntemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>\n    OutputIterator\n    set_intersection(InputIterator1 first1, InputIterator1 last1,\n                     InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);\n\ntemplate <class InputIterator1, class InputIterator2, class OutputIterator>\n    OutputIterator\n    set_difference(InputIterator1 first1, InputIterator1 last1,\n                   InputIterator2 first2, InputIterator2 last2, OutputIterator result);\n\ntemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>\n    OutputIterator\n    set_difference(InputIterator1 first1, InputIterator1 last1,\n                   InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);\n\ntemplate <class InputIterator1, class InputIterator2, class OutputIterator>\n    OutputIterator\n    set_symmetric_difference(InputIterator1 first1, InputIterator1 last1,\n                             InputIterator2 first2, InputIterator2 last2, OutputIterator result);\n\ntemplate <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>\n    OutputIterator\n    set_symmetric_difference(InputIterator1 first1, InputIterator1 last1,\n                             InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);\n\ntemplate <class RandomAccessIterator>\n    void\n    push_heap(RandomAccessIterator first, RandomAccessIterator last);\n\ntemplate <class RandomAccessIterator, class Compare>\n    void\n    push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);\n\ntemplate <class RandomAccessIterator>\n    void\n    pop_heap(RandomAccessIterator first, RandomAccessIterator last);\n\ntemplate <class RandomAccessIterator, class Compare>\n    void\n    pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);\n\ntemplate <class RandomAccessIterator>\n    void\n    make_heap(RandomAccessIterator first, RandomAccessIterator last);\n\ntemplate <class RandomAccessIterator, class Compare>\n    void\n    make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);\n\ntemplate <class RandomAccessIterator>\n    void\n    sort_heap(RandomAccessIterator first, RandomAccessIterator last);\n\ntemplate <class RandomAccessIterator, class Compare>\n    void\n    sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);\n\ntemplate <class RandomAccessIterator>\n    bool\n    is_heap(RandomAccessIterator first, RandomAccessiterator last);\n\ntemplate <class RandomAccessIterator, class Compare>\n    bool\n    is_heap(RandomAccessIterator first, RandomAccessiterator last, Compare comp);\n\ntemplate <class RandomAccessIterator>\n    RandomAccessIterator\n    is_heap_until(RandomAccessIterator first, RandomAccessiterator last);\n\ntemplate <class RandomAccessIterator, class Compare>\n    RandomAccessIterator\n    is_heap_until(RandomAccessIterator first, RandomAccessiterator last, Compare comp);\n\ntemplate <class ForwardIterator>\n    ForwardIterator\n    min_element(ForwardIterator first, ForwardIterator last);  // constexpr in C++14\n\ntemplate <class ForwardIterator, class Compare>\n    ForwardIterator\n    min_element(ForwardIterator first, ForwardIterator last, Compare comp);  // constexpr in C++14\n\ntemplate <class T>\n    const T&\n    min(const T& a, const T& b);  // constexpr in C++14\n\ntemplate <class T, class Compare>\n    const T&\n    min(const T& a, const T& b, Compare comp);  // constexpr in C++14\n\ntemplate<class T>\n    T\n    min(initializer_list<T> t);  // constexpr in C++14\n\ntemplate<class T, class Compare>\n    T\n    min(initializer_list<T> t, Compare comp);  // constexpr in C++14\n\ntemplate <class ForwardIterator>\n    ForwardIterator\n    max_element(ForwardIterator first, ForwardIterator last);  // constexpr in C++14\n\ntemplate <class ForwardIterator, class Compare>\n    ForwardIterator\n    max_element(ForwardIterator first, ForwardIterator last, Compare comp);  // constexpr in C++14\n\ntemplate <class T>\n    const T&\n    max(const T& a, const T& b); // constexpr in C++14\n\ntemplate <class T, class Compare>\n    const T&\n    max(const T& a, const T& b, Compare comp);  // constexpr in C++14\n\ntemplate<class T>\n    T\n    max(initializer_list<T> t);  // constexpr in C++14\n\ntemplate<class T, class Compare>\n    T\n    max(initializer_list<T> t, Compare comp);  // constexpr in C++14\n\ntemplate<class ForwardIterator>\n    pair<ForwardIterator, ForwardIterator>\n    minmax_element(ForwardIterator first, ForwardIterator last);   // constexpr in C++14\n\ntemplate<class ForwardIterator, class Compare>\n    pair<ForwardIterator, ForwardIterator>\n    minmax_element(ForwardIterator first, ForwardIterator last, Compare comp);   // constexpr in C++14\n\ntemplate<class T>\n    pair<const T&, const T&>\n    minmax(const T& a, const T& b);  // constexpr in C++14\n\ntemplate<class T, class Compare>\n    pair<const T&, const T&>\n    minmax(const T& a, const T& b, Compare comp);  // constexpr in C++14\n\ntemplate<class T>\n    pair<T, T>\n    minmax(initializer_list<T> t);  // constexpr in C++14\n\ntemplate<class T, class Compare>\n    pair<T, T>\n    minmax(initializer_list<T> t, Compare comp);  // constexpr in C++14\n\ntemplate <class InputIterator1, class InputIterator2>\n    bool\n    lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2);\n\ntemplate <class InputIterator1, class InputIterator2, class Compare>\n    bool\n    lexicographical_compare(InputIterator1 first1, InputIterator1 last1,\n                            InputIterator2 first2, InputIterator2 last2, Compare comp);\n\ntemplate <class BidirectionalIterator>\n    bool\n    next_permutation(BidirectionalIterator first, BidirectionalIterator last);\n\ntemplate <class BidirectionalIterator, class Compare>\n    bool\n    next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp);\n\ntemplate <class BidirectionalIterator>\n    bool\n    prev_permutation(BidirectionalIterator first, BidirectionalIterator last);\n\ntemplate <class BidirectionalIterator, class Compare>\n    bool\n    prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <initializer_list>\n#include <type_traits>\n#include <cstring>\n#include <utility>\n#include <memory>\n#include <iterator>\n#include <cstddef>\n\n#if defined(__IBMCPP__)\n#include \"support/ibm/support.h\"\n#endif\n#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)\n#include \"support/win32/support.h\"\n#endif\n\n#include <__undef_min_max>\n\n#include <__debug>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n// I'd like to replace these with _VSTD::equal_to<void>, but can't because:\n//   * That only works with C++14 and later, and\n//   * We haven't included <functional> here.\ntemplate <class _T1, class _T2 = _T1>\nstruct __equal_to\n{\n    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}\n    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;}\n    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;}\n    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;}\n};\n\ntemplate <class _T1>\nstruct __equal_to<_T1, _T1>\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}\n};\n\ntemplate <class _T1>\nstruct __equal_to<const _T1, _T1>\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}\n};\n\ntemplate <class _T1>\nstruct __equal_to<_T1, const _T1>\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}\n};\n\ntemplate <class _T1, class _T2 = _T1>\nstruct __less\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 \n    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;}\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;}\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;}\n};\n\ntemplate <class _T1>\nstruct __less<_T1, _T1>\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}\n};\n\ntemplate <class _T1>\nstruct __less<const _T1, _T1>\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}\n};\n\ntemplate <class _T1>\nstruct __less<_T1, const _T1>\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}\n};\n\ntemplate <class _Predicate>\nclass __negate\n{\nprivate:\n    _Predicate __p_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY __negate() {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __negate(_Predicate __p) : __p_(__p) {}\n\n    template <class _T1>\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _T1& __x) {return !__p_(__x);}\n\n    template <class _T1, class _T2>\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _T1& __x, const _T2& __y) {return !__p_(__x, __y);}\n};\n\n#ifdef _LIBCPP_DEBUG\n\ntemplate <class _Compare>\nstruct __debug_less\n{\n    _Compare __comp_;\n    __debug_less(_Compare& __c) : __comp_(__c) {}\n    template <class _Tp, class _Up>\n    bool operator()(const _Tp& __x, const _Up& __y)\n    {\n        bool __r = __comp_(__x, __y);\n        if (__r)\n            _LIBCPP_ASSERT(!__comp_(__y, __x), \"Comparator does not induce a strict weak ordering\");\n        return __r;\n    }\n};\n\n#endif  // _LIBCPP_DEBUG\n\n// Precondition:  __x != 0\ninline _LIBCPP_INLINE_VISIBILITY\nunsigned\n__ctz(unsigned __x)\n{\n    return static_cast<unsigned>(__builtin_ctz(__x));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nunsigned long\n__ctz(unsigned long __x)\n{\n    return static_cast<unsigned long>(__builtin_ctzl(__x));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nunsigned long long\n__ctz(unsigned long long __x)\n{\n    return static_cast<unsigned long long>(__builtin_ctzll(__x));\n}\n\n// Precondition:  __x != 0\ninline _LIBCPP_INLINE_VISIBILITY\nunsigned\n__clz(unsigned __x)\n{\n    return static_cast<unsigned>(__builtin_clz(__x));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nunsigned long\n__clz(unsigned long __x)\n{\n    return static_cast<unsigned long>(__builtin_clzl (__x));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nunsigned long long\n__clz(unsigned long long __x)\n{\n    return static_cast<unsigned long long>(__builtin_clzll(__x));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned           __x) {return __builtin_popcount  (__x);}\ninline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned      long __x) {return __builtin_popcountl (__x);}\ninline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned long long __x) {return __builtin_popcountll(__x);}\n\n// all_of\n\ntemplate <class _InputIterator, class _Predicate>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nall_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)\n{\n    for (; __first != __last; ++__first)\n        if (!__pred(*__first))\n            return false;\n    return true;\n}\n\n// any_of\n\ntemplate <class _InputIterator, class _Predicate>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nany_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)\n{\n    for (; __first != __last; ++__first)\n        if (__pred(*__first))\n            return true;\n    return false;\n}\n\n// none_of\n\ntemplate <class _InputIterator, class _Predicate>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nnone_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)\n{\n    for (; __first != __last; ++__first)\n        if (__pred(*__first))\n            return false;\n    return true;\n}\n\n// for_each\n\ntemplate <class _InputIterator, class _Function>\ninline _LIBCPP_INLINE_VISIBILITY\n_Function\nfor_each(_InputIterator __first, _InputIterator __last, _Function __f)\n{\n    for (; __first != __last; ++__first)\n        __f(*__first);\n    return _VSTD::move(__f);  // explicitly moved for (emulated) C++03\n}\n\n// find\n\ntemplate <class _InputIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_InputIterator\nfind(_InputIterator __first, _InputIterator __last, const _Tp& __value_)\n{\n    for (; __first != __last; ++__first)\n        if (*__first == __value_)\n            break;\n    return __first;\n}\n\n// find_if\n\ntemplate <class _InputIterator, class _Predicate>\ninline _LIBCPP_INLINE_VISIBILITY\n_InputIterator\nfind_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)\n{\n    for (; __first != __last; ++__first)\n        if (__pred(*__first))\n            break;\n    return __first;\n}\n\n// find_if_not\n\ntemplate<class _InputIterator, class _Predicate>\ninline _LIBCPP_INLINE_VISIBILITY\n_InputIterator\nfind_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred)\n{\n    for (; __first != __last; ++__first)\n        if (!__pred(*__first))\n            break;\n    return __first;\n}\n\n// find_end\n\ntemplate <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>\n_ForwardIterator1\n__find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,\n           _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred,\n           forward_iterator_tag, forward_iterator_tag)\n{\n    // modeled after search algorithm\n    _ForwardIterator1 __r = __last1;  // __last1 is the \"default\" answer\n    if (__first2 == __last2)\n        return __r;\n    while (true)\n    {\n        while (true)\n        {\n            if (__first1 == __last1)         // if source exhausted return last correct answer\n                return __r;                  //    (or __last1 if never found)\n            if (__pred(*__first1, *__first2))\n                break;\n            ++__first1;\n        }\n        // *__first1 matches *__first2, now match elements after here\n        _ForwardIterator1 __m1 = __first1;\n        _ForwardIterator2 __m2 = __first2;\n        while (true)\n        {\n            if (++__m2 == __last2)\n            {                         // Pattern exhaused, record answer and search for another one\n                __r = __first1;\n                ++__first1;\n                break;\n            }\n            if (++__m1 == __last1)     // Source exhausted, return last answer\n                return __r;\n            if (!__pred(*__m1, *__m2))  // mismatch, restart with a new __first\n            {\n                ++__first1;\n                break;\n            }  // else there is a match, check next elements\n        }\n    }\n}\n\ntemplate <class _BinaryPredicate, class _BidirectionalIterator1, class _BidirectionalIterator2>\n_BidirectionalIterator1\n__find_end(_BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1,\n           _BidirectionalIterator2 __first2, _BidirectionalIterator2 __last2, _BinaryPredicate __pred,\n           bidirectional_iterator_tag, bidirectional_iterator_tag)\n{\n    // modeled after search algorithm (in reverse)\n    if (__first2 == __last2)\n        return __last1;  // Everything matches an empty sequence\n    _BidirectionalIterator1 __l1 = __last1;\n    _BidirectionalIterator2 __l2 = __last2;\n    --__l2;\n    while (true)\n    {\n        // Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks\n        while (true)\n        {\n            if (__first1 == __l1)  // return __last1 if no element matches *__first2\n                return __last1;\n            if (__pred(*--__l1, *__l2))\n                break;\n        }\n        // *__l1 matches *__l2, now match elements before here\n        _BidirectionalIterator1 __m1 = __l1;\n        _BidirectionalIterator2 __m2 = __l2;\n        while (true)\n        {\n            if (__m2 == __first2)  // If pattern exhausted, __m1 is the answer (works for 1 element pattern)\n                return __m1;\n            if (__m1 == __first1)  // Otherwise if source exhaused, pattern not found\n                return __last1;\n            if (!__pred(*--__m1, *--__m2))  // if there is a mismatch, restart with a new __l1\n            {\n                break;\n            }  // else there is a match, check next elements\n        }\n    }\n}\n\ntemplate <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>\n_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1\n__find_end(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,\n           _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred,\n           random_access_iterator_tag, random_access_iterator_tag)\n{\n    // Take advantage of knowing source and pattern lengths.  Stop short when source is smaller than pattern\n    typename iterator_traits<_RandomAccessIterator2>::difference_type __len2 = __last2 - __first2;\n    if (__len2 == 0)\n        return __last1;\n    typename iterator_traits<_RandomAccessIterator1>::difference_type __len1 = __last1 - __first1;\n    if (__len1 < __len2)\n        return __last1;\n    const _RandomAccessIterator1 __s = __first1 + (__len2 - 1);  // End of pattern match can't go before here\n    _RandomAccessIterator1 __l1 = __last1;\n    _RandomAccessIterator2 __l2 = __last2;\n    --__l2;\n    while (true)\n    {\n        while (true)\n        {\n            if (__s == __l1)\n                return __last1;\n            if (__pred(*--__l1, *__l2))\n                break;\n        }\n        _RandomAccessIterator1 __m1 = __l1;\n        _RandomAccessIterator2 __m2 = __l2;\n        while (true)\n        {\n            if (__m2 == __first2)\n                return __m1;\n                                 // no need to check range on __m1 because __s guarantees we have enough source\n            if (!__pred(*--__m1, *--__m2))\n            {\n                break;\n            }\n        }\n    }\n}\n\ntemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator1\nfind_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,\n         _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)\n{\n    return _VSTD::__find_end<typename add_lvalue_reference<_BinaryPredicate>::type>\n                         (__first1, __last1, __first2, __last2, __pred,\n                          typename iterator_traits<_ForwardIterator1>::iterator_category(),\n                          typename iterator_traits<_ForwardIterator2>::iterator_category());\n}\n\ntemplate <class _ForwardIterator1, class _ForwardIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator1\nfind_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,\n         _ForwardIterator2 __first2, _ForwardIterator2 __last2)\n{\n    typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;\n    typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;\n    return _VSTD::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());\n}\n\n// find_first_of\n\ntemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>\n_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1\n__find_first_of_ce(_ForwardIterator1 __first1, _ForwardIterator1 __last1,\n              _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)\n{\n    for (; __first1 != __last1; ++__first1)\n        for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)\n            if (__pred(*__first1, *__j))\n                return __first1;\n    return __last1;\n}\n\n\ntemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator1\nfind_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1,\n              _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)\n{\n    return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred);\n}\n\ntemplate <class _ForwardIterator1, class _ForwardIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator1\nfind_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1,\n              _ForwardIterator2 __first2, _ForwardIterator2 __last2)\n{\n    typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;\n    typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;\n    return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());\n}\n\n// adjacent_find\n\ntemplate <class _ForwardIterator, class _BinaryPredicate>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator\nadjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)\n{\n    if (__first != __last)\n    {\n        _ForwardIterator __i = __first;\n        while (++__i != __last)\n        {\n            if (__pred(*__first, *__i))\n                return __first;\n            __first = __i;\n        }\n    }\n    return __last;\n}\n\ntemplate <class _ForwardIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator\nadjacent_find(_ForwardIterator __first, _ForwardIterator __last)\n{\n    typedef typename iterator_traits<_ForwardIterator>::value_type __v;\n    return _VSTD::adjacent_find(__first, __last, __equal_to<__v>());\n}\n\n// count\n\ntemplate <class _InputIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename iterator_traits<_InputIterator>::difference_type\ncount(_InputIterator __first, _InputIterator __last, const _Tp& __value_)\n{\n    typename iterator_traits<_InputIterator>::difference_type __r(0);\n    for (; __first != __last; ++__first)\n        if (*__first == __value_)\n            ++__r;\n    return __r;\n}\n\n// count_if\n\ntemplate <class _InputIterator, class _Predicate>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename iterator_traits<_InputIterator>::difference_type\ncount_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)\n{\n    typename iterator_traits<_InputIterator>::difference_type __r(0);\n    for (; __first != __last; ++__first)\n        if (__pred(*__first))\n            ++__r;\n    return __r;\n}\n\n// mismatch\n\ntemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>\ninline _LIBCPP_INLINE_VISIBILITY\npair<_InputIterator1, _InputIterator2>\nmismatch(_InputIterator1 __first1, _InputIterator1 __last1,\n         _InputIterator2 __first2, _BinaryPredicate __pred)\n{\n    for (; __first1 != __last1; ++__first1, (void) ++__first2)\n        if (!__pred(*__first1, *__first2))\n            break;\n    return pair<_InputIterator1, _InputIterator2>(__first1, __first2);\n}\n\ntemplate <class _InputIterator1, class _InputIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\npair<_InputIterator1, _InputIterator2>\nmismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2)\n{\n    typedef typename iterator_traits<_InputIterator1>::value_type __v1;\n    typedef typename iterator_traits<_InputIterator2>::value_type __v2;\n    return _VSTD::mismatch(__first1, __last1, __first2, __equal_to<__v1, __v2>());\n}\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>\ninline _LIBCPP_INLINE_VISIBILITY\npair<_InputIterator1, _InputIterator2>\nmismatch(_InputIterator1 __first1, _InputIterator1 __last1,\n         _InputIterator2 __first2, _InputIterator2 __last2,\n         _BinaryPredicate __pred)\n{\n    for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2)\n        if (!__pred(*__first1, *__first2))\n            break;\n    return pair<_InputIterator1, _InputIterator2>(__first1, __first2);\n}\n\ntemplate <class _InputIterator1, class _InputIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\npair<_InputIterator1, _InputIterator2>\nmismatch(_InputIterator1 __first1, _InputIterator1 __last1,\n         _InputIterator2 __first2, _InputIterator2 __last2)\n{\n    typedef typename iterator_traits<_InputIterator1>::value_type __v1;\n    typedef typename iterator_traits<_InputIterator2>::value_type __v2;\n    return _VSTD::mismatch(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());\n}\n#endif\n\n// equal\n\ntemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nequal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred)\n{\n    for (; __first1 != __last1; ++__first1, (void) ++__first2)\n        if (!__pred(*__first1, *__first2))\n            return false;\n    return true;\n}\n\ntemplate <class _InputIterator1, class _InputIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nequal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2)\n{\n    typedef typename iterator_traits<_InputIterator1>::value_type __v1;\n    typedef typename iterator_traits<_InputIterator2>::value_type __v2;\n    return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>());\n}\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _BinaryPredicate, class _InputIterator1, class _InputIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\n__equal(_InputIterator1 __first1, _InputIterator1 __last1, \n        _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred,\n        input_iterator_tag, input_iterator_tag )\n{\n    for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2)\n        if (!__pred(*__first1, *__first2))\n            return false;\n    return __first1 == __last1 && __first2 == __last2;\n}\n\ntemplate <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\n__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, \n        _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, \n      random_access_iterator_tag, random_access_iterator_tag )\n{\n    if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))\n        return false;\n    return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2,\n                        typename add_lvalue_reference<_BinaryPredicate>::type>\n                       (__first1, __last1, __first2, __pred );\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nequal(_InputIterator1 __first1, _InputIterator1 __last1, \n      _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred )\n{\n    return _VSTD::__equal<typename add_lvalue_reference<_BinaryPredicate>::type>\n       (__first1, __last1, __first2, __last2, __pred, \n        typename iterator_traits<_InputIterator1>::iterator_category(),\n        typename iterator_traits<_InputIterator2>::iterator_category());\n}\n\ntemplate <class _InputIterator1, class _InputIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nequal(_InputIterator1 __first1, _InputIterator1 __last1, \n      _InputIterator2 __first2, _InputIterator2 __last2)\n{\n    typedef typename iterator_traits<_InputIterator1>::value_type __v1;\n    typedef typename iterator_traits<_InputIterator2>::value_type __v2;\n    return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(),\n        typename iterator_traits<_InputIterator1>::iterator_category(),\n        typename iterator_traits<_InputIterator2>::iterator_category());\n}\n#endif\n\n// is_permutation\n\ntemplate<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>\nbool\nis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,\n               _ForwardIterator2 __first2, _BinaryPredicate __pred)\n{\n    // shorten sequences as much as possible by lopping of any equal parts\n    for (; __first1 != __last1; ++__first1, (void) ++__first2)\n        if (!__pred(*__first1, *__first2))\n            goto __not_done;\n    return true;\n__not_done:\n    // __first1 != __last1 && *__first1 != *__first2\n    typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;\n    _D1 __l1 = _VSTD::distance(__first1, __last1);\n    if (__l1 == _D1(1))\n        return false;\n    _ForwardIterator2 __last2 = _VSTD::next(__first2, __l1);\n    // For each element in [f1, l1) see if there are the same number of\n    //    equal elements in [f2, l2)\n    for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i)\n    {\n        // Have we already counted the number of *__i in [f1, l1)?\n        for (_ForwardIterator1 __j = __first1; __j != __i; ++__j)\n            if (__pred(*__j, *__i))\n                goto __next_iter;\n        {\n            // Count number of *__i in [f2, l2)\n            _D1 __c2 = 0;\n            for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)\n                if (__pred(*__i, *__j))\n                    ++__c2;\n            if (__c2 == 0)\n                return false;\n            // Count number of *__i in [__i, l1) (we can start with 1)\n            _D1 __c1 = 1;\n            for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)\n                if (__pred(*__i, *__j))\n                    ++__c1;\n            if (__c1 != __c2)\n                return false;\n        }\n__next_iter:;\n    }\n    return true;\n}\n\ntemplate<class _ForwardIterator1, class _ForwardIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,\n               _ForwardIterator2 __first2)\n{\n    typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;\n    typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;\n    return _VSTD::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>());\n}\n\n#if _LIBCPP_STD_VER > 11\ntemplate<class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>\nbool\n__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,\n                 _ForwardIterator2 __first2, _ForwardIterator2 __last2, \n                 _BinaryPredicate __pred,\n                 forward_iterator_tag, forward_iterator_tag )\n{\n    // shorten sequences as much as possible by lopping of any equal parts\n    for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2)\n        if (!__pred(*__first1, *__first2))\n            goto __not_done;\n    return __first1 == __last1 && __first2 == __last2;\n__not_done:\n    // __first1 != __last1 && __first2 != __last2 && *__first1 != *__first2\n    typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;\n    _D1 __l1 = _VSTD::distance(__first1, __last1);\n\n    typedef typename iterator_traits<_ForwardIterator2>::difference_type _D2;\n    _D2 __l2 = _VSTD::distance(__first2, __last2);\n    if (__l1 != __l2)\n        return false;\n\n    // For each element in [f1, l1) see if there are the same number of\n    //    equal elements in [f2, l2)\n    for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i)\n    {\n        // Have we already counted the number of *__i in [f1, l1)?\n        for (_ForwardIterator1 __j = __first1; __j != __i; ++__j)\n            if (__pred(*__j, *__i))\n                goto __next_iter;\n        {\n            // Count number of *__i in [f2, l2)\n            _D1 __c2 = 0;\n            for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)\n                if (__pred(*__i, *__j))\n                    ++__c2;\n            if (__c2 == 0)\n                return false;\n            // Count number of *__i in [__i, l1) (we can start with 1)\n            _D1 __c1 = 1;\n            for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)\n                if (__pred(*__i, *__j))\n                    ++__c1;\n            if (__c1 != __c2)\n                return false;\n        }\n__next_iter:;\n    }\n    return true;\n}\n\ntemplate<class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>\nbool\n__is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1,\n               _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2, \n               _BinaryPredicate __pred,\n               random_access_iterator_tag, random_access_iterator_tag )\n{\n    if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))\n        return false;\n    return _VSTD::is_permutation<_RandomAccessIterator1, _RandomAccessIterator2,\n                                 typename add_lvalue_reference<_BinaryPredicate>::type>\n                                (__first1, __last1, __first2, __pred );\n}\n\ntemplate<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,\n               _ForwardIterator2 __first2, _ForwardIterator2 __last2,\n               _BinaryPredicate __pred )\n{\n    return _VSTD::__is_permutation<typename add_lvalue_reference<_BinaryPredicate>::type>\n       (__first1, __last1, __first2, __last2, __pred,\n        typename iterator_traits<_ForwardIterator1>::iterator_category(),\n        typename iterator_traits<_ForwardIterator2>::iterator_category());\n}\n\ntemplate<class _ForwardIterator1, class _ForwardIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nis_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,\n               _ForwardIterator2 __first2, _ForwardIterator2 __last2)\n{\n    typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;\n    typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;\n    return _VSTD::__is_permutation(__first1, __last1, __first2, __last2,\n        __equal_to<__v1, __v2>(),\n        typename iterator_traits<_ForwardIterator1>::iterator_category(),\n        typename iterator_traits<_ForwardIterator2>::iterator_category());\n}\n#endif\n\n// search\n\ntemplate <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>\n_ForwardIterator1\n__search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,\n         _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred,\n         forward_iterator_tag, forward_iterator_tag)\n{\n    if (__first2 == __last2)\n        return __first1;  // Everything matches an empty sequence\n    while (true)\n    {\n        // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks\n        while (true)\n        {\n            if (__first1 == __last1)  // return __last1 if no element matches *__first2\n                return __last1;\n            if (__pred(*__first1, *__first2))\n                break;\n            ++__first1;\n        }\n        // *__first1 matches *__first2, now match elements after here\n        _ForwardIterator1 __m1 = __first1;\n        _ForwardIterator2 __m2 = __first2;\n        while (true)\n        {\n            if (++__m2 == __last2)  // If pattern exhausted, __first1 is the answer (works for 1 element pattern)\n                return __first1;\n            if (++__m1 == __last1)  // Otherwise if source exhaused, pattern not found\n                return __last1;\n            if (!__pred(*__m1, *__m2))  // if there is a mismatch, restart with a new __first1\n            {\n                ++__first1;\n                break;\n            }  // else there is a match, check next elements\n        }\n    }\n}\n\ntemplate <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>\n_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1\n__search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,\n           _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred,\n           random_access_iterator_tag, random_access_iterator_tag)\n{\n    typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _D1;\n    typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _D2;\n    // Take advantage of knowing source and pattern lengths.  Stop short when source is smaller than pattern\n    _D2 __len2 = __last2 - __first2;\n    if (__len2 == 0)\n        return __first1;\n    _D1 __len1 = __last1 - __first1;\n    if (__len1 < __len2)\n        return __last1;\n    const _RandomAccessIterator1 __s = __last1 - (__len2 - 1);  // Start of pattern match can't go beyond here\n    while (true)\n    {\n#if !_LIBCPP_UNROLL_LOOPS\n        while (true)\n        {\n            if (__first1 == __s)\n                return __last1;\n            if (__pred(*__first1, *__first2))\n                break;\n            ++__first1;\n        }\n#else  // !_LIBCPP_UNROLL_LOOPS\n        for (_D1 __loop_unroll = (__s - __first1) / 4; __loop_unroll > 0; --__loop_unroll)\n        {\n            if (__pred(*__first1, *__first2))\n                goto __phase2;\n            if (__pred(*++__first1, *__first2))\n                goto __phase2;\n            if (__pred(*++__first1, *__first2))\n                goto __phase2;\n            if (__pred(*++__first1, *__first2))\n                goto __phase2;\n            ++__first1;\n        }\n        switch (__s - __first1)\n        {\n        case 3:\n            if (__pred(*__first1, *__first2))\n                break;\n            ++__first1;\n        case 2:\n            if (__pred(*__first1, *__first2))\n                break;\n            ++__first1;\n        case 1:\n            if (__pred(*__first1, *__first2))\n                break;\n        case 0:\n            return __last1;\n        }\n    __phase2:\n#endif  // !_LIBCPP_UNROLL_LOOPS\n        _RandomAccessIterator1 __m1 = __first1;\n        _RandomAccessIterator2 __m2 = __first2;\n#if !_LIBCPP_UNROLL_LOOPS\n         while (true)\n         {\n             if (++__m2 == __last2)\n                 return __first1;\n             ++__m1;          // no need to check range on __m1 because __s guarantees we have enough source\n             if (!__pred(*__m1, *__m2))\n             {\n                 ++__first1;\n                 break;\n             }\n         }\n#else  // !_LIBCPP_UNROLL_LOOPS\n        ++__m2;\n        ++__m1;\n        for (_D2 __loop_unroll = (__last2 - __m2) / 4; __loop_unroll > 0; --__loop_unroll)\n        {\n            if (!__pred(*__m1, *__m2))\n                goto __continue;\n            if (!__pred(*++__m1, *++__m2))\n                goto __continue;\n            if (!__pred(*++__m1, *++__m2))\n                goto __continue;\n            if (!__pred(*++__m1, *++__m2))\n                goto __continue;\n            ++__m1;\n            ++__m2;\n        }\n        switch (__last2 - __m2)\n        {\n        case 3:\n            if (!__pred(*__m1, *__m2))\n                break;\n            ++__m1;\n            ++__m2;\n        case 2:\n            if (!__pred(*__m1, *__m2))\n                break;\n            ++__m1;\n            ++__m2;\n        case 1:\n            if (!__pred(*__m1, *__m2))\n                break;\n        case 0:\n            return __first1;\n        }\n    __continue:\n        ++__first1;\n#endif  // !_LIBCPP_UNROLL_LOOPS\n    }\n}\n\ntemplate <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator1\nsearch(_ForwardIterator1 __first1, _ForwardIterator1 __last1,\n       _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)\n{\n    return _VSTD::__search<typename add_lvalue_reference<_BinaryPredicate>::type>\n                         (__first1, __last1, __first2, __last2, __pred,\n                          typename std::iterator_traits<_ForwardIterator1>::iterator_category(),\n                          typename std::iterator_traits<_ForwardIterator2>::iterator_category());\n}\n\ntemplate <class _ForwardIterator1, class _ForwardIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator1\nsearch(_ForwardIterator1 __first1, _ForwardIterator1 __last1,\n       _ForwardIterator2 __first2, _ForwardIterator2 __last2)\n{\n    typedef typename std::iterator_traits<_ForwardIterator1>::value_type __v1;\n    typedef typename std::iterator_traits<_ForwardIterator2>::value_type __v2;\n    return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());\n}\n\n// search_n\n\ntemplate <class _BinaryPredicate, class _ForwardIterator, class _Size, class _Tp>\n_ForwardIterator\n__search_n(_ForwardIterator __first, _ForwardIterator __last,\n           _Size __count, const _Tp& __value_, _BinaryPredicate __pred, forward_iterator_tag)\n{\n    if (__count <= 0)\n        return __first;\n    while (true)\n    {\n        // Find first element in sequence that matchs __value_, with a mininum of loop checks\n        while (true)\n        {\n            if (__first == __last)  // return __last if no element matches __value_\n                return __last;\n            if (__pred(*__first, __value_))\n                break;\n            ++__first;\n        }\n        // *__first matches __value_, now match elements after here\n        _ForwardIterator __m = __first;\n        _Size __c(0);\n        while (true)\n        {\n            if (++__c == __count)  // If pattern exhausted, __first is the answer (works for 1 element pattern)\n                return __first;\n            if (++__m == __last)  // Otherwise if source exhaused, pattern not found\n                return __last;\n            if (!__pred(*__m, __value_))  // if there is a mismatch, restart with a new __first\n            {\n                __first = __m;\n                ++__first;\n                break;\n            }  // else there is a match, check next elements\n        }\n    }\n}\n\ntemplate <class _BinaryPredicate, class _RandomAccessIterator, class _Size, class _Tp>\n_RandomAccessIterator\n__search_n(_RandomAccessIterator __first, _RandomAccessIterator __last,\n           _Size __count, const _Tp& __value_, _BinaryPredicate __pred, random_access_iterator_tag)\n{\n    if (__count <= 0)\n        return __first;\n    _Size __len = static_cast<_Size>(__last - __first);\n    if (__len < __count)\n        return __last;\n    const _RandomAccessIterator __s = __last - (__count - 1);  // Start of pattern match can't go beyond here\n    while (true)\n    {\n        // Find first element in sequence that matchs __value_, with a mininum of loop checks\n        while (true)\n        {\n            if (__first >= __s)  // return __last if no element matches __value_\n                return __last;\n            if (__pred(*__first, __value_))\n                break;\n            ++__first;\n        }\n        // *__first matches __value_, now match elements after here\n        _RandomAccessIterator __m = __first;\n        _Size __c(0);\n        while (true)\n        {\n            if (++__c == __count)  // If pattern exhausted, __first is the answer (works for 1 element pattern)\n                return __first;\n             ++__m;          // no need to check range on __m because __s guarantees we have enough source\n            if (!__pred(*__m, __value_))  // if there is a mismatch, restart with a new __first\n            {\n                __first = __m;\n                ++__first;\n                break;\n            }  // else there is a match, check next elements\n        }\n    }\n}\n\ntemplate <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator\nsearch_n(_ForwardIterator __first, _ForwardIterator __last,\n         _Size __count, const _Tp& __value_, _BinaryPredicate __pred)\n{\n    return _VSTD::__search_n<typename add_lvalue_reference<_BinaryPredicate>::type>\n           (__first, __last, __convert_to_integral(__count), __value_, __pred,\n           typename iterator_traits<_ForwardIterator>::iterator_category());\n}\n\ntemplate <class _ForwardIterator, class _Size, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator\nsearch_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_)\n{\n    typedef typename iterator_traits<_ForwardIterator>::value_type __v;\n    return _VSTD::search_n(__first, __last, __convert_to_integral(__count),\n                           __value_, __equal_to<__v, _Tp>());\n}\n\n// copy\n\ntemplate <class _Iter>\nstruct __libcpp_is_trivial_iterator\n{\n    static const bool value = is_pointer<_Iter>::value;\n};\n\ntemplate <class _Iter>\nstruct __libcpp_is_trivial_iterator<move_iterator<_Iter> >\n{\n    static const bool value = is_pointer<_Iter>::value;\n};\n\ntemplate <class _Iter>\nstruct __libcpp_is_trivial_iterator<__wrap_iter<_Iter> >\n{\n    static const bool value = is_pointer<_Iter>::value;\n};\n\ntemplate <class _Iter>\ninline _LIBCPP_INLINE_VISIBILITY\n_Iter\n__unwrap_iter(_Iter __i)\n{\n    return __i;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_trivially_copy_assignable<_Tp>::value,\n    _Tp*\n>::type\n__unwrap_iter(move_iterator<_Tp*> __i)\n{\n    return __i.base();\n}\n\n#if _LIBCPP_DEBUG_LEVEL < 2\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_trivially_copy_assignable<_Tp>::value,\n    _Tp*\n>::type\n__unwrap_iter(__wrap_iter<_Tp*> __i)\n{\n    return __i.base();\n}\n\n#endif  // _LIBCPP_DEBUG_LEVEL < 2\n\ntemplate <class _InputIterator, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\n__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)\n{\n    for (; __first != __last; ++__first, (void) ++__result)\n        *__result = *__first;\n    return __result;\n}\n\ntemplate <class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_same<typename remove_const<_Tp>::type, _Up>::value &&\n    is_trivially_copy_assignable<_Up>::value,\n    _Up*\n>::type\n__copy(_Tp* __first, _Tp* __last, _Up* __result)\n{\n    const size_t __n = static_cast<size_t>(__last - __first);\n    if (__n > 0)\n        _VSTD::memmove(__result, __first, __n * sizeof(_Up));\n    return __result + __n;\n}\n\ntemplate <class _InputIterator, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\ncopy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)\n{\n    return _VSTD::__copy(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));\n}\n\n// copy_backward\n\ntemplate <class _BidirectionalIterator, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\n__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)\n{\n    while (__first != __last)\n        *--__result = *--__last;\n    return __result;\n}\n\ntemplate <class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_same<typename remove_const<_Tp>::type, _Up>::value &&\n    is_trivially_copy_assignable<_Up>::value,\n    _Up*\n>::type\n__copy_backward(_Tp* __first, _Tp* __last, _Up* __result)\n{\n    const size_t __n = static_cast<size_t>(__last - __first);\n    if (__n > 0)\n    {\n        __result -= __n;\n        _VSTD::memmove(__result, __first, __n * sizeof(_Up));\n    }\n    return __result;\n}\n\ntemplate <class _BidirectionalIterator1, class _BidirectionalIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\n_BidirectionalIterator2\ncopy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,\n              _BidirectionalIterator2 __result)\n{\n    return _VSTD::__copy_backward(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));\n}\n\n// copy_if\n\ntemplate<class _InputIterator, class _OutputIterator, class _Predicate>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\ncopy_if(_InputIterator __first, _InputIterator __last,\n        _OutputIterator __result, _Predicate __pred)\n{\n    for (; __first != __last; ++__first)\n    {\n        if (__pred(*__first))\n        {\n            *__result = *__first;\n            ++__result;\n        }\n    }\n    return __result;\n}\n\n// copy_n\n\ntemplate<class _InputIterator, class _Size, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_input_iterator<_InputIterator>::value &&\n   !__is_random_access_iterator<_InputIterator>::value,\n    _OutputIterator\n>::type\ncopy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)\n{\n    typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize;\n    _IntegralSize __n = __orig_n;\n    if (__n > 0)\n    {\n        *__result = *__first;\n        ++__result;\n        for (--__n; __n > 0; --__n)\n        {\n            ++__first;\n            *__result = *__first;\n            ++__result;\n        }\n    }\n    return __result;\n}\n\ntemplate<class _InputIterator, class _Size, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_random_access_iterator<_InputIterator>::value,\n    _OutputIterator\n>::type\ncopy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)\n{\n    typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize;\n    _IntegralSize __n = __orig_n;\n    return _VSTD::copy(__first, __first + __n, __result);\n}\n\n// move\n\ntemplate <class _InputIterator, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\n__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)\n{\n    for (; __first != __last; ++__first, (void) ++__result)\n        *__result = _VSTD::move(*__first);\n    return __result;\n}\n\ntemplate <class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_same<typename remove_const<_Tp>::type, _Up>::value &&\n    is_trivially_copy_assignable<_Up>::value,\n    _Up*\n>::type\n__move(_Tp* __first, _Tp* __last, _Up* __result)\n{\n    const size_t __n = static_cast<size_t>(__last - __first);\n    if (__n > 0)\n        _VSTD::memmove(__result, __first, __n * sizeof(_Up));\n    return __result + __n;\n}\n\ntemplate <class _InputIterator, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nmove(_InputIterator __first, _InputIterator __last, _OutputIterator __result)\n{\n    return _VSTD::__move(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));\n}\n\n// move_backward\n\ntemplate <class _InputIterator, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\n__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result)\n{\n    while (__first != __last)\n        *--__result = _VSTD::move(*--__last);\n    return __result;\n}\n\ntemplate <class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_same<typename remove_const<_Tp>::type, _Up>::value &&\n    is_trivially_copy_assignable<_Up>::value,\n    _Up*\n>::type\n__move_backward(_Tp* __first, _Tp* __last, _Up* __result)\n{\n    const size_t __n = static_cast<size_t>(__last - __first);\n    if (__n > 0)\n    {\n        __result -= __n;\n        _VSTD::memmove(__result, __first, __n * sizeof(_Up));\n    }\n    return __result;\n}\n\ntemplate <class _BidirectionalIterator1, class _BidirectionalIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\n_BidirectionalIterator2\nmove_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,\n              _BidirectionalIterator2 __result)\n{\n    return _VSTD::__move_backward(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));\n}\n\n// iter_swap\n\n// moved to <type_traits> for better swap / noexcept support\n\n// transform\n\ntemplate <class _InputIterator, class _OutputIterator, class _UnaryOperation>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\ntransform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op)\n{\n    for (; __first != __last; ++__first, (void) ++__result)\n        *__result = __op(*__first);\n    return __result;\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _BinaryOperation>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\ntransform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,\n          _OutputIterator __result, _BinaryOperation __binary_op)\n{\n    for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result)\n        *__result = __binary_op(*__first1, *__first2);\n    return __result;\n}\n\n// replace\n\ntemplate <class _ForwardIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nreplace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value)\n{\n    for (; __first != __last; ++__first)\n        if (*__first == __old_value)\n            *__first = __new_value;\n}\n\n// replace_if\n\ntemplate <class _ForwardIterator, class _Predicate, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nreplace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value)\n{\n    for (; __first != __last; ++__first)\n        if (__pred(*__first))\n            *__first = __new_value;\n}\n\n// replace_copy\n\ntemplate <class _InputIterator, class _OutputIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nreplace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result,\n             const _Tp& __old_value, const _Tp& __new_value)\n{\n    for (; __first != __last; ++__first, (void) ++__result)\n        if (*__first == __old_value)\n            *__result = __new_value;\n        else\n            *__result = *__first;\n    return __result;\n}\n\n// replace_copy_if\n\ntemplate <class _InputIterator, class _OutputIterator, class _Predicate, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nreplace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result,\n                _Predicate __pred, const _Tp& __new_value)\n{\n    for (; __first != __last; ++__first, (void) ++__result)\n        if (__pred(*__first))\n            *__result = __new_value;\n        else\n            *__result = *__first;\n    return __result;\n}\n\n// fill_n\n\ntemplate <class _OutputIterator, class _Size, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\n__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)\n{\n    for (; __n > 0; ++__first, (void) --__n)\n        *__first = __value_;\n    return __first;\n}\n\ntemplate <class _Tp, class _Size, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && sizeof(_Tp) == 1 &&\n    !is_same<_Tp, bool>::value &&\n    is_integral<_Up>::value && sizeof(_Up) == 1,\n    _Tp*\n>::type\n__fill_n(_Tp* __first, _Size __n,_Up __value_)\n{\n    if (__n > 0)\n        _VSTD::memset(__first, (unsigned char)__value_, (size_t)(__n));\n    return __first + __n;\n}\n\ntemplate <class _OutputIterator, class _Size, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nfill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)\n{\n   return _VSTD::__fill_n(__first, __convert_to_integral(__n), __value_);\n}\n\n// fill\n\ntemplate <class _ForwardIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, forward_iterator_tag)\n{\n    for (; __first != __last; ++__first)\n        *__first = __value_;\n}\n\ntemplate <class _RandomAccessIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value_, random_access_iterator_tag)\n{\n    _VSTD::fill_n(__first, __last - __first, __value_);\n}\n\ntemplate <class _ForwardIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nfill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)\n{\n    _VSTD::__fill(__first, __last, __value_, typename iterator_traits<_ForwardIterator>::iterator_category());\n}\n\n// generate\n\ntemplate <class _ForwardIterator, class _Generator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\ngenerate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen)\n{\n    for (; __first != __last; ++__first)\n        *__first = __gen();\n}\n\n// generate_n\n\ntemplate <class _OutputIterator, class _Size, class _Generator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\ngenerate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen)\n{\n    typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize;\n    _IntegralSize __n = __orig_n;\n    for (; __n > 0; ++__first, (void) --__n)\n        *__first = __gen();\n    return __first;\n}\n\n// remove\n\ntemplate <class _ForwardIterator, class _Tp>\n_ForwardIterator\nremove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)\n{\n    __first = _VSTD::find(__first, __last, __value_);\n    if (__first != __last)\n    {\n        _ForwardIterator __i = __first;\n        while (++__i != __last)\n        {\n            if (!(*__i == __value_))\n            {\n                *__first = _VSTD::move(*__i);\n                ++__first;\n            }\n        }\n    }\n    return __first;\n}\n\n// remove_if\n\ntemplate <class _ForwardIterator, class _Predicate>\n_ForwardIterator\nremove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)\n{\n    __first = _VSTD::find_if<_ForwardIterator, typename add_lvalue_reference<_Predicate>::type>\n                           (__first, __last, __pred);\n    if (__first != __last)\n    {\n        _ForwardIterator __i = __first;\n        while (++__i != __last)\n        {\n            if (!__pred(*__i))\n            {\n                *__first = _VSTD::move(*__i);\n                ++__first;\n            }\n        }\n    }\n    return __first;\n}\n\n// remove_copy\n\ntemplate <class _InputIterator, class _OutputIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nremove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value_)\n{\n    for (; __first != __last; ++__first)\n    {\n        if (!(*__first == __value_))\n        {\n            *__result = *__first;\n            ++__result;\n        }\n    }\n    return __result;\n}\n\n// remove_copy_if\n\ntemplate <class _InputIterator, class _OutputIterator, class _Predicate>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nremove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred)\n{\n    for (; __first != __last; ++__first)\n    {\n        if (!__pred(*__first))\n        {\n            *__result = *__first;\n            ++__result;\n        }\n    }\n    return __result;\n}\n\n// unique\n\ntemplate <class _ForwardIterator, class _BinaryPredicate>\n_ForwardIterator\nunique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)\n{\n    __first = _VSTD::adjacent_find<_ForwardIterator, typename add_lvalue_reference<_BinaryPredicate>::type>\n                                 (__first, __last, __pred);\n    if (__first != __last)\n    {\n        // ...  a  a  ?  ...\n        //      f     i\n        _ForwardIterator __i = __first;\n        for (++__i; ++__i != __last;)\n            if (!__pred(*__first, *__i))\n                *++__first = _VSTD::move(*__i);\n        ++__first;\n    }\n    return __first;\n}\n\ntemplate <class _ForwardIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator\nunique(_ForwardIterator __first, _ForwardIterator __last)\n{\n    typedef typename iterator_traits<_ForwardIterator>::value_type __v;\n    return _VSTD::unique(__first, __last, __equal_to<__v>());\n}\n\n// unique_copy\n\ntemplate <class _BinaryPredicate, class _InputIterator, class _OutputIterator>\n_OutputIterator\n__unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred,\n              input_iterator_tag, output_iterator_tag)\n{\n    if (__first != __last)\n    {\n        typename iterator_traits<_InputIterator>::value_type __t(*__first);\n        *__result = __t;\n        ++__result;\n        while (++__first != __last)\n        {\n            if (!__pred(__t, *__first))\n            {\n                __t = *__first;\n                *__result = __t;\n                ++__result;\n            }\n        }\n    }\n    return __result;\n}\n\ntemplate <class _BinaryPredicate, class _ForwardIterator, class _OutputIterator>\n_OutputIterator\n__unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred,\n              forward_iterator_tag, output_iterator_tag)\n{\n    if (__first != __last)\n    {\n        _ForwardIterator __i = __first;\n        *__result = *__i;\n        ++__result;\n        while (++__first != __last)\n        {\n            if (!__pred(*__i, *__first))\n            {\n                *__result = *__first;\n                ++__result;\n                __i = __first;\n            }\n        }\n    }\n    return __result;\n}\n\ntemplate <class _BinaryPredicate, class _InputIterator, class _ForwardIterator>\n_ForwardIterator\n__unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred,\n              input_iterator_tag, forward_iterator_tag)\n{\n    if (__first != __last)\n    {\n        *__result = *__first;\n        while (++__first != __last)\n            if (!__pred(*__result, *__first))\n                *++__result = *__first;\n        ++__result;\n    }\n    return __result;\n}\n\ntemplate <class _InputIterator, class _OutputIterator, class _BinaryPredicate>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nunique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred)\n{\n    return _VSTD::__unique_copy<typename add_lvalue_reference<_BinaryPredicate>::type>\n                              (__first, __last, __result, __pred,\n                               typename iterator_traits<_InputIterator>::iterator_category(),\n                               typename iterator_traits<_OutputIterator>::iterator_category());\n}\n\ntemplate <class _InputIterator, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nunique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)\n{\n    typedef typename iterator_traits<_InputIterator>::value_type __v;\n    return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>());\n}\n\n// reverse\n\ntemplate <class _BidirectionalIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag)\n{\n    while (__first != __last)\n    {\n        if (__first == --__last)\n            break;\n        swap(*__first, *__last);\n        ++__first;\n    }\n}\n\ntemplate <class _RandomAccessIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag)\n{\n    if (__first != __last)\n        for (; __first < --__last; ++__first)\n            swap(*__first, *__last);\n}\n\ntemplate <class _BidirectionalIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nreverse(_BidirectionalIterator __first, _BidirectionalIterator __last)\n{\n    _VSTD::__reverse(__first, __last, typename iterator_traits<_BidirectionalIterator>::iterator_category());\n}\n\n// reverse_copy\n\ntemplate <class _BidirectionalIterator, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nreverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)\n{\n    for (; __first != __last; ++__result)\n        *__result = *--__last;\n    return __result;\n}\n\n// rotate\n\ntemplate <class _ForwardIterator>\n_ForwardIterator\n__rotate_left(_ForwardIterator __first, _ForwardIterator __last)\n{\n    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;\n    value_type __tmp = _VSTD::move(*__first);\n    _ForwardIterator __lm1 = _VSTD::move(_VSTD::next(__first), __last, __first);\n    *__lm1 = _VSTD::move(__tmp);\n    return __lm1;\n}\n\ntemplate <class _BidirectionalIterator>\n_BidirectionalIterator\n__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last)\n{\n    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;\n    _BidirectionalIterator __lm1 = _VSTD::prev(__last);\n    value_type __tmp = _VSTD::move(*__lm1);\n    _BidirectionalIterator __fp1 = _VSTD::move_backward(__first, __lm1, __last);\n    *__first = _VSTD::move(__tmp);\n    return __fp1;\n}\n\ntemplate <class _ForwardIterator>\n_ForwardIterator\n__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)\n{\n    _ForwardIterator __i = __middle;\n    while (true)\n    {\n        swap(*__first, *__i);\n        ++__first;\n        if (++__i == __last)\n            break;\n        if (__first == __middle)\n            __middle = __i;\n    }\n    _ForwardIterator __r = __first;\n    if (__first != __middle)\n    {\n        __i = __middle;\n        while (true)\n        {\n            swap(*__first, *__i);\n            ++__first;\n            if (++__i == __last)\n            {\n                if (__first == __middle)\n                    break;\n                __i = __middle;\n            }\n            else if (__first == __middle)\n                __middle = __i;\n        }\n    }\n    return __r;\n}\n\ntemplate<typename _Integral>\ninline _LIBCPP_INLINE_VISIBILITY\n_Integral\n__gcd(_Integral __x, _Integral __y)\n{\n    do\n    {\n        _Integral __t = __x % __y;\n        __x = __y;\n        __y = __t;\n    } while (__y);\n    return __x;\n}\n\ntemplate<typename _RandomAccessIterator>\n_RandomAccessIterator\n__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)\n{\n    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;\n    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;\n\n    const difference_type __m1 = __middle - __first;\n    const difference_type __m2 = __last - __middle;\n    if (__m1 == __m2)\n    {\n        _VSTD::swap_ranges(__first, __middle, __middle);\n        return __middle;\n    }\n    const difference_type __g = _VSTD::__gcd(__m1, __m2);\n    for (_RandomAccessIterator __p = __first + __g; __p != __first;)\n    {\n        value_type __t(_VSTD::move(*--__p));\n        _RandomAccessIterator __p1 = __p;\n        _RandomAccessIterator __p2 = __p1 + __m1;\n        do\n        {\n            *__p1 = _VSTD::move(*__p2);\n            __p1 = __p2;\n            const difference_type __d = __last - __p2;\n            if (__m1 < __d)\n                __p2 += __m1;\n            else\n                __p2 = __first + (__m1 - __d);\n        } while (__p2 != __p);\n        *__p1 = _VSTD::move(__t);\n    }\n    return __first + __m2;\n}\n\ntemplate <class _ForwardIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator\n__rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,\n         _VSTD::forward_iterator_tag)\n{\n    typedef typename _VSTD::iterator_traits<_ForwardIterator>::value_type value_type;\n    if (_VSTD::is_trivially_move_assignable<value_type>::value)\n    {\n        if (_VSTD::next(__first) == __middle)\n            return _VSTD::__rotate_left(__first, __last);\n    }\n    return _VSTD::__rotate_forward(__first, __middle, __last);\n}\n\ntemplate <class _BidirectionalIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_BidirectionalIterator\n__rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,\n         _VSTD::bidirectional_iterator_tag)\n{\n    typedef typename _VSTD::iterator_traits<_BidirectionalIterator>::value_type value_type;\n    if (_VSTD::is_trivially_move_assignable<value_type>::value)\n    {\n        if (_VSTD::next(__first) == __middle)\n            return _VSTD::__rotate_left(__first, __last);\n        if (_VSTD::next(__middle) == __last)\n            return _VSTD::__rotate_right(__first, __last);\n    }\n    return _VSTD::__rotate_forward(__first, __middle, __last);\n}\n\ntemplate <class _RandomAccessIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_RandomAccessIterator\n__rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,\n         _VSTD::random_access_iterator_tag)\n{\n    typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::value_type value_type;\n    if (_VSTD::is_trivially_move_assignable<value_type>::value)\n    {\n        if (_VSTD::next(__first) == __middle)\n            return _VSTD::__rotate_left(__first, __last);\n        if (_VSTD::next(__middle) == __last)\n            return _VSTD::__rotate_right(__first, __last);\n        return _VSTD::__rotate_gcd(__first, __middle, __last);\n    }\n    return _VSTD::__rotate_forward(__first, __middle, __last);\n}\n\ntemplate <class _ForwardIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator\nrotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)\n{\n    if (__first == __middle)\n        return __last;\n    if (__middle == __last)\n        return __first;\n    return _VSTD::__rotate(__first, __middle, __last,\n                           typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category());\n}\n\n// rotate_copy\n\ntemplate <class _ForwardIterator, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nrotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result)\n{\n    return _VSTD::copy(__first, __middle, _VSTD::copy(__middle, __last, __result));\n}\n\n// min_element\n\ntemplate <class _ForwardIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_ForwardIterator\nmin_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)\n{\n    if (__first != __last)\n    {\n        _ForwardIterator __i = __first;\n        while (++__i != __last)\n            if (__comp(*__i, *__first))\n                __first = __i;\n    }\n    return __first;\n}\n\ntemplate <class _ForwardIterator>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_ForwardIterator\nmin_element(_ForwardIterator __first, _ForwardIterator __last)\n{\n    return _VSTD::min_element(__first, __last,\n              __less<typename iterator_traits<_ForwardIterator>::value_type>());\n}\n\n// min\n\ntemplate <class _Tp, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nconst _Tp&\nmin(const _Tp& __a, const _Tp& __b, _Compare __comp)\n{\n    return __comp(__b, __a) ? __b : __a;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nconst _Tp&\nmin(const _Tp& __a, const _Tp& __b)\n{\n    return _VSTD::min(__a, __b, __less<_Tp>());\n}\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate<class _Tp, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_Tp\nmin(initializer_list<_Tp> __t, _Compare __comp)\n{\n    return *_VSTD::min_element(__t.begin(), __t.end(), __comp);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_Tp\nmin(initializer_list<_Tp> __t)\n{\n    return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>());\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n// max_element\n\ntemplate <class _ForwardIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_ForwardIterator\nmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)\n{\n    if (__first != __last)\n    {\n        _ForwardIterator __i = __first;\n        while (++__i != __last)\n            if (__comp(*__first, *__i))\n                __first = __i;\n    }\n    return __first;\n}\n\n\ntemplate <class _ForwardIterator>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_ForwardIterator\nmax_element(_ForwardIterator __first, _ForwardIterator __last)\n{\n    return _VSTD::max_element(__first, __last,\n              __less<typename iterator_traits<_ForwardIterator>::value_type>());\n}\n\n// max\n\ntemplate <class _Tp, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nconst _Tp&\nmax(const _Tp& __a, const _Tp& __b, _Compare __comp)\n{\n    return __comp(__a, __b) ? __b : __a;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nconst _Tp&\nmax(const _Tp& __a, const _Tp& __b)\n{\n    return _VSTD::max(__a, __b, __less<_Tp>());\n}\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate<class _Tp, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_Tp\nmax(initializer_list<_Tp> __t, _Compare __comp)\n{\n    return *_VSTD::max_element(__t.begin(), __t.end(), __comp);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_Tp\nmax(initializer_list<_Tp> __t)\n{\n    return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>());\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n// minmax_element\n\ntemplate <class _ForwardIterator, class _Compare>\n_LIBCPP_CONSTEXPR_AFTER_CXX11\nstd::pair<_ForwardIterator, _ForwardIterator>\nminmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)\n{\n  std::pair<_ForwardIterator, _ForwardIterator> __result(__first, __first);\n  if (__first != __last)\n  {\n      if (++__first != __last)\n      {\n          if (__comp(*__first, *__result.first))\n              __result.first = __first;\n          else\n              __result.second = __first;\n          while (++__first != __last)\n          {\n              _ForwardIterator __i = __first;\n              if (++__first == __last)\n              {\n                  if (__comp(*__i, *__result.first))\n                      __result.first = __i;\n                  else if (!__comp(*__i, *__result.second))\n                      __result.second = __i;\n                  break;\n              }\n              else\n              {\n                  if (__comp(*__first, *__i))\n                  {\n                      if (__comp(*__first, *__result.first))\n                          __result.first = __first;\n                      if (!__comp(*__i, *__result.second))\n                          __result.second = __i;\n                  }\n                  else\n                  {\n                      if (__comp(*__i, *__result.first))\n                          __result.first = __i;\n                      if (!__comp(*__first, *__result.second))\n                          __result.second = __first;\n                  }\n              }\n          }\n      }\n  }\n  return __result;\n}\n\ntemplate <class _ForwardIterator>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nstd::pair<_ForwardIterator, _ForwardIterator>\nminmax_element(_ForwardIterator __first, _ForwardIterator __last)\n{\n    return _VSTD::minmax_element(__first, __last,\n              __less<typename iterator_traits<_ForwardIterator>::value_type>());\n}\n\n// minmax\n\ntemplate<class _Tp, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\npair<const _Tp&, const _Tp&>\nminmax(const _Tp& __a, const _Tp& __b, _Compare __comp)\n{\n    return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) :\n                              pair<const _Tp&, const _Tp&>(__a, __b);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\npair<const _Tp&, const _Tp&>\nminmax(const _Tp& __a, const _Tp& __b)\n{\n    return _VSTD::minmax(__a, __b, __less<_Tp>());\n}\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate<class _Tp, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\npair<_Tp, _Tp>\nminmax(initializer_list<_Tp> __t, _Compare __comp)\n{\n    typedef typename initializer_list<_Tp>::const_iterator _Iter;\n    _Iter __first = __t.begin();\n    _Iter __last  = __t.end();\n    std::pair<_Tp, _Tp> __result(*__first, *__first);\n\n    ++__first;\n    if (__t.size() % 2 == 0)\n    {\n        if (__comp(*__first,  __result.first))\n            __result.first  = *__first;\n        else\n            __result.second = *__first;\n        ++__first;\n    }\n    \n    while (__first != __last)\n    {\n        _Tp __prev = *__first++;\n        if (__comp(*__first, __prev)) {\n            if ( __comp(*__first, __result.first)) __result.first  = *__first;\n            if (!__comp(__prev, __result.second))  __result.second = __prev;\n            }\n        else {\n            if ( __comp(__prev, __result.first))    __result.first  = __prev;\n            if (!__comp(*__first, __result.second)) __result.second = *__first;\n            }\n                \n        __first++;\n    }\n    return __result;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\npair<_Tp, _Tp>\nminmax(initializer_list<_Tp> __t)\n{\n    return _VSTD::minmax(__t, __less<_Tp>());\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n// random_shuffle\n\n// __independent_bits_engine\n\ntemplate <unsigned long long _Xp, size_t _Rp>\nstruct __log2_imp\n{\n    static const size_t value = _Xp & ((unsigned long long)(1) << _Rp) ? _Rp\n                                           : __log2_imp<_Xp, _Rp - 1>::value;\n};\n\ntemplate <unsigned long long _Xp>\nstruct __log2_imp<_Xp, 0>\n{\n    static const size_t value = 0;\n};\n\ntemplate <size_t _Rp>\nstruct __log2_imp<0, _Rp>\n{\n    static const size_t value = _Rp + 1;\n};\n\ntemplate <class _UI, _UI _Xp>\nstruct __log2\n{\n    static const size_t value = __log2_imp<_Xp,\n                                         sizeof(_UI) * __CHAR_BIT__ - 1>::value;\n};\n\ntemplate<class _Engine, class _UIntType>\nclass __independent_bits_engine\n{\npublic:\n    // types\n    typedef _UIntType result_type;\n\nprivate:\n    typedef typename _Engine::result_type _Engine_result_type;\n    typedef typename conditional\n        <\n            sizeof(_Engine_result_type) <= sizeof(result_type),\n                result_type,\n                _Engine_result_type\n        >::type _Working_result_type;\n\n    _Engine& __e_;\n    size_t __w_;\n    size_t __w0_;\n    size_t __n_;\n    size_t __n0_;\n    _Working_result_type __y0_;\n    _Working_result_type __y1_;\n    _Engine_result_type __mask0_;\n    _Engine_result_type __mask1_;\n\n#ifdef _LIBCPP_HAS_NO_CONSTEXPR\n    static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min\n                                          + _Working_result_type(1);\n#else\n    static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min()\n                                                      + _Working_result_type(1);\n#endif\n    static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value;\n    static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits;\n    static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits;\n\npublic:\n    // constructors and seeding functions\n    __independent_bits_engine(_Engine& __e, size_t __w);\n\n    // generating functions\n    result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}\n\nprivate:\n    result_type __eval(false_type);\n    result_type __eval(true_type);\n};\n\ntemplate<class _Engine, class _UIntType>\n__independent_bits_engine<_Engine, _UIntType>\n    ::__independent_bits_engine(_Engine& __e, size_t __w)\n        : __e_(__e),\n          __w_(__w)\n{\n    __n_ = __w_ / __m + (__w_ % __m != 0);\n    __w0_ = __w_ / __n_;\n    if (_Rp == 0)\n        __y0_ = _Rp;\n    else if (__w0_ < _WDt)\n        __y0_ = (_Rp >> __w0_) << __w0_;\n    else\n        __y0_ = 0;\n    if (_Rp - __y0_ > __y0_ / __n_)\n    {\n        ++__n_;\n        __w0_ = __w_ / __n_;\n        if (__w0_ < _WDt)\n            __y0_ = (_Rp >> __w0_) << __w0_;\n        else\n            __y0_ = 0;\n    }\n    __n0_ = __n_ - __w_ % __n_;\n    if (__w0_ < _WDt - 1)\n        __y1_ = (_Rp >> (__w0_ + 1)) << (__w0_ + 1);\n    else\n        __y1_ = 0;\n    __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_) :\n                          _Engine_result_type(0);\n    __mask1_ = __w0_ < _EDt - 1 ?\n                               _Engine_result_type(~0) >> (_EDt - (__w0_ + 1)) :\n                               _Engine_result_type(~0);\n}\n\ntemplate<class _Engine, class _UIntType>\ninline\n_UIntType\n__independent_bits_engine<_Engine, _UIntType>::__eval(false_type)\n{\n    return static_cast<result_type>(__e_() & __mask0_);\n}\n\ntemplate<class _Engine, class _UIntType>\n_UIntType\n__independent_bits_engine<_Engine, _UIntType>::__eval(true_type)\n{\n    result_type _Sp = 0;\n    for (size_t __k = 0; __k < __n0_; ++__k)\n    {\n        _Engine_result_type __u;\n        do\n        {\n            __u = __e_() - _Engine::min();\n        } while (__u >= __y0_);\n        if (__w0_ < _WDt)\n            _Sp <<= __w0_;\n        else\n            _Sp = 0;\n        _Sp += __u & __mask0_;\n    }\n    for (size_t __k = __n0_; __k < __n_; ++__k)\n    {\n        _Engine_result_type __u;\n        do\n        {\n            __u = __e_() - _Engine::min();\n        } while (__u >= __y1_);\n        if (__w0_ < _WDt - 1)\n            _Sp <<= __w0_ + 1;\n        else\n            _Sp = 0;\n        _Sp += __u & __mask1_;\n    }\n    return _Sp;\n}\n\n// uniform_int_distribution\n\ntemplate<class _IntType = int>\nclass uniform_int_distribution\n{\npublic:\n    // types\n    typedef _IntType result_type;\n\n    class param_type\n    {\n        result_type __a_;\n        result_type __b_;\n    public:\n        typedef uniform_int_distribution distribution_type;\n\n        explicit param_type(result_type __a = 0,\n                            result_type __b = numeric_limits<result_type>::max())\n            : __a_(__a), __b_(__b) {}\n\n        result_type a() const {return __a_;}\n        result_type b() const {return __b_;}\n\n        friend bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}\n        friend bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructors and reset functions\n    explicit uniform_int_distribution(result_type __a = 0,\n                                      result_type __b = numeric_limits<result_type>::max())\n        : __p_(param_type(__a, __b)) {}\n    explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {}\n    void reset() {}\n\n    // generating functions\n    template<class _URNG> result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    result_type a() const {return __p_.a();}\n    result_type b() const {return __p_.b();}\n\n    param_type param() const {return __p_;}\n    void param(const param_type& __p) {__p_ = __p;}\n\n    result_type min() const {return a();}\n    result_type max() const {return b();}\n\n    friend bool operator==(const uniform_int_distribution& __x,\n                           const uniform_int_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend bool operator!=(const uniform_int_distribution& __x,\n                           const uniform_int_distribution& __y)\n            {return !(__x == __y);}\n};\n\ntemplate<class _IntType>\ntemplate<class _URNG>\ntypename uniform_int_distribution<_IntType>::result_type\nuniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)\n{\n    typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t),\n                                            uint32_t, uint64_t>::type _UIntType;\n    const _UIntType _Rp = __p.b() - __p.a() + _UIntType(1);\n    if (_Rp == 1)\n        return __p.a();\n    const size_t _Dt = numeric_limits<_UIntType>::digits;\n    typedef __independent_bits_engine<_URNG, _UIntType> _Eng;\n    if (_Rp == 0)\n        return static_cast<result_type>(_Eng(__g, _Dt)());\n    size_t __w = _Dt - __clz(_Rp) - 1;\n    if ((_Rp & (std::numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0)\n        ++__w;\n    _Eng __e(__g, __w);\n    _UIntType __u;\n    do\n    {\n        __u = __e();\n    } while (__u >= _Rp);\n    return static_cast<result_type>(__u + __p.a());\n}\n\nclass _LIBCPP_TYPE_VIS __rs_default;\n\n_LIBCPP_FUNC_VIS __rs_default __rs_get();\n\nclass _LIBCPP_TYPE_VIS __rs_default\n{\n    static unsigned __c_;\n\n    __rs_default();\npublic:\n    typedef uint_fast32_t result_type;\n\n    static const result_type _Min = 0;\n    static const result_type _Max = 0xFFFFFFFF;\n\n    __rs_default(const __rs_default&);\n    ~__rs_default();\n\n    result_type operator()();\n\n    static _LIBCPP_CONSTEXPR result_type min() {return _Min;}\n    static _LIBCPP_CONSTEXPR result_type max() {return _Max;}\n\n    friend _LIBCPP_FUNC_VIS __rs_default __rs_get();\n};\n\n_LIBCPP_FUNC_VIS __rs_default __rs_get();\n\ntemplate <class _RandomAccessIterator>\nvoid\nrandom_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)\n{\n    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;\n    typedef uniform_int_distribution<ptrdiff_t> _Dp;\n    typedef typename _Dp::param_type _Pp;\n    difference_type __d = __last - __first;\n    if (__d > 1)\n    {\n        _Dp __uid;\n        __rs_default __g = __rs_get();\n        for (--__last, --__d; __first < __last; ++__first, --__d)\n        {\n            difference_type __i = __uid(__g, _Pp(0, __d));\n            if (__i != difference_type(0))\n                swap(*__first, *(__first + __i));\n        }\n    }\n}\n\ntemplate <class _RandomAccessIterator, class _RandomNumberGenerator>\nvoid\nrandom_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n               _RandomNumberGenerator&& __rand)\n#else\n               _RandomNumberGenerator& __rand)\n#endif\n{\n    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;\n    difference_type __d = __last - __first;\n    if (__d > 1)\n    {\n        for (--__last; __first < __last; ++__first, --__d)\n        {\n            difference_type __i = __rand(__d);\n            swap(*__first, *(__first + __i));\n        }\n    }\n}\n\ntemplate<class _RandomAccessIterator, class _UniformRandomNumberGenerator>\n    void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n                 _UniformRandomNumberGenerator&& __g)\n#else\n                 _UniformRandomNumberGenerator& __g)\n#endif\n{\n    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;\n    typedef uniform_int_distribution<ptrdiff_t> _Dp;\n    typedef typename _Dp::param_type _Pp;\n    difference_type __d = __last - __first;\n    if (__d > 1)\n    {\n        _Dp __uid;\n        for (--__last, --__d; __first < __last; ++__first, --__d)\n        {\n            difference_type __i = __uid(__g, _Pp(0, __d));\n            if (__i != difference_type(0))\n                swap(*__first, *(__first + __i));\n        }\n    }\n}\n\ntemplate <class _InputIterator, class _Predicate>\nbool\nis_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred)\n{\n    for (; __first != __last; ++__first)\n        if (!__pred(*__first))\n            break;\n    if ( __first == __last )\n        return true;\n    ++__first;\n    for (; __first != __last; ++__first)\n        if (__pred(*__first))\n            return false;\n    return true;\n}\n\n// partition\n\ntemplate <class _Predicate, class _ForwardIterator>\n_ForwardIterator\n__partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag)\n{\n    while (true)\n    {\n        if (__first == __last)\n            return __first;\n        if (!__pred(*__first))\n            break;\n        ++__first;\n    }\n    for (_ForwardIterator __p = __first; ++__p != __last;)\n    {\n        if (__pred(*__p))\n        {\n            swap(*__first, *__p);\n            ++__first;\n        }\n    }\n    return __first;\n}\n\ntemplate <class _Predicate, class _BidirectionalIterator>\n_BidirectionalIterator\n__partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,\n            bidirectional_iterator_tag)\n{\n    while (true)\n    {\n        while (true)\n        {\n            if (__first == __last)\n                return __first;\n            if (!__pred(*__first))\n                break;\n            ++__first;\n        }\n        do\n        {\n            if (__first == --__last)\n                return __first;\n        } while (!__pred(*__last));\n        swap(*__first, *__last);\n        ++__first;\n    }\n}\n\ntemplate <class _ForwardIterator, class _Predicate>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator\npartition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)\n{\n    return _VSTD::__partition<typename add_lvalue_reference<_Predicate>::type>\n                            (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());\n}\n\n// partition_copy\n\ntemplate <class _InputIterator, class _OutputIterator1,\n          class _OutputIterator2, class _Predicate>\npair<_OutputIterator1, _OutputIterator2>\npartition_copy(_InputIterator __first, _InputIterator __last,\n               _OutputIterator1 __out_true, _OutputIterator2 __out_false,\n               _Predicate __pred)\n{\n    for (; __first != __last; ++__first)\n    {\n        if (__pred(*__first))\n        {\n            *__out_true = *__first;\n            ++__out_true;\n        }\n        else\n        {\n            *__out_false = *__first;\n            ++__out_false;\n        }\n    }\n    return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false);\n}\n\n// partition_point\n\ntemplate<class _ForwardIterator, class _Predicate>\n_ForwardIterator\npartition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)\n{\n    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;\n    difference_type __len = _VSTD::distance(__first, __last);\n    while (__len != 0)\n    {\n        difference_type __l2 = __len / 2;\n        _ForwardIterator __m = __first;\n        _VSTD::advance(__m, __l2);\n        if (__pred(*__m))\n        {\n            __first = ++__m;\n            __len -= __l2 + 1;\n        }\n        else\n            __len = __l2;\n    }\n    return __first;\n}\n\n// stable_partition\n\ntemplate <class _Predicate, class _ForwardIterator, class _Distance, class _Pair>\n_ForwardIterator\n__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,\n                   _Distance __len, _Pair __p, forward_iterator_tag __fit)\n{\n    // *__first is known to be false\n    // __len >= 1\n    if (__len == 1)\n        return __first;\n    if (__len == 2)\n    {\n        _ForwardIterator __m = __first;\n        if (__pred(*++__m))\n        {\n            swap(*__first, *__m);\n            return __m;\n        }\n        return __first;\n    }\n    if (__len <= __p.second)\n    {   // The buffer is big enough to use\n        typedef typename iterator_traits<_ForwardIterator>::value_type value_type;\n        __destruct_n __d(0);\n        unique_ptr<value_type, __destruct_n&> __h(__p.first, __d);\n        // Move the falses into the temporary buffer, and the trues to the front of the line\n        // Update __first to always point to the end of the trues\n        value_type* __t = __p.first;\n        ::new(__t) value_type(_VSTD::move(*__first));\n        __d.__incr((value_type*)0);\n        ++__t;\n        _ForwardIterator __i = __first;\n        while (++__i != __last)\n        {\n            if (__pred(*__i))\n            {\n                *__first = _VSTD::move(*__i);\n                ++__first;\n            }\n            else\n            {\n                ::new(__t) value_type(_VSTD::move(*__i));\n                __d.__incr((value_type*)0);\n                ++__t;\n            }\n        }\n        // All trues now at start of range, all falses in buffer\n        // Move falses back into range, but don't mess up __first which points to first false\n        __i = __first;\n        for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, ++__i)\n            *__i = _VSTD::move(*__t2);\n        // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer\n        return __first;\n    }\n    // Else not enough buffer, do in place\n    // __len >= 3\n    _ForwardIterator __m = __first;\n    _Distance __len2 = __len / 2;  // __len2 >= 2\n    _VSTD::advance(__m, __len2);\n    // recurse on [__first, __m), *__first know to be false\n    // F?????????????????\n    // f       m         l\n    typedef typename add_lvalue_reference<_Predicate>::type _PredRef;\n    _ForwardIterator __first_false = __stable_partition<_PredRef>(__first, __m, __pred, __len2, __p, __fit);\n    // TTTFFFFF??????????\n    // f  ff   m         l\n    // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true\n    _ForwardIterator __m1 = __m;\n    _ForwardIterator __second_false = __last;\n    _Distance __len_half = __len - __len2;\n    while (__pred(*__m1))\n    {\n        if (++__m1 == __last)\n            goto __second_half_done;\n        --__len_half;\n    }\n    // TTTFFFFFTTTF??????\n    // f  ff   m  m1     l\n    __second_false = __stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __fit);\n__second_half_done:\n    // TTTFFFFFTTTTTFFFFF\n    // f  ff   m    sf   l\n    return _VSTD::rotate(__first_false, __m, __second_false);\n    // TTTTTTTTFFFFFFFFFF\n    //         |\n}\n\nstruct __return_temporary_buffer\n{\n    template <class _Tp>\n    _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) const {_VSTD::return_temporary_buffer(__p);}\n};\n\ntemplate <class _Predicate, class _ForwardIterator>\n_ForwardIterator\n__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,\n                   forward_iterator_tag)\n{\n    const unsigned __alloc_limit = 3;  // might want to make this a function of trivial assignment\n    // Either prove all true and return __first or point to first false\n    while (true)\n    {\n        if (__first == __last)\n            return __first;\n        if (!__pred(*__first))\n            break;\n        ++__first;\n    }\n    // We now have a reduced range [__first, __last)\n    // *__first is known to be false\n    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;\n    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;\n    difference_type __len = _VSTD::distance(__first, __last);\n    pair<value_type*, ptrdiff_t> __p(0, 0);\n    unique_ptr<value_type, __return_temporary_buffer> __h;\n    if (__len >= __alloc_limit)\n    {\n        __p = _VSTD::get_temporary_buffer<value_type>(__len);\n        __h.reset(__p.first);\n    }\n    return __stable_partition<typename add_lvalue_reference<_Predicate>::type>\n                             (__first, __last, __pred, __len, __p, forward_iterator_tag());\n}\n\ntemplate <class _Predicate, class _BidirectionalIterator, class _Distance, class _Pair>\n_BidirectionalIterator\n__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,\n                   _Distance __len, _Pair __p, bidirectional_iterator_tag __bit)\n{\n    // *__first is known to be false\n    // *__last is known to be true\n    // __len >= 2\n    if (__len == 2)\n    {\n        swap(*__first, *__last);\n        return __last;\n    }\n    if (__len == 3)\n    {\n        _BidirectionalIterator __m = __first;\n        if (__pred(*++__m))\n        {\n            swap(*__first, *__m);\n            swap(*__m, *__last);\n            return __last;\n        }\n        swap(*__m, *__last);\n        swap(*__first, *__m);\n        return __m;\n    }\n    if (__len <= __p.second)\n    {   // The buffer is big enough to use\n        typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;\n        __destruct_n __d(0);\n        unique_ptr<value_type, __destruct_n&> __h(__p.first, __d);\n        // Move the falses into the temporary buffer, and the trues to the front of the line\n        // Update __first to always point to the end of the trues\n        value_type* __t = __p.first;\n        ::new(__t) value_type(_VSTD::move(*__first));\n        __d.__incr((value_type*)0);\n        ++__t;\n        _BidirectionalIterator __i = __first;\n        while (++__i != __last)\n        {\n            if (__pred(*__i))\n            {\n                *__first = _VSTD::move(*__i);\n                ++__first;\n            }\n            else\n            {\n                ::new(__t) value_type(_VSTD::move(*__i));\n                __d.__incr((value_type*)0);\n                ++__t;\n            }\n        }\n        // move *__last, known to be true\n        *__first = _VSTD::move(*__i);\n        __i = ++__first;\n        // All trues now at start of range, all falses in buffer\n        // Move falses back into range, but don't mess up __first which points to first false\n        for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, ++__i)\n            *__i = _VSTD::move(*__t2);\n        // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer\n        return __first;\n    }\n    // Else not enough buffer, do in place\n    // __len >= 4\n    _BidirectionalIterator __m = __first;\n    _Distance __len2 = __len / 2;  // __len2 >= 2\n    _VSTD::advance(__m, __len2);\n    // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false\n    // F????????????????T\n    // f       m        l\n    _BidirectionalIterator __m1 = __m;\n    _BidirectionalIterator __first_false = __first;\n    _Distance __len_half = __len2;\n    while (!__pred(*--__m1))\n    {\n        if (__m1 == __first)\n            goto __first_half_done;\n        --__len_half;\n    }\n    // F???TFFF?????????T\n    // f   m1  m        l\n    typedef typename add_lvalue_reference<_Predicate>::type _PredRef;\n    __first_false = __stable_partition<_PredRef>(__first, __m1, __pred, __len_half, __p, __bit);\n__first_half_done:\n    // TTTFFFFF?????????T\n    // f  ff   m        l\n    // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true\n    __m1 = __m;\n    _BidirectionalIterator __second_false = __last;\n    ++__second_false;\n    __len_half = __len - __len2;\n    while (__pred(*__m1))\n    {\n        if (++__m1 == __last)\n            goto __second_half_done;\n        --__len_half;\n    }\n    // TTTFFFFFTTTF?????T\n    // f  ff   m  m1    l\n    __second_false = __stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __bit);\n__second_half_done:\n    // TTTFFFFFTTTTTFFFFF\n    // f  ff   m    sf  l\n    return _VSTD::rotate(__first_false, __m, __second_false);\n    // TTTTTTTTFFFFFFFFFF\n    //         |\n}\n\ntemplate <class _Predicate, class _BidirectionalIterator>\n_BidirectionalIterator\n__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,\n                   bidirectional_iterator_tag)\n{\n    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;\n    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;\n    const difference_type __alloc_limit = 4;  // might want to make this a function of trivial assignment\n    // Either prove all true and return __first or point to first false\n    while (true)\n    {\n        if (__first == __last)\n            return __first;\n        if (!__pred(*__first))\n            break;\n        ++__first;\n    }\n    // __first points to first false, everything prior to __first is already set.\n    // Either prove [__first, __last) is all false and return __first, or point __last to last true\n    do\n    {\n        if (__first == --__last)\n            return __first;\n    } while (!__pred(*__last));\n    // We now have a reduced range [__first, __last]\n    // *__first is known to be false\n    // *__last is known to be true\n    // __len >= 2\n    difference_type __len = _VSTD::distance(__first, __last) + 1;\n    pair<value_type*, ptrdiff_t> __p(0, 0);\n    unique_ptr<value_type, __return_temporary_buffer> __h;\n    if (__len >= __alloc_limit)\n    {\n        __p = _VSTD::get_temporary_buffer<value_type>(__len);\n        __h.reset(__p.first);\n    }\n    return __stable_partition<typename add_lvalue_reference<_Predicate>::type>\n                             (__first, __last, __pred, __len, __p, bidirectional_iterator_tag());\n}\n\ntemplate <class _ForwardIterator, class _Predicate>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator\nstable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)\n{\n    return __stable_partition<typename add_lvalue_reference<_Predicate>::type>\n                             (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());\n}\n\n// is_sorted_until\n\ntemplate <class _ForwardIterator, class _Compare>\n_ForwardIterator\nis_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)\n{\n    if (__first != __last)\n    {\n        _ForwardIterator __i = __first;\n        while (++__i != __last)\n        {\n            if (__comp(*__i, *__first))\n                return __i;\n            __first = __i;\n        }\n    }\n    return __last;\n}\n\ntemplate<class _ForwardIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator\nis_sorted_until(_ForwardIterator __first, _ForwardIterator __last)\n{\n    return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());\n}\n\n// is_sorted\n\ntemplate <class _ForwardIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nis_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)\n{\n    return _VSTD::is_sorted_until(__first, __last, __comp) == __last;\n}\n\ntemplate<class _ForwardIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nis_sorted(_ForwardIterator __first, _ForwardIterator __last)\n{\n    return _VSTD::is_sorted(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());\n}\n\n// sort\n\n// stable, 2-3 compares, 0-2 swaps\n\ntemplate <class _Compare, class _ForwardIterator>\nunsigned\n__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c)\n{\n    unsigned __r = 0;\n    if (!__c(*__y, *__x))          // if x <= y\n    {\n        if (!__c(*__z, *__y))      // if y <= z\n            return __r;            // x <= y && y <= z\n                                   // x <= y && y > z\n        swap(*__y, *__z);          // x <= z && y < z\n        __r = 1;\n        if (__c(*__y, *__x))       // if x > y\n        {\n            swap(*__x, *__y);      // x < y && y <= z\n            __r = 2;\n        }\n        return __r;                // x <= y && y < z\n    }\n    if (__c(*__z, *__y))           // x > y, if y > z\n    {\n        swap(*__x, *__z);          // x < y && y < z\n        __r = 1;\n        return __r;\n    }\n    swap(*__x, *__y);              // x > y && y <= z\n    __r = 1;                       // x < y && x <= z\n    if (__c(*__z, *__y))           // if y > z\n    {\n        swap(*__y, *__z);          // x <= y && y < z\n        __r = 2;\n    }\n    return __r;\n}                                  // x <= y && y <= z\n\n// stable, 3-6 compares, 0-5 swaps\n\ntemplate <class _Compare, class _ForwardIterator>\nunsigned\n__sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,\n            _ForwardIterator __x4, _Compare __c)\n{\n    unsigned __r = __sort3<_Compare>(__x1, __x2, __x3, __c);\n    if (__c(*__x4, *__x3))\n    {\n        swap(*__x3, *__x4);\n        ++__r;\n        if (__c(*__x3, *__x2))\n        {\n            swap(*__x2, *__x3);\n            ++__r;\n            if (__c(*__x2, *__x1))\n            {\n                swap(*__x1, *__x2);\n                ++__r;\n            }\n        }\n    }\n    return __r;\n}\n\n// stable, 4-10 compares, 0-9 swaps\n\ntemplate <class _Compare, class _ForwardIterator>\nunsigned\n__sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,\n            _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c)\n{\n    unsigned __r = __sort4<_Compare>(__x1, __x2, __x3, __x4, __c);\n    if (__c(*__x5, *__x4))\n    {\n        swap(*__x4, *__x5);\n        ++__r;\n        if (__c(*__x4, *__x3))\n        {\n            swap(*__x3, *__x4);\n            ++__r;\n            if (__c(*__x3, *__x2))\n            {\n                swap(*__x2, *__x3);\n                ++__r;\n                if (__c(*__x2, *__x1))\n                {\n                    swap(*__x1, *__x2);\n                    ++__r;\n                }\n            }\n        }\n    }\n    return __r;\n}\n\n// Assumes size > 0\ntemplate <class _Compare, class _BirdirectionalIterator>\nvoid\n__selection_sort(_BirdirectionalIterator __first, _BirdirectionalIterator __last, _Compare __comp)\n{\n    _BirdirectionalIterator __lm1 = __last;\n    for (--__lm1; __first != __lm1; ++__first)\n    {\n        _BirdirectionalIterator __i = _VSTD::min_element<_BirdirectionalIterator,\n                                                        typename add_lvalue_reference<_Compare>::type>\n                                                       (__first, __last, __comp);\n        if (__i != __first)\n            swap(*__first, *__i);\n    }\n}\n\ntemplate <class _Compare, class _BirdirectionalIterator>\nvoid\n__insertion_sort(_BirdirectionalIterator __first, _BirdirectionalIterator __last, _Compare __comp)\n{\n    typedef typename iterator_traits<_BirdirectionalIterator>::value_type value_type;\n    if (__first != __last)\n    {\n        _BirdirectionalIterator __i = __first;\n        for (++__i; __i != __last; ++__i)\n        {\n            _BirdirectionalIterator __j = __i;\n            value_type __t(_VSTD::move(*__j));\n            for (_BirdirectionalIterator __k = __i; __k != __first && __comp(__t,  *--__k); --__j)\n                *__j = _VSTD::move(*__k);\n            *__j = _VSTD::move(__t);\n        }\n    }\n}\n\ntemplate <class _Compare, class _RandomAccessIterator>\nvoid\n__insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)\n{\n    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;\n    _RandomAccessIterator __j = __first+2;\n    __sort3<_Compare>(__first, __first+1, __j, __comp);\n    for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i)\n    {\n        if (__comp(*__i, *__j))\n        {\n            value_type __t(_VSTD::move(*__i));\n            _RandomAccessIterator __k = __j;\n            __j = __i;\n            do\n            {\n                *__j = _VSTD::move(*__k);\n                __j = __k;\n            } while (__j != __first && __comp(__t, *--__k));\n            *__j = _VSTD::move(__t);\n        }\n        __j = __i;\n    }\n}\n\ntemplate <class _Compare, class _RandomAccessIterator>\nbool\n__insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)\n{\n    switch (__last - __first)\n    {\n    case 0:\n    case 1:\n        return true;\n    case 2:\n        if (__comp(*--__last, *__first))\n            swap(*__first, *__last);\n        return true;\n    case 3:\n        _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp);\n        return true;\n    case 4:\n        _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp);\n        return true;\n    case 5:\n        _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp);\n        return true;\n    }\n    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;\n    _RandomAccessIterator __j = __first+2;\n    __sort3<_Compare>(__first, __first+1, __j, __comp);\n    const unsigned __limit = 8;\n    unsigned __count = 0;\n    for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i)\n    {\n        if (__comp(*__i, *__j))\n        {\n            value_type __t(_VSTD::move(*__i));\n            _RandomAccessIterator __k = __j;\n            __j = __i;\n            do\n            {\n                *__j = _VSTD::move(*__k);\n                __j = __k;\n            } while (__j != __first && __comp(__t, *--__k));\n            *__j = _VSTD::move(__t);\n            if (++__count == __limit)\n                return ++__i == __last;\n        }\n        __j = __i;\n    }\n    return true;\n}\n\ntemplate <class _Compare, class _BirdirectionalIterator>\nvoid\n__insertion_sort_move(_BirdirectionalIterator __first1, _BirdirectionalIterator __last1,\n                      typename iterator_traits<_BirdirectionalIterator>::value_type* __first2, _Compare __comp)\n{\n    typedef typename iterator_traits<_BirdirectionalIterator>::value_type value_type;\n    if (__first1 != __last1)\n    {\n        __destruct_n __d(0);\n        unique_ptr<value_type, __destruct_n&> __h(__first2, __d);\n        value_type* __last2 = __first2;\n        ::new(__last2) value_type(_VSTD::move(*__first1));\n        __d.__incr((value_type*)0);\n        for (++__last2; ++__first1 != __last1; ++__last2)\n        {\n            value_type* __j2 = __last2;\n            value_type* __i2 = __j2;\n            if (__comp(*__first1, *--__i2))\n            {\n                ::new(__j2) value_type(_VSTD::move(*__i2));\n                __d.__incr((value_type*)0);\n                for (--__j2; __i2 != __first2 && __comp(*__first1,  *--__i2); --__j2)\n                    *__j2 = _VSTD::move(*__i2);\n                *__j2 = _VSTD::move(*__first1);\n            }\n            else\n            {\n                ::new(__j2) value_type(_VSTD::move(*__first1));\n                __d.__incr((value_type*)0);\n            }\n        }\n        __h.release();\n    }\n}\n\ntemplate <class _Compare, class _RandomAccessIterator>\nvoid\n__sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)\n{\n    // _Compare is known to be a reference type\n    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;\n    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;\n    const difference_type __limit = is_trivially_copy_constructible<value_type>::value &&\n                                    is_trivially_copy_assignable<value_type>::value ? 30 : 6;\n    while (true)\n    {\n    __restart:\n        difference_type __len = __last - __first;\n        switch (__len)\n        {\n        case 0:\n        case 1:\n            return;\n        case 2:\n            if (__comp(*--__last, *__first))\n                swap(*__first, *__last);\n            return;\n        case 3:\n            _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp);\n            return;\n        case 4:\n            _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp);\n            return;\n        case 5:\n            _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp);\n            return;\n        }\n        if (__len <= __limit)\n        {\n            _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp);\n            return;\n        }\n        // __len > 5\n        _RandomAccessIterator __m = __first;\n        _RandomAccessIterator __lm1 = __last;\n        --__lm1;\n        unsigned __n_swaps;\n        {\n        difference_type __delta;\n        if (__len >= 1000)\n        {\n            __delta = __len/2;\n            __m += __delta;\n            __delta /= 2;\n            __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m+__delta, __lm1, __comp);\n        }\n        else\n        {\n            __delta = __len/2;\n            __m += __delta;\n            __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp);\n        }\n        }\n        // *__m is median\n        // partition [__first, __m) < *__m and *__m <= [__m, __last)\n        // (this inhibits tossing elements equivalent to __m around unnecessarily)\n        _RandomAccessIterator __i = __first;\n        _RandomAccessIterator __j = __lm1;\n        // j points beyond range to be tested, *__m is known to be <= *__lm1\n        // The search going up is known to be guarded but the search coming down isn't.\n        // Prime the downward search with a guard.\n        if (!__comp(*__i, *__m))  // if *__first == *__m\n        {\n            // *__first == *__m, *__first doesn't go in first part\n            // manually guard downward moving __j against __i\n            while (true)\n            {\n                if (__i == --__j)\n                {\n                    // *__first == *__m, *__m <= all other elements\n                    // Parition instead into [__first, __i) == *__first and *__first < [__i, __last)\n                    ++__i;  // __first + 1\n                    __j = __last;\n                    if (!__comp(*__first, *--__j))  // we need a guard if *__first == *(__last-1)\n                    {\n                        while (true)\n                        {\n                            if (__i == __j)\n                                return;  // [__first, __last) all equivalent elements\n                            if (__comp(*__first, *__i))\n                            {\n                                swap(*__i, *__j);\n                                ++__n_swaps;\n                                ++__i;\n                                break;\n                            }\n                            ++__i;\n                        }\n                    }\n                    // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1\n                    if (__i == __j)\n                        return;\n                    while (true)\n                    {\n                        while (!__comp(*__first, *__i))\n                            ++__i;\n                        while (__comp(*__first, *--__j))\n                            ;\n                        if (__i >= __j)\n                            break;\n                        swap(*__i, *__j);\n                        ++__n_swaps;\n                        ++__i;\n                    }\n                    // [__first, __i) == *__first and *__first < [__i, __last)\n                    // The first part is sorted, sort the secod part\n                    // _VSTD::__sort<_Compare>(__i, __last, __comp);\n                    __first = __i;\n                    goto __restart;\n                }\n                if (__comp(*__j, *__m))\n                {\n                    swap(*__i, *__j);\n                    ++__n_swaps;\n                    break;  // found guard for downward moving __j, now use unguarded partition\n                }\n            }\n        }\n        // It is known that *__i < *__m\n        ++__i;\n        // j points beyond range to be tested, *__m is known to be <= *__lm1\n        // if not yet partitioned...\n        if (__i < __j)\n        {\n            // known that *(__i - 1) < *__m\n            // known that __i <= __m\n            while (true)\n            {\n                // __m still guards upward moving __i\n                while (__comp(*__i, *__m))\n                    ++__i;\n                // It is now known that a guard exists for downward moving __j\n                while (!__comp(*--__j, *__m))\n                    ;\n                if (__i > __j)\n                    break;\n                swap(*__i, *__j);\n                ++__n_swaps;\n                // It is known that __m != __j\n                // If __m just moved, follow it\n                if (__m == __i)\n                    __m = __j;\n                ++__i;\n            }\n        }\n        // [__first, __i) < *__m and *__m <= [__i, __last)\n        if (__i != __m && __comp(*__m, *__i))\n        {\n            swap(*__i, *__m);\n            ++__n_swaps;\n        }\n        // [__first, __i) < *__i and *__i <= [__i+1, __last)\n        // If we were given a perfect partition, see if insertion sort is quick...\n        if (__n_swaps == 0)\n        {\n            bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp);\n            if (_VSTD::__insertion_sort_incomplete<_Compare>(__i+1, __last, __comp))\n            {\n                if (__fs)\n                    return;\n                __last = __i;\n                continue;\n            }\n            else\n            {\n                if (__fs)\n                {\n                    __first = ++__i;\n                    continue;\n                }\n            }\n        }\n        // sort smaller range with recursive call and larger with tail recursion elimination\n        if (__i - __first < __last - __i)\n        {\n            _VSTD::__sort<_Compare>(__first, __i, __comp);\n            // _VSTD::__sort<_Compare>(__i+1, __last, __comp);\n            __first = ++__i;\n        }\n        else\n        {\n            _VSTD::__sort<_Compare>(__i+1, __last, __comp);\n            // _VSTD::__sort<_Compare>(__first, __i, __comp);\n            __last = __i;\n        }\n    }\n}\n\n// This forwarder keeps the top call and the recursive calls using the same instantiation, forcing a reference _Compare\ntemplate <class _RandomAccessIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    __sort<_Comp_ref>(__first, __last, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    __sort<_Comp_ref>(__first, __last, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _RandomAccessIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nsort(_RandomAccessIterator __first, _RandomAccessIterator __last)\n{\n    _VSTD::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nsort(_Tp** __first, _Tp** __last)\n{\n    _VSTD::sort((size_t*)__first, (size_t*)__last, __less<size_t>());\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nsort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last)\n{\n    _VSTD::sort(__first.base(), __last.base());\n}\n\ntemplate <class _Tp, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nsort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last, _Compare __comp)\n{\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    _VSTD::sort<_Tp*, _Comp_ref>(__first.base(), __last.base(), __comp);\n}\n\n#ifdef _LIBCPP_MSVC\n#pragma warning( push )\n#pragma warning( disable: 4231)\n#endif // _LIBCPP_MSVC\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))\n\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))\n\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&))\n#ifdef _LIBCPP_MSVC\n#pragma warning( pop )\n#endif  // _LIBCPP_MSVC\n\n// lower_bound\n\ntemplate <class _Compare, class _ForwardIterator, class _Tp>\n_ForwardIterator\n__lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)\n{\n    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;\n    difference_type __len = _VSTD::distance(__first, __last);\n    while (__len != 0)\n    {\n        difference_type __l2 = __len / 2;\n        _ForwardIterator __m = __first;\n        _VSTD::advance(__m, __l2);\n        if (__comp(*__m, __value_))\n        {\n            __first = ++__m;\n            __len -= __l2 + 1;\n        }\n        else\n            __len = __l2;\n    }\n    return __first;\n}\n\ntemplate <class _ForwardIterator, class _Tp, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator\nlower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return __lower_bound<_Comp_ref>(__first, __last, __value_, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return __lower_bound<_Comp_ref>(__first, __last, __value_, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _ForwardIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator\nlower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)\n{\n    return _VSTD::lower_bound(__first, __last, __value_,\n                             __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());\n}\n\n// upper_bound\n\ntemplate <class _Compare, class _ForwardIterator, class _Tp>\n_ForwardIterator\n__upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)\n{\n    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;\n    difference_type __len = _VSTD::distance(__first, __last);\n    while (__len != 0)\n    {\n        difference_type __l2 = __len / 2;\n        _ForwardIterator __m = __first;\n        _VSTD::advance(__m, __l2);\n        if (__comp(__value_, *__m))\n            __len = __l2;\n        else\n        {\n            __first = ++__m;\n            __len -= __l2 + 1;\n        }\n    }\n    return __first;\n}\n\ntemplate <class _ForwardIterator, class _Tp, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator\nupper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return __upper_bound<_Comp_ref>(__first, __last, __value_, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return __upper_bound<_Comp_ref>(__first, __last, __value_, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _ForwardIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator\nupper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)\n{\n    return _VSTD::upper_bound(__first, __last, __value_,\n                             __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>());\n}\n\n// equal_range\n\ntemplate <class _Compare, class _ForwardIterator, class _Tp>\npair<_ForwardIterator, _ForwardIterator>\n__equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)\n{\n    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;\n    difference_type __len = _VSTD::distance(__first, __last);\n    while (__len != 0)\n    {\n        difference_type __l2 = __len / 2;\n        _ForwardIterator __m = __first;\n        _VSTD::advance(__m, __l2);\n        if (__comp(*__m, __value_))\n        {\n            __first = ++__m;\n            __len -= __l2 + 1;\n        }\n        else if (__comp(__value_, *__m))\n        {\n            __last = __m;\n            __len = __l2;\n        }\n        else\n        {\n            _ForwardIterator __mp1 = __m;\n            return pair<_ForwardIterator, _ForwardIterator>\n                   (\n                      __lower_bound<_Compare>(__first, __m, __value_, __comp),\n                      __upper_bound<_Compare>(++__mp1, __last, __value_, __comp)\n                   );\n        }\n    }\n    return pair<_ForwardIterator, _ForwardIterator>(__first, __first);\n}\n\ntemplate <class _ForwardIterator, class _Tp, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\npair<_ForwardIterator, _ForwardIterator>\nequal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return __equal_range<_Comp_ref>(__first, __last, __value_, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return __equal_range<_Comp_ref>(__first, __last, __value_, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _ForwardIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\npair<_ForwardIterator, _ForwardIterator>\nequal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)\n{\n    return _VSTD::equal_range(__first, __last, __value_,\n                             __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());\n}\n\n// binary_search\n\ntemplate <class _Compare, class _ForwardIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\n__binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)\n{\n    __first = __lower_bound<_Compare>(__first, __last, __value_, __comp);\n    return __first != __last && !__comp(__value_, *__first);\n}\n\ntemplate <class _ForwardIterator, class _Tp, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nbinary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return __binary_search<_Comp_ref>(__first, __last, __value_, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return __binary_search<_Comp_ref>(__first, __last, __value_, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _ForwardIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nbinary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)\n{\n    return _VSTD::binary_search(__first, __last, __value_,\n                             __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());\n}\n\n// merge\n\ntemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>\n_OutputIterator\n__merge(_InputIterator1 __first1, _InputIterator1 __last1,\n        _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)\n{\n    for (; __first1 != __last1; ++__result)\n    {\n        if (__first2 == __last2)\n            return _VSTD::copy(__first1, __last1, __result);\n        if (__comp(*__first2, *__first1))\n        {\n            *__result = *__first2;\n            ++__first2;\n        }\n        else\n        {\n            *__result = *__first1;\n            ++__first1;\n        }\n    }\n    return _VSTD::copy(__first2, __last2, __result);\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nmerge(_InputIterator1 __first1, _InputIterator1 __last1,\n      _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nmerge(_InputIterator1 __first1, _InputIterator1 __last1,\n      _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)\n{\n    typedef typename iterator_traits<_InputIterator1>::value_type __v1;\n    typedef typename iterator_traits<_InputIterator2>::value_type __v2;\n    return merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>());\n}\n\n// inplace_merge\n\ntemplate <class _Compare, class _InputIterator1, class _InputIterator2,\n          class _OutputIterator>\nvoid __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1,\n                          _InputIterator2 __first2, _InputIterator2 __last2,\n                          _OutputIterator __result, _Compare __comp)\n{\n    for (; __first1 != __last1; ++__result)\n    {\n        if (__first2 == __last2)\n        {\n            _VSTD::move(__first1, __last1, __result);\n            return;\n        }\n\n        if (__comp(*__first2, *__first1))\n        {\n            *__result = _VSTD::move(*__first2);\n            ++__first2;\n        }\n        else\n        {\n            *__result = _VSTD::move(*__first1);\n            ++__first1;\n        }\n    }\n    // __first2 through __last2 are already in the right spot.\n}\n\ntemplate <class _Compare, class _BidirectionalIterator>\nvoid\n__buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,\n                _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1,\n                                 typename iterator_traits<_BidirectionalIterator>::difference_type __len2,\n                typename iterator_traits<_BidirectionalIterator>::value_type* __buff)\n{\n    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;\n    __destruct_n __d(0);\n    unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);\n    if (__len1 <= __len2)\n    {\n        value_type* __p = __buff;\n        for (_BidirectionalIterator __i = __first; __i != __middle; __d.__incr((value_type*)0), (void) ++__i, ++__p)\n            ::new(__p) value_type(_VSTD::move(*__i));\n        __half_inplace_merge(__buff, __p, __middle, __last, __first, __comp);\n    }\n    else\n    {\n        value_type* __p = __buff;\n        for (_BidirectionalIterator __i = __middle; __i != __last; __d.__incr((value_type*)0), (void) ++__i, ++__p)\n            ::new(__p) value_type(_VSTD::move(*__i));\n        typedef reverse_iterator<_BidirectionalIterator> _RBi;\n        typedef reverse_iterator<value_type*> _Rv;\n        __half_inplace_merge(_Rv(__p), _Rv(__buff), \n                             _RBi(__middle), _RBi(__first),\n                             _RBi(__last), __negate<_Compare>(__comp));\n    }\n}\n\ntemplate <class _Compare, class _BidirectionalIterator>\nvoid\n__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,\n                _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1,\n                                 typename iterator_traits<_BidirectionalIterator>::difference_type __len2,\n                typename iterator_traits<_BidirectionalIterator>::value_type* __buff, ptrdiff_t __buff_size)\n{\n    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;\n    while (true)\n    {\n        // if __middle == __last, we're done\n        if (__len2 == 0)\n            return;\n        if (__len1 <= __buff_size || __len2 <= __buff_size)\n            return __buffered_inplace_merge<_Compare>\n                   (__first, __middle, __last, __comp, __len1, __len2, __buff);\n        // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0\n        for (; true; ++__first, (void) --__len1)\n        {\n            if (__len1 == 0)\n                return;\n            if (__comp(*__middle, *__first))\n                break;\n        }\n        // __first < __middle < __last\n        // *__first > *__middle\n        // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that\n        //     all elements in:\n        //         [__first, __m1)  <= [__middle, __m2)\n        //         [__middle, __m2) <  [__m1, __middle)\n        //         [__m1, __middle) <= [__m2, __last)\n        //     and __m1 or __m2 is in the middle of its range\n        _BidirectionalIterator __m1;  // \"median\" of [__first, __middle)\n        _BidirectionalIterator __m2;  // \"median\" of [__middle, __last)\n        difference_type __len11;      // distance(__first, __m1)\n        difference_type __len21;      // distance(__middle, __m2)\n        // binary search smaller range\n        if (__len1 < __len2)\n        {   // __len >= 1, __len2 >= 2\n            __len21 = __len2 / 2;\n            __m2 = __middle;\n            _VSTD::advance(__m2, __len21);\n            __m1 = __upper_bound<_Compare>(__first, __middle, *__m2, __comp);\n            __len11 = _VSTD::distance(__first, __m1);\n        }\n        else\n        {\n            if (__len1 == 1)\n            {   // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1\n                // It is known *__first > *__middle\n                swap(*__first, *__middle);\n                return;\n            }\n            // __len1 >= 2, __len2 >= 1\n            __len11 = __len1 / 2;\n            __m1 = __first;\n            _VSTD::advance(__m1, __len11);\n            __m2 = __lower_bound<_Compare>(__middle, __last, *__m1, __comp);\n            __len21 = _VSTD::distance(__middle, __m2);\n        }\n        difference_type __len12 = __len1 - __len11;  // distance(__m1, __middle)\n        difference_type __len22 = __len2 - __len21;  // distance(__m2, __last)\n        // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last)\n        // swap middle two partitions\n        __middle = _VSTD::rotate(__m1, __middle, __m2);\n        // __len12 and __len21 now have swapped meanings\n        // merge smaller range with recurisve call and larger with tail recursion elimination\n        if (__len11 + __len21 < __len12 + __len22)\n        {\n            __inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);\n//          __inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);\n            __first = __middle;\n            __middle = __m2;\n            __len1 = __len12;\n            __len2 = __len22;\n        }\n        else\n        {\n            __inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);\n//          __inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);\n            __last = __middle;\n            __middle = __m1;\n            __len1 = __len11;\n            __len2 = __len21;\n        }\n    }\n}\n\ntemplate <class _BidirectionalIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\ninplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,\n              _Compare __comp)\n{\n    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;\n    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;\n    difference_type __len1 = _VSTD::distance(__first, __middle);\n    difference_type __len2 = _VSTD::distance(__middle, __last);\n    difference_type __buf_size = _VSTD::min(__len1, __len2);\n    pair<value_type*, ptrdiff_t> __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size);\n    unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first);\n\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __c, __len1, __len2,\n                                            __buf.first, __buf.second);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2,\n                                            __buf.first, __buf.second);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _BidirectionalIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\ninplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last)\n{\n    _VSTD::inplace_merge(__first, __middle, __last,\n                        __less<typename iterator_traits<_BidirectionalIterator>::value_type>());\n}\n\n// stable_sort\n\ntemplate <class _Compare, class _InputIterator1, class _InputIterator2>\nvoid\n__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1,\n        _InputIterator2 __first2, _InputIterator2 __last2,\n        typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp)\n{\n    typedef typename iterator_traits<_InputIterator1>::value_type value_type;\n    __destruct_n __d(0);\n    unique_ptr<value_type, __destruct_n&> __h(__result, __d);\n    for (; true; ++__result)\n    {\n        if (__first1 == __last1)\n        {\n            for (; __first2 != __last2; ++__first2, ++__result, __d.__incr((value_type*)0))\n                ::new (__result) value_type(_VSTD::move(*__first2));\n            __h.release();\n            return;\n        }\n        if (__first2 == __last2)\n        {\n            for (; __first1 != __last1; ++__first1, ++__result, __d.__incr((value_type*)0))\n                ::new (__result) value_type(_VSTD::move(*__first1));\n            __h.release();\n            return;\n        }\n        if (__comp(*__first2, *__first1))\n        {\n            ::new (__result) value_type(_VSTD::move(*__first2));\n            __d.__incr((value_type*)0);\n            ++__first2;\n        }\n        else\n        {\n            ::new (__result) value_type(_VSTD::move(*__first1));\n            __d.__incr((value_type*)0);\n            ++__first1;\n        }\n    }\n}\n\ntemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>\nvoid\n__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1,\n        _InputIterator2 __first2, _InputIterator2 __last2,\n        _OutputIterator __result, _Compare __comp)\n{\n    for (; __first1 != __last1; ++__result)\n    {\n        if (__first2 == __last2)\n        {\n            for (; __first1 != __last1; ++__first1, ++__result)\n                *__result = _VSTD::move(*__first1);\n            return;\n        }\n        if (__comp(*__first2, *__first1))\n        {\n            *__result = _VSTD::move(*__first2);\n            ++__first2;\n        }\n        else\n        {\n            *__result = _VSTD::move(*__first1);\n            ++__first1;\n        }\n    }\n    for (; __first2 != __last2; ++__first2, ++__result)\n        *__result = _VSTD::move(*__first2);\n}\n\ntemplate <class _Compare, class _RandomAccessIterator>\nvoid\n__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,\n              typename iterator_traits<_RandomAccessIterator>::difference_type __len,\n              typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size);\n\ntemplate <class _Compare, class _RandomAccessIterator>\nvoid\n__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp,\n                   typename iterator_traits<_RandomAccessIterator>::difference_type __len,\n                   typename iterator_traits<_RandomAccessIterator>::value_type* __first2)\n{\n    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;\n    switch (__len)\n    {\n    case 0:\n        return;\n    case 1:\n        ::new(__first2) value_type(_VSTD::move(*__first1));\n        return;\n    case 2:\n       __destruct_n __d(0);\n        unique_ptr<value_type, __destruct_n&> __h2(__first2, __d);\n         if (__comp(*--__last1, *__first1))\n        {\n            ::new(__first2) value_type(_VSTD::move(*__last1));\n            __d.__incr((value_type*)0);\n            ++__first2;\n            ::new(__first2) value_type(_VSTD::move(*__first1));\n        }\n        else\n        {\n            ::new(__first2) value_type(_VSTD::move(*__first1));\n            __d.__incr((value_type*)0);\n            ++__first2;\n            ::new(__first2) value_type(_VSTD::move(*__last1));\n        }\n        __h2.release();\n        return;\n    }\n    if (__len <= 8)\n    {\n        __insertion_sort_move<_Compare>(__first1, __last1, __first2, __comp);\n        return;\n    }\n    typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2;\n    _RandomAccessIterator __m = __first1 + __l2;\n    __stable_sort<_Compare>(__first1, __m, __comp, __l2, __first2, __l2);\n    __stable_sort<_Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2);\n    __merge_move_construct<_Compare>(__first1, __m, __m, __last1, __first2, __comp);\n}\n\ntemplate <class _Tp>\nstruct __stable_sort_switch\n{\n    static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value;\n};\n\ntemplate <class _Compare, class _RandomAccessIterator>\nvoid\n__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,\n              typename iterator_traits<_RandomAccessIterator>::difference_type __len,\n              typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size)\n{\n    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;\n    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;\n    switch (__len)\n    {\n    case 0:\n    case 1:\n        return;\n    case 2:\n        if (__comp(*--__last, *__first))\n            swap(*__first, *__last);\n        return;\n    }\n    if (__len <= static_cast<difference_type>(__stable_sort_switch<value_type>::value))\n    {\n        __insertion_sort<_Compare>(__first, __last, __comp);\n        return;\n    }\n    typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2;\n    _RandomAccessIterator __m = __first + __l2;\n    if (__len <= __buff_size)\n    {\n        __destruct_n __d(0);\n        unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);\n        __stable_sort_move<_Compare>(__first, __m, __comp, __l2, __buff);\n        __d.__set(__l2, (value_type*)0);\n        __stable_sort_move<_Compare>(__m, __last, __comp, __len - __l2, __buff + __l2);\n        __d.__set(__len, (value_type*)0);\n        __merge_move_assign<_Compare>(__buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp);\n//         __merge<_Compare>(move_iterator<value_type*>(__buff),\n//                           move_iterator<value_type*>(__buff + __l2),\n//                           move_iterator<_RandomAccessIterator>(__buff + __l2),\n//                           move_iterator<_RandomAccessIterator>(__buff + __len),\n//                           __first, __comp);\n        return;\n    }\n    __stable_sort<_Compare>(__first, __m, __comp, __l2, __buff, __buff_size);\n    __stable_sort<_Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size);\n    __inplace_merge<_Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size);\n}\n\ntemplate <class _RandomAccessIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nstable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)\n{\n    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;\n    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;\n    difference_type __len = __last - __first;\n    pair<value_type*, ptrdiff_t> __buf(0, 0);\n    unique_ptr<value_type, __return_temporary_buffer> __h;\n    if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value))\n    {\n        __buf = _VSTD::get_temporary_buffer<value_type>(__len);\n        __h.reset(__buf.first);\n    }\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    __stable_sort<_Comp_ref>(__first, __last, __c, __len, __buf.first, __buf.second);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    __stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _RandomAccessIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nstable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last)\n{\n    _VSTD::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());\n}\n\n// is_heap_until\n\ntemplate <class _RandomAccessIterator, class _Compare>\n_RandomAccessIterator\nis_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)\n{\n    typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::difference_type difference_type;\n    difference_type __len = __last - __first;\n    difference_type __p = 0;\n    difference_type __c = 1;\n    _RandomAccessIterator __pp = __first;\n    while (__c < __len)\n    {\n        _RandomAccessIterator __cp = __first + __c;\n        if (__comp(*__pp, *__cp))\n            return __cp;\n        ++__c;\n        ++__cp;\n        if (__c == __len)\n            return __last;\n        if (__comp(*__pp, *__cp))\n            return __cp;\n        ++__p;\n        ++__pp;\n        __c = 2 * __p + 1;\n    }\n    return __last;\n}\n\ntemplate<class _RandomAccessIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_RandomAccessIterator\nis_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)\n{\n    return _VSTD::is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());\n}\n\n// is_heap\n\ntemplate <class _RandomAccessIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nis_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)\n{\n    return _VSTD::is_heap_until(__first, __last, __comp) == __last;\n}\n\ntemplate<class _RandomAccessIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nis_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)\n{\n    return _VSTD::is_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());\n}\n\n// push_heap\n\ntemplate <class _Compare, class _RandomAccessIterator>\nvoid\n__sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,\n          typename iterator_traits<_RandomAccessIterator>::difference_type __len)\n{\n    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;\n    if (__len > 1)\n    {\n        __len = (__len - 2) / 2;\n        _RandomAccessIterator __ptr = __first + __len;\n        if (__comp(*__ptr, *--__last))\n        {\n            value_type __t(_VSTD::move(*__last));\n            do\n            {\n                *__last = _VSTD::move(*__ptr);\n                __last = __ptr;\n                if (__len == 0)\n                    break;\n                __len = (__len - 1) / 2;\n                __ptr = __first + __len;\n            } while (__comp(*__ptr, __t));\n            *__last = _VSTD::move(__t);\n        }\n    }\n}\n\ntemplate <class _RandomAccessIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\npush_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    __sift_up<_Comp_ref>(__first, __last, __c, __last - __first);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    __sift_up<_Comp_ref>(__first, __last, __comp, __last - __first);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _RandomAccessIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\npush_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)\n{\n    _VSTD::push_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());\n}\n\n// pop_heap\n\ntemplate <class _Compare, class _RandomAccessIterator>\nvoid\n__sift_down(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,\n            typename iterator_traits<_RandomAccessIterator>::difference_type __len,\n            _RandomAccessIterator __start)\n{\n    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;\n    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;\n    // left-child of __start is at 2 * __start + 1\n    // right-child of __start is at 2 * __start + 2\n    difference_type __child = __start - __first;\n\n    if (__len < 2 || (__len - 2) / 2 < __child)\n        return;\n\n    __child = 2 * __child + 1;\n    _RandomAccessIterator __child_i = __first + __child;\n\n    if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) {\n        // right-child exists and is greater than left-child\n        ++__child_i;\n        ++__child;\n    }\n\n    // check if we are in heap-order\n    if (__comp(*__child_i, *__start))\n        // we are, __start is larger than it's largest child\n        return;\n\n    value_type __top(_VSTD::move(*__start));\n    do\n    {\n        // we are not in heap-order, swap the parent with it's largest child\n        *__start = _VSTD::move(*__child_i);\n        __start = __child_i;\n\n        if ((__len - 2) / 2 < __child)\n            break;\n\n        // recompute the child based off of the updated parent\n        __child = 2 * __child + 1;\n        __child_i = __first + __child;\n\n        if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) {\n            // right-child exists and is greater than left-child\n            ++__child_i;\n            ++__child;\n        }\n\n        // check if we are in heap-order\n    } while (!__comp(*__child_i, __top));\n    *__start = _VSTD::move(__top);\n}\n\ntemplate <class _Compare, class _RandomAccessIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,\n           typename iterator_traits<_RandomAccessIterator>::difference_type __len)\n{\n    if (__len > 1)\n    {\n        swap(*__first, *--__last);\n        __sift_down<_Compare>(__first, __last, __comp, __len - 1, __first);\n    }\n}\n\ntemplate <class _RandomAccessIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\npop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    __pop_heap<_Comp_ref>(__first, __last, __c, __last - __first);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    __pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _RandomAccessIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\npop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)\n{\n    _VSTD::pop_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());\n}\n\n// make_heap\n\ntemplate <class _Compare, class _RandomAccessIterator>\nvoid\n__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)\n{\n    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;\n    difference_type __n = __last - __first;\n    if (__n > 1)\n    {\n        // start from the first parent, there is no need to consider children\n        for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start)\n        {\n            __sift_down<_Compare>(__first, __last, __comp, __n, __first + __start);\n        }\n    }\n}\n\ntemplate <class _RandomAccessIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nmake_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    __make_heap<_Comp_ref>(__first, __last, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    __make_heap<_Comp_ref>(__first, __last, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _RandomAccessIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nmake_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)\n{\n    _VSTD::make_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());\n}\n\n// sort_heap\n\ntemplate <class _Compare, class _RandomAccessIterator>\nvoid\n__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)\n{\n    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;\n    for (difference_type __n = __last - __first; __n > 1; --__last, --__n)\n        __pop_heap<_Compare>(__first, __last, __comp, __n);\n}\n\ntemplate <class _RandomAccessIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nsort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    __sort_heap<_Comp_ref>(__first, __last, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    __sort_heap<_Comp_ref>(__first, __last, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _RandomAccessIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nsort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)\n{\n    _VSTD::sort_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());\n}\n\n// partial_sort\n\ntemplate <class _Compare, class _RandomAccessIterator>\nvoid\n__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,\n             _Compare __comp)\n{\n    __make_heap<_Compare>(__first, __middle, __comp);\n    typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first;\n    for (_RandomAccessIterator __i = __middle; __i != __last; ++__i)\n    {\n        if (__comp(*__i, *__first))\n        {\n            swap(*__i, *__first);\n            __sift_down<_Compare>(__first, __middle, __comp, __len, __first);\n        }\n    }\n    __sort_heap<_Compare>(__first, __middle, __comp);\n}\n\ntemplate <class _RandomAccessIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\npartial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,\n             _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    __partial_sort<_Comp_ref>(__first, __middle, __last, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    __partial_sort<_Comp_ref>(__first, __middle, __last, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _RandomAccessIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\npartial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)\n{\n    _VSTD::partial_sort(__first, __middle, __last,\n                       __less<typename iterator_traits<_RandomAccessIterator>::value_type>());\n}\n\n// partial_sort_copy\n\ntemplate <class _Compare, class _InputIterator, class _RandomAccessIterator>\n_RandomAccessIterator\n__partial_sort_copy(_InputIterator __first, _InputIterator __last,\n                    _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)\n{\n    _RandomAccessIterator __r = __result_first;\n    if (__r != __result_last)\n    {\n        for (; __first != __last && __r != __result_last; (void) ++__first, ++__r)\n            *__r = *__first;\n        __make_heap<_Compare>(__result_first, __r, __comp);\n        typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first;\n        for (; __first != __last; ++__first)\n            if (__comp(*__first, *__result_first))\n            {\n                *__result_first = *__first;\n                __sift_down<_Compare>(__result_first, __r, __comp, __len, __result_first);\n            }\n        __sort_heap<_Compare>(__result_first, __r, __comp);\n    }\n    return __r;\n}\n\ntemplate <class _InputIterator, class _RandomAccessIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\n_RandomAccessIterator\npartial_sort_copy(_InputIterator __first, _InputIterator __last,\n                  _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _InputIterator, class _RandomAccessIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_RandomAccessIterator\npartial_sort_copy(_InputIterator __first, _InputIterator __last,\n                  _RandomAccessIterator __result_first, _RandomAccessIterator __result_last)\n{\n    return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last,\n                                   __less<typename iterator_traits<_RandomAccessIterator>::value_type>());\n}\n\n// nth_element\n\ntemplate <class _Compare, class _RandomAccessIterator>\nvoid\n__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)\n{\n    // _Compare is known to be a reference type\n    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;\n    const difference_type __limit = 7;\n    while (true)\n    {\n    __restart:\n        if (__nth == __last)\n            return;\n        difference_type __len = __last - __first;\n        switch (__len)\n        {\n        case 0:\n        case 1:\n            return;\n        case 2:\n            if (__comp(*--__last, *__first))\n                swap(*__first, *__last);\n            return;\n        case 3:\n            {\n            _RandomAccessIterator __m = __first;\n            _VSTD::__sort3<_Compare>(__first, ++__m, --__last, __comp);\n            return;\n            }\n        }\n        if (__len <= __limit)\n        {\n            __selection_sort<_Compare>(__first, __last, __comp);\n            return;\n        }\n        // __len > __limit >= 3\n        _RandomAccessIterator __m = __first + __len/2;\n        _RandomAccessIterator __lm1 = __last;\n        unsigned __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, --__lm1, __comp);\n        // *__m is median\n        // partition [__first, __m) < *__m and *__m <= [__m, __last)\n        // (this inhibits tossing elements equivalent to __m around unnecessarily)\n        _RandomAccessIterator __i = __first;\n        _RandomAccessIterator __j = __lm1;\n        // j points beyond range to be tested, *__lm1 is known to be <= *__m\n        // The search going up is known to be guarded but the search coming down isn't.\n        // Prime the downward search with a guard.\n        if (!__comp(*__i, *__m))  // if *__first == *__m\n        {\n            // *__first == *__m, *__first doesn't go in first part\n            // manually guard downward moving __j against __i\n            while (true)\n            {\n                if (__i == --__j)\n                {\n                    // *__first == *__m, *__m <= all other elements\n                    // Parition instead into [__first, __i) == *__first and *__first < [__i, __last)\n                    ++__i;  // __first + 1\n                    __j = __last;\n                    if (!__comp(*__first, *--__j))  // we need a guard if *__first == *(__last-1)\n                    {\n                        while (true)\n                        {\n                            if (__i == __j)\n                                return;  // [__first, __last) all equivalent elements\n                            if (__comp(*__first, *__i))\n                            {\n                                swap(*__i, *__j);\n                                ++__n_swaps;\n                                ++__i;\n                                break;\n                            }\n                            ++__i;\n                        }\n                    }\n                    // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1\n                    if (__i == __j)\n                        return;\n                    while (true)\n                    {\n                        while (!__comp(*__first, *__i))\n                            ++__i;\n                        while (__comp(*__first, *--__j))\n                            ;\n                        if (__i >= __j)\n                            break;\n                        swap(*__i, *__j);\n                        ++__n_swaps;\n                        ++__i;\n                    }\n                    // [__first, __i) == *__first and *__first < [__i, __last)\n                    // The first part is sorted,\n                    if (__nth < __i)\n                        return;\n                    // __nth_element the secod part\n                    // __nth_element<_Compare>(__i, __nth, __last, __comp);\n                    __first = __i;\n                    goto __restart;\n                }\n                if (__comp(*__j, *__m))\n                {\n                    swap(*__i, *__j);\n                    ++__n_swaps;\n                    break;  // found guard for downward moving __j, now use unguarded partition\n                }\n            }\n        }\n        ++__i;\n        // j points beyond range to be tested, *__lm1 is known to be <= *__m\n        // if not yet partitioned...\n        if (__i < __j)\n        {\n            // known that *(__i - 1) < *__m\n            while (true)\n            {\n                // __m still guards upward moving __i\n                while (__comp(*__i, *__m))\n                    ++__i;\n                // It is now known that a guard exists for downward moving __j\n                while (!__comp(*--__j, *__m))\n                    ;\n                if (__i >= __j)\n                    break;\n                swap(*__i, *__j);\n                ++__n_swaps;\n                // It is known that __m != __j\n                // If __m just moved, follow it\n                if (__m == __i)\n                    __m = __j;\n                ++__i;\n            }\n        }\n        // [__first, __i) < *__m and *__m <= [__i, __last)\n        if (__i != __m && __comp(*__m, *__i))\n        {\n            swap(*__i, *__m);\n            ++__n_swaps;\n        }\n        // [__first, __i) < *__i and *__i <= [__i+1, __last)\n        if (__nth == __i)\n            return;\n        if (__n_swaps == 0)\n        {\n            // We were given a perfectly partitioned sequence.  Coincidence?\n            if (__nth < __i)\n            {\n                // Check for [__first, __i) already sorted\n                __j = __m = __first;\n                while (++__j != __i)\n                {\n                    if (__comp(*__j, *__m))\n                        // not yet sorted, so sort\n                        goto not_sorted;\n                    __m = __j;\n                }\n                // [__first, __i) sorted\n                return;\n            }\n            else\n            {\n                // Check for [__i, __last) already sorted\n                __j = __m = __i;\n                while (++__j != __last)\n                {\n                    if (__comp(*__j, *__m))\n                        // not yet sorted, so sort\n                        goto not_sorted;\n                    __m = __j;\n                }\n                // [__i, __last) sorted\n                return;\n            }\n        }\nnot_sorted:\n        // __nth_element on range containing __nth\n        if (__nth < __i)\n        {\n            // __nth_element<_Compare>(__first, __nth, __i, __comp);\n            __last = __i;\n        }\n        else\n        {\n            // __nth_element<_Compare>(__i+1, __nth, __last, __comp);\n            __first = ++__i;\n        }\n    }\n}\n\ntemplate <class _RandomAccessIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nnth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    __nth_element<_Comp_ref>(__first, __nth, __last, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    __nth_element<_Comp_ref>(__first, __nth, __last, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _RandomAccessIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nnth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last)\n{\n    _VSTD::nth_element(__first, __nth, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());\n}\n\n// includes\n\ntemplate <class _Compare, class _InputIterator1, class _InputIterator2>\nbool\n__includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,\n           _Compare __comp)\n{\n    for (; __first2 != __last2; ++__first1)\n    {\n        if (__first1 == __last1 || __comp(*__first2, *__first1))\n            return false;\n        if (!__comp(*__first1, *__first2))\n            ++__first2;\n    }\n    return true;\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nincludes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,\n         _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _InputIterator1, class _InputIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nincludes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2)\n{\n    return _VSTD::includes(__first1, __last1, __first2, __last2,\n                          __less<typename iterator_traits<_InputIterator1>::value_type,\n                                 typename iterator_traits<_InputIterator2>::value_type>());\n}\n\n// set_union\n\ntemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>\n_OutputIterator\n__set_union(_InputIterator1 __first1, _InputIterator1 __last1,\n            _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)\n{\n    for (; __first1 != __last1; ++__result)\n    {\n        if (__first2 == __last2)\n            return _VSTD::copy(__first1, __last1, __result);\n        if (__comp(*__first2, *__first1))\n        {\n            *__result = *__first2;\n            ++__first2;\n        }\n        else\n        {\n            *__result = *__first1;\n            if (!__comp(*__first1, *__first2))\n                ++__first2;\n            ++__first1;\n        }\n    }\n    return _VSTD::copy(__first2, __last2, __result);\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nset_union(_InputIterator1 __first1, _InputIterator1 __last1,\n          _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nset_union(_InputIterator1 __first1, _InputIterator1 __last1,\n          _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)\n{\n    return _VSTD::set_union(__first1, __last1, __first2, __last2, __result,\n                          __less<typename iterator_traits<_InputIterator1>::value_type,\n                                 typename iterator_traits<_InputIterator2>::value_type>());\n}\n\n// set_intersection\n\ntemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>\n_OutputIterator\n__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,\n                   _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)\n{\n    while (__first1 != __last1 && __first2 != __last2)\n    {\n        if (__comp(*__first1, *__first2))\n            ++__first1;\n        else\n        {\n            if (!__comp(*__first2, *__first1))\n            {\n                *__result = *__first1;\n                ++__result;\n                ++__first1;\n            }\n            ++__first2;\n        }\n    }\n    return __result;\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nset_intersection(_InputIterator1 __first1, _InputIterator1 __last1,\n                 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nset_intersection(_InputIterator1 __first1, _InputIterator1 __last1,\n                 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)\n{\n    return _VSTD::set_intersection(__first1, __last1, __first2, __last2, __result,\n                                  __less<typename iterator_traits<_InputIterator1>::value_type,\n                                         typename iterator_traits<_InputIterator2>::value_type>());\n}\n\n// set_difference\n\ntemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>\n_OutputIterator\n__set_difference(_InputIterator1 __first1, _InputIterator1 __last1,\n                 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)\n{\n    while (__first1 != __last1)\n    {\n        if (__first2 == __last2)\n            return _VSTD::copy(__first1, __last1, __result);\n        if (__comp(*__first1, *__first2))\n        {\n            *__result = *__first1;\n            ++__result;\n            ++__first1;\n        }\n        else\n        {\n            if (!__comp(*__first2, *__first1))\n                ++__first1;\n            ++__first2;\n        }\n    }\n    return __result;\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nset_difference(_InputIterator1 __first1, _InputIterator1 __last1,\n               _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nset_difference(_InputIterator1 __first1, _InputIterator1 __last1,\n               _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)\n{\n    return _VSTD::set_difference(__first1, __last1, __first2, __last2, __result,\n                                __less<typename iterator_traits<_InputIterator1>::value_type,\n                                       typename iterator_traits<_InputIterator2>::value_type>());\n}\n\n// set_symmetric_difference\n\ntemplate <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>\n_OutputIterator\n__set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,\n                           _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)\n{\n    while (__first1 != __last1)\n    {\n        if (__first2 == __last2)\n            return _VSTD::copy(__first1, __last1, __result);\n        if (__comp(*__first1, *__first2))\n        {\n            *__result = *__first1;\n            ++__result;\n            ++__first1;\n        }\n        else\n        {\n            if (__comp(*__first2, *__first1))\n            {\n                *__result = *__first2;\n                ++__result;\n            }\n            else\n                ++__first1;\n            ++__first2;\n        }\n    }\n    return _VSTD::copy(__first2, __last2, __result);\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nset_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,\n                         _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nset_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,\n                         _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)\n{\n    return _VSTD::set_symmetric_difference(__first1, __last1, __first2, __last2, __result,\n                                          __less<typename iterator_traits<_InputIterator1>::value_type,\n                                                 typename iterator_traits<_InputIterator2>::value_type>());\n}\n\n// lexicographical_compare\n\ntemplate <class _Compare, class _InputIterator1, class _InputIterator2>\nbool\n__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,\n                          _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)\n{\n    for (; __first2 != __last2; ++__first1, (void) ++__first2)\n    {\n        if (__first1 == __last1 || __comp(*__first1, *__first2))\n            return true;\n        if (__comp(*__first2, *__first1))\n            return false;\n    }\n    return false;\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nlexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,\n                        _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _InputIterator1, class _InputIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nlexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,\n                        _InputIterator2 __first2, _InputIterator2 __last2)\n{\n    return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2,\n                                         __less<typename iterator_traits<_InputIterator1>::value_type,\n                                                typename iterator_traits<_InputIterator2>::value_type>());\n}\n\n// next_permutation\n\ntemplate <class _Compare, class _BidirectionalIterator>\nbool\n__next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)\n{\n    _BidirectionalIterator __i = __last;\n    if (__first == __last || __first == --__i)\n        return false;\n    while (true)\n    {\n        _BidirectionalIterator __ip1 = __i;\n        if (__comp(*--__i, *__ip1))\n        {\n            _BidirectionalIterator __j = __last;\n            while (!__comp(*__i, *--__j))\n                ;\n            swap(*__i, *__j);\n            _VSTD::reverse(__ip1, __last);\n            return true;\n        }\n        if (__i == __first)\n        {\n            _VSTD::reverse(__first, __last);\n            return false;\n        }\n    }\n}\n\ntemplate <class _BidirectionalIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nnext_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return __next_permutation<_Comp_ref>(__first, __last, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return __next_permutation<_Comp_ref>(__first, __last, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _BidirectionalIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nnext_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)\n{\n    return _VSTD::next_permutation(__first, __last,\n                                  __less<typename iterator_traits<_BidirectionalIterator>::value_type>());\n}\n\n// prev_permutation\n\ntemplate <class _Compare, class _BidirectionalIterator>\nbool\n__prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)\n{\n    _BidirectionalIterator __i = __last;\n    if (__first == __last || __first == --__i)\n        return false;\n    while (true)\n    {\n        _BidirectionalIterator __ip1 = __i;\n        if (__comp(*__ip1, *--__i))\n        {\n            _BidirectionalIterator __j = __last;\n            while (!__comp(*--__j, *__i))\n                ;\n            swap(*__i, *__j);\n            _VSTD::reverse(__ip1, __last);\n            return true;\n        }\n        if (__i == __first)\n        {\n            _VSTD::reverse(__first, __last);\n            return false;\n        }\n    }\n}\n\ntemplate <class _BidirectionalIterator, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nprev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)\n{\n#ifdef _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;\n    __debug_less<_Compare> __c(__comp);\n    return __prev_permutation<_Comp_ref>(__first, __last, __c);\n#else  // _LIBCPP_DEBUG\n    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;\n    return __prev_permutation<_Comp_ref>(__first, __last, __comp);\n#endif  // _LIBCPP_DEBUG\n}\n\ntemplate <class _BidirectionalIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nprev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)\n{\n    return _VSTD::prev_permutation(__first, __last,\n                                  __less<typename iterator_traits<_BidirectionalIterator>::value_type>());\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value,\n    _Tp\n>::type\n__rotate_left(_Tp __t, _Tp __n = 1)\n{\n    const unsigned __bits = static_cast<unsigned>(sizeof(_Tp) * __CHAR_BIT__ - 1);\n    __n &= __bits;\n    return static_cast<_Tp>((__t << __n) | (static_cast<typename make_unsigned<_Tp>::type>(__t) >> (__bits - __n)));\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value,\n    _Tp\n>::type\n__rotate_right(_Tp __t, _Tp __n = 1)\n{\n    const unsigned __bits = static_cast<unsigned>(sizeof(_Tp) * __CHAR_BIT__ - 1);\n    __n &= __bits;\n    return static_cast<_Tp>((__t << (__bits - __n)) | (static_cast<typename make_unsigned<_Tp>::type>(__t) >> __n));\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_ALGORITHM\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/array",
    "content": "// -*- C++ -*-\n//===---------------------------- array -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_ARRAY\n#define _LIBCPP_ARRAY\n\n/*\n    array synopsis\n\nnamespace std\n{\ntemplate <class T, size_t N >\nstruct array\n{\n    // types:\n    typedef T & reference;\n    typedef const T & const_reference;\n    typedef implementation defined iterator;\n    typedef implementation defined const_iterator;\n    typedef size_t size_type;\n    typedef ptrdiff_t difference_type;\n    typedef T value_type;\n    typedef T* pointer;\n    typedef const T* const_pointer;\n    typedef std::reverse_iterator<iterator> reverse_iterator;\n    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;\n\n    // No explicit construct/copy/destroy for aggregate type\n    void fill(const T& u);\n    void swap(array& a) noexcept(noexcept(swap(declval<T&>(), declval<T&>())));\n\n    // iterators:\n    iterator begin() noexcept;\n    const_iterator begin() const noexcept;\n    iterator end() noexcept;\n    const_iterator end() const noexcept;\n\n    reverse_iterator rbegin() noexcept;\n    const_reverse_iterator rbegin() const noexcept;\n    reverse_iterator rend() noexcept;\n    const_reverse_iterator rend() const noexcept;\n\n    const_iterator cbegin() const noexcept;\n    const_iterator cend() const noexcept;\n    const_reverse_iterator crbegin() const noexcept;\n    const_reverse_iterator crend() const noexcept;\n\n    // capacity:\n    constexpr size_type size() const noexcept;\n    constexpr size_type max_size() const noexcept;\n    constexpr bool empty() const noexcept;\n\n    // element access:\n    reference operator[](size_type n);\n    const_reference operator[](size_type n) const; // constexpr in C++14\n    const_reference at(size_type n) const; // constexpr in C++14\n    reference at(size_type n);\n\n    reference front();\n    const_reference front() const; // constexpr in C++14\n    reference back();\n    const_reference back() const; // constexpr in C++14\n\n    T* data() noexcept;\n    const T* data() const noexcept;\n};\n\ntemplate <class T, size_t N>\n  bool operator==(const array<T,N>& x, const array<T,N>& y);\ntemplate <class T, size_t N>\n  bool operator!=(const array<T,N>& x, const array<T,N>& y);\ntemplate <class T, size_t N>\n  bool operator<(const array<T,N>& x, const array<T,N>& y);\ntemplate <class T, size_t N>\n  bool operator>(const array<T,N>& x, const array<T,N>& y);\ntemplate <class T, size_t N>\n  bool operator<=(const array<T,N>& x, const array<T,N>& y);\ntemplate <class T, size_t N>\n  bool operator>=(const array<T,N>& x, const array<T,N>& y);\n\ntemplate <class T, size_t N >\n  void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y)));\n\ntemplate <class T> class tuple_size;\ntemplate <int I, class T> class tuple_element;\ntemplate <class T, size_t N> struct tuple_size<array<T, N>>;\ntemplate <int I, class T, size_t N> struct tuple_element<I, array<T, N>>;\ntemplate <int I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14\ntemplate <int I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14\ntemplate <int I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14\n\n}  // std\n\n*/\n\n#include <__config>\n#include <__tuple>\n#include <type_traits>\n#include <utility>\n#include <iterator>\n#include <algorithm>\n#include <stdexcept>\n#if defined(_LIBCPP_NO_EXCEPTIONS)\n    #include <cassert>\n#endif\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Tp, size_t _Size>\nstruct _LIBCPP_TYPE_VIS_ONLY array\n{\n    // types:\n    typedef array __self;\n    typedef _Tp                                   value_type;\n    typedef value_type&                           reference;\n    typedef const value_type&                     const_reference;\n    typedef value_type*                           iterator;\n    typedef const value_type*                     const_iterator;\n    typedef value_type*                           pointer;\n    typedef const value_type*                     const_pointer;\n    typedef size_t                                size_type;\n    typedef ptrdiff_t                             difference_type;\n    typedef std::reverse_iterator<iterator>       reverse_iterator;\n    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;\n\n    value_type __elems_[_Size > 0 ? _Size : 1];\n\n    // No explicit construct/copy/destroy for aggregate type\n    _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u)\n        {_VSTD::fill_n(__elems_, _Size, __u);}\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)\n        {_VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);}\n\n    // iterators:\n    _LIBCPP_INLINE_VISIBILITY\n    iterator begin() _NOEXCEPT {return iterator(__elems_);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + _Size);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n    reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cbegin() const _NOEXCEPT {return begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cend() const _NOEXCEPT {return end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crend() const _NOEXCEPT {return rend();}\n\n    // capacity:\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return _Size;}\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return _Size;}\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return _Size == 0;}\n\n    // element access:\n    _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n)             {return __elems_[__n];}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference operator[](size_type __n) const {return __elems_[__n];}\n    reference at(size_type __n);\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const;\n\n    _LIBCPP_INLINE_VISIBILITY reference front()             {return __elems_[0];}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const {return __elems_[0];}\n    _LIBCPP_INLINE_VISIBILITY reference back()              {return __elems_[_Size > 0 ? _Size-1 : 0];}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const  {return __elems_[_Size > 0 ? _Size-1 : 0];}\n\n    _LIBCPP_INLINE_VISIBILITY\n    value_type* data() _NOEXCEPT {return __elems_;}\n    _LIBCPP_INLINE_VISIBILITY\n    const value_type* data() const _NOEXCEPT {return __elems_;}\n};\n\ntemplate <class _Tp, size_t _Size>\ntypename array<_Tp, _Size>::reference\narray<_Tp, _Size>::at(size_type __n)\n{\n    if (__n >= _Size)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        throw out_of_range(\"array::at\");\n#else\n        assert(!\"array::at out_of_range\");\n#endif\n    return __elems_[__n];\n}\n\ntemplate <class _Tp, size_t _Size>\n_LIBCPP_CONSTEXPR_AFTER_CXX11\ntypename array<_Tp, _Size>::const_reference\narray<_Tp, _Size>::at(size_type __n) const\n{\n    if (__n >= _Size)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        throw out_of_range(\"array::at\");\n#else\n        assert(!\"array::at out_of_range\");\n#endif\n    return __elems_[__n];\n}\n\ntemplate <class _Tp, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)\n{\n    return _VSTD::equal(__x.__elems_, __x.__elems_ + _Size, __y.__elems_);\n}\n\ntemplate <class _Tp, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Tp, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)\n{\n    return _VSTD::lexicographical_compare(__x.__elems_, __x.__elems_ + _Size, __y.__elems_, __y.__elems_ + _Size);\n}\n\ntemplate <class _Tp, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _Tp, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _Tp, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _Tp, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_swappable<_Tp>::value,\n    void\n>::type\nswap(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)\n                                  _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Tp, size_t _Size>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_size<array<_Tp, _Size> >\n    : public integral_constant<size_t, _Size> {};\n\ntemplate <size_t _Ip, class _Tp, size_t _Size>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, array<_Tp, _Size> >\n{\npublic:\n    typedef _Tp type;\n};\n\ntemplate <size_t _Ip, class _Tp, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_Tp&\nget(array<_Tp, _Size>& __a) _NOEXCEPT\n{\n    static_assert(_Ip < _Size, \"Index out of bounds in std::get<> (std::array)\");\n    return __a.__elems_[_Ip];\n}\n\ntemplate <size_t _Ip, class _Tp, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nconst _Tp&\nget(const array<_Tp, _Size>& __a) _NOEXCEPT\n{\n    static_assert(_Ip < _Size, \"Index out of bounds in std::get<> (const std::array)\");\n    return __a.__elems_[_Ip];\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <size_t _Ip, class _Tp, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_Tp&&\nget(array<_Tp, _Size>&& __a) _NOEXCEPT\n{\n    static_assert(_Ip < _Size, \"Index out of bounds in std::get<> (std::array &&)\");\n    return _VSTD::move(__a.__elems_[_Ip]);\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_ARRAY\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/atomic",
    "content": "// -*- C++ -*-\n//===--------------------------- atomic -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_ATOMIC\n#define _LIBCPP_ATOMIC\n\n/*\n    atomic synopsis\n\nnamespace std\n{\n\n// order and consistency\n\ntypedef enum memory_order\n{\n    memory_order_relaxed,\n    memory_order_consume,  // load-consume\n    memory_order_acquire,  // load-acquire\n    memory_order_release,  // store-release\n    memory_order_acq_rel,  // store-release load-acquire\n    memory_order_seq_cst   // store-release load-acquire\n} memory_order;\n\ntemplate <class T> T kill_dependency(T y) noexcept;\n\n// lock-free property\n\n#define ATOMIC_BOOL_LOCK_FREE unspecified\n#define ATOMIC_CHAR_LOCK_FREE unspecified\n#define ATOMIC_CHAR16_T_LOCK_FREE unspecified\n#define ATOMIC_CHAR32_T_LOCK_FREE unspecified\n#define ATOMIC_WCHAR_T_LOCK_FREE unspecified\n#define ATOMIC_SHORT_LOCK_FREE unspecified\n#define ATOMIC_INT_LOCK_FREE unspecified\n#define ATOMIC_LONG_LOCK_FREE unspecified\n#define ATOMIC_LLONG_LOCK_FREE unspecified\n#define ATOMIC_POINTER_LOCK_FREE unspecified\n\n// flag type and operations\n\ntypedef struct atomic_flag\n{\n    bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;\n    bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;\n    void clear(memory_order m = memory_order_seq_cst) volatile noexcept;\n    void clear(memory_order m = memory_order_seq_cst) noexcept;\n    atomic_flag()  noexcept = default;\n    atomic_flag(const atomic_flag&) = delete;\n    atomic_flag& operator=(const atomic_flag&) = delete;\n    atomic_flag& operator=(const atomic_flag&) volatile = delete;\n} atomic_flag;\n\nbool\n    atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;\n\nbool\n    atomic_flag_test_and_set(atomic_flag* obj) noexcept;\n\nbool\n    atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,\n                                      memory_order m) noexcept;\n\nbool\n    atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;\n\nvoid\n    atomic_flag_clear(volatile atomic_flag* obj) noexcept;\n\nvoid\n    atomic_flag_clear(atomic_flag* obj) noexcept;\n\nvoid\n    atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;\n\nvoid\n    atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;\n\n#define ATOMIC_FLAG_INIT see below\n#define ATOMIC_VAR_INIT(value) see below\n\ntemplate <class T>\nstruct atomic\n{\n    bool is_lock_free() const volatile noexcept;\n    bool is_lock_free() const noexcept;\n    void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;\n    void store(T desr, memory_order m = memory_order_seq_cst) noexcept;\n    T load(memory_order m = memory_order_seq_cst) const volatile noexcept;\n    T load(memory_order m = memory_order_seq_cst) const noexcept;\n    operator T() const volatile noexcept;\n    operator T() const noexcept;\n    T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;\n    T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;\n    bool compare_exchange_weak(T& expc, T desr,\n                               memory_order s, memory_order f) volatile noexcept;\n    bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;\n    bool compare_exchange_strong(T& expc, T desr,\n                                 memory_order s, memory_order f) volatile noexcept;\n    bool compare_exchange_strong(T& expc, T desr,\n                                 memory_order s, memory_order f) noexcept;\n    bool compare_exchange_weak(T& expc, T desr,\n                               memory_order m = memory_order_seq_cst) volatile noexcept;\n    bool compare_exchange_weak(T& expc, T desr,\n                               memory_order m = memory_order_seq_cst) noexcept;\n    bool compare_exchange_strong(T& expc, T desr,\n                                memory_order m = memory_order_seq_cst) volatile noexcept;\n    bool compare_exchange_strong(T& expc, T desr,\n                                 memory_order m = memory_order_seq_cst) noexcept;\n\n    atomic() noexcept = default;\n    constexpr atomic(T desr) noexcept;\n    atomic(const atomic&) = delete;\n    atomic& operator=(const atomic&) = delete;\n    atomic& operator=(const atomic&) volatile = delete;\n    T operator=(T) volatile noexcept;\n    T operator=(T) noexcept;\n};\n\ntemplate <>\nstruct atomic<integral>\n{\n    bool is_lock_free() const volatile noexcept;\n    bool is_lock_free() const noexcept;\n    void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;\n    void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;\n    integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;\n    integral load(memory_order m = memory_order_seq_cst) const noexcept;\n    operator integral() const volatile noexcept;\n    operator integral() const noexcept;\n    integral exchange(integral desr,\n                      memory_order m = memory_order_seq_cst) volatile noexcept;\n    integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;\n    bool compare_exchange_weak(integral& expc, integral desr,\n                               memory_order s, memory_order f) volatile noexcept;\n    bool compare_exchange_weak(integral& expc, integral desr,\n                               memory_order s, memory_order f) noexcept;\n    bool compare_exchange_strong(integral& expc, integral desr,\n                                 memory_order s, memory_order f) volatile noexcept;\n    bool compare_exchange_strong(integral& expc, integral desr,\n                                 memory_order s, memory_order f) noexcept;\n    bool compare_exchange_weak(integral& expc, integral desr,\n                               memory_order m = memory_order_seq_cst) volatile noexcept;\n    bool compare_exchange_weak(integral& expc, integral desr,\n                               memory_order m = memory_order_seq_cst) noexcept;\n    bool compare_exchange_strong(integral& expc, integral desr,\n                                memory_order m = memory_order_seq_cst) volatile noexcept;\n    bool compare_exchange_strong(integral& expc, integral desr,\n                                 memory_order m = memory_order_seq_cst) noexcept;\n\n    integral\n        fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;\n    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;\n    integral\n        fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;\n    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;\n    integral\n        fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;\n    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;\n    integral\n        fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;\n    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;\n    integral\n        fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;\n    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;\n\n    atomic() noexcept = default;\n    constexpr atomic(integral desr) noexcept;\n    atomic(const atomic&) = delete;\n    atomic& operator=(const atomic&) = delete;\n    atomic& operator=(const atomic&) volatile = delete;\n    integral operator=(integral desr) volatile noexcept;\n    integral operator=(integral desr) noexcept;\n\n    integral operator++(int) volatile noexcept;\n    integral operator++(int) noexcept;\n    integral operator--(int) volatile noexcept;\n    integral operator--(int) noexcept;\n    integral operator++() volatile noexcept;\n    integral operator++() noexcept;\n    integral operator--() volatile noexcept;\n    integral operator--() noexcept;\n    integral operator+=(integral op) volatile noexcept;\n    integral operator+=(integral op) noexcept;\n    integral operator-=(integral op) volatile noexcept;\n    integral operator-=(integral op) noexcept;\n    integral operator&=(integral op) volatile noexcept;\n    integral operator&=(integral op) noexcept;\n    integral operator|=(integral op) volatile noexcept;\n    integral operator|=(integral op) noexcept;\n    integral operator^=(integral op) volatile noexcept;\n    integral operator^=(integral op) noexcept;\n};\n\ntemplate <class T>\nstruct atomic<T*>\n{\n    bool is_lock_free() const volatile noexcept;\n    bool is_lock_free() const noexcept;\n    void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;\n    void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;\n    T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;\n    T* load(memory_order m = memory_order_seq_cst) const noexcept;\n    operator T*() const volatile noexcept;\n    operator T*() const noexcept;\n    T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;\n    T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;\n    bool compare_exchange_weak(T*& expc, T* desr,\n                               memory_order s, memory_order f) volatile noexcept;\n    bool compare_exchange_weak(T*& expc, T* desr,\n                               memory_order s, memory_order f) noexcept;\n    bool compare_exchange_strong(T*& expc, T* desr,\n                                 memory_order s, memory_order f) volatile noexcept;\n    bool compare_exchange_strong(T*& expc, T* desr,\n                                 memory_order s, memory_order f) noexcept;\n    bool compare_exchange_weak(T*& expc, T* desr,\n                               memory_order m = memory_order_seq_cst) volatile noexcept;\n    bool compare_exchange_weak(T*& expc, T* desr,\n                               memory_order m = memory_order_seq_cst) noexcept;\n    bool compare_exchange_strong(T*& expc, T* desr,\n                                memory_order m = memory_order_seq_cst) volatile noexcept;\n    bool compare_exchange_strong(T*& expc, T* desr,\n                                 memory_order m = memory_order_seq_cst) noexcept;\n    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;\n    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;\n    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;\n    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;\n\n    atomic() noexcept = default;\n    constexpr atomic(T* desr) noexcept;\n    atomic(const atomic&) = delete;\n    atomic& operator=(const atomic&) = delete;\n    atomic& operator=(const atomic&) volatile = delete;\n\n    T* operator=(T*) volatile noexcept;\n    T* operator=(T*) noexcept;\n    T* operator++(int) volatile noexcept;\n    T* operator++(int) noexcept;\n    T* operator--(int) volatile noexcept;\n    T* operator--(int) noexcept;\n    T* operator++() volatile noexcept;\n    T* operator++() noexcept;\n    T* operator--() volatile noexcept;\n    T* operator--() noexcept;\n    T* operator+=(ptrdiff_t op) volatile noexcept;\n    T* operator+=(ptrdiff_t op) noexcept;\n    T* operator-=(ptrdiff_t op) volatile noexcept;\n    T* operator-=(ptrdiff_t op) noexcept;\n};\n\n\ntemplate <class T>\n    bool\n    atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;\n\ntemplate <class T>\n    bool\n    atomic_is_lock_free(const atomic<T>* obj) noexcept;\n\ntemplate <class T>\n    void\n    atomic_init(volatile atomic<T>* obj, T desr) noexcept;\n\ntemplate <class T>\n    void\n    atomic_init(atomic<T>* obj, T desr) noexcept;\n\ntemplate <class T>\n    void\n    atomic_store(volatile atomic<T>* obj, T desr) noexcept;\n\ntemplate <class T>\n    void\n    atomic_store(atomic<T>* obj, T desr) noexcept;\n\ntemplate <class T>\n    void\n    atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;\n\ntemplate <class T>\n    void\n    atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;\n\ntemplate <class T>\n    T\n    atomic_load(const volatile atomic<T>* obj) noexcept;\n\ntemplate <class T>\n    T\n    atomic_load(const atomic<T>* obj) noexcept;\n\ntemplate <class T>\n    T\n    atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;\n\ntemplate <class T>\n    T\n    atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;\n\ntemplate <class T>\n    T\n    atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;\n\ntemplate <class T>\n    T\n    atomic_exchange(atomic<T>* obj, T desr) noexcept;\n\ntemplate <class T>\n    T\n    atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;\n\ntemplate <class T>\n    T\n    atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;\n\ntemplate <class T>\n    bool\n    atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;\n\ntemplate <class T>\n    bool\n    atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;\n\ntemplate <class T>\n    bool\n    atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;\n\ntemplate <class T>\n    bool\n    atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;\n\ntemplate <class T>\n    bool\n    atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,\n                                          T desr,\n                                          memory_order s, memory_order f) noexcept;\n\ntemplate <class T>\n    bool\n    atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,\n                                          memory_order s, memory_order f) noexcept;\n\ntemplate <class T>\n    bool\n    atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,\n                                            T* expc, T desr,\n                                            memory_order s, memory_order f) noexcept;\n\ntemplate <class T>\n    bool\n    atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,\n                                            T desr,\n                                            memory_order s, memory_order f) noexcept;\n\ntemplate <class Integral>\n    Integral\n    atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;\n\ntemplate <class Integral>\n    Integral\n    atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;\n\ntemplate <class Integral>\n    Integral\n    atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,\n                              memory_order m) noexcept;\ntemplate <class Integral>\n    Integral\n    atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,\n                              memory_order m) noexcept;\ntemplate <class Integral>\n    Integral\n    atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;\n\ntemplate <class Integral>\n    Integral\n    atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;\n\ntemplate <class Integral>\n    Integral\n    atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,\n                              memory_order m) noexcept;\ntemplate <class Integral>\n    Integral\n    atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,\n                              memory_order m) noexcept;\ntemplate <class Integral>\n    Integral\n    atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;\n\ntemplate <class Integral>\n    Integral\n    atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;\n\ntemplate <class Integral>\n    Integral\n    atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,\n                              memory_order m) noexcept;\ntemplate <class Integral>\n    Integral\n    atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,\n                              memory_order m) noexcept;\ntemplate <class Integral>\n    Integral\n    atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;\n\ntemplate <class Integral>\n    Integral\n    atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;\n\ntemplate <class Integral>\n    Integral\n    atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,\n                             memory_order m) noexcept;\ntemplate <class Integral>\n    Integral\n    atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,\n                             memory_order m) noexcept;\ntemplate <class Integral>\n    Integral\n    atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;\n\ntemplate <class Integral>\n    Integral\n    atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;\n\ntemplate <class Integral>\n    Integral\n    atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,\n                              memory_order m) noexcept;\ntemplate <class Integral>\n    Integral\n    atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,\n                              memory_order m) noexcept;\n\ntemplate <class T>\n    T*\n    atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;\n\ntemplate <class T>\n    T*\n    atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;\n\ntemplate <class T>\n    T*\n    atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,\n                              memory_order m) noexcept;\ntemplate <class T>\n    T*\n    atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;\n\ntemplate <class T>\n    T*\n    atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;\n\ntemplate <class T>\n    T*\n    atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;\n\ntemplate <class T>\n    T*\n    atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,\n                              memory_order m) noexcept;\ntemplate <class T>\n    T*\n    atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;\n\n// Atomics for standard typedef types\n\ntypedef atomic<bool>               atomic_bool;\ntypedef atomic<char>               atomic_char;\ntypedef atomic<signed char>        atomic_schar;\ntypedef atomic<unsigned char>      atomic_uchar;\ntypedef atomic<short>              atomic_short;\ntypedef atomic<unsigned short>     atomic_ushort;\ntypedef atomic<int>                atomic_int;\ntypedef atomic<unsigned int>       atomic_uint;\ntypedef atomic<long>               atomic_long;\ntypedef atomic<unsigned long>      atomic_ulong;\ntypedef atomic<long long>          atomic_llong;\ntypedef atomic<unsigned long long> atomic_ullong;\ntypedef atomic<char16_t>           atomic_char16_t;\ntypedef atomic<char32_t>           atomic_char32_t;\ntypedef atomic<wchar_t>            atomic_wchar_t;\n\ntypedef atomic<int_least8_t>   atomic_int_least8_t;\ntypedef atomic<uint_least8_t>  atomic_uint_least8_t;\ntypedef atomic<int_least16_t>  atomic_int_least16_t;\ntypedef atomic<uint_least16_t> atomic_uint_least16_t;\ntypedef atomic<int_least32_t>  atomic_int_least32_t;\ntypedef atomic<uint_least32_t> atomic_uint_least32_t;\ntypedef atomic<int_least64_t>  atomic_int_least64_t;\ntypedef atomic<uint_least64_t> atomic_uint_least64_t;\n\ntypedef atomic<int_fast8_t>   atomic_int_fast8_t;\ntypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;\ntypedef atomic<int_fast16_t>  atomic_int_fast16_t;\ntypedef atomic<uint_fast16_t> atomic_uint_fast16_t;\ntypedef atomic<int_fast32_t>  atomic_int_fast32_t;\ntypedef atomic<uint_fast32_t> atomic_uint_fast32_t;\ntypedef atomic<int_fast64_t>  atomic_int_fast64_t;\ntypedef atomic<uint_fast64_t> atomic_uint_fast64_t;\n\ntypedef atomic<intptr_t>  atomic_intptr_t;\ntypedef atomic<uintptr_t> atomic_uintptr_t;\ntypedef atomic<size_t>    atomic_size_t;\ntypedef atomic<ptrdiff_t> atomic_ptrdiff_t;\ntypedef atomic<intmax_t>  atomic_intmax_t;\ntypedef atomic<uintmax_t> atomic_uintmax_t;\n\n// fences\n\nvoid atomic_thread_fence(memory_order m) noexcept;\nvoid atomic_signal_fence(memory_order m) noexcept;\n\n}  // std\n\n*/\n\n#include <__config>\n#include <cstddef>\n#include <cstdint>\n#include <type_traits>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#ifdef _LIBCPP_HAS_NO_THREADS\n#error <atomic> is not supported on this single threaded system\n#else // !_LIBCPP_HAS_NO_THREADS\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n#if !__has_feature(cxx_atomic) && _GNUC_VER < 407\n#error <atomic> is not implemented\n#else\n\ntypedef enum memory_order\n{\n    memory_order_relaxed, memory_order_consume, memory_order_acquire,\n    memory_order_release, memory_order_acq_rel, memory_order_seq_cst\n} memory_order;\n\n#if _GNUC_VER >= 407\nnamespace __gcc_atomic {\ntemplate <typename _Tp>\nstruct __gcc_atomic_t {\n  __gcc_atomic_t() _NOEXCEPT {}\n  _LIBCPP_CONSTEXPR explicit __gcc_atomic_t(_Tp value) _NOEXCEPT\n    : __a_value(value) {}\n  _Tp __a_value;\n};\n#define _Atomic(x) __gcc_atomic::__gcc_atomic_t<x>\n\ntemplate <typename _Tp> _Tp __create();\n\ntemplate <typename _Tp, typename _Td>\ntypename enable_if<sizeof(_Tp()->__a_value = __create<_Td>()), char>::type\n    __test_atomic_assignable(int);\ntemplate <typename _Tp, typename _Up>\n__two __test_atomic_assignable(...);\n\ntemplate <typename _Tp, typename _Td>\nstruct __can_assign {\n  static const bool value =\n      sizeof(__test_atomic_assignable<_Tp, _Td>(1)) == sizeof(char);\n};\n\nstatic inline constexpr int __to_gcc_order(memory_order __order) {\n  // Avoid switch statement to make this a constexpr.\n  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:\n         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:\n          (__order == memory_order_release ? __ATOMIC_RELEASE:\n           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:\n            (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:\n              __ATOMIC_CONSUME))));\n}\n\nstatic inline constexpr int __to_gcc_failure_order(memory_order __order) {\n  // Avoid switch statement to make this a constexpr.\n  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:\n         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:\n          (__order == memory_order_release ? __ATOMIC_RELAXED:\n           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:\n            (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:\n              __ATOMIC_CONSUME))));\n}\n\n} // namespace __gcc_atomic\n\ntemplate <typename _Tp>\nstatic inline\ntypename enable_if<\n    __gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value>::type\n__c11_atomic_init(volatile _Atomic(_Tp)* __a,  _Tp __val) {\n  __a->__a_value = __val;\n}\n\ntemplate <typename _Tp>\nstatic inline\ntypename enable_if<\n    !__gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value &&\n     __gcc_atomic::__can_assign<         _Atomic(_Tp)*, _Tp>::value>::type\n__c11_atomic_init(volatile _Atomic(_Tp)* __a,  _Tp __val) {\n  // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because\n  // the default operator= in an object is not volatile, a byte-by-byte copy\n  // is required.\n  volatile char* to = reinterpret_cast<volatile char*>(&__a->__a_value);\n  volatile char* end = to + sizeof(_Tp);\n  char* from = reinterpret_cast<char*>(&__val);\n  while (to != end) {\n    *to++ = *from++;\n  }\n}\n\ntemplate <typename _Tp>\nstatic inline void __c11_atomic_init(_Atomic(_Tp)* __a,  _Tp __val) {\n  __a->__a_value = __val;\n}\n\nstatic inline void __c11_atomic_thread_fence(memory_order __order) {\n  __atomic_thread_fence(__gcc_atomic::__to_gcc_order(__order));\n}\n\nstatic inline void __c11_atomic_signal_fence(memory_order __order) {\n  __atomic_signal_fence(__gcc_atomic::__to_gcc_order(__order));\n}\n\ntemplate <typename _Tp>\nstatic inline void __c11_atomic_store(volatile _Atomic(_Tp)* __a,  _Tp __val,\n                                      memory_order __order) {\n  return __atomic_store(&__a->__a_value, &__val,\n                        __gcc_atomic::__to_gcc_order(__order));\n}\n\ntemplate <typename _Tp>\nstatic inline void __c11_atomic_store(_Atomic(_Tp)* __a,  _Tp __val,\n                                      memory_order __order) {\n  __atomic_store(&__a->__a_value, &__val,\n                 __gcc_atomic::__to_gcc_order(__order));\n}\n\ntemplate <typename _Tp>\nstatic inline _Tp __c11_atomic_load(volatile _Atomic(_Tp)* __a,\n                                    memory_order __order) {\n  _Tp __ret;\n  __atomic_load(&__a->__a_value, &__ret,\n                __gcc_atomic::__to_gcc_order(__order));\n  return __ret;\n}\n\ntemplate <typename _Tp>\nstatic inline _Tp __c11_atomic_load(_Atomic(_Tp)* __a, memory_order __order) {\n  _Tp __ret;\n  __atomic_load(&__a->__a_value, &__ret,\n                __gcc_atomic::__to_gcc_order(__order));\n  return __ret;\n}\n\ntemplate <typename _Tp>\nstatic inline _Tp __c11_atomic_exchange(volatile _Atomic(_Tp)* __a,\n                                        _Tp __value, memory_order __order) {\n  _Tp __ret;\n  __atomic_exchange(&__a->__a_value, &__value, &__ret,\n                    __gcc_atomic::__to_gcc_order(__order));\n  return __ret;\n}\n\ntemplate <typename _Tp>\nstatic inline _Tp __c11_atomic_exchange(_Atomic(_Tp)* __a, _Tp __value,\n                                        memory_order __order) {\n  _Tp __ret;\n  __atomic_exchange(&__a->__a_value, &__value, &__ret,\n                    __gcc_atomic::__to_gcc_order(__order));\n  return __ret;\n}\n\ntemplate <typename _Tp>\nstatic inline bool __c11_atomic_compare_exchange_strong(\n    volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value,\n    memory_order __success, memory_order __failure) {\n  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,\n                                   false,\n                                   __gcc_atomic::__to_gcc_order(__success),\n                                   __gcc_atomic::__to_gcc_failure_order(__failure));\n}\n\ntemplate <typename _Tp>\nstatic inline bool __c11_atomic_compare_exchange_strong(\n    _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success,\n    memory_order __failure) {\n  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,\n                                   false,\n                                   __gcc_atomic::__to_gcc_order(__success),\n                                   __gcc_atomic::__to_gcc_failure_order(__failure));\n}\n\ntemplate <typename _Tp>\nstatic inline bool __c11_atomic_compare_exchange_weak(\n    volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value,\n    memory_order __success, memory_order __failure) {\n  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,\n                                   true,\n                                   __gcc_atomic::__to_gcc_order(__success),\n                                   __gcc_atomic::__to_gcc_failure_order(__failure));\n}\n\ntemplate <typename _Tp>\nstatic inline bool __c11_atomic_compare_exchange_weak(\n    _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success,\n    memory_order __failure) {\n  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,\n                                   true,\n                                   __gcc_atomic::__to_gcc_order(__success),\n                                   __gcc_atomic::__to_gcc_failure_order(__failure));\n}\n\ntemplate <typename _Tp>\nstruct __skip_amt { enum {value = 1}; };\n\ntemplate <typename _Tp>\nstruct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };\n\n// FIXME: Haven't figured out what the spec says about using arrays with\n// atomic_fetch_add. Force a failure rather than creating bad behavior.\ntemplate <typename _Tp>\nstruct __skip_amt<_Tp[]> { };\ntemplate <typename _Tp, int n>\nstruct __skip_amt<_Tp[n]> { };\n\ntemplate <typename _Tp, typename _Td>\nstatic inline _Tp __c11_atomic_fetch_add(volatile _Atomic(_Tp)* __a,\n                                         _Td __delta, memory_order __order) {\n  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,\n                            __gcc_atomic::__to_gcc_order(__order));\n}\n\ntemplate <typename _Tp, typename _Td>\nstatic inline _Tp __c11_atomic_fetch_add(_Atomic(_Tp)* __a, _Td __delta,\n                                         memory_order __order) {\n  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,\n                            __gcc_atomic::__to_gcc_order(__order));\n}\n\ntemplate <typename _Tp, typename _Td>\nstatic inline _Tp __c11_atomic_fetch_sub(volatile _Atomic(_Tp)* __a,\n                                         _Td __delta, memory_order __order) {\n  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,\n                            __gcc_atomic::__to_gcc_order(__order));\n}\n\ntemplate <typename _Tp, typename _Td>\nstatic inline _Tp __c11_atomic_fetch_sub(_Atomic(_Tp)* __a, _Td __delta,\n                                         memory_order __order) {\n  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,\n                            __gcc_atomic::__to_gcc_order(__order));\n}\n\ntemplate <typename _Tp>\nstatic inline _Tp __c11_atomic_fetch_and(volatile _Atomic(_Tp)* __a,\n                                         _Tp __pattern, memory_order __order) {\n  return __atomic_fetch_and(&__a->__a_value, __pattern,\n                            __gcc_atomic::__to_gcc_order(__order));\n}\n\ntemplate <typename _Tp>\nstatic inline _Tp __c11_atomic_fetch_and(_Atomic(_Tp)* __a,\n                                         _Tp __pattern, memory_order __order) {\n  return __atomic_fetch_and(&__a->__a_value, __pattern,\n                            __gcc_atomic::__to_gcc_order(__order));\n}\n\ntemplate <typename _Tp>\nstatic inline _Tp __c11_atomic_fetch_or(volatile _Atomic(_Tp)* __a,\n                                        _Tp __pattern, memory_order __order) {\n  return __atomic_fetch_or(&__a->__a_value, __pattern,\n                           __gcc_atomic::__to_gcc_order(__order));\n}\n\ntemplate <typename _Tp>\nstatic inline _Tp __c11_atomic_fetch_or(_Atomic(_Tp)* __a, _Tp __pattern,\n                                        memory_order __order) {\n  return __atomic_fetch_or(&__a->__a_value, __pattern,\n                           __gcc_atomic::__to_gcc_order(__order));\n}\n\ntemplate <typename _Tp>\nstatic inline _Tp __c11_atomic_fetch_xor(volatile _Atomic(_Tp)* __a,\n                                         _Tp __pattern, memory_order __order) {\n  return __atomic_fetch_xor(&__a->__a_value, __pattern,\n                            __gcc_atomic::__to_gcc_order(__order));\n}\n\ntemplate <typename _Tp>\nstatic inline _Tp __c11_atomic_fetch_xor(_Atomic(_Tp)* __a, _Tp __pattern,\n                                         memory_order __order) {\n  return __atomic_fetch_xor(&__a->__a_value, __pattern,\n                            __gcc_atomic::__to_gcc_order(__order));\n}\n#endif // _GNUC_VER >= 407\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\nkill_dependency(_Tp __y) _NOEXCEPT\n{\n    return __y;\n}\n\n// general atomic<T>\n\ntemplate <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>\nstruct __atomic_base  // false\n{\n    mutable _Atomic(_Tp) __a_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool is_lock_free() const volatile _NOEXCEPT\n    {\n#if __has_feature(cxx_atomic)\n    return __c11_atomic_is_lock_free(sizeof(_Tp));\n#else\n    return __atomic_is_lock_free(sizeof(_Tp), 0);\n#endif\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    bool is_lock_free() const _NOEXCEPT\n        {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}\n    _LIBCPP_INLINE_VISIBILITY\n    void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT\n        {__c11_atomic_store(&__a_, __d, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT\n        {__c11_atomic_store(&__a_, __d, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT\n        {return __c11_atomic_load(&__a_, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT\n        {return __c11_atomic_load(&__a_, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    operator _Tp() const volatile _NOEXCEPT {return load();}\n    _LIBCPP_INLINE_VISIBILITY\n    operator _Tp() const _NOEXCEPT          {return load();}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT\n        {return __c11_atomic_exchange(&__a_, __d, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT\n        {return __c11_atomic_exchange(&__a_, __d, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool compare_exchange_weak(_Tp& __e, _Tp __d,\n                               memory_order __s, memory_order __f) volatile _NOEXCEPT\n        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool compare_exchange_weak(_Tp& __e, _Tp __d,\n                               memory_order __s, memory_order __f) _NOEXCEPT\n        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool compare_exchange_strong(_Tp& __e, _Tp __d,\n                                 memory_order __s, memory_order __f) volatile _NOEXCEPT\n        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool compare_exchange_strong(_Tp& __e, _Tp __d,\n                                 memory_order __s, memory_order __f) _NOEXCEPT\n        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool compare_exchange_weak(_Tp& __e, _Tp __d,\n                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT\n        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool compare_exchange_weak(_Tp& __e, _Tp __d,\n                               memory_order __m = memory_order_seq_cst) _NOEXCEPT\n        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool compare_exchange_strong(_Tp& __e, _Tp __d,\n                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT\n        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool compare_exchange_strong(_Tp& __e, _Tp __d,\n                                 memory_order __m = memory_order_seq_cst) _NOEXCEPT\n        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}\n\n    _LIBCPP_INLINE_VISIBILITY\n#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n    __atomic_base() _NOEXCEPT = default;\n#else\n    __atomic_base() _NOEXCEPT : __a_() {}\n#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}\n#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n    __atomic_base(const __atomic_base&) = delete;\n    __atomic_base& operator=(const __atomic_base&) = delete;\n    __atomic_base& operator=(const __atomic_base&) volatile = delete;\n#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS\nprivate:\n    __atomic_base(const __atomic_base&);\n    __atomic_base& operator=(const __atomic_base&);\n    __atomic_base& operator=(const __atomic_base&) volatile;\n#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n};\n\n// atomic<Integral>\n\ntemplate <class _Tp>\nstruct __atomic_base<_Tp, true>\n    : public __atomic_base<_Tp, false>\n{\n    typedef __atomic_base<_Tp, false> __base;\n    _LIBCPP_INLINE_VISIBILITY\n    __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT\n        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT\n        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT\n        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT\n        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT\n        {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT\n        {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT\n        {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT\n        {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT\n        {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT\n        {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}\n};\n\n// atomic<T>\n\ntemplate <class _Tp>\nstruct atomic\n    : public __atomic_base<_Tp>\n{\n    typedef __atomic_base<_Tp> __base;\n    _LIBCPP_INLINE_VISIBILITY\n    atomic() _NOEXCEPT _LIBCPP_DEFAULT\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator=(_Tp __d) volatile _NOEXCEPT\n        {__base::store(__d); return __d;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator=(_Tp __d) _NOEXCEPT\n        {__base::store(__d); return __d;}\n};\n\n// atomic<T*>\n\ntemplate <class _Tp>\nstruct atomic<_Tp*>\n    : public __atomic_base<_Tp*>\n{\n    typedef __atomic_base<_Tp*> __base;\n    _LIBCPP_INLINE_VISIBILITY\n    atomic() _NOEXCEPT _LIBCPP_DEFAULT\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* operator=(_Tp* __d) volatile _NOEXCEPT\n        {__base::store(__d); return __d;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* operator=(_Tp* __d) _NOEXCEPT\n        {__base::store(__d); return __d;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)\n                                                                        volatile _NOEXCEPT\n        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT\n        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)\n                                                                        volatile _NOEXCEPT\n        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT\n        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}\n};\n\n// atomic_is_lock_free\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT\n{\n    return __o->is_lock_free();\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT\n{\n    return __o->is_lock_free();\n}\n\n// atomic_init\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\natomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT\n{\n    __c11_atomic_init(&__o->__a_, __d);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\natomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT\n{\n    __c11_atomic_init(&__o->__a_, __d);\n}\n\n// atomic_store\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\natomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT\n{\n    __o->store(__d);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\natomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT\n{\n    __o->store(__d);\n}\n\n// atomic_store_explicit\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\natomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT\n{\n    __o->store(__d, __m);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\natomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT\n{\n    __o->store(__d, __m);\n}\n\n// atomic_load\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\natomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT\n{\n    return __o->load();\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\natomic_load(const atomic<_Tp>* __o) _NOEXCEPT\n{\n    return __o->load();\n}\n\n// atomic_load_explicit\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\natomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT\n{\n    return __o->load(__m);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\natomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT\n{\n    return __o->load(__m);\n}\n\n// atomic_exchange\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\natomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT\n{\n    return __o->exchange(__d);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\natomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT\n{\n    return __o->exchange(__d);\n}\n\n// atomic_exchange_explicit\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\natomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT\n{\n    return __o->exchange(__d, __m);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\natomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT\n{\n    return __o->exchange(__d, __m);\n}\n\n// atomic_compare_exchange_weak\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT\n{\n    return __o->compare_exchange_weak(*__e, __d);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT\n{\n    return __o->compare_exchange_weak(*__e, __d);\n}\n\n// atomic_compare_exchange_strong\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT\n{\n    return __o->compare_exchange_strong(*__e, __d);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT\n{\n    return __o->compare_exchange_strong(*__e, __d);\n}\n\n// atomic_compare_exchange_weak_explicit\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,\n                                      _Tp __d,\n                                      memory_order __s, memory_order __f) _NOEXCEPT\n{\n    return __o->compare_exchange_weak(*__e, __d, __s, __f);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,\n                                      memory_order __s, memory_order __f) _NOEXCEPT\n{\n    return __o->compare_exchange_weak(*__e, __d, __s, __f);\n}\n\n// atomic_compare_exchange_strong_explicit\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,\n                                        _Tp* __e, _Tp __d,\n                                        memory_order __s, memory_order __f) _NOEXCEPT\n{\n    return __o->compare_exchange_strong(*__e, __d, __s, __f);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,\n                                        _Tp __d,\n                                        memory_order __s, memory_order __f) _NOEXCEPT\n{\n    return __o->compare_exchange_strong(*__e, __d, __s, __f);\n}\n\n// atomic_fetch_add\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT\n{\n    return __o->fetch_add(__op);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT\n{\n    return __o->fetch_add(__op);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp*\natomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT\n{\n    return __o->fetch_add(__op);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp*\natomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT\n{\n    return __o->fetch_add(__op);\n}\n\n// atomic_fetch_add_explicit\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT\n{\n    return __o->fetch_add(__op, __m);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT\n{\n    return __o->fetch_add(__op, __m);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp*\natomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,\n                          memory_order __m) _NOEXCEPT\n{\n    return __o->fetch_add(__op, __m);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp*\natomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT\n{\n    return __o->fetch_add(__op, __m);\n}\n\n// atomic_fetch_sub\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT\n{\n    return __o->fetch_sub(__op);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT\n{\n    return __o->fetch_sub(__op);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp*\natomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT\n{\n    return __o->fetch_sub(__op);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp*\natomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT\n{\n    return __o->fetch_sub(__op);\n}\n\n// atomic_fetch_sub_explicit\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT\n{\n    return __o->fetch_sub(__op, __m);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT\n{\n    return __o->fetch_sub(__op, __m);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp*\natomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,\n                          memory_order __m) _NOEXCEPT\n{\n    return __o->fetch_sub(__op, __m);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp*\natomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT\n{\n    return __o->fetch_sub(__op, __m);\n}\n\n// atomic_fetch_and\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT\n{\n    return __o->fetch_and(__op);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT\n{\n    return __o->fetch_and(__op);\n}\n\n// atomic_fetch_and_explicit\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT\n{\n    return __o->fetch_and(__op, __m);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT\n{\n    return __o->fetch_and(__op, __m);\n}\n\n// atomic_fetch_or\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT\n{\n    return __o->fetch_or(__op);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT\n{\n    return __o->fetch_or(__op);\n}\n\n// atomic_fetch_or_explicit\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT\n{\n    return __o->fetch_or(__op, __m);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT\n{\n    return __o->fetch_or(__op, __m);\n}\n\n// atomic_fetch_xor\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT\n{\n    return __o->fetch_xor(__op);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT\n{\n    return __o->fetch_xor(__op);\n}\n\n// atomic_fetch_xor_explicit\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT\n{\n    return __o->fetch_xor(__op, __m);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,\n    _Tp\n>::type\natomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT\n{\n    return __o->fetch_xor(__op, __m);\n}\n\n// flag type and operations\n\ntypedef struct atomic_flag\n{\n    _Atomic(bool) __a_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT\n        {return __c11_atomic_exchange(&__a_, true, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT\n        {return __c11_atomic_exchange(&__a_, true, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT\n        {__c11_atomic_store(&__a_, false, __m);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT\n        {__c11_atomic_store(&__a_, false, __m);}\n\n    _LIBCPP_INLINE_VISIBILITY\n#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n    atomic_flag() _NOEXCEPT = default;\n#else\n    atomic_flag() _NOEXCEPT : __a_() {}\n#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n\n    _LIBCPP_INLINE_VISIBILITY\n    atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {}\n\n#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n    atomic_flag(const atomic_flag&) = delete;\n    atomic_flag& operator=(const atomic_flag&) = delete;\n    atomic_flag& operator=(const atomic_flag&) volatile = delete;\n#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS\nprivate:\n    atomic_flag(const atomic_flag&);\n    atomic_flag& operator=(const atomic_flag&);\n    atomic_flag& operator=(const atomic_flag&) volatile;\n#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n} atomic_flag;\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT\n{\n    return __o->test_and_set();\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT\n{\n    return __o->test_and_set();\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT\n{\n    return __o->test_and_set(__m);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT\n{\n    return __o->test_and_set(__m);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\natomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT\n{\n    __o->clear();\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\natomic_flag_clear(atomic_flag* __o) _NOEXCEPT\n{\n    __o->clear();\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\natomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT\n{\n    __o->clear(__m);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\natomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT\n{\n    __o->clear(__m);\n}\n\n// fences\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\natomic_thread_fence(memory_order __m) _NOEXCEPT\n{\n    __c11_atomic_thread_fence(__m);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\natomic_signal_fence(memory_order __m) _NOEXCEPT\n{\n    __c11_atomic_signal_fence(__m);\n}\n\n// Atomics for standard typedef types\n\ntypedef atomic<bool>               atomic_bool;\ntypedef atomic<char>               atomic_char;\ntypedef atomic<signed char>        atomic_schar;\ntypedef atomic<unsigned char>      atomic_uchar;\ntypedef atomic<short>              atomic_short;\ntypedef atomic<unsigned short>     atomic_ushort;\ntypedef atomic<int>                atomic_int;\ntypedef atomic<unsigned int>       atomic_uint;\ntypedef atomic<long>               atomic_long;\ntypedef atomic<unsigned long>      atomic_ulong;\ntypedef atomic<long long>          atomic_llong;\ntypedef atomic<unsigned long long> atomic_ullong;\ntypedef atomic<char16_t>           atomic_char16_t;\ntypedef atomic<char32_t>           atomic_char32_t;\ntypedef atomic<wchar_t>            atomic_wchar_t;\n\ntypedef atomic<int_least8_t>   atomic_int_least8_t;\ntypedef atomic<uint_least8_t>  atomic_uint_least8_t;\ntypedef atomic<int_least16_t>  atomic_int_least16_t;\ntypedef atomic<uint_least16_t> atomic_uint_least16_t;\ntypedef atomic<int_least32_t>  atomic_int_least32_t;\ntypedef atomic<uint_least32_t> atomic_uint_least32_t;\ntypedef atomic<int_least64_t>  atomic_int_least64_t;\ntypedef atomic<uint_least64_t> atomic_uint_least64_t;\n\ntypedef atomic<int_fast8_t>   atomic_int_fast8_t;\ntypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;\ntypedef atomic<int_fast16_t>  atomic_int_fast16_t;\ntypedef atomic<uint_fast16_t> atomic_uint_fast16_t;\ntypedef atomic<int_fast32_t>  atomic_int_fast32_t;\ntypedef atomic<uint_fast32_t> atomic_uint_fast32_t;\ntypedef atomic<int_fast64_t>  atomic_int_fast64_t;\ntypedef atomic<uint_fast64_t> atomic_uint_fast64_t;\n\ntypedef atomic<intptr_t>  atomic_intptr_t;\ntypedef atomic<uintptr_t> atomic_uintptr_t;\ntypedef atomic<size_t>    atomic_size_t;\ntypedef atomic<ptrdiff_t> atomic_ptrdiff_t;\ntypedef atomic<intmax_t>  atomic_intmax_t;\ntypedef atomic<uintmax_t> atomic_uintmax_t;\n\n#define ATOMIC_FLAG_INIT {false}\n#define ATOMIC_VAR_INIT(__v) {__v}\n\n// lock-free property\n\n#define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE\n#define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE\n#define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE\n#define ATOMIC_CHAR32_T_LOCK_FREE  __GCC_ATOMIC_CHAR32_T_LOCK_FREE\n#define ATOMIC_WCHAR_T_LOCK_FREE   __GCC_ATOMIC_WCHAR_T_LOCK_FREE\n#define ATOMIC_SHORT_LOCK_FREE     __GCC_ATOMIC_SHORT_LOCK_FREE\n#define ATOMIC_INT_LOCK_FREE       __GCC_ATOMIC_INT_LOCK_FREE\n#define ATOMIC_LONG_LOCK_FREE      __GCC_ATOMIC_LONG_LOCK_FREE\n#define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE\n#define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE\n\n#endif  //  !__has_feature(cxx_atomic)\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // !_LIBCPP_HAS_NO_THREADS\n\n#endif  // _LIBCPP_ATOMIC\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/bitset",
    "content": "// -*- C++ -*-\n//===---------------------------- bitset ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_BITSET\n#define _LIBCPP_BITSET\n\n/*\n    bitset synopsis\n\nnamespace std\n{\n\nnamespace std {\n\ntemplate <size_t N>\nclass bitset\n{\npublic:\n    // bit reference:\n    class reference\n    {\n        friend class bitset;\n        reference() noexcept;\n    public:\n        ~reference() noexcept;\n        reference& operator=(bool x) noexcept;           // for b[i] = x;\n        reference& operator=(const reference&) noexcept; // for b[i] = b[j];\n        bool operator~() const noexcept;                 // flips the bit\n        operator bool() const noexcept;                  // for x = b[i];\n        reference& flip() noexcept;                      // for b[i].flip();\n    };\n\n    // 23.3.5.1 constructors:\n    constexpr bitset() noexcept;\n    constexpr bitset(unsigned long long val) noexcept;\n    template <class charT>\n        explicit bitset(const charT* str,\n                        typename basic_string<charT>::size_type n = basic_string<charT>::npos,\n                        charT zero = charT('0'), charT one = charT('1'));\n    template<class charT, class traits, class Allocator>\n        explicit bitset(const basic_string<charT,traits,Allocator>& str,\n                        typename basic_string<charT,traits,Allocator>::size_type pos = 0,\n                        typename basic_string<charT,traits,Allocator>::size_type n =\n                                 basic_string<charT,traits,Allocator>::npos,\n                        charT zero = charT('0'), charT one = charT('1'));\n\n    // 23.3.5.2 bitset operations:\n    bitset& operator&=(const bitset& rhs) noexcept;\n    bitset& operator|=(const bitset& rhs) noexcept;\n    bitset& operator^=(const bitset& rhs) noexcept;\n    bitset& operator<<=(size_t pos) noexcept;\n    bitset& operator>>=(size_t pos) noexcept;\n    bitset& set() noexcept;\n    bitset& set(size_t pos, bool val = true);\n    bitset& reset() noexcept;\n    bitset& reset(size_t pos);\n    bitset operator~() const noexcept;\n    bitset& flip() noexcept;\n    bitset& flip(size_t pos);\n\n    // element access:\n    constexpr bool operator[](size_t pos) const; // for b[i];\n    reference operator[](size_t pos);            // for b[i];\n    unsigned long to_ulong() const;\n    unsigned long long to_ullong() const;\n    template <class charT, class traits, class Allocator>\n        basic_string<charT, traits, Allocator> to_string(charT zero = charT('0'), charT one = charT('1')) const;\n    template <class charT, class traits>\n        basic_string<charT, traits, allocator<charT> > to_string(charT zero = charT('0'), charT one = charT('1')) const;\n    template <class charT>\n        basic_string<charT, char_traits<charT>, allocator<charT> > to_string(charT zero = charT('0'), charT one = charT('1')) const;\n    basic_string<char, char_traits<char>, allocator<char> > to_string(char zero = '0', char one = '1') const;\n    size_t count() const noexcept;\n    constexpr size_t size() const noexcept;\n    bool operator==(const bitset& rhs) const noexcept;\n    bool operator!=(const bitset& rhs) const noexcept;\n    bool test(size_t pos) const;\n    bool all() const noexcept;\n    bool any() const noexcept;\n    bool none() const noexcept;\n    bitset operator<<(size_t pos) const noexcept;\n    bitset operator>>(size_t pos) const noexcept;\n};\n\n// 23.3.5.3 bitset operators:\ntemplate <size_t N>\nbitset<N> operator&(const bitset<N>&, const bitset<N>&) noexcept;\n\ntemplate <size_t N>\nbitset<N> operator|(const bitset<N>&, const bitset<N>&) noexcept;\n\ntemplate <size_t N>\nbitset<N> operator^(const bitset<N>&, const bitset<N>&) noexcept;\n\ntemplate <class charT, class traits, size_t N>\nbasic_istream<charT, traits>&\noperator>>(basic_istream<charT, traits>& is, bitset<N>& x);\n\ntemplate <class charT, class traits, size_t N>\nbasic_ostream<charT, traits>&\noperator<<(basic_ostream<charT, traits>& os, const bitset<N>& x);\n\ntemplate <size_t N> struct hash<std::bitset<N>>;\n\n}  // std\n\n*/\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#include <__config>\n#include <__bit_reference>\n#include <cstddef>\n#include <climits>\n#include <string>\n#include <stdexcept>\n#include <iosfwd>\n#include <__functional_base>\n#if defined(_LIBCPP_NO_EXCEPTIONS)\n    #include <cassert>\n#endif\n\n#include <__undef_min_max>\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <size_t _N_words, size_t _Size>\nclass __bitset;\n\ntemplate <size_t _N_words, size_t _Size>\nstruct __has_storage_type<__bitset<_N_words, _Size> >\n{\n    static const bool value = true;\n};\n\ntemplate <size_t _N_words, size_t _Size>\nclass __bitset\n{\npublic:\n    typedef ptrdiff_t              difference_type;\n    typedef size_t                 size_type;\n    typedef size_type              __storage_type;\nprotected:\n    typedef __bitset __self;\n    typedef       __storage_type*  __storage_pointer;\n    typedef const __storage_type*  __const_storage_pointer;\n    static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);\n\n    friend class __bit_reference<__bitset>;\n    friend class __bit_const_reference<__bitset>;\n    friend class __bit_iterator<__bitset, false>;\n    friend class __bit_iterator<__bitset, true>;\n    friend struct __bit_array<__bitset>;\n\n    __storage_type __first_[_N_words];\n\n    typedef __bit_reference<__bitset>                  reference;\n    typedef __bit_const_reference<__bitset>            const_reference;\n    typedef __bit_iterator<__bitset, false>            iterator;\n    typedef __bit_iterator<__bitset, true>             const_iterator;\n\n    _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;\n    explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t __pos) _NOEXCEPT\n        {return reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t __pos) const _NOEXCEPT\n        {return const_reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}\n    _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t __pos) _NOEXCEPT\n        {return iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}\n    _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t __pos) const _NOEXCEPT\n        {return const_iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}\n\n    void operator&=(const __bitset& __v) _NOEXCEPT;\n    void operator|=(const __bitset& __v) _NOEXCEPT;\n    void operator^=(const __bitset& __v) _NOEXCEPT;\n\n    void flip() _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY unsigned long to_ulong() const\n        {return to_ulong(integral_constant<bool, _Size < sizeof(unsigned long) * CHAR_BIT>());}\n    _LIBCPP_INLINE_VISIBILITY unsigned long long to_ullong() const\n        {return to_ullong(integral_constant<bool, _Size < sizeof(unsigned long long) * CHAR_BIT>());}\n\n    bool all() const _NOEXCEPT;\n    bool any() const _NOEXCEPT;\n    size_t __hash_code() const _NOEXCEPT;\nprivate:\n#ifdef _LIBCPP_HAS_NO_CONSTEXPR\n    void __init(unsigned long long __v, false_type) _NOEXCEPT;\n    void __init(unsigned long long __v, true_type) _NOEXCEPT;\n#endif  // _LIBCPP_HAS_NO_CONSTEXPR\n    unsigned long to_ulong(false_type) const;\n    unsigned long to_ulong(true_type) const;\n    unsigned long long to_ullong(false_type) const;\n    unsigned long long to_ullong(true_type) const;\n    unsigned long long to_ullong(true_type, false_type) const;\n    unsigned long long to_ullong(true_type, true_type) const;\n};\n\ntemplate <size_t _N_words, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\n__bitset<_N_words, _Size>::__bitset() _NOEXCEPT\n#ifndef _LIBCPP_HAS_NO_CONSTEXPR\n    : __first_{0}\n#endif\n{\n#ifdef _LIBCPP_HAS_NO_CONSTEXPR\n    _VSTD::fill_n(__first_, _N_words, __storage_type(0));\n#endif\n}\n\n#ifdef _LIBCPP_HAS_NO_CONSTEXPR\n\ntemplate <size_t _N_words, size_t _Size>\nvoid\n__bitset<_N_words, _Size>::__init(unsigned long long __v, false_type) _NOEXCEPT\n{\n    __storage_type __t[sizeof(unsigned long long) / sizeof(__storage_type)];\n    for (size_t __i = 0; __i < sizeof(__t)/sizeof(__t[0]); ++__i, __v >>= __bits_per_word)\n        __t[__i] = static_cast<__storage_type>(__v);\n    _VSTD::copy(__t, __t + sizeof(__t)/sizeof(__t[0]), __first_);\n    _VSTD::fill(__first_ + sizeof(__t)/sizeof(__t[0]), __first_ + sizeof(__first_)/sizeof(__first_[0]),\n               __storage_type(0));\n}\n\ntemplate <size_t _N_words, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__bitset<_N_words, _Size>::__init(unsigned long long __v, true_type) _NOEXCEPT\n{\n    __first_[0] = __v;\n    _VSTD::fill(__first_ + 1, __first_ + sizeof(__first_)/sizeof(__first_[0]), __storage_type(0));\n}\n\n#endif  // _LIBCPP_HAS_NO_CONSTEXPR\n\ntemplate <size_t _N_words, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\n__bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT\n#ifndef _LIBCPP_HAS_NO_CONSTEXPR\n#if __SIZEOF_SIZE_T__ == 8\n    : __first_{__v}\n#elif __SIZEOF_SIZE_T__ == 4\n    : __first_{__v, __v >> __bits_per_word}\n#else\n#error This constructor has not been ported to this platform\n#endif\n#endif\n{\n#ifdef _LIBCPP_HAS_NO_CONSTEXPR\n    __init(__v, integral_constant<bool, sizeof(unsigned long long) == sizeof(__storage_type)>());\n#endif\n}\n\ntemplate <size_t _N_words, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__bitset<_N_words, _Size>::operator&=(const __bitset& __v) _NOEXCEPT\n{\n    for (size_type __i = 0; __i < _N_words; ++__i)\n        __first_[__i] &= __v.__first_[__i];\n}\n\ntemplate <size_t _N_words, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__bitset<_N_words, _Size>::operator|=(const __bitset& __v) _NOEXCEPT\n{\n    for (size_type __i = 0; __i < _N_words; ++__i)\n        __first_[__i] |= __v.__first_[__i];\n}\n\ntemplate <size_t _N_words, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__bitset<_N_words, _Size>::operator^=(const __bitset& __v) _NOEXCEPT\n{\n    for (size_type __i = 0; __i < _N_words; ++__i)\n        __first_[__i] ^= __v.__first_[__i];\n}\n\ntemplate <size_t _N_words, size_t _Size>\nvoid\n__bitset<_N_words, _Size>::flip() _NOEXCEPT\n{\n    // do middle whole words\n    size_type __n = _Size;\n    __storage_pointer __p = __first_;\n    for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)\n        *__p = ~*__p;\n    // do last partial word\n    if (__n > 0)\n    {\n        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);\n        __storage_type __b = *__p & __m;\n        *__p &= ~__m;\n        *__p |= ~__b & __m;\n    }\n}\n\ntemplate <size_t _N_words, size_t _Size>\nunsigned long\n__bitset<_N_words, _Size>::to_ulong(false_type) const\n{\n    const_iterator __e = __make_iter(_Size);\n    const_iterator __i = _VSTD::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true);\n    if (__i != __e)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        throw overflow_error(\"bitset to_ulong overflow error\");\n#else\n        assert(!\"bitset to_ulong overflow error\");\n#endif\n    return __first_[0];\n}\n\ntemplate <size_t _N_words, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nunsigned long\n__bitset<_N_words, _Size>::to_ulong(true_type) const\n{\n    return __first_[0];\n}\n\ntemplate <size_t _N_words, size_t _Size>\nunsigned long long\n__bitset<_N_words, _Size>::to_ullong(false_type) const\n{\n    const_iterator __e = __make_iter(_Size);\n    const_iterator __i = _VSTD::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true);\n    if (__i != __e)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        throw overflow_error(\"bitset to_ullong overflow error\");\n#else\n        assert(!\"bitset to_ullong overflow error\");\n#endif\n    return to_ullong(true_type());\n}\n\ntemplate <size_t _N_words, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nunsigned long long\n__bitset<_N_words, _Size>::to_ullong(true_type) const\n{\n    return to_ullong(true_type(), integral_constant<bool, sizeof(__storage_type) < sizeof(unsigned long long)>());\n}\n\ntemplate <size_t _N_words, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nunsigned long long\n__bitset<_N_words, _Size>::to_ullong(true_type, false_type) const\n{\n    return __first_[0];\n}\n\ntemplate <size_t _N_words, size_t _Size>\nunsigned long long\n__bitset<_N_words, _Size>::to_ullong(true_type, true_type) const\n{\n    unsigned long long __r = __first_[0];\n    for (std::size_t __i = 1; __i < sizeof(unsigned long long) / sizeof(__storage_type); ++__i)\n        __r |= static_cast<unsigned long long>(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT);\n    return __r;\n}\n\ntemplate <size_t _N_words, size_t _Size>\nbool\n__bitset<_N_words, _Size>::all() const _NOEXCEPT\n{\n    // do middle whole words\n    size_type __n = _Size;\n    __const_storage_pointer __p = __first_;\n    for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)\n        if (~*__p)\n            return false;\n    // do last partial word\n    if (__n > 0)\n    {\n        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);\n        if (~*__p & __m)\n            return false;\n    }\n    return true;\n}\n\ntemplate <size_t _N_words, size_t _Size>\nbool\n__bitset<_N_words, _Size>::any() const _NOEXCEPT\n{\n    // do middle whole words\n    size_type __n = _Size;\n    __const_storage_pointer __p = __first_;\n    for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)\n        if (*__p)\n            return true;\n    // do last partial word\n    if (__n > 0)\n    {\n        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);\n        if (*__p & __m)\n            return true;\n    }\n    return false;\n}\n\ntemplate <size_t _N_words, size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nsize_t\n__bitset<_N_words, _Size>::__hash_code() const _NOEXCEPT\n{\n    size_t __h = 0;\n    for (size_type __i = 0; __i < _N_words; ++__i)\n        __h ^= __first_[__i];\n    return __h;\n}\n\ntemplate <size_t _Size>\nclass __bitset<1, _Size>\n{\npublic:\n    typedef ptrdiff_t              difference_type;\n    typedef size_t                 size_type;\n    typedef size_type              __storage_type;\nprotected:\n    typedef __bitset __self;\n    typedef       __storage_type*  __storage_pointer;\n    typedef const __storage_type*  __const_storage_pointer;\n    static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);\n\n    friend class __bit_reference<__bitset>;\n    friend class __bit_const_reference<__bitset>;\n    friend class __bit_iterator<__bitset, false>;\n    friend class __bit_iterator<__bitset, true>;\n    friend struct __bit_array<__bitset>;\n\n    __storage_type __first_;\n\n    typedef __bit_reference<__bitset>                  reference;\n    typedef __bit_const_reference<__bitset>            const_reference;\n    typedef __bit_iterator<__bitset, false>            iterator;\n    typedef __bit_iterator<__bitset, true>             const_iterator;\n\n    _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;\n    explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t __pos) _NOEXCEPT\n        {return reference(&__first_, __storage_type(1) << __pos);}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t __pos) const _NOEXCEPT\n        {return const_reference(&__first_, __storage_type(1) << __pos);}\n    _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t __pos) _NOEXCEPT\n        {return iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}\n    _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t __pos) const _NOEXCEPT\n        {return const_iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}\n\n    void operator&=(const __bitset& __v) _NOEXCEPT;\n    void operator|=(const __bitset& __v) _NOEXCEPT;\n    void operator^=(const __bitset& __v) _NOEXCEPT;\n\n    void flip() _NOEXCEPT;\n\n    unsigned long to_ulong() const;\n    unsigned long long to_ullong() const;\n\n    bool all() const _NOEXCEPT;\n    bool any() const _NOEXCEPT;\n\n    size_t __hash_code() const _NOEXCEPT;\n};\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\n__bitset<1, _Size>::__bitset() _NOEXCEPT\n    : __first_(0)\n{\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\n__bitset<1, _Size>::__bitset(unsigned long long __v) _NOEXCEPT\n    : __first_(static_cast<__storage_type>(__v))\n{\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__bitset<1, _Size>::operator&=(const __bitset& __v) _NOEXCEPT\n{\n    __first_ &= __v.__first_;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__bitset<1, _Size>::operator|=(const __bitset& __v) _NOEXCEPT\n{\n    __first_ |= __v.__first_;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__bitset<1, _Size>::operator^=(const __bitset& __v) _NOEXCEPT\n{\n    __first_ ^= __v.__first_;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__bitset<1, _Size>::flip() _NOEXCEPT\n{\n    __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);\n    __first_ = ~__first_;\n    __first_ &= __m;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nunsigned long\n__bitset<1, _Size>::to_ulong() const\n{\n    return __first_;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nunsigned long long\n__bitset<1, _Size>::to_ullong() const\n{\n    return __first_;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\n__bitset<1, _Size>::all() const _NOEXCEPT\n{\n    __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);\n    return !(~__first_ & __m);\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\n__bitset<1, _Size>::any() const _NOEXCEPT\n{\n    __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);\n    return __first_ & __m;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nsize_t\n__bitset<1, _Size>::__hash_code() const _NOEXCEPT\n{\n    return __first_;\n}\n\ntemplate <>\nclass __bitset<0, 0>\n{\npublic:\n    typedef ptrdiff_t              difference_type;\n    typedef size_t                 size_type;\n    typedef size_type              __storage_type;\nprotected:\n    typedef __bitset __self;\n    typedef       __storage_type*  __storage_pointer;\n    typedef const __storage_type*  __const_storage_pointer;\n    static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);\n\n    friend class __bit_reference<__bitset>;\n    friend class __bit_const_reference<__bitset>;\n    friend class __bit_iterator<__bitset, false>;\n    friend class __bit_iterator<__bitset, true>;\n    friend struct __bit_array<__bitset>;\n\n    typedef __bit_reference<__bitset>                  reference;\n    typedef __bit_const_reference<__bitset>            const_reference;\n    typedef __bit_iterator<__bitset, false>            iterator;\n    typedef __bit_iterator<__bitset, true>             const_iterator;\n\n    _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;\n    explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long) _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t) _NOEXCEPT\n        {return reference(0, 1);}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t) const _NOEXCEPT\n        {return const_reference(0, 1);}\n    _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t) _NOEXCEPT\n        {return iterator(0, 0);}\n    _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t) const _NOEXCEPT\n        {return const_iterator(0, 0);}\n\n    _LIBCPP_INLINE_VISIBILITY void operator&=(const __bitset&) _NOEXCEPT {}\n    _LIBCPP_INLINE_VISIBILITY void operator|=(const __bitset&) _NOEXCEPT {}\n    _LIBCPP_INLINE_VISIBILITY void operator^=(const __bitset&) _NOEXCEPT {}\n\n    _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {}\n\n    _LIBCPP_INLINE_VISIBILITY unsigned long to_ulong() const {return 0;}\n    _LIBCPP_INLINE_VISIBILITY unsigned long long to_ullong() const {return 0;}\n\n    _LIBCPP_INLINE_VISIBILITY bool all() const _NOEXCEPT {return true;}\n    _LIBCPP_INLINE_VISIBILITY bool any() const _NOEXCEPT {return false;}\n\n    _LIBCPP_INLINE_VISIBILITY size_t __hash_code() const _NOEXCEPT {return 0;}\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\n__bitset<0, 0>::__bitset() _NOEXCEPT\n{\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\n__bitset<0, 0>::__bitset(unsigned long long) _NOEXCEPT\n{\n}\n\ntemplate <size_t _Size> class _LIBCPP_TYPE_VIS_ONLY bitset;\ntemplate <size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY hash<bitset<_Size> >;\n\ntemplate <size_t _Size>\nclass _LIBCPP_TYPE_VIS_ONLY bitset\n    : private __bitset<_Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) * CHAR_BIT) + 1, _Size>\n{\npublic:\n    static const unsigned __n_words = _Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) * CHAR_BIT) + 1;\n    typedef __bitset<__n_words, _Size> base;\n\npublic:\n    typedef typename base::reference       reference;\n    typedef typename base::const_reference const_reference;\n\n    // 23.3.5.1 constructors:\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR\n        bitset(unsigned long long __v) _NOEXCEPT : base(__v) {}\n    template<class _CharT>\n        explicit bitset(const _CharT* __str,\n                        typename basic_string<_CharT>::size_type __n = basic_string<_CharT>::npos,\n                        _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));\n    template<class _CharT, class _Traits, class _Allocator>\n        explicit bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,\n                        typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos = 0,\n                        typename basic_string<_CharT,_Traits,_Allocator>::size_type __n =\n                                (basic_string<_CharT,_Traits,_Allocator>::npos),\n                        _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));\n\n    // 23.3.5.2 bitset operations:\n    bitset& operator&=(const bitset& __rhs) _NOEXCEPT;\n    bitset& operator|=(const bitset& __rhs) _NOEXCEPT;\n    bitset& operator^=(const bitset& __rhs) _NOEXCEPT;\n    bitset& operator<<=(size_t __pos) _NOEXCEPT;\n    bitset& operator>>=(size_t __pos) _NOEXCEPT;\n    bitset& set() _NOEXCEPT;\n    bitset& set(size_t __pos, bool __val = true);\n    bitset& reset() _NOEXCEPT;\n    bitset& reset(size_t __pos);\n    bitset  operator~() const _NOEXCEPT;\n    bitset& flip() _NOEXCEPT;\n    bitset& flip(size_t __pos);\n\n    // element access:\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR\n                              const_reference operator[](size_t __p) const {return base::__make_ref(__p);}\n    _LIBCPP_INLINE_VISIBILITY       reference operator[](size_t __p)       {return base::__make_ref(__p);}\n    unsigned long to_ulong() const;\n    unsigned long long to_ullong() const;\n    template <class _CharT, class _Traits, class _Allocator>\n        basic_string<_CharT, _Traits, _Allocator> to_string(_CharT __zero = _CharT('0'),\n                                                            _CharT __one = _CharT('1')) const;\n    template <class _CharT, class _Traits>\n        basic_string<_CharT, _Traits, allocator<_CharT> > to_string(_CharT __zero = _CharT('0'),\n                                                                    _CharT __one = _CharT('1')) const;\n    template <class _CharT>\n        basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> > to_string(_CharT __zero = _CharT('0'),\n                                                                                _CharT __one = _CharT('1')) const;\n    basic_string<char, char_traits<char>, allocator<char> > to_string(char __zero = '0',\n                                                                      char __one = '1') const;\n    size_t count() const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT {return _Size;}\n    bool operator==(const bitset& __rhs) const _NOEXCEPT;\n    bool operator!=(const bitset& __rhs) const _NOEXCEPT;\n    bool test(size_t __pos) const;\n    bool all() const _NOEXCEPT;\n    bool any() const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY bool none() const _NOEXCEPT {return !any();}\n    bitset operator<<(size_t __pos) const _NOEXCEPT;\n    bitset operator>>(size_t __pos) const _NOEXCEPT;\n\nprivate:\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t __hash_code() const _NOEXCEPT {return base::__hash_code();}\n\n    friend struct hash<bitset>;\n};\n\ntemplate <size_t _Size>\ntemplate<class _CharT>\nbitset<_Size>::bitset(const _CharT* __str,\n                      typename basic_string<_CharT>::size_type __n,\n                      _CharT __zero, _CharT __one)\n{\n    size_t __rlen = _VSTD::min(__n, char_traits<_CharT>::length(__str));\n    for (size_t __i = 0; __i < __rlen; ++__i)\n        if (__str[__i] != __zero && __str[__i] != __one)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            throw invalid_argument(\"bitset string ctor has invalid argument\");\n#else\n            assert(!\"bitset string ctor has invalid argument\");\n#endif\n    size_t _Mp = _VSTD::min(__rlen, _Size);\n    size_t __i = 0;\n    for (; __i < _Mp; ++__i)\n    {\n        _CharT __c = __str[_Mp - 1 - __i];\n        if (__c == __zero)\n            (*this)[__i] = false;\n        else\n            (*this)[__i] = true;\n    }\n    _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false);\n}\n\ntemplate <size_t _Size>\ntemplate<class _CharT, class _Traits, class _Allocator>\nbitset<_Size>::bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,\n       typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos,\n       typename basic_string<_CharT,_Traits,_Allocator>::size_type __n,\n       _CharT __zero, _CharT __one)\n{\n    if (__pos > __str.size())\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        throw out_of_range(\"bitset string pos out of range\");\n#else\n        assert(!\"bitset string pos out of range\");\n#endif\n    size_t __rlen = _VSTD::min(__n, __str.size() - __pos);\n    for (size_t __i = __pos; __i < __pos + __rlen; ++__i)\n        if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one))\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            throw invalid_argument(\"bitset string ctor has invalid argument\");\n#else\n            assert(!\"bitset string ctor has invalid argument\");\n#endif\n    size_t _Mp = _VSTD::min(__rlen, _Size);\n    size_t __i = 0;\n    for (; __i < _Mp; ++__i)\n    {\n        _CharT __c = __str[__pos + _Mp - 1 - __i];\n        if (_Traits::eq(__c, __zero))\n            (*this)[__i] = false;\n        else\n            (*this)[__i] = true;\n    }\n    _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false);\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbitset<_Size>&\nbitset<_Size>::operator&=(const bitset& __rhs) _NOEXCEPT\n{\n    base::operator&=(__rhs);\n    return *this;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbitset<_Size>&\nbitset<_Size>::operator|=(const bitset& __rhs) _NOEXCEPT\n{\n    base::operator|=(__rhs);\n    return *this;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbitset<_Size>&\nbitset<_Size>::operator^=(const bitset& __rhs) _NOEXCEPT\n{\n    base::operator^=(__rhs);\n    return *this;\n}\n\ntemplate <size_t _Size>\nbitset<_Size>&\nbitset<_Size>::operator<<=(size_t __pos) _NOEXCEPT\n{\n    __pos = _VSTD::min(__pos, _Size);\n    _VSTD::copy_backward(base::__make_iter(0), base::__make_iter(_Size - __pos), base::__make_iter(_Size));\n    _VSTD::fill_n(base::__make_iter(0), __pos, false);\n    return *this;\n}\n\ntemplate <size_t _Size>\nbitset<_Size>&\nbitset<_Size>::operator>>=(size_t __pos) _NOEXCEPT\n{\n    __pos = _VSTD::min(__pos, _Size);\n    _VSTD::copy(base::__make_iter(__pos), base::__make_iter(_Size), base::__make_iter(0));\n    _VSTD::fill_n(base::__make_iter(_Size - __pos), __pos, false);\n    return *this;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbitset<_Size>&\nbitset<_Size>::set() _NOEXCEPT\n{\n    _VSTD::fill_n(base::__make_iter(0), _Size, true);\n    return *this;\n}\n\ntemplate <size_t _Size>\nbitset<_Size>&\nbitset<_Size>::set(size_t __pos, bool __val)\n{\n    if (__pos >= _Size)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        throw out_of_range(\"bitset set argument out of range\");\n#else\n        assert(!\"bitset set argument out of range\");\n#endif\n    (*this)[__pos] = __val;\n    return *this;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbitset<_Size>&\nbitset<_Size>::reset() _NOEXCEPT\n{\n    _VSTD::fill_n(base::__make_iter(0), _Size, false);\n    return *this;\n}\n\ntemplate <size_t _Size>\nbitset<_Size>&\nbitset<_Size>::reset(size_t __pos)\n{\n    if (__pos >= _Size)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        throw out_of_range(\"bitset reset argument out of range\");\n#else\n        assert(!\"bitset reset argument out of range\");\n#endif\n    (*this)[__pos] = false;\n    return *this;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbitset<_Size>\nbitset<_Size>::operator~() const _NOEXCEPT\n{\n    bitset __x(*this);\n    __x.flip();\n    return __x;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbitset<_Size>&\nbitset<_Size>::flip() _NOEXCEPT\n{\n    base::flip();\n    return *this;\n}\n\ntemplate <size_t _Size>\nbitset<_Size>&\nbitset<_Size>::flip(size_t __pos)\n{\n    if (__pos >= _Size)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        throw out_of_range(\"bitset flip argument out of range\");\n#else\n        assert(!\"bitset flip argument out of range\");\n#endif\n    reference r = base::__make_ref(__pos);\n    r = ~r;\n    return *this;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nunsigned long\nbitset<_Size>::to_ulong() const\n{\n    return base::to_ulong();\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nunsigned long long\nbitset<_Size>::to_ullong() const\n{\n    return base::to_ullong();\n}\n\ntemplate <size_t _Size>\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>\nbitset<_Size>::to_string(_CharT __zero, _CharT __one) const\n{\n    basic_string<_CharT, _Traits, _Allocator> __r(_Size, __zero);\n    for (size_t __i = 0; __i < _Size; ++__i)\n    {\n        if ((*this)[__i])\n            __r[_Size - 1 - __i] = __one;\n    }\n    return __r;\n}\n\ntemplate <size_t _Size>\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, allocator<_CharT> >\nbitset<_Size>::to_string(_CharT __zero, _CharT __one) const\n{\n    return to_string<_CharT, _Traits, allocator<_CharT> >(__zero, __one);\n}\n\ntemplate <size_t _Size>\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, char_traits<_CharT>, allocator<_CharT> >\nbitset<_Size>::to_string(_CharT __zero, _CharT __one) const\n{\n    return to_string<_CharT, char_traits<_CharT>, allocator<_CharT> >(__zero, __one);\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<char, char_traits<char>, allocator<char> >\nbitset<_Size>::to_string(char __zero, char __one) const\n{\n    return to_string<char, char_traits<char>, allocator<char> >(__zero, __one);\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nsize_t\nbitset<_Size>::count() const _NOEXCEPT\n{\n    return static_cast<size_t>(_VSTD::count(base::__make_iter(0), base::__make_iter(_Size), true));\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nbitset<_Size>::operator==(const bitset& __rhs) const _NOEXCEPT\n{\n    return _VSTD::equal(base::__make_iter(0), base::__make_iter(_Size), __rhs.__make_iter(0));\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nbitset<_Size>::operator!=(const bitset& __rhs) const _NOEXCEPT\n{\n    return !(*this == __rhs);\n}\n\ntemplate <size_t _Size>\nbool\nbitset<_Size>::test(size_t __pos) const\n{\n    if (__pos >= _Size)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        throw out_of_range(\"bitset test argument out of range\");\n#else\n        assert(!\"bitset test argument out of range\");\n#endif\n    return (*this)[__pos];\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nbitset<_Size>::all() const _NOEXCEPT\n{\n    return base::all();\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nbitset<_Size>::any() const _NOEXCEPT\n{\n    return base::any();\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbitset<_Size>\nbitset<_Size>::operator<<(size_t __pos) const _NOEXCEPT\n{\n    bitset __r = *this;\n    __r <<= __pos;\n    return __r;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbitset<_Size>\nbitset<_Size>::operator>>(size_t __pos) const _NOEXCEPT\n{\n    bitset __r = *this;\n    __r >>= __pos;\n    return __r;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbitset<_Size>\noperator&(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT\n{\n    bitset<_Size> __r = __x;\n    __r &= __y;\n    return __r;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbitset<_Size>\noperator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT\n{\n    bitset<_Size> __r = __x;\n    __r |= __y;\n    return __r;\n}\n\ntemplate <size_t _Size>\ninline _LIBCPP_INLINE_VISIBILITY\nbitset<_Size>\noperator^(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT\n{\n    bitset<_Size> __r = __x;\n    __r ^= __y;\n    return __r;\n}\n\ntemplate <size_t _Size>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<bitset<_Size> >\n    : public unary_function<bitset<_Size>, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(const bitset<_Size>& __bs) const _NOEXCEPT\n        {return __bs.__hash_code();}\n};\n\ntemplate <class _CharT, class _Traits, size_t _Size>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x);\n\ntemplate <class _CharT, class _Traits, size_t _Size>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x);\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_BITSET\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cassert",
    "content": "// -*- C++ -*-\n//===-------------------------- cassert -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n/*\n    cassert synopsis\n\nMacros:\n\n    assert\n\n*/\n\n#include <__config>\n#include <assert.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/ccomplex",
    "content": "// -*- C++ -*-\n//===--------------------------- ccomplex ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CCOMPLEX\n#define _LIBCPP_CCOMPLEX\n\n/*\n    ccomplex synopsis\n\n#include <complex>\n\n*/\n\n#include <complex>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n// hh 080623 Created\n\n#endif  // _LIBCPP_CCOMPLEX\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cctype",
    "content": "// -*- C++ -*-\n//===---------------------------- cctype ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CCTYPE\n#define _LIBCPP_CCTYPE\n\n/*\n    cctype synopsis\n\nnamespace std\n{\n\nint isalnum(int c);\nint isalpha(int c);\nint isblank(int c);  // C99\nint iscntrl(int c);\nint isdigit(int c);\nint isgraph(int c);\nint islower(int c);\nint isprint(int c);\nint ispunct(int c);\nint isspace(int c);\nint isupper(int c);\nint isxdigit(int c);\nint tolower(int c);\nint toupper(int c);\n\n}  // std\n*/\n\n#include <__config>\n#include <ctype.h>\n#if defined(_LIBCPP_MSVCRT)\n#include \"support/win32/support.h\"\n#include \"support/win32/locale_win32.h\"\n#endif // _LIBCPP_MSVCRT\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n#ifdef isalnum\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_isalnum(int __c) {return isalnum(__c);}\n#undef isalnum\ninline _LIBCPP_INLINE_VISIBILITY int isalnum(int __c) {return __libcpp_isalnum(__c);}\n#else  // isalnum\nusing ::isalnum;\n#endif  // isalnum\n\n#ifdef isalpha\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_isalpha(int __c) {return isalpha(__c);}\n#undef isalpha\ninline _LIBCPP_INLINE_VISIBILITY int isalpha(int __c) {return __libcpp_isalpha(__c);}\n#else  // isalpha\nusing ::isalpha;\n#endif  // isalpha\n\n#ifdef isblank\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_isblank(int __c) {return isblank(__c);}\n#undef isblank\ninline _LIBCPP_INLINE_VISIBILITY int isblank(int __c) {return __libcpp_isblank(__c);}\n#else  // isblank\nusing ::isblank;\n#endif  // isblank\n\n#ifdef iscntrl\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_iscntrl(int __c) {return iscntrl(__c);}\n#undef iscntrl\ninline _LIBCPP_INLINE_VISIBILITY int iscntrl(int __c) {return __libcpp_iscntrl(__c);}\n#else  // iscntrl\nusing ::iscntrl;\n#endif  // iscntrl\n\n#ifdef isdigit\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_isdigit(int __c) {return isdigit(__c);}\n#undef isdigit\ninline _LIBCPP_INLINE_VISIBILITY int isdigit(int __c) {return __libcpp_isdigit(__c);}\n#else  // isdigit\nusing ::isdigit;\n#endif  // isdigit\n\n#ifdef isgraph\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_isgraph(int __c) {return isgraph(__c);}\n#undef isgraph\ninline _LIBCPP_INLINE_VISIBILITY int isgraph(int __c) {return __libcpp_isgraph(__c);}\n#else  // isgraph\nusing ::isgraph;\n#endif  // isgraph\n\n#ifdef islower\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_islower(int __c) {return islower(__c);}\n#undef islower\ninline _LIBCPP_INLINE_VISIBILITY int islower(int __c) {return __libcpp_islower(__c);}\n#else  // islower\nusing ::islower;\n#endif  // islower\n\n#ifdef isprint\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_isprint(int __c) {return isprint(__c);}\n#undef isprint\ninline _LIBCPP_INLINE_VISIBILITY int isprint(int __c) {return __libcpp_isprint(__c);}\n#else  // isprint\nusing ::isprint;\n#endif  // isprint\n\n#ifdef ispunct\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_ispunct(int __c) {return ispunct(__c);}\n#undef ispunct\ninline _LIBCPP_INLINE_VISIBILITY int ispunct(int __c) {return __libcpp_ispunct(__c);}\n#else  // ispunct\nusing ::ispunct;\n#endif  // ispunct\n\n#ifdef isspace\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_isspace(int __c) {return isspace(__c);}\n#undef isspace\ninline _LIBCPP_INLINE_VISIBILITY int isspace(int __c) {return __libcpp_isspace(__c);}\n#else  // isspace\nusing ::isspace;\n#endif  // isspace\n\n#ifdef isupper\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_isupper(int __c) {return isupper(__c);}\n#undef isupper\ninline _LIBCPP_INLINE_VISIBILITY int isupper(int __c) {return __libcpp_isupper(__c);}\n#else  // isupper\nusing ::isupper;\n#endif  // isupper\n\n#ifdef isxdigit\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_isxdigit(int __c) {return isxdigit(__c);}\n#undef isxdigit\ninline _LIBCPP_INLINE_VISIBILITY int isxdigit(int __c) {return __libcpp_isxdigit(__c);}\n#else  // isxdigit\nusing ::isxdigit;\n#endif  // isxdigit\n\n#ifdef tolower\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_tolower(int __c) {return tolower(__c);}\n#undef tolower\ninline _LIBCPP_INLINE_VISIBILITY int tolower(int __c) {return __libcpp_tolower(__c);}\n#else  // tolower\nusing ::tolower;\n#endif  // tolower\n\n#ifdef toupper\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_toupper(int __c) {return toupper(__c);}\n#undef toupper\ninline _LIBCPP_INLINE_VISIBILITY int toupper(int __c) {return __libcpp_toupper(__c);}\n#else  // toupper\nusing ::toupper;\n#endif  // toupper\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CCTYPE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cerrno",
    "content": "// -*- C++ -*-\n//===-------------------------- cerrno ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CERRNO\n#define _LIBCPP_CERRNO\n\n/*\n    cerrno synopsis\n\nMacros:\n\n    EDOM\n    EILSEQ  // C99\n    ERANGE\n    errno\n\n*/\n\n#include <__config>\n#include <errno.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#if !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE)\n\n#ifdef ELAST\n\nconst int __elast1 = ELAST+1;\nconst int __elast2 = ELAST+2;\n\n#else\n\nconst int __elast1 = 104;\nconst int __elast2 = 105;\n\n#endif\n\n#ifdef ENOTRECOVERABLE\n\n#define EOWNERDEAD __elast1\n\n#ifdef ELAST\n#undef ELAST\n#define ELAST EOWNERDEAD\n#endif\n\n#elif defined(EOWNERDEAD)\n\n#define ENOTRECOVERABLE __elast1\n#ifdef ELAST\n#undef ELAST\n#define ELAST ENOTRECOVERABLE\n#endif\n\n#else  // defined(EOWNERDEAD)\n\n#define EOWNERDEAD __elast1\n#define ENOTRECOVERABLE __elast2\n#ifdef ELAST\n#undef ELAST\n#define ELAST ENOTRECOVERABLE\n#endif\n\n#endif  // defined(EOWNERDEAD)\n\n#endif  // !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE)\n\n//  supply errno values likely to be missing, particularly on Windows\n\n#ifndef EAFNOSUPPORT\n#define EAFNOSUPPORT 9901\n#endif\n\n#ifndef EADDRINUSE\n#define EADDRINUSE 9902\n#endif\n\n#ifndef EADDRNOTAVAIL\n#define EADDRNOTAVAIL 9903\n#endif\n\n#ifndef EISCONN\n#define EISCONN 9904\n#endif\n\n#ifndef EBADMSG\n#define EBADMSG 9905\n#endif\n\n#ifndef ECONNABORTED\n#define ECONNABORTED 9906\n#endif\n\n#ifndef EALREADY\n#define EALREADY 9907\n#endif\n\n#ifndef ECONNREFUSED\n#define ECONNREFUSED 9908\n#endif\n\n#ifndef ECONNRESET\n#define ECONNRESET 9909\n#endif\n\n#ifndef EDESTADDRREQ\n#define EDESTADDRREQ 9910\n#endif\n\n#ifndef EHOSTUNREACH\n#define EHOSTUNREACH 9911\n#endif\n\n#ifndef EIDRM\n#define EIDRM 9912\n#endif\n\n#ifndef EMSGSIZE\n#define EMSGSIZE 9913\n#endif\n\n#ifndef ENETDOWN\n#define ENETDOWN 9914\n#endif\n\n#ifndef ENETRESET\n#define ENETRESET 9915\n#endif\n\n#ifndef ENETUNREACH\n#define ENETUNREACH 9916\n#endif\n\n#ifndef ENOBUFS\n#define ENOBUFS 9917\n#endif\n\n#ifndef ENOLINK\n#define ENOLINK 9918\n#endif\n\n#ifndef ENODATA\n#define ENODATA 9919\n#endif\n\n#ifndef ENOMSG\n#define ENOMSG 9920\n#endif\n\n#ifndef ENOPROTOOPT\n#define ENOPROTOOPT 9921\n#endif\n\n#ifndef ENOSR\n#define ENOSR 9922\n#endif\n\n#ifndef ENOTSOCK\n#define ENOTSOCK 9923\n#endif\n\n#ifndef ENOSTR\n#define ENOSTR 9924\n#endif\n\n#ifndef ENOTCONN\n#define ENOTCONN 9925\n#endif\n\n#ifndef ENOTSUP\n#define ENOTSUP 9926\n#endif\n\n#ifndef ECANCELED\n#define ECANCELED 9927\n#endif\n\n#ifndef EINPROGRESS\n#define EINPROGRESS 9928\n#endif\n\n#ifndef EOPNOTSUPP\n#define EOPNOTSUPP 9929\n#endif\n\n#ifndef EWOULDBLOCK\n#define EWOULDBLOCK 9930\n#endif\n\n#ifndef EOWNERDEAD\n#define EOWNERDEAD  9931\n#endif\n\n#ifndef EPROTO\n#define EPROTO 9932\n#endif\n\n#ifndef EPROTONOSUPPORT\n#define EPROTONOSUPPORT 9933\n#endif\n\n#ifndef ENOTRECOVERABLE\n#define ENOTRECOVERABLE 9934\n#endif\n\n#ifndef ETIME\n#define ETIME 9935\n#endif\n\n#ifndef ETXTBSY\n#define ETXTBSY 9936\n#endif\n\n#ifndef ETIMEDOUT\n#define ETIMEDOUT 9938\n#endif\n\n#ifndef ELOOP\n#define ELOOP 9939\n#endif\n\n#ifndef EOVERFLOW\n#define EOVERFLOW 9940\n#endif\n\n#ifndef EPROTOTYPE\n#define EPROTOTYPE 9941\n#endif\n\n#ifndef ENOSYS\n#define ENOSYS 9942\n#endif\n\n#ifndef EINVAL\n#define EINVAL 9943\n#endif\n\n#ifndef ERANGE\n#define ERANGE 9944\n#endif\n\n#ifndef EILSEQ\n#define EILSEQ 9945\n#endif\n\n//  Windows Mobile doesn't appear to define these:\n\n#ifndef E2BIG\n#define E2BIG 9946\n#endif\n\n#ifndef EDOM\n#define EDOM 9947\n#endif\n\n#ifndef EFAULT\n#define EFAULT 9948\n#endif\n\n#ifndef EBADF\n#define EBADF 9949\n#endif\n\n#ifndef EPIPE\n#define EPIPE 9950\n#endif\n\n#ifndef EXDEV\n#define EXDEV 9951\n#endif\n\n#ifndef EBUSY\n#define EBUSY 9952\n#endif\n\n#ifndef ENOTEMPTY\n#define ENOTEMPTY 9953\n#endif\n\n#ifndef ENOEXEC\n#define ENOEXEC 9954\n#endif\n\n#ifndef EEXIST\n#define EEXIST 9955\n#endif\n\n#ifndef EFBIG\n#define EFBIG 9956\n#endif\n\n#ifndef ENAMETOOLONG\n#define ENAMETOOLONG 9957\n#endif\n\n#ifndef ENOTTY\n#define ENOTTY 9958\n#endif\n\n#ifndef EINTR\n#define EINTR 9959\n#endif\n\n#ifndef ESPIPE\n#define ESPIPE 9960\n#endif\n\n#ifndef EIO\n#define EIO 9961\n#endif\n\n#ifndef EISDIR\n#define EISDIR 9962\n#endif\n\n#ifndef ECHILD\n#define ECHILD 9963\n#endif\n\n#ifndef ENOLCK\n#define ENOLCK 9964\n#endif\n\n#ifndef ENOSPC\n#define ENOSPC 9965\n#endif\n\n#ifndef ENXIO\n#define ENXIO 9966\n#endif\n\n#ifndef ENODEV\n#define ENODEV 9967\n#endif\n\n#ifndef ENOENT\n#define ENOENT 9968\n#endif\n\n#ifndef ESRCH\n#define ESRCH 9969\n#endif\n\n#ifndef ENOTDIR\n#define ENOTDIR 9970\n#endif\n\n#ifndef ENOMEM\n#define ENOMEM 9971\n#endif\n\n#ifndef EPERM\n#define EPERM 9972\n#endif\n\n#ifndef EACCES\n#define EACCES 9973\n#endif\n\n#ifndef EROFS\n#define EROFS 9974\n#endif\n\n#ifndef EDEADLK\n#define EDEADLK 9975\n#endif\n\n#ifndef EAGAIN\n#define EAGAIN 9976\n#endif\n\n#ifndef ENFILE\n#define ENFILE 9977\n#endif\n\n#ifndef EMFILE\n#define EMFILE 9978\n#endif\n\n#ifndef EMLINK\n#define EMLINK 9979\n#endif\n\n#endif  // _LIBCPP_CERRNO\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cfenv",
    "content": "// -*- C++ -*-\n//===---------------------------- cctype ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CFENV\n#define _LIBCPP_CFENV\n\n/*\n    cfenv synopsis\n\nThis entire header is C99 / C++0X\n\nMacros:\n\n    FE_DIVBYZERO\n    FE_INEXACT\n    FE_INVALID\n    FE_OVERFLOW\n    FE_UNDERFLOW\n    FE_ALL_EXCEPT\n    FE_DOWNWARD\n    FE_TONEAREST\n    FE_TOWARDZERO\n    FE_UPWARD\n    FE_DFL_ENV\n\nnamespace std\n{\n\nTypes:\n\n    fenv_t\n    fexcept_t\n\nint feclearexcept(int excepts);\nint fegetexceptflag(fexcept_t* flagp, int excepts);\nint feraiseexcept(int excepts);\nint fesetexceptflag(const fexcept_t* flagp, int excepts);\nint fetestexcept(int excepts);\nint fegetround();\nint fesetround(int round);\nint fegetenv(fenv_t* envp);\nint feholdexcept(fenv_t* envp);\nint fesetenv(const fenv_t* envp);\nint feupdateenv(const fenv_t* envp);\n\n}  // std\n*/\n\n#include <__config>\n#include <fenv.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing ::fenv_t;\nusing ::fexcept_t;\n\nusing ::feclearexcept;\nusing ::fegetexceptflag;\nusing ::feraiseexcept;\nusing ::fesetexceptflag;\nusing ::fetestexcept;\nusing ::fegetround;\nusing ::fesetround;\nusing ::fegetenv;\nusing ::feholdexcept;\nusing ::fesetenv;\nusing ::feupdateenv;\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CFENV\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cfloat",
    "content": "// -*- C++ -*-\n//===--------------------------- cfloat -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CFLOAT\n#define _LIBCPP_CFLOAT\n\n/*\n    cfloat synopsis\n\nMacros:\n\n    FLT_ROUNDS\n    FLT_EVAL_METHOD     // C99\n    FLT_RADIX\n\n    FLT_MANT_DIG\n    DBL_MANT_DIG\n    LDBL_MANT_DIG\n\n    DECIMAL_DIG         // C99\n\n    FLT_DIG\n    DBL_DIG\n    LDBL_DIG\n\n    FLT_MIN_EXP\n    DBL_MIN_EXP\n    LDBL_MIN_EXP\n\n    FLT_MIN_10_EXP\n    DBL_MIN_10_EXP\n    LDBL_MIN_10_EXP\n\n    FLT_MAX_EXP\n    DBL_MAX_EXP\n    LDBL_MAX_EXP\n\n    FLT_MAX_10_EXP\n    DBL_MAX_10_EXP\n    LDBL_MAX_10_EXP\n\n    FLT_MAX\n    DBL_MAX\n    LDBL_MAX\n\n    FLT_EPSILON\n    DBL_EPSILON\n    LDBL_EPSILON\n\n    FLT_MIN\n    DBL_MIN\n    LDBL_MIN\n\n*/\n\n#include <__config>\n#include <float.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#ifndef FLT_EVAL_METHOD\n#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__\n#endif\n\n#ifndef DECIMAL_DIG\n#define DECIMAL_DIG __DECIMAL_DIG__\n#endif\n\n#endif  // _LIBCPP_CFLOAT\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/chrono",
    "content": "// -*- C++ -*-\n//===---------------------------- chrono ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CHRONO\n#define _LIBCPP_CHRONO\n\n/*\n    chrono synopsis\n\nnamespace std\n{\nnamespace chrono\n{\n\ntemplate <class ToDuration, class Rep, class Period>\nconstexpr\nToDuration\nduration_cast(const duration<Rep, Period>& fd);\n\ntemplate <class Rep> struct treat_as_floating_point : is_floating_point<Rep> {};\n\ntemplate <class Rep>\nstruct duration_values\n{\npublic:\n    static constexpr Rep zero();\n    static constexpr Rep max();\n    static constexpr Rep min();\n};\n\n// duration\n\ntemplate <class Rep, class Period = ratio<1>>\nclass duration\n{\n    static_assert(!__is_duration<Rep>::value, \"A duration representation can not be a duration\");\n    static_assert(__is_ratio<Period>::value, \"Second template parameter of duration must be a std::ratio\");\n    static_assert(Period::num > 0, \"duration period must be positive\");\npublic:\n    typedef Rep rep;\n    typedef Period period;\n\n    constexpr duration() = default;\n    template <class Rep2>\n        constexpr explicit duration(const Rep2& r,\n            typename enable_if\n            <\n               is_convertible<Rep2, rep>::value &&\n               (treat_as_floating_point<rep>::value ||\n               !treat_as_floating_point<rep>::value && !treat_as_floating_point<Rep2>::value)\n            >::type* = 0);\n\n    // conversions\n    template <class Rep2, class Period2>\n        constexpr duration(const duration<Rep2, Period2>& d,\n            typename enable_if\n            <\n                treat_as_floating_point<rep>::value ||\n                ratio_divide<Period2, period>::type::den == 1\n            >::type* = 0);\n\n    // observer\n\n    constexpr rep count() const;\n\n    // arithmetic\n\n    constexpr duration  operator+() const;\n    constexpr duration  operator-() const;\n    duration& operator++();\n    duration  operator++(int);\n    duration& operator--();\n    duration  operator--(int);\n\n    duration& operator+=(const duration& d);\n    duration& operator-=(const duration& d);\n\n    duration& operator*=(const rep& rhs);\n    duration& operator/=(const rep& rhs);\n\n    // special values\n\n    static constexpr duration zero();\n    static constexpr duration min();\n    static constexpr duration max();\n};\n\ntypedef duration<long long,         nano> nanoseconds;\ntypedef duration<long long,        micro> microseconds;\ntypedef duration<long long,        milli> milliseconds;\ntypedef duration<long long              > seconds;\ntypedef duration<     long, ratio<  60> > minutes;\ntypedef duration<     long, ratio<3600> > hours;\n\ntemplate <class Clock, class Duration = typename Clock::duration>\nclass time_point\n{\npublic:\n    typedef Clock                     clock;\n    typedef Duration                  duration;\n    typedef typename duration::rep    rep;\n    typedef typename duration::period period;\nprivate:\n    duration d_;  // exposition only\n\npublic:\n    time_point();  // has value \"epoch\" // constexpr in C++14\n    explicit time_point(const duration& d);  // same as time_point() + d // constexpr in C++14\n\n    // conversions\n    template <class Duration2>\n       time_point(const time_point<clock, Duration2>& t); // constexpr in C++14\n\n    // observer\n\n    duration time_since_epoch() const; // constexpr in C++14\n\n    // arithmetic\n\n    time_point& operator+=(const duration& d);\n    time_point& operator-=(const duration& d);\n\n    // special values\n\n    static constexpr time_point min();\n    static constexpr time_point max();\n};\n\n} // chrono\n\n// common_type traits\ntemplate <class Rep1, class Period1, class Rep2, class Period2>\n  struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>>;\n\ntemplate <class Clock, class Duration1, class Duration2>\n  struct common_type<chrono::time_point<Clock, Duration1>, chrono::time_point<Clock, Duration2>>;\n\nnamespace chrono {\n\n// duration arithmetic\ntemplate <class Rep1, class Period1, class Rep2, class Period2>\n  constexpr\n  typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>::type\n  operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);\ntemplate <class Rep1, class Period1, class Rep2, class Period2>\n  constexpr\n  typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>::type\n  operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);\ntemplate <class Rep1, class Period, class Rep2>\n  constexpr\n  duration<typename common_type<Rep1, Rep2>::type, Period>\n  operator*(const duration<Rep1, Period>& d, const Rep2& s);\ntemplate <class Rep1, class Period, class Rep2>\n  constexpr\n  duration<typename common_type<Rep1, Rep2>::type, Period>\n  operator*(const Rep1& s, const duration<Rep2, Period>& d);\ntemplate <class Rep1, class Period, class Rep2>\n  constexpr\n  duration<typename common_type<Rep1, Rep2>::type, Period>\n  operator/(const duration<Rep1, Period>& d, const Rep2& s);\ntemplate <class Rep1, class Period1, class Rep2, class Period2>\n  constexpr\n  typename common_type<Rep1, Rep2>::type\n  operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);\n\n// duration comparisons\ntemplate <class Rep1, class Period1, class Rep2, class Period2>\n   constexpr\n   bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);\ntemplate <class Rep1, class Period1, class Rep2, class Period2>\n   constexpr\n   bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);\ntemplate <class Rep1, class Period1, class Rep2, class Period2>\n   constexpr\n   bool operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);\ntemplate <class Rep1, class Period1, class Rep2, class Period2>\n   constexpr\n   bool operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);\ntemplate <class Rep1, class Period1, class Rep2, class Period2>\n   constexpr\n   bool operator> (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);\ntemplate <class Rep1, class Period1, class Rep2, class Period2>\n   constexpr\n   bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);\n\n// duration_cast\ntemplate <class ToDuration, class Rep, class Period>\n  ToDuration duration_cast(const duration<Rep, Period>& d);\n\n// time_point arithmetic (all constexpr in C++14)\ntemplate <class Clock, class Duration1, class Rep2, class Period2>\n  time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type>\n  operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);\ntemplate <class Rep1, class Period1, class Clock, class Duration2>\n  time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type>\n  operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs);\ntemplate <class Clock, class Duration1, class Rep2, class Period2>\n  time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type>\n  operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);\ntemplate <class Clock, class Duration1, class Duration2>\n  typename common_type<Duration1, Duration2>::type\n  operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);\n\n// time_point comparisons (all constexpr in C++14)\ntemplate <class Clock, class Duration1, class Duration2>\n   bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);\ntemplate <class Clock, class Duration1, class Duration2>\n   bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);\ntemplate <class Clock, class Duration1, class Duration2>\n   bool operator< (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);\ntemplate <class Clock, class Duration1, class Duration2>\n   bool operator<=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);\ntemplate <class Clock, class Duration1, class Duration2>\n   bool operator> (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);\ntemplate <class Clock, class Duration1, class Duration2>\n   bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);\n\n// time_point_cast (constexpr in C++14)\n\ntemplate <class ToDuration, class Clock, class Duration>\n  time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);\n\n// Clocks\n\nclass system_clock\n{\npublic:\n    typedef microseconds                     duration;\n    typedef duration::rep                    rep;\n    typedef duration::period                 period;\n    typedef chrono::time_point<system_clock> time_point;\n    static const bool is_steady =            false; // constexpr in C++14\n\n    static time_point now() noexcept;\n    static time_t     to_time_t  (const time_point& __t) noexcept;\n    static time_point from_time_t(time_t __t) noexcept;\n};\n\nclass steady_clock\n{\npublic:\n    typedef nanoseconds                                   duration;\n    typedef duration::rep                                 rep;\n    typedef duration::period                              period;\n    typedef chrono::time_point<steady_clock, duration>    time_point;\n    static const bool is_steady =                         true; // constexpr in C++14\n\n    static time_point now() noexcept;\n};\n\ntypedef steady_clock high_resolution_clock;\n\n}  // chrono\n\nconstexpr chrono::hours                                 operator \"\" h(unsigned long long); // C++14\nconstexpr chrono::duration<unspecified , ratio<3600,1>> operator \"\" h(long double); // C++14\nconstexpr chrono::minutes                               operator \"\" min(unsigned long long); // C++14\nconstexpr chrono::duration<unspecified , ratio<60,1>>   operator \"\" min(long double); // C++14\nconstexpr chrono::seconds                               operator \"\" s(unsigned long long); // C++14\nconstexpr chrono::duration<unspecified >                operator \"\" s(long double); // C++14\nconstexpr chrono::milliseconds                          operator \"\" ms(unsigned long long); // C++14\nconstexpr chrono::duration<unspecified , milli>         operator \"\" ms(long double); // C++14\nconstexpr chrono::microseconds                          operator \"\" us(unsigned long long); // C++14\nconstexpr chrono::duration<unspecified , micro>         operator \"\" us(long double); // C++14\nconstexpr chrono::nanoseconds                           operator \"\" ns(unsigned long long); // C++14\nconstexpr chrono::duration<unspecified , nano>          operator \"\" ns(long double); // C++14\n\n}  // std\n*/\n\n#include <__config>\n#include <ctime>\n#include <type_traits>\n#include <ratio>\n#include <limits>\n\n#include <__undef_min_max>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nnamespace chrono\n{\n\ntemplate <class _Rep, class _Period = ratio<1> > class _LIBCPP_TYPE_VIS_ONLY duration;\n\ntemplate <class _Tp>\nstruct __is_duration : false_type {};\n\ntemplate <class _Rep, class _Period>\nstruct __is_duration<duration<_Rep, _Period> > : true_type  {};\n\ntemplate <class _Rep, class _Period>\nstruct __is_duration<const duration<_Rep, _Period> > : true_type  {};\n\ntemplate <class _Rep, class _Period>\nstruct __is_duration<volatile duration<_Rep, _Period> > : true_type  {};\n\ntemplate <class _Rep, class _Period>\nstruct __is_duration<const volatile duration<_Rep, _Period> > : true_type  {};\n\n} // chrono\n\ntemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>\nstruct _LIBCPP_TYPE_VIS_ONLY common_type<chrono::duration<_Rep1, _Period1>,\n                                         chrono::duration<_Rep2, _Period2> >\n{\n    typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type,\n                             typename __ratio_gcd<_Period1, _Period2>::type> type;\n};\n\nnamespace chrono {\n\n// duration_cast\n\ntemplate <class _FromDuration, class _ToDuration,\n          class _Period = typename ratio_divide<typename _FromDuration::period, typename _ToDuration::period>::type,\n          bool = _Period::num == 1,\n          bool = _Period::den == 1>\nstruct __duration_cast;\n\ntemplate <class _FromDuration, class _ToDuration, class _Period>\nstruct __duration_cast<_FromDuration, _ToDuration, _Period, true, true>\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR\n    _ToDuration operator()(const _FromDuration& __fd) const\n    {\n        return _ToDuration(static_cast<typename _ToDuration::rep>(__fd.count()));\n    }\n};\n\ntemplate <class _FromDuration, class _ToDuration, class _Period>\nstruct __duration_cast<_FromDuration, _ToDuration, _Period, true, false>\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR\n    _ToDuration operator()(const _FromDuration& __fd) const\n    {\n        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;\n        return _ToDuration(static_cast<typename _ToDuration::rep>(\n                           static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den)));\n    }\n};\n\ntemplate <class _FromDuration, class _ToDuration, class _Period>\nstruct __duration_cast<_FromDuration, _ToDuration, _Period, false, true>\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR\n    _ToDuration operator()(const _FromDuration& __fd) const\n    {\n        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;\n        return _ToDuration(static_cast<typename _ToDuration::rep>(\n                           static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)));\n    }\n};\n\ntemplate <class _FromDuration, class _ToDuration, class _Period>\nstruct __duration_cast<_FromDuration, _ToDuration, _Period, false, false>\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR\n    _ToDuration operator()(const _FromDuration& __fd) const\n    {\n        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;\n        return _ToDuration(static_cast<typename _ToDuration::rep>(\n                           static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)\n                                                          / static_cast<_Ct>(_Period::den)));\n    }\n};\n\ntemplate <class _ToDuration, class _Rep, class _Period>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ntypename enable_if\n<\n    __is_duration<_ToDuration>::value,\n    _ToDuration\n>::type\nduration_cast(const duration<_Rep, _Period>& __fd)\n{\n    return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd);\n}\n\ntemplate <class _Rep>\nstruct _LIBCPP_TYPE_VIS_ONLY treat_as_floating_point : is_floating_point<_Rep> {};\n\ntemplate <class _Rep>\nstruct _LIBCPP_TYPE_VIS_ONLY duration_values\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() {return _Rep(0);}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max()  {return numeric_limits<_Rep>::max();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min()  {return numeric_limits<_Rep>::lowest();}\n};\n\n// duration\n\ntemplate <class _Rep, class _Period>\nclass _LIBCPP_TYPE_VIS_ONLY duration\n{\n    static_assert(!__is_duration<_Rep>::value, \"A duration representation can not be a duration\");\n    static_assert(__is_ratio<_Period>::value, \"Second template parameter of duration must be a std::ratio\");\n    static_assert(_Period::num > 0, \"duration period must be positive\");\n\n    template <class _R1, class _R2>\n    struct __no_overflow\n    {\n    private:\n        static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;\n        static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;\n        static const intmax_t __n1 = _R1::num / __gcd_n1_n2;\n        static const intmax_t __d1 = _R1::den / __gcd_d1_d2;\n        static const intmax_t __n2 = _R2::num / __gcd_n1_n2;\n        static const intmax_t __d2 = _R2::den / __gcd_d1_d2;\n        static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1);\n\n        template <intmax_t _Xp, intmax_t _Yp, bool __overflow>\n        struct __mul    // __overflow == false\n        {\n            static const intmax_t value = _Xp * _Yp;\n        };\n\n        template <intmax_t _Xp, intmax_t _Yp>\n        struct __mul<_Xp, _Yp, true>\n        {\n            static const intmax_t value = 1;\n        };\n\n    public:\n        static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1);\n        typedef ratio<__mul<__n1, __d2, !value>::value,\n                      __mul<__n2, __d1, !value>::value> type;\n    };\n    \npublic:\n    typedef _Rep rep;\n    typedef _Period period;\nprivate:\n    rep __rep_;\npublic:\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR\n#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n        duration() = default;\n#else\n        duration() {}\n#endif\n\n    template <class _Rep2>\n        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR\n        explicit duration(const _Rep2& __r,\n            typename enable_if\n            <\n               is_convertible<_Rep2, rep>::value &&\n               (treat_as_floating_point<rep>::value ||\n               !treat_as_floating_point<_Rep2>::value)\n            >::type* = 0)\n                : __rep_(__r) {}\n\n    // conversions\n    template <class _Rep2, class _Period2>\n        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR\n        duration(const duration<_Rep2, _Period2>& __d,\n            typename enable_if\n            <\n                __no_overflow<_Period2, period>::value && (\n                treat_as_floating_point<rep>::value ||\n                (__no_overflow<_Period2, period>::type::den == 1 &&\n                 !treat_as_floating_point<_Rep2>::value))\n            >::type* = 0)\n                : __rep_(_VSTD::chrono::duration_cast<duration>(__d).count()) {}\n\n    // observer\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR rep count() const {return __rep_;}\n\n    // arithmetic\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR duration  operator+() const {return *this;}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR duration  operator-() const {return duration(-__rep_);}\n    _LIBCPP_INLINE_VISIBILITY duration& operator++()      {++__rep_; return *this;}\n    _LIBCPP_INLINE_VISIBILITY duration  operator++(int)   {return duration(__rep_++);}\n    _LIBCPP_INLINE_VISIBILITY duration& operator--()      {--__rep_; return *this;}\n    _LIBCPP_INLINE_VISIBILITY duration  operator--(int)   {return duration(__rep_--);}\n\n    _LIBCPP_INLINE_VISIBILITY duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;}\n    _LIBCPP_INLINE_VISIBILITY duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;}\n\n    _LIBCPP_INLINE_VISIBILITY duration& operator*=(const rep& rhs) {__rep_ *= rhs; return *this;}\n    _LIBCPP_INLINE_VISIBILITY duration& operator/=(const rep& rhs) {__rep_ /= rhs; return *this;}\n    _LIBCPP_INLINE_VISIBILITY duration& operator%=(const rep& rhs) {__rep_ %= rhs; return *this;}\n    _LIBCPP_INLINE_VISIBILITY duration& operator%=(const duration& rhs) {__rep_ %= rhs.count(); return *this;}\n\n    // special values\n\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() {return duration(duration_values<rep>::zero());}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min()  {return duration(duration_values<rep>::min());}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max()  {return duration(duration_values<rep>::max());}\n};\n\ntypedef duration<long long,         nano> nanoseconds;\ntypedef duration<long long,        micro> microseconds;\ntypedef duration<long long,        milli> milliseconds;\ntypedef duration<long long              > seconds;\ntypedef duration<     long, ratio<  60> > minutes;\ntypedef duration<     long, ratio<3600> > hours;\n\n// Duration ==\n\ntemplate <class _LhsDuration, class _RhsDuration>\nstruct __duration_eq\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR\n    bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const\n        {\n            typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;\n            return _Ct(__lhs).count() == _Ct(__rhs).count();\n        }\n};\n\ntemplate <class _LhsDuration>\nstruct __duration_eq<_LhsDuration, _LhsDuration>\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR\n    bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const\n        {return __lhs.count() == __rhs.count();}\n};\n\ntemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nbool\noperator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)\n{\n    return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);\n}\n\n// Duration !=\n\ntemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nbool\noperator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)\n{\n    return !(__lhs == __rhs);\n}\n\n// Duration <\n\ntemplate <class _LhsDuration, class _RhsDuration>\nstruct __duration_lt\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR\n    bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const\n        {\n            typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;\n            return _Ct(__lhs).count() < _Ct(__rhs).count();\n        }\n};\n\ntemplate <class _LhsDuration>\nstruct __duration_lt<_LhsDuration, _LhsDuration>\n{\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR\n    bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const\n        {return __lhs.count() < __rhs.count();}\n};\n\ntemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nbool\noperator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)\n{\n    return __duration_lt<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);\n}\n\n// Duration >\n\ntemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nbool\noperator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)\n{\n    return __rhs < __lhs;\n}\n\n// Duration <=\n\ntemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nbool\noperator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)\n{\n    return !(__rhs < __lhs);\n}\n\n// Duration >=\n\ntemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nbool\noperator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)\n{\n    return !(__lhs < __rhs);\n}\n\n// Duration +\n\ntemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ntypename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type\noperator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)\n{\n    typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;\n    return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count());\n}\n\n// Duration -\n\ntemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ntypename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type\noperator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)\n{\n    typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;\n    return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count());\n}\n\n// Duration *\n\ntemplate <class _Rep1, class _Period, class _Rep2>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ntypename enable_if\n<\n    is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value,\n    duration<typename common_type<_Rep1, _Rep2>::type, _Period>\n>::type\noperator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)\n{\n    typedef typename common_type<_Rep1, _Rep2>::type _Cr;\n    typedef duration<_Cr, _Period> _Cd;\n    return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s));\n}\n\ntemplate <class _Rep1, class _Period, class _Rep2>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ntypename enable_if\n<\n    is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value,\n    duration<typename common_type<_Rep1, _Rep2>::type, _Period>\n>::type\noperator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d)\n{\n    return __d * __s;\n}\n\n// Duration /\n\ntemplate <class _Duration, class _Rep, bool = __is_duration<_Rep>::value>\nstruct __duration_divide_result\n{\n};\n\ntemplate <class _Duration, class _Rep2,\n    bool = is_convertible<_Rep2,\n                          typename common_type<typename _Duration::rep, _Rep2>::type>::value>\nstruct __duration_divide_imp\n{\n};\n\ntemplate <class _Rep1, class _Period, class _Rep2>\nstruct __duration_divide_imp<duration<_Rep1, _Period>, _Rep2, true>\n{\n    typedef duration<typename common_type<_Rep1, _Rep2>::type, _Period> type;\n};\n\ntemplate <class _Rep1, class _Period, class _Rep2>\nstruct __duration_divide_result<duration<_Rep1, _Period>, _Rep2, false>\n    : __duration_divide_imp<duration<_Rep1, _Period>, _Rep2>\n{\n};\n\ntemplate <class _Rep1, class _Period, class _Rep2>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ntypename __duration_divide_result<duration<_Rep1, _Period>, _Rep2>::type\noperator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s)\n{\n    typedef typename common_type<_Rep1, _Rep2>::type _Cr;\n    typedef duration<_Cr, _Period> _Cd;\n    return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s));\n}\n\ntemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ntypename common_type<_Rep1, _Rep2>::type\noperator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)\n{\n    typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct;\n    return _Ct(__lhs).count() / _Ct(__rhs).count();\n}\n\n// Duration %\n\ntemplate <class _Rep1, class _Period, class _Rep2>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ntypename __duration_divide_result<duration<_Rep1, _Period>, _Rep2>::type\noperator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s)\n{\n    typedef typename common_type<_Rep1, _Rep2>::type _Cr;\n    typedef duration<_Cr, _Period> _Cd;\n    return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s));\n}\n\ntemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ntypename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type\noperator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)\n{\n    typedef typename common_type<_Rep1, _Rep2>::type _Cr;\n    typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;\n    return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count()));\n}\n\n//////////////////////////////////////////////////////////\n///////////////////// time_point /////////////////////////\n//////////////////////////////////////////////////////////\n\ntemplate <class _Clock, class _Duration = typename _Clock::duration>\nclass _LIBCPP_TYPE_VIS_ONLY time_point\n{\n    static_assert(__is_duration<_Duration>::value,\n                  \"Second template parameter of time_point must be a std::chrono::duration\");\npublic:\n    typedef _Clock                    clock;\n    typedef _Duration                 duration;\n    typedef typename duration::rep    rep;\n    typedef typename duration::period period;\nprivate:\n    duration __d_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 time_point() : __d_(duration::zero()) {}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit time_point(const duration& __d) : __d_(__d) {}\n\n    // conversions\n    template <class _Duration2>\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    time_point(const time_point<clock, _Duration2>& t,\n        typename enable_if\n        <\n            is_convertible<_Duration2, duration>::value\n        >::type* = 0)\n            : __d_(t.time_since_epoch()) {}\n\n    // observer\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 duration time_since_epoch() const {return __d_;}\n\n    // arithmetic\n\n    _LIBCPP_INLINE_VISIBILITY time_point& operator+=(const duration& __d) {__d_ += __d; return *this;}\n    _LIBCPP_INLINE_VISIBILITY time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;}\n\n    // special values\n\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() {return time_point(duration::min());}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() {return time_point(duration::max());}\n};\n\n} // chrono\n\ntemplate <class _Clock, class _Duration1, class _Duration2>\nstruct _LIBCPP_TYPE_VIS_ONLY common_type<chrono::time_point<_Clock, _Duration1>,\n                                         chrono::time_point<_Clock, _Duration2> >\n{\n    typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type;\n};\n\nnamespace chrono {\n\ntemplate <class _ToDuration, class _Clock, class _Duration>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntime_point<_Clock, _ToDuration>\ntime_point_cast(const time_point<_Clock, _Duration>& __t)\n{\n    return time_point<_Clock, _ToDuration>(_VSTD::chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));\n}\n\n// time_point ==\n\ntemplate <class _Clock, class _Duration1, class _Duration2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)\n{\n    return __lhs.time_since_epoch() == __rhs.time_since_epoch();\n}\n\n// time_point !=\n\ntemplate <class _Clock, class _Duration1, class _Duration2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)\n{\n    return !(__lhs == __rhs);\n}\n\n// time_point <\n\ntemplate <class _Clock, class _Duration1, class _Duration2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)\n{\n    return __lhs.time_since_epoch() < __rhs.time_since_epoch();\n}\n\n// time_point >\n\ntemplate <class _Clock, class _Duration1, class _Duration2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)\n{\n    return __rhs < __lhs;\n}\n\n// time_point <=\n\ntemplate <class _Clock, class _Duration1, class _Duration2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)\n{\n    return !(__rhs < __lhs);\n}\n\n// time_point >=\n\ntemplate <class _Clock, class _Duration1, class _Duration2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)\n{\n    return !(__lhs < __rhs);\n}\n\n// time_point operator+(time_point x, duration y);\n\ntemplate <class _Clock, class _Duration1, class _Rep2, class _Period2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntime_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>\noperator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs)\n{\n    typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr;\n    return _Tr (__lhs.time_since_epoch() + __rhs);\n}\n\n// time_point operator+(duration x, time_point y);\n\ntemplate <class _Rep1, class _Period1, class _Clock, class _Duration2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntime_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>\noperator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)\n{\n    return __rhs + __lhs;\n}\n\n// time_point operator-(time_point x, duration y);\n\ntemplate <class _Clock, class _Duration1, class _Rep2, class _Period2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntime_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>\noperator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs)\n{\n    return __lhs + (-__rhs);\n}\n\n// duration operator-(time_point x, time_point y);\n\ntemplate <class _Clock, class _Duration1, class _Duration2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntypename common_type<_Duration1, _Duration2>::type\noperator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)\n{\n    return __lhs.time_since_epoch() - __rhs.time_since_epoch();\n}\n\n//////////////////////////////////////////////////////////\n/////////////////////// clocks ///////////////////////////\n//////////////////////////////////////////////////////////\n\nclass _LIBCPP_TYPE_VIS system_clock\n{\npublic:\n    typedef microseconds                     duration;\n    typedef duration::rep                    rep;\n    typedef duration::period                 period;\n    typedef chrono::time_point<system_clock> time_point;\n    static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;\n\n    static time_point now() _NOEXCEPT;\n    static time_t     to_time_t  (const time_point& __t) _NOEXCEPT;\n    static time_point from_time_t(time_t __t) _NOEXCEPT;\n};\n\n#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK\nclass _LIBCPP_TYPE_VIS steady_clock\n{\npublic:\n    typedef nanoseconds                                   duration;\n    typedef duration::rep                                 rep;\n    typedef duration::period                              period;\n    typedef chrono::time_point<steady_clock, duration>    time_point;\n    static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = true;\n\n    static time_point now() _NOEXCEPT;\n};\n\ntypedef steady_clock high_resolution_clock;\n#else\ntypedef system_clock high_resolution_clock;\n#endif\n\n} // chrono\n\n#if _LIBCPP_STD_VER > 11\n// Suffixes for duration literals [time.duration.literals]\ninline namespace literals\n{ \n  inline namespace chrono_literals\n  {\n\n    constexpr chrono::hours operator\"\" h(unsigned long long __h)\n    {\n        return chrono::hours(static_cast<chrono::hours::rep>(__h));\n    }\n\n    constexpr chrono::duration<long double, ratio<3600,1>> operator\"\" h(long double __h)\n    {\n        return chrono::duration<long double, ratio<3600,1>>(__h);\n    }\n\n\n    constexpr chrono::minutes operator\"\" min(unsigned long long __m)\n    {\n        return chrono::minutes(static_cast<chrono::minutes::rep>(__m));\n    }\n\n    constexpr chrono::duration<long double, ratio<60,1>> operator\"\" min(long double __m)\n    {\n        return chrono::duration<long double, ratio<60,1>> (__m);\n    }\n\n\n    constexpr chrono::seconds operator\"\" s(unsigned long long __s)\n    {\n        return chrono::seconds(static_cast<chrono::seconds::rep>(__s));\n    }\n\n    constexpr chrono::duration<long double> operator\"\" s(long double __s)\n    {\n        return chrono::duration<long double> (__s);\n    }\n\n\n    constexpr chrono::milliseconds operator\"\" ms(unsigned long long __ms)\n    {\n        return chrono::milliseconds(static_cast<chrono::milliseconds::rep>(__ms));\n    }\n\n    constexpr chrono::duration<long double, milli> operator\"\" ms(long double __ms)\n    {\n        return chrono::duration<long double, milli>(__ms);\n    }\n\n\n    constexpr chrono::microseconds operator\"\" us(unsigned long long __us)\n    {\n        return chrono::microseconds(static_cast<chrono::microseconds::rep>(__us));\n    }\n\n    constexpr chrono::duration<long double, micro> operator\"\" us(long double __us)\n    {\n        return chrono::duration<long double, micro> (__us);\n    }\n    \n\n    constexpr chrono::nanoseconds operator\"\" ns(unsigned long long __ns)\n    {\n        return chrono::nanoseconds(static_cast<chrono::nanoseconds::rep>(__ns));\n    }\n\n    constexpr chrono::duration<long double, nano> operator\"\" ns(long double __ns)\n    {\n        return chrono::duration<long double, nano> (__ns);\n    }\n\n}}\n\nnamespace chrono { // hoist the literals into namespace std::chrono\n   using namespace literals::chrono_literals;\n}\n\n#endif\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CHRONO\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cinttypes",
    "content": "// -*- C++ -*-\n//===--------------------------- cinttypes --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CINTTYPES\n#define _LIBCPP_CINTTYPES\n\n/*\n    cinttypes synopsis\n\nThis entire header is C99 / C++0X\n\n#include <cstdint>  // <cinttypes> includes <cstdint>\n\nMacros:\n\n    PRId8\n    PRId16\n    PRId32\n    PRId64\n\n    PRIdLEAST8\n    PRIdLEAST16\n    PRIdLEAST32\n    PRIdLEAST64\n\n    PRIdFAST8\n    PRIdFAST16\n    PRIdFAST32\n    PRIdFAST64\n\n    PRIdMAX\n    PRIdPTR\n\n    PRIi8\n    PRIi16\n    PRIi32\n    PRIi64\n\n    PRIiLEAST8\n    PRIiLEAST16\n    PRIiLEAST32\n    PRIiLEAST64\n\n    PRIiFAST8\n    PRIiFAST16\n    PRIiFAST32\n    PRIiFAST64\n\n    PRIiMAX\n    PRIiPTR\n\n    PRIo8\n    PRIo16\n    PRIo32\n    PRIo64\n\n    PRIoLEAST8\n    PRIoLEAST16\n    PRIoLEAST32\n    PRIoLEAST64\n\n    PRIoFAST8\n    PRIoFAST16\n    PRIoFAST32\n    PRIoFAST64\n\n    PRIoMAX\n    PRIoPTR\n\n    PRIu8\n    PRIu16\n    PRIu32\n    PRIu64\n\n    PRIuLEAST8\n    PRIuLEAST16\n    PRIuLEAST32\n    PRIuLEAST64\n\n    PRIuFAST8\n    PRIuFAST16\n    PRIuFAST32\n    PRIuFAST64\n\n    PRIuMAX\n    PRIuPTR\n\n    PRIx8\n    PRIx16\n    PRIx32\n    PRIx64\n\n    PRIxLEAST8\n    PRIxLEAST16\n    PRIxLEAST32\n    PRIxLEAST64\n\n    PRIxFAST8\n    PRIxFAST16\n    PRIxFAST32\n    PRIxFAST64\n\n    PRIxMAX\n    PRIxPTR\n\n    PRIX8\n    PRIX16\n    PRIX32\n    PRIX64\n\n    PRIXLEAST8\n    PRIXLEAST16\n    PRIXLEAST32\n    PRIXLEAST64\n\n    PRIXFAST8\n    PRIXFAST16\n    PRIXFAST32\n    PRIXFAST64\n\n    PRIXMAX\n    PRIXPTR\n\n    SCNd8\n    SCNd16\n    SCNd32\n    SCNd64\n\n    SCNdLEAST8\n    SCNdLEAST16\n    SCNdLEAST32\n    SCNdLEAST64\n\n    SCNdFAST8\n    SCNdFAST16\n    SCNdFAST32\n    SCNdFAST64\n\n    SCNdMAX\n    SCNdPTR\n\n    SCNi8\n    SCNi16\n    SCNi32\n    SCNi64\n\n    SCNiLEAST8\n    SCNiLEAST16\n    SCNiLEAST32\n    SCNiLEAST64\n\n    SCNiFAST8\n    SCNiFAST16\n    SCNiFAST32\n    SCNiFAST64\n\n    SCNiMAX\n    SCNiPTR\n\n    SCNo8\n    SCNo16\n    SCNo32\n    SCNo64\n\n    SCNoLEAST8\n    SCNoLEAST16\n    SCNoLEAST32\n    SCNoLEAST64\n\n    SCNoFAST8\n    SCNoFAST16\n    SCNoFAST32\n    SCNoFAST64\n\n    SCNoMAX\n    SCNoPTR\n\n    SCNu8\n    SCNu16\n    SCNu32\n    SCNu64\n\n    SCNuLEAST8\n    SCNuLEAST16\n    SCNuLEAST32\n    SCNuLEAST64\n\n    SCNuFAST8\n    SCNuFAST16\n    SCNuFAST32\n    SCNuFAST64\n\n    SCNuMAX\n    SCNuPTR\n\n    SCNx8\n    SCNx16\n    SCNx32\n    SCNx64\n\n    SCNxLEAST8\n    SCNxLEAST16\n    SCNxLEAST32\n    SCNxLEAST64\n\n    SCNxFAST8\n    SCNxFAST16\n    SCNxFAST32\n    SCNxFAST64\n\n    SCNxMAX\n    SCNxPTR\n\nnamespace std\n{\n\nTypes:\n\n    imaxdiv_t\n\nintmax_t  imaxabs(intmax_t j);\nimaxdiv_t imaxdiv(intmax_t numer, intmax_t denom);\nintmax_t  strtoimax(const char* restrict nptr, char** restrict endptr, int base);\nuintmax_t strtoumax(const char* restrict nptr, char** restrict endptr, int base);\nintmax_t  wcstoimax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);\nuintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);\n\n}  // std\n*/\n\n#include <__config>\n#include <cstdint>\n#include <inttypes.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing::imaxdiv_t;\n\n#undef imaxabs\nusing::imaxabs;\n#undef imaxdiv\nusing::imaxdiv;\nusing::strtoimax;\nusing::strtoumax;\nusing::wcstoimax;\nusing::wcstoumax;\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CINTTYPES\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/ciso646",
    "content": "// -*- C++ -*-\n//===--------------------------- ciso646 ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CISO646\n#define _LIBCPP_CISO646\n\n/*\n    ciso646 synopsis\n\n*/\n\n#include <__config>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#endif  // _LIBCPP_CISO646\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/climits",
    "content": "// -*- C++ -*-\n//===--------------------------- climits ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CLIMITS\n#define _LIBCPP_CLIMITS\n\n/*\n    climits synopsis\n\nMacros:\n\n    CHAR_BIT\n    SCHAR_MIN\n    SCHAR_MAX\n    UCHAR_MAX\n    CHAR_MIN\n    CHAR_MAX\n    MB_LEN_MAX\n    SHRT_MIN\n    SHRT_MAX\n    USHRT_MAX\n    INT_MIN\n    INT_MAX\n    UINT_MAX\n    LONG_MIN\n    LONG_MAX\n    ULONG_MAX\n    LLONG_MIN   // C99\n    LLONG_MAX   // C99\n    ULLONG_MAX  // C99\n\n*/\n\n#include <__config>\n#include <limits.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#endif  // _LIBCPP_CLIMITS\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/clocale",
    "content": "// -*- C++ -*-\n//===--------------------------- clocale ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CLOCALE\n#define _LIBCPP_CLOCALE\n\n/*\n    clocale synopsis\n\nMacros:\n\n    LC_ALL\n    LC_COLLATE\n    LC_CTYPE\n    LC_MONETARY\n    LC_NUMERIC\n    LC_TIME\n    NULL\n\nnamespace std\n{\n\nstruct lconv;\nchar* setlocale(int category, const char* locale);\nlconv* localeconv();\n\n}  // std\n\n*/\n\n#include <__config>\n#include <locale.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing ::lconv;\n#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS\nusing ::setlocale;\n#endif\nusing ::localeconv;\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CLOCALE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cmath",
    "content": "// -*- C++ -*-\n//===---------------------------- cmath -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CMATH\n#define _LIBCPP_CMATH\n\n/*\n    cmath synopsis\n\nMacros:\n\n    HUGE_VAL\n    HUGE_VALF               // C99\n    HUGE_VALL               // C99\n    INFINITY                // C99\n    NAN                     // C99\n    FP_INFINITE             // C99\n    FP_NAN                  // C99\n    FP_NORMAL               // C99\n    FP_SUBNORMAL            // C99\n    FP_ZERO                 // C99\n    FP_FAST_FMA             // C99\n    FP_FAST_FMAF            // C99\n    FP_FAST_FMAL            // C99\n    FP_ILOGB0               // C99\n    FP_ILOGBNAN             // C99\n    MATH_ERRNO              // C99\n    MATH_ERREXCEPT          // C99\n    math_errhandling        // C99\n\nnamespace std\n{\n\nTypes:\n\n    float_t                 // C99\n    double_t                // C99\n\n// C90\n\nfloating_point abs(floating_point x);\n\nfloating_point acos (arithmetic x);\nfloat          acosf(float x);\nlong double    acosl(long double x);\n\nfloating_point asin (arithmetic x);\nfloat          asinf(float x);\nlong double    asinl(long double x);\n\nfloating_point atan (arithmetic x);\nfloat          atanf(float x);\nlong double    atanl(long double x);\n\nfloating_point atan2 (arithmetic y, arithmetic x);\nfloat          atan2f(float y, float x);\nlong double    atan2l(long double y, long double x);\n\nfloating_point ceil (arithmetic x);\nfloat          ceilf(float x);\nlong double    ceill(long double x);\n\nfloating_point cos (arithmetic x);\nfloat          cosf(float x);\nlong double    cosl(long double x);\n\nfloating_point cosh (arithmetic x);\nfloat          coshf(float x);\nlong double    coshl(long double x);\n\nfloating_point exp (arithmetic x);\nfloat          expf(float x);\nlong double    expl(long double x);\n\nfloating_point fabs (arithmetic x);\nfloat          fabsf(float x);\nlong double    fabsl(long double x);\n\nfloating_point floor (arithmetic x);\nfloat          floorf(float x);\nlong double    floorl(long double x);\n\nfloating_point fmod (arithmetic x, arithmetic y);\nfloat          fmodf(float x, float y);\nlong double    fmodl(long double x, long double y);\n\nfloating_point frexp (arithmetic value, int* exp);\nfloat          frexpf(float value, int* exp);\nlong double    frexpl(long double value, int* exp);\n\nfloating_point ldexp (arithmetic value, int exp);\nfloat          ldexpf(float value, int exp);\nlong double    ldexpl(long double value, int exp);\n\nfloating_point log (arithmetic x);\nfloat          logf(float x);\nlong double    logl(long double x);\n\nfloating_point log10 (arithmetic x);\nfloat          log10f(float x);\nlong double    log10l(long double x);\n\nfloating_point modf (floating_point value, floating_point* iptr);\nfloat          modff(float value, float* iptr);\nlong double    modfl(long double value, long double* iptr);\n\nfloating_point pow (arithmetic x, arithmetic y);\nfloat          powf(float x, float y);\nlong double    powl(long double x, long double y);\n\nfloating_point sin (arithmetic x);\nfloat          sinf(float x);\nlong double    sinl(long double x);\n\nfloating_point sinh (arithmetic x);\nfloat          sinhf(float x);\nlong double    sinhl(long double x);\n\nfloating_point sqrt (arithmetic x);\nfloat          sqrtf(float x);\nlong double    sqrtl(long double x);\n\nfloating_point tan (arithmetic x);\nfloat          tanf(float x);\nlong double    tanl(long double x);\n\nfloating_point tanh (arithmetic x);\nfloat          tanhf(float x);\nlong double    tanhl(long double x);\n\n//  C99\n\nbool signbit(arithmetic x);\n\nint fpclassify(arithmetic x);\n\nbool isfinite(arithmetic x);\nbool isinf(arithmetic x);\nbool isnan(arithmetic x);\nbool isnormal(arithmetic x);\n\nbool isgreater(arithmetic x, arithmetic y);\nbool isgreaterequal(arithmetic x, arithmetic y);\nbool isless(arithmetic x, arithmetic y);\nbool islessequal(arithmetic x, arithmetic y);\nbool islessgreater(arithmetic x, arithmetic y);\nbool isunordered(arithmetic x, arithmetic y);\n\nfloating_point acosh (arithmetic x);\nfloat          acoshf(float x);\nlong double    acoshl(long double x);\n\nfloating_point asinh (arithmetic x);\nfloat          asinhf(float x);\nlong double    asinhl(long double x);\n\nfloating_point atanh (arithmetic x);\nfloat          atanhf(float x);\nlong double    atanhl(long double x);\n\nfloating_point cbrt (arithmetic x);\nfloat          cbrtf(float x);\nlong double    cbrtl(long double x);\n\nfloating_point copysign (arithmetic x, arithmetic y);\nfloat          copysignf(float x, float y);\nlong double    copysignl(long double x, long double y);\n\nfloating_point erf (arithmetic x);\nfloat          erff(float x);\nlong double    erfl(long double x);\n\nfloating_point erfc (arithmetic x);\nfloat          erfcf(float x);\nlong double    erfcl(long double x);\n\nfloating_point exp2 (arithmetic x);\nfloat          exp2f(float x);\nlong double    exp2l(long double x);\n\nfloating_point expm1 (arithmetic x);\nfloat          expm1f(float x);\nlong double    expm1l(long double x);\n\nfloating_point fdim (arithmetic x, arithmetic y);\nfloat          fdimf(float x, float y);\nlong double    fdiml(long double x, long double y);\n\nfloating_point fma (arithmetic x, arithmetic y, arithmetic z);\nfloat          fmaf(float x, float y, float z);\nlong double    fmal(long double x, long double y, long double z);\n\nfloating_point fmax (arithmetic x, arithmetic y);\nfloat          fmaxf(float x, float y);\nlong double    fmaxl(long double x, long double y);\n\nfloating_point fmin (arithmetic x, arithmetic y);\nfloat          fminf(float x, float y);\nlong double    fminl(long double x, long double y);\n\nfloating_point hypot (arithmetic x, arithmetic y);\nfloat          hypotf(float x, float y);\nlong double    hypotl(long double x, long double y);\n\nint ilogb (arithmetic x);\nint ilogbf(float x);\nint ilogbl(long double x);\n\nfloating_point lgamma (arithmetic x);\nfloat          lgammaf(float x);\nlong double    lgammal(long double x);\n\nlong long llrint (arithmetic x);\nlong long llrintf(float x);\nlong long llrintl(long double x);\n\nlong long llround (arithmetic x);\nlong long llroundf(float x);\nlong long llroundl(long double x);\n\nfloating_point log1p (arithmetic x);\nfloat          log1pf(float x);\nlong double    log1pl(long double x);\n\nfloating_point log2 (arithmetic x);\nfloat          log2f(float x);\nlong double    log2l(long double x);\n\nfloating_point logb (arithmetic x);\nfloat          logbf(float x);\nlong double    logbl(long double x);\n\nlong lrint (arithmetic x);\nlong lrintf(float x);\nlong lrintl(long double x);\n\nlong lround (arithmetic x);\nlong lroundf(float x);\nlong lroundl(long double x);\n\ndouble      nan (const char* str);\nfloat       nanf(const char* str);\nlong double nanl(const char* str);\n\nfloating_point nearbyint (arithmetic x);\nfloat          nearbyintf(float x);\nlong double    nearbyintl(long double x);\n\nfloating_point nextafter (arithmetic x, arithmetic y);\nfloat          nextafterf(float x, float y);\nlong double    nextafterl(long double x, long double y);\n\nfloating_point nexttoward (arithmetic x, long double y);\nfloat          nexttowardf(float x, long double y);\nlong double    nexttowardl(long double x, long double y);\n\nfloating_point remainder (arithmetic x, arithmetic y);\nfloat          remainderf(float x, float y);\nlong double    remainderl(long double x, long double y);\n\nfloating_point remquo (arithmetic x, arithmetic y, int* pquo);\nfloat          remquof(float x, float y, int* pquo);\nlong double    remquol(long double x, long double y, int* pquo);\n\nfloating_point rint (arithmetic x);\nfloat          rintf(float x);\nlong double    rintl(long double x);\n\nfloating_point round (arithmetic x);\nfloat          roundf(float x);\nlong double    roundl(long double x);\n\nfloating_point scalbln (arithmetic x, long ex);\nfloat          scalblnf(float x, long ex);\nlong double    scalblnl(long double x, long ex);\n\nfloating_point scalbn (arithmetic x, int ex);\nfloat          scalbnf(float x, int ex);\nlong double    scalbnl(long double x, int ex);\n\nfloating_point tgamma (arithmetic x);\nfloat          tgammaf(float x);\nlong double    tgammal(long double x);\n\nfloating_point trunc (arithmetic x);\nfloat          truncf(float x);\nlong double    truncl(long double x);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <math.h>\n#include <type_traits>\n\n#ifdef _LIBCPP_MSVCRT\n#include \"support/win32/math_win32.h\"\n#endif\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n// signbit\n\n#ifdef signbit\n\ntemplate <class _A1>\n_LIBCPP_ALWAYS_INLINE\nbool\n__libcpp_signbit(_A1 __lcpp_x) _NOEXCEPT\n{\n    return signbit(__lcpp_x);\n}\n\n#undef signbit\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type\nsignbit(_A1 __lcpp_x) _NOEXCEPT\n{\n    return __libcpp_signbit((typename std::__promote<_A1>::type)__lcpp_x);\n}\n\n#endif  // signbit\n\n// fpclassify\n\n#ifdef fpclassify\n\ntemplate <class _A1>\n_LIBCPP_ALWAYS_INLINE\nint\n__libcpp_fpclassify(_A1 __lcpp_x) _NOEXCEPT\n{\n    return fpclassify(__lcpp_x);\n}\n\n#undef fpclassify\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename std::enable_if<std::is_arithmetic<_A1>::value, int>::type\nfpclassify(_A1 __lcpp_x) _NOEXCEPT\n{\n    return __libcpp_fpclassify((typename std::__promote<_A1>::type)__lcpp_x);\n}\n\n#endif  // fpclassify\n\n// isfinite\n\n#ifdef isfinite\n\ntemplate <class _A1>\n_LIBCPP_ALWAYS_INLINE\nbool\n__libcpp_isfinite(_A1 __lcpp_x) _NOEXCEPT\n{\n    return isfinite(__lcpp_x);\n}\n\n#undef isfinite\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type\nisfinite(_A1 __lcpp_x) _NOEXCEPT\n{\n    return __libcpp_isfinite((typename std::__promote<_A1>::type)__lcpp_x);\n}\n\n#endif  // isfinite\n\n// isinf\n\n#ifdef isinf\n\ntemplate <class _A1>\n_LIBCPP_ALWAYS_INLINE\nbool\n__libcpp_isinf(_A1 __lcpp_x) _NOEXCEPT\n{\n    return isinf(__lcpp_x);\n}\n\n#undef isinf\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type\nisinf(_A1 __lcpp_x) _NOEXCEPT\n{\n    return __libcpp_isinf((typename std::__promote<_A1>::type)__lcpp_x);\n}\n\n#endif  // isinf\n\n// isnan\n\n#ifdef isnan\n\ntemplate <class _A1>\n_LIBCPP_ALWAYS_INLINE\nbool\n__libcpp_isnan(_A1 __lcpp_x) _NOEXCEPT\n{\n    return isnan(__lcpp_x);\n}\n\n#undef isnan\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type\nisnan(_A1 __lcpp_x) _NOEXCEPT\n{\n    return __libcpp_isnan((typename std::__promote<_A1>::type)__lcpp_x);\n}\n\n#endif  // isnan\n\n// isnormal\n\n#ifdef isnormal\n\ntemplate <class _A1>\n_LIBCPP_ALWAYS_INLINE\nbool\n__libcpp_isnormal(_A1 __lcpp_x) _NOEXCEPT\n{\n    return isnormal(__lcpp_x);\n}\n\n#undef isnormal\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type\nisnormal(_A1 __lcpp_x) _NOEXCEPT\n{\n    return __libcpp_isnormal((typename std::__promote<_A1>::type)__lcpp_x);\n}\n\n#endif  // isnormal\n\n// isgreater\n\n#ifdef isgreater\n\ntemplate <class _A1, class _A2>\n_LIBCPP_ALWAYS_INLINE\nbool\n__libcpp_isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    return isgreater(__lcpp_x, __lcpp_y);\n}\n\n#undef isgreater\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename std::enable_if\n<\n    std::is_arithmetic<_A1>::value &&\n    std::is_arithmetic<_A2>::value,\n    bool\n>::type\nisgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename std::__promote<_A1, _A2>::type type;\n    return __libcpp_isgreater((type)__lcpp_x, (type)__lcpp_y);\n}\n\n#endif  // isgreater\n\n// isgreaterequal\n\n#ifdef isgreaterequal\n\ntemplate <class _A1, class _A2>\n_LIBCPP_ALWAYS_INLINE\nbool\n__libcpp_isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    return isgreaterequal(__lcpp_x, __lcpp_y);\n}\n\n#undef isgreaterequal\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename std::enable_if\n<\n    std::is_arithmetic<_A1>::value &&\n    std::is_arithmetic<_A2>::value,\n    bool\n>::type\nisgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename std::__promote<_A1, _A2>::type type;\n    return __libcpp_isgreaterequal((type)__lcpp_x, (type)__lcpp_y);\n}\n\n#endif  // isgreaterequal\n\n// isless\n\n#ifdef isless\n\ntemplate <class _A1, class _A2>\n_LIBCPP_ALWAYS_INLINE\nbool\n__libcpp_isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    return isless(__lcpp_x, __lcpp_y);\n}\n\n#undef isless\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename std::enable_if\n<\n    std::is_arithmetic<_A1>::value &&\n    std::is_arithmetic<_A2>::value,\n    bool\n>::type\nisless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename std::__promote<_A1, _A2>::type type;\n    return __libcpp_isless((type)__lcpp_x, (type)__lcpp_y);\n}\n\n#endif  // isless\n\n// islessequal\n\n#ifdef islessequal\n\ntemplate <class _A1, class _A2>\n_LIBCPP_ALWAYS_INLINE\nbool\n__libcpp_islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    return islessequal(__lcpp_x, __lcpp_y);\n}\n\n#undef islessequal\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename std::enable_if\n<\n    std::is_arithmetic<_A1>::value &&\n    std::is_arithmetic<_A2>::value,\n    bool\n>::type\nislessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename std::__promote<_A1, _A2>::type type;\n    return __libcpp_islessequal((type)__lcpp_x, (type)__lcpp_y);\n}\n\n#endif  // islessequal\n\n// islessgreater\n\n#ifdef islessgreater\n\ntemplate <class _A1, class _A2>\n_LIBCPP_ALWAYS_INLINE\nbool\n__libcpp_islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    return islessgreater(__lcpp_x, __lcpp_y);\n}\n\n#undef islessgreater\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename std::enable_if\n<\n    std::is_arithmetic<_A1>::value &&\n    std::is_arithmetic<_A2>::value,\n    bool\n>::type\nislessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename std::__promote<_A1, _A2>::type type;\n    return __libcpp_islessgreater((type)__lcpp_x, (type)__lcpp_y);\n}\n\n#endif  // islessgreater\n\n// isunordered\n\n#ifdef isunordered\n\ntemplate <class _A1, class _A2>\n_LIBCPP_ALWAYS_INLINE\nbool\n__libcpp_isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    return isunordered(__lcpp_x, __lcpp_y);\n}\n\n#undef isunordered\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename std::enable_if\n<\n    std::is_arithmetic<_A1>::value &&\n    std::is_arithmetic<_A2>::value,\n    bool\n>::type\nisunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename std::__promote<_A1, _A2>::type type;\n    return __libcpp_isunordered((type)__lcpp_x, (type)__lcpp_y);\n}\n\n#endif  // isunordered\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing ::signbit;\nusing ::fpclassify;\nusing ::isfinite;\nusing ::isinf;\nusing ::isnan;\nusing ::isnormal;\nusing ::isgreater;\nusing ::isgreaterequal;\nusing ::isless;\nusing ::islessequal;\nusing ::islessgreater;\nusing ::isunordered;\nusing ::isunordered;\n\nusing ::float_t;\nusing ::double_t;\n\n// abs\n\n#if defined(__sun__)\nusing ::abs;\n#endif\n\n#if !defined(_AIX) && !defined(__sun__)\ninline _LIBCPP_INLINE_VISIBILITY\nfloat\nabs(float __lcpp_x) _NOEXCEPT {return fabsf(__lcpp_x);}\n\ninline _LIBCPP_INLINE_VISIBILITY\ndouble\nabs(double __lcpp_x) _NOEXCEPT {return fabs(__lcpp_x);}\n\ninline _LIBCPP_INLINE_VISIBILITY\nlong double\nabs(long double __lcpp_x) _NOEXCEPT {return fabsl(__lcpp_x);}\n#endif // !defined(_AIX)\n\n#ifndef __sun__\n\n// acos\n\nusing ::acos;\nusing ::acosf;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       acos(float __lcpp_x) _NOEXCEPT       {return acosf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double acos(long double __lcpp_x) _NOEXCEPT {return acosl(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nacos(_A1 __lcpp_x) _NOEXCEPT {return acos((double)__lcpp_x);}\n\n// asin\n\nusing ::asin;\nusing ::asinf;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       asin(float __lcpp_x) _NOEXCEPT       {return asinf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double asin(long double __lcpp_x) _NOEXCEPT {return asinl(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nasin(_A1 __lcpp_x) _NOEXCEPT {return asin((double)__lcpp_x);}\n\n// atan\n\nusing ::atan;\nusing ::atanf;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       atan(float __lcpp_x) _NOEXCEPT       {return atanf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double atan(long double __lcpp_x) _NOEXCEPT {return atanl(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\natan(_A1 __lcpp_x) _NOEXCEPT {return atan((double)__lcpp_x);}\n\n// atan2\n\nusing ::atan2;\nusing ::atan2f;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       atan2(float __lcpp_y, float __lcpp_x) _NOEXCEPT             {return atan2f(__lcpp_y, __lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double atan2(long double __lcpp_y, long double __lcpp_x) _NOEXCEPT {return atan2l(__lcpp_y, __lcpp_x);}\n#endif\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __lazy_enable_if\n<\n    is_arithmetic<_A1>::value &&\n    is_arithmetic<_A2>::value,\n    __promote<_A1, _A2>\n>::type\natan2(_A1 __lcpp_y, _A2 __lcpp_x) _NOEXCEPT\n{\n    typedef typename __promote<_A1, _A2>::type __result_type;\n    static_assert((!(is_same<_A1, __result_type>::value &&\n                      is_same<_A2, __result_type>::value)), \"\");\n    return atan2((__result_type)__lcpp_y, (__result_type)__lcpp_x);\n}\n\n// ceil\n\nusing ::ceil;\nusing ::ceilf;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       ceil(float __lcpp_x) _NOEXCEPT       {return ceilf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double ceil(long double __lcpp_x) _NOEXCEPT {return ceill(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nceil(_A1 __lcpp_x) _NOEXCEPT {return ceil((double)__lcpp_x);}\n\n// cos\n\nusing ::cos;\nusing ::cosf;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       cos(float __lcpp_x) _NOEXCEPT       {return cosf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double cos(long double __lcpp_x) _NOEXCEPT {return cosl(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\ncos(_A1 __lcpp_x) _NOEXCEPT {return cos((double)__lcpp_x);}\n\n// cosh\n\nusing ::cosh;\nusing ::coshf;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       cosh(float __lcpp_x) _NOEXCEPT       {return coshf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double cosh(long double __lcpp_x) _NOEXCEPT {return coshl(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\ncosh(_A1 __lcpp_x) _NOEXCEPT {return cosh((double)__lcpp_x);}\n\n#endif // __sun__\n// exp\n\nusing ::exp;\nusing ::expf;\n\n#ifndef __sun__\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       exp(float __lcpp_x) _NOEXCEPT       {return expf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double exp(long double __lcpp_x) _NOEXCEPT {return expl(__lcpp_x);}\n#endif\n\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nexp(_A1 __lcpp_x) _NOEXCEPT {return exp((double)__lcpp_x);}\n\n// fabs\n\nusing ::fabs;\nusing ::fabsf;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       fabs(float __lcpp_x) _NOEXCEPT       {return fabsf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double fabs(long double __lcpp_x) _NOEXCEPT {return fabsl(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nfabs(_A1 __lcpp_x) _NOEXCEPT {return fabs((double)__lcpp_x);}\n\n// floor\n\nusing ::floor;\nusing ::floorf;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       floor(float __lcpp_x) _NOEXCEPT       {return floorf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double floor(long double __lcpp_x) _NOEXCEPT {return floorl(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nfloor(_A1 __lcpp_x) _NOEXCEPT {return floor((double)__lcpp_x);}\n\n// fmod\n\n#endif //__sun__\nusing ::fmod;\nusing ::fmodf;\n#ifndef __sun__\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       fmod(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fmodf(__lcpp_x, __lcpp_y);}\ninline _LIBCPP_INLINE_VISIBILITY long double fmod(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fmodl(__lcpp_x, __lcpp_y);}\n#endif\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __lazy_enable_if\n<\n    is_arithmetic<_A1>::value &&\n    is_arithmetic<_A2>::value,\n    __promote<_A1, _A2>\n>::type\nfmod(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename __promote<_A1, _A2>::type __result_type;\n    static_assert((!(is_same<_A1, __result_type>::value &&\n                      is_same<_A2, __result_type>::value)), \"\");\n    return fmod((__result_type)__lcpp_x, (__result_type)__lcpp_y);\n}\n\n\n// frexp\n\nusing ::frexp;\nusing ::frexpf;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       frexp(float __lcpp_x, int* __lcpp_e) _NOEXCEPT       {return frexpf(__lcpp_x, __lcpp_e);}\ninline _LIBCPP_INLINE_VISIBILITY long double frexp(long double __lcpp_x, int* __lcpp_e) _NOEXCEPT {return frexpl(__lcpp_x, __lcpp_e);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nfrexp(_A1 __lcpp_x, int* __lcpp_e) _NOEXCEPT {return frexp((double)__lcpp_x, __lcpp_e);}\n\n// ldexp\n\nusing ::ldexp;\nusing ::ldexpf;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       ldexp(float __lcpp_x, int __lcpp_e) _NOEXCEPT       {return ldexpf(__lcpp_x, __lcpp_e);}\ninline _LIBCPP_INLINE_VISIBILITY long double ldexp(long double __lcpp_x, int __lcpp_e) _NOEXCEPT {return ldexpl(__lcpp_x, __lcpp_e);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nldexp(_A1 __lcpp_x, int __lcpp_e) _NOEXCEPT {return ldexp((double)__lcpp_x, __lcpp_e);}\n\n// log\n\n#endif // __sun__\nusing ::log;\nusing ::logf;\n#ifndef __sun__\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       log(float __lcpp_x) _NOEXCEPT       {return logf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double log(long double __lcpp_x) _NOEXCEPT {return logl(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nlog(_A1 __lcpp_x) _NOEXCEPT {return log((double)__lcpp_x);}\n\n\n// log10\n\nusing ::log10;\nusing ::log10f;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       log10(float __lcpp_x) _NOEXCEPT       {return log10f(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double log10(long double __lcpp_x) _NOEXCEPT {return log10l(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nlog10(_A1 __lcpp_x) _NOEXCEPT {return log10((double)__lcpp_x);}\n\n// modf\n\nusing ::modf;\nusing ::modff;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       modf(float __lcpp_x, float* __lcpp_y) _NOEXCEPT             {return modff(__lcpp_x, __lcpp_y);}\ninline _LIBCPP_INLINE_VISIBILITY long double modf(long double __lcpp_x, long double* __lcpp_y) _NOEXCEPT {return modfl(__lcpp_x, __lcpp_y);}\n#endif\n\n// pow\n\n#endif // __sun__ \nusing ::pow;\nusing ::powf;\n\n#ifndef __sun__\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       pow(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return powf(__lcpp_x, __lcpp_y);}\ninline _LIBCPP_INLINE_VISIBILITY long double pow(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return powl(__lcpp_x, __lcpp_y);}\n#endif\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __lazy_enable_if\n<\n    is_arithmetic<_A1>::value &&\n    is_arithmetic<_A2>::value,\n    __promote<_A1, _A2>\n>::type\npow(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename __promote<_A1, _A2>::type __result_type;\n    static_assert((!(is_same<_A1, __result_type>::value &&\n                      is_same<_A2, __result_type>::value)), \"\");\n    return pow((__result_type)__lcpp_x, (__result_type)__lcpp_y);\n}\n\n// sin\n\nusing ::sin;\nusing ::sinf;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       sin(float __lcpp_x) _NOEXCEPT       {return sinf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double sin(long double __lcpp_x) _NOEXCEPT {return sinl(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nsin(_A1 __lcpp_x) _NOEXCEPT {return sin((double)__lcpp_x);}\n\n// sinh\n\nusing ::sinh;\nusing ::sinhf;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       sinh(float __lcpp_x) _NOEXCEPT       {return sinhf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double sinh(long double __lcpp_x) _NOEXCEPT {return sinhl(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nsinh(_A1 __lcpp_x) _NOEXCEPT {return sinh((double)__lcpp_x);}\n\n// sqrt\n\n#endif // __sun__\nusing ::sqrt;\nusing ::sqrtf;\n\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(__sun__) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       sqrt(float __lcpp_x) _NOEXCEPT       {return sqrtf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double sqrt(long double __lcpp_x) _NOEXCEPT {return sqrtl(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nsqrt(_A1 __lcpp_x) _NOEXCEPT {return sqrt((double)__lcpp_x);}\n\n// tan\n\nusing ::tan;\nusing ::tanf;\n#ifndef __sun__\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       tan(float __lcpp_x) _NOEXCEPT       {return tanf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double tan(long double __lcpp_x) _NOEXCEPT {return tanl(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\ntan(_A1 __lcpp_x) _NOEXCEPT {return tan((double)__lcpp_x);}\n\n// tanh\n\nusing ::tanh;\nusing ::tanhf;\n\n#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))\ninline _LIBCPP_INLINE_VISIBILITY float       tanh(float __lcpp_x) _NOEXCEPT       {return tanhf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double tanh(long double __lcpp_x) _NOEXCEPT {return tanhl(__lcpp_x);}\n#endif\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\ntanh(_A1 __lcpp_x) _NOEXCEPT {return tanh((double)__lcpp_x);}\n\n// acosh\n\n#ifndef _LIBCPP_MSVCRT\nusing ::acosh;\nusing ::acoshf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       acosh(float __lcpp_x) _NOEXCEPT       {return acoshf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double acosh(long double __lcpp_x) _NOEXCEPT {return acoshl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nacosh(_A1 __lcpp_x) _NOEXCEPT {return acosh((double)__lcpp_x);}\n#endif\n\n// asinh\n\n#ifndef _LIBCPP_MSVCRT\nusing ::asinh;\nusing ::asinhf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       asinh(float __lcpp_x) _NOEXCEPT       {return asinhf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double asinh(long double __lcpp_x) _NOEXCEPT {return asinhl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nasinh(_A1 __lcpp_x) _NOEXCEPT {return asinh((double)__lcpp_x);}\n#endif\n\n// atanh\n\n#ifndef _LIBCPP_MSVCRT\nusing ::atanh;\nusing ::atanhf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       atanh(float __lcpp_x) _NOEXCEPT       {return atanhf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double atanh(long double __lcpp_x) _NOEXCEPT {return atanhl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\natanh(_A1 __lcpp_x) _NOEXCEPT {return atanh((double)__lcpp_x);}\n#endif\n\n// cbrt\n\n#ifndef _LIBCPP_MSVCRT\nusing ::cbrt;\nusing ::cbrtf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       cbrt(float __lcpp_x) _NOEXCEPT       {return cbrtf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double cbrt(long double __lcpp_x) _NOEXCEPT {return cbrtl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\ncbrt(_A1 __lcpp_x) _NOEXCEPT {return cbrt((double)__lcpp_x);}\n#endif\n\n// copysign\n\nusing ::copysign;\nusing ::copysignf;\n\n#if !defined(_VC_CRT_MAJOR_VERSION) || (_VC_CRT_MAJOR_VERSION < 12)\ninline _LIBCPP_INLINE_VISIBILITY float copysign(float __lcpp_x,\n                                                float __lcpp_y) _NOEXCEPT {\n  return copysignf(__lcpp_x, __lcpp_y);\n}\ninline _LIBCPP_INLINE_VISIBILITY long double\ncopysign(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {\n  return copysignl(__lcpp_x, __lcpp_y);\n}\n#endif\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __lazy_enable_if\n<\n    is_arithmetic<_A1>::value &&\n    is_arithmetic<_A2>::value,\n    __promote<_A1, _A2>\n>::type\ncopysign(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename __promote<_A1, _A2>::type __result_type;\n    static_assert((!(is_same<_A1, __result_type>::value &&\n                      is_same<_A2, __result_type>::value)), \"\");\n    return copysign((__result_type)__lcpp_x, (__result_type)__lcpp_y);\n}\n\n#ifndef _LIBCPP_MSVCRT\n\n// erf\n\nusing ::erf;\nusing ::erff;\n\ninline _LIBCPP_INLINE_VISIBILITY float       erf(float __lcpp_x) _NOEXCEPT       {return erff(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double erf(long double __lcpp_x) _NOEXCEPT {return erfl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nerf(_A1 __lcpp_x) _NOEXCEPT {return erf((double)__lcpp_x);}\n\n// erfc\n\nusing ::erfc;\nusing ::erfcf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       erfc(float __lcpp_x) _NOEXCEPT       {return erfcf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double erfc(long double __lcpp_x) _NOEXCEPT {return erfcl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nerfc(_A1 __lcpp_x) _NOEXCEPT {return erfc((double)__lcpp_x);}\n\n// exp2\n\nusing ::exp2;\nusing ::exp2f;\n\ninline _LIBCPP_INLINE_VISIBILITY float       exp2(float __lcpp_x) _NOEXCEPT       {return exp2f(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double exp2(long double __lcpp_x) _NOEXCEPT {return exp2l(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nexp2(_A1 __lcpp_x) _NOEXCEPT {return exp2((double)__lcpp_x);}\n\n// expm1\n\nusing ::expm1;\nusing ::expm1f;\n\ninline _LIBCPP_INLINE_VISIBILITY float       expm1(float __lcpp_x) _NOEXCEPT       {return expm1f(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double expm1(long double __lcpp_x) _NOEXCEPT {return expm1l(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nexpm1(_A1 __lcpp_x) _NOEXCEPT {return expm1((double)__lcpp_x);}\n\n// fdim\n\nusing ::fdim;\nusing ::fdimf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       fdim(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fdimf(__lcpp_x, __lcpp_y);}\ninline _LIBCPP_INLINE_VISIBILITY long double fdim(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fdiml(__lcpp_x, __lcpp_y);}\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __lazy_enable_if\n<\n    is_arithmetic<_A1>::value &&\n    is_arithmetic<_A2>::value,\n    __promote<_A1, _A2>\n>::type\nfdim(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename __promote<_A1, _A2>::type __result_type;\n    static_assert((!(is_same<_A1, __result_type>::value &&\n                      is_same<_A2, __result_type>::value)), \"\");\n    return fdim((__result_type)__lcpp_x, (__result_type)__lcpp_y);\n}\n\n// fma\n\nusing ::fmaf;\nusing ::fma;\n\ninline _LIBCPP_INLINE_VISIBILITY float       fma(float __lcpp_x, float __lcpp_y, float __lcpp_z) _NOEXCEPT                   {return fmaf(__lcpp_x, __lcpp_y, __lcpp_z);}\ninline _LIBCPP_INLINE_VISIBILITY long double fma(long double __lcpp_x, long double __lcpp_y, long double __lcpp_z) _NOEXCEPT {return fmal(__lcpp_x, __lcpp_y, __lcpp_z);}\n\ntemplate <class _A1, class _A2, class _A3>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __lazy_enable_if\n<\n    is_arithmetic<_A1>::value &&\n    is_arithmetic<_A2>::value &&\n    is_arithmetic<_A3>::value,\n    __promote<_A1, _A2, _A3>\n>::type\nfma(_A1 __lcpp_x, _A2 __lcpp_y, _A3 __lcpp_z) _NOEXCEPT\n{\n    typedef typename __promote<_A1, _A2, _A3>::type __result_type;\n    static_assert((!(is_same<_A1, __result_type>::value &&\n                      is_same<_A2, __result_type>::value &&\n                      is_same<_A3, __result_type>::value)), \"\");\n    return fma((__result_type)__lcpp_x, (__result_type)__lcpp_y, (__result_type)__lcpp_z);\n}\n\n// fmax\n\nusing ::fmax;\nusing ::fmaxf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       fmax(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fmaxf(__lcpp_x, __lcpp_y);}\ninline _LIBCPP_INLINE_VISIBILITY long double fmax(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fmaxl(__lcpp_x, __lcpp_y);}\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __lazy_enable_if\n<\n    is_arithmetic<_A1>::value &&\n    is_arithmetic<_A2>::value,\n    __promote<_A1, _A2>\n>::type\nfmax(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename __promote<_A1, _A2>::type __result_type;\n    static_assert((!(is_same<_A1, __result_type>::value &&\n                      is_same<_A2, __result_type>::value)), \"\");\n    return fmax((__result_type)__lcpp_x, (__result_type)__lcpp_y);\n}\n\n// fmin\n\nusing ::fmin;\nusing ::fminf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       fmin(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fminf(__lcpp_x, __lcpp_y);}\ninline _LIBCPP_INLINE_VISIBILITY long double fmin(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fminl(__lcpp_x, __lcpp_y);}\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __lazy_enable_if\n<\n    is_arithmetic<_A1>::value &&\n    is_arithmetic<_A2>::value,\n    __promote<_A1, _A2>\n>::type\nfmin(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename __promote<_A1, _A2>::type __result_type;\n    static_assert((!(is_same<_A1, __result_type>::value &&\n                      is_same<_A2, __result_type>::value)), \"\");\n    return fmin((__result_type)__lcpp_x, (__result_type)__lcpp_y);\n}\n\n// hypot\n\nusing ::hypot;\nusing ::hypotf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       hypot(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return hypotf(__lcpp_x, __lcpp_y);}\ninline _LIBCPP_INLINE_VISIBILITY long double hypot(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return hypotl(__lcpp_x, __lcpp_y);}\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __lazy_enable_if\n<\n    is_arithmetic<_A1>::value &&\n    is_arithmetic<_A2>::value,\n    __promote<_A1, _A2>\n>::type\nhypot(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename __promote<_A1, _A2>::type __result_type;\n    static_assert((!(is_same<_A1, __result_type>::value &&\n                      is_same<_A2, __result_type>::value)), \"\");\n    return hypot((__result_type)__lcpp_x, (__result_type)__lcpp_y);\n}\n\n// ilogb\n\nusing ::ilogb;\nusing ::ilogbf;\n\ninline _LIBCPP_INLINE_VISIBILITY int ilogb(float __lcpp_x) _NOEXCEPT       {return ilogbf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY int ilogb(long double __lcpp_x) _NOEXCEPT {return ilogbl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, int>::type\nilogb(_A1 __lcpp_x) _NOEXCEPT {return ilogb((double)__lcpp_x);}\n\n// lgamma\n\nusing ::lgamma;\nusing ::lgammaf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       lgamma(float __lcpp_x) _NOEXCEPT       {return lgammaf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double lgamma(long double __lcpp_x) _NOEXCEPT {return lgammal(__lcpp_x);}\n\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nlgamma(_A1 __lcpp_x) _NOEXCEPT {return lgamma((double)__lcpp_x);}\n\n\n// llrint\n\nusing ::llrint;\nusing ::llrintf;\n\ninline _LIBCPP_INLINE_VISIBILITY long long llrint(float __lcpp_x) _NOEXCEPT       {return llrintf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long long llrint(long double __lcpp_x) _NOEXCEPT {return llrintl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, long long>::type\nllrint(_A1 __lcpp_x) _NOEXCEPT {return llrint((double)__lcpp_x);}\n\n// llround\n\nusing ::llround;\nusing ::llroundf;\n\ninline _LIBCPP_INLINE_VISIBILITY long long llround(float __lcpp_x) _NOEXCEPT       {return llroundf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long long llround(long double __lcpp_x) _NOEXCEPT {return llroundl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, long long>::type\nllround(_A1 __lcpp_x) _NOEXCEPT {return llround((double)__lcpp_x);}\n\n// log1p\n\nusing ::log1p;\nusing ::log1pf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       log1p(float __lcpp_x) _NOEXCEPT       {return log1pf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double log1p(long double __lcpp_x) _NOEXCEPT {return log1pl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nlog1p(_A1 __lcpp_x) _NOEXCEPT {return log1p((double)__lcpp_x);}\n\n// log2\n\nusing ::log2;\nusing ::log2f;\n\ninline _LIBCPP_INLINE_VISIBILITY float       log2(float __lcpp_x) _NOEXCEPT       {return log2f(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double log2(long double __lcpp_x) _NOEXCEPT {return log2l(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nlog2(_A1 __lcpp_x) _NOEXCEPT {return log2((double)__lcpp_x);}\n\n// logb\n\nusing ::logb;\nusing ::logbf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       logb(float __lcpp_x) _NOEXCEPT       {return logbf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double logb(long double __lcpp_x) _NOEXCEPT {return logbl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nlogb(_A1 __lcpp_x) _NOEXCEPT {return logb((double)__lcpp_x);}\n\n// lrint\n\nusing ::lrint;\nusing ::lrintf;\n\ninline _LIBCPP_INLINE_VISIBILITY long lrint(float __lcpp_x) _NOEXCEPT       {return lrintf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long lrint(long double __lcpp_x) _NOEXCEPT {return lrintl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, long>::type\nlrint(_A1 __lcpp_x) _NOEXCEPT {return lrint((double)__lcpp_x);}\n\n// lround\n\nusing ::lround;\nusing ::lroundf;\n\ninline _LIBCPP_INLINE_VISIBILITY long lround(float __lcpp_x) _NOEXCEPT       {return lroundf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long lround(long double __lcpp_x) _NOEXCEPT {return lroundl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, long>::type\nlround(_A1 __lcpp_x) _NOEXCEPT {return lround((double)__lcpp_x);}\n\n#endif // _LIBCPP_MSVCRT\n#endif // __sun__\n\n// nan\n\n#ifndef _LIBCPP_MSVCRT\nusing ::nan;\nusing ::nanf;\n#endif // _LIBCPP_MSVCRT\n\n#ifndef __sun__\n#ifndef _LIBCPP_MSVCRT\n\n// nearbyint\n\nusing ::nearbyint;\nusing ::nearbyintf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       nearbyint(float __lcpp_x) _NOEXCEPT       {return nearbyintf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double nearbyint(long double __lcpp_x) _NOEXCEPT {return nearbyintl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nnearbyint(_A1 __lcpp_x) _NOEXCEPT {return nearbyint((double)__lcpp_x);}\n\n// nextafter\n\nusing ::nextafter;\nusing ::nextafterf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       nextafter(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return nextafterf(__lcpp_x, __lcpp_y);}\ninline _LIBCPP_INLINE_VISIBILITY long double nextafter(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nextafterl(__lcpp_x, __lcpp_y);}\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __lazy_enable_if\n<\n    is_arithmetic<_A1>::value &&\n    is_arithmetic<_A2>::value,\n    __promote<_A1, _A2>\n>::type\nnextafter(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename __promote<_A1, _A2>::type __result_type;\n    static_assert((!(is_same<_A1, __result_type>::value &&\n                      is_same<_A2, __result_type>::value)), \"\");\n    return nextafter((__result_type)__lcpp_x, (__result_type)__lcpp_y);\n}\n\n// nexttoward\n\nusing ::nexttoward;\nusing ::nexttowardf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       nexttoward(float __lcpp_x, long double __lcpp_y) _NOEXCEPT       {return nexttowardf(__lcpp_x, __lcpp_y);}\ninline _LIBCPP_INLINE_VISIBILITY long double nexttoward(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nexttowardl(__lcpp_x, __lcpp_y);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nnexttoward(_A1 __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nexttoward((double)__lcpp_x, __lcpp_y);}\n\n// remainder\n\nusing ::remainder;\nusing ::remainderf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       remainder(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return remainderf(__lcpp_x, __lcpp_y);}\ninline _LIBCPP_INLINE_VISIBILITY long double remainder(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return remainderl(__lcpp_x, __lcpp_y);}\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __lazy_enable_if\n<\n    is_arithmetic<_A1>::value &&\n    is_arithmetic<_A2>::value,\n    __promote<_A1, _A2>\n>::type\nremainder(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT\n{\n    typedef typename __promote<_A1, _A2>::type __result_type;\n    static_assert((!(is_same<_A1, __result_type>::value &&\n                      is_same<_A2, __result_type>::value)), \"\");\n    return remainder((__result_type)__lcpp_x, (__result_type)__lcpp_y);\n}\n\n// remquo\n\nusing ::remquo;\nusing ::remquof;\n\ninline _LIBCPP_INLINE_VISIBILITY float       remquo(float __lcpp_x, float __lcpp_y, int* __lcpp_z) _NOEXCEPT             {return remquof(__lcpp_x, __lcpp_y, __lcpp_z);}\ninline _LIBCPP_INLINE_VISIBILITY long double remquo(long double __lcpp_x, long double __lcpp_y, int* __lcpp_z) _NOEXCEPT {return remquol(__lcpp_x, __lcpp_y, __lcpp_z);}\n\ntemplate <class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __lazy_enable_if\n<\n    is_arithmetic<_A1>::value &&\n    is_arithmetic<_A2>::value,\n    __promote<_A1, _A2>\n>::type\nremquo(_A1 __lcpp_x, _A2 __lcpp_y, int* __lcpp_z) _NOEXCEPT\n{\n    typedef typename __promote<_A1, _A2>::type __result_type;\n    static_assert((!(is_same<_A1, __result_type>::value &&\n                      is_same<_A2, __result_type>::value)), \"\");\n    return remquo((__result_type)__lcpp_x, (__result_type)__lcpp_y, __lcpp_z);\n}\n\n// rint\n\nusing ::rint;\nusing ::rintf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       rint(float __lcpp_x) _NOEXCEPT       {return rintf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double rint(long double __lcpp_x) _NOEXCEPT {return rintl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nrint(_A1 __lcpp_x) _NOEXCEPT {return rint((double)__lcpp_x);}\n\n// round\n\nusing ::round;\nusing ::roundf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       round(float __lcpp_x) _NOEXCEPT       {return roundf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double round(long double __lcpp_x) _NOEXCEPT {return roundl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nround(_A1 __lcpp_x) _NOEXCEPT {return round((double)__lcpp_x);}\n\n// scalbln\n\nusing ::scalbln;\nusing ::scalblnf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       scalbln(float __lcpp_x, long __lcpp_y) _NOEXCEPT       {return scalblnf(__lcpp_x, __lcpp_y);}\ninline _LIBCPP_INLINE_VISIBILITY long double scalbln(long double __lcpp_x, long __lcpp_y) _NOEXCEPT {return scalblnl(__lcpp_x, __lcpp_y);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nscalbln(_A1 __lcpp_x, long __lcpp_y) _NOEXCEPT {return scalbln((double)__lcpp_x, __lcpp_y);}\n\n// scalbn\n\nusing ::scalbn;\nusing ::scalbnf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       scalbn(float __lcpp_x, int __lcpp_y) _NOEXCEPT       {return scalbnf(__lcpp_x, __lcpp_y);}\ninline _LIBCPP_INLINE_VISIBILITY long double scalbn(long double __lcpp_x, int __lcpp_y) _NOEXCEPT {return scalbnl(__lcpp_x, __lcpp_y);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\nscalbn(_A1 __lcpp_x, int __lcpp_y) _NOEXCEPT {return scalbn((double)__lcpp_x, __lcpp_y);}\n\n// tgamma\n\nusing ::tgamma;\nusing ::tgammaf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       tgamma(float __lcpp_x) _NOEXCEPT       {return tgammaf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double tgamma(long double __lcpp_x) _NOEXCEPT {return tgammal(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\ntgamma(_A1 __lcpp_x) _NOEXCEPT {return tgamma((double)__lcpp_x);}\n\n// trunc\n\nusing ::trunc;\nusing ::truncf;\n\ninline _LIBCPP_INLINE_VISIBILITY float       trunc(float __lcpp_x) _NOEXCEPT       {return truncf(__lcpp_x);}\ninline _LIBCPP_INLINE_VISIBILITY long double trunc(long double __lcpp_x) _NOEXCEPT {return truncl(__lcpp_x);}\n\ntemplate <class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<is_integral<_A1>::value, double>::type\ntrunc(_A1 __lcpp_x) _NOEXCEPT {return trunc((double)__lcpp_x);}\n\n#endif // !_LIBCPP_MSVCRT\n\nusing ::acosl;\nusing ::asinl;\nusing ::atanl;\nusing ::atan2l;\nusing ::ceill;\nusing ::cosl;\nusing ::coshl;\nusing ::expl;\nusing ::fabsl;\nusing ::floorl;\nusing ::fmodl;\nusing ::frexpl;\nusing ::ldexpl;\nusing ::logl;\nusing ::log10l;\nusing ::modfl;\nusing ::powl;\nusing ::sinl;\nusing ::sinhl;\nusing ::sqrtl;\nusing ::tanl;\n#ifndef _LIBCPP_MSVCRT\nusing ::tanhl;\nusing ::acoshl;\nusing ::asinhl;\nusing ::atanhl;\nusing ::cbrtl;\n#endif  // !_LIBCPP_MSVCRT\nusing ::copysignl;\n#ifndef _LIBCPP_MSVCRT\nusing ::erfl;\nusing ::erfcl;\nusing ::exp2l;\nusing ::expm1l;\nusing ::fdiml;\nusing ::fmal;\nusing ::fmaxl;\nusing ::fminl;\nusing ::hypotl;\nusing ::ilogbl;\nusing ::lgammal;\nusing ::llrintl;\nusing ::llroundl;\nusing ::log1pl;\nusing ::log2l;\nusing ::logbl;\nusing ::lrintl;\nusing ::lroundl;\nusing ::nanl;\nusing ::nearbyintl;\nusing ::nextafterl;\nusing ::nexttowardl;\nusing ::remainderl;\nusing ::remquol;\nusing ::rintl;\nusing ::roundl;\nusing ::scalblnl;\nusing ::scalbnl;\nusing ::tgammal;\nusing ::truncl;\n#endif // !_LIBCPP_MSVCRT\n\n#else \nusing ::lgamma;\nusing ::lgammaf;\n#endif // __sun__\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CMATH\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/codecvt",
    "content": "// -*- C++ -*-\n//===-------------------------- codecvt -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CODECVT\n#define _LIBCPP_CODECVT\n\n/*\n    codecvt synopsis\n\nnamespace std\n{\n\nenum codecvt_mode\n{\n    consume_header = 4,\n    generate_header = 2,\n    little_endian = 1\n};\n\ntemplate <class Elem, unsigned long Maxcode = 0x10ffff,\n          codecvt_mode Mode = (codecvt_mode)0>\nclass codecvt_utf8\n    : public codecvt<Elem, char, mbstate_t>\n{\n    explicit codecvt_utf8(size_t refs = 0);\n    ~codecvt_utf8();\n};\n\ntemplate <class Elem, unsigned long Maxcode = 0x10ffff,\n          codecvt_mode Mode = (codecvt_mode)0>\nclass codecvt_utf16\n    : public codecvt<Elem, char, mbstate_t>\n{\n    explicit codecvt_utf16(size_t refs = 0);\n    ~codecvt_utf16();\n};\n\ntemplate <class Elem, unsigned long Maxcode = 0x10ffff,\n          codecvt_mode Mode = (codecvt_mode)0>\nclass codecvt_utf8_utf16\n    : public codecvt<Elem, char, mbstate_t>\n{\n    explicit codecvt_utf8_utf16(size_t refs = 0);\n    ~codecvt_utf8_utf16();\n};\n\n}  // std\n\n*/\n\n#include <__config>\n#include <__locale>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nenum codecvt_mode\n{\n    consume_header = 4,\n    generate_header = 2,\n    little_endian = 1\n};\n\n// codecvt_utf8\n\ntemplate <class _Elem> class __codecvt_utf8;\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS __codecvt_utf8<wchar_t>\n    : public codecvt<wchar_t, char, mbstate_t>\n{\n    unsigned long _Maxcode_;\n    codecvt_mode _Mode_;\npublic:\n    typedef wchar_t   intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode,\n                            codecvt_mode _Mode)\n        : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),\n          _Mode_(_Mode) {}\nprotected:\n    virtual result\n        do_out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result\n        do_in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result\n        do_unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const throw();\n    virtual bool do_always_noconv() const throw();\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,\n                          size_t __mx) const;\n    virtual int do_max_length() const throw();\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS __codecvt_utf8<char16_t>\n    : public codecvt<char16_t, char, mbstate_t>\n{\n    unsigned long _Maxcode_;\n    codecvt_mode _Mode_;\npublic:\n    typedef char16_t  intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode,\n                            codecvt_mode _Mode)\n        : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),\n          _Mode_(_Mode) {}\nprotected:\n    virtual result\n        do_out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result\n        do_in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result\n        do_unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const throw();\n    virtual bool do_always_noconv() const throw();\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,\n                          size_t __mx) const;\n    virtual int do_max_length() const throw();\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS __codecvt_utf8<char32_t>\n    : public codecvt<char32_t, char, mbstate_t>\n{\n    unsigned long _Maxcode_;\n    codecvt_mode _Mode_;\npublic:\n    typedef char32_t  intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode,\n                            codecvt_mode _Mode)\n        : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),\n          _Mode_(_Mode) {}\nprotected:\n    virtual result\n        do_out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result\n        do_in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result\n        do_unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const throw();\n    virtual bool do_always_noconv() const throw();\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,\n                          size_t __mx) const;\n    virtual int do_max_length() const throw();\n};\n\ntemplate <class _Elem, unsigned long _Maxcode = 0x10ffff,\n          codecvt_mode _Mode = (codecvt_mode)0>\nclass _LIBCPP_TYPE_VIS_ONLY codecvt_utf8\n    : public __codecvt_utf8<_Elem>\n{\npublic:\n    _LIBCPP_ALWAYS_INLINE\n    explicit codecvt_utf8(size_t __refs = 0)\n        : __codecvt_utf8<_Elem>(__refs, _Maxcode, _Mode) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    ~codecvt_utf8() {}\n};\n\n// codecvt_utf16\n\ntemplate <class _Elem, bool _LittleEndian> class __codecvt_utf16;\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS __codecvt_utf16<wchar_t, false>\n    : public codecvt<wchar_t, char, mbstate_t>\n{\n    unsigned long _Maxcode_;\n    codecvt_mode _Mode_;\npublic:\n    typedef wchar_t   intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,\n                            codecvt_mode _Mode)\n        : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),\n          _Mode_(_Mode) {}\nprotected:\n    virtual result\n        do_out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result\n        do_in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result\n        do_unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const throw();\n    virtual bool do_always_noconv() const throw();\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,\n                          size_t __mx) const;\n    virtual int do_max_length() const throw();\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS __codecvt_utf16<wchar_t, true>\n    : public codecvt<wchar_t, char, mbstate_t>\n{\n    unsigned long _Maxcode_;\n    codecvt_mode _Mode_;\npublic:\n    typedef wchar_t   intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,\n                            codecvt_mode _Mode)\n        : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),\n          _Mode_(_Mode) {}\nprotected:\n    virtual result\n        do_out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result\n        do_in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result\n        do_unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const throw();\n    virtual bool do_always_noconv() const throw();\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,\n                          size_t __mx) const;\n    virtual int do_max_length() const throw();\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS __codecvt_utf16<char16_t, false>\n    : public codecvt<char16_t, char, mbstate_t>\n{\n    unsigned long _Maxcode_;\n    codecvt_mode _Mode_;\npublic:\n    typedef char16_t  intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,\n                            codecvt_mode _Mode)\n        : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),\n          _Mode_(_Mode) {}\nprotected:\n    virtual result\n        do_out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result\n        do_in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result\n        do_unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const throw();\n    virtual bool do_always_noconv() const throw();\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,\n                          size_t __mx) const;\n    virtual int do_max_length() const throw();\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS __codecvt_utf16<char16_t, true>\n    : public codecvt<char16_t, char, mbstate_t>\n{\n    unsigned long _Maxcode_;\n    codecvt_mode _Mode_;\npublic:\n    typedef char16_t  intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,\n                            codecvt_mode _Mode)\n        : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),\n          _Mode_(_Mode) {}\nprotected:\n    virtual result\n        do_out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result\n        do_in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result\n        do_unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const throw();\n    virtual bool do_always_noconv() const throw();\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,\n                          size_t __mx) const;\n    virtual int do_max_length() const throw();\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS __codecvt_utf16<char32_t, false>\n    : public codecvt<char32_t, char, mbstate_t>\n{\n    unsigned long _Maxcode_;\n    codecvt_mode _Mode_;\npublic:\n    typedef char32_t  intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,\n                            codecvt_mode _Mode)\n        : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),\n          _Mode_(_Mode) {}\nprotected:\n    virtual result\n        do_out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result\n        do_in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result\n        do_unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const throw();\n    virtual bool do_always_noconv() const throw();\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,\n                          size_t __mx) const;\n    virtual int do_max_length() const throw();\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS __codecvt_utf16<char32_t, true>\n    : public codecvt<char32_t, char, mbstate_t>\n{\n    unsigned long _Maxcode_;\n    codecvt_mode _Mode_;\npublic:\n    typedef char32_t  intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,\n                            codecvt_mode _Mode)\n        : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),\n          _Mode_(_Mode) {}\nprotected:\n    virtual result\n        do_out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result\n        do_in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result\n        do_unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const throw();\n    virtual bool do_always_noconv() const throw();\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,\n                          size_t __mx) const;\n    virtual int do_max_length() const throw();\n};\n\ntemplate <class _Elem, unsigned long _Maxcode = 0x10ffff,\n          codecvt_mode _Mode = (codecvt_mode)0>\nclass _LIBCPP_TYPE_VIS_ONLY codecvt_utf16\n    : public __codecvt_utf16<_Elem, _Mode & little_endian>\n{\npublic:\n    _LIBCPP_ALWAYS_INLINE\n    explicit codecvt_utf16(size_t __refs = 0)\n        : __codecvt_utf16<_Elem, _Mode & little_endian>(__refs, _Maxcode, _Mode) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    ~codecvt_utf16() {}\n};\n\n// codecvt_utf8_utf16\n\ntemplate <class _Elem> class __codecvt_utf8_utf16;\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<wchar_t>\n    : public codecvt<wchar_t, char, mbstate_t>\n{\n    unsigned long _Maxcode_;\n    codecvt_mode _Mode_;\npublic:\n    typedef wchar_t   intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode,\n                            codecvt_mode _Mode)\n        : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),\n          _Mode_(_Mode) {}\nprotected:\n    virtual result\n        do_out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result\n        do_in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result\n        do_unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const throw();\n    virtual bool do_always_noconv() const throw();\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,\n                          size_t __mx) const;\n    virtual int do_max_length() const throw();\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<char32_t>\n    : public codecvt<char32_t, char, mbstate_t>\n{\n    unsigned long _Maxcode_;\n    codecvt_mode _Mode_;\npublic:\n    typedef char32_t  intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode,\n                            codecvt_mode _Mode)\n        : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),\n          _Mode_(_Mode) {}\nprotected:\n    virtual result\n        do_out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result\n        do_in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result\n        do_unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const throw();\n    virtual bool do_always_noconv() const throw();\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,\n                          size_t __mx) const;\n    virtual int do_max_length() const throw();\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<char16_t>\n    : public codecvt<char16_t, char, mbstate_t>\n{\n    unsigned long _Maxcode_;\n    codecvt_mode _Mode_;\npublic:\n    typedef char16_t  intern_type;\n    typedef char      extern_type;\n    typedef mbstate_t state_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode,\n                            codecvt_mode _Mode)\n        : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),\n          _Mode_(_Mode) {}\nprotected:\n    virtual result\n        do_out(state_type& __st,\n               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,\n               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual result\n        do_in(state_type& __st,\n              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,\n              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;\n    virtual result\n        do_unshift(state_type& __st,\n                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;\n    virtual int do_encoding() const throw();\n    virtual bool do_always_noconv() const throw();\n    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,\n                          size_t __mx) const;\n    virtual int do_max_length() const throw();\n};\n\ntemplate <class _Elem, unsigned long _Maxcode = 0x10ffff,\n          codecvt_mode _Mode = (codecvt_mode)0>\nclass _LIBCPP_TYPE_VIS_ONLY codecvt_utf8_utf16\n    : public __codecvt_utf8_utf16<_Elem>\n{\npublic:\n    _LIBCPP_ALWAYS_INLINE\n    explicit codecvt_utf8_utf16(size_t __refs = 0)\n        : __codecvt_utf8_utf16<_Elem>(__refs, _Maxcode, _Mode) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    ~codecvt_utf8_utf16() {}\n};\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CODECVT\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/complex",
    "content": "// -*- C++ -*-\n//===--------------------------- complex ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_COMPLEX\n#define _LIBCPP_COMPLEX\n\n/*\n    complex synopsis\n\nnamespace std\n{\n\ntemplate<class T>\nclass complex\n{\npublic:\n    typedef T value_type;\n\n    complex(const T& re = T(), const T& im = T()); // constexpr in C++14\n    complex(const complex&);  // constexpr in C++14\n    template<class X> complex(const complex<X>&);  // constexpr in C++14\n\n    T real() const; // constexpr in C++14\n    T imag() const; // constexpr in C++14\n\n    void real(T);\n    void imag(T);\n\n    complex<T>& operator= (const T&);\n    complex<T>& operator+=(const T&);\n    complex<T>& operator-=(const T&);\n    complex<T>& operator*=(const T&);\n    complex<T>& operator/=(const T&);\n\n    complex& operator=(const complex&);\n    template<class X> complex<T>& operator= (const complex<X>&);\n    template<class X> complex<T>& operator+=(const complex<X>&);\n    template<class X> complex<T>& operator-=(const complex<X>&);\n    template<class X> complex<T>& operator*=(const complex<X>&);\n    template<class X> complex<T>& operator/=(const complex<X>&);\n};\n\ntemplate<>\nclass complex<float>\n{\npublic:\n    typedef float value_type;\n\n    constexpr complex(float re = 0.0f, float im = 0.0f);\n    explicit constexpr complex(const complex<double>&);\n    explicit constexpr complex(const complex<long double>&);\n\n    constexpr float real() const;\n    void real(float);\n    constexpr float imag() const;\n    void imag(float);\n\n    complex<float>& operator= (float);\n    complex<float>& operator+=(float);\n    complex<float>& operator-=(float);\n    complex<float>& operator*=(float);\n    complex<float>& operator/=(float);\n\n    complex<float>& operator=(const complex<float>&);\n    template<class X> complex<float>& operator= (const complex<X>&);\n    template<class X> complex<float>& operator+=(const complex<X>&);\n    template<class X> complex<float>& operator-=(const complex<X>&);\n    template<class X> complex<float>& operator*=(const complex<X>&);\n    template<class X> complex<float>& operator/=(const complex<X>&);\n};\n\ntemplate<>\nclass complex<double>\n{\npublic:\n    typedef double value_type;\n\n    constexpr complex(double re = 0.0, double im = 0.0);\n    constexpr complex(const complex<float>&);\n    explicit constexpr complex(const complex<long double>&);\n\n    constexpr double real() const;\n    void real(double);\n    constexpr double imag() const;\n    void imag(double);\n\n    complex<double>& operator= (double);\n    complex<double>& operator+=(double);\n    complex<double>& operator-=(double);\n    complex<double>& operator*=(double);\n    complex<double>& operator/=(double);\n    complex<double>& operator=(const complex<double>&);\n\n    template<class X> complex<double>& operator= (const complex<X>&);\n    template<class X> complex<double>& operator+=(const complex<X>&);\n    template<class X> complex<double>& operator-=(const complex<X>&);\n    template<class X> complex<double>& operator*=(const complex<X>&);\n    template<class X> complex<double>& operator/=(const complex<X>&);\n};\n\ntemplate<>\nclass complex<long double>\n{\npublic:\n    typedef long double value_type;\n\n    constexpr complex(long double re = 0.0L, long double im = 0.0L);\n    constexpr complex(const complex<float>&);\n    constexpr complex(const complex<double>&);\n\n    constexpr long double real() const;\n    void real(long double);\n    constexpr long double imag() const;\n    void imag(long double);\n\n    complex<long double>& operator=(const complex<long double>&);\n    complex<long double>& operator= (long double);\n    complex<long double>& operator+=(long double);\n    complex<long double>& operator-=(long double);\n    complex<long double>& operator*=(long double);\n    complex<long double>& operator/=(long double);\n\n    template<class X> complex<long double>& operator= (const complex<X>&);\n    template<class X> complex<long double>& operator+=(const complex<X>&);\n    template<class X> complex<long double>& operator-=(const complex<X>&);\n    template<class X> complex<long double>& operator*=(const complex<X>&);\n    template<class X> complex<long double>& operator/=(const complex<X>&);\n};\n\n// 26.3.6 operators:\ntemplate<class T> complex<T> operator+(const complex<T>&, const complex<T>&);\ntemplate<class T> complex<T> operator+(const complex<T>&, const T&);\ntemplate<class T> complex<T> operator+(const T&, const complex<T>&);\ntemplate<class T> complex<T> operator-(const complex<T>&, const complex<T>&);\ntemplate<class T> complex<T> operator-(const complex<T>&, const T&);\ntemplate<class T> complex<T> operator-(const T&, const complex<T>&);\ntemplate<class T> complex<T> operator*(const complex<T>&, const complex<T>&);\ntemplate<class T> complex<T> operator*(const complex<T>&, const T&);\ntemplate<class T> complex<T> operator*(const T&, const complex<T>&);\ntemplate<class T> complex<T> operator/(const complex<T>&, const complex<T>&);\ntemplate<class T> complex<T> operator/(const complex<T>&, const T&);\ntemplate<class T> complex<T> operator/(const T&, const complex<T>&);\ntemplate<class T> complex<T> operator+(const complex<T>&);\ntemplate<class T> complex<T> operator-(const complex<T>&);\ntemplate<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14\ntemplate<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14\ntemplate<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14\ntemplate<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14\ntemplate<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14\ntemplate<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14\n\ntemplate<class T, class charT, class traits>\n  basic_istream<charT, traits>&\n  operator>>(basic_istream<charT, traits>&, complex<T>&);\ntemplate<class T, class charT, class traits>\n  basic_ostream<charT, traits>&\n  operator<<(basic_ostream<charT, traits>&, const complex<T>&);\n\n// 26.3.7 values:\n\ntemplate<class T>              T real(const complex<T>&); // constexpr in C++14\n                     long double real(long double);       // constexpr in C++14\n                          double real(double);            // constexpr in C++14\ntemplate<Integral T>      double real(T);                 // constexpr in C++14\n                          float  real(float);             // constexpr in C++14\n\ntemplate<class T>              T imag(const complex<T>&); // constexpr in C++14\n                     long double imag(long double);       // constexpr in C++14\n                          double imag(double);            // constexpr in C++14\ntemplate<Integral T>      double imag(T);                 // constexpr in C++14\n                          float  imag(float);             // constexpr in C++14\n\ntemplate<class T> T abs(const complex<T>&);\n\ntemplate<class T>              T arg(const complex<T>&);\n                     long double arg(long double);\n                          double arg(double);\ntemplate<Integral T>      double arg(T);\n                          float  arg(float);\n\ntemplate<class T>              T norm(const complex<T>&);\n                     long double norm(long double);\n                          double norm(double);\ntemplate<Integral T>      double norm(T);\n                          float  norm(float);\n\ntemplate<class T>      complex<T>           conj(const complex<T>&);\n                       complex<long double> conj(long double);\n                       complex<double>      conj(double);\ntemplate<Integral T>   complex<double>      conj(T);\n                       complex<float>       conj(float);\n\ntemplate<class T>    complex<T>           proj(const complex<T>&);\n                     complex<long double> proj(long double);\n                     complex<double>      proj(double);\ntemplate<Integral T> complex<double>      proj(T);\n                     complex<float>       proj(float);\n\ntemplate<class T> complex<T> polar(const T&, const T& = 0);\n\n// 26.3.8 transcendentals:\ntemplate<class T> complex<T> acos(const complex<T>&);\ntemplate<class T> complex<T> asin(const complex<T>&);\ntemplate<class T> complex<T> atan(const complex<T>&);\ntemplate<class T> complex<T> acosh(const complex<T>&);\ntemplate<class T> complex<T> asinh(const complex<T>&);\ntemplate<class T> complex<T> atanh(const complex<T>&);\ntemplate<class T> complex<T> cos (const complex<T>&);\ntemplate<class T> complex<T> cosh (const complex<T>&);\ntemplate<class T> complex<T> exp (const complex<T>&);\ntemplate<class T> complex<T> log (const complex<T>&);\ntemplate<class T> complex<T> log10(const complex<T>&);\n\ntemplate<class T> complex<T> pow(const complex<T>&, const T&);\ntemplate<class T> complex<T> pow(const complex<T>&, const complex<T>&);\ntemplate<class T> complex<T> pow(const T&, const complex<T>&);\n\ntemplate<class T> complex<T> sin (const complex<T>&);\ntemplate<class T> complex<T> sinh (const complex<T>&);\ntemplate<class T> complex<T> sqrt (const complex<T>&);\ntemplate<class T> complex<T> tan (const complex<T>&);\ntemplate<class T> complex<T> tanh (const complex<T>&);\n\ntemplate<class T, class charT, class traits>\n  basic_istream<charT, traits>&\n  operator>>(basic_istream<charT, traits>& is, complex<T>& x);\n\ntemplate<class T, class charT, class traits>\n  basic_ostream<charT, traits>&\n  operator<<(basic_ostream<charT, traits>& o, const complex<T>& x);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <type_traits>\n#include <stdexcept>\n#include <cmath>\n#include <sstream>\n#if defined(_LIBCPP_NO_EXCEPTIONS)\n    #include <cassert>\n#endif\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate<class _Tp> class _LIBCPP_TYPE_VIS_ONLY complex;\n\ntemplate<class _Tp> complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);\ntemplate<class _Tp> complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y);\n\ntemplate<class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY complex\n{\npublic:\n    typedef _Tp value_type;\nprivate:\n    value_type __re_;\n    value_type __im_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    complex(const value_type& __re = value_type(), const value_type& __im = value_type())\n        : __re_(__re), __im_(__im) {}\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    complex(const complex<_Xp>& __c)\n        : __re_(__c.real()), __im_(__c.imag()) {}\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;}\n\n    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}\n    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}\n\n    _LIBCPP_INLINE_VISIBILITY complex& operator= (const value_type& __re)\n        {__re_ = __re; __im_ = value_type(); return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator+=(const value_type& __re) {__re_ += __re; return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;}\n\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)\n        {\n            __re_ = __c.real();\n            __im_ = __c.imag();\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)\n        {\n            __re_ += __c.real();\n            __im_ += __c.imag();\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)\n        {\n            __re_ -= __c.real();\n            __im_ -= __c.imag();\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)\n        {\n            *this = *this * complex(__c.real(), __c.imag());\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)\n        {\n            *this = *this / complex(__c.real(), __c.imag());\n            return *this;\n        }\n};\n\ntemplate<> class _LIBCPP_TYPE_VIS_ONLY complex<double>;\ntemplate<> class _LIBCPP_TYPE_VIS_ONLY complex<long double>;\n\ntemplate<>\nclass _LIBCPP_TYPE_VIS_ONLY complex<float>\n{\n    float __re_;\n    float __im_;\npublic:\n    typedef float value_type;\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f)\n        : __re_(__re), __im_(__im) {}\n    explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c);\n    explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;}\n\n    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}\n    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}\n\n    _LIBCPP_INLINE_VISIBILITY complex& operator= (float __re)\n        {__re_ = __re; __im_ = value_type(); return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator+=(float __re) {__re_ += __re; return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator-=(float __re) {__re_ -= __re; return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;}\n\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)\n        {\n            __re_ = __c.real();\n            __im_ = __c.imag();\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)\n        {\n            __re_ += __c.real();\n            __im_ += __c.imag();\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)\n        {\n            __re_ -= __c.real();\n            __im_ -= __c.imag();\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)\n        {\n            *this = *this * complex(__c.real(), __c.imag());\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)\n        {\n            *this = *this / complex(__c.real(), __c.imag());\n            return *this;\n        }\n};\n\ntemplate<>\nclass _LIBCPP_TYPE_VIS_ONLY complex<double>\n{\n    double __re_;\n    double __im_;\npublic:\n    typedef double value_type;\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0)\n        : __re_(__re), __im_(__im) {}\n    _LIBCPP_CONSTEXPR complex(const complex<float>& __c);\n    explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;}\n\n    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}\n    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}\n\n    _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re)\n        {__re_ = __re; __im_ = value_type(); return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;}\n\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)\n        {\n            __re_ = __c.real();\n            __im_ = __c.imag();\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)\n        {\n            __re_ += __c.real();\n            __im_ += __c.imag();\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)\n        {\n            __re_ -= __c.real();\n            __im_ -= __c.imag();\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)\n        {\n            *this = *this * complex(__c.real(), __c.imag());\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)\n        {\n            *this = *this / complex(__c.real(), __c.imag());\n            return *this;\n        }\n};\n\ntemplate<>\nclass _LIBCPP_TYPE_VIS_ONLY complex<long double>\n{\n    long double __re_;\n    long double __im_;\npublic:\n    typedef long double value_type;\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L)\n        : __re_(__re), __im_(__im) {}\n    _LIBCPP_CONSTEXPR complex(const complex<float>& __c);\n    _LIBCPP_CONSTEXPR complex(const complex<double>& __c);\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;}\n\n    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}\n    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}\n\n    _LIBCPP_INLINE_VISIBILITY complex& operator= (long double __re)\n        {__re_ = __re; __im_ = value_type(); return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator+=(long double __re) {__re_ += __re; return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator-=(long double __re) {__re_ -= __re; return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;}\n    _LIBCPP_INLINE_VISIBILITY complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;}\n\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)\n        {\n            __re_ = __c.real();\n            __im_ = __c.imag();\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)\n        {\n            __re_ += __c.real();\n            __im_ += __c.imag();\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)\n        {\n            __re_ -= __c.real();\n            __im_ -= __c.imag();\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)\n        {\n            *this = *this * complex(__c.real(), __c.imag());\n            return *this;\n        }\n    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)\n        {\n            *this = *this / complex(__c.real(), __c.imag());\n            return *this;\n        }\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ncomplex<float>::complex(const complex<double>& __c)\n    : __re_(__c.real()), __im_(__c.imag()) {}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ncomplex<float>::complex(const complex<long double>& __c)\n    : __re_(__c.real()), __im_(__c.imag()) {}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ncomplex<double>::complex(const complex<float>& __c)\n    : __re_(__c.real()), __im_(__c.imag()) {}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ncomplex<double>::complex(const complex<long double>& __c)\n    : __re_(__c.real()), __im_(__c.imag()) {}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ncomplex<long double>::complex(const complex<float>& __c)\n    : __re_(__c.real()), __im_(__c.imag()) {}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\ncomplex<long double>::complex(const complex<double>& __c)\n    : __re_(__c.real()), __im_(__c.imag()) {}\n\n// 26.3.6 operators:\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\noperator+(const complex<_Tp>& __x, const complex<_Tp>& __y)\n{\n    complex<_Tp> __t(__x);\n    __t += __y;\n    return __t;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\noperator+(const complex<_Tp>& __x, const _Tp& __y)\n{\n    complex<_Tp> __t(__x);\n    __t += __y;\n    return __t;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\noperator+(const _Tp& __x, const complex<_Tp>& __y)\n{\n    complex<_Tp> __t(__y);\n    __t += __x;\n    return __t;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\noperator-(const complex<_Tp>& __x, const complex<_Tp>& __y)\n{\n    complex<_Tp> __t(__x);\n    __t -= __y;\n    return __t;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\noperator-(const complex<_Tp>& __x, const _Tp& __y)\n{\n    complex<_Tp> __t(__x);\n    __t -= __y;\n    return __t;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\noperator-(const _Tp& __x, const complex<_Tp>& __y)\n{\n    complex<_Tp> __t(-__y);\n    __t += __x;\n    return __t;\n}\n\ntemplate<class _Tp>\ncomplex<_Tp>\noperator*(const complex<_Tp>& __z, const complex<_Tp>& __w)\n{\n    _Tp __a = __z.real();\n    _Tp __b = __z.imag();\n    _Tp __c = __w.real();\n    _Tp __d = __w.imag();\n    _Tp __ac = __a * __c;\n    _Tp __bd = __b * __d;\n    _Tp __ad = __a * __d;\n    _Tp __bc = __b * __c;\n    _Tp __x = __ac - __bd;\n    _Tp __y = __ad + __bc;\n    if (isnan(__x) && isnan(__y))\n    {\n        bool __recalc = false;\n        if (isinf(__a) || isinf(__b))\n        {\n            __a = copysign(isinf(__a) ? _Tp(1) : _Tp(0), __a);\n            __b = copysign(isinf(__b) ? _Tp(1) : _Tp(0), __b);\n            if (isnan(__c))\n                __c = copysign(_Tp(0), __c);\n            if (isnan(__d))\n                __d = copysign(_Tp(0), __d);\n            __recalc = true;\n        }\n        if (isinf(__c) || isinf(__d))\n        {\n            __c = copysign(isinf(__c) ? _Tp(1) : _Tp(0), __c);\n            __d = copysign(isinf(__d) ? _Tp(1) : _Tp(0), __d);\n            if (isnan(__a))\n                __a = copysign(_Tp(0), __a);\n            if (isnan(__b))\n                __b = copysign(_Tp(0), __b);\n            __recalc = true;\n        }\n        if (!__recalc && (isinf(__ac) || isinf(__bd) ||\n                          isinf(__ad) || isinf(__bc)))\n        {\n            if (isnan(__a))\n                __a = copysign(_Tp(0), __a);\n            if (isnan(__b))\n                __b = copysign(_Tp(0), __b);\n            if (isnan(__c))\n                __c = copysign(_Tp(0), __c);\n            if (isnan(__d))\n                __d = copysign(_Tp(0), __d);\n            __recalc = true;\n        }\n        if (__recalc)\n        {\n            __x = _Tp(INFINITY) * (__a * __c - __b * __d);\n            __y = _Tp(INFINITY) * (__a * __d + __b * __c);\n        }\n    }\n    return complex<_Tp>(__x, __y);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\noperator*(const complex<_Tp>& __x, const _Tp& __y)\n{\n    complex<_Tp> __t(__x);\n    __t *= __y;\n    return __t;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\noperator*(const _Tp& __x, const complex<_Tp>& __y)\n{\n    complex<_Tp> __t(__y);\n    __t *= __x;\n    return __t;\n}\n\ntemplate<class _Tp>\ncomplex<_Tp>\noperator/(const complex<_Tp>& __z, const complex<_Tp>& __w)\n{\n    int __ilogbw = 0;\n    _Tp __a = __z.real();\n    _Tp __b = __z.imag();\n    _Tp __c = __w.real();\n    _Tp __d = __w.imag();\n    _Tp __logbw = logb(fmax(fabs(__c), fabs(__d)));\n    if (isfinite(__logbw))\n    {\n        __ilogbw = static_cast<int>(__logbw);\n        __c = scalbn(__c, -__ilogbw);\n        __d = scalbn(__d, -__ilogbw);\n    }\n    _Tp __denom = __c * __c + __d * __d;\n    _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);\n    _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);\n    if (isnan(__x) && isnan(__y))\n    {\n        if ((__denom == _Tp(0)) && (!isnan(__a) || !isnan(__b)))\n        {\n            __x = copysign(_Tp(INFINITY), __c) * __a;\n            __y = copysign(_Tp(INFINITY), __c) * __b;\n        }\n        else if ((isinf(__a) || isinf(__b)) && isfinite(__c) && isfinite(__d))\n        {\n            __a = copysign(isinf(__a) ? _Tp(1) : _Tp(0), __a);\n            __b = copysign(isinf(__b) ? _Tp(1) : _Tp(0), __b);\n            __x = _Tp(INFINITY) * (__a * __c + __b * __d);\n            __y = _Tp(INFINITY) * (__b * __c - __a * __d);\n        }\n        else if (isinf(__logbw) && __logbw > _Tp(0) && isfinite(__a) && isfinite(__b))\n        {\n            __c = copysign(isinf(__c) ? _Tp(1) : _Tp(0), __c);\n            __d = copysign(isinf(__d) ? _Tp(1) : _Tp(0), __d);\n            __x = _Tp(0) * (__a * __c + __b * __d);\n            __y = _Tp(0) * (__b * __c - __a * __d);\n        }\n    }\n    return complex<_Tp>(__x, __y);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\noperator/(const complex<_Tp>& __x, const _Tp& __y)\n{\n    return complex<_Tp>(__x.real() / __y, __x.imag() / __y);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\noperator/(const _Tp& __x, const complex<_Tp>& __y)\n{\n    complex<_Tp> __t(__x);\n    __t /= __y;\n    return __t;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\noperator+(const complex<_Tp>& __x)\n{\n    return __x;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\noperator-(const complex<_Tp>& __x)\n{\n    return complex<_Tp>(-__x.real(), -__x.imag());\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator==(const complex<_Tp>& __x, const complex<_Tp>& __y)\n{\n    return __x.real() == __y.real() && __x.imag() == __y.imag();\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator==(const complex<_Tp>& __x, const _Tp& __y)\n{\n    return __x.real() == __y && __x.imag() == 0;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator==(const _Tp& __x, const complex<_Tp>& __y)\n{\n    return __x == __y.real() && 0 == __y.imag();\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator!=(const complex<_Tp>& __x, const _Tp& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator!=(const _Tp& __x, const complex<_Tp>& __y)\n{\n    return !(__x == __y);\n}\n\n// 26.3.7 values:\n\n// real\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_Tp\nreal(const complex<_Tp>& __c)\n{\n    return __c.real();\n}\n\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nlong double\nreal(long double __re)\n{\n    return __re;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ndouble\nreal(double __re)\n{\n    return __re;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntypename enable_if\n<\n    is_integral<_Tp>::value,\n    double\n>::type\nreal(_Tp  __re)\n{\n    return __re;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nfloat\nreal(float  __re)\n{\n    return __re;\n}\n\n// imag\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_Tp\nimag(const complex<_Tp>& __c)\n{\n    return __c.imag();\n}\n\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nlong double\nimag(long double __re)\n{\n    return 0;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ndouble\nimag(double __re)\n{\n    return 0;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntypename enable_if\n<\n    is_integral<_Tp>::value,\n    double\n>::type\nimag(_Tp  __re)\n{\n    return 0;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nfloat\nimag(float  __re)\n{\n    return 0;\n}\n\n// abs\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\nabs(const complex<_Tp>& __c)\n{\n    return hypot(__c.real(), __c.imag());\n}\n\n// arg\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\narg(const complex<_Tp>& __c)\n{\n    return atan2(__c.imag(), __c.real());\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nlong double\narg(long double __re)\n{\n    return atan2l(0.L, __re);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\ndouble\narg(double __re)\n{\n    return atan2(0., __re);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value,\n    double\n>::type\narg(_Tp __re)\n{\n    return atan2(0., __re);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nfloat\narg(float __re)\n{\n    return atan2f(0.F, __re);\n}\n\n// norm\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\nnorm(const complex<_Tp>& __c)\n{\n    if (isinf(__c.real()))\n        return abs(__c.real());\n    if (isinf(__c.imag()))\n        return abs(__c.imag());\n    return __c.real() * __c.real() + __c.imag() * __c.imag();\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nlong double\nnorm(long double __re)\n{\n    return __re * __re;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\ndouble\nnorm(double __re)\n{\n    return __re * __re;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value,\n    double\n>::type\nnorm(_Tp __re)\n{\n    return (double)__re * __re;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nfloat\nnorm(float __re)\n{\n    return __re * __re;\n}\n\n// conj\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\nconj(const complex<_Tp>& __c)\n{\n    return complex<_Tp>(__c.real(), -__c.imag());\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<long double>\nconj(long double __re)\n{\n    return complex<long double>(__re);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<double>\nconj(double __re)\n{\n    return complex<double>(__re);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value,\n    complex<double>\n>::type\nconj(_Tp __re)\n{\n    return complex<double>(__re);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<float>\nconj(float __re)\n{\n    return complex<float>(__re);\n}\n\n// proj\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\nproj(const complex<_Tp>& __c)\n{\n    std::complex<_Tp> __r = __c;\n    if (isinf(__c.real()) || isinf(__c.imag()))\n        __r = complex<_Tp>(INFINITY, copysign(_Tp(0), __c.imag()));\n    return __r;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<long double>\nproj(long double __re)\n{\n    if (isinf(__re))\n        __re = abs(__re);\n    return complex<long double>(__re);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<double>\nproj(double __re)\n{\n    if (isinf(__re))\n        __re = abs(__re);\n    return complex<double>(__re);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_integral<_Tp>::value,\n    complex<double>\n>::type\nproj(_Tp __re)\n{\n    return complex<double>(__re);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<float>\nproj(float __re)\n{\n    if (isinf(__re))\n        __re = abs(__re);\n    return complex<float>(__re);\n}\n\n// polar\n\ntemplate<class _Tp>\ncomplex<_Tp>\npolar(const _Tp& __rho, const _Tp& __theta = _Tp(0))\n{\n    if (isnan(__rho) || signbit(__rho))\n        return complex<_Tp>(_Tp(NAN), _Tp(NAN));\n    if (isnan(__theta))\n    {\n        if (isinf(__rho))\n            return complex<_Tp>(__rho, __theta);\n        return complex<_Tp>(__theta, __theta);\n    }\n    if (isinf(__theta))\n    {\n        if (isinf(__rho))\n            return complex<_Tp>(__rho, _Tp(NAN));\n        return complex<_Tp>(_Tp(NAN), _Tp(NAN));\n    }\n    _Tp __x = __rho * cos(__theta);\n    if (isnan(__x))\n        __x = 0;\n    _Tp __y = __rho * sin(__theta);\n    if (isnan(__y))\n        __y = 0;\n    return complex<_Tp>(__x, __y);\n}\n\n// log\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\nlog(const complex<_Tp>& __x)\n{\n    return complex<_Tp>(log(abs(__x)), arg(__x));\n}\n\n// log10\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\nlog10(const complex<_Tp>& __x)\n{\n    return log(__x) / log(_Tp(10));\n}\n\n// sqrt\n\ntemplate<class _Tp>\ncomplex<_Tp>\nsqrt(const complex<_Tp>& __x)\n{\n    if (isinf(__x.imag()))\n        return complex<_Tp>(_Tp(INFINITY), __x.imag());\n    if (isinf(__x.real()))\n    {\n        if (__x.real() > _Tp(0))\n            return complex<_Tp>(__x.real(), isnan(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag()));\n        return complex<_Tp>(isnan(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag()));\n    }\n    return polar(sqrt(abs(__x)), arg(__x) / _Tp(2));\n}\n\n// exp\n\ntemplate<class _Tp>\ncomplex<_Tp>\nexp(const complex<_Tp>& __x)\n{\n    _Tp __i = __x.imag();\n    if (isinf(__x.real()))\n    {\n        if (__x.real() < _Tp(0))\n        {\n            if (!isfinite(__i))\n                __i = _Tp(1);\n        }\n        else if (__i == 0 || !isfinite(__i))\n        {\n            if (isinf(__i))\n                __i = _Tp(NAN);\n            return complex<_Tp>(__x.real(), __i);\n        }\n    }\n    else if (isnan(__x.real()) && __x.imag() == 0)\n        return __x;\n    _Tp __e = exp(__x.real());\n    return complex<_Tp>(__e * cos(__i), __e * sin(__i));\n}\n\n// pow\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\npow(const complex<_Tp>& __x, const complex<_Tp>& __y)\n{\n    return exp(__y * log(__x));\n}\n\ntemplate<class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<typename __promote<_Tp, _Up>::type>\npow(const complex<_Tp>& __x, const complex<_Up>& __y)\n{\n    typedef complex<typename __promote<_Tp, _Up>::type> result_type;\n    return _VSTD::pow(result_type(__x), result_type(__y));\n}\n\ntemplate<class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_arithmetic<_Up>::value,\n    complex<typename __promote<_Tp, _Up>::type>\n>::type\npow(const complex<_Tp>& __x, const _Up& __y)\n{\n    typedef complex<typename __promote<_Tp, _Up>::type> result_type;\n    return _VSTD::pow(result_type(__x), result_type(__y));\n}\n\ntemplate<class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_arithmetic<_Tp>::value,\n    complex<typename __promote<_Tp, _Up>::type>\n>::type\npow(const _Tp& __x, const complex<_Up>& __y)\n{\n    typedef complex<typename __promote<_Tp, _Up>::type> result_type;\n    return _VSTD::pow(result_type(__x), result_type(__y));\n}\n\n// asinh\n\ntemplate<class _Tp>\ncomplex<_Tp>\nasinh(const complex<_Tp>& __x)\n{\n    const _Tp __pi(atan2(+0., -0.));\n    if (isinf(__x.real()))\n    {\n        if (isnan(__x.imag()))\n            return __x;\n        if (isinf(__x.imag()))\n            return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));\n        return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));\n    }\n    if (isnan(__x.real()))\n    {\n        if (isinf(__x.imag()))\n            return complex<_Tp>(__x.imag(), __x.real());\n        if (__x.imag() == 0)\n            return __x;\n        return complex<_Tp>(__x.real(), __x.real());\n    }\n    if (isinf(__x.imag()))\n        return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag()));\n    complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) + _Tp(1)));\n    return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));\n}\n\n// acosh\n\ntemplate<class _Tp>\ncomplex<_Tp>\nacosh(const complex<_Tp>& __x)\n{\n    const _Tp __pi(atan2(+0., -0.));\n    if (isinf(__x.real()))\n    {\n        if (isnan(__x.imag()))\n            return complex<_Tp>(abs(__x.real()), __x.imag());\n        if (isinf(__x.imag()))\n        {\n            if (__x.real() > 0)\n                return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));\n            else\n                return complex<_Tp>(-__x.real(), copysign(__pi * _Tp(0.75), __x.imag()));\n        }\n        if (__x.real() < 0)\n            return complex<_Tp>(-__x.real(), copysign(__pi, __x.imag()));\n        return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));\n    }\n    if (isnan(__x.real()))\n    {\n        if (isinf(__x.imag()))\n            return complex<_Tp>(abs(__x.imag()), __x.real());\n        return complex<_Tp>(__x.real(), __x.real());\n    }\n    if (isinf(__x.imag()))\n        return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag()));\n    complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) - _Tp(1)));\n    return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag()));\n}\n\n// atanh\n\ntemplate<class _Tp>\ncomplex<_Tp>\natanh(const complex<_Tp>& __x)\n{\n    const _Tp __pi(atan2(+0., -0.));\n    if (isinf(__x.imag()))\n    {\n        return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));\n    }\n    if (isnan(__x.imag()))\n    {\n        if (isinf(__x.real()) || __x.real() == 0)\n            return complex<_Tp>(copysign(_Tp(0), __x.real()), __x.imag());\n        return complex<_Tp>(__x.imag(), __x.imag());\n    }\n    if (isnan(__x.real()))\n    {\n        return complex<_Tp>(__x.real(), __x.real());\n    }\n    if (isinf(__x.real()))\n    {\n        return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));\n    }\n    if (abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0))\n    {\n        return complex<_Tp>(copysign(_Tp(INFINITY), __x.real()), copysign(_Tp(0), __x.imag()));\n    }\n    complex<_Tp> __z = log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2);\n    return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));\n}\n\n// sinh\n\ntemplate<class _Tp>\ncomplex<_Tp>\nsinh(const complex<_Tp>& __x)\n{\n    if (isinf(__x.real()) && !isfinite(__x.imag()))\n        return complex<_Tp>(__x.real(), _Tp(NAN));\n    if (__x.real() == 0 && !isfinite(__x.imag()))\n        return complex<_Tp>(__x.real(), _Tp(NAN));\n    if (__x.imag() == 0 && !isfinite(__x.real()))\n        return __x;\n    return complex<_Tp>(sinh(__x.real()) * cos(__x.imag()), cosh(__x.real()) * sin(__x.imag()));\n}\n\n// cosh\n\ntemplate<class _Tp>\ncomplex<_Tp>\ncosh(const complex<_Tp>& __x)\n{\n    if (isinf(__x.real()) && !isfinite(__x.imag()))\n        return complex<_Tp>(abs(__x.real()), _Tp(NAN));\n    if (__x.real() == 0 && !isfinite(__x.imag()))\n        return complex<_Tp>(_Tp(NAN), __x.real());\n    if (__x.real() == 0 && __x.imag() == 0)\n        return complex<_Tp>(_Tp(1), __x.imag());\n    if (__x.imag() == 0 && !isfinite(__x.real()))\n        return complex<_Tp>(abs(__x.real()), __x.imag());\n    return complex<_Tp>(cosh(__x.real()) * cos(__x.imag()), sinh(__x.real()) * sin(__x.imag()));\n}\n\n// tanh\n\ntemplate<class _Tp>\ncomplex<_Tp>\ntanh(const complex<_Tp>& __x)\n{\n    if (isinf(__x.real()))\n    {\n        if (!isfinite(__x.imag()))\n            return complex<_Tp>(_Tp(1), _Tp(0));\n        return complex<_Tp>(_Tp(1), copysign(_Tp(0), sin(_Tp(2) * __x.imag())));\n    }\n    if (isnan(__x.real()) && __x.imag() == 0)\n        return __x;\n    _Tp __2r(_Tp(2) * __x.real());\n    _Tp __2i(_Tp(2) * __x.imag());\n    _Tp __d(cosh(__2r) + cos(__2i));\n    _Tp __2rsh(sinh(__2r));\n    if (isinf(__2rsh) && isinf(__d))\n        return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1),\n                            __2i > _Tp(0) ? _Tp(0) : _Tp(-0.));\n    return  complex<_Tp>(__2rsh/__d, sin(__2i)/__d);\n}\n\n// asin\n\ntemplate<class _Tp>\ncomplex<_Tp>\nasin(const complex<_Tp>& __x)\n{\n    complex<_Tp> __z = asinh(complex<_Tp>(-__x.imag(), __x.real()));\n    return complex<_Tp>(__z.imag(), -__z.real());\n}\n\n// acos\n\ntemplate<class _Tp>\ncomplex<_Tp>\nacos(const complex<_Tp>& __x)\n{\n    const _Tp __pi(atan2(+0., -0.));\n    if (isinf(__x.real()))\n    {\n        if (isnan(__x.imag()))\n            return complex<_Tp>(__x.imag(), __x.real());\n        if (isinf(__x.imag()))\n        {\n            if (__x.real() < _Tp(0))\n                return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag());\n            return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag());\n        }\n        if (__x.real() < _Tp(0))\n            return complex<_Tp>(__pi, signbit(__x.imag()) ? -__x.real() : __x.real());\n        return complex<_Tp>(_Tp(0), signbit(__x.imag()) ? __x.real() : -__x.real());\n    }\n    if (isnan(__x.real()))\n    {\n        if (isinf(__x.imag()))\n            return complex<_Tp>(__x.real(), -__x.imag());\n        return complex<_Tp>(__x.real(), __x.real());\n    }\n    if (isinf(__x.imag()))\n        return complex<_Tp>(__pi/_Tp(2), -__x.imag());\n    if (__x.real() == 0)\n        return complex<_Tp>(__pi/_Tp(2), -__x.imag());\n    complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) - _Tp(1)));\n    if (signbit(__x.imag()))\n        return complex<_Tp>(abs(__z.imag()), abs(__z.real()));\n    return complex<_Tp>(abs(__z.imag()), -abs(__z.real()));\n}\n\n// atan\n\ntemplate<class _Tp>\ncomplex<_Tp>\natan(const complex<_Tp>& __x)\n{\n    complex<_Tp> __z = atanh(complex<_Tp>(-__x.imag(), __x.real()));\n    return complex<_Tp>(__z.imag(), -__z.real());\n}\n\n// sin\n\ntemplate<class _Tp>\ncomplex<_Tp>\nsin(const complex<_Tp>& __x)\n{\n    complex<_Tp> __z = sinh(complex<_Tp>(-__x.imag(), __x.real()));\n    return complex<_Tp>(__z.imag(), -__z.real());\n}\n\n// cos\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ncomplex<_Tp>\ncos(const complex<_Tp>& __x)\n{\n    return cosh(complex<_Tp>(-__x.imag(), __x.real()));\n}\n\n// tan\n\ntemplate<class _Tp>\ncomplex<_Tp>\ntan(const complex<_Tp>& __x)\n{\n    complex<_Tp> __z = tanh(complex<_Tp>(-__x.imag(), __x.real()));\n    return complex<_Tp>(__z.imag(), -__z.real());\n}\n\ntemplate<class _Tp, class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)\n{\n    if (__is.good())\n    {\n        ws(__is);\n        if (__is.peek() == _CharT('('))\n        {\n            __is.get();\n            _Tp __r;\n            __is >> __r;\n            if (!__is.fail())\n            {\n                ws(__is);\n                _CharT __c = __is.peek();\n                if (__c == _CharT(','))\n                {\n                    __is.get();\n                    _Tp __i;\n                    __is >> __i;\n                    if (!__is.fail())\n                    {\n                        ws(__is);\n                        __c = __is.peek();\n                        if (__c == _CharT(')'))\n                        {\n                            __is.get();\n                            __x = complex<_Tp>(__r, __i);\n                        }\n                        else\n                            __is.setstate(ios_base::failbit);\n                    }\n                    else\n                        __is.setstate(ios_base::failbit);\n                }\n                else if (__c == _CharT(')'))\n                {\n                    __is.get();\n                    __x = complex<_Tp>(__r, _Tp(0));\n                }\n                else\n                    __is.setstate(ios_base::failbit);\n            }\n            else\n                __is.setstate(ios_base::failbit);\n        }\n        else\n        {\n            _Tp __r;\n            __is >> __r;\n            if (!__is.fail())\n                __x = complex<_Tp>(__r, _Tp(0));\n            else\n                __is.setstate(ios_base::failbit);\n        }\n    }\n    else\n        __is.setstate(ios_base::failbit);\n    return __is;\n}\n\ntemplate<class _Tp, class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)\n{\n    basic_ostringstream<_CharT, _Traits> __s;\n    __s.flags(__os.flags());\n    __s.imbue(__os.getloc());\n    __s.precision(__os.precision());\n    __s << '(' << __x.real() << ',' << __x.imag() << ')';\n    return __os << __s.str();\n}\n\n#if _LIBCPP_STD_VER > 11 \n// Literal suffix for complex number literals [complex.literals]\ninline namespace literals\n{ \n  inline namespace complex_literals\n  {\n    constexpr complex<long double> operator\"\"il(long double __im)\n    {\n        return { 0.0l, __im };\n    }\n\n    constexpr complex<long double> operator\"\"il(unsigned long long __im)\n    {\n        return { 0.0l, static_cast<long double>(__im) };\n    }\n\n\n    constexpr complex<double> operator\"\"i(long double __im)\n    {\n        return { 0.0, static_cast<double>(__im) };\n    }\n\n    constexpr complex<double> operator\"\"i(unsigned long long __im)\n    {\n        return { 0.0, static_cast<double>(__im) };\n    }\n\n\n    constexpr complex<float> operator\"\"if(long double __im)\n    {\n        return { 0.0f, static_cast<float>(__im) };\n    }\n\n    constexpr complex<float> operator\"\"if(unsigned long long __im)\n    {\n        return { 0.0f, static_cast<float>(__im) };\n    }\n  }\n}\n#endif\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_COMPLEX\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/complex.h",
    "content": "// -*- C++ -*-\n//===--------------------------- complex.h --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_COMPLEX_H\n#define _LIBCPP_COMPLEX_H\n\n/*\n    complex.h synopsis\n\n#include <ccomplex>\n\n*/\n\n#ifdef __cplusplus\n\n#include <ccomplex>\n\n#else  // __cplusplus\n\n#include_next <complex.h>\n\n#endif  // __cplusplus\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#endif  // _LIBCPP_COMPLEX_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/condition_variable",
    "content": "// -*- C++ -*-\n//===---------------------- condition_variable ----------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CONDITION_VARIABLE\n#define _LIBCPP_CONDITION_VARIABLE\n\n/*\n    condition_variable synopsis\n\nnamespace std\n{\n\nenum class cv_status { no_timeout, timeout };\n\nclass condition_variable\n{\npublic:\n    condition_variable();\n    ~condition_variable();\n\n    condition_variable(const condition_variable&) = delete;\n    condition_variable& operator=(const condition_variable&) = delete;\n\n    void notify_one() noexcept;\n    void notify_all() noexcept;\n\n    void wait(unique_lock<mutex>& lock);\n    template <class Predicate>\n        void wait(unique_lock<mutex>& lock, Predicate pred);\n\n    template <class Clock, class Duration>\n        cv_status\n        wait_until(unique_lock<mutex>& lock,\n                   const chrono::time_point<Clock, Duration>& abs_time);\n\n    template <class Clock, class Duration, class Predicate>\n        bool\n        wait_until(unique_lock<mutex>& lock,\n                   const chrono::time_point<Clock, Duration>& abs_time,\n                   Predicate pred);\n\n    template <class Rep, class Period>\n        cv_status\n        wait_for(unique_lock<mutex>& lock,\n                 const chrono::duration<Rep, Period>& rel_time);\n\n    template <class Rep, class Period, class Predicate>\n        bool\n        wait_for(unique_lock<mutex>& lock,\n                 const chrono::duration<Rep, Period>& rel_time,\n                 Predicate pred);\n\n    typedef pthread_cond_t* native_handle_type;\n    native_handle_type native_handle();\n};\n\nvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);\n\nclass condition_variable_any\n{\npublic:\n    condition_variable_any();\n    ~condition_variable_any();\n\n    condition_variable_any(const condition_variable_any&) = delete;\n    condition_variable_any& operator=(const condition_variable_any&) = delete;\n\n    void notify_one() noexcept;\n    void notify_all() noexcept;\n\n    template <class Lock>\n        void wait(Lock& lock);\n    template <class Lock, class Predicate>\n        void wait(Lock& lock, Predicate pred);\n\n    template <class Lock, class Clock, class Duration>\n        cv_status\n        wait_until(Lock& lock,\n                   const chrono::time_point<Clock, Duration>& abs_time);\n\n    template <class Lock, class Clock, class Duration, class Predicate>\n        bool\n        wait_until(Lock& lock,\n                   const chrono::time_point<Clock, Duration>& abs_time,\n                   Predicate pred);\n\n    template <class Lock, class Rep, class Period>\n        cv_status\n        wait_for(Lock& lock,\n                 const chrono::duration<Rep, Period>& rel_time);\n\n    template <class Lock, class Rep, class Period, class Predicate>\n        bool\n        wait_for(Lock& lock,\n                 const chrono::duration<Rep, Period>& rel_time,\n                 Predicate pred);\n};\n\n}  // std\n\n*/\n\n#include <__config>\n#include <__mutex_base>\n#include <memory>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#ifndef _LIBCPP_HAS_NO_THREADS\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nclass _LIBCPP_TYPE_VIS condition_variable_any\n{\n    condition_variable __cv_;\n    shared_ptr<mutex>  __mut_;\npublic:\n    condition_variable_any();\n\n    void notify_one() _NOEXCEPT;\n    void notify_all() _NOEXCEPT;\n\n    template <class _Lock>\n        void wait(_Lock& __lock);\n    template <class _Lock, class _Predicate>\n        void wait(_Lock& __lock, _Predicate __pred);\n\n    template <class _Lock, class _Clock, class _Duration>\n        cv_status\n        wait_until(_Lock& __lock,\n                   const chrono::time_point<_Clock, _Duration>& __t);\n\n    template <class _Lock, class _Clock, class _Duration, class _Predicate>\n        bool\n        wait_until(_Lock& __lock,\n                   const chrono::time_point<_Clock, _Duration>& __t,\n                   _Predicate __pred);\n\n    template <class _Lock, class _Rep, class _Period>\n        cv_status\n        wait_for(_Lock& __lock,\n                 const chrono::duration<_Rep, _Period>& __d);\n\n    template <class _Lock, class _Rep, class _Period, class _Predicate>\n        bool\n        wait_for(_Lock& __lock,\n                 const chrono::duration<_Rep, _Period>& __d,\n                 _Predicate __pred);\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\ncondition_variable_any::condition_variable_any()\n    : __mut_(make_shared<mutex>()) {}\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\ncondition_variable_any::notify_one() _NOEXCEPT\n{\n    {lock_guard<mutex> __lx(*__mut_);}\n    __cv_.notify_one();\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\ncondition_variable_any::notify_all() _NOEXCEPT\n{\n    {lock_guard<mutex> __lx(*__mut_);}\n    __cv_.notify_all();\n}\n\nstruct __lock_external\n{\n    template <class _Lock>\n    void operator()(_Lock* __m) {__m->lock();}\n};\n\ntemplate <class _Lock>\nvoid\ncondition_variable_any::wait(_Lock& __lock)\n{\n    shared_ptr<mutex> __mut = __mut_;\n    unique_lock<mutex> __lk(*__mut);\n    __lock.unlock();\n    unique_ptr<_Lock, __lock_external> __lxx(&__lock);\n    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock);\n    __cv_.wait(__lk);\n}  // __mut_.unlock(), __lock.lock()\n\ntemplate <class _Lock, class _Predicate>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\ncondition_variable_any::wait(_Lock& __lock, _Predicate __pred)\n{\n    while (!__pred())\n        wait(__lock);\n}\n\ntemplate <class _Lock, class _Clock, class _Duration>\ncv_status\ncondition_variable_any::wait_until(_Lock& __lock,\n                                   const chrono::time_point<_Clock, _Duration>& __t)\n{\n    shared_ptr<mutex> __mut = __mut_;\n    unique_lock<mutex> __lk(*__mut);\n    __lock.unlock();\n    unique_ptr<_Lock, __lock_external> __lxx(&__lock);\n    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock);\n    return __cv_.wait_until(__lk, __t);\n}  // __mut_.unlock(), __lock.lock()\n\ntemplate <class _Lock, class _Clock, class _Duration, class _Predicate>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\ncondition_variable_any::wait_until(_Lock& __lock,\n                                   const chrono::time_point<_Clock, _Duration>& __t,\n                                   _Predicate __pred)\n{\n    while (!__pred())\n        if (wait_until(__lock, __t) == cv_status::timeout)\n            return __pred();\n    return true;\n}\n\ntemplate <class _Lock, class _Rep, class _Period>\ninline _LIBCPP_INLINE_VISIBILITY\ncv_status\ncondition_variable_any::wait_for(_Lock& __lock,\n                                 const chrono::duration<_Rep, _Period>& __d)\n{\n    return wait_until(__lock, chrono::steady_clock::now() + __d);\n}\n\ntemplate <class _Lock, class _Rep, class _Period, class _Predicate>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\ncondition_variable_any::wait_for(_Lock& __lock,\n                                 const chrono::duration<_Rep, _Period>& __d,\n                                 _Predicate __pred)\n{\n    return wait_until(__lock, chrono::steady_clock::now() + __d,\n                      _VSTD::move(__pred));\n}\n\n_LIBCPP_FUNC_VIS\nvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif // !_LIBCPP_HAS_NO_THREADS\n\n#endif  // _LIBCPP_CONDITION_VARIABLE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/csetjmp",
    "content": "// -*- C++ -*-\n//===--------------------------- csetjmp ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CSETJMP\n#define _LIBCPP_CSETJMP\n\n/*\n    csetjmp synopsis\n\nMacros:\n\n    setjmp\n\nnamespace std\n{\n\nTypes:\n\n    jmp_buf\n\nvoid longjmp(jmp_buf env, int val);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <setjmp.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#ifndef setjmp\n#define setjmp(env) setjmp(env)\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing ::jmp_buf;\nusing ::longjmp;\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CSETJMP\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/csignal",
    "content": "// -*- C++ -*-\n//===--------------------------- csignal ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CSIGNAL\n#define _LIBCPP_CSIGNAL\n\n/*\n    csignal synopsis\n\nMacros:\n\n    SIG_DFL\n    SIG_ERR\n    SIG_IGN\n    SIGABRT\n    SIGFPE\n    SIGILL\n    SIGINT\n    SIGSEGV\n    SIGTERM\n\nnamespace std\n{\n\nTypes:\n\n    sig_atomic_t\n\nvoid (*signal(int sig, void (*func)(int)))(int);\nint raise(int sig);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <signal.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing ::sig_atomic_t;\nusing ::signal;\nusing ::raise;\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CSIGNAL\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cstdarg",
    "content": "// -*- C++ -*-\n//===--------------------------- cstdarg ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CSTDARG\n#define _LIBCPP_CSTDARG\n\n/*\n    cstdarg synopsis\n\nMacros:\n\n    type va_arg(va_list ap, type);\n    void va_copy(va_list dest, va_list src);  // C99\n    void va_end(va_list ap);\n    void va_start(va_list ap, parmN);\n\nnamespace std\n{\n\nTypes:\n\n    va_list\n\n}  // std\n\n*/\n\n#include <__config>\n#include <stdarg.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing ::va_list;\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CSTDARG\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cstdbool",
    "content": "// -*- C++ -*-\n//===--------------------------- cstdbool ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CSTDBOOL\n#define _LIBCPP_CSTDBOOL\n\n/*\n    cstdbool synopsis\n\nMacros:\n\n    __bool_true_false_are_defined\n\n*/\n\n#include <__config>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#undef __bool_true_false_are_defined\n#define __bool_true_false_are_defined 1\n\n#endif  // _LIBCPP_CSTDBOOL\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cstddef",
    "content": "// -*- C++ -*-\n//===--------------------------- cstddef ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CSTDDEF\n#define _LIBCPP_CSTDDEF\n\n/*\n    cstddef synopsis\n\nMacros:\n\n    offsetof(type,member-designator)\n    NULL\n\nnamespace std\n{\n\nTypes:\n\n    ptrdiff_t\n    size_t\n    max_align_t\n    nullptr_t\n\n}  // std\n\n*/\n\n#include <__config>\n\n#include <stddef.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing ::ptrdiff_t;\nusing ::size_t;\n\n#if defined(__CLANG_MAX_ALIGN_T_DEFINED) || defined(_GCC_MAX_ALIGN_T)\n// Re-use the compiler's <stddef.h> max_align_t where possible.\nusing ::max_align_t;\n#else\ntypedef long double max_align_t;\n#endif\n\n#ifdef _LIBCPP_HAS_NO_NULLPTR\n\nstruct _LIBCPP_TYPE_VIS_ONLY nullptr_t\n{\n    void* __lx;\n\n    struct __nat {int __for_bool_;};\n\n    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {}\n    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {}\n\n    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;}\n\n    template <class _Tp>\n        _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR\n        operator _Tp* () const {return 0;}\n\n    template <class _Tp, class _Up>\n        _LIBCPP_ALWAYS_INLINE\n        operator _Tp _Up::* () const {return 0;}\n\n    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;}\n    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;}\n    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator<(nullptr_t, nullptr_t) {return false;}\n    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator<=(nullptr_t, nullptr_t) {return true;}\n    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator>(nullptr_t, nullptr_t) {return false;}\n    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator>=(nullptr_t, nullptr_t) {return true;}\n};\n\ninline _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);}\n\n#define nullptr _VSTD::__get_nullptr_t()\n\n#endif  // _LIBCPP_HAS_NO_NULLPTR\n\n_LIBCPP_END_NAMESPACE_STD\n\n#ifndef _LIBCPP_HAS_NO_NULLPTR\n\nnamespace std\n{\n    typedef decltype(nullptr) nullptr_t;\n}\n\n#endif  // _LIBCPP_HAS_NO_NULLPTR\n\n#endif  // _LIBCPP_CSTDDEF\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cstdint",
    "content": "// -*- C++ -*-\n//===--------------------------- cstdint ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CSTDINT\n#define _LIBCPP_CSTDINT\n\n/*\n    cstdint synopsis\n\nMacros:\n\n    INT8_MIN\n    INT16_MIN\n    INT32_MIN\n    INT64_MIN\n\n    INT8_MAX\n    INT16_MAX\n    INT32_MAX\n    INT64_MAX\n\n    UINT8_MAX\n    UINT16_MAX\n    UINT32_MAX\n    UINT64_MAX\n\n    INT_LEAST8_MIN\n    INT_LEAST16_MIN\n    INT_LEAST32_MIN\n    INT_LEAST64_MIN\n\n    INT_LEAST8_MAX\n    INT_LEAST16_MAX\n    INT_LEAST32_MAX\n    INT_LEAST64_MAX\n\n    UINT_LEAST8_MAX\n    UINT_LEAST16_MAX\n    UINT_LEAST32_MAX\n    UINT_LEAST64_MAX\n\n    INT_FAST8_MIN\n    INT_FAST16_MIN\n    INT_FAST32_MIN\n    INT_FAST64_MIN\n\n    INT_FAST8_MAX\n    INT_FAST16_MAX\n    INT_FAST32_MAX\n    INT_FAST64_MAX\n\n    UINT_FAST8_MAX\n    UINT_FAST16_MAX\n    UINT_FAST32_MAX\n    UINT_FAST64_MAX\n\n    INTPTR_MIN\n    INTPTR_MAX\n    UINTPTR_MAX\n\n    INTMAX_MIN\n    INTMAX_MAX\n\n    UINTMAX_MAX\n\n    PTRDIFF_MIN\n    PTRDIFF_MAX\n\n    SIG_ATOMIC_MIN\n    SIG_ATOMIC_MAX\n\n    SIZE_MAX\n\n    WCHAR_MIN\n    WCHAR_MAX\n\n    WINT_MIN\n    WINT_MAX\n\n    INT8_C(value)\n    INT16_C(value)\n    INT32_C(value)\n    INT64_C(value)\n\n    UINT8_C(value)\n    UINT16_C(value)\n    UINT32_C(value)\n    UINT64_C(value)\n\n    INTMAX_C(value)\n    UINTMAX_C(value)\n\nnamespace std\n{\n\nTypes:\n\n    int8_t\n    int16_t\n    int32_t\n    int64_t\n\n    uint8_t\n    uint16_t\n    uint32_t\n    uint64_t\n\n    int_least8_t\n    int_least16_t\n    int_least32_t\n    int_least64_t\n\n    uint_least8_t\n    uint_least16_t\n    uint_least32_t\n    uint_least64_t\n\n    int_fast8_t\n    int_fast16_t\n    int_fast32_t\n    int_fast64_t\n\n    uint_fast8_t\n    uint_fast16_t\n    uint_fast32_t\n    uint_fast64_t\n\n    intptr_t\n    uintptr_t\n\n    intmax_t\n    uintmax_t\n\n}  // std\n*/\n\n#include <__config>\n#include <stdint.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing::int8_t;\nusing::int16_t;\nusing::int32_t;\nusing::int64_t;\n\nusing::uint8_t;\nusing::uint16_t;\nusing::uint32_t;\nusing::uint64_t;\n\nusing::int_least8_t;\nusing::int_least16_t;\nusing::int_least32_t;\nusing::int_least64_t;\n\nusing::uint_least8_t;\nusing::uint_least16_t;\nusing::uint_least32_t;\nusing::uint_least64_t;\n\nusing::int_fast8_t;\nusing::int_fast16_t;\nusing::int_fast32_t;\nusing::int_fast64_t;\n\nusing::uint_fast8_t;\nusing::uint_fast16_t;\nusing::uint_fast32_t;\nusing::uint_fast64_t;\n\nusing::intptr_t;\nusing::uintptr_t;\n\nusing::intmax_t;\nusing::uintmax_t;\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CSTDINT\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cstdio",
    "content": "// -*- C++ -*-\n//===---------------------------- cstdio ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CSTDIO\n#define _LIBCPP_CSTDIO\n\n/*\n    cstdio synopsis\n\nMacros:\n\n    BUFSIZ\n    EOF\n    FILENAME_MAX\n    FOPEN_MAX\n    L_tmpnam\n    NULL\n    SEEK_CUR\n    SEEK_END\n    SEEK_SET\n    TMP_MAX\n    _IOFBF\n    _IOLBF\n    _IONBF\n    stderr\n    stdin\n    stdout\n\nnamespace std\n{\n\nTypes:\n\nFILE\nfpos_t\nsize_t\n\nint remove(const char* filename);\nint rename(const char* old, const char* new);\nFILE* tmpfile(void);\nchar* tmpnam(char* s);\nint fclose(FILE* stream);\nint fflush(FILE* stream);\nFILE* fopen(const char* restrict filename, const char* restrict mode);\nFILE* freopen(const char* restrict filename, const char * restrict mode,\n              FILE * restrict stream);\nvoid setbuf(FILE* restrict stream, char* restrict buf);\nint setvbuf(FILE* restrict stream, char* restrict buf, int mode, size_t size);\nint fprintf(FILE* restrict stream, const char* restrict format, ...);\nint fscanf(FILE* restrict stream, const char * restrict format, ...);\nint printf(const char* restrict format, ...);\nint scanf(const char* restrict format, ...);\nint snprintf(char* restrict s, size_t n, const char* restrict format, ...);    // C99\nint sprintf(char* restrict s, const char* restrict format, ...);\nint sscanf(const char* restrict s, const char* restrict format, ...);\nint vfprintf(FILE* restrict stream, const char* restrict format, va_list arg);\nint vfscanf(FILE* restrict stream, const char* restrict format, va_list arg);  // C99\nint vprintf(const char* restrict format, va_list arg);\nint vscanf(const char* restrict format, va_list arg);                          // C99\nint vsnprintf(char* restrict s, size_t n, const char* restrict format,         // C99\n              va_list arg);\nint vsprintf(char* restrict s, const char* restrict format, va_list arg);\nint vsscanf(const char* restrict s, const char* restrict format, va_list arg); // C99\nint fgetc(FILE* stream);\nchar* fgets(char* restrict s, int n, FILE* restrict stream);\nint fputc(int c, FILE* stream);\nint fputs(const char* restrict s, FILE* restrict stream);\nint getc(FILE* stream);\nint getchar(void);\nchar* gets(char* s);  // removed in C++14\nint putc(int c, FILE* stream);\nint putchar(int c);\nint puts(const char* s);\nint ungetc(int c, FILE* stream);\nsize_t fread(void* restrict ptr, size_t size, size_t nmemb,\n             FILE* restrict stream);\nsize_t fwrite(const void* restrict ptr, size_t size, size_t nmemb,\n              FILE* restrict stream);\nint fgetpos(FILE* restrict stream, fpos_t* restrict pos);\nint fseek(FILE* stream, long offset, int whence);\nint fsetpos(FILE*stream, const fpos_t* pos);\nlong ftell(FILE* stream);\nvoid rewind(FILE* stream);\nvoid clearerr(FILE* stream);\nint feof(FILE* stream);\nint ferror(FILE* stream);\nvoid perror(const char* s);\n\n}  // std\n*/\n\n#include <__config>\n#include <stdio.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n// snprintf\n#if defined(_LIBCPP_MSVCRT)\n#include \"support/win32/support.h\"\n#endif\n\n#ifdef getc\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_getc(FILE* __stream) {return getc(__stream);}\n#undef getc\ninline _LIBCPP_INLINE_VISIBILITY int getc(FILE* __stream) {return __libcpp_getc(__stream);}\n#endif  // getc\n\n#ifdef putc\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_putc(int __c, FILE* __stream) {return putc(__c, __stream);}\n#undef putc\ninline _LIBCPP_INLINE_VISIBILITY int putc(int __c, FILE* __stream) {return __libcpp_putc(__c, __stream);}\n#endif  // putc\n\n#ifdef clearerr\ninline _LIBCPP_INLINE_VISIBILITY void __libcpp_clearerr(FILE* __stream) { return clearerr(__stream); }\n#undef clearerr\ninline _LIBCPP_INLINE_VISIBILITY void clearerr(FILE* __stream) { return __libcpp_clearerr(__stream); }\n#endif  // clearerr\n\n#ifdef feof\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_feof(FILE* __stream) { return feof(__stream); }\n#undef feof\ninline _LIBCPP_INLINE_VISIBILITY int feof(FILE* __stream) { return __libcpp_feof(__stream); }\n#endif  // feof\n\n#ifdef ferror\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_ferror(FILE* __stream) { return ferror(__stream); }\n#undef ferror\ninline _LIBCPP_INLINE_VISIBILITY int ferror(FILE* __stream) { return __libcpp_ferror(__stream); }\n#endif  // ferror\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing ::FILE;\nusing ::fpos_t;\nusing ::size_t;\n\nusing ::fclose;\nusing ::fflush;\nusing ::setbuf;\nusing ::setvbuf;\nusing ::fprintf;\nusing ::fscanf;\nusing ::snprintf;\nusing ::sprintf;\nusing ::sscanf;\n#ifndef _LIBCPP_MSVCRT\nusing ::vfprintf;\nusing ::vfscanf;\nusing ::vsscanf;\n#endif // _LIBCPP_MSVCRT\nusing ::vsnprintf;\nusing ::vsprintf;\nusing ::fgetc;\nusing ::fgets;\nusing ::fputc;\nusing ::fputs;\nusing ::getc;\nusing ::putc;\nusing ::ungetc;\nusing ::fread;\nusing ::fwrite;\nusing ::fgetpos;\nusing ::fseek;\nusing ::fsetpos;\nusing ::ftell;\nusing ::rewind;\nusing ::clearerr;\nusing ::feof;\nusing ::ferror;\nusing ::perror;\n\n#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\nusing ::fopen;\nusing ::freopen;\nusing ::remove;\nusing ::rename;\nusing ::tmpfile;\nusing ::tmpnam;\n#endif\n\n#ifndef _LIBCPP_HAS_NO_STDIN\nusing ::getchar;\n#if _LIBCPP_STD_VER <= 11\nusing ::gets;\n#endif\nusing ::scanf;\nusing ::vscanf;\n#endif\n\n#ifndef _LIBCPP_HAS_NO_STDOUT\nusing ::printf;\nusing ::putchar;\nusing ::puts;\nusing ::vprintf;\n#endif\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CSTDIO\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cstdlib",
    "content": "// -*- C++ -*-\n//===--------------------------- cstdlib ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CSTDLIB\n#define _LIBCPP_CSTDLIB\n\n/*\n    cstdlib synopsis\n\nMacros:\n\n    EXIT_FAILURE\n    EXIT_SUCCESS\n    MB_CUR_MAX\n    NULL\n    RAND_MAX\n\nnamespace std\n{\n\nTypes:\n\n    size_t\n    div_t\n    ldiv_t\n    lldiv_t                                                               // C99\n\ndouble    atof (const char* nptr);\nint       atoi (const char* nptr);\nlong      atol (const char* nptr);\nlong long atoll(const char* nptr);                                        // C99\ndouble             strtod  (const char* restrict nptr, char** restrict endptr);\nfloat              strtof  (const char* restrict nptr, char** restrict endptr); // C99\nlong double        strtold (const char* restrict nptr, char** restrict endptr); // C99\nlong               strtol  (const char* restrict nptr, char** restrict endptr, int base);\nlong long          strtoll (const char* restrict nptr, char** restrict endptr, int base); // C99\nunsigned long      strtoul (const char* restrict nptr, char** restrict endptr, int base);\nunsigned long long strtoull(const char* restrict nptr, char** restrict endptr, int base); // C99\nint rand(void);\nvoid srand(unsigned int seed);\nvoid* calloc(size_t nmemb, size_t size);\nvoid free(void* ptr);\nvoid* malloc(size_t size);\nvoid* realloc(void* ptr, size_t size);\nvoid abort(void);\nint atexit(void (*func)(void));\nvoid exit(int status);\nvoid _Exit(int status);\nchar* getenv(const char* name);\nint system(const char* string);\nvoid* bsearch(const void* key, const void* base, size_t nmemb, size_t size,\n              int (*compar)(const void *, const void *));\nvoid qsort(void* base, size_t nmemb, size_t size,\n           int (*compar)(const void *, const void *));\nint         abs(      int j);\nlong        abs(     long j);\nlong long   abs(long long j);                                             // C++0X\nlong       labs(     long j);\nlong long llabs(long long j);                                             // C99\ndiv_t     div(      int numer,       int denom);\nldiv_t    div(     long numer,      long denom);\nlldiv_t   div(long long numer, long long denom);                          // C++0X\nldiv_t   ldiv(     long numer,      long denom);\nlldiv_t lldiv(long long numer, long long denom);                          // C99\nint mblen(const char* s, size_t n);\nint mbtowc(wchar_t* restrict pwc, const char* restrict s, size_t n);\nint wctomb(char* s, wchar_t wchar);\nsize_t mbstowcs(wchar_t* restrict pwcs, const char* restrict s, size_t n);\nsize_t wcstombs(char* restrict s, const wchar_t* restrict pwcs, size_t n);\nint at_quick_exit(void (*func)(void))                                     // C++11\nvoid quick_exit(int status);                                              // C++11\nvoid *aligned_alloc(size_t alignment, size_t size);                       // C11\n\n}  // std\n\n*/\n\n#include <__config>\n#include <stdlib.h>\n#ifdef _LIBCPP_MSVCRT\n#include \"support/win32/locale_win32.h\"\n#endif // _LIBCPP_MSVCRT\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing ::size_t;\nusing ::div_t;\nusing ::ldiv_t;\n#ifndef _LIBCPP_HAS_NO_LONG_LONG\nusing ::lldiv_t;\n#endif // _LIBCPP_HAS_NO_LONG_LONG\nusing ::atof;\nusing ::atoi;\nusing ::atol;\n#ifndef _LIBCPP_HAS_NO_LONG_LONG\nusing ::atoll;\n#endif // _LIBCPP_HAS_NO_LONG_LONG\nusing ::strtod;\nusing ::strtof;\nusing ::strtold;\nusing ::strtol;\n#ifndef _LIBCPP_HAS_NO_LONG_LONG\nusing ::strtoll;\n#endif // _LIBCPP_HAS_NO_LONG_LONG\nusing ::strtoul;\n#ifndef _LIBCPP_HAS_NO_LONG_LONG\nusing ::strtoull;\n#endif // _LIBCPP_HAS_NO_LONG_LONG\nusing ::rand;\nusing ::srand;\nusing ::calloc;\nusing ::free;\nusing ::malloc;\nusing ::realloc;\nusing ::abort;\nusing ::atexit;\nusing ::exit;\nusing ::_Exit;\nusing ::getenv;\nusing ::system;\nusing ::bsearch;\nusing ::qsort;\n#undef abs\nusing ::abs;\n#undef labs\nusing ::labs;\n#ifndef _LIBCPP_HAS_NO_LONG_LONG\n#undef llabs\nusing ::llabs;\n#endif // _LIBCPP_HAS_NO_LONG_LONG\n#undef div\nusing ::div;\n#undef ldiv\nusing ::ldiv;\n#ifndef _LIBCPP_HAS_NO_LONG_LONG\n#undef lldiv\nusing ::lldiv;\n#endif // _LIBCPP_HAS_NO_LONG_LONG\n#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS\nusing ::mblen;\nusing ::mbtowc;\nusing ::wctomb;\n#endif\nusing ::mbstowcs;\nusing ::wcstombs;\n#ifdef _LIBCPP_HAS_QUICK_EXIT\nusing ::at_quick_exit;\nusing ::quick_exit;\n#endif\n#ifdef _LIBCPP_HAS_C11_FEATURES\nusing ::aligned_alloc;\n#endif\n\n// MSVCRT already has the correct prototype in <stdlib.h> #ifdef __cplusplus\n#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)\ninline _LIBCPP_INLINE_VISIBILITY long      abs(     long __x) _NOEXCEPT {return  labs(__x);}\n#ifndef _LIBCPP_HAS_NO_LONG_LONG\ninline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {return llabs(__x);}\n#endif // _LIBCPP_HAS_NO_LONG_LONG\n\ninline _LIBCPP_INLINE_VISIBILITY  ldiv_t div(     long __x,      long __y) _NOEXCEPT {return  ldiv(__x, __y);}\n#ifndef _LIBCPP_HAS_NO_LONG_LONG\ninline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x, long long __y) _NOEXCEPT {return lldiv(__x, __y);}\n#endif // _LIBCPP_HAS_NO_LONG_LONG\n#endif // _LIBCPP_MSVCRT\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CSTDLIB\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cstring",
    "content": "// -*- C++ -*-\n//===--------------------------- cstring ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CSTRING\n#define _LIBCPP_CSTRING\n\n/*\n    cstring synopsis\n\nMacros:\n\n    NULL\n\nnamespace std\n{\n\nTypes:\n\n    size_t\n\nvoid* memcpy(void* restrict s1, const void* restrict s2, size_t n);\nvoid* memmove(void* s1, const void* s2, size_t n);\nchar* strcpy (char* restrict s1, const char* restrict s2);\nchar* strncpy(char* restrict s1, const char* restrict s2, size_t n);\nchar* strcat (char* restrict s1, const char* restrict s2);\nchar* strncat(char* restrict s1, const char* restrict s2, size_t n);\nint memcmp(const void* s1, const void* s2, size_t n);\nint strcmp (const char* s1, const char* s2);\nint strncmp(const char* s1, const char* s2, size_t n);\nint strcoll(const char* s1, const char* s2);\nsize_t strxfrm(char* restrict s1, const char* restrict s2, size_t n);\nconst void* memchr(const void* s, int c, size_t n);\n      void* memchr(      void* s, int c, size_t n);\nconst char* strchr(const char* s, int c);\n      char* strchr(      char* s, int c);\nsize_t strcspn(const char* s1, const char* s2);\nconst char* strpbrk(const char* s1, const char* s2);\n      char* strpbrk(      char* s1, const char* s2);\nconst char* strrchr(const char* s, int c);\n      char* strrchr(      char* s, int c);\nsize_t strspn(const char* s1, const char* s2);\nconst char* strstr(const char* s1, const char* s2);\n      char* strstr(      char* s1, const char* s2);\nchar* strtok(char* restrict s1, const char* restrict s2);\nvoid* memset(void* s, int c, size_t n);\nchar* strerror(int errnum);\nsize_t strlen(const char* s);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <string.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing ::size_t;\nusing ::memcpy;\nusing ::memmove;\nusing ::strcpy;\nusing ::strncpy;\nusing ::strcat;\nusing ::strncat;\nusing ::memcmp;\nusing ::strcmp;\nusing ::strncmp;\nusing ::strcoll;\nusing ::strxfrm;\n\nusing ::memchr;\n\nusing ::strchr;\n\nusing ::strcspn;\n\nusing ::strpbrk;\n\nusing ::strrchr;\n\nusing ::strspn;\n\nusing ::strstr;\n\n// MSVCRT, GNU libc and its derivates already have the correct prototype in <string.h> #ifdef __cplusplus\n#if !defined(__GLIBC__) && !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_)\ninline _LIBCPP_INLINE_VISIBILITY       char* strchr(      char* __s, int __c) {return ::strchr(__s, __c);}\ninline _LIBCPP_INLINE_VISIBILITY       char* strpbrk(      char* __s1, const char* __s2) {return ::strpbrk(__s1, __s2);}\ninline _LIBCPP_INLINE_VISIBILITY       char* strrchr(      char* __s, int __c) {return ::strrchr(__s, __c);}\ninline _LIBCPP_INLINE_VISIBILITY       void* memchr(      void* __s, int __c, size_t __n) {return ::memchr(__s, __c, __n);}\ninline _LIBCPP_INLINE_VISIBILITY       char* strstr(      char* __s1, const char* __s2) {return ::strstr(__s1, __s2);}\n#endif\n\n#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS\nusing ::strtok;\n#endif\nusing ::memset;\nusing ::strerror;\nusing ::strlen;\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CSTRING\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/ctgmath",
    "content": "// -*- C++ -*-\n//===-------------------------- ctgmath -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CTGMATH\n#define _LIBCPP_CTGMATH\n\n/*\n    ctgmath synopsis\n\n#include <ccomplex>\n#include <cmath>\n\n*/\n\n#include <ccomplex>\n#include <cmath>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#endif  // _LIBCPP_CTGMATH\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/ctime",
    "content": "// -*- C++ -*-\n//===---------------------------- ctime -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CTIME\n#define _LIBCPP_CTIME\n\n/*\n    ctime synopsis\n\nMacros:\n\n    NULL\n    CLOCKS_PER_SEC\n\nnamespace std\n{\n\nTypes:\n\n    clock_t\n    size_t\n    time_t\n    tm\n\nclock_t clock();\ndouble difftime(time_t time1, time_t time0);\ntime_t mktime(tm* timeptr);\ntime_t time(time_t* timer);\nchar* asctime(const tm* timeptr);\nchar* ctime(const time_t* timer);\ntm*    gmtime(const time_t* timer);\ntm* localtime(const time_t* timer);\nsize_t strftime(char* restrict s, size_t maxsize, const char* restrict format,\n                const tm* restrict timeptr);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <time.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing ::clock_t;\nusing ::size_t;\nusing ::time_t;\nusing ::tm;\nusing ::clock;\nusing ::difftime;\nusing ::mktime;\nusing ::time;\n#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS\nusing ::asctime;\nusing ::ctime;\nusing ::gmtime;\nusing ::localtime;\n#endif\nusing ::strftime;\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CTIME\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cwchar",
    "content": "// -*- C++ -*-\n//===--------------------------- cwchar -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CWCHAR\n#define _LIBCPP_CWCHAR\n\n/*\n    cwchar synopsis\n\nMacros:\n\n    NULL\n    WCHAR_MAX\n    WCHAR_MIN\n    WEOF\n\nnamespace std\n{\n\nTypes:\n\n    mbstate_t\n    size_t\n    tm\n    wint_t\n\nint fwprintf(FILE* restrict stream, const wchar_t* restrict format, ...);\nint fwscanf(FILE* restrict stream, const wchar_t* restrict format, ...);\nint swprintf(wchar_t* restrict s, size_t n, const wchar_t* restrict format, ...);\nint swscanf(const wchar_t* restrict s, const wchar_t* restrict format, ...);\nint vfwprintf(FILE* restrict stream, const wchar_t* restrict format, va_list arg);\nint vfwscanf(FILE* restrict stream, const wchar_t* restrict format, va_list arg);  // C99\nint vswprintf(wchar_t* restrict s, size_t n, const wchar_t* restrict format, va_list arg);\nint vswscanf(const wchar_t* restrict s, const wchar_t* restrict format, va_list arg);  // C99\nint vwprintf(const wchar_t* restrict format, va_list arg);\nint vwscanf(const wchar_t* restrict format, va_list arg);  // C99\nint wprintf(const wchar_t* restrict format, ...);\nint wscanf(const wchar_t* restrict format, ...);\nwint_t fgetwc(FILE* stream);\nwchar_t* fgetws(wchar_t* restrict s, int n, FILE* restrict stream);\nwint_t fputwc(wchar_t c, FILE* stream);\nint fputws(const wchar_t* restrict s, FILE* restrict stream);\nint fwide(FILE* stream, int mode);\nwint_t getwc(FILE* stream);\nwint_t getwchar();\nwint_t putwc(wchar_t c, FILE* stream);\nwint_t putwchar(wchar_t c);\nwint_t ungetwc(wint_t c, FILE* stream);\ndouble wcstod(const wchar_t* restrict nptr, wchar_t** restrict endptr);\nfloat wcstof(const wchar_t* restrict nptr, wchar_t** restrict endptr);         // C99\nlong double wcstold(const wchar_t* restrict nptr, wchar_t** restrict endptr);  // C99\nlong wcstol(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);\nlong long wcstoll(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);  // C99\nunsigned long wcstoul(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);\nunsigned long long wcstoull(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);  // C99\nwchar_t* wcscpy(wchar_t* restrict s1, const wchar_t* restrict s2);\nwchar_t* wcsncpy(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);\nwchar_t* wcscat(wchar_t* restrict s1, const wchar_t* restrict s2);\nwchar_t* wcsncat(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);\nint wcscmp(const wchar_t* s1, const wchar_t* s2);\nint wcscoll(const wchar_t* s1, const wchar_t* s2);\nint wcsncmp(const wchar_t* s1, const wchar_t* s2, size_t n);\nsize_t wcsxfrm(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);\nconst wchar_t* wcschr(const wchar_t* s, wchar_t c);\n      wchar_t* wcschr(      wchar_t* s, wchar_t c);\nsize_t wcscspn(const wchar_t* s1, const wchar_t* s2);\nsize_t wcslen(const wchar_t* s);\nconst wchar_t* wcspbrk(const wchar_t* s1, const wchar_t* s2);\n      wchar_t* wcspbrk(      wchar_t* s1, const wchar_t* s2);\nconst wchar_t* wcsrchr(const wchar_t* s, wchar_t c);\n      wchar_t* wcsrchr(      wchar_t* s, wchar_t c);\nsize_t wcsspn(const wchar_t* s1, const wchar_t* s2);\nconst wchar_t* wcsstr(const wchar_t* s1, const wchar_t* s2);\n      wchar_t* wcsstr(      wchar_t* s1, const wchar_t* s2);\nwchar_t* wcstok(wchar_t* restrict s1, const wchar_t* restrict s2, wchar_t** restrict ptr);\nconst wchar_t* wmemchr(const wchar_t* s, wchar_t c, size_t n);\n      wchar_t* wmemchr(      wchar_t* s, wchar_t c, size_t n);\nint wmemcmp(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);\nwchar_t* wmemcpy(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);\nwchar_t* wmemmove(wchar_t* s1, const wchar_t* s2, size_t n);\nwchar_t* wmemset(wchar_t* s, wchar_t c, size_t n);\nsize_t wcsftime(wchar_t* restrict s, size_t maxsize, const wchar_t* restrict format,\n                const tm* restrict timeptr);\nwint_t btowc(int c);\nint wctob(wint_t c);\nint mbsinit(const mbstate_t* ps);\nsize_t mbrlen(const char* restrict s, size_t n, mbstate_t* restrict ps);\nsize_t mbrtowc(wchar_t* restrict pwc, const char* restrict s, size_t n, mbstate_t* restrict ps);\nsize_t wcrtomb(char* restrict s, wchar_t wc, mbstate_t* restrict ps);\nsize_t mbsrtowcs(wchar_t* restrict dst, const char** restrict src, size_t len,\n                 mbstate_t* restrict ps);\nsize_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,\n                 mbstate_t* restrict ps);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <cwctype>\n#include <wchar.h>\n#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)\n#include <support/win32/support.h> // pull in *swprintf defines\n#endif // _LIBCPP_MSVCRT\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing ::mbstate_t;\nusing ::size_t;\nusing ::tm;\nusing ::wint_t;\nusing ::FILE;\nusing ::fwprintf;\nusing ::fwscanf;\nusing ::swprintf;\nusing ::vfwprintf;\nusing ::vswprintf;\n#ifndef _LIBCPP_MSVCRT\nusing ::swscanf;\nusing ::vfwscanf;\nusing ::vswscanf;\n#endif // _LIBCPP_MSVCRT\nusing ::fgetwc;\nusing ::fgetws;\nusing ::fputwc;\nusing ::fputws;\nusing ::fwide;\nusing ::getwc;\nusing ::putwc;\nusing ::ungetwc;\nusing ::wcstod;\n#ifndef _LIBCPP_MSVCRT\nusing ::wcstof;\nusing ::wcstold;\n#endif // _LIBCPP_MSVCRT\nusing ::wcstol;\n#ifndef _LIBCPP_HAS_NO_LONG_LONG\nusing ::wcstoll;\n#endif // _LIBCPP_HAS_NO_LONG_LONG\nusing ::wcstoul;\n#ifndef _LIBCPP_HAS_NO_LONG_LONG\nusing ::wcstoull;\n#endif // _LIBCPP_HAS_NO_LONG_LONG\nusing ::wcscpy;\nusing ::wcsncpy;\nusing ::wcscat;\nusing ::wcsncat;\nusing ::wcscmp;\nusing ::wcscoll;\nusing ::wcsncmp;\nusing ::wcsxfrm;\n\n#if defined(_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_)\n\nusing ::wcschr;\nusing ::wcspbrk;\nusing ::wcsrchr;\nusing ::wcsstr;\nusing ::wmemchr;\n\n#else\n\ninline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcschr(const wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);}\ninline _LIBCPP_INLINE_VISIBILITY       wchar_t* wcschr(      wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);}\n\ninline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcspbrk(const wchar_t* __s1, const wchar_t* __s2) {return ::wcspbrk(__s1, __s2);}\ninline _LIBCPP_INLINE_VISIBILITY       wchar_t* wcspbrk(      wchar_t* __s1, const wchar_t* __s2) {return ::wcspbrk(__s1, __s2);}\n\ninline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcsrchr(const wchar_t* __s, wchar_t __c) {return ::wcsrchr(__s, __c);}\ninline _LIBCPP_INLINE_VISIBILITY       wchar_t* wcsrchr(      wchar_t* __s, wchar_t __c) {return ::wcsrchr(__s, __c);}\n\ninline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcsstr(const wchar_t* __s1, const wchar_t* __s2) {return ::wcsstr(__s1, __s2);}\ninline _LIBCPP_INLINE_VISIBILITY       wchar_t* wcsstr(      wchar_t* __s1, const wchar_t* __s2) {return ::wcsstr(__s1, __s2);}\n\ninline _LIBCPP_INLINE_VISIBILITY const wchar_t* wmemchr(const wchar_t* __s, wchar_t __c, size_t __n) {return ::wmemchr(__s, __c, __n);}\ninline _LIBCPP_INLINE_VISIBILITY       wchar_t* wmemchr(      wchar_t* __s, wchar_t __c, size_t __n) {return ::wmemchr(__s, __c, __n);}\n\n#endif\n\nusing ::wcscspn;\nusing ::wcslen;\nusing ::wcsspn;\nusing ::wcstok;\nusing ::wmemcmp;\nusing ::wmemcpy;\nusing ::wmemmove;\nusing ::wmemset;\nusing ::wcsftime;\nusing ::btowc;\nusing ::wctob;\nusing ::mbsinit;\nusing ::mbrlen;\nusing ::mbrtowc;\nusing ::wcrtomb;\nusing ::mbsrtowcs;\nusing ::wcsrtombs;\n\n#ifndef _LIBCPP_HAS_NO_STDIN\nusing ::getwchar;\n#ifndef _LIBCPP_MSVCRT\nusing ::vwscanf;\n#endif // _LIBCPP_MSVCRT\nusing ::wscanf;\n#endif\n\n#ifndef _LIBCPP_HAS_NO_STDOUT\nusing ::putwchar;\nusing ::vwprintf;\nusing ::wprintf;\n#endif\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CWCHAR\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/cwctype",
    "content": "// -*- C++ -*-\n//===--------------------------- cwctype ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CWCTYPE\n#define _LIBCPP_CWCTYPE\n\n/*\n    cwctype synopsis\n\nMacros:\n\n    WEOF\n\nnamespace std\n{\n\nTypes:\n\n    wint_t\n    wctrans_t\n    wctype_t\n\nint iswalnum(wint_t wc);\nint iswalpha(wint_t wc);\nint iswblank(wint_t wc);  // C99\nint iswcntrl(wint_t wc);\nint iswdigit(wint_t wc);\nint iswgraph(wint_t wc);\nint iswlower(wint_t wc);\nint iswprint(wint_t wc);\nint iswpunct(wint_t wc);\nint iswspace(wint_t wc);\nint iswupper(wint_t wc);\nint iswxdigit(wint_t wc);\nint iswctype(wint_t wc, wctype_t desc);\nwctype_t wctype(const char* property);\nwint_t towlower(wint_t wc);\nwint_t towupper(wint_t wc);\nwint_t towctrans(wint_t wc, wctrans_t desc);\nwctrans_t wctrans(const char* property);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <cctype>\n#include <wctype.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nusing ::wint_t;\nusing ::wctrans_t;\nusing ::wctype_t;\n\n#ifdef iswalnum\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswalnum(wint_t __wc) {return iswalnum(__wc);}\n#undef iswalnum\ninline _LIBCPP_INLINE_VISIBILITY int iswalnum(wint_t __wc) {return __libcpp_iswalnum(__wc);}\n#else  // iswalnum\nusing ::iswalnum;\n#endif\n\n#ifdef iswalpha\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswalpha(wint_t __wc) {return iswalpha(__wc);}\n#undef iswalpha\ninline _LIBCPP_INLINE_VISIBILITY int iswalpha(wint_t __wc) {return __libcpp_iswalpha(__wc);}\n#else  // iswalpha\nusing ::iswalpha;\n#endif\n\n#ifdef iswblank\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswblank(wint_t __wc) {return iswblank(__wc);}\n#undef iswblank\ninline _LIBCPP_INLINE_VISIBILITY int iswblank(wint_t __wc) {return __libcpp_iswblank(__wc);}\n#else  // iswblank\nusing ::iswblank;\n#endif\n\n#ifdef iswcntrl\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswcntrl(wint_t __wc) {return iswcntrl(__wc);}\n#undef iswcntrl\ninline _LIBCPP_INLINE_VISIBILITY int iswcntrl(wint_t __wc) {return __libcpp_iswcntrl(__wc);}\n#else  // iswcntrl\nusing ::iswcntrl;\n#endif\n\n#ifdef iswdigit\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswdigit(wint_t __wc) {return iswdigit(__wc);}\n#undef iswdigit\ninline _LIBCPP_INLINE_VISIBILITY int iswdigit(wint_t __wc) {return __libcpp_iswdigit(__wc);}\n#else  // iswdigit\nusing ::iswdigit;\n#endif\n\n#ifdef iswgraph\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswgraph(wint_t __wc) {return iswgraph(__wc);}\n#undef iswgraph\ninline _LIBCPP_INLINE_VISIBILITY int iswgraph(wint_t __wc) {return __libcpp_iswgraph(__wc);}\n#else  // iswgraph\nusing ::iswgraph;\n#endif\n\n#ifdef iswlower\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswlower(wint_t __wc) {return iswlower(__wc);}\n#undef iswlower\ninline _LIBCPP_INLINE_VISIBILITY int iswlower(wint_t __wc) {return __libcpp_iswlower(__wc);}\n#else  // iswlower\nusing ::iswlower;\n#endif\n\n#ifdef iswprint\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswprint(wint_t __wc) {return iswprint(__wc);}\n#undef iswprint\ninline _LIBCPP_INLINE_VISIBILITY int iswprint(wint_t __wc) {return __libcpp_iswprint(__wc);}\n#else  // iswprint\nusing ::iswprint;\n#endif\n\n#ifdef iswpunct\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswpunct(wint_t __wc) {return iswpunct(__wc);}\n#undef iswpunct\ninline _LIBCPP_INLINE_VISIBILITY int iswpunct(wint_t __wc) {return __libcpp_iswpunct(__wc);}\n#else  // iswpunct\nusing ::iswpunct;\n#endif\n\n#ifdef iswspace\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswspace(wint_t __wc) {return iswspace(__wc);}\n#undef iswspace\ninline _LIBCPP_INLINE_VISIBILITY int iswspace(wint_t __wc) {return __libcpp_iswspace(__wc);}\n#else  // iswspace\nusing ::iswspace;\n#endif\n\n#ifdef iswupper\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswupper(wint_t __wc) {return iswupper(__wc);}\n#undef iswupper\ninline _LIBCPP_INLINE_VISIBILITY int iswupper(wint_t __wc) {return __libcpp_iswupper(__wc);}\n#else  // iswupper\nusing ::iswupper;\n#endif\n\n#ifdef iswxdigit\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswxdigit(wint_t __wc) {return iswxdigit(__wc);}\n#undef iswxdigit\ninline _LIBCPP_INLINE_VISIBILITY int iswxdigit(wint_t __wc) {return __libcpp_iswxdigit(__wc);}\n#else  // iswxdigit\nusing ::iswxdigit;\n#endif\n\n#ifdef iswctype\ninline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswctype(wint_t __w, wctype_t __d) {return iswctype(__w, __d);}\n#undef iswctype\ninline _LIBCPP_INLINE_VISIBILITY int iswctype(wint_t __w, wctype_t __d) {return __libcpp_iswctype(__w, __d);}\n#else  // iswctype\nusing ::iswctype;\n#endif\n\n#ifdef wctype\ninline _LIBCPP_INLINE_VISIBILITY wctype_t __libcpp_wctype(const char* __p) {return wctype(__p);}\n#undef wctype\ninline _LIBCPP_INLINE_VISIBILITY wctype_t wctype(const char* __p) {return __libcpp_wctype(__p);}\n#else  // wctype\nusing ::wctype;\n#endif\n\n#ifdef towlower\ninline _LIBCPP_INLINE_VISIBILITY wint_t __libcpp_towlower(wint_t __wc) {return towlower(__wc);}\n#undef towlower\ninline _LIBCPP_INLINE_VISIBILITY wint_t towlower(wint_t __wc) {return __libcpp_towlower(__wc);}\n#else  // towlower\nusing ::towlower;\n#endif\n\n#ifdef towupper\ninline _LIBCPP_INLINE_VISIBILITY wint_t __libcpp_towupper(wint_t __wc) {return towupper(__wc);}\n#undef towupper\ninline _LIBCPP_INLINE_VISIBILITY wint_t towupper(wint_t __wc) {return __libcpp_towupper(__wc);}\n#else  // towupper\nusing ::towupper;\n#endif\n\n#ifdef towctrans\ninline _LIBCPP_INLINE_VISIBILITY wint_t __libcpp_towctrans(wint_t __wc, wctype_t __d) {return towctrans(__wc, __d);}\n#undef towctrans\ninline _LIBCPP_INLINE_VISIBILITY wint_t towctrans(wint_t __wc, wctype_t __d) {return __libcpp_towctrans(__wc, __d);}\n#else  // towctrans\nusing ::towctrans;\n#endif\n\n#ifdef wctrans\ninline _LIBCPP_INLINE_VISIBILITY wctrans_t __libcpp_wctrans(const char* __p) {return wctrans(__p);}\n#undef wctrans\ninline _LIBCPP_INLINE_VISIBILITY wctrans_t wctrans(const char* __p) {return __libcpp_wctrans(__p);}\n#else  // wctrans\nusing ::wctrans;\n#endif\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_CWCTYPE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/deque",
    "content": "// -*- C++ -*-\n//===---------------------------- deque -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_DEQUE\n#define _LIBCPP_DEQUE\n\n/*\n    deque synopsis\n\nnamespace std\n{\n\ntemplate <class T, class Allocator = allocator<T> >\nclass deque\n{\npublic:\n    // types:\n    typedef T value_type;\n    typedef Allocator allocator_type;\n\n    typedef typename allocator_type::reference       reference;\n    typedef typename allocator_type::const_reference const_reference;\n    typedef implementation-defined                   iterator;\n    typedef implementation-defined                   const_iterator;\n    typedef typename allocator_type::size_type       size_type;\n    typedef typename allocator_type::difference_type difference_type;\n\n    typedef typename allocator_type::pointer         pointer;\n    typedef typename allocator_type::const_pointer   const_pointer;\n    typedef std::reverse_iterator<iterator>          reverse_iterator;\n    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;\n\n    // construct/copy/destroy:\n    deque() noexcept(is_nothrow_default_constructible<allocator_type>::value);\n    explicit deque(const allocator_type& a);\n    explicit deque(size_type n);\n    explicit deque(size_type n, const allocator_type& a); // C++14\n    deque(size_type n, const value_type& v);\n    deque(size_type n, const value_type& v, const allocator_type& a);\n    template <class InputIterator>\n        deque(InputIterator f, InputIterator l);\n    template <class InputIterator>\n        deque(InputIterator f, InputIterator l, const allocator_type& a);\n    deque(const deque& c);\n    deque(deque&& c)\n        noexcept(is_nothrow_move_constructible<allocator_type>::value);\n    deque(initializer_list<value_type> il, const Allocator& a = allocator_type());\n    deque(const deque& c, const allocator_type& a);\n    deque(deque&& c, const allocator_type& a);\n    ~deque();\n\n    deque& operator=(const deque& c);\n    deque& operator=(deque&& c)\n        noexcept(\n             allocator_type::propagate_on_container_move_assignment::value &&\n             is_nothrow_move_assignable<allocator_type>::value);\n    deque& operator=(initializer_list<value_type> il);\n\n    template <class InputIterator>\n        void assign(InputIterator f, InputIterator l);\n    void assign(size_type n, const value_type& v);\n    void assign(initializer_list<value_type> il);\n\n    allocator_type get_allocator() const noexcept;\n\n    // iterators:\n\n    iterator       begin() noexcept;\n    const_iterator begin() const noexcept;\n    iterator       end() noexcept;\n    const_iterator end() const noexcept;\n\n    reverse_iterator       rbegin() noexcept;\n    const_reverse_iterator rbegin() const noexcept;\n    reverse_iterator       rend() noexcept;\n    const_reverse_iterator rend() const noexcept;\n\n    const_iterator         cbegin() const noexcept;\n    const_iterator         cend() const noexcept;\n    const_reverse_iterator crbegin() const noexcept;\n    const_reverse_iterator crend() const noexcept;\n\n    // capacity:\n    size_type size() const noexcept;\n    size_type max_size() const noexcept;\n    void resize(size_type n);\n    void resize(size_type n, const value_type& v);\n    void shrink_to_fit();\n    bool empty() const noexcept;\n\n    // element access:\n    reference operator[](size_type i);\n    const_reference operator[](size_type i) const;\n    reference at(size_type i);\n    const_reference at(size_type i) const;\n    reference front();\n    const_reference front() const;\n    reference back();\n    const_reference back() const;\n\n    // modifiers:\n    void push_front(const value_type& v);\n    void push_front(value_type&& v);\n    void push_back(const value_type& v);\n    void push_back(value_type&& v);\n    template <class... Args> void emplace_front(Args&&... args);\n    template <class... Args> void emplace_back(Args&&... args);\n    template <class... Args> iterator emplace(const_iterator p, Args&&... args);\n    iterator insert(const_iterator p, const value_type& v);\n    iterator insert(const_iterator p, value_type&& v);\n    iterator insert(const_iterator p, size_type n, const value_type& v);\n    template <class InputIterator>\n        iterator insert(const_iterator p, InputIterator f, InputIterator l);\n    iterator insert(const_iterator p, initializer_list<value_type> il);\n    void pop_front();\n    void pop_back();\n    iterator erase(const_iterator p);\n    iterator erase(const_iterator f, const_iterator l);\n    void swap(deque& c)\n        noexcept(allocator_traits<allocator_type>::is_always_equal::value);  // C++17\n    void clear() noexcept;\n};\n\ntemplate <class T, class Allocator>\n    bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);\ntemplate <class T, class Allocator>\n    bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);\ntemplate <class T, class Allocator>\n    bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);\ntemplate <class T, class Allocator>\n    bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y);\ntemplate <class T, class Allocator>\n    bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);\ntemplate <class T, class Allocator>\n    bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);\n\n// specialized algorithms:\ntemplate <class T, class Allocator>\n    void swap(deque<T,Allocator>& x, deque<T,Allocator>& y)\n         noexcept(noexcept(x.swap(y)));\n\n}  // std\n\n*/\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#include <__config>\n#include <__split_buffer>\n#include <type_traits>\n#include <initializer_list>\n#include <iterator>\n#include <algorithm>\n#include <stdexcept>\n\n#include <__undef_min_max>\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Tp, class _Allocator> class __deque_base;\ntemplate <class _Tp, class _Allocator = allocator<_Tp> > class _LIBCPP_TYPE_VIS_ONLY deque;\n\ntemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer,\n          class _DiffType, _DiffType _BlockSize>\nclass _LIBCPP_TYPE_VIS_ONLY __deque_iterator;\n\ntemplate <class _RAIter,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\ncopy(_RAIter __f,\n     _RAIter __l,\n     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,\n     typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _OutputIterator>\n_OutputIterator\ncopy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n     _OutputIterator __r);\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\ncopy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);\n\ntemplate <class _RAIter,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\ncopy_backward(_RAIter __f,\n              _RAIter __l,\n              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,\n              typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _OutputIterator>\n_OutputIterator\ncopy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n              _OutputIterator __r);\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\ncopy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);\n\ntemplate <class _RAIter,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\nmove(_RAIter __f,\n     _RAIter __l,\n     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,\n     typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _OutputIterator>\n_OutputIterator\nmove(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n     _OutputIterator __r);\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\nmove(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);\n\ntemplate <class _RAIter,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\nmove_backward(_RAIter __f,\n              _RAIter __l,\n              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,\n              typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _OutputIterator>\n_OutputIterator\nmove_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n              _OutputIterator __r);\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\nmove_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);\n\ntemplate <class _ValueType, class _Pointer, class _Reference, class _MapPointer,\n          class _DiffType, _DiffType _BlockSize>\nclass _LIBCPP_TYPE_VIS_ONLY __deque_iterator\n{\n    typedef _MapPointer __map_iterator;\npublic:\n    typedef _Pointer  pointer;\n    typedef _DiffType difference_type;\nprivate:\n    __map_iterator __m_iter_;\n    pointer        __ptr_;\n\n    static const difference_type __block_size = _BlockSize;\npublic:\n    typedef _ValueType                  value_type;\n    typedef random_access_iterator_tag  iterator_category;\n    typedef _Reference                  reference;\n\n    _LIBCPP_INLINE_VISIBILITY __deque_iterator() _NOEXCEPT\n#if _LIBCPP_STD_VER > 11\n     : __m_iter_(nullptr), __ptr_(nullptr)\n#endif\n     {}\n\n    template <class _Pp, class _Rp, class _MP>\n    _LIBCPP_INLINE_VISIBILITY\n    __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, __block_size>& __it,\n                typename enable_if<is_convertible<_Pp, pointer>::value>::type* = 0) _NOEXCEPT\n        : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {}\n\n    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *__ptr_;}\n    _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return __ptr_;}\n\n    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator++()\n    {\n        if (++__ptr_ - *__m_iter_ == __block_size)\n        {\n            ++__m_iter_;\n            __ptr_ = *__m_iter_;\n        }\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator++(int)\n    {\n        __deque_iterator __tmp = *this;\n        ++(*this);\n        return __tmp;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator--()\n    {\n        if (__ptr_ == *__m_iter_)\n        {\n            --__m_iter_;\n            __ptr_ = *__m_iter_ + __block_size;\n        }\n        --__ptr_;\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator--(int)\n    {\n        __deque_iterator __tmp = *this;\n        --(*this);\n        return __tmp;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator+=(difference_type __n)\n    {\n        if (__n != 0)\n        {\n            __n += __ptr_ - *__m_iter_;\n            if (__n > 0)\n            {\n                __m_iter_ += __n / __block_size;\n                __ptr_ = *__m_iter_ + __n % __block_size;\n            }\n            else // (__n < 0)\n            {\n                difference_type __z = __block_size - 1 - __n;\n                __m_iter_ -= __z / __block_size;\n                __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size);\n            }\n        }\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator-=(difference_type __n)\n    {\n        return *this += -__n;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator+(difference_type __n) const\n    {\n        __deque_iterator __t(*this);\n        __t += __n;\n        return __t;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator-(difference_type __n) const\n    {\n        __deque_iterator __t(*this);\n        __t -= __n;\n        return __t;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it)\n        {return __it + __n;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y)\n    {\n        if (__x != __y)\n            return (__x.__m_iter_ - __y.__m_iter_) * __block_size\n                 + (__x.__ptr_ - *__x.__m_iter_)\n                 - (__y.__ptr_ - *__y.__m_iter_);\n        return 0;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const\n        {return *(*this + __n);}\n\n    _LIBCPP_INLINE_VISIBILITY friend\n        bool operator==(const __deque_iterator& __x, const __deque_iterator& __y)\n        {return __x.__ptr_ == __y.__ptr_;}\n\n    _LIBCPP_INLINE_VISIBILITY friend\n        bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y)\n        {return !(__x == __y);}\n\n    _LIBCPP_INLINE_VISIBILITY friend\n        bool operator<(const __deque_iterator& __x, const __deque_iterator& __y)\n        {return __x.__m_iter_ < __y.__m_iter_ ||\n               (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);}\n\n    _LIBCPP_INLINE_VISIBILITY friend\n        bool operator>(const __deque_iterator& __x, const __deque_iterator& __y)\n        {return __y < __x;}\n\n    _LIBCPP_INLINE_VISIBILITY friend\n        bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y)\n        {return !(__y < __x);}\n\n    _LIBCPP_INLINE_VISIBILITY friend\n        bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y)\n        {return !(__x < __y);}\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT\n        : __m_iter_(__m), __ptr_(__p) {}\n\n    template <class _Tp, class _Ap> friend class __deque_base;\n    template <class _Tp, class _Ap> friend class _LIBCPP_TYPE_VIS_ONLY deque;\n    template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp>\n        friend class _LIBCPP_TYPE_VIS_ONLY __deque_iterator;\n\n    template <class _RAIter,\n              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n    friend\n    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\n    copy(_RAIter __f,\n         _RAIter __l,\n         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,\n         typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);\n\n    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n              class _OutputIterator>\n    friend\n    _OutputIterator\n    copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n         _OutputIterator __r);\n\n    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n    friend\n    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\n    copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);\n\n    template <class _RAIter,\n              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n    friend\n    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\n    copy_backward(_RAIter __f,\n                  _RAIter __l,\n                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,\n                  typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);\n\n    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n              class _OutputIterator>\n    friend\n    _OutputIterator\n    copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n                  _OutputIterator __r);\n\n    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n    friend\n    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\n    copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);\n\n    template <class _RAIter,\n              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n    friend\n    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\n    move(_RAIter __f,\n         _RAIter __l,\n         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,\n         typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);\n\n    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n              class _OutputIterator>\n    friend\n    _OutputIterator\n    move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n         _OutputIterator __r);\n\n    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n    friend\n    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\n    move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);\n\n    template <class _RAIter,\n              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n    friend\n    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\n    move_backward(_RAIter __f,\n                  _RAIter __l,\n                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,\n                  typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);\n\n    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n              class _OutputIterator>\n    friend\n    _OutputIterator\n    move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n                  _OutputIterator __r);\n\n    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n    friend\n    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\n    move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);\n};\n\n// copy\n\ntemplate <class _RAIter,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\ncopy(_RAIter __f,\n     _RAIter __l,\n     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,\n     typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)\n{\n    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;\n    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;\n    while (__f != __l)\n    {\n        pointer __rb = __r.__ptr_;\n        pointer __re = *__r.__m_iter_ + _B2;\n        difference_type __bs = __re - __rb;\n        difference_type __n = __l - __f;\n        _RAIter __m = __l;\n        if (__n > __bs)\n        {\n            __n = __bs;\n            __m = __f + __n;\n        }\n        _VSTD::copy(__f, __m, __rb);\n        __f = __m;\n        __r += __n;\n    }\n    return __r;\n}\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _OutputIterator>\n_OutputIterator\ncopy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n     _OutputIterator __r)\n{\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;\n    difference_type __n = __l - __f;\n    while (__n > 0)\n    {\n        pointer __fb = __f.__ptr_;\n        pointer __fe = *__f.__m_iter_ + _B1;\n        difference_type __bs = __fe - __fb;\n        if (__bs > __n)\n        {\n            __bs = __n;\n            __fe = __fb + __bs;\n        }\n        __r = _VSTD::copy(__fb, __fe, __r);\n        __n -= __bs;\n        __f += __bs;\n    }\n    return __r;\n}\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\ncopy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)\n{\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;\n    difference_type __n = __l - __f;\n    while (__n > 0)\n    {\n        pointer __fb = __f.__ptr_;\n        pointer __fe = *__f.__m_iter_ + _B1;\n        difference_type __bs = __fe - __fb;\n        if (__bs > __n)\n        {\n            __bs = __n;\n            __fe = __fb + __bs;\n        }\n        __r = _VSTD::copy(__fb, __fe, __r);\n        __n -= __bs;\n        __f += __bs;\n    }\n    return __r;\n}\n\n// copy_backward\n\ntemplate <class _RAIter,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\ncopy_backward(_RAIter __f,\n              _RAIter __l,\n              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,\n              typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)\n{\n    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;\n    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;\n    while (__f != __l)\n    {\n        __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);\n        pointer __rb = *__rp.__m_iter_;\n        pointer __re = __rp.__ptr_ + 1;\n        difference_type __bs = __re - __rb;\n        difference_type __n = __l - __f;\n        _RAIter __m = __f;\n        if (__n > __bs)\n        {\n            __n = __bs;\n            __m = __l - __n;\n        }\n        _VSTD::copy_backward(__m, __l, __re);\n        __l = __m;\n        __r -= __n;\n    }\n    return __r;\n}\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _OutputIterator>\n_OutputIterator\ncopy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n              _OutputIterator __r)\n{\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;\n    difference_type __n = __l - __f;\n    while (__n > 0)\n    {\n        --__l;\n        pointer __lb = *__l.__m_iter_;\n        pointer __le = __l.__ptr_ + 1;\n        difference_type __bs = __le - __lb;\n        if (__bs > __n)\n        {\n            __bs = __n;\n            __lb = __le - __bs;\n        }\n        __r = _VSTD::copy_backward(__lb, __le, __r);\n        __n -= __bs;\n        __l -= __bs - 1;\n    }\n    return __r;\n}\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\ncopy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)\n{\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;\n    difference_type __n = __l - __f;\n    while (__n > 0)\n    {\n        --__l;\n        pointer __lb = *__l.__m_iter_;\n        pointer __le = __l.__ptr_ + 1;\n        difference_type __bs = __le - __lb;\n        if (__bs > __n)\n        {\n            __bs = __n;\n            __lb = __le - __bs;\n        }\n        __r = _VSTD::copy_backward(__lb, __le, __r);\n        __n -= __bs;\n        __l -= __bs - 1;\n    }\n    return __r;\n}\n\n// move\n\ntemplate <class _RAIter,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\nmove(_RAIter __f,\n     _RAIter __l,\n     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,\n     typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)\n{\n    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;\n    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;\n    while (__f != __l)\n    {\n        pointer __rb = __r.__ptr_;\n        pointer __re = *__r.__m_iter_ + _B2;\n        difference_type __bs = __re - __rb;\n        difference_type __n = __l - __f;\n        _RAIter __m = __l;\n        if (__n > __bs)\n        {\n            __n = __bs;\n            __m = __f + __n;\n        }\n        _VSTD::move(__f, __m, __rb);\n        __f = __m;\n        __r += __n;\n    }\n    return __r;\n}\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _OutputIterator>\n_OutputIterator\nmove(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n     _OutputIterator __r)\n{\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;\n    difference_type __n = __l - __f;\n    while (__n > 0)\n    {\n        pointer __fb = __f.__ptr_;\n        pointer __fe = *__f.__m_iter_ + _B1;\n        difference_type __bs = __fe - __fb;\n        if (__bs > __n)\n        {\n            __bs = __n;\n            __fe = __fb + __bs;\n        }\n        __r = _VSTD::move(__fb, __fe, __r);\n        __n -= __bs;\n        __f += __bs;\n    }\n    return __r;\n}\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\nmove(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)\n{\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;\n    difference_type __n = __l - __f;\n    while (__n > 0)\n    {\n        pointer __fb = __f.__ptr_;\n        pointer __fe = *__f.__m_iter_ + _B1;\n        difference_type __bs = __fe - __fb;\n        if (__bs > __n)\n        {\n            __bs = __n;\n            __fe = __fb + __bs;\n        }\n        __r = _VSTD::move(__fb, __fe, __r);\n        __n -= __bs;\n        __f += __bs;\n    }\n    return __r;\n}\n\n// move_backward\n\ntemplate <class _RAIter,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\nmove_backward(_RAIter __f,\n              _RAIter __l,\n              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,\n              typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)\n{\n    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;\n    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;\n    while (__f != __l)\n    {\n        __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);\n        pointer __rb = *__rp.__m_iter_;\n        pointer __re = __rp.__ptr_ + 1;\n        difference_type __bs = __re - __rb;\n        difference_type __n = __l - __f;\n        _RAIter __m = __f;\n        if (__n > __bs)\n        {\n            __n = __bs;\n            __m = __l - __n;\n        }\n        _VSTD::move_backward(__m, __l, __re);\n        __l = __m;\n        __r -= __n;\n    }\n    return __r;\n}\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _OutputIterator>\n_OutputIterator\nmove_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n              _OutputIterator __r)\n{\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;\n    difference_type __n = __l - __f;\n    while (__n > 0)\n    {\n        --__l;\n        pointer __lb = *__l.__m_iter_;\n        pointer __le = __l.__ptr_ + 1;\n        difference_type __bs = __le - __lb;\n        if (__bs > __n)\n        {\n            __bs = __n;\n            __lb = __le - __bs;\n        }\n        __r = _VSTD::move_backward(__lb, __le, __r);\n        __n -= __bs;\n        __l -= __bs - 1;\n    }\n    return __r;\n}\n\ntemplate <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,\n          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>\n__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>\nmove_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,\n              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,\n              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)\n{\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;\n    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;\n    difference_type __n = __l - __f;\n    while (__n > 0)\n    {\n        --__l;\n        pointer __lb = *__l.__m_iter_;\n        pointer __le = __l.__ptr_ + 1;\n        difference_type __bs = __le - __lb;\n        if (__bs > __n)\n        {\n            __bs = __n;\n            __lb = __le - __bs;\n        }\n        __r = _VSTD::move_backward(__lb, __le, __r);\n        __n -= __bs;\n        __l -= __bs - 1;\n    }\n    return __r;\n}\n\ntemplate <bool>\nclass __deque_base_common\n{\nprotected:\n    void __throw_length_error() const;\n    void __throw_out_of_range() const;\n};\n\ntemplate <bool __b>\nvoid\n__deque_base_common<__b>::__throw_length_error() const\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    throw length_error(\"deque\");\n#endif\n}\n\ntemplate <bool __b>\nvoid\n__deque_base_common<__b>::__throw_out_of_range() const\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    throw out_of_range(\"deque\");\n#endif\n}\n\ntemplate <class _Tp, class _Allocator>\nclass __deque_base\n    : protected __deque_base_common<true>\n{\n    __deque_base(const __deque_base& __c);\n    __deque_base& operator=(const __deque_base& __c);\nprotected:\n    typedef _Tp                                      value_type;\n    typedef _Allocator                               allocator_type;\n    typedef allocator_traits<allocator_type>         __alloc_traits;\n    typedef value_type&                              reference;\n    typedef const value_type&                        const_reference;\n    typedef typename __alloc_traits::size_type       size_type;\n    typedef typename __alloc_traits::difference_type difference_type;\n    typedef typename __alloc_traits::pointer         pointer;\n    typedef typename __alloc_traits::const_pointer   const_pointer;\n\n    static const difference_type __block_size = sizeof(value_type) < 256 ? 4096 / sizeof(value_type) : 16;\n\n    typedef typename __rebind_alloc_helper<__alloc_traits, pointer>::type __pointer_allocator;\n    typedef allocator_traits<__pointer_allocator>        __map_traits;\n    typedef typename __map_traits::pointer               __map_pointer;\n    typedef typename __rebind_alloc_helper<__alloc_traits, const_pointer>::type __const_pointer_allocator;\n    typedef typename allocator_traits<__const_pointer_allocator>::const_pointer __map_const_pointer;\n    typedef __split_buffer<pointer, __pointer_allocator> __map;\n\n    typedef __deque_iterator<value_type, pointer, reference, __map_pointer,\n                             difference_type, __block_size>    iterator;\n    typedef __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer,\n                             difference_type, __block_size>    const_iterator;\n\n    __map __map_;\n    size_type __start_;\n    __compressed_pair<size_type, allocator_type> __size_;\n\n    iterator       begin() _NOEXCEPT;\n    const_iterator begin() const _NOEXCEPT;\n    iterator       end() _NOEXCEPT;\n    const_iterator end() const _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY size_type&            size()          {return __size_.first();}\n    _LIBCPP_INLINE_VISIBILITY\n    const size_type& size() const _NOEXCEPT {return __size_.first();}\n    _LIBCPP_INLINE_VISIBILITY allocator_type&       __alloc()       {return __size_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n    const allocator_type& __alloc() const _NOEXCEPT {return __size_.second();}\n\n    __deque_base()\n        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);\n    explicit __deque_base(const allocator_type& __a);\npublic:\n    ~__deque_base();\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    __deque_base(__deque_base&& __c)\n        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);\n    __deque_base(__deque_base&& __c, const allocator_type& __a);\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void swap(__deque_base& __c)\n#if _LIBCPP_STD_VER >= 14\n        _NOEXCEPT;\n#else\n        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || \n                    __is_nothrow_swappable<allocator_type>::value);\n#endif\nprotected:\n    void clear() _NOEXCEPT;\n\n    bool __invariants() const;\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign(__deque_base& __c)\n        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&\n                   is_nothrow_move_assignable<allocator_type>::value)\n    {\n        __map_ = _VSTD::move(__c.__map_);\n        __start_ = __c.__start_;\n        size() = __c.size();\n        __move_assign_alloc(__c);\n        __c.__start_ = __c.size() = 0;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__deque_base& __c)\n        _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||\n                   is_nothrow_move_assignable<allocator_type>::value)\n        {__move_assign_alloc(__c, integral_constant<bool,\n                      __alloc_traits::propagate_on_container_move_assignment::value>());}\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__deque_base& __c, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)\n        {\n            __alloc() = _VSTD::move(__c.__alloc());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__deque_base&, false_type) _NOEXCEPT\n        {}\n};\n\ntemplate <class _Tp, class _Allocator>\nbool\n__deque_base<_Tp, _Allocator>::__invariants() const\n{\n    if (!__map_.__invariants())\n        return false;\n    if (__map_.size() >= size_type(-1) / __block_size)\n        return false;\n    for (typename __map::const_iterator __i = __map_.begin(), __e = __map_.end();\n         __i != __e; ++__i)\n        if (*__i == nullptr)\n            return false;\n    if (__map_.size() != 0)\n    {\n        if (size() >= __map_.size() * __block_size)\n            return false;\n        if (__start_ >= __map_.size() * __block_size - size())\n            return false;\n    }\n    else\n    {\n        if (size() != 0)\n            return false;\n        if (__start_ != 0)\n            return false;\n    }\n    return true;\n}\n\ntemplate <class _Tp, class _Allocator>\ntypename __deque_base<_Tp, _Allocator>::iterator\n__deque_base<_Tp, _Allocator>::begin() _NOEXCEPT\n{\n    __map_pointer __mp = __map_.begin() + __start_ / __block_size;\n    return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);\n}\n\ntemplate <class _Tp, class _Allocator>\ntypename __deque_base<_Tp, _Allocator>::const_iterator\n__deque_base<_Tp, _Allocator>::begin() const _NOEXCEPT\n{\n    __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size);\n    return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);\n}\n\ntemplate <class _Tp, class _Allocator>\ntypename __deque_base<_Tp, _Allocator>::iterator\n__deque_base<_Tp, _Allocator>::end() _NOEXCEPT\n{\n    size_type __p = size() + __start_;\n    __map_pointer __mp = __map_.begin() + __p / __block_size;\n    return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);\n}\n\ntemplate <class _Tp, class _Allocator>\ntypename __deque_base<_Tp, _Allocator>::const_iterator\n__deque_base<_Tp, _Allocator>::end() const _NOEXCEPT\n{\n    size_type __p = size() + __start_;\n    __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size);\n    return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\n__deque_base<_Tp, _Allocator>::__deque_base()\n    _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)\n    : __start_(0), __size_(0) {}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\n__deque_base<_Tp, _Allocator>::__deque_base(const allocator_type& __a)\n    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {}\n\ntemplate <class _Tp, class _Allocator>\n__deque_base<_Tp, _Allocator>::~__deque_base()\n{\n    clear();\n    typename __map::iterator __i = __map_.begin();\n    typename __map::iterator __e = __map_.end();\n    for (; __i != __e; ++__i)\n        __alloc_traits::deallocate(__alloc(), *__i, __block_size);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\n__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c)\n    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)\n    : __map_(_VSTD::move(__c.__map_)),\n      __start_(_VSTD::move(__c.__start_)),\n      __size_(_VSTD::move(__c.__size_))\n{\n    __c.__start_ = 0;\n    __c.size() = 0;\n}\n\ntemplate <class _Tp, class _Allocator>\n__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c, const allocator_type& __a)\n    : __map_(_VSTD::move(__c.__map_), __pointer_allocator(__a)),\n      __start_(_VSTD::move(__c.__start_)),\n      __size_(_VSTD::move(__c.size()), __a)\n{\n    if (__a == __c.__alloc())\n    {\n        __c.__start_ = 0;\n        __c.size() = 0;\n    }\n    else\n    {\n        __map_.clear();\n        __start_ = 0;\n        size() = 0;\n    }\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\nvoid\n__deque_base<_Tp, _Allocator>::swap(__deque_base& __c)\n#if _LIBCPP_STD_VER >= 14\n        _NOEXCEPT\n#else\n        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || \n                    __is_nothrow_swappable<allocator_type>::value)\n#endif\n{\n    __map_.swap(__c.__map_);\n    _VSTD::swap(__start_, __c.__start_);\n    _VSTD::swap(size(), __c.size());\n    __swap_allocator(__alloc(), __c.__alloc());\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\n__deque_base<_Tp, _Allocator>::clear() _NOEXCEPT\n{\n    allocator_type& __a = __alloc();\n    for (iterator __i = begin(), __e = end(); __i != __e; ++__i)\n        __alloc_traits::destroy(__a, _VSTD::addressof(*__i));\n    size() = 0;\n    while (__map_.size() > 2)\n    {\n        __alloc_traits::deallocate(__a, __map_.front(), __block_size);\n        __map_.pop_front();\n    }\n    switch (__map_.size())\n    {\n    case 1:\n        __start_ = __block_size / 2;\n        break;\n    case 2:\n        __start_ = __block_size;\n        break;\n    }\n}\n\ntemplate <class _Tp, class _Allocator /*= allocator<_Tp>*/>\nclass _LIBCPP_TYPE_VIS_ONLY deque\n    : private __deque_base<_Tp, _Allocator>\n{\npublic:\n    // types:\n\n    typedef _Tp value_type;\n    typedef _Allocator allocator_type;\n\n    typedef __deque_base<value_type, allocator_type> __base;\n\n    typedef typename __base::__alloc_traits        __alloc_traits;\n    typedef typename __base::reference             reference;\n    typedef typename __base::const_reference       const_reference;\n    typedef typename __base::iterator              iterator;\n    typedef typename __base::const_iterator        const_iterator;\n    typedef typename __base::size_type             size_type;\n    typedef typename __base::difference_type       difference_type;\n\n    typedef typename __base::pointer               pointer;\n    typedef typename __base::const_pointer         const_pointer;\n    typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;\n    typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;\n\n    // construct/copy/destroy:\n    _LIBCPP_INLINE_VISIBILITY\n    deque()\n        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)\n        {}\n    _LIBCPP_INLINE_VISIBILITY explicit deque(const allocator_type& __a) : __base(__a) {}\n    explicit deque(size_type __n);\n#if _LIBCPP_STD_VER > 11\n    explicit deque(size_type __n, const _Allocator& __a);\n#endif\n    deque(size_type __n, const value_type& __v);\n    deque(size_type __n, const value_type& __v, const allocator_type& __a);\n    template <class _InputIter>\n        deque(_InputIter __f, _InputIter __l,\n              typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0);\n    template <class _InputIter>\n        deque(_InputIter __f, _InputIter __l, const allocator_type& __a,\n              typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0);\n    deque(const deque& __c);\n    deque(const deque& __c, const allocator_type& __a);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    deque(initializer_list<value_type> __il);\n    deque(initializer_list<value_type> __il, const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    deque& operator=(const deque& __c);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;}\n#endif   // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);\n    deque(deque&& __c, const allocator_type& __a);\n    deque& operator=(deque&& __c)\n        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&\n                   is_nothrow_move_assignable<allocator_type>::value);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    template <class _InputIter>\n        void assign(_InputIter __f, _InputIter __l,\n                    typename enable_if<__is_input_iterator<_InputIter>::value &&\n                                      !__is_random_access_iterator<_InputIter>::value>::type* = 0);\n    template <class _RAIter>\n        void assign(_RAIter __f, _RAIter __l,\n                    typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);\n    void assign(size_type __n, const value_type& __v);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    allocator_type get_allocator() const _NOEXCEPT;\n\n    // iterators:\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       begin() _NOEXCEPT       {return __base::begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin() const _NOEXCEPT {return __base::begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       end() _NOEXCEPT         {return __base::end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end()   const _NOEXCEPT {return __base::end();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    reverse_iterator       rbegin() _NOEXCEPT\n        {return       reverse_iterator(__base::end());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rbegin() const _NOEXCEPT\n        {return const_reverse_iterator(__base::end());}\n    _LIBCPP_INLINE_VISIBILITY\n    reverse_iterator       rend() _NOEXCEPT\n        {return       reverse_iterator(__base::begin());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rend()   const _NOEXCEPT\n        {return const_reverse_iterator(__base::begin());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator         cbegin()  const _NOEXCEPT\n        {return __base::begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator         cend()    const _NOEXCEPT\n        {return __base::end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crbegin() const _NOEXCEPT\n        {return const_reverse_iterator(__base::end());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crend()   const _NOEXCEPT\n        {return const_reverse_iterator(__base::begin());}\n\n    // capacity:\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const _NOEXCEPT {return __base::size();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const _NOEXCEPT\n        {return __alloc_traits::max_size(__base::__alloc());}\n    void resize(size_type __n);\n    void resize(size_type __n, const value_type& __v);\n    void shrink_to_fit() _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    bool empty() const _NOEXCEPT {return __base::size() == 0;}\n\n    // element access:\n    reference operator[](size_type __i);\n    const_reference operator[](size_type __i) const;\n    reference at(size_type __i);\n    const_reference at(size_type __i) const;\n    reference front();\n    const_reference front() const;\n    reference back();\n    const_reference back() const;\n\n    // 23.2.2.3 modifiers:\n    void push_front(const value_type& __v);\n    void push_back(const value_type& __v);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class... _Args> void emplace_front(_Args&&... __args);\n    template <class... _Args> void emplace_back(_Args&&... __args);\n    template <class... _Args> iterator emplace(const_iterator __p, _Args&&... __args);\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n    void push_front(value_type&& __v);\n    void push_back(value_type&& __v);\n    iterator insert(const_iterator __p, value_type&& __v);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    iterator insert(const_iterator __p, const value_type& __v);\n    iterator insert(const_iterator __p, size_type __n, const value_type& __v);\n    template <class _InputIter>\n        iterator insert(const_iterator __p, _InputIter __f, _InputIter __l,\n                         typename enable_if<__is_input_iterator<_InputIter>::value\n                                         &&!__is_forward_iterator<_InputIter>::value>::type* = 0);\n    template <class _ForwardIterator>\n        iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,\n                               typename enable_if<__is_forward_iterator<_ForwardIterator>::value\n                                         &&!__is_bidirectional_iterator<_ForwardIterator>::value>::type* = 0);\n    template <class _BiIter>\n        iterator insert(const_iterator __p, _BiIter __f, _BiIter __l,\n                         typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type* = 0);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator __p, initializer_list<value_type> __il)\n        {return insert(__p, __il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    void pop_front();\n    void pop_back();\n    iterator erase(const_iterator __p);\n    iterator erase(const_iterator __f, const_iterator __l);\n\n    void swap(deque& __c)\n#if _LIBCPP_STD_VER >= 14\n        _NOEXCEPT;\n#else\n        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||\n                   __is_nothrow_swappable<allocator_type>::value);\n#endif\n    void clear() _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool __invariants() const {return __base::__invariants();}\nprivate:\n    typedef typename __base::__map_const_pointer __map_const_pointer;\n\n    _LIBCPP_INLINE_VISIBILITY\n    static size_type __recommend_blocks(size_type __n)\n    {\n        return __n / __base::__block_size + (__n % __base::__block_size != 0);\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    size_type __capacity() const\n    {\n        return __base::__map_.size() == 0 ? 0 : __base::__map_.size() * __base::__block_size - 1;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    size_type __front_spare() const\n    {\n        return __base::__start_;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    size_type __back_spare() const\n    {\n        return __capacity() - (__base::__start_ + __base::size());\n    }\n\n    template <class _InpIter>\n        void __append(_InpIter __f, _InpIter __l,\n                 typename enable_if<__is_input_iterator<_InpIter>::value &&\n                                   !__is_forward_iterator<_InpIter>::value>::type* = 0);\n    template <class _ForIter>\n        void __append(_ForIter __f, _ForIter __l,\n                      typename enable_if<__is_forward_iterator<_ForIter>::value>::type* = 0);\n    void __append(size_type __n);\n    void __append(size_type __n, const value_type& __v);\n    void __erase_to_end(const_iterator __f);\n    void __add_front_capacity();\n    void __add_front_capacity(size_type __n);\n    void __add_back_capacity();\n    void __add_back_capacity(size_type __n);\n    iterator __move_and_check(iterator __f, iterator __l, iterator __r,\n                              const_pointer& __vt);\n    iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r,\n                                       const_pointer& __vt);\n    void __move_construct_and_check(iterator __f, iterator __l,\n                                    iterator __r, const_pointer& __vt);\n    void __move_construct_backward_and_check(iterator __f, iterator __l,\n                                             iterator __r, const_pointer& __vt);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const deque& __c)\n        {__copy_assign_alloc(__c, integral_constant<bool,\n                      __alloc_traits::propagate_on_container_copy_assignment::value>());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const deque& __c, true_type)\n        {\n            if (__base::__alloc() != __c.__alloc())\n            {\n                clear();\n                shrink_to_fit();\n            }\n            __base::__alloc() = __c.__alloc();\n            __base::__map_.__alloc() = __c.__map_.__alloc();\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const deque&, false_type)\n        {}\n\n    void __move_assign(deque& __c, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);\n    void __move_assign(deque& __c, false_type);\n};\n\ntemplate <class _Tp, class _Allocator>\ndeque<_Tp, _Allocator>::deque(size_type __n)\n{\n    if (__n > 0)\n        __append(__n);\n}\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp, class _Allocator>\ndeque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)\n    : __base(__a)\n{\n    if (__n > 0)\n        __append(__n);\n}\n#endif\n\ntemplate <class _Tp, class _Allocator>\ndeque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)\n{\n    if (__n > 0)\n        __append(__n, __v);\n}\n\ntemplate <class _Tp, class _Allocator>\ndeque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const allocator_type& __a)\n    : __base(__a)\n{\n    if (__n > 0)\n        __append(__n, __v);\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _InputIter>\ndeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l,\n              typename enable_if<__is_input_iterator<_InputIter>::value>::type*)\n{\n    __append(__f, __l);\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _InputIter>\ndeque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,\n              typename enable_if<__is_input_iterator<_InputIter>::value>::type*)\n    : __base(__a)\n{\n    __append(__f, __l);\n}\n\ntemplate <class _Tp, class _Allocator>\ndeque<_Tp, _Allocator>::deque(const deque& __c)\n    : __base(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))\n{\n    __append(__c.begin(), __c.end());\n}\n\ntemplate <class _Tp, class _Allocator>\ndeque<_Tp, _Allocator>::deque(const deque& __c, const allocator_type& __a)\n    : __base(__a)\n{\n    __append(__c.begin(), __c.end());\n}\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp, class _Allocator>\ndeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)\n{\n    __append(__il.begin(), __il.end());\n}\n\ntemplate <class _Tp, class _Allocator>\ndeque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)\n    : __base(__a)\n{\n    __append(__il.begin(), __il.end());\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp, class _Allocator>\ndeque<_Tp, _Allocator>&\ndeque<_Tp, _Allocator>::operator=(const deque& __c)\n{\n    if (this != &__c)\n    {\n        __copy_assign_alloc(__c);\n        assign(__c.begin(), __c.end());\n    }\n    return *this;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ndeque<_Tp, _Allocator>::deque(deque&& __c)\n    _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)\n    : __base(_VSTD::move(__c))\n{\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ndeque<_Tp, _Allocator>::deque(deque&& __c, const allocator_type& __a)\n    : __base(_VSTD::move(__c), __a)\n{\n    if (__a != __c.__alloc())\n    {\n        typedef move_iterator<iterator> _Ip;\n        assign(_Ip(__c.begin()), _Ip(__c.end()));\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ndeque<_Tp, _Allocator>&\ndeque<_Tp, _Allocator>::operator=(deque&& __c)\n        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&\n                   is_nothrow_move_assignable<allocator_type>::value)\n{\n    __move_assign(__c, integral_constant<bool,\n          __alloc_traits::propagate_on_container_move_assignment::value>());\n    return *this;\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::__move_assign(deque& __c, false_type)\n{\n    if (__base::__alloc() != __c.__alloc())\n    {\n        typedef move_iterator<iterator> _Ip;\n        assign(_Ip(__c.begin()), _Ip(__c.end()));\n    }\n    else\n        __move_assign(__c, true_type());\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::__move_assign(deque& __c, true_type)\n    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)\n{\n    clear();\n    shrink_to_fit();\n    __base::__move_assign(__c);\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _InputIter>\nvoid\ndeque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l,\n                               typename enable_if<__is_input_iterator<_InputIter>::value &&\n                                                 !__is_random_access_iterator<_InputIter>::value>::type*)\n{\n    iterator __i = __base::begin();\n    iterator __e = __base::end();\n    for (; __f != __l && __i != __e; ++__f, (void) ++__i)\n        *__i = *__f;\n    if (__f != __l)\n        __append(__f, __l);\n    else\n        __erase_to_end(__i);\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _RAIter>\nvoid\ndeque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l,\n                               typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)\n{\n    if (static_cast<size_type>(__l - __f) > __base::size())\n    {\n        _RAIter __m = __f + __base::size();\n        _VSTD::copy(__f, __m, __base::begin());\n        __append(__m, __l);\n    }\n    else\n        __erase_to_end(_VSTD::copy(__f, __l, __base::begin()));\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v)\n{\n    if (__n > __base::size())\n    {\n        _VSTD::fill_n(__base::begin(), __base::size(), __v);\n        __n -= __base::size();\n        __append(__n, __v);\n    }\n    else\n        __erase_to_end(_VSTD::fill_n(__base::begin(), __n, __v));\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\n_Allocator\ndeque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT\n{\n    return __base::__alloc();\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::resize(size_type __n)\n{\n    if (__n > __base::size())\n        __append(__n - __base::size());\n    else if (__n < __base::size())\n        __erase_to_end(__base::begin() + __n);\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v)\n{\n    if (__n > __base::size())\n        __append(__n - __base::size(), __v);\n    else if (__n < __base::size())\n        __erase_to_end(__base::begin() + __n);\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT\n{\n    allocator_type& __a = __base::__alloc();\n    if (empty())\n    {\n        while (__base::__map_.size() > 0)\n        {\n            __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);\n            __base::__map_.pop_back();\n        }\n        __base::__start_ = 0;\n    }\n    else\n    {\n        if (__front_spare() >= __base::__block_size)\n        {\n            __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);\n            __base::__map_.pop_front();\n            __base::__start_ -= __base::__block_size;\n        }\n        if (__back_spare() >= __base::__block_size)\n        {\n            __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);\n            __base::__map_.pop_back();\n        }\n    }\n    __base::__map_.shrink_to_fit();\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename deque<_Tp, _Allocator>::reference\ndeque<_Tp, _Allocator>::operator[](size_type __i)\n{\n    size_type __p = __base::__start_ + __i;\n    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename deque<_Tp, _Allocator>::const_reference\ndeque<_Tp, _Allocator>::operator[](size_type __i) const\n{\n    size_type __p = __base::__start_ + __i;\n    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename deque<_Tp, _Allocator>::reference\ndeque<_Tp, _Allocator>::at(size_type __i)\n{\n    if (__i >= __base::size())\n        __base::__throw_out_of_range();\n    size_type __p = __base::__start_ + __i;\n    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename deque<_Tp, _Allocator>::const_reference\ndeque<_Tp, _Allocator>::at(size_type __i) const\n{\n    if (__i >= __base::size())\n        __base::__throw_out_of_range();\n    size_type __p = __base::__start_ + __i;\n    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename deque<_Tp, _Allocator>::reference\ndeque<_Tp, _Allocator>::front()\n{\n    return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)\n                                      + __base::__start_ % __base::__block_size);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename deque<_Tp, _Allocator>::const_reference\ndeque<_Tp, _Allocator>::front() const\n{\n    return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)\n                                      + __base::__start_ % __base::__block_size);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename deque<_Tp, _Allocator>::reference\ndeque<_Tp, _Allocator>::back()\n{\n    size_type __p = __base::size() + __base::__start_ - 1;\n    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename deque<_Tp, _Allocator>::const_reference\ndeque<_Tp, _Allocator>::back() const\n{\n    size_type __p = __base::size() + __base::__start_ - 1;\n    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::push_back(const value_type& __v)\n{\n    allocator_type& __a = __base::__alloc();\n    if (__back_spare() == 0)\n        __add_back_capacity();\n    // __back_spare() >= 1\n    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v);\n    ++__base::size();\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::push_back(value_type&& __v)\n{\n    allocator_type& __a = __base::__alloc();\n    if (__back_spare() == 0)\n        __add_back_capacity();\n    // __back_spare() >= 1\n    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v));\n    ++__base::size();\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class... _Args>\nvoid\ndeque<_Tp, _Allocator>::emplace_back(_Args&&... __args)\n{\n    allocator_type& __a = __base::__alloc();\n    if (__back_spare() == 0)\n        __add_back_capacity();\n    // __back_spare() >= 1\n    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::forward<_Args>(__args)...);\n    ++__base::size();\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::push_front(const value_type& __v)\n{\n    allocator_type& __a = __base::__alloc();\n    if (__front_spare() == 0)\n        __add_front_capacity();\n    // __front_spare() >= 1\n    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);\n    --__base::__start_;\n    ++__base::size();\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::push_front(value_type&& __v)\n{\n    allocator_type& __a = __base::__alloc();\n    if (__front_spare() == 0)\n        __add_front_capacity();\n    // __front_spare() >= 1\n    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v));\n    --__base::__start_;\n    ++__base::size();\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class... _Args>\nvoid\ndeque<_Tp, _Allocator>::emplace_front(_Args&&... __args)\n{\n    allocator_type& __a = __base::__alloc();\n    if (__front_spare() == 0)\n        __add_front_capacity();\n    // __front_spare() >= 1\n    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...);\n    --__base::__start_;\n    ++__base::size();\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\ntypename deque<_Tp, _Allocator>::iterator\ndeque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)\n{\n    size_type __pos = __p - __base::begin();\n    size_type __to_end = __base::size() - __pos;\n    allocator_type& __a = __base::__alloc();\n    if (__pos < __to_end)\n    {   // insert by shifting things backward\n        if (__front_spare() == 0)\n            __add_front_capacity();\n        // __front_spare() >= 1\n        if (__pos == 0)\n        {\n            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);\n            --__base::__start_;\n            ++__base::size();\n        }\n        else\n        {\n            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);\n            iterator __b = __base::begin();\n            iterator __bm1 = _VSTD::prev(__b);\n            if (__vt == pointer_traits<const_pointer>::pointer_to(*__b))\n                __vt = pointer_traits<const_pointer>::pointer_to(*__bm1);\n            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));\n            --__base::__start_;\n            ++__base::size();\n            if (__pos > 1)\n                __b = __move_and_check(_VSTD::next(__b), __b + __pos, __b, __vt);\n            *__b = *__vt;\n        }\n    }\n    else\n    {   // insert by shifting things forward\n        if (__back_spare() == 0)\n            __add_back_capacity();\n        // __back_capacity >= 1\n        size_type __de = __base::size() - __pos;\n        if (__de == 0)\n        {\n            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v);\n            ++__base::size();\n        }\n        else\n        {\n            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);\n            iterator __e = __base::end();\n            iterator __em1 = _VSTD::prev(__e);\n            if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1))\n                __vt = pointer_traits<const_pointer>::pointer_to(*__e);\n            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));\n            ++__base::size();\n            if (__de > 1)\n                __e = __move_backward_and_check(__e - __de, __em1, __e, __vt);\n            *--__e = *__vt;\n        }\n    }\n    return __base::begin() + __pos;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\ntypename deque<_Tp, _Allocator>::iterator\ndeque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)\n{\n    size_type __pos = __p - __base::begin();\n    size_type __to_end = __base::size() - __pos;\n    allocator_type& __a = __base::__alloc();\n    if (__pos < __to_end)\n    {   // insert by shifting things backward\n        if (__front_spare() == 0)\n            __add_front_capacity();\n        // __front_spare() >= 1\n        if (__pos == 0)\n        {\n            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v));\n            --__base::__start_;\n            ++__base::size();\n        }\n        else\n        {\n            iterator __b = __base::begin();\n            iterator __bm1 = _VSTD::prev(__b);\n            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));\n            --__base::__start_;\n            ++__base::size();\n            if (__pos > 1)\n                __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);\n            *__b = _VSTD::move(__v);\n        }\n    }\n    else\n    {   // insert by shifting things forward\n        if (__back_spare() == 0)\n            __add_back_capacity();\n        // __back_capacity >= 1\n        size_type __de = __base::size() - __pos;\n        if (__de == 0)\n        {\n            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v));\n            ++__base::size();\n        }\n        else\n        {\n            iterator __e = __base::end();\n            iterator __em1 = _VSTD::prev(__e);\n            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));\n            ++__base::size();\n            if (__de > 1)\n                __e = _VSTD::move_backward(__e - __de, __em1, __e);\n            *--__e = _VSTD::move(__v);\n        }\n    }\n    return __base::begin() + __pos;\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class... _Args>\ntypename deque<_Tp, _Allocator>::iterator\ndeque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)\n{\n    size_type __pos = __p - __base::begin();\n    size_type __to_end = __base::size() - __pos;\n    allocator_type& __a = __base::__alloc();\n    if (__pos < __to_end)\n    {   // insert by shifting things backward\n        if (__front_spare() == 0)\n            __add_front_capacity();\n        // __front_spare() >= 1\n        if (__pos == 0)\n        {\n            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...);\n            --__base::__start_;\n            ++__base::size();\n        }\n        else\n        {\n            value_type __tmp(_VSTD::forward<_Args>(__args)...);\n            iterator __b = __base::begin();\n            iterator __bm1 = _VSTD::prev(__b);\n            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));\n            --__base::__start_;\n            ++__base::size();\n            if (__pos > 1)\n                __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);\n            *__b = _VSTD::move(__tmp);\n        }\n    }\n    else\n    {   // insert by shifting things forward\n        if (__back_spare() == 0)\n            __add_back_capacity();\n        // __back_capacity >= 1\n        size_type __de = __base::size() - __pos;\n        if (__de == 0)\n        {\n            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::forward<_Args>(__args)...);\n            ++__base::size();\n        }\n        else\n        {\n            value_type __tmp(_VSTD::forward<_Args>(__args)...);\n            iterator __e = __base::end();\n            iterator __em1 = _VSTD::prev(__e);\n            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));\n            ++__base::size();\n            if (__de > 1)\n                __e = _VSTD::move_backward(__e - __de, __em1, __e);\n            *--__e = _VSTD::move(__tmp);\n        }\n    }\n    return __base::begin() + __pos;\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\ntypename deque<_Tp, _Allocator>::iterator\ndeque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v)\n{\n    size_type __pos = __p - __base::begin();\n    size_type __to_end = __base::size() - __pos;\n    allocator_type& __a = __base::__alloc();\n    if (__pos < __to_end)\n    {   // insert by shifting things backward\n        if (__n > __front_spare())\n            __add_front_capacity(__n - __front_spare());\n        // __n <= __front_spare()\n        iterator __old_begin = __base::begin();\n        iterator __i = __old_begin;\n        if (__n > __pos)\n        {\n            for (size_type __m = __n - __pos; __m; --__m, --__base::__start_, ++__base::size())\n                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), __v);\n            __n = __pos;\n        }\n        if (__n > 0)\n        {\n            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);\n            iterator __obn = __old_begin + __n;\n            __move_construct_backward_and_check(__old_begin, __obn, __i, __vt);\n            if (__n < __pos)\n                __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt);\n            _VSTD::fill_n(__old_begin, __n, *__vt);\n        }\n    }\n    else\n    {   // insert by shifting things forward\n        size_type __back_capacity = __back_spare();\n        if (__n > __back_capacity)\n            __add_back_capacity(__n - __back_capacity);\n        // __n <= __back_capacity\n        iterator __old_end = __base::end();\n        iterator __i = __old_end;\n        size_type __de = __base::size() - __pos;\n        if (__n > __de)\n        {\n            for (size_type __m = __n - __de; __m; --__m, ++__i, ++__base::size())\n                __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v);\n            __n = __de;\n        }\n        if (__n > 0)\n        {\n            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);\n            iterator __oen = __old_end - __n;\n            __move_construct_and_check(__oen, __old_end, __i, __vt);\n            if (__n < __de)\n                __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt);\n            _VSTD::fill_n(__old_end - __n, __n, *__vt);\n        }\n    }\n    return __base::begin() + __pos;\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _InputIter>\ntypename deque<_Tp, _Allocator>::iterator\ndeque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,\n                               typename enable_if<__is_input_iterator<_InputIter>::value\n                                               &&!__is_forward_iterator<_InputIter>::value>::type*)\n{\n    __split_buffer<value_type, allocator_type&> __buf(__base::__alloc());\n    __buf.__construct_at_end(__f, __l);\n    typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;\n    return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _ForwardIterator>\ntypename deque<_Tp, _Allocator>::iterator\ndeque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,\n                               typename enable_if<__is_forward_iterator<_ForwardIterator>::value\n                                               &&!__is_bidirectional_iterator<_ForwardIterator>::value>::type*)\n{\n    size_type __n = _VSTD::distance(__f, __l);\n    __split_buffer<value_type, allocator_type&> __buf(__n, 0, __base::__alloc());\n    __buf.__construct_at_end(__f, __l);\n    typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd;\n    return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end()));\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _BiIter>\ntypename deque<_Tp, _Allocator>::iterator\ndeque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,\n                               typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type*)\n{\n    size_type __n = _VSTD::distance(__f, __l);\n    size_type __pos = __p - __base::begin();\n    size_type __to_end = __base::size() - __pos;\n    allocator_type& __a = __base::__alloc();\n    if (__pos < __to_end)\n    {   // insert by shifting things backward\n        if (__n > __front_spare())\n            __add_front_capacity(__n - __front_spare());\n        // __n <= __front_spare()\n        iterator __old_begin = __base::begin();\n        iterator __i = __old_begin;\n        _BiIter __m = __f;\n        if (__n > __pos)\n        {\n            __m = __pos < __n / 2 ? _VSTD::prev(__l, __pos) : _VSTD::next(__f, __n - __pos);\n            for (_BiIter __j = __m; __j != __f; --__base::__start_, ++__base::size())\n                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), *--__j);\n            __n = __pos;\n        }\n        if (__n > 0)\n        {\n            iterator __obn = __old_begin + __n;\n            for (iterator __j = __obn; __j != __old_begin;)\n            {\n                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), _VSTD::move(*--__j));\n                --__base::__start_;\n                ++__base::size();\n            }\n            if (__n < __pos)\n                __old_begin = _VSTD::move(__obn, __old_begin + __pos, __old_begin);\n            _VSTD::copy(__m, __l, __old_begin);\n        }\n    }\n    else\n    {   // insert by shifting things forward\n        size_type __back_capacity = __back_spare();\n        if (__n > __back_capacity)\n            __add_back_capacity(__n - __back_capacity);\n        // __n <= __back_capacity\n        iterator __old_end = __base::end();\n        iterator __i = __old_end;\n        _BiIter __m = __l;\n        size_type __de = __base::size() - __pos;\n        if (__n > __de)\n        {\n            __m = __de < __n / 2 ? _VSTD::next(__f, __de) : _VSTD::prev(__l, __n - __de);\n            for (_BiIter __j = __m; __j != __l; ++__i, (void) ++__j, ++__base::size())\n                __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__j);\n            __n = __de;\n        }\n        if (__n > 0)\n        {\n            iterator __oen = __old_end - __n;\n            for (iterator __j = __oen; __j != __old_end; ++__i, ++__j, ++__base::size())\n                __alloc_traits::construct(__a, _VSTD::addressof(*__i), _VSTD::move(*__j));\n            if (__n < __de)\n                __old_end = _VSTD::move_backward(__old_end - __de, __oen, __old_end);\n            _VSTD::copy_backward(__f, __m, __old_end);\n        }\n    }\n    return __base::begin() + __pos;\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _InpIter>\nvoid\ndeque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,\n                                 typename enable_if<__is_input_iterator<_InpIter>::value &&\n                                                   !__is_forward_iterator<_InpIter>::value>::type*)\n{\n    for (; __f != __l; ++__f)\n        push_back(*__f);\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _ForIter>\nvoid\ndeque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l,\n                                 typename enable_if<__is_forward_iterator<_ForIter>::value>::type*)\n{\n    size_type __n = _VSTD::distance(__f, __l);\n    allocator_type& __a = __base::__alloc();\n    size_type __back_capacity = __back_spare();\n    if (__n > __back_capacity)\n        __add_back_capacity(__n - __back_capacity);\n    // __n <= __back_capacity\n    for (iterator __i = __base::end(); __f != __l; ++__i, (void) ++__f, ++__base::size())\n        __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__f);\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::__append(size_type __n)\n{\n    allocator_type& __a = __base::__alloc();\n    size_type __back_capacity = __back_spare();\n    if (__n > __back_capacity)\n        __add_back_capacity(__n - __back_capacity);\n    // __n <= __back_capacity\n    for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size())\n        __alloc_traits::construct(__a, _VSTD::addressof(*__i));\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v)\n{\n    allocator_type& __a = __base::__alloc();\n    size_type __back_capacity = __back_spare();\n    if (__n > __back_capacity)\n        __add_back_capacity(__n - __back_capacity);\n    // __n <= __back_capacity\n    for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size())\n        __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v);\n}\n\n// Create front capacity for one block of elements.\n// Strong guarantee.  Either do it or don't touch anything.\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::__add_front_capacity()\n{\n    allocator_type& __a = __base::__alloc();\n    if (__back_spare() >= __base::__block_size)\n    {\n        __base::__start_ += __base::__block_size;\n        pointer __pt = __base::__map_.back();\n        __base::__map_.pop_back();\n        __base::__map_.push_front(__pt);\n    }\n    // Else if __base::__map_.size() < __base::__map_.capacity() then we need to allocate 1 buffer\n    else if (__base::__map_.size() < __base::__map_.capacity())\n    {   // we can put the new buffer into the map, but don't shift things around\n        // until all buffers are allocated.  If we throw, we don't need to fix\n        // anything up (any added buffers are undetectible)\n        if (__base::__map_.__front_spare() > 0)\n            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));\n        else\n        {\n            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));\n            // Done allocating, reorder capacity\n            pointer __pt = __base::__map_.back();\n            __base::__map_.pop_back();\n            __base::__map_.push_front(__pt);\n        }\n        __base::__start_ = __base::__map_.size() == 1 ?\n                               __base::__block_size / 2 :\n                               __base::__start_ + __base::__block_size;\n    }\n    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.\n    else\n    {\n        __split_buffer<pointer, typename __base::__pointer_allocator&>\n            __buf(max<size_type>(2 * __base::__map_.capacity(), 1),\n                  0, __base::__map_.__alloc());\n\n        typedef __allocator_destructor<_Allocator> _Dp;\n        unique_ptr<pointer, _Dp> __hold(\n            __alloc_traits::allocate(__a, __base::__block_size),\n                _Dp(__a, __base::__block_size));\n        __buf.push_back(__hold.get());\n        __hold.release();\n    \n        for (typename __base::__map_pointer __i = __base::__map_.begin();\n                __i != __base::__map_.end(); ++__i)\n            __buf.push_back(*__i);\n        _VSTD::swap(__base::__map_.__first_, __buf.__first_);\n        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);\n        _VSTD::swap(__base::__map_.__end_, __buf.__end_);\n        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());\n        __base::__start_ = __base::__map_.size() == 1 ?\n                               __base::__block_size / 2 :\n                               __base::__start_ + __base::__block_size;\n    }\n}\n\n// Create front capacity for __n elements.\n// Strong guarantee.  Either do it or don't touch anything.\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::__add_front_capacity(size_type __n)\n{\n    allocator_type& __a = __base::__alloc();\n    size_type __nb = __recommend_blocks(__n + __base::__map_.empty());\n    // Number of unused blocks at back:\n    size_type __back_capacity = __back_spare() / __base::__block_size;\n    __back_capacity = _VSTD::min(__back_capacity, __nb);  // don't take more than you need\n    __nb -= __back_capacity;  // number of blocks need to allocate\n    // If __nb == 0, then we have sufficient capacity.\n    if (__nb == 0)\n    {\n        __base::__start_ += __base::__block_size * __back_capacity;\n        for (; __back_capacity > 0; --__back_capacity)\n        {\n            pointer __pt = __base::__map_.back();\n            __base::__map_.pop_back();\n            __base::__map_.push_front(__pt);\n        }\n    }\n    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers\n    else if (__nb <= __base::__map_.capacity() - __base::__map_.size())\n    {   // we can put the new buffers into the map, but don't shift things around\n        // until all buffers are allocated.  If we throw, we don't need to fix\n        // anything up (any added buffers are undetectible)\n        for (; __nb > 0; --__nb, __base::__start_ += __base::__block_size - (__base::__map_.size() == 1))\n        {\n            if (__base::__map_.__front_spare() == 0)\n                break;\n            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));\n        }\n        for (; __nb > 0; --__nb, ++__back_capacity)\n            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));\n        // Done allocating, reorder capacity\n        __base::__start_ += __back_capacity * __base::__block_size;\n        for (; __back_capacity > 0; --__back_capacity)\n        {\n            pointer __pt = __base::__map_.back();\n            __base::__map_.pop_back();\n            __base::__map_.push_front(__pt);\n        }\n    }\n    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.\n    else\n    {\n        size_type __ds = (__nb + __back_capacity) * __base::__block_size - __base::__map_.empty();\n        __split_buffer<pointer, typename __base::__pointer_allocator&>\n            __buf(max<size_type>(2* __base::__map_.capacity(),\n                                 __nb + __base::__map_.size()),\n                  0, __base::__map_.__alloc());\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (; __nb > 0; --__nb)\n                __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            for (typename __base::__map_pointer __i = __buf.begin();\n                    __i != __buf.end(); ++__i)\n                __alloc_traits::deallocate(__a, *__i, __base::__block_size);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        for (; __back_capacity > 0; --__back_capacity)\n        {\n            __buf.push_back(__base::__map_.back());\n            __base::__map_.pop_back();\n        }\n        for (typename __base::__map_pointer __i = __base::__map_.begin();\n                __i != __base::__map_.end(); ++__i)\n            __buf.push_back(*__i);\n        _VSTD::swap(__base::__map_.__first_, __buf.__first_);\n        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);\n        _VSTD::swap(__base::__map_.__end_, __buf.__end_);\n        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());\n        __base::__start_ += __ds;\n    }\n}\n\n// Create back capacity for one block of elements.\n// Strong guarantee.  Either do it or don't touch anything.\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::__add_back_capacity()\n{\n    allocator_type& __a = __base::__alloc();\n    if (__front_spare() >= __base::__block_size)\n    {\n        __base::__start_ -= __base::__block_size;\n        pointer __pt = __base::__map_.front();\n        __base::__map_.pop_front();\n        __base::__map_.push_back(__pt);\n    }\n    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers\n    else if (__base::__map_.size() < __base::__map_.capacity())\n    {   // we can put the new buffer into the map, but don't shift things around\n        // until it is allocated.  If we throw, we don't need to fix\n        // anything up (any added buffers are undetectible)\n        if (__base::__map_.__back_spare() != 0)\n            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));\n        else\n        {\n            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));\n            // Done allocating, reorder capacity\n            pointer __pt = __base::__map_.front();\n            __base::__map_.pop_front();\n            __base::__map_.push_back(__pt);\n        }\n    }\n    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.\n    else\n    {\n        __split_buffer<pointer, typename __base::__pointer_allocator&>\n            __buf(max<size_type>(2* __base::__map_.capacity(), 1),\n                  __base::__map_.size(),\n                  __base::__map_.__alloc());\n\n        typedef __allocator_destructor<_Allocator> _Dp;\n        unique_ptr<pointer, _Dp> __hold(\n            __alloc_traits::allocate(__a, __base::__block_size),\n                _Dp(__a, __base::__block_size));\n        __buf.push_back(__hold.get());\n        __hold.release();\n\n        for (typename __base::__map_pointer __i = __base::__map_.end();\n                __i != __base::__map_.begin();)\n            __buf.push_front(*--__i);\n        _VSTD::swap(__base::__map_.__first_, __buf.__first_);\n        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);\n        _VSTD::swap(__base::__map_.__end_, __buf.__end_);\n        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());\n    }\n}\n\n// Create back capacity for __n elements.\n// Strong guarantee.  Either do it or don't touch anything.\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::__add_back_capacity(size_type __n)\n{\n    allocator_type& __a = __base::__alloc();\n    size_type __nb = __recommend_blocks(__n + __base::__map_.empty());\n    // Number of unused blocks at front:\n    size_type __front_capacity = __front_spare() / __base::__block_size;\n    __front_capacity = _VSTD::min(__front_capacity, __nb);  // don't take more than you need\n    __nb -= __front_capacity;  // number of blocks need to allocate\n    // If __nb == 0, then we have sufficient capacity.\n    if (__nb == 0)\n    {\n        __base::__start_ -= __base::__block_size * __front_capacity;\n        for (; __front_capacity > 0; --__front_capacity)\n        {\n            pointer __pt = __base::__map_.front();\n            __base::__map_.pop_front();\n            __base::__map_.push_back(__pt);\n        }\n    }\n    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers\n    else if (__nb <= __base::__map_.capacity() - __base::__map_.size())\n    {   // we can put the new buffers into the map, but don't shift things around\n        // until all buffers are allocated.  If we throw, we don't need to fix\n        // anything up (any added buffers are undetectible)\n        for (; __nb > 0; --__nb)\n        {\n            if (__base::__map_.__back_spare() == 0)\n                break;\n            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));\n        }\n        for (; __nb > 0; --__nb, ++__front_capacity, __base::__start_ +=\n                                 __base::__block_size - (__base::__map_.size() == 1))\n            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));\n        // Done allocating, reorder capacity\n        __base::__start_ -= __base::__block_size * __front_capacity;\n        for (; __front_capacity > 0; --__front_capacity)\n        {\n            pointer __pt = __base::__map_.front();\n            __base::__map_.pop_front();\n            __base::__map_.push_back(__pt);\n        }\n    }\n    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.\n    else\n    {\n        size_type __ds = __front_capacity * __base::__block_size;\n        __split_buffer<pointer, typename __base::__pointer_allocator&>\n            __buf(max<size_type>(2* __base::__map_.capacity(),\n                                 __nb + __base::__map_.size()),\n                  __base::__map_.size() - __front_capacity,\n                  __base::__map_.__alloc());\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (; __nb > 0; --__nb)\n                __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            for (typename __base::__map_pointer __i = __buf.begin();\n                    __i != __buf.end(); ++__i)\n                __alloc_traits::deallocate(__a, *__i, __base::__block_size);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        for (; __front_capacity > 0; --__front_capacity)\n        {\n            __buf.push_back(__base::__map_.front());\n            __base::__map_.pop_front();\n        }\n        for (typename __base::__map_pointer __i = __base::__map_.end();\n                __i != __base::__map_.begin();)\n            __buf.push_front(*--__i);\n        _VSTD::swap(__base::__map_.__first_, __buf.__first_);\n        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);\n        _VSTD::swap(__base::__map_.__end_, __buf.__end_);\n        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());\n        __base::__start_ -= __ds;\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::pop_front()\n{\n    allocator_type& __a = __base::__alloc();\n    __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() +\n                                                    __base::__start_ / __base::__block_size) +\n                                                    __base::__start_ % __base::__block_size));\n    --__base::size();\n    if (++__base::__start_ >= 2 * __base::__block_size)\n    {\n        __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);\n        __base::__map_.pop_front();\n        __base::__start_ -= __base::__block_size;\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::pop_back()\n{\n    allocator_type& __a = __base::__alloc();\n    size_type __p = __base::size() + __base::__start_ - 1;\n    __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() +\n                                                    __p / __base::__block_size) +\n                                                    __p % __base::__block_size));\n    --__base::size();\n    if (__back_spare() >= 2 * __base::__block_size)\n    {\n        __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);\n        __base::__map_.pop_back();\n    }\n}\n\n// move assign [__f, __l) to [__r, __r + (__l-__f)).\n// If __vt points into [__f, __l), then subtract (__f - __r) from __vt.\ntemplate <class _Tp, class _Allocator>\ntypename deque<_Tp, _Allocator>::iterator\ndeque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r,\n                                         const_pointer& __vt)\n{\n    // as if\n    //   for (; __f != __l; ++__f, ++__r)\n    //       *__r = _VSTD::move(*__f);\n    difference_type __n = __l - __f;\n    while (__n > 0)\n    {\n        pointer __fb = __f.__ptr_;\n        pointer __fe = *__f.__m_iter_ + __base::__block_size;\n        difference_type __bs = __fe - __fb;\n        if (__bs > __n)\n        {\n            __bs = __n;\n            __fe = __fb + __bs;\n        }\n        if (__fb <= __vt && __vt < __fe)\n            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_;\n        __r = _VSTD::move(__fb, __fe, __r);\n        __n -= __bs;\n        __f += __bs;\n    }\n    return __r;\n}\n\n// move assign [__f, __l) to [__r - (__l-__f), __r) backwards.\n// If __vt points into [__f, __l), then add (__r - __l) to __vt.\ntemplate <class _Tp, class _Allocator>\ntypename deque<_Tp, _Allocator>::iterator\ndeque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r,\n                                                  const_pointer& __vt)\n{\n    // as if\n    //   while (__f != __l)\n    //       *--__r = _VSTD::move(*--__l);\n    difference_type __n = __l - __f;\n    while (__n > 0)\n    {\n        --__l;\n        pointer __lb = *__l.__m_iter_;\n        pointer __le = __l.__ptr_ + 1;\n        difference_type __bs = __le - __lb;\n        if (__bs > __n)\n        {\n            __bs = __n;\n            __lb = __le - __bs;\n        }\n        if (__lb <= __vt && __vt < __le)\n            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_;\n        __r = _VSTD::move_backward(__lb, __le, __r);\n        __n -= __bs;\n        __l -= __bs - 1;\n    }\n    return __r;\n}\n\n// move construct [__f, __l) to [__r, __r + (__l-__f)).\n// If __vt points into [__f, __l), then add (__r - __f) to __vt.\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l,\n                                                   iterator __r, const_pointer& __vt)\n{\n    allocator_type& __a = __base::__alloc();\n    // as if\n    //   for (; __f != __l; ++__r, ++__f, ++__base::size())\n    //       __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__f));\n    difference_type __n = __l - __f;\n    while (__n > 0)\n    {\n        pointer __fb = __f.__ptr_;\n        pointer __fe = *__f.__m_iter_ + __base::__block_size;\n        difference_type __bs = __fe - __fb;\n        if (__bs > __n)\n        {\n            __bs = __n;\n            __fe = __fb + __bs;\n        }\n        if (__fb <= __vt && __vt < __fe)\n            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_;\n        for (; __fb != __fe; ++__fb, ++__r, ++__base::size())\n            __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__fb));\n        __n -= __bs;\n        __f += __bs;\n    }\n}\n\n// move construct [__f, __l) to [__r - (__l-__f), __r) backwards.\n// If __vt points into [__f, __l), then subtract (__l - __r) from __vt.\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l,\n                                                            iterator __r, const_pointer& __vt)\n{\n    allocator_type& __a = __base::__alloc();\n    // as if\n    //   for (iterator __j = __l; __j != __f;)\n    //   {\n    //       __alloc_traitsconstruct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__j));\n    //       --__base::__start_;\n    //       ++__base::size();\n    //   }\n    difference_type __n = __l - __f;\n    while (__n > 0)\n    {\n        --__l;\n        pointer __lb = *__l.__m_iter_;\n        pointer __le = __l.__ptr_ + 1;\n        difference_type __bs = __le - __lb;\n        if (__bs > __n)\n        {\n            __bs = __n;\n            __lb = __le - __bs;\n        }\n        if (__lb <= __vt && __vt < __le)\n            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_;\n        while (__le != __lb)\n        {\n            __alloc_traits::construct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__le));\n            --__base::__start_;\n            ++__base::size();\n        }\n        __n -= __bs;\n        __l -= __bs - 1;\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\ntypename deque<_Tp, _Allocator>::iterator\ndeque<_Tp, _Allocator>::erase(const_iterator __f)\n{\n    iterator __b = __base::begin();\n    difference_type __pos = __f - __b;\n    iterator __p = __b + __pos;\n    allocator_type& __a = __base::__alloc();\n    if (__pos <= (__base::size() - 1) / 2)\n    {   // erase from front\n        _VSTD::move_backward(__b, __p, _VSTD::next(__p));\n        __alloc_traits::destroy(__a, _VSTD::addressof(*__b));\n        --__base::size();\n        ++__base::__start_;\n        if (__front_spare() >= 2 * __base::__block_size)\n        {\n            __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);\n            __base::__map_.pop_front();\n            __base::__start_ -= __base::__block_size;\n        }\n    }\n    else\n    {   // erase from back\n        iterator __i = _VSTD::move(_VSTD::next(__p), __base::end(), __p);\n        __alloc_traits::destroy(__a, _VSTD::addressof(*__i));\n        --__base::size();\n        if (__back_spare() >= 2 * __base::__block_size)\n        {\n            __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);\n            __base::__map_.pop_back();\n        }\n    }\n    return __base::begin() + __pos;\n}\n\ntemplate <class _Tp, class _Allocator>\ntypename deque<_Tp, _Allocator>::iterator\ndeque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)\n{\n    difference_type __n = __l - __f;\n    iterator __b = __base::begin();\n    difference_type __pos = __f - __b;\n    iterator __p = __b + __pos;\n    if (__n > 0)\n    {\n        allocator_type& __a = __base::__alloc();\n        if (__pos <= (__base::size() - __n) / 2)\n        {   // erase from front\n            iterator __i = _VSTD::move_backward(__b, __p, __p + __n);\n            for (; __b != __i; ++__b)\n                __alloc_traits::destroy(__a, _VSTD::addressof(*__b));\n            __base::size() -= __n;\n            __base::__start_ += __n;\n            while (__front_spare() >= 2 * __base::__block_size)\n            {\n                __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);\n                __base::__map_.pop_front();\n                __base::__start_ -= __base::__block_size;\n            }\n        }\n        else\n        {   // erase from back\n            iterator __i = _VSTD::move(__p + __n, __base::end(), __p);\n            for (iterator __e = __base::end(); __i != __e; ++__i)\n                __alloc_traits::destroy(__a, _VSTD::addressof(*__i));\n            __base::size() -= __n;\n            while (__back_spare() >= 2 * __base::__block_size)\n            {\n                __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);\n                __base::__map_.pop_back();\n            }\n        }\n    }\n    return __base::begin() + __pos;\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\ndeque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)\n{\n    iterator __e = __base::end();\n    difference_type __n = __e - __f;\n    if (__n > 0)\n    {\n        allocator_type& __a = __base::__alloc();\n        iterator __b = __base::begin();\n        difference_type __pos = __f - __b;\n        for (iterator __p = __b + __pos; __p != __e; ++__p)\n            __alloc_traits::destroy(__a, _VSTD::addressof(*__p));\n        __base::size() -= __n;\n        while (__back_spare() >= 2 * __base::__block_size)\n        {\n            __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);\n            __base::__map_.pop_back();\n        }\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\ndeque<_Tp, _Allocator>::swap(deque& __c)\n#if _LIBCPP_STD_VER >= 14\n        _NOEXCEPT\n#else\n        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || \n                    __is_nothrow_swappable<allocator_type>::value)\n#endif\n{\n    __base::swap(__c);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\ndeque<_Tp, _Allocator>::clear() _NOEXCEPT\n{\n    __base::clear();\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)\n{\n    const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();\n    return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)\n{\n    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_DEQUE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/exception",
    "content": "// -*- C++ -*-\n//===-------------------------- exception ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_EXCEPTION\n#define _LIBCPP_EXCEPTION\n\n/*\n    exception synopsis\n\nnamespace std\n{\n\nclass exception\n{\npublic:\n    exception() noexcept;\n    exception(const exception&) noexcept;\n    exception& operator=(const exception&) noexcept;\n    virtual ~exception() noexcept;\n    virtual const char* what() const noexcept;\n};\n\nclass bad_exception\n    : public exception\n{\npublic:\n    bad_exception() noexcept;\n    bad_exception(const bad_exception&) noexcept;\n    bad_exception& operator=(const bad_exception&) noexcept;\n    virtual ~bad_exception() noexcept;\n    virtual const char* what() const noexcept;\n};\n\ntypedef void (*unexpected_handler)();\nunexpected_handler set_unexpected(unexpected_handler  f ) noexcept;\nunexpected_handler get_unexpected() noexcept;\n[[noreturn]] void unexpected();\n\ntypedef void (*terminate_handler)();\nterminate_handler set_terminate(terminate_handler  f ) noexcept;\nterminate_handler get_terminate() noexcept;\n[[noreturn]] void terminate() noexcept;\n\nbool uncaught_exception()  noexcept;\nint  uncaught_exceptions() noexcept;  // C++17\n\ntypedef unspecified exception_ptr;\n\nexception_ptr current_exception() noexcept;\nvoid rethrow_exception [[noreturn]] (exception_ptr p);\ntemplate<class E> exception_ptr make_exception_ptr(E e) noexcept;\n\nclass nested_exception\n{\npublic:\n    nested_exception() noexcept;\n    nested_exception(const nested_exception&) noexcept = default;\n    nested_exception& operator=(const nested_exception&) noexcept = default;\n    virtual ~nested_exception() = default;\n\n    // access functions\n    [[noreturn]] void rethrow_nested() const;\n    exception_ptr nested_ptr() const noexcept;\n};\n\ntemplate <class T> [[noreturn]] void throw_with_nested(T&& t);\ntemplate <class E> void rethrow_if_nested(const E& e);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <cstddef>\n#include <type_traits>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\nnamespace std  // purposefully not using versioning namespace\n{\n\nclass _LIBCPP_EXCEPTION_ABI exception\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {}\n    virtual ~exception() _NOEXCEPT;\n    virtual const char* what() const _NOEXCEPT;\n};\n\nclass _LIBCPP_EXCEPTION_ABI bad_exception\n    : public exception\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {}\n    virtual ~bad_exception() _NOEXCEPT;\n    virtual const char* what() const _NOEXCEPT;\n};\n\ntypedef void (*unexpected_handler)();\n_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;\n_LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT;\n_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected();\n\ntypedef void (*terminate_handler)();\n_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT;\n_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT;\n_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT;\n\n_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT;\n_LIBCPP_FUNC_VIS int uncaught_exceptions() _NOEXCEPT;\n\nclass _LIBCPP_TYPE_VIS exception_ptr;\n\n_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;\n_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);\n\nclass _LIBCPP_TYPE_VIS exception_ptr\n{\n    void* __ptr_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {}\n    _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}\n    exception_ptr(const exception_ptr&) _NOEXCEPT;\n    exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;\n    ~exception_ptr() _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_EXPLICIT\n        operator bool() const _NOEXCEPT {return __ptr_ != nullptr;}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT\n        {return __x.__ptr_ == __y.__ptr_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT\n        {return !(__x == __y);}\n\n    friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;\n    friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);\n};\n\ntemplate<class _Ep>\nexception_ptr\nmake_exception_ptr(_Ep __e) _NOEXCEPT\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n        throw __e;\n    }\n    catch (...)\n    {\n        return current_exception();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\n// nested_exception\n\nclass _LIBCPP_EXCEPTION_ABI nested_exception\n{\n    exception_ptr __ptr_;\npublic:\n    nested_exception() _NOEXCEPT;\n//     nested_exception(const nested_exception&) noexcept = default;\n//     nested_exception& operator=(const nested_exception&) noexcept = default;\n    virtual ~nested_exception() _NOEXCEPT;\n\n    // access functions\n    _LIBCPP_NORETURN void rethrow_nested() const;\n    _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;}\n};\n\ntemplate <class _Tp>\nstruct __nested\n    : public _Tp,\n      public nested_exception\n{\n    _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {}\n};\n\ntemplate <class _Tp>\n_LIBCPP_NORETURN\nvoid\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\nthrow_with_nested(_Tp&& __t, typename enable_if<\n                  is_class<typename remove_reference<_Tp>::type>::value &&\n                  !is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value\n                  && !__libcpp_is_final<typename remove_reference<_Tp>::type>::value\n                                    >::type* = 0)\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\nthrow_with_nested (_Tp& __t, typename enable_if<\n                  is_class<_Tp>::value && !is_base_of<nested_exception, _Tp>::value\n                                    >::type* = 0)\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    throw __nested<typename remove_reference<_Tp>::type>(_VSTD::forward<_Tp>(__t));\n#endif\n}\n\ntemplate <class _Tp>\n_LIBCPP_NORETURN\nvoid\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\nthrow_with_nested(_Tp&& __t, typename enable_if<\n                  !is_class<typename remove_reference<_Tp>::type>::value ||\n                  is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value\n                  || __libcpp_is_final<typename remove_reference<_Tp>::type>::value\n                                    >::type* = 0)\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\nthrow_with_nested (_Tp& __t, typename enable_if<\n                  !is_class<_Tp>::value || is_base_of<nested_exception, _Tp>::value\n                                    >::type* = 0)\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    throw _VSTD::forward<_Tp>(__t);\n#endif\n}\n\ntemplate <class _Ep>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nrethrow_if_nested(const _Ep& __e, typename enable_if<\n                                   is_polymorphic<_Ep>::value\n                                                   >::type* = 0)\n{\n    const nested_exception* __nep = dynamic_cast<const nested_exception*>(&__e);\n    if (__nep)\n        __nep->rethrow_nested();\n}\n\ntemplate <class _Ep>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nrethrow_if_nested(const _Ep&, typename enable_if<\n                                   !is_polymorphic<_Ep>::value\n                                                   >::type* = 0)\n{\n}\n\n}  // std\n\n#endif  // _LIBCPP_EXCEPTION\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/experimental/__config",
    "content": "// -*- C++ -*-\n//===--------------------------- __config ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_EXPERIMENTAL_CONFIG\n#define _LIBCPP_EXPERIMENTAL_CONFIG\n\n#include <__config>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL namespace std { namespace experimental {\n#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL  } }\n#define _VSTD_EXPERIMENTAL std::experimental\n\n#define _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace fundamentals_v1 {\n#define _LIBCPP_END_NAMESPACE_LFTS  } } }\n#define _VSTD_LFTS _VSTD_EXPERIMENTAL::fundamentals_v1\n\n#define _LIBCPP_BEGIN_NAMESPACE_CHRONO_LFTS _LIBCPP_BEGIN_NAMESPACE_STD        \\\n  namespace chrono { namespace experimental { inline namespace fundamentals_v1 {\n#define _LIBCPP_END_NAMESPACE_CHRONO_LFTS _LIBCPP_END_NAMESPACE_STD } } }\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/experimental/algorithm",
    "content": "// -*- C++ -*-\n//===-------------------------- algorithm ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_EXPERIMENTAL_ALGORITHM\n#define _LIBCPP_EXPERIMENTAL_ALGORITHM\n\n/*\n   experimental/algorithm synopsis\n\n#include <algorithm>\n\nnamespace std {\nnamespace experimental {\ninline namespace fundamentals_v1 {\n\ntemplate <class ForwardIterator, class Searcher>\nForwardIterator search(ForwardIterator first, ForwardIterator last,\n                       const Searcher &searcher);\ntemplate <class PopulationIterator, class SampleIterator, class Distance,\n          class UniformRandomNumberGenerator>\nSampleIterator sample(PopulationIterator first, PopulationIterator last,\n                      SampleIterator out, Distance n,\n                      UniformRandomNumberGenerator &&g);\n\n} // namespace fundamentals_v1\n} // namespace experimental\n} // namespace std\n\n*/\n\n#include <experimental/__config>\n#include <algorithm>\n#include <type_traits>\n\n#include <__undef_min_max>\n\n#include <__debug>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_LFTS\n\n\ntemplate <class _ForwardIterator, class _Searcher>\n_LIBCPP_INLINE_VISIBILITY\n_ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s)\n{ return __s(__f, __l); }\n\n\ntemplate <class _PopulationIterator, class _SampleIterator, class _Distance,\n          class _UniformRandomNumberGenerator>\n_LIBCPP_INLINE_VISIBILITY\n_SampleIterator __sample(_PopulationIterator __first,\n                         _PopulationIterator __last, _SampleIterator __out,\n                         _Distance __n,\n                         _UniformRandomNumberGenerator &&__g,\n                         input_iterator_tag) {\n\n  _Distance __k = 0;\n  for (; __first != __last && __k < __n; ++__first, (void)++__k)\n    __out[__k] = *__first;\n  _Distance __sz = __k;\n  for (; __first != __last; ++__first, (void)++__k) {\n    _Distance __r = _VSTD::uniform_int_distribution<_Distance>(0, __k)(__g);\n    if (__r < __sz)\n      __out[__r] = *__first;\n  }\n  return __out + _VSTD::min(__n, __k);\n}\n\ntemplate <class _PopulationIterator, class _SampleIterator, class _Distance,\n          class _UniformRandomNumberGenerator>\n_LIBCPP_INLINE_VISIBILITY\n_SampleIterator __sample(_PopulationIterator __first,\n                         _PopulationIterator __last, _SampleIterator __out,\n                         _Distance __n,\n                         _UniformRandomNumberGenerator &&__g,\n                         forward_iterator_tag) {\n  _Distance __unsampled_sz = _VSTD::distance(__first, __last);\n  for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) {\n    _Distance __r =\n        _VSTD::uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g);\n    if (__r < __n) {\n      *__out++ = *__first;\n      --__n;\n    }\n  }\n  return __out;\n}\n\ntemplate <class _PopulationIterator, class _SampleIterator, class _Distance,\n          class _UniformRandomNumberGenerator>\n_LIBCPP_INLINE_VISIBILITY\n_SampleIterator sample(_PopulationIterator __first,\n                         _PopulationIterator __last, _SampleIterator __out,\n                         _Distance __n, _UniformRandomNumberGenerator &&__g) {\n  typedef typename iterator_traits<_PopulationIterator>::iterator_category\n        _PopCategory;\n  typedef typename iterator_traits<_PopulationIterator>::difference_type\n        _Difference;\n  typedef typename common_type<_Distance, _Difference>::type _CommonType;\n  _LIBCPP_ASSERT(__n >= 0, \"N must be a positive number.\");\n  return _VSTD_LFTS::__sample(\n      __first, __last, __out, _CommonType(__n),\n      _VSTD::forward<_UniformRandomNumberGenerator>(__g),\n      _PopCategory());\n}\n\n_LIBCPP_END_NAMESPACE_LFTS\n\n#endif /* _LIBCPP_EXPERIMENTAL_ALGORITHM */\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/experimental/any",
    "content": "// -*- C++ -*-\n//===------------------------------ any -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_EXPERIMENTAL_ANY\n#define _LIBCPP_EXPERIMENTAL_ANY\n\n/*\n   experimental/any synopsis\n\nnamespace std {\nnamespace experimental {\ninline namespace fundamentals_v1 {\n\n  class bad_any_cast : public bad_cast\n  {\n  public:\n    virtual const char* what() const noexcept;\n  };\n\n  class any\n  {\n  public:\n\n    // 6.3.1 any construct/destruct\n    any() noexcept;\n\n    any(const any& other);\n    any(any&& other) noexcept;\n\n    template <class ValueType>\n      any(ValueType&& value);\n\n    ~any();\n\n    // 6.3.2 any assignments\n    any& operator=(const any& rhs);\n    any& operator=(any&& rhs) noexcept;\n\n    template <class ValueType>\n      any& operator=(ValueType&& rhs);\n\n    // 6.3.3 any modifiers\n    void clear() noexcept;\n    void swap(any& rhs) noexcept;\n\n    // 6.3.4 any observers\n    bool empty() const noexcept;\n    const type_info& type() const noexcept;\n  };\n\n   // 6.4 Non-member functions\n  void swap(any& x, any& y) noexcept;\n\n  template<class ValueType>\n    ValueType any_cast(const any& operand);\n  template<class ValueType>\n    ValueType any_cast(any& operand);\n  template<class ValueType>\n    ValueType any_cast(any&& operand);\n\n  template<class ValueType>\n    const ValueType* any_cast(const any* operand) noexcept;\n  template<class ValueType>\n    ValueType* any_cast(any* operand) noexcept;\n\n} // namespace fundamentals_v1\n} // namespace experimental\n} // namespace std\n\n*/\n\n#include <experimental/__config>\n#include <memory>\n#include <new>\n#include <typeinfo>\n#include <type_traits>\n#include <cstdlib>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_LFTS\n\nclass _LIBCPP_EXCEPTION_ABI bad_any_cast : public bad_cast\n{\npublic:\n     //TODO(EricWF) Enable or delete these.\n    //bad_any_cast() _NOEXCEPT;\n    //virtual ~bad_any_cast() _NOEXCEPT;\n    virtual const char* what() const _NOEXCEPT;\n};\n\n#if _LIBCPP_STD_VER > 11                                            // C++ > 11\n\n_LIBCPP_NORETURN _LIBCPP_INLINE_VISIBILITY\ninline void __throw_bad_any_cast()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    throw bad_any_cast();\n#else\n    _VSTD::abort();\n#endif\n}\n\n// Forward declarations\nclass any;\n\ntemplate <class _ValueType>\ntypename add_pointer<typename add_const<_ValueType>::type>::type\nany_cast(any const *) _NOEXCEPT;\n\ntemplate <class _ValueType>\ntypename add_pointer<_ValueType>::type\nany_cast(any *) _NOEXCEPT;\n\nnamespace __any_imp\n{\n  typedef typename aligned_storage<3*sizeof(void*), alignment_of<void*>::value>::type\n    _Buffer;\n\n  template <class _Tp>\n  struct _IsSmallObject\n    : public integral_constant<bool\n        , sizeof(_Tp) <= sizeof(_Buffer)\n          && alignment_of<_Buffer>::value\n             % alignment_of<_Tp>::value == 0\n          && is_nothrow_move_constructible<_Tp>::value\n        >\n  {};\n\n  enum class _Action\n  {\n    _Destroy,\n    _Copy,\n    _Move,\n    _Get,\n    _TypeInfo\n  };\n\n  template <class _Tp>\n  struct _SmallHandler;\n\n  template <class _Tp>\n  struct _LargeHandler;\n\n  template <class _Tp>\n  using _Handler = typename conditional<_IsSmallObject<_Tp>::value\n                                      , _SmallHandler<_Tp>\n                                      , _LargeHandler<_Tp>\n                                    >::type;\n  template <class _ValueType>\n  using _EnableIfNotAny = typename\n    enable_if<\n      !is_same<typename decay<_ValueType>::type, any>::value\n    >::type;\n\n} // namespace __any_imp\n\nclass any\n{\npublic:\n  // 6.3.1 any construct/destruct\n  _LIBCPP_INLINE_VISIBILITY\n  any() _NOEXCEPT : __h(nullptr) {}\n\n  _LIBCPP_INLINE_VISIBILITY\n  any(any const & __other) : __h(nullptr)\n  {\n    if (__other.__h) __other.__call(_Action::_Copy, this);\n  }\n\n  _LIBCPP_INLINE_VISIBILITY\n  any(any && __other) _NOEXCEPT : __h(nullptr)\n  {\n    if (__other.__h) __other.__call(_Action::_Move, this);\n  }\n\n  template <\n      class _ValueType\n    , class = __any_imp::_EnableIfNotAny<_ValueType>\n    >\n  any(_ValueType && __value);\n\n  _LIBCPP_INLINE_VISIBILITY\n  ~any()\n  {\n    this->clear();\n  }\n\n  // 6.3.2 any assignments\n  _LIBCPP_INLINE_VISIBILITY\n  any & operator=(any const & __rhs)\n  {\n    any(__rhs).swap(*this);\n    return *this;\n  }\n\n  _LIBCPP_INLINE_VISIBILITY\n  any & operator=(any && __rhs) _NOEXCEPT\n  {\n    any(_VSTD::move(__rhs)).swap(*this);\n    return *this;\n  }\n\n  template <\n      class _ValueType\n    , class = __any_imp::_EnableIfNotAny<_ValueType>\n    >\n  any & operator=(_ValueType && __rhs);\n\n  // 6.3.3 any modifiers\n  _LIBCPP_INLINE_VISIBILITY\n  void clear() _NOEXCEPT\n  {\n    if (__h) this->__call(_Action::_Destroy);\n  }\n\n  void swap(any & __rhs) _NOEXCEPT;\n\n  // 6.3.4 any observers\n  _LIBCPP_INLINE_VISIBILITY\n  bool empty() const _NOEXCEPT\n  {\n    return __h == nullptr;\n  }\n\n#if !defined(_LIBCPP_NO_RTTI)\n  _LIBCPP_INLINE_VISIBILITY\n  const type_info & type() const _NOEXCEPT\n  {\n    if (__h) {\n        return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo));\n    } else {\n        return typeid(void);\n    }\n  }\n#endif\n\nprivate:\n    typedef __any_imp::_Action _Action;\n\n    typedef void* (*_HandleFuncPtr)(_Action, any const *, any *, const type_info *);\n\n    union _Storage\n    {\n        void *  __ptr;\n        __any_imp::_Buffer __buf;\n    };\n\n    _LIBCPP_ALWAYS_INLINE\n    void * __call(_Action __a, any * __other = nullptr,\n                  type_info const * __info = nullptr) const\n    {\n        return __h(__a, this, __other, __info);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    void * __call(_Action __a, any * __other = nullptr,\n                  type_info const * __info = nullptr)\n    {\n        return __h(__a, this, __other, __info);\n    }\n\n    template <class>\n    friend struct __any_imp::_SmallHandler;\n    template <class>\n    friend struct __any_imp::_LargeHandler;\n\n    template <class _ValueType>\n    friend typename add_pointer<typename add_const<_ValueType>::type>::type\n    any_cast(any const *) _NOEXCEPT;\n\n    template <class _ValueType>\n    friend typename add_pointer<_ValueType>::type\n    any_cast(any *) _NOEXCEPT;\n\n    _HandleFuncPtr __h;\n    _Storage __s;\n};\n\nnamespace __any_imp\n{\n\n  template <class _Tp>\n  struct _LIBCPP_TYPE_VIS_ONLY _SmallHandler\n  {\n     _LIBCPP_INLINE_VISIBILITY\n     static void* __handle(_Action __act, any const * __this, any * __other,\n                           type_info const * __info)\n     {\n        switch (__act)\n        {\n        case _Action::_Destroy:\n          __destroy(const_cast<any &>(*__this));\n          return nullptr;\n        case _Action::_Copy:\n            __copy(*__this, *__other);\n            return nullptr;\n        case _Action::_Move:\n          __move(const_cast<any &>(*__this), *__other);\n          return nullptr;\n        case _Action::_Get:\n            return __get(const_cast<any &>(*__this), __info);\n        case _Action::_TypeInfo:\n          return __type_info();\n        }\n    }\n\n    template <class _Up>\n    _LIBCPP_INLINE_VISIBILITY\n    static void __create(any & __dest, _Up && __v)\n    {\n        ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Up>(__v));\n        __dest.__h = &_SmallHandler::__handle;\n    }\n\n  private:\n    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY\n    static void __destroy(any & __this)\n    {\n        _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));\n        __value.~_Tp();\n        __this.__h = nullptr;\n    }\n\n    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY\n    static void __copy(any const & __this, any & __dest)\n    {\n        _SmallHandler::__create(__dest, *static_cast<_Tp const *>(\n            static_cast<void const *>(&__this.__s.__buf)));\n    }\n\n    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY\n    static void __move(any & __this, any & __dest)\n    {\n        _SmallHandler::__create(__dest, _VSTD::move(\n            *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf))));\n        __destroy(__this);\n    }\n\n    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY\n    static void* __get(any & __this, type_info const * __info)\n    {\n#if !defined(_LIBCPP_NO_RTTI)\n        if (typeid(_Tp) == *__info) {\n            return static_cast<void*>(&__this.__s.__buf);\n        }\n        return nullptr;\n#else\n        return static_cast<void*>(&__this.__s.__buf);\n#endif\n    }\n\n    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY\n    static void* __type_info()\n    {\n#if !defined(_LIBCPP_NO_RTTI)\n        return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));\n#else\n        return nullptr;\n#endif\n    }\n  };\n\n  template <class _Tp>\n  struct _LIBCPP_TYPE_VIS_ONLY _LargeHandler\n  {\n    _LIBCPP_INLINE_VISIBILITY\n    static void* __handle(_Action __act, any const * __this, any * __other,\n                          type_info const * __info)\n    {\n        switch (__act)\n        {\n        case _Action::_Destroy:\n          __destroy(const_cast<any &>(*__this));\n          return nullptr;\n        case _Action::_Copy:\n          __copy(*__this, *__other);\n          return nullptr;\n        case _Action::_Move:\n          __move(const_cast<any &>(*__this), *__other);\n          return nullptr;\n        case _Action::_Get:\n            return __get(const_cast<any &>(*__this), __info);\n        case _Action::_TypeInfo:\n          return __type_info();\n        }\n    }\n\n    template <class _Up>\n    _LIBCPP_INLINE_VISIBILITY\n    static void __create(any & __dest, _Up && __v)\n    {\n        typedef allocator<_Tp> _Alloc;\n        typedef __allocator_destructor<_Alloc> _Dp;\n        _Alloc __a;\n        unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n        ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Up>(__v));\n        __dest.__s.__ptr = __hold.release();\n        __dest.__h = &_LargeHandler::__handle;\n    }\n\n  private:\n\n    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY\n    static void __destroy(any & __this)\n    {\n        delete static_cast<_Tp*>(__this.__s.__ptr);\n        __this.__h = nullptr;\n    }\n\n    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY\n    static void __copy(any const & __this, any & __dest)\n    {\n        _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr));\n    }\n\n    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY\n    static void __move(any & __this, any & __dest)\n    {\n      __dest.__s.__ptr = __this.__s.__ptr;\n      __dest.__h = &_LargeHandler::__handle;\n      __this.__h = nullptr;\n    }\n\n    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY\n    static void* __get(any & __this, type_info const * __info)\n    {\n#if !defined(_LIBCPP_NO_RTTI)\n        if (typeid(_Tp) == *__info) {\n            return static_cast<void*>(__this.__s.__ptr);\n        }\n        return nullptr;\n#else\n        return static_cast<void*>(__this.__s.__ptr);\n#endif\n    }\n\n    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY\n    static void* __type_info()\n    {\n#if !defined(_LIBCPP_NO_RTTI)\n        return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));\n#else\n        return nullptr;\n#endif\n    }\n  };\n\n} // namespace __any_imp\n\n\ntemplate <class _ValueType, class>\n_LIBCPP_INLINE_VISIBILITY\nany::any(_ValueType && __v) : __h(nullptr)\n{\n  typedef typename decay<_ValueType>::type _Tp;\n  static_assert(is_copy_constructible<_Tp>::value,\n                \"_ValueType must be CopyConstructible.\");\n  typedef __any_imp::_Handler<_Tp> _HandlerType;\n  _HandlerType::__create(*this, _VSTD::forward<_ValueType>(__v));\n}\n\ntemplate <class _ValueType, class>\n_LIBCPP_INLINE_VISIBILITY\nany & any::operator=(_ValueType && __v)\n{\n  typedef typename decay<_ValueType>::type _Tp;\n  static_assert(is_copy_constructible<_Tp>::value,\n                \"_ValueType must be CopyConstructible.\");\n  any(_VSTD::forward<_ValueType>(__v)).swap(*this);\n  return *this;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid any::swap(any & __rhs) _NOEXCEPT\n{\n    if (__h && __rhs.__h) {\n        any __tmp;\n        __rhs.__call(_Action::_Move, &__tmp);\n        this->__call(_Action::_Move, &__rhs);\n        __tmp.__call(_Action::_Move, this);\n    }\n    else if (__h) {\n        this->__call(_Action::_Move, &__rhs);\n    }\n    else if (__rhs.__h) {\n        __rhs.__call(_Action::_Move, this);\n    }\n}\n\n// 6.4 Non-member functions\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid swap(any & __lhs, any & __rhs) _NOEXCEPT\n{\n    __lhs.swap(__rhs);\n}\n\ntemplate <class _ValueType>\n_LIBCPP_INLINE_VISIBILITY\n_ValueType any_cast(any const & __v)\n{\n    static_assert(\n        is_reference<_ValueType>::value\n        || is_copy_constructible<_ValueType>::value,\n        \"_ValueType is required to be a reference or a CopyConstructible type.\");\n    typedef typename add_const<typename remove_reference<_ValueType>::type>::type\n            _Tp;\n    _Tp * __tmp = any_cast<_Tp>(&__v);\n    if (__tmp == nullptr)\n        __throw_bad_any_cast();\n    return *__tmp;\n}\n\ntemplate <class _ValueType>\n_LIBCPP_INLINE_VISIBILITY\n_ValueType any_cast(any & __v)\n{\n    static_assert(\n        is_reference<_ValueType>::value\n        || is_copy_constructible<_ValueType>::value,\n        \"_ValueType is required to be a reference or a CopyConstructible type.\");\n    typedef typename remove_reference<_ValueType>::type _Tp;\n    _Tp * __tmp = any_cast<_Tp>(&__v);\n    if (__tmp == nullptr)\n        __throw_bad_any_cast();\n    return *__tmp;\n}\n\ntemplate <class _ValueType>\n_LIBCPP_INLINE_VISIBILITY\n_ValueType any_cast(any && __v)\n{\n    static_assert(\n        is_reference<_ValueType>::value\n        || is_copy_constructible<_ValueType>::value,\n        \"_ValueType is required to be a reference or a CopyConstructible type.\");\n    typedef typename remove_reference<_ValueType>::type _Tp;\n    _Tp * __tmp = any_cast<_Tp>(&__v);\n    if (__tmp == nullptr)\n        __throw_bad_any_cast();\n    return *__tmp;\n}\n\ntemplate <class _ValueType>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename add_pointer<typename add_const<_ValueType>::type>::type\nany_cast(any const * __any) _NOEXCEPT\n{\n    static_assert(!is_reference<_ValueType>::value,\n                  \"_ValueType may not be a reference.\");\n    return any_cast<_ValueType>(const_cast<any *>(__any));\n}\n\ntemplate <class _ValueType>\n_LIBCPP_INLINE_VISIBILITY\ntypename add_pointer<_ValueType>::type\nany_cast(any * __any) _NOEXCEPT\n{\n    using __any_imp::_Action;\n    static_assert(!is_reference<_ValueType>::value,\n                  \"_ValueType may not be a reference.\");\n    typedef typename add_pointer<_ValueType>::type _ReturnType;\n    if (__any && __any->__h) {\n\n        return static_cast<_ReturnType>(\n            __any->__call(_Action::_Get, nullptr,\n#if !defined(_LIBCPP_NO_RTTI)\n                &typeid(_ValueType)\n#else\n                nullptr\n#endif\n        ));\n\n    }\n    return nullptr;\n}\n\n#endif // _LIBCPP_STD_VER > 11\n\n_LIBCPP_END_NAMESPACE_LFTS\n\n#endif // _LIBCPP_EXPERIMENTAL_ANY\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/experimental/chrono",
    "content": "// -*- C++ -*-\n//===------------------------------ chrono ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_EXPERIMENTAL_CHRONO\n#define _LIBCPP_EXPERIMENTAL_CHRONO\n\n/**\n    experimental/chrono synopsis\n\n// C++1y\n\n#include <chrono>\n\nnamespace std {\nnamespace chrono {\nnamespace experimental {\ninline namespace fundamentals_v1 {\n\n  // See C++14 20.12.4, customization traits\n  template <class Rep> constexpr bool treat_as_floating_point_v\n    = treat_as_floating_point<Rep>::value;\n\n} // namespace fundamentals_v1\n} // namespace experimental\n} // namespace chrono\n} // namespace std\n\n */\n\n#include <experimental/__config>\n#include <chrono>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#if _LIBCPP_STD_VER > 11\n\n_LIBCPP_BEGIN_NAMESPACE_CHRONO_LFTS\n\n#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES\n\ntemplate <class _Rep> _LIBCPP_CONSTEXPR bool treat_as_floating_point_v\n    = treat_as_floating_point<_Rep>::value;\n\n#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */\n\n_LIBCPP_END_NAMESPACE_CHRONO_LFTS\n\n#endif /* _LIBCPP_STD_VER > 11 */\n\n#endif /* _LIBCPP_EXPERIMENTAL_CHRONO */\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/experimental/dynarray",
    "content": "// -*- C++ -*-\n//===-------------------------- dynarray ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_DYNARRAY\n#define _LIBCPP_DYNARRAY\n\n#include <__config>\n#if _LIBCPP_STD_VER > 11\n\n/*\n    dynarray synopsis\n\nnamespace std { namespace experimental {\n\ntemplate< typename T >\nclass dynarray\n{\n    // types:\n    typedef       T                               value_type;\n    typedef       T&                              reference;\n    typedef const T&                              const_reference;\n    typedef       T*                              pointer;\n    typedef const T*                              const_pointer;\n    typedef       implementation-defined          iterator;\n    typedef       implementation-defined          const_iterator;\n    typedef reverse_iterator<iterator>            reverse_iterator;\n    typedef reverse_iterator<const_iterator>      const_reverse_iterator;\n    typedef size_t                                size_type;\n    typedef ptrdiff_t                             difference_type;\n\npublic:\n    // construct/copy/destroy:\n    explicit dynarray(size_type c);\n    dynarray(size_type c, const T& v);\n    dynarray(const dynarray& d);\n    dynarray(initializer_list<T>);\n\n    template <class Alloc>\n      dynarray(allocator_arg_t, const Alloc& a, size_type c, const Alloc& alloc);\n    template <class Alloc>\n      dynarray(allocator_arg_t, const Alloc& a, size_type c, const T& v, const Alloc& alloc);\n    template <class Alloc>\n      dynarray(allocator_arg_t, const Alloc& a, const dynarray& d, const Alloc& alloc);\n    template <class Alloc>\n      dynarray(allocator_arg_t, const Alloc& a, initializer_list<T>, const Alloc& alloc);\n    dynarray& operator=(const dynarray&) = delete;\n    ~dynarray();\n\n    // iterators:\n    iterator       begin()        noexcept;\n    const_iterator begin()  const noexcept;\n    const_iterator cbegin() const noexcept;\n    iterator       end()          noexcept;\n    const_iterator end()    const noexcept;\n    const_iterator cend()   const noexcept;\n\n    reverse_iterator       rbegin()        noexcept;\n    const_reverse_iterator rbegin()  const noexcept;\n    const_reverse_iterator crbegin() const noexcept;\n    reverse_iterator       rend()          noexcept;\n    const_reverse_iterator rend()    const noexcept;\n    const_reverse_iterator crend()   const noexcept;\n\n    // capacity:\n    size_type size()     const noexcept;\n    size_type max_size() const noexcept;\n    bool      empty()    const noexcept;\n\n    // element access:\n    reference       operator[](size_type n);\n    const_reference operator[](size_type n) const;\n\n    reference       front();\n    const_reference front() const;\n    reference       back();\n    const_reference back()  const;\n\n    const_reference at(size_type n) const;\n    reference       at(size_type n);\n\n    // data access:\n    T*       data()       noexcept;\n    const T* data() const noexcept;\n\n    // mutating member functions:\n    void fill(const T& v);\n};\n\n}}  // std::experimental\n\n*/\n\n#include <__functional_base>\n#include <iterator>\n#include <stdexcept>\n#include <initializer_list>\n#include <new>\n#include <algorithm>\n\n#include <__undef___deallocate>\n\n#if defined(_LIBCPP_NO_EXCEPTIONS)\n    #include <cassert>\n#endif\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\nnamespace std { namespace experimental { inline namespace __array_extensions_v1 {\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY dynarray\n{\npublic:\n    // types:\n    typedef dynarray __self;\n    typedef _Tp                                   value_type;\n    typedef value_type&                           reference;\n    typedef const value_type&                     const_reference;\n    typedef value_type*                           iterator;\n    typedef const value_type*                     const_iterator;\n    typedef value_type*                           pointer;\n    typedef const value_type*                     const_pointer;\n    typedef size_t                                size_type;\n    typedef ptrdiff_t                             difference_type;\n    typedef std::reverse_iterator<iterator>       reverse_iterator;\n    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;\n\nprivate:\n    size_t                  __size_;\n    value_type *            __base_;\n    _LIBCPP_ALWAYS_INLINE dynarray () noexcept : __base_(nullptr), __size_(0) {}\n    \n    static inline _LIBCPP_INLINE_VISIBILITY value_type* __allocate ( size_t count )\n    {\n        if ( numeric_limits<size_t>::max() / sizeof (value_type) <= count )\n        {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            throw bad_array_length();\n#else\n            assert(!\"dynarray::allocation\");\n#endif\n        }\n        return static_cast<value_type *> (_VSTD::__allocate (sizeof(value_type) * count));\n    }\n\n    static inline _LIBCPP_INLINE_VISIBILITY void __deallocate ( value_type* __ptr ) noexcept\n    {\n        _VSTD::__deallocate (static_cast<void *> (__ptr));\n    }\n\npublic:\n\n    explicit dynarray(size_type __c);\n    dynarray(size_type __c, const value_type& __v);\n    dynarray(const dynarray& __d);\n    dynarray(initializer_list<value_type>);\n\n//  We're not implementing these right now.\n//  Updated with the resolution of LWG issue #2255\n//     template <typename _Alloc>\n//       dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c);\n//     template <typename _Alloc>\n//       dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c, const value_type& __v);\n//     template <typename _Alloc>\n//       dynarray(allocator_arg_t, const _Alloc& __alloc, const dynarray& __d);\n//     template <typename _Alloc>\n//       dynarray(allocator_arg_t, const _Alloc& __alloc, initializer_list<value_type>);\n\n    dynarray& operator=(const dynarray&) = delete;\n    ~dynarray();\n\n    // iterators:\n    inline _LIBCPP_INLINE_VISIBILITY iterator       begin()        noexcept { return iterator(data()); }\n    inline _LIBCPP_INLINE_VISIBILITY const_iterator begin()  const noexcept { return const_iterator(data()); }\n    inline _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const noexcept { return const_iterator(data()); }\n    inline _LIBCPP_INLINE_VISIBILITY iterator       end()          noexcept { return iterator(data() + __size_); }\n    inline _LIBCPP_INLINE_VISIBILITY const_iterator end()    const noexcept { return const_iterator(data() + __size_); }\n    inline _LIBCPP_INLINE_VISIBILITY const_iterator cend()   const noexcept { return const_iterator(data() + __size_); }\n\n    inline _LIBCPP_INLINE_VISIBILITY reverse_iterator       rbegin()        noexcept { return reverse_iterator(end()); }\n    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin()  const noexcept { return const_reverse_iterator(end()); }\n    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }\n    inline _LIBCPP_INLINE_VISIBILITY reverse_iterator       rend()          noexcept { return reverse_iterator(begin()); }\n    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend()    const noexcept { return const_reverse_iterator(begin()); }\n    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend()   const noexcept { return const_reverse_iterator(begin()); }\n\n    // capacity:\n    inline _LIBCPP_INLINE_VISIBILITY size_type size()     const noexcept { return __size_; }\n    inline _LIBCPP_INLINE_VISIBILITY size_type max_size() const noexcept { return __size_; }\n    inline _LIBCPP_INLINE_VISIBILITY bool      empty()    const noexcept { return __size_ == 0; }\n\n    // element access:\n    inline _LIBCPP_INLINE_VISIBILITY reference       operator[](size_type __n)       { return data()[__n]; }\n    inline _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const { return data()[__n]; }\n\n    inline _LIBCPP_INLINE_VISIBILITY reference       front()       { return data()[0]; }\n    inline _LIBCPP_INLINE_VISIBILITY const_reference front() const { return data()[0]; }\n    inline _LIBCPP_INLINE_VISIBILITY reference       back()        { return data()[__size_-1]; }\n    inline _LIBCPP_INLINE_VISIBILITY const_reference back()  const { return data()[__size_-1]; }\n\n    inline _LIBCPP_INLINE_VISIBILITY const_reference at(size_type __n) const;\n    inline _LIBCPP_INLINE_VISIBILITY reference       at(size_type __n);\n\n    // data access:\n    inline _LIBCPP_INLINE_VISIBILITY _Tp*       data()       noexcept { return __base_; }\n    inline _LIBCPP_INLINE_VISIBILITY const _Tp* data() const noexcept { return __base_; }\n\n    // mutating member functions:\n    inline _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __v) { fill_n(begin(), __size_, __v); }\n};\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ndynarray<_Tp>::dynarray(size_type __c) : dynarray ()\n{\n    __base_ = __allocate (__c);\n    value_type *__data = data ();\n    for ( __size_ = 0; __size_ < __c; ++__size_, ++__data )\n        ::new (__data) value_type;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ndynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray ()\n{\n    __base_ = __allocate (__c);\n    value_type *__data = data ();\n    for ( __size_ = 0; __size_ < __c; ++__size_, ++__data )\n        ::new (__data) value_type (__v);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ndynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray ()\n{\n    size_t sz = __il.size();\n    __base_ = __allocate (sz);\n    value_type *__data = data ();\n    auto src = __il.begin();\n    for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src )\n        ::new (__data) value_type (*src);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ndynarray<_Tp>::dynarray(const dynarray& __d) : dynarray ()\n{\n    size_t sz = __d.size();\n    __base_ = __allocate (sz);\n    value_type *__data = data ();\n    auto src = __d.begin();\n    for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src )\n        ::new (__data) value_type (*src);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ndynarray<_Tp>::~dynarray()\n{ \n    value_type *__data = data () + __size_;\n    for ( size_t i = 0; i < __size_; ++i )\n        (--__data)->value_type::~value_type();\n    __deallocate ( __base_ );\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename dynarray<_Tp>::reference\ndynarray<_Tp>::at(size_type __n)\n{\n    if (__n >= __size_)\n    {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        throw out_of_range(\"dynarray::at\");\n#else\n        assert(!\"dynarray::at out_of_range\");\n#endif\n    }\n    return data()[__n];\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename dynarray<_Tp>::const_reference\ndynarray<_Tp>::at(size_type __n) const\n{\n    if (__n >= __size_)\n    {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        throw out_of_range(\"dynarray::at\");\n#else\n        assert(!\"dynarray::at out_of_range\");\n#endif\n    }\n    return data()[__n];\n}\n\n}}}\n\n\n_LIBCPP_BEGIN_NAMESPACE_STD\ntemplate <class _Tp, class _Alloc>\nstruct _LIBCPP_TYPE_VIS_ONLY uses_allocator<std::experimental::dynarray<_Tp>, _Alloc> : true_type {};\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // if _LIBCPP_STD_VER > 11 \n#endif  // _LIBCPP_DYNARRAY\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/experimental/functional",
    "content": "// -*- C++ -*-\n//===-------------------------- functional --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_EXPERIMENTAL_FUNCTIONAL\n#define _LIBCPP_EXPERIMENTAL_FUNCTIONAL\n\n/*\n   experimental/functional synopsis\n\n#include <algorithm>\n\nnamespace std {\nnamespace experimental {\ninline namespace fundamentals_v1 {\n\n    // See C++14 §20.9.9, Function object binders\n    template <class T> constexpr bool is_bind_expression_v\n      = is_bind_expression<T>::value;\n    template <class T> constexpr int is_placeholder_v\n      = is_placeholder<T>::value;\n\n    // 4.2, Class template function\n    template<class> class function; // undefined\n    template<class R, class... ArgTypes> class function<R(ArgTypes...)>;\n\n    template<class R, class... ArgTypes>\n    void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&);\n\n    template<class R, class... ArgTypes>\n    bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;\n    template<class R, class... ArgTypes>\n    bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;\n    template<class R, class... ArgTypes>\n    bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept;\n    template<class R, class... ArgTypes>\n    bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept;\n\n    // 4.3, Searchers\n    template<class ForwardIterator, class BinaryPredicate = equal_to<>>\n      class default_searcher;\n\n    template<class RandomAccessIterator,\n             class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,\n             class BinaryPredicate = equal_to<>>\n      class boyer_moore_searcher;\n\n    template<class RandomAccessIterator,\n             class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,\n             class BinaryPredicate = equal_to<>>\n      class boyer_moore_horspool_searcher;\n\n    template<class ForwardIterator, class BinaryPredicate = equal_to<>>\n    default_searcher<ForwardIterator, BinaryPredicate>\n    make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last,\n                          BinaryPredicate pred = BinaryPredicate());\n\n    template<class RandomAccessIterator,\n             class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,\n             class BinaryPredicate = equal_to<>>\n    boyer_moore_searcher<RandomAccessIterator, Hash, BinaryPredicate>\n    make_boyer_moore_searcher(\n        RandomAccessIterator pat_first, RandomAccessIterator pat_last,\n        Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());\n\n    template<class RandomAccessIterator,\n             class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,\n             class BinaryPredicate = equal_to<>>\n    boyer_moore_horspool_searcher<RandomAccessIterator, Hash, BinaryPredicate>\n    make_boyer_moore_horspool_searcher(\n        RandomAccessIterator pat_first, RandomAccessIterator pat_last,\n        Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());\n\n  } // namespace fundamentals_v1\n  } // namespace experimental\n\n  template<class R, class... ArgTypes, class Alloc>\n  struct uses_allocator<experimental::function<R(ArgTypes...)>, Alloc>;\n\n} // namespace std\n\n*/\n\n#include <experimental/__config>\n#include <functional>\n#include <algorithm>\n\n#include <__undef_min_max>\n\n#include <__debug>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_LFTS\n\n// default searcher\ntemplate<class _ForwardIterator, class _BinaryPredicate = equal_to<>>\nclass default_searcher {\npublic:\n    default_searcher(_ForwardIterator __f, _ForwardIterator __l, \n                       _BinaryPredicate __p = _BinaryPredicate())\n        : __first_(__f), __last_(__l), __pred_(__p) {}\n\n    template <typename _ForwardIterator2>\n    _ForwardIterator2 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const {\n        return _VSTD::search(__f, __l, __first_, __last_, __pred_);\n        }\n\nprivate:\n    _ForwardIterator __first_;\n    _ForwardIterator __last_;\n    _BinaryPredicate __pred_;\n    };\n\ntemplate<class _ForwardIterator, class _BinaryPredicate = equal_to<>>\ndefault_searcher<_ForwardIterator, _BinaryPredicate>\nmake_default_searcher( _ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate ())\n{\n    return default_searcher<_ForwardIterator, _BinaryPredicate>(__f, __l, __p);\n}\n\n\n_LIBCPP_END_NAMESPACE_LFTS\n\n#endif /* _LIBCPP_EXPERIMENTAL_FUNCTIONAL */\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/experimental/optional",
    "content": "// -*- C++ -*-\n//===-------------------------- optional ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_OPTIONAL\n#define _LIBCPP_OPTIONAL\n\n/*\n    optional synopsis\n\n// C++1y\n\nnamespace std { namespace experimental { inline namespace fundamentals_v1 {\n\n    // 5.3, optional for object types\n    template <class T> class optional;\n\n    // 5.4, In-place construction\n    struct in_place_t{};\n    constexpr in_place_t in_place{};\n\n    // 5.5, No-value state indicator\n    struct nullopt_t{see below};\n    constexpr nullopt_t nullopt(unspecified);\n\n    // 5.6, Class bad_optional_access\n    class bad_optional_access;\n\n    // 5.7, Relational operators\n    template <class T>\n      constexpr bool operator==(const optional<T>&, const optional<T>&);\n    template <class T>\n      constexpr bool operator!=(const optional<T>&, const optional<T>&);\n    template <class T>\n      constexpr bool operator<(const optional<T>&, const optional<T>&);\n    template <class T>\n      constexpr bool operator>(const optional<T>&, const optional<T>&);\n    template <class T>\n      constexpr bool operator<=(const optional<T>&, const optional<T>&);\n    template <class T>\n      constexpr bool operator>=(const optional<T>&, const optional<T>&);\n\n    // 5.8, Comparison with nullopt\n    template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;\n    template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;\n    template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;\n    template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;\n    template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;\n    template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;\n    template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;\n    template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;\n    template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;\n    template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;\n    template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;\n    template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;\n\n    // 5.9, Comparison with T\n    template <class T> constexpr bool operator==(const optional<T>&, const T&);\n    template <class T> constexpr bool operator==(const T&, const optional<T>&);\n    template <class T> constexpr bool operator!=(const optional<T>&, const T&);\n    template <class T> constexpr bool operator!=(const T&, const optional<T>&);\n    template <class T> constexpr bool operator<(const optional<T>&, const T&);\n    template <class T> constexpr bool operator<(const T&, const optional<T>&);\n    template <class T> constexpr bool operator<=(const optional<T>&, const T&);\n    template <class T> constexpr bool operator<=(const T&, const optional<T>&);\n    template <class T> constexpr bool operator>(const optional<T>&, const T&);\n    template <class T> constexpr bool operator>(const T&, const optional<T>&);\n    template <class T> constexpr bool operator>=(const optional<T>&, const T&);\n    template <class T> constexpr bool operator>=(const T&, const optional<T>&);\n\n    // 5.10, Specialized algorithms\n    template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below);\n    template <class T> constexpr optional<see below> make_optional(T&&);\n\n\ttemplate <class T>\n\tclass optional\n\t{\n\tpublic:\n\t  typedef T value_type;\n\n\t  // 5.3.1, Constructors\n\t  constexpr optional() noexcept;\n\t  constexpr optional(nullopt_t) noexcept;\n\t  optional(const optional&);\n\t  optional(optional&&) noexcept(see below);\n\t  constexpr optional(const T&);\n\t  constexpr optional(T&&);\n\t  template <class... Args> constexpr explicit optional(in_place_t, Args&&...);\n\t  template <class U, class... Args>\n\t\tconstexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);\n\n\t  // 5.3.2, Destructor\n\t  ~optional();\n\n\t  // 5.3.3, Assignment\n\t  optional& operator=(nullopt_t) noexcept;\n\t  optional& operator=(const optional&);\n\t  optional& operator=(optional&&) noexcept(see below);\n\t  template <class U> optional& operator=(U&&);\n\t  template <class... Args> void emplace(Args&&...);\n\t  template <class U, class... Args>\n\t\tvoid emplace(initializer_list<U>, Args&&...);\n\n\t  // 5.3.4, Swap\n\t  void swap(optional&) noexcept(see below);\n\n\t  // 5.3.5, Observers\n\t  constexpr T const* operator ->() const;\n\t  constexpr T* operator ->();\n\t  constexpr T const& operator *() const &;\n\t  constexpr T& operator *() &;\n\t  constexpr T&& operator *() &&;\n\t  constexpr const T&& operator *() const &&;\n\t  constexpr explicit operator bool() const noexcept;\n\t  constexpr T const& value() const &;\n\t  constexpr T& value() &;\n\t  constexpr T&& value() &&;\n\t  constexpr const T&& value() const &&;\n\t  template <class U> constexpr T value_or(U&&) const &;\n\t  template <class U> constexpr T value_or(U&&) &&;\n\n\tprivate:\n\t  T*   val;  // exposition only\n\t};\n\n  } // namespace fundamentals_v1\n  } // namespace experimental\n\n  // 5.11, Hash support\n  template <class T> struct hash;\n  template <class T> struct hash<experimental::optional<T>>;\n\n} // namespace std\n\n*/\n\n#include <experimental/__config>\n#include <functional>\n#include <stdexcept>\n\n_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL\nclass _LIBCPP_EXCEPTION_ABI bad_optional_access\n    : public std::logic_error\n{\npublic:\n\tbad_optional_access() : std::logic_error(\"Bad optional Access\") {}\n\n//\tGet the key function ~bad_optional_access() into the dylib\n    virtual ~bad_optional_access() _NOEXCEPT;\n};\n\n_LIBCPP_END_NAMESPACE_EXPERIMENTAL\n\n\n#if _LIBCPP_STD_VER > 11\n\n#include <initializer_list>\n#include <type_traits>\n#include <new>\n#include <__functional_base>\n#include <__undef_min_max>\n#include <__debug>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_LFTS\n\nstruct in_place_t {};\nconstexpr in_place_t in_place{};\n\nstruct nullopt_t\n{\n    explicit constexpr nullopt_t(int) noexcept {}\n};\n\nconstexpr nullopt_t nullopt{0};\n\ntemplate <class _Tp, bool = is_trivially_destructible<_Tp>::value>\nclass __optional_storage\n{\nprotected:\n    typedef _Tp value_type;\n    union\n    {\n        char __null_state_;\n        value_type __val_;\n    };\n    bool __engaged_ = false;\n\n    _LIBCPP_INLINE_VISIBILITY\n    ~__optional_storage()\n    {\n        if (__engaged_)\n            __val_.~value_type();\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr __optional_storage() noexcept\n        :  __null_state_('\\0') {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __optional_storage(const __optional_storage& __x)\n        :  __engaged_(__x.__engaged_)\n        {\n            if (__engaged_)\n                ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __optional_storage(__optional_storage&& __x)\n                      noexcept(is_nothrow_move_constructible<value_type>::value)\n        :  __engaged_(__x.__engaged_)\n        {\n            if (__engaged_)\n                ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr __optional_storage(const value_type& __v)\n        :  __val_(__v),\n           __engaged_(true) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr __optional_storage(value_type&& __v)\n        :  __val_(_VSTD::move(__v)),\n           __engaged_(true) {}\n\n    template <class... _Args>\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr\n    explicit __optional_storage(in_place_t, _Args&&... __args)\n       :  __val_(_VSTD::forward<_Args>(__args)...),\n           __engaged_(true) {}\n};\n\ntemplate <class _Tp>\nclass __optional_storage<_Tp, true>\n{\nprotected:\n    typedef _Tp value_type;\n    union\n    {\n        char __null_state_;\n        value_type __val_;\n    };\n    bool __engaged_ = false;\n\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr __optional_storage() noexcept\n        :  __null_state_('\\0') {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __optional_storage(const __optional_storage& __x)\n        :  __engaged_(__x.__engaged_)\n        {\n            if (__engaged_)\n                ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __optional_storage(__optional_storage&& __x)\n                      noexcept(is_nothrow_move_constructible<value_type>::value)\n        :  __engaged_(__x.__engaged_)\n        {\n            if (__engaged_)\n                ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr __optional_storage(const value_type& __v)\n        :  __val_(__v),\n           __engaged_(true) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr __optional_storage(value_type&& __v)\n        :  __val_(_VSTD::move(__v)),\n           __engaged_(true) {}\n\n    template <class... _Args>\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr\n    explicit __optional_storage(in_place_t, _Args&&... __args)\n       :  __val_(_VSTD::forward<_Args>(__args)...),\n           __engaged_(true) {}\n};\n\ntemplate <class _Tp>\nclass optional\n    : private __optional_storage<_Tp>\n{\n    typedef __optional_storage<_Tp> __base;\npublic:\n    typedef _Tp value_type;\n\n    static_assert(!is_reference<value_type>::value,\n              \"Instantiation of optional with a reference type is ill-formed.\");\n    static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value,\n              \"Instantiation of optional with a in_place_t type is ill-formed.\");\n    static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value,\n              \"Instantiation of optional with a nullopt_t type is ill-formed.\");\n    static_assert(is_object<value_type>::value,\n        \"Instantiation of optional with a non-object type is undefined behavior.\");\n    static_assert(is_nothrow_destructible<value_type>::value,\n        \"Instantiation of optional with an object type that is not noexcept destructible is undefined behavior.\");\n\n    _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}\n    _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;\n    _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;\n    _LIBCPP_INLINE_VISIBILITY ~optional() = default;\n    _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}\n    _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v)\n        : __base(__v) {}\n    _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v)\n        : __base(_VSTD::move(__v)) {}\n\n    template <class... _Args,\n              class = typename enable_if\n                      <\n                           is_constructible<value_type, _Args...>::value\n                      >::type\n             >\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr\n    explicit optional(in_place_t, _Args&&... __args)\n        : __base(in_place, _VSTD::forward<_Args>(__args)...) {}\n\n    template <class _Up, class... _Args,\n              class = typename enable_if\n                      <\n                           is_constructible<value_type, initializer_list<_Up>&, _Args...>::value\n                      >::type\n             >\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr\n    explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)\n        : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    optional& operator=(nullopt_t) noexcept\n    {\n        if (this->__engaged_)\n        {\n            this->__val_.~value_type();\n            this->__engaged_ = false;\n        }\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    optional&\n    operator=(const optional& __opt)\n    {\n        if (this->__engaged_ == __opt.__engaged_)\n        {\n            if (this->__engaged_)\n                this->__val_ = __opt.__val_;\n        }\n        else\n        {\n            if (this->__engaged_)\n                this->__val_.~value_type();\n            else\n                ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_);\n            this->__engaged_ = __opt.__engaged_;\n        }\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    optional&\n    operator=(optional&& __opt)\n        noexcept(is_nothrow_move_assignable<value_type>::value &&\n                 is_nothrow_move_constructible<value_type>::value)\n    {\n        if (this->__engaged_ == __opt.__engaged_)\n        {\n            if (this->__engaged_)\n                this->__val_ = _VSTD::move(__opt.__val_);\n        }\n        else\n        {\n            if (this->__engaged_)\n                this->__val_.~value_type();\n            else\n                ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));\n            this->__engaged_ = __opt.__engaged_;\n        }\n        return *this;\n    }\n\n    template <class _Up,\n              class = typename enable_if\n                      <\n                          is_same<typename remove_reference<_Up>::type, value_type>::value &&\n                          is_constructible<value_type, _Up>::value &&\n                          is_assignable<value_type&, _Up>::value\n                      >::type\n             >\n    _LIBCPP_INLINE_VISIBILITY\n    optional&\n    operator=(_Up&& __v)\n    {\n        if (this->__engaged_)\n            this->__val_ = _VSTD::forward<_Up>(__v);\n        else\n        {\n            ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v));\n            this->__engaged_ = true;\n        }\n        return *this;\n    }\n\n    template <class... _Args,\n              class = typename enable_if\n                      <\n                          is_constructible<value_type, _Args...>::value\n                      >::type\n             >\n    _LIBCPP_INLINE_VISIBILITY\n    void\n    emplace(_Args&&... __args)\n    {\n        *this = nullopt;\n        ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);\n        this->__engaged_ = true;\n    }\n\n    template <class _Up, class... _Args,\n              class = typename enable_if\n                      <\n                          is_constructible<value_type, initializer_list<_Up>&, _Args...>::value\n                      >::type\n             >\n    _LIBCPP_INLINE_VISIBILITY\n    void\n    emplace(initializer_list<_Up> __il, _Args&&... __args)\n    {\n        *this = nullopt;\n        ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...);\n        this->__engaged_ = true;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void\n    swap(optional& __opt)\n        noexcept(is_nothrow_move_constructible<value_type>::value &&\n                 __is_nothrow_swappable<value_type>::value)\n    {\n        using _VSTD::swap;\n        if (this->__engaged_ == __opt.__engaged_)\n        {\n            if (this->__engaged_)\n                swap(this->__val_, __opt.__val_);\n        }\n        else\n        {\n            if (this->__engaged_)\n            {\n                ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_));\n                this->__val_.~value_type();\n            }\n            else\n            {\n                ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));\n                __opt.__val_.~value_type();\n            }\n            swap(this->__engaged_, __opt.__engaged_);\n        }\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr\n    value_type const*\n    operator->() const\n    {\n        _LIBCPP_ASSERT(this->__engaged_, \"optional operator-> called for disengaged value\");\n        return __operator_arrow(__has_operator_addressof<value_type>{});\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    value_type*\n    operator->()\n    {\n        _LIBCPP_ASSERT(this->__engaged_, \"optional operator-> called for disengaged value\");\n        return _VSTD::addressof(this->__val_);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr\n    const value_type&\n    operator*() const\n    {\n        _LIBCPP_ASSERT(this->__engaged_, \"optional operator* called for disengaged value\");\n        return this->__val_;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    value_type&\n    operator*()\n    {\n        _LIBCPP_ASSERT(this->__engaged_, \"optional operator* called for disengaged value\");\n        return this->__val_;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr explicit operator bool() const noexcept {return this->__engaged_;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr value_type const& value() const\n    {\n        if (!this->__engaged_)\n            throw bad_optional_access();\n        return this->__val_;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    value_type& value()\n    {\n        if (!this->__engaged_)\n            throw bad_optional_access();\n        return this->__val_;\n    }\n\n    template <class _Up>\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr value_type value_or(_Up&& __v) const&\n    {\n        static_assert(is_copy_constructible<value_type>::value,\n                      \"optional<T>::value_or: T must be copy constructible\");\n        static_assert(is_convertible<_Up, value_type>::value,\n                      \"optional<T>::value_or: U must be convertible to T\");\n        return this->__engaged_ ? this->__val_ :\n                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));\n    }\n\n    template <class _Up>\n    _LIBCPP_INLINE_VISIBILITY\n    value_type value_or(_Up&& __v) &&\n    {\n        static_assert(is_move_constructible<value_type>::value,\n                      \"optional<T>::value_or: T must be move constructible\");\n        static_assert(is_convertible<_Up, value_type>::value,\n                      \"optional<T>::value_or: U must be convertible to T\");\n        return this->__engaged_ ? _VSTD::move(this->__val_) :\n                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));\n    }\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    value_type const*\n    __operator_arrow(true_type) const\n    {\n        return _VSTD::addressof(this->__val_);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr\n    value_type const*\n    __operator_arrow(false_type) const\n    {\n        return &this->__val_;\n    }\n};\n\n// Comparisons between optionals\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator==(const optional<_Tp>& __x, const optional<_Tp>& __y)\n{\n    if (static_cast<bool>(__x) != static_cast<bool>(__y))\n        return false;\n    if (!static_cast<bool>(__x))\n        return true;\n    return *__x == *__y;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator<(const optional<_Tp>& __x, const optional<_Tp>& __y)\n{\n    if (!static_cast<bool>(__y))\n        return false;\n    if (!static_cast<bool>(__x))\n        return true;\n    return *__x < *__y;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator>(const optional<_Tp>& __x, const optional<_Tp>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)\n{\n    return !(__x < __y);\n}\n\n\n// Comparisons with nullopt\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator==(const optional<_Tp>& __x, nullopt_t) noexcept\n{\n    return !static_cast<bool>(__x);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator==(nullopt_t, const optional<_Tp>& __x) noexcept\n{\n    return !static_cast<bool>(__x);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator!=(const optional<_Tp>& __x, nullopt_t) noexcept\n{\n    return static_cast<bool>(__x);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator!=(nullopt_t, const optional<_Tp>& __x) noexcept\n{\n    return static_cast<bool>(__x);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator<(const optional<_Tp>&, nullopt_t) noexcept\n{\n    return false;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator<(nullopt_t, const optional<_Tp>& __x) noexcept\n{\n    return static_cast<bool>(__x);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator<=(const optional<_Tp>& __x, nullopt_t) noexcept\n{\n    return !static_cast<bool>(__x);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator<=(nullopt_t, const optional<_Tp>& __x) noexcept\n{\n    return true;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator>(const optional<_Tp>& __x, nullopt_t) noexcept\n{\n    return static_cast<bool>(__x);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator>(nullopt_t, const optional<_Tp>& __x) noexcept\n{\n    return false;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator>=(const optional<_Tp>&, nullopt_t) noexcept\n{\n    return true;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator>=(nullopt_t, const optional<_Tp>& __x) noexcept\n{\n    return !static_cast<bool>(__x);\n}\n\n// Comparisons with T\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator==(const optional<_Tp>& __x, const _Tp& __v)\n{\n    return static_cast<bool>(__x) ? *__x == __v : false;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator==(const _Tp& __v, const optional<_Tp>& __x)\n{\n    return static_cast<bool>(__x) ? *__x == __v : false;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator!=(const optional<_Tp>& __x, const _Tp& __v)\n{\n    return static_cast<bool>(__x) ? !(*__x == __v) : true;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator!=(const _Tp& __v, const optional<_Tp>& __x)\n{\n    return static_cast<bool>(__x) ? !(*__x == __v) : true;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator<(const optional<_Tp>& __x, const _Tp& __v)\n{\n    return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator<(const _Tp& __v, const optional<_Tp>& __x)\n{\n    return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator<=(const optional<_Tp>& __x, const _Tp& __v)\n{\n    return !(__x > __v);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator<=(const _Tp& __v, const optional<_Tp>& __x)\n{\n    return !(__v > __x);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator>(const optional<_Tp>& __x, const _Tp& __v)\n{\n    return static_cast<bool>(__x) ? __v < __x : false;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator>(const _Tp& __v, const optional<_Tp>& __x)\n{\n    return static_cast<bool>(__x) ? __x < __v : true;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator>=(const optional<_Tp>& __x, const _Tp& __v)\n{\n    return !(__x < __v);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\nbool\noperator>=(const _Tp& __v, const optional<_Tp>& __x)\n{\n    return !(__v < __x);\n}\n\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr\noptional<typename decay<_Tp>::type>\nmake_optional(_Tp&& __v)\n{\n    return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));\n}\n\n_LIBCPP_END_NAMESPACE_LFTS\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> >\n{\n    typedef std::experimental::optional<_Tp> argument_type;\n    typedef size_t        result_type;\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator()(const argument_type& __opt) const _NOEXCEPT\n    {\n        return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;\n    }\n};\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_STD_VER > 11\n\n#endif  // _LIBCPP_OPTIONAL\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/experimental/ratio",
    "content": "// -*- C++ -*-\n//===------------------------------ ratio ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_EXPERIMENTAL_RATIO\n#define _LIBCPP_EXPERIMENTAL_RATIO\n\n/**\n    experimental/ratio synopsis\n    C++1y\n#include <ratio>\n\nnamespace std {\nnamespace experimental {\ninline namespace fundamentals_v1 {\n\n  // See C++14 20.11.5, ratio comparison\n  template <class R1, class R2> constexpr bool ratio_equal_v\n    = ratio_equal<R1, R2>::value;\n  template <class R1, class R2> constexpr bool ratio_not_equal_v\n    = ratio_not_equal<R1, R2>::value;\n  template <class R1, class R2> constexpr bool ratio_less_v\n    = ratio_less<R1, R2>::value;\n  template <class R1, class R2> constexpr bool ratio_less_equal_v\n    = ratio_less_equal<R1, R2>::value;\n  template <class R1, class R2> constexpr bool ratio_greater_v\n    = ratio_greater<R1, R2>::value;\n  template <class R1, class R2> constexpr bool ratio_greater_equal_v\n    = ratio_greater_equal<R1, R2>::value;\n\n} // namespace fundamentals_v1\n} // namespace experimental\n} // namespace std\n\n*/\n\n#include <experimental/__config>\n\n#if _LIBCPP_STD_VER > 11\n\n#include <ratio>\n\n_LIBCPP_BEGIN_NAMESPACE_LFTS\n\n#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES\n\ntemplate <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_equal_v\n    = ratio_equal<_R1, _R2>::value;\n\ntemplate <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_not_equal_v\n    = ratio_not_equal<_R1, _R2>::value;\n\ntemplate <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_less_v\n    = ratio_less<_R1, _R2>::value;\n\ntemplate <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_less_equal_v\n    = ratio_less_equal<_R1, _R2>::value;\n\ntemplate <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_greater_v\n    = ratio_greater<_R1, _R2>::value;\n\ntemplate <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_greater_equal_v\n    = ratio_greater_equal<_R1, _R2>::value;\n\n#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */\n\n_LIBCPP_END_NAMESPACE_LFTS\n\n#endif /* _LIBCPP_STD_VER > 11 */\n\n#endif // _LIBCPP_EXPERIMENTAL_RATIO\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/experimental/string_view",
    "content": "// -*- C++ -*-\n//===------------------------ string_view ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_LFTS_STRING_VIEW\n#define _LIBCPP_LFTS_STRING_VIEW\n\n/*\nstring_view synopsis\n\nnamespace std {\n namespace experimental {\n  inline namespace library_fundamentals_v1 {\n\n    // 7.2, Class template basic_string_view\n    template<class charT, class traits = char_traits<charT>>\n        class basic_string_view;\n\n    // 7.9, basic_string_view non-member comparison functions\n    template<class charT, class traits>\n    constexpr bool operator==(basic_string_view<charT, traits> x,\n                              basic_string_view<charT, traits> y) noexcept;\n    template<class charT, class traits>\n    constexpr bool operator!=(basic_string_view<charT, traits> x,\n                              basic_string_view<charT, traits> y) noexcept;\n    template<class charT, class traits>\n    constexpr bool operator< (basic_string_view<charT, traits> x,\n                                 basic_string_view<charT, traits> y) noexcept;\n    template<class charT, class traits>\n    constexpr bool operator> (basic_string_view<charT, traits> x,\n                              basic_string_view<charT, traits> y) noexcept;\n    template<class charT, class traits>\n    constexpr bool operator<=(basic_string_view<charT, traits> x,\n                                 basic_string_view<charT, traits> y) noexcept;\n    template<class charT, class traits>\n    constexpr bool operator>=(basic_string_view<charT, traits> x,\n                              basic_string_view<charT, traits> y) noexcept;\n    // see below, sufficient additional overloads of comparison functions\n\n    // 7.10, Inserters and extractors\n    template<class charT, class traits>\n      basic_ostream<charT, traits>&\n        operator<<(basic_ostream<charT, traits>& os,\n                   basic_string_view<charT, traits> str);\n\n    // basic_string_view typedef names\n    typedef basic_string_view<char> string_view;\n    typedef basic_string_view<char16_t> u16string_view;\n    typedef basic_string_view<char32_t> u32string_view;\n    typedef basic_string_view<wchar_t> wstring_view;\n\n    template<class charT, class traits = char_traits<charT>>\n    class basic_string_view {\n      public:\n      // types\n      typedef traits traits_type;\n      typedef charT value_type;\n      typedef charT* pointer;\n      typedef const charT* const_pointer;\n      typedef charT& reference;\n      typedef const charT& const_reference;\n      typedef implementation-defined const_iterator;\n      typedef const_iterator iterator;\n      typedef reverse_iterator<const_iterator> const_reverse_iterator;\n      typedef const_reverse_iterator reverse_iterator;\n      typedef size_t size_type;\n      typedef ptrdiff_t difference_type;\n      static constexpr size_type npos = size_type(-1);\n\n      // 7.3, basic_string_view constructors and assignment operators\n      constexpr basic_string_view() noexcept;\n      constexpr basic_string_view(const basic_string_view&) noexcept = default;\n      basic_string_view& operator=(const basic_string_view&) noexcept = default;\n      template<class Allocator>\n      basic_string_view(const basic_string<charT, traits, Allocator>& str) noexcept;\n      constexpr basic_string_view(const charT* str);\n      constexpr basic_string_view(const charT* str, size_type len);\n\n      // 7.4, basic_string_view iterator support\n      constexpr const_iterator begin() const noexcept;\n      constexpr const_iterator end() const noexcept;\n      constexpr const_iterator cbegin() const noexcept;\n      constexpr const_iterator cend() const noexcept;\n      const_reverse_iterator rbegin() const noexcept;\n      const_reverse_iterator rend() const noexcept;\n      const_reverse_iterator crbegin() const noexcept;\n      const_reverse_iterator crend() const noexcept;\n\n      // 7.5, basic_string_view capacity\n      constexpr size_type size() const noexcept;\n      constexpr size_type length() const noexcept;\n      constexpr size_type max_size() const noexcept;\n      constexpr bool empty() const noexcept;\n\n      // 7.6, basic_string_view element access\n      constexpr const_reference operator[](size_type pos) const;\n      constexpr const_reference at(size_type pos) const;\n      constexpr const_reference front() const;\n      constexpr const_reference back() const;\n      constexpr const_pointer data() const noexcept;\n\n      // 7.7, basic_string_view modifiers\n      constexpr void clear() noexcept;\n      constexpr void remove_prefix(size_type n);\n      constexpr void remove_suffix(size_type n);\n      constexpr void swap(basic_string_view& s) noexcept;\n\n      // 7.8, basic_string_view string operations\n      template<class Allocator>\n      explicit operator basic_string<charT, traits, Allocator>() const;\n      template<class Allocator = allocator<charT>>\n      basic_string<charT, traits, Allocator> to_string(\n        const Allocator& a = Allocator()) const;\n\n      size_type copy(charT* s, size_type n, size_type pos = 0) const;\n\n      constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;\n      constexpr int compare(basic_string_view s) const noexcept;\n      constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;\n      constexpr int compare(size_type pos1, size_type n1,\n                            basic_string_view s, size_type pos2, size_type n2) const;\n      constexpr int compare(const charT* s) const;\n      constexpr int compare(size_type pos1, size_type n1, const charT* s) const;\n      constexpr int compare(size_type pos1, size_type n1,\n                            const charT* s, size_type n2) const;\n      constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;\n      constexpr size_type find(charT c, size_type pos = 0) const noexcept;\n      constexpr size_type find(const charT* s, size_type pos, size_type n) const;\n      constexpr size_type find(const charT* s, size_type pos = 0) const;\n      constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;\n      constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;\n      constexpr size_type rfind(const charT* s, size_type pos, size_type n) const;\n      constexpr size_type rfind(const charT* s, size_type pos = npos) const;\n      constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;\n      constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;\n      constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const;\n      constexpr size_type find_first_of(const charT* s, size_type pos = 0) const;\n      constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;\n      constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;\n      constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const;\n      constexpr size_type find_last_of(const charT* s, size_type pos = npos) const;\n      constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;\n      constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;\n      constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const;\n      constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const;\n      constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept;\n      constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;\n      constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const;\n      constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const;\n\n     private:\n      const_pointer data_;  // exposition only\n      size_type     size_;  // exposition only\n    };\n\n  }  // namespace fundamentals_v1\n }  // namespace experimental\n\n  // 7.11, Hash support\n  template <class T> struct hash;\n  template <> struct hash<experimental::string_view>;\n  template <> struct hash<experimental::u16string_view>;\n  template <> struct hash<experimental::u32string_view>;\n  template <> struct hash<experimental::wstring_view>;\n\n}  // namespace std\n\n\n*/\n\n#include <experimental/__config>\n\n#include <string>\n#include <algorithm>\n#include <iterator>\n#include <ostream>\n#include <iomanip>\n\n#include <__debug>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_LFTS\n\n    template<class _CharT, class _Traits = _VSTD::char_traits<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_string_view {\n    public:\n        // types\n        typedef _Traits                                    traits_type;\n        typedef _CharT                                     value_type;\n        typedef const _CharT*                              pointer;\n        typedef const _CharT*                              const_pointer;\n        typedef const _CharT&                              reference;\n        typedef const _CharT&                              const_reference;\n        typedef const_pointer                              const_iterator; // See [string.view.iterators]\n        typedef const_iterator                             iterator;\n        typedef _VSTD::reverse_iterator<const_iterator>    const_reverse_iterator;\n        typedef const_reverse_iterator                     reverse_iterator;\n        typedef size_t                                     size_type;\n        typedef ptrdiff_t                                  difference_type;\n        static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1);\n\n        // [string.view.cons], construct/copy\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {}\n\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        basic_string_view(const basic_string_view&) _NOEXCEPT = default;\n\n        _LIBCPP_INLINE_VISIBILITY\n        basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;\n\n        template<class _Allocator>\n        _LIBCPP_INLINE_VISIBILITY\n        basic_string_view(const basic_string<_CharT, _Traits, _Allocator>& __str) _NOEXCEPT\n            : __data (__str.data()), __size(__str.size()) {}\n\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        basic_string_view(const _CharT* __s, size_type __len)\n            : __data(__s), __size(__len)\n        {\n//             _LIBCPP_ASSERT(__len == 0 || __s != nullptr, \"string_view::string_view(_CharT *, size_t): recieved nullptr\");\n        }\n\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        basic_string_view(const _CharT* __s)\n            : __data(__s), __size(_Traits::length(__s)) {}\n\n        // [string.view.iterators], iterators\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        const_iterator begin()  const _NOEXCEPT { return cbegin(); }\n\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        const_iterator end()    const _NOEXCEPT { return cend(); }\n\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        const_iterator cbegin() const _NOEXCEPT { return __data; }\n\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        const_iterator cend()   const _NOEXCEPT { return __data + __size; }\n\n        _LIBCPP_INLINE_VISIBILITY\n        const_reverse_iterator rbegin()   const _NOEXCEPT { return const_reverse_iterator(cend()); }\n\n        _LIBCPP_INLINE_VISIBILITY\n        const_reverse_iterator rend()     const _NOEXCEPT { return const_reverse_iterator(cbegin()); }\n\n        _LIBCPP_INLINE_VISIBILITY\n        const_reverse_iterator crbegin()  const _NOEXCEPT { return const_reverse_iterator(cend()); }\n\n        _LIBCPP_INLINE_VISIBILITY\n        const_reverse_iterator crend()    const _NOEXCEPT { return const_reverse_iterator(cbegin()); }\n\n        // [string.view.capacity], capacity\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        size_type size()     const _NOEXCEPT { return __size; }\n\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        size_type length()   const _NOEXCEPT { return __size; }\n\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        size_type max_size() const _NOEXCEPT { return _VSTD::numeric_limits<size_type>::max(); }\n\n        _LIBCPP_CONSTEXPR bool _LIBCPP_INLINE_VISIBILITY\n        empty()         const _NOEXCEPT { return __size == 0; }\n\n        // [string.view.access], element access\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        const_reference operator[](size_type __pos) const { return __data[__pos]; }\n\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        const_reference at(size_type __pos) const\n        {\n            return __pos >= size()\n                ? (throw out_of_range(\"string_view::at\"), __data[0])\n                : __data[__pos];\n        }\n\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        const_reference front() const\n        {\n            return _LIBCPP_ASSERT(!empty(), \"string_view::front(): string is empty\"), __data[0];\n        }\n\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        const_reference back() const\n        {\n            return _LIBCPP_ASSERT(!empty(), \"string_view::back(): string is empty\"), __data[__size-1];\n        }\n\n        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY\n        const_pointer data() const _NOEXCEPT { return __data; }\n\n        // [string.view.modifiers], modifiers:\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        void clear() _NOEXCEPT\n        {\n            __data = nullptr;\n            __size = 0;\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        void remove_prefix(size_type __n) _NOEXCEPT\n        {\n            _LIBCPP_ASSERT(__n <= size(), \"remove_prefix() can't remove more than size()\");\n            __data += __n;\n            __size -= __n;\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        void remove_suffix(size_type __n) _NOEXCEPT\n        {\n            _LIBCPP_ASSERT(__n <= size(), \"remove_suffix() can't remove more than size()\");\n            __size -= __n;\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        void swap(basic_string_view& __other) _NOEXCEPT\n        {\n            const value_type *__p = __data;\n            __data = __other.__data;\n            __other.__data = __p;\n\n            size_type __sz = __size;\n            __size = __other.__size;\n            __other.__size = __sz;\n//             _VSTD::swap( __data, __other.__data );\n//             _VSTD::swap( __size, __other.__size );\n        }\n\n        // [string.view.ops], string operations:\n        template<class _Allocator>\n        _LIBCPP_INLINE_VISIBILITY\n        _LIBCPP_EXPLICIT operator basic_string<_CharT, _Traits, _Allocator>() const\n        { return basic_string<_CharT, _Traits, _Allocator>( begin(), end()); }\n\n        template<class _Allocator = allocator<_CharT> >\n        _LIBCPP_INLINE_VISIBILITY\n        basic_string<_CharT, _Traits, _Allocator>\n        to_string( const _Allocator& __a = _Allocator()) const\n        { return basic_string<_CharT, _Traits, _Allocator> ( begin(), end(), __a ); }\n\n        size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const\n        {\n            if ( __pos > size())\n                throw out_of_range(\"string_view::copy\");\n            size_type __rlen = _VSTD::min( __n, size() - __pos );\n            _VSTD::copy_n(begin() + __pos, __rlen, __s );\n            return __rlen;\n        }\n\n        _LIBCPP_CONSTEXPR\n        basic_string_view substr(size_type __pos = 0, size_type __n = npos) const\n        {\n//             if (__pos > size())\n//                 throw out_of_range(\"string_view::substr\");\n//             size_type __rlen = _VSTD::min( __n, size() - __pos );\n//             return basic_string_view(data() + __pos, __rlen);\n            return __pos > size()\n                ? throw out_of_range(\"string_view::substr\")\n                : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos));\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT\n        {\n            size_type __rlen = _VSTD::min( size(), __sv.size());\n            int __retval = _Traits::compare(data(), __sv.data(), __rlen);\n            if ( __retval == 0 ) // first __rlen chars matched\n                __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 );\n            return __retval;\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const\n        {\n            return substr(__pos1, __n1).compare(__sv);\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        int compare(                       size_type __pos1, size_type __n1, \n                    basic_string_view _sv, size_type __pos2, size_type __n2) const\n        {\n            return substr(__pos1, __n1).compare(_sv.substr(__pos2, __n2));\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        int compare(const _CharT* __s) const\n        {\n            return compare(basic_string_view(__s));\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        int compare(size_type __pos1, size_type __n1, const _CharT* __s) const\n        {\n            return substr(__pos1, __n1).compare(basic_string_view(__s));\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const\n        {\n            return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));\n        }\n\n        // find\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT\n        {\n            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, \"string_view::find(): recieved nullptr\");\n            return _VSTD::__str_find<value_type, size_type, traits_type, npos>\n                (data(), size(), __s.data(), __pos, __s.size());\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT\n        {\n            return _VSTD::__str_find<value_type, size_type, traits_type, npos>\n                (data(), size(), __c, __pos);\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find(const _CharT* __s, size_type __pos, size_type __n) const\n        {\n            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string_view::find(): recieved nullptr\");\n            return _VSTD::__str_find<value_type, size_type, traits_type, npos>\n                (data(), size(), __s, __pos, __n);\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find(const _CharT* __s, size_type __pos = 0) const\n        {\n            _LIBCPP_ASSERT(__s != nullptr, \"string_view::find(): recieved nullptr\");\n            return _VSTD::__str_find<value_type, size_type, traits_type, npos>\n                (data(), size(), __s, __pos, traits_type::length(__s));\n        }\n\n        // rfind\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT\n        {\n            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, \"string_view::find(): recieved nullptr\");\n            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>\n                (data(), size(), __s.data(), __pos, __s.size());\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT\n        {\n            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>\n                (data(), size(), __c, __pos);\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const\n        {\n            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string_view::rfind(): recieved nullptr\");\n            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>\n                (data(), size(), __s, __pos, __n);\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type rfind(const _CharT* __s, size_type __pos=npos) const\n        {\n            _LIBCPP_ASSERT(__s != nullptr, \"string_view::rfind(): recieved nullptr\");\n            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>\n                (data(), size(), __s, __pos, traits_type::length(__s));\n        }\n\n        // find_first_of\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT\n        {\n            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, \"string_view::find_first_of(): recieved nullptr\");\n            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>\n                (data(), size(), __s.data(), __pos, __s.size());\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT\n        { return find(__c, __pos); }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const\n        {\n            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string_view::find_first_of(): recieved nullptr\");\n            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>\n                (data(), size(), __s, __pos, __n);\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_first_of(const _CharT* __s, size_type __pos=0) const\n        {\n            _LIBCPP_ASSERT(__s != nullptr, \"string_view::find_first_of(): recieved nullptr\");\n            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>\n                (data(), size(), __s, __pos, traits_type::length(__s));\n        }\n\n        // find_last_of\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT\n        {\n            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, \"string_view::find_last_of(): recieved nullptr\");\n            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>\n                (data(), size(), __s.data(), __pos, __s.size());\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT\n        { return rfind(__c, __pos); }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const\n        {\n            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string_view::find_last_of(): recieved nullptr\");\n            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>\n                (data(), size(), __s, __pos, __n);\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_last_of(const _CharT* __s, size_type __pos=npos) const\n        {\n            _LIBCPP_ASSERT(__s != nullptr, \"string_view::find_last_of(): recieved nullptr\");\n            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>\n                (data(), size(), __s, __pos, traits_type::length(__s));\n        }\n\n        // find_first_not_of\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT\n        {\n            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, \"string_view::find_first_not_of(): recieved nullptr\");\n            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>\n                (data(), size(), __s.data(), __pos, __s.size());\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT\n        {\n            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>\n                (data(), size(), __c, __pos);\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const\n        {\n            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string_view::find_first_not_of(): recieved nullptr\");\n            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>\n                (data(), size(), __s, __pos, __n);\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const\n        {\n            _LIBCPP_ASSERT(__s != nullptr, \"string_view::find_first_not_of(): recieved nullptr\");\n            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>\n                (data(), size(), __s, __pos, traits_type::length(__s));\n        }\n\n        // find_last_not_of\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT\n        {\n            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, \"string_view::find_last_not_of(): recieved nullptr\");\n            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>\n                (data(), size(), __s.data(), __pos, __s.size());\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT\n        {\n            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>\n                (data(), size(), __c, __pos);\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const\n        {\n            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string_view::find_last_not_of(): recieved nullptr\");\n            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>\n                (data(), size(), __s, __pos, __n);\n        }\n\n        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n        size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const\n        {\n            _LIBCPP_ASSERT(__s != nullptr, \"string_view::find_last_not_of(): recieved nullptr\");\n            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>\n                (data(), size(), __s, __pos, traits_type::length(__s));\n        }\n\n    private:\n        const   value_type* __data;\n        size_type           __size;\n    };\n\n\n    // [string.view.comparison]\n    // operator ==\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator==(basic_string_view<_CharT, _Traits> __lhs,\n                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT\n    {\n        if ( __lhs.size() != __rhs.size()) return false;\n        return __lhs.compare(__rhs) == 0;\n    }\n\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator==(basic_string_view<_CharT, _Traits> __lhs,\n                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT\n    {\n        if ( __lhs.size() != __rhs.size()) return false;\n        return __lhs.compare(__rhs) == 0;\n    }\n\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator==(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, \n                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT\n    {\n        if ( __lhs.size() != __rhs.size()) return false;\n        return __lhs.compare(__rhs) == 0;\n    }\n\n\n    // operator !=\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT\n    {\n        if ( __lhs.size() != __rhs.size())\n            return true;\n        return __lhs.compare(__rhs) != 0;\n    }\n\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(basic_string_view<_CharT, _Traits> __lhs,\n                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT\n    {\n        if ( __lhs.size() != __rhs.size())\n            return true;\n        return __lhs.compare(__rhs) != 0;\n    }\n\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, \n                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT\n    {\n        if ( __lhs.size() != __rhs.size())\n            return true;\n        return __lhs.compare(__rhs) != 0;\n    }\n\n\n    // operator <\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT\n    {\n        return __lhs.compare(__rhs) < 0;\n    }\n\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator<(basic_string_view<_CharT, _Traits> __lhs,\n                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT\n    {\n        return __lhs.compare(__rhs) < 0;\n    }\n\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator<(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, \n                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT\n    {\n        return __lhs.compare(__rhs) < 0;\n    }\n\n\n    // operator >\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT\n    {\n        return __lhs.compare(__rhs) > 0;\n    }\n\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator>(basic_string_view<_CharT, _Traits> __lhs,\n                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT\n    {\n        return __lhs.compare(__rhs) > 0;\n    }\n\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator>(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, \n                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT\n    {\n        return __lhs.compare(__rhs) > 0;\n    }\n\n\n    // operator <=\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT\n    {\n        return __lhs.compare(__rhs) <= 0;\n    }\n\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator<=(basic_string_view<_CharT, _Traits> __lhs,\n                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT\n    {\n        return __lhs.compare(__rhs) <= 0;\n    }\n\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator<=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, \n                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT\n    {\n        return __lhs.compare(__rhs) <= 0;\n    }\n\n\n    // operator >=\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT\n    {\n        return __lhs.compare(__rhs) >= 0;\n    }\n\n\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator>=(basic_string_view<_CharT, _Traits> __lhs,\n                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT\n    {\n        return __lhs.compare(__rhs) >= 0;\n    }\n\n    template<class _CharT, class _Traits>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator>=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, \n                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT\n    {\n        return __lhs.compare(__rhs) >= 0;\n    }\n\n\n    // [string.view.io]\n    template<class _CharT, class _Traits>\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __sv)\n    {\n        return _VSTD::__put_character_sequence(__os, __sv.data(), __sv.size());\n    }\n\n  typedef basic_string_view<char>     string_view;\n  typedef basic_string_view<char16_t> u16string_view;\n  typedef basic_string_view<char32_t> u32string_view;\n  typedef basic_string_view<wchar_t>  wstring_view;\n\n_LIBCPP_END_NAMESPACE_LFTS\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n// [string.view.hash]\n// Shamelessly stolen from <string>\ntemplate<class _CharT, class _Traits>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::basic_string_view<_CharT, _Traits> >\n    : public unary_function<std::experimental::basic_string_view<_CharT, _Traits>, size_t>\n{\n    size_t operator()(const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT;\n};\n\ntemplate<class _CharT, class _Traits>\nsize_t\nhash<std::experimental::basic_string_view<_CharT, _Traits> >::operator()(\n        const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT\n{\n    return __do_string_hash(__val.data(), __val.data() + __val.size());\n}\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _CharT, class _Traits>\n__quoted_output_proxy<_CharT, const _CharT *, _Traits>\nquoted ( std::experimental::basic_string_view <_CharT, _Traits> __sv,\n             _CharT __delim = _CharT('\"'), _CharT __escape=_CharT('\\\\'))\n{\n    return __quoted_output_proxy<_CharT, const _CharT *, _Traits> \n         ( __sv.data(), __sv.data() + __sv.size(), __delim, __escape );\n}\n#endif\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif // _LIBCPP_LFTS_STRING_VIEW\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/experimental/system_error",
    "content": "// -*- C++ -*-\n//===-------------------------- system_error ------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR\n#define _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR\n\n/**\n    experimental/system_error synopsis\n\n// C++1y\n\n#include <system_error>\n\nnamespace std {\nnamespace experimental {\ninline namespace fundamentals_v1 {\n\n  // See C++14 19.5, System error support\n  template <class T> constexpr bool is_error_code_enum_v\n    = is_error_code_enum<T>::value;\n  template <class T> constexpr bool is_error_condition_enum_v\n    = is_error_condition_enum<T>::value;\n\n} // namespace fundamentals_v1\n} // namespace experimental\n} // namespace std\n\n*/\n\n#include <experimental/__config>\n\n#if _LIBCPP_STD_VER > 11\n\n#include <system_error>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_LFTS\n\n#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_error_code_enum_v\n    = is_error_code_enum<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_error_condition_enum_v\n    = is_error_condition_enum<_Tp>::value;\n\n#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */\n\n_LIBCPP_END_NAMESPACE_LFTS\n\n#endif /* _LIBCPP_STD_VER > 11 */\n\n#endif /* _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR */\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/experimental/tuple",
    "content": "// -*- C++ -*-\n//===----------------------------- tuple ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_EXPERIMENTAL_TUPLE\n#define _LIBCPP_EXPERIMENTAL_TUPLE\n\n/*\n    experimental/tuple synopsis\n\n// C++1y\n\n#include <tuple>\n\nnamespace std {\nnamespace experimental {\ninline namespace fundamentals_v1 {\n\n  // See C++14 20.4.2.5, tuple helper classes\n  template <class T> constexpr size_t tuple_size_v\n    = tuple_size<T>::value;\n\n  // 3.2.2, Calling a function with a tuple of arguments\n  template <class F, class Tuple>\n  constexpr decltype(auto) apply(F&& f, Tuple&& t);\n\n} // namespace fundamentals_v1\n} // namespace experimental\n} // namespace std\n\n */\n\n# include <experimental/__config>\n\n#if _LIBCPP_STD_VER > 11\n\n# include <tuple>\n# include <utility>\n# include <__functional_base>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_LFTS\n\n#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES\ntemplate <class _Tp>\n_LIBCPP_CONSTEXPR size_t tuple_size_v = tuple_size<_Tp>::value;\n#endif\n\ntemplate <class _Fn, class _Tuple, size_t ..._Id>\ninline _LIBCPP_INLINE_VISIBILITY\ndecltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,\n                                  integer_sequence<size_t, _Id...>) {\n    return _VSTD::__invoke(\n        _VSTD::forward<_Fn>(__f),\n        _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...\n    );\n}\n\ntemplate <class _Fn, class _Tuple>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ndecltype(auto) apply(_Fn && __f, _Tuple && __t) {\n    return _VSTD_LFTS::__apply_tuple_impl(\n        _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),\n        make_index_sequence<tuple_size<typename decay<_Tuple>::type>::value>()\n    );\n}\n\n_LIBCPP_END_NAMESPACE_LFTS\n\n#endif /* _LIBCPP_STD_VER > 11 */\n\n#endif /* _LIBCPP_EXPERIMENTAL_TUPLE */\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/experimental/type_traits",
    "content": "// -*- C++ -*-\n//===-------------------------- type_traits -------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_EXPERIMENTAL_TYPE_TRAITS\n#define _LIBCPP_EXPERIMENTAL_TYPE_TRAITS\n\n/**\n    experimental/type_traits synopsis\n\n// C++1y\n#include <type_traits>\n\nnamespace std {\nnamespace experimental {\ninline namespace fundamentals_v1 {\n\n  // See C++14 20.10.4.1, primary type categories\n  template <class T> constexpr bool is_void_v\n    = is_void<T>::value;\n  template <class T> constexpr bool is_null_pointer_v\n    = is_null_pointer<T>::value;\n  template <class T> constexpr bool is_integral_v\n    = is_integral<T>::value;\n  template <class T> constexpr bool is_floating_point_v\n    = is_floating_point<T>::value;\n  template <class T> constexpr bool is_array_v\n    = is_array<T>::value;\n  template <class T> constexpr bool is_pointer_v\n    = is_pointer<T>::value;\n  template <class T> constexpr bool is_lvalue_reference_v\n    = is_lvalue_reference<T>::value;\n  template <class T> constexpr bool is_rvalue_reference_v\n    = is_rvalue_reference<T>::value;\n  template <class T> constexpr bool is_member_object_pointer_v\n    = is_member_object_pointer<T>::value;\n  template <class T> constexpr bool is_member_function_pointer_v\n    = is_member_function_pointer<T>::value;\n  template <class T> constexpr bool is_enum_v\n    = is_enum<T>::value;\n  template <class T> constexpr bool is_union_v\n    = is_union<T>::value;\n  template <class T> constexpr bool is_class_v\n    = is_class<T>::value;\n  template <class T> constexpr bool is_function_v\n    = is_function<T>::value;\n\n  // See C++14 20.10.4.2, composite type categories\n  template <class T> constexpr bool is_reference_v\n    = is_reference<T>::value;\n  template <class T> constexpr bool is_arithmetic_v\n    = is_arithmetic<T>::value;\n  template <class T> constexpr bool is_fundamental_v\n    = is_fundamental<T>::value;\n  template <class T> constexpr bool is_object_v\n    = is_object<T>::value;\n  template <class T> constexpr bool is_scalar_v\n    = is_scalar<T>::value;\n  template <class T> constexpr bool is_compound_v\n    = is_compound<T>::value;\n  template <class T> constexpr bool is_member_pointer_v\n    = is_member_pointer<T>::value;\n\n  // See C++14 20.10.4.3, type properties\n  template <class T> constexpr bool is_const_v\n    = is_const<T>::value;\n  template <class T> constexpr bool is_volatile_v\n    = is_volatile<T>::value;\n  template <class T> constexpr bool is_trivial_v\n    = is_trivial<T>::value;\n  template <class T> constexpr bool is_trivially_copyable_v\n    = is_trivially_copyable<T>::value;\n  template <class T> constexpr bool is_standard_layout_v\n    = is_standard_layout<T>::value;\n  template <class T> constexpr bool is_pod_v\n    = is_pod<T>::value;\n  template <class T> constexpr bool is_literal_type_v\n    = is_literal_type<T>::value;\n  template <class T> constexpr bool is_empty_v\n    = is_empty<T>::value;\n  template <class T> constexpr bool is_polymorphic_v\n    = is_polymorphic<T>::value;\n  template <class T> constexpr bool is_abstract_v\n    = is_abstract<T>::value;\n  template <class T> constexpr bool is_final_v\n    = is_final<T>::value;\n  template <class T> constexpr bool is_signed_v\n    = is_signed<T>::value;\n  template <class T> constexpr bool is_unsigned_v\n    = is_unsigned<T>::value;\n  template <class T, class... Args> constexpr bool is_constructible_v\n    = is_constructible<T, Args...>::value;\n  template <class T> constexpr bool is_default_constructible_v\n    = is_default_constructible<T>::value;\n  template <class T> constexpr bool is_copy_constructible_v\n    = is_copy_constructible<T>::value;\n  template <class T> constexpr bool is_move_constructible_v\n    = is_move_constructible<T>::value;\n  template <class T, class U> constexpr bool is_assignable_v\n    = is_assignable<T, U>::value;\n  template <class T> constexpr bool is_copy_assignable_v\n    = is_copy_assignable<T>::value;\n  template <class T> constexpr bool is_move_assignable_v\n    = is_move_assignable<T>::value;\n  template <class T> constexpr bool is_destructible_v\n    = is_destructible<T>::value;\n  template <class T, class... Args> constexpr bool is_trivially_constructible_v\n    = is_trivially_constructible<T, Args...>::value;\n  template <class T> constexpr bool is_trivially_default_constructible_v\n    = is_trivially_default_constructible<T>::value;\n  template <class T> constexpr bool is_trivially_copy_constructible_v\n    = is_trivially_copy_constructible<T>::value;\n  template <class T> constexpr bool is_trivially_move_constructible_v\n    = is_trivially_move_constructible<T>::value;\n  template <class T, class U> constexpr bool is_trivially_assignable_v\n    = is_trivially_assignable<T, U>::value;\n  template <class T> constexpr bool is_trivially_copy_assignable_v\n    = is_trivially_copy_assignable<T>::value;\n  template <class T> constexpr bool is_trivially_move_assignable_v\n    = is_trivially_move_assignable<T>::value;\n  template <class T> constexpr bool is_trivially_destructible_v\n    = is_trivially_destructible<T>::value;\n  template <class T, class... Args> constexpr bool is_nothrow_constructible_v\n    = is_nothrow_constructible<T, Args...>::value;\n  template <class T> constexpr bool is_nothrow_default_constructible_v\n    = is_nothrow_default_constructible<T>::value;\n  template <class T> constexpr bool is_nothrow_copy_constructible_v\n    = is_nothrow_copy_constructible<T>::value;\n  template <class T> constexpr bool is_nothrow_move_constructible_v\n    = is_nothrow_move_constructible<T>::value;\n  template <class T, class U> constexpr bool is_nothrow_assignable_v\n    = is_nothrow_assignable<T, U>::value;\n  template <class T> constexpr bool is_nothrow_copy_assignable_v\n    = is_nothrow_copy_assignable<T>::value;\n  template <class T> constexpr bool is_nothrow_move_assignable_v\n    = is_nothrow_move_assignable<T>::value;\n  template <class T> constexpr bool is_nothrow_destructible_v\n    = is_nothrow_destructible<T>::value;\n  template <class T> constexpr bool has_virtual_destructor_v\n    = has_virtual_destructor<T>::value;\n\n  // See C++14 20.10.5, type property queries\n  template <class T> constexpr size_t alignment_of_v\n    = alignment_of<T>::value;\n  template <class T> constexpr size_t rank_v\n    = rank<T>::value;\n  template <class T, unsigned I = 0> constexpr size_t extent_v\n    = extent<T, I>::value;\n\n  // See C++14 20.10.6, type relations\n  template <class T, class U> constexpr bool is_same_v\n    = is_same<T, U>::value;\n  template <class Base, class Derived> constexpr bool is_base_of_v\n    = is_base_of<Base, Derived>::value;\n  template <class From, class To> constexpr bool is_convertible_v\n    = is_convertible<From, To>::value;\n\n  // 3.3.2, Other type transformations\n  template <class> class invocation_type; // not defined\n  template <class F, class... ArgTypes> class invocation_type<F(ArgTypes...)>;\n  template <class> class raw_invocation_type; // not defined\n  template <class F, class... ArgTypes> class raw_invocation_type<F(ArgTypes...)>;\n\n  template <class T>\n    using invocation_type_t = typename invocation_type<T>::type;\n  template <class T>\n    using raw_invocation_type_t = typename raw_invocation_type<T>::type;\n\n} // namespace fundamentals_v1\n} // namespace experimental\n} // namespace std\n\n */\n\n#include <experimental/__config>\n\n#if _LIBCPP_STD_VER > 11\n\n#include <type_traits>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_LFTS\n\n#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES\n\n// C++14 20.10.4.1, primary type categories\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_void_v\n    = is_void<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_null_pointer_v\n    = is_null_pointer<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_integral_v\n    = is_integral<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_floating_point_v\n    = is_floating_point<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_array_v\n    = is_array<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_pointer_v\n    = is_pointer<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_lvalue_reference_v\n    = is_lvalue_reference<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_rvalue_reference_v\n    = is_rvalue_reference<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_member_object_pointer_v\n    = is_member_object_pointer<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_member_function_pointer_v\n    = is_member_function_pointer<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_enum_v\n    = is_enum<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_union_v\n    = is_union<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_class_v\n    = is_class<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_function_v\n    = is_function<_Tp>::value;\n\n// C++14 20.10.4.2,  composite type categories\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_reference_v\n    = is_reference<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_arithmetic_v\n    = is_arithmetic<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_fundamental_v\n    = is_fundamental<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_object_v\n    = is_object<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_scalar_v\n    = is_scalar<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_compound_v\n    = is_compound<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_member_pointer_v\n    = is_member_pointer<_Tp>::value;\n\n// C++14 20.10.4.3, type properties\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_const_v\n    = is_const<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_volatile_v\n    = is_volatile<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_trivial_v\n    = is_trivial<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_copyable_v\n    = is_trivially_copyable<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_standard_layout_v\n    = is_standard_layout<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_pod_v\n    = is_pod<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_literal_type_v\n    = is_literal_type<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_empty_v\n    = is_empty<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_polymorphic_v\n    = is_polymorphic<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_abstract_v\n    = is_abstract<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_final_v\n    = is_final<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_signed_v\n    = is_signed<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_unsigned_v\n    = is_unsigned<_Tp>::value;\n\ntemplate <class _Tp, class ..._Ts> _LIBCPP_CONSTEXPR bool is_constructible_v\n    = is_constructible<_Tp, _Ts...>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_default_constructible_v\n    = is_default_constructible<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_copy_constructible_v\n    = is_copy_constructible<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_move_constructible_v\n    = is_move_constructible<_Tp>::value;\n\ntemplate <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_assignable_v\n    = is_assignable<_Tp, _Up>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_copy_assignable_v\n    = is_copy_assignable<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_move_assignable_v\n    = is_move_assignable<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_destructible_v\n    = is_destructible<_Tp>::value;\n\ntemplate <class _Tp, class ..._Ts> _LIBCPP_CONSTEXPR bool is_trivially_constructible_v\n    = is_trivially_constructible<_Tp, _Ts...>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_default_constructible_v\n    = is_trivially_default_constructible<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_copy_constructible_v\n    = is_trivially_copy_constructible<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_move_constructible_v\n    = is_trivially_move_constructible<_Tp>::value;\n\ntemplate <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_trivially_assignable_v\n    = is_trivially_assignable<_Tp, _Up>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_copy_assignable_v\n    = is_trivially_copy_assignable<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_move_assignable_v\n    = is_trivially_move_assignable<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_destructible_v\n    = is_trivially_destructible<_Tp>::value;\n\ntemplate <class _Tp, class ..._Ts> _LIBCPP_CONSTEXPR bool is_nothrow_constructible_v\n    = is_nothrow_constructible<_Tp, _Ts...>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_default_constructible_v\n    = is_nothrow_default_constructible<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_copy_constructible_v\n    = is_nothrow_copy_constructible<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_move_constructible_v\n    = is_nothrow_move_constructible<_Tp>::value;\n\ntemplate <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_nothrow_assignable_v\n    = is_nothrow_assignable<_Tp, _Up>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_copy_assignable_v\n    = is_nothrow_copy_assignable<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_move_assignable_v\n    = is_nothrow_move_assignable<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_destructible_v\n    = is_nothrow_destructible<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR bool has_virtual_destructor_v\n    = has_virtual_destructor<_Tp>::value;\n\n// C++14 20.10.5, type properties queries\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR size_t alignment_of_v\n    = alignment_of<_Tp>::value;\n\ntemplate <class _Tp> _LIBCPP_CONSTEXPR size_t rank_v\n    = rank<_Tp>::value;\n\ntemplate <class _Tp, unsigned _Id = 0> _LIBCPP_CONSTEXPR size_t extent_v\n    = extent<_Tp, _Id>::value;\n\n// C++14 20.10.6, type relations\n\ntemplate <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_same_v\n    = is_same<_Tp, _Up>::value;\n\ntemplate <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_base_of_v\n    = is_base_of<_Tp, _Up>::value;\n\ntemplate <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_convertible_v\n    = is_convertible<_Tp, _Up>::value;\n\n#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */\n\n// 3.3.2, Other type transformations\n/*\ntemplate <class>\nclass _LIBCPP_TYPE_VIS_ONLY raw_invocation_type;\n\ntemplate <class _Fn, class ..._Args>\nclass _LIBCPP_TYPE_VIS_ONLY raw_invocation_type<_Fn(_Args...)>;\n\ntemplate <class>\nclass _LIBCPP_TYPE_VIS_ONLY invokation_type;\n\ntemplate <class _Fn, class ..._Args>\nclass _LIBCPP_TYPE_VIS_ONLY invokation_type<_Fn(_Args...)>;\n\ntemplate <class _Tp>\nusing invokation_type_t = typename invokation_type<_Tp>::type;\n\ntemplate <class _Tp>\nusing raw_invocation_type_t = typename raw_invocation_type<_Tp>::type;\n*/\n\n_LIBCPP_END_NAMESPACE_LFTS\n\n#endif /* _LIBCPP_STD_VER > 11 */\n\n#endif /* _LIBCPP_EXPERIMENTAL_TYPE_TRAITS */\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/experimental/utility",
    "content": "// -*- C++ -*-\n//===-------------------------- utility ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_EXPERIMENTAL_UTILITY\n#define _LIBCPP_EXPERIMENTAL_UTILITY\n\n/*\n    experimental/utility synopsis\n\n// C++1y\n\n#include <utility>\n\nnamespace std {\nnamespace experimental {\ninline namespace fundamentals_v1 {\n\n  3.1.2, erased-type placeholder\n  struct erased_type { };\n\n} // namespace fundamentals_v1\n} // namespace experimental\n} // namespace std\n\n */\n\n#include <experimental/__config>\n#include <utility>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_LFTS\n\n  struct _LIBCPP_TYPE_VIS_ONLY erased_type { };\n\n_LIBCPP_END_NAMESPACE_LFTS\n\n#endif /* _LIBCPP_EXPERIMENTAL_UTILITY */\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/ext/__hash",
    "content": "// -*- C++ -*-\n//===------------------------- hash_set ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_EXT_HASH\n#define _LIBCPP_EXT_HASH\n\n#pragma GCC system_header\n\n#include <string>\n#include <cstring>\n\nnamespace __gnu_cxx {\nusing namespace std;\n\ntemplate <typename _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash { };\n\ntemplate <> struct _LIBCPP_TYPE_VIS_ONLY hash<const char*>\n    : public unary_function<const char*, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(const char *__c) const _NOEXCEPT\n    {\n        return __do_string_hash(__c, __c + strlen(__c));\n    }\n};\n\ntemplate <> struct _LIBCPP_TYPE_VIS_ONLY hash<char *>\n    : public unary_function<char*, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(char *__c) const _NOEXCEPT\n    {\n        return __do_string_hash<const char *>(__c, __c + strlen(__c));\n    }\n};\n\ntemplate <> struct _LIBCPP_TYPE_VIS_ONLY hash<char>\n    : public unary_function<char, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(char __c) const _NOEXCEPT\n    {\n        return __c;\n    }\n};\n\ntemplate <> struct _LIBCPP_TYPE_VIS_ONLY hash<signed char>\n    : public unary_function<signed char, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(signed char __c) const _NOEXCEPT\n    {\n        return __c;\n    }\n};\n\ntemplate <> struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned char>\n    : public unary_function<unsigned char, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(unsigned char __c) const _NOEXCEPT\n    {\n        return __c;\n    }\n};\n\ntemplate <> struct _LIBCPP_TYPE_VIS_ONLY hash<short>\n    : public unary_function<short, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(short __c) const _NOEXCEPT\n    {\n        return __c;\n    }\n};\n\ntemplate <> struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned short>\n    : public unary_function<unsigned short, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(unsigned short __c) const _NOEXCEPT\n    {\n        return __c;\n    }\n};\n\ntemplate <> struct _LIBCPP_TYPE_VIS_ONLY hash<int>\n    : public unary_function<int, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(int __c) const _NOEXCEPT\n    {\n        return __c;\n    }\n};\n\ntemplate <> struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned int>\n    : public unary_function<unsigned int, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(unsigned int __c) const _NOEXCEPT\n    {\n        return __c;\n    }\n};\n\ntemplate <> struct _LIBCPP_TYPE_VIS_ONLY hash<long>\n    : public unary_function<long, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(long __c) const _NOEXCEPT\n    {\n        return __c;\n    }\n};\n\ntemplate <> struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned long>\n    : public unary_function<unsigned long, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(unsigned long __c) const _NOEXCEPT\n    {\n        return __c;\n    }\n};\n}\n\n#endif  // _LIBCPP_EXT_HASH\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/ext/hash_map",
    "content": "// -*- C++ -*-\n//===-------------------------- hash_map ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_HASH_MAP\n#define _LIBCPP_HASH_MAP\n\n/*\n\n    hash_map synopsis\n\nnamespace __gnu_cxx\n{\n\ntemplate <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,\n          class Alloc = allocator<pair<const Key, T>>>\nclass hash_map\n{\npublic:\n    // types\n    typedef Key                                                        key_type;\n    typedef T                                                          mapped_type;\n    typedef Hash                                                       hasher;\n    typedef Pred                                                       key_equal;\n    typedef Alloc                                                      allocator_type;\n    typedef pair<const key_type, mapped_type>                          value_type;\n    typedef value_type&                                                reference;\n    typedef const value_type&                                          const_reference;\n    typedef typename allocator_traits<allocator_type>::pointer         pointer;\n    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;\n    typedef typename allocator_traits<allocator_type>::size_type       size_type;\n    typedef typename allocator_traits<allocator_type>::difference_type difference_type;\n\n    typedef /unspecified/ iterator;\n    typedef /unspecified/ const_iterator;\n\n    explicit hash_map(size_type n = 193, const hasher& hf = hasher(),\n                           const key_equal& eql = key_equal(),\n                           const allocator_type& a = allocator_type());\n    template <class InputIterator>\n        hash_map(InputIterator f, InputIterator l,\n                      size_type n = 193, const hasher& hf = hasher(),\n                      const key_equal& eql = key_equal(),\n                      const allocator_type& a = allocator_type());\n    hash_map(const hash_map&);\n    ~hash_map();\n    hash_map& operator=(const hash_map&);\n\n    allocator_type get_allocator() const;\n\n    bool      empty() const;\n    size_type size() const;\n    size_type max_size() const;\n\n    iterator       begin();\n    iterator       end();\n    const_iterator begin()  const;\n    const_iterator end()    const;\n\n    pair<iterator, bool> insert(const value_type& obj);\n    template <class InputIterator>\n        void insert(InputIterator first, InputIterator last);\n\n    void erase(const_iterator position);\n    size_type erase(const key_type& k);\n    void erase(const_iterator first, const_iterator last);\n    void clear();\n\n    void swap(hash_map&);\n\n    hasher hash_funct() const;\n    key_equal key_eq() const;\n\n    iterator       find(const key_type& k);\n    const_iterator find(const key_type& k) const;\n    size_type count(const key_type& k) const;\n    pair<iterator, iterator>             equal_range(const key_type& k);\n    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;\n\n    mapped_type& operator[](const key_type& k);\n\n    size_type bucket_count() const;\n    size_type max_bucket_count() const;\n\n    size_type elems_in_bucket(size_type n) const;\n\n    void resize(size_type n);\n};\n\ntemplate <class Key, class T, class Hash, class Pred, class Alloc>\n    void swap(hash_map<Key, T, Hash, Pred, Alloc>& x,\n              hash_map<Key, T, Hash, Pred, Alloc>& y);\n\ntemplate <class Key, class T, class Hash, class Pred, class Alloc>\n    bool\n    operator==(const hash_map<Key, T, Hash, Pred, Alloc>& x,\n               const hash_map<Key, T, Hash, Pred, Alloc>& y);\n\ntemplate <class Key, class T, class Hash, class Pred, class Alloc>\n    bool\n    operator!=(const hash_map<Key, T, Hash, Pred, Alloc>& x,\n               const hash_map<Key, T, Hash, Pred, Alloc>& y);\n\ntemplate <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,\n          class Alloc = allocator<pair<const Key, T>>>\nclass hash_multimap\n{\npublic:\n    // types\n    typedef Key                                                        key_type;\n    typedef T                                                          mapped_type;\n    typedef Hash                                                       hasher;\n    typedef Pred                                                       key_equal;\n    typedef Alloc                                                      allocator_type;\n    typedef pair<const key_type, mapped_type>                          value_type;\n    typedef value_type&                                                reference;\n    typedef const value_type&                                          const_reference;\n    typedef typename allocator_traits<allocator_type>::pointer         pointer;\n    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;\n    typedef typename allocator_traits<allocator_type>::size_type       size_type;\n    typedef typename allocator_traits<allocator_type>::difference_type difference_type;\n\n    typedef /unspecified/ iterator;\n    typedef /unspecified/ const_iterator;\n\n    explicit hash_multimap(size_type n = 193, const hasher& hf = hasher(),\n                           const key_equal& eql = key_equal(),\n                           const allocator_type& a = allocator_type());\n    template <class InputIterator>\n        hash_multimap(InputIterator f, InputIterator l,\n                      size_type n = 193, const hasher& hf = hasher(),\n                      const key_equal& eql = key_equal(),\n                      const allocator_type& a = allocator_type());\n    explicit hash_multimap(const allocator_type&);\n    hash_multimap(const hash_multimap&);\n    ~hash_multimap();\n    hash_multimap& operator=(const hash_multimap&);\n\n    allocator_type get_allocator() const;\n\n    bool      empty() const;\n    size_type size() const;\n    size_type max_size() const;\n\n    iterator       begin();\n    iterator       end();\n    const_iterator begin()  const;\n    const_iterator end()    const;\n\n    iterator insert(const value_type& obj);\n    template <class InputIterator>\n        void insert(InputIterator first, InputIterator last);\n\n    void erase(const_iterator position);\n    size_type erase(const key_type& k);\n    void erase(const_iterator first, const_iterator last);\n    void clear();\n\n    void swap(hash_multimap&);\n\n    hasher hash_funct() const;\n    key_equal key_eq() const;\n\n    iterator       find(const key_type& k);\n    const_iterator find(const key_type& k) const;\n    size_type count(const key_type& k) const;\n    pair<iterator, iterator>             equal_range(const key_type& k);\n    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;\n\n    size_type bucket_count() const;\n    size_type max_bucket_count() const;\n\n    size_type elems_in_bucket(size_type n) const;\n\n    void resize(size_type n);\n};\n\ntemplate <class Key, class T, class Hash, class Pred, class Alloc>\n    void swap(hash_multimap<Key, T, Hash, Pred, Alloc>& x,\n              hash_multimap<Key, T, Hash, Pred, Alloc>& y);\n\ntemplate <class Key, class T, class Hash, class Pred, class Alloc>\n    bool\n    operator==(const hash_multimap<Key, T, Hash, Pred, Alloc>& x,\n               const hash_multimap<Key, T, Hash, Pred, Alloc>& y);\n\ntemplate <class Key, class T, class Hash, class Pred, class Alloc>\n    bool\n    operator!=(const hash_multimap<Key, T, Hash, Pred, Alloc>& x,\n               const hash_multimap<Key, T, Hash, Pred, Alloc>& y);\n\n}  // __gnu_cxx\n\n*/\n\n#include <__config>\n#include <__hash_table>\n#include <functional>\n#include <stdexcept>\n#include <type_traits>\n#include <ext/__hash>\n\n#if __DEPRECATED\n#if defined(_MSC_VER) && ! defined(__clang__)\n    _LIBCPP_WARNING(\"Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>\")\n#else\n#   warning Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>\n#endif\n#endif\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\nnamespace __gnu_cxx {\n\nusing namespace std;\n\ntemplate <class _Tp, class _Hash,\n          bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value\n        >\nclass __hash_map_hasher\n    : private _Hash\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : _Hash() {}\n    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : _Hash(__h) {}\n    _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return *this;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(const _Tp& __x) const\n        {return static_cast<const _Hash&>(*this)(__x.first);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(const typename _Tp::first_type& __x) const\n        {return static_cast<const _Hash&>(*this)(__x);}\n};\n\ntemplate <class _Tp, class _Hash>\nclass __hash_map_hasher<_Tp, _Hash, false>\n{\n    _Hash __hash_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : __hash_() {}\n    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : __hash_(__h) {}\n    _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return __hash_;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(const _Tp& __x) const\n        {return __hash_(__x.first);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(const typename _Tp::first_type& __x) const\n        {return __hash_(__x);}\n};\n\ntemplate <class _Tp, class _Pred,\n          bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value\n         >\nclass __hash_map_equal\n    : private _Pred\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : _Pred() {}\n    _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : _Pred(__p) {}\n    _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return *this;}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Tp& __x, const _Tp& __y) const\n        {return static_cast<const _Pred&>(*this)(__x.first, __y.first);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const\n        {return static_cast<const _Pred&>(*this)(__x, __y.first);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const\n        {return static_cast<const _Pred&>(*this)(__x.first, __y);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const typename _Tp::first_type& __x,\n                    const typename _Tp::first_type& __y) const\n        {return static_cast<const _Pred&>(*this)(__x, __y);}\n};\n\ntemplate <class _Tp, class _Pred>\nclass __hash_map_equal<_Tp, _Pred, false>\n{\n    _Pred __pred_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : __pred_() {}\n    _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : __pred_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return __pred_;}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Tp& __x, const _Tp& __y) const\n        {return __pred_(__x.first, __y.first);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const\n        {return __pred_(__x, __y.first);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const\n        {return __pred_(__x.first, __y);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const typename _Tp::first_type& __x,\n                    const typename _Tp::first_type& __y) const\n        {return __pred_(__x, __y);}\n};\n\ntemplate <class _Alloc>\nclass __hash_map_node_destructor\n{\n    typedef _Alloc                              allocator_type;\n    typedef allocator_traits<allocator_type>    __alloc_traits;\n    typedef typename __alloc_traits::value_type::value_type value_type;\npublic:\n    typedef typename __alloc_traits::pointer    pointer;\nprivate:\n    typedef typename value_type::first_type     first_type;\n    typedef typename value_type::second_type    second_type;\n\n    allocator_type& __na_;\n\n    __hash_map_node_destructor& operator=(const __hash_map_node_destructor&);\n\npublic:\n    bool __first_constructed;\n    bool __second_constructed;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __hash_map_node_destructor(allocator_type& __na)\n        : __na_(__na),\n          __first_constructed(false),\n          __second_constructed(false)\n        {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_node_destructor(__hash_node_destructor<allocator_type>&& __x)\n        : __na_(__x.__na_),\n          __first_constructed(__x.__value_constructed),\n          __second_constructed(__x.__value_constructed)\n        {\n            __x.__value_constructed = false;\n        }\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_node_destructor(const __hash_node_destructor<allocator_type>& __x)\n        : __na_(__x.__na_),\n          __first_constructed(__x.__value_constructed),\n          __second_constructed(__x.__value_constructed)\n        {\n            const_cast<bool&>(__x.__value_constructed) = false;\n        }\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    void operator()(pointer __p)\n    {\n        if (__second_constructed)\n            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.second));\n        if (__first_constructed)\n            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.first));\n        if (__p)\n            __alloc_traits::deallocate(__na_, __p, 1);\n    }\n};\n\ntemplate <class _HashIterator>\nclass _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator\n{\n    _HashIterator __i_;\n\n    typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;\n    typedef const typename _HashIterator::value_type::first_type key_type;\n    typedef typename _HashIterator::value_type::second_type      mapped_type;\npublic:\n    typedef forward_iterator_tag                                 iterator_category;\n    typedef pair<key_type, mapped_type>                          value_type;\n    typedef typename _HashIterator::difference_type              difference_type;\n    typedef value_type&                                          reference;\n    typedef typename __pointer_traits::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<value_type>\n#else\n            rebind<value_type>::other\n#endif\n                                                                 pointer;\n\n    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator() {}\n\n    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator(_HashIterator __i) : __i_(__i) {}\n\n    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *operator->();}\n    _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return (pointer)__i_.operator->();}\n\n    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator& operator++() {++__i_; return *this;}\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_iterator operator++(int)\n    {\n        __hash_map_iterator __t(*this);\n        ++(*this);\n        return __t;\n    }\n\n    friend _LIBCPP_INLINE_VISIBILITY \n    bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y)\n        {return __x.__i_ == __y.__i_;}\n    friend _LIBCPP_INLINE_VISIBILITY \n    bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)\n        {return __x.__i_ != __y.__i_;}\n\n    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY hash_map;\n    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY hash_multimap;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;\n};\n\ntemplate <class _HashIterator>\nclass _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator\n{\n    _HashIterator __i_;\n\n    typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;\n    typedef const typename _HashIterator::value_type::first_type key_type;\n    typedef typename _HashIterator::value_type::second_type      mapped_type;\npublic:\n    typedef forward_iterator_tag                                 iterator_category;\n    typedef pair<key_type, mapped_type>                          value_type;\n    typedef typename _HashIterator::difference_type              difference_type;\n    typedef const value_type&                                    reference;\n    typedef typename __pointer_traits::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<const value_type>\n#else\n            rebind<const value_type>::other\n#endif\n                                                                 pointer;\n\n    _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator() {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_const_iterator(_HashIterator __i) : __i_(__i) {}\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_const_iterator(\n            __hash_map_iterator<typename _HashIterator::__non_const_iterator> __i)\n                : __i_(__i.__i_) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    reference operator*() const {return *operator->();}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer operator->() const {return (pointer)__i_.operator->();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_const_iterator& operator++() {++__i_; return *this;}\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_const_iterator operator++(int)\n    {\n        __hash_map_const_iterator __t(*this);\n        ++(*this);\n        return __t;\n    }\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)\n        {return __x.__i_ == __y.__i_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)\n        {return __x.__i_ != __y.__i_;}\n\n    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY hash_map;\n    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY hash_multimap;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;\n};\n\ntemplate <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,\n          class _Alloc = allocator<pair<const _Key, _Tp> > >\nclass _LIBCPP_TYPE_VIS_ONLY hash_map\n{\npublic:\n    // types\n    typedef _Key                                           key_type;\n    typedef _Tp                                            mapped_type;\n    typedef _Tp                                            data_type;\n    typedef _Hash                                          hasher;\n    typedef _Pred                                          key_equal;\n    typedef _Alloc                                         allocator_type;\n    typedef pair<const key_type, mapped_type>              value_type;\n    typedef value_type&                                    reference;\n    typedef const value_type&                              const_reference;\n\nprivate:\n    typedef pair<key_type, mapped_type>                    __value_type;\n    typedef __hash_map_hasher<__value_type, hasher>   __hasher;\n    typedef __hash_map_equal<__value_type, key_equal> __key_equal;\n    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __value_type>::type __allocator_type;\n\n    typedef __hash_table<__value_type, __hasher,\n                         __key_equal,  __allocator_type>   __table;\n\n    __table __table_;\n\n    typedef typename __table::__node_pointer               __node_pointer;\n    typedef typename __table::__node_const_pointer         __node_const_pointer;\n    typedef typename __table::__node_traits                __node_traits;\n    typedef typename __table::__node_allocator             __node_allocator;\n    typedef typename __table::__node                       __node;\n    typedef __hash_map_node_destructor<__node_allocator>   _Dp;\n    typedef unique_ptr<__node, _Dp>                         __node_holder;\n    typedef allocator_traits<allocator_type>               __alloc_traits;\npublic:\n    typedef typename __alloc_traits::pointer         pointer;\n    typedef typename __alloc_traits::const_pointer   const_pointer;\n    typedef typename __alloc_traits::size_type       size_type;\n    typedef typename __alloc_traits::difference_type difference_type;\n\n    typedef __hash_map_iterator<typename __table::iterator>       iterator;\n    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY hash_map() {__table_.rehash(193);}\n    explicit hash_map(size_type __n, const hasher& __hf = hasher(),\n                           const key_equal& __eql = key_equal());\n    hash_map(size_type __n, const hasher& __hf,\n                  const key_equal& __eql,\n                  const allocator_type& __a);\n    template <class _InputIterator>\n        hash_map(_InputIterator __first, _InputIterator __last);\n    template <class _InputIterator>\n        hash_map(_InputIterator __first, _InputIterator __last,\n                      size_type __n, const hasher& __hf = hasher(),\n                      const key_equal& __eql = key_equal());\n    template <class _InputIterator>\n        hash_map(_InputIterator __first, _InputIterator __last,\n                      size_type __n, const hasher& __hf,\n                      const key_equal& __eql,\n                      const allocator_type& __a);\n    hash_map(const hash_map& __u);\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const\n        {return allocator_type(__table_.__node_alloc());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool      empty() const {return __table_.size() == 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const  {return __table_.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const {return __table_.max_size();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       begin()        {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       end()          {return __table_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin()  const {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end()    const {return __table_.end();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, bool> insert(const value_type& __x)\n        {return __table_.__insert_unique(__x);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;}\n    template <class _InputIterator>\n        void insert(_InputIterator __first, _InputIterator __last);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void erase(const_iterator __p) {__table_.erase(__p.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    void erase(const_iterator __first, const_iterator __last)\n        {__table_.erase(__first.__i_, __last.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() {__table_.clear();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(hash_map& __u) {__table_.swap(__u.__table_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    hasher hash_funct() const\n        {return __table_.hash_function().hash_function();}\n    _LIBCPP_INLINE_VISIBILITY\n    key_equal key_eq() const\n        {return __table_.key_eq().key_eq();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       find(const key_type& __k)       {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator find(const key_type& __k) const {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, iterator>             equal_range(const key_type& __k)\n        {return __table_.__equal_range_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const\n        {return __table_.__equal_range_unique(__k);}\n\n    mapped_type& operator[](const key_type& __k);\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket_count() const {return __table_.bucket_count();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_bucket_count() const {return __table_.max_bucket_count();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type elems_in_bucket(size_type __n) const\n        {return __table_.bucket_size(__n);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void resize(size_type __n) {__table_.rehash(__n);}\n\nprivate:\n    __node_holder __construct_node(const key_type& __k);\n};\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(\n        size_type __n, const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n    __table_.rehash(__n);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(\n        size_type __n, const hasher& __hf, const key_equal& __eql,\n        const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n    __table_.rehash(__n);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(\n        _InputIterator __first, _InputIterator __last)\n{\n    __table_.rehash(193);\n    insert(__first, __last);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(\n        const hash_map& __u)\n    : __table_(__u.__table_)\n{\n    __table_.rehash(__u.bucket_count());\n    insert(__u.begin(), __u.end());\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntypename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder\nhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k)\n{\n    __node_allocator& __na = __table_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), __k);\n    __h.get_deleter().__first_constructed = true;\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));\n    __h.get_deleter().__second_constructed = true;\n    return _VSTD::move(__h);  // explicitly moved for C++03\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,\n                                                       _InputIterator __last)\n{\n    for (; __first != __last; ++__first)\n        __table_.__insert_unique(*__first);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\n_Tp&\nhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)\n{\n    iterator __i = find(__k);\n    if (__i != end())\n        return __i->second;\n    __node_holder __h = __construct_node(__k);\n    pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());\n    __h.release();\n    return __r.first->second;\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,\n     hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nbool\noperator==(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,\n           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)\n{\n    if (__x.size() != __y.size())\n        return false;\n    typedef typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator\n                                                                 const_iterator;\n    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();\n            __i != __ex; ++__i)\n    {\n        const_iterator __j = __y.find(__i->first);\n        if (__j == __ey || !(*__i == *__j))\n            return false;\n    }\n    return true;\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,\n           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,\n          class _Alloc = allocator<pair<const _Key, _Tp> > >\nclass _LIBCPP_TYPE_VIS_ONLY hash_multimap\n{\npublic:\n    // types\n    typedef _Key                                           key_type;\n    typedef _Tp                                            mapped_type;\n    typedef _Tp                                            data_type;\n    typedef _Hash                                          hasher;\n    typedef _Pred                                          key_equal;\n    typedef _Alloc                                         allocator_type;\n    typedef pair<const key_type, mapped_type>              value_type;\n    typedef value_type&                                    reference;\n    typedef const value_type&                              const_reference;\n\nprivate:\n    typedef pair<key_type, mapped_type>                    __value_type;\n    typedef __hash_map_hasher<__value_type, hasher>   __hasher;\n    typedef __hash_map_equal<__value_type, key_equal> __key_equal;\n    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __value_type>::type __allocator_type;\n\n    typedef __hash_table<__value_type, __hasher,\n                         __key_equal,  __allocator_type>   __table;\n\n    __table __table_;\n\n    typedef typename __table::__node_traits                __node_traits;\n    typedef typename __table::__node_allocator             __node_allocator;\n    typedef typename __table::__node                       __node;\n    typedef __hash_map_node_destructor<__node_allocator>   _Dp;\n    typedef unique_ptr<__node, _Dp>                         __node_holder;\n    typedef allocator_traits<allocator_type>               __alloc_traits;\npublic:\n    typedef typename __alloc_traits::pointer         pointer;\n    typedef typename __alloc_traits::const_pointer   const_pointer;\n    typedef typename __alloc_traits::size_type       size_type;\n    typedef typename __alloc_traits::difference_type difference_type;\n\n    typedef __hash_map_iterator<typename __table::iterator>       iterator;\n    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY\n    hash_multimap() {__table_.rehash(193);}\n    explicit hash_multimap(size_type __n, const hasher& __hf = hasher(),\n                                const key_equal& __eql = key_equal());\n    hash_multimap(size_type __n, const hasher& __hf,\n                                const key_equal& __eql,\n                                const allocator_type& __a);\n    template <class _InputIterator>\n        hash_multimap(_InputIterator __first, _InputIterator __last);\n    template <class _InputIterator>\n        hash_multimap(_InputIterator __first, _InputIterator __last,\n                      size_type __n, const hasher& __hf = hasher(),\n                      const key_equal& __eql = key_equal());\n    template <class _InputIterator>\n        hash_multimap(_InputIterator __first, _InputIterator __last,\n                      size_type __n, const hasher& __hf,\n                      const key_equal& __eql,\n                      const allocator_type& __a);\n    hash_multimap(const hash_multimap& __u);\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const\n        {return allocator_type(__table_.__node_alloc());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool      empty() const {return __table_.size() == 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const  {return __table_.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const {return __table_.max_size();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       begin()        {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       end()          {return __table_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin()  const {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end()    const {return __table_.end();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator, const value_type& __x) {return insert(__x);}\n    template <class _InputIterator>\n        void insert(_InputIterator __first, _InputIterator __last);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void erase(const_iterator __p) {__table_.erase(__p.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    void erase(const_iterator __first, const_iterator __last)\n        {__table_.erase(__first.__i_, __last.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() {__table_.clear();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(hash_multimap& __u) {__table_.swap(__u.__table_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    hasher hash_funct() const\n        {return __table_.hash_function().hash_function();}\n    _LIBCPP_INLINE_VISIBILITY\n    key_equal key_eq() const\n        {return __table_.key_eq().key_eq();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       find(const key_type& __k)       {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator find(const key_type& __k) const {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, iterator>             equal_range(const key_type& __k)\n        {return __table_.__equal_range_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const\n        {return __table_.__equal_range_multi(__k);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket_count() const {return __table_.bucket_count();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_bucket_count() const {return __table_.max_bucket_count();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type elems_in_bucket(size_type __n) const\n        {return __table_.bucket_size(__n);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void resize(size_type __n) {__table_.rehash(__n);}\n};\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nhash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(\n        size_type __n, const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n    __table_.rehash(__n);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nhash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(\n        size_type __n, const hasher& __hf, const key_equal& __eql,\n        const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n    __table_.rehash(__n);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nhash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(\n        _InputIterator __first, _InputIterator __last)\n{\n    __table_.rehash(193);\n    insert(__first, __last);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nhash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nhash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nhash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(\n        const hash_multimap& __u)\n    : __table_(__u.__table_)\n{\n    __table_.rehash(__u.bucket_count());\n    insert(__u.begin(), __u.end());\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nhash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,\n                                                            _InputIterator __last)\n{\n    for (; __first != __last; ++__first)\n        __table_.__insert_multi(*__first);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,\n     hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nbool\noperator==(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,\n           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)\n{\n    if (__x.size() != __y.size())\n        return false;\n    typedef typename hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator\n                                                                 const_iterator;\n    typedef pair<const_iterator, const_iterator> _EqRng;\n    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)\n    {\n        _EqRng __xeq = __x.equal_range(__i->first);\n        _EqRng __yeq = __y.equal_range(__i->first);\n        if (_VSTD::distance(__xeq.first, __xeq.second) !=\n            _VSTD::distance(__yeq.first, __yeq.second) ||\n                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))\n            return false;\n        __i = __xeq.second;\n    }\n    return true;\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,\n           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)\n{\n    return !(__x == __y);\n}\n\n} // __gnu_cxx\n\n#endif  // _LIBCPP_HASH_MAP\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/ext/hash_set",
    "content": "// -*- C++ -*-\n//===------------------------- hash_set ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_HASH_SET\n#define _LIBCPP_HASH_SET\n\n/*\n\n    hash_set synopsis\n\nnamespace __gnu_cxx\n{\n\ntemplate <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,\n          class Alloc = allocator<Value>>\nclass hash_set\n{\npublic:\n    // types\n    typedef Value                                                      key_type;\n    typedef key_type                                                   value_type;\n    typedef Hash                                                       hasher;\n    typedef Pred                                                       key_equal;\n    typedef Alloc                                                      allocator_type;\n    typedef value_type&                                                reference;\n    typedef const value_type&                                          const_reference;\n    typedef typename allocator_traits<allocator_type>::pointer         pointer;\n    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;\n    typedef typename allocator_traits<allocator_type>::size_type       size_type;\n    typedef typename allocator_traits<allocator_type>::difference_type difference_type;\n\n    typedef /unspecified/ iterator;\n    typedef /unspecified/ const_iterator;\n\n    explicit hash_set(size_type n = 193, const hasher& hf = hasher(),\n                           const key_equal& eql = key_equal(),\n                           const allocator_type& a = allocator_type());\n    template <class InputIterator>\n        hash_set(InputIterator f, InputIterator l,\n                      size_type n = 193, const hasher& hf = hasher(),\n                      const key_equal& eql = key_equal(),\n                      const allocator_type& a = allocator_type());\n    hash_set(const hash_set&);\n    ~hash_set();\n    hash_set& operator=(const hash_set&);\n\n    allocator_type get_allocator() const;\n\n    bool      empty() const;\n    size_type size() const;\n    size_type max_size() const;\n\n    iterator       begin();\n    iterator       end();\n    const_iterator begin()  const;\n    const_iterator end()    const;\n\n    pair<iterator, bool> insert(const value_type& obj);\n    template <class InputIterator>\n        void insert(InputIterator first, InputIterator last);\n\n    void erase(const_iterator position);\n    size_type erase(const key_type& k);\n    void erase(const_iterator first, const_iterator last);\n    void clear();\n\n    void swap(hash_set&);\n\n    hasher hash_funct() const;\n    key_equal key_eq() const;\n\n    iterator       find(const key_type& k);\n    const_iterator find(const key_type& k) const;\n    size_type count(const key_type& k) const;\n    pair<iterator, iterator>             equal_range(const key_type& k);\n    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;\n\n    size_type bucket_count() const;\n    size_type max_bucket_count() const;\n\n    size_type elems_in_bucket(size_type n) const;\n\n    void resize(size_type n);\n};\n\ntemplate <class Value, class Hash, class Pred, class Alloc>\n    void swap(hash_set<Value, Hash, Pred, Alloc>& x,\n              hash_set<Value, Hash, Pred, Alloc>& y);\n\ntemplate <class Value, class Hash, class Pred, class Alloc>\n    bool\n    operator==(const hash_set<Value, Hash, Pred, Alloc>& x,\n               const hash_set<Value, Hash, Pred, Alloc>& y);\n\ntemplate <class Value, class Hash, class Pred, class Alloc>\n    bool\n    operator!=(const hash_set<Value, Hash, Pred, Alloc>& x,\n               const hash_set<Value, Hash, Pred, Alloc>& y);\n\ntemplate <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,\n          class Alloc = allocator<Value>>\nclass hash_multiset\n{\npublic:\n    // types\n    typedef Value                                                      key_type;\n    typedef key_type                                                   value_type;\n    typedef Hash                                                       hasher;\n    typedef Pred                                                       key_equal;\n    typedef Alloc                                                      allocator_type;\n    typedef value_type&                                                reference;\n    typedef const value_type&                                          const_reference;\n    typedef typename allocator_traits<allocator_type>::pointer         pointer;\n    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;\n    typedef typename allocator_traits<allocator_type>::size_type       size_type;\n    typedef typename allocator_traits<allocator_type>::difference_type difference_type;\n\n    typedef /unspecified/ iterator;\n    typedef /unspecified/ const_iterator;\n\n    explicit hash_multiset(size_type n = 193, const hasher& hf = hasher(),\n                           const key_equal& eql = key_equal(),\n                           const allocator_type& a = allocator_type());\n    template <class InputIterator>\n        hash_multiset(InputIterator f, InputIterator l,\n                      size_type n = 193, const hasher& hf = hasher(),\n                      const key_equal& eql = key_equal(),\n                      const allocator_type& a = allocator_type());\n    hash_multiset(const hash_multiset&);\n    ~hash_multiset();\n    hash_multiset& operator=(const hash_multiset&);\n\n    allocator_type get_allocator() const;\n\n    bool      empty() const;\n    size_type size() const;\n    size_type max_size() const;\n\n    iterator       begin();\n    iterator       end();\n    const_iterator begin()  const;\n    const_iterator end()    const;\n\n    iterator insert(const value_type& obj);\n    template <class InputIterator>\n        void insert(InputIterator first, InputIterator last);\n\n    void erase(const_iterator position);\n    size_type erase(const key_type& k);\n    void erase(const_iterator first, const_iterator last);\n    void clear();\n\n    void swap(hash_multiset&);\n\n    hasher hash_funct() const;\n    key_equal key_eq() const;\n\n    iterator       find(const key_type& k);\n    const_iterator find(const key_type& k) const;\n    size_type count(const key_type& k) const;\n    pair<iterator, iterator>             equal_range(const key_type& k);\n    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;\n\n    size_type bucket_count() const;\n    size_type max_bucket_count() const;\n\n    size_type elems_in_bucket(size_type n) const;\n\n    void resize(size_type n);\n};\n\ntemplate <class Value, class Hash, class Pred, class Alloc>\n    void swap(hash_multiset<Value, Hash, Pred, Alloc>& x,\n              hash_multiset<Value, Hash, Pred, Alloc>& y);\n\ntemplate <class Value, class Hash, class Pred, class Alloc>\n    bool\n    operator==(const hash_multiset<Value, Hash, Pred, Alloc>& x,\n               const hash_multiset<Value, Hash, Pred, Alloc>& y);\n\ntemplate <class Value, class Hash, class Pred, class Alloc>\n    bool\n    operator!=(const hash_multiset<Value, Hash, Pred, Alloc>& x,\n               const hash_multiset<Value, Hash, Pred, Alloc>& y);\n}  // __gnu_cxx\n\n*/\n\n#include <__config>\n#include <__hash_table>\n#include <functional>\n#include <ext/__hash>\n\n#if __DEPRECATED\n#if defined(_MSC_VER) && ! defined(__clang__)\n    _LIBCPP_WARNING(\"Use of the header <ext/hash_set> is deprecated.  Migrate to <unordered_set>\")\n#else\n#   warning Use of the header <ext/hash_set> is deprecated.  Migrate to <unordered_set>\n#endif\n#endif\n\nnamespace __gnu_cxx {\n\nusing namespace std;\n\ntemplate <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,\n          class _Alloc = allocator<_Value> >\nclass _LIBCPP_TYPE_VIS_ONLY hash_set\n{\npublic:\n    // types\n    typedef _Value                                                     key_type;\n    typedef key_type                                                   value_type;\n    typedef _Hash                                                      hasher;\n    typedef _Pred                                                      key_equal;\n    typedef _Alloc                                                     allocator_type;\n    typedef value_type&                                                reference;\n    typedef const value_type&                                          const_reference;\n\nprivate:\n    typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;\n\n    __table __table_;\n\npublic:\n    typedef typename __table::pointer         pointer;\n    typedef typename __table::const_pointer   const_pointer;\n    typedef typename __table::size_type       size_type;\n    typedef typename __table::difference_type difference_type;\n\n    typedef typename __table::const_iterator       iterator;\n    typedef typename __table::const_iterator       const_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY\n    hash_set() {__table_.rehash(193);}\n    explicit hash_set(size_type __n, const hasher& __hf = hasher(),\n                           const key_equal& __eql = key_equal());\n    hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,\n                  const allocator_type& __a);\n    template <class _InputIterator>\n        hash_set(_InputIterator __first, _InputIterator __last);\n    template <class _InputIterator>\n        hash_set(_InputIterator __first, _InputIterator __last,\n                      size_type __n, const hasher& __hf = hasher(),\n                      const key_equal& __eql = key_equal());\n    template <class _InputIterator>\n        hash_set(_InputIterator __first, _InputIterator __last,\n                      size_type __n, const hasher& __hf, const key_equal& __eql,\n                      const allocator_type& __a);\n    hash_set(const hash_set& __u);\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const\n        {return allocator_type(__table_.__node_alloc());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool      empty() const {return __table_.size() == 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const  {return __table_.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const {return __table_.max_size();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       begin()        {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       end()          {return __table_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin()  const {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end()    const {return __table_.end();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, bool> insert(const value_type& __x)\n        {return __table_.__insert_unique(__x);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;}\n    template <class _InputIterator>\n        void insert(_InputIterator __first, _InputIterator __last);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void erase(const_iterator __p) {__table_.erase(__p);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    void erase(const_iterator __first, const_iterator __last)\n        {__table_.erase(__first, __last);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() {__table_.clear();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(hash_set& __u) {__table_.swap(__u.__table_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    hasher hash_funct() const {return __table_.hash_function();}\n    _LIBCPP_INLINE_VISIBILITY\n    key_equal key_eq() const {return __table_.key_eq();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       find(const key_type& __k)       {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator find(const key_type& __k) const {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, iterator>             equal_range(const key_type& __k)\n        {return __table_.__equal_range_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const\n        {return __table_.__equal_range_unique(__k);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket_count() const {return __table_.bucket_count();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_bucket_count() const {return __table_.max_bucket_count();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type elems_in_bucket(size_type __n) const {return __table_.bucket_size(__n);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void resize(size_type __n) {__table_.rehash(__n);}\n};\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nhash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(size_type __n,\n        const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n    __table_.rehash(__n);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nhash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(size_type __n,\n        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n    __table_.rehash(__n);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nhash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(\n        _InputIterator __first, _InputIterator __last)\n{\n    __table_.rehash(193);\n    insert(__first, __last);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nhash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nhash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nhash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(\n        const hash_set& __u)\n    : __table_(__u.__table_)\n{\n    __table_.rehash(__u.bucket_count());\n    insert(__u.begin(), __u.end());\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nhash_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,\n                                                    _InputIterator __last)\n{\n    for (; __first != __last; ++__first)\n        __table_.__insert_unique(*__first);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(hash_set<_Value, _Hash, _Pred, _Alloc>& __x,\n     hash_set<_Value, _Hash, _Pred, _Alloc>& __y)\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nbool\noperator==(const hash_set<_Value, _Hash, _Pred, _Alloc>& __x,\n           const hash_set<_Value, _Hash, _Pred, _Alloc>& __y)\n{\n    if (__x.size() != __y.size())\n        return false;\n    typedef typename hash_set<_Value, _Hash, _Pred, _Alloc>::const_iterator\n                                                                 const_iterator;\n    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();\n            __i != __ex; ++__i)\n    {\n        const_iterator __j = __y.find(*__i);\n        if (__j == __ey || !(*__i == *__j))\n            return false;\n    }\n    return true;\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const hash_set<_Value, _Hash, _Pred, _Alloc>& __x,\n           const hash_set<_Value, _Hash, _Pred, _Alloc>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,\n          class _Alloc = allocator<_Value> >\nclass _LIBCPP_TYPE_VIS_ONLY hash_multiset\n{\npublic:\n    // types\n    typedef _Value                                                     key_type;\n    typedef key_type                                                   value_type;\n    typedef _Hash                                                      hasher;\n    typedef _Pred                                                      key_equal;\n    typedef _Alloc                                                     allocator_type;\n    typedef value_type&                                                reference;\n    typedef const value_type&                                          const_reference;\n\nprivate:\n    typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;\n\n    __table __table_;\n\npublic:\n    typedef typename __table::pointer         pointer;\n    typedef typename __table::const_pointer   const_pointer;\n    typedef typename __table::size_type       size_type;\n    typedef typename __table::difference_type difference_type;\n\n    typedef typename __table::const_iterator       iterator;\n    typedef typename __table::const_iterator       const_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY\n    hash_multiset() {__table_.rehash(193);}\n    explicit hash_multiset(size_type __n, const hasher& __hf = hasher(),\n                                const key_equal& __eql = key_equal());\n    hash_multiset(size_type __n, const hasher& __hf,\n                       const key_equal& __eql, const allocator_type& __a);\n    template <class _InputIterator>\n        hash_multiset(_InputIterator __first, _InputIterator __last);\n    template <class _InputIterator>\n        hash_multiset(_InputIterator __first, _InputIterator __last,\n                      size_type __n, const hasher& __hf = hasher(),\n                      const key_equal& __eql = key_equal());\n    template <class _InputIterator>\n        hash_multiset(_InputIterator __first, _InputIterator __last,\n                      size_type __n , const hasher& __hf,\n                      const key_equal& __eql, const allocator_type& __a);\n    hash_multiset(const hash_multiset& __u);\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const\n        {return allocator_type(__table_.__node_alloc());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool      empty() const {return __table_.size() == 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const  {return __table_.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const {return __table_.max_size();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       begin()        {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       end()          {return __table_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin()  const {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end()    const {return __table_.end();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator, const value_type& __x) {return insert(__x);}\n    template <class _InputIterator>\n        void insert(_InputIterator __first, _InputIterator __last);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void erase(const_iterator __p) {__table_.erase(__p);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    void erase(const_iterator __first, const_iterator __last)\n        {__table_.erase(__first, __last);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() {__table_.clear();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(hash_multiset& __u) {__table_.swap(__u.__table_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    hasher hash_funct() const {return __table_.hash_function();}\n    _LIBCPP_INLINE_VISIBILITY\n    key_equal key_eq() const {return __table_.key_eq();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       find(const key_type& __k)       {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator find(const key_type& __k) const {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, iterator>             equal_range(const key_type& __k)\n        {return __table_.__equal_range_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const\n        {return __table_.__equal_range_multi(__k);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket_count() const {return __table_.bucket_count();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_bucket_count() const {return __table_.max_bucket_count();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type elems_in_bucket(size_type __n) const {return __table_.bucket_size(__n);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void resize(size_type __n) {__table_.rehash(__n);}\n};\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nhash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(\n        size_type __n, const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n    __table_.rehash(__n);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nhash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(\n        size_type __n, const hasher& __hf, const key_equal& __eql,\n        const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n    __table_.rehash(__n);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nhash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(\n        _InputIterator __first, _InputIterator __last)\n{\n    __table_.rehash(193);\n    insert(__first, __last);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nhash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nhash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nhash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(\n        const hash_multiset& __u)\n    : __table_(__u.__table_)\n{\n    __table_.rehash(__u.bucket_count());\n    insert(__u.begin(), __u.end());\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nhash_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,\n                                                         _InputIterator __last)\n{\n    for (; __first != __last; ++__first)\n        __table_.__insert_multi(*__first);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,\n     hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y)\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nbool\noperator==(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,\n           const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y)\n{\n    if (__x.size() != __y.size())\n        return false;\n    typedef typename hash_multiset<_Value, _Hash, _Pred, _Alloc>::const_iterator\n                                                                 const_iterator;\n    typedef pair<const_iterator, const_iterator> _EqRng;\n    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)\n    {\n        _EqRng __xeq = __x.equal_range(*__i);\n        _EqRng __yeq = __y.equal_range(*__i);\n        if (_VSTD::distance(__xeq.first, __xeq.second) !=\n            _VSTD::distance(__yeq.first, __yeq.second) ||\n                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))\n            return false;\n        __i = __xeq.second;\n    }\n    return true;\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,\n           const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y)\n{\n    return !(__x == __y);\n}\n\n} // __gnu_cxx\n\n#endif  // _LIBCPP_HASH_SET\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/forward_list",
    "content": "// -*- C++ -*-\n//===----------------------- forward_list ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_FORWARD_LIST\n#define _LIBCPP_FORWARD_LIST\n\n/*\n    forward_list synopsis\n\nnamespace std\n{\n\ntemplate <class T, class Allocator = allocator<T>>\nclass forward_list\n{\npublic:\n    typedef T         value_type;\n    typedef Allocator allocator_type;\n\n    typedef value_type&                                                reference;\n    typedef const value_type&                                          const_reference;\n    typedef typename allocator_traits<allocator_type>::pointer         pointer;\n    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;\n    typedef typename allocator_traits<allocator_type>::size_type       size_type;\n    typedef typename allocator_traits<allocator_type>::difference_type difference_type;\n\n    typedef <details> iterator;\n    typedef <details> const_iterator;\n\n    forward_list()\n        noexcept(is_nothrow_default_constructible<allocator_type>::value);\n    explicit forward_list(const allocator_type& a);\n    explicit forward_list(size_type n);\n    explicit forward_list(size_type n, const allocator_type& a); // C++14\n    forward_list(size_type n, const value_type& v);\n    forward_list(size_type n, const value_type& v, const allocator_type& a);\n    template <class InputIterator>\n        forward_list(InputIterator first, InputIterator last);\n    template <class InputIterator>\n        forward_list(InputIterator first, InputIterator last, const allocator_type& a);\n    forward_list(const forward_list& x);\n    forward_list(const forward_list& x, const allocator_type& a);\n    forward_list(forward_list&& x)\n        noexcept(is_nothrow_move_constructible<allocator_type>::value);\n    forward_list(forward_list&& x, const allocator_type& a);\n    forward_list(initializer_list<value_type> il);\n    forward_list(initializer_list<value_type> il, const allocator_type& a);\n\n    ~forward_list();\n\n    forward_list& operator=(const forward_list& x);\n    forward_list& operator=(forward_list&& x)\n        noexcept(\n             allocator_type::propagate_on_container_move_assignment::value &&\n             is_nothrow_move_assignable<allocator_type>::value);\n    forward_list& operator=(initializer_list<value_type> il);\n\n    template <class InputIterator>\n        void assign(InputIterator first, InputIterator last);\n    void assign(size_type n, const value_type& v);\n    void assign(initializer_list<value_type> il);\n\n    allocator_type get_allocator() const noexcept;\n\n    iterator       begin() noexcept;\n    const_iterator begin() const noexcept;\n    iterator       end() noexcept;\n    const_iterator end() const noexcept;\n\n    const_iterator cbegin() const noexcept;\n    const_iterator cend() const noexcept;\n\n    iterator       before_begin() noexcept;\n    const_iterator before_begin() const noexcept;\n    const_iterator cbefore_begin() const noexcept;\n\n    bool empty() const noexcept;\n    size_type max_size() const noexcept;\n\n    reference       front();\n    const_reference front() const;\n\n    template <class... Args> void emplace_front(Args&&... args);\n    void push_front(const value_type& v);\n    void push_front(value_type&& v);\n\n    void pop_front();\n\n    template <class... Args>\n        iterator emplace_after(const_iterator p, Args&&... args);\n    iterator insert_after(const_iterator p, const value_type& v);\n    iterator insert_after(const_iterator p, value_type&& v);\n    iterator insert_after(const_iterator p, size_type n, const value_type& v);\n    template <class InputIterator>\n        iterator insert_after(const_iterator p,\n                              InputIterator first, InputIterator last);\n    iterator insert_after(const_iterator p, initializer_list<value_type> il);\n\n    iterator erase_after(const_iterator p);\n    iterator erase_after(const_iterator first, const_iterator last);\n\n    void swap(forward_list& x)\n        noexcept(allocator_traits<allocator_type>::is_always_equal::value);  // C++17\n\n    void resize(size_type n);\n    void resize(size_type n, const value_type& v);\n    void clear() noexcept;\n\n    void splice_after(const_iterator p, forward_list& x);\n    void splice_after(const_iterator p, forward_list&& x);\n    void splice_after(const_iterator p, forward_list& x, const_iterator i);\n    void splice_after(const_iterator p, forward_list&& x, const_iterator i);\n    void splice_after(const_iterator p, forward_list& x,\n                      const_iterator first, const_iterator last);\n    void splice_after(const_iterator p, forward_list&& x,\n                      const_iterator first, const_iterator last);\n    void remove(const value_type& v);\n    template <class Predicate> void remove_if(Predicate pred);\n    void unique();\n    template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);\n    void merge(forward_list& x);\n    void merge(forward_list&& x);\n    template <class Compare> void merge(forward_list& x, Compare comp);\n    template <class Compare> void merge(forward_list&& x, Compare comp);\n    void sort();\n    template <class Compare> void sort(Compare comp);\n    void reverse() noexcept;\n};\n\ntemplate <class T, class Allocator>\n    bool operator==(const forward_list<T, Allocator>& x,\n                    const forward_list<T, Allocator>& y);\n\ntemplate <class T, class Allocator>\n    bool operator< (const forward_list<T, Allocator>& x,\n                    const forward_list<T, Allocator>& y);\n\ntemplate <class T, class Allocator>\n    bool operator!=(const forward_list<T, Allocator>& x,\n                    const forward_list<T, Allocator>& y);\n\ntemplate <class T, class Allocator>\n    bool operator> (const forward_list<T, Allocator>& x,\n                    const forward_list<T, Allocator>& y);\n\ntemplate <class T, class Allocator>\n    bool operator>=(const forward_list<T, Allocator>& x,\n                    const forward_list<T, Allocator>& y);\n\ntemplate <class T, class Allocator>\n    bool operator<=(const forward_list<T, Allocator>& x,\n                    const forward_list<T, Allocator>& y);\n\ntemplate <class T, class Allocator>\n    void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)\n         noexcept(noexcept(x.swap(y)));\n\n}  // std\n\n*/\n\n#include <__config>\n\n#include <initializer_list>\n#include <memory>\n#include <limits>\n#include <iterator>\n#include <algorithm>\n\n#include <__undef_min_max>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Tp, class _VoidPtr> struct __forward_list_node;\n\ntemplate <class _NodePtr>\nstruct __forward_begin_node\n{\n    typedef _NodePtr pointer;\n\n    pointer __next_;\n\n     _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}\n};\n\ntemplate <class _Tp, class _VoidPtr>\nstruct _LIBCPP_HIDDEN __begin_node_of\n{\n    typedef __forward_begin_node\n        <\n             typename pointer_traits<_VoidPtr>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n                 rebind<__forward_list_node<_Tp, _VoidPtr> >\n#else\n                 rebind<__forward_list_node<_Tp, _VoidPtr> >::other\n#endif\n         > type;\n};\n\ntemplate <class _Tp, class _VoidPtr>\nstruct __forward_list_node\n    : public __begin_node_of<_Tp, _VoidPtr>::type\n{\n    typedef _Tp value_type;\n\n    value_type __value_;\n};\n\ntemplate <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TYPE_VIS_ONLY forward_list;\ntemplate<class _NodeConstPtr> class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator;\n\ntemplate <class _NodePtr>\nclass _LIBCPP_TYPE_VIS_ONLY __forward_list_iterator\n{\n    typedef _NodePtr __node_pointer;\n\n    __node_pointer __ptr_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}\n\n    template<class, class> friend class _LIBCPP_TYPE_VIS_ONLY forward_list;\n    template<class> friend class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator;\n\npublic:\n    typedef forward_iterator_tag                              iterator_category;\n    typedef typename pointer_traits<__node_pointer>::element_type::value_type\n                                                              value_type;\n    typedef value_type&                                       reference;\n    typedef typename pointer_traits<__node_pointer>::difference_type\n                                                              difference_type;\n    typedef typename pointer_traits<__node_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<value_type>\n#else\n            rebind<value_type>::other\n#endif\n                                                              pointer;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    reference operator*() const {return __ptr_->__value_;}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __forward_list_iterator& operator++()\n    {\n        __ptr_ = __ptr_->__next_;\n        return *this;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    __forward_list_iterator operator++(int)\n    {\n        __forward_list_iterator __t(*this);\n        ++(*this);\n        return __t;\n    }\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const __forward_list_iterator& __x,\n                    const __forward_list_iterator& __y)\n        {return __x.__ptr_ == __y.__ptr_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const __forward_list_iterator& __x,\n                    const __forward_list_iterator& __y)\n        {return !(__x == __y);}\n};\n\ntemplate <class _NodeConstPtr>\nclass _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator\n{\n    typedef _NodeConstPtr __node_const_pointer;\n\n    __node_const_pointer __ptr_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __forward_list_const_iterator(__node_const_pointer __p) _NOEXCEPT\n        : __ptr_(__p) {}\n\n    typedef typename remove_const\n        <\n            typename pointer_traits<__node_const_pointer>::element_type\n        >::type                                               __node;\n    typedef typename pointer_traits<__node_const_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<__node>\n#else\n            rebind<__node>::other\n#endif\n                                                              __node_pointer;\n\n    template<class, class> friend class forward_list;\n\npublic:\n    typedef forward_iterator_tag                              iterator_category;\n    typedef typename __node::value_type                       value_type;\n    typedef const value_type&                                 reference;\n    typedef typename pointer_traits<__node_const_pointer>::difference_type\n                                                              difference_type;\n    typedef typename pointer_traits<__node_const_pointer>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<const value_type>\n#else\n            rebind<const value_type>::other\n#endif\n                                                              pointer;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}\n    _LIBCPP_INLINE_VISIBILITY\n    __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT\n        : __ptr_(__p.__ptr_) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    reference operator*() const {return __ptr_->__value_;}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __forward_list_const_iterator& operator++()\n    {\n        __ptr_ = __ptr_->__next_;\n        return *this;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    __forward_list_const_iterator operator++(int)\n    {\n        __forward_list_const_iterator __t(*this);\n        ++(*this);\n        return __t;\n    }\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const __forward_list_const_iterator& __x,\n                    const __forward_list_const_iterator& __y)\n        {return __x.__ptr_ == __y.__ptr_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const __forward_list_const_iterator& __x,\n                           const __forward_list_const_iterator& __y)\n        {return !(__x == __y);}\n};\n\ntemplate <class _Tp, class _Alloc>\nclass __forward_list_base\n{\nprotected:\n    typedef _Tp    value_type;\n    typedef _Alloc allocator_type;\n\n    typedef typename allocator_traits<allocator_type>::void_pointer  void_pointer;\n    typedef __forward_list_node<value_type, void_pointer>            __node;\n    typedef typename __begin_node_of<value_type, void_pointer>::type __begin_node;\n    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __node>::type __node_allocator;\n    typedef allocator_traits<__node_allocator>        __node_traits;\n    typedef typename __node_traits::pointer           __node_pointer;\n    typedef typename __node_traits::pointer           __node_const_pointer;\n\n    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __begin_node>::type __begin_node_allocator;\n    typedef typename allocator_traits<__begin_node_allocator>::pointer __begin_node_pointer;\n\n    __compressed_pair<__begin_node, __node_allocator> __before_begin_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __node_pointer        __before_begin() _NOEXCEPT\n        {return static_cast<__node_pointer>(pointer_traits<__begin_node_pointer>::\n                                        pointer_to(__before_begin_.first()));}\n    _LIBCPP_INLINE_VISIBILITY\n    __node_const_pointer  __before_begin() const _NOEXCEPT\n        {return static_cast<__node_const_pointer>(pointer_traits<__begin_node_pointer>::\n                                        pointer_to(const_cast<__begin_node&>(__before_begin_.first())));}\n\n    _LIBCPP_INLINE_VISIBILITY\n          __node_allocator& __alloc() _NOEXCEPT\n            {return __before_begin_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n    const __node_allocator& __alloc() const _NOEXCEPT\n        {return __before_begin_.second();}\n\n    typedef __forward_list_iterator<__node_pointer>             iterator;\n    typedef __forward_list_const_iterator<__node_pointer>       const_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __forward_list_base()\n        _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)\n        : __before_begin_(__begin_node()) {}\n    _LIBCPP_INLINE_VISIBILITY\n    __forward_list_base(const allocator_type& __a)\n        : __before_begin_(__begin_node(), __node_allocator(__a)) {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\npublic:\n    __forward_list_base(__forward_list_base&& __x)\n        _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);\n    __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\nprivate:\n    __forward_list_base(const __forward_list_base&);\n    __forward_list_base& operator=(const __forward_list_base&);\n\npublic:\n    ~__forward_list_base();\n\nprotected:\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const __forward_list_base& __x)\n        {__copy_assign_alloc(__x, integral_constant<bool,\n              __node_traits::propagate_on_container_copy_assignment::value>());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__forward_list_base& __x)\n        _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||\n                   is_nothrow_move_assignable<__node_allocator>::value)\n        {__move_assign_alloc(__x, integral_constant<bool,\n              __node_traits::propagate_on_container_move_assignment::value>());}\n\npublic:\n    void swap(__forward_list_base& __x)\n#if _LIBCPP_STD_VER >= 14\n        _NOEXCEPT;\n#else\n        _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value || \n                    __is_nothrow_swappable<__node_allocator>::value);\n#endif\nprotected:\n    void clear() _NOEXCEPT;\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const __forward_list_base&, false_type) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const __forward_list_base& __x, true_type)\n    {\n        if (__alloc() != __x.__alloc())\n            clear();\n        __alloc() = __x.__alloc();\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__forward_list_base& __x, false_type) _NOEXCEPT\n        {}\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__forward_list_base& __x, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)\n        {__alloc() = _VSTD::move(__x.__alloc());}\n};\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\n__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)\n        _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)\n    : __before_begin_(_VSTD::move(__x.__before_begin_))\n{\n    __x.__before_begin()->__next_ = nullptr;\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\n__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,\n                                                      const allocator_type& __a)\n    : __before_begin_(__begin_node(), __node_allocator(__a))\n{\n    if (__alloc() == __x.__alloc())\n    {\n        __before_begin()->__next_ = __x.__before_begin()->__next_;\n        __x.__before_begin()->__next_ = nullptr;\n    }\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Alloc>\n__forward_list_base<_Tp, _Alloc>::~__forward_list_base()\n{\n    clear();\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)\n#if _LIBCPP_STD_VER >= 14\n        _NOEXCEPT\n#else\n        _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value || \n                    __is_nothrow_swappable<__node_allocator>::value)\n#endif\n{\n    __swap_allocator(__alloc(), __x.__alloc(), \n            integral_constant<bool, __node_traits::propagate_on_container_swap::value>());\n    using _VSTD::swap;\n    swap(__before_begin()->__next_, __x.__before_begin()->__next_);\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\n__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT\n{\n    __node_allocator& __a = __alloc();\n    for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)\n    {\n        __node_pointer __next = __p->__next_;\n        __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));\n        __node_traits::deallocate(__a, __p, 1);\n        __p = __next;\n    }\n    __before_begin()->__next_ = nullptr;\n}\n\ntemplate <class _Tp, class _Alloc /*= allocator<_Tp>*/>\nclass _LIBCPP_TYPE_VIS_ONLY forward_list\n    : private __forward_list_base<_Tp, _Alloc>\n{\n    typedef __forward_list_base<_Tp, _Alloc> base;\n    typedef typename base::__node_allocator  __node_allocator;\n    typedef typename base::__node            __node;\n    typedef typename base::__node_traits     __node_traits;\n    typedef typename base::__node_pointer    __node_pointer;\n\npublic:\n    typedef _Tp    value_type;\n    typedef _Alloc allocator_type;\n\n    typedef value_type&                                                reference;\n    typedef const value_type&                                          const_reference;\n    typedef typename allocator_traits<allocator_type>::pointer         pointer;\n    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;\n    typedef typename allocator_traits<allocator_type>::size_type       size_type;\n    typedef typename allocator_traits<allocator_type>::difference_type difference_type;\n\n    typedef typename base::iterator       iterator;\n    typedef typename base::const_iterator const_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY\n    forward_list()\n        _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)\n        {} // = default;\n    explicit forward_list(const allocator_type& __a);\n    explicit forward_list(size_type __n);\n#if _LIBCPP_STD_VER > 11\n    explicit forward_list(size_type __n, const allocator_type& __a);\n#endif\n    forward_list(size_type __n, const value_type& __v);\n    forward_list(size_type __n, const value_type& __v, const allocator_type& __a);\n    template <class _InputIterator>\n        forward_list(_InputIterator __f, _InputIterator __l,\n                     typename enable_if<\n                       __is_input_iterator<_InputIterator>::value\n                     >::type* = nullptr);\n    template <class _InputIterator>\n        forward_list(_InputIterator __f, _InputIterator __l,\n                     const allocator_type& __a,\n                     typename enable_if<\n                       __is_input_iterator<_InputIterator>::value\n                     >::type* = nullptr);\n    forward_list(const forward_list& __x);\n    forward_list(const forward_list& __x, const allocator_type& __a);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    forward_list(forward_list&& __x)\n        _NOEXCEPT_(is_nothrow_move_constructible<base>::value)\n        : base(_VSTD::move(__x)) {}\n    forward_list(forward_list&& __x, const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    forward_list(initializer_list<value_type> __il);\n    forward_list(initializer_list<value_type> __il, const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    // ~forward_list() = default;\n\n    forward_list& operator=(const forward_list& __x);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    forward_list& operator=(forward_list&& __x)\n        _NOEXCEPT_(\n             __node_traits::propagate_on_container_move_assignment::value &&\n             is_nothrow_move_assignable<allocator_type>::value);\n#endif\n#ifndef  _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    forward_list& operator=(initializer_list<value_type> __il);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    template <class _InputIterator>\n        typename enable_if\n        <\n            __is_input_iterator<_InputIterator>::value,\n            void\n        >::type\n        assign(_InputIterator __f, _InputIterator __l);\n    void assign(size_type __n, const value_type& __v);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    void assign(initializer_list<value_type> __il);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const _NOEXCEPT\n        {return allocator_type(base::__alloc());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       begin() _NOEXCEPT\n        {return       iterator(base::__before_begin()->__next_);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin() const _NOEXCEPT\n        {return const_iterator(base::__before_begin()->__next_);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       end() _NOEXCEPT\n        {return       iterator(nullptr);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end() const _NOEXCEPT\n        {return const_iterator(nullptr);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cbegin() const _NOEXCEPT\n        {return const_iterator(base::__before_begin()->__next_);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cend() const _NOEXCEPT\n        {return const_iterator(nullptr);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       before_begin() _NOEXCEPT\n        {return       iterator(base::__before_begin());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator before_begin() const _NOEXCEPT\n        {return const_iterator(base::__before_begin());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cbefore_begin() const _NOEXCEPT\n        {return const_iterator(base::__before_begin());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool empty() const _NOEXCEPT\n        {return base::__before_begin()->__next_ == nullptr;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const _NOEXCEPT\n        {return numeric_limits<size_type>::max();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    reference       front()       {return base::__before_begin()->__next_->__value_;}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reference front() const {return base::__before_begin()->__next_->__value_;}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class... _Args> void emplace_front(_Args&&... __args);\n#endif\n    void push_front(value_type&& __v);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void push_front(const value_type& __v);\n\n    void pop_front();\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class... _Args>\n        iterator emplace_after(const_iterator __p, _Args&&... __args);\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n    iterator insert_after(const_iterator __p, value_type&& __v);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    iterator insert_after(const_iterator __p, const value_type& __v);\n    iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);\n    template <class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        typename enable_if\n        <\n            __is_input_iterator<_InputIterator>::value,\n            iterator\n        >::type\n        insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    iterator insert_after(const_iterator __p, initializer_list<value_type> __il)\n        {return insert_after(__p, __il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    iterator erase_after(const_iterator __p);\n    iterator erase_after(const_iterator __f, const_iterator __l);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(forward_list& __x)\n#if _LIBCPP_STD_VER >= 14\n        _NOEXCEPT\n#else\n        _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||\n                   __is_nothrow_swappable<__node_allocator>::value)\n#endif\n        {base::swap(__x);}\n\n    void resize(size_type __n);\n    void resize(size_type __n, const value_type& __v);\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() _NOEXCEPT {base::clear();}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void splice_after(const_iterator __p, forward_list&& __x);\n    _LIBCPP_INLINE_VISIBILITY\n    void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);\n    _LIBCPP_INLINE_VISIBILITY\n    void splice_after(const_iterator __p, forward_list&& __x,\n                      const_iterator __f, const_iterator __l);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void splice_after(const_iterator __p, forward_list& __x);\n    void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);\n    void splice_after(const_iterator __p, forward_list& __x,\n                      const_iterator __f, const_iterator __l);\n    void remove(const value_type& __v);\n    template <class _Predicate> void remove_if(_Predicate __pred);\n    _LIBCPP_INLINE_VISIBILITY\n    void unique() {unique(__equal_to<value_type>());}\n    template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void merge(forward_list&& __x) {merge(__x, __less<value_type>());}\n    template <class _Compare>\n        _LIBCPP_INLINE_VISIBILITY\n        void merge(forward_list&& __x, _Compare __comp)\n        {merge(__x, _VSTD::move(__comp));}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void merge(forward_list& __x) {merge(__x, __less<value_type>());}\n    template <class _Compare> void merge(forward_list& __x, _Compare __comp);\n    _LIBCPP_INLINE_VISIBILITY\n    void sort() {sort(__less<value_type>());}\n    template <class _Compare> void sort(_Compare __comp);\n    void reverse() _NOEXCEPT;\n\nprivate:\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void __move_assign(forward_list& __x, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);\n    void __move_assign(forward_list& __x, false_type);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    template <class _Compare>\n        static\n        __node_pointer\n        __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);\n\n    template <class _Compare>\n        static\n        __node_pointer\n        __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);\n};\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nforward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)\n    : base(__a)\n{\n}\n\ntemplate <class _Tp, class _Alloc>\nforward_list<_Tp, _Alloc>::forward_list(size_type __n)\n{\n    if (__n > 0)\n    {\n        __node_allocator& __a = base::__alloc();\n        typedef __allocator_destructor<__node_allocator> _Dp;\n        unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));\n        for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,\n                                                             __p = __p->__next_)\n        {\n            __h.reset(__node_traits::allocate(__a, 1));\n            __node_traits::construct(__a, _VSTD::addressof(__h->__value_));\n            __h->__next_ = nullptr;\n            __p->__next_ = __h.release();\n        }\n    }\n}\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp, class _Alloc>\nforward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __a)\n    : base ( __a )\n{\n    if (__n > 0)\n    {\n        __node_allocator& __a = base::__alloc();\n        typedef __allocator_destructor<__node_allocator> _Dp;\n        unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));\n        for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,\n                                                             __p = __p->__next_)\n        {\n            __h.reset(__node_traits::allocate(__a, 1));\n            __node_traits::construct(__a, _VSTD::addressof(__h->__value_));\n            __h->__next_ = nullptr;\n            __p->__next_ = __h.release();\n        }\n    }\n}\n#endif\n\ntemplate <class _Tp, class _Alloc>\nforward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)\n{\n    insert_after(cbefore_begin(), __n, __v);\n}\n\ntemplate <class _Tp, class _Alloc>\nforward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,\n                                        const allocator_type& __a)\n    : base(__a)\n{\n    insert_after(cbefore_begin(), __n, __v);\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _InputIterator>\nforward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,\n                                        typename enable_if<\n                                          __is_input_iterator<_InputIterator>::value\n                                        >::type*)\n{\n    insert_after(cbefore_begin(), __f, __l);\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _InputIterator>\nforward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,\n                                        const allocator_type& __a,\n                                        typename enable_if<\n                                          __is_input_iterator<_InputIterator>::value\n                                        >::type*)\n    : base(__a)\n{\n    insert_after(cbefore_begin(), __f, __l);\n}\n\ntemplate <class _Tp, class _Alloc>\nforward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)\n    : base(allocator_type(\n             __node_traits::select_on_container_copy_construction(__x.__alloc())\n                         )\n          )\n{\n    insert_after(cbefore_begin(), __x.begin(), __x.end());\n}\n\ntemplate <class _Tp, class _Alloc>\nforward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,\n                                        const allocator_type& __a)\n    : base(__a)\n{\n    insert_after(cbefore_begin(), __x.begin(), __x.end());\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Alloc>\nforward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,\n                                        const allocator_type& __a)\n    : base(_VSTD::move(__x), __a)\n{\n    if (base::__alloc() != __x.__alloc())\n    {\n        typedef move_iterator<iterator> _Ip;\n        insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end()));\n    }\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp, class _Alloc>\nforward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)\n{\n    insert_after(cbefore_begin(), __il.begin(), __il.end());\n}\n\ntemplate <class _Tp, class _Alloc>\nforward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,\n                                        const allocator_type& __a)\n    : base(__a)\n{\n    insert_after(cbefore_begin(), __il.begin(), __il.end());\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp, class _Alloc>\nforward_list<_Tp, _Alloc>&\nforward_list<_Tp, _Alloc>::operator=(const forward_list& __x)\n{\n    if (this != &__x)\n    {\n        base::__copy_assign_alloc(__x);\n        assign(__x.begin(), __x.end());\n    }\n    return *this;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Alloc>\nvoid\nforward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)\n    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)\n{\n    clear();\n    base::__move_assign_alloc(__x);\n    base::__before_begin()->__next_ = __x.__before_begin()->__next_;\n    __x.__before_begin()->__next_ = nullptr;\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nforward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)\n{\n    if (base::__alloc() == __x.__alloc())\n        __move_assign(__x, true_type());\n    else\n    {\n        typedef move_iterator<iterator> _Ip;\n        assign(_Ip(__x.begin()), _Ip(__x.end()));\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nforward_list<_Tp, _Alloc>&\nforward_list<_Tp, _Alloc>::operator=(forward_list&& __x)\n    _NOEXCEPT_(\n             __node_traits::propagate_on_container_move_assignment::value &&\n             is_nothrow_move_assignable<allocator_type>::value)\n{\n    __move_assign(__x, integral_constant<bool,\n          __node_traits::propagate_on_container_move_assignment::value>());\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nforward_list<_Tp, _Alloc>&\nforward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)\n{\n    assign(__il.begin(), __il.end());\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _InputIterator>\ntypename enable_if\n<\n    __is_input_iterator<_InputIterator>::value,\n    void\n>::type\nforward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)\n{\n    iterator __i = before_begin();\n    iterator __j = _VSTD::next(__i);\n    iterator __e = end();\n    for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f)\n        *__j = *__f;\n    if (__j == __e)\n        insert_after(__i, __f, __l);\n    else\n        erase_after(__i, __e);\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nforward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)\n{\n    iterator __i = before_begin();\n    iterator __j = _VSTD::next(__i);\n    iterator __e = end();\n    for (; __j != __e && __n > 0; --__n, ++__i, ++__j)\n        *__j = __v;\n    if (__j == __e)\n        insert_after(__i, __n, __v);\n    else\n        erase_after(__i, __e);\n}\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nforward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)\n{\n    assign(__il.begin(), __il.end());\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class... _Args>\nvoid\nforward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)\n{\n    __node_allocator& __a = base::__alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));\n    __node_traits::construct(__a, _VSTD::addressof(__h->__value_),\n                                  _VSTD::forward<_Args>(__args)...);\n    __h->__next_ = base::__before_begin()->__next_;\n    base::__before_begin()->__next_ = __h.release();\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Alloc>\nvoid\nforward_list<_Tp, _Alloc>::push_front(value_type&& __v)\n{\n    __node_allocator& __a = base::__alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));\n    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));\n    __h->__next_ = base::__before_begin()->__next_;\n    base::__before_begin()->__next_ = __h.release();\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Alloc>\nvoid\nforward_list<_Tp, _Alloc>::push_front(const value_type& __v)\n{\n    __node_allocator& __a = base::__alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));\n    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);\n    __h->__next_ = base::__before_begin()->__next_;\n    base::__before_begin()->__next_ = __h.release();\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nforward_list<_Tp, _Alloc>::pop_front()\n{\n    __node_allocator& __a = base::__alloc();\n    __node_pointer __p = base::__before_begin()->__next_;\n    base::__before_begin()->__next_ = __p->__next_;\n    __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));\n    __node_traits::deallocate(__a, __p, 1);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class... _Args>\ntypename forward_list<_Tp, _Alloc>::iterator\nforward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)\n{\n    __node_pointer const __r = __p.__ptr_;\n    __node_allocator& __a = base::__alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));\n    __node_traits::construct(__a, _VSTD::addressof(__h->__value_),\n                                  _VSTD::forward<_Args>(__args)...);\n    __h->__next_ = __r->__next_;\n    __r->__next_ = __h.release();\n    return iterator(__r->__next_);\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Alloc>\ntypename forward_list<_Tp, _Alloc>::iterator\nforward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)\n{\n    __node_pointer const __r = __p.__ptr_;\n    __node_allocator& __a = base::__alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));\n    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));\n    __h->__next_ = __r->__next_;\n    __r->__next_ = __h.release();\n    return iterator(__r->__next_);\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Alloc>\ntypename forward_list<_Tp, _Alloc>::iterator\nforward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)\n{\n    __node_pointer const __r = __p.__ptr_;\n    __node_allocator& __a = base::__alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));\n    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);\n    __h->__next_ = __r->__next_;\n    __r->__next_ = __h.release();\n    return iterator(__r->__next_);\n}\n\ntemplate <class _Tp, class _Alloc>\ntypename forward_list<_Tp, _Alloc>::iterator\nforward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,\n                                        const value_type& __v)\n{\n    __node_pointer __r = __p.__ptr_;\n    if (__n > 0)\n    {\n        __node_allocator& __a = base::__alloc();\n        typedef __allocator_destructor<__node_allocator> _Dp;\n        unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));\n        __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);\n        __node_pointer __first = __h.release();\n        __node_pointer __last = __first;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (--__n; __n != 0; --__n, __last = __last->__next_)\n            {\n                __h.reset(__node_traits::allocate(__a, 1));\n                __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);\n                __last->__next_ = __h.release();\n            }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            while (__first != nullptr)\n            {\n                __node_pointer __next = __first->__next_;\n                __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));\n                __node_traits::deallocate(__a, __first, 1);\n                __first = __next;\n            }\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        __last->__next_ = __r->__next_;\n        __r->__next_ = __first;\n        __r = __last;\n    }\n    return iterator(__r);\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _InputIterator>\ntypename enable_if\n<\n    __is_input_iterator<_InputIterator>::value,\n    typename forward_list<_Tp, _Alloc>::iterator\n>::type\nforward_list<_Tp, _Alloc>::insert_after(const_iterator __p,\n                                        _InputIterator __f, _InputIterator __l)\n{\n    __node_pointer __r = __p.__ptr_;\n    if (__f != __l)\n    {\n        __node_allocator& __a = base::__alloc();\n        typedef __allocator_destructor<__node_allocator> _Dp;\n        unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));\n        __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);\n        __node_pointer __first = __h.release();\n        __node_pointer __last = __first;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_)))\n            {\n                __h.reset(__node_traits::allocate(__a, 1));\n                __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);\n                __last->__next_ = __h.release();\n            }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            while (__first != nullptr)\n            {\n                __node_pointer __next = __first->__next_;\n                __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));\n                __node_traits::deallocate(__a, __first, 1);\n                __first = __next;\n            }\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        __last->__next_ = __r->__next_;\n        __r->__next_ = __first;\n        __r = __last;\n    }\n    return iterator(__r);\n}\n\ntemplate <class _Tp, class _Alloc>\ntypename forward_list<_Tp, _Alloc>::iterator\nforward_list<_Tp, _Alloc>::erase_after(const_iterator __f)\n{\n    __node_pointer __p = __f.__ptr_;\n    __node_pointer __n = __p->__next_;\n    __p->__next_ = __n->__next_;\n    __node_allocator& __a = base::__alloc();\n    __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));\n    __node_traits::deallocate(__a, __n, 1);\n    return iterator(__p->__next_);\n}\n\ntemplate <class _Tp, class _Alloc>\ntypename forward_list<_Tp, _Alloc>::iterator\nforward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)\n{\n    __node_pointer __e = __l.__ptr_;\n    if (__f != __l)\n    {\n        __node_pointer __p = __f.__ptr_;\n        __node_pointer __n = __p->__next_;\n        if (__n != __e)\n        {\n            __p->__next_ = __e;\n            __node_allocator& __a = base::__alloc();\n            do\n            {\n                __p = __n->__next_;\n                __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));\n                __node_traits::deallocate(__a, __n, 1);\n                __n = __p;\n            } while (__n != __e);\n        }\n    }\n    return iterator(__e);\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nforward_list<_Tp, _Alloc>::resize(size_type __n)\n{\n    size_type __sz = 0;\n    iterator __p = before_begin();\n    iterator __i = begin();\n    iterator __e = end();\n    for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)\n        ;\n    if (__i != __e)\n        erase_after(__p, __e);\n    else\n    {\n        __n -= __sz;\n        if (__n > 0)\n        {\n            __node_allocator& __a = base::__alloc();\n            typedef __allocator_destructor<__node_allocator> _Dp;\n            unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));\n            for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,\n                                                         __ptr = __ptr->__next_)\n            {\n                __h.reset(__node_traits::allocate(__a, 1));\n                __node_traits::construct(__a, _VSTD::addressof(__h->__value_));\n                __h->__next_ = nullptr;\n                __ptr->__next_ = __h.release();\n            }\n        }\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nforward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)\n{\n    size_type __sz = 0;\n    iterator __p = before_begin();\n    iterator __i = begin();\n    iterator __e = end();\n    for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)\n        ;\n    if (__i != __e)\n        erase_after(__p, __e);\n    else\n    {\n        __n -= __sz;\n        if (__n > 0)\n        {\n            __node_allocator& __a = base::__alloc();\n            typedef __allocator_destructor<__node_allocator> _Dp;\n            unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));\n            for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,\n                                                         __ptr = __ptr->__next_)\n            {\n                __h.reset(__node_traits::allocate(__a, 1));\n                __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);\n                __h->__next_ = nullptr;\n                __ptr->__next_ = __h.release();\n            }\n        }\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nforward_list<_Tp, _Alloc>::splice_after(const_iterator __p,\n                                        forward_list& __x)\n{\n    if (!__x.empty())\n    {\n        if (__p.__ptr_->__next_ != nullptr)\n        {\n            const_iterator __lm1 = __x.before_begin();\n            while (__lm1.__ptr_->__next_ != nullptr)\n                ++__lm1;\n            __lm1.__ptr_->__next_ = __p.__ptr_->__next_;\n        }\n        __p.__ptr_->__next_ = __x.__before_begin()->__next_;\n        __x.__before_begin()->__next_ = nullptr;\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nforward_list<_Tp, _Alloc>::splice_after(const_iterator __p,\n                                        forward_list& __x,\n                                        const_iterator __i)\n{\n    const_iterator __lm1 = _VSTD::next(__i);\n    if (__p != __i && __p != __lm1)\n    {\n        __i.__ptr_->__next_ = __lm1.__ptr_->__next_;\n        __lm1.__ptr_->__next_ = __p.__ptr_->__next_;\n        __p.__ptr_->__next_ = __lm1.__ptr_;\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nforward_list<_Tp, _Alloc>::splice_after(const_iterator __p,\n                                        forward_list& __x,\n                                        const_iterator __f, const_iterator __l)\n{\n    if (__f != __l && __p != __f)\n    {\n        const_iterator __lm1 = __f;\n        while (__lm1.__ptr_->__next_ != __l.__ptr_)\n            ++__lm1;\n        if (__f != __lm1)\n        {\n            __lm1.__ptr_->__next_ = __p.__ptr_->__next_;\n            __p.__ptr_->__next_ = __f.__ptr_->__next_;\n            __f.__ptr_->__next_ = __l.__ptr_;\n        }\n    }\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nforward_list<_Tp, _Alloc>::splice_after(const_iterator __p,\n                                        forward_list&& __x)\n{\n    splice_after(__p, __x);\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nforward_list<_Tp, _Alloc>::splice_after(const_iterator __p,\n                                        forward_list&& __x,\n                                        const_iterator __i)\n{\n    splice_after(__p, __x, __i);\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nforward_list<_Tp, _Alloc>::splice_after(const_iterator __p,\n                                        forward_list&& __x,\n                                        const_iterator __f, const_iterator __l)\n{\n    splice_after(__p, __x, __f, __l);\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Alloc>\nvoid\nforward_list<_Tp, _Alloc>::remove(const value_type& __v)\n{\n    forward_list<_Tp, _Alloc> __deleted_nodes; // collect the nodes we're removing\n    iterator __e = end();\n    for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)\n    {\n        if (__i.__ptr_->__next_->__value_ == __v)\n        {\n            iterator __j = _VSTD::next(__i, 2);\n            for (; __j != __e && *__j == __v; ++__j)\n                ;\n            __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);\n            if (__j == __e)\n                break;\n            __i = __j;\n        }\n        else\n            ++__i;\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _Predicate>\nvoid\nforward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)\n{\n    iterator __e = end();\n    for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)\n    {\n        if (__pred(__i.__ptr_->__next_->__value_))\n        {\n            iterator __j = _VSTD::next(__i, 2);\n            for (; __j != __e && __pred(*__j); ++__j)\n                ;\n            erase_after(__i, __j);\n            if (__j == __e)\n                break;\n            __i = __j;\n        }\n        else\n            ++__i;\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _BinaryPredicate>\nvoid\nforward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)\n{\n    for (iterator __i = begin(), __e = end(); __i != __e;)\n    {\n        iterator __j = _VSTD::next(__i);\n        for (; __j != __e && __binary_pred(*__i, *__j); ++__j)\n            ;\n        if (__i.__ptr_->__next_ != __j.__ptr_)\n            erase_after(__i, __j);\n        __i = __j;\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _Compare>\nvoid\nforward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)\n{\n    if (this != &__x)\n    {\n        base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,\n                                                    __x.__before_begin()->__next_,\n                                                    __comp);\n        __x.__before_begin()->__next_ = nullptr;\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _Compare>\ntypename forward_list<_Tp, _Alloc>::__node_pointer\nforward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,\n                                   _Compare& __comp)\n{\n    if (__f1 == nullptr)\n        return __f2;\n    if (__f2 == nullptr)\n        return __f1;\n    __node_pointer __r;\n    if (__comp(__f2->__value_, __f1->__value_))\n    {\n        __node_pointer __t = __f2;\n        while (__t->__next_ != nullptr &&\n                             __comp(__t->__next_->__value_, __f1->__value_))\n            __t = __t->__next_;\n        __r = __f2;\n        __f2 = __t->__next_;\n        __t->__next_ = __f1;\n    }\n    else\n        __r = __f1;\n    __node_pointer __p = __f1;\n    __f1 = __f1->__next_;\n    while (__f1 != nullptr && __f2 != nullptr)\n    {\n        if (__comp(__f2->__value_, __f1->__value_))\n        {\n            __node_pointer __t = __f2;\n            while (__t->__next_ != nullptr &&\n                                 __comp(__t->__next_->__value_, __f1->__value_))\n                __t = __t->__next_;\n            __p->__next_ = __f2;\n            __f2 = __t->__next_;\n            __t->__next_ = __f1;\n        }\n        __p = __f1;\n        __f1 = __f1->__next_;\n    }\n    if (__f2 != nullptr)\n        __p->__next_ = __f2;\n    return __r;\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nforward_list<_Tp, _Alloc>::sort(_Compare __comp)\n{\n    base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,\n                                       _VSTD::distance(begin(), end()), __comp);\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _Compare>\ntypename forward_list<_Tp, _Alloc>::__node_pointer\nforward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,\n                                  _Compare& __comp)\n{\n    switch (__sz)\n    {\n    case 0:\n    case 1:\n        return __f1;\n    case 2:\n        if (__comp(__f1->__next_->__value_, __f1->__value_))\n        {\n            __node_pointer __t = __f1->__next_;\n            __t->__next_ = __f1;\n            __f1->__next_ = nullptr;\n            __f1 = __t;\n        }\n        return __f1;\n    }\n    difference_type __sz1 = __sz / 2;\n    difference_type __sz2 = __sz - __sz1;\n    __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__ptr_;\n    __node_pointer __f2 = __t->__next_;\n    __t->__next_ = nullptr;\n    return __merge(__sort(__f1, __sz1, __comp),\n                   __sort(__f2, __sz2, __comp), __comp);\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nforward_list<_Tp, _Alloc>::reverse() _NOEXCEPT\n{\n    __node_pointer __p = base::__before_begin()->__next_;\n    if (__p != nullptr)\n    {\n        __node_pointer __f = __p->__next_;\n        __p->__next_ = nullptr;\n        while (__f != nullptr)\n        {\n            __node_pointer __t = __f->__next_;\n            __f->__next_ = __p;\n            __p = __f;\n            __f = __t;\n        }\n        base::__before_begin()->__next_ = __p;\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\nbool operator==(const forward_list<_Tp, _Alloc>& __x,\n                const forward_list<_Tp, _Alloc>& __y)\n{\n    typedef forward_list<_Tp, _Alloc> _Cp;\n    typedef typename _Cp::const_iterator _Ip;\n    _Ip __ix = __x.begin();\n    _Ip __ex = __x.end();\n    _Ip __iy = __y.begin();\n    _Ip __ey = __y.end();\n    for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)\n        if (!(*__ix == *__iy))\n            return false;\n    return (__ix == __ex) == (__iy == __ey);\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool operator!=(const forward_list<_Tp, _Alloc>& __x,\n                const forward_list<_Tp, _Alloc>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool operator< (const forward_list<_Tp, _Alloc>& __x,\n                const forward_list<_Tp, _Alloc>& __y)\n{\n    return _VSTD::lexicographical_compare(__x.begin(), __x.end(),\n                                         __y.begin(), __y.end());\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool operator> (const forward_list<_Tp, _Alloc>& __x,\n                const forward_list<_Tp, _Alloc>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool operator>=(const forward_list<_Tp, _Alloc>& __x,\n                const forward_list<_Tp, _Alloc>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool operator<=(const forward_list<_Tp, _Alloc>& __x,\n                const forward_list<_Tp, _Alloc>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_FORWARD_LIST\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/fstream",
    "content": "// -*- C++ -*-\n//===------------------------- fstream ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_FSTREAM\n#define _LIBCPP_FSTREAM\n\n/*\n    fstream synopsis\n\ntemplate <class charT, class traits = char_traits<charT> >\nclass basic_filebuf\n    : public basic_streambuf<charT, traits>\n{\npublic:\n    typedef charT                          char_type;\n    typedef traits                         traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    // 27.9.1.2 Constructors/destructor:\n    basic_filebuf();\n    basic_filebuf(basic_filebuf&& rhs);\n    virtual ~basic_filebuf();\n\n    // 27.9.1.3 Assign/swap:\n    basic_filebuf& operator=(basic_filebuf&& rhs);\n    void swap(basic_filebuf& rhs);\n\n    // 27.9.1.4 Members:\n    bool is_open() const;\n    basic_filebuf* open(const char* s, ios_base::openmode mode);\n    basic_filebuf* open(const string& s, ios_base::openmode mode);\n    basic_filebuf* close();\n\nprotected:\n    // 27.9.1.5 Overridden virtual functions:\n    virtual streamsize showmanyc();\n    virtual int_type underflow();\n    virtual int_type uflow();\n    virtual int_type pbackfail(int_type c = traits_type::eof());\n    virtual int_type overflow (int_type c = traits_type::eof());\n    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* s, streamsize n);\n    virtual pos_type seekoff(off_type off, ios_base::seekdir way,\n                             ios_base::openmode which = ios_base::in | ios_base::out);\n    virtual pos_type seekpos(pos_type sp,\n                             ios_base::openmode which = ios_base::in | ios_base::out);\n    virtual int sync();\n    virtual void imbue(const locale& loc);\n};\n\ntemplate <class charT, class traits>\n  void\n  swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y);\n\ntypedef basic_filebuf<char>    filebuf;\ntypedef basic_filebuf<wchar_t> wfilebuf;\n\ntemplate <class charT, class traits = char_traits<charT> >\nclass basic_ifstream\n    : public basic_istream<charT,traits>\n{\npublic:\n    typedef charT                          char_type;\n    typedef traits                         traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    basic_ifstream();\n    explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);\n    explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in);\n    basic_ifstream(basic_ifstream&& rhs);\n\n    basic_ifstream& operator=(basic_ifstream&& rhs);\n    void swap(basic_ifstream& rhs);\n\n    basic_filebuf<char_type, traits_type>* rdbuf() const;\n    bool is_open() const;\n    void open(const char* s, ios_base::openmode mode = ios_base::in);\n    void open(const string& s, ios_base::openmode mode = ios_base::in);\n    void close();\n};\n\ntemplate <class charT, class traits>\n  void\n  swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y);\n\ntypedef basic_ifstream<char>    ifstream;\ntypedef basic_ifstream<wchar_t> wifstream;\n\ntemplate <class charT, class traits = char_traits<charT> >\nclass basic_ofstream\n    : public basic_ostream<charT,traits>\n{\npublic:\n    typedef charT                          char_type;\n    typedef traits                         traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    basic_ofstream();\n    explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);\n    explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);\n    basic_ofstream(basic_ofstream&& rhs);\n\n    basic_ofstream& operator=(basic_ofstream&& rhs);\n    void swap(basic_ofstream& rhs);\n\n    basic_filebuf<char_type, traits_type>* rdbuf() const;\n    bool is_open() const;\n    void open(const char* s, ios_base::openmode mode = ios_base::out);\n    void open(const string& s, ios_base::openmode mode = ios_base::out);\n    void close();\n};\n\ntemplate <class charT, class traits>\n  void\n  swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y);\n\ntypedef basic_ofstream<char>    ofstream;\ntypedef basic_ofstream<wchar_t> wofstream;\n\ntemplate <class charT, class traits=char_traits<charT> >\nclass basic_fstream\n    : public basic_iostream<charT,traits>\n{\npublic:\n    typedef charT                          char_type;\n    typedef traits                         traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    basic_fstream();\n    explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);\n    explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);\n    basic_fstream(basic_fstream&& rhs);\n\n    basic_fstream& operator=(basic_fstream&& rhs);\n    void swap(basic_fstream& rhs);\n\n    basic_filebuf<char_type, traits_type>* rdbuf() const;\n    bool is_open() const;\n    void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);\n    void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);\n    void close();\n};\n\ntemplate <class charT, class traits>\n  void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y);\n\ntypedef basic_fstream<char>    fstream;\ntypedef basic_fstream<wchar_t> wfstream;\n\n}  // std\n\n*/\n\n#include <__config>\n#include <ostream>\n#include <istream>\n#include <__locale>\n#include <cstdio>\n\n#include <__undef_min_max>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _CharT, class _Traits>\nclass _LIBCPP_TYPE_VIS_ONLY basic_filebuf\n    : public basic_streambuf<_CharT, _Traits>\n{\npublic:\n    typedef _CharT                           char_type;\n    typedef _Traits                          traits_type;\n    typedef typename traits_type::int_type   int_type;\n    typedef typename traits_type::pos_type   pos_type;\n    typedef typename traits_type::off_type   off_type;\n    typedef typename traits_type::state_type state_type;\n\n    // 27.9.1.2 Constructors/destructor:\n    basic_filebuf();\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    basic_filebuf(basic_filebuf&& __rhs);\n#endif\n    virtual ~basic_filebuf();\n\n    // 27.9.1.3 Assign/swap:\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    basic_filebuf& operator=(basic_filebuf&& __rhs);\n#endif\n    void swap(basic_filebuf& __rhs);\n\n    // 27.9.1.4 Members:\n    bool is_open() const;\n#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\n    basic_filebuf* open(const char* __s, ios_base::openmode __mode);\n    basic_filebuf* open(const string& __s, ios_base::openmode __mode);\n#endif\n    basic_filebuf* close();\n\nprotected:\n    // 27.9.1.5 Overridden virtual functions:\n    virtual int_type underflow();\n    virtual int_type pbackfail(int_type __c = traits_type::eof());\n    virtual int_type overflow (int_type __c = traits_type::eof());\n    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n);\n    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,\n                             ios_base::openmode __wch = ios_base::in | ios_base::out);\n    virtual pos_type seekpos(pos_type __sp,\n                             ios_base::openmode __wch = ios_base::in | ios_base::out);\n    virtual int sync();\n    virtual void imbue(const locale& __loc);\n\nprivate:\n    char*       __extbuf_;\n    const char* __extbufnext_;\n    const char* __extbufend_;\n    char __extbuf_min_[8];\n    size_t __ebs_;\n    char_type* __intbuf_;\n    size_t __ibs_;\n    FILE* __file_;\n    const codecvt<char_type, char, state_type>* __cv_;\n    state_type __st_;\n    state_type __st_last_;\n    ios_base::openmode __om_;\n    ios_base::openmode __cm_;\n    bool __owns_eb_;\n    bool __owns_ib_;\n    bool __always_noconv_;\n\n    bool __read_mode();\n    void __write_mode();\n};\n\ntemplate <class _CharT, class _Traits>\nbasic_filebuf<_CharT, _Traits>::basic_filebuf()\n    : __extbuf_(0),\n      __extbufnext_(0),\n      __extbufend_(0),\n      __ebs_(0),\n      __intbuf_(0),\n      __ibs_(0),\n      __file_(0),\n      __cv_(nullptr),\n      __st_(),\n      __st_last_(),\n      __om_(0),\n      __cm_(0),\n      __owns_eb_(false),\n      __owns_ib_(false),\n      __always_noconv_(false)\n{\n    if (has_facet<codecvt<char_type, char, state_type> >(this->getloc()))\n    {\n        __cv_ = &use_facet<codecvt<char_type, char, state_type> >(this->getloc());\n        __always_noconv_ = __cv_->always_noconv();\n    }\n    setbuf(0, 4096);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\nbasic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs)\n    : basic_streambuf<_CharT, _Traits>(__rhs)\n{\n    if (__rhs.__extbuf_ == __rhs.__extbuf_min_)\n    {\n        __extbuf_ = __extbuf_min_;\n        __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);\n        __extbufend_ = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);\n    }\n    else\n    {\n        __extbuf_ = __rhs.__extbuf_;\n        __extbufnext_ = __rhs.__extbufnext_;\n        __extbufend_ = __rhs.__extbufend_;\n    }\n    __ebs_ = __rhs.__ebs_;\n    __intbuf_ = __rhs.__intbuf_;\n    __ibs_ = __rhs.__ibs_;\n    __file_ = __rhs.__file_;\n    __cv_ = __rhs.__cv_;\n    __st_ = __rhs.__st_;\n    __st_last_ = __rhs.__st_last_;\n    __om_ = __rhs.__om_;\n    __cm_ = __rhs.__cm_;\n    __owns_eb_ = __rhs.__owns_eb_;\n    __owns_ib_ = __rhs.__owns_ib_;\n    __always_noconv_ = __rhs.__always_noconv_;\n    if (__rhs.pbase())\n    {\n        if (__rhs.pbase() == __rhs.__intbuf_)\n            this->setp(__intbuf_, __intbuf_ + (__rhs. epptr() - __rhs.pbase()));\n        else\n            this->setp((char_type*)__extbuf_,\n                       (char_type*)__extbuf_ + (__rhs. epptr() - __rhs.pbase()));\n        this->pbump(__rhs. pptr() - __rhs.pbase());\n    }\n    else if (__rhs.eback())\n    {\n        if (__rhs.eback() == __rhs.__intbuf_)\n            this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()),\n                                  __intbuf_ + (__rhs.egptr() - __rhs.eback()));\n        else\n            this->setg((char_type*)__extbuf_,\n                       (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),\n                       (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));\n    }\n    __rhs.__extbuf_ = 0;\n    __rhs.__extbufnext_ = 0;\n    __rhs.__extbufend_ = 0;\n    __rhs.__ebs_ = 0;\n    __rhs.__intbuf_ = 0;\n    __rhs.__ibs_ = 0;\n    __rhs.__file_ = 0;\n    __rhs.__st_ = state_type();\n    __rhs.__st_last_ = state_type();\n    __rhs.__om_ = 0;\n    __rhs.__cm_ = 0;\n    __rhs.__owns_eb_ = false;\n    __rhs.__owns_ib_ = false;\n    __rhs.setg(0, 0, 0);\n    __rhs.setp(0, 0);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_filebuf<_CharT, _Traits>&\nbasic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs)\n{\n    close();\n    swap(__rhs);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\nbasic_filebuf<_CharT, _Traits>::~basic_filebuf()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        close();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    if (__owns_eb_)\n        delete [] __extbuf_;\n    if (__owns_ib_)\n        delete [] __intbuf_;\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs)\n{\n    basic_streambuf<char_type, traits_type>::swap(__rhs);\n    if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)\n    {\n        _VSTD::swap(__extbuf_, __rhs.__extbuf_);\n        _VSTD::swap(__extbufnext_, __rhs.__extbufnext_);\n        _VSTD::swap(__extbufend_, __rhs.__extbufend_);\n    }\n    else\n    {\n        ptrdiff_t __ln = __extbufnext_ - __extbuf_;\n        ptrdiff_t __le = __extbufend_ - __extbuf_;\n        ptrdiff_t __rn = __rhs.__extbufnext_ - __rhs.__extbuf_;\n        ptrdiff_t __re = __rhs.__extbufend_ - __rhs.__extbuf_;\n        if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)\n        {\n            __extbuf_ = __rhs.__extbuf_;\n            __rhs.__extbuf_ = __rhs.__extbuf_min_;\n        }\n        else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_)\n        {\n            __rhs.__extbuf_ = __extbuf_;\n            __extbuf_ = __extbuf_min_;\n        }\n        __extbufnext_ = __extbuf_ + __rn;\n        __extbufend_ = __extbuf_ + __re;\n        __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;\n        __rhs.__extbufend_ = __rhs.__extbuf_ + __le;\n    }\n    _VSTD::swap(__ebs_, __rhs.__ebs_);\n    _VSTD::swap(__intbuf_, __rhs.__intbuf_);\n    _VSTD::swap(__ibs_, __rhs.__ibs_);\n    _VSTD::swap(__file_, __rhs.__file_);\n    _VSTD::swap(__cv_, __rhs.__cv_);\n    _VSTD::swap(__st_, __rhs.__st_);\n    _VSTD::swap(__st_last_, __rhs.__st_last_);\n    _VSTD::swap(__om_, __rhs.__om_);\n    _VSTD::swap(__cm_, __rhs.__cm_);\n    _VSTD::swap(__owns_eb_, __rhs.__owns_eb_);\n    _VSTD::swap(__owns_ib_, __rhs.__owns_ib_);\n    _VSTD::swap(__always_noconv_, __rhs.__always_noconv_);\n    if (this->eback() == (char_type*)__rhs.__extbuf_min_)\n    {\n        ptrdiff_t __n = this->gptr() - this->eback();\n        ptrdiff_t __e = this->egptr() - this->eback();\n        this->setg((char_type*)__extbuf_min_,\n                   (char_type*)__extbuf_min_ + __n,\n                   (char_type*)__extbuf_min_ + __e);\n    }\n    else if (this->pbase() == (char_type*)__rhs.__extbuf_min_)\n    {\n        ptrdiff_t __n = this->pptr() - this->pbase();\n        ptrdiff_t __e = this->epptr() - this->pbase();\n        this->setp((char_type*)__extbuf_min_,\n                   (char_type*)__extbuf_min_ + __e);\n        this->pbump(__n);\n    }\n    if (__rhs.eback() == (char_type*)__extbuf_min_)\n    {\n        ptrdiff_t __n = __rhs.gptr() - __rhs.eback();\n        ptrdiff_t __e = __rhs.egptr() - __rhs.eback();\n        __rhs.setg((char_type*)__rhs.__extbuf_min_,\n                   (char_type*)__rhs.__extbuf_min_ + __n,\n                   (char_type*)__rhs.__extbuf_min_ + __e);\n    }\n    else if (__rhs.pbase() == (char_type*)__extbuf_min_)\n    {\n        ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();\n        ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();\n        __rhs.setp((char_type*)__rhs.__extbuf_min_,\n                   (char_type*)__rhs.__extbuf_min_ + __e);\n        __rhs.pbump(__n);\n    }\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y)\n{\n    __x.swap(__y);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nbasic_filebuf<_CharT, _Traits>::is_open() const\n{\n    return __file_ != 0;\n}\n\n#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\ntemplate <class _CharT, class _Traits>\nbasic_filebuf<_CharT, _Traits>*\nbasic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)\n{\n    basic_filebuf<_CharT, _Traits>* __rt = 0;\n    if (__file_ == 0)\n    {\n        __rt = this;\n        const char* __mdstr;\n        switch (__mode & ~ios_base::ate)\n        {\n        case ios_base::out:\n        case ios_base::out | ios_base::trunc:\n            __mdstr = \"w\";\n            break;\n        case ios_base::out | ios_base::app:\n        case ios_base::app:\n            __mdstr = \"a\";\n            break;\n        case ios_base::in:\n            __mdstr = \"r\";\n            break;\n        case ios_base::in | ios_base::out:\n            __mdstr = \"r+\";\n            break;\n        case ios_base::in | ios_base::out | ios_base::trunc:\n            __mdstr = \"w+\";\n            break;\n        case ios_base::in | ios_base::out | ios_base::app:\n        case ios_base::in | ios_base::app:\n            __mdstr = \"a+\";\n            break;\n        case ios_base::out | ios_base::binary:\n        case ios_base::out | ios_base::trunc | ios_base::binary:\n            __mdstr = \"wb\";\n            break;\n        case ios_base::out | ios_base::app | ios_base::binary:\n        case ios_base::app | ios_base::binary:\n            __mdstr = \"ab\";\n            break;\n        case ios_base::in | ios_base::binary:\n            __mdstr = \"rb\";\n            break;\n        case ios_base::in | ios_base::out | ios_base::binary:\n            __mdstr = \"r+b\";\n            break;\n        case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:\n            __mdstr = \"w+b\";\n            break;\n        case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:\n        case ios_base::in | ios_base::app | ios_base::binary:\n            __mdstr = \"a+b\";\n            break;\n        default:\n            __rt = 0;\n            break;\n        }\n        if (__rt)\n        {\n            __file_ = fopen(__s, __mdstr);\n            if (__file_)\n            {\n                __om_ = __mode;\n                if (__mode & ios_base::ate)\n                {\n                    if (fseek(__file_, 0, SEEK_END))\n                    {\n                        fclose(__file_);\n                        __file_ = 0;\n                        __rt = 0;\n                    }\n                }\n            }\n            else\n                __rt = 0;\n        }\n    }\n    return __rt;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_filebuf<_CharT, _Traits>*\nbasic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)\n{\n    return open(__s.c_str(), __mode);\n}\n#endif\n\ntemplate <class _CharT, class _Traits>\nbasic_filebuf<_CharT, _Traits>*\nbasic_filebuf<_CharT, _Traits>::close()\n{\n    basic_filebuf<_CharT, _Traits>* __rt = 0;\n    if (__file_)\n    {\n        __rt = this;\n        unique_ptr<FILE, int(*)(FILE*)> __h(__file_, fclose);\n        if (sync())\n            __rt = 0;\n        if (fclose(__h.release()) == 0)\n            __file_ = 0;\n        else\n            __rt = 0;\n    }\n    return __rt;\n}\n\ntemplate <class _CharT, class _Traits>\ntypename basic_filebuf<_CharT, _Traits>::int_type\nbasic_filebuf<_CharT, _Traits>::underflow()\n{\n    if (__file_ == 0)\n        return traits_type::eof();\n    bool __initial = __read_mode();\n    char_type __1buf;\n    if (this->gptr() == 0)\n        this->setg(&__1buf, &__1buf+1, &__1buf+1);\n    const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);\n    int_type __c = traits_type::eof();\n    if (this->gptr() == this->egptr())\n    {\n        memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));\n        if (__always_noconv_)\n        {\n            size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);\n            __nmemb = fread(this->eback() + __unget_sz, 1, __nmemb, __file_);\n            if (__nmemb != 0)\n            {\n                this->setg(this->eback(),\n                           this->eback() + __unget_sz,\n                           this->eback() + __unget_sz + __nmemb);\n                __c = traits_type::to_int_type(*this->gptr());\n            }\n        }\n        else\n        {\n            memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);\n            __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);\n            __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);\n            size_t __nmemb = _VSTD::min(static_cast<size_t>(__ibs_ - __unget_sz),\n                                 static_cast<size_t>(__extbufend_ - __extbufnext_));\n            codecvt_base::result __r;\n            __st_last_ = __st_;\n            size_t __nr = fread((void*)__extbufnext_, 1, __nmemb, __file_);\n            if (__nr != 0)\n            {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n                if (!__cv_)\n                    throw bad_cast();\n#endif\n                __extbufend_ = __extbufnext_ + __nr;\n                char_type*  __inext;\n                __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,\n                                       this->eback() + __unget_sz,\n                                       this->eback() + __ibs_, __inext);\n                if (__r == codecvt_base::noconv)\n                {\n                    this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);\n                    __c = traits_type::to_int_type(*this->gptr());\n                }\n                else if (__inext != this->eback() + __unget_sz)\n                {\n                    this->setg(this->eback(), this->eback() + __unget_sz, __inext);\n                    __c = traits_type::to_int_type(*this->gptr());\n                }\n            }\n        }\n    }\n    else\n        __c = traits_type::to_int_type(*this->gptr());\n    if (this->eback() == &__1buf)\n        this->setg(0, 0, 0);\n    return __c;\n}\n\ntemplate <class _CharT, class _Traits>\ntypename basic_filebuf<_CharT, _Traits>::int_type\nbasic_filebuf<_CharT, _Traits>::pbackfail(int_type __c)\n{\n    if (__file_ && this->eback() < this->gptr())\n    {\n        if (traits_type::eq_int_type(__c, traits_type::eof()))\n        {\n            this->gbump(-1);\n            return traits_type::not_eof(__c);\n        }\n        if ((__om_ & ios_base::out) ||\n            traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))\n        {\n            this->gbump(-1);\n            *this->gptr() = traits_type::to_char_type(__c);\n            return __c;\n        }\n    }\n    return traits_type::eof();\n}\n\ntemplate <class _CharT, class _Traits>\ntypename basic_filebuf<_CharT, _Traits>::int_type\nbasic_filebuf<_CharT, _Traits>::overflow(int_type __c)\n{\n    if (__file_ == 0)\n        return traits_type::eof();\n    __write_mode();\n    char_type __1buf;\n    char_type* __pb_save = this->pbase();\n    char_type* __epb_save = this->epptr();\n    if (!traits_type::eq_int_type(__c, traits_type::eof()))\n    {\n        if (this->pptr() == 0)\n            this->setp(&__1buf, &__1buf+1);\n        *this->pptr() = traits_type::to_char_type(__c);\n        this->pbump(1);\n    }\n    if (this->pptr() != this->pbase())\n    {\n        if (__always_noconv_)\n        {\n            size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());\n            if (fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)\n                return traits_type::eof();\n        }\n        else\n        {\n            char* __extbe = __extbuf_;\n            codecvt_base::result __r;\n            do\n            {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n                if (!__cv_)\n                    throw bad_cast();\n#endif\n                const char_type* __e;\n                __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,\n                                        __extbuf_, __extbuf_ + __ebs_, __extbe);\n                if (__e == this->pbase())\n                    return traits_type::eof();\n                if (__r == codecvt_base::noconv)\n                {\n                    size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());\n                    if (fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)\n                        return traits_type::eof();\n                }\n                else if (__r == codecvt_base::ok || __r == codecvt_base::partial)\n                {\n                    size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);\n                    if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)\n                        return traits_type::eof();\n                    if (__r == codecvt_base::partial)\n                    {\n                        this->setp((char_type*)__e, this->pptr());\n                        this->pbump(this->epptr() - this->pbase());\n                    }\n                }\n                else\n                    return traits_type::eof();\n            } while (__r == codecvt_base::partial);\n        }\n        this->setp(__pb_save, __epb_save);\n    }\n    return traits_type::not_eof(__c);\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_streambuf<_CharT, _Traits>*\nbasic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n)\n{\n    this->setg(0, 0, 0);\n    this->setp(0, 0);\n    if (__owns_eb_)\n        delete [] __extbuf_;\n    if (__owns_ib_)\n        delete [] __intbuf_;\n    __ebs_ = __n;\n    if (__ebs_ > sizeof(__extbuf_min_))\n    {\n        if (__always_noconv_ && __s)\n        {\n            __extbuf_ = (char*)__s;\n            __owns_eb_ = false;\n        }\n        else\n        {\n            __extbuf_ = new char[__ebs_];\n            __owns_eb_ = true;\n        }\n    }\n    else\n    {\n        __extbuf_ = __extbuf_min_;\n        __ebs_ = sizeof(__extbuf_min_);\n        __owns_eb_ = false;\n    }\n    if (!__always_noconv_)\n    {\n        __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));\n        if (__s && __ibs_ >= sizeof(__extbuf_min_))\n        {\n            __intbuf_ = __s;\n            __owns_ib_ = false;\n        }\n        else\n        {\n            __intbuf_ = new char_type[__ibs_];\n            __owns_ib_ = true;\n        }\n    }\n    else\n    {\n        __ibs_ = 0;\n        __intbuf_ = 0;\n        __owns_ib_ = false;\n    }\n    return this;\n}\n\ntemplate <class _CharT, class _Traits>\ntypename basic_filebuf<_CharT, _Traits>::pos_type\nbasic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way,\n                                        ios_base::openmode)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (!__cv_)\n        throw bad_cast();\n#endif\n    int __width = __cv_->encoding();\n    if (__file_ == 0 || (__width <= 0 && __off != 0) || sync())\n        return pos_type(off_type(-1));\n    // __width > 0 || __off == 0\n    int __whence;\n    switch (__way)\n    {\n    case ios_base::beg:\n        __whence = SEEK_SET;\n        break;\n    case ios_base::cur:\n        __whence = SEEK_CUR;\n        break;\n    case ios_base::end:\n        __whence = SEEK_END;\n        break;\n    default:\n        return pos_type(off_type(-1));\n    }\n#if defined(_WIN32) || defined(_NEWLIB_VERSION)\n    if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))\n        return pos_type(off_type(-1));\n    pos_type __r = ftell(__file_);\n#else\n    if (fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))\n        return pos_type(off_type(-1));\n    pos_type __r = ftello(__file_);\n#endif\n    __r.state(__st_);\n    return __r;\n}\n\ntemplate <class _CharT, class _Traits>\ntypename basic_filebuf<_CharT, _Traits>::pos_type\nbasic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode)\n{\n    if (__file_ == 0 || sync())\n        return pos_type(off_type(-1));\n#if defined(_WIN32) || defined(_NEWLIB_VERSION)\n    if (fseek(__file_, __sp, SEEK_SET))\n        return pos_type(off_type(-1));\n#else\n    if (fseeko(__file_, __sp, SEEK_SET))\n        return pos_type(off_type(-1));\n#endif\n    __st_ = __sp.state();\n    return __sp;\n}\n\ntemplate <class _CharT, class _Traits>\nint\nbasic_filebuf<_CharT, _Traits>::sync()\n{\n    if (__file_ == 0)\n        return 0;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (!__cv_)\n        throw bad_cast();\n#endif\n    if (__cm_ & ios_base::out)\n    {\n        if (this->pptr() != this->pbase())\n            if (overflow() == traits_type::eof())\n                return -1;\n        codecvt_base::result __r;\n        do\n        {\n            char* __extbe;\n            __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);\n            size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);\n            if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)\n                return -1;\n        } while (__r == codecvt_base::partial);\n        if (__r == codecvt_base::error)\n            return -1;\n        if (fflush(__file_))\n            return -1;\n    }\n    else if (__cm_ & ios_base::in)\n    {\n        off_type __c;\n        state_type __state = __st_last_;\n        bool __update_st = false;\n        if (__always_noconv_)\n            __c = this->egptr() - this->gptr();\n        else\n        {\n            int __width = __cv_->encoding();\n            __c = __extbufend_ - __extbufnext_;\n            if (__width > 0)\n                __c += __width * (this->egptr() - this->gptr());\n            else\n            {\n                if (this->gptr() != this->egptr())\n                {\n                    const int __off =  __cv_->length(__state, __extbuf_,\n                                                     __extbufnext_,\n                                                     this->gptr() - this->eback());\n                    __c += __extbufnext_ - __extbuf_ - __off;\n                    __update_st = true;\n                }\n            }\n        }\n#if defined(_WIN32) || defined(_NEWLIB_VERSION)\n        if (fseek(__file_, -__c, SEEK_CUR))\n            return -1;\n#else\n        if (fseeko(__file_, -__c, SEEK_CUR))\n            return -1;\n#endif\n        if (__update_st)\n            __st_ = __state;\n        __extbufnext_ = __extbufend_ = __extbuf_;\n        this->setg(0, 0, 0);\n        __cm_ = 0;\n    }\n    return 0;\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_filebuf<_CharT, _Traits>::imbue(const locale& __loc)\n{\n    sync();\n    __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);\n    bool __old_anc = __always_noconv_;\n    __always_noconv_ = __cv_->always_noconv();\n    if (__old_anc != __always_noconv_)\n    {\n        this->setg(0, 0, 0);\n        this->setp(0, 0);\n        // invariant, char_type is char, else we couldn't get here\n        if (__always_noconv_)  // need to dump __intbuf_\n        {\n            if (__owns_eb_)\n                delete [] __extbuf_;\n            __owns_eb_ = __owns_ib_;\n            __ebs_ = __ibs_;\n            __extbuf_ = (char*)__intbuf_;\n            __ibs_ = 0;\n            __intbuf_ = 0;\n            __owns_ib_ = false;\n        }\n        else  // need to obtain an __intbuf_.\n        {     // If __extbuf_ is user-supplied, use it, else new __intbuf_\n            if (!__owns_eb_ && __extbuf_ != __extbuf_min_)\n            {\n                __ibs_ = __ebs_;\n                __intbuf_ = (char_type*)__extbuf_;\n                __owns_ib_ = false;\n                __extbuf_ = new char[__ebs_];\n                __owns_eb_ = true;\n            }\n            else\n            {\n                __ibs_ = __ebs_;\n                __intbuf_ = new char_type[__ibs_];\n                __owns_ib_ = true;\n            }\n        }\n    }\n}\n\ntemplate <class _CharT, class _Traits>\nbool\nbasic_filebuf<_CharT, _Traits>::__read_mode()\n{\n    if (!(__cm_ & ios_base::in))\n    {\n        this->setp(0, 0);\n        if (__always_noconv_)\n            this->setg((char_type*)__extbuf_,\n                       (char_type*)__extbuf_ + __ebs_,\n                       (char_type*)__extbuf_ + __ebs_);\n        else\n            this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);\n        __cm_ = ios_base::in;\n        return true;\n    }\n    return false;\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_filebuf<_CharT, _Traits>::__write_mode()\n{\n    if (!(__cm_ & ios_base::out))\n    {\n        this->setg(0, 0, 0);\n        if (__ebs_ > sizeof(__extbuf_min_))\n        {\n            if (__always_noconv_)\n                this->setp((char_type*)__extbuf_,\n                           (char_type*)__extbuf_ + (__ebs_ - 1));\n            else\n                this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));\n        }\n        else\n            this->setp(0, 0);\n        __cm_ = ios_base::out;\n    }\n}\n\n// basic_ifstream\n\ntemplate <class _CharT, class _Traits>\nclass _LIBCPP_TYPE_VIS_ONLY basic_ifstream\n    : public basic_istream<_CharT, _Traits>\n{\npublic:\n    typedef _CharT                         char_type;\n    typedef _Traits                        traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    basic_ifstream();\n#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\n    explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);\n    explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);\n#endif\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    basic_ifstream(basic_ifstream&& __rhs);\n#endif\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    basic_ifstream& operator=(basic_ifstream&& __rhs);\n#endif\n    void swap(basic_ifstream& __rhs);\n\n    basic_filebuf<char_type, traits_type>* rdbuf() const;\n    bool is_open() const;\n#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\n    void open(const char* __s, ios_base::openmode __mode = ios_base::in);\n    void open(const string& __s, ios_base::openmode __mode = ios_base::in);\n#endif\n    void close();\n\nprivate:\n    basic_filebuf<char_type, traits_type> __sb_;\n};\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ifstream<_CharT, _Traits>::basic_ifstream()\n    : basic_istream<char_type, traits_type>(&__sb_)\n{\n}\n\n#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)\n    : basic_istream<char_type, traits_type>(&__sb_)\n{\n    if (__sb_.open(__s, __mode | ios_base::in) == 0)\n        this->setstate(ios_base::failbit);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)\n    : basic_istream<char_type, traits_type>(&__sb_)\n{\n    if (__sb_.open(__s, __mode | ios_base::in) == 0)\n        this->setstate(ios_base::failbit);\n}\n#endif\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)\n    : basic_istream<char_type, traits_type>(_VSTD::move(__rhs)),\n      __sb_(_VSTD::move(__rhs.__sb_))\n{\n    this->set_rdbuf(&__sb_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ifstream<_CharT, _Traits>&\nbasic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs)\n{\n    basic_istream<char_type, traits_type>::operator=(_VSTD::move(__rhs));\n    __sb_ = _VSTD::move(__rhs.__sb_);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs)\n{\n    basic_istream<char_type, traits_type>::swap(__rhs);\n    __sb_.swap(__rhs.__sb_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y)\n{\n    __x.swap(__y);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_filebuf<_CharT, _Traits>*\nbasic_ifstream<_CharT, _Traits>::rdbuf() const\n{\n    return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nbasic_ifstream<_CharT, _Traits>::is_open() const\n{\n    return __sb_.is_open();\n}\n\n#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)\n{\n    if (__sb_.open(__s, __mode | ios_base::in))\n        this->clear();\n    else\n        this->setstate(ios_base::failbit);\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)\n{\n    if (__sb_.open(__s, __mode | ios_base::in))\n        this->clear();\n    else\n        this->setstate(ios_base::failbit);\n}\n#endif\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_ifstream<_CharT, _Traits>::close()\n{\n    if (__sb_.close() == 0)\n        this->setstate(ios_base::failbit);\n}\n\n// basic_ofstream\n\ntemplate <class _CharT, class _Traits>\nclass _LIBCPP_TYPE_VIS_ONLY basic_ofstream\n    : public basic_ostream<_CharT, _Traits>\n{\npublic:\n    typedef _CharT                         char_type;\n    typedef _Traits                        traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    basic_ofstream();\n    explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);\n    explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    basic_ofstream(basic_ofstream&& __rhs);\n#endif\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    basic_ofstream& operator=(basic_ofstream&& __rhs);\n#endif\n    void swap(basic_ofstream& __rhs);\n\n    basic_filebuf<char_type, traits_type>* rdbuf() const;\n    bool is_open() const;\n#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\n    void open(const char* __s, ios_base::openmode __mode = ios_base::out);\n    void open(const string& __s, ios_base::openmode __mode = ios_base::out);\n#endif\n    void close();\n\nprivate:\n    basic_filebuf<char_type, traits_type> __sb_;\n};\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ofstream<_CharT, _Traits>::basic_ofstream()\n    : basic_ostream<char_type, traits_type>(&__sb_)\n{\n}\n\n#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)\n    : basic_ostream<char_type, traits_type>(&__sb_)\n{\n    if (__sb_.open(__s, __mode | ios_base::out) == 0)\n        this->setstate(ios_base::failbit);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)\n    : basic_ostream<char_type, traits_type>(&__sb_)\n{\n    if (__sb_.open(__s, __mode | ios_base::out) == 0)\n        this->setstate(ios_base::failbit);\n}\n#endif\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)\n    : basic_ostream<char_type, traits_type>(_VSTD::move(__rhs)),\n      __sb_(_VSTD::move(__rhs.__sb_))\n{\n    this->set_rdbuf(&__sb_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ofstream<_CharT, _Traits>&\nbasic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs)\n{\n    basic_ostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));\n    __sb_ = _VSTD::move(__rhs.__sb_);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs)\n{\n    basic_ostream<char_type, traits_type>::swap(__rhs);\n    __sb_.swap(__rhs.__sb_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y)\n{\n    __x.swap(__y);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_filebuf<_CharT, _Traits>*\nbasic_ofstream<_CharT, _Traits>::rdbuf() const\n{\n    return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nbasic_ofstream<_CharT, _Traits>::is_open() const\n{\n    return __sb_.is_open();\n}\n\n#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)\n{\n    if (__sb_.open(__s, __mode | ios_base::out))\n        this->clear();\n    else\n        this->setstate(ios_base::failbit);\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)\n{\n    if (__sb_.open(__s, __mode | ios_base::out))\n        this->clear();\n    else\n        this->setstate(ios_base::failbit);\n}\n#endif\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_ofstream<_CharT, _Traits>::close()\n{\n    if (__sb_.close() == 0)\n        this->setstate(ios_base::failbit);\n}\n\n// basic_fstream\n\ntemplate <class _CharT, class _Traits>\nclass _LIBCPP_TYPE_VIS_ONLY basic_fstream\n    : public basic_iostream<_CharT, _Traits>\n{\npublic:\n    typedef _CharT                         char_type;\n    typedef _Traits                        traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    basic_fstream();\n#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\n    explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);\n    explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);\n#endif\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    basic_fstream(basic_fstream&& __rhs);\n#endif\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    basic_fstream& operator=(basic_fstream&& __rhs);\n#endif\n    void swap(basic_fstream& __rhs);\n\n    basic_filebuf<char_type, traits_type>* rdbuf() const;\n    bool is_open() const;\n#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\n    void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);\n    void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);\n#endif\n    void close();\n\nprivate:\n    basic_filebuf<char_type, traits_type> __sb_;\n};\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_fstream<_CharT, _Traits>::basic_fstream()\n    : basic_iostream<char_type, traits_type>(&__sb_)\n{\n}\n\n#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)\n    : basic_iostream<char_type, traits_type>(&__sb_)\n{\n    if (__sb_.open(__s, __mode) == 0)\n        this->setstate(ios_base::failbit);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode)\n    : basic_iostream<char_type, traits_type>(&__sb_)\n{\n    if (__sb_.open(__s, __mode) == 0)\n        this->setstate(ios_base::failbit);\n}\n#endif\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)\n    : basic_iostream<char_type, traits_type>(_VSTD::move(__rhs)),\n      __sb_(_VSTD::move(__rhs.__sb_))\n{\n    this->set_rdbuf(&__sb_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_fstream<_CharT, _Traits>&\nbasic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs)\n{\n    basic_iostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));\n    __sb_ = _VSTD::move(__rhs.__sb_);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs)\n{\n    basic_iostream<char_type, traits_type>::swap(__rhs);\n    __sb_.swap(__rhs.__sb_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y)\n{\n    __x.swap(__y);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_filebuf<_CharT, _Traits>*\nbasic_fstream<_CharT, _Traits>::rdbuf() const\n{\n    return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nbasic_fstream<_CharT, _Traits>::is_open() const\n{\n    return __sb_.is_open();\n}\n\n#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)\n{\n    if (__sb_.open(__s, __mode))\n        this->clear();\n    else\n        this->setstate(ios_base::failbit);\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)\n{\n    if (__sb_.open(__s, __mode))\n        this->clear();\n    else\n        this->setstate(ios_base::failbit);\n}\n#endif\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_fstream<_CharT, _Traits>::close()\n{\n    if (__sb_.close() == 0)\n        this->setstate(ios_base::failbit);\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_FSTREAM\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/functional",
    "content": "// -*- C++ -*-\n//===------------------------ functional ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_FUNCTIONAL\n#define _LIBCPP_FUNCTIONAL\n\n/*\n    functional synopsis\n\nnamespace std\n{\n\ntemplate <class Arg, class Result>\nstruct unary_function\n{\n    typedef Arg    argument_type;\n    typedef Result result_type;\n};\n\ntemplate <class Arg1, class Arg2, class Result>\nstruct binary_function\n{\n    typedef Arg1   first_argument_type;\n    typedef Arg2   second_argument_type;\n    typedef Result result_type;\n};\n\ntemplate <class T>\nclass reference_wrapper\n    : public unary_function<T1, R> // if wrapping a unary functor\n    : public binary_function<T1, T2, R> // if wraping a binary functor\n{\npublic:\n    // types\n    typedef T type;\n    typedef see below result_type; // Not always defined\n\n    // construct/copy/destroy\n    reference_wrapper(T&) noexcept;\n    reference_wrapper(T&&) = delete; // do not bind to temps\n    reference_wrapper(const reference_wrapper<T>& x) noexcept;\n\n    // assignment\n    reference_wrapper& operator=(const reference_wrapper<T>& x) noexcept;\n\n    // access\n    operator T& () const noexcept;\n    T& get() const noexcept;\n\n    // invoke\n    template <class... ArgTypes>\n      typename result_of<T&(ArgTypes&&...)>::type\n          operator() (ArgTypes&&...) const;\n};\n\ntemplate <class T> reference_wrapper<T> ref(T& t) noexcept;\ntemplate <class T> void ref(const T&& t) = delete;\ntemplate <class T> reference_wrapper<T> ref(reference_wrapper<T>t) noexcept;\n\ntemplate <class T> reference_wrapper<const T> cref(const T& t) noexcept;\ntemplate <class T> void cref(const T&& t) = delete;\ntemplate <class T> reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;\n\ntemplate <class T> // <class T=void> in C++14\nstruct plus : binary_function<T, T, T>\n{\n    T operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct minus : binary_function<T, T, T>\n{\n    T operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct multiplies : binary_function<T, T, T>\n{\n    T operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct divides : binary_function<T, T, T>\n{\n    T operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct modulus : binary_function<T, T, T>\n{\n    T operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct negate : unary_function<T, T>\n{\n    T operator()(const T& x) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct equal_to : binary_function<T, T, bool>\n{\n    bool operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct not_equal_to : binary_function<T, T, bool>\n{\n    bool operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct greater : binary_function<T, T, bool>\n{\n    bool operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct less : binary_function<T, T, bool>\n{\n    bool operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct greater_equal : binary_function<T, T, bool>\n{\n    bool operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct less_equal : binary_function<T, T, bool>\n{\n    bool operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct logical_and : binary_function<T, T, bool>\n{\n    bool operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct logical_or : binary_function<T, T, bool>\n{\n    bool operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct logical_not : unary_function<T, bool>\n{\n    bool operator()(const T& x) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct bit_and : unary_function<T, bool>\n{\n    bool operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct bit_or : unary_function<T, bool>\n{\n    bool operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T> // <class T=void> in C++14\nstruct bit_xor : unary_function<T, bool>\n{\n    bool operator()(const T& x, const T& y) const;\n};\n\ntemplate <class T=void> // C++14\nstruct bit_xor : unary_function<T, bool>\n{\n    bool operator()(const T& x) const;\n};\n\ntemplate <class Predicate>\nclass unary_negate\n    : public unary_function<typename Predicate::argument_type, bool>\n{\npublic:\n    explicit unary_negate(const Predicate& pred);\n    bool operator()(const typename Predicate::argument_type& x) const;\n};\n\ntemplate <class Predicate> unary_negate<Predicate> not1(const Predicate& pred);\n\ntemplate <class Predicate>\nclass binary_negate\n    : public binary_function<typename Predicate::first_argument_type,\n                             typename Predicate::second_argument_type,\n                             bool>\n{\npublic:\n    explicit binary_negate(const Predicate& pred);\n    bool operator()(const typename Predicate::first_argument_type& x,\n                    const typename Predicate::second_argument_type& y) const;\n};\n\ntemplate <class Predicate> binary_negate<Predicate> not2(const Predicate& pred);\n\ntemplate<class T> struct is_bind_expression;\ntemplate<class T> struct is_placeholder;\n\ntemplate<class Fn, class... BoundArgs>\n  unspecified bind(Fn&&, BoundArgs&&...);\ntemplate<class R, class Fn, class... BoundArgs>\n  unspecified bind(Fn&&, BoundArgs&&...);\n\nnamespace placeholders {\n  // M is the implementation-defined number of placeholders\n  extern unspecified _1;\n  extern unspecified _2;\n  .\n  .\n  .\n  extern unspecified _Mp;\n}\n\ntemplate <class Operation>\nclass binder1st\n    : public unary_function<typename Operation::second_argument_type,\n                            typename Operation::result_type>\n{\nprotected:\n    Operation                               op;\n    typename Operation::first_argument_type value;\npublic:\n    binder1st(const Operation& x, const typename Operation::first_argument_type y);\n    typename Operation::result_type operator()(      typename Operation::second_argument_type& x) const;\n    typename Operation::result_type operator()(const typename Operation::second_argument_type& x) const;\n};\n\ntemplate <class Operation, class T>\nbinder1st<Operation> bind1st(const Operation& op, const T& x);\n\ntemplate <class Operation>\nclass binder2nd\n    : public unary_function<typename Operation::first_argument_type,\n                            typename Operation::result_type>\n{\nprotected:\n    Operation                                op;\n    typename Operation::second_argument_type value;\npublic:\n    binder2nd(const Operation& x, const typename Operation::second_argument_type y);\n    typename Operation::result_type operator()(      typename Operation::first_argument_type& x) const;\n    typename Operation::result_type operator()(const typename Operation::first_argument_type& x) const;\n};\n\ntemplate <class Operation, class T>\nbinder2nd<Operation> bind2nd(const Operation& op, const T& x);\n\ntemplate <class Arg, class Result>\nclass pointer_to_unary_function : public unary_function<Arg, Result>\n{\npublic:\n    explicit pointer_to_unary_function(Result (*f)(Arg));\n    Result operator()(Arg x) const;\n};\n\ntemplate <class Arg, class Result>\npointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg));\n\ntemplate <class Arg1, class Arg2, class Result>\nclass pointer_to_binary_function : public binary_function<Arg1, Arg2, Result>\n{\npublic:\n    explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2));\n    Result operator()(Arg1 x, Arg2 y) const;\n};\n\ntemplate <class Arg1, class Arg2, class Result>\npointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1,Arg2));\n\ntemplate<class S, class T>\nclass mem_fun_t : public unary_function<T*, S>\n{\npublic:\n    explicit mem_fun_t(S (T::*p)());\n    S operator()(T* p) const;\n};\n\ntemplate<class S, class T, class A>\nclass mem_fun1_t : public binary_function<T*, A, S>\n{\npublic:\n    explicit mem_fun1_t(S (T::*p)(A));\n    S operator()(T* p, A x) const;\n};\n\ntemplate<class S, class T>          mem_fun_t<S,T>    mem_fun(S (T::*f)());\ntemplate<class S, class T, class A> mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A));\n\ntemplate<class S, class T>\nclass mem_fun_ref_t : public unary_function<T, S>\n{\npublic:\n    explicit mem_fun_ref_t(S (T::*p)());\n    S operator()(T& p) const;\n};\n\ntemplate<class S, class T, class A>\nclass mem_fun1_ref_t : public binary_function<T, A, S>\n{\npublic:\n    explicit mem_fun1_ref_t(S (T::*p)(A));\n    S operator()(T& p, A x) const;\n};\n\ntemplate<class S, class T>          mem_fun_ref_t<S,T>    mem_fun_ref(S (T::*f)());\ntemplate<class S, class T, class A> mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A));\n\ntemplate <class S, class T>\nclass const_mem_fun_t : public unary_function<const T*, S>\n{\npublic:\n    explicit const_mem_fun_t(S (T::*p)() const);\n    S operator()(const T* p) const;\n};\n\ntemplate <class S, class T, class A>\nclass const_mem_fun1_t : public binary_function<const T*, A, S>\n{\npublic:\n    explicit const_mem_fun1_t(S (T::*p)(A) const);\n    S operator()(const T* p, A x) const;\n};\n\ntemplate <class S, class T>          const_mem_fun_t<S,T>    mem_fun(S (T::*f)() const);\ntemplate <class S, class T, class A> const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const);\n\ntemplate <class S, class T>\nclass const_mem_fun_ref_t : public unary_function<T, S>\n{\npublic:\n    explicit const_mem_fun_ref_t(S (T::*p)() const);\n    S operator()(const T& p) const;\n};\n\ntemplate <class S, class T, class A>\nclass const_mem_fun1_ref_t : public binary_function<T, A, S>\n{\npublic:\n    explicit const_mem_fun1_ref_t(S (T::*p)(A) const);\n    S operator()(const T& p, A x) const;\n};\n\ntemplate <class S, class T>          const_mem_fun_ref_t<S,T>    mem_fun_ref(S (T::*f)() const);\ntemplate <class S, class T, class A> const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const);\n\ntemplate<class R, class T> unspecified mem_fn(R T::*);\n\nclass bad_function_call\n    : public exception\n{\n};\n\ntemplate<class> class function; // undefined\n\ntemplate<class R, class... ArgTypes>\nclass function<R(ArgTypes...)>\n  : public unary_function<T1, R>      // iff sizeof...(ArgTypes) == 1 and\n                                      // ArgTypes contains T1\n  : public binary_function<T1, T2, R> // iff sizeof...(ArgTypes) == 2 and\n                                      // ArgTypes contains T1 and T2\n{\npublic:\n    typedef R result_type;\n\n    // construct/copy/destroy:\n    function() noexcept;\n    function(nullptr_t) noexcept;\n    function(const function&);\n    function(function&&) noexcept;\n    template<class F>\n      function(F);\n    template<Allocator Alloc>\n      function(allocator_arg_t, const Alloc&) noexcept;\n    template<Allocator Alloc>\n      function(allocator_arg_t, const Alloc&, nullptr_t) noexcept;\n    template<Allocator Alloc>\n      function(allocator_arg_t, const Alloc&, const function&);\n    template<Allocator Alloc>\n      function(allocator_arg_t, const Alloc&, function&&);\n    template<class F, Allocator Alloc>\n      function(allocator_arg_t, const Alloc&, F);\n\n    function& operator=(const function&);\n    function& operator=(function&&) noexcept;\n    function& operator=(nullptr_t) noexcept;\n    template<class F>\n      function& operator=(F&&);\n    template<class F>\n      function& operator=(reference_wrapper<F>) noexcept;\n\n    ~function();\n\n    // function modifiers:\n    void swap(function&) noexcept;\n    template<class F, class Alloc>\n      void assign(F&&, const Alloc&);\n\n    // function capacity:\n    explicit operator bool() const noexcept;\n\n    // function invocation:\n    R operator()(ArgTypes...) const;\n\n    // function target access:\n    const std::type_info& target_type() const noexcept;\n    template <typename T>       T* target() noexcept;\n    template <typename T> const T* target() const noexcept;\n};\n\n// Null pointer comparisons:\ntemplate <class R, class ... ArgTypes>\n  bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;\n\ntemplate <class R, class ... ArgTypes>\n  bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;\n\ntemplate <class R, class ... ArgTypes>\n  bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept;\n\ntemplate <class  R, class ... ArgTypes>\n  bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept;\n\n// specialized algorithms:\ntemplate <class  R, class ... ArgTypes>\n  void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept;\n\ntemplate <class T> struct hash;\n\ntemplate <> struct hash<bool>;\ntemplate <> struct hash<char>;\ntemplate <> struct hash<signed char>;\ntemplate <> struct hash<unsigned char>;\ntemplate <> struct hash<char16_t>;\ntemplate <> struct hash<char32_t>;\ntemplate <> struct hash<wchar_t>;\ntemplate <> struct hash<short>;\ntemplate <> struct hash<unsigned short>;\ntemplate <> struct hash<int>;\ntemplate <> struct hash<unsigned int>;\ntemplate <> struct hash<long>;\ntemplate <> struct hash<long long>;\ntemplate <> struct hash<unsigned long>;\ntemplate <> struct hash<unsigned long long>;\n\ntemplate <> struct hash<float>;\ntemplate <> struct hash<double>;\ntemplate <> struct hash<long double>;\n\ntemplate<class T> struct hash<T*>;\n\n}  // std\n\nPOLICY:  For non-variadic implementations, the number of arguments is limited\n         to 3.  It is hoped that the need for non-variadic implementations\n         will be minimal.\n\n*/\n\n#include <__config>\n#include <type_traits>\n#include <typeinfo>\n#include <exception>\n#include <memory>\n#include <tuple>\n\n#include <__functional_base>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY plus : binary_function<_Tp, _Tp, _Tp>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x + __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY plus<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY minus : binary_function<_Tp, _Tp, _Tp>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x - __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY minus<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY multiplies : binary_function<_Tp, _Tp, _Tp>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x * __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY multiplies<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY divides : binary_function<_Tp, _Tp, _Tp>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x / __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY divides<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY modulus : binary_function<_Tp, _Tp, _Tp>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x % __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY modulus<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY negate : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return -__x;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY negate<void>\n{\n    template <class _Tp>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_Tp&& __x) const\n    _NOEXCEPT_(noexcept(- _VSTD::forward<_Tp>(__x)))\n    -> decltype        (- _VSTD::forward<_Tp>(__x))\n        { return        - _VSTD::forward<_Tp>(__x); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY equal_to : binary_function<_Tp, _Tp, bool>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x == __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY equal_to<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY not_equal_to : binary_function<_Tp, _Tp, bool>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x != __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY not_equal_to<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY greater : binary_function<_Tp, _Tp, bool>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x > __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY greater<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n// less in <__functional_base>\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY greater_equal : binary_function<_Tp, _Tp, bool>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x >= __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY greater_equal<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY less_equal : binary_function<_Tp, _Tp, bool>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x <= __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY less_equal<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY logical_and : binary_function<_Tp, _Tp, bool>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x && __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY logical_and<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY logical_or : binary_function<_Tp, _Tp, bool>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x || __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY logical_or<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY logical_not : unary_function<_Tp, bool>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Tp& __x) const\n        {return !__x;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY logical_not<void>\n{\n    template <class _Tp>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_Tp&& __x) const\n    _NOEXCEPT_(noexcept(!_VSTD::forward<_Tp>(__x)))\n    -> decltype        (!_VSTD::forward<_Tp>(__x))\n        { return        !_VSTD::forward<_Tp>(__x); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY bit_and : binary_function<_Tp, _Tp, _Tp>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x & __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY bit_and<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY bit_or : binary_function<_Tp, _Tp, _Tp>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x | __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY bit_or<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\n#else\ntemplate <class _Tp>\n#endif\nstruct _LIBCPP_TYPE_VIS_ONLY bit_xor : binary_function<_Tp, _Tp, _Tp>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x ^ __y;}\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY bit_xor<void>\n{\n    template <class _T1, class _T2>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_T1&& __t, _T2&& __u) const\n    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u)))\n    -> decltype        (_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u))\n        { return        _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u); }\n    typedef void is_transparent;\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp = void>\nstruct _LIBCPP_TYPE_VIS_ONLY bit_not : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return ~__x;}\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY bit_not<void>\n{\n    template <class _Tp>\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    auto operator()(_Tp&& __x) const\n    _NOEXCEPT_(noexcept(~_VSTD::forward<_Tp>(__x)))\n    -> decltype        (~_VSTD::forward<_Tp>(__x))\n        { return        ~_VSTD::forward<_Tp>(__x); }\n    typedef void is_transparent;\n};\n#endif\n\ntemplate <class _Predicate>\nclass _LIBCPP_TYPE_VIS_ONLY unary_negate\n    : public unary_function<typename _Predicate::argument_type, bool>\n{\n    _Predicate __pred_;\npublic:\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    explicit unary_negate(const _Predicate& __pred)\n        : __pred_(__pred) {}\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const typename _Predicate::argument_type& __x) const\n        {return !__pred_(__x);}\n};\n\ntemplate <class _Predicate>\ninline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\nunary_negate<_Predicate>\nnot1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);}\n\ntemplate <class _Predicate>\nclass _LIBCPP_TYPE_VIS_ONLY binary_negate\n    : public binary_function<typename _Predicate::first_argument_type,\n                             typename _Predicate::second_argument_type,\n                             bool>\n{\n    _Predicate __pred_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11 \n    binary_negate(const _Predicate& __pred) : __pred_(__pred) {}\n\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const typename _Predicate::first_argument_type& __x,\n                    const typename _Predicate::second_argument_type& __y) const\n        {return !__pred_(__x, __y);}\n};\n\ntemplate <class _Predicate>\ninline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\nbinary_negate<_Predicate>\nnot2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);}\n\ntemplate <class __Operation>\nclass _LIBCPP_TYPE_VIS_ONLY binder1st\n    : public unary_function<typename __Operation::second_argument_type,\n                            typename __Operation::result_type>\n{\nprotected:\n    __Operation                               op;\n    typename __Operation::first_argument_type value;\npublic:\n    _LIBCPP_INLINE_VISIBILITY binder1st(const __Operation& __x,\n                               const typename __Operation::first_argument_type __y)\n        : op(__x), value(__y) {}\n    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()\n        (typename __Operation::second_argument_type& __x) const\n            {return op(value, __x);}\n    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()\n        (const typename __Operation::second_argument_type& __x) const\n            {return op(value, __x);}\n};\n\ntemplate <class __Operation, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbinder1st<__Operation>\nbind1st(const __Operation& __op, const _Tp& __x)\n    {return binder1st<__Operation>(__op, __x);}\n\ntemplate <class __Operation>\nclass _LIBCPP_TYPE_VIS_ONLY binder2nd\n    : public unary_function<typename __Operation::first_argument_type,\n                            typename __Operation::result_type>\n{\nprotected:\n    __Operation                                op;\n    typename __Operation::second_argument_type value;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    binder2nd(const __Operation& __x, const typename __Operation::second_argument_type __y)\n        : op(__x), value(__y) {}\n    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()\n        (      typename __Operation::first_argument_type& __x) const\n            {return op(__x, value);}\n    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()\n        (const typename __Operation::first_argument_type& __x) const\n            {return op(__x, value);}\n};\n\ntemplate <class __Operation, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbinder2nd<__Operation>\nbind2nd(const __Operation& __op, const _Tp& __x)\n    {return binder2nd<__Operation>(__op, __x);}\n\ntemplate <class _Arg, class _Result>\nclass _LIBCPP_TYPE_VIS_ONLY pointer_to_unary_function\n    : public unary_function<_Arg, _Result>\n{\n    _Result (*__f_)(_Arg);\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit pointer_to_unary_function(_Result (*__f)(_Arg))\n        : __f_(__f) {}\n    _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg __x) const\n        {return __f_(__x);}\n};\n\ntemplate <class _Arg, class _Result>\ninline _LIBCPP_INLINE_VISIBILITY\npointer_to_unary_function<_Arg,_Result>\nptr_fun(_Result (*__f)(_Arg))\n    {return pointer_to_unary_function<_Arg,_Result>(__f);}\n\ntemplate <class _Arg1, class _Arg2, class _Result>\nclass _LIBCPP_TYPE_VIS_ONLY pointer_to_binary_function\n    : public binary_function<_Arg1, _Arg2, _Result>\n{\n    _Result (*__f_)(_Arg1, _Arg2);\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit pointer_to_binary_function(_Result (*__f)(_Arg1, _Arg2))\n        : __f_(__f) {}\n    _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg1 __x, _Arg2 __y) const\n        {return __f_(__x, __y);}\n};\n\ntemplate <class _Arg1, class _Arg2, class _Result>\ninline _LIBCPP_INLINE_VISIBILITY\npointer_to_binary_function<_Arg1,_Arg2,_Result>\nptr_fun(_Result (*__f)(_Arg1,_Arg2))\n    {return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__f);}\n\ntemplate<class _Sp, class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY mem_fun_t : public unary_function<_Tp*, _Sp>\n{\n    _Sp (_Tp::*__p_)();\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit mem_fun_t(_Sp (_Tp::*__p)())\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p) const\n        {return (__p->*__p_)();}\n};\n\ntemplate<class _Sp, class _Tp, class _Ap>\nclass _LIBCPP_TYPE_VIS_ONLY mem_fun1_t : public binary_function<_Tp*, _Ap, _Sp>\n{\n    _Sp (_Tp::*__p_)(_Ap);\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_t(_Sp (_Tp::*__p)(_Ap))\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p, _Ap __x) const\n        {return (__p->*__p_)(__x);}\n};\n\ntemplate<class _Sp, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nmem_fun_t<_Sp,_Tp>\nmem_fun(_Sp (_Tp::*__f)())\n    {return mem_fun_t<_Sp,_Tp>(__f);}\n\ntemplate<class _Sp, class _Tp, class _Ap>\ninline _LIBCPP_INLINE_VISIBILITY\nmem_fun1_t<_Sp,_Tp,_Ap>\nmem_fun(_Sp (_Tp::*__f)(_Ap))\n    {return mem_fun1_t<_Sp,_Tp,_Ap>(__f);}\n\ntemplate<class _Sp, class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY mem_fun_ref_t : public unary_function<_Tp, _Sp>\n{\n    _Sp (_Tp::*__p_)();\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit mem_fun_ref_t(_Sp (_Tp::*__p)())\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p) const\n        {return (__p.*__p_)();}\n};\n\ntemplate<class _Sp, class _Tp, class _Ap>\nclass _LIBCPP_TYPE_VIS_ONLY mem_fun1_ref_t : public binary_function<_Tp, _Ap, _Sp>\n{\n    _Sp (_Tp::*__p_)(_Ap);\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap))\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p, _Ap __x) const\n        {return (__p.*__p_)(__x);}\n};\n\ntemplate<class _Sp, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nmem_fun_ref_t<_Sp,_Tp>\nmem_fun_ref(_Sp (_Tp::*__f)())\n    {return mem_fun_ref_t<_Sp,_Tp>(__f);}\n\ntemplate<class _Sp, class _Tp, class _Ap>\ninline _LIBCPP_INLINE_VISIBILITY\nmem_fun1_ref_t<_Sp,_Tp,_Ap>\nmem_fun_ref(_Sp (_Tp::*__f)(_Ap))\n    {return mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}\n\ntemplate <class _Sp, class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY const_mem_fun_t : public unary_function<const _Tp*, _Sp>\n{\n    _Sp (_Tp::*__p_)() const;\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_t(_Sp (_Tp::*__p)() const)\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p) const\n        {return (__p->*__p_)();}\n};\n\ntemplate <class _Sp, class _Tp, class _Ap>\nclass _LIBCPP_TYPE_VIS_ONLY const_mem_fun1_t : public binary_function<const _Tp*, _Ap, _Sp>\n{\n    _Sp (_Tp::*__p_)(_Ap) const;\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_t(_Sp (_Tp::*__p)(_Ap) const)\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p, _Ap __x) const\n        {return (__p->*__p_)(__x);}\n};\n\ntemplate <class _Sp, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconst_mem_fun_t<_Sp,_Tp>\nmem_fun(_Sp (_Tp::*__f)() const)\n    {return const_mem_fun_t<_Sp,_Tp>(__f);}\n\ntemplate <class _Sp, class _Tp, class _Ap>\ninline _LIBCPP_INLINE_VISIBILITY\nconst_mem_fun1_t<_Sp,_Tp,_Ap>\nmem_fun(_Sp (_Tp::*__f)(_Ap) const)\n    {return const_mem_fun1_t<_Sp,_Tp,_Ap>(__f);}\n\ntemplate <class _Sp, class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY const_mem_fun_ref_t : public unary_function<_Tp, _Sp>\n{\n    _Sp (_Tp::*__p_)() const;\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_ref_t(_Sp (_Tp::*__p)() const)\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p) const\n        {return (__p.*__p_)();}\n};\n\ntemplate <class _Sp, class _Tp, class _Ap>\nclass _LIBCPP_TYPE_VIS_ONLY const_mem_fun1_ref_t\n    : public binary_function<_Tp, _Ap, _Sp>\n{\n    _Sp (_Tp::*__p_)(_Ap) const;\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap) const)\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p, _Ap __x) const\n        {return (__p.*__p_)(__x);}\n};\n\ntemplate <class _Sp, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconst_mem_fun_ref_t<_Sp,_Tp>\nmem_fun_ref(_Sp (_Tp::*__f)() const)\n    {return const_mem_fun_ref_t<_Sp,_Tp>(__f);}\n\ntemplate <class _Sp, class _Tp, class _Ap>\ninline _LIBCPP_INLINE_VISIBILITY\nconst_mem_fun1_ref_t<_Sp,_Tp,_Ap>\nmem_fun_ref(_Sp (_Tp::*__f)(_Ap) const)\n    {return const_mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}\n\n////////////////////////////////////////////////////////////////////////////////\n//                                MEMFUN\n//==============================================================================\n\ntemplate <class _Tp>\nclass __mem_fn\n    : public __weak_result_type<_Tp>\n{\npublic:\n    // types\n    typedef _Tp type;\nprivate:\n    type __f_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY __mem_fn(type __f) : __f_(__f) {}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    // invoke\n    template <class... _ArgTypes>\n    _LIBCPP_INLINE_VISIBILITY\n    typename __invoke_return<type, _ArgTypes...>::type\n    operator() (_ArgTypes&&... __args) const {\n        return __invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...);\n    }\n#else\n\n    template <class _A0>\n    typename __invoke_return0<type, _A0>::type\n    operator() (_A0& __a0) const {\n        return __invoke(__f_, __a0);\n    }\n\n    template <class _A0, class _A1>\n    typename __invoke_return1<type, _A0, _A1>::type\n    operator() (_A0& __a0, _A1& __a1) const {\n        return __invoke(__f_, __a0, __a1);\n    }\n\n    template <class _A0, class _A1, class _A2>\n    typename __invoke_return2<type, _A0, _A1, _A2>::type\n    operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {\n        return __invoke(__f_, __a0, __a1, __a2);\n    }\n#endif\n};\n\ntemplate<class _Rp, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n__mem_fn<_Rp _Tp::*>\nmem_fn(_Rp _Tp::* __pm)\n{\n    return __mem_fn<_Rp _Tp::*>(__pm);\n}\n\n////////////////////////////////////////////////////////////////////////////////\n//                                FUNCTION\n//==============================================================================\n\n// bad_function_call\n\nclass _LIBCPP_EXCEPTION_ABI bad_function_call\n    : public exception\n{\n};\n\ntemplate<class _Fp> class _LIBCPP_TYPE_VIS_ONLY function; // undefined\n\nnamespace __function\n{\n\ntemplate<class _Rp>\nstruct __maybe_derive_from_unary_function\n{\n};\n\ntemplate<class _Rp, class _A1>\nstruct __maybe_derive_from_unary_function<_Rp(_A1)>\n    : public unary_function<_A1, _Rp>\n{\n};\n\ntemplate<class _Rp>\nstruct __maybe_derive_from_binary_function\n{\n};\n\ntemplate<class _Rp, class _A1, class _A2>\nstruct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>\n    : public binary_function<_A1, _A2, _Rp>\n{\n};\n\n} // namespace __function\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\nnamespace __function {\n\ntemplate<class _Fp> class __base;\n\ntemplate<class _Rp, class ..._ArgTypes>\nclass __base<_Rp(_ArgTypes...)>\n{\n    __base(const __base&);\n    __base& operator=(const __base&);\npublic:\n    _LIBCPP_INLINE_VISIBILITY __base() {}\n    _LIBCPP_INLINE_VISIBILITY virtual ~__base() {}\n    virtual __base* __clone() const = 0;\n    virtual void __clone(__base*) const = 0;\n    virtual void destroy() _NOEXCEPT = 0;\n    virtual void destroy_deallocate() _NOEXCEPT = 0;\n    virtual _Rp operator()(_ArgTypes&& ...) = 0;\n#ifndef _LIBCPP_NO_RTTI\n    virtual const void* target(const type_info&) const _NOEXCEPT = 0;\n    virtual const std::type_info& target_type() const _NOEXCEPT = 0;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _FD, class _Alloc, class _FB> class __func;\n\ntemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>\nclass __func<_Fp, _Alloc, _Rp(_ArgTypes...)>\n    : public  __base<_Rp(_ArgTypes...)>\n{\n    __compressed_pair<_Fp, _Alloc> __f_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __func(_Fp&& __f)\n        : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),\n                                    _VSTD::forward_as_tuple()) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __func(const _Fp& __f, const _Alloc& __a)\n        : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),\n                                    _VSTD::forward_as_tuple(__a)) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __func(const _Fp& __f, _Alloc&& __a)\n        : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),\n                                    _VSTD::forward_as_tuple(_VSTD::move(__a))) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __func(_Fp&& __f, _Alloc&& __a)\n        : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),\n                                    _VSTD::forward_as_tuple(_VSTD::move(__a))) {}\n    virtual __base<_Rp(_ArgTypes...)>* __clone() const;\n    virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;\n    virtual void destroy() _NOEXCEPT;\n    virtual void destroy_deallocate() _NOEXCEPT;\n    virtual _Rp operator()(_ArgTypes&& ... __arg);\n#ifndef _LIBCPP_NO_RTTI\n    virtual const void* target(const type_info&) const _NOEXCEPT;\n    virtual const std::type_info& target_type() const _NOEXCEPT;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>\n__base<_Rp(_ArgTypes...)>*\n__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;\n    _Ap __a(__f_.second());\n    typedef __allocator_destructor<_Ap> _Dp;\n    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));\n    return __hold.release();\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>\nvoid\n__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const\n{\n    ::new (__p) __func(__f_.first(), __f_.second());\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>\nvoid\n__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT\n{\n    __f_.~__compressed_pair<_Fp, _Alloc>();\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>\nvoid\n__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;\n    _Ap __a(__f_.second());\n    __f_.~__compressed_pair<_Fp, _Alloc>();\n    __a.deallocate(this, 1);\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>\n_Rp\n__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)\n{\n    typedef __invoke_void_return_wrapper<_Rp> _Invoker;\n    return _Invoker::__call(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);\n}\n\n#ifndef _LIBCPP_NO_RTTI\n\ntemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>\nconst void*\n__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT\n{\n    if (__ti == typeid(_Fp))\n        return &__f_.first();\n    return (const void*)0;\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>\nconst std::type_info&\n__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT\n{\n    return typeid(_Fp);\n}\n\n#endif  // _LIBCPP_NO_RTTI\n\n}  // __function\n\ntemplate<class _Rp, class ..._ArgTypes>\nclass _LIBCPP_TYPE_VIS_ONLY function<_Rp(_ArgTypes...)>\n    : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,\n      public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>\n{\n    typedef __function::__base<_Rp(_ArgTypes...)> __base;\n    typename aligned_storage<3*sizeof(void*)>::type __buf_;\n    __base* __f_;\n\n    template <class _Fp>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(const _Fp&) {return true;}\n    template <class _R2, class ..._Ap>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (*__p)(_Ap...)) {return __p;}\n    template <class _R2, class _Cp, class ..._Ap>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)(_Ap...)) {return __p;}\n    template <class _R2, class _Cp, class ..._Ap>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const) {return __p;}\n    template <class _R2, class _Cp, class ..._Ap>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)(_Ap...) volatile) {return __p;}\n    template <class _R2, class _Cp, class ..._Ap>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const volatile) {return __p;}\n    template <class _R2, class ..._Ap>\n        _LIBCPP_INLINE_VISIBILITY\n        static bool __not_null(const function<_R2(_Ap...)>& __p) {return !!__p;}\n\n    template <class _Fp, bool = !is_same<_Fp, function>::value &&\n                                __invokable<_Fp&, _ArgTypes...>::value>\n        struct __callable;\n    template <class _Fp>\n        struct __callable<_Fp, true>\n        {\n            static const bool value = is_same<void, _Rp>::value ||\n                is_convertible<typename __invoke_of<_Fp&, _ArgTypes...>::type,\n                               _Rp>::value;\n        };\n    template <class _Fp>\n        struct __callable<_Fp, false>\n        {\n            static const bool value = false;\n        };\npublic:\n    typedef _Rp result_type;\n\n    // construct/copy/destroy:\n    _LIBCPP_INLINE_VISIBILITY\n    function() _NOEXCEPT : __f_(0) {}\n    _LIBCPP_INLINE_VISIBILITY\n    function(nullptr_t) _NOEXCEPT : __f_(0) {}\n    function(const function&);\n    function(function&&) _NOEXCEPT;\n    template<class _Fp>\n      function(_Fp, typename enable_if\n                                     <\n                                        __callable<_Fp>::value &&\n                                        !is_same<_Fp, function>::value\n                                      >::type* = 0);\n\n    template<class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      function(allocator_arg_t, const _Alloc&) _NOEXCEPT : __f_(0) {}\n    template<class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT : __f_(0) {}\n    template<class _Alloc>\n      function(allocator_arg_t, const _Alloc&, const function&);\n    template<class _Alloc>\n      function(allocator_arg_t, const _Alloc&, function&&);\n    template<class _Fp, class _Alloc>\n      function(allocator_arg_t, const _Alloc& __a, _Fp __f,\n               typename enable_if<__callable<_Fp>::value>::type* = 0);\n\n    function& operator=(const function&);\n    function& operator=(function&&) _NOEXCEPT;\n    function& operator=(nullptr_t) _NOEXCEPT;\n    template<class _Fp>\n      typename enable_if\n      <\n        __callable<typename decay<_Fp>::type>::value &&\n        !is_same<typename remove_reference<_Fp>::type, function>::value,\n        function&\n      >::type\n      operator=(_Fp&&);\n\n    ~function();\n\n    // function modifiers:\n    void swap(function&) _NOEXCEPT;\n    template<class _Fp, class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      void assign(_Fp&& __f, const _Alloc& __a)\n        {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);}\n\n    // function capacity:\n    _LIBCPP_INLINE_VISIBILITY\n        _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return __f_;}\n\n    // deleted overloads close possible hole in the type system\n    template<class _R2, class... _ArgTypes2>\n      bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;\n    template<class _R2, class... _ArgTypes2>\n      bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;\npublic:\n    // function invocation:\n    _Rp operator()(_ArgTypes...) const;\n\n#ifndef _LIBCPP_NO_RTTI\n    // function target access:\n    const std::type_info& target_type() const _NOEXCEPT;\n    template <typename _Tp> _Tp* target() _NOEXCEPT;\n    template <typename _Tp> const _Tp* target() const _NOEXCEPT;\n#endif  // _LIBCPP_NO_RTTI\n};\n\ntemplate<class _Rp, class ..._ArgTypes>\nfunction<_Rp(_ArgTypes...)>::function(const function& __f)\n{\n    if (__f.__f_ == 0)\n        __f_ = 0;\n    else if (__f.__f_ == (const __base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__clone(__f_);\n    }\n    else\n        __f_ = __f.__f_->__clone();\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\ntemplate <class _Alloc>\nfunction<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,\n                                     const function& __f)\n{\n    if (__f.__f_ == 0)\n        __f_ = 0;\n    else if (__f.__f_ == (const __base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__clone(__f_);\n    }\n    else\n        __f_ = __f.__f_->__clone();\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\nfunction<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT\n{\n    if (__f.__f_ == 0)\n        __f_ = 0;\n    else if (__f.__f_ == (__base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__clone(__f_);\n    }\n    else\n    {\n        __f_ = __f.__f_;\n        __f.__f_ = 0;\n    }\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\ntemplate <class _Alloc>\nfunction<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,\n                                     function&& __f)\n{\n    if (__f.__f_ == 0)\n        __f_ = 0;\n    else if (__f.__f_ == (__base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__clone(__f_);\n    }\n    else\n    {\n        __f_ = __f.__f_;\n        __f.__f_ = 0;\n    }\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\ntemplate <class _Fp>\nfunction<_Rp(_ArgTypes...)>::function(_Fp __f,\n                                     typename enable_if\n                                     <\n                                        __callable<_Fp>::value &&\n                                        !is_same<_Fp, function>::value\n                                     >::type*)\n    : __f_(0)\n{\n    if (__not_null(__f))\n    {\n        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_ArgTypes...)> _FF;\n        if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value)\n        {\n            __f_ = (__base*)&__buf_;\n            ::new (__f_) _FF(_VSTD::move(__f));\n        }\n        else\n        {\n            typedef allocator<_FF> _Ap;\n            _Ap __a;\n            typedef __allocator_destructor<_Ap> _Dp;\n            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n            ::new (__hold.get()) _FF(_VSTD::move(__f), allocator<_Fp>(__a));\n            __f_ = __hold.release();\n        }\n    }\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\ntemplate <class _Fp, class _Alloc>\nfunction<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,\n                                     typename enable_if<__callable<_Fp>::value>::type*)\n    : __f_(0)\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\n    if (__not_null(__f))\n    {\n        typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF;\n        typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;\n        _Ap __a(__a0);\n        if (sizeof(_FF) <= sizeof(__buf_) && \n            is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value)\n        {\n            __f_ = (__base*)&__buf_;\n            ::new (__f_) _FF(_VSTD::move(__f), _Alloc(__a));\n        }\n        else\n        {\n            typedef __allocator_destructor<_Ap> _Dp;\n            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n            ::new (__hold.get()) _FF(_VSTD::move(__f), _Alloc(__a));\n            __f_ = __hold.release();\n        }\n    }\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\nfunction<_Rp(_ArgTypes...)>&\nfunction<_Rp(_ArgTypes...)>::operator=(const function& __f)\n{\n    function(__f).swap(*this);\n    return *this;\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\nfunction<_Rp(_ArgTypes...)>&\nfunction<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT\n{\n    if (__f_ == (__base*)&__buf_)\n        __f_->destroy();\n    else if (__f_)\n        __f_->destroy_deallocate();\n    __f_ = 0;\n    if (__f.__f_ == 0)\n        __f_ = 0;\n    else if (__f.__f_ == (__base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__clone(__f_);\n    }\n    else\n    {\n        __f_ = __f.__f_;\n        __f.__f_ = 0;\n    }\n    return *this;\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\nfunction<_Rp(_ArgTypes...)>&\nfunction<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT\n{\n    if (__f_ == (__base*)&__buf_)\n        __f_->destroy();\n    else if (__f_)\n        __f_->destroy_deallocate();\n    __f_ = 0;\n    return *this;\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\ntemplate <class _Fp>\ntypename enable_if\n<\n    function<_Rp(_ArgTypes...)>::template __callable<typename decay<_Fp>::type>::value &&\n    !is_same<typename remove_reference<_Fp>::type, function<_Rp(_ArgTypes...)>>::value,\n    function<_Rp(_ArgTypes...)>&\n>::type\nfunction<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)\n{\n    function(_VSTD::forward<_Fp>(__f)).swap(*this);\n    return *this;\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\nfunction<_Rp(_ArgTypes...)>::~function()\n{\n    if (__f_ == (__base*)&__buf_)\n        __f_->destroy();\n    else if (__f_)\n        __f_->destroy_deallocate();\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\nvoid\nfunction<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT\n{\n    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)\n    {\n        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;\n        __base* __t = (__base*)&__tempbuf;\n        __f_->__clone(__t);\n        __f_->destroy();\n        __f_ = 0;\n        __f.__f_->__clone((__base*)&__buf_);\n        __f.__f_->destroy();\n        __f.__f_ = 0;\n        __f_ = (__base*)&__buf_;\n        __t->__clone((__base*)&__f.__buf_);\n        __t->destroy();\n        __f.__f_ = (__base*)&__f.__buf_;\n    }\n    else if (__f_ == (__base*)&__buf_)\n    {\n        __f_->__clone((__base*)&__f.__buf_);\n        __f_->destroy();\n        __f_ = __f.__f_;\n        __f.__f_ = (__base*)&__f.__buf_;\n    }\n    else if (__f.__f_ == (__base*)&__f.__buf_)\n    {\n        __f.__f_->__clone((__base*)&__buf_);\n        __f.__f_->destroy();\n        __f.__f_ = __f_;\n        __f_ = (__base*)&__buf_;\n    }\n    else\n        _VSTD::swap(__f_, __f.__f_);\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\n_Rp\nfunction<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__f_ == 0)\n        throw bad_function_call();\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);\n}\n\n#ifndef _LIBCPP_NO_RTTI\n\ntemplate<class _Rp, class ..._ArgTypes>\nconst std::type_info&\nfunction<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT\n{\n    if (__f_ == 0)\n        return typeid(void);\n    return __f_->target_type();\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\ntemplate <typename _Tp>\n_Tp*\nfunction<_Rp(_ArgTypes...)>::target() _NOEXCEPT\n{\n    if (__f_ == 0)\n        return (_Tp*)0;\n    return (_Tp*)__f_->target(typeid(_Tp));\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\ntemplate <typename _Tp>\nconst _Tp*\nfunction<_Rp(_ArgTypes...)>::target() const _NOEXCEPT\n{\n    if (__f_ == 0)\n        return (const _Tp*)0;\n    return (const _Tp*)__f_->target(typeid(_Tp));\n}\n\n#endif  // _LIBCPP_NO_RTTI\n\ntemplate <class _Rp, class... _ArgTypes>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;}\n\ntemplate <class _Rp, class... _ArgTypes>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;}\n\ntemplate <class _Rp, class... _ArgTypes>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;}\n\ntemplate <class _Rp, class... _ArgTypes>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;}\n\ntemplate <class _Rp, class... _ArgTypes>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT\n{return __x.swap(__y);}\n\n#else // _LIBCPP_HAS_NO_VARIADICS\n\n#include <__functional_03>\n\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n//                                  BIND\n//==============================================================================\n\ntemplate<class _Tp> struct __is_bind_expression : public false_type {};\ntemplate<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_bind_expression\n    : public __is_bind_expression<typename remove_cv<_Tp>::type> {};\n\ntemplate<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {};\ntemplate<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_placeholder\n    : public __is_placeholder<typename remove_cv<_Tp>::type> {};\n\nnamespace placeholders\n{\n\ntemplate <int _Np> struct __ph {};\n\n_LIBCPP_FUNC_VIS extern __ph<1>   _1;\n_LIBCPP_FUNC_VIS extern __ph<2>   _2;\n_LIBCPP_FUNC_VIS extern __ph<3>   _3;\n_LIBCPP_FUNC_VIS extern __ph<4>   _4;\n_LIBCPP_FUNC_VIS extern __ph<5>   _5;\n_LIBCPP_FUNC_VIS extern __ph<6>   _6;\n_LIBCPP_FUNC_VIS extern __ph<7>   _7;\n_LIBCPP_FUNC_VIS extern __ph<8>   _8;\n_LIBCPP_FUNC_VIS extern __ph<9>   _9;\n_LIBCPP_FUNC_VIS extern __ph<10> _10;\n\n}  // placeholders\n\ntemplate<int _Np>\nstruct __is_placeholder<placeholders::__ph<_Np> >\n    : public integral_constant<int, _Np> {};\n\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Uj>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp&\n__mu(reference_wrapper<_Tp> __t, _Uj&)\n{\n    return __t.get();\n}\n\ntemplate <class _Ti, class ..._Uj, size_t ..._Indx>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __invoke_of<_Ti&, _Uj...>::type\n__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>)\n{\n    return __ti(_VSTD::forward<_Uj>(_VSTD::get<_Indx>(__uj))...);\n}\n\ntemplate <class _Ti, class ..._Uj>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __lazy_enable_if\n<\n    is_bind_expression<_Ti>::value,\n    __invoke_of<_Ti&, _Uj...>\n>::type\n__mu(_Ti& __ti, tuple<_Uj...>& __uj)\n{\n    typedef typename __make_tuple_indices<sizeof...(_Uj)>::type __indices;\n    return  __mu_expand(__ti, __uj, __indices());\n}\n\ntemplate <bool IsPh, class _Ti, class _Uj>\nstruct __mu_return2 {};\n\ntemplate <class _Ti, class _Uj>\nstruct __mu_return2<true, _Ti, _Uj>\n{\n    typedef typename tuple_element<is_placeholder<_Ti>::value - 1, _Uj>::type type;\n};\n\ntemplate <class _Ti, class _Uj>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    0 < is_placeholder<_Ti>::value,\n    typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type\n>::type\n__mu(_Ti&, _Uj& __uj)\n{\n    const size_t _Indx = is_placeholder<_Ti>::value - 1;\n    return _VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj));\n}\n\ntemplate <class _Ti, class _Uj>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_bind_expression<_Ti>::value &&\n    is_placeholder<_Ti>::value == 0 &&\n    !__is_reference_wrapper<_Ti>::value,\n    _Ti&\n>::type\n__mu(_Ti& __ti, _Uj&)\n{\n    return __ti;\n}\n\ntemplate <class _Ti, bool IsReferenceWrapper, bool IsBindEx, bool IsPh,\n          class _TupleUj>\nstruct ____mu_return;\n\ntemplate <bool _Invokable, class _Ti, class ..._Uj>\nstruct ____mu_return_invokable  // false\n{\n    typedef __nat type;\n};\n\ntemplate <class _Ti, class ..._Uj>\nstruct ____mu_return_invokable<true, _Ti, _Uj...>\n{\n    typedef typename __invoke_of<_Ti&, _Uj...>::type type;\n};\n\ntemplate <class _Ti, class ..._Uj>\nstruct ____mu_return<_Ti, false, true, false, tuple<_Uj...> >\n    : public ____mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...>\n{\n};\n\ntemplate <class _Ti, class _TupleUj>\nstruct ____mu_return<_Ti, false, false, true, _TupleUj>\n{\n    typedef typename tuple_element<is_placeholder<_Ti>::value - 1,\n                                   _TupleUj>::type&& type;\n};\n\ntemplate <class _Ti, class _TupleUj>\nstruct ____mu_return<_Ti, true, false, false, _TupleUj>\n{\n    typedef typename _Ti::type& type;\n};\n\ntemplate <class _Ti, class _TupleUj>\nstruct ____mu_return<_Ti, false, false, false, _TupleUj>\n{\n    typedef _Ti& type;\n};\n\ntemplate <class _Ti, class _TupleUj>\nstruct __mu_return\n    : public ____mu_return<_Ti,\n                           __is_reference_wrapper<_Ti>::value,\n                           is_bind_expression<_Ti>::value,\n                           0 < is_placeholder<_Ti>::value &&\n                           is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value,\n                           _TupleUj>\n{\n};\n\ntemplate <class _Fp, class _BoundArgs, class _TupleUj>\nstruct __is_valid_bind_return\n{\n    static const bool value = false;\n};\n\ntemplate <class _Fp, class ..._BoundArgs, class _TupleUj>\nstruct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj>\n{\n    static const bool value = __invokable<_Fp,\n                    typename __mu_return<_BoundArgs, _TupleUj>::type...>::value;\n};\n\ntemplate <class _Fp, class ..._BoundArgs, class _TupleUj>\nstruct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj>\n{\n    static const bool value = __invokable<_Fp,\n                    typename __mu_return<const _BoundArgs, _TupleUj>::type...>::value;\n};\n\ntemplate <class _Fp, class _BoundArgs, class _TupleUj,\n          bool = __is_valid_bind_return<_Fp, _BoundArgs, _TupleUj>::value>\nstruct __bind_return;\n\ntemplate <class _Fp, class ..._BoundArgs, class _TupleUj>\nstruct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true>\n{\n    typedef typename __invoke_of\n    <\n        _Fp&,\n        typename __mu_return\n        <\n            _BoundArgs,\n            _TupleUj\n        >::type...\n    >::type type;\n};\n\ntemplate <class _Fp, class ..._BoundArgs, class _TupleUj>\nstruct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true>\n{\n    typedef typename __invoke_of\n    <\n        _Fp&,\n        typename __mu_return\n        <\n            const _BoundArgs,\n            _TupleUj\n        >::type...\n    >::type type;\n};\n\ntemplate <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __bind_return<_Fp, _BoundArgs, _Args>::type\n__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,\n                _Args&& __args)\n{\n    return __invoke(__f, __mu(_VSTD::get<_Indx>(__bound_args), __args)...);\n}\n\ntemplate<class _Fp, class ..._BoundArgs>\nclass __bind\n    : public __weak_result_type<typename decay<_Fp>::type>\n{\nprotected:\n    typedef typename decay<_Fp>::type _Fd;\n    typedef tuple<typename decay<_BoundArgs>::type...> _Td;\nprivate:\n    _Fd __f_;\n    _Td __bound_args_;\n\n    typedef typename __make_tuple_indices<sizeof...(_BoundArgs)>::type __indices;\npublic:\n#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bind(const __bind& __b)\n        : __f_(__b.__f_),\n          __bound_args_(__b.__bound_args_) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bind& operator=(const __bind& __b)\n    {\n        __f_ = __b.__f_;\n        __bound_args_ = __b.__bound_args_;\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bind(__bind&& __b)\n        : __f_(_VSTD::move(__b.__f_)),\n          __bound_args_(_VSTD::move(__b.__bound_args_)) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bind& operator=(__bind&& __b)\n    {\n        __f_ = _VSTD::move(__b.__f_);\n        __bound_args_ = _VSTD::move(__b.__bound_args_);\n        return *this;\n    }\n\n#endif  // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n\n    template <class _Gp, class ..._BA,\n              class = typename enable_if\n                               <\n                                  is_constructible<_Fd, _Gp>::value &&\n                                  !is_same<typename remove_reference<_Gp>::type,\n                                           __bind>::value\n                               >::type>\n      _LIBCPP_INLINE_VISIBILITY\n      explicit __bind(_Gp&& __f, _BA&& ...__bound_args)\n        : __f_(_VSTD::forward<_Gp>(__f)),\n          __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {}\n\n    template <class ..._Args>\n        _LIBCPP_INLINE_VISIBILITY\n        typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type\n        operator()(_Args&& ...__args)\n        {\n            return __apply_functor(__f_, __bound_args_, __indices(),\n                                  tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));\n        }\n\n    template <class ..._Args>\n        _LIBCPP_INLINE_VISIBILITY\n        typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type\n        operator()(_Args&& ...__args) const\n        {\n            return __apply_functor(__f_, __bound_args_, __indices(),\n                                   tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));\n        }\n};\n\ntemplate<class _Fp, class ..._BoundArgs>\nstruct __is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {};\n\ntemplate<class _Rp, class _Fp, class ..._BoundArgs>\nclass __bind_r\n    : public __bind<_Fp, _BoundArgs...>\n{\n    typedef __bind<_Fp, _BoundArgs...> base;\n    typedef typename base::_Fd _Fd;\n    typedef typename base::_Td _Td;\npublic:\n    typedef _Rp result_type;\n\n#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bind_r(const __bind_r& __b)\n        : base(_VSTD::forward<const base&>(__b)) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bind_r& operator=(const __bind_r& __b)\n    {\n        base::operator=(_VSTD::forward<const base&>(__b));\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bind_r(__bind_r&& __b)\n        : base(_VSTD::forward<base>(__b)) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bind_r& operator=(__bind_r&& __b)\n    {\n        base::operator=(_VSTD::forward<base>(__b));\n        return *this;\n    }\n\n#endif  // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n\n    template <class _Gp, class ..._BA,\n              class = typename enable_if\n                               <\n                                  is_constructible<_Fd, _Gp>::value &&\n                                  !is_same<typename remove_reference<_Gp>::type,\n                                           __bind_r>::value\n                               >::type>\n      _LIBCPP_INLINE_VISIBILITY\n      explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args)\n        : base(_VSTD::forward<_Gp>(__f),\n               _VSTD::forward<_BA>(__bound_args)...) {}\n\n    template <class ..._Args>\n        _LIBCPP_INLINE_VISIBILITY\n        typename enable_if\n        <\n            is_convertible<typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type,\n                           result_type>::value || is_void<_Rp>::value,\n            result_type\n        >::type\n        operator()(_Args&& ...__args)\n        {\n            typedef __invoke_void_return_wrapper<_Rp> _Invoker;\n            return _Invoker::__call(static_cast<base&>(*this), _VSTD::forward<_Args>(__args)...);\n        }\n\n    template <class ..._Args>\n        _LIBCPP_INLINE_VISIBILITY\n        typename enable_if\n        <\n            is_convertible<typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type,\n                           result_type>::value || is_void<_Rp>::value,\n            result_type\n        >::type\n        operator()(_Args&& ...__args) const\n        {\n            typedef __invoke_void_return_wrapper<_Rp> _Invoker;\n            return _Invoker::__call(static_cast<base const&>(*this), _VSTD::forward<_Args>(__args)...);\n        }\n};\n\ntemplate<class _Rp, class _Fp, class ..._BoundArgs>\nstruct __is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};\n\ntemplate<class _Fp, class ..._BoundArgs>\ninline _LIBCPP_INLINE_VISIBILITY\n__bind<_Fp, _BoundArgs...>\nbind(_Fp&& __f, _BoundArgs&&... __bound_args)\n{\n    typedef __bind<_Fp, _BoundArgs...> type;\n    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);\n}\n\ntemplate<class _Rp, class _Fp, class ..._BoundArgs>\ninline _LIBCPP_INLINE_VISIBILITY\n__bind_r<_Rp, _Fp, _BoundArgs...>\nbind(_Fp&& __f, _BoundArgs&&... __bound_args)\n{\n    typedef __bind_r<_Rp, _Fp, _BoundArgs...> type;\n    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<bool>\n    : public unary_function<bool, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(bool __v) const _NOEXCEPT {return static_cast<size_t>(__v);}\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<char>\n    : public unary_function<char, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<signed char>\n    : public unary_function<signed char, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(signed char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<unsigned char>\n    : public unary_function<unsigned char, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}\n};\n\n#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<char16_t>\n    : public unary_function<char16_t, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<char32_t>\n    : public unary_function<char32_t, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}\n};\n\n#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<wchar_t>\n    : public unary_function<wchar_t, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<short>\n    : public unary_function<short, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<unsigned short>\n    : public unary_function<unsigned short, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<int>\n    : public unary_function<int, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<unsigned int>\n    : public unary_function<unsigned int, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<long>\n    : public unary_function<long, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<unsigned long>\n    : public unary_function<unsigned long, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<long long>\n    : public __scalar_hash<long long>\n{\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<unsigned long long>\n    : public __scalar_hash<unsigned long long>\n{\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<float>\n    : public __scalar_hash<float>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(float __v) const _NOEXCEPT\n    {\n        // -0.0 and 0.0 should return same hash\n       if (__v == 0)\n           return 0;\n        return __scalar_hash<float>::operator()(__v);\n    }\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<double>\n    : public __scalar_hash<double>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(double __v) const _NOEXCEPT\n    {\n        // -0.0 and 0.0 should return same hash\n       if (__v == 0)\n           return 0;\n        return __scalar_hash<double>::operator()(__v);\n    }\n};\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<long double>\n    : public __scalar_hash<long double>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(long double __v) const _NOEXCEPT\n    {\n        // -0.0 and 0.0 should return same hash\n        if (__v == 0)\n            return 0;\n#if defined(__i386__)\n        // Zero out padding bits\n        union\n        {\n            long double __t;\n            struct\n            {\n                size_t __a;\n                size_t __b;\n                size_t __c;\n                size_t __d;\n            } __s;\n        } __u;\n        __u.__s.__a = 0;\n        __u.__s.__b = 0;\n        __u.__s.__c = 0;\n        __u.__s.__d = 0;\n        __u.__t = __v;\n        return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d;\n#elif defined(__x86_64__)\n        // Zero out padding bits\n        union\n        {\n            long double __t;\n            struct\n            {\n                size_t __a;\n                size_t __b;\n            } __s;\n        } __u;\n        __u.__s.__a = 0;\n        __u.__s.__b = 0;\n        __u.__t = __v;\n        return __u.__s.__a ^ __u.__s.__b;\n#else\n        return __scalar_hash<long double>::operator()(__v);\n#endif\n    }\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY hash\n    : public unary_function<_Tp, size_t>\n{\n    static_assert(is_enum<_Tp>::value, \"This hash only works for enumeration types\");\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(_Tp __v) const _NOEXCEPT\n    {\n        typedef typename underlying_type<_Tp>::type type;\n        return hash<type>{}(static_cast<type>(__v));\n    }\n};\n#endif\n\n\n#if _LIBCPP_STD_VER > 14\ntemplate <class _Fn, class ..._Args>\nresult_of_t<_Fn&&(_Args&&...)>\ninvoke(_Fn&& __f, _Args&&... __args) {\n    return __invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);\n}\n#endif\n\n// struct hash<T*> in <memory>\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_FUNCTIONAL\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/future",
    "content": "// -*- C++ -*-\n//===--------------------------- future -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_FUTURE\n#define _LIBCPP_FUTURE\n\n/*\n    future synopsis\n\nnamespace std\n{\n\nenum class future_errc\n{\n    future_already_retrieved = 1,\n    promise_already_satisfied,\n    no_state,\n    broken_promise\n};\n\nenum class launch\n{\n    async = 1,\n    deferred = 2,\n    any = async | deferred\n};\n\nenum class future_status\n{\n    ready,\n    timeout,\n    deferred\n};\n\ntemplate <> struct is_error_code_enum<future_errc> : public true_type { };\nerror_code make_error_code(future_errc e) noexcept;\nerror_condition make_error_condition(future_errc e) noexcept;\n\nconst error_category& future_category() noexcept;\n\nclass future_error\n    : public logic_error\n{\npublic:\n    future_error(error_code ec);  // exposition only\n\n    const error_code& code() const noexcept;\n    const char*       what() const noexcept;\n};\n\ntemplate <class R>\nclass promise\n{\npublic:\n    promise();\n    template <class Allocator>\n        promise(allocator_arg_t, const Allocator& a);\n    promise(promise&& rhs) noexcept;\n    promise(const promise& rhs) = delete;\n    ~promise();\n\n    // assignment\n    promise& operator=(promise&& rhs) noexcept;\n    promise& operator=(const promise& rhs) = delete;\n    void swap(promise& other) noexcept;\n\n    // retrieving the result\n    future<R> get_future();\n\n    // setting the result\n    void set_value(const R& r);\n    void set_value(R&& r);\n    void set_exception(exception_ptr p);\n\n    // setting the result with deferred notification\n    void set_value_at_thread_exit(const R& r);\n    void set_value_at_thread_exit(R&& r);\n    void set_exception_at_thread_exit(exception_ptr p);\n};\n\ntemplate <class R>\nclass promise<R&>\n{\npublic:\n    promise();\n    template <class Allocator>\n        promise(allocator_arg_t, const Allocator& a);\n    promise(promise&& rhs) noexcept;\n    promise(const promise& rhs) = delete;\n    ~promise();\n\n    // assignment\n    promise& operator=(promise&& rhs) noexcept;\n    promise& operator=(const promise& rhs) = delete;\n    void swap(promise& other) noexcept;\n\n    // retrieving the result\n    future<R&> get_future();\n\n    // setting the result\n    void set_value(R& r);\n    void set_exception(exception_ptr p);\n\n    // setting the result with deferred notification\n    void set_value_at_thread_exit(R&);\n    void set_exception_at_thread_exit(exception_ptr p);\n};\n\ntemplate <>\nclass promise<void>\n{\npublic:\n    promise();\n    template <class Allocator>\n        promise(allocator_arg_t, const Allocator& a);\n    promise(promise&& rhs) noexcept;\n    promise(const promise& rhs) = delete;\n    ~promise();\n\n    // assignment\n    promise& operator=(promise&& rhs) noexcept;\n    promise& operator=(const promise& rhs) = delete;\n    void swap(promise& other) noexcept;\n\n    // retrieving the result\n    future<void> get_future();\n\n    // setting the result\n    void set_value();\n    void set_exception(exception_ptr p);\n\n    // setting the result with deferred notification\n    void set_value_at_thread_exit();\n    void set_exception_at_thread_exit(exception_ptr p);\n};\n\ntemplate <class R> void swap(promise<R>& x, promise<R>& y) noexcept;\n\ntemplate <class R, class Alloc>\n    struct uses_allocator<promise<R>, Alloc> : public true_type {};\n\ntemplate <class R>\nclass future\n{\npublic:\n    future() noexcept;\n    future(future&&) noexcept;\n    future(const future& rhs) = delete;\n    ~future();\n    future& operator=(const future& rhs) = delete;\n    future& operator=(future&&) noexcept;\n    shared_future<R> share();\n\n    // retrieving the value\n    R get();\n\n    // functions to check state\n    bool valid() const noexcept;\n\n    void wait() const;\n    template <class Rep, class Period>\n        future_status\n        wait_for(const chrono::duration<Rep, Period>& rel_time) const;\n    template <class Clock, class Duration>\n        future_status\n        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;\n};\n\ntemplate <class R>\nclass future<R&>\n{\npublic:\n    future() noexcept;\n    future(future&&) noexcept;\n    future(const future& rhs) = delete;\n    ~future();\n    future& operator=(const future& rhs) = delete;\n    future& operator=(future&&) noexcept;\n    shared_future<R&> share();\n\n    // retrieving the value\n    R& get();\n\n    // functions to check state\n    bool valid() const noexcept;\n\n    void wait() const;\n    template <class Rep, class Period>\n        future_status\n        wait_for(const chrono::duration<Rep, Period>& rel_time) const;\n    template <class Clock, class Duration>\n        future_status\n        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;\n};\n\ntemplate <>\nclass future<void>\n{\npublic:\n    future() noexcept;\n    future(future&&) noexcept;\n    future(const future& rhs) = delete;\n    ~future();\n    future& operator=(const future& rhs) = delete;\n    future& operator=(future&&) noexcept;\n    shared_future<void> share();\n\n    // retrieving the value\n    void get();\n\n    // functions to check state\n    bool valid() const noexcept;\n\n    void wait() const;\n    template <class Rep, class Period>\n        future_status\n        wait_for(const chrono::duration<Rep, Period>& rel_time) const;\n    template <class Clock, class Duration>\n        future_status\n        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;\n};\n\ntemplate <class R>\nclass shared_future\n{\npublic:\n    shared_future() noexcept;\n    shared_future(const shared_future& rhs);\n    shared_future(future<R>&&) noexcept;\n    shared_future(shared_future&& rhs) noexcept;\n    ~shared_future();\n    shared_future& operator=(const shared_future& rhs);\n    shared_future& operator=(shared_future&& rhs) noexcept;\n\n    // retrieving the value\n    const R& get() const;\n\n    // functions to check state\n    bool valid() const noexcept;\n\n    void wait() const;\n    template <class Rep, class Period>\n        future_status\n        wait_for(const chrono::duration<Rep, Period>& rel_time) const;\n    template <class Clock, class Duration>\n        future_status\n        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;\n};\n\ntemplate <class R>\nclass shared_future<R&>\n{\npublic:\n    shared_future() noexcept;\n    shared_future(const shared_future& rhs);\n    shared_future(future<R&>&&) noexcept;\n    shared_future(shared_future&& rhs) noexcept;\n    ~shared_future();\n    shared_future& operator=(const shared_future& rhs);\n    shared_future& operator=(shared_future&& rhs) noexcept;\n\n    // retrieving the value\n    R& get() const;\n\n    // functions to check state\n    bool valid() const noexcept;\n\n    void wait() const;\n    template <class Rep, class Period>\n        future_status\n        wait_for(const chrono::duration<Rep, Period>& rel_time) const;\n    template <class Clock, class Duration>\n        future_status\n        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;\n};\n\ntemplate <>\nclass shared_future<void>\n{\npublic:\n    shared_future() noexcept;\n    shared_future(const shared_future& rhs);\n    shared_future(future<void>&&) noexcept;\n    shared_future(shared_future&& rhs) noexcept;\n    ~shared_future();\n    shared_future& operator=(const shared_future& rhs);\n    shared_future& operator=(shared_future&& rhs) noexcept;\n\n    // retrieving the value\n    void get() const;\n\n    // functions to check state\n    bool valid() const noexcept;\n\n    void wait() const;\n    template <class Rep, class Period>\n        future_status\n        wait_for(const chrono::duration<Rep, Period>& rel_time) const;\n    template <class Clock, class Duration>\n        future_status\n        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;\n};\n\ntemplate <class F, class... Args>\n  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>\n  async(F&& f, Args&&... args);\n\ntemplate <class F, class... Args>\n  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>\n  async(launch policy, F&& f, Args&&... args);\n\ntemplate <class> class packaged_task; // undefined\n\ntemplate <class R, class... ArgTypes>\nclass packaged_task<R(ArgTypes...)>\n{\npublic:\n    typedef R result_type;\n\n    // construction and destruction\n    packaged_task() noexcept;\n    template <class F>\n        explicit packaged_task(F&& f);\n    template <class F, class Allocator>\n        packaged_task(allocator_arg_t, const Allocator& a, F&& f);\n    ~packaged_task();\n\n    // no copy\n    packaged_task(const packaged_task&) = delete;\n    packaged_task& operator=(const packaged_task&) = delete;\n\n    // move support\n    packaged_task(packaged_task&& other) noexcept;\n    packaged_task& operator=(packaged_task&& other) noexcept;\n    void swap(packaged_task& other) noexcept;\n\n    bool valid() const noexcept;\n\n    // result retrieval\n    future<R> get_future();\n\n    // execution\n    void operator()(ArgTypes... );\n    void make_ready_at_thread_exit(ArgTypes...);\n\n    void reset();\n};\n\ntemplate <class R>\n  void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;\n\ntemplate <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;\n\n}  // std\n\n*/\n\n#include <__config>\n#include <system_error>\n#include <memory>\n#include <chrono>\n#include <exception>\n#include <mutex>\n#include <thread>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#ifdef _LIBCPP_HAS_NO_THREADS\n#error <future> is not supported on this single threaded system\n#else // !_LIBCPP_HAS_NO_THREADS\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n//enum class future_errc\n_LIBCPP_DECLARE_STRONG_ENUM(future_errc)\n{\n    future_already_retrieved = 1,\n    promise_already_satisfied,\n    no_state,\n    broken_promise\n};\n_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc> : public true_type {};\n\n#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc::__lx> : public true_type { };\n#endif\n\n//enum class launch\n_LIBCPP_DECLARE_STRONG_ENUM(launch)\n{\n    async = 1,\n    deferred = 2,\n    any = async | deferred\n};\n_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)\n\n#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS\n\n#ifdef _LIBCXX_UNDERLYING_TYPE\ntypedef underlying_type<launch>::type __launch_underlying_type;\n#else\ntypedef int __launch_underlying_type;\n#endif\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nlaunch\noperator&(launch __x, launch __y)\n{\n    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &\n                               static_cast<__launch_underlying_type>(__y));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nlaunch\noperator|(launch __x, launch __y)\n{\n    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |\n                               static_cast<__launch_underlying_type>(__y));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nlaunch\noperator^(launch __x, launch __y)\n{\n    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^\n                               static_cast<__launch_underlying_type>(__y));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nlaunch\noperator~(launch __x)\n{\n    return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nlaunch&\noperator&=(launch& __x, launch __y)\n{\n    __x = __x & __y; return __x;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nlaunch&\noperator|=(launch& __x, launch __y)\n{\n    __x = __x | __y; return __x;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nlaunch&\noperator^=(launch& __x, launch __y)\n{\n    __x = __x ^ __y; return __x;\n}\n\n#endif  // !_LIBCPP_HAS_NO_STRONG_ENUMS\n\n//enum class future_status\n_LIBCPP_DECLARE_STRONG_ENUM(future_status)\n{\n    ready,\n    timeout,\n    deferred\n};\n_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)\n\n_LIBCPP_FUNC_VIS\nconst error_category& future_category() _NOEXCEPT;\n\ninline _LIBCPP_INLINE_VISIBILITY\nerror_code\nmake_error_code(future_errc __e) _NOEXCEPT\n{\n    return error_code(static_cast<int>(__e), future_category());\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nerror_condition\nmake_error_condition(future_errc __e) _NOEXCEPT\n{\n    return error_condition(static_cast<int>(__e), future_category());\n}\n\nclass _LIBCPP_EXCEPTION_ABI future_error\n    : public logic_error\n{\n    error_code __ec_;\npublic:\n    future_error(error_code __ec);\n\n    _LIBCPP_INLINE_VISIBILITY\n    const error_code& code() const _NOEXCEPT {return __ec_;}\n\n    virtual ~future_error() _NOEXCEPT;\n};\n\nclass _LIBCPP_TYPE_VIS __assoc_sub_state\n    : public __shared_count\n{\nprotected:\n    exception_ptr __exception_;\n    mutable mutex __mut_;\n    mutable condition_variable __cv_;\n    unsigned __state_;\n\n    virtual void __on_zero_shared() _NOEXCEPT;\n    void __sub_wait(unique_lock<mutex>& __lk);\npublic:\n    enum\n    {\n        __constructed = 1,\n        __future_attached = 2,\n        ready = 4,\n        deferred = 8\n    };\n\n    _LIBCPP_INLINE_VISIBILITY\n    __assoc_sub_state() : __state_(0) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool __has_value() const\n        {return (__state_ & __constructed) || (__exception_ != nullptr);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __set_future_attached()\n    {\n        lock_guard<mutex> __lk(__mut_);\n        __state_ |= __future_attached;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __set_deferred() {__state_ |= deferred;}\n\n    void __make_ready();\n    _LIBCPP_INLINE_VISIBILITY\n    bool __is_ready() const {return (__state_ & ready) != 0;}\n\n    void set_value();\n    void set_value_at_thread_exit();\n\n    void set_exception(exception_ptr __p);\n    void set_exception_at_thread_exit(exception_ptr __p);\n\n    void copy();\n\n    void wait();\n    template <class _Rep, class _Period>\n        future_status\n        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;\n    template <class _Clock, class _Duration>\n        future_status\n        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;\n\n    virtual void __execute();\n};\n\ntemplate <class _Clock, class _Duration>\nfuture_status\n__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const\n{\n    unique_lock<mutex> __lk(__mut_);\n    if (__state_ & deferred)\n        return future_status::deferred;\n    while (!(__state_ & ready) && _Clock::now() < __abs_time)\n        __cv_.wait_until(__lk, __abs_time);\n    if (__state_ & ready)\n        return future_status::ready;\n    return future_status::timeout;\n}\n\ntemplate <class _Rep, class _Period>\ninline _LIBCPP_INLINE_VISIBILITY\nfuture_status\n__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const\n{\n    return wait_until(chrono::steady_clock::now() + __rel_time);\n}\n\ntemplate <class _Rp>\nclass __assoc_state\n    : public __assoc_sub_state\n{\n    typedef __assoc_sub_state base;\n    typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;\nprotected:\n    _Up __value_;\n\n    virtual void __on_zero_shared() _NOEXCEPT;\npublic:\n\n    template <class _Arg>\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n        void set_value(_Arg&& __arg);\n#else\n        void set_value(_Arg& __arg);\n#endif\n\n    template <class _Arg>\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n        void set_value_at_thread_exit(_Arg&& __arg);\n#else\n        void set_value_at_thread_exit(_Arg& __arg);\n#endif\n\n    _Rp move();\n    typename add_lvalue_reference<_Rp>::type copy();\n};\n\ntemplate <class _Rp>\nvoid\n__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT\n{\n    if (this->__state_ & base::__constructed)\n        reinterpret_cast<_Rp*>(&__value_)->~_Rp();\n    delete this;\n}\n\ntemplate <class _Rp>\ntemplate <class _Arg>\nvoid\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n__assoc_state<_Rp>::set_value(_Arg&& __arg)\n#else\n__assoc_state<_Rp>::set_value(_Arg& __arg)\n#endif\n{\n    unique_lock<mutex> __lk(this->__mut_);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (this->__has_value())\n        throw future_error(make_error_code(future_errc::promise_already_satisfied));\n#endif\n    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));\n    this->__state_ |= base::__constructed | base::ready;\n    __cv_.notify_all();\n}\n\ntemplate <class _Rp>\ntemplate <class _Arg>\nvoid\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)\n#else\n__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)\n#endif\n{\n    unique_lock<mutex> __lk(this->__mut_);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (this->__has_value())\n        throw future_error(make_error_code(future_errc::promise_already_satisfied));\n#endif\n    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));\n    this->__state_ |= base::__constructed;\n    __thread_local_data()->__make_ready_at_thread_exit(this);\n}\n\ntemplate <class _Rp>\n_Rp\n__assoc_state<_Rp>::move()\n{\n    unique_lock<mutex> __lk(this->__mut_);\n    this->__sub_wait(__lk);\n    if (this->__exception_ != nullptr)\n        rethrow_exception(this->__exception_);\n    return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));\n}\n\ntemplate <class _Rp>\ntypename add_lvalue_reference<_Rp>::type\n__assoc_state<_Rp>::copy()\n{\n    unique_lock<mutex> __lk(this->__mut_);\n    this->__sub_wait(__lk);\n    if (this->__exception_ != nullptr)\n        rethrow_exception(this->__exception_);\n    return *reinterpret_cast<_Rp*>(&__value_);\n}\n\ntemplate <class _Rp>\nclass __assoc_state<_Rp&>\n    : public __assoc_sub_state\n{\n    typedef __assoc_sub_state base;\n    typedef _Rp* _Up;\nprotected:\n    _Up __value_;\n\n    virtual void __on_zero_shared() _NOEXCEPT;\npublic:\n\n    void set_value(_Rp& __arg);\n    void set_value_at_thread_exit(_Rp& __arg);\n\n    _Rp& copy();\n};\n\ntemplate <class _Rp>\nvoid\n__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT\n{\n    delete this;\n}\n\ntemplate <class _Rp>\nvoid\n__assoc_state<_Rp&>::set_value(_Rp& __arg)\n{\n    unique_lock<mutex> __lk(this->__mut_);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (this->__has_value())\n        throw future_error(make_error_code(future_errc::promise_already_satisfied));\n#endif\n    __value_ = _VSTD::addressof(__arg);\n    this->__state_ |= base::__constructed | base::ready;\n    __cv_.notify_all();\n}\n\ntemplate <class _Rp>\nvoid\n__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)\n{\n    unique_lock<mutex> __lk(this->__mut_);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (this->__has_value())\n        throw future_error(make_error_code(future_errc::promise_already_satisfied));\n#endif\n    __value_ = _VSTD::addressof(__arg);\n    this->__state_ |= base::__constructed;\n    __thread_local_data()->__make_ready_at_thread_exit(this);\n}\n\ntemplate <class _Rp>\n_Rp&\n__assoc_state<_Rp&>::copy()\n{\n    unique_lock<mutex> __lk(this->__mut_);\n    this->__sub_wait(__lk);\n    if (this->__exception_ != nullptr)\n        rethrow_exception(this->__exception_);\n    return *__value_;\n}\n\ntemplate <class _Rp, class _Alloc>\nclass __assoc_state_alloc\n    : public __assoc_state<_Rp>\n{\n    typedef __assoc_state<_Rp> base;\n    _Alloc __alloc_;\n\n    virtual void __on_zero_shared() _NOEXCEPT;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __assoc_state_alloc(const _Alloc& __a)\n        : __alloc_(__a) {}\n};\n\ntemplate <class _Rp, class _Alloc>\nvoid\n__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT\n{\n    if (this->__state_ & base::__constructed)\n        reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();\n    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;\n    typedef allocator_traits<_Al> _ATraits;\n    typedef pointer_traits<typename _ATraits::pointer> _PTraits;\n    _Al __a(__alloc_);\n    this->~__assoc_state_alloc();\n    __a.deallocate(_PTraits::pointer_to(*this), 1);\n}\n\ntemplate <class _Rp, class _Alloc>\nclass __assoc_state_alloc<_Rp&, _Alloc>\n    : public __assoc_state<_Rp&>\n{\n    typedef __assoc_state<_Rp&> base;\n    _Alloc __alloc_;\n\n    virtual void __on_zero_shared() _NOEXCEPT;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __assoc_state_alloc(const _Alloc& __a)\n        : __alloc_(__a) {}\n};\n\ntemplate <class _Rp, class _Alloc>\nvoid\n__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT\n{\n    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;\n    typedef allocator_traits<_Al> _ATraits;\n    typedef pointer_traits<typename _ATraits::pointer> _PTraits;\n    _Al __a(__alloc_);\n    this->~__assoc_state_alloc();\n    __a.deallocate(_PTraits::pointer_to(*this), 1);\n}\n\ntemplate <class _Alloc>\nclass __assoc_sub_state_alloc\n    : public __assoc_sub_state\n{\n    typedef __assoc_sub_state base;\n    _Alloc __alloc_;\n\n    virtual void __on_zero_shared() _NOEXCEPT;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __assoc_sub_state_alloc(const _Alloc& __a)\n        : __alloc_(__a) {}\n};\n\ntemplate <class _Alloc>\nvoid\n__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT\n{\n    typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;\n    typedef allocator_traits<_Al> _ATraits;\n    typedef pointer_traits<typename _ATraits::pointer> _PTraits;\n    _Al __a(__alloc_);\n    this->~__assoc_sub_state_alloc();\n    __a.deallocate(_PTraits::pointer_to(*this), 1);\n}\n\ntemplate <class _Rp, class _Fp>\nclass __deferred_assoc_state\n    : public __assoc_state<_Rp>\n{\n    typedef __assoc_state<_Rp> base;\n\n    _Fp __func_;\n\npublic:\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    explicit __deferred_assoc_state(_Fp&& __f);\n#endif\n\n    virtual void __execute();\n};\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Rp, class _Fp>\ninline _LIBCPP_INLINE_VISIBILITY\n__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)\n    : __func_(_VSTD::forward<_Fp>(__f))\n{\n    this->__set_deferred();\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Rp, class _Fp>\nvoid\n__deferred_assoc_state<_Rp, _Fp>::__execute()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        this->set_value(__func_());\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->set_exception(current_exception());\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate <class _Fp>\nclass __deferred_assoc_state<void, _Fp>\n    : public __assoc_sub_state\n{\n    typedef __assoc_sub_state base;\n\n    _Fp __func_;\n\npublic:\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    explicit __deferred_assoc_state(_Fp&& __f);\n#endif\n\n    virtual void __execute();\n};\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Fp>\ninline _LIBCPP_INLINE_VISIBILITY\n__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)\n    : __func_(_VSTD::forward<_Fp>(__f))\n{\n    this->__set_deferred();\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Fp>\nvoid\n__deferred_assoc_state<void, _Fp>::__execute()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        __func_();\n        this->set_value();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->set_exception(current_exception());\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate <class _Rp, class _Fp>\nclass __async_assoc_state\n    : public __assoc_state<_Rp>\n{\n    typedef __assoc_state<_Rp> base;\n\n    _Fp __func_;\n\n    virtual void __on_zero_shared() _NOEXCEPT;\npublic:\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    explicit __async_assoc_state(_Fp&& __f);\n#endif\n\n    virtual void __execute();\n};\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Rp, class _Fp>\ninline _LIBCPP_INLINE_VISIBILITY\n__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)\n    : __func_(_VSTD::forward<_Fp>(__f))\n{\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Rp, class _Fp>\nvoid\n__async_assoc_state<_Rp, _Fp>::__execute()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        this->set_value(__func_());\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->set_exception(current_exception());\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate <class _Rp, class _Fp>\nvoid\n__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT\n{\n    this->wait();\n    base::__on_zero_shared();\n}\n\ntemplate <class _Fp>\nclass __async_assoc_state<void, _Fp>\n    : public __assoc_sub_state\n{\n    typedef __assoc_sub_state base;\n\n    _Fp __func_;\n\n    virtual void __on_zero_shared() _NOEXCEPT;\npublic:\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    explicit __async_assoc_state(_Fp&& __f);\n#endif\n\n    virtual void __execute();\n};\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Fp>\ninline _LIBCPP_INLINE_VISIBILITY\n__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)\n    : __func_(_VSTD::forward<_Fp>(__f))\n{\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Fp>\nvoid\n__async_assoc_state<void, _Fp>::__execute()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        __func_();\n        this->set_value();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->set_exception(current_exception());\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate <class _Fp>\nvoid\n__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT\n{\n    this->wait();\n    base::__on_zero_shared();\n}\n\ntemplate <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise;\ntemplate <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future;\n\n// future\n\ntemplate <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future;\n\ntemplate <class _Rp, class _Fp>\nfuture<_Rp>\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n__make_deferred_assoc_state(_Fp&& __f);\n#else\n__make_deferred_assoc_state(_Fp __f);\n#endif\n\ntemplate <class _Rp, class _Fp>\nfuture<_Rp>\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n__make_async_assoc_state(_Fp&& __f);\n#else\n__make_async_assoc_state(_Fp __f);\n#endif\n\ntemplate <class _Rp>\nclass _LIBCPP_TYPE_VIS_ONLY future\n{\n    __assoc_state<_Rp>* __state_;\n\n    explicit future(__assoc_state<_Rp>* __state);\n\n    template <class> friend class promise;\n    template <class> friend class shared_future;\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _R1, class _Fp>\n        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);\n    template <class _R1, class _Fp>\n        friend future<_R1> __make_async_assoc_state(_Fp&& __f);\n#else\n    template <class _R1, class _Fp>\n        friend future<_R1> __make_deferred_assoc_state(_Fp __f);\n    template <class _R1, class _Fp>\n        friend future<_R1> __make_async_assoc_state(_Fp __f);\n#endif\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    future() _NOEXCEPT : __state_(nullptr) {}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    future(future&& __rhs) _NOEXCEPT\n        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}\n    future(const future&) = delete;\n    future& operator=(const future&) = delete;\n    _LIBCPP_INLINE_VISIBILITY\n    future& operator=(future&& __rhs) _NOEXCEPT\n        {\n            future(std::move(__rhs)).swap(*this);\n            return *this;\n        }\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\nprivate:\n    future(const future&);\n    future& operator=(const future&);\npublic:\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    ~future();\n    shared_future<_Rp> share();\n\n    // retrieving the value\n    _Rp get();\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}\n\n    // functions to check state\n    _LIBCPP_INLINE_VISIBILITY\n    bool valid() const _NOEXCEPT {return __state_ != nullptr;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void wait() const {__state_->wait();}\n    template <class _Rep, class _Period>\n        _LIBCPP_INLINE_VISIBILITY\n        future_status\n        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const\n            {return __state_->wait_for(__rel_time);}\n    template <class _Clock, class _Duration>\n        _LIBCPP_INLINE_VISIBILITY\n        future_status\n        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const\n            {return __state_->wait_until(__abs_time);}\n};\n\ntemplate <class _Rp>\nfuture<_Rp>::future(__assoc_state<_Rp>* __state)\n    : __state_(__state)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_->__has_future_attached())\n        throw future_error(make_error_code(future_errc::future_already_retrieved));\n#endif\n    __state_->__add_shared();\n    __state_->__set_future_attached();\n}\n\nstruct __release_shared_count\n{\n    void operator()(__shared_count* p) {p->__release_shared();}\n};\n\ntemplate <class _Rp>\nfuture<_Rp>::~future()\n{\n    if (__state_)\n        __state_->__release_shared();\n}\n\ntemplate <class _Rp>\n_Rp\nfuture<_Rp>::get()\n{\n    unique_ptr<__shared_count, __release_shared_count> __(__state_);\n    __assoc_state<_Rp>* __s = __state_;\n    __state_ = nullptr;\n    return __s->move();\n}\n\ntemplate <class _Rp>\nclass _LIBCPP_TYPE_VIS_ONLY future<_Rp&>\n{\n    __assoc_state<_Rp&>* __state_;\n\n    explicit future(__assoc_state<_Rp&>* __state);\n\n    template <class> friend class promise;\n    template <class> friend class shared_future;\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _R1, class _Fp>\n        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);\n    template <class _R1, class _Fp>\n        friend future<_R1> __make_async_assoc_state(_Fp&& __f);\n#else\n    template <class _R1, class _Fp>\n        friend future<_R1> __make_deferred_assoc_state(_Fp __f);\n    template <class _R1, class _Fp>\n        friend future<_R1> __make_async_assoc_state(_Fp __f);\n#endif\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    future() _NOEXCEPT : __state_(nullptr) {}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    future(future&& __rhs) _NOEXCEPT\n        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}\n    future(const future&) = delete;\n    future& operator=(const future&) = delete;\n    _LIBCPP_INLINE_VISIBILITY\n    future& operator=(future&& __rhs) _NOEXCEPT\n        {\n            future(std::move(__rhs)).swap(*this);\n            return *this;\n        }\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\nprivate:\n    future(const future&);\n    future& operator=(const future&);\npublic:\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    ~future();\n    shared_future<_Rp&> share();\n\n    // retrieving the value\n    _Rp& get();\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}\n\n    // functions to check state\n    _LIBCPP_INLINE_VISIBILITY\n    bool valid() const _NOEXCEPT {return __state_ != nullptr;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void wait() const {__state_->wait();}\n    template <class _Rep, class _Period>\n        _LIBCPP_INLINE_VISIBILITY\n        future_status\n        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const\n            {return __state_->wait_for(__rel_time);}\n    template <class _Clock, class _Duration>\n        _LIBCPP_INLINE_VISIBILITY\n        future_status\n        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const\n            {return __state_->wait_until(__abs_time);}\n};\n\ntemplate <class _Rp>\nfuture<_Rp&>::future(__assoc_state<_Rp&>* __state)\n    : __state_(__state)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_->__has_future_attached())\n        throw future_error(make_error_code(future_errc::future_already_retrieved));\n#endif\n    __state_->__add_shared();\n    __state_->__set_future_attached();\n}\n\ntemplate <class _Rp>\nfuture<_Rp&>::~future()\n{\n    if (__state_)\n        __state_->__release_shared();\n}\n\ntemplate <class _Rp>\n_Rp&\nfuture<_Rp&>::get()\n{\n    unique_ptr<__shared_count, __release_shared_count> __(__state_);\n    __assoc_state<_Rp&>* __s = __state_;\n    __state_ = nullptr;\n    return __s->copy();\n}\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS future<void>\n{\n    __assoc_sub_state* __state_;\n\n    explicit future(__assoc_sub_state* __state);\n\n    template <class> friend class promise;\n    template <class> friend class shared_future;\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _R1, class _Fp>\n        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);\n    template <class _R1, class _Fp>\n        friend future<_R1> __make_async_assoc_state(_Fp&& __f);\n#else\n    template <class _R1, class _Fp>\n        friend future<_R1> __make_deferred_assoc_state(_Fp __f);\n    template <class _R1, class _Fp>\n        friend future<_R1> __make_async_assoc_state(_Fp __f);\n#endif\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    future() _NOEXCEPT : __state_(nullptr) {}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    future(future&& __rhs) _NOEXCEPT\n        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}\n    future(const future&) = delete;\n    future& operator=(const future&) = delete;\n    _LIBCPP_INLINE_VISIBILITY\n    future& operator=(future&& __rhs) _NOEXCEPT\n        {\n            future(std::move(__rhs)).swap(*this);\n            return *this;\n        }\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\nprivate:\n    future(const future&);\n    future& operator=(const future&);\npublic:\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    ~future();\n    shared_future<void> share();\n\n    // retrieving the value\n    void get();\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}\n\n    // functions to check state\n    _LIBCPP_INLINE_VISIBILITY\n    bool valid() const _NOEXCEPT {return __state_ != nullptr;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void wait() const {__state_->wait();}\n    template <class _Rep, class _Period>\n        _LIBCPP_INLINE_VISIBILITY\n        future_status\n        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const\n            {return __state_->wait_for(__rel_time);}\n    template <class _Clock, class _Duration>\n        _LIBCPP_INLINE_VISIBILITY\n        future_status\n        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const\n            {return __state_->wait_until(__abs_time);}\n};\n\ntemplate <class _Rp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT\n{\n    __x.swap(__y);\n}\n\n// promise<R>\n\ntemplate <class _Callable> class packaged_task;\n\ntemplate <class _Rp>\nclass _LIBCPP_TYPE_VIS_ONLY promise\n{\n    __assoc_state<_Rp>* __state_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}\n\n    template <class> friend class packaged_task;\npublic:\n    promise();\n    template <class _Alloc>\n        promise(allocator_arg_t, const _Alloc& __a);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    promise(promise&& __rhs) _NOEXCEPT\n        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}\n    promise(const promise& __rhs) = delete;\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\nprivate:\n    promise(const promise& __rhs);\npublic:\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    ~promise();\n\n    // assignment\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    promise& operator=(promise&& __rhs) _NOEXCEPT\n        {\n            promise(std::move(__rhs)).swap(*this);\n            return *this;\n        }\n    promise& operator=(const promise& __rhs) = delete;\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\nprivate:\n    promise& operator=(const promise& __rhs);\npublic:\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}\n\n    // retrieving the result\n    future<_Rp> get_future();\n\n    // setting the result\n    void set_value(const _Rp& __r);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void set_value(_Rp&& __r);\n#endif\n    void set_exception(exception_ptr __p);\n\n    // setting the result with deferred notification\n    void set_value_at_thread_exit(const _Rp& __r);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void set_value_at_thread_exit(_Rp&& __r);\n#endif\n    void set_exception_at_thread_exit(exception_ptr __p);\n};\n\ntemplate <class _Rp>\npromise<_Rp>::promise()\n    : __state_(new __assoc_state<_Rp>)\n{\n}\n\ntemplate <class _Rp>\ntemplate <class _Alloc>\npromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)\n{\n    typedef __assoc_state_alloc<_Rp, _Alloc> _State;\n    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;\n    typedef __allocator_destructor<_A2> _D2;\n    _A2 __a(__a0);\n    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));\n    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);\n    __state_ = _VSTD::addressof(*__hold.release());\n}\n\ntemplate <class _Rp>\npromise<_Rp>::~promise()\n{\n    if (__state_)\n    {\n        if (!__state_->__has_value() && __state_->use_count() > 1)\n            __state_->set_exception(make_exception_ptr(\n                      future_error(make_error_code(future_errc::broken_promise))\n                                                      ));\n        __state_->__release_shared();\n    }\n}\n\ntemplate <class _Rp>\nfuture<_Rp>\npromise<_Rp>::get_future()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    return future<_Rp>(__state_);\n}\n\ntemplate <class _Rp>\nvoid\npromise<_Rp>::set_value(const _Rp& __r)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    __state_->set_value(__r);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Rp>\nvoid\npromise<_Rp>::set_value(_Rp&& __r)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    __state_->set_value(_VSTD::move(__r));\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Rp>\nvoid\npromise<_Rp>::set_exception(exception_ptr __p)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    __state_->set_exception(__p);\n}\n\ntemplate <class _Rp>\nvoid\npromise<_Rp>::set_value_at_thread_exit(const _Rp& __r)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    __state_->set_value_at_thread_exit(__r);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Rp>\nvoid\npromise<_Rp>::set_value_at_thread_exit(_Rp&& __r)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    __state_->set_value_at_thread_exit(_VSTD::move(__r));\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Rp>\nvoid\npromise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    __state_->set_exception_at_thread_exit(__p);\n}\n\n// promise<R&>\n\ntemplate <class _Rp>\nclass _LIBCPP_TYPE_VIS_ONLY promise<_Rp&>\n{\n    __assoc_state<_Rp&>* __state_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}\n\n    template <class> friend class packaged_task;\n\npublic:\n    promise();\n    template <class _Allocator>\n        promise(allocator_arg_t, const _Allocator& __a);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    promise(promise&& __rhs) _NOEXCEPT\n        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}\n    promise(const promise& __rhs) = delete;\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\nprivate:\n    promise(const promise& __rhs);\npublic:\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    ~promise();\n\n    // assignment\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    promise& operator=(promise&& __rhs) _NOEXCEPT\n        {\n            promise(std::move(__rhs)).swap(*this);\n            return *this;\n        }\n    promise& operator=(const promise& __rhs) = delete;\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\nprivate:\n    promise& operator=(const promise& __rhs);\npublic:\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}\n\n    // retrieving the result\n    future<_Rp&> get_future();\n\n    // setting the result\n    void set_value(_Rp& __r);\n    void set_exception(exception_ptr __p);\n\n    // setting the result with deferred notification\n    void set_value_at_thread_exit(_Rp&);\n    void set_exception_at_thread_exit(exception_ptr __p);\n};\n\ntemplate <class _Rp>\npromise<_Rp&>::promise()\n    : __state_(new __assoc_state<_Rp&>)\n{\n}\n\ntemplate <class _Rp>\ntemplate <class _Alloc>\npromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)\n{\n    typedef __assoc_state_alloc<_Rp&, _Alloc> _State;\n    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;\n    typedef __allocator_destructor<_A2> _D2;\n    _A2 __a(__a0);\n    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));\n    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);\n    __state_ = _VSTD::addressof(*__hold.release());\n}\n\ntemplate <class _Rp>\npromise<_Rp&>::~promise()\n{\n    if (__state_)\n    {\n        if (!__state_->__has_value() && __state_->use_count() > 1)\n            __state_->set_exception(make_exception_ptr(\n                      future_error(make_error_code(future_errc::broken_promise))\n                                                      ));\n        __state_->__release_shared();\n    }\n}\n\ntemplate <class _Rp>\nfuture<_Rp&>\npromise<_Rp&>::get_future()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    return future<_Rp&>(__state_);\n}\n\ntemplate <class _Rp>\nvoid\npromise<_Rp&>::set_value(_Rp& __r)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    __state_->set_value(__r);\n}\n\ntemplate <class _Rp>\nvoid\npromise<_Rp&>::set_exception(exception_ptr __p)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    __state_->set_exception(__p);\n}\n\ntemplate <class _Rp>\nvoid\npromise<_Rp&>::set_value_at_thread_exit(_Rp& __r)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    __state_->set_value_at_thread_exit(__r);\n}\n\ntemplate <class _Rp>\nvoid\npromise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    __state_->set_exception_at_thread_exit(__p);\n}\n\n// promise<void>\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS promise<void>\n{\n    __assoc_sub_state* __state_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}\n\n    template <class> friend class packaged_task;\n\npublic:\n    promise();\n    template <class _Allocator>\n        promise(allocator_arg_t, const _Allocator& __a);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    promise(promise&& __rhs) _NOEXCEPT\n        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}\n    promise(const promise& __rhs) = delete;\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\nprivate:\n    promise(const promise& __rhs);\npublic:\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    ~promise();\n\n    // assignment\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    promise& operator=(promise&& __rhs) _NOEXCEPT\n        {\n            promise(std::move(__rhs)).swap(*this);\n            return *this;\n        }\n    promise& operator=(const promise& __rhs) = delete;\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\nprivate:\n    promise& operator=(const promise& __rhs);\npublic:\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}\n\n    // retrieving the result\n    future<void> get_future();\n\n    // setting the result\n    void set_value();\n    void set_exception(exception_ptr __p);\n\n    // setting the result with deferred notification\n    void set_value_at_thread_exit();\n    void set_exception_at_thread_exit(exception_ptr __p);\n};\n\ntemplate <class _Alloc>\npromise<void>::promise(allocator_arg_t, const _Alloc& __a0)\n{\n    typedef __assoc_sub_state_alloc<_Alloc> _State;\n    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;\n    typedef __allocator_destructor<_A2> _D2;\n    _A2 __a(__a0);\n    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));\n    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);\n    __state_ = _VSTD::addressof(*__hold.release());\n}\n\ntemplate <class _Rp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Rp, class _Alloc>\n    struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc>\n        : public true_type {};\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n// packaged_task\n\ntemplate<class _Fp> class __packaged_task_base;\n\ntemplate<class _Rp, class ..._ArgTypes>\nclass __packaged_task_base<_Rp(_ArgTypes...)>\n{\n    __packaged_task_base(const __packaged_task_base&);\n    __packaged_task_base& operator=(const __packaged_task_base&);\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __packaged_task_base() {}\n    _LIBCPP_INLINE_VISIBILITY\n    virtual ~__packaged_task_base() {}\n    virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;\n    virtual void destroy() = 0;\n    virtual void destroy_deallocate() = 0;\n    virtual _Rp operator()(_ArgTypes&& ...) = 0;\n};\n\ntemplate<class _FD, class _Alloc, class _FB> class __packaged_task_func;\n\ntemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>\nclass __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>\n    : public  __packaged_task_base<_Rp(_ArgTypes...)>\n{\n    __compressed_pair<_Fp, _Alloc> __f_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    __packaged_task_func(const _Fp& __f, const _Alloc& __a)\n        : __f_(__f, __a) {}\n    _LIBCPP_INLINE_VISIBILITY\n    __packaged_task_func(_Fp&& __f, const _Alloc& __a)\n        : __f_(_VSTD::move(__f), __a) {}\n    virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;\n    virtual void destroy();\n    virtual void destroy_deallocate();\n    virtual _Rp operator()(_ArgTypes&& ... __args);\n};\n\ntemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>\nvoid\n__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(\n                              __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT\n{\n    ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>\nvoid\n__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()\n{\n    __f_.~__compressed_pair<_Fp, _Alloc>();\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>\nvoid\n__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()\n{\n    typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;\n    typedef allocator_traits<_Ap> _ATraits;\n    typedef pointer_traits<typename _ATraits::pointer> _PTraits;\n    _Ap __a(__f_.second());\n    __f_.~__compressed_pair<_Fp, _Alloc>();\n    __a.deallocate(_PTraits::pointer_to(*this), 1);\n}\n\ntemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>\n_Rp\n__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)\n{\n    return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);\n}\n\ntemplate <class _Callable> class __packaged_task_function;\n\ntemplate<class _Rp, class ..._ArgTypes>\nclass __packaged_task_function<_Rp(_ArgTypes...)>\n{\n    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;\n    typename aligned_storage<3*sizeof(void*)>::type __buf_;\n    __base* __f_;\n\npublic:\n    typedef _Rp result_type;\n\n    // construct/copy/destroy:\n    _LIBCPP_INLINE_VISIBILITY\n    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}\n    template<class _Fp>\n      __packaged_task_function(_Fp&& __f);\n    template<class _Fp, class _Alloc>\n      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);\n\n    __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;\n    __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;\n\n    __packaged_task_function(const __packaged_task_function&) =  delete;\n    __packaged_task_function& operator=(const __packaged_task_function&) =  delete;\n\n    ~__packaged_task_function();\n\n    void swap(__packaged_task_function&) _NOEXCEPT;\n\n    _Rp operator()(_ArgTypes...) const;\n};\n\ntemplate<class _Rp, class ..._ArgTypes>\n__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT\n{\n    if (__f.__f_ == nullptr)\n        __f_ = nullptr;\n    else if (__f.__f_ == (__base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__move_to(__f_);\n    }\n    else\n    {\n        __f_ = __f.__f_;\n        __f.__f_ = nullptr;\n    }\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\ntemplate <class _Fp>\n__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)\n    : __f_(nullptr)\n{\n    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;\n    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;\n    if (sizeof(_FF) <= sizeof(__buf_))\n    {\n        __f_ = (__base*)&__buf_;\n        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));\n    }\n    else\n    {\n        typedef allocator<_FF> _Ap;\n        _Ap __a;\n        typedef __allocator_destructor<_Ap> _Dp;\n        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));\n        __f_ = __hold.release();\n    }\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\ntemplate <class _Fp, class _Alloc>\n__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(\n                                  allocator_arg_t, const _Alloc& __a0, _Fp&& __f)\n    : __f_(nullptr)\n{\n    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;\n    typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;\n    if (sizeof(_FF) <= sizeof(__buf_))\n    {\n        __f_ = (__base*)&__buf_;\n        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));\n    }\n    else\n    {\n        typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;\n        _Ap __a(__a0);\n        typedef __allocator_destructor<_Ap> _Dp;\n        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));\n        ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))\n            _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));\n        __f_ = _VSTD::addressof(*__hold.release());\n    }\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\n__packaged_task_function<_Rp(_ArgTypes...)>&\n__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT\n{\n    if (__f_ == (__base*)&__buf_)\n        __f_->destroy();\n    else if (__f_)\n        __f_->destroy_deallocate();\n    __f_ = nullptr;\n    if (__f.__f_ == nullptr)\n        __f_ = nullptr;\n    else if (__f.__f_ == (__base*)&__f.__buf_)\n    {\n        __f_ = (__base*)&__buf_;\n        __f.__f_->__move_to(__f_);\n    }\n    else\n    {\n        __f_ = __f.__f_;\n        __f.__f_ = nullptr;\n    }\n    return *this;\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\n__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()\n{\n    if (__f_ == (__base*)&__buf_)\n        __f_->destroy();\n    else if (__f_)\n        __f_->destroy_deallocate();\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\nvoid\n__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT\n{\n    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)\n    {\n        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;\n        __base* __t = (__base*)&__tempbuf;\n        __f_->__move_to(__t);\n        __f_->destroy();\n        __f_ = nullptr;\n        __f.__f_->__move_to((__base*)&__buf_);\n        __f.__f_->destroy();\n        __f.__f_ = nullptr;\n        __f_ = (__base*)&__buf_;\n        __t->__move_to((__base*)&__f.__buf_);\n        __t->destroy();\n        __f.__f_ = (__base*)&__f.__buf_;\n    }\n    else if (__f_ == (__base*)&__buf_)\n    {\n        __f_->__move_to((__base*)&__f.__buf_);\n        __f_->destroy();\n        __f_ = __f.__f_;\n        __f.__f_ = (__base*)&__f.__buf_;\n    }\n    else if (__f.__f_ == (__base*)&__f.__buf_)\n    {\n        __f.__f_->__move_to((__base*)&__buf_);\n        __f.__f_->destroy();\n        __f.__f_ = __f_;\n        __f_ = (__base*)&__buf_;\n    }\n    else\n        _VSTD::swap(__f_, __f.__f_);\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\ninline _LIBCPP_INLINE_VISIBILITY\n_Rp\n__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const\n{\n    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\nclass _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)>\n{\npublic:\n    typedef _Rp result_type;\n\nprivate:\n    __packaged_task_function<result_type(_ArgTypes...)> __f_;\n    promise<result_type>                                __p_;\n\npublic:\n    // construction and destruction\n    _LIBCPP_INLINE_VISIBILITY\n    packaged_task() _NOEXCEPT : __p_(nullptr) {}\n    template <class _Fp,\n              class = typename enable_if\n              <\n                  !is_same<\n                      typename decay<_Fp>::type, \n                      packaged_task\n                      >::value\n                  >::type\n             >\n        _LIBCPP_INLINE_VISIBILITY\n        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}\n    template <class _Fp, class _Allocator,\n              class = typename enable_if\n              <\n                  !is_same<\n                      typename decay<_Fp>::type, \n                      packaged_task\n                      >::value\n                  >::type\n              >\n        _LIBCPP_INLINE_VISIBILITY\n        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)\n             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),\n               __p_(allocator_arg, __a) {}\n    // ~packaged_task() = default;\n\n    // no copy\n    packaged_task(const packaged_task&) = delete;\n    packaged_task& operator=(const packaged_task&) = delete;\n\n    // move support\n    _LIBCPP_INLINE_VISIBILITY\n    packaged_task(packaged_task&& __other) _NOEXCEPT\n        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT\n    {\n        __f_ = _VSTD::move(__other.__f_);\n        __p_ = _VSTD::move(__other.__p_);\n        return *this;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(packaged_task& __other) _NOEXCEPT\n    {\n        __f_.swap(__other.__f_);\n        __p_.swap(__other.__p_);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}\n\n    // result retrieval\n    _LIBCPP_INLINE_VISIBILITY\n    future<result_type> get_future() {return __p_.get_future();}\n\n    // execution\n    void operator()(_ArgTypes... __args);\n    void make_ready_at_thread_exit(_ArgTypes... __args);\n\n    void reset();\n};\n\ntemplate<class _Rp, class ..._ArgTypes>\nvoid\npackaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__p_.__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n    if (__p_.__state_->__has_value())\n        throw future_error(make_error_code(future_errc::promise_already_satisfied));\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __p_.set_exception(current_exception());\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\nvoid\npackaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__p_.__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n    if (__p_.__state_->__has_value())\n        throw future_error(make_error_code(future_errc::promise_already_satisfied));\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __p_.set_exception_at_thread_exit(current_exception());\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate<class _Rp, class ..._ArgTypes>\nvoid\npackaged_task<_Rp(_ArgTypes...)>::reset()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (!valid())\n        throw future_error(make_error_code(future_errc::no_state));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    __p_ = promise<result_type>();\n}\n\ntemplate<class ..._ArgTypes>\nclass _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)>\n{\npublic:\n    typedef void result_type;\n\nprivate:\n    __packaged_task_function<result_type(_ArgTypes...)> __f_;\n    promise<result_type>                                __p_;\n\npublic:\n    // construction and destruction\n    _LIBCPP_INLINE_VISIBILITY\n    packaged_task() _NOEXCEPT : __p_(nullptr) {}\n    template <class _Fp,\n              class = typename enable_if\n              <\n                  !is_same<\n                      typename decay<_Fp>::type, \n                      packaged_task\n                      >::value\n                  >::type\n              >\n        _LIBCPP_INLINE_VISIBILITY\n        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}\n    template <class _Fp, class _Allocator,\n              class = typename enable_if\n              <\n                  !is_same<\n                      typename decay<_Fp>::type, \n                      packaged_task\n                      >::value\n                  >::type\n              >    \n        _LIBCPP_INLINE_VISIBILITY\n        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)\n             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),\n               __p_(allocator_arg, __a) {}\n    // ~packaged_task() = default;\n\n    // no copy\n    packaged_task(const packaged_task&) = delete;\n    packaged_task& operator=(const packaged_task&) = delete;\n\n    // move support\n    _LIBCPP_INLINE_VISIBILITY\n    packaged_task(packaged_task&& __other) _NOEXCEPT\n        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT\n    {\n        __f_ = _VSTD::move(__other.__f_);\n        __p_ = _VSTD::move(__other.__p_);\n        return *this;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(packaged_task& __other) _NOEXCEPT\n    {\n        __f_.swap(__other.__f_);\n        __p_.swap(__other.__p_);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}\n\n    // result retrieval\n    _LIBCPP_INLINE_VISIBILITY\n    future<result_type> get_future() {return __p_.get_future();}\n\n    // execution\n    void operator()(_ArgTypes... __args);\n    void make_ready_at_thread_exit(_ArgTypes... __args);\n\n    void reset();\n};\n\ntemplate<class ..._ArgTypes>\nvoid\npackaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__p_.__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n    if (__p_.__state_->__has_value())\n        throw future_error(make_error_code(future_errc::promise_already_satisfied));\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        __f_(_VSTD::forward<_ArgTypes>(__args)...);\n        __p_.set_value();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __p_.set_exception(current_exception());\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate<class ..._ArgTypes>\nvoid\npackaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__p_.__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n    if (__p_.__state_->__has_value())\n        throw future_error(make_error_code(future_errc::promise_already_satisfied));\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        __f_(_VSTD::forward<_ArgTypes>(__args)...);\n        __p_.set_value_at_thread_exit();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __p_.set_exception_at_thread_exit(current_exception());\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate<class ..._ArgTypes>\nvoid\npackaged_task<void(_ArgTypes...)>::reset()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (!valid())\n        throw future_error(make_error_code(future_errc::no_state));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    __p_ = promise<result_type>();\n}\n\ntemplate <class _Callable>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Callable, class _Alloc>\nstruct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc>\n    : public true_type {};\n\ntemplate <class _Rp, class _Fp>\nfuture<_Rp>\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n__make_deferred_assoc_state(_Fp&& __f)\n#else\n__make_deferred_assoc_state(_Fp __f)\n#endif\n{\n    unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>\n        __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));\n    return future<_Rp>(__h.get());\n}\n\ntemplate <class _Rp, class _Fp>\nfuture<_Rp>\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n__make_async_assoc_state(_Fp&& __f)\n#else\n__make_async_assoc_state(_Fp __f)\n#endif\n{\n    unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>\n        __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));\n    _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();\n    return future<_Rp>(__h.get());\n}\n\ntemplate <class _Fp, class... _Args>\nclass __async_func\n{\n    tuple<_Fp, _Args...> __f_;\n\npublic:\n    typedef typename __invoke_of<_Fp, _Args...>::type _Rp;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __async_func(_Fp&& __f, _Args&&... __args)\n        : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}\n\n    _Rp operator()()\n    {\n        typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;\n        return __execute(_Index());\n    }\nprivate:\n    template <size_t ..._Indices>\n    _Rp\n    __execute(__tuple_indices<_Indices...>)\n    {\n        return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);\n    }\n};\n\ninline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )\n{ return (int(__policy) & int(__value)) != 0; }\n\ntemplate <class _Fp, class... _Args>\nfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>\nasync(launch __policy, _Fp&& __f, _Args&&... __args)\n{\n    typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;\n    typedef typename _BF::_Rp _Rp;\n\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif\n        if (__does_policy_contain(__policy, launch::async))\n        return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),\n                                                     __decay_copy(_VSTD::forward<_Args>(__args))...));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch ( ... ) { if (__policy == launch::async) throw ; }\n#endif\n\n    if (__does_policy_contain(__policy, launch::deferred))\n        return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),\n                                                        __decay_copy(_VSTD::forward<_Args>(__args))...));\n    return future<_Rp>{};\n}\n\ntemplate <class _Fp, class... _Args>\ninline _LIBCPP_INLINE_VISIBILITY\nfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>\nasync(_Fp&& __f, _Args&&... __args)\n{\n    return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),\n                                    _VSTD::forward<_Args>(__args)...);\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n// shared_future\n\ntemplate <class _Rp>\nclass _LIBCPP_TYPE_VIS_ONLY shared_future\n{\n    __assoc_state<_Rp>* __state_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future() _NOEXCEPT : __state_(nullptr) {}\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)\n        {if (__state_) __state_->__add_shared();}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)\n        {__f.__state_ = nullptr;}\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)\n        {__rhs.__state_ = nullptr;}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    ~shared_future();\n    shared_future& operator=(const shared_future& __rhs);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT\n        {\n            shared_future(std::move(__rhs)).swap(*this);\n            return *this;\n        }\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    // retrieving the value\n    _LIBCPP_INLINE_VISIBILITY\n    const _Rp& get() const {return __state_->copy();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}\n\n    // functions to check state\n    _LIBCPP_INLINE_VISIBILITY\n    bool valid() const _NOEXCEPT {return __state_ != nullptr;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void wait() const {__state_->wait();}\n    template <class _Rep, class _Period>\n        _LIBCPP_INLINE_VISIBILITY\n        future_status\n        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const\n            {return __state_->wait_for(__rel_time);}\n    template <class _Clock, class _Duration>\n        _LIBCPP_INLINE_VISIBILITY\n        future_status\n        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const\n            {return __state_->wait_until(__abs_time);}\n};\n\ntemplate <class _Rp>\nshared_future<_Rp>::~shared_future()\n{\n    if (__state_)\n        __state_->__release_shared();\n}\n\ntemplate <class _Rp>\nshared_future<_Rp>&\nshared_future<_Rp>::operator=(const shared_future& __rhs)\n{\n    if (__rhs.__state_)\n        __rhs.__state_->__add_shared();\n    if (__state_)\n        __state_->__release_shared();\n    __state_ = __rhs.__state_;\n    return *this;\n}\n\ntemplate <class _Rp>\nclass _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&>\n{\n    __assoc_state<_Rp&>* __state_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future() _NOEXCEPT : __state_(nullptr) {}\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)\n        {if (__state_) __state_->__add_shared();}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)\n        {__f.__state_ = nullptr;}\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)\n        {__rhs.__state_ = nullptr;}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    ~shared_future();\n    shared_future& operator=(const shared_future& __rhs);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT\n        {\n            shared_future(std::move(__rhs)).swap(*this);\n            return *this;\n        }\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    // retrieving the value\n    _LIBCPP_INLINE_VISIBILITY\n    _Rp& get() const {return __state_->copy();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}\n\n    // functions to check state\n    _LIBCPP_INLINE_VISIBILITY\n    bool valid() const _NOEXCEPT {return __state_ != nullptr;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void wait() const {__state_->wait();}\n    template <class _Rep, class _Period>\n        _LIBCPP_INLINE_VISIBILITY\n        future_status\n        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const\n            {return __state_->wait_for(__rel_time);}\n    template <class _Clock, class _Duration>\n        _LIBCPP_INLINE_VISIBILITY\n        future_status\n        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const\n            {return __state_->wait_until(__abs_time);}\n};\n\ntemplate <class _Rp>\nshared_future<_Rp&>::~shared_future()\n{\n    if (__state_)\n        __state_->__release_shared();\n}\n\ntemplate <class _Rp>\nshared_future<_Rp&>&\nshared_future<_Rp&>::operator=(const shared_future& __rhs)\n{\n    if (__rhs.__state_)\n        __rhs.__state_->__add_shared();\n    if (__state_)\n        __state_->__release_shared();\n    __state_ = __rhs.__state_;\n    return *this;\n}\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS shared_future<void>\n{\n    __assoc_sub_state* __state_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future() _NOEXCEPT : __state_(nullptr) {}\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)\n        {if (__state_) __state_->__add_shared();}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)\n        {__f.__state_ = nullptr;}\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)\n        {__rhs.__state_ = nullptr;}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    ~shared_future();\n    shared_future& operator=(const shared_future& __rhs);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT\n        {\n            shared_future(std::move(__rhs)).swap(*this);\n            return *this;\n        }\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    // retrieving the value\n    _LIBCPP_INLINE_VISIBILITY\n    void get() const {__state_->copy();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}\n\n    // functions to check state\n    _LIBCPP_INLINE_VISIBILITY\n    bool valid() const _NOEXCEPT {return __state_ != nullptr;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void wait() const {__state_->wait();}\n    template <class _Rep, class _Period>\n        _LIBCPP_INLINE_VISIBILITY\n        future_status\n        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const\n            {return __state_->wait_for(__rel_time);}\n    template <class _Clock, class _Duration>\n        _LIBCPP_INLINE_VISIBILITY\n        future_status\n        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const\n            {return __state_->wait_until(__abs_time);}\n};\n\ntemplate <class _Rp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Rp>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_future<_Rp>\nfuture<_Rp>::share()\n{\n    return shared_future<_Rp>(_VSTD::move(*this));\n}\n\ntemplate <class _Rp>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_future<_Rp&>\nfuture<_Rp&>::share()\n{\n    return shared_future<_Rp&>(_VSTD::move(*this));\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ninline _LIBCPP_INLINE_VISIBILITY\nshared_future<void>\nfuture<void>::share()\n{\n    return shared_future<void>(_VSTD::move(*this));\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif // !_LIBCPP_HAS_NO_THREADS\n\n#endif  // _LIBCPP_FUTURE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/initializer_list",
    "content": "// -*- C++ -*-\n//===----------------------- initializer_list -----------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_INITIALIZER_LIST\n#define _LIBCPP_INITIALIZER_LIST\n\n/*\n    initializer_list synopsis\n\nnamespace std\n{\n\ntemplate<class E>\nclass initializer_list\n{\npublic:\n    typedef E        value_type;\n    typedef const E& reference;\n    typedef const E& const_reference;\n    typedef size_t   size_type;\n\n    typedef const E* iterator;\n    typedef const E* const_iterator;\n\n    initializer_list() noexcept; // constexpr in C++14\n\n    size_t   size()  const noexcept; // constexpr in C++14\n    const E* begin() const noexcept; // constexpr in C++14\n    const E* end()   const noexcept; // constexpr in C++14\n};\n\ntemplate<class E> const E* begin(initializer_list<E> il) noexcept; // constexpr in C++14\ntemplate<class E> const E* end(initializer_list<E> il) noexcept; // constexpr in C++14\n\n}  // std\n\n*/\n\n#include <__config>\n#include <cstddef>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\nnamespace std  // purposefully not versioned\n{\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate<class _Ep>\nclass _LIBCPP_TYPE_VIS_ONLY initializer_list\n{\n    const _Ep* __begin_;\n    size_t    __size_;\n\n    _LIBCPP_ALWAYS_INLINE\n    _LIBCPP_CONSTEXPR_AFTER_CXX11\n    initializer_list(const _Ep* __b, size_t __s) _NOEXCEPT\n        : __begin_(__b),\n          __size_(__s)\n        {}\npublic:\n    typedef _Ep        value_type;\n    typedef const _Ep& reference;\n    typedef const _Ep& const_reference;\n    typedef size_t    size_type;\n\n    typedef const _Ep* iterator;\n    typedef const _Ep* const_iterator;\n\n    _LIBCPP_ALWAYS_INLINE\n    _LIBCPP_CONSTEXPR_AFTER_CXX11\n    initializer_list() _NOEXCEPT : __begin_(nullptr), __size_(0) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    _LIBCPP_CONSTEXPR_AFTER_CXX11\n    size_t    size()  const _NOEXCEPT {return __size_;}\n    \n    _LIBCPP_ALWAYS_INLINE\n    _LIBCPP_CONSTEXPR_AFTER_CXX11\n    const _Ep* begin() const _NOEXCEPT {return __begin_;}\n\n    _LIBCPP_ALWAYS_INLINE\n    _LIBCPP_CONSTEXPR_AFTER_CXX11\n    const _Ep* end()   const _NOEXCEPT {return __begin_ + __size_;}\n};\n\ntemplate<class _Ep>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR_AFTER_CXX11\nconst _Ep*\nbegin(initializer_list<_Ep> __il) _NOEXCEPT\n{\n    return __il.begin();\n}\n\ntemplate<class _Ep>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR_AFTER_CXX11\nconst _Ep*\nend(initializer_list<_Ep> __il) _NOEXCEPT\n{\n    return __il.end();\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n}  // std\n\n#endif  // _LIBCPP_INITIALIZER_LIST\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/iomanip",
    "content": "// -*- C++ -*-\n//===--------------------------- iomanip ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_IOMANIP\n#define _LIBCPP_IOMANIP\n\n/*\n    iomanip synopsis\n\nnamespace std {\n\n// types T1, T2, ... are unspecified implementation types\nT1 resetiosflags(ios_base::fmtflags mask);\nT2 setiosflags (ios_base::fmtflags mask);\nT3 setbase(int base);\ntemplate<charT> T4 setfill(charT c);\nT5 setprecision(int n);\nT6 setw(int n);\ntemplate <class moneyT> T7 get_money(moneyT& mon, bool intl = false);\ntemplate <class charT, class moneyT> T8 put_money(const moneyT& mon, bool intl = false);\ntemplate <class charT> T9 get_time(struct tm* tmb, const charT* fmt);\ntemplate <class charT> T10 put_time(const struct tm* tmb, const charT* fmt);\n\ntemplate <class charT>\n  T11 quoted(const charT* s, charT delim=charT('\"'), charT escape=charT('\\\\')); // C++14\n\ntemplate <class charT, class traits, class Allocator>\n  T12 quoted(const basic_string<charT, traits, Allocator>& s,\n             charT delim=charT('\"'), charT escape=charT('\\\\')); // C++14\n\ntemplate <class charT, class traits, class Allocator>\n  T13 quoted(basic_string<charT, traits, Allocator>& s,\n             charT delim=charT('\"'), charT escape=charT('\\\\')); // C++14\n\n}  // std\n\n*/\n\n#include <__config>\n#include <istream>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n// resetiosflags\n\nclass __iom_t1\n{\n    ios_base::fmtflags __mask_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __iom_t1(ios_base::fmtflags __m) : __mask_(__m) {}\n\n    template <class _CharT, class _Traits>\n    friend\n    _LIBCPP_INLINE_VISIBILITY\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t1& __x)\n    {\n        __is.unsetf(__x.__mask_);\n        return __is;\n    }\n\n    template <class _CharT, class _Traits>\n    friend\n    _LIBCPP_INLINE_VISIBILITY\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t1& __x)\n    {\n        __os.unsetf(__x.__mask_);\n        return __os;\n    }\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\n__iom_t1\nresetiosflags(ios_base::fmtflags __mask)\n{\n    return __iom_t1(__mask);\n}\n\n// setiosflags\n\nclass __iom_t2\n{\n    ios_base::fmtflags __mask_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __iom_t2(ios_base::fmtflags __m) : __mask_(__m) {}\n\n    template <class _CharT, class _Traits>\n    friend\n    _LIBCPP_INLINE_VISIBILITY\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t2& __x)\n    {\n        __is.setf(__x.__mask_);\n        return __is;\n    }\n\n    template <class _CharT, class _Traits>\n    friend\n    _LIBCPP_INLINE_VISIBILITY\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t2& __x)\n    {\n        __os.setf(__x.__mask_);\n        return __os;\n    }\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\n__iom_t2\nsetiosflags(ios_base::fmtflags __mask)\n{\n    return __iom_t2(__mask);\n}\n\n// setbase\n\nclass __iom_t3\n{\n    int __base_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __iom_t3(int __b) : __base_(__b) {}\n\n    template <class _CharT, class _Traits>\n    friend\n    _LIBCPP_INLINE_VISIBILITY\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t3& __x)\n    {\n        __is.setf(__x.__base_ == 8  ? ios_base::oct :\n                  __x.__base_ == 10 ? ios_base::dec :\n                  __x.__base_ == 16 ? ios_base::hex :\n                  ios_base::fmtflags(0), ios_base::basefield);\n        return __is;\n    }\n\n    template <class _CharT, class _Traits>\n    friend\n    _LIBCPP_INLINE_VISIBILITY\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t3& __x)\n    {\n        __os.setf(__x.__base_ == 8  ? ios_base::oct :\n                  __x.__base_ == 10 ? ios_base::dec :\n                  __x.__base_ == 16 ? ios_base::hex :\n                  ios_base::fmtflags(0), ios_base::basefield);\n        return __os;\n    }\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\n__iom_t3\nsetbase(int __base)\n{\n    return __iom_t3(__base);\n}\n\n// setfill\n\ntemplate<class _CharT>\nclass __iom_t4\n{\n    _CharT __fill_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __iom_t4(_CharT __c) : __fill_(__c) {}\n\n    template <class _Traits>\n    friend\n    _LIBCPP_INLINE_VISIBILITY\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t4& __x)\n    {\n        __os.fill(__x.__fill_);\n        return __os;\n    }\n};\n\ntemplate<class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\n__iom_t4<_CharT>\nsetfill(_CharT __c)\n{\n    return __iom_t4<_CharT>(__c);\n}\n\n// setprecision\n\nclass __iom_t5\n{\n    int __n_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __iom_t5(int __n) : __n_(__n) {}\n\n    template <class _CharT, class _Traits>\n    friend\n    _LIBCPP_INLINE_VISIBILITY\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t5& __x)\n    {\n        __is.precision(__x.__n_);\n        return __is;\n    }\n\n    template <class _CharT, class _Traits>\n    friend\n    _LIBCPP_INLINE_VISIBILITY\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t5& __x)\n    {\n        __os.precision(__x.__n_);\n        return __os;\n    }\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\n__iom_t5\nsetprecision(int __n)\n{\n    return __iom_t5(__n);\n}\n\n// setw\n\nclass __iom_t6\n{\n    int __n_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __iom_t6(int __n) : __n_(__n) {}\n\n    template <class _CharT, class _Traits>\n    friend\n    _LIBCPP_INLINE_VISIBILITY\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t6& __x)\n    {\n        __is.width(__x.__n_);\n        return __is;\n    }\n\n    template <class _CharT, class _Traits>\n    friend\n    _LIBCPP_INLINE_VISIBILITY\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t6& __x)\n    {\n        __os.width(__x.__n_);\n        return __os;\n    }\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\n__iom_t6\nsetw(int __n)\n{\n    return __iom_t6(__n);\n}\n\n// get_money\n\ntemplate <class _MoneyT> class __iom_t7;\n\ntemplate <class _CharT, class _Traits, class _MoneyT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x);\n\ntemplate <class _MoneyT>\nclass __iom_t7\n{\n    _MoneyT& __mon_;\n    bool __intl_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __iom_t7(_MoneyT& __mon, bool __intl)\n        : __mon_(__mon), __intl_(__intl) {}\n\n    template <class _CharT, class _Traits, class _Mp>\n    friend\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_Mp>& __x);\n};\n\ntemplate <class _CharT, class _Traits, class _MoneyT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typename basic_istream<_CharT, _Traits>::sentry __s(__is);\n        if (__s)\n        {\n            typedef istreambuf_iterator<_CharT, _Traits> _Ip;\n            typedef money_get<_CharT, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            const _Fp& __mf = use_facet<_Fp>(__is.getloc());\n            __mf.get(_Ip(__is), _Ip(), __x.__intl_, __is, __err, __x.__mon_);\n            __is.setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __is.__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __is;\n}\n\ntemplate <class _MoneyT>\ninline _LIBCPP_INLINE_VISIBILITY\n__iom_t7<_MoneyT>\nget_money(_MoneyT& __mon, bool __intl = false)\n{\n    return __iom_t7<_MoneyT>(__mon, __intl);\n}\n\n// put_money\n\ntemplate <class _MoneyT> class __iom_t8;\n\ntemplate <class _CharT, class _Traits, class _MoneyT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x);\n\ntemplate <class _MoneyT>\nclass __iom_t8\n{\n    const _MoneyT& __mon_;\n    bool __intl_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __iom_t8(const _MoneyT& __mon, bool __intl)\n        : __mon_(__mon), __intl_(__intl) {}\n\n    template <class _CharT, class _Traits, class _Mp>\n    friend\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_Mp>& __x);\n};\n\ntemplate <class _CharT, class _Traits, class _MoneyT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typename basic_ostream<_CharT, _Traits>::sentry __s(__os);\n        if (__s)\n        {\n            typedef ostreambuf_iterator<_CharT, _Traits> _Op;\n            typedef money_put<_CharT, _Op> _Fp;\n            const _Fp& __mf = use_facet<_Fp>(__os.getloc());\n            if (__mf.put(_Op(__os), __x.__intl_, __os, __os.fill(), __x.__mon_).failed())\n                __os.setstate(ios_base::badbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __os.__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __os;\n}\n\ntemplate <class _MoneyT>\ninline _LIBCPP_INLINE_VISIBILITY\n__iom_t8<_MoneyT>\nput_money(const _MoneyT& __mon, bool __intl = false)\n{\n    return __iom_t8<_MoneyT>(__mon, __intl);\n}\n\n// get_time\n\ntemplate <class _CharT> class __iom_t9;\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x);\n\ntemplate <class _CharT>\nclass __iom_t9\n{\n    tm* __tm_;\n    const _CharT* __fmt_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __iom_t9(tm* __tm, const _CharT* __fmt)\n        : __tm_(__tm), __fmt_(__fmt) {}\n\n    template <class _Cp, class _Traits>\n    friend\n    basic_istream<_Cp, _Traits>&\n    operator>>(basic_istream<_Cp, _Traits>& __is, const __iom_t9<_Cp>& __x);\n};\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typename basic_istream<_CharT, _Traits>::sentry __s(__is);\n        if (__s)\n        {\n            typedef istreambuf_iterator<_CharT, _Traits> _Ip;\n            typedef time_get<_CharT, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            const _Fp& __tf = use_facet<_Fp>(__is.getloc());\n            __tf.get(_Ip(__is), _Ip(), __is, __err, __x.__tm_,\n                     __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_));\n            __is.setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __is.__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __is;\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\n__iom_t9<_CharT>\nget_time(tm* __tm, const _CharT* __fmt)\n{\n    return __iom_t9<_CharT>(__tm, __fmt);\n}\n\n// put_time\n\ntemplate <class _CharT> class __iom_t10;\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x);\n\ntemplate <class _CharT>\nclass __iom_t10\n{\n    const tm* __tm_;\n    const _CharT* __fmt_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __iom_t10(const tm* __tm, const _CharT* __fmt)\n        : __tm_(__tm), __fmt_(__fmt) {}\n\n    template <class _Cp, class _Traits>\n    friend\n    basic_ostream<_Cp, _Traits>&\n    operator<<(basic_ostream<_Cp, _Traits>& __os, const __iom_t10<_Cp>& __x);\n};\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typename basic_ostream<_CharT, _Traits>::sentry __s(__os);\n        if (__s)\n        {\n            typedef ostreambuf_iterator<_CharT, _Traits> _Op;\n            typedef time_put<_CharT, _Op> _Fp;\n            const _Fp& __tf = use_facet<_Fp>(__os.getloc());\n            if (__tf.put(_Op(__os), __os, __os.fill(), __x.__tm_,\n                         __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_)).failed())\n                __os.setstate(ios_base::badbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __os.__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __os;\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\n__iom_t10<_CharT>\nput_time(const tm* __tm, const _CharT* __fmt)\n{\n    return __iom_t10<_CharT>(__tm, __fmt);\n}\n\n#if _LIBCPP_STD_VER > 11\n\ntemplate <class _CharT, class _Traits, class _ForwardIterator>\nstd::basic_ostream<_CharT, _Traits> &\n__quoted_output ( basic_ostream<_CharT, _Traits> &__os, \n        _ForwardIterator __first, _ForwardIterator __last, _CharT __delim, _CharT __escape )\n{\n    _VSTD::basic_string<_CharT, _Traits> __str;\n    __str.push_back(__delim);\n    for ( ; __first != __last; ++ __first )\n    {\n        if (_Traits::eq (*__first, __escape) || _Traits::eq (*__first, __delim))\n            __str.push_back(__escape);\n        __str.push_back(*__first);\n    }\n    __str.push_back(__delim);\n    return __put_character_sequence(__os, __str.data(), __str.size());\n}\n\ntemplate <class _CharT, class _Traits, class _String>\nbasic_istream<_CharT, _Traits> &\n__quoted_input ( basic_istream<_CharT, _Traits> &__is, _String & __string, _CharT __delim, _CharT __escape )\n{\n    __string.clear ();\n    _CharT __c;\n    __is >> __c;\n    if ( __is.fail ())\n        return __is;\n\n    if (!_Traits::eq (__c, __delim))    // no delimiter, read the whole string\n    {\n        __is.unget ();\n        __is >> __string;\n        return __is;\n    }\n\n    __save_flags<_CharT, _Traits> sf(__is);\n    noskipws (__is);\n    while (true)\n        {\n        __is >> __c;\n        if ( __is.fail ())\n            break;\n        if (_Traits::eq (__c, __escape))\n        {\n            __is >> __c;\n            if ( __is.fail ())\n                break;\n        }\n        else if (_Traits::eq (__c, __delim))\n            break;\n        __string.push_back ( __c );\n        }\n    return __is;\n}\n\n\ntemplate <class _CharT, class _Iter, class _Traits=char_traits<_CharT>>\nstruct __quoted_output_proxy\n{\n    _Iter  __first;\n    _Iter  __last;\n    _CharT  __delim;\n    _CharT  __escape;\n\n    __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)\n    : __first(__f), __last(__l), __delim(__d), __escape(__e) {}\n    //  This would be a nice place for a string_ref \n};\n\ntemplate <class _CharT, class _Traits, class _Iter>\nbasic_ostream<_CharT, _Traits>& operator<<(\n         basic_ostream<_CharT, _Traits>& __os, \n         const __quoted_output_proxy<_CharT, _Iter, _Traits> & __proxy)\n{\n    return __quoted_output (__os, __proxy.__first, __proxy.__last, __proxy.__delim, __proxy.__escape);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nstruct __quoted_proxy\n{\n    basic_string<_CharT, _Traits, _Allocator> &__string;\n    _CharT  __delim;\n    _CharT  __escape;\n\n    __quoted_proxy(basic_string<_CharT, _Traits, _Allocator> &__s, _CharT __d, _CharT __e)\n    : __string(__s), __delim(__d), __escape(__e) {}\n};\n\ntemplate <class _CharT, class _Traits, class _Allocator>\n_LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>& operator<<(\n        basic_ostream<_CharT, _Traits>& __os, \n        const __quoted_proxy<_CharT, _Traits, _Allocator> & __proxy)\n{\n    return __quoted_output (__os, __proxy.__string.cbegin (), __proxy.__string.cend (), __proxy.__delim, __proxy.__escape);\n}\n\n//  extractor for non-const basic_string& proxies\ntemplate <class _CharT, class _Traits, class _Allocator>\n_LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>& operator>>(\n        basic_istream<_CharT, _Traits>& __is, \n        const __quoted_proxy<_CharT, _Traits, _Allocator> & __proxy)\n{\n    return __quoted_input ( __is, __proxy.__string, __proxy.__delim, __proxy.__escape );\n}\n\n\ntemplate <class _CharT>\n_LIBCPP_INLINE_VISIBILITY\n__quoted_output_proxy<_CharT, const _CharT *>\nquoted ( const _CharT *__s, _CharT __delim = _CharT('\"'), _CharT __escape =_CharT('\\\\'))\n{\n    const _CharT *__end = __s;\n    while ( *__end ) ++__end;\n    return __quoted_output_proxy<_CharT, const _CharT *> ( __s, __end, __delim, __escape );\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\n_LIBCPP_INLINE_VISIBILITY\n__quoted_output_proxy<_CharT, typename basic_string <_CharT, _Traits, _Allocator>::const_iterator>\nquoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('\"'), _CharT __escape=_CharT('\\\\'))\n{\n    return __quoted_output_proxy<_CharT, \n            typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> \n                    ( __s.cbegin(), __s.cend (), __delim, __escape );\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\n__quoted_proxy<_CharT, _Traits, _Allocator>\nquoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('\"'), _CharT __escape=_CharT('\\\\'))\n{\n    return __quoted_proxy<_CharT, _Traits, _Allocator>( __s, __delim, __escape );\n}\n#endif\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_IOMANIP\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/ios",
    "content": "// -*- C++ -*-\n//===---------------------------- ios -------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_IOS\n#define _LIBCPP_IOS\n\n/*\n    ios synopsis\n\n#include <iosfwd>\n\nnamespace std\n{\n\ntypedef OFF_T streamoff;\ntypedef SZ_T streamsize;\ntemplate <class stateT> class fpos;\n\nclass ios_base\n{\npublic:\n    class failure;\n\n    typedef T1 fmtflags;\n    static constexpr fmtflags boolalpha;\n    static constexpr fmtflags dec;\n    static constexpr fmtflags fixed;\n    static constexpr fmtflags hex;\n    static constexpr fmtflags internal;\n    static constexpr fmtflags left;\n    static constexpr fmtflags oct;\n    static constexpr fmtflags right;\n    static constexpr fmtflags scientific;\n    static constexpr fmtflags showbase;\n    static constexpr fmtflags showpoint;\n    static constexpr fmtflags showpos;\n    static constexpr fmtflags skipws;\n    static constexpr fmtflags unitbuf;\n    static constexpr fmtflags uppercase;\n    static constexpr fmtflags adjustfield;\n    static constexpr fmtflags basefield;\n    static constexpr fmtflags floatfield;\n\n    typedef T2 iostate;\n    static constexpr iostate badbit;\n    static constexpr iostate eofbit;\n    static constexpr iostate failbit;\n    static constexpr iostate goodbit;\n\n    typedef T3 openmode;\n    static constexpr openmode app;\n    static constexpr openmode ate;\n    static constexpr openmode binary;\n    static constexpr openmode in;\n    static constexpr openmode out;\n    static constexpr openmode trunc;\n\n    typedef T4 seekdir;\n    static constexpr seekdir beg;\n    static constexpr seekdir cur;\n    static constexpr seekdir end;\n\n    class Init;\n\n    // 27.5.2.2 fmtflags state:\n    fmtflags flags() const;\n    fmtflags flags(fmtflags fmtfl);\n    fmtflags setf(fmtflags fmtfl);\n    fmtflags setf(fmtflags fmtfl, fmtflags mask);\n    void unsetf(fmtflags mask);\n\n    streamsize precision() const;\n    streamsize precision(streamsize prec);\n    streamsize width() const;\n    streamsize width(streamsize wide);\n\n    // 27.5.2.3 locales:\n    locale imbue(const locale& loc);\n    locale getloc() const;\n\n    // 27.5.2.5 storage:\n    static int xalloc();\n    long& iword(int index);\n    void*& pword(int index);\n\n    // destructor\n    virtual ~ios_base();\n\n    // 27.5.2.6 callbacks;\n    enum event { erase_event, imbue_event, copyfmt_event };\n    typedef void (*event_callback)(event, ios_base&, int index);\n    void register_callback(event_callback fn, int index);\n\n    ios_base(const ios_base&) = delete;\n    ios_base& operator=(const ios_base&) = delete;\n\n    static bool sync_with_stdio(bool sync = true);\n\nprotected:\n    ios_base();\n};\n\ntemplate <class charT, class traits = char_traits<charT> >\nclass basic_ios\n    : public ios_base\n{\npublic:\n    // types:\n    typedef charT char_type;\n    typedef typename traits::int_type int_type;\n    typedef typename traits::pos_type pos_type;\n    typedef typename traits::off_type off_type;\n    typedef traits traits_type;\n\n    operator unspecified-bool-type() const;\n    bool operator!() const;\n    iostate rdstate() const;\n    void clear(iostate state = goodbit);\n    void setstate(iostate state);\n    bool good() const;\n    bool eof() const;\n    bool fail() const;\n    bool bad() const;\n\n    iostate exceptions() const;\n    void exceptions(iostate except);\n\n    // 27.5.4.1 Constructor/destructor:\n    explicit basic_ios(basic_streambuf<charT,traits>* sb);\n    virtual ~basic_ios();\n\n    // 27.5.4.2 Members:\n    basic_ostream<charT,traits>* tie() const;\n    basic_ostream<charT,traits>* tie(basic_ostream<charT,traits>* tiestr);\n\n    basic_streambuf<charT,traits>* rdbuf() const;\n    basic_streambuf<charT,traits>* rdbuf(basic_streambuf<charT,traits>* sb);\n\n    basic_ios& copyfmt(const basic_ios& rhs);\n\n    char_type fill() const;\n    char_type fill(char_type ch);\n\n    locale imbue(const locale& loc);\n\n    char narrow(char_type c, char dfault) const;\n    char_type widen(char c) const;\n\n    basic_ios(const basic_ios& ) = delete;\n    basic_ios& operator=(const basic_ios&) = delete;\n\nprotected:\n    basic_ios();\n    void init(basic_streambuf<charT,traits>* sb);\n    void move(basic_ios& rhs);\n    void swap(basic_ios& rhs) noexcept;\n    void set_rdbuf(basic_streambuf<charT, traits>* sb);\n};\n\n// 27.5.5, manipulators:\nios_base& boolalpha (ios_base& str);\nios_base& noboolalpha(ios_base& str);\nios_base& showbase (ios_base& str);\nios_base& noshowbase (ios_base& str);\nios_base& showpoint (ios_base& str);\nios_base& noshowpoint(ios_base& str);\nios_base& showpos (ios_base& str);\nios_base& noshowpos (ios_base& str);\nios_base& skipws (ios_base& str);\nios_base& noskipws (ios_base& str);\nios_base& uppercase (ios_base& str);\nios_base& nouppercase(ios_base& str);\nios_base& unitbuf (ios_base& str);\nios_base& nounitbuf (ios_base& str);\n\n// 27.5.5.2 adjustfield:\nios_base& internal (ios_base& str);\nios_base& left (ios_base& str);\nios_base& right (ios_base& str);\n\n// 27.5.5.3 basefield:\nios_base& dec (ios_base& str);\nios_base& hex (ios_base& str);\nios_base& oct (ios_base& str);\n\n// 27.5.5.4 floatfield:\nios_base& fixed (ios_base& str);\nios_base& scientific (ios_base& str);\nios_base& hexfloat (ios_base& str);\nios_base& defaultfloat(ios_base& str);\n\n// 27.5.5.5 error reporting:\nenum class io_errc\n{\n    stream = 1\n};\n\nconcept_map ErrorCodeEnum<io_errc> { };\nerror_code make_error_code(io_errc e) noexcept; \nerror_condition make_error_condition(io_errc e) noexcept; \nstorage-class-specifier const error_category& iostream_category() noexcept;\n\n}  // std\n\n*/\n\n#include <__config>\n#include <iosfwd>\n#include <__locale>\n#include <system_error>\n\n#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)\n#include <atomic>     // for __xindex_\n#endif\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntypedef ptrdiff_t streamsize;\n\nclass _LIBCPP_TYPE_VIS ios_base\n{\npublic:\n    class _LIBCPP_TYPE_VIS failure;\n\n    typedef unsigned int fmtflags;\n    static const fmtflags boolalpha   = 0x0001;\n    static const fmtflags dec         = 0x0002;\n    static const fmtflags fixed       = 0x0004;\n    static const fmtflags hex         = 0x0008;\n    static const fmtflags internal    = 0x0010;\n    static const fmtflags left        = 0x0020;\n    static const fmtflags oct         = 0x0040;\n    static const fmtflags right       = 0x0080;\n    static const fmtflags scientific  = 0x0100;\n    static const fmtflags showbase    = 0x0200;\n    static const fmtflags showpoint   = 0x0400;\n    static const fmtflags showpos     = 0x0800;\n    static const fmtflags skipws      = 0x1000;\n    static const fmtflags unitbuf     = 0x2000;\n    static const fmtflags uppercase   = 0x4000;\n    static const fmtflags adjustfield = left | right | internal;\n    static const fmtflags basefield   = dec | oct | hex;\n    static const fmtflags floatfield  = scientific | fixed;\n\n    typedef unsigned int iostate;\n    typedef iostate      io_state;\n    static const iostate badbit  = 0x1;\n    static const iostate eofbit  = 0x2;\n    static const iostate failbit = 0x4;\n    static const iostate goodbit = 0x0;\n\n    typedef unsigned int openmode;\n    typedef openmode     open_mode;\n    static const openmode app    = 0x01;\n    static const openmode ate    = 0x02;\n    static const openmode binary = 0x04;\n    static const openmode in     = 0x08;\n    static const openmode out    = 0x10;\n    static const openmode trunc  = 0x20;\n\n    enum seekdir {beg, cur, end};\n    typedef seekdir seek_dir;\n\n    typedef _VSTD::streamoff streamoff;\n    typedef _VSTD::streampos streampos;\n\n    class _LIBCPP_TYPE_VIS Init;\n\n    // 27.5.2.2 fmtflags state:\n    _LIBCPP_INLINE_VISIBILITY fmtflags flags() const;\n    _LIBCPP_INLINE_VISIBILITY fmtflags flags(fmtflags __fmtfl);\n    _LIBCPP_INLINE_VISIBILITY fmtflags setf(fmtflags __fmtfl);\n    _LIBCPP_INLINE_VISIBILITY fmtflags setf(fmtflags __fmtfl, fmtflags __mask);\n    _LIBCPP_INLINE_VISIBILITY void unsetf(fmtflags __mask);\n\n    _LIBCPP_INLINE_VISIBILITY streamsize precision() const;\n    _LIBCPP_INLINE_VISIBILITY streamsize precision(streamsize __prec);\n    _LIBCPP_INLINE_VISIBILITY streamsize width() const;\n    _LIBCPP_INLINE_VISIBILITY streamsize width(streamsize __wide);\n\n    // 27.5.2.3 locales:\n    locale imbue(const locale& __loc);\n    locale getloc() const;\n\n    // 27.5.2.5 storage:\n    static int xalloc();\n    long& iword(int __index);\n    void*& pword(int __index);\n\n    // destructor\n    virtual ~ios_base();\n\n    // 27.5.2.6 callbacks;\n    enum event { erase_event, imbue_event, copyfmt_event };\n    typedef void (*event_callback)(event, ios_base&, int __index);\n    void register_callback(event_callback __fn, int __index);\n\nprivate:\n    ios_base(const ios_base&); // = delete;\n    ios_base& operator=(const ios_base&); // = delete;\n\npublic:\n    static bool sync_with_stdio(bool __sync = true);\n\n    _LIBCPP_INLINE_VISIBILITY iostate rdstate() const;\n    void clear(iostate __state = goodbit);\n    _LIBCPP_INLINE_VISIBILITY void setstate(iostate __state);\n\n    _LIBCPP_INLINE_VISIBILITY bool good() const;\n    _LIBCPP_INLINE_VISIBILITY bool eof() const;\n    _LIBCPP_INLINE_VISIBILITY bool fail() const;\n    _LIBCPP_INLINE_VISIBILITY bool bad() const;\n\n    _LIBCPP_INLINE_VISIBILITY iostate exceptions() const;\n    _LIBCPP_INLINE_VISIBILITY void exceptions(iostate __iostate);\n\n    void __set_badbit_and_consider_rethrow();\n    void __set_failbit_and_consider_rethrow();\n\nprotected:\n    _LIBCPP_INLINE_VISIBILITY\n    ios_base() {// purposefully does no initialization\n               }\n\n    void init(void* __sb);\n    _LIBCPP_ALWAYS_INLINE void* rdbuf() const {return __rdbuf_;}\n\n    _LIBCPP_ALWAYS_INLINE\n    void rdbuf(void* __sb)\n    {\n        __rdbuf_ = __sb;\n        clear();\n    }\n\n    void __call_callbacks(event);\n    void copyfmt(const ios_base&);\n    void move(ios_base&);\n    void swap(ios_base&) _NOEXCEPT;\n\n    _LIBCPP_ALWAYS_INLINE\n    void set_rdbuf(void* __sb)\n    {\n        __rdbuf_ = __sb;\n    }\n\nprivate:\n    // All data members must be scalars\n    fmtflags        __fmtflags_;\n    streamsize      __precision_;\n    streamsize      __width_;\n    iostate         __rdstate_;\n    iostate         __exceptions_;\n    void*           __rdbuf_;\n    void*           __loc_;\n    event_callback* __fn_;\n    int*            __index_;\n    size_t          __event_size_;\n    size_t          __event_cap_;\n#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)\n    static atomic<int> __xindex_;\n#else\n    static int      __xindex_;\n#endif\n    long*           __iarray_;\n    size_t          __iarray_size_;\n    size_t          __iarray_cap_;\n    void**          __parray_;\n    size_t          __parray_size_;\n    size_t          __parray_cap_;\n};\n\n//enum class io_errc\n_LIBCPP_DECLARE_STRONG_ENUM(io_errc)\n{\n    stream = 1\n};\n_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(io_errc)\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<io_errc> : public true_type { };\n\n#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<io_errc::__lx> : public true_type { };\n#endif\n\n_LIBCPP_FUNC_VIS\nconst error_category& iostream_category() _NOEXCEPT;\n\ninline _LIBCPP_INLINE_VISIBILITY\nerror_code\nmake_error_code(io_errc __e) _NOEXCEPT\n{\n    return error_code(static_cast<int>(__e), iostream_category());\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nerror_condition\nmake_error_condition(io_errc __e) _NOEXCEPT\n{\n    return error_condition(static_cast<int>(__e), iostream_category());\n}\n\nclass _LIBCPP_EXCEPTION_ABI ios_base::failure\n    : public system_error\n{\npublic:\n    explicit failure(const string& __msg, const error_code& __ec = io_errc::stream);\n    explicit failure(const char* __msg, const error_code& __ec = io_errc::stream);\n    virtual ~failure() throw();\n};\n\nclass _LIBCPP_TYPE_VIS ios_base::Init\n{\npublic:\n    Init();\n    ~Init();\n};\n\n// fmtflags\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base::fmtflags\nios_base::flags() const\n{\n    return __fmtflags_;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base::fmtflags\nios_base::flags(fmtflags __fmtfl)\n{\n    fmtflags __r = __fmtflags_;\n    __fmtflags_ = __fmtfl;\n    return __r;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base::fmtflags\nios_base::setf(fmtflags __fmtfl)\n{\n    fmtflags __r = __fmtflags_;\n    __fmtflags_ |= __fmtfl;\n    return __r;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nios_base::unsetf(fmtflags __mask)\n{\n    __fmtflags_ &= ~__mask;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base::fmtflags\nios_base::setf(fmtflags __fmtfl, fmtflags __mask)\n{\n    fmtflags __r = __fmtflags_;\n    unsetf(__mask);\n    __fmtflags_ |= __fmtfl & __mask;\n    return __r;\n}\n\n// precision\n\ninline _LIBCPP_INLINE_VISIBILITY\nstreamsize\nios_base::precision() const\n{\n    return __precision_;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nstreamsize\nios_base::precision(streamsize __prec)\n{\n    streamsize __r = __precision_;\n    __precision_ = __prec;\n    return __r;\n}\n\n// width\n\ninline _LIBCPP_INLINE_VISIBILITY\nstreamsize\nios_base::width() const\n{\n    return __width_;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nstreamsize\nios_base::width(streamsize __wide)\n{\n    streamsize __r = __width_;\n    __width_ = __wide;\n    return __r;\n}\n\n// iostate\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base::iostate\nios_base::rdstate() const\n{\n    return __rdstate_;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nios_base::setstate(iostate __state)\n{\n    clear(__rdstate_ | __state);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nios_base::good() const\n{\n    return __rdstate_ == 0;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nios_base::eof() const\n{\n    return (__rdstate_ & eofbit) != 0;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nios_base::fail() const\n{\n    return (__rdstate_ & (failbit | badbit)) != 0;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nios_base::bad() const\n{\n    return (__rdstate_ & badbit) != 0;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base::iostate\nios_base::exceptions() const\n{\n    return __exceptions_;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nios_base::exceptions(iostate __iostate)\n{\n    __exceptions_ = __iostate;\n    clear(__rdstate_);\n}\n\ntemplate <class _CharT, class _Traits>\nclass _LIBCPP_TYPE_VIS_ONLY basic_ios\n    : public ios_base\n{\npublic:\n    // types:\n    typedef _CharT char_type;\n    typedef _Traits traits_type;\n\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    _LIBCPP_ALWAYS_INLINE\n        _LIBCPP_EXPLICIT\n        operator bool() const {return !fail();}\n    _LIBCPP_ALWAYS_INLINE bool operator!() const    {return  fail();}\n    _LIBCPP_ALWAYS_INLINE iostate rdstate() const   {return ios_base::rdstate();}\n    _LIBCPP_ALWAYS_INLINE void clear(iostate __state = goodbit) {ios_base::clear(__state);}\n    _LIBCPP_ALWAYS_INLINE void setstate(iostate __state) {ios_base::setstate(__state);}\n    _LIBCPP_ALWAYS_INLINE bool good() const {return ios_base::good();}\n    _LIBCPP_ALWAYS_INLINE bool eof() const  {return ios_base::eof();}\n    _LIBCPP_ALWAYS_INLINE bool fail() const {return ios_base::fail();}\n    _LIBCPP_ALWAYS_INLINE bool bad() const  {return ios_base::bad();}\n\n    _LIBCPP_ALWAYS_INLINE iostate exceptions() const {return ios_base::exceptions();}\n    _LIBCPP_ALWAYS_INLINE void exceptions(iostate __iostate) {ios_base::exceptions(__iostate);}\n\n    // 27.5.4.1 Constructor/destructor:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit basic_ios(basic_streambuf<char_type,traits_type>* __sb);\n    virtual ~basic_ios();\n\n    // 27.5.4.2 Members:\n    _LIBCPP_INLINE_VISIBILITY \n    basic_ostream<char_type, traits_type>* tie() const;\n    _LIBCPP_INLINE_VISIBILITY \n    basic_ostream<char_type, traits_type>* tie(basic_ostream<char_type, traits_type>* __tiestr);\n\n    _LIBCPP_INLINE_VISIBILITY \n    basic_streambuf<char_type, traits_type>* rdbuf() const;\n    _LIBCPP_INLINE_VISIBILITY \n    basic_streambuf<char_type, traits_type>* rdbuf(basic_streambuf<char_type, traits_type>* __sb);\n\n    basic_ios& copyfmt(const basic_ios& __rhs);\n\n    _LIBCPP_INLINE_VISIBILITY \n    char_type fill() const;\n    _LIBCPP_INLINE_VISIBILITY \n    char_type fill(char_type __ch);\n\n    _LIBCPP_INLINE_VISIBILITY \n    locale imbue(const locale& __loc);\n\n    _LIBCPP_INLINE_VISIBILITY \n    char narrow(char_type __c, char __dfault) const;\n    _LIBCPP_INLINE_VISIBILITY \n    char_type widen(char __c) const;\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    basic_ios() {// purposefully does no initialization\n                }\n    _LIBCPP_INLINE_VISIBILITY \n    void init(basic_streambuf<char_type, traits_type>* __sb);\n\n    _LIBCPP_INLINE_VISIBILITY \n    void move(basic_ios& __rhs);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_ALWAYS_INLINE\n    void move(basic_ios&& __rhs) {move(__rhs);}\n#endif\n    _LIBCPP_INLINE_VISIBILITY \n    void swap(basic_ios& __rhs) _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY \n    void set_rdbuf(basic_streambuf<char_type, traits_type>* __sb);\nprivate:\n    basic_ostream<char_type, traits_type>* __tie_;\n     mutable int_type __fill_;\n};\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ios<_CharT, _Traits>::basic_ios(basic_streambuf<char_type,traits_type>* __sb)\n{\n    init(__sb);\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ios<_CharT, _Traits>::~basic_ios()\n{\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_ios<_CharT, _Traits>::init(basic_streambuf<char_type, traits_type>* __sb)\n{\n    ios_base::init(__sb);\n    __tie_ = 0;\n    __fill_ = traits_type::eof();\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>*\nbasic_ios<_CharT, _Traits>::tie() const\n{\n    return __tie_;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>*\nbasic_ios<_CharT, _Traits>::tie(basic_ostream<char_type, traits_type>* __tiestr)\n{\n    basic_ostream<char_type, traits_type>* __r = __tie_;\n    __tie_ = __tiestr;\n    return __r;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_streambuf<_CharT, _Traits>*\nbasic_ios<_CharT, _Traits>::rdbuf() const\n{\n    return static_cast<basic_streambuf<char_type, traits_type>*>(ios_base::rdbuf());\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_streambuf<_CharT, _Traits>*\nbasic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<char_type, traits_type>* __sb)\n{\n    basic_streambuf<char_type, traits_type>* __r = rdbuf();\n    ios_base::rdbuf(__sb);\n    return __r;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nlocale\nbasic_ios<_CharT, _Traits>::imbue(const locale& __loc)\n{\n    locale __r = getloc();\n    ios_base::imbue(__loc);\n    if (rdbuf())\n        rdbuf()->pubimbue(__loc);\n    return __r;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nchar\nbasic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const\n{\n    return use_facet<ctype<char_type> >(getloc()).narrow(__c, __dfault);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\n_CharT\nbasic_ios<_CharT, _Traits>::widen(char __c) const\n{\n    return use_facet<ctype<char_type> >(getloc()).widen(__c);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\n_CharT\nbasic_ios<_CharT, _Traits>::fill() const\n{\n    if (traits_type::eq_int_type(traits_type::eof(), __fill_))\n        __fill_ = widen(' ');\n    return __fill_;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\n_CharT\nbasic_ios<_CharT, _Traits>::fill(char_type __ch)\n{\n    char_type __r = __fill_;\n    __fill_ = __ch;\n    return __r;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ios<_CharT, _Traits>&\nbasic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs)\n{\n    if (this != &__rhs)\n    {\n        __call_callbacks(erase_event);\n        ios_base::copyfmt(__rhs);\n        __tie_ = __rhs.__tie_;\n        __fill_ = __rhs.__fill_;\n        __call_callbacks(copyfmt_event);\n        exceptions(__rhs.exceptions());\n    }\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_ios<_CharT, _Traits>::move(basic_ios& __rhs)\n{\n    ios_base::move(__rhs);\n    __tie_ = __rhs.__tie_;\n    __rhs.__tie_ = 0;\n    __fill_ = __rhs.__fill_;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_ios<_CharT, _Traits>::swap(basic_ios& __rhs) _NOEXCEPT\n{\n    ios_base::swap(__rhs);\n    _VSTD::swap(__tie_, __rhs.__tie_);\n    _VSTD::swap(__fill_, __rhs.__fill_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_ios<_CharT, _Traits>::set_rdbuf(basic_streambuf<char_type, traits_type>* __sb)\n{\n    ios_base::set_rdbuf(__sb);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nboolalpha(ios_base& __str)\n{\n    __str.setf(ios_base::boolalpha);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nnoboolalpha(ios_base& __str)\n{\n    __str.unsetf(ios_base::boolalpha);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nshowbase(ios_base& __str)\n{\n    __str.setf(ios_base::showbase);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nnoshowbase(ios_base& __str)\n{\n    __str.unsetf(ios_base::showbase);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nshowpoint(ios_base& __str)\n{\n    __str.setf(ios_base::showpoint);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nnoshowpoint(ios_base& __str)\n{\n    __str.unsetf(ios_base::showpoint);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nshowpos(ios_base& __str)\n{\n    __str.setf(ios_base::showpos);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nnoshowpos(ios_base& __str)\n{\n    __str.unsetf(ios_base::showpos);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nskipws(ios_base& __str)\n{\n    __str.setf(ios_base::skipws);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nnoskipws(ios_base& __str)\n{\n    __str.unsetf(ios_base::skipws);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nuppercase(ios_base& __str)\n{\n    __str.setf(ios_base::uppercase);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nnouppercase(ios_base& __str)\n{\n    __str.unsetf(ios_base::uppercase);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nunitbuf(ios_base& __str)\n{\n    __str.setf(ios_base::unitbuf);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nnounitbuf(ios_base& __str)\n{\n    __str.unsetf(ios_base::unitbuf);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\ninternal(ios_base& __str)\n{\n    __str.setf(ios_base::internal, ios_base::adjustfield);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nleft(ios_base& __str)\n{\n    __str.setf(ios_base::left, ios_base::adjustfield);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nright(ios_base& __str)\n{\n    __str.setf(ios_base::right, ios_base::adjustfield);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\ndec(ios_base& __str)\n{\n    __str.setf(ios_base::dec, ios_base::basefield);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nhex(ios_base& __str)\n{\n    __str.setf(ios_base::hex, ios_base::basefield);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\noct(ios_base& __str)\n{\n    __str.setf(ios_base::oct, ios_base::basefield);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nfixed(ios_base& __str)\n{\n    __str.setf(ios_base::fixed, ios_base::floatfield);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nscientific(ios_base& __str)\n{\n    __str.setf(ios_base::scientific, ios_base::floatfield);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\nhexfloat(ios_base& __str)\n{\n    __str.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield);\n    return __str;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nios_base&\ndefaultfloat(ios_base& __str)\n{\n    __str.unsetf(ios_base::floatfield);\n    return __str;\n}\n\ntemplate <class _CharT, class _Traits>\nclass __save_flags\n{\n    typedef basic_ios<_CharT, _Traits> __stream_type;\n    typedef typename __stream_type::fmtflags fmtflags;\n\n    __stream_type& __stream_;\n    fmtflags       __fmtflags_;\n    _CharT         __fill_;\n\n    __save_flags(const __save_flags&);\n    __save_flags& operator=(const __save_flags&);\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __save_flags(__stream_type& __stream)\n        : __stream_(__stream),\n          __fmtflags_(__stream.flags()),\n          __fill_(__stream.fill())\n        {}\n    _LIBCPP_INLINE_VISIBILITY\n    ~__save_flags()\n    {\n        __stream_.flags(__fmtflags_);\n        __stream_.fill(__fill_);\n    }\n};\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_IOS\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/iosfwd",
    "content": "// -*- C++ -*-\n//===--------------------------- iosfwd -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_IOSFWD\n#define _LIBCPP_IOSFWD\n\n/*\n    iosfwd synopsis\n\nnamespace std\n{\n\ntemplate<class charT> struct char_traits;\ntemplate<class T>     class allocator;\n\nclass ios_base;\ntemplate <class charT, class traits = char_traits<charT> > class basic_ios;\n\ntemplate <class charT, class traits = char_traits<charT> > class basic_streambuf;\ntemplate <class charT, class traits = char_traits<charT> > class basic_istream;\ntemplate <class charT, class traits = char_traits<charT> > class basic_ostream;\ntemplate <class charT, class traits = char_traits<charT> > class basic_iostream;\n\ntemplate <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >\n    class basic_stringbuf;\ntemplate <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >\n    class basic_istringstream;\ntemplate <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >\n    class basic_ostringstream;\ntemplate <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >\n    class basic_stringstream;\n\ntemplate <class charT, class traits = char_traits<charT> > class basic_filebuf;\ntemplate <class charT, class traits = char_traits<charT> > class basic_ifstream;\ntemplate <class charT, class traits = char_traits<charT> > class basic_ofstream;\ntemplate <class charT, class traits = char_traits<charT> > class basic_fstream;\n\ntemplate <class charT, class traits = char_traits<charT> > class istreambuf_iterator;\ntemplate <class charT, class traits = char_traits<charT> > class ostreambuf_iterator;\n\ntypedef basic_ios<char>              ios;\ntypedef basic_ios<wchar_t>           wios;\n\ntypedef basic_streambuf<char>        streambuf;\ntypedef basic_istream<char>          istream;\ntypedef basic_ostream<char>          ostream;\ntypedef basic_iostream<char>         iostream;\n\ntypedef basic_stringbuf<char>        stringbuf;\ntypedef basic_istringstream<char>    istringstream;\ntypedef basic_ostringstream<char>    ostringstream;\ntypedef basic_stringstream<char>     stringstream;\n\ntypedef basic_filebuf<char>          filebuf;\ntypedef basic_ifstream<char>         ifstream;\ntypedef basic_ofstream<char>         ofstream;\ntypedef basic_fstream<char>          fstream;\n\ntypedef basic_streambuf<wchar_t>     wstreambuf;\ntypedef basic_istream<wchar_t>       wistream;\ntypedef basic_ostream<wchar_t>       wostream;\ntypedef basic_iostream<wchar_t>      wiostream;\n\ntypedef basic_stringbuf<wchar_t>     wstringbuf;\ntypedef basic_istringstream<wchar_t> wistringstream;\ntypedef basic_ostringstream<wchar_t> wostringstream;\ntypedef basic_stringstream<wchar_t>  wstringstream;\n\ntypedef basic_filebuf<wchar_t>       wfilebuf;\ntypedef basic_ifstream<wchar_t>      wifstream;\ntypedef basic_ofstream<wchar_t>      wofstream;\ntypedef basic_fstream<wchar_t>       wfstream;\n\ntemplate <class state> class fpos;\ntypedef fpos<char_traits<char>::state_type>    streampos;\ntypedef fpos<char_traits<wchar_t>::state_type> wstreampos;\n\n}  // std\n\n*/\n\n#include <__config>\n#include <wchar.h>  // for mbstate_t\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nclass _LIBCPP_TYPE_VIS ios_base;\n\ntemplate<class _CharT>  struct _LIBCPP_TYPE_VIS_ONLY char_traits;\ntemplate<class _Tp>     class _LIBCPP_TYPE_VIS_ONLY allocator;\n\ntemplate <class _CharT, class _Traits = char_traits<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_ios;\n\ntemplate <class _CharT, class _Traits = char_traits<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_streambuf;\ntemplate <class _CharT, class _Traits = char_traits<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_istream;\ntemplate <class _CharT, class _Traits = char_traits<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_ostream;\ntemplate <class _CharT, class _Traits = char_traits<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_iostream;\n\ntemplate <class _CharT, class _Traits = char_traits<_CharT>,\n          class _Allocator = allocator<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_stringbuf;\ntemplate <class _CharT, class _Traits = char_traits<_CharT>,\n          class _Allocator = allocator<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_istringstream;\ntemplate <class _CharT, class _Traits = char_traits<_CharT>,\n          class _Allocator = allocator<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_ostringstream;\ntemplate <class _CharT, class _Traits = char_traits<_CharT>,\n          class _Allocator = allocator<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_stringstream;\n\ntemplate <class _CharT, class _Traits = char_traits<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_filebuf;\ntemplate <class _CharT, class _Traits = char_traits<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_ifstream;\ntemplate <class _CharT, class _Traits = char_traits<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_ofstream;\ntemplate <class _CharT, class _Traits = char_traits<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_fstream;\n\ntemplate <class _CharT, class _Traits = char_traits<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY istreambuf_iterator;\ntemplate <class _CharT, class _Traits = char_traits<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY ostreambuf_iterator;\n\ntypedef basic_ios<char>              ios;\ntypedef basic_ios<wchar_t>           wios;\n\ntypedef basic_streambuf<char>        streambuf;\ntypedef basic_istream<char>          istream;\ntypedef basic_ostream<char>          ostream;\ntypedef basic_iostream<char>         iostream;\n\ntypedef basic_stringbuf<char>        stringbuf;\ntypedef basic_istringstream<char>    istringstream;\ntypedef basic_ostringstream<char>    ostringstream;\ntypedef basic_stringstream<char>     stringstream;\n\ntypedef basic_filebuf<char>          filebuf;\ntypedef basic_ifstream<char>         ifstream;\ntypedef basic_ofstream<char>         ofstream;\ntypedef basic_fstream<char>          fstream;\n\ntypedef basic_streambuf<wchar_t>     wstreambuf;\ntypedef basic_istream<wchar_t>       wistream;\ntypedef basic_ostream<wchar_t>       wostream;\ntypedef basic_iostream<wchar_t>      wiostream;\n\ntypedef basic_stringbuf<wchar_t>     wstringbuf;\ntypedef basic_istringstream<wchar_t> wistringstream;\ntypedef basic_ostringstream<wchar_t> wostringstream;\ntypedef basic_stringstream<wchar_t>  wstringstream;\n\ntypedef basic_filebuf<wchar_t>       wfilebuf;\ntypedef basic_ifstream<wchar_t>      wifstream;\ntypedef basic_ofstream<wchar_t>      wofstream;\ntypedef basic_fstream<wchar_t>       wfstream;\n\ntemplate <class _State>             class _LIBCPP_TYPE_VIS_ONLY fpos;\ntypedef fpos<mbstate_t>    streampos;\ntypedef fpos<mbstate_t>    wstreampos;\n#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS\ntypedef fpos<mbstate_t>    u16streampos;\ntypedef fpos<mbstate_t>    u32streampos;\n#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS\n\n#if defined(_NEWLIB_VERSION)\n// On newlib, off_t is 'long int'\ntypedef long int streamoff;         // for char_traits in <string>\n#else\ntypedef long long streamoff;        // for char_traits in <string>\n#endif\n\ntemplate <class _CharT,             // for <stdexcept>\n          class _Traits = char_traits<_CharT>,\n          class _Allocator = allocator<_CharT> >\n    class _LIBCPP_TYPE_VIS_ONLY basic_string;\ntypedef basic_string<char, char_traits<char>, allocator<char> > string;\ntypedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring;\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_IOSFWD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/iostream",
    "content": "// -*- C++ -*-\n//===--------------------------- iostream ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_IOSTREAM\n#define _LIBCPP_IOSTREAM\n\n/*\n    iostream synopsis\n\n#include <ios>\n#include <streambuf>\n#include <istream>\n#include <ostream>\n\nnamespace std {\n\nextern istream cin;\nextern ostream cout;\nextern ostream cerr;\nextern ostream clog;\nextern wistream wcin;\nextern wostream wcout;\nextern wostream wcerr;\nextern wostream wclog;\n\n}  // std\n\n*/\n\n#include <__config>\n#include <ios>\n#include <streambuf>\n#include <istream>\n#include <ostream>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n#ifndef _LIBCPP_HAS_NO_STDIN\nextern _LIBCPP_FUNC_VIS istream cin;\nextern _LIBCPP_FUNC_VIS wistream wcin;\n#endif\n#ifndef _LIBCPP_HAS_NO_STDOUT\nextern _LIBCPP_FUNC_VIS ostream cout;\nextern _LIBCPP_FUNC_VIS wostream wcout;\n#endif\nextern _LIBCPP_FUNC_VIS ostream cerr;\nextern _LIBCPP_FUNC_VIS wostream wcerr;\nextern _LIBCPP_FUNC_VIS ostream clog;\nextern _LIBCPP_FUNC_VIS wostream wclog;\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_IOSTREAM\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/istream",
    "content": "// -*- C++ -*-\n//===--------------------------- istream ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_ISTREAM\n#define _LIBCPP_ISTREAM\n\n/*\n    istream synopsis\n\ntemplate <class charT, class traits = char_traits<charT> >\nclass basic_istream\n    : virtual public basic_ios<charT,traits>\n{\npublic:\n    // types (inherited from basic_ios (27.5.4)):\n    typedef charT                          char_type;\n    typedef traits                         traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    // 27.7.1.1.1 Constructor/destructor:\n    explicit basic_istream(basic_streambuf<char_type, traits_type>* sb);\n    basic_istream(basic_istream&& rhs);\n    virtual ~basic_istream();\n\n    // 27.7.1.1.2 Assign/swap:\n    basic_istream& operator=(basic_istream&& rhs);\n    void swap(basic_istream& rhs);\n\n    // 27.7.1.1.3 Prefix/suffix:\n    class sentry;\n\n    // 27.7.1.2 Formatted input:\n    basic_istream& operator>>(basic_istream& (*pf)(basic_istream&));\n    basic_istream& operator>>(basic_ios<char_type, traits_type>&\n                              (*pf)(basic_ios<char_type, traits_type>&));\n    basic_istream& operator>>(ios_base& (*pf)(ios_base&));\n    basic_istream& operator>>(basic_streambuf<char_type, traits_type>* sb);\n    basic_istream& operator>>(bool& n);\n    basic_istream& operator>>(short& n);\n    basic_istream& operator>>(unsigned short& n);\n    basic_istream& operator>>(int& n);\n    basic_istream& operator>>(unsigned int& n);\n    basic_istream& operator>>(long& n);\n    basic_istream& operator>>(unsigned long& n);\n    basic_istream& operator>>(long long& n);\n    basic_istream& operator>>(unsigned long long& n);\n    basic_istream& operator>>(float& f);\n    basic_istream& operator>>(double& f);\n    basic_istream& operator>>(long double& f);\n    basic_istream& operator>>(void*& p);\n\n    // 27.7.1.3 Unformatted input:\n    streamsize gcount() const;\n    int_type get();\n    basic_istream& get(char_type& c);\n    basic_istream& get(char_type* s, streamsize n);\n    basic_istream& get(char_type* s, streamsize n, char_type delim);\n    basic_istream& get(basic_streambuf<char_type,traits_type>& sb);\n    basic_istream& get(basic_streambuf<char_type,traits_type>& sb, char_type delim);\n\n    basic_istream& getline(char_type* s, streamsize n);\n    basic_istream& getline(char_type* s, streamsize n, char_type delim);\n\n    basic_istream& ignore(streamsize n = 1, int_type delim = traits_type::eof());\n    int_type peek();\n    basic_istream& read (char_type* s, streamsize n);\n    streamsize readsome(char_type* s, streamsize n);\n\n    basic_istream& putback(char_type c);\n    basic_istream& unget();\n    int sync();\n\n    pos_type tellg();\n    basic_istream& seekg(pos_type);\n    basic_istream& seekg(off_type, ios_base::seekdir);\nprotected:\n    basic_istream(const basic_istream& rhs) = delete;\n    basic_istream(basic_istream&& rhs);\n    // 27.7.2.1.2 Assign/swap:\n    basic_istream& operator=(const basic_istream& rhs) = delete;\n    basic_istream& operator=(basic_istream&& rhs);\n    void swap(basic_istream& rhs);\n};\n\n// 27.7.1.2.3 character extraction templates:\ntemplate<class charT, class traits>\n  basic_istream<charT,traits>& operator>>(basic_istream<charT,traits>&, charT&);\n\ntemplate<class traits>\n  basic_istream<char,traits>& operator>>(basic_istream<char,traits>&, unsigned char&);\n\ntemplate<class traits>\n  basic_istream<char,traits>& operator>>(basic_istream<char,traits>&, signed char&);\n\ntemplate<class charT, class traits>\n  basic_istream<charT,traits>& operator>>(basic_istream<charT,traits>&, charT*);\n\ntemplate<class traits>\n  basic_istream<char,traits>& operator>>(basic_istream<char,traits>&, unsigned char*);\n\ntemplate<class traits>\n  basic_istream<char,traits>& operator>>(basic_istream<char,traits>&, signed char*);\n\ntemplate <class charT, class traits>\n  void\n  swap(basic_istream<charT, traits>& x, basic_istream<charT, traits>& y);\n\ntypedef basic_istream<char> istream;\ntypedef basic_istream<wchar_t> wistream;\n\ntemplate <class charT, class traits = char_traits<charT> >\nclass basic_iostream :\n    public basic_istream<charT,traits>,\n    public basic_ostream<charT,traits>\n{\npublic:\n    // types:\n    typedef charT                          char_type;\n    typedef traits                         traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    // constructor/destructor\n    explicit basic_iostream(basic_streambuf<char_type, traits_type>* sb);\n    basic_iostream(basic_iostream&& rhs);\n    virtual ~basic_iostream();\n\n    // assign/swap\n    basic_iostream& operator=(basic_iostream&& rhs);\n    void swap(basic_iostream& rhs);\n};\n\ntemplate <class charT, class traits>\n  void\n  swap(basic_iostream<charT, traits>& x, basic_iostream<charT, traits>& y);\n\ntypedef basic_iostream<char> iostream;\ntypedef basic_iostream<wchar_t> wiostream;\n\ntemplate <class charT, class traits>\n  basic_istream<charT,traits>&\n  ws(basic_istream<charT,traits>& is);\n\ntemplate <class charT, class traits, class T>\n  basic_istream<charT, traits>&\n  operator>>(basic_istream<charT, traits>&& is, T& x);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <ostream>\n\n#include <__undef_min_max>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _CharT, class _Traits>\nclass _LIBCPP_TYPE_VIS_ONLY basic_istream\n    : virtual public basic_ios<_CharT, _Traits>\n{\n    streamsize __gc_;\npublic:\n    // types (inherited from basic_ios (27.5.4)):\n    typedef _CharT                         char_type;\n    typedef _Traits                        traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    // 27.7.1.1.1 Constructor/destructor:\n    explicit basic_istream(basic_streambuf<char_type, traits_type>* __sb);\n    virtual ~basic_istream();\nprotected:\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    basic_istream(basic_istream&& __rhs);\n#endif\n    // 27.7.1.1.2 Assign/swap:\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    basic_istream& operator=(basic_istream&& __rhs);\n#endif\n    void swap(basic_istream& __rhs);\n\n#if _LIBCPP_STD_VER > 11\n#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n    basic_istream           (const basic_istream& __rhs) = delete;\n    basic_istream& operator=(const basic_istream& __rhs) = delete;\n#else\n    basic_istream           (const basic_istream& __rhs); // not defined\n    basic_istream& operator=(const basic_istream& __rhs); // not defined\n#endif\n#endif\npublic:\n\n    // 27.7.1.1.3 Prefix/suffix:\n    class _LIBCPP_TYPE_VIS_ONLY sentry;\n\n    // 27.7.1.2 Formatted input:\n    basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&));\n    basic_istream& operator>>(basic_ios<char_type, traits_type>&\n                              (*__pf)(basic_ios<char_type, traits_type>&));\n    basic_istream& operator>>(ios_base& (*__pf)(ios_base&));\n    basic_istream& operator>>(basic_streambuf<char_type, traits_type>* __sb);\n    basic_istream& operator>>(bool& __n);\n    basic_istream& operator>>(short& __n);\n    basic_istream& operator>>(unsigned short& __n);\n    basic_istream& operator>>(int& __n);\n    basic_istream& operator>>(unsigned int& __n);\n    basic_istream& operator>>(long& __n);\n    basic_istream& operator>>(unsigned long& __n);\n    basic_istream& operator>>(long long& __n);\n    basic_istream& operator>>(unsigned long long& __n);\n    basic_istream& operator>>(float& __f);\n    basic_istream& operator>>(double& __f);\n    basic_istream& operator>>(long double& __f);\n    basic_istream& operator>>(void*& __p);\n\n    // 27.7.1.3 Unformatted input:\n    _LIBCPP_INLINE_VISIBILITY\n    streamsize gcount() const {return __gc_;}\n    int_type get();\n    basic_istream& get(char_type& __c);\n    basic_istream& get(char_type* __s, streamsize __n);\n    basic_istream& get(char_type* __s, streamsize __n, char_type __dlm);\n    basic_istream& get(basic_streambuf<char_type, traits_type>& __sb);\n    basic_istream& get(basic_streambuf<char_type, traits_type>& __sb, char_type __dlm);\n\n    basic_istream& getline(char_type* __s, streamsize __n);\n    basic_istream& getline(char_type* __s, streamsize __n, char_type __dlm);\n\n    basic_istream& ignore(streamsize __n = 1, int_type __dlm = traits_type::eof());\n    int_type peek();\n    basic_istream& read (char_type* __s, streamsize __n);\n    streamsize readsome(char_type* __s, streamsize __n);\n\n    basic_istream& putback(char_type __c);\n    basic_istream& unget();\n    int sync();\n\n    pos_type tellg();\n    basic_istream& seekg(pos_type __pos);\n    basic_istream& seekg(off_type __off, ios_base::seekdir __dir);\n};\n\ntemplate <class _CharT, class _Traits>\nclass _LIBCPP_TYPE_VIS_ONLY basic_istream<_CharT, _Traits>::sentry\n{\n    bool __ok_;\n\n    sentry(const sentry&); // = delete;\n    sentry& operator=(const sentry&); // = delete;\n\npublic:\n    explicit sentry(basic_istream<_CharT, _Traits>& __is, bool __noskipws = false);\n//    ~sentry() = default;\n\n    _LIBCPP_INLINE_VISIBILITY\n        _LIBCPP_EXPLICIT\n        operator bool() const {return __ok_;}\n};\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>::sentry::sentry(basic_istream<_CharT, _Traits>& __is,\n                                               bool __noskipws)\n    : __ok_(false)\n{\n    if (__is.good())\n    {\n        if (__is.tie())\n            __is.tie()->flush();\n        if (!__noskipws && (__is.flags() & ios_base::skipws))\n        {\n            typedef istreambuf_iterator<_CharT, _Traits> _Ip;\n            const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());\n            _Ip __i(__is);\n            _Ip __eof;\n            for (; __i != __eof; ++__i)\n                if (!__ct.is(__ct.space, *__i))\n                    break;\n            if (__i == __eof)\n                __is.setstate(ios_base::failbit | ios_base::eofbit);\n        }\n        __ok_ = __is.good();\n    }\n    else\n        __is.setstate(ios_base::failbit);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>::basic_istream(basic_streambuf<char_type, traits_type>* __sb)\n    : __gc_(0)\n{\n    this->init(__sb);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>::basic_istream(basic_istream&& __rhs)\n    : __gc_(__rhs.__gc_)\n{\n    __rhs.__gc_ = 0;\n    this->move(__rhs);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator=(basic_istream&& __rhs)\n{\n    swap(__rhs);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>::~basic_istream()\n{\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_istream<_CharT, _Traits>::swap(basic_istream& __rhs)\n{\n    _VSTD::swap(__gc_, __rhs.__gc_);\n    basic_ios<char_type, traits_type>::swap(__rhs);\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(unsigned short& __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef istreambuf_iterator<char_type, traits_type> _Ip;\n            typedef num_get<char_type, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(unsigned int& __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef istreambuf_iterator<char_type, traits_type> _Ip;\n            typedef num_get<char_type, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(long& __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef istreambuf_iterator<char_type, traits_type> _Ip;\n            typedef num_get<char_type, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(unsigned long& __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef istreambuf_iterator<char_type, traits_type> _Ip;\n            typedef num_get<char_type, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(long long& __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef istreambuf_iterator<char_type, traits_type> _Ip;\n            typedef num_get<char_type, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(unsigned long long& __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef istreambuf_iterator<char_type, traits_type> _Ip;\n            typedef num_get<char_type, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(float& __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef istreambuf_iterator<char_type, traits_type> _Ip;\n            typedef num_get<char_type, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(double& __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef istreambuf_iterator<char_type, traits_type> _Ip;\n            typedef num_get<char_type, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(long double& __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef istreambuf_iterator<char_type, traits_type> _Ip;\n            typedef num_get<char_type, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(bool& __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef istreambuf_iterator<char_type, traits_type> _Ip;\n            typedef num_get<char_type, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(void*& __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef istreambuf_iterator<char_type, traits_type> _Ip;\n            typedef num_get<char_type, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(short& __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef istreambuf_iterator<char_type, traits_type> _Ip;\n            typedef num_get<char_type, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            long __temp;\n            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __temp);\n            if (__temp < numeric_limits<short>::min())\n            {\n                __err |= ios_base::failbit;\n                __n = numeric_limits<short>::min();\n            }\n            else if (__temp > numeric_limits<short>::max())\n            {\n                __err |= ios_base::failbit;\n                __n = numeric_limits<short>::max();\n            }\n            else\n                __n = static_cast<short>(__temp);\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(int& __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef istreambuf_iterator<char_type, traits_type> _Ip;\n            typedef num_get<char_type, _Ip> _Fp;\n            ios_base::iostate __err = ios_base::goodbit;\n            long __temp;\n            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __temp);\n            if (__temp < numeric_limits<int>::min())\n            {\n                __err |= ios_base::failbit;\n                __n = numeric_limits<int>::min();\n            }\n            else if (__temp > numeric_limits<int>::max())\n            {\n                __err |= ios_base::failbit;\n                __n = numeric_limits<int>::max();\n            }\n            else\n                __n = static_cast<int>(__temp);\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(basic_istream& (*__pf)(basic_istream&))\n{\n    return __pf(*this);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(basic_ios<char_type, traits_type>&\n                                           (*__pf)(basic_ios<char_type, traits_type>&))\n{\n    __pf(*this);\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(ios_base& (*__pf)(ios_base&))\n{\n    __pf(*this);\n    return *this;\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typename basic_istream<_CharT, _Traits>::sentry __sen(__is);\n        if (__sen)\n        {\n            streamsize __n = __is.width();\n            if (__n <= 0)\n                __n = numeric_limits<streamsize>::max() / sizeof(_CharT) - 1;\n            streamsize __c = 0;\n            const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());\n            ios_base::iostate __err = ios_base::goodbit;\n            while (__c < __n-1)\n            {\n                typename _Traits::int_type __i = __is.rdbuf()->sgetc();\n                if (_Traits::eq_int_type(__i, _Traits::eof()))\n                {\n                   __err |= ios_base::eofbit;\n                   break;\n                }\n                _CharT __ch = _Traits::to_char_type(__i);\n                if (__ct.is(__ct.space, __ch))\n                    break;\n                *__s++ = __ch;\n                ++__c;\n                 __is.rdbuf()->sbumpc();\n            }\n            *__s = _CharT();\n            __is.width(0);\n            if (__c == 0)\n               __err |= ios_base::failbit;\n            __is.setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __is.__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __is;\n}\n\ntemplate<class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<char, _Traits>&\noperator>>(basic_istream<char, _Traits>& __is, unsigned char* __s)\n{\n    return __is >> (char*)__s;\n}\n\ntemplate<class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<char, _Traits>&\noperator>>(basic_istream<char, _Traits>& __is, signed char* __s)\n{\n    return __is >> (char*)__s;\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typename basic_istream<_CharT, _Traits>::sentry __sen(__is);\n        if (__sen)\n        {\n            typename _Traits::int_type __i = __is.rdbuf()->sbumpc();\n            if (_Traits::eq_int_type(__i, _Traits::eof()))\n                __is.setstate(ios_base::eofbit | ios_base::failbit);\n            else\n                __c = _Traits::to_char_type(__i);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __is.__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __is;\n}\n\ntemplate<class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<char, _Traits>&\noperator>>(basic_istream<char, _Traits>& __is, unsigned char& __c)\n{\n    return __is >> (char&)__c;\n}\n\ntemplate<class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<char, _Traits>&\noperator>>(basic_istream<char, _Traits>& __is, signed char& __c)\n{\n    return __is >> (char&)__c;\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_type>* __sb)\n{\n    __gc_ = 0;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this, true);\n        if (__s)\n        {\n            if (__sb)\n            {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n                try\n                {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n                    ios_base::iostate __err = ios_base::goodbit;\n                    while (true)\n                    {\n                        typename traits_type::int_type __i = this->rdbuf()->sgetc();\n                        if (traits_type::eq_int_type(__i, _Traits::eof()))\n                        {\n                           __err |= ios_base::eofbit;\n                           break;\n                        }\n                        if (traits_type::eq_int_type(\n                                __sb->sputc(traits_type::to_char_type(__i)),\n                                traits_type::eof()))\n                            break;\n                        ++__gc_;\n                        this->rdbuf()->sbumpc();\n                    }\n                    if (__gc_ == 0)\n                       __err |= ios_base::failbit;\n                    this->setstate(__err);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n                }\n                catch (...)\n                {\n                    if (__gc_ == 0)\n                        this->__set_failbit_and_consider_rethrow();\n                }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            }\n            else\n                this->setstate(ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate<class _CharT, class _Traits>\ntypename basic_istream<_CharT, _Traits>::int_type\nbasic_istream<_CharT, _Traits>::get()\n{\n    __gc_ = 0;\n    int_type __r = traits_type::eof();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this, true);\n        if (__s)\n        {\n            __r = this->rdbuf()->sbumpc();\n            if (traits_type::eq_int_type(__r, traits_type::eof()))\n               this->setstate(ios_base::failbit | ios_base::eofbit);\n            else\n                __gc_ = 1;\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __r;\n}\n\ntemplate<class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::get(char_type& __c)\n{\n    int_type __ch = get();\n    if (__ch != traits_type::eof())\n        __c = traits_type::to_char_type(__ch);\n    return *this;\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __dlm)\n{\n    __gc_ = 0;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __sen(*this, true);\n        if (__sen)\n        {\n            if (__n > 0)\n            {\n                ios_base::iostate __err = ios_base::goodbit;\n                while (__gc_ < __n-1)\n                {\n                    int_type __i = this->rdbuf()->sgetc();\n                    if (traits_type::eq_int_type(__i, traits_type::eof()))\n                    {\n                       __err |= ios_base::eofbit;\n                       break;\n                    }\n                    char_type __ch = traits_type::to_char_type(__i);\n                    if (traits_type::eq(__ch, __dlm))\n                        break;\n                    *__s++ = __ch;\n                    ++__gc_;\n                     this->rdbuf()->sbumpc();\n                }\n                *__s = char_type();\n                if (__gc_ == 0)\n                   __err |= ios_base::failbit;\n                this->setstate(__err);\n            }\n            else\n                this->setstate(ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate<class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n)\n{\n    return get(__s, __n, this->widen('\\n'));\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __sb,\n                                    char_type __dlm)\n{\n    __gc_ = 0;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __sen(*this, true);\n        if (__sen)\n        {\n            ios_base::iostate __err = ios_base::goodbit;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            try\n            {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n                while (true)\n                {\n                    typename traits_type::int_type __i = this->rdbuf()->sgetc();\n                    if (traits_type::eq_int_type(__i, traits_type::eof()))\n                    {\n                       __err |= ios_base::eofbit;\n                       break;\n                    }\n                    char_type __ch = traits_type::to_char_type(__i);\n                    if (traits_type::eq(__ch, __dlm))\n                        break;\n                    if (traits_type::eq_int_type(__sb.sputc(__ch), traits_type::eof()))\n                        break;\n                    ++__gc_;\n                    this->rdbuf()->sbumpc();\n                }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            }\n            catch (...)\n            {\n            }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            if (__gc_ == 0)\n               __err |= ios_base::failbit;\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate<class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __sb)\n{\n    return get(__sb, this->widen('\\n'));\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_type __dlm)\n{\n    __gc_ = 0;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __sen(*this, true);\n        if (__sen)\n        {\n            ios_base::iostate __err = ios_base::goodbit;\n            while (true)\n            {\n                typename traits_type::int_type __i = this->rdbuf()->sgetc();\n                if (traits_type::eq_int_type(__i, traits_type::eof()))\n                {\n                   __err |= ios_base::eofbit;\n                   break;\n                }\n                char_type __ch = traits_type::to_char_type(__i);\n                if (traits_type::eq(__ch, __dlm))\n                {\n                    this->rdbuf()->sbumpc();\n                    ++__gc_;\n                    break;\n                }\n                if (__gc_ >= __n-1)\n                {\n                    __err |= ios_base::failbit;\n                    break;\n                }\n                *__s++ = __ch;\n                this->rdbuf()->sbumpc();\n                ++__gc_;\n            }\n            if (__n > 0)\n                *__s = char_type();\n            if (__gc_ == 0)\n               __err |= ios_base::failbit;\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate<class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n)\n{\n    return getline(__s, __n, this->widen('\\n'));\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)\n{\n    __gc_ = 0;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __sen(*this, true);\n        if (__sen)\n        {\n            ios_base::iostate __err = ios_base::goodbit;\n            if (__n == numeric_limits<streamsize>::max())\n            {\n                while (true)\n                {\n                    typename traits_type::int_type __i = this->rdbuf()->sbumpc();\n                    if (traits_type::eq_int_type(__i, traits_type::eof()))\n                    {\n                       __err |= ios_base::eofbit;\n                       break;\n                    }\n                    ++__gc_;\n                    if (traits_type::eq_int_type(__i, __dlm))\n                        break;\n                }\n            }\n            else\n            {\n                while (__gc_ < __n)\n                {\n                    typename traits_type::int_type __i = this->rdbuf()->sbumpc();\n                    if (traits_type::eq_int_type(__i, traits_type::eof()))\n                    {\n                       __err |= ios_base::eofbit;\n                       break;\n                    }\n                    ++__gc_;\n                    if (traits_type::eq_int_type(__i, __dlm))\n                        break;\n                }\n            }\n            this->setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate<class _CharT, class _Traits>\ntypename basic_istream<_CharT, _Traits>::int_type\nbasic_istream<_CharT, _Traits>::peek()\n{\n    __gc_ = 0;\n    int_type __r = traits_type::eof();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __sen(*this, true);\n        if (__sen)\n        {\n            __r = this->rdbuf()->sgetc();\n            if (traits_type::eq_int_type(__r, traits_type::eof()))\n                this->setstate(ios_base::eofbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __r;\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n)\n{\n    __gc_ = 0;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __sen(*this, true);\n        if (__sen)\n        {\n            __gc_ = this->rdbuf()->sgetn(__s, __n);\n            if (__gc_ != __n)\n                this->setstate(ios_base::failbit | ios_base::eofbit);\n        }\n        else\n            this->setstate(ios_base::failbit);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate<class _CharT, class _Traits>\nstreamsize\nbasic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n)\n{\n    __gc_ = 0;\n    streamsize __c = this->rdbuf()->in_avail();\n    switch (__c)\n    {\n    case -1:\n        this->setstate(ios_base::eofbit);\n        break;\n    case 0:\n        break;\n    default:\n        read(__s, _VSTD::min(__c, __n));\n        break;\n    }\n    return __gc_;\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::putback(char_type __c)\n{\n    __gc_ = 0;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        this->clear(this->rdstate() & ~ios_base::eofbit);\n        sentry __sen(*this, true);\n        if (__sen)\n        {\n            if (this->rdbuf() == 0 || this->rdbuf()->sputbackc(__c) == traits_type::eof())\n                this->setstate(ios_base::badbit);\n        }\n        else\n            this->setstate(ios_base::failbit);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::unget()\n{\n    __gc_ = 0;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        this->clear(this->rdstate() & ~ios_base::eofbit);\n        sentry __sen(*this, true);\n        if (__sen)\n        {\n            if (this->rdbuf() == 0 || this->rdbuf()->sungetc() == traits_type::eof())\n                this->setstate(ios_base::badbit);\n        }\n        else\n            this->setstate(ios_base::failbit);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate<class _CharT, class _Traits>\nint\nbasic_istream<_CharT, _Traits>::sync()\n{\n    int __r = 0;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __sen(*this, true);\n        if (__sen)\n        {\n            if (this->rdbuf() == 0)\n                return -1;\n            if (this->rdbuf()->pubsync() == -1)\n            {\n                this->setstate(ios_base::badbit);\n                return -1;\n            }\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __r;\n}\n\ntemplate<class _CharT, class _Traits>\ntypename basic_istream<_CharT, _Traits>::pos_type\nbasic_istream<_CharT, _Traits>::tellg()\n{\n    pos_type __r(-1);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __sen(*this, true);\n        if (__sen)\n            __r = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __r;\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::seekg(pos_type __pos)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        this->clear(this->rdstate() & ~ios_base::eofbit);\n        sentry __sen(*this, true);\n        if (__sen)\n        {\n            if (this->rdbuf()->pubseekpos(__pos, ios_base::in) == pos_type(-1))\n                this->setstate(ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nbasic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __sen(*this, true);\n        if (__sen)\n        {\n            if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::in) == pos_type(-1))\n                this->setstate(ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\nws(basic_istream<_CharT, _Traits>& __is)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true);\n        if (__sen)\n        {\n            const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());\n            while (true)\n            {\n                typename _Traits::int_type __i = __is.rdbuf()->sgetc();\n                if (_Traits::eq_int_type(__i, _Traits::eof()))\n                {\n                   __is.setstate(ios_base::eofbit);\n                   break;\n                }\n                if (!__ct.is(__ct.space, _Traits::to_char_type(__i)))\n                    break;\n                __is.rdbuf()->sbumpc();\n            }\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __is.__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __is;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>&& __is, _Tp& __x)\n{\n    __is >> __x;\n    return __is;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\nclass _LIBCPP_TYPE_VIS_ONLY basic_iostream\n    : public basic_istream<_CharT, _Traits>,\n      public basic_ostream<_CharT, _Traits>\n{\npublic:\n    // types:\n    typedef _CharT                         char_type;\n    typedef _Traits                        traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    // constructor/destructor\n    explicit basic_iostream(basic_streambuf<char_type, traits_type>* __sb);\n    virtual ~basic_iostream();\nprotected:\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    basic_iostream(basic_iostream&& __rhs);\n#endif\n\n    // assign/swap\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    basic_iostream& operator=(basic_iostream&& __rhs);\n#endif\n    void swap(basic_iostream& __rhs);\npublic:\n};\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_iostream<_CharT, _Traits>::basic_iostream(basic_streambuf<char_type, traits_type>* __sb)\n    : basic_istream<_CharT, _Traits>(__sb)\n{\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_iostream<_CharT, _Traits>::basic_iostream(basic_iostream&& __rhs)\n    : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs))\n{\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_iostream<_CharT, _Traits>&\nbasic_iostream<_CharT, _Traits>::operator=(basic_iostream&& __rhs)\n{\n    swap(__rhs);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\nbasic_iostream<_CharT, _Traits>::~basic_iostream()\n{\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_iostream<_CharT, _Traits>::swap(basic_iostream& __rhs)\n{\n    basic_istream<char_type, traits_type>::swap(__rhs);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           basic_string<_CharT, _Traits, _Allocator>& __str)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typename basic_istream<_CharT, _Traits>::sentry __sen(__is);\n        if (__sen)\n        {\n            __str.clear();\n            streamsize __n = __is.width();\n            if (__n <= 0)\n                __n = __str.max_size();\n            if (__n <= 0)\n                __n = numeric_limits<streamsize>::max();\n            streamsize __c = 0;\n            const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());\n            ios_base::iostate __err = ios_base::goodbit;\n            while (__c < __n)\n            {\n                typename _Traits::int_type __i = __is.rdbuf()->sgetc();\n                if (_Traits::eq_int_type(__i, _Traits::eof()))\n                {\n                   __err |= ios_base::eofbit;\n                   break;\n                }\n                _CharT __ch = _Traits::to_char_type(__i);\n                if (__ct.is(__ct.space, __ch))\n                    break;\n                __str.push_back(__ch);\n                ++__c;\n                 __is.rdbuf()->sbumpc();\n            }\n            __is.width(0);\n            if (__c == 0)\n               __err |= ios_base::failbit;\n            __is.setstate(__err);\n        }\n        else\n            __is.setstate(ios_base::failbit);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __is.__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __is;\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_istream<_CharT, _Traits>&\ngetline(basic_istream<_CharT, _Traits>& __is,\n        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true);\n        if (__sen)\n        {\n            __str.clear();\n            ios_base::iostate __err = ios_base::goodbit;\n            streamsize __extr = 0;\n            while (true)\n            {\n                typename _Traits::int_type __i = __is.rdbuf()->sbumpc();\n                if (_Traits::eq_int_type(__i, _Traits::eof()))\n                {\n                   __err |= ios_base::eofbit;\n                   break;\n                }\n                ++__extr;\n                _CharT __ch = _Traits::to_char_type(__i);\n                if (_Traits::eq(__ch, __dlm))\n                    break;\n                __str.push_back(__ch);\n                if (__str.size() == __str.max_size())\n                {\n                    __err |= ios_base::failbit;\n                    break;\n                }\n            }\n            if (__extr == 0)\n               __err |= ios_base::failbit;\n            __is.setstate(__err);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __is.__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __is;\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\ngetline(basic_istream<_CharT, _Traits>& __is,\n        basic_string<_CharT, _Traits, _Allocator>& __str)\n{\n    return getline(__is, __str, __is.widen('\\n'));\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\ngetline(basic_istream<_CharT, _Traits>&& __is,\n        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm)\n{\n    return getline(__is, __str, __dlm);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\ngetline(basic_istream<_CharT, _Traits>&& __is,\n        basic_string<_CharT, _Traits, _Allocator>& __str)\n{\n    return getline(__is, __str, __is.widen('\\n'));\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits, size_t _Size>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typename basic_istream<_CharT, _Traits>::sentry __sen(__is);\n        if (__sen)\n        {\n            basic_string<_CharT, _Traits> __str;\n            const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());\n            streamsize __c = 0;\n            ios_base::iostate __err = ios_base::goodbit;\n            _CharT __zero = __ct.widen('0');\n            _CharT __one = __ct.widen('1');\n            while (__c < _Size)\n            {\n                typename _Traits::int_type __i = __is.rdbuf()->sgetc();\n                if (_Traits::eq_int_type(__i, _Traits::eof()))\n                {\n                   __err |= ios_base::eofbit;\n                   break;\n                }\n                _CharT __ch = _Traits::to_char_type(__i);\n                if (!_Traits::eq(__ch, __zero) && !_Traits::eq(__ch, __one))\n                    break;\n                __str.push_back(__ch);\n                ++__c;\n                 __is.rdbuf()->sbumpc();\n            }\n            __x = bitset<_Size>(__str);\n            if (__c == 0)\n               __err |= ios_base::failbit;\n            __is.setstate(__err);\n        }\n        else\n            __is.setstate(ios_base::failbit);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __is.__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __is;\n}\n\n_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_istream<char>)\n_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_istream<wchar_t>)\n_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_iostream<char>)\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_ISTREAM\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/iterator",
    "content": "// -*- C++ -*-\n//===-------------------------- iterator ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_ITERATOR\n#define _LIBCPP_ITERATOR\n\n/*\n    iterator synopsis\n\nnamespace std\n{\n\ntemplate<class Iterator>\nstruct iterator_traits\n{\n    typedef typename Iterator::difference_type difference_type;\n    typedef typename Iterator::value_type value_type;\n    typedef typename Iterator::pointer pointer;\n    typedef typename Iterator::reference reference;\n    typedef typename Iterator::iterator_category iterator_category;\n};\n\ntemplate<class T>\nstruct iterator_traits<T*>\n{\n    typedef ptrdiff_t difference_type;\n    typedef T value_type;\n    typedef T* pointer;\n    typedef T& reference;\n    typedef random_access_iterator_tag iterator_category;\n};\n\ntemplate<class T>\nstruct iterator_traits<const T*>\n{\n    typedef ptrdiff_t difference_type;\n    typedef T value_type;\n    typedef const T* pointer;\n    typedef const T& reference;\n    typedef random_access_iterator_tag iterator_category;\n};\n\ntemplate<class Category, class T, class Distance = ptrdiff_t,\n         class Pointer = T*, class Reference = T&>\nstruct iterator\n{\n    typedef T         value_type;\n    typedef Distance  difference_type;\n    typedef Pointer   pointer;\n    typedef Reference reference;\n    typedef Category  iterator_category;\n};\n\nstruct input_iterator_tag  {};\nstruct output_iterator_tag {};\nstruct forward_iterator_tag       : public input_iterator_tag         {};\nstruct bidirectional_iterator_tag : public forward_iterator_tag       {};\nstruct random_access_iterator_tag : public bidirectional_iterator_tag {};\n\n// extension: second argument not conforming to C++03\ntemplate <class InputIterator>\nvoid advance(InputIterator& i,\n             typename iterator_traits<InputIterator>::difference_type n);\n\ntemplate <class InputIterator>\ntypename iterator_traits<InputIterator>::difference_type\ndistance(InputIterator first, InputIterator last);\n\ntemplate <class Iterator>\nclass reverse_iterator\n    : public iterator<typename iterator_traits<Iterator>::iterator_category,\n                      typename iterator_traits<Iterator>::value_type,\n                      typename iterator_traits<Iterator>::difference_type,\n                      typename iterator_traits<Iterator>::pointer,\n                      typename iterator_traits<Iterator>::reference>\n{\nprotected:\n    Iterator current;\npublic:\n    typedef Iterator                                            iterator_type;\n    typedef typename iterator_traits<Iterator>::difference_type difference_type;\n    typedef typename iterator_traits<Iterator>::reference       reference;\n    typedef typename iterator_traits<Iterator>::pointer         pointer;\n\n    reverse_iterator();\n    explicit reverse_iterator(Iterator x);\n    template <class U> reverse_iterator(const reverse_iterator<U>& u);\n    Iterator base() const;\n    reference operator*() const;\n    pointer   operator->() const;\n    reverse_iterator& operator++();\n    reverse_iterator  operator++(int);\n    reverse_iterator& operator--();\n    reverse_iterator  operator--(int);\n    reverse_iterator  operator+ (difference_type n) const;\n    reverse_iterator& operator+=(difference_type n);\n    reverse_iterator  operator- (difference_type n) const;\n    reverse_iterator& operator-=(difference_type n);\n    reference         operator[](difference_type n) const;\n};\n\ntemplate <class Iterator1, class Iterator2>\nbool\noperator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);\n\ntemplate <class Iterator1, class Iterator2>\nbool\noperator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);\n\ntemplate <class Iterator1, class Iterator2>\nbool\noperator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);\n\ntemplate <class Iterator1, class Iterator2>\nbool\noperator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);\n\ntemplate <class Iterator1, class Iterator2>\nbool\noperator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);\n\ntemplate <class Iterator1, class Iterator2>\nbool\noperator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);\n\ntemplate <class Iterator1, class Iterator2>\ntypename reverse_iterator<Iterator1>::difference_type\noperator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);\n\ntemplate <class Iterator>\nreverse_iterator<Iterator>\noperator+(typename reverse_iterator<Iterator>::difference_type n, const reverse_iterator<Iterator>& x);\n\ntemplate <class Iterator> reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14\n\ntemplate <class Container>\nclass back_insert_iterator\n{\nprotected:\n    Container* container;\npublic:\n    typedef Container                   container_type;\n    typedef void                        value_type;\n    typedef void                        difference_type;\n    typedef back_insert_iterator<Cont>& reference;\n    typedef void                        pointer;\n\n    explicit back_insert_iterator(Container& x);\n    back_insert_iterator& operator=(const typename Container::value_type& value);\n    back_insert_iterator& operator*();\n    back_insert_iterator& operator++();\n    back_insert_iterator  operator++(int);\n};\n\ntemplate <class Container> back_insert_iterator<Container> back_inserter(Container& x);\n\ntemplate <class Container>\nclass front_insert_iterator\n{\nprotected:\n    Container* container;\npublic:\n    typedef Container                    container_type;\n    typedef void                         value_type;\n    typedef void                         difference_type;\n    typedef front_insert_iterator<Cont>& reference;\n    typedef void                         pointer;\n\n    explicit front_insert_iterator(Container& x);\n    front_insert_iterator& operator=(const typename Container::value_type& value);\n    front_insert_iterator& operator*();\n    front_insert_iterator& operator++();\n    front_insert_iterator  operator++(int);\n};\n\ntemplate <class Container> front_insert_iterator<Container> front_inserter(Container& x);\n\ntemplate <class Container>\nclass insert_iterator\n{\nprotected:\n    Container* container;\n    typename Container::iterator iter;\npublic:\n    typedef Container              container_type;\n    typedef void                   value_type;\n    typedef void                   difference_type;\n    typedef insert_iterator<Cont>& reference;\n    typedef void                   pointer;\n\n    insert_iterator(Container& x, typename Container::iterator i);\n    insert_iterator& operator=(const typename Container::value_type& value);\n    insert_iterator& operator*();\n    insert_iterator& operator++();\n    insert_iterator& operator++(int);\n};\n\ntemplate <class Container, class Iterator>\ninsert_iterator<Container> inserter(Container& x, Iterator i);\n\ntemplate <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t>\nclass istream_iterator\n    : public iterator<input_iterator_tag, T, Distance, const T*, const T&>\n{\npublic:\n    typedef charT char_type;\n    typedef traits traits_type;\n    typedef basic_istream<charT,traits> istream_type;\n\n    constexpr istream_iterator();\n    istream_iterator(istream_type& s);\n    istream_iterator(const istream_iterator& x);\n    ~istream_iterator();\n\n    const T& operator*() const;\n    const T* operator->() const;\n    istream_iterator& operator++();\n    istream_iterator  operator++(int);\n};\n\ntemplate <class T, class charT, class traits, class Distance>\nbool operator==(const istream_iterator<T,charT,traits,Distance>& x,\n                const istream_iterator<T,charT,traits,Distance>& y);\ntemplate <class T, class charT, class traits, class Distance>\nbool operator!=(const istream_iterator<T,charT,traits,Distance>& x,\n                const istream_iterator<T,charT,traits,Distance>& y);\n\ntemplate <class T, class charT = char, class traits = char_traits<charT> >\nclass ostream_iterator\n    : public iterator<output_iterator_tag, void, void, void ,void>\n{\npublic:\n    typedef charT char_type;\n    typedef traits traits_type;\n    typedef basic_ostream<charT,traits> ostream_type;\n\n    ostream_iterator(ostream_type& s);\n    ostream_iterator(ostream_type& s, const charT* delimiter);\n    ostream_iterator(const ostream_iterator& x);\n    ~ostream_iterator();\n    ostream_iterator& operator=(const T& value);\n\n    ostream_iterator& operator*();\n    ostream_iterator& operator++();\n    ostream_iterator& operator++(int);\n};\n\ntemplate<class charT, class traits = char_traits<charT> >\nclass istreambuf_iterator\n    : public iterator<input_iterator_tag, charT,\n                      typename traits::off_type, unspecified,\n                      charT>\n{\npublic:\n    typedef charT                         char_type;\n    typedef traits                        traits_type;\n    typedef typename traits::int_type     int_type;\n    typedef basic_streambuf<charT,traits> streambuf_type;\n    typedef basic_istream<charT,traits>   istream_type;\n\n    istreambuf_iterator() noexcept;\n    istreambuf_iterator(istream_type& s) noexcept;\n    istreambuf_iterator(streambuf_type* s) noexcept;\n    istreambuf_iterator(a-private-type) noexcept;\n\n    charT                operator*() const;\n    pointer operator->() const;\n    istreambuf_iterator& operator++();\n    a-private-type       operator++(int);\n\n    bool equal(const istreambuf_iterator& b) const;\n};\n\ntemplate <class charT, class traits>\nbool operator==(const istreambuf_iterator<charT,traits>& a,\n                const istreambuf_iterator<charT,traits>& b);\ntemplate <class charT, class traits>\nbool operator!=(const istreambuf_iterator<charT,traits>& a,\n                const istreambuf_iterator<charT,traits>& b);\n\ntemplate <class charT, class traits = char_traits<charT> >\nclass ostreambuf_iterator\n    : public iterator<output_iterator_tag, void, void, void, void>\n{\npublic:\n    typedef charT                         char_type;\n    typedef traits                        traits_type;\n    typedef basic_streambuf<charT,traits> streambuf_type;\n    typedef basic_ostream<charT,traits>   ostream_type;\n\n    ostreambuf_iterator(ostream_type& s) noexcept;\n    ostreambuf_iterator(streambuf_type* s) noexcept;\n    ostreambuf_iterator& operator=(charT c);\n    ostreambuf_iterator& operator*();\n    ostreambuf_iterator& operator++();\n    ostreambuf_iterator& operator++(int);\n    bool failed() const noexcept;\n};\n\ntemplate <class C> auto begin(C& c) -> decltype(c.begin());\ntemplate <class C> auto begin(const C& c) -> decltype(c.begin());\ntemplate <class C> auto end(C& c) -> decltype(c.end());\ntemplate <class C> auto end(const C& c) -> decltype(c.end());\ntemplate <class T, size_t N> T* begin(T (&array)[N]);\ntemplate <class T, size_t N> T* end(T (&array)[N]);\n\ntemplate <class C> auto cbegin(const C& c) -> decltype(std::begin(c));        // C++14\ntemplate <class C> auto cend(const C& c) -> decltype(std::end(c));            // C++14\ntemplate <class C> auto rbegin(C& c) -> decltype(c.rbegin());                 // C++14\ntemplate <class C> auto rbegin(const C& c) -> decltype(c.rbegin());           // C++14\ntemplate <class C> auto rend(C& c) -> decltype(c.rend());                     // C++14\ntemplate <class C> auto rend(const C& c) -> decltype(c.rend());               // C++14\ntemplate <class E> reverse_iterator<const E*> rbegin(initializer_list<E> il); // C++14\ntemplate <class E> reverse_iterator<const E*> rend(initializer_list<E> il);   // C++14\ntemplate <class T, size_t N> reverse_iterator<T*> rbegin(T (&array)[N]);      // C++14\ntemplate <class T, size_t N> reverse_iterator<T*> rend(T (&array)[N]);        // C++14\ntemplate <class C> auto crbegin(const C& c) -> decltype(std::rbegin(c));      // C++14\ntemplate <class C> auto crend(const C& c) -> decltype(std::rend(c));          // C++14\n\n// 24.8, container access:\ntemplate <class C> constexpr auto size(const C& c) -> decltype(c.size());         // C++17\ntemplate <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; // C++17\ntemplate <class C> constexpr auto empty(const C& c) -> decltype(c.empty());       // C++17\ntemplate <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;  // C++17\ntemplate <class E> constexpr bool empty(initializer_list<E> il) noexcept;         // C++17\ntemplate <class C> constexpr auto data(C& c) -> decltype(c.data());               // C++17\ntemplate <class C> constexpr auto data(const C& c) -> decltype(c.data());         // C++17\ntemplate <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;           // C++17\ntemplate <class E> constexpr const E* data(initializer_list<E> il) noexcept;      // C++17\n\n}  // std\n\n*/\n\n#include <__config>\n#include <__functional_base>\n#include <type_traits>\n#include <cstddef>\n#include <iosfwd>\n#include <initializer_list>\n#ifdef __APPLE__\n#include <Availability.h>\n#endif\n\n#include <__debug>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nstruct _LIBCPP_TYPE_VIS_ONLY input_iterator_tag {};\nstruct _LIBCPP_TYPE_VIS_ONLY output_iterator_tag {};\nstruct _LIBCPP_TYPE_VIS_ONLY forward_iterator_tag       : public input_iterator_tag {};\nstruct _LIBCPP_TYPE_VIS_ONLY bidirectional_iterator_tag : public forward_iterator_tag {};\nstruct _LIBCPP_TYPE_VIS_ONLY random_access_iterator_tag : public bidirectional_iterator_tag {};\n\ntemplate <class _Tp>\nstruct __has_iterator_category\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::iterator_category* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\ntemplate <class _Iter, bool> struct __iterator_traits_impl {};\n\ntemplate <class _Iter>\nstruct __iterator_traits_impl<_Iter, true>\n{\n    typedef typename _Iter::difference_type   difference_type;\n    typedef typename _Iter::value_type        value_type;\n    typedef typename _Iter::pointer           pointer;\n    typedef typename _Iter::reference         reference;\n    typedef typename _Iter::iterator_category iterator_category;\n};\n\ntemplate <class _Iter, bool> struct __iterator_traits {};\n\ntemplate <class _Iter>\nstruct __iterator_traits<_Iter, true>\n    :  __iterator_traits_impl\n      <\n        _Iter,\n        is_convertible<typename _Iter::iterator_category, input_iterator_tag>::value ||\n        is_convertible<typename _Iter::iterator_category, output_iterator_tag>::value\n      >\n{};\n\n// iterator_traits<Iterator> will only have the nested types if Iterator::iterator_category\n//    exists.  Else iterator_traits<Iterator> will be an empty class.  This is a\n//    conforming extension which allows some programs to compile and behave as\n//    the client expects instead of failing at compile time.\n\ntemplate <class _Iter>\nstruct _LIBCPP_TYPE_VIS_ONLY iterator_traits\n    : __iterator_traits<_Iter, __has_iterator_category<_Iter>::value> {};\n\ntemplate<class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY iterator_traits<_Tp*>\n{\n    typedef ptrdiff_t difference_type;\n    typedef typename remove_const<_Tp>::type value_type;\n    typedef _Tp* pointer;\n    typedef _Tp& reference;\n    typedef random_access_iterator_tag iterator_category;\n};\n\ntemplate <class _Tp, class _Up, bool = __has_iterator_category<iterator_traits<_Tp> >::value>\nstruct __has_iterator_category_convertible_to\n    : public integral_constant<bool, is_convertible<typename iterator_traits<_Tp>::iterator_category, _Up>::value>\n{};\n\ntemplate <class _Tp, class _Up>\nstruct __has_iterator_category_convertible_to<_Tp, _Up, false> : public false_type {};\n\ntemplate <class _Tp>\nstruct __is_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {};\n\ntemplate <class _Tp>\nstruct __is_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {};\n\ntemplate <class _Tp>\nstruct __is_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {};\n\ntemplate <class _Tp>\nstruct __is_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {};\n\ntemplate<class _Category, class _Tp, class _Distance = ptrdiff_t,\n         class _Pointer = _Tp*, class _Reference = _Tp&>\nstruct _LIBCPP_TYPE_VIS_ONLY iterator\n{\n    typedef _Tp        value_type;\n    typedef _Distance  difference_type;\n    typedef _Pointer   pointer;\n    typedef _Reference reference;\n    typedef _Category  iterator_category;\n};\n\ntemplate <class _InputIter>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid __advance(_InputIter& __i,\n             typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag)\n{\n    for (; __n > 0; --__n)\n        ++__i;\n}\n\ntemplate <class _BiDirIter>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid __advance(_BiDirIter& __i,\n             typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag)\n{\n    if (__n >= 0)\n        for (; __n > 0; --__n)\n            ++__i;\n    else\n        for (; __n < 0; ++__n)\n            --__i;\n}\n\ntemplate <class _RandIter>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid __advance(_RandIter& __i,\n             typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag)\n{\n   __i += __n;\n}\n\ntemplate <class _InputIter>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid advance(_InputIter& __i,\n             typename iterator_traits<_InputIter>::difference_type __n)\n{\n    __advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());\n}\n\ntemplate <class _InputIter>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename iterator_traits<_InputIter>::difference_type\n__distance(_InputIter __first, _InputIter __last, input_iterator_tag)\n{\n    typename iterator_traits<_InputIter>::difference_type __r(0);\n    for (; __first != __last; ++__first)\n        ++__r;\n    return __r;\n}\n\ntemplate <class _RandIter>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename iterator_traits<_RandIter>::difference_type\n__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag)\n{\n    return __last - __first;\n}\n\ntemplate <class _InputIter>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename iterator_traits<_InputIter>::difference_type\ndistance(_InputIter __first, _InputIter __last)\n{\n    return __distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());\n}\n\ntemplate <class _ForwardIter>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIter\nnext(_ForwardIter __x,\n     typename iterator_traits<_ForwardIter>::difference_type __n = 1,\n     typename enable_if<__is_forward_iterator<_ForwardIter>::value>::type* = 0)\n{\n    _VSTD::advance(__x, __n);\n    return __x;\n}\n\ntemplate <class _BidiretionalIter>\ninline _LIBCPP_INLINE_VISIBILITY\n_BidiretionalIter\nprev(_BidiretionalIter __x,\n     typename iterator_traits<_BidiretionalIter>::difference_type __n = 1,\n     typename enable_if<__is_bidirectional_iterator<_BidiretionalIter>::value>::type* = 0)\n{\n    _VSTD::advance(__x, -__n);\n    return __x;\n}\n\ntemplate <class _Iter>\nclass _LIBCPP_TYPE_VIS_ONLY reverse_iterator\n    : public iterator<typename iterator_traits<_Iter>::iterator_category,\n                      typename iterator_traits<_Iter>::value_type,\n                      typename iterator_traits<_Iter>::difference_type,\n                      typename iterator_traits<_Iter>::pointer,\n                      typename iterator_traits<_Iter>::reference>\n{\nprivate:\n    mutable _Iter __t;  // no longer used as of LWG #2360, not removed due to ABI break\nprotected:\n    _Iter current;\npublic:\n    typedef _Iter                                            iterator_type;\n    typedef typename iterator_traits<_Iter>::difference_type difference_type;\n    typedef typename iterator_traits<_Iter>::reference       reference;\n    typedef typename iterator_traits<_Iter>::pointer         pointer;\n\n    _LIBCPP_INLINE_VISIBILITY reverse_iterator() : current() {}\n    _LIBCPP_INLINE_VISIBILITY explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {}\n    template <class _Up> _LIBCPP_INLINE_VISIBILITY reverse_iterator(const reverse_iterator<_Up>& __u)\n        : __t(__u.base()), current(__u.base()) {}\n    _LIBCPP_INLINE_VISIBILITY _Iter base() const {return current;}\n    _LIBCPP_INLINE_VISIBILITY reference operator*() const {_Iter __tmp = current; return *--__tmp;}\n    _LIBCPP_INLINE_VISIBILITY pointer  operator->() const {return _VSTD::addressof(operator*());}\n    _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator++() {--current; return *this;}\n    _LIBCPP_INLINE_VISIBILITY reverse_iterator  operator++(int)\n        {reverse_iterator __tmp(*this); --current; return __tmp;}\n    _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator--() {++current; return *this;}\n    _LIBCPP_INLINE_VISIBILITY reverse_iterator  operator--(int)\n        {reverse_iterator __tmp(*this); ++current; return __tmp;}\n    _LIBCPP_INLINE_VISIBILITY reverse_iterator  operator+ (difference_type __n) const\n        {return reverse_iterator(current - __n);}\n    _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator+=(difference_type __n)\n        {current -= __n; return *this;}\n    _LIBCPP_INLINE_VISIBILITY reverse_iterator  operator- (difference_type __n) const\n        {return reverse_iterator(current + __n);}\n    _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator-=(difference_type __n)\n        {current += __n; return *this;}\n    _LIBCPP_INLINE_VISIBILITY reference         operator[](difference_type __n) const\n        {return *(*this + __n);}\n};\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)\n{\n    return __x.base() == __y.base();\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)\n{\n    return __x.base() > __y.base();\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)\n{\n    return __x.base() != __y.base();\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)\n{\n    return __x.base() < __y.base();\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)\n{\n    return __x.base() <= __y.base();\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)\n{\n    return __x.base() >= __y.base();\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename reverse_iterator<_Iter1>::difference_type\noperator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)\n{\n    return __y.base() - __x.base();\n}\n\ntemplate <class _Iter>\ninline _LIBCPP_INLINE_VISIBILITY\nreverse_iterator<_Iter>\noperator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)\n{\n    return reverse_iterator<_Iter>(__x.base() - __n);\n}\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Iter>\ninline _LIBCPP_INLINE_VISIBILITY\nreverse_iterator<_Iter> make_reverse_iterator(_Iter __i)\n{\n    return reverse_iterator<_Iter>(__i);\n}\n#endif\n\ntemplate <class _Container>\nclass _LIBCPP_TYPE_VIS_ONLY back_insert_iterator\n    : public iterator<output_iterator_tag,\n                      void,\n                      void,\n                      void,\n                      back_insert_iterator<_Container>&>\n{\nprotected:\n    _Container* container;\npublic:\n    typedef _Container container_type;\n\n    _LIBCPP_INLINE_VISIBILITY explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}\n    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(const typename _Container::value_type& __value_)\n        {container->push_back(__value_); return *this;}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(typename _Container::value_type&& __value_)\n        {container->push_back(_VSTD::move(__value_)); return *this;}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator*()     {return *this;}\n    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator++()    {return *this;}\n    _LIBCPP_INLINE_VISIBILITY back_insert_iterator  operator++(int) {return *this;}\n};\n\ntemplate <class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nback_insert_iterator<_Container>\nback_inserter(_Container& __x)\n{\n    return back_insert_iterator<_Container>(__x);\n}\n\ntemplate <class _Container>\nclass _LIBCPP_TYPE_VIS_ONLY front_insert_iterator\n    : public iterator<output_iterator_tag,\n                      void,\n                      void,\n                      void,\n                      front_insert_iterator<_Container>&>\n{\nprotected:\n    _Container* container;\npublic:\n    typedef _Container container_type;\n\n    _LIBCPP_INLINE_VISIBILITY explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}\n    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(const typename _Container::value_type& __value_)\n        {container->push_front(__value_); return *this;}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(typename _Container::value_type&& __value_)\n        {container->push_front(_VSTD::move(__value_)); return *this;}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator*()     {return *this;}\n    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator++()    {return *this;}\n    _LIBCPP_INLINE_VISIBILITY front_insert_iterator  operator++(int) {return *this;}\n};\n\ntemplate <class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nfront_insert_iterator<_Container>\nfront_inserter(_Container& __x)\n{\n    return front_insert_iterator<_Container>(__x);\n}\n\ntemplate <class _Container>\nclass _LIBCPP_TYPE_VIS_ONLY insert_iterator\n    : public iterator<output_iterator_tag,\n                      void,\n                      void,\n                      void,\n                      insert_iterator<_Container>&>\n{\nprotected:\n    _Container* container;\n    typename _Container::iterator iter;\npublic:\n    typedef _Container container_type;\n\n    _LIBCPP_INLINE_VISIBILITY insert_iterator(_Container& __x, typename _Container::iterator __i)\n        : container(_VSTD::addressof(__x)), iter(__i) {}\n    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(const typename _Container::value_type& __value_)\n        {iter = container->insert(iter, __value_); ++iter; return *this;}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(typename _Container::value_type&& __value_)\n        {iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator*()        {return *this;}\n    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator++()       {return *this;}\n    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator++(int)    {return *this;}\n};\n\ntemplate <class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\ninsert_iterator<_Container>\ninserter(_Container& __x, typename _Container::iterator __i)\n{\n    return insert_iterator<_Container>(__x, __i);\n}\n\ntemplate <class _Tp, class _CharT = char,\n          class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>\nclass _LIBCPP_TYPE_VIS_ONLY istream_iterator\n    : public iterator<input_iterator_tag, _Tp, _Distance, const _Tp*, const _Tp&>\n{\npublic:\n    typedef _CharT char_type;\n    typedef _Traits traits_type;\n    typedef basic_istream<_CharT,_Traits> istream_type;\nprivate:\n    istream_type* __in_stream_;\n    _Tp __value_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(0), __value_() {}\n    _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(&__s)\n        {\n            if (!(*__in_stream_ >> __value_))\n                __in_stream_ = 0;\n        }\n\n    _LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;}\n    _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return &(operator*());}\n    _LIBCPP_INLINE_VISIBILITY istream_iterator& operator++()\n        {\n            if (!(*__in_stream_ >> __value_))\n                __in_stream_ = 0;\n            return *this;\n        }\n    _LIBCPP_INLINE_VISIBILITY istream_iterator  operator++(int)\n        {istream_iterator __t(*this); ++(*this); return __t;}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const istream_iterator& __x, const istream_iterator& __y)\n        {return __x.__in_stream_ == __y.__in_stream_;}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const istream_iterator& __x, const istream_iterator& __y)\n        {return !(__x == __y);}\n};\n\ntemplate <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT> >\nclass _LIBCPP_TYPE_VIS_ONLY ostream_iterator\n    : public iterator<output_iterator_tag, void, void, void, void>\n{\npublic:\n    typedef _CharT char_type;\n    typedef _Traits traits_type;\n    typedef basic_ostream<_CharT,_Traits> ostream_type;\nprivate:\n    ostream_type* __out_stream_;\n    const char_type* __delim_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s)\n        : __out_stream_(&__s), __delim_(0) {}\n    _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter)\n        : __out_stream_(&__s), __delim_(__delimiter) {}\n    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_)\n        {\n            *__out_stream_ << __value_;\n            if (__delim_)\n                *__out_stream_ << __delim_;\n            return *this;\n        }\n\n    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator*()     {return *this;}\n    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++()    {return *this;}\n    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++(int) {return *this;}\n};\n\ntemplate<class _CharT, class _Traits>\nclass _LIBCPP_TYPE_VIS_ONLY istreambuf_iterator\n    : public iterator<input_iterator_tag, _CharT,\n                      typename _Traits::off_type, _CharT*,\n                      _CharT>\n{\npublic:\n    typedef _CharT                          char_type;\n    typedef _Traits                         traits_type;\n    typedef typename _Traits::int_type      int_type;\n    typedef basic_streambuf<_CharT,_Traits> streambuf_type;\n    typedef basic_istream<_CharT,_Traits>   istream_type;\nprivate:\n    mutable streambuf_type* __sbuf_;\n\n    class __proxy\n    {\n        char_type __keep_;\n        streambuf_type* __sbuf_;\n        _LIBCPP_INLINE_VISIBILITY __proxy(char_type __c, streambuf_type* __s)\n            : __keep_(__c), __sbuf_(__s) {}\n        friend class istreambuf_iterator;\n    public:\n        _LIBCPP_INLINE_VISIBILITY char_type operator*() const {return __keep_;}\n    };\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool __test_for_eof() const\n    {\n        if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof()))\n            __sbuf_ = 0;\n        return __sbuf_ == 0;\n    }\npublic:\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(0) {}\n    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT\n        : __sbuf_(__s.rdbuf()) {}\n    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT\n        : __sbuf_(__s) {}\n    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT\n        : __sbuf_(__p.__sbuf_) {}\n\n    _LIBCPP_INLINE_VISIBILITY char_type  operator*() const\n        {return static_cast<char_type>(__sbuf_->sgetc());}\n    _LIBCPP_INLINE_VISIBILITY char_type* operator->() const {return nullptr;}\n    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++()\n        {\n            __sbuf_->sbumpc();\n            return *this;\n        }\n    _LIBCPP_INLINE_VISIBILITY __proxy              operator++(int)\n        {\n            return __proxy(__sbuf_->sbumpc(), __sbuf_);\n        }\n\n    _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const\n        {return __test_for_eof() == __b.__test_for_eof();}\n};\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool operator==(const istreambuf_iterator<_CharT,_Traits>& __a,\n                const istreambuf_iterator<_CharT,_Traits>& __b)\n                {return __a.equal(__b);}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a,\n                const istreambuf_iterator<_CharT,_Traits>& __b)\n                {return !__a.equal(__b);}\n\ntemplate <class _CharT, class _Traits>\nclass _LIBCPP_TYPE_VIS_ONLY ostreambuf_iterator\n    : public iterator<output_iterator_tag, void, void, void, void>\n{\npublic:\n    typedef _CharT                          char_type;\n    typedef _Traits                         traits_type;\n    typedef basic_streambuf<_CharT,_Traits> streambuf_type;\n    typedef basic_ostream<_CharT,_Traits>   ostream_type;\nprivate:\n    streambuf_type* __sbuf_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT\n        : __sbuf_(__s.rdbuf()) {}\n    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT\n        : __sbuf_(__s) {}\n    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator=(_CharT __c)\n        {\n            if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof()))\n                __sbuf_ = 0;\n            return *this;\n        }\n    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator*()     {return *this;}\n    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++()    {return *this;}\n    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++(int) {return *this;}\n    _LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == 0;}\n\n#if !defined(__APPLE__) || \\\n    (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \\\n    (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)\n\n    template <class _Ch, class _Tr>\n    friend\n    _LIBCPP_HIDDEN\n    ostreambuf_iterator<_Ch, _Tr>\n    __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s,\n                     const _Ch* __ob, const _Ch* __op, const _Ch* __oe,\n                     ios_base& __iob, _Ch __fl);\n#endif\n};\n\ntemplate <class _Iter>\nclass _LIBCPP_TYPE_VIS_ONLY move_iterator\n{\nprivate:\n    _Iter __i;\npublic:\n    typedef _Iter                                            iterator_type;\n    typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;\n    typedef typename iterator_traits<iterator_type>::value_type value_type;\n    typedef typename iterator_traits<iterator_type>::difference_type difference_type;\n    typedef typename iterator_traits<iterator_type>::pointer pointer;\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    typedef value_type&& reference;\n#else\n    typedef typename iterator_traits<iterator_type>::reference reference;\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY move_iterator() : __i() {}\n    _LIBCPP_INLINE_VISIBILITY explicit move_iterator(_Iter __x) : __i(__x) {}\n    template <class _Up> _LIBCPP_INLINE_VISIBILITY move_iterator(const move_iterator<_Up>& __u)\n        : __i(__u.base()) {}\n    _LIBCPP_INLINE_VISIBILITY _Iter base() const {return __i;}\n    _LIBCPP_INLINE_VISIBILITY reference operator*() const {\n      return static_cast<reference>(*__i);\n    }\n    _LIBCPP_INLINE_VISIBILITY pointer  operator->() const {\n      typename iterator_traits<iterator_type>::reference __ref = *__i;\n      return &__ref;\n    }\n    _LIBCPP_INLINE_VISIBILITY move_iterator& operator++() {++__i; return *this;}\n    _LIBCPP_INLINE_VISIBILITY move_iterator  operator++(int)\n        {move_iterator __tmp(*this); ++__i; return __tmp;}\n    _LIBCPP_INLINE_VISIBILITY move_iterator& operator--() {--__i; return *this;}\n    _LIBCPP_INLINE_VISIBILITY move_iterator  operator--(int)\n        {move_iterator __tmp(*this); --__i; return __tmp;}\n    _LIBCPP_INLINE_VISIBILITY move_iterator  operator+ (difference_type __n) const\n        {return move_iterator(__i + __n);}\n    _LIBCPP_INLINE_VISIBILITY move_iterator& operator+=(difference_type __n)\n        {__i += __n; return *this;}\n    _LIBCPP_INLINE_VISIBILITY move_iterator  operator- (difference_type __n) const\n        {return move_iterator(__i - __n);}\n    _LIBCPP_INLINE_VISIBILITY move_iterator& operator-=(difference_type __n)\n        {__i -= __n; return *this;}\n    _LIBCPP_INLINE_VISIBILITY reference         operator[](difference_type __n) const\n    {\n      return static_cast<reference>(__i[__n]);\n    }\n};\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)\n{\n    return __x.base() == __y.base();\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)\n{\n    return __x.base() < __y.base();\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)\n{\n    return __x.base() != __y.base();\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)\n{\n    return __x.base() > __y.base();\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)\n{\n    return __x.base() >= __y.base();\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)\n{\n    return __x.base() <= __y.base();\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename move_iterator<_Iter1>::difference_type\noperator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)\n{\n    return __x.base() - __y.base();\n}\n\ntemplate <class _Iter>\ninline _LIBCPP_INLINE_VISIBILITY\nmove_iterator<_Iter>\noperator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x)\n{\n    return move_iterator<_Iter>(__x.base() + __n);\n}\n\ntemplate <class _Iter>\ninline _LIBCPP_INLINE_VISIBILITY\nmove_iterator<_Iter>\nmake_move_iterator(_Iter __i)\n{\n    return move_iterator<_Iter>(__i);\n}\n\n// __wrap_iter\n\ntemplate <class _Iter> class __wrap_iter;\n\ntemplate <class _Iter1, class _Iter2>\n_LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;\n\ntemplate <class _Iter1, class _Iter2>\n_LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;\n\ntemplate <class _Iter1, class _Iter2>\n_LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;\n\ntemplate <class _Iter1, class _Iter2>\n_LIBCPP_INLINE_VISIBILITY\nbool\noperator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;\n\ntemplate <class _Iter1, class _Iter2>\n_LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;\n\ntemplate <class _Iter1, class _Iter2>\n_LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;\n\ntemplate <class _Iter1, class _Iter2>\n_LIBCPP_INLINE_VISIBILITY\ntypename __wrap_iter<_Iter1>::difference_type\noperator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;\n\ntemplate <class _Iter>\n_LIBCPP_INLINE_VISIBILITY\n__wrap_iter<_Iter>\noperator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT;\n\ntemplate <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY copy(_Ip, _Ip, _Op);\ntemplate <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY copy_backward(_B1, _B1, _B2);\ntemplate <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY move(_Ip, _Ip, _Op);\ntemplate <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY move_backward(_B1, _B1, _B2);\n\ntemplate <class _Tp>\n_LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_trivially_copy_assignable<_Tp>::value,\n    _Tp*\n>::type\n__unwrap_iter(__wrap_iter<_Tp*>);\n\ntemplate <class _Tp, class _Alloc> class _LIBCPP_TYPE_VIS_ONLY vector;\n\ntemplate <class _Iter>\nclass __wrap_iter\n{\npublic:\n    typedef _Iter                                                      iterator_type;\n    typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;\n    typedef typename iterator_traits<iterator_type>::value_type        value_type;\n    typedef typename iterator_traits<iterator_type>::difference_type   difference_type;\n    typedef typename iterator_traits<iterator_type>::pointer           pointer;\n    typedef typename iterator_traits<iterator_type>::reference         reference;\nprivate:\n    iterator_type __i;\npublic:\n    _LIBCPP_INLINE_VISIBILITY __wrap_iter() _NOEXCEPT\n#if _LIBCPP_STD_VER > 11\n                : __i{}\n#endif\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->__insert_i(this);\n#endif\n    }\n    template <class _Up> _LIBCPP_INLINE_VISIBILITY __wrap_iter(const __wrap_iter<_Up>& __u,\n        typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0) _NOEXCEPT\n        : __i(__u.base())\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->__iterator_copy(this, &__u);\n#endif\n    }\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_INLINE_VISIBILITY\n    __wrap_iter(const __wrap_iter& __x)\n        : __i(__x.base())\n    {\n        __get_db()->__iterator_copy(this, &__x);\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    __wrap_iter& operator=(const __wrap_iter& __x)\n    {\n        if (this != &__x)\n        {\n            __get_db()->__iterator_copy(this, &__x);\n            __i = __x.__i;\n        }\n        return *this;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    ~__wrap_iter()\n    {\n        __get_db()->__erase_i(this);\n    }\n#endif\n    _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                       \"Attempted to dereference a non-dereferenceable iterator\");\n#endif\n        return *__i;\n    }\n    _LIBCPP_INLINE_VISIBILITY pointer  operator->() const _NOEXCEPT\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                       \"Attempted to dereference a non-dereferenceable iterator\");\n#endif\n        return (pointer)&reinterpret_cast<const volatile char&>(*__i);\n    }\n    _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                       \"Attempted to increment non-incrementable iterator\");\n#endif\n        ++__i;\n        return *this;\n    }\n    _LIBCPP_INLINE_VISIBILITY __wrap_iter  operator++(int) _NOEXCEPT\n        {__wrap_iter __tmp(*this); ++(*this); return __tmp;}\n    _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator--() _NOEXCEPT\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),\n                       \"Attempted to decrement non-decrementable iterator\");\n#endif\n        --__i;\n        return *this;\n    }\n    _LIBCPP_INLINE_VISIBILITY __wrap_iter  operator--(int) _NOEXCEPT\n        {__wrap_iter __tmp(*this); --(*this); return __tmp;}\n    _LIBCPP_INLINE_VISIBILITY __wrap_iter  operator+ (difference_type __n) const _NOEXCEPT\n        {__wrap_iter __w(*this); __w += __n; return __w;}\n    _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator+=(difference_type __n) _NOEXCEPT\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n),\n                   \"Attempted to add/subtract iterator outside of valid range\");\n#endif\n        __i += __n;\n        return *this;\n    }\n    _LIBCPP_INLINE_VISIBILITY __wrap_iter  operator- (difference_type __n) const _NOEXCEPT\n        {return *this + (-__n);}\n    _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator-=(difference_type __n) _NOEXCEPT\n        {*this += -__n; return *this;}\n    _LIBCPP_INLINE_VISIBILITY reference        operator[](difference_type __n) const _NOEXCEPT\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n),\n                   \"Attempted to subscript iterator outside of valid range\");\n#endif\n        return __i[__n];\n    }\n\n    _LIBCPP_INLINE_VISIBILITY iterator_type base() const _NOEXCEPT {return __i;}\n\nprivate:\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_INLINE_VISIBILITY __wrap_iter(const void* __p, iterator_type __x) : __i(__x)\n    {\n        __get_db()->__insert_ic(this, __p);\n    }\n#else\n    _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}\n#endif\n\n    template <class _Up> friend class __wrap_iter;\n    template <class _CharT, class _Traits, class _Alloc> friend class basic_string;\n    template <class _Tp, class _Alloc> friend class vector;\n\n    template <class _Iter1, class _Iter2>\n    friend\n    bool\n    operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;\n\n    template <class _Iter1, class _Iter2>\n    friend\n    bool\n    operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;\n\n    template <class _Iter1, class _Iter2>\n    friend\n    bool\n    operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;\n\n    template <class _Iter1, class _Iter2>\n    friend\n    bool\n    operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;\n\n    template <class _Iter1, class _Iter2>\n    friend\n    bool\n    operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;\n\n    template <class _Iter1, class _Iter2>\n    friend\n    bool\n    operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;\n\n    template <class _Iter1, class _Iter2>\n    friend\n    typename __wrap_iter<_Iter1>::difference_type\n    operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;\n\n    template <class _Iter1>\n    friend\n    __wrap_iter<_Iter1>\n    operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT;\n\n    template <class _Ip, class _Op> friend _Op copy(_Ip, _Ip, _Op);\n    template <class _B1, class _B2> friend _B2 copy_backward(_B1, _B1, _B2);\n    template <class _Ip, class _Op> friend _Op move(_Ip, _Ip, _Op);\n    template <class _B1, class _B2> friend _B2 move_backward(_B1, _B1, _B2);\n\n    template <class _Tp>\n    friend\n    typename enable_if\n    <\n        is_trivially_copy_assignable<_Tp>::value,\n        _Tp*\n    >::type\n    __unwrap_iter(__wrap_iter<_Tp*>);\n};\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT\n{\n    return __x.base() == __y.base();\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),\n                   \"Attempted to compare incomparable iterators\");\n#endif\n    return __x.base() < __y.base();\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT\n{\n    return __y < __x;\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT\n{\n    return !(__x < __y);\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT\n{\n    return !(__y < __x);\n}\n\ntemplate <class _Iter1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Iter1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT\n{\n    return __y < __x;\n}\n\ntemplate <class _Iter1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT\n{\n    return !(__x < __y);\n}\n\ntemplate <class _Iter1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT\n{\n    return !(__y < __x);\n}\n\ntemplate <class _Iter1, class _Iter2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __wrap_iter<_Iter1>::difference_type\noperator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),\n                   \"Attempted to subtract incompatible iterators\");\n#endif\n    return __x.base() - __y.base();\n}\n\ntemplate <class _Iter>\ninline _LIBCPP_INLINE_VISIBILITY\n__wrap_iter<_Iter>\noperator+(typename __wrap_iter<_Iter>::difference_type __n,\n          __wrap_iter<_Iter> __x) _NOEXCEPT\n{\n    __x += __n;\n    return __x;\n}\n\ntemplate <class _Tp, size_t _Np>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_Tp*\nbegin(_Tp (&__array)[_Np])\n{\n    return __array;\n}\n\ntemplate <class _Tp, size_t _Np>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_Tp*\nend(_Tp (&__array)[_Np])\n{\n    return __array + _Np;\n}\n\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN)\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nauto\nbegin(_Cp& __c) -> decltype(__c.begin())\n{\n    return __c.begin();\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nauto\nbegin(const _Cp& __c) -> decltype(__c.begin())\n{\n    return __c.begin();\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nauto\nend(_Cp& __c) -> decltype(__c.end())\n{\n    return __c.end();\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nauto\nend(const _Cp& __c) -> decltype(__c.end())\n{\n    return __c.end();\n}\n\n#if _LIBCPP_STD_VER > 11\n\ntemplate <class _Tp, size_t _Np>\ninline _LIBCPP_INLINE_VISIBILITY\nreverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np])\n{\n    return reverse_iterator<_Tp*>(__array + _Np);\n}\n\ntemplate <class _Tp, size_t _Np>\ninline _LIBCPP_INLINE_VISIBILITY\nreverse_iterator<_Tp*> rend(_Tp (&__array)[_Np])\n{\n    return reverse_iterator<_Tp*>(__array);\n}\n\ntemplate <class _Ep>\ninline _LIBCPP_INLINE_VISIBILITY\nreverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il)\n{\n    return reverse_iterator<const _Ep*>(__il.end());\n}\n\ntemplate <class _Ep>\ninline _LIBCPP_INLINE_VISIBILITY\nreverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il)\n{\n    return reverse_iterator<const _Ep*>(__il.begin());\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nauto cbegin(const _Cp& __c) -> decltype(begin(__c))\n{\n    return begin(__c);\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nauto cend(const _Cp& __c) -> decltype(end(__c))\n{\n    return end(__c);\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nauto rbegin(_Cp& __c) -> decltype(__c.rbegin())\n{\n    return __c.rbegin();\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nauto rbegin(const _Cp& __c) -> decltype(__c.rbegin())\n{\n    return __c.rbegin();\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nauto rend(_Cp& __c) -> decltype(__c.rend())\n{\n    return __c.rend();\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nauto rend(const _Cp& __c) -> decltype(__c.rend())\n{\n    return __c.rend();\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nauto crbegin(const _Cp& __c) -> decltype(rbegin(__c))\n{\n    return rbegin(__c);\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\nauto crend(const _Cp& __c) -> decltype(rend(__c))\n{\n    return rend(__c);\n}\n\n#endif\n\n\n#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN)\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename _Cp::iterator\nbegin(_Cp& __c)\n{\n    return __c.begin();\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename _Cp::const_iterator\nbegin(const _Cp& __c)\n{\n    return __c.begin();\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename _Cp::iterator\nend(_Cp& __c)\n{\n    return __c.end();\n}\n\ntemplate <class _Cp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename _Cp::const_iterator\nend(const _Cp& __c)\n{\n    return __c.end();\n}\n\n#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN)\n\n#if _LIBCPP_STD_VER > 14\ntemplate <class _Cont>\nconstexpr auto size(const _Cont& __c) -> decltype(__c.size()) { return __c.size(); }\n\ntemplate <class _Tp, size_t _Sz>\nconstexpr size_t size(const _Tp (&__array)[_Sz]) noexcept { return _Sz; }\n\ntemplate <class _Cont>\nconstexpr auto empty(const _Cont& __c) -> decltype(__c.empty()) { return __c.empty(); }\n\ntemplate <class _Tp, size_t _Sz>\nconstexpr bool empty(const _Tp (&__array)[_Sz]) noexcept { return false; }\n\ntemplate <class _Ep>\nconstexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; }\n\ntemplate <class _Cont> constexpr\nauto data(_Cont& __c) -> decltype(__c.data()) { return __c.data(); }\n\ntemplate <class _Cont> constexpr\nauto data(const _Cont& __c) -> decltype(__c.data()) { return __c.data(); }\n\ntemplate <class _Tp, size_t _Sz>\nconstexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; }\n\ntemplate <class _Ep>\nconstexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); }\n#endif\n\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_ITERATOR\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/limits",
    "content": "// -*- C++ -*-\n//===---------------------------- limits ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_LIMITS\n#define _LIBCPP_LIMITS\n\n/*\n    limits synopsis\n\nnamespace std\n{\n\ntemplate<class T>\nclass numeric_limits\n{\npublic:\n    static constexpr bool is_specialized = false;\n    static constexpr T min() noexcept;\n    static constexpr T max() noexcept;\n    static constexpr T lowest() noexcept;\n\n    static constexpr int  digits = 0;\n    static constexpr int  digits10 = 0;\n    static constexpr int  max_digits10 = 0;\n    static constexpr bool is_signed = false;\n    static constexpr bool is_integer = false;\n    static constexpr bool is_exact = false;\n    static constexpr int  radix = 0;\n    static constexpr T epsilon() noexcept;\n    static constexpr T round_error() noexcept;\n\n    static constexpr int  min_exponent = 0;\n    static constexpr int  min_exponent10 = 0;\n    static constexpr int  max_exponent = 0;\n    static constexpr int  max_exponent10 = 0;\n\n    static constexpr bool has_infinity = false;\n    static constexpr bool has_quiet_NaN = false;\n    static constexpr bool has_signaling_NaN = false;\n    static constexpr float_denorm_style has_denorm = denorm_absent;\n    static constexpr bool has_denorm_loss = false;\n    static constexpr T infinity() noexcept;\n    static constexpr T quiet_NaN() noexcept;\n    static constexpr T signaling_NaN() noexcept;\n    static constexpr T denorm_min() noexcept;\n\n    static constexpr bool is_iec559 = false;\n    static constexpr bool is_bounded = false;\n    static constexpr bool is_modulo = false;\n\n    static constexpr bool traps = false;\n    static constexpr bool tinyness_before = false;\n    static constexpr float_round_style round_style = round_toward_zero;\n};\n\nenum float_round_style\n{\n    round_indeterminate       = -1,\n    round_toward_zero         =  0,\n    round_to_nearest          =  1,\n    round_toward_infinity     =  2,\n    round_toward_neg_infinity =  3\n};\n\nenum float_denorm_style\n{\n    denorm_indeterminate = -1,\n    denorm_absent = 0,\n    denorm_present = 1\n};\n\ntemplate<> class numeric_limits<cv bool>;\n\ntemplate<> class numeric_limits<cv char>;\ntemplate<> class numeric_limits<cv signed char>;\ntemplate<> class numeric_limits<cv unsigned char>;\ntemplate<> class numeric_limits<cv wchar_t>;\ntemplate<> class numeric_limits<cv char16_t>;\ntemplate<> class numeric_limits<cv char32_t>;\n\ntemplate<> class numeric_limits<cv short>;\ntemplate<> class numeric_limits<cv int>;\ntemplate<> class numeric_limits<cv long>;\ntemplate<> class numeric_limits<cv long long>;\ntemplate<> class numeric_limits<cv unsigned short>;\ntemplate<> class numeric_limits<cv unsigned int>;\ntemplate<> class numeric_limits<cv unsigned long>;\ntemplate<> class numeric_limits<cv unsigned long long>;\n\ntemplate<> class numeric_limits<cv float>;\ntemplate<> class numeric_limits<cv double>;\ntemplate<> class numeric_limits<cv long double>;\n\n}  // std\n\n*/\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#include <__config>\n#include <type_traits>\n\n#include <__undef_min_max>\n\n#if defined(_LIBCPP_MSVCRT)\n#include \"support/win32/limits_win32.h\"\n#endif // _LIBCPP_MSVCRT\n\n#if defined(__IBMCPP__)\n#include \"support/ibm/limits.h\"\n#endif // __IBMCPP__\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nenum float_round_style\n{\n    round_indeterminate       = -1,\n    round_toward_zero         =  0,\n    round_to_nearest          =  1,\n    round_toward_infinity     =  2,\n    round_toward_neg_infinity =  3\n};\n\nenum float_denorm_style\n{\n    denorm_indeterminate = -1,\n    denorm_absent = 0,\n    denorm_present = 1\n};\n\ntemplate <class _Tp, bool = is_arithmetic<_Tp>::value>\nclass __libcpp_numeric_limits\n{\nprotected:\n    typedef _Tp type;\n\n    static _LIBCPP_CONSTEXPR const  bool is_specialized = false;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return type();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return type();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return type();}\n\n    static _LIBCPP_CONSTEXPR const int  digits = 0;\n    static _LIBCPP_CONSTEXPR const int  digits10 = 0;\n    static _LIBCPP_CONSTEXPR const int  max_digits10 = 0;\n    static _LIBCPP_CONSTEXPR const bool is_signed = false;\n    static _LIBCPP_CONSTEXPR const bool is_integer = false;\n    static _LIBCPP_CONSTEXPR const bool is_exact = false;\n    static _LIBCPP_CONSTEXPR const int  radix = 0;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return type();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return type();}\n\n    static _LIBCPP_CONSTEXPR const int  min_exponent = 0;\n    static _LIBCPP_CONSTEXPR const int  min_exponent10 = 0;\n    static _LIBCPP_CONSTEXPR const int  max_exponent = 0;\n    static _LIBCPP_CONSTEXPR const int  max_exponent10 = 0;\n\n    static _LIBCPP_CONSTEXPR const bool has_infinity = false;\n    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = false;\n    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = false;\n    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_absent;\n    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return type();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return type();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return type();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return type();}\n\n    static _LIBCPP_CONSTEXPR const bool is_iec559 = false;\n    static _LIBCPP_CONSTEXPR const bool is_bounded = false;\n    static _LIBCPP_CONSTEXPR const bool is_modulo = false;\n\n    static _LIBCPP_CONSTEXPR const bool traps = false;\n    static _LIBCPP_CONSTEXPR const bool tinyness_before = false;\n    static _LIBCPP_CONSTEXPR const float_round_style round_style = round_toward_zero;\n};\n\ntemplate <class _Tp, int digits, bool is_signed>\nstruct __libcpp_compute_min\n{\n    static _LIBCPP_CONSTEXPR const _Tp value = _Tp(_Tp(1) << digits);\n};\n\ntemplate <class _Tp, int digits>\nstruct __libcpp_compute_min<_Tp, digits, false>\n{\n    static _LIBCPP_CONSTEXPR const _Tp value = _Tp(0);\n};\n\ntemplate <class _Tp>\nclass __libcpp_numeric_limits<_Tp, true>\n{\nprotected:\n    typedef _Tp type;\n\n    static _LIBCPP_CONSTEXPR const bool is_specialized = true;\n\n    static _LIBCPP_CONSTEXPR const bool is_signed = type(-1) < type(0);\n    static _LIBCPP_CONSTEXPR const int  digits = static_cast<int>(sizeof(type) * __CHAR_BIT__ - is_signed);\n    static _LIBCPP_CONSTEXPR const int  digits10 = digits * 3 / 10;\n    static _LIBCPP_CONSTEXPR const int  max_digits10 = 0;\n    static _LIBCPP_CONSTEXPR const type __min = __libcpp_compute_min<type, digits, is_signed>::value;\n    static _LIBCPP_CONSTEXPR const type __max = is_signed ? type(type(~0) ^ __min) : type(~0);\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __min;}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __max;}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return min();}\n\n    static _LIBCPP_CONSTEXPR const bool is_integer = true;\n    static _LIBCPP_CONSTEXPR const bool is_exact = true;\n    static _LIBCPP_CONSTEXPR const int  radix = 2;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return type(0);}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return type(0);}\n\n    static _LIBCPP_CONSTEXPR const int  min_exponent = 0;\n    static _LIBCPP_CONSTEXPR const int  min_exponent10 = 0;\n    static _LIBCPP_CONSTEXPR const int  max_exponent = 0;\n    static _LIBCPP_CONSTEXPR const int  max_exponent10 = 0;\n\n    static _LIBCPP_CONSTEXPR const bool has_infinity = false;\n    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = false;\n    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = false;\n    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_absent;\n    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return type(0);}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return type(0);}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return type(0);}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return type(0);}\n\n    static _LIBCPP_CONSTEXPR const bool is_iec559 = false;\n    static _LIBCPP_CONSTEXPR const bool is_bounded = true;\n    static _LIBCPP_CONSTEXPR const bool is_modulo = !_VSTD::is_signed<_Tp>::value;\n\n#if defined(__i386__) || defined(__x86_64__) || defined(__pnacl__)\n    static _LIBCPP_CONSTEXPR const bool traps = true;\n#else\n    static _LIBCPP_CONSTEXPR const bool traps = false;\n#endif\n    static _LIBCPP_CONSTEXPR const bool tinyness_before = false;\n    static _LIBCPP_CONSTEXPR const float_round_style round_style = round_toward_zero;\n};\n\ntemplate <>\nclass __libcpp_numeric_limits<bool, true>\n{\nprotected:\n    typedef bool type;\n\n    static _LIBCPP_CONSTEXPR const bool is_specialized = true;\n\n    static _LIBCPP_CONSTEXPR const bool is_signed = false;\n    static _LIBCPP_CONSTEXPR const int  digits = 1;\n    static _LIBCPP_CONSTEXPR const int  digits10 = 0;\n    static _LIBCPP_CONSTEXPR const int  max_digits10 = 0;\n    static _LIBCPP_CONSTEXPR const type __min = false;\n    static _LIBCPP_CONSTEXPR const type __max = true;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __min;}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __max;}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return min();}\n\n    static _LIBCPP_CONSTEXPR const bool is_integer = true;\n    static _LIBCPP_CONSTEXPR const bool is_exact = true;\n    static _LIBCPP_CONSTEXPR const int  radix = 2;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return type(0);}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return type(0);}\n\n    static _LIBCPP_CONSTEXPR const int  min_exponent = 0;\n    static _LIBCPP_CONSTEXPR const int  min_exponent10 = 0;\n    static _LIBCPP_CONSTEXPR const int  max_exponent = 0;\n    static _LIBCPP_CONSTEXPR const int  max_exponent10 = 0;\n\n    static _LIBCPP_CONSTEXPR const bool has_infinity = false;\n    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = false;\n    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = false;\n    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_absent;\n    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return type(0);}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return type(0);}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return type(0);}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return type(0);}\n\n    static _LIBCPP_CONSTEXPR const bool is_iec559 = false;\n    static _LIBCPP_CONSTEXPR const bool is_bounded = true;\n    static _LIBCPP_CONSTEXPR const bool is_modulo = false;\n\n    static _LIBCPP_CONSTEXPR const bool traps = false;\n    static _LIBCPP_CONSTEXPR const bool tinyness_before = false;\n    static _LIBCPP_CONSTEXPR const float_round_style round_style = round_toward_zero;\n};\n\ntemplate <>\nclass __libcpp_numeric_limits<float, true>\n{\nprotected:\n    typedef float type;\n\n    static _LIBCPP_CONSTEXPR const bool is_specialized = true;\n\n    static _LIBCPP_CONSTEXPR const bool is_signed = true;\n    static _LIBCPP_CONSTEXPR const int  digits = __FLT_MANT_DIG__;\n    static _LIBCPP_CONSTEXPR const int  digits10 = __FLT_DIG__;\n    static _LIBCPP_CONSTEXPR const int  max_digits10 = 2+(digits * 30103)/100000;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __FLT_MIN__;}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __FLT_MAX__;}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return -max();}\n\n    static _LIBCPP_CONSTEXPR const bool is_integer = false;\n    static _LIBCPP_CONSTEXPR const bool is_exact = false;\n    static _LIBCPP_CONSTEXPR const int  radix = __FLT_RADIX__;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __FLT_EPSILON__;}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return 0.5F;}\n\n    static _LIBCPP_CONSTEXPR const int  min_exponent = __FLT_MIN_EXP__;\n    static _LIBCPP_CONSTEXPR const int  min_exponent10 = __FLT_MIN_10_EXP__;\n    static _LIBCPP_CONSTEXPR const int  max_exponent = __FLT_MAX_EXP__;\n    static _LIBCPP_CONSTEXPR const int  max_exponent10 = __FLT_MAX_10_EXP__;\n\n    static _LIBCPP_CONSTEXPR const bool has_infinity = true;\n    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = true;\n    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = true;\n    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_present;\n    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __builtin_huge_valf();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __builtin_nanf(\"\");}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __builtin_nansf(\"\");}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __FLT_DENORM_MIN__;}\n\n    static _LIBCPP_CONSTEXPR const bool is_iec559 = true;\n    static _LIBCPP_CONSTEXPR const bool is_bounded = true;\n    static _LIBCPP_CONSTEXPR const bool is_modulo = false;\n\n    static _LIBCPP_CONSTEXPR const bool traps = false;\n    static _LIBCPP_CONSTEXPR const bool tinyness_before = false;\n    static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest;\n};\n\ntemplate <>\nclass __libcpp_numeric_limits<double, true>\n{\nprotected:\n    typedef double type;\n\n    static _LIBCPP_CONSTEXPR const bool is_specialized = true;\n\n    static _LIBCPP_CONSTEXPR const bool is_signed = true;\n    static _LIBCPP_CONSTEXPR const int  digits = __DBL_MANT_DIG__;\n    static _LIBCPP_CONSTEXPR const int  digits10 = __DBL_DIG__;\n    static _LIBCPP_CONSTEXPR const int  max_digits10 = 2+(digits * 30103)/100000;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __DBL_MIN__;}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __DBL_MAX__;}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return -max();}\n\n    static _LIBCPP_CONSTEXPR const bool is_integer = false;\n    static _LIBCPP_CONSTEXPR const bool is_exact = false;\n    static _LIBCPP_CONSTEXPR const int  radix = __FLT_RADIX__;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __DBL_EPSILON__;}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return 0.5;}\n\n    static _LIBCPP_CONSTEXPR const int  min_exponent = __DBL_MIN_EXP__;\n    static _LIBCPP_CONSTEXPR const int  min_exponent10 = __DBL_MIN_10_EXP__;\n    static _LIBCPP_CONSTEXPR const int  max_exponent = __DBL_MAX_EXP__;\n    static _LIBCPP_CONSTEXPR const int  max_exponent10 = __DBL_MAX_10_EXP__;\n\n    static _LIBCPP_CONSTEXPR const bool has_infinity = true;\n    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = true;\n    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = true;\n    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_present;\n    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __builtin_huge_val();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __builtin_nan(\"\");}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __builtin_nans(\"\");}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __DBL_DENORM_MIN__;}\n\n    static _LIBCPP_CONSTEXPR const bool is_iec559 = true;\n    static _LIBCPP_CONSTEXPR const bool is_bounded = true;\n    static _LIBCPP_CONSTEXPR const bool is_modulo = false;\n\n    static _LIBCPP_CONSTEXPR const bool traps = false;\n    static _LIBCPP_CONSTEXPR const bool tinyness_before = false;\n    static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest;\n};\n\ntemplate <>\nclass __libcpp_numeric_limits<long double, true>\n{\nprotected:\n    typedef long double type;\n\n    static _LIBCPP_CONSTEXPR const bool is_specialized = true;\n\n    static _LIBCPP_CONSTEXPR const bool is_signed = true;\n    static _LIBCPP_CONSTEXPR const int  digits = __LDBL_MANT_DIG__;\n    static _LIBCPP_CONSTEXPR const int  digits10 = __LDBL_DIG__;\n    static _LIBCPP_CONSTEXPR const int  max_digits10 = 2+(digits * 30103)/100000;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __LDBL_MIN__;}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __LDBL_MAX__;}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return -max();}\n\n    static _LIBCPP_CONSTEXPR const bool is_integer = false;\n    static _LIBCPP_CONSTEXPR const bool is_exact = false;\n    static _LIBCPP_CONSTEXPR const int  radix = __FLT_RADIX__;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __LDBL_EPSILON__;}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return 0.5;}\n\n    static _LIBCPP_CONSTEXPR const int  min_exponent = __LDBL_MIN_EXP__;\n    static _LIBCPP_CONSTEXPR const int  min_exponent10 = __LDBL_MIN_10_EXP__;\n    static _LIBCPP_CONSTEXPR const int  max_exponent = __LDBL_MAX_EXP__;\n    static _LIBCPP_CONSTEXPR const int  max_exponent10 = __LDBL_MAX_10_EXP__;\n\n    static _LIBCPP_CONSTEXPR const bool has_infinity = true;\n    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = true;\n    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = true;\n    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_present;\n    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __builtin_huge_vall();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __builtin_nanl(\"\");}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __builtin_nansl(\"\");}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __LDBL_DENORM_MIN__;}\n\n#if (defined(__ppc__) || defined(__ppc64__))\n    static _LIBCPP_CONSTEXPR const bool is_iec559 = false;\n#else\n    static _LIBCPP_CONSTEXPR const bool is_iec559 = true;\n#endif\n    static _LIBCPP_CONSTEXPR const bool is_bounded = true;\n    static _LIBCPP_CONSTEXPR const bool is_modulo = false;\n\n    static _LIBCPP_CONSTEXPR const bool traps = false;\n    static _LIBCPP_CONSTEXPR const bool tinyness_before = false;\n    static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest;\n};\n\ntemplate <class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY numeric_limits\n    : private __libcpp_numeric_limits<typename remove_cv<_Tp>::type>\n{\n    typedef __libcpp_numeric_limits<typename remove_cv<_Tp>::type> __base;\n    typedef typename __base::type type;\npublic:\n    static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __base::min();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __base::max();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return __base::lowest();}\n\n    static _LIBCPP_CONSTEXPR const int  digits = __base::digits;\n    static _LIBCPP_CONSTEXPR const int  digits10 = __base::digits10;\n    static _LIBCPP_CONSTEXPR const int  max_digits10 = __base::max_digits10;\n    static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed;\n    static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer;\n    static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact;\n    static _LIBCPP_CONSTEXPR const int  radix = __base::radix;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __base::epsilon();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return __base::round_error();}\n\n    static _LIBCPP_CONSTEXPR const int  min_exponent = __base::min_exponent;\n    static _LIBCPP_CONSTEXPR const int  min_exponent10 = __base::min_exponent10;\n    static _LIBCPP_CONSTEXPR const int  max_exponent = __base::max_exponent;\n    static _LIBCPP_CONSTEXPR const int  max_exponent10 = __base::max_exponent10;\n\n    static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity;\n    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN;\n    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN;\n    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm;\n    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __base::infinity();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __base::quiet_NaN();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __base::signaling_NaN();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __base::denorm_min();}\n\n    static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559;\n    static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded;\n    static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo;\n\n    static _LIBCPP_CONSTEXPR const bool traps = __base::traps;\n    static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before;\n    static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style;\n};\n\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_specialized;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::digits;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::digits10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::max_digits10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_signed;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_integer;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_exact;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::radix;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::min_exponent;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::min_exponent10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::max_exponent;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::max_exponent10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_infinity;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_quiet_NaN;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_signaling_NaN;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits<_Tp>::has_denorm;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_denorm_loss;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_iec559;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_bounded;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_modulo;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::traps;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::tinyness_before;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const float_round_style numeric_limits<_Tp>::round_style;\n\ntemplate <class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY numeric_limits<const _Tp>\n    : private numeric_limits<_Tp>\n{\n    typedef numeric_limits<_Tp> __base;\n    typedef _Tp type;\npublic:\n    static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __base::min();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __base::max();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return __base::lowest();}\n\n    static _LIBCPP_CONSTEXPR const int  digits = __base::digits;\n    static _LIBCPP_CONSTEXPR const int  digits10 = __base::digits10;\n    static _LIBCPP_CONSTEXPR const int  max_digits10 = __base::max_digits10;\n    static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed;\n    static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer;\n    static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact;\n    static _LIBCPP_CONSTEXPR const int  radix = __base::radix;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __base::epsilon();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return __base::round_error();}\n\n    static _LIBCPP_CONSTEXPR const int  min_exponent = __base::min_exponent;\n    static _LIBCPP_CONSTEXPR const int  min_exponent10 = __base::min_exponent10;\n    static _LIBCPP_CONSTEXPR const int  max_exponent = __base::max_exponent;\n    static _LIBCPP_CONSTEXPR const int  max_exponent10 = __base::max_exponent10;\n\n    static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity;\n    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN;\n    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN;\n    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm;\n    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __base::infinity();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __base::quiet_NaN();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __base::signaling_NaN();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __base::denorm_min();}\n\n    static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559;\n    static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded;\n    static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo;\n\n    static _LIBCPP_CONSTEXPR const bool traps = __base::traps;\n    static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before;\n    static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style;\n};\n\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_specialized;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::digits;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::digits10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::max_digits10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_signed;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_integer;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_exact;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::radix;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::min_exponent;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::min_exponent10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::max_exponent;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::max_exponent10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::has_infinity;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::has_quiet_NaN;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::has_signaling_NaN;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits<const _Tp>::has_denorm;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::has_denorm_loss;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_iec559;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_bounded;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_modulo;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::traps;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::tinyness_before;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const float_round_style numeric_limits<const _Tp>::round_style;\n\ntemplate <class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY numeric_limits<volatile _Tp>\n    : private numeric_limits<_Tp>\n{\n    typedef numeric_limits<_Tp> __base;\n    typedef _Tp type;\npublic:\n    static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __base::min();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __base::max();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return __base::lowest();}\n\n    static _LIBCPP_CONSTEXPR const int  digits = __base::digits;\n    static _LIBCPP_CONSTEXPR const int  digits10 = __base::digits10;\n    static _LIBCPP_CONSTEXPR const int  max_digits10 = __base::max_digits10;\n    static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed;\n    static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer;\n    static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact;\n    static _LIBCPP_CONSTEXPR const int  radix = __base::radix;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __base::epsilon();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return __base::round_error();}\n\n    static _LIBCPP_CONSTEXPR const int  min_exponent = __base::min_exponent;\n    static _LIBCPP_CONSTEXPR const int  min_exponent10 = __base::min_exponent10;\n    static _LIBCPP_CONSTEXPR const int  max_exponent = __base::max_exponent;\n    static _LIBCPP_CONSTEXPR const int  max_exponent10 = __base::max_exponent10;\n\n    static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity;\n    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN;\n    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN;\n    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm;\n    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __base::infinity();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __base::quiet_NaN();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __base::signaling_NaN();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __base::denorm_min();}\n\n    static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559;\n    static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded;\n    static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo;\n\n    static _LIBCPP_CONSTEXPR const bool traps = __base::traps;\n    static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before;\n    static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style;\n};\n\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_specialized;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::digits;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::digits10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::max_digits10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_signed;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_integer;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_exact;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::radix;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::min_exponent;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::min_exponent10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::max_exponent;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::max_exponent10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::has_infinity;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::has_quiet_NaN;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::has_signaling_NaN;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits<volatile _Tp>::has_denorm;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::has_denorm_loss;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_iec559;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_bounded;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_modulo;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::traps;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::tinyness_before;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const float_round_style numeric_limits<volatile _Tp>::round_style;\n\ntemplate <class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY numeric_limits<const volatile _Tp>\n    : private numeric_limits<_Tp>\n{\n    typedef numeric_limits<_Tp> __base;\n    typedef _Tp type;\npublic:\n    static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __base::min();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __base::max();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return __base::lowest();}\n\n    static _LIBCPP_CONSTEXPR const int  digits = __base::digits;\n    static _LIBCPP_CONSTEXPR const int  digits10 = __base::digits10;\n    static _LIBCPP_CONSTEXPR const int  max_digits10 = __base::max_digits10;\n    static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed;\n    static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer;\n    static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact;\n    static _LIBCPP_CONSTEXPR const int  radix = __base::radix;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __base::epsilon();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return __base::round_error();}\n\n    static _LIBCPP_CONSTEXPR const int  min_exponent = __base::min_exponent;\n    static _LIBCPP_CONSTEXPR const int  min_exponent10 = __base::min_exponent10;\n    static _LIBCPP_CONSTEXPR const int  max_exponent = __base::max_exponent;\n    static _LIBCPP_CONSTEXPR const int  max_exponent10 = __base::max_exponent10;\n\n    static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity;\n    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN;\n    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN;\n    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm;\n    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss;\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __base::infinity();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __base::quiet_NaN();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __base::signaling_NaN();}\n    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __base::denorm_min();}\n\n    static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559;\n    static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded;\n    static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo;\n\n    static _LIBCPP_CONSTEXPR const bool traps = __base::traps;\n    static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before;\n    static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style;\n};\n\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_specialized;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::digits;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::digits10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::max_digits10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_signed;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_integer;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_exact;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::radix;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::min_exponent;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::min_exponent10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::max_exponent;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::max_exponent10;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::has_infinity;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::has_quiet_NaN;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::has_signaling_NaN;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits<const volatile _Tp>::has_denorm;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::has_denorm_loss;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_iec559;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_bounded;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_modulo;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::traps;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::tinyness_before;\ntemplate <class _Tp>\n    _LIBCPP_CONSTEXPR const float_round_style numeric_limits<const volatile _Tp>::round_style;\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_LIMITS\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/list",
    "content": "// -*- C++ -*-\n//===---------------------------- list ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_LIST\n#define _LIBCPP_LIST\n\n/*\n    list synopsis\n\nnamespace std\n{\n\ntemplate <class T, class Alloc = allocator<T> >\nclass list\n{\npublic:\n\n    // types:\n    typedef T value_type;\n    typedef Alloc allocator_type;\n    typedef typename allocator_type::reference reference;\n    typedef typename allocator_type::const_reference const_reference;\n    typedef typename allocator_type::pointer pointer;\n    typedef typename allocator_type::const_pointer const_pointer;\n    typedef implementation-defined iterator;\n    typedef implementation-defined const_iterator;\n    typedef implementation-defined size_type;\n    typedef implementation-defined difference_type;\n    typedef reverse_iterator<iterator> reverse_iterator;\n    typedef reverse_iterator<const_iterator> const_reverse_iterator;\n\n    list()\n        noexcept(is_nothrow_default_constructible<allocator_type>::value);\n    explicit list(const allocator_type& a);\n    explicit list(size_type n);\n    explicit list(size_type n, const allocator_type& a); // C++14\n    list(size_type n, const value_type& value);\n    list(size_type n, const value_type& value, const allocator_type& a);\n    template <class Iter>\n        list(Iter first, Iter last);\n    template <class Iter>\n        list(Iter first, Iter last, const allocator_type& a);\n    list(const list& x);\n    list(const list&, const allocator_type& a);\n    list(list&& x)\n        noexcept(is_nothrow_move_constructible<allocator_type>::value);\n    list(list&&, const allocator_type& a);\n    list(initializer_list<value_type>);\n    list(initializer_list<value_type>, const allocator_type& a);\n\n    ~list();\n\n    list& operator=(const list& x);\n    list& operator=(list&& x)\n        noexcept(\n             allocator_type::propagate_on_container_move_assignment::value &&\n             is_nothrow_move_assignable<allocator_type>::value);\n    list& operator=(initializer_list<value_type>);\n    template <class Iter>\n        void assign(Iter first, Iter last);\n    void assign(size_type n, const value_type& t);\n    void assign(initializer_list<value_type>);\n\n    allocator_type get_allocator() const noexcept;\n\n    iterator begin() noexcept;\n    const_iterator begin() const noexcept;\n    iterator end() noexcept;\n    const_iterator end() const noexcept;\n    reverse_iterator rbegin() noexcept;\n    const_reverse_iterator rbegin() const noexcept;\n    reverse_iterator rend() noexcept;\n    const_reverse_iterator rend() const noexcept;\n    const_iterator cbegin() const noexcept;\n    const_iterator cend() const noexcept;\n    const_reverse_iterator crbegin() const noexcept;\n    const_reverse_iterator crend() const noexcept;\n\n    reference front();\n    const_reference front() const;\n    reference back();\n    const_reference back() const;\n\n    bool empty() const noexcept;\n    size_type size() const noexcept;\n    size_type max_size() const noexcept;\n\n    template <class... Args>\n        void emplace_front(Args&&... args);\n    void pop_front();\n    template <class... Args>\n        void emplace_back(Args&&... args);\n    void pop_back();\n    void push_front(const value_type& x);\n    void push_front(value_type&& x);\n    void push_back(const value_type& x);\n    void push_back(value_type&& x);\n    template <class... Args>\n        iterator emplace(const_iterator position, Args&&... args);\n    iterator insert(const_iterator position, const value_type& x);\n    iterator insert(const_iterator position, value_type&& x);\n    iterator insert(const_iterator position, size_type n, const value_type& x);\n    template <class Iter>\n        iterator insert(const_iterator position, Iter first, Iter last);\n    iterator insert(const_iterator position, initializer_list<value_type> il);\n\n    iterator erase(const_iterator position);\n    iterator erase(const_iterator position, const_iterator last);\n\n    void resize(size_type sz);\n    void resize(size_type sz, const value_type& c);\n\n    void swap(list&)\n        noexcept(allocator_traits<allocator_type>::is_always_equal::value);  // C++17\n    void clear() noexcept;\n\n    void splice(const_iterator position, list& x);\n    void splice(const_iterator position, list&& x);\n    void splice(const_iterator position, list& x, const_iterator i);\n    void splice(const_iterator position, list&& x, const_iterator i);\n    void splice(const_iterator position, list& x, const_iterator first,\n                                                  const_iterator last);\n    void splice(const_iterator position, list&& x, const_iterator first,\n                                                  const_iterator last);\n\n    void remove(const value_type& value);\n    template <class Pred> void remove_if(Pred pred);\n    void unique();\n    template <class BinaryPredicate>\n        void unique(BinaryPredicate binary_pred);\n    void merge(list& x);\n    void merge(list&& x);\n    template <class Compare>\n        void merge(list& x, Compare comp);\n    template <class Compare>\n        void merge(list&& x, Compare comp);\n    void sort();\n    template <class Compare>\n        void sort(Compare comp);\n    void reverse() noexcept;\n};\n\ntemplate <class T, class Alloc>\n    bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y);\ntemplate <class T, class Alloc>\n    bool operator< (const list<T,Alloc>& x, const list<T,Alloc>& y);\ntemplate <class T, class Alloc>\n    bool operator!=(const list<T,Alloc>& x, const list<T,Alloc>& y);\ntemplate <class T, class Alloc>\n    bool operator> (const list<T,Alloc>& x, const list<T,Alloc>& y);\ntemplate <class T, class Alloc>\n    bool operator>=(const list<T,Alloc>& x, const list<T,Alloc>& y);\ntemplate <class T, class Alloc>\n    bool operator<=(const list<T,Alloc>& x, const list<T,Alloc>& y);\n\ntemplate <class T, class Alloc>\n    void swap(list<T,Alloc>& x, list<T,Alloc>& y)\n         noexcept(noexcept(x.swap(y)));\n\n}  // std\n\n*/\n\n#include <__config>\n\n#include <memory>\n#include <limits>\n#include <initializer_list>\n#include <iterator>\n#include <algorithm>\n\n#include <__undef_min_max>\n\n#include <__debug>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Tp, class _VoidPtr> struct __list_node;\n\ntemplate <class _Tp, class _VoidPtr>\nstruct __list_node_base\n{\n    typedef typename pointer_traits<_VoidPtr>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n        rebind<__list_node<_Tp, _VoidPtr> > pointer;\n#else\n        rebind<__list_node<_Tp, _VoidPtr> >::other pointer;\n#endif\n\n    typedef typename pointer_traits<_VoidPtr>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n        rebind<__list_node_base> __base_pointer;\n#else\n        rebind<__list_node_base>::other __base_pointer;\n#endif\n\n    pointer __prev_;\n    pointer __next_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __list_node_base() : __prev_(__self()), __next_(__self()) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    pointer __self()\n    {\n        return static_cast<pointer>(pointer_traits<__base_pointer>::pointer_to(*this));\n    }\n};\n\ntemplate <class _Tp, class _VoidPtr>\nstruct __list_node\n    : public __list_node_base<_Tp, _VoidPtr>\n{\n    _Tp __value_;\n};\n\ntemplate <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TYPE_VIS_ONLY list;\ntemplate <class _Tp, class _Alloc> class __list_imp;\ntemplate <class _Tp, class _VoidPtr> class _LIBCPP_TYPE_VIS_ONLY __list_const_iterator;\n\ntemplate <class _Tp, class _VoidPtr>\nclass _LIBCPP_TYPE_VIS_ONLY __list_iterator\n{\n    typedef typename pointer_traits<_VoidPtr>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n        rebind<__list_node<_Tp, _VoidPtr> > __node_pointer;\n#else\n        rebind<__list_node<_Tp, _VoidPtr> >::other __node_pointer;\n#endif\n\n    __node_pointer __ptr_;\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __list_iterator(__node_pointer __p, const void* __c) _NOEXCEPT\n        : __ptr_(__p)\n    {\n        __get_db()->__insert_ic(this, __c);\n    }\n#else\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}\n#endif\n\n\n\n    template<class, class> friend class list;\n    template<class, class> friend class __list_imp;\n    template<class, class> friend class __list_const_iterator;\npublic:\n    typedef bidirectional_iterator_tag       iterator_category;\n    typedef _Tp                              value_type;\n    typedef value_type&                      reference;\n    typedef typename pointer_traits<_VoidPtr>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<value_type>\n#else\n            rebind<value_type>::other\n#endif\n                                             pointer;\n    typedef typename pointer_traits<pointer>::difference_type difference_type;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __list_iterator() _NOEXCEPT : __ptr_(nullptr)\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->__insert_i(this);\n#endif\n    }\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n    _LIBCPP_INLINE_VISIBILITY\n    __list_iterator(const __list_iterator& __p)\n        : __ptr_(__p.__ptr_)\n    {\n        __get_db()->__iterator_copy(this, &__p);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    ~__list_iterator()\n    {\n        __get_db()->__erase_i(this);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __list_iterator& operator=(const __list_iterator& __p)\n    {\n        if (this != &__p)\n        {\n            __get_db()->__iterator_copy(this, &__p);\n            __ptr_ = __p.__ptr_;\n        }\n        return *this;\n    }\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\n    _LIBCPP_INLINE_VISIBILITY\n    reference operator*() const\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                       \"Attempted to dereference a non-dereferenceable list::iterator\");\n#endif\n        return __ptr_->__value_;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    pointer operator->() const\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                       \"Attempted to dereference a non-dereferenceable list::iterator\");\n#endif\n        return pointer_traits<pointer>::pointer_to(__ptr_->__value_);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __list_iterator& operator++()\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                       \"Attempted to increment non-incrementable list::iterator\");\n#endif\n        __ptr_ = __ptr_->__next_;\n        return *this;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    __list_iterator operator++(int) {__list_iterator __t(*this); ++(*this); return __t;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __list_iterator& operator--()\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),\n                       \"Attempted to decrement non-decrementable list::iterator\");\n#endif\n        __ptr_ = __ptr_->__prev_;\n        return *this;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    __list_iterator operator--(int) {__list_iterator __t(*this); --(*this); return __t;}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const __list_iterator& __x, const __list_iterator& __y)\n    {\n        return __x.__ptr_ == __y.__ptr_;\n    }\n    friend _LIBCPP_INLINE_VISIBILITY\n     bool operator!=(const __list_iterator& __x, const __list_iterator& __y)\n        {return !(__x == __y);}\n};\n\ntemplate <class _Tp, class _VoidPtr>\nclass _LIBCPP_TYPE_VIS_ONLY __list_const_iterator\n{\n    typedef typename pointer_traits<_VoidPtr>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n        rebind<__list_node<_Tp, _VoidPtr> > __node_pointer;\n#else\n        rebind<__list_node<_Tp, _VoidPtr> >::other __node_pointer;\n#endif\n\n    __node_pointer __ptr_;\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __list_const_iterator(__node_pointer __p, const void* __c) _NOEXCEPT\n        : __ptr_(__p)\n    {\n        __get_db()->__insert_ic(this, __c);\n    }\n#else\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __list_const_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}\n#endif\n\n    template<class, class> friend class list;\n    template<class, class> friend class __list_imp;\npublic:\n    typedef bidirectional_iterator_tag       iterator_category;\n    typedef _Tp                              value_type;\n    typedef const value_type&                reference;\n    typedef typename pointer_traits<_VoidPtr>::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<const value_type>\n#else\n            rebind<const value_type>::other\n#endif\n                                             pointer;\n    typedef typename pointer_traits<pointer>::difference_type difference_type;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __list_const_iterator() _NOEXCEPT : __ptr_(nullptr)\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->__insert_i(this);\n#endif\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    __list_const_iterator(const __list_iterator<_Tp, _VoidPtr>& __p) _NOEXCEPT\n        : __ptr_(__p.__ptr_)\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->__iterator_copy(this, &__p);\n#endif\n    }\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n    _LIBCPP_INLINE_VISIBILITY\n    __list_const_iterator(const __list_const_iterator& __p)\n        : __ptr_(__p.__ptr_)\n    {\n        __get_db()->__iterator_copy(this, &__p);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    ~__list_const_iterator()\n    {\n        __get_db()->__erase_i(this);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __list_const_iterator& operator=(const __list_const_iterator& __p)\n    {\n        if (this != &__p)\n        {\n            __get_db()->__iterator_copy(this, &__p);\n            __ptr_ = __p.__ptr_;\n        }\n        return *this;\n    }\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_INLINE_VISIBILITY\n    reference operator*() const\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                       \"Attempted to dereference a non-dereferenceable list::const_iterator\");\n#endif\n        return __ptr_->__value_;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    pointer operator->() const\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                       \"Attempted to dereference a non-dereferenceable list::iterator\");\n#endif\n        return pointer_traits<pointer>::pointer_to(__ptr_->__value_);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __list_const_iterator& operator++()\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),\n                       \"Attempted to increment non-incrementable list::const_iterator\");\n#endif\n        __ptr_ = __ptr_->__next_;\n        return *this;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    __list_const_iterator operator++(int) {__list_const_iterator __t(*this); ++(*this); return __t;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __list_const_iterator& operator--()\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),\n                       \"Attempted to decrement non-decrementable list::const_iterator\");\n#endif\n        __ptr_ = __ptr_->__prev_;\n        return *this;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    __list_const_iterator operator--(int) {__list_const_iterator __t(*this); --(*this); return __t;}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const __list_const_iterator& __x, const __list_const_iterator& __y)\n    {\n        return __x.__ptr_ == __y.__ptr_;\n    }\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const __list_const_iterator& __x, const __list_const_iterator& __y)\n        {return !(__x == __y);}\n};\n\ntemplate <class _Tp, class _Alloc>\nclass __list_imp\n{\n    __list_imp(const __list_imp&);\n    __list_imp& operator=(const __list_imp&);\nprotected:\n    typedef _Tp                                                     value_type;\n    typedef _Alloc                                                  allocator_type;\n    typedef allocator_traits<allocator_type>                        __alloc_traits;\n    typedef typename __alloc_traits::size_type                      size_type;\n    typedef typename __alloc_traits::void_pointer                   __void_pointer;\n    typedef __list_iterator<value_type, __void_pointer>             iterator;\n    typedef __list_const_iterator<value_type, __void_pointer>       const_iterator;\n    typedef __list_node_base<value_type, __void_pointer>            __node_base;\n    typedef __list_node<value_type, __void_pointer>                 __node;\n    typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;\n    typedef allocator_traits<__node_allocator>                       __node_alloc_traits;\n    typedef typename __node_alloc_traits::pointer                    __node_pointer;\n    typedef typename __node_alloc_traits::pointer                    __node_const_pointer;\n    typedef typename __alloc_traits::pointer                         pointer;\n    typedef typename __alloc_traits::const_pointer                   const_pointer;\n    typedef typename __alloc_traits::difference_type                 difference_type;\n\n    typedef typename __rebind_alloc_helper<__alloc_traits, __node_base>::type __node_base_allocator;\n    typedef typename allocator_traits<__node_base_allocator>::pointer __node_base_pointer;\n\n    __node_base __end_;\n    __compressed_pair<size_type, __node_allocator> __size_alloc_;\n\n    _LIBCPP_INLINE_VISIBILITY\n          size_type& __sz() _NOEXCEPT {return __size_alloc_.first();}\n    _LIBCPP_INLINE_VISIBILITY\n    const size_type& __sz() const _NOEXCEPT\n        {return __size_alloc_.first();}\n    _LIBCPP_INLINE_VISIBILITY\n          __node_allocator& __node_alloc() _NOEXCEPT\n          {return __size_alloc_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n    const __node_allocator& __node_alloc() const _NOEXCEPT\n        {return __size_alloc_.second();}\n\n    static void __unlink_nodes(__node_pointer __f, __node_pointer __l) _NOEXCEPT;\n\n    __list_imp()\n        _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value);\n    __list_imp(const allocator_type& __a);\n    ~__list_imp();\n    void clear() _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    bool empty() const _NOEXCEPT {return __sz() == 0;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator begin() _NOEXCEPT\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        return iterator(__end_.__next_, this);\n#else\n        return iterator(__end_.__next_);\n#endif\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin() const  _NOEXCEPT\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        return const_iterator(__end_.__next_, this);\n#else\n        return const_iterator(__end_.__next_);\n#endif\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    iterator end() _NOEXCEPT\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        return iterator(static_cast<__node_pointer>(\n                pointer_traits<__node_base_pointer>::pointer_to(__end_)), this);\n#else\n        return iterator(static_cast<__node_pointer>(\n                      pointer_traits<__node_base_pointer>::pointer_to(__end_)));\n#endif\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end() const _NOEXCEPT\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        return const_iterator(static_cast<__node_const_pointer>(\n        pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(__end_))), this);\n#else\n        return const_iterator(static_cast<__node_const_pointer>(\n        pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(__end_))));\n#endif\n    }\n\n    void swap(__list_imp& __c)\n#if _LIBCPP_STD_VER >= 14\n        _NOEXCEPT;\n#else\n        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || \n                    __is_nothrow_swappable<allocator_type>::value);\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const __list_imp& __c)\n        {__copy_assign_alloc(__c, integral_constant<bool,\n                      __node_alloc_traits::propagate_on_container_copy_assignment::value>());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__list_imp& __c)\n        _NOEXCEPT_(\n            !__node_alloc_traits::propagate_on_container_move_assignment::value ||\n            is_nothrow_move_assignable<__node_allocator>::value)\n        {__move_assign_alloc(__c, integral_constant<bool,\n                      __node_alloc_traits::propagate_on_container_move_assignment::value>());}\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const __list_imp& __c, true_type)\n        {\n            if (__node_alloc() != __c.__node_alloc())\n                clear();\n            __node_alloc() = __c.__node_alloc();\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const __list_imp& __c, false_type)\n        {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__list_imp& __c, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)\n        {\n            __node_alloc() = _VSTD::move(__c.__node_alloc());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__list_imp& __c, false_type)\n        _NOEXCEPT\n        {}\n};\n\n// Unlink nodes [__f, __l]\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__list_imp<_Tp, _Alloc>::__unlink_nodes(__node_pointer __f, __node_pointer __l)\n    _NOEXCEPT\n{\n    __f->__prev_->__next_ = __l->__next_;\n    __l->__next_->__prev_ = __f->__prev_;\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\n__list_imp<_Tp, _Alloc>::__list_imp()\n        _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)\n    : __size_alloc_(0)\n{\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\n__list_imp<_Tp, _Alloc>::__list_imp(const allocator_type& __a)\n    : __size_alloc_(0, __node_allocator(__a))\n{\n}\n\ntemplate <class _Tp, class _Alloc>\n__list_imp<_Tp, _Alloc>::~__list_imp()\n{\n    clear();\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__erase_c(this);\n#endif\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\n__list_imp<_Tp, _Alloc>::clear() _NOEXCEPT\n{\n    if (!empty())\n    {\n        __node_allocator& __na = __node_alloc();\n        __node_pointer __f = __end_.__next_;\n        __node_pointer __l = static_cast<__node_pointer>(\n                       pointer_traits<__node_base_pointer>::pointer_to(__end_));\n        __unlink_nodes(__f, __l->__prev_);\n        __sz() = 0;\n        while (__f != __l)\n        {\n            __node_pointer __n = __f;\n            __f = __f->__next_;\n            __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));\n            __node_alloc_traits::deallocate(__na, __n, 1);\n        }\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __c_node* __c = __get_db()->__find_c_and_lock(this);\n        for (__i_node** __p = __c->end_; __p != __c->beg_; )\n        {\n            --__p;\n            const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);\n            if (__i->__ptr_ != __l)\n            {\n                (*__p)->__c_ = nullptr;\n                if (--__c->end_ != __p)\n                    memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));\n            }\n        }\n        __get_db()->unlock();\n#endif\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\n__list_imp<_Tp, _Alloc>::swap(__list_imp& __c)\n#if _LIBCPP_STD_VER >= 14\n        _NOEXCEPT\n#else\n        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || \n                    __is_nothrow_swappable<allocator_type>::value)\n#endif\n{\n    _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||\n                   this->__node_alloc() == __c.__node_alloc(),\n                   \"list::swap: Either propagate_on_container_swap must be true\"\n                   \" or the allocators must compare equal\");\n    using _VSTD::swap;\n    __swap_allocator(__node_alloc(), __c.__node_alloc());\n    swap(__sz(), __c.__sz());\n    swap(__end_, __c.__end_);\n    if (__sz() == 0)\n        __end_.__next_ = __end_.__prev_ = __end_.__self();\n    else\n        __end_.__prev_->__next_ = __end_.__next_->__prev_ = __end_.__self();\n    if (__c.__sz() == 0)\n        __c.__end_.__next_ = __c.__end_.__prev_ = __c.__end_.__self();\n    else\n        __c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = __c.__end_.__self();\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __libcpp_db* __db = __get_db();\n    __c_node* __cn1 = __db->__find_c_and_lock(this);\n    __c_node* __cn2 = __db->__find_c(&__c);\n    std::swap(__cn1->beg_, __cn2->beg_);\n    std::swap(__cn1->end_, __cn2->end_);\n    std::swap(__cn1->cap_, __cn2->cap_);\n    for (__i_node** __p = __cn1->end_; __p != __cn1->beg_;)\n    {\n        --__p;\n        const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);\n        if (__i->__ptr_ == static_cast<__node_pointer>(\n                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))\n        {\n            __cn2->__add(*__p);\n            if (--__cn1->end_ != __p)\n                memmove(__p, __p+1, (__cn1->end_ - __p)*sizeof(__i_node*));\n        }\n        else\n            (*__p)->__c_ = __cn1;\n    }\n    for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;)\n    {\n        --__p;\n        const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);\n        if (__i->__ptr_ == static_cast<__node_pointer>(\n                       pointer_traits<__node_base_pointer>::pointer_to(__end_)))\n        {\n            __cn1->__add(*__p);\n            if (--__cn2->end_ != __p)\n                memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*));\n        }\n        else\n            (*__p)->__c_ = __cn2;\n    }\n    __db->unlock();\n#endif\n}\n\ntemplate <class _Tp, class _Alloc /*= allocator<_Tp>*/>\nclass _LIBCPP_TYPE_VIS_ONLY list\n    : private __list_imp<_Tp, _Alloc>\n{\n    typedef __list_imp<_Tp, _Alloc> base;\n    typedef typename base::__node              __node;\n    typedef typename base::__node_allocator    __node_allocator;\n    typedef typename base::__node_pointer      __node_pointer;\n    typedef typename base::__node_alloc_traits __node_alloc_traits;\n    typedef typename base::__node_base         __node_base;\n    typedef typename base::__node_base_pointer __node_base_pointer;\n\npublic:\n    typedef _Tp                                      value_type;\n    typedef _Alloc                                   allocator_type;\n    static_assert((is_same<value_type, typename allocator_type::value_type>::value),\n                  \"Invalid allocator::value_type\");\n    typedef value_type&                              reference;\n    typedef const value_type&                        const_reference;\n    typedef typename base::pointer                   pointer;\n    typedef typename base::const_pointer             const_pointer;\n    typedef typename base::size_type                 size_type;\n    typedef typename base::difference_type           difference_type;\n    typedef typename base::iterator                  iterator;\n    typedef typename base::const_iterator            const_iterator;\n    typedef _VSTD::reverse_iterator<iterator>         reverse_iterator;\n    typedef _VSTD::reverse_iterator<const_iterator>   const_reverse_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY\n    list()\n        _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->__insert_c(this);\n#endif\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    explicit list(const allocator_type& __a) : base(__a)\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->__insert_c(this);\n#endif\n    }\n    explicit list(size_type __n);\n#if _LIBCPP_STD_VER > 11\n    explicit list(size_type __n, const allocator_type& __a);\n#endif\n    list(size_type __n, const value_type& __x);\n    list(size_type __n, const value_type& __x, const allocator_type& __a);\n    template <class _InpIter>\n        list(_InpIter __f, _InpIter __l,\n             typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);\n    template <class _InpIter>\n        list(_InpIter __f, _InpIter __l, const allocator_type& __a,\n             typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);\n\n    list(const list& __c);\n    list(const list& __c, const allocator_type& __a);\n    list& operator=(const list& __c);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    list(initializer_list<value_type> __il);\n    list(initializer_list<value_type> __il, const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    list(list&& __c)\n        _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);\n    list(list&& __c, const allocator_type& __a);\n    list& operator=(list&& __c)\n        _NOEXCEPT_(\n            __node_alloc_traits::propagate_on_container_move_assignment::value &&\n            is_nothrow_move_assignable<__node_allocator>::value);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    list& operator=(initializer_list<value_type> __il)\n        {assign(__il.begin(), __il.end()); return *this;}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    template <class _InpIter>\n        void assign(_InpIter __f, _InpIter __l,\n             typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);\n    void assign(size_type __n, const value_type& __x);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    void assign(initializer_list<value_type> __il)\n        {assign(__il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    allocator_type get_allocator() const _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const _NOEXCEPT     {return base::__sz();}\n    _LIBCPP_INLINE_VISIBILITY\n    bool empty() const _NOEXCEPT         {return base::empty();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const _NOEXCEPT\n        {return numeric_limits<difference_type>::max();}\n\n    _LIBCPP_INLINE_VISIBILITY\n          iterator begin() _NOEXCEPT        {return base::begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin()  const _NOEXCEPT {return base::begin();}\n    _LIBCPP_INLINE_VISIBILITY\n          iterator end() _NOEXCEPT          {return base::end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end()    const _NOEXCEPT {return base::end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cbegin() const _NOEXCEPT {return base::begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cend()   const _NOEXCEPT {return base::end();}\n\n    _LIBCPP_INLINE_VISIBILITY\n          reverse_iterator rbegin() _NOEXCEPT\n            {return       reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rbegin()  const _NOEXCEPT\n        {return const_reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n          reverse_iterator rend() _NOEXCEPT\n            {return       reverse_iterator(begin());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rend()    const _NOEXCEPT\n        {return const_reverse_iterator(begin());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crbegin() const _NOEXCEPT\n        {return const_reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crend()   const _NOEXCEPT\n        {return const_reverse_iterator(begin());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    reference front()\n    {\n        _LIBCPP_ASSERT(!empty(), \"list::front called on empty list\");\n        return base::__end_.__next_->__value_;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    const_reference front() const\n    {\n        _LIBCPP_ASSERT(!empty(), \"list::front called on empty list\");\n        return base::__end_.__next_->__value_;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    reference back()\n    {\n        _LIBCPP_ASSERT(!empty(), \"list::back called on empty list\");\n        return base::__end_.__prev_->__value_;\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    const_reference back() const\n    {\n        _LIBCPP_ASSERT(!empty(), \"list::back called on empty list\");\n        return base::__end_.__prev_->__value_;\n    }\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void push_front(value_type&& __x);\n    void push_back(value_type&& __x);\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class... _Args>\n       void emplace_front(_Args&&... __args);\n    template <class... _Args>\n        void emplace_back(_Args&&... __args);\n    template <class... _Args>\n        iterator emplace(const_iterator __p, _Args&&... __args);\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n    iterator insert(const_iterator __p, value_type&& __x);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    void push_front(const value_type& __x);\n    void push_back(const value_type& __x);\n\n    iterator insert(const_iterator __p, const value_type& __x);\n    iterator insert(const_iterator __p, size_type __n, const value_type& __x);\n    template <class _InpIter>\n        iterator insert(const_iterator __p, _InpIter __f, _InpIter __l,\n             typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator __p, initializer_list<value_type> __il)\n        {return insert(__p, __il.begin(), __il.end());}\n#endif   // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(list& __c)\n#if _LIBCPP_STD_VER >= 14\n        _NOEXCEPT\n#else\n        _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||\n                   __is_nothrow_swappable<__node_allocator>::value)\n#endif\n        {base::swap(__c);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() _NOEXCEPT {base::clear();}\n\n    void pop_front();\n    void pop_back();\n\n    iterator erase(const_iterator __p);\n    iterator erase(const_iterator __f, const_iterator __l);\n\n    void resize(size_type __n);\n    void resize(size_type __n, const value_type& __x);\n\n    void splice(const_iterator __p, list& __c);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void splice(const_iterator __p, list&& __c) {splice(__p, __c);}\n#endif\n    void splice(const_iterator __p, list& __c, const_iterator __i);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void splice(const_iterator __p, list&& __c, const_iterator __i)\n        {splice(__p, __c, __i);}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void splice(const_iterator __p, list&& __c, const_iterator __f, const_iterator __l)\n        {splice(__p, __c, __f, __l);}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    void remove(const value_type& __x);\n    template <class _Pred> void remove_if(_Pred __pred);\n    void unique();\n    template <class _BinaryPred>\n        void unique(_BinaryPred __binary_pred);\n    void merge(list& __c);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void merge(list&& __c) {merge(__c);}\n#endif\n    template <class _Comp>\n        void merge(list& __c, _Comp __comp);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Comp>\n    _LIBCPP_INLINE_VISIBILITY\n        void merge(list&& __c, _Comp __comp) {merge(__c, __comp);}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void sort();\n    template <class _Comp>\n        void sort(_Comp __comp);\n\n    void reverse() _NOEXCEPT;\n\n    bool __invariants() const;\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n    bool __dereferenceable(const const_iterator* __i) const;\n    bool __decrementable(const const_iterator* __i) const;\n    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;\n    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\nprivate:\n    static void __link_nodes  (__node_pointer __p, __node_pointer __f, __node_pointer __l);\n    void __link_nodes_at_front(__node_pointer __f, __node_pointer __l);\n    void __link_nodes_at_back (__node_pointer __f, __node_pointer __l);\n    iterator __iterator(size_type __n);\n    template <class _Comp>\n        static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp);\n\n    void __move_assign(list& __c, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value);\n    void __move_assign(list& __c, false_type);\n};\n\n// Link in nodes [__f, __l] just prior to __p\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nlist<_Tp, _Alloc>::__link_nodes(__node_pointer __p, __node_pointer __f, __node_pointer __l)\n{\n    __p->__prev_->__next_ = __f;\n    __f->__prev_ = __p->__prev_;\n    __p->__prev_ = __l;\n    __l->__next_ = __p;\n}\n\n// Link in nodes [__f, __l] at the front of the list\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nlist<_Tp, _Alloc>::__link_nodes_at_front(__node_pointer __f, __node_pointer __l)\n{\n    __f->__prev_ = base::__end_.__self();\n    __l->__next_ = base::__end_.__next_;\n    __l->__next_->__prev_ = __l;\n    base::__end_.__next_ = __f;\n}\n\n// Link in nodes [__f, __l] at the front of the list\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nlist<_Tp, _Alloc>::__link_nodes_at_back(__node_pointer __f, __node_pointer __l)\n{\n    __l->__next_ = base::__end_.__self();\n    __f->__prev_ = base::__end_.__prev_;\n    __f->__prev_->__next_ = __f;\n    base::__end_.__prev_ = __l;\n}\n\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename list<_Tp, _Alloc>::iterator\nlist<_Tp, _Alloc>::__iterator(size_type __n)\n{\n    return __n <= base::__sz() / 2 ? _VSTD::next(begin(), __n)\n                                   : _VSTD::prev(end(), base::__sz() - __n);\n}\n\ntemplate <class _Tp, class _Alloc>\nlist<_Tp, _Alloc>::list(size_type __n)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    for (; __n > 0; --__n)\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n        emplace_back();\n#else\n        push_back(value_type());\n#endif\n}\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp, class _Alloc>\nlist<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    for (; __n > 0; --__n)\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n        emplace_back();\n#else\n        push_back(value_type());\n#endif\n}\n#endif\n\ntemplate <class _Tp, class _Alloc>\nlist<_Tp, _Alloc>::list(size_type __n, const value_type& __x)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    for (; __n > 0; --__n)\n        push_back(__x);\n}\n\ntemplate <class _Tp, class _Alloc>\nlist<_Tp, _Alloc>::list(size_type __n, const value_type& __x, const allocator_type& __a)\n    : base(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    for (; __n > 0; --__n)\n        push_back(__x);\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _InpIter>\nlist<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l,\n                        typename enable_if<__is_input_iterator<_InpIter>::value>::type*)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    for (; __f != __l; ++__f)\n        push_back(*__f);\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _InpIter>\nlist<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a,\n                        typename enable_if<__is_input_iterator<_InpIter>::value>::type*)\n    : base(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    for (; __f != __l; ++__f)\n        push_back(*__f);\n}\n\ntemplate <class _Tp, class _Alloc>\nlist<_Tp, _Alloc>::list(const list& __c)\n    : base(allocator_type(\n           __node_alloc_traits::select_on_container_copy_construction(\n                __c.__node_alloc())))\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i)\n        push_back(*__i);\n}\n\ntemplate <class _Tp, class _Alloc>\nlist<_Tp, _Alloc>::list(const list& __c, const allocator_type& __a)\n    : base(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i)\n        push_back(*__i);\n}\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp, class _Alloc>\nlist<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& __a)\n    : base(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    for (typename initializer_list<value_type>::const_iterator __i = __il.begin(),\n            __e = __il.end(); __i != __e; ++__i)\n        push_back(*__i);\n}\n\ntemplate <class _Tp, class _Alloc>\nlist<_Tp, _Alloc>::list(initializer_list<value_type> __il)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    for (typename initializer_list<value_type>::const_iterator __i = __il.begin(),\n            __e = __il.end(); __i != __e; ++__i)\n        push_back(*__i);\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nlist<_Tp, _Alloc>&\nlist<_Tp, _Alloc>::operator=(const list& __c)\n{\n    if (this != &__c)\n    {\n        base::__copy_assign_alloc(__c);\n        assign(__c.begin(), __c.end());\n    }\n    return *this;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nlist<_Tp, _Alloc>::list(list&& __c)\n    _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)\n    : base(allocator_type(_VSTD::move(__c.__node_alloc())))\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    splice(end(), __c);\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nlist<_Tp, _Alloc>::list(list&& __c, const allocator_type& __a)\n    : base(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    if (__a == __c.get_allocator())\n        splice(end(), __c);\n    else\n    {\n        typedef move_iterator<iterator> _Ip;\n        assign(_Ip(__c.begin()), _Ip(__c.end()));\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nlist<_Tp, _Alloc>&\nlist<_Tp, _Alloc>::operator=(list&& __c)\n        _NOEXCEPT_(\n            __node_alloc_traits::propagate_on_container_move_assignment::value &&\n            is_nothrow_move_assignable<__node_allocator>::value)\n{\n    __move_assign(__c, integral_constant<bool,\n          __node_alloc_traits::propagate_on_container_move_assignment::value>());\n    return *this;\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::__move_assign(list& __c, false_type)\n{\n    if (base::__node_alloc() != __c.__node_alloc())\n    {\n        typedef move_iterator<iterator> _Ip;\n        assign(_Ip(__c.begin()), _Ip(__c.end()));\n    }\n    else\n        __move_assign(__c, true_type());\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::__move_assign(list& __c, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)\n{\n    clear();\n    base::__move_assign_alloc(__c);\n    splice(end(), __c);\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _InpIter>\nvoid\nlist<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l,\n                          typename enable_if<__is_input_iterator<_InpIter>::value>::type*)\n{\n    iterator __i = begin();\n    iterator __e = end();\n    for (; __f != __l && __i != __e; ++__f, ++__i)\n        *__i = *__f;\n    if (__i == __e)\n        insert(__e, __f, __l);\n    else\n        erase(__i, __e);\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::assign(size_type __n, const value_type& __x)\n{\n    iterator __i = begin();\n    iterator __e = end();\n    for (; __n > 0 && __i != __e; --__n, ++__i)\n        *__i = __x;\n    if (__i == __e)\n        insert(__e, __n, __x);\n    else\n        erase(__i, __e);\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\n_Alloc\nlist<_Tp, _Alloc>::get_allocator() const _NOEXCEPT\n{\n    return allocator_type(base::__node_alloc());\n}\n\ntemplate <class _Tp, class _Alloc>\ntypename list<_Tp, _Alloc>::iterator\nlist<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n        \"list::insert(iterator, x) called with an iterator not\"\n        \" referring to this list\");\n#endif\n    __node_allocator& __na = base::__node_alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));\n    __hold->__prev_ = 0;\n    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);\n    __link_nodes(__p.__ptr_, __hold.get(), __hold.get());\n    ++base::__sz();\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return iterator(__hold.release(), this);\n#else\n    return iterator(__hold.release());\n#endif\n}\n\ntemplate <class _Tp, class _Alloc>\ntypename list<_Tp, _Alloc>::iterator\nlist<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& __x)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n        \"list::insert(iterator, n, x) called with an iterator not\"\n        \" referring to this list\");\n    iterator __r(__p.__ptr_, this);\n#else\n    iterator __r(__p.__ptr_);\n#endif\n    if (__n > 0)\n    {\n        size_type __ds = 0;\n        __node_allocator& __na = base::__node_alloc();\n        typedef __allocator_destructor<__node_allocator> _Dp;\n        unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));\n        __hold->__prev_ = 0;\n        __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);\n        ++__ds;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __r = iterator(__hold.get(), this);\n#else\n        __r = iterator(__hold.get());\n#endif\n        __hold.release();\n        iterator __e = __r;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (--__n; __n != 0; --__n, ++__e, ++__ds)\n            {\n                __hold.reset(__node_alloc_traits::allocate(__na, 1));\n                __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);\n                __e.__ptr_->__next_ = __hold.get();\n                __hold->__prev_ = __e.__ptr_;\n                __hold.release();\n            }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            while (true)\n            {\n                __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));\n                __node_pointer __prev = __e.__ptr_->__prev_;\n                __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);\n                if (__prev == 0)\n                    break;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n                __e = iterator(__prev, this);\n#else\n                __e = iterator(__prev);\n#endif\n            }\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_);\n        base::__sz() += __ds;\n    }\n    return __r;\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _InpIter>\ntypename list<_Tp, _Alloc>::iterator\nlist<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,\n             typename enable_if<__is_input_iterator<_InpIter>::value>::type*)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n        \"list::insert(iterator, range) called with an iterator not\"\n        \" referring to this list\");\n    iterator __r(__p.__ptr_, this);\n#else\n    iterator __r(__p.__ptr_);\n#endif\n    if (__f != __l)\n    {\n        size_type __ds = 0;\n        __node_allocator& __na = base::__node_alloc();\n        typedef __allocator_destructor<__node_allocator> _Dp;\n        unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));\n        __hold->__prev_ = 0;\n        __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f);\n        ++__ds;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __r = iterator(__hold.get(), this);\n#else\n        __r = iterator(__hold.get());\n#endif\n        __hold.release();\n        iterator __e = __r;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (++__f; __f != __l; ++__f, (void) ++__e, (void) ++__ds)\n            {\n                __hold.reset(__node_alloc_traits::allocate(__na, 1));\n                __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f);\n                __e.__ptr_->__next_ = __hold.get();\n                __hold->__prev_ = __e.__ptr_;\n                __hold.release();\n            }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            while (true)\n            {\n                __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));\n                __node_pointer __prev = __e.__ptr_->__prev_;\n                __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);\n                if (__prev == 0)\n                    break;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n                __e = iterator(__prev, this);\n#else\n                __e = iterator(__prev);\n#endif\n            }\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_);\n        base::__sz() += __ds;\n    }\n    return __r;\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::push_front(const value_type& __x)\n{\n    __node_allocator& __na = base::__node_alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));\n    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);\n    __link_nodes_at_front(__hold.get(), __hold.get());\n    ++base::__sz();\n    __hold.release();\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::push_back(const value_type& __x)\n{\n    __node_allocator& __na = base::__node_alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));\n    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);\n    __link_nodes_at_back(__hold.get(), __hold.get());\n    ++base::__sz();\n    __hold.release();\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::push_front(value_type&& __x)\n{\n    __node_allocator& __na = base::__node_alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));\n    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));\n    __link_nodes_at_front(__hold.get(), __hold.get());\n    ++base::__sz();\n    __hold.release();\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::push_back(value_type&& __x)\n{\n    __node_allocator& __na = base::__node_alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));\n    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));\n    __link_nodes_at_back(__hold.get(), __hold.get());\n    ++base::__sz();\n    __hold.release();\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class... _Args>\nvoid\nlist<_Tp, _Alloc>::emplace_front(_Args&&... __args)\n{\n    __node_allocator& __na = base::__node_alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));\n    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);\n    __link_nodes_at_front(__hold.get(), __hold.get());\n    ++base::__sz();\n    __hold.release();\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class... _Args>\nvoid\nlist<_Tp, _Alloc>::emplace_back(_Args&&... __args)\n{\n    __node_allocator& __na = base::__node_alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));\n    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);\n    __link_nodes_at_back(__hold.get(), __hold.get());\n    ++base::__sz();\n    __hold.release();\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class... _Args>\ntypename list<_Tp, _Alloc>::iterator\nlist<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n        \"list::emplace(iterator, args...) called with an iterator not\"\n        \" referring to this list\");\n#endif\n    __node_allocator& __na = base::__node_alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));\n    __hold->__prev_ = 0;\n    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);\n    __link_nodes(__p.__ptr_, __hold.get(), __hold.get());\n    ++base::__sz();\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return iterator(__hold.release(), this);\n#else\n    return iterator(__hold.release());\n#endif\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Alloc>\ntypename list<_Tp, _Alloc>::iterator\nlist<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n        \"list::insert(iterator, x) called with an iterator not\"\n        \" referring to this list\");\n#endif\n    __node_allocator& __na = base::__node_alloc();\n    typedef __allocator_destructor<__node_allocator> _Dp;\n    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));\n    __hold->__prev_ = 0;\n    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));\n    __link_nodes(__p.__ptr_, __hold.get(), __hold.get());\n    ++base::__sz();\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return iterator(__hold.release(), this);\n#else\n    return iterator(__hold.release());\n#endif\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::pop_front()\n{\n    _LIBCPP_ASSERT(!empty(), \"list::pop_front() called with empty list\");\n    __node_allocator& __na = base::__node_alloc();\n    __node_pointer __n = base::__end_.__next_;\n    base::__unlink_nodes(__n, __n);\n    --base::__sz();\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __c_node* __c = __get_db()->__find_c_and_lock(this);\n    for (__i_node** __p = __c->end_; __p != __c->beg_; )\n    {\n        --__p;\n        iterator* __i = static_cast<iterator*>((*__p)->__i_);\n        if (__i->__ptr_ == __n)\n        {\n            (*__p)->__c_ = nullptr;\n            if (--__c->end_ != __p)\n                memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));\n        }\n    }\n    __get_db()->unlock();\n#endif\n    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));\n    __node_alloc_traits::deallocate(__na, __n, 1);\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::pop_back()\n{\n    _LIBCPP_ASSERT(!empty(), \"list::pop_back() called with empty list\");\n    __node_allocator& __na = base::__node_alloc();\n    __node_pointer __n = base::__end_.__prev_;\n    base::__unlink_nodes(__n, __n);\n    --base::__sz();\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __c_node* __c = __get_db()->__find_c_and_lock(this);\n    for (__i_node** __p = __c->end_; __p != __c->beg_; )\n    {\n        --__p;\n        iterator* __i = static_cast<iterator*>((*__p)->__i_);\n        if (__i->__ptr_ == __n)\n        {\n            (*__p)->__c_ = nullptr;\n            if (--__c->end_ != __p)\n                memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));\n        }\n    }\n    __get_db()->unlock();\n#endif\n    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));\n    __node_alloc_traits::deallocate(__na, __n, 1);\n}\n\ntemplate <class _Tp, class _Alloc>\ntypename list<_Tp, _Alloc>::iterator\nlist<_Tp, _Alloc>::erase(const_iterator __p)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n        \"list::erase(iterator) called with an iterator not\"\n        \" referring to this list\");\n#endif\n    _LIBCPP_ASSERT(__p != end(),\n        \"list::erase(iterator) called with a non-dereferenceable iterator\");\n    __node_allocator& __na = base::__node_alloc();\n    __node_pointer __n = __p.__ptr_;\n    __node_pointer __r = __n->__next_;\n    base::__unlink_nodes(__n, __n);\n    --base::__sz();\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __c_node* __c = __get_db()->__find_c_and_lock(this);\n    for (__i_node** __p = __c->end_; __p != __c->beg_; )\n    {\n        --__p;\n        iterator* __i = static_cast<iterator*>((*__p)->__i_);\n        if (__i->__ptr_ == __n)\n        {\n            (*__p)->__c_ = nullptr;\n            if (--__c->end_ != __p)\n                memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));\n        }\n    }\n    __get_db()->unlock();\n#endif\n    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));\n    __node_alloc_traits::deallocate(__na, __n, 1);\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return iterator(__r, this);\n#else\n    return iterator(__r);\n#endif\n}\n\ntemplate <class _Tp, class _Alloc>\ntypename list<_Tp, _Alloc>::iterator\nlist<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__f) == this,\n        \"list::erase(iterator, iterator) called with an iterator not\"\n        \" referring to this list\");\n#endif\n    if (__f != __l)\n    {\n        __node_allocator& __na = base::__node_alloc();\n        base::__unlink_nodes(__f.__ptr_, __l.__ptr_->__prev_);\n        while (__f != __l)\n        {\n            __node_pointer __n = __f.__ptr_;\n            ++__f;\n            --base::__sz();\n#if _LIBCPP_DEBUG_LEVEL >= 2\n            __c_node* __c = __get_db()->__find_c_and_lock(this);\n            for (__i_node** __p = __c->end_; __p != __c->beg_; )\n            {\n                --__p;\n                iterator* __i = static_cast<iterator*>((*__p)->__i_);\n                if (__i->__ptr_ == __n)\n                {\n                    (*__p)->__c_ = nullptr;\n                    if (--__c->end_ != __p)\n                        memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));\n                }\n            }\n            __get_db()->unlock();\n#endif\n            __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));\n            __node_alloc_traits::deallocate(__na, __n, 1);\n        }\n    }\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return iterator(__l.__ptr_, this);\n#else\n    return iterator(__l.__ptr_);\n#endif\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::resize(size_type __n)\n{\n    if (__n < base::__sz())\n        erase(__iterator(__n), end());\n    else if (__n > base::__sz())\n    {\n        __n -= base::__sz();\n        size_type __ds = 0;\n        __node_allocator& __na = base::__node_alloc();\n        typedef __allocator_destructor<__node_allocator> _Dp;\n        unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));\n        __hold->__prev_ = 0;\n        __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_));\n        ++__ds;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        iterator __r = iterator(__hold.release(), this);\n#else\n        iterator __r = iterator(__hold.release());\n#endif\n        iterator __e = __r;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (--__n; __n != 0; --__n, ++__e, ++__ds)\n            {\n                __hold.reset(__node_alloc_traits::allocate(__na, 1));\n                __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_));\n                __e.__ptr_->__next_ = __hold.get();\n                __hold->__prev_ = __e.__ptr_;\n                __hold.release();\n            }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            while (true)\n            {\n                __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));\n                __node_pointer __prev = __e.__ptr_->__prev_;\n                __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);\n                if (__prev == 0)\n                    break;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n                __e = iterator(__prev, this);\n#else\n                __e = iterator(__prev);\n#endif\n            }\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        __link_nodes_at_back(__r.__ptr_, __e.__ptr_);\n        base::__sz() += __ds;\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)\n{\n    if (__n < base::__sz())\n        erase(__iterator(__n), end());\n    else if (__n > base::__sz())\n    {\n        __n -= base::__sz();\n        size_type __ds = 0;\n        __node_allocator& __na = base::__node_alloc();\n        typedef __allocator_destructor<__node_allocator> _Dp;\n        unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));\n        __hold->__prev_ = 0;\n        __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);\n        ++__ds;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        iterator __r = iterator(__hold.release(), this);\n#else\n        iterator __r = iterator(__hold.release());\n#endif\n        iterator __e = __r;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (--__n; __n != 0; --__n, ++__e, ++__ds)\n            {\n                __hold.reset(__node_alloc_traits::allocate(__na, 1));\n                __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);\n                __e.__ptr_->__next_ = __hold.get();\n                __hold->__prev_ = __e.__ptr_;\n                __hold.release();\n            }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            while (true)\n            {\n                __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));\n                __node_pointer __prev = __e.__ptr_->__prev_;\n                __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);\n                if (__prev == 0)\n                    break;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n                __e = iterator(__prev, this);\n#else\n                __e = iterator(__prev);\n#endif\n            }\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        __link_nodes(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::\n                         pointer_to(base::__end_)), __r.__ptr_, __e.__ptr_);\n        base::__sz() += __ds;\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::splice(const_iterator __p, list& __c)\n{\n    _LIBCPP_ASSERT(this != &__c,\n                   \"list::splice(iterator, list) called with this == &list\");\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n        \"list::splice(iterator, list) called with an iterator not\"\n        \" referring to this list\");\n#endif\n    if (!__c.empty())\n    {\n        __node_pointer __f = __c.__end_.__next_;\n        __node_pointer __l = __c.__end_.__prev_;\n        base::__unlink_nodes(__f, __l);\n        __link_nodes(__p.__ptr_, __f, __l);\n        base::__sz() += __c.__sz();\n        __c.__sz() = 0;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __libcpp_db* __db = __get_db();\n        __c_node* __cn1 = __db->__find_c_and_lock(this);\n        __c_node* __cn2 = __db->__find_c(&__c);\n        for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;)\n        {\n            --__p;\n            iterator* __i = static_cast<iterator*>((*__p)->__i_);\n            if (__i->__ptr_ != static_cast<__node_pointer>(\n                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))\n            {\n                __cn1->__add(*__p);\n                (*__p)->__c_ = __cn1;\n                if (--__cn2->end_ != __p)\n                    memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*));\n            }\n        }\n        __db->unlock();\n#endif\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n        \"list::splice(iterator, list, iterator) called with first iterator not\"\n        \" referring to this list\");\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__i) == &__c,\n        \"list::splice(iterator, list, iterator) called with second iterator not\"\n        \" referring to list argument\");\n    _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(&__i),\n        \"list::splice(iterator, list, iterator) called with second iterator not\"\n        \" derefereceable\");\n#endif\n    if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_)\n    {\n        __node_pointer __f = __i.__ptr_;\n        base::__unlink_nodes(__f, __f);\n        __link_nodes(__p.__ptr_, __f, __f);\n        --__c.__sz();\n        ++base::__sz();\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __libcpp_db* __db = __get_db();\n        __c_node* __cn1 = __db->__find_c_and_lock(this);\n        __c_node* __cn2 = __db->__find_c(&__c);\n        for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;)\n        {\n            --__p;\n            iterator* __j = static_cast<iterator*>((*__p)->__i_);\n            if (__j->__ptr_ == __f)\n            {\n                __cn1->__add(*__p);\n                (*__p)->__c_ = __cn1;\n                if (--__cn2->end_ != __p)\n                    memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*));\n            }\n        }\n        __db->unlock();\n#endif\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n        \"list::splice(iterator, list, iterator, iterator) called with first iterator not\"\n        \" referring to this list\");\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__f) == &__c,\n        \"list::splice(iterator, list, iterator, iterator) called with second iterator not\"\n        \" referring to list argument\");\n    if (this == &__c)\n    {\n        for (const_iterator __i = __f; __i != __l; ++__i)\n            _LIBCPP_ASSERT(__i != __p,\n                           \"list::splice(iterator, list, iterator, iterator)\"\n                           \" called with the first iterator within the range\"\n                           \" of the second and third iterators\");\n    }\n#endif\n    if (__f != __l)\n    {\n        if (this != &__c)\n        {\n            size_type __s = _VSTD::distance(__f, __l);\n            __c.__sz() -= __s;\n            base::__sz() += __s;\n        }\n        __node_pointer __first = __f.__ptr_;\n        --__l;\n        __node_pointer __last = __l.__ptr_;\n        base::__unlink_nodes(__first, __last);\n        __link_nodes(__p.__ptr_, __first, __last);\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __libcpp_db* __db = __get_db();\n        __c_node* __cn1 = __db->__find_c_and_lock(this);\n        __c_node* __cn2 = __db->__find_c(&__c);\n        for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;)\n        {\n            --__p;\n            iterator* __j = static_cast<iterator*>((*__p)->__i_);\n            for (__node_pointer __k = __f.__ptr_;\n                                          __k != __l.__ptr_; __k = __k->__next_)\n            {\n                if (__j->__ptr_ == __k)\n                {\n                    __cn1->__add(*__p);\n                    (*__p)->__c_ = __cn1;\n                    if (--__cn2->end_ != __p)\n                        memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*));\n                }\n            }\n        }\n        __db->unlock();\n#endif\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::remove(const value_type& __x)\n{\n    list<_Tp, _Alloc> __deleted_nodes; // collect the nodes we're removing\n    for (const_iterator __i = begin(), __e = end(); __i != __e;)\n    {\n        if (*__i == __x)\n        {\n            const_iterator __j = _VSTD::next(__i);\n            for (; __j != __e && *__j == __x; ++__j)\n                ;\n            __deleted_nodes.splice(__deleted_nodes.end(), *this, __i, __j);\n            __i = __j;\n            if (__i != __e)\n                ++__i;\n        }\n        else\n            ++__i;\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _Pred>\nvoid\nlist<_Tp, _Alloc>::remove_if(_Pred __pred)\n{\n    for (iterator __i = begin(), __e = end(); __i != __e;)\n    {\n        if (__pred(*__i))\n        {\n            iterator __j = _VSTD::next(__i);\n            for (; __j != __e && __pred(*__j); ++__j)\n                ;\n            __i = erase(__i, __j);\n            if (__i != __e)\n                ++__i;\n        }\n        else\n            ++__i;\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nlist<_Tp, _Alloc>::unique()\n{\n    unique(__equal_to<value_type>());\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _BinaryPred>\nvoid\nlist<_Tp, _Alloc>::unique(_BinaryPred __binary_pred)\n{\n    for (iterator __i = begin(), __e = end(); __i != __e;)\n    {\n        iterator __j = _VSTD::next(__i);\n        for (; __j != __e && __binary_pred(*__i, *__j); ++__j)\n            ;\n        if (++__i != __j)\n            __i = erase(__i, __j);\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nlist<_Tp, _Alloc>::merge(list& __c)\n{\n    merge(__c, __less<value_type>());\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _Comp>\nvoid\nlist<_Tp, _Alloc>::merge(list& __c, _Comp __comp)\n{\n    if (this != &__c)\n    {\n        iterator __f1 = begin();\n        iterator __e1 = end();\n        iterator __f2 = __c.begin();\n        iterator __e2 = __c.end();\n        while (__f1 != __e1 && __f2 != __e2)\n        {\n            if (__comp(*__f2, *__f1))\n            {\n                size_type __ds = 1;\n                iterator __m2 = _VSTD::next(__f2);\n                for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2, ++__ds)\n                    ;\n                base::__sz() += __ds;\n                __c.__sz() -= __ds;\n                __node_pointer __f = __f2.__ptr_;\n                __node_pointer __l = __m2.__ptr_->__prev_;\n                __f2 = __m2;\n                base::__unlink_nodes(__f, __l);\n                __m2 = _VSTD::next(__f1);\n                __link_nodes(__f1.__ptr_, __f, __l);\n                __f1 = __m2;\n            }\n            else\n                ++__f1;\n        }\n        splice(__e1, __c);\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __libcpp_db* __db = __get_db();\n        __c_node* __cn1 = __db->__find_c_and_lock(this);\n        __c_node* __cn2 = __db->__find_c(&__c);\n        for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;)\n        {\n            --__p;\n            iterator* __i = static_cast<iterator*>((*__p)->__i_);\n            if (__i->__ptr_ != static_cast<__node_pointer>(\n                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))\n            {\n                __cn1->__add(*__p);\n                (*__p)->__c_ = __cn1;\n                if (--__cn2->end_ != __p)\n                    memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*));\n            }\n        }\n        __db->unlock();\n#endif\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nlist<_Tp, _Alloc>::sort()\n{\n    sort(__less<value_type>());\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _Comp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nlist<_Tp, _Alloc>::sort(_Comp __comp)\n{\n    __sort(begin(), end(), base::__sz(), __comp);\n}\n\ntemplate <class _Tp, class _Alloc>\ntemplate <class _Comp>\ntypename list<_Tp, _Alloc>::iterator\nlist<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp)\n{\n    switch (__n)\n    {\n    case 0:\n    case 1:\n        return __f1;\n    case 2:\n        if (__comp(*--__e2, *__f1))\n        {\n            __node_pointer __f = __e2.__ptr_;\n            base::__unlink_nodes(__f, __f);\n            __link_nodes(__f1.__ptr_, __f, __f);\n            return __e2;\n        }\n        return __f1;\n    }\n    size_type __n2 = __n / 2;\n    iterator __e1 = _VSTD::next(__f1, __n2);\n    iterator  __r = __f1 = __sort(__f1, __e1, __n2, __comp);\n    iterator __f2 = __e1 = __sort(__e1, __e2, __n - __n2, __comp);\n    if (__comp(*__f2, *__f1))\n    {\n        iterator __m2 = _VSTD::next(__f2);\n        for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)\n            ;\n        __node_pointer __f = __f2.__ptr_;\n        __node_pointer __l = __m2.__ptr_->__prev_;\n        __r = __f2;\n        __e1 = __f2 = __m2;\n        base::__unlink_nodes(__f, __l);\n        __m2 = _VSTD::next(__f1);\n        __link_nodes(__f1.__ptr_, __f, __l);\n        __f1 = __m2;\n    }\n    else\n        ++__f1;\n    while (__f1 != __e1 && __f2 != __e2)\n    {\n        if (__comp(*__f2, *__f1))\n        {\n            iterator __m2 = _VSTD::next(__f2);\n            for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)\n                ;\n            __node_pointer __f = __f2.__ptr_;\n            __node_pointer __l = __m2.__ptr_->__prev_;\n            if (__e1 == __f2)\n                __e1 = __m2;\n            __f2 = __m2;\n            base::__unlink_nodes(__f, __l);\n            __m2 = _VSTD::next(__f1);\n            __link_nodes(__f1.__ptr_, __f, __l);\n            __f1 = __m2;\n        }\n        else\n            ++__f1;\n    }\n    return __r;\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\nlist<_Tp, _Alloc>::reverse() _NOEXCEPT\n{\n    if (base::__sz() > 1)\n    {\n        iterator __e = end();\n        for (iterator __i = begin(); __i.__ptr_ != __e.__ptr_;)\n        {\n            _VSTD::swap(__i.__ptr_->__prev_, __i.__ptr_->__next_);\n            __i.__ptr_ = __i.__ptr_->__prev_;\n        }\n        _VSTD::swap(__e.__ptr_->__prev_, __e.__ptr_->__next_);\n    }\n}\n\ntemplate <class _Tp, class _Alloc>\nbool\nlist<_Tp, _Alloc>::__invariants() const\n{\n    return size() == _VSTD::distance(begin(), end());\n}\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\ntemplate <class _Tp, class _Alloc>\nbool\nlist<_Tp, _Alloc>::__dereferenceable(const const_iterator* __i) const\n{\n    return __i->__ptr_ != static_cast<__node_pointer>(\n                       pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(this->__end_)));\n}\n\ntemplate <class _Tp, class _Alloc>\nbool\nlist<_Tp, _Alloc>::__decrementable(const const_iterator* __i) const\n{\n    return !empty() &&  __i->__ptr_ != base::__end_.__next_;\n}\n\ntemplate <class _Tp, class _Alloc>\nbool\nlist<_Tp, _Alloc>::__addable(const const_iterator* __i, ptrdiff_t __n) const\n{\n    return false;\n}\n\ntemplate <class _Tp, class _Alloc>\nbool\nlist<_Tp, _Alloc>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const\n{\n    return false;\n}\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)\n{\n    return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)\n{\n    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator> (const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_LIST\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/locale",
    "content": "// -*- C++ -*-\n//===-------------------------- locale ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_LOCALE\n#define _LIBCPP_LOCALE\n\n/*\n    locale synopsis\n\nnamespace std\n{\n\nclass locale\n{\npublic:\n    // types:\n    class facet;\n    class id;\n\n    typedef int category;\n    static const category // values assigned here are for exposition only\n        none     = 0x000,\n        collate  = 0x010,\n        ctype    = 0x020,\n        monetary = 0x040,\n        numeric  = 0x080,\n        time     = 0x100,\n        messages = 0x200,\n        all = collate | ctype | monetary | numeric | time | messages;\n\n    // construct/copy/destroy:\n    locale() noexcept;\n    locale(const locale& other) noexcept;\n    explicit locale(const char* std_name);\n    explicit locale(const string& std_name);\n    locale(const locale& other, const char* std_name, category);\n    locale(const locale& other, const string& std_name, category);\n    template <class Facet> locale(const locale& other, Facet* f);\n    locale(const locale& other, const locale& one, category);\n\n    ~locale(); // not virtual\n\n    const locale& operator=(const locale& other) noexcept;\n\n    template <class Facet> locale combine(const locale& other) const;\n\n    // locale operations:\n    basic_string<char> name() const;\n    bool operator==(const locale& other) const;\n    bool operator!=(const locale& other) const;\n    template <class charT, class Traits, class Allocator>\n      bool operator()(const basic_string<charT,Traits,Allocator>& s1,\n                      const basic_string<charT,Traits,Allocator>& s2) const;\n\n    // global locale objects:\n    static locale global(const locale&);\n    static const locale& classic();\n};\n\ntemplate <class Facet> const Facet& use_facet(const locale&);\ntemplate <class Facet> bool has_facet(const locale&) noexcept;\n\n// 22.3.3, convenience interfaces:\ntemplate <class charT> bool isspace (charT c, const locale& loc);\ntemplate <class charT> bool isprint (charT c, const locale& loc);\ntemplate <class charT> bool iscntrl (charT c, const locale& loc);\ntemplate <class charT> bool isupper (charT c, const locale& loc);\ntemplate <class charT> bool islower (charT c, const locale& loc);\ntemplate <class charT> bool isalpha (charT c, const locale& loc);\ntemplate <class charT> bool isdigit (charT c, const locale& loc);\ntemplate <class charT> bool ispunct (charT c, const locale& loc);\ntemplate <class charT> bool isxdigit(charT c, const locale& loc);\ntemplate <class charT> bool isalnum (charT c, const locale& loc);\ntemplate <class charT> bool isgraph (charT c, const locale& loc);\ntemplate <class charT> charT toupper(charT c, const locale& loc);\ntemplate <class charT> charT tolower(charT c, const locale& loc);\n\ntemplate<class Codecvt, class Elem = wchar_t,\n         class Wide_alloc = allocator<Elem>,\n         class Byte_alloc = allocator<char>>\nclass wstring_convert\n{\npublic:\n    typedef basic_string<char, char_traits<char>, Byte_alloc> byte_string;\n    typedef basic_string<Elem, char_traits<Elem>, Wide_alloc> wide_string;\n    typedef typename Codecvt::state_type                      state_type;\n    typedef typename wide_string::traits_type::int_type       int_type;\n\n    explicit wstring_convert(Codecvt* pcvt = new Codecvt);          // explicit in C++14\n    wstring_convert(Codecvt* pcvt, state_type state);\n    explicit wstring_convert(const byte_string& byte_err,           // explicit in C++14\n                    const wide_string& wide_err = wide_string());\n    wstring_convert(const wstring_convert&) = delete;               // C++14\n    wstring_convert & operator=(const wstring_convert &) = delete;  // C++14\n    ~wstring_convert();\n\n    wide_string from_bytes(char byte);\n    wide_string from_bytes(const char* ptr);\n    wide_string from_bytes(const byte_string& str);\n    wide_string from_bytes(const char* first, const char* last);\n\n    byte_string to_bytes(Elem wchar);\n    byte_string to_bytes(const Elem* wptr);\n    byte_string to_bytes(const wide_string& wstr);\n    byte_string to_bytes(const Elem* first, const Elem* last);\n\n    size_t converted() const; // noexcept in C++14\n    state_type state() const;\n};\n\ntemplate <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>>\nclass wbuffer_convert\n    : public basic_streambuf<Elem, Tr>\n{\npublic:\n    typedef typename Tr::state_type state_type;\n\n    explicit wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,\n                    state_type state = state_type());       // explicit in C++14\n    wbuffer_convert(const wbuffer_convert&) = delete;               // C++14\n    wbuffer_convert & operator=(const wbuffer_convert &) = delete;  // C++14\n    ~wbuffer_convert();                                             // C++14\n    \n    streambuf* rdbuf() const;\n    streambuf* rdbuf(streambuf* bytebuf);\n\n    state_type state() const;\n};\n\n// 22.4.1 and 22.4.1.3, ctype:\nclass ctype_base;\ntemplate <class charT> class ctype;\ntemplate <> class ctype<char>; // specialization\ntemplate <class charT> class ctype_byname;\ntemplate <> class ctype_byname<char>; // specialization\n\nclass codecvt_base;\ntemplate <class internT, class externT, class stateT> class codecvt;\ntemplate <class internT, class externT, class stateT> class codecvt_byname;\n\n// 22.4.2 and 22.4.3, numeric:\ntemplate <class charT, class InputIterator> class num_get;\ntemplate <class charT, class OutputIterator> class num_put;\ntemplate <class charT> class numpunct;\ntemplate <class charT> class numpunct_byname;\n\n// 22.4.4, col lation:\ntemplate <class charT> class collate;\ntemplate <class charT> class collate_byname;\n\n// 22.4.5, date and time:\nclass time_base;\ntemplate <class charT, class InputIterator> class time_get;\ntemplate <class charT, class InputIterator> class time_get_byname;\ntemplate <class charT, class OutputIterator> class time_put;\ntemplate <class charT, class OutputIterator> class time_put_byname;\n\n// 22.4.6, money:\nclass money_base;\ntemplate <class charT, class InputIterator> class money_get;\ntemplate <class charT, class OutputIterator> class money_put;\ntemplate <class charT, bool Intl> class moneypunct;\ntemplate <class charT, bool Intl> class moneypunct_byname;\n\n// 22.4.7, message retrieval:\nclass messages_base;\ntemplate <class charT> class messages;\ntemplate <class charT> class messages_byname;\n\n}  // std\n\n*/\n\n#include <__config>\n#include <__locale>\n#include <algorithm>\n#include <memory>\n#include <ios>\n#include <streambuf>\n#include <iterator>\n#include <limits>\n#ifndef __APPLE__\n#include <cstdarg>\n#endif\n#include <cstdlib>\n#include <ctime>\n#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)\n#include <support/win32/locale_win32.h>\n#elif defined(_NEWLIB_VERSION)\n// FIXME: replace all the uses of _NEWLIB_VERSION with __NEWLIB__ preceded by an\n// include of <sys/cdefs.h> once https://sourceware.org/ml/newlib-cvs/2014-q3/msg00038.html\n// has had a chance to bake for a bit\n#include <support/newlib/xlocale.h>\n#endif\n#ifdef _LIBCPP_HAS_CATOPEN\n#include <nl_types.h>\n#endif\n\n#ifdef __APPLE__\n#include <Availability.h>\n#endif\n\n#include <__undef_min_max>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n#if defined(__APPLE__) || defined(__FreeBSD__)\n#  define _LIBCPP_GET_C_LOCALE 0\n#elif defined(__CloudABI__) || defined(__NetBSD__)\n#  define _LIBCPP_GET_C_LOCALE LC_C_LOCALE\n#else\n#  define _LIBCPP_GET_C_LOCALE __cloc()\n   // Get the C locale object\n   _LIBCPP_FUNC_VIS locale_t __cloc();\n#define __cloc_defined\n#endif\n\ntypedef _VSTD::remove_pointer<locale_t>::type __locale_struct;\ntypedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr;\n#ifndef _LIBCPP_LOCALE__L_EXTENSIONS\ntypedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;\n#endif\n\n// OSX has nice foo_l() functions that let you turn off use of the global\n// locale.  Linux, not so much.  The following functions avoid the locale when\n// that's possible and otherwise do the wrong thing.  FIXME.\n#if defined(__linux__) || defined(__EMSCRIPTEN__) || defined(_AIX) || \\\n    defined(_NEWLIB_VERSION) || defined(__GLIBC__)\n\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\ndecltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))\ninline _LIBCPP_INLINE_VISIBILITY\n__mb_cur_max_l(locale_t __l)\n{\n  return MB_CUR_MAX_L(__l);\n}\n#else  // _LIBCPP_LOCALE__L_EXTENSIONS\ninline _LIBCPP_ALWAYS_INLINE\ndecltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l)\n{\n  __locale_raii __current(uselocale(__l), uselocale);\n  return MB_CUR_MAX;\n}\n#endif // _LIBCPP_LOCALE__L_EXTENSIONS\n\ninline _LIBCPP_ALWAYS_INLINE\nwint_t __btowc_l(int __c, locale_t __l)\n{\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n  return btowc_l(__c, __l);\n#else\n  __locale_raii __current(uselocale(__l), uselocale);\n  return btowc(__c);\n#endif\n}\n\ninline _LIBCPP_ALWAYS_INLINE\nint __wctob_l(wint_t __c, locale_t __l)\n{\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n  return wctob_l(__c, __l);\n#else\n  __locale_raii __current(uselocale(__l), uselocale);\n  return wctob(__c);\n#endif\n}\n\ninline _LIBCPP_ALWAYS_INLINE\nsize_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,\n                      size_t __len, mbstate_t *__ps, locale_t __l)\n{\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n  return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l);\n#else\n  __locale_raii __current(uselocale(__l), uselocale);\n  return wcsnrtombs(__dest, __src, __nwc, __len, __ps);\n#endif\n}\n\ninline _LIBCPP_ALWAYS_INLINE\nsize_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l)\n{\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n  return wcrtomb_l(__s, __wc, __ps, __l);\n#else\n  __locale_raii __current(uselocale(__l), uselocale);\n  return wcrtomb(__s, __wc, __ps);\n#endif\n}\n\ninline _LIBCPP_ALWAYS_INLINE\nsize_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,\n                      size_t __len, mbstate_t *__ps, locale_t __l)\n{\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n  return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l);\n#else\n  __locale_raii __current(uselocale(__l), uselocale);\n  return mbsnrtowcs(__dest, __src, __nms, __len, __ps);\n#endif\n}\n\ninline _LIBCPP_ALWAYS_INLINE\nsize_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,\n                   mbstate_t *__ps, locale_t __l)\n{\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n  return mbrtowc_l(__pwc, __s, __n, __ps, __l);\n#else\n  __locale_raii __current(uselocale(__l), uselocale);\n  return mbrtowc(__pwc, __s, __n, __ps);\n#endif\n}\n\ninline _LIBCPP_ALWAYS_INLINE\nint __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l)\n{\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n  return mbtowc_l(__pwc, __pmb, __max, __l);\n#else\n  __locale_raii __current(uselocale(__l), uselocale);\n  return mbtowc(__pwc, __pmb, __max);\n#endif\n}\n\ninline _LIBCPP_ALWAYS_INLINE\nsize_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l)\n{\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n  return mbrlen_l(__s, __n, __ps, __l);\n#else\n  __locale_raii __current(uselocale(__l), uselocale);\n  return mbrlen(__s, __n, __ps);\n#endif\n}\n\ninline _LIBCPP_ALWAYS_INLINE\nlconv *__localeconv_l(locale_t __l)\n{\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n  return localeconv_l(__l);\n#else\n  __locale_raii __current(uselocale(__l), uselocale);\n  return localeconv();\n#endif\n}\n\ninline _LIBCPP_ALWAYS_INLINE\nsize_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,\n                     mbstate_t *__ps, locale_t __l)\n{\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n  return mbsrtowcs_l(__dest, __src, __len, __ps, __l);\n#else\n  __locale_raii __current(uselocale(__l), uselocale);\n  return mbsrtowcs(__dest, __src, __len, __ps);\n#endif\n}\n\ninline\nint __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) {\n  va_list __va;\n  va_start(__va, __format);\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n  int __res = vsnprintf_l(__s, __n, __l, __format, __va);\n#else\n  __locale_raii __current(uselocale(__l), uselocale);\n  int __res = vsnprintf(__s, __n, __format, __va);\n#endif\n  va_end(__va);\n  return __res;\n}\n\ninline\nint __asprintf_l(char **__s, locale_t __l, const char *__format, ...) {\n  va_list __va;\n  va_start(__va, __format);\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n  int __res = vasprintf_l(__s, __l, __format, __va);\n#else\n  __locale_raii __current(uselocale(__l), uselocale);\n  int __res = vasprintf(__s, __format, __va);\n#endif\n  va_end(__va);\n  return __res;\n}\n\ninline\nint __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {\n  va_list __va;\n  va_start(__va, __format);\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n  int __res = vsscanf_l(__s, __l, __format, __va);\n#else\n  __locale_raii __current(uselocale(__l), uselocale);\n  int __res = vsscanf(__s, __format, __va);\n#endif\n  va_end(__va);\n  return __res;\n}\n\n#endif  // __linux__\n\n// __scan_keyword\n// Scans [__b, __e) until a match is found in the basic_strings range\n//  [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).\n//  __b will be incremented (visibly), consuming CharT until a match is found\n//  or proved to not exist.  A keyword may be \"\", in which will match anything.\n//  If one keyword is a prefix of another, and the next CharT in the input\n//  might match another keyword, the algorithm will attempt to find the longest\n//  matching keyword.  If the longer matching keyword ends up not matching, then\n//  no keyword match is found.  If no keyword match is found, __ke is returned\n//  and failbit is set in __err.\n//  Else an iterator pointing to the matching keyword is found.  If more than\n//  one keyword matches, an iterator to the first matching keyword is returned.\n//  If on exit __b == __e, eofbit is set in __err.  If __case_sensitive is false,\n//  __ct is used to force to lower case before comparing characters.\n//  Examples:\n//  Keywords:  \"a\", \"abb\"\n//  If the input is \"a\", the first keyword matches and eofbit is set.\n//  If the input is \"abc\", no match is found and \"ab\" are consumed.\ntemplate <class _InputIterator, class _ForwardIterator, class _Ctype>\n_LIBCPP_HIDDEN\n_ForwardIterator\n__scan_keyword(_InputIterator& __b, _InputIterator __e,\n               _ForwardIterator __kb, _ForwardIterator __ke,\n               const _Ctype& __ct, ios_base::iostate& __err,\n               bool __case_sensitive = true)\n{\n    typedef typename iterator_traits<_InputIterator>::value_type _CharT;\n    size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke));\n    const unsigned char __doesnt_match = '\\0';\n    const unsigned char __might_match = '\\1';\n    const unsigned char __does_match = '\\2';\n    unsigned char __statbuf[100];\n    unsigned char* __status = __statbuf;\n    unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free);\n    if (__nkw > sizeof(__statbuf))\n    {\n        __status = (unsigned char*)malloc(__nkw);\n        if (__status == 0)\n            __throw_bad_alloc();\n        __stat_hold.reset(__status);\n    }\n    size_t __n_might_match = __nkw;  // At this point, any keyword might match\n    size_t __n_does_match = 0;       // but none of them definitely do\n    // Initialize all statuses to __might_match, except for \"\" keywords are __does_match\n    unsigned char* __st = __status;\n    for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)\n    {\n        if (!__ky->empty())\n            *__st = __might_match;\n        else\n        {\n            *__st = __does_match;\n            --__n_might_match;\n            ++__n_does_match;\n        }\n    }\n    // While there might be a match, test keywords against the next CharT\n    for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx)\n    {\n        // Peek at the next CharT but don't consume it\n        _CharT __c = *__b;\n        if (!__case_sensitive)\n            __c = __ct.toupper(__c);\n        bool __consume = false;\n        // For each keyword which might match, see if the __indx character is __c\n        // If a match if found, consume __c\n        // If a match is found, and that is the last character in the keyword,\n        //    then that keyword matches.\n        // If the keyword doesn't match this character, then change the keyword\n        //    to doesn't match\n        __st = __status;\n        for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)\n        {\n            if (*__st == __might_match)\n            {\n                _CharT __kc = (*__ky)[__indx];\n                if (!__case_sensitive)\n                    __kc = __ct.toupper(__kc);\n                if (__c == __kc)\n                {\n                    __consume = true;\n                    if (__ky->size() == __indx+1)\n                    {\n                        *__st = __does_match;\n                        --__n_might_match;\n                        ++__n_does_match;\n                    }\n                }\n                else\n                {\n                    *__st = __doesnt_match;\n                    --__n_might_match;\n                }\n            }\n        }\n        // consume if we matched a character\n        if (__consume)\n        {\n            ++__b;\n            // If we consumed a character and there might be a matched keyword that\n            //   was marked matched on a previous iteration, then such keywords\n            //   which are now marked as not matching.\n            if (__n_might_match + __n_does_match > 1)\n            {\n                __st = __status;\n                for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)\n                {\n                    if (*__st == __does_match && __ky->size() != __indx+1)\n                    {\n                        *__st = __doesnt_match;\n                        --__n_does_match;\n                    }\n                }\n            }\n        }\n    }\n    // We've exited the loop because we hit eof and/or we have no more \"might matches\".\n    if (__b == __e)\n        __err |= ios_base::eofbit;\n    // Return the first matching result\n    for (__st = __status; __kb != __ke; ++__kb, (void) ++__st)\n        if (*__st == __does_match)\n            break;\n    if (__kb == __ke)\n        __err |= ios_base::failbit;\n    return __kb;\n}\n\nstruct _LIBCPP_TYPE_VIS __num_get_base\n{\n    static const int __num_get_buf_sz = 40;\n\n    static int __get_base(ios_base&);\n    static const char __src[33];\n};\n\n_LIBCPP_FUNC_VIS\nvoid __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,\n                      ios_base::iostate& __err);\n\ntemplate <class _CharT>\nstruct __num_get\n    : protected __num_get_base\n{\n    static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);\n    static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,\n                                      _CharT& __thousands_sep);\n    static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,\n                  unsigned& __dc, _CharT __thousands_sep, const string& __grouping,\n                  unsigned* __g, unsigned*& __g_end, _CharT* __atoms);\n    static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp,\n                                   char* __a, char*& __a_end,\n                                   _CharT __decimal_point, _CharT __thousands_sep,\n                                   const string& __grouping, unsigned* __g,\n                                   unsigned*& __g_end, unsigned& __dc, _CharT* __atoms);\n};\n\ntemplate <class _CharT>\nstring\n__num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)\n{\n    locale __loc = __iob.getloc();\n    use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms);\n    const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);\n    __thousands_sep = __np.thousands_sep();\n    return __np.grouping();\n}\n\ntemplate <class _CharT>\nstring\n__num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,\n                    _CharT& __thousands_sep)\n{\n    locale __loc = __iob.getloc();\n    use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms);\n    const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);\n    __decimal_point = __np.decimal_point();\n    __thousands_sep = __np.thousands_sep();\n    return __np.grouping();\n}\n\ntemplate <class _CharT>\nint\n__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,\n                  unsigned& __dc, _CharT __thousands_sep, const string& __grouping,\n                  unsigned* __g, unsigned*& __g_end, _CharT* __atoms)\n{\n    if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25]))\n    {\n        *__a_end++ = __ct == __atoms[24] ? '+' : '-';\n        __dc = 0;\n        return 0;\n    }\n    if (__grouping.size() != 0 && __ct == __thousands_sep)\n    {\n        if (__g_end-__g < __num_get_buf_sz)\n        {\n            *__g_end++ = __dc;\n            __dc = 0;\n        }\n        return 0;\n    }\n    ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms;\n    if (__f >= 24)\n        return -1;\n    switch (__base)\n    {\n    case 8:\n    case 10:\n        if (__f >= __base)\n            return -1;\n        break;\n    case 16:\n        if (__f < 22)\n            break;\n        if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0')\n        {\n            __dc = 0;\n            *__a_end++ = __src[__f];\n            return 0;\n        }\n        return -1;\n    }\n    *__a_end++ = __src[__f];\n    ++__dc;\n    return 0;\n}\n\ntemplate <class _CharT>\nint\n__num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end,\n                    _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping,\n                    unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms)\n{\n    if (__ct == __decimal_point)\n    {\n        if (!__in_units)\n            return -1;\n        __in_units = false;\n        *__a_end++ = '.';\n        if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)\n            *__g_end++ = __dc;\n        return 0;\n    }\n    if (__ct == __thousands_sep && __grouping.size() != 0)\n    {\n        if (!__in_units)\n            return -1;\n        if (__g_end-__g < __num_get_buf_sz)\n        {\n            *__g_end++ = __dc;\n            __dc = 0;\n        }\n        return 0;\n    }\n    ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms;\n    if (__f >= 32)\n        return -1;\n    char __x = __src[__f];\n    if (__x == '-' || __x == '+')\n    {\n        if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F))\n        {\n            *__a_end++ = __x;\n            return 0;\n        }\n        return -1;\n    }\n    if (__x == 'x' || __x == 'X')\n        __exp = 'P';\n    else if ((__x & 0x5F) == __exp)\n    {\n        __exp |= 0x80;\n        if (__in_units)\n        {\n            __in_units = false;\n            if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)\n                *__g_end++ = __dc;\n        }\n    }\n    *__a_end++ = __x;\n    if (__f >= 22)\n        return 0;\n    ++__dc;\n    return 0;\n}\n\n_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<char>)\n_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<wchar_t>)\n\ntemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >\nclass _LIBCPP_TYPE_VIS_ONLY num_get\n    : public locale::facet,\n      private __num_get<_CharT>\n{\npublic:\n    typedef _CharT char_type;\n    typedef _InputIterator iter_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit num_get(size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,\n                  ios_base::iostate& __err, bool& __v) const\n    {\n        return do_get(__b, __e, __iob, __err, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,\n                  ios_base::iostate& __err, long& __v) const\n    {\n        return do_get(__b, __e, __iob, __err, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,\n                  ios_base::iostate& __err, long long& __v) const\n    {\n        return do_get(__b, __e, __iob, __err, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,\n                  ios_base::iostate& __err, unsigned short& __v) const\n    {\n        return do_get(__b, __e, __iob, __err, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,\n                  ios_base::iostate& __err, unsigned int& __v) const\n    {\n        return do_get(__b, __e, __iob, __err, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,\n                  ios_base::iostate& __err, unsigned long& __v) const\n    {\n        return do_get(__b, __e, __iob, __err, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,\n                  ios_base::iostate& __err, unsigned long long& __v) const\n    {\n        return do_get(__b, __e, __iob, __err, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,\n                  ios_base::iostate& __err, float& __v) const\n    {\n        return do_get(__b, __e, __iob, __err, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,\n                  ios_base::iostate& __err, double& __v) const\n    {\n        return do_get(__b, __e, __iob, __err, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,\n                  ios_base::iostate& __err, long double& __v) const\n    {\n        return do_get(__b, __e, __iob, __err, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,\n                  ios_base::iostate& __err, void*& __v) const\n    {\n        return do_get(__b, __e, __iob, __err, __v);\n    }\n\n    static locale::id id;\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    ~num_get() {}\n\n    template <class _Fp>\n    iter_type __do_get_floating_point\n                            (iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, _Fp& __v) const;\n\n    template <class _Signed>\n    iter_type __do_get_signed\n                            (iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, _Signed& __v) const;\n\n    template <class _Unsigned>\n    iter_type __do_get_unsigned\n                            (iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, _Unsigned& __v) const;\n\n\n    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, bool& __v) const;\n\n    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, long& __v) const\n    { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }\n\n    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, long long& __v) const\n    { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }\n\n    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, unsigned short& __v) const\n    { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }\n\n    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, unsigned int& __v) const\n    { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }\n\n    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, unsigned long& __v) const\n    { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }\n\n    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, unsigned long long& __v) const\n    { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }\n\n    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, float& __v) const\n    { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }\n\n    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, double& __v) const\n    { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }\n\n    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, long double& __v) const\n    { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }\n\n    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, void*& __v) const;\n};\n\ntemplate <class _CharT, class _InputIterator>\nlocale::id\nnum_get<_CharT, _InputIterator>::id;\n\ntemplate <class _Tp>\n_Tp\n__num_get_signed_integral(const char* __a, const char* __a_end,\n                          ios_base::iostate& __err, int __base)\n{\n    if (__a != __a_end)\n    {\n        typename remove_reference<decltype(errno)>::type __save_errno = errno;\n        errno = 0;\n        char *__p2;\n        long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);\n        typename remove_reference<decltype(errno)>::type __current_errno = errno;\n        if (__current_errno == 0)\n            errno = __save_errno;\n        if (__p2 != __a_end)\n        {\n            __err = ios_base::failbit;\n            return 0;\n        }\n        else if (__current_errno == ERANGE         ||\n                 __ll < numeric_limits<_Tp>::min() ||\n                 numeric_limits<_Tp>::max() < __ll)\n        {\n            __err = ios_base::failbit;\n            if (__ll > 0)\n                return numeric_limits<_Tp>::max();\n            else\n                return numeric_limits<_Tp>::min();\n        }\n        return static_cast<_Tp>(__ll);\n    }\n    __err = ios_base::failbit;\n    return 0;\n}\n\ntemplate <class _Tp>\n_Tp\n__num_get_unsigned_integral(const char* __a, const char* __a_end,\n                            ios_base::iostate& __err, int __base)\n{\n    if (__a != __a_end)\n    {\n        if (*__a == '-')\n        {\n            __err = ios_base::failbit;\n            return 0;\n        }\n        typename remove_reference<decltype(errno)>::type __save_errno = errno;\n        errno = 0;\n        char *__p2;\n        unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);\n        typename remove_reference<decltype(errno)>::type __current_errno = errno;\n        if (__current_errno == 0)\n            errno = __save_errno;\n        if (__p2 != __a_end)\n        {\n            __err = ios_base::failbit;\n            return 0;\n        }\n        else if (__current_errno == ERANGE ||\n                 numeric_limits<_Tp>::max() < __ll)\n        {\n            __err = ios_base::failbit;\n            return numeric_limits<_Tp>::max();\n        }\n        return static_cast<_Tp>(__ll);\n    }\n    __err = ios_base::failbit;\n    return 0;\n}\n\ntemplate <class _Tp>\n_Tp\n__num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err)\n{\n    if (__a != __a_end)\n    {\n        typename remove_reference<decltype(errno)>::type __save_errno = errno;\n        errno = 0;\n        char *__p2;\n        long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE);\n        typename remove_reference<decltype(errno)>::type __current_errno = errno;\n        if (__current_errno == 0)\n            errno = __save_errno;\n        if (__p2 != __a_end)\n        {\n            __err = ios_base::failbit;\n            return 0;\n        }\n        else if (__current_errno == ERANGE)\n            __err = ios_base::failbit;\n        return static_cast<_Tp>(__ld);\n    }\n    __err = ios_base::failbit;\n    return 0;\n}\n\ntemplate <class _CharT, class _InputIterator>\n_InputIterator\nnum_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,\n                                        ios_base& __iob,\n                                        ios_base::iostate& __err,\n                                        bool& __v) const\n{\n    if ((__iob.flags() & ios_base::boolalpha) == 0)\n    {\n        long __lv = -1;\n        __b = do_get(__b, __e, __iob, __err, __lv);\n        switch (__lv)\n        {\n        case 0:\n            __v = false;\n            break;\n        case 1:\n            __v = true;\n            break;\n        default:\n            __v = true;\n            __err = ios_base::failbit;\n            break;\n        }\n        return __b;\n    }\n    const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc());\n    const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc());\n    typedef typename numpunct<_CharT>::string_type string_type;\n    const string_type __names[2] = {__np.truename(), __np.falsename()};\n    const string_type* __i = __scan_keyword(__b, __e, __names, __names+2,\n                                            __ct, __err);\n    __v = __i == __names;\n    return __b;\n}\n\n// signed\n\ntemplate <class _CharT, class _InputIterator>\ntemplate <class _Signed>\n_InputIterator\nnum_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e,\n                                        ios_base& __iob,\n                                        ios_base::iostate& __err,\n                                        _Signed& __v) const\n{\n    // Stage 1\n    int __base = this->__get_base(__iob);\n    // Stage 2\n    char_type __atoms[26];\n    char_type __thousands_sep;\n    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);\n    string __buf;\n    __buf.resize(__buf.capacity());\n    char* __a = &__buf[0];\n    char* __a_end = __a;\n    unsigned __g[__num_get_base::__num_get_buf_sz];\n    unsigned* __g_end = __g;\n    unsigned __dc = 0;\n    for (; __b != __e; ++__b)\n    {\n        if (__a_end == __a + __buf.size())\n        {\n            size_t __tmp = __buf.size();\n            __buf.resize(2*__buf.size());\n            __buf.resize(__buf.capacity());\n            __a = &__buf[0];\n            __a_end = __a + __tmp;\n        }\n        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,\n                                    __thousands_sep, __grouping, __g, __g_end,\n                                    __atoms))\n            break;\n    }\n    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)\n        *__g_end++ = __dc;\n    // Stage 3\n    __v = __num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);\n    // Digit grouping checked\n    __check_grouping(__grouping, __g, __g_end, __err);\n    // EOF checked\n    if (__b == __e)\n        __err |= ios_base::eofbit;\n    return __b;\n}\n\n// unsigned\n\ntemplate <class _CharT, class _InputIterator>\ntemplate <class _Unsigned>\n_InputIterator\nnum_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e,\n                                        ios_base& __iob,\n                                        ios_base::iostate& __err,\n                                        _Unsigned& __v) const\n{\n    // Stage 1\n    int __base = this->__get_base(__iob);\n    // Stage 2\n    char_type __atoms[26];\n    char_type __thousands_sep;\n    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);\n    string __buf;\n    __buf.resize(__buf.capacity());\n    char* __a = &__buf[0];\n    char* __a_end = __a;\n    unsigned __g[__num_get_base::__num_get_buf_sz];\n    unsigned* __g_end = __g;\n    unsigned __dc = 0;\n    for (; __b != __e; ++__b)\n    {\n        if (__a_end == __a + __buf.size())\n        {\n            size_t __tmp = __buf.size();\n            __buf.resize(2*__buf.size());\n            __buf.resize(__buf.capacity());\n            __a = &__buf[0];\n            __a_end = __a + __tmp;\n        }\n        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,\n                                    __thousands_sep, __grouping, __g, __g_end,\n                                    __atoms))\n            break;\n    }\n    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)\n        *__g_end++ = __dc;\n    // Stage 3\n    __v = __num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);\n    // Digit grouping checked\n    __check_grouping(__grouping, __g, __g_end, __err);\n    // EOF checked\n    if (__b == __e)\n        __err |= ios_base::eofbit;\n    return __b;\n}\n\n// floating point\n\ntemplate <class _CharT, class _InputIterator>\ntemplate <class _Fp>\n_InputIterator\nnum_get<_CharT, _InputIterator>::__do_get_floating_point(iter_type __b, iter_type __e,\n                                        ios_base& __iob,\n                                        ios_base::iostate& __err,\n                                        _Fp& __v) const\n{\n    // Stage 1, nothing to do\n    // Stage 2\n    char_type __atoms[32];\n    char_type __decimal_point;\n    char_type __thousands_sep;\n    string __grouping = this->__stage2_float_prep(__iob, __atoms,\n                                                  __decimal_point,\n                                                  __thousands_sep);\n    string __buf;\n    __buf.resize(__buf.capacity());\n    char* __a = &__buf[0];\n    char* __a_end = __a;\n    unsigned __g[__num_get_base::__num_get_buf_sz];\n    unsigned* __g_end = __g;\n    unsigned __dc = 0;\n    bool __in_units = true;\n    char __exp = 'E';\n    for (; __b != __e; ++__b)\n    {\n        if (__a_end == __a + __buf.size())\n        {\n            size_t __tmp = __buf.size();\n            __buf.resize(2*__buf.size());\n            __buf.resize(__buf.capacity());\n            __a = &__buf[0];\n            __a_end = __a + __tmp;\n        }\n        if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,\n                                      __decimal_point, __thousands_sep,\n                                      __grouping, __g, __g_end,\n                                      __dc, __atoms))\n            break;\n    }\n    if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)\n        *__g_end++ = __dc;\n    // Stage 3\n    __v = __num_get_float<_Fp>(__a, __a_end, __err);\n    // Digit grouping checked\n    __check_grouping(__grouping, __g, __g_end, __err);\n    // EOF checked\n    if (__b == __e)\n        __err |= ios_base::eofbit;\n    return __b;\n}\n\ntemplate <class _CharT, class _InputIterator>\n_InputIterator\nnum_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,\n                                        ios_base& __iob,\n                                        ios_base::iostate& __err,\n                                        void*& __v) const\n{\n    // Stage 1\n    int __base = 16;\n    // Stage 2\n    char_type __atoms[26];\n    char_type __thousands_sep = 0;\n    string __grouping;\n    use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,\n                                                    __num_get_base::__src + 26, __atoms);\n    string __buf;\n    __buf.resize(__buf.capacity());\n    char* __a = &__buf[0];\n    char* __a_end = __a;\n    unsigned __g[__num_get_base::__num_get_buf_sz];\n    unsigned* __g_end = __g;\n    unsigned __dc = 0;\n    for (; __b != __e; ++__b)\n    {\n        if (__a_end == __a + __buf.size())\n        {\n            size_t __tmp = __buf.size();\n            __buf.resize(2*__buf.size());\n            __buf.resize(__buf.capacity());\n            __a = &__buf[0];\n            __a_end = __a + __tmp;\n        }\n        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,\n                                    __thousands_sep, __grouping,\n                                    __g, __g_end, __atoms))\n            break;\n    }\n    // Stage 3\n    __buf.resize(__a_end - __a);\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    if (sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, \"%p\", &__v) != 1)\n#else\n    if (__sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, \"%p\", &__v) != 1)\n#endif\n        __err = ios_base::failbit;\n    // EOF checked\n    if (__b == __e)\n        __err |= ios_base::eofbit;\n    return __b;\n}\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<char>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<wchar_t>)\n\nstruct _LIBCPP_TYPE_VIS __num_put_base\n{\nprotected:\n    static void __format_int(char* __fmt, const char* __len, bool __signd,\n                             ios_base::fmtflags __flags);\n    static bool __format_float(char* __fmt, const char* __len,\n                               ios_base::fmtflags __flags);\n    static char* __identify_padding(char* __nb, char* __ne,\n                                    const ios_base& __iob);\n};\n\ntemplate <class _CharT>\nstruct __num_put\n    : protected __num_put_base\n{\n    static void __widen_and_group_int(char* __nb, char* __np, char* __ne,\n                                      _CharT* __ob, _CharT*& __op, _CharT*& __oe,\n                                      const locale& __loc);\n    static void __widen_and_group_float(char* __nb, char* __np, char* __ne,\n                                        _CharT* __ob, _CharT*& __op, _CharT*& __oe,\n                                        const locale& __loc);\n};\n\ntemplate <class _CharT>\nvoid\n__num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,\n                                         _CharT* __ob, _CharT*& __op, _CharT*& __oe,\n                                         const locale& __loc)\n{\n    const ctype<_CharT>&    __ct = use_facet<ctype<_CharT> >   (__loc);\n    const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);\n    string __grouping = __npt.grouping();\n    if (__grouping.empty())\n    {\n        __ct.widen(__nb, __ne, __ob);\n        __oe = __ob + (__ne - __nb);\n    }\n    else\n    {\n        __oe = __ob;\n        char* __nf = __nb;\n        if (*__nf == '-' || *__nf == '+')\n            *__oe++ = __ct.widen(*__nf++);\n        if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||\n                                                   __nf[1] == 'X'))\n        {\n            *__oe++ = __ct.widen(*__nf++);\n            *__oe++ = __ct.widen(*__nf++);\n        }\n        reverse(__nf, __ne);\n        _CharT __thousands_sep = __npt.thousands_sep();\n        unsigned __dc = 0;\n        unsigned __dg = 0;\n        for (char* __p = __nf; __p < __ne; ++__p)\n        {\n            if (static_cast<unsigned>(__grouping[__dg]) > 0 &&\n                __dc == static_cast<unsigned>(__grouping[__dg]))\n            {\n                *__oe++ = __thousands_sep;\n                __dc = 0;\n                if (__dg < __grouping.size()-1)\n                    ++__dg;\n            }\n            *__oe++ = __ct.widen(*__p);\n            ++__dc;\n        }\n        reverse(__ob + (__nf - __nb), __oe);\n    }\n    if (__np == __ne)\n        __op = __oe;\n    else\n        __op = __ob + (__np - __nb);\n}\n\ntemplate <class _CharT>\nvoid\n__num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,\n                                           _CharT* __ob, _CharT*& __op, _CharT*& __oe,\n                                           const locale& __loc)\n{\n    const ctype<_CharT>&    __ct = use_facet<ctype<_CharT> >   (__loc);\n    const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);\n    string __grouping = __npt.grouping();\n    __oe = __ob;\n    char* __nf = __nb;\n    if (*__nf == '-' || *__nf == '+')\n        *__oe++ = __ct.widen(*__nf++);\n    char* __ns;\n    if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||\n                                               __nf[1] == 'X'))\n    {\n        *__oe++ = __ct.widen(*__nf++);\n        *__oe++ = __ct.widen(*__nf++);\n        for (__ns = __nf; __ns < __ne; ++__ns)\n            if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))\n                break;\n    }\n    else\n    {\n        for (__ns = __nf; __ns < __ne; ++__ns)\n            if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))\n                break;\n    }\n    if (__grouping.empty())\n    {\n        __ct.widen(__nf, __ns, __oe);\n        __oe += __ns - __nf;\n    }\n    else\n    {\n        reverse(__nf, __ns);\n        _CharT __thousands_sep = __npt.thousands_sep();\n        unsigned __dc = 0;\n        unsigned __dg = 0;\n        for (char* __p = __nf; __p < __ns; ++__p)\n        {\n            if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg]))\n            {\n                *__oe++ = __thousands_sep;\n                __dc = 0;\n                if (__dg < __grouping.size()-1)\n                    ++__dg;\n            }\n            *__oe++ = __ct.widen(*__p);\n            ++__dc;\n        }\n        reverse(__ob + (__nf - __nb), __oe);\n    }\n    for (__nf = __ns; __nf < __ne; ++__nf)\n    {\n        if (*__nf == '.')\n        {\n            *__oe++ = __npt.decimal_point();\n            ++__nf;\n            break;\n        }\n        else\n            *__oe++ = __ct.widen(*__nf);\n    }\n    __ct.widen(__nf, __ne, __oe);\n    __oe += __ne - __nf;\n    if (__np == __ne)\n        __op = __oe;\n    else\n        __op = __ob + (__np - __nb);\n}\n\n_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<char>)\n_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<wchar_t>)\n\ntemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >\nclass _LIBCPP_TYPE_VIS_ONLY num_put\n    : public locale::facet,\n      private __num_put<_CharT>\n{\npublic:\n    typedef _CharT char_type;\n    typedef _OutputIterator iter_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit num_put(size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,\n                  bool __v) const\n    {\n        return do_put(__s, __iob, __fl, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,\n                  long __v) const\n    {\n        return do_put(__s, __iob, __fl, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,\n                  long long __v) const\n    {\n        return do_put(__s, __iob, __fl, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,\n                  unsigned long __v) const\n    {\n        return do_put(__s, __iob, __fl, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,\n                  unsigned long long __v) const\n    {\n        return do_put(__s, __iob, __fl, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,\n                  double __v) const\n    {\n        return do_put(__s, __iob, __fl, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,\n                  long double __v) const\n    {\n        return do_put(__s, __iob, __fl, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,\n                  const void* __v) const\n    {\n        return do_put(__s, __iob, __fl, __v);\n    }\n\n    static locale::id id;\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    ~num_put() {}\n\n    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,\n                             bool __v) const;\n    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,\n                             long __v) const;\n    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,\n                             long long __v) const;\n    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,\n                             unsigned long) const;\n    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,\n                             unsigned long long) const;\n    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,\n                             double __v) const;\n    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,\n                             long double __v) const;\n    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,\n                             const void* __v) const;\n};\n\ntemplate <class _CharT, class _OutputIterator>\nlocale::id\nnum_put<_CharT, _OutputIterator>::id;\n\ntemplate <class _CharT, class _OutputIterator>\n_LIBCPP_HIDDEN\n_OutputIterator\n__pad_and_output(_OutputIterator __s,\n                 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,\n                 ios_base& __iob, _CharT __fl)\n{\n    streamsize __sz = __oe - __ob;\n    streamsize __ns = __iob.width();\n    if (__ns > __sz)\n        __ns -= __sz;\n    else\n        __ns = 0;\n    for (;__ob < __op; ++__ob, ++__s)\n        *__s = *__ob;\n    for (; __ns; --__ns, ++__s)\n        *__s = __fl;\n    for (; __ob < __oe; ++__ob, ++__s)\n        *__s = *__ob;\n    __iob.width(0);\n    return __s;\n}\n\n#if !defined(__APPLE__) || \\\n    (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \\\n    (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)\n\ntemplate <class _CharT, class _Traits>\n_LIBCPP_HIDDEN\nostreambuf_iterator<_CharT, _Traits>\n__pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s,\n                 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,\n                 ios_base& __iob, _CharT __fl)\n{\n    if (__s.__sbuf_ == nullptr)\n        return __s;\n    streamsize __sz = __oe - __ob;\n    streamsize __ns = __iob.width();\n    if (__ns > __sz)\n        __ns -= __sz;\n    else\n        __ns = 0;\n    streamsize __np = __op - __ob;\n    if (__np > 0)\n    {\n        if (__s.__sbuf_->sputn(__ob, __np) != __np)\n        {\n            __s.__sbuf_ = nullptr;\n            return __s;\n        }\n    }\n    if (__ns > 0)\n    {\n        basic_string<_CharT, _Traits> __sp(__ns, __fl);\n        if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns)\n        {\n            __s.__sbuf_ = nullptr;\n            return __s;\n        }\n    }\n    __np = __oe - __op;\n    if (__np > 0)\n    {\n        if (__s.__sbuf_->sputn(__op, __np) != __np)\n        {\n            __s.__sbuf_ = nullptr;\n            return __s;\n        }\n    }\n    __iob.width(0);\n    return __s;\n}\n\n#endif\n\ntemplate <class _CharT, class _OutputIterator>\n_OutputIterator\nnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,\n                                         char_type __fl, bool __v) const\n{\n    if ((__iob.flags() & ios_base::boolalpha) == 0)\n        return do_put(__s, __iob, __fl, (unsigned long)__v);\n    const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());\n    typedef typename numpunct<char_type>::string_type string_type;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    string_type __tmp(__v ? __np.truename() : __np.falsename());\n    string_type __nm = _VSTD::move(__tmp);\n#else\n    string_type __nm = __v ? __np.truename() : __np.falsename();\n#endif\n    for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)\n        *__s = *__i;\n    return __s;\n}\n\ntemplate <class _CharT, class _OutputIterator>\n_OutputIterator\nnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,\n                                         char_type __fl, long __v) const\n{\n    // Stage 1 - Get number in narrow char\n    char __fmt[6] = {'%', 0};\n    const char* __len = \"l\";\n    this->__format_int(__fmt+1, __len, true, __iob.flags());\n    const unsigned __nbuf = (numeric_limits<long>::digits / 3)\n                          + ((numeric_limits<long>::digits % 3) != 0)\n                          + 1;\n    char __nar[__nbuf];\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#else\n    int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#endif\n    char* __ne = __nar + __nc;\n    char* __np = this->__identify_padding(__nar, __ne, __iob);\n    // Stage 2 - Widen __nar while adding thousands separators\n    char_type __o[2*(__nbuf-1) - 1];\n    char_type* __op;  // pad here\n    char_type* __oe;  // end of output\n    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());\n    // [__o, __oe) contains thousands_sep'd wide number\n    // Stage 3 & 4\n    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);\n}\n\ntemplate <class _CharT, class _OutputIterator>\n_OutputIterator\nnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,\n                                         char_type __fl, long long __v) const\n{\n    // Stage 1 - Get number in narrow char\n    char __fmt[8] = {'%', 0};\n    const char* __len = \"ll\";\n    this->__format_int(__fmt+1, __len, true, __iob.flags());\n    const unsigned __nbuf = (numeric_limits<long long>::digits / 3)\n                          + ((numeric_limits<long long>::digits % 3) != 0)\n                          + 2;\n    char __nar[__nbuf];\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#else\n    int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#endif\n    char* __ne = __nar + __nc;\n    char* __np = this->__identify_padding(__nar, __ne, __iob);\n    // Stage 2 - Widen __nar while adding thousands separators\n    char_type __o[2*(__nbuf-1) - 1];\n    char_type* __op;  // pad here\n    char_type* __oe;  // end of output\n    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());\n    // [__o, __oe) contains thousands_sep'd wide number\n    // Stage 3 & 4\n    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);\n}\n\ntemplate <class _CharT, class _OutputIterator>\n_OutputIterator\nnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,\n                                         char_type __fl, unsigned long __v) const\n{\n    // Stage 1 - Get number in narrow char\n    char __fmt[6] = {'%', 0};\n    const char* __len = \"l\";\n    this->__format_int(__fmt+1, __len, false, __iob.flags());\n    const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)\n                          + ((numeric_limits<unsigned long>::digits % 3) != 0)\n                          + 1;\n    char __nar[__nbuf];\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#else\n    int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#endif\n    char* __ne = __nar + __nc;\n    char* __np = this->__identify_padding(__nar, __ne, __iob);\n    // Stage 2 - Widen __nar while adding thousands separators\n    char_type __o[2*(__nbuf-1) - 1];\n    char_type* __op;  // pad here\n    char_type* __oe;  // end of output\n    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());\n    // [__o, __oe) contains thousands_sep'd wide number\n    // Stage 3 & 4\n    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);\n}\n\ntemplate <class _CharT, class _OutputIterator>\n_OutputIterator\nnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,\n                                         char_type __fl, unsigned long long __v) const\n{\n    // Stage 1 - Get number in narrow char\n    char __fmt[8] = {'%', 0};\n    const char* __len = \"ll\";\n    this->__format_int(__fmt+1, __len, false, __iob.flags());\n    const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)\n                          + ((numeric_limits<unsigned long long>::digits % 3) != 0)\n                          + 1;\n    char __nar[__nbuf];\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#else\n    int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#endif\n    char* __ne = __nar + __nc;\n    char* __np = this->__identify_padding(__nar, __ne, __iob);\n    // Stage 2 - Widen __nar while adding thousands separators\n    char_type __o[2*(__nbuf-1) - 1];\n    char_type* __op;  // pad here\n    char_type* __oe;  // end of output\n    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());\n    // [__o, __oe) contains thousands_sep'd wide number\n    // Stage 3 & 4\n    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);\n}\n\ntemplate <class _CharT, class _OutputIterator>\n_OutputIterator\nnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,\n                                         char_type __fl, double __v) const\n{\n    // Stage 1 - Get number in narrow char\n    char __fmt[8] = {'%', 0};\n    const char* __len = \"\";\n    bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());\n    const unsigned __nbuf = 30;\n    char __nar[__nbuf];\n    char* __nb = __nar;\n    int __nc;\n    if (__specify_precision)\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,\n                                   (int)__iob.precision(), __v);\n#else\n        __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,\n                                   (int)__iob.precision(), __v);\n#endif\n    else\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#else\n        __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#endif\n    unique_ptr<char, void(*)(void*)> __nbh(0, free);\n    if (__nc > static_cast<int>(__nbuf-1))\n    {\n        if (__specify_precision)\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);\n#else\n            __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);\n#endif\n        else\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#else\n            __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);\n#endif\n        if (__nb == 0)\n            __throw_bad_alloc();\n        __nbh.reset(__nb);\n    }\n    char* __ne = __nb + __nc;\n    char* __np = this->__identify_padding(__nb, __ne, __iob);\n    // Stage 2 - Widen __nar while adding thousands separators\n    char_type __o[2*(__nbuf-1) - 1];\n    char_type* __ob = __o;\n    unique_ptr<char_type, void(*)(void*)> __obh(0, free);\n    if (__nb != __nar)\n    {\n        __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));\n        if (__ob == 0)\n            __throw_bad_alloc();\n        __obh.reset(__ob);\n    }\n    char_type* __op;  // pad here\n    char_type* __oe;  // end of output\n    this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());\n    // [__o, __oe) contains thousands_sep'd wide number\n    // Stage 3 & 4\n    __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);\n    return __s;\n}\n\ntemplate <class _CharT, class _OutputIterator>\n_OutputIterator\nnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,\n                                         char_type __fl, long double __v) const\n{\n    // Stage 1 - Get number in narrow char\n    char __fmt[8] = {'%', 0};\n    const char* __len = \"L\";\n    bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());\n    const unsigned __nbuf = 30;\n    char __nar[__nbuf];\n    char* __nb = __nar;\n    int __nc;\n    if (__specify_precision)\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,\n                                   (int)__iob.precision(), __v);\n#else\n        __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,\n                                   (int)__iob.precision(), __v);\n#endif\n    else\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#else\n        __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#endif\n    unique_ptr<char, void(*)(void*)> __nbh(0, free);\n    if (__nc > static_cast<int>(__nbuf-1))\n    {\n        if (__specify_precision)\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);\n#else\n            __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);\n#endif\n        else\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#else\n            __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#endif\n        if (__nb == 0)\n            __throw_bad_alloc();\n        __nbh.reset(__nb);\n    }\n    char* __ne = __nb + __nc;\n    char* __np = this->__identify_padding(__nb, __ne, __iob);\n    // Stage 2 - Widen __nar while adding thousands separators\n    char_type __o[2*(__nbuf-1) - 1];\n    char_type* __ob = __o;\n    unique_ptr<char_type, void(*)(void*)> __obh(0, free);\n    if (__nb != __nar)\n    {\n        __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));\n        if (__ob == 0)\n            __throw_bad_alloc();\n        __obh.reset(__ob);\n    }\n    char_type* __op;  // pad here\n    char_type* __oe;  // end of output\n    this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());\n    // [__o, __oe) contains thousands_sep'd wide number\n    // Stage 3 & 4\n    __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);\n    return __s;\n}\n\ntemplate <class _CharT, class _OutputIterator>\n_OutputIterator\nnum_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,\n                                         char_type __fl, const void* __v) const\n{\n    // Stage 1 - Get pointer in narrow char\n    char __fmt[6] = \"%p\";\n    const unsigned __nbuf = 20;\n    char __nar[__nbuf];\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#else\n    int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);\n#endif\n    char* __ne = __nar + __nc;\n    char* __np = this->__identify_padding(__nar, __ne, __iob);\n    // Stage 2 - Widen __nar\n    char_type __o[2*(__nbuf-1) - 1];\n    char_type* __op;  // pad here\n    char_type* __oe;  // end of output\n    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());\n    __ct.widen(__nar, __ne, __o);\n    __oe = __o + (__ne - __nar);\n    if (__np == __ne)\n        __op = __oe;\n    else\n        __op = __o + (__np - __nar);\n    // [__o, __oe) contains wide number\n    // Stage 3 & 4\n    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);\n}\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<char>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<wchar_t>)\n\ntemplate <class _CharT, class _InputIterator>\n_LIBCPP_HIDDEN\nint\n__get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,\n                     ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n)\n{\n    // Precondition:  __n >= 1\n    if (__b == __e)\n    {\n        __err |= ios_base::eofbit | ios_base::failbit;\n        return 0;\n    }\n    // get first digit\n    _CharT __c = *__b;\n    if (!__ct.is(ctype_base::digit, __c))\n    {\n        __err |= ios_base::failbit;\n        return 0;\n    }\n    int __r = __ct.narrow(__c, 0) - '0';\n    for (++__b, (void) --__n; __b != __e && __n > 0; ++__b, (void) --__n)\n    {\n        // get next digit\n        __c = *__b;\n        if (!__ct.is(ctype_base::digit, __c))\n            return __r;\n        __r = __r * 10 + __ct.narrow(__c, 0) - '0';\n    }\n    if (__b == __e)\n        __err |= ios_base::eofbit;\n    return __r;\n}\n\nclass _LIBCPP_TYPE_VIS time_base\n{\npublic:\n    enum dateorder {no_order, dmy, mdy, ymd, ydm};\n};\n\ntemplate <class _CharT>\nclass _LIBCPP_TYPE_VIS_ONLY __time_get_c_storage\n{\nprotected:\n    typedef basic_string<_CharT> string_type;\n\n    virtual const string_type* __weeks() const;\n    virtual const string_type* __months() const;\n    virtual const string_type* __am_pm() const;\n    virtual const string_type& __c() const;\n    virtual const string_type& __r() const;\n    virtual const string_type& __x() const;\n    virtual const string_type& __X() const;\n};\n\ntemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >\nclass _LIBCPP_TYPE_VIS_ONLY time_get\n    : public locale::facet,\n      public time_base,\n      private __time_get_c_storage<_CharT>\n{\npublic:\n    typedef _CharT                  char_type;\n    typedef _InputIterator          iter_type;\n    typedef time_base::dateorder    dateorder;\n    typedef basic_string<char_type> string_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit time_get(size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    dateorder date_order() const\n    {\n        return this->do_date_order();\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,\n                       ios_base::iostate& __err, tm* __tm) const\n    {\n        return do_get_time(__b, __e, __iob, __err, __tm);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,\n                       ios_base::iostate& __err, tm* __tm) const\n    {\n        return do_get_date(__b, __e, __iob, __err, __tm);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,\n                          ios_base::iostate& __err, tm* __tm) const\n    {\n        return do_get_weekday(__b, __e, __iob, __err, __tm);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,\n                            ios_base::iostate& __err, tm* __tm) const\n    {\n        return do_get_monthname(__b, __e, __iob, __err, __tm);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,\n                       ios_base::iostate& __err, tm* __tm) const\n    {\n        return do_get_year(__b, __e, __iob, __err, __tm);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,\n                  ios_base::iostate& __err, tm *__tm,\n                  char __fmt, char __mod = 0) const\n    {\n        return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);\n    }\n\n    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,\n                  ios_base::iostate& __err, tm* __tm,\n                  const char_type* __fmtb, const char_type* __fmte) const;\n\n    static locale::id id;\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    ~time_get() {}\n\n    virtual dateorder do_date_order() const;\n    virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,\n                                  ios_base::iostate& __err, tm* __tm) const;\n    virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob,\n                                  ios_base::iostate& __err, tm* __tm) const;\n    virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob,\n                                     ios_base::iostate& __err, tm* __tm) const;\n    virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob,\n                                       ios_base::iostate& __err, tm* __tm) const;\n    virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob,\n                                  ios_base::iostate& __err, tm* __tm) const;\n    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,\n                             ios_base::iostate& __err, tm* __tm,\n                             char __fmt, char __mod) const;\nprivate:\n    void __get_white_space(iter_type& __b, iter_type __e,\n                           ios_base::iostate& __err, const ctype<char_type>& __ct) const;\n    void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err,\n                       const ctype<char_type>& __ct) const;\n\n    void __get_weekdayname(int& __m,\n                           iter_type& __b, iter_type __e,\n                           ios_base::iostate& __err,\n                           const ctype<char_type>& __ct) const;\n    void __get_monthname(int& __m,\n                         iter_type& __b, iter_type __e,\n                         ios_base::iostate& __err,\n                         const ctype<char_type>& __ct) const;\n    void __get_day(int& __d,\n                   iter_type& __b, iter_type __e,\n                   ios_base::iostate& __err,\n                   const ctype<char_type>& __ct) const;\n    void __get_month(int& __m,\n                     iter_type& __b, iter_type __e,\n                     ios_base::iostate& __err,\n                     const ctype<char_type>& __ct) const;\n    void __get_year(int& __y,\n                   iter_type& __b, iter_type __e,\n                   ios_base::iostate& __err,\n                   const ctype<char_type>& __ct) const;\n    void __get_year4(int& __y,\n                    iter_type& __b, iter_type __e,\n                    ios_base::iostate& __err,\n                    const ctype<char_type>& __ct) const;\n    void __get_hour(int& __d,\n                    iter_type& __b, iter_type __e,\n                    ios_base::iostate& __err,\n                    const ctype<char_type>& __ct) const;\n    void __get_12_hour(int& __h,\n                       iter_type& __b, iter_type __e,\n                       ios_base::iostate& __err,\n                       const ctype<char_type>& __ct) const;\n    void __get_am_pm(int& __h,\n                     iter_type& __b, iter_type __e,\n                     ios_base::iostate& __err,\n                     const ctype<char_type>& __ct) const;\n    void __get_minute(int& __m,\n                      iter_type& __b, iter_type __e,\n                      ios_base::iostate& __err,\n                      const ctype<char_type>& __ct) const;\n    void __get_second(int& __s,\n                      iter_type& __b, iter_type __e,\n                      ios_base::iostate& __err,\n                      const ctype<char_type>& __ct) const;\n    void __get_weekday(int& __w,\n                       iter_type& __b, iter_type __e,\n                       ios_base::iostate& __err,\n                       const ctype<char_type>& __ct) const;\n    void __get_day_year_num(int& __w,\n                            iter_type& __b, iter_type __e,\n                            ios_base::iostate& __err,\n                            const ctype<char_type>& __ct) const;\n};\n\ntemplate <class _CharT, class _InputIterator>\nlocale::id\ntime_get<_CharT, _InputIterator>::id;\n\n// time_get primitives\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_weekdayname(int& __w,\n                                                    iter_type& __b, iter_type __e,\n                                                    ios_base::iostate& __err,\n                                                    const ctype<char_type>& __ct) const\n{\n    // Note:  ignoring case comes from the POSIX strptime spec\n    const string_type* __wk = this->__weeks();\n    ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk;\n    if (__i < 14)\n        __w = __i % 7;\n}\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_monthname(int& __m,\n                                                  iter_type& __b, iter_type __e,\n                                                  ios_base::iostate& __err,\n                                                  const ctype<char_type>& __ct) const\n{\n    // Note:  ignoring case comes from the POSIX strptime spec\n    const string_type* __month = this->__months();\n    ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month;\n    if (__i < 24)\n        __m = __i % 12;\n}\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_day(int& __d,\n                                            iter_type& __b, iter_type __e,\n                                            ios_base::iostate& __err,\n                                            const ctype<char_type>& __ct) const\n{\n    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);\n    if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)\n        __d = __t;\n    else\n        __err |= ios_base::failbit;\n}\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_month(int& __m,\n                                              iter_type& __b, iter_type __e,\n                                              ios_base::iostate& __err,\n                                              const ctype<char_type>& __ct) const\n{\n    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;\n    if (!(__err & ios_base::failbit) && __t <= 11)\n        __m = __t;\n    else\n        __err |= ios_base::failbit;\n}\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_year(int& __y,\n                                             iter_type& __b, iter_type __e,\n                                             ios_base::iostate& __err,\n                                             const ctype<char_type>& __ct) const\n{\n    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);\n    if (!(__err & ios_base::failbit))\n    {\n        if (__t < 69)\n            __t += 2000;\n        else if (69 <= __t && __t <= 99)\n            __t += 1900;\n        __y = __t - 1900;\n    }\n}\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_year4(int& __y,\n                                              iter_type& __b, iter_type __e,\n                                              ios_base::iostate& __err,\n                                              const ctype<char_type>& __ct) const\n{\n    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);\n    if (!(__err & ios_base::failbit))\n        __y = __t - 1900;\n}\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_hour(int& __h,\n                                             iter_type& __b, iter_type __e,\n                                             ios_base::iostate& __err,\n                                             const ctype<char_type>& __ct) const\n{\n    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);\n    if (!(__err & ios_base::failbit) && __t <= 23)\n        __h = __t;\n    else\n        __err |= ios_base::failbit;\n}\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_12_hour(int& __h,\n                                                iter_type& __b, iter_type __e,\n                                                ios_base::iostate& __err,\n                                                const ctype<char_type>& __ct) const\n{\n    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);\n    if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)\n        __h = __t;\n    else\n        __err |= ios_base::failbit;\n}\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_minute(int& __m,\n                                               iter_type& __b, iter_type __e,\n                                               ios_base::iostate& __err,\n                                               const ctype<char_type>& __ct) const\n{\n    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);\n    if (!(__err & ios_base::failbit) && __t <= 59)\n        __m = __t;\n    else\n        __err |= ios_base::failbit;\n}\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_second(int& __s,\n                                               iter_type& __b, iter_type __e,\n                                               ios_base::iostate& __err,\n                                               const ctype<char_type>& __ct) const\n{\n    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);\n    if (!(__err & ios_base::failbit) && __t <= 60)\n        __s = __t;\n    else\n        __err |= ios_base::failbit;\n}\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_weekday(int& __w,\n                                                iter_type& __b, iter_type __e,\n                                                ios_base::iostate& __err,\n                                                const ctype<char_type>& __ct) const\n{\n    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);\n    if (!(__err & ios_base::failbit) && __t <= 6)\n        __w = __t;\n    else\n        __err |= ios_base::failbit;\n}\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,\n                                                     iter_type& __b, iter_type __e,\n                                                     ios_base::iostate& __err,\n                                                     const ctype<char_type>& __ct) const\n{\n    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);\n    if (!(__err & ios_base::failbit) && __t <= 365)\n        __d = __t;\n    else\n        __err |= ios_base::failbit;\n}\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e,\n                                                    ios_base::iostate& __err,\n                                                    const ctype<char_type>& __ct) const\n{\n    for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)\n        ;\n    if (__b == __e)\n        __err |= ios_base::eofbit;\n}\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_am_pm(int& __h,\n                                              iter_type& __b, iter_type __e,\n                                              ios_base::iostate& __err,\n                                              const ctype<char_type>& __ct) const\n{\n    const string_type* __ap = this->__am_pm();\n    if (__ap[0].size() + __ap[1].size() == 0)\n    {\n        __err |= ios_base::failbit;\n        return;\n    }\n    ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap;\n    if (__i == 0 && __h == 12)\n        __h = 0;\n    else if (__i == 1 && __h < 12)\n        __h += 12;\n}\n\ntemplate <class _CharT, class _InputIterator>\nvoid\ntime_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e,\n                                                ios_base::iostate& __err,\n                                                const ctype<char_type>& __ct) const\n{\n    if (__b == __e)\n    {\n        __err |= ios_base::eofbit | ios_base::failbit;\n        return;\n    }\n    if (__ct.narrow(*__b, 0) != '%')\n        __err |= ios_base::failbit;\n    else if(++__b == __e)\n        __err |= ios_base::eofbit;\n}\n\n// time_get end primitives\n\ntemplate <class _CharT, class _InputIterator>\n_InputIterator\ntime_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,\n                                      ios_base& __iob,\n                                      ios_base::iostate& __err, tm* __tm,\n                                      const char_type* __fmtb, const char_type* __fmte) const\n{\n    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());\n    __err = ios_base::goodbit;\n    while (__fmtb != __fmte && __err == ios_base::goodbit)\n    {\n        if (__b == __e)\n        {\n            __err = ios_base::failbit;\n            break;\n        }\n        if (__ct.narrow(*__fmtb, 0) == '%')\n        {\n            if (++__fmtb == __fmte)\n            {\n                __err = ios_base::failbit;\n                break;\n            }\n            char __cmd = __ct.narrow(*__fmtb, 0);\n            char __opt = '\\0';\n            if (__cmd == 'E' || __cmd == '0')\n            {\n                if (++__fmtb == __fmte)\n                {\n                    __err = ios_base::failbit;\n                    break;\n                }\n                __opt = __cmd;\n                __cmd = __ct.narrow(*__fmtb, 0);\n            }\n            __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);\n            ++__fmtb;\n        }\n        else if (__ct.is(ctype_base::space, *__fmtb))\n        {\n            for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)\n                ;\n            for (        ;    __b != __e    && __ct.is(ctype_base::space, *__b);    ++__b)\n                ;\n        }\n        else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb))\n        {\n            ++__b;\n            ++__fmtb;\n        }\n        else\n            __err = ios_base::failbit;\n    }\n    if (__b == __e)\n        __err |= ios_base::eofbit;\n    return __b;\n}\n\ntemplate <class _CharT, class _InputIterator>\ntypename time_get<_CharT, _InputIterator>::dateorder\ntime_get<_CharT, _InputIterator>::do_date_order() const\n{\n    return mdy;\n}\n\ntemplate <class _CharT, class _InputIterator>\n_InputIterator\ntime_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e,\n                                              ios_base& __iob,\n                                              ios_base::iostate& __err,\n                                              tm* __tm) const\n{\n    const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};\n    return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0]));\n}\n\ntemplate <class _CharT, class _InputIterator>\n_InputIterator\ntime_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e,\n                                              ios_base& __iob,\n                                              ios_base::iostate& __err,\n                                              tm* __tm) const\n{\n    const string_type& __fmt = this->__x();\n    return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());\n}\n\ntemplate <class _CharT, class _InputIterator>\n_InputIterator\ntime_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,\n                                                 ios_base& __iob,\n                                                 ios_base::iostate& __err,\n                                                 tm* __tm) const\n{\n    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());\n    __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);\n    return __b;\n}\n\ntemplate <class _CharT, class _InputIterator>\n_InputIterator\ntime_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,\n                                                   ios_base& __iob,\n                                                   ios_base::iostate& __err,\n                                                   tm* __tm) const\n{\n    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());\n    __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);\n    return __b;\n}\n\ntemplate <class _CharT, class _InputIterator>\n_InputIterator\ntime_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,\n                                              ios_base& __iob,\n                                              ios_base::iostate& __err,\n                                              tm* __tm) const\n{\n    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());\n    __get_year(__tm->tm_year, __b, __e, __err, __ct);\n    return __b;\n}\n\ntemplate <class _CharT, class _InputIterator>\n_InputIterator\ntime_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,\n                                         ios_base& __iob,\n                                         ios_base::iostate& __err, tm* __tm,\n                                         char __fmt, char) const\n{\n    __err = ios_base::goodbit;\n    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());\n    switch (__fmt)\n    {\n    case 'a':\n    case 'A':\n        __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);\n        break;\n    case 'b':\n    case 'B':\n    case 'h':\n        __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);\n        break;\n    case 'c':\n        {\n        const string_type& __fm = this->__c();\n        __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());\n        }\n        break;\n    case 'd':\n    case 'e':\n        __get_day(__tm->tm_mday, __b, __e, __err, __ct);\n        break;\n    case 'D':\n        {\n        const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};\n        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));\n        }\n        break;\n    case 'F':\n        {\n        const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};\n        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));\n        }\n        break;\n    case 'H':\n        __get_hour(__tm->tm_hour, __b, __e, __err, __ct);\n        break;\n    case 'I':\n        __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);\n        break;\n    case 'j':\n        __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);\n        break;\n    case 'm':\n        __get_month(__tm->tm_mon, __b, __e, __err, __ct);\n        break;\n    case 'M':\n        __get_minute(__tm->tm_min, __b, __e, __err, __ct);\n        break;\n    case 'n':\n    case 't':\n        __get_white_space(__b, __e, __err, __ct);\n        break;\n    case 'p':\n        __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);\n        break;\n    case 'r':\n        {\n        const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};\n        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));\n        }\n        break;\n    case 'R':\n        {\n        const char_type __fm[] = {'%', 'H', ':', '%', 'M'};\n        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));\n        }\n        break;\n    case 'S':\n        __get_second(__tm->tm_sec, __b, __e, __err, __ct);\n        break;\n    case 'T':\n        {\n        const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};\n        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));\n        }\n        break;\n    case 'w':\n        __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);\n        break;\n    case 'x':\n        return do_get_date(__b, __e, __iob, __err, __tm);\n    case 'X':\n        {\n        const string_type& __fm = this->__X();\n        __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());\n        }\n        break;\n    case 'y':\n        __get_year(__tm->tm_year, __b, __e, __err, __ct);\n        break;\n    case 'Y':\n        __get_year4(__tm->tm_year, __b, __e, __err, __ct);\n        break;\n    case '%':\n        __get_percent(__b, __e, __err, __ct);\n        break;\n    default:\n        __err |= ios_base::failbit;\n    }\n    return __b;\n}\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<char>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<wchar_t>)\n\nclass _LIBCPP_TYPE_VIS __time_get\n{\nprotected:\n    locale_t __loc_;\n\n    __time_get(const char* __nm);\n    __time_get(const string& __nm);\n    ~__time_get();\n};\n\ntemplate <class _CharT>\nclass _LIBCPP_TYPE_VIS_ONLY __time_get_storage\n    : public __time_get\n{\nprotected:\n    typedef basic_string<_CharT> string_type;\n\n    string_type __weeks_[14];\n    string_type __months_[24];\n    string_type __am_pm_[2];\n    string_type __c_;\n    string_type __r_;\n    string_type __x_;\n    string_type __X_;\n\n    explicit __time_get_storage(const char* __nm);\n    explicit __time_get_storage(const string& __nm);\n\n    _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {}\n\n    time_base::dateorder __do_date_order() const;\n\nprivate:\n    void init(const ctype<_CharT>&);\n    string_type __analyze(char __fmt, const ctype<_CharT>&);\n};\n\ntemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >\nclass _LIBCPP_TYPE_VIS_ONLY time_get_byname\n    : public time_get<_CharT, _InputIterator>,\n      private __time_get_storage<_CharT>\n{\npublic:\n    typedef time_base::dateorder    dateorder;\n    typedef _InputIterator          iter_type;\n    typedef _CharT                  char_type;\n    typedef basic_string<char_type> string_type;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit time_get_byname(const char* __nm, size_t __refs = 0)\n        : time_get<_CharT, _InputIterator>(__refs),\n          __time_get_storage<_CharT>(__nm) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit time_get_byname(const string& __nm, size_t __refs = 0)\n        : time_get<_CharT, _InputIterator>(__refs),\n          __time_get_storage<_CharT>(__nm) {}\n\nprotected:\n    _LIBCPP_INLINE_VISIBILITY\n    ~time_get_byname() {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    virtual dateorder do_date_order() const {return this->__do_date_order();}\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    virtual const string_type* __weeks() const  {return this->__weeks_;}\n    _LIBCPP_INLINE_VISIBILITY\n    virtual const string_type* __months() const {return this->__months_;}\n    _LIBCPP_INLINE_VISIBILITY\n    virtual const string_type* __am_pm() const  {return this->__am_pm_;}\n    _LIBCPP_INLINE_VISIBILITY\n    virtual const string_type& __c() const      {return this->__c_;}\n    _LIBCPP_INLINE_VISIBILITY\n    virtual const string_type& __r() const      {return this->__r_;}\n    _LIBCPP_INLINE_VISIBILITY\n    virtual const string_type& __x() const      {return this->__x_;}\n    _LIBCPP_INLINE_VISIBILITY\n    virtual const string_type& __X() const      {return this->__X_;}\n};\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<char>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<wchar_t>)\n\nclass _LIBCPP_TYPE_VIS __time_put\n{\n    locale_t __loc_;\nprotected:\n    _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}\n    __time_put(const char* __nm);\n    __time_put(const string& __nm);\n    ~__time_put();\n    void __do_put(char* __nb, char*& __ne, const tm* __tm,\n                  char __fmt, char __mod) const;\n    void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,\n                  char __fmt, char __mod) const;\n};\n\ntemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >\nclass _LIBCPP_TYPE_VIS_ONLY time_put\n    : public locale::facet,\n      private __time_put\n{\npublic:\n    typedef _CharT char_type;\n    typedef _OutputIterator iter_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit time_put(size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,\n                  const char_type* __pb, const char_type* __pe) const;\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,\n                  const tm* __tm, char __fmt, char __mod = 0) const\n    {\n        return do_put(__s, __iob, __fl, __tm, __fmt, __mod);\n    }\n\n    static locale::id id;\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    ~time_put() {}\n    virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,\n                             char __fmt, char __mod) const;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit time_put(const char* __nm, size_t __refs)\n        : locale::facet(__refs),\n          __time_put(__nm) {}\n    _LIBCPP_ALWAYS_INLINE\n    explicit time_put(const string& __nm, size_t __refs)\n        : locale::facet(__refs),\n          __time_put(__nm) {}\n};\n\ntemplate <class _CharT, class _OutputIterator>\nlocale::id\ntime_put<_CharT, _OutputIterator>::id;\n\ntemplate <class _CharT, class _OutputIterator>\n_OutputIterator\ntime_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,\n                                       char_type __fl, const tm* __tm,\n                                       const char_type* __pb,\n                                       const char_type* __pe) const\n{\n    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());\n    for (; __pb != __pe; ++__pb)\n    {\n        if (__ct.narrow(*__pb, 0) == '%')\n        {\n            if (++__pb == __pe)\n            {\n                *__s++ = __pb[-1];\n                break;\n            }\n            char __mod = 0;\n            char __fmt = __ct.narrow(*__pb, 0);\n            if (__fmt == 'E' || __fmt == 'O')\n            {\n                if (++__pb == __pe)\n                {\n                    *__s++ = __pb[-2];\n                    *__s++ = __pb[-1];\n                    break;\n                }\n                __mod = __fmt;\n                __fmt = __ct.narrow(*__pb, 0);\n            }\n            __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);\n        }\n        else\n            *__s++ = *__pb;\n    }\n    return __s;\n}\n\ntemplate <class _CharT, class _OutputIterator>\n_OutputIterator\ntime_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,\n                                          char_type, const tm* __tm,\n                                          char __fmt, char __mod) const\n{\n    char_type __nar[100];\n    char_type* __nb = __nar;\n    char_type* __ne = __nb + 100;\n    __do_put(__nb, __ne, __tm, __fmt, __mod);\n    return _VSTD::copy(__nb, __ne, __s);\n}\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<char>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<wchar_t>)\n\ntemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >\nclass _LIBCPP_TYPE_VIS_ONLY time_put_byname\n    : public time_put<_CharT, _OutputIterator>\n{\npublic:\n    _LIBCPP_ALWAYS_INLINE\n    explicit time_put_byname(const char* __nm, size_t __refs = 0)\n        : time_put<_CharT, _OutputIterator>(__nm, __refs) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit time_put_byname(const string& __nm, size_t __refs = 0)\n        : time_put<_CharT, _OutputIterator>(__nm, __refs) {}\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    ~time_put_byname() {}\n};\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<char>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<wchar_t>)\n\n// money_base\n\nclass _LIBCPP_TYPE_VIS money_base\n{\npublic:\n    enum part {none, space, symbol, sign, value};\n    struct pattern {char field[4];};\n\n    _LIBCPP_ALWAYS_INLINE money_base() {}\n};\n\n// moneypunct\n\ntemplate <class _CharT, bool _International = false>\nclass _LIBCPP_TYPE_VIS_ONLY moneypunct\n    : public locale::facet,\n      public money_base\n{\npublic:\n    typedef _CharT                  char_type;\n    typedef basic_string<char_type> string_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit moneypunct(size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    _LIBCPP_ALWAYS_INLINE char_type   decimal_point() const {return do_decimal_point();}\n    _LIBCPP_ALWAYS_INLINE char_type   thousands_sep() const {return do_thousands_sep();}\n    _LIBCPP_ALWAYS_INLINE string      grouping()      const {return do_grouping();}\n    _LIBCPP_ALWAYS_INLINE string_type curr_symbol()   const {return do_curr_symbol();}\n    _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();}\n    _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();}\n    _LIBCPP_ALWAYS_INLINE int         frac_digits()   const {return do_frac_digits();}\n    _LIBCPP_ALWAYS_INLINE pattern     pos_format()    const {return do_pos_format();}\n    _LIBCPP_ALWAYS_INLINE pattern     neg_format()    const {return do_neg_format();}\n\n    static locale::id id;\n    static const bool intl = _International;\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    ~moneypunct() {}\n\n    virtual char_type   do_decimal_point() const {return numeric_limits<char_type>::max();}\n    virtual char_type   do_thousands_sep() const {return numeric_limits<char_type>::max();}\n    virtual string      do_grouping()      const {return string();}\n    virtual string_type do_curr_symbol()   const {return string_type();}\n    virtual string_type do_positive_sign() const {return string_type();}\n    virtual string_type do_negative_sign() const {return string_type(1, '-');}\n    virtual int         do_frac_digits()   const {return 0;}\n    virtual pattern     do_pos_format()    const\n        {pattern __p = {{symbol, sign, none, value}}; return __p;}\n    virtual pattern     do_neg_format()    const\n        {pattern __p = {{symbol, sign, none, value}}; return __p;}\n};\n\ntemplate <class _CharT, bool _International>\nlocale::id\nmoneypunct<_CharT, _International>::id;\n\ntemplate <class _CharT, bool _International>\nconst bool\nmoneypunct<_CharT, _International>::intl;\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, false>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, true>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, false>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, true>)\n\n// moneypunct_byname\n\ntemplate <class _CharT, bool _International = false>\nclass _LIBCPP_TYPE_VIS_ONLY moneypunct_byname\n    : public moneypunct<_CharT, _International>\n{\npublic:\n    typedef money_base::pattern  pattern;\n    typedef _CharT                  char_type;\n    typedef basic_string<char_type> string_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit moneypunct_byname(const char* __nm, size_t __refs = 0)\n        : moneypunct<_CharT, _International>(__refs) {init(__nm);}\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit moneypunct_byname(const string& __nm, size_t __refs = 0)\n        : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    ~moneypunct_byname() {}\n\n    virtual char_type   do_decimal_point() const {return __decimal_point_;}\n    virtual char_type   do_thousands_sep() const {return __thousands_sep_;}\n    virtual string      do_grouping()      const {return __grouping_;}\n    virtual string_type do_curr_symbol()   const {return __curr_symbol_;}\n    virtual string_type do_positive_sign() const {return __positive_sign_;}\n    virtual string_type do_negative_sign() const {return __negative_sign_;}\n    virtual int         do_frac_digits()   const {return __frac_digits_;}\n    virtual pattern     do_pos_format()    const {return __pos_format_;}\n    virtual pattern     do_neg_format()    const {return __neg_format_;}\n\nprivate:\n    char_type   __decimal_point_;\n    char_type   __thousands_sep_;\n    string      __grouping_;\n    string_type __curr_symbol_;\n    string_type __positive_sign_;\n    string_type __negative_sign_;\n    int         __frac_digits_;\n    pattern     __pos_format_;\n    pattern     __neg_format_;\n\n    void init(const char*);\n};\n\ntemplate<> void moneypunct_byname<char, false>::init(const char*);\ntemplate<> void moneypunct_byname<char, true>::init(const char*);\ntemplate<> void moneypunct_byname<wchar_t, false>::init(const char*);\ntemplate<> void moneypunct_byname<wchar_t, true>::init(const char*);\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, false>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, true>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, false>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, true>)\n\n// money_get\n\ntemplate <class _CharT>\nclass __money_get\n{\nprotected:\n    typedef _CharT                  char_type;\n    typedef basic_string<char_type> string_type;\n\n    _LIBCPP_ALWAYS_INLINE __money_get() {}\n\n    static void __gather_info(bool __intl, const locale& __loc,\n                              money_base::pattern& __pat, char_type& __dp,\n                              char_type& __ts, string& __grp,\n                              string_type& __sym, string_type& __psn,\n                              string_type& __nsn, int& __fd);\n};\n\ntemplate <class _CharT>\nvoid\n__money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,\n                                   money_base::pattern& __pat, char_type& __dp,\n                                   char_type& __ts, string& __grp,\n                                   string_type& __sym, string_type& __psn,\n                                   string_type& __nsn, int& __fd)\n{\n    if (__intl)\n    {\n        const moneypunct<char_type, true>& __mp =\n            use_facet<moneypunct<char_type, true> >(__loc);\n        __pat = __mp.neg_format();\n        __nsn = __mp.negative_sign();\n        __psn = __mp.positive_sign();\n        __dp = __mp.decimal_point();\n        __ts = __mp.thousands_sep();\n        __grp = __mp.grouping();\n        __sym = __mp.curr_symbol();\n        __fd = __mp.frac_digits();\n    }\n    else\n    {\n        const moneypunct<char_type, false>& __mp =\n            use_facet<moneypunct<char_type, false> >(__loc);\n        __pat = __mp.neg_format();\n        __nsn = __mp.negative_sign();\n        __psn = __mp.positive_sign();\n        __dp = __mp.decimal_point();\n        __ts = __mp.thousands_sep();\n        __grp = __mp.grouping();\n        __sym = __mp.curr_symbol();\n        __fd = __mp.frac_digits();\n    }\n}\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<char>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<wchar_t>)\n\ntemplate <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >\nclass _LIBCPP_TYPE_VIS_ONLY money_get\n    : public locale::facet,\n      private __money_get<_CharT>\n{\npublic:\n    typedef _CharT                  char_type;\n    typedef _InputIterator          iter_type;\n    typedef basic_string<char_type> string_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit money_get(size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,\n                  ios_base::iostate& __err, long double& __v) const\n    {\n        return do_get(__b, __e, __intl, __iob, __err, __v);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,\n                  ios_base::iostate& __err, string_type& __v) const\n    {\n        return do_get(__b, __e, __intl, __iob, __err, __v);\n    }\n\n    static locale::id id;\n\nprotected:\n\n    _LIBCPP_ALWAYS_INLINE\n    ~money_get() {}\n\n    virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,\n                             ios_base& __iob, ios_base::iostate& __err,\n                             long double& __v) const;\n    virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,\n                             ios_base& __iob, ios_base::iostate& __err,\n                             string_type& __v) const;\n\nprivate:\n    static bool __do_get(iter_type& __b, iter_type __e,\n                         bool __intl, const locale& __loc,\n                         ios_base::fmtflags __flags, ios_base::iostate& __err,\n                         bool& __neg, const ctype<char_type>& __ct,\n                         unique_ptr<char_type, void(*)(void*)>& __wb,\n                         char_type*& __wn, char_type* __we);\n};\n\ntemplate <class _CharT, class _InputIterator>\nlocale::id\nmoney_get<_CharT, _InputIterator>::id;\n\n_LIBCPP_FUNC_VIS void __do_nothing(void*);\n\ntemplate <class _Tp>\n_LIBCPP_HIDDEN\nvoid\n__double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)\n{\n    bool __owns = __b.get_deleter() != __do_nothing;\n    size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);\n    size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?\n                       2 * __cur_cap : numeric_limits<size_t>::max();\n    if (__new_cap == 0)\n        __new_cap = sizeof(_Tp);\n    size_t __n_off = static_cast<size_t>(__n - __b.get());\n    _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);\n    if (__t == 0)\n        __throw_bad_alloc();\n    if (__owns)\n        __b.release();\n    __b = unique_ptr<_Tp, void(*)(void*)>(__t, free);\n    __new_cap /= sizeof(_Tp);\n    __n = __b.get() + __n_off;\n    __e = __b.get() + __new_cap;\n}\n\n// true == success\ntemplate <class _CharT, class _InputIterator>\nbool\nmoney_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,\n                                            bool __intl, const locale& __loc,\n                                            ios_base::fmtflags __flags,\n                                            ios_base::iostate& __err,\n                                            bool& __neg,\n                                            const ctype<char_type>& __ct,\n                                            unique_ptr<char_type, void(*)(void*)>& __wb,\n                                            char_type*& __wn, char_type* __we)\n{\n    const unsigned __bz = 100;\n    unsigned __gbuf[__bz];\n    unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing);\n    unsigned* __gn = __gb.get();\n    unsigned* __ge = __gn + __bz;\n    money_base::pattern __pat;\n    char_type __dp;\n    char_type __ts;\n    string __grp;\n    string_type __sym;\n    string_type __psn;\n    string_type __nsn;\n    // Capture the spaces read into money_base::{space,none} so they\n    // can be compared to initial spaces in __sym.\n    string_type __spaces;\n    int __fd;\n    __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp,\n                                       __sym, __psn, __nsn, __fd);\n    const string_type* __trailing_sign = 0;\n    __wn = __wb.get();\n    for (unsigned __p = 0; __p < 4 && __b != __e; ++__p)\n    {\n        switch (__pat.field[__p])\n        {\n        case money_base::space:\n            if (__p != 3)\n            {\n                if (__ct.is(ctype_base::space, *__b))\n                    __spaces.push_back(*__b++);\n                else\n                {\n                    __err |= ios_base::failbit;\n                    return false;\n                }\n            }\n            // drop through\n        case money_base::none:\n            if (__p != 3)\n            {\n                while (__b != __e && __ct.is(ctype_base::space, *__b))\n                    __spaces.push_back(*__b++);\n            }\n            break;\n        case money_base::sign:\n            if (__psn.size() + __nsn.size() > 0)\n            {\n                if (__psn.size() == 0 || __nsn.size() == 0)\n                {   // sign is optional\n                    if (__psn.size() > 0)\n                    {   // __nsn.size() == 0\n                        if (*__b == __psn[0])\n                        {\n                            ++__b;\n                            if (__psn.size() > 1)\n                                __trailing_sign = &__psn;\n                        }\n                        else\n                            __neg = true;\n                    }\n                    else if (*__b == __nsn[0])  // __nsn.size() > 0 &&  __psn.size() == 0\n                    {\n                        ++__b;\n                        __neg = true;\n                        if (__nsn.size() > 1)\n                            __trailing_sign = &__nsn;\n                    }\n                }\n                else  // sign is required\n                {\n                    if (*__b == __psn[0])\n                    {\n                        ++__b;\n                        if (__psn.size() > 1)\n                            __trailing_sign = &__psn;\n                    }\n                    else if (*__b == __nsn[0])\n                    {\n                        ++__b;\n                        __neg = true;\n                        if (__nsn.size() > 1)\n                            __trailing_sign = &__nsn;\n                    }\n                    else\n                    {\n                        __err |= ios_base::failbit;\n                        return false;\n                    }\n                }\n            }\n            break;\n        case money_base::symbol:\n            {\n            bool __more_needed = __trailing_sign ||\n                                 (__p < 2)       ||\n                                 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));\n            bool __sb = (__flags & ios_base::showbase) != 0;\n            if (__sb || __more_needed)\n            {\n                typename string_type::const_iterator __sym_space_end = __sym.begin();\n                if (__p > 0 && (__pat.field[__p - 1] == money_base::none ||\n                                __pat.field[__p - 1] == money_base::space)) {\n                    // Match spaces we've already read against spaces at\n                    // the beginning of __sym.\n                    while (__sym_space_end != __sym.end() &&\n                           __ct.is(ctype_base::space, *__sym_space_end))\n                        ++__sym_space_end;\n                    const size_t __num_spaces = __sym_space_end - __sym.begin();\n                    if (__num_spaces > __spaces.size() ||\n                        !equal(__spaces.end() - __num_spaces, __spaces.end(),\n                               __sym.begin())) {\n                        // No match. Put __sym_space_end back at the\n                        // beginning of __sym, which will prevent a\n                        // match in the next loop.\n                        __sym_space_end = __sym.begin();\n                    }\n                }\n                typename string_type::const_iterator __sym_curr_char = __sym_space_end;\n                while (__sym_curr_char != __sym.end() && __b != __e &&\n                       *__b == *__sym_curr_char) {\n                    ++__b;\n                    ++__sym_curr_char;\n                }\n                if (__sb && __sym_curr_char != __sym.end())\n                {\n                    __err |= ios_base::failbit;\n                    return false;\n                }\n            }\n            }\n            break;\n        case money_base::value:\n            {\n            unsigned __ng = 0;\n            for (; __b != __e; ++__b)\n            {\n                char_type __c = *__b;\n                if (__ct.is(ctype_base::digit, __c))\n                {\n                    if (__wn == __we)\n                        __double_or_nothing(__wb, __wn, __we);\n                    *__wn++ = __c;\n                    ++__ng;\n                }\n                else if (__grp.size() > 0 && __ng > 0 && __c == __ts)\n                {\n                    if (__gn == __ge)\n                        __double_or_nothing(__gb, __gn, __ge);\n                    *__gn++ = __ng;\n                    __ng = 0;\n                }\n                else\n                    break;\n            }\n            if (__gb.get() != __gn && __ng > 0)\n            {\n                if (__gn == __ge)\n                    __double_or_nothing(__gb, __gn, __ge);\n                *__gn++ = __ng;\n            }\n            if (__fd > 0)\n            {\n                if (__b == __e || *__b != __dp)\n                {\n                    __err |= ios_base::failbit;\n                    return false;\n                }\n                for (++__b; __fd > 0; --__fd, ++__b)\n                {\n                    if (__b == __e || !__ct.is(ctype_base::digit, *__b))\n                    {\n                        __err |= ios_base::failbit;\n                        return false;\n                    }\n                    if (__wn == __we)\n                        __double_or_nothing(__wb, __wn, __we);\n                    *__wn++ = *__b;\n                }\n            }\n            if (__wn == __wb.get())\n            {\n                __err |= ios_base::failbit;\n                return false;\n            }\n            }\n            break;\n        }\n    }\n    if (__trailing_sign)\n    {\n        for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b)\n        {\n            if (__b == __e || *__b != (*__trailing_sign)[__i])\n            {\n                __err |= ios_base::failbit;\n                return false;\n            }\n        }\n    }\n    if (__gb.get() != __gn)\n    {\n        ios_base::iostate __et = ios_base::goodbit;\n        __check_grouping(__grp, __gb.get(), __gn, __et);\n        if (__et)\n        {\n            __err |= ios_base::failbit;\n            return false;\n        }\n    }\n    return true;\n}\n\ntemplate <class _CharT, class _InputIterator>\n_InputIterator\nmoney_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,\n                                          bool __intl, ios_base& __iob,\n                                          ios_base::iostate& __err,\n                                          long double& __v) const\n{\n    const int __bz = 100;\n    char_type __wbuf[__bz];\n    unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);\n    char_type* __wn;\n    char_type* __we = __wbuf + __bz;\n    locale __loc = __iob.getloc();\n    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);\n    bool __neg = false;\n    if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,\n                 __wb, __wn, __we))\n    {\n        const char __src[] = \"0123456789\";\n        char_type __atoms[sizeof(__src)-1];\n        __ct.widen(__src, __src + (sizeof(__src)-1), __atoms);\n        char __nbuf[__bz];\n        char* __nc = __nbuf;\n        unique_ptr<char, void(*)(void*)> __h(0, free);\n        if (__wn - __wb.get() > __bz-2)\n        {\n            __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));\n            if (__h.get() == 0)\n                __throw_bad_alloc();\n            __nc = __h.get();\n        }\n        if (__neg)\n            *__nc++ = '-';\n        for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)\n            *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms];\n        *__nc = char();\n        if (sscanf(__nbuf, \"%Lf\", &__v) != 1)\n            __throw_runtime_error(\"money_get error\");\n    }\n    if (__b == __e)\n        __err |= ios_base::eofbit;\n    return __b;\n}\n\ntemplate <class _CharT, class _InputIterator>\n_InputIterator\nmoney_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,\n                                          bool __intl, ios_base& __iob,\n                                          ios_base::iostate& __err,\n                                          string_type& __v) const\n{\n    const int __bz = 100;\n    char_type __wbuf[__bz];\n    unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);\n    char_type* __wn;\n    char_type* __we = __wbuf + __bz;\n    locale __loc = __iob.getloc();\n    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);\n    bool __neg = false;\n    if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,\n                 __wb, __wn, __we))\n    {\n        __v.clear();\n        if (__neg)\n            __v.push_back(__ct.widen('-'));\n        char_type __z = __ct.widen('0');\n        char_type* __w;\n        for (__w = __wb.get(); __w < __wn-1; ++__w)\n            if (*__w != __z)\n                break;\n        __v.append(__w, __wn);\n    }\n    if (__b == __e)\n        __err |= ios_base::eofbit;\n    return __b;\n}\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<char>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<wchar_t>)\n\n// money_put\n\ntemplate <class _CharT>\nclass __money_put\n{\nprotected:\n    typedef _CharT                  char_type;\n    typedef basic_string<char_type> string_type;\n\n    _LIBCPP_ALWAYS_INLINE __money_put() {}\n\n    static void __gather_info(bool __intl, bool __neg, const locale& __loc,\n                              money_base::pattern& __pat, char_type& __dp,\n                              char_type& __ts, string& __grp,\n                              string_type& __sym, string_type& __sn,\n                              int& __fd);\n    static void __format(char_type* __mb, char_type*& __mi, char_type*& __me,\n                         ios_base::fmtflags __flags,\n                         const char_type* __db, const char_type* __de,\n                         const ctype<char_type>& __ct, bool __neg,\n                         const money_base::pattern& __pat, char_type __dp,\n                         char_type __ts, const string& __grp,\n                         const string_type& __sym, const string_type& __sn,\n                         int __fd);\n};\n\ntemplate <class _CharT>\nvoid\n__money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,\n                                   money_base::pattern& __pat, char_type& __dp,\n                                   char_type& __ts, string& __grp,\n                                   string_type& __sym, string_type& __sn,\n                                   int& __fd)\n{\n    if (__intl)\n    {\n        const moneypunct<char_type, true>& __mp =\n            use_facet<moneypunct<char_type, true> >(__loc);\n        if (__neg)\n        {\n            __pat = __mp.neg_format();\n            __sn = __mp.negative_sign();\n        }\n        else\n        {\n            __pat = __mp.pos_format();\n            __sn = __mp.positive_sign();\n        }\n        __dp = __mp.decimal_point();\n        __ts = __mp.thousands_sep();\n        __grp = __mp.grouping();\n        __sym = __mp.curr_symbol();\n        __fd = __mp.frac_digits();\n    }\n    else\n    {\n        const moneypunct<char_type, false>& __mp =\n            use_facet<moneypunct<char_type, false> >(__loc);\n        if (__neg)\n        {\n            __pat = __mp.neg_format();\n            __sn = __mp.negative_sign();\n        }\n        else\n        {\n            __pat = __mp.pos_format();\n            __sn = __mp.positive_sign();\n        }\n        __dp = __mp.decimal_point();\n        __ts = __mp.thousands_sep();\n        __grp = __mp.grouping();\n        __sym = __mp.curr_symbol();\n        __fd = __mp.frac_digits();\n    }\n}\n\ntemplate <class _CharT>\nvoid\n__money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me,\n                              ios_base::fmtflags __flags,\n                              const char_type* __db, const char_type* __de,\n                              const ctype<char_type>& __ct, bool __neg,\n                              const money_base::pattern& __pat, char_type __dp,\n                              char_type __ts, const string& __grp,\n                              const string_type& __sym, const string_type& __sn,\n                              int __fd)\n{\n    __me = __mb;\n    for (unsigned __p = 0; __p < 4; ++__p)\n    {\n        switch (__pat.field[__p])\n        {\n        case money_base::none:\n            __mi = __me;\n            break;\n        case money_base::space:\n            __mi = __me;\n            *__me++ = __ct.widen(' ');\n            break;\n        case money_base::sign:\n            if (!__sn.empty())\n                *__me++ = __sn[0];\n            break;\n        case money_base::symbol:\n            if (!__sym.empty() && (__flags & ios_base::showbase))\n                __me = _VSTD::copy(__sym.begin(), __sym.end(), __me);\n            break;\n        case money_base::value:\n            {\n            // remember start of value so we can reverse it\n            char_type* __t = __me;\n            // find beginning of digits\n            if (__neg)\n                ++__db;\n            // find end of digits\n            const char_type* __d;\n            for (__d = __db; __d < __de; ++__d)\n                if (!__ct.is(ctype_base::digit, *__d))\n                    break;\n            // print fractional part\n            if (__fd > 0)\n            {\n                int __f;\n                for (__f = __fd; __d > __db && __f > 0; --__f)\n                    *__me++ = *--__d;\n                char_type __z = __f > 0 ? __ct.widen('0') : char_type();\n                for (; __f > 0; --__f)\n                    *__me++ = __z;\n                *__me++ = __dp;\n            }\n            // print units part\n            if (__d == __db)\n            {\n                *__me++ = __ct.widen('0');\n            }\n            else\n            {\n                unsigned __ng = 0;\n                unsigned __ig = 0;\n                unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max()\n                                              : static_cast<unsigned>(__grp[__ig]);\n                while (__d != __db)\n                {\n                    if (__ng == __gl)\n                    {\n                        *__me++ = __ts;\n                        __ng = 0;\n                        if (++__ig < __grp.size())\n                            __gl = __grp[__ig] == numeric_limits<char>::max() ?\n                                        numeric_limits<unsigned>::max() :\n                                        static_cast<unsigned>(__grp[__ig]);\n                    }\n                    *__me++ = *--__d;\n                    ++__ng;\n                }\n            }\n            // reverse it\n            reverse(__t, __me);\n            }\n            break;\n        }\n    }\n    // print rest of sign, if any\n    if (__sn.size() > 1)\n        __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me);\n    // set alignment\n    if ((__flags & ios_base::adjustfield) == ios_base::left)\n        __mi = __me;\n    else if ((__flags & ios_base::adjustfield) != ios_base::internal)\n        __mi = __mb;\n}\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<char>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<wchar_t>)\n\ntemplate <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >\nclass _LIBCPP_TYPE_VIS_ONLY money_put\n    : public locale::facet,\n      private __money_put<_CharT>\n{\npublic:\n    typedef _CharT                  char_type;\n    typedef _OutputIterator         iter_type;\n    typedef basic_string<char_type> string_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit money_put(size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,\n                  long double __units) const\n    {\n        return do_put(__s, __intl, __iob, __fl, __units);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,\n                  const string_type& __digits) const\n    {\n        return do_put(__s, __intl, __iob, __fl, __digits);\n    }\n\n    static locale::id id;\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    ~money_put() {}\n\n    virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,\n                             char_type __fl, long double __units) const;\n    virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,\n                             char_type __fl, const string_type& __digits) const;\n};\n\ntemplate <class _CharT, class _OutputIterator>\nlocale::id\nmoney_put<_CharT, _OutputIterator>::id;\n\ntemplate <class _CharT, class _OutputIterator>\n_OutputIterator\nmoney_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,\n                                           ios_base& __iob, char_type __fl,\n                                           long double __units) const\n{\n    // convert to char\n    const size_t __bs = 100;\n    char __buf[__bs];\n    char* __bb = __buf;\n    char_type __digits[__bs];\n    char_type* __db = __digits;\n    size_t __n = static_cast<size_t>(snprintf(__bb, __bs, \"%.0Lf\", __units));\n    unique_ptr<char, void(*)(void*)> __hn(0, free);\n    unique_ptr<char_type, void(*)(void*)> __hd(0, free);\n    // secure memory for digit storage\n    if (__n > __bs-1)\n    {\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, \"%.0Lf\", __units));\n#else\n        __n = __asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, \"%.0Lf\", __units);\n#endif\n        if (__bb == 0)\n            __throw_bad_alloc();\n        __hn.reset(__bb);\n        __hd.reset((char_type*)malloc(__n * sizeof(char_type)));\n        if (__hd == nullptr)\n            __throw_bad_alloc();\n        __db = __hd.get();\n    }\n    // gather info\n    locale __loc = __iob.getloc();\n    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);\n    __ct.widen(__bb, __bb + __n, __db);\n    bool __neg = __n > 0 && __bb[0] == '-';\n    money_base::pattern __pat;\n    char_type __dp;\n    char_type __ts;\n    string __grp;\n    string_type __sym;\n    string_type __sn;\n    int __fd;\n    this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);\n    // secure memory for formatting\n    char_type __mbuf[__bs];\n    char_type* __mb = __mbuf;\n    unique_ptr<char_type, void(*)(void*)> __hw(0, free);\n    size_t __exn = static_cast<int>(__n) > __fd ?\n                   (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() +\n                    __sym.size() + static_cast<size_t>(__fd) + 1\n                 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;\n    if (__exn > __bs)\n    {\n        __hw.reset((char_type*)malloc(__exn * sizeof(char_type)));\n        __mb = __hw.get();\n        if (__mb == 0)\n            __throw_bad_alloc();\n    }\n    // format\n    char_type* __mi;\n    char_type* __me;\n    this->__format(__mb, __mi, __me, __iob.flags(),\n                   __db, __db + __n, __ct,\n                   __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);\n    return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);\n}\n\ntemplate <class _CharT, class _OutputIterator>\n_OutputIterator\nmoney_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,\n                                           ios_base& __iob, char_type __fl,\n                                           const string_type& __digits) const\n{\n    // gather info\n    locale __loc = __iob.getloc();\n    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);\n    bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');\n    money_base::pattern __pat;\n    char_type __dp;\n    char_type __ts;\n    string __grp;\n    string_type __sym;\n    string_type __sn;\n    int __fd;\n    this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);\n    // secure memory for formatting\n    char_type __mbuf[100];\n    char_type* __mb = __mbuf;\n    unique_ptr<char_type, void(*)(void*)> __h(0, free);\n    size_t __exn = static_cast<int>(__digits.size()) > __fd ?\n                   (__digits.size() - static_cast<size_t>(__fd)) * 2 +\n                    __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1\n                 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;\n    if (__exn > 100)\n    {\n        __h.reset((char_type*)malloc(__exn * sizeof(char_type)));\n        __mb = __h.get();\n        if (__mb == 0)\n            __throw_bad_alloc();\n    }\n    // format\n    char_type* __mi;\n    char_type* __me;\n    this->__format(__mb, __mi, __me, __iob.flags(),\n                   __digits.data(), __digits.data() + __digits.size(), __ct,\n                   __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);\n    return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);\n}\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<char>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<wchar_t>)\n\n// messages\n\nclass _LIBCPP_TYPE_VIS messages_base\n{\npublic:\n    typedef ptrdiff_t catalog;\n\n    _LIBCPP_ALWAYS_INLINE messages_base() {}\n};\n\ntemplate <class _CharT>\nclass _LIBCPP_TYPE_VIS_ONLY messages\n    : public locale::facet,\n      public messages_base\n{\npublic:\n    typedef _CharT               char_type;\n    typedef basic_string<_CharT> string_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit messages(size_t __refs = 0)\n        : locale::facet(__refs) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    catalog open(const basic_string<char>& __nm, const locale& __loc) const\n    {\n        return do_open(__nm, __loc);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    string_type get(catalog __c, int __set, int __msgid,\n                    const string_type& __dflt) const\n    {\n        return do_get(__c, __set, __msgid, __dflt);\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    void close(catalog __c) const\n    {\n        do_close(__c);\n    }\n\n    static locale::id id;\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    ~messages() {}\n\n    virtual catalog do_open(const basic_string<char>&, const locale&) const;\n    virtual string_type do_get(catalog, int __set, int __msgid,\n                               const string_type& __dflt) const;\n    virtual void do_close(catalog) const;\n};\n\ntemplate <class _CharT>\nlocale::id\nmessages<_CharT>::id;\n\ntemplate <class _CharT>\ntypename messages<_CharT>::catalog\nmessages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const\n{\n#ifdef _LIBCPP_HAS_CATOPEN\n    catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);\n    if (__cat != -1)\n        __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));\n    return __cat;\n#else // !_LIBCPP_HAS_CATOPEN\n    return -1;\n#endif // _LIBCPP_HAS_CATOPEN\n}\n\ntemplate <class _CharT>\ntypename messages<_CharT>::string_type\nmessages<_CharT>::do_get(catalog __c, int __set, int __msgid,\n                         const string_type& __dflt) const\n{\n#ifdef _LIBCPP_HAS_CATOPEN\n    string __ndflt;\n    __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),\n                                                       __dflt.c_str(),\n                                                       __dflt.c_str() + __dflt.size());\n    if (__c != -1)\n        __c <<= 1;\n    nl_catd __cat = (nl_catd)__c;\n    char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());\n    string_type __w;\n    __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),\n                                                        __n, __n + strlen(__n));\n    return __w;\n#else // !_LIBCPP_HAS_CATOPEN\n    return __dflt;\n#endif // _LIBCPP_HAS_CATOPEN\n}\n\ntemplate <class _CharT>\nvoid\nmessages<_CharT>::do_close(catalog __c) const\n{\n#ifdef _LIBCPP_HAS_CATOPEN\n    if (__c != -1)\n        __c <<= 1;\n    nl_catd __cat = (nl_catd)__c;\n    catclose(__cat);\n#endif // _LIBCPP_HAS_CATOPEN\n}\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<char>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<wchar_t>)\n\ntemplate <class _CharT>\nclass _LIBCPP_TYPE_VIS_ONLY messages_byname\n    : public messages<_CharT>\n{\npublic:\n    typedef messages_base::catalog catalog;\n    typedef basic_string<_CharT> string_type;\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit messages_byname(const char*, size_t __refs = 0)\n        : messages<_CharT>(__refs) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    explicit messages_byname(const string&, size_t __refs = 0)\n        : messages<_CharT>(__refs) {}\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    ~messages_byname() {}\n};\n\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<char>)\n_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<wchar_t>)\n\ntemplate<class _Codecvt, class _Elem = wchar_t,\n         class _Wide_alloc = allocator<_Elem>,\n         class _Byte_alloc = allocator<char> >\nclass _LIBCPP_TYPE_VIS_ONLY wstring_convert\n{\npublic:\n    typedef basic_string<char, char_traits<char>, _Byte_alloc>   byte_string;\n    typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;\n    typedef typename _Codecvt::state_type                        state_type;\n    typedef typename wide_string::traits_type::int_type          int_type;\n\nprivate:\n    byte_string __byte_err_string_;\n    wide_string __wide_err_string_;\n    _Codecvt* __cvtptr_;\n    state_type __cvtstate_;\n    size_t __cvtcount_;\n\n    wstring_convert(const wstring_convert& __wc);\n    wstring_convert& operator=(const wstring_convert& __wc);\npublic:\n    _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt);\n    wstring_convert(_Codecvt* __pcvt, state_type __state);\n    _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,\n                    const wide_string& __wide_err = wide_string());\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    wstring_convert(wstring_convert&& __wc);\n#endif\n    ~wstring_convert();\n\n    _LIBCPP_ALWAYS_INLINE\n    wide_string from_bytes(char __byte)\n        {return from_bytes(&__byte, &__byte+1);}\n    _LIBCPP_ALWAYS_INLINE\n    wide_string from_bytes(const char* __ptr)\n        {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}\n    _LIBCPP_ALWAYS_INLINE\n    wide_string from_bytes(const byte_string& __str)\n        {return from_bytes(__str.data(), __str.data() + __str.size());}\n    wide_string from_bytes(const char* __first, const char* __last);\n\n    _LIBCPP_ALWAYS_INLINE\n    byte_string to_bytes(_Elem __wchar)\n        {return to_bytes(&__wchar, &__wchar+1);}\n    _LIBCPP_ALWAYS_INLINE\n    byte_string to_bytes(const _Elem* __wptr)\n        {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}\n    _LIBCPP_ALWAYS_INLINE\n    byte_string to_bytes(const wide_string& __wstr)\n        {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}\n    byte_string to_bytes(const _Elem* __first, const _Elem* __last);\n\n    _LIBCPP_ALWAYS_INLINE\n    size_t converted() const _NOEXCEPT {return __cvtcount_;}\n    _LIBCPP_ALWAYS_INLINE\n    state_type state() const {return __cvtstate_;}\n};\n\ntemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>\ninline _LIBCPP_ALWAYS_INLINE\nwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::\n    wstring_convert(_Codecvt* __pcvt)\n        : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)\n{\n}\n\ntemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>\ninline _LIBCPP_ALWAYS_INLINE\nwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::\n    wstring_convert(_Codecvt* __pcvt, state_type __state)\n        : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)\n{\n}\n\ntemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>\nwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::\n    wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)\n        : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),\n          __cvtstate_(), __cvtcount_(0)\n{\n    __cvtptr_ = new _Codecvt;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>\ninline _LIBCPP_ALWAYS_INLINE\nwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::\n    wstring_convert(wstring_convert&& __wc)\n        : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),\n          __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),\n          __cvtptr_(__wc.__cvtptr_),\n          __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_)\n{\n    __wc.__cvtptr_ = nullptr;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>\nwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()\n{\n    delete __cvtptr_;\n}\n\ntemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>\ntypename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string\nwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::\n    from_bytes(const char* __frm, const char* __frm_end)\n{\n    __cvtcount_ = 0;\n    if (__cvtptr_ != nullptr)\n    {\n        wide_string __ws(2*(__frm_end - __frm), _Elem());\n        if (__frm != __frm_end)\n            __ws.resize(__ws.capacity());\n        codecvt_base::result __r = codecvt_base::ok;\n        state_type __st = __cvtstate_;\n        if (__frm != __frm_end)\n        {\n            _Elem* __to = &__ws[0];\n            _Elem* __to_end = __to + __ws.size();\n            const char* __frm_nxt;\n            do\n            {\n                _Elem* __to_nxt;\n                __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt,\n                                          __to, __to_end, __to_nxt);\n                __cvtcount_ += __frm_nxt - __frm;\n                if (__frm_nxt == __frm)\n                {\n                    __r = codecvt_base::error;\n                }\n                else if (__r == codecvt_base::noconv)\n                {\n                    __ws.resize(__to - &__ws[0]);\n                    // This only gets executed if _Elem is char\n                    __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);\n                    __frm = __frm_nxt;\n                    __r = codecvt_base::ok;\n                }\n                else if (__r == codecvt_base::ok)\n                {\n                    __ws.resize(__to_nxt - &__ws[0]);\n                    __frm = __frm_nxt;\n                }\n                else if (__r == codecvt_base::partial)\n                {\n                    ptrdiff_t __s = __to_nxt - &__ws[0];\n                    __ws.resize(2 * __s);\n                    __to = &__ws[0] + __s;\n                    __to_end = &__ws[0] + __ws.size();\n                    __frm = __frm_nxt;\n                }\n            } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);\n        }\n        if (__r == codecvt_base::ok)\n            return __ws;\n    }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__wide_err_string_.empty())\n        throw range_error(\"wstring_convert: from_bytes error\");\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __wide_err_string_;\n}\n\ntemplate<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>\ntypename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string\nwstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::\n    to_bytes(const _Elem* __frm, const _Elem* __frm_end)\n{\n    __cvtcount_ = 0;\n    if (__cvtptr_ != nullptr)\n    {\n        byte_string __bs(2*(__frm_end - __frm), char());\n        if (__frm != __frm_end)\n            __bs.resize(__bs.capacity());\n        codecvt_base::result __r = codecvt_base::ok;\n        state_type __st = __cvtstate_;\n        if (__frm != __frm_end)\n        {\n            char* __to = &__bs[0];\n            char* __to_end = __to + __bs.size();\n            const _Elem* __frm_nxt;\n            do\n            {\n                char* __to_nxt;\n                __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt,\n                                           __to, __to_end, __to_nxt);\n                __cvtcount_ += __frm_nxt - __frm;\n                if (__frm_nxt == __frm)\n                {\n                    __r = codecvt_base::error;\n                }\n                else if (__r == codecvt_base::noconv)\n                {\n                    __bs.resize(__to - &__bs[0]);\n                    // This only gets executed if _Elem is char\n                    __bs.append((const char*)__frm, (const char*)__frm_end);\n                    __frm = __frm_nxt;\n                    __r = codecvt_base::ok;\n                }\n                else if (__r == codecvt_base::ok)\n                {\n                    __bs.resize(__to_nxt - &__bs[0]);\n                    __frm = __frm_nxt;\n                }\n                else if (__r == codecvt_base::partial)\n                {\n                    ptrdiff_t __s = __to_nxt - &__bs[0];\n                    __bs.resize(2 * __s);\n                    __to = &__bs[0] + __s;\n                    __to_end = &__bs[0] + __bs.size();\n                    __frm = __frm_nxt;\n                }\n            } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);\n        }\n        if (__r == codecvt_base::ok)\n        {\n            size_t __s = __bs.size();\n            __bs.resize(__bs.capacity());\n            char* __to = &__bs[0] + __s;\n            char* __to_end = __to + __bs.size();\n            do\n            {\n                char* __to_nxt;\n                __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);\n                if (__r == codecvt_base::noconv)\n                {\n                    __bs.resize(__to - &__bs[0]);\n                    __r = codecvt_base::ok;\n                }\n                else if (__r == codecvt_base::ok)\n                {\n                    __bs.resize(__to_nxt - &__bs[0]);\n                }\n                else if (__r == codecvt_base::partial)\n                {\n                    ptrdiff_t __sp = __to_nxt - &__bs[0];\n                    __bs.resize(2 * __sp);\n                    __to = &__bs[0] + __sp;\n                    __to_end = &__bs[0] + __bs.size();\n                }\n            } while (__r == codecvt_base::partial);\n            if (__r == codecvt_base::ok)\n                return __bs;\n        }\n    }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__byte_err_string_.empty())\n        throw range_error(\"wstring_convert: to_bytes error\");\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __byte_err_string_;\n}\n\ntemplate <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >\nclass _LIBCPP_TYPE_VIS_ONLY wbuffer_convert\n    : public basic_streambuf<_Elem, _Tr>\n{\npublic:\n    // types:\n    typedef _Elem                          char_type;\n    typedef _Tr                            traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n    typedef typename _Codecvt::state_type  state_type;\n\nprivate:\n    char*       __extbuf_;\n    const char* __extbufnext_;\n    const char* __extbufend_;\n    char __extbuf_min_[8];\n    size_t __ebs_;\n    char_type* __intbuf_;\n    size_t __ibs_;\n    streambuf* __bufptr_;\n    _Codecvt* __cv_;\n    state_type __st_;\n    ios_base::openmode __cm_;\n    bool __owns_eb_;\n    bool __owns_ib_;\n    bool __always_noconv_;\n\n    wbuffer_convert(const wbuffer_convert&);\n    wbuffer_convert& operator=(const wbuffer_convert&);\npublic:\n    _LIBCPP_EXPLICIT_AFTER_CXX11 wbuffer_convert(streambuf* __bytebuf = 0, \n            _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type());\n    ~wbuffer_convert();\n\n    _LIBCPP_INLINE_VISIBILITY\n    streambuf* rdbuf() const {return __bufptr_;}\n    _LIBCPP_INLINE_VISIBILITY\n    streambuf* rdbuf(streambuf* __bytebuf)\n    {\n        streambuf* __r = __bufptr_;\n        __bufptr_ = __bytebuf;\n        return __r;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    state_type state() const {return __st_;}\n\nprotected:\n    virtual int_type underflow();\n    virtual int_type pbackfail(int_type __c = traits_type::eof());\n    virtual int_type overflow (int_type __c = traits_type::eof());\n    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,\n                                                            streamsize __n);\n    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,\n                             ios_base::openmode __wch = ios_base::in | ios_base::out);\n    virtual pos_type seekpos(pos_type __sp,\n                             ios_base::openmode __wch = ios_base::in | ios_base::out);\n    virtual int sync();\n\nprivate:\n    bool __read_mode();\n    void __write_mode();\n    wbuffer_convert* __close();\n};\n\ntemplate <class _Codecvt, class _Elem, class _Tr>\nwbuffer_convert<_Codecvt, _Elem, _Tr>::\n    wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)\n    : __extbuf_(0),\n      __extbufnext_(0),\n      __extbufend_(0),\n      __ebs_(0),\n      __intbuf_(0),\n      __ibs_(0),\n      __bufptr_(__bytebuf),\n      __cv_(__pcvt),\n      __st_(__state),\n      __cm_(0),\n      __owns_eb_(false),\n      __owns_ib_(false),\n      __always_noconv_(__cv_ ? __cv_->always_noconv() : false)\n{\n    setbuf(0, 4096);\n}\n\ntemplate <class _Codecvt, class _Elem, class _Tr>\nwbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()\n{\n    __close();\n    delete __cv_;\n    if (__owns_eb_)\n        delete [] __extbuf_;\n    if (__owns_ib_)\n        delete [] __intbuf_;\n}\n\ntemplate <class _Codecvt, class _Elem, class _Tr>\ntypename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type\nwbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()\n{\n    if (__cv_ == 0 || __bufptr_ == 0)\n        return traits_type::eof();\n    bool __initial = __read_mode();\n    char_type __1buf;\n    if (this->gptr() == 0)\n        this->setg(&__1buf, &__1buf+1, &__1buf+1);\n    const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);\n    int_type __c = traits_type::eof();\n    if (this->gptr() == this->egptr())\n    {\n        memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));\n        if (__always_noconv_)\n        {\n            streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);\n            __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);\n            if (__nmemb != 0)\n            {\n                this->setg(this->eback(),\n                           this->eback() + __unget_sz,\n                           this->eback() + __unget_sz + __nmemb);\n                __c = *this->gptr();\n            }\n        }\n        else\n        {\n            memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);\n            __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);\n            __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);\n            streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),\n                                 static_cast<streamsize>(__extbufend_ - __extbufnext_));\n            codecvt_base::result __r;\n            state_type __svs = __st_;\n            streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);\n            if (__nr != 0)\n            {\n                __extbufend_ = __extbufnext_ + __nr;\n                char_type*  __inext;\n                __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,\n                                       this->eback() + __unget_sz,\n                                       this->egptr(), __inext);\n                if (__r == codecvt_base::noconv)\n                {\n                    this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);\n                    __c = *this->gptr();\n                }\n                else if (__inext != this->eback() + __unget_sz)\n                {\n                    this->setg(this->eback(), this->eback() + __unget_sz, __inext);\n                    __c = *this->gptr();\n                }\n            }\n        }\n    }\n    else\n        __c = *this->gptr();\n    if (this->eback() == &__1buf)\n        this->setg(0, 0, 0);\n    return __c;\n}\n\ntemplate <class _Codecvt, class _Elem, class _Tr>\ntypename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type\nwbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)\n{\n    if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())\n    {\n        if (traits_type::eq_int_type(__c, traits_type::eof()))\n        {\n            this->gbump(-1);\n            return traits_type::not_eof(__c);\n        }\n        if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))\n        {\n            this->gbump(-1);\n            *this->gptr() = traits_type::to_char_type(__c);\n            return __c;\n        }\n    }\n    return traits_type::eof();\n}\n\ntemplate <class _Codecvt, class _Elem, class _Tr>\ntypename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type\nwbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)\n{\n    if (__cv_ == 0 || __bufptr_ == 0)\n        return traits_type::eof();\n    __write_mode();\n    char_type __1buf;\n    char_type* __pb_save = this->pbase();\n    char_type* __epb_save = this->epptr();\n    if (!traits_type::eq_int_type(__c, traits_type::eof()))\n    {\n        if (this->pptr() == 0)\n            this->setp(&__1buf, &__1buf+1);\n        *this->pptr() = traits_type::to_char_type(__c);\n        this->pbump(1);\n    }\n    if (this->pptr() != this->pbase())\n    {\n        if (__always_noconv_)\n        {\n            streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());\n            if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)\n                return traits_type::eof();\n        }\n        else\n        {\n            char* __extbe = __extbuf_;\n            codecvt_base::result __r;\n            do\n            {\n                const char_type* __e;\n                __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,\n                                        __extbuf_, __extbuf_ + __ebs_, __extbe);\n                if (__e == this->pbase())\n                    return traits_type::eof();\n                if (__r == codecvt_base::noconv)\n                {\n                    streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());\n                    if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)\n                        return traits_type::eof();\n                }\n                else if (__r == codecvt_base::ok || __r == codecvt_base::partial)\n                {\n                    streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);\n                    if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)\n                        return traits_type::eof();\n                    if (__r == codecvt_base::partial)\n                    {\n                        this->setp((char_type*)__e, this->pptr());\n                        this->pbump(this->epptr() - this->pbase());\n                    }\n                }\n                else\n                    return traits_type::eof();\n            } while (__r == codecvt_base::partial);\n        }\n        this->setp(__pb_save, __epb_save);\n    }\n    return traits_type::not_eof(__c);\n}\n\ntemplate <class _Codecvt, class _Elem, class _Tr>\nbasic_streambuf<_Elem, _Tr>*\nwbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)\n{\n    this->setg(0, 0, 0);\n    this->setp(0, 0);\n    if (__owns_eb_)\n        delete [] __extbuf_;\n    if (__owns_ib_)\n        delete [] __intbuf_;\n    __ebs_ = __n;\n    if (__ebs_ > sizeof(__extbuf_min_))\n    {\n        if (__always_noconv_ && __s)\n        {\n            __extbuf_ = (char*)__s;\n            __owns_eb_ = false;\n        }\n        else\n        {\n            __extbuf_ = new char[__ebs_];\n            __owns_eb_ = true;\n        }\n    }\n    else\n    {\n        __extbuf_ = __extbuf_min_;\n        __ebs_ = sizeof(__extbuf_min_);\n        __owns_eb_ = false;\n    }\n    if (!__always_noconv_)\n    {\n        __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));\n        if (__s && __ibs_ >= sizeof(__extbuf_min_))\n        {\n            __intbuf_ = __s;\n            __owns_ib_ = false;\n        }\n        else\n        {\n            __intbuf_ = new char_type[__ibs_];\n            __owns_ib_ = true;\n        }\n    }\n    else\n    {\n        __ibs_ = 0;\n        __intbuf_ = 0;\n        __owns_ib_ = false;\n    }\n    return this;\n}\n\ntemplate <class _Codecvt, class _Elem, class _Tr>\ntypename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type\nwbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,\n                                        ios_base::openmode __om)\n{\n    int __width = __cv_->encoding();\n    if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())\n        return pos_type(off_type(-1));\n    // __width > 0 || __off == 0\n    switch (__way)\n    {\n    case ios_base::beg:\n        break;\n    case ios_base::cur:\n        break;\n    case ios_base::end:\n        break;\n    default:\n        return pos_type(off_type(-1));\n    }\n    pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);\n    __r.state(__st_);\n    return __r;\n}\n\ntemplate <class _Codecvt, class _Elem, class _Tr>\ntypename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type\nwbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)\n{\n    if (__cv_ == 0 || __bufptr_ == 0 || sync())\n        return pos_type(off_type(-1));\n    if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))\n        return pos_type(off_type(-1));\n    return __sp;\n}\n\ntemplate <class _Codecvt, class _Elem, class _Tr>\nint\nwbuffer_convert<_Codecvt, _Elem, _Tr>::sync()\n{\n    if (__cv_ == 0 || __bufptr_ == 0)\n        return 0;\n    if (__cm_ & ios_base::out)\n    {\n        if (this->pptr() != this->pbase())\n            if (overflow() == traits_type::eof())\n                return -1;\n        codecvt_base::result __r;\n        do\n        {\n            char* __extbe;\n            __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);\n            streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);\n            if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)\n                return -1;\n        } while (__r == codecvt_base::partial);\n        if (__r == codecvt_base::error)\n            return -1;\n        if (__bufptr_->pubsync())\n            return -1;\n    }\n    else if (__cm_ & ios_base::in)\n    {\n        off_type __c;\n        if (__always_noconv_)\n            __c = this->egptr() - this->gptr();\n        else\n        {\n            int __width = __cv_->encoding();\n            __c = __extbufend_ - __extbufnext_;\n            if (__width > 0)\n                __c += __width * (this->egptr() - this->gptr());\n            else\n            {\n                if (this->gptr() != this->egptr())\n                {\n                    reverse(this->gptr(), this->egptr());\n                    codecvt_base::result __r;\n                    const char_type* __e = this->gptr();\n                    char* __extbe;\n                    do\n                    {\n                        __r = __cv_->out(__st_, __e, this->egptr(), __e,\n                                         __extbuf_, __extbuf_ + __ebs_, __extbe);\n                        switch (__r)\n                        {\n                        case codecvt_base::noconv:\n                            __c += this->egptr() - this->gptr();\n                            break;\n                        case codecvt_base::ok:\n                        case codecvt_base::partial:\n                            __c += __extbe - __extbuf_;\n                            break;\n                        default:\n                            return -1;\n                        }\n                    } while (__r == codecvt_base::partial);\n                }\n            }\n        }\n        if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))\n            return -1;\n        this->setg(0, 0, 0);\n        __cm_ = 0;\n    }\n    return 0;\n}\n\ntemplate <class _Codecvt, class _Elem, class _Tr>\nbool\nwbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()\n{\n    if (!(__cm_ & ios_base::in))\n    {\n        this->setp(0, 0);\n        if (__always_noconv_)\n            this->setg((char_type*)__extbuf_,\n                       (char_type*)__extbuf_ + __ebs_,\n                       (char_type*)__extbuf_ + __ebs_);\n        else\n            this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);\n        __cm_ = ios_base::in;\n        return true;\n    }\n    return false;\n}\n\ntemplate <class _Codecvt, class _Elem, class _Tr>\nvoid\nwbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()\n{\n    if (!(__cm_ & ios_base::out))\n    {\n        this->setg(0, 0, 0);\n        if (__ebs_ > sizeof(__extbuf_min_))\n        {\n            if (__always_noconv_)\n                this->setp((char_type*)__extbuf_,\n                           (char_type*)__extbuf_ + (__ebs_ - 1));\n            else\n                this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));\n        }\n        else\n            this->setp(0, 0);\n        __cm_ = ios_base::out;\n    }\n}\n\ntemplate <class _Codecvt, class _Elem, class _Tr>\nwbuffer_convert<_Codecvt, _Elem, _Tr>*\nwbuffer_convert<_Codecvt, _Elem, _Tr>::__close()\n{\n    wbuffer_convert* __rt = 0;\n    if (__cv_ != 0 && __bufptr_ != 0)\n    {\n        __rt = this;\n        if ((__cm_ & ios_base::out) && sync())\n            __rt = 0;\n    }\n    return __rt;\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_LOCALE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/map",
    "content": "// -*- C++ -*-\n//===----------------------------- map ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_MAP\n#define _LIBCPP_MAP\n\n/*\n\n    map synopsis\n\nnamespace std\n{\n\ntemplate <class Key, class T, class Compare = less<Key>,\n          class Allocator = allocator<pair<const Key, T>>>\nclass map\n{\npublic:\n    // types:\n    typedef Key                                      key_type;\n    typedef T                                        mapped_type;\n    typedef pair<const key_type, mapped_type>        value_type;\n    typedef Compare                                  key_compare;\n    typedef Allocator                                allocator_type;\n    typedef typename allocator_type::reference       reference;\n    typedef typename allocator_type::const_reference const_reference;\n    typedef typename allocator_type::pointer         pointer;\n    typedef typename allocator_type::const_pointer   const_pointer;\n    typedef typename allocator_type::size_type       size_type;\n    typedef typename allocator_type::difference_type difference_type;\n\n    typedef implementation-defined                   iterator;\n    typedef implementation-defined                   const_iterator;\n    typedef std::reverse_iterator<iterator>          reverse_iterator;\n    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;\n\n    class value_compare\n        : public binary_function<value_type, value_type, bool>\n    {\n        friend class map;\n    protected:\n        key_compare comp;\n\n        value_compare(key_compare c);\n    public:\n        bool operator()(const value_type& x, const value_type& y) const;\n    };\n\n    // construct/copy/destroy:\n    map()\n        noexcept(\n            is_nothrow_default_constructible<allocator_type>::value &&\n            is_nothrow_default_constructible<key_compare>::value &&\n            is_nothrow_copy_constructible<key_compare>::value);\n    explicit map(const key_compare& comp);\n    map(const key_compare& comp, const allocator_type& a);\n    template <class InputIterator>\n        map(InputIterator first, InputIterator last,\n            const key_compare& comp = key_compare());\n    template <class InputIterator>\n        map(InputIterator first, InputIterator last,\n            const key_compare& comp, const allocator_type& a);\n    map(const map& m);\n    map(map&& m)\n        noexcept(\n            is_nothrow_move_constructible<allocator_type>::value &&\n            is_nothrow_move_constructible<key_compare>::value);\n    explicit map(const allocator_type& a);\n    map(const map& m, const allocator_type& a);\n    map(map&& m, const allocator_type& a);\n    map(initializer_list<value_type> il, const key_compare& comp = key_compare());\n    map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a);\n    template <class InputIterator>\n        map(InputIterator first, InputIterator last, const allocator_type& a)\n            : map(first, last, Compare(), a) {}  // C++14\n    map(initializer_list<value_type> il, const allocator_type& a)\n        : map(il, Compare(), a) {}  // C++14\n   ~map();\n\n    map& operator=(const map& m);\n    map& operator=(map&& m)\n        noexcept(\n            allocator_type::propagate_on_container_move_assignment::value &&\n            is_nothrow_move_assignable<allocator_type>::value &&\n            is_nothrow_move_assignable<key_compare>::value);\n    map& operator=(initializer_list<value_type> il);\n\n    // iterators:\n          iterator begin() noexcept;\n    const_iterator begin() const noexcept;\n          iterator end() noexcept;\n    const_iterator end()   const noexcept;\n\n          reverse_iterator rbegin() noexcept;\n    const_reverse_iterator rbegin() const noexcept;\n          reverse_iterator rend() noexcept;\n    const_reverse_iterator rend()   const noexcept;\n\n    const_iterator         cbegin()  const noexcept;\n    const_iterator         cend()    const noexcept;\n    const_reverse_iterator crbegin() const noexcept;\n    const_reverse_iterator crend()   const noexcept;\n\n    // capacity:\n    bool      empty()    const noexcept;\n    size_type size()     const noexcept;\n    size_type max_size() const noexcept;\n\n    // element access:\n    mapped_type& operator[](const key_type& k);\n    mapped_type& operator[](key_type&& k);\n\n          mapped_type& at(const key_type& k);\n    const mapped_type& at(const key_type& k) const;\n\n    // modifiers:\n    template <class... Args>\n        pair<iterator, bool> emplace(Args&&... args);\n    template <class... Args>\n        iterator emplace_hint(const_iterator position, Args&&... args);\n    pair<iterator, bool> insert(const value_type& v);\n    template <class P>\n        pair<iterator, bool> insert(P&& p);\n    iterator insert(const_iterator position, const value_type& v);\n    template <class P>\n        iterator insert(const_iterator position, P&& p);\n    template <class InputIterator>\n        void insert(InputIterator first, InputIterator last);\n    void insert(initializer_list<value_type> il);\n\n    template <class... Args>\n        pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);          // C++17\n    template <class... Args>\n        pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);               // C++17\n    template <class... Args>\n        iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17\n    template <class... Args>\n        iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);      // C++17\n    template <class M>\n        pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);            // C++17\n    template <class M>\n        pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);                 // C++17\n    template <class M>\n        iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);   // C++17\n    template <class M>\n        iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);        // C++17\n\n    iterator  erase(const_iterator position);\n    iterator  erase(iterator position); // C++14\n    size_type erase(const key_type& k);\n    iterator  erase(const_iterator first, const_iterator last);\n    void clear() noexcept;\n\n    void swap(map& m)\n        noexcept(allocator_traits<allocator_type>::is_always_equal::value &&\n            __is_nothrow_swappable<key_compare>::value); // C++17\n\n    // observers:\n    allocator_type get_allocator() const noexcept;\n    key_compare    key_comp()      const;\n    value_compare  value_comp()    const;\n\n    // map operations:\n          iterator find(const key_type& k);\n    const_iterator find(const key_type& k) const;\n    template<typename K>\n        iterator find(const K& x);              // C++14\n    template<typename K>\n        const_iterator find(const K& x) const;  // C++14\n    template<typename K>\n      size_type count(const K& x) const;        // C++14\n\n    size_type      count(const key_type& k) const;\n          iterator lower_bound(const key_type& k);\n    const_iterator lower_bound(const key_type& k) const;\n    template<typename K>\n        iterator lower_bound(const K& x);              // C++14\n    template<typename K>\n        const_iterator lower_bound(const K& x) const;  // C++14\n\n          iterator upper_bound(const key_type& k);\n    const_iterator upper_bound(const key_type& k) const;\n    template<typename K>\n        iterator upper_bound(const K& x);              // C++14\n    template<typename K>\n        const_iterator upper_bound(const K& x) const;  // C++14\n\n    pair<iterator,iterator>             equal_range(const key_type& k);\n    pair<const_iterator,const_iterator> equal_range(const key_type& k) const;\n    template<typename K>\n        pair<iterator,iterator>             equal_range(const K& x);        // C++14\n    template<typename K>\n        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14\n};\n\ntemplate <class Key, class T, class Compare, class Allocator>\nbool\noperator==(const map<Key, T, Compare, Allocator>& x,\n           const map<Key, T, Compare, Allocator>& y);\n\ntemplate <class Key, class T, class Compare, class Allocator>\nbool\noperator< (const map<Key, T, Compare, Allocator>& x,\n           const map<Key, T, Compare, Allocator>& y);\n\ntemplate <class Key, class T, class Compare, class Allocator>\nbool\noperator!=(const map<Key, T, Compare, Allocator>& x,\n           const map<Key, T, Compare, Allocator>& y);\n\ntemplate <class Key, class T, class Compare, class Allocator>\nbool\noperator> (const map<Key, T, Compare, Allocator>& x,\n           const map<Key, T, Compare, Allocator>& y);\n\ntemplate <class Key, class T, class Compare, class Allocator>\nbool\noperator>=(const map<Key, T, Compare, Allocator>& x,\n           const map<Key, T, Compare, Allocator>& y);\n\ntemplate <class Key, class T, class Compare, class Allocator>\nbool\noperator<=(const map<Key, T, Compare, Allocator>& x,\n           const map<Key, T, Compare, Allocator>& y);\n\n// specialized algorithms:\ntemplate <class Key, class T, class Compare, class Allocator>\nvoid\nswap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y)\n    noexcept(noexcept(x.swap(y)));\n\ntemplate <class Key, class T, class Compare = less<Key>,\n          class Allocator = allocator<pair<const Key, T>>>\nclass multimap\n{\npublic:\n    // types:\n    typedef Key                                      key_type;\n    typedef T                                        mapped_type;\n    typedef pair<const key_type,mapped_type>         value_type;\n    typedef Compare                                  key_compare;\n    typedef Allocator                                allocator_type;\n    typedef typename allocator_type::reference       reference;\n    typedef typename allocator_type::const_reference const_reference;\n    typedef typename allocator_type::size_type       size_type;\n    typedef typename allocator_type::difference_type difference_type;\n    typedef typename allocator_type::pointer         pointer;\n    typedef typename allocator_type::const_pointer   const_pointer;\n\n    typedef implementation-defined                   iterator;\n    typedef implementation-defined                   const_iterator;\n    typedef std::reverse_iterator<iterator>          reverse_iterator;\n    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;\n\n    class value_compare\n        : public binary_function<value_type,value_type,bool>\n    {\n        friend class multimap;\n    protected:\n        key_compare comp;\n        value_compare(key_compare c);\n    public:\n        bool operator()(const value_type& x, const value_type& y) const;\n    };\n\n    // construct/copy/destroy:\n    multimap()\n        noexcept(\n            is_nothrow_default_constructible<allocator_type>::value &&\n            is_nothrow_default_constructible<key_compare>::value &&\n            is_nothrow_copy_constructible<key_compare>::value);\n    explicit multimap(const key_compare& comp);\n    multimap(const key_compare& comp, const allocator_type& a);\n    template <class InputIterator>\n        multimap(InputIterator first, InputIterator last, const key_compare& comp);\n    template <class InputIterator>\n        multimap(InputIterator first, InputIterator last, const key_compare& comp,\n                 const allocator_type& a);\n    multimap(const multimap& m);\n    multimap(multimap&& m)\n        noexcept(\n            is_nothrow_move_constructible<allocator_type>::value &&\n            is_nothrow_move_constructible<key_compare>::value);\n    explicit multimap(const allocator_type& a);\n    multimap(const multimap& m, const allocator_type& a);\n    multimap(multimap&& m, const allocator_type& a);\n    multimap(initializer_list<value_type> il, const key_compare& comp = key_compare());\n    multimap(initializer_list<value_type> il, const key_compare& comp,\n             const allocator_type& a);\n    template <class InputIterator>\n        multimap(InputIterator first, InputIterator last, const allocator_type& a)\n            : multimap(first, last, Compare(), a) {} // C++14\n    multimap(initializer_list<value_type> il, const allocator_type& a)\n        : multimap(il, Compare(), a) {} // C++14\n    ~multimap();\n\n    multimap& operator=(const multimap& m);\n    multimap& operator=(multimap&& m)\n        noexcept(\n            allocator_type::propagate_on_container_move_assignment::value &&\n            is_nothrow_move_assignable<allocator_type>::value &&\n            is_nothrow_move_assignable<key_compare>::value);\n    multimap& operator=(initializer_list<value_type> il);\n\n    // iterators:\n          iterator begin() noexcept;\n    const_iterator begin() const noexcept;\n          iterator end() noexcept;\n    const_iterator end()   const noexcept;\n\n          reverse_iterator rbegin() noexcept;\n    const_reverse_iterator rbegin() const noexcept;\n          reverse_iterator rend() noexcept;\n    const_reverse_iterator rend()   const noexcept;\n\n    const_iterator         cbegin()  const noexcept;\n    const_iterator         cend()    const noexcept;\n    const_reverse_iterator crbegin() const noexcept;\n    const_reverse_iterator crend()   const noexcept;\n\n    // capacity:\n    bool      empty()    const noexcept;\n    size_type size()     const noexcept;\n    size_type max_size() const noexcept;\n\n    // modifiers:\n    template <class... Args>\n        iterator emplace(Args&&... args);\n    template <class... Args>\n        iterator emplace_hint(const_iterator position, Args&&... args);\n    iterator insert(const value_type& v);\n    template <class P>\n        iterator insert(P&& p);\n    iterator insert(const_iterator position, const value_type& v);\n    template <class P>\n        iterator insert(const_iterator position, P&& p);\n    template <class InputIterator>\n        void insert(InputIterator first, InputIterator last);\n    void insert(initializer_list<value_type> il);\n\n    iterator  erase(const_iterator position);\n    iterator  erase(iterator position); // C++14\n    size_type erase(const key_type& k);\n    iterator  erase(const_iterator first, const_iterator last);\n    void clear() noexcept;\n\n    void swap(multimap& m)\n        noexcept(allocator_traits<allocator_type>::is_always_equal::value &&\n            __is_nothrow_swappable<key_compare>::value); // C++17\n\n    // observers:\n    allocator_type get_allocator() const noexcept;\n    key_compare    key_comp()      const;\n    value_compare  value_comp()    const;\n\n    // map operations:\n          iterator find(const key_type& k);\n    const_iterator find(const key_type& k) const;\n    template<typename K>\n        iterator find(const K& x);              // C++14\n    template<typename K>\n        const_iterator find(const K& x) const;  // C++14\n    template<typename K>\n      size_type count(const K& x) const;        // C++14\n\n    size_type      count(const key_type& k) const;\n          iterator lower_bound(const key_type& k);\n    const_iterator lower_bound(const key_type& k) const;\n    template<typename K>\n        iterator lower_bound(const K& x);              // C++14\n    template<typename K>\n        const_iterator lower_bound(const K& x) const;  // C++14\n\n          iterator upper_bound(const key_type& k);\n    const_iterator upper_bound(const key_type& k) const;\n    template<typename K>\n        iterator upper_bound(const K& x);              // C++14\n    template<typename K>\n        const_iterator upper_bound(const K& x) const;  // C++14\n\n    pair<iterator,iterator>             equal_range(const key_type& k);\n    pair<const_iterator,const_iterator> equal_range(const key_type& k) const;\n    template<typename K>\n        pair<iterator,iterator>             equal_range(const K& x);        // C++14\n    template<typename K>\n        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14\n};\n\ntemplate <class Key, class T, class Compare, class Allocator>\nbool\noperator==(const multimap<Key, T, Compare, Allocator>& x,\n           const multimap<Key, T, Compare, Allocator>& y);\n\ntemplate <class Key, class T, class Compare, class Allocator>\nbool\noperator< (const multimap<Key, T, Compare, Allocator>& x,\n           const multimap<Key, T, Compare, Allocator>& y);\n\ntemplate <class Key, class T, class Compare, class Allocator>\nbool\noperator!=(const multimap<Key, T, Compare, Allocator>& x,\n           const multimap<Key, T, Compare, Allocator>& y);\n\ntemplate <class Key, class T, class Compare, class Allocator>\nbool\noperator> (const multimap<Key, T, Compare, Allocator>& x,\n           const multimap<Key, T, Compare, Allocator>& y);\n\ntemplate <class Key, class T, class Compare, class Allocator>\nbool\noperator>=(const multimap<Key, T, Compare, Allocator>& x,\n           const multimap<Key, T, Compare, Allocator>& y);\n\ntemplate <class Key, class T, class Compare, class Allocator>\nbool\noperator<=(const multimap<Key, T, Compare, Allocator>& x,\n           const multimap<Key, T, Compare, Allocator>& y);\n\n// specialized algorithms:\ntemplate <class Key, class T, class Compare, class Allocator>\nvoid\nswap(multimap<Key, T, Compare, Allocator>& x,\n     multimap<Key, T, Compare, Allocator>& y)\n    noexcept(noexcept(x.swap(y)));\n\n}  // std\n\n*/\n\n#include <__config>\n#include <__tree>\n#include <iterator>\n#include <memory>\n#include <utility>\n#include <functional>\n#include <initializer_list>\n#include <type_traits>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Key, class _CP, class _Compare,\n          bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value\n         >\nclass __map_value_compare\n    : private _Compare\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __map_value_compare()\n        _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)\n        : _Compare() {}\n    _LIBCPP_INLINE_VISIBILITY\n    __map_value_compare(_Compare c)\n        _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)\n        : _Compare(c) {}\n    _LIBCPP_INLINE_VISIBILITY\n    const _Compare& key_comp() const _NOEXCEPT {return *this;}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _CP& __x, const _CP& __y) const\n        {return static_cast<const _Compare&>(*this)(__x.__cc.first, __y.__cc.first);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _CP& __x, const _Key& __y) const\n        {return static_cast<const _Compare&>(*this)(__x.__cc.first, __y);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Key& __x, const _CP& __y) const\n        {return static_cast<const _Compare&>(*this)(__x, __y.__cc.first);}\n    void swap(__map_value_compare&__y)\n        _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)\n    {\n        using _VSTD::swap;\n        swap(static_cast<const _Compare&>(*this), static_cast<const _Compare&>(__y));\n    }\n\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type\n    operator () ( const _K2& __x, const _CP& __y ) const\n        {return static_cast<const _Compare&>(*this) (__x, __y.__cc.first);}\n\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type\n    operator () (const _CP& __x, const _K2& __y) const\n        {return static_cast<const _Compare&>(*this) (__x.__cc.first, __y);}\n#endif\n};\n\ntemplate <class _Key, class _CP, class _Compare>\nclass __map_value_compare<_Key, _CP, _Compare, false>\n{\n    _Compare comp;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __map_value_compare()\n        _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)\n        : comp() {}\n    _LIBCPP_INLINE_VISIBILITY\n    __map_value_compare(_Compare c)\n        _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)\n        : comp(c) {}\n    _LIBCPP_INLINE_VISIBILITY\n    const _Compare& key_comp() const _NOEXCEPT {return comp;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _CP& __x, const _CP& __y) const\n        {return comp(__x.__cc.first, __y.__cc.first);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _CP& __x, const _Key& __y) const\n        {return comp(__x.__cc.first, __y);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Key& __x, const _CP& __y) const\n        {return comp(__x, __y.__cc.first);}\n    void swap(__map_value_compare&__y)\n        _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)\n    {\n        using _VSTD::swap;\n        swap(comp, __y.comp);\n    }\n    \n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type\n    operator () ( const _K2& __x, const _CP& __y ) const\n        {return comp (__x, __y.__cc.first);}\n\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type\n    operator () (const _CP& __x, const _K2& __y) const\n        {return comp (__x.__cc.first, __y);}\n#endif\n};\n\ntemplate <class _Key, class _CP, class _Compare, bool __b>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(__map_value_compare<_Key, _CP, _Compare, __b>& __x,\n     __map_value_compare<_Key, _CP, _Compare, __b>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Allocator>\nclass __map_node_destructor\n{\n    typedef _Allocator                          allocator_type;\n    typedef allocator_traits<allocator_type>    __alloc_traits;\n    typedef typename __alloc_traits::value_type::value_type value_type;\npublic:\n    typedef typename __alloc_traits::pointer    pointer;\nprivate:\n    typedef typename value_type::value_type::first_type     first_type;\n    typedef typename value_type::value_type::second_type    second_type;\n\n    allocator_type& __na_;\n\n    __map_node_destructor& operator=(const __map_node_destructor&);\n\npublic:\n    bool __first_constructed;\n    bool __second_constructed;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __map_node_destructor(allocator_type& __na) _NOEXCEPT\n        : __na_(__na),\n          __first_constructed(false),\n          __second_constructed(false)\n        {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    __map_node_destructor(__tree_node_destructor<allocator_type>&& __x) _NOEXCEPT\n        : __na_(__x.__na_),\n          __first_constructed(__x.__value_constructed),\n          __second_constructed(__x.__value_constructed)\n        {\n            __x.__value_constructed = false;\n        }\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    void operator()(pointer __p) _NOEXCEPT\n    {\n        if (__second_constructed)\n            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.second));\n        if (__first_constructed)\n            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.first));\n        if (__p)\n            __alloc_traits::deallocate(__na_, __p, 1);\n    }\n};\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\n    class map;\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\n    class multimap;\ntemplate <class _TreeIterator> class __map_const_iterator;\n\n#if __cplusplus >= 201103L\n\ntemplate <class _Key, class _Tp>\nunion __value_type\n{\n    typedef _Key                                     key_type;\n    typedef _Tp                                      mapped_type;\n    typedef pair<const key_type, mapped_type>        value_type;\n    typedef pair<key_type, mapped_type>              __nc_value_type;\n\n    value_type __cc;\n    __nc_value_type __nc;\n\n    template <class ..._Args>\n    _LIBCPP_INLINE_VISIBILITY\n    __value_type(_Args&& ...__args)\n        : __cc(std::forward<_Args>(__args)...) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __value_type(const __value_type& __v)\n        : __cc(__v.__cc) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __value_type(__value_type& __v)\n        : __cc(__v.__cc) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __value_type(__value_type&& __v)\n        : __nc(std::move(__v.__nc)) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __value_type& operator=(const __value_type& __v)\n        {__nc = __v.__cc; return *this;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __value_type& operator=(__value_type&& __v)\n        {__nc = std::move(__v.__nc); return *this;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    ~__value_type() {__cc.~value_type();}\n};\n\n#else\n\ntemplate <class _Key, class _Tp>\nstruct __value_type\n{\n    typedef _Key                                     key_type;\n    typedef _Tp                                      mapped_type;\n    typedef pair<const key_type, mapped_type>        value_type;\n\n    value_type __cc;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __value_type() {}\n\n    template <class _A0>\n    _LIBCPP_INLINE_VISIBILITY\n    __value_type(const _A0& __a0)\n        : __cc(__a0) {}\n\n    template <class _A0, class _A1>\n    _LIBCPP_INLINE_VISIBILITY\n    __value_type(const _A0& __a0, const _A1& __a1)\n        : __cc(__a0, __a1) {}\n};\n\n#endif\n\ntemplate <class _Tp>\nstruct __extract_key_value_types;\n\ntemplate <class _Key, class _Tp>\nstruct __extract_key_value_types<__value_type<_Key, _Tp> >\n{\n  typedef _Key const __key_type;\n  typedef _Tp        __mapped_type;\n};\n\ntemplate <class _TreeIterator>\nclass _LIBCPP_TYPE_VIS_ONLY __map_iterator\n{\n    _TreeIterator __i_;\n\n    typedef typename _TreeIterator::__pointer_traits             __pointer_traits;\n    typedef typename _TreeIterator::value_type __value_type;\n    typedef typename __extract_key_value_types<__value_type>::__key_type    __key_type;\n    typedef typename __extract_key_value_types<__value_type>::__mapped_type __mapped_type;\npublic:\n    typedef bidirectional_iterator_tag                           iterator_category;\n    typedef pair<__key_type, __mapped_type>                      value_type;\n    typedef typename _TreeIterator::difference_type              difference_type;\n    typedef value_type&                                          reference;\n    typedef typename __pointer_traits::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<value_type>\n#else\n            rebind<value_type>::other\n#endif\n                                                                 pointer;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __map_iterator() _NOEXCEPT {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    reference operator*() const {return __i_->__cc;}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __map_iterator& operator++() {++__i_; return *this;}\n    _LIBCPP_INLINE_VISIBILITY\n    __map_iterator operator++(int)\n    {\n        __map_iterator __t(*this);\n        ++(*this);\n        return __t;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __map_iterator& operator--() {--__i_; return *this;}\n    _LIBCPP_INLINE_VISIBILITY\n    __map_iterator operator--(int)\n    {\n        __map_iterator __t(*this);\n        --(*this);\n        return __t;\n    }\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const __map_iterator& __x, const __map_iterator& __y)\n        {return __x.__i_ == __y.__i_;}\n    friend \n    _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const __map_iterator& __x, const __map_iterator& __y)\n        {return __x.__i_ != __y.__i_;}\n\n    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;\n    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;\n};\n\ntemplate <class _TreeIterator>\nclass _LIBCPP_TYPE_VIS_ONLY __map_const_iterator\n{\n    _TreeIterator __i_;\n\n    typedef typename _TreeIterator::__pointer_traits             __pointer_traits;\n    typedef typename _TreeIterator::value_type __value_type;\n    typedef typename __extract_key_value_types<__value_type>::__key_type    __key_type;\n    typedef typename __extract_key_value_types<__value_type>::__mapped_type __mapped_type;\npublic:\n    typedef bidirectional_iterator_tag                           iterator_category;\n    typedef pair<__key_type, __mapped_type>                      value_type;\n    typedef typename _TreeIterator::difference_type              difference_type;\n    typedef const value_type&                                    reference;\n    typedef typename __pointer_traits::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<const value_type>\n#else\n            rebind<const value_type>::other\n#endif\n                                                                 pointer;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __map_const_iterator() _NOEXCEPT {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}\n    _LIBCPP_INLINE_VISIBILITY\n    __map_const_iterator(__map_iterator<\n        typename _TreeIterator::__non_const_iterator> __i) _NOEXCEPT\n        : __i_(__i.__i_) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    reference operator*() const {return __i_->__cc;}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __map_const_iterator& operator++() {++__i_; return *this;}\n    _LIBCPP_INLINE_VISIBILITY\n    __map_const_iterator operator++(int)\n    {\n        __map_const_iterator __t(*this);\n        ++(*this);\n        return __t;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __map_const_iterator& operator--() {--__i_; return *this;}\n    _LIBCPP_INLINE_VISIBILITY\n    __map_const_iterator operator--(int)\n    {\n        __map_const_iterator __t(*this);\n        --(*this);\n        return __t;\n    }\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const __map_const_iterator& __x, const __map_const_iterator& __y)\n        {return __x.__i_ == __y.__i_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y)\n        {return __x.__i_ != __y.__i_;}\n\n    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;\n    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;\n    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;\n};\n\ntemplate <class _Key, class _Tp, class _Compare = less<_Key>,\n          class _Allocator = allocator<pair<const _Key, _Tp> > >\nclass _LIBCPP_TYPE_VIS_ONLY map\n{\npublic:\n    // types:\n    typedef _Key                                     key_type;\n    typedef _Tp                                      mapped_type;\n    typedef pair<const key_type, mapped_type>        value_type;\n    typedef pair<key_type, mapped_type>              __nc_value_type;\n    typedef _Compare                                 key_compare;\n    typedef _Allocator                               allocator_type;\n    typedef value_type&                              reference;\n    typedef const value_type&                        const_reference;\n\n    class _LIBCPP_TYPE_VIS_ONLY value_compare\n        : public binary_function<value_type, value_type, bool>\n    {\n        friend class map;\n    protected:\n        key_compare comp;\n\n        _LIBCPP_INLINE_VISIBILITY value_compare(key_compare c) : comp(c) {}\n    public:\n        _LIBCPP_INLINE_VISIBILITY\n        bool operator()(const value_type& __x, const value_type& __y) const\n            {return comp(__x.first, __y.first);}\n    };\n\nprivate:\n\n    typedef _VSTD::__value_type<key_type, mapped_type>             __value_type;\n    typedef __map_value_compare<key_type, __value_type, key_compare> __vc;\n    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,\n                                                 __value_type>::type __allocator_type;\n    typedef __tree<__value_type, __vc, __allocator_type>   __base;\n    typedef typename __base::__node_traits                 __node_traits;\n    typedef allocator_traits<allocator_type>               __alloc_traits;\n\n    __base __tree_;\n\npublic:\n    typedef typename __alloc_traits::pointer               pointer;\n    typedef typename __alloc_traits::const_pointer         const_pointer;\n    typedef typename __alloc_traits::size_type             size_type;\n    typedef typename __alloc_traits::difference_type       difference_type;\n    typedef __map_iterator<typename __base::iterator>             iterator;\n    typedef __map_const_iterator<typename __base::const_iterator> const_iterator;\n    typedef _VSTD::reverse_iterator<iterator>               reverse_iterator;\n    typedef _VSTD::reverse_iterator<const_iterator>         const_reverse_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY\n    map()\n        _NOEXCEPT_(\n            is_nothrow_default_constructible<allocator_type>::value &&\n            is_nothrow_default_constructible<key_compare>::value &&\n            is_nothrow_copy_constructible<key_compare>::value)\n        : __tree_(__vc(key_compare())) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit map(const key_compare& __comp)\n        _NOEXCEPT_(\n            is_nothrow_default_constructible<allocator_type>::value &&\n            is_nothrow_copy_constructible<key_compare>::value)\n        : __tree_(__vc(__comp)) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit map(const key_compare& __comp, const allocator_type& __a)\n        : __tree_(__vc(__comp), __a) {}\n\n    template <class _InputIterator>\n    _LIBCPP_INLINE_VISIBILITY\n        map(_InputIterator __f, _InputIterator __l,\n            const key_compare& __comp = key_compare())\n        : __tree_(__vc(__comp))\n        {\n            insert(__f, __l);\n        }\n\n    template <class _InputIterator>\n    _LIBCPP_INLINE_VISIBILITY\n        map(_InputIterator __f, _InputIterator __l,\n            const key_compare& __comp, const allocator_type& __a)\n        : __tree_(__vc(__comp), __a)\n        {\n            insert(__f, __l);\n        }\n\n#if _LIBCPP_STD_VER > 11\n    template <class _InputIterator>\n    _LIBCPP_INLINE_VISIBILITY \n    map(_InputIterator __f, _InputIterator __l, const allocator_type& __a)\n        : map(__f, __l, key_compare(), __a) {}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    map(const map& __m)\n        : __tree_(__m.__tree_)\n        {\n            insert(__m.begin(), __m.end());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    map& operator=(const map& __m)\n        {\n#if __cplusplus >= 201103L\n            __tree_ = __m.__tree_;\n#else\n            if (this != &__m) {\n                __tree_.clear();\n                __tree_.value_comp() = __m.__tree_.value_comp();\n                __tree_.__copy_assign_alloc(__m.__tree_);\n                insert(__m.begin(), __m.end());\n            }\n#endif\n            return *this;\n        }\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    map(map&& __m)\n        _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)\n        : __tree_(_VSTD::move(__m.__tree_))\n        {\n        }\n\n    map(map&& __m, const allocator_type& __a);\n\n    _LIBCPP_INLINE_VISIBILITY\n    map& operator=(map&& __m)\n        _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)\n        {\n            __tree_ = _VSTD::move(__m.__tree_);\n            return *this;\n        }\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    map(initializer_list<value_type> __il, const key_compare& __comp = key_compare())\n        : __tree_(__vc(__comp))\n        {\n            insert(__il.begin(), __il.end());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    map(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)\n        : __tree_(__vc(__comp), __a)\n        {\n            insert(__il.begin(), __il.end());\n        }\n\n#if _LIBCPP_STD_VER > 11\n    _LIBCPP_INLINE_VISIBILITY \n    map(initializer_list<value_type> __il, const allocator_type& __a)\n        : map(__il, key_compare(), __a) {}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    map& operator=(initializer_list<value_type> __il)\n        {\n            __tree_.__assign_unique(__il.begin(), __il.end());\n            return *this;\n        }\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit map(const allocator_type& __a)\n        : __tree_(__a)\n        {\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    map(const map& __m, const allocator_type& __a)\n        : __tree_(__m.__tree_.value_comp(), __a)\n        {\n            insert(__m.begin(), __m.end());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n          iterator begin() _NOEXCEPT {return __tree_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin() const _NOEXCEPT {return __tree_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n          iterator end() _NOEXCEPT {return __tree_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end() const _NOEXCEPT {return __tree_.end();}\n\n    _LIBCPP_INLINE_VISIBILITY\n          reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rbegin() const _NOEXCEPT\n        {return const_reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n          reverse_iterator rend() _NOEXCEPT\n            {return       reverse_iterator(begin());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rend() const _NOEXCEPT\n        {return const_reverse_iterator(begin());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cbegin() const _NOEXCEPT {return begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cend() const _NOEXCEPT {return end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crend() const _NOEXCEPT {return rend();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool      empty() const _NOEXCEPT {return __tree_.size() == 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const _NOEXCEPT {return __tree_.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const _NOEXCEPT {return __tree_.max_size();}\n\n    mapped_type& operator[](const key_type& __k);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    mapped_type& operator[](key_type&& __k);\n#endif\n\n          mapped_type& at(const key_type& __k);\n    const mapped_type& at(const key_type& __k) const;\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();}\n    _LIBCPP_INLINE_VISIBILITY\n    key_compare    key_comp()      const {return __tree_.value_comp().key_comp();}\n    _LIBCPP_INLINE_VISIBILITY\n    value_compare  value_comp()    const {return value_compare(__tree_.value_comp().key_comp());}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n    template <class ..._Args>\n        pair<iterator, bool>\n        emplace(_Args&& ...__args);\n\n    template <class ..._Args>\n        iterator\n        emplace_hint(const_iterator __p, _Args&& ...__args);\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n    template <class _Pp,\n              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>\n        _LIBCPP_INLINE_VISIBILITY\n        pair<iterator, bool> insert(_Pp&& __p)\n            {return __tree_.__insert_unique(_VSTD::forward<_Pp>(__p));}\n\n    template <class _Pp,\n              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator insert(const_iterator __pos, _Pp&& __p)\n            {return __tree_.__insert_unique(__pos.__i_, _VSTD::forward<_Pp>(__p));}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, bool>\n        insert(const value_type& __v) {return __tree_.__insert_unique(__v);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator\n        insert(const_iterator __p, const value_type& __v)\n            {return __tree_.__insert_unique(__p.__i_, __v);}\n\n    template <class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        void insert(_InputIterator __f, _InputIterator __l)\n        {\n            for (const_iterator __e = cend(); __f != __l; ++__f)\n                insert(__e.__i_, *__f);\n        }\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    void insert(initializer_list<value_type> __il)\n        {insert(__il.begin(), __il.end());}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n#if _LIBCPP_STD_VER > 14\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args)\n    {\n        iterator __p = lower_bound(__k);\n        if ( __p != end() && !key_comp()(__k, __p->first))\n            return _VSTD::make_pair(__p, false);\n        else\n            return _VSTD::make_pair(\n                      emplace_hint(__p, \n                        _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), \n                        _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)),\n                      true);\n    }\n\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args)\n    {\n        iterator __p = lower_bound(__k);\n        if ( __p != end() && !key_comp()(__k, __p->first))\n            return _VSTD::make_pair(__p, false);\n        else\n            return _VSTD::make_pair(\n                      emplace_hint(__p, \n                        _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), \n                        _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)),\n                      true);\n    }\n\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args)\n    {\n        iterator __p = lower_bound(__k);\n        if ( __p != end() && !key_comp()(__k, __p->first))\n            return __p;\n        else\n            return emplace_hint(__p, \n                      _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), \n                      _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));\n    }\n\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args)\n    {\n        iterator __p = lower_bound(__k);\n        if ( __p != end() && !key_comp()(__k, __p->first))\n            return __p;\n        else\n            return emplace_hint(__p, \n                      _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), \n                      _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));\n    }\n\n    template <class _Vp>\n        _LIBCPP_INLINE_VISIBILITY\n        pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v)\n    {\n        iterator __p = lower_bound(__k);\n        if ( __p != end() && !key_comp()(__k, __p->first))\n        {\n            __p->second = _VSTD::forward<_Vp>(__v);\n            return _VSTD::make_pair(__p, false);\n        }\n        return _VSTD::make_pair(emplace_hint(__p, __k, _VSTD::forward<_Vp>(__v)), true);\n    }\n        \n    template <class _Vp>\n        _LIBCPP_INLINE_VISIBILITY\n        pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v)\n    {\n        iterator __p = lower_bound(__k);\n        if ( __p != end() && !key_comp()(__k, __p->first))\n        {\n            __p->second = _VSTD::forward<_Vp>(__v);\n            return _VSTD::make_pair(__p, false);\n        }\n        return _VSTD::make_pair(emplace_hint(__p, _VSTD::move(__k), _VSTD::forward<_Vp>(__v)), true);\n    }\n\n    template <class _Vp>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator insert_or_assign(const_iterator __h, const key_type& __k, _Vp&& __v)\n     {\n        iterator __p = lower_bound(__k);\n        if ( __p != end() && !key_comp()(__k, __p->first))\n        {\n            __p->second = _VSTD::forward<_Vp>(__v);\n            return __p;\n        }\n        return emplace_hint(__h, __k, _VSTD::forward<_Vp>(__v));\n     }\n\n    template <class _Vp>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator insert_or_assign(const_iterator __h, key_type&& __k, _Vp&& __v)\n     {\n        iterator __p = lower_bound(__k);\n        if ( __p != end() && !key_comp()(__k, __p->first))\n        {\n            __p->second = _VSTD::forward<_Vp>(__v);\n            return __p;\n        }\n        return emplace_hint(__h, _VSTD::move(__k), _VSTD::forward<_Vp>(__v));\n     }\n#endif\n#endif\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator erase(iterator __p)       {return __tree_.erase(__p.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type erase(const key_type& __k)\n        {return __tree_.__erase_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator  erase(const_iterator __f, const_iterator __l)\n        {return __tree_.erase(__f.__i_, __l.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() _NOEXCEPT {__tree_.clear();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(map& __m)\n        _NOEXCEPT_(__is_nothrow_swappable<__base>::value)\n        {__tree_.swap(__m.__tree_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator find(const key_type& __k)             {return __tree_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator find(const key_type& __k) const {return __tree_.find(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type\n    find(const _K2& __k)                           {return __tree_.find(__k);}\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type\n    find(const _K2& __k) const                     {return __tree_.find(__k);}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type      count(const key_type& __k) const\n        {return __tree_.__count_unique(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type\n    count(const _K2& __k) const {return __tree_.__count_unique(__k);}\n#endif\n    _LIBCPP_INLINE_VISIBILITY\n    iterator lower_bound(const key_type& __k)\n        {return __tree_.lower_bound(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator lower_bound(const key_type& __k) const\n        {return __tree_.lower_bound(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type\n    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}\n\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type\n    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator upper_bound(const key_type& __k)\n        {return __tree_.upper_bound(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator upper_bound(const key_type& __k) const\n        {return __tree_.upper_bound(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type\n    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type\n    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator,iterator> equal_range(const key_type& __k)\n        {return __tree_.__equal_range_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<const_iterator,const_iterator> equal_range(const key_type& __k) const\n        {return __tree_.__equal_range_unique(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type\n    equal_range(const _K2& __k)       {return __tree_.__equal_range_unique(__k);}\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type\n    equal_range(const _K2& __k) const {return __tree_.__equal_range_unique(__k);}\n#endif\n\nprivate:\n    typedef typename __base::__node                    __node;\n    typedef typename __base::__node_allocator          __node_allocator;\n    typedef typename __base::__node_pointer            __node_pointer;\n    typedef typename __base::__node_const_pointer      __node_const_pointer;\n    typedef typename __base::__node_base_pointer       __node_base_pointer;\n    typedef typename __base::__node_base_const_pointer __node_base_const_pointer;\n    typedef __map_node_destructor<__node_allocator> _Dp;\n    typedef unique_ptr<__node, _Dp> __node_holder;\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __node_holder __construct_node();\n    template <class _A0>\n        __node_holder __construct_node(_A0&& __a0);\n    __node_holder __construct_node_with_key(key_type&& __k);\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class _A0, class _A1, class ..._Args>\n        __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif\n    __node_holder __construct_node_with_key(const key_type& __k);\n\n    __node_base_pointer&\n        __find_equal_key(__node_base_pointer& __parent, const key_type& __k);\n    __node_base_const_pointer\n        __find_equal_key(__node_base_const_pointer& __parent, const key_type& __k) const;\n};\n\n// Find place to insert if __k doesn't exist\n// Set __parent to parent of null leaf\n// Return reference to null leaf\n// If __k exists, set parent to node of __k and return reference to node of __k\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ntypename map<_Key, _Tp, _Compare, _Allocator>::__node_base_pointer&\nmap<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_pointer& __parent,\n                                                       const key_type& __k)\n{\n    __node_pointer __nd = __tree_.__root();\n    if (__nd != nullptr)\n    {\n        while (true)\n        {\n            if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first))\n            {\n                if (__nd->__left_ != nullptr)\n                    __nd = static_cast<__node_pointer>(__nd->__left_);\n                else\n                {\n                    __parent = static_cast<__node_base_pointer>(__nd);\n                    return __parent->__left_;\n                }\n            }\n            else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k))\n            {\n                if (__nd->__right_ != nullptr)\n                    __nd = static_cast<__node_pointer>(__nd->__right_);\n                else\n                {\n                    __parent = static_cast<__node_base_pointer>(__nd);\n                    return __parent->__right_;\n                }\n            }\n            else\n            {\n                __parent = static_cast<__node_base_pointer>(__nd);\n                return __parent;\n            }\n        }\n    }\n    __parent = static_cast<__node_base_pointer>(__tree_.__end_node());\n    return __parent->__left_;\n}\n\n// Find __k\n// Set __parent to parent of null leaf and\n//    return reference to null leaf iv __k does not exist.\n// If __k exists, set parent to node of __k and return reference to node of __k\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ntypename map<_Key, _Tp, _Compare, _Allocator>::__node_base_const_pointer\nmap<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_const_pointer& __parent,\n                                                       const key_type& __k) const\n{\n    __node_const_pointer __nd = __tree_.__root();\n    if (__nd != nullptr)\n    {\n        while (true)\n        {\n            if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first))\n            {\n                if (__nd->__left_ != nullptr)\n                    __nd = static_cast<__node_pointer>(__nd->__left_);\n                else\n                {\n                    __parent = static_cast<__node_base_pointer>(__nd);\n                    return const_cast<const __node_base_const_pointer&>(__parent->__left_);\n                }\n            }\n            else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k))\n            {\n                if (__nd->__right_ != nullptr)\n                    __nd = static_cast<__node_pointer>(__nd->__right_);\n                else\n                {\n                    __parent = static_cast<__node_base_pointer>(__nd);\n                    return const_cast<const __node_base_const_pointer&>(__parent->__right_);\n                }\n            }\n            else\n            {\n                __parent = static_cast<__node_base_pointer>(__nd);\n                return __parent;\n            }\n        }\n    }\n    __parent = static_cast<__node_base_pointer>(__tree_.__end_node());\n    return const_cast<const __node_base_const_pointer&>(__parent->__left_);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\nmap<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a)\n    : __tree_(_VSTD::move(__m.__tree_), __a)\n{\n    if (__a != __m.get_allocator())\n    {\n        const_iterator __e = cend();\n        while (!__m.empty())\n            __tree_.__insert_unique(__e.__i_,\n                    _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_));\n    }\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ntypename map<_Key, _Tp, _Compare, _Allocator>::__node_holder\nmap<_Key, _Tp, _Compare, _Allocator>::__construct_node()\n{\n    __node_allocator& __na = __tree_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first));\n    __h.get_deleter().__first_constructed = true;\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));\n    __h.get_deleter().__second_constructed = true;\n    return __h;\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ntemplate <class _A0>\ntypename map<_Key, _Tp, _Compare, _Allocator>::__node_holder\nmap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)\n{\n    __node_allocator& __na = __tree_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_A0>(__a0));\n    __h.get_deleter().__first_constructed = true;\n    __h.get_deleter().__second_constructed = true;\n    return __h;\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ntypename map<_Key, _Tp, _Compare, _Allocator>::__node_holder\nmap<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(key_type&& __k)\n{\n    __node_allocator& __na = __tree_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), _VSTD::move(__k));\n    __h.get_deleter().__first_constructed = true;\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));\n    __h.get_deleter().__second_constructed = true;\n    return __h;\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ntemplate <class _A0, class _A1, class ..._Args>\ntypename map<_Key, _Tp, _Compare, _Allocator>::__node_holder\nmap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args)\n{\n    __node_allocator& __na = __tree_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_),\n                             _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1),\n                             _VSTD::forward<_Args>(__args)...);\n    __h.get_deleter().__first_constructed = true;\n    __h.get_deleter().__second_constructed = true;\n    return __h;\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ntypename map<_Key, _Tp, _Compare, _Allocator>::__node_holder\nmap<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k)\n{\n    __node_allocator& __na = __tree_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), __k);\n    __h.get_deleter().__first_constructed = true;\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));\n    __h.get_deleter().__second_constructed = true;\n    return _VSTD::move(__h);  // explicitly moved for C++03\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\n_Tp&\nmap<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)\n{\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_equal_key(__parent, __k);\n    __node_pointer __r = static_cast<__node_pointer>(__child);\n    if (__child == nullptr)\n    {\n        __node_holder __h = __construct_node_with_key(__k);\n        __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));\n        __r = __h.release();\n    }\n    return __r->__value_.__cc.second;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\n_Tp&\nmap<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k)\n{\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_equal_key(__parent, __k);\n    __node_pointer __r = static_cast<__node_pointer>(__child);\n    if (__child == nullptr)\n    {\n        __node_holder __h = __construct_node_with_key(_VSTD::move(__k));\n        __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));\n        __r = __h.release();\n    }\n    return __r->__value_.__cc.second;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\n_Tp&\nmap<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k)\n{\n    __node_base_pointer __parent;\n    __node_base_pointer& __child = __find_equal_key(__parent, __k);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__child == nullptr)\n        throw out_of_range(\"map::at:  key not found\");\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return static_cast<__node_pointer>(__child)->__value_.__cc.second;\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\nconst _Tp&\nmap<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const\n{\n    __node_base_const_pointer __parent;\n    __node_base_const_pointer __child = __find_equal_key(__parent, __k);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__child == nullptr)\n        throw out_of_range(\"map::at:  key not found\");\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return static_cast<__node_const_pointer>(__child)->__value_.__cc.second;\n}\n\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ntemplate <class ..._Args>\npair<typename map<_Key, _Tp, _Compare, _Allocator>::iterator, bool>\nmap<_Key, _Tp, _Compare, _Allocator>::emplace(_Args&& ...__args)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);\n    pair<iterator, bool> __r = __tree_.__node_insert_unique(__h.get());\n    if (__r.second)\n        __h.release();\n    return __r;\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ntemplate <class ..._Args>\ntypename map<_Key, _Tp, _Compare, _Allocator>::iterator\nmap<_Key, _Tp, _Compare, _Allocator>::emplace_hint(const_iterator __p,\n                                                   _Args&& ...__args)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);\n    iterator __r = __tree_.__node_insert_unique(__p.__i_, __h.get());\n    if (__r.__i_.__ptr_ == __h.get())\n        __h.release();\n    return __r;\n}\n\n#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const map<_Key, _Tp, _Compare, _Allocator>& __x,\n           const map<_Key, _Tp, _Compare, _Allocator>& __y)\n{\n    return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const map<_Key, _Tp, _Compare, _Allocator>& __x,\n           const map<_Key, _Tp, _Compare, _Allocator>& __y)\n{\n    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const map<_Key, _Tp, _Compare, _Allocator>& __x,\n           const map<_Key, _Tp, _Compare, _Allocator>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator> (const map<_Key, _Tp, _Compare, _Allocator>& __x,\n           const map<_Key, _Tp, _Compare, _Allocator>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const map<_Key, _Tp, _Compare, _Allocator>& __x,\n           const map<_Key, _Tp, _Compare, _Allocator>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x,\n           const map<_Key, _Tp, _Compare, _Allocator>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(map<_Key, _Tp, _Compare, _Allocator>& __x,\n     map<_Key, _Tp, _Compare, _Allocator>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Key, class _Tp, class _Compare = less<_Key>,\n          class _Allocator = allocator<pair<const _Key, _Tp> > >\nclass _LIBCPP_TYPE_VIS_ONLY multimap\n{\npublic:\n    // types:\n    typedef _Key                                     key_type;\n    typedef _Tp                                      mapped_type;\n    typedef pair<const key_type, mapped_type>        value_type;\n    typedef pair<key_type, mapped_type>              __nc_value_type;\n    typedef _Compare                                 key_compare;\n    typedef _Allocator                               allocator_type;\n    typedef value_type&                              reference;\n    typedef const value_type&                        const_reference;\n\n    class _LIBCPP_TYPE_VIS_ONLY value_compare\n        : public binary_function<value_type, value_type, bool>\n    {\n        friend class multimap;\n    protected:\n        key_compare comp;\n\n        _LIBCPP_INLINE_VISIBILITY\n        value_compare(key_compare c) : comp(c) {}\n    public:\n        _LIBCPP_INLINE_VISIBILITY\n        bool operator()(const value_type& __x, const value_type& __y) const\n            {return comp(__x.first, __y.first);}\n    };\n\nprivate:\n\n    typedef _VSTD::__value_type<key_type, mapped_type>             __value_type;\n    typedef __map_value_compare<key_type, __value_type, key_compare> __vc;\n    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,\n                                                 __value_type>::type __allocator_type;\n    typedef __tree<__value_type, __vc, __allocator_type>            __base;\n    typedef typename __base::__node_traits                          __node_traits;\n    typedef allocator_traits<allocator_type>                        __alloc_traits;\n\n    __base __tree_;\n\npublic:\n    typedef typename __alloc_traits::pointer               pointer;\n    typedef typename __alloc_traits::const_pointer         const_pointer;\n    typedef typename __alloc_traits::size_type             size_type;\n    typedef typename __alloc_traits::difference_type       difference_type;\n    typedef __map_iterator<typename __base::iterator>      iterator;\n    typedef __map_const_iterator<typename __base::const_iterator> const_iterator;\n    typedef _VSTD::reverse_iterator<iterator>               reverse_iterator;\n    typedef _VSTD::reverse_iterator<const_iterator>         const_reverse_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY\n    multimap()\n        _NOEXCEPT_(\n            is_nothrow_default_constructible<allocator_type>::value &&\n            is_nothrow_default_constructible<key_compare>::value &&\n            is_nothrow_copy_constructible<key_compare>::value)\n        : __tree_(__vc(key_compare())) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit multimap(const key_compare& __comp)\n        _NOEXCEPT_(\n            is_nothrow_default_constructible<allocator_type>::value &&\n            is_nothrow_copy_constructible<key_compare>::value)\n        : __tree_(__vc(__comp)) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit multimap(const key_compare& __comp, const allocator_type& __a)\n        : __tree_(__vc(__comp), __a) {}\n\n    template <class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        multimap(_InputIterator __f, _InputIterator __l,\n            const key_compare& __comp = key_compare())\n        : __tree_(__vc(__comp))\n        {\n            insert(__f, __l);\n        }\n\n    template <class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        multimap(_InputIterator __f, _InputIterator __l,\n            const key_compare& __comp, const allocator_type& __a)\n        : __tree_(__vc(__comp), __a)\n        {\n            insert(__f, __l);\n        }\n\n#if _LIBCPP_STD_VER > 11\n    template <class _InputIterator>\n    _LIBCPP_INLINE_VISIBILITY \n    multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a)\n        : multimap(__f, __l, key_compare(), __a) {}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    multimap(const multimap& __m)\n        : __tree_(__m.__tree_.value_comp(),\n          __alloc_traits::select_on_container_copy_construction(__m.__tree_.__alloc()))\n        {\n            insert(__m.begin(), __m.end());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    multimap& operator=(const multimap& __m)\n        {\n#if __cplusplus >= 201103L\n            __tree_ = __m.__tree_;\n#else\n            if (this != &__m) {\n                __tree_.clear();\n                __tree_.value_comp() = __m.__tree_.value_comp();\n                __tree_.__copy_assign_alloc(__m.__tree_);\n                insert(__m.begin(), __m.end());\n            }\n#endif\n            return *this;\n        }\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    multimap(multimap&& __m)\n        _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)\n        : __tree_(_VSTD::move(__m.__tree_))\n        {\n        }\n\n    multimap(multimap&& __m, const allocator_type& __a);\n\n    _LIBCPP_INLINE_VISIBILITY\n    multimap& operator=(multimap&& __m)\n        _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)\n        {\n            __tree_ = _VSTD::move(__m.__tree_);\n            return *this;\n        }\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())\n        : __tree_(__vc(__comp))\n        {\n            insert(__il.begin(), __il.end());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    multimap(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)\n        : __tree_(__vc(__comp), __a)\n        {\n            insert(__il.begin(), __il.end());\n        }\n\n#if _LIBCPP_STD_VER > 11\n    _LIBCPP_INLINE_VISIBILITY \n    multimap(initializer_list<value_type> __il, const allocator_type& __a)\n        : multimap(__il, key_compare(), __a) {}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    multimap& operator=(initializer_list<value_type> __il)\n        {\n            __tree_.__assign_multi(__il.begin(), __il.end());\n            return *this;\n        }\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit multimap(const allocator_type& __a)\n        : __tree_(__a)\n        {\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    multimap(const multimap& __m, const allocator_type& __a)\n        : __tree_(__m.__tree_.value_comp(), __a)\n        {\n            insert(__m.begin(), __m.end());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n          iterator begin() _NOEXCEPT {return __tree_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin() const _NOEXCEPT {return __tree_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n          iterator end() _NOEXCEPT {return __tree_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end() const _NOEXCEPT {return __tree_.end();}\n\n    _LIBCPP_INLINE_VISIBILITY\n          reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rbegin() const _NOEXCEPT\n        {return const_reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n          reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rend() const _NOEXCEPT\n        {return const_reverse_iterator(begin());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cbegin()  const _NOEXCEPT {return begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cend() const _NOEXCEPT {return end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crend() const _NOEXCEPT {return rend();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool empty() const _NOEXCEPT {return __tree_.size() == 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const _NOEXCEPT {return __tree_.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const _NOEXCEPT {return __tree_.max_size();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();}\n    _LIBCPP_INLINE_VISIBILITY\n    key_compare    key_comp() const {return __tree_.value_comp().key_comp();}\n    _LIBCPP_INLINE_VISIBILITY\n    value_compare  value_comp() const\n        {return value_compare(__tree_.value_comp().key_comp());}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n    template <class ..._Args>\n        iterator\n        emplace(_Args&& ...__args);\n\n    template <class ..._Args>\n        iterator\n        emplace_hint(const_iterator __p, _Args&& ...__args);\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n    template <class _Pp,\n              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator insert(_Pp&& __p)\n            {return __tree_.__insert_multi(_VSTD::forward<_Pp>(__p));}\n\n    template <class _Pp,\n              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator insert(const_iterator __pos, _Pp&& __p)\n            {return __tree_.__insert_multi(__pos.__i_, _VSTD::forward<_Pp>(__p));}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator __p, const value_type& __v)\n            {return __tree_.__insert_multi(__p.__i_, __v);}\n\n    template <class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        void insert(_InputIterator __f, _InputIterator __l)\n        {\n            for (const_iterator __e = cend(); __f != __l; ++__f)\n                __tree_.__insert_multi(__e.__i_, *__f);\n        }\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    void insert(initializer_list<value_type> __il)\n        {insert(__il.begin(), __il.end());}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator erase(iterator __p)       {return __tree_.erase(__p.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator  erase(const_iterator __f, const_iterator __l)\n        {return __tree_.erase(__f.__i_, __l.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() {__tree_.clear();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(multimap& __m)\n        _NOEXCEPT_(__is_nothrow_swappable<__base>::value)\n        {__tree_.swap(__m.__tree_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator find(const key_type& __k)             {return __tree_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator find(const key_type& __k) const {return __tree_.find(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type\n    find(const _K2& __k)                           {return __tree_.find(__k);}\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type\n    find(const _K2& __k) const                     {return __tree_.find(__k);}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type      count(const key_type& __k) const\n        {return __tree_.__count_multi(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type\n    count(const _K2& __k) const {return __tree_.__count_multi(__k);}\n#endif\n    _LIBCPP_INLINE_VISIBILITY\n    iterator lower_bound(const key_type& __k)\n        {return __tree_.lower_bound(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator lower_bound(const key_type& __k) const\n            {return __tree_.lower_bound(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type\n    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}\n\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type\n    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator upper_bound(const key_type& __k)\n            {return __tree_.upper_bound(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator upper_bound(const key_type& __k) const\n            {return __tree_.upper_bound(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type\n    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type\n    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator,iterator>             equal_range(const key_type& __k)\n            {return __tree_.__equal_range_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<const_iterator,const_iterator> equal_range(const key_type& __k) const\n            {return __tree_.__equal_range_multi(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type\n    equal_range(const _K2& __k)       {return __tree_.__equal_range_multi(__k);}\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type\n    equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}\n#endif\n\nprivate:\n    typedef typename __base::__node                    __node;\n    typedef typename __base::__node_allocator          __node_allocator;\n    typedef typename __base::__node_pointer            __node_pointer;\n    typedef typename __base::__node_const_pointer      __node_const_pointer;\n    typedef __map_node_destructor<__node_allocator> _Dp;\n    typedef unique_ptr<__node, _Dp> __node_holder;\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __node_holder __construct_node();\n    template <class _A0>\n        __node_holder\n         __construct_node(_A0&& __a0);\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class _A0, class _A1, class ..._Args>\n        __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n};\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\nmultimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a)\n    : __tree_(_VSTD::move(__m.__tree_), __a)\n{\n    if (__a != __m.get_allocator())\n    {\n        const_iterator __e = cend();\n        while (!__m.empty())\n            __tree_.__insert_multi(__e.__i_,\n                    _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_));\n    }\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ntypename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder\nmultimap<_Key, _Tp, _Compare, _Allocator>::__construct_node()\n{\n    __node_allocator& __na = __tree_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first));\n    __h.get_deleter().__first_constructed = true;\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));\n    __h.get_deleter().__second_constructed = true;\n    return __h;\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ntemplate <class _A0>\ntypename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder\nmultimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)\n{\n    __node_allocator& __na = __tree_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_A0>(__a0));\n    __h.get_deleter().__first_constructed = true;\n    __h.get_deleter().__second_constructed = true;\n    return __h;\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ntemplate <class _A0, class _A1, class ..._Args>\ntypename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder\nmultimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args)\n{\n    __node_allocator& __na = __tree_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_),\n                             _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1),\n                             _VSTD::forward<_Args>(__args)...);\n    __h.get_deleter().__first_constructed = true;\n    __h.get_deleter().__second_constructed = true;\n    return __h;\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ntemplate <class ..._Args>\ntypename multimap<_Key, _Tp, _Compare, _Allocator>::iterator\nmultimap<_Key, _Tp, _Compare, _Allocator>::emplace(_Args&& ...__args)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);\n    iterator __r = __tree_.__node_insert_multi(__h.get());\n    __h.release();\n    return __r;\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ntemplate <class ..._Args>\ntypename multimap<_Key, _Tp, _Compare, _Allocator>::iterator\nmultimap<_Key, _Tp, _Compare, _Allocator>::emplace_hint(const_iterator __p,\n                                                        _Args&& ...__args)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);\n    iterator __r = __tree_.__node_insert_multi(__p.__i_, __h.get());\n    __h.release();\n    return __r;\n}\n\n#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,\n           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)\n{\n    return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,\n           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)\n{\n    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,\n           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator> (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,\n           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,\n           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,\n           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _Key, class _Tp, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(multimap<_Key, _Tp, _Compare, _Allocator>& __x,\n     multimap<_Key, _Tp, _Compare, _Allocator>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_MAP\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/memory",
    "content": "// -*- C++ -*-\n//===-------------------------- memory ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_MEMORY\n#define _LIBCPP_MEMORY\n\n/*\n    memory synopsis\n\nnamespace std\n{\n\nstruct allocator_arg_t { };\nconstexpr allocator_arg_t allocator_arg = allocator_arg_t();\n\ntemplate <class T, class Alloc> struct uses_allocator;\n\ntemplate <class Ptr>\nstruct pointer_traits\n{\n    typedef Ptr pointer;\n    typedef <details> element_type;\n    typedef <details> difference_type;\n\n    template <class U> using rebind = <details>;\n\n    static pointer pointer_to(<details>);\n};\n\ntemplate <class T>\nstruct pointer_traits<T*>\n{\n    typedef T* pointer;\n    typedef T element_type;\n    typedef ptrdiff_t difference_type;\n\n    template <class U> using rebind = U*;\n\n    static pointer pointer_to(<details>) noexcept;\n};\n\ntemplate <class Alloc>\nstruct allocator_traits\n{\n    typedef Alloc                        allocator_type;\n    typedef typename allocator_type::value_type\n                                         value_type;\n\n    typedef Alloc::pointer | value_type* pointer;\n    typedef Alloc::const_pointer\n          | pointer_traits<pointer>::rebind<const value_type>\n                                         const_pointer;\n    typedef Alloc::void_pointer\n          | pointer_traits<pointer>::rebind<void>\n                                         void_pointer;\n    typedef Alloc::const_void_pointer\n          | pointer_traits<pointer>::rebind<const void>\n                                         const_void_pointer;\n    typedef Alloc::difference_type\n          | pointer_traits<pointer>::difference_type\n                                         difference_type;\n    typedef Alloc::size_type\n          | make_unsigned<difference_type>::type\n                                         size_type;\n    typedef Alloc::propagate_on_container_copy_assignment\n          | false_type                   propagate_on_container_copy_assignment;\n    typedef Alloc::propagate_on_container_move_assignment\n          | false_type                   propagate_on_container_move_assignment;\n    typedef Alloc::propagate_on_container_swap\n          | false_type                   propagate_on_container_swap;\n    typedef Alloc::is_always_equal\n          | is_empty                     is_always_equal;\n\n    template <class T> using rebind_alloc  = Alloc::rebind<U>::other | Alloc<T, Args...>;\n    template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;\n\n    static pointer allocate(allocator_type& a, size_type n);\n    static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint);\n\n    static void deallocate(allocator_type& a, pointer p, size_type n) noexcept;\n\n    template <class T, class... Args>\n        static void construct(allocator_type& a, T* p, Args&&... args);\n\n    template <class T>\n        static void destroy(allocator_type& a, T* p);\n\n    static size_type max_size(const allocator_type& a); // noexcept in C++14\n\n    static allocator_type\n        select_on_container_copy_construction(const allocator_type& a);\n};\n\ntemplate <>\nclass allocator<void>\n{\npublic:\n    typedef void*                                 pointer;\n    typedef const void*                           const_pointer;\n    typedef void                                  value_type;\n\n    template <class _Up> struct rebind {typedef allocator<_Up> other;};\n};\n\ntemplate <class T>\nclass allocator\n{\npublic:\n    typedef size_t                                size_type;\n    typedef ptrdiff_t                             difference_type;\n    typedef T*                                    pointer;\n    typedef const T*                              const_pointer;\n    typedef typename add_lvalue_reference<T>::type       reference;\n    typedef typename add_lvalue_reference<const T>::type const_reference;\n    typedef T                                     value_type;\n\n    template <class U> struct rebind {typedef allocator<U> other;};\n\n    allocator() noexcept;\n    allocator(const allocator&) noexcept;\n    template <class U> allocator(const allocator<U>&) noexcept;\n    ~allocator();\n    pointer address(reference x) const noexcept;\n    const_pointer address(const_reference x) const noexcept;\n    pointer allocate(size_type, allocator<void>::const_pointer hint = 0);\n    void deallocate(pointer p, size_type n) noexcept;\n    size_type max_size() const noexcept;\n    template<class U, class... Args>\n        void construct(U* p, Args&&... args);\n    template <class U>\n        void destroy(U* p);\n};\n\ntemplate <class T, class U>\nbool operator==(const allocator<T>&, const allocator<U>&) noexcept;\n\ntemplate <class T, class U>\nbool operator!=(const allocator<T>&, const allocator<U>&) noexcept;\n\ntemplate <class OutputIterator, class T>\nclass raw_storage_iterator\n    : public iterator<output_iterator_tag,\n                      T,                               // purposefully not C++03\n                      ptrdiff_t,                       // purposefully not C++03\n                      T*,                              // purposefully not C++03\n                      raw_storage_iterator&>           // purposefully not C++03\n{\npublic:\n    explicit raw_storage_iterator(OutputIterator x);\n    raw_storage_iterator& operator*();\n    raw_storage_iterator& operator=(const T& element);\n    raw_storage_iterator& operator++();\n    raw_storage_iterator  operator++(int);\n};\n\ntemplate <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;\ntemplate <class T> void               return_temporary_buffer(T* p) noexcept;\n\ntemplate <class T> T* addressof(T& r) noexcept;\n\ntemplate <class InputIterator, class ForwardIterator>\nForwardIterator\nuninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);\n\ntemplate <class InputIterator, class Size, class ForwardIterator>\nForwardIterator\nuninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);\n\ntemplate <class ForwardIterator, class T>\nvoid uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);\n\ntemplate <class ForwardIterator, class Size, class T>\nForwardIterator\nuninitialized_fill_n(ForwardIterator first, Size n, const T& x);\n\ntemplate <class Y> struct auto_ptr_ref {};\n\ntemplate<class X>\nclass auto_ptr\n{\npublic:\n    typedef X element_type;\n\n    explicit auto_ptr(X* p =0) throw();\n    auto_ptr(auto_ptr&) throw();\n    template<class Y> auto_ptr(auto_ptr<Y>&) throw();\n    auto_ptr& operator=(auto_ptr&) throw();\n    template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();\n    auto_ptr& operator=(auto_ptr_ref<X> r) throw();\n    ~auto_ptr() throw();\n\n    typename add_lvalue_reference<X>::type operator*() const throw();\n    X* operator->() const throw();\n    X* get() const throw();\n    X* release() throw();\n    void reset(X* p =0) throw();\n\n    auto_ptr(auto_ptr_ref<X>) throw();\n    template<class Y> operator auto_ptr_ref<Y>() throw();\n    template<class Y> operator auto_ptr<Y>() throw();\n};\n\ntemplate <class T>\nstruct default_delete\n{\n    constexpr default_delete() noexcept = default;\n    template <class U> default_delete(const default_delete<U>&) noexcept;\n\n    void operator()(T*) const noexcept;\n};\n\ntemplate <class T>\nstruct default_delete<T[]>\n{\n    constexpr default_delete() noexcept = default;\n    void operator()(T*) const noexcept;\n    template <class U> void operator()(U*) const = delete;\n};\n\ntemplate <class T, class D = default_delete<T>>\nclass unique_ptr\n{\npublic:\n    typedef see below pointer;\n    typedef T element_type;\n    typedef D deleter_type;\n\n    // constructors\n    constexpr unique_ptr() noexcept;\n    explicit unique_ptr(pointer p) noexcept;\n    unique_ptr(pointer p, see below d1) noexcept;\n    unique_ptr(pointer p, see below d2) noexcept;\n    unique_ptr(unique_ptr&& u) noexcept;\n    unique_ptr(nullptr_t) noexcept : unique_ptr() { }\n    template <class U, class E>\n        unique_ptr(unique_ptr<U, E>&& u) noexcept;\n    template <class U>\n        unique_ptr(auto_ptr<U>&& u) noexcept;\n\n    // destructor\n    ~unique_ptr();\n\n    // assignment\n    unique_ptr& operator=(unique_ptr&& u) noexcept;\n    template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;\n    unique_ptr& operator=(nullptr_t) noexcept;\n\n    // observers\n    typename add_lvalue_reference<T>::type operator*() const;\n    pointer operator->() const noexcept;\n    pointer get() const noexcept;\n    deleter_type& get_deleter() noexcept;\n    const deleter_type& get_deleter() const noexcept;\n    explicit operator bool() const noexcept;\n\n    // modifiers\n    pointer release() noexcept;\n    void reset(pointer p = pointer()) noexcept;\n    void swap(unique_ptr& u) noexcept;\n};\n\ntemplate <class T, class D>\nclass unique_ptr<T[], D>\n{\npublic:\n    typedef implementation-defined pointer;\n    typedef T element_type;\n    typedef D deleter_type;\n\n    // constructors\n    constexpr unique_ptr() noexcept;\n    explicit unique_ptr(pointer p) noexcept;\n    unique_ptr(pointer p, see below d) noexcept;\n    unique_ptr(pointer p, see below d) noexcept;\n    unique_ptr(unique_ptr&& u) noexcept;\n    unique_ptr(nullptr_t) noexcept : unique_ptr() { }\n\n    // destructor\n    ~unique_ptr();\n\n    // assignment\n    unique_ptr& operator=(unique_ptr&& u) noexcept;\n    unique_ptr& operator=(nullptr_t) noexcept;\n\n    // observers\n    T& operator[](size_t i) const;\n    pointer get() const noexcept;\n    deleter_type& get_deleter() noexcept;\n    const deleter_type& get_deleter() const noexcept;\n    explicit operator bool() const noexcept;\n\n    // modifiers\n    pointer release() noexcept;\n    void reset(pointer p = pointer()) noexcept;\n    void reset(nullptr_t) noexcept;\n    template <class U> void reset(U) = delete;\n    void swap(unique_ptr& u) noexcept;\n};\n\ntemplate <class T, class D>\n    void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;\n\ntemplate <class T1, class D1, class T2, class D2>\n    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);\ntemplate <class T1, class D1, class T2, class D2>\n    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);\ntemplate <class T1, class D1, class T2, class D2>\n    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);\ntemplate <class T1, class D1, class T2, class D2>\n    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);\ntemplate <class T1, class D1, class T2, class D2>\n    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);\ntemplate <class T1, class D1, class T2, class D2>\n    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);\n\ntemplate <class T, class D>\n    bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;\ntemplate <class T, class D>\n    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;\ntemplate <class T, class D>\n    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;\ntemplate <class T, class D>\n    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;\n\ntemplate <class T, class D>\n    bool operator<(const unique_ptr<T, D>& x, nullptr_t);\ntemplate <class T, class D>\n    bool operator<(nullptr_t, const unique_ptr<T, D>& y);\ntemplate <class T, class D>\n    bool operator<=(const unique_ptr<T, D>& x, nullptr_t);\ntemplate <class T, class D>\n    bool operator<=(nullptr_t, const unique_ptr<T, D>& y);\ntemplate <class T, class D>\n    bool operator>(const unique_ptr<T, D>& x, nullptr_t);\ntemplate <class T, class D>\n    bool operator>(nullptr_t, const unique_ptr<T, D>& y);\ntemplate <class T, class D>\n    bool operator>=(const unique_ptr<T, D>& x, nullptr_t);\ntemplate <class T, class D>\n    bool operator>=(nullptr_t, const unique_ptr<T, D>& y);\n\nclass bad_weak_ptr\n    : public std::exception\n{\n    bad_weak_ptr() noexcept;\n};\n\ntemplate<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);     // C++14\ntemplate<class T>                unique_ptr<T> make_unique(size_t n);           // C++14\ntemplate<class T, class... Args> unspecified   make_unique(Args&&...) = delete; // C++14, T == U[N]\n\ntemplate<class T>\nclass shared_ptr\n{\npublic:\n    typedef T element_type;\n\n    // constructors:\n    constexpr shared_ptr() noexcept;\n    template<class Y> explicit shared_ptr(Y* p);\n    template<class Y, class D> shared_ptr(Y* p, D d);\n    template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);\n    template <class D> shared_ptr(nullptr_t p, D d);\n    template <class D, class A> shared_ptr(nullptr_t p, D d, A a);\n    template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept;\n    shared_ptr(const shared_ptr& r) noexcept;\n    template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;\n    shared_ptr(shared_ptr&& r) noexcept;\n    template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;\n    template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);\n    template<class Y> shared_ptr(auto_ptr<Y>&& r);\n    template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);\n    shared_ptr(nullptr_t) : shared_ptr() { }\n\n    // destructor:\n    ~shared_ptr();\n\n    // assignment:\n    shared_ptr& operator=(const shared_ptr& r) noexcept;\n    template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;\n    shared_ptr& operator=(shared_ptr&& r) noexcept;\n    template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r);\n    template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r);\n    template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);\n\n    // modifiers:\n    void swap(shared_ptr& r) noexcept;\n    void reset() noexcept;\n    template<class Y> void reset(Y* p);\n    template<class Y, class D> void reset(Y* p, D d);\n    template<class Y, class D, class A> void reset(Y* p, D d, A a);\n\n    // observers:\n    T* get() const noexcept;\n    T& operator*() const noexcept;\n    T* operator->() const noexcept;\n    long use_count() const noexcept;\n    bool unique() const noexcept;\n    explicit operator bool() const noexcept;\n    template<class U> bool owner_before(shared_ptr<U> const& b) const;\n    template<class U> bool owner_before(weak_ptr<U> const& b) const;\n};\n\n// shared_ptr comparisons:\ntemplate<class T, class U>\n    bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;\ntemplate<class T, class U>\n    bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;\ntemplate<class T, class U>\n    bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;\ntemplate<class T, class U>\n    bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;\ntemplate<class T, class U>\n    bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;\ntemplate<class T, class U>\n    bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;\n\ntemplate <class T>\n    bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;\ntemplate <class T>\n    bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept;\ntemplate <class T>\n    bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept;\ntemplate <class T>\n    bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept;\ntemplate <class T>\n    bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept;\ntemplate <class T>\nbool operator<(nullptr_t, const shared_ptr<T>& y) noexcept;\ntemplate <class T>\n    bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept;\ntemplate <class T>\n    bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept;\ntemplate <class T>\n    bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept;\ntemplate <class T>\n    bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept;\ntemplate <class T>\n    bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept;\ntemplate <class T>\n    bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept;\n\n// shared_ptr specialized algorithms:\ntemplate<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;\n\n// shared_ptr casts:\ntemplate<class T, class U>\n    shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r) noexcept;\ntemplate<class T, class U>\n    shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r) noexcept;\ntemplate<class T, class U>\n    shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r) noexcept;\n\n// shared_ptr I/O:\ntemplate<class E, class T, class Y>\n    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);\n\n// shared_ptr get_deleter:\ntemplate<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept;\n\ntemplate<class T, class... Args>\n    shared_ptr<T> make_shared(Args&&... args);\ntemplate<class T, class A, class... Args>\n    shared_ptr<T> allocate_shared(const A& a, Args&&... args);\n\ntemplate<class T>\nclass weak_ptr\n{\npublic:\n    typedef T element_type;\n\n    // constructors\n    constexpr weak_ptr() noexcept;\n    template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;\n    weak_ptr(weak_ptr const& r) noexcept;\n    template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;\n    weak_ptr(weak_ptr&& r) noexcept;                      // C++14\n    template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // C++14\n\n    // destructor\n    ~weak_ptr();\n\n    // assignment\n    weak_ptr& operator=(weak_ptr const& r) noexcept;\n    template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;\n    template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;\n    weak_ptr& operator=(weak_ptr&& r) noexcept;                      // C++14\n    template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // C++14\n\n    // modifiers\n    void swap(weak_ptr& r) noexcept;\n    void reset() noexcept;\n\n    // observers\n    long use_count() const noexcept;\n    bool expired() const noexcept;\n    shared_ptr<T> lock() const noexcept;\n    template<class U> bool owner_before(shared_ptr<U> const& b) const;\n    template<class U> bool owner_before(weak_ptr<U> const& b) const;\n};\n\n// weak_ptr specialized algorithms:\ntemplate<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;\n\n// class owner_less:\ntemplate<class T> struct owner_less;\n\ntemplate<class T>\nstruct owner_less<shared_ptr<T>>\n    : binary_function<shared_ptr<T>, shared_ptr<T>, bool>\n{\n    typedef bool result_type;\n    bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const;\n    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const;\n    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const;\n};\n\ntemplate<class T>\nstruct owner_less<weak_ptr<T>>\n    : binary_function<weak_ptr<T>, weak_ptr<T>, bool>\n{\n    typedef bool result_type;\n    bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const;\n    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const;\n    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const;\n};\n\ntemplate<class T>\nclass enable_shared_from_this\n{\nprotected:\n    constexpr enable_shared_from_this() noexcept;\n    enable_shared_from_this(enable_shared_from_this const&) noexcept;\n    enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept;\n    ~enable_shared_from_this();\npublic:\n    shared_ptr<T> shared_from_this();\n    shared_ptr<T const> shared_from_this() const;\n};\n\ntemplate<class T>\n    bool atomic_is_lock_free(const shared_ptr<T>* p);\ntemplate<class T>\n    shared_ptr<T> atomic_load(const shared_ptr<T>* p);\ntemplate<class T>\n    shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);\ntemplate<class T>\n    void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);\ntemplate<class T>\n    void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);\ntemplate<class T>\n    shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);\ntemplate<class T>\n    shared_ptr<T>\n    atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);\ntemplate<class T>\n    bool\n    atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);\ntemplate<class T>\n    bool\n    atomic_compare_exchange_strong( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);\ntemplate<class T>\n    bool\n    atomic_compare_exchange_weak_explicit(shared_ptr<T>* p, shared_ptr<T>* v,\n                                          shared_ptr<T> w, memory_order success,\n                                          memory_order failure);\ntemplate<class T>\n    bool\n    atomic_compare_exchange_strong_explicit(shared_ptr<T>* p, shared_ptr<T>* v,\n                                            shared_ptr<T> w, memory_order success,\n                                            memory_order failure);\n// Hash support\ntemplate <class T> struct hash;\ntemplate <class T, class D> struct hash<unique_ptr<T, D> >;\ntemplate <class T> struct hash<shared_ptr<T> >;\n\n// Pointer safety\nenum class pointer_safety { relaxed, preferred, strict };\nvoid declare_reachable(void *p);\ntemplate <class T> T *undeclare_reachable(T *p);\nvoid declare_no_pointers(char *p, size_t n);\nvoid undeclare_no_pointers(char *p, size_t n);\npointer_safety get_pointer_safety() noexcept;\n\nvoid* align(size_t alignment, size_t size, void*& ptr, size_t& space);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <type_traits>\n#include <typeinfo>\n#include <cstddef>\n#include <cstdint>\n#include <new>\n#include <utility>\n#include <limits>\n#include <iterator>\n#include <__functional_base>\n#include <iosfwd>\n#include <tuple>\n#include <cstring>\n#if defined(_LIBCPP_NO_EXCEPTIONS)\n    #include <cassert>\n#endif\n\n#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)\n#  include <atomic>\n#endif\n\n#include <__undef_min_max>\n#include <__undef___deallocate>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _ValueType>\ninline _LIBCPP_ALWAYS_INLINE\n_ValueType __libcpp_relaxed_load(_ValueType const* __value) {\n#if !defined(_LIBCPP_HAS_NO_THREADS) && \\\n    defined(__ATOMIC_RELAXED) &&        \\\n    (__has_builtin(__atomic_load_n) || _GNUC_VER >= 407)\n    return __atomic_load_n(__value, __ATOMIC_RELAXED);\n#else\n    return *__value;\n#endif\n}\n\n// addressof moved to <__functional_base>\n\ntemplate <class _Tp> class allocator;\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS_ONLY allocator<void>\n{\npublic:\n    typedef void*             pointer;\n    typedef const void*       const_pointer;\n    typedef void              value_type;\n\n    template <class _Up> struct rebind {typedef allocator<_Up> other;};\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS_ONLY allocator<const void>\n{\npublic:\n    typedef const void*       pointer;\n    typedef const void*       const_pointer;\n    typedef const void        value_type;\n\n    template <class _Up> struct rebind {typedef allocator<_Up> other;};\n};\n\n// pointer_traits\n\ntemplate <class _Tp>\nstruct __has_element_type\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::element_type* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\ntemplate <class _Ptr, bool = __has_element_type<_Ptr>::value>\nstruct __pointer_traits_element_type;\n\ntemplate <class _Ptr>\nstruct __pointer_traits_element_type<_Ptr, true>\n{\n    typedef typename _Ptr::element_type type;\n};\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <template <class, class...> class _Sp, class _Tp, class ..._Args>\nstruct __pointer_traits_element_type<_Sp<_Tp, _Args...>, true>\n{\n    typedef typename _Sp<_Tp, _Args...>::element_type type;\n};\n\ntemplate <template <class, class...> class _Sp, class _Tp, class ..._Args>\nstruct __pointer_traits_element_type<_Sp<_Tp, _Args...>, false>\n{\n    typedef _Tp type;\n};\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <template <class> class _Sp, class _Tp>\nstruct __pointer_traits_element_type<_Sp<_Tp>, true>\n{\n    typedef typename _Sp<_Tp>::element_type type;\n};\n\ntemplate <template <class> class _Sp, class _Tp>\nstruct __pointer_traits_element_type<_Sp<_Tp>, false>\n{\n    typedef _Tp type;\n};\n\ntemplate <template <class, class> class _Sp, class _Tp, class _A0>\nstruct __pointer_traits_element_type<_Sp<_Tp, _A0>, true>\n{\n    typedef typename _Sp<_Tp, _A0>::element_type type;\n};\n\ntemplate <template <class, class> class _Sp, class _Tp, class _A0>\nstruct __pointer_traits_element_type<_Sp<_Tp, _A0>, false>\n{\n    typedef _Tp type;\n};\n\ntemplate <template <class, class, class> class _Sp, class _Tp, class _A0, class _A1>\nstruct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1>, true>\n{\n    typedef typename _Sp<_Tp, _A0, _A1>::element_type type;\n};\n\ntemplate <template <class, class, class> class _Sp, class _Tp, class _A0, class _A1>\nstruct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1>, false>\n{\n    typedef _Tp type;\n};\n\ntemplate <template <class, class, class, class> class _Sp, class _Tp, class _A0,\n                                                           class _A1, class _A2>\nstruct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1, _A2>, true>\n{\n    typedef typename _Sp<_Tp, _A0, _A1, _A2>::element_type type;\n};\n\ntemplate <template <class, class, class, class> class _Sp, class _Tp, class _A0,\n                                                           class _A1, class _A2>\nstruct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1, _A2>, false>\n{\n    typedef _Tp type;\n};\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp>\nstruct __has_difference_type\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::difference_type* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\ntemplate <class _Ptr, bool = __has_difference_type<_Ptr>::value>\nstruct __pointer_traits_difference_type\n{\n    typedef ptrdiff_t type;\n};\n\ntemplate <class _Ptr>\nstruct __pointer_traits_difference_type<_Ptr, true>\n{\n    typedef typename _Ptr::difference_type type;\n};\n\ntemplate <class _Tp, class _Up>\nstruct __has_rebind\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Xp> static __two __test(...);\n    template <class _Xp> static char __test(typename _Xp::template rebind<_Up>* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\ntemplate <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>\nstruct __pointer_traits_rebind\n{\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n    typedef typename _Tp::template rebind<_Up> type;\n#else\n    typedef typename _Tp::template rebind<_Up>::other type;\n#endif\n};\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up>\nstruct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, true>\n{\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n    typedef typename _Sp<_Tp, _Args...>::template rebind<_Up> type;\n#else\n    typedef typename _Sp<_Tp, _Args...>::template rebind<_Up>::other type;\n#endif\n};\n\ntemplate <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up>\nstruct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, false>\n{\n    typedef _Sp<_Up, _Args...> type;\n};\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <template <class> class _Sp, class _Tp, class _Up>\nstruct __pointer_traits_rebind<_Sp<_Tp>, _Up, true>\n{\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n    typedef typename _Sp<_Tp>::template rebind<_Up> type;\n#else\n    typedef typename _Sp<_Tp>::template rebind<_Up>::other type;\n#endif\n};\n\ntemplate <template <class> class _Sp, class _Tp, class _Up>\nstruct __pointer_traits_rebind<_Sp<_Tp>, _Up, false>\n{\n    typedef _Sp<_Up> type;\n};\n\ntemplate <template <class, class> class _Sp, class _Tp, class _A0, class _Up>\nstruct __pointer_traits_rebind<_Sp<_Tp, _A0>, _Up, true>\n{\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n    typedef typename _Sp<_Tp, _A0>::template rebind<_Up> type;\n#else\n    typedef typename _Sp<_Tp, _A0>::template rebind<_Up>::other type;\n#endif\n};\n\ntemplate <template <class, class> class _Sp, class _Tp, class _A0, class _Up>\nstruct __pointer_traits_rebind<_Sp<_Tp, _A0>, _Up, false>\n{\n    typedef _Sp<_Up, _A0> type;\n};\n\ntemplate <template <class, class, class> class _Sp, class _Tp, class _A0,\n                                         class _A1, class _Up>\nstruct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1>, _Up, true>\n{\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n    typedef typename _Sp<_Tp, _A0, _A1>::template rebind<_Up> type;\n#else\n    typedef typename _Sp<_Tp, _A0, _A1>::template rebind<_Up>::other type;\n#endif\n};\n\ntemplate <template <class, class, class> class _Sp, class _Tp, class _A0,\n                                         class _A1, class _Up>\nstruct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1>, _Up, false>\n{\n    typedef _Sp<_Up, _A0, _A1> type;\n};\n\ntemplate <template <class, class, class, class> class _Sp, class _Tp, class _A0,\n                                                class _A1, class _A2, class _Up>\nstruct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1, _A2>, _Up, true>\n{\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n    typedef typename _Sp<_Tp, _A0, _A1, _A2>::template rebind<_Up> type;\n#else\n    typedef typename _Sp<_Tp, _A0, _A1, _A2>::template rebind<_Up>::other type;\n#endif\n};\n\ntemplate <template <class, class, class, class> class _Sp, class _Tp, class _A0,\n                                                class _A1, class _A2, class _Up>\nstruct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1, _A2>, _Up, false>\n{\n    typedef _Sp<_Up, _A0, _A1, _A2> type;\n};\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Ptr>\nstruct _LIBCPP_TYPE_VIS_ONLY pointer_traits\n{\n    typedef _Ptr                                                     pointer;\n    typedef typename __pointer_traits_element_type<pointer>::type    element_type;\n    typedef typename __pointer_traits_difference_type<pointer>::type difference_type;\n\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n    template <class _Up> using rebind = typename __pointer_traits_rebind<pointer, _Up>::type;\n#else\n    template <class _Up> struct rebind\n        {typedef typename __pointer_traits_rebind<pointer, _Up>::type other;};\n#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\nprivate:\n    struct __nat {};\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    static pointer pointer_to(typename conditional<is_void<element_type>::value,\n                                           __nat, element_type>::type& __r)\n        {return pointer::pointer_to(__r);}\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY pointer_traits<_Tp*>\n{\n    typedef _Tp*      pointer;\n    typedef _Tp       element_type;\n    typedef ptrdiff_t difference_type;\n\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n    template <class _Up> using rebind = _Up*;\n#else\n    template <class _Up> struct rebind {typedef _Up* other;};\n#endif\n\nprivate:\n    struct __nat {};\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    static pointer pointer_to(typename conditional<is_void<element_type>::value,\n                                      __nat, element_type>::type& __r) _NOEXCEPT\n        {return _VSTD::addressof(__r);}\n};\n\n// allocator_traits\n\nnamespace __has_pointer_type_imp\n{\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::pointer* = 0);\n}\n\ntemplate <class _Tp>\nstruct __has_pointer_type\n    : public integral_constant<bool, sizeof(__has_pointer_type_imp::__test<_Tp>(0)) == 1>\n{\n};\n\nnamespace __pointer_type_imp\n{\n\ntemplate <class _Tp, class _Dp, bool = __has_pointer_type<_Dp>::value>\nstruct __pointer_type\n{\n    typedef typename _Dp::pointer type;\n};\n\ntemplate <class _Tp, class _Dp>\nstruct __pointer_type<_Tp, _Dp, false>\n{\n    typedef _Tp* type;\n};\n\n}  // __pointer_type_imp\n\ntemplate <class _Tp, class _Dp>\nstruct __pointer_type\n{\n    typedef typename __pointer_type_imp::__pointer_type<_Tp, typename remove_reference<_Dp>::type>::type type;\n};\n\ntemplate <class _Tp>\nstruct __has_const_pointer\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::const_pointer* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\ntemplate <class _Tp, class _Ptr, class _Alloc, bool = __has_const_pointer<_Alloc>::value>\nstruct __const_pointer\n{\n    typedef typename _Alloc::const_pointer type;\n};\n\ntemplate <class _Tp, class _Ptr, class _Alloc>\nstruct __const_pointer<_Tp, _Ptr, _Alloc, false>\n{\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n    typedef typename pointer_traits<_Ptr>::template rebind<const _Tp> type;\n#else\n    typedef typename pointer_traits<_Ptr>::template rebind<const _Tp>::other type;\n#endif\n};\n\ntemplate <class _Tp>\nstruct __has_void_pointer\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::void_pointer* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\ntemplate <class _Ptr, class _Alloc, bool = __has_void_pointer<_Alloc>::value>\nstruct __void_pointer\n{\n    typedef typename _Alloc::void_pointer type;\n};\n\ntemplate <class _Ptr, class _Alloc>\nstruct __void_pointer<_Ptr, _Alloc, false>\n{\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n    typedef typename pointer_traits<_Ptr>::template rebind<void> type;\n#else\n    typedef typename pointer_traits<_Ptr>::template rebind<void>::other type;\n#endif\n};\n\ntemplate <class _Tp>\nstruct __has_const_void_pointer\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::const_void_pointer* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\ntemplate <class _Ptr, class _Alloc, bool = __has_const_void_pointer<_Alloc>::value>\nstruct __const_void_pointer\n{\n    typedef typename _Alloc::const_void_pointer type;\n};\n\ntemplate <class _Ptr, class _Alloc>\nstruct __const_void_pointer<_Ptr, _Alloc, false>\n{\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n    typedef typename pointer_traits<_Ptr>::template rebind<const void> type;\n#else\n    typedef typename pointer_traits<_Ptr>::template rebind<const void>::other type;\n#endif\n};\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp*\n__to_raw_pointer(_Tp* __p) _NOEXCEPT\n{\n    return __p;\n}\n\ntemplate <class _Pointer>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename pointer_traits<_Pointer>::element_type*\n__to_raw_pointer(_Pointer __p) _NOEXCEPT\n{\n    return _VSTD::__to_raw_pointer(__p.operator->());\n}\n\ntemplate <class _Tp>\nstruct __has_size_type\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::size_type* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\ntemplate <class _Alloc, class _DiffType, bool = __has_size_type<_Alloc>::value>\nstruct __size_type\n{\n    typedef typename make_unsigned<_DiffType>::type type;\n};\n\ntemplate <class _Alloc, class _DiffType>\nstruct __size_type<_Alloc, _DiffType, true>\n{\n    typedef typename _Alloc::size_type type;\n};\n\ntemplate <class _Tp>\nstruct __has_propagate_on_container_copy_assignment\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::propagate_on_container_copy_assignment* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\ntemplate <class _Alloc, bool = __has_propagate_on_container_copy_assignment<_Alloc>::value>\nstruct __propagate_on_container_copy_assignment\n{\n    typedef false_type type;\n};\n\ntemplate <class _Alloc>\nstruct __propagate_on_container_copy_assignment<_Alloc, true>\n{\n    typedef typename _Alloc::propagate_on_container_copy_assignment type;\n};\n\ntemplate <class _Tp>\nstruct __has_propagate_on_container_move_assignment\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::propagate_on_container_move_assignment* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\ntemplate <class _Alloc, bool = __has_propagate_on_container_move_assignment<_Alloc>::value>\nstruct __propagate_on_container_move_assignment\n{\n    typedef false_type type;\n};\n\ntemplate <class _Alloc>\nstruct __propagate_on_container_move_assignment<_Alloc, true>\n{\n    typedef typename _Alloc::propagate_on_container_move_assignment type;\n};\n\ntemplate <class _Tp>\nstruct __has_propagate_on_container_swap\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::propagate_on_container_swap* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\ntemplate <class _Alloc, bool = __has_propagate_on_container_swap<_Alloc>::value>\nstruct __propagate_on_container_swap\n{\n    typedef false_type type;\n};\n\ntemplate <class _Alloc>\nstruct __propagate_on_container_swap<_Alloc, true>\n{\n    typedef typename _Alloc::propagate_on_container_swap type;\n};\n\ntemplate <class _Tp>\nstruct __has_is_always_equal\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Up> static __two __test(...);\n    template <class _Up> static char __test(typename _Up::is_always_equal* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\ntemplate <class _Alloc, bool = __has_is_always_equal<_Alloc>::value>\nstruct __is_always_equal\n{\n    typedef typename _VSTD::is_empty<_Alloc>::type type;\n};\n\ntemplate <class _Alloc>\nstruct __is_always_equal<_Alloc, true>\n{\n    typedef typename _Alloc::is_always_equal type;\n};\n\ntemplate <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>\nstruct __has_rebind_other\n{\nprivate:\n    struct __two {char __lx; char __lxx;};\n    template <class _Xp> static __two __test(...);\n    template <class _Xp> static char __test(typename _Xp::template rebind<_Up>::other* = 0);\npublic:\n    static const bool value = sizeof(__test<_Tp>(0)) == 1;\n};\n\ntemplate <class _Tp, class _Up>\nstruct __has_rebind_other<_Tp, _Up, false>\n{\n    static const bool value = false;\n};\n\ntemplate <class _Tp, class _Up, bool = __has_rebind_other<_Tp, _Up>::value>\nstruct __allocator_traits_rebind\n{\n    typedef typename _Tp::template rebind<_Up>::other type;\n};\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>\nstruct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, true>\n{\n    typedef typename _Alloc<_Tp, _Args...>::template rebind<_Up>::other type;\n};\n\ntemplate <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>\nstruct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, false>\n{\n    typedef _Alloc<_Up, _Args...> type;\n};\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <template <class> class _Alloc, class _Tp, class _Up>\nstruct __allocator_traits_rebind<_Alloc<_Tp>, _Up, true>\n{\n    typedef typename _Alloc<_Tp>::template rebind<_Up>::other type;\n};\n\ntemplate <template <class> class _Alloc, class _Tp, class _Up>\nstruct __allocator_traits_rebind<_Alloc<_Tp>, _Up, false>\n{\n    typedef _Alloc<_Up> type;\n};\n\ntemplate <template <class, class> class _Alloc, class _Tp, class _A0, class _Up>\nstruct __allocator_traits_rebind<_Alloc<_Tp, _A0>, _Up, true>\n{\n    typedef typename _Alloc<_Tp, _A0>::template rebind<_Up>::other type;\n};\n\ntemplate <template <class, class> class _Alloc, class _Tp, class _A0, class _Up>\nstruct __allocator_traits_rebind<_Alloc<_Tp, _A0>, _Up, false>\n{\n    typedef _Alloc<_Up, _A0> type;\n};\n\ntemplate <template <class, class, class> class _Alloc, class _Tp, class _A0,\n                                         class _A1, class _Up>\nstruct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1>, _Up, true>\n{\n    typedef typename _Alloc<_Tp, _A0, _A1>::template rebind<_Up>::other type;\n};\n\ntemplate <template <class, class, class> class _Alloc, class _Tp, class _A0,\n                                         class _A1, class _Up>\nstruct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1>, _Up, false>\n{\n    typedef _Alloc<_Up, _A0, _A1> type;\n};\n\ntemplate <template <class, class, class, class> class _Alloc, class _Tp, class _A0,\n                                                class _A1, class _A2, class _Up>\nstruct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, true>\n{\n    typedef typename _Alloc<_Tp, _A0, _A1, _A2>::template rebind<_Up>::other type;\n};\n\ntemplate <template <class, class, class, class> class _Alloc, class _Tp, class _A0,\n                                                class _A1, class _A2, class _Up>\nstruct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, false>\n{\n    typedef _Alloc<_Up, _A0, _A1, _A2> type;\n};\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE\n\ntemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>\nauto\n__has_allocate_hint_test(_Alloc&& __a, _SizeType&& __sz, _ConstVoidPtr&& __p)\n    -> decltype(__a.allocate(__sz, __p), true_type());\n\ntemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>\nauto\n__has_allocate_hint_test(const _Alloc& __a, _SizeType&& __sz, _ConstVoidPtr&& __p)\n    -> false_type;\n\ntemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>\nstruct __has_allocate_hint\n    : integral_constant<bool,\n        is_same<\n            decltype(__has_allocate_hint_test(declval<_Alloc>(),\n                                          declval<_SizeType>(),\n                                          declval<_ConstVoidPtr>())),\n            true_type>::value>\n{\n};\n\n#else  // _LIBCPP_HAS_NO_ADVANCED_SFINAE\n\ntemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>\nstruct __has_allocate_hint\n    : true_type\n{\n};\n\n#endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE\n\n#if !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n\ntemplate <class _Alloc, class _Tp, class ..._Args>\ndecltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Tp*>(),\n                                           _VSTD::declval<_Args>()...),\n                                           true_type())\n__has_construct_test(_Alloc&& __a, _Tp* __p, _Args&& ...__args);\n\ntemplate <class _Alloc, class _Pointer, class ..._Args>\nfalse_type\n__has_construct_test(const _Alloc& __a, _Pointer&& __p, _Args&& ...__args);\n\ntemplate <class _Alloc, class _Pointer, class ..._Args>\nstruct __has_construct\n    : integral_constant<bool,\n        is_same<\n            decltype(__has_construct_test(declval<_Alloc>(),\n                                          declval<_Pointer>(),\n                                          declval<_Args>()...)),\n            true_type>::value>\n{\n};\n\ntemplate <class _Alloc, class _Pointer>\nauto\n__has_destroy_test(_Alloc&& __a, _Pointer&& __p)\n    -> decltype(__a.destroy(__p), true_type());\n\ntemplate <class _Alloc, class _Pointer>\nauto\n__has_destroy_test(const _Alloc& __a, _Pointer&& __p)\n    -> false_type;\n\ntemplate <class _Alloc, class _Pointer>\nstruct __has_destroy\n    : integral_constant<bool,\n        is_same<\n            decltype(__has_destroy_test(declval<_Alloc>(),\n                                        declval<_Pointer>())),\n            true_type>::value>\n{\n};\n\ntemplate <class _Alloc>\nauto\n__has_max_size_test(_Alloc&& __a)\n    -> decltype(__a.max_size(), true_type());\n\ntemplate <class _Alloc>\nauto\n__has_max_size_test(const volatile _Alloc& __a)\n    -> false_type;\n\ntemplate <class _Alloc>\nstruct __has_max_size\n    : integral_constant<bool,\n        is_same<\n            decltype(__has_max_size_test(declval<_Alloc&>())),\n            true_type>::value>\n{\n};\n\ntemplate <class _Alloc>\nauto\n__has_select_on_container_copy_construction_test(_Alloc&& __a)\n    -> decltype(__a.select_on_container_copy_construction(), true_type());\n\ntemplate <class _Alloc>\nauto\n__has_select_on_container_copy_construction_test(const volatile _Alloc& __a)\n    -> false_type;\n\ntemplate <class _Alloc>\nstruct __has_select_on_container_copy_construction\n    : integral_constant<bool,\n        is_same<\n            decltype(__has_select_on_container_copy_construction_test(declval<_Alloc&>())),\n            true_type>::value>\n{\n};\n\n#else  // _LIBCPP_HAS_NO_ADVANCED_SFINAE\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Alloc, class _Pointer, class ..._Args>\nstruct __has_construct\n    : false_type\n{\n};\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Alloc, class _Pointer, class _Args>\nstruct __has_construct\n    : false_type\n{\n};\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Alloc, class _Pointer>\nstruct __has_destroy\n    : false_type\n{\n};\n\ntemplate <class _Alloc>\nstruct __has_max_size\n    : true_type\n{\n};\n\ntemplate <class _Alloc>\nstruct __has_select_on_container_copy_construction\n    : false_type\n{\n};\n\n#endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE\n\ntemplate <class _Alloc, class _Ptr, bool = __has_difference_type<_Alloc>::value>\nstruct __alloc_traits_difference_type\n{\n    typedef typename pointer_traits<_Ptr>::difference_type type;\n};\n\ntemplate <class _Alloc, class _Ptr>\nstruct __alloc_traits_difference_type<_Alloc, _Ptr, true>\n{\n    typedef typename _Alloc::difference_type type;\n};\n\ntemplate <class _Alloc>\nstruct _LIBCPP_TYPE_VIS_ONLY allocator_traits\n{\n    typedef _Alloc                              allocator_type;\n    typedef typename allocator_type::value_type value_type;\n\n    typedef typename __pointer_type<value_type, allocator_type>::type pointer;\n    typedef typename __const_pointer<value_type, pointer, allocator_type>::type const_pointer;\n    typedef typename __void_pointer<pointer, allocator_type>::type void_pointer;\n    typedef typename __const_void_pointer<pointer, allocator_type>::type const_void_pointer;\n\n    typedef typename __alloc_traits_difference_type<allocator_type, pointer>::type difference_type;\n    typedef typename __size_type<allocator_type, difference_type>::type size_type;\n\n    typedef typename __propagate_on_container_copy_assignment<allocator_type>::type\n                     propagate_on_container_copy_assignment;\n    typedef typename __propagate_on_container_move_assignment<allocator_type>::type\n                     propagate_on_container_move_assignment;\n    typedef typename __propagate_on_container_swap<allocator_type>::type\n                     propagate_on_container_swap;\n    typedef typename __is_always_equal<allocator_type>::type\n                     is_always_equal;\n\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n    template <class _Tp> using rebind_alloc =\n                  typename __allocator_traits_rebind<allocator_type, _Tp>::type;\n    template <class _Tp> using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;\n#else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n    template <class _Tp> struct rebind_alloc\n        {typedef typename __allocator_traits_rebind<allocator_type, _Tp>::type other;};\n    template <class _Tp> struct rebind_traits\n        {typedef allocator_traits<typename rebind_alloc<_Tp>::other> other;};\n#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\n    _LIBCPP_INLINE_VISIBILITY\n    static pointer allocate(allocator_type& __a, size_type __n)\n        {return __a.allocate(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    static pointer allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)\n        {return allocate(__a, __n, __hint,\n            __has_allocate_hint<allocator_type, size_type, const_void_pointer>());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    static void deallocate(allocator_type& __a, pointer __p, size_type __n) _NOEXCEPT\n        {__a.deallocate(__p, __n);}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class _Tp, class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        static void construct(allocator_type& __a, _Tp* __p, _Args&&... __args)\n            {__construct(__has_construct<allocator_type, _Tp*, _Args...>(),\n                         __a, __p, _VSTD::forward<_Args>(__args)...);}\n#else  // _LIBCPP_HAS_NO_VARIADICS\n    template <class _Tp>\n        _LIBCPP_INLINE_VISIBILITY\n        static void construct(allocator_type& __a, _Tp* __p)\n            {\n                ::new ((void*)__p) _Tp();\n            }\n    template <class _Tp, class _A0>\n        _LIBCPP_INLINE_VISIBILITY\n        static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0)\n            {\n                ::new ((void*)__p) _Tp(__a0);\n            }\n    template <class _Tp, class _A0, class _A1>\n        _LIBCPP_INLINE_VISIBILITY\n        static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0,\n                              const _A1& __a1)\n            {\n                ::new ((void*)__p) _Tp(__a0, __a1);\n            }\n    template <class _Tp, class _A0, class _A1, class _A2>\n        _LIBCPP_INLINE_VISIBILITY\n        static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0,\n                              const _A1& __a1, const _A2& __a2)\n            {\n                ::new ((void*)__p) _Tp(__a0, __a1, __a2);\n            }\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n    template <class _Tp>\n        _LIBCPP_INLINE_VISIBILITY\n        static void destroy(allocator_type& __a, _Tp* __p)\n            {__destroy(__has_destroy<allocator_type, _Tp*>(), __a, __p);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    static size_type max_size(const allocator_type& __a) _NOEXCEPT\n        {return __max_size(__has_max_size<const allocator_type>(), __a);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    static allocator_type\n        select_on_container_copy_construction(const allocator_type& __a)\n            {return select_on_container_copy_construction(\n                __has_select_on_container_copy_construction<const allocator_type>(),\n                __a);}\n\n    template <class _Ptr>\n        _LIBCPP_INLINE_VISIBILITY\n        static\n        void\n        __construct_forward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2)\n        {\n            for (; __begin1 != __end1; ++__begin1, ++__begin2)\n                construct(__a, _VSTD::__to_raw_pointer(__begin2), _VSTD::move_if_noexcept(*__begin1));\n        }\n\n    template <class _Tp>\n        _LIBCPP_INLINE_VISIBILITY\n        static\n        typename enable_if\n        <\n            (is_same<allocator_type, allocator<_Tp> >::value\n                || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&\n             is_trivially_move_constructible<_Tp>::value,\n            void\n        >::type\n        __construct_forward(allocator_type& __a, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2)\n        {\n            ptrdiff_t _Np = __end1 - __begin1;\n            if (_Np > 0)\n            {\n                _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Tp));\n                __begin2 += _Np;\n            }\n        }\n\n    template <class _Iter, class _Ptr>\n        _LIBCPP_INLINE_VISIBILITY\n        static\n        void\n        __construct_range_forward(allocator_type& __a, _Iter __begin1, _Iter __end1, _Ptr& __begin2)\n        {\n            for (; __begin1 != __end1; ++__begin1, (void) ++__begin2)\n                construct(__a, _VSTD::__to_raw_pointer(__begin2), *__begin1);\n        }\n\n    template <class _Tp>\n        _LIBCPP_INLINE_VISIBILITY\n        static\n        typename enable_if\n        <\n            (is_same<allocator_type, allocator<_Tp> >::value\n                || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&\n             is_trivially_move_constructible<_Tp>::value,\n            void\n        >::type\n        __construct_range_forward(allocator_type& __a, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2)\n        {\n            typedef typename remove_const<_Tp>::type _Vp;\n            ptrdiff_t _Np = __end1 - __begin1;\n            if (_Np > 0)\n            {\n                _VSTD::memcpy(const_cast<_Vp*>(__begin2), __begin1, _Np * sizeof(_Tp));\n                __begin2 += _Np;\n            }\n        }\n\n    template <class _Ptr>\n        _LIBCPP_INLINE_VISIBILITY\n        static\n        void\n        __construct_backward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2)\n        {\n            while (__end1 != __begin1)\n            {\n                construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD::move_if_noexcept(*--__end1));\n                --__end2;\n            }\n        }\n\n    template <class _Tp>\n        _LIBCPP_INLINE_VISIBILITY\n        static\n        typename enable_if\n        <\n            (is_same<allocator_type, allocator<_Tp> >::value\n                || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&\n             is_trivially_move_constructible<_Tp>::value,\n            void\n        >::type\n        __construct_backward(allocator_type& __a, _Tp* __begin1, _Tp* __end1, _Tp*& __end2)\n        {\n            ptrdiff_t _Np = __end1 - __begin1;\n            __end2 -= _Np;\n            if (_Np > 0)\n                _VSTD::memcpy(__end2, __begin1, _Np * sizeof(_Tp));\n        }\n\nprivate:\n\n    _LIBCPP_INLINE_VISIBILITY\n    static pointer allocate(allocator_type& __a, size_type __n,\n        const_void_pointer __hint, true_type)\n        {return __a.allocate(__n, __hint);}\n    _LIBCPP_INLINE_VISIBILITY\n    static pointer allocate(allocator_type& __a, size_type __n,\n        const_void_pointer, false_type)\n        {return __a.allocate(__n);}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class _Tp, class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        static void __construct(true_type, allocator_type& __a, _Tp* __p, _Args&&... __args)\n            {__a.construct(__p, _VSTD::forward<_Args>(__args)...);}\n    template <class _Tp, class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        static void __construct(false_type, allocator_type&, _Tp* __p, _Args&&... __args)\n            {\n                ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);\n            }\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n    template <class _Tp>\n        _LIBCPP_INLINE_VISIBILITY\n        static void __destroy(true_type, allocator_type& __a, _Tp* __p)\n            {__a.destroy(__p);}\n    template <class _Tp>\n        _LIBCPP_INLINE_VISIBILITY\n        static void __destroy(false_type, allocator_type&, _Tp* __p)\n            {\n                __p->~_Tp();\n            }\n\n    _LIBCPP_INLINE_VISIBILITY\n    static size_type __max_size(true_type, const allocator_type& __a)\n            {return __a.max_size();}\n    _LIBCPP_INLINE_VISIBILITY\n    static size_type __max_size(false_type, const allocator_type&)\n            {return numeric_limits<size_type>::max();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    static allocator_type\n        select_on_container_copy_construction(true_type, const allocator_type& __a)\n            {return __a.select_on_container_copy_construction();}\n    _LIBCPP_INLINE_VISIBILITY\n    static allocator_type\n        select_on_container_copy_construction(false_type, const allocator_type& __a)\n            {return __a;}\n};\n\ntemplate <class _Traits, class _Tp>\nstruct __rebind_alloc_helper\n{\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n    typedef typename _Traits::template rebind_alloc<_Tp>        type;\n#else\n    typedef typename _Traits::template rebind_alloc<_Tp>::other type;\n#endif\n};\n\n// allocator\n\ntemplate <class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY allocator\n{\npublic:\n    typedef size_t            size_type;\n    typedef ptrdiff_t         difference_type;\n    typedef _Tp*              pointer;\n    typedef const _Tp*        const_pointer;\n    typedef _Tp&              reference;\n    typedef const _Tp&        const_reference;\n    typedef _Tp               value_type;\n\n    typedef true_type propagate_on_container_move_assignment;\n    typedef true_type is_always_equal;\n\n    template <class _Up> struct rebind {typedef allocator<_Up> other;};\n\n    _LIBCPP_INLINE_VISIBILITY allocator() _NOEXCEPT {}\n    template <class _Up> _LIBCPP_INLINE_VISIBILITY allocator(const allocator<_Up>&) _NOEXCEPT {}\n    _LIBCPP_INLINE_VISIBILITY pointer address(reference __x) const _NOEXCEPT\n        {return _VSTD::addressof(__x);}\n    _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT\n        {return _VSTD::addressof(__x);}\n    _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0)\n        {return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));}\n    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT\n        {_VSTD::__deallocate((void*)__p);}\n    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT\n        {return size_type(~0) / sizeof(_Tp);}\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    template <class _Up, class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(_Up* __p, _Args&&... __args)\n        {\n            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);\n        }\n#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(pointer __p)\n        {\n            ::new((void*)__p) _Tp();\n        }\n# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n\n    template <class _A0>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(pointer __p, _A0& __a0)\n        {\n            ::new((void*)__p) _Tp(__a0);\n        }\n    template <class _A0>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(pointer __p, const _A0& __a0)\n        {\n            ::new((void*)__p) _Tp(__a0);\n        }\n# endif  // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n    template <class _A0, class _A1>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(pointer __p, _A0& __a0, _A1& __a1)\n        {\n            ::new((void*)__p) _Tp(__a0, __a1);\n        }\n    template <class _A0, class _A1>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(pointer __p, const _A0& __a0, _A1& __a1)\n        {\n            ::new((void*)__p) _Tp(__a0, __a1);\n        }\n    template <class _A0, class _A1>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(pointer __p, _A0& __a0, const _A1& __a1)\n        {\n            ::new((void*)__p) _Tp(__a0, __a1);\n        }\n    template <class _A0, class _A1>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(pointer __p, const _A0& __a0, const _A1& __a1)\n        {\n            ::new((void*)__p) _Tp(__a0, __a1);\n        }\n#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}\n};\n\ntemplate <class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY allocator<const _Tp>\n{\npublic:\n    typedef size_t            size_type;\n    typedef ptrdiff_t         difference_type;\n    typedef const _Tp*        pointer;\n    typedef const _Tp*        const_pointer;\n    typedef const _Tp&        reference;\n    typedef const _Tp&        const_reference;\n    typedef const _Tp         value_type;\n\n    typedef true_type propagate_on_container_move_assignment;\n    typedef true_type is_always_equal;\n\n    template <class _Up> struct rebind {typedef allocator<_Up> other;};\n\n    _LIBCPP_INLINE_VISIBILITY allocator() _NOEXCEPT {}\n    template <class _Up> _LIBCPP_INLINE_VISIBILITY allocator(const allocator<_Up>&) _NOEXCEPT {}\n    _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT\n        {return _VSTD::addressof(__x);}\n    _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0)\n        {return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));}\n    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT\n        {_VSTD::__deallocate((void*)__p);}\n    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT\n        {return size_type(~0) / sizeof(_Tp);}\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    template <class _Up, class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(_Up* __p, _Args&&... __args)\n        {\n            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);\n        }\n#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(pointer __p)\n        {\n            ::new((void*)__p) _Tp();\n        }\n# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n\n    template <class _A0>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(pointer __p, _A0& __a0)\n        {\n            ::new((void*)__p) _Tp(__a0);\n        }\n    template <class _A0>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(pointer __p, const _A0& __a0)\n        {\n            ::new((void*)__p) _Tp(__a0);\n        }\n# endif  // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n    template <class _A0, class _A1>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(pointer __p, _A0& __a0, _A1& __a1)\n        {\n            ::new((void*)__p) _Tp(__a0, __a1);\n        }\n    template <class _A0, class _A1>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(pointer __p, const _A0& __a0, _A1& __a1)\n        {\n            ::new((void*)__p) _Tp(__a0, __a1);\n        }\n    template <class _A0, class _A1>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(pointer __p, _A0& __a0, const _A1& __a1)\n        {\n            ::new((void*)__p) _Tp(__a0, __a1);\n        }\n    template <class _A0, class _A1>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        construct(pointer __p, const _A0& __a0, const _A1& __a1)\n        {\n            ::new((void*)__p) _Tp(__a0, __a1);\n        }\n#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}\n};\n\ntemplate <class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\nbool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;}\n\ntemplate <class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\nbool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;}\n\ntemplate <class _OutputIterator, class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY raw_storage_iterator\n    : public iterator<output_iterator_tag,\n                      _Tp,                                         // purposefully not C++03\n                      ptrdiff_t,                                   // purposefully not C++03\n                      _Tp*,                                        // purposefully not C++03\n                      raw_storage_iterator<_OutputIterator, _Tp>&> // purposefully not C++03\n{\nprivate:\n    _OutputIterator __x_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {}\n    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;}\n    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element)\n        {::new(&*__x_) _Tp(__element); return *this;}\n    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator++() {++__x_; return *this;}\n    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator  operator++(int)\n        {raw_storage_iterator __t(*this); ++__x_; return __t;}\n#if _LIBCPP_STD_VER >= 14\n    _LIBCPP_INLINE_VISIBILITY _OutputIterator base() const { return __x_; } \n#endif\n};\n\ntemplate <class _Tp>\npair<_Tp*, ptrdiff_t>\nget_temporary_buffer(ptrdiff_t __n) _NOEXCEPT\n{\n    pair<_Tp*, ptrdiff_t> __r(0, 0);\n    const ptrdiff_t __m = (~ptrdiff_t(0) ^\n                           ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1)))\n                           / sizeof(_Tp);\n    if (__n > __m)\n        __n = __m;\n    while (__n > 0)\n    {\n        __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow));\n        if (__r.first)\n        {\n            __r.second = __n;\n            break;\n        }\n        __n /= 2;\n    }\n    return __r;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid return_temporary_buffer(_Tp* __p) _NOEXCEPT {::operator delete(__p);}\n\ntemplate <class _Tp>\nstruct auto_ptr_ref\n{\n    _Tp* __ptr_;\n};\n\ntemplate<class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY auto_ptr\n{\nprivate:\n    _Tp* __ptr_;\npublic:\n    typedef _Tp element_type;\n\n    _LIBCPP_INLINE_VISIBILITY explicit auto_ptr(_Tp* __p = 0) throw() : __ptr_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr& __p) throw() : __ptr_(__p.release()) {}\n    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr<_Up>& __p) throw()\n        : __ptr_(__p.release()) {}\n    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr& __p) throw()\n        {reset(__p.release()); return *this;}\n    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr<_Up>& __p) throw()\n        {reset(__p.release()); return *this;}\n    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr_ref<_Tp> __p) throw()\n        {reset(__p.__ptr_); return *this;}\n    _LIBCPP_INLINE_VISIBILITY ~auto_ptr() throw() {delete __ptr_;}\n\n    _LIBCPP_INLINE_VISIBILITY _Tp& operator*() const throw()\n        {return *__ptr_;}\n    _LIBCPP_INLINE_VISIBILITY _Tp* operator->() const throw() {return __ptr_;}\n    _LIBCPP_INLINE_VISIBILITY _Tp* get() const throw() {return __ptr_;}\n    _LIBCPP_INLINE_VISIBILITY _Tp* release() throw()\n    {\n        _Tp* __t = __ptr_;\n        __ptr_ = 0;\n        return __t;\n    }\n    _LIBCPP_INLINE_VISIBILITY void reset(_Tp* __p = 0) throw()\n    {\n        if (__ptr_ != __p)\n            delete __ptr_;\n        __ptr_ = __p;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr_ref<_Tp> __p) throw() : __ptr_(__p.__ptr_) {}\n    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr_ref<_Up>() throw()\n        {auto_ptr_ref<_Up> __t; __t.__ptr_ = release(); return __t;}\n    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr<_Up>() throw()\n        {return auto_ptr<_Up>(release());}\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS_ONLY auto_ptr<void>\n{\npublic:\n    typedef void element_type;\n};\n\ntemplate <class _T1, class _T2, bool = is_same<typename remove_cv<_T1>::type,\n                                                     typename remove_cv<_T2>::type>::value,\n                                bool = is_empty<_T1>::value\n                                       && !__libcpp_is_final<_T1>::value,\n                                bool = is_empty<_T2>::value\n                                       && !__libcpp_is_final<_T2>::value\n         >\nstruct __libcpp_compressed_pair_switch;\n\ntemplate <class _T1, class _T2, bool IsSame>\nstruct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, false, false> {enum {value = 0};};\n\ntemplate <class _T1, class _T2, bool IsSame>\nstruct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, true, false>  {enum {value = 1};};\n\ntemplate <class _T1, class _T2, bool IsSame>\nstruct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, false, true>  {enum {value = 2};};\n\ntemplate <class _T1, class _T2>\nstruct __libcpp_compressed_pair_switch<_T1, _T2, false, true, true>    {enum {value = 3};};\n\ntemplate <class _T1, class _T2>\nstruct __libcpp_compressed_pair_switch<_T1, _T2, true, true, true>     {enum {value = 1};};\n\ntemplate <class _T1, class _T2, unsigned = __libcpp_compressed_pair_switch<_T1, _T2>::value>\nclass __libcpp_compressed_pair_imp;\n\ntemplate <class _T1, class _T2>\nclass __libcpp_compressed_pair_imp<_T1, _T2, 0>\n{\nprivate:\n    _T1 __first_;\n    _T2 __second_;\npublic:\n    typedef _T1 _T1_param;\n    typedef _T2 _T2_param;\n\n    typedef typename remove_reference<_T1>::type& _T1_reference;\n    typedef typename remove_reference<_T2>::type& _T2_reference;\n\n    typedef const typename remove_reference<_T1>::type& _T1_const_reference;\n    typedef const typename remove_reference<_T2>::type& _T2_const_reference;\n\n    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __first_(), __second_() {}\n    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)\n        : __first_(_VSTD::forward<_T1_param>(__t1)), __second_() {}\n    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)\n        : __first_(), __second_(_VSTD::forward<_T2_param>(__t2)) {}\n    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)\n        : __first_(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}\n\n#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)\n        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&\n                   is_nothrow_copy_constructible<_T2>::value)\n        : __first_(__p.first()),\n          __second_(__p.second()) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p)\n        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&\n                   is_nothrow_copy_assignable<_T2>::value)\n        {\n            __first_ = __p.first();\n            __second_ = __p.second();\n            return *this;\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)\n        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&\n                   is_nothrow_move_constructible<_T2>::value)\n        : __first_(_VSTD::forward<_T1>(__p.first())),\n          __second_(_VSTD::forward<_T2>(__p.second())) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p)\n        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&\n                   is_nothrow_move_assignable<_T2>::value)\n        {\n            __first_ = _VSTD::forward<_T1>(__p.first());\n            __second_ = _VSTD::forward<_T2>(__p.second());\n            return *this;\n        }\n\n#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>\n        _LIBCPP_INLINE_VISIBILITY\n        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,\n                                     tuple<_Args1...> __first_args,\n                                     tuple<_Args2...> __second_args,\n                                     __tuple_indices<_I1...>,\n                                     __tuple_indices<_I2...>)\n            : __first_(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...),\n              __second_(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)\n            {}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return __first_;}\n    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return __first_;}\n\n    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return __second_;}\n    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return __second_;}\n\n    _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp& __x)\n        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&\n                   __is_nothrow_swappable<_T2>::value)\n    {\n        using _VSTD::swap;\n        swap(__first_, __x.__first_);\n        swap(__second_, __x.__second_);\n    }\n};\n\ntemplate <class _T1, class _T2>\nclass __libcpp_compressed_pair_imp<_T1, _T2, 1>\n    : private _T1\n{\nprivate:\n    _T2 __second_;\npublic:\n    typedef _T1 _T1_param;\n    typedef _T2 _T2_param;\n\n    typedef _T1&                                        _T1_reference;\n    typedef typename remove_reference<_T2>::type& _T2_reference;\n\n    typedef const _T1&                                        _T1_const_reference;\n    typedef const typename remove_reference<_T2>::type& _T2_const_reference;\n\n    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __second_() {}\n    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)\n        : _T1(_VSTD::forward<_T1_param>(__t1)), __second_() {}\n    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)\n        : __second_(_VSTD::forward<_T2_param>(__t2)) {}\n    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)\n        : _T1(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}\n\n#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)\n        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&\n                   is_nothrow_copy_constructible<_T2>::value)\n        : _T1(__p.first()), __second_(__p.second()) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p)\n        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&\n                   is_nothrow_copy_assignable<_T2>::value)\n        {\n            _T1::operator=(__p.first());\n            __second_ = __p.second();\n            return *this;\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)\n        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&\n                   is_nothrow_move_constructible<_T2>::value)\n        : _T1(_VSTD::move(__p.first())), __second_(_VSTD::forward<_T2>(__p.second())) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p)\n        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&\n                   is_nothrow_move_assignable<_T2>::value)\n        {\n            _T1::operator=(_VSTD::move(__p.first()));\n            __second_ = _VSTD::forward<_T2>(__p.second());\n            return *this;\n        }\n\n#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>\n        _LIBCPP_INLINE_VISIBILITY\n        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,\n                                     tuple<_Args1...> __first_args,\n                                     tuple<_Args2...> __second_args,\n                                     __tuple_indices<_I1...>,\n                                     __tuple_indices<_I2...>)\n            : _T1(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...),\n              __second_(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)\n            {}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return *this;}\n    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return *this;}\n\n    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return __second_;}\n    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return __second_;}\n\n    _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp& __x)\n        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&\n                   __is_nothrow_swappable<_T2>::value)\n    {\n        using _VSTD::swap;\n        swap(__second_, __x.__second_);\n    }\n};\n\ntemplate <class _T1, class _T2>\nclass __libcpp_compressed_pair_imp<_T1, _T2, 2>\n    : private _T2\n{\nprivate:\n    _T1 __first_;\npublic:\n    typedef _T1 _T1_param;\n    typedef _T2 _T2_param;\n\n    typedef typename remove_reference<_T1>::type& _T1_reference;\n    typedef _T2&                                        _T2_reference;\n\n    typedef const typename remove_reference<_T1>::type& _T1_const_reference;\n    typedef const _T2&                                        _T2_const_reference;\n\n    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __first_() {}\n    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)\n        : __first_(_VSTD::forward<_T1_param>(__t1)) {}\n    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)\n        : _T2(_VSTD::forward<_T2_param>(__t2)), __first_() {}\n    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)\n        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&\n                   is_nothrow_move_constructible<_T2>::value)\n        : _T2(_VSTD::forward<_T2_param>(__t2)), __first_(_VSTD::forward<_T1_param>(__t1)) {}\n\n#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)\n        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&\n                   is_nothrow_copy_constructible<_T2>::value)\n        : _T2(__p.second()), __first_(__p.first()) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p)\n        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&\n                   is_nothrow_copy_assignable<_T2>::value)\n        {\n            _T2::operator=(__p.second());\n            __first_ = __p.first();\n            return *this;\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)\n        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&\n                   is_nothrow_move_constructible<_T2>::value)\n        : _T2(_VSTD::forward<_T2>(__p.second())), __first_(_VSTD::move(__p.first())) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p)\n        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&\n                   is_nothrow_move_assignable<_T2>::value)\n        {\n            _T2::operator=(_VSTD::forward<_T2>(__p.second()));\n            __first_ = _VSTD::move(__p.first());\n            return *this;\n        }\n\n#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>\n        _LIBCPP_INLINE_VISIBILITY\n        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,\n                                     tuple<_Args1...> __first_args,\n                                     tuple<_Args2...> __second_args,\n                                     __tuple_indices<_I1...>,\n                                     __tuple_indices<_I2...>)\n            : _T2(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...),\n              __first_(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...)\n              \n            {}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return __first_;}\n    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return __first_;}\n\n    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return *this;}\n    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return *this;}\n\n    _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp& __x)\n        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&\n                   __is_nothrow_swappable<_T2>::value)\n    {\n        using _VSTD::swap;\n        swap(__first_, __x.__first_);\n    }\n};\n\ntemplate <class _T1, class _T2>\nclass __libcpp_compressed_pair_imp<_T1, _T2, 3>\n    : private _T1,\n      private _T2\n{\npublic:\n    typedef _T1 _T1_param;\n    typedef _T2 _T2_param;\n\n    typedef _T1& _T1_reference;\n    typedef _T2& _T2_reference;\n\n    typedef const _T1& _T1_const_reference;\n    typedef const _T2& _T2_const_reference;\n\n    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() {}\n    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)\n        : _T1(_VSTD::forward<_T1_param>(__t1)) {}\n    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)\n        : _T2(_VSTD::forward<_T2_param>(__t2)) {}\n    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)\n        : _T1(_VSTD::forward<_T1_param>(__t1)), _T2(_VSTD::forward<_T2_param>(__t2)) {}\n\n#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)\n        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&\n                   is_nothrow_copy_constructible<_T2>::value)\n        : _T1(__p.first()), _T2(__p.second()) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p)\n        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&\n                   is_nothrow_copy_assignable<_T2>::value)\n        {\n            _T1::operator=(__p.first());\n            _T2::operator=(__p.second());\n            return *this;\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)\n        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&\n                   is_nothrow_move_constructible<_T2>::value)\n        : _T1(_VSTD::move(__p.first())), _T2(_VSTD::move(__p.second())) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p)\n        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&\n                   is_nothrow_move_assignable<_T2>::value)\n        {\n            _T1::operator=(_VSTD::move(__p.first()));\n            _T2::operator=(_VSTD::move(__p.second()));\n            return *this;\n        }\n\n#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>\n        _LIBCPP_INLINE_VISIBILITY\n        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,\n                                     tuple<_Args1...> __first_args,\n                                     tuple<_Args2...> __second_args,\n                                     __tuple_indices<_I1...>,\n                                     __tuple_indices<_I2...>)\n            : _T1(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...),\n              _T2(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)\n            {}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return *this;}\n    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return *this;}\n\n    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return *this;}\n    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return *this;}\n\n    _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp&)\n        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&\n                   __is_nothrow_swappable<_T2>::value)\n    {\n    }\n};\n\ntemplate <class _T1, class _T2>\nclass __compressed_pair\n    : private __libcpp_compressed_pair_imp<_T1, _T2>\n{\n    typedef __libcpp_compressed_pair_imp<_T1, _T2> base;\npublic:\n    typedef typename base::_T1_param _T1_param;\n    typedef typename base::_T2_param _T2_param;\n\n    typedef typename base::_T1_reference _T1_reference;\n    typedef typename base::_T2_reference _T2_reference;\n\n    typedef typename base::_T1_const_reference _T1_const_reference;\n    typedef typename base::_T2_const_reference _T2_const_reference;\n\n    _LIBCPP_INLINE_VISIBILITY __compressed_pair() {}\n    _LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T1_param __t1)\n        : base(_VSTD::forward<_T1_param>(__t1)) {}\n    _LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T2_param __t2)\n        : base(_VSTD::forward<_T2_param>(__t2)) {}\n    _LIBCPP_INLINE_VISIBILITY __compressed_pair(_T1_param __t1, _T2_param __t2)\n        : base(_VSTD::forward<_T1_param>(__t1), _VSTD::forward<_T2_param>(__t2)) {}\n\n#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n\n    _LIBCPP_INLINE_VISIBILITY\n    __compressed_pair(const __compressed_pair& __p)\n        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&\n                   is_nothrow_copy_constructible<_T2>::value)\n        : base(__p) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __compressed_pair& operator=(const __compressed_pair& __p)\n        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&\n                   is_nothrow_copy_assignable<_T2>::value)\n        {\n            base::operator=(__p);\n            return *this;\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __compressed_pair(__compressed_pair&& __p)\n        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&\n                   is_nothrow_move_constructible<_T2>::value)\n        : base(_VSTD::move(__p)) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __compressed_pair& operator=(__compressed_pair&& __p)\n        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&\n                   is_nothrow_move_assignable<_T2>::value)\n        {\n            base::operator=(_VSTD::move(__p));\n            return *this;\n        }\n\n#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n    template <class... _Args1, class... _Args2>\n        _LIBCPP_INLINE_VISIBILITY\n        __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,\n                                                      tuple<_Args2...> __second_args)\n            : base(__pc, _VSTD::move(__first_args), _VSTD::move(__second_args),\n                   typename __make_tuple_indices<sizeof...(_Args1)>::type(),\n                   typename __make_tuple_indices<sizeof...(_Args2) >::type())\n            {}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return base::first();}\n    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return base::first();}\n\n    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return base::second();}\n    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return base::second();}\n\n    _LIBCPP_INLINE_VISIBILITY void swap(__compressed_pair& __x)\n        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&\n                   __is_nothrow_swappable<_T2>::value)\n        {base::swap(__x);}\n};\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y)\n        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&\n                   __is_nothrow_swappable<_T2>::value)\n    {__x.swap(__y);}\n\n// __same_or_less_cv_qualified\n\ntemplate <class _Ptr1, class _Ptr2,\n          bool = is_same<typename remove_cv<typename pointer_traits<_Ptr1>::element_type>::type,\n                         typename remove_cv<typename pointer_traits<_Ptr2>::element_type>::type\n                        >::value\n         >\nstruct __same_or_less_cv_qualified_imp\n    : is_convertible<_Ptr1, _Ptr2> {};\n\ntemplate <class _Ptr1, class _Ptr2>\nstruct __same_or_less_cv_qualified_imp<_Ptr1, _Ptr2, false>\n    : false_type {};\n\ntemplate <class _Ptr1, class _Ptr2, bool = is_pointer<_Ptr1>::value ||\n                                           is_same<_Ptr1, _Ptr2>::value ||\n                                           __has_element_type<_Ptr1>::value>\nstruct __same_or_less_cv_qualified\n    : __same_or_less_cv_qualified_imp<_Ptr1, _Ptr2> {};\n\ntemplate <class _Ptr1, class _Ptr2>\nstruct __same_or_less_cv_qualified<_Ptr1, _Ptr2, false>\n    : false_type {};\n\n// default_delete\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY default_delete\n{\n#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT = default;\n#else\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT {}\n#endif\n    template <class _Up>\n        _LIBCPP_INLINE_VISIBILITY default_delete(const default_delete<_Up>&,\n             typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* = 0) _NOEXCEPT {}\n    _LIBCPP_INLINE_VISIBILITY void operator() (_Tp* __ptr) const _NOEXCEPT\n        {\n            static_assert(sizeof(_Tp) > 0, \"default_delete can not delete incomplete type\");\n            static_assert(!is_void<_Tp>::value, \"default_delete can not delete incomplete type\");\n            delete __ptr;\n        }\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY default_delete<_Tp[]>\n{\npublic:\n#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT = default;\n#else\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT {}\n#endif\n    template <class _Up>\n        _LIBCPP_INLINE_VISIBILITY default_delete(const default_delete<_Up[]>&,\n             typename enable_if<__same_or_less_cv_qualified<_Up*, _Tp*>::value>::type* = 0) _NOEXCEPT {}\n    template <class _Up>\n        _LIBCPP_INLINE_VISIBILITY\n        void operator() (_Up* __ptr,\n                         typename enable_if<__same_or_less_cv_qualified<_Up*, _Tp*>::value>::type* = 0) const _NOEXCEPT\n        {\n            static_assert(sizeof(_Tp) > 0, \"default_delete can not delete incomplete type\");\n            static_assert(!is_void<_Tp>::value, \"default_delete can not delete incomplete type\");\n            delete [] __ptr;\n        }\n};\n\ntemplate <class _Tp, class _Dp = default_delete<_Tp> >\nclass _LIBCPP_TYPE_VIS_ONLY unique_ptr\n{\npublic:\n    typedef _Tp element_type;\n    typedef _Dp deleter_type;\n    typedef typename __pointer_type<_Tp, deleter_type>::type pointer;\nprivate:\n    __compressed_pair<pointer, deleter_type> __ptr_;\n\n#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    unique_ptr(unique_ptr&);\n    template <class _Up, class _Ep>\n        unique_ptr(unique_ptr<_Up, _Ep>&);\n    unique_ptr& operator=(unique_ptr&);\n    template <class _Up, class _Ep>\n        unique_ptr& operator=(unique_ptr<_Up, _Ep>&);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    struct __nat {int __for_bool_;};\n\n    typedef       typename remove_reference<deleter_type>::type& _Dp_reference;\n    typedef const typename remove_reference<deleter_type>::type& _Dp_const_reference;\npublic:\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT\n        : __ptr_(pointer())\n        {\n            static_assert(!is_pointer<deleter_type>::value,\n                \"unique_ptr constructed with null function pointer deleter\");\n        }\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT\n        : __ptr_(pointer())\n        {\n            static_assert(!is_pointer<deleter_type>::value,\n                \"unique_ptr constructed with null function pointer deleter\");\n        }\n    _LIBCPP_INLINE_VISIBILITY explicit unique_ptr(pointer __p) _NOEXCEPT\n        : __ptr_(_VSTD::move(__p))\n        {\n            static_assert(!is_pointer<deleter_type>::value,\n                \"unique_ptr constructed with null function pointer deleter\");\n        }\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, typename conditional<\n                                        is_reference<deleter_type>::value,\n                                        deleter_type,\n                                        typename add_lvalue_reference<const deleter_type>::type>::type __d)\n             _NOEXCEPT\n        : __ptr_(__p, __d) {}\n\n    _LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, typename remove_reference<deleter_type>::type&& __d)\n             _NOEXCEPT\n        : __ptr_(__p, _VSTD::move(__d))\n        {\n            static_assert(!is_reference<deleter_type>::value, \"rvalue deleter bound to reference\");\n        }\n    _LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT\n        : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {}\n    template <class _Up, class _Ep>\n        _LIBCPP_INLINE_VISIBILITY\n        unique_ptr(unique_ptr<_Up, _Ep>&& __u,\n                   typename enable_if\n                      <\n                        !is_array<_Up>::value &&\n                         is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value &&\n                         is_convertible<_Ep, deleter_type>::value &&\n                         (\n                            !is_reference<deleter_type>::value ||\n                            is_same<deleter_type, _Ep>::value\n                         ),\n                         __nat\n                      >::type = __nat()) _NOEXCEPT\n            : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {}\n\n    template <class _Up>\n        _LIBCPP_INLINE_VISIBILITY unique_ptr(auto_ptr<_Up>&& __p,\n                typename enable_if<\n                                      is_convertible<_Up*, _Tp*>::value &&\n                                      is_same<_Dp, default_delete<_Tp> >::value,\n                                      __nat\n                                  >::type = __nat()) _NOEXCEPT\n            : __ptr_(__p.release())\n            {\n            }\n\n        _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT\n            {\n                reset(__u.release());\n                __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());\n                return *this;\n            }\n\n        template <class _Up, class _Ep>\n            _LIBCPP_INLINE_VISIBILITY\n            typename enable_if\n            <\n                !is_array<_Up>::value &&\n                is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value &&\n                is_assignable<deleter_type&, _Ep&&>::value,\n                unique_ptr&\n            >::type\n            operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT\n            {\n                reset(__u.release());\n                __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());\n                return *this;\n            }\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY operator __rv<unique_ptr>()\n    {\n        return __rv<unique_ptr>(*this);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY unique_ptr(__rv<unique_ptr> __u)\n        : __ptr_(__u->release(), _VSTD::forward<deleter_type>(__u->get_deleter())) {}\n\n    template <class _Up, class _Ep>\n    _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(unique_ptr<_Up, _Ep> __u)\n    {\n        reset(__u.release());\n        __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, deleter_type __d)\n        : __ptr_(_VSTD::move(__p), _VSTD::move(__d)) {}\n\n    template <class _Up>\n        _LIBCPP_INLINE_VISIBILITY\n                typename enable_if<\n                                      is_convertible<_Up*, _Tp*>::value &&\n                                      is_same<_Dp, default_delete<_Tp> >::value,\n                                      unique_ptr&\n                                  >::type\n        operator=(auto_ptr<_Up> __p)\n            {reset(__p.release()); return *this;}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY ~unique_ptr() {reset();}\n\n    _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(nullptr_t) _NOEXCEPT\n    {\n        reset();\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY typename add_lvalue_reference<_Tp>::type operator*() const\n        {return *__ptr_.first();}\n    _LIBCPP_INLINE_VISIBILITY pointer operator->() const _NOEXCEPT {return __ptr_.first();}\n    _LIBCPP_INLINE_VISIBILITY pointer get() const _NOEXCEPT {return __ptr_.first();}\n    _LIBCPP_INLINE_VISIBILITY       _Dp_reference get_deleter() _NOEXCEPT\n        {return __ptr_.second();}\n    _LIBCPP_INLINE_VISIBILITY _Dp_const_reference get_deleter() const _NOEXCEPT\n        {return __ptr_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n        _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT\n        {return __ptr_.first() != nullptr;}\n\n    _LIBCPP_INLINE_VISIBILITY pointer release() _NOEXCEPT\n    {\n        pointer __t = __ptr_.first();\n        __ptr_.first() = pointer();\n        return __t;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY void reset(pointer __p = pointer()) _NOEXCEPT\n    {\n        pointer __tmp = __ptr_.first();\n        __ptr_.first() = __p;\n        if (__tmp)\n            __ptr_.second()(__tmp);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY void swap(unique_ptr& __u) _NOEXCEPT\n        {__ptr_.swap(__u.__ptr_);}\n};\n\ntemplate <class _Tp, class _Dp>\nclass _LIBCPP_TYPE_VIS_ONLY unique_ptr<_Tp[], _Dp>\n{\npublic:\n    typedef _Tp element_type;\n    typedef _Dp deleter_type;\n    typedef typename __pointer_type<_Tp, deleter_type>::type pointer;\nprivate:\n    __compressed_pair<pointer, deleter_type> __ptr_;\n\n#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    unique_ptr(unique_ptr&);\n    template <class _Up>\n        unique_ptr(unique_ptr<_Up>&);\n    unique_ptr& operator=(unique_ptr&);\n    template <class _Up>\n        unique_ptr& operator=(unique_ptr<_Up>&);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    struct __nat {int __for_bool_;};\n\n    typedef       typename remove_reference<deleter_type>::type& _Dp_reference;\n    typedef const typename remove_reference<deleter_type>::type& _Dp_const_reference;\npublic:\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT\n        : __ptr_(pointer())\n        {\n            static_assert(!is_pointer<deleter_type>::value,\n                \"unique_ptr constructed with null function pointer deleter\");\n        }\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT\n        : __ptr_(pointer())\n        {\n            static_assert(!is_pointer<deleter_type>::value,\n                \"unique_ptr constructed with null function pointer deleter\");\n        }\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Pp>\n    _LIBCPP_INLINE_VISIBILITY explicit unique_ptr(_Pp __p,\n            typename enable_if<__same_or_less_cv_qualified<_Pp, pointer>::value, __nat>::type = __nat()) _NOEXCEPT\n        : __ptr_(__p)\n        {\n            static_assert(!is_pointer<deleter_type>::value,\n                \"unique_ptr constructed with null function pointer deleter\");\n        }\n\n    template <class _Pp>\n    _LIBCPP_INLINE_VISIBILITY unique_ptr(_Pp __p, typename conditional<\n                                       is_reference<deleter_type>::value,\n                                       deleter_type,\n                                       typename add_lvalue_reference<const deleter_type>::type>::type __d,\n                                       typename enable_if<__same_or_less_cv_qualified<_Pp, pointer>::value, __nat>::type = __nat())\n             _NOEXCEPT\n        : __ptr_(__p, __d) {}\n\n    _LIBCPP_INLINE_VISIBILITY unique_ptr(nullptr_t, typename conditional<\n                                       is_reference<deleter_type>::value,\n                                       deleter_type,\n                                       typename add_lvalue_reference<const deleter_type>::type>::type __d)\n             _NOEXCEPT\n        : __ptr_(pointer(), __d) {}\n\n    template <class _Pp>\n    _LIBCPP_INLINE_VISIBILITY unique_ptr(_Pp __p,\n                                         typename remove_reference<deleter_type>::type&& __d,\n                                         typename enable_if<__same_or_less_cv_qualified<_Pp, pointer>::value, __nat>::type = __nat())\n             _NOEXCEPT\n        : __ptr_(__p, _VSTD::move(__d))\n        {\n            static_assert(!is_reference<deleter_type>::value, \"rvalue deleter bound to reference\");\n        }\n\n    _LIBCPP_INLINE_VISIBILITY unique_ptr(nullptr_t, typename remove_reference<deleter_type>::type&& __d)\n             _NOEXCEPT\n        : __ptr_(pointer(), _VSTD::move(__d))\n        {\n            static_assert(!is_reference<deleter_type>::value, \"rvalue deleter bound to reference\");\n        }\n\n    _LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT\n        : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {}\n\n    _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT\n        {\n            reset(__u.release());\n            __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());\n            return *this;\n        }\n\n    template <class _Up, class _Ep>\n        _LIBCPP_INLINE_VISIBILITY\n        unique_ptr(unique_ptr<_Up, _Ep>&& __u,\n                   typename enable_if\n                            <\n                                is_array<_Up>::value &&\n                                __same_or_less_cv_qualified<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value\n                                && is_convertible<_Ep, deleter_type>::value &&\n                                (\n                                    !is_reference<deleter_type>::value ||\n                                    is_same<deleter_type, _Ep>::value\n                                ),\n                                __nat\n                            >::type = __nat()\n                  ) _NOEXCEPT\n        : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {}\n\n\n        template <class _Up, class _Ep>\n            _LIBCPP_INLINE_VISIBILITY\n            typename enable_if\n            <\n                is_array<_Up>::value &&\n                __same_or_less_cv_qualified<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value &&\n                is_assignable<deleter_type&, _Ep&&>::value,\n                unique_ptr&\n            >::type\n            operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT\n            {\n                reset(__u.release());\n                __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());\n                return *this;\n            }\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY explicit unique_ptr(pointer __p)\n        : __ptr_(__p)\n        {\n            static_assert(!is_pointer<deleter_type>::value,\n                \"unique_ptr constructed with null function pointer deleter\");\n        }\n\n    _LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, deleter_type __d)\n        : __ptr_(__p, _VSTD::forward<deleter_type>(__d)) {}\n\n    _LIBCPP_INLINE_VISIBILITY unique_ptr(nullptr_t, deleter_type __d)\n        : __ptr_(pointer(), _VSTD::forward<deleter_type>(__d)) {}\n\n    _LIBCPP_INLINE_VISIBILITY operator __rv<unique_ptr>()\n    {\n        return __rv<unique_ptr>(*this);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY unique_ptr(__rv<unique_ptr> __u)\n        : __ptr_(__u->release(), _VSTD::forward<deleter_type>(__u->get_deleter())) {}\n\n    _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(__rv<unique_ptr> __u)\n    {\n        reset(__u->release());\n        __ptr_.second() = _VSTD::forward<deleter_type>(__u->get_deleter());\n        return *this;\n    }\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY ~unique_ptr() {reset();}\n\n    _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(nullptr_t) _NOEXCEPT\n    {\n        reset();\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY typename add_lvalue_reference<_Tp>::type operator[](size_t __i) const\n        {return __ptr_.first()[__i];}\n    _LIBCPP_INLINE_VISIBILITY pointer get() const _NOEXCEPT {return __ptr_.first();}\n    _LIBCPP_INLINE_VISIBILITY       _Dp_reference get_deleter() _NOEXCEPT\n        {return __ptr_.second();}\n    _LIBCPP_INLINE_VISIBILITY _Dp_const_reference get_deleter() const _NOEXCEPT\n        {return __ptr_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n        _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT\n        {return __ptr_.first() != nullptr;}\n\n    _LIBCPP_INLINE_VISIBILITY pointer release() _NOEXCEPT\n    {\n        pointer __t = __ptr_.first();\n        __ptr_.first() = pointer();\n        return __t;\n    }\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Pp>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__same_or_less_cv_qualified<_Pp, pointer>::value, void>::type\n    reset(_Pp __p) _NOEXCEPT\n    {\n        pointer __tmp = __ptr_.first();\n        __ptr_.first() = __p;\n        if (__tmp)\n            __ptr_.second()(__tmp);\n    }\n    _LIBCPP_INLINE_VISIBILITY void reset(nullptr_t) _NOEXCEPT\n    {\n        pointer __tmp = __ptr_.first();\n        __ptr_.first() = nullptr;\n        if (__tmp)\n            __ptr_.second()(__tmp);\n    }\n    _LIBCPP_INLINE_VISIBILITY void reset() _NOEXCEPT\n    {\n        pointer __tmp = __ptr_.first();\n        __ptr_.first() = nullptr;\n        if (__tmp)\n            __ptr_.second()(__tmp);\n    }\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY void reset(pointer __p = pointer())\n    {\n        pointer __tmp = __ptr_.first();\n        __ptr_.first() = __p;\n        if (__tmp)\n            __ptr_.second()(__tmp);\n    }\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY void swap(unique_ptr& __u) {__ptr_.swap(__u.__ptr_);}\nprivate:\n\n#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Up>\n        explicit unique_ptr(_Up);\n    template <class _Up>\n        unique_ptr(_Up __u,\n                   typename conditional<\n                                       is_reference<deleter_type>::value,\n                                       deleter_type,\n                                       typename add_lvalue_reference<const deleter_type>::type>::type,\n                   typename enable_if\n                      <\n                         is_convertible<_Up, pointer>::value,\n                         __nat\n                      >::type = __nat());\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n};\n\ntemplate <class _Tp, class _Dp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);}\n\ntemplate <class _T1, class _D1, class _T2, class _D2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}\n\ntemplate <class _T1, class _D1, class _T2, class _D2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}\n\ntemplate <class _T1, class _D1, class _T2, class _D2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y)\n{\n    typedef typename unique_ptr<_T1, _D1>::pointer _P1;\n    typedef typename unique_ptr<_T2, _D2>::pointer _P2;\n    typedef typename common_type<_P1, _P2>::type _Vp;\n    return less<_Vp>()(__x.get(), __y.get());\n}\n\ntemplate <class _T1, class _D1, class _T2, class _D2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;}\n\ntemplate <class _T1, class _D1, class _T2, class _D2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);}\n\ntemplate <class _T1, class _D1, class _T2, class _D2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}\n\ntemplate <class _T1, class _D1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT\n{\n    return !__x;\n}\n\ntemplate <class _T1, class _D1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT\n{\n    return !__x;\n}\n\ntemplate <class _T1, class _D1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT\n{\n    return static_cast<bool>(__x);\n}\n\ntemplate <class _T1, class _D1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT\n{\n    return static_cast<bool>(__x);\n}\n\ntemplate <class _T1, class _D1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const unique_ptr<_T1, _D1>& __x, nullptr_t)\n{\n    typedef typename unique_ptr<_T1, _D1>::pointer _P1;\n    return less<_P1>()(__x.get(), nullptr);\n}\n\ntemplate <class _T1, class _D1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(nullptr_t, const unique_ptr<_T1, _D1>& __x)\n{\n    typedef typename unique_ptr<_T1, _D1>::pointer _P1;\n    return less<_P1>()(nullptr, __x.get());\n}\n\ntemplate <class _T1, class _D1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)\n{\n    return nullptr < __x;\n}\n\ntemplate <class _T1, class _D1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)\n{\n    return __x < nullptr;\n}\n\ntemplate <class _T1, class _D1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)\n{\n    return !(nullptr < __x);\n}\n\ntemplate <class _T1, class _D1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)\n{\n    return !(__x < nullptr);\n}\n\ntemplate <class _T1, class _D1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)\n{\n    return !(__x < nullptr);\n}\n\ntemplate <class _T1, class _D1>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)\n{\n    return !(nullptr < __x);\n}\n\n#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Dp>\ninline _LIBCPP_INLINE_VISIBILITY\nunique_ptr<_Tp, _Dp>\nmove(unique_ptr<_Tp, _Dp>& __t)\n{\n    return unique_ptr<_Tp, _Dp>(__rv<unique_ptr<_Tp, _Dp> >(__t));\n}\n\n#endif\n\n#if _LIBCPP_STD_VER > 11\n\ntemplate<class _Tp>\nstruct __unique_if\n{\n    typedef unique_ptr<_Tp> __unique_single;\n};\n\ntemplate<class _Tp>\nstruct __unique_if<_Tp[]>\n{\n    typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;\n};\n\ntemplate<class _Tp, size_t _Np>\nstruct __unique_if<_Tp[_Np]>\n{\n    typedef void __unique_array_known_bound;\n};\n\ntemplate<class _Tp, class... _Args>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __unique_if<_Tp>::__unique_single\nmake_unique(_Args&&... __args)\n{\n    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename __unique_if<_Tp>::__unique_array_unknown_bound\nmake_unique(size_t __n)\n{\n    typedef typename remove_extent<_Tp>::type _Up;\n    return unique_ptr<_Tp>(new _Up[__n]());\n}\n\ntemplate<class _Tp, class... _Args>\n    typename __unique_if<_Tp>::__unique_array_known_bound\n    make_unique(_Args&&...) = delete;\n\n#endif  // _LIBCPP_STD_VER > 11\n\ntemplate <class _Tp> struct hash;\n\ntemplate <class _Size>\ninline _LIBCPP_INLINE_VISIBILITY\n_Size\n__loadword(const void* __p)\n{\n    _Size __r;\n    std::memcpy(&__r, __p, sizeof(__r));\n    return __r;\n}\n\n// We use murmur2 when size_t is 32 bits, and cityhash64 when size_t\n// is 64 bits.  This is because cityhash64 uses 64bit x 64bit\n// multiplication, which can be very slow on 32-bit systems.\ntemplate <class _Size, size_t = sizeof(_Size)*__CHAR_BIT__>\nstruct __murmur2_or_cityhash;\n\ntemplate <class _Size>\nstruct __murmur2_or_cityhash<_Size, 32>\n{\n    _Size operator()(const void* __key, _Size __len);\n};\n\n// murmur2\ntemplate <class _Size>\n_Size\n__murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len)\n{\n    const _Size __m = 0x5bd1e995;\n    const _Size __r = 24;\n    _Size __h = __len;\n    const unsigned char* __data = static_cast<const unsigned char*>(__key);\n    for (; __len >= 4; __data += 4, __len -= 4)\n    {\n        _Size __k = __loadword<_Size>(__data);\n        __k *= __m;\n        __k ^= __k >> __r;\n        __k *= __m;\n        __h *= __m;\n        __h ^= __k;\n    }\n    switch (__len)\n    {\n    case 3:\n        __h ^= __data[2] << 16;\n    case 2:\n        __h ^= __data[1] << 8;\n    case 1:\n        __h ^= __data[0];\n        __h *= __m;\n    }\n    __h ^= __h >> 13;\n    __h *= __m;\n    __h ^= __h >> 15;\n    return __h;\n}\n\ntemplate <class _Size>\nstruct __murmur2_or_cityhash<_Size, 64>\n{\n    _Size operator()(const void* __key, _Size __len);\n\n private:\n  // Some primes between 2^63 and 2^64.\n  static const _Size __k0 = 0xc3a5c85c97cb3127ULL;\n  static const _Size __k1 = 0xb492b66fbe98f273ULL;\n  static const _Size __k2 = 0x9ae16a3b2f90404fULL;\n  static const _Size __k3 = 0xc949d7c7509e6557ULL;\n\n  static _Size __rotate(_Size __val, int __shift) {\n    return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift)));\n  }\n\n  static _Size __rotate_by_at_least_1(_Size __val, int __shift) {\n    return (__val >> __shift) | (__val << (64 - __shift));\n  }\n\n  static _Size __shift_mix(_Size __val) {\n    return __val ^ (__val >> 47);\n  }\n\n  static _Size __hash_len_16(_Size __u, _Size __v) {\n    const _Size __mul = 0x9ddfea08eb382d69ULL;\n    _Size __a = (__u ^ __v) * __mul;\n    __a ^= (__a >> 47);\n    _Size __b = (__v ^ __a) * __mul;\n    __b ^= (__b >> 47);\n    __b *= __mul;\n    return __b;\n  }\n\n  static _Size __hash_len_0_to_16(const char* __s, _Size __len) {\n    if (__len > 8) {\n      const _Size __a = __loadword<_Size>(__s);\n      const _Size __b = __loadword<_Size>(__s + __len - 8);\n      return __hash_len_16(__a, __rotate_by_at_least_1(__b + __len, __len)) ^ __b;\n    }\n    if (__len >= 4) {\n      const uint32_t __a = __loadword<uint32_t>(__s);\n      const uint32_t __b = __loadword<uint32_t>(__s + __len - 4);\n      return __hash_len_16(__len + (__a << 3), __b);\n    }\n    if (__len > 0) {\n      const unsigned char __a = __s[0];\n      const unsigned char __b = __s[__len >> 1];\n      const unsigned char __c = __s[__len - 1];\n      const uint32_t __y = static_cast<uint32_t>(__a) +\n                           (static_cast<uint32_t>(__b) << 8);\n      const uint32_t __z = __len + (static_cast<uint32_t>(__c) << 2);\n      return __shift_mix(__y * __k2 ^ __z * __k3) * __k2;\n    }\n    return __k2;\n  }\n\n  static _Size __hash_len_17_to_32(const char *__s, _Size __len) {\n    const _Size __a = __loadword<_Size>(__s) * __k1;\n    const _Size __b = __loadword<_Size>(__s + 8);\n    const _Size __c = __loadword<_Size>(__s + __len - 8) * __k2;\n    const _Size __d = __loadword<_Size>(__s + __len - 16) * __k0;\n    return __hash_len_16(__rotate(__a - __b, 43) + __rotate(__c, 30) + __d,\n                         __a + __rotate(__b ^ __k3, 20) - __c + __len);\n  }\n\n  // Return a 16-byte hash for 48 bytes.  Quick and dirty.\n  // Callers do best to use \"random-looking\" values for a and b.\n  static pair<_Size, _Size> __weak_hash_len_32_with_seeds(\n      _Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b) {\n    __a += __w;\n    __b = __rotate(__b + __a + __z, 21);\n    const _Size __c = __a;\n    __a += __x;\n    __a += __y;\n    __b += __rotate(__a, 44);\n    return pair<_Size, _Size>(__a + __z, __b + __c);\n  }\n\n  // Return a 16-byte hash for s[0] ... s[31], a, and b.  Quick and dirty.\n  static pair<_Size, _Size> __weak_hash_len_32_with_seeds(\n      const char* __s, _Size __a, _Size __b) {\n    return __weak_hash_len_32_with_seeds(__loadword<_Size>(__s),\n                                         __loadword<_Size>(__s + 8),\n                                         __loadword<_Size>(__s + 16),\n                                         __loadword<_Size>(__s + 24),\n                                         __a,\n                                         __b);\n  }\n\n  // Return an 8-byte hash for 33 to 64 bytes.\n  static _Size __hash_len_33_to_64(const char *__s, size_t __len) {\n    _Size __z = __loadword<_Size>(__s + 24);\n    _Size __a = __loadword<_Size>(__s) +\n                (__len + __loadword<_Size>(__s + __len - 16)) * __k0;\n    _Size __b = __rotate(__a + __z, 52);\n    _Size __c = __rotate(__a, 37);\n    __a += __loadword<_Size>(__s + 8);\n    __c += __rotate(__a, 7);\n    __a += __loadword<_Size>(__s + 16);\n    _Size __vf = __a + __z;\n    _Size __vs = __b + __rotate(__a, 31) + __c;\n    __a = __loadword<_Size>(__s + 16) + __loadword<_Size>(__s + __len - 32);\n    __z += __loadword<_Size>(__s + __len - 8);\n    __b = __rotate(__a + __z, 52);\n    __c = __rotate(__a, 37);\n    __a += __loadword<_Size>(__s + __len - 24);\n    __c += __rotate(__a, 7);\n    __a += __loadword<_Size>(__s + __len - 16);\n    _Size __wf = __a + __z;\n    _Size __ws = __b + __rotate(__a, 31) + __c;\n    _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0);\n    return __shift_mix(__r * __k0 + __vs) * __k2;\n  }\n};\n\n// cityhash64\ntemplate <class _Size>\n_Size\n__murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len)\n{\n  const char* __s = static_cast<const char*>(__key);\n  if (__len <= 32) {\n    if (__len <= 16) {\n      return __hash_len_0_to_16(__s, __len);\n    } else {\n      return __hash_len_17_to_32(__s, __len);\n    }\n  } else if (__len <= 64) {\n    return __hash_len_33_to_64(__s, __len);\n  }\n\n  // For strings over 64 bytes we hash the end first, and then as we\n  // loop we keep 56 bytes of state: v, w, x, y, and z.\n  _Size __x = __loadword<_Size>(__s + __len - 40);\n  _Size __y = __loadword<_Size>(__s + __len - 16) +\n              __loadword<_Size>(__s + __len - 56);\n  _Size __z = __hash_len_16(__loadword<_Size>(__s + __len - 48) + __len,\n                          __loadword<_Size>(__s + __len - 24));\n  pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z);\n  pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x);\n  __x = __x * __k1 + __loadword<_Size>(__s);\n\n  // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.\n  __len = (__len - 1) & ~static_cast<_Size>(63);\n  do {\n    __x = __rotate(__x + __y + __v.first + __loadword<_Size>(__s + 8), 37) * __k1;\n    __y = __rotate(__y + __v.second + __loadword<_Size>(__s + 48), 42) * __k1;\n    __x ^= __w.second;\n    __y += __v.first + __loadword<_Size>(__s + 40);\n    __z = __rotate(__z + __w.first, 33) * __k1;\n    __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first);\n    __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second,\n                                        __y + __loadword<_Size>(__s + 16));\n    std::swap(__z, __x);\n    __s += 64;\n    __len -= 64;\n  } while (__len != 0);\n  return __hash_len_16(\n      __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z,\n      __hash_len_16(__v.second, __w.second) + __x);\n}\n\ntemplate <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)>\nstruct __scalar_hash;\n\ntemplate <class _Tp>\nstruct __scalar_hash<_Tp, 0>\n    : public unary_function<_Tp, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(_Tp __v) const _NOEXCEPT\n    {\n        union\n        {\n            _Tp    __t;\n            size_t __a;\n        } __u;\n        __u.__a = 0;\n        __u.__t = __v;\n        return __u.__a;\n    }\n};\n\ntemplate <class _Tp>\nstruct __scalar_hash<_Tp, 1>\n    : public unary_function<_Tp, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(_Tp __v) const _NOEXCEPT\n    {\n        union\n        {\n            _Tp    __t;\n            size_t __a;\n        } __u;\n        __u.__t = __v;\n        return __u.__a;\n    }\n};\n\ntemplate <class _Tp>\nstruct __scalar_hash<_Tp, 2>\n    : public unary_function<_Tp, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(_Tp __v) const _NOEXCEPT\n    {\n        union\n        {\n            _Tp __t;\n            struct\n            {\n                size_t __a;\n                size_t __b;\n            } __s;\n        } __u;\n        __u.__t = __v;\n        return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));\n    }\n};\n\ntemplate <class _Tp>\nstruct __scalar_hash<_Tp, 3>\n    : public unary_function<_Tp, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(_Tp __v) const _NOEXCEPT\n    {\n        union\n        {\n            _Tp __t;\n            struct\n            {\n                size_t __a;\n                size_t __b;\n                size_t __c;\n            } __s;\n        } __u;\n        __u.__t = __v;\n        return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));\n    }\n};\n\ntemplate <class _Tp>\nstruct __scalar_hash<_Tp, 4>\n    : public unary_function<_Tp, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(_Tp __v) const _NOEXCEPT\n    {\n        union\n        {\n            _Tp __t;\n            struct\n            {\n                size_t __a;\n                size_t __b;\n                size_t __c;\n                size_t __d;\n            } __s;\n        } __u;\n        __u.__t = __v;\n        return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));\n    }\n};\n\ntemplate<class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<_Tp*>\n    : public unary_function<_Tp*, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(_Tp* __v) const _NOEXCEPT\n    {\n        union\n        {\n            _Tp* __t;\n            size_t __a;\n        } __u;\n        __u.__t = __v;\n        return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));\n    }\n};\n\ntemplate <class _Tp, class _Dp>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<unique_ptr<_Tp, _Dp> >\n{\n    typedef unique_ptr<_Tp, _Dp> argument_type;\n    typedef size_t               result_type;\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator()(const argument_type& __ptr) const _NOEXCEPT\n    {\n        typedef typename argument_type::pointer pointer;\n        return hash<pointer>()(__ptr.get());\n    }\n};\n\nstruct __destruct_n\n{\nprivate:\n    size_t size;\n\n    template <class _Tp>\n    _LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT\n        {for (size_t __i = 0; __i < size; ++__i, ++__p) __p->~_Tp();}\n\n    template <class _Tp>\n    _LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT\n        {}\n\n    _LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT\n        {++size;}\n    _LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT\n        {}\n\n    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT\n        {size = __s;}\n    _LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT\n        {}\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT\n        : size(__s) {}\n\n    template <class _Tp>\n    _LIBCPP_INLINE_VISIBILITY void __incr(_Tp*) _NOEXCEPT\n        {__incr(integral_constant<bool, is_trivially_destructible<_Tp>::value>());}\n\n    template <class _Tp>\n    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, _Tp*) _NOEXCEPT\n        {__set(__s, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}\n\n    template <class _Tp>\n    _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) _NOEXCEPT\n        {__process(__p, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}\n};\n\ntemplate <class _Alloc>\nclass __allocator_destructor\n{\n    typedef allocator_traits<_Alloc> __alloc_traits;\npublic:\n    typedef typename __alloc_traits::pointer pointer;\n    typedef typename __alloc_traits::size_type size_type;\nprivate:\n    _Alloc& __alloc_;\n    size_type __s_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY __allocator_destructor(_Alloc& __a, size_type __s)\n             _NOEXCEPT\n        : __alloc_(__a), __s_(__s) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void operator()(pointer __p) _NOEXCEPT\n        {__alloc_traits::deallocate(__alloc_, __p, __s_);}\n};\n\ntemplate <class _InputIterator, class _ForwardIterator>\n_ForwardIterator\nuninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r)\n{\n    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    _ForwardIterator __s = __r;\n    try\n    {\n#endif\n        for (; __f != __l; ++__f, (void) ++__r)\n            ::new (static_cast<void*>(_VSTD::addressof(*__r))) value_type(*__f);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        for (; __s != __r; ++__s)\n            __s->~value_type();\n        throw;\n    }\n#endif\n    return __r;\n}\n\ntemplate <class _InputIterator, class _Size, class _ForwardIterator>\n_ForwardIterator\nuninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r)\n{\n    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    _ForwardIterator __s = __r;\n    try\n    {\n#endif\n        for (; __n > 0; ++__f, (void) ++__r, (void) --__n)\n            ::new (static_cast<void*>(_VSTD::addressof(*__r))) value_type(*__f);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        for (; __s != __r; ++__s)\n            __s->~value_type();\n        throw;\n    }\n#endif\n    return __r;\n}\n\ntemplate <class _ForwardIterator, class _Tp>\nvoid\nuninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x)\n{\n    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    _ForwardIterator __s = __f;\n    try\n    {\n#endif\n        for (; __f != __l; ++__f)\n            ::new (static_cast<void*>(_VSTD::addressof(*__f))) value_type(__x);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        for (; __s != __f; ++__s)\n            __s->~value_type();\n        throw;\n    }\n#endif\n}\n\ntemplate <class _ForwardIterator, class _Size, class _Tp>\n_ForwardIterator\nuninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x)\n{\n    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    _ForwardIterator __s = __f;\n    try\n    {\n#endif\n        for (; __n > 0; ++__f, (void) --__n)\n            ::new (static_cast<void*>(_VSTD::addressof(*__f))) value_type(__x);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        for (; __s != __f; ++__s)\n            __s->~value_type();\n        throw;\n    }\n#endif\n    return __f;\n}\n\nclass _LIBCPP_EXCEPTION_ABI bad_weak_ptr\n    : public std::exception\n{\npublic:\n    virtual ~bad_weak_ptr() _NOEXCEPT;\n    virtual const char* what() const  _NOEXCEPT;\n};\n\ntemplate<class _Tp> class _LIBCPP_TYPE_VIS_ONLY weak_ptr;\n\nclass _LIBCPP_TYPE_VIS __shared_count\n{\n    __shared_count(const __shared_count&);\n    __shared_count& operator=(const __shared_count&);\n\nprotected:\n    long __shared_owners_;\n    virtual ~__shared_count();\nprivate:\n    virtual void __on_zero_shared() _NOEXCEPT = 0;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __shared_count(long __refs = 0) _NOEXCEPT\n        : __shared_owners_(__refs) {}\n\n    void __add_shared() _NOEXCEPT;\n    bool __release_shared() _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    long use_count() const _NOEXCEPT {\n        return __libcpp_relaxed_load(&__shared_owners_) + 1;\n    }\n};\n\nclass _LIBCPP_TYPE_VIS __shared_weak_count\n    : private __shared_count\n{\n    long __shared_weak_owners_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __shared_weak_count(long __refs = 0) _NOEXCEPT\n        : __shared_count(__refs),\n          __shared_weak_owners_(__refs) {}\nprotected:\n    virtual ~__shared_weak_count();\n\npublic:\n    void __add_shared() _NOEXCEPT;\n    void __add_weak() _NOEXCEPT;\n    void __release_shared() _NOEXCEPT;\n    void __release_weak() _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    long use_count() const _NOEXCEPT {return __shared_count::use_count();}\n    __shared_weak_count* lock() _NOEXCEPT;\n\n    // Define the function out only if we build static libc++ without RTTI.\n    // Otherwise we may break clients who need to compile their projects with\n    // -fno-rtti and yet link against a libc++.dylib compiled\n    // without -fno-rtti.\n#if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC)\n    virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;\n#endif\nprivate:\n    virtual void __on_zero_shared_weak() _NOEXCEPT = 0;\n};\n\ntemplate <class _Tp, class _Dp, class _Alloc>\nclass __shared_ptr_pointer\n    : public __shared_weak_count\n{\n    __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)\n        :  __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}\n\n#ifndef _LIBCPP_NO_RTTI\n    virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;\n#endif\n\nprivate:\n    virtual void __on_zero_shared() _NOEXCEPT;\n    virtual void __on_zero_shared_weak() _NOEXCEPT;\n};\n\n#ifndef _LIBCPP_NO_RTTI\n\ntemplate <class _Tp, class _Dp, class _Alloc>\nconst void*\n__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT\n{\n    return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : 0;\n}\n\n#endif  // _LIBCPP_NO_RTTI\n\ntemplate <class _Tp, class _Dp, class _Alloc>\nvoid\n__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT\n{\n    __data_.first().second()(__data_.first().first());\n    __data_.first().second().~_Dp();\n}\n\ntemplate <class _Tp, class _Dp, class _Alloc>\nvoid\n__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT\n{\n    typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al;\n    typedef allocator_traits<_Al> _ATraits;\n    typedef pointer_traits<typename _ATraits::pointer> _PTraits;\n\n    _Al __a(__data_.second());\n    __data_.second().~_Alloc();\n    __a.deallocate(_PTraits::pointer_to(*this), 1);\n}\n\ntemplate <class _Tp, class _Alloc>\nclass __shared_ptr_emplace\n    : public __shared_weak_count\n{\n    __compressed_pair<_Alloc, _Tp> __data_;\npublic:\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n    _LIBCPP_INLINE_VISIBILITY\n    __shared_ptr_emplace(_Alloc __a)\n        :  __data_(_VSTD::move(__a)) {}\n\n    template <class ..._Args>\n        _LIBCPP_INLINE_VISIBILITY\n        __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)\n            :  __data_(piecewise_construct, _VSTD::forward_as_tuple(__a),\n                   _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)) {}\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\n    _LIBCPP_INLINE_VISIBILITY\n    __shared_ptr_emplace(_Alloc __a)\n        :  __data_(__a) {}\n\n    template <class _A0>\n        _LIBCPP_INLINE_VISIBILITY\n        __shared_ptr_emplace(_Alloc __a, _A0& __a0)\n            :  __data_(__a, _Tp(__a0)) {}\n\n    template <class _A0, class _A1>\n        _LIBCPP_INLINE_VISIBILITY\n        __shared_ptr_emplace(_Alloc __a, _A0& __a0, _A1& __a1)\n            :  __data_(__a, _Tp(__a0, __a1)) {}\n\n    template <class _A0, class _A1, class _A2>\n        _LIBCPP_INLINE_VISIBILITY\n        __shared_ptr_emplace(_Alloc __a, _A0& __a0, _A1& __a1, _A2& __a2)\n            :  __data_(__a, _Tp(__a0, __a1, __a2)) {}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\nprivate:\n    virtual void __on_zero_shared() _NOEXCEPT;\n    virtual void __on_zero_shared_weak() _NOEXCEPT;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp* get() _NOEXCEPT {return &__data_.second();}\n};\n\ntemplate <class _Tp, class _Alloc>\nvoid\n__shared_ptr_emplace<_Tp, _Alloc>::__on_zero_shared() _NOEXCEPT\n{\n    __data_.second().~_Tp();\n}\n\ntemplate <class _Tp, class _Alloc>\nvoid\n__shared_ptr_emplace<_Tp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT\n{\n    typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type _Al;\n    typedef allocator_traits<_Al> _ATraits;\n    typedef pointer_traits<typename _ATraits::pointer> _PTraits;\n    _Al __a(__data_.first());\n    __data_.first().~_Alloc();\n    __a.deallocate(_PTraits::pointer_to(*this), 1);\n}\n\ntemplate<class _Tp> class _LIBCPP_TYPE_VIS_ONLY enable_shared_from_this;\n\ntemplate<class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY shared_ptr\n{\npublic:\n    typedef _Tp element_type;\nprivate:\n    element_type*      __ptr_;\n    __shared_weak_count* __cntrl_;\n\n    struct __nat {int __for_bool_;};\npublic:\n    _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT;\n    _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT;\n    template<class _Yp>\n        explicit shared_ptr(_Yp* __p,\n                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());\n    template<class _Yp, class _Dp>\n        shared_ptr(_Yp* __p, _Dp __d,\n                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());\n    template<class _Yp, class _Dp, class _Alloc>\n        shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,\n                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());\n    template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);\n    template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);\n    template<class _Yp> shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT;\n    shared_ptr(const shared_ptr& __r) _NOEXCEPT;\n    template<class _Yp>\n        shared_ptr(const shared_ptr<_Yp>& __r,\n                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type = __nat())\n                       _NOEXCEPT;\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    shared_ptr(shared_ptr&& __r) _NOEXCEPT;\n    template<class _Yp> shared_ptr(shared_ptr<_Yp>&& __r,\n                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type = __nat())\n                       _NOEXCEPT;\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,\n                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type= __nat());\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template<class _Yp>\n        shared_ptr(auto_ptr<_Yp>&& __r,\n                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());\n#else\n    template<class _Yp>\n        shared_ptr(auto_ptr<_Yp> __r,\n                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());\n#endif\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Yp, class _Dp>\n        shared_ptr(unique_ptr<_Yp, _Dp>&&,\n                   typename enable_if\n                   <\n                       !is_lvalue_reference<_Dp>::value &&\n                       !is_array<_Yp>::value &&\n                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,\n                       __nat\n                   >::type = __nat());\n    template <class _Yp, class _Dp>\n        shared_ptr(unique_ptr<_Yp, _Dp>&&,\n                   typename enable_if\n                   <\n                       is_lvalue_reference<_Dp>::value &&\n                       !is_array<_Yp>::value &&\n                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,\n                       __nat\n                   >::type = __nat());\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Yp, class _Dp>\n        shared_ptr(unique_ptr<_Yp, _Dp>,\n                   typename enable_if\n                   <\n                       !is_lvalue_reference<_Dp>::value &&\n                       !is_array<_Yp>::value &&\n                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,\n                       __nat\n                   >::type = __nat());\n    template <class _Yp, class _Dp>\n        shared_ptr(unique_ptr<_Yp, _Dp>,\n                   typename enable_if\n                   <\n                       is_lvalue_reference<_Dp>::value &&\n                       !is_array<_Yp>::value &&\n                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,\n                       __nat\n                   >::type = __nat());\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    ~shared_ptr();\n\n    shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT;\n    template<class _Yp>\n        typename enable_if\n        <\n            is_convertible<_Yp*, element_type*>::value,\n            shared_ptr&\n        >::type\n        operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT;\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPT;\n    template<class _Yp>\n        typename enable_if\n        <\n            is_convertible<_Yp*, element_type*>::value,\n            shared_ptr<_Tp>&\n        >::type\n        operator=(shared_ptr<_Yp>&& __r);\n    template<class _Yp>\n        typename enable_if\n        <\n            !is_array<_Yp>::value &&\n            is_convertible<_Yp*, element_type*>::value,\n            shared_ptr\n        >::type&\n        operator=(auto_ptr<_Yp>&& __r);\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template<class _Yp>\n        typename enable_if\n        <\n            !is_array<_Yp>::value &&\n            is_convertible<_Yp*, element_type*>::value,\n            shared_ptr&\n        >::type\n        operator=(auto_ptr<_Yp> __r);\n#endif\n    template <class _Yp, class _Dp>\n        typename enable_if\n        <\n            !is_array<_Yp>::value &&\n            is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,\n            shared_ptr&\n        >::type\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n        operator=(unique_ptr<_Yp, _Dp>&& __r);\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n        operator=(unique_ptr<_Yp, _Dp> __r);\n#endif\n\n    void swap(shared_ptr& __r) _NOEXCEPT;\n    void reset() _NOEXCEPT;\n    template<class _Yp>\n        typename enable_if\n        <\n            is_convertible<_Yp*, element_type*>::value,\n            void\n        >::type\n        reset(_Yp* __p);\n    template<class _Yp, class _Dp>\n        typename enable_if\n        <\n            is_convertible<_Yp*, element_type*>::value,\n            void\n        >::type\n        reset(_Yp* __p, _Dp __d);\n    template<class _Yp, class _Dp, class _Alloc>\n        typename enable_if\n        <\n            is_convertible<_Yp*, element_type*>::value,\n            void\n        >::type\n        reset(_Yp* __p, _Dp __d, _Alloc __a);\n\n    _LIBCPP_INLINE_VISIBILITY\n    element_type* get() const _NOEXCEPT {return __ptr_;}\n    _LIBCPP_INLINE_VISIBILITY\n    typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT\n        {return *__ptr_;}\n    _LIBCPP_INLINE_VISIBILITY\n    element_type* operator->() const _NOEXCEPT {return __ptr_;}\n    _LIBCPP_INLINE_VISIBILITY\n    long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    bool unique() const _NOEXCEPT {return use_count() == 1;}\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return get() != 0;}\n    template <class _Up>\n        _LIBCPP_INLINE_VISIBILITY\n        bool owner_before(shared_ptr<_Up> const& __p) const\n        {return __cntrl_ < __p.__cntrl_;}\n    template <class _Up>\n        _LIBCPP_INLINE_VISIBILITY\n        bool owner_before(weak_ptr<_Up> const& __p) const\n        {return __cntrl_ < __p.__cntrl_;}\n    _LIBCPP_INLINE_VISIBILITY\n    bool\n    __owner_equivalent(const shared_ptr& __p) const\n        {return __cntrl_ == __p.__cntrl_;}\n\n#ifndef _LIBCPP_NO_RTTI\n    template <class _Dp>\n        _LIBCPP_INLINE_VISIBILITY\n        _Dp* __get_deleter() const _NOEXCEPT\n            {return (_Dp*)(__cntrl_ ? __cntrl_->__get_deleter(typeid(_Dp)) : 0);}\n#endif  // _LIBCPP_NO_RTTI\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n    template<class ..._Args>\n        static\n        shared_ptr<_Tp>\n        make_shared(_Args&& ...__args);\n\n    template<class _Alloc, class ..._Args>\n        static\n        shared_ptr<_Tp>\n        allocate_shared(const _Alloc& __a, _Args&& ...__args);\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\n    static shared_ptr<_Tp> make_shared();\n\n    template<class _A0>\n        static shared_ptr<_Tp> make_shared(_A0&);\n\n    template<class _A0, class _A1>\n        static shared_ptr<_Tp> make_shared(_A0&, _A1&);\n\n    template<class _A0, class _A1, class _A2>\n        static shared_ptr<_Tp> make_shared(_A0&, _A1&, _A2&);\n\n    template<class _Alloc>\n        static shared_ptr<_Tp>\n        allocate_shared(const _Alloc& __a);\n\n    template<class _Alloc, class _A0>\n        static shared_ptr<_Tp>\n        allocate_shared(const _Alloc& __a, _A0& __a0);\n\n    template<class _Alloc, class _A0, class _A1>\n        static shared_ptr<_Tp>\n        allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1);\n\n    template<class _Alloc, class _A0, class _A1, class _A2>\n        static shared_ptr<_Tp>\n        allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2);\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\nprivate:\n\n    template <class _Yp>\n        _LIBCPP_INLINE_VISIBILITY\n        void\n        __enable_weak_this(const enable_shared_from_this<_Yp>* __e) _NOEXCEPT\n        {\n            if (__e)\n            {\n                __e->__weak_this_.__ptr_ = const_cast<_Yp*>(static_cast<const _Yp*>(__e));\n                __e->__weak_this_.__cntrl_ = __cntrl_;\n                __cntrl_->__add_weak();\n            }\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __enable_weak_this(const volatile void*) _NOEXCEPT {}\n\n    template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY shared_ptr;\n    template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY weak_ptr;\n};\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nshared_ptr<_Tp>::shared_ptr() _NOEXCEPT\n    : __ptr_(0),\n      __cntrl_(0)\n{\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nshared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT\n    : __ptr_(0),\n      __cntrl_(0)\n{\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp>\nshared_ptr<_Tp>::shared_ptr(_Yp* __p,\n                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)\n    : __ptr_(__p)\n{\n    unique_ptr<_Yp> __hold(__p);\n    typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;\n    __cntrl_ = new _CntrlBlk(__p, default_delete<_Yp>(), allocator<_Yp>());\n    __hold.release();\n    __enable_weak_this(__p);\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp, class _Dp>\nshared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d,\n                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)\n    : __ptr_(__p)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typedef __shared_ptr_pointer<_Yp*, _Dp, allocator<_Yp> > _CntrlBlk;\n        __cntrl_ = new _CntrlBlk(__p, __d, allocator<_Yp>());\n        __enable_weak_this(__p);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __d(__p);\n        throw;\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate<class _Tp>\ntemplate<class _Dp>\nshared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d)\n    : __ptr_(0)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typedef __shared_ptr_pointer<nullptr_t, _Dp, allocator<_Tp> > _CntrlBlk;\n        __cntrl_ = new _CntrlBlk(__p, __d, allocator<_Tp>());\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __d(__p);\n        throw;\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp, class _Dp, class _Alloc>\nshared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,\n                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)\n    : __ptr_(__p)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;\n        typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;\n        typedef __allocator_destructor<_A2> _D2;\n        _A2 __a2(__a);\n        unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));\n        ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))\n            _CntrlBlk(__p, __d, __a);\n        __cntrl_ = _VSTD::addressof(*__hold2.release());\n        __enable_weak_this(__p);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __d(__p);\n        throw;\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate<class _Tp>\ntemplate<class _Dp, class _Alloc>\nshared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)\n    : __ptr_(0)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;\n        typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;\n        typedef __allocator_destructor<_A2> _D2;\n        _A2 __a2(__a);\n        unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));\n        ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))\n            _CntrlBlk(__p, __d, __a);\n        __cntrl_ = _VSTD::addressof(*__hold2.release());\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __d(__p);\n        throw;\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT\n    : __ptr_(__p),\n      __cntrl_(__r.__cntrl_)\n{\n    if (__cntrl_)\n        __cntrl_->__add_shared();\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPT\n    : __ptr_(__r.__ptr_),\n      __cntrl_(__r.__cntrl_)\n{\n    if (__cntrl_)\n        __cntrl_->__add_shared();\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r,\n                            typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type)\n         _NOEXCEPT\n    : __ptr_(__r.__ptr_),\n      __cntrl_(__r.__cntrl_)\n{\n    if (__cntrl_)\n        __cntrl_->__add_shared();\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPT\n    : __ptr_(__r.__ptr_),\n      __cntrl_(__r.__cntrl_)\n{\n    __r.__ptr_ = 0;\n    __r.__cntrl_ = 0;\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r,\n                            typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type)\n         _NOEXCEPT\n    : __ptr_(__r.__ptr_),\n      __cntrl_(__r.__cntrl_)\n{\n    __r.__ptr_ = 0;\n    __r.__cntrl_ = 0;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _Tp>\ntemplate<class _Yp>\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\nshared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r,\n#else\nshared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp> __r,\n#endif\n                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)\n    : __ptr_(__r.get())\n{\n    typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;\n    __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>());\n    __enable_weak_this(__r.get());\n    __r.release();\n}\n\ntemplate<class _Tp>\ntemplate <class _Yp, class _Dp>\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\nshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,\n#else\nshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r,\n#endif\n                            typename enable_if\n                            <\n                                !is_lvalue_reference<_Dp>::value &&\n                                !is_array<_Yp>::value &&\n                                is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,\n                                __nat\n                            >::type)\n    : __ptr_(__r.get())\n{\n#if _LIBCPP_STD_VER > 11\n    if (__ptr_ == nullptr)\n        __cntrl_ = nullptr;\n    else\n#endif\n    {\n        typedef __shared_ptr_pointer<_Yp*, _Dp, allocator<_Yp> > _CntrlBlk;\n        __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), allocator<_Yp>());\n        __enable_weak_this(__r.get());\n    }\n    __r.release();\n}\n\ntemplate<class _Tp>\ntemplate <class _Yp, class _Dp>\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\nshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,\n#else\nshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r,\n#endif\n                            typename enable_if\n                            <\n                                is_lvalue_reference<_Dp>::value &&\n                                !is_array<_Yp>::value &&\n                                is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,\n                                __nat\n                            >::type)\n    : __ptr_(__r.get())\n{\n#if _LIBCPP_STD_VER > 11\n    if (__ptr_ == nullptr)\n        __cntrl_ = nullptr;\n    else\n#endif\n    {\n        typedef __shared_ptr_pointer<_Yp*,\n                                     reference_wrapper<typename remove_reference<_Dp>::type>,\n                                     allocator<_Yp> > _CntrlBlk;\n        __cntrl_ = new _CntrlBlk(__r.get(), ref(__r.get_deleter()), allocator<_Yp>());\n        __enable_weak_this(__r.get());\n    }\n    __r.release();\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate<class _Tp>\ntemplate<class ..._Args>\nshared_ptr<_Tp>\nshared_ptr<_Tp>::make_shared(_Args&& ...__args)\n{\n    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;\n    typedef allocator<_CntrlBlk> _A2;\n    typedef __allocator_destructor<_A2> _D2;\n    _A2 __a2;\n    unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));\n    ::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...);\n    shared_ptr<_Tp> __r;\n    __r.__ptr_ = __hold2.get()->get();\n    __r.__cntrl_ = __hold2.release();\n    __r.__enable_weak_this(__r.__ptr_);\n    return __r;\n}\n\ntemplate<class _Tp>\ntemplate<class _Alloc, class ..._Args>\nshared_ptr<_Tp>\nshared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _Args&& ...__args)\n{\n    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;\n    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;\n    typedef __allocator_destructor<_A2> _D2;\n    _A2 __a2(__a);\n    unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));\n    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))\n        _CntrlBlk(__a, _VSTD::forward<_Args>(__args)...);\n    shared_ptr<_Tp> __r;\n    __r.__ptr_ = __hold2.get()->get();\n    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());\n    __r.__enable_weak_this(__r.__ptr_);\n    return __r;\n}\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate<class _Tp>\nshared_ptr<_Tp>\nshared_ptr<_Tp>::make_shared()\n{\n    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;\n    typedef allocator<_CntrlBlk> _Alloc2;\n    typedef __allocator_destructor<_Alloc2> _D2;\n    _Alloc2 __alloc2;\n    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));\n    ::new(__hold2.get()) _CntrlBlk(__alloc2);\n    shared_ptr<_Tp> __r;\n    __r.__ptr_ = __hold2.get()->get();\n    __r.__cntrl_ = __hold2.release();\n    __r.__enable_weak_this(__r.__ptr_);\n    return __r;\n}\n\ntemplate<class _Tp>\ntemplate<class _A0>\nshared_ptr<_Tp>\nshared_ptr<_Tp>::make_shared(_A0& __a0)\n{\n    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;\n    typedef allocator<_CntrlBlk> _Alloc2;\n    typedef __allocator_destructor<_Alloc2> _D2;\n    _Alloc2 __alloc2;\n    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));\n    ::new(__hold2.get()) _CntrlBlk(__alloc2, __a0);\n    shared_ptr<_Tp> __r;\n    __r.__ptr_ = __hold2.get()->get();\n    __r.__cntrl_ = __hold2.release();\n    __r.__enable_weak_this(__r.__ptr_);\n    return __r;\n}\n\ntemplate<class _Tp>\ntemplate<class _A0, class _A1>\nshared_ptr<_Tp>\nshared_ptr<_Tp>::make_shared(_A0& __a0, _A1& __a1)\n{\n    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;\n    typedef allocator<_CntrlBlk> _Alloc2;\n    typedef __allocator_destructor<_Alloc2> _D2;\n    _Alloc2 __alloc2;\n    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));\n    ::new(__hold2.get()) _CntrlBlk(__alloc2, __a0, __a1);\n    shared_ptr<_Tp> __r;\n    __r.__ptr_ = __hold2.get()->get();\n    __r.__cntrl_ = __hold2.release();\n    __r.__enable_weak_this(__r.__ptr_);\n    return __r;\n}\n\ntemplate<class _Tp>\ntemplate<class _A0, class _A1, class _A2>\nshared_ptr<_Tp>\nshared_ptr<_Tp>::make_shared(_A0& __a0, _A1& __a1, _A2& __a2)\n{\n    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;\n    typedef allocator<_CntrlBlk> _Alloc2;\n    typedef __allocator_destructor<_Alloc2> _D2;\n    _Alloc2 __alloc2;\n    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));\n    ::new(__hold2.get()) _CntrlBlk(__alloc2, __a0, __a1, __a2);\n    shared_ptr<_Tp> __r;\n    __r.__ptr_ = __hold2.get()->get();\n    __r.__cntrl_ = __hold2.release();\n    __r.__enable_weak_this(__r.__ptr_);\n    return __r;\n}\n\ntemplate<class _Tp>\ntemplate<class _Alloc>\nshared_ptr<_Tp>\nshared_ptr<_Tp>::allocate_shared(const _Alloc& __a)\n{\n    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;\n    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;\n    typedef __allocator_destructor<_Alloc2> _D2;\n    _Alloc2 __alloc2(__a);\n    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));\n    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))\n        _CntrlBlk(__a);\n    shared_ptr<_Tp> __r;\n    __r.__ptr_ = __hold2.get()->get();\n    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());\n    __r.__enable_weak_this(__r.__ptr_);\n    return __r;\n}\n\ntemplate<class _Tp>\ntemplate<class _Alloc, class _A0>\nshared_ptr<_Tp>\nshared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0)\n{\n    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;\n    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;\n    typedef __allocator_destructor<_Alloc2> _D2;\n    _Alloc2 __alloc2(__a);\n    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));\n    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))\n        _CntrlBlk(__a, __a0);\n    shared_ptr<_Tp> __r;\n    __r.__ptr_ = __hold2.get()->get();\n    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());\n    __r.__enable_weak_this(__r.__ptr_);\n    return __r;\n}\n\ntemplate<class _Tp>\ntemplate<class _Alloc, class _A0, class _A1>\nshared_ptr<_Tp>\nshared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1)\n{\n    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;\n    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;\n    typedef __allocator_destructor<_Alloc2> _D2;\n    _Alloc2 __alloc2(__a);\n    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));\n    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))\n        _CntrlBlk(__a, __a0, __a1);\n    shared_ptr<_Tp> __r;\n    __r.__ptr_ = __hold2.get()->get();\n    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());\n    __r.__enable_weak_this(__r.__ptr_);\n    return __r;\n}\n\ntemplate<class _Tp>\ntemplate<class _Alloc, class _A0, class _A1, class _A2>\nshared_ptr<_Tp>\nshared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2)\n{\n    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;\n    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;\n    typedef __allocator_destructor<_Alloc2> _D2;\n    _Alloc2 __alloc2(__a);\n    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));\n    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))\n        _CntrlBlk(__a, __a0, __a1, __a2);\n    shared_ptr<_Tp> __r;\n    __r.__ptr_ = __hold2.get()->get();\n    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());\n    __r.__enable_weak_this(__r.__ptr_);\n    return __r;\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate<class _Tp>\nshared_ptr<_Tp>::~shared_ptr()\n{\n    if (__cntrl_)\n        __cntrl_->__release_shared();\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>&\nshared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPT\n{\n    shared_ptr(__r).swap(*this);\n    return *this;\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_convertible<_Yp*, _Tp*>::value,\n    shared_ptr<_Tp>&\n>::type\nshared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT\n{\n    shared_ptr(__r).swap(*this);\n    return *this;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>&\nshared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPT\n{\n    shared_ptr(_VSTD::move(__r)).swap(*this);\n    return *this;\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_convertible<_Yp*, _Tp*>::value,\n    shared_ptr<_Tp>&\n>::type\nshared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r)\n{\n    shared_ptr(_VSTD::move(__r)).swap(*this);\n    return *this;\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_array<_Yp>::value &&\n    is_convertible<_Yp*, _Tp*>::value,\n    shared_ptr<_Tp>\n>::type&\nshared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r)\n{\n    shared_ptr(_VSTD::move(__r)).swap(*this);\n    return *this;\n}\n\ntemplate<class _Tp>\ntemplate <class _Yp, class _Dp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_array<_Yp>::value &&\n    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, _Tp*>::value,\n    shared_ptr<_Tp>&\n>::type\nshared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r)\n{\n    shared_ptr(_VSTD::move(__r)).swap(*this);\n    return *this;\n}\n\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _Tp>\ntemplate<class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_array<_Yp>::value &&\n    is_convertible<_Yp*, _Tp*>::value,\n    shared_ptr<_Tp>&\n>::type\nshared_ptr<_Tp>::operator=(auto_ptr<_Yp> __r)\n{\n    shared_ptr(__r).swap(*this);\n    return *this;\n}\n\ntemplate<class _Tp>\ntemplate <class _Yp, class _Dp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_array<_Yp>::value &&\n    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, _Tp*>::value,\n    shared_ptr<_Tp>&\n>::type\nshared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp> __r)\n{\n    shared_ptr(_VSTD::move(__r)).swap(*this);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nshared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPT\n{\n    _VSTD::swap(__ptr_, __r.__ptr_);\n    _VSTD::swap(__cntrl_, __r.__cntrl_);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nshared_ptr<_Tp>::reset() _NOEXCEPT\n{\n    shared_ptr().swap(*this);\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_convertible<_Yp*, _Tp*>::value,\n    void\n>::type\nshared_ptr<_Tp>::reset(_Yp* __p)\n{\n    shared_ptr(__p).swap(*this);\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp, class _Dp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_convertible<_Yp*, _Tp*>::value,\n    void\n>::type\nshared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)\n{\n    shared_ptr(__p, __d).swap(*this);\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp, class _Dp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_convertible<_Yp*, _Tp*>::value,\n    void\n>::type\nshared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)\n{\n    shared_ptr(__p, __d, __a).swap(*this);\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate<class _Tp, class ..._Args>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_array<_Tp>::value,\n    shared_ptr<_Tp>\n>::type\nmake_shared(_Args&& ...__args)\n{\n    return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...);\n}\n\ntemplate<class _Tp, class _Alloc, class ..._Args>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_array<_Tp>::value,\n    shared_ptr<_Tp>\n>::type\nallocate_shared(const _Alloc& __a, _Args&& ...__args)\n{\n    return shared_ptr<_Tp>::allocate_shared(__a, _VSTD::forward<_Args>(__args)...);\n}\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>\nmake_shared()\n{\n    return shared_ptr<_Tp>::make_shared();\n}\n\ntemplate<class _Tp, class _A0>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>\nmake_shared(_A0& __a0)\n{\n    return shared_ptr<_Tp>::make_shared(__a0);\n}\n\ntemplate<class _Tp, class _A0, class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>\nmake_shared(_A0& __a0, _A1& __a1)\n{\n    return shared_ptr<_Tp>::make_shared(__a0, __a1);\n}\n\ntemplate<class _Tp, class _A0, class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>\nmake_shared(_A0& __a0, _A1& __a1, _A2& __a2)\n{\n    return shared_ptr<_Tp>::make_shared(__a0, __a1, __a2);\n}\n\ntemplate<class _Tp, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>\nallocate_shared(const _Alloc& __a)\n{\n    return shared_ptr<_Tp>::allocate_shared(__a);\n}\n\ntemplate<class _Tp, class _Alloc, class _A0>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>\nallocate_shared(const _Alloc& __a, _A0& __a0)\n{\n    return shared_ptr<_Tp>::allocate_shared(__a, __a0);\n}\n\ntemplate<class _Tp, class _Alloc, class _A0, class _A1>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>\nallocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1)\n{\n    return shared_ptr<_Tp>::allocate_shared(__a, __a0, __a1);\n}\n\ntemplate<class _Tp, class _Alloc, class _A0, class _A1, class _A2>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>\nallocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2)\n{\n    return shared_ptr<_Tp>::allocate_shared(__a, __a0, __a1, __a2);\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate<class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT\n{\n    return __x.get() == __y.get();\n}\n\ntemplate<class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT\n{\n    return !(__x == __y);\n}\n\ntemplate<class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT\n{\n    typedef typename common_type<_Tp*, _Up*>::type _Vp;\n    return less<_Vp>()(__x.get(), __y.get());\n}\n\ntemplate<class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT\n{\n    return __y < __x;\n}\n\ntemplate<class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT\n{\n    return !(__y < __x);\n}\n\ntemplate<class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT\n{\n    return !(__x < __y);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT\n{\n    return !__x;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT\n{\n    return !__x;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT\n{\n    return static_cast<bool>(__x);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT\n{\n    return static_cast<bool>(__x);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT\n{\n    return less<_Tp*>()(__x.get(), nullptr);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT\n{\n    return less<_Tp*>()(nullptr, __x.get());\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT\n{\n    return nullptr < __x;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT\n{\n    return __x < nullptr;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT\n{\n    return !(nullptr < __x);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT\n{\n    return !(__x < nullptr);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT\n{\n    return !(__x < nullptr);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT\n{\n    return !(nullptr < __x);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT\n{\n    __x.swap(__y);\n}\n\ntemplate<class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_array<_Tp>::value && !is_array<_Up>::value,\n    shared_ptr<_Tp>\n>::type\nstatic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT\n{\n    return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get()));\n}\n\ntemplate<class _Tp, class _Up>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_array<_Tp>::value && !is_array<_Up>::value,\n    shared_ptr<_Tp>\n>::type\ndynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT\n{\n    _Tp* __p = dynamic_cast<_Tp*>(__r.get());\n    return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();\n}\n\ntemplate<class _Tp, class _Up>\ntypename enable_if\n<\n    is_array<_Tp>::value == is_array<_Up>::value,\n    shared_ptr<_Tp>\n>::type\nconst_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT\n{\n    typedef typename remove_extent<_Tp>::type _RTp;\n    return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));\n}\n\n#ifndef _LIBCPP_NO_RTTI\n\ntemplate<class _Dp, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Dp*\nget_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT\n{\n    return __p.template __get_deleter<_Dp>();\n}\n\n#endif  // _LIBCPP_NO_RTTI\n\ntemplate<class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY weak_ptr\n{\npublic:\n    typedef _Tp element_type;\nprivate:\n    element_type*        __ptr_;\n    __shared_weak_count* __cntrl_;\n\npublic:\n    _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT;\n    template<class _Yp> weak_ptr(shared_ptr<_Yp> const& __r,\n                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)\n                        _NOEXCEPT;\n    weak_ptr(weak_ptr const& __r) _NOEXCEPT;\n    template<class _Yp> weak_ptr(weak_ptr<_Yp> const& __r,\n                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)\n                         _NOEXCEPT;\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    weak_ptr(weak_ptr&& __r) _NOEXCEPT;\n    template<class _Yp> weak_ptr(weak_ptr<_Yp>&& __r,\n                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)\n                         _NOEXCEPT;\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    ~weak_ptr();\n\n    weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;\n    template<class _Yp>\n        typename enable_if\n        <\n            is_convertible<_Yp*, element_type*>::value,\n            weak_ptr&\n        >::type\n        operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT;\n    template<class _Yp>\n        typename enable_if\n        <\n            is_convertible<_Yp*, element_type*>::value,\n            weak_ptr&\n        >::type\n        operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT;\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    template<class _Yp>\n        typename enable_if\n        <\n            is_convertible<_Yp*, element_type*>::value,\n            weak_ptr&\n        >::type\n        operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT;\n\n    void swap(weak_ptr& __r) _NOEXCEPT;\n    void reset() _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    long use_count() const _NOEXCEPT\n        {return __cntrl_ ? __cntrl_->use_count() : 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    bool expired() const _NOEXCEPT\n        {return __cntrl_ == 0 || __cntrl_->use_count() == 0;}\n    shared_ptr<_Tp> lock() const _NOEXCEPT;\n    template<class _Up>\n        _LIBCPP_INLINE_VISIBILITY\n        bool owner_before(const shared_ptr<_Up>& __r) const\n        {return __cntrl_ < __r.__cntrl_;}\n    template<class _Up>\n        _LIBCPP_INLINE_VISIBILITY\n        bool owner_before(const weak_ptr<_Up>& __r) const\n        {return __cntrl_ < __r.__cntrl_;}\n\n    template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY weak_ptr;\n    template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY shared_ptr;\n};\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nweak_ptr<_Tp>::weak_ptr() _NOEXCEPT\n    : __ptr_(0),\n      __cntrl_(0)\n{\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nweak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT\n    : __ptr_(__r.__ptr_),\n      __cntrl_(__r.__cntrl_)\n{\n    if (__cntrl_)\n        __cntrl_->__add_weak();\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\nweak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,\n                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)\n                         _NOEXCEPT\n    : __ptr_(__r.__ptr_),\n      __cntrl_(__r.__cntrl_)\n{\n    if (__cntrl_)\n        __cntrl_->__add_weak();\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\nweak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,\n                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)\n         _NOEXCEPT\n    : __ptr_(__r.__ptr_),\n      __cntrl_(__r.__cntrl_)\n{\n    if (__cntrl_)\n        __cntrl_->__add_weak();\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nweak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT\n    : __ptr_(__r.__ptr_),\n      __cntrl_(__r.__cntrl_)\n{\n    __r.__ptr_ = 0;\n    __r.__cntrl_ = 0;\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\nweak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,\n                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)\n         _NOEXCEPT\n    : __ptr_(__r.__ptr_),\n      __cntrl_(__r.__cntrl_)\n{\n    __r.__ptr_ = 0;\n    __r.__cntrl_ = 0;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _Tp>\nweak_ptr<_Tp>::~weak_ptr()\n{\n    if (__cntrl_)\n        __cntrl_->__release_weak();\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nweak_ptr<_Tp>&\nweak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT\n{\n    weak_ptr(__r).swap(*this);\n    return *this;\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_convertible<_Yp*, _Tp*>::value,\n    weak_ptr<_Tp>&\n>::type\nweak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT\n{\n    weak_ptr(__r).swap(*this);\n    return *this;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nweak_ptr<_Tp>&\nweak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT\n{\n    weak_ptr(_VSTD::move(__r)).swap(*this);\n    return *this;\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_convertible<_Yp*, _Tp*>::value,\n    weak_ptr<_Tp>&\n>::type\nweak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT\n{\n    weak_ptr(_VSTD::move(__r)).swap(*this);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _Tp>\ntemplate<class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    is_convertible<_Yp*, _Tp*>::value,\n    weak_ptr<_Tp>&\n>::type\nweak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT\n{\n    weak_ptr(__r).swap(*this);\n    return *this;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nweak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT\n{\n    _VSTD::swap(__ptr_, __r.__ptr_);\n    _VSTD::swap(__cntrl_, __r.__cntrl_);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT\n{\n    __x.swap(__y);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nweak_ptr<_Tp>::reset() _NOEXCEPT\n{\n    weak_ptr().swap(*this);\n}\n\ntemplate<class _Tp>\ntemplate<class _Yp>\nshared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r,\n                            typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type)\n    : __ptr_(__r.__ptr_),\n      __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)\n{\n    if (__cntrl_ == 0)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        throw bad_weak_ptr();\n#else\n        assert(!\"bad_weak_ptr\");\n#endif\n}\n\ntemplate<class _Tp>\nshared_ptr<_Tp>\nweak_ptr<_Tp>::lock() const _NOEXCEPT\n{\n    shared_ptr<_Tp> __r;\n    __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_;\n    if (__r.__cntrl_)\n        __r.__ptr_ = __ptr_;\n    return __r;\n}\n\ntemplate <class _Tp> struct owner_less;\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY owner_less<shared_ptr<_Tp> >\n    : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>\n{\n    typedef bool result_type;\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const\n        {return __x.owner_before(__y);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const\n        {return __x.owner_before(__y);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const\n        {return __x.owner_before(__y);}\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY owner_less<weak_ptr<_Tp> >\n    : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>\n{\n    typedef bool result_type;\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(  weak_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const\n        {return __x.owner_before(__y);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const\n        {return __x.owner_before(__y);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const\n        {return __x.owner_before(__y);}\n};\n\ntemplate<class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY enable_shared_from_this\n{\n    mutable weak_ptr<_Tp> __weak_this_;\nprotected:\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR\n    enable_shared_from_this() _NOEXCEPT {}\n    _LIBCPP_INLINE_VISIBILITY\n    enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}\n    _LIBCPP_INLINE_VISIBILITY\n    enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT\n        {return *this;}\n    _LIBCPP_INLINE_VISIBILITY\n    ~enable_shared_from_this() {}\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    shared_ptr<_Tp> shared_from_this()\n        {return shared_ptr<_Tp>(__weak_this_);}\n    _LIBCPP_INLINE_VISIBILITY\n    shared_ptr<_Tp const> shared_from_this() const\n        {return shared_ptr<const _Tp>(__weak_this_);}\n\n    template <class _Up> friend class shared_ptr;\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<shared_ptr<_Tp> >\n{\n    typedef shared_ptr<_Tp>      argument_type;\n    typedef size_t               result_type;\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator()(const argument_type& __ptr) const _NOEXCEPT\n    {\n        return hash<_Tp*>()(__ptr.get());\n    }\n};\n\ntemplate<class _CharT, class _Traits, class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);\n\n#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)\n\nclass _LIBCPP_TYPE_VIS __sp_mut\n{\n    void* __lx;\npublic:\n    void lock() _NOEXCEPT;\n    void unlock() _NOEXCEPT;\n\nprivate:\n    _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT;\n    __sp_mut(const __sp_mut&);\n    __sp_mut& operator=(const __sp_mut&);\n\n    friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);\n};\n\n_LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_is_lock_free(const shared_ptr<_Tp>*)\n{\n    return false;\n}\n\ntemplate <class _Tp>\nshared_ptr<_Tp>\natomic_load(const shared_ptr<_Tp>* __p)\n{\n    __sp_mut& __m = __get_sp_mut(__p);\n    __m.lock();\n    shared_ptr<_Tp> __q = *__p;\n    __m.unlock();\n    return __q;\n}\n  \ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>\natomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)\n{\n    return atomic_load(__p);\n}\n\ntemplate <class _Tp>\nvoid\natomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)\n{\n    __sp_mut& __m = __get_sp_mut(__p);\n    __m.lock();\n    __p->swap(__r);\n    __m.unlock();\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\natomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)\n{\n    atomic_store(__p, __r);\n}\n\ntemplate <class _Tp>\nshared_ptr<_Tp>\natomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)\n{\n    __sp_mut& __m = __get_sp_mut(__p);\n    __m.lock();\n    __p->swap(__r);\n    __m.unlock();\n    return __r;\n}\n  \ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nshared_ptr<_Tp>\natomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)\n{\n    return atomic_exchange(__p, __r);\n}\n\ntemplate <class _Tp>\nbool\natomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)\n{\n    __sp_mut& __m = __get_sp_mut(__p);\n    __m.lock();\n    if (__p->__owner_equivalent(*__v))\n    {\n        *__p = __w;\n        __m.unlock();\n        return true;\n    }\n    *__v = *__p;\n    __m.unlock();\n    return false;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)\n{\n    return atomic_compare_exchange_strong(__p, __v, __w);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,\n                                        shared_ptr<_Tp> __w, memory_order, memory_order)\n{\n    return atomic_compare_exchange_strong(__p, __v, __w);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\natomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,\n                                      shared_ptr<_Tp> __w, memory_order, memory_order)\n{\n    return atomic_compare_exchange_weak(__p, __v, __w);\n}\n\n#endif  // __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)\n\n//enum class\nstruct _LIBCPP_TYPE_VIS pointer_safety\n{\n    enum __lx\n    {\n        relaxed,\n        preferred,\n        strict\n    };\n\n    __lx __v_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    pointer_safety(__lx __v) : __v_(__v) {}\n    _LIBCPP_INLINE_VISIBILITY\n    operator int() const {return __v_;}\n};\n\n_LIBCPP_FUNC_VIS void declare_reachable(void* __p);\n_LIBCPP_FUNC_VIS void declare_no_pointers(char* __p, size_t __n);\n_LIBCPP_FUNC_VIS void undeclare_no_pointers(char* __p, size_t __n);\n_LIBCPP_FUNC_VIS pointer_safety get_pointer_safety() _NOEXCEPT;\n_LIBCPP_FUNC_VIS void* __undeclare_reachable(void* __p);\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp*\nundeclare_reachable(_Tp* __p)\n{\n    return static_cast<_Tp*>(__undeclare_reachable(__p));\n}\n\n_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);\n\n// --- Helper for container swap --\ntemplate <typename _Alloc>\n_LIBCPP_INLINE_VISIBILITY\nvoid __swap_allocator(_Alloc & __a1, _Alloc & __a2)\n#if _LIBCPP_STD_VER >= 14\n    _NOEXCEPT\n#else\n    _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)\n#endif\n{\n    __swap_allocator(__a1, __a2, \n      integral_constant<bool, _VSTD::allocator_traits<_Alloc>::propagate_on_container_swap::value>());\n}\n\ntemplate <typename _Alloc>\n_LIBCPP_INLINE_VISIBILITY\nvoid __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type)\n#if _LIBCPP_STD_VER >= 14\n    _NOEXCEPT\n#else\n    _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)\n#endif\n{\n    using _VSTD::swap;\n    swap(__a1, __a2);\n}\n\ntemplate <typename _Alloc>\n_LIBCPP_INLINE_VISIBILITY\nvoid __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {}\n\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_MEMORY\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/module.modulemap",
    "content": "module std [system] {\n  // FIXME: The standard does not require that each of these submodules\n  // re-exports its imported modules. We should provide an alternative form of\n  // export that issues a warning if a name from the submodule is used, and\n  // use that to provide a 'strict mode' for libc++.\n  module algorithm {\n    header \"algorithm\"\n    export initializer_list\n    export *\n  }\n  module array {\n    header \"array\"\n    export initializer_list\n    export *\n  }\n  module atomic {\n    header \"atomic\"\n    export *\n    requires cplusplus11\n  }\n  module bitset {\n    header \"bitset\"\n    export string\n    export iosfwd\n    export *\n  }\n  // No submodule for cassert. It fundamentally needs repeated, textual inclusion.\n  module ccomplex {\n    header \"ccomplex\"\n    export complex\n    export *\n  }\n  module cctype {\n    header \"cctype\"\n    export *\n  }\n  module cerrno {\n    header \"cerrno\"\n/*\n    export_macros    ECONNREFUSED, EIO,          ENODEV,      ENOTEMPTY,       ERANGE,\n      E2BIG,         ECONNRESET,   EISCONN,      ENOENT,      ENOTRECOVERABLE, EROFS,\n      EACCES,        EDEADLK,      EISDIR,       ENOEXEC,     ENOTSOCK,        ESPIPE,\n      EADDRINUSE,    EDESTADDRREQ, ELOOP,        ENOLCK,      ENOTSUP,         ESRCH,\n      EADDRNOTAVAIL, EDOM,         EMFILE,       ENOLINK,     ENOTTY,          ETIME,\n      EAFNOSUPPORT,  EEXIST,       EMLINK,       ENOMEM,      ENXIO,           ETIMEDOUT,\n      EAGAIN,        EFAULT,       EMSGSIZE,     ENOMSG,      EOPNOTSUPP,      ETXTBSY,\n      EALREADY,      EFBIG,        ENAMETOOLONG, ENOPROTOOPT, EOVERFLOW,       EWOULDBLOCK,\n      EBADF,         EHOSTUNREACH, ENETDOWN,     ENOSPC,      EOWNERDEAD,      EXDEV,\n      EBADMSG,       EIDRM,        ENETRESET,    ENOSR,       EPERM,           errno,\n      EBUSY,         EILSEQ,       ENETUNREACH,  ENOSTR,      EPIPE,\n      ECANCELED,     EINPROGRESS,  ENFILE,       ENOSYS,      EPROTO,\n      ECHILD,        EINTR,        ENOBUFS,      ENOTCONN,    EPROTONOSUPPORT,\n      ECONNABORTED,  EINVAL,       ENODATA,      ENOTDIR,     EPROTOTYPE\n*/\n    export *\n  }\n  module cfenv {\n    header \"cfenv\"\n/*\n    export_macros FE_ALL_EXCEPT, FE_DIVBYZERO, FE_INEXACT, FE_INVALID, FE_OVERFLOW,\n                  FE_UNDERFLOW, FE_DOWNWARD, FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD,\n                  FE_DFL_ENV\n*/\n    export *\n  }\n  module cfloat {\n    header \"cfloat\"\n/*\n    export_macros FLT_EVAL_METHOD, FLT_RADIX, FLT_ROUNDS,\n                  FLT_DIG, FLT_EPSILON, FLT_MANT_DIG,\n                  FLT_MAX, FLT_MAX_10_EXP, FLT_MAX_EXP,\n                  FLT_MIN, FLT_MIN_10_EXP, FLT_MIN_EXP,\n                  DBL_DIG, DBL_EPSILON, DBL_MANT_DIG,\n                  DBL_MAX, DBL_MAX_10_EXP, DBL_MAX_EXP,\n                  DBL_MIN, DBL_MIN_10_EXP, DBL_MIN_EXP,\n                  LDBL_DIG, LDBL_EPSILON, LDBL_MANT_DIG,\n                  LDBL_MAX, LDBL_MAX_10_EXP, LDBL_MAX_EXP,\n                  LDBL_MIN, LDBL_MIN_10_EXP, LDBL_MIN_EXP\n*/\n    export *\n  }\n  module chrono {\n    header \"chrono\"\n    export *\n  }\n  module cinttypes {\n    header \"cinttypes\"\n    export cstdint\n/*\n    export_macros\n      PRId8, PRId16, PRId32, PRId64, PRIdFAST8, PRIdFAST16, PRIdFAST32, PRIdFAST64, PRIdLEAST8, PRIdLEAST16, PRIdLEAST32, PRIdLEAST64, PRIdMAX, PRIdPTR,\n      PRIi8, PRIi16, PRIi32, PRIi64, PRIiFAST8, PRIiFAST16, PRIiFAST32, PRIiFAST64, PRIiLEAST8, PRIiLEAST16, PRIiLEAST32, PRIiLEAST64, PRIiMAX, PRIiPTR,\n      PRIo8, PRIo16, PRIo32, PRIo64, PRIoFAST8, PRIoFAST16, PRIoFAST32, PRIoFAST64, PRIoLEAST8, PRIoLEAST16, PRIoLEAST32, PRIoLEAST64, PRIoMAX, PRIoPTR,\n      PRIu8, PRIu16, PRIu32, PRIu64, PRIuFAST8, PRIuFAST16, PRIuFAST32, PRIuFAST64, PRIuLEAST8, PRIuLEAST16, PRIuLEAST32, PRIuLEAST64, PRIuMAX, PRIuPTR,\n      PRIx8, PRIx16, PRIx32, PRIx64, PRIxFAST8, PRIxFAST16, PRIxFAST32, PRIxFAST64, PRIxLEAST8, PRIxLEAST16, PRIxLEAST32, PRIxLEAST64, PRIxMAX, PRIxPTR,\n      PRIX8, PRIX16, PRIX32, PRIX64, PRIXFAST8, PRIXFAST16, PRIXFAST32, PRIXFAST64, PRIXLEAST8, PRIXLEAST16, PRIXLEAST32, PRIXLEAST64, PRIXMAX, PRIXPTR,\n      SCNd8, SCNd16, SCNd32, SCNd64, SCNdFAST8, SCNdFAST16, SCNdFAST32, SCNdFAST64, SCNdLEAST8, SCNdLEAST16, SCNdLEAST32, SCNdLEAST64, SCNdMAX, SCNdPTR,\n      SCNi8, SCNi16, SCNi32, SCNi64, SCNiFAST8, SCNiFAST16, SCNiFAST32, SCNiFAST64, SCNiLEAST8, SCNiLEAST16, SCNiLEAST32, SCNiLEAST64, SCNiMAX, SCNiPTR,\n      SCNo8, SCNo16, SCNo32, SCNo64, SCNoFAST8, SCNoFAST16, SCNoFAST32, SCNoFAST64, SCNoLEAST8, SCNoLEAST16, SCNoLEAST32, SCNoLEAST64, SCNoMAX, SCNoPTR,\n      SCNu8, SCNu16, SCNu32, SCNu64, SCNuFAST8, SCNuFAST16, SCNuFAST32, SCNuFAST64, SCNuLEAST8, SCNuLEAST16, SCNuLEAST32, SCNuLEAST64, SCNuMAX, SCNuPTR,\n      SCNx8, SCNx16, SCNx32, SCNx64, SCNxFAST8, SCNxFAST16, SCNxFAST32, SCNxFAST64, SCNxLEAST8, SCNxLEAST16, SCNxLEAST32, SCNxLEAST64, SCNxMAX, SCNxPTR,\n      SCNX8, SCNX16, SCNX32, SCNX64, SCNXFAST8, SCNXFAST16, SCNXFAST32, SCNXFAST64, SCNXLEAST8, SCNXLEAST16, SCNXLEAST32, SCNXLEAST64, SCNXMAX, SCNXPTR\n*/\n    export *\n  }\n  module ciso646 {\n    header \"ciso646\"\n    export *\n  }\n  module climits {\n    header \"climits\"\n/*\n    export_macros CHAR_BIT,  CHAR_MIN,  CHAR_MAX,\n                  SCHAR_MIN, SCHAR_MAX, UCHAR_MAX,\n                  SHRT_MIN,  SHRT_MAX,  USHRT_MAX,\n                  INT_MIN,   INT_MAX,   UINT_MAX,\n                  LONG_MIN,  LONG_MAX,  ULONG_MAX,\n                  LLONG_MIN, LLONG_MAX, ULLONG_MAX,\n                  MB_LEN_MAX\n*/\n    export *\n  }\n  module clocale {\n    header \"clocale\"\n/*\n    export_macros LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME, NULL\n*/\n    export *\n  }\n  module cmath {\n    header \"cmath\"\n/*\n    export_macros FP_FAST_FMA, FP_FAST_FMAF, FP_FAST_FMAL, FP_ILOGBO, FP_ILOGBNAN,\n                  FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL, FP_ZERO,\n                  HUGE_VAL, HUGE_VALF, HUGE_VALL, INFINITY, NAN,\n                  MATH_ERRNO, MATH_ERREXCEPT, math_errhandling\n*/\n    export *\n  }\n  module codecvt {\n    header \"codecvt\"\n    export *\n  }\n  module complex {\n    header \"complex\"\n    export *\n  }\n  module condition_variable {\n    header \"condition_variable\"\n    export *\n  }\n  module csetjmp {\n    header \"csetjmp\"\n/*\n    export_macros setjmp\n*/\n    export *\n  }\n  module csignal {\n    header \"csignal\"\n/*\n    export_macros SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM,\n                  SIG_DFL, SIG_IGN, SIG_ERR\n*/\n    export *\n  }\n  module cstdarg {\n    header \"cstdarg\"\n/*\n    export_macros va_arg, va_start, va_end, va_copy\n*/\n    export *\n  }\n  module cstdbool {\n    header \"cstdbool\"\n/*\n    export_macros __bool_true_false_are_defined\n*/\n    export *\n  }\n  module cstddef {\n    header \"cstddef\"\n/*\n    export_macros NULL, offsetof\n*/\n    export *\n  }\n  module cstdint {\n    header \"cstdint\"\n/*\n    export_macros\n      INT_8_MIN, INT_8_MAX, UINT_8_MAX, INT_16_MIN, INT_16_MAX, UINT_16_MAX,\n      INT_32_MIN, INT_32_MAX, UINT_32_MAX, INT_64_MIN, INT_64_MAX, UINT_64_MAX,\n      INT_FAST8_MIN, INT_FAST8_MAX, UINT_FAST8_MAX, INT_FAST16_MIN, INT_FAST16_MAX, UINT_FAST16_MAX,\n      INT_FAST32_MIN, INT_FAST32_MAX, UINT_FAST32_MAX, INT_FAST64_MIN, INT_FAST64_MAX, UINT_FAST64_MAX,\n      INT_LEAST8_MIN, INT_LEAST8_MAX, UINT_LEAST8_MAX, INT_LEAST16_MIN, INT_LEAST16_MAX, UINT_LEAST16_MAX,\n      INT_LEAST32_MIN, INT_LEAST32_MAX, UINT_LEAST32_MAX, INT_LEAST64_MIN, INT_LEAST64_MAX, UINT_LEAST64_MAX,\n      INT_MAX_MIN, INT_MAX_MAX, UINT_MAX_MAX, INT_PTR_MIN, INT_PTR_MAX, UINT_PTR_MAX,\n      PTRDIFF_MIN, PTRDIFF_MAX, SIG_ATOMIC_MIN, SIG_ATOMIC_MAX, WCHAR_MIN, WCHAR_MAX, WINT_MIN, WINT_MAX,\n      SIZE_MAX\n*/\n    export *\n  }\n  module cstdio {\n    header \"cstdio\"\n/*\n    export_macros BUFSIZ, EOF, FILENAME_MAX, FOPEN_MAX, L_tmpnam, NULL,\n                  SEEK_CUR, SEEK_END, SEEK_SET, TMP_MAX, _IOFBF, _IOLBF,\n                  stdin, stdout, stderr\n*/\n    export *\n  }\n  module cstdlib {\n    header \"cstdlib\"\n/*\n    export_macros RAND_MAX\n*/\n    export *\n  }\n  module cstring {\n    header \"cstring\"\n/*\n    export_macros NULL\n*/\n    export *\n  }\n  module ctgmath {\n    header \"ctgmath\"\n    export ccomplex\n    export cmath\n    export *\n  }\n  module ctime {\n    header \"ctime\"\n/*\n    export_macros NULL, CLOCKS_PER_SEC\n*/\n    export *\n  }\n  module cwchar {\n    header \"cwchar\"\n/*\n    export_macros NULL, WCHAR_MAX, WCHAR_MIN, WEOF\n*/\n    export *\n  }\n  module cwctype {\n    header \"cwctype\"\n/*\n    export_macros WEOF\n*/\n    export *\n  }\n  module deque {\n    header \"deque\"\n    export initializer_list\n    export *\n  }\n  module exception {\n    header \"exception\"\n    export *\n  }\n  module forward_list {\n    header \"forward_list\"\n    export initializer_list\n    export *\n  }\n  module fstream {\n    header \"fstream\"\n    export *\n  }\n  module functional {\n    header \"functional\"\n    export *\n  }\n  module future {\n    header \"future\"\n    export *\n  }\n  module initializer_list {\n    header \"initializer_list\"\n    export *\n  }\n  module iomanip {\n    header \"iomanip\"\n    export *\n  }\n  module ios {\n    header \"ios\"\n    export iosfwd\n    export *\n  }\n  module iosfwd {\n    header \"iosfwd\"\n    export *\n  }\n  module iostream {\n    header \"iostream\"\n    export ios\n    export streambuf\n    export istream\n    export ostream\n    export *\n  }\n  module istream {\n    header \"istream\"\n    // FIXME: should re-export ios, streambuf?\n    export *\n  }\n  module iterator {\n    header \"iterator\"\n    export *\n  }\n  module limits {\n    header \"limits\"\n    export *\n  }\n  module list {\n    header \"list\"\n    export initializer_list\n    export *\n  }\n  module locale {\n    header \"locale\"\n    export *\n  }\n  module map {\n    header \"map\"\n    export initializer_list\n    export *\n  }\n  module memory {\n    header \"memory\"\n    export *\n  }\n  module mutex {\n    header \"mutex\"\n    export *\n  }\n  module new {\n    header \"new\"\n    export *\n  }\n  module numeric {\n    header \"numeric\"\n    export *\n  }\n  module ostream {\n    header \"ostream\"\n    // FIXME: should re-export ios, streambuf?\n    export *\n  }\n  module queue {\n    header \"queue\"\n    export initializer_list\n    export *\n  }\n  module random {\n    header \"random\"\n    export initializer_list\n    export *\n  }\n  module ratio {\n    header \"ratio\"\n    export *\n  }\n  module regex {\n    header \"regex\"\n    export initializer_list\n    export *\n  }\n  module scoped_allocator {\n    header \"scoped_allocator\"\n    export *\n  }\n  module set {\n    header \"set\"\n    export initializer_list\n    export *\n  }\n  module sstream {\n    header \"sstream\"\n    // FIXME: should re-export istream, ostream, ios, streambuf, string?\n    export *\n  }\n  module stack {\n    header \"stack\"\n    export initializer_list\n    export *\n  }\n  module stdexcept {\n    header \"stdexcept\"\n    export *\n  }\n  module streambuf {\n    header \"streambuf\"\n    export *\n  }\n  module string {\n    header \"string\"\n    export initializer_list\n    export *\n  }\n  module strstream {\n    header \"strstream\"\n    requires !cplusplus11\n  }\n  module system_error {\n    header \"system_error\"\n    export *\n  }\n  module thread {\n    header \"thread\"\n    export *\n  }\n  module tuple {\n    header \"tuple\"\n    export *\n  }\n  module type_traits {\n    header \"type_traits\"\n    export *\n  }\n  module typeindex {\n    header \"typeindex\"\n    export *\n  }\n  module typeinfo {\n    header \"typeinfo\"\n    export *\n  }\n  module unordered_map {\n    header \"unordered_map\"\n    export initializer_list\n    export *\n  }\n  module unordered_set {\n    header \"unordered_set\"\n    export initializer_list\n    export *\n  }\n  module utility {\n    header \"utility\"\n    export initializer_list\n    export *\n  }\n  module valarray {\n    header \"valarray\"\n    export initializer_list\n    export *\n  }\n  module vector {\n    header \"vector\"\n    export initializer_list\n    export *\n  }\n\n  // FIXME: These should be private.\n  module __bit_reference { header \"__bit_reference\" export * }\n  module __config { header \"__config\" export * }\n  module __debug { header \"__debug\" export * }\n  module __functional_base { header \"__functional_base\" export * }\n  module __hash_table { header \"__hash_table\" export * }\n  module __locale { header \"__locale\" export * }\n  module __mutex_base { header \"__mutex_base\" export * }\n  module __split_buffer { header \"__split_buffer\" export * }\n  module __sso_allocator { header \"__sso_allocator\" export * }\n  module __std_stream { header \"__std_stream\" export * }\n  module __tree { header \"__tree\" export * }\n  module __tuple { header \"__tuple\" export * }\n  module __undef_min_max { header \"__undef_min_max\" export * }\n  module __undef___deallocate { header \"__undef___deallocate\" export * }\n}\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/mutex",
    "content": "// -*- C++ -*-\n//===--------------------------- mutex ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_MUTEX\n#define _LIBCPP_MUTEX\n\n/*\n    mutex synopsis\n\nnamespace std\n{\n\nclass mutex\n{\npublic:\n     constexpr mutex() noexcept;\n     ~mutex();\n\n    mutex(const mutex&) = delete;\n    mutex& operator=(const mutex&) = delete;\n\n    void lock();\n    bool try_lock();\n    void unlock();\n\n    typedef pthread_mutex_t* native_handle_type;\n    native_handle_type native_handle();\n};\n\nclass recursive_mutex\n{\npublic:\n     recursive_mutex();\n     ~recursive_mutex();\n\n    recursive_mutex(const recursive_mutex&) = delete;\n    recursive_mutex& operator=(const recursive_mutex&) = delete;\n\n    void lock();\n    bool try_lock() noexcept;\n    void unlock();\n\n    typedef pthread_mutex_t* native_handle_type;\n    native_handle_type native_handle();\n};\n\nclass timed_mutex\n{\npublic:\n     timed_mutex();\n     ~timed_mutex();\n\n    timed_mutex(const timed_mutex&) = delete;\n    timed_mutex& operator=(const timed_mutex&) = delete;\n\n    void lock();\n    bool try_lock();\n    template <class Rep, class Period>\n        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);\n    template <class Clock, class Duration>\n        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);\n    void unlock();\n};\n\nclass recursive_timed_mutex\n{\npublic:\n     recursive_timed_mutex();\n     ~recursive_timed_mutex();\n\n    recursive_timed_mutex(const recursive_timed_mutex&) = delete;\n    recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;\n\n    void lock();\n    bool try_lock() noexcept;\n    template <class Rep, class Period>\n        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);\n    template <class Clock, class Duration>\n        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);\n    void unlock();\n};\n\nstruct defer_lock_t {};\nstruct try_to_lock_t {};\nstruct adopt_lock_t {};\n\nconstexpr defer_lock_t  defer_lock{};\nconstexpr try_to_lock_t try_to_lock{};\nconstexpr adopt_lock_t  adopt_lock{};\n\ntemplate <class Mutex>\nclass lock_guard\n{\npublic:\n    typedef Mutex mutex_type;\n\n    explicit lock_guard(mutex_type& m);\n    lock_guard(mutex_type& m, adopt_lock_t);\n    ~lock_guard();\n\n    lock_guard(lock_guard const&) = delete;\n    lock_guard& operator=(lock_guard const&) = delete;\n};\n\ntemplate <class Mutex>\nclass unique_lock\n{\npublic:\n    typedef Mutex mutex_type;\n    unique_lock() noexcept;\n    explicit unique_lock(mutex_type& m);\n    unique_lock(mutex_type& m, defer_lock_t) noexcept;\n    unique_lock(mutex_type& m, try_to_lock_t);\n    unique_lock(mutex_type& m, adopt_lock_t);\n    template <class Clock, class Duration>\n        unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);\n    template <class Rep, class Period>\n        unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);\n    ~unique_lock();\n\n    unique_lock(unique_lock const&) = delete;\n    unique_lock& operator=(unique_lock const&) = delete;\n\n    unique_lock(unique_lock&& u) noexcept;\n    unique_lock& operator=(unique_lock&& u) noexcept;\n\n    void lock();\n    bool try_lock();\n\n    template <class Rep, class Period>\n        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);\n    template <class Clock, class Duration>\n        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);\n\n    void unlock();\n\n    void swap(unique_lock& u) noexcept;\n    mutex_type* release() noexcept;\n\n    bool owns_lock() const noexcept;\n    explicit operator bool () const noexcept;\n    mutex_type* mutex() const noexcept;\n};\n\ntemplate <class Mutex>\n  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;\n\ntemplate <class L1, class L2, class... L3>\n  int try_lock(L1&, L2&, L3&...);\ntemplate <class L1, class L2, class... L3>\n  void lock(L1&, L2&, L3&...);\n\nstruct once_flag\n{\n    constexpr once_flag() noexcept;\n\n    once_flag(const once_flag&) = delete;\n    once_flag& operator=(const once_flag&) = delete;\n};\n\ntemplate<class Callable, class ...Args>\n  void call_once(once_flag& flag, Callable&& func, Args&&... args);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <__mutex_base>\n#include <functional>\n#include <memory>\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n#include <tuple>\n#endif\n#include <sched.h>\n\n#include <__undef_min_max>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n#ifndef _LIBCPP_HAS_NO_THREADS\n\nclass _LIBCPP_TYPE_VIS recursive_mutex\n{\n    pthread_mutex_t __m_;\n\npublic:\n     recursive_mutex();\n     ~recursive_mutex();\n\nprivate:\n    recursive_mutex(const recursive_mutex&); // = delete;\n    recursive_mutex& operator=(const recursive_mutex&); // = delete;\n\npublic:\n    void lock();\n    bool try_lock() _NOEXCEPT;\n    void unlock()  _NOEXCEPT;\n\n    typedef pthread_mutex_t* native_handle_type;\n    _LIBCPP_INLINE_VISIBILITY\n    native_handle_type native_handle() {return &__m_;}\n};\n\nclass _LIBCPP_TYPE_VIS timed_mutex\n{\n    mutex              __m_;\n    condition_variable __cv_;\n    bool               __locked_;\npublic:\n     timed_mutex();\n     ~timed_mutex();\n\nprivate:\n    timed_mutex(const timed_mutex&); // = delete;\n    timed_mutex& operator=(const timed_mutex&); // = delete;\n\npublic:\n    void lock();\n    bool try_lock() _NOEXCEPT;\n    template <class _Rep, class _Period>\n        _LIBCPP_INLINE_VISIBILITY\n        bool try_lock_for(const chrono::duration<_Rep, _Period>& __d)\n            {return try_lock_until(chrono::steady_clock::now() + __d);}\n    template <class _Clock, class _Duration>\n        bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);\n    void unlock() _NOEXCEPT;\n};\n\ntemplate <class _Clock, class _Duration>\nbool\ntimed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)\n{\n    using namespace chrono;\n    unique_lock<mutex> __lk(__m_);\n    bool no_timeout = _Clock::now() < __t;\n    while (no_timeout && __locked_)\n        no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;\n    if (!__locked_)\n    {\n        __locked_ = true;\n        return true;\n    }\n    return false;\n}\n\nclass _LIBCPP_TYPE_VIS recursive_timed_mutex\n{\n    mutex              __m_;\n    condition_variable __cv_;\n    size_t             __count_;\n    pthread_t          __id_;\npublic:\n     recursive_timed_mutex();\n     ~recursive_timed_mutex();\n\nprivate:\n    recursive_timed_mutex(const recursive_timed_mutex&); // = delete;\n    recursive_timed_mutex& operator=(const recursive_timed_mutex&); // = delete;\n\npublic:\n    void lock();\n    bool try_lock() _NOEXCEPT;\n    template <class _Rep, class _Period>\n        _LIBCPP_INLINE_VISIBILITY\n        bool try_lock_for(const chrono::duration<_Rep, _Period>& __d)\n            {return try_lock_until(chrono::steady_clock::now() + __d);}\n    template <class _Clock, class _Duration>\n        bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);\n    void unlock() _NOEXCEPT;\n};\n\ntemplate <class _Clock, class _Duration>\nbool\nrecursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)\n{\n    using namespace chrono;\n    pthread_t __id = pthread_self();\n    unique_lock<mutex> lk(__m_);\n    if (pthread_equal(__id, __id_))\n    {\n        if (__count_ == numeric_limits<size_t>::max())\n            return false;\n        ++__count_;\n        return true;\n    }\n    bool no_timeout = _Clock::now() < __t;\n    while (no_timeout && __count_ != 0)\n        no_timeout = __cv_.wait_until(lk, __t) == cv_status::no_timeout;\n    if (__count_ == 0)\n    {\n        __count_ = 1;\n        __id_ = __id;\n        return true;\n    }\n    return false;\n}\n\ntemplate <class _L0, class _L1>\nint\ntry_lock(_L0& __l0, _L1& __l1)\n{\n    unique_lock<_L0> __u0(__l0, try_to_lock);\n    if (__u0.owns_lock())\n    {\n        if (__l1.try_lock())\n        {\n            __u0.release();\n            return -1;\n        }\n        else\n            return 1;\n    }\n    return 0;\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _L0, class _L1, class _L2, class... _L3>\nint\ntry_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3)\n{\n    int __r = 0;\n    unique_lock<_L0> __u0(__l0, try_to_lock);\n    if (__u0.owns_lock())\n    {\n        __r = try_lock(__l1, __l2, __l3...);\n        if (__r == -1)\n            __u0.release();\n        else\n            ++__r;\n    }\n    return __r;\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _L0, class _L1>\nvoid\nlock(_L0& __l0, _L1& __l1)\n{\n    while (true)\n    {\n        {\n            unique_lock<_L0> __u0(__l0);\n            if (__l1.try_lock())\n            {\n                __u0.release();\n                break;\n            }\n        }\n        sched_yield();\n        {\n            unique_lock<_L1> __u1(__l1);\n            if (__l0.try_lock())\n            {\n                __u1.release();\n                break;\n            }\n        }\n        sched_yield();\n    }\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _L0, class _L1, class _L2, class ..._L3>\nvoid\n__lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)\n{\n    while (true)\n    {\n        switch (__i)\n        {\n        case 0:\n            {\n                unique_lock<_L0> __u0(__l0);\n                __i = try_lock(__l1, __l2, __l3...);\n                if (__i == -1)\n                {\n                    __u0.release();\n                    return;\n                }\n            }\n            ++__i;\n            sched_yield();\n            break;\n        case 1:\n            {\n                unique_lock<_L1> __u1(__l1);\n                __i = try_lock(__l2, __l3..., __l0);\n                if (__i == -1)\n                {\n                    __u1.release();\n                    return;\n                }\n            }\n            if (__i == sizeof...(_L3) + 1)\n                __i = 0;\n            else\n                __i += 2;\n            sched_yield();\n            break;\n        default:\n            __lock_first(__i - 2, __l2, __l3..., __l0, __l1);\n            return;\n        }\n    }\n}\n\ntemplate <class _L0, class _L1, class _L2, class ..._L3>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)\n{\n    __lock_first(0, __l0, __l1, __l2, __l3...);\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n#endif // !_LIBCPP_HAS_NO_THREADS\n\nstruct _LIBCPP_TYPE_VIS_ONLY once_flag;\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate<class _Callable, class... _Args>\n_LIBCPP_INLINE_VISIBILITY\nvoid call_once(once_flag&, _Callable&&, _Args&&...);\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate<class _Callable>\n_LIBCPP_INLINE_VISIBILITY\nvoid call_once(once_flag&, _Callable&);\n\ntemplate<class _Callable>\n_LIBCPP_INLINE_VISIBILITY\nvoid call_once(once_flag&, const _Callable&);\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\nstruct _LIBCPP_TYPE_VIS_ONLY once_flag\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_CONSTEXPR\n        once_flag() _NOEXCEPT : __state_(0) {}\n\nprivate:\n    once_flag(const once_flag&); // = delete;\n    once_flag& operator=(const once_flag&); // = delete;\n\n    unsigned long __state_;\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template<class _Callable, class... _Args>\n    friend\n    void call_once(once_flag&, _Callable&&, _Args&&...);\n#else  // _LIBCPP_HAS_NO_VARIADICS\n    template<class _Callable>\n    friend\n    void call_once(once_flag&, _Callable&);\n\n    template<class _Callable>\n    friend\n    void call_once(once_flag&, const _Callable&);\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n};\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Fp>\nclass __call_once_param\n{\n    _Fp& __f_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __call_once_param(_Fp& __f) : __f_(__f) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void operator()()\n    {\n        typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index;\n        __execute(_Index());\n    }\n\nprivate:\n    template <size_t ..._Indices>\n    _LIBCPP_INLINE_VISIBILITY\n    void __execute(__tuple_indices<_Indices...>)\n    {\n        __invoke(_VSTD::get<0>(_VSTD::move(__f_)), _VSTD::get<_Indices>(_VSTD::move(__f_))...);\n    }\n};\n\n#else\n\ntemplate <class _Fp>\nclass __call_once_param\n{\n    _Fp& __f_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __call_once_param(_Fp& __f) : __f_(__f) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void operator()()\n    {\n        __f_();\n    }\n};\n\n#endif\n\ntemplate <class _Fp>\nvoid\n__call_once_proxy(void* __vp)\n{\n    __call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp);\n    (*__p)();\n}\n\n_LIBCPP_FUNC_VIS void __call_once(volatile unsigned long&, void*, void(*)(void*));\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate<class _Callable, class... _Args>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\ncall_once(once_flag& __flag, _Callable&& __func, _Args&&... __args)\n{\n    if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul)\n    {\n        typedef tuple<_Callable&&, _Args&&...> _Gp;\n        _Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...);\n        __call_once_param<_Gp> __p(__f);\n        __call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>);\n    }\n}\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate<class _Callable>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\ncall_once(once_flag& __flag, _Callable& __func)\n{\n    if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul)\n    {\n        __call_once_param<_Callable> __p(__func);\n        __call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>);\n    }\n}\n\ntemplate<class _Callable>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\ncall_once(once_flag& __flag, const _Callable& __func)\n{\n    if (__flag.__state_ != ~0ul)\n    {\n        __call_once_param<const _Callable> __p(__func);\n        __call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>);\n    }\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_MUTEX\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/new",
    "content": "// -*- C++ -*-\n//===----------------------------- new ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_NEW\n#define _LIBCPP_NEW\n\n/*\n    new synopsis\n\nnamespace std\n{\n\nclass bad_alloc\n    : public exception\n{\npublic:\n    bad_alloc() noexcept;\n    bad_alloc(const bad_alloc&) noexcept;\n    bad_alloc& operator=(const bad_alloc&) noexcept;\n    virtual const char* what() const noexcept;\n};\n\nclass bad_array_length : public bad_alloc // C++14\n{\npublic:\n    bad_array_length() noexcept;\n};\n\nclass bad_array_new_length : public bad_alloc\n{\npublic:\n    bad_array_new_length() noexcept;\n};\n\nstruct nothrow_t {};\nextern const nothrow_t nothrow;\ntypedef void (*new_handler)();\nnew_handler set_new_handler(new_handler new_p) noexcept;\nnew_handler get_new_handler() noexcept;\n\n}  // std\n\nvoid* operator new(std::size_t size);                                   // replaceable\nvoid* operator new(std::size_t size, const std::nothrow_t&) noexcept;   // replaceable\nvoid  operator delete(void* ptr) noexcept;                              // replaceable\nvoid  operator delete(void* ptr, std::size_t size) noexcept;            // replaceable, C++14\nvoid  operator delete(void* ptr, const std::nothrow_t&) noexcept;       // replaceable\n\nvoid* operator new[](std::size_t size);                                 // replaceable\nvoid* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable\nvoid  operator delete[](void* ptr) noexcept;                            // replaceable\nvoid  operator delete[](void* ptr, std::size_t size) noexcept;          // replaceable, C++14\nvoid  operator delete[](void* ptr, const std::nothrow_t&) noexcept;     // replaceable\n\nvoid* operator new  (std::size_t size, void* ptr) noexcept;\nvoid* operator new[](std::size_t size, void* ptr) noexcept;\nvoid  operator delete  (void* ptr, void*) noexcept;\nvoid  operator delete[](void* ptr, void*) noexcept;\n\n*/\n\n#include <__config>\n#include <exception>\n#include <cstddef>\n\n#include <__undef___deallocate>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\nnamespace std  // purposefully not using versioning namespace\n{\n\nclass _LIBCPP_EXCEPTION_ABI bad_alloc\n    : public exception\n{\npublic:\n    bad_alloc() _NOEXCEPT;\n    virtual ~bad_alloc() _NOEXCEPT;\n    virtual const char* what() const _NOEXCEPT;\n};\n\nclass _LIBCPP_EXCEPTION_ABI bad_array_new_length\n    : public bad_alloc\n{\npublic:\n    bad_array_new_length() _NOEXCEPT;\n    virtual ~bad_array_new_length() _NOEXCEPT;\n    virtual const char* what() const _NOEXCEPT;\n};\n\n#if defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11)\n\nclass _LIBCPP_EXCEPTION_ABI bad_array_length\n    : public bad_alloc\n{\npublic:\n    bad_array_length() _NOEXCEPT;\n    virtual ~bad_array_length() _NOEXCEPT;\n    virtual const char* what() const _NOEXCEPT;\n};\n\n#define _LIBCPP_BAD_ARRAY_LENGTH_DEFINED\n\n#endif  // defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11)\n\n_LIBCPP_FUNC_VIS void __throw_bad_alloc();  // not in C++ spec\n\nstruct _LIBCPP_TYPE_VIS nothrow_t {};\nextern _LIBCPP_FUNC_VIS const nothrow_t nothrow;\ntypedef void (*new_handler)();\n_LIBCPP_FUNC_VIS new_handler set_new_handler(new_handler) _NOEXCEPT;\n_LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT;\n\n}  // std\n\n#if defined(_WIN32) && !defined(cxx_EXPORTS)\n# define _LIBCPP_NEW_DELETE_VIS _LIBCPP_FUNC_VIS_ONLY\n#else\n# define _LIBCPP_NEW_DELETE_VIS _LIBCPP_FUNC_VIS\n#endif\n\n_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz)\n#if !__has_feature(cxx_noexcept)\n    throw(std::bad_alloc)\n#endif\n;\n_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;\n_LIBCPP_NEW_DELETE_VIS void  operator delete(void* __p) _NOEXCEPT;\n_LIBCPP_NEW_DELETE_VIS void  operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;\n#if defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \\\n    (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309)\n_LIBCPP_NEW_DELETE_VIS void  operator delete(void* __p, std::size_t __sz) _NOEXCEPT;\n#endif\n\n_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz)\n#if !__has_feature(cxx_noexcept)\n    throw(std::bad_alloc)\n#endif\n;\n_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;\n_LIBCPP_NEW_DELETE_VIS void  operator delete[](void* __p) _NOEXCEPT;\n_LIBCPP_NEW_DELETE_VIS void  operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;\n#if defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \\\n    (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309)\n_LIBCPP_NEW_DELETE_VIS void  operator delete[](void* __p, std::size_t __sz) _NOEXCEPT;\n#endif\n\ninline _LIBCPP_INLINE_VISIBILITY void* operator new  (std::size_t, void* __p) _NOEXCEPT {return __p;}\ninline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;}\ninline _LIBCPP_INLINE_VISIBILITY void  operator delete  (void*, void*) _NOEXCEPT {}\ninline _LIBCPP_INLINE_VISIBILITY void  operator delete[](void*, void*) _NOEXCEPT {}\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ninline _LIBCPP_INLINE_VISIBILITY void *__allocate(size_t __size) {\n#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE\n  return ::operator new(__size);\n#else\n  return __builtin_operator_new(__size);\n#endif\n}\n\ninline _LIBCPP_INLINE_VISIBILITY void __deallocate(void *__ptr) {\n#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE\n  ::operator delete(__ptr);\n#else\n  __builtin_operator_delete(__ptr);\n#endif\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_NEW\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/numeric",
    "content": "// -*- C++ -*-\n//===---------------------------- numeric ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_NUMERIC\n#define _LIBCPP_NUMERIC\n\n/*\n    numeric synopsis\n\nnamespace std\n{\n\ntemplate <class InputIterator, class T>\n    T\n    accumulate(InputIterator first, InputIterator last, T init);\n\ntemplate <class InputIterator, class T, class BinaryOperation>\n    T\n    accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);\n\ntemplate <class InputIterator1, class InputIterator2, class T>\n    T\n    inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init);\n\ntemplate <class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2>\n    T\n    inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,\n                  T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);\n\ntemplate <class InputIterator, class OutputIterator>\n    OutputIterator\n    partial_sum(InputIterator first, InputIterator last, OutputIterator result);\n\ntemplate <class InputIterator, class OutputIterator, class BinaryOperation>\n    OutputIterator\n    partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);\n\ntemplate <class InputIterator, class OutputIterator>\n    OutputIterator\n    adjacent_difference(InputIterator first, InputIterator last, OutputIterator result);\n\ntemplate <class InputIterator, class OutputIterator, class BinaryOperation>\n    OutputIterator\n    adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);\n\ntemplate <class ForwardIterator, class T>\n    void iota(ForwardIterator first, ForwardIterator last, T value);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <iterator>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _InputIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\naccumulate(_InputIterator __first, _InputIterator __last, _Tp __init)\n{\n    for (; __first != __last; ++__first)\n        __init = __init + *__first;\n    return __init;\n}\n\ntemplate <class _InputIterator, class _Tp, class _BinaryOperation>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\naccumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op)\n{\n    for (; __first != __last; ++__first)\n        __init = __binary_op(__init, *__first);\n    return __init;\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\ninner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init)\n{\n    for (; __first1 != __last1; ++__first1, (void) ++__first2)\n        __init = __init + *__first1 * *__first2;\n    return __init;\n}\n\ntemplate <class _InputIterator1, class _InputIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\ninner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,\n              _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)\n{\n    for (; __first1 != __last1; ++__first1, (void) ++__first2)\n        __init = __binary_op1(__init, __binary_op2(*__first1, *__first2));\n    return __init;\n}\n\ntemplate <class _InputIterator, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\npartial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result)\n{\n    if (__first != __last)\n    {\n        typename iterator_traits<_InputIterator>::value_type __t(*__first);\n        *__result = __t;\n        for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)\n        {\n            __t = __t + *__first;\n            *__result = __t;\n        }\n    }\n    return __result;\n}\n\ntemplate <class _InputIterator, class _OutputIterator, class _BinaryOperation>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\npartial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result,\n              _BinaryOperation __binary_op)\n{\n    if (__first != __last)\n    {\n        typename iterator_traits<_InputIterator>::value_type __t(*__first);\n        *__result = __t;\n        for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)\n        {\n            __t = __binary_op(__t, *__first);\n            *__result = __t;\n        }\n    }\n    return __result;\n}\n\ntemplate <class _InputIterator, class _OutputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nadjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result)\n{\n    if (__first != __last)\n    {\n        typename iterator_traits<_InputIterator>::value_type __t1(*__first);\n        *__result = __t1;\n        for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)\n        {\n            typename iterator_traits<_InputIterator>::value_type __t2(*__first);\n            *__result = __t2 - __t1;\n            __t1 = _VSTD::move(__t2);\n        }\n    }\n    return __result;\n}\n\ntemplate <class _InputIterator, class _OutputIterator, class _BinaryOperation>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nadjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result,\n                      _BinaryOperation __binary_op)\n{\n    if (__first != __last)\n    {\n        typename iterator_traits<_InputIterator>::value_type __t1(*__first);\n        *__result = __t1;\n        for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)\n        {\n            typename iterator_traits<_InputIterator>::value_type __t2(*__first);\n            *__result = __binary_op(__t2, __t1);\n            __t1 = _VSTD::move(__t2);\n        }\n    }\n    return __result;\n}\n\ntemplate <class _ForwardIterator, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\niota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value_)\n{\n    for (; __first != __last; ++__first, (void) ++__value_)\n        *__first = __value_;\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_NUMERIC\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/ostream",
    "content": "// -*- C++ -*-\n//===-------------------------- ostream -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_OSTREAM\n#define _LIBCPP_OSTREAM\n\n/*\n    ostream synopsis\n\ntemplate <class charT, class traits = char_traits<charT> >\nclass basic_ostream\n    : virtual public basic_ios<charT,traits>\n{\npublic:\n    // types (inherited from basic_ios (27.5.4)):\n    typedef charT                          char_type;\n    typedef traits                         traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    // 27.7.2.2 Constructor/destructor:\n    explicit basic_ostream(basic_streambuf<char_type,traits>* sb);\n    basic_ostream(basic_ostream&& rhs);\n    virtual ~basic_ostream();\n\n    // 27.7.2.3 Assign/swap\n    basic_ostream& operator=(const basic_ostream& rhs) = delete; // C++14\n    basic_ostream& operator=(basic_ostream&& rhs);\n    void swap(basic_ostream& rhs);\n\n    // 27.7.2.4 Prefix/suffix:\n    class sentry;\n\n    // 27.7.2.6 Formatted output:\n    basic_ostream& operator<<(basic_ostream& (*pf)(basic_ostream&));\n    basic_ostream& operator<<(basic_ios<charT, traits>& (*pf)(basic_ios<charT,traits>&));\n    basic_ostream& operator<<(ios_base& (*pf)(ios_base&));\n    basic_ostream& operator<<(bool n);\n    basic_ostream& operator<<(short n);\n    basic_ostream& operator<<(unsigned short n);\n    basic_ostream& operator<<(int n);\n    basic_ostream& operator<<(unsigned int n);\n    basic_ostream& operator<<(long n);\n    basic_ostream& operator<<(unsigned long n);\n    basic_ostream& operator<<(long long n);\n    basic_ostream& operator<<(unsigned long long n);\n    basic_ostream& operator<<(float f);\n    basic_ostream& operator<<(double f);\n    basic_ostream& operator<<(long double f);\n    basic_ostream& operator<<(const void* p);\n    basic_ostream& operator<<(basic_streambuf<char_type,traits>* sb);\n\n    // 27.7.2.7 Unformatted output:\n    basic_ostream& put(char_type c);\n    basic_ostream& write(const char_type* s, streamsize n);\n    basic_ostream& flush();\n\n    // 27.7.2.5 seeks:\n    pos_type tellp();\n    basic_ostream& seekp(pos_type);\n    basic_ostream& seekp(off_type, ios_base::seekdir);\nprotected:\n    basic_ostream(const basic_ostream& rhs) = delete;\n    basic_ostream(basic_ostream&& rhs);\n    // 27.7.3.3 Assign/swap\n    basic_ostream& operator=(basic_ostream& rhs) = delete;\n    basic_ostream& operator=(const basic_ostream&& rhs);\n    void swap(basic_ostream& rhs);\n};\n\n// 27.7.2.6.4 character inserters\n\ntemplate<class charT, class traits>\n  basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, charT);\n\ntemplate<class charT, class traits>\n  basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, char);\n\ntemplate<class traits>\n  basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, char);\n\n// signed and unsigned\n\ntemplate<class traits>\n  basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, signed char);\n\ntemplate<class traits>\n  basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, unsigned char);\n\n// NTBS\ntemplate<class charT, class traits>\n  basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);\n\ntemplate<class charT, class traits>\n  basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const char*);\n\ntemplate<class traits>\n  basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, const char*);\n\n// signed and unsigned\ntemplate<class traits>\nbasic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, const signed char*);\n\ntemplate<class traits>\n  basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, const unsigned char*);\n\n// swap:\ntemplate <class charT, class traits>\n  void swap(basic_ostream<charT, traits>& x, basic_ostream<charT, traits>& y);\n\ntemplate <class charT, class traits>\n  basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os);\n\ntemplate <class charT, class traits>\n  basic_ostream<charT,traits>& ends(basic_ostream<charT,traits>& os);\n\ntemplate <class charT, class traits>\n  basic_ostream<charT,traits>& flush(basic_ostream<charT,traits>& os);\n\n// rvalue stream insertion\ntemplate <class charT, class traits, class T>\n  basic_ostream<charT, traits>&\n  operator<<(basic_ostream<charT, traits>&& os, const T& x);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <ios>\n#include <streambuf>\n#include <locale>\n#include <iterator>\n#include <bitset>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _CharT, class _Traits>\nclass _LIBCPP_TYPE_VIS_ONLY basic_ostream\n    : virtual public basic_ios<_CharT, _Traits>\n{\npublic:\n    // types (inherited from basic_ios (27.5.4)):\n    typedef _CharT                         char_type;\n    typedef _Traits                        traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    // 27.7.2.2 Constructor/destructor:\n    explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb);\n    virtual ~basic_ostream();\nprotected:\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    basic_ostream(basic_ostream&& __rhs);\n#endif\n\n    // 27.7.2.3 Assign/swap\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    basic_ostream& operator=(basic_ostream&& __rhs);\n#endif\n    void swap(basic_ostream& __rhs);\n\n#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n    basic_ostream           (const basic_ostream& __rhs) = delete;\n    basic_ostream& operator=(const basic_ostream& __rhs) = delete;\n#else\n    basic_ostream           (const basic_ostream& __rhs); // not defined\n    basic_ostream& operator=(const basic_ostream& __rhs); // not defined\n#endif\npublic:\n\n    // 27.7.2.4 Prefix/suffix:\n    class _LIBCPP_TYPE_VIS_ONLY sentry;\n\n    // 27.7.2.6 Formatted output:\n    basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&));\n    basic_ostream& operator<<(basic_ios<char_type, traits_type>&\n                              (*__pf)(basic_ios<char_type,traits_type>&));\n    basic_ostream& operator<<(ios_base& (*__pf)(ios_base&));\n    basic_ostream& operator<<(bool __n);\n    basic_ostream& operator<<(short __n);\n    basic_ostream& operator<<(unsigned short __n);\n    basic_ostream& operator<<(int __n);\n    basic_ostream& operator<<(unsigned int __n);\n    basic_ostream& operator<<(long __n);\n    basic_ostream& operator<<(unsigned long __n);\n    basic_ostream& operator<<(long long __n);\n    basic_ostream& operator<<(unsigned long long __n);\n    basic_ostream& operator<<(float __f);\n    basic_ostream& operator<<(double __f);\n    basic_ostream& operator<<(long double __f);\n    basic_ostream& operator<<(const void* __p);\n    basic_ostream& operator<<(basic_streambuf<char_type, traits_type>* __sb);\n\n    // 27.7.2.7 Unformatted output:\n    basic_ostream& put(char_type __c);\n    basic_ostream& write(const char_type* __s, streamsize __n);\n    basic_ostream& flush();\n\n    // 27.7.2.5 seeks:\n    pos_type tellp();\n    basic_ostream& seekp(pos_type __pos);\n    basic_ostream& seekp(off_type __off, ios_base::seekdir __dir);\n\nprotected:\n    _LIBCPP_ALWAYS_INLINE\n    basic_ostream() {}  // extension, intentially does not initialize\n};\n\ntemplate <class _CharT, class _Traits>\nclass _LIBCPP_TYPE_VIS_ONLY basic_ostream<_CharT, _Traits>::sentry\n{\n    bool __ok_;\n    basic_ostream<_CharT, _Traits>& __os_;\n\n    sentry(const sentry&); // = delete;\n    sentry& operator=(const sentry&); // = delete;\n\npublic:\n    explicit sentry(basic_ostream<_CharT, _Traits>& __os);\n    ~sentry();\n\n    _LIBCPP_ALWAYS_INLINE\n        _LIBCPP_EXPLICIT\n        operator bool() const {return __ok_;}\n};\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>::sentry::sentry(basic_ostream<_CharT, _Traits>& __os)\n    : __ok_(false),\n      __os_(__os)\n{\n    if (__os.good())\n    {\n        if (__os.tie())\n            __os.tie()->flush();\n        __ok_ = true;\n    }\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>::sentry::~sentry()\n{\n    if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf)\n                      && !uncaught_exception())\n    {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            if (__os_.rdbuf()->pubsync() == -1)\n                __os_.setstate(ios_base::badbit);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>::basic_ostream(basic_streambuf<char_type, traits_type>* __sb)\n{\n    this->init(__sb);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>::basic_ostream(basic_ostream&& __rhs)\n{\n    this->move(__rhs);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator=(basic_ostream&& __rhs)\n{\n    swap(__rhs);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>::~basic_ostream()\n{\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_ostream<_CharT, _Traits>::swap(basic_ostream& __rhs)\n{\n    basic_ios<char_type, traits_type>::swap(__rhs);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(basic_ostream& (*__pf)(basic_ostream&))\n{\n    return __pf(*this);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(basic_ios<char_type, traits_type>&\n                                           (*__pf)(basic_ios<char_type,traits_type>&))\n{\n    __pf(*this);\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(ios_base& (*__pf)(ios_base&))\n{\n    __pf(*this);\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_type>* __sb)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            if (__sb)\n            {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n                try\n                {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n                    typedef istreambuf_iterator<_CharT, _Traits> _Ip;\n                    typedef ostreambuf_iterator<_CharT, _Traits> _Op;\n                    _Ip __i(__sb);\n                    _Ip __eof;\n                    _Op __o(*this);\n                    size_t __c = 0;\n                    for (; __i != __eof; ++__i, ++__o, ++__c)\n                    {\n                        *__o = *__i;\n                        if (__o.failed())\n                            break;\n                    }\n                    if (__c == 0)\n                        this->setstate(ios_base::failbit);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n                }\n                catch (...)\n                {\n                    this->__set_failbit_and_consider_rethrow();\n                }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            }\n            else\n                this->setstate(ios_base::badbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(bool __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;\n            const _Fp& __f = use_facet<_Fp>(this->getloc());\n            if (__f.put(*this, *this, this->fill(), __n).failed())\n                this->setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(short __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            ios_base::fmtflags __flags = ios_base::flags() & ios_base::basefield;\n            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;\n            const _Fp& __f = use_facet<_Fp>(this->getloc());\n            if (__f.put(*this, *this, this->fill(),\n                        __flags == ios_base::oct || __flags == ios_base::hex ?\n                        static_cast<long>(static_cast<unsigned short>(__n))  :\n                        static_cast<long>(__n)).failed())\n                this->setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(unsigned short __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;\n            const _Fp& __f = use_facet<_Fp>(this->getloc());\n            if (__f.put(*this, *this, this->fill(), static_cast<unsigned long>(__n)).failed())\n                this->setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(int __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            ios_base::fmtflags __flags = ios_base::flags() & ios_base::basefield;\n            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;\n            const _Fp& __f = use_facet<_Fp>(this->getloc());\n            if (__f.put(*this, *this, this->fill(),\n                        __flags == ios_base::oct || __flags == ios_base::hex ?\n                        static_cast<long>(static_cast<unsigned int>(__n))  :\n                        static_cast<long>(__n)).failed())\n                this->setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(unsigned int __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;\n            const _Fp& __f = use_facet<_Fp>(this->getloc());\n            if (__f.put(*this, *this, this->fill(), static_cast<unsigned long>(__n)).failed())\n                this->setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(long __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;\n            const _Fp& __f = use_facet<_Fp>(this->getloc());\n            if (__f.put(*this, *this, this->fill(), __n).failed())\n                this->setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(unsigned long __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;\n            const _Fp& __f = use_facet<_Fp>(this->getloc());\n            if (__f.put(*this, *this, this->fill(), __n).failed())\n                this->setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(long long __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;\n            const _Fp& __f = use_facet<_Fp>(this->getloc());\n            if (__f.put(*this, *this, this->fill(), __n).failed())\n                this->setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;\n            const _Fp& __f = use_facet<_Fp>(this->getloc());\n            if (__f.put(*this, *this, this->fill(), __n).failed())\n                this->setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(float __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;\n            const _Fp& __f = use_facet<_Fp>(this->getloc());\n            if (__f.put(*this, *this, this->fill(), static_cast<double>(__n)).failed())\n                this->setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(double __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;\n            const _Fp& __f = use_facet<_Fp>(this->getloc());\n            if (__f.put(*this, *this, this->fill(), __n).failed())\n                this->setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(long double __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;\n            const _Fp& __f = use_facet<_Fp>(this->getloc());\n            if (__f.put(*this, *this, this->fill(), __n).failed())\n                this->setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::operator<<(const void* __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;\n            const _Fp& __f = use_facet<_Fp>(this->getloc());\n            if (__f.put(*this, *this, this->fill(), __n).failed())\n                this->setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\n__put_character_sequence(basic_ostream<_CharT, _Traits>& __os,\n                          const _CharT* __str, size_t __len)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typename basic_ostream<_CharT, _Traits>::sentry __s(__os);\n        if (__s)\n        {\n            typedef ostreambuf_iterator<_CharT, _Traits> _Ip;\n            if (__pad_and_output(_Ip(__os),\n                                 __str,\n                                 (__os.flags() & ios_base::adjustfield) == ios_base::left ?\n                                     __str + __len :\n                                     __str,\n                                 __str + __len,\n                                 __os,\n                                 __os.fill()).failed())\n                __os.setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __os.__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __os;\n}\n\n\ntemplate<class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, _CharT __c)\n{\n    return _VSTD::__put_character_sequence(__os, &__c, 1);\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, char __cn)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typename basic_ostream<_CharT, _Traits>::sentry __s(__os);\n        if (__s)\n        {\n            _CharT __c = __os.widen(__cn);\n            typedef ostreambuf_iterator<_CharT, _Traits> _Ip;\n            if (__pad_and_output(_Ip(__os),\n                                 &__c,\n                                 (__os.flags() & ios_base::adjustfield) == ios_base::left ?\n                                     &__c + 1 :\n                                     &__c,\n                                 &__c + 1,\n                                 __os,\n                                 __os.fill()).failed())\n                __os.setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __os.__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __os;\n}\n\ntemplate<class _Traits>\nbasic_ostream<char, _Traits>&\noperator<<(basic_ostream<char, _Traits>& __os, char __c)\n{\n    return _VSTD::__put_character_sequence(__os, &__c, 1);\n}\n\ntemplate<class _Traits>\nbasic_ostream<char, _Traits>&\noperator<<(basic_ostream<char, _Traits>& __os, signed char __c)\n{\n    return _VSTD::__put_character_sequence(__os, (char *) &__c, 1);\n}\n\ntemplate<class _Traits>\nbasic_ostream<char, _Traits>&\noperator<<(basic_ostream<char, _Traits>& __os, unsigned char __c)\n{\n    return _VSTD::__put_character_sequence(__os, (char *) &__c, 1);\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, const _CharT* __str)\n{\n    return _VSTD::__put_character_sequence(__os, __str, _Traits::length(__str));\n}\n\ntemplate<class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, const char* __strn)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        typename basic_ostream<_CharT, _Traits>::sentry __s(__os);\n        if (__s)\n        {\n            typedef ostreambuf_iterator<_CharT, _Traits> _Ip;\n            size_t __len = char_traits<char>::length(__strn);\n            const int __bs = 100;\n            _CharT __wbb[__bs];\n            _CharT* __wb = __wbb;\n            unique_ptr<_CharT, void(*)(void*)> __h(0, free);\n            if (__len > __bs)\n            {\n                __wb = (_CharT*)malloc(__len*sizeof(_CharT));\n                if (__wb == 0)\n                    __throw_bad_alloc();\n                __h.reset(__wb);\n            }\n            for (_CharT* __p = __wb; *__strn != '\\0'; ++__strn, ++__p)\n                *__p = __os.widen(*__strn);\n            if (__pad_and_output(_Ip(__os),\n                                 __wb,\n                                 (__os.flags() & ios_base::adjustfield) == ios_base::left ?\n                                     __wb + __len :\n                                     __wb,\n                                 __wb + __len,\n                                 __os,\n                                 __os.fill()).failed())\n                __os.setstate(ios_base::badbit | ios_base::failbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        __os.__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __os;\n}\n\ntemplate<class _Traits>\nbasic_ostream<char, _Traits>&\noperator<<(basic_ostream<char, _Traits>& __os, const char* __str)\n{\n    return _VSTD::__put_character_sequence(__os, __str, _Traits::length(__str));\n}\n\ntemplate<class _Traits>\nbasic_ostream<char, _Traits>&\noperator<<(basic_ostream<char, _Traits>& __os, const signed char* __str)\n{\n    const char *__s = (const char *) __str;\n    return _VSTD::__put_character_sequence(__os, __s, _Traits::length(__s));\n}\n\ntemplate<class _Traits>\nbasic_ostream<char, _Traits>&\noperator<<(basic_ostream<char, _Traits>& __os, const unsigned char* __str)\n{\n    const char *__s = (const char *) __str;\n    return _VSTD::__put_character_sequence(__os, __s, _Traits::length(__s));\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::put(char_type __c)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __s(*this);\n        if (__s)\n        {\n            typedef ostreambuf_iterator<_CharT, _Traits> _Op;\n            _Op __o(*this);\n            *__o = __c;\n            if (__o.failed())\n                this->setstate(ios_base::badbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::write(const char_type* __s, streamsize __n)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        sentry __sen(*this);\n        if (__sen && __n)\n        {\n            if (this->rdbuf()->sputn(__s, __n) != __n)\n                this->setstate(ios_base::badbit);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::flush()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        if (this->rdbuf())\n        {\n            sentry __s(*this);\n            if (__s)\n            {\n                if (this->rdbuf()->pubsync() == -1)\n                    this->setstate(ios_base::badbit);\n            }\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        this->__set_badbit_and_consider_rethrow();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_ostream<_CharT, _Traits>::pos_type\nbasic_ostream<_CharT, _Traits>::tellp()\n{\n    if (this->fail())\n        return pos_type(-1);\n    return this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::seekp(pos_type __pos)\n{\n    sentry __s(*this);\n    if (!this->fail())\n    {\n        if (this->rdbuf()->pubseekpos(__pos, ios_base::out) == pos_type(-1))\n            this->setstate(ios_base::failbit);\n    }\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\nbasic_ostream<_CharT, _Traits>::seekp(off_type __off, ios_base::seekdir __dir)\n{\n    sentry __s(*this);\n    if (!this->fail())\n    {\n        if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::out) == pos_type(-1))\n            this->setstate(ios_base::failbit);\n    }\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\nendl(basic_ostream<_CharT, _Traits>& __os)\n{\n    __os.put(__os.widen('\\n'));\n    __os.flush();\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\nends(basic_ostream<_CharT, _Traits>& __os)\n{\n    __os.put(_CharT());\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\nflush(basic_ostream<_CharT, _Traits>& __os)\n{\n    __os.flush();\n    return __os;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Stream, class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    !is_lvalue_reference<_Stream>::value &&\n    is_base_of<ios_base, _Stream>::value,\n    _Stream&&\n>::type\noperator<<(_Stream&& __os, const _Tp& __x)\n{\n    __os << __x;\n    return _VSTD::move(__os);\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const basic_string<_CharT, _Traits, _Allocator>& __str)\n{\n    return _VSTD::__put_character_sequence(__os, __str.data(), __str.size());\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __ec)\n{\n    return __os << __ec.category().name() << ':' << __ec.value();\n}\n\ntemplate<class _CharT, class _Traits, class _Yp>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p)\n{\n    return __os << __p.get();\n}\n\ntemplate <class _CharT, class _Traits, size_t _Size>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x)\n{\n    return __os << __x.template to_string<_CharT, _Traits>\n                        (use_facet<ctype<_CharT> >(__os.getloc()).widen('0'),\n                         use_facet<ctype<_CharT> >(__os.getloc()).widen('1'));\n}\n\n_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ostream<char>)\n_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ostream<wchar_t>)\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_OSTREAM\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/queue",
    "content": "// -*- C++ -*-\n//===--------------------------- queue ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_QUEUE\n#define _LIBCPP_QUEUE\n\n/*\n    queue synopsis\n\nnamespace std\n{\n\ntemplate <class T, class Container = deque<T>>\nclass queue\n{\npublic:\n    typedef Container                                container_type;\n    typedef typename container_type::value_type      value_type;\n    typedef typename container_type::reference       reference;\n    typedef typename container_type::const_reference const_reference;\n    typedef typename container_type::size_type       size_type;\n\nprotected:\n    container_type c;\n\npublic:\n    queue() = default;\n    ~queue() = default;\n\n    queue(const queue& q) = default;\n    queue(queue&& q) = default;\n\n    queue& operator=(const queue& q) = default;\n    queue& operator=(queue&& q) = default;\n\n    explicit queue(const container_type& c);\n    explicit queue(container_type&& c)\n    template <class Alloc>\n        explicit queue(const Alloc& a);\n    template <class Alloc>\n        queue(const container_type& c, const Alloc& a);\n    template <class Alloc>\n        queue(container_type&& c, const Alloc& a);\n    template <class Alloc>\n        queue(const queue& q, const Alloc& a);\n    template <class Alloc>\n        queue(queue&& q, const Alloc& a);\n\n    bool      empty() const;\n    size_type size() const;\n\n    reference       front();\n    const_reference front() const;\n    reference       back();\n    const_reference back() const;\n\n    void push(const value_type& v);\n    void push(value_type&& v);\n    template <class... Args> void emplace(Args&&... args);\n    void pop();\n\n    void swap(queue& q) noexcept(noexcept(swap(c, q.c)));\n};\n\ntemplate <class T, class Container>\n  bool operator==(const queue<T, Container>& x,const queue<T, Container>& y);\n\ntemplate <class T, class Container>\n  bool operator< (const queue<T, Container>& x,const queue<T, Container>& y);\n\ntemplate <class T, class Container>\n  bool operator!=(const queue<T, Container>& x,const queue<T, Container>& y);\n\ntemplate <class T, class Container>\n  bool operator> (const queue<T, Container>& x,const queue<T, Container>& y);\n\ntemplate <class T, class Container>\n  bool operator>=(const queue<T, Container>& x,const queue<T, Container>& y);\n\ntemplate <class T, class Container>\n  bool operator<=(const queue<T, Container>& x,const queue<T, Container>& y);\n\ntemplate <class T, class Container>\n  void swap(queue<T, Container>& x, queue<T, Container>& y)\n  noexcept(noexcept(x.swap(y)));\n\ntemplate <class T, class Container = vector<T>,\n          class Compare = less<typename Container::value_type>>\nclass priority_queue\n{\npublic:\n    typedef Container                                container_type;\n    typedef typename container_type::value_type      value_type;\n    typedef typename container_type::reference       reference;\n    typedef typename container_type::const_reference const_reference;\n    typedef typename container_type::size_type       size_type;\n\nprotected:\n    container_type c;\n    Compare comp;\n\npublic:\n    priority_queue() = default;\n    ~priority_queue() = default;\n\n    priority_queue(const priority_queue& q) = default;\n    priority_queue(priority_queue&& q) = default;\n\n    priority_queue& operator=(const priority_queue& q) = default;\n    priority_queue& operator=(priority_queue&& q) = default;\n\n    explicit priority_queue(const Compare& comp);\n    priority_queue(const Compare& comp, const container_type& c);\n    explicit priority_queue(const Compare& comp, container_type&& c);\n    template <class InputIterator>\n        priority_queue(InputIterator first, InputIterator last,\n                       const Compare& comp = Compare());\n    template <class InputIterator>\n        priority_queue(InputIterator first, InputIterator last,\n                       const Compare& comp, const container_type& c);\n    template <class InputIterator>\n        priority_queue(InputIterator first, InputIterator last,\n                       const Compare& comp, container_type&& c);\n    template <class Alloc>\n        explicit priority_queue(const Alloc& a);\n    template <class Alloc>\n        priority_queue(const Compare& comp, const Alloc& a);\n    template <class Alloc>\n        priority_queue(const Compare& comp, const container_type& c,\n                       const Alloc& a);\n    template <class Alloc>\n        priority_queue(const Compare& comp, container_type&& c,\n                       const Alloc& a);\n    template <class Alloc>\n        priority_queue(const priority_queue& q, const Alloc& a);\n    template <class Alloc>\n        priority_queue(priority_queue&& q, const Alloc& a);\n\n    bool            empty() const;\n    size_type       size() const;\n    const_reference top() const;\n\n    void push(const value_type& v);\n    void push(value_type&& v);\n    template <class... Args> void emplace(Args&&... args);\n    void pop();\n\n    void swap(priority_queue& q)\n        noexcept(noexcept(swap(c, q.c)) && noexcept(swap(comp.q.comp)));\n};\n\ntemplate <class T, class Container, class Compare>\n  void swap(priority_queue<T, Container, Compare>& x,\n            priority_queue<T, Container, Compare>& y)\n            noexcept(noexcept(x.swap(y)));\n\n}  // std\n\n*/\n\n#include <__config>\n#include <deque>\n#include <vector>\n#include <functional>\n#include <algorithm>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Tp, class _Container = deque<_Tp> > class _LIBCPP_TYPE_VIS_ONLY queue;\n\ntemplate <class _Tp, class _Container>\n_LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y);\n\ntemplate <class _Tp, class _Container>\n_LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y);\n\ntemplate <class _Tp, class _Container /*= deque<_Tp>*/>\nclass _LIBCPP_TYPE_VIS_ONLY queue\n{\npublic:\n    typedef _Container                               container_type;\n    typedef typename container_type::value_type      value_type;\n    typedef typename container_type::reference       reference;\n    typedef typename container_type::const_reference const_reference;\n    typedef typename container_type::size_type       size_type;\n\nprotected:\n    container_type c;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    queue()\n        _NOEXCEPT_(is_nothrow_default_constructible<container_type>::value)\n        : c() {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    queue(const queue& __q) : c(__q.c) {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    queue(queue&& __q)\n        _NOEXCEPT_(is_nothrow_move_constructible<container_type>::value)\n        : c(_VSTD::move(__q.c)) {}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    queue& operator=(const queue& __q) {c = __q.c; return *this;}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    queue& operator=(queue&& __q)\n        _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value)\n        {c = _VSTD::move(__q.c); return *this;}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit queue(const container_type& __c)  : c(__c) {}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    explicit queue(container_type&& __c) : c(_VSTD::move(__c)) {}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit queue(const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type* = 0)\n            : c(__a) {}\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        queue(const queue& __q, const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type* = 0)\n            : c(__q.c, __a) {}\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        queue(const container_type& __c, const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type* = 0)\n            : c(__c, __a) {}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        queue(container_type&& __c, const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type* = 0)\n            : c(_VSTD::move(__c), __a) {}\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        queue(queue&& __q, const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type* = 0)\n            : c(_VSTD::move(__q.c), __a) {}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool      empty() const {return c.empty();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const  {return c.size();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    reference       front()       {return c.front();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reference front() const {return c.front();}\n    _LIBCPP_INLINE_VISIBILITY\n    reference       back()        {return c.back();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reference back() const  {return c.back();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void push(const value_type& __v) {c.push_back(__v);}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void push(value_type&& __v)      {c.push_back(_VSTD::move(__v));}\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        void emplace(_Args&&... __args)\n            {c.emplace_back(_VSTD::forward<_Args>(__args)...);}\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void pop() {c.pop_front();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(queue& __q)\n        _NOEXCEPT_(__is_nothrow_swappable<container_type>::value)\n    {\n        using _VSTD::swap;\n        swap(c, __q.c);\n    }\n\n    template <class _T1, class _C1>\n    friend\n    _LIBCPP_INLINE_VISIBILITY\n    bool\n    operator==(const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y);\n\n    template <class _T1, class _C1>\n    friend\n    _LIBCPP_INLINE_VISIBILITY\n    bool\n    operator< (const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y);\n};\n\ntemplate <class _Tp, class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)\n{\n    return __x.c == __y.c;\n}\n\ntemplate <class _Tp, class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)\n{\n    return __x.c < __y.c;\n}\n\ntemplate <class _Tp, class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Tp, class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator> (const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _Tp, class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _Tp, class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _Tp, class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(queue<_Tp, _Container>& __x, queue<_Tp, _Container>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Tp, class _Container, class _Alloc>\nstruct _LIBCPP_TYPE_VIS_ONLY uses_allocator<queue<_Tp, _Container>, _Alloc>\n    : public uses_allocator<_Container, _Alloc>\n{\n};\n\ntemplate <class _Tp, class _Container = vector<_Tp>,\n          class _Compare = less<typename _Container::value_type> >\nclass _LIBCPP_TYPE_VIS_ONLY priority_queue\n{\npublic:\n    typedef _Container                               container_type;\n    typedef _Compare                                 value_compare;\n    typedef typename container_type::value_type      value_type;\n    typedef typename container_type::reference       reference;\n    typedef typename container_type::const_reference const_reference;\n    typedef typename container_type::size_type       size_type;\n\nprotected:\n    container_type c;\n    value_compare comp;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    priority_queue()\n        _NOEXCEPT_(is_nothrow_default_constructible<container_type>::value &&\n                   is_nothrow_default_constructible<value_compare>::value)\n        : c(), comp() {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    priority_queue(const priority_queue& __q) : c(__q.c), comp(__q.comp) {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    priority_queue(priority_queue&& __q)\n        _NOEXCEPT_(is_nothrow_move_constructible<container_type>::value &&\n                   is_nothrow_move_constructible<value_compare>::value)\n        : c(_VSTD::move(__q.c)), comp(_VSTD::move(__q.comp)) {}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    priority_queue& operator=(const priority_queue& __q)\n        {c = __q.c; comp = __q.comp; return *this;}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    priority_queue& operator=(priority_queue&& __q)\n        _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value &&\n                   is_nothrow_move_assignable<value_compare>::value)\n        {c = _VSTD::move(__q.c); comp = _VSTD::move(__q.comp); return *this;}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit priority_queue(const value_compare& __comp)\n        : c(), comp(__comp) {}\n    priority_queue(const value_compare& __comp, const container_type& __c);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    explicit priority_queue(const value_compare& __comp, container_type&& __c);\n#endif\n    template <class _InputIter>\n        priority_queue(_InputIter __f, _InputIter __l,\n                       const value_compare& __comp = value_compare());\n    template <class _InputIter>\n        priority_queue(_InputIter __f, _InputIter __l,\n                       const value_compare& __comp, const container_type& __c);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _InputIter>\n        priority_queue(_InputIter __f, _InputIter __l,\n                       const value_compare& __comp, container_type&& __c);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Alloc>\n        explicit priority_queue(const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type* = 0);\n    template <class _Alloc>\n        priority_queue(const value_compare& __comp, const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type* = 0);\n    template <class _Alloc>\n        priority_queue(const value_compare& __comp, const container_type& __c,\n                       const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type* = 0);\n    template <class _Alloc>\n        priority_queue(const priority_queue& __q, const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type* = 0);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Alloc>\n        priority_queue(const value_compare& __comp, container_type&& __c,\n                       const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type* = 0);\n    template <class _Alloc>\n        priority_queue(priority_queue&& __q, const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type* = 0);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool            empty() const {return c.empty();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type       size() const  {return c.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reference top() const   {return c.front();}\n\n    void push(const value_type& __v);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void push(value_type&& __v);\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class... _Args> void emplace(_Args&&... __args);\n#endif\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void pop();\n\n    void swap(priority_queue& __q)\n        _NOEXCEPT_(__is_nothrow_swappable<container_type>::value &&\n                   __is_nothrow_swappable<value_compare>::value);\n};\n\ntemplate <class _Tp, class _Container, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\npriority_queue<_Tp, _Container, _Compare>::priority_queue(const _Compare& __comp,\n                                                          const container_type& __c)\n    : c(__c),\n      comp(__comp)\n{\n    _VSTD::make_heap(c.begin(), c.end(), comp);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Container, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\npriority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,\n                                                          container_type&& __c)\n    : c(_VSTD::move(__c)),\n      comp(__comp)\n{\n    _VSTD::make_heap(c.begin(), c.end(), comp);\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Container, class _Compare>\ntemplate <class _InputIter>\ninline _LIBCPP_INLINE_VISIBILITY\npriority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l,\n                                                          const value_compare& __comp)\n    : c(__f, __l),\n      comp(__comp)\n{\n    _VSTD::make_heap(c.begin(), c.end(), comp);\n}\n\ntemplate <class _Tp, class _Container, class _Compare>\ntemplate <class _InputIter>\ninline _LIBCPP_INLINE_VISIBILITY\npriority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l,\n                                                          const value_compare& __comp,\n                                                          const container_type& __c)\n    : c(__c),\n      comp(__comp)\n{\n    c.insert(c.end(), __f, __l);\n    _VSTD::make_heap(c.begin(), c.end(), comp);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Container, class _Compare>\ntemplate <class _InputIter>\ninline _LIBCPP_INLINE_VISIBILITY\npriority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l,\n                                                          const value_compare& __comp,\n                                                          container_type&& __c)\n    : c(_VSTD::move(__c)),\n      comp(__comp)\n{\n    c.insert(c.end(), __f, __l);\n    _VSTD::make_heap(c.begin(), c.end(), comp);\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Container, class _Compare>\ntemplate <class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\npriority_queue<_Tp, _Container, _Compare>::priority_queue(const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type*)\n    : c(__a)\n{\n}\n\ntemplate <class _Tp, class _Container, class _Compare>\ntemplate <class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\npriority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,\n                                                          const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type*)\n    : c(__a),\n      comp(__comp)\n{\n}\n\ntemplate <class _Tp, class _Container, class _Compare>\ntemplate <class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\npriority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,\n                                                          const container_type& __c,\n                                                          const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type*)\n    : c(__c, __a),\n      comp(__comp)\n{\n    _VSTD::make_heap(c.begin(), c.end(), comp);\n}\n\ntemplate <class _Tp, class _Container, class _Compare>\ntemplate <class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\npriority_queue<_Tp, _Container, _Compare>::priority_queue(const priority_queue& __q,\n                                                          const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type*)\n    : c(__q.c, __a),\n      comp(__q.comp)\n{\n    _VSTD::make_heap(c.begin(), c.end(), comp);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Container, class _Compare>\ntemplate <class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\npriority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,\n                                                          container_type&& __c,\n                                                          const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type*)\n    : c(_VSTD::move(__c), __a),\n      comp(__comp)\n{\n    _VSTD::make_heap(c.begin(), c.end(), comp);\n}\n\ntemplate <class _Tp, class _Container, class _Compare>\ntemplate <class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\npriority_queue<_Tp, _Container, _Compare>::priority_queue(priority_queue&& __q,\n                                                          const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type*)\n    : c(_VSTD::move(__q.c), __a),\n      comp(_VSTD::move(__q.comp))\n{\n    _VSTD::make_heap(c.begin(), c.end(), comp);\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Container, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\npriority_queue<_Tp, _Container, _Compare>::push(const value_type& __v)\n{\n    c.push_back(__v);\n    _VSTD::push_heap(c.begin(), c.end(), comp);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Container, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\npriority_queue<_Tp, _Container, _Compare>::push(value_type&& __v)\n{\n    c.push_back(_VSTD::move(__v));\n    _VSTD::push_heap(c.begin(), c.end(), comp);\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Container, class _Compare>\ntemplate <class... _Args>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\npriority_queue<_Tp, _Container, _Compare>::emplace(_Args&&... __args)\n{\n    c.emplace_back(_VSTD::forward<_Args>(__args)...);\n    _VSTD::push_heap(c.begin(), c.end(), comp);\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Container, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\npriority_queue<_Tp, _Container, _Compare>::pop()\n{\n    _VSTD::pop_heap(c.begin(), c.end(), comp);\n    c.pop_back();\n}\n\ntemplate <class _Tp, class _Container, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\npriority_queue<_Tp, _Container, _Compare>::swap(priority_queue& __q)\n        _NOEXCEPT_(__is_nothrow_swappable<container_type>::value &&\n                   __is_nothrow_swappable<value_compare>::value)\n{\n    using _VSTD::swap;\n    swap(c, __q.c);\n    swap(comp, __q.comp);\n}\n\ntemplate <class _Tp, class _Container, class _Compare>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(priority_queue<_Tp, _Container, _Compare>& __x,\n     priority_queue<_Tp, _Container, _Compare>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Tp, class _Container, class _Compare, class _Alloc>\nstruct _LIBCPP_TYPE_VIS_ONLY uses_allocator<priority_queue<_Tp, _Container, _Compare>, _Alloc>\n    : public uses_allocator<_Container, _Alloc>\n{\n};\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_QUEUE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/random",
    "content": "// -*- C++ -*-\n//===--------------------------- random -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_RANDOM\n#define _LIBCPP_RANDOM\n\n/*\n    random synopsis\n\n#include <initializer_list>\n\nnamespace std\n{\n\n// Engines\n\ntemplate <class UIntType, UIntType a, UIntType c, UIntType m>\nclass linear_congruential_engine\n{\npublic:\n    // types\n    typedef UIntType result_type;\n\n    // engine characteristics\n    static constexpr result_type multiplier = a;\n    static constexpr result_type increment = c;\n    static constexpr result_type modulus = m;\n    static constexpr result_type min() { return c == 0u ? 1u: 0u;}\n    static constexpr result_type max() { return m - 1u;}\n    static constexpr result_type default_seed = 1u;\n\n    // constructors and seeding functions\n    explicit linear_congruential_engine(result_type s = default_seed);\n    template<class Sseq> explicit linear_congruential_engine(Sseq& q);\n    void seed(result_type s = default_seed);\n    template<class Sseq> void seed(Sseq& q);\n\n    // generating functions\n    result_type operator()();\n    void discard(unsigned long long z);\n};\n\ntemplate <class UIntType, UIntType a, UIntType c, UIntType m>\nbool\noperator==(const linear_congruential_engine<UIntType, a, c, m>& x,\n           const linear_congruential_engine<UIntType, a, c, m>& y);\n\ntemplate <class UIntType, UIntType a, UIntType c, UIntType m>\nbool\noperator!=(const linear_congruential_engine<UIntType, a, c, m>& x,\n           const linear_congruential_engine<UIntType, a, c, m>& y);\n\ntemplate <class charT, class traits,\n          class UIntType, UIntType a, UIntType c, UIntType m>\nbasic_ostream<charT, traits>&\noperator<<(basic_ostream<charT, traits>& os,\n           const linear_congruential_engine<UIntType, a, c, m>& x);\n\ntemplate <class charT, class traits,\n          class UIntType, UIntType a, UIntType c, UIntType m>\nbasic_istream<charT, traits>&\noperator>>(basic_istream<charT, traits>& is,\n           linear_congruential_engine<UIntType, a, c, m>& x);\n\ntemplate <class UIntType, size_t w, size_t n, size_t m, size_t r,\n          UIntType a, size_t u, UIntType d, size_t s,\n          UIntType b, size_t t, UIntType c, size_t l, UIntType f>\nclass mersenne_twister_engine\n{\npublic:\n    // types\n    typedef UIntType result_type;\n\n    // engine characteristics\n    static constexpr size_t word_size = w;\n    static constexpr size_t state_size = n;\n    static constexpr size_t shift_size = m;\n    static constexpr size_t mask_bits = r;\n    static constexpr result_type xor_mask = a;\n    static constexpr size_t tempering_u = u;\n    static constexpr result_type tempering_d = d;\n    static constexpr size_t tempering_s = s;\n    static constexpr result_type tempering_b = b;\n    static constexpr size_t tempering_t = t;\n    static constexpr result_type tempering_c = c;\n    static constexpr size_t tempering_l = l;\n    static constexpr result_type initialization_multiplier = f;\n    static constexpr result_type min () { return 0; }\n    static constexpr result_type max() { return 2^w - 1; }\n    static constexpr result_type default_seed = 5489u;\n\n    // constructors and seeding functions\n    explicit mersenne_twister_engine(result_type value = default_seed);\n    template<class Sseq> explicit mersenne_twister_engine(Sseq& q);\n    void seed(result_type value = default_seed);\n    template<class Sseq> void seed(Sseq& q);\n\n    // generating functions\n    result_type operator()();\n    void discard(unsigned long long z);\n};\n\ntemplate <class UIntType, size_t w, size_t n, size_t m, size_t r,\n          UIntType a, size_t u, UIntType d, size_t s,\n          UIntType b, size_t t, UIntType c, size_t l, UIntType f>\nbool\noperator==(\n    const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& x,\n    const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& y);\n\ntemplate <class UIntType, size_t w, size_t n, size_t m, size_t r,\n          UIntType a, size_t u, UIntType d, size_t s,\n          UIntType b, size_t t, UIntType c, size_t l, UIntType f>\nbool\noperator!=(\n    const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& x,\n    const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& y);\n\ntemplate <class charT, class traits,\n          class UIntType, size_t w, size_t n, size_t m, size_t r,\n          UIntType a, size_t u, UIntType d, size_t s,\n          UIntType b, size_t t, UIntType c, size_t l, UIntType f>\nbasic_ostream<charT, traits>&\noperator<<(basic_ostream<charT, traits>& os,\n           const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& x);\n\ntemplate <class charT, class traits,\n          class UIntType, size_t w, size_t n, size_t m, size_t r,\n          UIntType a, size_t u, UIntType d, size_t s,\n          UIntType b, size_t t, UIntType c, size_t l, UIntType f>\nbasic_istream<charT, traits>&\noperator>>(basic_istream<charT, traits>& is,\n           mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& x);\n\ntemplate<class UIntType, size_t w, size_t s, size_t r>\nclass subtract_with_carry_engine\n{\npublic:\n    // types\n    typedef UIntType result_type;\n\n    // engine characteristics\n    static constexpr size_t word_size = w;\n    static constexpr size_t short_lag = s;\n    static constexpr size_t long_lag = r;\n    static constexpr result_type min() { return 0; }\n    static constexpr result_type max() { return m-1; }\n    static constexpr result_type default_seed = 19780503u;\n\n    // constructors and seeding functions\n    explicit subtract_with_carry_engine(result_type value = default_seed);\n    template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);\n    void seed(result_type value = default_seed);\n    template<class Sseq> void seed(Sseq& q);\n\n    // generating functions\n    result_type operator()();\n    void discard(unsigned long long z);\n};\n\ntemplate<class UIntType, size_t w, size_t s, size_t r>\nbool\noperator==(\n    const subtract_with_carry_engine<UIntType, w, s, r>& x,\n    const subtract_with_carry_engine<UIntType, w, s, r>& y);\n\ntemplate<class UIntType, size_t w, size_t s, size_t r>\nbool\noperator!=(\n    const subtract_with_carry_engine<UIntType, w, s, r>& x,\n    const subtract_with_carry_engine<UIntType, w, s, r>& y);\n\ntemplate <class charT, class traits,\n          class UIntType, size_t w, size_t s, size_t r>\nbasic_ostream<charT, traits>&\noperator<<(basic_ostream<charT, traits>& os,\n           const subtract_with_carry_engine<UIntType, w, s, r>& x);\n\ntemplate <class charT, class traits,\n          class UIntType, size_t w, size_t s, size_t r>\nbasic_istream<charT, traits>&\noperator>>(basic_istream<charT, traits>& is,\n           subtract_with_carry_engine<UIntType, w, s, r>& x);\n\ntemplate<class Engine, size_t p, size_t r>\nclass discard_block_engine\n{\npublic:\n    // types\n    typedef typename Engine::result_type result_type;\n\n    // engine characteristics\n    static constexpr size_t block_size = p;\n    static constexpr size_t used_block = r;\n    static constexpr result_type min() { return Engine::min(); }\n    static constexpr result_type max() { return Engine::max(); }\n\n    // constructors and seeding functions\n    discard_block_engine();\n    explicit discard_block_engine(const Engine& e);\n    explicit discard_block_engine(Engine&& e);\n    explicit discard_block_engine(result_type s);\n    template<class Sseq> explicit discard_block_engine(Sseq& q);\n    void seed();\n    void seed(result_type s);\n    template<class Sseq> void seed(Sseq& q);\n\n    // generating functions\n    result_type operator()();\n    void discard(unsigned long long z);\n\n    // property functions\n    const Engine& base() const noexcept;\n};\n\ntemplate<class Engine, size_t p, size_t r>\nbool\noperator==(\n    const discard_block_engine<Engine, p, r>& x,\n    const discard_block_engine<Engine, p, r>& y);\n\ntemplate<class Engine, size_t p, size_t r>\nbool\noperator!=(\n    const discard_block_engine<Engine, p, r>& x,\n    const discard_block_engine<Engine, p, r>& y);\n\ntemplate <class charT, class traits,\n          class Engine, size_t p, size_t r>\nbasic_ostream<charT, traits>&\noperator<<(basic_ostream<charT, traits>& os,\n           const discard_block_engine<Engine, p, r>& x);\n\ntemplate <class charT, class traits,\n          class Engine, size_t p, size_t r>\nbasic_istream<charT, traits>&\noperator>>(basic_istream<charT, traits>& is,\n           discard_block_engine<Engine, p, r>& x);\n\ntemplate<class Engine, size_t w, class UIntType>\nclass independent_bits_engine\n{\npublic:\n    // types\n    typedef UIntType result_type;\n\n    // engine characteristics\n    static constexpr result_type min() { return 0; }\n    static constexpr result_type max() { return 2^w - 1; }\n\n    // constructors and seeding functions\n    independent_bits_engine();\n    explicit independent_bits_engine(const Engine& e);\n    explicit independent_bits_engine(Engine&& e);\n    explicit independent_bits_engine(result_type s);\n    template<class Sseq> explicit independent_bits_engine(Sseq& q);\n    void seed();\n    void seed(result_type s);\n    template<class Sseq> void seed(Sseq& q);\n\n    // generating functions\n    result_type operator()(); void discard(unsigned long long z);\n\n    // property functions\n    const Engine& base() const noexcept;\n};\n\ntemplate<class Engine, size_t w, class UIntType>\nbool\noperator==(\n    const independent_bits_engine<Engine, w, UIntType>& x,\n    const independent_bits_engine<Engine, w, UIntType>& y);\n\ntemplate<class Engine, size_t w, class UIntType>\nbool\noperator!=(\n    const independent_bits_engine<Engine, w, UIntType>& x,\n    const independent_bits_engine<Engine, w, UIntType>& y);\n\ntemplate <class charT, class traits,\n          class Engine, size_t w, class UIntType>\nbasic_ostream<charT, traits>&\noperator<<(basic_ostream<charT, traits>& os,\n           const independent_bits_engine<Engine, w, UIntType>& x);\n\ntemplate <class charT, class traits,\n          class Engine, size_t w, class UIntType>\nbasic_istream<charT, traits>&\noperator>>(basic_istream<charT, traits>& is,\n           independent_bits_engine<Engine, w, UIntType>& x);\n\ntemplate<class Engine, size_t k>\nclass shuffle_order_engine\n{\npublic:\n    // types\n    typedef typename Engine::result_type result_type;\n\n    // engine characteristics\n    static constexpr size_t table_size = k;\n    static constexpr result_type min() { return Engine::min; }\n    static constexpr result_type max() { return Engine::max; }\n\n    // constructors and seeding functions\n    shuffle_order_engine();\n    explicit shuffle_order_engine(const Engine& e);\n    explicit shuffle_order_engine(Engine&& e);\n    explicit shuffle_order_engine(result_type s);\n    template<class Sseq> explicit shuffle_order_engine(Sseq& q);\n    void seed();\n    void seed(result_type s);\n    template<class Sseq> void seed(Sseq& q);\n\n    // generating functions\n    result_type operator()();\n    void discard(unsigned long long z);\n\n    // property functions\n    const Engine& base() const noexcept;\n};\n\ntemplate<class Engine, size_t k>\nbool\noperator==(\n    const shuffle_order_engine<Engine, k>& x,\n    const shuffle_order_engine<Engine, k>& y);\n\ntemplate<class Engine, size_t k>\nbool\noperator!=(\n    const shuffle_order_engine<Engine, k>& x,\n    const shuffle_order_engine<Engine, k>& y);\n\ntemplate <class charT, class traits,\n          class Engine, size_t k>\nbasic_ostream<charT, traits>&\noperator<<(basic_ostream<charT, traits>& os,\n           const shuffle_order_engine<Engine, k>& x);\n\ntemplate <class charT, class traits,\n          class Engine, size_t k>\nbasic_istream<charT, traits>&\noperator>>(basic_istream<charT, traits>& is,\n           shuffle_order_engine<Engine, k>& x);\n\ntypedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>\n                                                                   minstd_rand0;\ntypedef linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647>\n                                                                    minstd_rand;\ntypedef mersenne_twister_engine<uint_fast32_t, 32, 624, 397, 31,\n                                0x9908b0df,\n                                11, 0xffffffff,\n                                7,  0x9d2c5680,\n                                15, 0xefc60000,\n                                18, 1812433253>                         mt19937;\ntypedef mersenne_twister_engine<uint_fast64_t, 64, 312, 156, 31,\n                                0xb5026f5aa96619e9,\n                                29, 0x5555555555555555,\n                                17, 0x71d67fffeda60000,\n                                37, 0xfff7eee000000000,\n                                43, 6364136223846793005>             mt19937_64;\ntypedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>     ranlux24_base;\ntypedef subtract_with_carry_engine<uint_fast64_t, 48,  5, 12>     ranlux48_base;\ntypedef discard_block_engine<ranlux24_base, 223, 23>                   ranlux24;\ntypedef discard_block_engine<ranlux48_base, 389, 11>                   ranlux48;\ntypedef shuffle_order_engine<minstd_rand0, 256>                         knuth_b;\ntypedef minstd_rand                                       default_random_engine;\n\n// Generators\n\nclass random_device\n{\npublic:\n    // types\n    typedef unsigned int result_type;\n\n    // generator characteristics\n    static constexpr result_type min() { return numeric_limits<result_type>::min(); }\n    static constexpr result_type max() { return numeric_limits<result_type>::max(); }\n\n    // constructors\n    explicit random_device(const string& token = \"/dev/urandom\");\n\n    // generating functions\n    result_type operator()();\n\n    // property functions\n    double entropy() const noexcept;\n\n    // no copy functions\n    random_device(const random_device& ) = delete;\n    void operator=(const random_device& ) = delete;\n};\n\n// Utilities\n\nclass seed_seq\n{\npublic:\n    // types\n    typedef uint_least32_t result_type;\n\n    // constructors\n    seed_seq();\n    template<class T>\n        seed_seq(initializer_list<T> il);\n    template<class InputIterator>\n        seed_seq(InputIterator begin, InputIterator end);\n\n    // generating functions\n    template<class RandomAccessIterator>\n        void generate(RandomAccessIterator begin, RandomAccessIterator end);\n\n    // property functions\n    size_t size() const;\n    template<class OutputIterator>\n        void param(OutputIterator dest) const;\n\n    // no copy functions\n    seed_seq(const seed_seq&) = delete;\n    void operator=(const seed_seq& ) = delete;\n};\n\ntemplate<class RealType, size_t bits, class URNG>\n    RealType generate_canonical(URNG& g);\n\n// Distributions\n\ntemplate<class IntType = int>\nclass uniform_int_distribution\n{\npublic:\n    // types\n    typedef IntType result_type;\n\n    class param_type\n    {\n    public:\n        typedef uniform_int_distribution distribution_type;\n\n        explicit param_type(IntType a = 0,\n                                    IntType b = numeric_limits<IntType>::max());\n\n        result_type a() const;\n        result_type b() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructors and reset functions\n    explicit uniform_int_distribution(IntType a = 0,\n                                    IntType b = numeric_limits<IntType>::max());\n    explicit uniform_int_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    result_type a() const;\n    result_type b() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const uniform_int_distribution& x,\n                           const uniform_int_distribution& y);\n    friend bool operator!=(const uniform_int_distribution& x,\n                           const uniform_int_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const uniform_int_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               uniform_int_distribution& x);\n};\n\ntemplate<class RealType = double>\nclass uniform_real_distribution\n{\npublic:\n    // types\n    typedef RealType result_type;\n\n    class param_type\n    {\n    public:\n        typedef uniform_real_distribution distribution_type;\n\n        explicit param_type(RealType a = 0,\n                            RealType b = 1);\n\n        result_type a() const;\n        result_type b() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructors and reset functions\n    explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0);\n    explicit uniform_real_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    result_type a() const;\n    result_type b() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const uniform_real_distribution& x,\n                           const uniform_real_distribution& y);\n    friend bool operator!=(const uniform_real_distribution& x,\n                           const uniform_real_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const uniform_real_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               uniform_real_distribution& x);\n};\n\nclass bernoulli_distribution\n{\npublic:\n    // types\n    typedef bool result_type;\n\n    class param_type\n    {\n    public:\n        typedef bernoulli_distribution distribution_type;\n\n        explicit param_type(double p = 0.5);\n\n        double p() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructors and reset functions\n    explicit bernoulli_distribution(double p = 0.5);\n    explicit bernoulli_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    double p() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const bernoulli_distribution& x,\n                           const bernoulli_distribution& y);\n    friend bool operator!=(const bernoulli_distribution& x,\n                           const bernoulli_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const bernoulli_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               bernoulli_distribution& x);\n};\n\ntemplate<class IntType = int>\nclass binomial_distribution\n{\npublic:\n    // types\n    typedef IntType result_type;\n\n    class param_type\n    {\n    public:\n        typedef binomial_distribution distribution_type;\n\n        explicit param_type(IntType t = 1, double p = 0.5);\n\n        IntType t() const;\n        double p() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructors and reset functions\n    explicit binomial_distribution(IntType t = 1, double p = 0.5);\n    explicit binomial_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    IntType t() const;\n    double p() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const binomial_distribution& x,\n                           const binomial_distribution& y);\n    friend bool operator!=(const binomial_distribution& x,\n                           const binomial_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const binomial_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               binomial_distribution& x);\n};\n\ntemplate<class IntType = int>\nclass geometric_distribution\n{\npublic:\n    // types\n    typedef IntType result_type;\n\n    class param_type\n    {\n    public:\n        typedef geometric_distribution distribution_type;\n\n        explicit param_type(double p = 0.5);\n\n        double p() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructors and reset functions\n    explicit geometric_distribution(double p = 0.5);\n    explicit geometric_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    double p() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const geometric_distribution& x,\n                           const geometric_distribution& y);\n    friend bool operator!=(const geometric_distribution& x,\n                           const geometric_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const geometric_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               geometric_distribution& x);\n};\n\ntemplate<class IntType = int>\nclass negative_binomial_distribution\n{\npublic:\n    // types\n    typedef IntType result_type;\n\n    class param_type\n    {\n    public:\n        typedef negative_binomial_distribution distribution_type;\n\n        explicit param_type(result_type k = 1, double p = 0.5);\n\n        result_type k() const;\n        double p() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructor and reset functions\n    explicit negative_binomial_distribution(result_type k = 1, double p = 0.5);\n    explicit negative_binomial_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    result_type k() const;\n    double p() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const negative_binomial_distribution& x,\n                           const negative_binomial_distribution& y);\n    friend bool operator!=(const negative_binomial_distribution& x,\n                           const negative_binomial_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const negative_binomial_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               negative_binomial_distribution& x);\n};\n\ntemplate<class IntType = int>\nclass poisson_distribution\n{\npublic:\n    // types\n    typedef IntType result_type;\n\n    class param_type\n    {\n    public:\n        typedef poisson_distribution distribution_type;\n\n        explicit param_type(double mean = 1.0);\n\n        double mean() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructors and reset functions\n    explicit poisson_distribution(double mean = 1.0);\n    explicit poisson_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    double mean() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const poisson_distribution& x,\n                           const poisson_distribution& y);\n    friend bool operator!=(const poisson_distribution& x,\n                           const poisson_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const poisson_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               poisson_distribution& x);\n};\n\ntemplate<class RealType = double>\nclass exponential_distribution\n{\npublic:\n    // types\n    typedef RealType result_type;\n\n    class param_type\n    {\n    public:\n        typedef exponential_distribution distribution_type;\n\n        explicit param_type(result_type lambda = 1.0);\n\n        result_type lambda() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructors and reset functions\n    explicit exponential_distribution(result_type lambda = 1.0);\n    explicit exponential_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    result_type lambda() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const exponential_distribution& x,\n                           const exponential_distribution& y);\n    friend bool operator!=(const exponential_distribution& x,\n                           const exponential_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const exponential_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               exponential_distribution& x);\n};\n\ntemplate<class RealType = double>\nclass gamma_distribution\n{\npublic:\n    // types\n    typedef RealType result_type;\n\n    class param_type\n    {\n    public:\n        typedef gamma_distribution distribution_type;\n\n        explicit param_type(result_type alpha = 1, result_type beta = 1);\n\n        result_type alpha() const;\n        result_type beta() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructors and reset functions\n    explicit gamma_distribution(result_type alpha = 1, result_type beta = 1);\n    explicit gamma_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    result_type alpha() const;\n    result_type beta() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const gamma_distribution& x,\n                           const gamma_distribution& y);\n    friend bool operator!=(const gamma_distribution& x,\n                           const gamma_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const gamma_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               gamma_distribution& x);\n};\n\ntemplate<class RealType = double>\nclass weibull_distribution\n{\npublic:\n    // types\n    typedef RealType result_type;\n\n    class param_type\n    {\n    public:\n        typedef weibull_distribution distribution_type;\n\n        explicit param_type(result_type alpha = 1, result_type beta = 1);\n\n        result_type a() const;\n        result_type b() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructor and reset functions\n    explicit weibull_distribution(result_type a = 1, result_type b = 1);\n    explicit weibull_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    result_type a() const;\n    result_type b() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const weibull_distribution& x,\n                           const weibull_distribution& y);\n    friend bool operator!=(const weibull_distribution& x,\n                           const weibull_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const weibull_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               weibull_distribution& x);\n};\n\ntemplate<class RealType = double>\nclass extreme_value_distribution\n{\npublic:\n    // types\n    typedef RealType result_type;\n\n    class param_type\n    {\n    public:\n        typedef extreme_value_distribution distribution_type;\n\n        explicit param_type(result_type a = 0, result_type b = 1);\n\n        result_type a() const;\n        result_type b() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructor and reset functions\n    explicit extreme_value_distribution(result_type a = 0, result_type b = 1);\n    explicit extreme_value_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    result_type a() const;\n    result_type b() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const extreme_value_distribution& x,\n                           const extreme_value_distribution& y);\n    friend bool operator!=(const extreme_value_distribution& x,\n                           const extreme_value_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const extreme_value_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               extreme_value_distribution& x);\n};\n\ntemplate<class RealType = double>\nclass normal_distribution\n{\npublic:\n    // types\n    typedef RealType result_type;\n\n    class param_type\n    {\n    public:\n        typedef normal_distribution distribution_type;\n\n        explicit param_type(result_type mean = 0, result_type stddev = 1);\n\n        result_type mean() const;\n        result_type stddev() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructors and reset functions\n    explicit normal_distribution(result_type mean = 0, result_type stddev = 1);\n    explicit normal_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    result_type mean() const;\n    result_type stddev() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const normal_distribution& x,\n                           const normal_distribution& y);\n    friend bool operator!=(const normal_distribution& x,\n                           const normal_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const normal_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               normal_distribution& x);\n};\n\ntemplate<class RealType = double>\nclass lognormal_distribution\n{\npublic:\n    // types\n    typedef RealType result_type;\n\n    class param_type\n    {\n    public:\n        typedef lognormal_distribution distribution_type;\n\n        explicit param_type(result_type m = 0, result_type s = 1);\n\n        result_type m() const;\n        result_type s() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructor and reset functions\n    explicit lognormal_distribution(result_type m = 0, result_type s = 1);\n    explicit lognormal_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    result_type m() const;\n    result_type s() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const lognormal_distribution& x,\n                           const lognormal_distribution& y);\n    friend bool operator!=(const lognormal_distribution& x,\n                           const lognormal_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const lognormal_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               lognormal_distribution& x);\n};\n\ntemplate<class RealType = double>\nclass chi_squared_distribution\n{\npublic:\n    // types\n    typedef RealType result_type;\n\n    class param_type\n    {\n    public:\n        typedef chi_squared_distribution distribution_type;\n\n        explicit param_type(result_type n = 1);\n\n        result_type n() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructor and reset functions\n    explicit chi_squared_distribution(result_type n = 1);\n    explicit chi_squared_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    result_type n() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const chi_squared_distribution& x,\n                           const chi_squared_distribution& y);\n    friend bool operator!=(const chi_squared_distribution& x,\n                           const chi_squared_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const chi_squared_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               chi_squared_distribution& x);\n};\n\ntemplate<class RealType = double>\nclass cauchy_distribution\n{\npublic:\n    // types\n    typedef RealType result_type;\n\n    class param_type\n    {\n    public:\n        typedef cauchy_distribution distribution_type;\n\n        explicit param_type(result_type a = 0, result_type b = 1);\n\n        result_type a() const;\n        result_type b() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructor and reset functions\n    explicit cauchy_distribution(result_type a = 0, result_type b = 1);\n    explicit cauchy_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    result_type a() const;\n    result_type b() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const cauchy_distribution& x,\n                           const cauchy_distribution& y);\n    friend bool operator!=(const cauchy_distribution& x,\n                           const cauchy_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const cauchy_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               cauchy_distribution& x);\n};\n\ntemplate<class RealType = double>\nclass fisher_f_distribution\n{\npublic:\n    // types\n    typedef RealType result_type;\n\n    class param_type\n    {\n    public:\n        typedef fisher_f_distribution distribution_type;\n\n        explicit param_type(result_type m = 1, result_type n = 1);\n\n        result_type m() const;\n        result_type n() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructor and reset functions\n    explicit fisher_f_distribution(result_type m = 1, result_type n = 1);\n    explicit fisher_f_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    result_type m() const;\n    result_type n() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const fisher_f_distribution& x,\n                           const fisher_f_distribution& y);\n    friend bool operator!=(const fisher_f_distribution& x,\n                           const fisher_f_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const fisher_f_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               fisher_f_distribution& x);\n};\n\ntemplate<class RealType = double>\nclass student_t_distribution\n{\npublic:\n    // types\n    typedef RealType result_type;\n\n    class param_type\n    {\n    public:\n        typedef student_t_distribution distribution_type;\n\n        explicit param_type(result_type n = 1);\n\n        result_type n() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructor and reset functions\n    explicit student_t_distribution(result_type n = 1);\n    explicit student_t_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    result_type n() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const student_t_distribution& x,\n                           const student_t_distribution& y);\n    friend bool operator!=(const student_t_distribution& x,\n                           const student_t_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const student_t_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               student_t_distribution& x);\n};\n\ntemplate<class IntType = int>\nclass discrete_distribution\n{\npublic:\n    // types\n    typedef IntType result_type;\n\n    class param_type\n    {\n    public:\n        typedef discrete_distribution distribution_type;\n\n        param_type();\n        template<class InputIterator>\n            param_type(InputIterator firstW, InputIterator lastW);\n        param_type(initializer_list<double> wl);\n        template<class UnaryOperation>\n            param_type(size_t nw, double xmin, double xmax, UnaryOperation fw);\n\n        vector<double> probabilities() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructor and reset functions\n    discrete_distribution();\n    template<class InputIterator>\n        discrete_distribution(InputIterator firstW, InputIterator lastW);\n    discrete_distribution(initializer_list<double> wl);\n    template<class UnaryOperation>\n        discrete_distribution(size_t nw, double xmin, double xmax,\n                              UnaryOperation fw);\n    explicit discrete_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    vector<double> probabilities() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const discrete_distribution& x,\n                           const discrete_distribution& y);\n    friend bool operator!=(const discrete_distribution& x,\n                           const discrete_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const discrete_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               discrete_distribution& x);\n};\n\ntemplate<class RealType = double>\nclass piecewise_constant_distribution\n{\n    // types\n    typedef RealType result_type;\n\n    class param_type\n    {\n    public:\n        typedef piecewise_constant_distribution distribution_type;\n\n        param_type();\n        template<class InputIteratorB, class InputIteratorW>\n            param_type(InputIteratorB firstB, InputIteratorB lastB,\n                       InputIteratorW firstW);\n        template<class UnaryOperation>\n            param_type(initializer_list<result_type> bl, UnaryOperation fw);\n        template<class UnaryOperation>\n            param_type(size_t nw, result_type xmin, result_type xmax,\n                       UnaryOperation fw);\n\n        vector<result_type> intervals() const;\n        vector<result_type> densities() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructor and reset functions\n    piecewise_constant_distribution();\n    template<class InputIteratorB, class InputIteratorW>\n        piecewise_constant_distribution(InputIteratorB firstB,\n                                        InputIteratorB lastB,\n                                        InputIteratorW firstW);\n    template<class UnaryOperation>\n        piecewise_constant_distribution(initializer_list<result_type> bl,\n                                        UnaryOperation fw);\n    template<class UnaryOperation>\n        piecewise_constant_distribution(size_t nw, result_type xmin,\n                                        result_type xmax, UnaryOperation fw);\n    explicit piecewise_constant_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    vector<result_type> intervals() const;\n    vector<result_type> densities() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const piecewise_constant_distribution& x,\n                           const piecewise_constant_distribution& y);\n    friend bool operator!=(const piecewise_constant_distribution& x,\n                           const piecewise_constant_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const piecewise_constant_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               piecewise_constant_distribution& x);\n};\n\ntemplate<class RealType = double>\nclass piecewise_linear_distribution\n{\n    // types\n    typedef RealType result_type;\n\n    class param_type\n    {\n    public:\n        typedef piecewise_linear_distribution distribution_type;\n\n        param_type();\n        template<class InputIteratorB, class InputIteratorW>\n            param_type(InputIteratorB firstB, InputIteratorB lastB,\n                       InputIteratorW firstW);\n        template<class UnaryOperation>\n            param_type(initializer_list<result_type> bl, UnaryOperation fw);\n        template<class UnaryOperation>\n            param_type(size_t nw, result_type xmin, result_type xmax,\n                       UnaryOperation fw);\n\n        vector<result_type> intervals() const;\n        vector<result_type> densities() const;\n\n        friend bool operator==(const param_type& x, const param_type& y);\n        friend bool operator!=(const param_type& x, const param_type& y);\n    };\n\n    // constructor and reset functions\n    piecewise_linear_distribution();\n    template<class InputIteratorB, class InputIteratorW>\n        piecewise_linear_distribution(InputIteratorB firstB,\n                                      InputIteratorB lastB,\n                                      InputIteratorW firstW);\n\n    template<class UnaryOperation>\n        piecewise_linear_distribution(initializer_list<result_type> bl,\n                                      UnaryOperation fw);\n\n    template<class UnaryOperation>\n        piecewise_linear_distribution(size_t nw, result_type xmin,\n                                      result_type xmax, UnaryOperation fw);\n\n    explicit piecewise_linear_distribution(const param_type& parm);\n    void reset();\n\n    // generating functions\n    template<class URNG> result_type operator()(URNG& g);\n    template<class URNG> result_type operator()(URNG& g, const param_type& parm);\n\n    // property functions\n    vector<result_type> intervals() const;\n    vector<result_type> densities() const;\n\n    param_type param() const;\n    void param(const param_type& parm);\n\n    result_type min() const;\n    result_type max() const;\n\n    friend bool operator==(const piecewise_linear_distribution& x,\n                           const piecewise_linear_distribution& y);\n    friend bool operator!=(const piecewise_linear_distribution& x,\n                           const piecewise_linear_distribution& y);\n\n    template <class charT, class traits>\n    friend\n    basic_ostream<charT, traits>&\n    operator<<(basic_ostream<charT, traits>& os,\n               const piecewise_linear_distribution& x);\n\n    template <class charT, class traits>\n    friend\n    basic_istream<charT, traits>&\n    operator>>(basic_istream<charT, traits>& is,\n               piecewise_linear_distribution& x);\n};\n\n} // std\n*/\n\n#include <__config>\n#include <cstddef>\n#include <cstdint>\n#include <cmath>\n#include <type_traits>\n#include <initializer_list>\n#include <limits>\n#include <algorithm>\n#include <numeric>\n#include <vector>\n#include <string>\n#include <istream>\n#include <ostream>\n\n#include <__undef_min_max>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n// __is_seed_sequence\n\ntemplate <class _Sseq, class _Engine>\nstruct __is_seed_sequence\n{\n    static _LIBCPP_CONSTEXPR const bool value =\n              !is_convertible<_Sseq, typename _Engine::result_type>::value &&\n              !is_same<typename remove_cv<_Sseq>::type, _Engine>::value;\n};\n\n// linear_congruential_engine\n\ntemplate <unsigned long long __a, unsigned long long __c,\n          unsigned long long __m, unsigned long long _Mp,\n          bool _MightOverflow = (__a != 0 && __m != 0 && __m-1 > (_Mp-__c)/__a)>\nstruct __lce_ta;\n\n// 64\n\ntemplate <unsigned long long __a, unsigned long long __c, unsigned long long __m>\nstruct __lce_ta<__a, __c, __m, (unsigned long long)(~0), true>\n{\n    typedef unsigned long long result_type;\n    _LIBCPP_INLINE_VISIBILITY\n    static result_type next(result_type __x)\n    {\n        // Schrage's algorithm\n        const result_type __q = __m / __a;\n        const result_type __r = __m % __a;\n        const result_type __t0 = __a * (__x % __q);\n        const result_type __t1 = __r * (__x / __q);\n        __x = __t0 + (__t0 < __t1) * __m - __t1;\n        __x += __c - (__x >= __m - __c) * __m;\n        return __x;\n    }\n};\n\ntemplate <unsigned long long __a, unsigned long long __m>\nstruct __lce_ta<__a, 0, __m, (unsigned long long)(~0), true>\n{\n    typedef unsigned long long result_type;\n    _LIBCPP_INLINE_VISIBILITY\n    static result_type next(result_type __x)\n    {\n        // Schrage's algorithm\n        const result_type __q = __m / __a;\n        const result_type __r = __m % __a;\n        const result_type __t0 = __a * (__x % __q);\n        const result_type __t1 = __r * (__x / __q);\n        __x = __t0 + (__t0 < __t1) * __m - __t1;\n        return __x;\n    }\n};\n\ntemplate <unsigned long long __a, unsigned long long __c, unsigned long long __m>\nstruct __lce_ta<__a, __c, __m, (unsigned long long)(~0), false>\n{\n    typedef unsigned long long result_type;\n    _LIBCPP_INLINE_VISIBILITY\n    static result_type next(result_type __x)\n    {\n        return (__a * __x + __c) % __m;\n    }\n};\n\ntemplate <unsigned long long __a, unsigned long long __c>\nstruct __lce_ta<__a, __c, 0, (unsigned long long)(~0), false>\n{\n    typedef unsigned long long result_type;\n    _LIBCPP_INLINE_VISIBILITY\n    static result_type next(result_type __x)\n    {\n        return __a * __x + __c;\n    }\n};\n\n// 32\n\ntemplate <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp>\nstruct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), true>\n{\n    typedef unsigned result_type;\n    _LIBCPP_INLINE_VISIBILITY\n    static result_type next(result_type __x)\n    {\n        const result_type __a = static_cast<result_type>(_Ap);\n        const result_type __c = static_cast<result_type>(_Cp);\n        const result_type __m = static_cast<result_type>(_Mp);\n        // Schrage's algorithm\n        const result_type __q = __m / __a;\n        const result_type __r = __m % __a;\n        const result_type __t0 = __a * (__x % __q);\n        const result_type __t1 = __r * (__x / __q);\n        __x = __t0 + (__t0 < __t1) * __m - __t1;\n        __x += __c - (__x >= __m - __c) * __m;\n        return __x;\n    }\n};\n\ntemplate <unsigned long long _Ap, unsigned long long _Mp>\nstruct __lce_ta<_Ap, 0, _Mp, unsigned(~0), true>\n{\n    typedef unsigned result_type;\n    _LIBCPP_INLINE_VISIBILITY\n    static result_type next(result_type __x)\n    {\n        const result_type __a = static_cast<result_type>(_Ap);\n        const result_type __m = static_cast<result_type>(_Mp);\n        // Schrage's algorithm\n        const result_type __q = __m / __a;\n        const result_type __r = __m % __a;\n        const result_type __t0 = __a * (__x % __q);\n        const result_type __t1 = __r * (__x / __q);\n        __x = __t0 + (__t0 < __t1) * __m - __t1;\n        return __x;\n    }\n};\n\ntemplate <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp>\nstruct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), false>\n{\n    typedef unsigned result_type;\n    _LIBCPP_INLINE_VISIBILITY\n    static result_type next(result_type __x)\n    {\n        const result_type __a = static_cast<result_type>(_Ap);\n        const result_type __c = static_cast<result_type>(_Cp);\n        const result_type __m = static_cast<result_type>(_Mp);\n        return (__a * __x + __c) % __m;\n    }\n};\n\ntemplate <unsigned long long _Ap, unsigned long long _Cp>\nstruct __lce_ta<_Ap, _Cp, 0, unsigned(~0), false>\n{\n    typedef unsigned result_type;\n    _LIBCPP_INLINE_VISIBILITY\n    static result_type next(result_type __x)\n    {\n        const result_type __a = static_cast<result_type>(_Ap);\n        const result_type __c = static_cast<result_type>(_Cp);\n        return __a * __x + __c;\n    }\n};\n\n// 16\n\ntemplate <unsigned long long __a, unsigned long long __c, unsigned long long __m, bool __b>\nstruct __lce_ta<__a, __c, __m, (unsigned short)(~0), __b>\n{\n    typedef unsigned short result_type;\n    _LIBCPP_INLINE_VISIBILITY\n    static result_type next(result_type __x)\n    {\n        return static_cast<result_type>(__lce_ta<__a, __c, __m, unsigned(~0)>::next(__x));\n    }\n};\n\ntemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>\nclass _LIBCPP_TYPE_VIS_ONLY linear_congruential_engine;\n\ntemplate <class _CharT, class _Traits,\n          class _Up, _Up _Ap, _Up _Cp, _Up _Np>\n_LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&);\n\ntemplate <class _CharT, class _Traits,\n          class _Up, _Up _Ap, _Up _Cp, _Up _Np>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x);\n\ntemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>\nclass _LIBCPP_TYPE_VIS_ONLY linear_congruential_engine\n{\npublic:\n    // types\n    typedef _UIntType result_type;\n\nprivate:\n    result_type __x_;\n\n    static _LIBCPP_CONSTEXPR const result_type _Mp = result_type(~0);\n\n    static_assert(__m == 0 || __a < __m, \"linear_congruential_engine invalid parameters\");\n    static_assert(__m == 0 || __c < __m, \"linear_congruential_engine invalid parameters\");\npublic:\n    static _LIBCPP_CONSTEXPR const result_type _Min = __c == 0u ? 1u: 0u;\n    static _LIBCPP_CONSTEXPR const result_type _Max = __m - 1u;\n    static_assert(_Min < _Max,           \"linear_congruential_engine invalid parameters\");\n\n    // engine characteristics\n    static _LIBCPP_CONSTEXPR const result_type multiplier = __a;\n    static _LIBCPP_CONSTEXPR const result_type increment = __c;\n    static _LIBCPP_CONSTEXPR const result_type modulus = __m;\n    _LIBCPP_INLINE_VISIBILITY\n    static _LIBCPP_CONSTEXPR result_type min() {return _Min;}\n    _LIBCPP_INLINE_VISIBILITY\n    static _LIBCPP_CONSTEXPR result_type max() {return _Max;}\n    static _LIBCPP_CONSTEXPR const result_type default_seed = 1u;\n\n    // constructors and seeding functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit linear_congruential_engine(result_type __s = default_seed)\n        {seed(__s);}\n    template<class _Sseq>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit linear_congruential_engine(_Sseq& __q,\n        typename enable_if<__is_seed_sequence<_Sseq, linear_congruential_engine>::value>::type* = 0)\n        {seed(__q);}\n    _LIBCPP_INLINE_VISIBILITY\n    void seed(result_type __s = default_seed)\n        {seed(integral_constant<bool, __m == 0>(),\n              integral_constant<bool, __c == 0>(), __s);}\n    template<class _Sseq>\n        _LIBCPP_INLINE_VISIBILITY\n        typename enable_if\n        <\n            __is_seed_sequence<_Sseq, linear_congruential_engine>::value,\n            void\n        >::type\n        seed(_Sseq& __q)\n            {__seed(__q, integral_constant<unsigned,\n                1 + (__m == 0 ? (sizeof(result_type) * __CHAR_BIT__ - 1)/32\n                             :  (__m > 0x100000000ull))>());}\n\n    // generating functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator()()\n        {return __x_ = static_cast<result_type>(__lce_ta<__a, __c, __m, _Mp>::next(__x_));}\n    _LIBCPP_INLINE_VISIBILITY\n    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const linear_congruential_engine& __x,\n                    const linear_congruential_engine& __y)\n        {return __x.__x_ == __y.__x_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const linear_congruential_engine& __x,\n                    const linear_congruential_engine& __y)\n        {return !(__x == __y);}\n\nprivate:\n\n    _LIBCPP_INLINE_VISIBILITY\n    void seed(true_type, true_type, result_type __s) {__x_ = __s == 0 ? 1 : __s;}\n    _LIBCPP_INLINE_VISIBILITY\n    void seed(true_type, false_type, result_type __s) {__x_ = __s;}\n    _LIBCPP_INLINE_VISIBILITY\n    void seed(false_type, true_type, result_type __s) {__x_ = __s % __m == 0 ?\n                                                                 1 : __s % __m;}\n    _LIBCPP_INLINE_VISIBILITY\n    void seed(false_type, false_type, result_type __s) {__x_ = __s % __m;}\n\n    template<class _Sseq>\n        void __seed(_Sseq& __q, integral_constant<unsigned, 1>);\n    template<class _Sseq>\n        void __seed(_Sseq& __q, integral_constant<unsigned, 2>);\n\n    template <class _CharT, class _Traits,\n              class _Up, _Up _Ap, _Up _Cp, _Up _Np>\n    friend\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os,\n               const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&);\n\n    template <class _CharT, class _Traits,\n              class _Up, _Up _Ap, _Up _Cp, _Up _Np>\n    friend\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is,\n               linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x);\n};\n\ntemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>\n    _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type\n    linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier;\n\ntemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>\n    _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type\n    linear_congruential_engine<_UIntType, __a, __c, __m>::increment;\n\ntemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>\n    _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type\n    linear_congruential_engine<_UIntType, __a, __c, __m>::modulus;\n\ntemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>\n    _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type\n    linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed;\n\ntemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>\ntemplate<class _Sseq>\nvoid\nlinear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q,\n                                                 integral_constant<unsigned, 1>)\n{\n    const unsigned __k = 1;\n    uint32_t __ar[__k+3];\n    __q.generate(__ar, __ar + __k + 3);\n    result_type __s = static_cast<result_type>(__ar[3] % __m);\n    __x_ = __c == 0 && __s == 0 ? result_type(1) : __s;\n}\n\ntemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>\ntemplate<class _Sseq>\nvoid\nlinear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q,\n                                                 integral_constant<unsigned, 2>)\n{\n    const unsigned __k = 2;\n    uint32_t __ar[__k+3];\n    __q.generate(__ar, __ar + __k + 3);\n    result_type __s = static_cast<result_type>((__ar[3] +\n                                              ((uint64_t)__ar[4] << 32)) % __m);\n    __x_ = __c == 0 && __s == 0 ? result_type(1) : __s;\n}\n\ntemplate <class _CharT, class _Traits,\n          class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const linear_congruential_engine<_UIntType, __a, __c, __m>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left);\n    __os.fill(__os.widen(' '));\n    return __os << __x.__x_;\n}\n\ntemplate <class _CharT, class _Traits,\n          class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           linear_congruential_engine<_UIntType, __a, __c, __m>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    _UIntType __t;\n    __is >> __t;\n    if (!__is.fail())\n        __x.__x_ = __t;\n    return __is;\n}\n\ntypedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>\n                                                                   minstd_rand0;\ntypedef linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647>\n                                                                    minstd_rand;\ntypedef minstd_rand                                       default_random_engine;\n// mersenne_twister_engine\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\nclass _LIBCPP_TYPE_VIS_ONLY mersenne_twister_engine;\n\ntemplate <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,\n          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,\n          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>\nbool\noperator==(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x,\n           const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __y);\n\ntemplate <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,\n          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,\n          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>\n_LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x,\n           const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __y);\n\ntemplate <class _CharT, class _Traits,\n          class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,\n          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,\n          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x);\n\ntemplate <class _CharT, class _Traits,\n          class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,\n          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,\n          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                   _Bp, _Tp, _Cp, _Lp, _Fp>& __x);\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\nclass _LIBCPP_TYPE_VIS_ONLY mersenne_twister_engine\n{\npublic:\n    // types\n    typedef _UIntType result_type;\n\nprivate:\n    result_type __x_[__n];\n    size_t      __i_;\n\n    static_assert(  0 <  __m, \"mersenne_twister_engine invalid parameters\");\n    static_assert(__m <= __n, \"mersenne_twister_engine invalid parameters\");\n    static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits<result_type>::digits;\n    static_assert(__w <= _Dt, \"mersenne_twister_engine invalid parameters\");\n    static_assert(  2 <= __w, \"mersenne_twister_engine invalid parameters\");\n    static_assert(__r <= __w, \"mersenne_twister_engine invalid parameters\");\n    static_assert(__u <= __w, \"mersenne_twister_engine invalid parameters\");\n    static_assert(__s <= __w, \"mersenne_twister_engine invalid parameters\");\n    static_assert(__t <= __w, \"mersenne_twister_engine invalid parameters\");\n    static_assert(__l <= __w, \"mersenne_twister_engine invalid parameters\");\npublic:\n    static _LIBCPP_CONSTEXPR const result_type _Min = 0;\n    static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) :\n                                                      (result_type(1) << __w) - result_type(1);\n    static_assert(_Min < _Max, \"mersenne_twister_engine invalid parameters\");\n    static_assert(__a <= _Max, \"mersenne_twister_engine invalid parameters\");\n    static_assert(__b <= _Max, \"mersenne_twister_engine invalid parameters\");\n    static_assert(__c <= _Max, \"mersenne_twister_engine invalid parameters\");\n    static_assert(__d <= _Max, \"mersenne_twister_engine invalid parameters\");\n    static_assert(__f <= _Max, \"mersenne_twister_engine invalid parameters\");\n\n    // engine characteristics\n    static _LIBCPP_CONSTEXPR const size_t word_size = __w;\n    static _LIBCPP_CONSTEXPR const size_t state_size = __n;\n    static _LIBCPP_CONSTEXPR const size_t shift_size = __m;\n    static _LIBCPP_CONSTEXPR const size_t mask_bits = __r;\n    static _LIBCPP_CONSTEXPR const result_type xor_mask = __a;\n    static _LIBCPP_CONSTEXPR const size_t tempering_u = __u;\n    static _LIBCPP_CONSTEXPR const result_type tempering_d = __d;\n    static _LIBCPP_CONSTEXPR const size_t tempering_s = __s;\n    static _LIBCPP_CONSTEXPR const result_type tempering_b = __b;\n    static _LIBCPP_CONSTEXPR const size_t tempering_t = __t;\n    static _LIBCPP_CONSTEXPR const result_type tempering_c = __c;\n    static _LIBCPP_CONSTEXPR const size_t tempering_l = __l;\n    static _LIBCPP_CONSTEXPR const result_type initialization_multiplier = __f;\n    _LIBCPP_INLINE_VISIBILITY\n    static _LIBCPP_CONSTEXPR result_type min() { return _Min; }\n    _LIBCPP_INLINE_VISIBILITY\n    static _LIBCPP_CONSTEXPR result_type max() { return _Max; }\n    static _LIBCPP_CONSTEXPR const result_type default_seed = 5489u;\n\n    // constructors and seeding functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit mersenne_twister_engine(result_type __sd = default_seed)\n        {seed(__sd);}\n    template<class _Sseq>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit mersenne_twister_engine(_Sseq& __q,\n        typename enable_if<__is_seed_sequence<_Sseq, mersenne_twister_engine>::value>::type* = 0)\n        {seed(__q);}\n    void seed(result_type __sd = default_seed);\n    template<class _Sseq>\n        _LIBCPP_INLINE_VISIBILITY\n        typename enable_if\n        <\n            __is_seed_sequence<_Sseq, mersenne_twister_engine>::value,\n            void\n        >::type\n        seed(_Sseq& __q)\n            {__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());}\n\n    // generating functions\n    result_type operator()();\n    _LIBCPP_INLINE_VISIBILITY\n    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}\n\n    template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,\n              _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,\n              _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>\n    friend\n    bool\n    operator==(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __x,\n               const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __y);\n\n    template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,\n              _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,\n              _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>\n    friend\n    bool\n    operator!=(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __x,\n               const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __y);\n\n    template <class _CharT, class _Traits,\n              class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,\n              _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,\n              _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>\n    friend\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os,\n               const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __x);\n\n    template <class _CharT, class _Traits,\n              class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,\n              _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,\n              _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>\n    friend\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is,\n               mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                       _Bp, _Tp, _Cp, _Lp, _Fp>& __x);\nprivate:\n\n    template<class _Sseq>\n        void __seed(_Sseq& __q, integral_constant<unsigned, 1>);\n    template<class _Sseq>\n        void __seed(_Sseq& __q, integral_constant<unsigned, 2>);\n\n    template <size_t __count>\n        _LIBCPP_INLINE_VISIBILITY\n        static\n        typename enable_if\n        <\n            __count < __w,\n            result_type\n        >::type\n        __lshift(result_type __x) {return (__x << __count) & _Max;}\n\n    template <size_t __count>\n        _LIBCPP_INLINE_VISIBILITY\n        static\n        typename enable_if\n        <\n            (__count >= __w),\n            result_type\n        >::type\n        __lshift(result_type) {return result_type(0);}\n\n    template <size_t __count>\n        _LIBCPP_INLINE_VISIBILITY\n        static\n        typename enable_if\n        <\n            __count < _Dt,\n            result_type\n        >::type\n        __rshift(result_type __x) {return __x >> __count;}\n\n    template <size_t __count>\n        _LIBCPP_INLINE_VISIBILITY\n        static\n        typename enable_if\n        <\n            (__count >= _Dt),\n            result_type\n        >::type\n        __rshift(result_type) {return result_type(0);}\n};\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n    _LIBCPP_CONSTEXPR const size_t\n    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::word_size;\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n    _LIBCPP_CONSTEXPR const size_t \n    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::state_size;\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n    _LIBCPP_CONSTEXPR const size_t \n    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::shift_size;\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n    _LIBCPP_CONSTEXPR const size_t \n    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::mask_bits;\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type\n    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::xor_mask;\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n    _LIBCPP_CONSTEXPR const size_t \n    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_u;\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type\n    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_d;\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n    _LIBCPP_CONSTEXPR const size_t \n    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_s;\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type\n    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_b;\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n    _LIBCPP_CONSTEXPR const size_t \n    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_t;\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type\n    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_c;\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n    _LIBCPP_CONSTEXPR const size_t \n    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_l;\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type\n    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::initialization_multiplier;\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type\n    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::default_seed;\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\nvoid\nmersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,\n    __t, __c, __l, __f>::seed(result_type __sd)\n{   // __w >= 2\n    __x_[0] = __sd & _Max;\n    for (size_t __i = 1; __i < __n; ++__i)\n        __x_[__i] = (__f * (__x_[__i-1] ^ __rshift<__w - 2>(__x_[__i-1])) + __i) & _Max;\n    __i_ = 0;\n}\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\ntemplate<class _Sseq>\nvoid\nmersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,\n    __t, __c, __l, __f>::__seed(_Sseq& __q, integral_constant<unsigned, 1>)\n{\n    const unsigned __k = 1;\n    uint32_t __ar[__n * __k];\n    __q.generate(__ar, __ar + __n * __k);\n    for (size_t __i = 0; __i < __n; ++__i)\n        __x_[__i] = static_cast<result_type>(__ar[__i] & _Max);\n    const result_type __mask = __r == _Dt ? result_type(~0) :\n                                       (result_type(1) << __r) - result_type(1);\n    __i_ = 0;\n    if ((__x_[0] & ~__mask) == 0)\n    {\n        for (size_t __i = 1; __i < __n; ++__i)\n            if (__x_[__i] != 0)\n                return;\n        __x_[0] = _Max;\n    }\n}\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\ntemplate<class _Sseq>\nvoid\nmersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,\n    __t, __c, __l, __f>::__seed(_Sseq& __q, integral_constant<unsigned, 2>)\n{\n    const unsigned __k = 2;\n    uint32_t __ar[__n * __k];\n    __q.generate(__ar, __ar + __n * __k);\n    for (size_t __i = 0; __i < __n; ++__i)\n        __x_[__i] = static_cast<result_type>(\n            (__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max);\n    const result_type __mask = __r == _Dt ? result_type(~0) :\n                                       (result_type(1) << __r) - result_type(1);\n    __i_ = 0;\n    if ((__x_[0] & ~__mask) == 0)\n    {\n        for (size_t __i = 1; __i < __n; ++__i)\n            if (__x_[__i] != 0)\n                return;\n        __x_[0] = _Max;\n    }\n}\n\ntemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,\n          _UIntType __a, size_t __u, _UIntType __d, size_t __s,\n          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>\n_UIntType\nmersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,\n    __t, __c, __l, __f>::operator()()\n{\n    const size_t __j = (__i_ + 1) % __n;\n    const result_type __mask = __r == _Dt ? result_type(~0) :\n                                       (result_type(1) << __r) - result_type(1);\n    const result_type _Yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask);\n    const size_t __k = (__i_ + __m) % __n;\n    __x_[__i_] = __x_[__k] ^ __rshift<1>(_Yp) ^ (__a * (_Yp & 1));\n    result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d);\n    __i_ = __j;\n    __z ^= __lshift<__s>(__z) & __b;\n    __z ^= __lshift<__t>(__z) & __c;\n    return __z ^ __rshift<__l>(__z);\n}\n\ntemplate <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,\n          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,\n          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>\nbool\noperator==(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x,\n           const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __y)\n{\n    if (__x.__i_ == __y.__i_)\n        return _VSTD::equal(__x.__x_, __x.__x_ + _Np, __y.__x_);\n    if (__x.__i_ == 0 || __y.__i_ == 0)\n    {\n        size_t __j = _VSTD::min(_Np - __x.__i_, _Np - __y.__i_);\n        if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + __x.__i_ + __j,\n                         __y.__x_ + __y.__i_))\n            return false;\n        if (__x.__i_ == 0)\n            return _VSTD::equal(__x.__x_ + __j, __x.__x_ + _Np, __y.__x_);\n        return _VSTD::equal(__x.__x_, __x.__x_ + (_Np - __j), __y.__x_ + __j);\n    }\n    if (__x.__i_ < __y.__i_)\n    {\n        size_t __j = _Np - __y.__i_;\n        if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + (__x.__i_ + __j),\n                         __y.__x_ + __y.__i_))\n            return false;\n        if (!_VSTD::equal(__x.__x_ + (__x.__i_ + __j), __x.__x_ + _Np,\n                         __y.__x_))\n            return false;\n        return _VSTD::equal(__x.__x_, __x.__x_ + __x.__i_,\n                           __y.__x_ + (_Np - (__x.__i_ + __j)));\n    }\n    size_t __j = _Np - __x.__i_;\n    if (!_VSTD::equal(__y.__x_ + __y.__i_, __y.__x_ + (__y.__i_ + __j),\n                     __x.__x_ + __x.__i_))\n        return false;\n    if (!_VSTD::equal(__y.__x_ + (__y.__i_ + __j), __y.__x_ + _Np,\n                     __x.__x_))\n        return false;\n    return _VSTD::equal(__y.__x_, __y.__x_ + __y.__i_,\n                       __x.__x_ + (_Np - (__y.__i_ + __j)));\n}\n\ntemplate <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,\n          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,\n          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x,\n           const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _CharT, class _Traits,\n          class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,\n          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,\n          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    __os << __x.__x_[__x.__i_];\n    for (size_t __j = __x.__i_ + 1; __j < _Np; ++__j)\n        __os << __sp << __x.__x_[__j];\n    for (size_t __j = 0; __j < __x.__i_; ++__j)\n        __os << __sp << __x.__x_[__j];\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits,\n          class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,\n          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,\n          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,\n                                   _Bp, _Tp, _Cp, _Lp, _Fp>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    _UI __t[_Np];\n    for (size_t __i = 0; __i < _Np; ++__i)\n        __is >> __t[__i];\n    if (!__is.fail())\n    {\n        for (size_t __i = 0; __i < _Np; ++__i)\n            __x.__x_[__i] = __t[__i];\n        __x.__i_ = 0;\n    }\n    return __is;\n}\n\ntypedef mersenne_twister_engine<uint_fast32_t, 32, 624, 397, 31,\n                                0x9908b0df, 11, 0xffffffff,\n                                7,  0x9d2c5680,\n                                15, 0xefc60000,\n                                18, 1812433253>                         mt19937;\ntypedef mersenne_twister_engine<uint_fast64_t, 64, 312, 156, 31,\n                                0xb5026f5aa96619e9ULL, 29, 0x5555555555555555ULL,\n                                17, 0x71d67fffeda60000ULL,\n                                37, 0xfff7eee000000000ULL,\n                                43, 6364136223846793005ULL>          mt19937_64;\n\n// subtract_with_carry_engine\n\ntemplate<class _UIntType, size_t __w, size_t __s, size_t __r>\nclass _LIBCPP_TYPE_VIS_ONLY subtract_with_carry_engine;\n\ntemplate<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>\nbool\noperator==(\n    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,\n    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y);\n\ntemplate<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>\n_LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(\n    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,\n    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y);\n\ntemplate <class _CharT, class _Traits,\n          class _UI, size_t _Wp, size_t _Sp, size_t _Rp>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x);\n\ntemplate <class _CharT, class _Traits,\n          class _UI, size_t _Wp, size_t _Sp, size_t _Rp>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x);\n\ntemplate<class _UIntType, size_t __w, size_t __s, size_t __r>\nclass _LIBCPP_TYPE_VIS_ONLY subtract_with_carry_engine\n{\npublic:\n    // types\n    typedef _UIntType result_type;\n\nprivate:\n    result_type __x_[__r];\n    result_type  __c_;\n    size_t      __i_;\n\n    static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits<result_type>::digits;\n    static_assert(  0 <  __w, \"subtract_with_carry_engine invalid parameters\");\n    static_assert(__w <= _Dt, \"subtract_with_carry_engine invalid parameters\");\n    static_assert(  0 <  __s, \"subtract_with_carry_engine invalid parameters\");\n    static_assert(__s <  __r, \"subtract_with_carry_engine invalid parameters\");\npublic:\n    static _LIBCPP_CONSTEXPR const result_type _Min = 0;\n    static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) :\n                                                      (result_type(1) << __w) - result_type(1);\n    static_assert(_Min < _Max, \"subtract_with_carry_engine invalid parameters\");\n\n    // engine characteristics\n    static _LIBCPP_CONSTEXPR const size_t word_size = __w;\n    static _LIBCPP_CONSTEXPR const size_t short_lag = __s;\n    static _LIBCPP_CONSTEXPR const size_t long_lag = __r;\n    _LIBCPP_INLINE_VISIBILITY\n    static _LIBCPP_CONSTEXPR result_type min() { return _Min; }\n    _LIBCPP_INLINE_VISIBILITY\n    static _LIBCPP_CONSTEXPR result_type max() { return _Max; }\n    static _LIBCPP_CONSTEXPR const result_type default_seed = 19780503u;\n\n    // constructors and seeding functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit subtract_with_carry_engine(result_type __sd = default_seed)\n        {seed(__sd);}\n    template<class _Sseq>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit subtract_with_carry_engine(_Sseq& __q,\n        typename enable_if<__is_seed_sequence<_Sseq, subtract_with_carry_engine>::value>::type* = 0)\n        {seed(__q);}\n    _LIBCPP_INLINE_VISIBILITY\n    void seed(result_type __sd = default_seed)\n        {seed(__sd, integral_constant<unsigned, 1 + (__w - 1) / 32>());}\n    template<class _Sseq>\n        _LIBCPP_INLINE_VISIBILITY\n        typename enable_if\n        <\n            __is_seed_sequence<_Sseq, subtract_with_carry_engine>::value,\n            void\n        >::type\n        seed(_Sseq& __q)\n            {__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());}\n\n    // generating functions\n    result_type operator()();\n    _LIBCPP_INLINE_VISIBILITY\n    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}\n\n    template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>\n    friend\n    bool\n    operator==(\n        const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,\n        const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y);\n\n    template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>\n    friend\n    bool\n    operator!=(\n        const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,\n        const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y);\n\n    template <class _CharT, class _Traits,\n              class _UI, size_t _Wp, size_t _Sp, size_t _Rp>\n    friend\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os,\n               const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x);\n\n    template <class _CharT, class _Traits,\n              class _UI, size_t _Wp, size_t _Sp, size_t _Rp>\n    friend\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is,\n               subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x);\n\nprivate:\n\n    void seed(result_type __sd, integral_constant<unsigned, 1>);\n    void seed(result_type __sd, integral_constant<unsigned, 2>);\n    template<class _Sseq>\n        void __seed(_Sseq& __q, integral_constant<unsigned, 1>);\n    template<class _Sseq>\n        void __seed(_Sseq& __q, integral_constant<unsigned, 2>);\n};\n\ntemplate<class _UIntType, size_t __w, size_t __s, size_t __r>\n    _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size;\n\ntemplate<class _UIntType, size_t __w, size_t __s, size_t __r>\n    _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag;\n\ntemplate<class _UIntType, size_t __w, size_t __s, size_t __r>\n    _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag;\n\ntemplate<class _UIntType, size_t __w, size_t __s, size_t __r>\n    _LIBCPP_CONSTEXPR const typename subtract_with_carry_engine<_UIntType, __w, __s, __r>::result_type\n    subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed;\n\ntemplate<class _UIntType, size_t __w, size_t __s, size_t __r>\nvoid\nsubtract_with_carry_engine<_UIntType, __w, __s, __r>::seed(result_type __sd,\n        integral_constant<unsigned, 1>)\n{\n    linear_congruential_engine<result_type, 40014u, 0u, 2147483563u>\n        __e(__sd == 0u ? default_seed : __sd);\n    for (size_t __i = 0; __i < __r; ++__i)\n        __x_[__i] = static_cast<result_type>(__e() & _Max);\n    __c_ = __x_[__r-1] == 0;\n    __i_ = 0;\n}\n\ntemplate<class _UIntType, size_t __w, size_t __s, size_t __r>\nvoid\nsubtract_with_carry_engine<_UIntType, __w, __s, __r>::seed(result_type __sd,\n        integral_constant<unsigned, 2>)\n{\n    linear_congruential_engine<result_type, 40014u, 0u, 2147483563u>\n        __e(__sd == 0u ? default_seed : __sd);\n    for (size_t __i = 0; __i < __r; ++__i)\n    {\n        result_type __e0 = __e();\n        __x_[__i] = static_cast<result_type>(\n                                    (__e0 + ((uint64_t)__e() << 32)) & _Max);\n    }\n    __c_ = __x_[__r-1] == 0;\n    __i_ = 0;\n}\n\ntemplate<class _UIntType, size_t __w, size_t __s, size_t __r>\ntemplate<class _Sseq>\nvoid\nsubtract_with_carry_engine<_UIntType, __w, __s, __r>::__seed(_Sseq& __q,\n        integral_constant<unsigned, 1>)\n{\n    const unsigned __k = 1;\n    uint32_t __ar[__r * __k];\n    __q.generate(__ar, __ar + __r * __k);\n    for (size_t __i = 0; __i < __r; ++__i)\n        __x_[__i] = static_cast<result_type>(__ar[__i] & _Max);\n    __c_ = __x_[__r-1] == 0;\n    __i_ = 0;\n}\n\ntemplate<class _UIntType, size_t __w, size_t __s, size_t __r>\ntemplate<class _Sseq>\nvoid\nsubtract_with_carry_engine<_UIntType, __w, __s, __r>::__seed(_Sseq& __q,\n        integral_constant<unsigned, 2>)\n{\n    const unsigned __k = 2;\n    uint32_t __ar[__r * __k];\n    __q.generate(__ar, __ar + __r * __k);\n    for (size_t __i = 0; __i < __r; ++__i)\n        __x_[__i] = static_cast<result_type>(\n                  (__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max);\n    __c_ = __x_[__r-1] == 0;\n    __i_ = 0;\n}\n\ntemplate<class _UIntType, size_t __w, size_t __s, size_t __r>\n_UIntType\nsubtract_with_carry_engine<_UIntType, __w, __s, __r>::operator()()\n{\n    const result_type& __xs = __x_[(__i_ + (__r - __s)) % __r];\n    result_type& __xr = __x_[__i_];\n    result_type __new_c = __c_ == 0 ? __xs < __xr : __xs != 0 ? __xs <= __xr : 1;\n    __xr = (__xs - __xr - __c_) & _Max;\n    __c_ = __new_c;\n    __i_ = (__i_ + 1) % __r;\n    return __xr;\n}\n\ntemplate<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>\nbool\noperator==(\n    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,\n    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y)\n{\n    if (__x.__c_ != __y.__c_)\n        return false;\n    if (__x.__i_ == __y.__i_)\n        return _VSTD::equal(__x.__x_, __x.__x_ + _Rp, __y.__x_);\n    if (__x.__i_ == 0 || __y.__i_ == 0)\n    {\n        size_t __j = _VSTD::min(_Rp - __x.__i_, _Rp - __y.__i_);\n        if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + __x.__i_ + __j,\n                         __y.__x_ + __y.__i_))\n            return false;\n        if (__x.__i_ == 0)\n            return _VSTD::equal(__x.__x_ + __j, __x.__x_ + _Rp, __y.__x_);\n        return _VSTD::equal(__x.__x_, __x.__x_ + (_Rp - __j), __y.__x_ + __j);\n    }\n    if (__x.__i_ < __y.__i_)\n    {\n        size_t __j = _Rp - __y.__i_;\n        if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + (__x.__i_ + __j),\n                         __y.__x_ + __y.__i_))\n            return false;\n        if (!_VSTD::equal(__x.__x_ + (__x.__i_ + __j), __x.__x_ + _Rp,\n                         __y.__x_))\n            return false;\n        return _VSTD::equal(__x.__x_, __x.__x_ + __x.__i_,\n                           __y.__x_ + (_Rp - (__x.__i_ + __j)));\n    }\n    size_t __j = _Rp - __x.__i_;\n    if (!_VSTD::equal(__y.__x_ + __y.__i_, __y.__x_ + (__y.__i_ + __j),\n                     __x.__x_ + __x.__i_))\n        return false;\n    if (!_VSTD::equal(__y.__x_ + (__y.__i_ + __j), __y.__x_ + _Rp,\n                     __x.__x_))\n        return false;\n    return _VSTD::equal(__y.__x_, __y.__x_ + __y.__i_,\n                       __x.__x_ + (_Rp - (__y.__i_ + __j)));\n}\n\ntemplate<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(\n    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,\n    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _CharT, class _Traits,\n          class _UI, size_t _Wp, size_t _Sp, size_t _Rp>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    __os << __x.__x_[__x.__i_];\n    for (size_t __j = __x.__i_ + 1; __j < _Rp; ++__j)\n        __os << __sp << __x.__x_[__j];\n    for (size_t __j = 0; __j < __x.__i_; ++__j)\n        __os << __sp << __x.__x_[__j];\n    __os << __sp << __x.__c_;\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits,\n          class _UI, size_t _Wp, size_t _Sp, size_t _Rp>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    _UI __t[_Rp+1];\n    for (size_t __i = 0; __i < _Rp+1; ++__i)\n        __is >> __t[__i];\n    if (!__is.fail())\n    {\n        for (size_t __i = 0; __i < _Rp; ++__i)\n            __x.__x_[__i] = __t[__i];\n        __x.__c_ = __t[_Rp];\n        __x.__i_ = 0;\n    }\n    return __is;\n}\n\ntypedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>     ranlux24_base;\ntypedef subtract_with_carry_engine<uint_fast64_t, 48,  5, 12>     ranlux48_base;\n\n// discard_block_engine\n\ntemplate<class _Engine, size_t __p, size_t __r>\nclass _LIBCPP_TYPE_VIS_ONLY discard_block_engine\n{\n    _Engine __e_;\n    int     __n_;\n\n    static_assert(  0 <  __r, \"discard_block_engine invalid parameters\");\n    static_assert(__r <= __p, \"discard_block_engine invalid parameters\");\npublic:\n    // types\n    typedef typename _Engine::result_type result_type;\n\n    // engine characteristics\n    static _LIBCPP_CONSTEXPR const size_t block_size = __p;\n    static _LIBCPP_CONSTEXPR const size_t used_block = __r;\n\n#ifdef _LIBCPP_HAS_NO_CONSTEXPR\n    static const result_type _Min = _Engine::_Min;\n    static const result_type _Max = _Engine::_Max;\n#else\n    static _LIBCPP_CONSTEXPR const result_type _Min = _Engine::min();\n    static _LIBCPP_CONSTEXPR const result_type _Max = _Engine::max();\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    static _LIBCPP_CONSTEXPR result_type min() { return _Engine::min(); }\n    _LIBCPP_INLINE_VISIBILITY\n    static _LIBCPP_CONSTEXPR result_type max() { return _Engine::max(); }\n\n    // constructors and seeding functions\n    _LIBCPP_INLINE_VISIBILITY\n    discard_block_engine() : __n_(0) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit discard_block_engine(const _Engine& __e)\n        : __e_(__e), __n_(0) {}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    explicit discard_block_engine(_Engine&& __e)\n        : __e_(_VSTD::move(__e)), __n_(0) {}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    explicit discard_block_engine(result_type __sd) : __e_(__sd), __n_(0) {}\n    template<class _Sseq>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit discard_block_engine(_Sseq& __q,\n        typename enable_if<__is_seed_sequence<_Sseq, discard_block_engine>::value &&\n                           !is_convertible<_Sseq, _Engine>::value>::type* = 0)\n        : __e_(__q), __n_(0) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void seed() {__e_.seed(); __n_ = 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    void seed(result_type __sd) {__e_.seed(__sd); __n_ = 0;}\n    template<class _Sseq>\n        _LIBCPP_INLINE_VISIBILITY\n        typename enable_if\n        <\n            __is_seed_sequence<_Sseq, discard_block_engine>::value,\n            void\n        >::type\n        seed(_Sseq& __q) {__e_.seed(__q); __n_ = 0;}\n\n    // generating functions\n    result_type operator()();\n    _LIBCPP_INLINE_VISIBILITY\n    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    const _Engine& base() const _NOEXCEPT {return __e_;}\n\n    template<class _Eng, size_t _Pp, size_t _Rp>\n    friend\n    bool\n    operator==(\n        const discard_block_engine<_Eng, _Pp, _Rp>& __x,\n        const discard_block_engine<_Eng, _Pp, _Rp>& __y);\n\n    template<class _Eng, size_t _Pp, size_t _Rp>\n    friend\n    bool\n    operator!=(\n        const discard_block_engine<_Eng, _Pp, _Rp>& __x,\n        const discard_block_engine<_Eng, _Pp, _Rp>& __y);\n\n    template <class _CharT, class _Traits,\n              class _Eng, size_t _Pp, size_t _Rp>\n    friend\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os,\n               const discard_block_engine<_Eng, _Pp, _Rp>& __x);\n\n    template <class _CharT, class _Traits,\n              class _Eng, size_t _Pp, size_t _Rp>\n    friend\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is,\n               discard_block_engine<_Eng, _Pp, _Rp>& __x);\n};\n\ntemplate<class _Engine, size_t __p, size_t __r>\n    _LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::block_size;\n\ntemplate<class _Engine, size_t __p, size_t __r>\n    _LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::used_block;\n\ntemplate<class _Engine, size_t __p, size_t __r>\ntypename discard_block_engine<_Engine, __p, __r>::result_type\ndiscard_block_engine<_Engine, __p, __r>::operator()()\n{\n    if (__n_ >= __r)\n    {\n        __e_.discard(__p - __r);\n        __n_ = 0;\n    }\n    ++__n_;\n    return __e_();\n}\n\ntemplate<class _Eng, size_t _Pp, size_t _Rp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const discard_block_engine<_Eng, _Pp, _Rp>& __x,\n           const discard_block_engine<_Eng, _Pp, _Rp>& __y)\n{\n    return __x.__n_ == __y.__n_ && __x.__e_ == __y.__e_;\n}\n\ntemplate<class _Eng, size_t _Pp, size_t _Rp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const discard_block_engine<_Eng, _Pp, _Rp>& __x,\n           const discard_block_engine<_Eng, _Pp, _Rp>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _CharT, class _Traits,\n          class _Eng, size_t _Pp, size_t _Rp>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const discard_block_engine<_Eng, _Pp, _Rp>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    return __os << __x.__e_ << __sp << __x.__n_;\n}\n\ntemplate <class _CharT, class _Traits,\n          class _Eng, size_t _Pp, size_t _Rp>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           discard_block_engine<_Eng, _Pp, _Rp>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    _Eng __e;\n    int __n;\n    __is >> __e >> __n;\n    if (!__is.fail())\n    {\n        __x.__e_ = __e;\n        __x.__n_ = __n;\n    }\n    return __is;\n}\n\ntypedef discard_block_engine<ranlux24_base, 223, 23> ranlux24;\ntypedef discard_block_engine<ranlux48_base, 389, 11> ranlux48;\n\n// independent_bits_engine\n\ntemplate<class _Engine, size_t __w, class _UIntType>\nclass _LIBCPP_TYPE_VIS_ONLY independent_bits_engine\n{\n    template <class _UI, _UI _R0, size_t _Wp, size_t _Mp>\n    class __get_n\n    {\n        static _LIBCPP_CONSTEXPR const size_t _Dt = numeric_limits<_UI>::digits;\n        static _LIBCPP_CONSTEXPR const size_t _Np = _Wp / _Mp + (_Wp % _Mp != 0);\n        static _LIBCPP_CONSTEXPR const size_t _W0 = _Wp / _Np;\n        static _LIBCPP_CONSTEXPR const _UI _Y0 = _W0 >= _Dt ? 0 : (_R0 >> _W0) << _W0;\n    public:\n        static _LIBCPP_CONSTEXPR const size_t value = _R0 - _Y0 > _Y0 / _Np ? _Np + 1 : _Np;\n    };\npublic:\n    // types\n    typedef _UIntType result_type;\n\nprivate:\n    _Engine __e_;\n\n    static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits<result_type>::digits;\n    static_assert(  0 <  __w, \"independent_bits_engine invalid parameters\");\n    static_assert(__w <= _Dt, \"independent_bits_engine invalid parameters\");\n\n    typedef typename _Engine::result_type _Engine_result_type;\n    typedef typename conditional\n        <\n            sizeof(_Engine_result_type) <= sizeof(result_type),\n                result_type,\n                _Engine_result_type\n        >::type _Working_result_type;\n#ifdef _LIBCPP_HAS_NO_CONSTEXPR\n    static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min\n                                          + _Working_result_type(1);\n#else\n    static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min()\n                                                            + _Working_result_type(1);\n#endif\n    static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value;\n    static _LIBCPP_CONSTEXPR const size_t __n = __get_n<_Working_result_type, _Rp, __w, __m>::value;\n    static _LIBCPP_CONSTEXPR const size_t __w0 = __w / __n;\n    static _LIBCPP_CONSTEXPR const size_t __n0 = __n - __w % __n;\n    static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits;\n    static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits;\n    static _LIBCPP_CONSTEXPR const _Working_result_type __y0 = __w0 >= _WDt ? 0 :\n                                                               (_Rp >> __w0) << __w0;\n    static _LIBCPP_CONSTEXPR const _Working_result_type __y1 = __w0 >= _WDt - 1 ? 0 :\n                                                               (_Rp >> (__w0+1)) << (__w0+1);\n    static _LIBCPP_CONSTEXPR const _Engine_result_type __mask0 = __w0 > 0 ?\n                                _Engine_result_type(~0) >> (_EDt - __w0) :\n                                _Engine_result_type(0);\n    static _LIBCPP_CONSTEXPR const _Engine_result_type __mask1 = __w0 < _EDt - 1 ?\n                                _Engine_result_type(~0) >> (_EDt - (__w0 + 1)) :\n                                _Engine_result_type(~0);\npublic:\n    static _LIBCPP_CONSTEXPR const result_type _Min = 0;\n    static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) :\n                                                      (result_type(1) << __w) - result_type(1);\n    static_assert(_Min < _Max, \"independent_bits_engine invalid parameters\");\n\n    // engine characteristics\n    _LIBCPP_INLINE_VISIBILITY\n    static _LIBCPP_CONSTEXPR result_type min() { return _Min; }\n    _LIBCPP_INLINE_VISIBILITY\n    static _LIBCPP_CONSTEXPR result_type max() { return _Max; }\n\n    // constructors and seeding functions\n    _LIBCPP_INLINE_VISIBILITY\n    independent_bits_engine() {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit independent_bits_engine(const _Engine& __e)\n        : __e_(__e) {}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    explicit independent_bits_engine(_Engine&& __e)\n        : __e_(_VSTD::move(__e)) {}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    explicit independent_bits_engine(result_type __sd) : __e_(__sd) {}\n    template<class _Sseq>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit independent_bits_engine(_Sseq& __q,\n        typename enable_if<__is_seed_sequence<_Sseq, independent_bits_engine>::value &&\n                           !is_convertible<_Sseq, _Engine>::value>::type* = 0)\n         : __e_(__q) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void seed() {__e_.seed();}\n    _LIBCPP_INLINE_VISIBILITY\n    void seed(result_type __sd) {__e_.seed(__sd);}\n    template<class _Sseq>\n        _LIBCPP_INLINE_VISIBILITY\n        typename enable_if\n        <\n            __is_seed_sequence<_Sseq, independent_bits_engine>::value,\n            void\n        >::type\n        seed(_Sseq& __q) {__e_.seed(__q);}\n\n    // generating functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}\n    _LIBCPP_INLINE_VISIBILITY\n    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    const _Engine& base() const _NOEXCEPT {return __e_;}\n\n    template<class _Eng, size_t _Wp, class _UI>\n    friend\n    bool\n    operator==(\n        const independent_bits_engine<_Eng, _Wp, _UI>& __x,\n        const independent_bits_engine<_Eng, _Wp, _UI>& __y);\n\n    template<class _Eng, size_t _Wp, class _UI>\n    friend\n    bool\n    operator!=(\n        const independent_bits_engine<_Eng, _Wp, _UI>& __x,\n        const independent_bits_engine<_Eng, _Wp, _UI>& __y);\n\n    template <class _CharT, class _Traits,\n              class _Eng, size_t _Wp, class _UI>\n    friend\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os,\n               const independent_bits_engine<_Eng, _Wp, _UI>& __x);\n\n    template <class _CharT, class _Traits,\n              class _Eng, size_t _Wp, class _UI>\n    friend\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is,\n               independent_bits_engine<_Eng, _Wp, _UI>& __x);\n\nprivate:\n    result_type __eval(false_type);\n    result_type __eval(true_type);\n\n    template <size_t __count>\n        _LIBCPP_INLINE_VISIBILITY\n        static\n        typename enable_if\n        <\n            __count < _Dt,\n            result_type\n        >::type\n        __lshift(result_type __x) {return __x << __count;}\n\n    template <size_t __count>\n        _LIBCPP_INLINE_VISIBILITY\n        static\n        typename enable_if\n        <\n            (__count >= _Dt),\n            result_type\n        >::type\n        __lshift(result_type) {return result_type(0);}\n};\n\ntemplate<class _Engine, size_t __w, class _UIntType>\ninline _LIBCPP_INLINE_VISIBILITY\n_UIntType\nindependent_bits_engine<_Engine, __w, _UIntType>::__eval(false_type)\n{\n    return static_cast<result_type>(__e_() & __mask0);\n}\n\ntemplate<class _Engine, size_t __w, class _UIntType>\n_UIntType\nindependent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type)\n{\n    result_type _Sp = 0;\n    for (size_t __k = 0; __k < __n0; ++__k)\n    {\n        _Engine_result_type __u;\n        do\n        {\n            __u = __e_() - _Engine::min();\n        } while (__u >= __y0);\n        _Sp = static_cast<result_type>(__lshift<__w0>(_Sp) + (__u & __mask0));\n    }\n    for (size_t __k = __n0; __k < __n; ++__k)\n    {\n        _Engine_result_type __u;\n        do\n        {\n            __u = __e_() - _Engine::min();\n        } while (__u >= __y1);\n        _Sp = static_cast<result_type>(__lshift<__w0+1>(_Sp) + (__u & __mask1));\n    }\n    return _Sp;\n}\n\ntemplate<class _Eng, size_t _Wp, class _UI>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(\n    const independent_bits_engine<_Eng, _Wp, _UI>& __x,\n    const independent_bits_engine<_Eng, _Wp, _UI>& __y)\n{\n    return __x.base() == __y.base();\n}\n\ntemplate<class _Eng, size_t _Wp, class _UI>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(\n    const independent_bits_engine<_Eng, _Wp, _UI>& __x,\n    const independent_bits_engine<_Eng, _Wp, _UI>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _CharT, class _Traits,\n          class _Eng, size_t _Wp, class _UI>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const independent_bits_engine<_Eng, _Wp, _UI>& __x)\n{\n    return __os << __x.base();\n}\n\ntemplate <class _CharT, class _Traits,\n          class _Eng, size_t _Wp, class _UI>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           independent_bits_engine<_Eng, _Wp, _UI>& __x)\n{\n    _Eng __e;\n    __is >> __e;\n    if (!__is.fail())\n        __x.__e_ = __e;\n    return __is;\n}\n\n// shuffle_order_engine\n\ntemplate <uint64_t _Xp, uint64_t _Yp>\nstruct __ugcd\n{\n    static _LIBCPP_CONSTEXPR const uint64_t value = __ugcd<_Yp, _Xp % _Yp>::value;\n};\n\ntemplate <uint64_t _Xp>\nstruct __ugcd<_Xp, 0>\n{\n    static _LIBCPP_CONSTEXPR const uint64_t value = _Xp;\n};\n\ntemplate <uint64_t _Np, uint64_t _Dp>\nclass __uratio\n{\n    static_assert(_Dp != 0, \"__uratio divide by 0\");\n    static _LIBCPP_CONSTEXPR const uint64_t __gcd = __ugcd<_Np, _Dp>::value;\npublic:\n    static _LIBCPP_CONSTEXPR const uint64_t num = _Np / __gcd;\n    static _LIBCPP_CONSTEXPR const uint64_t den = _Dp / __gcd;\n\n    typedef __uratio<num, den> type;\n};\n\ntemplate<class _Engine, size_t __k>\nclass _LIBCPP_TYPE_VIS_ONLY shuffle_order_engine\n{\n    static_assert(0 < __k, \"shuffle_order_engine invalid parameters\");\npublic:\n    // types\n    typedef typename _Engine::result_type result_type;\n\nprivate:\n    _Engine __e_;\n    result_type _V_[__k];\n    result_type _Y_;\n\npublic:\n    // engine characteristics\n    static _LIBCPP_CONSTEXPR const size_t table_size = __k;\n\n#ifdef _LIBCPP_HAS_NO_CONSTEXPR\n    static const result_type _Min = _Engine::_Min;\n    static const result_type _Max = _Engine::_Max;\n#else\n    static _LIBCPP_CONSTEXPR const result_type _Min = _Engine::min();\n    static _LIBCPP_CONSTEXPR const result_type _Max = _Engine::max();\n#endif\n    static_assert(_Min < _Max, \"shuffle_order_engine invalid parameters\");\n    _LIBCPP_INLINE_VISIBILITY\n    static _LIBCPP_CONSTEXPR result_type min() { return _Min; }\n    _LIBCPP_INLINE_VISIBILITY\n    static _LIBCPP_CONSTEXPR result_type max() { return _Max; }\n\n    static _LIBCPP_CONSTEXPR const unsigned long long _Rp = _Max - _Min + 1ull;\n\n    // constructors and seeding functions\n    _LIBCPP_INLINE_VISIBILITY\n    shuffle_order_engine() {__init();}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit shuffle_order_engine(const _Engine& __e)\n        : __e_(__e) {__init();}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    explicit shuffle_order_engine(_Engine&& __e)\n        : __e_(_VSTD::move(__e)) {__init();}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    explicit shuffle_order_engine(result_type __sd) : __e_(__sd) {__init();}\n    template<class _Sseq>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit shuffle_order_engine(_Sseq& __q,\n        typename enable_if<__is_seed_sequence<_Sseq, shuffle_order_engine>::value &&\n                           !is_convertible<_Sseq, _Engine>::value>::type* = 0)\n         : __e_(__q) {__init();}\n    _LIBCPP_INLINE_VISIBILITY\n    void seed() {__e_.seed(); __init();}\n    _LIBCPP_INLINE_VISIBILITY\n    void seed(result_type __sd) {__e_.seed(__sd); __init();}\n    template<class _Sseq>\n        _LIBCPP_INLINE_VISIBILITY\n        typename enable_if\n        <\n            __is_seed_sequence<_Sseq, shuffle_order_engine>::value,\n            void\n        >::type\n        seed(_Sseq& __q) {__e_.seed(__q); __init();}\n\n    // generating functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}\n    _LIBCPP_INLINE_VISIBILITY\n    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    const _Engine& base() const _NOEXCEPT {return __e_;}\n\nprivate:\n    template<class _Eng, size_t _Kp>\n    friend\n    bool\n    operator==(\n        const shuffle_order_engine<_Eng, _Kp>& __x,\n        const shuffle_order_engine<_Eng, _Kp>& __y);\n\n    template<class _Eng, size_t _Kp>\n    friend\n    bool\n    operator!=(\n        const shuffle_order_engine<_Eng, _Kp>& __x,\n        const shuffle_order_engine<_Eng, _Kp>& __y);\n\n    template <class _CharT, class _Traits,\n              class _Eng, size_t _Kp>\n    friend\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os,\n               const shuffle_order_engine<_Eng, _Kp>& __x);\n\n    template <class _CharT, class _Traits,\n              class _Eng, size_t _Kp>\n    friend\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is,\n               shuffle_order_engine<_Eng, _Kp>& __x);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __init()\n    {\n        for (size_t __i = 0; __i < __k; ++__i)\n            _V_[__i] = __e_();\n        _Y_ = __e_();\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type __eval(false_type) {return __eval2(integral_constant<bool, __k & 1>());}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type __eval(true_type) {return __eval(__uratio<__k, _Rp>());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type __eval2(false_type) {return __eval(__uratio<__k/2, 0x8000000000000000ull>());}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type __eval2(true_type) {return __evalf<__k, 0>();}\n\n    template <uint64_t _Np, uint64_t _Dp>\n        _LIBCPP_INLINE_VISIBILITY\n        typename enable_if\n        <\n            (__uratio<_Np, _Dp>::num > 0xFFFFFFFFFFFFFFFFull / (_Max - _Min)),\n            result_type\n        >::type\n        __eval(__uratio<_Np, _Dp>)\n            {return __evalf<__uratio<_Np, _Dp>::num, __uratio<_Np, _Dp>::den>();}\n\n    template <uint64_t _Np, uint64_t _Dp>\n        _LIBCPP_INLINE_VISIBILITY\n        typename enable_if\n        <\n            __uratio<_Np, _Dp>::num <= 0xFFFFFFFFFFFFFFFFull / (_Max - _Min),\n            result_type\n        >::type\n        __eval(__uratio<_Np, _Dp>)\n        {\n            const size_t __j = static_cast<size_t>(__uratio<_Np, _Dp>::num * (_Y_ - _Min)\n                                                   / __uratio<_Np, _Dp>::den);\n            _Y_ = _V_[__j];\n            _V_[__j] = __e_();\n            return _Y_;\n        }\n\n    template <uint64_t __n, uint64_t __d>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type __evalf()\n        {\n            const double _Fp = __d == 0 ?\n                __n / (2. * 0x8000000000000000ull) :\n                __n / (double)__d;\n            const size_t __j = static_cast<size_t>(_Fp * (_Y_ - _Min));\n            _Y_ = _V_[__j];\n            _V_[__j] = __e_();\n            return _Y_;\n        }\n};\n\ntemplate<class _Engine, size_t __k>\n    _LIBCPP_CONSTEXPR const size_t shuffle_order_engine<_Engine, __k>::table_size;\n\ntemplate<class _Eng, size_t _Kp>\nbool\noperator==(\n    const shuffle_order_engine<_Eng, _Kp>& __x,\n    const shuffle_order_engine<_Eng, _Kp>& __y)\n{\n    return __x._Y_ == __y._Y_ && _VSTD::equal(__x._V_, __x._V_ + _Kp, __y._V_) &&\n           __x.__e_ == __y.__e_;\n}\n\ntemplate<class _Eng, size_t _Kp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(\n    const shuffle_order_engine<_Eng, _Kp>& __x,\n    const shuffle_order_engine<_Eng, _Kp>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _CharT, class _Traits,\n          class _Eng, size_t _Kp>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const shuffle_order_engine<_Eng, _Kp>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    __os << __x.__e_ << __sp << __x._V_[0];\n    for (size_t __i = 1; __i < _Kp; ++__i)\n        __os << __sp << __x._V_[__i];\n    return __os << __sp << __x._Y_;\n}\n\ntemplate <class _CharT, class _Traits,\n          class _Eng, size_t _Kp>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           shuffle_order_engine<_Eng, _Kp>& __x)\n{\n    typedef typename shuffle_order_engine<_Eng, _Kp>::result_type result_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    _Eng __e;\n    result_type _Vp[_Kp+1];\n    __is >> __e;\n    for (size_t __i = 0; __i < _Kp+1; ++__i)\n        __is >> _Vp[__i];\n    if (!__is.fail())\n    {\n        __x.__e_ = __e;\n        for (size_t __i = 0; __i < _Kp; ++__i)\n            __x._V_[__i] = _Vp[__i];\n        __x._Y_ = _Vp[_Kp];\n    }\n    return __is;\n}\n\ntypedef shuffle_order_engine<minstd_rand0, 256>                         knuth_b;\n\n// random_device\n\nclass _LIBCPP_TYPE_VIS random_device\n{\n#ifdef _LIBCPP_USING_DEV_RANDOM\n    int __f_;\n#endif // defined(_LIBCPP_USING_DEV_RANDOM)\npublic:\n    // types\n    typedef unsigned result_type;\n\n    // generator characteristics\n    static _LIBCPP_CONSTEXPR const result_type _Min = 0;\n    static _LIBCPP_CONSTEXPR const result_type _Max = 0xFFFFFFFFu;\n\n    _LIBCPP_INLINE_VISIBILITY\n    static _LIBCPP_CONSTEXPR result_type min() { return _Min;}\n    _LIBCPP_INLINE_VISIBILITY\n    static _LIBCPP_CONSTEXPR result_type max() { return _Max;}\n\n    // constructors\n    explicit random_device(const string& __token = \"/dev/urandom\");\n    ~random_device();\n\n    // generating functions\n    result_type operator()();\n\n    // property functions\n    double entropy() const _NOEXCEPT;\n\nprivate:\n    // no copy functions\n    random_device(const random_device&); // = delete;\n    random_device& operator=(const random_device&); // = delete;\n};\n\n// seed_seq\n\nclass _LIBCPP_TYPE_VIS_ONLY seed_seq\n{\npublic:\n    // types\n    typedef uint32_t result_type;\n\nprivate:\n    vector<result_type> __v_;\n\n    template<class _InputIterator>\n        void init(_InputIterator __first, _InputIterator __last);\npublic:\n    // constructors\n    _LIBCPP_INLINE_VISIBILITY\n    seed_seq() _NOEXCEPT {}\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    template<class _Tp>\n        _LIBCPP_INLINE_VISIBILITY\n        seed_seq(initializer_list<_Tp> __il) {init(__il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    template<class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        seed_seq(_InputIterator __first, _InputIterator __last)\n             {init(__first, __last);}\n\n    // generating functions\n    template<class _RandomAccessIterator>\n        void generate(_RandomAccessIterator __first, _RandomAccessIterator __last);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const _NOEXCEPT {return __v_.size();}\n    template<class _OutputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        void param(_OutputIterator __dest) const\n            {_VSTD::copy(__v_.begin(), __v_.end(), __dest);}\n\nprivate:\n    // no copy functions\n    seed_seq(const seed_seq&); // = delete;\n    void operator=(const seed_seq&); // = delete;\n\n    _LIBCPP_INLINE_VISIBILITY\n    static result_type _Tp(result_type __x) {return __x ^ (__x >> 27);}\n};\n\ntemplate<class _InputIterator>\nvoid\nseed_seq::init(_InputIterator __first, _InputIterator __last)\n{\n    for (_InputIterator __s = __first; __s != __last; ++__s)\n        __v_.push_back(*__s & 0xFFFFFFFF);\n}\n\ntemplate<class _RandomAccessIterator>\nvoid\nseed_seq::generate(_RandomAccessIterator __first, _RandomAccessIterator __last)\n{\n    if (__first != __last)\n    {\n        _VSTD::fill(__first, __last, 0x8b8b8b8b);\n        const size_t __n = static_cast<size_t>(__last - __first);\n        const size_t __s = __v_.size();\n        const size_t __t = (__n >= 623) ? 11\n                         : (__n >= 68) ? 7\n                         : (__n >= 39) ? 5\n                         : (__n >= 7)  ? 3\n                         : (__n - 1) / 2;\n        const size_t __p = (__n - __t) / 2;\n        const size_t __q = __p + __t;\n        const size_t __m = _VSTD::max(__s + 1, __n);\n        // __k = 0;\n        {\n            result_type __r = 1664525 * _Tp(__first[0] ^ __first[__p]\n                                                      ^  __first[__n - 1]);\n            __first[__p] += __r;\n            __r += __s;\n            __first[__q] += __r;\n            __first[0] = __r;\n        }\n        for (size_t __k = 1; __k <= __s; ++__k)\n        {\n            const size_t __kmodn = __k % __n;\n            const size_t __kpmodn = (__k + __p) % __n;\n            result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn]\n                                           ^ __first[(__k - 1) % __n]);\n            __first[__kpmodn] += __r;\n            __r +=  __kmodn + __v_[__k-1];\n            __first[(__k + __q) % __n] += __r;\n            __first[__kmodn] = __r;\n        }\n        for (size_t __k = __s + 1; __k < __m; ++__k)\n        {\n            const size_t __kmodn = __k % __n;\n            const size_t __kpmodn = (__k + __p) % __n;\n            result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn]\n                                           ^ __first[(__k - 1) % __n]);\n            __first[__kpmodn] += __r;\n            __r +=  __kmodn;\n            __first[(__k + __q) % __n] += __r;\n            __first[__kmodn] = __r;\n        }\n        for (size_t __k = __m; __k < __m + __n; ++__k)\n        {\n            const size_t __kmodn = __k % __n;\n            const size_t __kpmodn = (__k + __p) % __n;\n            result_type __r = 1566083941 * _Tp(__first[__kmodn] +\n                                              __first[__kpmodn] +\n                                              __first[(__k - 1) % __n]);\n            __first[__kpmodn] ^= __r;\n            __r -= __kmodn;\n            __first[(__k + __q) % __n] ^= __r;\n            __first[__kmodn] = __r;\n        }\n    }\n}\n\n// generate_canonical\n\ntemplate<class _RealType, size_t __bits, class _URNG>\n_RealType\ngenerate_canonical(_URNG& __g)\n{\n    const size_t _Dt = numeric_limits<_RealType>::digits;\n    const size_t __b = _Dt < __bits ? _Dt : __bits;\n#ifdef _LIBCPP_HAS_NO_CONSTEXPR\n    const size_t __logR = __log2<uint64_t, _URNG::_Max - _URNG::_Min + uint64_t(1)>::value;\n#else\n    const size_t __logR = __log2<uint64_t, _URNG::max() - _URNG::min() + uint64_t(1)>::value;\n#endif\n    const size_t __k = __b / __logR + (__b % __logR != 0) + (__b == 0);\n    const _RealType _Rp = _URNG::max() - _URNG::min() + _RealType(1);\n    _RealType __base = _Rp;\n    _RealType _Sp = __g() - _URNG::min();\n    for (size_t __i = 1; __i < __k; ++__i, __base *= _Rp)\n        _Sp += (__g() - _URNG::min()) * __base;\n    return _Sp / __base;\n}\n\n// uniform_int_distribution\n\n// in <algorithm>\n\ntemplate <class _CharT, class _Traits, class _IT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const uniform_int_distribution<_IT>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    return __os << __x.a() << __sp << __x.b();\n}\n\ntemplate <class _CharT, class _Traits, class _IT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           uniform_int_distribution<_IT>& __x)\n{\n    typedef uniform_int_distribution<_IT> _Eng;\n    typedef typename _Eng::result_type result_type;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    result_type __a;\n    result_type __b;\n    __is >> __a >> __b;\n    if (!__is.fail())\n        __x.param(param_type(__a, __b));\n    return __is;\n}\n\n// uniform_real_distribution\n\ntemplate<class _RealType = double>\nclass _LIBCPP_TYPE_VIS_ONLY uniform_real_distribution\n{\npublic:\n    // types\n    typedef _RealType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        result_type __a_;\n        result_type __b_;\n    public:\n        typedef uniform_real_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        explicit param_type(result_type __a = 0,\n                            result_type __b = 1)\n            : __a_(__a), __b_(__b) {}\n\n        _LIBCPP_INLINE_VISIBILITY\n        result_type a() const {return __a_;}\n        _LIBCPP_INLINE_VISIBILITY\n        result_type b() const {return __b_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructors and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit uniform_real_distribution(result_type __a = 0, result_type __b = 1)\n        : __p_(param_type(__a, __b)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit uniform_real_distribution(const param_type& __p) : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type a() const {return __p_.a();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type b() const {return __p_.b();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return a();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return b();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const uniform_real_distribution& __x,\n                        const uniform_real_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const uniform_real_distribution& __x,\n                        const uniform_real_distribution& __y)\n        {return !(__x == __y);}\n};\n\ntemplate<class _RealType>\ntemplate<class _URNG>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename uniform_real_distribution<_RealType>::result_type\nuniform_real_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)\n{\n    return (__p.b() - __p.a())\n        * _VSTD::generate_canonical<_RealType, numeric_limits<_RealType>::digits>(__g)\n        + __p.a();\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const uniform_real_distribution<_RT>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    return __os << __x.a() << __sp << __x.b();\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           uniform_real_distribution<_RT>& __x)\n{\n    typedef uniform_real_distribution<_RT> _Eng;\n    typedef typename _Eng::result_type result_type;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    result_type __a;\n    result_type __b;\n    __is >> __a >> __b;\n    if (!__is.fail())\n        __x.param(param_type(__a, __b));\n    return __is;\n}\n\n// bernoulli_distribution\n\nclass _LIBCPP_TYPE_VIS_ONLY bernoulli_distribution\n{\npublic:\n    // types\n    typedef bool result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        double __p_;\n    public:\n        typedef bernoulli_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        explicit param_type(double __p = 0.5) : __p_(__p) {}\n\n        _LIBCPP_INLINE_VISIBILITY\n        double p() const {return __p_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__p_ == __y.__p_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructors and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit bernoulli_distribution(double __p = 0.5)\n        : __p_(param_type(__p)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit bernoulli_distribution(const param_type& __p) : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    double p() const {return __p_.p();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return false;}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return true;}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const bernoulli_distribution& __x,\n                        const bernoulli_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const bernoulli_distribution& __x,\n                        const bernoulli_distribution& __y)\n        {return !(__x == __y);}\n};\n\ntemplate<class _URNG>\ninline _LIBCPP_INLINE_VISIBILITY\nbernoulli_distribution::result_type\nbernoulli_distribution::operator()(_URNG& __g, const param_type& __p)\n{\n    uniform_real_distribution<double> __gen;\n    return __gen(__g) < __p.p();\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os, const bernoulli_distribution& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    return __os << __x.p();\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is, bernoulli_distribution& __x)\n{\n    typedef bernoulli_distribution _Eng;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    double __p;\n    __is >> __p;\n    if (!__is.fail())\n        __x.param(param_type(__p));\n    return __is;\n}\n\n// binomial_distribution\n\ntemplate<class _IntType = int>\nclass _LIBCPP_TYPE_VIS_ONLY binomial_distribution\n{\npublic:\n    // types\n    typedef _IntType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        result_type __t_;\n        double __p_;\n        double __pr_;\n        double __odds_ratio_;\n        result_type __r0_;\n    public:\n        typedef binomial_distribution distribution_type;\n\n        explicit param_type(result_type __t = 1, double __p = 0.5);\n\n        _LIBCPP_INLINE_VISIBILITY\n        result_type t() const {return __t_;}\n        _LIBCPP_INLINE_VISIBILITY\n        double p() const {return __p_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__t_ == __y.__t_ && __x.__p_ == __y.__p_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n\n        friend class binomial_distribution;\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructors and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit binomial_distribution(result_type __t = 1, double __p = 0.5)\n        : __p_(param_type(__t, __p)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit binomial_distribution(const param_type& __p) : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type t() const {return __p_.t();}\n    _LIBCPP_INLINE_VISIBILITY\n    double p() const {return __p_.p();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return t();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const binomial_distribution& __x,\n                        const binomial_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const binomial_distribution& __x,\n                        const binomial_distribution& __y)\n        {return !(__x == __y);}\n};\n\ntemplate<class _IntType>\nbinomial_distribution<_IntType>::param_type::param_type(result_type __t, double __p)\n    : __t_(__t), __p_(__p)\n{\n    if (0 < __p_ && __p_ < 1)\n    {\n        __r0_ = static_cast<result_type>((__t_ + 1) * __p_);\n        __pr_ = _VSTD::exp(_VSTD::lgamma(__t_ + 1.) - _VSTD::lgamma(__r0_ + 1.) -\n                          _VSTD::lgamma(__t_ - __r0_ + 1.) + __r0_ * _VSTD::log(__p_) +\n                          (__t_ - __r0_) * _VSTD::log(1 - __p_));\n        __odds_ratio_ = __p_ / (1 - __p_);\n    }\n}\n\n// Reference: Kemp, C.D. (1986). `A modal method for generating binomial\n//           variables', Commun. Statist. - Theor. Meth. 15(3), 805-813.\ntemplate<class _IntType>\ntemplate<class _URNG>\n_IntType\nbinomial_distribution<_IntType>::operator()(_URNG& __g, const param_type& __pr)\n{\n    if (__pr.__t_ == 0 || __pr.__p_ == 0)\n        return 0;\n    if (__pr.__p_ == 1)\n        return __pr.__t_;\n    uniform_real_distribution<double> __gen;\n    double __u = __gen(__g) - __pr.__pr_;\n    if (__u < 0)\n        return __pr.__r0_;\n    double __pu = __pr.__pr_;\n    double __pd = __pu;\n    result_type __ru = __pr.__r0_;\n    result_type __rd = __ru;\n    while (true)\n    {\n        if (__rd >= 1)\n        {\n            __pd *= __rd / (__pr.__odds_ratio_ * (__pr.__t_ - __rd + 1));\n            __u -= __pd;\n            if (__u < 0)\n                return __rd - 1;\n        }\n        if ( __rd != 0 )\n            --__rd;\n        ++__ru;\n        if (__ru <= __pr.__t_)\n        {\n            __pu *= (__pr.__t_ - __ru + 1) * __pr.__odds_ratio_ / __ru;\n            __u -= __pu;\n            if (__u < 0)\n                return __ru;\n        }\n    }\n}\n\ntemplate <class _CharT, class _Traits, class _IntType>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const binomial_distribution<_IntType>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    return __os << __x.t() << __sp << __x.p();\n}\n\ntemplate <class _CharT, class _Traits, class _IntType>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           binomial_distribution<_IntType>& __x)\n{\n    typedef binomial_distribution<_IntType> _Eng;\n    typedef typename _Eng::result_type result_type;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    result_type __t;\n    double __p;\n    __is >> __t >> __p;\n    if (!__is.fail())\n        __x.param(param_type(__t, __p));\n    return __is;\n}\n\n// exponential_distribution\n\ntemplate<class _RealType = double>\nclass _LIBCPP_TYPE_VIS_ONLY exponential_distribution\n{\npublic:\n    // types\n    typedef _RealType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        result_type __lambda_;\n    public:\n        typedef exponential_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        explicit param_type(result_type __lambda = 1) : __lambda_(__lambda) {}\n\n        _LIBCPP_INLINE_VISIBILITY\n        result_type lambda() const {return __lambda_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__lambda_ == __y.__lambda_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructors and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit exponential_distribution(result_type __lambda = 1)\n        : __p_(param_type(__lambda)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit exponential_distribution(const param_type& __p) : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type lambda() const {return __p_.lambda();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return numeric_limits<result_type>::infinity();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const exponential_distribution& __x,\n                        const exponential_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const exponential_distribution& __x,\n                        const exponential_distribution& __y)\n        {return !(__x == __y);}\n};\n\ntemplate <class _RealType>\ntemplate<class _URNG>\n_RealType\nexponential_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)\n{\n    return -_VSTD::log\n                  (\n                      result_type(1) -\n                      _VSTD::generate_canonical<result_type,\n                                       numeric_limits<result_type>::digits>(__g)\n                  )\n                  / __p.lambda();\n}\n\ntemplate <class _CharT, class _Traits, class _RealType>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const exponential_distribution<_RealType>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    return __os << __x.lambda();\n}\n\ntemplate <class _CharT, class _Traits, class _RealType>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           exponential_distribution<_RealType>& __x)\n{\n    typedef exponential_distribution<_RealType> _Eng;\n    typedef typename _Eng::result_type result_type;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    result_type __lambda;\n    __is >> __lambda;\n    if (!__is.fail())\n        __x.param(param_type(__lambda));\n    return __is;\n}\n\n// normal_distribution\n\ntemplate<class _RealType = double>\nclass _LIBCPP_TYPE_VIS_ONLY normal_distribution\n{\npublic:\n    // types\n    typedef _RealType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        result_type __mean_;\n        result_type __stddev_;\n    public:\n        typedef normal_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        explicit param_type(result_type __mean = 0, result_type __stddev = 1)\n            : __mean_(__mean), __stddev_(__stddev) {}\n\n        _LIBCPP_INLINE_VISIBILITY\n        result_type mean() const {return __mean_;}\n        _LIBCPP_INLINE_VISIBILITY\n        result_type stddev() const {return __stddev_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__mean_ == __y.__mean_ && __x.__stddev_ == __y.__stddev_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n    };\n\nprivate:\n    param_type __p_;\n    result_type _V_;\n    bool _V_hot_;\n\npublic:\n    // constructors and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit normal_distribution(result_type __mean = 0, result_type __stddev = 1)\n        : __p_(param_type(__mean, __stddev)), _V_hot_(false) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit normal_distribution(const param_type& __p)\n        : __p_(__p), _V_hot_(false) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {_V_hot_ = false;}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type mean() const {return __p_.mean();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type stddev() const {return __p_.stddev();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return -numeric_limits<result_type>::infinity();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return numeric_limits<result_type>::infinity();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const normal_distribution& __x,\n                        const normal_distribution& __y)\n        {return __x.__p_ == __y.__p_ && __x._V_hot_ == __y._V_hot_ &&\n                (!__x._V_hot_ || __x._V_ == __y._V_);}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const normal_distribution& __x,\n                        const normal_distribution& __y)\n        {return !(__x == __y);}\n\n    template <class _CharT, class _Traits, class _RT>\n    friend\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os,\n               const normal_distribution<_RT>& __x);\n\n    template <class _CharT, class _Traits, class _RT>\n    friend\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is,\n               normal_distribution<_RT>& __x);\n};\n\ntemplate <class _RealType>\ntemplate<class _URNG>\n_RealType\nnormal_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)\n{\n    result_type _Up;\n    if (_V_hot_)\n    {\n        _V_hot_ = false;\n        _Up = _V_;\n    }\n    else\n    {\n        uniform_real_distribution<result_type> _Uni(-1, 1);\n        result_type __u;\n        result_type __v;\n        result_type __s;\n        do\n        {\n            __u = _Uni(__g);\n            __v = _Uni(__g);\n            __s = __u * __u + __v * __v;\n        } while (__s > 1 || __s == 0);\n        result_type _Fp = _VSTD::sqrt(-2 * _VSTD::log(__s) / __s);\n        _V_ = __v * _Fp;\n        _V_hot_ = true;\n        _Up = __u * _Fp;\n    }\n    return _Up * __p.stddev() + __p.mean();\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const normal_distribution<_RT>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    __os << __x.mean() << __sp << __x.stddev() << __sp << __x._V_hot_;\n    if (__x._V_hot_)\n        __os << __sp << __x._V_;\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           normal_distribution<_RT>& __x)\n{\n    typedef normal_distribution<_RT> _Eng;\n    typedef typename _Eng::result_type result_type;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    result_type __mean;\n    result_type __stddev;\n    result_type _Vp = 0;\n    bool _V_hot = false;\n    __is >> __mean >> __stddev >> _V_hot;\n    if (_V_hot)\n        __is >> _Vp;\n    if (!__is.fail())\n    {\n        __x.param(param_type(__mean, __stddev));\n        __x._V_hot_ = _V_hot;\n        __x._V_ = _Vp;\n    }\n    return __is;\n}\n\n// lognormal_distribution\n\ntemplate<class _RealType = double>\nclass _LIBCPP_TYPE_VIS_ONLY lognormal_distribution\n{\npublic:\n    // types\n    typedef _RealType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        normal_distribution<result_type> __nd_;\n    public:\n        typedef lognormal_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        explicit param_type(result_type __m = 0, result_type __s = 1)\n            : __nd_(__m, __s) {}\n\n        _LIBCPP_INLINE_VISIBILITY\n        result_type m() const {return __nd_.mean();}\n        _LIBCPP_INLINE_VISIBILITY\n        result_type s() const {return __nd_.stddev();}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__nd_ == __y.__nd_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n        friend class lognormal_distribution;\n\n        template <class _CharT, class _Traits, class _RT>\n        friend\n        basic_ostream<_CharT, _Traits>&\n        operator<<(basic_ostream<_CharT, _Traits>& __os,\n                   const lognormal_distribution<_RT>& __x);\n\n        template <class _CharT, class _Traits, class _RT>\n        friend\n        basic_istream<_CharT, _Traits>&\n        operator>>(basic_istream<_CharT, _Traits>& __is,\n                   lognormal_distribution<_RT>& __x);\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructor and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit lognormal_distribution(result_type __m = 0, result_type __s = 1)\n        : __p_(param_type(__m, __s)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit lognormal_distribution(const param_type& __p)\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {__p_.__nd_.reset();}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g, const param_type& __p)\n        {return _VSTD::exp(const_cast<normal_distribution<result_type>&>(__p.__nd_)(__g));}\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type m() const {return __p_.m();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type s() const {return __p_.s();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return numeric_limits<result_type>::infinity();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const lognormal_distribution& __x,\n                        const lognormal_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const lognormal_distribution& __x,\n                        const lognormal_distribution& __y)\n        {return !(__x == __y);}\n\n    template <class _CharT, class _Traits, class _RT>\n    friend\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os,\n               const lognormal_distribution<_RT>& __x);\n\n    template <class _CharT, class _Traits, class _RT>\n    friend\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is,\n               lognormal_distribution<_RT>& __x);\n};\n\ntemplate <class _CharT, class _Traits, class _RT>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const lognormal_distribution<_RT>& __x)\n{\n    return __os << __x.__p_.__nd_;\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           lognormal_distribution<_RT>& __x)\n{\n    return __is >> __x.__p_.__nd_;\n}\n\n// poisson_distribution\n\ntemplate<class _IntType = int>\nclass _LIBCPP_TYPE_VIS_ONLY poisson_distribution\n{\npublic:\n    // types\n    typedef _IntType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        double __mean_;\n        double __s_;\n        double __d_;\n        double __l_;\n        double __omega_;\n        double __c0_;\n        double __c1_;\n        double __c2_;\n        double __c3_;\n        double __c_;\n\n    public:\n        typedef poisson_distribution distribution_type;\n\n        explicit param_type(double __mean = 1.0);\n\n        _LIBCPP_INLINE_VISIBILITY\n        double mean() const {return __mean_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__mean_ == __y.__mean_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n\n        friend class poisson_distribution;\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructors and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit poisson_distribution(double __mean = 1.0) : __p_(__mean) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit poisson_distribution(const param_type& __p) : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    double mean() const {return __p_.mean();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return numeric_limits<result_type>::max();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const poisson_distribution& __x,\n                        const poisson_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const poisson_distribution& __x,\n                        const poisson_distribution& __y)\n        {return !(__x == __y);}\n};\n\ntemplate<class _IntType>\npoisson_distribution<_IntType>::param_type::param_type(double __mean)\n    : __mean_(__mean)\n{\n    if (__mean_ < 10)\n    {\n        __s_ = 0;\n        __d_ = 0;\n        __l_ = _VSTD::exp(-__mean_);\n        __omega_ = 0;\n        __c3_ = 0;\n        __c2_ = 0;\n        __c1_ = 0;\n        __c0_ = 0;\n        __c_ = 0;\n    }\n    else\n    {\n        __s_ = _VSTD::sqrt(__mean_);\n        __d_ = 6 * __mean_ * __mean_;\n        __l_ = static_cast<result_type>(__mean_ - 1.1484);\n        __omega_ = .3989423 / __s_;\n        double __b1_ = .4166667E-1 / __mean_;\n        double __b2_ = .3 * __b1_ * __b1_;\n        __c3_ = .1428571 * __b1_ * __b2_;\n        __c2_ = __b2_ - 15. * __c3_;\n        __c1_ = __b1_ - 6. * __b2_ + 45. * __c3_;\n        __c0_ = 1. - __b1_ + 3. * __b2_ - 15. * __c3_;\n        __c_ = .1069 / __mean_;\n    }\n}\n\ntemplate <class _IntType>\ntemplate<class _URNG>\n_IntType\npoisson_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr)\n{\n    result_type __x;\n    uniform_real_distribution<double> __urd;\n    if (__pr.__mean_ < 10)\n    {\n         __x = 0;\n        for (double __p = __urd(__urng); __p > __pr.__l_; ++__x)\n            __p *= __urd(__urng);\n    }\n    else\n    {\n        double __difmuk;\n        double __g = __pr.__mean_ + __pr.__s_ * normal_distribution<double>()(__urng);\n        double __u;\n        if (__g > 0)\n        {\n            __x = static_cast<result_type>(__g);\n            if (__x >= __pr.__l_)\n                return __x;\n            __difmuk = __pr.__mean_ - __x;\n            __u = __urd(__urng);\n            if (__pr.__d_ * __u >= __difmuk * __difmuk * __difmuk)\n                return __x;\n        }\n        exponential_distribution<double> __edist;\n        for (bool __using_exp_dist = false; true; __using_exp_dist = true)\n        {\n            double __e;\n            if (__using_exp_dist || __g < 0)\n            {\n                double __t;\n                do\n                {\n                    __e = __edist(__urng);\n                    __u = __urd(__urng);\n                    __u += __u - 1;\n                    __t = 1.8 + (__u < 0 ? -__e : __e);\n                } while (__t <= -.6744);\n                __x = __pr.__mean_ + __pr.__s_ * __t;\n                __difmuk = __pr.__mean_ - __x;\n                __using_exp_dist = true;\n            }\n            double __px;\n            double __py;\n            if (__x < 10)\n            {\n                const result_type __fac[] = {1, 1, 2, 6, 24, 120, 720, 5040,\n                                             40320, 362880};\n                __px = -__pr.__mean_;\n                __py = _VSTD::pow(__pr.__mean_, (double)__x) / __fac[__x];\n            }\n            else\n            {\n                double __del = .8333333E-1 / __x;\n                __del -= 4.8 * __del * __del * __del;\n                double __v = __difmuk / __x;\n                if (_VSTD::abs(__v) > 0.25)\n                    __px = __x * _VSTD::log(1 + __v) - __difmuk - __del;\n                else\n                    __px = __x * __v * __v * (((((((.1250060 * __v + -.1384794) *\n                           __v + .1421878) * __v + -.1661269) * __v + .2000118) *\n                           __v + -.2500068) * __v + .3333333) * __v + -.5) - __del;\n                __py = .3989423 / _VSTD::sqrt(__x);\n            }\n            double __r = (0.5 - __difmuk) / __pr.__s_;\n            double __r2 = __r * __r;\n            double __fx = -0.5 * __r2;\n            double __fy = __pr.__omega_ * (((__pr.__c3_ * __r2 + __pr.__c2_) *\n                                        __r2 + __pr.__c1_) * __r2 + __pr.__c0_);\n            if (__using_exp_dist)\n            {\n                if (__pr.__c_ * _VSTD::abs(__u) <= __py * _VSTD::exp(__px + __e) -\n                                                   __fy * _VSTD::exp(__fx + __e))\n                    break;\n            }\n            else\n            {\n                if (__fy - __u * __fy <= __py * _VSTD::exp(__px - __fx))\n                    break;\n            }\n        }\n    }\n    return __x;\n}\n\ntemplate <class _CharT, class _Traits, class _IntType>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const poisson_distribution<_IntType>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    return __os << __x.mean();\n}\n\ntemplate <class _CharT, class _Traits, class _IntType>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           poisson_distribution<_IntType>& __x)\n{\n    typedef poisson_distribution<_IntType> _Eng;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    double __mean;\n    __is >> __mean;\n    if (!__is.fail())\n        __x.param(param_type(__mean));\n    return __is;\n}\n\n// weibull_distribution\n\ntemplate<class _RealType = double>\nclass _LIBCPP_TYPE_VIS_ONLY weibull_distribution\n{\npublic:\n    // types\n    typedef _RealType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        result_type __a_;\n        result_type __b_;\n    public:\n        typedef weibull_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        explicit param_type(result_type __a = 1, result_type __b = 1)\n            : __a_(__a), __b_(__b) {}\n\n        _LIBCPP_INLINE_VISIBILITY\n        result_type a() const {return __a_;}\n        _LIBCPP_INLINE_VISIBILITY\n        result_type b() const {return __b_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructor and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit weibull_distribution(result_type __a = 1, result_type __b = 1)\n        : __p_(param_type(__a, __b)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit weibull_distribution(const param_type& __p)\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g, const param_type& __p)\n        {return __p.b() *\n            _VSTD::pow(exponential_distribution<result_type>()(__g), 1/__p.a());}\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type a() const {return __p_.a();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type b() const {return __p_.b();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return numeric_limits<result_type>::infinity();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const weibull_distribution& __x,\n                        const weibull_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const weibull_distribution& __x,\n                        const weibull_distribution& __y)\n        {return !(__x == __y);}\n};\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const weibull_distribution<_RT>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    __os << __x.a() << __sp << __x.b();\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           weibull_distribution<_RT>& __x)\n{\n    typedef weibull_distribution<_RT> _Eng;\n    typedef typename _Eng::result_type result_type;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    result_type __a;\n    result_type __b;\n    __is >> __a >> __b;\n    if (!__is.fail())\n        __x.param(param_type(__a, __b));\n    return __is;\n}\n\ntemplate<class _RealType = double>\nclass _LIBCPP_TYPE_VIS_ONLY extreme_value_distribution\n{\npublic:\n    // types\n    typedef _RealType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        result_type __a_;\n        result_type __b_;\n    public:\n        typedef extreme_value_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        explicit param_type(result_type __a = 0, result_type __b = 1)\n            : __a_(__a), __b_(__b) {}\n\n        _LIBCPP_INLINE_VISIBILITY\n        result_type a() const {return __a_;}\n        _LIBCPP_INLINE_VISIBILITY\n        result_type b() const {return __b_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructor and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit extreme_value_distribution(result_type __a = 0, result_type __b = 1)\n        : __p_(param_type(__a, __b)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit extreme_value_distribution(const param_type& __p)\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type a() const {return __p_.a();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type b() const {return __p_.b();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return -numeric_limits<result_type>::infinity();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return numeric_limits<result_type>::infinity();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const extreme_value_distribution& __x,\n                        const extreme_value_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const extreme_value_distribution& __x,\n                        const extreme_value_distribution& __y)\n        {return !(__x == __y);}\n};\n\ntemplate<class _RealType>\ntemplate<class _URNG>\n_RealType\nextreme_value_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)\n{\n    return __p.a() - __p.b() *\n         _VSTD::log(-_VSTD::log(1-uniform_real_distribution<result_type>()(__g)));\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const extreme_value_distribution<_RT>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    __os << __x.a() << __sp << __x.b();\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           extreme_value_distribution<_RT>& __x)\n{\n    typedef extreme_value_distribution<_RT> _Eng;\n    typedef typename _Eng::result_type result_type;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    result_type __a;\n    result_type __b;\n    __is >> __a >> __b;\n    if (!__is.fail())\n        __x.param(param_type(__a, __b));\n    return __is;\n}\n\n// gamma_distribution\n\ntemplate<class _RealType = double>\nclass _LIBCPP_TYPE_VIS_ONLY gamma_distribution\n{\npublic:\n    // types\n    typedef _RealType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        result_type __alpha_;\n        result_type __beta_;\n    public:\n        typedef gamma_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        explicit param_type(result_type __alpha = 1, result_type __beta = 1)\n            : __alpha_(__alpha), __beta_(__beta) {}\n\n        _LIBCPP_INLINE_VISIBILITY\n        result_type alpha() const {return __alpha_;}\n        _LIBCPP_INLINE_VISIBILITY\n        result_type beta() const {return __beta_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__alpha_ == __y.__alpha_ && __x.__beta_ == __y.__beta_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructors and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit gamma_distribution(result_type __alpha = 1, result_type __beta = 1)\n        : __p_(param_type(__alpha, __beta)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit gamma_distribution(const param_type& __p)\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type alpha() const {return __p_.alpha();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type beta() const {return __p_.beta();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return numeric_limits<result_type>::infinity();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const gamma_distribution& __x,\n                        const gamma_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const gamma_distribution& __x,\n                        const gamma_distribution& __y)\n        {return !(__x == __y);}\n};\n\ntemplate <class _RealType>\ntemplate<class _URNG>\n_RealType\ngamma_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)\n{\n    result_type __a = __p.alpha();\n    uniform_real_distribution<result_type> __gen(0, 1);\n    exponential_distribution<result_type> __egen;\n    result_type __x;\n    if (__a == 1)\n        __x = __egen(__g);\n    else if (__a > 1)\n    {\n        const result_type __b = __a - 1;\n        const result_type __c = 3 * __a - result_type(0.75);\n        while (true)\n        {\n            const result_type __u = __gen(__g);\n            const result_type __v = __gen(__g);\n            const result_type __w = __u * (1 - __u);\n            if (__w != 0)\n            {\n                const result_type __y = _VSTD::sqrt(__c / __w) *\n                                        (__u - result_type(0.5));\n                __x = __b + __y;\n                if (__x >= 0)\n                {\n                    const result_type __z = 64 * __w * __w * __w * __v * __v;\n                    if (__z <= 1 - 2 * __y * __y / __x)\n                        break;\n                    if (_VSTD::log(__z) <= 2 * (__b * _VSTD::log(__x / __b) - __y))\n                        break;\n                }\n            }\n        }\n    }\n    else  // __a < 1\n    {\n        while (true)\n        {\n            const result_type __u = __gen(__g);\n            const result_type __es = __egen(__g);\n            if (__u <= 1 - __a)\n            {\n                __x = _VSTD::pow(__u, 1 / __a);\n                if (__x <= __es)\n                    break;\n            }\n            else\n            {\n                const result_type __e = -_VSTD::log((1-__u)/__a);\n                __x = _VSTD::pow(1 - __a + __a * __e, 1 / __a);\n                if (__x <= __e + __es)\n                    break;\n            }\n        }\n    }\n    return __x * __p.beta();\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const gamma_distribution<_RT>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    __os << __x.alpha() << __sp << __x.beta();\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           gamma_distribution<_RT>& __x)\n{\n    typedef gamma_distribution<_RT> _Eng;\n    typedef typename _Eng::result_type result_type;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    result_type __alpha;\n    result_type __beta;\n    __is >> __alpha >> __beta;\n    if (!__is.fail())\n        __x.param(param_type(__alpha, __beta));\n    return __is;\n}\n\n// negative_binomial_distribution\n\ntemplate<class _IntType = int>\nclass _LIBCPP_TYPE_VIS_ONLY negative_binomial_distribution\n{\npublic:\n    // types\n    typedef _IntType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        result_type __k_;\n        double __p_;\n    public:\n        typedef negative_binomial_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        explicit param_type(result_type __k = 1, double __p = 0.5)\n            : __k_(__k), __p_(__p) {}\n\n        _LIBCPP_INLINE_VISIBILITY\n        result_type k() const {return __k_;}\n        _LIBCPP_INLINE_VISIBILITY\n        double p() const {return __p_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__k_ == __y.__k_ && __x.__p_ == __y.__p_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructor and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit negative_binomial_distribution(result_type __k = 1, double __p = 0.5)\n        : __p_(__k, __p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit negative_binomial_distribution(const param_type& __p) : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type k() const {return __p_.k();}\n    _LIBCPP_INLINE_VISIBILITY\n    double p() const {return __p_.p();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return numeric_limits<result_type>::max();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const negative_binomial_distribution& __x,\n                        const negative_binomial_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const negative_binomial_distribution& __x,\n                        const negative_binomial_distribution& __y)\n        {return !(__x == __y);}\n};\n\ntemplate <class _IntType>\ntemplate<class _URNG>\n_IntType\nnegative_binomial_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr)\n{\n    result_type __k = __pr.k();\n    double __p = __pr.p();\n    if (__k <= 21 * __p)\n    {\n        bernoulli_distribution __gen(__p);\n        result_type __f = 0;\n        result_type __s = 0;\n        while (__s < __k)\n        {\n            if (__gen(__urng))\n                ++__s;\n            else\n                ++__f;\n        }\n        return __f;\n    }\n    return poisson_distribution<result_type>(gamma_distribution<double>\n                                            (__k, (1-__p)/__p)(__urng))(__urng);\n}\n\ntemplate <class _CharT, class _Traits, class _IntType>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const negative_binomial_distribution<_IntType>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    return __os << __x.k() << __sp << __x.p();\n}\n\ntemplate <class _CharT, class _Traits, class _IntType>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           negative_binomial_distribution<_IntType>& __x)\n{\n    typedef negative_binomial_distribution<_IntType> _Eng;\n    typedef typename _Eng::result_type result_type;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    result_type __k;\n    double __p;\n    __is >> __k >> __p;\n    if (!__is.fail())\n        __x.param(param_type(__k, __p));\n    return __is;\n}\n\n// geometric_distribution\n\ntemplate<class _IntType = int>\nclass _LIBCPP_TYPE_VIS_ONLY geometric_distribution\n{\npublic:\n    // types\n    typedef _IntType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        double __p_;\n    public:\n        typedef geometric_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        explicit param_type(double __p = 0.5) : __p_(__p) {}\n\n        _LIBCPP_INLINE_VISIBILITY\n        double p() const {return __p_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__p_ == __y.__p_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructors and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit geometric_distribution(double __p = 0.5) : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit geometric_distribution(const param_type& __p) : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g, const param_type& __p)\n        {return negative_binomial_distribution<result_type>(1, __p.p())(__g);}\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    double p() const {return __p_.p();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return numeric_limits<result_type>::max();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const geometric_distribution& __x,\n                        const geometric_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const geometric_distribution& __x,\n                        const geometric_distribution& __y)\n        {return !(__x == __y);}\n};\n\ntemplate <class _CharT, class _Traits, class _IntType>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const geometric_distribution<_IntType>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    return __os << __x.p();\n}\n\ntemplate <class _CharT, class _Traits, class _IntType>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           geometric_distribution<_IntType>& __x)\n{\n    typedef geometric_distribution<_IntType> _Eng;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    double __p;\n    __is >> __p;\n    if (!__is.fail())\n        __x.param(param_type(__p));\n    return __is;\n}\n\n// chi_squared_distribution\n\ntemplate<class _RealType = double>\nclass _LIBCPP_TYPE_VIS_ONLY chi_squared_distribution\n{\npublic:\n    // types\n    typedef _RealType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        result_type __n_;\n    public:\n        typedef chi_squared_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        explicit param_type(result_type __n = 1) : __n_(__n) {}\n\n        _LIBCPP_INLINE_VISIBILITY\n        result_type n() const {return __n_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__n_ == __y.__n_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructor and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit chi_squared_distribution(result_type __n = 1)\n        : __p_(param_type(__n)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit chi_squared_distribution(const param_type& __p)\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g, const param_type& __p)\n        {return gamma_distribution<result_type>(__p.n() / 2, 2)(__g);}\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type n() const {return __p_.n();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return numeric_limits<result_type>::infinity();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const chi_squared_distribution& __x,\n                        const chi_squared_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const chi_squared_distribution& __x,\n                        const chi_squared_distribution& __y)\n        {return !(__x == __y);}\n};\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const chi_squared_distribution<_RT>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    __os << __x.n();\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           chi_squared_distribution<_RT>& __x)\n{\n    typedef chi_squared_distribution<_RT> _Eng;\n    typedef typename _Eng::result_type result_type;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    result_type __n;\n    __is >> __n;\n    if (!__is.fail())\n        __x.param(param_type(__n));\n    return __is;\n}\n\n// cauchy_distribution\n\ntemplate<class _RealType = double>\nclass _LIBCPP_TYPE_VIS_ONLY cauchy_distribution\n{\npublic:\n    // types\n    typedef _RealType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        result_type __a_;\n        result_type __b_;\n    public:\n        typedef cauchy_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        explicit param_type(result_type __a = 0, result_type __b = 1)\n            : __a_(__a), __b_(__b) {}\n\n        _LIBCPP_INLINE_VISIBILITY\n        result_type a() const {return __a_;}\n        _LIBCPP_INLINE_VISIBILITY\n        result_type b() const {return __b_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructor and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit cauchy_distribution(result_type __a = 0, result_type __b = 1)\n        : __p_(param_type(__a, __b)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit cauchy_distribution(const param_type& __p)\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type a() const {return __p_.a();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type b() const {return __p_.b();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return -numeric_limits<result_type>::infinity();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return numeric_limits<result_type>::infinity();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const cauchy_distribution& __x,\n                        const cauchy_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const cauchy_distribution& __x,\n                        const cauchy_distribution& __y)\n        {return !(__x == __y);}\n};\n\ntemplate <class _RealType>\ntemplate<class _URNG>\ninline _LIBCPP_INLINE_VISIBILITY\n_RealType\ncauchy_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)\n{\n    uniform_real_distribution<result_type> __gen;\n    // purposefully let tan arg get as close to pi/2 as it wants, tan will return a finite\n    return __p.a() + __p.b() * _VSTD::tan(3.1415926535897932384626433832795 * __gen(__g));\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const cauchy_distribution<_RT>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    __os << __x.a() << __sp << __x.b();\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           cauchy_distribution<_RT>& __x)\n{\n    typedef cauchy_distribution<_RT> _Eng;\n    typedef typename _Eng::result_type result_type;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    result_type __a;\n    result_type __b;\n    __is >> __a >> __b;\n    if (!__is.fail())\n        __x.param(param_type(__a, __b));\n    return __is;\n}\n\n// fisher_f_distribution\n\ntemplate<class _RealType = double>\nclass _LIBCPP_TYPE_VIS_ONLY fisher_f_distribution\n{\npublic:\n    // types\n    typedef _RealType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        result_type __m_;\n        result_type __n_;\n    public:\n        typedef fisher_f_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        explicit param_type(result_type __m = 1, result_type __n = 1)\n            : __m_(__m), __n_(__n) {}\n\n        _LIBCPP_INLINE_VISIBILITY\n        result_type m() const {return __m_;}\n        _LIBCPP_INLINE_VISIBILITY\n        result_type n() const {return __n_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__m_ == __y.__m_ && __x.__n_ == __y.__n_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructor and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit fisher_f_distribution(result_type __m = 1, result_type __n = 1)\n        : __p_(param_type(__m, __n)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit fisher_f_distribution(const param_type& __p)\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type m() const {return __p_.m();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type n() const {return __p_.n();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return numeric_limits<result_type>::infinity();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const fisher_f_distribution& __x,\n                        const fisher_f_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const fisher_f_distribution& __x,\n                        const fisher_f_distribution& __y)\n        {return !(__x == __y);}\n};\n\ntemplate <class _RealType>\ntemplate<class _URNG>\n_RealType\nfisher_f_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)\n{\n    gamma_distribution<result_type> __gdm(__p.m() * result_type(.5));\n    gamma_distribution<result_type> __gdn(__p.n() * result_type(.5));\n    return __p.n() * __gdm(__g) / (__p.m() * __gdn(__g));\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const fisher_f_distribution<_RT>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    __os << __x.m() << __sp << __x.n();\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           fisher_f_distribution<_RT>& __x)\n{\n    typedef fisher_f_distribution<_RT> _Eng;\n    typedef typename _Eng::result_type result_type;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    result_type __m;\n    result_type __n;\n    __is >> __m >> __n;\n    if (!__is.fail())\n        __x.param(param_type(__m, __n));\n    return __is;\n}\n\n// student_t_distribution\n\ntemplate<class _RealType = double>\nclass _LIBCPP_TYPE_VIS_ONLY student_t_distribution\n{\npublic:\n    // types\n    typedef _RealType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        result_type __n_;\n    public:\n        typedef student_t_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        explicit param_type(result_type __n = 1) : __n_(__n) {}\n\n        _LIBCPP_INLINE_VISIBILITY\n        result_type n() const {return __n_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__n_ == __y.__n_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n    };\n\nprivate:\n    param_type __p_;\n    normal_distribution<result_type> __nd_;\n\npublic:\n    // constructor and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    explicit student_t_distribution(result_type __n = 1)\n        : __p_(param_type(__n)) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit student_t_distribution(const param_type& __p)\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {__nd_.reset();}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    result_type n() const {return __p_.n();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return -numeric_limits<result_type>::infinity();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return numeric_limits<result_type>::infinity();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const student_t_distribution& __x,\n                        const student_t_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const student_t_distribution& __x,\n                        const student_t_distribution& __y)\n        {return !(__x == __y);}\n};\n\ntemplate <class _RealType>\ntemplate<class _URNG>\n_RealType\nstudent_t_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)\n{\n    gamma_distribution<result_type> __gd(__p.n() * .5, 2);\n    return __nd_(__g) * _VSTD::sqrt(__p.n()/__gd(__g));\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const student_t_distribution<_RT>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    __os << __x.n();\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           student_t_distribution<_RT>& __x)\n{\n    typedef student_t_distribution<_RT> _Eng;\n    typedef typename _Eng::result_type result_type;\n    typedef typename _Eng::param_type param_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    result_type __n;\n    __is >> __n;\n    if (!__is.fail())\n        __x.param(param_type(__n));\n    return __is;\n}\n\n// discrete_distribution\n\ntemplate<class _IntType = int>\nclass _LIBCPP_TYPE_VIS_ONLY discrete_distribution\n{\npublic:\n    // types\n    typedef _IntType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        vector<double> __p_;\n    public:\n        typedef discrete_distribution distribution_type;\n\n        _LIBCPP_INLINE_VISIBILITY\n        param_type() {}\n        template<class _InputIterator>\n            _LIBCPP_INLINE_VISIBILITY\n            param_type(_InputIterator __f, _InputIterator __l)\n            : __p_(__f, __l) {__init();}\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n        _LIBCPP_INLINE_VISIBILITY\n        param_type(initializer_list<double> __wl)\n            : __p_(__wl.begin(), __wl.end()) {__init();}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n        template<class _UnaryOperation>\n            param_type(size_t __nw, double __xmin, double __xmax,\n                       _UnaryOperation __fw);\n\n        vector<double> probabilities() const;\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__p_ == __y.__p_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n\n    private:\n        void __init();\n\n        friend class discrete_distribution;\n\n        template <class _CharT, class _Traits, class _IT>\n        friend\n        basic_ostream<_CharT, _Traits>&\n        operator<<(basic_ostream<_CharT, _Traits>& __os,\n                   const discrete_distribution<_IT>& __x);\n\n        template <class _CharT, class _Traits, class _IT>\n        friend\n        basic_istream<_CharT, _Traits>&\n        operator>>(basic_istream<_CharT, _Traits>& __is,\n                   discrete_distribution<_IT>& __x);\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructor and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    discrete_distribution() {}\n    template<class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        discrete_distribution(_InputIterator __f, _InputIterator __l)\n            : __p_(__f, __l) {}\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    discrete_distribution(initializer_list<double> __wl)\n        : __p_(__wl) {}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    template<class _UnaryOperation>\n        _LIBCPP_INLINE_VISIBILITY\n        discrete_distribution(size_t __nw, double __xmin, double __xmax,\n                              _UnaryOperation __fw)\n        : __p_(__nw, __xmin, __xmax, __fw) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit discrete_distribution(const param_type& __p)\n        : __p_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    vector<double> probabilities() const {return __p_.probabilities();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return __p_.__p_.size();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const discrete_distribution& __x,\n                        const discrete_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const discrete_distribution& __x,\n                        const discrete_distribution& __y)\n        {return !(__x == __y);}\n\n    template <class _CharT, class _Traits, class _IT>\n    friend\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os,\n               const discrete_distribution<_IT>& __x);\n\n    template <class _CharT, class _Traits, class _IT>\n    friend\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is,\n               discrete_distribution<_IT>& __x);\n};\n\ntemplate<class _IntType>\ntemplate<class _UnaryOperation>\ndiscrete_distribution<_IntType>::param_type::param_type(size_t __nw,\n                                                        double __xmin,\n                                                        double __xmax,\n                                                        _UnaryOperation __fw)\n{\n    if (__nw > 1)\n    {\n        __p_.reserve(__nw - 1);\n        double __d = (__xmax - __xmin) / __nw;\n        double __d2 = __d / 2;\n        for (size_t __k = 0; __k < __nw; ++__k)\n            __p_.push_back(__fw(__xmin + __k * __d + __d2));\n        __init();\n    }\n}\n\ntemplate<class _IntType>\nvoid\ndiscrete_distribution<_IntType>::param_type::__init()\n{\n    if (!__p_.empty())\n    {\n        if (__p_.size() > 1)\n        {\n            double __s = _VSTD::accumulate(__p_.begin(), __p_.end(), 0.0);\n            for (_VSTD::vector<double>::iterator __i = __p_.begin(), __e = __p_.end();\n                                                                       __i < __e; ++__i)\n                *__i /= __s;\n            vector<double> __t(__p_.size() - 1);\n            _VSTD::partial_sum(__p_.begin(), __p_.end() - 1, __t.begin());\n            swap(__p_, __t);\n        }\n        else\n        {\n            __p_.clear();\n            __p_.shrink_to_fit();\n        }\n    }\n}\n\ntemplate<class _IntType>\nvector<double>\ndiscrete_distribution<_IntType>::param_type::probabilities() const\n{\n    size_t __n = __p_.size();\n    _VSTD::vector<double> __p(__n+1);\n    _VSTD::adjacent_difference(__p_.begin(), __p_.end(), __p.begin());\n    if (__n > 0)\n        __p[__n] = 1 - __p_[__n-1];\n    else\n        __p[0] = 1;\n    return __p;\n}\n\ntemplate<class _IntType>\ntemplate<class _URNG>\n_IntType\ndiscrete_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)\n{\n    uniform_real_distribution<double> __gen;\n    return static_cast<_IntType>(\n           _VSTD::upper_bound(__p.__p_.begin(), __p.__p_.end(), __gen(__g)) -\n                                                              __p.__p_.begin());\n}\n\ntemplate <class _CharT, class _Traits, class _IT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const discrete_distribution<_IT>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    size_t __n = __x.__p_.__p_.size();\n    __os << __n;\n    for (size_t __i = 0; __i < __n; ++__i)\n        __os << __sp << __x.__p_.__p_[__i];\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits, class _IT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           discrete_distribution<_IT>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    size_t __n;\n    __is >> __n;\n    vector<double> __p(__n);\n    for (size_t __i = 0; __i < __n; ++__i)\n        __is >> __p[__i];\n    if (!__is.fail())\n        swap(__x.__p_.__p_, __p);\n    return __is;\n}\n\n// piecewise_constant_distribution\n\ntemplate<class _RealType = double>\nclass _LIBCPP_TYPE_VIS_ONLY piecewise_constant_distribution\n{\npublic:\n    // types\n    typedef _RealType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        vector<result_type> __b_;\n        vector<result_type> __densities_;\n        vector<result_type> __areas_;\n    public:\n        typedef piecewise_constant_distribution distribution_type;\n\n        param_type();\n        template<class _InputIteratorB, class _InputIteratorW>\n            param_type(_InputIteratorB __fB, _InputIteratorB __lB,\n                       _InputIteratorW __fW);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n        template<class _UnaryOperation>\n            param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n        template<class _UnaryOperation>\n            param_type(size_t __nw, result_type __xmin, result_type __xmax,\n                       _UnaryOperation __fw);\n        param_type & operator=(const param_type& __rhs);\n\n        _LIBCPP_INLINE_VISIBILITY\n        vector<result_type> intervals() const {return __b_;}\n        _LIBCPP_INLINE_VISIBILITY\n        vector<result_type> densities() const {return __densities_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__densities_ == __y.__densities_ && __x.__b_ == __y.__b_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n\n    private:\n        void __init();\n\n        friend class piecewise_constant_distribution;\n\n        template <class _CharT, class _Traits, class _RT>\n        friend\n        basic_ostream<_CharT, _Traits>&\n        operator<<(basic_ostream<_CharT, _Traits>& __os,\n                   const piecewise_constant_distribution<_RT>& __x);\n\n        template <class _CharT, class _Traits, class _RT>\n        friend\n        basic_istream<_CharT, _Traits>&\n        operator>>(basic_istream<_CharT, _Traits>& __is,\n                   piecewise_constant_distribution<_RT>& __x);\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructor and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    piecewise_constant_distribution() {}\n    template<class _InputIteratorB, class _InputIteratorW>\n        _LIBCPP_INLINE_VISIBILITY\n        piecewise_constant_distribution(_InputIteratorB __fB,\n                                        _InputIteratorB __lB,\n                                        _InputIteratorW __fW)\n        : __p_(__fB, __lB, __fW) {}\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    template<class _UnaryOperation>\n        _LIBCPP_INLINE_VISIBILITY\n        piecewise_constant_distribution(initializer_list<result_type> __bl,\n                                        _UnaryOperation __fw)\n        : __p_(__bl, __fw) {}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    template<class _UnaryOperation>\n        _LIBCPP_INLINE_VISIBILITY\n        piecewise_constant_distribution(size_t __nw, result_type __xmin,\n                                        result_type __xmax, _UnaryOperation __fw)\n        : __p_(__nw, __xmin, __xmax, __fw) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit piecewise_constant_distribution(const param_type& __p)\n        : __p_(__p) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    vector<result_type> intervals() const {return __p_.intervals();}\n    _LIBCPP_INLINE_VISIBILITY\n    vector<result_type> densities() const {return __p_.densities();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return __p_.__b_.front();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return __p_.__b_.back();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const piecewise_constant_distribution& __x,\n                        const piecewise_constant_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const piecewise_constant_distribution& __x,\n                           const piecewise_constant_distribution& __y)\n        {return !(__x == __y);}\n\n    template <class _CharT, class _Traits, class _RT>\n    friend\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os,\n               const piecewise_constant_distribution<_RT>& __x);\n\n    template <class _CharT, class _Traits, class _RT>\n    friend\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is,\n               piecewise_constant_distribution<_RT>& __x);\n};\n\ntemplate<class _RealType>\ntypename piecewise_constant_distribution<_RealType>::param_type &\npiecewise_constant_distribution<_RealType>::param_type::operator=\n                                                       (const param_type& __rhs)\n{\n//  These can throw\n    __b_.reserve        (__rhs.__b_.size ());\n    __densities_.reserve(__rhs.__densities_.size());\n    __areas_.reserve    (__rhs.__areas_.size());\n\n//  These can not throw\n    __b_         = __rhs.__b_;\n    __densities_ = __rhs.__densities_;\n    __areas_     =  __rhs.__areas_;\n    return *this;\n}\n\ntemplate<class _RealType>\nvoid\npiecewise_constant_distribution<_RealType>::param_type::__init()\n{\n    // __densities_ contains non-normalized areas\n    result_type __total_area = _VSTD::accumulate(__densities_.begin(),\n                                                __densities_.end(),\n                                                result_type());\n    for (size_t __i = 0; __i < __densities_.size(); ++__i)\n        __densities_[__i] /= __total_area;\n    // __densities_ contains normalized areas\n    __areas_.assign(__densities_.size(), result_type());\n    _VSTD::partial_sum(__densities_.begin(), __densities_.end() - 1,\n                                                          __areas_.begin() + 1);\n    // __areas_ contains partial sums of normalized areas: [0, __densities_ - 1]\n    __densities_.back() = 1 - __areas_.back();  // correct round off error\n    for (size_t __i = 0; __i < __densities_.size(); ++__i)\n        __densities_[__i] /= (__b_[__i+1] - __b_[__i]);\n    // __densities_ now contains __densities_\n}\n\ntemplate<class _RealType>\npiecewise_constant_distribution<_RealType>::param_type::param_type()\n    : __b_(2),\n      __densities_(1, 1.0),\n      __areas_(1, 0.0)\n{\n    __b_[1] = 1;\n}\n\ntemplate<class _RealType>\ntemplate<class _InputIteratorB, class _InputIteratorW>\npiecewise_constant_distribution<_RealType>::param_type::param_type(\n        _InputIteratorB __fB, _InputIteratorB __lB, _InputIteratorW __fW)\n    : __b_(__fB, __lB)\n{\n    if (__b_.size() < 2)\n    {\n        __b_.resize(2);\n        __b_[0] = 0;\n        __b_[1] = 1;\n        __densities_.assign(1, 1.0);\n        __areas_.assign(1, 0.0);\n    }\n    else\n    {\n        __densities_.reserve(__b_.size() - 1);\n        for (size_t __i = 0; __i < __b_.size() - 1; ++__i, ++__fW)\n            __densities_.push_back(*__fW);\n        __init();\n    }\n}\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate<class _RealType>\ntemplate<class _UnaryOperation>\npiecewise_constant_distribution<_RealType>::param_type::param_type(\n        initializer_list<result_type> __bl, _UnaryOperation __fw)\n    : __b_(__bl.begin(), __bl.end())\n{\n    if (__b_.size() < 2)\n    {\n        __b_.resize(2);\n        __b_[0] = 0;\n        __b_[1] = 1;\n        __densities_.assign(1, 1.0);\n        __areas_.assign(1, 0.0);\n    }\n    else\n    {\n        __densities_.reserve(__b_.size() - 1);\n        for (size_t __i = 0; __i < __b_.size() - 1; ++__i)\n            __densities_.push_back(__fw((__b_[__i+1] + __b_[__i])*.5));\n        __init();\n    }\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate<class _RealType>\ntemplate<class _UnaryOperation>\npiecewise_constant_distribution<_RealType>::param_type::param_type(\n        size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw)\n    : __b_(__nw == 0 ? 2 : __nw + 1)\n{\n    size_t __n = __b_.size() - 1;\n    result_type __d = (__xmax - __xmin) / __n;\n    __densities_.reserve(__n);\n    for (size_t __i = 0; __i < __n; ++__i)\n    {\n        __b_[__i] = __xmin + __i * __d;\n        __densities_.push_back(__fw(__b_[__i] + __d*.5));\n    }\n    __b_[__n] = __xmax;\n    __init();\n}\n\ntemplate<class _RealType>\ntemplate<class _URNG>\n_RealType\npiecewise_constant_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)\n{\n    typedef uniform_real_distribution<result_type> _Gen;\n    result_type __u = _Gen()(__g);\n    ptrdiff_t __k = _VSTD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(),\n                                      __u) - __p.__areas_.begin() - 1;\n    return (__u - __p.__areas_[__k]) / __p.__densities_[__k] + __p.__b_[__k];\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const piecewise_constant_distribution<_RT>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    size_t __n = __x.__p_.__b_.size();\n    __os << __n;\n    for (size_t __i = 0; __i < __n; ++__i)\n        __os << __sp << __x.__p_.__b_[__i];\n    __n = __x.__p_.__densities_.size();\n    __os << __sp << __n;\n    for (size_t __i = 0; __i < __n; ++__i)\n        __os << __sp << __x.__p_.__densities_[__i];\n    __n = __x.__p_.__areas_.size();\n    __os << __sp << __n;\n    for (size_t __i = 0; __i < __n; ++__i)\n        __os << __sp << __x.__p_.__areas_[__i];\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           piecewise_constant_distribution<_RT>& __x)\n{\n    typedef piecewise_constant_distribution<_RT> _Eng;\n    typedef typename _Eng::result_type result_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    size_t __n;\n    __is >> __n;\n    vector<result_type> __b(__n);\n    for (size_t __i = 0; __i < __n; ++__i)\n        __is >> __b[__i];\n    __is >> __n;\n    vector<result_type> __densities(__n);\n    for (size_t __i = 0; __i < __n; ++__i)\n        __is >> __densities[__i];\n    __is >> __n;\n    vector<result_type> __areas(__n);\n    for (size_t __i = 0; __i < __n; ++__i)\n        __is >> __areas[__i];\n    if (!__is.fail())\n    {\n        swap(__x.__p_.__b_, __b);\n        swap(__x.__p_.__densities_, __densities);\n        swap(__x.__p_.__areas_, __areas);\n    }\n    return __is;\n}\n\n// piecewise_linear_distribution\n\ntemplate<class _RealType = double>\nclass _LIBCPP_TYPE_VIS_ONLY piecewise_linear_distribution\n{\npublic:\n    // types\n    typedef _RealType result_type;\n\n    class _LIBCPP_TYPE_VIS_ONLY param_type\n    {\n        vector<result_type> __b_;\n        vector<result_type> __densities_;\n        vector<result_type> __areas_;\n    public:\n        typedef piecewise_linear_distribution distribution_type;\n\n        param_type();\n        template<class _InputIteratorB, class _InputIteratorW>\n            param_type(_InputIteratorB __fB, _InputIteratorB __lB,\n                       _InputIteratorW __fW);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n        template<class _UnaryOperation>\n            param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n        template<class _UnaryOperation>\n            param_type(size_t __nw, result_type __xmin, result_type __xmax,\n                       _UnaryOperation __fw);\n        param_type & operator=(const param_type& __rhs);\n        \n        _LIBCPP_INLINE_VISIBILITY\n        vector<result_type> intervals() const {return __b_;}\n        _LIBCPP_INLINE_VISIBILITY\n        vector<result_type> densities() const {return __densities_;}\n\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator==(const param_type& __x, const param_type& __y)\n            {return __x.__densities_ == __y.__densities_ && __x.__b_ == __y.__b_;}\n        friend _LIBCPP_INLINE_VISIBILITY\n            bool operator!=(const param_type& __x, const param_type& __y)\n            {return !(__x == __y);}\n\n    private:\n        void __init();\n\n        friend class piecewise_linear_distribution;\n\n        template <class _CharT, class _Traits, class _RT>\n        friend\n        basic_ostream<_CharT, _Traits>&\n        operator<<(basic_ostream<_CharT, _Traits>& __os,\n                   const piecewise_linear_distribution<_RT>& __x);\n\n        template <class _CharT, class _Traits, class _RT>\n        friend\n        basic_istream<_CharT, _Traits>&\n        operator>>(basic_istream<_CharT, _Traits>& __is,\n                   piecewise_linear_distribution<_RT>& __x);\n    };\n\nprivate:\n    param_type __p_;\n\npublic:\n    // constructor and reset functions\n    _LIBCPP_INLINE_VISIBILITY\n    piecewise_linear_distribution() {}\n    template<class _InputIteratorB, class _InputIteratorW>\n        _LIBCPP_INLINE_VISIBILITY\n        piecewise_linear_distribution(_InputIteratorB __fB,\n                                      _InputIteratorB __lB,\n                                      _InputIteratorW __fW)\n        : __p_(__fB, __lB, __fW) {}\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    template<class _UnaryOperation>\n        _LIBCPP_INLINE_VISIBILITY\n        piecewise_linear_distribution(initializer_list<result_type> __bl,\n                                      _UnaryOperation __fw)\n        : __p_(__bl, __fw) {}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    template<class _UnaryOperation>\n        _LIBCPP_INLINE_VISIBILITY\n        piecewise_linear_distribution(size_t __nw, result_type __xmin,\n                                      result_type __xmax, _UnaryOperation __fw)\n        : __p_(__nw, __xmin, __xmax, __fw) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit piecewise_linear_distribution(const param_type& __p)\n        : __p_(__p) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void reset() {}\n\n    // generating functions\n    template<class _URNG>\n        _LIBCPP_INLINE_VISIBILITY\n        result_type operator()(_URNG& __g)\n        {return (*this)(__g, __p_);}\n    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);\n\n    // property functions\n    _LIBCPP_INLINE_VISIBILITY\n    vector<result_type> intervals() const {return __p_.intervals();}\n    _LIBCPP_INLINE_VISIBILITY\n    vector<result_type> densities() const {return __p_.densities();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    param_type param() const {return __p_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void param(const param_type& __p) {__p_ = __p;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const {return __p_.__b_.front();}\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const {return __p_.__b_.back();}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const piecewise_linear_distribution& __x,\n                        const piecewise_linear_distribution& __y)\n        {return __x.__p_ == __y.__p_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const piecewise_linear_distribution& __x,\n                        const piecewise_linear_distribution& __y)\n        {return !(__x == __y);}\n\n    template <class _CharT, class _Traits, class _RT>\n    friend\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os,\n               const piecewise_linear_distribution<_RT>& __x);\n\n    template <class _CharT, class _Traits, class _RT>\n    friend\n    basic_istream<_CharT, _Traits>&\n    operator>>(basic_istream<_CharT, _Traits>& __is,\n               piecewise_linear_distribution<_RT>& __x);\n};\n\ntemplate<class _RealType>\ntypename piecewise_linear_distribution<_RealType>::param_type &\npiecewise_linear_distribution<_RealType>::param_type::operator=\n                                                       (const param_type& __rhs)\n{\n//  These can throw\n    __b_.reserve        (__rhs.__b_.size ());\n    __densities_.reserve(__rhs.__densities_.size());\n    __areas_.reserve    (__rhs.__areas_.size());\n\n//  These can not throw\n    __b_         = __rhs.__b_;\n    __densities_ = __rhs.__densities_;\n    __areas_     =  __rhs.__areas_;\n    return *this;\n}\n\n\ntemplate<class _RealType>\nvoid\npiecewise_linear_distribution<_RealType>::param_type::__init()\n{\n    __areas_.assign(__densities_.size() - 1, result_type());\n    result_type _Sp = 0;\n    for (size_t __i = 0; __i < __areas_.size(); ++__i)\n    {\n        __areas_[__i] = (__densities_[__i+1] + __densities_[__i]) *\n                        (__b_[__i+1] - __b_[__i]) * .5;\n        _Sp += __areas_[__i];\n    }\n    for (size_t __i = __areas_.size(); __i > 1;)\n    {\n        --__i;\n        __areas_[__i] = __areas_[__i-1] / _Sp;\n    }\n    __areas_[0] = 0;\n    for (size_t __i = 1; __i < __areas_.size(); ++__i)\n        __areas_[__i] += __areas_[__i-1];\n    for (size_t __i = 0; __i < __densities_.size(); ++__i)\n        __densities_[__i] /= _Sp;\n}\n\ntemplate<class _RealType>\npiecewise_linear_distribution<_RealType>::param_type::param_type()\n    : __b_(2),\n      __densities_(2, 1.0),\n      __areas_(1, 0.0)\n{\n    __b_[1] = 1;\n}\n\ntemplate<class _RealType>\ntemplate<class _InputIteratorB, class _InputIteratorW>\npiecewise_linear_distribution<_RealType>::param_type::param_type(\n        _InputIteratorB __fB, _InputIteratorB __lB, _InputIteratorW __fW)\n    : __b_(__fB, __lB)\n{\n    if (__b_.size() < 2)\n    {\n        __b_.resize(2);\n        __b_[0] = 0;\n        __b_[1] = 1;\n        __densities_.assign(2, 1.0);\n        __areas_.assign(1, 0.0);\n    }\n    else\n    {\n        __densities_.reserve(__b_.size());\n        for (size_t __i = 0; __i < __b_.size(); ++__i, ++__fW)\n            __densities_.push_back(*__fW);\n        __init();\n    }\n}\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate<class _RealType>\ntemplate<class _UnaryOperation>\npiecewise_linear_distribution<_RealType>::param_type::param_type(\n        initializer_list<result_type> __bl, _UnaryOperation __fw)\n    : __b_(__bl.begin(), __bl.end())\n{\n    if (__b_.size() < 2)\n    {\n        __b_.resize(2);\n        __b_[0] = 0;\n        __b_[1] = 1;\n        __densities_.assign(2, 1.0);\n        __areas_.assign(1, 0.0);\n    }\n    else\n    {\n        __densities_.reserve(__b_.size());\n        for (size_t __i = 0; __i < __b_.size(); ++__i)\n            __densities_.push_back(__fw(__b_[__i]));\n        __init();\n    }\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate<class _RealType>\ntemplate<class _UnaryOperation>\npiecewise_linear_distribution<_RealType>::param_type::param_type(\n        size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw)\n    : __b_(__nw == 0 ? 2 : __nw + 1)\n{\n    size_t __n = __b_.size() - 1;\n    result_type __d = (__xmax - __xmin) / __n;\n    __densities_.reserve(__b_.size());\n    for (size_t __i = 0; __i < __n; ++__i)\n    {\n        __b_[__i] = __xmin + __i * __d;\n        __densities_.push_back(__fw(__b_[__i]));\n    }\n    __b_[__n] = __xmax;\n    __densities_.push_back(__fw(__b_[__n]));\n    __init();\n}\n\ntemplate<class _RealType>\ntemplate<class _URNG>\n_RealType\npiecewise_linear_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)\n{\n    typedef uniform_real_distribution<result_type> _Gen;\n    result_type __u = _Gen()(__g);\n    ptrdiff_t __k = _VSTD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(),\n                                      __u) - __p.__areas_.begin() - 1;\n    __u -= __p.__areas_[__k];\n    const result_type __dk = __p.__densities_[__k];\n    const result_type __dk1 = __p.__densities_[__k+1];\n    const result_type __deltad = __dk1 - __dk;\n    const result_type __bk = __p.__b_[__k];\n    if (__deltad == 0)\n        return __u / __dk + __bk;\n    const result_type __bk1 = __p.__b_[__k+1];\n    const result_type __deltab = __bk1 - __bk;\n    return (__bk * __dk1 - __bk1 * __dk +\n        _VSTD::sqrt(__deltab * (__deltab * __dk * __dk + 2 * __deltad * __u))) /\n        __deltad;\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const piecewise_linear_distribution<_RT>& __x)\n{\n    __save_flags<_CharT, _Traits> __lx(__os);\n    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |\n               ios_base::scientific);\n    _CharT __sp = __os.widen(' ');\n    __os.fill(__sp);\n    size_t __n = __x.__p_.__b_.size();\n    __os << __n;\n    for (size_t __i = 0; __i < __n; ++__i)\n        __os << __sp << __x.__p_.__b_[__i];\n    __n = __x.__p_.__densities_.size();\n    __os << __sp << __n;\n    for (size_t __i = 0; __i < __n; ++__i)\n        __os << __sp << __x.__p_.__densities_[__i];\n    __n = __x.__p_.__areas_.size();\n    __os << __sp << __n;\n    for (size_t __i = 0; __i < __n; ++__i)\n        __os << __sp << __x.__p_.__areas_[__i];\n    return __os;\n}\n\ntemplate <class _CharT, class _Traits, class _RT>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           piecewise_linear_distribution<_RT>& __x)\n{\n    typedef piecewise_linear_distribution<_RT> _Eng;\n    typedef typename _Eng::result_type result_type;\n    __save_flags<_CharT, _Traits> __lx(__is);\n    __is.flags(ios_base::dec | ios_base::skipws);\n    size_t __n;\n    __is >> __n;\n    vector<result_type> __b(__n);\n    for (size_t __i = 0; __i < __n; ++__i)\n        __is >> __b[__i];\n    __is >> __n;\n    vector<result_type> __densities(__n);\n    for (size_t __i = 0; __i < __n; ++__i)\n        __is >> __densities[__i];\n    __is >> __n;\n    vector<result_type> __areas(__n);\n    for (size_t __i = 0; __i < __n; ++__i)\n        __is >> __areas[__i];\n    if (!__is.fail())\n    {\n        swap(__x.__p_.__b_, __b);\n        swap(__x.__p_.__densities_, __densities);\n        swap(__x.__p_.__areas_, __areas);\n    }\n    return __is;\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_RANDOM\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/ratio",
    "content": "// -*- C++ -*-\n//===---------------------------- ratio -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_RATIO\n#define _LIBCPP_RATIO\n\n/*\n    ratio synopsis\n\nnamespace std\n{\n\ntemplate <intmax_t N, intmax_t D = 1>\nclass ratio\n{\npublic:\n    static constexpr intmax_t num;\n    static constexpr intmax_t den;\n    typedef ratio<num, den> type;\n};\n\n// ratio arithmetic\ntemplate <class R1, class R2> using ratio_add = ...;\ntemplate <class R1, class R2> using ratio_subtract = ...;\ntemplate <class R1, class R2> using ratio_multiply = ...;\ntemplate <class R1, class R2> using ratio_divide = ...;\n\n// ratio comparison\ntemplate <class R1, class R2> struct ratio_equal;\ntemplate <class R1, class R2> struct ratio_not_equal;\ntemplate <class R1, class R2> struct ratio_less;\ntemplate <class R1, class R2> struct ratio_less_equal;\ntemplate <class R1, class R2> struct ratio_greater;\ntemplate <class R1, class R2> struct ratio_greater_equal;\n\n// convenience SI typedefs\ntypedef ratio<1, 1000000000000000000000000> yocto;  // not supported\ntypedef ratio<1,    1000000000000000000000> zepto;  // not supported\ntypedef ratio<1,       1000000000000000000> atto;\ntypedef ratio<1,          1000000000000000> femto;\ntypedef ratio<1,             1000000000000> pico;\ntypedef ratio<1,                1000000000> nano;\ntypedef ratio<1,                   1000000> micro;\ntypedef ratio<1,                      1000> milli;\ntypedef ratio<1,                       100> centi;\ntypedef ratio<1,                        10> deci;\ntypedef ratio<                       10, 1> deca;\ntypedef ratio<                      100, 1> hecto;\ntypedef ratio<                     1000, 1> kilo;\ntypedef ratio<                  1000000, 1> mega;\ntypedef ratio<               1000000000, 1> giga;\ntypedef ratio<            1000000000000, 1> tera;\ntypedef ratio<         1000000000000000, 1> peta;\ntypedef ratio<      1000000000000000000, 1> exa;\ntypedef ratio<   1000000000000000000000, 1> zetta;  // not supported\ntypedef ratio<1000000000000000000000000, 1> yotta;  // not supported\n\n}\n*/\n\n#include <__config>\n#include <cstdint>\n#include <climits>\n#include <type_traits>\n\n#include <__undef_min_max>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n// __static_gcd\n\ntemplate <intmax_t _Xp, intmax_t _Yp>\nstruct __static_gcd\n{\n    static const intmax_t value = __static_gcd<_Yp, _Xp % _Yp>::value;\n};\n\ntemplate <intmax_t _Xp>\nstruct __static_gcd<_Xp, 0>\n{\n    static const intmax_t value = _Xp;\n};\n\ntemplate <>\nstruct __static_gcd<0, 0>\n{\n    static const intmax_t value = 1;\n};\n\n// __static_lcm\n\ntemplate <intmax_t _Xp, intmax_t _Yp>\nstruct __static_lcm\n{\n    static const intmax_t value = _Xp / __static_gcd<_Xp, _Yp>::value * _Yp;\n};\n\ntemplate <intmax_t _Xp>\nstruct __static_abs\n{\n    static const intmax_t value = _Xp < 0 ? -_Xp : _Xp;\n};\n\ntemplate <intmax_t _Xp>\nstruct __static_sign\n{\n    static const intmax_t value = _Xp == 0 ? 0 : (_Xp < 0 ? -1 : 1);\n};\n\ntemplate <intmax_t _Xp, intmax_t _Yp, intmax_t = __static_sign<_Yp>::value>\nclass __ll_add;\n\ntemplate <intmax_t _Xp, intmax_t _Yp>\nclass __ll_add<_Xp, _Yp, 1>\n{\n    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;\n    static const intmax_t max = -min;\n\n    static_assert(_Xp <= max - _Yp, \"overflow in __ll_add\");\npublic:\n    static const intmax_t value = _Xp + _Yp;\n};\n\ntemplate <intmax_t _Xp, intmax_t _Yp>\nclass __ll_add<_Xp, _Yp, 0>\n{\npublic:\n    static const intmax_t value = _Xp;\n};\n\ntemplate <intmax_t _Xp, intmax_t _Yp>\nclass __ll_add<_Xp, _Yp, -1>\n{\n    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;\n    static const intmax_t max = -min;\n\n    static_assert(min - _Yp <= _Xp, \"overflow in __ll_add\");\npublic:\n    static const intmax_t value = _Xp + _Yp;\n};\n\ntemplate <intmax_t _Xp, intmax_t _Yp, intmax_t = __static_sign<_Yp>::value>\nclass __ll_sub;\n\ntemplate <intmax_t _Xp, intmax_t _Yp>\nclass __ll_sub<_Xp, _Yp, 1>\n{\n    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;\n    static const intmax_t max = -min;\n\n    static_assert(min + _Yp <= _Xp, \"overflow in __ll_sub\");\npublic:\n    static const intmax_t value = _Xp - _Yp;\n};\n\ntemplate <intmax_t _Xp, intmax_t _Yp>\nclass __ll_sub<_Xp, _Yp, 0>\n{\npublic:\n    static const intmax_t value = _Xp;\n};\n\ntemplate <intmax_t _Xp, intmax_t _Yp>\nclass __ll_sub<_Xp, _Yp, -1>\n{\n    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;\n    static const intmax_t max = -min;\n\n    static_assert(_Xp <= max + _Yp, \"overflow in __ll_sub\");\npublic:\n    static const intmax_t value = _Xp - _Yp;\n};\n\ntemplate <intmax_t _Xp, intmax_t _Yp>\nclass __ll_mul\n{\n    static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1));\n    static const intmax_t min = nan + 1;\n    static const intmax_t max = -min;\n    static const intmax_t __a_x = __static_abs<_Xp>::value;\n    static const intmax_t __a_y = __static_abs<_Yp>::value;\n\n    static_assert(_Xp != nan && _Yp != nan && __a_x <= max / __a_y, \"overflow in __ll_mul\");\npublic:\n    static const intmax_t value = _Xp * _Yp;\n};\n\ntemplate <intmax_t _Yp>\nclass __ll_mul<0, _Yp>\n{\npublic:\n    static const intmax_t value = 0;\n};\n\ntemplate <intmax_t _Xp>\nclass __ll_mul<_Xp, 0>\n{\npublic:\n    static const intmax_t value = 0;\n};\n\ntemplate <>\nclass __ll_mul<0, 0>\n{\npublic:\n    static const intmax_t value = 0;\n};\n\n// Not actually used but left here in case needed in future maintenance\ntemplate <intmax_t _Xp, intmax_t _Yp>\nclass __ll_div\n{\n    static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1));\n    static const intmax_t min = nan + 1;\n    static const intmax_t max = -min;\n\n    static_assert(_Xp != nan && _Yp != nan && _Yp != 0, \"overflow in __ll_div\");\npublic:\n    static const intmax_t value = _Xp / _Yp;\n};\n\ntemplate <intmax_t _Num, intmax_t _Den = 1>\nclass _LIBCPP_TYPE_VIS_ONLY ratio\n{\n    static_assert(__static_abs<_Num>::value >= 0, \"ratio numerator is out of range\");\n    static_assert(_Den != 0, \"ratio divide by 0\");\n    static_assert(__static_abs<_Den>::value >  0, \"ratio denominator is out of range\");\n    static _LIBCPP_CONSTEXPR const intmax_t __na = __static_abs<_Num>::value;\n    static _LIBCPP_CONSTEXPR const intmax_t __da = __static_abs<_Den>::value;\n    static _LIBCPP_CONSTEXPR const intmax_t __s = __static_sign<_Num>::value * __static_sign<_Den>::value;\n    static _LIBCPP_CONSTEXPR const intmax_t __gcd = __static_gcd<__na, __da>::value;\npublic:\n    static _LIBCPP_CONSTEXPR const intmax_t num = __s * __na / __gcd;\n    static _LIBCPP_CONSTEXPR const intmax_t den = __da / __gcd;\n\n    typedef ratio<num, den> type;\n};\n\ntemplate <intmax_t _Num, intmax_t _Den>\n_LIBCPP_CONSTEXPR const intmax_t ratio<_Num, _Den>::num;\n\ntemplate <intmax_t _Num, intmax_t _Den>\n_LIBCPP_CONSTEXPR const intmax_t ratio<_Num, _Den>::den;\n\ntemplate <class _Tp>                    struct __is_ratio                     : false_type {};\ntemplate <intmax_t _Num, intmax_t _Den> struct __is_ratio<ratio<_Num, _Den> > : true_type  {};\n\ntypedef ratio<1LL, 1000000000000000000LL> atto;\ntypedef ratio<1LL,    1000000000000000LL> femto;\ntypedef ratio<1LL,       1000000000000LL> pico;\ntypedef ratio<1LL,          1000000000LL> nano;\ntypedef ratio<1LL,             1000000LL> micro;\ntypedef ratio<1LL,                1000LL> milli;\ntypedef ratio<1LL,                 100LL> centi;\ntypedef ratio<1LL,                  10LL> deci;\ntypedef ratio<                 10LL, 1LL> deca;\ntypedef ratio<                100LL, 1LL> hecto;\ntypedef ratio<               1000LL, 1LL> kilo;\ntypedef ratio<            1000000LL, 1LL> mega;\ntypedef ratio<         1000000000LL, 1LL> giga;\ntypedef ratio<      1000000000000LL, 1LL> tera;\ntypedef ratio<   1000000000000000LL, 1LL> peta;\ntypedef ratio<1000000000000000000LL, 1LL> exa;\n\ntemplate <class _R1, class _R2>\nstruct __ratio_multiply\n{\nprivate:\n    static const intmax_t __gcd_n1_d2 = __static_gcd<_R1::num, _R2::den>::value;\n    static const intmax_t __gcd_d1_n2 = __static_gcd<_R1::den, _R2::num>::value;\npublic:\n    typedef typename ratio\n        <\n            __ll_mul<_R1::num / __gcd_n1_d2, _R2::num / __gcd_d1_n2>::value,\n            __ll_mul<_R2::den / __gcd_n1_d2, _R1::den / __gcd_d1_n2>::value\n        >::type type;\n};\n\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\ntemplate <class _R1, class _R2> using ratio_multiply\n                                    = typename __ratio_multiply<_R1, _R2>::type;\n\n#else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\ntemplate <class _R1, class _R2>\nstruct _LIBCPP_TYPE_VIS_ONLY ratio_multiply\n    : public __ratio_multiply<_R1, _R2>::type {};\n\n#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\ntemplate <class _R1, class _R2>\nstruct __ratio_divide\n{\nprivate:\n    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;\n    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;\npublic:\n    typedef typename ratio\n        <\n            __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,\n            __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value\n        >::type type;\n};\n\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\ntemplate <class _R1, class _R2> using ratio_divide\n                                      = typename __ratio_divide<_R1, _R2>::type;\n\n#else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\ntemplate <class _R1, class _R2>\nstruct _LIBCPP_TYPE_VIS_ONLY ratio_divide\n    : public __ratio_divide<_R1, _R2>::type {};\n\n#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\ntemplate <class _R1, class _R2>\nstruct __ratio_add\n{\nprivate:\n    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;\n    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;\npublic:\n    typedef typename ratio_multiply\n        <\n            ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>,\n            ratio\n            <\n                __ll_add\n                <\n                    __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,\n                    __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value\n                >::value,\n                _R2::den\n            >\n        >::type type;\n};\n\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\ntemplate <class _R1, class _R2> using ratio_add\n                                         = typename __ratio_add<_R1, _R2>::type;\n\n#else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\ntemplate <class _R1, class _R2>\nstruct _LIBCPP_TYPE_VIS_ONLY ratio_add\n    : public __ratio_add<_R1, _R2>::type {};\n\n#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\ntemplate <class _R1, class _R2>\nstruct __ratio_subtract\n{\nprivate:\n    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;\n    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;\npublic:\n    typedef typename ratio_multiply\n        <\n            ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>,\n            ratio\n            <\n                __ll_sub\n                <\n                    __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,\n                    __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value\n                >::value,\n                _R2::den\n            >\n        >::type type;\n};\n\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\ntemplate <class _R1, class _R2> using ratio_subtract\n                                    = typename __ratio_subtract<_R1, _R2>::type;\n\n#else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\ntemplate <class _R1, class _R2>\nstruct _LIBCPP_TYPE_VIS_ONLY ratio_subtract\n    : public __ratio_subtract<_R1, _R2>::type {};\n\n#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n\n// ratio_equal\n\ntemplate <class _R1, class _R2>\nstruct _LIBCPP_TYPE_VIS_ONLY ratio_equal\n    : public _LIBCPP_BOOL_CONSTANT((_R1::num == _R2::num && _R1::den == _R2::den)) {};\n\ntemplate <class _R1, class _R2>\nstruct _LIBCPP_TYPE_VIS_ONLY ratio_not_equal\n    : public _LIBCPP_BOOL_CONSTANT((!ratio_equal<_R1, _R2>::value)) {};\n\n// ratio_less\n\ntemplate <class _R1, class _R2, bool _Odd = false,\n          intmax_t _Q1 = _R1::num / _R1::den, intmax_t _M1 = _R1::num % _R1::den,\n          intmax_t _Q2 = _R2::num / _R2::den, intmax_t _M2 = _R2::num % _R2::den>\nstruct __ratio_less1\n{\n    static const bool value = _Odd ? _Q2 < _Q1 : _Q1 < _Q2;\n};\n\ntemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp>\nstruct __ratio_less1<_R1, _R2, _Odd, _Qp, 0, _Qp, 0>\n{\n    static const bool value = false;\n};\n\ntemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M2>\nstruct __ratio_less1<_R1, _R2, _Odd, _Qp, 0, _Qp, _M2>\n{\n    static const bool value = !_Odd;\n};\n\ntemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M1>\nstruct __ratio_less1<_R1, _R2, _Odd, _Qp, _M1, _Qp, 0>\n{\n    static const bool value = _Odd;\n};\n\ntemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M1,\n                                                        intmax_t _M2>\nstruct __ratio_less1<_R1, _R2, _Odd, _Qp, _M1, _Qp, _M2>\n{\n    static const bool value = __ratio_less1<ratio<_R1::den, _M1>,\n                                            ratio<_R2::den, _M2>, !_Odd>::value;\n};\n\ntemplate <class _R1, class _R2, intmax_t _S1 = __static_sign<_R1::num>::value,\n                                intmax_t _S2 = __static_sign<_R2::num>::value>\nstruct __ratio_less\n{\n    static const bool value = _S1 < _S2;\n};\n\ntemplate <class _R1, class _R2>\nstruct __ratio_less<_R1, _R2, 1LL, 1LL>\n{\n    static const bool value = __ratio_less1<_R1, _R2>::value;\n};\n\ntemplate <class _R1, class _R2>\nstruct __ratio_less<_R1, _R2, -1LL, -1LL>\n{\n    static const bool value = __ratio_less1<ratio<-_R2::num, _R2::den>, ratio<-_R1::num, _R1::den> >::value;\n};\n\ntemplate <class _R1, class _R2>\nstruct _LIBCPP_TYPE_VIS_ONLY ratio_less\n    : public _LIBCPP_BOOL_CONSTANT((__ratio_less<_R1, _R2>::value)) {};\n\ntemplate <class _R1, class _R2>\nstruct _LIBCPP_TYPE_VIS_ONLY ratio_less_equal\n    : public _LIBCPP_BOOL_CONSTANT((!ratio_less<_R2, _R1>::value)) {};\n\ntemplate <class _R1, class _R2>\nstruct _LIBCPP_TYPE_VIS_ONLY ratio_greater\n    : public _LIBCPP_BOOL_CONSTANT((ratio_less<_R2, _R1>::value)) {};\n\ntemplate <class _R1, class _R2>\nstruct _LIBCPP_TYPE_VIS_ONLY ratio_greater_equal\n    : public _LIBCPP_BOOL_CONSTANT((!ratio_less<_R1, _R2>::value)) {};\n\ntemplate <class _R1, class _R2>\nstruct __ratio_gcd\n{\n    typedef ratio<__static_gcd<_R1::num, _R2::num>::value,\n                  __static_lcm<_R1::den, _R2::den>::value> type;\n};\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_RATIO\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/regex",
    "content": "// -*- C++ -*-\n//===--------------------------- regex ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_REGEX\n#define _LIBCPP_REGEX\n\n/*\n    regex synopsis\n\n#include <initializer_list>\n\nnamespace std\n{\n\nnamespace regex_constants\n{\n\nemum syntax_option_type\n{\n    icase      = unspecified,\n    nosubs     = unspecified,\n    optimize   = unspecified,\n    collate    = unspecified,\n    ECMAScript = unspecified,\n    basic      = unspecified,\n    extended   = unspecified,\n    awk        = unspecified,\n    grep       = unspecified,\n    egrep      = unspecified\n};\n\nconstexpr syntax_option_type operator~(syntax_option_type f);\nconstexpr syntax_option_type operator&(syntax_option_type lhs, syntax_option_type rhs);\nconstexpr syntax_option_type operator|(syntax_option_type lhs, syntax_option_type rhs);\n\nenum match_flag_type\n{\n    match_default     = 0,\n    match_not_bol     = unspecified,\n    match_not_eol     = unspecified,\n    match_not_bow     = unspecified,\n    match_not_eow     = unspecified,\n    match_any         = unspecified,\n    match_not_null    = unspecified,\n    match_continuous  = unspecified,\n    match_prev_avail  = unspecified,\n    format_default    = 0,\n    format_sed        = unspecified,\n    format_no_copy    = unspecified,\n    format_first_only = unspecified\n};\n\nconstexpr match_flag_type operator~(match_flag_type f);\nconstexpr match_flag_type operator&(match_flag_type lhs, match_flag_type rhs);\nconstexpr match_flag_type operator|(match_flag_type lhs, match_flag_type rhs);\n\nenum error_type\n{\n    error_collate    = unspecified,\n    error_ctype      = unspecified,\n    error_escape     = unspecified,\n    error_backref    = unspecified,\n    error_brack      = unspecified,\n    error_paren      = unspecified,\n    error_brace      = unspecified,\n    error_badbrace   = unspecified,\n    error_range      = unspecified,\n    error_space      = unspecified,\n    error_badrepeat  = unspecified,\n    error_complexity = unspecified,\n    error_stack      = unspecified\n};\n\n}  // regex_constants\n\nclass regex_error\n    : public runtime_error\n{\npublic:\n    explicit regex_error(regex_constants::error_type ecode);\n    regex_constants::error_type code() const;\n};\n\ntemplate <class charT>\nstruct regex_traits\n{\npublic:\n    typedef charT                   char_type;\n    typedef basic_string<char_type> string_type;\n    typedef locale                  locale_type;\n    typedef /bitmask_type/          char_class_type;\n\n    regex_traits();\n\n    static size_t length(const char_type* p);\n    charT translate(charT c) const;\n    charT translate_nocase(charT c) const;\n    template <class ForwardIterator>\n        string_type\n        transform(ForwardIterator first, ForwardIterator last) const;\n    template <class ForwardIterator>\n        string_type\n        transform_primary( ForwardIterator first, ForwardIterator last) const;\n    template <class ForwardIterator>\n        string_type\n        lookup_collatename(ForwardIterator first, ForwardIterator last) const;\n    template <class ForwardIterator>\n        char_class_type\n        lookup_classname(ForwardIterator first, ForwardIterator last,\n                         bool icase = false) const;\n    bool isctype(charT c, char_class_type f) const;\n    int value(charT ch, int radix) const;\n    locale_type imbue(locale_type l);\n    locale_type getloc()const;\n};\n\ntemplate <class charT, class traits = regex_traits<charT>>\nclass basic_regex\n{\npublic:\n    // types:\n    typedef charT                               value_type;\n    typedef regex_constants::syntax_option_type flag_type;\n    typedef typename traits::locale_type        locale_type;\n\n    // constants:\n    static constexpr regex_constants::syntax_option_type icase = regex_constants::icase;\n    static constexpr regex_constants::syntax_option_type nosubs = regex_constants::nosubs;\n    static constexpr regex_constants::syntax_option_type optimize = regex_constants::optimize;\n    static constexpr regex_constants::syntax_option_type collate = regex_constants::collate;\n    static constexpr regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript;\n    static constexpr regex_constants::syntax_option_type basic = regex_constants::basic;\n    static constexpr regex_constants::syntax_option_type extended = regex_constants::extended;\n    static constexpr regex_constants::syntax_option_type awk = regex_constants::awk;\n    static constexpr regex_constants::syntax_option_type grep = regex_constants::grep;\n    static constexpr regex_constants::syntax_option_type egrep = regex_constants::egrep;\n\n    // construct/copy/destroy:\n    basic_regex();\n    explicit basic_regex(const charT* p, flag_type f = regex_constants::ECMAScript);\n    basic_regex(const charT* p, size_t len, flag_type f);\n    basic_regex(const basic_regex&);\n    basic_regex(basic_regex&&) noexcept;\n    template <class ST, class SA>\n        explicit basic_regex(const basic_string<charT, ST, SA>& p,\n                             flag_type f = regex_constants::ECMAScript);\n    template <class ForwardIterator>\n        basic_regex(ForwardIterator first, ForwardIterator last,\n                    flag_type f = regex_constants::ECMAScript);\n    basic_regex(initializer_list<charT>, flag_type = regex_constants::ECMAScript);\n\n    ~basic_regex();\n\n    basic_regex& operator=(const basic_regex&);\n    basic_regex& operator=(basic_regex&&) noexcept;\n    basic_regex& operator=(const charT* ptr);\n    basic_regex& operator=(initializer_list<charT> il);\n    template <class ST, class SA>\n        basic_regex& operator=(const basic_string<charT, ST, SA>& p);\n\n    // assign:\n    basic_regex& assign(const basic_regex& that);\n    basic_regex& assign(basic_regex&& that) noexcept;\n    basic_regex& assign(const charT* ptr, flag_type f = regex_constants::ECMAScript);\n    basic_regex& assign(const charT* p, size_t len, flag_type f);\n    template <class string_traits, class A>\n        basic_regex& assign(const basic_string<charT, string_traits, A>& s,\n                            flag_type f = regex_constants::ECMAScript);\n    template <class InputIterator>\n        basic_regex& assign(InputIterator first, InputIterator last,\n                            flag_type f = regex_constants::ECMAScript);\n    basic_regex& assign(initializer_list<charT>, flag_type = regex_constants::ECMAScript);\n\n    // const operations:\n    unsigned mark_count() const;\n    flag_type flags() const;\n\n    // locale:\n    locale_type imbue(locale_type loc);\n    locale_type getloc() const;\n\n    // swap:\n    void swap(basic_regex&);\n};\n\ntypedef basic_regex<char>    regex;\ntypedef basic_regex<wchar_t> wregex;\n\ntemplate <class charT, class traits>\n    void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2);\n\ntemplate <class BidirectionalIterator>\nclass sub_match\n    : public pair<BidirectionalIterator, BidirectionalIterator>\n{\npublic:\n    typedef typename iterator_traits<BidirectionalIterator>::value_type value_type;\n    typedef typename iterator_traits<BidirectionalIterator>::difference_type difference_type;\n    typedef BidirectionalIterator                                      iterator;\n    typedef basic_string<value_type>                                string_type;\n\n    bool matched;\n\n    constexpr sub_match();\n\n    difference_type length() const;\n    operator string_type() const;\n    string_type str() const;\n\n    int compare(const sub_match& s) const;\n    int compare(const string_type& s) const;\n    int compare(const value_type* s) const;\n};\n\ntypedef sub_match<const char*>             csub_match;\ntypedef sub_match<const wchar_t*>          wcsub_match;\ntypedef sub_match<string::const_iterator>  ssub_match;\ntypedef sub_match<wstring::const_iterator> wssub_match;\n\ntemplate <class BiIter>\n    bool\n    operator==(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator!=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator<(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator<=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator>=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter, class ST, class SA>\n    bool\n    operator==(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,\n               const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter, class ST, class SA>\n    bool\n    operator!=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,\n               const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter, class ST, class SA>\n    bool\n    operator<(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,\n              const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter, class ST, class SA>\n    bool\n    operator>(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,\n              const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter, class ST, class SA>\n    bool operator>=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,\n                    const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter, class ST, class SA>\n    bool\n    operator<=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,\n               const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter, class ST, class SA>\n    bool\n    operator==(const sub_match<BiIter>& lhs,\n               const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);\n\ntemplate <class BiIter, class ST, class SA>\n    bool\n    operator!=(const sub_match<BiIter>& lhs,\n               const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);\n\ntemplate <class BiIter, class ST, class SA>\n    bool\n    operator<(const sub_match<BiIter>& lhs,\n              const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);\n\ntemplate <class BiIter, class ST, class SA>\n    bool operator>(const sub_match<BiIter>& lhs,\n                   const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);\n\ntemplate <class BiIter, class ST, class SA>\n    bool\n    operator>=(const sub_match<BiIter>& lhs,\n               const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);\n\ntemplate <class BiIter, class ST, class SA>\n    bool\n    operator<=(const sub_match<BiIter>& lhs,\n               const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator==(typename iterator_traits<BiIter>::value_type const* lhs,\n               const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator!=(typename iterator_traits<BiIter>::value_type const* lhs,\n               const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator<(typename iterator_traits<BiIter>::value_type const* lhs,\n              const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator>(typename iterator_traits<BiIter>::value_type const* lhs,\n              const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator>=(typename iterator_traits<BiIter>::value_type const* lhs,\n               const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator<=(typename iterator_traits<BiIter>::value_type const* lhs,\n               const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator==(const sub_match<BiIter>& lhs,\n               typename iterator_traits<BiIter>::value_type const* rhs);\n\ntemplate <class BiIter>\n    bool\n    operator!=(const sub_match<BiIter>& lhs,\n               typename iterator_traits<BiIter>::value_type const* rhs);\n\ntemplate <class BiIter>\n    bool\n    operator<(const sub_match<BiIter>& lhs,\n              typename iterator_traits<BiIter>::value_type const* rhs);\n\ntemplate <class BiIter>\n    bool\n    operator>(const sub_match<BiIter>& lhs,\n              typename iterator_traits<BiIter>::value_type const* rhs);\n\ntemplate <class BiIter>\n    bool\n    operator>=(const sub_match<BiIter>& lhs,\n               typename iterator_traits<BiIter>::value_type const* rhs);\n\ntemplate <class BiIter>\n    bool\n    operator<=(const sub_match<BiIter>& lhs,\n               typename iterator_traits<BiIter>::value_type const* rhs);\n\ntemplate <class BiIter>\n    bool\n    operator==(typename iterator_traits<BiIter>::value_type const& lhs,\n               const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator!=(typename iterator_traits<BiIter>::value_type const& lhs,\n               const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator<(typename iterator_traits<BiIter>::value_type const& lhs,\n              const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator>(typename iterator_traits<BiIter>::value_type const& lhs,\n              const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator>=(typename iterator_traits<BiIter>::value_type const& lhs,\n               const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator<=(typename iterator_traits<BiIter>::value_type const& lhs,\n               const sub_match<BiIter>& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator==(const sub_match<BiIter>& lhs,\n               typename iterator_traits<BiIter>::value_type const& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator!=(const sub_match<BiIter>& lhs,\n               typename iterator_traits<BiIter>::value_type const& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator<(const sub_match<BiIter>& lhs,\n              typename iterator_traits<BiIter>::value_type const& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator>(const sub_match<BiIter>& lhs,\n              typename iterator_traits<BiIter>::value_type const& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator>=(const sub_match<BiIter>& lhs,\n               typename iterator_traits<BiIter>::value_type const& rhs);\n\ntemplate <class BiIter>\n    bool\n    operator<=(const sub_match<BiIter>& lhs,\n               typename iterator_traits<BiIter>::value_type const& rhs);\n\ntemplate <class charT, class ST, class BiIter>\n    basic_ostream<charT, ST>&\n    operator<<(basic_ostream<charT, ST>& os, const sub_match<BiIter>& m);\n\ntemplate <class BidirectionalIterator,\n          class Allocator = allocator<sub_match<BidirectionalIterator>>>\nclass match_results\n{\npublic:\n    typedef sub_match<BidirectionalIterator>                  value_type;\n    typedef const value_type&                                 const_reference;\n    typedef value_type&                                       reference;\n    typedef /implementation-defined/                          const_iterator;\n    typedef const_iterator                                    iterator;\n    typedef typename iterator_traits<BidirectionalIterator>::difference_type difference_type;\n    typedef typename allocator_traits<Allocator>::size_type   size_type;\n    typedef Allocator                                         allocator_type;\n    typedef typename iterator_traits<BidirectionalIterator>::value_type char_type;\n    typedef basic_string<char_type>                           string_type;\n\n    // construct/copy/destroy:\n    explicit match_results(const Allocator& a = Allocator());\n    match_results(const match_results& m);\n    match_results(match_results&& m) noexcept;\n    match_results& operator=(const match_results& m);\n    match_results& operator=(match_results&& m);\n    ~match_results();\n\n    bool ready() const;\n\n    // size:\n    size_type size() const;\n    size_type max_size() const;\n    bool empty() const;\n\n    // element access:\n    difference_type length(size_type sub = 0) const;\n    difference_type position(size_type sub = 0) const;\n    string_type str(size_type sub = 0) const;\n    const_reference operator[](size_type n) const;\n\n    const_reference prefix() const;\n    const_reference suffix() const;\n\n    const_iterator begin() const;\n    const_iterator end() const;\n    const_iterator cbegin() const;\n    const_iterator cend() const;\n\n    // format:\n    template <class OutputIter>\n        OutputIter\n        format(OutputIter out, const char_type* fmt_first,\n               const char_type* fmt_last,\n               regex_constants::match_flag_type flags = regex_constants::format_default) const;\n    template <class OutputIter, class ST, class SA>\n        OutputIter\n        format(OutputIter out, const basic_string<char_type, ST, SA>& fmt,\n               regex_constants::match_flag_type flags = regex_constants::format_default) const;\n    template <class ST, class SA>\n        basic_string<char_type, ST, SA>\n        format(const basic_string<char_type, ST, SA>& fmt,\n               regex_constants::match_flag_type flags = regex_constants::format_default) const;\n    string_type\n        format(const char_type* fmt,\n               regex_constants::match_flag_type flags = regex_constants::format_default) const;\n\n    // allocator:\n    allocator_type get_allocator() const;\n\n    // swap:\n    void swap(match_results& that);\n};\n\ntypedef match_results<const char*>             cmatch;\ntypedef match_results<const wchar_t*>          wcmatch;\ntypedef match_results<string::const_iterator>  smatch;\ntypedef match_results<wstring::const_iterator> wsmatch;\n\ntemplate <class BidirectionalIterator, class Allocator>\n    bool\n    operator==(const match_results<BidirectionalIterator, Allocator>& m1,\n               const match_results<BidirectionalIterator, Allocator>& m2);\n\ntemplate <class BidirectionalIterator, class Allocator>\n    bool\n    operator!=(const match_results<BidirectionalIterator, Allocator>& m1,\n               const match_results<BidirectionalIterator, Allocator>& m2);\n\ntemplate <class BidirectionalIterator, class Allocator>\n    void\n    swap(match_results<BidirectionalIterator, Allocator>& m1,\n         match_results<BidirectionalIterator, Allocator>& m2);\n\ntemplate <class BidirectionalIterator, class Allocator, class charT, class traits>\n    bool\n    regex_match(BidirectionalIterator first, BidirectionalIterator last,\n                match_results<BidirectionalIterator, Allocator>& m,\n                const basic_regex<charT, traits>& e,\n                regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class BidirectionalIterator, class charT, class traits>\n    bool\n    regex_match(BidirectionalIterator first, BidirectionalIterator last,\n                const basic_regex<charT, traits>& e,\n                regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class charT, class Allocator, class traits>\n    bool\n    regex_match(const charT* str, match_results<const charT*, Allocator>& m,\n                const basic_regex<charT, traits>& e,\n                regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class ST, class SA, class Allocator, class charT, class traits>\n    bool\n    regex_match(const basic_string<charT, ST, SA>& s,\n                match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m,\n                const basic_regex<charT, traits>& e,\n                regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class ST, class SA, class Allocator, class charT, class traits>\n    bool\n    regex_match(const basic_string<charT, ST, SA>&& s,\n                match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m,\n                const basic_regex<charT, traits>& e,\n                regex_constants::match_flag_type flags = regex_constants::match_default) = delete; // C++14\n\ntemplate <class charT, class traits>\n    bool\n    regex_match(const charT* str, const basic_regex<charT, traits>& e,\n                regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class ST, class SA, class charT, class traits>\n    bool\n    regex_match(const basic_string<charT, ST, SA>& s,\n                const basic_regex<charT, traits>& e,\n                regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class BidirectionalIterator, class Allocator, class charT, class traits>\n    bool\n    regex_search(BidirectionalIterator first, BidirectionalIterator last,\n                 match_results<BidirectionalIterator, Allocator>& m,\n                 const basic_regex<charT, traits>& e,\n                 regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class BidirectionalIterator, class charT, class traits>\n    bool\n    regex_search(BidirectionalIterator first, BidirectionalIterator last,\n                 const basic_regex<charT, traits>& e,\n                 regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class charT, class Allocator, class traits>\n    bool\n    regex_search(const charT* str, match_results<const charT*, Allocator>& m,\n                 const basic_regex<charT, traits>& e,\n                 regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class charT, class traits>\n    bool\n    regex_search(const charT* str, const basic_regex<charT, traits>& e,\n                 regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class ST, class SA, class charT, class traits>\n    bool\n    regex_search(const basic_string<charT, ST, SA>& s,\n                 const basic_regex<charT, traits>& e,\n                 regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class ST, class SA, class Allocator, class charT, class traits>\n    bool\n    regex_search(const basic_string<charT, ST, SA>& s,\n                 match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m,\n                 const basic_regex<charT, traits>& e,\n                 regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class ST, class SA, class Allocator, class charT, class traits>\n    bool\n    regex_search(const basic_string<charT, ST, SA>&& s,\n                 match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m,\n                 const basic_regex<charT, traits>& e,\n                 regex_constants::match_flag_type flags = regex_constants::match_default) = delete; // C++14\n\ntemplate <class OutputIterator, class BidirectionalIterator,\n          class traits, class charT, class ST, class SA>\n    OutputIterator\n    regex_replace(OutputIterator out,\n                  BidirectionalIterator first, BidirectionalIterator last,\n                  const basic_regex<charT, traits>& e,\n                  const basic_string<charT, ST, SA>& fmt,\n                  regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class OutputIterator, class BidirectionalIterator,\n          class traits, class charT>\n    OutputIterator\n    regex_replace(OutputIterator out,\n                  BidirectionalIterator first, BidirectionalIterator last,\n                  const basic_regex<charT, traits>& e, const charT* fmt,\n                  regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class traits, class charT, class ST, class SA, class FST, class FSA>>\n    basic_string<charT, ST, SA>\n    regex_replace(const basic_string<charT, ST, SA>& s,\n                  const basic_regex<charT, traits>& e,\n                  const basic_string<charT, FST, FSA>& fmt,\n                  regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class traits, class charT, class ST, class SA>\n    basic_string<charT, ST, SA>\n    regex_replace(const basic_string<charT, ST, SA>& s,\n                  const basic_regex<charT, traits>& e, const charT* fmt,\n                  regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class traits, class charT, class ST, class SA>\n    basic_string<charT>\n    regex_replace(const charT* s,\n                  const basic_regex<charT, traits>& e,\n                  const basic_string<charT, ST, SA>& fmt,\n                  regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class traits, class charT>\n    basic_string<charT>\n    regex_replace(const charT* s,\n                  const basic_regex<charT, traits>& e,\n                  const charT* fmt,\n                  regex_constants::match_flag_type flags = regex_constants::match_default);\n\ntemplate <class BidirectionalIterator,\n          class charT = typename iterator_traits< BidirectionalIterator>::value_type,\n          class traits = regex_traits<charT>>\nclass regex_iterator\n{\npublic:\n    typedef basic_regex<charT, traits>           regex_type;\n    typedef match_results<BidirectionalIterator> value_type;\n    typedef ptrdiff_t                            difference_type;\n    typedef const value_type*                    pointer;\n    typedef const value_type&                    reference;\n    typedef forward_iterator_tag                 iterator_category;\n\n    regex_iterator();\n    regex_iterator(BidirectionalIterator a, BidirectionalIterator b,\n                   const regex_type& re,\n                   regex_constants::match_flag_type m = regex_constants::match_default);\n    regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,\n                   const regex_type&& __re,\n                   regex_constants::match_flag_type __m \n                                     = regex_constants::match_default) = delete; // C++14\n    regex_iterator(const regex_iterator&);\n    regex_iterator& operator=(const regex_iterator&);\n\n    bool operator==(const regex_iterator&) const;\n    bool operator!=(const regex_iterator&) const;\n\n    const value_type& operator*() const;\n    const value_type* operator->() const;\n\n    regex_iterator& operator++();\n    regex_iterator operator++(int);\n};\n\ntypedef regex_iterator<const char*>             cregex_iterator;\ntypedef regex_iterator<const wchar_t*>          wcregex_iterator;\ntypedef regex_iterator<string::const_iterator>  sregex_iterator;\ntypedef regex_iterator<wstring::const_iterator> wsregex_iterator;\n\ntemplate <class BidirectionalIterator,\n          class charT = typename iterator_traits< BidirectionalIterator>::value_type,\n          class traits = regex_traits<charT>>\nclass regex_token_iterator\n{\npublic:\n    typedef basic_regex<charT, traits>       regex_type;\n    typedef sub_match<BidirectionalIterator> value_type;\n    typedef ptrdiff_t                        difference_type;\n    typedef const value_type*                pointer;\n    typedef const value_type&                reference;\n    typedef forward_iterator_tag             iterator_category;\n\n    regex_token_iterator();\n    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,\n                         const regex_type& re, int submatch = 0,\n                         regex_constants::match_flag_type m = regex_constants::match_default);\n    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,\n                         const regex_type&& re, int submatch = 0,\n                         regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14\n    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,\n                         const regex_type& re, const vector<int>& submatches,\n                         regex_constants::match_flag_type m = regex_constants::match_default);\n    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,\n                         const regex_type&& re, const vector<int>& submatches,\n                         regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14\n    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,\n                         const regex_type& re, initializer_list<int> submatches,\n                         regex_constants::match_flag_type m = regex_constants::match_default);\n    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,\n                         const regex_type&& re, initializer_list<int> submatches,\n                         regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14\n    template <size_t N>\n        regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,\n                             const regex_type& re, const int (&submatches)[N],\n                             regex_constants::match_flag_type m = regex_constants::match_default);\n    template <size_t N>\n        regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,\n                             const regex_type& re, const int (&submatches)[N],\n                             regex_constants::match_flag_type m = regex_constants::match_default) = delete // C++14;\n    regex_token_iterator(const regex_token_iterator&);\n    regex_token_iterator& operator=(const regex_token_iterator&);\n\n    bool operator==(const regex_token_iterator&) const;\n    bool operator!=(const regex_token_iterator&) const;\n\n    const value_type& operator*() const;\n    const value_type* operator->() const;\n\n    regex_token_iterator& operator++();\n    regex_token_iterator operator++(int);\n};\n\ntypedef regex_token_iterator<const char*>             cregex_token_iterator;\ntypedef regex_token_iterator<const wchar_t*>          wcregex_token_iterator;\ntypedef regex_token_iterator<string::const_iterator>  sregex_token_iterator;\ntypedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;\n\n} // std\n*/\n\n#include <__config>\n#include <stdexcept>\n#include <__locale>\n#include <initializer_list>\n#include <utility>\n#include <iterator>\n#include <string>\n#include <memory>\n#include <vector>\n#include <deque>\n\n#include <__undef_min_max>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nnamespace regex_constants\n{\n\n// syntax_option_type\n\nenum syntax_option_type\n{\n    icase      = 1 << 0,\n    nosubs     = 1 << 1,\n    optimize   = 1 << 2,\n    collate    = 1 << 3,\n    ECMAScript = 0,\n    basic      = 1 << 4,\n    extended   = 1 << 5,\n    awk        = 1 << 6,\n    grep       = 1 << 7,\n    egrep      = 1 << 8\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nsyntax_option_type\noperator~(syntax_option_type __x)\n{\n    return syntax_option_type(~int(__x) & 0x1FF);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nsyntax_option_type\noperator&(syntax_option_type __x, syntax_option_type __y)\n{\n    return syntax_option_type(int(__x) & int(__y));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nsyntax_option_type\noperator|(syntax_option_type __x, syntax_option_type __y)\n{\n    return syntax_option_type(int(__x) | int(__y));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nsyntax_option_type\noperator^(syntax_option_type __x, syntax_option_type __y)\n{\n    return syntax_option_type(int(__x) ^ int(__y));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nsyntax_option_type&\noperator&=(syntax_option_type& __x, syntax_option_type __y)\n{\n    __x = __x & __y;\n    return __x;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nsyntax_option_type&\noperator|=(syntax_option_type& __x, syntax_option_type __y)\n{\n    __x = __x | __y;\n    return __x;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nsyntax_option_type&\noperator^=(syntax_option_type& __x, syntax_option_type __y)\n{\n    __x = __x ^ __y;\n    return __x;\n}\n\n// match_flag_type\n\nenum match_flag_type\n{\n    match_default     = 0,\n    match_not_bol     = 1 << 0,\n    match_not_eol     = 1 << 1,\n    match_not_bow     = 1 << 2,\n    match_not_eow     = 1 << 3,\n    match_any         = 1 << 4,\n    match_not_null    = 1 << 5,\n    match_continuous  = 1 << 6,\n    match_prev_avail  = 1 << 7,\n    format_default    = 0,\n    format_sed        = 1 << 8,\n    format_no_copy    = 1 << 9,\n    format_first_only = 1 << 10,\n    __no_update_pos   = 1 << 11\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nmatch_flag_type\noperator~(match_flag_type __x)\n{\n    return match_flag_type(~int(__x) & 0x0FFF);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nmatch_flag_type\noperator&(match_flag_type __x, match_flag_type __y)\n{\n    return match_flag_type(int(__x) & int(__y));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nmatch_flag_type\noperator|(match_flag_type __x, match_flag_type __y)\n{\n    return match_flag_type(int(__x) | int(__y));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\n_LIBCPP_CONSTEXPR\nmatch_flag_type\noperator^(match_flag_type __x, match_flag_type __y)\n{\n    return match_flag_type(int(__x) ^ int(__y));\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nmatch_flag_type&\noperator&=(match_flag_type& __x, match_flag_type __y)\n{\n    __x = __x & __y;\n    return __x;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nmatch_flag_type&\noperator|=(match_flag_type& __x, match_flag_type __y)\n{\n    __x = __x | __y;\n    return __x;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nmatch_flag_type&\noperator^=(match_flag_type& __x, match_flag_type __y)\n{\n    __x = __x ^ __y;\n    return __x;\n}\n\nenum error_type\n{\n    error_collate = 1,\n    error_ctype,\n    error_escape,\n    error_backref,\n    error_brack,\n    error_paren,\n    error_brace,\n    error_badbrace,\n    error_range,\n    error_space,\n    error_badrepeat,\n    error_complexity,\n    error_stack,\n    __re_err_grammar,\n    __re_err_empty,\n    __re_err_unknown\n};\n\n}  // regex_constants\n\nclass _LIBCPP_EXCEPTION_ABI regex_error\n    : public runtime_error\n{\n    regex_constants::error_type __code_;\npublic:\n    explicit regex_error(regex_constants::error_type __ecode);\n    virtual ~regex_error() throw();\n     _LIBCPP_INLINE_VISIBILITY\n    regex_constants::error_type code() const {return __code_;}\n};\n\ntemplate <regex_constants::error_type _Ev>\n_LIBCPP_ALWAYS_INLINE\nvoid __throw_regex_error()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n\tthrow regex_error(_Ev);\n#endif\n}\n\ntemplate <class _CharT>\nstruct _LIBCPP_TYPE_VIS_ONLY regex_traits\n{\npublic:\n    typedef _CharT                  char_type;\n    typedef basic_string<char_type> string_type;\n    typedef locale                  locale_type;\n#ifdef __ANDROID__\n    typedef uint16_t                char_class_type;\n#else\n    typedef ctype_base::mask        char_class_type;\n#endif\n\n#ifdef __ANDROID__\n    static const char_class_type __regex_word = 0x8000;\n#else\n    static const char_class_type __regex_word = 0x80;\n#endif\n\nprivate:\n    locale __loc_;\n    const ctype<char_type>* __ct_;\n    const collate<char_type>* __col_;\n\npublic:\n    regex_traits();\n\n    _LIBCPP_INLINE_VISIBILITY\n    static size_t length(const char_type* __p)\n        {return char_traits<char_type>::length(__p);}\n    _LIBCPP_INLINE_VISIBILITY\n    char_type translate(char_type __c) const {return __c;}\n    char_type translate_nocase(char_type __c) const;\n    template <class _ForwardIterator>\n        string_type\n        transform(_ForwardIterator __f, _ForwardIterator __l) const;\n    template <class _ForwardIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        string_type\n        transform_primary( _ForwardIterator __f, _ForwardIterator __l) const\n            {return __transform_primary(__f, __l, char_type());}\n    template <class _ForwardIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        string_type\n        lookup_collatename(_ForwardIterator __f, _ForwardIterator __l) const\n            {return __lookup_collatename(__f, __l, char_type());}\n    template <class _ForwardIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        char_class_type\n        lookup_classname(_ForwardIterator __f, _ForwardIterator __l,\n                         bool __icase = false) const\n            {return __lookup_classname(__f, __l, __icase, char_type());}\n    bool isctype(char_type __c, char_class_type __m) const;\n    _LIBCPP_INLINE_VISIBILITY\n    int value(char_type __ch, int __radix) const\n        {return __regex_traits_value(__ch, __radix);}\n    locale_type imbue(locale_type __l);\n    _LIBCPP_INLINE_VISIBILITY\n    locale_type getloc()const {return __loc_;}\n\nprivate:\n    void __init();\n\n    template <class _ForwardIterator>\n        string_type\n        __transform_primary(_ForwardIterator __f, _ForwardIterator __l, char) const;\n    template <class _ForwardIterator>\n        string_type\n        __transform_primary(_ForwardIterator __f, _ForwardIterator __l, wchar_t) const;\n\n    template <class _ForwardIterator>\n        string_type\n        __lookup_collatename(_ForwardIterator __f, _ForwardIterator __l, char) const;\n    template <class _ForwardIterator>\n        string_type\n        __lookup_collatename(_ForwardIterator __f, _ForwardIterator __l, wchar_t) const;\n\n    template <class _ForwardIterator>\n        char_class_type\n        __lookup_classname(_ForwardIterator __f, _ForwardIterator __l,\n                           bool __icase, char) const;\n    template <class _ForwardIterator>\n        char_class_type\n        __lookup_classname(_ForwardIterator __f, _ForwardIterator __l,\n                           bool __icase, wchar_t) const;\n\n    static int __regex_traits_value(unsigned char __ch, int __radix);\n    _LIBCPP_INLINE_VISIBILITY\n    int __regex_traits_value(char __ch, int __radix) const\n        {return __regex_traits_value(static_cast<unsigned char>(__ch), __radix);}\n    int __regex_traits_value(wchar_t __ch, int __radix) const;\n};\n\ntemplate <class _CharT>\nconst typename regex_traits<_CharT>::char_class_type\nregex_traits<_CharT>::__regex_word;\n\ntemplate <class _CharT>\nregex_traits<_CharT>::regex_traits()\n{\n    __init();\n}\n\ntemplate <class _CharT>\ntypename regex_traits<_CharT>::char_type\nregex_traits<_CharT>::translate_nocase(char_type __c) const\n{\n    return __ct_->tolower(__c);\n}\n\ntemplate <class _CharT>\ntemplate <class _ForwardIterator>\ntypename regex_traits<_CharT>::string_type\nregex_traits<_CharT>::transform(_ForwardIterator __f, _ForwardIterator __l) const\n{\n    string_type __s(__f, __l);\n    return __col_->transform(__s.data(), __s.data() + __s.size());\n}\n\ntemplate <class _CharT>\nvoid\nregex_traits<_CharT>::__init()\n{\n    __ct_ = &use_facet<ctype<char_type> >(__loc_);\n    __col_ = &use_facet<collate<char_type> >(__loc_);\n}\n\ntemplate <class _CharT>\ntypename regex_traits<_CharT>::locale_type\nregex_traits<_CharT>::imbue(locale_type __l)\n{\n    locale __r = __loc_;\n    __loc_ = __l;\n    __init();\n    return __r;\n}\n\n// transform_primary is very FreeBSD-specific\n\ntemplate <class _CharT>\ntemplate <class _ForwardIterator>\ntypename regex_traits<_CharT>::string_type\nregex_traits<_CharT>::__transform_primary(_ForwardIterator __f,\n                                          _ForwardIterator __l, char) const\n{\n    const string_type __s(__f, __l);\n    string_type __d = __col_->transform(__s.data(), __s.data() + __s.size());\n    switch (__d.size())\n    {\n    case 1:\n        break;\n    case 12:\n        __d[11] = __d[3];\n        break;\n    default:\n        __d.clear();\n        break;\n    }\n    return __d;\n}\n\ntemplate <class _CharT>\ntemplate <class _ForwardIterator>\ntypename regex_traits<_CharT>::string_type\nregex_traits<_CharT>::__transform_primary(_ForwardIterator __f,\n                                          _ForwardIterator __l, wchar_t) const\n{\n    const string_type __s(__f, __l);\n    string_type __d = __col_->transform(__s.data(), __s.data() + __s.size());\n    switch (__d.size())\n    {\n    case 1:\n        break;\n    case 3:\n        __d[2] = __d[0];\n        break;\n    default:\n        __d.clear();\n        break;\n    }\n    return __d;\n}\n\n// lookup_collatename is very FreeBSD-specific\n\n_LIBCPP_FUNC_VIS string __get_collation_name(const char* __s);\n\ntemplate <class _CharT>\ntemplate <class _ForwardIterator>\ntypename regex_traits<_CharT>::string_type\nregex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f,\n                                           _ForwardIterator __l, char) const\n{\n    string_type __s(__f, __l);\n    string_type __r;\n    if (!__s.empty())\n    {\n        __r = __get_collation_name(__s.c_str());\n        if (__r.empty() && __s.size() <= 2)\n        {\n            __r = __col_->transform(__s.data(), __s.data() + __s.size());\n            if (__r.size() == 1 || __r.size() == 12)\n                __r = __s;\n            else\n                __r.clear();\n        }\n    }\n    return __r;\n}\n\ntemplate <class _CharT>\ntemplate <class _ForwardIterator>\ntypename regex_traits<_CharT>::string_type\nregex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f,\n                                           _ForwardIterator __l, wchar_t) const\n{\n    string_type __s(__f, __l);\n    string __n;\n    __n.reserve(__s.size());\n    for (typename string_type::const_iterator __i = __s.begin(), __e = __s.end();\n                                                              __i != __e; ++__i)\n    {\n        if (static_cast<unsigned>(*__i) >= 127)\n            return string_type();\n        __n.push_back(char(*__i));\n    }\n    string_type __r;\n    if (!__s.empty())\n    {\n        __n = __get_collation_name(__n.c_str());\n        if (!__n.empty())\n            __r.assign(__n.begin(), __n.end());\n        else if (__s.size() <= 2)\n        {\n            __r = __col_->transform(__s.data(), __s.data() + __s.size());\n            if (__r.size() == 1 || __r.size() == 3)\n                __r = __s;\n            else\n                __r.clear();\n        }\n    }\n    return __r;\n}\n\n// lookup_classname\n\nregex_traits<char>::char_class_type _LIBCPP_FUNC_VIS\n__get_classname(const char* __s, bool __icase);\n\ntemplate <class _CharT>\ntemplate <class _ForwardIterator>\ntypename regex_traits<_CharT>::char_class_type\nregex_traits<_CharT>::__lookup_classname(_ForwardIterator __f,\n                                         _ForwardIterator __l,\n                                         bool __icase, char) const\n{\n    string_type __s(__f, __l);\n    __ct_->tolower(&__s[0], &__s[0] + __s.size());\n    return __get_classname(__s.c_str(), __icase);\n}\n\ntemplate <class _CharT>\ntemplate <class _ForwardIterator>\ntypename regex_traits<_CharT>::char_class_type\nregex_traits<_CharT>::__lookup_classname(_ForwardIterator __f,\n                                         _ForwardIterator __l,\n                                         bool __icase, wchar_t) const\n{\n    string_type __s(__f, __l);\n    __ct_->tolower(&__s[0], &__s[0] + __s.size());\n    string __n;\n    __n.reserve(__s.size());\n    for (typename string_type::const_iterator __i = __s.begin(), __e = __s.end();\n                                                              __i != __e; ++__i)\n    {\n        if (static_cast<unsigned>(*__i) >= 127)\n            return char_class_type();\n        __n.push_back(char(*__i));\n    }\n    return __get_classname(__n.c_str(), __icase);\n}\n\ntemplate <class _CharT>\nbool\nregex_traits<_CharT>::isctype(char_type __c, char_class_type __m) const\n{\n    if (__ct_->is(__m, __c))\n        return true;\n    return (__c == '_' && (__m & __regex_word));\n}\n\ntemplate <class _CharT>\nint\nregex_traits<_CharT>::__regex_traits_value(unsigned char __ch, int __radix)\n{\n    if ((__ch & 0xF8u) == 0x30)  // '0' <= __ch && __ch <= '7'\n        return __ch - '0';\n    if (__radix != 8)\n    {\n        if ((__ch & 0xFEu) == 0x38)  // '8' <= __ch && __ch <= '9'\n            return __ch - '0';\n        if (__radix == 16)\n        {\n            __ch |= 0x20;  // tolower\n            if ('a' <= __ch && __ch <= 'f')\n                return __ch - ('a' - 10);\n        }\n    }\n    return -1;\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nint\nregex_traits<_CharT>::__regex_traits_value(wchar_t __ch, int __radix) const\n{\n    return __regex_traits_value(static_cast<unsigned char>(__ct_->narrow(__ch, char_type())), __radix);\n}\n\ntemplate <class _CharT> class __node;\n\ntemplate <class _BidirectionalIterator> class _LIBCPP_TYPE_VIS_ONLY sub_match;\n\ntemplate <class _BidirectionalIterator,\n          class _Allocator = allocator<sub_match<_BidirectionalIterator> > >\nclass _LIBCPP_TYPE_VIS_ONLY match_results;\n\ntemplate <class _CharT>\nstruct __state\n{\n    enum\n    {\n        __end_state = -1000,\n        __consume_input,  // -999\n        __begin_marked_expr, // -998\n        __end_marked_expr,   // -997\n        __pop_state,           // -996\n        __accept_and_consume,  // -995\n        __accept_but_not_consume,  // -994\n        __reject,                  // -993\n        __split,\n        __repeat\n    };\n\n    int __do_;\n    const _CharT* __first_;\n    const _CharT* __current_;\n    const _CharT* __last_;\n    vector<sub_match<const _CharT*> > __sub_matches_;\n    vector<pair<size_t, const _CharT*> > __loop_data_;\n    const __node<_CharT>* __node_;\n    regex_constants::match_flag_type __flags_;\n    bool __at_first_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __state()\n        : __do_(0), __first_(nullptr), __current_(nullptr), __last_(nullptr),\n          __node_(nullptr), __flags_() {}\n};\n\n// __node\n\ntemplate <class _CharT>\nclass __node\n{\n    __node(const __node&);\n    __node& operator=(const __node&);\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __node() {}\n    _LIBCPP_INLINE_VISIBILITY\n    virtual ~__node() {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    virtual void __exec(__state&) const {};\n    _LIBCPP_INLINE_VISIBILITY\n    virtual void __exec_split(bool, __state&) const {};\n};\n\n// __end_state\n\ntemplate <class _CharT>\nclass __end_state\n    : public __node<_CharT>\n{\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __end_state() {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT>\nvoid\n__end_state<_CharT>::__exec(__state& __s) const\n{\n    __s.__do_ = __state::__end_state;\n}\n\n// __has_one_state\n\ntemplate <class _CharT>\nclass __has_one_state\n    : public __node<_CharT>\n{\n    __node<_CharT>* __first_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __has_one_state(__node<_CharT>* __s)\n        : __first_(__s) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __node<_CharT>*  first() const {return __first_;}\n    _LIBCPP_INLINE_VISIBILITY\n    __node<_CharT>*& first()       {return __first_;}\n};\n\n// __owns_one_state\n\ntemplate <class _CharT>\nclass __owns_one_state\n    : public __has_one_state<_CharT>\n{\n    typedef __has_one_state<_CharT> base;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __owns_one_state(__node<_CharT>* __s)\n        : base(__s) {}\n\n    virtual ~__owns_one_state();\n};\n\ntemplate <class _CharT>\n__owns_one_state<_CharT>::~__owns_one_state()\n{\n    delete this->first();\n}\n\n// __empty_state\n\ntemplate <class _CharT>\nclass __empty_state\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __empty_state(__node<_CharT>* __s)\n        : base(__s) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT>\nvoid\n__empty_state<_CharT>::__exec(__state& __s) const\n{\n    __s.__do_ = __state::__accept_but_not_consume;\n    __s.__node_ = this->first();\n}\n\n// __empty_non_own_state\n\ntemplate <class _CharT>\nclass __empty_non_own_state\n    : public __has_one_state<_CharT>\n{\n    typedef __has_one_state<_CharT> base;\n\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __empty_non_own_state(__node<_CharT>* __s)\n        : base(__s) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT>\nvoid\n__empty_non_own_state<_CharT>::__exec(__state& __s) const\n{\n    __s.__do_ = __state::__accept_but_not_consume;\n    __s.__node_ = this->first();\n}\n\n// __repeat_one_loop\n\ntemplate <class _CharT>\nclass __repeat_one_loop\n    : public __has_one_state<_CharT>\n{\n    typedef __has_one_state<_CharT> base;\n\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __repeat_one_loop(__node<_CharT>* __s)\n        : base(__s) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT>\nvoid\n__repeat_one_loop<_CharT>::__exec(__state& __s) const\n{\n    __s.__do_ = __state::__repeat;\n    __s.__node_ = this->first();\n}\n\n// __owns_two_states\n\ntemplate <class _CharT>\nclass __owns_two_states\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\n    base* __second_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __owns_two_states(__node<_CharT>* __s1, base* __s2)\n        : base(__s1), __second_(__s2) {}\n\n    virtual ~__owns_two_states();\n\n    _LIBCPP_INLINE_VISIBILITY\n    base*  second() const {return __second_;}\n    _LIBCPP_INLINE_VISIBILITY\n    base*& second()       {return __second_;}\n};\n\ntemplate <class _CharT>\n__owns_two_states<_CharT>::~__owns_two_states()\n{\n    delete __second_;\n}\n\n// __loop\n\ntemplate <class _CharT>\nclass __loop\n    : public __owns_two_states<_CharT>\n{\n    typedef __owns_two_states<_CharT> base;\n\n    size_t __min_;\n    size_t __max_;\n    unsigned __loop_id_;\n    unsigned __mexp_begin_;\n    unsigned __mexp_end_;\n    bool __greedy_;\n\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __loop(unsigned __loop_id,\n                          __node<_CharT>* __s1, __owns_one_state<_CharT>* __s2,\n                          unsigned __mexp_begin, unsigned __mexp_end,\n                          bool __greedy = true,\n                          size_t __min = 0,\n                          size_t __max = numeric_limits<size_t>::max())\n        : base(__s1, __s2), __min_(__min), __max_(__max), __loop_id_(__loop_id),\n          __mexp_begin_(__mexp_begin), __mexp_end_(__mexp_end),\n          __greedy_(__greedy) {}\n\n    virtual void __exec(__state& __s) const;\n    virtual void __exec_split(bool __second, __state& __s) const;\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    void __init_repeat(__state& __s) const\n    {\n        __s.__loop_data_[__loop_id_].second = __s.__current_;\n        for (size_t __i = __mexp_begin_-1; __i != __mexp_end_-1; ++__i)\n        {\n            __s.__sub_matches_[__i].first = __s.__last_;\n            __s.__sub_matches_[__i].second = __s.__last_;\n            __s.__sub_matches_[__i].matched = false;\n        }\n    }\n};\n\ntemplate <class _CharT>\nvoid\n__loop<_CharT>::__exec(__state& __s) const\n{\n    if (__s.__do_ == __state::__repeat)\n    {\n        bool __do_repeat = ++__s.__loop_data_[__loop_id_].first < __max_;\n        bool __do_alt = __s.__loop_data_[__loop_id_].first >= __min_;\n        if (__do_repeat && __do_alt &&\n                               __s.__loop_data_[__loop_id_].second == __s.__current_)\n            __do_repeat = false;\n        if (__do_repeat && __do_alt)\n            __s.__do_ = __state::__split;\n        else if (__do_repeat)\n        {\n            __s.__do_ = __state::__accept_but_not_consume;\n            __s.__node_ = this->first();\n            __init_repeat(__s);\n        }\n        else\n        {\n            __s.__do_ = __state::__accept_but_not_consume;\n            __s.__node_ = this->second();\n        }\n    }\n    else\n    {\n        __s.__loop_data_[__loop_id_].first = 0;\n        bool __do_repeat = 0 < __max_;\n        bool __do_alt = 0 >= __min_;\n        if (__do_repeat && __do_alt)\n            __s.__do_ = __state::__split;\n        else if (__do_repeat)\n        {\n            __s.__do_ = __state::__accept_but_not_consume;\n            __s.__node_ = this->first();\n            __init_repeat(__s);\n        }\n        else\n        {\n            __s.__do_ = __state::__accept_but_not_consume;\n            __s.__node_ = this->second();\n        }\n    }\n}\n\ntemplate <class _CharT>\nvoid\n__loop<_CharT>::__exec_split(bool __second, __state& __s) const\n{\n    __s.__do_ = __state::__accept_but_not_consume;\n    if (__greedy_ != __second)\n    {\n        __s.__node_ = this->first();\n        __init_repeat(__s);\n    }\n    else\n        __s.__node_ = this->second();\n}\n\n// __alternate\n\ntemplate <class _CharT>\nclass __alternate\n    : public __owns_two_states<_CharT>\n{\n    typedef __owns_two_states<_CharT> base;\n\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __alternate(__owns_one_state<_CharT>* __s1,\n                         __owns_one_state<_CharT>* __s2)\n        : base(__s1, __s2) {}\n\n    virtual void __exec(__state& __s) const;\n    virtual void __exec_split(bool __second, __state& __s) const;\n};\n\ntemplate <class _CharT>\nvoid\n__alternate<_CharT>::__exec(__state& __s) const\n{\n    __s.__do_ = __state::__split;\n}\n\ntemplate <class _CharT>\nvoid\n__alternate<_CharT>::__exec_split(bool __second, __state& __s) const\n{\n    __s.__do_ = __state::__accept_but_not_consume;\n    if (__second)\n        __s.__node_ = this->second();\n    else\n        __s.__node_ = this->first();\n}\n\n// __begin_marked_subexpression\n\ntemplate <class _CharT>\nclass __begin_marked_subexpression\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\n    unsigned __mexp_;\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __begin_marked_subexpression(unsigned __mexp, __node<_CharT>* __s)\n        : base(__s), __mexp_(__mexp) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT>\nvoid\n__begin_marked_subexpression<_CharT>::__exec(__state& __s) const\n{\n    __s.__do_ = __state::__accept_but_not_consume;\n    __s.__sub_matches_[__mexp_-1].first = __s.__current_;\n    __s.__node_ = this->first();\n}\n\n// __end_marked_subexpression\n\ntemplate <class _CharT>\nclass __end_marked_subexpression\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\n    unsigned __mexp_;\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __end_marked_subexpression(unsigned __mexp, __node<_CharT>* __s)\n        : base(__s), __mexp_(__mexp) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT>\nvoid\n__end_marked_subexpression<_CharT>::__exec(__state& __s) const\n{\n    __s.__do_ = __state::__accept_but_not_consume;\n    __s.__sub_matches_[__mexp_-1].second = __s.__current_;\n    __s.__sub_matches_[__mexp_-1].matched = true;\n    __s.__node_ = this->first();\n}\n\n// __back_ref\n\ntemplate <class _CharT>\nclass __back_ref\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\n    unsigned __mexp_;\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __back_ref(unsigned __mexp, __node<_CharT>* __s)\n        : base(__s), __mexp_(__mexp) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT>\nvoid\n__back_ref<_CharT>::__exec(__state& __s) const\n{\n    sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_-1];\n    if (__sm.matched)\n    {\n        ptrdiff_t __len = __sm.second - __sm.first;\n        if (__s.__last_ - __s.__current_ >= __len &&\n            _VSTD::equal(__sm.first, __sm.second, __s.__current_))\n        {\n            __s.__do_ = __state::__accept_but_not_consume;\n            __s.__current_ += __len;\n            __s.__node_ = this->first();\n        }\n        else\n        {\n            __s.__do_ = __state::__reject;\n            __s.__node_ = nullptr;\n        }\n    }\n    else\n    {\n        __s.__do_ = __state::__reject;\n        __s.__node_ = nullptr;\n    }\n}\n\n// __back_ref_icase\n\ntemplate <class _CharT, class _Traits>\nclass __back_ref_icase\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\n    _Traits __traits_;\n    unsigned __mexp_;\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __back_ref_icase(const _Traits& __traits, unsigned __mexp,\n                              __node<_CharT>* __s)\n        : base(__s), __traits_(__traits), __mexp_(__mexp) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT, class _Traits>\nvoid\n__back_ref_icase<_CharT, _Traits>::__exec(__state& __s) const\n{\n    sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_-1];\n    if (__sm.matched)\n    {\n        ptrdiff_t __len = __sm.second - __sm.first;\n        if (__s.__last_ - __s.__current_ >= __len)\n        {\n            for (ptrdiff_t __i = 0; __i < __len; ++__i)\n            {\n                if (__traits_.translate_nocase(__sm.first[__i]) !=\n                                __traits_.translate_nocase(__s.__current_[__i]))\n                    goto __not_equal;\n            }\n            __s.__do_ = __state::__accept_but_not_consume;\n            __s.__current_ += __len;\n            __s.__node_ = this->first();\n        }\n        else\n        {\n            __s.__do_ = __state::__reject;\n            __s.__node_ = nullptr;\n        }\n    }\n    else\n    {\n__not_equal:\n        __s.__do_ = __state::__reject;\n        __s.__node_ = nullptr;\n    }\n}\n\n// __back_ref_collate\n\ntemplate <class _CharT, class _Traits>\nclass __back_ref_collate\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\n    _Traits __traits_;\n    unsigned __mexp_;\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __back_ref_collate(const _Traits& __traits, unsigned __mexp,\n                              __node<_CharT>* __s)\n        : base(__s), __traits_(__traits), __mexp_(__mexp) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT, class _Traits>\nvoid\n__back_ref_collate<_CharT, _Traits>::__exec(__state& __s) const\n{\n    sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_-1];\n    if (__sm.matched)\n    {\n        ptrdiff_t __len = __sm.second - __sm.first;\n        if (__s.__last_ - __s.__current_ >= __len)\n        {\n            for (ptrdiff_t __i = 0; __i < __len; ++__i)\n            {\n                if (__traits_.translate(__sm.first[__i]) !=\n                                       __traits_.translate(__s.__current_[__i]))\n                    goto __not_equal;\n            }\n            __s.__do_ = __state::__accept_but_not_consume;\n            __s.__current_ += __len;\n            __s.__node_ = this->first();\n        }\n        else\n        {\n            __s.__do_ = __state::__reject;\n            __s.__node_ = nullptr;\n        }\n    }\n    else\n    {\n__not_equal:\n        __s.__do_ = __state::__reject;\n        __s.__node_ = nullptr;\n    }\n}\n\n// __word_boundary\n\ntemplate <class _CharT, class _Traits>\nclass __word_boundary\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\n    _Traits __traits_;\n    bool __invert_;\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __word_boundary(const _Traits& __traits, bool __invert,\n                             __node<_CharT>* __s)\n        : base(__s), __traits_(__traits), __invert_(__invert) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT, class _Traits>\nvoid\n__word_boundary<_CharT, _Traits>::__exec(__state& __s) const\n{\n    bool __is_word_b = false;\n    if (__s.__first_ != __s.__last_)\n    {\n        if (__s.__current_ == __s.__last_)\n        {\n            if (!(__s.__flags_ & regex_constants::match_not_eow))\n            {\n                _CharT __c = __s.__current_[-1];\n                __is_word_b = __c == '_' ||\n                              __traits_.isctype(__c, ctype_base::alnum);\n            }\n        }\n        else if (__s.__current_ == __s.__first_ &&\n                !(__s.__flags_ & regex_constants::match_prev_avail))\n        {\n            if (!(__s.__flags_ & regex_constants::match_not_bow))\n            {\n                _CharT __c = *__s.__current_;\n                __is_word_b = __c == '_' ||\n                              __traits_.isctype(__c, ctype_base::alnum);\n            }\n        }\n        else\n        {\n            _CharT __c1 = __s.__current_[-1];\n            _CharT __c2 = *__s.__current_;\n            bool __is_c1_b = __c1 == '_' ||\n                             __traits_.isctype(__c1, ctype_base::alnum);\n            bool __is_c2_b = __c2 == '_' ||\n                             __traits_.isctype(__c2, ctype_base::alnum);\n            __is_word_b = __is_c1_b != __is_c2_b;\n        }\n    }\n    if (__is_word_b != __invert_)\n    {\n        __s.__do_ = __state::__accept_but_not_consume;\n        __s.__node_ = this->first();\n    }\n    else\n    {\n        __s.__do_ = __state::__reject;\n        __s.__node_ = nullptr;\n    }\n}\n\n// __l_anchor\n\ntemplate <class _CharT>\nclass __l_anchor\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __l_anchor(__node<_CharT>* __s)\n        : base(__s) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT>\nvoid\n__l_anchor<_CharT>::__exec(__state& __s) const\n{\n    if (__s.__at_first_ && __s.__current_ == __s.__first_ &&\n        !(__s.__flags_ & regex_constants::match_not_bol))\n    {\n        __s.__do_ = __state::__accept_but_not_consume;\n        __s.__node_ = this->first();\n    }\n    else\n    {\n        __s.__do_ = __state::__reject;\n        __s.__node_ = nullptr;\n    }\n}\n\n// __r_anchor\n\ntemplate <class _CharT>\nclass __r_anchor\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __r_anchor(__node<_CharT>* __s)\n        : base(__s) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT>\nvoid\n__r_anchor<_CharT>::__exec(__state& __s) const\n{\n    if (__s.__current_ == __s.__last_ &&\n        !(__s.__flags_ & regex_constants::match_not_eol))\n    {\n        __s.__do_ = __state::__accept_but_not_consume;\n        __s.__node_ = this->first();\n    }\n    else\n    {\n        __s.__do_ = __state::__reject;\n        __s.__node_ = nullptr;\n    }\n}\n\n// __match_any\n\ntemplate <class _CharT>\nclass __match_any\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __match_any(__node<_CharT>* __s)\n        : base(__s) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT>\nvoid\n__match_any<_CharT>::__exec(__state& __s) const\n{\n    if (__s.__current_ != __s.__last_ && *__s.__current_ != 0)\n    {\n        __s.__do_ = __state::__accept_and_consume;\n        ++__s.__current_;\n        __s.__node_ = this->first();\n    }\n    else\n    {\n        __s.__do_ = __state::__reject;\n        __s.__node_ = nullptr;\n    }\n}\n\n// __match_any_but_newline\n\ntemplate <class _CharT>\nclass __match_any_but_newline\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __match_any_but_newline(__node<_CharT>* __s)\n        : base(__s) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <> _LIBCPP_FUNC_VIS void __match_any_but_newline<char>::__exec(__state&) const;\ntemplate <> _LIBCPP_FUNC_VIS void __match_any_but_newline<wchar_t>::__exec(__state&) const;\n\n// __match_char\n\ntemplate <class _CharT>\nclass __match_char\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\n    _CharT __c_;\n\n    __match_char(const __match_char&);\n    __match_char& operator=(const __match_char&);\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __match_char(_CharT __c, __node<_CharT>* __s)\n        : base(__s), __c_(__c) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT>\nvoid\n__match_char<_CharT>::__exec(__state& __s) const\n{\n    if (__s.__current_ != __s.__last_ && *__s.__current_ == __c_)\n    {\n        __s.__do_ = __state::__accept_and_consume;\n        ++__s.__current_;\n        __s.__node_ = this->first();\n    }\n    else\n    {\n        __s.__do_ = __state::__reject;\n        __s.__node_ = nullptr;\n    }\n}\n\n// __match_char_icase\n\ntemplate <class _CharT, class _Traits>\nclass __match_char_icase\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\n    _Traits __traits_;\n    _CharT __c_;\n\n    __match_char_icase(const __match_char_icase&);\n    __match_char_icase& operator=(const __match_char_icase&);\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __match_char_icase(const _Traits& __traits, _CharT __c, __node<_CharT>* __s)\n        : base(__s), __traits_(__traits), __c_(__traits.translate_nocase(__c)) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT, class _Traits>\nvoid\n__match_char_icase<_CharT, _Traits>::__exec(__state& __s) const\n{\n    if (__s.__current_ != __s.__last_ &&\n        __traits_.translate_nocase(*__s.__current_) == __c_)\n    {\n        __s.__do_ = __state::__accept_and_consume;\n        ++__s.__current_;\n        __s.__node_ = this->first();\n    }\n    else\n    {\n        __s.__do_ = __state::__reject;\n        __s.__node_ = nullptr;\n    }\n}\n\n// __match_char_collate\n\ntemplate <class _CharT, class _Traits>\nclass __match_char_collate\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\n    _Traits __traits_;\n    _CharT __c_;\n\n    __match_char_collate(const __match_char_collate&);\n    __match_char_collate& operator=(const __match_char_collate&);\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __match_char_collate(const _Traits& __traits, _CharT __c, __node<_CharT>* __s)\n        : base(__s), __traits_(__traits), __c_(__traits.translate(__c)) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT, class _Traits>\nvoid\n__match_char_collate<_CharT, _Traits>::__exec(__state& __s) const\n{\n    if (__s.__current_ != __s.__last_ &&\n        __traits_.translate(*__s.__current_) == __c_)\n    {\n        __s.__do_ = __state::__accept_and_consume;\n        ++__s.__current_;\n        __s.__node_ = this->first();\n    }\n    else\n    {\n        __s.__do_ = __state::__reject;\n        __s.__node_ = nullptr;\n    }\n}\n\n// __bracket_expression\n\ntemplate <class _CharT, class _Traits>\nclass __bracket_expression\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n    typedef typename _Traits::string_type string_type;\n\n    _Traits __traits_;\n    vector<_CharT> __chars_;\n    vector<_CharT> __neg_chars_;\n    vector<pair<string_type, string_type> > __ranges_;\n    vector<pair<_CharT, _CharT> > __digraphs_;\n    vector<string_type> __equivalences_;\n    typename regex_traits<_CharT>::char_class_type __mask_;\n    typename regex_traits<_CharT>::char_class_type __neg_mask_;\n    bool __negate_;\n    bool __icase_;\n    bool __collate_;\n    bool __might_have_digraph_;\n\n    __bracket_expression(const __bracket_expression&);\n    __bracket_expression& operator=(const __bracket_expression&);\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __bracket_expression(const _Traits& __traits, __node<_CharT>* __s,\n                                 bool __negate, bool __icase, bool __collate)\n        : base(__s), __traits_(__traits), __mask_(), __neg_mask_(),\n          __negate_(__negate), __icase_(__icase), __collate_(__collate),\n          __might_have_digraph_(__traits_.getloc().name() != \"C\") {}\n\n    virtual void __exec(__state&) const;\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool __negated() const {return __negate_;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __add_char(_CharT __c)\n        {\n            if (__icase_)\n                __chars_.push_back(__traits_.translate_nocase(__c));\n            else if (__collate_)\n                __chars_.push_back(__traits_.translate(__c));\n            else\n                __chars_.push_back(__c);\n        }\n    _LIBCPP_INLINE_VISIBILITY\n    void __add_neg_char(_CharT __c)\n        {\n            if (__icase_)\n                __neg_chars_.push_back(__traits_.translate_nocase(__c));\n            else if (__collate_)\n                __neg_chars_.push_back(__traits_.translate(__c));\n            else\n                __neg_chars_.push_back(__c);\n        }\n    _LIBCPP_INLINE_VISIBILITY\n    void __add_range(string_type __b, string_type __e)\n        {\n            if (__collate_)\n            {\n                if (__icase_)\n                {\n                    for (size_t __i = 0; __i < __b.size(); ++__i)\n                        __b[__i] = __traits_.translate_nocase(__b[__i]);\n                    for (size_t __i = 0; __i < __e.size(); ++__i)\n                        __e[__i] = __traits_.translate_nocase(__e[__i]);\n                }\n                else\n                {\n                    for (size_t __i = 0; __i < __b.size(); ++__i)\n                        __b[__i] = __traits_.translate(__b[__i]);\n                    for (size_t __i = 0; __i < __e.size(); ++__i)\n                        __e[__i] = __traits_.translate(__e[__i]);\n                }\n                __ranges_.push_back(make_pair(\n                                  __traits_.transform(__b.begin(), __b.end()),\n                                  __traits_.transform(__e.begin(), __e.end())));\n            }\n            else\n            {\n                if (__b.size() != 1 || __e.size() != 1)\n                    __throw_regex_error<regex_constants::error_collate>();\n                if (__icase_)\n                {\n                    __b[0] = __traits_.translate_nocase(__b[0]);\n                    __e[0] = __traits_.translate_nocase(__e[0]);\n                }\n                __ranges_.push_back(make_pair(_VSTD::move(__b), _VSTD::move(__e)));\n            }\n        }\n    _LIBCPP_INLINE_VISIBILITY\n    void __add_digraph(_CharT __c1, _CharT __c2)\n        {\n            if (__icase_)\n                __digraphs_.push_back(make_pair(__traits_.translate_nocase(__c1),\n                                                __traits_.translate_nocase(__c2)));\n            else if (__collate_)\n                __digraphs_.push_back(make_pair(__traits_.translate(__c1),\n                                                __traits_.translate(__c2)));\n            else\n                __digraphs_.push_back(make_pair(__c1, __c2));\n        }\n    _LIBCPP_INLINE_VISIBILITY\n    void __add_equivalence(const string_type& __s)\n        {__equivalences_.push_back(__s);}\n    _LIBCPP_INLINE_VISIBILITY\n    void __add_class(typename regex_traits<_CharT>::char_class_type __mask)\n        {__mask_ |= __mask;}\n    _LIBCPP_INLINE_VISIBILITY\n    void __add_neg_class(typename regex_traits<_CharT>::char_class_type __mask)\n        {__neg_mask_ |= __mask;}\n};\n\ntemplate <class _CharT, class _Traits>\nvoid\n__bracket_expression<_CharT, _Traits>::__exec(__state& __s) const\n{\n    bool __found = false;\n    unsigned __consumed = 0;\n    if (__s.__current_ != __s.__last_)\n    {\n        ++__consumed;\n        if (__might_have_digraph_)\n        {\n            const _CharT* __next = _VSTD::next(__s.__current_);\n            if (__next != __s.__last_)\n            {\n                pair<_CharT, _CharT> __ch2(*__s.__current_, *__next);\n                if (__icase_)\n                {\n                    __ch2.first = __traits_.translate_nocase(__ch2.first);\n                    __ch2.second = __traits_.translate_nocase(__ch2.second);\n                }\n                else if (__collate_)\n                {\n                    __ch2.first = __traits_.translate(__ch2.first);\n                    __ch2.second = __traits_.translate(__ch2.second);\n                }\n                if (!__traits_.lookup_collatename(&__ch2.first, &__ch2.first+2).empty())\n                {\n                    // __ch2 is a digraph in this locale\n                    ++__consumed;\n                    for (size_t __i = 0; __i < __digraphs_.size(); ++__i)\n                    {\n                        if (__ch2 == __digraphs_[__i])\n                        {\n                            __found = true;\n                            goto __exit;\n                        }\n                    }\n                    if (__collate_ && !__ranges_.empty())\n                    {\n                        string_type __s2 = __traits_.transform(&__ch2.first,\n                                                               &__ch2.first + 2);\n                        for (size_t __i = 0; __i < __ranges_.size(); ++__i)\n                        {\n                            if (__ranges_[__i].first <= __s2 &&\n                                __s2 <= __ranges_[__i].second)\n                            {\n                                __found = true;\n                                goto __exit;\n                            }\n                        }\n                    }\n                    if (!__equivalences_.empty())\n                    {\n                        string_type __s2 = __traits_.transform_primary(&__ch2.first,\n                                                                       &__ch2.first + 2);\n                        for (size_t __i = 0; __i < __equivalences_.size(); ++__i)\n                        {\n                            if (__s2 == __equivalences_[__i])\n                            {\n                                __found = true;\n                                goto __exit;\n                            }\n                        }\n                    }\n                    if (__traits_.isctype(__ch2.first, __mask_) &&\n                        __traits_.isctype(__ch2.second, __mask_))\n                    {\n                        __found = true;\n                        goto __exit;\n                    }\n                    if (!__traits_.isctype(__ch2.first, __neg_mask_) &&\n                        !__traits_.isctype(__ch2.second, __neg_mask_))\n                    {\n                        __found = true;\n                        goto __exit;\n                    }\n                    goto __exit;\n                }\n            }\n        }\n        // test *__s.__current_ as not a digraph\n        _CharT __ch = *__s.__current_;\n        if (__icase_)\n            __ch = __traits_.translate_nocase(__ch);\n        else if (__collate_)\n            __ch = __traits_.translate(__ch);\n        for (size_t __i = 0; __i < __chars_.size(); ++__i)\n        {\n            if (__ch == __chars_[__i])\n            {\n                __found = true;\n                goto __exit;\n            }\n        }\n        if (!__neg_chars_.empty())\n        {\n            for (size_t __i = 0; __i < __neg_chars_.size(); ++__i)\n            {\n                if (__ch == __neg_chars_[__i])\n                    goto __is_neg_char;\n            }\n            __found = true;\n            goto __exit;\n        }\n__is_neg_char:\n        if (!__ranges_.empty())\n        {\n            string_type __s2 = __collate_ ?\n                                   __traits_.transform(&__ch, &__ch + 1) :\n                                   string_type(1, __ch);\n            for (size_t __i = 0; __i < __ranges_.size(); ++__i)\n            {\n                if (__ranges_[__i].first <= __s2 && __s2 <= __ranges_[__i].second)\n                {\n                    __found = true;\n                    goto __exit;\n                }\n            }\n        }\n        if (!__equivalences_.empty())\n        {\n            string_type __s2 = __traits_.transform_primary(&__ch, &__ch + 1);\n            for (size_t __i = 0; __i < __equivalences_.size(); ++__i)\n            {\n                if (__s2 == __equivalences_[__i])\n                {\n                    __found = true;\n                    goto __exit;\n                }\n            }\n        }\n        if (__traits_.isctype(__ch, __mask_))\n        {\n            __found = true;\n            goto __exit;\n        }\n        if (__neg_mask_ && !__traits_.isctype(__ch, __neg_mask_))\n        {\n            __found = true;\n            goto __exit;\n        }\n    }\n    else\n        __found = __negate_;  // force reject\n__exit:\n    if (__found != __negate_)\n    {\n        __s.__do_ = __state::__accept_and_consume;\n        __s.__current_ += __consumed;\n        __s.__node_ = this->first();\n    }\n    else\n    {\n        __s.__do_ = __state::__reject;\n        __s.__node_ = nullptr;\n    }\n}\n\ntemplate <class _CharT, class _Traits> class __lookahead;\n\ntemplate <class _CharT, class _Traits = regex_traits<_CharT> >\nclass _LIBCPP_TYPE_VIS_ONLY basic_regex\n{\npublic:\n    // types:\n    typedef _CharT                              value_type;\n    typedef regex_constants::syntax_option_type flag_type;\n    typedef typename _Traits::locale_type       locale_type;\n\nprivate:\n    _Traits   __traits_;\n    flag_type __flags_;\n    unsigned __marked_count_;\n    unsigned __loop_count_;\n    int __open_count_;\n    shared_ptr<__empty_state<_CharT> > __start_;\n    __owns_one_state<_CharT>* __end_;\n\n    typedef _VSTD::__state<_CharT> __state;\n    typedef _VSTD::__node<_CharT> __node;\n\npublic:\n    // constants:\n    static const regex_constants::syntax_option_type icase = regex_constants::icase;\n    static const regex_constants::syntax_option_type nosubs = regex_constants::nosubs;\n    static const regex_constants::syntax_option_type optimize = regex_constants::optimize;\n    static const regex_constants::syntax_option_type collate = regex_constants::collate;\n    static const regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript;\n    static const regex_constants::syntax_option_type basic = regex_constants::basic;\n    static const regex_constants::syntax_option_type extended = regex_constants::extended;\n    static const regex_constants::syntax_option_type awk = regex_constants::awk;\n    static const regex_constants::syntax_option_type grep = regex_constants::grep;\n    static const regex_constants::syntax_option_type egrep = regex_constants::egrep;\n\n    // construct/copy/destroy:\n    _LIBCPP_INLINE_VISIBILITY\n    basic_regex()\n        : __flags_(), __marked_count_(0), __loop_count_(0), __open_count_(0),\n          __end_(0)\n        {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript)\n        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),\n          __end_(0)\n        {__parse(__p, __p + __traits_.length(__p));}\n    _LIBCPP_INLINE_VISIBILITY\n    basic_regex(const value_type* __p, size_t __len, flag_type __f)\n        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),\n          __end_(0)\n        {__parse(__p, __p + __len);}\n//     basic_regex(const basic_regex&) = default;\n//     basic_regex(basic_regex&&) = default;\n    template <class _ST, class _SA>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit basic_regex(const basic_string<value_type, _ST, _SA>& __p,\n                             flag_type __f = regex_constants::ECMAScript)\n        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),\n          __end_(0)\n        {__parse(__p.begin(), __p.end());}\n    template <class _ForwardIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        basic_regex(_ForwardIterator __first, _ForwardIterator __last,\n                    flag_type __f = regex_constants::ECMAScript)\n        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),\n          __end_(0)\n        {__parse(__first, __last);}\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    basic_regex(initializer_list<value_type> __il,\n                flag_type __f = regex_constants::ECMAScript)\n        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),\n          __end_(0)\n        {__parse(__il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n//    ~basic_regex() = default;\n\n//     basic_regex& operator=(const basic_regex&) = default;\n//     basic_regex& operator=(basic_regex&&) = default;\n    _LIBCPP_INLINE_VISIBILITY\n    basic_regex& operator=(const value_type* __p)\n        {return assign(__p);}\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    basic_regex& operator=(initializer_list<value_type> __il)\n        {return assign(__il);}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    template <class _ST, class _SA>\n        _LIBCPP_INLINE_VISIBILITY\n        basic_regex& operator=(const basic_string<value_type, _ST, _SA>& __p)\n        {return assign(__p);}\n\n    // assign:\n    _LIBCPP_INLINE_VISIBILITY\n    basic_regex& assign(const basic_regex& __that)\n        {return *this = __that;}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    basic_regex& assign(basic_regex&& __that) _NOEXCEPT\n        {return *this = _VSTD::move(__that);}\n#endif\n    _LIBCPP_INLINE_VISIBILITY\n    basic_regex& assign(const value_type* __p, flag_type __f = regex_constants::ECMAScript)\n        {return assign(__p, __p + __traits_.length(__p), __f);}\n    _LIBCPP_INLINE_VISIBILITY\n    basic_regex& assign(const value_type* __p, size_t __len, flag_type __f)\n        {return assign(__p, __p + __len, __f);}\n    template <class _ST, class _SA>\n        _LIBCPP_INLINE_VISIBILITY\n        basic_regex& assign(const basic_string<value_type, _ST, _SA>& __s,\n                            flag_type __f = regex_constants::ECMAScript)\n            {return assign(__s.begin(), __s.end(), __f);}\n\n    template <class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        typename enable_if\n        <\n             __is_input_iterator  <_InputIterator>::value &&\n            !__is_forward_iterator<_InputIterator>::value,\n            basic_regex&\n        >::type\n        assign(_InputIterator __first, _InputIterator __last,\n                            flag_type __f = regex_constants::ECMAScript)\n        {\n            basic_string<_CharT> __t(__first, __last);\n            return assign(__t.begin(), __t.end(), __f);\n        }\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    void __member_init(flag_type __f)\n    {\n        __flags_ = __f;\n        __marked_count_ = 0;\n        __loop_count_ = 0;\n        __open_count_ = 0;\n        __end_ = nullptr;\n    }\npublic:\n\n    template <class _ForwardIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        typename enable_if\n        <\n            __is_forward_iterator<_ForwardIterator>::value,\n            basic_regex&\n        >::type\n        assign(_ForwardIterator __first, _ForwardIterator __last,\n                            flag_type __f = regex_constants::ECMAScript)\n        {\n            return assign(basic_regex(__first, __last, __f));\n        }\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    basic_regex& assign(initializer_list<value_type> __il,\n                        flag_type __f = regex_constants::ECMAScript)\n        {return assign(__il.begin(), __il.end(), __f);}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    // const operations:\n    _LIBCPP_INLINE_VISIBILITY\n    unsigned mark_count() const {return __marked_count_;}\n    _LIBCPP_INLINE_VISIBILITY\n    flag_type flags() const {return __flags_;}\n\n    // locale:\n    _LIBCPP_INLINE_VISIBILITY\n    locale_type imbue(locale_type __loc)\n    {\n        __member_init(ECMAScript);\n        __start_.reset();\n        return __traits_.imbue(__loc);\n    }\n    _LIBCPP_INLINE_VISIBILITY\n    locale_type getloc() const {return __traits_.getloc();}\n\n    // swap:\n    void swap(basic_regex& __r);\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    unsigned __loop_count() const {return __loop_count_;}\n\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_basic_reg_exp(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_RE_expression(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_simple_RE(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_nondupl_RE(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_one_char_or_coll_elem_RE(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_Back_open_paren(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_Back_close_paren(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_Back_open_brace(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_Back_close_brace(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_BACKREF(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_ORD_CHAR(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_QUOTED_CHAR(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_RE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last,\n                               __owns_one_state<_CharT>* __s,\n                               unsigned __mexp_begin, unsigned __mexp_end);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_ERE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last,\n                                __owns_one_state<_CharT>* __s,\n                                unsigned __mexp_begin, unsigned __mexp_end);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_bracket_expression(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_follow_list(_ForwardIterator __first, _ForwardIterator __last,\n                            __bracket_expression<_CharT, _Traits>* __ml);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_expression_term(_ForwardIterator __first, _ForwardIterator __last,\n                                __bracket_expression<_CharT, _Traits>* __ml);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_equivalence_class(_ForwardIterator __first, _ForwardIterator __last,\n                                  __bracket_expression<_CharT, _Traits>* __ml);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_character_class(_ForwardIterator __first, _ForwardIterator __last,\n                                __bracket_expression<_CharT, _Traits>* __ml);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_collating_symbol(_ForwardIterator __first, _ForwardIterator __last,\n                                 basic_string<_CharT>& __col_sym);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_DUP_COUNT(_ForwardIterator __first, _ForwardIterator __last, int& __c);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_extended_reg_exp(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_ERE_branch(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_ERE_expression(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_one_char_or_coll_elem_ERE(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_ORD_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_QUOTED_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_ecma_exp(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_alternative(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_term(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_assertion(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_atom(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_atom_escape(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_decimal_escape(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_character_class_escape(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_character_escape(_ForwardIterator __first, _ForwardIterator __last,\n                                 basic_string<_CharT>* __str = nullptr);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_pattern_character(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_grep(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_egrep(_ForwardIterator __first, _ForwardIterator __last);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_class_escape(_ForwardIterator __first, _ForwardIterator __last,\n                          basic_string<_CharT>& __str,\n                          __bracket_expression<_CharT, _Traits>* __ml);\n    template <class _ForwardIterator>\n        _ForwardIterator\n        __parse_awk_escape(_ForwardIterator __first, _ForwardIterator __last,\n                          basic_string<_CharT>* __str = nullptr);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __push_l_anchor();\n    void __push_r_anchor();\n    void __push_match_any();\n    void __push_match_any_but_newline();\n    _LIBCPP_INLINE_VISIBILITY\n    void __push_greedy_inf_repeat(size_t __min, __owns_one_state<_CharT>* __s,\n                                  unsigned __mexp_begin = 0, unsigned __mexp_end = 0)\n        {__push_loop(__min, numeric_limits<size_t>::max(), __s,\n                     __mexp_begin, __mexp_end);}\n    _LIBCPP_INLINE_VISIBILITY\n    void __push_nongreedy_inf_repeat(size_t __min, __owns_one_state<_CharT>* __s,\n                                  unsigned __mexp_begin = 0, unsigned __mexp_end = 0)\n        {__push_loop(__min, numeric_limits<size_t>::max(), __s,\n                     __mexp_begin, __mexp_end, false);}\n    void __push_loop(size_t __min, size_t __max, __owns_one_state<_CharT>* __s,\n                     size_t __mexp_begin = 0, size_t __mexp_end = 0,\n                     bool __greedy = true);\n    __bracket_expression<_CharT, _Traits>* __start_matching_list(bool __negate);\n    void __push_char(value_type __c);\n    void __push_back_ref(int __i);\n    void __push_alternation(__owns_one_state<_CharT>* __sa,\n                            __owns_one_state<_CharT>* __sb);\n    void __push_begin_marked_subexpression();\n    void __push_end_marked_subexpression(unsigned);\n    void __push_empty();\n    void __push_word_boundary(bool);\n    void __push_lookahead(const basic_regex&, bool, unsigned);\n\n    template <class _Allocator>\n        bool\n        __search(const _CharT* __first, const _CharT* __last,\n                 match_results<const _CharT*, _Allocator>& __m,\n                 regex_constants::match_flag_type __flags) const;\n\n    template <class _Allocator>\n        bool\n        __match_at_start(const _CharT* __first, const _CharT* __last,\n                 match_results<const _CharT*, _Allocator>& __m,\n                 regex_constants::match_flag_type __flags, bool) const;\n    template <class _Allocator>\n        bool\n        __match_at_start_ecma(const _CharT* __first, const _CharT* __last,\n                 match_results<const _CharT*, _Allocator>& __m,\n                 regex_constants::match_flag_type __flags, bool) const;\n    template <class _Allocator>\n        bool\n        __match_at_start_posix_nosubs(const _CharT* __first, const _CharT* __last,\n                 match_results<const _CharT*, _Allocator>& __m,\n                 regex_constants::match_flag_type __flags, bool) const;\n    template <class _Allocator>\n        bool\n        __match_at_start_posix_subs(const _CharT* __first, const _CharT* __last,\n                 match_results<const _CharT*, _Allocator>& __m,\n                 regex_constants::match_flag_type __flags, bool) const;\n\n    template <class _Bp, class _Ap, class _Cp, class _Tp>\n    friend\n    bool\n    regex_search(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Cp, _Tp>&,\n                 regex_constants::match_flag_type);\n\n    template <class _Ap, class _Cp, class _Tp>\n    friend\n    bool\n    regex_search(const _Cp*, const _Cp*, match_results<const _Cp*, _Ap>&,\n                 const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);\n\n    template <class _Bp, class _Cp, class _Tp>\n    friend\n    bool\n    regex_search(_Bp, _Bp, const basic_regex<_Cp, _Tp>&,\n                 regex_constants::match_flag_type);\n\n    template <class _Cp, class _Tp>\n    friend\n    bool\n    regex_search(const _Cp*, const _Cp*,\n                 const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);\n\n    template <class _Cp, class _Ap, class _Tp>\n    friend\n    bool\n    regex_search(const _Cp*, match_results<const _Cp*, _Ap>&, const basic_regex<_Cp, _Tp>&,\n                 regex_constants::match_flag_type);\n\n    template <class _ST, class _SA, class _Cp, class _Tp>\n    friend\n    bool\n    regex_search(const basic_string<_Cp, _ST, _SA>& __s,\n                 const basic_regex<_Cp, _Tp>& __e,\n                 regex_constants::match_flag_type __flags);\n\n    template <class _ST, class _SA, class _Ap, class _Cp, class _Tp>\n    friend\n    bool\n    regex_search(const basic_string<_Cp, _ST, _SA>& __s,\n                 match_results<typename basic_string<_Cp, _ST, _SA>::const_iterator, _Ap>&,\n                 const basic_regex<_Cp, _Tp>& __e,\n                 regex_constants::match_flag_type __flags);\n\n    template <class _Iter, class _Ap, class _Cp, class _Tp>\n    friend\n    bool\n    regex_search(__wrap_iter<_Iter> __first,\n                 __wrap_iter<_Iter> __last,\n                 match_results<__wrap_iter<_Iter>, _Ap>& __m,\n                 const basic_regex<_Cp, _Tp>& __e,\n                 regex_constants::match_flag_type __flags);\n\n    template <class, class> friend class __lookahead;\n};\n\ntemplate <class _CharT, class _Traits>\n    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::icase;\ntemplate <class _CharT, class _Traits>\n    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::nosubs;\ntemplate <class _CharT, class _Traits>\n    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::optimize;\ntemplate <class _CharT, class _Traits>\n    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::collate;\ntemplate <class _CharT, class _Traits>\n    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::ECMAScript;\ntemplate <class _CharT, class _Traits>\n    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::basic;\ntemplate <class _CharT, class _Traits>\n    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::extended;\ntemplate <class _CharT, class _Traits>\n    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::awk;\ntemplate <class _CharT, class _Traits>\n    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::grep;\ntemplate <class _CharT, class _Traits>\n    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::egrep;\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_regex<_CharT, _Traits>::swap(basic_regex& __r)\n{\n    using _VSTD::swap;\n    swap(__traits_, __r.__traits_);\n    swap(__flags_, __r.__flags_);\n    swap(__marked_count_, __r.__marked_count_);\n    swap(__loop_count_, __r.__loop_count_);\n    swap(__open_count_, __r.__open_count_);\n    swap(__start_, __r.__start_);\n    swap(__end_, __r.__end_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(basic_regex<_CharT, _Traits>& __x, basic_regex<_CharT, _Traits>& __y)\n{\n    return __x.swap(__y);\n}\n\n// __lookahead\n\ntemplate <class _CharT, class _Traits>\nclass __lookahead\n    : public __owns_one_state<_CharT>\n{\n    typedef __owns_one_state<_CharT> base;\n\n    basic_regex<_CharT, _Traits> __exp_;\n    unsigned __mexp_;\n    bool __invert_;\n\n    __lookahead(const __lookahead&);\n    __lookahead& operator=(const __lookahead&);\npublic:\n    typedef _VSTD::__state<_CharT> __state;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __lookahead(const basic_regex<_CharT, _Traits>& __exp, bool __invert, __node<_CharT>* __s, unsigned __mexp)\n        : base(__s), __exp_(__exp), __mexp_(__mexp), __invert_(__invert) {}\n\n    virtual void __exec(__state&) const;\n};\n\ntemplate <class _CharT, class _Traits>\nvoid\n__lookahead<_CharT, _Traits>::__exec(__state& __s) const\n{\n    match_results<const _CharT*> __m;\n    __m.__init(1 + __exp_.mark_count(), __s.__current_, __s.__last_);\n    bool __matched = __exp_.__match_at_start_ecma(__s.__current_, __s.__last_,\n                                                  __m,\n                                                  __s.__flags_ | regex_constants::match_continuous,\n                                                  __s.__at_first_ && __s.__current_ == __s.__first_);\n    if (__matched != __invert_)\n    {\n        __s.__do_ = __state::__accept_but_not_consume;\n        __s.__node_ = this->first();\n        for (unsigned __i = 1; __i < __m.size(); ++__i) {\n            __s.__sub_matches_[__mexp_ + __i - 1] = __m.__matches_[__i];\n        }\n    }\n    else\n    {\n        __s.__do_ = __state::__reject;\n        __s.__node_ = nullptr;\n    }\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first,\n                                      _ForwardIterator __last)\n{\n    {\n        unique_ptr<__node> __h(new __end_state<_CharT>);\n        __start_.reset(new __empty_state<_CharT>(__h.get()));\n        __h.release();\n        __end_ = __start_.get();\n    }\n    switch (__flags_ & 0x1F0)\n    {\n    case ECMAScript:\n        __first = __parse_ecma_exp(__first, __last);\n        break;\n    case basic:\n        __first = __parse_basic_reg_exp(__first, __last);\n        break;\n    case extended:\n    case awk:\n        __first = __parse_extended_reg_exp(__first, __last);\n        break;\n    case grep:\n        __first = __parse_grep(__first, __last);\n        break;\n    case egrep:\n        __first = __parse_egrep(__first, __last);\n        break;\n    default:\n        __throw_regex_error<regex_constants::__re_err_grammar>();\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_basic_reg_exp(_ForwardIterator __first,\n                                                    _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        if (*__first == '^')\n        {\n            __push_l_anchor();\n            ++__first;\n        }\n        if (__first != __last)\n        {\n            __first = __parse_RE_expression(__first, __last);\n            if (__first != __last)\n            {\n                _ForwardIterator __temp = _VSTD::next(__first);\n                if (__temp == __last && *__first == '$')\n                {\n                    __push_r_anchor();\n                    ++__first;\n                }\n            }\n        }\n        if (__first != __last)\n            __throw_regex_error<regex_constants::__re_err_empty>();\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_extended_reg_exp(_ForwardIterator __first,\n                                                       _ForwardIterator __last)\n{\n    __owns_one_state<_CharT>* __sa = __end_;\n    _ForwardIterator __temp = __parse_ERE_branch(__first, __last);\n    if (__temp == __first)\n        __throw_regex_error<regex_constants::__re_err_empty>();\n    __first = __temp;\n    while (__first != __last && *__first == '|')\n    {\n        __owns_one_state<_CharT>* __sb = __end_;\n        __temp = __parse_ERE_branch(++__first, __last);\n        if (__temp == __first)\n            __throw_regex_error<regex_constants::__re_err_empty>();\n        __push_alternation(__sa, __sb);\n        __first = __temp;\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_ERE_branch(_ForwardIterator __first,\n                                                 _ForwardIterator __last)\n{\n    _ForwardIterator __temp = __parse_ERE_expression(__first, __last);\n    if (__temp == __first)\n        __throw_regex_error<regex_constants::__re_err_empty>();\n    do\n    {\n        __first = __temp;\n        __temp = __parse_ERE_expression(__first, __last);\n    } while (__temp != __first);\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_ERE_expression(_ForwardIterator __first,\n                                                     _ForwardIterator __last)\n{\n    __owns_one_state<_CharT>* __e = __end_;\n    unsigned __mexp_begin = __marked_count_;\n    _ForwardIterator __temp = __parse_one_char_or_coll_elem_ERE(__first, __last);\n    if (__temp == __first && __temp != __last)\n    {\n        switch (*__temp)\n        {\n        case '^':\n            __push_l_anchor();\n            ++__temp;\n            break;\n        case '$':\n            __push_r_anchor();\n            ++__temp;\n            break;\n        case '(':\n            __push_begin_marked_subexpression();\n            unsigned __temp_count = __marked_count_;\n            ++__open_count_;\n            __temp = __parse_extended_reg_exp(++__temp, __last);\n            if (__temp == __last || *__temp != ')')\n                __throw_regex_error<regex_constants::error_paren>();\n            __push_end_marked_subexpression(__temp_count);\n            --__open_count_;\n            ++__temp;\n            break;\n        }\n    }\n    if (__temp != __first)\n        __temp = __parse_ERE_dupl_symbol(__temp, __last, __e, __mexp_begin+1,\n                                         __marked_count_+1);\n    __first = __temp;\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_RE_expression(_ForwardIterator __first,\n                                                    _ForwardIterator __last)\n{\n    while (true)\n    {\n        _ForwardIterator __temp = __parse_simple_RE(__first, __last);\n        if (__temp == __first)\n            break;\n        __first = __temp;\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_simple_RE(_ForwardIterator __first,\n                                                _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        __owns_one_state<_CharT>* __e = __end_;\n        unsigned __mexp_begin = __marked_count_;\n        _ForwardIterator __temp = __parse_nondupl_RE(__first, __last);\n        if (__temp != __first)\n            __first = __parse_RE_dupl_symbol(__temp, __last, __e,\n                                             __mexp_begin+1, __marked_count_+1);\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_nondupl_RE(_ForwardIterator __first,\n                                                 _ForwardIterator __last)\n{\n    _ForwardIterator __temp = __first;\n    __first = __parse_one_char_or_coll_elem_RE(__first, __last);\n    if (__temp == __first)\n    {\n        __temp = __parse_Back_open_paren(__first, __last);\n        if (__temp != __first)\n        {\n            __push_begin_marked_subexpression();\n            unsigned __temp_count = __marked_count_;\n            __first = __parse_RE_expression(__temp, __last);\n            __temp = __parse_Back_close_paren(__first, __last);\n            if (__temp == __first)\n                __throw_regex_error<regex_constants::error_paren>();\n            __push_end_marked_subexpression(__temp_count);\n            __first = __temp;\n        }\n        else\n            __first = __parse_BACKREF(__first, __last);\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_RE(\n                                                       _ForwardIterator __first,\n                                                       _ForwardIterator __last)\n{\n    _ForwardIterator __temp = __parse_ORD_CHAR(__first, __last);\n    if (__temp == __first)\n    {\n        __temp = __parse_QUOTED_CHAR(__first, __last);\n        if (__temp == __first)\n        {\n            if (__temp != __last && *__temp == '.')\n            {\n                __push_match_any();\n                ++__temp;\n            }\n            else\n                __temp = __parse_bracket_expression(__first, __last);\n        }\n    }\n    __first = __temp;\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_ERE(\n                                                       _ForwardIterator __first,\n                                                       _ForwardIterator __last)\n{\n    _ForwardIterator __temp = __parse_ORD_CHAR_ERE(__first, __last);\n    if (__temp == __first)\n    {\n        __temp = __parse_QUOTED_CHAR_ERE(__first, __last);\n        if (__temp == __first)\n        {\n            if (__temp != __last && *__temp == '.')\n            {\n                __push_match_any();\n                ++__temp;\n            }\n            else\n                __temp = __parse_bracket_expression(__first, __last);\n        }\n    }\n    __first = __temp;\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_Back_open_paren(_ForwardIterator __first,\n                                                      _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        _ForwardIterator __temp = _VSTD::next(__first);\n        if (__temp != __last)\n        {\n            if (*__first == '\\\\' && *__temp == '(')\n                __first = ++__temp;\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_Back_close_paren(_ForwardIterator __first,\n                                                       _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        _ForwardIterator __temp = _VSTD::next(__first);\n        if (__temp != __last)\n        {\n            if (*__first == '\\\\' && *__temp == ')')\n                __first = ++__temp;\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_Back_open_brace(_ForwardIterator __first,\n                                                      _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        _ForwardIterator __temp = _VSTD::next(__first);\n        if (__temp != __last)\n        {\n            if (*__first == '\\\\' && *__temp == '{')\n                __first = ++__temp;\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_Back_close_brace(_ForwardIterator __first,\n                                                       _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        _ForwardIterator __temp = _VSTD::next(__first);\n        if (__temp != __last)\n        {\n            if (*__first == '\\\\' && *__temp == '}')\n                __first = ++__temp;\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_BACKREF(_ForwardIterator __first,\n                                              _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        _ForwardIterator __temp = _VSTD::next(__first);\n        if (__temp != __last)\n        {\n            if (*__first == '\\\\')\n            { \n                int __val = __traits_.value(*__temp, 10);\n                if (__val >= 1 && __val <= 9)\n                {\n                    __push_back_ref(__val);\n                    __first = ++__temp;\n                }\n            }\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_ORD_CHAR(_ForwardIterator __first,\n                                               _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        _ForwardIterator __temp = _VSTD::next(__first);\n        if (__temp == __last && *__first == '$')\n            return __first;\n        // Not called inside a bracket\n        if (*__first == '.' || *__first == '\\\\' || *__first == '[')\n            return __first;\n        __push_char(*__first);\n        ++__first;\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_ORD_CHAR_ERE(_ForwardIterator __first,\n                                                   _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        switch (*__first)\n        {\n        case '^':\n        case '.':\n        case '[':\n        case '$':\n        case '(':\n        case '|':\n        case '*':\n        case '+':\n        case '?':\n        case '{':\n        case '\\\\':\n            break;\n        case ')':\n            if (__open_count_ == 0)\n            {\n                __push_char(*__first);\n                ++__first;\n            }\n            break;\n        default:\n            __push_char(*__first);\n            ++__first;\n            break;\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR(_ForwardIterator __first,\n                                                  _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        _ForwardIterator __temp = _VSTD::next(__first);\n        if (__temp != __last)\n        {\n            if (*__first == '\\\\')\n            {\n                switch (*__temp)\n                {\n                case '^':\n                case '.':\n                case '*':\n                case '[':\n                case '$':\n                case '\\\\':\n                    __push_char(*__temp);\n                    __first = ++__temp;\n                    break;\n                }\n            }\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR_ERE(_ForwardIterator __first,\n                                                      _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        _ForwardIterator __temp = _VSTD::next(__first);\n        if (__temp != __last)\n        {\n            if (*__first == '\\\\')\n            {\n                switch (*__temp)\n                {\n                case '^':\n                case '.':\n                case '*':\n                case '[':\n                case '$':\n                case '\\\\':\n                case '(':\n                case ')':\n                case '|':\n                case '+':\n                case '?':\n                case '{':\n                case '}':\n                    __push_char(*__temp);\n                    __first = ++__temp;\n                    break;\n                default:\n                    if ((__flags_ & 0x1F0) == awk)\n                        __first = __parse_awk_escape(++__first, __last);\n                    break;\n                }\n            }\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_RE_dupl_symbol(_ForwardIterator __first,\n                                                     _ForwardIterator __last,\n                                                     __owns_one_state<_CharT>* __s,\n                                                     unsigned __mexp_begin,\n                                                     unsigned __mexp_end)\n{\n    if (__first != __last)\n    {\n        if (*__first == '*')\n        {\n            __push_greedy_inf_repeat(0, __s, __mexp_begin, __mexp_end);\n            ++__first;\n        }\n        else\n        {\n            _ForwardIterator __temp = __parse_Back_open_brace(__first, __last);\n            if (__temp != __first)\n            {\n                int __min = 0;\n                __first = __temp;\n                __temp = __parse_DUP_COUNT(__first, __last, __min);\n                if (__temp == __first)\n                    __throw_regex_error<regex_constants::error_badbrace>();\n                __first = __temp;\n                if (__first == __last)\n                    __throw_regex_error<regex_constants::error_brace>();\n                if (*__first != ',')\n                {\n                    __temp = __parse_Back_close_brace(__first, __last);\n                    if (__temp == __first)\n                        __throw_regex_error<regex_constants::error_brace>();\n                    __push_loop(__min, __min, __s, __mexp_begin, __mexp_end,\n                                    true);\n                    __first = __temp;\n                }\n                else\n                {\n                    ++__first;  // consume ','\n                    int __max = -1;\n                    __first = __parse_DUP_COUNT(__first, __last, __max);\n                    __temp = __parse_Back_close_brace(__first, __last);\n                    if (__temp == __first)\n                        __throw_regex_error<regex_constants::error_brace>();\n                    if (__max == -1)\n                        __push_greedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end);\n                    else\n                    {\n                        if (__max < __min)\n                            __throw_regex_error<regex_constants::error_badbrace>();\n                        __push_loop(__min, __max, __s, __mexp_begin, __mexp_end,\n                                    true);\n                    }\n                    __first = __temp;\n                }\n            }\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_ERE_dupl_symbol(_ForwardIterator __first,\n                                                      _ForwardIterator __last,\n                                                      __owns_one_state<_CharT>* __s,\n                                                      unsigned __mexp_begin,\n                                                      unsigned __mexp_end)\n{\n    if (__first != __last)\n    {\n        unsigned __grammar = __flags_ & 0x1F0;\n        switch (*__first)\n        {\n        case '*':\n            ++__first;\n            if (__grammar == ECMAScript && __first != __last && *__first == '?')\n            {\n                ++__first;\n                __push_nongreedy_inf_repeat(0, __s, __mexp_begin, __mexp_end);\n            }\n            else\n                __push_greedy_inf_repeat(0, __s, __mexp_begin, __mexp_end);\n            break;\n        case '+':\n            ++__first;\n            if (__grammar == ECMAScript && __first != __last && *__first == '?')\n            {\n                ++__first;\n                __push_nongreedy_inf_repeat(1, __s, __mexp_begin, __mexp_end);\n            }\n            else\n                __push_greedy_inf_repeat(1, __s, __mexp_begin, __mexp_end);\n            break;\n        case '?':\n            ++__first;\n            if (__grammar == ECMAScript && __first != __last && *__first == '?')\n            {\n                ++__first;\n                __push_loop(0, 1, __s, __mexp_begin, __mexp_end, false);\n            }\n            else\n                __push_loop(0, 1, __s, __mexp_begin, __mexp_end);\n            break;\n        case '{':\n            {\n                int __min;\n                _ForwardIterator __temp = __parse_DUP_COUNT(++__first, __last, __min);\n                if (__temp == __first)\n                    __throw_regex_error<regex_constants::error_badbrace>();\n                __first = __temp;\n                if (__first == __last)\n                    __throw_regex_error<regex_constants::error_brace>();\n                switch (*__first)\n                {\n                case '}':\n                    ++__first;\n                    if (__grammar == ECMAScript && __first != __last && *__first == '?')\n                    {\n                        ++__first;\n                        __push_loop(__min, __min, __s, __mexp_begin, __mexp_end, false);\n                    }\n                    else\n                        __push_loop(__min, __min, __s, __mexp_begin, __mexp_end);\n                    break;\n                case ',':\n                    ++__first;\n                    if (__first == __last)\n                        __throw_regex_error<regex_constants::error_badbrace>();\n                    if (*__first == '}')\n                    {\n                        ++__first;\n                        if (__grammar == ECMAScript && __first != __last && *__first == '?')\n                        {\n                            ++__first;\n                            __push_nongreedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end);\n                        }\n                        else\n                            __push_greedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end);\n                    }\n                    else\n                    {\n                        int __max = -1;\n                        __temp = __parse_DUP_COUNT(__first, __last, __max);\n                        if (__temp == __first)\n                            __throw_regex_error<regex_constants::error_brace>();\n                        __first = __temp;\n                        if (__first == __last || *__first != '}')\n                            __throw_regex_error<regex_constants::error_brace>();\n                        ++__first;\n                        if (__max < __min)\n                            __throw_regex_error<regex_constants::error_badbrace>();\n                        if (__grammar == ECMAScript && __first != __last && *__first == '?')\n                        {\n                            ++__first;\n                            __push_loop(__min, __max, __s, __mexp_begin, __mexp_end, false);\n                        }\n                        else\n                            __push_loop(__min, __max, __s, __mexp_begin, __mexp_end);\n                    }\n                    break;\n                default:\n                    __throw_regex_error<regex_constants::error_badbrace>();\n                }\n            }\n            break;\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_bracket_expression(_ForwardIterator __first,\n                                                         _ForwardIterator __last)\n{\n    if (__first != __last && *__first == '[')\n    {\n        ++__first;\n        if (__first == __last)\n            __throw_regex_error<regex_constants::error_brack>();\n        bool __negate = false;\n        if (*__first == '^')\n        {\n            ++__first;\n            __negate = true;\n        }\n        __bracket_expression<_CharT, _Traits>* __ml = __start_matching_list(__negate);\n        // __ml owned by *this\n        if (__first == __last)\n            __throw_regex_error<regex_constants::error_brack>();\n        if ((__flags_ & 0x1F0) != ECMAScript && *__first == ']')\n        {\n            __ml->__add_char(']');\n            ++__first;\n        }\n        __first = __parse_follow_list(__first, __last, __ml);\n        if (__first == __last)\n            __throw_regex_error<regex_constants::error_brack>();\n        if (*__first == '-')\n        {\n            __ml->__add_char('-');\n            ++__first;\n        }\n        if (__first == __last || *__first != ']')\n            __throw_regex_error<regex_constants::error_brack>();\n        ++__first;\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_follow_list(_ForwardIterator __first,\n                                    _ForwardIterator __last,\n                                    __bracket_expression<_CharT, _Traits>* __ml)\n{\n    if (__first != __last)\n    {\n        while (true)\n        {\n            _ForwardIterator __temp = __parse_expression_term(__first, __last,\n                                                              __ml);\n            if (__temp == __first)\n                break;\n            __first = __temp;\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_expression_term(_ForwardIterator __first,\n                                    _ForwardIterator __last,\n                                    __bracket_expression<_CharT, _Traits>* __ml)\n{\n    if (__first != __last && *__first != ']')\n    {\n        _ForwardIterator __temp = _VSTD::next(__first);\n        basic_string<_CharT> __start_range;\n        if (__temp != __last && *__first == '[')\n        {\n            if (*__temp == '=')\n                return __parse_equivalence_class(++__temp, __last, __ml);\n            else if (*__temp == ':')\n                return __parse_character_class(++__temp, __last, __ml);\n            else if (*__temp == '.')\n                __first = __parse_collating_symbol(++__temp, __last, __start_range);\n        }\n        unsigned __grammar = __flags_ & 0x1F0;\n        if (__start_range.empty())\n        {\n            if ((__grammar == ECMAScript || __grammar == awk) && *__first == '\\\\')\n            {\n                if (__grammar == ECMAScript)\n                    __first = __parse_class_escape(++__first, __last, __start_range, __ml);\n                else\n                    __first = __parse_awk_escape(++__first, __last, &__start_range);\n            }\n            else\n            {\n                __start_range = *__first;\n                ++__first;\n            }\n        }\n        if (__first != __last && *__first != ']')\n        {\n            __temp = _VSTD::next(__first);\n            if (__temp != __last && *__first == '-' && *__temp != ']')\n            {\n                // parse a range\n                basic_string<_CharT> __end_range;\n                __first = __temp;\n                ++__temp;\n                if (__temp != __last && *__first == '[' && *__temp == '.')\n                    __first = __parse_collating_symbol(++__temp, __last, __end_range);\n                else\n                {\n                    if ((__grammar == ECMAScript || __grammar == awk) && *__first == '\\\\')\n                    {\n                        if (__grammar == ECMAScript)\n                            __first = __parse_class_escape(++__first, __last,\n                                                           __end_range, __ml);\n                        else\n                            __first = __parse_awk_escape(++__first, __last,\n                                                         &__end_range);\n                    }\n                    else\n                    {\n                        __end_range = *__first;\n                        ++__first;\n                    }\n                }\n                __ml->__add_range(_VSTD::move(__start_range), _VSTD::move(__end_range));\n            }\n            else if (!__start_range.empty())\n            {\n                if (__start_range.size() == 1)\n                    __ml->__add_char(__start_range[0]);\n                else\n                    __ml->__add_digraph(__start_range[0], __start_range[1]);\n            }\n        }\n        else if (!__start_range.empty())\n        {\n            if (__start_range.size() == 1)\n                __ml->__add_char(__start_range[0]);\n            else\n                __ml->__add_digraph(__start_range[0], __start_range[1]);\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_class_escape(_ForwardIterator __first,\n                          _ForwardIterator __last,\n                          basic_string<_CharT>& __str,\n                          __bracket_expression<_CharT, _Traits>* __ml)\n{\n    if (__first == __last)\n        __throw_regex_error<regex_constants::error_escape>();\n    switch (*__first)\n    {\n    case 0:\n        __str = *__first;\n        return ++__first;\n    case 'b':\n        __str = _CharT(8);\n        return ++__first;\n    case 'd':\n        __ml->__add_class(ctype_base::digit);\n        return ++__first;\n    case 'D':\n        __ml->__add_neg_class(ctype_base::digit);\n        return ++__first;\n    case 's':\n        __ml->__add_class(ctype_base::space);\n        return ++__first;\n    case 'S':\n        __ml->__add_neg_class(ctype_base::space);\n        return ++__first;\n    case 'w':\n        __ml->__add_class(ctype_base::alnum);\n        __ml->__add_char('_');\n        return ++__first;\n    case 'W':\n        __ml->__add_neg_class(ctype_base::alnum);\n        __ml->__add_neg_char('_');\n        return ++__first;\n    }\n    __first = __parse_character_escape(__first, __last, &__str);\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_awk_escape(_ForwardIterator __first,\n                          _ForwardIterator __last,\n                          basic_string<_CharT>* __str)\n{\n    if (__first == __last)\n        __throw_regex_error<regex_constants::error_escape>();\n    switch (*__first)\n    {\n    case '\\\\':\n    case '\"':\n    case '/':\n        if (__str)\n            *__str = *__first;\n        else\n            __push_char(*__first);\n        return ++__first;\n    case 'a':\n        if (__str)\n            *__str = _CharT(7);\n        else\n            __push_char(_CharT(7));\n        return ++__first;\n    case 'b':\n        if (__str)\n            *__str = _CharT(8);\n        else\n            __push_char(_CharT(8));\n        return ++__first;\n    case 'f':\n        if (__str)\n            *__str = _CharT(0xC);\n        else\n            __push_char(_CharT(0xC));\n        return ++__first;\n    case 'n':\n        if (__str)\n            *__str = _CharT(0xA);\n        else\n            __push_char(_CharT(0xA));\n        return ++__first;\n    case 'r':\n        if (__str)\n            *__str = _CharT(0xD);\n        else\n            __push_char(_CharT(0xD));\n        return ++__first;\n    case 't':\n        if (__str)\n            *__str = _CharT(0x9);\n        else\n            __push_char(_CharT(0x9));\n        return ++__first;\n    case 'v':\n        if (__str)\n            *__str = _CharT(0xB);\n        else\n            __push_char(_CharT(0xB));\n        return ++__first;\n    }\n    if ('0' <= *__first && *__first <= '7')\n    {\n        unsigned __val = *__first - '0';\n        if (++__first != __last && ('0' <= *__first && *__first <= '7'))\n        {\n            __val = 8 * __val + *__first - '0';\n            if (++__first != __last && ('0' <= *__first && *__first <= '7'))\n                __val = 8 * __val + *__first++ - '0';\n        }\n        if (__str)\n            *__str = _CharT(__val);\n        else\n            __push_char(_CharT(__val));\n    }\n    else\n        __throw_regex_error<regex_constants::error_escape>();\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_equivalence_class(_ForwardIterator __first,\n                                    _ForwardIterator __last,\n                                    __bracket_expression<_CharT, _Traits>* __ml)\n{\n    // Found [=\n    //   This means =] must exist\n    value_type _Equal_close[2] = {'=', ']'};\n    _ForwardIterator __temp = _VSTD::search(__first, __last, _Equal_close,\n                                                            _Equal_close+2);\n    if (__temp == __last)\n        __throw_regex_error<regex_constants::error_brack>();\n    // [__first, __temp) contains all text in [= ... =]\n    typedef typename _Traits::string_type string_type;\n    string_type __collate_name =\n        __traits_.lookup_collatename(__first, __temp);\n    if (__collate_name.empty())\n        __throw_regex_error<regex_constants::error_collate>();\n    string_type __equiv_name =\n        __traits_.transform_primary(__collate_name.begin(),\n                                    __collate_name.end());\n    if (!__equiv_name.empty())\n        __ml->__add_equivalence(__equiv_name);\n    else\n    {\n        switch (__collate_name.size())\n        {\n        case 1:\n            __ml->__add_char(__collate_name[0]);\n            break;\n        case 2:\n            __ml->__add_digraph(__collate_name[0], __collate_name[1]);\n            break;\n        default:\n            __throw_regex_error<regex_constants::error_collate>();\n        }\n    }\n    __first = _VSTD::next(__temp, 2);\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_character_class(_ForwardIterator __first,\n                                    _ForwardIterator __last,\n                                    __bracket_expression<_CharT, _Traits>* __ml)\n{\n    // Found [:\n    //   This means :] must exist\n    value_type _Colon_close[2] = {':', ']'};\n    _ForwardIterator __temp = _VSTD::search(__first, __last, _Colon_close,\n                                                            _Colon_close+2);\n    if (__temp == __last)\n        __throw_regex_error<regex_constants::error_brack>();\n    // [__first, __temp) contains all text in [: ... :]\n    typedef typename _Traits::char_class_type char_class_type;\n    char_class_type __class_type =\n        __traits_.lookup_classname(__first, __temp, __flags_ & icase);\n    if (__class_type == 0)\n        __throw_regex_error<regex_constants::error_brack>();\n    __ml->__add_class(__class_type);\n    __first = _VSTD::next(__temp, 2);\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_collating_symbol(_ForwardIterator __first,\n                                                _ForwardIterator __last,\n                                                basic_string<_CharT>& __col_sym)\n{\n    // Found [.\n    //   This means .] must exist\n    value_type _Dot_close[2] = {'.', ']'};\n    _ForwardIterator __temp = _VSTD::search(__first, __last, _Dot_close,\n                                                            _Dot_close+2);\n    if (__temp == __last)\n        __throw_regex_error<regex_constants::error_brack>();\n    // [__first, __temp) contains all text in [. ... .]\n    __col_sym = __traits_.lookup_collatename(__first, __temp);\n    switch (__col_sym.size())\n    {\n    case 1:\n    case 2:\n        break;\n    default:\n        __throw_regex_error<regex_constants::error_collate>();\n    }\n    __first = _VSTD::next(__temp, 2);\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_DUP_COUNT(_ForwardIterator __first,\n                                                _ForwardIterator __last,\n                                                int& __c)\n{\n    if (__first != __last )\n    {\n        int __val = __traits_.value(*__first, 10);\n        if ( __val != -1 )\n        {\n            __c = __val;\n            for (++__first; \n                 __first != __last && ( __val = __traits_.value(*__first, 10)) != -1;\n                 ++__first)\n            {\n                __c *= 10;\n                __c += __val;\n            }\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_ecma_exp(_ForwardIterator __first,\n                                               _ForwardIterator __last)\n{\n    __owns_one_state<_CharT>* __sa = __end_;\n    _ForwardIterator __temp = __parse_alternative(__first, __last);\n    if (__temp == __first)\n        __push_empty();\n    __first = __temp;\n    while (__first != __last && *__first == '|')\n    {\n        __owns_one_state<_CharT>* __sb = __end_;\n        __temp = __parse_alternative(++__first, __last);\n        if (__temp == __first)\n            __push_empty();\n        __push_alternation(__sa, __sb);\n        __first = __temp;\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_alternative(_ForwardIterator __first,\n                                                  _ForwardIterator __last)\n{\n    while (true)\n    {\n        _ForwardIterator __temp = __parse_term(__first, __last);\n        if (__temp == __first)\n            break;\n        __first = __temp;\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_term(_ForwardIterator __first,\n                                           _ForwardIterator __last)\n{\n    _ForwardIterator __temp = __parse_assertion(__first, __last);\n    if (__temp == __first)\n    {\n        __owns_one_state<_CharT>* __e = __end_;\n        unsigned __mexp_begin = __marked_count_;\n        __temp = __parse_atom(__first, __last);\n        if (__temp != __first)\n            __first = __parse_ERE_dupl_symbol(__temp, __last, __e,\n                                              __mexp_begin+1, __marked_count_+1);\n    }\n    else\n        __first = __temp;\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_assertion(_ForwardIterator __first,\n                                                _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        switch (*__first)\n        {\n        case '^':\n            __push_l_anchor();\n            ++__first;\n            break;\n        case '$':\n            __push_r_anchor();\n            ++__first;\n            break;\n        case '\\\\':\n            {\n                _ForwardIterator __temp = _VSTD::next(__first);\n                if (__temp != __last)\n                {\n                    if (*__temp == 'b')\n                    {\n                        __push_word_boundary(false);\n                        __first = ++__temp;\n                    }\n                    else if (*__temp == 'B')\n                    {\n                        __push_word_boundary(true);\n                        __first = ++__temp;\n                    }\n                }\n            }\n            break;\n        case '(':\n            {\n                _ForwardIterator __temp = _VSTD::next(__first);\n                if (__temp != __last && *__temp == '?')\n                {\n                    if (++__temp != __last)\n                    {\n                        switch (*__temp)\n                        {\n                        case '=':\n                            {\n                                basic_regex __exp;\n                                __exp.__flags_ = __flags_;\n                                __temp = __exp.__parse(++__temp, __last);\n                                unsigned __mexp = __exp.__marked_count_;\n                                __push_lookahead(_VSTD::move(__exp), false, __marked_count_);\n                                __marked_count_ += __mexp;\n                                if (__temp == __last || *__temp != ')')\n                                    __throw_regex_error<regex_constants::error_paren>();\n                                __first = ++__temp;\n                            }\n                            break;\n                        case '!':\n                            {\n                                basic_regex __exp;\n                                __exp.__flags_ = __flags_;\n                                __temp = __exp.__parse(++__temp, __last);\n                                unsigned __mexp = __exp.__marked_count_;\n                                __push_lookahead(_VSTD::move(__exp), true, __marked_count_);\n                                __marked_count_ += __mexp;\n                                if (__temp == __last || *__temp != ')')\n                                    __throw_regex_error<regex_constants::error_paren>();\n                                __first = ++__temp;\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n            break;\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_atom(_ForwardIterator __first,\n                                           _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        switch (*__first)\n        {\n        case '.':\n            __push_match_any_but_newline();\n            ++__first;\n            break;\n        case '\\\\':\n            __first = __parse_atom_escape(__first, __last);\n            break;\n        case '[':\n            __first = __parse_bracket_expression(__first, __last);\n            break;\n        case '(':\n            {\n                ++__first;\n                if (__first == __last)\n                    __throw_regex_error<regex_constants::error_paren>();\n                _ForwardIterator __temp = _VSTD::next(__first);\n                if (__temp != __last && *__first == '?' && *__temp == ':')\n                {\n                    ++__open_count_;\n                    __first = __parse_ecma_exp(++__temp, __last);\n                    if (__first == __last || *__first != ')')\n                        __throw_regex_error<regex_constants::error_paren>();\n                    --__open_count_;\n                    ++__first;\n                }\n                else\n                {\n                    __push_begin_marked_subexpression();\n                    unsigned __temp_count = __marked_count_;\n                    ++__open_count_;\n                    __first = __parse_ecma_exp(__first, __last);\n                    if (__first == __last || *__first != ')')\n                        __throw_regex_error<regex_constants::error_paren>();\n                    __push_end_marked_subexpression(__temp_count);\n                    --__open_count_;\n                    ++__first;\n                }\n            }\n            break;\n        case '*':\n        case '+':\n        case '?':\n        case '{':\n            __throw_regex_error<regex_constants::error_badrepeat>();\n            break;\n        default:\n            __first = __parse_pattern_character(__first, __last);\n            break;\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_atom_escape(_ForwardIterator __first,\n                                                  _ForwardIterator __last)\n{\n    if (__first != __last && *__first == '\\\\')\n    {\n        _ForwardIterator __t1 = _VSTD::next(__first);\n        _ForwardIterator __t2 = __parse_decimal_escape(__t1, __last);\n        if (__t2 != __t1)\n            __first = __t2;\n        else\n        {\n            __t2 = __parse_character_class_escape(__t1, __last);\n            if (__t2 != __t1)\n                __first = __t2;\n            else\n            {\n                __t2 = __parse_character_escape(__t1, __last);\n                if (__t2 != __t1)\n                    __first = __t2;\n            }\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_decimal_escape(_ForwardIterator __first,\n                                                     _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        if (*__first == '0')\n        {\n            __push_char(_CharT());\n            ++__first;\n        }\n        else if ('1' <= *__first && *__first <= '9')\n        {\n            unsigned __v = *__first - '0';\n            for (++__first; '0' <= *__first && *__first <= '9'; ++__first)\n                __v = 10 * __v + *__first - '0';\n            if (__v > mark_count())\n                __throw_regex_error<regex_constants::error_backref>();\n            __push_back_ref(__v);\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_character_class_escape(_ForwardIterator __first,\n                                                             _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        __bracket_expression<_CharT, _Traits>* __ml;\n        switch (*__first)\n        {\n        case 'd':\n            __ml = __start_matching_list(false);\n            __ml->__add_class(ctype_base::digit);\n            ++__first;\n            break;\n        case 'D':\n            __ml = __start_matching_list(true);\n            __ml->__add_class(ctype_base::digit);\n            ++__first;\n            break;\n        case 's':\n            __ml = __start_matching_list(false);\n            __ml->__add_class(ctype_base::space);\n            ++__first;\n            break;\n        case 'S':\n            __ml = __start_matching_list(true);\n            __ml->__add_class(ctype_base::space);\n            ++__first;\n            break;\n        case 'w':\n            __ml = __start_matching_list(false);\n            __ml->__add_class(ctype_base::alnum);\n            __ml->__add_char('_');\n            ++__first;\n            break;\n        case 'W':\n            __ml = __start_matching_list(true);\n            __ml->__add_class(ctype_base::alnum);\n            __ml->__add_char('_');\n            ++__first;\n            break;\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_character_escape(_ForwardIterator __first,\n                                                    _ForwardIterator __last,\n                                                    basic_string<_CharT>* __str)\n{\n    if (__first != __last)\n    {\n        _ForwardIterator __t;\n        unsigned __sum = 0;\n        int __hd;\n        switch (*__first)\n        {\n        case 'f':\n            if (__str)\n                *__str = _CharT(0xC);\n            else\n                __push_char(_CharT(0xC));\n            ++__first;\n            break;\n        case 'n':\n            if (__str)\n                *__str = _CharT(0xA);\n            else\n                __push_char(_CharT(0xA));\n            ++__first;\n            break;\n        case 'r':\n            if (__str)\n                *__str = _CharT(0xD);\n            else\n                __push_char(_CharT(0xD));\n            ++__first;\n            break;\n        case 't':\n            if (__str)\n                *__str = _CharT(0x9);\n            else\n                __push_char(_CharT(0x9));\n            ++__first;\n            break;\n        case 'v':\n            if (__str)\n                *__str = _CharT(0xB);\n            else\n                __push_char(_CharT(0xB));\n            ++__first;\n            break;\n        case 'c':\n            if ((__t = _VSTD::next(__first)) != __last)\n            {\n                if (('A' <= *__t && *__t <= 'Z') || \n                    ('a' <= *__t && *__t <= 'z'))\n                {\n                    if (__str)\n                        *__str = _CharT(*__t % 32);\n                    else\n                        __push_char(_CharT(*__t % 32));\n                    __first = ++__t;\n                }\n                else \n                    __throw_regex_error<regex_constants::error_escape>();\n            }\n            else\n                __throw_regex_error<regex_constants::error_escape>();\n            break;\n        case 'u':\n            ++__first;\n            if (__first == __last)\n                __throw_regex_error<regex_constants::error_escape>();\n            __hd = __traits_.value(*__first, 16);\n            if (__hd == -1)\n                __throw_regex_error<regex_constants::error_escape>();\n            __sum = 16 * __sum + static_cast<unsigned>(__hd);\n            ++__first;\n            if (__first == __last)\n                __throw_regex_error<regex_constants::error_escape>();\n            __hd = __traits_.value(*__first, 16);\n            if (__hd == -1)\n                __throw_regex_error<regex_constants::error_escape>();\n            __sum = 16 * __sum + static_cast<unsigned>(__hd);\n            // drop through\n        case 'x':\n            ++__first;\n            if (__first == __last)\n                __throw_regex_error<regex_constants::error_escape>();\n            __hd = __traits_.value(*__first, 16);\n            if (__hd == -1)\n                __throw_regex_error<regex_constants::error_escape>();\n            __sum = 16 * __sum + static_cast<unsigned>(__hd);\n            ++__first;\n            if (__first == __last)\n                __throw_regex_error<regex_constants::error_escape>();\n            __hd = __traits_.value(*__first, 16);\n            if (__hd == -1)\n                __throw_regex_error<regex_constants::error_escape>();\n            __sum = 16 * __sum + static_cast<unsigned>(__hd);\n            if (__str)\n                *__str = _CharT(__sum);\n            else\n                __push_char(_CharT(__sum));\n            ++__first;\n            break;\n        case '0':\n            if (__str)\n                *__str = _CharT(0);\n            else\n                __push_char(_CharT(0));\n            ++__first;\n            break;\n        default:\n            if (*__first != '_' && !__traits_.isctype(*__first, ctype_base::alnum))\n            {\n                if (__str)\n                    *__str = *__first;\n                else\n                    __push_char(*__first);\n                ++__first;\n            }\n            else\n                __throw_regex_error<regex_constants::error_escape>();\n            break;\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_pattern_character(_ForwardIterator __first,\n                                                        _ForwardIterator __last)\n{\n    if (__first != __last)\n    {\n        switch (*__first)\n        {\n        case '^':\n        case '$':\n        case '\\\\':\n        case '.':\n        case '*':\n        case '+':\n        case '?':\n        case '(':\n        case ')':\n        case '[':\n        case ']':\n        case '{':\n        case '}':\n        case '|':\n            break;\n        default:\n            __push_char(*__first);\n            ++__first;\n            break;\n        }\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_grep(_ForwardIterator __first,\n                                           _ForwardIterator __last)\n{\n    __owns_one_state<_CharT>* __sa = __end_;\n    _ForwardIterator __t1 = _VSTD::find(__first, __last, _CharT('\\n'));\n    if (__t1 != __first)\n        __parse_basic_reg_exp(__first, __t1);\n    else\n        __push_empty();\n    __first = __t1;\n    if (__first != __last)\n        ++__first;\n    while (__first != __last)\n    {\n        __t1 = _VSTD::find(__first, __last, _CharT('\\n'));\n        __owns_one_state<_CharT>* __sb = __end_;\n        if (__t1 != __first)\n            __parse_basic_reg_exp(__first, __t1);\n        else\n            __push_empty();\n        __push_alternation(__sa, __sb);\n        __first = __t1;\n        if (__first != __last)\n            ++__first;\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _ForwardIterator>\n_ForwardIterator\nbasic_regex<_CharT, _Traits>::__parse_egrep(_ForwardIterator __first,\n                                            _ForwardIterator __last)\n{\n    __owns_one_state<_CharT>* __sa = __end_;\n    _ForwardIterator __t1 = _VSTD::find(__first, __last, _CharT('\\n'));\n    if (__t1 != __first)\n        __parse_extended_reg_exp(__first, __t1);\n    else\n        __push_empty();\n    __first = __t1;\n    if (__first != __last)\n        ++__first;\n    while (__first != __last)\n    {\n        __t1 = _VSTD::find(__first, __last, _CharT('\\n'));\n        __owns_one_state<_CharT>* __sb = __end_;\n        if (__t1 != __first)\n            __parse_extended_reg_exp(__first, __t1);\n        else\n            __push_empty();\n        __push_alternation(__sa, __sb);\n        __first = __t1;\n        if (__first != __last)\n            ++__first;\n    }\n    return __first;\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_regex<_CharT, _Traits>::__push_loop(size_t __min, size_t __max,\n        __owns_one_state<_CharT>* __s, size_t __mexp_begin, size_t __mexp_end,\n        bool __greedy)\n{\n    unique_ptr<__empty_state<_CharT> > __e1(new __empty_state<_CharT>(__end_->first()));\n    __end_->first() = nullptr;\n    unique_ptr<__loop<_CharT> > __e2(new __loop<_CharT>(__loop_count_,\n                __s->first(), __e1.get(), __mexp_begin, __mexp_end, __greedy,\n                __min, __max));\n    __s->first() = nullptr;\n    __e1.release();\n    __end_->first() = new __repeat_one_loop<_CharT>(__e2.get());\n    __end_ = __e2->second();\n    __s->first() = __e2.release();\n    ++__loop_count_;\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_regex<_CharT, _Traits>::__push_char(value_type __c)\n{\n    if (flags() & icase)\n        __end_->first() = new __match_char_icase<_CharT, _Traits>\n                                              (__traits_, __c, __end_->first());\n    else if (flags() & collate)\n        __end_->first() = new __match_char_collate<_CharT, _Traits>\n                                              (__traits_, __c, __end_->first());\n    else\n        __end_->first() = new __match_char<_CharT>(__c, __end_->first());\n    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_regex<_CharT, _Traits>::__push_begin_marked_subexpression()\n{\n    if (!(__flags_ & nosubs))\n    {\n        __end_->first() =\n                new __begin_marked_subexpression<_CharT>(++__marked_count_,\n                                                         __end_->first());\n        __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());\n    }\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_regex<_CharT, _Traits>::__push_end_marked_subexpression(unsigned __sub)\n{\n    if (!(__flags_ & nosubs))\n    {\n        __end_->first() =\n                new __end_marked_subexpression<_CharT>(__sub, __end_->first());\n        __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());\n    }\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_regex<_CharT, _Traits>::__push_l_anchor()\n{\n    __end_->first() = new __l_anchor<_CharT>(__end_->first());\n    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_regex<_CharT, _Traits>::__push_r_anchor()\n{\n    __end_->first() = new __r_anchor<_CharT>(__end_->first());\n    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_regex<_CharT, _Traits>::__push_match_any()\n{\n    __end_->first() = new __match_any<_CharT>(__end_->first());\n    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_regex<_CharT, _Traits>::__push_match_any_but_newline()\n{\n    __end_->first() = new __match_any_but_newline<_CharT>(__end_->first());\n    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_regex<_CharT, _Traits>::__push_empty()\n{\n    __end_->first() = new __empty_state<_CharT>(__end_->first());\n    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_regex<_CharT, _Traits>::__push_word_boundary(bool __invert)\n{\n    __end_->first() = new __word_boundary<_CharT, _Traits>(__traits_, __invert,\n                                                           __end_->first());\n    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_regex<_CharT, _Traits>::__push_back_ref(int __i)\n{\n    if (flags() & icase)\n        __end_->first() = new __back_ref_icase<_CharT, _Traits>\n                                              (__traits_, __i, __end_->first());\n    else if (flags() & collate)\n        __end_->first() = new __back_ref_collate<_CharT, _Traits>\n                                              (__traits_, __i, __end_->first());\n    else\n        __end_->first() = new __back_ref<_CharT>(__i, __end_->first());\n    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_regex<_CharT, _Traits>::__push_alternation(__owns_one_state<_CharT>* __sa,\n                                                 __owns_one_state<_CharT>* __ea)\n{\n    __sa->first() = new __alternate<_CharT>(\n                         static_cast<__owns_one_state<_CharT>*>(__sa->first()),\n                         static_cast<__owns_one_state<_CharT>*>(__ea->first()));\n    __ea->first() = nullptr;\n    __ea->first() = new __empty_state<_CharT>(__end_->first());\n    __end_->first() = nullptr;\n    __end_->first() = new __empty_non_own_state<_CharT>(__ea->first());\n    __end_ = static_cast<__owns_one_state<_CharT>*>(__ea->first());\n}\n\ntemplate <class _CharT, class _Traits>\n__bracket_expression<_CharT, _Traits>*\nbasic_regex<_CharT, _Traits>::__start_matching_list(bool __negate)\n{\n    __bracket_expression<_CharT, _Traits>* __r =\n        new __bracket_expression<_CharT, _Traits>(__traits_, __end_->first(),\n                                                  __negate, __flags_ & icase,\n                                                  __flags_ & collate);\n    __end_->first() = __r;\n    __end_ = __r;\n    return __r;\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_regex<_CharT, _Traits>::__push_lookahead(const basic_regex& __exp,\n                                               bool __invert,\n                                               unsigned __mexp)\n{\n    __end_->first() = new __lookahead<_CharT, _Traits>(__exp, __invert,\n                                                           __end_->first(), __mexp);\n    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());\n}\n\ntypedef basic_regex<char>    regex;\ntypedef basic_regex<wchar_t> wregex;\n\n// sub_match\n\ntemplate <class _BidirectionalIterator>\nclass _LIBCPP_TYPE_VIS_ONLY sub_match\n    : public pair<_BidirectionalIterator, _BidirectionalIterator>\n{\npublic:\n    typedef _BidirectionalIterator                              iterator;\n    typedef typename iterator_traits<iterator>::value_type      value_type;\n    typedef typename iterator_traits<iterator>::difference_type difference_type;\n    typedef basic_string<value_type>                            string_type;\n\n    bool matched;\n\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_CONSTEXPR sub_match() : matched() {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    difference_type length() const\n        {return matched ? _VSTD::distance(this->first, this->second) : 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    string_type str() const\n        {return matched ? string_type(this->first, this->second) : string_type();}\n    _LIBCPP_INLINE_VISIBILITY\n    operator string_type() const\n        {return str();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    int compare(const sub_match& __s) const\n        {return str().compare(__s.str());}\n    _LIBCPP_INLINE_VISIBILITY\n    int compare(const string_type& __s) const\n        {return str().compare(__s);}\n    _LIBCPP_INLINE_VISIBILITY\n    int compare(const value_type* __s) const\n        {return str().compare(__s);}\n};\n\ntypedef sub_match<const char*>             csub_match;\ntypedef sub_match<const wchar_t*>          wcsub_match;\ntypedef sub_match<string::const_iterator>  ssub_match;\ntypedef sub_match<wstring::const_iterator> wssub_match;\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)\n{\n    return __x.compare(__y) == 0;\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)\n{\n    return __x.compare(__y) < 0;\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _BiIter, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,\n           const sub_match<_BiIter>& __y)\n{\n    return __y.compare(typename sub_match<_BiIter>::string_type(__x.data(), __x.size())) == 0;\n}\n\ntemplate <class _BiIter, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,\n           const sub_match<_BiIter>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _BiIter, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,\n          const sub_match<_BiIter>& __y)\n{\n    return __y.compare(typename sub_match<_BiIter>::string_type(__x.data(), __x.size())) > 0;\n}\n\ntemplate <class _BiIter, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,\n          const sub_match<_BiIter>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _BiIter, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\nbool operator>=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,\n                const sub_match<_BiIter>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _BiIter, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,\n           const sub_match<_BiIter>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _BiIter, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const sub_match<_BiIter>& __x,\n           const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)\n{\n    return __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) == 0;\n}\n\ntemplate <class _BiIter, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const sub_match<_BiIter>& __x,\n           const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _BiIter, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const sub_match<_BiIter>& __x,\n          const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)\n{\n    return __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) < 0;\n}\n\ntemplate <class _BiIter, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\nbool operator>(const sub_match<_BiIter>& __x,\n               const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _BiIter, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const sub_match<_BiIter>& __x,\n           const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _BiIter, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const sub_match<_BiIter>& __x,\n           const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(typename iterator_traits<_BiIter>::value_type const* __x,\n           const sub_match<_BiIter>& __y)\n{\n    return __y.compare(__x) == 0;\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(typename iterator_traits<_BiIter>::value_type const* __x,\n           const sub_match<_BiIter>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(typename iterator_traits<_BiIter>::value_type const* __x,\n          const sub_match<_BiIter>& __y)\n{\n    return __y.compare(__x) > 0;\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(typename iterator_traits<_BiIter>::value_type const* __x,\n          const sub_match<_BiIter>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(typename iterator_traits<_BiIter>::value_type const* __x,\n           const sub_match<_BiIter>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(typename iterator_traits<_BiIter>::value_type const* __x,\n           const sub_match<_BiIter>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const sub_match<_BiIter>& __x,\n           typename iterator_traits<_BiIter>::value_type const* __y)\n{\n    return __x.compare(__y) == 0;\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const sub_match<_BiIter>& __x,\n           typename iterator_traits<_BiIter>::value_type const* __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const sub_match<_BiIter>& __x,\n          typename iterator_traits<_BiIter>::value_type const* __y)\n{\n    return __x.compare(__y) < 0;\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(const sub_match<_BiIter>& __x,\n          typename iterator_traits<_BiIter>::value_type const* __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const sub_match<_BiIter>& __x,\n           typename iterator_traits<_BiIter>::value_type const* __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const sub_match<_BiIter>& __x,\n           typename iterator_traits<_BiIter>::value_type const* __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(typename iterator_traits<_BiIter>::value_type const& __x,\n           const sub_match<_BiIter>& __y)\n{\n    typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;\n    return __y.compare(string_type(1, __x)) == 0;\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(typename iterator_traits<_BiIter>::value_type const& __x,\n           const sub_match<_BiIter>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(typename iterator_traits<_BiIter>::value_type const& __x,\n          const sub_match<_BiIter>& __y)\n{\n    typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;\n    return __y.compare(string_type(1, __x)) > 0;\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(typename iterator_traits<_BiIter>::value_type const& __x,\n          const sub_match<_BiIter>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(typename iterator_traits<_BiIter>::value_type const& __x,\n           const sub_match<_BiIter>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(typename iterator_traits<_BiIter>::value_type const& __x,\n           const sub_match<_BiIter>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const sub_match<_BiIter>& __x,\n           typename iterator_traits<_BiIter>::value_type const& __y)\n{\n    typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;\n    return __x.compare(string_type(1, __y)) == 0;\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const sub_match<_BiIter>& __x,\n           typename iterator_traits<_BiIter>::value_type const& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const sub_match<_BiIter>& __x,\n          typename iterator_traits<_BiIter>::value_type const& __y)\n{\n    typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;\n    return __x.compare(string_type(1, __y)) < 0;\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>(const sub_match<_BiIter>& __x,\n          typename iterator_traits<_BiIter>::value_type const& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const sub_match<_BiIter>& __x,\n           typename iterator_traits<_BiIter>::value_type const& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const sub_match<_BiIter>& __x,\n           typename iterator_traits<_BiIter>::value_type const& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _CharT, class _ST, class _BiIter>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostream<_CharT, _ST>&\noperator<<(basic_ostream<_CharT, _ST>& __os, const sub_match<_BiIter>& __m)\n{\n    return __os << __m.str();\n}\n\ntemplate <class _BidirectionalIterator, class _Allocator>\nclass _LIBCPP_TYPE_VIS_ONLY match_results\n{\npublic:\n    typedef _Allocator                                        allocator_type;\n    typedef sub_match<_BidirectionalIterator>                 value_type;\nprivate:\n    typedef vector<value_type, allocator_type>                __container_type;\n\n    __container_type  __matches_;\n    value_type __unmatched_;\n    value_type __prefix_;\n    value_type __suffix_;\n    bool       __ready_;\npublic:\n    _BidirectionalIterator __position_start_;\n    typedef const value_type&                                 const_reference;\n    typedef value_type&                                       reference;\n    typedef typename __container_type::const_iterator         const_iterator;\n    typedef const_iterator                                    iterator;\n    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;\n    typedef typename allocator_traits<allocator_type>::size_type size_type;\n    typedef typename iterator_traits<_BidirectionalIterator>::value_type char_type;\n    typedef basic_string<char_type>                           string_type;\n\n    // construct/copy/destroy:\n    explicit match_results(const allocator_type& __a = allocator_type());\n//    match_results(const match_results&) = default;\n//    match_results& operator=(const match_results&) = default;\n//    match_results(match_results&& __m) = default;\n//    match_results& operator=(match_results&& __m) = default;\n//    ~match_results() = default;\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool ready() const {return __ready_;}\n\n    // size:\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const {return __matches_.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const {return __matches_.max_size();}\n    _LIBCPP_INLINE_VISIBILITY\n    bool empty() const {return size() == 0;}\n\n    // element access:\n    _LIBCPP_INLINE_VISIBILITY\n    difference_type length(size_type __sub = 0) const\n        {return (*this)[__sub].length();}\n    _LIBCPP_INLINE_VISIBILITY\n    difference_type position(size_type __sub = 0) const\n        {return _VSTD::distance(__position_start_, (*this)[__sub].first);}\n    _LIBCPP_INLINE_VISIBILITY\n    string_type str(size_type __sub = 0) const\n        {return (*this)[__sub].str();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reference operator[](size_type __n) const\n        {return __n < __matches_.size() ? __matches_[__n] : __unmatched_;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    const_reference prefix() const {return __prefix_;}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reference suffix() const {return __suffix_;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin() const {return empty() ? __matches_.end() : __matches_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end() const {return __matches_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cbegin() const {return empty() ? __matches_.end() : __matches_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cend() const {return __matches_.end();}\n\n    // format:\n    template <class _OutputIter>\n        _OutputIter\n        format(_OutputIter __out, const char_type* __fmt_first,\n               const char_type* __fmt_last,\n               regex_constants::match_flag_type __flags = regex_constants::format_default) const;\n    template <class _OutputIter, class _ST, class _SA>\n        _LIBCPP_INLINE_VISIBILITY\n        _OutputIter\n        format(_OutputIter __out, const basic_string<char_type, _ST, _SA>& __fmt,\n               regex_constants::match_flag_type __flags = regex_constants::format_default) const\n            {return format(__out, __fmt.data(), __fmt.data() + __fmt.size(), __flags);}\n    template <class _ST, class _SA>\n        _LIBCPP_INLINE_VISIBILITY\n        basic_string<char_type, _ST, _SA>\n        format(const basic_string<char_type, _ST, _SA>& __fmt,\n               regex_constants::match_flag_type __flags = regex_constants::format_default) const\n        {\n            basic_string<char_type, _ST, _SA> __r;\n            format(back_inserter(__r), __fmt.data(), __fmt.data() + __fmt.size(),\n                   __flags);\n            return __r;\n        }\n    _LIBCPP_INLINE_VISIBILITY\n    string_type\n        format(const char_type* __fmt,\n               regex_constants::match_flag_type __flags = regex_constants::format_default) const\n        {\n            string_type __r;\n            format(back_inserter(__r), __fmt,\n                   __fmt + char_traits<char_type>::length(__fmt), __flags);\n            return __r;\n        }\n\n    // allocator:\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const {return __matches_.get_allocator();}\n\n    // swap:\n    void swap(match_results& __m);\n\n    template <class _Bp, class _Ap>\n        _LIBCPP_INLINE_VISIBILITY\n        void __assign(_BidirectionalIterator __f, _BidirectionalIterator __l,\n                      const match_results<_Bp, _Ap>& __m, bool __no_update_pos)\n    {\n        _Bp __mf = __m.prefix().first;\n        __matches_.resize(__m.size());\n        for (size_type __i = 0; __i < __matches_.size(); ++__i)\n        {\n            __matches_[__i].first = _VSTD::next(__f, _VSTD::distance(__mf, __m[__i].first));\n            __matches_[__i].second = _VSTD::next(__f, _VSTD::distance(__mf, __m[__i].second));\n            __matches_[__i].matched = __m[__i].matched;\n        }\n        __unmatched_.first   = __l;\n        __unmatched_.second  = __l;\n        __unmatched_.matched = false;\n        __prefix_.first = _VSTD::next(__f, _VSTD::distance(__mf, __m.prefix().first));\n        __prefix_.second = _VSTD::next(__f, _VSTD::distance(__mf, __m.prefix().second));\n        __prefix_.matched = __m.prefix().matched;\n        __suffix_.first = _VSTD::next(__f, _VSTD::distance(__mf, __m.suffix().first));\n        __suffix_.second = _VSTD::next(__f, _VSTD::distance(__mf, __m.suffix().second));\n        __suffix_.matched = __m.suffix().matched;\n        if (!__no_update_pos)\n            __position_start_ = __prefix_.first;\n        __ready_ = __m.ready();\n    }\n\nprivate:\n    void __init(unsigned __s,\n                _BidirectionalIterator __f, _BidirectionalIterator __l,\n                bool __no_update_pos = false);\n\n    template <class, class> friend class basic_regex;\n\n    template <class _Bp, class _Ap, class _Cp, class _Tp>\n    friend\n    bool\n    regex_match(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Cp, _Tp>&,\n                regex_constants::match_flag_type);\n\n    template <class _Bp, class _Ap>\n    friend\n    bool\n    operator==(const match_results<_Bp, _Ap>&, const match_results<_Bp, _Ap>&);\n\n    template <class, class> friend class __lookahead;\n};\n\ntemplate <class _BidirectionalIterator, class _Allocator>\nmatch_results<_BidirectionalIterator, _Allocator>::match_results(\n        const allocator_type& __a)\n    : __matches_(__a),\n      __unmatched_(),\n      __prefix_(),\n      __suffix_(),\n      __ready_(false),\n      __position_start_()\n{\n}\n\ntemplate <class _BidirectionalIterator, class _Allocator>\nvoid\nmatch_results<_BidirectionalIterator, _Allocator>::__init(unsigned __s,\n                         _BidirectionalIterator __f, _BidirectionalIterator __l,\n                         bool __no_update_pos)\n{\n    __unmatched_.first   = __l;\n    __unmatched_.second  = __l;\n    __unmatched_.matched = false;\n    __matches_.assign(__s, __unmatched_);\n    __prefix_.first      = __f;\n    __prefix_.second     = __f;\n    __prefix_.matched    = false;\n    __suffix_ = __unmatched_;\n    if (!__no_update_pos)\n        __position_start_ = __prefix_.first;\n    __ready_ = true;\n}\n\ntemplate <class _BidirectionalIterator, class _Allocator>\ntemplate <class _OutputIter>\n_OutputIter\nmatch_results<_BidirectionalIterator, _Allocator>::format(_OutputIter __out,\n        const char_type* __fmt_first, const char_type* __fmt_last,\n        regex_constants::match_flag_type __flags) const\n{\n    if (__flags & regex_constants::format_sed)\n    {\n        for (; __fmt_first != __fmt_last; ++__fmt_first)\n        {\n            if (*__fmt_first == '&')\n                __out = _VSTD::copy(__matches_[0].first, __matches_[0].second,\n                                   __out);\n            else if (*__fmt_first == '\\\\' && __fmt_first + 1 != __fmt_last)\n            {\n                ++__fmt_first;\n                if ('0' <= *__fmt_first && *__fmt_first <= '9')\n                {\n                    size_t __i = *__fmt_first - '0';\n                    __out = _VSTD::copy(__matches_[__i].first,\n                                       __matches_[__i].second, __out);\n                }\n                else\n                {\n                    *__out = *__fmt_first;\n                    ++__out;\n                }\n            }\n            else\n            {\n                *__out = *__fmt_first;\n                ++__out;\n            }\n        }\n    }\n    else\n    {\n        for (; __fmt_first != __fmt_last; ++__fmt_first)\n        {\n            if (*__fmt_first == '$' && __fmt_first + 1 != __fmt_last)\n            {\n                switch (__fmt_first[1])\n                {\n                case '$':\n                    *__out = *++__fmt_first;\n                    ++__out;\n                    break;\n                case '&':\n                    ++__fmt_first;\n                    __out = _VSTD::copy(__matches_[0].first, __matches_[0].second,\n                                       __out);\n                    break;\n                case '`':\n                    ++__fmt_first;\n                    __out = _VSTD::copy(__prefix_.first, __prefix_.second, __out);\n                    break;\n                case '\\'':\n                    ++__fmt_first;\n                    __out = _VSTD::copy(__suffix_.first, __suffix_.second, __out);\n                    break;\n                default:\n                    if ('0' <= __fmt_first[1] && __fmt_first[1] <= '9')\n                    {\n                        ++__fmt_first;\n                        size_t __i = *__fmt_first - '0';\n                        if (__fmt_first + 1 != __fmt_last &&\n                            '0' <= __fmt_first[1] && __fmt_first[1] <= '9')\n                        {\n                            ++__fmt_first;\n                            __i = 10 * __i + *__fmt_first - '0';\n                        }\n                        __out = _VSTD::copy(__matches_[__i].first,\n                                           __matches_[__i].second, __out);\n                    }\n                    else\n                    {\n                        *__out = *__fmt_first;\n                        ++__out;\n                    }\n                    break;\n                }\n            }\n            else\n            {\n                *__out = *__fmt_first;\n                ++__out;\n            }\n        }\n    }\n    return __out;\n}\n\ntemplate <class _BidirectionalIterator, class _Allocator>\nvoid\nmatch_results<_BidirectionalIterator, _Allocator>::swap(match_results& __m)\n{\n    using _VSTD::swap;\n    swap(__matches_, __m.__matches_);\n    swap(__unmatched_, __m.__unmatched_);\n    swap(__prefix_, __m.__prefix_);\n    swap(__suffix_, __m.__suffix_);\n    swap(__position_start_, __m.__position_start_);\n    swap(__ready_, __m.__ready_);\n}\n\ntypedef match_results<const char*>             cmatch;\ntypedef match_results<const wchar_t*>          wcmatch;\ntypedef match_results<string::const_iterator>  smatch;\ntypedef match_results<wstring::const_iterator> wsmatch;\n\ntemplate <class _BidirectionalIterator, class _Allocator>\nbool\noperator==(const match_results<_BidirectionalIterator, _Allocator>& __x,\n           const match_results<_BidirectionalIterator, _Allocator>& __y)\n{\n    if (__x.__ready_ != __y.__ready_)\n        return false;\n    if (!__x.__ready_)\n        return true;\n    return __x.__matches_ == __y.__matches_ &&\n           __x.__prefix_ == __y.__prefix_ &&\n           __x.__suffix_ == __y.__suffix_;\n}\n\ntemplate <class _BidirectionalIterator, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const match_results<_BidirectionalIterator, _Allocator>& __x,\n           const match_results<_BidirectionalIterator, _Allocator>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _BidirectionalIterator, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(match_results<_BidirectionalIterator, _Allocator>& __x,\n     match_results<_BidirectionalIterator, _Allocator>& __y)\n{\n    __x.swap(__y);\n}\n\n// regex_search\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _Allocator>\nbool\nbasic_regex<_CharT, _Traits>::__match_at_start_ecma(\n        const _CharT* __first, const _CharT* __last,\n        match_results<const _CharT*, _Allocator>& __m,\n        regex_constants::match_flag_type __flags, bool __at_first) const\n{\n    vector<__state> __states;\n    __node* __st = __start_.get();\n    if (__st)\n    {\n        sub_match<const _CharT*> __unmatched;\n        __unmatched.first   = __last;\n        __unmatched.second  = __last;\n        __unmatched.matched = false;\n\n        __states.push_back(__state());\n        __states.back().__do_ = 0;\n        __states.back().__first_ = __first;\n        __states.back().__current_ = __first;\n        __states.back().__last_ = __last;\n        __states.back().__sub_matches_.resize(mark_count(), __unmatched);\n        __states.back().__loop_data_.resize(__loop_count());\n        __states.back().__node_ = __st;\n        __states.back().__flags_ = __flags;\n        __states.back().__at_first_ = __at_first;\n        do\n        {\n            __state& __s = __states.back();\n            if (__s.__node_)\n                __s.__node_->__exec(__s);\n            switch (__s.__do_)\n            {\n            case __state::__end_state:\n                __m.__matches_[0].first = __first;\n                __m.__matches_[0].second = _VSTD::next(__first, __s.__current_ - __first);\n                __m.__matches_[0].matched = true;\n                for (unsigned __i = 0; __i < __s.__sub_matches_.size(); ++__i)\n                    __m.__matches_[__i+1] = __s.__sub_matches_[__i];\n                return true;\n            case __state::__accept_and_consume:\n            case __state::__repeat:\n            case __state::__accept_but_not_consume:\n                break;\n            case __state::__split:\n                {\n                __state __snext = __s;\n                __s.__node_->__exec_split(true, __s);\n                __snext.__node_->__exec_split(false, __snext);\n                __states.push_back(_VSTD::move(__snext));\n                }\n                break;\n            case __state::__reject:\n                __states.pop_back();\n                break;\n            default:\n                __throw_regex_error<regex_constants::__re_err_unknown>();\n                break;\n\n            }\n        } while (!__states.empty());\n    }\n    return false;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _Allocator>\nbool\nbasic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(\n        const _CharT* __first, const _CharT* __last,\n        match_results<const _CharT*, _Allocator>& __m,\n        regex_constants::match_flag_type __flags, bool __at_first) const\n{\n    deque<__state> __states;\n    ptrdiff_t __highest_j = 0;\n    ptrdiff_t _Np = _VSTD::distance(__first, __last);\n    __node* __st = __start_.get();\n    if (__st)\n    {\n        __states.push_back(__state());\n        __states.back().__do_ = 0;\n        __states.back().__first_ = __first;\n        __states.back().__current_ = __first;\n        __states.back().__last_ = __last;\n        __states.back().__loop_data_.resize(__loop_count());\n        __states.back().__node_ = __st;\n        __states.back().__flags_ = __flags;\n        __states.back().__at_first_ = __at_first;\n        bool __matched = false;\n        do\n        {\n            __state& __s = __states.back();\n            if (__s.__node_)\n                __s.__node_->__exec(__s);\n            switch (__s.__do_)\n            {\n            case __state::__end_state:\n                if (!__matched || __highest_j < __s.__current_ - __s.__first_)\n                    __highest_j = __s.__current_ - __s.__first_;\n                __matched = true;\n                if (__highest_j == _Np)\n                    __states.clear();\n                else\n                    __states.pop_back();\n                break;\n            case __state::__consume_input:\n                break;\n            case __state::__accept_and_consume:\n                __states.push_front(_VSTD::move(__s));\n                __states.pop_back();\n                break;\n            case __state::__repeat:\n            case __state::__accept_but_not_consume:\n                break;\n            case __state::__split:\n                {\n                __state __snext = __s;\n                __s.__node_->__exec_split(true, __s);\n                __snext.__node_->__exec_split(false, __snext);\n                __states.push_back(_VSTD::move(__snext));\n                }\n                break;\n            case __state::__reject:\n                __states.pop_back();\n                break;\n            default:\n                __throw_regex_error<regex_constants::__re_err_unknown>();\n                break;\n            }\n        } while (!__states.empty());\n        if (__matched)\n        {\n            __m.__matches_[0].first = __first;\n            __m.__matches_[0].second = _VSTD::next(__first, __highest_j);\n            __m.__matches_[0].matched = true;\n            return true;\n        }\n    }\n    return false;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _Allocator>\nbool\nbasic_regex<_CharT, _Traits>::__match_at_start_posix_subs(\n        const _CharT* __first, const _CharT* __last,\n        match_results<const _CharT*, _Allocator>& __m,\n        regex_constants::match_flag_type __flags, bool __at_first) const\n{\n    vector<__state> __states;\n    __state __best_state;\n    ptrdiff_t __j = 0;\n    ptrdiff_t __highest_j = 0;\n    ptrdiff_t _Np = _VSTD::distance(__first, __last);\n    __node* __st = __start_.get();\n    if (__st)\n    {\n        sub_match<const _CharT*> __unmatched;\n        __unmatched.first   = __last;\n        __unmatched.second  = __last;\n        __unmatched.matched = false;\n\n        __states.push_back(__state());\n        __states.back().__do_ = 0;\n        __states.back().__first_ = __first;\n        __states.back().__current_ = __first;\n        __states.back().__last_ = __last;\n        __states.back().__sub_matches_.resize(mark_count(), __unmatched);\n        __states.back().__loop_data_.resize(__loop_count());\n        __states.back().__node_ = __st;\n        __states.back().__flags_ = __flags;\n        __states.back().__at_first_ = __at_first;\n        const _CharT* __current = __first;\n        bool __matched = false;\n        do\n        {\n            __state& __s = __states.back();\n            if (__s.__node_)\n                __s.__node_->__exec(__s);\n            switch (__s.__do_)\n            {\n            case __state::__end_state:\n                if (!__matched || __highest_j < __s.__current_ - __s.__first_)\n                {\n                    __highest_j = __s.__current_ - __s.__first_;\n                    __best_state = __s;\n                }\n                __matched = true;\n                if (__highest_j == _Np)\n                    __states.clear();\n                else\n                    __states.pop_back();\n                break;\n            case __state::__accept_and_consume:\n                __j += __s.__current_ - __current;\n                __current = __s.__current_;\n                break;\n            case __state::__repeat:\n            case __state::__accept_but_not_consume:\n                break;\n            case __state::__split:\n                {\n                __state __snext = __s;\n                __s.__node_->__exec_split(true, __s);\n                __snext.__node_->__exec_split(false, __snext);\n                __states.push_back(_VSTD::move(__snext));\n                }\n                break;\n            case __state::__reject:\n                __states.pop_back();\n                break;\n            default:\n                __throw_regex_error<regex_constants::__re_err_unknown>();\n                break;\n            }\n        } while (!__states.empty());\n        if (__matched)\n        {\n            __m.__matches_[0].first = __first;\n            __m.__matches_[0].second = _VSTD::next(__first, __highest_j);\n            __m.__matches_[0].matched = true;\n            for (unsigned __i = 0; __i < __best_state.__sub_matches_.size(); ++__i)\n                __m.__matches_[__i+1] = __best_state.__sub_matches_[__i];\n            return true;\n        }\n    }\n    return false;\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _Allocator>\nbool\nbasic_regex<_CharT, _Traits>::__match_at_start(\n        const _CharT* __first, const _CharT* __last,\n        match_results<const _CharT*, _Allocator>& __m,\n        regex_constants::match_flag_type __flags, bool __at_first) const\n{\n    if ((__flags_ & 0x1F0) == ECMAScript)\n        return __match_at_start_ecma(__first, __last, __m, __flags, __at_first);\n    if (mark_count() == 0)\n        return __match_at_start_posix_nosubs(__first, __last, __m, __flags, __at_first);\n    return __match_at_start_posix_subs(__first, __last, __m, __flags, __at_first);\n}\n\ntemplate <class _CharT, class _Traits>\ntemplate <class _Allocator>\nbool\nbasic_regex<_CharT, _Traits>::__search(\n        const _CharT* __first, const _CharT* __last,\n        match_results<const _CharT*, _Allocator>& __m,\n        regex_constants::match_flag_type __flags) const\n{\n    __m.__init(1 + mark_count(), __first, __last,\n                                    __flags & regex_constants::__no_update_pos);\n    if (__match_at_start(__first, __last, __m, __flags, \n                                    !(__flags & regex_constants::__no_update_pos)))\n    {\n        __m.__prefix_.second = __m[0].first;\n        __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;\n        __m.__suffix_.first = __m[0].second;\n        __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;\n        return true;\n    }\n    if (__first != __last && !(__flags & regex_constants::match_continuous))\n    {\n        __flags |= regex_constants::match_prev_avail;\n        for (++__first; __first != __last; ++__first)\n        {\n            __m.__matches_.assign(__m.size(), __m.__unmatched_);\n            if (__match_at_start(__first, __last, __m, __flags, false))\n            {\n                __m.__prefix_.second = __m[0].first;\n                __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;\n                __m.__suffix_.first = __m[0].second;\n                __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;\n                return true;\n            }\n            __m.__matches_.assign(__m.size(), __m.__unmatched_);\n        }\n    }\n    __m.__matches_.clear();\n    return false;\n}\n\ntemplate <class _BidirectionalIterator, class _Allocator, class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_search(_BidirectionalIterator __first, _BidirectionalIterator __last,\n             match_results<_BidirectionalIterator, _Allocator>& __m,\n             const basic_regex<_CharT, _Traits>& __e,\n             regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    int __offset = (__flags & regex_constants::match_prev_avail) ? 1 : 0;\n    basic_string<_CharT> __s(_VSTD::prev(__first, __offset), __last);\n    match_results<const _CharT*> __mc;\n    bool __r = __e.__search(__s.data() + __offset, __s.data() + __s.size(), __mc, __flags);\n    __m.__assign(__first, __last, __mc, __flags & regex_constants::__no_update_pos);\n    return __r;\n}\n\ntemplate <class _Iter, class _Allocator, class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_search(__wrap_iter<_Iter> __first,\n             __wrap_iter<_Iter> __last,\n             match_results<__wrap_iter<_Iter>, _Allocator>& __m,\n             const basic_regex<_CharT, _Traits>& __e,\n             regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    match_results<const _CharT*> __mc;\n    bool __r = __e.__search(__first.base(), __last.base(), __mc, __flags);\n    __m.__assign(__first, __last, __mc, __flags & regex_constants::__no_update_pos);\n    return __r;\n}\n\ntemplate <class _Allocator, class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_search(const _CharT* __first, const _CharT* __last,\n             match_results<const _CharT*, _Allocator>& __m,\n             const basic_regex<_CharT, _Traits>& __e,\n             regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    return __e.__search(__first, __last, __m, __flags);\n}\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_search(_BidirectionalIterator __first, _BidirectionalIterator __last,\n             const basic_regex<_CharT, _Traits>& __e,\n             regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    basic_string<_CharT> __s(__first, __last);\n    match_results<const _CharT*> __mc;\n    return __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_search(const _CharT* __first, const _CharT* __last,\n             const basic_regex<_CharT, _Traits>& __e,\n             regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    match_results<const _CharT*> __mc;\n    return __e.__search(__first, __last, __mc, __flags);\n}\n\ntemplate <class _CharT, class _Allocator, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_search(const _CharT* __str, match_results<const _CharT*, _Allocator>& __m,\n             const basic_regex<_CharT, _Traits>& __e,\n             regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    return __e.__search(__str, __str + _Traits::length(__str), __m, __flags);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_search(const _CharT* __str, const basic_regex<_CharT, _Traits>& __e,\n             regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    match_results<const _CharT*> __m;\n    return _VSTD::regex_search(__str, __m, __e, __flags);\n}\n\ntemplate <class _ST, class _SA, class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_search(const basic_string<_CharT, _ST, _SA>& __s,\n             const basic_regex<_CharT, _Traits>& __e,\n             regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    match_results<const _CharT*> __mc;\n    return __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags);\n}\n\ntemplate <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_search(const basic_string<_CharT, _ST, _SA>& __s,\n             match_results<typename basic_string<_CharT, _ST, _SA>::const_iterator, _Allocator>& __m,\n             const basic_regex<_CharT, _Traits>& __e,\n             regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    match_results<const _CharT*> __mc;\n    bool __r = __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags);\n    __m.__assign(__s.begin(), __s.end(), __mc, __flags & regex_constants::__no_update_pos);\n    return __r;\n}\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _ST, class _SA, class _Ap, class _Cp, class _Tp>\nbool\nregex_search(const basic_string<_Cp, _ST, _SA>&& __s,\n             match_results<typename basic_string<_Cp, _ST, _SA>::const_iterator, _Ap>&,\n             const basic_regex<_Cp, _Tp>& __e,\n             regex_constants::match_flag_type __flags = regex_constants::match_default) = delete; \n#endif\n\n// regex_match\n\ntemplate <class _BidirectionalIterator, class _Allocator, class _CharT, class _Traits>\nbool\nregex_match(_BidirectionalIterator __first, _BidirectionalIterator __last,\n            match_results<_BidirectionalIterator, _Allocator>& __m,\n            const basic_regex<_CharT, _Traits>& __e,\n            regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    bool __r = _VSTD::regex_search(__first, __last, __m, __e,\n                            __flags | regex_constants::match_continuous);\n    if (__r)\n    {\n        __r = !__m.suffix().matched;\n        if (!__r)\n            __m.__matches_.clear();\n    }\n    return __r;\n}\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_match(_BidirectionalIterator __first, _BidirectionalIterator __last,\n            const basic_regex<_CharT, _Traits>& __e,\n            regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    match_results<_BidirectionalIterator> __m;\n    return _VSTD::regex_match(__first, __last, __m, __e, __flags);\n}\n\ntemplate <class _CharT, class _Allocator, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_match(const _CharT* __str, match_results<const _CharT*, _Allocator>& __m,\n            const basic_regex<_CharT, _Traits>& __e,\n            regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    return _VSTD::regex_match(__str, __str + _Traits::length(__str), __m, __e, __flags);\n}\n\ntemplate <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_match(const basic_string<_CharT, _ST, _SA>& __s,\n            match_results<typename basic_string<_CharT, _ST, _SA>::const_iterator, _Allocator>& __m,\n            const basic_regex<_CharT, _Traits>& __e,\n            regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    return _VSTD::regex_match(__s.begin(), __s.end(), __m, __e, __flags);\n}\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_match(const basic_string<_CharT, _ST, _SA>&& __s,\n            match_results<typename basic_string<_CharT, _ST, _SA>::const_iterator, _Allocator>& __m,\n            const basic_regex<_CharT, _Traits>& __e,\n            regex_constants::match_flag_type __flags = regex_constants::match_default) = delete; \n#endif\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_match(const _CharT* __str, const basic_regex<_CharT, _Traits>& __e,\n            regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    return _VSTD::regex_match(__str, __str + _Traits::length(__str), __e, __flags);\n}\n\ntemplate <class _ST, class _SA, class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nregex_match(const basic_string<_CharT, _ST, _SA>& __s,\n            const basic_regex<_CharT, _Traits>& __e,\n            regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    return _VSTD::regex_match(__s.begin(), __s.end(), __e, __flags);\n}\n\n// regex_iterator\n\ntemplate <class _BidirectionalIterator,\n          class _CharT = typename iterator_traits<_BidirectionalIterator>::value_type,\n          class _Traits = regex_traits<_CharT> >\nclass _LIBCPP_TYPE_VIS_ONLY regex_iterator\n{\npublic:\n    typedef basic_regex<_CharT, _Traits>          regex_type;\n    typedef match_results<_BidirectionalIterator> value_type;\n    typedef ptrdiff_t                             difference_type;\n    typedef const value_type*                     pointer;\n    typedef const value_type&                     reference;\n    typedef forward_iterator_tag                  iterator_category;\n\nprivate:\n    _BidirectionalIterator           __begin_;\n    _BidirectionalIterator           __end_;\n    const regex_type*                __pregex_;\n    regex_constants::match_flag_type __flags_;\n    value_type                       __match_;\n\npublic:\n    regex_iterator();\n    regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,\n                   const regex_type& __re,\n                   regex_constants::match_flag_type __m\n                                              = regex_constants::match_default);\n#if _LIBCPP_STD_VER > 11\n    regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,\n                   const regex_type&& __re,\n                   regex_constants::match_flag_type __m \n                                     = regex_constants::match_default) = delete;\n#endif\n\n    bool operator==(const regex_iterator& __x) const;\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const regex_iterator& __x) const {return !(*this == __x);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    reference operator*() const {return  __match_;}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer operator->() const  {return &__match_;}\n\n    regex_iterator& operator++();\n    _LIBCPP_INLINE_VISIBILITY\n    regex_iterator operator++(int)\n    {\n        regex_iterator __t(*this);\n        ++(*this);\n        return __t;\n    }\n};\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\nregex_iterator<_BidirectionalIterator, _CharT, _Traits>::regex_iterator()\n    : __begin_(), __end_(), __pregex_(nullptr), __flags_(), __match_()\n{\n}\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\nregex_iterator<_BidirectionalIterator, _CharT, _Traits>::\n    regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,\n                   const regex_type& __re, regex_constants::match_flag_type __m)\n    : __begin_(__a),\n      __end_(__b),\n      __pregex_(&__re),\n      __flags_(__m)\n{\n    _VSTD::regex_search(__begin_, __end_, __match_, *__pregex_, __flags_);\n}\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\nbool\nregex_iterator<_BidirectionalIterator, _CharT, _Traits>::\n    operator==(const regex_iterator& __x) const\n{\n    if (__match_.empty() && __x.__match_.empty())\n        return true;\n    if (__match_.empty() || __x.__match_.empty())\n        return false;\n    return __begin_ == __x.__begin_       &&\n           __end_ == __x.__end_           &&\n           __pregex_ == __x.__pregex_     &&\n           __flags_ == __x.__flags_       &&\n           __match_[0] == __x.__match_[0];\n}\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\nregex_iterator<_BidirectionalIterator, _CharT, _Traits>&\nregex_iterator<_BidirectionalIterator, _CharT, _Traits>::operator++()\n{\n    __flags_ |= regex_constants::__no_update_pos;\n    _BidirectionalIterator __start = __match_[0].second;\n    if (__match_.empty())\n    {\n        if (__start == __end_)\n        {\n            __match_ = value_type();\n            return *this;\n        }\n        else if (_VSTD::regex_search(__start, __end_, __match_, *__pregex_,\n                                    __flags_ | regex_constants::match_not_null |\n                                    regex_constants::match_continuous))\n            return *this;\n        else\n            ++__start;\n    }\n    __flags_ |= regex_constants::match_prev_avail;\n    if (!_VSTD::regex_search(__start, __end_, __match_, *__pregex_, __flags_))\n        __match_ = value_type();\n    return *this;\n}\n\ntypedef regex_iterator<const char*>             cregex_iterator;\ntypedef regex_iterator<const wchar_t*>          wcregex_iterator;\ntypedef regex_iterator<string::const_iterator>  sregex_iterator;\ntypedef regex_iterator<wstring::const_iterator> wsregex_iterator;\n\n// regex_token_iterator\n\ntemplate <class _BidirectionalIterator,\n          class _CharT = typename iterator_traits<_BidirectionalIterator>::value_type,\n          class _Traits = regex_traits<_CharT> >\nclass _LIBCPP_TYPE_VIS_ONLY regex_token_iterator\n{\npublic:\n    typedef basic_regex<_CharT, _Traits>      regex_type;\n    typedef sub_match<_BidirectionalIterator> value_type;\n    typedef ptrdiff_t                         difference_type;\n    typedef const value_type*                 pointer;\n    typedef const value_type&                 reference;\n    typedef forward_iterator_tag              iterator_category;\n\nprivate:\n    typedef regex_iterator<_BidirectionalIterator, _CharT, _Traits> _Position;\n\n    _Position         __position_;\n    const value_type* __result_;\n    value_type        __suffix_;\n    ptrdiff_t         _N_;\n    vector<int>       __subs_;\n\npublic:\n    regex_token_iterator();\n    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,\n                         const regex_type& __re, int __submatch = 0,\n                         regex_constants::match_flag_type __m =\n                                                regex_constants::match_default);\n#if _LIBCPP_STD_VER > 11\n    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,\n                         const regex_type&& __re, int __submatch = 0,\n                         regex_constants::match_flag_type __m =\n                                       regex_constants::match_default) = delete;\n#endif\n\n    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,\n                         const regex_type& __re, const vector<int>& __submatches,\n                         regex_constants::match_flag_type __m =\n                                                regex_constants::match_default);\n#if _LIBCPP_STD_VER > 11\n    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,\n                         const regex_type&& __re, const vector<int>& __submatches,\n                         regex_constants::match_flag_type __m =\n                                     regex_constants::match_default) = delete;\n#endif\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,\n                         const regex_type& __re,\n                         initializer_list<int> __submatches,\n                         regex_constants::match_flag_type __m =\n                                                regex_constants::match_default);\n\n#if _LIBCPP_STD_VER > 11\n    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,\n                         const regex_type&& __re,\n                         initializer_list<int> __submatches,\n                         regex_constants::match_flag_type __m =\n                                       regex_constants::match_default) = delete;\n#endif\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    template <size_t _Np>\n        regex_token_iterator(_BidirectionalIterator __a,\n                             _BidirectionalIterator __b,\n                             const regex_type& __re,\n                             const int (&__submatches)[_Np],\n                             regex_constants::match_flag_type __m =\n                                                regex_constants::match_default);\n#if _LIBCPP_STD_VER > 11\n    template <std::size_t _Np>\n        regex_token_iterator(_BidirectionalIterator __a,\n                             _BidirectionalIterator __b,\n                             const regex_type&& __re,\n                             const int (&__submatches)[_Np],\n                             regex_constants::match_flag_type __m =\n                                      regex_constants::match_default) = delete;\n#endif\n\n    regex_token_iterator(const regex_token_iterator&);\n    regex_token_iterator& operator=(const regex_token_iterator&);\n\n    bool operator==(const regex_token_iterator& __x) const;\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const regex_token_iterator& __x) const {return !(*this == __x);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    const value_type& operator*() const {return *__result_;}\n    _LIBCPP_INLINE_VISIBILITY\n    const value_type* operator->() const {return __result_;}\n\n    regex_token_iterator& operator++();\n    _LIBCPP_INLINE_VISIBILITY\n    regex_token_iterator operator++(int)\n    {\n        regex_token_iterator __t(*this);\n        ++(*this);\n        return __t;\n    }\n\nprivate:\n    void __init(_BidirectionalIterator __a, _BidirectionalIterator __b);\n    void __establish_result () {\n        if (__subs_[_N_] == -1)\n            __result_ = &__position_->prefix();\n        else\n            __result_ = &(*__position_)[__subs_[_N_]];\n        }       \n};\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\nregex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::\n    regex_token_iterator()\n    : __result_(nullptr),\n      __suffix_(),\n      _N_(0)\n{\n}\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\nvoid\nregex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::\n    __init(_BidirectionalIterator __a, _BidirectionalIterator __b)\n{\n    if (__position_ != _Position())\n        __establish_result ();\n    else if (__subs_[_N_] == -1)\n    {\n        __suffix_.matched = true;\n        __suffix_.first = __a;\n        __suffix_.second = __b;\n        __result_ = &__suffix_;\n    }\n    else\n        __result_ = nullptr;\n}\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\nregex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::\n    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,\n                         const regex_type& __re, int __submatch,\n                         regex_constants::match_flag_type __m)\n    : __position_(__a, __b, __re, __m),\n      _N_(0),\n      __subs_(1, __submatch)\n{\n    __init(__a, __b);\n}\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\nregex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::\n    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,\n                         const regex_type& __re, const vector<int>& __submatches,\n                         regex_constants::match_flag_type __m)\n    : __position_(__a, __b, __re, __m),\n      _N_(0),\n      __subs_(__submatches)\n{\n    __init(__a, __b);\n}\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\nregex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::\n    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,\n                         const regex_type& __re,\n                         initializer_list<int> __submatches,\n                         regex_constants::match_flag_type __m)\n    : __position_(__a, __b, __re, __m),\n      _N_(0),\n      __subs_(__submatches)\n{\n    __init(__a, __b);\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\ntemplate <size_t _Np>\nregex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::\n    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,\n                             const regex_type& __re,\n                             const int (&__submatches)[_Np],\n                             regex_constants::match_flag_type __m)\n    : __position_(__a, __b, __re, __m),\n      _N_(0),\n      __subs_(__submatches, __submatches + _Np)\n{\n    __init(__a, __b);\n}\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\nregex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::\n    regex_token_iterator(const regex_token_iterator& __x)\n    : __position_(__x.__position_),\n      __result_(__x.__result_),\n      __suffix_(__x.__suffix_),\n      _N_(__x._N_),\n      __subs_(__x.__subs_)\n{\n    if (__x.__result_ == &__x.__suffix_)\n        __result_ = &__suffix_;\n    else if ( __result_ != nullptr )\n        __establish_result ();\n}\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\nregex_token_iterator<_BidirectionalIterator, _CharT, _Traits>&\nregex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::\n    operator=(const regex_token_iterator& __x)\n{\n    if (this != &__x)\n    {\n        __position_ = __x.__position_;\n        if (__x.__result_ == &__x.__suffix_)\n            __result_ = &__suffix_;\n        else\n            __result_ = __x.__result_;\n        __suffix_ = __x.__suffix_;\n        _N_ = __x._N_;\n        __subs_ = __x.__subs_;\n\n        if ( __result_ != nullptr && __result_ != &__suffix_ )\n            __establish_result();\n    }\n    return *this;\n}\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\nbool\nregex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::\n    operator==(const regex_token_iterator& __x) const\n{\n    if (__result_ == nullptr && __x.__result_ == nullptr)\n        return true;\n    if (__result_ == &__suffix_ && __x.__result_ == &__x.__suffix_ &&\n            __suffix_ == __x.__suffix_)\n        return true;\n    if (__result_ == nullptr || __x.__result_ == nullptr)\n        return false;\n    if (__result_ == &__suffix_ || __x.__result_ == &__x.__suffix_)\n        return false;\n    return __position_ == __x.__position_ && _N_ == __x._N_ &&\n           __subs_ == __x.__subs_;\n}\n\ntemplate <class _BidirectionalIterator, class _CharT, class _Traits>\nregex_token_iterator<_BidirectionalIterator, _CharT, _Traits>&\nregex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::operator++()\n{\n    _Position __prev = __position_;\n    if (__result_ == &__suffix_)\n        __result_ = nullptr;\n    else if (_N_ + 1 < __subs_.size())\n    {\n        ++_N_;\n        __establish_result();\n    }\n    else\n    {\n        _N_ = 0;\n        ++__position_;\n        if (__position_ != _Position())\n            __establish_result();\n        else\n        {\n            if (_VSTD::find(__subs_.begin(), __subs_.end(), -1) != __subs_.end()\n                && __prev->suffix().length() != 0)\n            {\n                __suffix_.matched = true;\n                __suffix_.first = __prev->suffix().first;\n                __suffix_.second = __prev->suffix().second;\n                __result_ = &__suffix_;\n            }\n            else\n                __result_ = nullptr;\n        }\n    }\n    return *this;\n}\n\ntypedef regex_token_iterator<const char*>             cregex_token_iterator;\ntypedef regex_token_iterator<const wchar_t*>          wcregex_token_iterator;\ntypedef regex_token_iterator<string::const_iterator>  sregex_token_iterator;\ntypedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;\n\n// regex_replace\n\ntemplate <class _OutputIterator, class _BidirectionalIterator,\n          class _Traits, class _CharT>\n_OutputIterator\nregex_replace(_OutputIterator __out,\n              _BidirectionalIterator __first, _BidirectionalIterator __last,\n              const basic_regex<_CharT, _Traits>& __e, const _CharT* __fmt,\n              regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    typedef regex_iterator<_BidirectionalIterator, _CharT, _Traits> _Iter;\n    _Iter __i(__first, __last, __e, __flags);\n    _Iter __eof;\n    if (__i == __eof)\n    {\n        if (!(__flags & regex_constants::format_no_copy))\n            __out = _VSTD::copy(__first, __last, __out);\n    }\n    else\n    {\n        sub_match<_BidirectionalIterator> __lm;\n        for (size_t __len = char_traits<_CharT>::length(__fmt); __i != __eof; ++__i)\n        {\n            if (!(__flags & regex_constants::format_no_copy))\n                __out = _VSTD::copy(__i->prefix().first, __i->prefix().second, __out);\n            __out = __i->format(__out, __fmt, __fmt + __len, __flags);\n            __lm = __i->suffix();\n            if (__flags & regex_constants::format_first_only)\n                break;\n        }\n        if (!(__flags & regex_constants::format_no_copy))\n            __out = _VSTD::copy(__lm.first, __lm.second, __out);\n    }\n    return __out;\n}\n\ntemplate <class _OutputIterator, class _BidirectionalIterator,\n          class _Traits, class _CharT, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\n_OutputIterator\nregex_replace(_OutputIterator __out,\n              _BidirectionalIterator __first, _BidirectionalIterator __last,\n              const basic_regex<_CharT, _Traits>& __e,\n              const basic_string<_CharT, _ST, _SA>& __fmt,\n              regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    return _VSTD::regex_replace(__out, __first, __last, __e, __fmt.c_str(), __flags);\n}\n\ntemplate <class _Traits, class _CharT, class _ST, class _SA, class _FST,\n          class _FSA>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _ST, _SA>\nregex_replace(const basic_string<_CharT, _ST, _SA>& __s,\n              const basic_regex<_CharT, _Traits>& __e,\n              const basic_string<_CharT, _FST, _FSA>& __fmt,\n              regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    basic_string<_CharT, _ST, _SA> __r;\n    _VSTD::regex_replace(back_inserter(__r), __s.begin(), __s.end(), __e,\n                        __fmt.c_str(), __flags);\n    return __r;\n}\n\ntemplate <class _Traits, class _CharT, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _ST, _SA>\nregex_replace(const basic_string<_CharT, _ST, _SA>& __s,\n              const basic_regex<_CharT, _Traits>& __e, const _CharT* __fmt,\n              regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    basic_string<_CharT, _ST, _SA> __r;\n    _VSTD::regex_replace(back_inserter(__r), __s.begin(), __s.end(), __e,\n                        __fmt, __flags);\n    return __r;\n}\n\ntemplate <class _Traits, class _CharT, class _ST, class _SA>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT>\nregex_replace(const _CharT* __s,\n              const basic_regex<_CharT, _Traits>& __e,\n              const basic_string<_CharT, _ST, _SA>& __fmt,\n              regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    basic_string<_CharT> __r;\n    _VSTD::regex_replace(back_inserter(__r), __s,\n                        __s + char_traits<_CharT>::length(__s), __e,\n                        __fmt.c_str(), __flags);\n    return __r;\n}\n\ntemplate <class _Traits, class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT>\nregex_replace(const _CharT* __s,\n              const basic_regex<_CharT, _Traits>& __e,\n              const _CharT* __fmt,\n              regex_constants::match_flag_type __flags = regex_constants::match_default)\n{\n    basic_string<_CharT> __r;\n    _VSTD::regex_replace(back_inserter(__r), __s,\n                        __s + char_traits<_CharT>::length(__s), __e,\n                        __fmt, __flags);\n    return __r;\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_REGEX\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/scoped_allocator",
    "content": "// -*- C++ -*-\n//===-------------------------- scoped_allocator --------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SCOPED_ALLOCATOR\n#define _LIBCPP_SCOPED_ALLOCATOR\n\n/*\n    scoped_allocator synopsis\n\nnamespace std\n{\n\ntemplate <class OuterAlloc, class... InnerAllocs>\nclass scoped_allocator_adaptor : public OuterAlloc\n{\n    typedef allocator_traits<OuterAlloc> OuterTraits; // exposition only\n    scoped_allocator_adaptor<InnerAllocs...> inner;   // exposition only\npublic:\n\n    typedef OuterAlloc outer_allocator_type;\n    typedef see below inner_allocator_type;\n\n    typedef typename OuterTraits::value_type value_type;\n    typedef typename OuterTraits::size_type size_type;\n    typedef typename OuterTraits::difference_type difference_type;\n    typedef typename OuterTraits::pointer pointer;\n    typedef typename OuterTraits::const_pointer const_pointer;\n    typedef typename OuterTraits::void_pointer void_pointer;\n    typedef typename OuterTraits::const_void_pointer const_void_pointer;\n\n    typedef see below propagate_on_container_copy_assignment;\n    typedef see below propagate_on_container_move_assignment;\n    typedef see below propagate_on_container_swap;\n    typedef see below is_always_equal;\n\n    template <class Tp>\n        struct rebind\n        {\n            typedef scoped_allocator_adaptor<\n                OuterTraits::template rebind_alloc<Tp>, InnerAllocs...> other;\n        };\n\n    scoped_allocator_adaptor();\n    template <class OuterA2>\n        scoped_allocator_adaptor(OuterA2&& outerAlloc,\n                                 const InnerAllocs&... innerAllocs) noexcept;\n    scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;\n    scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;\n    template <class OuterA2>\n        scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;\n    template <class OuterA2>\n        scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;\n\n    ~scoped_allocator_adaptor();\n\n    inner_allocator_type& inner_allocator() noexcept;\n    const inner_allocator_type& inner_allocator() const noexcept;\n\n    outer_allocator_type& outer_allocator() noexcept;\n    const outer_allocator_type& outer_allocator() const noexcept;\n\n    pointer allocate(size_type n);\n    pointer allocate(size_type n, const_void_pointer hint);\n    void deallocate(pointer p, size_type n) noexcept;\n\n    size_type max_size() const;\n    template <class T, class... Args> void construct(T* p, Args&& args);\n    template <class T1, class T2, class... Args1, class... Args2>\n        void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x,\n                       tuple<Args2...> y);\n    template <class T1, class T2>\n        void construct(pair<T1, T2>* p);\n    template <class T1, class T2, class U, class V>\n        void construct(pair<T1, T2>* p, U&& x, V&& y);\n    template <class T1, class T2, class U, class V>\n        void construct(pair<T1, T2>* p, const pair<U, V>& x);\n    template <class T1, class T2, class U, class V>\n        void construct(pair<T1, T2>* p, pair<U, V>&& x);\n    template <class T> void destroy(T* p);\n\n    template <class T> void destroy(T* p) noexcept;\n\n    scoped_allocator_adaptor select_on_container_copy_construction() const noexcept;\n};\n\ntemplate <class OuterA1, class OuterA2, class... InnerAllocs>\n    bool\n    operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,\n               const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;\n\ntemplate <class OuterA1, class OuterA2, class... InnerAllocs>\n    bool\n    operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,\n               const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;\n\n}  // std\n\n*/\n\n#include <__config>\n#include <memory>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)\n\n// scoped_allocator_adaptor\n\ntemplate <class ..._Allocs>\nclass scoped_allocator_adaptor;\n\ntemplate <class ..._Allocs> struct __get_poc_copy_assignment;\n\ntemplate <class _A0>\nstruct __get_poc_copy_assignment<_A0>\n{\n    static const bool value = allocator_traits<_A0>::\n                              propagate_on_container_copy_assignment::value;\n};\n\ntemplate <class _A0, class ..._Allocs>\nstruct __get_poc_copy_assignment<_A0, _Allocs...>\n{\n    static const bool value =\n        allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||\n        __get_poc_copy_assignment<_Allocs...>::value;\n};\n\ntemplate <class ..._Allocs> struct __get_poc_move_assignment;\n\ntemplate <class _A0>\nstruct __get_poc_move_assignment<_A0>\n{\n    static const bool value = allocator_traits<_A0>::\n                              propagate_on_container_move_assignment::value;\n};\n\ntemplate <class _A0, class ..._Allocs>\nstruct __get_poc_move_assignment<_A0, _Allocs...>\n{\n    static const bool value =\n        allocator_traits<_A0>::propagate_on_container_move_assignment::value ||\n        __get_poc_move_assignment<_Allocs...>::value;\n};\n\ntemplate <class ..._Allocs> struct __get_poc_swap;\n\ntemplate <class _A0>\nstruct __get_poc_swap<_A0>\n{\n    static const bool value = allocator_traits<_A0>::\n                              propagate_on_container_swap::value;\n};\n\ntemplate <class _A0, class ..._Allocs>\nstruct __get_poc_swap<_A0, _Allocs...>\n{\n    static const bool value =\n        allocator_traits<_A0>::propagate_on_container_swap::value ||\n        __get_poc_swap<_Allocs...>::value;\n};\n\ntemplate <class ..._Allocs> struct __get_is_always_equal;\n\ntemplate <class _A0>\nstruct __get_is_always_equal<_A0>\n{\n    static const bool value = allocator_traits<_A0>::is_always_equal::value;\n};\n\ntemplate <class _A0, class ..._Allocs>\nstruct __get_is_always_equal<_A0, _Allocs...>\n{\n    static const bool value =\n        allocator_traits<_A0>::is_always_equal::value &&\n        __get_is_always_equal<_Allocs...>::value;\n};\n\ntemplate <class ..._Allocs>\nclass __scoped_allocator_storage;\n\ntemplate <class _OuterAlloc, class... _InnerAllocs>\nclass __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>\n    : public _OuterAlloc\n{\n    typedef _OuterAlloc outer_allocator_type;\nprotected:\n    typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;\n\nprivate:\n    inner_allocator_type __inner_;\n\nprotected:\n\n    _LIBCPP_INLINE_VISIBILITY\n    __scoped_allocator_storage() _NOEXCEPT {}\n\n    template <class _OuterA2,\n              class = typename enable_if<\n                        is_constructible<outer_allocator_type, _OuterA2>::value\n                      >::type>\n        _LIBCPP_INLINE_VISIBILITY\n        __scoped_allocator_storage(_OuterA2&& __outerAlloc,\n                                   const _InnerAllocs& ...__innerAllocs) _NOEXCEPT\n            : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)),\n              __inner_(__innerAllocs...) {}\n\n    template <class _OuterA2,\n              class = typename enable_if<\n                        is_constructible<outer_allocator_type, const _OuterA2&>::value\n                      >::type>\n        _LIBCPP_INLINE_VISIBILITY\n        __scoped_allocator_storage(\n            const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT\n            : outer_allocator_type(__other.outer_allocator()),\n              __inner_(__other.inner_allocator()) {}\n\n    template <class _OuterA2,\n              class = typename enable_if<\n                        is_constructible<outer_allocator_type, _OuterA2>::value\n                      >::type>\n        _LIBCPP_INLINE_VISIBILITY\n        __scoped_allocator_storage(\n            __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT\n            : outer_allocator_type(_VSTD::move(__other.outer_allocator())),\n              __inner_(_VSTD::move(__other.inner_allocator())) {}\n\n    template <class _OuterA2,\n              class = typename enable_if<\n                        is_constructible<outer_allocator_type, _OuterA2>::value\n                      >::type>\n        _LIBCPP_INLINE_VISIBILITY\n        __scoped_allocator_storage(_OuterA2&& __o,\n                                   const inner_allocator_type& __i) _NOEXCEPT\n            : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)),\n              __inner_(__i)\n        {\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    inner_allocator_type& inner_allocator() _NOEXCEPT             {return __inner_;}\n    _LIBCPP_INLINE_VISIBILITY\n    const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    outer_allocator_type& outer_allocator() _NOEXCEPT\n        {return static_cast<outer_allocator_type&>(*this);}\n    _LIBCPP_INLINE_VISIBILITY\n    const outer_allocator_type& outer_allocator() const _NOEXCEPT\n        {return static_cast<const outer_allocator_type&>(*this);}\n\n    scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>\n    _LIBCPP_INLINE_VISIBILITY\n    select_on_container_copy_construction() const _NOEXCEPT\n        {\n            return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>\n            (\n                allocator_traits<outer_allocator_type>::\n                    select_on_container_copy_construction(outer_allocator()),\n                allocator_traits<inner_allocator_type>::\n                    select_on_container_copy_construction(inner_allocator())\n            );\n        }\n\n    template <class...> friend class __scoped_allocator_storage;\n};\n\ntemplate <class _OuterAlloc>\nclass __scoped_allocator_storage<_OuterAlloc>\n    : public _OuterAlloc\n{\n    typedef _OuterAlloc outer_allocator_type;\nprotected:\n    typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __scoped_allocator_storage() _NOEXCEPT {}\n\n    template <class _OuterA2,\n              class = typename enable_if<\n                        is_constructible<outer_allocator_type, _OuterA2>::value\n                      >::type>\n        _LIBCPP_INLINE_VISIBILITY\n        __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT\n            : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)) {}\n\n    template <class _OuterA2,\n              class = typename enable_if<\n                        is_constructible<outer_allocator_type, const _OuterA2&>::value\n                      >::type>\n        _LIBCPP_INLINE_VISIBILITY\n        __scoped_allocator_storage(\n            const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT\n            : outer_allocator_type(__other.outer_allocator()) {}\n\n    template <class _OuterA2,\n              class = typename enable_if<\n                        is_constructible<outer_allocator_type, _OuterA2>::value\n                      >::type>\n        _LIBCPP_INLINE_VISIBILITY\n        __scoped_allocator_storage(\n            __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT\n            : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    inner_allocator_type& inner_allocator() _NOEXCEPT\n        {return static_cast<inner_allocator_type&>(*this);}\n    _LIBCPP_INLINE_VISIBILITY\n    const inner_allocator_type& inner_allocator() const _NOEXCEPT\n        {return static_cast<const inner_allocator_type&>(*this);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    outer_allocator_type& outer_allocator() _NOEXCEPT\n        {return static_cast<outer_allocator_type&>(*this);}\n    _LIBCPP_INLINE_VISIBILITY\n    const outer_allocator_type& outer_allocator() const _NOEXCEPT\n        {return static_cast<const outer_allocator_type&>(*this);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    scoped_allocator_adaptor<outer_allocator_type>\n    select_on_container_copy_construction() const _NOEXCEPT\n        {return scoped_allocator_adaptor<outer_allocator_type>(\n            allocator_traits<outer_allocator_type>::\n                select_on_container_copy_construction(outer_allocator())\n        );}\n\n    __scoped_allocator_storage(const outer_allocator_type& __o,\n                               const inner_allocator_type& __i) _NOEXCEPT;\n\n    template <class...> friend class __scoped_allocator_storage;\n};\n\n// __outermost\n\ntemplate <class _Alloc>\ndecltype(declval<_Alloc>().outer_allocator(), true_type())\n__has_outer_allocator_test(_Alloc&& __a);\n\ntemplate <class _Alloc>\nfalse_type\n__has_outer_allocator_test(const volatile _Alloc& __a);\n\ntemplate <class _Alloc>\nstruct __has_outer_allocator\n    : public common_type\n             <\n                 decltype(__has_outer_allocator_test(declval<_Alloc&>()))\n             >::type\n{\n};\n\ntemplate <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>\nstruct __outermost\n{\n    typedef _Alloc type;\n    _LIBCPP_INLINE_VISIBILITY\n    type& operator()(type& __a) const _NOEXCEPT {return __a;}\n};\n\ntemplate <class _Alloc>\nstruct __outermost<_Alloc, true>\n{\n    typedef typename remove_reference\n                     <\n                        decltype(_VSTD::declval<_Alloc>().outer_allocator())\n                     >::type                                    _OuterAlloc;\n    typedef typename __outermost<_OuterAlloc>::type             type;\n    _LIBCPP_INLINE_VISIBILITY\n    type& operator()(_Alloc& __a) const _NOEXCEPT\n        {return __outermost<_OuterAlloc>()(__a.outer_allocator());}\n};\n\ntemplate <class _OuterAlloc, class... _InnerAllocs>\nclass _LIBCPP_TYPE_VIS_ONLY scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>\n    : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>\n{\n    typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;\n    typedef allocator_traits<_OuterAlloc>             _OuterTraits;\npublic:\n    typedef _OuterAlloc                               outer_allocator_type;\n    typedef typename base::inner_allocator_type       inner_allocator_type;\n    typedef typename _OuterTraits::size_type          size_type;\n    typedef typename _OuterTraits::difference_type    difference_type;\n    typedef typename _OuterTraits::pointer            pointer;\n    typedef typename _OuterTraits::const_pointer      const_pointer;\n    typedef typename _OuterTraits::void_pointer       void_pointer;\n    typedef typename _OuterTraits::const_void_pointer const_void_pointer;\n\n    typedef integral_constant\n            <\n                bool,\n                __get_poc_copy_assignment<outer_allocator_type,\n                                          _InnerAllocs...>::value\n            > propagate_on_container_copy_assignment;\n    typedef integral_constant\n            <\n                bool,\n                __get_poc_move_assignment<outer_allocator_type,\n                                          _InnerAllocs...>::value\n            > propagate_on_container_move_assignment;\n    typedef integral_constant\n            <\n                bool,\n                __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value\n            > propagate_on_container_swap;\n    typedef integral_constant\n            <\n                bool,\n                __get_is_always_equal<outer_allocator_type, _InnerAllocs...>::value\n            > is_always_equal;\n\n    template <class _Tp>\n    struct rebind\n    {\n        typedef scoped_allocator_adaptor\n        <\n            typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs...\n        > other;\n    };\n\n    _LIBCPP_INLINE_VISIBILITY\n    scoped_allocator_adaptor() _NOEXCEPT {}\n    template <class _OuterA2,\n              class = typename enable_if<\n                        is_constructible<outer_allocator_type, _OuterA2>::value\n                      >::type>\n        _LIBCPP_INLINE_VISIBILITY\n        scoped_allocator_adaptor(_OuterA2&& __outerAlloc,\n                                 const _InnerAllocs& ...__innerAllocs) _NOEXCEPT\n            : base(_VSTD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {}\n    // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;\n    template <class _OuterA2,\n              class = typename enable_if<\n                        is_constructible<outer_allocator_type, const _OuterA2&>::value\n                      >::type>\n        _LIBCPP_INLINE_VISIBILITY\n        scoped_allocator_adaptor(\n            const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT\n                : base(__other) {}\n    template <class _OuterA2,\n              class = typename enable_if<\n                        is_constructible<outer_allocator_type, _OuterA2>::value\n                      >::type>\n        _LIBCPP_INLINE_VISIBILITY\n        scoped_allocator_adaptor(\n            scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT\n                : base(_VSTD::move(__other)) {}\n\n    // ~scoped_allocator_adaptor() = default;\n\n    _LIBCPP_INLINE_VISIBILITY\n    inner_allocator_type& inner_allocator() _NOEXCEPT\n        {return base::inner_allocator();}\n    _LIBCPP_INLINE_VISIBILITY\n    const inner_allocator_type& inner_allocator() const _NOEXCEPT\n        {return base::inner_allocator();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    outer_allocator_type& outer_allocator() _NOEXCEPT\n        {return base::outer_allocator();}\n    _LIBCPP_INLINE_VISIBILITY\n    const outer_allocator_type& outer_allocator() const _NOEXCEPT\n        {return base::outer_allocator();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    pointer allocate(size_type __n)\n        {return allocator_traits<outer_allocator_type>::\n            allocate(outer_allocator(), __n);}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer allocate(size_type __n, const_void_pointer __hint)\n        {return allocator_traits<outer_allocator_type>::\n            allocate(outer_allocator(), __n, __hint);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void deallocate(pointer __p, size_type __n) _NOEXCEPT\n        {allocator_traits<outer_allocator_type>::\n            deallocate(outer_allocator(), __p, __n);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const\n        {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}\n\n    template <class _Tp, class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        void construct(_Tp* __p, _Args&& ...__args)\n            {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type, _Args...>(),\n                         __p, _VSTD::forward<_Args>(__args)...);}\n    template <class _Tp>\n        _LIBCPP_INLINE_VISIBILITY\n        void destroy(_Tp* __p)\n            {\n                typedef __outermost<outer_allocator_type> _OM;\n                allocator_traits<typename _OM::type>::\n                                         destroy(_OM()(outer_allocator()), __p);\n            }\n\n    _LIBCPP_INLINE_VISIBILITY\n    scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT\n        {return base::select_on_container_copy_construction();}\n\nprivate:\n\n    template <class _OuterA2,\n              class = typename enable_if<\n                        is_constructible<outer_allocator_type, _OuterA2>::value\n                      >::type>\n    _LIBCPP_INLINE_VISIBILITY\n    scoped_allocator_adaptor(_OuterA2&& __o,\n                             const inner_allocator_type& __i) _NOEXCEPT\n        : base(_VSTD::forward<_OuterA2>(__o), __i) {}\n\n    template <class _Tp, class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)\n            {\n                typedef __outermost<outer_allocator_type> _OM;\n                allocator_traits<typename _OM::type>::construct\n                (\n                    _OM()(outer_allocator()),\n                    __p,\n                    _VSTD::forward<_Args>(__args)...\n                );\n            }\n\n    template <class _Tp, class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)\n            {\n                typedef __outermost<outer_allocator_type> _OM;\n                allocator_traits<typename _OM::type>::construct\n                (\n                    _OM()(outer_allocator()),\n                    __p,\n                    allocator_arg,\n                    inner_allocator(),\n                    _VSTD::forward<_Args>(__args)...\n                );\n            }\n\n    template <class _Tp, class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)\n            {\n                typedef __outermost<outer_allocator_type> _OM;\n                allocator_traits<typename _OM::type>::construct\n                (\n                    _OM()(outer_allocator()),\n                    __p,\n                    _VSTD::forward<_Args>(__args)...,\n                    inner_allocator()\n                );\n            }\n\n    template <class...> friend class __scoped_allocator_storage;\n};\n\ntemplate <class _OuterA1, class _OuterA2>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const scoped_allocator_adaptor<_OuterA1>& __a,\n           const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT\n{\n    return __a.outer_allocator() == __b.outer_allocator();\n}\n\ntemplate <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,\n           const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT\n{\n    return __a.outer_allocator() == __b.outer_allocator() &&\n           __a.inner_allocator() == __b.inner_allocator();\n}\n\ntemplate <class _OuterA1, class _OuterA2, class... _InnerAllocs>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,\n           const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT\n{\n    return !(__a == __b);\n}\n\n#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_SCOPED_ALLOCATOR\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/set",
    "content": "// -*- C++ -*-\n//===---------------------------- set -------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SET\n#define _LIBCPP_SET\n\n/*\n\n    set synopsis\n\nnamespace std\n{\n\ntemplate <class Key, class Compare = less<Key>,\n          class Allocator = allocator<Key>>\nclass set\n{\npublic:\n    // types:\n    typedef Key                                      key_type;\n    typedef key_type                                 value_type;\n    typedef Compare                                  key_compare;\n    typedef key_compare                              value_compare;\n    typedef Allocator                                allocator_type;\n    typedef typename allocator_type::reference       reference;\n    typedef typename allocator_type::const_reference const_reference;\n    typedef typename allocator_type::size_type       size_type;\n    typedef typename allocator_type::difference_type difference_type;\n    typedef typename allocator_type::pointer         pointer;\n    typedef typename allocator_type::const_pointer   const_pointer;\n\n    typedef implementation-defined                   iterator;\n    typedef implementation-defined                   const_iterator;\n    typedef std::reverse_iterator<iterator>          reverse_iterator;\n    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;\n\n    // construct/copy/destroy:\n    set()\n        noexcept(\n            is_nothrow_default_constructible<allocator_type>::value &&\n            is_nothrow_default_constructible<key_compare>::value &&\n            is_nothrow_copy_constructible<key_compare>::value);\n    explicit set(const value_compare& comp);\n    set(const value_compare& comp, const allocator_type& a);\n    template <class InputIterator>\n        set(InputIterator first, InputIterator last,\n            const value_compare& comp = value_compare());\n    template <class InputIterator>\n        set(InputIterator first, InputIterator last, const value_compare& comp,\n            const allocator_type& a);\n    set(const set& s);\n    set(set&& s)\n        noexcept(\n            is_nothrow_move_constructible<allocator_type>::value &&\n            is_nothrow_move_constructible<key_compare>::value);\n    explicit set(const allocator_type& a);\n    set(const set& s, const allocator_type& a);\n    set(set&& s, const allocator_type& a);\n    set(initializer_list<value_type> il, const value_compare& comp = value_compare());\n    set(initializer_list<value_type> il, const value_compare& comp,\n        const allocator_type& a);\n    template <class InputIterator>\n        set(InputIterator first, InputIterator last, const allocator_type& a)\n            : set(first, last, Compare(), a) {}  // C++14\n    set(initializer_list<value_type> il, const allocator_type& a)\n        : set(il, Compare(), a) {}  // C++14\n    ~set();\n\n    set& operator=(const set& s);\n    set& operator=(set&& s)\n        noexcept(\n            allocator_type::propagate_on_container_move_assignment::value &&\n            is_nothrow_move_assignable<allocator_type>::value &&\n            is_nothrow_move_assignable<key_compare>::value);\n    set& operator=(initializer_list<value_type> il);\n\n    // iterators:\n          iterator begin() noexcept;\n    const_iterator begin() const noexcept;\n          iterator end() noexcept;\n    const_iterator end()   const noexcept;\n\n          reverse_iterator rbegin() noexcept;\n    const_reverse_iterator rbegin() const noexcept;\n          reverse_iterator rend() noexcept;\n    const_reverse_iterator rend()   const noexcept;\n\n    const_iterator         cbegin()  const noexcept;\n    const_iterator         cend()    const noexcept;\n    const_reverse_iterator crbegin() const noexcept;\n    const_reverse_iterator crend()   const noexcept;\n\n    // capacity:\n    bool      empty()    const noexcept;\n    size_type size()     const noexcept;\n    size_type max_size() const noexcept;\n\n    // modifiers:\n    template <class... Args>\n        pair<iterator, bool> emplace(Args&&... args);\n    template <class... Args>\n        iterator emplace_hint(const_iterator position, Args&&... args);\n    pair<iterator,bool> insert(const value_type& v);\n    pair<iterator,bool> insert(value_type&& v);\n    iterator insert(const_iterator position, const value_type& v);\n    iterator insert(const_iterator position, value_type&& v);\n    template <class InputIterator>\n        void insert(InputIterator first, InputIterator last);\n    void insert(initializer_list<value_type> il);\n\n    iterator  erase(const_iterator position);\n    iterator  erase(iterator position);  // C++14\n    size_type erase(const key_type& k);\n    iterator  erase(const_iterator first, const_iterator last);\n    void clear() noexcept;\n\n    void swap(set& s)\n        noexcept(\n            __is_nothrow_swappable<key_compare>::value &&\n            (!allocator_type::propagate_on_container_swap::value ||\n             __is_nothrow_swappable<allocator_type>::value));\n\n    // observers:\n    allocator_type get_allocator() const noexcept;\n    key_compare    key_comp()      const;\n    value_compare  value_comp()    const;\n\n    // set operations:\n          iterator find(const key_type& k);\n    const_iterator find(const key_type& k) const;\n    template<typename K>\n        iterator find(const K& x);\n    template<typename K>\n        const_iterator find(const K& x) const;  // C++14\n    template<typename K>\n      size_type count(const K& x) const;        // C++14\n\n    size_type      count(const key_type& k) const;\n          iterator lower_bound(const key_type& k);\n    const_iterator lower_bound(const key_type& k) const;\n    template<typename K>\n        iterator lower_bound(const K& x);              // C++14\n    template<typename K>\n        const_iterator lower_bound(const K& x) const;  // C++14\n\n          iterator upper_bound(const key_type& k);\n    const_iterator upper_bound(const key_type& k) const;\n    template<typename K>\n        iterator upper_bound(const K& x);              // C++14\n    template<typename K>\n        const_iterator upper_bound(const K& x) const;  // C++14\n    pair<iterator,iterator>             equal_range(const key_type& k);\n    pair<const_iterator,const_iterator> equal_range(const key_type& k) const;\n    template<typename K>\n        pair<iterator,iterator>             equal_range(const K& x);        // C++14\n    template<typename K>\n        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14\n};\n\ntemplate <class Key, class Compare, class Allocator>\nbool\noperator==(const set<Key, Compare, Allocator>& x,\n           const set<Key, Compare, Allocator>& y);\n\ntemplate <class Key, class Compare, class Allocator>\nbool\noperator< (const set<Key, Compare, Allocator>& x,\n           const set<Key, Compare, Allocator>& y);\n\ntemplate <class Key, class Compare, class Allocator>\nbool\noperator!=(const set<Key, Compare, Allocator>& x,\n           const set<Key, Compare, Allocator>& y);\n\ntemplate <class Key, class Compare, class Allocator>\nbool\noperator> (const set<Key, Compare, Allocator>& x,\n           const set<Key, Compare, Allocator>& y);\n\ntemplate <class Key, class Compare, class Allocator>\nbool\noperator>=(const set<Key, Compare, Allocator>& x,\n           const set<Key, Compare, Allocator>& y);\n\ntemplate <class Key, class Compare, class Allocator>\nbool\noperator<=(const set<Key, Compare, Allocator>& x,\n           const set<Key, Compare, Allocator>& y);\n\n// specialized algorithms:\ntemplate <class Key, class Compare, class Allocator>\nvoid\nswap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y)\n    noexcept(noexcept(x.swap(y)));\n\ntemplate <class Key, class Compare = less<Key>,\n          class Allocator = allocator<Key>>\nclass multiset\n{\npublic:\n    // types:\n    typedef Key                                      key_type;\n    typedef key_type                                 value_type;\n    typedef Compare                                  key_compare;\n    typedef key_compare                              value_compare;\n    typedef Allocator                                allocator_type;\n    typedef typename allocator_type::reference       reference;\n    typedef typename allocator_type::const_reference const_reference;\n    typedef typename allocator_type::size_type       size_type;\n    typedef typename allocator_type::difference_type difference_type;\n    typedef typename allocator_type::pointer         pointer;\n    typedef typename allocator_type::const_pointer   const_pointer;\n\n    typedef implementation-defined                   iterator;\n    typedef implementation-defined                   const_iterator;\n    typedef std::reverse_iterator<iterator>          reverse_iterator;\n    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;\n\n    // construct/copy/destroy:\n    multiset()\n        noexcept(\n            is_nothrow_default_constructible<allocator_type>::value &&\n            is_nothrow_default_constructible<key_compare>::value &&\n            is_nothrow_copy_constructible<key_compare>::value);\n    explicit multiset(const value_compare& comp);\n    multiset(const value_compare& comp, const allocator_type& a);\n    template <class InputIterator>\n        multiset(InputIterator first, InputIterator last,\n                 const value_compare& comp = value_compare());\n    template <class InputIterator>\n        multiset(InputIterator first, InputIterator last,\n                 const value_compare& comp, const allocator_type& a);\n    multiset(const multiset& s);\n    multiset(multiset&& s)\n        noexcept(\n            is_nothrow_move_constructible<allocator_type>::value &&\n            is_nothrow_move_constructible<key_compare>::value);\n    explicit multiset(const allocator_type& a);\n    multiset(const multiset& s, const allocator_type& a);\n    multiset(multiset&& s, const allocator_type& a);\n    multiset(initializer_list<value_type> il, const value_compare& comp = value_compare());\n    multiset(initializer_list<value_type> il, const value_compare& comp,\n             const allocator_type& a);\n    template <class InputIterator>\n        multiset(InputIterator first, InputIterator last, const allocator_type& a)\n            : set(first, last, Compare(), a) {}  // C++14\n    multiset(initializer_list<value_type> il, const allocator_type& a)\n        : set(il, Compare(), a) {}  // C++14\n    ~multiset();\n\n    multiset& operator=(const multiset& s);\n    multiset& operator=(multiset&& s)\n        noexcept(\n            allocator_type::propagate_on_container_move_assignment::value &&\n            is_nothrow_move_assignable<allocator_type>::value &&\n            is_nothrow_move_assignable<key_compare>::value);\n    multiset& operator=(initializer_list<value_type> il);\n\n    // iterators:\n          iterator begin() noexcept;\n    const_iterator begin() const noexcept;\n          iterator end() noexcept;\n    const_iterator end()   const noexcept;\n\n          reverse_iterator rbegin() noexcept;\n    const_reverse_iterator rbegin() const noexcept;\n          reverse_iterator rend() noexcept;\n    const_reverse_iterator rend()   const noexcept;\n\n    const_iterator         cbegin()  const noexcept;\n    const_iterator         cend()    const noexcept;\n    const_reverse_iterator crbegin() const noexcept;\n    const_reverse_iterator crend()   const noexcept;\n\n    // capacity:\n    bool      empty()    const noexcept;\n    size_type size()     const noexcept;\n    size_type max_size() const noexcept;\n\n    // modifiers:\n    template <class... Args>\n        iterator emplace(Args&&... args);\n    template <class... Args>\n        iterator emplace_hint(const_iterator position, Args&&... args);\n    iterator insert(const value_type& v);\n    iterator insert(value_type&& v);\n    iterator insert(const_iterator position, const value_type& v);\n    iterator insert(const_iterator position, value_type&& v);\n    template <class InputIterator>\n        void insert(InputIterator first, InputIterator last);\n    void insert(initializer_list<value_type> il);\n\n    iterator  erase(const_iterator position);\n    iterator  erase(iterator position);  // C++14\n    size_type erase(const key_type& k);\n    iterator  erase(const_iterator first, const_iterator last);\n    void clear() noexcept;\n\n    void swap(multiset& s)\n        noexcept(\n            __is_nothrow_swappable<key_compare>::value &&\n            (!allocator_type::propagate_on_container_swap::value ||\n             __is_nothrow_swappable<allocator_type>::value));\n\n    // observers:\n    allocator_type get_allocator() const noexcept;\n    key_compare    key_comp()      const;\n    value_compare  value_comp()    const;\n\n    // set operations:\n          iterator find(const key_type& k);\n    const_iterator find(const key_type& k) const;\n    template<typename K>\n        iterator find(const K& x);\n    template<typename K>\n        const_iterator find(const K& x) const;  // C++14\n\n    size_type      count(const key_type& k) const;\n          iterator lower_bound(const key_type& k);\n    const_iterator lower_bound(const key_type& k) const;\n    template<typename K>\n        iterator lower_bound(const K& x);              // C++14\n    template<typename K>\n        const_iterator lower_bound(const K& x) const;  // C++14\n\n          iterator upper_bound(const key_type& k);\n    const_iterator upper_bound(const key_type& k) const;\n    template<typename K>\n        iterator upper_bound(const K& x);              // C++14\n    template<typename K>\n        const_iterator upper_bound(const K& x) const;  // C++14\n\n    pair<iterator,iterator>             equal_range(const key_type& k);\n    pair<const_iterator,const_iterator> equal_range(const key_type& k) const;\n    template<typename K>\n        pair<iterator,iterator>             equal_range(const K& x);        // C++14\n    template<typename K>\n        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14\n};\n\ntemplate <class Key, class Compare, class Allocator>\nbool\noperator==(const multiset<Key, Compare, Allocator>& x,\n           const multiset<Key, Compare, Allocator>& y);\n\ntemplate <class Key, class Compare, class Allocator>\nbool\noperator< (const multiset<Key, Compare, Allocator>& x,\n           const multiset<Key, Compare, Allocator>& y);\n\ntemplate <class Key, class Compare, class Allocator>\nbool\noperator!=(const multiset<Key, Compare, Allocator>& x,\n           const multiset<Key, Compare, Allocator>& y);\n\ntemplate <class Key, class Compare, class Allocator>\nbool\noperator> (const multiset<Key, Compare, Allocator>& x,\n           const multiset<Key, Compare, Allocator>& y);\n\ntemplate <class Key, class Compare, class Allocator>\nbool\noperator>=(const multiset<Key, Compare, Allocator>& x,\n           const multiset<Key, Compare, Allocator>& y);\n\ntemplate <class Key, class Compare, class Allocator>\nbool\noperator<=(const multiset<Key, Compare, Allocator>& x,\n           const multiset<Key, Compare, Allocator>& y);\n\n// specialized algorithms:\ntemplate <class Key, class Compare, class Allocator>\nvoid\nswap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)\n    noexcept(noexcept(x.swap(y)));\n\n}  // std\n\n*/\n\n#include <__config>\n#include <__tree>\n#include <functional>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Key, class _Compare = less<_Key>,\n          class _Allocator = allocator<_Key> >\nclass _LIBCPP_TYPE_VIS_ONLY set\n{\npublic:\n    // types:\n    typedef _Key                                     key_type;\n    typedef key_type                                 value_type;\n    typedef _Compare                                 key_compare;\n    typedef key_compare                              value_compare;\n    typedef _Allocator                               allocator_type;\n    typedef value_type&                              reference;\n    typedef const value_type&                        const_reference;\n\nprivate:\n    typedef __tree<value_type, value_compare, allocator_type> __base;\n    typedef allocator_traits<allocator_type>                  __alloc_traits;\n    typedef typename __base::__node_holder                    __node_holder;\n\n    __base __tree_;\n\npublic:\n    typedef typename __base::pointer               pointer;\n    typedef typename __base::const_pointer         const_pointer;\n    typedef typename __base::size_type             size_type;\n    typedef typename __base::difference_type       difference_type;\n    typedef typename __base::const_iterator        iterator;\n    typedef typename __base::const_iterator        const_iterator;\n    typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;\n    typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY\n    set()\n        _NOEXCEPT_(\n            is_nothrow_default_constructible<allocator_type>::value &&\n            is_nothrow_default_constructible<key_compare>::value &&\n            is_nothrow_copy_constructible<key_compare>::value)\n        : __tree_(value_compare()) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit set(const value_compare& __comp)\n        _NOEXCEPT_(\n            is_nothrow_default_constructible<allocator_type>::value &&\n            is_nothrow_copy_constructible<key_compare>::value)\n        : __tree_(__comp) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit set(const value_compare& __comp, const allocator_type& __a)\n        : __tree_(__comp, __a) {}\n    template <class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        set(_InputIterator __f, _InputIterator __l,\n            const value_compare& __comp = value_compare())\n        : __tree_(__comp)\n        {\n            insert(__f, __l);\n        }\n\n    template <class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        set(_InputIterator __f, _InputIterator __l, const value_compare& __comp,\n            const allocator_type& __a)\n        : __tree_(__comp, __a)\n        {\n            insert(__f, __l);\n        }\n\n#if _LIBCPP_STD_VER > 11\n        template <class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY \n        set(_InputIterator __f, _InputIterator __l, const allocator_type& __a)\n            : set(__f, __l, key_compare(), __a) {}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    set(const set& __s)\n        : __tree_(__s.__tree_)\n        {\n            insert(__s.begin(), __s.end());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    set& operator=(const set& __s)\n        {\n            __tree_ = __s.__tree_;\n            return *this;\n        }\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    set(set&& __s)\n        _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)\n        : __tree_(_VSTD::move(__s.__tree_)) {}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit set(const allocator_type& __a)\n        : __tree_(__a) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    set(const set& __s, const allocator_type& __a)\n        : __tree_(__s.__tree_.value_comp(), __a)\n        {\n            insert(__s.begin(), __s.end());\n        }\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    set(set&& __s, const allocator_type& __a);\n#endif\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    set(initializer_list<value_type> __il, const value_compare& __comp = value_compare())\n        : __tree_(__comp)\n        {\n            insert(__il.begin(), __il.end());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    set(initializer_list<value_type> __il, const value_compare& __comp,\n        const allocator_type& __a)\n        : __tree_(__comp, __a)\n        {\n            insert(__il.begin(), __il.end());\n        }\n\n#if _LIBCPP_STD_VER > 11\n    _LIBCPP_INLINE_VISIBILITY \n    set(initializer_list<value_type> __il, const allocator_type& __a)\n        : set(__il, key_compare(), __a) {}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    set& operator=(initializer_list<value_type> __il)\n        {\n            __tree_.__assign_unique(__il.begin(), __il.end());\n            return *this;\n        }\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    set& operator=(set&& __s)\n        _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)\n        {\n            __tree_ = _VSTD::move(__s.__tree_);\n            return *this;\n        }\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n          iterator begin() _NOEXCEPT       {return __tree_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin() const _NOEXCEPT {return __tree_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n          iterator end() _NOEXCEPT         {return __tree_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end()   const _NOEXCEPT {return __tree_.end();}\n\n    _LIBCPP_INLINE_VISIBILITY\n          reverse_iterator rbegin() _NOEXCEPT\n            {return reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rbegin() const _NOEXCEPT\n        {return const_reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n          reverse_iterator rend() _NOEXCEPT\n            {return reverse_iterator(begin());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rend() const _NOEXCEPT\n        {return const_reverse_iterator(begin());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cbegin()  const _NOEXCEPT {return begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cend() const _NOEXCEPT {return end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crend() const _NOEXCEPT {return rend();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool empty() const _NOEXCEPT {return __tree_.size() == 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const _NOEXCEPT {return __tree_.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const _NOEXCEPT {return __tree_.max_size();}\n\n    // modifiers:\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        pair<iterator, bool> emplace(_Args&&... __args)\n            {return __tree_.__emplace_unique(_VSTD::forward<_Args>(__args)...);}\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator emplace_hint(const_iterator __p, _Args&&... __args)\n            {return __tree_.__emplace_hint_unique(__p, _VSTD::forward<_Args>(__args)...);}\n#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator,bool> insert(const value_type& __v)\n        {return __tree_.__insert_unique(__v);}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator,bool> insert(value_type&& __v)\n        {return __tree_.__insert_unique(_VSTD::move(__v));}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator __p, const value_type& __v)\n        {return __tree_.__insert_unique(__p, __v);}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator __p, value_type&& __v)\n        {return __tree_.__insert_unique(__p, _VSTD::move(__v));}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        void insert(_InputIterator __f, _InputIterator __l)\n        {\n            for (const_iterator __e = cend(); __f != __l; ++__f)\n                __tree_.__insert_unique(__e, *__f);\n        }\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    void insert(initializer_list<value_type> __il)\n        {insert(__il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator  erase(const_iterator __p) {return __tree_.erase(__p);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type erase(const key_type& __k)\n        {return __tree_.__erase_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator  erase(const_iterator __f, const_iterator __l)\n        {return __tree_.erase(__f, __l);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() _NOEXCEPT {__tree_.clear();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(set& __s) _NOEXCEPT_(__is_nothrow_swappable<__base>::value)\n        {__tree_.swap(__s.__tree_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();}\n    _LIBCPP_INLINE_VISIBILITY\n    key_compare    key_comp()      const {return __tree_.value_comp();}\n    _LIBCPP_INLINE_VISIBILITY\n    value_compare  value_comp()    const {return __tree_.value_comp();}\n\n    // set operations:\n    _LIBCPP_INLINE_VISIBILITY\n    iterator find(const key_type& __k)             {return __tree_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator find(const key_type& __k) const {return __tree_.find(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type\n    find(const _K2& __k)                           {return __tree_.find(__k);}\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type\n    find(const _K2& __k) const                     {return __tree_.find(__k);}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type      count(const key_type& __k) const\n        {return __tree_.__count_unique(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type\n    count(const _K2& __k)                  {return __tree_.__count_unique(__k);}\n#endif\n    _LIBCPP_INLINE_VISIBILITY\n    iterator lower_bound(const key_type& __k)\n        {return __tree_.lower_bound(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator lower_bound(const key_type& __k) const\n        {return __tree_.lower_bound(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type\n    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}\n\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type\n    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator upper_bound(const key_type& __k)\n        {return __tree_.upper_bound(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator upper_bound(const key_type& __k) const\n        {return __tree_.upper_bound(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type\n    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type\n    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator,iterator> equal_range(const key_type& __k)\n        {return __tree_.__equal_range_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<const_iterator,const_iterator> equal_range(const key_type& __k) const\n        {return __tree_.__equal_range_unique(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type\n    equal_range(const _K2& __k)       {return __tree_.__equal_range_unique(__k);}\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type\n    equal_range(const _K2& __k) const {return __tree_.__equal_range_unique(__k);}\n#endif\n};\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Compare, class _Allocator>\nset<_Key, _Compare, _Allocator>::set(set&& __s, const allocator_type& __a)\n    : __tree_(_VSTD::move(__s.__tree_), __a)\n{\n    if (__a != __s.get_allocator())\n    {\n        const_iterator __e = cend();\n        while (!__s.empty())\n            insert(__e, _VSTD::move(__s.__tree_.remove(__s.begin())->__value_));\n    }\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const set<_Key, _Compare, _Allocator>& __x,\n           const set<_Key, _Compare, _Allocator>& __y)\n{\n    return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());\n}\n\ntemplate <class _Key, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const set<_Key, _Compare, _Allocator>& __x,\n           const set<_Key, _Compare, _Allocator>& __y)\n{\n    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());\n}\n\ntemplate <class _Key, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const set<_Key, _Compare, _Allocator>& __x,\n           const set<_Key, _Compare, _Allocator>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Key, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator> (const set<_Key, _Compare, _Allocator>& __x,\n           const set<_Key, _Compare, _Allocator>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _Key, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const set<_Key, _Compare, _Allocator>& __x,\n           const set<_Key, _Compare, _Allocator>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _Key, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const set<_Key, _Compare, _Allocator>& __x,\n           const set<_Key, _Compare, _Allocator>& __y)\n{\n    return !(__y < __x);\n}\n\n// specialized algorithms:\ntemplate <class _Key, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(set<_Key, _Compare, _Allocator>& __x,\n     set<_Key, _Compare, _Allocator>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Key, class _Compare = less<_Key>,\n          class _Allocator = allocator<_Key> >\nclass _LIBCPP_TYPE_VIS_ONLY multiset\n{\npublic:\n    // types:\n    typedef _Key                                      key_type;\n    typedef key_type                                 value_type;\n    typedef _Compare                                  key_compare;\n    typedef key_compare                              value_compare;\n    typedef _Allocator                                allocator_type;\n    typedef value_type&                              reference;\n    typedef const value_type&                        const_reference;\n\nprivate:\n    typedef __tree<value_type, value_compare, allocator_type> __base;\n    typedef allocator_traits<allocator_type>                  __alloc_traits;\n    typedef typename __base::__node_holder                    __node_holder;\n\n    __base __tree_;\n\npublic:\n    typedef typename __base::pointer               pointer;\n    typedef typename __base::const_pointer         const_pointer;\n    typedef typename __base::size_type             size_type;\n    typedef typename __base::difference_type       difference_type;\n    typedef typename __base::const_iterator        iterator;\n    typedef typename __base::const_iterator        const_iterator;\n    typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;\n    typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;\n\n    // construct/copy/destroy:\n    _LIBCPP_INLINE_VISIBILITY\n    multiset()\n        _NOEXCEPT_(\n            is_nothrow_default_constructible<allocator_type>::value &&\n            is_nothrow_default_constructible<key_compare>::value &&\n            is_nothrow_copy_constructible<key_compare>::value)\n        : __tree_(value_compare()) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit multiset(const value_compare& __comp)\n        _NOEXCEPT_(\n            is_nothrow_default_constructible<allocator_type>::value &&\n            is_nothrow_copy_constructible<key_compare>::value)\n        : __tree_(__comp) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit multiset(const value_compare& __comp, const allocator_type& __a)\n        : __tree_(__comp, __a) {}\n    template <class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        multiset(_InputIterator __f, _InputIterator __l,\n                 const value_compare& __comp = value_compare())\n        : __tree_(__comp)\n        {\n            insert(__f, __l);\n        }\n\n#if _LIBCPP_STD_VER > 11\n        template <class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY \n        multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a)\n            : multiset(__f, __l, key_compare(), __a) {}\n#endif\n\n    template <class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        multiset(_InputIterator __f, _InputIterator __l,\n                 const value_compare& __comp, const allocator_type& __a)\n        : __tree_(__comp, __a)\n        {\n            insert(__f, __l);\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    multiset(const multiset& __s)\n        : __tree_(__s.__tree_.value_comp(),\n          __alloc_traits::select_on_container_copy_construction(__s.__tree_.__alloc()))\n        {\n            insert(__s.begin(), __s.end());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    multiset& operator=(const multiset& __s)\n        {\n            __tree_ = __s.__tree_;\n            return *this;\n        }\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    multiset(multiset&& __s)\n        _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)\n        : __tree_(_VSTD::move(__s.__tree_)) {}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    explicit multiset(const allocator_type& __a)\n        : __tree_(__a) {}\n    _LIBCPP_INLINE_VISIBILITY\n    multiset(const multiset& __s, const allocator_type& __a)\n        : __tree_(__s.__tree_.value_comp(), __a)\n        {\n            insert(__s.begin(), __s.end());\n        }\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    multiset(multiset&& __s, const allocator_type& __a);\n#endif\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    multiset(initializer_list<value_type> __il, const value_compare& __comp = value_compare())\n        : __tree_(__comp)\n        {\n            insert(__il.begin(), __il.end());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    multiset(initializer_list<value_type> __il, const value_compare& __comp,\n        const allocator_type& __a)\n        : __tree_(__comp, __a)\n        {\n            insert(__il.begin(), __il.end());\n        }\n\n#if _LIBCPP_STD_VER > 11\n    _LIBCPP_INLINE_VISIBILITY \n    multiset(initializer_list<value_type> __il, const allocator_type& __a)\n        : multiset(__il, key_compare(), __a) {}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    multiset& operator=(initializer_list<value_type> __il)\n        {\n            __tree_.__assign_multi(__il.begin(), __il.end());\n            return *this;\n        }\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    multiset& operator=(multiset&& __s)\n        _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)\n        {\n            __tree_ = _VSTD::move(__s.__tree_);\n            return *this;\n        }\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n          iterator begin() _NOEXCEPT       {return __tree_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin() const _NOEXCEPT {return __tree_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n          iterator end() _NOEXCEPT         {return __tree_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end()   const _NOEXCEPT {return __tree_.end();}\n\n    _LIBCPP_INLINE_VISIBILITY\n          reverse_iterator rbegin() _NOEXCEPT\n            {return reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rbegin() const _NOEXCEPT\n        {return const_reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n          reverse_iterator rend() _NOEXCEPT\n            {return       reverse_iterator(begin());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rend() const _NOEXCEPT\n        {return const_reverse_iterator(begin());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cbegin()  const _NOEXCEPT {return begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cend() const _NOEXCEPT {return end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crend() const _NOEXCEPT {return rend();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool empty() const _NOEXCEPT {return __tree_.size() == 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const _NOEXCEPT {return __tree_.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const _NOEXCEPT {return __tree_.max_size();}\n\n    // modifiers:\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator emplace(_Args&&... __args)\n            {return __tree_.__emplace_multi(_VSTD::forward<_Args>(__args)...);}\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator emplace_hint(const_iterator __p, _Args&&... __args)\n            {return __tree_.__emplace_hint_multi(__p, _VSTD::forward<_Args>(__args)...);}\n#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const value_type& __v)\n        {return __tree_.__insert_multi(__v);}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(value_type&& __v)\n        {return __tree_.__insert_multi(_VSTD::move(__v));}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator __p, const value_type& __v)\n        {return __tree_.__insert_multi(__p, __v);}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator __p, value_type&& __v)\n        {return __tree_.__insert_multi(_VSTD::move(__v));}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        void insert(_InputIterator __f, _InputIterator __l)\n        {\n            for (const_iterator __e = cend(); __f != __l; ++__f)\n                __tree_.__insert_multi(__e, *__f);\n        }\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    void insert(initializer_list<value_type> __il)\n        {insert(__il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator  erase(const_iterator __p) {return __tree_.erase(__p);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator  erase(const_iterator __f, const_iterator __l)\n        {return __tree_.erase(__f, __l);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() _NOEXCEPT {__tree_.clear();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(multiset& __s)\n        _NOEXCEPT_(__is_nothrow_swappable<__base>::value)\n        {__tree_.swap(__s.__tree_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();}\n    _LIBCPP_INLINE_VISIBILITY\n    key_compare    key_comp()      const {return __tree_.value_comp();}\n    _LIBCPP_INLINE_VISIBILITY\n    value_compare  value_comp()    const {return __tree_.value_comp();}\n\n    // set operations:\n    _LIBCPP_INLINE_VISIBILITY\n    iterator find(const key_type& __k)             {return __tree_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator find(const key_type& __k) const {return __tree_.find(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type\n    find(const _K2& __k)                           {return __tree_.find(__k);}\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type\n    find(const _K2& __k) const                     {return __tree_.find(__k);}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type      count(const key_type& __k) const\n        {return __tree_.__count_multi(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type\n    count(const _K2& __k)                  {return __tree_.__count_multi(__k);}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator lower_bound(const key_type& __k)\n        {return __tree_.lower_bound(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator lower_bound(const key_type& __k) const\n            {return __tree_.lower_bound(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type\n    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}\n\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type\n    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator upper_bound(const key_type& __k)\n            {return __tree_.upper_bound(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator upper_bound(const key_type& __k) const\n            {return __tree_.upper_bound(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type\n    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type\n    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator,iterator>             equal_range(const key_type& __k)\n            {return __tree_.__equal_range_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<const_iterator,const_iterator> equal_range(const key_type& __k) const\n            {return __tree_.__equal_range_multi(__k);}\n#if _LIBCPP_STD_VER > 11\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type\n    equal_range(const _K2& __k)       {return __tree_.__equal_range_multi(__k);}\n    template <typename _K2>\n    _LIBCPP_INLINE_VISIBILITY\n    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type\n    equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}\n#endif\n};\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Compare, class _Allocator>\nmultiset<_Key, _Compare, _Allocator>::multiset(multiset&& __s, const allocator_type& __a)\n    : __tree_(_VSTD::move(__s.__tree_), __a)\n{\n    if (__a != __s.get_allocator())\n    {\n        const_iterator __e = cend();\n        while (!__s.empty())\n            insert(__e, _VSTD::move(__s.__tree_.remove(__s.begin())->__value_));\n    }\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const multiset<_Key, _Compare, _Allocator>& __x,\n           const multiset<_Key, _Compare, _Allocator>& __y)\n{\n    return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());\n}\n\ntemplate <class _Key, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const multiset<_Key, _Compare, _Allocator>& __x,\n           const multiset<_Key, _Compare, _Allocator>& __y)\n{\n    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());\n}\n\ntemplate <class _Key, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const multiset<_Key, _Compare, _Allocator>& __x,\n           const multiset<_Key, _Compare, _Allocator>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Key, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator> (const multiset<_Key, _Compare, _Allocator>& __x,\n           const multiset<_Key, _Compare, _Allocator>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _Key, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const multiset<_Key, _Compare, _Allocator>& __x,\n           const multiset<_Key, _Compare, _Allocator>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _Key, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const multiset<_Key, _Compare, _Allocator>& __x,\n           const multiset<_Key, _Compare, _Allocator>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _Key, class _Compare, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(multiset<_Key, _Compare, _Allocator>& __x,\n     multiset<_Key, _Compare, _Allocator>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_SET\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/shared_mutex",
    "content": "// -*- C++ -*-\n//===------------------------ shared_mutex --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SHARED_MUTEX\n#define _LIBCPP_SHARED_MUTEX\n\n/*\n    shared_mutex synopsis\n\n// C++1y\n\nnamespace std\n{\n\nclass shared_mutex      // C++17\n{\npublic:\n    shared_mutex();\n    ~shared_mutex();\n\n    shared_mutex(const shared_mutex&) = delete;\n    shared_mutex& operator=(const shared_mutex&) = delete;\n\n    // Exclusive ownership\n    void lock(); // blocking\n    bool try_lock();\n    void unlock();\n\n    // Shared ownership\n    void lock_shared(); // blocking\n    bool try_lock_shared();\n    void unlock_shared();\n\n    typedef implementation-defined native_handle_type; // See 30.2.3\n    native_handle_type native_handle(); // See 30.2.3\n};\n\nclass shared_timed_mutex\n{\npublic:\n    shared_timed_mutex();\n    ~shared_timed_mutex();\n\n    shared_timed_mutex(const shared_timed_mutex&) = delete;\n    shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;\n\n    // Exclusive ownership\n    void lock(); // blocking\n    bool try_lock();\n    template <class Rep, class Period>\n        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);\n    template <class Clock, class Duration>\n        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);\n    void unlock();\n\n    // Shared ownership\n    void lock_shared(); // blocking\n    bool try_lock_shared();\n    template <class Rep, class Period>\n        bool\n        try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);\n    template <class Clock, class Duration>\n        bool\n        try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);\n    void unlock_shared();\n};\n\ntemplate <class Mutex>\nclass shared_lock\n{\npublic:\n    typedef Mutex mutex_type;\n\n    // Shared locking\n    shared_lock() noexcept;\n    explicit shared_lock(mutex_type& m); // blocking\n    shared_lock(mutex_type& m, defer_lock_t) noexcept;\n    shared_lock(mutex_type& m, try_to_lock_t);\n    shared_lock(mutex_type& m, adopt_lock_t);\n    template <class Clock, class Duration>\n        shared_lock(mutex_type& m,\n                    const chrono::time_point<Clock, Duration>& abs_time);\n    template <class Rep, class Period>\n        shared_lock(mutex_type& m,\n                    const chrono::duration<Rep, Period>& rel_time);\n    ~shared_lock();\n\n    shared_lock(shared_lock const&) = delete;\n    shared_lock& operator=(shared_lock const&) = delete;\n\n    shared_lock(shared_lock&& u) noexcept;\n    shared_lock& operator=(shared_lock&& u) noexcept;\n\n    void lock(); // blocking\n    bool try_lock();\n    template <class Rep, class Period>\n        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);\n    template <class Clock, class Duration>\n        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);\n    void unlock();\n\n    // Setters\n    void swap(shared_lock& u) noexcept;\n    mutex_type* release() noexcept;\n\n    // Getters\n    bool owns_lock() const noexcept;\n    explicit operator bool () const noexcept;\n    mutex_type* mutex() const noexcept;\n};\n\ntemplate <class Mutex>\n    void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;\n\n}  // std\n\n*/\n\n#include <__config>\n\n#if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_SHARED_MUTEX)\n\n#include <__mutex_base>\n\n#include <__undef_min_max>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#ifdef _LIBCPP_HAS_NO_THREADS\n#error <shared_mutex> is not supported on this single threaded system\n#else // !_LIBCPP_HAS_NO_THREADS\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nstruct _LIBCPP_TYPE_VIS __shared_mutex_base\n{\n    mutex               __mut_;\n    condition_variable  __gate1_;\n    condition_variable  __gate2_;\n    unsigned            __state_;\n\n    static const unsigned __write_entered_ = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1);\n    static const unsigned __n_readers_ = ~__write_entered_;\n\n    __shared_mutex_base();\n    _LIBCPP_INLINE_VISIBILITY ~__shared_mutex_base() = default;\n\n    __shared_mutex_base(const __shared_mutex_base&) = delete;\n    __shared_mutex_base& operator=(const __shared_mutex_base&) = delete;\n\n    // Exclusive ownership\n    void lock(); // blocking\n    bool try_lock();\n    void unlock();\n\n    // Shared ownership\n    void lock_shared(); // blocking\n    bool try_lock_shared();\n    void unlock_shared();\n\n//     typedef implementation-defined native_handle_type; // See 30.2.3\n//     native_handle_type native_handle(); // See 30.2.3\n};\n\n\n#if _LIBCPP_STD_VER > 14\nclass _LIBCPP_TYPE_VIS shared_mutex\n{\n\t__shared_mutex_base __base;\npublic:\n    shared_mutex() : __base() {}\n    _LIBCPP_INLINE_VISIBILITY ~shared_mutex() = default;\n\n    shared_mutex(const shared_mutex&) = delete;\n    shared_mutex& operator=(const shared_mutex&) = delete;\n\n    // Exclusive ownership\n    _LIBCPP_INLINE_VISIBILITY void lock()     { return __base.lock(); }\n    _LIBCPP_INLINE_VISIBILITY bool try_lock() { return __base.try_lock(); }\n    _LIBCPP_INLINE_VISIBILITY void unlock()   { return __base.unlock(); }\n\n    // Shared ownership\n    _LIBCPP_INLINE_VISIBILITY void lock_shared()     { return __base.lock_shared(); }\n    _LIBCPP_INLINE_VISIBILITY bool try_lock_shared() { return __base.try_lock_shared(); }\n    _LIBCPP_INLINE_VISIBILITY void unlock_shared()   { return __base.unlock_shared(); }\n\n//     typedef __shared_mutex_base::native_handle_type native_handle_type;\n//     _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() { return __base::unlock_shared(); }\n};\n#endif\n\n\nclass _LIBCPP_TYPE_VIS shared_timed_mutex\n{\n\t__shared_mutex_base __base;\npublic:\n    shared_timed_mutex();\n    _LIBCPP_INLINE_VISIBILITY ~shared_timed_mutex() = default;\n\n    shared_timed_mutex(const shared_timed_mutex&) = delete;\n    shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;\n\n    // Exclusive ownership\n    void lock();\n    bool try_lock();\n    template <class _Rep, class _Period>\n        _LIBCPP_INLINE_VISIBILITY\n        bool\n        try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time)\n        {\n            return try_lock_until(chrono::steady_clock::now() + __rel_time);\n        }\n    template <class _Clock, class _Duration>\n        bool\n        try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time);\n    void unlock();\n\n    // Shared ownership\n    void lock_shared();\n    bool try_lock_shared();\n    template <class _Rep, class _Period>\n        _LIBCPP_INLINE_VISIBILITY\n        bool\n        try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time)\n        {\n            return try_lock_shared_until(chrono::steady_clock::now() + __rel_time);\n        }\n    template <class _Clock, class _Duration>\n        bool\n        try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time);\n    void unlock_shared();\n};\n\ntemplate <class _Clock, class _Duration>\nbool\nshared_timed_mutex::try_lock_until(\n                        const chrono::time_point<_Clock, _Duration>& __abs_time)\n{\n    unique_lock<mutex> __lk(__base.__mut_);\n    if (__base.__state_ & __base.__write_entered_)\n    {\n        while (true)\n        {\n            cv_status __status = __base.__gate1_.wait_until(__lk, __abs_time);\n            if ((__base.__state_ & __base.__write_entered_) == 0)\n                break;\n            if (__status == cv_status::timeout)\n                return false;\n        }\n    }\n    __base.__state_ |= __base.__write_entered_;\n    if (__base.__state_ & __base.__n_readers_)\n    {\n        while (true)\n        {\n            cv_status __status = __base.__gate2_.wait_until(__lk, __abs_time);\n            if ((__base.__state_ & __base.__n_readers_) == 0)\n                break;\n            if (__status == cv_status::timeout)\n            {\n                __base.__state_ &= ~__base.__write_entered_;\n                __base.__gate1_.notify_all();\n                return false;\n            }\n        }\n    }\n    return true;\n}\n\ntemplate <class _Clock, class _Duration>\nbool\nshared_timed_mutex::try_lock_shared_until(\n                        const chrono::time_point<_Clock, _Duration>& __abs_time)\n{\n    unique_lock<mutex> __lk(__base.__mut_);\n    if ((__base.__state_ & __base.__write_entered_) || (__base.__state_ & __base.__n_readers_) == __base.__n_readers_)\n    {\n        while (true)\n        {\n            cv_status status = __base.__gate1_.wait_until(__lk, __abs_time);\n            if ((__base.__state_ & __base.__write_entered_) == 0 &&\n                                       (__base.__state_ & __base.__n_readers_) < __base.__n_readers_)\n                break;\n            if (status == cv_status::timeout)\n                return false;\n        }\n    }\n    unsigned __num_readers = (__base.__state_ & __base.__n_readers_) + 1;\n    __base.__state_ &= ~__base.__n_readers_;\n    __base.__state_ |= __num_readers;\n    return true;\n}\n\ntemplate <class _Mutex>\nclass shared_lock\n{\npublic:\n    typedef _Mutex mutex_type;\n\nprivate:\n    mutex_type* __m_;\n    bool __owns_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    shared_lock() _NOEXCEPT\n        : __m_(nullptr),\n          __owns_(false)\n        {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit shared_lock(mutex_type& __m)\n        : __m_(&__m),\n          __owns_(true)\n        {__m_->lock_shared();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    shared_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT\n        : __m_(&__m),\n          __owns_(false)\n        {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    shared_lock(mutex_type& __m, try_to_lock_t)\n        : __m_(&__m),\n          __owns_(__m.try_lock_shared())\n        {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    shared_lock(mutex_type& __m, adopt_lock_t)\n        : __m_(&__m),\n          __owns_(true)\n        {}\n\n    template <class _Clock, class _Duration>\n        _LIBCPP_INLINE_VISIBILITY\n        shared_lock(mutex_type& __m,\n                    const chrono::time_point<_Clock, _Duration>& __abs_time)\n            : __m_(&__m),\n              __owns_(__m.try_lock_shared_until(__abs_time))\n            {}\n\n    template <class _Rep, class _Period>\n        _LIBCPP_INLINE_VISIBILITY\n        shared_lock(mutex_type& __m,\n                    const chrono::duration<_Rep, _Period>& __rel_time)\n            : __m_(&__m),\n              __owns_(__m.try_lock_shared_for(__rel_time))\n            {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    ~shared_lock()\n    {\n        if (__owns_)\n            __m_->unlock_shared();\n    }\n\n    shared_lock(shared_lock const&) = delete;\n    shared_lock& operator=(shared_lock const&) = delete;\n\n    _LIBCPP_INLINE_VISIBILITY\n    shared_lock(shared_lock&& __u) _NOEXCEPT\n        : __m_(__u.__m_),\n          __owns_(__u.__owns_)\n        {\n            __u.__m_ = nullptr;\n            __u.__owns_ = false;\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    shared_lock& operator=(shared_lock&& __u) _NOEXCEPT\n    {\n        if (__owns_)\n            __m_->unlock_shared();\n        __m_ = nullptr;\n        __owns_ = false;\n        __m_ = __u.__m_;\n        __owns_ = __u.__owns_;\n        __u.__m_ = nullptr;\n        __u.__owns_ = false;\n        return *this;\n    }\n\n    void lock();\n    bool try_lock();\n    template <class Rep, class Period>\n        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);\n    template <class Clock, class Duration>\n        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);\n    void unlock();\n\n    // Setters\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(shared_lock& __u) _NOEXCEPT\n    {\n        _VSTD::swap(__m_, __u.__m_);\n        _VSTD::swap(__owns_, __u.__owns_);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    mutex_type* release() _NOEXCEPT\n    {\n        mutex_type* __m = __m_;\n        __m_ = nullptr;\n        __owns_ = false;\n        return __m;\n    }\n\n    // Getters\n    _LIBCPP_INLINE_VISIBILITY\n    bool owns_lock() const _NOEXCEPT {return __owns_;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit operator bool () const _NOEXCEPT {return __owns_;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    mutex_type* mutex() const _NOEXCEPT {return __m_;}\n};\n\ntemplate <class _Mutex>\nvoid\nshared_lock<_Mutex>::lock()\n{\n    if (__m_ == nullptr)\n        __throw_system_error(EPERM, \"shared_lock::lock: references null mutex\");\n    if (__owns_)\n        __throw_system_error(EDEADLK, \"shared_lock::lock: already locked\");\n    __m_->lock_shared();\n    __owns_ = true;\n}\n\ntemplate <class _Mutex>\nbool\nshared_lock<_Mutex>::try_lock()\n{\n    if (__m_ == nullptr)\n        __throw_system_error(EPERM, \"shared_lock::try_lock: references null mutex\");\n    if (__owns_)\n        __throw_system_error(EDEADLK, \"shared_lock::try_lock: already locked\");\n    __owns_ = __m_->try_lock_shared();\n    return __owns_;\n}\n\ntemplate <class _Mutex>\ntemplate <class _Rep, class _Period>\nbool\nshared_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d)\n{\n    if (__m_ == nullptr)\n        __throw_system_error(EPERM, \"shared_lock::try_lock_for: references null mutex\");\n    if (__owns_)\n        __throw_system_error(EDEADLK, \"shared_lock::try_lock_for: already locked\");\n    __owns_ = __m_->try_lock_shared_for(__d);\n    return __owns_;\n}\n\ntemplate <class _Mutex>\ntemplate <class _Clock, class _Duration>\nbool\nshared_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)\n{\n    if (__m_ == nullptr)\n        __throw_system_error(EPERM, \"shared_lock::try_lock_until: references null mutex\");\n    if (__owns_)\n        __throw_system_error(EDEADLK, \"shared_lock::try_lock_until: already locked\");\n    __owns_ = __m_->try_lock_shared_until(__t);\n    return __owns_;\n}\n\ntemplate <class _Mutex>\nvoid\nshared_lock<_Mutex>::unlock()\n{\n    if (!__owns_)\n        __throw_system_error(EPERM, \"shared_lock::unlock: not locked\");\n    __m_->unlock_shared();\n    __owns_ = false;\n}\n\ntemplate <class _Mutex>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) _NOEXCEPT\n    {__x.swap(__y);}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // !_LIBCPP_HAS_NO_THREADS\n\n#endif  // _LIBCPP_STD_VER > 11\n\n#endif  // _LIBCPP_SHARED_MUTEX\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/sstream",
    "content": "// -*- C++ -*-\n//===--------------------------- sstream ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SSTREAM\n#define _LIBCPP_SSTREAM\n\n/*\n    sstream synopsis\n\ntemplate <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >\nclass basic_stringbuf\n    : public basic_streambuf<charT, traits>\n{\npublic:\n    typedef charT                          char_type;\n    typedef traits                         traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n    typedef Allocator                      allocator_type;\n\n    // 27.8.1.1 Constructors:\n    explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out);\n    explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& str,\n                             ios_base::openmode which = ios_base::in | ios_base::out);\n    basic_stringbuf(basic_stringbuf&& rhs);\n\n    // 27.8.1.2 Assign and swap:\n    basic_stringbuf& operator=(basic_stringbuf&& rhs);\n    void swap(basic_stringbuf& rhs);\n\n    // 27.8.1.3 Get and set:\n    basic_string<char_type, traits_type, allocator_type> str() const;\n    void str(const basic_string<char_type, traits_type, allocator_type>& s);\n\nprotected:\n    // 27.8.1.4 Overridden virtual functions:\n    virtual int_type underflow();\n    virtual int_type pbackfail(int_type c = traits_type::eof());\n    virtual int_type overflow (int_type c = traits_type::eof());\n    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type*, streamsize);\n    virtual pos_type seekoff(off_type off, ios_base::seekdir way,\n                             ios_base::openmode which = ios_base::in | ios_base::out);\n    virtual pos_type seekpos(pos_type sp,\n                             ios_base::openmode which = ios_base::in | ios_base::out);\n};\n\ntemplate <class charT, class traits, class Allocator>\n  void swap(basic_stringbuf<charT, traits, Allocator>& x,\n            basic_stringbuf<charT, traits, Allocator>& y);\n\ntypedef basic_stringbuf<char>    stringbuf;\ntypedef basic_stringbuf<wchar_t> wstringbuf;\n\ntemplate <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >\nclass basic_istringstream\n    : public basic_istream<charT, traits>\n{\npublic:\n    typedef charT                          char_type;\n    typedef traits                         traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n    typedef Allocator                      allocator_type;\n\n    // 27.8.2.1 Constructors:\n    explicit basic_istringstream(ios_base::openmode which = ios_base::in);\n    explicit basic_istringstream(const basic_string<char_type, traits_type,allocator_type>& str,\n                                 ios_base::openmode which = ios_base::in);\n    basic_istringstream(basic_istringstream&& rhs);\n\n    // 27.8.2.2 Assign and swap:\n    basic_istringstream& operator=(basic_istringstream&& rhs);\n    void swap(basic_istringstream& rhs);\n\n    // 27.8.2.3 Members:\n    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;\n    basic_string<char_type, traits_type, allocator_type> str() const;\n    void str(const basic_string<char_type, traits_type, allocator_type>& s);\n};\n\ntemplate <class charT, class traits, class Allocator>\n  void swap(basic_istringstream<charT, traits, Allocator>& x,\n            basic_istringstream<charT, traits, Allocator>& y);\n\ntypedef basic_istringstream<char>    istringstream;\ntypedef basic_istringstream<wchar_t> wistringstream;\n\ntemplate <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >\nclass basic_ostringstream\n    : public basic_ostream<charT, traits>\n{\npublic:\n    // types:\n    typedef charT                          char_type;\n    typedef traits                         traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n    typedef Allocator                      allocator_type;\n\n    // 27.8.3.1 Constructors/destructor:\n    explicit basic_ostringstream(ios_base::openmode which = ios_base::out);\n    explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type>& str,\n                                 ios_base::openmode which = ios_base::out);\n    basic_ostringstream(basic_ostringstream&& rhs);\n\n    // 27.8.3.2 Assign/swap:\n    basic_ostringstream& operator=(basic_ostringstream&& rhs);\n    void swap(basic_ostringstream& rhs);\n\n    // 27.8.3.3 Members:\n    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;\n    basic_string<char_type, traits_type, allocator_type> str() const;\n    void str(const basic_string<char_type, traits_type, allocator_type>& s);\n};\n\ntemplate <class charT, class traits, class Allocator>\n  void swap(basic_ostringstream<charT, traits, Allocator>& x,\n            basic_ostringstream<charT, traits, Allocator>& y);\n\ntypedef basic_ostringstream<char>    ostringstream;\ntypedef basic_ostringstream<wchar_t> wostringstream;\n\ntemplate <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >\nclass basic_stringstream\n    : public basic_iostream<charT, traits>\n{\npublic:\n    // types:\n    typedef charT                          char_type;\n    typedef traits                         traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n    typedef Allocator                      allocator_type;\n\n    // constructors/destructor\n    explicit basic_stringstream(ios_base::openmode which = ios_base::out|ios_base::in);\n    explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type>& str,\n                                ios_base::openmode which = ios_base::out|ios_base::in);\n    basic_stringstream(basic_stringstream&& rhs);\n\n    // 27.8.5.1 Assign/swap:\n    basic_stringstream& operator=(basic_stringstream&& rhs);\n    void swap(basic_stringstream& rhs);\n\n    // Members:\n    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;\n    basic_string<char_type, traits_type, allocator_type> str() const;\n    void str(const basic_string<char_type, traits_type, allocator_type>& str);\n};\n\ntemplate <class charT, class traits, class Allocator>\n  void swap(basic_stringstream<charT, traits, Allocator>& x,\n            basic_stringstream<charT, traits, Allocator>& y);\n\ntypedef basic_stringstream<char>    stringstream;\ntypedef basic_stringstream<wchar_t> wstringstream;\n\n}  // std\n\n*/\n\n#include <__config>\n#include <ostream>\n#include <istream>\n#include <string>\n\n#include <__undef_min_max>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n// basic_stringbuf\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nclass _LIBCPP_TYPE_VIS_ONLY basic_stringbuf\n    : public basic_streambuf<_CharT, _Traits>\n{\npublic:\n    typedef _CharT                         char_type;\n    typedef _Traits                        traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n    typedef _Allocator                     allocator_type;\n\n    typedef basic_string<char_type, traits_type, allocator_type> string_type;\n\nprivate:\n\n    string_type __str_;\n    mutable char_type* __hm_;\n    ios_base::openmode __mode_;\n\npublic:\n    // 27.8.1.1 Constructors:\n    explicit basic_stringbuf(ios_base::openmode __wch = ios_base::in | ios_base::out);\n    explicit basic_stringbuf(const string_type& __s,\n                             ios_base::openmode __wch = ios_base::in | ios_base::out);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    basic_stringbuf(basic_stringbuf&& __rhs);\n#endif\n\n    // 27.8.1.2 Assign and swap:\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    basic_stringbuf& operator=(basic_stringbuf&& __rhs);\n#endif\n    void swap(basic_stringbuf& __rhs);\n\n    // 27.8.1.3 Get and set:\n    string_type str() const;\n    void str(const string_type& __s);\n\nprotected:\n    // 27.8.1.4 Overridden virtual functions:\n    virtual int_type underflow();\n    virtual int_type pbackfail(int_type __c = traits_type::eof());\n    virtual int_type overflow (int_type __c = traits_type::eof());\n    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,\n                             ios_base::openmode __wch = ios_base::in | ios_base::out);\n    virtual pos_type seekpos(pos_type __sp,\n                             ios_base::openmode __wch = ios_base::in | ios_base::out);\n};\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(ios_base::openmode __wch)\n    : __hm_(0),\n      __mode_(__wch)\n{\n    str(string_type());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(const string_type& __s,\n                             ios_base::openmode __wch)\n    : __hm_(0),\n      __mode_(__wch)\n{\n    str(__s);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(basic_stringbuf&& __rhs)\n    : __mode_(__rhs.__mode_)\n{\n    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());\n    ptrdiff_t __binp = -1;\n    ptrdiff_t __ninp = -1;\n    ptrdiff_t __einp = -1;\n    if (__rhs.eback() != nullptr)\n    {\n        __binp = __rhs.eback() - __p;\n        __ninp = __rhs.gptr() - __p;\n        __einp = __rhs.egptr() - __p;\n    }\n    ptrdiff_t __bout = -1;\n    ptrdiff_t __nout = -1;\n    ptrdiff_t __eout = -1;\n    if (__rhs.pbase() != nullptr)\n    {\n        __bout = __rhs.pbase() - __p;\n        __nout = __rhs.pptr() - __p;\n        __eout = __rhs.epptr() - __p;\n    }\n    ptrdiff_t __hm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;\n    __str_ = _VSTD::move(__rhs.__str_);\n    __p = const_cast<char_type*>(__str_.data());\n    if (__binp != -1)\n        this->setg(__p + __binp, __p + __ninp, __p + __einp);\n    if (__bout != -1)\n    {\n        this->setp(__p + __bout, __p + __eout);\n        this->pbump(__nout);\n    }\n    __hm_ = __hm == -1 ? nullptr : __p + __hm;\n    __p = const_cast<char_type*>(__rhs.__str_.data());\n    __rhs.setg(__p, __p, __p);\n    __rhs.setp(__p, __p);\n    __rhs.__hm_ = __p;\n    this->pubimbue(__rhs.getloc());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_stringbuf<_CharT, _Traits, _Allocator>&\nbasic_stringbuf<_CharT, _Traits, _Allocator>::operator=(basic_stringbuf&& __rhs)\n{\n    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());\n    ptrdiff_t __binp = -1;\n    ptrdiff_t __ninp = -1;\n    ptrdiff_t __einp = -1;\n    if (__rhs.eback() != nullptr)\n    {\n        __binp = __rhs.eback() - __p;\n        __ninp = __rhs.gptr() - __p;\n        __einp = __rhs.egptr() - __p;\n    }\n    ptrdiff_t __bout = -1;\n    ptrdiff_t __nout = -1;\n    ptrdiff_t __eout = -1;\n    if (__rhs.pbase() != nullptr)\n    {\n        __bout = __rhs.pbase() - __p;\n        __nout = __rhs.pptr() - __p;\n        __eout = __rhs.epptr() - __p;\n    }\n    ptrdiff_t __hm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;\n    __str_ = _VSTD::move(__rhs.__str_);\n    __p = const_cast<char_type*>(__str_.data());\n    if (__binp != -1)\n        this->setg(__p + __binp, __p + __ninp, __p + __einp);\n    else\n        this->setg(nullptr, nullptr, nullptr);\n    if (__bout != -1)\n    {\n        this->setp(__p + __bout, __p + __eout);\n        this->pbump(__nout);\n    }\n    else\n        this->setp(nullptr, nullptr);\n\n    __hm_ = __hm == -1 ? nullptr : __p + __hm;\n    __mode_ = __rhs.__mode_;\n    __p = const_cast<char_type*>(__rhs.__str_.data());\n    __rhs.setg(__p, __p, __p);\n    __rhs.setp(__p, __p);\n    __rhs.__hm_ = __p;\n    this->pubimbue(__rhs.getloc());\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nvoid\nbasic_stringbuf<_CharT, _Traits, _Allocator>::swap(basic_stringbuf& __rhs)\n{\n    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());\n    ptrdiff_t __rbinp = -1;\n    ptrdiff_t __rninp = -1;\n    ptrdiff_t __reinp = -1;\n    if (__rhs.eback() != nullptr)\n    {\n        __rbinp = __rhs.eback() - __p;\n        __rninp = __rhs.gptr() - __p;\n        __reinp = __rhs.egptr() - __p;\n    }\n    ptrdiff_t __rbout = -1;\n    ptrdiff_t __rnout = -1;\n    ptrdiff_t __reout = -1;\n    if (__rhs.pbase() != nullptr)\n    {\n        __rbout = __rhs.pbase() - __p;\n        __rnout = __rhs.pptr() - __p;\n        __reout = __rhs.epptr() - __p;\n    }\n    ptrdiff_t __rhm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;\n    __p = const_cast<char_type*>(__str_.data());\n    ptrdiff_t __lbinp = -1;\n    ptrdiff_t __lninp = -1;\n    ptrdiff_t __leinp = -1;\n    if (this->eback() != nullptr)\n    {\n        __lbinp = this->eback() - __p;\n        __lninp = this->gptr() - __p;\n        __leinp = this->egptr() - __p;\n    }\n    ptrdiff_t __lbout = -1;\n    ptrdiff_t __lnout = -1;\n    ptrdiff_t __leout = -1;\n    if (this->pbase() != nullptr)\n    {\n        __lbout = this->pbase() - __p;\n        __lnout = this->pptr() - __p;\n        __leout = this->epptr() - __p;\n    }\n    ptrdiff_t __lhm = __hm_ == nullptr ? -1 : __hm_ - __p;\n    _VSTD::swap(__mode_, __rhs.__mode_);\n    __str_.swap(__rhs.__str_);\n    __p = const_cast<char_type*>(__str_.data());\n    if (__rbinp != -1)\n        this->setg(__p + __rbinp, __p + __rninp, __p + __reinp);\n    else\n        this->setg(nullptr, nullptr, nullptr);\n    if (__rbout != -1)\n    {\n        this->setp(__p + __rbout, __p + __reout);\n        this->pbump(__rnout);\n    }\n    else\n        this->setp(nullptr, nullptr);\n    __hm_ = __rhm == -1 ? nullptr : __p + __rhm;\n    __p = const_cast<char_type*>(__rhs.__str_.data());\n    if (__lbinp != -1)\n        __rhs.setg(__p + __lbinp, __p + __lninp, __p + __leinp);\n    else\n        __rhs.setg(nullptr, nullptr, nullptr);\n    if (__lbout != -1)\n    {\n        __rhs.setp(__p + __lbout, __p + __leout);\n        __rhs.pbump(__lnout);\n    }\n    else\n        __rhs.setp(nullptr, nullptr);\n    __rhs.__hm_ = __lhm == -1 ? nullptr : __p + __lhm;\n    locale __tl = __rhs.getloc();\n    __rhs.pubimbue(this->getloc());\n    this->pubimbue(__tl);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,\n     basic_stringbuf<_CharT, _Traits, _Allocator>& __y)\n{\n    __x.swap(__y);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>\nbasic_stringbuf<_CharT, _Traits, _Allocator>::str() const\n{\n    if (__mode_ & ios_base::out)\n    {\n        if (__hm_ < this->pptr())\n            __hm_ = this->pptr();\n        return string_type(this->pbase(), __hm_, __str_.get_allocator());\n    }\n    else if (__mode_ & ios_base::in)\n        return string_type(this->eback(), this->egptr(), __str_.get_allocator());\n    return string_type(__str_.get_allocator());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nvoid\nbasic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s)\n{\n    __str_ = __s;\n    __hm_ = 0;\n    if (__mode_ & ios_base::in)\n    {\n        __hm_ = const_cast<char_type*>(__str_.data()) + __str_.size();\n        this->setg(const_cast<char_type*>(__str_.data()),\n                   const_cast<char_type*>(__str_.data()),\n                   __hm_);\n    }\n    if (__mode_ & ios_base::out)\n    {\n        typename string_type::size_type __sz = __str_.size();\n        __hm_ = const_cast<char_type*>(__str_.data()) + __sz;\n        __str_.resize(__str_.capacity());\n        this->setp(const_cast<char_type*>(__str_.data()),\n                   const_cast<char_type*>(__str_.data()) + __str_.size());\n        if (__mode_ & (ios_base::app | ios_base::ate))\n            this->pbump(__sz);\n    }\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntypename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type\nbasic_stringbuf<_CharT, _Traits, _Allocator>::underflow()\n{\n    if (__hm_ < this->pptr())\n        __hm_ = this->pptr();\n    if (__mode_ & ios_base::in)\n    {\n        if (this->egptr() < __hm_)\n            this->setg(this->eback(), this->gptr(), __hm_);\n        if (this->gptr() < this->egptr())\n            return traits_type::to_int_type(*this->gptr());\n    }\n    return traits_type::eof();\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntypename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type\nbasic_stringbuf<_CharT, _Traits, _Allocator>::pbackfail(int_type __c)\n{\n    if (__hm_ < this->pptr())\n        __hm_ = this->pptr();\n    if (this->eback() < this->gptr())\n    {\n        if (traits_type::eq_int_type(__c, traits_type::eof()))\n        {\n            this->setg(this->eback(), this->gptr()-1, __hm_);\n            return traits_type::not_eof(__c);\n        }\n        if ((__mode_ & ios_base::out) ||\n            traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))\n        {\n            this->setg(this->eback(), this->gptr()-1, __hm_);\n            *this->gptr() = traits_type::to_char_type(__c);\n            return __c;\n        }\n    }\n    return traits_type::eof();\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntypename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type\nbasic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c)\n{\n    if (!traits_type::eq_int_type(__c, traits_type::eof()))\n    {\n        ptrdiff_t __ninp = this->gptr()  - this->eback();\n        if (this->pptr() == this->epptr())\n        {\n            if (!(__mode_ & ios_base::out))\n                return traits_type::eof();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            try\n            {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n                ptrdiff_t __nout = this->pptr()  - this->pbase();\n                ptrdiff_t __hm = __hm_ - this->pbase();\n                __str_.push_back(char_type());\n                __str_.resize(__str_.capacity());\n                char_type* __p = const_cast<char_type*>(__str_.data());\n                this->setp(__p, __p + __str_.size());\n                this->pbump(__nout);\n                __hm_ = this->pbase() + __hm;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            }\n            catch (...)\n            {\n                return traits_type::eof();\n            }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        }\n        __hm_ = _VSTD::max(this->pptr() + 1, __hm_);\n        if (__mode_ & ios_base::in)\n        {\n            char_type* __p = const_cast<char_type*>(__str_.data());\n            this->setg(__p, __p + __ninp, __hm_);\n        }\n        return this->sputc(__c);\n    }\n    return traits_type::not_eof(__c);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntypename basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type\nbasic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(off_type __off,\n                                                      ios_base::seekdir __way,\n                                                      ios_base::openmode __wch)\n{\n    if (__hm_ < this->pptr())\n        __hm_ = this->pptr();\n    if ((__wch & (ios_base::in | ios_base::out)) == 0)\n        return pos_type(-1);\n    if ((__wch & (ios_base::in | ios_base::out)) == (ios_base::in | ios_base::out)\n        && __way == ios_base::cur)\n        return pos_type(-1);\n    off_type __noff;\n    switch (__way)\n    {\n    case ios_base::beg:\n        __noff = 0;\n        break;\n    case ios_base::cur:\n        if (__wch & ios_base::in)\n            __noff = this->gptr() - this->eback();\n        else\n            __noff = this->pptr() - this->pbase();\n        break;\n    case ios_base::end:\n        __noff = __hm_ - __str_.data();\n        break;\n    default:\n        return pos_type(-1);\n    }\n    __noff += __off;\n    if (__noff < 0 || __hm_ - __str_.data() < __noff)\n        return pos_type(-1);\n    if (__noff != 0)\n    {\n        if ((__wch & ios_base::in) && this->gptr() == 0)\n            return pos_type(-1);\n        if ((__wch & ios_base::out) && this->pptr() == 0)\n            return pos_type(-1);\n    }\n    if (__wch & ios_base::in)\n        this->setg(this->eback(), this->eback() + __noff, __hm_);\n    if (__wch & ios_base::out)\n    {\n        this->setp(this->pbase(), this->epptr());\n        this->pbump(__noff);\n    }\n    return pos_type(__noff);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type\nbasic_stringbuf<_CharT, _Traits, _Allocator>::seekpos(pos_type __sp,\n                                                      ios_base::openmode __wch)\n{\n    return seekoff(__sp, ios_base::beg, __wch);\n}\n\n// basic_istringstream\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nclass _LIBCPP_TYPE_VIS_ONLY basic_istringstream\n    : public basic_istream<_CharT, _Traits>\n{\npublic:\n    typedef _CharT                         char_type;\n    typedef _Traits                        traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n    typedef _Allocator                     allocator_type;\n\n    typedef basic_string<char_type, traits_type, allocator_type> string_type;\n\nprivate:\n    basic_stringbuf<char_type, traits_type, allocator_type> __sb_;\n\npublic:\n    // 27.8.2.1 Constructors:\n    explicit basic_istringstream(ios_base::openmode __wch = ios_base::in);\n    explicit basic_istringstream(const string_type& __s,\n                                 ios_base::openmode __wch = ios_base::in);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    basic_istringstream(basic_istringstream&& __rhs);\n\n    // 27.8.2.2 Assign and swap:\n    basic_istringstream& operator=(basic_istringstream&& __rhs);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void swap(basic_istringstream& __rhs);\n\n    // 27.8.2.3 Members:\n    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;\n    string_type str() const;\n    void str(const string_type& __s);\n};\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istringstream<_CharT, _Traits, _Allocator>::basic_istringstream(ios_base::openmode __wch)\n    : basic_istream<_CharT, _Traits>(&__sb_),\n      __sb_(__wch | ios_base::in)\n{\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istringstream<_CharT, _Traits, _Allocator>::basic_istringstream(const string_type& __s,\n                                                                      ios_base::openmode __wch)\n    : basic_istream<_CharT, _Traits>(&__sb_),\n      __sb_(__s, __wch | ios_base::in)\n{\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istringstream<_CharT, _Traits, _Allocator>::basic_istringstream(basic_istringstream&& __rhs)\n    : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs)),\n      __sb_(_VSTD::move(__rhs.__sb_))\n{\n    basic_istream<_CharT, _Traits>::set_rdbuf(&__sb_);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_istringstream<_CharT, _Traits, _Allocator>&\nbasic_istringstream<_CharT, _Traits, _Allocator>::operator=(basic_istringstream&& __rhs)\n{\n    basic_istream<char_type, traits_type>::operator=(_VSTD::move(__rhs));\n    __sb_ = _VSTD::move(__rhs.__sb_);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_istringstream<_CharT, _Traits, _Allocator>::swap(basic_istringstream& __rhs)\n{\n    basic_istream<char_type, traits_type>::swap(__rhs);\n    __sb_.swap(__rhs.__sb_);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(basic_istringstream<_CharT, _Traits, _Allocator>& __x,\n     basic_istringstream<_CharT, _Traits, _Allocator>& __y)\n{\n    __x.swap(__y);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_stringbuf<_CharT, _Traits, _Allocator>*\nbasic_istringstream<_CharT, _Traits, _Allocator>::rdbuf() const\n{\n    return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>\nbasic_istringstream<_CharT, _Traits, _Allocator>::str() const\n{\n    return __sb_.str();\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_istringstream<_CharT, _Traits, _Allocator>::str(const string_type& __s)\n{\n    __sb_.str(__s);\n}\n\n// basic_ostringstream\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nclass _LIBCPP_TYPE_VIS_ONLY basic_ostringstream\n    : public basic_ostream<_CharT, _Traits>\n{\npublic:\n    typedef _CharT                         char_type;\n    typedef _Traits                        traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n    typedef _Allocator                     allocator_type;\n\n    typedef basic_string<char_type, traits_type, allocator_type> string_type;\n\nprivate:\n    basic_stringbuf<char_type, traits_type, allocator_type> __sb_;\n\npublic:\n    // 27.8.2.1 Constructors:\n    explicit basic_ostringstream(ios_base::openmode __wch = ios_base::out);\n    explicit basic_ostringstream(const string_type& __s,\n                                 ios_base::openmode __wch = ios_base::out);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    basic_ostringstream(basic_ostringstream&& __rhs);\n\n    // 27.8.2.2 Assign and swap:\n    basic_ostringstream& operator=(basic_ostringstream&& __rhs);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void swap(basic_ostringstream& __rhs);\n\n    // 27.8.2.3 Members:\n    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;\n    string_type str() const;\n    void str(const string_type& __s);\n};\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostringstream<_CharT, _Traits, _Allocator>::basic_ostringstream(ios_base::openmode __wch)\n    : basic_ostream<_CharT, _Traits>(&__sb_),\n      __sb_(__wch | ios_base::out)\n{\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostringstream<_CharT, _Traits, _Allocator>::basic_ostringstream(const string_type& __s,\n                                                                      ios_base::openmode __wch)\n    : basic_ostream<_CharT, _Traits>(&__sb_),\n      __sb_(__s, __wch | ios_base::out)\n{\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_ostringstream<_CharT, _Traits, _Allocator>::basic_ostringstream(basic_ostringstream&& __rhs)\n    : basic_ostream<_CharT, _Traits>(_VSTD::move(__rhs)),\n      __sb_(_VSTD::move(__rhs.__sb_))\n{\n    basic_ostream<_CharT, _Traits>::set_rdbuf(&__sb_);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_ostringstream<_CharT, _Traits, _Allocator>&\nbasic_ostringstream<_CharT, _Traits, _Allocator>::operator=(basic_ostringstream&& __rhs)\n{\n    basic_ostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));\n    __sb_ = _VSTD::move(__rhs.__sb_);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_ostringstream<_CharT, _Traits, _Allocator>::swap(basic_ostringstream& __rhs)\n{\n    basic_ostream<char_type, traits_type>::swap(__rhs);\n    __sb_.swap(__rhs.__sb_);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x,\n     basic_ostringstream<_CharT, _Traits, _Allocator>& __y)\n{\n    __x.swap(__y);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_stringbuf<_CharT, _Traits, _Allocator>*\nbasic_ostringstream<_CharT, _Traits, _Allocator>::rdbuf() const\n{\n    return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>\nbasic_ostringstream<_CharT, _Traits, _Allocator>::str() const\n{\n    return __sb_.str();\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_ostringstream<_CharT, _Traits, _Allocator>::str(const string_type& __s)\n{\n    __sb_.str(__s);\n}\n\n// basic_stringstream\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nclass _LIBCPP_TYPE_VIS_ONLY basic_stringstream\n    : public basic_iostream<_CharT, _Traits>\n{\npublic:\n    typedef _CharT                         char_type;\n    typedef _Traits                        traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n    typedef _Allocator                     allocator_type;\n\n    typedef basic_string<char_type, traits_type, allocator_type> string_type;\n\nprivate:\n    basic_stringbuf<char_type, traits_type, allocator_type> __sb_;\n\npublic:\n    // 27.8.2.1 Constructors:\n    explicit basic_stringstream(ios_base::openmode __wch = ios_base::in | ios_base::out);\n    explicit basic_stringstream(const string_type& __s,\n                                ios_base::openmode __wch = ios_base::in | ios_base::out);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    basic_stringstream(basic_stringstream&& __rhs);\n\n    // 27.8.2.2 Assign and swap:\n    basic_stringstream& operator=(basic_stringstream&& __rhs);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void swap(basic_stringstream& __rhs);\n\n    // 27.8.2.3 Members:\n    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;\n    string_type str() const;\n    void str(const string_type& __s);\n};\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_stringstream<_CharT, _Traits, _Allocator>::basic_stringstream(ios_base::openmode __wch)\n    : basic_iostream<_CharT, _Traits>(&__sb_),\n      __sb_(__wch)\n{\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_stringstream<_CharT, _Traits, _Allocator>::basic_stringstream(const string_type& __s,\n                                                                    ios_base::openmode __wch)\n    : basic_iostream<_CharT, _Traits>(&__sb_),\n      __sb_(__s, __wch)\n{\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_stringstream<_CharT, _Traits, _Allocator>::basic_stringstream(basic_stringstream&& __rhs)\n    : basic_iostream<_CharT, _Traits>(_VSTD::move(__rhs)),\n      __sb_(_VSTD::move(__rhs.__sb_))\n{\n    basic_istream<_CharT, _Traits>::set_rdbuf(&__sb_);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_stringstream<_CharT, _Traits, _Allocator>&\nbasic_stringstream<_CharT, _Traits, _Allocator>::operator=(basic_stringstream&& __rhs)\n{\n    basic_iostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));\n    __sb_ = _VSTD::move(__rhs.__sb_);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_stringstream<_CharT, _Traits, _Allocator>::swap(basic_stringstream& __rhs)\n{\n    basic_iostream<char_type, traits_type>::swap(__rhs);\n    __sb_.swap(__rhs.__sb_);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(basic_stringstream<_CharT, _Traits, _Allocator>& __x,\n     basic_stringstream<_CharT, _Traits, _Allocator>& __y)\n{\n    __x.swap(__y);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_stringbuf<_CharT, _Traits, _Allocator>*\nbasic_stringstream<_CharT, _Traits, _Allocator>::rdbuf() const\n{\n    return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>\nbasic_stringstream<_CharT, _Traits, _Allocator>::str() const\n{\n    return __sb_.str();\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_stringstream<_CharT, _Traits, _Allocator>::str(const string_type& __s)\n{\n    __sb_.str(__s);\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_SSTREAM\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/stack",
    "content": "// -*- C++ -*-\n//===---------------------------- stack -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_STACK\n#define _LIBCPP_STACK\n\n/*\n    stack synopsis\n\nnamespace std\n{\n\ntemplate <class T, class Container = deque<T>>\nclass stack\n{\npublic:\n    typedef Container                                container_type;\n    typedef typename container_type::value_type      value_type;\n    typedef typename container_type::reference       reference;\n    typedef typename container_type::const_reference const_reference;\n    typedef typename container_type::size_type       size_type;\n\nprotected:\n    container_type c;\n\npublic:\n    stack() = default;\n    ~stack() = default;\n\n    stack(const stack& q) = default;\n    stack(stack&& q) = default;\n\n    stack& operator=(const stack& q) = default;\n    stack& operator=(stack&& q) = default;\n\n    explicit stack(const container_type& c);\n    explicit stack(container_type&& c);\n    template <class Alloc> explicit stack(const Alloc& a);\n    template <class Alloc> stack(const container_type& c, const Alloc& a);\n    template <class Alloc> stack(container_type&& c, const Alloc& a);\n    template <class Alloc> stack(const stack& c, const Alloc& a);\n    template <class Alloc> stack(stack&& c, const Alloc& a);\n\n    bool empty() const;\n    size_type size() const;\n    reference top();\n    const_reference top() const;\n\n    void push(const value_type& x);\n    void push(value_type&& x);\n    template <class... Args> void emplace(Args&&... args);\n    void pop();\n\n    void swap(stack& c) noexcept(noexcept(swap(c, q.c)));\n};\n\ntemplate <class T, class Container>\n  bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);\ntemplate <class T, class Container>\n  bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);\ntemplate <class T, class Container>\n  bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);\ntemplate <class T, class Container>\n  bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);\ntemplate <class T, class Container>\n  bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);\ntemplate <class T, class Container>\n  bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);\n\ntemplate <class T, class Container>\n  void swap(stack<T, Container>& x, stack<T, Container>& y)\n  noexcept(noexcept(x.swap(y)));\n\n}  // std\n\n*/\n\n#include <__config>\n#include <deque>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Tp, class _Container = deque<_Tp> > class _LIBCPP_TYPE_VIS_ONLY stack;\n\ntemplate <class _Tp, class _Container>\n_LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y);\n\ntemplate <class _Tp, class _Container>\n_LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y);\n\ntemplate <class _Tp, class _Container /*= deque<_Tp>*/>\nclass _LIBCPP_TYPE_VIS_ONLY stack\n{\npublic:\n    typedef _Container                               container_type;\n    typedef typename container_type::value_type      value_type;\n    typedef typename container_type::reference       reference;\n    typedef typename container_type::const_reference const_reference;\n    typedef typename container_type::size_type       size_type;\n\nprotected:\n    container_type c;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    stack()\n        _NOEXCEPT_(is_nothrow_default_constructible<container_type>::value)\n        : c() {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    stack(const stack& __q) : c(__q.c) {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    stack(stack&& __q)\n        _NOEXCEPT_(is_nothrow_move_constructible<container_type>::value)\n        : c(_VSTD::move(__q.c)) {}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    stack& operator=(const stack& __q) {c = __q.c; return *this;}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    stack& operator=(stack&& __q)\n        _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value)\n        {c = _VSTD::move(__q.c); return *this;}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit stack(const container_type& __c) : c(__c) {}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    explicit stack(container_type&& __c) : c(_VSTD::move(__c)) {}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit stack(const _Alloc& __a,\n                       typename enable_if<uses_allocator<container_type,\n                                                         _Alloc>::value>::type* = 0)\n            : c(__a) {}\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        stack(const container_type& __c, const _Alloc& __a,\n              typename enable_if<uses_allocator<container_type,\n                                                _Alloc>::value>::type* = 0)\n            : c(__c, __a) {}\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        stack(const stack& __s, const _Alloc& __a,\n              typename enable_if<uses_allocator<container_type,\n                                                _Alloc>::value>::type* = 0)\n            : c(__s.c, __a) {}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        stack(container_type&& __c, const _Alloc& __a,\n              typename enable_if<uses_allocator<container_type,\n                                                _Alloc>::value>::type* = 0)\n            : c(_VSTD::move(__c), __a) {}\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        stack(stack&& __s, const _Alloc& __a,\n              typename enable_if<uses_allocator<container_type,\n                                                _Alloc>::value>::type* = 0)\n            : c(_VSTD::move(__s.c), __a) {}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool empty()     const      {return c.empty();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const      {return c.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    reference top()             {return c.back();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reference top() const {return c.back();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void push(const value_type& __v) {c.push_back(__v);}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void push(value_type&& __v) {c.push_back(_VSTD::move(__v));}\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        void emplace(_Args&&... __args)\n        {c.emplace_back(_VSTD::forward<_Args>(__args)...);}\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void pop() {c.pop_back();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(stack& __s)\n        _NOEXCEPT_(__is_nothrow_swappable<container_type>::value)\n    {\n        using _VSTD::swap;\n        swap(c, __s.c);\n    }\n\n    template <class T1, class _C1>\n    friend\n    bool\n    operator==(const stack<T1, _C1>& __x, const stack<T1, _C1>& __y);\n\n    template <class T1, class _C1>\n    friend\n    bool\n    operator< (const stack<T1, _C1>& __x, const stack<T1, _C1>& __y);\n};\n\ntemplate <class _Tp, class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)\n{\n    return __x.c == __y.c;\n}\n\ntemplate <class _Tp, class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)\n{\n    return __x.c < __y.c;\n}\n\ntemplate <class _Tp, class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Tp, class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator> (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _Tp, class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _Tp, class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _Tp, class _Container>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(stack<_Tp, _Container>& __x, stack<_Tp, _Container>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Tp, class _Container, class _Alloc>\nstruct _LIBCPP_TYPE_VIS_ONLY uses_allocator<stack<_Tp, _Container>, _Alloc>\n    : public uses_allocator<_Container, _Alloc>\n{\n};\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_STACK\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/stdexcept",
    "content": "// -*- C++ -*-\n//===--------------------------- stdexcept --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_STDEXCEPT\n#define _LIBCPP_STDEXCEPT\n\n/*\n    stdexcept synopsis\n\nnamespace std\n{\n\nclass logic_error;\n    class domain_error;\n    class invalid_argument;\n    class length_error;\n    class out_of_range;\nclass runtime_error;\n    class range_error;\n    class overflow_error;\n    class underflow_error;\n\nfor each class xxx_error:\n\nclass xxx_error : public exception // at least indirectly\n{\npublic:\n    explicit xxx_error(const string& what_arg);\n    explicit xxx_error(const char*   what_arg);\n\n    virtual const char* what() const noexcept // returns what_arg\n};\n\n}  // std\n\n*/\n\n#include <__config>\n#include <exception>\n#include <iosfwd>  // for string forward decl\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#ifndef _LIBCPP___REFSTRING\n_LIBCPP_BEGIN_NAMESPACE_STD\nclass _LIBCPP_HIDDEN __libcpp_refstring {\n    const char *__imp_ _LIBCPP_UNUSED;\n};\n_LIBCPP_END_NAMESPACE_STD\n#endif\n\nnamespace std  // purposefully not using versioning namespace\n{\n\nclass _LIBCPP_EXCEPTION_ABI logic_error\n    : public exception\n{\nprivate:\n    _VSTD::__libcpp_refstring __imp_;\npublic:\n    explicit logic_error(const string&);\n    explicit logic_error(const char*);\n\n    logic_error(const logic_error&) _NOEXCEPT;\n    logic_error& operator=(const logic_error&) _NOEXCEPT;\n\n    virtual ~logic_error() _NOEXCEPT;\n\n    virtual const char* what() const _NOEXCEPT;\n};\n\nclass _LIBCPP_EXCEPTION_ABI runtime_error\n    : public exception\n{\nprivate:\n    _VSTD::__libcpp_refstring __imp_;\npublic:\n    explicit runtime_error(const string&);\n    explicit runtime_error(const char*);\n\n    runtime_error(const runtime_error&) _NOEXCEPT;\n    runtime_error& operator=(const runtime_error&) _NOEXCEPT;\n\n    virtual ~runtime_error() _NOEXCEPT;\n\n    virtual const char* what() const _NOEXCEPT;\n};\n\nclass _LIBCPP_EXCEPTION_ABI domain_error\n    : public logic_error\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit domain_error(const string& __s) : logic_error(__s) {}\n    _LIBCPP_INLINE_VISIBILITY explicit domain_error(const char* __s)   : logic_error(__s) {}\n\n    virtual ~domain_error() _NOEXCEPT;\n};\n\nclass _LIBCPP_EXCEPTION_ABI invalid_argument\n    : public logic_error\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit invalid_argument(const string& __s) : logic_error(__s) {}\n    _LIBCPP_INLINE_VISIBILITY explicit invalid_argument(const char* __s)   : logic_error(__s) {}\n\n    virtual ~invalid_argument() _NOEXCEPT;\n};\n\nclass _LIBCPP_EXCEPTION_ABI length_error\n    : public logic_error\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit length_error(const string& __s) : logic_error(__s) {}\n    _LIBCPP_INLINE_VISIBILITY explicit length_error(const char* __s)   : logic_error(__s) {}\n\n    virtual ~length_error() _NOEXCEPT;\n};\n\nclass _LIBCPP_EXCEPTION_ABI out_of_range\n    : public logic_error\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit out_of_range(const string& __s) : logic_error(__s) {}\n    _LIBCPP_INLINE_VISIBILITY explicit out_of_range(const char* __s)   : logic_error(__s) {}\n\n    virtual ~out_of_range() _NOEXCEPT;\n};\n\nclass _LIBCPP_EXCEPTION_ABI range_error\n    : public runtime_error\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit range_error(const string& __s) : runtime_error(__s) {}\n    _LIBCPP_INLINE_VISIBILITY explicit range_error(const char* __s)   : runtime_error(__s) {}\n\n    virtual ~range_error() _NOEXCEPT;\n};\n\nclass _LIBCPP_EXCEPTION_ABI overflow_error\n    : public runtime_error\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit overflow_error(const string& __s) : runtime_error(__s) {}\n    _LIBCPP_INLINE_VISIBILITY explicit overflow_error(const char* __s)   : runtime_error(__s) {}\n\n    virtual ~overflow_error() _NOEXCEPT;\n};\n\nclass _LIBCPP_EXCEPTION_ABI underflow_error\n    : public runtime_error\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY explicit underflow_error(const string& __s) : runtime_error(__s) {}\n    _LIBCPP_INLINE_VISIBILITY explicit underflow_error(const char* __s)   : runtime_error(__s) {}\n\n    virtual ~underflow_error() _NOEXCEPT;\n};\n\n}  // std\n\n#endif  // _LIBCPP_STDEXCEPT\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/streambuf",
    "content": "// -*- C++ -*-\n//===------------------------- streambuf ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_STEAMBUF\n#define _LIBCPP_STEAMBUF\n\n/*\n    streambuf synopsis\n\nnamespace std\n{\n\ntemplate <class charT, class traits = char_traits<charT> >\nclass basic_streambuf\n{\npublic:\n    // types:\n    typedef charT char_type;\n    typedef traits traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    virtual ~basic_streambuf();\n\n    // 27.6.2.2.1 locales:\n    locale pubimbue(const locale& loc);\n    locale getloc() const;\n\n    // 27.6.2.2.2 buffer and positioning:\n    basic_streambuf* pubsetbuf(char_type* s, streamsize n);\n    pos_type pubseekoff(off_type off, ios_base::seekdir way,\n                        ios_base::openmode which = ios_base::in | ios_base::out);\n    pos_type pubseekpos(pos_type sp,\n                        ios_base::openmode which = ios_base::in | ios_base::out);\n    int pubsync();\n\n    // Get and put areas:\n    // 27.6.2.2.3 Get area:\n    streamsize in_avail();\n    int_type snextc();\n    int_type sbumpc();\n    int_type sgetc();\n    streamsize sgetn(char_type* s, streamsize n);\n\n    // 27.6.2.2.4 Putback:\n    int_type sputbackc(char_type c);\n    int_type sungetc();\n\n    // 27.6.2.2.5 Put area:\n    int_type sputc(char_type c);\n    streamsize sputn(const char_type* s, streamsize n);\n\nprotected:\n    basic_streambuf();\n    basic_streambuf(const basic_streambuf& rhs);\n    basic_streambuf& operator=(const basic_streambuf& rhs);\n    void swap(basic_streambuf& rhs);\n\n    // 27.6.2.3.2 Get area:\n    char_type* eback() const;\n    char_type* gptr() const;\n    char_type* egptr() const;\n    void gbump(int n);\n    void setg(char_type* gbeg, char_type* gnext, char_type* gend);\n\n    // 27.6.2.3.3 Put area:\n    char_type* pbase() const;\n    char_type* pptr() const;\n    char_type* epptr() const;\n    void pbump(int n);\n    void setp(char_type* pbeg, char_type* pend);\n\n    // 27.6.2.4 virtual functions:\n    // 27.6.2.4.1 Locales:\n    virtual void imbue(const locale& loc);\n\n    // 27.6.2.4.2 Buffer management and positioning:\n    virtual basic_streambuf* setbuf(char_type* s, streamsize n);\n    virtual pos_type seekoff(off_type off, ios_base::seekdir way,\n                             ios_base::openmode which = ios_base::in | ios_base::out);\n    virtual pos_type seekpos(pos_type sp,\n                             ios_base::openmode which = ios_base::in | ios_base::out);\n    virtual int sync();\n\n    // 27.6.2.4.3 Get area:\n    virtual streamsize showmanyc();\n    virtual streamsize xsgetn(char_type* s, streamsize n);\n    virtual int_type underflow();\n    virtual int_type uflow();\n\n    // 27.6.2.4.4 Putback:\n    virtual int_type pbackfail(int_type c = traits_type::eof());\n\n    // 27.6.2.4.5 Put area:\n    virtual streamsize xsputn(const char_type* s, streamsize n);\n    virtual int_type overflow (int_type c = traits_type::eof());\n};\n\n}  // std\n\n*/\n\n#include <__config>\n#include <iosfwd>\n#include <ios>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _CharT, class _Traits>\nclass _LIBCPP_TYPE_VIS_ONLY basic_streambuf\n{\npublic:\n    // types:\n    typedef _CharT                         char_type;\n    typedef _Traits                        traits_type;\n    typedef typename traits_type::int_type int_type;\n    typedef typename traits_type::pos_type pos_type;\n    typedef typename traits_type::off_type off_type;\n\n    virtual ~basic_streambuf();\n\n    // 27.6.2.2.1 locales:\n    locale pubimbue(const locale& __loc);\n    locale getloc() const;\n\n    // 27.6.2.2.2 buffer and positioning:\n    basic_streambuf* pubsetbuf(char_type* __s, streamsize __n);\n    pos_type pubseekoff(off_type __off, ios_base::seekdir __way,\n                        ios_base::openmode __which = ios_base::in | ios_base::out);\n    pos_type pubseekpos(pos_type __sp,\n                        ios_base::openmode __which = ios_base::in | ios_base::out);\n    int pubsync();\n\n    // Get and put areas:\n    // 27.6.2.2.3 Get area:\n    streamsize in_avail();\n    int_type snextc();\n    int_type sbumpc();\n    int_type sgetc();\n    streamsize sgetn(char_type* __s, streamsize __n);\n\n    // 27.6.2.2.4 Putback:\n    int_type sputbackc(char_type __c);\n    int_type sungetc();\n\n    // 27.6.2.2.5 Put area:\n    int_type sputc(char_type __c);\n    streamsize sputn(const char_type* __s, streamsize __n);\n\nprotected:\n    basic_streambuf();\n    basic_streambuf(const basic_streambuf& __rhs);\n    basic_streambuf& operator=(const basic_streambuf& __rhs);\n    void swap(basic_streambuf& __rhs);\n\n    // 27.6.2.3.2 Get area:\n    _LIBCPP_ALWAYS_INLINE char_type* eback() const {return __binp_;}\n    _LIBCPP_ALWAYS_INLINE char_type* gptr()  const {return __ninp_;}\n    _LIBCPP_ALWAYS_INLINE char_type* egptr() const {return __einp_;}\n    void gbump(int __n);\n    void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend);\n\n    // 27.6.2.3.3 Put area:\n    _LIBCPP_ALWAYS_INLINE char_type* pbase() const {return __bout_;}\n    _LIBCPP_ALWAYS_INLINE char_type* pptr()  const {return __nout_;}\n    _LIBCPP_ALWAYS_INLINE char_type* epptr() const {return __eout_;}\n    void pbump(int __n);\n    void setp(char_type* __pbeg, char_type* __pend);\n\n    // 27.6.2.4 virtual functions:\n    // 27.6.2.4.1 Locales:\n    virtual void imbue(const locale& __loc);\n\n    // 27.6.2.4.2 Buffer management and positioning:\n    virtual basic_streambuf* setbuf(char_type* __s, streamsize __n);\n    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,\n                             ios_base::openmode __which = ios_base::in | ios_base::out);\n    virtual pos_type seekpos(pos_type __sp,\n                             ios_base::openmode __which = ios_base::in | ios_base::out);\n    virtual int sync();\n\n    // 27.6.2.4.3 Get area:\n    virtual streamsize showmanyc();\n    virtual streamsize xsgetn(char_type* __s, streamsize __n);\n    virtual int_type underflow();\n    virtual int_type uflow();\n\n    // 27.6.2.4.4 Putback:\n    virtual int_type pbackfail(int_type __c = traits_type::eof());\n\n    // 27.6.2.4.5 Put area:\n    virtual streamsize xsputn(const char_type* __s, streamsize __n);\n    virtual int_type overflow(int_type __c = traits_type::eof());\n\nprivate:\n    locale __loc_;\n    char_type* __binp_;\n    char_type* __ninp_;\n    char_type* __einp_;\n    char_type* __bout_;\n    char_type* __nout_;\n    char_type* __eout_;\n};\n\ntemplate <class _CharT, class _Traits>\nbasic_streambuf<_CharT, _Traits>::~basic_streambuf()\n{\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nlocale\nbasic_streambuf<_CharT, _Traits>::pubimbue(const locale& __loc)\n{\n    imbue(__loc);\n    locale __r = __loc_;\n    __loc_ = __loc;\n    return __r;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nlocale\nbasic_streambuf<_CharT, _Traits>::getloc() const\n{\n    return __loc_;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_streambuf<_CharT, _Traits>*\nbasic_streambuf<_CharT, _Traits>::pubsetbuf(char_type* __s, streamsize __n)\n{\n    return setbuf(__s, __n);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_streambuf<_CharT, _Traits>::pos_type\nbasic_streambuf<_CharT, _Traits>::pubseekoff(off_type __off,\n                                             ios_base::seekdir __way,\n                                             ios_base::openmode __which)\n{\n    return seekoff(__off, __way, __which);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_streambuf<_CharT, _Traits>::pos_type\nbasic_streambuf<_CharT, _Traits>::pubseekpos(pos_type __sp,\n                                             ios_base::openmode __which)\n{\n    return seekpos(__sp, __which);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nint\nbasic_streambuf<_CharT, _Traits>::pubsync()\n{\n    return sync();\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nstreamsize\nbasic_streambuf<_CharT, _Traits>::in_avail()\n{\n    if (__ninp_ < __einp_)\n        return static_cast<streamsize>(__einp_ - __ninp_);\n    return showmanyc();\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_streambuf<_CharT, _Traits>::int_type\nbasic_streambuf<_CharT, _Traits>::snextc()\n{\n    if (sbumpc() == traits_type::eof())\n        return traits_type::eof();\n    return sgetc();\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_streambuf<_CharT, _Traits>::int_type\nbasic_streambuf<_CharT, _Traits>::sbumpc()\n{\n    if (__ninp_ == __einp_)\n        return uflow();\n    return traits_type::to_int_type(*__ninp_++);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_streambuf<_CharT, _Traits>::int_type\nbasic_streambuf<_CharT, _Traits>::sgetc()\n{\n    if (__ninp_ == __einp_)\n        return underflow();\n    return traits_type::to_int_type(*__ninp_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nstreamsize\nbasic_streambuf<_CharT, _Traits>::sgetn(char_type* __s, streamsize __n)\n{\n    return xsgetn(__s, __n);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_streambuf<_CharT, _Traits>::int_type\nbasic_streambuf<_CharT, _Traits>::sputbackc(char_type __c)\n{\n    if (__binp_ == __ninp_ || !traits_type::eq(__c, __ninp_[-1]))\n        return pbackfail(traits_type::to_int_type(__c));\n    return traits_type::to_int_type(*--__ninp_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_streambuf<_CharT, _Traits>::int_type\nbasic_streambuf<_CharT, _Traits>::sungetc()\n{\n    if (__binp_ == __ninp_)\n        return pbackfail();\n    return traits_type::to_int_type(*--__ninp_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_streambuf<_CharT, _Traits>::int_type\nbasic_streambuf<_CharT, _Traits>::sputc(char_type __c)\n{\n    if (__nout_ == __eout_)\n        return overflow(traits_type::to_int_type(__c));\n    *__nout_++ = __c;\n    return traits_type::to_int_type(__c);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nstreamsize\nbasic_streambuf<_CharT, _Traits>::sputn(const char_type* __s, streamsize __n)\n{\n    return xsputn(__s, __n);\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_streambuf<_CharT, _Traits>::basic_streambuf()\n    : __binp_(0),\n      __ninp_(0),\n      __einp_(0),\n      __bout_(0),\n      __nout_(0),\n      __eout_(0)\n{\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_streambuf<_CharT, _Traits>::basic_streambuf(const basic_streambuf& __sb)\n    : __loc_(__sb.__loc_),\n      __binp_(__sb.__binp_),\n      __ninp_(__sb.__ninp_),\n      __einp_(__sb.__einp_),\n      __bout_(__sb.__bout_),\n      __nout_(__sb.__nout_),\n      __eout_(__sb.__eout_)\n{\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_streambuf<_CharT, _Traits>&\nbasic_streambuf<_CharT, _Traits>::operator=(const basic_streambuf& __sb)\n{\n    __loc_ = __sb.__loc_;\n    __binp_ = __sb.__binp_;\n    __ninp_ = __sb.__ninp_;\n    __einp_ = __sb.__einp_;\n    __bout_ = __sb.__bout_;\n    __nout_ = __sb.__nout_;\n    __eout_ = __sb.__eout_;\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_streambuf<_CharT, _Traits>::swap(basic_streambuf& __sb)\n{\n    _VSTD::swap(__loc_, __sb.__loc_);\n    _VSTD::swap(__binp_, __sb.__binp_);\n    _VSTD::swap(__ninp_, __sb.__ninp_);\n    _VSTD::swap(__einp_, __sb.__einp_);\n    _VSTD::swap(__bout_, __sb.__bout_);\n    _VSTD::swap(__nout_, __sb.__nout_);\n    _VSTD::swap(__eout_, __sb.__eout_);\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_streambuf<_CharT, _Traits>::gbump(int __n)\n{\n    __ninp_ += __n;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_streambuf<_CharT, _Traits>::setg(char_type* __gbeg, char_type* __gnext,\n                                                          char_type* __gend)\n{\n    __binp_ = __gbeg;\n    __ninp_ = __gnext;\n    __einp_ = __gend;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_streambuf<_CharT, _Traits>::pbump(int __n)\n{\n    __nout_ += __n;\n}\n\ntemplate <class _CharT, class _Traits>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_streambuf<_CharT, _Traits>::setp(char_type* __pbeg, char_type* __pend)\n{\n    __bout_ = __nout_ = __pbeg;\n    __eout_ = __pend;\n}\n\ntemplate <class _CharT, class _Traits>\nvoid\nbasic_streambuf<_CharT, _Traits>::imbue(const locale&)\n{\n}\n\ntemplate <class _CharT, class _Traits>\nbasic_streambuf<_CharT, _Traits>*\nbasic_streambuf<_CharT, _Traits>::setbuf(char_type*, streamsize)\n{\n    return this;\n}\n\ntemplate <class _CharT, class _Traits>\ntypename basic_streambuf<_CharT, _Traits>::pos_type\nbasic_streambuf<_CharT, _Traits>::seekoff(off_type, ios_base::seekdir,\n                                          ios_base::openmode)\n{\n    return pos_type(off_type(-1));\n}\n\ntemplate <class _CharT, class _Traits>\ntypename basic_streambuf<_CharT, _Traits>::pos_type\nbasic_streambuf<_CharT, _Traits>::seekpos(pos_type, ios_base::openmode)\n{\n    return pos_type(off_type(-1));\n}\n\ntemplate <class _CharT, class _Traits>\nint\nbasic_streambuf<_CharT, _Traits>::sync()\n{\n    return 0;\n}\n\ntemplate <class _CharT, class _Traits>\nstreamsize\nbasic_streambuf<_CharT, _Traits>::showmanyc()\n{\n    return 0;\n}\n\ntemplate <class _CharT, class _Traits>\nstreamsize\nbasic_streambuf<_CharT, _Traits>::xsgetn(char_type* __s, streamsize __n)\n{\n    const int_type __eof = traits_type::eof();\n    int_type __c;\n    streamsize __i = 0;\n    for (;__i < __n; ++__i, ++__s)\n    {\n        if (__ninp_ < __einp_)\n            *__s = *__ninp_++;\n        else if ((__c = uflow()) != __eof)\n            *__s = traits_type::to_char_type(__c);\n        else\n            break;\n    }\n    return __i;\n}\n\ntemplate <class _CharT, class _Traits>\ntypename basic_streambuf<_CharT, _Traits>::int_type\nbasic_streambuf<_CharT, _Traits>::underflow()\n{\n    return traits_type::eof();\n}\n\ntemplate <class _CharT, class _Traits>\ntypename basic_streambuf<_CharT, _Traits>::int_type\nbasic_streambuf<_CharT, _Traits>::uflow()\n{\n    if (underflow() == traits_type::eof())\n        return traits_type::eof();\n    return traits_type::to_int_type(*__ninp_++);\n}\n\ntemplate <class _CharT, class _Traits>\ntypename basic_streambuf<_CharT, _Traits>::int_type\nbasic_streambuf<_CharT, _Traits>::pbackfail(int_type)\n{\n    return traits_type::eof();\n}\n\ntemplate <class _CharT, class _Traits>\nstreamsize\nbasic_streambuf<_CharT, _Traits>::xsputn(const char_type* __s, streamsize __n)\n{\n    streamsize __i = 0;\n    int_type __eof = traits_type::eof();\n    while( __i < __n)\n    {\n        if (__nout_ >= __eout_)\n        {\n            if (overflow(traits_type::to_int_type(*__s)) == __eof)\n                break;\n            ++__s;\n            ++__i;\n        }\n        else\n        {\n            streamsize __chunk_size = _VSTD::min(__eout_ - __nout_, __n - __i);\n            traits_type::copy(__nout_, __s, __chunk_size);\n            __nout_ += __chunk_size;\n            __s     += __chunk_size;\n            __i     += __chunk_size;\n        }\n    }\n    return __i;\n}\n\ntemplate <class _CharT, class _Traits>\ntypename basic_streambuf<_CharT, _Traits>::int_type\nbasic_streambuf<_CharT, _Traits>::overflow(int_type)\n{\n    return traits_type::eof();\n}\n\n_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_streambuf<char>)\n_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_streambuf<wchar_t>)\n\n_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ios<char>)\n_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ios<wchar_t>)\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_STEAMBUF\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/string",
    "content": "// -*- C++ -*-\n//===--------------------------- string -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_STRING\n#define _LIBCPP_STRING\n\n/*\n    string synopsis\n\nnamespace std\n{\n\ntemplate <class stateT>\nclass fpos\n{\nprivate:\n    stateT st;\npublic:\n    fpos(streamoff = streamoff());\n\n    operator streamoff() const;\n\n    stateT state() const;\n    void state(stateT);\n\n    fpos& operator+=(streamoff);\n    fpos  operator+ (streamoff) const;\n    fpos& operator-=(streamoff);\n    fpos  operator- (streamoff) const;\n};\n\ntemplate <class stateT> streamoff operator-(const fpos<stateT>& x, const fpos<stateT>& y);\n\ntemplate <class stateT> bool operator==(const fpos<stateT>& x, const fpos<stateT>& y);\ntemplate <class stateT> bool operator!=(const fpos<stateT>& x, const fpos<stateT>& y);\n\ntemplate <class charT>\nstruct char_traits\n{\n    typedef charT     char_type;\n    typedef ...       int_type;\n    typedef streamoff off_type;\n    typedef streampos pos_type;\n    typedef mbstate_t state_type;\n\n    static void assign(char_type& c1, const char_type& c2) noexcept;\n    static constexpr bool eq(char_type c1, char_type c2) noexcept;\n    static constexpr bool lt(char_type c1, char_type c2) noexcept;\n\n    static int              compare(const char_type* s1, const char_type* s2, size_t n);\n    static size_t           length(const char_type* s);\n    static const char_type* find(const char_type* s, size_t n, const char_type& a);\n    static char_type*       move(char_type* s1, const char_type* s2, size_t n);\n    static char_type*       copy(char_type* s1, const char_type* s2, size_t n);\n    static char_type*       assign(char_type* s, size_t n, char_type a);\n\n    static constexpr int_type  not_eof(int_type c) noexcept;\n    static constexpr char_type to_char_type(int_type c) noexcept;\n    static constexpr int_type  to_int_type(char_type c) noexcept;\n    static constexpr bool      eq_int_type(int_type c1, int_type c2) noexcept;\n    static constexpr int_type  eof() noexcept;\n};\n\ntemplate <> struct char_traits<char>;\ntemplate <> struct char_traits<wchar_t>;\n\ntemplate<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >\nclass basic_string\n{\npublic:\n// types:\n    typedef traits traits_type;\n    typedef typename traits_type::char_type value_type;\n    typedef Allocator allocator_type;\n    typedef typename allocator_type::size_type size_type;\n    typedef typename allocator_type::difference_type difference_type;\n    typedef typename allocator_type::reference reference;\n    typedef typename allocator_type::const_reference const_reference;\n    typedef typename allocator_type::pointer pointer;\n    typedef typename allocator_type::const_pointer const_pointer;\n    typedef implementation-defined iterator;\n    typedef implementation-defined const_iterator;\n    typedef std::reverse_iterator<iterator> reverse_iterator;\n    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;\n\n    static const size_type npos = -1;\n\n    basic_string()\n        noexcept(is_nothrow_default_constructible<allocator_type>::value);\n    explicit basic_string(const allocator_type& a);\n    basic_string(const basic_string& str);\n    basic_string(basic_string&& str)\n        noexcept(is_nothrow_move_constructible<allocator_type>::value);\n    basic_string(const basic_string& str, size_type pos, size_type n = npos,\n                 const allocator_type& a = allocator_type());\n    basic_string(const value_type* s, const allocator_type& a = allocator_type());\n    basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type());\n    basic_string(size_type n, value_type c, const allocator_type& a = allocator_type());\n    template<class InputIterator>\n        basic_string(InputIterator begin, InputIterator end,\n                     const allocator_type& a = allocator_type());\n    basic_string(initializer_list<value_type>, const Allocator& = Allocator());\n    basic_string(const basic_string&, const Allocator&);\n    basic_string(basic_string&&, const Allocator&);\n\n    ~basic_string();\n\n    basic_string& operator=(const basic_string& str);\n    basic_string& operator=(basic_string&& str)\n        noexcept(\n             allocator_type::propagate_on_container_move_assignment::value &&\n             is_nothrow_move_assignable<allocator_type>::value);\n    basic_string& operator=(const value_type* s);\n    basic_string& operator=(value_type c);\n    basic_string& operator=(initializer_list<value_type>);\n\n    iterator       begin() noexcept;\n    const_iterator begin() const noexcept;\n    iterator       end() noexcept;\n    const_iterator end() const noexcept;\n\n    reverse_iterator       rbegin() noexcept;\n    const_reverse_iterator rbegin() const noexcept;\n    reverse_iterator       rend() noexcept;\n    const_reverse_iterator rend() const noexcept;\n\n    const_iterator         cbegin() const noexcept;\n    const_iterator         cend() const noexcept;\n    const_reverse_iterator crbegin() const noexcept;\n    const_reverse_iterator crend() const noexcept;\n\n    size_type size() const noexcept;\n    size_type length() const noexcept;\n    size_type max_size() const noexcept;\n    size_type capacity() const noexcept;\n\n    void resize(size_type n, value_type c);\n    void resize(size_type n);\n\n    void reserve(size_type res_arg = 0);\n    void shrink_to_fit();\n    void clear() noexcept;\n    bool empty() const noexcept;\n\n    const_reference operator[](size_type pos) const;\n    reference       operator[](size_type pos);\n\n    const_reference at(size_type n) const;\n    reference       at(size_type n);\n\n    basic_string& operator+=(const basic_string& str);\n    basic_string& operator+=(const value_type* s);\n    basic_string& operator+=(value_type c);\n    basic_string& operator+=(initializer_list<value_type>);\n\n    basic_string& append(const basic_string& str);\n    basic_string& append(const basic_string& str, size_type pos, size_type n=npos); //C++14\n    basic_string& append(const value_type* s, size_type n);\n    basic_string& append(const value_type* s);\n    basic_string& append(size_type n, value_type c);\n    template<class InputIterator>\n        basic_string& append(InputIterator first, InputIterator last);\n    basic_string& append(initializer_list<value_type>);\n\n    void push_back(value_type c);\n    void pop_back();\n    reference       front();\n    const_reference front() const;\n    reference       back();\n    const_reference back() const;\n\n    basic_string& assign(const basic_string& str);\n    basic_string& assign(basic_string&& str);\n    basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14\n    basic_string& assign(const value_type* s, size_type n);\n    basic_string& assign(const value_type* s);\n    basic_string& assign(size_type n, value_type c);\n    template<class InputIterator>\n        basic_string& assign(InputIterator first, InputIterator last);\n    basic_string& assign(initializer_list<value_type>);\n\n    basic_string& insert(size_type pos1, const basic_string& str);\n    basic_string& insert(size_type pos1, const basic_string& str,\n                         size_type pos2, size_type n);\n    basic_string& insert(size_type pos, const value_type* s, size_type n=npos); //C++14\n    basic_string& insert(size_type pos, const value_type* s);\n    basic_string& insert(size_type pos, size_type n, value_type c);\n    iterator      insert(const_iterator p, value_type c);\n    iterator      insert(const_iterator p, size_type n, value_type c);\n    template<class InputIterator>\n        iterator insert(const_iterator p, InputIterator first, InputIterator last);\n    iterator      insert(const_iterator p, initializer_list<value_type>);\n\n    basic_string& erase(size_type pos = 0, size_type n = npos);\n    iterator      erase(const_iterator position);\n    iterator      erase(const_iterator first, const_iterator last);\n\n    basic_string& replace(size_type pos1, size_type n1, const basic_string& str);\n    basic_string& replace(size_type pos1, size_type n1, const basic_string& str,\n                          size_type pos2, size_type n2=npos); // C++14\n    basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2);\n    basic_string& replace(size_type pos, size_type n1, const value_type* s);\n    basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c);\n    basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);\n    basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n);\n    basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s);\n    basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c);\n    template<class InputIterator>\n        basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2);\n    basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>);\n\n    size_type copy(value_type* s, size_type n, size_type pos = 0) const;\n    basic_string substr(size_type pos = 0, size_type n = npos) const;\n\n    void swap(basic_string& str)\n        noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||\n                 allocator_traits<allocator_type>::is_always_equal::value);  // C++17\n\n    const value_type* c_str() const noexcept;\n    const value_type* data() const noexcept;\n\n    allocator_type get_allocator() const noexcept;\n\n    size_type find(const basic_string& str, size_type pos = 0) const noexcept;\n    size_type find(const value_type* s, size_type pos, size_type n) const noexcept;\n    size_type find(const value_type* s, size_type pos = 0) const noexcept;\n    size_type find(value_type c, size_type pos = 0) const noexcept;\n\n    size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;\n    size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept;\n    size_type rfind(const value_type* s, size_type pos = npos) const noexcept;\n    size_type rfind(value_type c, size_type pos = npos) const noexcept;\n\n    size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;\n    size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept;\n    size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept;\n    size_type find_first_of(value_type c, size_type pos = 0) const noexcept;\n\n    size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;\n    size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept;\n    size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept;\n    size_type find_last_of(value_type c, size_type pos = npos) const noexcept;\n\n    size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;\n    size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept;\n    size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept;\n    size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept;\n\n    size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;\n    size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept;\n    size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept;\n    size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept;\n\n    int compare(const basic_string& str) const noexcept;\n    int compare(size_type pos1, size_type n1, const basic_string& str) const;\n    int compare(size_type pos1, size_type n1, const basic_string& str,\n                size_type pos2, size_type n2=npos) const; // C++14\n    int compare(const value_type* s) const noexcept;\n    int compare(size_type pos1, size_type n1, const value_type* s) const;\n    int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const;\n\n    bool __invariants() const;\n};\n\ntemplate<class charT, class traits, class Allocator>\nbasic_string<charT, traits, Allocator>\noperator+(const basic_string<charT, traits, Allocator>& lhs,\n          const basic_string<charT, traits, Allocator>& rhs);\n\ntemplate<class charT, class traits, class Allocator>\nbasic_string<charT, traits, Allocator>\noperator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs);\n\ntemplate<class charT, class traits, class Allocator>\nbasic_string<charT, traits, Allocator>\noperator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs);\n\ntemplate<class charT, class traits, class Allocator>\nbasic_string<charT, traits, Allocator>\noperator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);\n\ntemplate<class charT, class traits, class Allocator>\nbasic_string<charT, traits, Allocator>\noperator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs);\n\ntemplate<class charT, class traits, class Allocator>\nbool operator==(const basic_string<charT, traits, Allocator>& lhs,\n                const basic_string<charT, traits, Allocator>& rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator!=(const basic_string<charT,traits,Allocator>& lhs,\n                const basic_string<charT, traits, Allocator>& rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator< (const basic_string<charT, traits, Allocator>& lhs,\n                const basic_string<charT, traits, Allocator>& rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator> (const basic_string<charT, traits, Allocator>& lhs,\n                const basic_string<charT, traits, Allocator>& rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator<=(const basic_string<charT, traits, Allocator>& lhs,\n                const basic_string<charT, traits, Allocator>& rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator>=(const basic_string<charT, traits, Allocator>& lhs,\n                const basic_string<charT, traits, Allocator>& rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nbool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;\n\ntemplate<class charT, class traits, class Allocator>\nvoid swap(basic_string<charT, traits, Allocator>& lhs,\n          basic_string<charT, traits, Allocator>& rhs)\n            noexcept(noexcept(lhs.swap(rhs)));\n\ntemplate<class charT, class traits, class Allocator>\nbasic_istream<charT, traits>&\noperator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);\n\ntemplate<class charT, class traits, class Allocator>\nbasic_ostream<charT, traits>&\noperator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);\n\ntemplate<class charT, class traits, class Allocator>\nbasic_istream<charT, traits>&\ngetline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str,\n        charT delim);\n\ntemplate<class charT, class traits, class Allocator>\nbasic_istream<charT, traits>&\ngetline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);\n\ntypedef basic_string<char>    string;\ntypedef basic_string<wchar_t> wstring;\ntypedef basic_string<char16_t> u16string;\ntypedef basic_string<char32_t> u32string;\n\nint                stoi  (const string& str, size_t* idx = 0, int base = 10);\nlong               stol  (const string& str, size_t* idx = 0, int base = 10);\nunsigned long      stoul (const string& str, size_t* idx = 0, int base = 10);\nlong long          stoll (const string& str, size_t* idx = 0, int base = 10);\nunsigned long long stoull(const string& str, size_t* idx = 0, int base = 10);\n\nfloat       stof (const string& str, size_t* idx = 0);\ndouble      stod (const string& str, size_t* idx = 0);\nlong double stold(const string& str, size_t* idx = 0);\n\nstring to_string(int val);\nstring to_string(unsigned val);\nstring to_string(long val);\nstring to_string(unsigned long val);\nstring to_string(long long val);\nstring to_string(unsigned long long val);\nstring to_string(float val);\nstring to_string(double val);\nstring to_string(long double val);\n\nint                stoi  (const wstring& str, size_t* idx = 0, int base = 10);\nlong               stol  (const wstring& str, size_t* idx = 0, int base = 10);\nunsigned long      stoul (const wstring& str, size_t* idx = 0, int base = 10);\nlong long          stoll (const wstring& str, size_t* idx = 0, int base = 10);\nunsigned long long stoull(const wstring& str, size_t* idx = 0, int base = 10);\n\nfloat       stof (const wstring& str, size_t* idx = 0);\ndouble      stod (const wstring& str, size_t* idx = 0);\nlong double stold(const wstring& str, size_t* idx = 0);\n\nwstring to_wstring(int val);\nwstring to_wstring(unsigned val);\nwstring to_wstring(long val);\nwstring to_wstring(unsigned long val);\nwstring to_wstring(long long val);\nwstring to_wstring(unsigned long long val);\nwstring to_wstring(float val);\nwstring to_wstring(double val);\nwstring to_wstring(long double val);\n\ntemplate <> struct hash<string>;\ntemplate <> struct hash<u16string>;\ntemplate <> struct hash<u32string>;\ntemplate <> struct hash<wstring>;\n\nbasic_string<char>     operator \"\" s( const char *str,     size_t len ); // C++14\nbasic_string<wchar_t>  operator \"\" s( const wchar_t *str,  size_t len ); // C++14\nbasic_string<char16_t> operator \"\" s( const char16_t *str, size_t len ); // C++14\nbasic_string<char32_t> operator \"\" s( const char32_t *str, size_t len ); // C++14\n\n}  // std\n\n*/\n\n#include <__config>\n#include <iosfwd>\n#include <cstring>\n#include <cstdio>  // For EOF.\n#include <cwchar>\n#include <algorithm>\n#include <iterator>\n#include <utility>\n#include <memory>\n#include <stdexcept>\n#include <type_traits>\n#include <initializer_list>\n#include <__functional_base>\n#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS\n#include <cstdint>\n#endif\n#if defined(_LIBCPP_NO_EXCEPTIONS)\n#include <cassert>\n#endif\n\n#include <__undef_min_max>\n\n#include <__debug>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n// fpos\n\ntemplate <class _StateT>\nclass _LIBCPP_TYPE_VIS_ONLY fpos\n{\nprivate:\n    _StateT __st_;\n    streamoff __off_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY fpos(streamoff __off = streamoff()) : __st_(), __off_(__off) {}\n\n    _LIBCPP_INLINE_VISIBILITY operator streamoff() const {return __off_;}\n\n    _LIBCPP_INLINE_VISIBILITY _StateT state() const {return __st_;}\n    _LIBCPP_INLINE_VISIBILITY void state(_StateT __st) {__st_ = __st;}\n\n    _LIBCPP_INLINE_VISIBILITY fpos& operator+=(streamoff __off) {__off_ += __off; return *this;}\n    _LIBCPP_INLINE_VISIBILITY fpos  operator+ (streamoff __off) const {fpos __t(*this); __t += __off; return __t;}\n    _LIBCPP_INLINE_VISIBILITY fpos& operator-=(streamoff __off) {__off_ -= __off; return *this;}\n    _LIBCPP_INLINE_VISIBILITY fpos  operator- (streamoff __off) const {fpos __t(*this); __t -= __off; return __t;}\n};\n\ntemplate <class _StateT>\ninline _LIBCPP_INLINE_VISIBILITY\nstreamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y)\n    {return streamoff(__x) - streamoff(__y);}\n\ntemplate <class _StateT>\ninline _LIBCPP_INLINE_VISIBILITY\nbool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y)\n    {return streamoff(__x) == streamoff(__y);}\n\ntemplate <class _StateT>\ninline _LIBCPP_INLINE_VISIBILITY\nbool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y)\n    {return streamoff(__x) != streamoff(__y);}\n\n// char_traits\n\ntemplate <class _CharT>\nstruct _LIBCPP_TYPE_VIS_ONLY char_traits\n{\n    typedef _CharT    char_type;\n    typedef int       int_type;\n    typedef streamoff off_type;\n    typedef streampos pos_type;\n    typedef mbstate_t state_type;\n\n    static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT\n        {__c1 = __c2;}\n    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT\n        {return __c1 == __c2;}\n    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT\n        {return __c1 < __c2;}\n\n    static int              compare(const char_type* __s1, const char_type* __s2, size_t __n);\n    static size_t           length(const char_type* __s);\n    static const char_type* find(const char_type* __s, size_t __n, const char_type& __a);\n    static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n);\n    static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n);\n    static char_type*       assign(char_type* __s, size_t __n, char_type __a);\n\n    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT\n        {return eq_int_type(__c, eof()) ? ~eof() : __c;}\n    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT\n        {return char_type(__c);}\n    static inline _LIBCPP_CONSTEXPR int_type  to_int_type(char_type __c) _NOEXCEPT\n        {return int_type(__c);}\n    static inline _LIBCPP_CONSTEXPR bool      eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT\n        {return __c1 == __c2;}\n    static inline _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT\n        {return int_type(EOF);}\n};\n\ntemplate <class _CharT>\nint\nchar_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)\n{\n    for (; __n; --__n, ++__s1, ++__s2)\n    {\n        if (lt(*__s1, *__s2))\n            return -1;\n        if (lt(*__s2, *__s1))\n            return 1;\n    }\n    return 0;\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nsize_t\nchar_traits<_CharT>::length(const char_type* __s)\n{\n    size_t __len = 0;\n    for (; !eq(*__s, char_type(0)); ++__s)\n        ++__len;\n    return __len;\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\nconst _CharT*\nchar_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)\n{\n    for (; __n; --__n)\n    {\n        if (eq(*__s, __a))\n            return __s;\n        ++__s;\n    }\n    return 0;\n}\n\ntemplate <class _CharT>\n_CharT*\nchar_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)\n{\n    char_type* __r = __s1;\n    if (__s1 < __s2)\n    {\n        for (; __n; --__n, ++__s1, ++__s2)\n            assign(*__s1, *__s2);\n    }\n    else if (__s2 < __s1)\n    {\n        __s1 += __n;\n        __s2 += __n;\n        for (; __n; --__n)\n            assign(*--__s1, *--__s2);\n    }\n    return __r;\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\n_CharT*\nchar_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)\n{\n    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, \"char_traits::copy overlapped range\");\n    char_type* __r = __s1;\n    for (; __n; --__n, ++__s1, ++__s2)\n        assign(*__s1, *__s2);\n    return __r;\n}\n\ntemplate <class _CharT>\ninline _LIBCPP_INLINE_VISIBILITY\n_CharT*\nchar_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)\n{\n    char_type* __r = __s;\n    for (; __n; --__n, ++__s)\n        assign(*__s, __a);\n    return __r;\n}\n\n// char_traits<char>\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY char_traits<char>\n{\n    typedef char      char_type;\n    typedef int       int_type;\n    typedef streamoff off_type;\n    typedef streampos pos_type;\n    typedef mbstate_t state_type;\n\n    static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT\n        {__c1 = __c2;}\n    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT\n            {return __c1 == __c2;}\n    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT\n        {return (unsigned char)__c1 < (unsigned char)__c2;}\n\n    static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n)\n        {return __n == 0 ? 0 : memcmp(__s1, __s2, __n);}\n    static inline size_t length(const char_type* __s) {return strlen(__s);}\n    static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a)\n        {return __n == 0 ? NULL : (const char_type*) memchr(__s, to_int_type(__a), __n);}\n    static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n)\n        {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}\n    static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n)\n        {\n            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, \"char_traits::copy overlapped range\");\n            return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);\n        }\n    static inline char_type* assign(char_type* __s, size_t __n, char_type __a)\n        {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}\n\n    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT\n        {return eq_int_type(__c, eof()) ? ~eof() : __c;}\n    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT\n        {return char_type(__c);}\n    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT\n        {return int_type((unsigned char)__c);}\n    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT\n        {return __c1 == __c2;}\n    static inline _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT\n        {return int_type(EOF);}\n};\n\n// char_traits<wchar_t>\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY char_traits<wchar_t>\n{\n    typedef wchar_t   char_type;\n    typedef wint_t    int_type;\n    typedef streamoff off_type;\n    typedef streampos pos_type;\n    typedef mbstate_t state_type;\n\n    static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT\n        {__c1 = __c2;}\n    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT\n        {return __c1 == __c2;}\n    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT\n        {return __c1 < __c2;}\n\n    static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n)\n        {return __n == 0 ? 0 : wmemcmp(__s1, __s2, __n);}\n    static inline size_t length(const char_type* __s)\n        {return wcslen(__s);}\n    static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a)\n        {return __n == 0 ? NULL : (const char_type*)wmemchr(__s, __a, __n);}\n    static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n)\n        {return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);}\n    static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n)\n        {\n            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, \"char_traits::copy overlapped range\");\n            return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n);\n        }\n    static inline char_type* assign(char_type* __s, size_t __n, char_type __a)\n        {return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);}\n\n    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT\n        {return eq_int_type(__c, eof()) ? ~eof() : __c;}\n    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT\n        {return char_type(__c);}\n    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT\n        {return int_type(__c);}\n    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT\n        {return __c1 == __c2;}\n    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT\n        {return int_type(WEOF);}\n};\n\n#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY char_traits<char16_t>\n{\n    typedef char16_t       char_type;\n    typedef uint_least16_t int_type;\n    typedef streamoff      off_type;\n    typedef u16streampos   pos_type;\n    typedef mbstate_t      state_type;\n\n    static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT\n        {__c1 = __c2;}\n    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT\n        {return __c1 == __c2;}\n    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT\n        {return __c1 < __c2;}\n\n    static int              compare(const char_type* __s1, const char_type* __s2, size_t __n);\n    static size_t           length(const char_type* __s);\n    static const char_type* find(const char_type* __s, size_t __n, const char_type& __a);\n    static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n);\n    static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n);\n    static char_type*       assign(char_type* __s, size_t __n, char_type __a);\n\n    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT\n        {return eq_int_type(__c, eof()) ? ~eof() : __c;}\n    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT\n        {return char_type(__c);}\n    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT\n        {return int_type(__c);}\n    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT\n        {return __c1 == __c2;}\n    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT\n        {return int_type(0xFFFF);}\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\nint\nchar_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n)\n{\n    for (; __n; --__n, ++__s1, ++__s2)\n    {\n        if (lt(*__s1, *__s2))\n            return -1;\n        if (lt(*__s2, *__s1))\n            return 1;\n    }\n    return 0;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nsize_t\nchar_traits<char16_t>::length(const char_type* __s)\n{\n    size_t __len = 0;\n    for (; !eq(*__s, char_type(0)); ++__s)\n        ++__len;\n    return __len;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nconst char16_t*\nchar_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a)\n{\n    for (; __n; --__n)\n    {\n        if (eq(*__s, __a))\n            return __s;\n        ++__s;\n    }\n    return 0;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nchar16_t*\nchar_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n)\n{\n    char_type* __r = __s1;\n    if (__s1 < __s2)\n    {\n        for (; __n; --__n, ++__s1, ++__s2)\n            assign(*__s1, *__s2);\n    }\n    else if (__s2 < __s1)\n    {\n        __s1 += __n;\n        __s2 += __n;\n        for (; __n; --__n)\n            assign(*--__s1, *--__s2);\n    }\n    return __r;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nchar16_t*\nchar_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n)\n{\n    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, \"char_traits::copy overlapped range\");\n    char_type* __r = __s1;\n    for (; __n; --__n, ++__s1, ++__s2)\n        assign(*__s1, *__s2);\n    return __r;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nchar16_t*\nchar_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a)\n{\n    char_type* __r = __s;\n    for (; __n; --__n, ++__s)\n        assign(*__s, __a);\n    return __r;\n}\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY char_traits<char32_t>\n{\n    typedef char32_t       char_type;\n    typedef uint_least32_t int_type;\n    typedef streamoff      off_type;\n    typedef u32streampos   pos_type;\n    typedef mbstate_t      state_type;\n\n    static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT\n        {__c1 = __c2;}\n    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT\n        {return __c1 == __c2;}\n    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT\n        {return __c1 < __c2;}\n\n    static int              compare(const char_type* __s1, const char_type* __s2, size_t __n);\n    static size_t           length(const char_type* __s);\n    static const char_type* find(const char_type* __s, size_t __n, const char_type& __a);\n    static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n);\n    static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n);\n    static char_type*       assign(char_type* __s, size_t __n, char_type __a);\n\n    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT\n        {return eq_int_type(__c, eof()) ? ~eof() : __c;}\n    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT\n        {return char_type(__c);}\n    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT\n        {return int_type(__c);}\n    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT\n        {return __c1 == __c2;}\n    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT\n        {return int_type(0xFFFFFFFF);}\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\nint\nchar_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n)\n{\n    for (; __n; --__n, ++__s1, ++__s2)\n    {\n        if (lt(*__s1, *__s2))\n            return -1;\n        if (lt(*__s2, *__s1))\n            return 1;\n    }\n    return 0;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nsize_t\nchar_traits<char32_t>::length(const char_type* __s)\n{\n    size_t __len = 0;\n    for (; !eq(*__s, char_type(0)); ++__s)\n        ++__len;\n    return __len;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nconst char32_t*\nchar_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a)\n{\n    for (; __n; --__n)\n    {\n        if (eq(*__s, __a))\n            return __s;\n        ++__s;\n    }\n    return 0;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nchar32_t*\nchar_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n)\n{\n    char_type* __r = __s1;\n    if (__s1 < __s2)\n    {\n        for (; __n; --__n, ++__s1, ++__s2)\n            assign(*__s1, *__s2);\n    }\n    else if (__s2 < __s1)\n    {\n        __s1 += __n;\n        __s2 += __n;\n        for (; __n; --__n)\n            assign(*--__s1, *--__s2);\n    }\n    return __r;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nchar32_t*\nchar_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n)\n{\n    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, \"char_traits::copy overlapped range\");\n    char_type* __r = __s1;\n    for (; __n; --__n, ++__s1, ++__s2)\n        assign(*__s1, *__s2);\n    return __r;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nchar32_t*\nchar_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a)\n{\n    char_type* __r = __s;\n    for (; __n; --__n, ++__s)\n        assign(*__s, __a);\n    return __r;\n}\n\n#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS\n\n// helper fns for basic_string\n\n// __str_find\ntemplate<class _CharT, class _SizeT, class _Traits, _SizeT __npos>\n_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n__str_find(const _CharT *__p, _SizeT __sz, \n             _CharT __c, _SizeT __pos) _NOEXCEPT\n{\n    if (__pos >= __sz)\n        return __npos;\n    const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);\n    if (__r == 0)\n        return __npos;\n    return static_cast<_SizeT>(__r - __p);\n}\n\ntemplate<class _CharT, class _SizeT, class _Traits, _SizeT __npos>\n_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n__str_find(const _CharT *__p, _SizeT __sz, \n       const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT\n{\n    if (__pos > __sz || __sz - __pos < __n)\n        return __npos;\n    if (__n == 0)\n        return __pos;\n    const _CharT* __r = \n        _VSTD::__search(__p + __pos, __p + __sz,\n                        __s, __s + __n, _Traits::eq,\n                        random_access_iterator_tag(), random_access_iterator_tag());\n    if (__r == __p + __sz)\n        return __npos;\n    return static_cast<_SizeT>(__r - __p);\n}\n\n\n// __str_rfind\n\ntemplate<class _CharT, class _SizeT, class _Traits, _SizeT __npos>\n_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n__str_rfind(const _CharT *__p, _SizeT __sz, \n              _CharT __c, _SizeT __pos) _NOEXCEPT\n{\n    if (__sz < 1)\n        return __npos;\n    if (__pos < __sz)\n        ++__pos;\n    else\n        __pos = __sz;\n    for (const _CharT* __ps = __p + __pos; __ps != __p;)\n    {\n        if (_Traits::eq(*--__ps, __c))\n            return static_cast<_SizeT>(__ps - __p);\n    }\n    return __npos;\n}\n\ntemplate<class _CharT, class _SizeT, class _Traits, _SizeT __npos>\n_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n__str_rfind(const _CharT *__p, _SizeT __sz, \n        const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT\n{\n    __pos = _VSTD::min(__pos, __sz);\n    if (__n < __sz - __pos)\n        __pos += __n;\n    else\n        __pos = __sz;\n    const _CharT* __r = _VSTD::__find_end(\n                  __p, __p + __pos, __s, __s + __n, _Traits::eq, \n                        random_access_iterator_tag(), random_access_iterator_tag());\n    if (__n > 0 && __r == __p + __pos)\n        return __npos;\n    return static_cast<_SizeT>(__r - __p);\n}\n\n// __str_find_first_of\ntemplate<class _CharT, class _SizeT, class _Traits, _SizeT __npos>\n_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n__str_find_first_of(const _CharT *__p, _SizeT __sz,\n                const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT\n{\n    if (__pos >= __sz || __n == 0)\n        return __npos;\n    const _CharT* __r = _VSTD::__find_first_of_ce\n        (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );\n    if (__r == __p + __sz)\n        return __npos;\n    return static_cast<_SizeT>(__r - __p);\n}\n\n\n// __str_find_last_of\ntemplate<class _CharT, class _SizeT, class _Traits, _SizeT __npos>\n_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY \n__str_find_last_of(const _CharT *__p, _SizeT __sz,\n               const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT\n    {\n    if (__n != 0)\n    {\n        if (__pos < __sz)\n            ++__pos;\n        else\n            __pos = __sz;\n        for (const _CharT* __ps = __p + __pos; __ps != __p;)\n        {\n            const _CharT* __r = _Traits::find(__s, __n, *--__ps);\n            if (__r)\n                return static_cast<_SizeT>(__ps - __p);\n        }\n    }\n    return __npos;\n}\n\n\n// __str_find_first_not_of\ntemplate<class _CharT, class _SizeT, class _Traits, _SizeT __npos>\n_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n__str_find_first_not_of(const _CharT *__p, _SizeT __sz,\n                    const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT\n{\n    if (__pos < __sz)\n    {\n        const _CharT* __pe = __p + __sz;\n        for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)\n            if (_Traits::find(__s, __n, *__ps) == 0)\n                return static_cast<_SizeT>(__ps - __p);\n    }\n    return __npos;\n}\n\n\ntemplate<class _CharT, class _SizeT, class _Traits, _SizeT __npos>\n_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n__str_find_first_not_of(const _CharT *__p, _SizeT __sz,\n                          _CharT __c, _SizeT __pos) _NOEXCEPT\n{\n    if (__pos < __sz)\n    {\n        const _CharT* __pe = __p + __sz;\n        for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)\n            if (!_Traits::eq(*__ps, __c))\n                return static_cast<_SizeT>(__ps - __p);\n    }\n    return __npos;\n}\n\n\n// __str_find_last_not_of\ntemplate<class _CharT, class _SizeT, class _Traits, _SizeT __npos>\n_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n__str_find_last_not_of(const _CharT *__p, _SizeT __sz,\n                   const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT\n{\n    if (__pos < __sz)\n        ++__pos;\n    else\n        __pos = __sz;\n    for (const _CharT* __ps = __p + __pos; __ps != __p;)\n        if (_Traits::find(__s, __n, *--__ps) == 0)\n            return static_cast<_SizeT>(__ps - __p);\n    return __npos;\n}\n\n\ntemplate<class _CharT, class _SizeT, class _Traits, _SizeT __npos>\n_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY\n__str_find_last_not_of(const _CharT *__p, _SizeT __sz,\n                         _CharT __c, _SizeT __pos) _NOEXCEPT\n{\n    if (__pos < __sz)\n        ++__pos;\n    else\n        __pos = __sz;\n    for (const _CharT* __ps = __p + __pos; __ps != __p;)\n        if (!_Traits::eq(*--__ps, __c))\n            return static_cast<_SizeT>(__ps - __p);\n    return __npos;\n}\n\ntemplate<class _Ptr>\nsize_t _LIBCPP_INLINE_VISIBILITY __do_string_hash(_Ptr __p, _Ptr __e)\n{\n    typedef typename iterator_traits<_Ptr>::value_type value_type;\n    return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));\n}\n\n// basic_string\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(const basic_string<_CharT, _Traits, _Allocator>& __x,\n          const basic_string<_CharT, _Traits, _Allocator>& __y);\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y);\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y);\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);\n\ntemplate <bool>\nclass _LIBCPP_TYPE_VIS_ONLY __basic_string_common\n{\nprotected:\n    void __throw_length_error() const;\n    void __throw_out_of_range() const;\n};\n\ntemplate <bool __b>\nvoid\n__basic_string_common<__b>::__throw_length_error() const\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    throw length_error(\"basic_string\");\n#else\n    assert(!\"basic_string length_error\");\n#endif\n}\n\ntemplate <bool __b>\nvoid\n__basic_string_common<__b>::__throw_out_of_range() const\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    throw out_of_range(\"basic_string\");\n#else\n    assert(!\"basic_string out_of_range\");\n#endif\n}\n\n#ifdef _LIBCPP_MSVC\n#pragma warning( push )\n#pragma warning( disable: 4231 )\n#endif // _LIBCPP_MSVC\n_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __basic_string_common<true>)\n#ifdef _LIBCPP_MSVC\n#pragma warning( pop )\n#endif // _LIBCPP_MSVC\n\n#ifdef _LIBCPP_ALTERNATE_STRING_LAYOUT\n\ntemplate <class _CharT, size_t = sizeof(_CharT)>\nstruct __padding\n{\n    unsigned char __xx[sizeof(_CharT)-1];\n};\n\ntemplate <class _CharT>\nstruct __padding<_CharT, 1>\n{\n};\n\n#endif  // _LIBCPP_ALTERNATE_STRING_LAYOUT\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nclass _LIBCPP_TYPE_VIS_ONLY basic_string\n    : private __basic_string_common<true>\n{\npublic:\n    typedef basic_string                                 __self;\n    typedef _Traits                                      traits_type;\n    typedef typename traits_type::char_type              value_type;\n    typedef _Allocator                                   allocator_type;\n    typedef allocator_traits<allocator_type>             __alloc_traits;\n    typedef typename __alloc_traits::size_type           size_type;\n    typedef typename __alloc_traits::difference_type     difference_type;\n    typedef value_type&                                  reference;\n    typedef const value_type&                            const_reference;\n    typedef typename __alloc_traits::pointer             pointer;\n    typedef typename __alloc_traits::const_pointer       const_pointer;\n\n    static_assert(is_pod<value_type>::value, \"Character type of basic_string must be a POD\");\n    static_assert((is_same<_CharT, value_type>::value),\n                  \"traits_type::char_type must be the same type as CharT\");\n    static_assert((is_same<typename allocator_type::value_type, value_type>::value),\n                  \"Allocator::value_type must be same type as value_type\");\n#if defined(_LIBCPP_RAW_ITERATORS)\n    typedef pointer                                      iterator;\n    typedef const_pointer                                const_iterator;\n#else  // defined(_LIBCPP_RAW_ITERATORS)\n    typedef __wrap_iter<pointer>                         iterator;\n    typedef __wrap_iter<const_pointer>                   const_iterator;\n#endif  // defined(_LIBCPP_RAW_ITERATORS)\n    typedef _VSTD::reverse_iterator<iterator>             reverse_iterator;\n    typedef _VSTD::reverse_iterator<const_iterator>       const_reverse_iterator;\n\nprivate:\n\n#ifdef _LIBCPP_ALTERNATE_STRING_LAYOUT\n\n    struct __long\n    {\n        pointer   __data_;\n        size_type __size_;\n        size_type __cap_;\n    };\n\n#if _LIBCPP_BIG_ENDIAN\n    enum {__short_mask = 0x01};\n    enum {__long_mask  = 0x1ul};\n#else  // _LIBCPP_BIG_ENDIAN\n    enum {__short_mask = 0x80};\n    enum {__long_mask  = ~(size_type(~0) >> 1)};\n#endif  // _LIBCPP_BIG_ENDIAN\n\n    enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?\n                      (sizeof(__long) - 1)/sizeof(value_type) : 2};\n\n    struct __short\n    {\n        value_type __data_[__min_cap];\n        struct\n            : __padding<value_type>\n        {\n            unsigned char __size_;\n        };\n    };\n\n#else\n\n    struct __long\n    {\n        size_type __cap_;\n        size_type __size_;\n        pointer   __data_;\n    };\n\n#if _LIBCPP_BIG_ENDIAN\n    enum {__short_mask = 0x80};\n    enum {__long_mask  = ~(size_type(~0) >> 1)};\n#else  // _LIBCPP_BIG_ENDIAN\n    enum {__short_mask = 0x01};\n    enum {__long_mask  = 0x1ul};\n#endif  // _LIBCPP_BIG_ENDIAN\n\n    enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?\n                      (sizeof(__long) - 1)/sizeof(value_type) : 2};\n\n    struct __short\n    {\n        union\n        {\n            unsigned char __size_;\n            value_type __lx;\n        };\n        value_type __data_[__min_cap];\n    };\n\n#endif  // _LIBCPP_ALTERNATE_STRING_LAYOUT\n\n    union __ulx{__long __lx; __short __lxx;};\n\n    enum {__n_words = sizeof(__ulx) / sizeof(size_type)};\n\n    struct __raw\n    {\n        size_type __words[__n_words];\n    };\n\n    struct __rep\n    {\n        union\n        {\n            __long  __l;\n            __short __s;\n            __raw   __r;\n        };\n    };\n\n    __compressed_pair<__rep, allocator_type> __r_;\n\npublic:\n    static const size_type npos = -1;\n\n    _LIBCPP_INLINE_VISIBILITY basic_string()\n        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);\n\n    _LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a)\n#if _LIBCPP_STD_VER <= 14\n        _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value);\n#else\n        _NOEXCEPT;\n#endif\n\n    basic_string(const basic_string& __str);\n    basic_string(const basic_string& __str, const allocator_type& __a);\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string(basic_string&& __str)\n#if _LIBCPP_STD_VER <= 14\n        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);\n#else\n        _NOEXCEPT;\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string(basic_string&& __str, const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY basic_string(const value_type* __s);\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string(const value_type* __s, const allocator_type& __a);\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string(const value_type* __s, size_type __n);\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string(const value_type* __s, size_type __n, const allocator_type& __a);\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string(size_type __n, value_type __c);\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string(size_type __n, value_type __c, const allocator_type& __a);\n    basic_string(const basic_string& __str, size_type __pos, size_type __n = npos,\n                 const allocator_type& __a = allocator_type());\n    template<class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        basic_string(_InputIterator __first, _InputIterator __last);\n    template<class _InputIterator>\n        _LIBCPP_INLINE_VISIBILITY\n        basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string(initializer_list<value_type> __il);\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string(initializer_list<value_type> __il, const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    ~basic_string();\n\n    basic_string& operator=(const basic_string& __str);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string& operator=(basic_string&& __str)\n        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&\n                   is_nothrow_move_assignable<allocator_type>::value);\n#endif\n    _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);}\n    basic_string& operator=(value_type __c);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_INLINE_VISIBILITY\n    iterator begin() _NOEXCEPT\n        {return iterator(this, __get_pointer());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin() const _NOEXCEPT\n        {return const_iterator(this, __get_pointer());}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator end() _NOEXCEPT\n        {return iterator(this, __get_pointer() + size());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end() const _NOEXCEPT\n        {return const_iterator(this, __get_pointer() + size());}\n#else\n    _LIBCPP_INLINE_VISIBILITY\n    iterator begin() _NOEXCEPT\n        {return iterator(__get_pointer());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin() const _NOEXCEPT\n        {return const_iterator(__get_pointer());}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator end() _NOEXCEPT\n        {return iterator(__get_pointer() + size());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end() const _NOEXCEPT\n        {return const_iterator(__get_pointer() + size());}\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_INLINE_VISIBILITY\n    reverse_iterator rbegin() _NOEXCEPT\n        {return reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rbegin() const _NOEXCEPT\n        {return const_reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n    reverse_iterator rend() _NOEXCEPT\n        {return reverse_iterator(begin());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rend() const _NOEXCEPT\n        {return const_reverse_iterator(begin());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cbegin() const _NOEXCEPT\n        {return begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cend() const _NOEXCEPT\n        {return end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crbegin() const _NOEXCEPT\n        {return rbegin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crend() const _NOEXCEPT\n        {return rend();}\n\n    _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT\n        {return __is_long() ? __get_long_size() : __get_short_size();}\n    _LIBCPP_INLINE_VISIBILITY size_type length() const _NOEXCEPT {return size();}\n    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY size_type capacity() const _NOEXCEPT\n        {return (__is_long() ? __get_long_cap() : __min_cap) - 1;}\n\n    void resize(size_type __n, value_type __c);\n    _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());}\n\n    void reserve(size_type res_arg = 0);\n    _LIBCPP_INLINE_VISIBILITY\n    void shrink_to_fit() _NOEXCEPT {reserve();}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return size() == 0;}\n\n    _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const;\n    _LIBCPP_INLINE_VISIBILITY reference       operator[](size_type __pos);\n\n    const_reference at(size_type __n) const;\n    reference       at(size_type __n);\n\n    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);}\n    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s)         {return append(__s);}\n    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c)            {push_back(__c); return *this;}\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string& append(const basic_string& __str);\n    basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);\n    basic_string& append(const value_type* __s, size_type __n);\n    basic_string& append(const value_type* __s);\n    basic_string& append(size_type __n, value_type __c);\n    template<class _InputIterator>\n        typename enable_if\n        <\n             __is_input_iterator  <_InputIterator>::value &&\n            !__is_forward_iterator<_InputIterator>::value,\n            basic_string&\n        >::type\n        append(_InputIterator __first, _InputIterator __last);\n    template<class _ForwardIterator>\n        typename enable_if\n        <\n            __is_forward_iterator<_ForwardIterator>::value,\n            basic_string&\n        >::type\n        append(_ForwardIterator __first, _ForwardIterator __last);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    void push_back(value_type __c);\n    _LIBCPP_INLINE_VISIBILITY\n    void pop_back();\n    _LIBCPP_INLINE_VISIBILITY reference       front();\n    _LIBCPP_INLINE_VISIBILITY const_reference front() const;\n    _LIBCPP_INLINE_VISIBILITY reference       back();\n    _LIBCPP_INLINE_VISIBILITY const_reference back() const;\n\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string& assign(const basic_string& __str);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string& assign(basic_string&& str)\n        {*this = _VSTD::move(str); return *this;}\n#endif\n    basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);\n    basic_string& assign(const value_type* __s, size_type __n);\n    basic_string& assign(const value_type* __s);\n    basic_string& assign(size_type __n, value_type __c);\n    template<class _InputIterator>\n        typename enable_if\n        <\n             __is_input_iterator  <_InputIterator>::value &&\n            !__is_forward_iterator<_InputIterator>::value,\n            basic_string&\n        >::type\n        assign(_InputIterator __first, _InputIterator __last);\n    template<class _ForwardIterator>\n        typename enable_if\n        <\n            __is_forward_iterator<_ForwardIterator>::value,\n            basic_string&\n        >::type\n        assign(_ForwardIterator __first, _ForwardIterator __last);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string& insert(size_type __pos1, const basic_string& __str);\n    basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);\n    basic_string& insert(size_type __pos, const value_type* __s, size_type __n);\n    basic_string& insert(size_type __pos, const value_type* __s);\n    basic_string& insert(size_type __pos, size_type __n, value_type __c);\n    iterator      insert(const_iterator __pos, value_type __c);\n    _LIBCPP_INLINE_VISIBILITY\n    iterator      insert(const_iterator __pos, size_type __n, value_type __c);\n    template<class _InputIterator>\n        typename enable_if\n        <\n             __is_input_iterator  <_InputIterator>::value &&\n            !__is_forward_iterator<_InputIterator>::value,\n            iterator\n        >::type\n        insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);\n    template<class _ForwardIterator>\n        typename enable_if\n        <\n            __is_forward_iterator<_ForwardIterator>::value,\n            iterator\n        >::type\n        insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator __pos, initializer_list<value_type> __il)\n                    {return insert(__pos, __il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    basic_string& erase(size_type __pos = 0, size_type __n = npos);\n    _LIBCPP_INLINE_VISIBILITY\n    iterator      erase(const_iterator __pos);\n    _LIBCPP_INLINE_VISIBILITY\n    iterator      erase(const_iterator __first, const_iterator __last);\n\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str);\n    basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);\n    basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);\n    basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);\n    basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str);\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n);\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s);\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c);\n    template<class _InputIterator>\n        typename enable_if\n        <\n            __is_input_iterator<_InputIterator>::value,\n            basic_string&\n        >::type\n        replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il)\n        {return replace(__i1, __i2, __il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;\n    _LIBCPP_INLINE_VISIBILITY\n    basic_string substr(size_type __pos = 0, size_type __n = npos) const;\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(basic_string& __str)\n#if _LIBCPP_STD_VER >= 14\n        _NOEXCEPT;\n#else\n        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || \n                    __is_nothrow_swappable<allocator_type>::value);\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    const value_type* c_str() const _NOEXCEPT {return data();}\n    _LIBCPP_INLINE_VISIBILITY\n    const value_type* data() const _NOEXCEPT  {return _VSTD::__to_raw_pointer(__get_pointer());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const _NOEXCEPT {return __alloc();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;\n    size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;\n    size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;\n    size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;\n    size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;\n    size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;\n    size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;\n    size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;\n    size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    int compare(const basic_string& __str) const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;\n    int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos) const;\n    int compare(const value_type* __s) const _NOEXCEPT;\n    int compare(size_type __pos1, size_type __n1, const value_type* __s) const;\n    int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;\n\n    _LIBCPP_INLINE_VISIBILITY bool __invariants() const;\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool __is_long() const _NOEXCEPT\n        {return bool(__r_.first().__s.__size_ & __short_mask);}\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n    bool __dereferenceable(const const_iterator* __i) const;\n    bool __decrementable(const const_iterator* __i) const;\n    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;\n    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type& __alloc() _NOEXCEPT\n        {return __r_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n    const allocator_type& __alloc() const _NOEXCEPT\n        {return __r_.second();}\n\n#ifdef _LIBCPP_ALTERNATE_STRING_LAYOUT\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __set_short_size(size_type __s) _NOEXCEPT\n#   if _LIBCPP_BIG_ENDIAN\n        {__r_.first().__s.__size_ = (unsigned char)(__s << 1);}\n#   else\n        {__r_.first().__s.__size_ = (unsigned char)(__s);}\n#   endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type __get_short_size() const _NOEXCEPT\n#   if _LIBCPP_BIG_ENDIAN\n        {return __r_.first().__s.__size_ >> 1;}\n#   else\n        {return __r_.first().__s.__size_;}\n#   endif\n\n#else  // _LIBCPP_ALTERNATE_STRING_LAYOUT\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __set_short_size(size_type __s) _NOEXCEPT\n#   if _LIBCPP_BIG_ENDIAN\n        {__r_.first().__s.__size_ = (unsigned char)(__s);}\n#   else\n        {__r_.first().__s.__size_ = (unsigned char)(__s << 1);}\n#   endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type __get_short_size() const _NOEXCEPT\n#   if _LIBCPP_BIG_ENDIAN\n        {return __r_.first().__s.__size_;}\n#   else\n        {return __r_.first().__s.__size_ >> 1;}\n#   endif\n\n#endif  // _LIBCPP_ALTERNATE_STRING_LAYOUT\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __set_long_size(size_type __s) _NOEXCEPT\n        {__r_.first().__l.__size_ = __s;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type __get_long_size() const _NOEXCEPT\n        {return __r_.first().__l.__size_;}\n    _LIBCPP_INLINE_VISIBILITY\n    void __set_size(size_type __s) _NOEXCEPT\n        {if (__is_long()) __set_long_size(__s); else __set_short_size(__s);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __set_long_cap(size_type __s) _NOEXCEPT\n        {__r_.first().__l.__cap_  = __long_mask | __s;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type __get_long_cap() const _NOEXCEPT\n        {return __r_.first().__l.__cap_ & size_type(~__long_mask);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __set_long_pointer(pointer __p) _NOEXCEPT\n        {__r_.first().__l.__data_ = __p;}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer __get_long_pointer() _NOEXCEPT\n        {return __r_.first().__l.__data_;}\n    _LIBCPP_INLINE_VISIBILITY\n    const_pointer __get_long_pointer() const _NOEXCEPT\n        {return __r_.first().__l.__data_;}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer __get_short_pointer() _NOEXCEPT\n        {return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_pointer __get_short_pointer() const _NOEXCEPT\n        {return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer __get_pointer() _NOEXCEPT\n        {return __is_long() ? __get_long_pointer() : __get_short_pointer();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_pointer __get_pointer() const _NOEXCEPT\n        {return __is_long() ? __get_long_pointer() : __get_short_pointer();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __zero() _NOEXCEPT\n        {\n            size_type (&__a)[__n_words] = __r_.first().__r.__words;\n            for (unsigned __i = 0; __i < __n_words; ++__i)\n                __a[__i] = 0;\n        }\n\n    template <size_type __a> static\n        _LIBCPP_INLINE_VISIBILITY\n        size_type __align_it(size_type __s) _NOEXCEPT\n            {return __s + (__a-1) & ~(__a-1);}\n    enum {__alignment = 16};\n    static _LIBCPP_INLINE_VISIBILITY\n    size_type __recommend(size_type __s) _NOEXCEPT\n        {return (__s < __min_cap ? __min_cap :\n                 __align_it<sizeof(value_type) < __alignment ?\n                            __alignment/sizeof(value_type) : 1 > (__s+1)) - 1;}\n\n    void __init(const value_type* __s, size_type __sz, size_type __reserve);\n    void __init(const value_type* __s, size_type __sz);\n    void __init(size_type __n, value_type __c);\n\n    template <class _InputIterator>\n    typename enable_if\n    <\n         __is_input_iterator  <_InputIterator>::value &&\n        !__is_forward_iterator<_InputIterator>::value,\n        void\n    >::type\n    __init(_InputIterator __first, _InputIterator __last);\n\n    template <class _ForwardIterator>\n    typename enable_if\n    <\n        __is_forward_iterator<_ForwardIterator>::value,\n        void\n    >::type\n    __init(_ForwardIterator __first, _ForwardIterator __last);\n\n    void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,\n                   size_type __n_copy,  size_type __n_del,     size_type __n_add = 0);\n    void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,\n                               size_type __n_copy,  size_type __n_del,\n                               size_type __n_add, const value_type* __p_new_stuff);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __erase_to_end(size_type __pos);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const basic_string& __str)\n        {__copy_assign_alloc(__str, integral_constant<bool,\n                      __alloc_traits::propagate_on_container_copy_assignment::value>());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const basic_string& __str, true_type)\n        {\n            if (__alloc() != __str.__alloc())\n            {\n                clear();\n                shrink_to_fit();\n            }\n            __alloc() = __str.__alloc();\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT\n        {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign(basic_string& __str, false_type);\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign(basic_string& __str, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    void\n    __move_assign_alloc(basic_string& __str)\n        _NOEXCEPT_(\n            !__alloc_traits::propagate_on_container_move_assignment::value ||\n            is_nothrow_move_assignable<allocator_type>::value)\n    {__move_assign_alloc(__str, integral_constant<bool,\n                      __alloc_traits::propagate_on_container_move_assignment::value>());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(basic_string& __c, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)\n        {\n            __alloc() = _VSTD::move(__c.__alloc());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(basic_string&, false_type)\n        _NOEXCEPT\n        {}\n\n    _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();\n    _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type);\n\n    friend basic_string operator+<>(const basic_string&, const basic_string&);\n    friend basic_string operator+<>(const value_type*, const basic_string&);\n    friend basic_string operator+<>(value_type, const basic_string&);\n    friend basic_string operator+<>(const basic_string&, const value_type*);\n    friend basic_string operator+<>(const basic_string&, value_type);\n};\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators()\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__invalidate_all(this);\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type\n#if _LIBCPP_DEBUG_LEVEL >= 2\n                                                                        __pos\n#endif\n                                                                      )\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __c_node* __c = __get_db()->__find_c_and_lock(this);\n    if (__c)\n    {\n        const_pointer __new_last = __get_pointer() + __pos;\n        for (__i_node** __p = __c->end_; __p != __c->beg_; )\n        {\n            --__p;\n            const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);\n            if (__i->base() > __new_last)\n            {\n                (*__p)->__c_ = nullptr;\n                if (--__c->end_ != __p)\n                    memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));\n            }\n        }\n        __get_db()->unlock();\n    }\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>::basic_string()\n    _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __zero();\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a)\n#if _LIBCPP_STD_VER <= 14\n        _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)\n#else\n        _NOEXCEPT\n#endif\n: __r_(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __zero();\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve)\n{\n    if (__reserve > max_size())\n        this->__throw_length_error();\n    pointer __p;\n    if (__reserve < __min_cap)\n    {\n        __set_short_size(__sz);\n        __p = __get_short_pointer();\n    }\n    else\n    {\n        size_type __cap = __recommend(__reserve);\n        __p = __alloc_traits::allocate(__alloc(), __cap+1);\n        __set_long_pointer(__p);\n        __set_long_cap(__cap+1);\n        __set_long_size(__sz);\n    }\n    traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz);\n    traits_type::assign(__p[__sz], value_type());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)\n{\n    if (__sz > max_size())\n        this->__throw_length_error();\n    pointer __p;\n    if (__sz < __min_cap)\n    {\n        __set_short_size(__sz);\n        __p = __get_short_pointer();\n    }\n    else\n    {\n        size_type __cap = __recommend(__sz);\n        __p = __alloc_traits::allocate(__alloc(), __cap+1);\n        __set_long_pointer(__p);\n        __set_long_cap(__cap+1);\n        __set_long_size(__sz);\n    }\n    traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz);\n    traits_type::assign(__p[__sz], value_type());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)\n{\n    _LIBCPP_ASSERT(__s != nullptr, \"basic_string(const char*) detected nullptr\");\n    __init(__s, traits_type::length(__s));\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, const allocator_type& __a)\n    : __r_(__a)\n{\n    _LIBCPP_ASSERT(__s != nullptr, \"basic_string(const char*, allocator) detected nullptr\");\n    __init(__s, traits_type::length(__s));\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n)\n{\n    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"basic_string(const char*, n) detected nullptr\");\n    __init(__s, __n);\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n, const allocator_type& __a)\n    : __r_(__a)\n{\n    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"basic_string(const char*, n, allocator) detected nullptr\");\n    __init(__s, __n);\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)\n    : __r_(__alloc_traits::select_on_container_copy_construction(__str.__alloc()))\n{\n    if (!__str.__is_long())\n        __r_.first().__r = __str.__r_.first().__r;\n    else\n        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, const allocator_type& __a)\n    : __r_(__a)\n{\n    if (!__str.__is_long())\n        __r_.first().__r = __str.__r_.first().__r;\n    else\n        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)\n#if _LIBCPP_STD_VER <= 14\n        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)\n#else\n        _NOEXCEPT\n#endif\n    : __r_(_VSTD::move(__str.__r_))\n{\n    __str.__zero();\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n    if (__is_long())\n        __get_db()->swap(this, &__str);\n#endif\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)\n    : __r_(__a)\n{\n    if (__str.__is_long() && __a != __str.__alloc()) // copy, not move\n        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());\n    else\n    {\n        __r_.first().__r = __str.__r_.first().__r;\n        __str.__zero();\n    }\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n    if (__is_long())\n        __get_db()->swap(this, &__str);\n#endif\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)\n{\n    if (__n > max_size())\n        this->__throw_length_error();\n    pointer __p;\n    if (__n < __min_cap)\n    {\n        __set_short_size(__n);\n        __p = __get_short_pointer();\n    }\n    else\n    {\n        size_type __cap = __recommend(__n);\n        __p = __alloc_traits::allocate(__alloc(), __cap+1);\n        __set_long_pointer(__p);\n        __set_long_cap(__cap+1);\n        __set_long_size(__n);\n    }\n    traits_type::assign(_VSTD::__to_raw_pointer(__p), __n, __c);\n    traits_type::assign(__p[__n], value_type());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c)\n{\n    __init(__n, __c);\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c, const allocator_type& __a)\n    : __r_(__a)\n{\n    __init(__n, __c);\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n,\n                                                        const allocator_type& __a)\n    : __r_(__a)\n{\n    size_type __str_sz = __str.size();\n    if (__pos > __str_sz)\n        this->__throw_out_of_range();\n    __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos));\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntemplate <class _InputIterator>\ntypename enable_if\n<\n     __is_input_iterator  <_InputIterator>::value &&\n    !__is_forward_iterator<_InputIterator>::value,\n    void\n>::type\nbasic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)\n{\n    __zero();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    for (; __first != __last; ++__first)\n        push_back(*__first);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        if (__is_long())\n            __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());\n        throw;\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntemplate <class _ForwardIterator>\ntypename enable_if\n<\n    __is_forward_iterator<_ForwardIterator>::value,\n    void\n>::type\nbasic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)\n{\n    size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last));\n    if (__sz > max_size())\n        this->__throw_length_error();\n    pointer __p;\n    if (__sz < __min_cap)\n    {\n        __set_short_size(__sz);\n        __p = __get_short_pointer();\n    }\n    else\n    {\n        size_type __cap = __recommend(__sz);\n        __p = __alloc_traits::allocate(__alloc(), __cap+1);\n        __set_long_pointer(__p);\n        __set_long_cap(__cap+1);\n        __set_long_size(__sz);\n    }\n    for (; __first != __last; ++__first, (void) ++__p)\n        traits_type::assign(*__p, *__first);\n    traits_type::assign(*__p, value_type());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntemplate<class _InputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last)\n{\n    __init(__first, __last);\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntemplate<class _InputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last,\n                                                        const allocator_type& __a)\n    : __r_(__a)\n{\n    __init(__first, __last);\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il)\n{\n    __init(__il.begin(), __il.end());\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il, const allocator_type& __a)\n    : __r_(__a)\n{\n    __init(__il.begin(), __il.end());\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>::~basic_string()\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__erase_c(this);\n#endif\n    if (__is_long())\n        __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace\n    (size_type __old_cap, size_type __delta_cap, size_type __old_sz,\n     size_type __n_copy,  size_type __n_del,     size_type __n_add, const value_type* __p_new_stuff)\n{\n    size_type __ms = max_size();\n    if (__delta_cap > __ms - __old_cap - 1)\n        this->__throw_length_error();\n    pointer __old_p = __get_pointer();\n    size_type __cap = __old_cap < __ms / 2 - __alignment ?\n                          __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :\n                          __ms - 1;\n    pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);\n    __invalidate_all_iterators();\n    if (__n_copy != 0)\n        traits_type::copy(_VSTD::__to_raw_pointer(__p),\n                          _VSTD::__to_raw_pointer(__old_p), __n_copy);\n    if (__n_add != 0)\n        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy, __p_new_stuff, __n_add);\n    size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;\n    if (__sec_cp_sz != 0)\n        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add,\n                          _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del, __sec_cp_sz);\n    if (__old_cap+1 != __min_cap)\n        __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);\n    __set_long_pointer(__p);\n    __set_long_cap(__cap+1);\n    __old_sz = __n_copy + __n_add + __sec_cp_sz;\n    __set_long_size(__old_sz);\n    traits_type::assign(__p[__old_sz], value_type());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,\n                                                     size_type __n_copy,  size_type __n_del,     size_type __n_add)\n{\n    size_type __ms = max_size();\n    if (__delta_cap > __ms - __old_cap)\n        this->__throw_length_error();\n    pointer __old_p = __get_pointer();\n    size_type __cap = __old_cap < __ms / 2 - __alignment ?\n                          __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :\n                          __ms - 1;\n    pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);\n    __invalidate_all_iterators();\n    if (__n_copy != 0)\n        traits_type::copy(_VSTD::__to_raw_pointer(__p),\n                          _VSTD::__to_raw_pointer(__old_p), __n_copy);\n    size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;\n    if (__sec_cp_sz != 0)\n        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add,\n                          _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del,\n                          __sec_cp_sz);\n    if (__old_cap+1 != __min_cap)\n        __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);\n    __set_long_pointer(__p);\n    __set_long_cap(__cap+1);\n}\n\n// assign\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)\n{\n    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string::assign received nullptr\");\n    size_type __cap = capacity();\n    if (__cap >= __n)\n    {\n        value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());\n        traits_type::move(__p, __s, __n);\n        traits_type::assign(__p[__n], value_type());\n        __set_size(__n);\n        __invalidate_iterators_past(__n);\n    }\n    else\n    {\n        size_type __sz = size();\n        __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s);\n    }\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)\n{\n    size_type __cap = capacity();\n    if (__cap < __n)\n    {\n        size_type __sz = size();\n        __grow_by(__cap, __n - __cap, __sz, 0, __sz);\n    }\n    else\n        __invalidate_iterators_past(__n);\n    value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());\n    traits_type::assign(__p, __n, __c);\n    traits_type::assign(__p[__n], value_type());\n    __set_size(__n);\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)\n{\n    pointer __p;\n    if (__is_long())\n    {\n        __p = __get_long_pointer();\n        __set_long_size(1);\n    }\n    else\n    {\n        __p = __get_short_pointer();\n        __set_short_size(1);\n    }\n    traits_type::assign(*__p, __c);\n    traits_type::assign(*++__p, value_type());\n    __invalidate_iterators_past(1);\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)\n{\n    if (this != &__str)\n    {\n        __copy_assign_alloc(__str);\n        assign(__str);\n    }\n    return *this;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)\n{\n    if (__alloc() != __str.__alloc())\n        assign(__str);\n    else\n        __move_assign(__str, true_type());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)\n    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)\n{\n    clear();\n    shrink_to_fit();\n    __r_.first() = __str.__r_.first();\n    __move_assign_alloc(__str);\n    __str.__zero();\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)\n    _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&\n               is_nothrow_move_assignable<allocator_type>::value)\n{\n    __move_assign(__str, integral_constant<bool,\n          __alloc_traits::propagate_on_container_move_assignment::value>());\n    return *this;\n}\n\n#endif\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntemplate<class _InputIterator>\ntypename enable_if\n<\n     __is_input_iterator  <_InputIterator>::value &&\n    !__is_forward_iterator<_InputIterator>::value,\n    basic_string<_CharT, _Traits, _Allocator>&\n>::type\nbasic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)\n{\n    clear();\n    for (; __first != __last; ++__first)\n        push_back(*__first);\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntemplate<class _ForwardIterator>\ntypename enable_if\n<\n    __is_forward_iterator<_ForwardIterator>::value,\n    basic_string<_CharT, _Traits, _Allocator>&\n>::type\nbasic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)\n{\n    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));\n    size_type __cap = capacity();\n    if (__cap < __n)\n    {\n        size_type __sz = size();\n        __grow_by(__cap, __n - __cap, __sz, 0, __sz);\n    }\n    else\n        __invalidate_iterators_past(__n);\n    pointer __p = __get_pointer();\n    for (; __first != __last; ++__first, ++__p)\n        traits_type::assign(*__p, *__first);\n    traits_type::assign(*__p, value_type());\n    __set_size(__n);\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str)\n{\n    return assign(__str.data(), __str.size());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n)\n{\n    size_type __sz = __str.size();\n    if (__pos > __sz)\n        this->__throw_out_of_range();\n    return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos));\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)\n{\n    _LIBCPP_ASSERT(__s != nullptr, \"string::assign received nullptr\");\n    return assign(__s, traits_type::length(__s));\n}\n\n// append\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)\n{\n    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string::append received nullptr\");\n    size_type __cap = capacity();\n    size_type __sz = size();\n    if (__cap - __sz >= __n)\n    {\n        if (__n)\n        {\n            value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());\n            traits_type::copy(__p + __sz, __s, __n);\n            __sz += __n;\n            __set_size(__sz);\n            traits_type::assign(__p[__sz], value_type());\n        }\n    }\n    else\n        __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s);\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)\n{\n    if (__n)\n    {\n        size_type __cap = capacity();\n        size_type __sz = size();\n        if (__cap - __sz < __n)\n            __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);\n        pointer __p = __get_pointer();\n        traits_type::assign(_VSTD::__to_raw_pointer(__p) + __sz, __n, __c);\n        __sz += __n;\n        __set_size(__sz);\n        traits_type::assign(__p[__sz], value_type());\n    }\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)\n{\n    bool __is_short = !__is_long();\n    size_type __cap;\n    size_type __sz;\n    if (__is_short)\n    {\n        __cap = __min_cap - 1;\n        __sz = __get_short_size();\n    }\n    else\n    {\n        __cap = __get_long_cap() - 1;\n        __sz = __get_long_size();\n    }\n    if (__sz == __cap)\n    {\n        __grow_by(__cap, 1, __sz, __sz, 0);\n        __is_short = !__is_long();\n    }\n    pointer __p;\n    if (__is_short)\n    {\n        __p = __get_short_pointer() + __sz;\n        __set_short_size(__sz+1);\n    }\n    else\n    {\n        __p = __get_long_pointer() + __sz;\n        __set_long_size(__sz+1);\n    }\n    traits_type::assign(*__p, __c);\n    traits_type::assign(*++__p, value_type());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntemplate<class _InputIterator>\ntypename enable_if\n<\n     __is_input_iterator  <_InputIterator>::value &&\n    !__is_forward_iterator<_InputIterator>::value,\n    basic_string<_CharT, _Traits, _Allocator>&\n>::type\nbasic_string<_CharT, _Traits, _Allocator>::append(_InputIterator __first, _InputIterator __last)\n{\n    for (; __first != __last; ++__first)\n        push_back(*__first);\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntemplate<class _ForwardIterator>\ntypename enable_if\n<\n    __is_forward_iterator<_ForwardIterator>::value,\n    basic_string<_CharT, _Traits, _Allocator>&\n>::type\nbasic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last)\n{\n    size_type __sz = size();\n    size_type __cap = capacity();\n    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));\n    if (__n)\n    {\n        if (__cap - __sz < __n)\n            __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);\n        pointer __p = __get_pointer() + __sz;\n        for (; __first != __last; ++__p, ++__first)\n            traits_type::assign(*__p, *__first);\n        traits_type::assign(*__p, value_type());\n        __set_size(__sz + __n);\n    }\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str)\n{\n    return append(__str.data(), __str.size());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n)\n{\n    size_type __sz = __str.size();\n    if (__pos > __sz)\n        this->__throw_out_of_range();\n    return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos));\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)\n{\n    _LIBCPP_ASSERT(__s != nullptr, \"string::append received nullptr\");\n    return append(__s, traits_type::length(__s));\n}\n\n// insert\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)\n{\n    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string::insert received nullptr\");\n    size_type __sz = size();\n    if (__pos > __sz)\n        this->__throw_out_of_range();\n    size_type __cap = capacity();\n    if (__cap - __sz >= __n)\n    {\n        if (__n)\n        {\n            value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());\n            size_type __n_move = __sz - __pos;\n            if (__n_move != 0)\n            {\n                if (__p + __pos <= __s && __s < __p + __sz)\n                    __s += __n;\n                traits_type::move(__p + __pos + __n, __p + __pos, __n_move);\n            }\n            traits_type::move(__p + __pos, __s, __n);\n            __sz += __n;\n            __set_size(__sz);\n            traits_type::assign(__p[__sz], value_type());\n        }\n    }\n    else\n        __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c)\n{\n    size_type __sz = size();\n    if (__pos > __sz)\n        this->__throw_out_of_range();\n    if (__n)\n    {\n        size_type __cap = capacity();\n        value_type* __p;\n        if (__cap - __sz >= __n)\n        {\n            __p = _VSTD::__to_raw_pointer(__get_pointer());\n            size_type __n_move = __sz - __pos;\n            if (__n_move != 0)\n                traits_type::move(__p + __pos + __n, __p + __pos, __n_move);\n        }\n        else\n        {\n            __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);\n            __p = _VSTD::__to_raw_pointer(__get_long_pointer());\n        }\n        traits_type::assign(__p + __pos, __n, __c);\n        __sz += __n;\n        __set_size(__sz);\n        traits_type::assign(__p[__sz], value_type());\n    }\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntemplate<class _InputIterator>\ntypename enable_if\n<\n     __is_input_iterator  <_InputIterator>::value &&\n    !__is_forward_iterator<_InputIterator>::value,\n    typename basic_string<_CharT, _Traits, _Allocator>::iterator\n>::type\nbasic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,\n        \"string::insert(iterator, range) called with an iterator not\"\n        \" referring to this string\");\n#endif\n    size_type __old_sz = size();\n    difference_type __ip = __pos - begin();\n    for (; __first != __last; ++__first)\n        push_back(*__first);\n    pointer __p = __get_pointer();\n    _VSTD::rotate(__p + __ip, __p + __old_sz, __p + size());\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return iterator(this, __p + __ip);\n#else\n    return iterator(__p + __ip);\n#endif\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntemplate<class _ForwardIterator>\ntypename enable_if\n<\n    __is_forward_iterator<_ForwardIterator>::value,\n    typename basic_string<_CharT, _Traits, _Allocator>::iterator\n>::type\nbasic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,\n        \"string::insert(iterator, range) called with an iterator not\"\n        \" referring to this string\");\n#endif\n    size_type __ip = static_cast<size_type>(__pos - begin());\n    size_type __sz = size();\n    size_type __cap = capacity();\n    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));\n    if (__n)\n    {\n        value_type* __p;\n        if (__cap - __sz >= __n)\n        {\n            __p = _VSTD::__to_raw_pointer(__get_pointer());\n            size_type __n_move = __sz - __ip;\n            if (__n_move != 0)\n                traits_type::move(__p + __ip + __n, __p + __ip, __n_move);\n        }\n        else\n        {\n            __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);\n            __p = _VSTD::__to_raw_pointer(__get_long_pointer());\n        }\n        __sz += __n;\n        __set_size(__sz);\n        traits_type::assign(__p[__sz], value_type());\n        for (__p += __ip; __first != __last; ++__p, ++__first)\n            traits_type::assign(*__p, *__first);\n    }\n    return begin() + __ip;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str)\n{\n    return insert(__pos1, __str.data(), __str.size());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str,\n                                                  size_type __pos2, size_type __n)\n{\n    size_type __str_sz = __str.size();\n    if (__pos2 > __str_sz)\n        this->__throw_out_of_range();\n    return insert(__pos1, __str.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2));\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)\n{\n    _LIBCPP_ASSERT(__s != nullptr, \"string::insert received nullptr\");\n    return insert(__pos, __s, traits_type::length(__s));\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntypename basic_string<_CharT, _Traits, _Allocator>::iterator\nbasic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)\n{\n    size_type __ip = static_cast<size_type>(__pos - begin());\n    size_type __sz = size();\n    size_type __cap = capacity();\n    value_type* __p;\n    if (__cap == __sz)\n    {\n        __grow_by(__cap, 1, __sz, __ip, 0, 1);\n        __p = _VSTD::__to_raw_pointer(__get_long_pointer());\n    }\n    else\n    {\n        __p = _VSTD::__to_raw_pointer(__get_pointer());\n        size_type __n_move = __sz - __ip;\n        if (__n_move != 0)\n            traits_type::move(__p + __ip + 1, __p + __ip, __n_move);\n    }\n    traits_type::assign(__p[__ip], __c);\n    traits_type::assign(__p[++__sz], value_type());\n    __set_size(__sz);\n    return begin() + static_cast<difference_type>(__ip);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::iterator\nbasic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,\n        \"string::insert(iterator, n, value) called with an iterator not\"\n        \" referring to this string\");\n#endif\n    difference_type __p = __pos - begin();\n    insert(static_cast<size_type>(__p), __n, __c);\n    return begin() + __p;\n}\n\n// replace\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)\n{\n    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, \"string::replace received nullptr\");\n    size_type __sz = size();\n    if (__pos > __sz)\n        this->__throw_out_of_range();\n    __n1 = _VSTD::min(__n1, __sz - __pos);\n    size_type __cap = capacity();\n    if (__cap - __sz + __n1 >= __n2)\n    {\n        value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());\n        if (__n1 != __n2)\n        {\n            size_type __n_move = __sz - __pos - __n1;\n            if (__n_move != 0)\n            {\n                if (__n1 > __n2)\n                {\n                    traits_type::move(__p + __pos, __s, __n2);\n                    traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);\n                    goto __finish;\n                }\n                if (__p + __pos < __s && __s < __p + __sz)\n                {\n                    if (__p + __pos + __n1 <= __s)\n                        __s += __n2 - __n1;\n                    else // __p + __pos < __s < __p + __pos + __n1\n                    {\n                        traits_type::move(__p + __pos, __s, __n1);\n                        __pos += __n1;\n                        __s += __n2;\n                        __n2 -= __n1;\n                        __n1 = 0;\n                    }\n                }\n                traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);\n            }\n        }\n        traits_type::move(__p + __pos, __s, __n2);\n__finish:\n        __sz += __n2 - __n1;\n        __set_size(__sz);\n        __invalidate_iterators_past(__sz);\n        traits_type::assign(__p[__sz], value_type());\n    }\n    else\n        __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c)\n{\n    size_type __sz = size();\n    if (__pos > __sz)\n        this->__throw_out_of_range();\n    __n1 = _VSTD::min(__n1, __sz - __pos);\n    size_type __cap = capacity();\n    value_type* __p;\n    if (__cap - __sz + __n1 >= __n2)\n    {\n        __p = _VSTD::__to_raw_pointer(__get_pointer());\n        if (__n1 != __n2)\n        {\n            size_type __n_move = __sz - __pos - __n1;\n            if (__n_move != 0)\n                traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);\n        }\n    }\n    else\n    {\n        __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);\n        __p = _VSTD::__to_raw_pointer(__get_long_pointer());\n    }\n    traits_type::assign(__p + __pos, __n2, __c);\n    __sz += __n2 - __n1;\n    __set_size(__sz);\n    __invalidate_iterators_past(__sz);\n    traits_type::assign(__p[__sz], value_type());\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntemplate<class _InputIterator>\ntypename enable_if\n<\n    __is_input_iterator<_InputIterator>::value,\n    basic_string<_CharT, _Traits, _Allocator>&\n>::type\nbasic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,\n                                                   _InputIterator __j1, _InputIterator __j2)\n{\n    for (; true; ++__i1, ++__j1)\n    {\n        if (__i1 == __i2)\n        {\n            if (__j1 != __j2)\n                insert(__i1, __j1, __j2);\n            break;\n        }\n        if (__j1 == __j2)\n        {\n            erase(__i1, __i2);\n            break;\n        }\n        traits_type::assign(const_cast<value_type&>(*__i1), *__j1);\n    }\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str)\n{\n    return replace(__pos1, __n1, __str.data(), __str.size());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str,\n                                                   size_type __pos2, size_type __n2)\n{\n    size_type __str_sz = __str.size();\n    if (__pos2 > __str_sz)\n        this->__throw_out_of_range();\n    return replace(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2));\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)\n{\n    _LIBCPP_ASSERT(__s != nullptr, \"string::replace received nullptr\");\n    return replace(__pos, __n1, __s, traits_type::length(__s));\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str)\n{\n    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1),\n                   __str.data(), __str.size());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n)\n{\n    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s)\n{\n    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c)\n{\n    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c);\n}\n\n// erase\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>&\nbasic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n)\n{\n    size_type __sz = size();\n    if (__pos > __sz)\n        this->__throw_out_of_range();\n    if (__n)\n    {\n        value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());\n        __n = _VSTD::min(__n, __sz - __pos);\n        size_type __n_move = __sz - __pos - __n;\n        if (__n_move != 0)\n            traits_type::move(__p + __pos, __p + __pos + __n, __n_move);\n        __sz -= __n;\n        __set_size(__sz);\n        __invalidate_iterators_past(__sz);\n        traits_type::assign(__p[__sz], value_type());\n    }\n    return *this;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::iterator\nbasic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,\n        \"string::erase(iterator) called with an iterator not\"\n        \" referring to this string\");\n#endif\n    _LIBCPP_ASSERT(__pos != end(),\n        \"string::erase(iterator) called with a non-dereferenceable iterator\");\n    iterator __b = begin();\n    size_type __r = static_cast<size_type>(__pos - __b);\n    erase(__r, 1);\n    return __b + static_cast<difference_type>(__r);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::iterator\nbasic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,\n        \"string::erase(iterator,  iterator) called with an iterator not\"\n        \" referring to this string\");\n#endif\n    _LIBCPP_ASSERT(__first <= __last, \"string::erase(first, last) called with invalid range\");\n    iterator __b = begin();\n    size_type __r = static_cast<size_type>(__first - __b);\n    erase(__r, static_cast<size_type>(__last - __first));\n    return __b + static_cast<difference_type>(__r);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::pop_back()\n{\n    _LIBCPP_ASSERT(!empty(), \"string::pop_back(): string is already empty\");\n    size_type __sz;\n    if (__is_long())\n    {\n        __sz = __get_long_size() - 1;\n        __set_long_size(__sz);\n        traits_type::assign(*(__get_long_pointer() + __sz), value_type());\n    }\n    else\n    {\n        __sz = __get_short_size() - 1;\n        __set_short_size(__sz);\n        traits_type::assign(*(__get_short_pointer() + __sz), value_type());\n    }\n    __invalidate_iterators_past(__sz);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT\n{\n    __invalidate_all_iterators();\n    if (__is_long())\n    {\n        traits_type::assign(*__get_long_pointer(), value_type());\n        __set_long_size(0);\n    }\n    else\n    {\n        traits_type::assign(*__get_short_pointer(), value_type());\n        __set_short_size(0);\n    }\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos)\n{\n    if (__is_long())\n    {\n        traits_type::assign(*(__get_long_pointer() + __pos), value_type());\n        __set_long_size(__pos);\n    }\n    else\n    {\n        traits_type::assign(*(__get_short_pointer() + __pos), value_type());\n        __set_short_size(__pos);\n    }\n    __invalidate_iterators_past(__pos);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c)\n{\n    size_type __sz = size();\n    if (__n > __sz)\n        append(__n - __sz, __c);\n    else\n        __erase_to_end(__n);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT\n{\n    size_type __m = __alloc_traits::max_size(__alloc());\n#if _LIBCPP_BIG_ENDIAN\n    return (__m <= ~__long_mask ? __m : __m/2) - __alignment;\n#else\n    return __m - __alignment;\n#endif\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::reserve(size_type __res_arg)\n{\n    if (__res_arg > max_size())\n        this->__throw_length_error();\n    size_type __cap = capacity();\n    size_type __sz = size();\n    __res_arg = _VSTD::max(__res_arg, __sz);\n    __res_arg = __recommend(__res_arg);\n    if (__res_arg != __cap)\n    {\n        pointer __new_data, __p;\n        bool __was_long, __now_long;\n        if (__res_arg == __min_cap - 1)\n        {\n            __was_long = true;\n            __now_long = false;\n            __new_data = __get_short_pointer();\n            __p = __get_long_pointer();\n        }\n        else\n        {\n            if (__res_arg > __cap)\n                __new_data = __alloc_traits::allocate(__alloc(), __res_arg+1);\n            else\n            {\n            #ifndef _LIBCPP_NO_EXCEPTIONS\n                try\n                {\n            #endif  // _LIBCPP_NO_EXCEPTIONS\n                    __new_data = __alloc_traits::allocate(__alloc(), __res_arg+1);\n            #ifndef _LIBCPP_NO_EXCEPTIONS\n                }\n                catch (...)\n                {\n                    return;\n                }\n            #else  // _LIBCPP_NO_EXCEPTIONS\n                if (__new_data == nullptr)\n                    return;\n            #endif  // _LIBCPP_NO_EXCEPTIONS\n            }\n            __now_long = true;\n            __was_long = __is_long();\n            __p = __get_pointer();\n        }\n        traits_type::copy(_VSTD::__to_raw_pointer(__new_data),\n                          _VSTD::__to_raw_pointer(__p), size()+1);\n        if (__was_long)\n            __alloc_traits::deallocate(__alloc(), __p, __cap+1);\n        if (__now_long)\n        {\n            __set_long_cap(__res_arg+1);\n            __set_long_size(__sz);\n            __set_long_pointer(__new_data);\n        }\n        else\n            __set_short_size(__sz);\n        __invalidate_all_iterators();\n    }\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::const_reference\nbasic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const\n{\n    _LIBCPP_ASSERT(__pos <= size(), \"string index out of bounds\");\n    return *(data() + __pos);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::reference\nbasic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos)\n{\n    _LIBCPP_ASSERT(__pos <= size(), \"string index out of bounds\");\n    return *(__get_pointer() + __pos);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntypename basic_string<_CharT, _Traits, _Allocator>::const_reference\nbasic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const\n{\n    if (__n >= size())\n        this->__throw_out_of_range();\n    return (*this)[__n];\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntypename basic_string<_CharT, _Traits, _Allocator>::reference\nbasic_string<_CharT, _Traits, _Allocator>::at(size_type __n)\n{\n    if (__n >= size())\n        this->__throw_out_of_range();\n    return (*this)[__n];\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::reference\nbasic_string<_CharT, _Traits, _Allocator>::front()\n{\n    _LIBCPP_ASSERT(!empty(), \"string::front(): string is empty\");\n    return *__get_pointer();\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::const_reference\nbasic_string<_CharT, _Traits, _Allocator>::front() const\n{\n    _LIBCPP_ASSERT(!empty(), \"string::front(): string is empty\");\n    return *data();\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::reference\nbasic_string<_CharT, _Traits, _Allocator>::back()\n{\n    _LIBCPP_ASSERT(!empty(), \"string::back(): string is empty\");\n    return *(__get_pointer() + size() - 1);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::const_reference\nbasic_string<_CharT, _Traits, _Allocator>::back() const\n{\n    _LIBCPP_ASSERT(!empty(), \"string::back(): string is empty\");\n    return *(data() + size() - 1);\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const\n{\n    size_type __sz = size();\n    if (__pos > __sz)\n        this->__throw_out_of_range();\n    size_type __rlen = _VSTD::min(__n, __sz - __pos);\n    traits_type::copy(__s, data() + __pos, __rlen);\n    return __rlen;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const\n{\n    return basic_string(*this, __pos, __n, __alloc());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nbasic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)\n#if _LIBCPP_STD_VER >= 14\n        _NOEXCEPT\n#else\n        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || \n                    __is_nothrow_swappable<allocator_type>::value)\n#endif\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    if (!__is_long())\n        __get_db()->__invalidate_all(this);\n    if (!__str.__is_long())\n        __get_db()->__invalidate_all(&__str);\n    __get_db()->swap(this, &__str);\n#endif\n    _VSTD::swap(__r_.first(), __str.__r_.first());\n    __swap_allocator(__alloc(), __str.__alloc());\n}\n\n// find\n\ntemplate <class _Traits>\nstruct _LIBCPP_HIDDEN __traits_eq\n{\n    typedef typename _Traits::char_type char_type;\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT\n        {return _Traits::eq(__x, __y);}\n};\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,\n                                                size_type __pos,\n                                                size_type __n) const _NOEXCEPT\n{\n    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string::find(): received nullptr\");\n    return _VSTD::__str_find<value_type, size_type, traits_type, npos>\n        (data(), size(), __s, __pos, __n);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,\n                                                size_type __pos) const _NOEXCEPT\n{\n    return _VSTD::__str_find<value_type, size_type, traits_type, npos>\n        (data(), size(), __str.data(), __pos, __str.size());\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,\n                                                size_type __pos) const _NOEXCEPT\n{\n    _LIBCPP_ASSERT(__s != nullptr, \"string::find(): received nullptr\");\n    return _VSTD::__str_find<value_type, size_type, traits_type, npos>\n        (data(), size(), __s, __pos, traits_type::length(__s));\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find(value_type __c,\n                                                size_type __pos) const _NOEXCEPT\n{\n    return _VSTD::__str_find<value_type, size_type, traits_type, npos>\n        (data(), size(), __c, __pos);\n}\n\n// rfind\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,\n                                                 size_type __pos,\n                                                 size_type __n) const _NOEXCEPT\n{\n    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string::rfind(): received nullptr\");\n    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>\n        (data(), size(), __s, __pos, __n);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,\n                                                 size_type __pos) const _NOEXCEPT\n{\n    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>\n        (data(), size(), __str.data(), __pos, __str.size());\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,\n                                                 size_type __pos) const _NOEXCEPT\n{\n    _LIBCPP_ASSERT(__s != nullptr, \"string::rfind(): received nullptr\");\n    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>\n        (data(), size(), __s, __pos, traits_type::length(__s));\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c,\n                                                 size_type __pos) const _NOEXCEPT\n{\n    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>\n        (data(), size(), __c, __pos);\n}\n\n// find_first_of\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,\n                                                         size_type __pos,\n                                                         size_type __n) const _NOEXCEPT\n{\n    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string::find_first_of(): received nullptr\");\n    return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>\n        (data(), size(), __s, __pos, __n);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,\n                                                         size_type __pos) const _NOEXCEPT\n{\n    return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>\n        (data(), size(), __str.data(), __pos, __str.size());\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,\n                                                         size_type __pos) const _NOEXCEPT\n{\n    _LIBCPP_ASSERT(__s != nullptr, \"string::find_first_of(): received nullptr\");\n    return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>\n        (data(), size(), __s, __pos, traits_type::length(__s));\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c,\n                                                         size_type __pos) const _NOEXCEPT\n{\n    return find(__c, __pos);\n}\n\n// find_last_of\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,\n                                                        size_type __pos,\n                                                        size_type __n) const _NOEXCEPT\n{\n    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string::find_last_of(): received nullptr\");\n    return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>\n        (data(), size(), __s, __pos, __n);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,\n                                                        size_type __pos) const _NOEXCEPT\n{\n    return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>\n        (data(), size(), __str.data(), __pos, __str.size());\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,\n                                                        size_type __pos) const _NOEXCEPT\n{\n    _LIBCPP_ASSERT(__s != nullptr, \"string::find_last_of(): received nullptr\");\n    return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>\n        (data(), size(), __s, __pos, traits_type::length(__s));\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c,\n                                                        size_type __pos) const _NOEXCEPT\n{\n    return rfind(__c, __pos);\n}\n\n// find_first_not_of\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,\n                                                             size_type __pos,\n                                                             size_type __n) const _NOEXCEPT\n{\n    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string::find_first_not_of(): received nullptr\");\n    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>\n        (data(), size(), __s, __pos, __n);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,\n                                                             size_type __pos) const _NOEXCEPT\n{\n    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>\n        (data(), size(), __str.data(), __pos, __str.size());\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,\n                                                             size_type __pos) const _NOEXCEPT\n{\n    _LIBCPP_ASSERT(__s != nullptr, \"string::find_first_not_of(): received nullptr\");\n    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>\n        (data(), size(), __s, __pos, traits_type::length(__s));\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,\n                                                             size_type __pos) const _NOEXCEPT\n{\n    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>\n        (data(), size(), __c, __pos);\n}\n\n// find_last_not_of\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,\n                                                            size_type __pos,\n                                                            size_type __n) const _NOEXCEPT\n{\n    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, \"string::find_last_not_of(): received nullptr\");\n    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>\n        (data(), size(), __s, __pos, __n);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,\n                                                            size_type __pos) const _NOEXCEPT\n{\n    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>\n        (data(), size(), __str.data(), __pos, __str.size());\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,\n                                                            size_type __pos) const _NOEXCEPT\n{\n    _LIBCPP_ASSERT(__s != nullptr, \"string::find_last_not_of(): received nullptr\");\n    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>\n        (data(), size(), __s, __pos, traits_type::length(__s));\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename basic_string<_CharT, _Traits, _Allocator>::size_type\nbasic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,\n                                                            size_type __pos) const _NOEXCEPT\n{\n    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>\n        (data(), size(), __c, __pos);\n}\n\n// compare\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nint\nbasic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT\n{\n    size_t __lhs_sz = size();\n    size_t __rhs_sz = __str.size();\n    int __result = traits_type::compare(data(), __str.data(),\n                                        _VSTD::min(__lhs_sz, __rhs_sz));\n    if (__result != 0)\n        return __result;\n    if (__lhs_sz < __rhs_sz)\n        return -1;\n    if (__lhs_sz > __rhs_sz)\n        return 1;\n    return 0;\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nint\nbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,\n                                                   size_type __n1,\n                                                   const basic_string& __str) const\n{\n    return compare(__pos1, __n1, __str.data(), __str.size());\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nint\nbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,\n                                                   size_type __n1,\n                                                   const basic_string& __str,\n                                                   size_type __pos2,\n                                                   size_type __n2) const\n{\n    size_type __sz = __str.size();\n    if (__pos2 > __sz)\n        this->__throw_out_of_range();\n    return compare(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2,\n                                                                  __sz - __pos2));\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nint\nbasic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT\n{\n    _LIBCPP_ASSERT(__s != nullptr, \"string::compare(): received nullptr\");\n    return compare(0, npos, __s, traits_type::length(__s));\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nint\nbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,\n                                                   size_type __n1,\n                                                   const value_type* __s) const\n{\n    _LIBCPP_ASSERT(__s != nullptr, \"string::compare(): received nullptr\");\n    return compare(__pos1, __n1, __s, traits_type::length(__s));\n}\n\ntemplate <class _CharT, class _Traits, class _Allocator>\nint\nbasic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,\n                                                   size_type __n1,\n                                                   const value_type* __s,\n                                                   size_type __n2) const\n{\n    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, \"string::compare(): received nullptr\");\n    size_type __sz = size();\n    if (__pos1 > __sz || __n2 == npos)\n        this->__throw_out_of_range();\n    size_type __rlen = _VSTD::min(__n1, __sz - __pos1);\n    int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2));\n    if (__r == 0)\n    {\n        if (__rlen < __n2)\n            __r = -1;\n        else if (__rlen > __n2)\n            __r = 1;\n    }\n    return __r;\n}\n\n// __invariants\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\nbasic_string<_CharT, _Traits, _Allocator>::__invariants() const\n{\n    if (size() > capacity())\n        return false;\n    if (capacity() < __min_cap - 1)\n        return false;\n    if (data() == 0)\n        return false;\n    if (data()[size()] != value_type(0))\n        return false;\n    return true;\n}\n\n// operator==\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,\n           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT\n{\n    size_t __lhs_sz = __lhs.size();\n    return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(),\n                                                        __rhs.data(),\n                                                        __lhs_sz) == 0;\n}\n\ntemplate<class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,\n           const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT\n{\n    size_t __lhs_sz = __lhs.size();\n    if (__lhs_sz != __rhs.size())\n        return false;\n    const char* __lp = __lhs.data();\n    const char* __rp = __rhs.data();\n    if (__lhs.__is_long())\n        return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0;\n    for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp)\n        if (*__lp != *__rp)\n            return false;\n    return true;\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const _CharT* __lhs,\n           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT\n{\n    return __rhs.compare(__lhs) == 0;\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,\n           const _CharT* __rhs) _NOEXCEPT\n{\n    return __lhs.compare(__rhs) == 0;\n}\n\n// operator!=\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,\n           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT\n{\n    return !(__lhs == __rhs);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const _CharT* __lhs,\n           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT\n{\n    return !(__lhs == __rhs);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,\n           const _CharT* __rhs) _NOEXCEPT\n{\n    return !(__lhs == __rhs);\n}\n\n// operator<\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,\n           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT\n{\n    return __lhs.compare(__rhs) < 0;\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,\n           const _CharT* __rhs) _NOEXCEPT\n{\n    return __lhs.compare(__rhs) < 0;\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const _CharT* __lhs,\n           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT\n{\n    return __rhs.compare(__lhs) > 0;\n}\n\n// operator>\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,\n           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT\n{\n    return __rhs < __lhs;\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,\n           const _CharT* __rhs) _NOEXCEPT\n{\n    return __rhs < __lhs;\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator> (const _CharT* __lhs,\n           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT\n{\n    return __rhs < __lhs;\n}\n\n// operator<=\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,\n           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT\n{\n    return !(__rhs < __lhs);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,\n           const _CharT* __rhs) _NOEXCEPT\n{\n    return !(__rhs < __lhs);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const _CharT* __lhs,\n           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT\n{\n    return !(__rhs < __lhs);\n}\n\n// operator>=\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,\n           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT\n{\n    return !(__lhs < __rhs);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,\n           const _CharT* __rhs) _NOEXCEPT\n{\n    return !(__lhs < __rhs);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const _CharT* __lhs,\n           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT\n{\n    return !(__lhs < __rhs);\n}\n\n// operator +\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,\n          const basic_string<_CharT, _Traits, _Allocator>& __rhs)\n{\n    basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());\n    typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();\n    typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();\n    __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);\n    __r.append(__rhs.data(), __rhs_sz);\n    return __r;\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs)\n{\n    basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());\n    typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = _Traits::length(__lhs);\n    typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();\n    __r.__init(__lhs, __lhs_sz, __lhs_sz + __rhs_sz);\n    __r.append(__rhs.data(), __rhs_sz);\n    return __r;\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs)\n{\n    basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());\n    typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();\n    __r.__init(&__lhs, 1, 1 + __rhs_sz);\n    __r.append(__rhs.data(), __rhs_sz);\n    return __r;\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)\n{\n    basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());\n    typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();\n    typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = _Traits::length(__rhs);\n    __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);\n    __r.append(__rhs, __rhs_sz);\n    return __r;\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs)\n{\n    basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());\n    typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();\n    __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + 1);\n    __r.push_back(__rhs);\n    return __r;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)\n{\n    return _VSTD::move(__lhs.append(__rhs));\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)\n{\n    return _VSTD::move(__rhs.insert(0, __lhs));\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)\n{\n    return _VSTD::move(__lhs.append(__rhs));\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs)\n{\n    return _VSTD::move(__rhs.insert(0, __lhs));\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs)\n{\n    __rhs.insert(__rhs.begin(), __lhs);\n    return _VSTD::move(__rhs);\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs)\n{\n    return _VSTD::move(__lhs.append(__rhs));\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_string<_CharT, _Traits, _Allocator>\noperator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)\n{\n    __lhs.push_back(__rhs);\n    return _VSTD::move(__lhs);\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n// swap\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(basic_string<_CharT, _Traits, _Allocator>& __lhs,\n     basic_string<_CharT, _Traits, _Allocator>& __rhs)\n     _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs)))\n{\n    __lhs.swap(__rhs);\n}\n\n#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS\n\ntypedef basic_string<char16_t> u16string;\ntypedef basic_string<char32_t> u32string;\n\n#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS\n\n_LIBCPP_FUNC_VIS int                stoi  (const string& __str, size_t* __idx = 0, int __base = 10);\n_LIBCPP_FUNC_VIS long               stol  (const string& __str, size_t* __idx = 0, int __base = 10);\n_LIBCPP_FUNC_VIS unsigned long      stoul (const string& __str, size_t* __idx = 0, int __base = 10);\n_LIBCPP_FUNC_VIS long long          stoll (const string& __str, size_t* __idx = 0, int __base = 10);\n_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = 0, int __base = 10);\n\n_LIBCPP_FUNC_VIS float       stof (const string& __str, size_t* __idx = 0);\n_LIBCPP_FUNC_VIS double      stod (const string& __str, size_t* __idx = 0);\n_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = 0);\n\n_LIBCPP_FUNC_VIS string to_string(int __val);\n_LIBCPP_FUNC_VIS string to_string(unsigned __val);\n_LIBCPP_FUNC_VIS string to_string(long __val);\n_LIBCPP_FUNC_VIS string to_string(unsigned long __val);\n_LIBCPP_FUNC_VIS string to_string(long long __val);\n_LIBCPP_FUNC_VIS string to_string(unsigned long long __val);\n_LIBCPP_FUNC_VIS string to_string(float __val);\n_LIBCPP_FUNC_VIS string to_string(double __val);\n_LIBCPP_FUNC_VIS string to_string(long double __val);\n\n_LIBCPP_FUNC_VIS int                stoi  (const wstring& __str, size_t* __idx = 0, int __base = 10);\n_LIBCPP_FUNC_VIS long               stol  (const wstring& __str, size_t* __idx = 0, int __base = 10);\n_LIBCPP_FUNC_VIS unsigned long      stoul (const wstring& __str, size_t* __idx = 0, int __base = 10);\n_LIBCPP_FUNC_VIS long long          stoll (const wstring& __str, size_t* __idx = 0, int __base = 10);\n_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = 0, int __base = 10);\n\n_LIBCPP_FUNC_VIS float       stof (const wstring& __str, size_t* __idx = 0);\n_LIBCPP_FUNC_VIS double      stod (const wstring& __str, size_t* __idx = 0);\n_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = 0);\n\n_LIBCPP_FUNC_VIS wstring to_wstring(int __val);\n_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val);\n_LIBCPP_FUNC_VIS wstring to_wstring(long __val);\n_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val);\n_LIBCPP_FUNC_VIS wstring to_wstring(long long __val);\n_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val);\n_LIBCPP_FUNC_VIS wstring to_wstring(float __val);\n_LIBCPP_FUNC_VIS wstring to_wstring(double __val);\n_LIBCPP_FUNC_VIS wstring to_wstring(long double __val);\n\ntemplate<class _CharT, class _Traits, class _Allocator>\n    const typename basic_string<_CharT, _Traits, _Allocator>::size_type\n                   basic_string<_CharT, _Traits, _Allocator>::npos;\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<basic_string<_CharT, _Traits, _Allocator> >\n    : public unary_function<basic_string<_CharT, _Traits, _Allocator>, size_t>\n{\n    size_t\n        operator()(const basic_string<_CharT, _Traits, _Allocator>& __val) const _NOEXCEPT;\n};\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nsize_t\nhash<basic_string<_CharT, _Traits, _Allocator> >::operator()(\n        const basic_string<_CharT, _Traits, _Allocator>& __val) const _NOEXCEPT\n{\n    return __do_string_hash(__val.data(), __val.data() + __val.size());\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_ostream<_CharT, _Traits>&\noperator<<(basic_ostream<_CharT, _Traits>& __os,\n           const basic_string<_CharT, _Traits, _Allocator>& __str);\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_istream<_CharT, _Traits>&\noperator>>(basic_istream<_CharT, _Traits>& __is,\n           basic_string<_CharT, _Traits, _Allocator>& __str);\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbasic_istream<_CharT, _Traits>&\ngetline(basic_istream<_CharT, _Traits>& __is,\n        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\ngetline(basic_istream<_CharT, _Traits>& __is,\n        basic_string<_CharT, _Traits, _Allocator>& __str);\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\ngetline(basic_istream<_CharT, _Traits>&& __is,\n        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);\n\ntemplate<class _CharT, class _Traits, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbasic_istream<_CharT, _Traits>&\ngetline(basic_istream<_CharT, _Traits>&& __is,\n        basic_string<_CharT, _Traits, _Allocator>& __str);\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbool\nbasic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const\n{\n    return this->data() <= _VSTD::__to_raw_pointer(__i->base()) &&\n           _VSTD::__to_raw_pointer(__i->base()) < this->data() + this->size();\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbool\nbasic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const\n{\n    return this->data() < _VSTD::__to_raw_pointer(__i->base()) &&\n           _VSTD::__to_raw_pointer(__i->base()) <= this->data() + this->size();\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbool\nbasic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const\n{\n    const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n;\n    return this->data() <= __p && __p <= this->data() + this->size();\n}\n\ntemplate<class _CharT, class _Traits, class _Allocator>\nbool\nbasic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const\n{\n    const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n;\n    return this->data() <= __p && __p < this->data() + this->size();\n}\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\n#if _LIBCPP_STD_VER > 11 \n// Literal suffixes for basic_string [basic.string.literals]\ninline namespace literals\n{\n  inline namespace string_literals\n  {\n    inline _LIBCPP_INLINE_VISIBILITY\n    basic_string<char> operator \"\" s( const char *__str, size_t __len )\n    {\n        return basic_string<char> (__str, __len);\n    }\n\n    inline _LIBCPP_INLINE_VISIBILITY\n    basic_string<wchar_t> operator \"\" s( const wchar_t *__str, size_t __len )\n    {\n        return basic_string<wchar_t> (__str, __len);\n    }\n\n    inline _LIBCPP_INLINE_VISIBILITY\n    basic_string<char16_t> operator \"\" s( const char16_t *__str, size_t __len )\n    {\n        return basic_string<char16_t> (__str, __len);\n    }\n\n    inline _LIBCPP_INLINE_VISIBILITY\n    basic_string<char32_t> operator \"\" s( const char32_t *__str, size_t __len )\n    {\n        return basic_string<char32_t> (__str, __len);\n    }\n  }\n}\n#endif\n\n_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<char>)\n_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<wchar_t>)\n_LIBCPP_EXTERN_TEMPLATE(string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&))\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_STRING\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/strstream",
    "content": "// -*- C++ -*-\n//===--------------------------- strstream --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_STRSTREAM\n#define _LIBCPP_STRSTREAM\n\n/*\n    strstream synopsis\n\nclass strstreambuf\n    : public basic_streambuf<char>\n{\npublic:\n    explicit strstreambuf(streamsize alsize_arg = 0);\n    strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*));\n    strstreambuf(char* gnext_arg, streamsize n, char* pbeg_arg = 0);\n    strstreambuf(const char* gnext_arg, streamsize n);\n\n    strstreambuf(signed char* gnext_arg, streamsize n, signed char* pbeg_arg = 0);\n    strstreambuf(const signed char* gnext_arg, streamsize n);\n    strstreambuf(unsigned char* gnext_arg, streamsize n, unsigned char* pbeg_arg = 0);\n    strstreambuf(const unsigned char* gnext_arg, streamsize n);\n\n    strstreambuf(strstreambuf&& rhs);\n    strstreambuf& operator=(strstreambuf&& rhs);\n\n    virtual ~strstreambuf();\n\n    void swap(strstreambuf& rhs);\n\n    void freeze(bool freezefl = true);\n    char* str();\n    int pcount() const;\n\nprotected:\n    virtual int_type overflow (int_type c = EOF);\n    virtual int_type pbackfail(int_type c = EOF);\n    virtual int_type underflow();\n    virtual pos_type seekoff(off_type off, ios_base::seekdir way,\n                             ios_base::openmode which = ios_base::in | ios_base::out);\n    virtual pos_type seekpos(pos_type sp,\n                             ios_base::openmode which = ios_base::in | ios_base::out);\n    virtual streambuf* setbuf(char* s, streamsize n);\n\nprivate:\n    typedef T1 strstate;                // exposition only\n    static const strstate allocated;    // exposition only\n    static const strstate constant;     // exposition only\n    static const strstate dynamic;      // exposition only\n    static const strstate frozen;       // exposition only\n    strstate strmode;                   // exposition only\n    streamsize alsize;                  // exposition only\n    void* (*palloc)(size_t);            // exposition only\n    void (*pfree)(void*);               // exposition only\n};\n\nclass istrstream\n    : public basic_istream<char>\n{\npublic:\n    explicit istrstream(const char* s);\n    explicit istrstream(char* s);\n    istrstream(const char* s, streamsize n);\n    istrstream(char* s, streamsize n);\n\n    virtual ~istrstream();\n\n    strstreambuf* rdbuf() const;\n    char *str();\n\nprivate:\n    strstreambuf sb; // exposition only\n};\n\nclass ostrstream\n    : public basic_ostream<char>\n{\npublic:\n    ostrstream();\n    ostrstream(char* s, int n, ios_base::openmode mode = ios_base::out);\n\n    virtual ~ostrstream();\n\n    strstreambuf* rdbuf() const;\n    void freeze(bool freezefl = true);\n    char* str();\n    int pcount() const;\n\nprivate:\n    strstreambuf sb; // exposition only\n};\n\nclass strstream\n    : public basic_iostream<char>\n{\npublic:\n    // Types\n    typedef char                        char_type;\n    typedef char_traits<char>::int_type int_type;\n    typedef char_traits<char>::pos_type pos_type;\n    typedef char_traits<char>::off_type off_type;\n\n    // constructors/destructor\n    strstream();\n    strstream(char* s, int n, ios_base::openmode mode = ios_base::in | ios_base::out);\n\n    virtual ~strstream();\n\n    // Members:\n    strstreambuf* rdbuf() const;\n    void freeze(bool freezefl = true);\n    int pcount() const;\n    char* str();\n\nprivate:\n    strstreambuf sb; // exposition only\n};\n\n}  // std\n\n*/\n\n#include <__config>\n#include <ostream>\n#include <istream>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nclass _LIBCPP_TYPE_VIS strstreambuf\n    : public streambuf\n{\npublic:\n    explicit strstreambuf(streamsize __alsize = 0);\n    strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*));\n    strstreambuf(char* __gnext, streamsize __n, char* __pbeg = 0);\n    strstreambuf(const char* __gnext, streamsize __n);\n\n    strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg = 0);\n    strstreambuf(const signed char* __gnext, streamsize __n);\n    strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg = 0);\n    strstreambuf(const unsigned char* __gnext, streamsize __n);\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    strstreambuf(strstreambuf&& __rhs);\n    _LIBCPP_INLINE_VISIBILITY\n    strstreambuf& operator=(strstreambuf&& __rhs);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    virtual ~strstreambuf();\n\n    void swap(strstreambuf& __rhs);\n\n    void freeze(bool __freezefl = true);\n    char* str();\n    int pcount() const;\n\nprotected:\n    virtual int_type overflow (int_type __c = EOF);\n    virtual int_type pbackfail(int_type __c = EOF);\n    virtual int_type underflow();\n    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,\n                             ios_base::openmode __which = ios_base::in | ios_base::out);\n    virtual pos_type seekpos(pos_type __sp,\n                             ios_base::openmode __which = ios_base::in | ios_base::out);\n\nprivate:\n    typedef unsigned __mode_type;\n    static const __mode_type __allocated = 0x01;\n    static const __mode_type __constant  = 0x02;\n    static const __mode_type __dynamic   = 0x04;\n    static const __mode_type __frozen    = 0x08;\n    static const streamsize    __default_alsize = 4096;\n\n    __mode_type __strmode_;\n    streamsize __alsize_;\n    void* (*__palloc_)(size_t);\n    void (*__pfree_)(void*);\n\n    void __init(char* __gnext, streamsize __n, char* __pbeg);\n};\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ninline _LIBCPP_INLINE_VISIBILITY\nstrstreambuf::strstreambuf(strstreambuf&& __rhs)\n    : streambuf(__rhs),\n      __strmode_(__rhs.__strmode_),\n      __alsize_(__rhs.__alsize_),\n      __palloc_(__rhs.__palloc_),\n      __pfree_(__rhs.__pfree_)\n{\n    __rhs.setg(nullptr, nullptr, nullptr);\n    __rhs.setp(nullptr, nullptr);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nstrstreambuf&\nstrstreambuf::operator=(strstreambuf&& __rhs)\n{\n    if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0)\n    {\n        if (__pfree_)\n            __pfree_(eback());\n        else\n            delete [] eback();\n    }\n    streambuf::operator=(__rhs);\n    __strmode_ = __rhs.__strmode_;\n    __alsize_ = __rhs.__alsize_;\n    __palloc_ = __rhs.__palloc_;\n    __pfree_ = __rhs.__pfree_;\n    __rhs.setg(nullptr, nullptr, nullptr);\n    __rhs.setp(nullptr, nullptr);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\nclass _LIBCPP_TYPE_VIS istrstream\n    : public istream\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit istrstream(const char* __s)\n        : istream(&__sb_), __sb_(__s, 0) {}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit istrstream(char* __s)\n        : istream(&__sb_), __sb_(__s, 0) {}\n    _LIBCPP_INLINE_VISIBILITY\n    istrstream(const char* __s, streamsize __n)\n        : istream(&__sb_), __sb_(__s, __n) {}\n    _LIBCPP_INLINE_VISIBILITY\n    istrstream(char* __s, streamsize __n)\n        : istream(&__sb_), __sb_(__s, __n) {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    istrstream(istrstream&& __rhs)\n        : istream(_VSTD::move(__rhs)),\n          __sb_(_VSTD::move(__rhs.__sb_))\n    {\n        istream::set_rdbuf(&__sb_);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    istrstream& operator=(istrstream&& __rhs)\n    {\n        istream::operator=(_VSTD::move(__rhs));\n        __sb_ = _VSTD::move(__rhs.__sb_);\n        return *this;\n    }\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    virtual ~istrstream();\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(istrstream& __rhs)\n    {\n        istream::swap(__rhs);\n        __sb_.swap(__rhs.__sb_);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    strstreambuf* rdbuf() const {return const_cast<strstreambuf*>(&__sb_);}\n    _LIBCPP_INLINE_VISIBILITY\n    char *str() {return __sb_.str();}\n\nprivate:\n    strstreambuf __sb_;\n};\n\nclass _LIBCPP_TYPE_VIS ostrstream\n    : public ostream\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    ostrstream()\n        : ostream(&__sb_) {}\n    _LIBCPP_INLINE_VISIBILITY\n    ostrstream(char* __s, int __n, ios_base::openmode __mode = ios_base::out)\n        : ostream(&__sb_),\n          __sb_(__s, __n, __s + (__mode & ios::app ? strlen(__s) : 0))\n        {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    ostrstream(ostrstream&& __rhs)\n        : ostream(_VSTD::move(__rhs)),\n          __sb_(_VSTD::move(__rhs.__sb_))\n    {\n        ostream::set_rdbuf(&__sb_);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    ostrstream& operator=(ostrstream&& __rhs)\n    {\n        ostream::operator=(_VSTD::move(__rhs));\n        __sb_ = _VSTD::move(__rhs.__sb_);\n        return *this;\n    }\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    virtual ~ostrstream();\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(ostrstream& __rhs)\n    {\n        ostream::swap(__rhs);\n        __sb_.swap(__rhs.__sb_);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    strstreambuf* rdbuf() const {return const_cast<strstreambuf*>(&__sb_);}\n    _LIBCPP_INLINE_VISIBILITY\n    void freeze(bool __freezefl = true) {__sb_.freeze(__freezefl);}\n    _LIBCPP_INLINE_VISIBILITY\n    char* str()         {return __sb_.str();}\n    _LIBCPP_INLINE_VISIBILITY\n    int pcount() const  {return __sb_.pcount();}\n\nprivate:\n    strstreambuf __sb_; // exposition only\n};\n\nclass _LIBCPP_TYPE_VIS strstream\n    : public iostream\n{\npublic:\n    // Types\n    typedef char                        char_type;\n    typedef char_traits<char>::int_type int_type;\n    typedef char_traits<char>::pos_type pos_type;\n    typedef char_traits<char>::off_type off_type;\n\n    // constructors/destructor\n    _LIBCPP_INLINE_VISIBILITY\n    strstream()\n        : iostream(&__sb_) {}\n    _LIBCPP_INLINE_VISIBILITY\n    strstream(char* __s, int __n, ios_base::openmode __mode = ios_base::in | ios_base::out)\n        : iostream(&__sb_),\n          __sb_(__s, __n, __s + (__mode & ios::app ? strlen(__s) : 0))\n        {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    strstream(strstream&& __rhs)\n        : iostream(_VSTD::move(__rhs)),\n          __sb_(_VSTD::move(__rhs.__sb_))\n    {\n        iostream::set_rdbuf(&__sb_);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    strstream& operator=(strstream&& __rhs)\n    {\n        iostream::operator=(_VSTD::move(__rhs));\n        __sb_ = _VSTD::move(__rhs.__sb_);\n        return *this;\n    }\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    virtual ~strstream();\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(strstream& __rhs)\n    {\n        iostream::swap(__rhs);\n        __sb_.swap(__rhs.__sb_);\n    }\n\n    // Members:\n    _LIBCPP_INLINE_VISIBILITY\n    strstreambuf* rdbuf() const {return const_cast<strstreambuf*>(&__sb_);}\n    _LIBCPP_INLINE_VISIBILITY\n    void freeze(bool __freezefl = true) {__sb_.freeze(__freezefl);}\n    _LIBCPP_INLINE_VISIBILITY\n    int pcount() const {return __sb_.pcount();}\n    _LIBCPP_INLINE_VISIBILITY\n    char* str()        {return __sb_.str();}\n\nprivate:\n    strstreambuf __sb_; // exposition only\n};\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_STRSTREAM\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/support/android/locale_bionic.h",
    "content": "// -*- C++ -*-\n//===------------------- support/android/locale_bionic.h ------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H\n#define _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H\n\n#if defined(__ANDROID__)\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdlib.h>\n#include <xlocale.h>\n\n#ifdef __cplusplus\n}\n#endif\n\n// Share implementation with Newlib\n#include <support/xlocale/xlocale.h>\n\n#endif // defined(__ANDROID__)\n#endif // _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/support/ibm/limits.h",
    "content": "// -*- C++ -*-\n//===--------------------- support/ibm/limits.h ---------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SUPPORT_IBM_LIMITS_H\n#define _LIBCPP_SUPPORT_IBM_LIMITS_H\n\n#if !defined(_AIX) // Linux\n#include <math.h> // for HUGE_VAL, HUGE_VALF, HUGE_VALL, and NAN\n\nstatic const unsigned int _QNAN_F = 0x7fc00000;\n#define NANF (*((float *)(&_QNAN_F)))\nstatic const unsigned int _QNAN_LDBL128[4] = {0x7ff80000, 0x0, 0x0, 0x0};\n#define NANL (*((long double *)(&_QNAN_LDBL128)))\nstatic const unsigned int _SNAN_F= 0x7f855555;\n#define NANSF (*((float *)(&_SNAN_F)))\nstatic const unsigned int _SNAN_D[2] = {0x7ff55555, 0x55555555};\n#define NANS (*((double *)(&_SNAN_D)))\nstatic const unsigned int _SNAN_LDBL128[4] = {0x7ff55555, 0x55555555, 0x0, 0x0};\n#define NANSL (*((long double *)(&_SNAN_LDBL128)))\n\n#define __builtin_huge_val()     HUGE_VAL\n#define __builtin_huge_valf()    HUGE_VALF\n#define __builtin_huge_vall()    HUGE_VALL\n#define __builtin_nan(__dummy)   NAN\n#define __builtin_nanf(__dummy)  NANF\n#define __builtin_nanl(__dummy)  NANL\n#define __builtin_nans(__dummy)  NANS\n#define __builtin_nansf(__dummy) NANSF\n#define __builtin_nansl(__dummy) NANSL\n\n#else\n\n#include <math.h>\n#include <float.h> // limit constants\n\n#define __builtin_huge_val()     HUGE_VAL  //0x7ff0000000000000\n#define __builtin_huge_valf()    HUGE_VALF //0x7f800000\n#define __builtin_huge_vall()    HUGE_VALL //0x7ff0000000000000\n#define __builtin_nan(__dummy)   nan(__dummy) //0x7ff8000000000000\n#define __builtin_nanf(__dummy)  nanf(__dummy) // 0x7ff80000\n#define __builtin_nanl(__dummy)  nanl(__dummy) //0x7ff8000000000000\n#define __builtin_nans(__dummy)  DBL_SNAN //0x7ff5555555555555\n#define __builtin_nansf(__dummy) FLT_SNAN //0x7f855555\n#define __builtin_nansl(__dummy) DBL_SNAN //0x7ff5555555555555\n\n#define __FLT_MANT_DIG__   FLT_MANT_DIG\n#define __FLT_DIG__        FLT_DIG\n#define __FLT_RADIX__      FLT_RADIX\n#define __FLT_MIN_EXP__    FLT_MIN_EXP\n#define __FLT_MIN_10_EXP__ FLT_MIN_10_EXP\n#define __FLT_MAX_EXP__    FLT_MAX_EXP\n#define __FLT_MAX_10_EXP__ FLT_MAX_10_EXP\n#define __FLT_MIN__        FLT_MIN\n#define __FLT_MAX__        FLT_MAX\n#define __FLT_EPSILON__    FLT_EPSILON\n// predefined by XLC on LoP\n#define __FLT_DENORM_MIN__ 1.40129846e-45F\n\n#define __DBL_MANT_DIG__   DBL_MANT_DIG\n#define __DBL_DIG__        DBL_DIG\n#define __DBL_MIN_EXP__    DBL_MIN_EXP\n#define __DBL_MIN_10_EXP__ DBL_MIN_10_EXP\n#define __DBL_MAX_EXP__    DBL_MAX_EXP\n#define __DBL_MAX_10_EXP__ DBL_MAX_10_EXP\n#define __DBL_MIN__        DBL_MIN\n#define __DBL_MAX__        DBL_MAX\n#define __DBL_EPSILON__    DBL_EPSILON\n// predefined by XLC on LoP\n#define __DBL_DENORM_MIN__ 4.9406564584124654e-324\n\n#define __LDBL_MANT_DIG__   LDBL_MANT_DIG\n#define __LDBL_DIG__        LDBL_DIG\n#define __LDBL_MIN_EXP__    LDBL_MIN_EXP\n#define __LDBL_MIN_10_EXP__ LDBL_MIN_10_EXP\n#define __LDBL_MAX_EXP__    LDBL_MAX_EXP\n#define __LDBL_MAX_10_EXP__ LDBL_MAX_10_EXP\n#define __LDBL_MIN__        LDBL_MIN\n#define __LDBL_MAX__        LDBL_MAX\n#define __LDBL_EPSILON__    LDBL_EPSILON\n// predefined by XLC on LoP\n#if __LONGDOUBLE128\n#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L\n#else\n#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L\n#endif\n\n// predefined by XLC on LoP\n#define __CHAR_BIT__    8\n\n#endif // _AIX\n\n#endif // _LIBCPP_SUPPORT_IBM_LIMITS_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/support/ibm/support.h",
    "content": "// -*- C++ -*-\n//===----------------------- support/ibm/support.h ----------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SUPPORT_IBM_SUPPORT_H\n#define _LIBCPP_SUPPORT_IBM_SUPPORT_H\n\nextern \"builtin\" int __popcnt4(unsigned int);\nextern \"builtin\" int __popcnt8(unsigned long long);\nextern \"builtin\" unsigned int __cnttz4(unsigned int);\nextern \"builtin\" unsigned int __cnttz8(unsigned long long);\nextern \"builtin\" unsigned int __cntlz4(unsigned int);\nextern \"builtin\" unsigned int __cntlz8(unsigned long long);\n\n// Builtin functions for counting population\n#define __builtin_popcount(x) __popcnt4(x)\n#define __builtin_popcountll(x) __popcnt8(x)\n#if defined(__64BIT__)\n#define __builtin_popcountl(x) __builtin_popcountll(x)\n#else\n#define __builtin_popcountl(x) __builtin_popcount(x)\n#endif\n\n// Builtin functions for counting trailing zeros\n#define __builtin_ctz(x) __cnttz4(x)\n#define __builtin_ctzll(x) __cnttz8(x)\n#if defined(__64BIT__)\n#define __builtin_ctzl(x) __builtin_ctzll(x)\n#else\n#define __builtin_ctzl(x) __builtin_ctz(x)\n#endif\n\n// Builtin functions for counting leading zeros\n#define __builtin_clz(x) __cntlz4(x)\n#define __builtin_clzll(x) __cntlz8(x)\n#if defined(__64BIT__)\n#define __builtin_clzl(x) __builtin_clzll(x)\n#else\n#define __builtin_clzl(x) __builtin_clz(x)\n#endif\n\n#if defined(__64BIT__)\n#define __SIZE_WIDTH__ 64\n#else\n#define __SIZE_WIDTH__ 32\n#endif\n\n#endif // _LIBCPP_SUPPORT_IBM_SUPPORT_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/support/ibm/xlocale.h",
    "content": "// -*- C++ -*-\n//===--------------------- support/ibm/xlocale.h -------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SUPPORT_IBM_XLOCALE_H\n#define _LIBCPP_SUPPORT_IBM_XLOCALE_H\n\n#if defined(_AIX)\n#include \"cstdlib\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#if !defined(_AIX71)\n// AIX 7.1 and higher has these definitions.  Definitions and stubs\n// are provied here as a temporary workaround on AIX 6.1.\n\n#define LC_COLLATE_MASK         1\n#define LC_CTYPE_MASK           2\n#define LC_MESSAGES_MASK        4\n#define LC_MONETARY_MASK        8\n#define LC_NUMERIC_MASK         16\n#define LC_TIME_MASK            32\n#define LC_ALL_MASK             (LC_COLLATE_MASK | LC_CTYPE_MASK | \\\n                                 LC_MESSAGES_MASK | LC_MONETARY_MASK |\\\n                                 LC_NUMERIC_MASK | LC_TIME_MASK)\n\ntypedef void* locale_t;\n\n// The following are stubs.  They are not supported on AIX 6.1.\nstatic inline\nlocale_t newlocale(int category_mask, const char *locale, locale_t base)\n{\n  _LC_locale_t *newloc, *loc;\n  if ((loc = (_LC_locale_t *)__xopen_locale(locale)) == NULL)\n  {\n    errno = EINVAL;\n    return (locale_t)0;\n  }\n  if ((newloc = (_LC_locale_t *)calloc(1, sizeof(_LC_locale_t))) == NULL)\n  {\n    errno = ENOMEM;\n    return (locale_t)0;\n  }\n  if (!base)\n    base = (_LC_locale_t *)__xopen_locale(\"C\");\n  memcpy(newloc, base, sizeof (_LC_locale_t));\n  if (category_mask & LC_COLLATE_MASK) \n    newloc->lc_collate = loc->lc_collate;\n  if (category_mask & LC_CTYPE_MASK)\n    newloc->lc_ctype = loc->lc_ctype;\n  //if (category_mask & LC_MESSAGES_MASK)\n  //  newloc->lc_messages = loc->lc_messages;\n  if (category_mask & LC_MONETARY_MASK)\n    newloc->lc_monetary = loc->lc_monetary;\n  if (category_mask & LC_TIME_MASK)\n    newloc->lc_time = loc->lc_time;\n  if (category_mask & LC_NUMERIC_MASK)\n    newloc->lc_numeric = loc->lc_numeric;\n  return (locale_t)newloc; \n}\nstatic inline\nvoid freelocale(locale_t locobj)\n{\n  free(locobj);\n}\nstatic inline\nlocale_t uselocale(locale_t newloc)\n{\n  return (locale_t)0;\n}\n\nstatic inline\nint isalnum_l(int c, locale_t locale)\n{\n  return __xisalnum(locale, c);\n}\nstatic inline\nint isalpha_l(int c, locale_t locale)\n{\n  return __xisalpha(locale, c);\n}\nstatic inline\nint isblank_l(int c, locale_t locale)\n{\n  return __xisblank(locale, c);\n}\nstatic inline\nint iscntrl_l(int c, locale_t locale)\n{\n  return __xiscntrl(locale, c);\n}\nstatic inline\nint isdigit_l(int c, locale_t locale)\n{\n  return __xisdigit(locale, c);\n}\nstatic inline\nint isgraph_l(int c, locale_t locale)\n{\n  return __xisgraph(locale, c);\n}\nstatic inline\nint islower_l(int c, locale_t locale)\n{\n  return __xislower(locale, c);\n}\nstatic inline\nint isprint_l(int c, locale_t locale)\n{\n  return __xisprint(locale, c);\n}\n\nstatic inline\nint ispunct_l(int c, locale_t locale)\n{\n  return __xispunct(locale, c);\n}\nstatic inline\nint isspace_l(int c, locale_t locale)\n{\n  return __xisspace(locale, c);\n}\nstatic inline\nint isupper_l(int c, locale_t locale)\n{\n  return __xisupper(locale, c);\n}\n\nstatic inline\nint isxdigit_l(int c, locale_t locale)\n{\n  return __xisxdigit(locale, c);\n}\n\nstatic inline\nint iswalnum_l(wchar_t wc, locale_t locale)\n{\n  return __xiswalnum(locale, wc); \n}\n\nstatic inline\nint iswalpha_l(wchar_t wc, locale_t locale)\n{\n  return __xiswalpha(locale, wc);\n}\n\nstatic inline\nint iswblank_l(wchar_t wc, locale_t locale)\n{\n  return __xiswblank(locale, wc);\n}\n\nstatic inline\nint iswcntrl_l(wchar_t wc, locale_t locale)\n{\n  return __xiswcntrl(locale, wc);\n}\n\nstatic inline\nint iswdigit_l(wchar_t wc, locale_t locale)\n{\n  return __xiswdigit(locale, wc);\n}\n\nstatic inline\nint iswgraph_l(wchar_t wc, locale_t locale)\n{\n  return __xiswgraph(locale, wc);\n}\n\nstatic inline\nint iswlower_l(wchar_t wc, locale_t locale)\n{\n  return __xiswlower(locale, wc);\n}\n\nstatic inline\nint iswprint_l(wchar_t wc, locale_t locale)\n{\n  return __xiswprint(locale, wc);\n}\n\nstatic inline\nint iswpunct_l(wchar_t wc, locale_t locale)\n{\n  return __xiswpunct(locale, wc);\n}\n\nstatic inline\nint iswspace_l(wchar_t wc, locale_t locale)\n{\n  return __xiswspace(locale, wc);\n}\n\nstatic inline\nint iswupper_l(wchar_t wc, locale_t locale)\n{\n  return __xiswupper(locale, wc);\n}\n\nstatic inline\nint iswxdigit_l(wchar_t wc, locale_t locale)\n{\n  return __xiswxdigit(locale, wc);\n}\n\nstatic inline\nint iswctype_l(wint_t wc, wctype_t desc, locale_t locale)\n{\n  return __xiswctype(locale, wc, desc); \n}\n\nstatic inline\nint toupper_l(int c, locale_t locale)\n{\n  return __xtoupper(locale, c);\n}\nstatic inline\nint tolower_l(int c, locale_t locale)\n{\n  return __xtolower(locale, c);\n}\nstatic inline\nwint_t towupper_l(wint_t wc, locale_t locale)\n{\n  return __xtowupper(locale, wc);\n}\nstatic inline\nwint_t towlower_l(wint_t wc, locale_t locale)\n{\n  return __xtowlower(locale, wc);\n}\n\nstatic inline\nint strcoll_l(const char *__s1, const char *__s2, locale_t locale)\n{\n  return __xstrcoll(locale, __s1, __s2);\n}\nstatic inline\nint wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, locale_t locale)\n{\n  return __xwcscoll(locale, __s1, __s2);\n}\nstatic inline\nsize_t strxfrm_l(char *__s1, const char *__s2, size_t __n, locale_t locale)\n{\n  return __xstrxfrm(locale, __s1, __s2, __n);\n}\n\nstatic inline\nsize_t wcsxfrm_l(wchar_t *__ws1, const wchar_t *__ws2, size_t __n,\n    locale_t locale)\n{\n  return __xwcsxfrm(locale, __ws1, __ws2, __n);\n}\n#endif // !defined(_AIX71)\n\n// strftime_l() is defined by POSIX. However, AIX 7.1 does not have it\n// implemented yet.\nstatic inline\nsize_t strftime_l(char *__s, size_t __size, const char *__fmt,\n                  const struct tm *__tm, locale_t locale) {\n  return __xstrftime(locale, __s, __size, __fmt, __tm);\n}\n\n// The following are not POSIX routines.  These are quick-and-dirty hacks\n// to make things pretend to work\nstatic inline\nlong long strtoll_l(const char *__nptr, char **__endptr,\n    int __base, locale_t locale) {\n  return strtoll(__nptr, __endptr, __base);\n}\nstatic inline\nlong strtol_l(const char *__nptr, char **__endptr,\n    int __base, locale_t locale) {\n  return strtol(__nptr, __endptr, __base);\n}\nstatic inline\nlong double strtold_l(const char *__nptr, char **__endptr,\n    locale_t locale) {\n  return strtold(__nptr, __endptr);\n}\nstatic inline\nunsigned long long strtoull_l(const char *__nptr, char **__endptr,\n    int __base, locale_t locale) {\n  return strtoull(__nptr, __endptr, __base);\n}\nstatic inline\nunsigned long strtoul_l(const char *__nptr, char **__endptr,\n    int __base, locale_t locale) {\n  return strtoul(__nptr, __endptr, __base);\n}\n\nstatic inline\nint vasprintf(char **strp, const char *fmt, va_list ap)\n{\n  const size_t buff_size = 256;\n  int str_size;\n  if ((*strp = (char *)malloc(buff_size)) == NULL)\n  {\n    return -1;\n  }\n  if ((str_size = vsnprintf(*strp, buff_size, fmt,  ap)) >= buff_size)\n  {\n    if ((*strp = (char *)realloc(*strp, str_size + 1)) == NULL)\n    {\n      return -1;\n    }\n    str_size = vsnprintf(*strp, str_size + 1, fmt,  ap);\n  }\n  return str_size;\n}  \n\n#ifdef __cplusplus\n}\n#endif\n#endif // defined(_AIX)\n#endif // _LIBCPP_SUPPORT_IBM_XLOCALE_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/support/newlib/xlocale.h",
    "content": "//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SUPPORT_NEWLIB_XLOCALE_H\n#define _LIBCPP_SUPPORT_NEWLIB_XLOCALE_H\n\n#if defined(_NEWLIB_VERSION)\n\n#include <cstdlib>\n#include <clocale>\n#include <cwctype>\n#include <ctype.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// Patch over newlib's lack of extended locale support\ntypedef void *locale_t;\nstatic inline locale_t duplocale(locale_t) {\n  return NULL;\n}\n\nstatic inline void freelocale(locale_t) {\n}\n\nstatic inline locale_t newlocale(int, const char *, locale_t) {\n  return NULL;\n}\n\nstatic inline locale_t uselocale(locale_t) {\n  return NULL;\n}\n\n#define LC_COLLATE_MASK  (1 << LC_COLLATE)\n#define LC_CTYPE_MASK    (1 << LC_CTYPE)\n#define LC_MESSAGES_MASK (1 << LC_MESSAGES)\n#define LC_MONETARY_MASK (1 << LC_MONETARY)\n#define LC_NUMERIC_MASK  (1 << LC_NUMERIC)\n#define LC_TIME_MASK     (1 << LC_TIME)\n#define LC_ALL_MASK (LC_COLLATE_MASK|\\\n                     LC_CTYPE_MASK|\\\n                     LC_MONETARY_MASK|\\\n                     LC_NUMERIC_MASK|\\\n                     LC_TIME_MASK|\\\n                     LC_MESSAGES_MASK)\n\n// Share implementation with Android's Bionic\n#include <support/xlocale/xlocale.h>\n\n#ifdef __cplusplus\n} // extern \"C\"\n#endif\n\n#endif // _NEWLIB_VERSION\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/support/solaris/floatingpoint.h",
    "content": "//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define atof sun_atof\n#define strtod sun_strtod\n#include_next \"floatingpoint.h\"\n#undef atof\n#undef strtod\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/support/solaris/wchar.h",
    "content": "//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define iswalpha sun_iswalpha\n#define iswupper sun_iswupper\n#define iswlower sun_iswlower\n#define iswdigit sun_iswdigit\n#define iswxdigit sun_iswxdigit\n#define iswalnum sun_iswalnum\n#define iswspace sun_iswspace\n#define iswpunct sun_iswpunct\n#define iswprint sun_iswprint\n#define iswgraph sun_iswgraph\n#define iswcntrl sun_iswcntrl\n#define iswctype sun_iswctype\n#define towlower sun_towlower\n#define towupper sun_towupper\n#define wcswcs sun_wcswcs\n#define wcswidth sun_wcswidth\n#define wcwidth sun_wcwidth\n#define wctype sun_wctype\n#define _WCHAR_T 1\n#include_next \"wchar.h\"\n#undef iswalpha \n#undef iswupper\n#undef iswlower\n#undef iswdigit\n#undef iswxdigit\n#undef iswalnum\n#undef iswspace\n#undef iswpunct\n#undef iswprint\n#undef iswgraph\n#undef iswcntrl\n#undef iswctype\n#undef towlower\n#undef towupper\n#undef wcswcs\n#undef wcswidth\n#undef wcwidth\n#undef wctype\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/support/solaris/xlocale.h",
    "content": "//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n////////////////////////////////////////////////////////////////////////////////\n// Minimal xlocale implementation for Solaris.  This implements the subset of\n// the xlocale APIs that libc++ depends on.\n////////////////////////////////////////////////////////////////////////////////\n#ifndef __XLOCALE_H_INCLUDED\n#define __XLOCALE_H_INCLUDED\n\n#include <stdlib.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\nint snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...);\nint asprintf_l(char **__s, locale_t __l, const char *__format, ...);\n\nint sscanf_l(const char *__s, locale_t __l, const char *__format, ...);\n\nint toupper_l(int __c, locale_t __l);\nint tolower_l(int __c, locale_t __l);\n\nstruct lconv *localeconv(void);\nstruct lconv *localeconv_l(locale_t __l);\n\n// FIXME: These are quick-and-dirty hacks to make things pretend to work\nstatic inline\nlong long strtoll_l(const char *__nptr, char **__endptr,\n    int __base, locale_t __loc) {\n  return strtoll(__nptr, __endptr, __base);\n}\nstatic inline\nlong strtol_l(const char *__nptr, char **__endptr,\n    int __base, locale_t __loc) {\n  return strtol(__nptr, __endptr, __base);\n}\nstatic inline\nlong double strtold_l(const char *__nptr, char **__endptr,\n    locale_t __loc) {\n  return strtold(__nptr, __endptr);\n}\nstatic inline\nunsigned long long strtoull_l(const char *__nptr, char **__endptr,\n    int __base, locale_t __loc) {\n  return strtoull(__nptr, __endptr, __base);\n}\nstatic inline\nunsigned long strtoul_l(const char *__nptr, char **__endptr,\n    int __base, locale_t __loc) {\n  return strtoul(__nptr, __endptr, __base);\n}\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/support/win32/limits_win32.h",
    "content": "// -*- C++ -*-\n//===--------------------- support/win32/limits_win32.h -------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SUPPORT_WIN32_LIMITS_WIN32_H\n#define _LIBCPP_SUPPORT_WIN32_LIMITS_WIN32_H\n\n#if !defined(_LIBCPP_MSVCRT)\n#error \"This header complements the Microsoft C Runtime library, and should not be included otherwise.\"\n#else\n\n#include <limits.h> // CHAR_BIT\n#include <float.h> // limit constants\n\n#if ! defined(__clang__)\n#define __CHAR_BIT__       CHAR_BIT\n\n#define __FLT_MANT_DIG__   FLT_MANT_DIG\n#define __FLT_DIG__        FLT_DIG\n#define __FLT_RADIX__      FLT_RADIX\n#define __FLT_MIN_EXP__    FLT_MIN_EXP\n#define __FLT_MIN_10_EXP__ FLT_MIN_10_EXP\n#define __FLT_MAX_EXP__    FLT_MAX_EXP\n#define __FLT_MAX_10_EXP__ FLT_MAX_10_EXP\n#define __FLT_MIN__        FLT_MIN\n#define __FLT_MAX__        FLT_MAX\n#define __FLT_EPSILON__    FLT_EPSILON\n// predefined by MinGW GCC\n#define __FLT_DENORM_MIN__ 1.40129846432481707092e-45F\n\n#define __DBL_MANT_DIG__   DBL_MANT_DIG\n#define __DBL_DIG__        DBL_DIG\n#define __DBL_RADIX__      DBL_RADIX\n#define __DBL_MIN_EXP__    DBL_MIN_EXP\n#define __DBL_MIN_10_EXP__ DBL_MIN_10_EXP\n#define __DBL_MAX_EXP__    DBL_MAX_EXP\n#define __DBL_MAX_10_EXP__ DBL_MAX_10_EXP\n#define __DBL_MIN__        DBL_MIN\n#define __DBL_MAX__        DBL_MAX\n#define __DBL_EPSILON__    DBL_EPSILON\n// predefined by MinGW GCC\n#define __DBL_DENORM_MIN__ double(4.94065645841246544177e-324L)\n\n#define __LDBL_MANT_DIG__   LDBL_MANT_DIG\n#define __LDBL_DIG__        LDBL_DIG\n#define __LDBL_RADIX__      LDBL_RADIX\n#define __LDBL_MIN_EXP__    LDBL_MIN_EXP\n#define __LDBL_MIN_10_EXP__ LDBL_MIN_10_EXP\n#define __LDBL_MAX_EXP__    LDBL_MAX_EXP\n#define __LDBL_MAX_10_EXP__ LDBL_MAX_10_EXP\n#define __LDBL_MIN__        LDBL_MIN\n#define __LDBL_MAX__        LDBL_MAX\n#define __LDBL_EPSILON__    LDBL_EPSILON\n// predefined by MinGW GCC\n#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L\n\n// __builtin replacements/workarounds\n#include <math.h> // HUGE_VAL\n#include <ymath.h> // internal MSVC header providing the needed functionality\n#define __builtin_huge_val()     HUGE_VAL\n#define __builtin_huge_valf()    _FInf._Float\n#define __builtin_huge_vall()    _LInf._Long_double\n#define __builtin_nan(__dummy)   _Nan._Double\n#define __builtin_nanf(__dummy)  _FNan._Float\n#define __builtin_nanl(__dummmy) _LNan._Long_double\n#define __builtin_nans(__dummy)  _Snan._Double\n#define __builtin_nansf(__dummy) _FSnan._Float\n#define __builtin_nansl(__dummy) _LSnan._Long_double\n#endif // ! defined(__clang__)\n\n#endif // _LIBCPP_MSVCRT\n\n#endif // _LIBCPP_SUPPORT_WIN32_LIMITS_WIN32_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/support/win32/locale_win32.h",
    "content": "// -*- C++ -*-\n//===--------------------- support/win32/locale_win32.h -------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H\n#define _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H\n\n// ctype mask table defined in msvcrt.dll\nextern \"C\" unsigned short  __declspec(dllimport) _ctype[];\n\n#include \"support/win32/support.h\"\n#include <stdio.h>\n#include <memory>\n#include <xlocinfo.h> // _locale_t\n#define locale_t _locale_t\n#define LC_COLLATE_MASK _M_COLLATE\n#define LC_CTYPE_MASK _M_CTYPE\n#define LC_MONETARY_MASK _M_MONETARY\n#define LC_NUMERIC_MASK _M_NUMERIC\n#define LC_TIME_MASK _M_TIME\n#define LC_MESSAGES_MASK _M_MESSAGES\n#define LC_ALL_MASK (  LC_COLLATE_MASK \\\n                     | LC_CTYPE_MASK \\\n                     | LC_MESSAGES_MASK \\\n                     | LC_MONETARY_MASK \\\n                     | LC_NUMERIC_MASK \\\n                     | LC_TIME_MASK )\n#define freelocale _free_locale\n// FIXME: base currently unused. Needs manual work to construct the new locale\nlocale_t newlocale( int mask, const char * locale, locale_t base );\nlocale_t uselocale( locale_t newloc );\nlconv *localeconv_l( locale_t loc );\nsize_t mbrlen_l( const char *__restrict s, size_t n,\n                 mbstate_t *__restrict ps, locale_t loc);\nsize_t mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,\n                    size_t len, mbstate_t *__restrict ps, locale_t loc );\nsize_t wcrtomb_l( char *__restrict s, wchar_t wc, mbstate_t *__restrict ps,\n                  locale_t loc);\nsize_t mbrtowc_l( wchar_t *__restrict pwc, const char *__restrict s,\n                  size_t n, mbstate_t *__restrict ps, locale_t loc);\nsize_t mbsnrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,\n                     size_t nms, size_t len, mbstate_t *__restrict ps, locale_t loc);\nsize_t wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src,\n                     size_t nwc, size_t len, mbstate_t *__restrict ps, locale_t loc);\nwint_t btowc_l( int c, locale_t loc );\nint wctob_l( wint_t c, locale_t loc );\ntypedef _VSTD::remove_pointer<locale_t>::type __locale_struct;\ntypedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;\ninline _LIBCPP_ALWAYS_INLINE\ndecltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l )\n{\n  __locale_raii __current( uselocale(__l), uselocale );\n  return MB_CUR_MAX;\n}\n\n// the *_l functions are prefixed on Windows, only available for msvcr80+, VS2005+\n#define mbtowc_l _mbtowc_l\n#define strtoll_l _strtoi64_l\n#define strtoull_l _strtoui64_l\n// FIXME: current msvcrt does not know about long double\n#define strtold_l _strtod_l\n\ninline _LIBCPP_INLINE_VISIBILITY\nint\nislower_l(int c, _locale_t loc)\n{\n return _islower_l((int)c, loc);\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nint\nisupper_l(int c, _locale_t loc)\n{\n return _isupper_l((int)c, loc);\n}\n\n#define isdigit_l _isdigit_l\n#define isxdigit_l _isxdigit_l\n#define strcoll_l _strcoll_l\n#define strxfrm_l _strxfrm_l\n#define wcscoll_l _wcscoll_l\n#define wcsxfrm_l _wcsxfrm_l\n#define toupper_l _toupper_l\n#define tolower_l _tolower_l\n#define iswspace_l _iswspace_l\n#define iswprint_l _iswprint_l\n#define iswcntrl_l _iswcntrl_l\n#define iswupper_l _iswupper_l\n#define iswlower_l _iswlower_l\n#define iswalpha_l _iswalpha_l\n#define iswdigit_l _iswdigit_l\n#define iswpunct_l _iswpunct_l\n#define iswxdigit_l _iswxdigit_l\n#define towupper_l _towupper_l\n#define towlower_l _towlower_l\n#define strftime_l _strftime_l\n#define sscanf_l( __s, __l, __f, ...) _sscanf_l( __s, __f, __l, __VA_ARGS__ )\n#define vsscanf_l( __s, __l, __f, ...) _sscanf_l( __s, __f, __l, __VA_ARGS__ )\n#define sprintf_l( __s, __l, __f, ... ) _sprintf_l( __s, __f, __l, __VA_ARGS__ )\n#define vsprintf_l( __s, __l, __f, ... ) _vsprintf_l( __s, __f, __l, __VA_ARGS__ )\n#define vsnprintf_l( __s, __n, __l, __f, ... ) _vsnprintf_l( __s, __n, __f, __l, __VA_ARGS__ )\nint snprintf_l(char *ret, size_t n, locale_t loc, const char *format, ...);\nint asprintf_l( char **ret, locale_t loc, const char *format, ... );\nint vasprintf_l( char **ret, locale_t loc, const char *format, va_list ap );\n\n\n// not-so-pressing FIXME: use locale to determine blank characters\ninline int isblank_l( int c, locale_t /*loc*/ )\n{\n    return ( c == ' ' || c == '\\t' );\n}\ninline int iswblank_l( wint_t c, locale_t /*loc*/ )\n{\n    return ( c == L' ' || c == L'\\t' );\n}\n\n#if defined(_LIBCPP_MSVCRT)\ninline int isblank( int c, locale_t /*loc*/ )\n{ return ( c == ' ' || c == '\\t' ); }\ninline int iswblank( wint_t c, locale_t /*loc*/ )\n{ return ( c == L' ' || c == L'\\t' ); }\n#endif // _LIBCPP_MSVCRT\n#endif // _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/support/win32/math_win32.h",
    "content": "// -*- C++ -*-\n//===---------------------- support/win32/math_win32.h --------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SUPPORT_WIN32_MATH_WIN32_H\n#define _LIBCPP_SUPPORT_WIN32_MATH_WIN32_H\n\n#if !defined(_LIBCPP_MSVCRT)\n#error \"This header complements Microsoft's C Runtime library, and should not be included otherwise.\"\n#else\n\n#include <math.h>\n#include <float.h> // _FPCLASS_PN etc.\n#include <crtversion.h>\n\n#if ((_VC_CRT_MAJOR_VERSION-0) < 12)\n// Necessary?\ntypedef float float_t;\ntypedef double double_t;\n\n_LIBCPP_ALWAYS_INLINE bool isfinite( double num )\n{\n    return _finite(num) != 0;\n}\n_LIBCPP_ALWAYS_INLINE bool isinf( double num )\n{\n    return !isfinite(num) && !_isnan(num);\n}\n_LIBCPP_ALWAYS_INLINE bool isnan( double num )\n{\n    return _isnan(num) != 0;\n}\n_LIBCPP_ALWAYS_INLINE bool isnormal( double num )\n{\n    int class_ = _fpclass(num);\n    return class_ == _FPCLASS_NN || class_ == _FPCLASS_PN;\n}\n\n_LIBCPP_ALWAYS_INLINE bool isgreater( double x, double y )\n{\n    if(_fpclass(x) == _FPCLASS_SNAN || _fpclass(y) == _FPCLASS_SNAN) return false;\n    else return x > y;\n}\n\n_LIBCPP_ALWAYS_INLINE bool isgreaterequal( double x, double y )\n{\n    if(_fpclass(x) == _FPCLASS_SNAN || _fpclass(y) == _FPCLASS_SNAN) return false;\n    else return x >= y;\n}\n\n_LIBCPP_ALWAYS_INLINE bool isless( double x, double y )\n{\n    if(_fpclass(x) == _FPCLASS_SNAN || _fpclass(y) == _FPCLASS_SNAN) return false;\n    else return x < y;\n}\n\n_LIBCPP_ALWAYS_INLINE bool islessequal( double x, double y )\n{\n    if(::_fpclass(x) == _FPCLASS_SNAN || ::_fpclass(y) == _FPCLASS_SNAN) return false;\n    else return x <= y;\n}\n\n_LIBCPP_ALWAYS_INLINE bool islessgreater( double x, double y )\n{\n    if(::_fpclass(x) == _FPCLASS_SNAN || ::_fpclass(y) == _FPCLASS_SNAN) return false;\n    else return x < y || x > y;\n}\n\n_LIBCPP_ALWAYS_INLINE bool isunordered( double x, double y )\n{\n    return isnan(x) || isnan(y);\n}\n_LIBCPP_ALWAYS_INLINE bool signbit( double num )\n{\n    switch(_fpclass(num))\n    {\n        case _FPCLASS_SNAN:\n        case _FPCLASS_QNAN:\n        case _FPCLASS_NINF:\n        case _FPCLASS_NN:\n        case _FPCLASS_ND:\n        case _FPCLASS_NZ:\n            return true;\n        case _FPCLASS_PZ:\n        case _FPCLASS_PD:\n        case _FPCLASS_PN:\n        case _FPCLASS_PINF:\n            return false;\n    }\n    return false;\n}\n_LIBCPP_ALWAYS_INLINE float copysignf( float x, float y )\n{\n    return (signbit (x) != signbit (y) ? - x : x);\n}\n_LIBCPP_ALWAYS_INLINE double copysign( double x, double y )\n{\n    return ::_copysign(x,y);\n}\n_LIBCPP_ALWAYS_INLINE double copysignl( long double x, long double y )\n{\n    return ::_copysignl(x,y);\n}\n_LIBCPP_ALWAYS_INLINE int fpclassify( double num )\n{\n    return _fpclass(num);\n}\n#endif\n#endif // _LIBCPP_MSVCRT\n\n#endif // _LIBCPP_SUPPORT_WIN32_MATH_WIN32_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/support/win32/support.h",
    "content": "// -*- C++ -*-\n//===----------------------- support/win32/support.h ----------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SUPPORT_WIN32_SUPPORT_H\n#define _LIBCPP_SUPPORT_WIN32_SUPPORT_H\n\n// Functions and constants used in libc++ that\n// are missing from the Windows C library.\n\n#include <wchar.h> // mbstate_t\n#include <cstdarg> // va_ macros\n// \"builtins\" not implemented here for Clang or GCC as they provide\n// implementations. Assuming required for elsewhere else, certainly MSVC.\n#if defined(_LIBCPP_MSVC)\n#include <intrin.h>\n#endif\n#if defined(_LIBCPP_MSVCRT)\n#include <xlocinfo.h>\n#endif\n#define swprintf _snwprintf\n#define vswprintf _vsnwprintf\n\n#ifndef NOMINMAX\n#define NOMINMAX\n#endif\n\n// The mingw headers already define these as static.\n#ifndef __MINGW32__\nextern \"C\" {\n\nint vasprintf(char **sptr, const char *__restrict fmt, va_list ap);\nint asprintf(char **sptr, const char *__restrict fmt, ...);\nsize_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src,\n                  size_t nmc, size_t len, mbstate_t *__restrict ps);\nsize_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src,\n                  size_t nwc, size_t len, mbstate_t *__restrict ps);\n}\n#endif // __MINGW32__\n\n#if defined(_LIBCPP_MSVCRT)\n#define snprintf _snprintf\n#define atoll _atoi64\n#define strtoll _strtoi64\n#define strtoull _strtoui64\n#define wcstoll _wcstoi64\n#define wcstoull _wcstoui64\n_LIBCPP_ALWAYS_INLINE float strtof(const char *nptr, char **endptr)\n{\n  return _Stof(nptr, endptr, 0);\n}\n_LIBCPP_ALWAYS_INLINE double strtod(const char *nptr, char **endptr)\n{\n  return _Stod(nptr, endptr, 0);\n}\n_LIBCPP_ALWAYS_INLINE long double strtold(const char *nptr, char **endptr)\n{\n  return _Stold(nptr, endptr, 0);\n}\n\n#define _Exit _exit\n#endif\n\n#if defined(_LIBCPP_MSVC)\n\n// Bit builtin's make these assumptions when calling _BitScanForward/Reverse\n// etc. These assumptions are expected to be true for Win32/Win64 which this\n// file supports.\nstatic_assert(sizeof(unsigned long long) == 8, \"\");\nstatic_assert(sizeof(unsigned long) == 4, \"\");\nstatic_assert(sizeof(unsigned int) == 4, \"\");\n\n_LIBCPP_ALWAYS_INLINE int __builtin_popcount(unsigned int x)\n{\n  // Binary: 0101...\n  static const unsigned int m1 = 0x55555555;\n  // Binary: 00110011..\n  static const unsigned int m2 = 0x33333333;\n  // Binary:  4 zeros,  4 ones ...\n  static const unsigned int m4 = 0x0f0f0f0f;\n  // The sum of 256 to the power of 0,1,2,3...\n  static const unsigned int h01 = 0x01010101;\n  // Put count of each 2 bits into those 2 bits.\n  x -= (x >> 1) & m1;\n  // Put count of each 4 bits into those 4 bits.\n  x = (x & m2) + ((x >> 2) & m2);\n  // Put count of each 8 bits into those 8 bits.\n  x = (x + (x >> 4)) & m4;\n  // Returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24).\n  return (x * h01) >> 24;\n}\n\n_LIBCPP_ALWAYS_INLINE int __builtin_popcountl(unsigned long x)\n{\n  return __builtin_popcount(static_cast<int>(x));\n}\n\n_LIBCPP_ALWAYS_INLINE int __builtin_popcountll(unsigned long long x)\n{\n  // Binary: 0101...\n  static const unsigned long long m1 = 0x5555555555555555;\n  // Binary: 00110011..\n  static const unsigned long long m2 = 0x3333333333333333;\n  // Binary:  4 zeros,  4 ones ...\n  static const unsigned long long m4 = 0x0f0f0f0f0f0f0f0f;\n  // The sum of 256 to the power of 0,1,2,3...\n  static const unsigned long long h01 = 0x0101010101010101;\n  // Put count of each 2 bits into those 2 bits.\n  x -= (x >> 1) & m1;\n  // Put count of each 4 bits into those 4 bits.\n  x = (x & m2) + ((x >> 2) & m2);\n  // Put count of each 8 bits into those 8 bits.\n  x = (x + (x >> 4)) & m4;\n  // Returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...\n  return static_cast<int>((x * h01) >> 56);\n}\n\n// Returns the number of trailing 0-bits in x, starting at the least significant\n// bit position. If x is 0, the result is undefined.\n_LIBCPP_ALWAYS_INLINE int __builtin_ctzll(unsigned long long mask)\n{\n  unsigned long where;\n// Search from LSB to MSB for first set bit.\n// Returns zero if no set bit is found.\n#if defined(_WIN64)\n  if (_BitScanForward64(&where, mask))\n    return static_cast<int>(where);\n#elif defined(_WIN32)\n  // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.\n  // Scan the Low Word.\n  if (_BitScanForward(&where, static_cast<unsigned long>(mask)))\n    return static_cast<int>(where);\n  // Scan the High Word.\n  if (_BitScanForward(&where, static_cast<unsigned long>(mask >> 32)))\n    return static_cast<int>(where + 32); // Create a bit offset from the LSB.\n#else\n#error \"Implementation of __builtin_ctzll required\"\n#endif\n  return 64;\n}\n\n_LIBCPP_ALWAYS_INLINE int __builtin_ctzl(unsigned long mask)\n{\n  unsigned long where;\n  // Search from LSB to MSB for first set bit.\n  // Returns zero if no set bit is found.\n  if (_BitScanForward(&where, mask))\n    return static_cast<int>(where);\n  return 32;\n}\n\n_LIBCPP_ALWAYS_INLINE int __builtin_ctz(unsigned int mask)\n{\n  // Win32 and Win64 expectations.\n  static_assert(sizeof(mask) == 4, \"\");\n  static_assert(sizeof(unsigned long) == 4, \"\");\n  return __builtin_ctzl(static_cast<unsigned long>(mask));\n}\n\n// Returns the number of leading 0-bits in x, starting at the most significant\n// bit position. If x is 0, the result is undefined.\n_LIBCPP_ALWAYS_INLINE int __builtin_clzll(unsigned long long mask)\n{\n  unsigned long where;\n// BitScanReverse scans from MSB to LSB for first set bit.\n// Returns 0 if no set bit is found.\n#if defined(_WIN64)\n  if (_BitScanReverse64(&where, mask))\n    return static_cast<int>(63 - where);\n#elif defined(_WIN32)\n  // Scan the high 32 bits.\n  if (_BitScanReverse(&where, static_cast<unsigned long>(mask >> 32)))\n    return static_cast<int>(63 -\n                            (where + 32)); // Create a bit offset from the MSB.\n  // Scan the low 32 bits.\n  if (_BitScanReverse(&where, static_cast<unsigned long>(mask)))\n    return static_cast<int>(63 - where);\n#else\n#error \"Implementation of __builtin_clzll required\"\n#endif\n  return 64; // Undefined Behavior.\n}\n\n_LIBCPP_ALWAYS_INLINE int __builtin_clzl(unsigned long mask)\n{\n  unsigned long where;\n  // Search from LSB to MSB for first set bit.\n  // Returns zero if no set bit is found.\n  if (_BitScanReverse(&where, mask))\n    return static_cast<int>(31 - where);\n  return 32; // Undefined Behavior.\n}\n\n_LIBCPP_ALWAYS_INLINE int __builtin_clz(unsigned int x)\n{\n  return __builtin_clzl(x);\n}\n#endif // _LIBCPP_MSVC\n\n#endif // _LIBCPP_SUPPORT_WIN32_SUPPORT_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/support/xlocale/xlocale.h",
    "content": "// -*- C++ -*-\n//===------------------- support/xlocale/xlocale.h ------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n// This is a shared implementation of a shim to provide extended locale support\n// on top of libc's that don't support it (like Android's bionic, and Newlib).\n//\n// The 'illusion' only works when the specified locale is \"C\" or \"POSIX\", but\n// that's about as good as we can do without implementing full xlocale support\n// in the underlying libc.\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SUPPORT_XLOCALE_XLOCALE_H\n#define _LIBCPP_SUPPORT_XLOCALE_XLOCALE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstatic inline int isalnum_l(int c, locale_t) {\n  return isalnum(c);\n}\n\nstatic inline int isalpha_l(int c, locale_t) {\n  return isalpha(c);\n}\n\nstatic inline int isblank_l(int c, locale_t) {\n  return isblank(c);\n}\n\nstatic inline int iscntrl_l(int c, locale_t) {\n  return iscntrl(c);\n}\n\nstatic inline int isdigit_l(int c, locale_t) {\n  return isdigit(c);\n}\n\nstatic inline int isgraph_l(int c, locale_t) {\n  return isgraph(c);\n}\n\nstatic inline int islower_l(int c, locale_t) {\n  return islower(c);\n}\n\nstatic inline int isprint_l(int c, locale_t) {\n  return isprint(c);\n}\n\nstatic inline int ispunct_l(int c, locale_t) {\n  return ispunct(c);\n}\n\nstatic inline int isspace_l(int c, locale_t) {\n  return isspace(c);\n}\n\nstatic inline int isupper_l(int c, locale_t) {\n  return isupper(c);\n}\n\nstatic inline int isxdigit_l(int c, locale_t) {\n  return isxdigit(c);\n}\n\nstatic inline int iswalnum_l(wint_t c, locale_t) {\n  return iswalnum(c);\n}\n\nstatic inline int iswalpha_l(wint_t c, locale_t) {\n  return iswalpha(c);\n}\n\nstatic inline int iswblank_l(wint_t c, locale_t) {\n  return iswblank(c);\n}\n\nstatic inline int iswcntrl_l(wint_t c, locale_t) {\n  return iswcntrl(c);\n}\n\nstatic inline int iswdigit_l(wint_t c, locale_t) {\n  return iswdigit(c);\n}\n\nstatic inline int iswgraph_l(wint_t c, locale_t) {\n  return iswgraph(c);\n}\n\nstatic inline int iswlower_l(wint_t c, locale_t) {\n  return iswlower(c);\n}\n\nstatic inline int iswprint_l(wint_t c, locale_t) {\n  return iswprint(c);\n}\n\nstatic inline int iswpunct_l(wint_t c, locale_t) {\n  return iswpunct(c);\n}\n\nstatic inline int iswspace_l(wint_t c, locale_t) {\n  return iswspace(c);\n}\n\nstatic inline int iswupper_l(wint_t c, locale_t) {\n  return iswupper(c);\n}\n\nstatic inline int iswxdigit_l(wint_t c, locale_t) {\n  return iswxdigit(c);\n}\n\nstatic inline int toupper_l(int c, locale_t) {\n  return toupper(c);\n}\n\nstatic inline int tolower_l(int c, locale_t) {\n  return tolower(c);\n}\n\nstatic inline int towupper_l(int c, locale_t) {\n  return towupper(c);\n}\n\nstatic inline int towlower_l(int c, locale_t) {\n  return towlower(c);\n}\n\nstatic inline int strcoll_l(const char *s1, const char *s2, locale_t) {\n  return strcoll(s1, s2);\n}\n\nstatic inline size_t strxfrm_l(char *dest, const char *src, size_t n,\n                               locale_t) {\n  return strxfrm(dest, src, n);\n}\n\nstatic inline size_t strftime_l(char *s, size_t max, const char *format,\n                                const struct tm *tm, locale_t) {\n  return strftime(s, max, format, tm);\n}\n\nstatic inline int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t) {\n  return wcscoll(ws1, ws2);\n}\n\nstatic inline size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, size_t n,\n                               locale_t) {\n  return wcsxfrm(dest, src, n);\n}\n\nstatic inline long double strtold_l(const char *nptr, char **endptr, locale_t) {\n  return strtold(nptr, endptr);\n}\n\nstatic inline long long strtoll_l(const char *nptr, char **endptr, int base,\n                                  locale_t) {\n  return strtoll(nptr, endptr, base);\n}\n\nstatic inline unsigned long long strtoull_l(const char *nptr, char **endptr,\n                                            int base, locale_t) {\n  return strtoull(nptr, endptr, base);\n}\n\nstatic inline long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr,\n                                  int base, locale_t) {\n  return wcstoll(nptr, endptr, base);\n}\n\nstatic inline unsigned long long wcstoull_l(const wchar_t *nptr,\n                                            wchar_t **endptr, int base,\n                                            locale_t) {\n  return wcstoull(nptr, endptr, base);\n}\n\nstatic inline long double wcstold_l(const wchar_t *nptr, wchar_t **endptr,\n                                    locale_t) {\n  return wcstold(nptr, endptr);\n}\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // _LIBCPP_SUPPORT_XLOCALE_XLOCALE_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/system_error",
    "content": "// -*- C++ -*-\n//===---------------------------- system_error ----------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_SYSTEM_ERROR\n#define _LIBCPP_SYSTEM_ERROR\n\n/*\n    system_error synopsis\n\nnamespace std\n{\n\nclass error_category\n{\npublic:\n    virtual ~error_category() noexcept;\n\n    constexpr error_category();\n    error_category(const error_category&) = delete;\n    error_category& operator=(const error_category&) = delete;\n\n    virtual const char* name() const noexcept = 0;\n    virtual error_condition default_error_condition(int ev) const noexcept;\n    virtual bool equivalent(int code, const error_condition& condition) const noexcept;\n    virtual bool equivalent(const error_code& code, int condition) const noexcept;\n    virtual string message(int ev) const = 0;\n\n    bool operator==(const error_category& rhs) const noexcept;\n    bool operator!=(const error_category& rhs) const noexcept;\n    bool operator<(const error_category& rhs) const noexcept;\n};\n\nconst error_category& generic_category() noexcept;\nconst error_category& system_category() noexcept;\n\ntemplate <class T> struct is_error_code_enum\n    : public false_type {};\n\ntemplate <class T> struct is_error_condition_enum\n    : public false_type {};\n\nclass error_code\n{\npublic:\n    // constructors:\n    error_code() noexcept;\n    error_code(int val, const error_category& cat) noexcept;\n    template <class ErrorCodeEnum>\n        error_code(ErrorCodeEnum e) noexcept;\n\n    // modifiers:\n    void assign(int val, const error_category& cat) noexcept;\n    template <class ErrorCodeEnum>\n        error_code& operator=(ErrorCodeEnum e) noexcept;\n    void clear() noexcept;\n\n    // observers:\n    int value() const noexcept;\n    const error_category& category() const noexcept;\n    error_condition default_error_condition() const noexcept;\n    string message() const;\n    explicit operator bool() const noexcept;\n};\n\n// non-member functions:\nbool operator<(const error_code& lhs, const error_code& rhs) noexcept;\ntemplate <class charT, class traits>\n    basic_ostream<charT,traits>&\n    operator<<(basic_ostream<charT,traits>& os, const error_code& ec);\n\nclass error_condition\n{\npublic:\n    // constructors:\n    error_condition() noexcept;\n    error_condition(int val, const error_category& cat) noexcept;\n    template <class ErrorConditionEnum>\n        error_condition(ErrorConditionEnum e) noexcept;\n\n    // modifiers:\n    void assign(int val, const error_category& cat) noexcept;\n    template <class ErrorConditionEnum>\n        error_condition& operator=(ErrorConditionEnum e) noexcept;\n    void clear() noexcept;\n\n    // observers:\n    int value() const noexcept;\n    const error_category& category() const noexcept;\n    string message() const noexcept;\n    explicit operator bool() const noexcept;\n};\n\nbool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;\n\nclass system_error\n    : public runtime_error\n{\npublic:\n    system_error(error_code ec, const string& what_arg);\n    system_error(error_code ec, const char* what_arg);\n    system_error(error_code ec);\n    system_error(int ev, const error_category& ecat, const string& what_arg);\n    system_error(int ev, const error_category& ecat, const char* what_arg);\n    system_error(int ev, const error_category& ecat);\n\n    const error_code& code() const noexcept;\n    const char* what() const noexcept;\n};\n\nenum class errc\n{\n    address_family_not_supported,       // EAFNOSUPPORT\n    address_in_use,                     // EADDRINUSE\n    address_not_available,              // EADDRNOTAVAIL\n    already_connected,                  // EISCONN\n    argument_list_too_long,             // E2BIG\n    argument_out_of_domain,             // EDOM\n    bad_address,                        // EFAULT\n    bad_file_descriptor,                // EBADF\n    bad_message,                        // EBADMSG\n    broken_pipe,                        // EPIPE\n    connection_aborted,                 // ECONNABORTED\n    connection_already_in_progress,     // EALREADY\n    connection_refused,                 // ECONNREFUSED\n    connection_reset,                   // ECONNRESET\n    cross_device_link,                  // EXDEV\n    destination_address_required,       // EDESTADDRREQ\n    device_or_resource_busy,            // EBUSY\n    directory_not_empty,                // ENOTEMPTY\n    executable_format_error,            // ENOEXEC\n    file_exists,                        // EEXIST\n    file_too_large,                     // EFBIG\n    filename_too_long,                  // ENAMETOOLONG\n    function_not_supported,             // ENOSYS\n    host_unreachable,                   // EHOSTUNREACH\n    identifier_removed,                 // EIDRM\n    illegal_byte_sequence,              // EILSEQ\n    inappropriate_io_control_operation, // ENOTTY\n    interrupted,                        // EINTR\n    invalid_argument,                   // EINVAL\n    invalid_seek,                       // ESPIPE\n    io_error,                           // EIO\n    is_a_directory,                     // EISDIR\n    message_size,                       // EMSGSIZE\n    network_down,                       // ENETDOWN\n    network_reset,                      // ENETRESET\n    network_unreachable,                // ENETUNREACH\n    no_buffer_space,                    // ENOBUFS\n    no_child_process,                   // ECHILD\n    no_link,                            // ENOLINK\n    no_lock_available,                  // ENOLCK\n    no_message_available,               // ENODATA\n    no_message,                         // ENOMSG\n    no_protocol_option,                 // ENOPROTOOPT\n    no_space_on_device,                 // ENOSPC\n    no_stream_resources,                // ENOSR\n    no_such_device_or_address,          // ENXIO\n    no_such_device,                     // ENODEV\n    no_such_file_or_directory,          // ENOENT\n    no_such_process,                    // ESRCH\n    not_a_directory,                    // ENOTDIR\n    not_a_socket,                       // ENOTSOCK\n    not_a_stream,                       // ENOSTR\n    not_connected,                      // ENOTCONN\n    not_enough_memory,                  // ENOMEM\n    not_supported,                      // ENOTSUP\n    operation_canceled,                 // ECANCELED\n    operation_in_progress,              // EINPROGRESS\n    operation_not_permitted,            // EPERM\n    operation_not_supported,            // EOPNOTSUPP\n    operation_would_block,              // EWOULDBLOCK\n    owner_dead,                         // EOWNERDEAD\n    permission_denied,                  // EACCES\n    protocol_error,                     // EPROTO\n    protocol_not_supported,             // EPROTONOSUPPORT\n    read_only_file_system,              // EROFS\n    resource_deadlock_would_occur,      // EDEADLK\n    resource_unavailable_try_again,     // EAGAIN\n    result_out_of_range,                // ERANGE\n    state_not_recoverable,              // ENOTRECOVERABLE\n    stream_timeout,                     // ETIME\n    text_file_busy,                     // ETXTBSY\n    timed_out,                          // ETIMEDOUT\n    too_many_files_open_in_system,      // ENFILE\n    too_many_files_open,                // EMFILE\n    too_many_links,                     // EMLINK\n    too_many_symbolic_link_levels,      // ELOOP\n    value_too_large,                    // EOVERFLOW\n    wrong_protocol_type                 // EPROTOTYPE\n};\n\ntemplate <> struct is_error_condition_enum<errc>\n    : true_type { }\n\nerror_code make_error_code(errc e) noexcept;\nerror_condition make_error_condition(errc e) noexcept;\n\n// Comparison operators:\nbool operator==(const error_code& lhs, const error_code& rhs) noexcept;\nbool operator==(const error_code& lhs, const error_condition& rhs) noexcept;\nbool operator==(const error_condition& lhs, const error_code& rhs) noexcept;\nbool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;\nbool operator!=(const error_code& lhs, const error_code& rhs) noexcept;\nbool operator!=(const error_code& lhs, const error_condition& rhs) noexcept;\nbool operator!=(const error_condition& lhs, const error_code& rhs) noexcept;\nbool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept;\n\ntemplate <> struct hash<std::error_code>;\n\n}  // std\n\n*/\n\n#include <__config>\n#include <cerrno>\n#include <type_traits>\n#include <stdexcept>\n#include <__functional_base>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n// is_error_code_enum\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum\n    : public false_type {};\n\n// is_error_condition_enum\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_error_condition_enum\n    : public false_type {};\n\n// Some error codes are not present on all platforms, so we provide equivalents\n// for them:\n\n//enum class errc\n_LIBCPP_DECLARE_STRONG_ENUM(errc)\n{\n    address_family_not_supported        = EAFNOSUPPORT,\n    address_in_use                      = EADDRINUSE,\n    address_not_available               = EADDRNOTAVAIL,\n    already_connected                   = EISCONN,\n    argument_list_too_long              = E2BIG,\n    argument_out_of_domain              = EDOM,\n    bad_address                         = EFAULT,\n    bad_file_descriptor                 = EBADF,\n    bad_message                         = EBADMSG,\n    broken_pipe                         = EPIPE,\n    connection_aborted                  = ECONNABORTED,\n    connection_already_in_progress      = EALREADY,\n    connection_refused                  = ECONNREFUSED,\n    connection_reset                    = ECONNRESET,\n    cross_device_link                   = EXDEV,\n    destination_address_required        = EDESTADDRREQ,\n    device_or_resource_busy             = EBUSY,\n    directory_not_empty                 = ENOTEMPTY,\n    executable_format_error             = ENOEXEC,\n    file_exists                         = EEXIST,\n    file_too_large                      = EFBIG,\n    filename_too_long                   = ENAMETOOLONG,\n    function_not_supported              = ENOSYS,\n    host_unreachable                    = EHOSTUNREACH,\n    identifier_removed                  = EIDRM,\n    illegal_byte_sequence               = EILSEQ,\n    inappropriate_io_control_operation  = ENOTTY,\n    interrupted                         = EINTR,\n    invalid_argument                    = EINVAL,\n    invalid_seek                        = ESPIPE,\n    io_error                            = EIO,\n    is_a_directory                      = EISDIR,\n    message_size                        = EMSGSIZE,\n    network_down                        = ENETDOWN,\n    network_reset                       = ENETRESET,\n    network_unreachable                 = ENETUNREACH,\n    no_buffer_space                     = ENOBUFS,\n    no_child_process                    = ECHILD,\n    no_link                             = ENOLINK,\n    no_lock_available                   = ENOLCK,\n#ifdef ENODATA\n    no_message_available                = ENODATA,\n#else\n    no_message_available                = ENOMSG,\n#endif\n    no_message                          = ENOMSG,\n    no_protocol_option                  = ENOPROTOOPT,\n    no_space_on_device                  = ENOSPC,\n#ifdef ENOSR\n    no_stream_resources                 = ENOSR,\n#else\n    no_stream_resources                 = ENOMEM,\n#endif\n    no_such_device_or_address           = ENXIO,\n    no_such_device                      = ENODEV,\n    no_such_file_or_directory           = ENOENT,\n    no_such_process                     = ESRCH,\n    not_a_directory                     = ENOTDIR,\n    not_a_socket                        = ENOTSOCK,\n#ifdef ENOSTR\n    not_a_stream                        = ENOSTR,\n#else\n    not_a_stream                        = EINVAL,\n#endif\n    not_connected                       = ENOTCONN,\n    not_enough_memory                   = ENOMEM,\n    not_supported                       = ENOTSUP,\n    operation_canceled                  = ECANCELED,\n    operation_in_progress               = EINPROGRESS,\n    operation_not_permitted             = EPERM,\n    operation_not_supported             = EOPNOTSUPP,\n    operation_would_block               = EWOULDBLOCK,\n    owner_dead                          = EOWNERDEAD,\n    permission_denied                   = EACCES,\n    protocol_error                      = EPROTO,\n    protocol_not_supported              = EPROTONOSUPPORT,\n    read_only_file_system               = EROFS,\n    resource_deadlock_would_occur       = EDEADLK,\n    resource_unavailable_try_again      = EAGAIN,\n    result_out_of_range                 = ERANGE,\n    state_not_recoverable               = ENOTRECOVERABLE,\n#ifdef ETIME\n    stream_timeout                      = ETIME,\n#else\n    stream_timeout                      = ETIMEDOUT,\n#endif\n    text_file_busy                      = ETXTBSY,\n    timed_out                           = ETIMEDOUT,\n    too_many_files_open_in_system       = ENFILE,\n    too_many_files_open                 = EMFILE,\n    too_many_links                      = EMLINK,\n    too_many_symbolic_link_levels       = ELOOP,\n    value_too_large                     = EOVERFLOW,\n    wrong_protocol_type                 = EPROTOTYPE\n};\n_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc)\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY is_error_condition_enum<errc>\n    : true_type { };\n\n#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY is_error_condition_enum<errc::__lx>\n    : true_type { };\n#endif\n\nclass _LIBCPP_TYPE_VIS error_condition;\nclass _LIBCPP_TYPE_VIS error_code;\n\n// class error_category\n\nclass _LIBCPP_HIDDEN __do_message;\n\nclass _LIBCPP_TYPE_VIS error_category\n{\npublic:\n    virtual ~error_category() _NOEXCEPT;\n\n#ifdef _LIBCPP_BUILDING_SYSTEM_ERROR\n    error_category() _NOEXCEPT;\n#else\n    _LIBCPP_ALWAYS_INLINE\n    _LIBCPP_CONSTEXPR_AFTER_CXX11 error_category() _NOEXCEPT _LIBCPP_DEFAULT;\n#endif\nprivate:\n    error_category(const error_category&);// = delete;\n    error_category& operator=(const error_category&);// = delete;\n\npublic:\n    virtual const char* name() const _NOEXCEPT = 0;\n    virtual error_condition default_error_condition(int __ev) const _NOEXCEPT;\n    virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT;\n    virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT;\n    virtual string message(int __ev) const = 0;\n\n    _LIBCPP_ALWAYS_INLINE\n    bool operator==(const error_category& __rhs) const _NOEXCEPT {return this == &__rhs;}\n\n    _LIBCPP_ALWAYS_INLINE\n    bool operator!=(const error_category& __rhs) const _NOEXCEPT {return !(*this == __rhs);}\n\n    _LIBCPP_ALWAYS_INLINE\n    bool operator< (const error_category& __rhs) const _NOEXCEPT {return this < &__rhs;}\n\n    friend class _LIBCPP_HIDDEN __do_message;\n};\n\nclass _LIBCPP_HIDDEN __do_message\n    : public error_category\n{\npublic:\n    virtual string message(int ev) const;\n};\n\n_LIBCPP_FUNC_VIS const error_category& generic_category() _NOEXCEPT;\n_LIBCPP_FUNC_VIS const error_category& system_category() _NOEXCEPT;\n\nclass _LIBCPP_TYPE_VIS error_condition\n{\n    int __val_;\n    const error_category* __cat_;\npublic:\n    _LIBCPP_ALWAYS_INLINE\n    error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    error_condition(int __val, const error_category& __cat) _NOEXCEPT\n        : __val_(__val), __cat_(&__cat) {}\n\n    template <class _Ep>\n        _LIBCPP_ALWAYS_INLINE\n        error_condition(_Ep __e,\n              typename enable_if<is_error_condition_enum<_Ep>::value>::type* = 0\n                                                                     ) _NOEXCEPT\n            {*this = make_error_condition(__e);}\n\n    _LIBCPP_ALWAYS_INLINE\n    void assign(int __val, const error_category& __cat) _NOEXCEPT\n    {\n        __val_ = __val;\n        __cat_ = &__cat;\n    }\n\n    template <class _Ep>\n        _LIBCPP_ALWAYS_INLINE\n        typename enable_if\n        <\n            is_error_condition_enum<_Ep>::value,\n            error_condition&\n        >::type\n        operator=(_Ep __e) _NOEXCEPT\n            {*this = make_error_condition(__e); return *this;}\n\n    _LIBCPP_ALWAYS_INLINE\n    void clear() _NOEXCEPT\n    {\n        __val_ = 0;\n        __cat_ = &generic_category();\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    int value() const _NOEXCEPT {return __val_;}\n\n    _LIBCPP_ALWAYS_INLINE\n    const error_category& category() const _NOEXCEPT {return *__cat_;}\n    string message() const;\n\n    _LIBCPP_ALWAYS_INLINE\n        _LIBCPP_EXPLICIT\n        operator bool() const _NOEXCEPT {return __val_ != 0;}\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\nerror_condition\nmake_error_condition(errc __e) _NOEXCEPT\n{\n    return error_condition(static_cast<int>(__e), generic_category());\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT\n{\n    return __x.category() < __y.category()\n        || (__x.category() == __y.category() && __x.value() < __y.value());\n}\n\n// error_code\n\nclass _LIBCPP_TYPE_VIS error_code\n{\n    int __val_;\n    const error_category* __cat_;\npublic:\n    _LIBCPP_ALWAYS_INLINE\n    error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {}\n\n    _LIBCPP_ALWAYS_INLINE\n    error_code(int __val, const error_category& __cat) _NOEXCEPT\n        : __val_(__val), __cat_(&__cat) {}\n\n    template <class _Ep>\n        _LIBCPP_ALWAYS_INLINE\n        error_code(_Ep __e,\n                   typename enable_if<is_error_code_enum<_Ep>::value>::type* = 0\n                                                                     ) _NOEXCEPT\n            {*this = make_error_code(__e);}\n\n    _LIBCPP_ALWAYS_INLINE\n    void assign(int __val, const error_category& __cat) _NOEXCEPT\n    {\n        __val_ = __val;\n        __cat_ = &__cat;\n    }\n\n    template <class _Ep>\n        _LIBCPP_ALWAYS_INLINE\n        typename enable_if\n        <\n            is_error_code_enum<_Ep>::value,\n            error_code&\n        >::type\n        operator=(_Ep __e) _NOEXCEPT\n            {*this = make_error_code(__e); return *this;}\n\n    _LIBCPP_ALWAYS_INLINE\n    void clear() _NOEXCEPT\n    {\n        __val_ = 0;\n        __cat_ = &system_category();\n    }\n\n    _LIBCPP_ALWAYS_INLINE\n    int value() const _NOEXCEPT {return __val_;}\n\n    _LIBCPP_ALWAYS_INLINE\n    const error_category& category() const _NOEXCEPT {return *__cat_;}\n\n    _LIBCPP_ALWAYS_INLINE\n    error_condition default_error_condition() const _NOEXCEPT\n        {return __cat_->default_error_condition(__val_);}\n\n    string message() const;\n\n    _LIBCPP_ALWAYS_INLINE\n        _LIBCPP_EXPLICIT\n        operator bool() const _NOEXCEPT {return __val_ != 0;}\n};\n\ninline _LIBCPP_INLINE_VISIBILITY\nerror_code\nmake_error_code(errc __e) _NOEXCEPT\n{\n    return error_code(static_cast<int>(__e), generic_category());\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<(const error_code& __x, const error_code& __y) _NOEXCEPT\n{\n    return __x.category() < __y.category()\n        || (__x.category() == __y.category() && __x.value() < __y.value());\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const error_code& __x, const error_code& __y) _NOEXCEPT\n{\n    return __x.category() == __y.category() && __x.value() == __y.value();\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const error_code& __x, const error_condition& __y) _NOEXCEPT\n{\n    return __x.category().equivalent(__x.value(), __y)\n        || __y.category().equivalent(__x, __y.value());\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const error_condition& __x, const error_code& __y) _NOEXCEPT\n{\n    return __y == __x;\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT\n{\n    return __x.category() == __y.category() && __x.value() == __y.value();\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const error_code& __x, const error_code& __y) _NOEXCEPT\n{return !(__x == __y);}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT\n{return !(__x == __y);}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT\n{return !(__x == __y);}\n\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT\n{return !(__x == __y);}\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<error_code>\n    : public unary_function<error_code, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(const error_code& __ec) const _NOEXCEPT\n    {\n        return static_cast<size_t>(__ec.value());\n    }\n};\n\n// system_error\n\nclass _LIBCPP_TYPE_VIS system_error\n    : public runtime_error\n{\n    error_code __ec_;\npublic:\n    system_error(error_code __ec, const string& __what_arg);\n    system_error(error_code __ec, const char* __what_arg);\n    system_error(error_code __ec);\n    system_error(int __ev, const error_category& __ecat, const string& __what_arg);\n    system_error(int __ev, const error_category& __ecat, const char* __what_arg);\n    system_error(int __ev, const error_category& __ecat);\n    ~system_error() _NOEXCEPT;\n\n    _LIBCPP_ALWAYS_INLINE\n    const error_code& code() const _NOEXCEPT {return __ec_;}\n\nprivate:\n    static string __init(const error_code&, string);\n};\n\n_LIBCPP_FUNC_VIS void __throw_system_error(int ev, const char* what_arg);\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_SYSTEM_ERROR\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/tgmath.h",
    "content": "// -*- C++ -*-\n//===-------------------------- tgmath.h ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_TGMATH_H\n#define _LIBCPP_TGMATH_H\n\n/*\n    tgmath.h synopsis\n\n#include <complex.h>\n#include <math.h>\n\n*/\n\n#include <complex.h>\n#include <math.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#endif  // _LIBCPP_TGMATH_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/thread",
    "content": "// -*- C++ -*-\n//===--------------------------- thread -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_THREAD\n#define _LIBCPP_THREAD\n\n/*\n\n    thread synopsis\n\n#define __STDCPP_THREADS__ __cplusplus\n\nnamespace std\n{\n\nclass thread\n{\npublic:\n    class id;\n    typedef pthread_t native_handle_type;\n\n    thread() noexcept;\n    template <class F, class ...Args> explicit thread(F&& f, Args&&... args);\n    ~thread();\n\n    thread(const thread&) = delete;\n    thread(thread&& t) noexcept;\n\n    thread& operator=(const thread&) = delete;\n    thread& operator=(thread&& t) noexcept;\n\n    void swap(thread& t) noexcept;\n\n    bool joinable() const noexcept;\n    void join();\n    void detach();\n    id get_id() const noexcept;\n    native_handle_type native_handle();\n\n    static unsigned hardware_concurrency() noexcept;\n};\n\nvoid swap(thread& x, thread& y) noexcept;\n\nclass thread::id\n{\npublic:\n    id() noexcept;\n};\n\nbool operator==(thread::id x, thread::id y) noexcept;\nbool operator!=(thread::id x, thread::id y) noexcept;\nbool operator< (thread::id x, thread::id y) noexcept;\nbool operator<=(thread::id x, thread::id y) noexcept;\nbool operator> (thread::id x, thread::id y) noexcept;\nbool operator>=(thread::id x, thread::id y) noexcept;\n\ntemplate<class charT, class traits>\nbasic_ostream<charT, traits>&\noperator<<(basic_ostream<charT, traits>& out, thread::id id);\n\nnamespace this_thread\n{\n\nthread::id get_id() noexcept;\n\nvoid yield() noexcept;\n\ntemplate <class Clock, class Duration>\nvoid sleep_until(const chrono::time_point<Clock, Duration>& abs_time);\n\ntemplate <class Rep, class Period>\nvoid sleep_for(const chrono::duration<Rep, Period>& rel_time);\n\n}  // this_thread\n\n}  // std\n\n*/\n\n#include <__config>\n#include <iosfwd>\n#include <__functional_base>\n#include <type_traits>\n#include <cstddef>\n#include <functional>\n#include <memory>\n#include <system_error>\n#include <chrono>\n#include <__mutex_base>\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n#include <tuple>\n#endif\n#include <pthread.h>\n#include <sched.h>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n#define __STDCPP_THREADS__ __cplusplus\n\n#ifdef _LIBCPP_HAS_NO_THREADS\n#error <thread> is not supported on this single threaded system\n#else // !_LIBCPP_HAS_NO_THREADS\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Tp>\nclass __thread_specific_ptr\n{\n    pthread_key_t __key_;\n\n    __thread_specific_ptr(const __thread_specific_ptr&);\n    __thread_specific_ptr& operator=(const __thread_specific_ptr&);\n\n    static void __at_thread_exit(void*);\npublic:\n    typedef _Tp* pointer;\n\n    __thread_specific_ptr();\n    ~__thread_specific_ptr();\n\n    _LIBCPP_INLINE_VISIBILITY\n    pointer get() const {return static_cast<_Tp*>(pthread_getspecific(__key_));}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer operator*() const {return *get();}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer operator->() const {return get();}\n    pointer release();\n    void reset(pointer __p = nullptr);\n};\n\ntemplate <class _Tp>\nvoid\n__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)\n{\n    delete static_cast<pointer>(__p);\n}\n\ntemplate <class _Tp>\n__thread_specific_ptr<_Tp>::__thread_specific_ptr()\n{\n    int __ec = pthread_key_create(&__key_, &__thread_specific_ptr::__at_thread_exit);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__ec)\n        throw system_error(error_code(__ec, system_category()),\n                           \"__thread_specific_ptr construction failed\");\n#endif\n}\n\ntemplate <class _Tp>\n__thread_specific_ptr<_Tp>::~__thread_specific_ptr()\n{\n    pthread_key_delete(__key_);\n}\n\ntemplate <class _Tp>\ntypename __thread_specific_ptr<_Tp>::pointer\n__thread_specific_ptr<_Tp>::release()\n{\n    pointer __p = get();\n    pthread_setspecific(__key_, 0);\n    return __p;\n}\n\ntemplate <class _Tp>\nvoid\n__thread_specific_ptr<_Tp>::reset(pointer __p)\n{\n    pointer __p_old = get();\n    pthread_setspecific(__key_, __p);\n    delete __p_old;\n}\n\nclass _LIBCPP_TYPE_VIS thread;\nclass _LIBCPP_TYPE_VIS __thread_id;\n\nnamespace this_thread\n{\n\n_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;\n\n}  // this_thread\n\ntemplate<> struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id>;\n\nclass _LIBCPP_TYPE_VIS_ONLY __thread_id\n{\n    // FIXME: pthread_t is a pointer on Darwin but a long on Linux.\n    // NULL is the no-thread value on Darwin.  Someone needs to check\n    // on other platforms.  We assume 0 works everywhere for now.\n    pthread_t __id_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __thread_id() _NOEXCEPT : __id_(0) {}\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT\n        {return __x.__id_ == __y.__id_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT\n        {return !(__x == __y);}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT\n        {return __x.__id_ < __y.__id_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT\n        {return !(__y < __x);}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT\n        {return   __y < __x ;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT\n        {return !(__x < __y);}\n\n    template<class _CharT, class _Traits>\n    friend\n    _LIBCPP_INLINE_VISIBILITY\n    basic_ostream<_CharT, _Traits>&\n    operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id)\n        {return __os << __id.__id_;}\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    __thread_id(pthread_t __id) : __id_(__id) {}\n\n    friend __thread_id this_thread::get_id() _NOEXCEPT;\n    friend class _LIBCPP_TYPE_VIS thread;\n    friend struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id>;\n};\n\ntemplate<>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id>\n    : public unary_function<__thread_id, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(__thread_id __v) const\n    {\n        return hash<pthread_t>()(__v.__id_);\n    }\n};\n\nnamespace this_thread\n{\n\ninline _LIBCPP_INLINE_VISIBILITY\n__thread_id\nget_id() _NOEXCEPT\n{\n    return pthread_self();\n}\n\n}  // this_thread\n\nclass _LIBCPP_TYPE_VIS thread\n{\n    pthread_t __t_;\n\n    thread(const thread&);\n    thread& operator=(const thread&);\npublic:\n    typedef __thread_id id;\n    typedef pthread_t native_handle_type;\n\n    _LIBCPP_INLINE_VISIBILITY\n    thread() _NOEXCEPT : __t_(0) {}\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class _Fp, class ..._Args,\n              class = typename enable_if\n              <\n                   !is_same<typename decay<_Fp>::type, thread>::value\n              >::type\n             >\n        explicit thread(_Fp&& __f, _Args&&... __args);\n#else  // _LIBCPP_HAS_NO_VARIADICS\n    template <class _Fp> explicit thread(_Fp __f);\n#endif\n    ~thread();\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {__t.__t_ = 0;}\n    thread& operator=(thread&& __t) _NOEXCEPT;\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool joinable() const _NOEXCEPT {return __t_ != 0;}\n    void join();\n    void detach();\n    _LIBCPP_INLINE_VISIBILITY\n    id get_id() const _NOEXCEPT {return __t_;}\n    _LIBCPP_INLINE_VISIBILITY\n    native_handle_type native_handle() _NOEXCEPT {return __t_;}\n\n    static unsigned hardware_concurrency() _NOEXCEPT;\n};\n\nclass __assoc_sub_state;\n\nclass _LIBCPP_HIDDEN __thread_struct_imp;\n\nclass _LIBCPP_TYPE_VIS __thread_struct\n{\n    __thread_struct_imp* __p_;\n\n    __thread_struct(const __thread_struct&);\n    __thread_struct& operator=(const __thread_struct&);\npublic:\n    __thread_struct();\n    ~__thread_struct();\n\n    void notify_all_at_thread_exit(condition_variable*, mutex*);\n    void __make_ready_at_thread_exit(__assoc_sub_state*);\n};\n\n_LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Fp, class ..._Args, size_t ..._Indices>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__thread_execute(tuple<_Fp, _Args...>& __t, __tuple_indices<_Indices...>)\n{\n    __invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);\n}\n\ntemplate <class _Fp>\nvoid*\n__thread_proxy(void* __vp)\n{\n    __thread_local_data().reset(new __thread_struct);\n    std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));\n    typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index;\n    __thread_execute(*__p, _Index());\n    return nullptr;\n}\n\ntemplate <class _Fp, class ..._Args,\n          class\n         >\nthread::thread(_Fp&& __f, _Args&&... __args)\n{\n    typedef tuple<typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp;\n    _VSTD::unique_ptr<_Gp> __p(new _Gp(__decay_copy(_VSTD::forward<_Fp>(__f)),\n                                __decay_copy(_VSTD::forward<_Args>(__args))...));\n    int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Gp>, __p.get());\n    if (__ec == 0)\n        __p.release();\n    else\n        __throw_system_error(__ec, \"thread constructor failed\");\n}\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Fp>\nvoid*\n__thread_proxy(void* __vp)\n{\n    __thread_local_data().reset(new __thread_struct);\n    std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));\n    (*__p)();\n    return nullptr;\n}\n\ntemplate <class _Fp>\nthread::thread(_Fp __f)\n{\n    std::unique_ptr<_Fp> __p(new _Fp(__f));\n    int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Fp>, __p.get());\n    if (__ec == 0)\n        __p.release();\n    else\n        __throw_system_error(__ec, \"thread constructor failed\");\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ninline _LIBCPP_INLINE_VISIBILITY\nthread&\nthread::operator=(thread&& __t) _NOEXCEPT\n{\n    if (__t_ != 0)\n        terminate();\n    __t_ = __t.__t_;\n    __t.__t_ = 0;\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);}\n\nnamespace this_thread\n{\n\n_LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& ns);\n\ntemplate <class _Rep, class _Period>\nvoid\nsleep_for(const chrono::duration<_Rep, _Period>& __d)\n{\n    using namespace chrono;\n    if (__d > duration<_Rep, _Period>::zero())\n    {\n        _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();\n        nanoseconds __ns;\n        if (__d < _Max)\n        {\n            __ns = duration_cast<nanoseconds>(__d);\n            if (__ns < __d)\n                ++__ns;\n        }\n        else\n            __ns = nanoseconds::max();\n        sleep_for(__ns);\n    }\n}\n\ntemplate <class _Clock, class _Duration>\nvoid\nsleep_until(const chrono::time_point<_Clock, _Duration>& __t)\n{\n    using namespace chrono;\n    mutex __mut;\n    condition_variable __cv;\n    unique_lock<mutex> __lk(__mut);\n    while (_Clock::now() < __t)\n        __cv.wait_until(__lk, __t);\n}\n\ntemplate <class _Duration>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nsleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t)\n{\n    using namespace chrono;\n    sleep_for(__t - steady_clock::now());\n}\n\ninline _LIBCPP_INLINE_VISIBILITY\nvoid yield() _NOEXCEPT {sched_yield();}\n\n}  // this_thread\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif // !_LIBCPP_HAS_NO_THREADS\n\n#endif  // _LIBCPP_THREAD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/tuple",
    "content": "// -*- C++ -*-\n//===--------------------------- tuple ------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is distributed under the University of Illinois Open Source\n// License. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_TUPLE\n#define _LIBCPP_TUPLE\n\n/*\n    tuple synopsis\n\nnamespace std\n{\n\ntemplate <class... T>\nclass tuple {\npublic:\n    constexpr tuple();\n    explicit tuple(const T&...);  // constexpr in C++14\n    template <class... U>\n        explicit tuple(U&&...);  // constexpr in C++14\n    tuple(const tuple&) = default;\n    tuple(tuple&&) = default;\n    template <class... U>\n        tuple(const tuple<U...>&);  // constexpr in C++14\n    template <class... U>\n        tuple(tuple<U...>&&);  // constexpr in C++14\n    template <class U1, class U2>\n        tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14\n    template <class U1, class U2>\n        tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2  // constexpr in C++14\n\n    // allocator-extended constructors\n    template <class Alloc>\n        tuple(allocator_arg_t, const Alloc& a);\n    template <class Alloc>\n        tuple(allocator_arg_t, const Alloc& a, const T&...);\n    template <class Alloc, class... U>\n        tuple(allocator_arg_t, const Alloc& a, U&&...);\n    template <class Alloc>\n        tuple(allocator_arg_t, const Alloc& a, const tuple&);\n    template <class Alloc>\n        tuple(allocator_arg_t, const Alloc& a, tuple&&);\n    template <class Alloc, class... U>\n        tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);\n    template <class Alloc, class... U>\n        tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);\n    template <class Alloc, class U1, class U2>\n        tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);\n    template <class Alloc, class U1, class U2>\n        tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);\n\n    tuple& operator=(const tuple&);\n    tuple&\n        operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...));\n    template <class... U>\n        tuple& operator=(const tuple<U...>&);\n    template <class... U>\n        tuple& operator=(tuple<U...>&&);\n    template <class U1, class U2>\n        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2\n    template <class U1, class U2>\n        tuple& operator=(pair<U1, U2>&&); //iffsizeof...(T) == 2\n\n    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));\n};\n\nconst unspecified ignore;\n\ntemplate <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14\ntemplate <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14\ntemplate <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14\ntemplate <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14\n  \n// 20.4.1.4, tuple helper classes:\ntemplate <class T> class tuple_size; // undefined\ntemplate <class... T> class tuple_size<tuple<T...>>;\ntemplate <intsize_t I, class T> class tuple_element; // undefined\ntemplate <intsize_t I, class... T> class tuple_element<I, tuple<T...>>;\ntemplate <size_t _Ip, class ..._Tp>\n  using tuple_element_t = typename tuple_element <_Ip, _Tp...>::type; // C++14\n\n// 20.4.1.5, element access:\ntemplate <intsize_t I, class... T>\n    typename tuple_element<I, tuple<T...>>::type&\n    get(tuple<T...>&) noexcept; // constexpr in C++14\ntemplate <intsize_t I, class... T>\n    typename const tuple_element<I, tuple<T...>>::type &\n    get(const tuple<T...>&) noexcept; // constexpr in C++14\ntemplate <intsize_t I, class... T>\n    typename tuple_element<I, tuple<T...>>::type&&\n    get(tuple<T...>&&) noexcept; // constexpr in C++14\n\ntemplate <class T1, class... T>\n    constexpr T1& get(tuple<T...>&) noexcept;  // C++14\ntemplate <class T1, class... T>\n    constexpr T1 const& get(const tuple<T...>&) noexcept;   // C++14\ntemplate <class T1, class... T>\n    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14\n\n// 20.4.1.6, relational operators:\ntemplate<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14\ntemplate<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14\ntemplate<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14\ntemplate<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14\ntemplate<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14\ntemplate<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14\n\ntemplate <class... Types, class Alloc>\n  struct uses_allocator<tuple<Types...>, Alloc>;\n\ntemplate <class... Types>\n  void\n  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));\n\n}  // std\n\n*/\n\n#include <__config>\n#include <__tuple>\n#include <cstddef>\n#include <type_traits>\n#include <__functional_base>\n#include <utility>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n// tuple_size\n\ntemplate <class ..._Tp>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_size<tuple<_Tp...> >\n    : public integral_constant<size_t, sizeof...(_Tp)>\n{\n};\n\n// tuple_element\n\ntemplate <size_t _Ip, class ..._Tp>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, tuple<_Tp...> >\n{\npublic:\n    typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <size_t _Ip, class ..._Tp>\nusing tuple_element_t = typename tuple_element <_Ip, _Tp...>::type;\n#endif\n\n// __tuple_leaf\n\ntemplate <size_t _Ip, class _Hp,\n          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value\n         >\nclass __tuple_leaf;\n\ntemplate <size_t _Ip, class _Hp, bool _Ep>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)\n    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)\n{\n    swap(__x.get(), __y.get());\n}\n\ntemplate <size_t _Ip, class _Hp, bool>\nclass __tuple_leaf\n{\n    _Hp value;\n\n    __tuple_leaf& operator=(const __tuple_leaf&);\npublic:\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()\n             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : value()\n       {static_assert(!is_reference<_Hp>::value,\n              \"Attempted to default construct a reference element in a tuple\");}\n\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)\n            : value()\n        {static_assert(!is_reference<_Hp>::value,\n              \"Attempted to default construct a reference element in a tuple\");}\n\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)\n            : value(allocator_arg_t(), __a)\n        {static_assert(!is_reference<_Hp>::value,\n              \"Attempted to default construct a reference element in a tuple\");}\n\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)\n            : value(__a)\n        {static_assert(!is_reference<_Hp>::value,\n              \"Attempted to default construct a reference element in a tuple\");}\n\n    template <class _Tp,\n              class = typename enable_if<\n                  __lazy_and<\n                      __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>>\n                    , is_constructible<_Hp, _Tp>\n                    >::value\n                >::type\n            >\n        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))\n            : value(_VSTD::forward<_Tp>(__t))\n        {static_assert(!is_reference<_Hp>::value ||\n                       (is_lvalue_reference<_Hp>::value &&\n                        (is_lvalue_reference<_Tp>::value ||\n                         is_same<typename remove_reference<_Tp>::type,\n                                 reference_wrapper<\n                                    typename remove_reference<_Hp>::type\n                                 >\n                                >::value)) ||\n                        (is_rvalue_reference<_Hp>::value &&\n                         !is_lvalue_reference<_Tp>::value),\n       \"Attempted to construct a reference element in a tuple with an rvalue\");}\n\n    template <class _Tp, class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)\n            : value(_VSTD::forward<_Tp>(__t))\n        {static_assert(!is_lvalue_reference<_Hp>::value ||\n                       (is_lvalue_reference<_Hp>::value &&\n                        (is_lvalue_reference<_Tp>::value ||\n                         is_same<typename remove_reference<_Tp>::type,\n                                 reference_wrapper<\n                                    typename remove_reference<_Hp>::type\n                                 >\n                                >::value)),\n       \"Attempted to construct a reference element in a tuple with an rvalue\");}\n\n    template <class _Tp, class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)\n            : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))\n        {static_assert(!is_lvalue_reference<_Hp>::value ||\n                       (is_lvalue_reference<_Hp>::value &&\n                        (is_lvalue_reference<_Tp>::value ||\n                         is_same<typename remove_reference<_Tp>::type,\n                                 reference_wrapper<\n                                    typename remove_reference<_Hp>::type\n                                 >\n                                >::value)),\n       \"Attempted to construct a reference element in a tuple with an rvalue\");}\n\n    template <class _Tp, class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)\n            : value(_VSTD::forward<_Tp>(__t), __a)\n        {static_assert(!is_lvalue_reference<_Hp>::value ||\n                       (is_lvalue_reference<_Hp>::value &&\n                        (is_lvalue_reference<_Tp>::value ||\n                         is_same<typename remove_reference<_Tp>::type,\n                                 reference_wrapper<\n                                    typename remove_reference<_Hp>::type\n                                 >\n                                >::value)),\n       \"Attempted to construct a reference element in a tuple with an rvalue\");}\n\n    __tuple_leaf(const __tuple_leaf& __t) = default;\n    __tuple_leaf(__tuple_leaf&& __t) = default;\n\n    template <class _Tp>\n        _LIBCPP_INLINE_VISIBILITY\n        __tuple_leaf&\n        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))\n        {\n            value = _VSTD::forward<_Tp>(__t);\n            return *this;\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)\n    {\n        _VSTD::swap(*this, __t);\n        return 0;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return value;}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return value;}\n};\n\ntemplate <size_t _Ip, class _Hp>\nclass __tuple_leaf<_Ip, _Hp, true>\n    : private _Hp\n{\n\n    __tuple_leaf& operator=(const __tuple_leaf&);\npublic:\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()\n             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}\n\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}\n\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)\n            : _Hp(allocator_arg_t(), __a) {}\n\n    template <class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)\n            : _Hp(__a) {}\n\n    template <class _Tp,\n              class = typename enable_if<\n                  __lazy_and<\n                        __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>>\n                      , is_constructible<_Hp, _Tp>\n                    >::value\n                >::type\n            >\n        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))\n            : _Hp(_VSTD::forward<_Tp>(__t)) {}\n\n    template <class _Tp, class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)\n            : _Hp(_VSTD::forward<_Tp>(__t)) {}\n\n    template <class _Tp, class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)\n            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}\n\n    template <class _Tp, class _Alloc>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)\n            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}\n\n    __tuple_leaf(__tuple_leaf const &) = default;\n    __tuple_leaf(__tuple_leaf &&) = default;\n\n    template <class _Tp>\n        _LIBCPP_INLINE_VISIBILITY\n        __tuple_leaf&\n        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))\n        {\n            _Hp::operator=(_VSTD::forward<_Tp>(__t));\n            return *this;\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    int\n    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)\n    {\n        _VSTD::swap(*this, __t);\n        return 0;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}\n};\n\ntemplate <class ..._Tp>\n_LIBCPP_INLINE_VISIBILITY\nvoid __swallow(_Tp&&...) _NOEXCEPT {}\n\ntemplate <bool ..._Pred>\nstruct __all\n    : is_same<__all<_Pred...>, __all<(_Pred, true)...>>\n{ };\n\ntemplate <class _Tp>\nstruct __all_default_constructible;\n\ntemplate <class ..._Tp>\nstruct __all_default_constructible<__tuple_types<_Tp...>>\n    : __all<is_default_constructible<_Tp>::value...>\n{ };\n\n// __tuple_impl\n\ntemplate<class _Indx, class ..._Tp> struct __tuple_impl;\n\ntemplate<size_t ..._Indx, class ..._Tp>\nstruct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>\n    : public __tuple_leaf<_Indx, _Tp>...\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_CONSTEXPR __tuple_impl()\n        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}\n\n    template <size_t ..._Uf, class ..._Tf,\n              size_t ..._Ul, class ..._Tl, class ..._Up>\n        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n        explicit\n        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,\n                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,\n                     _Up&&... __u)\n                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&\n                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :\n            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,\n            __tuple_leaf<_Ul, _Tl>()...\n            {}\n\n    template <class _Alloc, size_t ..._Uf, class ..._Tf,\n              size_t ..._Ul, class ..._Tl, class ..._Up>\n        _LIBCPP_INLINE_VISIBILITY\n        explicit\n        __tuple_impl(allocator_arg_t, const _Alloc& __a,\n                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,\n                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,\n                     _Up&&... __u) :\n            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,\n            _VSTD::forward<_Up>(__u))...,\n            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...\n            {}\n\n    template <class _Tuple,\n              class = typename enable_if\n                      <\n                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value\n                      >::type\n             >\n        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,\n                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))\n            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,\n                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...\n            {}\n\n    template <class _Alloc, class _Tuple,\n              class = typename enable_if\n                      <\n                         __tuple_convertible<_Tuple, tuple<_Tp...> >::value\n                      >::type\n             >\n        _LIBCPP_INLINE_VISIBILITY\n        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)\n            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,\n                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,\n                                       _VSTD::forward<typename tuple_element<_Indx,\n                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...\n            {}\n\n    template <class _Tuple>\n        _LIBCPP_INLINE_VISIBILITY\n        typename enable_if\n        <\n            __tuple_assignable<_Tuple, tuple<_Tp...> >::value,\n            __tuple_impl&\n        >::type\n        operator=(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_assignable<_Tp&, typename tuple_element<_Indx,\n                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))\n        {\n            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx,\n                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...);\n            return *this;\n        }\n\n    __tuple_impl(const __tuple_impl&) = default;\n    __tuple_impl(__tuple_impl&&) = default;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __tuple_impl&\n    operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))\n    {\n        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __tuple_impl&\n    operator=(__tuple_impl&& __t) _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))\n    {\n        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t).get()))...);\n        return *this;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(__tuple_impl& __t)\n        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)\n    {\n        __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);\n    }\n};\n\ntemplate <class ..._Tp>\nclass _LIBCPP_TYPE_VIS_ONLY tuple\n{\n    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;\n\n    base base_;\n\n    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11\n        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;\n    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11\n        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;\n    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11\n        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;\npublic:\n\n    template <bool _Dummy = true, class = typename enable_if<\n        __all<__dependent_type<is_default_constructible<_Tp>, _Dummy>::value...>::value\n    >::type>\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_CONSTEXPR tuple()\n        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) \n        : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),\n                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),\n                typename __make_tuple_indices<0>::type(),\n                typename __make_tuple_types<tuple, 0>::type(),\n                __t...\n               ) {}\n\n    template <class _Alloc>\n      _LIBCPP_INLINE_VISIBILITY\n      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)\n        : base_(allocator_arg_t(), __a,\n                typename __make_tuple_indices<sizeof...(_Tp)>::type(),\n                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),\n                typename __make_tuple_indices<0>::type(),\n                typename __make_tuple_types<tuple, 0>::type(),\n                __t...\n               ) {}\n\n    template <class ..._Up,\n              typename enable_if\n                      <\n                         sizeof...(_Up) <= sizeof...(_Tp) &&\n                         __tuple_convertible\n                         <\n                            tuple<_Up...>,\n                            typename __make_tuple_types<tuple,\n                                     sizeof...(_Up) < sizeof...(_Tp) ?\n                                        sizeof...(_Up) :\n                                        sizeof...(_Tp)>::type\n                         >::value &&\n                         __all_default_constructible<\n                            typename __make_tuple_types<tuple, sizeof...(_Tp),\n                                sizeof...(_Up) < sizeof...(_Tp) ?\n                                    sizeof...(_Up) :\n                                    sizeof...(_Tp)>::type\n                         >::value,\n                         bool\n                      >::type = false\n             >\n        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n        tuple(_Up&&... __u)\n            _NOEXCEPT_((\n                is_nothrow_constructible<base,\n                    typename __make_tuple_indices<sizeof...(_Up)>::type,\n                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,\n                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,\n                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,\n                    _Up...\n                >::value\n            ))\n            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),\n                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),\n                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),\n                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),\n                    _VSTD::forward<_Up>(__u)...) {}\n\n    template <class ..._Up,\n              typename enable_if\n                      <\n                         sizeof...(_Up) <= sizeof...(_Tp) &&\n                         __tuple_constructible\n                         <\n                            tuple<_Up...>,\n                            typename __make_tuple_types<tuple,\n                                     sizeof...(_Up) < sizeof...(_Tp) ?\n                                        sizeof...(_Up) :\n                                        sizeof...(_Tp)>::type\n                         >::value &&\n                         !__tuple_convertible\n                         <\n                            tuple<_Up...>,\n                            typename __make_tuple_types<tuple,\n                                     sizeof...(_Up) < sizeof...(_Tp) ?\n                                        sizeof...(_Up) :\n                                        sizeof...(_Tp)>::type\n                         >::value &&\n                         __all_default_constructible<\n                            typename __make_tuple_types<tuple, sizeof...(_Tp),\n                                sizeof...(_Up) < sizeof...(_Tp) ?\n                                    sizeof...(_Up) :\n                                    sizeof...(_Tp)>::type\n                         >::value,\n                         bool\n                      >::type =false\n             >\n        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n        explicit\n        tuple(_Up&&... __u)\n            _NOEXCEPT_((\n                is_nothrow_constructible<base,\n                    typename __make_tuple_indices<sizeof...(_Up)>::type,\n                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,\n                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,\n                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,\n                    _Up...\n                >::value\n            ))\n            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),\n                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),\n                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),\n                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),\n                    _VSTD::forward<_Up>(__u)...) {}\n\n    template <class _Alloc, class ..._Up,\n              class = typename enable_if\n                      <\n                         sizeof...(_Up) <= sizeof...(_Tp) &&\n                         __tuple_convertible\n                         <\n                            tuple<_Up...>,\n                            typename __make_tuple_types<tuple,\n                                     sizeof...(_Up) < sizeof...(_Tp) ?\n                                        sizeof...(_Up) :\n                                        sizeof...(_Tp)>::type\n                         >::value &&\n                         __all_default_constructible<\n                            typename __make_tuple_types<tuple, sizeof...(_Tp),\n                                sizeof...(_Up) < sizeof...(_Tp) ?\n                                    sizeof...(_Up) :\n                                    sizeof...(_Tp)>::type\n                         >::value\n                      >::type\n             >\n        _LIBCPP_INLINE_VISIBILITY\n        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)\n            : base_(allocator_arg_t(), __a,\n                    typename __make_tuple_indices<sizeof...(_Up)>::type(),\n                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),\n                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),\n                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),\n                    _VSTD::forward<_Up>(__u)...) {}\n\n    template <class _Tuple,\n              typename enable_if\n                      <\n                         __tuple_convertible<_Tuple, tuple>::value,\n                         bool\n                      >::type = false\n             >\n        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))\n            : base_(_VSTD::forward<_Tuple>(__t)) {}\n\n    template <class _Tuple,\n              typename enable_if\n                      <\n                         __tuple_constructible<_Tuple, tuple>::value &&\n                         !__tuple_convertible<_Tuple, tuple>::value,\n                         bool\n                      >::type = false\n             >\n        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n        explicit\n        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))\n            : base_(_VSTD::forward<_Tuple>(__t)) {}\n\n    template <class _Alloc, class _Tuple,\n              class = typename enable_if\n                      <\n                         __tuple_convertible<_Tuple, tuple>::value\n                      >::type\n             >\n        _LIBCPP_INLINE_VISIBILITY\n        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)\n            : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}\n\n    template <class _Tuple,\n              class = typename enable_if\n                      <\n                         __tuple_assignable<_Tuple, tuple>::value\n                      >::type\n             >\n        _LIBCPP_INLINE_VISIBILITY\n        tuple&\n        operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<base&, _Tuple>::value))\n        {\n            base_.operator=(_VSTD::forward<_Tuple>(__t));\n            return *this;\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)\n        {base_.swap(__t.base_);}\n};\n\ntemplate <>\nclass _LIBCPP_TYPE_VIS_ONLY tuple<>\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    _LIBCPP_CONSTEXPR tuple() _NOEXCEPT {}\n    template <class _Alloc>\n    _LIBCPP_INLINE_VISIBILITY\n        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}\n    template <class _Alloc>\n    _LIBCPP_INLINE_VISIBILITY\n        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}\n    template <class _Up>\n    _LIBCPP_INLINE_VISIBILITY\n        tuple(array<_Up, 0>) _NOEXCEPT {}\n    template <class _Alloc, class _Up>\n    _LIBCPP_INLINE_VISIBILITY\n        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(tuple&) _NOEXCEPT {}\n};\n\ntemplate <class ..._Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __all<__is_swappable<_Tp>::value...>::value,\n    void\n>::type\nswap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)\n                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)\n    {__t.swap(__u);}\n\n// get\n\ntemplate <size_t _Ip, class ..._Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntypename tuple_element<_Ip, tuple<_Tp...> >::type&\nget(tuple<_Tp...>& __t) _NOEXCEPT\n{\n    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;\n    return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get();\n}\n\ntemplate <size_t _Ip, class ..._Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nconst typename tuple_element<_Ip, tuple<_Tp...> >::type&\nget(const tuple<_Tp...>& __t) _NOEXCEPT\n{\n    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;\n    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get();\n}\n\ntemplate <size_t _Ip, class ..._Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntypename tuple_element<_Ip, tuple<_Tp...> >::type&&\nget(tuple<_Tp...>&& __t) _NOEXCEPT\n{\n    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;\n    return static_cast<type&&>(\n             static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get());\n}\n\n#if _LIBCPP_STD_VER > 11\n// get by type\ntemplate <typename _T1, size_t _Idx, typename... _Args>\nstruct __find_exactly_one_t_helper;\n\n// -- find exactly one\ntemplate <typename _T1, size_t _Idx, typename... _Args>\nstruct __find_exactly_one_t_checker {\n    static constexpr size_t value = _Idx;\n//  Check the rest of the list to make sure there's only one\n    static_assert ( __find_exactly_one_t_helper<_T1, 0, _Args...>::value == -1, \"type can only occur once in type list\" );\n    };\n\n\ntemplate <typename _T1, size_t _Idx>\nstruct __find_exactly_one_t_helper <_T1, _Idx> {\n    static constexpr size_t value = -1;\n    };\n\ntemplate <typename _T1, size_t _Idx, typename _Head, typename... _Args>\nstruct __find_exactly_one_t_helper <_T1, _Idx, _Head, _Args...> {\n    static constexpr size_t value =\n        std::conditional<\n            std::is_same<_T1, _Head>::value,\n            __find_exactly_one_t_checker<_T1, _Idx,   _Args...>,\n            __find_exactly_one_t_helper <_T1, _Idx+1, _Args...>\n        >::type::value;\n    };\n\ntemplate <typename _T1, typename... _Args>\nstruct __find_exactly_one_t {\n    static constexpr size_t value = __find_exactly_one_t_helper<_T1, 0, _Args...>::value;\n    static_assert ( value != -1, \"type not found in type list\" );\n    };\n\ntemplate <class _T1, class... _Args>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr _T1& get(tuple<_Args...>& __tup) noexcept\n{\n    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);\n}\n\ntemplate <class _T1, class... _Args>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept\n{\n    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);\n}\n\ntemplate <class _T1, class... _Args>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr _T1&& get(tuple<_Args...>&& __tup) noexcept\n{\n    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));\n}\n\n#endif\n\n// tie\n\ntemplate <class ..._Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntuple<_Tp&...>\ntie(_Tp&... __t) _NOEXCEPT\n{\n    return tuple<_Tp&...>(__t...);\n}\n\ntemplate <class _Up>\nstruct __ignore_t\n{\n    template <class _Tp>\n        _LIBCPP_INLINE_VISIBILITY\n        const __ignore_t& operator=(_Tp&&) const {return *this;}\n};\n\nnamespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }\n\ntemplate <class _Tp>\nstruct __make_tuple_return_impl\n{\n    typedef _Tp type;\n};\n\ntemplate <class _Tp>\nstruct __make_tuple_return_impl<reference_wrapper<_Tp> >\n{\n    typedef _Tp& type;\n};\n\ntemplate <class _Tp>\nstruct __make_tuple_return\n{\n    typedef typename __make_tuple_return_impl<typename decay<_Tp>::type>::type type;\n};\n\ntemplate <class... _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntuple<typename __make_tuple_return<_Tp>::type...>\nmake_tuple(_Tp&&... __t)\n{\n    return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);\n}\n\ntemplate <class... _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntuple<_Tp&&...>\nforward_as_tuple(_Tp&&... __t) _NOEXCEPT\n{\n    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);\n}\n\ntemplate <size_t _Ip>\nstruct __tuple_equal\n{\n    template <class _Tp, class _Up>\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    bool operator()(const _Tp& __x, const _Up& __y)\n    {\n        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);\n    }\n};\n\ntemplate <>\nstruct __tuple_equal<0>\n{\n    template <class _Tp, class _Up>\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    bool operator()(const _Tp&, const _Up&)\n    {\n        return true;\n    }\n};\n\ntemplate <class ..._Tp, class ..._Up>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)\n{\n    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);\n}\n\ntemplate <class ..._Tp, class ..._Up>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <size_t _Ip>\nstruct __tuple_less\n{\n    template <class _Tp, class _Up>\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    bool operator()(const _Tp& __x, const _Up& __y)\n    {\n        const size_t __idx = tuple_size<_Tp>::value - _Ip;\n        if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))\n            return true;\n        if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))\n            return false;\n        return __tuple_less<_Ip-1>()(__x, __y);\n    }\n};\n\ntemplate <>\nstruct __tuple_less<0>\n{\n    template <class _Tp, class _Up>\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    bool operator()(const _Tp&, const _Up&)\n    {\n        return false;\n    }\n};\n\ntemplate <class ..._Tp, class ..._Up>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)\n{\n    return __tuple_less<sizeof...(_Tp)>()(__x, __y);\n}\n\ntemplate <class ..._Tp, class ..._Up>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class ..._Tp, class ..._Up>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class ..._Tp, class ..._Up>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)\n{\n    return !(__y < __x);\n}\n\n// tuple_cat\n\ntemplate <class _Tp, class _Up> struct __tuple_cat_type;\n\ntemplate <class ..._Ttypes, class ..._Utypes>\nstruct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >\n{\n    typedef tuple<_Ttypes..., _Utypes...> type;\n};\n\ntemplate <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>\nstruct __tuple_cat_return_1\n{\n};\n\ntemplate <class ..._Types, class _Tuple0>\nstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>\n{\n    typedef typename __tuple_cat_type<tuple<_Types...>,\n            typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type>::type\n                                                                           type;\n};\n\ntemplate <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>\nstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>\n    : public __tuple_cat_return_1<\n                 typename __tuple_cat_type<\n                     tuple<_Types...>,\n                     typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type\n                 >::type,\n                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,\n                 _Tuple1, _Tuples...>\n{\n};\n\ntemplate <class ..._Tuples> struct __tuple_cat_return;\n\ntemplate <class _Tuple0, class ..._Tuples>\nstruct __tuple_cat_return<_Tuple0, _Tuples...>\n    : public __tuple_cat_return_1<tuple<>,\n         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,\n                                                                     _Tuples...>\n{\n};\n\ntemplate <>\nstruct __tuple_cat_return<>\n{\n    typedef tuple<> type;\n};\n\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntuple<>\ntuple_cat()\n{\n    return tuple<>();\n}\n\ntemplate <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>\nstruct __tuple_cat_return_ref_imp;\n\ntemplate <class ..._Types, size_t ..._I0, class _Tuple0>\nstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>\n{\n    typedef typename remove_reference<_Tuple0>::type _T0;\n    typedef tuple<_Types..., typename __apply_cv<_Tuple0,\n                          typename tuple_element<_I0, _T0>::type>::type&&...> type;\n};\n\ntemplate <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>\nstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,\n                                  _Tuple0, _Tuple1, _Tuples...>\n    : public __tuple_cat_return_ref_imp<\n         tuple<_Types..., typename __apply_cv<_Tuple0,\n               typename tuple_element<_I0,\n                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,\n         typename __make_tuple_indices<tuple_size<typename\n                                 remove_reference<_Tuple1>::type>::value>::type,\n         _Tuple1, _Tuples...>\n{\n};\n\ntemplate <class _Tuple0, class ..._Tuples>\nstruct __tuple_cat_return_ref\n    : public __tuple_cat_return_ref_imp<tuple<>,\n               typename __make_tuple_indices<\n                        tuple_size<typename remove_reference<_Tuple0>::type>::value\n               >::type, _Tuple0, _Tuples...>\n{\n};\n\ntemplate <class _Types, class _I0, class _J0>\nstruct __tuple_cat;\n\ntemplate <class ..._Types, size_t ..._I0, size_t ..._J0>\nstruct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >\n{\n    template <class _Tuple0>\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type\n    operator()(tuple<_Types...> __t, _Tuple0&& __t0)\n    {\n        return forward_as_tuple(_VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,\n                                      _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);\n    }\n\n    template <class _Tuple0, class _Tuple1, class ..._Tuples>\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type\n    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)\n    {\n        typedef typename remove_reference<_Tuple0>::type _T0;\n        typedef typename remove_reference<_Tuple1>::type _T1;\n        return __tuple_cat<\n           tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>,\n           typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type,\n           typename __make_tuple_indices<tuple_size<_T1>::value>::type>()\n                           (forward_as_tuple(\n                              _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,\n                              _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...\n                            ),\n                            _VSTD::forward<_Tuple1>(__t1),\n                            _VSTD::forward<_Tuples>(__tpls)...);\n    }\n};\n\ntemplate <class _Tuple0, class... _Tuples>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntypename __tuple_cat_return<_Tuple0, _Tuples...>::type\ntuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)\n{\n    typedef typename remove_reference<_Tuple0>::type _T0;\n    return __tuple_cat<tuple<>, __tuple_indices<>,\n                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()\n                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),\n                                            _VSTD::forward<_Tuples>(__tpls)...);\n}\n\ntemplate <class ..._Tp, class _Alloc>\nstruct _LIBCPP_TYPE_VIS_ONLY uses_allocator<tuple<_Tp...>, _Alloc>\n    : true_type {};\n\ntemplate <class _T1, class _T2>\ntemplate <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>\ninline _LIBCPP_INLINE_VISIBILITY\npair<_T1, _T2>::pair(piecewise_construct_t,\n                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,\n                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)\n    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),\n      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)\n{\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_TUPLE\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/type_traits",
    "content": "// -*- C++ -*-\n//===------------------------ type_traits ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_TYPE_TRAITS\n#define _LIBCPP_TYPE_TRAITS\n\n/*\n    type_traits synopsis\n\nnamespace std\n{\n\n    // helper class:\n    template <class T, T v> struct integral_constant;\n    typedef integral_constant<bool, true>  true_type;   // C++11\n    typedef integral_constant<bool, false> false_type;  // C++11\n    \n    template <bool B>                                   // C++14\n    using bool_constant = integral_constant<bool, B>;   // C++14\n    typedef bool_constant<true> true_type;              // C++14\n    typedef bool_constant<false> false_type;            // C++14\n\n    // helper traits\n    template <bool, class T = void> struct enable_if;\n    template <bool, class T, class F> struct conditional;\n\n    // Primary classification traits:\n    template <class T> struct is_void;\n    template <class T> struct is_null_pointer;  // C++14\n    template <class T> struct is_integral;\n    template <class T> struct is_floating_point;\n    template <class T> struct is_array;\n    template <class T> struct is_pointer;\n    template <class T> struct is_lvalue_reference;\n    template <class T> struct is_rvalue_reference;\n    template <class T> struct is_member_object_pointer;\n    template <class T> struct is_member_function_pointer;\n    template <class T> struct is_enum;\n    template <class T> struct is_union;\n    template <class T> struct is_class;\n    template <class T> struct is_function;\n\n    // Secondary classification traits:\n    template <class T> struct is_reference;\n    template <class T> struct is_arithmetic;\n    template <class T> struct is_fundamental;\n    template <class T> struct is_member_pointer;\n    template <class T> struct is_scalar;\n    template <class T> struct is_object;\n    template <class T> struct is_compound;\n\n    // Const-volatile properties and transformations:\n    template <class T> struct is_const;\n    template <class T> struct is_volatile;\n    template <class T> struct remove_const;\n    template <class T> struct remove_volatile;\n    template <class T> struct remove_cv;\n    template <class T> struct add_const;\n    template <class T> struct add_volatile;\n    template <class T> struct add_cv;\n\n    // Reference transformations:\n    template <class T> struct remove_reference;\n    template <class T> struct add_lvalue_reference;\n    template <class T> struct add_rvalue_reference;\n\n    // Pointer transformations:\n    template <class T> struct remove_pointer;\n    template <class T> struct add_pointer;\n\n    // Integral properties:\n    template <class T> struct is_signed;\n    template <class T> struct is_unsigned;\n    template <class T> struct make_signed;\n    template <class T> struct make_unsigned;\n\n    // Array properties and transformations:\n    template <class T> struct rank;\n    template <class T, unsigned I = 0> struct extent;\n    template <class T> struct remove_extent;\n    template <class T> struct remove_all_extents;\n\n    // Member introspection:\n    template <class T> struct is_pod;\n    template <class T> struct is_trivial;\n    template <class T> struct is_trivially_copyable;\n    template <class T> struct is_standard_layout;\n    template <class T> struct is_literal_type;\n    template <class T> struct is_empty;\n    template <class T> struct is_polymorphic;\n    template <class T> struct is_abstract;\n    template <class T> struct is_final; // C++14\n\n    template <class T, class... Args> struct is_constructible;\n    template <class T>                struct is_default_constructible;\n    template <class T>                struct is_copy_constructible;\n    template <class T>                struct is_move_constructible;\n    template <class T, class U>       struct is_assignable;\n    template <class T>                struct is_copy_assignable;\n    template <class T>                struct is_move_assignable;\n    template <class T>                struct is_destructible;\n\n    template <class T, class... Args> struct is_trivially_constructible;\n    template <class T>                struct is_trivially_default_constructible;\n    template <class T>                struct is_trivially_copy_constructible;\n    template <class T>                struct is_trivially_move_constructible;\n    template <class T, class U>       struct is_trivially_assignable;\n    template <class T>                struct is_trivially_copy_assignable;\n    template <class T>                struct is_trivially_move_assignable;\n    template <class T>                struct is_trivially_destructible;\n\n    template <class T, class... Args> struct is_nothrow_constructible;\n    template <class T>                struct is_nothrow_default_constructible;\n    template <class T>                struct is_nothrow_copy_constructible;\n    template <class T>                struct is_nothrow_move_constructible;\n    template <class T, class U>       struct is_nothrow_assignable;\n    template <class T>                struct is_nothrow_copy_assignable;\n    template <class T>                struct is_nothrow_move_assignable;\n    template <class T>                struct is_nothrow_destructible;\n\n    template <class T> struct has_virtual_destructor;\n\n    // Relationships between types:\n    template <class T, class U> struct is_same;\n    template <class Base, class Derived> struct is_base_of;\n    template <class From, class To> struct is_convertible;\n\n    // Alignment properties and transformations:\n    template <class T> struct alignment_of;\n    template <size_t Len, size_t Align = most_stringent_alignment_requirement>\n        struct aligned_storage;\n    template <size_t Len, class... Types> struct aligned_union;\n\n    template <class T> struct decay;\n    template <class... T> struct common_type;\n    template <class T> struct underlying_type;\n    template <class> class result_of; // undefined\n    template <class Fn, class... ArgTypes> class result_of<Fn(ArgTypes...)>;\n\n    // const-volatile modifications:\n    template <class T>\n      using remove_const_t    = typename remove_const<T>::type;  // C++14\n    template <class T>\n      using remove_volatile_t = typename remove_volatile<T>::type;  // C++14\n    template <class T>\n      using remove_cv_t       = typename remove_cv<T>::type;  // C++14\n    template <class T>\n      using add_const_t       = typename add_const<T>::type;  // C++14\n    template <class T>\n      using add_volatile_t    = typename add_volatile<T>::type;  // C++14\n    template <class T>\n      using add_cv_t          = typename add_cv<T>::type;  // C++14\n  \n    // reference modifications:\n    template <class T>\n      using remove_reference_t     = typename remove_reference<T>::type;  // C++14\n    template <class T>\n      using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;  // C++14\n    template <class T>\n      using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;  // C++14\n  \n    // sign modifications:\n    template <class T>\n      using make_signed_t   = typename make_signed<T>::type;  // C++14\n    template <class T>\n      using make_unsigned_t = typename make_unsigned<T>::type;  // C++14\n  \n    // array modifications:\n    template <class T>\n      using remove_extent_t      = typename remove_extent<T>::type;  // C++14\n    template <class T>\n      using remove_all_extents_t = typename remove_all_extents<T>::type;  // C++14\n\n    // pointer modifications:\n    template <class T>\n      using remove_pointer_t = typename remove_pointer<T>::type;  // C++14\n    template <class T>\n      using add_pointer_t    = typename add_pointer<T>::type;  // C++14\n\n    // other transformations:\n    template <size_t Len, std::size_t Align=default-alignment>\n      using aligned_storage_t = typename aligned_storage<Len,Align>::type;  // C++14\n    template <std::size_t Len, class... Types>\n      using aligned_union_t   = typename aligned_union<Len,Types...>::type;  // C++14\n    template <class T>\n      using decay_t           = typename decay<T>::type;  // C++14\n    template <bool b, class T=void>\n      using enable_if_t       = typename enable_if<b,T>::type;  // C++14\n    template <bool b, class T, class F>\n      using conditional_t     = typename conditional<b,T,F>::type;  // C++14\n    template <class... T>\n      using common_type_t     = typename common_type<T...>::type;  // C++14\n    template <class T>\n      using underlying_type_t = typename underlying_type<T>::type;  // C++14\n    template <class F, class... ArgTypes>\n      using result_of_t       = typename result_of<F(ArgTypes...)>::type;  // C++14\n\n    template <class...>\n      using void_t = void;\n}  // C++17\n\n*/\n#include <__config>\n#include <cstddef>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class>\nstruct __void_t { typedef void type; };\n\ntemplate <class _Tp>\nstruct __identity { typedef _Tp type; };\n\ntemplate <class _Tp, bool>\nstruct _LIBCPP_TYPE_VIS_ONLY __dependent_type : public _Tp {};\n\ntemplate <bool _Bp, class _If, class _Then>\n    struct _LIBCPP_TYPE_VIS_ONLY conditional {typedef _If type;};\ntemplate <class _If, class _Then>\n    struct _LIBCPP_TYPE_VIS_ONLY conditional<false, _If, _Then> {typedef _Then type;};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <bool _Bp, class _If, class _Then> using conditional_t = typename conditional<_Bp, _If, _Then>::type;\n#endif\n\ntemplate <bool, class _Tp> struct _LIBCPP_TYPE_VIS_ONLY __lazy_enable_if {};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY __lazy_enable_if<true, _Tp> {typedef typename _Tp::type type;};\n\ntemplate <bool, class _Tp = void> struct _LIBCPP_TYPE_VIS_ONLY enable_if {};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY enable_if<true, _Tp> {typedef _Tp type;};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;\n#endif\n\n\nstruct __two {char __lx[2];};\n\n// helper class:\n\ntemplate <class _Tp, _Tp __v>\nstruct _LIBCPP_TYPE_VIS_ONLY integral_constant\n{\n    static _LIBCPP_CONSTEXPR const _Tp      value = __v;\n    typedef _Tp               value_type;\n    typedef integral_constant type;\n    _LIBCPP_INLINE_VISIBILITY\n        _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT {return value;}\n#if _LIBCPP_STD_VER > 11\n    _LIBCPP_INLINE_VISIBILITY\n         constexpr value_type operator ()() const _NOEXCEPT {return value;}\n#endif\n};\n\ntemplate <class _Tp, _Tp __v>\n_LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value;\n\n#if _LIBCPP_STD_VER > 14\ntemplate <bool __b>\nusing bool_constant = integral_constant<bool, __b>;\n#define\t_LIBCPP_BOOL_CONSTANT(__b) bool_constant<(__b)>\n#else\n#define\t_LIBCPP_BOOL_CONSTANT(__b) integral_constant<bool,(__b)>\n#endif\n\ntypedef _LIBCPP_BOOL_CONSTANT(true)  true_type;\ntypedef _LIBCPP_BOOL_CONSTANT(false) false_type;\n\n// is_const\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_const            : public false_type {};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_const<_Tp const> : public true_type {};\n\n// is_volatile\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_volatile               : public false_type {};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_volatile<_Tp volatile> : public true_type {};\n\n// remove_const\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_const            {typedef _Tp type;};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_const<const _Tp> {typedef _Tp type;};\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using remove_const_t = typename remove_const<_Tp>::type;\n#endif\n\n// remove_volatile\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_volatile               {typedef _Tp type;};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_volatile<volatile _Tp> {typedef _Tp type;};\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using remove_volatile_t = typename remove_volatile<_Tp>::type;\n#endif\n\n// remove_cv\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_cv\n{typedef typename remove_volatile<typename remove_const<_Tp>::type>::type type;};\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using remove_cv_t = typename remove_cv<_Tp>::type;\n#endif\n\n// is_void\n\ntemplate <class _Tp> struct __libcpp_is_void       : public false_type {};\ntemplate <>          struct __libcpp_is_void<void> : public true_type {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_void\n    : public __libcpp_is_void<typename remove_cv<_Tp>::type> {};\n\n// __is_nullptr_t\n\ntemplate <class _Tp> struct __is_nullptr_t_impl       : public false_type {};\ntemplate <>          struct __is_nullptr_t_impl<nullptr_t> : public true_type {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY __is_nullptr_t\n    : public __is_nullptr_t_impl<typename remove_cv<_Tp>::type> {};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_null_pointer\n    : public __is_nullptr_t_impl<typename remove_cv<_Tp>::type> {};\n#endif\n\n// is_integral\n\ntemplate <class _Tp> struct __libcpp_is_integral                     : public false_type {};\ntemplate <>          struct __libcpp_is_integral<bool>               : public true_type {};\ntemplate <>          struct __libcpp_is_integral<char>               : public true_type {};\ntemplate <>          struct __libcpp_is_integral<signed char>        : public true_type {};\ntemplate <>          struct __libcpp_is_integral<unsigned char>      : public true_type {};\ntemplate <>          struct __libcpp_is_integral<wchar_t>            : public true_type {};\n#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS\ntemplate <>          struct __libcpp_is_integral<char16_t>           : public true_type {};\ntemplate <>          struct __libcpp_is_integral<char32_t>           : public true_type {};\n#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS\ntemplate <>          struct __libcpp_is_integral<short>              : public true_type {};\ntemplate <>          struct __libcpp_is_integral<unsigned short>     : public true_type {};\ntemplate <>          struct __libcpp_is_integral<int>                : public true_type {};\ntemplate <>          struct __libcpp_is_integral<unsigned int>       : public true_type {};\ntemplate <>          struct __libcpp_is_integral<long>               : public true_type {};\ntemplate <>          struct __libcpp_is_integral<unsigned long>      : public true_type {};\ntemplate <>          struct __libcpp_is_integral<long long>          : public true_type {};\ntemplate <>          struct __libcpp_is_integral<unsigned long long> : public true_type {};\n#ifndef _LIBCPP_HAS_NO_INT128\ntemplate <>          struct __libcpp_is_integral<__int128_t>         : public true_type {};\ntemplate <>          struct __libcpp_is_integral<__uint128_t>        : public true_type {};\n#endif\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_integral\n    : public __libcpp_is_integral<typename remove_cv<_Tp>::type> {};\n\n// is_floating_point\n\ntemplate <class _Tp> struct __libcpp_is_floating_point              : public false_type {};\ntemplate <>          struct __libcpp_is_floating_point<float>       : public true_type {};\ntemplate <>          struct __libcpp_is_floating_point<double>      : public true_type {};\ntemplate <>          struct __libcpp_is_floating_point<long double> : public true_type {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_floating_point\n    : public __libcpp_is_floating_point<typename remove_cv<_Tp>::type> {};\n\n// is_array\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_array\n    : public false_type {};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_array<_Tp[]>\n    : public true_type {};\ntemplate <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY is_array<_Tp[_Np]>\n    : public true_type {};\n\n// is_pointer\n\ntemplate <class _Tp> struct __libcpp_is_pointer       : public false_type {};\ntemplate <class _Tp> struct __libcpp_is_pointer<_Tp*> : public true_type {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_pointer\n    : public __libcpp_is_pointer<typename remove_cv<_Tp>::type> {};\n\n// is_reference\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_lvalue_reference       : public false_type {};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_lvalue_reference<_Tp&> : public true_type {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_rvalue_reference        : public false_type {};\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_rvalue_reference<_Tp&&> : public true_type {};\n#endif\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_reference        : public false_type {};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_reference<_Tp&>  : public true_type {};\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_reference<_Tp&&> : public true_type {};\n#endif\n\n// is_union\n\n#if __has_feature(is_union) || (_GNUC_VER >= 403)\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_union\n    : public integral_constant<bool, __is_union(_Tp)> {};\n\n#else\n\ntemplate <class _Tp> struct __libcpp_union : public false_type {};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_union\n    : public __libcpp_union<typename remove_cv<_Tp>::type> {};\n\n#endif\n\n// is_class\n\n#if __has_feature(is_class) || (_GNUC_VER >= 403)\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_class\n    : public integral_constant<bool, __is_class(_Tp)> {};\n\n#else\n\nnamespace __is_class_imp\n{\ntemplate <class _Tp> char  __test(int _Tp::*);\ntemplate <class _Tp> __two __test(...);\n}\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_class\n    : public integral_constant<bool, sizeof(__is_class_imp::__test<_Tp>(0)) == 1 && !is_union<_Tp>::value> {};\n\n#endif\n\n// is_same\n\ntemplate <class _Tp, class _Up> struct _LIBCPP_TYPE_VIS_ONLY is_same           : public false_type {};\ntemplate <class _Tp>            struct _LIBCPP_TYPE_VIS_ONLY is_same<_Tp, _Tp> : public true_type {};\n\n// is_function\n\nnamespace __libcpp_is_function_imp\n{\nstruct __dummy_type {};\ntemplate <class _Tp> char  __test(_Tp*);\ntemplate <class _Tp> char __test(__dummy_type);\ntemplate <class _Tp> __two __test(...);\ntemplate <class _Tp> _Tp&  __source(int);\ntemplate <class _Tp> __dummy_type __source(...);\n}\n\ntemplate <class _Tp, bool = is_class<_Tp>::value ||\n                            is_union<_Tp>::value ||\n                            is_void<_Tp>::value  ||\n                            is_reference<_Tp>::value ||\n                            __is_nullptr_t<_Tp>::value >\nstruct __libcpp_is_function\n    : public integral_constant<bool, sizeof(__libcpp_is_function_imp::__test<_Tp>(__libcpp_is_function_imp::__source<_Tp>(0))) == 1>\n    {};\ntemplate <class _Tp> struct __libcpp_is_function<_Tp, true> : public false_type {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_function\n    : public __libcpp_is_function<_Tp> {};\n\n// is_member_function_pointer\n\n// template <class _Tp> struct            __libcpp_is_member_function_pointer             : public false_type {};\n// template <class _Tp, class _Up> struct __libcpp_is_member_function_pointer<_Tp _Up::*> : public is_function<_Tp> {};\n// \n\ntemplate <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>\nstruct __member_pointer_traits_imp\n{  // forward declaration; specializations later\n};\n\n\ntemplate <class _Tp> struct __libcpp_is_member_function_pointer\n    : public false_type {};\n\ntemplate <class _Ret, class _Class>\nstruct __libcpp_is_member_function_pointer<_Ret _Class::*>\n    : public is_function<_Ret> {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_function_pointer\n    : public __libcpp_is_member_function_pointer<typename remove_cv<_Tp>::type>::type {};\n\n// is_member_pointer\n\ntemplate <class _Tp>            struct __libcpp_is_member_pointer             : public false_type {};\ntemplate <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> : public true_type {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_pointer\n    : public __libcpp_is_member_pointer<typename remove_cv<_Tp>::type> {};\n\n// is_member_object_pointer\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_object_pointer\n    : public integral_constant<bool, is_member_pointer<_Tp>::value &&\n                                    !is_member_function_pointer<_Tp>::value> {};\n\n// is_enum\n\n#if __has_feature(is_enum) || (_GNUC_VER >= 403)\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_enum\n    : public integral_constant<bool, __is_enum(_Tp)> {};\n\n#else\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_enum\n    : public integral_constant<bool, !is_void<_Tp>::value             &&\n                                     !is_integral<_Tp>::value         &&\n                                     !is_floating_point<_Tp>::value   &&\n                                     !is_array<_Tp>::value            &&\n                                     !is_pointer<_Tp>::value          &&\n                                     !is_reference<_Tp>::value        &&\n                                     !is_member_pointer<_Tp>::value   &&\n                                     !is_union<_Tp>::value            &&\n                                     !is_class<_Tp>::value            &&\n                                     !is_function<_Tp>::value         > {};\n\n#endif\n\n// is_arithmetic\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_arithmetic\n    : public integral_constant<bool, is_integral<_Tp>::value      ||\n                                     is_floating_point<_Tp>::value> {};\n\n// is_fundamental\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_fundamental\n    : public integral_constant<bool, is_void<_Tp>::value        ||\n                                     __is_nullptr_t<_Tp>::value ||\n                                     is_arithmetic<_Tp>::value> {};\n\n// is_scalar\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_scalar\n    : public integral_constant<bool, is_arithmetic<_Tp>::value     ||\n                                     is_member_pointer<_Tp>::value ||\n                                     is_pointer<_Tp>::value        ||\n                                     __is_nullptr_t<_Tp>::value    ||\n                                     is_enum<_Tp>::value           > {};\n\ntemplate <> struct _LIBCPP_TYPE_VIS_ONLY is_scalar<nullptr_t> : public true_type {};\n\n// is_object\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_object\n    : public integral_constant<bool, is_scalar<_Tp>::value ||\n                                     is_array<_Tp>::value  ||\n                                     is_union<_Tp>::value  ||\n                                     is_class<_Tp>::value  > {};\n\n// is_compound\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_compound\n    : public integral_constant<bool, !is_fundamental<_Tp>::value> {};\n\n// add_const\n\ntemplate <class _Tp, bool = is_reference<_Tp>::value ||\n                            is_function<_Tp>::value  ||\n                            is_const<_Tp>::value     >\nstruct __add_const             {typedef _Tp type;};\n\ntemplate <class _Tp>\nstruct __add_const<_Tp, false> {typedef const _Tp type;};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_const\n    {typedef typename __add_const<_Tp>::type type;};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using add_const_t = typename add_const<_Tp>::type;\n#endif\n\n// add_volatile\n\ntemplate <class _Tp, bool = is_reference<_Tp>::value ||\n                            is_function<_Tp>::value  ||\n                            is_volatile<_Tp>::value  >\nstruct __add_volatile             {typedef _Tp type;};\n\ntemplate <class _Tp>\nstruct __add_volatile<_Tp, false> {typedef volatile _Tp type;};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_volatile\n    {typedef typename __add_volatile<_Tp>::type type;};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using add_volatile_t = typename add_volatile<_Tp>::type;\n#endif\n\n// add_cv\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_cv\n    {typedef typename add_const<typename add_volatile<_Tp>::type>::type type;};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using add_cv_t = typename add_cv<_Tp>::type;\n#endif\n\n// remove_reference\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference        {typedef _Tp type;};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference<_Tp&>  {typedef _Tp type;};\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference<_Tp&&> {typedef _Tp type;};\n#endif\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using remove_reference_t = typename remove_reference<_Tp>::type;\n#endif\n\n// add_lvalue_reference\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference                      {typedef _Tp& type;};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<_Tp&>                {typedef _Tp& type;};  // for older compiler\ntemplate <>          struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<void>                {typedef void type;};\ntemplate <>          struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<const void>          {typedef const void type;};\ntemplate <>          struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<volatile void>       {typedef volatile void type;};\ntemplate <>          struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<const volatile void> {typedef const volatile void type;};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type;\n#endif\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY  add_rvalue_reference                     {typedef _Tp&& type;};\ntemplate <>          struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<void>                {typedef void type;};\ntemplate <>          struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<const void>          {typedef const void type;};\ntemplate <>          struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<volatile void>       {typedef volatile void type;};\ntemplate <>          struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<const volatile void> {typedef const volatile void type;};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type;\n#endif\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\ntypename add_rvalue_reference<_Tp>::type\ndeclval() _NOEXCEPT;\n\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\ntypename add_lvalue_reference<_Tp>::type\ndeclval();\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\nstruct __any\n{\n    __any(...);\n};\n\n// remove_pointer\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer                      {typedef _Tp type;};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp*>                {typedef _Tp type;};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp* const>          {typedef _Tp type;};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp* volatile>       {typedef _Tp type;};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp* const volatile> {typedef _Tp type;};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using remove_pointer_t = typename remove_pointer<_Tp>::type;\n#endif\n\n// add_pointer\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_pointer\n    {typedef typename remove_reference<_Tp>::type* type;};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using add_pointer_t = typename add_pointer<_Tp>::type;\n#endif\n\n// is_signed\n\ntemplate <class _Tp, bool = is_integral<_Tp>::value>\nstruct __libcpp_is_signed_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(-1) < _Tp(0)) {};\n\ntemplate <class _Tp>\nstruct __libcpp_is_signed_impl<_Tp, false> : public true_type {};  // floating point\n\ntemplate <class _Tp, bool = is_arithmetic<_Tp>::value>\nstruct __libcpp_is_signed : public __libcpp_is_signed_impl<_Tp> {};\n\ntemplate <class _Tp> struct __libcpp_is_signed<_Tp, false> : public false_type {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_signed : public __libcpp_is_signed<_Tp> {};\n\n// is_unsigned\n\ntemplate <class _Tp, bool = is_integral<_Tp>::value>\nstruct __libcpp_is_unsigned_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(0) < _Tp(-1)) {};\n\ntemplate <class _Tp>\nstruct __libcpp_is_unsigned_impl<_Tp, false> : public false_type {};  // floating point\n\ntemplate <class _Tp, bool = is_arithmetic<_Tp>::value>\nstruct __libcpp_is_unsigned : public __libcpp_is_unsigned_impl<_Tp> {};\n\ntemplate <class _Tp> struct __libcpp_is_unsigned<_Tp, false> : public false_type {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_unsigned : public __libcpp_is_unsigned<_Tp> {};\n\n// rank\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY rank\n    : public integral_constant<size_t, 0> {};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY rank<_Tp[]>\n    : public integral_constant<size_t, rank<_Tp>::value + 1> {};\ntemplate <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY rank<_Tp[_Np]>\n    : public integral_constant<size_t, rank<_Tp>::value + 1> {};\n\n// extent\n\ntemplate <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TYPE_VIS_ONLY extent\n    : public integral_constant<size_t, 0> {};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[], 0>\n    : public integral_constant<size_t, 0> {};\ntemplate <class _Tp, unsigned _Ip> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[], _Ip>\n    : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};\ntemplate <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[_Np], 0>\n    : public integral_constant<size_t, _Np> {};\ntemplate <class _Tp, size_t _Np, unsigned _Ip> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[_Np], _Ip>\n    : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};\n\n// remove_extent\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_extent\n    {typedef _Tp type;};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_extent<_Tp[]>\n    {typedef _Tp type;};\ntemplate <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY remove_extent<_Tp[_Np]>\n    {typedef _Tp type;};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using remove_extent_t = typename remove_extent<_Tp>::type;\n#endif\n\n// remove_all_extents\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_all_extents\n    {typedef _Tp type;};\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_all_extents<_Tp[]>\n    {typedef typename remove_all_extents<_Tp>::type type;};\ntemplate <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY remove_all_extents<_Tp[_Np]>\n    {typedef typename remove_all_extents<_Tp>::type type;};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using remove_all_extents_t = typename remove_all_extents<_Tp>::type;\n#endif\n\n// decay\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY decay\n{\nprivate:\n    typedef typename remove_reference<_Tp>::type _Up;\npublic:\n    typedef typename conditional\n                     <\n                         is_array<_Up>::value,\n                         typename remove_extent<_Up>::type*,\n                         typename conditional\n                         <\n                              is_function<_Up>::value,\n                              typename add_pointer<_Up>::type,\n                              typename remove_cv<_Up>::type\n                         >::type\n                     >::type type;\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using decay_t = typename decay<_Tp>::type;\n#endif\n\n// is_abstract\n\nnamespace __is_abstract_imp\n{\ntemplate <class _Tp> char  __test(_Tp (*)[1]);\ntemplate <class _Tp> __two __test(...);\n}\n\ntemplate <class _Tp, bool = is_class<_Tp>::value>\nstruct __libcpp_abstract : public integral_constant<bool, sizeof(__is_abstract_imp::__test<_Tp>(0)) != 1> {};\n\ntemplate <class _Tp> struct __libcpp_abstract<_Tp, false> : public false_type {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_abstract : public __libcpp_abstract<_Tp> {};\n\n// is_final\n\n#if defined(_LIBCPP_HAS_IS_FINAL)\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY\n__libcpp_is_final : public integral_constant<bool, __is_final(_Tp)> {};\n#else\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY\n__libcpp_is_final : public false_type {};\n#endif\n\n#if defined(_LIBCPP_HAS_IS_FINAL) && _LIBCPP_STD_VER > 11\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY\nis_final : public integral_constant<bool, __is_final(_Tp)> {};\n#endif\n\n// is_base_of\n\n#ifdef _LIBCPP_HAS_IS_BASE_OF\n\ntemplate <class _Bp, class _Dp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_base_of\n    : public integral_constant<bool, __is_base_of(_Bp, _Dp)> {};\n\n#else  // _LIBCPP_HAS_IS_BASE_OF\n\nnamespace __is_base_of_imp\n{\ntemplate <class _Tp>\nstruct _Dst\n{\n    _Dst(const volatile _Tp &);\n};\ntemplate <class _Tp>\nstruct _Src\n{\n    operator const volatile _Tp &();\n    template <class _Up> operator const _Dst<_Up> &();\n};\ntemplate <size_t> struct __one { typedef char type; };\ntemplate <class _Bp, class _Dp> typename __one<sizeof(_Dst<_Bp>(declval<_Src<_Dp> >()))>::type __test(int);\ntemplate <class _Bp, class _Dp> __two __test(...);\n}\n\ntemplate <class _Bp, class _Dp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_base_of\n    : public integral_constant<bool, is_class<_Bp>::value &&\n                                     sizeof(__is_base_of_imp::__test<_Bp, _Dp>(0)) == 2> {};\n\n#endif  // _LIBCPP_HAS_IS_BASE_OF\n\n// is_convertible\n\n#if __has_feature(is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)\n\ntemplate <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY is_convertible\n    : public integral_constant<bool, __is_convertible_to(_T1, _T2) &&\n                                     !is_abstract<_T2>::value> {};\n\n#else  // __has_feature(is_convertible_to)\n\nnamespace __is_convertible_imp\n{\ntemplate <class _Tp> void  __test_convert(_Tp);\n\ntemplate <class _From, class _To, class = void>\nstruct __is_convertible_test : public false_type {};\n\ntemplate <class _From, class _To>\nstruct __is_convertible_test<_From, _To,\n    decltype(__test_convert<_To>(_VSTD::declval<_From>()))> : public true_type\n{};\n\ntemplate <class _Tp> __two __test(...);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\ntemplate <class _Tp> _Tp&& __source();\n#else\ntemplate <class _Tp> typename remove_reference<_Tp>::type& __source();\n#endif\n\ntemplate <class _Tp, bool _IsArray =    is_array<_Tp>::value,\n                     bool _IsFunction = is_function<_Tp>::value,\n                     bool _IsVoid =     is_void<_Tp>::value>\n                     struct __is_array_function_or_void                          {enum {value = 0};};\ntemplate <class _Tp> struct __is_array_function_or_void<_Tp, true, false, false> {enum {value = 1};};\ntemplate <class _Tp> struct __is_array_function_or_void<_Tp, false, true, false> {enum {value = 2};};\ntemplate <class _Tp> struct __is_array_function_or_void<_Tp, false, false, true> {enum {value = 3};};\n}\n\ntemplate <class _Tp,\n    unsigned = __is_convertible_imp::__is_array_function_or_void<typename remove_reference<_Tp>::type>::value>\nstruct __is_convertible_check\n{\n    static const size_t __v = 0;\n};\n\ntemplate <class _Tp>\nstruct __is_convertible_check<_Tp, 0>\n{\n    static const size_t __v = sizeof(_Tp);\n};\n\ntemplate <class _T1, class _T2,\n    unsigned _T1_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T1>::value,\n    unsigned _T2_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T2>::value>\nstruct __is_convertible\n    : public integral_constant<bool,\n        __is_convertible_imp::__is_convertible_test<_T1, _T2>::value\n#if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n         && !(!is_function<_T1>::value && !is_reference<_T1>::value && is_reference<_T2>::value\n              && (!is_const<typename remove_reference<_T2>::type>::value\n                  || is_volatile<typename remove_reference<_T2>::type>::value)\n                  && (is_same<typename remove_cv<_T1>::type,\n                              typename remove_cv<typename remove_reference<_T2>::type>::type>::value\n                      || is_base_of<typename remove_reference<_T2>::type, _T1>::value))\n#endif\n    >\n{};\n\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 0> : false_type {};\n\ntemplate <class _T1> struct __is_convertible<_T1, const _T1&, 1, 0> : true_type {};\ntemplate <class _T1> struct __is_convertible<const _T1, const _T1&, 1, 0> : true_type {};\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\ntemplate <class _T1> struct __is_convertible<_T1, _T1&&, 1, 0> : true_type {};\ntemplate <class _T1> struct __is_convertible<_T1, const _T1&&, 1, 0> : true_type {};\ntemplate <class _T1> struct __is_convertible<_T1, volatile _T1&&, 1, 0> : true_type {};\ntemplate <class _T1> struct __is_convertible<_T1, const volatile _T1&&, 1, 0> : true_type {};\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2*, 1, 0>\n    : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*>::value> {};\n\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2* const, 1, 0>\n    : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*const>::value> {};\n\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2* volatile, 1, 0>\n    : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*volatile>::value> {};\n\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2* const volatile, 1, 0>\n    : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*const volatile>::value> {};\n\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 0>                : public false_type {};\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\ntemplate <class _T1>            struct __is_convertible<_T1, _T1&&, 2, 0>               : public true_type {};\n#endif\ntemplate <class _T1>            struct __is_convertible<_T1, _T1&, 2, 0>               : public true_type {};\ntemplate <class _T1>            struct __is_convertible<_T1, _T1*, 2, 0>               : public true_type {};\ntemplate <class _T1>            struct __is_convertible<_T1, _T1*const, 2, 0>          : public true_type {};\ntemplate <class _T1>            struct __is_convertible<_T1, _T1*volatile, 2, 0>       : public true_type {};\ntemplate <class _T1>            struct __is_convertible<_T1, _T1*const volatile, 2, 0> : public true_type {};\n\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 0> : public false_type {};\n\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 1> : public false_type {};\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 1> : public false_type {};\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 1> : public false_type {};\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 1> : public false_type {};\n\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 2> : public false_type {};\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 2> : public false_type {};\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 2> : public false_type {};\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 2> : public false_type {};\n\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 3> : public false_type {};\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 3> : public false_type {};\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 3> : public false_type {};\ntemplate <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 3> : public true_type {};\n\ntemplate <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY is_convertible\n    : public __is_convertible<_T1, _T2>\n{\n    static const size_t __complete_check1 = __is_convertible_check<_T1>::__v;\n    static const size_t __complete_check2 = __is_convertible_check<_T2>::__v;\n};\n\n#endif  // __has_feature(is_convertible_to)\n\n// is_empty\n\n#if __has_feature(is_empty) || (_GNUC_VER >= 407)\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_empty\n    : public integral_constant<bool, __is_empty(_Tp)> {};\n\n#else  // __has_feature(is_empty)\n\ntemplate <class _Tp>\nstruct __is_empty1\n    : public _Tp\n{\n    double __lx;\n};\n\nstruct __is_empty2\n{\n    double __lx;\n};\n\ntemplate <class _Tp, bool = is_class<_Tp>::value>\nstruct __libcpp_empty : public integral_constant<bool, sizeof(__is_empty1<_Tp>) == sizeof(__is_empty2)> {};\n\ntemplate <class _Tp> struct __libcpp_empty<_Tp, false> : public false_type {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_empty : public __libcpp_empty<_Tp> {};\n\n#endif  // __has_feature(is_empty)\n\n// is_polymorphic\n\n#if __has_feature(is_polymorphic) || defined(_LIBCPP_MSVC)\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_polymorphic\n    : public integral_constant<bool, __is_polymorphic(_Tp)> {};\n\n#else\n\ntemplate<typename _Tp> char &__is_polymorphic_impl(\n    typename enable_if<sizeof((_Tp*)dynamic_cast<const volatile void*>(declval<_Tp*>())) != 0,\n                       int>::type);\ntemplate<typename _Tp> __two &__is_polymorphic_impl(...);\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_polymorphic\n    : public integral_constant<bool, sizeof(__is_polymorphic_impl<_Tp>(0)) == 1> {};\n\n#endif // __has_feature(is_polymorphic)\n\n// has_virtual_destructor\n\n#if __has_feature(has_virtual_destructor) || (_GNUC_VER >= 403)\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY has_virtual_destructor\n    : public integral_constant<bool, __has_virtual_destructor(_Tp)> {};\n\n#else\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY has_virtual_destructor\n    : public false_type {};\n\n#endif\n\n// alignment_of\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY alignment_of\n    : public integral_constant<size_t, __alignof__(_Tp)> {};\n\n// aligned_storage\n\ntemplate <class _Hp, class _Tp>\nstruct __type_list\n{\n    typedef _Hp _Head;\n    typedef _Tp _Tail;\n};\n\nstruct __nat\n{\n#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS\n    __nat() = delete;\n    __nat(const __nat&) = delete;\n    __nat& operator=(const __nat&) = delete;\n    ~__nat() = delete;\n#endif\n};\n\ntemplate <class _Tp>\nstruct __align_type\n{\n    static const size_t value = alignment_of<_Tp>::value;\n    typedef _Tp type;\n};\n\nstruct __struct_double {long double __lx;};\nstruct __struct_double4 {double __lx[4];};\n\ntypedef\n    __type_list<__align_type<unsigned char>,\n    __type_list<__align_type<unsigned short>,\n    __type_list<__align_type<unsigned int>,\n    __type_list<__align_type<unsigned long>,\n    __type_list<__align_type<unsigned long long>,\n    __type_list<__align_type<double>,\n    __type_list<__align_type<long double>,\n    __type_list<__align_type<__struct_double>,\n    __type_list<__align_type<__struct_double4>,\n    __type_list<__align_type<int*>,\n    __nat\n    > > > > > > > > > > __all_types;\n\ntemplate <class _TL, size_t _Align> struct __find_pod;\n\ntemplate <class _Hp, size_t _Align>\nstruct __find_pod<__type_list<_Hp, __nat>, _Align>\n{\n    typedef typename conditional<\n                             _Align == _Hp::value,\n                             typename _Hp::type,\n                             void\n                         >::type type;\n};\n\ntemplate <class _Hp, class _Tp, size_t _Align>\nstruct __find_pod<__type_list<_Hp, _Tp>, _Align>\n{\n    typedef typename conditional<\n                             _Align == _Hp::value,\n                             typename _Hp::type,\n                             typename __find_pod<_Tp, _Align>::type\n                         >::type type;\n};\n\ntemplate <class _TL, size_t _Len> struct __find_max_align;\n\ntemplate <class _Hp, size_t _Len>\nstruct __find_max_align<__type_list<_Hp, __nat>, _Len> : public integral_constant<size_t, _Hp::value> {};\n\ntemplate <size_t _Len, size_t _A1, size_t _A2>\nstruct __select_align\n{\nprivate:\n    static const size_t __min = _A2 < _A1 ? _A2 : _A1;\n    static const size_t __max = _A1 < _A2 ? _A2 : _A1;\npublic:\n    static const size_t value = _Len < __max ? __min : __max;\n};\n\ntemplate <class _Hp, class _Tp, size_t _Len>\nstruct __find_max_align<__type_list<_Hp, _Tp>, _Len>\n    : public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {};\n\ntemplate <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>\nstruct _LIBCPP_TYPE_VIS_ONLY aligned_storage\n{\n    typedef typename __find_pod<__all_types, _Align>::type _Aligner;\n    static_assert(!is_void<_Aligner>::value, \"\");\n    union type\n    {\n        _Aligner __align;\n        unsigned char __data[_Len];\n    };\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>\n    using aligned_storage_t = typename aligned_storage<_Len, _Align>::type;\n#endif\n\n#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \\\ntemplate <size_t _Len>\\\nstruct _LIBCPP_TYPE_VIS_ONLY aligned_storage<_Len, n>\\\n{\\\n    struct _ALIGNAS(n) type\\\n    {\\\n        unsigned char __lx[_Len];\\\n    };\\\n}\n\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1);\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2);\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4);\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x8);\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x10);\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x20);\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x40);\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x80);\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x100);\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x200);\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x400);\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x800);\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1000);\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2000);\n// MSDN says that MSVC does not support alignment beyond 8192 (=0x2000)\n#if !defined(_LIBCPP_MSVC)\n_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4000);\n#endif // !_LIBCPP_MSVC\n\n#undef _CREATE_ALIGNED_STORAGE_SPECIALIZATION\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n// aligned_union\n\ntemplate <size_t _I0, size_t ..._In>\nstruct __static_max;\n\ntemplate <size_t _I0>\nstruct __static_max<_I0>\n{\n    static const size_t value = _I0;\n};\n\ntemplate <size_t _I0, size_t _I1, size_t ..._In>\nstruct __static_max<_I0, _I1, _In...>\n{\n    static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value :\n                                             __static_max<_I1, _In...>::value;\n};\n\ntemplate <size_t _Len, class _Type0, class ..._Types>\nstruct aligned_union\n{\n    static const size_t alignment_value = __static_max<__alignof__(_Type0),\n                                                       __alignof__(_Types)...>::value;\n    static const size_t __len = __static_max<_Len, sizeof(_Type0),\n                                             sizeof(_Types)...>::value;\n    typedef typename aligned_storage<__len, alignment_value>::type type;\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <size_t _Len, class ..._Types> using aligned_union_t = typename aligned_union<_Len, _Types...>::type;\n#endif\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp>\nstruct __numeric_type\n{\n   static void __test(...);\n   static float __test(float);\n   static double __test(char);\n   static double __test(int);\n   static double __test(unsigned);\n   static double __test(long);\n   static double __test(unsigned long);\n   static double __test(long long);\n   static double __test(unsigned long long);\n   static double __test(double);\n   static long double __test(long double);\n\n   typedef decltype(__test(declval<_Tp>())) type;\n   static const bool value = !is_same<type, void>::value;\n};\n\ntemplate <>\nstruct __numeric_type<void>\n{\n   static const bool value = true;\n};\n\n// __promote\n\ntemplate <class _A1, class _A2 = void, class _A3 = void,\n          bool = __numeric_type<_A1>::value &&\n                 __numeric_type<_A2>::value &&\n                 __numeric_type<_A3>::value>\nclass __promote_imp\n{\npublic:\n    static const bool value = false;\n};\n\ntemplate <class _A1, class _A2, class _A3>\nclass __promote_imp<_A1, _A2, _A3, true>\n{\nprivate:\n    typedef typename __promote_imp<_A1>::type __type1;\n    typedef typename __promote_imp<_A2>::type __type2;\n    typedef typename __promote_imp<_A3>::type __type3;\npublic:\n    typedef decltype(__type1() + __type2() + __type3()) type;\n    static const bool value = true;\n};\n\ntemplate <class _A1, class _A2>\nclass __promote_imp<_A1, _A2, void, true>\n{\nprivate:\n    typedef typename __promote_imp<_A1>::type __type1;\n    typedef typename __promote_imp<_A2>::type __type2;\npublic:\n    typedef decltype(__type1() + __type2()) type;\n    static const bool value = true;\n};\n\ntemplate <class _A1>\nclass __promote_imp<_A1, void, void, true>\n{\npublic:\n    typedef typename __numeric_type<_A1>::type type;\n    static const bool value = true;\n};\n\ntemplate <class _A1, class _A2 = void, class _A3 = void>\nclass __promote : public __promote_imp<_A1, _A2, _A3> {};\n\n#ifdef _LIBCPP_STORE_AS_OPTIMIZATION\n\n// __transform\n\ntemplate <class _Tp, size_t = sizeof(_Tp), bool = is_scalar<_Tp>::value> struct __transform {typedef _Tp type;};\ntemplate <class _Tp> struct __transform<_Tp, 1, true> {typedef unsigned char      type;};\ntemplate <class _Tp> struct __transform<_Tp, 2, true> {typedef unsigned short     type;};\ntemplate <class _Tp> struct __transform<_Tp, 4, true> {typedef unsigned int       type;};\ntemplate <class _Tp> struct __transform<_Tp, 8, true> {typedef unsigned long long type;};\n\n#endif  // _LIBCPP_STORE_AS_OPTIMIZATION\n\n// make_signed / make_unsigned\n\ntypedef\n    __type_list<signed char,\n    __type_list<signed short,\n    __type_list<signed int,\n    __type_list<signed long,\n    __type_list<signed long long,\n#ifndef _LIBCPP_HAS_NO_INT128\n    __type_list<__int128_t,\n#endif\n    __nat\n#ifndef _LIBCPP_HAS_NO_INT128\n    >\n#endif\n    > > > > > __signed_types;\n\ntypedef\n    __type_list<unsigned char,\n    __type_list<unsigned short,\n    __type_list<unsigned int,\n    __type_list<unsigned long,\n    __type_list<unsigned long long,\n#ifndef _LIBCPP_HAS_NO_INT128\n    __type_list<__uint128_t,\n#endif\n    __nat\n#ifndef _LIBCPP_HAS_NO_INT128\n    >\n#endif\n    > > > > > __unsigned_types;\n\ntemplate <class _TypeList, size_t _Size, bool = _Size <= sizeof(typename _TypeList::_Head)> struct __find_first;\n\ntemplate <class _Hp, class _Tp, size_t _Size>\nstruct __find_first<__type_list<_Hp, _Tp>, _Size, true>\n{\n    typedef _Hp type;\n};\n\ntemplate <class _Hp, class _Tp, size_t _Size>\nstruct __find_first<__type_list<_Hp, _Tp>, _Size, false>\n{\n    typedef typename __find_first<_Tp, _Size>::type type;\n};\n\ntemplate <class _Tp, class _Up, bool = is_const<typename remove_reference<_Tp>::type>::value,\n                             bool = is_volatile<typename remove_reference<_Tp>::type>::value>\nstruct __apply_cv\n{\n    typedef _Up type;\n};\n\ntemplate <class _Tp, class _Up>\nstruct __apply_cv<_Tp, _Up, true, false>\n{\n    typedef const _Up type;\n};\n\ntemplate <class _Tp, class _Up>\nstruct __apply_cv<_Tp, _Up, false, true>\n{\n    typedef volatile _Up type;\n};\n\ntemplate <class _Tp, class _Up>\nstruct __apply_cv<_Tp, _Up, true, true>\n{\n    typedef const volatile _Up type;\n};\n\ntemplate <class _Tp, class _Up>\nstruct __apply_cv<_Tp&, _Up, false, false>\n{\n    typedef _Up& type;\n};\n\ntemplate <class _Tp, class _Up>\nstruct __apply_cv<_Tp&, _Up, true, false>\n{\n    typedef const _Up& type;\n};\n\ntemplate <class _Tp, class _Up>\nstruct __apply_cv<_Tp&, _Up, false, true>\n{\n    typedef volatile _Up& type;\n};\n\ntemplate <class _Tp, class _Up>\nstruct __apply_cv<_Tp&, _Up, true, true>\n{\n    typedef const volatile _Up& type;\n};\n\ntemplate <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>\nstruct __make_signed {};\n\ntemplate <class _Tp>\nstruct __make_signed<_Tp, true>\n{\n    typedef typename __find_first<__signed_types, sizeof(_Tp)>::type type;\n};\n\ntemplate <> struct __make_signed<bool,               true> {};\ntemplate <> struct __make_signed<  signed short,     true> {typedef short     type;};\ntemplate <> struct __make_signed<unsigned short,     true> {typedef short     type;};\ntemplate <> struct __make_signed<  signed int,       true> {typedef int       type;};\ntemplate <> struct __make_signed<unsigned int,       true> {typedef int       type;};\ntemplate <> struct __make_signed<  signed long,      true> {typedef long      type;};\ntemplate <> struct __make_signed<unsigned long,      true> {typedef long      type;};\ntemplate <> struct __make_signed<  signed long long, true> {typedef long long type;};\ntemplate <> struct __make_signed<unsigned long long, true> {typedef long long type;};\n#ifndef _LIBCPP_HAS_NO_INT128\ntemplate <> struct __make_signed<__int128_t,         true> {typedef __int128_t type;};\ntemplate <> struct __make_signed<__uint128_t,        true> {typedef __int128_t type;};\n#endif\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY make_signed\n{\n    typedef typename __apply_cv<_Tp, typename __make_signed<typename remove_cv<_Tp>::type>::type>::type type;\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using make_signed_t = typename make_signed<_Tp>::type;\n#endif\n\ntemplate <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>\nstruct __make_unsigned {};\n\ntemplate <class _Tp>\nstruct __make_unsigned<_Tp, true>\n{\n    typedef typename __find_first<__unsigned_types, sizeof(_Tp)>::type type;\n};\n\ntemplate <> struct __make_unsigned<bool,               true> {};\ntemplate <> struct __make_unsigned<  signed short,     true> {typedef unsigned short     type;};\ntemplate <> struct __make_unsigned<unsigned short,     true> {typedef unsigned short     type;};\ntemplate <> struct __make_unsigned<  signed int,       true> {typedef unsigned int       type;};\ntemplate <> struct __make_unsigned<unsigned int,       true> {typedef unsigned int       type;};\ntemplate <> struct __make_unsigned<  signed long,      true> {typedef unsigned long      type;};\ntemplate <> struct __make_unsigned<unsigned long,      true> {typedef unsigned long      type;};\ntemplate <> struct __make_unsigned<  signed long long, true> {typedef unsigned long long type;};\ntemplate <> struct __make_unsigned<unsigned long long, true> {typedef unsigned long long type;};\n#ifndef _LIBCPP_HAS_NO_INT128\ntemplate <> struct __make_unsigned<__int128_t,         true> {typedef __uint128_t        type;};\ntemplate <> struct __make_unsigned<__uint128_t,        true> {typedef __uint128_t        type;};\n#endif\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY make_unsigned\n{\n    typedef typename __apply_cv<_Tp, typename __make_unsigned<typename remove_cv<_Tp>::type>::type>::type type;\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using make_unsigned_t = typename make_unsigned<_Tp>::type;\n#endif\n\n#ifdef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Up = void, class _Vp = void>\nstruct _LIBCPP_TYPE_VIS_ONLY common_type\n{\npublic:\n    typedef typename common_type<typename common_type<_Tp, _Up>::type, _Vp>::type type;\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, void, void>\n{\npublic:\n    typedef typename decay<_Tp>::type type;\n};\n\ntemplate <class _Tp, class _Up>\nstruct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up, void>\n{\nprivate:\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    static _Tp&& __t();\n    static _Up&& __u();\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    static _Tp __t();\n    static _Up __u();\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\npublic:\n    typedef typename remove_reference<decltype(true ? __t() : __u())>::type type;\n};\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class ..._Tp> struct common_type;\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp>\n{\n    typedef typename decay<_Tp>::type type;\n};\n\ntemplate <class _Tp, class _Up>\nstruct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up>\n{\nprivate:\n    static _Tp&& __t();\n    static _Up&& __u();\n    static bool __f();\npublic:\n    typedef typename decay<decltype(__f() ? __t() : __u())>::type type;\n};\n\ntemplate <class _Tp, class _Up, class ..._Vp>\nstruct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up, _Vp...>\n{\n    typedef typename common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type;\n#endif\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n// is_assignable\n\ntemplate<typename, typename _Tp> struct __select_2nd { typedef _Tp type; };\n\ntemplate <class _Tp, class _Arg>\ntypename __select_2nd<decltype((_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>())), true_type>::type\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n__is_assignable_test(_Tp&&, _Arg&&);\n#else\n__is_assignable_test(_Tp, _Arg&);\n#endif\n\ntemplate <class _Arg>\nfalse_type\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n__is_assignable_test(__any, _Arg&&);\n#else\n__is_assignable_test(__any, _Arg&);\n#endif\n\ntemplate <class _Tp, class _Arg, bool = is_void<_Tp>::value || is_void<_Arg>::value>\nstruct __is_assignable_imp\n    : public common_type\n        <\n            decltype(_VSTD::__is_assignable_test(declval<_Tp>(), declval<_Arg>()))\n        >::type {};\n\ntemplate <class _Tp, class _Arg>\nstruct __is_assignable_imp<_Tp, _Arg, true>\n    : public false_type\n{\n};\n\ntemplate <class _Tp, class _Arg>\nstruct is_assignable\n    : public __is_assignable_imp<_Tp, _Arg> {};\n\n// is_copy_assignable\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_copy_assignable\n    : public is_assignable<typename add_lvalue_reference<_Tp>::type,\n                  typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};\n\n// is_move_assignable\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_move_assignable\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    : public is_assignable<typename add_lvalue_reference<_Tp>::type,\n                     const typename add_rvalue_reference<_Tp>::type> {};\n#else\n    : public is_copy_assignable<_Tp> {};\n#endif\n\n// is_destructible\n\n//  if it's a reference, return true\n//  if it's a function, return false\n//  if it's   void,     return false\n//  if it's an array of unknown bound, return false\n//  Otherwise, return \"std::declval<_Up&>().~_Up()\" is well-formed\n//    where _Up is remove_all_extents<_Tp>::type\n\ntemplate <class>\nstruct __is_destructible_apply { typedef int type; };\n\ntemplate <typename _Tp>\nstruct __is_destructor_wellformed {\n    template <typename _Tp1>\n    static char  __test (\n        typename __is_destructible_apply<decltype(_VSTD::declval<_Tp1&>().~_Tp1())>::type\n    );\n\n    template <typename _Tp1>\n    static __two __test (...);\n    \n    static const bool value = sizeof(__test<_Tp>(12)) == sizeof(char);\n};\n\ntemplate <class _Tp, bool>\nstruct __destructible_imp;\n\ntemplate <class _Tp>\nstruct __destructible_imp<_Tp, false> \n   : public _VSTD::integral_constant<bool, \n        __is_destructor_wellformed<typename _VSTD::remove_all_extents<_Tp>::type>::value> {};\n\ntemplate <class _Tp>\nstruct __destructible_imp<_Tp, true>\n    : public _VSTD::true_type {};\n\ntemplate <class _Tp, bool>\nstruct __destructible_false;\n\ntemplate <class _Tp>\nstruct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, _VSTD::is_reference<_Tp>::value> {};\n\ntemplate <class _Tp>\nstruct __destructible_false<_Tp, true> : public _VSTD::false_type {};\n\ntemplate <class _Tp>\nstruct is_destructible\n    : public __destructible_false<_Tp, _VSTD::is_function<_Tp>::value> {};\n\ntemplate <class _Tp>\nstruct is_destructible<_Tp[]>\n    : public _VSTD::false_type {};\n\ntemplate <>\nstruct is_destructible<void>\n    : public _VSTD::false_type {};\n\n// move\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntypename remove_reference<_Tp>::type&&\nmove(_Tp&& __t) _NOEXCEPT\n{\n    typedef typename remove_reference<_Tp>::type _Up;\n    return static_cast<_Up&&>(__t);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_Tp&&\nforward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT\n{\n    return static_cast<_Tp&&>(__t);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n_Tp&&\nforward(typename std::remove_reference<_Tp>::type&& __t) _NOEXCEPT\n{\n    static_assert(!std::is_lvalue_reference<_Tp>::value,\n                  \"Can not forward an rvalue as an lvalue.\");\n    return static_cast<_Tp&&>(__t);\n}\n\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp&\nmove(_Tp& __t)\n{\n    return __t;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconst _Tp&\nmove(const _Tp& __t)\n{\n    return __t;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp&\nforward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT\n{\n    return __t;\n}\n\n\ntemplate <class _Tp>\nclass __rv\n{\n    typedef typename remove_reference<_Tp>::type _Trr;\n    _Trr& t_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    _Trr* operator->() {return &t_;}\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __rv(_Trr& __t) : t_(__t) {}\n};\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename decay<_Tp>::type\n__decay_copy(_Tp&& __t)\n{\n    return _VSTD::forward<_Tp>(__t);\n}\n\n#else\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename decay<_Tp>::type\n__decay_copy(const _Tp& __t)\n{\n    return _VSTD::forward<_Tp>(__t);\n}\n\n#endif\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false>\n{\n    typedef _Class _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false>\n{\n    typedef _Class _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param..., ...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false>\n{\n    typedef _Class const _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false>\n{\n    typedef _Class const _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param..., ...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false>\n{\n    typedef _Class volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false>\n{\n    typedef _Class volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param..., ...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false>\n{\n    typedef _Class const volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false>\n{\n    typedef _Class const volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param..., ...);\n};\n\n#if __has_feature(cxx_reference_qualified_functions) || \\\n    (defined(_GNUC_VER) && _GNUC_VER >= 409)\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false>\n{\n    typedef _Class& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &, true, false>\n{\n    typedef _Class& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param..., ...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false>\n{\n    typedef _Class const& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false>\n{\n    typedef _Class const& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param..., ...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false>\n{\n    typedef _Class volatile& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false>\n{\n    typedef _Class volatile& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param..., ...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false>\n{\n    typedef _Class const volatile& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false>\n{\n    typedef _Class const volatile& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param..., ...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &&, true, false>\n{\n    typedef _Class&& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &&, true, false>\n{\n    typedef _Class&& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param..., ...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false>\n{\n    typedef _Class const&& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false>\n{\n    typedef _Class const&& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param..., ...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false>\n{\n    typedef _Class volatile&& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false>\n{\n    typedef _Class volatile&& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param..., ...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false>\n{\n    typedef _Class const volatile&& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param...);\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false>\n{\n    typedef _Class const volatile&& _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_Param..., ...);\n};\n\n#endif  // __has_feature(cxx_reference_qualified_functions) || _GNUC_VER >= 409\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Rp, class _Class>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(), true, false>\n{\n    typedef _Class _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) ();\n};\n\ntemplate <class _Rp, class _Class>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(...), true, false>\n{\n    typedef _Class _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (...);\n};\n\ntemplate <class _Rp, class _Class, class _P0>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0), true, false>\n{\n    typedef _Class _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0);\n};\n\ntemplate <class _Rp, class _Class, class _P0>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, ...), true, false>\n{\n    typedef _Class _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, ...);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1), true, false>\n{\n    typedef _Class _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, ...), true, false>\n{\n    typedef _Class _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1, ...);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1, class _P2>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2), true, false>\n{\n    typedef _Class _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1, _P2);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1, class _P2>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2, ...), true, false>\n{\n    typedef _Class _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1, _P2, ...);\n};\n\ntemplate <class _Rp, class _Class>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)() const, true, false>\n{\n    typedef _Class const _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) ();\n};\n\ntemplate <class _Rp, class _Class>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(...) const, true, false>\n{\n    typedef _Class const _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (...);\n};\n\ntemplate <class _Rp, class _Class, class _P0>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0) const, true, false>\n{\n    typedef _Class const _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0);\n};\n\ntemplate <class _Rp, class _Class, class _P0>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, ...) const, true, false>\n{\n    typedef _Class const _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, ...);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1) const, true, false>\n{\n    typedef _Class const _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, ...) const, true, false>\n{\n    typedef _Class const _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1, ...);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1, class _P2>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2) const, true, false>\n{\n    typedef _Class const _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1, _P2);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1, class _P2>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2, ...) const, true, false>\n{\n    typedef _Class const _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1, _P2, ...);\n};\n\ntemplate <class _Rp, class _Class>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)() volatile, true, false>\n{\n    typedef _Class volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) ();\n};\n\ntemplate <class _Rp, class _Class>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(...) volatile, true, false>\n{\n    typedef _Class volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (...);\n};\n\ntemplate <class _Rp, class _Class, class _P0>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0) volatile, true, false>\n{\n    typedef _Class volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0);\n};\n\ntemplate <class _Rp, class _Class, class _P0>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, ...) volatile, true, false>\n{\n    typedef _Class volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, ...);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1) volatile, true, false>\n{\n    typedef _Class volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, ...) volatile, true, false>\n{\n    typedef _Class volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1, ...);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1, class _P2>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2) volatile, true, false>\n{\n    typedef _Class volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1, _P2);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1, class _P2>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2, ...) volatile, true, false>\n{\n    typedef _Class volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1, _P2, ...);\n};\n\ntemplate <class _Rp, class _Class>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)() const volatile, true, false>\n{\n    typedef _Class const volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) ();\n};\n\ntemplate <class _Rp, class _Class>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(...) const volatile, true, false>\n{\n    typedef _Class const volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (...);\n};\n\ntemplate <class _Rp, class _Class, class _P0>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0) const volatile, true, false>\n{\n    typedef _Class const volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0);\n};\n\ntemplate <class _Rp, class _Class, class _P0>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, ...) const volatile, true, false>\n{\n    typedef _Class const volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, ...);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1) const volatile, true, false>\n{\n    typedef _Class const volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, ...) const volatile, true, false>\n{\n    typedef _Class const volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1, ...);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1, class _P2>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2) const volatile, true, false>\n{\n    typedef _Class const volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1, _P2);\n};\n\ntemplate <class _Rp, class _Class, class _P0, class _P1, class _P2>\nstruct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2, ...) const volatile, true, false>\n{\n    typedef _Class const volatile _ClassType;\n    typedef _Rp _ReturnType;\n    typedef _Rp (_FnType) (_P0, _P1, _P2, ...);\n};\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Rp, class _Class>\nstruct __member_pointer_traits_imp<_Rp _Class::*, false, true>\n{\n    typedef _Class _ClassType;\n    typedef _Rp _ReturnType;\n};\n\ntemplate <class _MP>\nstruct __member_pointer_traits\n    : public __member_pointer_traits_imp<typename remove_cv<_MP>::type,\n                    is_member_function_pointer<_MP>::value,\n                    is_member_object_pointer<_MP>::value>\n{\n//     typedef ... _ClassType;\n//     typedef ... _ReturnType;\n//     typedef ... _FnType;\n};\n\n// result_of\n\ntemplate <class _Callable> class result_of;\n\n#ifdef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Fn, bool, bool>\nclass __result_of\n{\n};\n\ntemplate <class _Fn>\nclass __result_of<_Fn(), true, false>\n{\npublic:\n    typedef decltype(declval<_Fn>()()) type;\n};\n\ntemplate <class _Fn, class _A0>\nclass __result_of<_Fn(_A0), true, false>\n{\npublic:\n    typedef decltype(declval<_Fn>()(declval<_A0>())) type;\n};\n\ntemplate <class _Fn, class _A0, class _A1>\nclass __result_of<_Fn(_A0, _A1), true, false>\n{\npublic:\n    typedef decltype(declval<_Fn>()(declval<_A0>(), declval<_A1>())) type;\n};\n\ntemplate <class _Fn, class _A0, class _A1, class _A2>\nclass __result_of<_Fn(_A0, _A1, _A2), true, false>\n{\npublic:\n    typedef decltype(declval<_Fn>()(declval<_A0>(), declval<_A1>(), declval<_A2>())) type;\n};\n\ntemplate <class _MP, class _Tp, bool _IsMemberFunctionPtr>\nstruct __result_of_mp;\n\n// member function pointer\n\ntemplate <class _MP, class _Tp>\nstruct __result_of_mp<_MP, _Tp, true>\n    : public __identity<typename __member_pointer_traits<_MP>::_ReturnType>\n{\n};\n\n// member data pointer\n\ntemplate <class _MP, class _Tp, bool>\nstruct __result_of_mdp;\n\ntemplate <class _Rp, class _Class, class _Tp>\nstruct __result_of_mdp<_Rp _Class::*, _Tp, false>\n{\n    typedef typename __apply_cv<decltype(*_VSTD::declval<_Tp>()), _Rp>::type& type;\n};\n\ntemplate <class _Rp, class _Class, class _Tp>\nstruct __result_of_mdp<_Rp _Class::*, _Tp, true>\n{\n    typedef typename __apply_cv<_Tp, _Rp>::type& type;\n};\n\ntemplate <class _Rp, class _Class, class _Tp>\nstruct __result_of_mp<_Rp _Class::*, _Tp, false>\n    : public __result_of_mdp<_Rp _Class::*, _Tp,\n            is_base_of<_Class, typename remove_reference<_Tp>::type>::value>\n{\n};\n\n\n\ntemplate <class _Fn, class _Tp>\nclass __result_of<_Fn(_Tp), false, true>  // _Fn must be member pointer\n    : public __result_of_mp<typename remove_reference<_Fn>::type,\n                            _Tp,\n                            is_member_function_pointer<typename remove_reference<_Fn>::type>::value>\n{\n};\n\ntemplate <class _Fn, class _Tp, class _A0>\nclass __result_of<_Fn(_Tp, _A0), false, true>  // _Fn must be member pointer\n    : public __result_of_mp<typename remove_reference<_Fn>::type,\n                            _Tp,\n                            is_member_function_pointer<typename remove_reference<_Fn>::type>::value>\n{\n};\n\ntemplate <class _Fn, class _Tp, class _A0, class _A1>\nclass __result_of<_Fn(_Tp, _A0, _A1), false, true>  // _Fn must be member pointer\n    : public __result_of_mp<typename remove_reference<_Fn>::type,\n                            _Tp,\n                            is_member_function_pointer<typename remove_reference<_Fn>::type>::value>\n{\n};\n\ntemplate <class _Fn, class _Tp, class _A0, class _A1, class _A2>\nclass __result_of<_Fn(_Tp, _A0, _A1, _A2), false, true>  // _Fn must be member pointer\n    : public __result_of_mp<typename remove_reference<_Fn>::type,\n                            _Tp,\n                            is_member_function_pointer<typename remove_reference<_Fn>::type>::value>\n{\n};\n\n// result_of\n\ntemplate <class _Fn>\nclass _LIBCPP_TYPE_VIS_ONLY result_of<_Fn()>\n    : public __result_of<_Fn(),\n                         is_class<typename remove_reference<_Fn>::type>::value ||\n                         is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value,\n                         is_member_pointer<typename remove_reference<_Fn>::type>::value\n                        >\n{\n};\n\ntemplate <class _Fn, class _A0>\nclass _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0)>\n    : public __result_of<_Fn(_A0),\n                         is_class<typename remove_reference<_Fn>::type>::value ||\n                         is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value,\n                         is_member_pointer<typename remove_reference<_Fn>::type>::value\n                        >\n{\n};\n\ntemplate <class _Fn, class _A0, class _A1>\nclass _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0, _A1)>\n    : public __result_of<_Fn(_A0, _A1),\n                         is_class<typename remove_reference<_Fn>::type>::value ||\n                         is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value,\n                         is_member_pointer<typename remove_reference<_Fn>::type>::value\n                        >\n{\n};\n\ntemplate <class _Fn, class _A0, class _A1, class _A2>\nclass _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0, _A1, _A2)>\n    : public __result_of<_Fn(_A0, _A1, _A2),\n                         is_class<typename remove_reference<_Fn>::type>::value ||\n                         is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value,\n                         is_member_pointer<typename remove_reference<_Fn>::type>::value\n                        >\n{\n};\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n// template <class T, class... Args> struct is_constructible;\n\nnamespace __is_construct\n{\nstruct __nat {};\n}\n\n#if __has_feature(is_constructible)\n\ntemplate <class _Tp, class ..._Args>\nstruct _LIBCPP_TYPE_VIS_ONLY is_constructible\n    : public integral_constant<bool, __is_constructible(_Tp, _Args...)>\n    {};\n\n#else\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n//      main is_constructible test\n\ntemplate <class _Tp, class ..._Args>\ntypename __select_2nd<decltype(_VSTD::move(_Tp(_VSTD::declval<_Args>()...))), true_type>::type\n__is_constructible_test(_Tp&&, _Args&& ...);\n\ntemplate <class ..._Args>\nfalse_type\n__is_constructible_test(__any, _Args&& ...);\n\ntemplate <bool, class _Tp, class... _Args>\nstruct __libcpp_is_constructible // false, _Tp is not a scalar\n    : public common_type\n             <\n                 decltype(__is_constructible_test(declval<_Tp>(), declval<_Args>()...))\n             >::type\n    {};\n\n//      function types are not constructible\n\ntemplate <class _Rp, class... _A1, class... _A2>\nstruct __libcpp_is_constructible<false, _Rp(_A1...), _A2...>\n    : public false_type\n    {};\n\n//      handle scalars and reference types\n\n//      Scalars are default constructible, references are not\n\ntemplate <class _Tp>\nstruct __libcpp_is_constructible<true, _Tp>\n    : public is_scalar<_Tp>\n    {};\n\n//      Scalars and references are constructible from one arg if that arg is\n//          implicitly convertible to the scalar or reference.\n\ntemplate <class _Tp>\nstruct __is_constructible_ref\n{\n    true_type static __lxx(_Tp);\n    false_type static __lxx(...);\n};\n\ntemplate <class _Tp, class _A0>\nstruct __libcpp_is_constructible<true, _Tp, _A0>\n    : public common_type\n             <\n                 decltype(__is_constructible_ref<_Tp>::__lxx(declval<_A0>()))\n             >::type\n    {};\n\n//      Scalars and references are not constructible from multiple args.\n\ntemplate <class _Tp, class _A0, class ..._Args>\nstruct __libcpp_is_constructible<true, _Tp, _A0, _Args...>\n    : public false_type\n    {};\n\n//      Treat scalars and reference types separately\n\ntemplate <bool, class _Tp, class... _Args>\nstruct __is_constructible_void_check\n    : public __libcpp_is_constructible<is_scalar<_Tp>::value || is_reference<_Tp>::value,\n                                _Tp, _Args...>\n    {};\n\n//      If any of T or Args is void, is_constructible should be false\n\ntemplate <class _Tp, class... _Args>\nstruct __is_constructible_void_check<true, _Tp, _Args...>\n    : public false_type\n    {};\n\ntemplate <class ..._Args> struct __contains_void;\n\ntemplate <> struct __contains_void<> : false_type {};\n\ntemplate <class _A0, class ..._Args>\nstruct __contains_void<_A0, _Args...>\n{\n    static const bool value = is_void<_A0>::value ||\n                              __contains_void<_Args...>::value;\n};\n\n//      is_constructible entry point\n\ntemplate <class _Tp, class... _Args>\nstruct _LIBCPP_TYPE_VIS_ONLY is_constructible\n    : public __is_constructible_void_check<__contains_void<_Tp, _Args...>::value\n                                        || is_abstract<_Tp>::value,\n                                           _Tp, _Args...>\n    {};\n\n//      Array types are default constructible if their element type\n//      is default constructible\n\ntemplate <class _Ap, size_t _Np>\nstruct __libcpp_is_constructible<false, _Ap[_Np]>\n    : public is_constructible<typename remove_all_extents<_Ap>::type>\n    {};\n\n//      Otherwise array types are not constructible by this syntax\n\ntemplate <class _Ap, size_t _Np, class ..._Args>\nstruct __libcpp_is_constructible<false, _Ap[_Np], _Args...>\n    : public false_type\n    {};\n\n//      Incomplete array types are not constructible\n\ntemplate <class _Ap, class ..._Args>\nstruct __libcpp_is_constructible<false, _Ap[], _Args...>\n    : public false_type\n    {};\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\n// template <class T> struct is_constructible0;\n\n//      main is_constructible0 test\n\ntemplate <class _Tp>\ndecltype((_Tp(), true_type()))\n__is_constructible0_test(_Tp&);\n\nfalse_type\n__is_constructible0_test(__any);\n\ntemplate <class _Tp, class _A0>\ndecltype((_Tp(_VSTD::declval<_A0>()), true_type()))\n__is_constructible1_test(_Tp&, _A0&);\n\ntemplate <class _A0>\nfalse_type\n__is_constructible1_test(__any, _A0&);\n\ntemplate <class _Tp, class _A0, class _A1>\ndecltype((_Tp(_VSTD::declval<_A0>(), _VSTD::declval<_A1>()), true_type()))\n__is_constructible2_test(_Tp&, _A0&, _A1&);\n\ntemplate <class _A0, class _A1>\nfalse_type\n__is_constructible2_test(__any, _A0&, _A1&);\n\ntemplate <bool, class _Tp>\nstruct __is_constructible0_imp // false, _Tp is not a scalar\n    : public common_type\n             <\n                 decltype(__is_constructible0_test(declval<_Tp&>()))\n             >::type\n    {};\n\ntemplate <bool, class _Tp, class _A0>\nstruct __is_constructible1_imp // false, _Tp is not a scalar\n    : public common_type\n             <\n                 decltype(__is_constructible1_test(declval<_Tp&>(), declval<_A0&>()))\n             >::type\n    {};\n\ntemplate <bool, class _Tp, class _A0, class _A1>\nstruct __is_constructible2_imp // false, _Tp is not a scalar\n    : public common_type\n             <\n                 decltype(__is_constructible2_test(declval<_Tp&>(), declval<_A0>(), declval<_A1>()))\n             >::type\n    {};\n\n//      handle scalars and reference types\n\n//      Scalars are default constructible, references are not\n\ntemplate <class _Tp>\nstruct __is_constructible0_imp<true, _Tp>\n    : public is_scalar<_Tp>\n    {};\n\ntemplate <class _Tp, class _A0>\nstruct __is_constructible1_imp<true, _Tp, _A0>\n    : public is_convertible<_A0, _Tp>\n    {};\n\ntemplate <class _Tp, class _A0, class _A1>\nstruct __is_constructible2_imp<true, _Tp, _A0, _A1>\n    : public false_type\n    {};\n\n//      Treat scalars and reference types separately\n\ntemplate <bool, class _Tp>\nstruct __is_constructible0_void_check\n    : public __is_constructible0_imp<is_scalar<_Tp>::value || is_reference<_Tp>::value,\n                                _Tp>\n    {};\n\ntemplate <bool, class _Tp, class _A0>\nstruct __is_constructible1_void_check\n    : public __is_constructible1_imp<is_scalar<_Tp>::value || is_reference<_Tp>::value,\n                                _Tp, _A0>\n    {};\n\ntemplate <bool, class _Tp, class _A0, class _A1>\nstruct __is_constructible2_void_check\n    : public __is_constructible2_imp<is_scalar<_Tp>::value || is_reference<_Tp>::value,\n                                _Tp, _A0, _A1>\n    {};\n\n//      If any of T or Args is void, is_constructible should be false\n\ntemplate <class _Tp>\nstruct __is_constructible0_void_check<true, _Tp>\n    : public false_type\n    {};\n\ntemplate <class _Tp, class _A0>\nstruct __is_constructible1_void_check<true, _Tp, _A0>\n    : public false_type\n    {};\n\ntemplate <class _Tp, class _A0, class _A1>\nstruct __is_constructible2_void_check<true, _Tp, _A0, _A1>\n    : public false_type\n    {};\n\n//      is_constructible entry point\n\ntemplate <class _Tp, class _A0 = __is_construct::__nat,\n                     class _A1 = __is_construct::__nat>\nstruct _LIBCPP_TYPE_VIS_ONLY is_constructible\n    : public __is_constructible2_void_check<is_void<_Tp>::value\n                                        || is_abstract<_Tp>::value\n                                        || is_function<_Tp>::value\n                                        || is_void<_A0>::value\n                                        || is_void<_A1>::value,\n                                           _Tp, _A0, _A1>\n    {};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_constructible<_Tp, __is_construct::__nat, __is_construct::__nat>\n    : public __is_constructible0_void_check<is_void<_Tp>::value\n                                        || is_abstract<_Tp>::value\n                                        || is_function<_Tp>::value,\n                                           _Tp>\n    {};\n\ntemplate <class _Tp, class _A0>\nstruct _LIBCPP_TYPE_VIS_ONLY is_constructible<_Tp, _A0, __is_construct::__nat>\n    : public __is_constructible1_void_check<is_void<_Tp>::value\n                                        || is_abstract<_Tp>::value\n                                        || is_function<_Tp>::value\n                                        || is_void<_A0>::value,\n                                           _Tp, _A0>\n    {};\n\n//      Array types are default constructible if their element type\n//      is default constructible\n\ntemplate <class _Ap, size_t _Np>\nstruct __is_constructible0_imp<false, _Ap[_Np]>\n    : public is_constructible<typename remove_all_extents<_Ap>::type>\n    {};\n\ntemplate <class _Ap, size_t _Np, class _A0>\nstruct __is_constructible1_imp<false, _Ap[_Np], _A0>\n    : public false_type\n    {};\n\ntemplate <class _Ap, size_t _Np, class _A0, class _A1>\nstruct __is_constructible2_imp<false, _Ap[_Np], _A0, _A1>\n    : public false_type\n    {};\n\n//      Incomplete array types are not constructible\n\ntemplate <class _Ap>\nstruct __is_constructible0_imp<false, _Ap[]>\n    : public false_type\n    {};\n\ntemplate <class _Ap, class _A0>\nstruct __is_constructible1_imp<false, _Ap[], _A0>\n    : public false_type\n    {};\n\ntemplate <class _Ap, class _A0, class _A1>\nstruct __is_constructible2_imp<false, _Ap[], _A0, _A1>\n    : public false_type\n    {};\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // __has_feature(is_constructible)\n\n// is_default_constructible\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_default_constructible\n    : public is_constructible<_Tp>\n    {};\n\n// is_copy_constructible\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_copy_constructible\n    : public is_constructible<_Tp, \n                  typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};\n\n// is_move_constructible\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_move_constructible\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    : public is_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>\n#else\n    : public is_copy_constructible<_Tp>\n#endif\n    {};\n\n// is_trivially_constructible\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n#if __has_feature(is_trivially_constructible) || _GNUC_VER >= 501\n\ntemplate <class _Tp, class... _Args>\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible\n    : integral_constant<bool, __is_trivially_constructible(_Tp, _Args...)>\n{\n};\n\n#else  // !__has_feature(is_trivially_constructible)\n\ntemplate <class _Tp, class... _Args>\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible\n    : false_type\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp>\n#if __has_feature(has_trivial_constructor) || (_GNUC_VER >= 403)\n    : integral_constant<bool, __has_trivial_constructor(_Tp)>\n#else\n    : integral_constant<bool, is_scalar<_Tp>::value>\n#endif\n{\n};\n\ntemplate <class _Tp>\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&&>\n#else\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp>\n#endif\n    : integral_constant<bool, is_scalar<_Tp>::value>\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, const _Tp&>\n    : integral_constant<bool, is_scalar<_Tp>::value>\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&>\n    : integral_constant<bool, is_scalar<_Tp>::value>\n{\n};\n\n#endif  // !__has_feature(is_trivially_constructible)\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _A0 = __is_construct::__nat,\n                     class _A1 = __is_construct::__nat>\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible\n    : false_type\n{\n};\n\n#if __has_feature(is_trivially_constructible) || _GNUC_VER >= 501\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, __is_construct::__nat,\n                                                       __is_construct::__nat>\n    : integral_constant<bool, __is_trivially_constructible(_Tp)>\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp,\n                                                       __is_construct::__nat>\n    : integral_constant<bool, __is_trivially_constructible(_Tp, _Tp)>\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, const _Tp&,\n                                                       __is_construct::__nat>\n    : integral_constant<bool, __is_trivially_constructible(_Tp, const _Tp&)>\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&,\n                                                       __is_construct::__nat>\n    : integral_constant<bool, __is_trivially_constructible(_Tp, _Tp&)>\n{\n};\n\n#else  // !__has_feature(is_trivially_constructible)\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, __is_construct::__nat,\n                                                       __is_construct::__nat>\n    : integral_constant<bool, is_scalar<_Tp>::value>\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp,\n                                                       __is_construct::__nat>\n    : integral_constant<bool, is_scalar<_Tp>::value>\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, const _Tp&,\n                                                       __is_construct::__nat>\n    : integral_constant<bool, is_scalar<_Tp>::value>\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&,\n                                                       __is_construct::__nat>\n    : integral_constant<bool, is_scalar<_Tp>::value>\n{\n};\n\n#endif  // !__has_feature(is_trivially_constructible)\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n// is_trivially_default_constructible\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_default_constructible\n    : public is_trivially_constructible<_Tp>\n    {};\n\n// is_trivially_copy_constructible\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copy_constructible\n    : public is_trivially_constructible<_Tp, typename add_lvalue_reference<const _Tp>::type>\n    {};\n\n// is_trivially_move_constructible\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_move_constructible\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    : public is_trivially_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>\n#else\n    : public is_trivially_copy_constructible<_Tp>\n#endif\n    {};\n\n// is_trivially_assignable\n\n#if __has_feature(is_trivially_assignable) || _GNUC_VER >= 501\n\ntemplate <class _Tp, class _Arg>\nstruct is_trivially_assignable\n    : integral_constant<bool, __is_trivially_assignable(_Tp, _Arg)>\n{\n};\n\n#else  // !__has_feature(is_trivially_assignable)\n\ntemplate <class _Tp, class _Arg>\nstruct is_trivially_assignable\n    : public false_type {};\n\ntemplate <class _Tp>\nstruct is_trivially_assignable<_Tp&, _Tp>\n    : integral_constant<bool, is_scalar<_Tp>::value> {};\n\ntemplate <class _Tp>\nstruct is_trivially_assignable<_Tp&, _Tp&>\n    : integral_constant<bool, is_scalar<_Tp>::value> {};\n\ntemplate <class _Tp>\nstruct is_trivially_assignable<_Tp&, const _Tp&>\n    : integral_constant<bool, is_scalar<_Tp>::value> {};\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\nstruct is_trivially_assignable<_Tp&, _Tp&&>\n    : integral_constant<bool, is_scalar<_Tp>::value> {};\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#endif  // !__has_feature(is_trivially_assignable)\n\n// is_trivially_copy_assignable\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copy_assignable\n    : public is_trivially_assignable<typename add_lvalue_reference<_Tp>::type,\n                  typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};\n\n// is_trivially_move_assignable\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_move_assignable\n    : public is_trivially_assignable<typename add_lvalue_reference<_Tp>::type,\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n                                     typename add_rvalue_reference<_Tp>::type>\n#else\n                                     typename add_lvalue_reference<_Tp>::type>\n#endif\n    {};\n\n// is_trivially_destructible\n\n#if __has_feature(has_trivial_destructor) || (_GNUC_VER >= 403)\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_destructible\n    : public integral_constant<bool, is_destructible<_Tp>::value && __has_trivial_destructor(_Tp)> {};\n\n#else\n\ntemplate <class _Tp> struct __libcpp_trivial_destructor\n    : public integral_constant<bool, is_scalar<_Tp>::value ||\n                                     is_reference<_Tp>::value> {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_destructible\n    : public __libcpp_trivial_destructor<typename remove_all_extents<_Tp>::type> {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_destructible<_Tp[]>\n    : public false_type {};\n\n#endif\n\n// is_nothrow_constructible\n\n#if 0\ntemplate <class _Tp, class... _Args>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible\n    : public integral_constant<bool, __is_nothrow_constructible(_Tp(_Args...))>\n{\n};\n\n#else\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)\n\ntemplate <bool, bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_constructible;\n\ntemplate <class _Tp, class... _Args>\nstruct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/false, _Tp, _Args...>\n    : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))>\n{\n};\n\ntemplate <class _Tp>\nvoid __implicit_conversion_to(_Tp) noexcept { }\n\ntemplate <class _Tp, class _Arg>\nstruct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/true, _Tp, _Arg>\n    : public integral_constant<bool, noexcept(__implicit_conversion_to<_Tp>(declval<_Arg>()))>\n{\n};\n\ntemplate <class _Tp, bool _IsReference, class... _Args>\nstruct __libcpp_is_nothrow_constructible</*is constructible*/false, _IsReference, _Tp, _Args...>\n    : public false_type\n{\n};\n\ntemplate <class _Tp, class... _Args>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible\n    : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, is_reference<_Tp>::value, _Tp, _Args...>\n{\n};\n\ntemplate <class _Tp, size_t _Ns>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp[_Ns]>\n    : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, is_reference<_Tp>::value, _Tp>\n{\n};\n\n#else  // __has_feature(cxx_noexcept)\n\ntemplate <class _Tp, class... _Args>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible\n    : false_type\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp>\n#if __has_feature(has_nothrow_constructor) || (_GNUC_VER >= 403)\n    : integral_constant<bool, __has_nothrow_constructor(_Tp)>\n#else\n    : integral_constant<bool, is_scalar<_Tp>::value>\n#endif\n{\n};\n\ntemplate <class _Tp>\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp&&>\n#else\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp>\n#endif\n#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403)\n    : integral_constant<bool, __has_nothrow_copy(_Tp)>\n#else\n    : integral_constant<bool, is_scalar<_Tp>::value>\n#endif\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, const _Tp&>\n#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403)\n    : integral_constant<bool, __has_nothrow_copy(_Tp)>\n#else\n    : integral_constant<bool, is_scalar<_Tp>::value>\n#endif\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp&>\n#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403)\n    : integral_constant<bool, __has_nothrow_copy(_Tp)>\n#else\n    : integral_constant<bool, is_scalar<_Tp>::value>\n#endif\n{\n};\n\n#endif  // __has_feature(cxx_noexcept)\n\n#else  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _A0 = __is_construct::__nat,\n                     class _A1 = __is_construct::__nat>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible\n    : false_type\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, __is_construct::__nat,\n                                                       __is_construct::__nat>\n#if __has_feature(has_nothrow_constructor) || (_GNUC_VER >= 403)\n    : integral_constant<bool, __has_nothrow_constructor(_Tp)>\n#else\n    : integral_constant<bool, is_scalar<_Tp>::value>\n#endif\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp,\n                                                       __is_construct::__nat>\n#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403)\n    : integral_constant<bool, __has_nothrow_copy(_Tp)>\n#else\n    : integral_constant<bool, is_scalar<_Tp>::value>\n#endif\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, const _Tp&,\n                                                       __is_construct::__nat>\n#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403)\n    : integral_constant<bool, __has_nothrow_copy(_Tp)>\n#else\n    : integral_constant<bool, is_scalar<_Tp>::value>\n#endif\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp&,\n                                                       __is_construct::__nat>\n#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403)\n    : integral_constant<bool, __has_nothrow_copy(_Tp)>\n#else\n    : integral_constant<bool, is_scalar<_Tp>::value>\n#endif\n{\n};\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // __has_feature(is_nothrow_constructible)\n\n// is_nothrow_default_constructible\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_default_constructible\n    : public is_nothrow_constructible<_Tp>\n    {};\n\n// is_nothrow_copy_constructible\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_copy_constructible\n    : public is_nothrow_constructible<_Tp,\n                  typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};\n\n// is_nothrow_move_constructible\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_move_constructible\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    : public is_nothrow_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>\n#else\n    : public is_nothrow_copy_constructible<_Tp>\n#endif\n    {};\n\n// is_nothrow_assignable\n\n#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)\n\ntemplate <bool, class _Tp, class _Arg> struct __libcpp_is_nothrow_assignable;\n\ntemplate <class _Tp, class _Arg>\nstruct __libcpp_is_nothrow_assignable<false, _Tp, _Arg>\n    : public false_type\n{\n};\n\ntemplate <class _Tp, class _Arg>\nstruct __libcpp_is_nothrow_assignable<true, _Tp, _Arg>\n    : public integral_constant<bool, noexcept(_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>()) >\n{\n};\n\ntemplate <class _Tp, class _Arg>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable\n    : public __libcpp_is_nothrow_assignable<is_assignable<_Tp, _Arg>::value, _Tp, _Arg>\n{\n};\n\n#else  // __has_feature(cxx_noexcept)\n\ntemplate <class _Tp, class _Arg>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable\n    : public false_type {};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable<_Tp&, _Tp>\n#if __has_feature(has_nothrow_assign) || (_GNUC_VER >= 403)\n    : integral_constant<bool, __has_nothrow_assign(_Tp)> {};\n#else\n    : integral_constant<bool, is_scalar<_Tp>::value> {};\n#endif\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable<_Tp&, _Tp&>\n#if __has_feature(has_nothrow_assign) || (_GNUC_VER >= 403)\n    : integral_constant<bool, __has_nothrow_assign(_Tp)> {};\n#else\n    : integral_constant<bool, is_scalar<_Tp>::value> {};\n#endif\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable<_Tp&, const _Tp&>\n#if __has_feature(has_nothrow_assign) || (_GNUC_VER >= 403)\n    : integral_constant<bool, __has_nothrow_assign(_Tp)> {};\n#else\n    : integral_constant<bool, is_scalar<_Tp>::value> {};\n#endif\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\nstruct is_nothrow_assignable<_Tp&, _Tp&&>\n#if __has_feature(has_nothrow_assign) || (_GNUC_VER >= 403)\n    : integral_constant<bool, __has_nothrow_assign(_Tp)> {};\n#else\n    : integral_constant<bool, is_scalar<_Tp>::value> {};\n#endif\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#endif  // __has_feature(cxx_noexcept)\n\n// is_nothrow_copy_assignable\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_copy_assignable\n    : public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type,\n                  typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};\n\n// is_nothrow_move_assignable\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_move_assignable\n    : public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type,\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n                                     typename add_rvalue_reference<_Tp>::type>\n#else\n                                     typename add_lvalue_reference<_Tp>::type>\n#endif\n    {};\n\n// is_nothrow_destructible\n\n#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)\n\ntemplate <bool, class _Tp> struct __libcpp_is_nothrow_destructible;\n\ntemplate <class _Tp>\nstruct __libcpp_is_nothrow_destructible<false, _Tp>\n    : public false_type\n{\n};\n\ntemplate <class _Tp>\nstruct __libcpp_is_nothrow_destructible<true, _Tp>\n    : public integral_constant<bool, noexcept(_VSTD::declval<_Tp>().~_Tp()) >\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible\n    : public __libcpp_is_nothrow_destructible<is_destructible<_Tp>::value, _Tp>\n{\n};\n\ntemplate <class _Tp, size_t _Ns>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp[_Ns]>\n    : public is_nothrow_destructible<_Tp>\n{\n};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp&>\n    : public true_type\n{\n};\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp&&>\n    : public true_type\n{\n};\n\n#endif\n\n#else\n\ntemplate <class _Tp> struct __libcpp_nothrow_destructor\n    : public integral_constant<bool, is_scalar<_Tp>::value ||\n                                     is_reference<_Tp>::value> {};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible\n    : public __libcpp_nothrow_destructor<typename remove_all_extents<_Tp>::type> {};\n\ntemplate <class _Tp>\nstruct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp[]>\n    : public false_type {};\n\n#endif\n\n// is_pod\n\n#if __has_feature(is_pod) || (_GNUC_VER >= 403)\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_pod\n    : public integral_constant<bool, __is_pod(_Tp)> {};\n\n#else\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_pod\n    : public integral_constant<bool, is_trivially_default_constructible<_Tp>::value   &&\n                                     is_trivially_copy_constructible<_Tp>::value      &&\n                                     is_trivially_copy_assignable<_Tp>::value    &&\n                                     is_trivially_destructible<_Tp>::value> {};\n\n#endif\n\n// is_literal_type;\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_literal_type\n#ifdef _LIBCPP_IS_LITERAL\n    : public integral_constant<bool, _LIBCPP_IS_LITERAL(_Tp)>\n#else\n    : integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value ||\n                              is_reference<typename remove_all_extents<_Tp>::type>::value>\n#endif\n    {};\n    \n// is_standard_layout;\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_standard_layout\n#if __has_feature(is_standard_layout) || (_GNUC_VER >= 407)\n    : public integral_constant<bool, __is_standard_layout(_Tp)>\n#else\n    : integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value>\n#endif\n    {};\n    \n// is_trivially_copyable;\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copyable\n#if __has_feature(is_trivially_copyable)\n    : public integral_constant<bool, __is_trivially_copyable(_Tp)>\n#elif _GNUC_VER >= 501\n    : public integral_constant<bool, !is_volatile<_Tp>::value && __is_trivially_copyable(_Tp)>\n#else\n    : integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value>\n#endif\n    {};\n    \n// is_trivial;\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivial\n#if __has_feature(is_trivial) || _GNUC_VER >= 407\n    : public integral_constant<bool, __is_trivial(_Tp)>\n#else\n    : integral_constant<bool, is_trivially_copyable<_Tp>::value &&\n                                 is_trivially_default_constructible<_Tp>::value>\n#endif\n    {};\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n// Check for complete types\n\ntemplate <class ..._Tp> struct __check_complete;\n\ntemplate <>\nstruct __check_complete<>\n{\n};\n\ntemplate <class _Hp, class _T0, class ..._Tp>\nstruct __check_complete<_Hp, _T0, _Tp...>\n    : private __check_complete<_Hp>,\n      private __check_complete<_T0, _Tp...>\n{\n};\n\ntemplate <class _Hp>\nstruct __check_complete<_Hp, _Hp>\n    : private __check_complete<_Hp>\n{\n};\n\ntemplate <class _Tp>\nstruct __check_complete<_Tp>\n{\n    static_assert(sizeof(_Tp) > 0, \"Type must be complete.\");\n};\n\ntemplate <class _Tp>\nstruct __check_complete<_Tp&>\n    : private __check_complete<_Tp>\n{\n};\n\ntemplate <class _Tp>\nstruct __check_complete<_Tp&&>\n    : private __check_complete<_Tp>\n{\n};\n\ntemplate <class _Rp, class ..._Param>\nstruct __check_complete<_Rp (*)(_Param...)>\n    : private __check_complete<_Rp>\n{\n};\n\ntemplate <class ..._Param>\nstruct __check_complete<void (*)(_Param...)>\n{\n};\n\ntemplate <class _Rp, class ..._Param>\nstruct __check_complete<_Rp (_Param...)>\n    : private __check_complete<_Rp>\n{\n};\n\ntemplate <class ..._Param>\nstruct __check_complete<void (_Param...)>\n{\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __check_complete<_Rp (_Class::*)(_Param...)>\n    : private __check_complete<_Class>\n{\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __check_complete<_Rp (_Class::*)(_Param...) const>\n    : private __check_complete<_Class>\n{\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __check_complete<_Rp (_Class::*)(_Param...) volatile>\n    : private __check_complete<_Class>\n{\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __check_complete<_Rp (_Class::*)(_Param...) const volatile>\n    : private __check_complete<_Class>\n{\n};\n\n#if __has_feature(cxx_reference_qualified_functions)\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __check_complete<_Rp (_Class::*)(_Param...) &>\n    : private __check_complete<_Class>\n{\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __check_complete<_Rp (_Class::*)(_Param...) const&>\n    : private __check_complete<_Class>\n{\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __check_complete<_Rp (_Class::*)(_Param...) volatile&>\n    : private __check_complete<_Class>\n{\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __check_complete<_Rp (_Class::*)(_Param...) const volatile&>\n    : private __check_complete<_Class>\n{\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __check_complete<_Rp (_Class::*)(_Param...) &&>\n    : private __check_complete<_Class>\n{\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __check_complete<_Rp (_Class::*)(_Param...) const&&>\n    : private __check_complete<_Class>\n{\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __check_complete<_Rp (_Class::*)(_Param...) volatile&&>\n    : private __check_complete<_Class>\n{\n};\n\ntemplate <class _Rp, class _Class, class ..._Param>\nstruct __check_complete<_Rp (_Class::*)(_Param...) const volatile&&>\n    : private __check_complete<_Class>\n{\n};\n\n#endif\n\ntemplate <class _Rp, class _Class>\nstruct __check_complete<_Rp _Class::*>\n    : private __check_complete<_Class>\n{\n};\n\n// __invoke forward declarations\n\n// fall back - none of the bullets\n\ntemplate <class ..._Args>\nauto\n__invoke(__any, _Args&& ...__args)\n    -> __nat;\n\n// bullets 1 and 2\n\ntemplate <class _Fp, class _A0, class ..._Args,\n            class = typename enable_if\n            <\n                is_member_function_pointer<typename remove_reference<_Fp>::type>::value &&\n                is_base_of<typename remove_reference<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType>::type,\n                           typename remove_reference<_A0>::type>::value\n            >::type\n         >\n_LIBCPP_INLINE_VISIBILITY\nauto\n__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)\n    -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...));\n\ntemplate <class _Fp, class _A0, class ..._Args,\n            class = typename enable_if\n            <\n                is_member_function_pointer<typename remove_reference<_Fp>::type>::value &&\n                !is_base_of<typename remove_reference<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType>::type,\n                           typename remove_reference<_A0>::type>::value\n            >::type\n         >\n_LIBCPP_INLINE_VISIBILITY\nauto\n__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)\n    -> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...));\n\n// bullets 3 and 4\n\ntemplate <class _Fp, class _A0,\n            class = typename enable_if\n            <\n                is_member_object_pointer<typename remove_reference<_Fp>::type>::value &&\n                is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType,\n                           typename remove_reference<_A0>::type>::value\n            >::type\n         >\n_LIBCPP_INLINE_VISIBILITY\nauto\n__invoke(_Fp&& __f, _A0&& __a0)\n    -> decltype(_VSTD::forward<_A0>(__a0).*__f);\n\ntemplate <class _Fp, class _A0,\n            class = typename enable_if\n            <\n                is_member_object_pointer<typename remove_reference<_Fp>::type>::value &&\n                !is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType,\n                           typename remove_reference<_A0>::type>::value\n            >::type\n         >\n_LIBCPP_INLINE_VISIBILITY\nauto\n__invoke(_Fp&& __f, _A0&& __a0)\n    -> decltype((*_VSTD::forward<_A0>(__a0)).*__f);\n\n// bullet 5\n\ntemplate <class _Fp, class ..._Args>\n_LIBCPP_INLINE_VISIBILITY\nauto\n__invoke(_Fp&& __f, _Args&& ...__args)\n    -> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...));\n\n// __invokable\n\ntemplate <class _Fp, class ..._Args>\nstruct __invokable_imp\n    : private __check_complete<_Fp>\n{\n    typedef decltype(\n            __invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...)\n                    ) type;\n    static const bool value = !is_same<type, __nat>::value;\n};\n\ntemplate <class _Fp, class ..._Args>\nstruct __invokable\n    : public integral_constant<bool,\n          __invokable_imp<_Fp, _Args...>::value>\n{\n};\n\n// __invoke_of\n\ntemplate <bool _Invokable, class _Fp, class ..._Args>\nstruct __invoke_of_imp  // false\n{\n};\n\ntemplate <class _Fp, class ..._Args>\nstruct __invoke_of_imp<true, _Fp, _Args...>\n{\n    typedef typename __invokable_imp<_Fp, _Args...>::type type;\n};\n\ntemplate <class _Fp, class ..._Args>\nstruct __invoke_of\n    : public __invoke_of_imp<__invokable<_Fp, _Args...>::value, _Fp, _Args...>\n{\n};\n\ntemplate <class _Fp, class ..._Args>\nclass _LIBCPP_TYPE_VIS_ONLY result_of<_Fp(_Args...)>\n    : public __invoke_of<_Fp, _Args...>\n{\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using result_of_t = typename result_of<_Tp>::type;\n#endif\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE\ntypename enable_if\n<\n    is_move_constructible<_Tp>::value &&\n    is_move_assignable<_Tp>::value\n>::type\n#else\nvoid\n#endif\nswap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value &&\n                                    is_nothrow_move_assignable<_Tp>::value)\n{\n    _Tp __t(_VSTD::move(__x));\n    __x = _VSTD::move(__y);\n    __y = _VSTD::move(__t);\n}\n\ntemplate <class _ForwardIterator1, class _ForwardIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\niter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b)\n    //                                  _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b)))\n               _NOEXCEPT_(_NOEXCEPT_(swap(*_VSTD::declval<_ForwardIterator1>(),\n                                          *_VSTD::declval<_ForwardIterator2>())))\n{\n    swap(*__a, *__b);\n}\n\n// __swappable\n\nnamespace __detail\n{\n\nusing _VSTD::swap;\n__nat swap(__any, __any);\n\ntemplate <class _Tp>\nstruct __swappable\n{\n    typedef decltype(swap(_VSTD::declval<_Tp&>(), _VSTD::declval<_Tp&>())) type;\n    static const bool value = !is_same<type, __nat>::value;\n};\n\n}  // __detail\n\ntemplate <class _Tp>\nstruct __is_swappable\n    : public integral_constant<bool, __detail::__swappable<_Tp>::value>\n{\n};\n\n#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)\n\ntemplate <bool, class _Tp>\nstruct __is_nothrow_swappable_imp\n    : public integral_constant<bool, noexcept(swap(_VSTD::declval<_Tp&>(),\n                                                   _VSTD::declval<_Tp&>()))>\n{\n};\n\ntemplate <class _Tp>\nstruct __is_nothrow_swappable_imp<false, _Tp>\n    : public false_type\n{\n};\n\ntemplate <class _Tp>\nstruct __is_nothrow_swappable\n    : public __is_nothrow_swappable_imp<__is_swappable<_Tp>::value, _Tp>\n{\n};\n\n#else  // __has_feature(cxx_noexcept)\n\ntemplate <class _Tp>\nstruct __is_nothrow_swappable\n    : public false_type\n{\n};\n\n#endif  // __has_feature(cxx_noexcept)\n\n#ifdef _LIBCPP_UNDERLYING_TYPE\n\ntemplate <class _Tp>\nstruct underlying_type\n{\n    typedef _LIBCPP_UNDERLYING_TYPE(_Tp) type;\n};\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp> using underlying_type_t = typename underlying_type<_Tp>::type;\n#endif\n\n#else  // _LIBCPP_UNDERLYING_TYPE\n\ntemplate <class _Tp, bool _Support = false>\nstruct underlying_type\n{\n    static_assert(_Support, \"The underyling_type trait requires compiler \"\n                            \"support. Either no such support exists or \"\n                            \"libc++ does not know how to use it.\");\n};\n\n#endif // _LIBCPP_UNDERLYING_TYPE\n\n\ntemplate <class _Tp, bool = std::is_enum<_Tp>::value>\nstruct __sfinae_underlying_type\n{\n    typedef typename underlying_type<_Tp>::type type;\n    typedef decltype(((type)1) + 0) __promoted_type;\n};\n\ntemplate <class _Tp>\nstruct __sfinae_underlying_type<_Tp, false> {};\n\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE\nint __convert_to_integral(int __val) { return __val; }\n\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE\nunsigned __convert_to_integral(unsigned __val) { return __val; }\n\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE\nlong __convert_to_integral(long __val) { return __val; }\n\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE\nunsigned long __convert_to_integral(unsigned long __val) { return __val; }\n\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE\nlong long __convert_to_integral(long long __val) { return __val; }\n\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE\nunsigned long long __convert_to_integral(unsigned long long __val) {return __val; }\n\n#ifndef _LIBCPP_HAS_NO_INT128\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE\n__int128_t __convert_to_integral(__int128_t __val) { return __val; }\n\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE\n__uint128_t __convert_to_integral(__uint128_t __val) { return __val; }\n#endif\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE\ntypename __sfinae_underlying_type<_Tp>::__promoted_type\n__convert_to_integral(_Tp __val) { return __val; }\n\n#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE\n\ntemplate <class _Tp>\nstruct __has_operator_addressof_member_imp\n{\n    template <class _Up>\n        static auto __test(int)\n            -> typename __select_2nd<decltype(_VSTD::declval<_Up>().operator&()), true_type>::type;\n    template <class>\n        static auto __test(long) -> false_type;\n\n    static const bool value = decltype(__test<_Tp>(0))::value;\n};\n\ntemplate <class _Tp>\nstruct __has_operator_addressof_free_imp\n{\n    template <class _Up>\n        static auto __test(int)\n            -> typename __select_2nd<decltype(operator&(_VSTD::declval<_Up>())), true_type>::type;\n    template <class>\n        static auto __test(long) -> false_type;\n\n    static const bool value = decltype(__test<_Tp>(0))::value;\n};\n\ntemplate <class _Tp>\nstruct __has_operator_addressof\n    : public integral_constant<bool, __has_operator_addressof_member_imp<_Tp>::value\n                                  || __has_operator_addressof_free_imp<_Tp>::value>\n{};\n\n#endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE\n\n#if _LIBCPP_STD_VER > 14\ntemplate <class...> using void_t = void;\n#endif\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_TYPE_TRAITS\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/typeindex",
    "content": "// -*- C++ -*-\n//===-------------------------- typeindex ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_TYPEINDEX\n#define _LIBCPP_TYPEINDEX\n\n/*\n\n    typeindex synopsis\n\nnamespace std\n{\n\nclass type_index\n{\npublic:\n    type_index(const type_info& rhs) noexcept;\n\n    bool operator==(const type_index& rhs) const noexcept;\n    bool operator!=(const type_index& rhs) const noexcept;\n    bool operator< (const type_index& rhs) const noexcept;\n    bool operator<=(const type_index& rhs) const noexcept;\n    bool operator> (const type_index& rhs) const noexcept;\n    bool operator>=(const type_index& rhs) const noexcept;\n\n    size_t hash_code() const noexcept;\n    const char* name() const noexcept;\n};\n\ntemplate <>\nstruct hash<type_index>\n    : public unary_function<type_index, size_t>\n{\n    size_t operator()(type_index index) const noexcept;\n};\n\n}  // std\n\n*/\n\n#include <__config>\n#include <typeinfo>\n#include <__functional_base>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nclass _LIBCPP_TYPE_VIS_ONLY type_index\n{\n    const type_info* __t_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    type_index(const type_info& __y) _NOEXCEPT : __t_(&__y) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const type_index& __y) const _NOEXCEPT\n        {return *__t_ == *__y.__t_;}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const type_index& __y) const _NOEXCEPT\n        {return *__t_ != *__y.__t_;}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator< (const type_index& __y) const _NOEXCEPT\n        {return  __t_->before(*__y.__t_);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator<=(const type_index& __y) const _NOEXCEPT\n        {return !__y.__t_->before(*__t_);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator> (const type_index& __y) const _NOEXCEPT\n        {return  __y.__t_->before(*__t_);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator>=(const type_index& __y) const _NOEXCEPT\n        {return !__t_->before(*__y.__t_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t hash_code() const _NOEXCEPT {return __t_->hash_code();}\n    _LIBCPP_INLINE_VISIBILITY\n    const char* name() const _NOEXCEPT {return __t_->name();}\n};\n\ntemplate <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash;\n\ntemplate <>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<type_index>\n    : public unary_function<type_index, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(type_index __index) const _NOEXCEPT\n        {return __index.hash_code();}\n};\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_TYPEINDEX\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/typeinfo",
    "content": "// -*- C++ -*-\n//===-------------------------- typeinfo ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef __LIBCPP_TYPEINFO\n#define __LIBCPP_TYPEINFO\n\n/*\n\n    typeinfo synopsis\n\nnamespace std {\n\nclass type_info\n{\npublic:\n    virtual ~type_info();\n\n    bool operator==(const type_info& rhs) const noexcept;\n    bool operator!=(const type_info& rhs) const noexcept;\n\n    bool before(const type_info& rhs) const noexcept;\n    size_t hash_code() const noexcept;\n    const char* name() const noexcept;\n\n    type_info(const type_info& rhs) = delete;\n    type_info& operator=(const type_info& rhs) = delete;\n};\n\nclass bad_cast\n    : public exception\n{\npublic:\n    bad_cast() noexcept;\n    bad_cast(const bad_cast&) noexcept;\n    bad_cast& operator=(const bad_cast&) noexcept;\n    virtual const char* what() const noexcept;\n};\n\nclass bad_typeid\n    : public exception\n{\npublic:\n    bad_typeid() noexcept;\n    bad_typeid(const bad_typeid&) noexcept;\n    bad_typeid& operator=(const bad_typeid&) noexcept;\n    virtual const char* what() const noexcept;\n};\n\n}  // std\n\n*/\n\n#include <__config>\n#include <exception>\n#include <cstddef>\n#include <cstdint>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\nnamespace std  // purposefully not using versioning namespace\n{\n\nclass _LIBCPP_EXCEPTION_ABI type_info\n{\n    type_info& operator=(const type_info&);\n    type_info(const type_info&);\nprotected:\n#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT\n    const char* __type_name;\n#else\n    // A const char* with the non-unique RTTI bit possibly set.\n    uintptr_t __type_name;\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit type_info(const char* __n)\n#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT\n        : __type_name(__n) {}\n#else\n        : __type_name(reinterpret_cast<uintptr_t>(__n)) {}\n#endif\n\npublic:\n    virtual ~type_info();\n\n    _LIBCPP_INLINE_VISIBILITY\n    const char* name() const _NOEXCEPT\n#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT\n        {return __type_name;}\n#else\n        {return reinterpret_cast<const char*>(__type_name & ~_LIBCPP_NONUNIQUE_RTTI_BIT);}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool before(const type_info& __arg) const _NOEXCEPT\n#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT\n        {return __type_name < __arg.__type_name;}\n#else\n        {if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))\n           return __type_name < __arg.__type_name;\n         return __compare_nonunique_names(__arg) < 0;}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t hash_code() const _NOEXCEPT\n#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT\n        {return *reinterpret_cast<const size_t*>(&__type_name);}\n#else\n        {if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) return __type_name;\n         const char *__ptr = name();\n         size_t __hash = 5381;\n         while (unsigned char __c = static_cast<unsigned char>(*__ptr++))\n           __hash = (__hash * 33) ^ __c;\n         return __hash;}\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator==(const type_info& __arg) const _NOEXCEPT\n#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT\n        {return __type_name == __arg.__type_name;}\n#else\n        {if (__type_name == __arg.__type_name) return true;\n         if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))\n           return false;\n         return __compare_nonunique_names(__arg) == 0;}\n#endif\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator!=(const type_info& __arg) const _NOEXCEPT\n        {return !operator==(__arg);}\n\n#ifdef _LIBCPP_NONUNIQUE_RTTI_BIT\n  private:\n    _LIBCPP_INLINE_VISIBILITY\n    int __compare_nonunique_names(const type_info &__arg) const _NOEXCEPT\n        {return __builtin_strcmp(name(), __arg.name());}\n#endif\n};\n\nclass _LIBCPP_EXCEPTION_ABI bad_cast\n    : public exception\n{\npublic:\n    bad_cast() _NOEXCEPT;\n    virtual ~bad_cast() _NOEXCEPT;\n    virtual const char* what() const _NOEXCEPT;\n};\n\nclass _LIBCPP_EXCEPTION_ABI bad_typeid\n    : public exception\n{\npublic:\n    bad_typeid() _NOEXCEPT;\n    virtual ~bad_typeid() _NOEXCEPT;\n    virtual const char* what() const _NOEXCEPT;\n};\n\n}  // std\n\n#endif  // __LIBCPP_TYPEINFO\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/unordered_map",
    "content": "// -*- C++ -*-\n//===-------------------------- unordered_map -----------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_UNORDERED_MAP\n#define _LIBCPP_UNORDERED_MAP\n\n/*\n\n    unordered_map synopsis\n\n#include <initializer_list>\n\nnamespace std\n{\n\ntemplate <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,\n          class Alloc = allocator<pair<const Key, T>>>\nclass unordered_map\n{\npublic:\n    // types\n    typedef Key                                                        key_type;\n    typedef T                                                          mapped_type;\n    typedef Hash                                                       hasher;\n    typedef Pred                                                       key_equal;\n    typedef Alloc                                                      allocator_type;\n    typedef pair<const key_type, mapped_type>                          value_type;\n    typedef value_type&                                                reference;\n    typedef const value_type&                                          const_reference;\n    typedef typename allocator_traits<allocator_type>::pointer         pointer;\n    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;\n    typedef typename allocator_traits<allocator_type>::size_type       size_type;\n    typedef typename allocator_traits<allocator_type>::difference_type difference_type;\n\n    typedef /unspecified/ iterator;\n    typedef /unspecified/ const_iterator;\n    typedef /unspecified/ local_iterator;\n    typedef /unspecified/ const_local_iterator;\n\n    unordered_map()\n        noexcept(\n            is_nothrow_default_constructible<hasher>::value &&\n            is_nothrow_default_constructible<key_equal>::value &&\n            is_nothrow_default_constructible<allocator_type>::value);\n    explicit unordered_map(size_type n, const hasher& hf = hasher(),\n                           const key_equal& eql = key_equal(),\n                           const allocator_type& a = allocator_type());\n    template <class InputIterator>\n        unordered_map(InputIterator f, InputIterator l,\n                      size_type n = 0, const hasher& hf = hasher(),\n                      const key_equal& eql = key_equal(),\n                      const allocator_type& a = allocator_type());\n    explicit unordered_map(const allocator_type&);\n    unordered_map(const unordered_map&);\n    unordered_map(const unordered_map&, const Allocator&);\n    unordered_map(unordered_map&&)\n        noexcept(\n            is_nothrow_move_constructible<hasher>::value &&\n            is_nothrow_move_constructible<key_equal>::value &&\n            is_nothrow_move_constructible<allocator_type>::value);\n    unordered_map(unordered_map&&, const Allocator&);\n    unordered_map(initializer_list<value_type>, size_type n = 0,\n                  const hasher& hf = hasher(), const key_equal& eql = key_equal(),\n                  const allocator_type& a = allocator_type());\n    unordered_map(size_type n, const allocator_type& a)\n      : unordered_map(n, hasher(), key_equal(), a) {}  // C++14\n    unordered_map(size_type n, const hasher& hf, const allocator_type& a)\n      : unordered_map(n, hf, key_equal(), a) {}  // C++14\n    template <class InputIterator>\n      unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a)\n      : unordered_map(f, l, n, hasher(), key_equal(), a) {}  // C++14\n    template <class InputIterator>\n      unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, \n        const allocator_type& a)\n      : unordered_map(f, l, n, hf, key_equal(), a) {}  // C++14\n    unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)\n      : unordered_map(il, n, hasher(), key_equal(), a) {}  // C++14\n    unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf, \n      const allocator_type& a)\n      : unordered_map(il, n, hf, key_equal(), a) {}  // C++14\n    ~unordered_map();\n    unordered_map& operator=(const unordered_map&);\n    unordered_map& operator=(unordered_map&&)\n        noexcept(\n            allocator_type::propagate_on_container_move_assignment::value &&\n            is_nothrow_move_assignable<allocator_type>::value &&\n            is_nothrow_move_assignable<hasher>::value &&\n            is_nothrow_move_assignable<key_equal>::value);\n    unordered_map& operator=(initializer_list<value_type>);\n\n    allocator_type get_allocator() const noexcept;\n\n    bool      empty() const noexcept;\n    size_type size() const noexcept;\n    size_type max_size() const noexcept;\n\n    iterator       begin() noexcept;\n    iterator       end() noexcept;\n    const_iterator begin()  const noexcept;\n    const_iterator end()    const noexcept;\n    const_iterator cbegin() const noexcept;\n    const_iterator cend()   const noexcept;\n\n    template <class... Args>\n        pair<iterator, bool> emplace(Args&&... args);\n    template <class... Args>\n        iterator emplace_hint(const_iterator position, Args&&... args);\n    pair<iterator, bool> insert(const value_type& obj);\n    template <class P>\n        pair<iterator, bool> insert(P&& obj);\n    iterator insert(const_iterator hint, const value_type& obj);\n    template <class P>\n        iterator insert(const_iterator hint, P&& obj);\n    template <class InputIterator>\n        void insert(InputIterator first, InputIterator last);\n    void insert(initializer_list<value_type>);\n\n    template <class... Args>\n        pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);          // C++17\n    template <class... Args>\n        pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);               // C++17\n    template <class... Args>\n        iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17\n    template <class... Args>\n        iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);      // C++17\n    template <class M>\n        pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);            // C++17\n    template <class M>\n        pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);                 // C++17\n    template <class M>\n        iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);   // C++17\n    template <class M>\n        iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);        // C++17\n\n    iterator erase(const_iterator position);\n    iterator erase(iterator position);  // C++14\n    size_type erase(const key_type& k);\n    iterator erase(const_iterator first, const_iterator last);\n    void clear() noexcept;\n\n    void swap(unordered_map&)\n        noexcept(\n            (!allocator_type::propagate_on_container_swap::value ||\n             __is_nothrow_swappable<allocator_type>::value) &&\n            __is_nothrow_swappable<hasher>::value &&\n            __is_nothrow_swappable<key_equal>::value);\n\n    hasher hash_function() const;\n    key_equal key_eq() const;\n\n    iterator       find(const key_type& k);\n    const_iterator find(const key_type& k) const;\n    size_type count(const key_type& k) const;\n    pair<iterator, iterator>             equal_range(const key_type& k);\n    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;\n\n    mapped_type& operator[](const key_type& k);\n    mapped_type& operator[](key_type&& k);\n\n    mapped_type&       at(const key_type& k);\n    const mapped_type& at(const key_type& k) const;\n\n    size_type bucket_count() const noexcept;\n    size_type max_bucket_count() const noexcept;\n\n    size_type bucket_size(size_type n) const;\n    size_type bucket(const key_type& k) const;\n\n    local_iterator       begin(size_type n);\n    local_iterator       end(size_type n);\n    const_local_iterator begin(size_type n) const;\n    const_local_iterator end(size_type n) const;\n    const_local_iterator cbegin(size_type n) const;\n    const_local_iterator cend(size_type n) const;\n\n    float load_factor() const noexcept;\n    float max_load_factor() const noexcept;\n    void max_load_factor(float z);\n    void rehash(size_type n);\n    void reserve(size_type n);\n};\n\ntemplate <class Key, class T, class Hash, class Pred, class Alloc>\n    void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x,\n              unordered_map<Key, T, Hash, Pred, Alloc>& y)\n              noexcept(noexcept(x.swap(y)));\n\ntemplate <class Key, class T, class Hash, class Pred, class Alloc>\n    bool\n    operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& x,\n               const unordered_map<Key, T, Hash, Pred, Alloc>& y);\n\ntemplate <class Key, class T, class Hash, class Pred, class Alloc>\n    bool\n    operator!=(const unordered_map<Key, T, Hash, Pred, Alloc>& x,\n               const unordered_map<Key, T, Hash, Pred, Alloc>& y);\n\ntemplate <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,\n          class Alloc = allocator<pair<const Key, T>>>\nclass unordered_multimap\n{\npublic:\n    // types\n    typedef Key                                                        key_type;\n    typedef T                                                          mapped_type;\n    typedef Hash                                                       hasher;\n    typedef Pred                                                       key_equal;\n    typedef Alloc                                                      allocator_type;\n    typedef pair<const key_type, mapped_type>                          value_type;\n    typedef value_type&                                                reference;\n    typedef const value_type&                                          const_reference;\n    typedef typename allocator_traits<allocator_type>::pointer         pointer;\n    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;\n    typedef typename allocator_traits<allocator_type>::size_type       size_type;\n    typedef typename allocator_traits<allocator_type>::difference_type difference_type;\n\n    typedef /unspecified/ iterator;\n    typedef /unspecified/ const_iterator;\n    typedef /unspecified/ local_iterator;\n    typedef /unspecified/ const_local_iterator;\n\n    unordered_multimap()\n        noexcept(\n            is_nothrow_default_constructible<hasher>::value &&\n            is_nothrow_default_constructible<key_equal>::value &&\n            is_nothrow_default_constructible<allocator_type>::value);\n    explicit unordered_multimap(size_type n, const hasher& hf = hasher(),\n                           const key_equal& eql = key_equal(),\n                           const allocator_type& a = allocator_type());\n    template <class InputIterator>\n        unordered_multimap(InputIterator f, InputIterator l,\n                      size_type n = 0, const hasher& hf = hasher(),\n                      const key_equal& eql = key_equal(),\n                      const allocator_type& a = allocator_type());\n    explicit unordered_multimap(const allocator_type&);\n    unordered_multimap(const unordered_multimap&);\n    unordered_multimap(const unordered_multimap&, const Allocator&);\n    unordered_multimap(unordered_multimap&&)\n        noexcept(\n            is_nothrow_move_constructible<hasher>::value &&\n            is_nothrow_move_constructible<key_equal>::value &&\n            is_nothrow_move_constructible<allocator_type>::value);\n    unordered_multimap(unordered_multimap&&, const Allocator&);\n    unordered_multimap(initializer_list<value_type>, size_type n = 0,\n                  const hasher& hf = hasher(), const key_equal& eql = key_equal(),\n                  const allocator_type& a = allocator_type());\n    unordered_multimap(size_type n, const allocator_type& a)\n      : unordered_multimap(n, hasher(), key_equal(), a) {}  // C++14\n    unordered_multimap(size_type n, const hasher& hf, const allocator_type& a)\n      : unordered_multimap(n, hf, key_equal(), a) {}  // C++14\n    template <class InputIterator>\n      unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a)\n      : unordered_multimap(f, l, n, hasher(), key_equal(), a) {}  // C++14\n    template <class InputIterator>\n      unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, \n        const allocator_type& a)\n      : unordered_multimap(f, l, n, hf, key_equal(), a) {}  // C++14\n    unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)\n      : unordered_multimap(il, n, hasher(), key_equal(), a) {}  // C++14\n    unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf, \n      const allocator_type& a)\n      : unordered_multimap(il, n, hf, key_equal(), a) {}  // C++14\n    ~unordered_multimap();\n    unordered_multimap& operator=(const unordered_multimap&);\n    unordered_multimap& operator=(unordered_multimap&&)\n        noexcept(\n            allocator_type::propagate_on_container_move_assignment::value &&\n            is_nothrow_move_assignable<allocator_type>::value &&\n            is_nothrow_move_assignable<hasher>::value &&\n            is_nothrow_move_assignable<key_equal>::value);\n    unordered_multimap& operator=(initializer_list<value_type>);\n\n    allocator_type get_allocator() const noexcept;\n\n    bool      empty() const noexcept;\n    size_type size() const noexcept;\n    size_type max_size() const noexcept;\n\n    iterator       begin() noexcept;\n    iterator       end() noexcept;\n    const_iterator begin()  const noexcept;\n    const_iterator end()    const noexcept;\n    const_iterator cbegin() const noexcept;\n    const_iterator cend()   const noexcept;\n\n    template <class... Args>\n        iterator emplace(Args&&... args);\n    template <class... Args>\n        iterator emplace_hint(const_iterator position, Args&&... args);\n    iterator insert(const value_type& obj);\n    template <class P>\n        iterator insert(P&& obj);\n    iterator insert(const_iterator hint, const value_type& obj);\n    template <class P>\n        iterator insert(const_iterator hint, P&& obj);\n    template <class InputIterator>\n        void insert(InputIterator first, InputIterator last);\n    void insert(initializer_list<value_type>);\n\n    iterator erase(const_iterator position);\n    iterator erase(iterator position);  // C++14\n    size_type erase(const key_type& k);\n    iterator erase(const_iterator first, const_iterator last);\n    void clear() noexcept;\n\n    void swap(unordered_multimap&)\n        noexcept(\n            (!allocator_type::propagate_on_container_swap::value ||\n             __is_nothrow_swappable<allocator_type>::value) &&\n            __is_nothrow_swappable<hasher>::value &&\n            __is_nothrow_swappable<key_equal>::value);\n\n    hasher hash_function() const;\n    key_equal key_eq() const;\n\n    iterator       find(const key_type& k);\n    const_iterator find(const key_type& k) const;\n    size_type count(const key_type& k) const;\n    pair<iterator, iterator>             equal_range(const key_type& k);\n    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;\n\n    size_type bucket_count() const noexcept;\n    size_type max_bucket_count() const noexcept;\n\n    size_type bucket_size(size_type n) const;\n    size_type bucket(const key_type& k) const;\n\n    local_iterator       begin(size_type n);\n    local_iterator       end(size_type n);\n    const_local_iterator begin(size_type n) const;\n    const_local_iterator end(size_type n) const;\n    const_local_iterator cbegin(size_type n) const;\n    const_local_iterator cend(size_type n) const;\n\n    float load_factor() const noexcept;\n    float max_load_factor() const noexcept;\n    void max_load_factor(float z);\n    void rehash(size_type n);\n    void reserve(size_type n);\n};\n\ntemplate <class Key, class T, class Hash, class Pred, class Alloc>\n    void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x,\n              unordered_multimap<Key, T, Hash, Pred, Alloc>& y)\n              noexcept(noexcept(x.swap(y)));\n\ntemplate <class Key, class T, class Hash, class Pred, class Alloc>\n    bool\n    operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x,\n               const unordered_multimap<Key, T, Hash, Pred, Alloc>& y);\n\ntemplate <class Key, class T, class Hash, class Pred, class Alloc>\n    bool\n    operator!=(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x,\n               const unordered_multimap<Key, T, Hash, Pred, Alloc>& y);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <__hash_table>\n#include <functional>\n#include <stdexcept>\n\n#include <__debug>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Key, class _Cp, class _Hash,\n          bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value\n         >\nclass __unordered_map_hasher\n    : private _Hash\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __unordered_map_hasher()\n        _NOEXCEPT_(is_nothrow_default_constructible<_Hash>::value)\n        : _Hash() {}\n    _LIBCPP_INLINE_VISIBILITY\n    __unordered_map_hasher(const _Hash& __h)\n        _NOEXCEPT_(is_nothrow_copy_constructible<_Hash>::value)\n        : _Hash(__h) {}\n    _LIBCPP_INLINE_VISIBILITY\n    const _Hash& hash_function() const _NOEXCEPT {return *this;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(const _Cp& __x) const\n        {return static_cast<const _Hash&>(*this)(__x.__cc.first);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(const _Key& __x) const\n        {return static_cast<const _Hash&>(*this)(__x);}\n    void swap(__unordered_map_hasher&__y)\n        _NOEXCEPT_(__is_nothrow_swappable<_Hash>::value)\n    {\n        using _VSTD::swap;\n        swap(static_cast<const _Hash&>(*this), static_cast<const _Hash&>(__y));\n    }\n};\n\ntemplate <class _Key, class _Cp, class _Hash>\nclass __unordered_map_hasher<_Key, _Cp, _Hash, false>\n{\n    _Hash __hash_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __unordered_map_hasher()\n        _NOEXCEPT_(is_nothrow_default_constructible<_Hash>::value)\n        : __hash_() {}\n    _LIBCPP_INLINE_VISIBILITY\n    __unordered_map_hasher(const _Hash& __h)\n        _NOEXCEPT_(is_nothrow_copy_constructible<_Hash>::value)\n        : __hash_(__h) {}\n    _LIBCPP_INLINE_VISIBILITY\n    const _Hash& hash_function() const _NOEXCEPT {return __hash_;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(const _Cp& __x) const\n        {return __hash_(__x.__cc.first);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(const _Key& __x) const\n        {return __hash_(__x);}\n    void swap(__unordered_map_hasher&__y)\n        _NOEXCEPT_(__is_nothrow_swappable<_Hash>::value)\n    {\n        using _VSTD::swap;\n        swap(__hash_, __y.__hash_);\n    }\n};\n\ntemplate <class _Key, class _Cp, class _Hash, bool __b>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(__unordered_map_hasher<_Key, _Cp, _Hash, __b>& __x,\n     __unordered_map_hasher<_Key, _Cp, _Hash, __b>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Key, class _Cp, class _Pred,\n          bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value\n         >\nclass __unordered_map_equal\n    : private _Pred\n{\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __unordered_map_equal()\n        _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value)\n        : _Pred() {}\n    _LIBCPP_INLINE_VISIBILITY\n    __unordered_map_equal(const _Pred& __p)\n        _NOEXCEPT_(is_nothrow_copy_constructible<_Pred>::value)\n        : _Pred(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    const _Pred& key_eq() const _NOEXCEPT {return *this;}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Cp& __x, const _Cp& __y) const\n        {return static_cast<const _Pred&>(*this)(__x.__cc.first, __y.__cc.first);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Cp& __x, const _Key& __y) const\n        {return static_cast<const _Pred&>(*this)(__x.__cc.first, __y);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Key& __x, const _Cp& __y) const\n        {return static_cast<const _Pred&>(*this)(__x, __y.__cc.first);}\n    void swap(__unordered_map_equal&__y)\n        _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value)\n    {\n        using _VSTD::swap;\n        swap(static_cast<const _Pred&>(*this), static_cast<const _Pred&>(__y));\n    }\n};\n\ntemplate <class _Key, class _Cp, class _Pred>\nclass __unordered_map_equal<_Key, _Cp, _Pred, false>\n{\n    _Pred __pred_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    __unordered_map_equal()\n        _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value)\n        : __pred_() {}\n    _LIBCPP_INLINE_VISIBILITY\n    __unordered_map_equal(const _Pred& __p)\n        _NOEXCEPT_(is_nothrow_copy_constructible<_Pred>::value)\n        : __pred_(__p) {}\n    _LIBCPP_INLINE_VISIBILITY\n    const _Pred& key_eq() const _NOEXCEPT {return __pred_;}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Cp& __x, const _Cp& __y) const\n        {return __pred_(__x.__cc.first, __y.__cc.first);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Cp& __x, const _Key& __y) const\n        {return __pred_(__x.__cc.first, __y);}\n    _LIBCPP_INLINE_VISIBILITY\n    bool operator()(const _Key& __x, const _Cp& __y) const\n        {return __pred_(__x, __y.__cc.first);}\n    void swap(__unordered_map_equal&__y)\n        _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value)\n    {\n        using _VSTD::swap;\n        swap(__pred_, __y.__pred_);\n    }\n};\n\ntemplate <class _Key, class _Cp, class _Pred, bool __b>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(__unordered_map_equal<_Key, _Cp, _Pred, __b>& __x,\n     __unordered_map_equal<_Key, _Cp, _Pred, __b>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Alloc>\nclass __hash_map_node_destructor\n{\n    typedef _Alloc                              allocator_type;\n    typedef allocator_traits<allocator_type>    __alloc_traits;\n    typedef typename __alloc_traits::value_type::value_type value_type;\npublic:\n    typedef typename __alloc_traits::pointer    pointer;\nprivate:\n    typedef typename value_type::value_type::first_type     first_type;\n    typedef typename value_type::value_type::second_type    second_type;\n\n    allocator_type& __na_;\n\n    __hash_map_node_destructor& operator=(const __hash_map_node_destructor&);\n\npublic:\n    bool __first_constructed;\n    bool __second_constructed;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __hash_map_node_destructor(allocator_type& __na) _NOEXCEPT\n        : __na_(__na),\n          __first_constructed(false),\n          __second_constructed(false)\n        {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_node_destructor(__hash_node_destructor<allocator_type>&& __x)\n        _NOEXCEPT\n        : __na_(__x.__na_),\n          __first_constructed(__x.__value_constructed),\n          __second_constructed(__x.__value_constructed)\n        {\n            __x.__value_constructed = false;\n        }\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_node_destructor(const __hash_node_destructor<allocator_type>& __x)\n        : __na_(__x.__na_),\n          __first_constructed(__x.__value_constructed),\n          __second_constructed(__x.__value_constructed)\n        {\n            const_cast<bool&>(__x.__value_constructed) = false;\n        }\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    void operator()(pointer __p) _NOEXCEPT\n    {\n        if (__second_constructed)\n            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.second));\n        if (__first_constructed)\n            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.first));\n        if (__p)\n            __alloc_traits::deallocate(__na_, __p, 1);\n    }\n};\n\n#if __cplusplus >= 201103L\n\ntemplate <class _Key, class _Tp>\nunion __hash_value_type\n{\n    typedef _Key                                     key_type;\n    typedef _Tp                                      mapped_type;\n    typedef pair<const key_type, mapped_type>        value_type;\n    typedef pair<key_type, mapped_type>              __nc_value_type;\n\n    value_type __cc;\n    __nc_value_type __nc;\n\n    template <class ..._Args>\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_value_type(_Args&& ...__args)\n        : __cc(std::forward<_Args>(__args)...) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_value_type(const __hash_value_type& __v)\n        : __cc(__v.__cc) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_value_type(__hash_value_type&& __v)\n        : __nc(_VSTD::move(__v.__nc)) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_value_type& operator=(const __hash_value_type& __v)\n        {__nc = __v.__cc; return *this;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_value_type& operator=(__hash_value_type&& __v)\n        {__nc = _VSTD::move(__v.__nc); return *this;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    ~__hash_value_type() {__cc.~value_type();}\n};\n\n#else\n\ntemplate <class _Key, class _Tp>\nstruct __hash_value_type\n{\n    typedef _Key                                     key_type;\n    typedef _Tp                                      mapped_type;\n    typedef pair<const key_type, mapped_type>        value_type;\n\n    value_type __cc;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_value_type() {}\n\n    template <class _A0>\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_value_type(const _A0& __a0)\n        : __cc(__a0) {}\n\n    template <class _A0, class _A1>\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_value_type(const _A0& __a0, const _A1& __a1)\n        : __cc(__a0, __a1) {}\n};\n\n#endif\n\ntemplate <class _HashIterator>\nclass _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator\n{\n    _HashIterator __i_;\n\n    typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;\n    typedef const typename _HashIterator::value_type::value_type::first_type key_type;\n    typedef typename _HashIterator::value_type::value_type::second_type      mapped_type;\npublic:\n    typedef forward_iterator_tag                                 iterator_category;\n    typedef pair<key_type, mapped_type>                          value_type;\n    typedef typename _HashIterator::difference_type              difference_type;\n    typedef value_type&                                          reference;\n    typedef typename __pointer_traits::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<value_type>\n#else\n            rebind<value_type>::other\n#endif\n                                                                 pointer;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_iterator() _NOEXCEPT {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    reference operator*() const {return __i_->__cc;}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_iterator& operator++() {++__i_; return *this;}\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_iterator operator++(int)\n    {\n        __hash_map_iterator __t(*this);\n        ++(*this);\n        return __t;\n    }\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y)\n        {return __x.__i_ == __y.__i_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)\n        {return __x.__i_ != __y.__i_;}\n\n    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;\n    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;\n};\n\ntemplate <class _HashIterator>\nclass _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator\n{\n    _HashIterator __i_;\n\n    typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;\n    typedef const typename _HashIterator::value_type::value_type::first_type key_type;\n    typedef typename _HashIterator::value_type::value_type::second_type      mapped_type;\npublic:\n    typedef forward_iterator_tag                                 iterator_category;\n    typedef pair<key_type, mapped_type>                          value_type;\n    typedef typename _HashIterator::difference_type              difference_type;\n    typedef const value_type&                                    reference;\n    typedef typename __pointer_traits::template\n#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES\n            rebind<const value_type>\n#else\n            rebind<const value_type>::other\n#endif\n                                                                 pointer;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_const_iterator() _NOEXCEPT {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_const_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {}\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_const_iterator(\n            __hash_map_iterator<typename _HashIterator::__non_const_iterator> __i)\n                 _NOEXCEPT\n                : __i_(__i.__i_) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    reference operator*() const {return __i_->__cc;}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_const_iterator& operator++() {++__i_; return *this;}\n    _LIBCPP_INLINE_VISIBILITY\n    __hash_map_const_iterator operator++(int)\n    {\n        __hash_map_const_iterator __t(*this);\n        ++(*this);\n        return __t;\n    }\n\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)\n        {return __x.__i_ == __y.__i_;}\n    friend _LIBCPP_INLINE_VISIBILITY\n        bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)\n        {return __x.__i_ != __y.__i_;}\n\n    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;\n    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;\n};\n\ntemplate <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,\n          class _Alloc = allocator<pair<const _Key, _Tp> > >\nclass _LIBCPP_TYPE_VIS_ONLY unordered_map\n{\npublic:\n    // types\n    typedef _Key                                           key_type;\n    typedef _Tp                                            mapped_type;\n    typedef _Hash                                          hasher;\n    typedef _Pred                                          key_equal;\n    typedef _Alloc                                         allocator_type;\n    typedef pair<const key_type, mapped_type>              value_type;\n    typedef pair<key_type, mapped_type>                    __nc_value_type;\n    typedef value_type&                                    reference;\n    typedef const value_type&                              const_reference;\n    static_assert((is_same<value_type, typename allocator_type::value_type>::value),\n                  \"Invalid allocator::value_type\");\n\nprivate:\n    typedef __hash_value_type<key_type, mapped_type>                 __value_type;\n    typedef __unordered_map_hasher<key_type, __value_type, hasher>   __hasher;\n    typedef __unordered_map_equal<key_type, __value_type, key_equal> __key_equal;\n    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,\n                                                 __value_type>::type __allocator_type;\n\n    typedef __hash_table<__value_type, __hasher,\n                         __key_equal,  __allocator_type>   __table;\n\n    __table __table_;\n\n    typedef typename __table::__node_pointer               __node_pointer;\n    typedef typename __table::__node_const_pointer         __node_const_pointer;\n    typedef typename __table::__node_traits                __node_traits;\n    typedef typename __table::__node_allocator             __node_allocator;\n    typedef typename __table::__node                       __node;\n    typedef __hash_map_node_destructor<__node_allocator>   _Dp;\n    typedef unique_ptr<__node, _Dp>                         __node_holder;\n    typedef allocator_traits<allocator_type>               __alloc_traits;\npublic:\n    typedef typename __alloc_traits::pointer         pointer;\n    typedef typename __alloc_traits::const_pointer   const_pointer;\n    typedef typename __alloc_traits::size_type       size_type;\n    typedef typename __alloc_traits::difference_type difference_type;\n\n    typedef __hash_map_iterator<typename __table::iterator>       iterator;\n    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;\n    typedef __hash_map_iterator<typename __table::local_iterator> local_iterator;\n    typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_map()\n        _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)\n        {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n            __get_db()->__insert_c(this);\n#endif\n        }\n    explicit unordered_map(size_type __n, const hasher& __hf = hasher(),\n                           const key_equal& __eql = key_equal());\n    unordered_map(size_type __n, const hasher& __hf,\n                  const key_equal& __eql,\n                  const allocator_type& __a);\n    template <class _InputIterator>\n        unordered_map(_InputIterator __first, _InputIterator __last);\n    template <class _InputIterator>\n        unordered_map(_InputIterator __first, _InputIterator __last,\n                      size_type __n, const hasher& __hf = hasher(),\n                      const key_equal& __eql = key_equal());\n    template <class _InputIterator>\n        unordered_map(_InputIterator __first, _InputIterator __last,\n                      size_type __n, const hasher& __hf,\n                      const key_equal& __eql,\n                      const allocator_type& __a);\n    explicit unordered_map(const allocator_type& __a);\n    unordered_map(const unordered_map& __u);\n    unordered_map(const unordered_map& __u, const allocator_type& __a);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    unordered_map(unordered_map&& __u)\n        _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);\n    unordered_map(unordered_map&& __u, const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    unordered_map(initializer_list<value_type> __il);\n    unordered_map(initializer_list<value_type> __il, size_type __n,\n                  const hasher& __hf = hasher(), const key_equal& __eql = key_equal());\n    unordered_map(initializer_list<value_type> __il, size_type __n,\n                  const hasher& __hf, const key_equal& __eql,\n                  const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n#if _LIBCPP_STD_VER > 11\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_map(size_type __n, const allocator_type& __a)\n      : unordered_map(__n, hasher(), key_equal(), __a) {}\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_map(size_type __n, const hasher& __hf, const allocator_type& __a)\n      : unordered_map(__n, __hf, key_equal(), __a) {}\n    template <class _InputIterator>\n    _LIBCPP_INLINE_VISIBILITY\n      unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a)\n      : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) {}\n    template <class _InputIterator>\n    _LIBCPP_INLINE_VISIBILITY\n      unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, \n        const allocator_type& __a)\n      : unordered_map(__first, __last, __n, __hf, key_equal(), __a) {}\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_map(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)\n      : unordered_map(__il, __n, hasher(), key_equal(), __a) {}\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_map(initializer_list<value_type> __il, size_type __n, const hasher& __hf, \n      const allocator_type& __a)\n      : unordered_map(__il, __n, __hf, key_equal(), __a) {}\n#endif\n    // ~unordered_map() = default;\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_map& operator=(const unordered_map& __u)\n    {\n#if __cplusplus >= 201103L\n        __table_ = __u.__table_;\n#else\n        if (this != &__u) {\n            __table_.clear();\n            __table_.hash_function() = __u.__table_.hash_function();\n            __table_.key_eq() = __u.__table_.key_eq();\n            __table_.max_load_factor() = __u.__table_.max_load_factor();\n            __table_.__copy_assign_alloc(__u.__table_);\n            insert(__u.begin(), __u.end());\n        }\n#endif\n        return *this;\n    }\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    unordered_map& operator=(unordered_map&& __u)\n        _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);\n#endif\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    unordered_map& operator=(initializer_list<value_type> __il);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const _NOEXCEPT\n        {return allocator_type(__table_.__node_alloc());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool      empty() const _NOEXCEPT {return __table_.size() == 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const _NOEXCEPT  {return __table_.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const _NOEXCEPT {return __table_.max_size();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       begin() _NOEXCEPT        {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       end() _NOEXCEPT          {return __table_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin()  const _NOEXCEPT {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end()    const _NOEXCEPT {return __table_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cbegin() const _NOEXCEPT {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cend()   const _NOEXCEPT {return __table_.end();}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n    template <class... _Args>\n        pair<iterator, bool> emplace(_Args&&... __args);\n\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        iterator emplace_hint(const_iterator __p, _Args&&... __args)\n        {\n            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n                \"unordered_map::emplace_hint(const_iterator, args...) called with an iterator not\"\n                \" referring to this unordered_map\");\n            return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;\n        }\n#else\n        iterator emplace_hint(const_iterator, _Args&&... __args)\n            {return emplace(_VSTD::forward<_Args>(__args)...).first;}\n#endif\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, bool> insert(const value_type& __x)\n        {return __table_.__insert_unique(__x);}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Pp,\n              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>\n        _LIBCPP_INLINE_VISIBILITY\n        pair<iterator, bool> insert(_Pp&& __x)\n            {return __table_.__insert_unique(_VSTD::forward<_Pp>(__x));}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    iterator insert(const_iterator __p, const value_type& __x)\n        {\n            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n                \"unordered_map::insert(const_iterator, const value_type&) called with an iterator not\"\n                \" referring to this unordered_map\");\n            return insert(__x).first;\n        }\n#else\n    iterator insert(const_iterator, const value_type& __x)\n        {return insert(__x).first;}\n#endif\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Pp,\n              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>\n        _LIBCPP_INLINE_VISIBILITY\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        iterator insert(const_iterator __p, _Pp&& __x)\n        {\n            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n                \"unordered_map::insert(const_iterator, value_type&&) called with an iterator not\"\n                \" referring to this unordered_map\");\n            return insert(_VSTD::forward<_Pp>(__x)).first;\n        }\n#else\n        iterator insert(const_iterator, _Pp&& __x)\n            {return insert(_VSTD::forward<_Pp>(__x)).first;}\n#endif\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _InputIterator>\n        void insert(_InputIterator __first, _InputIterator __last);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    void insert(initializer_list<value_type> __il)\n        {insert(__il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n#if _LIBCPP_STD_VER > 14\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args)\n    {\n        iterator __p = __table_.find(__k);\n        if ( __p != end())\n            return _VSTD::make_pair(__p, false);\n        else\n            return _VSTD::make_pair(\n                      emplace_hint(__p, \n                        _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), \n                        _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)),\n                      true);\n    }\n\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args)\n    {\n        iterator __p = __table_.find(__k);\n        if ( __p != end())\n            return _VSTD::make_pair(__p, false);\n        else\n            return _VSTD::make_pair(\n                      emplace_hint(__p, \n                        _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), \n                        _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)),\n                      true);\n    }\n\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args)\n    {\n        iterator __p = __table_.find(__k);\n        if ( __p != end())\n            return __p;\n        else\n            return emplace_hint(__h, \n                      _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), \n                      _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));\n    }\n\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args)\n    {\n        iterator __p = __table_.find(__k);\n        if ( __p != end())\n            return __p;\n        else\n            return emplace_hint(__h, \n                      _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), \n                      _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));\n    }\n\n    template <class _Vp>\n        _LIBCPP_INLINE_VISIBILITY\n        pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v)\n    {\n        iterator __p = __table_.find(__k);\n        if ( __p != end())\n        {\n            __p->second = _VSTD::move(__v);\n            return _VSTD::make_pair(__p, false);\n        }\n        return _VSTD::make_pair(emplace_hint(__p, __k, _VSTD::forward<_Vp>(__v)), true);\n    }\n        \n    template <class _Vp>\n        _LIBCPP_INLINE_VISIBILITY\n        pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v)\n    {\n        iterator __p = __table_.find(__k);\n        if ( __p != end())\n        {\n            __p->second = _VSTD::move(__v);\n            return _VSTD::make_pair(__p, false);\n        }\n        return _VSTD::make_pair(emplace_hint(__p, _VSTD::forward<key_type>(__k), _VSTD::forward<_Vp>(__v)), true);\n    }\n\n    template <class _Vp>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator insert_or_assign(const_iterator __h, const key_type& __k, _Vp&& __v)\n     {\n        iterator __p = __table_.find(__k);\n        if ( __p != end())\n        {\n            __p->second = _VSTD::move(__v);\n            return __p;\n        }\n        return emplace_hint(__h, __k, _VSTD::forward<_Vp>(__v));\n     }\n\n    template <class _Vp>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator insert_or_assign(const_iterator __h, key_type&& __k, _Vp&& __v)\n     {\n        iterator __p = __table_.find(__k);\n        if ( __p != end())\n        {\n            __p->second = _VSTD::move(__v);\n            return __p;\n        }\n        return emplace_hint(__h, _VSTD::forward<key_type>(__k), _VSTD::forward<_Vp>(__v));\n     }\n#endif\n#endif\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator erase(iterator __p)       {return __table_.erase(__p.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator erase(const_iterator __first, const_iterator __last)\n        {return __table_.erase(__first.__i_, __last.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() _NOEXCEPT {__table_.clear();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(unordered_map& __u)\n        _NOEXCEPT_(__is_nothrow_swappable<__table>::value)\n        {__table_.swap(__u.__table_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    hasher hash_function() const\n        {return __table_.hash_function().hash_function();}\n    _LIBCPP_INLINE_VISIBILITY\n    key_equal key_eq() const\n        {return __table_.key_eq().key_eq();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       find(const key_type& __k)       {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator find(const key_type& __k) const {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, iterator>             equal_range(const key_type& __k)\n        {return __table_.__equal_range_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const\n        {return __table_.__equal_range_unique(__k);}\n\n    mapped_type& operator[](const key_type& __k);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    mapped_type& operator[](key_type&& __k);\n#endif\n\n    mapped_type&       at(const key_type& __k);\n    const mapped_type& at(const key_type& __k) const;\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket_size(size_type __n) const\n        {return __table_.bucket_size(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    local_iterator       begin(size_type __n)        {return __table_.begin(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    local_iterator       end(size_type __n)          {return __table_.end(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator begin(size_type __n) const  {return __table_.cbegin(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator end(size_type __n) const    {return __table_.cend(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator cend(size_type __n) const   {return __table_.cend(__n);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    float load_factor() const _NOEXCEPT {return __table_.load_factor();}\n    _LIBCPP_INLINE_VISIBILITY\n    float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();}\n    _LIBCPP_INLINE_VISIBILITY\n    void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}\n    _LIBCPP_INLINE_VISIBILITY\n    void rehash(size_type __n) {__table_.rehash(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    void reserve(size_type __n) {__table_.reserve(__n);}\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n    bool __dereferenceable(const const_iterator* __i) const\n        {return __table_.__dereferenceable(&__i->__i_);}\n    bool __decrementable(const const_iterator* __i) const\n        {return __table_.__decrementable(&__i->__i_);}\n    bool __addable(const const_iterator* __i, ptrdiff_t __n) const\n        {return __table_.__addable(&__i->__i_, __n);}\n    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const\n        {return __table_.__addable(&__i->__i_, __n);}\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\nprivate:\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __node_holder __construct_node();\n    template <class _A0>\n        __node_holder\n         __construct_node(_A0&& __a0);\n    __node_holder __construct_node_with_key(key_type&& __k);\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class _A0, class _A1, class ..._Args>\n        __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __node_holder __construct_node_with_key(const key_type& __k);\n};\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(\n        size_type __n, const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(\n        size_type __n, const hasher& __hf, const key_equal& __eql,\n        const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(\n        const allocator_type& __a)\n    : __table_(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(\n        _InputIterator __first, _InputIterator __last)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    insert(__first, __last);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(\n        const unordered_map& __u)\n    : __table_(__u.__table_)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__u.bucket_count());\n    insert(__u.begin(), __u.end());\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(\n        const unordered_map& __u, const allocator_type& __a)\n    : __table_(__u.__table_, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__u.bucket_count());\n    insert(__u.begin(), __u.end());\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(\n        unordered_map&& __u)\n    _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)\n    : __table_(_VSTD::move(__u.__table_))\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n    __get_db()->swap(this, &__u);\n#endif\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(\n        unordered_map&& __u, const allocator_type& __a)\n    : __table_(_VSTD::move(__u.__table_), __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    if (__a != __u.get_allocator())\n    {\n        iterator __i = __u.begin();\n        while (__u.size() != 0)\n            __table_.__insert_unique(\n                _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_)\n                                    );\n    }\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    else\n        __get_db()->swap(this, &__u);\n#endif\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(\n        initializer_list<value_type> __il)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    insert(__il.begin(), __il.end());\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(\n        initializer_list<value_type> __il, size_type __n, const hasher& __hf,\n        const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__il.begin(), __il.end());\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(\n        initializer_list<value_type> __il, size_type __n, const hasher& __hf,\n        const key_equal& __eql, const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__il.begin(), __il.end());\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_map&& __u)\n    _NOEXCEPT_(is_nothrow_move_assignable<__table>::value)\n{\n    __table_ = _VSTD::move(__u.__table_);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(\n        initializer_list<value_type> __il)\n{\n    __table_.__assign_unique(__il.begin(), __il.end());\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntypename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node()\n{\n    __node_allocator& __na = __table_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_));\n    __h.get_deleter().__first_constructed = true;\n    __h.get_deleter().__second_constructed = true;\n    return __h;\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _A0>\ntypename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)\n{\n    __node_allocator& __na = __table_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_),\n                             _VSTD::forward<_A0>(__a0));\n    __h.get_deleter().__first_constructed = true;\n    __h.get_deleter().__second_constructed = true;\n    return __h;\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntypename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(key_type&& __k)\n{\n    __node_allocator& __na = __table_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), _VSTD::move(__k));\n    __h.get_deleter().__first_constructed = true;\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));\n    __h.get_deleter().__second_constructed = true;\n    return __h;\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _A0, class _A1, class ..._Args>\ntypename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0,\n                                                                 _A1&& __a1,\n                                                                 _Args&&... __args)\n{\n    __node_allocator& __na = __table_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_),\n                             _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1),\n                             _VSTD::forward<_Args>(__args)...);\n    __h.get_deleter().__first_constructed = true;\n    __h.get_deleter().__second_constructed = true;\n    return __h;\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class... _Args>\npair<typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator, bool>\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace(_Args&&... __args)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);\n    pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());\n    if (__r.second)\n        __h.release();\n    return __r;\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntypename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(const key_type& __k)\n{\n    __node_allocator& __na = __table_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), __k);\n    __h.get_deleter().__first_constructed = true;\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));\n    __h.get_deleter().__second_constructed = true;\n    return _VSTD::move(__h);  // explicitly moved for C++03\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,\n                                                       _InputIterator __last)\n{\n    for (; __first != __last; ++__first)\n        __table_.__insert_unique(*__first);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\n_Tp&\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)\n{\n    iterator __i = find(__k);\n    if (__i != end())\n        return __i->second;\n    __node_holder __h = __construct_node_with_key(__k);\n    pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());\n    __h.release();\n    return __r.first->second;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\n_Tp&\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](key_type&& __k)\n{\n    iterator __i = find(__k);\n    if (__i != end())\n        return __i->second;\n    __node_holder __h = __construct_node_with_key(_VSTD::move(__k));\n    pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());\n    __h.release();\n    return __r.first->second;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\n_Tp&\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::at(const key_type& __k)\n{\n    iterator __i = find(__k);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__i == end())\n        throw out_of_range(\"unordered_map::at: key not found\");\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __i->second;\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nconst _Tp&\nunordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::at(const key_type& __k) const\n{\n    const_iterator __i = find(__k);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__i == end())\n        throw out_of_range(\"unordered_map::at: key not found\");\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return __i->second;\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,\n     unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nbool\noperator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,\n           const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)\n{\n    if (__x.size() != __y.size())\n        return false;\n    typedef typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator\n                                                                 const_iterator;\n    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();\n            __i != __ex; ++__i)\n    {\n        const_iterator __j = __y.find(__i->first);\n        if (__j == __ey || !(*__i == *__j))\n            return false;\n    }\n    return true;\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,\n           const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,\n          class _Alloc = allocator<pair<const _Key, _Tp> > >\nclass _LIBCPP_TYPE_VIS_ONLY unordered_multimap\n{\npublic:\n    // types\n    typedef _Key                                           key_type;\n    typedef _Tp                                            mapped_type;\n    typedef _Hash                                          hasher;\n    typedef _Pred                                          key_equal;\n    typedef _Alloc                                         allocator_type;\n    typedef pair<const key_type, mapped_type>              value_type;\n    typedef pair<key_type, mapped_type>                    __nc_value_type;\n    typedef value_type&                                    reference;\n    typedef const value_type&                              const_reference;\n    static_assert((is_same<value_type, typename allocator_type::value_type>::value),\n                  \"Invalid allocator::value_type\");\n\nprivate:\n    typedef __hash_value_type<key_type, mapped_type>                 __value_type;\n    typedef __unordered_map_hasher<key_type, __value_type, hasher>   __hasher;\n    typedef __unordered_map_equal<key_type, __value_type, key_equal> __key_equal;\n    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,\n                                                 __value_type>::type __allocator_type;\n\n    typedef __hash_table<__value_type, __hasher,\n                         __key_equal,  __allocator_type>   __table;\n\n    __table __table_;\n\n    typedef typename __table::__node_traits                __node_traits;\n    typedef typename __table::__node_allocator             __node_allocator;\n    typedef typename __table::__node                       __node;\n    typedef __hash_map_node_destructor<__node_allocator>   _Dp;\n    typedef unique_ptr<__node, _Dp>                         __node_holder;\n    typedef allocator_traits<allocator_type>               __alloc_traits;\npublic:\n    typedef typename __alloc_traits::pointer         pointer;\n    typedef typename __alloc_traits::const_pointer   const_pointer;\n    typedef typename __alloc_traits::size_type       size_type;\n    typedef typename __alloc_traits::difference_type difference_type;\n\n    typedef __hash_map_iterator<typename __table::iterator>       iterator;\n    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;\n    typedef __hash_map_iterator<typename __table::local_iterator> local_iterator;\n    typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_multimap()\n        _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)\n        {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n            __get_db()->__insert_c(this);\n#endif\n        }\n    explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(),\n                                const key_equal& __eql = key_equal());\n    unordered_multimap(size_type __n, const hasher& __hf,\n                                const key_equal& __eql,\n                                const allocator_type& __a);\n    template <class _InputIterator>\n        unordered_multimap(_InputIterator __first, _InputIterator __last);\n    template <class _InputIterator>\n        unordered_multimap(_InputIterator __first, _InputIterator __last,\n                      size_type __n, const hasher& __hf = hasher(),\n                      const key_equal& __eql = key_equal());\n    template <class _InputIterator>\n        unordered_multimap(_InputIterator __first, _InputIterator __last,\n                      size_type __n, const hasher& __hf,\n                      const key_equal& __eql,\n                      const allocator_type& __a);\n    explicit unordered_multimap(const allocator_type& __a);\n    unordered_multimap(const unordered_multimap& __u);\n    unordered_multimap(const unordered_multimap& __u, const allocator_type& __a);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    unordered_multimap(unordered_multimap&& __u)\n        _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);\n    unordered_multimap(unordered_multimap&& __u, const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    unordered_multimap(initializer_list<value_type> __il);\n    unordered_multimap(initializer_list<value_type> __il, size_type __n,\n                       const hasher& __hf = hasher(),\n                       const key_equal& __eql = key_equal());\n    unordered_multimap(initializer_list<value_type> __il, size_type __n,\n                       const hasher& __hf, const key_equal& __eql,\n                       const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n#if _LIBCPP_STD_VER > 11\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_multimap(size_type __n, const allocator_type& __a)\n      : unordered_multimap(__n, hasher(), key_equal(), __a) {}\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_multimap(size_type __n, const hasher& __hf, const allocator_type& __a)\n      : unordered_multimap(__n, __hf, key_equal(), __a) {}\n    template <class _InputIterator>\n    _LIBCPP_INLINE_VISIBILITY\n      unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a)\n      : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) {}\n    template <class _InputIterator>\n    _LIBCPP_INLINE_VISIBILITY\n      unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, \n        const allocator_type& __a)\n      : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) {}\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_multimap(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)\n      : unordered_multimap(__il, __n, hasher(), key_equal(), __a) {}\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_multimap(initializer_list<value_type> __il, size_type __n, const hasher& __hf, \n      const allocator_type& __a)\n      : unordered_multimap(__il, __n, __hf, key_equal(), __a) {}\n#endif\n    // ~unordered_multimap() = default;\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_multimap& operator=(const unordered_multimap& __u)\n    {\n#if __cplusplus >= 201103L\n        __table_ = __u.__table_;\n#else\n        if (this != &__u) {\n            __table_.clear();\n            __table_.hash_function() = __u.__table_.hash_function();\n            __table_.key_eq() = __u.__table_.key_eq();\n            __table_.max_load_factor() = __u.__table_.max_load_factor();\n            __table_.__copy_assign_alloc(__u.__table_);\n            insert(__u.begin(), __u.end());\n        }\n#endif\n        return *this;\n    }\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    unordered_multimap& operator=(unordered_multimap&& __u)\n        _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);\n#endif\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    unordered_multimap& operator=(initializer_list<value_type> __il);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const _NOEXCEPT\n        {return allocator_type(__table_.__node_alloc());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool      empty() const _NOEXCEPT {return __table_.size() == 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const _NOEXCEPT  {return __table_.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const _NOEXCEPT {return __table_.max_size();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       begin() _NOEXCEPT        {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       end() _NOEXCEPT          {return __table_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin()  const _NOEXCEPT {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end()    const _NOEXCEPT {return __table_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cbegin() const _NOEXCEPT {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cend()   const _NOEXCEPT {return __table_.end();}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n    template <class... _Args>\n        iterator emplace(_Args&&... __args);\n\n    template <class... _Args>\n        iterator emplace_hint(const_iterator __p, _Args&&... __args);\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Pp,\n              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator insert(_Pp&& __x)\n            {return __table_.__insert_multi(_VSTD::forward<_Pp>(__x));}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator __p, const value_type& __x)\n        {return __table_.__insert_multi(__p.__i_, __x);}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _Pp,\n              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator insert(const_iterator __p, _Pp&& __x)\n            {return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _InputIterator>\n        void insert(_InputIterator __first, _InputIterator __last);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    void insert(initializer_list<value_type> __il)\n        {insert(__il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator erase(iterator __p)       {return __table_.erase(__p.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator erase(const_iterator __first, const_iterator __last)\n        {return __table_.erase(__first.__i_, __last.__i_);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() _NOEXCEPT {__table_.clear();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(unordered_multimap& __u)\n        _NOEXCEPT_(__is_nothrow_swappable<__table>::value)\n        {__table_.swap(__u.__table_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    hasher hash_function() const\n        {return __table_.hash_function().hash_function();}\n    _LIBCPP_INLINE_VISIBILITY\n    key_equal key_eq() const\n        {return __table_.key_eq().key_eq();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       find(const key_type& __k)       {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator find(const key_type& __k) const {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, iterator>             equal_range(const key_type& __k)\n        {return __table_.__equal_range_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const\n        {return __table_.__equal_range_multi(__k);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_bucket_count() const _NOEXCEPT\n        {return __table_.max_bucket_count();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket_size(size_type __n) const\n        {return __table_.bucket_size(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    local_iterator       begin(size_type __n)        {return __table_.begin(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    local_iterator       end(size_type __n)          {return __table_.end(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator begin(size_type __n) const  {return __table_.cbegin(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator end(size_type __n) const    {return __table_.cend(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator cend(size_type __n) const   {return __table_.cend(__n);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    float load_factor() const _NOEXCEPT {return __table_.load_factor();}\n    _LIBCPP_INLINE_VISIBILITY\n    float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();}\n    _LIBCPP_INLINE_VISIBILITY\n    void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}\n    _LIBCPP_INLINE_VISIBILITY\n    void rehash(size_type __n) {__table_.rehash(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    void reserve(size_type __n) {__table_.reserve(__n);}\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n    bool __dereferenceable(const const_iterator* __i) const\n        {return __table_.__dereferenceable(&__i->__i_);}\n    bool __decrementable(const const_iterator* __i) const\n        {return __table_.__decrementable(&__i->__i_);}\n    bool __addable(const const_iterator* __i, ptrdiff_t __n) const\n        {return __table_.__addable(&__i->__i_, __n);}\n    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const\n        {return __table_.__addable(&__i->__i_, __n);}\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\nprivate:\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __node_holder __construct_node();\n    template <class _A0>\n        __node_holder\n         __construct_node(_A0&& __a0);\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class _A0, class _A1, class ..._Args>\n        __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n};\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(\n        size_type __n, const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(\n        size_type __n, const hasher& __hf, const key_equal& __eql,\n        const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(\n        _InputIterator __first, _InputIterator __last)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    insert(__first, __last);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(\n        const allocator_type& __a)\n    : __table_(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(\n        const unordered_multimap& __u)\n    : __table_(__u.__table_)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__u.bucket_count());\n    insert(__u.begin(), __u.end());\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(\n        const unordered_multimap& __u, const allocator_type& __a)\n    : __table_(__u.__table_, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__u.bucket_count());\n    insert(__u.begin(), __u.end());\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(\n        unordered_multimap&& __u)\n    _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)\n    : __table_(_VSTD::move(__u.__table_))\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n    __get_db()->swap(this, &__u);\n#endif\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(\n        unordered_multimap&& __u, const allocator_type& __a)\n    : __table_(_VSTD::move(__u.__table_), __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    if (__a != __u.get_allocator())\n    {\n        iterator __i = __u.begin();\n        while (__u.size() != 0)\n        {\n            __table_.__insert_multi(\n                _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_)\n                                   );\n        }\n    }\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    else\n        __get_db()->swap(this, &__u);\n#endif\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(\n        initializer_list<value_type> __il)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    insert(__il.begin(), __il.end());\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(\n        initializer_list<value_type> __il, size_type __n, const hasher& __hf,\n        const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__il.begin(), __il.end());\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(\n        initializer_list<value_type> __il, size_type __n, const hasher& __hf,\n        const key_equal& __eql, const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__il.begin(), __il.end());\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_multimap&& __u)\n    _NOEXCEPT_(is_nothrow_move_assignable<__table>::value)\n{\n    __table_ = _VSTD::move(__u.__table_);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(\n        initializer_list<value_type> __il)\n{\n    __table_.__assign_multi(__il.begin(), __il.end());\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntypename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node()\n{\n    __node_allocator& __na = __table_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_));\n    __h.get_deleter().__first_constructed = true;\n    __h.get_deleter().__second_constructed = true;\n    return __h;\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _A0>\ntypename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)\n{\n    __node_allocator& __na = __table_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_),\n                             _VSTD::forward<_A0>(__a0));\n    __h.get_deleter().__first_constructed = true;\n    __h.get_deleter().__second_constructed = true;\n    return __h;\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _A0, class _A1, class ..._Args>\ntypename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(\n        _A0&& __a0, _A1&& __a1, _Args&&... __args)\n{\n    __node_allocator& __na = __table_.__node_alloc();\n    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));\n    __node_traits::construct(__na, _VSTD::addressof(__h->__value_),\n                             _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1),\n                             _VSTD::forward<_Args>(__args)...);\n    __h.get_deleter().__first_constructed = true;\n    __h.get_deleter().__second_constructed = true;\n    return __h;\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class... _Args>\ntypename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace(_Args&&... __args)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);\n    iterator __r = __table_.__node_insert_multi(__h.get());\n    __h.release();\n    return __r;\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class... _Args>\ntypename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace_hint(\n        const_iterator __p, _Args&&... __args)\n{\n    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);\n    iterator __r = __table_.__node_insert_multi(__p.__i_, __h.get());\n    __h.release();\n    return __r;\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nunordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,\n                                                            _InputIterator __last)\n{\n    for (; __first != __last; ++__first)\n        __table_.__insert_multi(*__first);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,\n     unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\nbool\noperator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,\n           const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)\n{\n    if (__x.size() != __y.size())\n        return false;\n    typedef typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator\n                                                                 const_iterator;\n    typedef pair<const_iterator, const_iterator> _EqRng;\n    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)\n    {\n        _EqRng __xeq = __x.equal_range(__i->first);\n        _EqRng __yeq = __y.equal_range(__i->first);\n        if (_VSTD::distance(__xeq.first, __xeq.second) !=\n            _VSTD::distance(__yeq.first, __yeq.second) ||\n                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))\n            return false;\n        __i = __xeq.second;\n    }\n    return true;\n}\n\ntemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,\n           const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)\n{\n    return !(__x == __y);\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_UNORDERED_MAP\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/unordered_set",
    "content": "// -*- C++ -*-\n//===-------------------------- unordered_set -----------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_UNORDERED_SET\n#define _LIBCPP_UNORDERED_SET\n\n/*\n\n    unordered_set synopsis\n\n#include <initializer_list>\n\nnamespace std\n{\n\ntemplate <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,\n          class Alloc = allocator<Value>>\nclass unordered_set\n{\npublic:\n    // types\n    typedef Value                                                      key_type;\n    typedef key_type                                                   value_type;\n    typedef Hash                                                       hasher;\n    typedef Pred                                                       key_equal;\n    typedef Alloc                                                      allocator_type;\n    typedef value_type&                                                reference;\n    typedef const value_type&                                          const_reference;\n    typedef typename allocator_traits<allocator_type>::pointer         pointer;\n    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;\n    typedef typename allocator_traits<allocator_type>::size_type       size_type;\n    typedef typename allocator_traits<allocator_type>::difference_type difference_type;\n\n    typedef /unspecified/ iterator;\n    typedef /unspecified/ const_iterator;\n    typedef /unspecified/ local_iterator;\n    typedef /unspecified/ const_local_iterator;\n\n    unordered_set()\n        noexcept(\n            is_nothrow_default_constructible<hasher>::value &&\n            is_nothrow_default_constructible<key_equal>::value &&\n            is_nothrow_default_constructible<allocator_type>::value);\n    explicit unordered_set(size_type n, const hasher& hf = hasher(),\n                           const key_equal& eql = key_equal(),\n                           const allocator_type& a = allocator_type());\n    template <class InputIterator>\n        unordered_set(InputIterator f, InputIterator l,\n                      size_type n = 0, const hasher& hf = hasher(),\n                      const key_equal& eql = key_equal(),\n                      const allocator_type& a = allocator_type());\n    explicit unordered_set(const allocator_type&);\n    unordered_set(const unordered_set&);\n    unordered_set(const unordered_set&, const Allocator&);\n    unordered_set(unordered_set&&)\n        noexcept(\n            is_nothrow_move_constructible<hasher>::value &&\n            is_nothrow_move_constructible<key_equal>::value &&\n            is_nothrow_move_constructible<allocator_type>::value);\n    unordered_set(unordered_set&&, const Allocator&);\n    unordered_set(initializer_list<value_type>, size_type n = 0,\n                  const hasher& hf = hasher(), const key_equal& eql = key_equal(),\n                  const allocator_type& a = allocator_type());\n    unordered_set(size_type n, const allocator_type& a); // C++14\n    unordered_set(size_type n, const hasher& hf, const allocator_type& a); // C++14\n    template <class InputIterator>\n      unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); // C++14\n    template <class InputIterator>\n      unordered_set(InputIterator f, InputIterator l, size_type n, \n                    const hasher& hf,  const allocator_type& a); // C++14\n    unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14\n    unordered_set(initializer_list<value_type> il, size_type n,\n                  const hasher& hf,  const allocator_type& a); // C++14\n    ~unordered_set();\n    unordered_set& operator=(const unordered_set&);\n    unordered_set& operator=(unordered_set&&)\n        noexcept(\n            allocator_type::propagate_on_container_move_assignment::value &&\n            is_nothrow_move_assignable<allocator_type>::value &&\n            is_nothrow_move_assignable<hasher>::value &&\n            is_nothrow_move_assignable<key_equal>::value);\n    unordered_set& operator=(initializer_list<value_type>);\n\n    allocator_type get_allocator() const noexcept;\n\n    bool      empty() const noexcept;\n    size_type size() const noexcept;\n    size_type max_size() const noexcept;\n\n    iterator       begin() noexcept;\n    iterator       end() noexcept;\n    const_iterator begin()  const noexcept;\n    const_iterator end()    const noexcept;\n    const_iterator cbegin() const noexcept;\n    const_iterator cend()   const noexcept;\n\n    template <class... Args>\n        pair<iterator, bool> emplace(Args&&... args);\n    template <class... Args>\n        iterator emplace_hint(const_iterator position, Args&&... args);\n    pair<iterator, bool> insert(const value_type& obj);\n    pair<iterator, bool> insert(value_type&& obj);\n    iterator insert(const_iterator hint, const value_type& obj);\n    iterator insert(const_iterator hint, value_type&& obj);\n    template <class InputIterator>\n        void insert(InputIterator first, InputIterator last);\n    void insert(initializer_list<value_type>);\n\n    iterator erase(const_iterator position);\n    iterator erase(iterator position);  // C++14\n    size_type erase(const key_type& k);\n    iterator erase(const_iterator first, const_iterator last);\n    void clear() noexcept;\n\n    void swap(unordered_set&)\n       noexcept(allocator_traits<Allocator>::is_always_equal::value &&\n                 noexcept(swap(declval<hasher&>(), declval<hasher&>())) &&\n                 noexcept(swap(declval<key_equal&>(), declval<key_equal&>()))); // C++17\n\n    hasher hash_function() const;\n    key_equal key_eq() const;\n\n    iterator       find(const key_type& k);\n    const_iterator find(const key_type& k) const;\n    size_type count(const key_type& k) const;\n    pair<iterator, iterator>             equal_range(const key_type& k);\n    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;\n\n    size_type bucket_count() const noexcept;\n    size_type max_bucket_count() const noexcept;\n\n    size_type bucket_size(size_type n) const;\n    size_type bucket(const key_type& k) const;\n\n    local_iterator       begin(size_type n);\n    local_iterator       end(size_type n);\n    const_local_iterator begin(size_type n) const;\n    const_local_iterator end(size_type n) const;\n    const_local_iterator cbegin(size_type n) const;\n    const_local_iterator cend(size_type n) const;\n\n    float load_factor() const noexcept;\n    float max_load_factor() const noexcept;\n    void max_load_factor(float z);\n    void rehash(size_type n);\n    void reserve(size_type n);\n};\n\ntemplate <class Value, class Hash, class Pred, class Alloc>\n    void swap(unordered_set<Value, Hash, Pred, Alloc>& x,\n              unordered_set<Value, Hash, Pred, Alloc>& y)\n              noexcept(noexcept(x.swap(y)));\n\ntemplate <class Value, class Hash, class Pred, class Alloc>\n    bool\n    operator==(const unordered_set<Value, Hash, Pred, Alloc>& x,\n               const unordered_set<Value, Hash, Pred, Alloc>& y);\n\ntemplate <class Value, class Hash, class Pred, class Alloc>\n    bool\n    operator!=(const unordered_set<Value, Hash, Pred, Alloc>& x,\n               const unordered_set<Value, Hash, Pred, Alloc>& y);\n\ntemplate <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,\n          class Alloc = allocator<Value>>\nclass unordered_multiset\n{\npublic:\n    // types\n    typedef Value                                                      key_type;\n    typedef key_type                                                   value_type;\n    typedef Hash                                                       hasher;\n    typedef Pred                                                       key_equal;\n    typedef Alloc                                                      allocator_type;\n    typedef value_type&                                                reference;\n    typedef const value_type&                                          const_reference;\n    typedef typename allocator_traits<allocator_type>::pointer         pointer;\n    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;\n    typedef typename allocator_traits<allocator_type>::size_type       size_type;\n    typedef typename allocator_traits<allocator_type>::difference_type difference_type;\n\n    typedef /unspecified/ iterator;\n    typedef /unspecified/ const_iterator;\n    typedef /unspecified/ local_iterator;\n    typedef /unspecified/ const_local_iterator;\n\n    unordered_multiset()\n        noexcept(\n            is_nothrow_default_constructible<hasher>::value &&\n            is_nothrow_default_constructible<key_equal>::value &&\n            is_nothrow_default_constructible<allocator_type>::value);\n    explicit unordered_multiset(size_type n, const hasher& hf = hasher(),\n                           const key_equal& eql = key_equal(),\n                           const allocator_type& a = allocator_type());\n    template <class InputIterator>\n        unordered_multiset(InputIterator f, InputIterator l,\n                      size_type n = 0, const hasher& hf = hasher(),\n                      const key_equal& eql = key_equal(),\n                      const allocator_type& a = allocator_type());\n    explicit unordered_multiset(const allocator_type&);\n    unordered_multiset(const unordered_multiset&);\n    unordered_multiset(const unordered_multiset&, const Allocator&);\n    unordered_multiset(unordered_multiset&&)\n        noexcept(\n            is_nothrow_move_constructible<hasher>::value &&\n            is_nothrow_move_constructible<key_equal>::value &&\n            is_nothrow_move_constructible<allocator_type>::value);\n    unordered_multiset(unordered_multiset&&, const Allocator&);\n    unordered_multiset(initializer_list<value_type>, size_type n = /see below/,\n                  const hasher& hf = hasher(), const key_equal& eql = key_equal(),\n                  const allocator_type& a = allocator_type());\n    unordered_multiset(size_type n, const allocator_type& a); // C++14\n    unordered_multiset(size_type n, const hasher& hf, const allocator_type& a); // C++14\n    template <class InputIterator>\n      unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a); // C++14\n    template <class InputIterator>\n      unordered_multiset(InputIterator f, InputIterator l, size_type n,\n                         const hasher& hf, const allocator_type& a); // C++14\n    unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14\n    unordered_multiset(initializer_list<value_type> il, size_type n, \n                       const hasher& hf,  const allocator_type& a); // C++14\n    ~unordered_multiset();\n    unordered_multiset& operator=(const unordered_multiset&);\n    unordered_multiset& operator=(unordered_multiset&&)\n        noexcept(\n            allocator_type::propagate_on_container_move_assignment::value &&\n            is_nothrow_move_assignable<allocator_type>::value &&\n            is_nothrow_move_assignable<hasher>::value &&\n            is_nothrow_move_assignable<key_equal>::value);\n    unordered_multiset& operator=(initializer_list<value_type>);\n\n    allocator_type get_allocator() const noexcept;\n\n    bool      empty() const noexcept;\n    size_type size() const noexcept;\n    size_type max_size() const noexcept;\n\n    iterator       begin() noexcept;\n    iterator       end() noexcept;\n    const_iterator begin()  const noexcept;\n    const_iterator end()    const noexcept;\n    const_iterator cbegin() const noexcept;\n    const_iterator cend()   const noexcept;\n\n    template <class... Args>\n        iterator emplace(Args&&... args);\n    template <class... Args>\n        iterator emplace_hint(const_iterator position, Args&&... args);\n    iterator insert(const value_type& obj);\n    iterator insert(value_type&& obj);\n    iterator insert(const_iterator hint, const value_type& obj);\n    iterator insert(const_iterator hint, value_type&& obj);\n    template <class InputIterator>\n        void insert(InputIterator first, InputIterator last);\n    void insert(initializer_list<value_type>);\n\n    iterator erase(const_iterator position);\n    iterator erase(iterator position);  // C++14\n    size_type erase(const key_type& k);\n    iterator erase(const_iterator first, const_iterator last);\n    void clear() noexcept;\n\n    void swap(unordered_multiset&)\n       noexcept(allocator_traits<Allocator>::is_always_equal::value &&\n                 noexcept(swap(declval<hasher&>(), declval<hasher&>())) &&\n                 noexcept(swap(declval<key_equal&>(), declval<key_equal&>()))); // C++17\n\n    hasher hash_function() const;\n    key_equal key_eq() const;\n\n    iterator       find(const key_type& k);\n    const_iterator find(const key_type& k) const;\n    size_type count(const key_type& k) const;\n    pair<iterator, iterator>             equal_range(const key_type& k);\n    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;\n\n    size_type bucket_count() const noexcept;\n    size_type max_bucket_count() const noexcept;\n\n    size_type bucket_size(size_type n) const;\n    size_type bucket(const key_type& k) const;\n\n    local_iterator       begin(size_type n);\n    local_iterator       end(size_type n);\n    const_local_iterator begin(size_type n) const;\n    const_local_iterator end(size_type n) const;\n    const_local_iterator cbegin(size_type n) const;\n    const_local_iterator cend(size_type n) const;\n\n    float load_factor() const noexcept;\n    float max_load_factor() const noexcept;\n    void max_load_factor(float z);\n    void rehash(size_type n);\n    void reserve(size_type n);\n};\n\ntemplate <class Value, class Hash, class Pred, class Alloc>\n    void swap(unordered_multiset<Value, Hash, Pred, Alloc>& x,\n              unordered_multiset<Value, Hash, Pred, Alloc>& y)\n              noexcept(noexcept(x.swap(y)));\n\ntemplate <class Value, class Hash, class Pred, class Alloc>\n    bool\n    operator==(const unordered_multiset<Value, Hash, Pred, Alloc>& x,\n               const unordered_multiset<Value, Hash, Pred, Alloc>& y);\n\ntemplate <class Value, class Hash, class Pred, class Alloc>\n    bool\n    operator!=(const unordered_multiset<Value, Hash, Pred, Alloc>& x,\n               const unordered_multiset<Value, Hash, Pred, Alloc>& y);\n}  // std\n\n*/\n\n#include <__config>\n#include <__hash_table>\n#include <functional>\n\n#include <__debug>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,\n          class _Alloc = allocator<_Value> >\nclass _LIBCPP_TYPE_VIS_ONLY unordered_set\n{\npublic:\n    // types\n    typedef _Value                                                     key_type;\n    typedef key_type                                                   value_type;\n    typedef _Hash                                                      hasher;\n    typedef _Pred                                                      key_equal;\n    typedef _Alloc                                                     allocator_type;\n    typedef value_type&                                                reference;\n    typedef const value_type&                                          const_reference;\n    static_assert((is_same<value_type, typename allocator_type::value_type>::value),\n                  \"Invalid allocator::value_type\");\n\nprivate:\n    typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;\n\n    __table __table_;\n\npublic:\n    typedef typename __table::pointer         pointer;\n    typedef typename __table::const_pointer   const_pointer;\n    typedef typename __table::size_type       size_type;\n    typedef typename __table::difference_type difference_type;\n\n    typedef typename __table::const_iterator       iterator;\n    typedef typename __table::const_iterator       const_iterator;\n    typedef typename __table::const_local_iterator local_iterator;\n    typedef typename __table::const_local_iterator const_local_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_set()\n        _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)\n        {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n            __get_db()->__insert_c(this);\n#endif\n        }\n    explicit unordered_set(size_type __n, const hasher& __hf = hasher(),\n                           const key_equal& __eql = key_equal());\n#if _LIBCPP_STD_VER > 11\n    inline _LIBCPP_INLINE_VISIBILITY\n    unordered_set(size_type __n, const allocator_type& __a)\n        : unordered_set(__n, hasher(), key_equal(), __a) {}\n    inline _LIBCPP_INLINE_VISIBILITY\n    unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a)\n        : unordered_set(__n, __hf, key_equal(), __a) {}\n#endif\n    unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql,\n                  const allocator_type& __a);\n    template <class _InputIterator>\n        unordered_set(_InputIterator __first, _InputIterator __last);\n    template <class _InputIterator>\n        unordered_set(_InputIterator __first, _InputIterator __last,\n                      size_type __n, const hasher& __hf = hasher(),\n                      const key_equal& __eql = key_equal());\n    template <class _InputIterator>\n        unordered_set(_InputIterator __first, _InputIterator __last,\n                      size_type __n, const hasher& __hf, const key_equal& __eql,\n                      const allocator_type& __a);\n#if _LIBCPP_STD_VER > 11\n    template <class _InputIterator>\n    inline _LIBCPP_INLINE_VISIBILITY\n        unordered_set(_InputIterator __first, _InputIterator __last, \n                    size_type __n, const allocator_type& __a)\n            : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) {}\n    template <class _InputIterator>\n        unordered_set(_InputIterator __first, _InputIterator __last, \n                      size_type __n, const hasher& __hf, const allocator_type& __a)\n            : unordered_set(__first, __last, __n, __hf, key_equal(), __a) {}\n#endif\n    explicit unordered_set(const allocator_type& __a);\n    unordered_set(const unordered_set& __u);\n    unordered_set(const unordered_set& __u, const allocator_type& __a);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    unordered_set(unordered_set&& __u)\n        _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);\n    unordered_set(unordered_set&& __u, const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    unordered_set(initializer_list<value_type> __il);\n    unordered_set(initializer_list<value_type> __il, size_type __n,\n                  const hasher& __hf = hasher(),\n                  const key_equal& __eql = key_equal());\n    unordered_set(initializer_list<value_type> __il, size_type __n,\n                  const hasher& __hf, const key_equal& __eql,\n                  const allocator_type& __a);\n#if _LIBCPP_STD_VER > 11\n    inline _LIBCPP_INLINE_VISIBILITY\n    unordered_set(initializer_list<value_type> __il, size_type __n,\n                                                      const allocator_type& __a)\n        : unordered_set(__il, __n, hasher(), key_equal(), __a) {}\n    inline _LIBCPP_INLINE_VISIBILITY\n    unordered_set(initializer_list<value_type> __il, size_type __n, \n                                  const hasher& __hf, const allocator_type& __a)\n        : unordered_set(__il, __n, __hf, key_equal(), __a) {}\n#endif\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    // ~unordered_set() = default;\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_set& operator=(const unordered_set& __u)\n    {\n        __table_ = __u.__table_;\n        return *this;\n    }\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    unordered_set& operator=(unordered_set&& __u)\n        _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);\n#endif\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    unordered_set& operator=(initializer_list<value_type> __il);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const _NOEXCEPT\n        {return allocator_type(__table_.__node_alloc());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool      empty() const _NOEXCEPT {return __table_.size() == 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const _NOEXCEPT  {return __table_.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const _NOEXCEPT {return __table_.max_size();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       begin() _NOEXCEPT        {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       end() _NOEXCEPT          {return __table_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin()  const _NOEXCEPT {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end()    const _NOEXCEPT {return __table_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cbegin() const _NOEXCEPT {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cend()   const _NOEXCEPT {return __table_.end();}\n\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        pair<iterator, bool> emplace(_Args&&... __args)\n            {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...);}\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        iterator emplace_hint(const_iterator __p, _Args&&... __args)\n        {\n            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n                \"unordered_set::emplace_hint(const_iterator, args...) called with an iterator not\"\n                \" referring to this unordered_set\");\n            return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;\n        }\n#else\n        iterator emplace_hint(const_iterator, _Args&&... __args)\n            {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;}\n#endif\n#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, bool> insert(const value_type& __x)\n        {return __table_.__insert_unique(__x);}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, bool> insert(value_type&& __x)\n        {return __table_.__insert_unique(_VSTD::move(__x));}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    iterator insert(const_iterator __p, const value_type& __x)\n        {\n            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n                \"unordered_set::insert(const_iterator, const value_type&) called with an iterator not\"\n                \" referring to this unordered_set\");\n            return insert(__x).first;\n        }\n#else\n    iterator insert(const_iterator, const value_type& __x)\n        {return insert(__x).first;}\n#endif\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    iterator insert(const_iterator __p, value_type&& __x)\n        {\n            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,\n                \"unordered_set::insert(const_iterator, value_type&&) called with an iterator not\"\n                \" referring to this unordered_set\");\n            return insert(_VSTD::move(__x)).first;\n        }\n#else\n    iterator insert(const_iterator, value_type&& __x)\n        {return insert(_VSTD::move(__x)).first;}\n#endif\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _InputIterator>\n        void insert(_InputIterator __first, _InputIterator __last);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    void insert(initializer_list<value_type> __il)\n        {insert(__il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator erase(const_iterator __p) {return __table_.erase(__p);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator erase(const_iterator __first, const_iterator __last)\n        {return __table_.erase(__first, __last);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() _NOEXCEPT {__table_.clear();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(unordered_set& __u)\n        _NOEXCEPT_(__is_nothrow_swappable<__table>::value)\n        {__table_.swap(__u.__table_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    hasher hash_function() const {return __table_.hash_function();}\n    _LIBCPP_INLINE_VISIBILITY\n    key_equal key_eq() const {return __table_.key_eq();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       find(const key_type& __k)       {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator find(const key_type& __k) const {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, iterator>             equal_range(const key_type& __k)\n        {return __table_.__equal_range_unique(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const\n        {return __table_.__equal_range_unique(__k);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket_size(size_type __n) const {return __table_.bucket_size(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    local_iterator       begin(size_type __n)        {return __table_.begin(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    local_iterator       end(size_type __n)          {return __table_.end(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator begin(size_type __n) const  {return __table_.cbegin(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator end(size_type __n) const    {return __table_.cend(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator cend(size_type __n) const   {return __table_.cend(__n);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    float load_factor() const _NOEXCEPT {return __table_.load_factor();}\n    _LIBCPP_INLINE_VISIBILITY\n    float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();}\n    _LIBCPP_INLINE_VISIBILITY\n    void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}\n    _LIBCPP_INLINE_VISIBILITY\n    void rehash(size_type __n) {__table_.rehash(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    void reserve(size_type __n) {__table_.reserve(__n);}\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n    bool __dereferenceable(const const_iterator* __i) const\n        {return __table_.__dereferenceable(__i);}\n    bool __decrementable(const const_iterator* __i) const\n        {return __table_.__decrementable(__i);}\n    bool __addable(const const_iterator* __i, ptrdiff_t __n) const\n        {return __table_.__addable(__i, __n);}\n    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const\n        {return __table_.__addable(__i, __n);}\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\n};\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,\n        const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,\n        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nunordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(\n        _InputIterator __first, _InputIterator __last)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    insert(__first, __last);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nunordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nunordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(\n        const allocator_type& __a)\n    : __table_(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(\n        const unordered_set& __u)\n    : __table_(__u.__table_)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__u.bucket_count());\n    insert(__u.begin(), __u.end());\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(\n        const unordered_set& __u, const allocator_type& __a)\n    : __table_(__u.__table_, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__u.bucket_count());\n    insert(__u.begin(), __u.end());\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(\n        unordered_set&& __u)\n    _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)\n    : __table_(_VSTD::move(__u.__table_))\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n    __get_db()->swap(this, &__u);\n#endif\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(\n        unordered_set&& __u, const allocator_type& __a)\n    : __table_(_VSTD::move(__u.__table_), __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    if (__a != __u.get_allocator())\n    {\n        iterator __i = __u.begin();\n        while (__u.size() != 0)\n            __table_.__insert_unique(_VSTD::move(__u.__table_.remove(__i++)->__value_));\n    }\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    else\n        __get_db()->swap(this, &__u);\n#endif\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(\n        initializer_list<value_type> __il)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    insert(__il.begin(), __il.end());\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(\n        initializer_list<value_type> __il, size_type __n, const hasher& __hf,\n        const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__il.begin(), __il.end());\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(\n        initializer_list<value_type> __il, size_type __n, const hasher& __hf,\n        const key_equal& __eql, const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__il.begin(), __il.end());\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_set<_Value, _Hash, _Pred, _Alloc>&\nunordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(unordered_set&& __u)\n    _NOEXCEPT_(is_nothrow_move_assignable<__table>::value)\n{\n    __table_ = _VSTD::move(__u.__table_);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_set<_Value, _Hash, _Pred, _Alloc>&\nunordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(\n        initializer_list<value_type> __il)\n{\n    __table_.__assign_unique(__il.begin(), __il.end());\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nunordered_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,\n                                                    _InputIterator __last)\n{\n    for (; __first != __last; ++__first)\n        __table_.__insert_unique(*__first);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,\n     unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nbool\noperator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,\n           const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)\n{\n    if (__x.size() != __y.size())\n        return false;\n    typedef typename unordered_set<_Value, _Hash, _Pred, _Alloc>::const_iterator\n                                                                 const_iterator;\n    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();\n            __i != __ex; ++__i)\n    {\n        const_iterator __j = __y.find(*__i);\n        if (__j == __ey || !(*__i == *__j))\n            return false;\n    }\n    return true;\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,\n           const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,\n          class _Alloc = allocator<_Value> >\nclass _LIBCPP_TYPE_VIS_ONLY unordered_multiset\n{\npublic:\n    // types\n    typedef _Value                                                     key_type;\n    typedef key_type                                                   value_type;\n    typedef _Hash                                                      hasher;\n    typedef _Pred                                                      key_equal;\n    typedef _Alloc                                                     allocator_type;\n    typedef value_type&                                                reference;\n    typedef const value_type&                                          const_reference;\n    static_assert((is_same<value_type, typename allocator_type::value_type>::value),\n                  \"Invalid allocator::value_type\");\n\nprivate:\n    typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;\n\n    __table __table_;\n\npublic:\n    typedef typename __table::pointer         pointer;\n    typedef typename __table::const_pointer   const_pointer;\n    typedef typename __table::size_type       size_type;\n    typedef typename __table::difference_type difference_type;\n\n    typedef typename __table::const_iterator       iterator;\n    typedef typename __table::const_iterator       const_iterator;\n    typedef typename __table::const_local_iterator local_iterator;\n    typedef typename __table::const_local_iterator const_local_iterator;\n\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_multiset()\n        _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)\n        {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n            __get_db()->__insert_c(this);\n#endif\n        }\n    explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(),\n                                const key_equal& __eql = key_equal());\n    unordered_multiset(size_type __n, const hasher& __hf,\n                       const key_equal& __eql, const allocator_type& __a);\n#if _LIBCPP_STD_VER > 11\n    inline _LIBCPP_INLINE_VISIBILITY\n    unordered_multiset(size_type __n, const allocator_type& __a)\n        : unordered_multiset(__n, hasher(), key_equal(), __a) {}\n    inline _LIBCPP_INLINE_VISIBILITY\n    unordered_multiset(size_type __n, const hasher& __hf, const allocator_type& __a)\n        : unordered_multiset(__n, __hf, key_equal(), __a) {}\n#endif\n    template <class _InputIterator>\n        unordered_multiset(_InputIterator __first, _InputIterator __last);\n    template <class _InputIterator>\n        unordered_multiset(_InputIterator __first, _InputIterator __last,\n                      size_type __n, const hasher& __hf = hasher(),\n                      const key_equal& __eql = key_equal());\n    template <class _InputIterator>\n        unordered_multiset(_InputIterator __first, _InputIterator __last,\n                      size_type __n , const hasher& __hf,\n                      const key_equal& __eql, const allocator_type& __a);\n#if _LIBCPP_STD_VER > 11\n    template <class _InputIterator>\n    inline _LIBCPP_INLINE_VISIBILITY\n    unordered_multiset(_InputIterator __first, _InputIterator __last, \n                       size_type __n, const allocator_type& __a)\n        : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) {}\n    template <class _InputIterator>\n    inline _LIBCPP_INLINE_VISIBILITY\n    unordered_multiset(_InputIterator __first, _InputIterator __last,\n                       size_type __n, const hasher& __hf, const allocator_type& __a)\n        : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) {}\n#endif\n    explicit unordered_multiset(const allocator_type& __a);\n    unordered_multiset(const unordered_multiset& __u);\n    unordered_multiset(const unordered_multiset& __u, const allocator_type& __a);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    unordered_multiset(unordered_multiset&& __u)\n        _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);\n    unordered_multiset(unordered_multiset&& __u, const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    unordered_multiset(initializer_list<value_type> __il);\n    unordered_multiset(initializer_list<value_type> __il, size_type __n,\n                       const hasher& __hf = hasher(),\n                       const key_equal& __eql = key_equal());\n    unordered_multiset(initializer_list<value_type> __il, size_type __n,\n                       const hasher& __hf, const key_equal& __eql,\n                       const allocator_type& __a);\n#if _LIBCPP_STD_VER > 11\n    inline _LIBCPP_INLINE_VISIBILITY\n    unordered_multiset(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)\n      : unordered_multiset(__il, __n, hasher(), key_equal(), __a) {}\n    inline _LIBCPP_INLINE_VISIBILITY\n    unordered_multiset(initializer_list<value_type> __il, size_type __n, const hasher& __hf, const allocator_type& __a)\n      : unordered_multiset(__il, __n, __hf, key_equal(), __a) {}\n#endif\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    // ~unordered_multiset() = default;\n    _LIBCPP_INLINE_VISIBILITY\n    unordered_multiset& operator=(const unordered_multiset& __u)\n    {\n        __table_ = __u.__table_;\n        return *this;\n    }\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    unordered_multiset& operator=(unordered_multiset&& __u)\n        _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);\n#endif\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    unordered_multiset& operator=(initializer_list<value_type> __il);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const _NOEXCEPT\n        {return allocator_type(__table_.__node_alloc());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    bool      empty() const _NOEXCEPT {return __table_.size() == 0;}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const _NOEXCEPT  {return __table_.size();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_size() const _NOEXCEPT {return __table_.max_size();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       begin() _NOEXCEPT        {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       end() _NOEXCEPT          {return __table_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin()  const _NOEXCEPT {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end()    const _NOEXCEPT {return __table_.end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cbegin() const _NOEXCEPT {return __table_.begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator cend()   const _NOEXCEPT {return __table_.end();}\n\n#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator emplace(_Args&&... __args)\n            {return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...);}\n    template <class... _Args>\n        _LIBCPP_INLINE_VISIBILITY\n        iterator emplace_hint(const_iterator __p, _Args&&... __args)\n            {return __table_.__emplace_hint_multi(__p, _VSTD::forward<_Args>(__args)...);}\n#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(value_type&& __x) {return __table_.__insert_multi(_VSTD::move(__x));}\n#endif\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator __p, const value_type& __x)\n        {return __table_.__insert_multi(__p, __x);}\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator __p, value_type&& __x)\n        {return __table_.__insert_multi(__p, _VSTD::move(__x));}\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    template <class _InputIterator>\n        void insert(_InputIterator __first, _InputIterator __last);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    void insert(initializer_list<value_type> __il)\n        {insert(__il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator erase(const_iterator __p) {return __table_.erase(__p);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator erase(const_iterator __first, const_iterator __last)\n        {return __table_.erase(__first, __last);}\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() _NOEXCEPT {__table_.clear();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void swap(unordered_multiset& __u)\n        _NOEXCEPT_(__is_nothrow_swappable<__table>::value)\n        {__table_.swap(__u.__table_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    hasher hash_function() const {return __table_.hash_function();}\n    _LIBCPP_INLINE_VISIBILITY\n    key_equal key_eq() const {return __table_.key_eq();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       find(const key_type& __k)       {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator find(const key_type& __k) const {return __table_.find(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<iterator, iterator>             equal_range(const key_type& __k)\n        {return __table_.__equal_range_multi(__k);}\n    _LIBCPP_INLINE_VISIBILITY\n    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const\n        {return __table_.__equal_range_multi(__k);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket_size(size_type __n) const {return __table_.bucket_size(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    local_iterator       begin(size_type __n)        {return __table_.begin(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    local_iterator       end(size_type __n)          {return __table_.end(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator begin(size_type __n) const  {return __table_.cbegin(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator end(size_type __n) const    {return __table_.cend(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_local_iterator cend(size_type __n) const   {return __table_.cend(__n);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    float load_factor() const _NOEXCEPT {return __table_.load_factor();}\n    _LIBCPP_INLINE_VISIBILITY\n    float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();}\n    _LIBCPP_INLINE_VISIBILITY\n    void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}\n    _LIBCPP_INLINE_VISIBILITY\n    void rehash(size_type __n) {__table_.rehash(__n);}\n    _LIBCPP_INLINE_VISIBILITY\n    void reserve(size_type __n) {__table_.reserve(__n);}\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n    bool __dereferenceable(const const_iterator* __i) const\n        {return __table_.__dereferenceable(__i);}\n    bool __decrementable(const const_iterator* __i) const\n        {return __table_.__decrementable(__i);}\n    bool __addable(const const_iterator* __i, ptrdiff_t __n) const\n        {return __table_.__addable(__i, __n);}\n    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const\n        {return __table_.__addable(__i, __n);}\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\n};\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(\n        size_type __n, const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(\n        size_type __n, const hasher& __hf, const key_equal& __eql,\n        const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(\n        _InputIterator __first, _InputIterator __last)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    insert(__first, __last);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(\n        _InputIterator __first, _InputIterator __last, size_type __n,\n        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__first, __last);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(\n        const allocator_type& __a)\n    : __table_(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(\n        const unordered_multiset& __u)\n    : __table_(__u.__table_)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__u.bucket_count());\n    insert(__u.begin(), __u.end());\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(\n        const unordered_multiset& __u, const allocator_type& __a)\n    : __table_(__u.__table_, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__u.bucket_count());\n    insert(__u.begin(), __u.end());\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(\n        unordered_multiset&& __u)\n    _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)\n    : __table_(_VSTD::move(__u.__table_))\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n    __get_db()->swap(this, &__u);\n#endif\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(\n        unordered_multiset&& __u, const allocator_type& __a)\n    : __table_(_VSTD::move(__u.__table_), __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    if (__a != __u.get_allocator())\n    {\n        iterator __i = __u.begin();\n        while (__u.size() != 0)\n            __table_.__insert_multi(_VSTD::move(__u.__table_.remove(__i++)->__value_));\n    }\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    else\n        __get_db()->swap(this, &__u);\n#endif\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(\n        initializer_list<value_type> __il)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    insert(__il.begin(), __il.end());\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(\n        initializer_list<value_type> __il, size_type __n, const hasher& __hf,\n        const key_equal& __eql)\n    : __table_(__hf, __eql)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__il.begin(), __il.end());\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(\n        initializer_list<value_type> __il, size_type __n, const hasher& __hf,\n        const key_equal& __eql, const allocator_type& __a)\n    : __table_(__hf, __eql, __a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    __table_.rehash(__n);\n    insert(__il.begin(), __il.end());\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>&\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=(\n        unordered_multiset&& __u)\n    _NOEXCEPT_(is_nothrow_move_assignable<__table>::value)\n{\n    __table_ = _VSTD::move(__u.__table_);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>&\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=(\n        initializer_list<value_type> __il)\n{\n    __table_.__assign_multi(__il.begin(), __il.end());\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ntemplate <class _InputIterator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nunordered_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,\n                                                         _InputIterator __last)\n{\n    for (; __first != __last; ++__first)\n        __table_.__insert_multi(*__first);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,\n     unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\nbool\noperator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,\n           const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)\n{\n    if (__x.size() != __y.size())\n        return false;\n    typedef typename unordered_multiset<_Value, _Hash, _Pred, _Alloc>::const_iterator\n                                                                 const_iterator;\n    typedef pair<const_iterator, const_iterator> _EqRng;\n    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)\n    {\n        _EqRng __xeq = __x.equal_range(*__i);\n        _EqRng __yeq = __y.equal_range(*__i);\n        if (_VSTD::distance(__xeq.first, __xeq.second) !=\n            _VSTD::distance(__yeq.first, __yeq.second) ||\n                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))\n            return false;\n        __i = __xeq.second;\n    }\n    return true;\n}\n\ntemplate <class _Value, class _Hash, class _Pred, class _Alloc>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,\n           const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)\n{\n    return !(__x == __y);\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_UNORDERED_SET\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/utility",
    "content": "// -*- C++ -*-\n//===-------------------------- utility -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_UTILITY\n#define _LIBCPP_UTILITY\n\n/*\n    utility synopsis\n\nnamespace std\n{\n\ntemplate <class T>\n    void\n    swap(T& a, T& b);\n\nnamespace rel_ops\n{\n    template<class T> bool operator!=(const T&, const T&);\n    template<class T> bool operator> (const T&, const T&);\n    template<class T> bool operator<=(const T&, const T&);\n    template<class T> bool operator>=(const T&, const T&);\n}\n\ntemplate<class T>\nvoid\nswap(T& a, T& b) noexcept(is_nothrow_move_constructible<T>::value &&\n                          is_nothrow_move_assignable<T>::value);\n\ntemplate <class T, size_t N>\nvoid\nswap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b)));\n\ntemplate <class T> T&& forward(typename remove_reference<T>::type& t) noexcept;  // constexpr in C++14\ntemplate <class T> T&& forward(typename remove_reference<T>::type&& t) noexcept; // constexpr in C++14\n\ntemplate <class T> typename remove_reference<T>::type&& move(T&&) noexcept;      // constexpr in C++14\n\ntemplate <class T>\n    typename conditional\n    <\n        !is_nothrow_move_constructible<T>::value && is_copy_constructible<T>::value,\n        const T&,\n        T&&\n    >::type\n    move_if_noexcept(T& x) noexcept; // constexpr in C++14\n\ntemplate <class T> typename add_rvalue_reference<T>::type declval() noexcept;\n\ntemplate <class T1, class T2>\nstruct pair\n{\n    typedef T1 first_type;\n    typedef T2 second_type;\n\n    T1 first;\n    T2 second;\n\n    pair(const pair&) = default;\n    pair(pair&&) = default;\n    constexpr pair();\n    pair(const T1& x, const T2& y);                          // constexpr in C++14\n    template <class U, class V> pair(U&& x, V&& y);          // constexpr in C++14\n    template <class U, class V> pair(const pair<U, V>& p);   // constexpr in C++14\n    template <class U, class V> pair(pair<U, V>&& p);        // constexpr in C++14\n    template <class... Args1, class... Args2>\n        pair(piecewise_construct_t, tuple<Args1...> first_args,\n             tuple<Args2...> second_args);\n\n    template <class U, class V> pair& operator=(const pair<U, V>& p);\n    pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value &&\n                                       is_nothrow_move_assignable<T2>::value);\n    template <class U, class V> pair& operator=(pair<U, V>&& p);\n\n    void swap(pair& p) noexcept(noexcept(swap(first, p.first)) &&\n                                noexcept(swap(second, p.second)));\n};\n\ntemplate <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14\ntemplate <class T1, class T2> bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14\ntemplate <class T1, class T2> bool operator< (const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14\ntemplate <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14\ntemplate <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14\ntemplate <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14\n\ntemplate <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&);   // constexpr in C++14\ntemplate <class T1, class T2>\nvoid\nswap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));\n\nstruct piecewise_construct_t { };\nconstexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();\n\ntemplate <class T> class tuple_size;\ntemplate <size_t I, class T> class tuple_element;\n\ntemplate <class T1, class T2> struct tuple_size<pair<T1, T2> >;\ntemplate <class T1, class T2> struct tuple_element<0, pair<T1, T2> >;\ntemplate <class T1, class T2> struct tuple_element<1, pair<T1, T2> >;\n\ntemplate<size_t I, class T1, class T2>\n    typename tuple_element<I, pair<T1, T2> >::type&\n    get(pair<T1, T2>&) noexcept; // constexpr in C++14\n\ntemplate<size_t I, class T1, class T2>\n    const typename const tuple_element<I, pair<T1, T2> >::type&\n    get(const pair<T1, T2>&) noexcept; // constexpr in C++14\n\ntemplate<size_t I, class T1, class T2>\n    typename tuple_element<I, pair<T1, T2> >::type&&\n    get(pair<T1, T2>&&) noexcept; // constexpr in C++14\n\ntemplate<class T1, class T2>\n    constexpr T1& get(pair<T1, T2>&) noexcept; // C++14\n\ntemplate<size_t I, class T1, class T2>\n    constexpr T1 const& get(pair<T1, T2> const &) noexcept; // C++14\n\ntemplate<size_t I, class T1, class T2>\n    constexpr T1&& get(pair<T1, T2>&&) noexcept; // C++14\n\n// C++14\n\ntemplate<class T, T... I>\nstruct integer_sequence\n{\n    typedef T value_type;\n\n    static constexpr size_t size() noexcept;\n};\n\ntemplate<size_t... I>\n  using index_sequence = integer_sequence<size_t, I...>;\n\ntemplate<class T, T N>\n  using make_integer_sequence = integer_sequence<T, 0, 1, ..., N-1>;\ntemplate<size_t N>\n  using make_index_sequence = make_integer_sequence<size_t, N>;\n\ntemplate<class... T>\n  using index_sequence_for = make_index_sequence<sizeof...(T)>;\n\ntemplate<class T, class U=T> \n    T exchange(T& obj, U&& new_value);\n}  // std\n\n*/\n\n#include <__config>\n#include <__tuple>\n#include <type_traits>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nnamespace rel_ops\n{\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const _Tp& __x, const _Tp& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator> (const _Tp& __x, const _Tp& __y)\n{\n    return __y < __x;\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const _Tp& __x, const _Tp& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const _Tp& __x, const _Tp& __y)\n{\n    return !(__x < __y);\n}\n\n}  // rel_ops\n\n// swap_ranges\n\n// forward\ntemplate<class _Tp, size_t _Np>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value);\n\ntemplate <class _ForwardIterator1, class _ForwardIterator2>\ninline _LIBCPP_INLINE_VISIBILITY\n_ForwardIterator2\nswap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2)\n{\n    for(; __first1 != __last1; ++__first1, (void) ++__first2)\n        swap(*__first1, *__first2);\n    return __first2;\n}\n\ntemplate<class _Tp, size_t _Np>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)\n{\n    _VSTD::swap_ranges(__a, __a + _Np, __b);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\ntypename conditional\n<\n    !is_nothrow_move_constructible<_Tp>::value && is_copy_constructible<_Tp>::value,\n    const _Tp&,\n    _Tp&&\n>::type\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\nconst _Tp&\n#endif\nmove_if_noexcept(_Tp& __x) _NOEXCEPT\n{\n    return _VSTD::move(__x);\n}\n\nstruct _LIBCPP_TYPE_VIS_ONLY piecewise_construct_t { };\n#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_UTILITY)\nextern const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();\n#else\nconstexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();\n#endif\n\ntemplate <class _T1, class _T2>\nstruct _LIBCPP_TYPE_VIS_ONLY pair\n{\n    typedef _T1 first_type;\n    typedef _T2 second_type;\n\n    _T1 first;\n    _T2 second;\n\n    // pair(const pair&) = default;\n    // pair(pair&&) = default;\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR pair() : first(), second() {}\n\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    pair(const _T1& __x, const _T2& __y)\n        : first(__x), second(__y) {}\n\n    template<class _U1, class _U2>\n        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n        pair(const pair<_U1, _U2>& __p\n#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE\n                 ,typename enable_if<is_convertible<const _U1&, _T1>::value &&\n                                    is_convertible<const _U2&, _T2>::value>::type* = 0\n#endif\n                                      )\n            : first(__p.first), second(__p.second) {}\n\n#if !defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && _LIBCPP_TRIVIAL_PAIR_COPY_CTOR\n    _LIBCPP_INLINE_VISIBILITY\n    pair(const pair& __p) = default;\n#elif !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) || !_LIBCPP_TRIVIAL_PAIR_COPY_CTOR\n    _LIBCPP_INLINE_VISIBILITY\n    pair(const pair& __p)\n        _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&\n                   is_nothrow_copy_constructible<second_type>::value)\n        : first(__p.first),\n          second(__p.second)\n    {\n    }\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    pair& operator=(const pair& __p)\n        _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value &&\n                   is_nothrow_copy_assignable<second_type>::value)\n    {\n        first = __p.first;\n        second = __p.second;\n        return *this;\n    }\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    template <class _U1, class _U2,\n              class = typename enable_if<is_convertible<_U1, first_type>::value &&\n                                         is_convertible<_U2, second_type>::value>::type>\n        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n        pair(_U1&& __u1, _U2&& __u2)\n            : first(_VSTD::forward<_U1>(__u1)),\n              second(_VSTD::forward<_U2>(__u2))\n            {}\n\n    template<class _U1, class _U2>\n        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n        pair(pair<_U1, _U2>&& __p,\n                 typename enable_if<is_convertible<_U1, _T1>::value &&\n                                    is_convertible<_U2, _T2>::value>::type* = 0)\n            : first(_VSTD::forward<_U1>(__p.first)),\n              second(_VSTD::forward<_U2>(__p.second)) {}\n\n#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n    _LIBCPP_INLINE_VISIBILITY\n    pair(pair&& __p) = default;\n#else\n    _LIBCPP_INLINE_VISIBILITY\n    pair(pair&& __p) _NOEXCEPT_(is_nothrow_move_constructible<first_type>::value &&\n                                is_nothrow_move_constructible<second_type>::value)\n        : first(_VSTD::forward<first_type>(__p.first)),\n          second(_VSTD::forward<second_type>(__p.second))\n    {\n    }\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY\n    pair&\n    operator=(pair&& __p) _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&\n                                     is_nothrow_move_assignable<second_type>::value)\n    {\n        first = _VSTD::forward<first_type>(__p.first);\n        second = _VSTD::forward<second_type>(__p.second);\n        return *this;\n    }\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\n    template<class _Tuple,\n             class = typename enable_if<__tuple_convertible<_Tuple, pair>::value>::type>\n        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n        pair(_Tuple&& __p)\n            : first(_VSTD::forward<typename tuple_element<0,\n                                  typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<0>(__p))),\n              second(_VSTD::forward<typename tuple_element<1,\n                                   typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<1>(__p)))\n            {}\n\n\n\n    template <class... _Args1, class... _Args2>\n        _LIBCPP_INLINE_VISIBILITY\n        pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,\n                                    tuple<_Args2...> __second_args)\n            : pair(__pc, __first_args, __second_args,\n                   typename __make_tuple_indices<sizeof...(_Args1)>::type(),\n                   typename __make_tuple_indices<sizeof...(_Args2) >::type())\n            {}\n\n    template <class _Tuple,\n              class = typename enable_if<__tuple_assignable<_Tuple, pair>::value>::type>\n        _LIBCPP_INLINE_VISIBILITY\n        pair&\n        operator=(_Tuple&& __p)\n        {\n            typedef typename __make_tuple_types<_Tuple>::type _TupleRef;\n            typedef typename tuple_element<0, _TupleRef>::type _U0;\n            typedef typename tuple_element<1, _TupleRef>::type _U1;\n            first  = _VSTD::forward<_U0>(_VSTD::get<0>(__p));\n            second = _VSTD::forward<_U1>(_VSTD::get<1>(__p));\n            return *this;\n        }\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    void\n    swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value &&\n                               __is_nothrow_swappable<second_type>::value)\n    {\n        _VSTD::iter_swap(&first, &__p.first);\n        _VSTD::iter_swap(&second, &__p.second);\n    }\nprivate:\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>\n        _LIBCPP_INLINE_VISIBILITY\n        pair(piecewise_construct_t,\n             tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,\n             __tuple_indices<_I1...>, __tuple_indices<_I2...>);\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n};\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator==(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)\n{\n    return __x.first == __y.first && __x.second == __y.second;\n}\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator!=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator< (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)\n{\n    return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);\n}\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator> (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator>=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nbool\noperator<=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_swappable<_T1>::value &&\n    __is_swappable<_T2>::value,\n    void\n>::type\nswap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)\n                     _NOEXCEPT_((__is_nothrow_swappable<_T1>::value &&\n                                 __is_nothrow_swappable<_T2>::value))\n{\n    __x.swap(__y);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp> class _LIBCPP_TYPE_VIS_ONLY reference_wrapper;\n\ntemplate <class _Tp>\nstruct __make_pair_return_impl\n{\n    typedef _Tp type;\n};\n\ntemplate <class _Tp>\nstruct __make_pair_return_impl<reference_wrapper<_Tp>>\n{\n    typedef _Tp& type;\n};\n\ntemplate <class _Tp>\nstruct __make_pair_return\n{\n    typedef typename __make_pair_return_impl<typename decay<_Tp>::type>::type type;\n};\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\npair<typename __make_pair_return<_T1>::type, typename __make_pair_return<_T2>::type>\nmake_pair(_T1&& __t1, _T2&& __t2)\n{\n    return pair<typename __make_pair_return<_T1>::type, typename __make_pair_return<_T2>::type>\n               (_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));\n}\n\n#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY\npair<_T1,_T2>\nmake_pair(_T1 __x, _T2 __y)\n{\n    return pair<_T1, _T2>(__x, __y);\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _T1, class _T2>\n  class _LIBCPP_TYPE_VIS_ONLY tuple_size<pair<_T1, _T2> >\n    : public integral_constant<size_t, 2> {};\n\ntemplate <class _T1, class _T2>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_element<0, pair<_T1, _T2> >\n{\npublic:\n    typedef _T1 type;\n};\n\ntemplate <class _T1, class _T2>\nclass _LIBCPP_TYPE_VIS_ONLY tuple_element<1, pair<_T1, _T2> >\n{\npublic:\n    typedef _T2 type;\n};\n\ntemplate <size_t _Ip> struct __get_pair;\n\ntemplate <>\nstruct __get_pair<0>\n{\n    template <class _T1, class _T2>\n    static\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    _T1&\n    get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}\n\n    template <class _T1, class _T2>\n    static\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    const _T1&\n    get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    template <class _T1, class _T2>\n    static\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    _T1&&\n    get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T1>(__p.first);}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n};\n\ntemplate <>\nstruct __get_pair<1>\n{\n    template <class _T1, class _T2>\n    static\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    _T2&\n    get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}\n\n    template <class _T1, class _T2>\n    static\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    const _T2&\n    get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    template <class _T1, class _T2>\n    static\n    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\n    _T2&&\n    get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T2>(__p.second);}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n};\n\ntemplate <size_t _Ip, class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntypename tuple_element<_Ip, pair<_T1, _T2> >::type&\nget(pair<_T1, _T2>& __p) _NOEXCEPT\n{\n    return __get_pair<_Ip>::get(__p);\n}\n\ntemplate <size_t _Ip, class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\nconst typename tuple_element<_Ip, pair<_T1, _T2> >::type&\nget(const pair<_T1, _T2>& __p) _NOEXCEPT\n{\n    return __get_pair<_Ip>::get(__p);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <size_t _Ip, class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11\ntypename tuple_element<_Ip, pair<_T1, _T2> >::type&&\nget(pair<_T1, _T2>&& __p) _NOEXCEPT\n{\n    return __get_pair<_Ip>::get(_VSTD::move(__p));\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT\n{\n    return __get_pair<0>::get(__p);\n}\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT\n{\n    return __get_pair<0>::get(__p);\n}\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT\n{\n    return __get_pair<0>::get(_VSTD::move(__p));\n}\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT\n{\n    return __get_pair<1>::get(__p);\n}\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT\n{\n    return __get_pair<1>::get(__p);\n}\n\ntemplate <class _T1, class _T2>\ninline _LIBCPP_INLINE_VISIBILITY\nconstexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT\n{\n    return __get_pair<1>::get(_VSTD::move(__p));\n}\n\n#endif\n\n#if _LIBCPP_STD_VER > 11\n\ntemplate<class _Tp, _Tp... _Ip>\nstruct _LIBCPP_TYPE_VIS_ONLY integer_sequence\n{\n    typedef _Tp value_type;\n    static_assert( is_integral<_Tp>::value,\n                  \"std::integer_sequence can only be instantiated with an integral type\" );\n    static\n    _LIBCPP_INLINE_VISIBILITY\n    constexpr\n    size_t\n    size() noexcept { return sizeof...(_Ip); }\n};\n\ntemplate<size_t... _Ip>\n    using index_sequence = integer_sequence<size_t, _Ip...>;\n\nnamespace __detail {\n\ntemplate<typename _Tp, size_t ..._Extra> struct __repeat;\ntemplate<typename _Tp, _Tp ..._Np, size_t ..._Extra> struct __repeat<integer_sequence<_Tp, _Np...>, _Extra...> {\n  typedef integer_sequence<_Tp,\n                           _Np...,\n                           sizeof...(_Np) + _Np...,\n                           2 * sizeof...(_Np) + _Np...,\n                           3 * sizeof...(_Np) + _Np...,\n                           4 * sizeof...(_Np) + _Np...,\n                           5 * sizeof...(_Np) + _Np...,\n                           6 * sizeof...(_Np) + _Np...,\n                           7 * sizeof...(_Np) + _Np...,\n                           _Extra...> type;\n};\n\ntemplate<size_t _Np> struct __parity;\ntemplate<size_t _Np> struct __make : __parity<_Np % 8>::template __pmake<_Np> {};\n\ntemplate<> struct __make<0> { typedef integer_sequence<size_t> type; };\ntemplate<> struct __make<1> { typedef integer_sequence<size_t, 0> type; };\ntemplate<> struct __make<2> { typedef integer_sequence<size_t, 0, 1> type; };\ntemplate<> struct __make<3> { typedef integer_sequence<size_t, 0, 1, 2> type; };\ntemplate<> struct __make<4> { typedef integer_sequence<size_t, 0, 1, 2, 3> type; };\ntemplate<> struct __make<5> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4> type; };\ntemplate<> struct __make<6> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4, 5> type; };\ntemplate<> struct __make<7> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6> type; };\n\ntemplate<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; };\ntemplate<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; };\ntemplate<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; };\ntemplate<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; };\ntemplate<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };\ntemplate<> struct __parity<5> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };\ntemplate<> struct __parity<6> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };\ntemplate<> struct __parity<7> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };\n\ntemplate<typename _Tp, typename _Up> struct __convert {\n  template<typename> struct __result;\n  template<_Tp ..._Np> struct __result<integer_sequence<_Tp, _Np...> > { typedef integer_sequence<_Up, _Np...> type; };\n};\ntemplate<typename _Tp> struct __convert<_Tp, _Tp> { template<typename _Up> struct __result { typedef _Up type; }; };\n\n}\n\ntemplate<typename _Tp, _Tp _Np> using __make_integer_sequence_unchecked =\n  typename __detail::__convert<size_t, _Tp>::template __result<typename __detail::__make<_Np>::type>::type;\n\ntemplate <class _Tp, _Tp _Ep>\nstruct __make_integer_sequence\n{\n    static_assert(is_integral<_Tp>::value,\n                  \"std::make_integer_sequence can only be instantiated with an integral type\" );\n    static_assert(0 <= _Ep, \"std::make_integer_sequence input shall not be negative\");\n    typedef __make_integer_sequence_unchecked<_Tp, _Ep> type;\n};\n\ntemplate<class _Tp, _Tp _Np>\n    using make_integer_sequence = typename __make_integer_sequence<_Tp, _Np>::type;\n\ntemplate<size_t _Np>\n    using make_index_sequence = make_integer_sequence<size_t, _Np>;\n\ntemplate<class... _Tp>\n    using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;\n  \n#endif  // _LIBCPP_STD_VER > 11\n\n#if _LIBCPP_STD_VER > 11\ntemplate<class _T1, class _T2 = _T1>\ninline _LIBCPP_INLINE_VISIBILITY\n_T1 exchange(_T1& __obj, _T2 && __new_value)\n{\n    _T1 __old_value = _VSTD::move(__obj);\n    __obj = _VSTD::forward<_T2>(__new_value);\n    return __old_value;\n}    \n#endif  // _LIBCPP_STD_VER > 11\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_UTILITY\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/valarray",
    "content": "// -*- C++ -*-\n//===-------------------------- valarray ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_VALARRAY\n#define _LIBCPP_VALARRAY\n\n/*\n    valarray synopsis\n\nnamespace std\n{\n\ntemplate<class T>\nclass valarray\n{\npublic:\n    typedef T value_type;\n\n    // construct/destroy:\n    valarray();\n    explicit valarray(size_t n);\n    valarray(const value_type& x, size_t n);\n    valarray(const value_type* px, size_t n);\n    valarray(const valarray& v);\n    valarray(valarray&& v) noexcept;\n    valarray(const slice_array<value_type>& sa);\n    valarray(const gslice_array<value_type>& ga);\n    valarray(const mask_array<value_type>& ma);\n    valarray(const indirect_array<value_type>& ia);\n    valarray(initializer_list<value_type> il);\n    ~valarray();\n\n    // assignment:\n    valarray& operator=(const valarray& v);\n    valarray& operator=(valarray&& v) noexcept;\n    valarray& operator=(initializer_list<value_type> il);\n    valarray& operator=(const value_type& x);\n    valarray& operator=(const slice_array<value_type>& sa);\n    valarray& operator=(const gslice_array<value_type>& ga);\n    valarray& operator=(const mask_array<value_type>& ma);\n    valarray& operator=(const indirect_array<value_type>& ia);\n\n    // element access:\n    const value_type& operator[](size_t i) const;\n    value_type&       operator[](size_t i);\n\n    // subset operations:\n    valarray                   operator[](slice s) const;\n    slice_array<value_type>    operator[](slice s);\n    valarray                   operator[](const gslice& gs) const;\n    gslice_array<value_type>   operator[](const gslice& gs);\n    valarray                   operator[](const valarray<bool>& vb) const;\n    mask_array<value_type>     operator[](const valarray<bool>& vb);\n    valarray                   operator[](const valarray<size_t>& vs) const;\n    indirect_array<value_type> operator[](const valarray<size_t>& vs);\n\n    // unary operators:\n    valarray       operator+() const;\n    valarray       operator-() const;\n    valarray       operator~() const;\n    valarray<bool> operator!() const;\n\n    // computed assignment:\n    valarray& operator*= (const value_type& x);\n    valarray& operator/= (const value_type& x);\n    valarray& operator%= (const value_type& x);\n    valarray& operator+= (const value_type& x);\n    valarray& operator-= (const value_type& x);\n    valarray& operator^= (const value_type& x);\n    valarray& operator&= (const value_type& x);\n    valarray& operator|= (const value_type& x);\n    valarray& operator<<=(const value_type& x);\n    valarray& operator>>=(const value_type& x);\n\n    valarray& operator*= (const valarray& v);\n    valarray& operator/= (const valarray& v);\n    valarray& operator%= (const valarray& v);\n    valarray& operator+= (const valarray& v);\n    valarray& operator-= (const valarray& v);\n    valarray& operator^= (const valarray& v);\n    valarray& operator|= (const valarray& v);\n    valarray& operator&= (const valarray& v);\n    valarray& operator<<=(const valarray& v);\n    valarray& operator>>=(const valarray& v);\n\n    // member functions:\n    void swap(valarray& v) noexcept;\n\n    size_t size() const;\n\n    value_type sum() const;\n    value_type min() const;\n    value_type max() const;\n\n    valarray shift (int i) const;\n    valarray cshift(int i) const;\n    valarray apply(value_type f(value_type)) const;\n    valarray apply(value_type f(const value_type&)) const;\n    void resize(size_t n, value_type x = value_type());\n};\n\nclass slice\n{\npublic:\n    slice();\n    slice(size_t start, size_t size, size_t stride);\n\n    size_t start()  const;\n    size_t size()   const;\n    size_t stride() const;\n};\n\ntemplate <class T>\nclass slice_array\n{\npublic:\n    typedef T value_type;\n\n    const slice_array& operator=(const slice_array& sa) const;\n    void operator=  (const valarray<value_type>& v) const;\n    void operator*= (const valarray<value_type>& v) const;\n    void operator/= (const valarray<value_type>& v) const;\n    void operator%= (const valarray<value_type>& v) const;\n    void operator+= (const valarray<value_type>& v) const;\n    void operator-= (const valarray<value_type>& v) const;\n    void operator^= (const valarray<value_type>& v) const;\n    void operator&= (const valarray<value_type>& v) const;\n    void operator|= (const valarray<value_type>& v) const;\n    void operator<<=(const valarray<value_type>& v) const;\n    void operator>>=(const valarray<value_type>& v) const;\n\n    void operator=(const value_type& x) const;\n\n    slice_array() = delete;\n};\n\nclass gslice\n{\npublic:\n    gslice();\n    gslice(size_t start, const valarray<size_t>& size,\n                         const valarray<size_t>& stride);\n\n    size_t           start()  const;\n    valarray<size_t> size()   const;\n    valarray<size_t> stride() const;\n};\n\ntemplate <class T>\nclass gslice_array\n{\npublic:\n    typedef T value_type;\n\n    void operator=  (const valarray<value_type>& v) const;\n    void operator*= (const valarray<value_type>& v) const;\n    void operator/= (const valarray<value_type>& v) const;\n    void operator%= (const valarray<value_type>& v) const;\n    void operator+= (const valarray<value_type>& v) const;\n    void operator-= (const valarray<value_type>& v) const;\n    void operator^= (const valarray<value_type>& v) const;\n    void operator&= (const valarray<value_type>& v) const;\n    void operator|= (const valarray<value_type>& v) const;\n    void operator<<=(const valarray<value_type>& v) const;\n    void operator>>=(const valarray<value_type>& v) const;\n\n    gslice_array(const gslice_array& ga);\n    ~gslice_array();\n    const gslice_array& operator=(const gslice_array& ga) const;\n    void operator=(const value_type& x) const;\n\n    gslice_array() = delete;\n};\n\ntemplate <class T>\nclass mask_array\n{\npublic:\n    typedef T value_type;\n\n    void operator=  (const valarray<value_type>& v) const;\n    void operator*= (const valarray<value_type>& v) const;\n    void operator/= (const valarray<value_type>& v) const;\n    void operator%= (const valarray<value_type>& v) const;\n    void operator+= (const valarray<value_type>& v) const;\n    void operator-= (const valarray<value_type>& v) const;\n    void operator^= (const valarray<value_type>& v) const;\n    void operator&= (const valarray<value_type>& v) const;\n    void operator|= (const valarray<value_type>& v) const;\n    void operator<<=(const valarray<value_type>& v) const;\n    void operator>>=(const valarray<value_type>& v) const;\n\n    mask_array(const mask_array& ma);\n    ~mask_array();\n    const mask_array& operator=(const mask_array& ma) const;\n    void operator=(const value_type& x) const;\n\n    mask_array() = delete;\n};\n\ntemplate <class T>\nclass indirect_array\n{\npublic:\n    typedef T value_type;\n\n    void operator=  (const valarray<value_type>& v) const;\n    void operator*= (const valarray<value_type>& v) const;\n    void operator/= (const valarray<value_type>& v) const;\n    void operator%= (const valarray<value_type>& v) const;\n    void operator+= (const valarray<value_type>& v) const;\n    void operator-= (const valarray<value_type>& v) const;\n    void operator^= (const valarray<value_type>& v) const;\n    void operator&= (const valarray<value_type>& v) const;\n    void operator|= (const valarray<value_type>& v) const;\n    void operator<<=(const valarray<value_type>& v) const;\n    void operator>>=(const valarray<value_type>& v) const;\n\n    indirect_array(const indirect_array& ia);\n    ~indirect_array();\n    const indirect_array& operator=(const indirect_array& ia) const;\n    void operator=(const value_type& x) const;\n\n    indirect_array() = delete;\n};\n\ntemplate<class T> void swap(valarray<T>& x, valarray<T>& y) noexcept;\n\ntemplate<class T> valarray<T> operator* (const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<T> operator* (const valarray<T>& x, const T& y);\ntemplate<class T> valarray<T> operator* (const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<T> operator/ (const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<T> operator/ (const valarray<T>& x, const T& y);\ntemplate<class T> valarray<T> operator/ (const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<T> operator% (const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<T> operator% (const valarray<T>& x, const T& y);\ntemplate<class T> valarray<T> operator% (const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<T> operator+ (const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<T> operator+ (const valarray<T>& x, const T& y);\ntemplate<class T> valarray<T> operator+ (const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<T> operator- (const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<T> operator- (const valarray<T>& x, const T& y);\ntemplate<class T> valarray<T> operator- (const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<T> operator^ (const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<T> operator^ (const valarray<T>& x, const T& y);\ntemplate<class T> valarray<T> operator^ (const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<T> operator& (const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<T> operator& (const valarray<T>& x, const T& y);\ntemplate<class T> valarray<T> operator& (const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<T> operator| (const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<T> operator| (const valarray<T>& x, const T& y);\ntemplate<class T> valarray<T> operator| (const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<T> operator<<(const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<T> operator<<(const valarray<T>& x, const T& y);\ntemplate<class T> valarray<T> operator<<(const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<T> operator>>(const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<T> operator>>(const valarray<T>& x, const T& y);\ntemplate<class T> valarray<T> operator>>(const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<bool> operator&&(const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<bool> operator&&(const valarray<T>& x, const T& y);\ntemplate<class T> valarray<bool> operator&&(const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<bool> operator||(const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<bool> operator||(const valarray<T>& x, const T& y);\ntemplate<class T> valarray<bool> operator||(const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<bool> operator==(const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<bool> operator==(const valarray<T>& x, const T& y);\ntemplate<class T> valarray<bool> operator==(const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<bool> operator!=(const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<bool> operator!=(const valarray<T>& x, const T& y);\ntemplate<class T> valarray<bool> operator!=(const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<bool> operator< (const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<bool> operator< (const valarray<T>& x, const T& y);\ntemplate<class T> valarray<bool> operator< (const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<bool> operator> (const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<bool> operator> (const valarray<T>& x, const T& y);\ntemplate<class T> valarray<bool> operator> (const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<bool> operator<=(const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<bool> operator<=(const valarray<T>& x, const T& y);\ntemplate<class T> valarray<bool> operator<=(const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<bool> operator>=(const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<bool> operator>=(const valarray<T>& x, const T& y);\ntemplate<class T> valarray<bool> operator>=(const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<T> abs (const valarray<T>& x);\ntemplate<class T> valarray<T> acos (const valarray<T>& x);\ntemplate<class T> valarray<T> asin (const valarray<T>& x);\ntemplate<class T> valarray<T> atan (const valarray<T>& x);\n\ntemplate<class T> valarray<T> atan2(const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<T> atan2(const valarray<T>& x, const T& y);\ntemplate<class T> valarray<T> atan2(const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<T> cos (const valarray<T>& x);\ntemplate<class T> valarray<T> cosh (const valarray<T>& x);\ntemplate<class T> valarray<T> exp (const valarray<T>& x);\ntemplate<class T> valarray<T> log (const valarray<T>& x);\ntemplate<class T> valarray<T> log10(const valarray<T>& x);\n\ntemplate<class T> valarray<T> pow(const valarray<T>& x, const valarray<T>& y);\ntemplate<class T> valarray<T> pow(const valarray<T>& x, const T& y);\ntemplate<class T> valarray<T> pow(const T& x, const valarray<T>& y);\n\ntemplate<class T> valarray<T> sin (const valarray<T>& x);\ntemplate<class T> valarray<T> sinh (const valarray<T>& x);\ntemplate<class T> valarray<T> sqrt (const valarray<T>& x);\ntemplate<class T> valarray<T> tan (const valarray<T>& x);\ntemplate<class T> valarray<T> tanh (const valarray<T>& x);\n\ntemplate <class T> unspecified1 begin(valarray<T>& v);\ntemplate <class T> unspecified2 begin(const valarray<T>& v);\ntemplate <class T> unspecified1 end(valarray<T>& v);\ntemplate <class T> unspecified2 end(const valarray<T>& v);\n\n}  // std\n\n*/\n\n#include <__config>\n#include <cstddef>\n#include <cmath>\n#include <initializer_list>\n#include <algorithm>\n#include <functional>\n#include <new>\n\n#include <__undef_min_max>\n#include <__undef___deallocate>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate<class _Tp> class _LIBCPP_TYPE_VIS_ONLY valarray;\n\nclass _LIBCPP_TYPE_VIS_ONLY slice\n{\n    size_t __start_;\n    size_t __size_;\n    size_t __stride_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    slice()\n        : __start_(0),\n          __size_(0),\n          __stride_(0)\n          {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    slice(size_t __start, size_t __size, size_t __stride)\n        : __start_(__start),\n          __size_(__size),\n          __stride_(__stride)\n          {}\n\n    _LIBCPP_INLINE_VISIBILITY size_t start()  const {return __start_;}\n    _LIBCPP_INLINE_VISIBILITY size_t size()   const {return __size_;}\n    _LIBCPP_INLINE_VISIBILITY size_t stride() const {return __stride_;}\n};\n\ntemplate <class _Tp> class _LIBCPP_TYPE_VIS_ONLY slice_array;\nclass _LIBCPP_TYPE_VIS gslice;\ntemplate <class _Tp> class _LIBCPP_TYPE_VIS_ONLY gslice_array;\ntemplate <class _Tp> class _LIBCPP_TYPE_VIS_ONLY mask_array;\ntemplate <class _Tp> class _LIBCPP_TYPE_VIS_ONLY indirect_array;\n\ntemplate <class _Tp>\n_LIBCPP_INLINE_VISIBILITY\n_Tp*\nbegin(valarray<_Tp>& __v);\n\ntemplate <class _Tp>\n_LIBCPP_INLINE_VISIBILITY\nconst _Tp*\nbegin(const valarray<_Tp>& __v);\n\ntemplate <class _Tp>\n_LIBCPP_INLINE_VISIBILITY\n_Tp*\nend(valarray<_Tp>& __v);\n\ntemplate <class _Tp>\n_LIBCPP_INLINE_VISIBILITY\nconst _Tp*\nend(const valarray<_Tp>& __v);\n\ntemplate <class _Op, class _A0>\nstruct _UnaryOp\n{\n    typedef typename _Op::result_type result_type;\n    typedef typename _A0::value_type value_type;\n\n    _Op __op_;\n    _A0 __a0_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    _UnaryOp(const _Op& __op, const _A0& __a0) : __op_(__op), __a0_(__a0) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator[](size_t __i) const {return __op_(__a0_[__i]);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const {return __a0_.size();}\n};\n\ntemplate <class _Op, class _A0, class _A1>\nstruct _BinaryOp\n{\n    typedef typename _Op::result_type result_type;\n    typedef typename _A0::value_type value_type;\n\n    _Op __op_;\n    _A0 __a0_;\n    _A1 __a1_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    _BinaryOp(const _Op& __op, const _A0& __a0, const _A1& __a1)\n        : __op_(__op), __a0_(__a0), __a1_(__a1) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const {return __a0_.size();}\n};\n\ntemplate <class _Tp>\nclass __scalar_expr\n{\npublic:\n    typedef _Tp        value_type;\n    typedef const _Tp& result_type;\nprivate:\n    const value_type& __t_;\n    size_t __s_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __scalar_expr(const value_type& __t, size_t __s) : __t_(__t), __s_(__s) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator[](size_t) const {return __t_;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const {return __s_;}\n};\n\ntemplate <class _Tp>\nstruct __unary_plus : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return +__x;}\n};\n\ntemplate <class _Tp>\nstruct __bit_not  : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return ~__x;}\n};\n\ntemplate <class _Tp>\nstruct __bit_shift_left : binary_function<_Tp, _Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x << __y;}\n};\n\ntemplate <class _Tp>\nstruct __bit_shift_right : binary_function<_Tp, _Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x, const _Tp& __y) const\n        {return __x >> __y;}\n};\n\ntemplate <class _Tp, class _Fp>\nstruct __apply_expr   : unary_function<_Tp, _Tp>\n{\nprivate:\n    _Fp __f_;\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __apply_expr(_Fp __f) : __f_(__f) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return __f_(__x);}\n};\n\ntemplate <class _Tp>\nstruct __abs_expr : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return abs(__x);}\n};\n\ntemplate <class _Tp>\nstruct __acos_expr : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return acos(__x);}\n};\n\ntemplate <class _Tp>\nstruct __asin_expr : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return asin(__x);}\n};\n\ntemplate <class _Tp>\nstruct __atan_expr : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return atan(__x);}\n};\n\ntemplate <class _Tp>\nstruct __atan2_expr : binary_function<_Tp, _Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x, const _Tp& __y) const\n        {return atan2(__x, __y);}\n};\n\ntemplate <class _Tp>\nstruct __cos_expr : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return cos(__x);}\n};\n\ntemplate <class _Tp>\nstruct __cosh_expr : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return cosh(__x);}\n};\n\ntemplate <class _Tp>\nstruct __exp_expr : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return exp(__x);}\n};\n\ntemplate <class _Tp>\nstruct __log_expr : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return log(__x);}\n};\n\ntemplate <class _Tp>\nstruct __log10_expr : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return log10(__x);}\n};\n\ntemplate <class _Tp>\nstruct __pow_expr : binary_function<_Tp, _Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x, const _Tp& __y) const\n        {return pow(__x, __y);}\n};\n\ntemplate <class _Tp>\nstruct __sin_expr : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return sin(__x);}\n};\n\ntemplate <class _Tp>\nstruct __sinh_expr : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return sinh(__x);}\n};\n\ntemplate <class _Tp>\nstruct __sqrt_expr : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return sqrt(__x);}\n};\n\ntemplate <class _Tp>\nstruct __tan_expr : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return tan(__x);}\n};\n\ntemplate <class _Tp>\nstruct __tanh_expr : unary_function<_Tp, _Tp>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    _Tp operator()(const _Tp& __x) const\n        {return tanh(__x);}\n};\n\ntemplate <class _ValExpr>\nclass __slice_expr\n{\n    typedef typename remove_reference<_ValExpr>::type  _RmExpr;\npublic:\n    typedef typename _RmExpr::value_type value_type;\n    typedef value_type result_type;\n\nprivate:\n    _ValExpr __expr_;\n    size_t __start_;\n    size_t __size_;\n    size_t __stride_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __slice_expr(const slice& __sl, const _RmExpr& __e)\n        : __expr_(__e),\n          __start_(__sl.start()),\n          __size_(__sl.size()),\n          __stride_(__sl.stride())\n        {}\npublic:\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator[](size_t __i) const\n        {return __expr_[__start_ + __i * __stride_];}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const {return __size_;}\n\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY valarray;\n};\n\ntemplate <class _ValExpr>\nclass __mask_expr;\n\ntemplate <class _ValExpr>\nclass __indirect_expr;\n\ntemplate <class _ValExpr>\nclass __shift_expr\n{\n    typedef typename remove_reference<_ValExpr>::type  _RmExpr;\npublic:\n    typedef typename _RmExpr::value_type value_type;\n    typedef value_type result_type;\n\nprivate:\n    _ValExpr __expr_;\n    size_t __size_;\n    ptrdiff_t __ul_;\n    ptrdiff_t __sn_;\n    ptrdiff_t __n_;\n    static const ptrdiff_t _Np = static_cast<ptrdiff_t>(\n                                    sizeof(ptrdiff_t) * __CHAR_BIT__ - 1);\n\n    _LIBCPP_INLINE_VISIBILITY\n    __shift_expr(int __n, const _RmExpr& __e)\n        : __expr_(__e),\n          __size_(__e.size()),\n          __n_(__n)\n        {\n            ptrdiff_t __neg_n = static_cast<ptrdiff_t>(__n_ >> _Np);\n            __sn_ = __neg_n | static_cast<ptrdiff_t>(static_cast<size_t>(-__n_) >> _Np);\n            __ul_ = ((__size_ - __n_) & ~__neg_n) | ((__n_ + 1) & __neg_n);\n        }\npublic:\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator[](size_t __j) const\n        {\n            ptrdiff_t __i = static_cast<ptrdiff_t>(__j);\n            ptrdiff_t __m = (__sn_ * __i - __ul_) >> _Np;\n            return (__expr_[(__i + __n_) & __m] & __m) | (value_type() & ~__m);\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const {return __size_;}\n\n    template <class> friend class __val_expr;\n};\n\ntemplate <class _ValExpr>\nclass __cshift_expr\n{\n    typedef typename remove_reference<_ValExpr>::type  _RmExpr;\npublic:\n    typedef typename _RmExpr::value_type value_type;\n    typedef value_type result_type;\n\nprivate:\n    _ValExpr __expr_;\n    size_t __size_;\n    size_t __m_;\n    size_t __o1_;\n    size_t __o2_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __cshift_expr(int __n, const _RmExpr& __e)\n        : __expr_(__e),\n          __size_(__e.size())\n        {\n            __n %= static_cast<int>(__size_);\n            if (__n >= 0)\n            {\n                __m_ = __size_ - __n;\n                __o1_ = __n;\n                __o2_ = __n - __size_;\n            }\n            else\n            {\n                __m_ = -__n;\n                __o1_ = __n + __size_;\n                __o2_ = __n;\n            }\n        }\npublic:\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator[](size_t __i) const\n        {\n            if (__i < __m_)\n                return __expr_[__i + __o1_];\n            return __expr_[__i + __o2_];\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const {return __size_;}\n\n    template <class> friend class __val_expr;\n};\n\ntemplate<class _ValExpr>\nclass __val_expr;\n\ntemplate<class _ValExpr>\nstruct __is_val_expr : false_type {};\n\ntemplate<class _ValExpr>\nstruct __is_val_expr<__val_expr<_ValExpr> > : true_type {};\n\ntemplate<class _Tp>\nstruct __is_val_expr<valarray<_Tp> > : true_type {};\n\ntemplate<class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY valarray\n{\npublic:\n    typedef _Tp value_type;\n    typedef _Tp result_type;\n\nprivate:\n    value_type* __begin_;\n    value_type* __end_;\n\npublic:\n    // construct/destroy:\n    _LIBCPP_INLINE_VISIBILITY\n    valarray() : __begin_(0), __end_(0) {}\n    explicit valarray(size_t __n);\n    valarray(const value_type& __x, size_t __n);\n    valarray(const value_type* __p, size_t __n);\n    valarray(const valarray& __v);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    valarray(valarray&& __v) _NOEXCEPT;\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    valarray(initializer_list<value_type> __il);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    valarray(const slice_array<value_type>& __sa);\n    valarray(const gslice_array<value_type>& __ga);\n    valarray(const mask_array<value_type>& __ma);\n    valarray(const indirect_array<value_type>& __ia);\n    ~valarray();\n\n    // assignment:\n    valarray& operator=(const valarray& __v);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    valarray& operator=(valarray&& __v) _NOEXCEPT;\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    valarray& operator=(initializer_list<value_type>);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    valarray& operator=(const value_type& __x);\n    valarray& operator=(const slice_array<value_type>& __sa);\n    valarray& operator=(const gslice_array<value_type>& __ga);\n    valarray& operator=(const mask_array<value_type>& __ma);\n    valarray& operator=(const indirect_array<value_type>& __ia);\n    template <class _ValExpr>\n        valarray& operator=(const __val_expr<_ValExpr>& __v);\n\n    // element access:\n    _LIBCPP_INLINE_VISIBILITY\n    const value_type& operator[](size_t __i) const {return __begin_[__i];}\n\n    _LIBCPP_INLINE_VISIBILITY\n    value_type&       operator[](size_t __i)       {return __begin_[__i];}\n\n    // subset operations:\n    __val_expr<__slice_expr<const valarray&> >    operator[](slice __s) const;\n    slice_array<value_type>                       operator[](slice __s);\n    __val_expr<__indirect_expr<const valarray&> > operator[](const gslice& __gs) const;\n    gslice_array<value_type>   operator[](const gslice& __gs);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __val_expr<__indirect_expr<const valarray&> > operator[](gslice&& __gs) const;\n    gslice_array<value_type>                      operator[](gslice&& __gs);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __val_expr<__mask_expr<const valarray&> >     operator[](const valarray<bool>& __vb) const;\n    mask_array<value_type>                        operator[](const valarray<bool>& __vb);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __val_expr<__mask_expr<const valarray&> >     operator[](valarray<bool>&& __vb) const;\n    mask_array<value_type>                        operator[](valarray<bool>&& __vb);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __val_expr<__indirect_expr<const valarray&> > operator[](const valarray<size_t>& __vs) const;\n    indirect_array<value_type>                    operator[](const valarray<size_t>& __vs);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    __val_expr<__indirect_expr<const valarray&> > operator[](valarray<size_t>&& __vs) const;\n    indirect_array<value_type>                    operator[](valarray<size_t>&& __vs);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    // unary operators:\n    valarray       operator+() const;\n    valarray       operator-() const;\n    valarray       operator~() const;\n    valarray<bool> operator!() const;\n\n    // computed assignment:\n    valarray& operator*= (const value_type& __x);\n    valarray& operator/= (const value_type& __x);\n    valarray& operator%= (const value_type& __x);\n    valarray& operator+= (const value_type& __x);\n    valarray& operator-= (const value_type& __x);\n    valarray& operator^= (const value_type& __x);\n    valarray& operator&= (const value_type& __x);\n    valarray& operator|= (const value_type& __x);\n    valarray& operator<<=(const value_type& __x);\n    valarray& operator>>=(const value_type& __x);\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        valarray&\n    >::type\n    operator*= (const _Expr& __v);\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        valarray&\n    >::type\n    operator/= (const _Expr& __v);\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        valarray&\n    >::type\n    operator%= (const _Expr& __v);\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        valarray&\n    >::type\n    operator+= (const _Expr& __v);\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        valarray&\n    >::type\n    operator-= (const _Expr& __v);\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        valarray&\n    >::type\n    operator^= (const _Expr& __v);\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        valarray&\n    >::type\n    operator|= (const _Expr& __v);\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        valarray&\n    >::type\n    operator&= (const _Expr& __v);\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        valarray&\n    >::type\n    operator<<= (const _Expr& __v);\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        valarray&\n    >::type\n    operator>>= (const _Expr& __v);\n\n    // member functions:\n    void swap(valarray& __v) _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const {return static_cast<size_t>(__end_ - __begin_);}\n\n    value_type sum() const;\n    value_type min() const;\n    value_type max() const;\n\n    valarray shift (int __i) const;\n    valarray cshift(int __i) const;\n    valarray apply(value_type __f(value_type)) const;\n    valarray apply(value_type __f(const value_type&)) const;\n    void     resize(size_t __n, value_type __x = value_type());\n\nprivate:\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY valarray;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY slice_array;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY gslice_array;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY mask_array;\n    template <class> friend class __mask_expr;\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY indirect_array;\n    template <class> friend class __indirect_expr;\n    template <class> friend class __val_expr;\n\n    template <class _Up>\n    friend\n    _Up*\n    begin(valarray<_Up>& __v);\n\n    template <class _Up>\n    friend\n    const _Up*\n    begin(const valarray<_Up>& __v);\n\n    template <class _Up>\n    friend\n    _Up*\n    end(valarray<_Up>& __v);\n\n    template <class _Up>\n    friend\n    const _Up*\n    end(const valarray<_Up>& __v);\n};\n\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS valarray<size_t>::valarray(size_t))\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS valarray<size_t>::~valarray())\n_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void valarray<size_t>::resize(size_t, size_t))\n\ntemplate <class _Op, class _Tp>\nstruct _UnaryOp<_Op, valarray<_Tp> >\n{\n    typedef typename _Op::result_type result_type;\n    typedef _Tp value_type;\n\n    _Op __op_;\n    const valarray<_Tp>& __a0_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    _UnaryOp(const _Op& __op, const valarray<_Tp>& __a0) : __op_(__op), __a0_(__a0) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator[](size_t __i) const {return __op_(__a0_[__i]);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const {return __a0_.size();}\n};\n\ntemplate <class _Op, class _Tp, class _A1>\nstruct _BinaryOp<_Op, valarray<_Tp>, _A1>\n{\n    typedef typename _Op::result_type result_type;\n    typedef _Tp value_type;\n\n    _Op __op_;\n    const valarray<_Tp>& __a0_;\n    _A1 __a1_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    _BinaryOp(const _Op& __op, const valarray<_Tp>& __a0, const _A1& __a1)\n        : __op_(__op), __a0_(__a0), __a1_(__a1) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const {return __a0_.size();}\n};\n\ntemplate <class _Op, class _A0, class _Tp>\nstruct _BinaryOp<_Op, _A0, valarray<_Tp> >\n{\n    typedef typename _Op::result_type result_type;\n    typedef _Tp value_type;\n\n    _Op __op_;\n    _A0 __a0_;\n    const valarray<_Tp>& __a1_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    _BinaryOp(const _Op& __op, const _A0& __a0, const valarray<_Tp>& __a1)\n        : __op_(__op), __a0_(__a0), __a1_(__a1) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const {return __a0_.size();}\n};\n\ntemplate <class _Op, class _Tp>\nstruct _BinaryOp<_Op, valarray<_Tp>, valarray<_Tp> >\n{\n    typedef typename _Op::result_type result_type;\n    typedef _Tp value_type;\n\n    _Op __op_;\n    const valarray<_Tp>& __a0_;\n    const valarray<_Tp>& __a1_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    _BinaryOp(const _Op& __op, const valarray<_Tp>& __a0, const valarray<_Tp>& __a1)\n        : __op_(__op), __a0_(__a0), __a1_(__a1) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const {return __a0_.size();}\n};\n\n// slice_array\n\ntemplate <class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY slice_array\n{\npublic:\n    typedef _Tp value_type;\n\nprivate:\n    value_type* __vp_;\n    size_t __size_;\n    size_t __stride_;\n\npublic:\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator*=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator/=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator%=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator+=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator-=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator^=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator&=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator|=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator<<=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator>>=(const _Expr& __v) const;\n\n    const slice_array& operator=(const slice_array& __sa) const;\n\n    void operator=(const value_type& __x) const;\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    slice_array(const slice& __sl, const valarray<value_type>& __v)\n        : __vp_(const_cast<value_type*>(__v.__begin_ + __sl.start())),\n          __size_(__sl.size()),\n          __stride_(__sl.stride())\n        {}\n\n    template <class> friend class valarray;\n    template <class> friend class sliceExpr;\n};\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconst slice_array<_Tp>&\nslice_array<_Tp>::operator=(const slice_array& __sa) const\n{\n    value_type* __t = __vp_;\n    const value_type* __s = __sa.__vp_;\n    for (size_t __n = __size_; __n; --__n, __t += __stride_, __s += __sa.__stride_)\n        *__t = *__s;\n    return *this;\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nslice_array<_Tp>::operator=(const _Expr& __v) const\n{\n    value_type* __t = __vp_;\n    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)\n        *__t = __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nslice_array<_Tp>::operator*=(const _Expr& __v) const\n{\n    value_type* __t = __vp_;\n    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)\n        *__t *= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nslice_array<_Tp>::operator/=(const _Expr& __v) const\n{\n    value_type* __t = __vp_;\n    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)\n        *__t /= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nslice_array<_Tp>::operator%=(const _Expr& __v) const\n{\n    value_type* __t = __vp_;\n    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)\n        *__t %= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nslice_array<_Tp>::operator+=(const _Expr& __v) const\n{\n    value_type* __t = __vp_;\n    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)\n        *__t += __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nslice_array<_Tp>::operator-=(const _Expr& __v) const\n{\n    value_type* __t = __vp_;\n    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)\n        *__t -= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nslice_array<_Tp>::operator^=(const _Expr& __v) const\n{\n    value_type* __t = __vp_;\n    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)\n        *__t ^= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nslice_array<_Tp>::operator&=(const _Expr& __v) const\n{\n    value_type* __t = __vp_;\n    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)\n        *__t &= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nslice_array<_Tp>::operator|=(const _Expr& __v) const\n{\n    value_type* __t = __vp_;\n    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)\n        *__t |= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nslice_array<_Tp>::operator<<=(const _Expr& __v) const\n{\n    value_type* __t = __vp_;\n    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)\n        *__t <<= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nslice_array<_Tp>::operator>>=(const _Expr& __v) const\n{\n    value_type* __t = __vp_;\n    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)\n        *__t >>= __v[__i];\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nslice_array<_Tp>::operator=(const value_type& __x) const\n{\n    value_type* __t = __vp_;\n    for (size_t __n = __size_; __n; --__n, __t += __stride_)\n        *__t = __x;\n}\n\n// gslice\n\nclass _LIBCPP_TYPE_VIS gslice\n{\n    valarray<size_t> __size_;\n    valarray<size_t> __stride_;\n    valarray<size_t> __1d_;\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    gslice() {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    gslice(size_t __start, const valarray<size_t>& __size,\n                           const valarray<size_t>& __stride)\n        : __size_(__size),\n          __stride_(__stride)\n        {__init(__start);}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    gslice(size_t __start, const valarray<size_t>&  __size,\n                                 valarray<size_t>&& __stride)\n        : __size_(__size),\n          __stride_(move(__stride))\n        {__init(__start);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    gslice(size_t __start,       valarray<size_t>&& __size,\n                           const valarray<size_t>&  __stride)\n        : __size_(move(__size)),\n          __stride_(__stride)\n        {__init(__start);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    gslice(size_t __start,       valarray<size_t>&& __size,\n                                 valarray<size_t>&& __stride)\n        : __size_(move(__size)),\n          __stride_(move(__stride))\n        {__init(__start);}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n//  gslice(const gslice&)            = default;\n//  gslice(gslice&&)                 = default;\n//  gslice& operator=(const gslice&) = default;\n//  gslice& operator=(gslice&&)      = default;\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t           start()  const {return __1d_.size() ? __1d_[0] : 0;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    valarray<size_t> size()   const {return __size_;}\n\n    _LIBCPP_INLINE_VISIBILITY\n    valarray<size_t> stride() const {return __stride_;}\n\nprivate:\n    void __init(size_t __start);\n\n    template <class> friend class gslice_array;\n    template <class> friend class valarray;\n    template <class> friend class __val_expr;\n};\n\n// gslice_array\n\ntemplate <class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY gslice_array\n{\npublic:\n    typedef _Tp value_type;\n\nprivate:\n    value_type*      __vp_;\n    valarray<size_t> __1d_;\n\npublic:\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator*=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator/=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator%=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator+=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator-=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator^=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator&=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator|=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator<<=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator>>=(const _Expr& __v) const;\n\n    const gslice_array& operator=(const gslice_array& __ga) const;\n\n    void operator=(const value_type& __x) const;\n\n//  gslice_array(const gslice_array&)            = default;\n//  gslice_array(gslice_array&&)                 = default;\n//  gslice_array& operator=(const gslice_array&) = default;\n//  gslice_array& operator=(gslice_array&&)      = default;\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    gslice_array(const gslice& __gs, const valarray<value_type>& __v)\n        : __vp_(const_cast<value_type*>(__v.__begin_)),\n          __1d_(__gs.__1d_)\n        {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    gslice_array(gslice&& __gs, const valarray<value_type>& __v)\n        : __vp_(const_cast<value_type*>(__v.__begin_)),\n          __1d_(move(__gs.__1d_))\n        {}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    template <class> friend class valarray;\n};\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\ngslice_array<_Tp>::operator=(const _Expr& __v) const\n{\n    typedef const size_t* _Ip;\n    size_t __j = 0;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)\n        __vp_[*__i] = __v[__j];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\ngslice_array<_Tp>::operator*=(const _Expr& __v) const\n{\n    typedef const size_t* _Ip;\n    size_t __j = 0;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)\n        __vp_[*__i] *= __v[__j];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\ngslice_array<_Tp>::operator/=(const _Expr& __v) const\n{\n    typedef const size_t* _Ip;\n    size_t __j = 0;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)\n        __vp_[*__i] /= __v[__j];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\ngslice_array<_Tp>::operator%=(const _Expr& __v) const\n{\n    typedef const size_t* _Ip;\n    size_t __j = 0;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)\n        __vp_[*__i] %= __v[__j];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\ngslice_array<_Tp>::operator+=(const _Expr& __v) const\n{\n    typedef const size_t* _Ip;\n    size_t __j = 0;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)\n        __vp_[*__i] += __v[__j];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\ngslice_array<_Tp>::operator-=(const _Expr& __v) const\n{\n    typedef const size_t* _Ip;\n    size_t __j = 0;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)\n        __vp_[*__i] -= __v[__j];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\ngslice_array<_Tp>::operator^=(const _Expr& __v) const\n{\n    typedef const size_t* _Ip;\n    size_t __j = 0;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)\n        __vp_[*__i] ^= __v[__j];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\ngslice_array<_Tp>::operator&=(const _Expr& __v) const\n{\n    typedef const size_t* _Ip;\n    size_t __j = 0;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)\n        __vp_[*__i] &= __v[__j];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\ngslice_array<_Tp>::operator|=(const _Expr& __v) const\n{\n    typedef const size_t* _Ip;\n    size_t __j = 0;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)\n        __vp_[*__i] |= __v[__j];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\ngslice_array<_Tp>::operator<<=(const _Expr& __v) const\n{\n    typedef const size_t* _Ip;\n    size_t __j = 0;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)\n        __vp_[*__i] <<= __v[__j];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\ngslice_array<_Tp>::operator>>=(const _Expr& __v) const\n{\n    typedef const size_t* _Ip;\n    size_t __j = 0;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)\n        __vp_[*__i] >>= __v[__j];\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconst gslice_array<_Tp>&\ngslice_array<_Tp>::operator=(const gslice_array& __ga) const\n{\n    typedef const size_t* _Ip;\n    const value_type* __s = __ga.__vp_;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_, __j = __ga.__1d_.__begin_;\n            __i != __e; ++__i, ++__j)\n        __vp_[*__i] = __s[*__j];\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\ngslice_array<_Tp>::operator=(const value_type& __x) const\n{\n    typedef const size_t* _Ip;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i)\n        __vp_[*__i] = __x;\n}\n\n// mask_array\n\ntemplate <class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY mask_array\n{\npublic:\n    typedef _Tp value_type;\n\nprivate:\n    value_type*      __vp_;\n    valarray<size_t> __1d_;\n\npublic:\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator*=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator/=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator%=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator+=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator-=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator^=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator&=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator|=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator<<=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator>>=(const _Expr& __v) const;\n\n    const mask_array& operator=(const mask_array& __ma) const;\n\n    void operator=(const value_type& __x) const;\n\n//  mask_array(const mask_array&)            = default;\n//  mask_array(mask_array&&)                 = default;\n//  mask_array& operator=(const mask_array&) = default;\n//  mask_array& operator=(mask_array&&)      = default;\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    mask_array(const valarray<bool>& __vb, const valarray<value_type>& __v)\n        : __vp_(const_cast<value_type*>(__v.__begin_)),\n          __1d_(static_cast<size_t>(count(__vb.__begin_, __vb.__end_, true)))\n          {\n              size_t __j = 0;\n              for (size_t __i = 0; __i < __vb.size(); ++__i)\n                  if (__vb[__i])\n                      __1d_[__j++] = __i;\n          }\n\n    template <class> friend class valarray;\n};\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nmask_array<_Tp>::operator=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] = __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nmask_array<_Tp>::operator*=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] *= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nmask_array<_Tp>::operator/=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] /= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nmask_array<_Tp>::operator%=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] %= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nmask_array<_Tp>::operator+=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] += __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nmask_array<_Tp>::operator-=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] -= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nmask_array<_Tp>::operator^=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] ^= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nmask_array<_Tp>::operator&=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] &= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nmask_array<_Tp>::operator|=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] |= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nmask_array<_Tp>::operator<<=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] <<= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nmask_array<_Tp>::operator>>=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] >>= __v[__i];\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconst mask_array<_Tp>&\nmask_array<_Tp>::operator=(const mask_array& __ma) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] = __ma.__vp_[__1d_[__i]];\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nmask_array<_Tp>::operator=(const value_type& __x) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] = __x;\n}\n\ntemplate <class _ValExpr>\nclass __mask_expr\n{\n    typedef typename remove_reference<_ValExpr>::type  _RmExpr;\npublic:\n    typedef typename _RmExpr::value_type value_type;\n    typedef value_type result_type;\n\nprivate:\n    _ValExpr __expr_;\n    valarray<size_t> __1d_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __mask_expr(const valarray<bool>& __vb, const _RmExpr& __e)\n        : __expr_(__e),\n          __1d_(static_cast<size_t>(count(__vb.__begin_, __vb.__end_, true)))\n          {\n              size_t __j = 0;\n              for (size_t __i = 0; __i < __vb.size(); ++__i)\n                  if (__vb[__i])\n                      __1d_[__j++] = __i;\n          }\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator[](size_t __i) const\n        {return __expr_[__1d_[__i]];}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const {return __1d_.size();}\n\n    template <class> friend class valarray;\n};\n\n// indirect_array\n\ntemplate <class _Tp>\nclass _LIBCPP_TYPE_VIS_ONLY indirect_array\n{\npublic:\n    typedef _Tp value_type;\n\nprivate:\n    value_type*      __vp_;\n    valarray<size_t> __1d_;\n\npublic:\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator*=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator/=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator%=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator+=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator-=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator^=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator&=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator|=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator<<=(const _Expr& __v) const;\n\n    template <class _Expr>\n    typename enable_if\n    <\n        __is_val_expr<_Expr>::value,\n        void\n    >::type\n    operator>>=(const _Expr& __v) const;\n\n    const indirect_array& operator=(const indirect_array& __ia) const;\n\n    void operator=(const value_type& __x) const;\n\n//  indirect_array(const indirect_array&)            = default;\n//  indirect_array(indirect_array&&)                 = default;\n//  indirect_array& operator=(const indirect_array&) = default;\n//  indirect_array& operator=(indirect_array&&)      = default;\n\nprivate:\n     _LIBCPP_INLINE_VISIBILITY\n   indirect_array(const valarray<size_t>& __ia, const valarray<value_type>& __v)\n        : __vp_(const_cast<value_type*>(__v.__begin_)),\n          __1d_(__ia)\n        {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    indirect_array(valarray<size_t>&& __ia, const valarray<value_type>& __v)\n        : __vp_(const_cast<value_type*>(__v.__begin_)),\n          __1d_(move(__ia))\n        {}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    template <class> friend class valarray;\n};\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nindirect_array<_Tp>::operator=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] = __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nindirect_array<_Tp>::operator*=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] *= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nindirect_array<_Tp>::operator/=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] /= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nindirect_array<_Tp>::operator%=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] %= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nindirect_array<_Tp>::operator+=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] += __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nindirect_array<_Tp>::operator-=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] -= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nindirect_array<_Tp>::operator^=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] ^= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nindirect_array<_Tp>::operator&=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] &= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nindirect_array<_Tp>::operator|=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] |= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nindirect_array<_Tp>::operator<<=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] <<= __v[__i];\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    void\n>::type\nindirect_array<_Tp>::operator>>=(const _Expr& __v) const\n{\n    size_t __n = __1d_.size();\n    for (size_t __i = 0; __i < __n; ++__i)\n        __vp_[__1d_[__i]] >>= __v[__i];\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconst indirect_array<_Tp>&\nindirect_array<_Tp>::operator=(const indirect_array& __ia) const\n{\n    typedef const size_t* _Ip;\n    const value_type* __s = __ia.__vp_;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_, __j = __ia.__1d_.__begin_;\n            __i != __e; ++__i, ++__j)\n        __vp_[*__i] = __s[*__j];\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nindirect_array<_Tp>::operator=(const value_type& __x) const\n{\n    typedef const size_t* _Ip;\n    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i)\n        __vp_[*__i] = __x;\n}\n\ntemplate <class _ValExpr>\nclass __indirect_expr\n{\n    typedef typename remove_reference<_ValExpr>::type  _RmExpr;\npublic:\n    typedef typename _RmExpr::value_type value_type;\n    typedef value_type result_type;\n\nprivate:\n    _ValExpr __expr_;\n    valarray<size_t> __1d_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    __indirect_expr(const valarray<size_t>& __ia, const _RmExpr& __e)\n        : __expr_(__e),\n          __1d_(__ia)\n          {}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n    _LIBCPP_INLINE_VISIBILITY\n    __indirect_expr(valarray<size_t>&& __ia, const _RmExpr& __e)\n        : __expr_(__e),\n          __1d_(move(__ia))\n          {}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator[](size_t __i) const\n        {return __expr_[__1d_[__i]];}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const {return __1d_.size();}\n\n    template <class> friend class _LIBCPP_TYPE_VIS_ONLY valarray;\n};\n\ntemplate<class _ValExpr>\nclass __val_expr\n{\n    typedef typename remove_reference<_ValExpr>::type  _RmExpr;\n\n    _ValExpr __expr_;\npublic:\n    typedef typename _RmExpr::value_type value_type;\n    typedef typename _RmExpr::result_type result_type;\n\n    _LIBCPP_INLINE_VISIBILITY\n    explicit __val_expr(const _RmExpr& __e) : __expr_(__e) {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type operator[](size_t __i) const\n        {return __expr_[__i];}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __val_expr<__slice_expr<_ValExpr> > operator[](slice __s) const\n        {return __val_expr<__slice_expr<_ValExpr> >(__expr_, __s);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __val_expr<__indirect_expr<_ValExpr> > operator[](const gslice& __gs) const\n        {return __val_expr<__indirect_expr<_ValExpr> >(__expr_, __gs.__1d_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __val_expr<__mask_expr<_ValExpr> > operator[](const valarray<bool>& __vb) const\n        {return __val_expr<__mask_expr<_ValExpr> >(__expr_, __vb);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __val_expr<__indirect_expr<_ValExpr> > operator[](const valarray<size_t>& __vs) const\n        {return __val_expr<__indirect_expr<_ValExpr> >(__expr_, __vs);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __val_expr<_UnaryOp<__unary_plus<value_type>, _ValExpr> >\n    operator+() const\n    {\n        typedef _UnaryOp<__unary_plus<value_type>, _ValExpr> _NewExpr;\n        return __val_expr<_NewExpr>(_NewExpr(__unary_plus<value_type>(), __expr_));\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __val_expr<_UnaryOp<negate<value_type>, _ValExpr> >\n    operator-() const\n    {\n        typedef _UnaryOp<negate<value_type>, _ValExpr> _NewExpr;\n        return __val_expr<_NewExpr>(_NewExpr(negate<value_type>(), __expr_));\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __val_expr<_UnaryOp<__bit_not<value_type>, _ValExpr> >\n    operator~() const\n    {\n        typedef _UnaryOp<__bit_not<value_type>, _ValExpr> _NewExpr;\n        return __val_expr<_NewExpr>(_NewExpr(__bit_not<value_type>(), __expr_));\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __val_expr<_UnaryOp<logical_not<value_type>, _ValExpr> >\n    operator!() const\n    {\n        typedef _UnaryOp<logical_not<value_type>, _ValExpr> _NewExpr;\n        return __val_expr<_NewExpr>(_NewExpr(logical_not<value_type>(), __expr_));\n    }\n\n    operator valarray<result_type>() const;\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_t size() const {return __expr_.size();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type sum() const\n    {\n        size_t __n = __expr_.size();\n        result_type __r = __n ? __expr_[0] : result_type();\n        for (size_t __i = 1; __i < __n; ++__i)\n            __r += __expr_[__i];\n        return __r;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type min() const\n    {\n        size_t __n = size();\n        result_type __r = __n ? (*this)[0] : result_type();\n        for (size_t __i = 1; __i < __n; ++__i)\n        {\n            result_type __x = __expr_[__i];\n            if (__x < __r)\n                __r = __x;\n        }\n        return __r;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    result_type max() const\n    {\n        size_t __n = size();\n        result_type __r = __n ? (*this)[0] : result_type();\n        for (size_t __i = 1; __i < __n; ++__i)\n        {\n            result_type __x = __expr_[__i];\n            if (__r < __x)\n                __r = __x;\n        }\n        return __r;\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __val_expr<__shift_expr<_ValExpr> > shift (int __i) const\n        {return __val_expr<__shift_expr<_ValExpr> >(__shift_expr<_ValExpr>(__i, __expr_));}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __val_expr<__cshift_expr<_ValExpr> > cshift(int __i) const\n        {return __val_expr<__cshift_expr<_ValExpr> >(__cshift_expr<_ValExpr>(__i, __expr_));}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __val_expr<_UnaryOp<__apply_expr<value_type, value_type(*)(value_type)>, _ValExpr> >\n    apply(value_type __f(value_type)) const\n    {\n        typedef __apply_expr<value_type, value_type(*)(value_type)> _Op;\n        typedef _UnaryOp<_Op, _ValExpr> _NewExpr;\n        return __val_expr<_NewExpr>(_NewExpr(_Op(__f), __expr_));\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    __val_expr<_UnaryOp<__apply_expr<value_type, value_type(*)(const value_type&)>, _ValExpr> >\n    apply(value_type __f(const value_type&)) const\n    {\n        typedef __apply_expr<value_type, value_type(*)(const value_type&)> _Op;\n        typedef _UnaryOp<_Op, _ValExpr> _NewExpr;\n        return __val_expr<_NewExpr>(_NewExpr(_Op(__f), __expr_));\n    }\n};\n\ntemplate<class _ValExpr>\n__val_expr<_ValExpr>::operator valarray<__val_expr::result_type>() const\n{\n    valarray<result_type> __r;\n    size_t __n = __expr_.size();\n    if (__n)\n    {\n        __r.__begin_ =\n            __r.__end_ =\n                static_cast<result_type*>(_VSTD::__allocate(__n * sizeof(result_type)));\n        for (size_t __i = 0; __i != __n; ++__r.__end_, ++__i)\n            ::new (__r.__end_) result_type(__expr_[__i]);\n    }\n    return __r;\n}\n\n// valarray\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>::valarray(size_t __n)\n    : __begin_(0),\n      __end_(0)\n{\n    resize(__n);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>::valarray(const value_type& __x, size_t __n)\n    : __begin_(0),\n      __end_(0)\n{\n    resize(__n, __x);\n}\n\ntemplate <class _Tp>\nvalarray<_Tp>::valarray(const value_type* __p, size_t __n)\n    : __begin_(0),\n      __end_(0)\n{\n    if (__n)\n    {\n        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (; __n; ++__end_, ++__p, --__n)\n                ::new (__end_) value_type(*__p);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            resize(0);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n}\n\ntemplate <class _Tp>\nvalarray<_Tp>::valarray(const valarray& __v)\n    : __begin_(0),\n      __end_(0)\n{\n    if (__v.size())\n    {\n        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__v.size() * sizeof(value_type)));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (value_type* __p = __v.__begin_; __p != __v.__end_; ++__end_, ++__p)\n                ::new (__end_) value_type(*__p);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            resize(0);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>::valarray(valarray&& __v) _NOEXCEPT\n    : __begin_(__v.__begin_),\n      __end_(__v.__end_)\n{\n    __v.__begin_ = __v.__end_ = nullptr;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp>\nvalarray<_Tp>::valarray(initializer_list<value_type> __il)\n    : __begin_(0),\n      __end_(0)\n{\n    size_t __n = __il.size();\n    if (__n)\n    {\n        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (const value_type* __p = __il.begin(); __n; ++__end_, ++__p, --__n)\n                ::new (__end_) value_type(*__p);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            resize(0);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp>\nvalarray<_Tp>::valarray(const slice_array<value_type>& __sa)\n    : __begin_(0),\n      __end_(0)\n{\n    size_t __n = __sa.__size_;\n    if (__n)\n    {\n        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (const value_type* __p = __sa.__vp_; __n; ++__end_, __p += __sa.__stride_, --__n)\n                ::new (__end_) value_type(*__p);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            resize(0);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n}\n\ntemplate <class _Tp>\nvalarray<_Tp>::valarray(const gslice_array<value_type>& __ga)\n    : __begin_(0),\n      __end_(0)\n{\n    size_t __n = __ga.__1d_.size();\n    if (__n)\n    {\n        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            typedef const size_t* _Ip;\n            const value_type* __s = __ga.__vp_;\n            for (_Ip __i = __ga.__1d_.__begin_, __e = __ga.__1d_.__end_;\n                    __i != __e; ++__i, ++__end_)\n                ::new (__end_) value_type(__s[*__i]);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            resize(0);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n}\n\ntemplate <class _Tp>\nvalarray<_Tp>::valarray(const mask_array<value_type>& __ma)\n    : __begin_(0),\n      __end_(0)\n{\n    size_t __n = __ma.__1d_.size();\n    if (__n)\n    {\n        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            typedef const size_t* _Ip;\n            const value_type* __s = __ma.__vp_;\n            for (_Ip __i = __ma.__1d_.__begin_, __e = __ma.__1d_.__end_;\n                    __i != __e; ++__i, ++__end_)\n                ::new (__end_) value_type(__s[*__i]);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            resize(0);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n}\n\ntemplate <class _Tp>\nvalarray<_Tp>::valarray(const indirect_array<value_type>& __ia)\n    : __begin_(0),\n      __end_(0)\n{\n    size_t __n = __ia.__1d_.size();\n    if (__n)\n    {\n        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            typedef const size_t* _Ip;\n            const value_type* __s = __ia.__vp_;\n            for (_Ip __i = __ia.__1d_.__begin_, __e = __ia.__1d_.__end_;\n                    __i != __e; ++__i, ++__end_)\n                ::new (__end_) value_type(__s[*__i]);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            resize(0);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>::~valarray()\n{\n    resize(0);\n}\n\ntemplate <class _Tp>\nvalarray<_Tp>&\nvalarray<_Tp>::operator=(const valarray& __v)\n{\n    if (this != &__v)\n    {\n        if (size() != __v.size())\n            resize(__v.size());\n        _VSTD::copy(__v.__begin_, __v.__end_, __begin_);\n    }\n    return *this;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator=(valarray&& __v) _NOEXCEPT\n{\n    resize(0);\n    __begin_ = __v.__begin_;\n    __end_ = __v.__end_;\n    __v.__begin_ = nullptr;\n    __v.__end_ = nullptr;\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator=(initializer_list<value_type> __il)\n{\n    if (size() != __il.size())\n        resize(__il.size());\n    _VSTD::copy(__il.begin(), __il.end(), __begin_);\n    return *this;\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator=(const value_type& __x)\n{\n    _VSTD::fill(__begin_, __end_, __x);\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator=(const slice_array<value_type>& __sa)\n{\n    value_type* __t = __begin_;\n    const value_type* __s = __sa.__vp_;\n    for (size_t __n = __sa.__size_; __n; --__n, __s += __sa.__stride_, ++__t)\n        *__t = *__s;\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator=(const gslice_array<value_type>& __ga)\n{\n    typedef const size_t* _Ip;\n    value_type* __t = __begin_;\n    const value_type* __s = __ga.__vp_;\n    for (_Ip __i = __ga.__1d_.__begin_, __e = __ga.__1d_.__end_;\n                    __i != __e; ++__i, ++__t)\n        *__t = __s[*__i];\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator=(const mask_array<value_type>& __ma)\n{\n    typedef const size_t* _Ip;\n    value_type* __t = __begin_;\n    const value_type* __s = __ma.__vp_;\n    for (_Ip __i = __ma.__1d_.__begin_, __e = __ma.__1d_.__end_;\n                    __i != __e; ++__i, ++__t)\n        *__t = __s[*__i];\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator=(const indirect_array<value_type>& __ia)\n{\n    typedef const size_t* _Ip;\n    value_type* __t = __begin_;\n    const value_type* __s = __ia.__vp_;\n    for (_Ip __i = __ia.__1d_.__begin_, __e = __ia.__1d_.__end_;\n                    __i != __e; ++__i, ++__t)\n        *__t = __s[*__i];\n    return *this;\n}\n\ntemplate <class _Tp>\ntemplate <class _ValExpr>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator=(const __val_expr<_ValExpr>& __v)\n{\n    size_t __n = __v.size();\n    if (size() != __n)\n        resize(__n);\n    value_type* __t = __begin_;\n    for (size_t __i = 0; __i != __n; ++__t, ++__i)\n        *__t = result_type(__v[__i]);\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n__val_expr<__slice_expr<const valarray<_Tp>&> >\nvalarray<_Tp>::operator[](slice __s) const\n{\n    return __val_expr<__slice_expr<const valarray&> >(__slice_expr<const valarray&>(__s, *this));\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nslice_array<_Tp>\nvalarray<_Tp>::operator[](slice __s)\n{\n    return slice_array<value_type>(__s, *this);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n__val_expr<__indirect_expr<const valarray<_Tp>&> >\nvalarray<_Tp>::operator[](const gslice& __gs) const\n{\n    return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(__gs.__1d_, *this));\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ngslice_array<_Tp>\nvalarray<_Tp>::operator[](const gslice& __gs)\n{\n    return gslice_array<value_type>(__gs, *this);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n__val_expr<__indirect_expr<const valarray<_Tp>&> >\nvalarray<_Tp>::operator[](gslice&& __gs) const\n{\n    return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(move(__gs.__1d_), *this));\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\ngslice_array<_Tp>\nvalarray<_Tp>::operator[](gslice&& __gs)\n{\n    return gslice_array<value_type>(move(__gs), *this);\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n__val_expr<__mask_expr<const valarray<_Tp>&> >\nvalarray<_Tp>::operator[](const valarray<bool>& __vb) const\n{\n    return __val_expr<__mask_expr<const valarray&> >(__mask_expr<const valarray&>(__vb, *this));\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nmask_array<_Tp>\nvalarray<_Tp>::operator[](const valarray<bool>& __vb)\n{\n    return mask_array<value_type>(__vb, *this);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n__val_expr<__mask_expr<const valarray<_Tp>&> >\nvalarray<_Tp>::operator[](valarray<bool>&& __vb) const\n{\n    return __val_expr<__mask_expr<const valarray&> >(__mask_expr<const valarray&>(move(__vb), *this));\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nmask_array<_Tp>\nvalarray<_Tp>::operator[](valarray<bool>&& __vb)\n{\n    return mask_array<value_type>(move(__vb), *this);\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n__val_expr<__indirect_expr<const valarray<_Tp>&> >\nvalarray<_Tp>::operator[](const valarray<size_t>& __vs) const\n{\n    return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(__vs, *this));\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nindirect_array<_Tp>\nvalarray<_Tp>::operator[](const valarray<size_t>& __vs)\n{\n    return indirect_array<value_type>(__vs, *this);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n__val_expr<__indirect_expr<const valarray<_Tp>&> >\nvalarray<_Tp>::operator[](valarray<size_t>&& __vs) const\n{\n    return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(move(__vs), *this));\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nindirect_array<_Tp>\nvalarray<_Tp>::operator[](valarray<size_t>&& __vs)\n{\n    return indirect_array<value_type>(move(__vs), *this);\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp>\nvalarray<_Tp>\nvalarray<_Tp>::operator+() const\n{\n    valarray<value_type> __r;\n    size_t __n = size();\n    if (__n)\n    {\n        __r.__begin_ =\n            __r.__end_ =\n                static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));\n        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)\n            ::new (__r.__end_) value_type(+*__p);\n    }\n    return __r;\n}\n\ntemplate <class _Tp>\nvalarray<_Tp>\nvalarray<_Tp>::operator-() const\n{\n    valarray<value_type> __r;\n    size_t __n = size();\n    if (__n)\n    {\n        __r.__begin_ =\n            __r.__end_ =\n                static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));\n        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)\n            ::new (__r.__end_) value_type(-*__p);\n    }\n    return __r;\n}\n\ntemplate <class _Tp>\nvalarray<_Tp>\nvalarray<_Tp>::operator~() const\n{\n    valarray<value_type> __r;\n    size_t __n = size();\n    if (__n)\n    {\n        __r.__begin_ =\n            __r.__end_ =\n                static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));\n        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)\n            ::new (__r.__end_) value_type(~*__p);\n    }\n    return __r;\n}\n\ntemplate <class _Tp>\nvalarray<bool>\nvalarray<_Tp>::operator!() const\n{\n    valarray<bool> __r;\n    size_t __n = size();\n    if (__n)\n    {\n        __r.__begin_ =\n            __r.__end_ =\n                static_cast<bool*>(_VSTD::__allocate(__n * sizeof(bool)));\n        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)\n            ::new (__r.__end_) bool(!*__p);\n    }\n    return __r;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator*=(const value_type& __x)\n{\n    for (value_type* __p = __begin_; __p != __end_; ++__p)\n        *__p *= __x;\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator/=(const value_type& __x)\n{\n    for (value_type* __p = __begin_; __p != __end_; ++__p)\n        *__p /= __x;\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator%=(const value_type& __x)\n{\n    for (value_type* __p = __begin_; __p != __end_; ++__p)\n        *__p %= __x;\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator+=(const value_type& __x)\n{\n    for (value_type* __p = __begin_; __p != __end_; ++__p)\n        *__p += __x;\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator-=(const value_type& __x)\n{\n    for (value_type* __p = __begin_; __p != __end_; ++__p)\n        *__p -= __x;\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator^=(const value_type& __x)\n{\n    for (value_type* __p = __begin_; __p != __end_; ++__p)\n        *__p ^= __x;\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator&=(const value_type& __x)\n{\n    for (value_type* __p = __begin_; __p != __end_; ++__p)\n        *__p &= __x;\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator|=(const value_type& __x)\n{\n    for (value_type* __p = __begin_; __p != __end_; ++__p)\n        *__p |= __x;\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator<<=(const value_type& __x)\n{\n    for (value_type* __p = __begin_; __p != __end_; ++__p)\n        *__p <<= __x;\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvalarray<_Tp>&\nvalarray<_Tp>::operator>>=(const value_type& __x)\n{\n    for (value_type* __p = __begin_; __p != __end_; ++__p)\n        *__p >>= __x;\n    return *this;\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    valarray<_Tp>&\n>::type\nvalarray<_Tp>::operator*=(const _Expr& __v)\n{\n    size_t __i = 0;\n    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)\n        *__t *= __v[__i];\n    return *this;\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    valarray<_Tp>&\n>::type\nvalarray<_Tp>::operator/=(const _Expr& __v)\n{\n    size_t __i = 0;\n    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)\n        *__t /= __v[__i];\n    return *this;\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    valarray<_Tp>&\n>::type\nvalarray<_Tp>::operator%=(const _Expr& __v)\n{\n    size_t __i = 0;\n    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)\n        *__t %= __v[__i];\n    return *this;\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    valarray<_Tp>&\n>::type\nvalarray<_Tp>::operator+=(const _Expr& __v)\n{\n    size_t __i = 0;\n    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)\n        *__t += __v[__i];\n    return *this;\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    valarray<_Tp>&\n>::type\nvalarray<_Tp>::operator-=(const _Expr& __v)\n{\n    size_t __i = 0;\n    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)\n        *__t -= __v[__i];\n    return *this;\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    valarray<_Tp>&\n>::type\nvalarray<_Tp>::operator^=(const _Expr& __v)\n{\n    size_t __i = 0;\n    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)\n        *__t ^= __v[__i];\n    return *this;\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    valarray<_Tp>&\n>::type\nvalarray<_Tp>::operator|=(const _Expr& __v)\n{\n    size_t __i = 0;\n    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)\n        *__t |= __v[__i];\n    return *this;\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    valarray<_Tp>&\n>::type\nvalarray<_Tp>::operator&=(const _Expr& __v)\n{\n    size_t __i = 0;\n    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)\n        *__t &= __v[__i];\n    return *this;\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    valarray<_Tp>&\n>::type\nvalarray<_Tp>::operator<<=(const _Expr& __v)\n{\n    size_t __i = 0;\n    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)\n        *__t <<= __v[__i];\n    return *this;\n}\n\ntemplate <class _Tp>\ntemplate <class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    valarray<_Tp>&\n>::type\nvalarray<_Tp>::operator>>=(const _Expr& __v)\n{\n    size_t __i = 0;\n    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)\n        *__t >>= __v[__i];\n    return *this;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nvalarray<_Tp>::swap(valarray& __v) _NOEXCEPT\n{\n    _VSTD::swap(__begin_, __v.__begin_);\n    _VSTD::swap(__end_, __v.__end_);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\nvalarray<_Tp>::sum() const\n{\n    if (__begin_ == __end_)\n        return value_type();\n    const value_type* __p = __begin_;\n    _Tp __r = *__p;\n    for (++__p; __p != __end_; ++__p)\n        __r += *__p;\n    return __r;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\nvalarray<_Tp>::min() const\n{\n    if (__begin_ == __end_)\n        return value_type();\n    return *_VSTD::min_element(__begin_, __end_);\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp\nvalarray<_Tp>::max() const\n{\n    if (__begin_ == __end_)\n        return value_type();\n    return *_VSTD::max_element(__begin_, __end_);\n}\n\ntemplate <class _Tp>\nvalarray<_Tp>\nvalarray<_Tp>::shift(int __i) const\n{\n    valarray<value_type> __r;\n    size_t __n = size();\n    if (__n)\n    {\n        __r.__begin_ =\n            __r.__end_ =\n                static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));\n        const value_type* __sb;\n        value_type* __tb;\n        value_type* __te;\n        if (__i >= 0)\n        {\n            __i = _VSTD::min(__i, static_cast<int>(__n));\n            __sb = __begin_ + __i;\n            __tb = __r.__begin_;\n            __te = __r.__begin_ + (__n - __i);\n        }\n        else\n        {\n            __i = _VSTD::min(-__i, static_cast<int>(__n));\n            __sb = __begin_;\n            __tb = __r.__begin_ + __i;\n            __te = __r.__begin_ + __n;\n        }\n        for (; __r.__end_ != __tb; ++__r.__end_)\n            ::new (__r.__end_) value_type();\n        for (; __r.__end_ != __te; ++__r.__end_, ++__sb)\n            ::new (__r.__end_) value_type(*__sb);\n        for (__te = __r.__begin_ + __n; __r.__end_ != __te; ++__r.__end_)\n            ::new (__r.__end_) value_type();\n    }\n    return __r;\n}\n\ntemplate <class _Tp>\nvalarray<_Tp>\nvalarray<_Tp>::cshift(int __i) const\n{\n    valarray<value_type> __r;\n    size_t __n = size();\n    if (__n)\n    {\n        __r.__begin_ =\n            __r.__end_ =\n                static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));\n        __i %= static_cast<int>(__n);\n        const value_type* __m = __i >= 0 ? __begin_ + __i : __end_ + __i;\n        for (const value_type* __s = __m; __s != __end_; ++__r.__end_, ++__s)\n            ::new (__r.__end_) value_type(*__s);\n        for (const value_type* __s = __begin_; __s != __m; ++__r.__end_, ++__s)\n            ::new (__r.__end_) value_type(*__s);\n    }\n    return __r;\n}\n\ntemplate <class _Tp>\nvalarray<_Tp>\nvalarray<_Tp>::apply(value_type __f(value_type)) const\n{\n    valarray<value_type> __r;\n    size_t __n = size();\n    if (__n)\n    {\n        __r.__begin_ =\n            __r.__end_ =\n                static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));\n        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)\n            ::new (__r.__end_) value_type(__f(*__p));\n    }\n    return __r;\n}\n\ntemplate <class _Tp>\nvalarray<_Tp>\nvalarray<_Tp>::apply(value_type __f(const value_type&)) const\n{\n    valarray<value_type> __r;\n    size_t __n = size();\n    if (__n)\n    {\n        __r.__begin_ =\n            __r.__end_ =\n                static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));\n        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)\n            ::new (__r.__end_) value_type(__f(*__p));\n    }\n    return __r;\n}\n\ntemplate <class _Tp>\nvoid\nvalarray<_Tp>::resize(size_t __n, value_type __x)\n{\n    if (__begin_ != nullptr)\n    {\n        while (__end_ != __begin_)\n            (--__end_)->~value_type();\n        _VSTD::__deallocate(__begin_);\n        __begin_ = __end_ = nullptr;\n    }\n    if (__n)\n    {\n        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            for (; __n; --__n, ++__end_)\n                ::new (__end_) value_type(__x);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            resize(0);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n}\n\ntemplate<class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(valarray<_Tp>& __x, valarray<_Tp>& __y) _NOEXCEPT\n{\n    __x.swap(__y);\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<multiplies<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator*(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<multiplies<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(multiplies<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<multiplies<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator*(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<multiplies<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(multiplies<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<multiplies<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator*(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<multiplies<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(multiplies<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<divides<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator/(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<divides<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(divides<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<divides<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator/(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<divides<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(divides<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<divides<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator/(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<divides<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(divides<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<modulus<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator%(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<modulus<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(modulus<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<modulus<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator%(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<modulus<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(modulus<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<modulus<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator%(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<modulus<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(modulus<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<plus<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator+(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<plus<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(plus<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<plus<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator+(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<plus<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(plus<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<plus<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator+(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<plus<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(plus<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<minus<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator-(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<minus<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(minus<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<minus<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator-(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<minus<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(minus<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<minus<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator-(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<minus<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(minus<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<bit_xor<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator^(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<bit_xor<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(bit_xor<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<bit_xor<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator^(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<bit_xor<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(bit_xor<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<bit_xor<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator^(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<bit_xor<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(bit_xor<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<bit_and<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator&(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<bit_and<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(bit_and<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<bit_and<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator&(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<bit_and<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(bit_and<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<bit_and<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator&(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<bit_and<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(bit_and<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<bit_or<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator|(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<bit_or<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(bit_or<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<bit_or<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator|(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<bit_or<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(bit_or<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<bit_or<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator|(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<bit_or<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(bit_or<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<__bit_shift_left<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator<<(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<__bit_shift_left<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(__bit_shift_left<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<__bit_shift_left<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator<<(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<__bit_shift_left<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(__bit_shift_left<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<__bit_shift_left<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator<<(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<__bit_shift_left<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__bit_shift_left<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<__bit_shift_right<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator>>(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<__bit_shift_right<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(__bit_shift_right<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<__bit_shift_right<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator>>(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<__bit_shift_right<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(__bit_shift_right<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<__bit_shift_right<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator>>(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<__bit_shift_right<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__bit_shift_right<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<logical_and<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator&&(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<logical_and<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(logical_and<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<logical_and<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator&&(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<logical_and<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(logical_and<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<logical_and<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator&&(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<logical_and<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(logical_and<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<logical_or<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator||(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<logical_or<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(logical_or<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<logical_or<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator||(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<logical_or<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(logical_or<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<logical_or<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator||(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<logical_or<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(logical_or<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<equal_to<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator==(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<equal_to<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(equal_to<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<equal_to<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator==(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<equal_to<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(equal_to<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<equal_to<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator==(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<equal_to<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(equal_to<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<not_equal_to<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator!=(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<not_equal_to<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(not_equal_to<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<not_equal_to<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator!=(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<not_equal_to<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(not_equal_to<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<not_equal_to<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator!=(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<not_equal_to<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(not_equal_to<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<less<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator<(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<less<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(less<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<less<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator<(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<less<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(less<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<less<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator<(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<less<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(less<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<greater<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator>(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<greater<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(greater<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<greater<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator>(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<greater<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(greater<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<greater<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator>(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<greater<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(greater<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<less_equal<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator<=(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<less_equal<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(less_equal<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<less_equal<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator<=(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<less_equal<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(less_equal<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<less_equal<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator<=(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<less_equal<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(less_equal<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<greater_equal<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\noperator>=(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<greater_equal<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(greater_equal<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<greater_equal<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\noperator>=(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<greater_equal<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(greater_equal<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<greater_equal<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\noperator>=(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<greater_equal<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(greater_equal<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_UnaryOp<__abs_expr<typename _Expr::value_type>, _Expr> >\n>::type\nabs(const _Expr& __x)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _UnaryOp<__abs_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__abs_expr<value_type>(), __x));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_UnaryOp<__acos_expr<typename _Expr::value_type>, _Expr> >\n>::type\nacos(const _Expr& __x)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _UnaryOp<__acos_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__acos_expr<value_type>(), __x));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_UnaryOp<__asin_expr<typename _Expr::value_type>, _Expr> >\n>::type\nasin(const _Expr& __x)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _UnaryOp<__asin_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__asin_expr<value_type>(), __x));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_UnaryOp<__atan_expr<typename _Expr::value_type>, _Expr> >\n>::type\natan(const _Expr& __x)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _UnaryOp<__atan_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__atan_expr<value_type>(), __x));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<__atan2_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\natan2(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<__atan2_expr<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(__atan2_expr<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<__atan2_expr<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\natan2(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<__atan2_expr<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(__atan2_expr<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<__atan2_expr<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\natan2(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<__atan2_expr<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__atan2_expr<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_UnaryOp<__cos_expr<typename _Expr::value_type>, _Expr> >\n>::type\ncos(const _Expr& __x)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _UnaryOp<__cos_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__cos_expr<value_type>(), __x));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_UnaryOp<__cosh_expr<typename _Expr::value_type>, _Expr> >\n>::type\ncosh(const _Expr& __x)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _UnaryOp<__cosh_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__cosh_expr<value_type>(), __x));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_UnaryOp<__exp_expr<typename _Expr::value_type>, _Expr> >\n>::type\nexp(const _Expr& __x)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _UnaryOp<__exp_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__exp_expr<value_type>(), __x));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_UnaryOp<__log_expr<typename _Expr::value_type>, _Expr> >\n>::type\nlog(const _Expr& __x)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _UnaryOp<__log_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__log_expr<value_type>(), __x));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_UnaryOp<__log10_expr<typename _Expr::value_type>, _Expr> >\n>::type\nlog10(const _Expr& __x)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _UnaryOp<__log10_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__log10_expr<value_type>(), __x));\n}\n\ntemplate<class _Expr1, class _Expr2>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,\n    __val_expr<_BinaryOp<__pow_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >\n>::type\npow(const _Expr1& __x, const _Expr2& __y)\n{\n    typedef typename _Expr1::value_type value_type;\n    typedef _BinaryOp<__pow_expr<value_type>, _Expr1, _Expr2> _Op;\n    return __val_expr<_Op>(_Op(__pow_expr<value_type>(), __x, __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<__pow_expr<typename _Expr::value_type>,\n               _Expr, __scalar_expr<typename _Expr::value_type> > >\n>::type\npow(const _Expr& __x, const typename _Expr::value_type& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<__pow_expr<value_type>, _Expr, __scalar_expr<value_type> > _Op;\n    return __val_expr<_Op>(_Op(__pow_expr<value_type>(),\n                           __x, __scalar_expr<value_type>(__y, __x.size())));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_BinaryOp<__pow_expr<typename _Expr::value_type>,\n               __scalar_expr<typename _Expr::value_type>, _Expr> >\n>::type\npow(const typename _Expr::value_type& __x, const _Expr& __y)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _BinaryOp<__pow_expr<value_type>, __scalar_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__pow_expr<value_type>(),\n                           __scalar_expr<value_type>(__x, __y.size()), __y));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_UnaryOp<__sin_expr<typename _Expr::value_type>, _Expr> >\n>::type\nsin(const _Expr& __x)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _UnaryOp<__sin_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__sin_expr<value_type>(), __x));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_UnaryOp<__sinh_expr<typename _Expr::value_type>, _Expr> >\n>::type\nsinh(const _Expr& __x)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _UnaryOp<__sinh_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__sinh_expr<value_type>(), __x));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_UnaryOp<__sqrt_expr<typename _Expr::value_type>, _Expr> >\n>::type\nsqrt(const _Expr& __x)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _UnaryOp<__sqrt_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__sqrt_expr<value_type>(), __x));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_UnaryOp<__tan_expr<typename _Expr::value_type>, _Expr> >\n>::type\ntan(const _Expr& __x)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _UnaryOp<__tan_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__tan_expr<value_type>(), __x));\n}\n\ntemplate<class _Expr>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if\n<\n    __is_val_expr<_Expr>::value,\n    __val_expr<_UnaryOp<__tanh_expr<typename _Expr::value_type>, _Expr> >\n>::type\ntanh(const _Expr& __x)\n{\n    typedef typename _Expr::value_type value_type;\n    typedef _UnaryOp<__tanh_expr<value_type>, _Expr> _Op;\n    return __val_expr<_Op>(_Op(__tanh_expr<value_type>(), __x));\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp*\nbegin(valarray<_Tp>& __v)\n{\n    return __v.__begin_;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconst _Tp*\nbegin(const valarray<_Tp>& __v)\n{\n    return __v.__begin_;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\n_Tp*\nend(valarray<_Tp>& __v)\n{\n    return __v.__end_;\n}\n\ntemplate <class _Tp>\ninline _LIBCPP_INLINE_VISIBILITY\nconst _Tp*\nend(const valarray<_Tp>& __v)\n{\n    return __v.__end_;\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_VALARRAY\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/include/vector",
    "content": "// -*- C++ -*-\n//===------------------------------ vector --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_VECTOR\n#define _LIBCPP_VECTOR\n\n/*\n    vector synopsis\n\nnamespace std\n{\n\ntemplate <class T, class Allocator = allocator<T> >\nclass vector\n{\npublic:\n    typedef T                                        value_type;\n    typedef Allocator                                allocator_type;\n    typedef typename allocator_type::reference       reference;\n    typedef typename allocator_type::const_reference const_reference;\n    typedef implementation-defined                   iterator;\n    typedef implementation-defined                   const_iterator;\n    typedef typename allocator_type::size_type       size_type;\n    typedef typename allocator_type::difference_type difference_type;\n    typedef typename allocator_type::pointer         pointer;\n    typedef typename allocator_type::const_pointer   const_pointer;\n    typedef std::reverse_iterator<iterator>          reverse_iterator;\n    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;\n\n    vector()\n        noexcept(is_nothrow_default_constructible<allocator_type>::value);\n    explicit vector(const allocator_type&);\n    explicit vector(size_type n);\n    explicit vector(size_type n, const allocator_type&); // C++14\n    vector(size_type n, const value_type& value, const allocator_type& = allocator_type());\n    template <class InputIterator>\n        vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type());\n    vector(const vector& x);\n    vector(vector&& x)\n        noexcept(is_nothrow_move_constructible<allocator_type>::value);\n    vector(initializer_list<value_type> il);\n    vector(initializer_list<value_type> il, const allocator_type& a);\n    ~vector();\n    vector& operator=(const vector& x);\n    vector& operator=(vector&& x)\n        noexcept(\n             allocator_type::propagate_on_container_move_assignment::value &&\n             is_nothrow_move_assignable<allocator_type>::value);\n    vector& operator=(initializer_list<value_type> il);\n    template <class InputIterator>\n        void assign(InputIterator first, InputIterator last);\n    void assign(size_type n, const value_type& u);\n    void assign(initializer_list<value_type> il);\n\n    allocator_type get_allocator() const noexcept;\n\n    iterator               begin() noexcept;\n    const_iterator         begin()   const noexcept;\n    iterator               end() noexcept;\n    const_iterator         end()     const noexcept;\n\n    reverse_iterator       rbegin() noexcept;\n    const_reverse_iterator rbegin()  const noexcept;\n    reverse_iterator       rend() noexcept;\n    const_reverse_iterator rend()    const noexcept;\n\n    const_iterator         cbegin()  const noexcept;\n    const_iterator         cend()    const noexcept;\n    const_reverse_iterator crbegin() const noexcept;\n    const_reverse_iterator crend()   const noexcept;\n\n    size_type size() const noexcept;\n    size_type max_size() const noexcept;\n    size_type capacity() const noexcept;\n    bool empty() const noexcept;\n    void reserve(size_type n);\n    void shrink_to_fit() noexcept;\n\n    reference       operator[](size_type n);\n    const_reference operator[](size_type n) const;\n    reference       at(size_type n);\n    const_reference at(size_type n) const;\n\n    reference       front();\n    const_reference front() const;\n    reference       back();\n    const_reference back() const;\n\n    value_type*       data() noexcept;\n    const value_type* data() const noexcept;\n\n    void push_back(const value_type& x);\n    void push_back(value_type&& x);\n    template <class... Args>\n        void emplace_back(Args&&... args);\n    void pop_back();\n\n    template <class... Args> iterator emplace(const_iterator position, Args&&... args);\n    iterator insert(const_iterator position, const value_type& x);\n    iterator insert(const_iterator position, value_type&& x);\n    iterator insert(const_iterator position, size_type n, const value_type& x);\n    template <class InputIterator>\n        iterator insert(const_iterator position, InputIterator first, InputIterator last);\n    iterator insert(const_iterator position, initializer_list<value_type> il);\n\n    iterator erase(const_iterator position);\n    iterator erase(const_iterator first, const_iterator last);\n\n    void clear() noexcept;\n\n    void resize(size_type sz);\n    void resize(size_type sz, const value_type& c);\n\n    void swap(vector&)\n        noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||\n                 allocator_traits<allocator_type>::is_always_equal::value);  // C++17\n\n    bool __invariants() const;\n};\n\ntemplate <class Allocator = allocator<T> >\nclass vector<bool, Allocator>\n{\npublic:\n    typedef bool                                     value_type;\n    typedef Allocator                                allocator_type;\n    typedef implementation-defined                   iterator;\n    typedef implementation-defined                   const_iterator;\n    typedef typename allocator_type::size_type       size_type;\n    typedef typename allocator_type::difference_type difference_type;\n    typedef iterator                                 pointer;\n    typedef const_iterator                           const_pointer;\n    typedef std::reverse_iterator<iterator>          reverse_iterator;\n    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;\n\n    class reference\n    {\n    public:\n        reference(const reference&) noexcept;\n        operator bool() const noexcept;\n        reference& operator=(const bool x) noexcept;\n        reference& operator=(const reference& x) noexcept;\n        iterator operator&() const noexcept;\n        void flip() noexcept;\n    };\n\n    class const_reference\n    {\n    public:\n        const_reference(const reference&) noexcept;\n        operator bool() const noexcept;\n        const_iterator operator&() const noexcept;\n    };\n\n    vector()\n        noexcept(is_nothrow_default_constructible<allocator_type>::value);\n    explicit vector(const allocator_type&);\n    explicit vector(size_type n, const allocator_type& a = allocator_type()); // C++14\n    vector(size_type n, const value_type& value, const allocator_type& = allocator_type());\n    template <class InputIterator>\n        vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type());\n    vector(const vector& x);\n    vector(vector&& x)\n        noexcept(is_nothrow_move_constructible<allocator_type>::value);\n    vector(initializer_list<value_type> il);\n    vector(initializer_list<value_type> il, const allocator_type& a);\n    ~vector();\n    vector& operator=(const vector& x);\n    vector& operator=(vector&& x)\n        noexcept(\n             allocator_type::propagate_on_container_move_assignment::value &&\n             is_nothrow_move_assignable<allocator_type>::value);\n    vector& operator=(initializer_list<value_type> il);\n    template <class InputIterator>\n        void assign(InputIterator first, InputIterator last);\n    void assign(size_type n, const value_type& u);\n    void assign(initializer_list<value_type> il);\n\n    allocator_type get_allocator() const noexcept;\n\n    iterator               begin() noexcept;\n    const_iterator         begin()   const noexcept;\n    iterator               end() noexcept;\n    const_iterator         end()     const noexcept;\n\n    reverse_iterator       rbegin() noexcept;\n    const_reverse_iterator rbegin()  const noexcept;\n    reverse_iterator       rend() noexcept;\n    const_reverse_iterator rend()    const noexcept;\n\n    const_iterator         cbegin()  const noexcept;\n    const_iterator         cend()    const noexcept;\n    const_reverse_iterator crbegin() const noexcept;\n    const_reverse_iterator crend()   const noexcept;\n\n    size_type size() const noexcept;\n    size_type max_size() const noexcept;\n    size_type capacity() const noexcept;\n    bool empty() const noexcept;\n    void reserve(size_type n);\n    void shrink_to_fit() noexcept;\n\n    reference       operator[](size_type n);\n    const_reference operator[](size_type n) const;\n    reference       at(size_type n);\n    const_reference at(size_type n) const;\n\n    reference       front();\n    const_reference front() const;\n    reference       back();\n    const_reference back() const;\n\n    void push_back(const value_type& x);\n    template <class... Args> void emplace_back(Args&&... args);  // C++14\n    void pop_back();\n\n    template <class... Args> iterator emplace(const_iterator position, Args&&... args);  // C++14\n    iterator insert(const_iterator position, const value_type& x);\n    iterator insert(const_iterator position, size_type n, const value_type& x);\n    template <class InputIterator>\n        iterator insert(const_iterator position, InputIterator first, InputIterator last);\n    iterator insert(const_iterator position, initializer_list<value_type> il);\n\n    iterator erase(const_iterator position);\n    iterator erase(const_iterator first, const_iterator last);\n\n    void clear() noexcept;\n\n    void resize(size_type sz);\n    void resize(size_type sz, value_type x);\n\n    void swap(vector&)\n        noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||\n                 allocator_traits<allocator_type>::is_always_equal::value);  // C++17\n    void flip() noexcept;\n\n    bool __invariants() const;\n};\n\ntemplate <class Allocator> struct hash<std::vector<bool, Allocator>>;\n\ntemplate <class T, class Allocator> bool operator==(const vector<T,Allocator>& x, const vector<T,Allocator>& y);\ntemplate <class T, class Allocator> bool operator< (const vector<T,Allocator>& x, const vector<T,Allocator>& y);\ntemplate <class T, class Allocator> bool operator!=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);\ntemplate <class T, class Allocator> bool operator> (const vector<T,Allocator>& x, const vector<T,Allocator>& y);\ntemplate <class T, class Allocator> bool operator>=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);\ntemplate <class T, class Allocator> bool operator<=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);\n\ntemplate <class T, class Allocator>\nvoid swap(vector<T,Allocator>& x, vector<T,Allocator>& y)\n    noexcept(noexcept(x.swap(y)));\n\n}  // std\n\n*/\n\n#include <__config>\n#include <__bit_reference>\n#include <type_traits>\n#include <climits>\n#include <limits>\n#include <initializer_list>\n#include <memory>\n#include <stdexcept>\n#include <algorithm>\n#include <cstring>\n#include <__split_buffer>\n#include <__functional_base>\n\n#include <__undef_min_max>\n\n#include <__debug>\n\n#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)\n#pragma GCC system_header\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate <bool>\nclass __vector_base_common\n{\nprotected:\n    _LIBCPP_ALWAYS_INLINE __vector_base_common() {}\n    void __throw_length_error() const;\n    void __throw_out_of_range() const;\n};\n\ntemplate <bool __b>\nvoid\n__vector_base_common<__b>::__throw_length_error() const\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    throw length_error(\"vector\");\n#else\n    assert(!\"vector length_error\");\n#endif\n}\n\ntemplate <bool __b>\nvoid\n__vector_base_common<__b>::__throw_out_of_range() const\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    throw out_of_range(\"vector\");\n#else\n    assert(!\"vector out_of_range\");\n#endif\n}\n\n#ifdef _LIBCPP_MSVC\n#pragma warning( push )\n#pragma warning( disable: 4231 )\n#endif // _LIBCPP_MSVC\n_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __vector_base_common<true>)\n#ifdef _LIBCPP_MSVC\n#pragma warning( pop )\n#endif // _LIBCPP_MSVC\n\ntemplate <class _Tp, class _Allocator>\nclass __vector_base\n    : protected __vector_base_common<true>\n{\nprotected:\n    typedef _Tp                                      value_type;\n    typedef _Allocator                               allocator_type;\n    typedef allocator_traits<allocator_type>         __alloc_traits;\n    typedef value_type&                              reference;\n    typedef const value_type&                        const_reference;\n    typedef typename __alloc_traits::size_type       size_type;\n    typedef typename __alloc_traits::difference_type difference_type;\n    typedef typename __alloc_traits::pointer         pointer;\n    typedef typename __alloc_traits::const_pointer   const_pointer;\n    typedef pointer                                  iterator;\n    typedef const_pointer                            const_iterator;\n\n    pointer                                         __begin_;\n    pointer                                         __end_;\n    __compressed_pair<pointer, allocator_type> __end_cap_;\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type& __alloc() _NOEXCEPT\n        {return __end_cap_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n    const allocator_type& __alloc() const _NOEXCEPT\n        {return __end_cap_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n    pointer& __end_cap() _NOEXCEPT\n        {return __end_cap_.first();}\n    _LIBCPP_INLINE_VISIBILITY\n    const pointer& __end_cap() const _NOEXCEPT\n        {return __end_cap_.first();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    __vector_base()\n        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);\n    _LIBCPP_INLINE_VISIBILITY __vector_base(const allocator_type& __a);\n    ~__vector_base();\n\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() _NOEXCEPT {__destruct_at_end(__begin_);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type capacity() const _NOEXCEPT\n        {return static_cast<size_type>(__end_cap() - __begin_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __destruct_at_end(pointer __new_last) _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const __vector_base& __c)\n        {__copy_assign_alloc(__c, integral_constant<bool,\n                      __alloc_traits::propagate_on_container_copy_assignment::value>());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__vector_base& __c)\n        _NOEXCEPT_(\n            !__alloc_traits::propagate_on_container_move_assignment::value ||\n            is_nothrow_move_assignable<allocator_type>::value)\n        {__move_assign_alloc(__c, integral_constant<bool,\n                      __alloc_traits::propagate_on_container_move_assignment::value>());}\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const __vector_base& __c, true_type)\n        {\n            if (__alloc() != __c.__alloc())\n            {\n                clear();\n                __alloc_traits::deallocate(__alloc(), __begin_, capacity());\n                __begin_ = __end_ = __end_cap() = nullptr;\n            }\n            __alloc() = __c.__alloc();\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const __vector_base&, false_type)\n        {}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__vector_base& __c, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)\n        {\n            __alloc() = _VSTD::move(__c.__alloc());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(__vector_base&, false_type)\n        _NOEXCEPT\n        {}\n};\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\n__vector_base<_Tp, _Allocator>::__destruct_at_end(pointer __new_last) _NOEXCEPT\n{\n    while (__new_last != __end_)\n        __alloc_traits::destroy(__alloc(), _VSTD::__to_raw_pointer(--__end_));\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\n__vector_base<_Tp, _Allocator>::__vector_base()\n        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)\n    : __begin_(nullptr),\n      __end_(nullptr),\n      __end_cap_(nullptr)\n{\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\n__vector_base<_Tp, _Allocator>::__vector_base(const allocator_type& __a)\n    : __begin_(nullptr),\n      __end_(nullptr),\n      __end_cap_(nullptr, __a)\n{\n}\n\ntemplate <class _Tp, class _Allocator>\n__vector_base<_Tp, _Allocator>::~__vector_base()\n{\n    if (__begin_ != nullptr)\n    {\n        clear();\n        __alloc_traits::deallocate(__alloc(), __begin_, capacity());\n    }\n}\n\ntemplate <class _Tp, class _Allocator = allocator<_Tp> >\nclass _LIBCPP_TYPE_VIS_ONLY vector\n    : private __vector_base<_Tp, _Allocator>\n{\nprivate:\n    typedef __vector_base<_Tp, _Allocator>           __base;\n    typedef allocator<_Tp>                           __default_allocator_type;\npublic:\n    typedef vector                                   __self;\n    typedef _Tp                                      value_type;\n    typedef _Allocator                               allocator_type;\n    typedef typename __base::__alloc_traits          __alloc_traits;\n    typedef typename __base::reference               reference;\n    typedef typename __base::const_reference         const_reference;\n    typedef typename __base::size_type               size_type;\n    typedef typename __base::difference_type         difference_type;\n    typedef typename __base::pointer                 pointer;\n    typedef typename __base::const_pointer           const_pointer;\n    typedef __wrap_iter<pointer>                     iterator;\n    typedef __wrap_iter<const_pointer>               const_iterator;\n    typedef _VSTD::reverse_iterator<iterator>         reverse_iterator;\n    typedef _VSTD::reverse_iterator<const_iterator>   const_reverse_iterator;\n\n    static_assert((is_same<typename allocator_type::value_type, value_type>::value),\n                  \"Allocator::value_type must be same type as value_type\");\n\n    _LIBCPP_INLINE_VISIBILITY\n    vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)\n        {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n            __get_db()->__insert_c(this);\n#endif\n        }\n    _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a)\n#if _LIBCPP_STD_VER <= 14\n        _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)\n#else\n        _NOEXCEPT\n#endif\n        : __base(__a)\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->__insert_c(this);\n#endif\n    }\n    explicit vector(size_type __n);\n#if _LIBCPP_STD_VER > 11\n    explicit vector(size_type __n, const allocator_type& __a);\n#endif\n    vector(size_type __n, const_reference __x);\n    vector(size_type __n, const_reference __x, const allocator_type& __a);\n    template <class _InputIterator>\n        vector(_InputIterator __first,\n               typename enable_if<__is_input_iterator  <_InputIterator>::value &&\n                                 !__is_forward_iterator<_InputIterator>::value &&\n                                 is_constructible<\n                                    value_type,\n                                    typename iterator_traits<_InputIterator>::reference>::value,\n                                 _InputIterator>::type __last);\n    template <class _InputIterator>\n        vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,\n               typename enable_if<__is_input_iterator  <_InputIterator>::value &&\n                                 !__is_forward_iterator<_InputIterator>::value &&\n                                 is_constructible<\n                                    value_type,\n                                    typename iterator_traits<_InputIterator>::reference>::value>::type* = 0);\n    template <class _ForwardIterator>\n        vector(_ForwardIterator __first,\n               typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&\n                                 is_constructible<\n                                    value_type,\n                                    typename iterator_traits<_ForwardIterator>::reference>::value,\n                                 _ForwardIterator>::type __last);\n    template <class _ForwardIterator>\n        vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,\n               typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&\n                                 is_constructible<\n                                    value_type,\n                                    typename iterator_traits<_ForwardIterator>::reference>::value>::type* = 0);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    vector(initializer_list<value_type> __il);\n    _LIBCPP_INLINE_VISIBILITY\n    vector(initializer_list<value_type> __il, const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_INLINE_VISIBILITY\n    ~vector()\n    {\n        __get_db()->__erase_c(this);\n    }\n#endif\n\n    vector(const vector& __x);\n    vector(const vector& __x, const allocator_type& __a);\n    _LIBCPP_INLINE_VISIBILITY\n    vector& operator=(const vector& __x);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    vector(vector&& __x)\n#if _LIBCPP_STD_VER > 14\n        _NOEXCEPT;\n#else\n        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);\n#endif\n    _LIBCPP_INLINE_VISIBILITY\n    vector(vector&& __x, const allocator_type& __a);\n    _LIBCPP_INLINE_VISIBILITY\n    vector& operator=(vector&& __x)\n        _NOEXCEPT_(\n             __alloc_traits::propagate_on_container_move_assignment::value &&\n             is_nothrow_move_assignable<allocator_type>::value);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    vector& operator=(initializer_list<value_type> __il)\n        {assign(__il.begin(), __il.end()); return *this;}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    template <class _InputIterator>\n        typename enable_if\n        <\n             __is_input_iterator  <_InputIterator>::value &&\n            !__is_forward_iterator<_InputIterator>::value &&\n            is_constructible<\n                 value_type,\n                 typename iterator_traits<_InputIterator>::reference>::value,\n            void\n        >::type\n        assign(_InputIterator __first, _InputIterator __last);\n    template <class _ForwardIterator>\n        typename enable_if\n        <\n            __is_forward_iterator<_ForwardIterator>::value &&\n            is_constructible<\n                 value_type,\n                 typename iterator_traits<_ForwardIterator>::reference>::value,\n            void\n        >::type\n        assign(_ForwardIterator __first, _ForwardIterator __last);\n\n    void assign(size_type __n, const_reference __u);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    void assign(initializer_list<value_type> __il)\n        {assign(__il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY\n    allocator_type get_allocator() const _NOEXCEPT\n        {return this->__alloc();}\n\n    _LIBCPP_INLINE_VISIBILITY iterator               begin() _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY const_iterator         begin()   const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY iterator               end() _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY const_iterator         end()     const _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    reverse_iterator       rbegin() _NOEXCEPT\n        {return       reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rbegin()  const _NOEXCEPT\n        {return const_reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n    reverse_iterator       rend() _NOEXCEPT\n        {return       reverse_iterator(begin());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rend()    const _NOEXCEPT\n        {return const_reverse_iterator(begin());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator         cbegin()  const _NOEXCEPT\n        {return begin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator         cend()    const _NOEXCEPT\n        {return end();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crbegin() const _NOEXCEPT\n        {return rbegin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crend()   const _NOEXCEPT\n        {return rend();}\n\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const _NOEXCEPT\n        {return static_cast<size_type>(this->__end_ - this->__begin_);}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type capacity() const _NOEXCEPT\n        {return __base::capacity();}\n    _LIBCPP_INLINE_VISIBILITY\n    bool empty() const _NOEXCEPT\n        {return this->__begin_ == this->__end_;}\n    size_type max_size() const _NOEXCEPT;\n    void reserve(size_type __n);\n    void shrink_to_fit() _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY reference       operator[](size_type __n);\n    _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const;\n    reference       at(size_type __n);\n    const_reference at(size_type __n) const;\n\n    _LIBCPP_INLINE_VISIBILITY reference       front()\n    {\n        _LIBCPP_ASSERT(!empty(), \"front() called for empty vector\");\n        return *this->__begin_;\n    }\n    _LIBCPP_INLINE_VISIBILITY const_reference front() const\n    {\n        _LIBCPP_ASSERT(!empty(), \"front() called for empty vector\");\n        return *this->__begin_;\n    }\n    _LIBCPP_INLINE_VISIBILITY reference       back()\n    {\n        _LIBCPP_ASSERT(!empty(), \"back() called for empty vector\");\n        return *(this->__end_ - 1);\n    }\n    _LIBCPP_INLINE_VISIBILITY const_reference back()  const\n    {\n        _LIBCPP_ASSERT(!empty(), \"back() called for empty vector\");\n        return *(this->__end_ - 1);\n    }\n\n    _LIBCPP_INLINE_VISIBILITY\n    value_type*       data() _NOEXCEPT\n        {return _VSTD::__to_raw_pointer(this->__begin_);}\n    _LIBCPP_INLINE_VISIBILITY\n    const value_type* data() const _NOEXCEPT\n        {return _VSTD::__to_raw_pointer(this->__begin_);}\n\n    _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY void push_back(value_type&& __x);\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class... _Args>\n        void emplace_back(_Args&&... __args);\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    void pop_back();\n\n    iterator insert(const_iterator __position, const_reference __x);\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    iterator insert(const_iterator __position, value_type&& __x);\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n    template <class... _Args>\n        iterator emplace(const_iterator __position, _Args&&... __args);\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    iterator insert(const_iterator __position, size_type __n, const_reference __x);\n    template <class _InputIterator>\n        typename enable_if\n        <\n             __is_input_iterator  <_InputIterator>::value &&\n            !__is_forward_iterator<_InputIterator>::value &&\n            is_constructible<\n                 value_type,\n                 typename iterator_traits<_InputIterator>::reference>::value,\n            iterator\n        >::type\n        insert(const_iterator __position, _InputIterator __first, _InputIterator __last);\n    template <class _ForwardIterator>\n        typename enable_if\n        <\n            __is_forward_iterator<_ForwardIterator>::value &&\n            is_constructible<\n                 value_type,\n                 typename iterator_traits<_ForwardIterator>::reference>::value,\n            iterator\n        >::type\n        insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator __position, initializer_list<value_type> __il)\n        {return insert(__position, __il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __position);\n    iterator erase(const_iterator __first, const_iterator __last);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() _NOEXCEPT\n    {\n        size_type __old_size = size();\n        __base::clear();\n        __annotate_shrink(__old_size);\n        __invalidate_all_iterators();\n    }\n\n    void resize(size_type __sz);\n    void resize(size_type __sz, const_reference __x);\n\n    void swap(vector&)\n#if _LIBCPP_STD_VER >= 14\n        _NOEXCEPT;\n#else\n        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || \n                    __is_nothrow_swappable<allocator_type>::value);\n#endif\n\n    bool __invariants() const;\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\n    bool __dereferenceable(const const_iterator* __i) const;\n    bool __decrementable(const const_iterator* __i) const;\n    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;\n    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();\n    void allocate(size_type __n);\n    void deallocate() _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const;\n    void __construct_at_end(size_type __n);\n    void __construct_at_end(size_type __n, const_reference __x);\n    template <class _ForwardIterator>\n        typename enable_if\n        <\n            __is_forward_iterator<_ForwardIterator>::value,\n            void\n        >::type\n        __construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n);\n    void __append(size_type __n);\n    void __append(size_type __n, const_reference __x);\n    _LIBCPP_INLINE_VISIBILITY\n    iterator       __make_iter(pointer __p) _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator __make_iter(const_pointer __p) const _NOEXCEPT;\n    void __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v);\n    pointer __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p);\n    void __move_range(pointer __from_s, pointer __from_e, pointer __to);\n    void __move_assign(vector& __c, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);\n    void __move_assign(vector& __c, false_type);\n    _LIBCPP_INLINE_VISIBILITY\n    void __destruct_at_end(pointer __new_last) _NOEXCEPT\n    {\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __c_node* __c = __get_db()->__find_c_and_lock(this);\n        for (__i_node** __p = __c->end_; __p != __c->beg_; )\n        {\n            --__p;\n            const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);\n            if (__i->base() > __new_last)\n            {\n                (*__p)->__c_ = nullptr;\n                if (--__c->end_ != __p)\n                    memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));\n            }\n        }\n        __get_db()->unlock();\n#endif\n        size_type __old_size = size();\n        __base::__destruct_at_end(__new_last);\n        __annotate_shrink(__old_size);\n    }\n    template <class _Up>\n        void\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n        __push_back_slow_path(_Up&& __x);\n#else\n        __push_back_slow_path(_Up& __x);\n#endif\n#if !defined(_LIBCPP_HAS_NO_VARIADICS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)\n    template <class... _Args>\n        void\n        __emplace_back_slow_path(_Args&&... __args);\n#endif\n    // The following functions are no-ops outside of AddressSanitizer mode.\n    // We call annotatations only for the default Allocator because other allocators\n    // may not meet the AddressSanitizer alignment constraints.\n    // See the documentation for __sanitizer_annotate_contiguous_container for more details.\n    void __annotate_contiguous_container\n    (const void *__beg, const void *__end, const void *__old_mid, const void *__new_mid) const\n    {\n#ifndef _LIBCPP_HAS_NO_ASAN\n      if (__beg && is_same<allocator_type, __default_allocator_type>::value)\n        __sanitizer_annotate_contiguous_container(__beg, __end, __old_mid, __new_mid);\n#endif\n    }\n\n    void __annotate_new(size_type __current_size) const\n    {\n      __annotate_contiguous_container(data(), data() + capacity(),\n                                      data() + capacity(), data() + __current_size);\n    }\n    void __annotate_delete() const\n    {\n      __annotate_contiguous_container(data(), data() + capacity(),\n                                      data() + size(), data() + capacity());\n    }\n    void __annotate_increase(size_type __n) const\n    {\n      __annotate_contiguous_container(data(), data() + capacity(),\n                                      data() + size(), data() + size() + __n);\n    }\n    void __annotate_shrink(size_type __old_size) const\n    {\n      __annotate_contiguous_container(data(), data() + capacity(),\n                                      data() + __old_size, data() + size());\n    }\n#ifndef _LIBCPP_HAS_NO_ASAN\n    // The annotation for size increase should happen before the actual increase,\n    // but if an exception is thrown after that the annotation has to be undone.\n    struct __RAII_IncreaseAnnotator {\n      __RAII_IncreaseAnnotator(const vector &__v, size_type __n = 1)\n        : __commit(false), __v(__v), __old_size(__v.size() + __n) {\n        __v.__annotate_increase(__n);\n      }\n      void __done() { __commit = true; }\n      ~__RAII_IncreaseAnnotator() {\n        if (__commit) return;\n        __v.__annotate_shrink(__old_size);\n      }\n      bool __commit;\n      const vector &__v;\n      size_type __old_size;\n    };\n#else\n    struct __RAII_IncreaseAnnotator {\n      inline __RAII_IncreaseAnnotator(const vector &, size_type __n = 1) {}\n      inline void __done() {}\n    };\n#endif\n\n};\n\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v)\n{\n    __annotate_delete();\n    __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, this->__end_, __v.__begin_);\n    _VSTD::swap(this->__begin_, __v.__begin_);\n    _VSTD::swap(this->__end_, __v.__end_);\n    _VSTD::swap(this->__end_cap(), __v.__end_cap());\n    __v.__first_ = __v.__begin_;\n    __annotate_new(size());\n    __invalidate_all_iterators();\n}\n\ntemplate <class _Tp, class _Allocator>\ntypename vector<_Tp, _Allocator>::pointer\nvector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p)\n{\n    __annotate_delete();\n    pointer __r = __v.__begin_;\n    __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, __p, __v.__begin_);\n    __alloc_traits::__construct_forward(this->__alloc(), __p, this->__end_, __v.__end_);\n    _VSTD::swap(this->__begin_, __v.__begin_);\n    _VSTD::swap(this->__end_, __v.__end_);\n    _VSTD::swap(this->__end_cap(), __v.__end_cap());\n    __v.__first_ = __v.__begin_;\n    __annotate_new(size());\n    __invalidate_all_iterators();\n    return __r;\n}\n\n//  Allocate space for __n objects\n//  throws length_error if __n > max_size()\n//  throws (probably bad_alloc) if memory run out\n//  Precondition:  __begin_ == __end_ == __end_cap() == 0\n//  Precondition:  __n > 0\n//  Postcondition:  capacity() == __n\n//  Postcondition:  size() == 0\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::allocate(size_type __n)\n{\n    if (__n > max_size())\n        this->__throw_length_error();\n    this->__begin_ = this->__end_ = __alloc_traits::allocate(this->__alloc(), __n);\n    this->__end_cap() = this->__begin_ + __n;\n    __annotate_new(0);\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::deallocate() _NOEXCEPT\n{\n    if (this->__begin_ != nullptr)\n    {\n        clear();\n        __alloc_traits::deallocate(this->__alloc(), this->__begin_, capacity());\n        this->__begin_ = this->__end_ = this->__end_cap() = nullptr;\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\ntypename vector<_Tp, _Allocator>::size_type\nvector<_Tp, _Allocator>::max_size() const _NOEXCEPT\n{\n    return _VSTD::min<size_type>(__alloc_traits::max_size(this->__alloc()), numeric_limits<size_type>::max() / 2);  // end() >= begin(), always\n}\n\n//  Precondition:  __new_size > capacity()\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename vector<_Tp, _Allocator>::size_type\nvector<_Tp, _Allocator>::__recommend(size_type __new_size) const\n{\n    const size_type __ms = max_size();\n    if (__new_size > __ms)\n        this->__throw_length_error();\n    const size_type __cap = capacity();\n    if (__cap >= __ms / 2)\n        return __ms;\n    return _VSTD::max<size_type>(2*__cap, __new_size);\n}\n\n//  Default constructs __n objects starting at __end_\n//  throws if construction throws\n//  Precondition:  __n > 0\n//  Precondition:  size() + __n <= capacity()\n//  Postcondition:  size() == size() + __n\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::__construct_at_end(size_type __n)\n{\n    allocator_type& __a = this->__alloc();\n    do\n    {\n        __RAII_IncreaseAnnotator __annotator(*this);\n        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));\n        ++this->__end_;\n        --__n;\n        __annotator.__done();\n    } while (__n > 0);\n}\n\n//  Copy constructs __n objects starting at __end_ from __x\n//  throws if construction throws\n//  Precondition:  __n > 0\n//  Precondition:  size() + __n <= capacity()\n//  Postcondition:  size() == old size() + __n\n//  Postcondition:  [i] == __x for all i in [size() - __n, __n)\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nvector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)\n{\n    allocator_type& __a = this->__alloc();\n    do\n    {\n        __RAII_IncreaseAnnotator __annotator(*this);\n        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x);\n        ++this->__end_;\n        --__n;\n        __annotator.__done();\n    } while (__n > 0);\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _ForwardIterator>\ntypename enable_if\n<\n    __is_forward_iterator<_ForwardIterator>::value,\n    void\n>::type\nvector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n)\n{\n    allocator_type& __a = this->__alloc();\n    __RAII_IncreaseAnnotator __annotator(*this, __n);\n    __alloc_traits::__construct_range_forward(__a, __first, __last, this->__end_);\n    __annotator.__done();\n}\n\n//  Default constructs __n objects starting at __end_\n//  throws if construction throws\n//  Postcondition:  size() == size() + __n\n//  Exception safety: strong.\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::__append(size_type __n)\n{\n    if (static_cast<size_type>(this->__end_cap() - this->__end_) >= __n)\n        this->__construct_at_end(__n);\n    else\n    {\n        allocator_type& __a = this->__alloc();\n        __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), __a);\n        __v.__construct_at_end(__n);\n        __swap_out_circular_buffer(__v);\n    }\n}\n\n//  Default constructs __n objects starting at __end_\n//  throws if construction throws\n//  Postcondition:  size() == size() + __n\n//  Exception safety: strong.\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::__append(size_type __n, const_reference __x)\n{\n    if (static_cast<size_type>(this->__end_cap() - this->__end_) >= __n)\n        this->__construct_at_end(__n, __x);\n    else\n    {\n        allocator_type& __a = this->__alloc();\n        __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), __a);\n        __v.__construct_at_end(__n, __x);\n        __swap_out_circular_buffer(__v);\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\nvector<_Tp, _Allocator>::vector(size_type __n)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__n);\n    }\n}\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Tp, class _Allocator>\nvector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a)\n    : __base(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__n);\n    }\n}\n#endif\n\ntemplate <class _Tp, class _Allocator>\nvector<_Tp, _Allocator>::vector(size_type __n, const_reference __x)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__n, __x);\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\nvector<_Tp, _Allocator>::vector(size_type __n, const_reference __x, const allocator_type& __a)\n    : __base(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__n, __x);\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _InputIterator>\nvector<_Tp, _Allocator>::vector(_InputIterator __first,\n       typename enable_if<__is_input_iterator  <_InputIterator>::value &&\n                         !__is_forward_iterator<_InputIterator>::value &&\n                         is_constructible<\n                            value_type,\n                            typename iterator_traits<_InputIterator>::reference>::value,\n                          _InputIterator>::type __last)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    for (; __first != __last; ++__first)\n        push_back(*__first);\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _InputIterator>\nvector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,\n       typename enable_if<__is_input_iterator  <_InputIterator>::value &&\n                         !__is_forward_iterator<_InputIterator>::value &&\n                         is_constructible<\n                            value_type,\n                            typename iterator_traits<_InputIterator>::reference>::value>::type*)\n    : __base(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    for (; __first != __last; ++__first)\n        push_back(*__first);\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _ForwardIterator>\nvector<_Tp, _Allocator>::vector(_ForwardIterator __first,\n                                typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&\n                                is_constructible<\n                                   value_type,\n                                   typename iterator_traits<_ForwardIterator>::reference>::value,\n                                                   _ForwardIterator>::type __last)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__first, __last, __n);\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _ForwardIterator>\nvector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,\n                                typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&\n                                is_constructible<\n                                   value_type,\n                                   typename iterator_traits<_ForwardIterator>::reference>::value>::type*)\n    : __base(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__first, __last, __n);\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\nvector<_Tp, _Allocator>::vector(const vector& __x)\n    : __base(__alloc_traits::select_on_container_copy_construction(__x.__alloc()))\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    size_type __n = __x.size();\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__x.__begin_, __x.__end_, __n);\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\nvector<_Tp, _Allocator>::vector(const vector& __x, const allocator_type& __a)\n    : __base(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    size_type __n = __x.size();\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__x.__begin_, __x.__end_, __n);\n    }\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvector<_Tp, _Allocator>::vector(vector&& __x)\n#if _LIBCPP_STD_VER > 14\n        _NOEXCEPT\n#else\n        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)\n#endif\n    : __base(_VSTD::move(__x.__alloc()))\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n    __get_db()->swap(this, &__x);\n#endif\n    this->__begin_ = __x.__begin_;\n    this->__end_ = __x.__end_;\n    this->__end_cap() = __x.__end_cap();\n    __x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr;\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvector<_Tp, _Allocator>::vector(vector&& __x, const allocator_type& __a)\n    : __base(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    if (__a == __x.__alloc())\n    {\n        this->__begin_ = __x.__begin_;\n        this->__end_ = __x.__end_;\n        this->__end_cap() = __x.__end_cap();\n        __x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n        __get_db()->swap(this, &__x);\n#endif\n    }\n    else\n    {\n        typedef move_iterator<iterator> _Ip;\n        assign(_Ip(__x.begin()), _Ip(__x.end()));\n    }\n}\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    if (__il.size() > 0)\n    {\n        allocate(__il.size());\n        __construct_at_end(__il.begin(), __il.end(), __il.size());\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)\n    : __base(__a)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__insert_c(this);\n#endif\n    if (__il.size() > 0)\n    {\n        allocate(__il.size());\n        __construct_at_end(__il.begin(), __il.end(), __il.size());\n    }\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvector<_Tp, _Allocator>&\nvector<_Tp, _Allocator>::operator=(vector&& __x)\n        _NOEXCEPT_(\n             __alloc_traits::propagate_on_container_move_assignment::value &&\n             is_nothrow_move_assignable<allocator_type>::value)\n{\n    __move_assign(__x, integral_constant<bool,\n          __alloc_traits::propagate_on_container_move_assignment::value>());\n    return *this;\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::__move_assign(vector& __c, false_type)\n{\n    if (__base::__alloc() != __c.__alloc())\n    {\n        typedef move_iterator<iterator> _Ip;\n        assign(_Ip(__c.begin()), _Ip(__c.end()));\n    }\n    else\n        __move_assign(__c, true_type());\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::__move_assign(vector& __c, true_type)\n    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)\n{\n    deallocate();\n    __base::__move_assign_alloc(__c); // this can throw\n    this->__begin_ = __c.__begin_;\n    this->__end_ = __c.__end_;\n    this->__end_cap() = __c.__end_cap();\n    __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr;\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->swap(this, &__c);\n#endif\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvector<_Tp, _Allocator>&\nvector<_Tp, _Allocator>::operator=(const vector& __x)\n{\n    if (this != &__x)\n    {\n        __base::__copy_assign_alloc(__x);\n        assign(__x.__begin_, __x.__end_);\n    }\n    return *this;\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _InputIterator>\ntypename enable_if\n<\n     __is_input_iterator  <_InputIterator>::value &&\n    !__is_forward_iterator<_InputIterator>::value &&\n    is_constructible<\n       _Tp,\n       typename iterator_traits<_InputIterator>::reference>::value,\n    void\n>::type\nvector<_Tp, _Allocator>::assign(_InputIterator __first, _InputIterator __last)\n{\n    clear();\n    for (; __first != __last; ++__first)\n        push_back(*__first);\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _ForwardIterator>\ntypename enable_if\n<\n    __is_forward_iterator<_ForwardIterator>::value &&\n    is_constructible<\n       _Tp,\n       typename iterator_traits<_ForwardIterator>::reference>::value,\n    void\n>::type\nvector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)\n{\n    size_type __new_size = static_cast<size_type>(_VSTD::distance(__first, __last));\n    if (__new_size <= capacity())\n    {\n        _ForwardIterator __mid = __last;\n        bool __growing = false;\n        if (__new_size > size())\n        {\n            __growing = true;\n            __mid =  __first;\n            _VSTD::advance(__mid, size());\n        }\n        pointer __m = _VSTD::copy(__first, __mid, this->__begin_);\n        if (__growing)\n            __construct_at_end(__mid, __last, __new_size - size());\n        else\n            this->__destruct_at_end(__m);\n    }\n    else\n    {\n        deallocate();\n        allocate(__recommend(__new_size));\n        __construct_at_end(__first, __last, __new_size);\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::assign(size_type __n, const_reference __u)\n{\n    if (__n <= capacity())\n    {\n        size_type __s = size();\n        _VSTD::fill_n(this->__begin_, _VSTD::min(__n, __s), __u);\n        if (__n > __s)\n            __construct_at_end(__n - __s, __u);\n        else\n            this->__destruct_at_end(this->__begin_ + __n);\n    }\n    else\n    {\n        deallocate();\n        allocate(__recommend(static_cast<size_type>(__n)));\n        __construct_at_end(__n, __u);\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename vector<_Tp, _Allocator>::iterator\nvector<_Tp, _Allocator>::__make_iter(pointer __p) _NOEXCEPT\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return iterator(this, __p);\n#else\n    return iterator(__p);\n#endif\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename vector<_Tp, _Allocator>::const_iterator\nvector<_Tp, _Allocator>::__make_iter(const_pointer __p) const _NOEXCEPT\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    return const_iterator(this, __p);\n#else\n    return const_iterator(__p);\n#endif\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename vector<_Tp, _Allocator>::iterator\nvector<_Tp, _Allocator>::begin() _NOEXCEPT\n{\n    return __make_iter(this->__begin_);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename vector<_Tp, _Allocator>::const_iterator\nvector<_Tp, _Allocator>::begin() const _NOEXCEPT\n{\n    return __make_iter(this->__begin_);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename vector<_Tp, _Allocator>::iterator\nvector<_Tp, _Allocator>::end() _NOEXCEPT\n{\n    return __make_iter(this->__end_);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename vector<_Tp, _Allocator>::const_iterator\nvector<_Tp, _Allocator>::end() const _NOEXCEPT\n{\n    return __make_iter(this->__end_);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename vector<_Tp, _Allocator>::reference\nvector<_Tp, _Allocator>::operator[](size_type __n)\n{\n    _LIBCPP_ASSERT(__n < size(), \"vector[] index out of bounds\");\n    return this->__begin_[__n];\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename vector<_Tp, _Allocator>::const_reference\nvector<_Tp, _Allocator>::operator[](size_type __n) const\n{\n    _LIBCPP_ASSERT(__n < size(), \"vector[] index out of bounds\");\n    return this->__begin_[__n];\n}\n\ntemplate <class _Tp, class _Allocator>\ntypename vector<_Tp, _Allocator>::reference\nvector<_Tp, _Allocator>::at(size_type __n)\n{\n    if (__n >= size())\n        this->__throw_out_of_range();\n    return this->__begin_[__n];\n}\n\ntemplate <class _Tp, class _Allocator>\ntypename vector<_Tp, _Allocator>::const_reference\nvector<_Tp, _Allocator>::at(size_type __n) const\n{\n    if (__n >= size())\n        this->__throw_out_of_range();\n    return this->__begin_[__n];\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::reserve(size_type __n)\n{\n    if (__n > capacity())\n    {\n        allocator_type& __a = this->__alloc();\n        __split_buffer<value_type, allocator_type&> __v(__n, size(), __a);\n        __swap_out_circular_buffer(__v);\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT\n{\n    if (capacity() > size())\n    {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            allocator_type& __a = this->__alloc();\n            __split_buffer<value_type, allocator_type&> __v(size(), size(), __a);\n            __swap_out_circular_buffer(__v);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _Up>\nvoid\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\nvector<_Tp, _Allocator>::__push_back_slow_path(_Up&& __x)\n#else\nvector<_Tp, _Allocator>::__push_back_slow_path(_Up& __x)\n#endif\n{\n    allocator_type& __a = this->__alloc();\n    __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), size(), __a);\n    // __v.push_back(_VSTD::forward<_Up>(__x));\n    __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(__v.__end_), _VSTD::forward<_Up>(__x));\n    __v.__end_++;\n    __swap_out_circular_buffer(__v);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nvector<_Tp, _Allocator>::push_back(const_reference __x)\n{\n    if (this->__end_ != this->__end_cap())\n    {\n        __RAII_IncreaseAnnotator __annotator(*this);\n        __alloc_traits::construct(this->__alloc(),\n                                  _VSTD::__to_raw_pointer(this->__end_), __x);\n        __annotator.__done();\n        ++this->__end_;\n    }\n    else\n        __push_back_slow_path(__x);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nvector<_Tp, _Allocator>::push_back(value_type&& __x)\n{\n    if (this->__end_ < this->__end_cap())\n    {\n        __RAII_IncreaseAnnotator __annotator(*this);\n        __alloc_traits::construct(this->__alloc(),\n                                  _VSTD::__to_raw_pointer(this->__end_),\n                                  _VSTD::move(__x));\n        __annotator.__done();\n        ++this->__end_;\n    }\n    else\n        __push_back_slow_path(_VSTD::move(__x));\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class... _Args>\nvoid\nvector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args)\n{\n    allocator_type& __a = this->__alloc();\n    __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), size(), __a);\n//    __v.emplace_back(_VSTD::forward<_Args>(__args)...);\n    __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(__v.__end_), _VSTD::forward<_Args>(__args)...);\n    __v.__end_++;\n    __swap_out_circular_buffer(__v);\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class... _Args>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nvector<_Tp, _Allocator>::emplace_back(_Args&&... __args)\n{\n    if (this->__end_ < this->__end_cap())\n    {\n        __RAII_IncreaseAnnotator __annotator(*this);\n        __alloc_traits::construct(this->__alloc(),\n                                  _VSTD::__to_raw_pointer(this->__end_),\n                                  _VSTD::forward<_Args>(__args)...);\n        __annotator.__done();\n        ++this->__end_;\n    }\n    else\n        __emplace_back_slow_path(_VSTD::forward<_Args>(__args)...);\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nvector<_Tp, _Allocator>::pop_back()\n{\n    _LIBCPP_ASSERT(!empty(), \"vector::pop_back called for empty vector\");\n    this->__destruct_at_end(this->__end_ - 1);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename vector<_Tp, _Allocator>::iterator\nvector<_Tp, _Allocator>::erase(const_iterator __position)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,\n        \"vector::erase(iterator) called with an iterator not\"\n        \" referring to this vector\");\n#endif\n    _LIBCPP_ASSERT(__position != end(),\n        \"vector::erase(iterator) called with a non-dereferenceable iterator\");\n    difference_type __ps = __position - cbegin();\n    pointer __p = this->__begin_ + __ps;\n    iterator __r = __make_iter(__p);\n    this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p));\n    return __r;\n}\n\ntemplate <class _Tp, class _Allocator>\ntypename vector<_Tp, _Allocator>::iterator\nvector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,\n        \"vector::erase(iterator,  iterator) called with an iterator not\"\n        \" referring to this vector\");\n#endif\n    _LIBCPP_ASSERT(__first <= __last, \"vector::erase(first, last) called with invalid range\");\n    pointer __p = this->__begin_ + (__first - begin());\n    iterator __r = __make_iter(__p);\n    if (__first != __last)\n        this->__destruct_at_end(_VSTD::move(__p + (__last - __first), this->__end_, __p));\n    return __r;\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointer __to)\n{\n    pointer __old_last = this->__end_;\n    difference_type __n = __old_last - __to;\n    for (pointer __i = __from_s + __n; __i < __from_e; ++__i, ++this->__end_)\n        __alloc_traits::construct(this->__alloc(),\n                                  _VSTD::__to_raw_pointer(this->__end_),\n                                  _VSTD::move(*__i));\n    _VSTD::move_backward(__from_s, __from_s + __n, __old_last);\n}\n\ntemplate <class _Tp, class _Allocator>\ntypename vector<_Tp, _Allocator>::iterator\nvector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,\n        \"vector::insert(iterator, x) called with an iterator not\"\n        \" referring to this vector\");\n#endif\n    pointer __p = this->__begin_ + (__position - begin());\n    if (this->__end_ < this->__end_cap())\n    {\n        __RAII_IncreaseAnnotator __annotator(*this);\n        if (__p == this->__end_)\n        {\n            __alloc_traits::construct(this->__alloc(),\n                                      _VSTD::__to_raw_pointer(this->__end_), __x);\n            ++this->__end_;\n        }\n        else\n        {\n            __move_range(__p, this->__end_, __p + 1);\n            const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);\n            if (__p <= __xr && __xr < this->__end_)\n                ++__xr;\n            *__p = *__xr;\n        }\n        __annotator.__done();\n    }\n    else\n    {\n        allocator_type& __a = this->__alloc();\n        __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, __a);\n        __v.push_back(__x);\n        __p = __swap_out_circular_buffer(__v, __p);\n    }\n    return __make_iter(__p);\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\ntypename vector<_Tp, _Allocator>::iterator\nvector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,\n        \"vector::insert(iterator, x) called with an iterator not\"\n        \" referring to this vector\");\n#endif\n    pointer __p = this->__begin_ + (__position - begin());\n    if (this->__end_ < this->__end_cap())\n    {\n        __RAII_IncreaseAnnotator __annotator(*this);\n        if (__p == this->__end_)\n        {\n            __alloc_traits::construct(this->__alloc(),\n                                      _VSTD::__to_raw_pointer(this->__end_),\n                                      _VSTD::move(__x));\n            ++this->__end_;\n        }\n        else\n        {\n            __move_range(__p, this->__end_, __p + 1);\n            *__p = _VSTD::move(__x);\n        }\n        __annotator.__done();\n    }\n    else\n    {\n        allocator_type& __a = this->__alloc();\n        __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, __a);\n        __v.push_back(_VSTD::move(__x));\n        __p = __swap_out_circular_buffer(__v, __p);\n    }\n    return __make_iter(__p);\n}\n\n#ifndef _LIBCPP_HAS_NO_VARIADICS\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class... _Args>\ntypename vector<_Tp, _Allocator>::iterator\nvector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,\n        \"vector::emplace(iterator, x) called with an iterator not\"\n        \" referring to this vector\");\n#endif\n    pointer __p = this->__begin_ + (__position - begin());\n    if (this->__end_ < this->__end_cap())\n    {\n        __RAII_IncreaseAnnotator __annotator(*this);\n        if (__p == this->__end_)\n        {\n            __alloc_traits::construct(this->__alloc(),\n                                      _VSTD::__to_raw_pointer(this->__end_),\n                                      _VSTD::forward<_Args>(__args)...);\n            ++this->__end_;\n        }\n        else\n        {\n            value_type __tmp(_VSTD::forward<_Args>(__args)...);\n            __move_range(__p, this->__end_, __p + 1);\n            *__p = _VSTD::move(__tmp);\n        }\n        __annotator.__done();\n    }\n    else\n    {\n        allocator_type& __a = this->__alloc();\n        __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, __a);\n        __v.emplace_back(_VSTD::forward<_Args>(__args)...);\n        __p = __swap_out_circular_buffer(__v, __p);\n    }\n    return __make_iter(__p);\n}\n\n#endif  // _LIBCPP_HAS_NO_VARIADICS\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Tp, class _Allocator>\ntypename vector<_Tp, _Allocator>::iterator\nvector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,\n        \"vector::insert(iterator, n, x) called with an iterator not\"\n        \" referring to this vector\");\n#endif\n    pointer __p = this->__begin_ + (__position - begin());\n    if (__n > 0)\n    {\n        if (__n <= static_cast<size_type>(this->__end_cap() - this->__end_))\n        {\n            size_type __old_n = __n;\n            pointer __old_last = this->__end_;\n            if (__n > static_cast<size_type>(this->__end_ - __p))\n            {\n                size_type __cx = __n - (this->__end_ - __p);\n                __construct_at_end(__cx, __x);\n                __n -= __cx;\n            }\n            if (__n > 0)\n            {\n                __RAII_IncreaseAnnotator __annotator(*this, __n);\n                __move_range(__p, __old_last, __p + __old_n);\n                __annotator.__done();\n                const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);\n                if (__p <= __xr && __xr < this->__end_)\n                    __xr += __old_n;\n                _VSTD::fill_n(__p, __n, *__xr);\n            }\n        }\n        else\n        {\n            allocator_type& __a = this->__alloc();\n            __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, __a);\n            __v.__construct_at_end(__n, __x);\n            __p = __swap_out_circular_buffer(__v, __p);\n        }\n    }\n    return __make_iter(__p);\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _InputIterator>\ntypename enable_if\n<\n     __is_input_iterator  <_InputIterator>::value &&\n    !__is_forward_iterator<_InputIterator>::value &&\n    is_constructible<\n       _Tp,\n       typename iterator_traits<_InputIterator>::reference>::value,\n    typename vector<_Tp, _Allocator>::iterator\n>::type\nvector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,\n        \"vector::insert(iterator, range) called with an iterator not\"\n        \" referring to this vector\");\n#endif\n    difference_type __off = __position - begin();\n    pointer __p = this->__begin_ + __off;\n    allocator_type& __a = this->__alloc();\n    pointer __old_last = this->__end_;\n    for (; this->__end_ != this->__end_cap() && __first != __last; ++__first)\n    {\n        __RAII_IncreaseAnnotator __annotator(*this);\n        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_),\n                                  *__first);\n        ++this->__end_;\n        __annotator.__done();\n    }\n    __split_buffer<value_type, allocator_type&> __v(__a);\n    if (__first != __last)\n    {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            __v.__construct_at_end(__first, __last);\n            difference_type __old_size = __old_last - this->__begin_;\n            difference_type __old_p = __p - this->__begin_;\n            reserve(__recommend(size() + __v.size()));\n            __p = this->__begin_ + __old_p;\n            __old_last = this->__begin_ + __old_size;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            erase(__make_iter(__old_last), end());\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n    __p = _VSTD::rotate(__p, __old_last, this->__end_);\n    insert(__make_iter(__p), make_move_iterator(__v.begin()),\n                                    make_move_iterator(__v.end()));\n    return begin() + __off;\n}\n\ntemplate <class _Tp, class _Allocator>\ntemplate <class _ForwardIterator>\ntypename enable_if\n<\n    __is_forward_iterator<_ForwardIterator>::value &&\n    is_constructible<\n       _Tp,\n       typename iterator_traits<_ForwardIterator>::reference>::value,\n    typename vector<_Tp, _Allocator>::iterator\n>::type\nvector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last)\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,\n        \"vector::insert(iterator, range) called with an iterator not\"\n        \" referring to this vector\");\n#endif\n    pointer __p = this->__begin_ + (__position - begin());\n    difference_type __n = _VSTD::distance(__first, __last);\n    if (__n > 0)\n    {\n        if (__n <= this->__end_cap() - this->__end_)\n        {\n            size_type __old_n = __n;\n            pointer __old_last = this->__end_;\n            _ForwardIterator __m = __last;\n            difference_type __dx = this->__end_ - __p;\n            if (__n > __dx)\n            {\n                __m = __first;\n                difference_type __diff = this->__end_ - __p;\n                _VSTD::advance(__m, __diff);\n                __construct_at_end(__m, __last, __n - __diff);\n                __n = __dx;\n            }\n            if (__n > 0)\n            {\n                __RAII_IncreaseAnnotator __annotator(*this, __n);\n                __move_range(__p, __old_last, __p + __old_n);\n                __annotator.__done();\n                _VSTD::copy(__first, __m, __p);\n            }\n        }\n        else\n        {\n            allocator_type& __a = this->__alloc();\n            __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, __a);\n            __v.__construct_at_end(__first, __last);\n            __p = __swap_out_circular_buffer(__v, __p);\n        }\n    }\n    return __make_iter(__p);\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::resize(size_type __sz)\n{\n    size_type __cs = size();\n    if (__cs < __sz)\n        this->__append(__sz - __cs);\n    else if (__cs > __sz)\n        this->__destruct_at_end(this->__begin_ + __sz);\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::resize(size_type __sz, const_reference __x)\n{\n    size_type __cs = size();\n    if (__cs < __sz)\n        this->__append(__sz - __cs, __x);\n    else if (__cs > __sz)\n        this->__destruct_at_end(this->__begin_ + __sz);\n}\n\ntemplate <class _Tp, class _Allocator>\nvoid\nvector<_Tp, _Allocator>::swap(vector& __x)\n#if _LIBCPP_STD_VER >= 14\n    _NOEXCEPT\n#else\n    _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || \n                __is_nothrow_swappable<allocator_type>::value)\n#endif\n{\n    _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||\n                   this->__alloc() == __x.__alloc(),\n                   \"vector::swap: Either propagate_on_container_swap must be true\"\n                   \" or the allocators must compare equal\");\n    _VSTD::swap(this->__begin_, __x.__begin_);\n    _VSTD::swap(this->__end_, __x.__end_);\n    _VSTD::swap(this->__end_cap(), __x.__end_cap());\n    __swap_allocator(this->__alloc(), __x.__alloc(), \n        integral_constant<bool,__alloc_traits::propagate_on_container_swap::value>());\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->swap(this, &__x);\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n}\n\ntemplate <class _Tp, class _Allocator>\nbool\nvector<_Tp, _Allocator>::__invariants() const\n{\n    if (this->__begin_ == nullptr)\n    {\n        if (this->__end_ != nullptr || this->__end_cap() != nullptr)\n            return false;\n    }\n    else\n    {\n        if (this->__begin_ > this->__end_)\n            return false;\n        if (this->__begin_ == this->__end_cap())\n            return false;\n        if (this->__end_ > this->__end_cap())\n            return false;\n    }\n    return true;\n}\n\n#if _LIBCPP_DEBUG_LEVEL >= 2\n\ntemplate <class _Tp, class _Allocator>\nbool\nvector<_Tp, _Allocator>::__dereferenceable(const const_iterator* __i) const\n{\n    return this->__begin_ <= __i->base() && __i->base() < this->__end_;\n}\n\ntemplate <class _Tp, class _Allocator>\nbool\nvector<_Tp, _Allocator>::__decrementable(const const_iterator* __i) const\n{\n    return this->__begin_ < __i->base() && __i->base() <= this->__end_;\n}\n\ntemplate <class _Tp, class _Allocator>\nbool\nvector<_Tp, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const\n{\n    const_pointer __p = __i->base() + __n;\n    return this->__begin_ <= __p && __p <= this->__end_;\n}\n\ntemplate <class _Tp, class _Allocator>\nbool\nvector<_Tp, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const\n{\n    const_pointer __p = __i->base() + __n;\n    return this->__begin_ <= __p && __p < this->__end_;\n}\n\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nvector<_Tp, _Allocator>::__invalidate_all_iterators()\n{\n#if _LIBCPP_DEBUG_LEVEL >= 2\n    __get_db()->__invalidate_all(this);\n#endif  // _LIBCPP_DEBUG_LEVEL >= 2\n}\n\n// vector<bool>\n\ntemplate <class _Allocator> class vector<bool, _Allocator>;\n\ntemplate <class _Allocator> struct hash<vector<bool, _Allocator> >;\n\ntemplate <class _Allocator>\nstruct __has_storage_type<vector<bool, _Allocator> >\n{\n    static const bool value = true;\n};\n\ntemplate <class _Allocator>\nclass _LIBCPP_TYPE_VIS_ONLY vector<bool, _Allocator>\n    : private __vector_base_common<true>\n{\npublic:\n    typedef vector                                   __self;\n    typedef bool                                     value_type;\n    typedef _Allocator                               allocator_type;\n    typedef allocator_traits<allocator_type>         __alloc_traits;\n    typedef typename __alloc_traits::size_type       size_type;\n    typedef typename __alloc_traits::difference_type difference_type;\n    typedef size_type __storage_type;\n    typedef __bit_iterator<vector, false>            pointer;\n    typedef __bit_iterator<vector, true>             const_pointer;\n    typedef pointer                                  iterator;\n    typedef const_pointer                            const_iterator;\n    typedef _VSTD::reverse_iterator<iterator>         reverse_iterator;\n    typedef _VSTD::reverse_iterator<const_iterator>   const_reverse_iterator;\n\nprivate:\n    typedef typename __rebind_alloc_helper<__alloc_traits, __storage_type>::type __storage_allocator;\n    typedef allocator_traits<__storage_allocator>    __storage_traits;\n    typedef typename __storage_traits::pointer       __storage_pointer;\n    typedef typename __storage_traits::const_pointer __const_storage_pointer;\n\n    __storage_pointer                                      __begin_;\n    size_type                                              __size_;\n    __compressed_pair<size_type, __storage_allocator> __cap_alloc_;\npublic:\n    typedef __bit_reference<vector>                  reference;\n    typedef __bit_const_reference<vector>            const_reference;\nprivate:\n    _LIBCPP_INLINE_VISIBILITY\n    size_type& __cap() _NOEXCEPT\n        {return __cap_alloc_.first();}\n    _LIBCPP_INLINE_VISIBILITY\n    const size_type& __cap() const _NOEXCEPT\n        {return __cap_alloc_.first();}\n    _LIBCPP_INLINE_VISIBILITY\n    __storage_allocator& __alloc() _NOEXCEPT\n        {return __cap_alloc_.second();}\n    _LIBCPP_INLINE_VISIBILITY\n    const __storage_allocator& __alloc() const _NOEXCEPT\n        {return __cap_alloc_.second();}\n\n    static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);\n\n    _LIBCPP_INLINE_VISIBILITY\n    static size_type __internal_cap_to_external(size_type __n) _NOEXCEPT\n        {return __n * __bits_per_word;}\n    _LIBCPP_INLINE_VISIBILITY\n    static size_type __external_cap_to_internal(size_type __n) _NOEXCEPT\n        {return (__n - 1) / __bits_per_word + 1;}\n\npublic:\n    _LIBCPP_INLINE_VISIBILITY\n    vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);\n\n    _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a)\n#if _LIBCPP_STD_VER <= 14\n        _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value);\n#else\n        _NOEXCEPT;\n#endif\n    ~vector();\n    explicit vector(size_type __n);\n#if _LIBCPP_STD_VER > 11\n    explicit vector(size_type __n, const allocator_type& __a);\n#endif\n    vector(size_type __n, const value_type& __v);\n    vector(size_type __n, const value_type& __v, const allocator_type& __a);\n    template <class _InputIterator>\n        vector(_InputIterator __first, _InputIterator __last,\n               typename enable_if<__is_input_iterator  <_InputIterator>::value &&\n                                 !__is_forward_iterator<_InputIterator>::value>::type* = 0);\n    template <class _InputIterator>\n        vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,\n               typename enable_if<__is_input_iterator  <_InputIterator>::value &&\n                                 !__is_forward_iterator<_InputIterator>::value>::type* = 0);\n    template <class _ForwardIterator>\n        vector(_ForwardIterator __first, _ForwardIterator __last,\n               typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type* = 0);\n    template <class _ForwardIterator>\n        vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,\n               typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type* = 0);\n\n    vector(const vector& __v);\n    vector(const vector& __v, const allocator_type& __a);\n    vector& operator=(const vector& __v);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    vector(initializer_list<value_type> __il);\n    vector(initializer_list<value_type> __il, const allocator_type& __a);\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n    _LIBCPP_INLINE_VISIBILITY\n    vector(vector&& __v)\n#if _LIBCPP_STD_VER > 14\n        _NOEXCEPT;\n#else\n        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);\n#endif\n    vector(vector&& __v, const allocator_type& __a);\n    _LIBCPP_INLINE_VISIBILITY\n    vector& operator=(vector&& __v)\n        _NOEXCEPT_(\n             __alloc_traits::propagate_on_container_move_assignment::value &&\n             is_nothrow_move_assignable<allocator_type>::value);\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    vector& operator=(initializer_list<value_type> __il)\n        {assign(__il.begin(), __il.end()); return *this;}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    template <class _InputIterator>\n        typename enable_if\n        <\n            __is_input_iterator<_InputIterator>::value &&\n           !__is_forward_iterator<_InputIterator>::value,\n           void\n        >::type\n        assign(_InputIterator __first, _InputIterator __last);\n    template <class _ForwardIterator>\n        typename enable_if\n        <\n            __is_forward_iterator<_ForwardIterator>::value,\n           void\n        >::type\n        assign(_ForwardIterator __first, _ForwardIterator __last);\n\n    void assign(size_type __n, const value_type& __x);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    void assign(initializer_list<value_type> __il)\n        {assign(__il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const _NOEXCEPT\n        {return allocator_type(this->__alloc());}\n\n    size_type max_size() const _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    size_type capacity() const _NOEXCEPT\n        {return __internal_cap_to_external(__cap());}\n    _LIBCPP_INLINE_VISIBILITY\n    size_type size() const _NOEXCEPT\n        {return __size_;}\n    _LIBCPP_INLINE_VISIBILITY\n    bool empty() const _NOEXCEPT\n        {return __size_ == 0;}\n    void reserve(size_type __n);\n    void shrink_to_fit() _NOEXCEPT;\n\n    _LIBCPP_INLINE_VISIBILITY\n    iterator begin() _NOEXCEPT\n        {return __make_iter(0);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator begin() const _NOEXCEPT\n        {return __make_iter(0);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator end() _NOEXCEPT\n        {return __make_iter(__size_);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator end()   const _NOEXCEPT\n        {return __make_iter(__size_);}\n\n    _LIBCPP_INLINE_VISIBILITY\n    reverse_iterator rbegin() _NOEXCEPT\n        {return       reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rbegin() const _NOEXCEPT\n        {return const_reverse_iterator(end());}\n    _LIBCPP_INLINE_VISIBILITY\n    reverse_iterator rend() _NOEXCEPT\n        {return       reverse_iterator(begin());}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator rend()   const _NOEXCEPT\n        {return const_reverse_iterator(begin());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator         cbegin()  const _NOEXCEPT\n        {return __make_iter(0);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator         cend()    const _NOEXCEPT\n        {return __make_iter(__size_);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crbegin() const _NOEXCEPT\n        {return rbegin();}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reverse_iterator crend()   const _NOEXCEPT\n        {return rend();}\n\n    _LIBCPP_INLINE_VISIBILITY reference       operator[](size_type __n)       {return __make_ref(__n);}\n    _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const {return __make_ref(__n);}\n    reference       at(size_type __n);\n    const_reference at(size_type __n) const;\n\n    _LIBCPP_INLINE_VISIBILITY reference       front()       {return __make_ref(0);}\n    _LIBCPP_INLINE_VISIBILITY const_reference front() const {return __make_ref(0);}\n    _LIBCPP_INLINE_VISIBILITY reference       back()        {return __make_ref(__size_ - 1);}\n    _LIBCPP_INLINE_VISIBILITY const_reference back()  const {return __make_ref(__size_ - 1);}\n\n    void push_back(const value_type& __x);\n#if _LIBCPP_STD_VER > 11\n    template <class... _Args>\n    _LIBCPP_INLINE_VISIBILITY void emplace_back(_Args&&... __args)\n        { push_back ( value_type ( _VSTD::forward<_Args>(__args)... )); }\n#endif\n\n    _LIBCPP_INLINE_VISIBILITY void pop_back() {--__size_;}\n\n#if _LIBCPP_STD_VER > 11\n    template <class... _Args>\n   _LIBCPP_INLINE_VISIBILITY iterator emplace(const_iterator position, _Args&&... __args)\n        { return insert ( position, value_type ( _VSTD::forward<_Args>(__args)... )); }\n#endif\n\n    iterator insert(const_iterator __position, const value_type& __x);\n    iterator insert(const_iterator __position, size_type __n, const value_type& __x);\n    iterator insert(const_iterator __position, size_type __n, const_reference __x);\n    template <class _InputIterator>\n        typename enable_if\n        <\n             __is_input_iterator  <_InputIterator>::value &&\n            !__is_forward_iterator<_InputIterator>::value,\n            iterator\n        >::type\n        insert(const_iterator __position, _InputIterator __first, _InputIterator __last);\n    template <class _ForwardIterator>\n        typename enable_if\n        <\n            __is_forward_iterator<_ForwardIterator>::value,\n            iterator\n        >::type\n        insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last);\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n    _LIBCPP_INLINE_VISIBILITY\n    iterator insert(const_iterator __position, initializer_list<value_type> __il)\n        {return insert(__position, __il.begin(), __il.end());}\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\n    _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __position);\n    iterator erase(const_iterator __first, const_iterator __last);\n\n    _LIBCPP_INLINE_VISIBILITY\n    void clear() _NOEXCEPT {__size_ = 0;}\n\n    void swap(vector&)\n#if _LIBCPP_STD_VER >= 14\n        _NOEXCEPT;\n#else\n        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || \n                    __is_nothrow_swappable<allocator_type>::value);\n#endif\n\n    void resize(size_type __sz, value_type __x = false);\n    void flip() _NOEXCEPT;\n\n    bool __invariants() const;\n\nprivate:\n    _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();\n    void allocate(size_type __n);\n    void deallocate() _NOEXCEPT;\n    _LIBCPP_INLINE_VISIBILITY\n    static size_type __align_it(size_type __new_size) _NOEXCEPT\n        {return __new_size + (__bits_per_word-1) & ~((size_type)__bits_per_word-1);};\n    _LIBCPP_INLINE_VISIBILITY  size_type __recommend(size_type __new_size) const;\n    _LIBCPP_INLINE_VISIBILITY void __construct_at_end(size_type __n, bool __x);\n    template <class _ForwardIterator>\n        typename enable_if\n        <\n            __is_forward_iterator<_ForwardIterator>::value,\n            void\n        >::type\n        __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);\n    void __append(size_type __n, const_reference __x);\n    _LIBCPP_INLINE_VISIBILITY\n    reference __make_ref(size_type __pos) _NOEXCEPT\n        {return reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}\n    _LIBCPP_INLINE_VISIBILITY\n    const_reference __make_ref(size_type __pos) const _NOEXCEPT\n        {return const_reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator __make_iter(size_type __pos) _NOEXCEPT\n        {return iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word));}\n    _LIBCPP_INLINE_VISIBILITY\n    const_iterator __make_iter(size_type __pos) const _NOEXCEPT\n        {return const_iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word));}\n    _LIBCPP_INLINE_VISIBILITY\n    iterator __const_iterator_cast(const_iterator __p) _NOEXCEPT\n        {return begin() + (__p - cbegin());}\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const vector& __v)\n        {__copy_assign_alloc(__v, integral_constant<bool,\n                      __storage_traits::propagate_on_container_copy_assignment::value>());}\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const vector& __c, true_type)\n        {\n            if (__alloc() != __c.__alloc())\n                deallocate();\n            __alloc() = __c.__alloc();\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __copy_assign_alloc(const vector&, false_type)\n        {}\n\n    void __move_assign(vector& __c, false_type);\n    void __move_assign(vector& __c, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(vector& __c)\n        _NOEXCEPT_(\n            !__storage_traits::propagate_on_container_move_assignment::value ||\n            is_nothrow_move_assignable<allocator_type>::value)\n        {__move_assign_alloc(__c, integral_constant<bool,\n                      __storage_traits::propagate_on_container_move_assignment::value>());}\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(vector& __c, true_type)\n        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)\n        {\n            __alloc() = _VSTD::move(__c.__alloc());\n        }\n\n    _LIBCPP_INLINE_VISIBILITY\n    void __move_assign_alloc(vector&, false_type)\n        _NOEXCEPT\n        {}\n\n    size_t __hash_code() const _NOEXCEPT;\n\n    friend class __bit_reference<vector>;\n    friend class __bit_const_reference<vector>;\n    friend class __bit_iterator<vector, false>;\n    friend class __bit_iterator<vector, true>;\n    friend struct __bit_array<vector>;\n    friend struct _LIBCPP_TYPE_VIS_ONLY hash<vector>;\n};\n\ntemplate <class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nvector<bool, _Allocator>::__invalidate_all_iterators()\n{\n}\n\n//  Allocate space for __n objects\n//  throws length_error if __n > max_size()\n//  throws (probably bad_alloc) if memory run out\n//  Precondition:  __begin_ == __end_ == __cap() == 0\n//  Precondition:  __n > 0\n//  Postcondition:  capacity() == __n\n//  Postcondition:  size() == 0\ntemplate <class _Allocator>\nvoid\nvector<bool, _Allocator>::allocate(size_type __n)\n{\n    if (__n > max_size())\n        this->__throw_length_error();\n    __n = __external_cap_to_internal(__n);\n    this->__begin_ = __storage_traits::allocate(this->__alloc(), __n);\n    this->__size_ = 0;\n    this->__cap() = __n;\n}\n\ntemplate <class _Allocator>\nvoid\nvector<bool, _Allocator>::deallocate() _NOEXCEPT\n{\n    if (this->__begin_ != nullptr)\n    {\n        __storage_traits::deallocate(this->__alloc(), this->__begin_, __cap());\n        __invalidate_all_iterators();\n        this->__begin_ = nullptr;\n        this->__size_ = this->__cap() = 0;\n    }\n}\n\ntemplate <class _Allocator>\ntypename vector<bool, _Allocator>::size_type\nvector<bool, _Allocator>::max_size() const _NOEXCEPT\n{\n    size_type __amax = __storage_traits::max_size(__alloc());\n    size_type __nmax = numeric_limits<size_type>::max() / 2;  // end() >= begin(), always\n    if (__nmax / __bits_per_word <= __amax)\n        return __nmax;\n    return __internal_cap_to_external(__amax);\n}\n\n//  Precondition:  __new_size > capacity()\ntemplate <class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename vector<bool, _Allocator>::size_type\nvector<bool, _Allocator>::__recommend(size_type __new_size) const\n{\n    const size_type __ms = max_size();\n    if (__new_size > __ms)\n        this->__throw_length_error();\n    const size_type __cap = capacity();\n    if (__cap >= __ms / 2)\n        return __ms;\n    return _VSTD::max(2*__cap, __align_it(__new_size));\n}\n\n//  Default constructs __n objects starting at __end_\n//  Precondition:  __n > 0\n//  Precondition:  size() + __n <= capacity()\n//  Postcondition:  size() == size() + __n\ntemplate <class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nvector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x)\n{\n    size_type __old_size = this->__size_;\n    this->__size_ += __n;\n    _VSTD::fill_n(__make_iter(__old_size), __n, __x);\n}\n\ntemplate <class _Allocator>\ntemplate <class _ForwardIterator>\ntypename enable_if\n<\n    __is_forward_iterator<_ForwardIterator>::value,\n    void\n>::type\nvector<bool, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)\n{\n    size_type __old_size = this->__size_;\n    this->__size_ += _VSTD::distance(__first, __last);\n    _VSTD::copy(__first, __last, __make_iter(__old_size));\n}\n\ntemplate <class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvector<bool, _Allocator>::vector()\n    _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0)\n{\n}\n\ntemplate <class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvector<bool, _Allocator>::vector(const allocator_type& __a)\n#if _LIBCPP_STD_VER <= 14\n        _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)\n#else\n        _NOEXCEPT\n#endif\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0, static_cast<__storage_allocator>(__a))\n{\n}\n\ntemplate <class _Allocator>\nvector<bool, _Allocator>::vector(size_type __n)\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0)\n{\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__n, false);\n    }\n}\n\n#if _LIBCPP_STD_VER > 11\ntemplate <class _Allocator>\nvector<bool, _Allocator>::vector(size_type __n, const allocator_type& __a)\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0, static_cast<__storage_allocator>(__a))\n{\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__n, false);\n    }\n}\n#endif\n\ntemplate <class _Allocator>\nvector<bool, _Allocator>::vector(size_type __n, const value_type& __x)\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0)\n{\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__n, __x);\n    }\n}\n\ntemplate <class _Allocator>\nvector<bool, _Allocator>::vector(size_type __n, const value_type& __x, const allocator_type& __a)\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0, static_cast<__storage_allocator>(__a))\n{\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__n, __x);\n    }\n}\n\ntemplate <class _Allocator>\ntemplate <class _InputIterator>\nvector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,\n       typename enable_if<__is_input_iterator  <_InputIterator>::value &&\n                         !__is_forward_iterator<_InputIterator>::value>::type*)\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        for (; __first != __last; ++__first)\n            push_back(*__first);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        if (__begin_ != nullptr)\n            __storage_traits::deallocate(__alloc(), __begin_, __cap());\n        __invalidate_all_iterators();\n        throw;\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate <class _Allocator>\ntemplate <class _InputIterator>\nvector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,\n       typename enable_if<__is_input_iterator  <_InputIterator>::value &&\n                         !__is_forward_iterator<_InputIterator>::value>::type*)\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0, static_cast<__storage_allocator>(__a))\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        for (; __first != __last; ++__first)\n            push_back(*__first);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        if (__begin_ != nullptr)\n            __storage_traits::deallocate(__alloc(), __begin_, __cap());\n        __invalidate_all_iterators();\n        throw;\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate <class _Allocator>\ntemplate <class _ForwardIterator>\nvector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last,\n                                typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type*)\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0)\n{\n    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__first, __last);\n    }\n}\n\ntemplate <class _Allocator>\ntemplate <class _ForwardIterator>\nvector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,\n                                typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type*)\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0, static_cast<__storage_allocator>(__a))\n{\n    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__first, __last);\n    }\n}\n\n#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Allocator>\nvector<bool, _Allocator>::vector(initializer_list<value_type> __il)\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0)\n{\n    size_type __n = static_cast<size_type>(__il.size());\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__il.begin(), __il.end());\n    }\n}\n\ntemplate <class _Allocator>\nvector<bool, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0, static_cast<__storage_allocator>(__a))\n{\n    size_type __n = static_cast<size_type>(__il.size());\n    if (__n > 0)\n    {\n        allocate(__n);\n        __construct_at_end(__il.begin(), __il.end());\n    }\n}\n\n#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS\n\ntemplate <class _Allocator>\nvector<bool, _Allocator>::~vector()\n{\n    if (__begin_ != nullptr)\n        __storage_traits::deallocate(__alloc(), __begin_, __cap());\n    __invalidate_all_iterators();\n}\n\ntemplate <class _Allocator>\nvector<bool, _Allocator>::vector(const vector& __v)\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0, __storage_traits::select_on_container_copy_construction(__v.__alloc()))\n{\n    if (__v.size() > 0)\n    {\n        allocate(__v.size());\n        __construct_at_end(__v.begin(), __v.end());\n    }\n}\n\ntemplate <class _Allocator>\nvector<bool, _Allocator>::vector(const vector& __v, const allocator_type& __a)\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0, __a)\n{\n    if (__v.size() > 0)\n    {\n        allocate(__v.size());\n        __construct_at_end(__v.begin(), __v.end());\n    }\n}\n\ntemplate <class _Allocator>\nvector<bool, _Allocator>&\nvector<bool, _Allocator>::operator=(const vector& __v)\n{\n    if (this != &__v)\n    {\n        __copy_assign_alloc(__v);\n        if (__v.__size_)\n        {\n            if (__v.__size_ > capacity())\n            {\n                deallocate();\n                allocate(__v.__size_);\n            }\n            _VSTD::copy(__v.__begin_, __v.__begin_ + __external_cap_to_internal(__v.__size_), __begin_);\n        }\n        __size_ = __v.__size_;\n    }\n    return *this;\n}\n\n#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvector<bool, _Allocator>::vector(vector&& __v)\n#if _LIBCPP_STD_VER > 14\n        _NOEXCEPT\n#else\n        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)\n#endif\n    : __begin_(__v.__begin_),\n      __size_(__v.__size_),\n      __cap_alloc_(__v.__cap_alloc_)\n{\n    __v.__begin_ = nullptr;\n    __v.__size_ = 0;\n    __v.__cap() = 0;\n}\n\ntemplate <class _Allocator>\nvector<bool, _Allocator>::vector(vector&& __v, const allocator_type& __a)\n    : __begin_(nullptr),\n      __size_(0),\n      __cap_alloc_(0, __a)\n{\n    if (__a == allocator_type(__v.__alloc()))\n    {\n        this->__begin_ = __v.__begin_;\n        this->__size_ = __v.__size_;\n        this->__cap() = __v.__cap();\n        __v.__begin_ = nullptr;\n        __v.__cap() = __v.__size_ = 0;\n    }\n    else if (__v.size() > 0)\n    {\n        allocate(__v.size());\n        __construct_at_end(__v.begin(), __v.end());\n    }\n}\n\ntemplate <class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvector<bool, _Allocator>&\nvector<bool, _Allocator>::operator=(vector&& __v)\n        _NOEXCEPT_(\n             __alloc_traits::propagate_on_container_move_assignment::value &&\n             is_nothrow_move_assignable<allocator_type>::value)\n{\n    __move_assign(__v, integral_constant<bool,\n          __storage_traits::propagate_on_container_move_assignment::value>());\n    return *this;\n}\n\ntemplate <class _Allocator>\nvoid\nvector<bool, _Allocator>::__move_assign(vector& __c, false_type)\n{\n    if (__alloc() != __c.__alloc())\n        assign(__c.begin(), __c.end());\n    else\n        __move_assign(__c, true_type());\n}\n\ntemplate <class _Allocator>\nvoid\nvector<bool, _Allocator>::__move_assign(vector& __c, true_type)\n    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)\n{\n    deallocate();\n    __move_assign_alloc(__c);\n    this->__begin_ = __c.__begin_;\n    this->__size_ = __c.__size_;\n    this->__cap() = __c.__cap();\n    __c.__begin_ = nullptr;\n    __c.__cap() = __c.__size_ = 0;\n}\n\n#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES\n\ntemplate <class _Allocator>\nvoid\nvector<bool, _Allocator>::assign(size_type __n, const value_type& __x)\n{\n    __size_ = 0;\n    if (__n > 0)\n    {\n        size_type __c = capacity();\n        if (__n <= __c)\n            __size_ = __n;\n        else\n        {\n            vector __v(__alloc());\n            __v.reserve(__recommend(__n));\n            __v.__size_ = __n;\n            swap(__v);\n        }\n        _VSTD::fill_n(begin(), __n, __x);\n    }\n}\n\ntemplate <class _Allocator>\ntemplate <class _InputIterator>\ntypename enable_if\n<\n    __is_input_iterator<_InputIterator>::value &&\n   !__is_forward_iterator<_InputIterator>::value,\n   void\n>::type\nvector<bool, _Allocator>::assign(_InputIterator __first, _InputIterator __last)\n{\n    clear();\n    for (; __first != __last; ++__first)\n        push_back(*__first);\n}\n\ntemplate <class _Allocator>\ntemplate <class _ForwardIterator>\ntypename enable_if\n<\n    __is_forward_iterator<_ForwardIterator>::value,\n   void\n>::type\nvector<bool, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)\n{\n    clear();\n    difference_type __n = _VSTD::distance(__first, __last);\n    if (__n)\n    {\n        if (__n > capacity())\n        {\n            deallocate();\n            allocate(__n);\n        }\n        __construct_at_end(__first, __last);\n    }\n}\n\ntemplate <class _Allocator>\nvoid\nvector<bool, _Allocator>::reserve(size_type __n)\n{\n    if (__n > capacity())\n    {\n        vector __v(this->__alloc());\n        __v.allocate(__n);\n        __v.__construct_at_end(this->begin(), this->end());\n        swap(__v);\n        __invalidate_all_iterators();\n    }\n}\n\ntemplate <class _Allocator>\nvoid\nvector<bool, _Allocator>::shrink_to_fit() _NOEXCEPT\n{\n    if (__external_cap_to_internal(size()) > __cap())\n    {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            vector(*this, allocator_type(__alloc())).swap(*this);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n}\n\ntemplate <class _Allocator>\ntypename vector<bool, _Allocator>::reference\nvector<bool, _Allocator>::at(size_type __n)\n{\n    if (__n >= size())\n        this->__throw_out_of_range();\n    return (*this)[__n];\n}\n\ntemplate <class _Allocator>\ntypename vector<bool, _Allocator>::const_reference\nvector<bool, _Allocator>::at(size_type __n) const\n{\n    if (__n >= size())\n        this->__throw_out_of_range();\n    return (*this)[__n];\n}\n\ntemplate <class _Allocator>\nvoid\nvector<bool, _Allocator>::push_back(const value_type& __x)\n{\n    if (this->__size_ == this->capacity())\n        reserve(__recommend(this->__size_ + 1));\n    ++this->__size_;\n    back() = __x;\n}\n\ntemplate <class _Allocator>\ntypename vector<bool, _Allocator>::iterator\nvector<bool, _Allocator>::insert(const_iterator __position, const value_type& __x)\n{\n    iterator __r;\n    if (size() < capacity())\n    {\n        const_iterator __old_end = end();\n        ++__size_;\n        _VSTD::copy_backward(__position, __old_end, end());\n        __r = __const_iterator_cast(__position);\n    }\n    else\n    {\n        vector __v(__alloc());\n        __v.reserve(__recommend(__size_ + 1));\n        __v.__size_ = __size_ + 1;\n        __r = _VSTD::copy(cbegin(), __position, __v.begin());\n        _VSTD::copy_backward(__position, cend(), __v.end());\n        swap(__v);\n    }\n    *__r = __x;\n    return __r;\n}\n\ntemplate <class _Allocator>\ntypename vector<bool, _Allocator>::iterator\nvector<bool, _Allocator>::insert(const_iterator __position, size_type __n, const value_type& __x)\n{\n    iterator __r;\n    size_type __c = capacity();\n    if (__n <= __c && size() <= __c - __n)\n    {\n        const_iterator __old_end = end();\n        __size_ += __n;\n        _VSTD::copy_backward(__position, __old_end, end());\n        __r = __const_iterator_cast(__position);\n    }\n    else\n    {\n        vector __v(__alloc());\n        __v.reserve(__recommend(__size_ + __n));\n        __v.__size_ = __size_ + __n;\n        __r = _VSTD::copy(cbegin(), __position, __v.begin());\n        _VSTD::copy_backward(__position, cend(), __v.end());\n        swap(__v);\n    }\n    _VSTD::fill_n(__r, __n, __x);\n    return __r;\n}\n\ntemplate <class _Allocator>\ntemplate <class _InputIterator>\ntypename enable_if\n<\n     __is_input_iterator  <_InputIterator>::value &&\n    !__is_forward_iterator<_InputIterator>::value,\n    typename vector<bool, _Allocator>::iterator\n>::type\nvector<bool, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)\n{\n    difference_type __off = __position - begin();\n    iterator __p = __const_iterator_cast(__position);\n    iterator __old_end = end();\n    for (; size() != capacity() && __first != __last; ++__first)\n    {\n        ++this->__size_;\n        back() = *__first;\n    }\n    vector __v(__alloc());\n    if (__first != __last)\n    {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            __v.assign(__first, __last);\n            difference_type __old_size = static_cast<difference_type>(__old_end - begin());\n            difference_type __old_p = __p - begin();\n            reserve(__recommend(size() + __v.size()));\n            __p = begin() + __old_p;\n            __old_end = begin() + __old_size;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            erase(__old_end, end());\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n    __p = _VSTD::rotate(__p, __old_end, end());\n    insert(__p, __v.begin(), __v.end());\n    return begin() + __off;\n}\n\ntemplate <class _Allocator>\ntemplate <class _ForwardIterator>\ntypename enable_if\n<\n    __is_forward_iterator<_ForwardIterator>::value,\n    typename vector<bool, _Allocator>::iterator\n>::type\nvector<bool, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last)\n{\n    difference_type __n = _VSTD::distance(__first, __last);\n    iterator __r;\n    size_type __c = capacity();\n    if (__n <= __c && size() <= __c - __n)\n    {\n        const_iterator __old_end = end();\n        __size_ += __n;\n        _VSTD::copy_backward(__position, __old_end, end());\n        __r = __const_iterator_cast(__position);\n    }\n    else\n    {\n        vector __v(__alloc());\n        __v.reserve(__recommend(__size_ + __n));\n        __v.__size_ = __size_ + __n;\n        __r = _VSTD::copy(cbegin(), __position, __v.begin());\n        _VSTD::copy_backward(__position, cend(), __v.end());\n        swap(__v);\n    }\n    _VSTD::copy(__first, __last, __r);\n    return __r;\n}\n\ntemplate <class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename vector<bool, _Allocator>::iterator\nvector<bool, _Allocator>::erase(const_iterator __position)\n{\n    iterator __r = __const_iterator_cast(__position);\n    _VSTD::copy(__position + 1, this->cend(), __r);\n    --__size_;\n    return __r;\n}\n\ntemplate <class _Allocator>\ntypename vector<bool, _Allocator>::iterator\nvector<bool, _Allocator>::erase(const_iterator __first, const_iterator __last)\n{\n    iterator __r = __const_iterator_cast(__first);\n    difference_type __d = __last - __first;\n    _VSTD::copy(__last, this->cend(), __r);\n    __size_ -= __d;\n    return __r;\n}\n\ntemplate <class _Allocator>\nvoid\nvector<bool, _Allocator>::swap(vector& __x)\n#if _LIBCPP_STD_VER >= 14\n    _NOEXCEPT\n#else\n    _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || \n                __is_nothrow_swappable<allocator_type>::value)\n#endif\n{\n    _VSTD::swap(this->__begin_, __x.__begin_);\n    _VSTD::swap(this->__size_, __x.__size_);\n    _VSTD::swap(this->__cap(), __x.__cap());\n    __swap_allocator(this->__alloc(), __x.__alloc(), \n        integral_constant<bool, __alloc_traits::propagate_on_container_swap::value>());\n}\n\ntemplate <class _Allocator>\nvoid\nvector<bool, _Allocator>::resize(size_type __sz, value_type __x)\n{\n    size_type __cs = size();\n    if (__cs < __sz)\n    {\n        iterator __r;\n        size_type __c = capacity();\n        size_type __n = __sz - __cs;\n        if (__n <= __c && __cs <= __c - __n)\n        {\n            __r = end();\n            __size_ += __n;\n        }\n        else\n        {\n            vector __v(__alloc());\n            __v.reserve(__recommend(__size_ + __n));\n            __v.__size_ = __size_ + __n;\n            __r = _VSTD::copy(cbegin(), cend(), __v.begin());\n            swap(__v);\n        }\n        _VSTD::fill_n(__r, __n, __x);\n    }\n    else\n        __size_ = __sz;\n}\n\ntemplate <class _Allocator>\nvoid\nvector<bool, _Allocator>::flip() _NOEXCEPT\n{\n    // do middle whole words\n    size_type __n = __size_;\n    __storage_pointer __p = __begin_;\n    for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)\n        *__p = ~*__p;\n    // do last partial word\n    if (__n > 0)\n    {\n        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);\n        __storage_type __b = *__p & __m;\n        *__p &= ~__m;\n        *__p |= ~__b & __m;\n    }\n}\n\ntemplate <class _Allocator>\nbool\nvector<bool, _Allocator>::__invariants() const\n{\n    if (this->__begin_ == nullptr)\n    {\n        if (this->__size_ != 0 || this->__cap() != 0)\n            return false;\n    }\n    else\n    {\n        if (this->__cap() == 0)\n            return false;\n        if (this->__size_ > this->capacity())\n            return false;\n    }\n    return true;\n}\n\ntemplate <class _Allocator>\nsize_t\nvector<bool, _Allocator>::__hash_code() const _NOEXCEPT\n{\n    size_t __h = 0;\n    // do middle whole words\n    size_type __n = __size_;\n    __storage_pointer __p = __begin_;\n    for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)\n        __h ^= *__p;\n    // do last partial word\n    if (__n > 0)\n    {\n        const __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);\n        __h ^= *__p & __m;\n    }\n    return __h;\n}\n\ntemplate <class _Allocator>\nstruct _LIBCPP_TYPE_VIS_ONLY hash<vector<bool, _Allocator> >\n    : public unary_function<vector<bool, _Allocator>, size_t>\n{\n    _LIBCPP_INLINE_VISIBILITY\n    size_t operator()(const vector<bool, _Allocator>& __vec) const _NOEXCEPT\n        {return __vec.__hash_code();}\n};\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator==(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)\n{\n    const typename vector<_Tp, _Allocator>::size_type __sz = __x.size();\n    return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator!=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)\n{\n    return !(__x == __y);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator< (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)\n{\n    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator> (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)\n{\n    return __y < __x;\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator>=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)\n{\n    return !(__x < __y);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nbool\noperator<=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)\n{\n    return !(__y < __x);\n}\n\ntemplate <class _Tp, class _Allocator>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid\nswap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y)\n    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))\n{\n    __x.swap(__y);\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif  // _LIBCPP_VECTOR\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/lib/CMakeLists.txt",
    "content": "set(LIBCXX_LIB_CMAKEFILES_DIR \"${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}\"  PARENT_SCOPE)\n\n# Get sources\nfile(GLOB LIBCXX_SOURCES ../src/*.cpp)\nif(WIN32)\n  file(GLOB LIBCXX_WIN32_SOURCES ../src/support/win32/*.cpp)\n  list(APPEND LIBCXX_SOURCES ${LIBCXX_WIN32_SOURCES})\nelseif(\"${CMAKE_SYSTEM_NAME}\" STREQUAL \"SunOS\")\n  file(GLOB LIBCXX_SOLARIS_SOURCES ../src/support/solaris/*.c)\n  list(APPEND LIBCXX_SOURCES ${LIBCXX_SOLARIS_SOURCES})\nendif()\n\n# Add all the headers to the project for IDEs.\nif (MSVC_IDE OR XCODE)\n  file(GLOB_RECURSE LIBCXX_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/*)\n  if(WIN32)\n    file( GLOB LIBCXX_WIN32_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/support/win32/*.h)\n    list(APPEND LIBCXX_HEADERS ${LIBCXX_WIN32_HEADERS})\n  endif()\n  # Force them all into the headers dir on MSVC, otherwise they end up at\n  # project scope because they don't have extensions.\n  if (MSVC_IDE)\n    source_group(\"Header Files\" FILES ${LIBCXX_HEADERS})\n  endif()\nendif()\n\nif (LIBCXX_ENABLE_SHARED)\n  add_library(cxx SHARED ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})\nelse()\n  add_library(cxx STATIC ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})\nendif()\n\nif (DEFINED LIBCXX_CXX_ABI_DEPS)\n  add_dependencies(cxx LIBCXX_CXX_ABI_DEPS)\nendif()\n\n#if LIBCXX_CXX_ABI_LIBRARY_PATH is defined we want to add it to the search path.\nadd_link_flags_if(LIBCXX_CXX_ABI_LIBRARY_PATH \"-L${LIBCXX_CXX_ABI_LIBRARY_PATH}\")\n\nadd_library_flags_if(LIBCXX_COVERAGE_LIBRARY \"${LIBCXX_COVERAGE_LIBRARY}\")\n\nadd_library_flags_if(LIBCXX_ENABLE_STATIC_ABI_LIBRARY \"-Wl,--whole-archive\" \"-Wl,-Bstatic\")\nadd_library_flags(\"${LIBCXX_CXX_ABI_LIBRARY}\")\nadd_library_flags_if(LIBCXX_ENABLE_STATIC_ABI_LIBRARY \"-Wl,-Bdynamic\" \"-Wl,--no-whole-archive\")\n\nif (APPLE AND LLVM_USE_SANITIZER)\n  if (\"${LLVM_USE_SANITIZER}\" STREQUAL \"Address\")\n    set(LIBFILE \"libclang_rt.asan_osx_dynamic.dylib\")\n  elseif(\"${LLVM_USE_SANITIZER}\" STREQUAL \"Undefined\")\n    set(LIBFILE \"libclang_rt.ubsan_osx_dynamic.dylib\")\n  else()\n    message(WARNING \"LLVM_USE_SANITIZER=${LLVM_USE_SANITIZER} is not supported on OS X\")\n  endif()\n  if (LIBFILE)\n    execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=lib OUTPUT_VARIABLE LIBDIR RESULT_VARIABLE Result)\n    if (NOT ${Result} EQUAL \"0\")\n      message(FATAL \"Failed to find library resource directory\")\n    endif()\n    string(STRIP \"${LIBDIR}\" LIBDIR)\n    set(LIBDIR \"${LIBDIR}/darwin/\")\n    if (NOT IS_DIRECTORY \"${LIBDIR}\")\n      message(FATAL_ERROR \"Cannot find compiler-rt directory on OS X required for LLVM_USE_SANITIZER\")\n    endif()\n    set(LIBCXX_SANITIZER_LIBRARY \"${LIBDIR}/${LIBFILE}\")\n    set(LIBCXX_SANITIZER_LIBRARY \"${LIBCXX_SANITIZER_LIBRARY}\" PARENT_SCOPE)\n    message(STATUS \"Manually linking compiler-rt library: ${LIBCXX_SANITIZER_LIBRARY}\")\n    add_library_flags(\"${LIBCXX_SANITIZER_LIBRARY}\")\n    add_link_flags(\"-Wl,-rpath,${LIBDIR}\")\n  endif()\nendif()\n\n# Generate library list.\nadd_library_flags_if(LIBCXX_HAS_PTHREAD_LIB pthread)\nadd_library_flags_if(LIBCXX_HAS_C_LIB c)\nadd_library_flags_if(LIBCXX_HAS_M_LIB m)\nadd_library_flags_if(LIBCXX_HAS_RT_LIB rt)\nadd_library_flags_if(LIBCXX_HAS_GCC_S_LIB gcc_s)\n\n# Setup flags.\nadd_flags_if_supported(-fPIC)\nadd_link_flags_if_supported(-nodefaultlibs)\n\nif ( APPLE AND (LIBCXX_CXX_ABI_LIBNAME STREQUAL \"libcxxabi\" OR\n                LIBCXX_CXX_ABI_LIBNAME STREQUAL \"none\"))\n  if (NOT DEFINED LIBCXX_LIBCPPABI_VERSION)\n    set(LIBCXX_LIBCPPABI_VERSION \"2\")\n  endif()\n\n  if ( CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL \"10.6\" )\n    add_definitions(-D__STRICT_ANSI__)\n    add_link_flags(\n      \"-compatibility_version 1\"\n      \"-current_version 1\"\n      \"-install_name /usr/lib/libc++.1.dylib\"\n      \"-Wl,-reexport_library,/usr/lib/libc++abi.dylib\"\n      \"-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++unexp.exp\"\n      \"/usr/lib/libSystem.B.dylib\")\n  else()\n    if ( ${CMAKE_OSX_SYSROOT} )\n      list(FIND ${CMAKE_OSX_ARCHITECTURES} \"armv7\" OSX_HAS_ARMV7)\n      if (OSX_HAS_ARMV7)\n        set(OSX_RE_EXPORT_LINE\n          \"${CMAKE_OSX_SYSROOT}/usr/lib/libc++abi.dylib\"\n          \"-Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++sjlj-abi.exp\")\n      else()\n        set(OSX_RE_EXPORT_LINE\n          \"-Wl,-reexport_library,${CMAKE_OSX_SYSROOT}/usr/lib/libc++abi.dylib\")\n      endif()\n    else()\n      set (OSX_RE_EXPORT_LINE \"/usr/lib/libc++abi.dylib -Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++abi${LIBCXX_LIBCPPABI_VERSION}.exp\")\n    endif()\n\n    add_link_flags(\n      \"-compatibility_version 1\"\n      \"-install_name /usr/lib/libc++.1.dylib\"\n      \"-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++unexp.exp\"\n      \"${OSX_RE_EXPORT_LINE}\"\n      \"-Wl,-force_symbols_not_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/notweak.exp\"\n      \"-Wl,-force_symbols_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/weak.exp\")\n  endif()\nendif()\n\ntarget_link_libraries(cxx ${LIBCXX_LIBRARIES})\nsplit_list(LIBCXX_COMPILE_FLAGS)\nsplit_list(LIBCXX_LINK_FLAGS)\n\nset_target_properties(cxx\n  PROPERTIES\n    COMPILE_FLAGS \"${LIBCXX_COMPILE_FLAGS}\"\n    LINK_FLAGS    \"${LIBCXX_LINK_FLAGS}\"\n    OUTPUT_NAME   \"c++\"\n    VERSION       \"1.0\"\n    SOVERSION     \"1\"\n  )\n\ninstall(TARGETS cxx\n  LIBRARY DESTINATION lib${LIBCXX_LIBDIR_SUFFIX}\n  ARCHIVE DESTINATION lib${LIBCXX_LIBDIR_SUFFIX}\n  )\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/lib/buildit",
    "content": "#! /bin/sh\n#\n# Set the $TRIPLE environment variable to your system's triple before\n# running this script.  If you set $CXX, that will be used to compile\n# the library.  Otherwise we'll use clang++.\n\nset -e\n\nif [ `basename $(pwd)` != \"lib\" ]\nthen\n    echo \"current directory must be lib\"\n    exit 1\nfi\n\nif [ -z \"$CXX\" ]\nthen\n    CXX=clang++\nfi\n\nif [ -z \"$CXX_LANG\" ]\nthen\n    CXX_LANG=c++11\nfi\n\nif [ -z \"$CC\" ]\nthen\n    CC=clang\nfi\n\nif [ -z \"$MACOSX_DEPLOYMENT_TARGET\" ]\nthen\n    if [ -z \"$IPHONEOS_DEPLOYMENT_TARGET\" ]\n    then\n        MACOSX_DEPLOYMENT_TARGET=10.7\n    fi\nfi\n\nif [ -z \"$RC_ProjectSourceVersion\" ]\nthen\n  RC_ProjectSourceVersion=1\nfi\n\nEXTRA_FLAGS=\"-nostdinc++ -std=${CXX_LANG} -fstrict-aliasing -Wall -Wextra -Wshadow -Wconversion \\\n             -Wpadded -Wstrict-aliasing=2 -Wstrict-overflow=4 \"\n\ncase $TRIPLE in\n  *-apple-*)\n    if [ -z $RC_XBS ]\n    then\n      RC_CFLAGS=\"-arch i386 -arch x86_64\"\n    fi\n    SOEXT=dylib\n    if [ \"$MACOSX_DEPLOYMENT_TARGET\" = \"10.6\" ]\n    then\n        EXTRA_FLAGS=\"-nostdinc++ -std=c++11 -U__STRICT_ANSI__\"\n        LDSHARED_FLAGS=\"-o libc++.1.dylib \\\n            -dynamiclib -nodefaultlibs -current_version 1 \\\n            -compatibility_version 1 \\\n            -install_name /usr/lib/libc++.1.dylib \\\n            -Wl,-reexport_library,/usr/lib/libc++abi.dylib \\\n            -Wl,-unexported_symbols_list,libc++unexp.exp  \\\n            /usr/lib/libSystem.B.dylib\"\n    else\n        if [ -n \"$SDKROOT\" ]\n        then\n            EXTRA_FLAGS+=\"-isysroot ${SDKROOT} \"\n            if echo \"${RC_ARCHS}\" | grep -q \"armv7\"  \n            then\n                RE_EXPORT_LINE=\"${SDKROOT}/usr/lib/libc++abi.dylib -Wl,-reexported_symbols_list,libc++sjlj-abi.exp\"\n            else\n                RE_EXPORT_LINE=\"-Wl,-reexport_library,${SDKROOT}/usr/lib/libc++abi.dylib\"\n            fi\n            CXX=`xcrun -sdk \"${SDKROOT}\"  -find clang++`\n            CC=`xcrun -sdk \"${SDKROOT}\"  -find clang`\n        else\n            # Check if we have _LIBCPPABI_VERSION, to determine the reexport list to use.\n            if (echo \"#include <cxxabi.h>\" | $CXX -E -dM -x c++ - | \\\n                grep _LIBCPPABI_VERSION > /dev/null)\n            then\n                RE_EXPORT_LINE=\"/usr/lib/libc++abi.dylib -Wl,-reexported_symbols_list,libc++abi2.exp\"\n            else\n                RE_EXPORT_LINE=\"/usr/lib/libc++abi.dylib -Wl,-reexported_symbols_list,libc++abi.exp\"\n            fi\n        fi\n        LDSHARED_FLAGS=\"-o libc++.1.dylib \\\n            -dynamiclib -nodefaultlibs  \\\n            -current_version ${RC_ProjectSourceVersion} \\\n            -compatibility_version 1 \\\n            -install_name /usr/lib/libc++.1.dylib \\\n            -lSystem  \\\n            -Wl,-unexported_symbols_list,libc++unexp.exp  \\\n            ${RE_EXPORT_LINE}  \\\n            -Wl,-force_symbols_not_weak_list,notweak.exp \\\n            -Wl,-force_symbols_weak_list,weak.exp\"\n    fi\n    ;;\n  *-*-mingw*)\n    # FIXME: removing libgcc and libsupc++ dependencies means porting libcxxrt and LLVM/compiler-rt\n    SOEXT=dll\n    LDSHARED_FLAGS=\"-o libc++.dll \\\n        -shared -nodefaultlibs -Wl,--export-all-symbols -Wl,--allow-multiple-definition -Wl,--out-implib,libc++.dll.a \\\n        -lsupc++ -lpthread -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcr100 -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt\"\n    ;;\n  *-ibm-*)\n    hostOS=`uname`\n    hostOS=`echo $hostOS | sed -e \"s/\\s+$//\"`\n    hostOS=`echo $hostOS | tr '[A-Z]' '[a-z]'`\n\n    if [ $hostOS = \"linux\" ]\n    then\n      LDSHARED_FLAGS=\"-o libc++.so.1 \\\n        -qmkshrobj -Wl,-soname,libc++.so.1 \\\n        -lpthread -lrt -lc -lstdc++\"\n      EXTRA_FLAGS=\"-qlanglvl=extended0x -D__GLIBCXX__=1\"\n    else\n      LDSHARED_FLAGS=\"-o shr.o -qmkshrobj -lpthread -bnoquiet\"\n      EXTRA_FLAGS=\"-qlanglvl=extended0x\"\n    fi\n    RC_CFLAGS=\"-qpic=large\"\n    ;;\n  *)\n    RC_CFLAGS=\"-fPIC\"\n    SOEXT=so\n    LDSHARED_FLAGS=\"-o libc++.so.1.0 \\\n        -shared -nodefaultlibs -Wl,-soname,libc++.so.1 \\\n        -lpthread -lrt -lc -lstdc++\"\n    ;;\nesac\n\nif [ -z \"$RC_XBS\" ]\nthen\n    rm -f libc++.1.$SOEXT*\nfi\n\nset -x\n\nfor FILE in ../src/*.cpp; do\n    $CXX -c -g -Os $RC_CFLAGS $EXTRA_FLAGS -I../include $FILE\ndone\ncase $TRIPLE in\n  *-*-mingw*)\n  for FILE in ../src/support/win32/*.cpp; do\n    $CXX -c -g -Os $RC_CFLAGS $EXTRA_FLAGS -I../include $FILE\n  done\n  ;;\nesac\n$CC *.o $RC_CFLAGS $LDSHARED_FLAGS $EXTRA_FLAGS\n\n#libtool -static -o libc++.a *.o\n\n# Create the link for the final library name, so that we can use this directory\n# as a link target for the tests.\ncase $TRIPLE in\n    *-apple-*)\n        rm -f libc++.dylib\n        ln -s libc++.1.dylib libc++.dylib\n        ;;\n    *-*-mingw*)\n        ;;\n    *-ibm-*)\n        if [ $hostOS = \"linux\" ]\n        then\n           rm -f libc++.so\n           ln -s libc++.so.1 libc++.so\n        else #AIX\n           rm -f libc++.a\n           ar r libc++.a shr.o\n        fi\n        ;;\n    *)\n        rm -f libc++.so\n        ln -s libc++.so.1 libc++.so\n        ;;\nesac\n\nif [ -z \"$RC_XBS\" ]\nthen\n    rm *.o\nfi\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/lib/libc++abi.exp",
    "content": "___cxa_allocate_exception\n___cxa_end_catch\n___cxa_demangle\n___cxa_current_exception_type\n___cxa_call_unexpected\n___cxa_free_exception\n___cxa_get_exception_ptr\n___cxa_get_globals\n___cxa_get_globals_fast\n___cxa_guard_abort\n___cxa_guard_acquire\n___cxa_guard_release\n___cxa_rethrow\n___cxa_pure_virtual\n___cxa_begin_catch\n___cxa_throw\n___cxa_vec_cctor\n___cxa_vec_cleanup\n___cxa_vec_ctor\n___cxa_vec_delete\n___cxa_vec_delete2\n___cxa_vec_delete3\n___cxa_vec_dtor\n___cxa_vec_new\n___cxa_vec_new2\n___cxa_vec_new3\n___dynamic_cast\n___gxx_personality_v0\n__ZTIDi\n__ZTIDn\n__ZTIDs\n__ZTIPDi\n__ZTIPDn\n__ZTIPDs\n__ZTIPKDi\n__ZTIPKDn\n__ZTIPKDs\n__ZTSPm\n__ZTSPl\n__ZTSPj\n__ZTSPi\n__ZTSPh\n__ZTSPf\n__ZTSPe\n__ZTSPd\n__ZTSPc\n__ZTSPb\n__ZTSPa\n__ZTSPKc\n__ZTSPKy\n__ZTSPKx\n__ZTSPKw\n__ZTSPKv\n__ZTSPKt\n__ZTSPKs\n__ZTSPKm\n__ZTSPKl\n__ZTSPKi\n__ZTSPKh\n__ZTSPs\n__ZTSPt\n__ZTSPv\n__ZTSPw\n__ZTSPKa\n__ZTSPx\n__ZTSPy\n__ZTSPKd\n__ZTSPKe\n__ZTSPKj\n__ZTSPKb\n__ZTSPKf\n__ZTSv\n__ZTSt\n__ZTSs\n__ZTSm\n__ZTSl\n__ZTSj\n__ZTSi\n__ZTSh\n__ZTSf\n__ZTSe\n__ZTSd\n__ZTSc\n__ZTSw\n__ZTSx\n__ZTSy\n__ZTSb\n__ZTSa\n__ZTIPKh\n__ZTIPKf\n__ZTIPKe\n__ZTIPKd\n__ZTIPKc\n__ZTIPKb\n__ZTIPKa\n__ZTIPy\n__ZTIPx\n__ZTIPw\n__ZTIPv\n__ZTIPt\n__ZTIPs\n__ZTIPm\n__ZTIPl\n__ZTIPj\n__ZTIPi\n__ZTIPKi\n__ZTIPKj\n__ZTIPKl\n__ZTIPKm\n__ZTIPKs\n__ZTIPKt\n__ZTIPKv\n__ZTIPKw\n__ZTIPKx\n__ZTIPKy\n__ZTIPa\n__ZTIPb\n__ZTIPc\n__ZTIPd\n__ZTIPe\n__ZTIPf\n__ZTIPh\n__ZTVN10__cxxabiv129__pointer_to_member_type_infoE\n__ZTVN10__cxxabiv116__enum_type_infoE\n__ZTVN10__cxxabiv117__array_type_infoE\n__ZTVN10__cxxabiv117__class_type_infoE\n__ZTVN10__cxxabiv117__pbase_type_infoE\n__ZTVN10__cxxabiv119__pointer_type_infoE\n__ZTVN10__cxxabiv120__function_type_infoE\n__ZTVN10__cxxabiv120__si_class_type_infoE\n__ZTVN10__cxxabiv121__vmi_class_type_infoE\n__ZTVN10__cxxabiv123__fundamental_type_infoE\n__ZTIa\n__ZTIb\n__ZTIc\n__ZTId\n__ZTIe\n__ZTIf\n__ZTIh\n__ZTIi\n__ZTIj\n__ZTIl\n__ZTIm\n__ZTIs\n__ZTIt\n__ZTSN10__cxxabiv129__pointer_to_member_type_infoE\n__ZTSN10__cxxabiv123__fundamental_type_infoE\n__ZTSN10__cxxabiv121__vmi_class_type_infoE\n__ZTSN10__cxxabiv120__si_class_type_infoE\n__ZTSN10__cxxabiv120__function_type_infoE\n__ZTSN10__cxxabiv119__pointer_type_infoE\n__ZTSN10__cxxabiv117__pbase_type_infoE\n__ZTSN10__cxxabiv117__class_type_infoE\n__ZTSN10__cxxabiv117__array_type_infoE\n__ZTSN10__cxxabiv116__enum_type_infoE\n__ZTIy\n__ZTIx\n__ZTIw\n__ZTIv\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/lib/libc++abi2.exp",
    "content": "___cxa_allocate_exception\n___cxa_end_catch\n___cxa_demangle\n___cxa_current_exception_type\n___cxa_call_unexpected\n___cxa_free_exception\n___cxa_get_exception_ptr\n___cxa_get_globals\n___cxa_get_globals_fast\n___cxa_guard_abort\n___cxa_guard_acquire\n___cxa_guard_release\n___cxa_rethrow\n___cxa_pure_virtual\n___cxa_begin_catch\n___cxa_throw\n___cxa_vec_cctor\n___cxa_vec_cleanup\n___cxa_vec_ctor\n___cxa_vec_delete\n___cxa_vec_delete2\n___cxa_vec_delete3\n___cxa_vec_dtor\n___cxa_vec_new\n___cxa_vec_new2\n___cxa_vec_new3\n___dynamic_cast\n___gxx_personality_v0\n__ZTIDi\n__ZTIDn\n__ZTIDs\n__ZTIPDi\n__ZTIPDn\n__ZTIPDs\n__ZTIPKDi\n__ZTIPKDn\n__ZTIPKDs\n__ZTSPm\n__ZTSPl\n__ZTSPj\n__ZTSPi\n__ZTSPh\n__ZTSPf\n__ZTSPe\n__ZTSPd\n__ZTSPc\n__ZTSPb\n__ZTSPa\n__ZTSPKc\n__ZTSPKy\n__ZTSPKx\n__ZTSPKw\n__ZTSPKv\n__ZTSPKt\n__ZTSPKs\n__ZTSPKm\n__ZTSPKl\n__ZTSPKi\n__ZTSPKh\n__ZTSPs\n__ZTSPt\n__ZTSPv\n__ZTSPw\n__ZTSPKa\n__ZTSPx\n__ZTSPy\n__ZTSPKd\n__ZTSPKe\n__ZTSPKj\n__ZTSPKb\n__ZTSPKf\n__ZTSv\n__ZTSt\n__ZTSs\n__ZTSm\n__ZTSl\n__ZTSj\n__ZTSi\n__ZTSh\n__ZTSf\n__ZTSe\n__ZTSd\n__ZTSc\n__ZTSw\n__ZTSx\n__ZTSy\n__ZTSb\n__ZTSa\n__ZTIPKh\n__ZTIPKf\n__ZTIPKe\n__ZTIPKd\n__ZTIPKc\n__ZTIPKb\n__ZTIPKa\n__ZTIPy\n__ZTIPx\n__ZTIPw\n__ZTIPv\n__ZTIPt\n__ZTIPs\n__ZTIPm\n__ZTIPl\n__ZTIPj\n__ZTIPi\n__ZTIPKi\n__ZTIPKj\n__ZTIPKl\n__ZTIPKm\n__ZTIPKs\n__ZTIPKt\n__ZTIPKv\n__ZTIPKw\n__ZTIPKx\n__ZTIPKy\n__ZTIPa\n__ZTIPb\n__ZTIPc\n__ZTIPd\n__ZTIPe\n__ZTIPf\n__ZTIPh\n__ZTVN10__cxxabiv129__pointer_to_member_type_infoE\n__ZTVN10__cxxabiv116__enum_type_infoE\n__ZTVN10__cxxabiv117__array_type_infoE\n__ZTVN10__cxxabiv117__class_type_infoE\n__ZTVN10__cxxabiv117__pbase_type_infoE\n__ZTVN10__cxxabiv119__pointer_type_infoE\n__ZTVN10__cxxabiv120__function_type_infoE\n__ZTVN10__cxxabiv120__si_class_type_infoE\n__ZTVN10__cxxabiv121__vmi_class_type_infoE\n__ZTVN10__cxxabiv123__fundamental_type_infoE\n__ZTIa\n__ZTIb\n__ZTIc\n__ZTId\n__ZTIe\n__ZTIf\n__ZTIh\n__ZTIi\n__ZTIj\n__ZTIl\n__ZTIm\n__ZTIs\n__ZTIt\n__ZTSN10__cxxabiv129__pointer_to_member_type_infoE\n__ZTSN10__cxxabiv123__fundamental_type_infoE\n__ZTSN10__cxxabiv121__vmi_class_type_infoE\n__ZTSN10__cxxabiv120__si_class_type_infoE\n__ZTSN10__cxxabiv120__function_type_infoE\n__ZTSN10__cxxabiv119__pointer_type_infoE\n__ZTSN10__cxxabiv117__pbase_type_infoE\n__ZTSN10__cxxabiv117__class_type_infoE\n__ZTSN10__cxxabiv117__array_type_infoE\n__ZTSN10__cxxabiv116__enum_type_infoE\n__ZTIy\n__ZTIx\n__ZTIw\n__ZTIv\n__ZSt13get_terminatev\n__ZSt13set_terminatePFvvE\n__ZSt14get_unexpectedv\n__ZSt14set_unexpectedPFvvE\n__ZSt15get_new_handlerv\n__ZSt15set_new_handlerPFvvE\n__ZSt9terminatev\n__ZNSt9bad_allocD1Ev\n__ZTISt9bad_alloc\n__ZNSt9bad_allocC1Ev\n__ZTISt13bad_exception\n__ZTVSt10bad_typeid\n__ZTVSt9exception\n__ZNSt10bad_typeidC1Ev\n__ZNSt10bad_typeidC1Ev\n__ZNKSt10bad_typeid4whatEv\n__ZNSt10bad_typeidD1Ev\n__ZTVSt8bad_cast\n__ZNSt8bad_castC1Ev\n__ZNSt8bad_castC2Ev\n__ZNSt8bad_castD0Ev\n__ZNKSt8bad_cast4whatEv\n__ZNSt8bad_castD1Ev\n__ZNSt8bad_castD2Ev\n__ZTVSt9bad_alloc\n__ZTVSt20bad_array_new_length\n__ZTVSt13bad_exception\n__ZNKSt9exception4whatEv\n__ZNKSt9bad_alloc4whatEv\n__ZNSt9bad_allocC2Ev\n__ZNSt9bad_allocD0Ev\n__ZNSt9bad_allocD2Ev\n__ZNSt9exceptionD0Ev\n__ZNSt20bad_array_new_lengthC1Ev\n__ZNKSt13bad_exception4whatEv\n__ZNSt9exceptionD1Ev\n__ZNKSt20bad_array_new_length4whatEv\n__ZNSt13bad_exceptionD1Ev\n__ZNSt20bad_array_new_lengthD1Ev\n__ZNSt9exceptionD2Ev\n__ZNSt9type_infoD0Ev\n__ZNSt9type_infoD1Ev\n__ZNSt9type_infoD2Ev\n__ZNSt10bad_typeidC2Ev\n__ZNSt10bad_typeidD0Ev\n__ZNSt10bad_typeidD2Ev\n__ZNSt13bad_exceptionD0Ev\n__ZNSt13bad_exceptionD2Ev\n__ZNSt20bad_array_new_lengthC2Ev\n__ZNSt20bad_array_new_lengthD0Ev\n__ZNSt20bad_array_new_lengthD2Ev\n__ZSt10unexpectedv\n# __ZdaPv\n# __ZdlPv\n# __ZdlPvRKSt9nothrow_t\n# __Znam\n# __ZdaPvRKSt9nothrow_t\n# __Znwm\n# __ZnwmRKSt9nothrow_t\n# __ZnamRKSt9nothrow_t\n__ZTISt10bad_typeid\n__ZTISt8bad_cast\n___cxa_bad_typeid\n___cxa_bad_cast\n__ZTISt9exception\n__ZTISt9type_info\n__ZTISt20bad_array_new_length\n\n__ZNKSt11logic_error4whatEv\n__ZNSt11logic_errorD0Ev\n__ZNSt11logic_errorD1Ev\n__ZNSt11logic_errorD2Ev\n__ZTISt11logic_error\n__ZTSSt11logic_error\n__ZTVSt11logic_error\n\n__ZNKSt13runtime_error4whatEv\n__ZNSt13runtime_errorD0Ev\n__ZNSt13runtime_errorD1Ev\n__ZNSt13runtime_errorD2Ev\n__ZTISt13runtime_error\n__ZTSSt13runtime_error\n__ZTVSt13runtime_error\n\n__ZNSt11range_errorD0Ev\n__ZNSt11range_errorD1Ev\n__ZNSt11range_errorD2Ev\n__ZTISt11range_error\n__ZTSSt11range_error\n__ZTVSt11range_error\n\n__ZNSt12domain_errorD0Ev\n__ZNSt12domain_errorD1Ev\n__ZNSt12domain_errorD2Ev\n__ZTISt12domain_error\n__ZTSSt12domain_error\n__ZTVSt12domain_error\n\n__ZNSt12length_errorD0Ev\n__ZNSt12length_errorD1Ev\n__ZNSt12length_errorD2Ev\n__ZTISt12length_error\n__ZTSSt12length_error\n__ZTVSt12length_error\n\n__ZNSt12out_of_rangeD0Ev\n__ZNSt12out_of_rangeD1Ev\n__ZNSt12out_of_rangeD2Ev\n__ZTISt12out_of_range\n__ZTSSt12out_of_range\n__ZTVSt12out_of_range\n\n__ZNSt14overflow_errorD0Ev\n__ZNSt14overflow_errorD1Ev\n__ZNSt14overflow_errorD2Ev\n__ZTISt14overflow_error\n__ZTSSt14overflow_error\n__ZTVSt14overflow_error\n\n__ZNSt15underflow_errorD0Ev\n__ZNSt15underflow_errorD1Ev\n__ZNSt15underflow_errorD2Ev\n__ZTISt15underflow_error\n__ZTSSt15underflow_error\n__ZTVSt15underflow_error\n\n__ZNSt16invalid_argumentD0Ev\n__ZNSt16invalid_argumentD1Ev\n__ZNSt16invalid_argumentD2Ev\n__ZTISt16invalid_argument\n__ZTSSt16invalid_argument\n__ZTVSt16invalid_argument\n\n__ZTSDi\n__ZTSDn\n__ZTSDs\n__ZTSPDi\n__ZTSPDn\n__ZTSPDs\n__ZTSPKDi\n__ZTSPKDn\n__ZTSPKDs\n\n__ZTSSt8bad_cast\n__ZTSSt9bad_alloc\n__ZTSSt9exception\n__ZTSSt9type_info\n__ZTSSt10bad_typeid\n__ZTSSt13bad_exception\n__ZTSSt20bad_array_new_length\n__ZTVSt9type_info\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/lib/libc++sjlj-abi.exp",
    "content": "___cxa_allocate_exception\n___cxa_end_catch\n___cxa_demangle\n___cxa_current_exception_type\n___cxa_call_unexpected\n___cxa_free_exception\n___cxa_get_exception_ptr\n___cxa_get_globals\n___cxa_get_globals_fast\n___cxa_guard_abort\n___cxa_guard_acquire\n___cxa_guard_release\n___cxa_rethrow\n___cxa_pure_virtual\n___cxa_begin_catch\n___cxa_throw\n___cxa_vec_cctor\n___cxa_vec_cleanup\n___cxa_vec_ctor\n___cxa_vec_delete\n___cxa_vec_delete2\n___cxa_vec_delete3\n___cxa_vec_dtor\n___cxa_vec_new\n___cxa_vec_new2\n___cxa_vec_new3\n___dynamic_cast\n___gxx_personality_sj0\n__ZTIDi\n__ZTIDn\n__ZTIDs\n__ZTIPDi\n__ZTIPDn\n__ZTIPDs\n__ZTIPKDi\n__ZTIPKDn\n__ZTIPKDs\n__ZTSPm\n__ZTSPl\n__ZTSPj\n__ZTSPi\n__ZTSPh\n__ZTSPf\n__ZTSPe\n__ZTSPd\n__ZTSPc\n__ZTSPb\n__ZTSPa\n__ZTSPKc\n__ZTSPKy\n__ZTSPKx\n__ZTSPKw\n__ZTSPKv\n__ZTSPKt\n__ZTSPKs\n__ZTSPKm\n__ZTSPKl\n__ZTSPKi\n__ZTSPKh\n__ZTSPs\n__ZTSPt\n__ZTSPv\n__ZTSPw\n__ZTSPKa\n__ZTSPx\n__ZTSPy\n__ZTSPKd\n__ZTSPKe\n__ZTSPKj\n__ZTSPKb\n__ZTSPKf\n__ZTSv\n__ZTSt\n__ZTSs\n__ZTSm\n__ZTSl\n__ZTSj\n__ZTSi\n__ZTSh\n__ZTSf\n__ZTSe\n__ZTSd\n__ZTSc\n__ZTSw\n__ZTSx\n__ZTSy\n__ZTSb\n__ZTSa\n__ZTIPKh\n__ZTIPKf\n__ZTIPKe\n__ZTIPKd\n__ZTIPKc\n__ZTIPKb\n__ZTIPKa\n__ZTIPy\n__ZTIPx\n__ZTIPw\n__ZTIPv\n__ZTIPt\n__ZTIPs\n__ZTIPm\n__ZTIPl\n__ZTIPj\n__ZTIPi\n__ZTIPKi\n__ZTIPKj\n__ZTIPKl\n__ZTIPKm\n__ZTIPKs\n__ZTIPKt\n__ZTIPKv\n__ZTIPKw\n__ZTIPKx\n__ZTIPKy\n__ZTIPa\n__ZTIPb\n__ZTIPc\n__ZTIPd\n__ZTIPe\n__ZTIPf\n__ZTIPh\n__ZTVN10__cxxabiv129__pointer_to_member_type_infoE\n__ZTVN10__cxxabiv116__enum_type_infoE\n__ZTVN10__cxxabiv117__array_type_infoE\n__ZTVN10__cxxabiv117__class_type_infoE\n__ZTVN10__cxxabiv117__pbase_type_infoE\n__ZTVN10__cxxabiv119__pointer_type_infoE\n__ZTVN10__cxxabiv120__function_type_infoE\n__ZTVN10__cxxabiv120__si_class_type_infoE\n__ZTVN10__cxxabiv121__vmi_class_type_infoE\n__ZTVN10__cxxabiv123__fundamental_type_infoE\n__ZTIa\n__ZTIb\n__ZTIc\n__ZTId\n__ZTIe\n__ZTIf\n__ZTIh\n__ZTIi\n__ZTIj\n__ZTIl\n__ZTIm\n__ZTIs\n__ZTIt\n__ZTSN10__cxxabiv129__pointer_to_member_type_infoE\n__ZTSN10__cxxabiv123__fundamental_type_infoE\n__ZTSN10__cxxabiv121__vmi_class_type_infoE\n__ZTSN10__cxxabiv120__si_class_type_infoE\n__ZTSN10__cxxabiv120__function_type_infoE\n__ZTSN10__cxxabiv119__pointer_type_infoE\n__ZTSN10__cxxabiv117__pbase_type_infoE\n__ZTSN10__cxxabiv117__class_type_infoE\n__ZTSN10__cxxabiv117__array_type_infoE\n__ZTSN10__cxxabiv116__enum_type_infoE\n__ZTIy\n__ZTIx\n__ZTIw\n__ZTIv\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/lib/libc++unexp.exp",
    "content": "# all guard variables\n__ZGVNSt3__*\n# all vtables\n# __ZTV*\n# all VTT\n# __ZTT*\n# all non-virtual thunks\n# __ZTh*\n# all virtual thunks\n# __ZTv*\n# typeinfo for std::__1::__types\n#    There are no std::__types\n# __ZTINSt3__1[0-9][0-9]*__*\n# typeinfo name for std::__1::__types\n__ZTSNSt3__1[0-9][0-9]*__*\n# anything using __hidden_allocator\n*__hidden_allocator*\n# anything using __sso_allocator\n*__sso_allocator*\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/lib/notweak.exp",
    "content": "# Remove the weak-def bit from these external symbols\n__ZT*\n__ZN*\n__ZS*\n\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/lib/weak.exp",
    "content": "__ZTISt10bad_typeid\n__ZTISt11logic_error\n__ZTISt11range_error\n__ZTISt12domain_error\n__ZTISt12length_error\n__ZTISt12out_of_range\n__ZTISt13bad_exception\n__ZTISt13runtime_error\n__ZTISt14overflow_error\n__ZTISt15underflow_error\n__ZTISt16invalid_argument\n__ZTISt16nested_exception\n__ZTISt20bad_array_new_length\n__ZTISt8bad_cast\n__ZTISt9bad_alloc\n__ZTISt9exception\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/lit.site.cfg",
    "content": "import os\nimport sys\n\n# Tell pylint that we know config and lit_config exist somewhere.\nif 'PYLINT_IMPORT' in os.environ:\n    config = object()\n    lit_config = object()\n\nndk = os.getenv('NDK')\nif ndk is None:\n    sys.exit('The environment variable NDK must point to an NDK toolchain.')\n\ntop = os.getenv('ANDROID_BUILD_TOP')\nout_dir = os.getenv('ANDROID_PRODUCT_OUT')\n\nif top is None or out_dir is None:\n    sys.exit('ANDROID_BUILD_TOP or ANDROID_PRODUCT_OUT is not set. Have you '\n             'run lunch?')\n\nconfig.cxx_under_test = os.path.join(\n    top, \"prebuilts/clang/linux-x86/host/3.6/bin/clang++\")\nconfig.std = \"c++11\"\nconfig.libcxx_src_root = os.path.join(top, \"external/libcxx\")\nconfig.libcxx_obj_root = os.path.join(top, \"external/libcxx\")\nconfig.cxx_library_root = os.path.join(out_dir, 'system/lib')\nconfig.enable_exceptions = \"True\"\nconfig.enable_rtti = \"True\"\nconfig.enable_shared = \"False\"\nconfig.enable_32bit = \"False\"\nconfig.enable_threads = \"True\"\nconfig.enable_monotonic_clock = \"True\"\nconfig.cxx_abi = \"libcxxabi\"\nconfig.use_sanitizer = \"\"\nconfig.configuration_variant = \"libcxx.ndk\"\nconfig.target_triple = \"armv7a-linux-androideabi\"\nconfig.sysroot = os.path.join(ndk, \"platforms/android-21/arch-arm/\")\nconfig.gcc_toolchain = os.path.join(\n    top, \"prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9\")\n\n# Let the main config do the real work.\nlit_config.load_config(\n    config, os.path.join(top, \"external/libcxx/test/lit.cfg\"))\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/ndk-test.sh",
    "content": "#!/bin/bash\n\n# This file should reside in test/, but it seems that if there is already one\n# lit.site.cfg in the test/ directory it is impossible to tell LIT to use\n# another. This will need to be fixed upstream before this can get a proper\n# home. The downside of this is that there isn't a way to run a subset of the\n# libc++ tests against the NDK.\nif [ -z \"$ANDROID_PRODUCT_OUT\" ]; then\n  >&2 echo \"Error: ANDROID_PRODUCT_OUT is not set. Have you run lunch?\"\n  exit 1\nfi\n\nif [ ! -f $ANDROID_PRODUCT_OUT/system/lib/libc++_ndk.so ]; then\n  >&2 echo \"Error: libc++_ndk.so has not been built for this target.\"\n  exit 1\nfi\n\nadb push $ANDROID_PRODUCT_OUT/system/lib/libc++_ndk.so /data/local/tmp\nlit -sv $* .\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/run-tests.py",
    "content": "#\n# Copyright (C) 2015 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nfrom __future__ import print_function\n\nimport argparse\nimport os\nimport subprocess\nimport sys\n\n\nTHIS_DIR = os.path.dirname(os.path.realpath(__file__))\nANDROID_DIR = os.path.realpath(os.path.join(THIS_DIR, '../..'))\n\n\nclass ArgParser(argparse.ArgumentParser):\n    def __init__(self):\n        super(ArgParser, self).__init__()\n        self.add_argument(\n            '--compiler', choices=('clang', 'gcc'), default='clang')\n        self.add_argument(\n            '--bitness', choices=(32, 64), type=int, default=32)\n        self.add_argument('--host', action='store_true')\n\n\ndef gen_test_config(bitness, compiler, host):\n    testconfig_mk_path = os.path.join(THIS_DIR, 'buildcmds/testconfig.mk')\n    with open(testconfig_mk_path, 'w') as test_config:\n        if compiler == 'clang':\n            print('LOCAL_CLANG := true', file=test_config)\n        elif compiler == 'gcc':\n            print('LOCAL_CLANG := false', file=test_config)\n\n        if bitness == 32:\n            print('LOCAL_MULTILIB := 32', file=test_config)\n        elif bitness == 64:\n            print('LOCAL_MULTILIB := 64', file=test_config)\n\n        if compiler == 'clang':\n            print('LOCAL_CXX := $(LOCAL_PATH)/buildcmdscc $(CLANG_CXX)',\n                  file=test_config)\n        else:\n            if host:\n                prefix = 'HOST_'\n            else:\n                prefix = 'TARGET_'\n            print('LOCAL_CXX := $(LOCAL_PATH)/buildcmdscc '\n                  '$($(LOCAL_2ND_ARCH_VAR_PREFIX){}CXX)'.format(prefix),\n                  file=test_config)\n\n        if host:\n            print('include $(BUILD_HOST_EXECUTABLE)', file=test_config)\n        else:\n            print('include $(BUILD_EXECUTABLE)', file=test_config)\n\n\ndef mmm(path):\n    makefile = os.path.join(path, 'Android.mk')\n    main_mk = 'build/core/main.mk'\n\n    env = dict(os.environ)\n    env['ONE_SHOT_MAKEFILE'] = makefile\n    env['LIBCXX_TESTING'] = 'true'\n    cmd = ['make', '-C', ANDROID_DIR, '-f', main_mk, 'all_modules']\n    subprocess.check_call(cmd, env=env)\n\n\ndef gen_build_cmds(bitness, compiler, host):\n    gen_test_config(bitness, compiler, host)\n    mmm(os.path.join(THIS_DIR, 'buildcmds'))\n\n\ndef main():\n    args, lit_args = ArgParser().parse_known_args()\n    lit_path = os.path.join(ANDROID_DIR, 'external/llvm/utils/lit/lit.py')\n    gen_build_cmds(args.bitness, args.compiler, args.host)\n\n    mode_str = 'host' if args.host else 'device'\n    android_mode_arg = '--param=android_mode=' + mode_str\n    test_path = os.path.join(THIS_DIR, 'test')\n\n    lit_args = ['-sv', android_mode_arg] + lit_args\n    cmd = ['python', lit_path] + lit_args + [test_path]\n    sys.exit(subprocess.call(cmd))\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/algorithm.cpp",
    "content": "//===----------------------- algorithm.cpp --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#undef _LIBCPP_EXTERN_TEMPLATE\n#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;\n#include \"algorithm\"\n#include \"random\"\n#include \"mutex\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate void __sort<__less<char>&, char*>(char*, char*, __less<char>&);\ntemplate void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);\ntemplate void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);\ntemplate void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);\ntemplate void __sort<__less<short>&, short*>(short*, short*, __less<short>&);\ntemplate void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);\ntemplate void __sort<__less<int>&, int*>(int*, int*, __less<int>&);\ntemplate void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);\ntemplate void __sort<__less<long>&, long*>(long*, long*, __less<long>&);\ntemplate void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);\ntemplate void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);\ntemplate void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&);\ntemplate void __sort<__less<float>&, float*>(float*, float*, __less<float>&);\ntemplate void __sort<__less<double>&, double*>(double*, double*, __less<double>&);\ntemplate void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);\n\ntemplate bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&);\ntemplate bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);\ntemplate bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);\ntemplate bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);\ntemplate bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&);\ntemplate bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);\ntemplate bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&);\ntemplate bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);\ntemplate bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&);\ntemplate bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);\ntemplate bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);\ntemplate bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&);\ntemplate bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&);\ntemplate bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&);\ntemplate bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);\n\ntemplate unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&);\n\n#ifndef _LIBCPP_HAS_NO_THREADS\nstatic pthread_mutex_t __rs_mut = PTHREAD_MUTEX_INITIALIZER;\n#endif\nunsigned __rs_default::__c_ = 0;\n\n__rs_default::__rs_default()\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    pthread_mutex_lock(&__rs_mut);\n#endif\n    __c_ = 1;\n}\n\n__rs_default::__rs_default(const __rs_default&)\n{\n    ++__c_;\n}\n\n__rs_default::~__rs_default()\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    if (--__c_ == 0)\n        pthread_mutex_unlock(&__rs_mut);\n#else\n    --__c_;\n#endif\n}\n\n__rs_default::result_type\n__rs_default::operator()()\n{\n    static mt19937 __rs_g;\n    return __rs_g();\n}\n\n__rs_default\n__rs_get()\n{\n    return __rs_default();\n}\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/any.cpp",
    "content": "//===---------------------------- any.cpp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"experimental/any\"\n\n_LIBCPP_BEGIN_NAMESPACE_LFTS\n\n// TODO(EricWF) Enable or delete these\n//bad_any_cast::bad_any_cast() _NOEXCEPT {}\n//bad_any_cast::~bad_any_cast() _NOEXCEPT {}\n\nconst char* bad_any_cast::what() const _NOEXCEPT {\n    return \"bad any cast\";\n}\n\n_LIBCPP_END_NAMESPACE_LFTS\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/bind.cpp",
    "content": "//===-------------------------- bind.cpp ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"functional\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nnamespace placeholders\n{\n\n__ph<1>   _1;\n__ph<2>   _2;\n__ph<3>   _3;\n__ph<4>   _4;\n__ph<5>   _5;\n__ph<6>   _6;\n__ph<7>   _7;\n__ph<8>   _8;\n__ph<9>   _9;\n__ph<10> _10;\n\n}  // placeholders\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/chrono.cpp",
    "content": "//===------------------------- chrono.cpp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"chrono\"\n#include \"cerrno\"        // errno\n#include \"system_error\"  // __throw_system_error\n#include <time.h>        // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME\n\n#if !defined(CLOCK_REALTIME)\n#include <sys/time.h>        // for gettimeofday and timeval\n#endif\n\n#if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(CLOCK_MONOTONIC)\n#if __APPLE__\n#include <mach/mach_time.h>  // mach_absolute_time, mach_timebase_info_data_t\n#else\n#error \"Monotonic clock not implemented\"\n#endif\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nnamespace chrono\n{\n\n// system_clock\n\nconst bool system_clock::is_steady;\n\nsystem_clock::time_point\nsystem_clock::now() _NOEXCEPT\n{\n#ifdef CLOCK_REALTIME\n    struct timespec tp;\n    if (0 != clock_gettime(CLOCK_REALTIME, &tp))\n        __throw_system_error(errno, \"clock_gettime(CLOCK_REALTIME) failed\");\n    return time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000));\n#else  // !CLOCK_REALTIME\n    timeval tv;\n    gettimeofday(&tv, 0);\n    return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));\n#endif  // CLOCK_REALTIME\n}\n\ntime_t\nsystem_clock::to_time_t(const time_point& t) _NOEXCEPT\n{\n    return time_t(duration_cast<seconds>(t.time_since_epoch()).count());\n}\n\nsystem_clock::time_point\nsystem_clock::from_time_t(time_t t) _NOEXCEPT\n{\n    return system_clock::time_point(seconds(t));\n}\n\n#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK\n// steady_clock\n//\n// Warning:  If this is not truly steady, then it is non-conforming.  It is\n//  better for it to not exist and have the rest of libc++ use system_clock\n//  instead.\n\nconst bool steady_clock::is_steady;\n\n#ifdef CLOCK_MONOTONIC\n\nsteady_clock::time_point\nsteady_clock::now() _NOEXCEPT\n{\n    struct timespec tp;\n    if (0 != clock_gettime(CLOCK_MONOTONIC, &tp))\n        __throw_system_error(errno, \"clock_gettime(CLOCK_MONOTONIC) failed\");\n    return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));\n}\n\n#elif defined(__APPLE__)\n\n//   mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of\n//   nanoseconds since the computer booted up.  MachInfo.numer and MachInfo.denom\n//   are run time constants supplied by the OS.  This clock has no relationship\n//   to the Gregorian calendar.  It's main use is as a high resolution timer.\n\n// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment.  Specialize\n//   for that case as an optimization.\n\n#pragma GCC visibility push(hidden)\n\nstatic\nsteady_clock::rep\nsteady_simplified()\n{\n    return static_cast<steady_clock::rep>(mach_absolute_time());\n}\n\nstatic\ndouble\ncompute_steady_factor()\n{\n    mach_timebase_info_data_t MachInfo;\n    mach_timebase_info(&MachInfo);\n    return static_cast<double>(MachInfo.numer) / MachInfo.denom;\n}\n\nstatic\nsteady_clock::rep\nsteady_full()\n{\n    static const double factor = compute_steady_factor();\n    return static_cast<steady_clock::rep>(mach_absolute_time() * factor);\n}\n\ntypedef steady_clock::rep (*FP)();\n\nstatic\nFP\ninit_steady_clock()\n{\n    mach_timebase_info_data_t MachInfo;\n    mach_timebase_info(&MachInfo);\n    if (MachInfo.numer == MachInfo.denom)\n        return &steady_simplified;\n    return &steady_full;\n}\n\n#pragma GCC visibility pop\n\nsteady_clock::time_point\nsteady_clock::now() _NOEXCEPT\n{\n    static FP fp = init_steady_clock();\n    return time_point(duration(fp()));\n}\n\n#else\n#error \"Monotonic clock not implemented\"\n#endif\n\n#endif // !_LIBCPP_HAS_NO_MONOTONIC_CLOCK\n\n}\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/condition_variable.cpp",
    "content": "//===-------------------- condition_variable.cpp --------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"__config\"\n\n#ifndef _LIBCPP_HAS_NO_THREADS\n\n#include \"condition_variable\"\n#include \"thread\"\n#include \"system_error\"\n#include \"cassert\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ncondition_variable::~condition_variable()\n{\n    pthread_cond_destroy(&__cv_);\n}\n\nvoid\ncondition_variable::notify_one() _NOEXCEPT\n{\n    pthread_cond_signal(&__cv_);\n}\n\nvoid\ncondition_variable::notify_all() _NOEXCEPT\n{\n    pthread_cond_broadcast(&__cv_);\n}\n\nvoid\ncondition_variable::wait(unique_lock<mutex>& lk) _NOEXCEPT\n{\n    if (!lk.owns_lock())\n        __throw_system_error(EPERM,\n                                  \"condition_variable::wait: mutex not locked\");\n    int ec = pthread_cond_wait(&__cv_, lk.mutex()->native_handle());\n    if (ec)\n        __throw_system_error(ec, \"condition_variable wait failed\");\n}\n\nvoid\ncondition_variable::__do_timed_wait(unique_lock<mutex>& lk,\n     chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp) _NOEXCEPT\n{\n    using namespace chrono;\n    if (!lk.owns_lock())\n        __throw_system_error(EPERM,\n                            \"condition_variable::timed wait: mutex not locked\");\n    nanoseconds d = tp.time_since_epoch();\n    if (d > nanoseconds(0x59682F000000E941))\n        d = nanoseconds(0x59682F000000E941);\n    timespec ts;\n    seconds s = duration_cast<seconds>(d);\n    typedef decltype(ts.tv_sec) ts_sec;\n    _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max();\n    if (s.count() < ts_sec_max)\n    {\n        ts.tv_sec = static_cast<ts_sec>(s.count());\n        ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((d - s).count());\n    }\n    else\n    {\n        ts.tv_sec = ts_sec_max;\n        ts.tv_nsec = giga::num - 1;\n    }\n    int ec = pthread_cond_timedwait(&__cv_, lk.mutex()->native_handle(), &ts);\n    if (ec != 0 && ec != ETIMEDOUT)\n        __throw_system_error(ec, \"condition_variable timed_wait failed\");\n}\n\nvoid\nnotify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk)\n{\n    __thread_local_data()->notify_all_at_thread_exit(&cond, lk.release());\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif // !_LIBCPP_HAS_NO_THREADS\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/config_elast.h",
    "content": "//===----------------------- config_elast.h -------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef _LIBCPP_CONFIG_ELAST\n#define _LIBCPP_CONFIG_ELAST\n\n#if defined(_WIN32)\n#include <stdlib.h>\n#else\n#include <errno.h>\n#endif\n\n#if defined(ELAST)\n#define _LIBCPP_ELAST ELAST\n#elif defined(_NEWLIB_VERSION)\n#define _LIBCPP_ELAST __ELASTERROR\n#elif defined(__linux__)\n#define _LIBCPP_ELAST 4095\n#elif defined(__APPLE__)\n// No _LIBCPP_ELAST needed on Apple\n#elif defined(__sun__)\n#define _LIBCPP_ELAST ESTALE\n#elif defined(_WIN32)\n#define _LIBCPP_ELAST _sys_nerr\n#else\n// Warn here so that the person doing the libcxx port has an easier time:\n#warning ELAST for this platform not yet implemented\n#endif\n\n#endif // _LIBCPP_CONFIG_ELAST\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/debug.cpp",
    "content": "//===-------------------------- debug.cpp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define _LIBCPP_DEBUG 1\n#include \"__config\"\n#include \"__debug\"\n#include \"functional\"\n#include \"algorithm\"\n#include \"__hash_table\"\n#include \"mutex\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n_LIBCPP_FUNC_VIS\n__libcpp_db*\n__get_db()\n{\n    static __libcpp_db db;\n    return &db;\n}\n\n_LIBCPP_FUNC_VIS\nconst __libcpp_db*\n__get_const_db()\n{\n    return __get_db();\n}\n\nnamespace\n{\n\n#ifndef _LIBCPP_HAS_NO_THREADS\ntypedef mutex mutex_type;\ntypedef lock_guard<mutex_type> WLock;\ntypedef lock_guard<mutex_type> RLock;\n\nmutex_type&\nmut()\n{\n    static mutex_type m;\n    return m;\n}\n#endif // !_LIBCPP_HAS_NO_THREADS\n\n}  // unnamed namespace\n\n__i_node::~__i_node()\n{\n    if (__next_)\n    {\n        __next_->~__i_node();\n        free(__next_);\n    }\n}\n\n__c_node::~__c_node()\n{\n    free(beg_);\n    if (__next_)\n    {\n        __next_->~__c_node();\n        free(__next_);\n    }\n}\n\n__libcpp_db::__libcpp_db()\n    : __cbeg_(nullptr),\n      __cend_(nullptr),\n      __csz_(0),\n      __ibeg_(nullptr),\n      __iend_(nullptr),\n      __isz_(0)\n{\n}\n\n__libcpp_db::~__libcpp_db()\n{\n    if (__cbeg_)\n    {\n        for (__c_node** p = __cbeg_; p != __cend_; ++p)\n        {\n            if (*p != nullptr)\n            {\n                (*p)->~__c_node();\n                free(*p);\n            }\n        }\n        free(__cbeg_);\n    }\n    if (__ibeg_)\n    {\n        for (__i_node** p = __ibeg_; p != __iend_; ++p)\n        {\n            if (*p != nullptr)\n            {\n                (*p)->~__i_node();\n                free(*p);\n            }\n        }\n        free(__ibeg_);\n    }\n}\n\nvoid*\n__libcpp_db::__find_c_from_i(void* __i) const\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    RLock _(mut());\n#endif\n    __i_node* i = __find_iterator(__i);\n    _LIBCPP_ASSERT(i != nullptr, \"iterator not found in debug database.\");\n    return i->__c_ != nullptr ? i->__c_->__c_ : nullptr;\n}\n\nvoid\n__libcpp_db::__insert_ic(void* __i, const void* __c)\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    WLock _(mut());\n#endif\n    if (__cbeg_ == __cend_)\n        return;\n    size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);\n    __c_node* c = __cbeg_[hc];\n    if (c == nullptr)\n        return;\n    while (c->__c_ != __c)\n    {\n        c = c->__next_;\n        if (c == nullptr)\n            return;\n    }\n    __i_node* i = __insert_iterator(__i);\n    c->__add(i);\n    i->__c_ = c;\n}\n\n__c_node*\n__libcpp_db::__insert_c(void* __c)\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    WLock _(mut());\n#endif\n    if (__csz_ + 1 > static_cast<size_t>(__cend_ - __cbeg_))\n    {\n        size_t nc = __next_prime(2*static_cast<size_t>(__cend_ - __cbeg_) + 1);\n        __c_node** cbeg = static_cast<__c_node**>(calloc(nc, sizeof(void*)));\n        if (cbeg == nullptr)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            throw bad_alloc();\n#else\n            abort();\n#endif\n        for (__c_node** p = __cbeg_; p != __cend_; ++p)\n        {\n            __c_node* q = *p;\n            while (q != nullptr)\n            {\n                size_t h = hash<void*>()(q->__c_) % nc;\n                __c_node* r = q->__next_;\n                q->__next_ = cbeg[h];\n                cbeg[h] = q;\n                q = r;\n            }\n        }\n        free(__cbeg_);\n        __cbeg_ = cbeg;\n        __cend_ = __cbeg_ + nc;\n    }\n    size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);\n    __c_node* p = __cbeg_[hc];\n    __c_node* r = __cbeg_[hc] =\n      static_cast<__c_node*>(malloc(sizeof(__c_node)));\n    if (__cbeg_[hc] == nullptr)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        throw bad_alloc();\n#else\n        abort();\n#endif\n    r->__c_ = __c;\n    r->__next_ = p;\n    ++__csz_;\n    return r;\n}\n\nvoid\n__libcpp_db::__erase_i(void* __i)\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    WLock _(mut());\n#endif\n    if (__ibeg_ != __iend_)\n    {\n        size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);\n        __i_node* p = __ibeg_[hi];\n        if (p != nullptr)\n        {\n            __i_node* q = nullptr;\n            while (p->__i_ != __i)\n            {\n                q = p;\n                p = p->__next_;\n                if (p == nullptr)\n                    return;\n            }\n            if (q == nullptr)\n                __ibeg_[hi] = p->__next_;\n            else\n                q->__next_ = p->__next_;\n            __c_node* c = p->__c_;\n            --__isz_;\n            if (c != nullptr)\n                c->__remove(p);\n            free(p);\n        }\n    }\n}\n\nvoid\n__libcpp_db::__invalidate_all(void* __c)\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    WLock _(mut());\n#endif\n    if (__cend_ != __cbeg_)\n    {\n        size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);\n        __c_node* p = __cbeg_[hc];\n        if (p == nullptr)\n            return;\n        while (p->__c_ != __c)\n        {\n            p = p->__next_;\n            if (p == nullptr)\n                return;\n        }\n        while (p->end_ != p->beg_)\n        {\n            --p->end_;\n            (*p->end_)->__c_ = nullptr;\n        }\n    }\n}\n\n__c_node*\n__libcpp_db::__find_c_and_lock(void* __c) const\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    mut().lock();\n#endif\n    if (__cend_ == __cbeg_)\n    {\n#ifndef _LIBCPP_HAS_NO_THREADS\n        mut().unlock();\n#endif\n        return nullptr;\n    }\n    size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);\n    __c_node* p = __cbeg_[hc];\n    if (p == nullptr)\n    {\n#ifndef _LIBCPP_HAS_NO_THREADS\n        mut().unlock();\n#endif\n        return nullptr;\n    }\n    while (p->__c_ != __c)\n    {\n        p = p->__next_;\n        if (p == nullptr)\n        {\n#ifndef _LIBCPP_HAS_NO_THREADS\n            mut().unlock();\n#endif\n            return nullptr;\n        }\n    }\n    return p;\n}\n\n__c_node*\n__libcpp_db::__find_c(void* __c) const\n{\n    size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);\n    __c_node* p = __cbeg_[hc];\n    _LIBCPP_ASSERT(p != nullptr, \"debug mode internal logic error __find_c A\");\n    while (p->__c_ != __c)\n    {\n        p = p->__next_;\n        _LIBCPP_ASSERT(p != nullptr, \"debug mode internal logic error __find_c B\");\n    }\n    return p;\n}\n\nvoid\n__libcpp_db::unlock() const\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    mut().unlock();\n#endif\n}\n\nvoid\n__libcpp_db::__erase_c(void* __c)\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    WLock _(mut());\n#endif\n    if (__cend_ != __cbeg_)\n    {\n        size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);\n        __c_node* p = __cbeg_[hc];\n        if (p == nullptr)\n            return;\n        __c_node* q = nullptr;\n        _LIBCPP_ASSERT(p != nullptr, \"debug mode internal logic error __erase_c A\");\n        while (p->__c_ != __c)\n        {\n            q = p;\n            p = p->__next_;\n            if (p == nullptr)\n                return;\n            _LIBCPP_ASSERT(p != nullptr, \"debug mode internal logic error __erase_c B\");\n        }\n        if (q == nullptr)\n            __cbeg_[hc] = p->__next_;\n        else\n            q->__next_ = p->__next_;\n        while (p->end_ != p->beg_)\n        {\n            --p->end_;\n            (*p->end_)->__c_ = nullptr;\n        }\n        free(p->beg_);\n        free(p);\n        --__csz_;\n    }\n}\n\nvoid\n__libcpp_db::__iterator_copy(void* __i, const void* __i0)\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    WLock _(mut());\n#endif\n    __i_node* i = __find_iterator(__i);\n    __i_node* i0 = __find_iterator(__i0);\n    __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr;\n    if (i == nullptr && i0 != nullptr)\n        i = __insert_iterator(__i);\n    __c_node* c = i != nullptr ? i->__c_ : nullptr;\n    if (c != c0)\n    {\n        if (c != nullptr)\n            c->__remove(i);\n        if (i != nullptr)\n        {\n            i->__c_ = nullptr;\n            if (c0 != nullptr)\n            {\n                i->__c_ = c0;\n                i->__c_->__add(i);\n            }\n        }\n    }\n}\n\nbool\n__libcpp_db::__dereferenceable(const void* __i) const\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    RLock _(mut());\n#endif\n    __i_node* i = __find_iterator(__i);\n    return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i);\n}\n\nbool\n__libcpp_db::__decrementable(const void* __i) const\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    RLock _(mut());\n#endif\n    __i_node* i = __find_iterator(__i);\n    return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i);\n}\n\nbool\n__libcpp_db::__addable(const void* __i, ptrdiff_t __n) const\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    RLock _(mut());\n#endif\n    __i_node* i = __find_iterator(__i);\n    return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n);\n}\n\nbool\n__libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    RLock _(mut());\n#endif\n    __i_node* i = __find_iterator(__i);\n    return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n);\n}\n\nbool\n__libcpp_db::__less_than_comparable(const void* __i, const void* __j) const\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    RLock _(mut());\n#endif\n    __i_node* i = __find_iterator(__i);\n    __i_node* j = __find_iterator(__j);\n    __c_node* ci = i != nullptr ? i->__c_ : nullptr;\n    __c_node* cj = j != nullptr ? j->__c_ : nullptr;\n    return ci != nullptr && ci == cj;\n}\n\nvoid\n__libcpp_db::swap(void* c1, void* c2)\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    WLock _(mut());\n#endif\n    size_t hc = hash<void*>()(c1) % static_cast<size_t>(__cend_ - __cbeg_);\n    __c_node* p1 = __cbeg_[hc];\n    _LIBCPP_ASSERT(p1 != nullptr, \"debug mode internal logic error swap A\");\n    while (p1->__c_ != c1)\n    {\n        p1 = p1->__next_;\n        _LIBCPP_ASSERT(p1 != nullptr, \"debug mode internal logic error swap B\");\n    }\n    hc = hash<void*>()(c2) % static_cast<size_t>(__cend_ - __cbeg_);\n    __c_node* p2 = __cbeg_[hc];\n    _LIBCPP_ASSERT(p2 != nullptr, \"debug mode internal logic error swap C\");\n    while (p2->__c_ != c2)\n    {\n        p2 = p2->__next_;\n        _LIBCPP_ASSERT(p2 != nullptr, \"debug mode internal logic error swap D\");\n    }\n    std::swap(p1->beg_, p2->beg_);\n    std::swap(p1->end_, p2->end_);\n    std::swap(p1->cap_, p2->cap_);\n    for (__i_node** p = p1->beg_; p != p1->end_; ++p)\n        (*p)->__c_ = p1;\n    for (__i_node** p = p2->beg_; p != p2->end_; ++p)\n        (*p)->__c_ = p2;\n}\n\nvoid\n__libcpp_db::__insert_i(void* __i)\n{\n#ifndef _LIBCPP_HAS_NO_THREADS\n    WLock _(mut());\n#endif\n    __insert_iterator(__i);\n}\n\nvoid\n__c_node::__add(__i_node* i)\n{\n    if (end_ == cap_)\n    {\n        size_t nc = 2*static_cast<size_t>(cap_ - beg_);\n        if (nc == 0)\n            nc = 1;\n        __i_node** beg =\n           static_cast<__i_node**>(malloc(nc * sizeof(__i_node*)));\n        if (beg == nullptr)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            throw bad_alloc();\n#else\n            abort();\n#endif\n        if (nc > 1)\n            memcpy(beg, beg_, nc/2*sizeof(__i_node*));\n        free(beg_);\n        beg_ = beg;\n        end_ = beg_ + nc/2;\n        cap_ = beg_ + nc;\n    }\n    *end_++ = i;\n}\n\n// private api\n\n_LIBCPP_HIDDEN\n__i_node*\n__libcpp_db::__insert_iterator(void* __i)\n{\n    if (__isz_ + 1 > static_cast<size_t>(__iend_ - __ibeg_))\n    {\n        size_t nc = __next_prime(2*static_cast<size_t>(__iend_ - __ibeg_) + 1);\n        __i_node** ibeg = static_cast<__i_node**>(calloc(nc, sizeof(void*)));\n        if (ibeg == nullptr)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            throw bad_alloc();\n#else\n            abort();\n#endif\n        for (__i_node** p = __ibeg_; p != __iend_; ++p)\n        {\n            __i_node* q = *p;\n            while (q != nullptr)\n            {\n                size_t h = hash<void*>()(q->__i_) % nc;\n                __i_node* r = q->__next_;\n                q->__next_ = ibeg[h];\n                ibeg[h] = q;\n                q = r;\n            }\n        }\n        free(__ibeg_);\n        __ibeg_ = ibeg;\n        __iend_ = __ibeg_ + nc;\n    }\n    size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);\n    __i_node* p = __ibeg_[hi];\n    __i_node* r = __ibeg_[hi] =\n      static_cast<__i_node*>(malloc(sizeof(__i_node)));\n    if (r == nullptr)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        throw bad_alloc();\n#else\n        abort();\n#endif\n    ::new(r) __i_node(__i, p, nullptr);\n    ++__isz_;\n    return r;\n}\n\n_LIBCPP_HIDDEN\n__i_node*\n__libcpp_db::__find_iterator(const void* __i) const\n{\n    __i_node* r = nullptr;\n    if (__ibeg_ != __iend_)\n    {\n        size_t h = hash<const void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);\n        for (__i_node* nd = __ibeg_[h]; nd != nullptr; nd = nd->__next_)\n        {\n            if (nd->__i_ == __i)\n            {\n                r = nd;\n                break;\n            }\n        }\n    }\n    return r;\n}\n\n_LIBCPP_HIDDEN\nvoid\n__c_node::__remove(__i_node* p)\n{\n    __i_node** r = find(beg_, end_, p);\n    _LIBCPP_ASSERT(r != end_, \"debug mode internal logic error __c_node::__remove\");\n    if (--end_ != r)\n        memmove(r, r+1, static_cast<size_t>(end_ - r)*sizeof(__i_node*));\n}\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/exception.cpp",
    "content": "//===------------------------ exception.cpp -------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n#include <stdlib.h>\n#include <stdio.h>\n\n#include \"exception\"\n#include \"new\"\n\n#ifndef __has_include\n#define __has_include(inc) 0\n#endif\n\n#if defined(__APPLE__) && !defined(LIBCXXRT)\n  #include <cxxabi.h>\n\n  using namespace __cxxabiv1;\n  #define HAVE_DEPENDENT_EH_ABI 1\n  #ifndef _LIBCPPABI_VERSION\n    using namespace __cxxabiapple;\n    // On Darwin, there are two STL shared libraries and a lower level ABI\n    // shared library.  The globals holding the current terminate handler and\n    // current unexpected handler are in the ABI library.\n    #define __terminate_handler  __cxxabiapple::__cxa_terminate_handler\n    #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler\n  #endif  // _LIBCPPABI_VERSION\n#elif defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI) || __has_include(<cxxabi.h>)\n  #include <cxxabi.h>\n  using namespace __cxxabiv1;\n  #if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION)\n    #define HAVE_DEPENDENT_EH_ABI 1\n  #endif\n#elif !defined(__GLIBCXX__) // __has_include(<cxxabi.h>)\n  static std::terminate_handler  __terminate_handler;\n  static std::unexpected_handler __unexpected_handler;\n#endif // __has_include(<cxxabi.h>)\n\nnamespace std\n{\n\n#if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)\n\n// libcxxrt provides implementations of these functions itself.\nunexpected_handler\nset_unexpected(unexpected_handler func) _NOEXCEPT\n{\n    return __sync_lock_test_and_set(&__unexpected_handler, func);\n}\n\nunexpected_handler\nget_unexpected() _NOEXCEPT\n{\n    return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0);\n}\n\n_LIBCPP_NORETURN\nvoid\nunexpected()\n{\n    (*get_unexpected())();\n    // unexpected handler should not return\n    terminate();\n}\n\nterminate_handler\nset_terminate(terminate_handler func) _NOEXCEPT\n{\n    return __sync_lock_test_and_set(&__terminate_handler, func);\n}\n\nterminate_handler\nget_terminate() _NOEXCEPT\n{\n    return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);\n}\n\n#ifndef __EMSCRIPTEN__ // We provide this in JS\n_LIBCPP_NORETURN\nvoid\nterminate() _NOEXCEPT\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        (*get_terminate())();\n        // handler should not return\n        fprintf(stderr, \"terminate_handler unexpectedly returned\\n\");\n        ::abort();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        // handler should not throw exception\n        fprintf(stderr, \"terminate_handler unexpectedly threw an exception\\n\");\n        ::abort();\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n#endif // !__EMSCRIPTEN__\n#endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)\n\n#if !defined(LIBCXXRT) && !defined(__GLIBCXX__) && !defined(__EMSCRIPTEN__)\nbool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }\n\nint uncaught_exceptions() _NOEXCEPT\n{\n#if defined(__APPLE__) || defined(_LIBCPPABI_VERSION)\n   // on Darwin, there is a helper function so __cxa_get_globals is private\n# if _LIBCPPABI_VERSION > 1101\n    return __cxa_uncaught_exceptions();\n# else\n    return __cxa_uncaught_exception() ? 1 : 0;\n# endif\n#else  // __APPLE__\n#   if defined(_MSC_VER) && ! defined(__clang__)\n        _LIBCPP_WARNING(\"uncaught_exceptions not yet implemented\")\n#   else\n#       warning uncaught_exception not yet implemented\n#   endif\n    fprintf(stderr, \"uncaught_exceptions not yet implemented\\n\");\n    ::abort();\n#endif  // __APPLE__\n}\n\n\n#ifndef _LIBCPPABI_VERSION\n\nexception::~exception() _NOEXCEPT\n{\n}\n\nconst char* exception::what() const _NOEXCEPT\n{\n  return \"std::exception\";\n}\n\n#endif  // _LIBCPPABI_VERSION\n#endif //LIBCXXRT\n#if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)\n\nbad_exception::~bad_exception() _NOEXCEPT\n{\n}\n\nconst char* bad_exception::what() const _NOEXCEPT\n{\n  return \"std::bad_exception\";\n}\n\n#endif\n\n#if defined(__GLIBCXX__)\n\n// libsupc++ does not implement the dependent EH ABI and the functionality\n// it uses to implement std::exception_ptr (which it declares as an alias of\n// std::__exception_ptr::exception_ptr) is not directly exported to clients. So\n// we have little choice but to hijack std::__exception_ptr::exception_ptr's\n// (which fortunately has the same layout as our std::exception_ptr) copy\n// constructor, assignment operator and destructor (which are part of its\n// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr)\n// function.\n\nnamespace __exception_ptr\n{\n\nstruct exception_ptr\n{\n    void* __ptr_;\n\n    exception_ptr(const exception_ptr&) _NOEXCEPT;\n    exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;\n    ~exception_ptr() _NOEXCEPT;\n};\n\n}\n\n_LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr);\n\n#endif\n\nexception_ptr::~exception_ptr() _NOEXCEPT\n{\n#if HAVE_DEPENDENT_EH_ABI\n    __cxa_decrement_exception_refcount(__ptr_);\n#elif defined(__GLIBCXX__)\n    reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr();\n#else\n#   if defined(_MSC_VER) && ! defined(__clang__)\n        _LIBCPP_WARNING(\"exception_ptr not yet implemented\")\n#   else\n#       warning exception_ptr not yet implemented\n#   endif\n    fprintf(stderr, \"exception_ptr not yet implemented\\n\");\n    ::abort();\n#endif\n}\n\nexception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT\n    : __ptr_(other.__ptr_)\n{\n#if HAVE_DEPENDENT_EH_ABI\n    __cxa_increment_exception_refcount(__ptr_);\n#elif defined(__GLIBCXX__)\n    new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr(\n        reinterpret_cast<const __exception_ptr::exception_ptr&>(other));\n#else\n#   if defined(_MSC_VER) && ! defined(__clang__)\n        _LIBCPP_WARNING(\"exception_ptr not yet implemented\")\n#   else\n#       warning exception_ptr not yet implemented\n#   endif\n    fprintf(stderr, \"exception_ptr not yet implemented\\n\");\n    ::abort();\n#endif\n}\n\nexception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT\n{\n#if HAVE_DEPENDENT_EH_ABI\n    if (__ptr_ != other.__ptr_)\n    {\n        __cxa_increment_exception_refcount(other.__ptr_);\n        __cxa_decrement_exception_refcount(__ptr_);\n        __ptr_ = other.__ptr_;\n    }\n    return *this;\n#elif defined(__GLIBCXX__)\n    *reinterpret_cast<__exception_ptr::exception_ptr*>(this) =\n        reinterpret_cast<const __exception_ptr::exception_ptr&>(other);\n    return *this;\n#else\n#   if defined(_MSC_VER) && ! defined(__clang__)\n        _LIBCPP_WARNING(\"exception_ptr not yet implemented\")\n#   else\n#       warning exception_ptr not yet implemented\n#   endif\n    fprintf(stderr, \"exception_ptr not yet implemented\\n\");\n    ::abort();\n#endif\n}\n\nnested_exception::nested_exception() _NOEXCEPT\n    : __ptr_(current_exception())\n{\n}\n\n#if !defined(__GLIBCXX__)\n\nnested_exception::~nested_exception() _NOEXCEPT\n{\n}\n\n#endif\n\n_LIBCPP_NORETURN\nvoid\nnested_exception::rethrow_nested() const\n{\n    if (__ptr_ == nullptr)\n        terminate();\n    rethrow_exception(__ptr_);\n}\n\n#if !defined(__GLIBCXX__)\n\nexception_ptr current_exception() _NOEXCEPT\n{\n#if HAVE_DEPENDENT_EH_ABI\n    // be nicer if there was a constructor that took a ptr, then\n    // this whole function would be just:\n    //    return exception_ptr(__cxa_current_primary_exception());\n    exception_ptr ptr;\n    ptr.__ptr_ = __cxa_current_primary_exception();\n    return ptr;\n#else\n#   if defined(_MSC_VER) && ! defined(__clang__)\n        _LIBCPP_WARNING( \"exception_ptr not yet implemented\" )\n#   else\n#       warning exception_ptr not yet implemented\n#   endif\n    fprintf(stderr, \"exception_ptr not yet implemented\\n\");\n    ::abort();\n#endif\n}\n\n#endif  // !__GLIBCXX__\n\n_LIBCPP_NORETURN\nvoid rethrow_exception(exception_ptr p)\n{\n#if HAVE_DEPENDENT_EH_ABI\n    __cxa_rethrow_primary_exception(p.__ptr_);\n    // if p.__ptr_ is NULL, above returns so we terminate\n    terminate();\n#elif defined(__GLIBCXX__)\n    rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p));\n#else\n#   if defined(_MSC_VER) && ! defined(__clang__)\n        _LIBCPP_WARNING(\"exception_ptr not yet implemented\")\n#   else\n#       warning exception_ptr not yet implemented\n#   endif\n    fprintf(stderr, \"exception_ptr not yet implemented\\n\");\n    ::abort();\n#endif\n}\n} // std\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/future.cpp",
    "content": "//===------------------------- future.cpp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"__config\"\n\n#ifndef _LIBCPP_HAS_NO_THREADS\n\n#include \"future\"\n#include \"string\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nclass _LIBCPP_HIDDEN __future_error_category\n    : public __do_message\n{\npublic:\n    virtual const char* name() const _NOEXCEPT;\n    virtual string message(int ev) const;\n};\n\nconst char*\n__future_error_category::name() const _NOEXCEPT\n{\n    return \"future\";\n}\n\n#if defined(__clang__)\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wswitch\"\n#elif defined(__GNUC__) || defined(__GNUG__)\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wswitch\"\n#endif\n\nstring\n__future_error_category::message(int ev) const\n{\n    switch (static_cast<future_errc>(ev))\n    {\n    case future_errc(0):  // For backwards compatibility with C++11 (LWG 2056)\n    case future_errc::broken_promise:\n        return string(\"The associated promise has been destructed prior \"\n                      \"to the associated state becoming ready.\");\n    case future_errc::future_already_retrieved:\n        return string(\"The future has already been retrieved from \"\n                      \"the promise or packaged_task.\");\n    case future_errc::promise_already_satisfied:\n        return string(\"The state of the promise has already been set.\");\n    case future_errc::no_state:\n        return string(\"Operation not permitted on an object without \"\n                      \"an associated state.\");\n    }\n    return string(\"unspecified future_errc value\\n\");\n}\n\n#if defined(__clang__)\n#pragma clang diagnostic pop\n#elif defined(__GNUC__) || defined(__GNUG__)\n#pragma GCC diagnostic pop\n#endif\n\nconst error_category&\nfuture_category() _NOEXCEPT\n{\n    static __future_error_category __f;\n    return __f;\n}\n\nfuture_error::future_error(error_code __ec)\n    : logic_error(__ec.message()),\n      __ec_(__ec)\n{\n}\n\nfuture_error::~future_error() _NOEXCEPT\n{\n}\n\nvoid\n__assoc_sub_state::__on_zero_shared() _NOEXCEPT\n{\n    delete this;\n}\n\nvoid\n__assoc_sub_state::set_value()\n{\n    unique_lock<mutex> __lk(__mut_);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__has_value())\n        throw future_error(make_error_code(future_errc::promise_already_satisfied));\n#endif\n    __state_ |= __constructed | ready;\n    __cv_.notify_all();\n}\n\nvoid\n__assoc_sub_state::set_value_at_thread_exit()\n{\n    unique_lock<mutex> __lk(__mut_);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__has_value())\n        throw future_error(make_error_code(future_errc::promise_already_satisfied));\n#endif\n    __state_ |= __constructed;\n    __thread_local_data()->__make_ready_at_thread_exit(this);\n}\n\nvoid\n__assoc_sub_state::set_exception(exception_ptr __p)\n{\n    unique_lock<mutex> __lk(__mut_);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__has_value())\n        throw future_error(make_error_code(future_errc::promise_already_satisfied));\n#endif\n    __exception_ = __p;\n    __state_ |= ready;\n    __cv_.notify_all();\n}\n\nvoid\n__assoc_sub_state::set_exception_at_thread_exit(exception_ptr __p)\n{\n    unique_lock<mutex> __lk(__mut_);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__has_value())\n        throw future_error(make_error_code(future_errc::promise_already_satisfied));\n#endif\n    __exception_ = __p;\n    __thread_local_data()->__make_ready_at_thread_exit(this);\n}\n\nvoid\n__assoc_sub_state::__make_ready()\n{\n    unique_lock<mutex> __lk(__mut_);\n    __state_ |= ready;\n    __cv_.notify_all();\n}\n\nvoid\n__assoc_sub_state::copy()\n{\n    unique_lock<mutex> __lk(__mut_);\n    __sub_wait(__lk);\n    if (__exception_ != nullptr)\n        rethrow_exception(__exception_);\n}\n\nvoid\n__assoc_sub_state::wait()\n{\n    unique_lock<mutex> __lk(__mut_);\n    __sub_wait(__lk);\n}\n\nvoid\n__assoc_sub_state::__sub_wait(unique_lock<mutex>& __lk)\n{\n    if (!__is_ready())\n    {\n        if (__state_ & static_cast<unsigned>(deferred))\n        {\n            __state_ &= ~static_cast<unsigned>(deferred);\n            __lk.unlock();\n            __execute();\n        }\n        else\n            while (!__is_ready())\n                __cv_.wait(__lk);\n    }\n}\n\nvoid\n__assoc_sub_state::__execute()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    throw future_error(make_error_code(future_errc::no_state));\n#endif\n}\n\nfuture<void>::future(__assoc_sub_state* __state)\n    : __state_(__state)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_->__has_future_attached())\n        throw future_error(make_error_code(future_errc::future_already_retrieved));\n#endif\n    __state_->__add_shared();\n    __state_->__set_future_attached();\n}\n\nfuture<void>::~future()\n{\n    if (__state_)\n        __state_->__release_shared();\n}\n\nvoid\nfuture<void>::get()\n{\n    unique_ptr<__shared_count, __release_shared_count> __(__state_);\n    __assoc_sub_state* __s = __state_;\n    __state_ = nullptr;\n    __s->copy();\n}\n\npromise<void>::promise()\n    : __state_(new __assoc_sub_state)\n{\n}\n\npromise<void>::~promise()\n{\n    if (__state_)\n    {\n        if (!__state_->__has_value() && __state_->use_count() > 1)\n            __state_->set_exception(make_exception_ptr(\n                      future_error(make_error_code(future_errc::broken_promise))\n                                                      ));\n        __state_->__release_shared();\n    }\n}\n\nfuture<void>\npromise<void>::get_future()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    return future<void>(__state_);\n}\n\nvoid\npromise<void>::set_value()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    __state_->set_value();\n}\n\nvoid\npromise<void>::set_exception(exception_ptr __p)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    __state_->set_exception(__p);\n}\n\nvoid\npromise<void>::set_value_at_thread_exit()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    __state_->set_value_at_thread_exit();\n}\n\nvoid\npromise<void>::set_exception_at_thread_exit(exception_ptr __p)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__state_ == nullptr)\n        throw future_error(make_error_code(future_errc::no_state));\n#endif\n    __state_->set_exception_at_thread_exit(__p);\n}\n\nshared_future<void>::~shared_future()\n{\n    if (__state_)\n        __state_->__release_shared();\n}\n\nshared_future<void>&\nshared_future<void>::operator=(const shared_future& __rhs)\n{\n    if (__rhs.__state_)\n        __rhs.__state_->__add_shared();\n    if (__state_)\n        __state_->__release_shared();\n    __state_ = __rhs.__state_;\n    return *this;\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif // !_LIBCPP_HAS_NO_THREADS\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/hash.cpp",
    "content": "//===-------------------------- hash.cpp ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"__hash_table\"\n#include \"algorithm\"\n#include \"stdexcept\"\n#include \"type_traits\"\n\n#ifdef __clang__\n#pragma clang diagnostic ignored \"-Wtautological-constant-out-of-range-compare\"\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nnamespace {\n\n// handle all next_prime(i) for i in [1, 210), special case 0\nconst unsigned small_primes[] =\n{\n    0,\n    2,\n    3,\n    5,\n    7,\n    11,\n    13,\n    17,\n    19,\n    23,\n    29,\n    31,\n    37,\n    41,\n    43,\n    47,\n    53,\n    59,\n    61,\n    67,\n    71,\n    73,\n    79,\n    83,\n    89,\n    97,\n    101,\n    103,\n    107,\n    109,\n    113,\n    127,\n    131,\n    137,\n    139,\n    149,\n    151,\n    157,\n    163,\n    167,\n    173,\n    179,\n    181,\n    191,\n    193,\n    197,\n    199,\n    211\n};\n\n// potential primes = 210*k + indices[i], k >= 1\n//   these numbers are not divisible by 2, 3, 5 or 7\n//   (or any integer 2 <= j <= 10 for that matter).\nconst unsigned indices[] =\n{\n    1,\n    11,\n    13,\n    17,\n    19,\n    23,\n    29,\n    31,\n    37,\n    41,\n    43,\n    47,\n    53,\n    59,\n    61,\n    67,\n    71,\n    73,\n    79,\n    83,\n    89,\n    97,\n    101,\n    103,\n    107,\n    109,\n    113,\n    121,\n    127,\n    131,\n    137,\n    139,\n    143,\n    149,\n    151,\n    157,\n    163,\n    167,\n    169,\n    173,\n    179,\n    181,\n    187,\n    191,\n    193,\n    197,\n    199,\n    209\n};\n\n}\n\n// Returns:  If n == 0, returns 0.  Else returns the lowest prime number that\n// is greater than or equal to n.\n//\n// The algorithm creates a list of small primes, plus an open-ended list of\n// potential primes.  All prime numbers are potential prime numbers.  However\n// some potential prime numbers are not prime.  In an ideal world, all potential\n// prime numbers would be prime.  Candidate prime numbers are chosen as the next\n// highest potential prime.  Then this number is tested for prime by dividing it\n// by all potential prime numbers less than the sqrt of the candidate.\n//\n// This implementation defines potential primes as those numbers not divisible\n// by 2, 3, 5, and 7.  Other (common) implementations define potential primes\n// as those not divisible by 2.  A few other implementations define potential\n// primes as those not divisible by 2 or 3.  By raising the number of small\n// primes which the potential prime is not divisible by, the set of potential\n// primes more closely approximates the set of prime numbers.  And thus there\n// are fewer potential primes to search, and fewer potential primes to divide\n// against.\n\ntemplate <size_t _Sz = sizeof(size_t)>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<_Sz == 4, void>::type\n__check_for_overflow(size_t N)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (N > 0xFFFFFFFB)\n        throw overflow_error(\"__next_prime overflow\");\n#else\n    (void)N;\n#endif\n}\n\ntemplate <size_t _Sz = sizeof(size_t)>\ninline _LIBCPP_INLINE_VISIBILITY\ntypename enable_if<_Sz == 8, void>::type\n__check_for_overflow(size_t N)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (N > 0xFFFFFFFFFFFFFFC5ull)\n        throw overflow_error(\"__next_prime overflow\");\n#else\n    (void)N;\n#endif\n}\n\nsize_t\n__next_prime(size_t n)\n{\n    const size_t L = 210;\n    const size_t N = sizeof(small_primes) / sizeof(small_primes[0]);\n    // If n is small enough, search in small_primes\n    if (n <= small_primes[N-1])\n        return *std::lower_bound(small_primes, small_primes + N, n);\n    // Else n > largest small_primes\n    // Check for overflow\n    __check_for_overflow(n);\n    // Start searching list of potential primes: L * k0 + indices[in]\n    const size_t M = sizeof(indices) / sizeof(indices[0]);\n    // Select first potential prime >= n\n    //   Known a-priori n >= L\n    size_t k0 = n / L;\n    size_t in = static_cast<size_t>(std::lower_bound(indices, indices + M, n - k0 * L)\n                                    - indices);\n    n = L * k0 + indices[in];\n    while (true)\n    {\n        // Divide n by all primes or potential primes (i) until:\n        //    1.  The division is even, so try next potential prime.\n        //    2.  The i > sqrt(n), in which case n is prime.\n        // It is known a-priori that n is not divisible by 2, 3, 5 or 7,\n        //    so don't test those (j == 5 ->  divide by 11 first).  And the\n        //    potential primes start with 211, so don't test against the last\n        //    small prime.\n        for (size_t j = 5; j < N - 1; ++j)\n        {\n            const std::size_t p = small_primes[j];\n            const std::size_t q = n / p;\n            if (q < p)\n                return n;\n            if (n == q * p)\n                goto next;\n        }\n        // n wasn't divisible by small primes, try potential primes\n        {\n            size_t i = 211;\n            while (true)\n            {\n                std::size_t q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 10;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 2;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 2;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 6;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 2;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 6;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 2;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 6;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 6;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 2;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 6;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 2;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 6;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 6;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 8;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 2;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 2;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 8;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 6;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 6;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 2;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 6;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 2;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 6;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 6;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 2;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 6;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 2;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 6;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 2;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 4;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 2;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                i += 10;\n                q = n / i;\n                if (q < i)\n                    return n;\n                if (n == q * i)\n                    break;\n\n                // This will loop i to the next \"plane\" of potential primes\n                i += 2;\n            }\n        }\nnext:\n        // n is not prime.  Increment n to next potential prime.\n        if (++in == M)\n        {\n            ++k0;\n            in = 0;\n        }\n        n = L * k0 + indices[in];\n    }\n}\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/ios.cpp",
    "content": "//===-------------------------- ios.cpp -----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"__config\"\n\n#undef _LIBCPP_EXTERN_TEMPLATE\n#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;\n\n#include \"ios\"\n\n#include <stdlib.h>\n\n#include \"__locale\"\n#include \"algorithm\"\n#include \"config_elast.h\"\n#include \"istream\"\n#include \"limits\"\n#include \"memory\"\n#include \"new\"\n#include \"streambuf\"\n#include \"string\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate class basic_ios<char>;\ntemplate class basic_ios<wchar_t>;\n\ntemplate class basic_streambuf<char>;\ntemplate class basic_streambuf<wchar_t>;\n\ntemplate class basic_istream<char>;\ntemplate class basic_istream<wchar_t>;\n\ntemplate class basic_ostream<char>;\ntemplate class basic_ostream<wchar_t>;\n\ntemplate class basic_iostream<char>;\n\nclass _LIBCPP_HIDDEN __iostream_category\n    : public __do_message\n{\npublic:\n    virtual const char* name() const _NOEXCEPT;\n    virtual string message(int ev) const;\n};\n\nconst char*\n__iostream_category::name() const _NOEXCEPT\n{\n    return \"iostream\";\n}\n\nstring\n__iostream_category::message(int ev) const\n{\n    if (ev != static_cast<int>(io_errc::stream)\n#ifdef _LIBCPP_ELAST\n        && ev <= _LIBCPP_ELAST\n#endif  // _LIBCPP_ELAST\n        )\n        return __do_message::message(ev);\n    return string(\"unspecified iostream_category error\");\n}\n\nconst error_category&\niostream_category() _NOEXCEPT\n{\n    static __iostream_category s;\n    return s;\n}\n\n// ios_base::failure\n\nios_base::failure::failure(const string& msg, const error_code& ec)\n    : system_error(ec, msg)\n{\n}\n\nios_base::failure::failure(const char* msg, const error_code& ec)\n    : system_error(ec, msg)\n{\n}\n\nios_base::failure::~failure() throw()\n{\n}\n\n// ios_base locale\n\nconst ios_base::fmtflags ios_base::boolalpha;\nconst ios_base::fmtflags ios_base::dec;\nconst ios_base::fmtflags ios_base::fixed;\nconst ios_base::fmtflags ios_base::hex;\nconst ios_base::fmtflags ios_base::internal;\nconst ios_base::fmtflags ios_base::left;\nconst ios_base::fmtflags ios_base::oct;\nconst ios_base::fmtflags ios_base::right;\nconst ios_base::fmtflags ios_base::scientific;\nconst ios_base::fmtflags ios_base::showbase;\nconst ios_base::fmtflags ios_base::showpoint;\nconst ios_base::fmtflags ios_base::showpos;\nconst ios_base::fmtflags ios_base::skipws;\nconst ios_base::fmtflags ios_base::unitbuf;\nconst ios_base::fmtflags ios_base::uppercase;\nconst ios_base::fmtflags ios_base::adjustfield;\nconst ios_base::fmtflags ios_base::basefield;\nconst ios_base::fmtflags ios_base::floatfield;\n\nconst ios_base::iostate ios_base::badbit;\nconst ios_base::iostate ios_base::eofbit;\nconst ios_base::iostate ios_base::failbit;\nconst ios_base::iostate ios_base::goodbit;\n\nconst ios_base::openmode ios_base::app;\nconst ios_base::openmode ios_base::ate;\nconst ios_base::openmode ios_base::binary;\nconst ios_base::openmode ios_base::in;\nconst ios_base::openmode ios_base::out;\nconst ios_base::openmode ios_base::trunc;\n\nvoid\nios_base::__call_callbacks(event ev)\n{\n    for (size_t i = __event_size_; i;)\n    {\n        --i;\n        __fn_[i](ev, *this, __index_[i]);\n    }\n}\n\n// locale\n\nlocale\nios_base::imbue(const locale& newloc)\n{\n    static_assert(sizeof(locale) == sizeof(__loc_), \"\");\n    locale& loc_storage = *reinterpret_cast<locale*>(&__loc_);\n    locale oldloc = loc_storage;\n    loc_storage = newloc;\n    __call_callbacks(imbue_event);\n    return oldloc;\n}\n\nlocale\nios_base::getloc() const\n{\n    const locale& loc_storage = *reinterpret_cast<const locale*>(&__loc_);\n    return loc_storage;\n}\n\n// xalloc\n#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)\natomic<int> ios_base::__xindex_ = ATOMIC_VAR_INIT(0);\n#else\nint ios_base::__xindex_ = 0;\n#endif\n\ntemplate <typename _Tp>\nstatic size_t __ios_new_cap(size_t __req_size, size_t __current_cap)\n{ // Precondition: __req_size > __current_cap\n\tconst size_t mx = std::numeric_limits<size_t>::max() / sizeof(_Tp);\n\tif (__req_size < mx/2)\n\t\treturn _VSTD::max(2 * __current_cap, __req_size);\n\telse\n\t\treturn mx;\n}\n\nint\nios_base::xalloc()\n{\n    return __xindex_++;\n}\n\nlong&\nios_base::iword(int index)\n{\n    size_t req_size = static_cast<size_t>(index)+1;\n    if (req_size > __iarray_cap_)\n    {\n        size_t newcap = __ios_new_cap<long>(req_size, __iarray_cap_);\n        long* iarray = static_cast<long*>(realloc(__iarray_, newcap * sizeof(long)));\n        if (iarray == 0)\n        {\n            setstate(badbit);\n            static long error;\n            error = 0;\n            return error;\n        }\n        __iarray_ = iarray;\n        for (long* p = __iarray_ + __iarray_size_; p < __iarray_ + newcap; ++p)\n            *p = 0;\n        __iarray_cap_ = newcap;\n    }\n    __iarray_size_ = max<size_t>(__iarray_size_, req_size);\n    return __iarray_[index];\n}\n\nvoid*&\nios_base::pword(int index)\n{\n    size_t req_size = static_cast<size_t>(index)+1;\n    if (req_size > __parray_cap_)\n    {\n        size_t newcap = __ios_new_cap<void *>(req_size, __iarray_cap_);\n        void** parray = static_cast<void**>(realloc(__parray_, newcap * sizeof(void *)));\n        if (parray == 0)\n        {\n            setstate(badbit);\n            static void* error;\n            error = 0;\n            return error;\n        }\n        __parray_ = parray;\n        for (void** p = __parray_ + __parray_size_; p < __parray_ + newcap; ++p)\n            *p = 0;\n        __parray_cap_ = newcap;\n    }\n    __parray_size_ = max<size_t>(__parray_size_, req_size);\n    return __parray_[index];\n}\n\n// register_callback\n\nvoid\nios_base::register_callback(event_callback fn, int index)\n{\n    size_t req_size = __event_size_ + 1;\n    if (req_size > __event_cap_)\n    {\n        size_t newcap = __ios_new_cap<event_callback>(req_size, __event_cap_);\n        event_callback* fns = static_cast<event_callback*>(realloc(__fn_, newcap * sizeof(event_callback)));\n        if (fns == 0)\n            setstate(badbit);\n        __fn_ = fns;\n        int* indxs = static_cast<int *>(realloc(__index_, newcap * sizeof(int)));\n        if (indxs == 0)\n            setstate(badbit);\n        __index_ = indxs;\n        __event_cap_ = newcap;\n    }\n    __fn_[__event_size_] = fn;\n    __index_[__event_size_] = index;\n    ++__event_size_;\n}\n\nios_base::~ios_base()\n{\n    __call_callbacks(erase_event);\n    locale& loc_storage = *reinterpret_cast<locale*>(&__loc_);\n    loc_storage.~locale();\n    free(__fn_);\n    free(__index_);\n    free(__iarray_);\n    free(__parray_);\n}\n\n// iostate\n\nvoid\nios_base::clear(iostate state)\n{\n    if (__rdbuf_)\n        __rdstate_ = state;\n    else\n        __rdstate_ = state | badbit;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (((state | (__rdbuf_ ? goodbit : badbit)) & __exceptions_) != 0)\n        throw failure(\"ios_base::clear\");\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\n// init\n\nvoid\nios_base::init(void* sb)\n{\n    __rdbuf_ = sb;\n    __rdstate_ = __rdbuf_ ? goodbit : badbit;\n    __exceptions_ = goodbit;\n    __fmtflags_ = skipws | dec;\n    __width_ = 0;\n    __precision_ = 6;\n    __fn_ = 0;\n    __index_ = 0;\n    __event_size_ = 0;\n    __event_cap_ = 0;\n    __iarray_ = 0;\n    __iarray_size_ = 0;\n    __iarray_cap_ = 0;\n    __parray_ = 0;\n    __parray_size_ = 0;\n    __parray_cap_ = 0;\n    ::new(&__loc_) locale;\n}\n\nvoid\nios_base::copyfmt(const ios_base& rhs)\n{\n    // If we can't acquire the needed resources, throw bad_alloc (can't set badbit)\n    // Don't alter *this until all needed resources are acquired\n    unique_ptr<event_callback, void (*)(void*)> new_callbacks(0, free);\n    unique_ptr<int, void (*)(void*)> new_ints(0, free);\n    unique_ptr<long, void (*)(void*)> new_longs(0, free);\n    unique_ptr<void*, void (*)(void*)> new_pointers(0, free);\n    if (__event_cap_ < rhs.__event_size_)\n    {\n        size_t newesize = sizeof(event_callback) * rhs.__event_size_;\n        new_callbacks.reset(static_cast<event_callback*>(malloc(newesize)));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        if (!new_callbacks)\n            throw bad_alloc();\n#endif  // _LIBCPP_NO_EXCEPTIONS\n\n        size_t newisize = sizeof(int) * rhs.__event_size_;\n        new_ints.reset(static_cast<int *>(malloc(newisize)));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        if (!new_ints)\n            throw bad_alloc();\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n    if (__iarray_cap_ < rhs.__iarray_size_)\n    {\n        size_t newsize = sizeof(long) * rhs.__iarray_size_;\n        new_longs.reset(static_cast<long*>(malloc(newsize)));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        if (!new_longs)\n            throw bad_alloc();\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n    if (__parray_cap_ < rhs.__parray_size_)\n    {\n        size_t newsize = sizeof(void*) * rhs.__parray_size_;\n        new_pointers.reset(static_cast<void**>(malloc(newsize)));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        if (!new_pointers)\n            throw bad_alloc();\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n    // Got everything we need.  Copy everything but __rdstate_, __rdbuf_ and __exceptions_\n    __fmtflags_ = rhs.__fmtflags_;\n    __precision_ = rhs.__precision_;\n    __width_ = rhs.__width_;\n    locale& lhs_loc = *reinterpret_cast<locale*>(&__loc_);\n    const locale& rhs_loc = *reinterpret_cast<const locale*>(&rhs.__loc_);\n    lhs_loc = rhs_loc;\n    if (__event_cap_ < rhs.__event_size_)\n    {\n        free(__fn_);\n        __fn_ = new_callbacks.release();\n        free(__index_);\n        __index_ = new_ints.release();\n        __event_cap_ = rhs.__event_size_;\n    }\n    for (__event_size_ = 0; __event_size_ < rhs.__event_size_; ++__event_size_)\n    {\n        __fn_[__event_size_] = rhs.__fn_[__event_size_];\n        __index_[__event_size_] = rhs.__index_[__event_size_];\n    }\n    if (__iarray_cap_ < rhs.__iarray_size_)\n    {\n        free(__iarray_);\n        __iarray_ = new_longs.release();\n        __iarray_cap_ = rhs.__iarray_size_;\n    }\n    for (__iarray_size_ = 0; __iarray_size_ < rhs.__iarray_size_; ++__iarray_size_)\n        __iarray_[__iarray_size_] = rhs.__iarray_[__iarray_size_];\n    if (__parray_cap_ < rhs.__parray_size_)\n    {\n        free(__parray_);\n        __parray_ = new_pointers.release();\n        __parray_cap_ = rhs.__parray_size_;\n    }\n    for (__parray_size_ = 0; __parray_size_ < rhs.__parray_size_; ++__parray_size_)\n        __parray_[__parray_size_] = rhs.__parray_[__parray_size_];\n}\n\nvoid\nios_base::move(ios_base& rhs)\n{\n    // *this is uninitialized\n    __fmtflags_ = rhs.__fmtflags_;\n    __precision_ = rhs.__precision_;\n    __width_ = rhs.__width_;\n    __rdstate_ = rhs.__rdstate_;\n    __exceptions_ = rhs.__exceptions_;\n    __rdbuf_ = 0;\n    locale& rhs_loc = *reinterpret_cast<locale*>(&rhs.__loc_);\n    ::new(&__loc_) locale(rhs_loc);\n    __fn_ = rhs.__fn_;\n    rhs.__fn_ = 0;\n    __index_ = rhs.__index_;\n    rhs.__index_ = 0;\n    __event_size_ = rhs.__event_size_;\n    rhs.__event_size_ = 0;\n    __event_cap_ = rhs.__event_cap_;\n    rhs.__event_cap_ = 0;\n    __iarray_ = rhs.__iarray_;\n    rhs.__iarray_ = 0;\n    __iarray_size_ = rhs.__iarray_size_;\n    rhs.__iarray_size_ = 0;\n    __iarray_cap_ = rhs.__iarray_cap_;\n    rhs.__iarray_cap_ = 0;\n    __parray_ = rhs.__parray_;\n    rhs.__parray_ = 0;\n    __parray_size_ = rhs.__parray_size_;\n    rhs.__parray_size_ = 0;\n    __parray_cap_ = rhs.__parray_cap_;\n    rhs.__parray_cap_ = 0;\n}\n\nvoid\nios_base::swap(ios_base& rhs) _NOEXCEPT\n{\n    _VSTD::swap(__fmtflags_, rhs.__fmtflags_);\n    _VSTD::swap(__precision_, rhs.__precision_);\n    _VSTD::swap(__width_, rhs.__width_);\n    _VSTD::swap(__rdstate_, rhs.__rdstate_);\n    _VSTD::swap(__exceptions_, rhs.__exceptions_);\n    locale& lhs_loc = *reinterpret_cast<locale*>(&__loc_);\n    locale& rhs_loc = *reinterpret_cast<locale*>(&rhs.__loc_);\n    _VSTD::swap(lhs_loc, rhs_loc);\n    _VSTD::swap(__fn_, rhs.__fn_);\n    _VSTD::swap(__index_, rhs.__index_);\n    _VSTD::swap(__event_size_, rhs.__event_size_);\n    _VSTD::swap(__event_cap_, rhs.__event_cap_);\n    _VSTD::swap(__iarray_, rhs.__iarray_);\n    _VSTD::swap(__iarray_size_, rhs.__iarray_size_);\n    _VSTD::swap(__iarray_cap_, rhs.__iarray_cap_);\n    _VSTD::swap(__parray_, rhs.__parray_);\n    _VSTD::swap(__parray_size_, rhs.__parray_size_);\n    _VSTD::swap(__parray_cap_, rhs.__parray_cap_);\n}\n\nvoid\nios_base::__set_badbit_and_consider_rethrow()\n{\n    __rdstate_ |= badbit;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__exceptions_ & badbit)\n        throw;\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\nvoid\nios_base::__set_failbit_and_consider_rethrow()\n{\n    __rdstate_ |= failbit;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__exceptions_ & failbit)\n        throw;\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\nbool\nios_base::sync_with_stdio(bool sync)\n{\n    static bool previous_state = true;\n    bool r = previous_state;\n    previous_state = sync;\n    return r;\n}\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/iostream.cpp",
    "content": "//===------------------------ iostream.cpp --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"__std_stream\"\n#include \"string\"\n#include \"new\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n#ifndef _LIBCPP_HAS_NO_STDIN\n_ALIGNAS_TYPE (istream)  _LIBCPP_FUNC_VIS char cin [sizeof(istream)];\n_ALIGNAS_TYPE (__stdinbuf<char> ) static char __cin [sizeof(__stdinbuf <char>)];\nstatic mbstate_t mb_cin;\n_ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin [sizeof(wistream)];\n_ALIGNAS_TYPE (__stdinbuf<wchar_t> ) static char __wcin [sizeof(__stdinbuf <wchar_t>)];\nstatic mbstate_t mb_wcin;\n#endif\n\n#ifndef _LIBCPP_HAS_NO_STDOUT\n_ALIGNAS_TYPE (ostream)  _LIBCPP_FUNC_VIS char cout[sizeof(ostream)];\n_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)];\nstatic mbstate_t mb_cout;\n_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcout[sizeof(wostream)];\n_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)];\nstatic mbstate_t mb_wcout;\n#endif\n\n_ALIGNAS_TYPE (ostream)  _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)];\n_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)];\nstatic mbstate_t mb_cerr;\n_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcerr[sizeof(wostream)];\n_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)];\nstatic mbstate_t mb_wcerr;\n\n_ALIGNAS_TYPE (ostream)  _LIBCPP_FUNC_VIS char clog[sizeof(ostream)];\n_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wclog[sizeof(wostream)];\n\nios_base::Init __start_std_streams;\n\nios_base::Init::Init()\n{\n#ifndef _LIBCPP_HAS_NO_STDIN\n    istream* cin_ptr  = ::new(cin)  istream(::new(__cin)  __stdinbuf <char>(stdin, &mb_cin));\n    wistream* wcin_ptr  = ::new(wcin)  wistream(::new(__wcin)  __stdinbuf <wchar_t>(stdin, &mb_wcin));\n#endif\n#ifndef _LIBCPP_HAS_NO_STDOUT\n    ostream* cout_ptr = ::new(cout) ostream(::new(__cout) __stdoutbuf<char>(stdout, &mb_cout));\n    wostream* wcout_ptr = ::new(wcout) wostream(::new(__wcout) __stdoutbuf<wchar_t>(stdout, &mb_wcout));\n#endif\n    ostream* cerr_ptr = ::new(cerr) ostream(::new(__cerr) __stdoutbuf<char>(stderr, &mb_cerr));\n                        ::new(clog) ostream(cerr_ptr->rdbuf());\n    wostream* wcerr_ptr = ::new(wcerr) wostream(::new(__wcerr) __stdoutbuf<wchar_t>(stderr, &mb_wcerr));\n                          ::new(wclog) wostream(wcerr_ptr->rdbuf());\n\n#if !defined(_LIBCPP_HAS_NO_STDIN) && !defined(_LIBCPP_HAS_NO_STDOUT)\n    cin_ptr->tie(cout_ptr);\n    wcin_ptr->tie(wcout_ptr);\n#endif\n    _VSTD::unitbuf(*cerr_ptr);\n    _VSTD::unitbuf(*wcerr_ptr);\n#ifndef _LIBCPP_HAS_NO_STDOUT\n    cerr_ptr->tie(cout_ptr);\n    wcerr_ptr->tie(wcout_ptr);\n#endif\n}\n\nios_base::Init::~Init()\n{\n#ifndef _LIBCPP_HAS_NO_STDOUT\n    ostream* cout_ptr = reinterpret_cast<ostream*>(cout);\n    wostream* wcout_ptr = reinterpret_cast<wostream*>(wcout);\n    cout_ptr->flush();\n    wcout_ptr->flush();\n#endif\n\n    ostream* clog_ptr = reinterpret_cast<ostream*>(clog);\n    wostream* wclog_ptr = reinterpret_cast<wostream*>(wclog);\n    clog_ptr->flush();\n    wclog_ptr->flush();\n}\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/locale.cpp",
    "content": "//===------------------------- locale.cpp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#undef _LIBCPP_EXTERN_TEMPLATE\n#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;\n\n// On Solaris, we need to define something to make the C99 parts of localeconv\n// visible.\n#ifdef __sun__\n#define _LCONV_C99\n#endif\n\n#include \"string\"\n#include \"locale\"\n#include \"codecvt\"\n#include \"vector\"\n#include \"algorithm\"\n#include \"typeinfo\"\n#ifndef _LIBCPP_NO_EXCEPTIONS\n#  include \"type_traits\"\n#endif\n#include \"clocale\"\n#include \"cstring\"\n#include \"cwctype\"\n#include \"__sso_allocator\"\n#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)\n#include \"support/win32/locale_win32.h\"\n#elif !defined(__ANDROID__)\n#include <langinfo.h>\n#endif\n#include <stdlib.h>\n#include <stdio.h>\n\n// On Linux, wint_t and wchar_t have different signed-ness, and this causes\n// lots of noise in the build log, but no bugs that I know of. \n#if defined(__clang__)\n#pragma clang diagnostic ignored \"-Wsign-conversion\"\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n#ifdef __cloc_defined\nlocale_t __cloc() {\n  // In theory this could create a race condition. In practice\n  // the race condition is non-fatal since it will just create\n  // a little resource leak. Better approach would be appreciated.\n  static locale_t result = newlocale(LC_ALL_MASK, \"C\", 0);\n  return result;\n}\n#endif // __cloc_defined\n\nnamespace {\n\nstruct release\n{\n    void operator()(locale::facet* p) {p->__release_shared();}\n};\n\ntemplate <class T, class A0>\ninline\nT&\nmake(A0 a0)\n{\n    static typename aligned_storage<sizeof(T)>::type buf;\n    ::new (&buf) T(a0);\n    return *reinterpret_cast<T*>(&buf);\n}\n\ntemplate <class T, class A0, class A1>\ninline\nT&\nmake(A0 a0, A1 a1)\n{\n    static typename aligned_storage<sizeof(T)>::type buf;\n    ::new (&buf) T(a0, a1);\n    return *reinterpret_cast<T*>(&buf);\n}\n\ntemplate <class T, class A0, class A1, class A2>\ninline\nT&\nmake(A0 a0, A1 a1, A2 a2)\n{\n    static typename aligned_storage<sizeof(T)>::type buf;\n    ::new (&buf) T(a0, a1, a2);\n    return *reinterpret_cast<T*>(&buf);\n}\n\ntemplate <typename T, size_t N>\ninline\n_LIBCPP_CONSTEXPR\nsize_t\ncountof(const T (&)[N])\n{\n    return N;\n}\n\ntemplate <typename T>\ninline\n_LIBCPP_CONSTEXPR\nsize_t\ncountof(const T * const begin, const T * const end)\n{\n    return static_cast<size_t>(end - begin);\n}\n\n}\n\n#if defined(_AIX)\n// Set priority to INT_MIN + 256 + 150\n# pragma priority ( -2147483242 )\n#endif\n\nconst locale::category locale::none;\nconst locale::category locale::collate;\nconst locale::category locale::ctype;\nconst locale::category locale::monetary;\nconst locale::category locale::numeric;\nconst locale::category locale::time;\nconst locale::category locale::messages;\nconst locale::category locale::all;\n\n#if defined(__clang__)\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\nclass _LIBCPP_HIDDEN locale::__imp\n    : public facet\n{\n    enum {N = 28};\n#if defined(_LIBCPP_MSVC)\n// FIXME: MSVC doesn't support aligned parameters by value.\n// I can't get the __sso_allocator to work here\n// for MSVC I think for this reason.\n    vector<facet*> facets_;\n#else\n    vector<facet*, __sso_allocator<facet*, N> > facets_;\n#endif\n    string         name_;\npublic:\n    explicit __imp(size_t refs = 0);\n    explicit __imp(const string& name, size_t refs = 0);\n    __imp(const __imp&);\n    __imp(const __imp&, const string&, locale::category c);\n    __imp(const __imp& other, const __imp& one, locale::category c);\n    __imp(const __imp&, facet* f, long id);\n    ~__imp();\n\n    const string& name() const {return name_;}\n    bool has_facet(long id) const\n        {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}\n    const locale::facet* use_facet(long id) const;\n\n    static const locale& make_classic();\n    static       locale& make_global();\nprivate:\n    void install(facet* f, long id);\n    template <class F> void install(F* f) {install(f, f->id.__get());}\n    template <class F> void install_from(const __imp& other);\n};\n\n#if defined(__clang__)\n#pragma clang diagnostic pop\n#endif\n\nlocale::__imp::__imp(size_t refs)\n    : facet(refs),\n      facets_(N),\n      name_(\"C\")\n{\n    facets_.clear();\n    install(&make<_VSTD::collate<char> >(1u));\n    install(&make<_VSTD::collate<wchar_t> >(1u));\n    install(&make<_VSTD::ctype<char> >(nullptr, false, 1u));\n    install(&make<_VSTD::ctype<wchar_t> >(1u));\n    install(&make<codecvt<char, char, mbstate_t> >(1u));\n    install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));\n    install(&make<codecvt<char16_t, char, mbstate_t> >(1u));\n    install(&make<codecvt<char32_t, char, mbstate_t> >(1u));\n    install(&make<numpunct<char> >(1u));\n    install(&make<numpunct<wchar_t> >(1u));\n    install(&make<num_get<char> >(1u));\n    install(&make<num_get<wchar_t> >(1u));\n    install(&make<num_put<char> >(1u));\n    install(&make<num_put<wchar_t> >(1u));\n    install(&make<moneypunct<char, false> >(1u));\n    install(&make<moneypunct<char, true> >(1u));\n    install(&make<moneypunct<wchar_t, false> >(1u));\n    install(&make<moneypunct<wchar_t, true> >(1u));\n    install(&make<money_get<char> >(1u));\n    install(&make<money_get<wchar_t> >(1u));\n    install(&make<money_put<char> >(1u));\n    install(&make<money_put<wchar_t> >(1u));\n    install(&make<time_get<char> >(1u));\n    install(&make<time_get<wchar_t> >(1u));\n    install(&make<time_put<char> >(1u));\n    install(&make<time_put<wchar_t> >(1u));\n    install(&make<_VSTD::messages<char> >(1u));\n    install(&make<_VSTD::messages<wchar_t> >(1u));\n}\n\nlocale::__imp::__imp(const string& name, size_t refs)\n    : facet(refs),\n      facets_(N),\n      name_(name)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        facets_ = locale::classic().__locale_->facets_;\n        for (unsigned i = 0; i < facets_.size(); ++i)\n            if (facets_[i])\n                facets_[i]->__add_shared();\n        install(new collate_byname<char>(name_));\n        install(new collate_byname<wchar_t>(name_));\n        install(new ctype_byname<char>(name_));\n        install(new ctype_byname<wchar_t>(name_));\n        install(new codecvt_byname<char, char, mbstate_t>(name_));\n        install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));\n        install(new codecvt_byname<char16_t, char, mbstate_t>(name_));\n        install(new codecvt_byname<char32_t, char, mbstate_t>(name_));\n        install(new numpunct_byname<char>(name_));\n        install(new numpunct_byname<wchar_t>(name_));\n        install(new moneypunct_byname<char, false>(name_));\n        install(new moneypunct_byname<char, true>(name_));\n        install(new moneypunct_byname<wchar_t, false>(name_));\n        install(new moneypunct_byname<wchar_t, true>(name_));\n        install(new time_get_byname<char>(name_));\n        install(new time_get_byname<wchar_t>(name_));\n        install(new time_put_byname<char>(name_));\n        install(new time_put_byname<wchar_t>(name_));\n        install(new messages_byname<char>(name_));\n        install(new messages_byname<wchar_t>(name_));\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        for (unsigned i = 0; i < facets_.size(); ++i)\n            if (facets_[i])\n                facets_[i]->__release_shared();\n        throw;\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\n// NOTE avoid the `base class should be explicitly initialized in the\n// copy constructor` warning emitted by GCC\n#if defined(__clang__) || _GNUC_VER >= 406\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wextra\"\n#endif\n\nlocale::__imp::__imp(const __imp& other)\n    : facets_(max<size_t>(N, other.facets_.size())),\n      name_(other.name_)\n{\n    facets_ = other.facets_;\n    for (unsigned i = 0; i < facets_.size(); ++i)\n        if (facets_[i])\n            facets_[i]->__add_shared();\n}\n\n#if defined(__clang__) || _GNUC_VER >= 406\n#pragma GCC diagnostic pop\n#endif\n\nlocale::__imp::__imp(const __imp& other, const string& name, locale::category c)\n    : facets_(N),\n      name_(\"*\")\n{\n    facets_ = other.facets_;\n    for (unsigned i = 0; i < facets_.size(); ++i)\n        if (facets_[i])\n            facets_[i]->__add_shared();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        if (c & locale::collate)\n        {\n            install(new collate_byname<char>(name));\n            install(new collate_byname<wchar_t>(name));\n        }\n        if (c & locale::ctype)\n        {\n            install(new ctype_byname<char>(name));\n            install(new ctype_byname<wchar_t>(name));\n            install(new codecvt_byname<char, char, mbstate_t>(name));\n            install(new codecvt_byname<wchar_t, char, mbstate_t>(name));\n            install(new codecvt_byname<char16_t, char, mbstate_t>(name));\n            install(new codecvt_byname<char32_t, char, mbstate_t>(name));\n        }\n        if (c & locale::monetary)\n        {\n            install(new moneypunct_byname<char, false>(name));\n            install(new moneypunct_byname<char, true>(name));\n            install(new moneypunct_byname<wchar_t, false>(name));\n            install(new moneypunct_byname<wchar_t, true>(name));\n        }\n        if (c & locale::numeric)\n        {\n            install(new numpunct_byname<char>(name));\n            install(new numpunct_byname<wchar_t>(name));\n        }\n        if (c & locale::time)\n        {\n            install(new time_get_byname<char>(name));\n            install(new time_get_byname<wchar_t>(name));\n            install(new time_put_byname<char>(name));\n            install(new time_put_byname<wchar_t>(name));\n        }\n        if (c & locale::messages)\n        {\n            install(new messages_byname<char>(name));\n            install(new messages_byname<wchar_t>(name));\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        for (unsigned i = 0; i < facets_.size(); ++i)\n            if (facets_[i])\n                facets_[i]->__release_shared();\n        throw;\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ntemplate<class F>\ninline\nvoid\nlocale::__imp::install_from(const locale::__imp& one)\n{\n    long id = F::id.__get();\n    install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);\n}\n\nlocale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)\n    : facets_(N),\n      name_(\"*\")\n{\n    facets_ = other.facets_;\n    for (unsigned i = 0; i < facets_.size(); ++i)\n        if (facets_[i])\n            facets_[i]->__add_shared();\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        if (c & locale::collate)\n        {\n            install_from<_VSTD::collate<char> >(one);\n            install_from<_VSTD::collate<wchar_t> >(one);\n        }\n        if (c & locale::ctype)\n        {\n            install_from<_VSTD::ctype<char> >(one);\n            install_from<_VSTD::ctype<wchar_t> >(one);\n            install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);\n            install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);\n            install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);\n            install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);\n        }\n        if (c & locale::monetary)\n        {\n            install_from<moneypunct<char, false> >(one);\n            install_from<moneypunct<char, true> >(one);\n            install_from<moneypunct<wchar_t, false> >(one);\n            install_from<moneypunct<wchar_t, true> >(one);\n            install_from<money_get<char> >(one);\n            install_from<money_get<wchar_t> >(one);\n            install_from<money_put<char> >(one);\n            install_from<money_put<wchar_t> >(one);\n        }\n        if (c & locale::numeric)\n        {\n            install_from<numpunct<char> >(one);\n            install_from<numpunct<wchar_t> >(one);\n            install_from<num_get<char> >(one);\n            install_from<num_get<wchar_t> >(one);\n            install_from<num_put<char> >(one);\n            install_from<num_put<wchar_t> >(one);\n        }\n        if (c & locale::time)\n        {\n            install_from<time_get<char> >(one);\n            install_from<time_get<wchar_t> >(one);\n            install_from<time_put<char> >(one);\n            install_from<time_put<wchar_t> >(one);\n        }\n        if (c & locale::messages)\n        {\n            install_from<_VSTD::messages<char> >(one);\n            install_from<_VSTD::messages<wchar_t> >(one);\n        }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n        for (unsigned i = 0; i < facets_.size(); ++i)\n            if (facets_[i])\n                facets_[i]->__release_shared();\n        throw;\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\nlocale::__imp::__imp(const __imp& other, facet* f, long id)\n    : facets_(max<size_t>(N, other.facets_.size()+1)),\n      name_(\"*\")\n{\n    f->__add_shared();\n    unique_ptr<facet, release> hold(f);\n    facets_ = other.facets_;\n    for (unsigned i = 0; i < other.facets_.size(); ++i)\n        if (facets_[i])\n            facets_[i]->__add_shared();\n    install(hold.get(), id);\n}\n\nlocale::__imp::~__imp()\n{\n    for (unsigned i = 0; i < facets_.size(); ++i)\n        if (facets_[i])\n            facets_[i]->__release_shared();\n}\n\nvoid\nlocale::__imp::install(facet* f, long id)\n{\n    f->__add_shared();\n    unique_ptr<facet, release> hold(f);\n    if (static_cast<size_t>(id) >= facets_.size())\n        facets_.resize(static_cast<size_t>(id+1));\n    if (facets_[static_cast<size_t>(id)])\n        facets_[static_cast<size_t>(id)]->__release_shared();\n    facets_[static_cast<size_t>(id)] = hold.release();\n}\n\nconst locale::facet*\nlocale::__imp::use_facet(long id) const\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (!has_facet(id))\n        throw bad_cast();\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return facets_[static_cast<size_t>(id)];\n}\n\n// locale\n\nconst locale&\nlocale::__imp::make_classic()\n{\n    // only one thread can get in here and it only gets in once\n    static aligned_storage<sizeof(locale)>::type buf;\n    locale* c = reinterpret_cast<locale*>(&buf);\n    c->__locale_ = &make<__imp>(1u);\n    return *c;\n}\n\nconst locale&\nlocale::classic()\n{\n    static const locale& c = __imp::make_classic();\n    return c;\n}\n\nlocale&\nlocale::__imp::make_global()\n{\n    // only one thread can get in here and it only gets in once\n    static aligned_storage<sizeof(locale)>::type buf;\n    ::new (&buf) locale(locale::classic());\n    return *reinterpret_cast<locale*>(&buf);\n}\n\nlocale&\nlocale::__global()\n{\n    static locale& g = __imp::make_global();\n    return g;\n}\n\nlocale::locale()  _NOEXCEPT\n    : __locale_(__global().__locale_)\n{\n    __locale_->__add_shared();\n}\n\nlocale::locale(const locale& l)  _NOEXCEPT\n    : __locale_(l.__locale_)\n{\n    __locale_->__add_shared();\n}\n\nlocale::~locale()\n{\n    __locale_->__release_shared();\n}\n\nconst locale&\nlocale::operator=(const locale& other)  _NOEXCEPT\n{\n    other.__locale_->__add_shared();\n    __locale_->__release_shared();\n    __locale_ = other.__locale_;\n    return *this;\n}\n\nlocale::locale(const char* name)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    : __locale_(name ? new __imp(name)\n                     : throw runtime_error(\"locale constructed with null\"))\n#else  // _LIBCPP_NO_EXCEPTIONS\n    : __locale_(new __imp(name))\n#endif\n{\n    __locale_->__add_shared();\n}\n\nlocale::locale(const string& name)\n    : __locale_(new __imp(name))\n{\n    __locale_->__add_shared();\n}\n\nlocale::locale(const locale& other, const char* name, category c)\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    : __locale_(name ? new __imp(*other.__locale_, name, c)\n                     : throw runtime_error(\"locale constructed with null\"))\n#else  // _LIBCPP_NO_EXCEPTIONS\n    : __locale_(new __imp(*other.__locale_, name, c))\n#endif\n{\n    __locale_->__add_shared();\n}\n\nlocale::locale(const locale& other, const string& name, category c)\n    : __locale_(new __imp(*other.__locale_, name, c))\n{\n    __locale_->__add_shared();\n}\n\nlocale::locale(const locale& other, const locale& one, category c)\n    : __locale_(new __imp(*other.__locale_, *one.__locale_, c))\n{\n    __locale_->__add_shared();\n}\n\nstring\nlocale::name() const\n{\n    return __locale_->name();\n}\n\nvoid\nlocale::__install_ctor(const locale& other, facet* f, long id)\n{\n    if (f)\n        __locale_ = new __imp(*other.__locale_, f, id);\n    else\n        __locale_ = other.__locale_;\n    __locale_->__add_shared();\n}\n\nlocale\nlocale::global(const locale& loc)\n{\n    locale& g = __global();\n    locale r = g;\n    g = loc;\n#ifndef __CloudABI__\n    if (g.name() != \"*\")\n        setlocale(LC_ALL, g.name().c_str());\n#endif\n    return r;\n}\n\nbool\nlocale::has_facet(id& x) const\n{\n    return __locale_->has_facet(x.__get());\n}\n\nconst locale::facet*\nlocale::use_facet(id& x) const\n{\n    return __locale_->use_facet(x.__get());\n}\n\nbool\nlocale::operator==(const locale& y) const\n{\n    return (__locale_ == y.__locale_)\n        || (__locale_->name() != \"*\" && __locale_->name() == y.__locale_->name());\n}\n\n// locale::facet\n\nlocale::facet::~facet()\n{\n}\n\nvoid\nlocale::facet::__on_zero_shared() _NOEXCEPT\n{\n    delete this;\n}\n\n// locale::id\n\nint32_t locale::id::__next_id = 0;\n\nnamespace\n{\n\nclass __fake_bind\n{\n    locale::id* id_;\n    void (locale::id::* pmf_)();\npublic:\n    __fake_bind(void (locale::id::* pmf)(), locale::id* id)\n        : id_(id), pmf_(pmf) {}\n\n    void operator()() const\n    {\n        (id_->*pmf_)();\n    }\n};\n\n}\n\nlong\nlocale::id::__get()\n{\n    call_once(__flag_, __fake_bind(&locale::id::__init, this));\n    return __id_ - 1;\n}\n\nvoid\nlocale::id::__init()\n{\n    __id_ = __sync_add_and_fetch(&__next_id, 1);\n}\n\n// template <> class collate_byname<char>\n\ncollate_byname<char>::collate_byname(const char* n, size_t refs)\n    : collate<char>(refs),\n      __l(newlocale(LC_ALL_MASK, n, 0))\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__l == 0)\n        throw runtime_error(\"collate_byname<char>::collate_byname\"\n                            \" failed to construct for \" + string(n));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ncollate_byname<char>::collate_byname(const string& name, size_t refs)\n    : collate<char>(refs),\n      __l(newlocale(LC_ALL_MASK, name.c_str(), 0))\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__l == 0)\n        throw runtime_error(\"collate_byname<char>::collate_byname\"\n                            \" failed to construct for \" + name);\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ncollate_byname<char>::~collate_byname()\n{\n    freelocale(__l);\n}\n\nint\ncollate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,\n                                 const char_type* __lo2, const char_type* __hi2) const\n{\n    string_type lhs(__lo1, __hi1);\n    string_type rhs(__lo2, __hi2);\n    int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);\n    if (r < 0)\n        return -1;\n    if (r > 0)\n        return 1;\n    return r;\n}\n\ncollate_byname<char>::string_type\ncollate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const\n{\n    const string_type in(lo, hi);\n    string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());\n    strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);\n    return out;\n}\n\n// template <> class collate_byname<wchar_t>\n\ncollate_byname<wchar_t>::collate_byname(const char* n, size_t refs)\n    : collate<wchar_t>(refs),\n      __l(newlocale(LC_ALL_MASK, n, 0))\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__l == 0)\n        throw runtime_error(\"collate_byname<wchar_t>::collate_byname(size_t refs)\"\n                            \" failed to construct for \" + string(n));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ncollate_byname<wchar_t>::collate_byname(const string& name, size_t refs)\n    : collate<wchar_t>(refs),\n      __l(newlocale(LC_ALL_MASK, name.c_str(), 0))\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__l == 0)\n        throw runtime_error(\"collate_byname<wchar_t>::collate_byname(size_t refs)\"\n                            \" failed to construct for \" + name);\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ncollate_byname<wchar_t>::~collate_byname()\n{\n    freelocale(__l);\n}\n\nint\ncollate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,\n                                 const char_type* __lo2, const char_type* __hi2) const\n{\n    string_type lhs(__lo1, __hi1);\n    string_type rhs(__lo2, __hi2);\n    int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);\n    if (r < 0)\n        return -1;\n    if (r > 0)\n        return 1;\n    return r;\n}\n\ncollate_byname<wchar_t>::string_type\ncollate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const\n{\n    const string_type in(lo, hi);\n    string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());\n    wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);\n    return out;\n}\n\n// template <> class ctype<wchar_t>;\n\nconst ctype_base::mask ctype_base::space;\nconst ctype_base::mask ctype_base::print;\nconst ctype_base::mask ctype_base::cntrl;\nconst ctype_base::mask ctype_base::upper;\nconst ctype_base::mask ctype_base::lower;\nconst ctype_base::mask ctype_base::alpha;\nconst ctype_base::mask ctype_base::digit;\nconst ctype_base::mask ctype_base::punct;\nconst ctype_base::mask ctype_base::xdigit;\nconst ctype_base::mask ctype_base::blank;\nconst ctype_base::mask ctype_base::alnum;\nconst ctype_base::mask ctype_base::graph;\n    \nlocale::id ctype<wchar_t>::id;\n\nctype<wchar_t>::~ctype()\n{\n}\n\nbool\nctype<wchar_t>::do_is(mask m, char_type c) const\n{\n    return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;\n}\n\nconst wchar_t*\nctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const\n{\n    for (; low != high; ++low, ++vec)\n        *vec = static_cast<mask>(isascii(*low) ?\n                                   ctype<char>::classic_table()[*low] : 0);\n    return low;\n}\n\nconst wchar_t*\nctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const\n{\n    for (; low != high; ++low)\n        if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))\n            break;\n    return low;\n}\n\nconst wchar_t*\nctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const\n{\n    for (; low != high; ++low)\n        if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))\n            break;\n    return low;\n}\n\nwchar_t\nctype<wchar_t>::do_toupper(char_type c) const\n{\n#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE\n    return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;\n#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)\n    return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;\n#else\n    return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;\n#endif\n}\n\nconst wchar_t*\nctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const\n{\n    for (; low != high; ++low)\n#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE\n        *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;\n#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)\n        *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]\n                             : *low;\n#else\n        *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low;\n#endif\n    return low;\n}\n\nwchar_t\nctype<wchar_t>::do_tolower(char_type c) const\n{\n#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE\n    return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;\n#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)\n    return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;\n#else\n    return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;\n#endif\n}\n\nconst wchar_t*\nctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const\n{\n    for (; low != high; ++low)\n#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE\n        *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;\n#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)\n        *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]\n                             : *low;\n#else\n        *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low;\n#endif\n    return low;\n}\n\nwchar_t\nctype<wchar_t>::do_widen(char c) const\n{\n    return c;\n}\n\nconst char*\nctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const\n{\n    for (; low != high; ++low, ++dest)\n        *dest = *low;\n    return low;\n}\n\nchar\nctype<wchar_t>::do_narrow(char_type c, char dfault) const\n{\n    if (isascii(c))\n        return static_cast<char>(c);\n    return dfault;\n}\n\nconst wchar_t*\nctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const\n{\n    for (; low != high; ++low, ++dest)\n        if (isascii(*low))\n            *dest = static_cast<char>(*low);\n        else\n            *dest = dfault;\n    return low;\n}\n\n// template <> class ctype<char>;\n\nlocale::id ctype<char>::id;\n\nctype<char>::ctype(const mask* tab, bool del, size_t refs)\n    : locale::facet(refs),\n      __tab_(tab),\n      __del_(del)\n{\n  if (__tab_ == 0)\n      __tab_ = classic_table();\n}\n\nctype<char>::~ctype()\n{\n    if (__tab_ && __del_)\n        delete [] __tab_;\n}\n\nchar\nctype<char>::do_toupper(char_type c) const\n{\n#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE\n    return isascii(c) ?\n      static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;\n#elif defined(__NetBSD__)\n    return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);\n#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)\n    return isascii(c) ? \n      static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;\n#else\n    return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;\n#endif\n}\n\nconst char*\nctype<char>::do_toupper(char_type* low, const char_type* high) const\n{\n    for (; low != high; ++low)\n#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE\n        *low = isascii(*low) ?\n          static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;\n#elif defined(__NetBSD__)\n        *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);\n#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)\n        *low = isascii(*low) ?\n          static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;\n#else\n        *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low;\n#endif\n    return low;\n}\n\nchar\nctype<char>::do_tolower(char_type c) const\n{\n#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE\n    return isascii(c) ?\n      static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;\n#elif defined(__NetBSD__)\n    return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);\n#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)\n    return isascii(c) ?\n      static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;\n#else\n    return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c;\n#endif\n}\n\nconst char*\nctype<char>::do_tolower(char_type* low, const char_type* high) const\n{\n    for (; low != high; ++low)\n#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE\n        *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;\n#elif defined(__NetBSD__)\n        *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);\n#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)\n        *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;\n#else\n        *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;\n#endif\n    return low;\n}\n\nchar\nctype<char>::do_widen(char c) const\n{\n    return c;\n}\n\nconst char*\nctype<char>::do_widen(const char* low, const char* high, char_type* dest) const\n{\n    for (; low != high; ++low, ++dest)\n        *dest = *low;\n    return low;\n}\n\nchar\nctype<char>::do_narrow(char_type c, char dfault) const\n{\n    if (isascii(c))\n        return static_cast<char>(c);\n    return dfault;\n}\n\nconst char*\nctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const\n{\n    for (; low != high; ++low, ++dest)\n        if (isascii(*low))\n            *dest = *low;\n        else\n            *dest = dfault;\n    return low;\n}\n\n#ifdef __EMSCRIPTEN__\nextern \"C\" const unsigned short ** __ctype_b_loc();\nextern \"C\" const int ** __ctype_tolower_loc();\nextern \"C\" const int ** __ctype_toupper_loc();\n#endif\n\n#ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE\nconst ctype<char>::mask*\nctype<char>::classic_table()  _NOEXCEPT\n{\n    static _LIBCPP_CONSTEXPR const ctype<char>::mask builtin_table[table_size] = {\n        cntrl,                          cntrl,\n        cntrl,                          cntrl,\n        cntrl,                          cntrl,\n        cntrl,                          cntrl,\n        cntrl,                          cntrl | space | blank,\n        cntrl | space,                  cntrl | space,\n        cntrl | space,                  cntrl | space,\n        cntrl,                          cntrl,\n        cntrl,                          cntrl,\n        cntrl,                          cntrl,\n        cntrl,                          cntrl,\n        cntrl,                          cntrl,\n        cntrl,                          cntrl,\n        cntrl,                          cntrl,\n        cntrl,                          cntrl,\n        cntrl,                          cntrl,\n        space | blank | print,          punct | print,\n        punct | print,                  punct | print,\n        punct | print,                  punct | print,\n        punct | print,                  punct | print,\n        punct | print,                  punct | print,\n        punct | print,                  punct | print,\n        punct | print,                  punct | print,\n        punct | print,                  punct | print,\n        digit | print | xdigit,         digit | print | xdigit,\n        digit | print | xdigit,         digit | print | xdigit,\n        digit | print | xdigit,         digit | print | xdigit,\n        digit | print | xdigit,         digit | print | xdigit,\n        digit | print | xdigit,         digit | print | xdigit,\n        punct | print,                  punct | print,\n        punct | print,                  punct | print,\n        punct | print,                  punct | print,\n        punct | print,                  upper | xdigit | print | alpha,\n        upper | xdigit | print | alpha, upper | xdigit | print | alpha,\n        upper | xdigit | print | alpha, upper | xdigit | print | alpha,\n        upper | xdigit | print | alpha, upper | print | alpha,\n        upper | print | alpha,          upper | print | alpha,\n        upper | print | alpha,          upper | print | alpha,\n        upper | print | alpha,          upper | print | alpha,\n        upper | print | alpha,          upper | print | alpha,\n        upper | print | alpha,          upper | print | alpha,\n        upper | print | alpha,          upper | print | alpha,\n        upper | print | alpha,          upper | print | alpha,\n        upper | print | alpha,          upper | print | alpha,\n        upper | print | alpha,          upper | print | alpha,\n        upper | print | alpha,          punct | print,\n        punct | print,                  punct | print,\n        punct | print,                  punct | print,\n        punct | print,                  lower | xdigit | print | alpha,\n        lower | xdigit | print | alpha, lower | xdigit | print | alpha,\n        lower | xdigit | print | alpha, lower | xdigit | print | alpha,\n        lower | xdigit | print | alpha, lower | print | alpha,\n        lower | print | alpha,          lower | print | alpha,\n        lower | print | alpha,          lower | print | alpha,\n        lower | print | alpha,          lower | print | alpha,\n        lower | print | alpha,          lower | print | alpha,\n        lower | print | alpha,          lower | print | alpha,\n        lower | print | alpha,          lower | print | alpha,\n        lower | print | alpha,          lower | print | alpha,\n        lower | print | alpha,          lower | print | alpha,\n        lower | print | alpha,          lower | print | alpha,\n        lower | print | alpha,          punct | print,\n        punct | print,                  punct | print,\n        punct | print,                  cntrl,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n    };\n    return builtin_table;\n}\n#else\nconst ctype<char>::mask*\nctype<char>::classic_table()  _NOEXCEPT\n{\n#if defined(__APPLE__) || defined(__FreeBSD__)\n    return _DefaultRuneLocale.__runetype;\n#elif defined(__NetBSD__)\n    return _C_ctype_tab_ + 1;\n#elif defined(__GLIBC__)\n    return _LIBCPP_GET_C_LOCALE->__ctype_b;\n#elif __sun__\n    return __ctype_mask;\n#elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)\n    return _ctype+1; // internal ctype mask table defined in msvcrt.dll\n// This is assumed to be safe, which is a nonsense assumption because we're\n// going to end up dereferencing it later...\n#elif defined(__EMSCRIPTEN__)\n    return *__ctype_b_loc();\n#elif defined(_NEWLIB_VERSION)\n    // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].\n    return _ctype_ + 1;\n#elif defined(_AIX)\n    return (const unsigned int *)__lc_ctype_ptr->obj->mask;\n#else\n    // Platform not supported: abort so the person doing the port knows what to\n    // fix\n# warning  ctype<char>::classic_table() is not implemented\n    printf(\"ctype<char>::classic_table() is not implemented\\n\");\n    abort();\n    return NULL;\n#endif\n}\n#endif\n\n#if defined(__GLIBC__)\nconst int*\nctype<char>::__classic_lower_table() _NOEXCEPT\n{\n    return _LIBCPP_GET_C_LOCALE->__ctype_tolower;\n}\n\nconst int*\nctype<char>::__classic_upper_table() _NOEXCEPT\n{\n    return _LIBCPP_GET_C_LOCALE->__ctype_toupper;\n}\n#elif __NetBSD__\nconst short*\nctype<char>::__classic_lower_table() _NOEXCEPT\n{\n    return _C_tolower_tab_ + 1;\n}\n\nconst short*\nctype<char>::__classic_upper_table() _NOEXCEPT\n{\n    return _C_toupper_tab_ + 1;\n}\n\n#elif defined(__EMSCRIPTEN__)\nconst int*\nctype<char>::__classic_lower_table() _NOEXCEPT\n{\n    return *__ctype_tolower_loc();\n}\n\nconst int*\nctype<char>::__classic_upper_table() _NOEXCEPT\n{\n    return *__ctype_toupper_loc();\n}\n#endif // __GLIBC__ || __EMSCRIPTEN__ || __NETBSD__\n\n// template <> class ctype_byname<char>\n\nctype_byname<char>::ctype_byname(const char* name, size_t refs)\n    : ctype<char>(0, false, refs),\n      __l(newlocale(LC_ALL_MASK, name, 0))\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__l == 0)\n        throw runtime_error(\"ctype_byname<char>::ctype_byname\"\n                            \" failed to construct for \" + string(name));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\nctype_byname<char>::ctype_byname(const string& name, size_t refs)\n    : ctype<char>(0, false, refs),\n      __l(newlocale(LC_ALL_MASK, name.c_str(), 0))\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__l == 0)\n        throw runtime_error(\"ctype_byname<char>::ctype_byname\"\n                            \" failed to construct for \" + name);\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\nctype_byname<char>::~ctype_byname()\n{\n    freelocale(__l);\n}\n\nchar\nctype_byname<char>::do_toupper(char_type c) const\n{\n    return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l));\n}\n\nconst char*\nctype_byname<char>::do_toupper(char_type* low, const char_type* high) const\n{\n    for (; low != high; ++low)\n        *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l));\n    return low;\n}\n\nchar\nctype_byname<char>::do_tolower(char_type c) const\n{\n    return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l));\n}\n\nconst char*\nctype_byname<char>::do_tolower(char_type* low, const char_type* high) const\n{\n    for (; low != high; ++low)\n        *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l));\n    return low;\n}\n\n// template <> class ctype_byname<wchar_t>\n\nctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)\n    : ctype<wchar_t>(refs),\n      __l(newlocale(LC_ALL_MASK, name, 0))\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__l == 0)\n        throw runtime_error(\"ctype_byname<wchar_t>::ctype_byname\"\n                            \" failed to construct for \" + string(name));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\nctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)\n    : ctype<wchar_t>(refs),\n      __l(newlocale(LC_ALL_MASK, name.c_str(), 0))\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__l == 0)\n        throw runtime_error(\"ctype_byname<wchar_t>::ctype_byname\"\n                            \" failed to construct for \" + name);\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\nctype_byname<wchar_t>::~ctype_byname()\n{\n    freelocale(__l);\n}\n\nbool\nctype_byname<wchar_t>::do_is(mask m, char_type c) const\n{\n#ifdef _LIBCPP_WCTYPE_IS_MASK\n    return static_cast<bool>(iswctype_l(c, m, __l));\n#else\n    bool result = false;\n    wint_t ch = static_cast<wint_t>(c);\n    if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0);\n    if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0);\n    if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0);\n    if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0);\n    if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0);\n    if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0);\n    if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0);\n    if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0);\n    if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0);\n    if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0);\n    return result;\n#endif\n}\n\nconst wchar_t*\nctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const\n{\n    for (; low != high; ++low, ++vec)\n    {\n        if (isascii(*low))\n            *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);\n        else\n        {\n            *vec = 0;\n            wint_t ch = static_cast<wint_t>(*low);\n            if (iswspace_l(ch, __l))\n                *vec |= space;\n#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT\n            if (iswprint_l(ch, __l))\n                *vec |= print;\n#endif\n            if (iswcntrl_l(ch, __l))\n                *vec |= cntrl;\n            if (iswupper_l(ch, __l))\n                *vec |= upper;\n            if (iswlower_l(ch, __l))\n                *vec |= lower;\n#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA\n            if (iswalpha_l(ch, __l))\n                *vec |= alpha;\n#endif\n            if (iswdigit_l(ch, __l))\n                *vec |= digit;\n            if (iswpunct_l(ch, __l))\n                *vec |= punct;\n#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT\n            if (iswxdigit_l(ch, __l))\n                *vec |= xdigit;\n#endif\n#if !defined(__sun__)\n            if (iswblank_l(ch, __l))\n                *vec |= blank;\n#endif\n        }\n    }\n    return low;\n}\n\nconst wchar_t*\nctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const\n{\n    for (; low != high; ++low)\n    {\n#ifdef _LIBCPP_WCTYPE_IS_MASK\n        if (iswctype_l(*low, m, __l))\n            break;\n#else\n        wint_t ch = static_cast<wint_t>(*low);\n        if ((m & space) == space && iswspace_l(ch, __l)) break;\n        if ((m & print) == print && iswprint_l(ch, __l)) break;\n        if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break;\n        if ((m & upper) == upper && iswupper_l(ch, __l)) break;\n        if ((m & lower) == lower && iswlower_l(ch, __l)) break;\n        if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break;\n        if ((m & digit) == digit && iswdigit_l(ch, __l)) break;\n        if ((m & punct) == punct && iswpunct_l(ch, __l)) break;\n        if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break;\n        if ((m & blank) == blank && iswblank_l(ch, __l)) break;\n#endif\n    }\n    return low;\n}\n\nconst wchar_t*\nctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const\n{\n    for (; low != high; ++low)\n    {\n#ifdef _LIBCPP_WCTYPE_IS_MASK\n        if (!iswctype_l(*low, m, __l))\n            break;\n#else\n        wint_t ch = static_cast<wint_t>(*low);\n        if ((m & space) == space && iswspace_l(ch, __l)) continue;\n        if ((m & print) == print && iswprint_l(ch, __l)) continue;\n        if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue;\n        if ((m & upper) == upper && iswupper_l(ch, __l)) continue;\n        if ((m & lower) == lower && iswlower_l(ch, __l)) continue;\n        if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue;\n        if ((m & digit) == digit && iswdigit_l(ch, __l)) continue;\n        if ((m & punct) == punct && iswpunct_l(ch, __l)) continue;\n        if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue;\n        if ((m & blank) == blank && iswblank_l(ch, __l)) continue;\n        break;\n#endif\n    }\n    return low;\n}\n\nwchar_t\nctype_byname<wchar_t>::do_toupper(char_type c) const\n{\n    return towupper_l(c, __l);\n}\n\nconst wchar_t*\nctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const\n{\n    for (; low != high; ++low)\n        *low = towupper_l(*low, __l);\n    return low;\n}\n\nwchar_t\nctype_byname<wchar_t>::do_tolower(char_type c) const\n{\n    return towlower_l(c, __l);\n}\n\nconst wchar_t*\nctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const\n{\n    for (; low != high; ++low)\n        *low = towlower_l(*low, __l);\n    return low;\n}\n\nwchar_t\nctype_byname<wchar_t>::do_widen(char c) const\n{\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    return btowc_l(c, __l);\n#else\n    return __btowc_l(c, __l);\n#endif\n}\n\nconst char*\nctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const\n{\n    for (; low != high; ++low, ++dest)\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        *dest = btowc_l(*low, __l);\n#else\n        *dest = __btowc_l(*low, __l);\n#endif\n    return low;\n}\n\nchar\nctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const\n{\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    int r = wctob_l(c, __l);\n#else\n    int r = __wctob_l(c, __l);\n#endif\n    return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;\n}\n\nconst wchar_t*\nctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const\n{\n    for (; low != high; ++low, ++dest)\n    {\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        int r = wctob_l(*low, __l);\n#else\n        int r = __wctob_l(*low, __l);\n#endif\n        *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;\n    }\n    return low;\n}\n\n// template <> class codecvt<char, char, mbstate_t>\n\nlocale::id codecvt<char, char, mbstate_t>::id;\n\ncodecvt<char, char, mbstate_t>::~codecvt()\n{\n}\n\ncodecvt<char, char, mbstate_t>::result\ncodecvt<char, char, mbstate_t>::do_out(state_type&,\n    const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    return noconv;\n}\n\ncodecvt<char, char, mbstate_t>::result\ncodecvt<char, char, mbstate_t>::do_in(state_type&,\n    const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,\n    intern_type* to, intern_type*, intern_type*& to_nxt) const\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    return noconv;\n}\n\ncodecvt<char, char, mbstate_t>::result\ncodecvt<char, char, mbstate_t>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\ncodecvt<char, char, mbstate_t>::do_encoding() const  _NOEXCEPT\n{\n    return 1;\n}\n\nbool\ncodecvt<char, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT\n{\n    return true;\n}\n\nint\ncodecvt<char, char, mbstate_t>::do_length(state_type&,\n    const extern_type* frm, const extern_type* end, size_t mx) const\n{\n    return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));\n}\n\nint\ncodecvt<char, char, mbstate_t>::do_max_length() const  _NOEXCEPT\n{\n    return 1;\n}\n\n// template <> class codecvt<wchar_t, char, mbstate_t>\n\nlocale::id codecvt<wchar_t, char, mbstate_t>::id;\n\ncodecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)\n    : locale::facet(refs),\n      __l(_LIBCPP_GET_C_LOCALE)\n{\n}\n\ncodecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)\n    : locale::facet(refs),\n      __l(newlocale(LC_ALL_MASK, nm, 0))\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__l == 0)\n        throw runtime_error(\"codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname\"\n                            \" failed to construct for \" + string(nm));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\ncodecvt<wchar_t, char, mbstate_t>::~codecvt()\n{\n    if (__l != _LIBCPP_GET_C_LOCALE)\n        freelocale(__l);\n}\n\ncodecvt<wchar_t, char, mbstate_t>::result\ncodecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    // look for first internal null in frm\n    const intern_type* fend = frm;\n    for (; fend != frm_end; ++fend)\n        if (*fend == 0)\n            break;\n    // loop over all null-terminated sequences in frm\n    to_nxt = to;\n    for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)\n    {\n        // save state in case it is needed to recover to_nxt on error\n        mbstate_t save_state = st;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        size_t n = wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),\n                                static_cast<size_t>(to_end-to), &st, __l);\n#else\n        size_t n = __wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);\n#endif\n        if (n == size_t(-1))\n        {\n            // need to recover to_nxt\n            for (to_nxt = to; frm != frm_nxt; ++frm)\n            {\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n                n = wcrtomb_l(to_nxt, *frm, &save_state, __l);\n#else\n                n = __wcrtomb_l(to_nxt, *frm, &save_state, __l);\n#endif\n                if (n == size_t(-1))\n                    break;\n                to_nxt += n;\n            }\n            frm_nxt = frm;\n            return error;\n        }\n        if (n == 0)\n            return partial;\n        to_nxt += n;\n        if (to_nxt == to_end)\n            break;\n        if (fend != frm_end)  // set up next null terminated sequence\n        {\n            // Try to write the terminating null\n            extern_type tmp[MB_LEN_MAX];\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n            n = wcrtomb_l(tmp, intern_type(), &st, __l);\n#else\n            n = __wcrtomb_l(tmp, intern_type(), &st, __l);\n#endif\n            if (n == size_t(-1))  // on error\n                return error;\n            if (n > static_cast<size_t>(to_end-to_nxt))  // is there room?\n                return partial;\n            for (extern_type* p = tmp; n; --n)  // write it\n                *to_nxt++ = *p++;\n            ++frm_nxt;\n            // look for next null in frm\n            for (fend = frm_nxt; fend != frm_end; ++fend)\n                if (*fend == 0)\n                    break;\n        }\n    }\n    return frm_nxt == frm_end ? ok : partial;\n}\n\ncodecvt<wchar_t, char, mbstate_t>::result\ncodecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    // look for first internal null in frm\n    const extern_type* fend = frm;\n    for (; fend != frm_end; ++fend)\n        if (*fend == 0)\n            break;\n    // loop over all null-terminated sequences in frm\n    to_nxt = to;\n    for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)\n    {\n        // save state in case it is needed to recover to_nxt on error\n        mbstate_t save_state = st;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        size_t n = mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),\n                                static_cast<size_t>(to_end-to), &st, __l);\n#else\n        size_t n = __mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);\n#endif\n        if (n == size_t(-1))\n        {\n            // need to recover to_nxt\n            for (to_nxt = to; frm != frm_nxt; ++to_nxt)\n            {\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n                n = mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),\n                              &save_state, __l);\n#else\n                n = __mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l);\n#endif\n                switch (n)\n                {\n                case 0:\n                    ++frm;\n                    break;\n                case size_t(-1):\n                    frm_nxt = frm;\n                    return error;\n                case size_t(-2):\n                    frm_nxt = frm;\n                    return partial;\n                default:\n                    frm += n;\n                    break;\n                }\n            }\n            frm_nxt = frm;\n            return frm_nxt == frm_end ? ok : partial;\n        }\n        if (n == size_t(-1))\n            return error;\n        to_nxt += n;\n        if (to_nxt == to_end)\n            break;\n        if (fend != frm_end)  // set up next null terminated sequence\n        {\n            // Try to write the terminating null\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n            n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);\n#else\n            n = __mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);\n#endif\n            if (n != 0)  // on error\n                return error;\n            ++to_nxt;\n            ++frm_nxt;\n            // look for next null in frm\n            for (fend = frm_nxt; fend != frm_end; ++fend)\n                if (*fend == 0)\n                    break;\n        }\n    }\n    return frm_nxt == frm_end ? ok : partial;\n}\n\ncodecvt<wchar_t, char, mbstate_t>::result\ncodecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    extern_type tmp[MB_LEN_MAX];\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    size_t n = wcrtomb_l(tmp, intern_type(), &st, __l);\n#else\n    size_t n = __wcrtomb_l(tmp, intern_type(), &st, __l);\n#endif\n    if (n == size_t(-1) || n == 0)  // on error\n        return error;\n    --n;\n    if (n > static_cast<size_t>(to_end-to_nxt))  // is there room?\n        return partial;\n    for (extern_type* p = tmp; n; --n)  // write it\n        *to_nxt++ = *p++;\n    return ok;\n}\n\nint\ncodecvt<wchar_t, char, mbstate_t>::do_encoding() const  _NOEXCEPT\n{\n#ifndef __CloudABI__\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    if (mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)\n#else\n    if (__mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)\n#endif\n        return -1;\n#endif\n\n    // stateless encoding\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    if (__l == 0 || MB_CUR_MAX_L(__l) == 1)  // there are no known constant length encodings\n#else\n    if (__l == 0 || __mb_cur_max_l(__l) == 1)  // there are no known constant length encodings\n#endif\n        return 1;                // which take more than 1 char to form a wchar_t\n    return 0;\n}\n\nbool\ncodecvt<wchar_t, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\ncodecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    int nbytes = 0;\n    for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)\n    {\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        size_t n = mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);\n#else\n        size_t n = __mbrlen_l(frm, frm_end-frm, &st, __l);\n#endif\n        switch (n)\n        {\n        case 0:\n            ++nbytes;\n            ++frm;\n            break;\n        case size_t(-1):\n        case size_t(-2):\n            return nbytes;\n        default:\n            nbytes += n;\n            frm += n;\n            break;\n        }\n    }\n    return nbytes;\n}\n\nint\ncodecvt<wchar_t, char, mbstate_t>::do_max_length() const  _NOEXCEPT\n{\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    return __l == 0 ? 1 : static_cast<int>(  MB_CUR_MAX_L(__l));\n#else\n    return __l == 0 ? 1 : static_cast<int>(__mb_cur_max_l(__l));\n#endif\n}\n\n//                                     Valid UTF ranges\n//     UTF-32               UTF-16                          UTF-8               # of code points\n//                     first      second       first   second    third   fourth\n// 000000 - 00007F  0000 - 007F               00 - 7F                                 127\n// 000080 - 0007FF  0080 - 07FF               C2 - DF, 80 - BF                       1920\n// 000800 - 000FFF  0800 - 0FFF               E0 - E0, A0 - BF, 80 - BF              2048\n// 001000 - 00CFFF  1000 - CFFF               E1 - EC, 80 - BF, 80 - BF             49152\n// 00D000 - 00D7FF  D000 - D7FF               ED - ED, 80 - 9F, 80 - BF              2048\n// 00D800 - 00DFFF                invalid\n// 00E000 - 00FFFF  E000 - FFFF               EE - EF, 80 - BF, 80 - BF              8192\n// 010000 - 03FFFF  D800 - D8BF, DC00 - DFFF  F0 - F0, 90 - BF, 80 - BF, 80 - BF   196608\n// 040000 - 0FFFFF  D8C0 - DBBF, DC00 - DFFF  F1 - F3, 80 - BF, 80 - BF, 80 - BF   786432\n// 100000 - 10FFFF  DBC0 - DBFF, DC00 - DFFF  F4 - F4, 80 - 8F, 80 - BF, 80 - BF    65536\n\nstatic\ncodecvt_base::result\nutf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,\n              uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,\n              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & generate_header)\n    {\n        if (to_end-to_nxt < 3)\n            return codecvt_base::partial;\n        *to_nxt++ = static_cast<uint8_t>(0xEF);\n        *to_nxt++ = static_cast<uint8_t>(0xBB);\n        *to_nxt++ = static_cast<uint8_t>(0xBF);\n    }\n    for (; frm_nxt < frm_end; ++frm_nxt)\n    {\n        uint16_t wc1 = *frm_nxt;\n        if (wc1 > Maxcode)\n            return codecvt_base::error;\n        if (wc1 < 0x0080)\n        {\n            if (to_end-to_nxt < 1)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(wc1);\n        }\n        else if (wc1 < 0x0800)\n        {\n            if (to_end-to_nxt < 2)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));\n        }\n        else if (wc1 < 0xD800)\n        {\n            if (to_end-to_nxt < 3)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));\n            *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));\n        }\n        else if (wc1 < 0xDC00)\n        {\n            if (frm_end-frm_nxt < 2)\n                return codecvt_base::partial;\n            uint16_t wc2 = frm_nxt[1];\n            if ((wc2 & 0xFC00) != 0xDC00)\n                return codecvt_base::error;\n            if (to_end-to_nxt < 4)\n                return codecvt_base::partial;\n            if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +\n                ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)\n                return codecvt_base::error;\n            ++frm_nxt;\n            uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;\n            *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4)     | ((wc1 & 0x003C) >> 2));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));\n            *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc2 & 0x003F));\n        }\n        else if (wc1 < 0xE000)\n        {\n            return codecvt_base::error;\n        }\n        else\n        {\n            if (to_end-to_nxt < 3)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));\n            *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));\n        }\n    }\n    return codecvt_base::ok;\n}\n\nstatic\ncodecvt_base::result\nutf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,\n              uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,\n              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & generate_header)\n    {\n        if (to_end-to_nxt < 3)\n            return codecvt_base::partial;\n        *to_nxt++ = static_cast<uint8_t>(0xEF);\n        *to_nxt++ = static_cast<uint8_t>(0xBB);\n        *to_nxt++ = static_cast<uint8_t>(0xBF);\n    }\n    for (; frm_nxt < frm_end; ++frm_nxt)\n    {\n        uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);\n        if (wc1 > Maxcode)\n            return codecvt_base::error;\n        if (wc1 < 0x0080)\n        {\n            if (to_end-to_nxt < 1)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(wc1);\n        }\n        else if (wc1 < 0x0800)\n        {\n            if (to_end-to_nxt < 2)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));\n        }\n        else if (wc1 < 0xD800)\n        {\n            if (to_end-to_nxt < 3)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));\n            *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));\n        }\n        else if (wc1 < 0xDC00)\n        {\n            if (frm_end-frm_nxt < 2)\n                return codecvt_base::partial;\n            uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);\n            if ((wc2 & 0xFC00) != 0xDC00)\n                return codecvt_base::error;\n            if (to_end-to_nxt < 4)\n                return codecvt_base::partial;\n            if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +\n                ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)\n                return codecvt_base::error;\n            ++frm_nxt;\n            uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;\n            *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4)     | ((wc1 & 0x003C) >> 2));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));\n            *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc2 & 0x003F));\n        }\n        else if (wc1 < 0xE000)\n        {\n            return codecvt_base::error;\n        }\n        else\n        {\n            if (to_end-to_nxt < 3)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));\n            *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));\n        }\n    }\n    return codecvt_base::ok;\n}\n\nstatic\ncodecvt_base::result\nutf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,\n              uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,\n              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&\n                                                          frm_nxt[2] == 0xBF)\n            frm_nxt += 3;\n    }\n    for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)\n    {\n        uint8_t c1 = *frm_nxt;\n        if (c1 > Maxcode)\n            return codecvt_base::error;\n        if (c1 < 0x80)\n        {\n            *to_nxt = static_cast<uint16_t>(c1);\n            ++frm_nxt;\n        }\n        else if (c1 < 0xC2)\n        {\n            return codecvt_base::error;\n        }\n        else if (c1 < 0xE0)\n        {\n            if (frm_end-frm_nxt < 2)\n                return codecvt_base::partial;\n            uint8_t c2 = frm_nxt[1];\n            if ((c2 & 0xC0) != 0x80)\n                return codecvt_base::error;\n            uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));\n            if (t > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = t;\n            frm_nxt += 2;\n        }\n        else if (c1 < 0xF0)\n        {\n            if (frm_end-frm_nxt < 3)\n                return codecvt_base::partial;\n            uint8_t c2 = frm_nxt[1];\n            uint8_t c3 = frm_nxt[2];\n            switch (c1)\n            {\n            case 0xE0:\n                if ((c2 & 0xE0) != 0xA0)\n                    return codecvt_base::error;\n                 break;\n            case 0xED:\n                if ((c2 & 0xE0) != 0x80)\n                    return codecvt_base::error;\n                 break;\n            default:\n                if ((c2 & 0xC0) != 0x80)\n                    return codecvt_base::error;\n                 break;\n            }\n            if ((c3 & 0xC0) != 0x80)\n                return codecvt_base::error;\n            uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)\n                                             | ((c2 & 0x3F) << 6)\n                                             |  (c3 & 0x3F));\n            if (t > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = t;\n            frm_nxt += 3;\n        }\n        else if (c1 < 0xF5)\n        {\n            if (frm_end-frm_nxt < 4)\n                return codecvt_base::partial;\n            uint8_t c2 = frm_nxt[1];\n            uint8_t c3 = frm_nxt[2];\n            uint8_t c4 = frm_nxt[3];\n            switch (c1)\n            {\n            case 0xF0:\n                if (!(0x90 <= c2 && c2 <= 0xBF))\n                    return codecvt_base::error;\n                 break;\n            case 0xF4:\n                if ((c2 & 0xF0) != 0x80)\n                    return codecvt_base::error;\n                 break;\n            default:\n                if ((c2 & 0xC0) != 0x80)\n                    return codecvt_base::error;\n                 break;\n            }\n            if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)\n                return codecvt_base::error;\n            if (to_end-to_nxt < 2)\n                return codecvt_base::partial;\n            if ((((c1 & 7UL) << 18) +\n                ((c2 & 0x3FUL) << 12) +\n                ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = static_cast<uint16_t>(\n                    0xD800\n                  | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)\n                  | ((c2 & 0x0F) << 2)\n                  | ((c3 & 0x30) >> 4));\n            *++to_nxt = static_cast<uint16_t>(\n                    0xDC00\n                  | ((c3 & 0x0F) << 6)\n                  |  (c4 & 0x3F));\n            frm_nxt += 4;\n        }\n        else\n        {\n            return codecvt_base::error;\n        }\n    }\n    return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;\n}\n\nstatic\ncodecvt_base::result\nutf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,\n              uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,\n              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&\n                                                          frm_nxt[2] == 0xBF)\n            frm_nxt += 3;\n    }\n    for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)\n    {\n        uint8_t c1 = *frm_nxt;\n        if (c1 > Maxcode)\n            return codecvt_base::error;\n        if (c1 < 0x80)\n        {\n            *to_nxt = static_cast<uint32_t>(c1);\n            ++frm_nxt;\n        }\n        else if (c1 < 0xC2)\n        {\n            return codecvt_base::error;\n        }\n        else if (c1 < 0xE0)\n        {\n            if (frm_end-frm_nxt < 2)\n                return codecvt_base::partial;\n            uint8_t c2 = frm_nxt[1];\n            if ((c2 & 0xC0) != 0x80)\n                return codecvt_base::error;\n            uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));\n            if (t > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = static_cast<uint32_t>(t);\n            frm_nxt += 2;\n        }\n        else if (c1 < 0xF0)\n        {\n            if (frm_end-frm_nxt < 3)\n                return codecvt_base::partial;\n            uint8_t c2 = frm_nxt[1];\n            uint8_t c3 = frm_nxt[2];\n            switch (c1)\n            {\n            case 0xE0:\n                if ((c2 & 0xE0) != 0xA0)\n                    return codecvt_base::error;\n                 break;\n            case 0xED:\n                if ((c2 & 0xE0) != 0x80)\n                    return codecvt_base::error;\n                 break;\n            default:\n                if ((c2 & 0xC0) != 0x80)\n                    return codecvt_base::error;\n                 break;\n            }\n            if ((c3 & 0xC0) != 0x80)\n                return codecvt_base::error;\n            uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)\n                                             | ((c2 & 0x3F) << 6)\n                                             |  (c3 & 0x3F));\n            if (t > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = static_cast<uint32_t>(t);\n            frm_nxt += 3;\n        }\n        else if (c1 < 0xF5)\n        {\n            if (frm_end-frm_nxt < 4)\n                return codecvt_base::partial;\n            uint8_t c2 = frm_nxt[1];\n            uint8_t c3 = frm_nxt[2];\n            uint8_t c4 = frm_nxt[3];\n            switch (c1)\n            {\n            case 0xF0:\n                if (!(0x90 <= c2 && c2 <= 0xBF))\n                    return codecvt_base::error;\n                 break;\n            case 0xF4:\n                if ((c2 & 0xF0) != 0x80)\n                    return codecvt_base::error;\n                 break;\n            default:\n                if ((c2 & 0xC0) != 0x80)\n                    return codecvt_base::error;\n                 break;\n            }\n            if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)\n                return codecvt_base::error;\n            if (to_end-to_nxt < 2)\n                return codecvt_base::partial;\n            if ((((c1 & 7UL) << 18) +\n                ((c2 & 0x3FUL) << 12) +\n                ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = static_cast<uint32_t>(\n                    0xD800\n                  | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)\n                  | ((c2 & 0x0F) << 2)\n                  | ((c3 & 0x30) >> 4));\n            *++to_nxt = static_cast<uint32_t>(\n                    0xDC00\n                  | ((c3 & 0x0F) << 6)\n                  |  (c4 & 0x3F));\n            frm_nxt += 4;\n        }\n        else\n        {\n            return codecvt_base::error;\n        }\n    }\n    return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;\n}\n\nstatic\nint\nutf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,\n                     size_t mx, unsigned long Maxcode = 0x10FFFF,\n                     codecvt_mode mode = codecvt_mode(0))\n{\n    const uint8_t* frm_nxt = frm;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&\n                                                          frm_nxt[2] == 0xBF)\n            frm_nxt += 3;\n    }\n    for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)\n    {\n        uint8_t c1 = *frm_nxt;\n        if (c1 > Maxcode)\n            break;\n        if (c1 < 0x80)\n        {\n            ++frm_nxt;\n        }\n        else if (c1 < 0xC2)\n        {\n            break;\n        }\n        else if (c1 < 0xE0)\n        {\n            if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)\n                break;\n            uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));\n            if (t > Maxcode)\n                break;\n            frm_nxt += 2;\n        }\n        else if (c1 < 0xF0)\n        {\n            if (frm_end-frm_nxt < 3)\n                break;\n            uint8_t c2 = frm_nxt[1];\n            uint8_t c3 = frm_nxt[2];\n            switch (c1)\n            {\n            case 0xE0:\n                if ((c2 & 0xE0) != 0xA0)\n                    return static_cast<int>(frm_nxt - frm);\n                break;\n            case 0xED:\n                if ((c2 & 0xE0) != 0x80)\n                    return static_cast<int>(frm_nxt - frm);\n                 break;\n            default:\n                if ((c2 & 0xC0) != 0x80)\n                    return static_cast<int>(frm_nxt - frm);\n                 break;\n            }\n            if ((c3 & 0xC0) != 0x80)\n                break;\n            if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)\n                break;\n            frm_nxt += 3;\n        }\n        else if (c1 < 0xF5)\n        {\n            if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)\n                break;\n            uint8_t c2 = frm_nxt[1];\n            uint8_t c3 = frm_nxt[2];\n            uint8_t c4 = frm_nxt[3];\n            switch (c1)\n            {\n            case 0xF0:\n                if (!(0x90 <= c2 && c2 <= 0xBF))\n                    return static_cast<int>(frm_nxt - frm);\n                 break;\n            case 0xF4:\n                if ((c2 & 0xF0) != 0x80)\n                    return static_cast<int>(frm_nxt - frm);\n                 break;\n            default:\n                if ((c2 & 0xC0) != 0x80)\n                    return static_cast<int>(frm_nxt - frm);\n                 break;\n            }\n            if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)\n                break;\n            if ((((c1 & 7UL) << 18) +\n                ((c2 & 0x3FUL) << 12) +\n                ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)\n                break;\n            ++nchar16_t;\n            frm_nxt += 4;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return static_cast<int>(frm_nxt - frm);\n}\n\nstatic\ncodecvt_base::result\nucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,\n             uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,\n             unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & generate_header)\n    {\n        if (to_end-to_nxt < 3)\n            return codecvt_base::partial;\n        *to_nxt++ = static_cast<uint8_t>(0xEF);\n        *to_nxt++ = static_cast<uint8_t>(0xBB);\n        *to_nxt++ = static_cast<uint8_t>(0xBF);\n    }\n    for (; frm_nxt < frm_end; ++frm_nxt)\n    {\n        uint32_t wc = *frm_nxt;\n        if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)\n            return codecvt_base::error;\n        if (wc < 0x000080)\n        {\n            if (to_end-to_nxt < 1)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(wc);\n        }\n        else if (wc < 0x000800)\n        {\n            if (to_end-to_nxt < 2)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));\n        }\n        else if (wc < 0x010000)\n        {\n            if (to_end-to_nxt < 3)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc >> 12));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));\n            *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x003F));\n        }\n        else // if (wc < 0x110000)\n        {\n            if (to_end-to_nxt < 4)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(0xF0 |  (wc >> 18));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));\n            *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x00003F));\n        }\n    }\n    return codecvt_base::ok;\n}\n\nstatic\ncodecvt_base::result\nutf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,\n             uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,\n             unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&\n                                                          frm_nxt[2] == 0xBF)\n            frm_nxt += 3;\n    }\n    for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)\n    {\n        uint8_t c1 = static_cast<uint8_t>(*frm_nxt);\n        if (c1 < 0x80)\n        {\n            if (c1 > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = static_cast<uint32_t>(c1);\n            ++frm_nxt;\n        }\n        else if (c1 < 0xC2)\n        {\n            return codecvt_base::error;\n        }\n        else if (c1 < 0xE0)\n        {\n            if (frm_end-frm_nxt < 2)\n                return codecvt_base::partial;\n            uint8_t c2 = frm_nxt[1];\n            if ((c2 & 0xC0) != 0x80)\n                return codecvt_base::error;\n            uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)\n                                              | (c2 & 0x3F));\n            if (t > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = t;\n            frm_nxt += 2;\n        }\n        else if (c1 < 0xF0)\n        {\n            if (frm_end-frm_nxt < 3)\n                return codecvt_base::partial;\n            uint8_t c2 = frm_nxt[1];\n            uint8_t c3 = frm_nxt[2];\n            switch (c1)\n            {\n            case 0xE0:\n                if ((c2 & 0xE0) != 0xA0)\n                    return codecvt_base::error;\n                 break;\n            case 0xED:\n                if ((c2 & 0xE0) != 0x80)\n                    return codecvt_base::error;\n                 break;\n            default:\n                if ((c2 & 0xC0) != 0x80)\n                    return codecvt_base::error;\n                 break;\n            }\n            if ((c3 & 0xC0) != 0x80)\n                return codecvt_base::error;\n            uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)\n                                             | ((c2 & 0x3F) << 6)\n                                             |  (c3 & 0x3F));\n            if (t > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = t;\n            frm_nxt += 3;\n        }\n        else if (c1 < 0xF5)\n        {\n            if (frm_end-frm_nxt < 4)\n                return codecvt_base::partial;\n            uint8_t c2 = frm_nxt[1];\n            uint8_t c3 = frm_nxt[2];\n            uint8_t c4 = frm_nxt[3];\n            switch (c1)\n            {\n            case 0xF0:\n                if (!(0x90 <= c2 && c2 <= 0xBF))\n                    return codecvt_base::error;\n                 break;\n            case 0xF4:\n                if ((c2 & 0xF0) != 0x80)\n                    return codecvt_base::error;\n                 break;\n            default:\n                if ((c2 & 0xC0) != 0x80)\n                    return codecvt_base::error;\n                 break;\n            }\n            if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)\n                return codecvt_base::error;\n            uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)\n                                             | ((c2 & 0x3F) << 12)\n                                             | ((c3 & 0x3F) << 6)\n                                             |  (c4 & 0x3F));\n            if (t > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = t;\n            frm_nxt += 4;\n        }\n        else\n        {\n            return codecvt_base::error;\n        }\n    }\n    return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;\n}\n\nstatic\nint\nutf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,\n                    size_t mx, unsigned long Maxcode = 0x10FFFF,\n                    codecvt_mode mode = codecvt_mode(0))\n{\n    const uint8_t* frm_nxt = frm;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&\n                                                          frm_nxt[2] == 0xBF)\n            frm_nxt += 3;\n    }\n    for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)\n    {\n        uint8_t c1 = static_cast<uint8_t>(*frm_nxt);\n        if (c1 < 0x80)\n        {\n            if (c1 > Maxcode)\n                break;\n            ++frm_nxt;\n        }\n        else if (c1 < 0xC2)\n        {\n            break;\n        }\n        else if (c1 < 0xE0)\n        {\n            if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))\n                break;\n            if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)\n                break;\n            frm_nxt += 2;\n        }\n        else if (c1 < 0xF0)\n        {\n            if (frm_end-frm_nxt < 3)\n                break;\n            uint8_t c2 = frm_nxt[1];\n            uint8_t c3 = frm_nxt[2];\n            switch (c1)\n            {\n            case 0xE0:\n                if ((c2 & 0xE0) != 0xA0)\n                    return static_cast<int>(frm_nxt - frm);\n                break;\n            case 0xED:\n                if ((c2 & 0xE0) != 0x80)\n                    return static_cast<int>(frm_nxt - frm);\n                 break;\n            default:\n                if ((c2 & 0xC0) != 0x80)\n                    return static_cast<int>(frm_nxt - frm);\n                 break;\n            }\n            if ((c3 & 0xC0) != 0x80)\n                break;\n            if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)\n                break;\n            frm_nxt += 3;\n        }\n        else if (c1 < 0xF5)\n        {\n            if (frm_end-frm_nxt < 4)\n                break;\n            uint8_t c2 = frm_nxt[1];\n            uint8_t c3 = frm_nxt[2];\n            uint8_t c4 = frm_nxt[3];\n            switch (c1)\n            {\n            case 0xF0:\n                if (!(0x90 <= c2 && c2 <= 0xBF))\n                    return static_cast<int>(frm_nxt - frm);\n                 break;\n            case 0xF4:\n                if ((c2 & 0xF0) != 0x80)\n                    return static_cast<int>(frm_nxt - frm);\n                 break;\n            default:\n                if ((c2 & 0xC0) != 0x80)\n                    return static_cast<int>(frm_nxt - frm);\n                 break;\n            }\n            if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)\n                break;\n            if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |\n                 ((c3 & 0x3Fu) << 6)  |  (c4 & 0x3Fu)) > Maxcode)\n                break;\n            frm_nxt += 4;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return static_cast<int>(frm_nxt - frm);\n}\n\nstatic\ncodecvt_base::result\nucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,\n             uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,\n             unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & generate_header)\n    {\n        if (to_end-to_nxt < 3)\n            return codecvt_base::partial;\n        *to_nxt++ = static_cast<uint8_t>(0xEF);\n        *to_nxt++ = static_cast<uint8_t>(0xBB);\n        *to_nxt++ = static_cast<uint8_t>(0xBF);\n    }\n    for (; frm_nxt < frm_end; ++frm_nxt)\n    {\n        uint16_t wc = *frm_nxt;\n        if ((wc & 0xF800) == 0xD800 || wc > Maxcode)\n            return codecvt_base::error;\n        if (wc < 0x0080)\n        {\n            if (to_end-to_nxt < 1)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(wc);\n        }\n        else if (wc < 0x0800)\n        {\n            if (to_end-to_nxt < 2)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));\n        }\n        else // if (wc <= 0xFFFF)\n        {\n            if (to_end-to_nxt < 3)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc >> 12));\n            *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));\n            *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x003F));\n        }\n    }\n    return codecvt_base::ok;\n}\n\nstatic\ncodecvt_base::result\nutf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,\n             uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,\n             unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&\n                                                          frm_nxt[2] == 0xBF)\n            frm_nxt += 3;\n    }\n    for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)\n    {\n        uint8_t c1 = static_cast<uint8_t>(*frm_nxt);\n        if (c1 < 0x80)\n        {\n            if (c1 > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = static_cast<uint16_t>(c1);\n            ++frm_nxt;\n        }\n        else if (c1 < 0xC2)\n        {\n            return codecvt_base::error;\n        }\n        else if (c1 < 0xE0)\n        {\n            if (frm_end-frm_nxt < 2)\n                return codecvt_base::partial;\n            uint8_t c2 = frm_nxt[1];\n            if ((c2 & 0xC0) != 0x80)\n                return codecvt_base::error;\n            uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)\n                                              | (c2 & 0x3F));\n            if (t > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = t;\n            frm_nxt += 2;\n        }\n        else if (c1 < 0xF0)\n        {\n            if (frm_end-frm_nxt < 3)\n                return codecvt_base::partial;\n            uint8_t c2 = frm_nxt[1];\n            uint8_t c3 = frm_nxt[2];\n            switch (c1)\n            {\n            case 0xE0:\n                if ((c2 & 0xE0) != 0xA0)\n                    return codecvt_base::error;\n                 break;\n            case 0xED:\n                if ((c2 & 0xE0) != 0x80)\n                    return codecvt_base::error;\n                 break;\n            default:\n                if ((c2 & 0xC0) != 0x80)\n                    return codecvt_base::error;\n                 break;\n            }\n            if ((c3 & 0xC0) != 0x80)\n                return codecvt_base::error;\n            uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)\n                                             | ((c2 & 0x3F) << 6)\n                                             |  (c3 & 0x3F));\n            if (t > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = t;\n            frm_nxt += 3;\n        }\n        else\n        {\n            return codecvt_base::error;\n        }\n    }\n    return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;\n}\n\nstatic\nint\nutf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,\n                    size_t mx, unsigned long Maxcode = 0x10FFFF,\n                    codecvt_mode mode = codecvt_mode(0))\n{\n    const uint8_t* frm_nxt = frm;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&\n                                                          frm_nxt[2] == 0xBF)\n            frm_nxt += 3;\n    }\n    for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)\n    {\n        uint8_t c1 = static_cast<uint8_t>(*frm_nxt);\n        if (c1 < 0x80)\n        {\n            if (c1 > Maxcode)\n                break;\n            ++frm_nxt;\n        }\n        else if (c1 < 0xC2)\n        {\n            break;\n        }\n        else if (c1 < 0xE0)\n        {\n            if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))\n                break;\n            if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)\n                break;\n            frm_nxt += 2;\n        }\n        else if (c1 < 0xF0)\n        {\n            if (frm_end-frm_nxt < 3)\n                break;\n            uint8_t c2 = frm_nxt[1];\n            uint8_t c3 = frm_nxt[2];\n            switch (c1)\n            {\n            case 0xE0:\n                if ((c2 & 0xE0) != 0xA0)\n                    return static_cast<int>(frm_nxt - frm);\n                break;\n            case 0xED:\n                if ((c2 & 0xE0) != 0x80)\n                    return static_cast<int>(frm_nxt - frm);\n                 break;\n            default:\n                if ((c2 & 0xC0) != 0x80)\n                    return static_cast<int>(frm_nxt - frm);\n                 break;\n            }\n            if ((c3 & 0xC0) != 0x80)\n                break;\n            if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)\n                break;\n            frm_nxt += 3;\n        }\n        else\n        {\n            break;\n        }\n    }\n    return static_cast<int>(frm_nxt - frm);\n}\n\nstatic\ncodecvt_base::result\nucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,\n                uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,\n                unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & generate_header)\n    {\n        if (to_end-to_nxt < 2)\n            return codecvt_base::partial;\n        *to_nxt++ = static_cast<uint8_t>(0xFE);\n        *to_nxt++ = static_cast<uint8_t>(0xFF);\n    }\n    for (; frm_nxt < frm_end; ++frm_nxt)\n    {\n        uint32_t wc = *frm_nxt;\n        if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)\n            return codecvt_base::error;\n        if (wc < 0x010000)\n        {\n            if (to_end-to_nxt < 2)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(wc >> 8);\n            *to_nxt++ = static_cast<uint8_t>(wc);\n        }\n        else\n        {\n            if (to_end-to_nxt < 4)\n                return codecvt_base::partial;\n            uint16_t t = static_cast<uint16_t>(\n                    0xD800\n                  | ((((wc & 0x1F0000) >> 16) - 1) << 6)\n                  |   ((wc & 0x00FC00) >> 10));\n            *to_nxt++ = static_cast<uint8_t>(t >> 8);\n            *to_nxt++ = static_cast<uint8_t>(t);\n            t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));\n            *to_nxt++ = static_cast<uint8_t>(t >> 8);\n            *to_nxt++ = static_cast<uint8_t>(t);\n        }\n    }\n    return codecvt_base::ok;\n}\n\nstatic\ncodecvt_base::result\nutf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,\n                uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,\n                unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)\n            frm_nxt += 2;\n    }\n    for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)\n    {\n        uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);\n        if ((c1 & 0xFC00) == 0xDC00)\n            return codecvt_base::error;\n        if ((c1 & 0xFC00) != 0xD800)\n        {\n            if (c1 > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = static_cast<uint32_t>(c1);\n            frm_nxt += 2;\n        }\n        else\n        {\n            if (frm_end-frm_nxt < 4)\n                return codecvt_base::partial;\n            uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);\n            if ((c2 & 0xFC00) != 0xDC00)\n                return codecvt_base::error;\n            uint32_t t = static_cast<uint32_t>(\n                    ((((c1 & 0x03C0) >> 6) + 1) << 16)\n                  |   ((c1 & 0x003F) << 10)\n                  |    (c2 & 0x03FF));\n            if (t > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = t;\n            frm_nxt += 4;\n        }\n    }\n    return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;\n}\n\nstatic\nint\nutf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,\n                       size_t mx, unsigned long Maxcode = 0x10FFFF,\n                       codecvt_mode mode = codecvt_mode(0))\n{\n    const uint8_t* frm_nxt = frm;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)\n            frm_nxt += 2;\n    }\n    for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)\n    {\n        uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);\n        if ((c1 & 0xFC00) == 0xDC00)\n            break;\n        if ((c1 & 0xFC00) != 0xD800)\n        {\n            if (c1 > Maxcode)\n                break;\n            frm_nxt += 2;\n        }\n        else\n        {\n            if (frm_end-frm_nxt < 4)\n                break;\n            uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);\n            if ((c2 & 0xFC00) != 0xDC00)\n                break;\n            uint32_t t = static_cast<uint32_t>(\n                    ((((c1 & 0x03C0) >> 6) + 1) << 16)\n                  |   ((c1 & 0x003F) << 10)\n                  |    (c2 & 0x03FF));\n            if (t > Maxcode)\n                break;\n            frm_nxt += 4;\n        }\n    }\n    return static_cast<int>(frm_nxt - frm);\n}\n\nstatic\ncodecvt_base::result\nucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,\n                uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,\n                unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & generate_header)\n    {\n        if (to_end-to_nxt < 2)\n            return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(0xFF);\n            *to_nxt++ = static_cast<uint8_t>(0xFE);\n    }\n    for (; frm_nxt < frm_end; ++frm_nxt)\n    {\n        uint32_t wc = *frm_nxt;\n        if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)\n            return codecvt_base::error;\n        if (wc < 0x010000)\n        {\n            if (to_end-to_nxt < 2)\n                return codecvt_base::partial;\n            *to_nxt++ = static_cast<uint8_t>(wc);\n            *to_nxt++ = static_cast<uint8_t>(wc >> 8);\n        }\n        else\n        {\n            if (to_end-to_nxt < 4)\n                return codecvt_base::partial;\n            uint16_t t = static_cast<uint16_t>(\n                    0xD800\n                  | ((((wc & 0x1F0000) >> 16) - 1) << 6)\n                  |   ((wc & 0x00FC00) >> 10));\n            *to_nxt++ = static_cast<uint8_t>(t);\n            *to_nxt++ = static_cast<uint8_t>(t >> 8);\n            t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));\n            *to_nxt++ = static_cast<uint8_t>(t);\n            *to_nxt++ = static_cast<uint8_t>(t >> 8);\n        }\n    }\n    return codecvt_base::ok;\n}\n\nstatic\ncodecvt_base::result\nutf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,\n                uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,\n                unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)\n            frm_nxt += 2;\n    }\n    for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)\n    {\n        uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);\n        if ((c1 & 0xFC00) == 0xDC00)\n            return codecvt_base::error;\n        if ((c1 & 0xFC00) != 0xD800)\n        {\n            if (c1 > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = static_cast<uint32_t>(c1);\n            frm_nxt += 2;\n        }\n        else\n        {\n            if (frm_end-frm_nxt < 4)\n                return codecvt_base::partial;\n            uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);\n            if ((c2 & 0xFC00) != 0xDC00)\n                return codecvt_base::error;\n            uint32_t t = static_cast<uint32_t>(\n                    ((((c1 & 0x03C0) >> 6) + 1) << 16)\n                  |   ((c1 & 0x003F) << 10)\n                  |    (c2 & 0x03FF));\n            if (t > Maxcode)\n                return codecvt_base::error;\n            *to_nxt = t;\n            frm_nxt += 4;\n        }\n    }\n    return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;\n}\n\nstatic\nint\nutf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,\n                       size_t mx, unsigned long Maxcode = 0x10FFFF,\n                       codecvt_mode mode = codecvt_mode(0))\n{\n    const uint8_t* frm_nxt = frm;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)\n            frm_nxt += 2;\n    }\n    for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)\n    {\n        uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);\n        if ((c1 & 0xFC00) == 0xDC00)\n            break;\n        if ((c1 & 0xFC00) != 0xD800)\n        {\n            if (c1 > Maxcode)\n                break;\n            frm_nxt += 2;\n        }\n        else\n        {\n            if (frm_end-frm_nxt < 4)\n                break;\n            uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);\n            if ((c2 & 0xFC00) != 0xDC00)\n                break;\n            uint32_t t = static_cast<uint32_t>(\n                    ((((c1 & 0x03C0) >> 6) + 1) << 16)\n                  |   ((c1 & 0x003F) << 10)\n                  |    (c2 & 0x03FF));\n            if (t > Maxcode)\n                break;\n            frm_nxt += 4;\n        }\n    }\n    return static_cast<int>(frm_nxt - frm);\n}\n\nstatic\ncodecvt_base::result\nucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,\n                uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,\n                unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & generate_header)\n    {\n        if (to_end-to_nxt < 2)\n            return codecvt_base::partial;\n        *to_nxt++ = static_cast<uint8_t>(0xFE);\n        *to_nxt++ = static_cast<uint8_t>(0xFF);\n    }\n    for (; frm_nxt < frm_end; ++frm_nxt)\n    {\n        uint16_t wc = *frm_nxt;\n        if ((wc & 0xF800) == 0xD800 || wc > Maxcode)\n            return codecvt_base::error;\n        if (to_end-to_nxt < 2)\n            return codecvt_base::partial;\n        *to_nxt++ = static_cast<uint8_t>(wc >> 8);\n        *to_nxt++ = static_cast<uint8_t>(wc);\n    }\n    return codecvt_base::ok;\n}\n\nstatic\ncodecvt_base::result\nutf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,\n                uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,\n                unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)\n            frm_nxt += 2;\n    }\n    for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)\n    {\n        uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);\n        if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)\n            return codecvt_base::error;\n        *to_nxt = c1;\n        frm_nxt += 2;\n    }\n    return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;\n}\n\nstatic\nint\nutf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,\n                       size_t mx, unsigned long Maxcode = 0x10FFFF,\n                       codecvt_mode mode = codecvt_mode(0))\n{\n    const uint8_t* frm_nxt = frm;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)\n            frm_nxt += 2;\n    }\n    for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)\n    {\n        uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);\n        if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)\n            break;\n        frm_nxt += 2;\n    }\n    return static_cast<int>(frm_nxt - frm);\n}\n\nstatic\ncodecvt_base::result\nucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,\n                uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,\n                unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & generate_header)\n    {\n        if (to_end-to_nxt < 2)\n            return codecvt_base::partial;\n        *to_nxt++ = static_cast<uint8_t>(0xFF);\n        *to_nxt++ = static_cast<uint8_t>(0xFE);\n    }\n    for (; frm_nxt < frm_end; ++frm_nxt)\n    {\n        uint16_t wc = *frm_nxt;\n        if ((wc & 0xF800) == 0xD800 || wc > Maxcode)\n            return codecvt_base::error;\n        if (to_end-to_nxt < 2)\n            return codecvt_base::partial;\n        *to_nxt++ = static_cast<uint8_t>(wc);\n        *to_nxt++ = static_cast<uint8_t>(wc >> 8);\n    }\n    return codecvt_base::ok;\n}\n\nstatic\ncodecvt_base::result\nutf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,\n                uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,\n                unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))\n{\n    frm_nxt = frm;\n    to_nxt = to;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)\n            frm_nxt += 2;\n    }\n    for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)\n    {\n        uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);\n        if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)\n            return codecvt_base::error;\n        *to_nxt = c1;\n        frm_nxt += 2;\n    }\n    return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;\n}\n\nstatic\nint\nutf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,\n                       size_t mx, unsigned long Maxcode = 0x10FFFF,\n                       codecvt_mode mode = codecvt_mode(0))\n{\n    const uint8_t* frm_nxt = frm;\n    frm_nxt = frm;\n    if (mode & consume_header)\n    {\n        if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)\n            frm_nxt += 2;\n    }\n    for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)\n    {\n        uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);\n        if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)\n            break;\n        frm_nxt += 2;\n    }\n    return static_cast<int>(frm_nxt - frm);\n}\n\n// template <> class codecvt<char16_t, char, mbstate_t>\n\nlocale::id codecvt<char16_t, char, mbstate_t>::id;\n\ncodecvt<char16_t, char, mbstate_t>::~codecvt()\n{\n}\n\ncodecvt<char16_t, char, mbstate_t>::result\ncodecvt<char16_t, char, mbstate_t>::do_out(state_type&,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);\n    const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);\n    const uint16_t* _frm_nxt = _frm;\n    uint8_t* _to = reinterpret_cast<uint8_t*>(to);\n    uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);\n    uint8_t* _to_nxt = _to;\n    result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\ncodecvt<char16_t, char, mbstate_t>::result\ncodecvt<char16_t, char, mbstate_t>::do_in(state_type&,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    const uint8_t* _frm_nxt = _frm;\n    uint16_t* _to = reinterpret_cast<uint16_t*>(to);\n    uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);\n    uint16_t* _to_nxt = _to;\n    result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\ncodecvt<char16_t, char, mbstate_t>::result\ncodecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\ncodecvt<char16_t, char, mbstate_t>::do_encoding() const  _NOEXCEPT\n{\n    return 0;\n}\n\nbool\ncodecvt<char16_t, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\ncodecvt<char16_t, char, mbstate_t>::do_length(state_type&,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    return utf8_to_utf16_length(_frm, _frm_end, mx);\n}\n\nint\ncodecvt<char16_t, char, mbstate_t>::do_max_length() const  _NOEXCEPT\n{\n    return 4;\n}\n\n// template <> class codecvt<char32_t, char, mbstate_t>\n\nlocale::id codecvt<char32_t, char, mbstate_t>::id;\n\ncodecvt<char32_t, char, mbstate_t>::~codecvt()\n{\n}\n\ncodecvt<char32_t, char, mbstate_t>::result\ncodecvt<char32_t, char, mbstate_t>::do_out(state_type&,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);\n    const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);\n    const uint32_t* _frm_nxt = _frm;\n    uint8_t* _to = reinterpret_cast<uint8_t*>(to);\n    uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);\n    uint8_t* _to_nxt = _to;\n    result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\ncodecvt<char32_t, char, mbstate_t>::result\ncodecvt<char32_t, char, mbstate_t>::do_in(state_type&,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    const uint8_t* _frm_nxt = _frm;\n    uint32_t* _to = reinterpret_cast<uint32_t*>(to);\n    uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);\n    uint32_t* _to_nxt = _to;\n    result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\ncodecvt<char32_t, char, mbstate_t>::result\ncodecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\ncodecvt<char32_t, char, mbstate_t>::do_encoding() const  _NOEXCEPT\n{\n    return 0;\n}\n\nbool\ncodecvt<char32_t, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\ncodecvt<char32_t, char, mbstate_t>::do_length(state_type&,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    return utf8_to_ucs4_length(_frm, _frm_end, mx);\n}\n\nint\ncodecvt<char32_t, char, mbstate_t>::do_max_length() const  _NOEXCEPT\n{\n    return 4;\n}\n\n// __codecvt_utf8<wchar_t>\n\n__codecvt_utf8<wchar_t>::result\n__codecvt_utf8<wchar_t>::do_out(state_type&,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n#if _WIN32\n    const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);\n    const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);\n    const uint16_t* _frm_nxt = _frm;\n#else\n    const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);\n    const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);\n    const uint32_t* _frm_nxt = _frm;\n#endif\n    uint8_t* _to = reinterpret_cast<uint8_t*>(to);\n    uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);\n    uint8_t* _to_nxt = _to;\n#if _WIN32\n    result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                            _Maxcode_, _Mode_);\n#else\n    result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                            _Maxcode_, _Mode_);\n#endif\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf8<wchar_t>::result\n__codecvt_utf8<wchar_t>::do_in(state_type&,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    const uint8_t* _frm_nxt = _frm;\n#if _WIN32\n    uint16_t* _to = reinterpret_cast<uint16_t*>(to);\n    uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);\n    uint16_t* _to_nxt = _to;\n    result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                            _Maxcode_, _Mode_);\n#else\n    uint32_t* _to = reinterpret_cast<uint32_t*>(to);\n    uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);\n    uint32_t* _to_nxt = _to;\n    result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                            _Maxcode_, _Mode_);\n#endif\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf8<wchar_t>::result\n__codecvt_utf8<wchar_t>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\n__codecvt_utf8<wchar_t>::do_encoding() const  _NOEXCEPT\n{\n    return 0;\n}\n\nbool\n__codecvt_utf8<wchar_t>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\n__codecvt_utf8<wchar_t>::do_length(state_type&,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);\n}\n\nint\n__codecvt_utf8<wchar_t>::do_max_length() const  _NOEXCEPT\n{\n    if (_Mode_ & consume_header)\n        return 7;\n    return 4;\n}\n\n// __codecvt_utf8<char16_t>\n\n__codecvt_utf8<char16_t>::result\n__codecvt_utf8<char16_t>::do_out(state_type&,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);\n    const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);\n    const uint16_t* _frm_nxt = _frm;\n    uint8_t* _to = reinterpret_cast<uint8_t*>(to);\n    uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);\n    uint8_t* _to_nxt = _to;\n    result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                            _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf8<char16_t>::result\n__codecvt_utf8<char16_t>::do_in(state_type&,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    const uint8_t* _frm_nxt = _frm;\n    uint16_t* _to = reinterpret_cast<uint16_t*>(to);\n    uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);\n    uint16_t* _to_nxt = _to;\n    result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                            _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf8<char16_t>::result\n__codecvt_utf8<char16_t>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\n__codecvt_utf8<char16_t>::do_encoding() const  _NOEXCEPT\n{\n    return 0;\n}\n\nbool\n__codecvt_utf8<char16_t>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\n__codecvt_utf8<char16_t>::do_length(state_type&,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);\n}\n\nint\n__codecvt_utf8<char16_t>::do_max_length() const  _NOEXCEPT\n{\n    if (_Mode_ & consume_header)\n        return 6;\n    return 3;\n}\n\n// __codecvt_utf8<char32_t>\n\n__codecvt_utf8<char32_t>::result\n__codecvt_utf8<char32_t>::do_out(state_type&,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);\n    const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);\n    const uint32_t* _frm_nxt = _frm;\n    uint8_t* _to = reinterpret_cast<uint8_t*>(to);\n    uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);\n    uint8_t* _to_nxt = _to;\n    result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                            _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf8<char32_t>::result\n__codecvt_utf8<char32_t>::do_in(state_type&,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    const uint8_t* _frm_nxt = _frm;\n    uint32_t* _to = reinterpret_cast<uint32_t*>(to);\n    uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);\n    uint32_t* _to_nxt = _to;\n    result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                            _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf8<char32_t>::result\n__codecvt_utf8<char32_t>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\n__codecvt_utf8<char32_t>::do_encoding() const  _NOEXCEPT\n{\n    return 0;\n}\n\nbool\n__codecvt_utf8<char32_t>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\n__codecvt_utf8<char32_t>::do_length(state_type&,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);\n}\n\nint\n__codecvt_utf8<char32_t>::do_max_length() const  _NOEXCEPT\n{\n    if (_Mode_ & consume_header)\n        return 7;\n    return 4;\n}\n\n// __codecvt_utf16<wchar_t, false>\n\n__codecvt_utf16<wchar_t, false>::result\n__codecvt_utf16<wchar_t, false>::do_out(state_type&,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);\n    const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);\n    const uint32_t* _frm_nxt = _frm;\n    uint8_t* _to = reinterpret_cast<uint8_t*>(to);\n    uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);\n    uint8_t* _to_nxt = _to;\n    result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                               _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf16<wchar_t, false>::result\n__codecvt_utf16<wchar_t, false>::do_in(state_type&,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    const uint8_t* _frm_nxt = _frm;\n    uint32_t* _to = reinterpret_cast<uint32_t*>(to);\n    uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);\n    uint32_t* _to_nxt = _to;\n    result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                               _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf16<wchar_t, false>::result\n__codecvt_utf16<wchar_t, false>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\n__codecvt_utf16<wchar_t, false>::do_encoding() const  _NOEXCEPT\n{\n    return 0;\n}\n\nbool\n__codecvt_utf16<wchar_t, false>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\n__codecvt_utf16<wchar_t, false>::do_length(state_type&,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);\n}\n\nint\n__codecvt_utf16<wchar_t, false>::do_max_length() const  _NOEXCEPT\n{\n    if (_Mode_ & consume_header)\n        return 6;\n    return 4;\n}\n\n// __codecvt_utf16<wchar_t, true>\n\n__codecvt_utf16<wchar_t, true>::result\n__codecvt_utf16<wchar_t, true>::do_out(state_type&,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);\n    const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);\n    const uint32_t* _frm_nxt = _frm;\n    uint8_t* _to = reinterpret_cast<uint8_t*>(to);\n    uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);\n    uint8_t* _to_nxt = _to;\n    result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                               _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf16<wchar_t, true>::result\n__codecvt_utf16<wchar_t, true>::do_in(state_type&,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    const uint8_t* _frm_nxt = _frm;\n    uint32_t* _to = reinterpret_cast<uint32_t*>(to);\n    uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);\n    uint32_t* _to_nxt = _to;\n    result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                               _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf16<wchar_t, true>::result\n__codecvt_utf16<wchar_t, true>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\n__codecvt_utf16<wchar_t, true>::do_encoding() const  _NOEXCEPT\n{\n    return 0;\n}\n\nbool\n__codecvt_utf16<wchar_t, true>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\n__codecvt_utf16<wchar_t, true>::do_length(state_type&,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);\n}\n\nint\n__codecvt_utf16<wchar_t, true>::do_max_length() const  _NOEXCEPT\n{\n    if (_Mode_ & consume_header)\n        return 6;\n    return 4;\n}\n\n// __codecvt_utf16<char16_t, false>\n\n__codecvt_utf16<char16_t, false>::result\n__codecvt_utf16<char16_t, false>::do_out(state_type&,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);\n    const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);\n    const uint16_t* _frm_nxt = _frm;\n    uint8_t* _to = reinterpret_cast<uint8_t*>(to);\n    uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);\n    uint8_t* _to_nxt = _to;\n    result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                               _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf16<char16_t, false>::result\n__codecvt_utf16<char16_t, false>::do_in(state_type&,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    const uint8_t* _frm_nxt = _frm;\n    uint16_t* _to = reinterpret_cast<uint16_t*>(to);\n    uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);\n    uint16_t* _to_nxt = _to;\n    result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                               _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf16<char16_t, false>::result\n__codecvt_utf16<char16_t, false>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\n__codecvt_utf16<char16_t, false>::do_encoding() const  _NOEXCEPT\n{\n    return 0;\n}\n\nbool\n__codecvt_utf16<char16_t, false>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\n__codecvt_utf16<char16_t, false>::do_length(state_type&,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);\n}\n\nint\n__codecvt_utf16<char16_t, false>::do_max_length() const  _NOEXCEPT\n{\n    if (_Mode_ & consume_header)\n        return 4;\n    return 2;\n}\n\n// __codecvt_utf16<char16_t, true>\n\n__codecvt_utf16<char16_t, true>::result\n__codecvt_utf16<char16_t, true>::do_out(state_type&,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);\n    const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);\n    const uint16_t* _frm_nxt = _frm;\n    uint8_t* _to = reinterpret_cast<uint8_t*>(to);\n    uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);\n    uint8_t* _to_nxt = _to;\n    result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                               _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf16<char16_t, true>::result\n__codecvt_utf16<char16_t, true>::do_in(state_type&,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    const uint8_t* _frm_nxt = _frm;\n    uint16_t* _to = reinterpret_cast<uint16_t*>(to);\n    uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);\n    uint16_t* _to_nxt = _to;\n    result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                               _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf16<char16_t, true>::result\n__codecvt_utf16<char16_t, true>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\n__codecvt_utf16<char16_t, true>::do_encoding() const  _NOEXCEPT\n{\n    return 0;\n}\n\nbool\n__codecvt_utf16<char16_t, true>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\n__codecvt_utf16<char16_t, true>::do_length(state_type&,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);\n}\n\nint\n__codecvt_utf16<char16_t, true>::do_max_length() const  _NOEXCEPT\n{\n    if (_Mode_ & consume_header)\n        return 4;\n    return 2;\n}\n\n// __codecvt_utf16<char32_t, false>\n\n__codecvt_utf16<char32_t, false>::result\n__codecvt_utf16<char32_t, false>::do_out(state_type&,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);\n    const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);\n    const uint32_t* _frm_nxt = _frm;\n    uint8_t* _to = reinterpret_cast<uint8_t*>(to);\n    uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);\n    uint8_t* _to_nxt = _to;\n    result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                               _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf16<char32_t, false>::result\n__codecvt_utf16<char32_t, false>::do_in(state_type&,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    const uint8_t* _frm_nxt = _frm;\n    uint32_t* _to = reinterpret_cast<uint32_t*>(to);\n    uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);\n    uint32_t* _to_nxt = _to;\n    result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                               _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf16<char32_t, false>::result\n__codecvt_utf16<char32_t, false>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\n__codecvt_utf16<char32_t, false>::do_encoding() const  _NOEXCEPT\n{\n    return 0;\n}\n\nbool\n__codecvt_utf16<char32_t, false>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\n__codecvt_utf16<char32_t, false>::do_length(state_type&,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);\n}\n\nint\n__codecvt_utf16<char32_t, false>::do_max_length() const  _NOEXCEPT\n{\n    if (_Mode_ & consume_header)\n        return 6;\n    return 4;\n}\n\n// __codecvt_utf16<char32_t, true>\n\n__codecvt_utf16<char32_t, true>::result\n__codecvt_utf16<char32_t, true>::do_out(state_type&,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);\n    const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);\n    const uint32_t* _frm_nxt = _frm;\n    uint8_t* _to = reinterpret_cast<uint8_t*>(to);\n    uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);\n    uint8_t* _to_nxt = _to;\n    result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                               _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf16<char32_t, true>::result\n__codecvt_utf16<char32_t, true>::do_in(state_type&,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    const uint8_t* _frm_nxt = _frm;\n    uint32_t* _to = reinterpret_cast<uint32_t*>(to);\n    uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);\n    uint32_t* _to_nxt = _to;\n    result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                               _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf16<char32_t, true>::result\n__codecvt_utf16<char32_t, true>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\n__codecvt_utf16<char32_t, true>::do_encoding() const  _NOEXCEPT\n{\n    return 0;\n}\n\nbool\n__codecvt_utf16<char32_t, true>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\n__codecvt_utf16<char32_t, true>::do_length(state_type&,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);\n}\n\nint\n__codecvt_utf16<char32_t, true>::do_max_length() const  _NOEXCEPT\n{\n    if (_Mode_ & consume_header)\n        return 6;\n    return 4;\n}\n\n// __codecvt_utf8_utf16<wchar_t>\n\n__codecvt_utf8_utf16<wchar_t>::result\n__codecvt_utf8_utf16<wchar_t>::do_out(state_type&,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);\n    const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);\n    const uint32_t* _frm_nxt = _frm;\n    uint8_t* _to = reinterpret_cast<uint8_t*>(to);\n    uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);\n    uint8_t* _to_nxt = _to;\n    result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                             _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf8_utf16<wchar_t>::result\n__codecvt_utf8_utf16<wchar_t>::do_in(state_type&,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    const uint8_t* _frm_nxt = _frm;\n    uint32_t* _to = reinterpret_cast<uint32_t*>(to);\n    uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);\n    uint32_t* _to_nxt = _to;\n    result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                             _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf8_utf16<wchar_t>::result\n__codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\n__codecvt_utf8_utf16<wchar_t>::do_encoding() const  _NOEXCEPT\n{\n    return 0;\n}\n\nbool\n__codecvt_utf8_utf16<wchar_t>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\n__codecvt_utf8_utf16<wchar_t>::do_length(state_type&,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);\n}\n\nint\n__codecvt_utf8_utf16<wchar_t>::do_max_length() const  _NOEXCEPT\n{\n    if (_Mode_ & consume_header)\n        return 7;\n    return 4;\n}\n\n// __codecvt_utf8_utf16<char16_t>\n\n__codecvt_utf8_utf16<char16_t>::result\n__codecvt_utf8_utf16<char16_t>::do_out(state_type&,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);\n    const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);\n    const uint16_t* _frm_nxt = _frm;\n    uint8_t* _to = reinterpret_cast<uint8_t*>(to);\n    uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);\n    uint8_t* _to_nxt = _to;\n    result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                             _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf8_utf16<char16_t>::result\n__codecvt_utf8_utf16<char16_t>::do_in(state_type&,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    const uint8_t* _frm_nxt = _frm;\n    uint16_t* _to = reinterpret_cast<uint16_t*>(to);\n    uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);\n    uint16_t* _to_nxt = _to;\n    result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                             _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf8_utf16<char16_t>::result\n__codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\n__codecvt_utf8_utf16<char16_t>::do_encoding() const  _NOEXCEPT\n{\n    return 0;\n}\n\nbool\n__codecvt_utf8_utf16<char16_t>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\n__codecvt_utf8_utf16<char16_t>::do_length(state_type&,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);\n}\n\nint\n__codecvt_utf8_utf16<char16_t>::do_max_length() const  _NOEXCEPT\n{\n    if (_Mode_ & consume_header)\n        return 7;\n    return 4;\n}\n\n// __codecvt_utf8_utf16<char32_t>\n\n__codecvt_utf8_utf16<char32_t>::result\n__codecvt_utf8_utf16<char32_t>::do_out(state_type&,\n    const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,\n    extern_type* to, extern_type* to_end, extern_type*& to_nxt) const\n{\n    const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);\n    const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);\n    const uint32_t* _frm_nxt = _frm;\n    uint8_t* _to = reinterpret_cast<uint8_t*>(to);\n    uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);\n    uint8_t* _to_nxt = _to;\n    result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                             _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf8_utf16<char32_t>::result\n__codecvt_utf8_utf16<char32_t>::do_in(state_type&,\n    const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,\n    intern_type* to, intern_type* to_end, intern_type*& to_nxt) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    const uint8_t* _frm_nxt = _frm;\n    uint32_t* _to = reinterpret_cast<uint32_t*>(to);\n    uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);\n    uint32_t* _to_nxt = _to;\n    result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,\n                             _Maxcode_, _Mode_);\n    frm_nxt = frm + (_frm_nxt - _frm);\n    to_nxt = to + (_to_nxt - _to);\n    return r;\n}\n\n__codecvt_utf8_utf16<char32_t>::result\n__codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,\n    extern_type* to, extern_type*, extern_type*& to_nxt) const\n{\n    to_nxt = to;\n    return noconv;\n}\n\nint\n__codecvt_utf8_utf16<char32_t>::do_encoding() const  _NOEXCEPT\n{\n    return 0;\n}\n\nbool\n__codecvt_utf8_utf16<char32_t>::do_always_noconv() const  _NOEXCEPT\n{\n    return false;\n}\n\nint\n__codecvt_utf8_utf16<char32_t>::do_length(state_type&,\n    const extern_type* frm, const extern_type* frm_end, size_t mx) const\n{\n    const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);\n    const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);\n    return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);\n}\n\nint\n__codecvt_utf8_utf16<char32_t>::do_max_length() const  _NOEXCEPT\n{\n    if (_Mode_ & consume_header)\n        return 7;\n    return 4;\n}\n\n// __narrow_to_utf8<16>\n\n__narrow_to_utf8<16>::~__narrow_to_utf8()\n{\n}\n\n// __narrow_to_utf8<32>\n\n__narrow_to_utf8<32>::~__narrow_to_utf8()\n{\n}\n\n// __widen_from_utf8<16>\n\n__widen_from_utf8<16>::~__widen_from_utf8()\n{\n}\n\n// __widen_from_utf8<32>\n\n__widen_from_utf8<32>::~__widen_from_utf8()\n{\n}\n\n// numpunct<char> && numpunct<wchar_t>\n\nlocale::id numpunct< char  >::id;\nlocale::id numpunct<wchar_t>::id;\n\nnumpunct<char>::numpunct(size_t refs)\n    : locale::facet(refs),\n      __decimal_point_('.'),\n      __thousands_sep_(',')\n{\n}\n\nnumpunct<wchar_t>::numpunct(size_t refs)\n    : locale::facet(refs),\n      __decimal_point_(L'.'),\n      __thousands_sep_(L',')\n{\n}\n\nnumpunct<char>::~numpunct()\n{\n}\n\nnumpunct<wchar_t>::~numpunct()\n{\n}\n\n char   numpunct< char  >::do_decimal_point() const {return __decimal_point_;}\nwchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}\n\n char   numpunct< char  >::do_thousands_sep() const {return __thousands_sep_;}\nwchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}\n\nstring numpunct< char  >::do_grouping() const {return __grouping_;}\nstring numpunct<wchar_t>::do_grouping() const {return __grouping_;}\n\n string numpunct< char  >::do_truename() const {return \"true\";}\nwstring numpunct<wchar_t>::do_truename() const {return L\"true\";}\n\n string numpunct< char  >::do_falsename() const {return \"false\";}\nwstring numpunct<wchar_t>::do_falsename() const {return L\"false\";}\n\n// numpunct_byname<char>\n\nnumpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)\n    : numpunct<char>(refs)\n{\n    __init(nm);\n}\n\nnumpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)\n    : numpunct<char>(refs)\n{\n    __init(nm.c_str());\n}\n\nnumpunct_byname<char>::~numpunct_byname()\n{\n}\n\nvoid\nnumpunct_byname<char>::__init(const char* nm)\n{\n    if (strcmp(nm, \"C\") != 0)\n    {\n        __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        if (loc == nullptr)\n            throw runtime_error(\"numpunct_byname<char>::numpunct_byname\"\n                                \" failed to construct for \" + string(nm));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        lconv* lc = localeconv_l(loc.get());\n#else\n        lconv* lc = __localeconv_l(loc.get());\n#endif\n        if (*lc->decimal_point)\n            __decimal_point_ = *lc->decimal_point;\n        if (*lc->thousands_sep)\n            __thousands_sep_ = *lc->thousands_sep;\n        __grouping_ = lc->grouping;\n        // localization for truename and falsename is not available\n    }\n}\n\n// numpunct_byname<wchar_t>\n\nnumpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)\n    : numpunct<wchar_t>(refs)\n{\n    __init(nm);\n}\n\nnumpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)\n    : numpunct<wchar_t>(refs)\n{\n    __init(nm.c_str());\n}\n\nnumpunct_byname<wchar_t>::~numpunct_byname()\n{\n}\n\nvoid\nnumpunct_byname<wchar_t>::__init(const char* nm)\n{\n    if (strcmp(nm, \"C\") != 0)\n    {\n        __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        if (loc == nullptr)\n            throw runtime_error(\"numpunct_byname<char>::numpunct_byname\"\n                                \" failed to construct for \" + string(nm));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        lconv* lc = localeconv_l(loc.get());\n#else\n        lconv* lc = __localeconv_l(loc.get());\n#endif\n        if (*lc->decimal_point)\n            __decimal_point_ = *lc->decimal_point;\n        if (*lc->thousands_sep)\n            __thousands_sep_ = *lc->thousands_sep;\n        __grouping_ = lc->grouping;\n        // locallization for truename and falsename is not available\n    }\n}\n\n// num_get helpers\n\nint\n__num_get_base::__get_base(ios_base& iob)\n{\n    ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;\n    if (__basefield == ios_base::oct)\n        return 8;\n    else if (__basefield == ios_base::hex)\n        return 16;\n    else if (__basefield == 0)\n        return 0;\n    return 10;\n}\n\nconst char __num_get_base::__src[33] = \"0123456789abcdefABCDEFxX+-pPiInN\";\n\nvoid\n__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,\n                 ios_base::iostate& __err)\n{\n    if (__grouping.size() != 0)\n    {\n        reverse(__g, __g_end);\n        const char* __ig = __grouping.data();\n        const char* __eg = __ig + __grouping.size();\n        for (unsigned* __r = __g; __r < __g_end-1; ++__r)\n        {\n            if (0 < *__ig && *__ig < numeric_limits<char>::max())\n            {\n                if (static_cast<unsigned>(*__ig) != *__r)\n                {\n                    __err = ios_base::failbit;\n                    return;\n                }\n            }\n            if (__eg - __ig > 1)\n                ++__ig;\n        }\n        if (0 < *__ig && *__ig < numeric_limits<char>::max())\n        {\n            if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)\n                __err = ios_base::failbit;\n        }\n    }\n}\n\nvoid\n__num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,\n                             ios_base::fmtflags __flags)\n{\n    if (__flags & ios_base::showpos)\n        *__fmtp++ = '+';\n    if (__flags & ios_base::showbase)\n        *__fmtp++ = '#';\n    while(*__len)\n        *__fmtp++ = *__len++;\n    if ((__flags & ios_base::basefield) == ios_base::oct)\n        *__fmtp = 'o';\n    else if ((__flags & ios_base::basefield) == ios_base::hex)\n    {\n        if (__flags & ios_base::uppercase)\n            *__fmtp = 'X';\n        else\n            *__fmtp = 'x';\n    }\n    else if (__signd)\n        *__fmtp = 'd';\n    else\n        *__fmtp = 'u';\n}\n\nbool\n__num_put_base::__format_float(char* __fmtp, const char* __len,\n                               ios_base::fmtflags __flags)\n{\n    bool specify_precision = true;\n    if (__flags & ios_base::showpos)\n        *__fmtp++ = '+';\n    if (__flags & ios_base::showpoint)\n        *__fmtp++ = '#';\n    ios_base::fmtflags floatfield = __flags & ios_base::floatfield;\n    bool uppercase = (__flags & ios_base::uppercase) != 0;\n    if (floatfield == (ios_base::fixed | ios_base::scientific))\n        specify_precision = false;\n    else\n    {\n        *__fmtp++ = '.';\n        *__fmtp++ = '*';\n    }\n    while(*__len)\n        *__fmtp++ = *__len++;\n    if (floatfield == ios_base::fixed)\n    {\n        if (uppercase)\n            *__fmtp = 'F';\n        else\n            *__fmtp = 'f';\n    }\n    else if (floatfield == ios_base::scientific)\n    {\n        if (uppercase)\n            *__fmtp = 'E';\n        else\n            *__fmtp = 'e';\n    }\n    else if (floatfield == (ios_base::fixed | ios_base::scientific))\n    {\n        if (uppercase)\n            *__fmtp = 'A';\n        else\n            *__fmtp = 'a';\n    }\n    else\n    {\n        if (uppercase)\n            *__fmtp = 'G';\n        else\n            *__fmtp = 'g';\n    }\n    return specify_precision;\n}\n\nchar*\n__num_put_base::__identify_padding(char* __nb, char* __ne,\n                                   const ios_base& __iob)\n{\n    switch (__iob.flags() & ios_base::adjustfield)\n    {\n    case ios_base::internal:\n        if (__nb[0] == '-' || __nb[0] == '+')\n            return __nb+1;\n        if (__ne - __nb >= 2 && __nb[0] == '0'\n                            && (__nb[1] == 'x' || __nb[1] == 'X'))\n            return __nb+2;\n        break;\n    case ios_base::left:\n        return __ne;\n    case ios_base::right:\n    default:\n        break;\n    }\n    return __nb;\n}\n\n// time_get\n\nstatic\nstring*\ninit_weeks()\n{\n    static string weeks[14];\n    weeks[0]  = \"Sunday\";\n    weeks[1]  = \"Monday\";\n    weeks[2]  = \"Tuesday\";\n    weeks[3]  = \"Wednesday\";\n    weeks[4]  = \"Thursday\";\n    weeks[5]  = \"Friday\";\n    weeks[6]  = \"Saturday\";\n    weeks[7]  = \"Sun\";\n    weeks[8]  = \"Mon\";\n    weeks[9]  = \"Tue\";\n    weeks[10] = \"Wed\";\n    weeks[11] = \"Thu\";\n    weeks[12] = \"Fri\";\n    weeks[13] = \"Sat\";\n    return weeks;\n}\n\nstatic\nwstring*\ninit_wweeks()\n{\n    static wstring weeks[14];\n    weeks[0]  = L\"Sunday\";\n    weeks[1]  = L\"Monday\";\n    weeks[2]  = L\"Tuesday\";\n    weeks[3]  = L\"Wednesday\";\n    weeks[4]  = L\"Thursday\";\n    weeks[5]  = L\"Friday\";\n    weeks[6]  = L\"Saturday\";\n    weeks[7]  = L\"Sun\";\n    weeks[8]  = L\"Mon\";\n    weeks[9]  = L\"Tue\";\n    weeks[10] = L\"Wed\";\n    weeks[11] = L\"Thu\";\n    weeks[12] = L\"Fri\";\n    weeks[13] = L\"Sat\";\n    return weeks;\n}\n\ntemplate <>\nconst string*\n__time_get_c_storage<char>::__weeks() const\n{\n    static const string* weeks = init_weeks();\n    return weeks;\n}\n\ntemplate <>\nconst wstring*\n__time_get_c_storage<wchar_t>::__weeks() const\n{\n    static const wstring* weeks = init_wweeks();\n    return weeks;\n}\n\nstatic\nstring*\ninit_months()\n{\n    static string months[24];\n    months[0]  = \"January\";\n    months[1]  = \"February\";\n    months[2]  = \"March\";\n    months[3]  = \"April\";\n    months[4]  = \"May\";\n    months[5]  = \"June\";\n    months[6]  = \"July\";\n    months[7]  = \"August\";\n    months[8]  = \"September\";\n    months[9]  = \"October\";\n    months[10] = \"November\";\n    months[11] = \"December\";\n    months[12] = \"Jan\";\n    months[13] = \"Feb\";\n    months[14] = \"Mar\";\n    months[15] = \"Apr\";\n    months[16] = \"May\";\n    months[17] = \"Jun\";\n    months[18] = \"Jul\";\n    months[19] = \"Aug\";\n    months[20] = \"Sep\";\n    months[21] = \"Oct\";\n    months[22] = \"Nov\";\n    months[23] = \"Dec\";\n    return months;\n}\n\nstatic\nwstring*\ninit_wmonths()\n{\n    static wstring months[24];\n    months[0]  = L\"January\";\n    months[1]  = L\"February\";\n    months[2]  = L\"March\";\n    months[3]  = L\"April\";\n    months[4]  = L\"May\";\n    months[5]  = L\"June\";\n    months[6]  = L\"July\";\n    months[7]  = L\"August\";\n    months[8]  = L\"September\";\n    months[9]  = L\"October\";\n    months[10] = L\"November\";\n    months[11] = L\"December\";\n    months[12] = L\"Jan\";\n    months[13] = L\"Feb\";\n    months[14] = L\"Mar\";\n    months[15] = L\"Apr\";\n    months[16] = L\"May\";\n    months[17] = L\"Jun\";\n    months[18] = L\"Jul\";\n    months[19] = L\"Aug\";\n    months[20] = L\"Sep\";\n    months[21] = L\"Oct\";\n    months[22] = L\"Nov\";\n    months[23] = L\"Dec\";\n    return months;\n}\n\ntemplate <>\nconst string*\n__time_get_c_storage<char>::__months() const\n{\n    static const string* months = init_months();\n    return months;\n}\n\ntemplate <>\nconst wstring*\n__time_get_c_storage<wchar_t>::__months() const\n{\n    static const wstring* months = init_wmonths();\n    return months;\n}\n\nstatic\nstring*\ninit_am_pm()\n{\n    static string am_pm[24];\n    am_pm[0]  = \"AM\";\n    am_pm[1]  = \"PM\";\n    return am_pm;\n}\n\nstatic\nwstring*\ninit_wam_pm()\n{\n    static wstring am_pm[24];\n    am_pm[0]  = L\"AM\";\n    am_pm[1]  = L\"PM\";\n    return am_pm;\n}\n\ntemplate <>\nconst string*\n__time_get_c_storage<char>::__am_pm() const\n{\n    static const string* am_pm = init_am_pm();\n    return am_pm;\n}\n\ntemplate <>\nconst wstring*\n__time_get_c_storage<wchar_t>::__am_pm() const\n{\n    static const wstring* am_pm = init_wam_pm();\n    return am_pm;\n}\n\ntemplate <>\nconst string&\n__time_get_c_storage<char>::__x() const\n{\n    static string s(\"%m/%d/%y\");\n    return s;\n}\n\ntemplate <>\nconst wstring&\n__time_get_c_storage<wchar_t>::__x() const\n{\n    static wstring s(L\"%m/%d/%y\");\n    return s;\n}\n\ntemplate <>\nconst string&\n__time_get_c_storage<char>::__X() const\n{\n    static string s(\"%H:%M:%S\");\n    return s;\n}\n\ntemplate <>\nconst wstring&\n__time_get_c_storage<wchar_t>::__X() const\n{\n    static wstring s(L\"%H:%M:%S\");\n    return s;\n}\n\ntemplate <>\nconst string&\n__time_get_c_storage<char>::__c() const\n{\n    static string s(\"%a %b %d %H:%M:%S %Y\");\n    return s;\n}\n\ntemplate <>\nconst wstring&\n__time_get_c_storage<wchar_t>::__c() const\n{\n    static wstring s(L\"%a %b %d %H:%M:%S %Y\");\n    return s;\n}\n\ntemplate <>\nconst string&\n__time_get_c_storage<char>::__r() const\n{\n    static string s(\"%I:%M:%S %p\");\n    return s;\n}\n\ntemplate <>\nconst wstring&\n__time_get_c_storage<wchar_t>::__r() const\n{\n    static wstring s(L\"%I:%M:%S %p\");\n    return s;\n}\n\n// time_get_byname\n\n__time_get::__time_get(const char* nm)\n    : __loc_(newlocale(LC_ALL_MASK, nm, 0))\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__loc_ == 0)\n        throw runtime_error(\"time_get_byname\"\n                            \" failed to construct for \" + string(nm));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\n__time_get::__time_get(const string& nm)\n    : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__loc_ == 0)\n        throw runtime_error(\"time_get_byname\"\n                            \" failed to construct for \" + nm);\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\n__time_get::~__time_get()\n{\n    freelocale(__loc_);\n}\n#if defined(__clang__)\n#pragma clang diagnostic ignored \"-Wmissing-field-initializers\"\n#endif\n#if defined(__GNUG__)\n#pragma GCC   diagnostic ignored \"-Wmissing-field-initializers\"\n#endif\n\ntemplate <>\nstring\n__time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)\n{\n    tm t = {0};\n    t.tm_sec = 59;\n    t.tm_min = 55;\n    t.tm_hour = 23;\n    t.tm_mday = 31;\n    t.tm_mon = 11;\n    t.tm_year = 161;\n    t.tm_wday = 6;\n    t.tm_yday = 364;\n    t.tm_isdst = -1;\n    char buf[100];\n    char f[3] = {0};\n    f[0] = '%';\n    f[1] = fmt;\n    size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);\n    char* bb = buf;\n    char* be = buf + n;\n    string result;\n    while (bb != be)\n    {\n        if (ct.is(ctype_base::space, *bb))\n        {\n            result.push_back(' ');\n            for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)\n                ;\n            continue;\n        }\n        char* w = bb;\n        ios_base::iostate err = ios_base::goodbit;\n        ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,\n                               ct, err, false)\n                               - this->__weeks_;\n        if (i < 14)\n        {\n            result.push_back('%');\n            if (i < 7)\n                result.push_back('A');\n            else\n                result.push_back('a');\n            bb = w;\n            continue;\n        }\n        w = bb;\n        i = __scan_keyword(w, be, this->__months_, this->__months_+24,\n                           ct, err, false)\n                           - this->__months_;\n        if (i < 24)\n        {\n            result.push_back('%');\n            if (i < 12)\n                result.push_back('B');\n            else\n                result.push_back('b');\n            if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))\n                result.back() = 'm';\n            bb = w;\n            continue;\n        }\n        if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)\n        {\n            w = bb;\n            i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,\n                               ct, err, false) - this->__am_pm_;\n            if (i < 2)\n            {\n                result.push_back('%');\n                result.push_back('p');\n                bb = w;\n                continue;\n            }\n        }\n        w = bb;\n        if (ct.is(ctype_base::digit, *bb))\n        {\n            switch(__get_up_to_n_digits(bb, be, err, ct, 4))\n            {\n            case 6:\n                result.push_back('%');\n                result.push_back('w');\n                break;\n            case 7:\n                result.push_back('%');\n                result.push_back('u');\n                break;\n            case 11:\n                result.push_back('%');\n                result.push_back('I');\n                break;\n            case 12:\n                result.push_back('%');\n                result.push_back('m');\n                break;\n            case 23:\n                result.push_back('%');\n                result.push_back('H');\n                break;\n            case 31:\n                result.push_back('%');\n                result.push_back('d');\n                break;\n            case 55:\n                result.push_back('%');\n                result.push_back('M');\n                break;\n            case 59:\n                result.push_back('%');\n                result.push_back('S');\n                break;\n            case 61:\n                result.push_back('%');\n                result.push_back('y');\n                break;\n            case 364:\n                result.push_back('%');\n                result.push_back('j');\n                break;\n            case 2061:\n                result.push_back('%');\n                result.push_back('Y');\n                break;\n            default:\n                for (; w != bb; ++w)\n                    result.push_back(*w);\n                break;\n            }\n            continue;\n        }\n        if (*bb == '%')\n        {\n            result.push_back('%');\n            result.push_back('%');\n            ++bb;\n            continue;\n        }\n        result.push_back(*bb);\n        ++bb;\n    }\n    return result;\n}\n\n#if defined(__clang__)\n#pragma clang diagnostic ignored \"-Wmissing-braces\"\n#endif\n\ntemplate <>\nwstring\n__time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)\n{\n    tm t = {0};\n    t.tm_sec = 59;\n    t.tm_min = 55;\n    t.tm_hour = 23;\n    t.tm_mday = 31;\n    t.tm_mon = 11;\n    t.tm_year = 161;\n    t.tm_wday = 6;\n    t.tm_yday = 364;\n    t.tm_isdst = -1;\n    char buf[100];\n    char f[3] = {0};\n    f[0] = '%';\n    f[1] = fmt;\n    strftime_l(buf, countof(buf), f, &t, __loc_);\n    wchar_t wbuf[100];\n    wchar_t* wbb = wbuf;\n    mbstate_t mb = {0};\n    const char* bb = buf;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    size_t j = mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);\n#else\n    size_t j = __mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);\n#endif\n    if (j == size_t(-1))\n        __throw_runtime_error(\"locale not supported\");\n    wchar_t* wbe = wbb + j;\n    wstring result;\n    while (wbb != wbe)\n    {\n        if (ct.is(ctype_base::space, *wbb))\n        {\n            result.push_back(L' ');\n            for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)\n                ;\n            continue;\n        }\n        wchar_t* w = wbb;\n        ios_base::iostate err = ios_base::goodbit;\n        ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,\n                               ct, err, false)\n                               - this->__weeks_;\n        if (i < 14)\n        {\n            result.push_back(L'%');\n            if (i < 7)\n                result.push_back(L'A');\n            else\n                result.push_back(L'a');\n            wbb = w;\n            continue;\n        }\n        w = wbb;\n        i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,\n                           ct, err, false)\n                           - this->__months_;\n        if (i < 24)\n        {\n            result.push_back(L'%');\n            if (i < 12)\n                result.push_back(L'B');\n            else\n                result.push_back(L'b');\n            if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))\n                result.back() = L'm';\n            wbb = w;\n            continue;\n        }\n        if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)\n        {\n            w = wbb;\n            i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,\n                               ct, err, false) - this->__am_pm_;\n            if (i < 2)\n            {\n                result.push_back(L'%');\n                result.push_back(L'p');\n                wbb = w;\n                continue;\n            }\n        }\n        w = wbb;\n        if (ct.is(ctype_base::digit, *wbb))\n        {\n            switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))\n            {\n            case 6:\n                result.push_back(L'%');\n                result.push_back(L'w');\n                break;\n            case 7:\n                result.push_back(L'%');\n                result.push_back(L'u');\n                break;\n            case 11:\n                result.push_back(L'%');\n                result.push_back(L'I');\n                break;\n            case 12:\n                result.push_back(L'%');\n                result.push_back(L'm');\n                break;\n            case 23:\n                result.push_back(L'%');\n                result.push_back(L'H');\n                break;\n            case 31:\n                result.push_back(L'%');\n                result.push_back(L'd');\n                break;\n            case 55:\n                result.push_back(L'%');\n                result.push_back(L'M');\n                break;\n            case 59:\n                result.push_back(L'%');\n                result.push_back(L'S');\n                break;\n            case 61:\n                result.push_back(L'%');\n                result.push_back(L'y');\n                break;\n            case 364:\n                result.push_back(L'%');\n                result.push_back(L'j');\n                break;\n            case 2061:\n                result.push_back(L'%');\n                result.push_back(L'Y');\n                break;\n            default:\n                for (; w != wbb; ++w)\n                    result.push_back(*w);\n                break;\n            }\n            continue;\n        }\n        if (ct.narrow(*wbb, 0) == '%')\n        {\n            result.push_back(L'%');\n            result.push_back(L'%');\n            ++wbb;\n            continue;\n        }\n        result.push_back(*wbb);\n        ++wbb;\n    }\n    return result;\n}\n\ntemplate <>\nvoid\n__time_get_storage<char>::init(const ctype<char>& ct)\n{\n    tm t = {0};\n    char buf[100];\n    // __weeks_\n    for (int i = 0; i < 7; ++i)\n    {\n        t.tm_wday = i;\n        strftime_l(buf, countof(buf), \"%A\", &t, __loc_);\n        __weeks_[i] = buf;\n        strftime_l(buf, countof(buf), \"%a\", &t, __loc_);\n        __weeks_[i+7] = buf;\n    }\n    // __months_\n    for (int i = 0; i < 12; ++i)\n    {\n        t.tm_mon = i;\n        strftime_l(buf, countof(buf), \"%B\", &t, __loc_);\n        __months_[i] = buf;\n        strftime_l(buf, countof(buf), \"%b\", &t, __loc_);\n        __months_[i+12] = buf;\n    }\n    // __am_pm_\n    t.tm_hour = 1;\n    strftime_l(buf, countof(buf), \"%p\", &t, __loc_);\n    __am_pm_[0] = buf;\n    t.tm_hour = 13;\n    strftime_l(buf, countof(buf), \"%p\", &t, __loc_);\n    __am_pm_[1] = buf;\n    __c_ = __analyze('c', ct);\n    __r_ = __analyze('r', ct);\n    __x_ = __analyze('x', ct);\n    __X_ = __analyze('X', ct);\n}\n\ntemplate <>\nvoid\n__time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)\n{\n    tm t = {0};\n    char buf[100];\n    wchar_t wbuf[100];\n    wchar_t* wbe;\n    mbstate_t mb = {0};\n    // __weeks_\n    for (int i = 0; i < 7; ++i)\n    {\n        t.tm_wday = i;\n        strftime_l(buf, countof(buf), \"%A\", &t, __loc_);\n        mb = mbstate_t();\n        const char* bb = buf;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);\n#else\n        size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);\n#endif\n        if (j == size_t(-1))\n            __throw_runtime_error(\"locale not supported\");\n        wbe = wbuf + j;\n        __weeks_[i].assign(wbuf, wbe);\n        strftime_l(buf, countof(buf), \"%a\", &t, __loc_);\n        mb = mbstate_t();\n        bb = buf;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);\n#else\n        j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);\n#endif\n        if (j == size_t(-1))\n            __throw_runtime_error(\"locale not supported\");\n        wbe = wbuf + j;\n        __weeks_[i+7].assign(wbuf, wbe);\n    }\n    // __months_\n    for (int i = 0; i < 12; ++i)\n    {\n        t.tm_mon = i;\n        strftime_l(buf, countof(buf), \"%B\", &t, __loc_);\n        mb = mbstate_t();\n        const char* bb = buf;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);\n#else\n        size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);\n#endif\n        if (j == size_t(-1))\n            __throw_runtime_error(\"locale not supported\");\n        wbe = wbuf + j;\n        __months_[i].assign(wbuf, wbe);\n        strftime_l(buf, countof(buf), \"%b\", &t, __loc_);\n        mb = mbstate_t();\n        bb = buf;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);\n#else\n        j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);\n#endif\n        if (j == size_t(-1))\n            __throw_runtime_error(\"locale not supported\");\n        wbe = wbuf + j;\n        __months_[i+12].assign(wbuf, wbe);\n    }\n    // __am_pm_\n    t.tm_hour = 1;\n    strftime_l(buf, countof(buf), \"%p\", &t, __loc_);\n    mb = mbstate_t();\n    const char* bb = buf;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);\n#else\n    size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);\n#endif\n    if (j == size_t(-1))\n        __throw_runtime_error(\"locale not supported\");\n    wbe = wbuf + j;\n    __am_pm_[0].assign(wbuf, wbe);\n    t.tm_hour = 13;\n    strftime_l(buf, countof(buf), \"%p\", &t, __loc_);\n    mb = mbstate_t();\n    bb = buf;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);\n#else\n    j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);\n#endif\n    if (j == size_t(-1))\n        __throw_runtime_error(\"locale not supported\");\n    wbe = wbuf + j;\n    __am_pm_[1].assign(wbuf, wbe);\n    __c_ = __analyze('c', ct);\n    __r_ = __analyze('r', ct);\n    __x_ = __analyze('x', ct);\n    __X_ = __analyze('X', ct);\n}\n\ntemplate <class CharT>\nstruct _LIBCPP_HIDDEN __time_get_temp\n    : public ctype_byname<CharT>\n{\n    explicit __time_get_temp(const char* nm)\n        : ctype_byname<CharT>(nm, 1) {}\n    explicit __time_get_temp(const string& nm)\n        : ctype_byname<CharT>(nm, 1) {}\n};\n\ntemplate <>\n__time_get_storage<char>::__time_get_storage(const char* __nm)\n    : __time_get(__nm)\n{\n    const __time_get_temp<char> ct(__nm);\n    init(ct);\n}\n\ntemplate <>\n__time_get_storage<char>::__time_get_storage(const string& __nm)\n    : __time_get(__nm)\n{\n    const __time_get_temp<char> ct(__nm);\n    init(ct);\n}\n\ntemplate <>\n__time_get_storage<wchar_t>::__time_get_storage(const char* __nm)\n    : __time_get(__nm)\n{\n    const __time_get_temp<wchar_t> ct(__nm);\n    init(ct);\n}\n\ntemplate <>\n__time_get_storage<wchar_t>::__time_get_storage(const string& __nm)\n    : __time_get(__nm)\n{\n    const __time_get_temp<wchar_t> ct(__nm);\n    init(ct);\n}\n\ntemplate <>\ntime_base::dateorder\n__time_get_storage<char>::__do_date_order() const\n{\n    unsigned i;\n    for (i = 0; i < __x_.size(); ++i)\n        if (__x_[i] == '%')\n            break;\n    ++i;\n    switch (__x_[i])\n    {\n    case 'y':\n    case 'Y':\n        for (++i; i < __x_.size(); ++i)\n            if (__x_[i] == '%')\n                break;\n        if (i == __x_.size())\n            break;\n        ++i;\n        switch (__x_[i])\n        {\n        case 'm':\n            for (++i; i < __x_.size(); ++i)\n                if (__x_[i] == '%')\n                    break;\n            if (i == __x_.size())\n                break;\n            ++i;\n            if (__x_[i] == 'd')\n                return time_base::ymd;\n            break;\n        case 'd':\n            for (++i; i < __x_.size(); ++i)\n                if (__x_[i] == '%')\n                    break;\n            if (i == __x_.size())\n                break;\n            ++i;\n            if (__x_[i] == 'm')\n                return time_base::ydm;\n            break;\n        }\n        break;\n    case 'm':\n        for (++i; i < __x_.size(); ++i)\n            if (__x_[i] == '%')\n                break;\n        if (i == __x_.size())\n            break;\n        ++i;\n        if (__x_[i] == 'd')\n        {\n            for (++i; i < __x_.size(); ++i)\n                if (__x_[i] == '%')\n                    break;\n            if (i == __x_.size())\n                break;\n            ++i;\n            if (__x_[i] == 'y' || __x_[i] == 'Y')\n                return time_base::mdy;\n            break;\n        }\n        break;\n    case 'd':\n        for (++i; i < __x_.size(); ++i)\n            if (__x_[i] == '%')\n                break;\n        if (i == __x_.size())\n            break;\n        ++i;\n        if (__x_[i] == 'm')\n        {\n            for (++i; i < __x_.size(); ++i)\n                if (__x_[i] == '%')\n                    break;\n            if (i == __x_.size())\n                break;\n            ++i;\n            if (__x_[i] == 'y' || __x_[i] == 'Y')\n                return time_base::dmy;\n            break;\n        }\n        break;\n    }\n    return time_base::no_order;\n}\n\ntemplate <>\ntime_base::dateorder\n__time_get_storage<wchar_t>::__do_date_order() const\n{\n    unsigned i;\n    for (i = 0; i < __x_.size(); ++i)\n        if (__x_[i] == L'%')\n            break;\n    ++i;\n    switch (__x_[i])\n    {\n    case L'y':\n    case L'Y':\n        for (++i; i < __x_.size(); ++i)\n            if (__x_[i] == L'%')\n                break;\n        if (i == __x_.size())\n            break;\n        ++i;\n        switch (__x_[i])\n        {\n        case L'm':\n            for (++i; i < __x_.size(); ++i)\n                if (__x_[i] == L'%')\n                    break;\n            if (i == __x_.size())\n                break;\n            ++i;\n            if (__x_[i] == L'd')\n                return time_base::ymd;\n            break;\n        case L'd':\n            for (++i; i < __x_.size(); ++i)\n                if (__x_[i] == L'%')\n                    break;\n            if (i == __x_.size())\n                break;\n            ++i;\n            if (__x_[i] == L'm')\n                return time_base::ydm;\n            break;\n        }\n        break;\n    case L'm':\n        for (++i; i < __x_.size(); ++i)\n            if (__x_[i] == L'%')\n                break;\n        if (i == __x_.size())\n            break;\n        ++i;\n        if (__x_[i] == L'd')\n        {\n            for (++i; i < __x_.size(); ++i)\n                if (__x_[i] == L'%')\n                    break;\n            if (i == __x_.size())\n                break;\n            ++i;\n            if (__x_[i] == L'y' || __x_[i] == L'Y')\n                return time_base::mdy;\n            break;\n        }\n        break;\n    case L'd':\n        for (++i; i < __x_.size(); ++i)\n            if (__x_[i] == L'%')\n                break;\n        if (i == __x_.size())\n            break;\n        ++i;\n        if (__x_[i] == L'm')\n        {\n            for (++i; i < __x_.size(); ++i)\n                if (__x_[i] == L'%')\n                    break;\n            if (i == __x_.size())\n                break;\n            ++i;\n            if (__x_[i] == L'y' || __x_[i] == L'Y')\n                return time_base::dmy;\n            break;\n        }\n        break;\n    }\n    return time_base::no_order;\n}\n\n// time_put\n\n__time_put::__time_put(const char* nm)\n    : __loc_(newlocale(LC_ALL_MASK, nm, 0))\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__loc_ == 0)\n        throw runtime_error(\"time_put_byname\"\n                            \" failed to construct for \" + string(nm));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\n__time_put::__time_put(const string& nm)\n    : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (__loc_ == 0)\n        throw runtime_error(\"time_put_byname\"\n                            \" failed to construct for \" + nm);\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\n__time_put::~__time_put()\n{\n    if (__loc_ != _LIBCPP_GET_C_LOCALE)\n        freelocale(__loc_);\n}\n\nvoid\n__time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,\n                     char __fmt, char __mod) const\n{\n    char fmt[] = {'%', __fmt, __mod, 0};\n    if (__mod != 0)\n        swap(fmt[1], fmt[2]);\n    size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);\n    __ne = __nb + n;\n}\n\nvoid\n__time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,\n                     char __fmt, char __mod) const\n{\n    char __nar[100];\n    char* __ne = __nar + 100;\n    __do_put(__nar, __ne, __tm, __fmt, __mod);\n    mbstate_t mb = {0};\n    const char* __nb = __nar;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    size_t j = mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);\n#else\n    size_t j = __mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);\n#endif\n    if (j == size_t(-1))\n        __throw_runtime_error(\"locale not supported\");\n    __we = __wb + j;\n}\n\n// moneypunct_byname\n\ntemplate <class charT>\nstatic\nvoid\n__init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,\n           bool intl, char cs_precedes, char sep_by_space, char sign_posn,\n           charT space_char)\n{\n    const char sign = static_cast<char>(money_base::sign);\n    const char space = static_cast<char>(money_base::space);\n    const char none = static_cast<char>(money_base::none);\n    const char symbol = static_cast<char>(money_base::symbol);\n    const char value = static_cast<char>(money_base::value);\n    const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;\n\n    // Comments on case branches reflect 'C11 7.11.2.1 The localeconv\n    // function'. \"Space between sign and symbol or value\" means that\n    // if the sign is adjacent to the symbol, there's a space between\n    // them, and otherwise there's a space between the sign and value.\n    //\n    // C11's localeconv specifies that the fourth character of an\n    // international curr_symbol is used to separate the sign and\n    // value when sep_by_space says to do so. C++ can't represent\n    // that, so we just use a space.  When sep_by_space says to\n    // separate the symbol and value-or-sign with a space, we rearrange the\n    // curr_symbol to put its spacing character on the correct side of\n    // the symbol.\n    //\n    // We also need to avoid adding an extra space between the sign\n    // and value when the currency symbol is suppressed (by not\n    // setting showbase).  We match glibc's strfmon by interpreting\n    // sep_by_space==1 as \"omit the space when the currency symbol is\n    // absent\".\n    //\n    // Users who want to get this right should use ICU instead.\n\n    switch (cs_precedes)\n    {\n    case 0:  // value before curr_symbol\n        if (symbol_contains_sep) {\n            // Move the separator to before the symbol, to place it\n            // between the value and symbol.\n            rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,\n                   __curr_symbol_.end());\n        }\n        switch (sign_posn)\n        {\n        case 0:  // Parentheses surround the quantity and currency symbol.\n            pat.field[0] = sign;\n            pat.field[1] = value;\n            pat.field[2] = none;  // Any space appears in the symbol.\n            pat.field[3] = symbol;\n            switch (sep_by_space)\n            {\n            case 0:  // No space separates the currency symbol and value.\n                // This case may have changed between C99 and C11;\n                // assume the currency symbol matches the intention.\n            case 2:  // Space between sign and currency or value.\n                // The \"sign\" is two parentheses, so no space here either.\n                return;\n            case 1:  // Space between currency-and-sign or currency and value.\n                if (!symbol_contains_sep) {\n                    // We insert the space into the symbol instead of\n                    // setting pat.field[2]=space so that when\n                    // showbase is not set, the space goes away too.\n                    __curr_symbol_.insert(0, 1, space_char);\n                }\n                return;\n            default:\n                break;\n            }\n            break;\n        case 1:  // The sign string precedes the quantity and currency symbol.\n            pat.field[0] = sign;\n            pat.field[3] = symbol;\n            switch (sep_by_space)\n            {\n            case 0:  // No space separates the currency symbol and value.\n                pat.field[1] = value;\n                pat.field[2] = none;\n                return;\n            case 1:  // Space between currency-and-sign or currency and value.\n                pat.field[1] = value;\n                pat.field[2] = none;\n                if (!symbol_contains_sep) {\n                    // We insert the space into the symbol instead of\n                    // setting pat.field[2]=space so that when\n                    // showbase is not set, the space goes away too.\n                    __curr_symbol_.insert(0, 1, space_char);\n                }\n                return;\n            case 2:  // Space between sign and currency or value.\n                pat.field[1] = space;\n                pat.field[2] = value;\n                if (symbol_contains_sep) {\n                    // Remove the separator from the symbol, since it\n                    // has already appeared after the sign.\n                    __curr_symbol_.erase(__curr_symbol_.begin());\n                }\n                return;\n            default:\n                break;\n            }\n            break;\n        case 2:  // The sign string succeeds the quantity and currency symbol.\n            pat.field[0] = value;\n            pat.field[3] = sign;\n            switch (sep_by_space)\n            {\n            case 0:  // No space separates the currency symbol and value.\n                pat.field[1] = none;\n                pat.field[2] = symbol;\n                return;\n            case 1:  // Space between currency-and-sign or currency and value.\n                if (!symbol_contains_sep) {\n                    // We insert the space into the symbol instead of\n                    // setting pat.field[1]=space so that when\n                    // showbase is not set, the space goes away too.\n                    __curr_symbol_.insert(0, 1, space_char);\n                }\n                pat.field[1] = none;\n                pat.field[2] = symbol;\n                return;\n            case 2:  // Space between sign and currency or value.\n                pat.field[1] = symbol;\n                pat.field[2] = space;\n                if (symbol_contains_sep) {\n                    // Remove the separator from the symbol, since it\n                    // should not be removed if showbase is absent.\n                    __curr_symbol_.erase(__curr_symbol_.begin());\n                }\n                return;\n            default:\n                break;\n            }\n            break;\n        case 3:  // The sign string immediately precedes the currency symbol.\n            pat.field[0] = value;\n            pat.field[3] = symbol;\n            switch (sep_by_space)\n            {\n            case 0:  // No space separates the currency symbol and value.\n                pat.field[1] = none;\n                pat.field[2] = sign;\n                return;\n            case 1:  // Space between currency-and-sign or currency and value.\n                pat.field[1] = space;\n                pat.field[2] = sign;\n                if (symbol_contains_sep) {\n                    // Remove the separator from the symbol, since it\n                    // has already appeared before the sign.\n                    __curr_symbol_.erase(__curr_symbol_.begin());\n                }\n                return;\n            case 2:  // Space between sign and currency or value.\n                pat.field[1] = sign;\n                pat.field[2] = none;\n                if (!symbol_contains_sep) {\n                    // We insert the space into the symbol instead of\n                    // setting pat.field[2]=space so that when\n                    // showbase is not set, the space goes away too.\n                    __curr_symbol_.insert(0, 1, space_char);\n                }\n                return;\n            default:\n                break;\n            }\n            break;\n        case 4:  // The sign string immediately succeeds the currency symbol.\n            pat.field[0] = value;\n            pat.field[3] = sign;\n            switch (sep_by_space)\n            {\n            case 0:  // No space separates the currency symbol and value.\n                pat.field[1] = none;\n                pat.field[2] = symbol;\n                return;\n            case 1:  // Space between currency-and-sign or currency and value.\n                pat.field[1] = none;\n                pat.field[2] = symbol;\n                if (!symbol_contains_sep) {\n                    // We insert the space into the symbol instead of\n                    // setting pat.field[1]=space so that when\n                    // showbase is not set, the space goes away too.\n                    __curr_symbol_.insert(0, 1, space_char);\n                }\n                return;\n            case 2:  // Space between sign and currency or value.\n                pat.field[1] = symbol;\n                pat.field[2] = space;\n                if (symbol_contains_sep) {\n                    // Remove the separator from the symbol, since it\n                    // should not disappear when showbase is absent.\n                    __curr_symbol_.erase(__curr_symbol_.begin());\n                }\n                return;\n            default:\n                break;\n            }\n            break;\n        default:\n            break;\n        }\n        break;\n    case 1:  // curr_symbol before value\n        switch (sign_posn)\n        {\n        case 0:  // Parentheses surround the quantity and currency symbol.\n            pat.field[0] = sign;\n            pat.field[1] = symbol;\n            pat.field[2] = none;  // Any space appears in the symbol.\n            pat.field[3] = value;\n            switch (sep_by_space)\n            {\n            case 0:  // No space separates the currency symbol and value.\n                // This case may have changed between C99 and C11;\n                // assume the currency symbol matches the intention.\n            case 2:  // Space between sign and currency or value.\n                // The \"sign\" is two parentheses, so no space here either.\n                return;\n            case 1:  // Space between currency-and-sign or currency and value.\n                if (!symbol_contains_sep) {\n                    // We insert the space into the symbol instead of\n                    // setting pat.field[2]=space so that when\n                    // showbase is not set, the space goes away too.\n                    __curr_symbol_.insert(0, 1, space_char);\n                }\n                return;\n            default:\n                break;\n            }\n            break;\n        case 1:  // The sign string precedes the quantity and currency symbol.\n            pat.field[0] = sign;\n            pat.field[3] = value;\n            switch (sep_by_space)\n            {\n            case 0:  // No space separates the currency symbol and value.\n                pat.field[1] = symbol;\n                pat.field[2] = none;\n                return;\n            case 1:  // Space between currency-and-sign or currency and value.\n                pat.field[1] = symbol;\n                pat.field[2] = none;\n                if (!symbol_contains_sep) {\n                    // We insert the space into the symbol instead of\n                    // setting pat.field[2]=space so that when\n                    // showbase is not set, the space goes away too.\n                    __curr_symbol_.push_back(space_char);\n                }\n                return;\n            case 2:  // Space between sign and currency or value.\n                pat.field[1] = space;\n                pat.field[2] = symbol;\n                if (symbol_contains_sep) {\n                    // Remove the separator from the symbol, since it\n                    // has already appeared after the sign.\n                    __curr_symbol_.pop_back();\n                }\n                return;\n            default:\n                break;\n            }\n            break;\n        case 2:  // The sign string succeeds the quantity and currency symbol.\n            pat.field[0] = symbol;\n            pat.field[3] = sign;\n            switch (sep_by_space)\n            {\n            case 0:  // No space separates the currency symbol and value.\n                pat.field[1] = none;\n                pat.field[2] = value;\n                return;\n            case 1:  // Space between currency-and-sign or currency and value.\n                pat.field[1] = none;\n                pat.field[2] = value;\n                if (!symbol_contains_sep) {\n                    // We insert the space into the symbol instead of\n                    // setting pat.field[1]=space so that when\n                    // showbase is not set, the space goes away too.\n                    __curr_symbol_.push_back(space_char);\n                }\n                return;\n            case 2:  // Space between sign and currency or value.\n                pat.field[1] = value;\n                pat.field[2] = space;\n                if (symbol_contains_sep) {\n                    // Remove the separator from the symbol, since it\n                    // will appear before the sign.\n                    __curr_symbol_.pop_back();\n                }\n                return;\n            default:\n                break;\n            }\n            break;\n        case 3:  // The sign string immediately precedes the currency symbol.\n            pat.field[0] = sign;\n            pat.field[3] = value;\n            switch (sep_by_space)\n            {\n            case 0:  // No space separates the currency symbol and value.\n                pat.field[1] = symbol;\n                pat.field[2] = none;\n                return;\n            case 1:  // Space between currency-and-sign or currency and value.\n                pat.field[1] = symbol;\n                pat.field[2] = none;\n                if (!symbol_contains_sep) {\n                    // We insert the space into the symbol instead of\n                    // setting pat.field[2]=space so that when\n                    // showbase is not set, the space goes away too.\n                    __curr_symbol_.push_back(space_char);\n                }\n                return;\n            case 2:  // Space between sign and currency or value.\n                pat.field[1] = space;\n                pat.field[2] = symbol;\n                if (symbol_contains_sep) {\n                    // Remove the separator from the symbol, since it\n                    // has already appeared after the sign.\n                    __curr_symbol_.pop_back();\n                }\n                return;\n            default:\n                break;\n            }\n            break;\n        case 4:  // The sign string immediately succeeds the currency symbol.\n            pat.field[0] = symbol;\n            pat.field[3] = value;\n            switch (sep_by_space)\n            {\n            case 0:  // No space separates the currency symbol and value.\n                pat.field[1] = sign;\n                pat.field[2] = none;\n                return;\n            case 1:  // Space between currency-and-sign or currency and value.\n                pat.field[1] = sign;\n                pat.field[2] = space;\n                if (symbol_contains_sep) {\n                    // Remove the separator from the symbol, since it\n                    // should not disappear when showbase is absent.\n                    __curr_symbol_.pop_back();\n                }\n                return;\n            case 2:  // Space between sign and currency or value.\n                pat.field[1] = none;\n                pat.field[2] = sign;\n                if (!symbol_contains_sep) {\n                    // We insert the space into the symbol instead of\n                    // setting pat.field[1]=space so that when\n                    // showbase is not set, the space goes away too.\n                    __curr_symbol_.push_back(space_char);\n                }\n                return;\n           default:\n                break;\n            }\n            break;\n        default:\n            break;\n        }\n        break;\n    default:\n        break;\n    }\n    pat.field[0] = symbol;\n    pat.field[1] = sign;\n    pat.field[2] = none;\n    pat.field[3] = value;\n}\n\ntemplate<>\nvoid\nmoneypunct_byname<char, false>::init(const char* nm)\n{\n    typedef moneypunct<char, false> base;\n    __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (loc == nullptr)\n        throw runtime_error(\"moneypunct_byname\"\n                            \" failed to construct for \" + string(nm));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    lconv* lc = localeconv_l(loc.get());\n#else\n    lconv* lc = __localeconv_l(loc.get());\n#endif\n    if (*lc->mon_decimal_point)\n        __decimal_point_ = *lc->mon_decimal_point;\n    else\n        __decimal_point_ = base::do_decimal_point();\n    if (*lc->mon_thousands_sep)\n        __thousands_sep_ = *lc->mon_thousands_sep;\n    else\n        __thousands_sep_ = base::do_thousands_sep();\n    __grouping_ = lc->mon_grouping;\n    __curr_symbol_ = lc->currency_symbol;\n    if (lc->frac_digits != CHAR_MAX)\n        __frac_digits_ = lc->frac_digits;\n    else\n        __frac_digits_ = base::do_frac_digits();\n    if (lc->p_sign_posn == 0)\n        __positive_sign_ = \"()\";\n    else\n        __positive_sign_ = lc->positive_sign;\n    if (lc->n_sign_posn == 0)\n        __negative_sign_ = \"()\";\n    else\n        __negative_sign_ = lc->negative_sign;\n    // Assume the positive and negative formats will want spaces in\n    // the same places in curr_symbol since there's no way to\n    // represent anything else.\n    string_type __dummy_curr_symbol = __curr_symbol_;\n    __init_pat(__pos_format_, __dummy_curr_symbol, false,\n               lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');\n    __init_pat(__neg_format_, __curr_symbol_, false,\n               lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');\n}\n\ntemplate<>\nvoid\nmoneypunct_byname<char, true>::init(const char* nm)\n{\n    typedef moneypunct<char, true> base;\n    __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (loc == nullptr)\n        throw runtime_error(\"moneypunct_byname\"\n                            \" failed to construct for \" + string(nm));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    lconv* lc = localeconv_l(loc.get());\n#else\n    lconv* lc = __localeconv_l(loc.get());\n#endif\n    if (*lc->mon_decimal_point)\n        __decimal_point_ = *lc->mon_decimal_point;\n    else\n        __decimal_point_ = base::do_decimal_point();\n    if (*lc->mon_thousands_sep)\n        __thousands_sep_ = *lc->mon_thousands_sep;\n    else\n        __thousands_sep_ = base::do_thousands_sep();\n    __grouping_ = lc->mon_grouping;\n    __curr_symbol_ = lc->int_curr_symbol;\n    if (lc->int_frac_digits != CHAR_MAX)\n        __frac_digits_ = lc->int_frac_digits;\n    else\n        __frac_digits_ = base::do_frac_digits();\n#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)\n    if (lc->p_sign_posn == 0)\n#else // _LIBCPP_MSVCRT\n    if (lc->int_p_sign_posn == 0)\n#endif // !_LIBCPP_MSVCRT\n        __positive_sign_ = \"()\";\n    else\n        __positive_sign_ = lc->positive_sign;\n#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)\n    if(lc->n_sign_posn == 0)\n#else // _LIBCPP_MSVCRT\n    if (lc->int_n_sign_posn == 0)\n#endif // !_LIBCPP_MSVCRT\n        __negative_sign_ = \"()\";\n    else\n        __negative_sign_ = lc->negative_sign;\n    // Assume the positive and negative formats will want spaces in\n    // the same places in curr_symbol since there's no way to\n    // represent anything else.\n    string_type __dummy_curr_symbol = __curr_symbol_;\n#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)\n    __init_pat(__pos_format_, __dummy_curr_symbol, true,\n               lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');\n    __init_pat(__neg_format_, __curr_symbol_, true,\n               lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');\n#else // _LIBCPP_MSVCRT\n    __init_pat(__pos_format_, __dummy_curr_symbol, true,\n               lc->int_p_cs_precedes, lc->int_p_sep_by_space,\n               lc->int_p_sign_posn, ' ');\n    __init_pat(__neg_format_, __curr_symbol_, true,\n               lc->int_n_cs_precedes, lc->int_n_sep_by_space,\n               lc->int_n_sign_posn, ' ');\n#endif // !_LIBCPP_MSVCRT\n}\n\ntemplate<>\nvoid\nmoneypunct_byname<wchar_t, false>::init(const char* nm)\n{\n    typedef moneypunct<wchar_t, false> base;\n    __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (loc == nullptr)\n        throw runtime_error(\"moneypunct_byname\"\n                            \" failed to construct for \" + string(nm));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    lconv* lc = localeconv_l(loc.get());\n#else\n    lconv* lc = __localeconv_l(loc.get());\n#endif\n    if (*lc->mon_decimal_point)\n        __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);\n    else\n        __decimal_point_ = base::do_decimal_point();\n    if (*lc->mon_thousands_sep)\n        __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);\n    else\n        __thousands_sep_ = base::do_thousands_sep();\n    __grouping_ = lc->mon_grouping;\n    wchar_t wbuf[100];\n    mbstate_t mb = {0};\n    const char* bb = lc->currency_symbol;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());\n#else\n    size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());\n#endif\n    if (j == size_t(-1))\n        __throw_runtime_error(\"locale not supported\");\n    wchar_t* wbe = wbuf + j;\n    __curr_symbol_.assign(wbuf, wbe);\n    if (lc->frac_digits != CHAR_MAX)\n        __frac_digits_ = lc->frac_digits;\n    else\n        __frac_digits_ = base::do_frac_digits();\n    if (lc->p_sign_posn == 0)\n        __positive_sign_ = L\"()\";\n    else\n    {\n        mb = mbstate_t();\n        bb = lc->positive_sign;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());\n#else\n        j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());\n#endif\n        if (j == size_t(-1))\n            __throw_runtime_error(\"locale not supported\");\n        wbe = wbuf + j;\n        __positive_sign_.assign(wbuf, wbe);\n    }\n    if (lc->n_sign_posn == 0)\n        __negative_sign_ = L\"()\";\n    else\n    {\n        mb = mbstate_t();\n        bb = lc->negative_sign;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());\n#else\n        j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());\n#endif\n        if (j == size_t(-1))\n            __throw_runtime_error(\"locale not supported\");\n        wbe = wbuf + j;\n        __negative_sign_.assign(wbuf, wbe);\n    }\n    // Assume the positive and negative formats will want spaces in\n    // the same places in curr_symbol since there's no way to\n    // represent anything else.\n    string_type __dummy_curr_symbol = __curr_symbol_;\n    __init_pat(__pos_format_, __dummy_curr_symbol, false,\n               lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');\n    __init_pat(__neg_format_, __curr_symbol_, false,\n               lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');\n}\n\ntemplate<>\nvoid\nmoneypunct_byname<wchar_t, true>::init(const char* nm)\n{\n    typedef moneypunct<wchar_t, true> base;\n    __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (loc == nullptr)\n        throw runtime_error(\"moneypunct_byname\"\n                            \" failed to construct for \" + string(nm));\n#endif  // _LIBCPP_NO_EXCEPTIONS\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    lconv* lc = localeconv_l(loc.get());\n#else\n    lconv* lc = __localeconv_l(loc.get());\n#endif\n    if (*lc->mon_decimal_point)\n        __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);\n    else\n        __decimal_point_ = base::do_decimal_point();\n    if (*lc->mon_thousands_sep)\n        __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);\n    else\n        __thousands_sep_ = base::do_thousands_sep();\n    __grouping_ = lc->mon_grouping;\n    wchar_t wbuf[100];\n    mbstate_t mb = {0};\n    const char* bb = lc->int_curr_symbol;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n    size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());\n#else\n    size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());\n#endif\n    if (j == size_t(-1))\n        __throw_runtime_error(\"locale not supported\");\n    wchar_t* wbe = wbuf + j;\n    __curr_symbol_.assign(wbuf, wbe);\n    if (lc->int_frac_digits != CHAR_MAX)\n        __frac_digits_ = lc->int_frac_digits;\n    else\n        __frac_digits_ = base::do_frac_digits();\n#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)\n    if (lc->p_sign_posn == 0)\n#else // _LIBCPP_MSVCRT\n    if (lc->int_p_sign_posn == 0)\n#endif // !_LIBCPP_MSVCRT\n        __positive_sign_ = L\"()\";\n    else\n    {\n        mb = mbstate_t();\n        bb = lc->positive_sign;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());\n#else\n        j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());\n#endif\n        if (j == size_t(-1))\n            __throw_runtime_error(\"locale not supported\");\n        wbe = wbuf + j;\n        __positive_sign_.assign(wbuf, wbe);\n    }\n#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)\n    if (lc->n_sign_posn == 0)\n#else // _LIBCPP_MSVCRT\n    if (lc->int_n_sign_posn == 0)\n#endif // !_LIBCPP_MSVCRT\n        __negative_sign_ = L\"()\";\n    else\n    {\n        mb = mbstate_t();\n        bb = lc->negative_sign;\n#ifdef _LIBCPP_LOCALE__L_EXTENSIONS\n        j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());\n#else\n        j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());\n#endif\n        if (j == size_t(-1))\n            __throw_runtime_error(\"locale not supported\");\n        wbe = wbuf + j;\n        __negative_sign_.assign(wbuf, wbe);\n    }\n    // Assume the positive and negative formats will want spaces in\n    // the same places in curr_symbol since there's no way to\n    // represent anything else.\n    string_type __dummy_curr_symbol = __curr_symbol_;\n#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)\n    __init_pat(__pos_format_, __dummy_curr_symbol, true,\n               lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');\n    __init_pat(__neg_format_, __curr_symbol_, true,\n               lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');\n#else // _LIBCPP_MSVCRT\n    __init_pat(__pos_format_, __dummy_curr_symbol, true,\n               lc->int_p_cs_precedes, lc->int_p_sep_by_space,\n               lc->int_p_sign_posn, L' ');\n    __init_pat(__neg_format_, __curr_symbol_, true,\n               lc->int_n_cs_precedes, lc->int_n_sep_by_space,\n               lc->int_n_sign_posn, L' ');\n#endif // !_LIBCPP_MSVCRT\n}\n\nvoid __do_nothing(void*) {}\n\nvoid __throw_runtime_error(const char* msg)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    throw runtime_error(msg);\n#else\n    (void)msg;\n#endif\n}\n\ntemplate class collate<char>;\ntemplate class collate<wchar_t>;\n\ntemplate class num_get<char>;\ntemplate class num_get<wchar_t>;\n\ntemplate struct __num_get<char>;\ntemplate struct __num_get<wchar_t>;\n\ntemplate class num_put<char>;\ntemplate class num_put<wchar_t>;\n\ntemplate struct __num_put<char>;\ntemplate struct __num_put<wchar_t>;\n\ntemplate class time_get<char>;\ntemplate class time_get<wchar_t>;\n\ntemplate class time_get_byname<char>;\ntemplate class time_get_byname<wchar_t>;\n\ntemplate class time_put<char>;\ntemplate class time_put<wchar_t>;\n\ntemplate class time_put_byname<char>;\ntemplate class time_put_byname<wchar_t>;\n\ntemplate class moneypunct<char, false>;\ntemplate class moneypunct<char, true>;\ntemplate class moneypunct<wchar_t, false>;\ntemplate class moneypunct<wchar_t, true>;\n\ntemplate class moneypunct_byname<char, false>;\ntemplate class moneypunct_byname<char, true>;\ntemplate class moneypunct_byname<wchar_t, false>;\ntemplate class moneypunct_byname<wchar_t, true>;\n\ntemplate class money_get<char>;\ntemplate class money_get<wchar_t>;\n\ntemplate class __money_get<char>;\ntemplate class __money_get<wchar_t>;\n\ntemplate class money_put<char>;\ntemplate class money_put<wchar_t>;\n\ntemplate class __money_put<char>;\ntemplate class __money_put<wchar_t>;\n\ntemplate class messages<char>;\ntemplate class messages<wchar_t>;\n\ntemplate class messages_byname<char>;\ntemplate class messages_byname<wchar_t>;\n\ntemplate class codecvt_byname<char, char, mbstate_t>;\ntemplate class codecvt_byname<wchar_t, char, mbstate_t>;\ntemplate class codecvt_byname<char16_t, char, mbstate_t>;\ntemplate class codecvt_byname<char32_t, char, mbstate_t>;\n\ntemplate class __vector_base_common<true>;\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/memory.cpp",
    "content": "//===------------------------ memory.cpp ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define _LIBCPP_BUILDING_MEMORY\n#include \"memory\"\n#ifndef _LIBCPP_HAS_NO_THREADS\n#include \"mutex\"\n#include \"thread\"\n#endif\n#include \"support/atomic_support.h\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nnamespace\n{\n\n// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)\n// should be sufficient for thread safety.\n// See https://llvm.org/bugs/show_bug.cgi?id=22803\ntemplate <class T>\ninline T\nincrement(T& t) _NOEXCEPT\n{\n    return __libcpp_atomic_add(&t, 1, _AO_Relaxed);\n}\n\ntemplate <class T>\ninline T\ndecrement(T& t) _NOEXCEPT\n{\n    return __libcpp_atomic_add(&t, -1, _AO_Acq_Rel);\n}\n\n}  // namespace\n\nconst allocator_arg_t allocator_arg = allocator_arg_t();\n\nbad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {}\n\nconst char*\nbad_weak_ptr::what() const _NOEXCEPT\n{\n    return \"bad_weak_ptr\";\n}\n\n__shared_count::~__shared_count()\n{\n}\n\nvoid\n__shared_count::__add_shared() _NOEXCEPT\n{\n    increment(__shared_owners_);\n}\n\nbool\n__shared_count::__release_shared() _NOEXCEPT\n{\n    if (decrement(__shared_owners_) == -1)\n    {\n        __on_zero_shared();\n        return true;\n    }\n    return false;\n}\n\n__shared_weak_count::~__shared_weak_count()\n{\n}\n\nvoid\n__shared_weak_count::__add_shared() _NOEXCEPT\n{\n    __shared_count::__add_shared();\n}\n\nvoid\n__shared_weak_count::__add_weak() _NOEXCEPT\n{\n    increment(__shared_weak_owners_);\n}\n\nvoid\n__shared_weak_count::__release_shared() _NOEXCEPT\n{\n    if (__shared_count::__release_shared())\n        __release_weak();\n}\n\nvoid\n__shared_weak_count::__release_weak() _NOEXCEPT\n{\n    if (decrement(__shared_weak_owners_) == -1)\n        __on_zero_shared_weak();\n}\n\n__shared_weak_count*\n__shared_weak_count::lock() _NOEXCEPT\n{\n    long object_owners = __libcpp_atomic_load(&__shared_owners_);\n    while (object_owners != -1)\n    {\n        if (__libcpp_atomic_compare_exchange(&__shared_owners_,\n                                             &object_owners,\n                                             object_owners+1))\n            return this;\n    }\n    return 0;\n}\n\n#if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC)\n\nconst void*\n__shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT\n{\n    return 0;\n}\n\n#endif  // _LIBCPP_NO_RTTI\n\n#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)\n\nstatic const std::size_t __sp_mut_count = 16;\nstatic pthread_mutex_t mut_back_imp[__sp_mut_count] =\n{\n    PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,\n    PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,\n    PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,\n    PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER\n};\n\nstatic mutex* mut_back = reinterpret_cast<std::mutex*>(mut_back_imp);\n\n_LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT\n   : __lx(p)\n{\n}\n\nvoid\n__sp_mut::lock() _NOEXCEPT\n{\n    mutex& m = *static_cast<mutex*>(__lx);\n    unsigned count = 0;\n    while (!m.try_lock())\n    {\n        if (++count > 16)\n        {\n            m.lock();\n            break;\n        }\n        this_thread::yield();\n    }\n}\n\nvoid\n__sp_mut::unlock() _NOEXCEPT\n{\n    static_cast<mutex*>(__lx)->unlock();\n}\n\n__sp_mut&\n__get_sp_mut(const void* p)\n{\n    static __sp_mut muts[__sp_mut_count] \n    {\n        &mut_back[ 0], &mut_back[ 1], &mut_back[ 2], &mut_back[ 3],\n        &mut_back[ 4], &mut_back[ 5], &mut_back[ 6], &mut_back[ 7],\n        &mut_back[ 8], &mut_back[ 9], &mut_back[10], &mut_back[11],\n        &mut_back[12], &mut_back[13], &mut_back[14], &mut_back[15]\n    };\n    return muts[hash<const void*>()(p) & (__sp_mut_count-1)];\n}\n\n#endif // __has_feature(cxx_atomic) && !_LIBCPP_HAS_NO_THREADS\n\nvoid\ndeclare_reachable(void*)\n{\n}\n\nvoid\ndeclare_no_pointers(char*, size_t)\n{\n}\n\nvoid\nundeclare_no_pointers(char*, size_t)\n{\n}\n\npointer_safety\nget_pointer_safety() _NOEXCEPT\n{\n    return pointer_safety::relaxed;\n}\n\nvoid*\n__undeclare_reachable(void* p)\n{\n    return p;\n}\n\nvoid*\nalign(size_t alignment, size_t size, void*& ptr, size_t& space)\n{\n    void* r = nullptr;\n    if (size <= space)\n    {\n        char* p1 = static_cast<char*>(ptr);\n        char* p2 = reinterpret_cast<char*>(reinterpret_cast<size_t>(p1 + (alignment - 1)) & -alignment);\n        size_t d = static_cast<size_t>(p2 - p1);\n        if (d <= space - size)\n        {\n            r = p2;\n            ptr = r;\n            space -= d;\n        }\n    }\n    return r;\n}\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/mutex.cpp",
    "content": "//===------------------------- mutex.cpp ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define _LIBCPP_BUILDING_MUTEX\n#include \"mutex\"\n#include \"limits\"\n#include \"system_error\"\n#include \"cassert\"\n#include \"support/atomic_support.h\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n#ifndef _LIBCPP_HAS_NO_THREADS\n\nconst defer_lock_t  defer_lock = {};\nconst try_to_lock_t try_to_lock = {};\nconst adopt_lock_t  adopt_lock = {};\n\nmutex::~mutex()\n{\n    pthread_mutex_destroy(&__m_);\n}\n\nvoid\nmutex::lock()\n{\n    int ec = pthread_mutex_lock(&__m_);\n    if (ec)\n        __throw_system_error(ec, \"mutex lock failed\");\n}\n\nbool\nmutex::try_lock() _NOEXCEPT\n{\n    return pthread_mutex_trylock(&__m_) == 0;\n}\n\nvoid\nmutex::unlock() _NOEXCEPT\n{\n    int ec = pthread_mutex_unlock(&__m_);\n    (void)ec;\n    assert(ec == 0);\n}\n\n// recursive_mutex\n\nrecursive_mutex::recursive_mutex()\n{\n    pthread_mutexattr_t attr;\n    int ec = pthread_mutexattr_init(&attr);\n    if (ec)\n        goto fail;\n    ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);\n    if (ec)\n    {\n        pthread_mutexattr_destroy(&attr);\n        goto fail;\n    }\n    ec = pthread_mutex_init(&__m_, &attr);\n    if (ec)\n    {\n        pthread_mutexattr_destroy(&attr);\n        goto fail;\n    }\n    ec = pthread_mutexattr_destroy(&attr);\n    if (ec)\n    {\n        pthread_mutex_destroy(&__m_);\n        goto fail;\n    }\n    return;\nfail:\n    __throw_system_error(ec, \"recursive_mutex constructor failed\");\n}\n\nrecursive_mutex::~recursive_mutex()\n{\n    int e = pthread_mutex_destroy(&__m_);\n    (void)e;\n    assert(e == 0);\n}\n\nvoid\nrecursive_mutex::lock()\n{\n    int ec = pthread_mutex_lock(&__m_);\n    if (ec)\n        __throw_system_error(ec, \"recursive_mutex lock failed\");\n}\n\nvoid\nrecursive_mutex::unlock() _NOEXCEPT\n{\n    int e = pthread_mutex_unlock(&__m_);\n    (void)e;\n    assert(e == 0);\n}\n\nbool\nrecursive_mutex::try_lock() _NOEXCEPT\n{\n    return pthread_mutex_trylock(&__m_) == 0;\n}\n\n// timed_mutex\n\ntimed_mutex::timed_mutex()\n    : __locked_(false)\n{\n}\n\ntimed_mutex::~timed_mutex()\n{\n    lock_guard<mutex> _(__m_);\n}\n\nvoid\ntimed_mutex::lock()\n{\n    unique_lock<mutex> lk(__m_);\n    while (__locked_)\n        __cv_.wait(lk);\n    __locked_ = true;\n}\n\nbool\ntimed_mutex::try_lock() _NOEXCEPT\n{\n    unique_lock<mutex> lk(__m_, try_to_lock);\n    if (lk.owns_lock() && !__locked_)\n    {\n        __locked_ = true;\n        return true;\n    }\n    return false;\n}\n\nvoid\ntimed_mutex::unlock() _NOEXCEPT\n{\n    lock_guard<mutex> _(__m_);\n    __locked_ = false;\n    __cv_.notify_one();\n}\n\n// recursive_timed_mutex\n\nrecursive_timed_mutex::recursive_timed_mutex()\n    : __count_(0),\n      __id_(0)\n{\n}\n\nrecursive_timed_mutex::~recursive_timed_mutex()\n{\n    lock_guard<mutex> _(__m_);\n}\n\nvoid\nrecursive_timed_mutex::lock()\n{\n    pthread_t id = pthread_self();\n    unique_lock<mutex> lk(__m_);\n    if (pthread_equal(id, __id_))\n    {\n        if (__count_ == numeric_limits<size_t>::max())\n            __throw_system_error(EAGAIN, \"recursive_timed_mutex lock limit reached\");\n        ++__count_;\n        return;\n    }\n    while (__count_ != 0)\n        __cv_.wait(lk);\n    __count_ = 1;\n    __id_ = id;\n}\n\nbool\nrecursive_timed_mutex::try_lock() _NOEXCEPT\n{\n    pthread_t id = pthread_self();\n    unique_lock<mutex> lk(__m_, try_to_lock);\n    if (lk.owns_lock() && (__count_ == 0 || pthread_equal(id, __id_)))\n    {\n        if (__count_ == numeric_limits<size_t>::max())\n            return false;\n        ++__count_;\n        __id_ = id;\n        return true;\n    }\n    return false;\n}\n\nvoid\nrecursive_timed_mutex::unlock() _NOEXCEPT\n{\n    unique_lock<mutex> lk(__m_);\n    if (--__count_ == 0)\n    {\n        __id_ = 0;\n        lk.unlock();\n        __cv_.notify_one();\n    }\n}\n\n#endif // !_LIBCPP_HAS_NO_THREADS\n\n// If dispatch_once_f ever handles C++ exceptions, and if one can get to it\n// without illegal macros (unexpected macros not beginning with _UpperCase or\n// __lowercase), and if it stops spinning waiting threads, then call_once should\n// call into dispatch_once_f instead of here. Relevant radar this code needs to\n// keep in sync with:  7741191.\n\n#ifndef _LIBCPP_HAS_NO_THREADS\nstatic pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;\nstatic pthread_cond_t  cv  = PTHREAD_COND_INITIALIZER;\n#endif\n\n/// NOTE: Changes to flag are done via relaxed atomic stores\n///       even though the accesses are protected by a mutex because threads\n///       just entering 'call_once` concurrently read from flag.\nvoid\n__call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))\n{\n#if defined(_LIBCPP_HAS_NO_THREADS)\n    if (flag == 0)\n    {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            flag = 1;\n            func(arg);\n            flag = ~0ul;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            flag = 0ul;\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n#else // !_LIBCPP_HAS_NO_THREADS\n    pthread_mutex_lock(&mut);\n    while (flag == 1)\n        pthread_cond_wait(&cv, &mut);\n    if (flag == 0)\n    {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        try\n        {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n            __libcpp_relaxed_store(&flag, 1ul);\n            pthread_mutex_unlock(&mut);\n            func(arg);\n            pthread_mutex_lock(&mut);\n            __libcpp_relaxed_store(&flag, ~0ul);\n            pthread_mutex_unlock(&mut);\n            pthread_cond_broadcast(&cv);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n        }\n        catch (...)\n        {\n            pthread_mutex_lock(&mut);\n            __libcpp_relaxed_store(&flag, 0ul);\n            pthread_mutex_unlock(&mut);\n            pthread_cond_broadcast(&cv);\n            throw;\n        }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    }\n    else\n        pthread_mutex_unlock(&mut);\n#endif // !_LIBCPP_HAS_NO_THREADS\n\n}\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/new.cpp",
    "content": "//===--------------------------- new.cpp ----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define _LIBCPP_BUILDING_NEW\n\n#include <stdlib.h>\n\n#include \"new\"\n\n#ifndef __has_include\n#define __has_include(inc) 0\n#endif\n\n#if defined(__APPLE__) && !defined(LIBCXXRT)\n    #include <cxxabi.h>\n\n    #ifndef _LIBCPPABI_VERSION\n        // On Darwin, there are two STL shared libraries and a lower level ABI\n        // shared library.  The global holding the current new handler is\n        // in the ABI library and named __cxa_new_handler.\n        #define __new_handler __cxxabiapple::__cxa_new_handler\n    #endif\n#else  // __APPLE__\n    #if defined(LIBCXXRT) || __has_include(<cxxabi.h>)\n        #include <cxxabi.h>\n    #endif  // __has_include(<cxxabi.h>)\n    #if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)\n        static std::new_handler __new_handler;\n    #endif  // _LIBCPPABI_VERSION\n#endif\n\n#ifndef __GLIBCXX__\n\n// Implement all new and delete operators as weak definitions\n// in this shared library, so that they can be overriden by programs\n// that define non-weak copies of the functions.\n\n_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS\nvoid *\noperator new(std::size_t size)\n#if !__has_feature(cxx_noexcept)\n    throw(std::bad_alloc)\n#endif\n{\n    if (size == 0)\n        size = 1;\n    void* p;\n    while ((p = ::malloc(size)) == 0)\n    {\n        // If malloc fails and there is a new_handler,\n        // call it to try free up memory.\n        std::new_handler nh = std::get_new_handler();\n        if (nh)\n            nh();\n        else\n#ifndef _LIBCPP_NO_EXCEPTIONS\n            throw std::bad_alloc();\n#else\n            break;\n#endif\n    }\n    return p;\n}\n\n_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS\nvoid*\noperator new(size_t size, const std::nothrow_t&) _NOEXCEPT\n{\n    void* p = 0;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        p = ::operator new(size);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return p;\n}\n\n_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS\nvoid*\noperator new[](size_t size)\n#if !__has_feature(cxx_noexcept)\n    throw(std::bad_alloc)\n#endif\n{\n    return ::operator new(size);\n}\n\n_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS\nvoid*\noperator new[](size_t size, const std::nothrow_t&) _NOEXCEPT\n{\n    void* p = 0;\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    try\n    {\n#endif  // _LIBCPP_NO_EXCEPTIONS\n        p = ::operator new[](size);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    }\n    catch (...)\n    {\n    }\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    return p;\n}\n\n_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS\nvoid\noperator delete(void* ptr) _NOEXCEPT\n{\n    if (ptr)\n        ::free(ptr);\n}\n\n_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS\nvoid\noperator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT\n{\n    ::operator delete(ptr);\n}\n\n_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS\nvoid\noperator delete(void* ptr, size_t) _NOEXCEPT\n{\n    ::operator delete(ptr);\n}\n\n_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS\nvoid\noperator delete[] (void* ptr) _NOEXCEPT\n{\n    ::operator delete(ptr);\n}\n\n_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS\nvoid\noperator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT\n{\n    ::operator delete[](ptr);\n}\n\n_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS\nvoid\noperator delete[] (void* ptr, size_t) _NOEXCEPT\n{\n    ::operator delete[](ptr);\n}\n\n#endif // !__GLIBCXX__\n\nnamespace std\n{\n\n#ifndef __GLIBCXX__\nconst nothrow_t nothrow = {};\n#endif\n\n#ifndef _LIBCPPABI_VERSION\n\n#ifndef __GLIBCXX__\n\nnew_handler\nset_new_handler(new_handler handler) _NOEXCEPT\n{\n    return __sync_lock_test_and_set(&__new_handler, handler);\n}\n\nnew_handler\nget_new_handler() _NOEXCEPT\n{\n    return __sync_fetch_and_add(&__new_handler, nullptr);\n}\n\n#endif // !__GLIBCXX__\n\n#ifndef LIBCXXRT\n\nbad_alloc::bad_alloc() _NOEXCEPT\n{\n}\n\n#ifndef __GLIBCXX__\n\nbad_alloc::~bad_alloc() _NOEXCEPT\n{\n}\n\nconst char*\nbad_alloc::what() const _NOEXCEPT\n{\n    return \"std::bad_alloc\";\n}\n\n#endif // !__GLIBCXX__\n\nbad_array_new_length::bad_array_new_length() _NOEXCEPT\n{\n}\n\nbad_array_new_length::~bad_array_new_length() _NOEXCEPT\n{\n}\n\nconst char*\nbad_array_new_length::what() const _NOEXCEPT\n{\n    return \"bad_array_new_length\";\n}\n\n#endif //LIBCXXRT\n\nconst char*\nbad_array_length::what() const _NOEXCEPT\n{\n    return \"bad_array_length\";\n}\n\nbad_array_length::bad_array_length() _NOEXCEPT\n{\n}\n\nbad_array_length::~bad_array_length() _NOEXCEPT\n{\n}\n\n#endif // _LIBCPPABI_VERSION\n\n#ifndef LIBSTDCXX\n\nvoid\n__throw_bad_alloc()\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    throw bad_alloc();\n#endif\n}\n\n#endif // !LIBSTDCXX\n\n}  // std\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/optional.cpp",
    "content": "//===------------------------ optional.cpp --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"experimental/optional\"\n\n_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL\n\n#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS\n\nbad_optional_access::~bad_optional_access() _NOEXCEPT {}\n\n#else\n\nbad_optional_access::~bad_optional_access() _NOEXCEPT = default;\n\n#endif\n\n_LIBCPP_END_NAMESPACE_EXPERIMENTAL\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/random.cpp",
    "content": "//===-------------------------- random.cpp --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#if defined(_LIBCPP_USING_WIN32_RANDOM)\n// Must be defined before including stdlib.h to enable rand_s().\n#define _CRT_RAND_S\n#endif // defined(_LIBCPP_USING_WIN32_RANDOM)\n\n#include \"random\"\n#include \"system_error\"\n\n#if defined(__sun__)\n#define rename solaris_headers_are_broken\n#endif // defined(__sun__)\n\n#include <errno.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#if defined(_LIBCPP_USING_DEV_RANDOM)\n#include <fcntl.h>\n#include <unistd.h>\n#elif defined(_LIBCPP_USING_NACL_RANDOM)\n#include <nacl/nacl_random.h>\n#endif\n\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n#if defined(_LIBCPP_USING_ARC4_RANDOM)\n\nrandom_device::random_device(const string& __token)\n{\n    if (__token != \"/dev/urandom\")\n        __throw_system_error(ENOENT, (\"random device not supported \" + __token).c_str());\n}\n\nrandom_device::~random_device()\n{\n}\n\nunsigned\nrandom_device::operator()()\n{\n    return arc4random();\n}\n\n#elif defined(_LIBCPP_USING_DEV_RANDOM)\n\nrandom_device::random_device(const string& __token)\n    : __f_(open(__token.c_str(), O_RDONLY))\n{\n    if (__f_ < 0)\n        __throw_system_error(errno, (\"random_device failed to open \" + __token).c_str());\n}\n\nrandom_device::~random_device()\n{\n    close(__f_);\n}\n\nunsigned\nrandom_device::operator()()\n{\n    unsigned r;\n    size_t n = sizeof(r);\n    char* p = reinterpret_cast<char*>(&r);\n    while (n > 0)\n    {\n        ssize_t s = read(__f_, p, n);\n        if (s == 0)\n            __throw_system_error(ENODATA, \"random_device got EOF\");\n        if (s == -1)\n        {\n            if (errno != EINTR)\n                __throw_system_error(errno, \"random_device got an unexpected error\");\n            continue;\n        }\n        n -= static_cast<size_t>(s);\n        p += static_cast<size_t>(s);\n    }\n    return r;\n}\n\n#elif defined(_LIBCPP_USING_NACL_RANDOM)\n\nrandom_device::random_device(const string& __token)\n{\n    if (__token != \"/dev/urandom\")\n        __throw_system_error(ENOENT, (\"random device not supported \" + __token).c_str());\n    int error = nacl_secure_random_init();\n    if (error)\n        __throw_system_error(error, (\"random device failed to open \" + __token).c_str());\n}\n\nrandom_device::~random_device()\n{\n}\n\nunsigned\nrandom_device::operator()()\n{\n    unsigned r;\n    size_t n = sizeof(r);\n    size_t bytes_written;\n    int error = nacl_secure_random(&r, n, &bytes_written);\n    if (error != 0)\n        __throw_system_error(error, \"random_device failed getting bytes\");\n    else if (bytes_written != n)\n        __throw_runtime_error(\"random_device failed to obtain enough bytes\");\n    return r;\n}\n\n#elif defined(_LIBCPP_USING_WIN32_RANDOM)\n\nrandom_device::random_device(const string& __token)\n{\n    if (__token != \"/dev/urandom\")\n        __throw_system_error(ENOENT, (\"random device not supported \" + __token).c_str());\n}\n\nrandom_device::~random_device()\n{\n}\n\nunsigned\nrandom_device::operator()()\n{\n    unsigned r;\n    errno_t err = rand_s(&r);\n    if (err)\n        __throw_system_error(err, \"random_device rand_s failed.\");\n    return r;\n}\n\n#else\n#error \"Random device not implemented for this architecture\"\n#endif\n\ndouble\nrandom_device::entropy() const _NOEXCEPT\n{\n    return 0;\n}\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/regex.cpp",
    "content": "//===-------------------------- regex.cpp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"regex\"\n#include \"algorithm\"\n#include \"iterator\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nstatic\nconst char*\nmake_error_type_string(regex_constants::error_type ecode)\n{\n    switch (ecode)\n    {\n    case regex_constants::error_collate:\n        return \"The expression contained an invalid collating element name.\";\n    case regex_constants::error_ctype:\n        return \"The expression contained an invalid character class name.\";\n    case regex_constants::error_escape:\n        return \"The expression contained an invalid escaped character, or a \"\n               \"trailing escape.\";\n    case regex_constants::error_backref:\n        return \"The expression contained an invalid back reference.\";\n    case regex_constants::error_brack:\n        return \"The expression contained mismatched [ and ].\";\n    case regex_constants::error_paren:\n        return \"The expression contained mismatched ( and ).\";\n    case regex_constants::error_brace:\n        return \"The expression contained mismatched { and }.\";\n    case regex_constants::error_badbrace:\n        return \"The expression contained an invalid range in a {} expression.\";\n    case regex_constants::error_range:\n        return \"The expression contained an invalid character range, \"\n               \"such as [b-a] in most encodings.\";\n    case regex_constants::error_space:\n        return \"There was insufficient memory to convert the expression into \"\n               \"a finite state machine.\";\n    case regex_constants::error_badrepeat:\n        return \"One of *?+{ was not preceded by a valid regular expression.\";\n    case regex_constants::error_complexity:\n        return \"The complexity of an attempted match against a regular \"\n               \"expression exceeded a pre-set level.\";\n    case regex_constants::error_stack:\n        return \"There was insufficient memory to determine whether the regular \"\n               \"expression could match the specified character sequence.\";\n    case regex_constants::__re_err_grammar:\n        return \"An invalid regex grammar has been requested.\";\n    case regex_constants::__re_err_empty:\n        return \"An empty regex is not allowed in the POSIX grammar.\";\n    default:\n        break;\n    }\n    return \"Unknown error type\";\n}\n\nregex_error::regex_error(regex_constants::error_type ecode)\n    : runtime_error(make_error_type_string(ecode)),\n      __code_(ecode)\n{}\n\nregex_error::~regex_error() throw() {}\n\nnamespace {\n\n#if defined(__clang__)\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\nstruct collationnames\n{\n    const char* elem_;\n    char char_;\n};\n\n#if defined(__clang__)\n#pragma clang diagnostic pop\n#endif\n\nconst collationnames collatenames[] =\n{\n    {\"A\", 0x41},\n    {\"B\", 0x42},\n    {\"C\", 0x43},\n    {\"D\", 0x44},\n    {\"E\", 0x45},\n    {\"F\", 0x46},\n    {\"G\", 0x47},\n    {\"H\", 0x48},\n    {\"I\", 0x49},\n    {\"J\", 0x4a},\n    {\"K\", 0x4b},\n    {\"L\", 0x4c},\n    {\"M\", 0x4d},\n    {\"N\", 0x4e},\n    {\"NUL\", 0x00},\n    {\"O\", 0x4f},\n    {\"P\", 0x50},\n    {\"Q\", 0x51},\n    {\"R\", 0x52},\n    {\"S\", 0x53},\n    {\"T\", 0x54},\n    {\"U\", 0x55},\n    {\"V\", 0x56},\n    {\"W\", 0x57},\n    {\"X\", 0x58},\n    {\"Y\", 0x59},\n    {\"Z\", 0x5a},\n    {\"a\", 0x61},\n    {\"alert\", 0x07},\n    {\"ampersand\", 0x26},\n    {\"apostrophe\", 0x27},\n    {\"asterisk\", 0x2a},\n    {\"b\", 0x62},\n    {\"backslash\", 0x5c},\n    {\"backspace\", 0x08},\n    {\"c\", 0x63},\n    {\"carriage-return\", 0x0d},\n    {\"circumflex\", 0x5e},\n    {\"circumflex-accent\", 0x5e},\n    {\"colon\", 0x3a},\n    {\"comma\", 0x2c},\n    {\"commercial-at\", 0x40},\n    {\"d\", 0x64},\n    {\"dollar-sign\", 0x24},\n    {\"e\", 0x65},\n    {\"eight\", 0x38},\n    {\"equals-sign\", 0x3d},\n    {\"exclamation-mark\", 0x21},\n    {\"f\", 0x66},\n    {\"five\", 0x35},\n    {\"form-feed\", 0x0c},\n    {\"four\", 0x34},\n    {\"full-stop\", 0x2e},\n    {\"g\", 0x67},\n    {\"grave-accent\", 0x60},\n    {\"greater-than-sign\", 0x3e},\n    {\"h\", 0x68},\n    {\"hyphen\", 0x2d},\n    {\"hyphen-minus\", 0x2d},\n    {\"i\", 0x69},\n    {\"j\", 0x6a},\n    {\"k\", 0x6b},\n    {\"l\", 0x6c},\n    {\"left-brace\", 0x7b},\n    {\"left-curly-bracket\", 0x7b},\n    {\"left-parenthesis\", 0x28},\n    {\"left-square-bracket\", 0x5b},\n    {\"less-than-sign\", 0x3c},\n    {\"low-line\", 0x5f},\n    {\"m\", 0x6d},\n    {\"n\", 0x6e},\n    {\"newline\", 0x0a},\n    {\"nine\", 0x39},\n    {\"number-sign\", 0x23},\n    {\"o\", 0x6f},\n    {\"one\", 0x31},\n    {\"p\", 0x70},\n    {\"percent-sign\", 0x25},\n    {\"period\", 0x2e},\n    {\"plus-sign\", 0x2b},\n    {\"q\", 0x71},\n    {\"question-mark\", 0x3f},\n    {\"quotation-mark\", 0x22},\n    {\"r\", 0x72},\n    {\"reverse-solidus\", 0x5c},\n    {\"right-brace\", 0x7d},\n    {\"right-curly-bracket\", 0x7d},\n    {\"right-parenthesis\", 0x29},\n    {\"right-square-bracket\", 0x5d},\n    {\"s\", 0x73},\n    {\"semicolon\", 0x3b},\n    {\"seven\", 0x37},\n    {\"six\", 0x36},\n    {\"slash\", 0x2f},\n    {\"solidus\", 0x2f},\n    {\"space\", 0x20},\n    {\"t\", 0x74},\n    {\"tab\", 0x09},\n    {\"three\", 0x33},\n    {\"tilde\", 0x7e},\n    {\"two\", 0x32},\n    {\"u\", 0x75},\n    {\"underscore\", 0x5f},\n    {\"v\", 0x76},\n    {\"vertical-line\", 0x7c},\n    {\"vertical-tab\", 0x0b},\n    {\"w\", 0x77},\n    {\"x\", 0x78},\n    {\"y\", 0x79},\n    {\"z\", 0x7a},\n    {\"zero\", 0x30}\n};\n\n#if defined(__clang__)\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\nstruct classnames\n{\n    const char* elem_;\n    regex_traits<char>::char_class_type mask_;\n};\n\n#if defined(__clang__)\n#pragma clang diagnostic pop\n#endif\n\nconst classnames ClassNames[] =\n{\n    {\"alnum\",  ctype_base::alnum},\n    {\"alpha\",  ctype_base::alpha},\n    {\"blank\",  ctype_base::blank},\n    {\"cntrl\",  ctype_base::cntrl},\n    {\"d\",      ctype_base::digit},\n    {\"digit\",  ctype_base::digit},\n    {\"graph\",  ctype_base::graph},\n    {\"lower\",  ctype_base::lower},\n    {\"print\",  ctype_base::print},\n    {\"punct\",  ctype_base::punct},\n    {\"s\",      ctype_base::space},\n    {\"space\",  ctype_base::space},\n    {\"upper\",  ctype_base::upper},\n    {\"w\",      regex_traits<char>::__regex_word},\n    {\"xdigit\", ctype_base::xdigit}\n};\n\nstruct use_strcmp\n{\n    bool operator()(const collationnames& x, const char* y)\n        {return strcmp(x.elem_, y) < 0;}\n    bool operator()(const classnames& x, const char* y)\n        {return strcmp(x.elem_, y) < 0;}\n};\n\n}\n\nstring\n__get_collation_name(const char* s)\n{\n    const collationnames* i =\n            _VSTD::lower_bound(begin(collatenames), end(collatenames), s, use_strcmp());\n    string r;\n    if (i != end(collatenames) && strcmp(s, i->elem_) == 0)\n        r = char(i->char_);\n    return r;\n}\n\nregex_traits<char>::char_class_type\n__get_classname(const char* s, bool __icase)\n{\n    const classnames* i =\n            _VSTD::lower_bound(begin(ClassNames), end(ClassNames), s, use_strcmp());\n    regex_traits<char>::char_class_type r = 0;\n    if (i != end(ClassNames) && strcmp(s, i->elem_) == 0)\n    {\n        r = i->mask_;\n        if (r == regex_traits<char>::__regex_word)\n            r |= ctype_base::alnum | ctype_base::upper | ctype_base::lower;\n        else if (__icase)\n        {\n            if (r & (ctype_base::lower | ctype_base::upper))\n                r |= ctype_base::alpha;\n        }\n    }\n    return r;\n}\n\ntemplate <>\nvoid\n__match_any_but_newline<char>::__exec(__state& __s) const\n{\n    if (__s.__current_ != __s.__last_)\n    {\n        switch (*__s.__current_)\n        {\n        case '\\r':\n        case '\\n':\n            __s.__do_ = __state::__reject;\n            __s.__node_ = nullptr;\n            break;\n        default:\n            __s.__do_ = __state::__accept_and_consume;\n            ++__s.__current_;\n            __s.__node_ = this->first();\n            break;\n        }\n    }\n    else\n    {\n        __s.__do_ = __state::__reject;\n        __s.__node_ = nullptr;\n    }\n}\n\ntemplate <>\nvoid\n__match_any_but_newline<wchar_t>::__exec(__state& __s) const\n{\n    if (__s.__current_ != __s.__last_)\n    {\n        switch (*__s.__current_)\n        {\n        case '\\r':\n        case '\\n':\n        case 0x2028:\n        case 0x2029:\n            __s.__do_ = __state::__reject;\n            __s.__node_ = nullptr;\n            break;\n        default:\n            __s.__do_ = __state::__accept_and_consume;\n            ++__s.__current_;\n            __s.__node_ = this->first();\n            break;\n        }\n    }\n    else\n    {\n        __s.__do_ = __state::__reject;\n        __s.__node_ = nullptr;\n    }\n}\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/shared_mutex.cpp",
    "content": "//===---------------------- shared_mutex.cpp ------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"__config\"\n#ifndef _LIBCPP_HAS_NO_THREADS\n\n#define _LIBCPP_BUILDING_SHARED_MUTEX\n#include \"shared_mutex\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n// Shared Mutex Base\n__shared_mutex_base::__shared_mutex_base()\n    : __state_(0)\n{\n}\n\n// Exclusive ownership\n\nvoid\n__shared_mutex_base::lock()\n{\n    unique_lock<mutex> lk(__mut_);\n    while (__state_ & __write_entered_)\n        __gate1_.wait(lk);\n    __state_ |= __write_entered_;\n    while (__state_ & __n_readers_)\n        __gate2_.wait(lk);\n}\n\nbool\n__shared_mutex_base::try_lock()\n{\n    unique_lock<mutex> lk(__mut_);\n    if (__state_ == 0)\n    {\n        __state_ = __write_entered_;\n        return true;\n    }\n    return false;\n}\n\nvoid\n__shared_mutex_base::unlock()\n{\n    lock_guard<mutex> _(__mut_);\n    __state_ = 0;\n    __gate1_.notify_all();\n}\n\n// Shared ownership\n\nvoid\n__shared_mutex_base::lock_shared()\n{\n    unique_lock<mutex> lk(__mut_);\n    while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)\n        __gate1_.wait(lk);\n    unsigned num_readers = (__state_ & __n_readers_) + 1;\n    __state_ &= ~__n_readers_;\n    __state_ |= num_readers;\n}\n\nbool\n__shared_mutex_base::try_lock_shared()\n{\n    unique_lock<mutex> lk(__mut_);\n    unsigned num_readers = __state_ & __n_readers_;\n    if (!(__state_ & __write_entered_) && num_readers != __n_readers_)\n    {\n        ++num_readers;\n        __state_ &= ~__n_readers_;\n        __state_ |= num_readers;\n        return true;\n    }\n    return false;\n}\n\nvoid\n__shared_mutex_base::unlock_shared()\n{\n    lock_guard<mutex> _(__mut_);\n    unsigned num_readers = (__state_ & __n_readers_) - 1;\n    __state_ &= ~__n_readers_;\n    __state_ |= num_readers;\n    if (__state_ & __write_entered_)\n    {\n        if (num_readers == 0)\n            __gate2_.notify_one();\n    }\n    else\n    {\n        if (num_readers == __n_readers_ - 1)\n            __gate1_.notify_one();\n    }\n}\n\n\n// Shared Timed Mutex\n// These routines are here for ABI stability\nshared_timed_mutex::shared_timed_mutex() : __base() {}\nvoid shared_timed_mutex::lock()     { return __base.lock(); }\nbool shared_timed_mutex::try_lock() { return __base.try_lock(); }\nvoid shared_timed_mutex::unlock()   { return __base.unlock(); }\nvoid shared_timed_mutex::lock_shared() { return __base.lock_shared(); }\nbool shared_timed_mutex::try_lock_shared() { return __base.try_lock_shared(); }\nvoid shared_timed_mutex::unlock_shared() { return __base.unlock_shared(); }\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif // !_LIBCPP_HAS_NO_THREADS\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/stdexcept.cpp",
    "content": "//===------------------------ stdexcept.cpp -------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"__refstring\"\n#include \"stdexcept\"\n#include \"new\"\n#include \"string\"\n#include \"system_error\"\n\n#ifndef __has_include\n#define __has_include(inc) 0\n#endif\n\n/* For _LIBCPPABI_VERSION */\n#if __has_include(<cxxabi.h>) || defined(__APPLE_) || defined(LIBCXXRT)\n#include <cxxabi.h>\n#endif\n\nstatic_assert(sizeof(std::__libcpp_refstring) == sizeof(const char *), \"\");\n\nnamespace std  // purposefully not using versioning namespace\n{\n\nlogic_error::logic_error(const string& msg) : __imp_(msg.c_str())\n{\n}\n\nlogic_error::logic_error(const char* msg) : __imp_(msg)\n{\n}\n\nlogic_error::logic_error(const logic_error& le) _NOEXCEPT : __imp_(le.__imp_)\n{\n}\n\nlogic_error&\nlogic_error::operator=(const logic_error& le) _NOEXCEPT\n{\n    __imp_ = le.__imp_;\n    return *this;\n}\n\n#if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX)\n\nlogic_error::~logic_error() _NOEXCEPT\n{\n}\n\nconst char*\nlogic_error::what() const _NOEXCEPT\n{\n    return __imp_.c_str();\n}\n\n#endif\n\nruntime_error::runtime_error(const string& msg) : __imp_(msg.c_str())\n{\n}\n\nruntime_error::runtime_error(const char* msg) : __imp_(msg)\n{\n}\n\nruntime_error::runtime_error(const runtime_error& le) _NOEXCEPT\n  : __imp_(le.__imp_)\n{\n}\n\nruntime_error&\nruntime_error::operator=(const runtime_error& le) _NOEXCEPT\n{\n    __imp_ = le.__imp_;\n    return *this;\n}\n\n#if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX)\n\nruntime_error::~runtime_error() _NOEXCEPT\n{\n}\n\nconst char*\nruntime_error::what() const _NOEXCEPT\n{\n    return __imp_.c_str();\n}\n\ndomain_error::~domain_error() _NOEXCEPT {}\ninvalid_argument::~invalid_argument() _NOEXCEPT {}\nlength_error::~length_error() _NOEXCEPT {}\nout_of_range::~out_of_range() _NOEXCEPT {}\n\nrange_error::~range_error() _NOEXCEPT {}\noverflow_error::~overflow_error() _NOEXCEPT {}\nunderflow_error::~underflow_error() _NOEXCEPT {}\n\n#endif\n\n}  // std\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/string.cpp",
    "content": "//===------------------------- string.cpp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#undef _LIBCPP_EXTERN_TEMPLATE\n#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;\n\n#include \"string\"\n#include \"cstdlib\"\n#include \"cwchar\"\n#include \"cerrno\"\n#include \"limits\"\n#include \"stdexcept\"\n#ifdef _LIBCPP_MSVCRT\n#include \"support/win32/support.h\"\n#endif // _LIBCPP_MSVCRT\n#include <stdio.h>\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate class __basic_string_common<true>;\n\ntemplate class basic_string<char>;\ntemplate class basic_string<wchar_t>;\n\ntemplate\n    string\n    operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);\n\nnamespace\n{\n\ntemplate<typename T>\ninline\nvoid throw_helper( const string& msg )\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    throw T( msg );\n#else\n    fprintf(stderr, \"%s\\n\", msg.c_str());\n    abort();\n#endif\n}\n\ninline\nvoid throw_from_string_out_of_range( const string& func )\n{\n    throw_helper<out_of_range>(func + \": out of range\");\n}\n\ninline\nvoid throw_from_string_invalid_arg( const string& func )\n{\n    throw_helper<invalid_argument>(func + \": no conversion\");\n}\n\n// as_integer\n\ntemplate<typename V, typename S, typename F>\ninline\nV\nas_integer_helper(const string& func, const S& str, size_t* idx, int base, F f)\n{\n    typename S::value_type* ptr = nullptr;\n    const typename S::value_type* const p = str.c_str();\n    typename remove_reference<decltype(errno)>::type errno_save = errno;\n    errno = 0;\n    V r = f(p, &ptr, base);\n    swap(errno, errno_save);\n    if (errno_save == ERANGE)\n        throw_from_string_out_of_range(func);\n    if (ptr == p)\n        throw_from_string_invalid_arg(func);\n    if (idx)\n        *idx = static_cast<size_t>(ptr - p);\n    return r;\n}\n\ntemplate<typename V, typename S>\ninline\nV\nas_integer(const string& func, const S& s, size_t* idx, int base);\n\n// string\ntemplate<>\ninline\nint\nas_integer(const string& func, const string& s, size_t* idx, int base )\n{\n    // Use long as no Standard string to integer exists.\n    long r = as_integer_helper<long>( func, s, idx, base, strtol );\n    if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)\n        throw_from_string_out_of_range(func);\n    return static_cast<int>(r);\n}\n\ntemplate<>\ninline\nlong\nas_integer(const string& func, const string& s, size_t* idx, int base )\n{\n    return as_integer_helper<long>( func, s, idx, base, strtol );\n}\n\ntemplate<>\ninline\nunsigned long\nas_integer( const string& func, const string& s, size_t* idx, int base )\n{\n    return as_integer_helper<unsigned long>( func, s, idx, base, strtoul );\n}\n\ntemplate<>\ninline\nlong long\nas_integer( const string& func, const string& s, size_t* idx, int base )\n{\n    return as_integer_helper<long long>( func, s, idx, base, strtoll );\n}\n\ntemplate<>\ninline\nunsigned long long\nas_integer( const string& func, const string& s, size_t* idx, int base )\n{\n    return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull );\n}\n\n// wstring\ntemplate<>\ninline\nint\nas_integer( const string& func, const wstring& s, size_t* idx, int base )\n{\n    // Use long as no Stantard string to integer exists.\n    long r = as_integer_helper<long>( func, s, idx, base, wcstol );\n    if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)\n        throw_from_string_out_of_range(func);\n    return static_cast<int>(r);\n}\n\ntemplate<>\ninline\nlong\nas_integer( const string& func, const wstring& s, size_t* idx, int base )\n{\n    return as_integer_helper<long>( func, s, idx, base, wcstol );\n}\n\ntemplate<>\ninline\nunsigned long\nas_integer( const string& func, const wstring& s, size_t* idx, int base )\n{\n    return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul );\n}\n\ntemplate<>\ninline\nlong long\nas_integer( const string& func, const wstring& s, size_t* idx, int base )\n{\n    return as_integer_helper<long long>( func, s, idx, base, wcstoll );\n}\n\ntemplate<>\ninline\nunsigned long long\nas_integer( const string& func, const wstring& s, size_t* idx, int base )\n{\n    return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull );\n}\n\n// as_float\n\ntemplate<typename V, typename S, typename F> \ninline\nV\nas_float_helper(const string& func, const S& str, size_t* idx, F f )\n{\n    typename S::value_type* ptr = nullptr;\n    const typename S::value_type* const p = str.c_str();\n    typename remove_reference<decltype(errno)>::type errno_save = errno;\n    errno = 0;\n    V r = f(p, &ptr);\n    swap(errno, errno_save);\n    if (errno_save == ERANGE)\n        throw_from_string_out_of_range(func);\n    if (ptr == p)\n        throw_from_string_invalid_arg(func);\n    if (idx)\n        *idx = static_cast<size_t>(ptr - p);\n    return r;\n}\n\ntemplate<typename V, typename S>\ninline\nV as_float( const string& func, const S& s, size_t* idx = nullptr );\n\ntemplate<>\ninline\nfloat\nas_float( const string& func, const string& s, size_t* idx )\n{\n    return as_float_helper<float>( func, s, idx, strtof );\n}\n\ntemplate<>\ninline\ndouble\nas_float(const string& func, const string& s, size_t* idx )\n{\n    return as_float_helper<double>( func, s, idx, strtod );\n}\n\ntemplate<>\ninline\nlong double\nas_float( const string& func, const string& s, size_t* idx )\n{\n    return as_float_helper<long double>( func, s, idx, strtold );\n}\n\ntemplate<>\ninline\nfloat\nas_float( const string& func, const wstring& s, size_t* idx )\n{\n    return as_float_helper<float>( func, s, idx, wcstof );\n}\n\ntemplate<>\ninline\ndouble\nas_float( const string& func, const wstring& s, size_t* idx )\n{\n    return as_float_helper<double>( func, s, idx, wcstod );\n}\n\ntemplate<>\ninline\nlong double\nas_float( const string& func, const wstring& s, size_t* idx )\n{\n    return as_float_helper<long double>( func, s, idx, wcstold );\n}\n\n}  // unnamed namespace\n\nint\nstoi(const string& str, size_t* idx, int base)\n{\n    return as_integer<int>( \"stoi\", str, idx, base );\n}\n\nint\nstoi(const wstring& str, size_t* idx, int base)\n{\n    return as_integer<int>( \"stoi\", str, idx, base );\n}\n\nlong\nstol(const string& str, size_t* idx, int base)\n{\n    return as_integer<long>( \"stol\", str, idx, base );\n}\n\nlong\nstol(const wstring& str, size_t* idx, int base)\n{\n    return as_integer<long>( \"stol\", str, idx, base );\n}\n\nunsigned long\nstoul(const string& str, size_t* idx, int base)\n{\n    return as_integer<unsigned long>( \"stoul\", str, idx, base );\n}\n\nunsigned long\nstoul(const wstring& str, size_t* idx, int base)\n{\n    return as_integer<unsigned long>( \"stoul\", str, idx, base );\n}\n\nlong long\nstoll(const string& str, size_t* idx, int base)\n{\n    return as_integer<long long>( \"stoll\", str, idx, base );\n}\n\nlong long\nstoll(const wstring& str, size_t* idx, int base)\n{\n    return as_integer<long long>( \"stoll\", str, idx, base );\n}\n\nunsigned long long\nstoull(const string& str, size_t* idx, int base)\n{\n    return as_integer<unsigned long long>( \"stoull\", str, idx, base );\n}\n\nunsigned long long\nstoull(const wstring& str, size_t* idx, int base)\n{\n    return as_integer<unsigned long long>( \"stoull\", str, idx, base );\n}\n\nfloat\nstof(const string& str, size_t* idx)\n{\n    return as_float<float>( \"stof\", str, idx );\n}\n\nfloat\nstof(const wstring& str, size_t* idx)\n{\n    return as_float<float>( \"stof\", str, idx );\n}\n\ndouble\nstod(const string& str, size_t* idx)\n{\n    return as_float<double>( \"stod\", str, idx );\n}\n\ndouble\nstod(const wstring& str, size_t* idx)\n{\n    return as_float<double>( \"stod\", str, idx );\n}\n\nlong double\nstold(const string& str, size_t* idx)\n{\n    return as_float<long double>( \"stold\", str, idx );\n}\n\nlong double\nstold(const wstring& str, size_t* idx)\n{\n    return as_float<long double>( \"stold\", str, idx );\n}\n\n// to_string\n\nnamespace\n{\n\n// as_string\n\ntemplate<typename S, typename P, typename V >\ninline\nS\nas_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)\n{\n    typedef typename S::size_type size_type;\n    size_type available = s.size();\n    while (true)\n    {\n        int status = sprintf_like(&s[0], available + 1, fmt, a);\n        if ( status >= 0 )\n        {\n            size_type used = static_cast<size_type>(status);\n            if ( used <= available )\n            {\n                s.resize( used );\n                break;\n            }\n            available = used; // Assume this is advice of how much space we need.\n        }\n        else\n            available = available * 2 + 1;\n        s.resize(available);\n    }\n    return s;\n}\n\ntemplate <class S, class V, bool = is_floating_point<V>::value>\nstruct initial_string;\n\ntemplate <class V, bool b>\nstruct initial_string<string, V, b>\n{\n    string\n    operator()() const\n    {\n        string s;\n        s.resize(s.capacity());\n        return s;\n    }\n};\n\ntemplate <class V>\nstruct initial_string<wstring, V, false>\n{\n    wstring\n    operator()() const\n    {\n        const size_t n = (numeric_limits<unsigned long long>::digits / 3)\n          + ((numeric_limits<unsigned long long>::digits % 3) != 0)\n          + 1;\n        wstring s(n, wchar_t());\n        s.resize(s.capacity());\n        return s;\n    }\n};\n\ntemplate <class V>\nstruct initial_string<wstring, V, true>\n{\n    wstring\n    operator()() const\n    {\n        wstring s(20, wchar_t());\n        s.resize(s.capacity());\n        return s;\n    }\n};\n\ntypedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...);\n\ninline\nwide_printf\nget_swprintf()\n{\n#ifndef _LIBCPP_MSVCRT\n    return swprintf;\n#else\n    return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf);\n#endif\n}\n\n}  // unnamed namespace\n\nstring to_string(int val)\n{\n    return as_string(snprintf, initial_string<string, int>()(), \"%d\", val);\n}\n\nstring to_string(unsigned val)\n{\n    return as_string(snprintf, initial_string<string, unsigned>()(), \"%u\", val);\n}\n\nstring to_string(long val)\n{\n    return as_string(snprintf, initial_string<string, long>()(), \"%ld\", val);\n}\n\nstring to_string(unsigned long val)\n{\n    return as_string(snprintf, initial_string<string, unsigned long>()(), \"%lu\", val);\n}\n\nstring to_string(long long val)\n{\n    return as_string(snprintf, initial_string<string, long long>()(), \"%lld\", val);\n}\n\nstring to_string(unsigned long long val)\n{\n    return as_string(snprintf, initial_string<string, unsigned long long>()(), \"%llu\", val);\n}\n\nstring to_string(float val)\n{\n    return as_string(snprintf, initial_string<string, float>()(), \"%f\", val);\n}\n\nstring to_string(double val)\n{\n    return as_string(snprintf, initial_string<string, double>()(), \"%f\", val);\n}\n\nstring to_string(long double val)\n{\n    return as_string(snprintf, initial_string<string, long double>()(), \"%Lf\", val);\n}\n\nwstring to_wstring(int val)\n{\n    return as_string(get_swprintf(), initial_string<wstring, int>()(), L\"%d\", val);\n}\n\nwstring to_wstring(unsigned val)\n{\n    return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L\"%u\", val);\n}\n\nwstring to_wstring(long val)\n{\n    return as_string(get_swprintf(), initial_string<wstring, long>()(), L\"%ld\", val);\n}\n\nwstring to_wstring(unsigned long val)\n{\n    return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L\"%lu\", val);\n}\n\nwstring to_wstring(long long val)\n{\n    return as_string(get_swprintf(), initial_string<wstring, long long>()(), L\"%lld\", val);\n}\n\nwstring to_wstring(unsigned long long val)\n{\n    return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L\"%llu\", val);\n}\n\nwstring to_wstring(float val)\n{\n    return as_string(get_swprintf(), initial_string<wstring, float>()(), L\"%f\", val);\n}\n\nwstring to_wstring(double val)\n{\n    return as_string(get_swprintf(), initial_string<wstring, double>()(), L\"%f\", val);\n}\n\nwstring to_wstring(long double val)\n{\n    return as_string(get_swprintf(), initial_string<wstring, long double>()(), L\"%Lf\", val);\n}\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/strstream.cpp",
    "content": "//===------------------------ strstream.cpp -------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"strstream\"\n#include \"algorithm\"\n#include \"climits\"\n#include \"cstring\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nstrstreambuf::strstreambuf(streamsize __alsize)\n    : __strmode_(__dynamic),\n      __alsize_(__alsize),\n      __palloc_(nullptr),\n      __pfree_(nullptr)\n{\n}\n\nstrstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*))\n    : __strmode_(__dynamic),\n      __alsize_(__default_alsize),\n      __palloc_(__palloc),\n      __pfree_(__pfree)\n{\n}\n\nvoid\nstrstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg)\n{\n    if (__n == 0)\n        __n = static_cast<streamsize>(strlen(__gnext));\n    else if (__n < 0)\n        __n = INT_MAX;\n    if (__pbeg == nullptr)\n        setg(__gnext, __gnext, __gnext + __n);\n    else\n    {\n        setg(__gnext, __gnext, __pbeg);\n        setp(__pbeg, __pbeg + __n);\n    }\n}\n\nstrstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg)\n    : __strmode_(),\n      __alsize_(__default_alsize),\n      __palloc_(nullptr),\n      __pfree_(nullptr)\n{\n    __init(__gnext, __n, __pbeg);\n}\n\nstrstreambuf::strstreambuf(const char* __gnext, streamsize __n)\n    : __strmode_(__constant),\n      __alsize_(__default_alsize),\n      __palloc_(nullptr),\n      __pfree_(nullptr)\n{\n    __init(const_cast<char *>(__gnext), __n, nullptr);\n}\n\nstrstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg)\n    : __strmode_(),\n      __alsize_(__default_alsize),\n      __palloc_(nullptr),\n      __pfree_(nullptr)\n{\n    __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg));\n}\n\nstrstreambuf::strstreambuf(const signed char* __gnext, streamsize __n)\n    : __strmode_(__constant),\n      __alsize_(__default_alsize),\n      __palloc_(nullptr),\n      __pfree_(nullptr)\n{\n    __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr);\n}\n\nstrstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg)\n    : __strmode_(),\n      __alsize_(__default_alsize),\n      __palloc_(nullptr),\n      __pfree_(nullptr)\n{\n    __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg));\n}\n\nstrstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n)\n    : __strmode_(__constant),\n      __alsize_(__default_alsize),\n      __palloc_(nullptr),\n      __pfree_(nullptr)\n{\n    __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr);\n}\n\nstrstreambuf::~strstreambuf()\n{\n    if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0)\n    {\n        if (__pfree_)\n            __pfree_(eback());\n        else\n            delete [] eback();\n    }\n}\n\nvoid\nstrstreambuf::swap(strstreambuf& __rhs)\n{\n    streambuf::swap(__rhs);\n    _VSTD::swap(__strmode_, __rhs.__strmode_);\n    _VSTD::swap(__alsize_, __rhs.__alsize_);\n    _VSTD::swap(__palloc_, __rhs.__palloc_);\n    _VSTD::swap(__pfree_, __rhs.__pfree_);\n}\n\nvoid\nstrstreambuf::freeze(bool __freezefl)\n{\n    if (__strmode_ & __dynamic)\n    {\n        if (__freezefl)\n            __strmode_ |= __frozen;\n        else\n            __strmode_ &= ~__frozen;\n    }\n}\n\nchar*\nstrstreambuf::str()\n{\n    if (__strmode_ & __dynamic)\n        __strmode_ |= __frozen;\n    return eback();\n}\n\nint\nstrstreambuf::pcount() const\n{\n    return static_cast<int>(pptr() - pbase());\n}\n\nstrstreambuf::int_type\nstrstreambuf::overflow(int_type __c)\n{\n    if (__c == EOF)\n        return int_type(0);\n    if (pptr() == epptr())\n    {\n        if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0)\n            return int_type(EOF);\n        size_t old_size = static_cast<size_t> ((epptr() ? epptr() : egptr()) - eback());\n        size_t new_size = max<size_t>(static_cast<size_t>(__alsize_), 2*old_size);\n        if (new_size == 0)\n            new_size = __default_alsize;\n        char* buf = nullptr;\n        if (__palloc_)\n            buf = static_cast<char*>(__palloc_(new_size));\n        else\n            buf = new char[new_size];\n        if (buf == nullptr)\n            return int_type(EOF);\n        memcpy(buf, eback(), static_cast<size_t>(old_size));\n        ptrdiff_t ninp = gptr()  - eback();\n        ptrdiff_t einp = egptr() - eback();\n        ptrdiff_t nout = pptr()  - pbase();\n        ptrdiff_t eout = epptr() - pbase();\n        if (__strmode_ & __allocated)\n        {\n            if (__pfree_)\n                __pfree_(eback());\n            else\n                delete [] eback();\n        }\n        setg(buf, buf + ninp, buf + einp);\n        setp(buf + einp, buf + einp + eout);\n        pbump(static_cast<int>(nout));\n        __strmode_ |= __allocated;\n    }\n    *pptr() = static_cast<char>(__c);\n    pbump(1);\n    return int_type(static_cast<unsigned char>(__c));\n}\n\nstrstreambuf::int_type\nstrstreambuf::pbackfail(int_type __c)\n{\n    if (eback() == gptr())\n        return EOF;\n    if (__c == EOF)\n    {\n        gbump(-1);\n        return int_type(0);\n    }\n    if (__strmode_ & __constant)\n    {\n        if (gptr()[-1] == static_cast<char>(__c))\n        {\n            gbump(-1);\n            return __c;\n        }\n        return EOF;\n    }\n    gbump(-1);\n    *gptr() = static_cast<char>(__c);\n    return __c;\n}\n\nstrstreambuf::int_type\nstrstreambuf::underflow()\n{\n    if (gptr() == egptr())\n    {\n        if (egptr() >= pptr())\n            return EOF;\n        setg(eback(), gptr(), pptr());\n    }\n    return int_type(static_cast<unsigned char>(*gptr()));\n}\n\nstrstreambuf::pos_type\nstrstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which)\n{\n    off_type __p(-1);\n    bool pos_in = (__which & ios::in) != 0;\n    bool pos_out = (__which & ios::out) != 0;\n    bool legal = false;\n    switch (__way)\n    {\n    case ios::beg:\n    case ios::end:\n        if (pos_in || pos_out)\n            legal = true;\n        break;\n    case ios::cur:\n        if (pos_in != pos_out)\n            legal = true;\n        break;\n    }\n    if (pos_in && gptr() == nullptr)\n        legal = false;\n    if (pos_out && pptr() == nullptr)\n        legal = false;\n    if (legal)\n    {\n        off_type newoff;\n        char* seekhigh = epptr() ? epptr() : egptr();\n        switch (__way)\n        {\n        case ios::beg:\n            newoff = 0;\n            break;\n        case ios::cur:\n            newoff = (pos_in ? gptr() : pptr()) - eback();\n            break;\n        case ios::end:\n            newoff = seekhigh - eback();\n            break;\n        }\n        newoff += __off;\n        if (0 <= newoff && newoff <= seekhigh - eback())\n        {\n            char* newpos = eback() + newoff;\n            if (pos_in)\n                setg(eback(), newpos, _VSTD::max(newpos, egptr()));\n            if (pos_out)\n            {\n                // min(pbase, newpos), newpos, epptr()\n                __off = epptr() - newpos;\n                setp(min(pbase(), newpos), epptr());\n                pbump(static_cast<int>((epptr() - pbase()) - __off));\n            }\n            __p = newoff;\n        }\n    }\n    return pos_type(__p);\n}\n\nstrstreambuf::pos_type\nstrstreambuf::seekpos(pos_type __sp, ios_base::openmode __which)\n{\n    off_type __p(-1);\n    bool pos_in = (__which & ios::in) != 0;\n    bool pos_out = (__which & ios::out) != 0;\n    if (pos_in || pos_out)\n    {\n        if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr)))\n        {\n            off_type newoff = __sp;\n            char* seekhigh = epptr() ? epptr() : egptr();\n            if (0 <= newoff && newoff <= seekhigh - eback())\n            {\n                char* newpos = eback() + newoff;\n                if (pos_in)\n                    setg(eback(), newpos, _VSTD::max(newpos, egptr()));\n                if (pos_out)\n                {\n                    // min(pbase, newpos), newpos, epptr()\n                    off_type temp = epptr() - newpos;\n                    setp(min(pbase(), newpos), epptr());\n                    pbump(static_cast<int>((epptr() - pbase()) - temp));\n                }\n                __p = newoff;\n            }\n        }\n    }\n    return pos_type(__p);\n}\n\nistrstream::~istrstream()\n{\n}\n\nostrstream::~ostrstream()\n{\n}\n\nstrstream::~strstream()\n{\n}\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/support/atomic_support.h",
    "content": "#ifndef ATOMIC_SUPPORT_H\n#define ATOMIC_SUPPORT_H\n\n#include \"__config\"\n#include \"memory\" // for __libcpp_relaxed_load\n\n#if defined(__clang__) && __has_builtin(__atomic_load_n)             \\\n                       && __has_builtin(__atomic_store_n)            \\\n                       && __has_builtin(__atomic_add_fetch)          \\\n                       && __has_builtin(__atomic_compare_exchange_n) \\\n                       && defined(__ATOMIC_RELAXED)                  \\\n                       && defined(__ATOMIC_CONSUME)                  \\\n                       && defined(__ATOMIC_ACQUIRE)                  \\\n                       && defined(__ATOMIC_RELEASE)                  \\\n                       && defined(__ATOMIC_ACQ_REL)                  \\\n                       && defined(__ATOMIC_SEQ_CST)\n#   define _LIBCPP_HAS_ATOMIC_BUILTINS\n#elif !defined(__clang__) && defined(_GNUC_VER) && _GNUC_VER >= 407\n#   define _LIBCPP_HAS_ATOMIC_BUILTINS\n#endif\n\n#if !defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS)\n# if defined(_MSC_VER) && !defined(__clang__)\n    _LIBCPP_WARNING(\"Building libc++ without __atomic builtins is unsupported\")\n# else\n#   warning Building libc++ without __atomic builtins is unsupported\n# endif\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nnamespace {\n\n#if defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS)\n\nenum __libcpp_atomic_order {\n    _AO_Relaxed = __ATOMIC_RELAXED,\n    _AO_Consume = __ATOMIC_CONSUME,\n    _AO_Aquire  = __ATOMIC_ACQUIRE,\n    _AO_Release = __ATOMIC_RELEASE,\n    _AO_Acq_Rel = __ATOMIC_ACQ_REL,\n    _AO_Seq     = __ATOMIC_SEQ_CST\n};\n\ntemplate <class _ValueType, class _FromType>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid __libcpp_atomic_store(_ValueType* __dest, _FromType __val,\n                           int __order = _AO_Seq)\n{\n    __atomic_store_n(__dest, __val, __order);\n}\n\ntemplate <class _ValueType, class _FromType>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid __libcpp_relaxed_store(_ValueType* __dest, _FromType __val)\n{\n    __atomic_store_n(__dest, __val, _AO_Relaxed);\n}\n\ntemplate <class _ValueType>\ninline _LIBCPP_INLINE_VISIBILITY\n_ValueType __libcpp_atomic_load(_ValueType const* __val,\n                                int __order = _AO_Seq)\n{\n    return __atomic_load_n(__val, __order);\n}\n\ntemplate <class _ValueType, class _AddType>\ninline _LIBCPP_INLINE_VISIBILITY\n_ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a,\n                               int __order = _AO_Seq)\n{\n    return __atomic_add_fetch(__val, __a, __order);\n}\n\ntemplate <class _ValueType>\ninline _LIBCPP_INLINE_VISIBILITY\nbool __libcpp_atomic_compare_exchange(_ValueType* __val,\n    _ValueType* __expected, _ValueType __after,\n    int __success_order = _AO_Seq,\n    int __fail_order = _AO_Seq)\n{\n    return __atomic_compare_exchange_n(__val, __expected, __after, true,\n                                       __success_order, __fail_order);\n}\n\n#else // _LIBCPP_HAS_NO_THREADS\n\nenum __libcpp_atomic_order {\n    _AO_Relaxed,\n    _AO_Consume,\n    _AO_Acquire,\n    _AO_Release,\n    _AO_Acq_Rel,\n    _AO_Seq\n};\n\ntemplate <class _ValueType, class _FromType>\ninline _LIBCPP_INLINE_VISIBILITY\nvoid __libcpp_atomic_store(_ValueType* __dest, _FromType __val,\n                           int = 0)\n{\n    *__dest = __val;\n}\n\ntemplate <class _ValueType>\ninline _LIBCPP_INLINE_VISIBILITY\n_ValueType __libcpp_atomic_load(_ValueType const* __val,\n                                int = 0)\n{\n    return *__val;\n}\n\ntemplate <class _ValueType, class _AddType>\ninline _LIBCPP_INLINE_VISIBILITY\n_ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a,\n                               int = 0)\n{\n    return *__val += __a;\n}\n\ntemplate <class _ValueType>\ninline _LIBCPP_INLINE_VISIBILITY\nbool __libcpp_atomic_compare_exchange(_ValueType* __val,\n    _ValueType* __expected, _ValueType __after,\n    int = 0, int = 0)\n{\n    if (*__val == *__expected) {\n        *__val = __after;\n        return true;\n    }\n    *__expected = *__val;\n    return false;\n}\n\n#endif // _LIBCPP_HAS_NO_THREADS\n\n} // end namespace\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif // ATOMIC_SUPPORT_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/support/solaris/README",
    "content": "This directory contains a partial implementation of the xlocale APIs for\nSolaris.  Some portions are lifted from FreeBSD libc, and so are covered by a\n2-clause BSD license instead of the MIT/UUIC license that the rest of libc++ is\ndistributed under.\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/support/solaris/mbsnrtowcs.inc",
    "content": "\n\n/*-\n * As noted in the source, some portions of this implementation are copied from\n * FreeBSD libc.  These are covered by the following copyright:\n *\n * Copyright (c) 2002-2004 Tim J. Robbins.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\nsize_t\nmbsnrtowcs_l(wchar_t * __restrict dst, const char ** __restrict src,\n    size_t nms, size_t len, mbstate_t * __restrict ps, locale_t loc)\n{\n  const char *s;\n  size_t nchr;\n  wchar_t wc;\n  size_t nb;\n  FIX_LOCALE(loc);\n\n  s = *src;\n  nchr = 0;\n\n  if (dst == NULL) {\n    for (;;) {\n      if ((nb = mbrtowc_l(&wc, s, nms, ps, loc)) == (size_t)-1)\n        /* Invalid sequence - mbrtowc() sets errno. */\n        return ((size_t)-1);\n      else if (nb == 0 || nb == (size_t)-2)\n        return (nchr);\n      s += nb;\n      nms -= nb;\n      nchr++;\n    }\n    /*NOTREACHED*/\n  }\n\n  while (len-- > 0) {\n    if ((nb = mbrtowc_l(dst, s, nms, ps, loc)) == (size_t)-1) {\n      *src = s;\n      return ((size_t)-1);\n    } else if (nb == (size_t)-2) {\n      *src = s + nms;\n      return (nchr);\n    } else if (nb == 0) {\n      *src = NULL;\n      return (nchr);\n    }\n    s += nb;\n    nms -= nb;\n    nchr++;\n    dst++;\n  }\n  *src = s;\n  return (nchr);\n}\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/support/solaris/wcsnrtombs.inc",
    "content": "/*-\n * Copyright (c) 2002-2004 Tim J. Robbins.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n\nsize_t\nwcsnrtombs_l(char * __restrict dst, const wchar_t ** __restrict src,\n    size_t nwc, size_t len, mbstate_t * __restrict ps, locale_t loc)\n{\n  FIX_LOCALE(loc);\n  mbstate_t mbsbak;\n  char buf[MB_CUR_MAX_L(loc)];\n  const wchar_t *s;\n  size_t nbytes;\n  size_t nb;\n\n  s = *src;\n  nbytes = 0;\n\n  if (dst == NULL) {\n    while (nwc-- > 0) {\n      if ((nb = wcrtomb_l(buf, *s, ps, loc)) == (size_t)-1)\n        /* Invalid character - wcrtomb() sets errno. */\n        return ((size_t)-1);\n      else if (*s == L'\\0')\n        return (nbytes + nb - 1);\n      s++;\n      nbytes += nb;\n    }\n    return (nbytes);\n  }\n\n  while (len > 0 && nwc-- > 0) {\n    if (len > (size_t)MB_CUR_MAX_L(loc)) {\n      /* Enough space to translate in-place. */\n      if ((nb = wcrtomb_l(dst, *s, ps, loc)) == (size_t)-1) {\n        *src = s;\n        return ((size_t)-1);\n      }\n    } else {\n      /*\n       * May not be enough space; use temp. buffer.\n       *\n       * We need to save a copy of the conversion state\n       * here so we can restore it if the multibyte\n       * character is too long for the buffer.\n       */\n      mbsbak = *ps;\n      if ((nb = wcrtomb_l(buf, *s, ps, loc)) == (size_t)-1) {\n        *src = s;\n        return ((size_t)-1);\n      }\n      if (nb > (int)len) {\n        /* MB sequence for character won't fit. */\n        *ps = mbsbak;\n        break;\n      }\n      memcpy(dst, buf, nb);\n    }\n    if (*s == L'\\0') {\n      *src = NULL;\n      return (nbytes + nb - 1);\n    }\n    s++;\n    dst += nb;\n    len -= nb;\n    nbytes += nb;\n  }\n  *src = s;\n  return (nbytes);\n}\n\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/support/solaris/xlocale.c",
    "content": "//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifdef __sun__\n\n#include \"support/solaris/xlocale.h\"\n#include <stdarg.h>\n#include <stdio.h>\n#include <sys/localedef.h>\n\n\nint isxdigit_l(int __c, locale_t __l) {\n    return isxdigit(__c);\n}\n\nint iswxdigit_l(wchar_t __c, locale_t __l) {\n    return isxdigit(__c);\n}\n\n// FIXME: This disregards the locale, which is Very Wrong\n#define vsnprintf_l(__s, __n, __l, __format, __va)  \\\n    vsnprintf(__s, __n, __format, __va) \n\nint snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...)\n{\n  va_list __va;\n  va_start(__va, __format);\n  int __res = vsnprintf_l(__s, __n , __l, __format, __va);\n  va_end(__va);\n  return __res;\n}\n\nint asprintf_l(char **__s, locale_t __l, const char *__format, ...) {\n  va_list __va;\n  va_start(__va, __format);\n  // FIXME:\n  int __res = vasprintf(__s, __format, __va);\n  va_end(__va);\n  return __res;\n}\n\nint sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {\n  va_list __va;\n  va_start(__va, __format);\n  // FIXME:\n  int __res = vsscanf(__s, __format, __va);\n  va_end(__va);\n  return __res;\n}\n\nsize_t mbrtowc_l(wchar_t *__pwc, const char *__pmb,\n                 size_t __max, mbstate_t *__ps, locale_t __loc) {\n  return mbrtowc(__pwc, __pmb, __max, __ps);\n}\n\nstruct lconv *localeconv_l(locale_t __l) {\n  return localeconv();\n}\n\n#endif // __sun__\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/support/win32/locale_win32.cpp",
    "content": "// -*- C++ -*-\n//===-------------------- support/win32/locale_win32.cpp ------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <locale>\n#include <cstdarg> // va_start, va_end\n\n// FIXME: base currently unused. Needs manual work to construct the new locale\nlocale_t newlocale( int mask, const char * locale, locale_t /*base*/ )\n{\n    return _create_locale( mask, locale );\n}\nlocale_t uselocale( locale_t newloc )\n{\n    locale_t old_locale = _get_current_locale();\n    if ( newloc == NULL )\n        return old_locale;\n    // uselocale sets the thread's locale by definition, so unconditionally use thread-local locale\n    _configthreadlocale( _ENABLE_PER_THREAD_LOCALE );\n    // uselocale sets all categories\n    setlocale( LC_ALL, newloc->locinfo->lc_category[LC_ALL].locale );\n    // uselocale returns the old locale_t\n    return old_locale;\n}\nlconv *localeconv_l( locale_t loc )\n{\n    __locale_raii __current( uselocale(loc), uselocale );\n    return localeconv();\n}\nsize_t mbrlen_l( const char *__restrict s, size_t n,\n                 mbstate_t *__restrict ps, locale_t loc )\n{\n    __locale_raii __current( uselocale(loc), uselocale );\n    return mbrlen( s, n, ps );\n}\nsize_t mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,\n                    size_t len, mbstate_t *__restrict ps, locale_t loc )\n{\n    __locale_raii __current( uselocale(loc), uselocale );\n    return mbsrtowcs( dst, src, len, ps );\n}\nsize_t wcrtomb_l( char *__restrict s, wchar_t wc, mbstate_t *__restrict ps,\n                  locale_t loc )\n{\n    __locale_raii __current( uselocale(loc), uselocale );\n    return wcrtomb( s, wc, ps );\n}\nsize_t mbrtowc_l( wchar_t *__restrict pwc, const char *__restrict s,\n                  size_t n, mbstate_t *__restrict ps, locale_t loc )\n{\n    __locale_raii __current( uselocale(loc), uselocale );\n    return mbrtowc( pwc, s, n, ps );\n}\nsize_t mbsnrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,\n                     size_t nms, size_t len, mbstate_t *__restrict ps, locale_t loc )\n{\n    __locale_raii __current( uselocale(loc), uselocale );\n    return mbsnrtowcs( dst, src, nms, len, ps );\n}\nsize_t wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src,\n                     size_t nwc, size_t len, mbstate_t *__restrict ps, locale_t loc )\n{\n    __locale_raii __current( uselocale(loc), uselocale );\n    return wcsnrtombs( dst, src, nwc, len, ps );\n}\nwint_t btowc_l( int c, locale_t loc )\n{\n    __locale_raii __current( uselocale(loc), uselocale );\n    return btowc( c );\n}\nint wctob_l( wint_t c, locale_t loc )\n{\n    __locale_raii __current( uselocale(loc), uselocale );\n    return wctob( c );\n}\n\nint snprintf_l(char *ret, size_t n, locale_t loc, const char *format, ...)\n{\n    __locale_raii __current( uselocale(loc), uselocale );\n    va_list ap;\n    va_start( ap, format );\n    int result = vsnprintf( ret, n, format, ap );\n    va_end(ap);\n    return result;\n}\n\nint asprintf_l( char **ret, locale_t loc, const char *format, ... )\n{\n    va_list ap;\n    va_start( ap, format );\n    int result = vasprintf_l( ret, loc, format, ap );\n    va_end(ap);\n    return result;\n}\nint vasprintf_l( char **ret, locale_t loc, const char *format, va_list ap )\n{\n    __locale_raii __current( uselocale(loc), uselocale );\n    return vasprintf( ret, format, ap );\n}\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/support/win32/support.cpp",
    "content": "// -*- C++ -*-\n//===----------------------- support/win32/support.h ----------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <cstdarg> // va_start, va_end\n#include <cstddef> // size_t\n#include <cstdlib> // malloc\n#include <cstdio>  // vsprintf, vsnprintf\n#include <cstring> // strcpy, wcsncpy\n#include <cwchar>  // mbstate_t\n\n// Some of these functions aren't standard or if they conform, the name does not.\n\nint asprintf(char **sptr, const char *__restrict format, ...)\n{\n    va_list ap;\n    va_start(ap, format);\n    int result;\n    result = vasprintf(sptr, format, ap);\n    va_end(ap);\n    return result;\n}\n\n// Like sprintf, but when return value >= 0 it returns\n// a pointer to a malloc'd string in *sptr.\n// If return >= 0, use free to delete *sptr.\nint vasprintf( char **sptr, const char *__restrict format, va_list ap )\n{\n    *sptr = NULL;\n    // Query the count required.\n    int count = _vsnprintf( NULL, 0, format, ap );\n    if (count < 0)\n        return count;\n    size_t buffer_size = static_cast<size_t>(count) + 1;\n    char* p = static_cast<char*>(malloc(buffer_size));\n    if ( ! p )\n        return -1;\n    // If we haven't used exactly what was required, something is wrong.\n    // Maybe bug in vsnprintf. Report the error and return.\n    if (_vsnprintf(p, buffer_size, format, ap) != count) {\n        free(p);\n        return -1;\n    }\n    // All good. This is returning memory to the caller not freeing it.\n    *sptr = p;\n    return count;\n}\n\n// Returns >= 0: the number of wide characters found in the \n// multi byte sequence src (of src_size_bytes), that fit in the buffer dst \n// (of max_dest_chars elements size). The count returned excludes the\n// null terminator. When dst is NULL, no characters are copied \n// and no \"out\" parameters are updated.\n// Returns (size_t) -1: an incomplete sequence encountered.\n// Leaves *src pointing the next character to convert or NULL \n// if a null character was converted from *src.\nsize_t mbsnrtowcs( wchar_t *__restrict dst, const char **__restrict src,\n                   size_t src_size_bytes, size_t max_dest_chars, mbstate_t *__restrict ps )\n{\n    const size_t terminated_sequence = static_cast<size_t>(0);\n    //const size_t invalid_sequence = static_cast<size_t>(-1);\n    const size_t incomplete_sequence = static_cast< size_t>(-2);\n\n    size_t dest_converted = 0;\n    size_t source_converted = 0;\n    size_t source_remaining = src_size_bytes;\n    size_t result = 0;\n    bool have_result = false;\n\n    while ( source_remaining ) {\n        if ( dst && dest_converted >= max_dest_chars )\n            break;\n        // Converts one multi byte character.\n        // if result > 0, it's the size in bytes of that character.\n        // othewise if result is zero it indicates the null character has been found.\n        // otherwise it's an error and errno may be set.\n        size_t char_size = mbrtowc( dst ? dst + dest_converted : NULL, *src + source_converted, source_remaining, ps );\n        // Don't do anything to change errno from here on.\n        if ( char_size > 0 ) {\n            source_remaining -= char_size;\n            source_converted += char_size;\n            ++dest_converted;\n            continue;\n        }\n        result = char_size;\n        have_result = true;\n        break;\n    }\n    if ( dst ) {\n        if ( have_result && result == terminated_sequence )\n            *src = NULL;\n        else\n            *src += source_converted;\n    }\n    if ( have_result && result != terminated_sequence && result != incomplete_sequence )\n        return static_cast<size_t>(-1);\n\n    return dest_converted;\n}\n\n// Converts max_source_chars from the wide character buffer pointer to by *src,\n// into the multi byte character sequence buffer stored at dst which must be\n// dst_size_bytes bytes in size.\n// Returns >= 0: the number of bytes in the sequence\n// converted from *src, excluding the null terminator.\n// Returns size_t(-1) if an error occurs, also sets errno.\n// If dst is NULL dst_size_bytes is ignored and no bytes are copied to dst \n// and no \"out\" parameters are updated.\nsize_t wcsnrtombs( char *__restrict dst, const wchar_t **__restrict src,\n                   size_t max_source_chars, size_t dst_size_bytes, mbstate_t *__restrict ps )\n{\n    //const size_t invalid_sequence = static_cast<size_t>(-1);\n\n    size_t source_converted = 0;\n    size_t dest_converted = 0;\n    size_t dest_remaining = dst_size_bytes;\n    size_t char_size = 0;\n    const errno_t no_error = ( errno_t) 0;\n    errno_t result = ( errno_t ) 0;\n    bool have_result = false;\n    bool terminator_found = false;\n\n    while ( source_converted != max_source_chars ) {\n        if ( ! dest_remaining )\n            break;\n        wchar_t c = (*src)[source_converted];\n        if ( dst )\n            result = wcrtomb_s( &char_size, dst + dest_converted, dest_remaining, c, ps);\n        else\n            result = wcrtomb_s( &char_size, NULL, 0, c, ps);\n        // If result is zero there is no error and char_size contains the \n        // size of the multi-byte-sequence converted.\n        // Otherwise result indicates an errno type error.\n        if ( result == no_error ) {\n            if ( c == L'\\0' ) {\n                terminator_found = true;\n                break;\n            }\n            ++source_converted;\n            if ( dst )\n                dest_remaining -= char_size;\n            dest_converted += char_size;\n            continue;\n        }\n        have_result = true;\n        break;\n    }\n    if ( dst ) {\n        if ( terminator_found )\n            *src = NULL;\n        else\n            *src = *src + source_converted;\n    }\n    if ( have_result && result != no_error ) {\n        errno = result;\n        return static_cast<size_t>(-1);\n    }\n\n    return dest_converted;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/system_error.cpp",
    "content": "//===---------------------- system_error.cpp ------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"__config\"\n\n#define _LIBCPP_BUILDING_SYSTEM_ERROR\n#include \"system_error\"\n\n#include \"config_elast.h\"\n#include \"cstring\"\n#include \"string\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\n// class error_category\n\nerror_category::error_category() _NOEXCEPT\n{\n}\n\nerror_category::~error_category() _NOEXCEPT\n{\n}\n\nerror_condition\nerror_category::default_error_condition(int ev) const _NOEXCEPT\n{\n    return error_condition(ev, *this);\n}\n\nbool\nerror_category::equivalent(int code, const error_condition& condition) const _NOEXCEPT\n{\n    return default_error_condition(code) == condition;\n}\n\nbool\nerror_category::equivalent(const error_code& code, int condition) const _NOEXCEPT\n{\n    return *this == code.category() && code.value() == condition;\n}\n\nstring\n__do_message::message(int ev) const\n{\n    return string(strerror(ev));\n}\n\nclass _LIBCPP_HIDDEN __generic_error_category\n    : public __do_message\n{\npublic:\n    virtual const char* name() const _NOEXCEPT;\n    virtual string message(int ev) const;\n};\n\nconst char*\n__generic_error_category::name() const _NOEXCEPT\n{\n    return \"generic\";\n}\n\nstring\n__generic_error_category::message(int ev) const\n{\n#ifdef _LIBCPP_ELAST\n    if (ev > _LIBCPP_ELAST)\n      return string(\"unspecified generic_category error\");\n#endif  // _LIBCPP_ELAST\n    return __do_message::message(ev);\n}\n\nconst error_category&\ngeneric_category() _NOEXCEPT\n{\n    static __generic_error_category s;\n    return s;\n}\n\nclass _LIBCPP_HIDDEN __system_error_category\n    : public __do_message\n{\npublic:\n    virtual const char* name() const _NOEXCEPT;\n    virtual string message(int ev) const;\n    virtual error_condition default_error_condition(int ev) const _NOEXCEPT;\n};\n\nconst char*\n__system_error_category::name() const _NOEXCEPT\n{\n    return \"system\";\n}\n\nstring\n__system_error_category::message(int ev) const\n{\n#ifdef _LIBCPP_ELAST\n    if (ev > _LIBCPP_ELAST)\n      return string(\"unspecified system_category error\");\n#endif  // _LIBCPP_ELAST\n    return __do_message::message(ev);\n}\n\nerror_condition\n__system_error_category::default_error_condition(int ev) const _NOEXCEPT\n{\n#ifdef _LIBCPP_ELAST\n    if (ev > _LIBCPP_ELAST)\n      return error_condition(ev, system_category());\n#endif  // _LIBCPP_ELAST\n    return error_condition(ev, generic_category());\n}\n\nconst error_category&\nsystem_category() _NOEXCEPT\n{\n    static __system_error_category s;\n    return s;\n}\n\n// error_condition\n\nstring\nerror_condition::message() const\n{\n    return __cat_->message(__val_);\n}\n\n// error_code\n\nstring\nerror_code::message() const\n{\n    return __cat_->message(__val_);\n}\n\n// system_error\n\nstring\nsystem_error::__init(const error_code& ec, string what_arg)\n{\n    if (ec)\n    {\n        if (!what_arg.empty())\n            what_arg += \": \";\n        what_arg += ec.message();\n    }\n    return what_arg;\n}\n\nsystem_error::system_error(error_code ec, const string& what_arg)\n    : runtime_error(__init(ec, what_arg)),\n      __ec_(ec)\n{\n}\n\nsystem_error::system_error(error_code ec, const char* what_arg)\n    : runtime_error(__init(ec, what_arg)),\n      __ec_(ec)\n{\n}\n\nsystem_error::system_error(error_code ec)\n    : runtime_error(__init(ec, \"\")),\n      __ec_(ec)\n{\n}\n\nsystem_error::system_error(int ev, const error_category& ecat, const string& what_arg)\n    : runtime_error(__init(error_code(ev, ecat), what_arg)),\n      __ec_(error_code(ev, ecat))\n{\n}\n\nsystem_error::system_error(int ev, const error_category& ecat, const char* what_arg)\n    : runtime_error(__init(error_code(ev, ecat), what_arg)),\n      __ec_(error_code(ev, ecat))\n{\n}\n\nsystem_error::system_error(int ev, const error_category& ecat)\n    : runtime_error(__init(error_code(ev, ecat), \"\")),\n      __ec_(error_code(ev, ecat))\n{\n}\n\nsystem_error::~system_error() _NOEXCEPT\n{\n}\n\nvoid\n__throw_system_error(int ev, const char* what_arg)\n{\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    throw system_error(error_code(ev, system_category()), what_arg);\n#else\n    (void)ev;\n    (void)what_arg;\n#endif\n}\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/thread.cpp",
    "content": "//===------------------------- thread.cpp----------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"__config\"\n#ifndef _LIBCPP_HAS_NO_THREADS\n\n#include \"thread\"\n#include \"exception\"\n#include \"vector\"\n#include \"future\"\n#include \"limits\"\n#include <sys/types.h>\n#if !defined(_WIN32)\n# if !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) && !defined(__CloudABI__)\n#   include <sys/sysctl.h>\n# endif // !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) && !defined(__CloudABI__)\n# include <unistd.h>\n#endif // !_WIN32\n\n#if defined(__NetBSD__)\n#pragma weak pthread_create // Do not create libpthread dependency\n#endif\n#if defined(_WIN32)\n#include <windows.h>\n#endif\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nthread::~thread()\n{\n    if (__t_ != 0)\n        terminate();\n}\n\nvoid\nthread::join()\n{\n    int ec = pthread_join(__t_, 0);\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (ec)\n        throw system_error(error_code(ec, system_category()), \"thread::join failed\");\n#else\n    (void)ec;\n#endif  // _LIBCPP_NO_EXCEPTIONS\n    __t_ = 0;\n}\n\nvoid\nthread::detach()\n{\n    int ec = EINVAL;\n    if (__t_ != 0)\n    {\n        ec = pthread_detach(__t_);\n        if (ec == 0)\n            __t_ = 0;\n    }\n#ifndef _LIBCPP_NO_EXCEPTIONS\n    if (ec)\n        throw system_error(error_code(ec, system_category()), \"thread::detach failed\");\n#endif  // _LIBCPP_NO_EXCEPTIONS\n}\n\nunsigned\nthread::hardware_concurrency() _NOEXCEPT\n{\n#if defined(CTL_HW) && defined(HW_NCPU)\n    unsigned n;\n    int mib[2] = {CTL_HW, HW_NCPU};\n    std::size_t s = sizeof(n);\n    sysctl(mib, 2, &n, &s, 0, 0);\n    return n;\n#elif defined(_SC_NPROCESSORS_ONLN)\n    long result = sysconf(_SC_NPROCESSORS_ONLN);\n    // sysconf returns -1 if the name is invalid, the option does not exist or\n    // does not have a definite limit.\n    // if sysconf returns some other negative number, we have no idea\n    // what is going on. Default to something safe.\n    if (result < 0)\n        return 0;\n    return static_cast<unsigned>(result);\n#elif defined(_WIN32)\n    SYSTEM_INFO info;\n    GetSystemInfo(&info);\n    return info.dwNumberOfProcessors;\n#else  // defined(CTL_HW) && defined(HW_NCPU)\n    // TODO: grovel through /proc or check cpuid on x86 and similar\n    // instructions on other architectures.\n#   if defined(_MSC_VER) && ! defined(__clang__)\n        _LIBCPP_WARNING(\"hardware_concurrency not yet implemented\")\n#   else\n#       warning hardware_concurrency not yet implemented\n#   endif\n    return 0;  // Means not computable [thread.thread.static]\n#endif  // defined(CTL_HW) && defined(HW_NCPU)\n}\n\nnamespace this_thread\n{\n\nvoid\nsleep_for(const chrono::nanoseconds& ns)\n{\n    using namespace chrono;\n    if (ns > nanoseconds::zero())\n    {\n        seconds s = duration_cast<seconds>(ns);\n        timespec ts;\n        typedef decltype(ts.tv_sec) ts_sec;\n        _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max();\n        if (s.count() < ts_sec_max)\n        {\n            ts.tv_sec = static_cast<ts_sec>(s.count());\n            ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((ns-s).count());\n        }\n        else\n        {\n            ts.tv_sec = ts_sec_max;\n            ts.tv_nsec = giga::num - 1;\n        }\n\n        while (nanosleep(&ts, &ts) == -1 && errno == EINTR)\n            ;\n    }\n}\n\n}  // this_thread\n\n__thread_specific_ptr<__thread_struct>&\n__thread_local_data()\n{\n    static __thread_specific_ptr<__thread_struct> __p;\n    return __p;\n}\n\n// __thread_struct_imp\n\ntemplate <class T>\nclass _LIBCPP_HIDDEN __hidden_allocator\n{\npublic:\n    typedef T  value_type;\n    \n    T* allocate(size_t __n)\n        {return static_cast<T*>(::operator new(__n * sizeof(T)));}\n    void deallocate(T* __p, size_t) {::operator delete(static_cast<void*>(__p));}\n\n    size_t max_size() const {return size_t(~0) / sizeof(T);}\n};\n\nclass _LIBCPP_HIDDEN __thread_struct_imp\n{\n    typedef vector<__assoc_sub_state*,\n                          __hidden_allocator<__assoc_sub_state*> > _AsyncStates;\n    typedef vector<pair<condition_variable*, mutex*>,\n               __hidden_allocator<pair<condition_variable*, mutex*> > > _Notify;\n\n    _AsyncStates async_states_;\n    _Notify notify_;\n\n    __thread_struct_imp(const __thread_struct_imp&);\n    __thread_struct_imp& operator=(const __thread_struct_imp&);\npublic:\n    __thread_struct_imp() {}\n    ~__thread_struct_imp();\n\n    void notify_all_at_thread_exit(condition_variable* cv, mutex* m);\n    void __make_ready_at_thread_exit(__assoc_sub_state* __s);\n};\n\n__thread_struct_imp::~__thread_struct_imp()\n{\n    for (_Notify::iterator i = notify_.begin(), e = notify_.end();\n            i != e; ++i)\n    {\n        i->second->unlock();\n        i->first->notify_all();\n    }\n    for (_AsyncStates::iterator i = async_states_.begin(), e = async_states_.end();\n            i != e; ++i)\n    {\n        (*i)->__make_ready();\n        (*i)->__release_shared();\n    }\n}\n\nvoid\n__thread_struct_imp::notify_all_at_thread_exit(condition_variable* cv, mutex* m)\n{\n    notify_.push_back(pair<condition_variable*, mutex*>(cv, m));\n}\n\nvoid\n__thread_struct_imp::__make_ready_at_thread_exit(__assoc_sub_state* __s)\n{\n    async_states_.push_back(__s);\n    __s->__add_shared();\n}\n\n// __thread_struct\n\n__thread_struct::__thread_struct()\n    : __p_(new __thread_struct_imp)\n{\n}\n\n__thread_struct::~__thread_struct()\n{\n    delete __p_;\n}\n\nvoid\n__thread_struct::notify_all_at_thread_exit(condition_variable* cv, mutex* m)\n{\n    __p_->notify_all_at_thread_exit(cv, m);\n}\n\nvoid\n__thread_struct::__make_ready_at_thread_exit(__assoc_sub_state* __s)\n{\n    __p_->__make_ready_at_thread_exit(__s);\n}\n\n_LIBCPP_END_NAMESPACE_STD\n\n#endif // !_LIBCPP_HAS_NO_THREADS\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/typeinfo.cpp",
    "content": "//===------------------------- typeinfo.cpp -------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n#include <stdlib.h>\n\n#ifndef __has_include\n#define __has_include(inc) 0\n#endif\n\n#ifdef __APPLE__\n#include <cxxabi.h>\n#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>)\n#include <cxxabi.h>\n#endif\n\n#include \"typeinfo\"\n\n#if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)\n\nstd::bad_cast::bad_cast() _NOEXCEPT\n{\n}\n\nstd::bad_typeid::bad_typeid() _NOEXCEPT\n{\n}\n\n#ifndef __GLIBCXX__\n\nstd::bad_cast::~bad_cast() _NOEXCEPT\n{\n}\n\nconst char*\nstd::bad_cast::what() const _NOEXCEPT\n{\n  return \"std::bad_cast\";\n}\n\nstd::bad_typeid::~bad_typeid() _NOEXCEPT\n{\n}\n\nconst char*\nstd::bad_typeid::what() const _NOEXCEPT\n{\n  return \"std::bad_typeid\";\n}\n\n#ifdef __APPLE__\n  // On Darwin, the cxa_bad_* functions cannot be in the lower level library\n  // because bad_cast and bad_typeid are defined in his higher level library\n  void __cxxabiv1::__cxa_bad_typeid()\n  {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n     throw std::bad_typeid();\n#endif\n  }\n  void __cxxabiv1::__cxa_bad_cast()\n  {\n#ifndef _LIBCPP_NO_EXCEPTIONS\n      throw std::bad_cast();\n#endif\n  }\n#endif\n\n#endif  // !__GLIBCXX__\n#endif  // !LIBCXXRT && !_LIBCPPABI_VERSION\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/utility.cpp",
    "content": "//===------------------------ utility.cpp ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define _LIBCPP_BUILDING_UTILITY\n#include \"utility\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\nconst piecewise_construct_t piecewise_construct = {};\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/src/valarray.cpp",
    "content": "//===------------------------ valarray.cpp --------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#undef _LIBCPP_EXTERN_TEMPLATE\n#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;\n\n#include \"valarray\"\n\n_LIBCPP_BEGIN_NAMESPACE_STD\n\ntemplate valarray<size_t>::valarray(size_t);\ntemplate valarray<size_t>::~valarray();\ntemplate void valarray<size_t>::resize(size_t, size_t);\n\nvoid\ngslice::__init(size_t __start)\n{\n    valarray<size_t> __indices(__size_.size());\n    size_t __k = __size_.size() != 0;\n    for (size_t __i = 0; __i < __size_.size(); ++__i)\n        __k *= __size_[__i];\n    __1d_.resize(__k);\n    if (__1d_.size())\n    {\n        __k = 0;\n        __1d_[__k] = __start;\n        while (true)\n        {\n            size_t __i = __indices.size() - 1;\n            while (true)\n            {\n                if (++__indices[__i] < __size_[__i])\n                {\n                    ++__k;\n                    __1d_[__k] = __1d_[__k-1] + __stride_[__i];\n                    for (size_t __j = __i + 1; __j != __indices.size(); ++__j)\n                        __1d_[__k] -= __stride_[__j] * (__size_[__j] - 1);\n                    break;\n                }\n                else\n                {\n                    if (__i == 0)\n                        return;\n                    __indices[__i--] = 0;\n                }\n            }\n        }\n    }\n}\n\n_LIBCPP_END_NAMESPACE_STD\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/test.mk",
    "content": ".NOTPARALLEL:\ndefault:\n\tpython $(LIT) -sv --param android_mode=$(LIT_MODE) $(LIT_ARGS) \\\n        $(ANDROID_BUILD_TOP)/external/libcxx/test\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/utils/not/not.py",
    "content": "\"\"\"not.py is a utility for inverting the return code of commands.\nIt acts similar to llvm/utils/not.\nex: python /path/to/not.py ' echo hello\n    echo $? // (prints 1)\n\"\"\"\n\nimport distutils.spawn\nimport subprocess\nimport sys\n\n\ndef main():\n    argv = list(sys.argv)\n    del argv[0]\n    if len(argv) > 0 and argv[0] == '--crash':\n        del argv[0]\n        expectCrash = True\n    else:\n        expectCrash = False\n    if len(argv) == 0:\n        return 1\n    prog = distutils.spawn.find_executable(argv[0])\n    if prog is None:\n        sys.stderr.write('Failed to find program %s' % argv[0])\n        return 1\n    rc = subprocess.call(argv)\n    if rc < 0:\n        return 0 if expectCrash else 1\n    if expectCrash:\n        return 1\n    return rc == 0\n\n\nif __name__ == '__main__':\n    exit(main())\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/utils/sym_check/linux_blacklist.txt",
    "content": "# all guard variables\n_ZGVNSt3__\n# all vtables\n_ZTV\n# all VTT\n_ZTT\n# all non-virtual thunks\n_ZTh\n# all virtual thunks\n_ZTv\n# typeinfo for std::__1::__types\n#    There are no std::__types\n_ZTINSt3__1[0-9][0-9]*__\n# typeinfo name for std::__1::__types\n_ZTSNSt3__1[0-9][0-9]*__\n# anything using __hidden_allocator\n.*__hidden_allocator\n# anything using __sso_allocator\n.*__sso_allocator\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/utils/sym_check/osx_blacklist.txt",
    "content": "# all guard variables\n__ZGVNSt3__\n# all vtables\n__ZTV\n# all VTT\n__ZTT\n# all non-virtual thunks\n__ZTh\n# all virtual thunks\n__ZTv\n# typeinfo for std::__1::__types\n#    There are no std::__types\n__ZTINSt3__1[0-9][0-9]*__\n# typeinfo name for std::__1::__types\n__ZTSNSt3__1[0-9][0-9]*__\n# anything using __hidden_allocator\n.*__hidden_allocator\n# anything using __sso_allocator\n.*__sso_allocator\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/utils/sym_check/sym_check/__init__.py",
    "content": "\"\"\"libcxx abi symbol checker\"\"\"\n\n__author__ = 'Eric Fiselier'\n__email__ = 'eric@efcs.ca'\n__versioninfo__ = (0, 1, 0)\n__version__ = ' '.join(str(v) for v in __versioninfo__) + 'dev'\n\n__all__ = ['diff', 'extract', 'util']\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/utils/sym_check/sym_check/diff.py",
    "content": "# -*- Python -*- vim: set syntax=python tabstop=4 expandtab cc=80:\n\"\"\"\ndiff - A set of functions for diff-ing two symbol lists.\n\"\"\"\n\nfrom sym_check import util\n\n\ndef _symbol_difference(lhs, rhs):\n    lhs_names = set((n['name'] for n in lhs))\n    rhs_names = set((n['name'] for n in rhs))\n    diff_names = lhs_names - rhs_names\n    return [n for n in lhs if n['name'] in diff_names]\n\n\ndef _find_by_key(sym_list, k):\n    for sym in sym_list:\n        if sym['name'] == k:\n            return sym\n    return None\n\n\ndef added_symbols(old, new):\n    return _symbol_difference(new, old)\n\n\ndef removed_symbols(old, new):\n    return _symbol_difference(old, new)\n\n\ndef changed_symbols(old, new):\n    changed = []\n    for old_sym in old:\n        if old_sym in new:\n            continue\n        new_sym = _find_by_key(new, old_sym['name'])\n        if (new_sym is not None and not new_sym in old\n                and cmp(old_sym, new_sym) != 0):\n            changed += [(old_sym, new_sym)]\n    return changed\n\n\ndef diff(old, new):\n    added = added_symbols(old, new)\n    removed = removed_symbols(old, new)\n    changed = changed_symbols(old, new)\n    return added, removed, changed\n\n\ndef report_diff(added_syms, removed_syms, changed_syms, names_only=False,\n                demangle=True):\n    def maybe_demangle(name):\n        return util.demangle_symbol(name) if demangle else name\n\n    report = ''\n    for sym in added_syms:\n        report += 'Symbol added: %s\\n' % maybe_demangle(sym['name'])\n        if not names_only:\n            report += '    %s\\n\\n' % sym\n    if added_syms and names_only:\n        report += '\\n'\n    for sym in removed_syms:\n        report += 'SYMBOL REMOVED: %s\\n' % maybe_demangle(sym['name'])\n        if not names_only:\n            report += '    %s\\n\\n' % sym\n    if removed_syms and names_only:\n        report += '\\n'\n    if not names_only:\n        for sym_pair in changed_syms:\n            old_sym, new_sym = sym_pair\n            old_str = '\\n    OLD SYMBOL: %s' % old_sym\n            new_str = '\\n    NEW SYMBOL: %s' % new_sym\n            report += ('SYMBOL CHANGED: %s%s%s\\n\\n' %\n                       (maybe_demangle(old_sym['name']),\n                        old_str, new_str))\n\n    added = bool(len(added_syms) != 0)\n    abi_break = bool(len(removed_syms))\n    if not names_only:\n        abi_break = abi_break or len(changed_syms)\n    if added or abi_break:\n        report += 'Summary\\n'\n        report += '    Added:   %d\\n' % len(added_syms)\n        report += '    Removed: %d\\n' % len(removed_syms)\n        if not names_only:\n            report += '    Changed: %d\\n' % len(changed_syms)\n        if not abi_break:\n            report += 'Symbols added.'\n        else:\n            report += 'ABI BREAKAGE: SYMBOLS ADDED OR REMOVED!'\n    else:\n        report += 'Symbols match.'\n    return report, int(abi_break)\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/utils/sym_check/sym_check/extract.py",
    "content": "# -*- Python -*- vim: set syntax=python tabstop=4 expandtab cc=80:\n\"\"\"\nextract - A set of function that extract symbol lists from shared libraries.\n\"\"\"\nimport distutils.spawn\nimport sys\n\nfrom sym_check import util\n\n\nclass NMExtractor(object):\n    \"\"\"\n    NMExtractor - Extract symbol lists from libraries using nm.\n    \"\"\"\n\n    @staticmethod\n    def find_tool():\n        \"\"\"\n        Search for the nm executable and return the path.\n        \"\"\"\n        return distutils.spawn.find_executable('nm')\n\n    def __init__(self):\n        \"\"\"\n        Initialize the nm executable and flags that will be used to extract\n        symbols from shared libraries.\n        \"\"\"\n        self.nm_exe = self.find_tool()\n        if self.nm_exe is None:\n            # ERROR no NM found\n            print(\"ERROR: Could not find nm\")\n            sys.exit(1)\n        self.flags = ['-P', '-g']\n\n    def extract(self, lib):\n        \"\"\"\n        Extract symbols from a library and return the results as a dict of\n        parsed symbols.\n        \"\"\"\n        cmd = [self.nm_exe] + self.flags + [lib]\n        out, _, exit_code = util.execute_command_verbose(cmd)\n        if exit_code != 0:\n            raise RuntimeError('Failed to run %s on %s' % (self.nm_exe, lib))\n        fmt_syms = (self._extract_sym(l)\n                    for l in out.splitlines() if l.strip())\n            # Cast symbol to string.\n        final_syms = (repr(s) for s in fmt_syms if self._want_sym(s))\n        # Make unique and sort strings.\n        tmp_list = list(sorted(set(final_syms)))\n        # Cast string back to symbol.\n        return util.read_syms_from_list(tmp_list)\n\n    def _extract_sym(self, sym_str):\n        bits = sym_str.split()\n        # Everything we want has at least two columns.\n        if len(bits) < 2:\n            return None\n        new_sym = {\n            'name': bits[0],\n            'type': bits[1]\n        }\n        new_sym['name'] = new_sym['name'].replace('@@', '@')\n        new_sym = self._transform_sym_type(new_sym)\n        # NM types which we want to save the size for.\n        if new_sym['type'] == 'OBJECT' and len(bits) > 3:\n            new_sym['size'] = int(bits[3], 16)\n        return new_sym\n\n    @staticmethod\n    def _want_sym(sym):\n        \"\"\"\n        Check that s is a valid symbol that we want to keep.\n        \"\"\"\n        if sym is None or len(sym) < 2:\n            return False\n        bad_types = ['t', 'b', 'r', 'd', 'w']\n        return (sym['type'] not in bad_types\n                and sym['name'] not in ['__bss_start', '_end', '_edata'])\n\n    @staticmethod\n    def _transform_sym_type(sym):\n        \"\"\"\n        Map the nm single letter output for type to either FUNC or OBJECT.\n        If the type is not recognized it is left unchanged.\n        \"\"\"\n        func_types = ['T', 'W']\n        obj_types = ['B', 'D', 'R', 'V', 'S']\n        if sym['type'] in func_types:\n            sym['type'] = 'FUNC'\n        elif sym['type'] in obj_types:\n            sym['type'] = 'OBJECT'\n        return sym\n\nclass ReadElfExtractor(object):\n    \"\"\"\n    ReadElfExtractor - Extract symbol lists from libraries using readelf.\n    \"\"\"\n\n    @staticmethod\n    def find_tool():\n        \"\"\"\n        Search for the readelf executable and return the path.\n        \"\"\"\n        return distutils.spawn.find_executable('readelf')\n\n    def __init__(self):\n        \"\"\"\n        Initialize the readelf executable and flags that will be used to\n        extract symbols from shared libraries.\n        \"\"\"\n        self.tool = self.find_tool()\n        if self.tool is None:\n            # ERROR no NM found\n            print(\"ERROR: Could not find readelf\")\n            sys.exit(1)\n        self.flags = ['--wide', '--symbols']\n\n    def extract(self, lib):\n        \"\"\"\n        Extract symbols from a library and return the results as a dict of\n        parsed symbols.\n        \"\"\"\n        cmd = [self.tool] + self.flags + [lib]\n        out, _, exit_code = util.execute_command_verbose(cmd)\n        if exit_code != 0:\n            raise RuntimeError('Failed to run %s on %s' % (self.nm_exe, lib))\n        dyn_syms = self.get_dynsym_table(out)\n        return self.process_syms(dyn_syms)\n\n    def process_syms(self, sym_list):\n        new_syms = []\n        for s in sym_list:\n            parts = s.split()\n            if not parts:\n                continue\n            assert len(parts) == 7 or len(parts) == 8 or len(parts) == 9\n            if len(parts) == 7:\n                continue\n            new_sym = {\n                'name': parts[7],\n                'size': int(parts[2]),\n                'type': parts[3],\n            }\n            assert new_sym['type'] in ['OBJECT', 'FUNC', 'NOTYPE']\n            if new_sym['type'] == 'NOTYPE':\n                continue\n            if new_sym['type'] == 'FUNC':\n                del new_sym['size']\n            new_syms += [new_sym]\n        return new_syms\n\n    def get_dynsym_table(self, out):\n        lines = out.splitlines()\n        start = -1\n        end = -1\n        for i in range(len(lines)):\n            if lines[i].startswith(\"Symbol table '.dynsym'\"):\n                start = i + 2\n            if start != -1 and end == -1 and not lines[i].strip():\n                end = i + 1\n        assert start != -1\n        if end == -1:\n            end = len(lines)\n        return lines[start:end]\n\n\ndef extract_symbols(lib_file):\n    \"\"\"\n    Extract and return a list of symbols extracted from a dynamic library.\n    The symbols are extracted using NM. They are then filtered and formated.\n    Finally they symbols are made unique.\n    \"\"\"\n    if ReadElfExtractor.find_tool():\n        extractor = ReadElfExtractor()\n    else:\n        extractor = NMExtractor()\n    return extractor.extract(lib_file)\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/utils/sym_check/sym_check/match.py",
    "content": "# -*- Python -*- vim: set syntax=python tabstop=4 expandtab cc=80:\n\"\"\"\nmatch - A set of functions for matching symbols in a list to a list of regexs\n\"\"\"\n\nimport re\n\n\ndef find_and_report_matching(symbol_list, regex_list):\n    report = ''\n    found_count = 0\n    for regex_str in regex_list:\n        report += 'Matching regex \"%s\":\\n' % regex_str\n        matching_list = find_matching_symbols(symbol_list, regex_str)\n        if not matching_list:\n            report += '    No matches found\\n\\n'\n            continue\n        # else\n        found_count += len(matching_list)\n        for m in matching_list:\n            report += '    MATCHES: %s\\n' % m['name']\n        report += '\\n'\n    return found_count, report\n\n\ndef find_matching_symbols(symbol_list, regex_str):\n    regex = re.compile(regex_str)\n    matching_list = []\n    for s in symbol_list:\n        if regex.match(s['name']):\n            matching_list += [s]\n    return matching_list\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/utils/sym_check/sym_check/util.py",
    "content": "import ast\nimport distutils.spawn\nimport signal\nimport subprocess\nimport sys\n\n\ndef execute_command(cmd, input_str=None):\n    \"\"\"\n    Execute a command, capture and return its output.\n    \"\"\"\n    kwargs = {\n        'stdin': subprocess.PIPE,\n        'stdout': subprocess.PIPE,\n        'stderr': subprocess.PIPE,\n    }\n    p = subprocess.Popen(cmd, **kwargs)\n    out, err = p.communicate(input=input_str)\n    exitCode = p.wait()\n    if exitCode == -signal.SIGINT:\n        raise KeyboardInterrupt\n    return out, err, exitCode\n\n\ndef execute_command_verbose(cmd, input_str=None):\n    \"\"\"\n    Execute a command and print its output on failure.\n    \"\"\"\n    out, err, exitCode = execute_command(cmd, input_str=input_str)\n    if exitCode != 0:\n        report = \"Command: %s\\n\" % ' '.join([\"'%s'\" % a for a in cmd])\n        report += \"Exit Code: %d\\n\" % exitCode\n        if out:\n            report += \"Standard Output:\\n--\\n%s--\" % out\n        if err:\n            report += \"Standard Error:\\n--\\n%s--\" % err\n        report += \"\\n\\nFailed!\"\n        sys.stderr.write('%s\\n' % report)\n    return out, err, exitCode\n\n\ndef read_syms_from_list(slist):\n    \"\"\"\n    Read a list of symbols from a list of strings.\n    Each string is one symbol.\n    \"\"\"\n    return [ast.literal_eval(l) for l in slist]\n\n\ndef read_syms_from_file(filename):\n    \"\"\"\n    Read a list of symbols in from a file.\n    \"\"\"\n    with open(filename, 'r') as f:\n        data = f.read()\n    return read_syms_from_list(data.splitlines())\n\n\ndef read_blacklist(filename):\n    with open(filename, 'r') as f:\n        data = f.read()\n    lines = [l.strip() for l in data.splitlines() if l.strip()]\n    lines = [l for l in lines if not l.startswith('#')]\n    return lines\n\n\ndef write_syms(sym_list, out=None, names_only=False):\n    \"\"\"\n    Write a list of symbols to the file named by out.\n    \"\"\"\n    out_str = ''\n    out_list = sym_list\n    if names_only:\n        out_list = [sym['name'] for sym in sym_list]\n        out_list.sort()\n    for sym in out_list:\n        out_str += '%s\\n' % sym\n    if out is None:\n        sys.stdout.write(out_str)\n    else:\n        with open(out, 'w') as f:\n            f.write(out_str)\n\n\n_cppfilt_exe = distutils.spawn.find_executable('c++filt')\n\n\ndef demangle_symbol(symbol):\n    if _cppfilt_exe is None:\n        return symbol\n    out, _, exit_code = execute_command_verbose(\n        [_cppfilt_exe], input_str=symbol)\n    if exit_code != 0:\n        return symbol\n    return out\n\n\ndef is_elf(filename):\n    with open(filename, 'r') as f:\n        magic_bytes = f.read(4)\n    return magic_bytes == '\\x7fELF'\n\n\ndef is_mach_o(filename):\n    with open(filename, 'r') as f:\n        magic_bytes = f.read(4)\n    return magic_bytes in [\n        '\\xfe\\xed\\xfa\\xce',  # MH_MAGIC\n        '\\xce\\xfa\\xed\\xfe',  # MH_CIGAM\n        '\\xfe\\xed\\xfa\\xcf',  # MH_MAGIC_64\n        '\\xcf\\xfa\\xed\\xfe',  # MH_CIGAM_64\n        '\\xca\\xfe\\xba\\xbe',  # FAT_MAGIC\n        '\\xbe\\xba\\xfe\\xca'   # FAT_CIGAM\n    ]\n\n\ndef is_library_file(filename):\n    if sys.platform == 'darwin':\n        return is_mach_o(filename)\n    else:\n        return is_elf(filename)\n\n\ndef extract_or_load(filename):\n    import sym_check.extract\n    if is_library_file(filename):\n        return sym_check.extract.extract_symbols(filename)\n    return read_syms_from_file(filename)\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/utils/sym_check/sym_diff.py",
    "content": "#!/usr/bin/env python\n\"\"\"\nsym_diff - Compare two symbol lists and output the differences.\n\"\"\"\nfrom argparse import ArgumentParser\nimport sys\nfrom sym_check import diff, util\n\n\ndef main():\n    parser = ArgumentParser(\n        description='Extract a list of symbols from a shared library.')\n    parser.add_argument(\n        '--names-only', dest='names_only',\n        help='Only print symbol names',\n        action='store_true', default=False)\n    parser.add_argument(\n        '-o', '--output', dest='output',\n        help='The output file. stdout is used if not given',\n        type=str, action='store', default=None)\n    parser.add_argument(\n        '--demangle', dest='demangle', action='store_true', default=False)\n    parser.add_argument(\n        'old_syms', metavar='old-syms', type=str,\n        help='The file containing the old symbol list or a library')\n    parser.add_argument(\n        'new_syms', metavar='new-syms', type=str,\n        help='The file containing the new symbol list or a library')\n    args = parser.parse_args()\n\n    old_syms_list = util.extract_or_load(args.old_syms)\n    new_syms_list = util.extract_or_load(args.new_syms)\n\n    added, removed, changed = diff.diff(old_syms_list, new_syms_list)\n    report, is_break = diff.report_diff(added, removed, changed,\n                                        names_only=args.names_only,\n                                        demangle=args.demangle)\n    if args.output is None:\n        print(report)\n    else:\n        with open(args.output, 'w') as f:\n            f.write(report + '\\n')\n    sys.exit(is_break)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/utils/sym_check/sym_extract.py",
    "content": "#!/usr/bin/env python\n\"\"\"\nsym_extract - Extract and output a list of symbols from a shared library.\n\"\"\"\nfrom argparse import ArgumentParser\nfrom sym_check import extract, util\n\n\ndef main():\n    parser = ArgumentParser(\n        description='Extract a list of symbols from a shared library.')\n    parser.add_argument('library', metavar='shared-lib', type=str,\n                        help='The library to extract symbols from')\n    parser.add_argument('-o', '--output', dest='output',\n                        help='The output file. stdout is used if not given',\n                        type=str, action='store', default=None)\n    parser.add_argument('--names-only', dest='names_only',\n                        help='Output only the name of the symbol',\n                        action='store_true', default=False)\n    args = parser.parse_args()\n    if args.output is not None:\n        print('Extracting symbols from %s to %s.'\n              % (args.library, args.output))\n    syms = extract.extract_symbols(args.library)\n    util.write_syms(syms, out=args.output, names_only=args.names_only)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "atlas-aapt/external/libcxx/utils/sym_check/sym_match.py",
    "content": "#!/usr/bin/env python\n\"\"\"\nsym_match - Match all symbols in a list against a list of regexes.\n\"\"\"\nfrom argparse import ArgumentParser\nimport sys\nfrom sym_check import util, match, extract\n\n\ndef main():\n    parser = ArgumentParser(\n        description='Extract a list of symbols from a shared library.')\n    parser.add_argument(\n        '--blacklist', dest='blacklist',\n        type=str, action='store', default=None)\n    parser.add_argument(\n        'symbol_list', metavar='symbol_list', type=str,\n        help='The file containing the old symbol list')\n    parser.add_argument(\n        'regexes', metavar='regexes', default=[], nargs='*',\n        help='The file containing the new symbol list or a library')\n    args = parser.parse_args()\n\n    if not args.regexes and args.blacklist is None:\n        sys.stderr.write('Either a regex or a blacklist must be specified.\\n')\n        sys.exit(1)\n    if args.blacklist:\n        search_list = util.read_blacklist(args.blacklist)\n    else:\n        search_list = args.regexes\n\n    symbol_list = util.extract_or_load(args.symbol_list)\n\n    matching_count, report = match.find_and_report_matching(\n        symbol_list, search_list)\n    sys.stdout.write(report)\n    if matching_count != 0:\n        print('%d matching symbols found...' % matching_count)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/.arcconfig",
    "content": "{\n  \"project_id\" : \"libcxxabi\",\n  \"conduit_uri\" : \"http://reviews.llvm.org/\"\n}\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/.gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nenv/\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n#lib/ # We actually have things checked in to lib/\nlib64/\nparts/\nsdist/\nvar/\n*.egg-info/\n.installed.cfg\n*.egg\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.coverage\n.cache\nnosetests.xml\ncoverage.xml\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/Android.bp",
    "content": "//\n// Copyright (C) 2014 The Android Open Source Project\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\ncc_library_static {\n    name: \"libc++abi\",\n    host_supported: true,\n    clang: true,\n    srcs: [\n        \"src/abort_message.cpp\",\n        \"src/cxa_aux_runtime.cpp\",\n        \"src/cxa_default_handlers.cpp\",\n        \"src/cxa_demangle.cpp\",\n        \"src/cxa_exception.cpp\",\n        \"src/cxa_exception_storage.cpp\",\n        \"src/cxa_guard.cpp\",\n        \"src/cxa_handlers.cpp\",\n        \"src/cxa_new_delete.cpp\",\n        \"src/cxa_personality.cpp\",\n        \"src/cxa_thread_atexit.cpp\",\n        \"src/cxa_unexpected.cpp\",\n        \"src/cxa_vector.cpp\",\n        \"src/cxa_virtual.cpp\",\n        \"src/exception.cpp\",\n        \"src/private_typeinfo.cpp\",\n        \"src/stdexcept.cpp\",\n        \"src/typeinfo.cpp\",\n    ],\n    include_dirs: [\"external/libcxx/include\"],\n    local_include_dirs:  [\"include\"],\n    export_include_dirs: [\"include\"],\n    cppflags: [\n        \"-std=c++14\",\n        \"-fexceptions\",\n        \"-Wall\",\n        \"-Wextra\",\n        \"-Wno-unused-function\",\n        \"-Werror\",\n    ],\n    sanitize: [\"never\"],\n    stl: \"none\",\n    rtti: true,\n    arch: {\n        arm: {\n            include_dirs: [\"external/libunwind_llvm/include\"],\n            cppflags: [\"-DLIBCXXABI_USE_LLVM_UNWINDER=1\"],\n        },\n        arm64: {\n            cppflags: [\"-DLIBCXXABI_USE_LLVM_UNWINDER=0\"],\n        },\n        mips: {\n            cppflags: [\"-DLIBCXXABI_USE_LLVM_UNWINDER=0\"],\n        },\n        mips64: {\n            cppflags: [\"-DLIBCXXABI_USE_LLVM_UNWINDER=0\"],\n        },\n        x86: {\n            cppflags: [\"-DLIBCXXABI_USE_LLVM_UNWINDER=0\"],\n        },\n        x86_64: {\n            cppflags: [\"-DLIBCXXABI_USE_LLVM_UNWINDER=0\"],\n        },\n    },\n    target: {\n        android: {\n            cppflags: [\"-DHAVE___CXA_THREAD_ATEXIT_IMPL\"],\n        },\n        darwin: {\n            // libcxxabi really doesn't like the non-LLVM assembler on Darwin\n            asflags: [\"-integrated-as\"],\n            cflags: [\"-integrated-as\"],\n            cppflags: [\"-integrated-as\"],\n        },\n    },\n\n}\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/Android.mk",
    "content": "#\n# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\nLOCAL_PATH := $(call my-dir)\n\nLIBCXXABI_SRC_FILES := \\\n    src/abort_message.cpp \\\n    src/cxa_aux_runtime.cpp \\\n    src/cxa_default_handlers.cpp \\\n    src/cxa_demangle.cpp \\\n    src/cxa_exception.cpp \\\n    src/cxa_exception_storage.cpp \\\n    src/cxa_guard.cpp \\\n    src/cxa_handlers.cpp \\\n    src/cxa_new_delete.cpp \\\n    src/cxa_personality.cpp \\\n    src/cxa_thread_atexit.cpp \\\n    src/cxa_unexpected.cpp \\\n    src/cxa_vector.cpp \\\n    src/cxa_virtual.cpp \\\n    src/exception.cpp \\\n    src/private_typeinfo.cpp \\\n    src/stdexcept.cpp \\\n    src/typeinfo.cpp \\\n\nLIBCXXABI_INCLUDES := \\\n    $(LOCAL_PATH)/include \\\n    external/libcxx/include \\\n\nLIBCXXABI_RTTI_FLAG := -frtti\nLIBCXXABI_CPPFLAGS := \\\n    -std=c++14 \\\n    -fexceptions \\\n    -Wall \\\n    -Wextra \\\n    -Wno-unused-function \\\n    -Werror \\\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libc++abi\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := $(LIBCXXABI_SRC_FILES)\nLOCAL_C_INCLUDES := $(LIBCXXABI_INCLUDES)\nLOCAL_C_INCLUDES_arm := external/libunwind_llvm/include\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include\nLOCAL_CPPFLAGS := $(LIBCXXABI_CPPFLAGS) -DHAVE___CXA_THREAD_ATEXIT_IMPL\nLOCAL_CPPFLAGS_arm := -DLIBCXXABI_USE_LLVM_UNWINDER=1\nLOCAL_CPPFLAGS_arm64 := -DLIBCXXABI_USE_LLVM_UNWINDER=0\nLOCAL_CPPFLAGS_mips := -DLIBCXXABI_USE_LLVM_UNWINDER=0\nLOCAL_CPPFLAGS_mips64 := -DLIBCXXABI_USE_LLVM_UNWINDER=0\nLOCAL_CPPFLAGS_x86 := -DLIBCXXABI_USE_LLVM_UNWINDER=0\nLOCAL_CPPFLAGS_x86_64 := -DLIBCXXABI_USE_LLVM_UNWINDER=0\nLOCAL_RTTI_FLAG := $(LIBCXXABI_RTTI_FLAG)\nLOCAL_CXX_STL := none\nLOCAL_SANITIZE := never\ninclude $(BUILD_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libc++abi\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := $(LIBCXXABI_SRC_FILES)\nLOCAL_C_INCLUDES := $(LIBCXXABI_INCLUDES)\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include\nLOCAL_CPPFLAGS := $(LIBCXXABI_CPPFLAGS)\nLOCAL_RTTI_FLAG := $(LIBCXXABI_RTTI_FLAG)\nLOCAL_MULTILIB := both\nLOCAL_CXX_STL := none\nLOCAL_SANITIZE := never\n\nifeq ($(HOST_OS),darwin)\n# libcxxabi really doesn't like the non-LLVM assembler on Darwin\nLOCAL_ASFLAGS += -integrated-as\nLOCAL_CFLAGS += -integrated-as\nLOCAL_CPPFLAGS += -integrated-as\nendif\n\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/CMakeLists.txt",
    "content": "#===============================================================================\n# Setup Project\n#===============================================================================\n\ncmake_minimum_required(VERSION 2.8.8)\n\nif(POLICY CMP0042)\n  cmake_policy(SET CMP0042 NEW) # Set MACOSX_RPATH=YES by default\nendif()\n\nif (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)\n  project(libcxxabi)\n\n  # Rely on llvm-config.\n  set(CONFIG_OUTPUT)\n  find_program(LLVM_CONFIG \"llvm-config\")\n  if(DEFINED LLVM_PATH)\n    set(LLVM_INCLUDE_DIR ${LLVM_INCLUDE_DIR} CACHE PATH \"Path to llvm/include\")\n    set(LLVM_PATH ${LLVM_PATH} CACHE PATH \"Path to LLVM source tree\")\n    set(LLVM_MAIN_SRC_DIR ${LLVM_PATH})\n    set(LLVM_CMAKE_PATH \"${LLVM_PATH}/cmake/modules\")\n  elseif(LLVM_CONFIG)\n    message(STATUS \"Found LLVM_CONFIG as ${LLVM_CONFIG}\")\n    set(CONFIG_COMMAND ${LLVM_CONFIG}\n      \"--includedir\"\n      \"--prefix\"\n      \"--src-root\")\n    execute_process(\n      COMMAND ${CONFIG_COMMAND}\n      RESULT_VARIABLE HAD_ERROR\n      OUTPUT_VARIABLE CONFIG_OUTPUT\n    )\n    if(NOT HAD_ERROR)\n      string(REGEX REPLACE\n        \"[ \\t]*[\\r\\n]+[ \\t]*\" \";\"\n        CONFIG_OUTPUT ${CONFIG_OUTPUT})\n    else()\n      string(REPLACE \";\" \" \" CONFIG_COMMAND_STR \"${CONFIG_COMMAND}\")\n      message(STATUS \"${CONFIG_COMMAND_STR}\")\n      message(FATAL_ERROR \"llvm-config failed with status ${HAD_ERROR}\")\n    endif()\n\n    list(GET CONFIG_OUTPUT 0 INCLUDE_DIR)\n    list(GET CONFIG_OUTPUT 1 LLVM_OBJ_ROOT)\n    list(GET CONFIG_OUTPUT 2 MAIN_SRC_DIR)\n\n    set(LLVM_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH \"Path to llvm/include\")\n    set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH \"Path to LLVM build tree\")\n    set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH \"Path to LLVM source tree\")\n    set(LLVM_CMAKE_PATH \"${LLVM_BINARY_DIR}/share/llvm/cmake\")\n    set(LLVM_LIT_PATH \"${LLVM_PATH}/utils/lit/lit.py\")\n  else()\n    message(FATAL_ERROR \"llvm-config not found and LLVM_MAIN_SRC_DIR not defined. \"\n                        \"Reconfigure with -DLLVM_CONFIG=path/to/llvm-config \"\n                        \"or -DLLVM_PATH=path/to/llvm-source-root.\")\n  endif()\n\n  if(EXISTS ${LLVM_CMAKE_PATH})\n    list(APPEND CMAKE_MODULE_PATH \"${LLVM_CMAKE_PATH}\")\n    include(\"${LLVM_CMAKE_PATH}/AddLLVM.cmake\")\n    include(\"${LLVM_CMAKE_PATH}/HandleLLVMOptions.cmake\")\n  else()\n    message(FATAL_ERROR \"Not found: ${LLVM_CMAKE_PATH}\")\n  endif()\n\n  set(PACKAGE_NAME libcxxabi)\n  set(PACKAGE_VERSION 3.7.0svn)\n  set(PACKAGE_STRING \"${PACKAGE_NAME} ${PACKAGE_VERSION}\")\n  set(PACKAGE_BUGREPORT \"llvm-bugs@lists.llvm.org\")\n\n  if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py)\n    set(LLVM_LIT ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py)\n  else()\n    # Seek installed Lit.\n    find_program(LLVM_LIT \"lit.py\" ${LLVM_MAIN_SRC_DIR}/utils/lit\n      DOC \"Path to lit.py\")\n  endif()\n\n  if(LLVM_LIT)\n    # Define the default arguments to use with 'lit', and an option for the user\n    # to override.\n    set(LIT_ARGS_DEFAULT \"-sv\")\n    if (MSVC OR XCODE)\n      set(LIT_ARGS_DEFAULT \"${LIT_ARGS_DEFAULT} --no-progress-bar\")\n    endif()\n    set(LLVM_LIT_ARGS \"${LIT_ARGS_DEFAULT}\" CACHE STRING \"Default options for lit\")\n\n    # On Win32 hosts, provide an option to specify the path to the GnuWin32 tools.\n    if( WIN32 AND NOT CYGWIN )\n      set(LLVM_LIT_TOOLS_DIR \"\" CACHE PATH \"Path to GnuWin32 tools\")\n    endif()\n  else()\n    set(LLVM_INCLUDE_TESTS OFF)\n  endif()\n\n  set(LIBCXXABI_LIBDIR_SUFFIX \"\" CACHE STRING\n      \"Define suffix of library directory name (32/64)\")\n\n  set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LIBCXXABI_LIBDIR_SUFFIX})\n  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LIBCXXABI_LIBDIR_SUFFIX})\n\n  set(LIBCXXABI_BUILT_STANDALONE 1)\nelse()\n  set(LLVM_MAIN_SRC_DIR \"${CMAKE_SOURCE_DIR}\" CACHE PATH \"Path to LLVM source tree\")\n  set(LLVM_LIT \"${CMAKE_SOURCE_DIR}/utils/lit/lit.py\")\n  set(LIBCXXABI_LIBDIR_SUFFIX ${LLVM_LIBDIR_SUFFIX})\nendif()\n\n#===============================================================================\n# Setup CMake Options\n#===============================================================================\n\n# Define options.\noption(LIBCXXABI_ENABLE_ASSERTIONS \"Enable assertions independent of build mode.\" ON)\noption(LIBCXXABI_ENABLE_PEDANTIC \"Compile with pedantic enabled.\" ON)\noption(LIBCXXABI_ENABLE_WERROR \"Fail and stop if a warning is triggered.\" OFF)\noption(LIBCXXABI_USE_LLVM_UNWINDER \"Build and use the LLVM unwinder.\" OFF)\noption(LIBCXXABI_ENABLE_THREADS \"Build with threads enabled\" ON)\nset(LIBCXXABI_GCC_TOOLCHAIN \"\" CACHE STRING \"GCC toolchain for cross compiling.\")\nset(LIBCXXABI_SYSROOT \"\" CACHE STRING \"Sysroot for cross compiling.\")\nset(LIBCXXABI_LIBCXX_LIBRARY_PATH \"\" CACHE STRING \"The path to libc++ library.\")\n\n# Default to building a shared library so that the default options still test\n# the libc++abi that is being built. There are two problems with testing a\n# static libc++abi. In the case of a standalone build, the tests will link the\n# system's libc++, which might not have been built against our libc++abi. In the\n# case of an in tree build, libc++ will prefer a dynamic libc++abi from the\n# system over a static libc++abi from the output directory.\noption(LIBCXXABI_ENABLE_SHARED \"Build libc++abi as a shared library.\" ON)\noption(LIBCXXABI_ENABLE_STATIC \"Build libc++abi as a static library.\" ON)\n\nif (NOT LIBCXXABI_ENABLE_SHARED AND NOT LIBCXXABI_ENABLE_STATIC)\n  message(FATAL_ERROR \"libc++abi must be built as either a shared or static library.\")\nendif()\n\nfind_path(\n  LIBCXXABI_LIBCXX_INCLUDES\n  vector\n  PATHS ${LIBCXXABI_LIBCXX_INCLUDES}\n        ${LIBCXXABI_LIBCXX_PATH}/include\n        ${CMAKE_BINARY_DIR}/${LIBCXXABI_LIBCXX_INCLUDES}\n        ${LLVM_MAIN_SRC_DIR}/projects/libcxx/include\n        ${LLVM_INCLUDE_DIR}/c++/v1\n  )\n\nset(LIBCXXABI_LIBCXX_INCLUDES \"${LIBCXXABI_LIBCXX_INCLUDES}\" CACHE PATH\n    \"Specify path to libc++ includes.\" FORCE)\n\nfind_path(\n  LIBCXXABI_LIBCXX_PATH\n  test/libcxx/__init__.py\n  PATHS ${LIBCXXABI_LIBCXX_PATH}\n        ${LIBCXXABI_LIBCXX_INCLUDES}/../\n        ${LLVM_MAIN_SRC_DIR}/projects/libcxx/\n  NO_DEFAULT_PATH\n  )\n\nif (LIBCXXABI_LIBCXX_PATH STREQUAL \"LIBCXXABI_LIBCXX_PATH-NOTFOUND\")\n  message(WARNING \"LIBCXXABI_LIBCXX_PATH was not specified and couldn't be infered.\")\n  set(LIBCXXABI_LIBCXX_PATH \"\")\nendif()\n\nset(LIBCXXABI_LIBCXX_PATH \"${LIBCXXABI_LIBCXX_PATH}\" CACHE PATH\n    \"Specify path to libc++ source.\" FORCE)\n\n#===============================================================================\n# Configure System\n#===============================================================================\n\n# Add path for custom modules\nset(CMAKE_MODULE_PATH\n  \"${CMAKE_CURRENT_SOURCE_DIR}/cmake\"\n  \"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules\"\n  ${CMAKE_MODULE_PATH}\n  )\n\n# Configure compiler.\ninclude(config-ix)\n\nset(LIBCXXABI_COMPILER    ${CMAKE_CXX_COMPILER})\nset(LIBCXXABI_SOURCE_DIR  ${CMAKE_CURRENT_SOURCE_DIR})\nset(LIBCXXABI_BINARY_DIR  ${CMAKE_CURRENT_BINARY_DIR})\nset(LIBCXXABI_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXXABI_LIBDIR_SUFFIX})\n\n#===============================================================================\n# Setup Compiler Flags\n#===============================================================================\n\n# Get required flags.\nmacro(append_if list condition var)\n  if (${condition})\n    list(APPEND ${list} ${var})\n  endif()\nendmacro()\n\nset(LIBCXXABI_C_FLAGS \"\")\nset(LIBCXXABI_CXX_FLAGS \"\")\nset(LIBCXXABI_COMPILE_FLAGS \"\")\nset(LIBCXXABI_LINK_FLAGS \"\")\n\n\nif (LIBCXXABI_HAS_NOSTDINCXX_FLAG)\n  list(APPEND LIBCXXABI_COMPILE_FLAGS -nostdinc++)\n  # Remove -stdlib flags to prevent them from causing an unused flag warning.\n  string(REPLACE \"-stdlib=libc++\" \"\" CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS}\")\n  string(REPLACE \"-stdlib=libstdc++\" \"\" CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS}\")\nendif()\n\n\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WERROR_FLAG -Werror=return-type)\n\n# Get warning flags\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_W_FLAG -W)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WALL_FLAG -Wall)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WCHAR_SUBSCRIPTS_FLAG -Wchar-subscripts)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WCONVERSION_FLAG -Wconversion)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WMISMATCHED_TAGS_FLAG -Wmismatched-tags)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WMISSING_BRACES_FLAG -Wmissing-braces)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WNEWLINE_EOF_FLAG -Wnewline-eof)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WNO_UNUSED_FUNCTION_FLAG -Wno-unused-function)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WSHADOW_FLAG -Wshadow)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WSHORTEN_64_TO_32_FLAG -Wshorten-64-to-32)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WSIGN_COMPARE_FLAG -Wsign-compare)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WSIGN_CONVERSION_FLAG -Wsign-conversion)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WSTRICT_ALIASING_FLAG -Wstrict-aliasing=2)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WSTRICT_OVERFLOW_FLAG -Wstrict-overflow=4)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WUNUSED_PARAMETER_FLAG -Wunused-parameter)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WUNUSED_VARIABLE_FLAG -Wunused-variable)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WWRITE_STRINGS_FLAG -Wwrite-strings)\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WUNDEF_FLAG -Wundef)\n\nif (LIBCXXABI_ENABLE_WERROR)\n  append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WERROR_FLAG -Werror)\n  append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WX_FLAG -WX)\nelse()\n  append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WNO_ERROR_FLAG -Wno-error)\n  append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_NO_WX_FLAG -WX-)\nendif()\nif (LIBCXXABI_ENABLE_PEDANTIC)\n  append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_PEDANTIC_FLAG -pedantic)\nendif()\n\n# Get feature flags.\n# Exceptions\n# Catches C++ exceptions only and tells the compiler to assume that extern C\n# functions never throw a C++ exception.\nappend_if(LIBCXXABI_CXX_FLAGS LIBCXXABI_HAS_FSTRICT_ALIASING_FLAG -fstrict-aliasing)\nappend_if(LIBCXXABI_CXX_FLAGS LIBCXXABI_HAS_EHSC_FLAG -EHsc)\n\nappend_if(LIBCXXABI_C_FLAGS LIBCXXABI_HAS_FUNWIND_TABLES -funwind-tables)\n\n# Assert\nstring(TOUPPER \"${CMAKE_BUILD_TYPE}\" uppercase_CMAKE_BUILD_TYPE)\nif (LIBCXXABI_ENABLE_ASSERTIONS)\n  # MSVC doesn't like _DEBUG on release builds. See PR 4379.\n  if (NOT MSVC)\n    list(APPEND LIBCXXABI_COMPILE_FLAGS -D_DEBUG)\n  endif()\n  # On Release builds cmake automatically defines NDEBUG, so we\n  # explicitly undefine it:\n  if (uppercase_CMAKE_BUILD_TYPE STREQUAL \"RELEASE\")\n    list(APPEND LIBCXXABI_COMPILE_FLAGS -UNDEBUG)\n  endif()\nelse()\n  if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL \"RELEASE\")\n    list(APPEND LIBCXXABI_COMPILE_FLAGS -DNDEBUG)\n  endif()\nendif()\n# Static library\nif (NOT LIBCXXABI_ENABLE_SHARED)\n  list(APPEND LIBCXXABI_COMPILE_FLAGS -D_LIBCPP_BUILD_STATIC)\nendif()\n\nif (NOT LIBCXXABI_ENABLE_THREADS)\n  add_definitions(-DLIBCXXABI_HAS_NO_THREADS=1)\nendif()\n\n# This is the _ONLY_ place where add_definitions is called.\nif (MSVC)\n  add_definitions(-D_CRT_SECURE_NO_WARNINGS)\nendif()\n\n# Define LIBCXXABI_USE_LLVM_UNWINDER for conditional compilation.\nif (LIBCXXABI_USE_LLVM_UNWINDER OR LLVM_NATIVE_ARCH MATCHES ARM)\n  add_definitions(-DLIBCXXABI_USE_LLVM_UNWINDER=1)\nendif()\n\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_TARGET_TRIPLE\n          \"-target ${LIBCXXABI_TARGET_TRIPLE}\")\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_GCC_TOOLCHAIN\n         \"-gcc-toolchain ${LIBCXXABI_GCC_TOOLCHAIN}\")\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_SYSROOT\n          \"--sysroot ${LIBCXXABI_SYSROOT}\")\nstring(REPLACE \";\" \" \" LIBCXXABI_CXX_FLAGS \"${LIBCXXABI_CXX_FLAGS}\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} ${LIBCXXABI_CXX_FLAGS}\")\nset(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} ${LIBCXXABI_C_FLAGS}\")\n\n#===============================================================================\n# Setup Source Code\n#===============================================================================\n\nset(LIBCXXABI_LIBUNWIND_INCLUDES \"${LIBCXXABI_LIBUNWIND_INCLUDES}\" CACHE PATH\n    \"Specify path to libunwind includes.\" FORCE)\nset(LIBCXXABI_LIBUNWIND_PATH \"${LIBCXXABI_LIBUNWIND_PATH}\" CACHE PATH\n    \"Specify path to libunwind source.\" FORCE)\n\ninclude_directories(include)\nif (LIBCXXABI_USE_LLVM_UNWINDER OR LLVM_NATIVE_ARCH MATCHES ARM)\n  find_path(\n    LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL\n    libunwind.h\n    PATHS ${LIBCXXABI_LIBUNWIND_INCLUDES}\n          ${LIBCXXABI_LIBUNWIND_PATH}/include\n          ${CMAKE_BINARY_DIR}/${LIBCXXABI_LIBUNWIND_INCLUDES}\n          ${LLVM_MAIN_SRC_DIR}/projects/libunwind/include\n    NO_DEFAULT_PATH\n  )\n\n  find_path(\n    LIBCXXABI_LIBUNWIND_SOURCES\n    libunwind_ext.h\n    PATHS ${LIBCXXABI_LIBUNWIND_PATH}/src/\n          ${LIBCXXABI_LIBUNWIND_INCLUDES}/../src/\n          ${LLVM_MAIN_SRC_DIR}/projects/libunwind/src/\n    NO_DEFAULT_PATH\n  )\n\n  if (LIBCXXABI_LIBUNWIND_SOURCES STREQUAL \"LIBCXXABI_LIBUNWIND_SOURCES-NOTFOUND\")\n    message(WARNING \"LIBCXXABI_LIBCXX_PATH was not specified and couldn't be infered.\")\n    set(LIBCXXABI_LIBUNWIND_SOURCES \"\")\n  endif()\n\n  include_directories(\"${LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL}\")\n  include_directories(\"${LIBCXXABI_LIBUNWIND_SOURCES}\")\nendif ()\n\n# Add source code. This also contains all of the logic for deciding linker flags\n# soname, etc...\nadd_subdirectory(src)\n\nif(NOT LIBCXXABI_ENABLE_SHARED)\n  # TODO: Fix the libc++ cmake files so that libc++abi can be statically linked.\n  # As it is now, libc++ will prefer linking against a dynamic libc++abi in the\n  # system library paths over a static libc++abi in the out directory. This\n  # would test the system library rather than the one we just built, which isn't\n  # very helpful.\n  message(WARNING \"The libc++abi tests are currently only valid when \"\n                  \"LIBCXXABI_ENABLE_SHARED is on, no check target will be \"\n                  \"available!\")\nelse()\n  add_subdirectory(test)\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/CREDITS.TXT",
    "content": "This file is a partial list of people who have contributed to the LLVM/libc++abi\nproject.  If you have contributed a patch or made some other contribution to\nLLVM/libc++abi, please submit a patch to this file to add yourself, and it will be\ndone!\n\nThe list is sorted by surname and formatted to allow easy grepping and\nbeautification by scripts.  The fields are: name (N), email (E), web-address\n(W), PGP key ID and fingerprint (P), description (D), and snail-mail address\n(S).\n\nN: Aaron Ballman\nE: aaron@aaronballman.com\nD: Minor patches\n\nN: Logan Chien\nE: logan.chien@mediatek.com\nD: ARM EHABI Unwind & Exception Handling\n\nN: Marshall Clow\nE: mclow.lists@gmail.com\nE: marshall@idio.com\nD: Architect and primary coauthor of libc++abi\n\nN: Matthew Dempsky\nE: matthew@dempsky.org\nD: Minor patches and bug fixes.\n\nN: Nowar Gu\nE: wenhan.gu@gmail.com\nD: Minor patches and fixes\n\nN: Howard Hinnant\nE: hhinnant@apple.com\nD: Architect and primary coauthor of libc++abi\n\nN: Dana Jansens\nE: danakj@chromium.org\nD: ARM EHABI Unwind & Exception Handling\n\nN: Nick Kledzik\nE: kledzik@apple.com\n\nN: Antoine Labour\nE: piman@chromium.org\nD: ARM EHABI Unwind & Exception Handling\n\nN: Bruce Mitchener, Jr.\nE: bruce.mitchener@gmail.com\nD: Minor typo fixes\n\nN: Andrew Morrow\nE: andrew.c.morrow@gmail.com\nD: Minor patches and fixes\n\nN: Erik Olofsson\nE: erik.olofsson@hansoft.se\nE: erik@olofsson.info\nD: Minor patches and fixes\n\nN: Jon Roelofs\nE: jonathan@codesourcery.com\nD: ARM EHABI Unwind & Exception Handling, Bare-metal\n\nN: Nico Weber\nE: thakis@chromium.org\nD: ARM EHABI Unwind & Exception Handling\n\nN: Albert J. Wong\nE: ajwong@google.com\nD: ARM EHABI Unwind & Exception Handling\n\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/LICENSE.TXT",
    "content": "==============================================================================\nlibc++abi License\n==============================================================================\n\nThe libc++abi library is dual licensed under both the University of Illinois\n\"BSD-Like\" license and the MIT license.  As a user of this code you may choose\nto use it under either license.  As a contributor, you agree to allow your code\nto be used under both.\n\nFull text of the relevant licenses is included below.\n\n==============================================================================\n\nUniversity of Illinois/NCSA\nOpen Source License\n\nCopyright (c) 2009-2015 by the contributors listed in CREDITS.TXT\n\nAll rights reserved.\n\nDeveloped by:\n\n    LLVM Team\n\n    University of Illinois at Urbana-Champaign\n\n    http://llvm.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal with\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimers.\n\n    * Redistributions in binary form must reproduce the above copyright notice,\n      this list of conditions and the following disclaimers in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the names of the LLVM Team, University of Illinois at\n      Urbana-Champaign, nor the names of its contributors may be used to\n      endorse or promote products derived from this Software without specific\n      prior written permission.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\nCONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE\nSOFTWARE.\n\n==============================================================================\n\nCopyright (c) 2009-2014 by the contributors listed in CREDITS.TXT\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/MODULE_LICENSE_BSD_LIKE",
    "content": ""
  },
  {
    "path": "atlas-aapt/external/libcxxabi/NOTICE",
    "content": "==============================================================================\nlibc++abi License\n==============================================================================\n\nThe libc++abi library is dual licensed under both the University of Illinois\n\"BSD-Like\" license and the MIT license.  As a user of this code you may choose\nto use it under either license.  As a contributor, you agree to allow your code\nto be used under both.\n\nFull text of the relevant licenses is included below.\n\n==============================================================================\n\nUniversity of Illinois/NCSA\nOpen Source License\n\nCopyright (c) 2009-2014 by the contributors listed in CREDITS.TXT\n\nAll rights reserved.\n\nDeveloped by:\n\n    LLVM Team\n\n    University of Illinois at Urbana-Champaign\n\n    http://llvm.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal with\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimers.\n\n    * Redistributions in binary form must reproduce the above copyright notice,\n      this list of conditions and the following disclaimers in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the names of the LLVM Team, University of Illinois at\n      Urbana-Champaign, nor the names of its contributors may be used to\n      endorse or promote products derived from this Software without specific\n      prior written permission.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\nCONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE\nSOFTWARE.\n\n==============================================================================\n\nCopyright (c) 2009-2014 by the contributors listed in CREDITS.TXT\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/cmake/config-ix.cmake",
    "content": "include(CheckLibraryExists)\ninclude(CheckCCompilerFlag)\ninclude(CheckCXXCompilerFlag)\n\n# Check compiler flags\ncheck_c_compiler_flag(-funwind-tables         LIBCXXABI_HAS_FUNWIND_TABLES)\ncheck_cxx_compiler_flag(-fPIC                 LIBCXXABI_HAS_FPIC_FLAG)\ncheck_cxx_compiler_flag(-fno-exceptions       LIBCXXABI_HAS_NO_EXCEPTIONS_FLAG)\ncheck_cxx_compiler_flag(-fno-rtti             LIBCXXABI_HAS_NO_RTTI_FLAG)\ncheck_cxx_compiler_flag(-fstrict-aliasing     LIBCXXABI_HAS_FSTRICT_ALIASING_FLAG)\ncheck_cxx_compiler_flag(-nodefaultlibs        LIBCXXABI_HAS_NODEFAULTLIBS_FLAG)\ncheck_cxx_compiler_flag(-nostdinc++           LIBCXXABI_HAS_NOSTDINCXX_FLAG)\ncheck_cxx_compiler_flag(-Wall                 LIBCXXABI_HAS_WALL_FLAG)\ncheck_cxx_compiler_flag(-W                    LIBCXXABI_HAS_W_FLAG)\ncheck_cxx_compiler_flag(-Wno-unused-function  LIBCXXABI_HAS_WNO_UNUSED_FUNCTION_FLAG)\ncheck_cxx_compiler_flag(-Wunused-variable     LIBCXXABI_HAS_WUNUSED_VARIABLE_FLAG)\ncheck_cxx_compiler_flag(-Wunused-parameter    LIBCXXABI_HAS_WUNUSED_PARAMETER_FLAG)\ncheck_cxx_compiler_flag(-Wstrict-aliasing     LIBCXXABI_HAS_WSTRICT_ALIASING_FLAG)\ncheck_cxx_compiler_flag(-Wstrict-overflow     LIBCXXABI_HAS_WSTRICT_OVERFLOW_FLAG)\ncheck_cxx_compiler_flag(-Wwrite-strings       LIBCXXABI_HAS_WWRITE_STRINGS_FLAG)\ncheck_cxx_compiler_flag(-Wchar-subscripts     LIBCXXABI_HAS_WCHAR_SUBSCRIPTS_FLAG)\ncheck_cxx_compiler_flag(-Wmismatched-tags     LIBCXXABI_HAS_WMISMATCHED_TAGS_FLAG)\ncheck_cxx_compiler_flag(-Wmissing-braces      LIBCXXABI_HAS_WMISSING_BRACES_FLAG)\ncheck_cxx_compiler_flag(-Wshorten-64-to-32    LIBCXXABI_HAS_WSHORTEN_64_TO_32_FLAG)\ncheck_cxx_compiler_flag(-Wsign-conversion     LIBCXXABI_HAS_WSIGN_CONVERSION_FLAG)\ncheck_cxx_compiler_flag(-Wsign-compare        LIBCXXABI_HAS_WSIGN_COMPARE_FLAG)\ncheck_cxx_compiler_flag(-Wshadow              LIBCXXABI_HAS_WSHADOW_FLAG)\ncheck_cxx_compiler_flag(-Wconversion          LIBCXXABI_HAS_WCONVERSION_FLAG)\ncheck_cxx_compiler_flag(-Wnewline-eof         LIBCXXABI_HAS_WNEWLINE_EOF_FLAG)\ncheck_cxx_compiler_flag(-Wundef               LIBCXXABI_HAS_WUNDEF_FLAG)\ncheck_cxx_compiler_flag(-pedantic             LIBCXXABI_HAS_PEDANTIC_FLAG)\ncheck_cxx_compiler_flag(-Werror               LIBCXXABI_HAS_WERROR_FLAG)\ncheck_cxx_compiler_flag(-Wno-error            LIBCXXABI_HAS_WNO_ERROR_FLAG)\ncheck_cxx_compiler_flag(/WX                   LIBCXXABI_HAS_WX_FLAG)\ncheck_cxx_compiler_flag(/WX-                  LIBCXXABI_HAS_NO_WX_FLAG)\ncheck_cxx_compiler_flag(/EHsc                 LIBCXXABI_HAS_EHSC_FLAG)\ncheck_cxx_compiler_flag(/EHs-                 LIBCXXABI_HAS_NO_EHS_FLAG)\ncheck_cxx_compiler_flag(/EHa-                 LIBCXXABI_HAS_NO_EHA_FLAG)\ncheck_cxx_compiler_flag(/GR-                  LIBCXXABI_HAS_NO_GR_FLAG)\n\n# Check libraries\ncheck_library_exists(c printf \"\" LIBCXXABI_HAS_C_LIB)\ncheck_library_exists(dl dladdr \"\" LIBCXXABI_HAS_DL_LIB)\ncheck_library_exists(pthread pthread_once \"\" LIBCXXABI_HAS_PTHREAD_LIB)\ncheck_library_exists(gcc_eh _Unwind_GetRegionStart \"\" LIBCXXABI_HAS_GCC_EH_LIB)\ncheck_library_exists(c __cxa_thread_atexit_impl \"\"\n  LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/include/__cxxabi_config.h",
    "content": "//===-------------------------- __cxxabi_config.h -------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef ____CXXABI_CONFIG_H\n#define ____CXXABI_CONFIG_H\n\n#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \\\n    !defined(__ARM_DWARF_EH__)\n#define LIBCXXABI_ARM_EHABI 1\n#else\n#define LIBCXXABI_ARM_EHABI 0\n#endif\n\n#endif // ____CXXABI_CONFIG_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/include/cxxabi.h",
    "content": "//===--------------------------- cxxabi.h ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef __CXXABI_H\n#define __CXXABI_H\n\n/*\n * This header provides the interface to the C++ ABI as defined at:\n *       http://www.codesourcery.com/cxx-abi/\n */\n\n#include <stddef.h>\n#include <stdint.h>\n\n#include <__cxxabi_config.h>\n\n#define _LIBCPPABI_VERSION 1002\n#define LIBCXXABI_NORETURN  __attribute__((noreturn))\n\n#ifdef __cplusplus\n\nnamespace std {\nclass type_info; // forward declaration\n}\n\n\n// runtime routines use C calling conventions, but are in __cxxabiv1 namespace\nnamespace __cxxabiv1 {\nextern \"C\"  {\n\n// 2.4.2 Allocating the Exception Object\nextern void * __cxa_allocate_exception(size_t thrown_size) throw();\nextern void __cxa_free_exception(void * thrown_exception) throw();\n\n// 2.4.3 Throwing the Exception Object\nextern LIBCXXABI_NORETURN void __cxa_throw(void * thrown_exception,\n        std::type_info * tinfo, void (*dest)(void *));\n\n// 2.5.3 Exception Handlers\nextern void * __cxa_get_exception_ptr(void * exceptionObject) throw();\nextern void * __cxa_begin_catch(void * exceptionObject) throw();\nextern void __cxa_end_catch();\n#if LIBCXXABI_ARM_EHABI\nextern bool __cxa_begin_cleanup(void * exceptionObject) throw();\nextern void __cxa_end_cleanup();\n#endif\nextern std::type_info * __cxa_current_exception_type();\n\n// 2.5.4 Rethrowing Exceptions\nextern LIBCXXABI_NORETURN void __cxa_rethrow();\n\n\n\n// 2.6 Auxiliary Runtime APIs\nextern LIBCXXABI_NORETURN void __cxa_bad_cast(void);\nextern LIBCXXABI_NORETURN void __cxa_bad_typeid(void);\nextern LIBCXXABI_NORETURN void __cxa_throw_bad_array_new_length(void);\n\n\n\n// 3.2.6 Pure Virtual Function API\nextern LIBCXXABI_NORETURN void __cxa_pure_virtual(void);\n\n// 3.2.7 Deleted Virtual Function API\nextern LIBCXXABI_NORETURN void __cxa_deleted_virtual(void);\n\n// 3.3.2 One-time Construction API\n#ifdef __arm__\nextern int  __cxa_guard_acquire(uint32_t*);\nextern void __cxa_guard_release(uint32_t*);\nextern void __cxa_guard_abort(uint32_t*);\n#else\nextern int  __cxa_guard_acquire(uint64_t*);\nextern void __cxa_guard_release(uint64_t*);\nextern void __cxa_guard_abort(uint64_t*);\n#endif\n\n// 3.3.3 Array Construction and Destruction API\nextern void* __cxa_vec_new(size_t element_count,\n                           size_t element_size,\n                           size_t padding_size,\n                           void (*constructor)(void*),\n                           void (*destructor)(void*));\n\nextern void* __cxa_vec_new2(size_t element_count,\n                            size_t element_size,\n                            size_t padding_size,\n                            void  (*constructor)(void*),\n                            void  (*destructor)(void*),\n                            void* (*alloc)(size_t),\n                            void  (*dealloc)(void*));\n\nextern void* __cxa_vec_new3(size_t element_count,\n                            size_t element_size,\n                            size_t padding_size,\n                            void  (*constructor)(void*),\n                            void  (*destructor)(void*),\n                            void* (*alloc)(size_t),\n                            void  (*dealloc)(void*, size_t));\n\nextern void __cxa_vec_ctor(void*  array_address,\n                           size_t element_count,\n                           size_t element_size,\n                           void (*constructor)(void*),\n                           void (*destructor)(void*));\n\nextern void __cxa_vec_dtor(void*  array_address,\n                           size_t element_count,\n                           size_t element_size,\n                           void (*destructor)(void*));\n\nextern void __cxa_vec_cleanup(void* array_address,\n                             size_t element_count,\n                             size_t element_size,\n                             void  (*destructor)(void*));\n\nextern void __cxa_vec_delete(void*  array_address,\n                             size_t element_size,\n                             size_t padding_size,\n                             void  (*destructor)(void*));\n\nextern void __cxa_vec_delete2(void* array_address,\n                             size_t element_size,\n                             size_t padding_size,\n                             void  (*destructor)(void*),\n                             void  (*dealloc)(void*));\n\nextern void __cxa_vec_delete3(void* __array_address,\n                             size_t element_size,\n                             size_t padding_size,\n                             void  (*destructor)(void*),\n                             void  (*dealloc)(void*, size_t));\n\nextern void __cxa_vec_cctor(void*  dest_array,\n                            void*  src_array,\n                            size_t element_count,\n                            size_t element_size,\n                            void  (*constructor)(void*, void*),\n                            void  (*destructor)(void*));\n\n// 3.3.5.3 Runtime API\nextern int __cxa_atexit(void (*f)(void*), void* p, void* d);\nextern int __cxa_finalize(void*);\n\n// 3.4 Demangler API\nextern char* __cxa_demangle(const char* mangled_name,\n                            char*       output_buffer,\n                            size_t*     length,\n                            int*        status);\n\n// Apple additions to support C++ 0x exception_ptr class\n// These are primitives to wrap a smart pointer around an exception object\nextern void * __cxa_current_primary_exception() throw();\nextern void __cxa_rethrow_primary_exception(void* primary_exception);\nextern void __cxa_increment_exception_refcount(void* primary_exception) throw();\nextern void __cxa_decrement_exception_refcount(void* primary_exception) throw();\n\n// Apple extension to support std::uncaught_exception()\nextern bool          __cxa_uncaught_exception () throw();\nextern unsigned int  __cxa_uncaught_exceptions() throw();\n\n#ifdef __linux__\n// Linux TLS support. Not yet an official part of the Itanium ABI.\n// https://sourceware.org/glibc/wiki/Destructor%20support%20for%20thread_local%20variables\nextern int __cxa_thread_atexit(void (*)(void *), void *, void *) throw();\n#endif\n\n  } // extern \"C\"\n} // namespace __cxxabiv1\n\nnamespace abi = __cxxabiv1;\n\n#endif // __cplusplus\n\n#endif // __CXXABI_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/lib/buildit",
    "content": "#! /bin/sh\n#\n# Set the $TRIPLE environment variable to your system's triple before\n# running this script.  If you set $CXX, that will be used to compile\n# the library.  Otherwise we'll use clang++.\n\nset -e\n\nif [ `basename $(pwd)` != \"lib\" ]\nthen\n\techo \"current directory must be lib\"\n\texit 1\nfi\n\nif [ -z \"$CXX\" ]\nthen\n\tCXX=clang++\nfi\n\nif [ -z \"$CC\" ]\nthen\n    CC=clang\nfi\n\nif [ -z $RC_ProjectSourceVersion ]\nthen\n  RC_ProjectSourceVersion=1\nfi\n\nEXTRA_FLAGS=\"-std=c++11 -stdlib=libc++ -fstrict-aliasing -Wstrict-aliasing=2 \\\n             -Wsign-conversion -Wshadow -Wconversion -Wunused-variable \\\n             -Wmissing-field-initializers -Wchar-subscripts -Wmismatched-tags \\\n             -Wmissing-braces -Wshorten-64-to-32 -Wsign-compare \\\n             -Wstrict-aliasing=2 -Wstrict-overflow=4 -Wunused-parameter \\\n             -Wnewline-eof\"\n\ncase $TRIPLE in\n  *-apple-*)\n    if [ -z $RC_XBS ]\n    then\n      RC_CFLAGS=\"-arch i386 -arch x86_64\"\n    fi\n    SOEXT=dylib\n    if [ -n \"$SDKROOT\" ]\n    then\n        EXTRA_FLAGS+=\"-isysroot ${SDKROOT}\"\n        CXX=`xcrun -sdk \"${SDKROOT}\"  -find clang++`\n        CC=`xcrun -sdk \"${SDKROOT}\"  -find clang`\n    fi\n    LDSHARED_FLAGS=\"-o libc++abi.dylib \\\n        -dynamiclib -nodefaultlibs  \\\n        -current_version ${RC_ProjectSourceVersion} \\\n        -compatibility_version 1 \\\n        -install_name /usr/lib/libc++abi.dylib \\\n        -lSystem\"\n\tif [ -f \"${SDKROOT}/usr/local/lib/libCrashReporterClient.a\" ]\n\tthen\n\t\tLDSHARED_FLAGS+=\" -lCrashReporterClient\"\n\tfi\n    ;;\n  *-*-mingw*)\n    # FIXME: removing libgcc and libsupc++ dependencies means porting libcxxrt and LLVM/compiler-rt\n    SOEXT=dll\n    LDSHARED_FLAGS=\"-o libc++abi.dll \\\n        -shared -nodefaultlibs -Wl,--export-all-symbols -Wl,--allow-multiple-definition -Wl,--out-implib,libc++abi.dll.a \\\n        -lsupc++ -lpthread -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcr100 -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt\"\n\t;;\n  *)\n    RC_CFLAGS=\"-fPIC\"\n    SOEXT=so\n    LDSHARED_FLAGS=\"-o libc++abi.so.1.0 \\\n        -shared -nodefaultlibs -Wl,-soname,libc++abi.so.1 \\\n        -lpthread -lrt -lc -lstdc++\"\n    ;;\nesac\n\nif [ -z $RC_XBS ]\nthen\n    rm -f libc++abi.1.$SOEXT*\nfi\n\nset -x\n\nfor FILE in ../src/*.cpp; do\n\t$CXX -c -g -O3 $RC_CFLAGS $EXTRA_FLAGS -I../include $OPTIONS $FILE\ndone\ncase $TRIPLE in\n  *-*-mingw*)\n  for FILE in ../src/support/win32/*.cpp; do\n    $CXX -c -g -Os $RC_CFLAGS $EXTRA_FLAGS -I../include $OPTIONS $FILE\n  done\n  ;;\nesac\n$CC *.o $RC_CFLAGS $LDSHARED_FLAGS $EXTRA_FLAGS\n\nif [ -z $RC_XBS ]\nthen\n    rm *.o\nfi\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/CMakeLists.txt",
    "content": "# Get sources\nset(LIBCXXABI_SOURCES\n  abort_message.cpp\n  cxa_aux_runtime.cpp\n  cxa_default_handlers.cpp\n  cxa_demangle.cpp\n  cxa_exception.cpp\n  cxa_exception_storage.cpp\n  cxa_guard.cpp\n  cxa_handlers.cpp\n  cxa_new_delete.cpp\n  cxa_personality.cpp\n  cxa_unexpected.cpp\n  cxa_vector.cpp\n  cxa_virtual.cpp\n  exception.cpp\n  private_typeinfo.cpp\n  stdexcept.cpp\n  typeinfo.cpp\n)\n\nif (UNIX AND NOT (APPLE OR CYGWIN))\n  list(APPEND LIBCXXABI_SOURCES cxa_thread_atexit.cpp)\nendif()\n\nset(LIBCXXABI_HEADERS ../include/cxxabi.h)\n\n# Add all the headers to the project for IDEs.\nif (MSVC_IDE OR XCODE)\n  # Force them all into the headers dir on MSVC, otherwise they end up at\n  # project scope because they don't have extensions.\n  if (MSVC_IDE)\n    source_group(\"Header Files\" FILES ${LIBCXXABI_HEADERS})\n  endif()\nendif()\n\ninclude_directories(\"${LIBCXXABI_LIBCXX_INCLUDES}\")\n\nif (LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)\n  add_definitions(-DHAVE___CXA_THREAD_ATEXIT_IMPL)\nendif()\n\n# Generate library list.\nset(libraries ${LIBCXXABI_CXX_ABI_LIBRARIES})\nappend_if(libraries LIBCXXABI_HAS_C_LIB c)\nif (LIBCXXABI_ENABLE_THREADS)\n  append_if(libraries LIBCXXABI_HAS_PTHREAD_LIB pthread)\nendif()\n\nif (LIBCXXABI_USE_LLVM_UNWINDER)\n  list(APPEND libraries unwind)\nelse()\n  append_if(libraries LIBCXXABI_HAS_GCC_EH_LIB gcc_eh)\nendif()\n\n# Setup flags.\nappend_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_FPIC_FLAG -fPIC)\nappend_if(LIBCXXABI_LINK_FLAGS LIBCXXABI_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs)\n\nset(LIBCXXABI_SHARED_LINK_FLAGS)\n\nif ( APPLE )\n  if ( CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL \"10.6\" )\n    list(APPEND LIBCXXABI_COMPILE_FLAGS \"-U__STRICT_ANSI__\")\n    list(APPEND LIBCXXABI_SHARED_LINK_FLAGS\n      \"-compatibility_version 1\"\n      \"-current_version 1\"\n      \"-install_name /usr/lib/libc++abi.1.dylib\")\n    list(APPEND LIBCXXABI_LINK_FLAGS\n        \"/usr/lib/libSystem.B.dylib\")\n  else()\n    list(APPEND LIBCXXABI_SHARED_LINK_FLAGS\n      \"-compatibility_version 1\"\n      \"-install_name /usr/lib/libc++abi.1.dylib\")\n  endif()\nendif()\n\nstring(REPLACE \";\" \" \" LIBCXXABI_COMPILE_FLAGS \"${LIBCXXABI_COMPILE_FLAGS}\")\nstring(REPLACE \";\" \" \" LIBCXXABI_LINK_FLAGS \"${LIBCXXABI_LINK_FLAGS}\")\nstring(REPLACE \";\" \" \" LIBCXXABI_SHARED_LINK_FLAGS \"${LIBCXXABI_SHARED_LINK_FLAGS}\")\n\n# Add a object library that contains the compiled source files.\nadd_library(cxxabi_objects OBJECT ${LIBCXXABI_SOURCES} ${LIBCXXABI_HEADERS})\n\nset_target_properties(cxxabi_objects\n  PROPERTIES\n    COMPILE_FLAGS \"${LIBCXXABI_COMPILE_FLAGS}\"\n  )\n\nset(LIBCXXABI_TARGETS)\n\n# Build the shared library.\nif (LIBCXXABI_ENABLE_SHARED)\n  add_library(cxxabi_shared SHARED $<TARGET_OBJECTS:cxxabi_objects>)\n  target_link_libraries(cxxabi_shared ${libraries})\n  set_target_properties(cxxabi_shared\n    PROPERTIES\n      LINK_FLAGS    \"${LIBCXXABI_LINK_FLAGS} ${LIBCXXABI_SHARED_LINK_FLAGS}\"\n      OUTPUT_NAME   \"c++abi\"\n      VERSION       \"1.0\"\n      SOVERSION     \"1\"\n    )\n  list(APPEND LIBCXXABI_TARGETS \"cxxabi_shared\")\nendif()\n\n# Build the static library.\nif (LIBCXXABI_ENABLE_STATIC)\n  add_library(cxxabi_static STATIC $<TARGET_OBJECTS:cxxabi_objects>)\n  target_link_libraries(cxxabi_static ${libraries})\n  set_target_properties(cxxabi_static\n    PROPERTIES\n      LINK_FLAGS    \"${LIBCXXABI_LINK_FLAGS}\"\n      OUTPUT_NAME   \"c++abi\"\n  )\n  list(APPEND LIBCXXABI_TARGETS \"cxxabi_static\")\nendif()\n\n# Add a meta-target for both libraries.\nadd_custom_target(cxxabi DEPENDS ${LIBCXXABI_TARGETS})\n\ninstall(TARGETS ${LIBCXXABI_TARGETS}\n  LIBRARY DESTINATION lib${LIBCXXABI_LIBDIR_SUFFIX}\n  ARCHIVE DESTINATION lib${LIBCXXABI_LIBDIR_SUFFIX}\n  )\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/abort_message.cpp",
    "content": "//===------------------------- abort_message.cpp --------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stdlib.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include \"abort_message.h\"\n\n#ifdef __BIONIC__\n#include <android/api-level.h>\n#if __ANDROID_API__ >= 21\n#include <syslog.h>\nextern \"C\" void android_set_abort_message(const char* msg);\n#else\n#include <assert.h>\n#endif // __ANDROID_API__ >= 21\n#endif // __BIONIC__\n\n#pragma GCC visibility push(hidden)\n\n#ifdef __APPLE__\n#   if defined(__has_include) && __has_include(<CrashReporterClient.h>)\n#       define HAVE_CRASHREPORTERCLIENT_H\n#       include <CrashReporterClient.h>\n#   endif\n#endif\n\n__attribute__((visibility(\"hidden\"), noreturn))\nvoid abort_message(const char* format, ...)\n{\n    // write message to stderr\n#ifdef __APPLE__\n    fprintf(stderr, \"libc++abi.dylib: \");\n#endif\n    va_list list;\n    va_start(list, format);\n    vfprintf(stderr, format, list);\n    va_end(list);\n    fprintf(stderr, \"\\n\");\n\n#if defined(__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H)\n    // record message in crash report\n    char* buffer;\n    va_list list2;\n    va_start(list2, format);\n    vasprintf(&buffer, format, list2);\n    va_end(list2);\n    CRSetCrashLogMessage(buffer);\n#elif defined(__BIONIC__)\n    char* buffer;\n    va_list list2;\n    va_start(list2, format);\n    vasprintf(&buffer, format, list2);\n    va_end(list2);\n\n#if __ANDROID_API__ >= 21\n    // Show error in tombstone.\n    android_set_abort_message(buffer);\n\n    // Show error in logcat.\n    openlog(\"libc++abi\", 0, 0);\n    syslog(LOG_CRIT, \"%s\", buffer);\n    closelog();\n#else\n    // The good error reporting wasn't available in Android until L. Since we're\n    // about to abort anyway, just call __assert2, which will log _somewhere_\n    // (tombstone and/or logcat) in older releases.\n    __assert2(__FILE__, __LINE__, __func__, buffer);\n#endif // __ANDROID_API__ >= 21\n#endif // __BIONIC__\n\n    abort();\n}\n\n#pragma GCC visibility pop\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/abort_message.h",
    "content": "//===-------------------------- abort_message.h-----------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef __ABORT_MESSAGE_H_\n#define __ABORT_MESSAGE_H_\n\n#include <stdio.h>\n\n#pragma GCC visibility push(hidden)\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n__attribute__((visibility(\"hidden\"), noreturn))\n       void abort_message(const char* format, ...) \n            __attribute__((format(printf, 1, 2)));\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#pragma GCC visibility pop\n\n#endif\n\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/config.h",
    "content": "//===----------------------------- config.h -------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//\n//  Defines macros used within the libc++abi project.\n//\n//===----------------------------------------------------------------------===//\n\n\n#ifndef LIBCXXABI_CONFIG_H\n#define LIBCXXABI_CONFIG_H\n\n#include <unistd.h>\n\n// Set this in the CXXFLAGS when you need it\n#if !defined(LIBCXXABI_HAS_NO_THREADS)\n#  define LIBCXXABI_HAS_NO_THREADS 0\n#endif\n\n// Set this in the CXXFLAGS when you need it, because otherwise we'd have to\n// #if !defined(__linux__) && !defined(__APPLE__) && ...\n// and so-on for *every* platform.\n#ifndef LIBCXXABI_BAREMETAL\n#  define LIBCXXABI_BAREMETAL 0\n#endif\n\n#endif // LIBCXXABI_CONFIG_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_aux_runtime.cpp",
    "content": "//===------------------------ cxa_aux_runtime.cpp -------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//\n// This file implements the \"Auxiliary Runtime APIs\"\n// http://mentorembedded.github.io/cxx-abi/abi-eh.html#cxx-aux\n//===----------------------------------------------------------------------===//\n\n#include \"cxxabi.h\"\n#include <new>\n#include <typeinfo>\n\nnamespace __cxxabiv1\n{\n\nextern \"C\"\n{\n\nLIBCXXABI_NORETURN\nvoid __cxa_bad_cast (void) {\n    throw std::bad_cast();\n}\n\nLIBCXXABI_NORETURN\nvoid __cxa_bad_typeid(void) {\n    throw std::bad_typeid();\n}\n\nLIBCXXABI_NORETURN\nvoid __cxa_throw_bad_array_new_length(void) {\n    throw std::bad_array_new_length();\n}\n}  // extern \"C\"\n\n}  // abi\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_default_handlers.cpp",
    "content": "//===------------------------- cxa_default_handlers.cpp -------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//\n// This file implements the default terminate_handler and unexpected_handler.\n//===----------------------------------------------------------------------===//\n\n#include <stdexcept>\n#include <new>\n#include <exception>\n#include \"abort_message.h\"\n#include \"config.h\" // For __sync_swap\n#include \"cxxabi.h\"\n#include \"cxa_handlers.hpp\"\n#include \"cxa_exception.hpp\"\n#include \"private_typeinfo.h\"\n\nstatic const char* cause = \"uncaught\";\n\n__attribute__((noreturn))\nstatic void default_terminate_handler()\n{\n    // If there might be an uncaught exception\n    using namespace __cxxabiv1;\n    __cxa_eh_globals* globals = __cxa_get_globals_fast();\n    if (globals)\n    {\n        __cxa_exception* exception_header = globals->caughtExceptions;\n        // If there is an uncaught exception\n        if (exception_header)\n        {\n            _Unwind_Exception* unwind_exception =\n                reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;\n            bool native_exception =\n                (unwind_exception->exception_class   & get_vendor_and_language) == \n                                 (kOurExceptionClass & get_vendor_and_language);\n            if (native_exception)\n            {\n                void* thrown_object =\n                    unwind_exception->exception_class == kOurDependentExceptionClass ?\n                        ((__cxa_dependent_exception*)exception_header)->primaryException :\n                        exception_header + 1;\n                const __shim_type_info* thrown_type =\n                    static_cast<const __shim_type_info*>(exception_header->exceptionType);\n                // Try to get demangled name of thrown_type\n                int status;\n                char buf[1024];\n                size_t len = sizeof(buf);\n                const char* name = __cxa_demangle(thrown_type->name(), buf, &len, &status);\n                if (status != 0)\n                    name = thrown_type->name();\n                // If the uncaught exception can be caught with std::exception&\n                const __shim_type_info* catch_type =\n\t\t\t\t static_cast<const __shim_type_info*>(&typeid(std::exception));\n                if (catch_type->can_catch(thrown_type, thrown_object))\n                {\n                    // Include the what() message from the exception\n                    const std::exception* e = static_cast<const std::exception*>(thrown_object);\n                    abort_message(\"terminating with %s exception of type %s: %s\",\n                                  cause, name, e->what());\n                }\n                else\n                    // Else just note that we're terminating with an exception\n                    abort_message(\"terminating with %s exception of type %s\",\n                                   cause, name);\n            }\n            else\n                // Else we're terminating with a foreign exception\n                abort_message(\"terminating with %s foreign exception\", cause);\n        }\n    }\n    // Else just note that we're terminating\n    abort_message(\"terminating\");\n}\n\n__attribute__((noreturn))\nstatic void default_unexpected_handler() \n{\n    cause = \"unexpected\";\n    std::terminate();\n}\n\n\n//\n// Global variables that hold the pointers to the current handler\n//\nstd::terminate_handler  __cxa_terminate_handler = default_terminate_handler;\nstd::unexpected_handler __cxa_unexpected_handler = default_unexpected_handler;\n\n// In the future these will become:\n// std::atomic<std::terminate_handler>  __cxa_terminate_handler(default_terminate_handler);\n// std::atomic<std::unexpected_handler> __cxa_unexpected_handler(default_unexpected_handler);\n\nnamespace std\n{\n\nunexpected_handler\nset_unexpected(unexpected_handler func) _NOEXCEPT\n{\n    if (func == 0)\n        func = default_unexpected_handler;\n    return __atomic_exchange_n(&__cxa_unexpected_handler, func,\n                               __ATOMIC_ACQ_REL);\n//  Using of C++11 atomics this should be rewritten\n//  return __cxa_unexpected_handler.exchange(func, memory_order_acq_rel);\n}\n\nterminate_handler\nset_terminate(terminate_handler func) _NOEXCEPT\n{\n    if (func == 0)\n        func = default_terminate_handler;\n    return __atomic_exchange_n(&__cxa_terminate_handler, func,\n                               __ATOMIC_ACQ_REL);\n//  Using of C++11 atomics this should be rewritten\n//  return __cxa_terminate_handler.exchange(func, memory_order_acq_rel);\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_demangle.cpp",
    "content": "//===-------------------------- cxa_demangle.cpp --------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#define _LIBCPP_EXTERN_TEMPLATE(...)\n#define _LIBCPP_NO_EXCEPTIONS\n\n#include <vector>\n#include <algorithm>\n#include <string>\n#include <numeric>\n#include <cstdlib>\n#include <cstring>\n#include <cctype>\n\nnamespace __cxxabiv1\n{\n\nnamespace\n{\n\nenum\n{\n    unknown_error = -4,\n    invalid_args = -3,\n    invalid_mangled_name,\n    memory_alloc_failure,\n    success\n};\n\ntemplate <class C>\n    const char* parse_type(const char* first, const char* last, C& db);\ntemplate <class C>\n    const char* parse_encoding(const char* first, const char* last, C& db);\ntemplate <class C>\n    const char* parse_name(const char* first, const char* last, C& db,\n                           bool* ends_with_template_args = 0);\ntemplate <class C>\n    const char* parse_expression(const char* first, const char* last, C& db);\ntemplate <class C>\n    const char* parse_template_args(const char* first, const char* last, C& db);\ntemplate <class C>\n    const char* parse_operator_name(const char* first, const char* last, C& db);\ntemplate <class C>\n    const char* parse_unqualified_name(const char* first, const char* last, C& db);\ntemplate <class C>\n    const char* parse_decltype(const char* first, const char* last, C& db);\n\ntemplate <class C>\nvoid\nprint_stack(const C& db)\n{\n    fprintf(stderr, \"---------\\n\");\n    fprintf(stderr, \"names:\\n\");\n    for (auto& s : db.names)\n        fprintf(stderr, \"{%s#%s}\\n\", s.first.c_str(), s.second.c_str());\n    int i = -1;\n    fprintf(stderr, \"subs:\\n\");\n    for (auto& v : db.subs)\n    {\n        if (i >= 0)\n            fprintf(stderr, \"S%i_ = {\", i);\n        else\n            fprintf(stderr, \"S_  = {\");\n        for (auto& s : v)\n            fprintf(stderr, \"{%s#%s}\", s.first.c_str(), s.second.c_str());\n        fprintf(stderr, \"}\\n\");\n        ++i;\n    }\n    fprintf(stderr, \"template_param:\\n\");\n    for (auto& t : db.template_param)\n    {\n        fprintf(stderr, \"--\\n\");\n        i = -1;\n        for (auto& v : t)\n        {\n            if (i >= 0)\n                fprintf(stderr, \"T%i_ = {\", i);\n            else\n                fprintf(stderr, \"T_  = {\");\n            for (auto& s : v)\n                fprintf(stderr, \"{%s#%s}\", s.first.c_str(), s.second.c_str());\n            fprintf(stderr, \"}\\n\");\n            ++i;\n        }\n    }\n    fprintf(stderr, \"---------\\n\\n\");\n}\n\ntemplate <class C>\nvoid\nprint_state(const char* msg, const char* first, const char* last, const C& db)\n{\n    fprintf(stderr, \"%s: \", msg);\n    for (; first != last; ++first)\n        fprintf(stderr, \"%c\", *first);\n    fprintf(stderr, \"\\n\");\n    print_stack(db);\n}\n\n// <number> ::= [n] <non-negative decimal integer>\n\nconst char*\nparse_number(const char* first, const char* last)\n{\n    if (first != last)\n    {\n        const char* t = first;\n        if (*t == 'n')\n            ++t;\n        if (t != last)\n        {\n            if (*t == '0')\n            {\n                first = t+1;\n            }\n            else if ('1' <= *t && *t <= '9')\n            {\n                first = t+1;\n                while (first != last && std::isdigit(*first))\n                    ++first;\n            }\n        }\n    }\n    return first;\n}\n\ntemplate <class Float>\nstruct float_data;\n\ntemplate <>\nstruct float_data<float>\n{\n    static const size_t mangled_size = 8;\n    static const size_t max_demangled_size = 24;\n    static constexpr const char* spec = \"%af\";\n};\n\nconstexpr const char* float_data<float>::spec;\n\ntemplate <>\nstruct float_data<double>\n{\n    static const size_t mangled_size = 16;\n    static const size_t max_demangled_size = 32;\n    static constexpr const char* spec = \"%a\";\n};\n\nconstexpr const char* float_data<double>::spec;\n\ntemplate <>\nstruct float_data<long double>\n{\n#if defined(__mips__) && defined(__mips_n64)\n    static const size_t mangled_size = 32;\n#elif defined(__arm__) || defined(__mips__)\n    static const size_t mangled_size = 16;\n#else\n    static const size_t mangled_size = 20;  // May need to be adjusted to 16 or 24 on other platforms\n#endif\n    static const size_t max_demangled_size = 40;\n    static constexpr const char* spec = \"%LaL\";\n};\n\nconstexpr const char* float_data<long double>::spec;\n\ntemplate <class Float, class C>\nconst char*\nparse_floating_number(const char* first, const char* last, C& db)\n{\n    const size_t N = float_data<Float>::mangled_size;\n    if (static_cast<std::size_t>(last - first) > N)\n    {\n        last = first + N;\n        union\n        {\n            Float value;\n            char buf[sizeof(Float)];\n        };\n        const char* t = first;\n        char* e = buf;\n        for (; t != last; ++t, ++e)\n        {\n            if (!isxdigit(*t))\n                return first;\n            unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0') :\n                                        static_cast<unsigned>(*t - 'a' + 10);\n            ++t;\n            unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0') :\n                                        static_cast<unsigned>(*t - 'a' + 10);\n            *e = static_cast<char>((d1 << 4) + d0);\n        }\n        if (*t == 'E')\n        {\n#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n            std::reverse(buf, e);\n#endif\n            char num[float_data<Float>::max_demangled_size] = {0};\n            int n = snprintf(num, sizeof(num), float_data<Float>::spec, value);\n            if (static_cast<std::size_t>(n) >= sizeof(num))\n                return first;\n            db.names.push_back(typename C::String(num, static_cast<std::size_t>(n)));\n            first = t+1;\n        }\n    }\n    return first;\n}\n\n// <source-name> ::= <positive length number> <identifier>\n\ntemplate <class C>\nconst char*\nparse_source_name(const char* first, const char* last, C& db)\n{\n    if (first != last)\n    {\n        char c = *first;\n        if (isdigit(c) && first+1 != last)\n        {\n            const char* t = first+1;\n            size_t n = static_cast<size_t>(c - '0');\n            for (c = *t; isdigit(c); c = *t)\n            {\n                n = n * 10 + static_cast<size_t>(c - '0');\n                if (++t == last)\n                    return first;\n            }\n            if (static_cast<size_t>(last - t) >= n)\n            {\n                typename C::String r(t, n);\n                if (r.substr(0, 10) == \"_GLOBAL__N\")\n                    db.names.push_back(\"(anonymous namespace)\");\n                else\n                    db.names.push_back(std::move(r));\n                first = t + n;\n            }\n        }\n    }\n    return first;\n}\n\n// <substitution> ::= S <seq-id> _\n//                ::= S_\n// <substitution> ::= Sa # ::std::allocator\n// <substitution> ::= Sb # ::std::basic_string\n// <substitution> ::= Ss # ::std::basic_string < char,\n//                                               ::std::char_traits<char>,\n//                                               ::std::allocator<char> >\n// <substitution> ::= Si # ::std::basic_istream<char,  std::char_traits<char> >\n// <substitution> ::= So # ::std::basic_ostream<char,  std::char_traits<char> >\n// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >\n\ntemplate <class C>\nconst char*\nparse_substitution(const char* first, const char* last, C& db)\n{\n    if (last - first >= 2)\n    {\n        if (*first == 'S')\n        {\n            switch (first[1])\n            {\n            case 'a':\n                db.names.push_back(\"std::allocator\");\n                first += 2;\n                break;\n            case 'b':\n                db.names.push_back(\"std::basic_string\");\n                first += 2;\n                break;\n            case 's':\n                db.names.push_back(\"std::string\");\n                first += 2;\n                break;\n            case 'i':\n                db.names.push_back(\"std::istream\");\n                first += 2;\n                break;\n            case 'o':\n                db.names.push_back(\"std::ostream\");\n                first += 2;\n                break;\n            case 'd':\n                db.names.push_back(\"std::iostream\");\n                first += 2;\n                break;\n            case '_':\n                if (!db.subs.empty())\n                {\n                    for (const auto& n : db.subs.front())\n                        db.names.push_back(n);\n                    first += 2;\n                }\n                break;\n            default:\n                if (std::isdigit(first[1]) || std::isupper(first[1]))\n                {\n                    size_t sub = 0;\n                    const char* t = first+1;\n                    if (std::isdigit(*t))\n                        sub = static_cast<size_t>(*t - '0');\n                    else\n                        sub = static_cast<size_t>(*t - 'A') + 10;\n                    for (++t; t != last && (std::isdigit(*t) || std::isupper(*t)); ++t)\n                    {\n                        sub *= 36;\n                        if (std::isdigit(*t))\n                            sub += static_cast<size_t>(*t - '0');\n                        else\n                            sub += static_cast<size_t>(*t - 'A') + 10;\n                    }\n                    if (t == last || *t != '_')\n                        return first;\n                    ++sub;\n                    if (sub < db.subs.size())\n                    {\n                        for (const auto& n : db.subs[sub])\n                            db.names.push_back(n);\n                        first = t+1;\n                    }\n                }\n                break;\n            }\n        }\n    }\n    return first;\n}\n\n// <builtin-type> ::= v    # void\n//                ::= w    # wchar_t\n//                ::= b    # bool\n//                ::= c    # char\n//                ::= a    # signed char\n//                ::= h    # unsigned char\n//                ::= s    # short\n//                ::= t    # unsigned short\n//                ::= i    # int\n//                ::= j    # unsigned int\n//                ::= l    # long\n//                ::= m    # unsigned long\n//                ::= x    # long long, __int64\n//                ::= y    # unsigned long long, __int64\n//                ::= n    # __int128\n//                ::= o    # unsigned __int128\n//                ::= f    # float\n//                ::= d    # double\n//                ::= e    # long double, __float80\n//                ::= g    # __float128\n//                ::= z    # ellipsis\n//                ::= Dd   # IEEE 754r decimal floating point (64 bits)\n//                ::= De   # IEEE 754r decimal floating point (128 bits)\n//                ::= Df   # IEEE 754r decimal floating point (32 bits)\n//                ::= Dh   # IEEE 754r half-precision floating point (16 bits)\n//                ::= Di   # char32_t\n//                ::= Ds   # char16_t\n//                ::= Da   # auto (in dependent new-expressions)\n//                ::= Dc   # decltype(auto)\n//                ::= Dn   # std::nullptr_t (i.e., decltype(nullptr))\n//                ::= u <source-name>    # vendor extended type\n\ntemplate <class C>\nconst char*\nparse_builtin_type(const char* first, const char* last, C& db)\n{\n    if (first != last)\n    {\n        switch (*first)\n        {\n        case 'v':\n            db.names.push_back(\"void\");\n            ++first;\n            break;\n        case 'w':\n            db.names.push_back(\"wchar_t\");\n            ++first;\n            break;\n        case 'b':\n            db.names.push_back(\"bool\");\n            ++first;\n            break;\n        case 'c':\n            db.names.push_back(\"char\");\n            ++first;\n            break;\n        case 'a':\n            db.names.push_back(\"signed char\");\n            ++first;\n            break;\n        case 'h':\n            db.names.push_back(\"unsigned char\");\n            ++first;\n            break;\n        case 's':\n            db.names.push_back(\"short\");\n            ++first;\n            break;\n        case 't':\n            db.names.push_back(\"unsigned short\");\n            ++first;\n            break;\n        case 'i':\n            db.names.push_back(\"int\");\n            ++first;\n            break;\n        case 'j':\n            db.names.push_back(\"unsigned int\");\n            ++first;\n            break;\n        case 'l':\n            db.names.push_back(\"long\");\n            ++first;\n            break;\n        case 'm':\n            db.names.push_back(\"unsigned long\");\n            ++first;\n            break;\n        case 'x':\n            db.names.push_back(\"long long\");\n            ++first;\n            break;\n        case 'y':\n            db.names.push_back(\"unsigned long long\");\n            ++first;\n            break;\n        case 'n':\n            db.names.push_back(\"__int128\");\n            ++first;\n            break;\n        case 'o':\n            db.names.push_back(\"unsigned __int128\");\n            ++first;\n            break;\n        case 'f':\n            db.names.push_back(\"float\");\n            ++first;\n            break;\n        case 'd':\n            db.names.push_back(\"double\");\n            ++first;\n            break;\n        case 'e':\n            db.names.push_back(\"long double\");\n            ++first;\n            break;\n        case 'g':\n            db.names.push_back(\"__float128\");\n            ++first;\n            break;\n        case 'z':\n            db.names.push_back(\"...\");\n            ++first;\n            break;\n        case 'u':\n            {\n                const char*t = parse_source_name(first+1, last, db);\n                if (t != first+1)\n                    first = t;\n            }\n            break;\n        case 'D':\n            if (first+1 != last)\n            {\n                switch (first[1])\n                {\n                case 'd':\n                    db.names.push_back(\"decimal64\");\n                    first += 2;\n                    break;\n                case 'e':\n                    db.names.push_back(\"decimal128\");\n                    first += 2;\n                    break;\n                case 'f':\n                    db.names.push_back(\"decimal32\");\n                    first += 2;\n                    break;\n                case 'h':\n                    db.names.push_back(\"decimal16\");\n                    first += 2;\n                    break;\n                case 'i':\n                    db.names.push_back(\"char32_t\");\n                    first += 2;\n                    break;\n                case 's':\n                    db.names.push_back(\"char16_t\");\n                    first += 2;\n                    break;\n                case 'a':\n                    db.names.push_back(\"auto\");\n                    first += 2;\n                    break;\n                case 'c':\n                    db.names.push_back(\"decltype(auto)\");\n                    first += 2;\n                    break;\n                case 'n':\n                    db.names.push_back(\"std::nullptr_t\");\n                    first += 2;\n                    break;\n                }\n            }\n            break;\n        }\n    }\n    return first;\n}\n\n// <CV-qualifiers> ::= [r] [V] [K]\n\nconst char*\nparse_cv_qualifiers(const char* first, const char* last, unsigned& cv)\n{\n    cv = 0;\n    if (first != last)\n    {\n        if (*first == 'r')\n        {\n            cv |= 4;\n            ++first;\n        }\n        if (*first == 'V')\n        {\n            cv |= 2;\n            ++first;\n        }\n        if (*first == 'K')\n        {\n            cv |= 1;\n            ++first;\n        }\n    }\n    return first;\n}\n\n// <template-param> ::= T_    # first template parameter\n//                  ::= T <parameter-2 non-negative number> _\n\ntemplate <class C>\nconst char*\nparse_template_param(const char* first, const char* last, C& db)\n{\n    if (last - first >= 2)\n    {\n        if (*first == 'T')\n        {\n            if (first[1] == '_')\n            {\n                if (db.template_param.empty())\n                    return first;\n                if (!db.template_param.back().empty())\n                {\n                    for (auto& t : db.template_param.back().front())\n                        db.names.push_back(t);\n                    first += 2;\n                }\n                else\n                {\n                    db.names.push_back(\"T_\");\n                    first += 2;\n                    db.fix_forward_references = true;\n                }\n            }\n            else if (isdigit(first[1]))\n            {\n                const char* t = first+1;\n                size_t sub = static_cast<size_t>(*t - '0');\n                for (++t; t != last && isdigit(*t); ++t)\n                {\n                    sub *= 10;\n                    sub += static_cast<size_t>(*t - '0');\n                }\n                if (t == last || *t != '_' || db.template_param.empty())\n                    return first;\n                ++sub;\n                if (sub < db.template_param.back().size())\n                {\n                    for (auto& temp : db.template_param.back()[sub])\n                        db.names.push_back(temp);\n                    first = t+1;\n                }\n                else\n                {\n                    db.names.push_back(typename C::String(first, t+1));\n                    first = t+1;\n                    db.fix_forward_references = true;\n                }\n            }\n        }\n    }\n    return first;\n}\n\n// cc <type> <expression>                               # const_cast<type> (expression)\n\ntemplate <class C>\nconst char*\nparse_const_cast_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 'c' && first[1] == 'c')\n    {\n        const char* t = parse_type(first+2, last, db);\n        if (t != first+2)\n        {\n            const char* t1 = parse_expression(t, last, db);\n            if (t1 != t)\n            {\n                if (db.names.size() < 2)\n                    return first;\n                auto expr = db.names.back().move_full();\n                db.names.pop_back();\n                db.names.back() = \"const_cast<\" + db.names.back().move_full() + \">(\" + expr + \")\";\n                first = t1;\n            }\n        }\n    }\n    return first;\n}\n\n// dc <type> <expression>                               # dynamic_cast<type> (expression)\n\ntemplate <class C>\nconst char*\nparse_dynamic_cast_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 'd' && first[1] == 'c')\n    {\n        const char* t = parse_type(first+2, last, db);\n        if (t != first+2)\n        {\n            const char* t1 = parse_expression(t, last, db);\n            if (t1 != t)\n            {\n                if (db.names.size() < 2)\n                    return first;\n                auto expr = db.names.back().move_full();\n                db.names.pop_back();\n                db.names.back() = \"dynamic_cast<\" + db.names.back().move_full() + \">(\" + expr + \")\";\n                first = t1;\n            }\n        }\n    }\n    return first;\n}\n\n// rc <type> <expression>                               # reinterpret_cast<type> (expression)\n\ntemplate <class C>\nconst char*\nparse_reinterpret_cast_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 'r' && first[1] == 'c')\n    {\n        const char* t = parse_type(first+2, last, db);\n        if (t != first+2)\n        {\n            const char* t1 = parse_expression(t, last, db);\n            if (t1 != t)\n            {\n                if (db.names.size() < 2)\n                    return first;\n                auto expr = db.names.back().move_full();\n                db.names.pop_back();\n                db.names.back() = \"reinterpret_cast<\" + db.names.back().move_full() + \">(\" + expr + \")\";\n                first = t1;\n            }\n        }\n    }\n    return first;\n}\n\n// sc <type> <expression>                               # static_cast<type> (expression)\n\ntemplate <class C>\nconst char*\nparse_static_cast_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 's' && first[1] == 'c')\n    {\n        const char* t = parse_type(first+2, last, db);\n        if (t != first+2)\n        {\n            const char* t1 = parse_expression(t, last, db);\n            if (t1 != t)\n            {\n                if (db.names.size() < 2)\n                    return first;\n                auto expr = db.names.back().move_full();\n                db.names.pop_back();\n                db.names.back() = \"static_cast<\" + db.names.back().move_full() + \">(\" + expr + \")\";\n                first = t1;\n            }\n        }\n    }\n    return first;\n}\n\n// sp <expression>                                  # pack expansion\n\ntemplate <class C>\nconst char*\nparse_pack_expansion(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 's' && first[1] == 'p')\n    {\n        const char* t = parse_expression(first+2, last, db);\n        if (t != first+2)\n            first = t;\n    }\n    return first;\n}\n\n// st <type>                                            # sizeof (a type)\n\ntemplate <class C>\nconst char*\nparse_sizeof_type_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 's' && first[1] == 't')\n    {\n        const char* t = parse_type(first+2, last, db);\n        if (t != first+2)\n        {\n            if (db.names.empty())\n                return first;\n            db.names.back() = \"sizeof (\" + db.names.back().move_full() + \")\";\n            first = t;\n        }\n    }\n    return first;\n}\n\n// sz <expr>                                            # sizeof (a expression)\n\ntemplate <class C>\nconst char*\nparse_sizeof_expr_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 's' && first[1] == 'z')\n    {\n        const char* t = parse_expression(first+2, last, db);\n        if (t != first+2)\n        {\n            if (db.names.empty())\n                return first;\n            db.names.back() = \"sizeof (\" + db.names.back().move_full() + \")\";\n            first = t;\n        }\n    }\n    return first;\n}\n\n// sZ <template-param>                                  # size of a parameter pack\n\ntemplate <class C>\nconst char*\nparse_sizeof_param_pack_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'T')\n    {\n        size_t k0 = db.names.size();\n        const char* t = parse_template_param(first+2, last, db);\n        size_t k1 = db.names.size();\n        if (t != first+2)\n        {\n            typename C::String tmp(\"sizeof...(\");\n            size_t k = k0;\n            if (k != k1)\n            {\n                tmp += db.names[k].move_full();\n                for (++k; k != k1; ++k)\n                    tmp += \", \" + db.names[k].move_full();\n            }\n            tmp += \")\";\n            for (; k1 != k0; --k1)\n                db.names.pop_back();\n            db.names.push_back(std::move(tmp));\n            first = t;\n        }\n    }\n    return first;\n}\n\n// <function-param> ::= fp <top-level CV-qualifiers> _                                     # L == 0, first parameter\n//                  ::= fp <top-level CV-qualifiers> <parameter-2 non-negative number> _   # L == 0, second and later parameters\n//                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> _         # L > 0, first parameter\n//                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> <parameter-2 non-negative number> _   # L > 0, second and later parameters\n\ntemplate <class C>\nconst char*\nparse_function_param(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && *first == 'f')\n    {\n        if (first[1] == 'p')\n        {\n            unsigned cv;\n            const char* t = parse_cv_qualifiers(first+2, last, cv);\n            const char* t1 = parse_number(t, last);\n            if (t1 != last && *t1 == '_')\n            {\n                db.names.push_back(\"fp\" + typename C::String(t, t1));\n                first = t1+1;\n            }\n        }\n        else if (first[1] == 'L')\n        {\n            unsigned cv;\n            const char* t0 = parse_number(first+2, last);\n            if (t0 != last && *t0 == 'p')\n            {\n                ++t0;\n                const char* t = parse_cv_qualifiers(t0, last, cv);\n                const char* t1 = parse_number(t, last);\n                if (t1 != last && *t1 == '_')\n                {\n                    db.names.push_back(\"fp\" + typename C::String(t, t1));\n                    first = t1+1;\n                }\n            }\n        }\n    }\n    return first;\n}\n\n// sZ <function-param>                                  # size of a function parameter pack\n\ntemplate <class C>\nconst char*\nparse_sizeof_function_param_pack_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'f')\n    {\n        const char* t = parse_function_param(first+2, last, db);\n        if (t != first+2)\n        {\n            if (db.names.empty())\n                return first;\n            db.names.back() = \"sizeof...(\" + db.names.back().move_full() + \")\";\n            first = t;\n        }\n    }\n    return first;\n}\n\n// te <expression>                                      # typeid (expression)\n// ti <type>                                            # typeid (type)\n\ntemplate <class C>\nconst char*\nparse_typeid_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 't' && (first[1] == 'e' || first[1] == 'i'))\n    {\n        const char* t;\n        if (first[1] == 'e')\n            t = parse_expression(first+2, last, db);\n        else\n            t = parse_type(first+2, last, db);\n        if (t != first+2)\n        {\n            if (db.names.empty())\n                return first;\n            db.names.back() = \"typeid(\" + db.names.back().move_full() + \")\";\n            first = t;\n        }\n    }\n    return first;\n}\n\n// tw <expression>                                      # throw expression\n\ntemplate <class C>\nconst char*\nparse_throw_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 't' && first[1] == 'w')\n    {\n        const char* t = parse_expression(first+2, last, db);\n        if (t != first+2)\n        {\n            if (db.names.empty())\n                return first;\n            db.names.back() = \"throw \" + db.names.back().move_full();\n            first = t;\n        }\n    }\n    return first;\n}\n\n// ds <expression> <expression>                         # expr.*expr\n\ntemplate <class C>\nconst char*\nparse_dot_star_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 'd' && first[1] == 's')\n    {\n        const char* t = parse_expression(first+2, last, db);\n        if (t != first+2)\n        {\n            const char* t1 = parse_expression(t, last, db);\n            if (t1 != t)\n            {\n                if (db.names.size() < 2)\n                    return first;\n                auto expr = db.names.back().move_full();\n                db.names.pop_back();\n                db.names.back().first += \".*\" + expr;\n                first = t1;\n            }\n        }\n    }\n    return first;\n}\n\n// <simple-id> ::= <source-name> [ <template-args> ]\n\ntemplate <class C>\nconst char*\nparse_simple_id(const char* first, const char* last, C& db)\n{\n    if (first != last)\n    {\n        const char* t = parse_source_name(first, last, db);\n        if (t != first)\n        {\n            const char* t1 = parse_template_args(t, last, db);\n            if (t1 != t)\n            {\n                if (db.names.size() < 2)\n                    return first;\n                auto args = db.names.back().move_full();\n                db.names.pop_back();\n                db.names.back().first += std::move(args);\n            }\n            first = t1;\n        }\n        else\n            first = t;\n    }\n    return first;\n}\n\n// <unresolved-type> ::= <template-param>\n//                   ::= <decltype>\n//                   ::= <substitution>\n\ntemplate <class C>\nconst char*\nparse_unresolved_type(const char* first, const char* last, C& db)\n{\n    if (first != last)\n    {\n        const char* t = first;\n        switch (*first)\n        {\n        case 'T':\n          {\n            size_t k0 = db.names.size();\n            t = parse_template_param(first, last, db);\n            size_t k1 = db.names.size();\n            if (t != first && k1 == k0 + 1)\n            {\n                db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                first = t;\n            }\n            else\n            {\n                for (; k1 != k0; --k1)\n                    db.names.pop_back();\n            }\n            break;\n          }\n        case 'D':\n            t = parse_decltype(first, last, db);\n            if (t != first)\n            {\n                if (db.names.empty())\n                    return first;\n                db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                first = t;\n            }\n            break;\n        case 'S':\n            t = parse_substitution(first, last, db);\n            if (t != first)\n                first = t;\n            else\n            {\n                if (last - first > 2 && first[1] == 't')\n                {\n                    t = parse_unqualified_name(first+2, last, db);\n                    if (t != first+2)\n                    {\n                        if (db.names.empty())\n                            return first;\n                        db.names.back().first.insert(0, \"std::\");\n                        db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                        first = t;\n                    }\n                }\n            }\n            break;\n       }\n    }\n    return first;\n}\n\n// <destructor-name> ::= <unresolved-type>                               # e.g., ~T or ~decltype(f())\n//                   ::= <simple-id>                                     # e.g., ~A<2*N>\n\ntemplate <class C>\nconst char*\nparse_destructor_name(const char* first, const char* last, C& db)\n{\n    if (first != last)\n    {\n        const char* t = parse_unresolved_type(first, last, db);\n        if (t == first)\n            t = parse_simple_id(first, last, db);\n        if (t != first)\n        {\n            if (db.names.empty())\n                return first;\n            db.names.back().first.insert(0, \"~\");\n            first = t;\n        }\n    }\n    return first;\n}\n\n// <base-unresolved-name> ::= <simple-id>                                # unresolved name\n//          extension     ::= <operator-name>                            # unresolved operator-function-id\n//          extension     ::= <operator-name> <template-args>            # unresolved operator template-id\n//                        ::= on <operator-name>                         # unresolved operator-function-id\n//                        ::= on <operator-name> <template-args>         # unresolved operator template-id\n//                        ::= dn <destructor-name>                       # destructor or pseudo-destructor;\n//                                                                         # e.g. ~X or ~X<N-1>\n\ntemplate <class C>\nconst char*\nparse_base_unresolved_name(const char* first, const char* last, C& db)\n{\n    if (last - first >= 2)\n    {\n        if ((first[0] == 'o' || first[0] == 'd') && first[1] == 'n')\n        {\n            if (first[0] == 'o')\n            {\n                const char* t = parse_operator_name(first+2, last, db);\n                if (t != first+2)\n                {\n                    first = parse_template_args(t, last, db);\n                    if (first != t)\n                    {\n                        if (db.names.size() < 2)\n                            return first;\n                        auto args = db.names.back().move_full();\n                        db.names.pop_back();\n                        db.names.back().first += std::move(args);\n                    }\n                }\n            }\n            else\n            {\n                const char* t = parse_destructor_name(first+2, last, db);\n                if (t != first+2)\n                    first = t;\n            }\n        }\n        else\n        {\n            const char* t = parse_simple_id(first, last, db);\n            if (t == first)\n            {\n                t = parse_operator_name(first, last, db);\n                if (t != first)\n                {\n                    first = parse_template_args(t, last, db);\n                    if (first != t)\n                    {\n                        if (db.names.size() < 2)\n                            return first;\n                        auto args = db.names.back().move_full();\n                        db.names.pop_back();\n                        db.names.back().first += std::move(args);\n                    }\n                }\n            }\n            else\n                first = t;\n        }\n    }\n    return first;\n}\n\n// <unresolved-qualifier-level> ::= <simple-id>\n\ntemplate <class C>\nconst char*\nparse_unresolved_qualifier_level(const char* first, const char* last, C& db)\n{\n    return parse_simple_id(first, last, db);\n}\n\n// <unresolved-name>\n//  extension        ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>\n//                   ::= [gs] <base-unresolved-name>                     # x or (with \"gs\") ::x\n//                   ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>  \n//                                                                       # A::x, N::y, A<T>::z; \"gs\" means leading \"::\"\n//                   ::= sr <unresolved-type> <base-unresolved-name>     # T::x / decltype(p)::x\n//  extension        ::= sr <unresolved-type> <template-args> <base-unresolved-name>\n//                                                                       # T::N::x /decltype(p)::N::x\n//  (ignored)        ::= srN <unresolved-type>  <unresolved-qualifier-level>+ E <base-unresolved-name>\n\ntemplate <class C>\nconst char*\nparse_unresolved_name(const char* first, const char* last, C& db)\n{\n    if (last - first > 2)\n    {\n        const char* t = first;\n        bool global = false;\n        if (t[0] == 'g' && t[1] == 's')\n        {\n            global = true;\n            t += 2;\n        }\n        const char* t2 = parse_base_unresolved_name(t, last, db);\n        if (t2 != t)\n        {\n            if (global)\n            {\n                if (db.names.empty())\n                    return first;\n                db.names.back().first.insert(0, \"::\");\n            }\n            first = t2;\n        }\n        else if (last - t > 2 && t[0] == 's' && t[1] == 'r')\n        {\n            if (t[2] == 'N')\n            {\n                t += 3;\n                const char* t1 = parse_unresolved_type(t, last, db);\n                if (t1 == t || t1 == last)\n                    return first;\n                t = t1;\n                t1 = parse_template_args(t, last, db);\n                if (t1 != t)\n                {\n                    if (db.names.size() < 2)\n                        return first;\n                    auto args = db.names.back().move_full();\n                    db.names.pop_back();\n                    db.names.back().first += std::move(args);\n                    t = t1;\n                    if (t == last)\n                    {\n                        db.names.pop_back();\n                        return first;\n                    }\n                }\n                while (*t != 'E')\n                {\n                    t1 = parse_unresolved_qualifier_level(t, last, db);\n                    if (t1 == t || t1 == last || db.names.size() < 2)\n                        return first;\n                    auto s = db.names.back().move_full();\n                    db.names.pop_back();\n                    db.names.back().first += \"::\" + std::move(s);\n                    t = t1;\n                }\n                ++t;\n                t1 = parse_base_unresolved_name(t, last, db);\n                if (t1 == t)\n                {\n                    if (!db.names.empty())\n                        db.names.pop_back();\n                    return first;\n                }\n                if (db.names.size() < 2)\n                    return first;\n                auto s = db.names.back().move_full();\n                db.names.pop_back();\n                db.names.back().first += \"::\" + std::move(s);\n                first = t1;\n            }\n            else\n            {\n                t += 2;\n                const char* t1 = parse_unresolved_type(t, last, db);\n                if (t1 != t)\n                {\n                    t = t1;\n                    t1 = parse_template_args(t, last, db);\n                    if (t1 != t)\n                    {\n                        if (db.names.size() < 2)\n                            return first;\n                        auto args = db.names.back().move_full();\n                        db.names.pop_back();\n                        db.names.back().first += std::move(args);\n                        t = t1;\n                    }\n                    t1 = parse_base_unresolved_name(t, last, db);\n                    if (t1 == t)\n                    {\n                        if (!db.names.empty())\n                            db.names.pop_back();\n                        return first;\n                    }\n                    if (db.names.size() < 2)\n                        return first;\n                    auto s = db.names.back().move_full();\n                    db.names.pop_back();\n                    db.names.back().first += \"::\" + std::move(s);\n                    first = t1;\n                }\n                else\n                {\n                    t1 = parse_unresolved_qualifier_level(t, last, db);\n                    if (t1 == t || t1 == last)\n                        return first;\n                    t = t1;\n                    if (global)\n                    {\n                        if (db.names.empty())\n                            return first;\n                        db.names.back().first.insert(0, \"::\");\n                    }\n                    while (*t != 'E')\n                    {\n                        t1 = parse_unresolved_qualifier_level(t, last, db);\n                        if (t1 == t || t1 == last || db.names.size() < 2)\n                            return first;\n                        auto s = db.names.back().move_full();\n                        db.names.pop_back();\n                        db.names.back().first += \"::\" + std::move(s);\n                        t = t1;\n                    }\n                    ++t;\n                    t1 = parse_base_unresolved_name(t, last, db);\n                    if (t1 == t)\n                    {\n                        if (!db.names.empty())\n                            db.names.pop_back();\n                        return first;\n                    }\n                    if (db.names.size() < 2)\n                        return first;\n                    auto s = db.names.back().move_full();\n                    db.names.pop_back();\n                    db.names.back().first += \"::\" + std::move(s);\n                    first = t1;\n                }\n            }\n        }\n    }\n    return first;\n}\n\n// dt <expression> <unresolved-name>                    # expr.name\n\ntemplate <class C>\nconst char*\nparse_dot_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 'd' && first[1] == 't')\n    {\n        const char* t = parse_expression(first+2, last, db);\n        if (t != first+2)\n        {\n            const char* t1 = parse_unresolved_name(t, last, db);\n            if (t1 != t)\n            {\n                if (db.names.size() < 2)\n                    return first;\n                auto name = db.names.back().move_full();\n                db.names.pop_back();\n                db.names.back().first += \".\" + name;\n                first = t1;\n            }\n        }\n    }\n    return first;\n}\n\n// cl <expression>+ E                                   # call\n\ntemplate <class C>\nconst char*\nparse_call_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 4 && first[0] == 'c' && first[1] == 'l')\n    {\n        const char* t = parse_expression(first+2, last, db);\n        if (t != first+2)\n        {\n            if (t == last)\n                return first;\n            if (db.names.empty())\n                return first;\n            db.names.back().first += db.names.back().second;\n            db.names.back().second = typename C::String();\n            db.names.back().first.append(\"(\");\n            bool first_expr = true;\n            while (*t != 'E')\n            {\n                const char* t1 = parse_expression(t, last, db);\n                if (t1 == t || t1 == last)\n                    return first;\n                if (db.names.empty())\n                    return first;\n                auto tmp = db.names.back().move_full();\n                db.names.pop_back();\n                if (!tmp.empty())\n                {\n                    if (db.names.empty())\n                        return first;\n                    if (!first_expr)\n                    {\n                        db.names.back().first.append(\", \");\n                        first_expr = false;\n                    }\n                    db.names.back().first.append(tmp);\n                }\n                t = t1;\n            }\n            ++t;\n            if (db.names.empty())\n                return first;\n            db.names.back().first.append(\")\");\n            first = t;\n        }\n    }\n    return first;\n}\n\n// [gs] nw <expression>* _ <type> E                     # new (expr-list) type\n// [gs] nw <expression>* _ <type> <initializer>         # new (expr-list) type (init)\n// [gs] na <expression>* _ <type> E                     # new[] (expr-list) type\n// [gs] na <expression>* _ <type> <initializer>         # new[] (expr-list) type (init)\n// <initializer> ::= pi <expression>* E                 # parenthesized initialization\n\ntemplate <class C>\nconst char*\nparse_new_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 4)\n    {\n        const char* t = first;\n        bool parsed_gs = false;\n        if (t[0] == 'g' && t[1] == 's')\n        {\n            t += 2;\n            parsed_gs = true;\n        }\n        if (t[0] == 'n' && (t[1] == 'w' || t[1] == 'a'))\n        {\n            bool is_array = t[1] == 'a';\n            t += 2;\n            if (t == last)\n                return first;\n            bool has_expr_list = false;\n            bool first_expr = true;\n            while (*t != '_')\n            {\n                const char* t1 = parse_expression(t, last, db);\n                if (t1 == t || t1 == last)\n                    return first;\n                has_expr_list = true;\n                if (!first_expr)\n                {\n                    if (db.names.empty())\n                        return first;\n                    auto tmp = db.names.back().move_full();\n                    db.names.pop_back();\n                    if (!tmp.empty())\n                    {\n                        if (db.names.empty())\n                            return first;\n                        db.names.back().first.append(\", \");\n                        db.names.back().first.append(tmp);\n                        first_expr = false;\n                    }\n                }\n                t = t1;\n            }\n            ++t;\n            const char* t1 = parse_type(t, last, db);\n            if (t1 == t || t1 == last)\n                return first;\n            t = t1;\n            bool has_init = false;\n            if (last - t >= 3 && t[0] == 'p' && t[1] == 'i')\n            {\n                t += 2;\n                has_init = true;\n                first_expr = true;\n                while (*t != 'E')\n                {\n                    t1 = parse_expression(t, last, db);\n                    if (t1 == t || t1 == last)\n                        return first;\n                    if (!first_expr)\n                    {\n                        if (db.names.empty())\n                            return first;\n                        auto tmp = db.names.back().move_full();\n                        db.names.pop_back();\n                        if (!tmp.empty())\n                        {\n                            if (db.names.empty())\n                                return first;\n                            db.names.back().first.append(\", \");\n                            db.names.back().first.append(tmp);\n                            first_expr = false;\n                        }\n                    }\n                    t = t1;\n                }\n            }\n            if (*t != 'E')\n                return first;\n            typename C::String init_list;\n            if (has_init)\n            {\n                if (db.names.empty())\n                    return first;\n                init_list = db.names.back().move_full();\n                db.names.pop_back();\n            }\n            if (db.names.empty())\n                return first;\n            auto type = db.names.back().move_full();\n            db.names.pop_back();\n            typename C::String expr_list;\n            if (has_expr_list)\n            {\n                if (db.names.empty())\n                    return first;\n                expr_list = db.names.back().move_full();\n                db.names.pop_back();\n            }\n            typename C::String r;\n            if (parsed_gs)\n                r = \"::\";\n            if (is_array)\n                r += \"[] \";\n            else\n                r += \" \";\n            if (has_expr_list)\n                r += \"(\" + expr_list + \") \";\n            r += type;\n            if (has_init)\n                r += \" (\" + init_list + \")\";\n            db.names.push_back(std::move(r));\n            first = t+1;\n        }\n    }\n    return first;\n}\n\n// cv <type> <expression>                               # conversion with one argument\n// cv <type> _ <expression>* E                          # conversion with a different number of arguments\n\ntemplate <class C>\nconst char*\nparse_conversion_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 'c' && first[1] == 'v')\n    {\n        bool try_to_parse_template_args = db.try_to_parse_template_args;\n        db.try_to_parse_template_args = false;\n        const char* t = parse_type(first+2, last, db);\n        db.try_to_parse_template_args = try_to_parse_template_args;\n        if (t != first+2 && t != last)\n        {\n            if (*t != '_')\n            {\n                const char* t1 = parse_expression(t, last, db);\n                if (t1 == t)\n                    return first;\n                t = t1;\n            }\n            else\n            {\n                ++t;\n                if (t == last)\n                    return first;\n                if (*t == 'E')\n                    db.names.emplace_back();\n                else\n                {\n                    bool first_expr = true;\n                    while (*t != 'E')\n                    {\n                        const char* t1 = parse_expression(t, last, db);\n                        if (t1 == t || t1 == last)\n                            return first;\n                        if (!first_expr)\n                        {\n                            if (db.names.empty())\n                                return first;\n                            auto tmp = db.names.back().move_full();\n                            db.names.pop_back();\n                            if (!tmp.empty())\n                            {\n                                if (db.names.empty())\n                                    return first;\n                                db.names.back().first.append(\", \");\n                                db.names.back().first.append(tmp);\n                                first_expr = false;\n                            }\n                        }\n                        t = t1;\n                    }\n                }\n                ++t;\n            }\n            if (db.names.size() < 2)\n                return first;\n            auto tmp = db.names.back().move_full();\n            db.names.pop_back();\n            db.names.back() = \"(\" + db.names.back().move_full() + \")(\" + tmp + \")\";\n            first = t;\n        }\n    }\n    return first;\n}\n\n// pt <expression> <expression>                    # expr->name\n\ntemplate <class C>\nconst char*\nparse_arrow_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 'p' && first[1] == 't')\n    {\n        const char* t = parse_expression(first+2, last, db);\n        if (t != first+2)\n        {\n            const char* t1 = parse_expression(t, last, db);\n            if (t1 != t)\n            {\n                if (db.names.size() < 2)\n                    return first;\n                auto tmp = db.names.back().move_full();\n                db.names.pop_back();\n                db.names.back().first += \"->\";\n                db.names.back().first += tmp;\n                first = t1;\n            }\n        }\n    }\n    return first;\n}\n\n//  <ref-qualifier> ::= R                   # & ref-qualifier\n//  <ref-qualifier> ::= O                   # && ref-qualifier\n\n// <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E\n\ntemplate <class C>\nconst char*\nparse_function_type(const char* first, const char* last, C& db)\n{\n    if (first != last && *first == 'F')\n    {\n        const char* t = first+1;\n        if (t != last)\n        {\n            if (*t == 'Y')\n            {\n                /* extern \"C\" */\n                if (++t == last)\n                    return first;\n            }\n            const char* t1 = parse_type(t, last, db);\n            if (t1 != t)\n            {\n                t = t1;\n                typename C::String sig(\"(\");\n                int ref_qual = 0;\n                while (true)\n                {\n                    if (t == last)\n                    {\n                        db.names.pop_back();\n                        return first;\n                    }\n                    if (*t == 'E')\n                    {\n                        ++t;\n                        break;\n                    }\n                    if (*t == 'v')\n                    {\n                        ++t;\n                        continue;\n                    }\n                    if (*t == 'R' && t+1 != last && t[1] == 'E')\n                    {\n                        ref_qual = 1;\n                        ++t;\n                        continue;\n                    }\n                    if (*t == 'O' && t+1 != last && t[1] == 'E')\n                    {\n                        ref_qual = 2;\n                        ++t;\n                        continue;\n                    }\n                    size_t k0 = db.names.size();\n                    t1 = parse_type(t, last, db);\n                    size_t k1 = db.names.size();\n                    if (t1 == t || t1 == last)\n                        return first;\n                    for (size_t k = k0; k < k1; ++k)\n                    {\n                        if (sig.size() > 1)\n                            sig += \", \";\n                        sig += db.names[k].move_full();\n                    }\n                    for (size_t k = k0; k < k1; ++k)\n                        db.names.pop_back();\n                    t = t1;\n                }\n                sig += \")\";\n                switch (ref_qual)\n                {\n                case 1:\n                    sig += \" &\";\n                    break;\n                case 2:\n                    sig += \" &&\";\n                    break;\n                }\n                if (db.names.empty())\n                    return first;\n                db.names.back().first += \" \";\n                db.names.back().second.insert(0, sig);\n                first = t;\n            }\n        }\n    }\n    return first;\n}\n\n// <pointer-to-member-type> ::= M <class type> <member type>\n\ntemplate <class C>\nconst char*\nparse_pointer_to_member_type(const char* first, const char* last, C& db)\n{\n    if (first != last && *first == 'M')\n    {\n        const char* t = parse_type(first+1, last, db);\n        if (t != first+1)\n        {\n            const char* t2 = parse_type(t, last, db);\n            if (t2 != t)\n            {\n                if (db.names.size() < 2)\n                    return first;\n                auto func = std::move(db.names.back());\n                db.names.pop_back();\n                auto class_type = std::move(db.names.back());\n                if (!func.second.empty() && func.second.front() == '(')\n                {\n                    db.names.back().first = std::move(func.first) + \"(\" + class_type.move_full() + \"::*\";\n                    db.names.back().second = \")\" + std::move(func.second);\n                }\n                else\n                {\n                    db.names.back().first = std::move(func.first) + \" \" + class_type.move_full() + \"::*\";\n                    db.names.back().second = std::move(func.second);\n                }\n                first = t2;\n            }\n        }\n    }\n    return first;\n}\n\n// <array-type> ::= A <positive dimension number> _ <element type>\n//              ::= A [<dimension expression>] _ <element type>\n\ntemplate <class C>\nconst char*\nparse_array_type(const char* first, const char* last, C& db)\n{\n    if (first != last && *first == 'A' && first+1 != last)\n    {\n        if (first[1] == '_')\n        {\n            const char* t = parse_type(first+2, last, db);\n            if (t != first+2)\n            {\n                if (db.names.empty())\n                    return first;\n                if (db.names.back().second.substr(0, 2) == \" [\")\n                    db.names.back().second.erase(0, 1);\n                db.names.back().second.insert(0, \" []\");\n                first = t;\n            }\n        }\n        else if ('1' <= first[1] && first[1] <= '9')\n        {\n            const char* t = parse_number(first+1, last);\n            if (t != last && *t == '_')\n            {\n                const char* t2 = parse_type(t+1, last, db);\n                if (t2 != t+1)\n                {\n                    if (db.names.empty())\n                        return first;\n                    if (db.names.back().second.substr(0, 2) == \" [\")\n                        db.names.back().second.erase(0, 1);\n                    db.names.back().second.insert(0, \" [\" + typename C::String(first+1, t) + \"]\");\n                    first = t2;\n                }\n            }\n        }\n        else\n        {\n            const char* t = parse_expression(first+1, last, db);\n            if (t != first+1 && t != last && *t == '_')\n            {\n                const char* t2 = parse_type(++t, last, db);\n                if (t2 != t)\n                {\n                    if (db.names.size() < 2)\n                        return first;\n                    auto type = std::move(db.names.back());\n                    db.names.pop_back();\n                    auto expr = std::move(db.names.back());\n                    db.names.back().first = std::move(type.first);\n                    if (type.second.substr(0, 2) == \" [\")\n                        type.second.erase(0, 1);\n                    db.names.back().second = \" [\" + expr.move_full() + \"]\" + std::move(type.second);\n                    first = t2;\n                }\n            }\n        }\n    }\n    return first;\n}\n\n// <decltype>  ::= Dt <expression> E  # decltype of an id-expression or class member access (C++0x)\n//             ::= DT <expression> E  # decltype of an expression (C++0x)\n\ntemplate <class C>\nconst char*\nparse_decltype(const char* first, const char* last, C& db)\n{\n    if (last - first >= 4 && first[0] == 'D')\n    {\n        switch (first[1])\n        {\n        case 't':\n        case 'T':\n            {\n                const char* t = parse_expression(first+2, last, db);\n                if (t != first+2 && t != last && *t == 'E')\n                {\n                    if (db.names.empty())\n                        return first;\n                    db.names.back() = \"decltype(\" + db.names.back().move_full() + \")\";\n                    first = t+1;\n                }\n            }\n            break;\n        }\n    }\n    return first;\n}\n\n// extension:\n// <vector-type>           ::= Dv <positive dimension number> _\n//                                    <extended element type>\n//                         ::= Dv [<dimension expression>] _ <element type>\n// <extended element type> ::= <element type>\n//                         ::= p # AltiVec vector pixel\n\ntemplate <class C>\nconst char*\nparse_vector_type(const char* first, const char* last, C& db)\n{\n    if (last - first > 3 && first[0] == 'D' && first[1] == 'v')\n    {\n        if ('1' <= first[2] && first[2] <= '9')\n        {\n            const char* t = parse_number(first+2, last);\n            if (t == last || *t != '_')\n                return first;\n            const char* num = first + 2;\n            size_t sz = static_cast<size_t>(t - num);\n            if (++t != last)\n            {\n                if (*t != 'p')\n                {\n                    const char* t1 = parse_type(t, last, db);\n                    if (t1 != t)\n                    {\n                        if (db.names.empty())\n                            return first;\n                        db.names.back().first += \" vector[\" + typename C::String(num, sz) + \"]\";\n                        first = t1;\n                    }\n                }\n                else\n                {\n                    ++t;\n                    db.names.push_back(\"pixel vector[\" + typename C::String(num, sz) + \"]\");\n                    first = t;\n                }\n            }\n        }\n        else\n        {\n            typename C::String num;\n            const char* t1 = first+2;\n            if (*t1 != '_')\n            {\n                const char* t = parse_expression(t1, last, db);\n                if (t != t1)\n                {\n                    if (db.names.empty())\n                        return first;\n                    num = db.names.back().move_full();\n                    db.names.pop_back();\n                    t1 = t;\n                }\n            }\n            if (t1 != last && *t1 == '_' && ++t1 != last)\n            {\n                const char* t = parse_type(t1, last, db);\n                if (t != t1)\n                {\n                    if (db.names.empty())\n                        return first;\n                    db.names.back().first += \" vector[\" + num + \"]\";\n                    first = t;\n                }\n            }\n        }\n    }\n    return first;\n}\n\n// <type> ::= <builtin-type>\n//        ::= <function-type>\n//        ::= <class-enum-type>\n//        ::= <array-type>\n//        ::= <pointer-to-member-type>\n//        ::= <template-param>\n//        ::= <template-template-param> <template-args>\n//        ::= <decltype>\n//        ::= <substitution>\n//        ::= <CV-qualifiers> <type>\n//        ::= P <type>        # pointer-to\n//        ::= R <type>        # reference-to\n//        ::= O <type>        # rvalue reference-to (C++0x)\n//        ::= C <type>        # complex pair (C 2000)\n//        ::= G <type>        # imaginary (C 2000)\n//        ::= Dp <type>       # pack expansion (C++0x)\n//        ::= U <source-name> <type>  # vendor extended type qualifier\n// extension := U <objc-name> <objc-type>  # objc-type<identifier>\n// extension := <vector-type> # <vector-type> starts with Dv\n\n// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier>  # k0 = 9 + <number of digits in k1> + k1\n// <objc-type> := <source-name>  # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>\n\ntemplate <class C>\nconst char*\nparse_type(const char* first, const char* last, C& db)\n{\n    if (first != last)\n    {\n        switch (*first)\n        {\n            case 'r':\n            case 'V':\n            case 'K':\n              {\n                unsigned cv = 0;\n                const char* t = parse_cv_qualifiers(first, last, cv);\n                if (t != first)\n                {\n                    bool is_function = *t == 'F';\n                    size_t k0 = db.names.size();\n                    const char* t1 = parse_type(t, last, db);\n                    size_t k1 = db.names.size();\n                    if (t1 != t)\n                    {\n                        if (is_function)\n                            db.subs.pop_back();\n                        db.subs.emplace_back(db.names.get_allocator());\n                        for (size_t k = k0; k < k1; ++k)\n                        {\n                            if (is_function)\n                            {\n                                size_t p = db.names[k].second.size();\n                                if (db.names[k].second[p-2] == '&')\n                                    p -= 3;\n                                else if (db.names[k].second.back() == '&')\n                                    p -= 2;\n                                if (cv & 1)\n                                {\n                                    db.names[k].second.insert(p, \" const\");\n                                    p += 6;\n                                }\n                                if (cv & 2)\n                                {\n                                    db.names[k].second.insert(p, \" volatile\");\n                                    p += 9;\n                                }\n                                if (cv & 4)\n                                    db.names[k].second.insert(p, \" restrict\");\n                            }\n                            else\n                            {\n                                if (cv & 1)\n                                    db.names[k].first.append(\" const\");\n                                if (cv & 2)\n                                    db.names[k].first.append(\" volatile\");\n                                if (cv & 4)\n                                    db.names[k].first.append(\" restrict\");\n                            }\n                            db.subs.back().push_back(db.names[k]);\n                        }\n                        first = t1;\n                    }\n                }\n              }\n                break;\n            default:\n              {\n                const char* t = parse_builtin_type(first, last, db);\n                if (t != first)\n                {\n                    first = t;\n                }\n                else\n                {\n                    switch (*first)\n                    {\n                    case 'A':\n                        t = parse_array_type(first, last, db);\n                        if (t != first)\n                        {\n                            if (db.names.empty())\n                                return first;\n                            first = t;\n                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                        }\n                        break;\n                    case 'C':\n                        t = parse_type(first+1, last, db);\n                        if (t != first+1)\n                        {\n                            if (db.names.empty())\n                                return first;\n                            db.names.back().first.append(\" complex\");\n                            first = t;\n                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                        }\n                        break;\n                    case 'F':\n                        t = parse_function_type(first, last, db);\n                        if (t != first)\n                        {\n                            if (db.names.empty())\n                                return first;\n                            first = t;\n                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                        }\n                        break;\n                    case 'G':\n                        t = parse_type(first+1, last, db);\n                        if (t != first+1)\n                        {\n                            if (db.names.empty())\n                                return first;\n                            db.names.back().first.append(\" imaginary\");\n                            first = t;\n                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                        }\n                        break;\n                    case 'M':\n                        t = parse_pointer_to_member_type(first, last, db);\n                        if (t != first)\n                        {\n                            if (db.names.empty())\n                                return first;\n                            first = t;\n                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                        }\n                        break;\n                    case 'O':\n                      {\n                        size_t k0 = db.names.size();\n                        t = parse_type(first+1, last, db);\n                        size_t k1 = db.names.size();\n                        if (t != first+1)\n                        {\n                            db.subs.emplace_back(db.names.get_allocator());\n                            for (size_t k = k0; k < k1; ++k)\n                            {\n                                if (db.names[k].second.substr(0, 2) == \" [\")\n                                {\n                                    db.names[k].first += \" (\";\n                                    db.names[k].second.insert(0, \")\");\n                                }\n                                else if (!db.names[k].second.empty() &&\n                                          db.names[k].second.front() == '(')\n                                {\n                                    db.names[k].first += \"(\";\n                                    db.names[k].second.insert(0, \")\");\n                                }\n                                db.names[k].first.append(\"&&\");\n                                db.subs.back().push_back(db.names[k]);\n                            }\n                            first = t;\n                        }\n                        break;\n                      }\n                    case 'P':\n                      {\n                        size_t k0 = db.names.size();\n                        t = parse_type(first+1, last, db);\n                        size_t k1 = db.names.size();\n                        if (t != first+1)\n                        {\n                            db.subs.emplace_back(db.names.get_allocator());\n                            for (size_t k = k0; k < k1; ++k)\n                            {\n                                if (db.names[k].second.substr(0, 2) == \" [\")\n                                {\n                                    db.names[k].first += \" (\";\n                                    db.names[k].second.insert(0, \")\");\n                                }\n                                else if (!db.names[k].second.empty() &&\n                                          db.names[k].second.front() == '(')\n                                {\n                                    db.names[k].first += \"(\";\n                                    db.names[k].second.insert(0, \")\");\n                                }\n                                if (first[1] != 'U' || db.names[k].first.substr(0, 12) != \"objc_object<\")\n                                {\n                                    db.names[k].first.append(\"*\");\n                                }\n                                else\n                                {\n                                    db.names[k].first.replace(0, 11, \"id\");\n                                }\n                                db.subs.back().push_back(db.names[k]);\n                            }\n                            first = t;\n                        }\n                        break;\n                      }\n                    case 'R':\n                      {\n                        size_t k0 = db.names.size();\n                        t = parse_type(first+1, last, db);\n                        size_t k1 = db.names.size();\n                        if (t != first+1)\n                        {\n                            db.subs.emplace_back(db.names.get_allocator());\n                            for (size_t k = k0; k < k1; ++k)\n                            {\n                                if (db.names[k].second.substr(0, 2) == \" [\")\n                                {\n                                    db.names[k].first += \" (\";\n                                    db.names[k].second.insert(0, \")\");\n                                }\n                                else if (!db.names[k].second.empty() &&\n                                          db.names[k].second.front() == '(')\n                                {\n                                    db.names[k].first += \"(\";\n                                    db.names[k].second.insert(0, \")\");\n                                }\n                                db.names[k].first.append(\"&\");\n                                db.subs.back().push_back(db.names[k]);\n                            }\n                            first = t;\n                        }\n                        break;\n                      }\n                    case 'T':\n                      {\n                        size_t k0 = db.names.size();\n                        t = parse_template_param(first, last, db);\n                        size_t k1 = db.names.size();\n                        if (t != first)\n                        {\n                            db.subs.emplace_back(db.names.get_allocator());\n                            for (size_t k = k0; k < k1; ++k)\n                                db.subs.back().push_back(db.names[k]);\n                            if (db.try_to_parse_template_args && k1 == k0+1)\n                            {\n                                const char* t1 = parse_template_args(t, last, db);\n                                if (t1 != t)\n                                {\n                                    auto args = db.names.back().move_full();\n                                    db.names.pop_back();\n                                    db.names.back().first += std::move(args);\n                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                                    t = t1;\n                                }\n                            }\n                            first = t;\n                        }\n                        break;\n                      }\n                    case 'U':\n                        if (first+1 != last)\n                        {\n                            t = parse_source_name(first+1, last, db);\n                            if (t != first+1)\n                            {\n                                const char* t2 = parse_type(t, last, db);\n                                if (t2 != t)\n                                {\n                                    if (db.names.size() < 2)\n                                        return first;\n                                    auto type = db.names.back().move_full();\n                                    db.names.pop_back();\n                                    if (db.names.back().first.substr(0, 9) != \"objcproto\")\n                                    {\n                                        db.names.back() = type + \" \" + db.names.back().move_full();\n                                    }\n                                    else\n                                    {\n                                        auto proto = db.names.back().move_full();\n                                        db.names.pop_back();\n                                        t = parse_source_name(proto.data() + 9, proto.data() + proto.size(), db);\n                                        if (t != proto.data() + 9)\n                                        {\n                                            db.names.back() = type + \"<\" + db.names.back().move_full() + \">\";\n                                        }\n                                        else\n                                        {\n                                            db.names.push_back(type + \" \" + proto);\n                                        }\n                                    }\n                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                                    first = t2;\n                                }\n                            }\n                        }\n                        break;\n                    case 'S':\n                        if (first+1 != last && first[1] == 't')\n                        {\n                            t = parse_name(first, last, db);\n                            if (t != first)\n                            {\n                                if (db.names.empty())\n                                    return first;\n                                db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                                first = t;\n                            }\n                        }\n                        else\n                        {\n                            t = parse_substitution(first, last, db);\n                            if (t != first)\n                            {\n                                first = t;\n                                // Parsed a substitution.  If the substitution is a\n                                //  <template-param> it might be followed by <template-args>.\n                                t = parse_template_args(first, last, db);\n                                if (t != first)\n                                {\n                                    if (db.names.size() < 2)\n                                        return first;\n                                    auto template_args = db.names.back().move_full();\n                                    db.names.pop_back();\n                                    db.names.back().first += template_args;\n                                    // Need to create substitution for <template-template-param> <template-args>\n                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                                    first = t;\n                                }\n                            }\n                        }\n                        break;\n                    case 'D':\n                        if (first+1 != last)\n                        {\n                            switch (first[1])\n                            {\n                            case 'p':\n                              {\n                                size_t k0 = db.names.size();\n                                t = parse_type(first+2, last, db);\n                                size_t k1 = db.names.size();\n                                if (t != first+2)\n                                {\n                                    db.subs.emplace_back(db.names.get_allocator());\n                                    for (size_t k = k0; k < k1; ++k)\n                                        db.subs.back().push_back(db.names[k]);\n                                    first = t;\n                                    return first;\n                                }\n                                break;\n                              }\n                            case 't':\n                            case 'T':\n                                t = parse_decltype(first, last, db);\n                                if (t != first)\n                                {\n                                    if (db.names.empty())\n                                        return first;\n                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                                    first = t;\n                                    return first;\n                                }\n                                break;\n                            case 'v':\n                                t = parse_vector_type(first, last, db);\n                                if (t != first)\n                                {\n                                    if (db.names.empty())\n                                        return first;\n                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                                    first = t;\n                                    return first;\n                                }\n                                break;\n                            }\n                        }\n                        // drop through\n                    default:\n                        // must check for builtin-types before class-enum-types to avoid\n                        // ambiguities with operator-names\n                        t = parse_builtin_type(first, last, db);\n                        if (t != first)\n                        {\n                            first = t;\n                        }\n                        else\n                        {\n                            t = parse_name(first, last, db);\n                            if (t != first)\n                            {\n                                if (db.names.empty())\n                                    return first;\n                                db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                                first = t;\n                            }\n                        }\n                        break;\n                    }\n              }\n                break;\n            }\n        }\n    }\n    return first;\n}\n\n//   <operator-name>\n//                   ::= aa    # &&            \n//                   ::= ad    # & (unary)     \n//                   ::= an    # &             \n//                   ::= aN    # &=            \n//                   ::= aS    # =             \n//                   ::= cl    # ()            \n//                   ::= cm    # ,             \n//                   ::= co    # ~             \n//                   ::= cv <type>    # (cast)        \n//                   ::= da    # delete[]      \n//                   ::= de    # * (unary)     \n//                   ::= dl    # delete        \n//                   ::= dv    # /             \n//                   ::= dV    # /=            \n//                   ::= eo    # ^             \n//                   ::= eO    # ^=            \n//                   ::= eq    # ==            \n//                   ::= ge    # >=            \n//                   ::= gt    # >             \n//                   ::= ix    # []            \n//                   ::= le    # <=            \n//                   ::= li <source-name>  # operator \"\"\n//                   ::= ls    # <<            \n//                   ::= lS    # <<=           \n//                   ::= lt    # <             \n//                   ::= mi    # -             \n//                   ::= mI    # -=            \n//                   ::= ml    # *             \n//                   ::= mL    # *=            \n//                   ::= mm    # -- (postfix in <expression> context)           \n//                   ::= na    # new[]\n//                   ::= ne    # !=            \n//                   ::= ng    # - (unary)     \n//                   ::= nt    # !             \n//                   ::= nw    # new           \n//                   ::= oo    # ||            \n//                   ::= or    # |             \n//                   ::= oR    # |=            \n//                   ::= pm    # ->*           \n//                   ::= pl    # +             \n//                   ::= pL    # +=            \n//                   ::= pp    # ++ (postfix in <expression> context)\n//                   ::= ps    # + (unary)\n//                   ::= pt    # ->            \n//                   ::= qu    # ?             \n//                   ::= rm    # %             \n//                   ::= rM    # %=            \n//                   ::= rs    # >>            \n//                   ::= rS    # >>=           \n//                   ::= v <digit> <source-name>        # vendor extended operator\n\ntemplate <class C>\nconst char*\nparse_operator_name(const char* first, const char* last, C& db)\n{\n    if (last - first >= 2)\n    {\n        switch (first[0])\n        {\n        case 'a':\n            switch (first[1])\n            {\n            case 'a':\n                db.names.push_back(\"operator&&\");\n                first += 2;\n                break;\n            case 'd':\n            case 'n':\n                db.names.push_back(\"operator&\");\n                first += 2;\n                break;\n            case 'N':\n                db.names.push_back(\"operator&=\");\n                first += 2;\n                break;\n            case 'S':\n                db.names.push_back(\"operator=\");\n                first += 2;\n                break;\n            }\n            break;\n        case 'c':\n            switch (first[1])\n            {\n            case 'l':\n                db.names.push_back(\"operator()\");\n                first += 2;\n                break;\n            case 'm':\n                db.names.push_back(\"operator,\");\n                first += 2;\n                break;\n            case 'o':\n                db.names.push_back(\"operator~\");\n                first += 2;\n                break;\n            case 'v':\n                {\n                    bool try_to_parse_template_args = db.try_to_parse_template_args;\n                    db.try_to_parse_template_args = false;\n                    const char* t = parse_type(first+2, last, db);\n                    db.try_to_parse_template_args = try_to_parse_template_args;\n                    if (t != first+2)\n                    {\n                        if (db.names.empty())\n                            return first;\n                        db.names.back().first.insert(0, \"operator \");\n                        db.parsed_ctor_dtor_cv = true;\n                        first = t;\n                    }\n                }\n                break;\n            }\n            break;\n        case 'd':\n            switch (first[1])\n            {\n            case 'a':\n                db.names.push_back(\"operator delete[]\");\n                first += 2;\n                break;\n            case 'e':\n                db.names.push_back(\"operator*\");\n                first += 2;\n                break;\n            case 'l':\n                db.names.push_back(\"operator delete\");\n                first += 2;\n                break;\n            case 'v':\n                db.names.push_back(\"operator/\");\n                first += 2;\n                break;\n            case 'V':\n                db.names.push_back(\"operator/=\");\n                first += 2;\n                break;\n            }\n            break;\n        case 'e':\n            switch (first[1])\n            {\n            case 'o':\n                db.names.push_back(\"operator^\");\n                first += 2;\n                break;\n            case 'O':\n                db.names.push_back(\"operator^=\");\n                first += 2;\n                break;\n            case 'q':\n                db.names.push_back(\"operator==\");\n                first += 2;\n                break;\n            }\n            break;\n        case 'g':\n            switch (first[1])\n            {\n            case 'e':\n                db.names.push_back(\"operator>=\");\n                first += 2;\n                break;\n            case 't':\n                db.names.push_back(\"operator>\");\n                first += 2;\n                break;\n            }\n            break;\n        case 'i':\n            if (first[1] == 'x')\n            {\n                db.names.push_back(\"operator[]\");\n                first += 2;\n            }\n            break;\n        case 'l':\n            switch (first[1])\n            {\n            case 'e':\n                db.names.push_back(\"operator<=\");\n                first += 2;\n                break;\n            case 'i':\n                {\n                    const char* t = parse_source_name(first+2, last, db);\n                    if (t != first+2)\n                    {\n                        if (db.names.empty())\n                            return first;\n                        db.names.back().first.insert(0, \"operator\\\"\\\" \");\n                        first = t;\n                    }\n                }\n                break;\n            case 's':\n                db.names.push_back(\"operator<<\");\n                first += 2;\n                break;\n            case 'S':\n                db.names.push_back(\"operator<<=\");\n                first += 2;\n                break;\n            case 't':\n                db.names.push_back(\"operator<\");\n                first += 2;\n                break;\n            }\n            break;\n        case 'm':\n            switch (first[1])\n            {\n            case 'i':\n                db.names.push_back(\"operator-\");\n                first += 2;\n                break;\n            case 'I':\n                db.names.push_back(\"operator-=\");\n                first += 2;\n                break;\n            case 'l':\n                db.names.push_back(\"operator*\");\n                first += 2;\n                break;\n            case 'L':\n                db.names.push_back(\"operator*=\");\n                first += 2;\n                break;\n            case 'm':\n                db.names.push_back(\"operator--\");\n                first += 2;\n                break;\n            }\n            break;\n        case 'n':\n            switch (first[1])\n            {\n            case 'a':\n                db.names.push_back(\"operator new[]\");\n                first += 2;\n                break;\n            case 'e':\n                db.names.push_back(\"operator!=\");\n                first += 2;\n                break;\n            case 'g':\n                db.names.push_back(\"operator-\");\n                first += 2;\n                break;\n            case 't':\n                db.names.push_back(\"operator!\");\n                first += 2;\n                break;\n            case 'w':\n                db.names.push_back(\"operator new\");\n                first += 2;\n                break;\n            }\n            break;\n        case 'o':\n            switch (first[1])\n            {\n            case 'o':\n                db.names.push_back(\"operator||\");\n                first += 2;\n                break;\n            case 'r':\n                db.names.push_back(\"operator|\");\n                first += 2;\n                break;\n            case 'R':\n                db.names.push_back(\"operator|=\");\n                first += 2;\n                break;\n            }\n            break;\n        case 'p':\n            switch (first[1])\n            {\n            case 'm':\n                db.names.push_back(\"operator->*\");\n                first += 2;\n                break;\n            case 'l':\n                db.names.push_back(\"operator+\");\n                first += 2;\n                break;\n            case 'L':\n                db.names.push_back(\"operator+=\");\n                first += 2;\n                break;\n            case 'p':\n                db.names.push_back(\"operator++\");\n                first += 2;\n                break;\n            case 's':\n                db.names.push_back(\"operator+\");\n                first += 2;\n                break;\n            case 't':\n                db.names.push_back(\"operator->\");\n                first += 2;\n                break;\n            }\n            break;\n        case 'q':\n            if (first[1] == 'u')\n            {\n                db.names.push_back(\"operator?\");\n                first += 2;\n            }\n            break;\n        case 'r':\n            switch (first[1])\n            {\n            case 'm':\n                db.names.push_back(\"operator%\");\n                first += 2;\n                break;\n            case 'M':\n                db.names.push_back(\"operator%=\");\n                first += 2;\n                break;\n            case 's':\n                db.names.push_back(\"operator>>\");\n                first += 2;\n                break;\n            case 'S':\n                db.names.push_back(\"operator>>=\");\n                first += 2;\n                break;\n            }\n            break;\n        case 'v':\n            if (std::isdigit(first[1]))\n            {\n                const char* t = parse_source_name(first+2, last, db);\n                if (t != first+2)\n                {\n                    if (db.names.empty())\n                        return first;\n                    db.names.back().first.insert(0, \"operator \");\n                    first = t;\n                }\n            }\n            break;\n        }\n    }\n    return first;\n}\n\ntemplate <class C>\nconst char*\nparse_integer_literal(const char* first, const char* last, const typename C::String& lit, C& db)\n{\n    const char* t = parse_number(first, last);\n    if (t != first && t != last && *t == 'E')\n    {\n        if (lit.size() > 3)\n            db.names.push_back(\"(\" + lit + \")\");\n        else\n            db.names.emplace_back();\n        if (*first == 'n')\n        {\n            db.names.back().first += '-';\n            ++first;\n        }\n        db.names.back().first.append(first, t);\n        if (lit.size() <= 3)\n            db.names.back().first += lit;\n        first = t+1;\n    }\n    return first;\n}\n\n// <expr-primary> ::= L <type> <value number> E                          # integer literal\n//                ::= L <type> <value float> E                           # floating literal\n//                ::= L <string type> E                                  # string literal\n//                ::= L <nullptr type> E                                 # nullptr literal (i.e., \"LDnE\")\n//                ::= L <type> <real-part float> _ <imag-part float> E   # complex floating point literal (C 2000)\n//                ::= L <mangled-name> E                                 # external name\n\ntemplate <class C>\nconst char*\nparse_expr_primary(const char* first, const char* last, C& db)\n{\n    if (last - first >= 4 && *first == 'L')\n    {\n        switch (first[1])\n        {\n        case 'w':\n            {\n            const char* t = parse_integer_literal(first+2, last, \"wchar_t\", db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 'b':\n            if (first[3] == 'E')\n            {\n                switch (first[2])\n                {\n                case '0':\n                    db.names.push_back(\"false\");\n                    first += 4;\n                    break;\n                case '1':\n                    db.names.push_back(\"true\");\n                    first += 4;\n                    break;\n                }\n            }\n            break;\n        case 'c':\n            {\n            const char* t = parse_integer_literal(first+2, last, \"char\", db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 'a':\n            {\n            const char* t = parse_integer_literal(first+2, last, \"signed char\", db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 'h':\n            {\n            const char* t = parse_integer_literal(first+2, last, \"unsigned char\", db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 's':\n            {\n            const char* t = parse_integer_literal(first+2, last, \"short\", db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 't':\n            {\n            const char* t = parse_integer_literal(first+2, last, \"unsigned short\", db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 'i':\n            {\n            const char* t = parse_integer_literal(first+2, last, \"\", db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 'j':\n            {\n            const char* t = parse_integer_literal(first+2, last, \"u\", db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 'l':\n            {\n            const char* t = parse_integer_literal(first+2, last, \"l\", db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 'm':\n            {\n            const char* t = parse_integer_literal(first+2, last, \"ul\", db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 'x':\n            {\n            const char* t = parse_integer_literal(first+2, last, \"ll\", db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 'y':\n            {\n            const char* t = parse_integer_literal(first+2, last, \"ull\", db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 'n':\n            {\n            const char* t = parse_integer_literal(first+2, last, \"__int128\", db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 'o':\n            {\n            const char* t = parse_integer_literal(first+2, last, \"unsigned __int128\", db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 'f':\n            {\n            const char* t = parse_floating_number<float>(first+2, last, db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case 'd':\n            {\n            const char* t = parse_floating_number<double>(first+2, last, db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n         case 'e':\n            {\n            const char* t = parse_floating_number<long double>(first+2, last, db);\n            if (t != first+2)\n                first = t;\n            }\n            break;\n        case '_':\n            if (first[2] == 'Z')\n            {\n                const char* t = parse_encoding(first+3, last, db);\n                if (t != first+3 && t != last && *t == 'E')\n                    first = t+1;\n            }\n            break;\n        case 'T':\n            // Invalid mangled name per\n            //   http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html\n            break;\n        default:\n            {\n                // might be named type\n                const char* t = parse_type(first+1, last, db);\n                if (t != first+1 && t != last)\n                {\n                    if (*t != 'E')\n                    {\n                        const char* n = t;\n                        for (; n != last && isdigit(*n); ++n)\n                            ;\n                        if (n != t && n != last && *n == 'E')\n                        {\n                            if (db.names.empty())\n                                return first;\n                            db.names.back() = \"(\" + db.names.back().move_full() + \")\" + typename C::String(t, n);\n                            first = n+1;\n                            break;\n                        }\n                    }\n                    else\n                    {\n                        first = t+1;\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    return first;\n}\n\ntemplate <class String>\nString\nbase_name(String& s)\n{\n    if (s.empty())\n        return s;\n    if (s == \"std::string\")\n    {\n        s = \"std::basic_string<char, std::char_traits<char>, std::allocator<char> >\";\n        return \"basic_string\";\n    }\n    if (s == \"std::istream\")\n    {\n        s = \"std::basic_istream<char, std::char_traits<char> >\";\n        return \"basic_istream\";\n    }\n    if (s == \"std::ostream\")\n    {\n        s = \"std::basic_ostream<char, std::char_traits<char> >\";\n        return \"basic_ostream\";\n    }\n    if (s == \"std::iostream\")\n    {\n        s = \"std::basic_iostream<char, std::char_traits<char> >\";\n        return \"basic_iostream\";\n    }\n    const char* const pf = s.data();\n    const char* pe = pf + s.size();\n    if (pe[-1] == '>')\n    {\n        unsigned c = 1;\n        while (true)\n        {\n            if (--pe == pf)\n                return String();\n            if (pe[-1] == '<')\n            {\n                if (--c == 0)\n                {\n                    --pe;\n                    break;\n                }\n            }\n            else if (pe[-1] == '>')\n                ++c;\n        }\n    }\n    const char* p0 = pe - 1;\n    for (; p0 != pf; --p0)\n    {\n        if (*p0 == ':')\n        {\n            ++p0;\n            break;\n        }\n    }\n    return String(p0, pe);\n}\n\n// <ctor-dtor-name> ::= C1    # complete object constructor\n//                  ::= C2    # base object constructor\n//                  ::= C3    # complete object allocating constructor\n//   extension      ::= C5    # ?\n//                  ::= D0    # deleting destructor\n//                  ::= D1    # complete object destructor\n//                  ::= D2    # base object destructor\n//   extension      ::= D5    # ?\n\ntemplate <class C>\nconst char*\nparse_ctor_dtor_name(const char* first, const char* last, C& db)\n{\n    if (last-first >= 2 && !db.names.empty())\n    {\n        switch (first[0])\n        {\n        case 'C':\n            switch (first[1])\n            {\n            case '1':\n            case '2':\n            case '3':\n            case '5':\n                if (db.names.empty())\n                    return first;\n                db.names.push_back(base_name(db.names.back().first));\n                first += 2;\n                db.parsed_ctor_dtor_cv = true;\n                break;\n            }\n            break;\n        case 'D':\n            switch (first[1])\n            {\n            case '0':\n            case '1':\n            case '2':\n            case '5':\n                if (db.names.empty())\n                    return first;\n                db.names.push_back(\"~\" + base_name(db.names.back().first));\n                first += 2;\n                db.parsed_ctor_dtor_cv = true;\n                break;\n            }\n            break;\n        }\n    }\n    return first;\n}\n\n// <unnamed-type-name> ::= Ut [ <nonnegative number> ] _\n//                     ::= <closure-type-name>\n// \n// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ \n// \n// <lambda-sig> ::= <parameter type>+  # Parameter types or \"v\" if the lambda has no parameters\n\ntemplate <class C>\nconst char*\nparse_unnamed_type_name(const char* first, const char* last, C& db)\n{\n    if (last - first > 2 && first[0] == 'U')\n    {\n        char type = first[1];\n        switch (type)\n        {\n        case 't':\n          {\n            db.names.push_back(typename C::String(\"'unnamed\"));\n            const char* t0 = first+2;\n            if (t0 == last)\n            {\n                db.names.pop_back();\n                return first;\n            }\n            if (std::isdigit(*t0))\n            {\n                const char* t1 = t0 + 1;\n                while (t1 != last && std::isdigit(*t1))\n                    ++t1;\n                db.names.back().first.append(t0, t1);\n                t0 = t1;\n            }\n            db.names.back().first.push_back('\\'');\n            if (t0 == last || *t0 != '_')\n            {\n                db.names.pop_back();\n                return first;\n            }\n            first = t0 + 1;\n          }\n            break;\n        case 'l':\n          {\n            db.names.push_back(typename C::String(\"'lambda'(\"));\n            const char* t0 = first+2;\n            if (first[2] == 'v')\n            {\n                db.names.back().first += ')';\n                ++t0;\n            }\n            else\n            {\n                const char* t1 = parse_type(t0, last, db);\n                if (t1 == t0)\n                {\n                    db.names.pop_back();\n                    return first;\n                }\n                if (db.names.size() < 2)\n                    return first;\n                auto tmp = db.names.back().move_full();\n                db.names.pop_back();\n                db.names.back().first.append(tmp);\n                t0 = t1;\n                while (true)\n                {\n                    t1 = parse_type(t0, last, db);\n                    if (t1 == t0)\n                        break;\n                    if (db.names.size() < 2)\n                        return first;\n                    tmp = db.names.back().move_full();\n                    db.names.pop_back();\n                    if (!tmp.empty())\n                    {\n                        db.names.back().first.append(\", \");\n                        db.names.back().first.append(tmp);\n                    }\n                    t0 = t1;\n                }\n                db.names.back().first.append(\")\");\n            }\n            if (t0 == last || *t0 != 'E')\n            {\n                db.names.pop_back();\n                return first;\n            }\n            ++t0;\n            if (t0 == last)\n            {\n                db.names.pop_back();\n                return first;\n            }\n            if (std::isdigit(*t0))\n            {\n                const char* t1 = t0 + 1;\n                while (t1 != last && std::isdigit(*t1))\n                    ++t1;\n                db.names.back().first.insert(db.names.back().first.begin()+7, t0, t1);\n                t0 = t1;\n            }\n            if (t0 == last || *t0 != '_')\n            {\n                db.names.pop_back();\n                return first;\n            }\n            first = t0 + 1;\n          }\n            break;\n        }\n    }\n    return first;\n}\n\n// <unqualified-name> ::= <operator-name>\n//                    ::= <ctor-dtor-name>\n//                    ::= <source-name>   \n//                    ::= <unnamed-type-name>\n\ntemplate <class C>\nconst char*\nparse_unqualified_name(const char* first, const char* last, C& db)\n{\n    if (first != last)\n    {\n        const char* t;\n        switch (*first)\n        {\n        case 'C':\n        case 'D':\n            t = parse_ctor_dtor_name(first, last, db);\n            if (t != first)\n                first = t;\n            break;\n        case 'U':\n            t = parse_unnamed_type_name(first, last, db);\n            if (t != first)\n                first = t;\n            break;\n        case '1':\n        case '2':\n        case '3':\n        case '4':\n        case '5':\n        case '6':\n        case '7':\n        case '8':\n        case '9':\n            t = parse_source_name(first, last, db);\n            if (t != first)\n                first = t;\n            break;\n        default:\n            t = parse_operator_name(first, last, db);\n            if (t != first)\n                first = t;\n            break;\n        };\n    }\n    return first;\n}\n\n// <unscoped-name> ::= <unqualified-name>\n//                 ::= St <unqualified-name>   # ::std::\n// extension       ::= StL<unqualified-name>\n\ntemplate <class C>\nconst char*\nparse_unscoped_name(const char* first, const char* last, C& db)\n{\n    if (last - first >= 2)\n    {\n        const char* t0 = first;\n        bool St = false;\n        if (first[0] == 'S' && first[1] == 't')\n        {\n            t0 += 2;\n            St = true;\n            if (t0 != last && *t0 == 'L')\n                ++t0;\n        }\n        const char* t1 = parse_unqualified_name(t0, last, db);\n        if (t1 != t0)\n        {\n            if (St)\n            {\n                if (db.names.empty())\n                    return first;\n                db.names.back().first.insert(0, \"std::\");\n            }\n            first = t1;\n        }\n    }\n    return first;\n}\n\n// at <type>                                            # alignof (a type)\n\ntemplate <class C>\nconst char*\nparse_alignof_type(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 'a' && first[1] == 't')\n    {\n        const char* t = parse_type(first+2, last, db);\n        if (t != first+2)\n        {\n            if (db.names.empty())\n                return first;\n            db.names.back().first = \"alignof (\" + db.names.back().move_full() + \")\";\n            first = t;\n        }\n    }\n    return first;\n}\n\n// az <expression>                                            # alignof (a expression)\n\ntemplate <class C>\nconst char*\nparse_alignof_expr(const char* first, const char* last, C& db)\n{\n    if (last - first >= 3 && first[0] == 'a' && first[1] == 'z')\n    {\n        const char* t = parse_expression(first+2, last, db);\n        if (t != first+2)\n        {\n            if (db.names.empty())\n                return first;\n            db.names.back().first = \"alignof (\" + db.names.back().move_full() + \")\";\n            first = t;\n        }\n    }\n    return first;\n}\n\ntemplate <class C>\nconst char*\nparse_noexcept_expression(const char* first, const char* last, C& db)\n{\n    const char* t1 = parse_expression(first, last, db);\n    if (t1 != first)\n    {\n        if (db.names.empty())\n            return first;\n        db.names.back().first =  \"noexcept (\" + db.names.back().move_full() + \")\";\n        first = t1;\n    }\n    return first;\n}\n\ntemplate <class C>\nconst char*\nparse_prefix_expression(const char* first, const char* last, const typename C::String& op, C& db)\n{\n    const char* t1 = parse_expression(first, last, db);\n    if (t1 != first)\n    {\n        if (db.names.empty())\n            return first;\n        db.names.back().first =  op + \"(\" + db.names.back().move_full() + \")\";\n        first = t1;\n    }\n    return first;\n}\n\ntemplate <class C>\nconst char*\nparse_binary_expression(const char* first, const char* last, const typename C::String& op, C& db)\n{\n    const char* t1 = parse_expression(first, last, db);\n    if (t1 != first)\n    {\n        const char* t2 = parse_expression(t1, last, db);\n        if (t2 != t1)\n        {\n            if (db.names.size() < 2)\n                return first;\n            auto op2 = db.names.back().move_full();\n            db.names.pop_back();\n            auto op1 = db.names.back().move_full();\n            auto& nm = db.names.back().first;\n            nm.clear();\n            if (op == \">\")\n                nm += '(';\n            nm += \"(\" + op1 + \") \" + op + \" (\" + op2 + \")\";\n            if (op == \">\")\n                nm += ')';\n            first = t2;\n        }\n        else\n            db.names.pop_back();\n    }\n    return first;\n}\n\n// <expression> ::= <unary operator-name> <expression>\n//              ::= <binary operator-name> <expression> <expression>\n//              ::= <ternary operator-name> <expression> <expression> <expression>\n//              ::= cl <expression>+ E                                   # call\n//              ::= cv <type> <expression>                               # conversion with one argument\n//              ::= cv <type> _ <expression>* E                          # conversion with a different number of arguments\n//              ::= [gs] nw <expression>* _ <type> E                     # new (expr-list) type\n//              ::= [gs] nw <expression>* _ <type> <initializer>         # new (expr-list) type (init)\n//              ::= [gs] na <expression>* _ <type> E                     # new[] (expr-list) type\n//              ::= [gs] na <expression>* _ <type> <initializer>         # new[] (expr-list) type (init)\n//              ::= [gs] dl <expression>                                 # delete expression\n//              ::= [gs] da <expression>                                 # delete[] expression\n//              ::= pp_ <expression>                                     # prefix ++\n//              ::= mm_ <expression>                                     # prefix --\n//              ::= ti <type>                                            # typeid (type)\n//              ::= te <expression>                                      # typeid (expression)\n//              ::= dc <type> <expression>                               # dynamic_cast<type> (expression)\n//              ::= sc <type> <expression>                               # static_cast<type> (expression)\n//              ::= cc <type> <expression>                               # const_cast<type> (expression)\n//              ::= rc <type> <expression>                               # reinterpret_cast<type> (expression)\n//              ::= st <type>                                            # sizeof (a type)\n//              ::= sz <expression>                                      # sizeof (an expression)\n//              ::= at <type>                                            # alignof (a type)\n//              ::= az <expression>                                      # alignof (an expression)\n//              ::= nx <expression>                                      # noexcept (expression)\n//              ::= <template-param>\n//              ::= <function-param>\n//              ::= dt <expression> <unresolved-name>                    # expr.name\n//              ::= pt <expression> <unresolved-name>                    # expr->name\n//              ::= ds <expression> <expression>                         # expr.*expr\n//              ::= sZ <template-param>                                  # size of a parameter pack\n//              ::= sZ <function-param>                                  # size of a function parameter pack\n//              ::= sp <expression>                                      # pack expansion\n//              ::= tw <expression>                                      # throw expression\n//              ::= tr                                                   # throw with no operand (rethrow)\n//              ::= <unresolved-name>                                    # f(p), N::f(p), ::f(p),\n//                                                                       # freestanding dependent name (e.g., T::x),\n//                                                                       # objectless nonstatic member reference\n//              ::= <expr-primary>\n\ntemplate <class C>\nconst char*\nparse_expression(const char* first, const char* last, C& db)\n{\n    if (last - first >= 2)\n    {\n        const char* t = first;\n        bool parsed_gs = false;\n        if (last - first >= 4 && t[0] == 'g' && t[1] == 's')\n        {\n            t += 2;\n            parsed_gs = true;\n        }\n        switch (*t)\n        {\n        case 'L':\n            first = parse_expr_primary(first, last, db);\n            break;\n        case 'T':\n            first = parse_template_param(first, last, db);\n            break;\n        case 'f':\n            first = parse_function_param(first, last, db);\n            break;\n        case 'a':\n            switch (t[1])\n            {\n            case 'a':\n                t = parse_binary_expression(first+2, last, \"&&\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'd':\n                t = parse_prefix_expression(first+2, last, \"&\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'n':\n                t = parse_binary_expression(first+2, last, \"&\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'N':\n                t = parse_binary_expression(first+2, last, \"&=\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'S':\n                t = parse_binary_expression(first+2, last, \"=\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 't':\n                first = parse_alignof_type(first, last, db);\n                break;\n            case 'z':\n                first = parse_alignof_expr(first, last, db);\n                break;\n            }\n            break;\n        case 'c':\n            switch (t[1])\n            {\n            case 'c':\n                first = parse_const_cast_expr(first, last, db);\n                break;\n            case 'l':\n                first = parse_call_expr(first, last, db);\n                break;\n            case 'm':\n                t = parse_binary_expression(first+2, last, \",\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'o':\n                t = parse_prefix_expression(first+2, last, \"~\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'v':\n                first = parse_conversion_expr(first, last, db);\n                break;\n            }\n            break;\n        case 'd':\n            switch (t[1])\n            {\n            case 'a':\n                {\n                    const char* t1 = parse_expression(t+2, last, db);\n                    if (t1 != t+2)\n                    {\n                        if (db.names.empty())\n                            return first;\n                        db.names.back().first = (parsed_gs ? typename C::String(\"::\") : typename C::String()) +\n                                          \"delete[] \" + db.names.back().move_full();\n                        first = t1;\n                    }\n                }\n                break;\n            case 'c':\n                first = parse_dynamic_cast_expr(first, last, db);\n                break;\n            case 'e':\n                t = parse_prefix_expression(first+2, last, \"*\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'l':\n                {\n                    const char* t1 = parse_expression(t+2, last, db);\n                    if (t1 != t+2)\n                    {\n                        if (db.names.empty())\n                            return first;\n                        db.names.back().first = (parsed_gs ? typename C::String(\"::\") : typename C::String()) +\n                                          \"delete \" + db.names.back().move_full();\n                        first = t1;\n                    }\n                }\n                break;\n            case 'n':\n                return parse_unresolved_name(first, last, db);\n            case 's':\n                first = parse_dot_star_expr(first, last, db);\n                break;\n            case 't':\n                first = parse_dot_expr(first, last, db);\n                break;\n            case 'v':\n                t = parse_binary_expression(first+2, last, \"/\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'V':\n                t = parse_binary_expression(first+2, last, \"/=\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            }\n            break;\n        case 'e':\n            switch (t[1])\n            {\n            case 'o':\n                t = parse_binary_expression(first+2, last, \"^\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'O':\n                t = parse_binary_expression(first+2, last, \"^=\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'q':\n                t = parse_binary_expression(first+2, last, \"==\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            }\n            break;\n        case 'g':\n            switch (t[1])\n            {\n            case 'e':\n                t = parse_binary_expression(first+2, last, \">=\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 't':\n                t = parse_binary_expression(first+2, last, \">\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            }\n            break;\n        case 'i':\n            if (t[1] == 'x')\n            {\n                const char* t1 = parse_expression(first+2, last, db);\n                if (t1 != first+2)\n                {\n                    const char* t2 = parse_expression(t1, last, db);\n                    if (t2 != t1)\n                    {\n                        if (db.names.size() < 2)\n                            return first;\n                        auto op2 = db.names.back().move_full();\n                        db.names.pop_back();\n                        auto op1 = db.names.back().move_full();\n                        db.names.back() = \"(\" + op1 + \")[\" + op2 + \"]\";\n                        first = t2;\n                    }\n                    else\n                        db.names.pop_back();\n                }\n            }\n            break;\n        case 'l':\n            switch (t[1])\n            {\n            case 'e':\n                t = parse_binary_expression(first+2, last, \"<=\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 's':\n                t = parse_binary_expression(first+2, last, \"<<\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'S':\n                t = parse_binary_expression(first+2, last, \"<<=\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 't':\n                t = parse_binary_expression(first+2, last, \"<\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            }\n            break;\n        case 'm':\n            switch (t[1])\n            {\n            case 'i':\n                t = parse_binary_expression(first+2, last, \"-\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'I':\n                t = parse_binary_expression(first+2, last, \"-=\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'l':\n                t = parse_binary_expression(first+2, last, \"*\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'L':\n                t = parse_binary_expression(first+2, last, \"*=\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'm':\n                if (first+2 != last && first[2] == '_')\n                {\n                    t = parse_prefix_expression(first+3, last, \"--\", db);\n                    if (t != first+3)\n                        first = t;\n                }\n                else\n                {\n                    const char* t1 = parse_expression(first+2, last, db);\n                    if (t1 != first+2)\n                    {\n                        if (db.names.empty())\n                            return first;\n                        db.names.back() = \"(\" + db.names.back().move_full() + \")--\";\n                        first = t1;\n                    }\n                }\n                break;\n            }\n            break;\n        case 'n':\n            switch (t[1])\n            {\n            case 'a':\n            case 'w':\n                first = parse_new_expr(first, last, db);\n                break;\n            case 'e':\n                t = parse_binary_expression(first+2, last, \"!=\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'g':\n                t = parse_prefix_expression(first+2, last, \"-\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 't':\n                t = parse_prefix_expression(first+2, last, \"!\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'x':\n                t = parse_noexcept_expression(first+2, last, db);\n                if (t != first+2)\n                    first = t;\n                break;\n            }\n            break;\n        case 'o':\n            switch (t[1])\n            {\n            case 'n':\n                return parse_unresolved_name(first, last, db);\n            case 'o':\n                t = parse_binary_expression(first+2, last, \"||\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'r':\n                t = parse_binary_expression(first+2, last, \"|\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'R':\n                t = parse_binary_expression(first+2, last, \"|=\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            }\n            break;\n        case 'p':\n            switch (t[1])\n            {\n            case 'm':\n                t = parse_binary_expression(first+2, last, \"->*\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'l':\n                t = parse_binary_expression(first+2, last, \"+\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'L':\n                t = parse_binary_expression(first+2, last, \"+=\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'p':\n                if (first+2 != last && first[2] == '_')\n                {\n                    t = parse_prefix_expression(first+3, last, \"++\", db);\n                    if (t != first+3)\n                        first = t;\n                }\n                else\n                {\n                    const char* t1 = parse_expression(first+2, last, db);\n                    if (t1 != first+2)\n                    {\n                        if (db.names.empty())\n                            return first;\n                        db.names.back() = \"(\" + db.names.back().move_full() + \")++\";\n                        first = t1;\n                    }\n                }\n                break;\n            case 's':\n                t = parse_prefix_expression(first+2, last, \"+\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 't':\n                first = parse_arrow_expr(first, last, db);\n                break;\n            }\n            break;\n        case 'q':\n            if (t[1] == 'u')\n            {\n                const char* t1 = parse_expression(first+2, last, db);\n                if (t1 != first+2)\n                {\n                    const char* t2 = parse_expression(t1, last, db);\n                    if (t2 != t1)\n                    {\n                        const char* t3 = parse_expression(t2, last, db);\n                        if (t3 != t2)\n                        {\n                            if (db.names.size() < 3)\n                                return first;\n                            auto op3 = db.names.back().move_full();\n                            db.names.pop_back();\n                            auto op2 = db.names.back().move_full();\n                            db.names.pop_back();\n                            auto op1 = db.names.back().move_full();\n                            db.names.back() = \"(\" + op1 + \") ? (\" + op2 + \") : (\" + op3 + \")\";\n                            first = t3;\n                        }\n                        else\n                        {\n                            db.names.pop_back();\n                            db.names.pop_back();\n                        }\n                    }\n                    else\n                        db.names.pop_back();\n                }\n            }\n            break;\n        case 'r':\n            switch (t[1])\n            {\n            case 'c':\n                first = parse_reinterpret_cast_expr(first, last, db);\n                break;\n            case 'm':\n                t = parse_binary_expression(first+2, last, \"%\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'M':\n                t = parse_binary_expression(first+2, last, \"%=\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 's':\n                t = parse_binary_expression(first+2, last, \">>\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            case 'S':\n                t = parse_binary_expression(first+2, last, \">>=\", db);\n                if (t != first+2)\n                    first = t;\n                break;\n            }\n            break;\n        case 's':\n            switch (t[1])\n            {\n            case 'c':\n                first = parse_static_cast_expr(first, last, db);\n                break;\n            case 'p':\n                first = parse_pack_expansion(first, last, db);\n                break;\n            case 'r':\n                return parse_unresolved_name(first, last, db);\n            case 't':\n                first = parse_sizeof_type_expr(first, last, db);\n                break;\n            case 'z':\n                first = parse_sizeof_expr_expr(first, last, db);\n                break;\n            case 'Z':\n                if (last - t >= 3)\n                {\n                    switch (t[2])\n                    {\n                    case 'T':\n                        first = parse_sizeof_param_pack_expr(first, last, db);\n                        break;\n                    case 'f':\n                        first = parse_sizeof_function_param_pack_expr(first, last, db);\n                        break;\n                    }\n                }\n                break;\n            }\n            break;\n        case 't':\n            switch (t[1])\n            {\n            case 'e':\n            case 'i':\n                first = parse_typeid_expr(first, last, db);\n                break;\n            case 'r':\n                db.names.push_back(\"throw\");\n                first += 2;\n                break;\n            case 'w':\n                first = parse_throw_expr(first, last, db);\n                break;\n            }\n            break;\n        case '1':\n        case '2':\n        case '3':\n        case '4':\n        case '5':\n        case '6':\n        case '7':\n        case '8':\n        case '9':\n            return parse_unresolved_name(first, last, db);\n        }\n    }\n    return first;\n}\n\n// <template-arg> ::= <type>                                             # type or template\n//                ::= X <expression> E                                   # expression\n//                ::= <expr-primary>                                     # simple expressions\n//                ::= J <template-arg>* E                                # argument pack\n//                ::= LZ <encoding> E                                    # extension\n\ntemplate <class C>\nconst char*\nparse_template_arg(const char* first, const char* last, C& db)\n{\n    if (first != last)\n    {\n        const char* t;\n        switch (*first)\n        {\n        case 'X':\n            t = parse_expression(first+1, last, db);\n            if (t != first+1)\n            {\n                if (t != last && *t == 'E')\n                    first = t+1;\n            }\n            break;\n        case 'J':\n            t = first+1;\n            if (t == last)\n                return first;\n            while (*t != 'E')\n            {\n                const char* t1 = parse_template_arg(t, last, db);\n                if (t1 == t)\n                    return first;\n                t = t1;\n            }\n            first = t+1;\n            break;\n        case 'L':\n            // <expr-primary> or LZ <encoding> E\n            if (first+1 != last && first[1] == 'Z')\n            {\n                t = parse_encoding(first+2, last, db);\n                if (t != first+2 && t != last && *t == 'E')\n                    first = t+1;\n            }\n            else\n                first = parse_expr_primary(first, last, db);\n            break;\n        default:\n            // <type>\n            first = parse_type(first, last, db);\n            break;\n        }\n    }\n    return first;\n}\n\n// <template-args> ::= I <template-arg>* E\n//     extension, the abi says <template-arg>+\n\ntemplate <class C>\nconst char*\nparse_template_args(const char* first, const char* last, C& db)\n{\n    if (last - first >= 2 && *first == 'I')\n    {\n        if (db.tag_templates)\n            db.template_param.back().clear();\n        const char* t = first+1;\n        typename C::String args(\"<\");\n        while (*t != 'E')\n        {\n            if (db.tag_templates)\n                db.template_param.emplace_back(db.names.get_allocator());\n            size_t k0 = db.names.size();\n            const char* t1 = parse_template_arg(t, last, db);\n            size_t k1 = db.names.size();\n            if (db.tag_templates)\n                db.template_param.pop_back();\n            if (t1 == t || t1 == last)\n                return first;\n            if (db.tag_templates)\n            {\n                db.template_param.back().emplace_back(db.names.get_allocator());\n                for (size_t k = k0; k < k1; ++k)\n                    db.template_param.back().back().push_back(db.names[k]);\n            }\n            for (size_t k = k0; k < k1; ++k)\n            {\n                if (args.size() > 1)\n                    args += \", \";\n                args += db.names[k].move_full();\n            }\n            for (; k1 != k0; --k1)\n                db.names.pop_back();\n            t = t1;\n        }\n        first = t + 1;\n        if (args.back() != '>')\n            args += \">\";\n        else\n            args += \" >\";\n        db.names.push_back(std::move(args));\n        \n    }\n    return first;\n}\n\n// <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E\n//               ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E\n// \n// <prefix> ::= <prefix> <unqualified-name>\n//          ::= <template-prefix> <template-args>\n//          ::= <template-param>\n//          ::= <decltype>\n//          ::= # empty\n//          ::= <substitution>\n//          ::= <prefix> <data-member-prefix>\n//  extension ::= L\n// \n// <template-prefix> ::= <prefix> <template unqualified-name>\n//                   ::= <template-param>\n//                   ::= <substitution>\n\ntemplate <class C>\nconst char*\nparse_nested_name(const char* first, const char* last, C& db,\n                  bool* ends_with_template_args)\n{\n    if (first != last && *first == 'N')\n    {\n        unsigned cv;\n        const char* t0 = parse_cv_qualifiers(first+1, last, cv);\n        if (t0 == last)\n            return first;\n        db.ref = 0;\n        if (*t0 == 'R')\n        {\n            db.ref = 1;\n            ++t0;\n        }\n        else if (*t0 == 'O')\n        {\n            db.ref = 2;\n            ++t0;\n        }\n        db.names.emplace_back();\n        if (last - t0 >= 2 && t0[0] == 'S' && t0[1] == 't')\n        {\n            t0 += 2;\n            db.names.back().first = \"std\";\n        }\n        if (t0 == last)\n        {\n            db.names.pop_back();\n            return first;\n        }\n        bool pop_subs = false;\n        bool component_ends_with_template_args = false;\n        while (*t0 != 'E')\n        {\n            component_ends_with_template_args = false;\n            const char* t1;\n            switch (*t0)\n            {\n            case 'S':\n                if (t0 + 1 != last && t0[1] == 't')\n                    goto do_parse_unqualified_name;\n                t1 = parse_substitution(t0, last, db);\n                if (t1 != t0 && t1 != last)\n                {\n                    auto name = db.names.back().move_full();\n                    db.names.pop_back();\n                    if (!db.names.back().first.empty())\n                    {\n                        db.names.back().first += \"::\" + name;\n                        db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                    }\n                    else\n                        db.names.back().first = name;\n                    pop_subs = true;\n                    t0 = t1;\n                }\n                else\n                    return first;\n                break;\n            case 'T':\n                t1 = parse_template_param(t0, last, db);\n                if (t1 != t0 && t1 != last)\n                {\n                    auto name = db.names.back().move_full();\n                    db.names.pop_back();\n                    if (!db.names.back().first.empty())\n                        db.names.back().first += \"::\" + name;\n                    else\n                        db.names.back().first = name;\n                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                    pop_subs = true;\n                    t0 = t1;\n                }\n                else\n                    return first;\n                break;\n            case 'D':\n                if (t0 + 1 != last && t0[1] != 't' && t0[1] != 'T')\n                    goto do_parse_unqualified_name;\n                t1 = parse_decltype(t0, last, db);\n                if (t1 != t0 && t1 != last)\n                {\n                    auto name = db.names.back().move_full();\n                    db.names.pop_back();\n                    if (!db.names.back().first.empty())\n                        db.names.back().first += \"::\" + name;\n                    else\n                        db.names.back().first = name;\n                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                    pop_subs = true;\n                    t0 = t1;\n                }\n                else\n                    return first;\n                break;\n            case 'I':\n                t1 = parse_template_args(t0, last, db);\n                if (t1 != t0 && t1 != last)\n                {\n                    auto name = db.names.back().move_full();\n                    db.names.pop_back();\n                    db.names.back().first += name;\n                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                    t0 = t1;\n                    component_ends_with_template_args = true;\n                }\n                else\n                    return first;\n                break;\n            case 'L':\n                if (++t0 == last)\n                    return first;\n                break;\n            default:\n            do_parse_unqualified_name:\n                t1 = parse_unqualified_name(t0, last, db);\n                if (t1 != t0 && t1 != last)\n                {\n                    auto name = db.names.back().move_full();\n                    db.names.pop_back();\n                    if (!db.names.back().first.empty())\n                        db.names.back().first += \"::\" + name;\n                    else\n                        db.names.back().first = name;\n                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                    pop_subs = true;\n                    t0 = t1;\n                }\n                else\n                    return first;\n            }\n        }\n        first = t0 + 1;\n        db.cv = cv;\n        if (pop_subs && !db.subs.empty())\n            db.subs.pop_back();\n        if (ends_with_template_args)\n            *ends_with_template_args = component_ends_with_template_args;\n    }\n    return first;\n}\n\n// <discriminator> := _ <non-negative number>      # when number < 10\n//                 := __ <non-negative number> _   # when number >= 10\n//  extension      := decimal-digit+\n\nconst char*\nparse_discriminator(const char* first, const char* last)\n{\n    // parse but ignore discriminator\n    if (first != last)\n    {\n        if (*first == '_')\n        {\n            const char* t1 = first+1;\n            if (t1 != last)\n            {\n                if (std::isdigit(*t1))\n                    first = t1+1;\n                else if (*t1 == '_')\n                {\n                    for (++t1; t1 != last && std::isdigit(*t1); ++t1)\n                        ;\n                    if (t1 != last && *t1 == '_')\n                        first = t1 + 1;\n                }\n            }\n        }\n        else if (std::isdigit(*first))\n        {\n            const char* t1 = first+1;\n            for (; t1 != last && std::isdigit(*t1); ++t1)\n                ;\n            first = t1;\n        }\n    }\n    return first;\n}\n\n// <local-name> := Z <function encoding> E <entity name> [<discriminator>]\n//              := Z <function encoding> E s [<discriminator>]\n//              := Z <function encoding> Ed [ <parameter number> ] _ <entity name>\n\ntemplate <class C>\nconst char*\nparse_local_name(const char* first, const char* last, C& db,\n                 bool* ends_with_template_args)\n{\n    if (first != last && *first == 'Z')\n    {\n        const char* t = parse_encoding(first+1, last, db);\n        if (t != first+1 && t != last && *t == 'E' && ++t != last)\n        {\n            switch (*t)\n            {\n            case 's':\n                first = parse_discriminator(t+1, last);\n                if (db.names.empty())\n                    return first;\n                db.names.back().first.append(\"::string literal\");\n                break;\n            case 'd':\n                if (++t != last)\n                {\n                    const char* t1 = parse_number(t, last);\n                    if (t1 != last && *t1 == '_')\n                    {\n                        t = t1 + 1;\n                        t1 = parse_name(t, last, db,\n                                        ends_with_template_args);\n                        if (t1 != t)\n                        {\n                            if (db.names.size() < 2)\n                                return first;\n                            auto name = db.names.back().move_full();\n                            db.names.pop_back();\n                            db.names.back().first.append(\"::\");\n                            db.names.back().first.append(name);\n                            first = t1;\n                        }\n                        else\n                            db.names.pop_back();\n                    }\n                }\n                break;\n            default:\n                {\n                    const char* t1 = parse_name(t, last, db,\n                                                ends_with_template_args);\n                    if (t1 != t)\n                    {\n                        // parse but ignore discriminator\n                        first = parse_discriminator(t1, last);\n                        if (db.names.size() < 2)\n                            return first;\n                        auto name = db.names.back().move_full();\n                        db.names.pop_back();\n                        db.names.back().first.append(\"::\");\n                        db.names.back().first.append(name);\n                    }\n                    else\n                        db.names.pop_back();\n                }\n                break;\n            }\n        }\n    }\n    return first;\n}\n\n// <name> ::= <nested-name> // N\n//        ::= <local-name> # See Scope Encoding below  // Z\n//        ::= <unscoped-template-name> <template-args>\n//        ::= <unscoped-name>\n\n// <unscoped-template-name> ::= <unscoped-name>\n//                          ::= <substitution>\n\ntemplate <class C>\nconst char*\nparse_name(const char* first, const char* last, C& db,\n           bool* ends_with_template_args)\n{\n    if (last - first >= 2)\n    {\n        const char* t0 = first;\n        // extension: ignore L here\n        if (*t0 == 'L')\n            ++t0;\n        switch (*t0)\n        {\n        case 'N':\n          {\n            const char* t1 = parse_nested_name(t0, last, db,\n                                               ends_with_template_args);\n            if (t1 != t0)\n                first = t1;\n            break;\n          }\n        case 'Z':\n          {\n            const char* t1 = parse_local_name(t0, last, db,\n                                              ends_with_template_args);\n            if (t1 != t0)\n                first = t1;\n            break;\n          }\n        default:\n          {\n            const char* t1 = parse_unscoped_name(t0, last, db);\n            if (t1 != t0)\n            {\n                if (t1 != last && *t1 == 'I')  // <unscoped-template-name> <template-args>\n                {\n                    if (db.names.empty())\n                        return first;\n                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));\n                    t0 = t1;\n                    t1 = parse_template_args(t0, last, db);\n                    if (t1 != t0)\n                    {\n                        if (db.names.size() < 2)\n                            return first;\n                        auto tmp = db.names.back().move_full();\n                        db.names.pop_back();\n                        db.names.back().first += tmp;\n                        first = t1;\n                        if (ends_with_template_args)\n                            *ends_with_template_args = true;\n                    }\n                }\n                else   // <unscoped-name>\n                    first = t1;\n            }\n            else\n            {   // try <substitution> <template-args>\n                t1 = parse_substitution(t0, last, db);\n                if (t1 != t0 && t1 != last && *t1 == 'I')\n                {\n                    t0 = t1;\n                    t1 = parse_template_args(t0, last, db);\n                    if (t1 != t0)\n                    {\n                        if (db.names.size() < 2)\n                            return first;\n                        auto tmp = db.names.back().move_full();\n                        db.names.pop_back();\n                        db.names.back().first += tmp;\n                        first = t1;\n                        if (ends_with_template_args)\n                            *ends_with_template_args = true;\n                    }\n                }\n            }\n            break;\n          }\n        }\n    }\n    return first;\n}\n\n// <call-offset> ::= h <nv-offset> _\n//               ::= v <v-offset> _\n// \n// <nv-offset> ::= <offset number>\n//               # non-virtual base override\n// \n// <v-offset>  ::= <offset number> _ <virtual offset number>\n//               # virtual base override, with vcall offset\n\nconst char*\nparse_call_offset(const char* first, const char* last)\n{\n    if (first != last)\n    {\n        switch (*first)\n        {\n        case 'h':\n            {\n            const char* t = parse_number(first + 1, last);\n            if (t != first + 1 && t != last && *t == '_')\n                first = t + 1;\n            }\n            break;\n        case 'v':\n            {\n            const char* t = parse_number(first + 1, last);\n            if (t != first + 1 && t != last && *t == '_')\n            {\n                const char* t2 = parse_number(++t, last);\n                if (t2 != t && t2 != last && *t2 == '_')\n                    first = t2 + 1;\n            }\n            }\n            break;\n        }\n    }\n    return first;\n}\n\n// <special-name> ::= TV <type>    # virtual table\n//                ::= TT <type>    # VTT structure (construction vtable index)\n//                ::= TI <type>    # typeinfo structure\n//                ::= TS <type>    # typeinfo name (null-terminated byte string)\n//                ::= Tc <call-offset> <call-offset> <base encoding>\n//                    # base is the nominal target function of thunk\n//                    # first call-offset is 'this' adjustment\n//                    # second call-offset is result adjustment\n//                ::= T <call-offset> <base encoding>\n//                    # base is the nominal target function of thunk\n//                ::= GV <object name> # Guard variable for one-time initialization\n//                                     # No <type>\n//      extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first\n//      extension ::= GR <object name> # reference temporary for object\n\ntemplate <class C>\nconst char*\nparse_special_name(const char* first, const char* last, C& db)\n{\n    if (last - first > 2)\n    {\n        const char* t;\n        switch (*first)\n        {\n        case 'T':\n            switch (first[1])\n            {\n            case 'V':\n                // TV <type>    # virtual table\n                t = parse_type(first+2, last, db);\n                if (t != first+2)\n                {\n                    if (db.names.empty())\n                        return first;\n                    db.names.back().first.insert(0, \"vtable for \");\n                    first = t;\n                }\n                break;\n            case 'T':\n                // TT <type>    # VTT structure (construction vtable index)\n                t = parse_type(first+2, last, db);\n                if (t != first+2)\n                {\n                    if (db.names.empty())\n                        return first;\n                    db.names.back().first.insert(0, \"VTT for \");\n                    first = t;\n                }\n                break;\n            case 'I':\n                // TI <type>    # typeinfo structure\n                t = parse_type(first+2, last, db);\n                if (t != first+2)\n                {\n                    if (db.names.empty())\n                        return first;\n                    db.names.back().first.insert(0, \"typeinfo for \");\n                    first = t;\n                }\n                break;\n            case 'S':\n                // TS <type>    # typeinfo name (null-terminated byte string)\n                t = parse_type(first+2, last, db);\n                if (t != first+2)\n                {\n                    if (db.names.empty())\n                        return first;\n                    db.names.back().first.insert(0, \"typeinfo name for \");\n                    first = t;\n                }\n                break;\n            case 'c':\n                // Tc <call-offset> <call-offset> <base encoding>\n              {\n                const char* t0 = parse_call_offset(first+2, last);\n                if (t0 == first+2)\n                    break;\n                const char* t1 = parse_call_offset(t0, last);\n                if (t1 == t0)\n                    break;\n                t = parse_encoding(t1, last, db);\n                if (t != t1)\n                {\n                    if (db.names.empty())\n                        return first;\n                    db.names.back().first.insert(0, \"covariant return thunk to \");\n                    first = t;\n                }\n              }\n                break;\n            case 'C':\n                // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first\n                t = parse_type(first+2, last, db);\n                if (t != first+2)\n                {\n                    const char* t0 = parse_number(t, last);\n                    if (t0 != t && t0 != last && *t0 == '_')\n                    {\n                        const char* t1 = parse_type(++t0, last, db);\n                        if (t1 != t0)\n                        {\n                            if (db.names.size() < 2)\n                                return first;\n                            auto left = db.names.back().move_full();\n                            db.names.pop_back();\n                            db.names.back().first = \"construction vtable for \" +\n                                                    std::move(left) + \"-in-\" +\n                                                    db.names.back().move_full();\n                            first = t1;\n                        }\n                    }\n                }\n                break;\n            default:\n                // T <call-offset> <base encoding>\n                {\n                const char* t0 = parse_call_offset(first+1, last);\n                if (t0 == first+1)\n                    break;\n                t = parse_encoding(t0, last, db);\n                if (t != t0)\n                {\n                    if (db.names.empty())\n                        return first;\n                    if (first[2] == 'v')\n                    {\n                        db.names.back().first.insert(0, \"virtual thunk to \");\n                        first = t;\n                    }\n                    else\n                    {\n                        db.names.back().first.insert(0, \"non-virtual thunk to \");\n                        first = t;\n                    }\n                }\n                }\n                break;\n            }\n            break;\n        case 'G':\n            switch (first[1])\n            {\n            case 'V':\n                // GV <object name> # Guard variable for one-time initialization\n                t = parse_name(first+2, last, db);\n                if (t != first+2)\n                {\n                    if (db.names.empty())\n                        return first;\n                    db.names.back().first.insert(0, \"guard variable for \");\n                    first = t;\n                }\n                break;\n            case 'R':\n                // extension ::= GR <object name> # reference temporary for object\n                t = parse_name(first+2, last, db);\n                if (t != first+2)\n                {\n                    if (db.names.empty())\n                        return first;\n                    db.names.back().first.insert(0, \"reference temporary for \");\n                    first = t;\n                }\n                break;\n            }\n            break;\n        }\n    }\n    return first;\n}\n\ntemplate <class T>\nclass save_value\n{\n    T& restore_;\n    T original_value_;\npublic:\n    save_value(T& restore)\n        : restore_(restore),\n          original_value_(restore)\n        {}\n\n    ~save_value()\n    {\n        restore_ = std::move(original_value_);\n    }\n\n    save_value(const save_value&) = delete;\n    save_value& operator=(const save_value&) = delete;\n};\n\n// <encoding> ::= <function name> <bare-function-type>\n//            ::= <data name>\n//            ::= <special-name>\n\ntemplate <class C>\nconst char*\nparse_encoding(const char* first, const char* last, C& db)\n{\n    if (first != last)\n    {\n        save_value<decltype(db.encoding_depth)> su(db.encoding_depth);\n        ++db.encoding_depth;\n        save_value<decltype(db.tag_templates)> sb(db.tag_templates);\n        if (db.encoding_depth > 1)\n            db.tag_templates = true;\n        switch (*first)\n        {\n        case 'G':\n        case 'T':\n            first = parse_special_name(first, last, db);\n            break;\n        default:\n          {\n            bool ends_with_template_args = false;\n            const char* t = parse_name(first, last, db,\n                                       &ends_with_template_args);\n            unsigned cv = db.cv;\n            unsigned ref = db.ref;\n            if (t != first)\n            {\n                if (t != last && *t != 'E' && *t != '.')\n                {\n                    save_value<bool> sb2(db.tag_templates);\n                    db.tag_templates = false;\n                    const char* t2;\n                    typename C::String ret2;\n                    if (db.names.empty())\n                        return first;\n                    const typename C::String& nm = db.names.back().first;\n                    if (nm.empty())\n                        return first;\n                    if (!db.parsed_ctor_dtor_cv && ends_with_template_args)\n                    {\n                        t2 = parse_type(t, last, db);\n                        if (t2 == t)\n                            return first;\n                        if (db.names.size() < 2)\n                            return first;\n                        auto ret1 = std::move(db.names.back().first);\n                        ret2 = std::move(db.names.back().second);\n                        if (ret2.empty())\n                            ret1 += ' ';\n                        db.names.pop_back();\n                        db.names.back().first.insert(0, ret1);\n                        t = t2;\n                    }\n                    db.names.back().first += '(';\n                    if (t != last && *t == 'v')\n                    {\n                        ++t;\n                    }\n                    else\n                    {\n                        bool first_arg = true;\n                        while (true)\n                        {\n                            size_t k0 = db.names.size();\n                            t2 = parse_type(t, last, db);\n                            size_t k1 = db.names.size();\n                            if (t2 == t)\n                                break;\n                            if (k1 > k0)\n                            {\n                                typename C::String tmp;\n                                for (size_t k = k0; k < k1; ++k)\n                                {\n                                    if (!tmp.empty())\n                                        tmp += \", \";\n                                    tmp += db.names[k].move_full();\n                                }\n                                for (size_t k = k0; k < k1; ++k)\n                                    db.names.pop_back();\n                                if (!tmp.empty())\n                                {\n                                    if (db.names.empty())\n                                        return first;\n                                    if (!first_arg)\n                                        db.names.back().first += \", \";\n                                    else\n                                        first_arg = false;\n                                    db.names.back().first += tmp;\n                                }\n                            }\n                            t = t2;\n                        }\n                    }\n                    if (db.names.empty())\n                        return first;\n                    db.names.back().first += ')';\n                    if (cv & 1)\n                        db.names.back().first.append(\" const\");\n                    if (cv & 2)\n                        db.names.back().first.append(\" volatile\");\n                    if (cv & 4)\n                        db.names.back().first.append(\" restrict\");\n                    if (ref == 1)\n                        db.names.back().first.append(\" &\");\n                    else if (ref == 2)\n                        db.names.back().first.append(\" &&\");\n                    db.names.back().first += ret2;\n                    first = t;\n                }\n                else\n                    first = t;\n            }\n            break;\n          }\n        }\n    }\n    return first;\n}\n\n// _block_invoke\n// _block_invoke<decimal-digit>+\n// _block_invoke_<decimal-digit>+\n\ntemplate <class C>\nconst char*\nparse_block_invoke(const char* first, const char* last, C& db)\n{\n    if (last - first >= 13)\n    {\n        const char test[] = \"_block_invoke\";\n        const char* t = first;\n        for (int i = 0; i < 13; ++i, ++t)\n        {\n            if (*t != test[i])\n                return first;\n        }\n        if (t != last)\n        {\n            if (*t == '_')\n            {\n                // must have at least 1 decimal digit\n                if (++t == last || !std::isdigit(*t))\n                    return first;\n                ++t;\n            }\n            // parse zero or more digits\n            while (t != last && isdigit(*t))\n                ++t;\n        }\n        if (db.names.empty())\n            return first;\n        db.names.back().first.insert(0, \"invocation function for block in \");\n        first = t;\n    }\n    return first;\n}\n\n// extension\n// <dot-suffix> := .<anything and everything>\n\ntemplate <class C>\nconst char*\nparse_dot_suffix(const char* first, const char* last, C& db)\n{\n    if (first != last && *first == '.')\n    {\n        if (db.names.empty())\n            return first;\n        db.names.back().first += \" (\" + typename C::String(first, last) + \")\";\n        first = last;\n    }\n    return first;\n}\n\n// <block-involcaton-function> ___Z<encoding>_block_invoke\n// <block-involcaton-function> ___Z<encoding>_block_invoke<decimal-digit>+\n// <block-involcaton-function> ___Z<encoding>_block_invoke_<decimal-digit>+\n// <mangled-name> ::= _Z<encoding>\n//                ::= <type>\n\ntemplate <class C>\nvoid\ndemangle(const char* first, const char* last, C& db, int& status)\n{\n    if (first >= last)\n    {\n        status = invalid_mangled_name;\n        return;\n    }\n    if (*first == '_')\n    {\n        if (last - first >= 4)\n        {\n            if (first[1] == 'Z')\n            {\n                const char* t = parse_encoding(first+2, last, db);\n                if (t != first+2 && t != last && *t == '.')\n                    t = parse_dot_suffix(t, last, db);\n                if (t != last)\n                    status = invalid_mangled_name;\n            }\n            else if (first[1] == '_' && first[2] == '_' && first[3] == 'Z')\n            {\n                const char* t = parse_encoding(first+4, last, db);\n                if (t != first+4 && t != last)\n                {\n                    const char* t1 = parse_block_invoke(t, last, db);\n                    if (t1 != last)\n                        status = invalid_mangled_name;\n                }\n                else\n                    status = invalid_mangled_name;\n            }\n            else\n                status = invalid_mangled_name;\n        }\n        else\n            status = invalid_mangled_name;\n    }\n    else\n    {\n        const char* t = parse_type(first, last, db);\n        if (t != last)\n            status = invalid_mangled_name;\n    }\n    if (status == success && db.names.empty())\n        status = invalid_mangled_name;\n}\n\ntemplate <std::size_t N>\nclass arena\n{\n    static const std::size_t alignment = 16;\n    alignas(alignment) char buf_[N];\n    char* ptr_;\n\n    std::size_t \n    align_up(std::size_t n) noexcept\n        {return (n + (alignment-1)) & ~(alignment-1);}\n\n    bool\n    pointer_in_buffer(char* p) noexcept\n        {return buf_ <= p && p <= buf_ + N;}\n\npublic:\n    arena() noexcept : ptr_(buf_) {}\n    ~arena() {ptr_ = nullptr;}\n    arena(const arena&) = delete;\n    arena& operator=(const arena&) = delete;\n\n    char* allocate(std::size_t n);\n    void deallocate(char* p, std::size_t n) noexcept;\n\n    static constexpr std::size_t size() {return N;}\n    std::size_t used() const {return static_cast<std::size_t>(ptr_ - buf_);}\n    void reset() {ptr_ = buf_;}\n};\n\ntemplate <std::size_t N>\nchar*\narena<N>::allocate(std::size_t n)\n{\n    n = align_up(n);\n    if (static_cast<std::size_t>(buf_ + N - ptr_) >= n)\n    {\n        char* r = ptr_;\n        ptr_ += n;\n        return r;\n    }\n    return static_cast<char*>(std::malloc(n));\n}\n\ntemplate <std::size_t N>\nvoid\narena<N>::deallocate(char* p, std::size_t n) noexcept\n{\n    if (pointer_in_buffer(p))\n    {\n        n = align_up(n);\n        if (p + n == ptr_)\n            ptr_ = p;\n    }\n    else\n        std::free(p);\n}\n\ntemplate <class T, std::size_t N>\nclass short_alloc\n{\n    arena<N>& a_;\npublic:\n    typedef T value_type;\n\npublic:\n    template <class _Up> struct rebind {typedef short_alloc<_Up, N> other;};\n\n    short_alloc(arena<N>& a) noexcept : a_(a) {}\n    template <class U>\n        short_alloc(const short_alloc<U, N>& a) noexcept\n            : a_(a.a_) {}\n    short_alloc(const short_alloc&) = default;\n    short_alloc& operator=(const short_alloc&) = delete;\n\n    T* allocate(std::size_t n)\n    {\n        return reinterpret_cast<T*>(a_.allocate(n*sizeof(T)));\n    }\n    void deallocate(T* p, std::size_t n) noexcept\n    {\n        a_.deallocate(reinterpret_cast<char*>(p), n*sizeof(T));\n    }\n\n    template <class T1, std::size_t N1, class U, std::size_t M>\n    friend\n    bool\n    operator==(const short_alloc<T1, N1>& x, const short_alloc<U, M>& y) noexcept;\n\n    template <class U, std::size_t M> friend class short_alloc;\n};\n\ntemplate <class T, std::size_t N, class U, std::size_t M>\ninline\nbool\noperator==(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept\n{\n    return N == M && &x.a_ == &y.a_;\n}\n\ntemplate <class T, std::size_t N, class U, std::size_t M>\ninline\nbool\noperator!=(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept\n{\n    return !(x == y);\n}\n\ntemplate <class T>\nclass malloc_alloc\n{\npublic:\n    typedef T value_type;\n\n    malloc_alloc() = default;\n    template <class U> malloc_alloc(const malloc_alloc<U>&) noexcept {}\n\n    T* allocate(std::size_t n)\n    {\n        return static_cast<T*>(std::malloc(n*sizeof(T)));\n    }\n    void deallocate(T* p, std::size_t) noexcept\n    {\n        std::free(p);\n    }\n};\n\ntemplate <class T, class U>\ninline\nbool\noperator==(const malloc_alloc<T>&, const malloc_alloc<U>&) noexcept\n{\n    return true;\n}\n\ntemplate <class T, class U>\ninline\nbool\noperator!=(const malloc_alloc<T>& x, const malloc_alloc<U>& y) noexcept\n{\n    return !(x == y);\n}\n\nconst size_t bs = 4 * 1024;\ntemplate <class T> using Alloc = short_alloc<T, bs>;\ntemplate <class T> using Vector = std::vector<T, Alloc<T>>;\n\ntemplate <class StrT>\nstruct string_pair\n{\n    StrT first;\n    StrT second;\n\n    string_pair() = default;\n    string_pair(StrT f) : first(std::move(f)) {}\n    string_pair(StrT f, StrT s)\n        : first(std::move(f)), second(std::move(s)) {}\n    template <size_t N>\n        string_pair(const char (&s)[N]) : first(s, N-1) {}\n\n    size_t size() const {return first.size() + second.size();}\n    StrT full() const {return first + second;}\n    StrT move_full() {return std::move(first) + std::move(second);}\n};\n\nstruct Db\n{\n    typedef std::basic_string<char, std::char_traits<char>,\n                              malloc_alloc<char>> String;\n    typedef Vector<string_pair<String>> sub_type;\n    typedef Vector<sub_type> template_param_type;\n    sub_type names;\n    template_param_type subs;\n    Vector<template_param_type> template_param;\n    unsigned cv;\n    unsigned ref;\n    unsigned encoding_depth;\n    bool parsed_ctor_dtor_cv;\n    bool tag_templates;\n    bool fix_forward_references;\n    bool try_to_parse_template_args;\n\n    template <size_t N>\n    Db(arena<N>& ar) :\n        names(ar),\n        subs(0, names, ar),\n        template_param(0, subs, ar)\n    {}\n};\n\n}  // unnamed namespace\n\nextern \"C\"\n__attribute__ ((__visibility__(\"default\")))\nchar*\n__cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status)\n{\n    if (mangled_name == nullptr || (buf != nullptr && n == nullptr))\n    {\n        if (status)\n            *status = invalid_args;\n        return nullptr;\n    }\n    size_t internal_size = buf != nullptr ? *n : 0;\n    arena<bs> a;\n    Db db(a);\n    db.cv = 0;\n    db.ref = 0;\n    db.encoding_depth = 0;\n    db.parsed_ctor_dtor_cv = false;\n    db.tag_templates = true;\n    db.template_param.emplace_back(a);\n    db.fix_forward_references = false;\n    db.try_to_parse_template_args = true;\n    int internal_status = success;\n    size_t len = std::strlen(mangled_name);\n    demangle(mangled_name, mangled_name + len, db,\n             internal_status);\n    if (internal_status == success && db.fix_forward_references &&\n           !db.template_param.empty() && !db.template_param.front().empty())\n    {\n        db.fix_forward_references = false;\n        db.tag_templates = false;\n        db.names.clear();\n        db.subs.clear();\n        demangle(mangled_name, mangled_name + len, db, internal_status);\n        if (db.fix_forward_references)\n            internal_status = invalid_mangled_name;\n    }\n    if (internal_status == success)\n    {\n        size_t sz = db.names.back().size() + 1;\n        if (sz > internal_size)\n        {\n            char* newbuf = static_cast<char*>(std::realloc(buf, sz));\n            if (newbuf == nullptr)\n            {\n                internal_status = memory_alloc_failure;\n                buf = nullptr;\n            }\n            else\n            {\n                buf = newbuf;\n                if (n != nullptr)\n                    *n = sz;\n            }\n        }\n        if (buf != nullptr)\n        {\n            db.names.back().first += db.names.back().second;\n            std::memcpy(buf, db.names.back().first.data(), sz-1);\n            buf[sz-1] = char(0);\n        }\n    }\n    else\n        buf = nullptr;\n    if (status)\n        *status = internal_status;\n    return buf;\n}\n\n}  // __cxxabiv1\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_exception.cpp",
    "content": "//===------------------------- cxa_exception.cpp --------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//  \n//  This file implements the \"Exception Handling APIs\"\n//  http://mentorembedded.github.io/cxx-abi/abi-eh.html\n//  \n//===----------------------------------------------------------------------===//\n\n#include \"config.h\"\n#include \"cxxabi.h\"\n\n#include <exception>        // for std::terminate\n#include <cstdlib>          // for malloc, free\n#include <cstring>          // for memset\n#if !LIBCXXABI_HAS_NO_THREADS\n#  include <pthread.h>      // for fallback_malloc.ipp's mutexes\n#endif\n#include \"cxa_exception.hpp\"\n#include \"cxa_handlers.hpp\"\n\n// +---------------------------+-----------------------------+---------------+\n// | __cxa_exception           | _Unwind_Exception CLNGC++\\0 | thrown object |\n// +---------------------------+-----------------------------+---------------+\n//                                                           ^\n//                                                           |\n//   +-------------------------------------------------------+\n//   |\n// +---------------------------+-----------------------------+\n// | __cxa_dependent_exception | _Unwind_Exception CLNGC++\\1 |\n// +---------------------------+-----------------------------+\n\nnamespace __cxxabiv1 {\n\n#pragma GCC visibility push(default)\n\n//  Utility routines\nstatic\ninline\n__cxa_exception*\ncxa_exception_from_thrown_object(void* thrown_object)\n{\n    return static_cast<__cxa_exception*>(thrown_object) - 1;\n}\n\n// Note:  This is never called when exception_header is masquerading as a\n//        __cxa_dependent_exception.\nstatic\ninline\nvoid*\nthrown_object_from_cxa_exception(__cxa_exception* exception_header)\n{\n    return static_cast<void*>(exception_header + 1);\n}\n\n//  Get the exception object from the unwind pointer.\n//  Relies on the structure layout, where the unwind pointer is right in\n//  front of the user's exception object\nstatic\ninline\n__cxa_exception*\ncxa_exception_from_exception_unwind_exception(_Unwind_Exception* unwind_exception)\n{\n    return cxa_exception_from_thrown_object(unwind_exception + 1 );\n}\n\nstatic\ninline\nsize_t\ncxa_exception_size_from_exception_thrown_size(size_t size)\n{\n    return size + sizeof (__cxa_exception);\n}\n\nstatic void setExceptionClass(_Unwind_Exception* unwind_exception) {\n    unwind_exception->exception_class = kOurExceptionClass;\n}\n\nstatic void setDependentExceptionClass(_Unwind_Exception* unwind_exception) {\n    unwind_exception->exception_class = kOurDependentExceptionClass;\n}\n\n//  Is it one of ours?\nstatic bool isOurExceptionClass(const _Unwind_Exception* unwind_exception) {\n    return (unwind_exception->exception_class & get_vendor_and_language) == \n           (kOurExceptionClass                & get_vendor_and_language);\n}\n\nstatic bool isDependentException(_Unwind_Exception* unwind_exception) {\n    return (unwind_exception->exception_class & 0xFF) == 0x01;\n}\n\n//  This does not need to be atomic\nstatic inline int incrementHandlerCount(__cxa_exception *exception) {\n    return ++exception->handlerCount;\n}\n\n//  This does not need to be atomic\nstatic inline  int decrementHandlerCount(__cxa_exception *exception) {\n    return --exception->handlerCount;\n}\n\n#include \"fallback_malloc.ipp\"\n\n//  Allocate some memory from _somewhere_\nstatic void *do_malloc(size_t size) {\n    void *ptr = std::malloc(size);\n    if (NULL == ptr) // if malloc fails, fall back to emergency stash\n        ptr = fallback_malloc(size);\n    return ptr;\n}\n\nstatic void do_free(void *ptr) {\n    is_fallback_ptr(ptr) ? fallback_free(ptr) : std::free(ptr);\n}\n\n/*\n    If reason isn't _URC_FOREIGN_EXCEPTION_CAUGHT, then the terminateHandler\n    stored in exc is called.  Otherwise the exceptionDestructor stored in \n    exc is called, and then the memory for the exception is deallocated.\n\n    This is never called for a __cxa_dependent_exception.\n*/\nstatic\nvoid\nexception_cleanup_func(_Unwind_Reason_Code reason, _Unwind_Exception* unwind_exception)\n{\n    __cxa_exception* exception_header = cxa_exception_from_exception_unwind_exception(unwind_exception);\n    if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason)\n        std::__terminate(exception_header->terminateHandler);\n    // Just in case there exists a dependent exception that is pointing to this,\n    //    check the reference count and only destroy this if that count goes to zero.\n    __cxa_decrement_exception_refcount(unwind_exception + 1);\n}\n\nstatic LIBCXXABI_NORETURN void failed_throw(__cxa_exception* exception_header) {\n//  Section 2.5.3 says:\n//      * For purposes of this ABI, several things are considered exception handlers:\n//      ** A terminate() call due to a throw.\n//  and\n//      * Upon entry, Following initialization of the catch parameter, \n//          a handler must call:\n//      * void *__cxa_begin_catch(void *exceptionObject );\n    (void) __cxa_begin_catch(&exception_header->unwindHeader);\n    std::__terminate(exception_header->terminateHandler);\n}\n\nextern \"C\" {\n\n//  Allocate a __cxa_exception object, and zero-fill it.\n//  Reserve \"thrown_size\" bytes on the end for the user's exception\n//  object. Zero-fill the object. If memory can't be allocated, call\n//  std::terminate. Return a pointer to the memory to be used for the\n//  user's exception object.\nvoid * __cxa_allocate_exception (size_t thrown_size) throw() {\n    size_t actual_size = cxa_exception_size_from_exception_thrown_size(thrown_size);\n    __cxa_exception* exception_header = static_cast<__cxa_exception*>(do_malloc(actual_size));\n    if (NULL == exception_header)\n        std::terminate();\n    std::memset(exception_header, 0, actual_size);\n    return thrown_object_from_cxa_exception(exception_header);\n}\n\n\n//  Free a __cxa_exception object allocated with __cxa_allocate_exception.\nvoid __cxa_free_exception (void * thrown_object) throw() {\n    do_free(cxa_exception_from_thrown_object(thrown_object));\n}\n\n\n//  This function shall allocate a __cxa_dependent_exception and\n//  return a pointer to it. (Really to the object, not past its' end).\n//  Otherwise, it will work like __cxa_allocate_exception.\nvoid * __cxa_allocate_dependent_exception () {\n    size_t actual_size = sizeof(__cxa_dependent_exception);\n    void *ptr = do_malloc(actual_size);\n    if (NULL == ptr)\n        std::terminate();\n    std::memset(ptr, 0, actual_size);\n    return ptr;\n}\n\n\n//  This function shall free a dependent_exception.\n//  It does not affect the reference count of the primary exception.\nvoid __cxa_free_dependent_exception (void * dependent_exception) {\n    do_free(dependent_exception);\n}\n\n\n// 2.4.3 Throwing the Exception Object\n/*\nAfter constructing the exception object with the throw argument value,\nthe generated code calls the __cxa_throw runtime library routine. This\nroutine never returns.\n\nThe __cxa_throw routine will do the following:\n\n* Obtain the __cxa_exception header from the thrown exception object address,\nwhich can be computed as follows: \n __cxa_exception *header = ((__cxa_exception *) thrown_exception - 1); \n* Save the current unexpected_handler and terminate_handler in the __cxa_exception header.\n* Save the tinfo and dest arguments in the __cxa_exception header. \n* Set the exception_class field in the unwind header. This is a 64-bit value\nrepresenting the ASCII string \"XXXXC++\\0\", where \"XXXX\" is a\nvendor-dependent string. That is, for implementations conforming to this\nABI, the low-order 4 bytes of this 64-bit value will be \"C++\\0\".\n* Increment the uncaught_exception flag. \n* Call _Unwind_RaiseException in the system unwind library, Its argument is the\npointer to the thrown exception, which __cxa_throw itself received as an argument.\n__Unwind_RaiseException begins the process of stack unwinding, described\nin Section 2.5. In special cases, such as an inability to find a\nhandler, _Unwind_RaiseException may return. In that case, __cxa_throw\nwill call terminate, assuming that there was no handler for the\nexception.\n*/\nLIBCXXABI_NORETURN\nvoid \n__cxa_throw(void* thrown_object, std::type_info* tinfo, void (*dest)(void*))\n{\n    __cxa_eh_globals *globals = __cxa_get_globals();\n    __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);\n\n    exception_header->unexpectedHandler = std::get_unexpected();\n    exception_header->terminateHandler  = std::get_terminate();\n    exception_header->exceptionType = tinfo;\n    exception_header->exceptionDestructor = dest;\n    setExceptionClass(&exception_header->unwindHeader);\n    exception_header->referenceCount = 1;  // This is a newly allocated exception, no need for thread safety.\n    globals->uncaughtExceptions += 1;   // Not atomically, since globals are thread-local\n\n    exception_header->unwindHeader.exception_cleanup = exception_cleanup_func;\n#ifdef __USING_SJLJ_EXCEPTIONS__\n    _Unwind_SjLj_RaiseException(&exception_header->unwindHeader);\n#else\n    _Unwind_RaiseException(&exception_header->unwindHeader);\n#endif\n    //  This only happens when there is no handler, or some unexpected unwinding\n    //     error happens.\n    failed_throw(exception_header);\n}\n\n\n// 2.5.3 Exception Handlers\n/*\nThe adjusted pointer is computed by the personality routine during phase 1\n  and saved in the exception header (either __cxa_exception or\n  __cxa_dependent_exception).\n\n  Requires:  exception is native\n*/\nvoid*\n__cxa_get_exception_ptr(void* unwind_exception) throw()\n{\n#if LIBCXXABI_ARM_EHABI\n    return reinterpret_cast<void*>(\n        static_cast<_Unwind_Control_Block*>(unwind_exception)->barrier_cache.bitpattern[0]);\n#else\n    return cxa_exception_from_exception_unwind_exception(\n        static_cast<_Unwind_Exception*>(unwind_exception))->adjustedPtr;\n#endif\n}\n\n#if LIBCXXABI_ARM_EHABI\n/*\nThe routine to be called before the cleanup.  This will save __cxa_exception in\n__cxa_eh_globals, so that __cxa_end_cleanup() can recover later.\n*/\nbool\n__cxa_begin_cleanup(void* unwind_arg) throw ()\n{\n    _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg);\n    __cxa_eh_globals* globals = __cxa_get_globals();\n    __cxa_exception* exception_header =\n        cxa_exception_from_exception_unwind_exception(unwind_exception);\n\n    if (isOurExceptionClass(unwind_exception))\n    {\n        if (0 == exception_header->propagationCount)\n        {\n            exception_header->nextPropagatingException = globals->propagatingExceptions;\n            globals->propagatingExceptions = exception_header;\n        }\n        ++exception_header->propagationCount;\n    }\n    else\n    {\n        // If the propagatingExceptions stack is not empty, since we can't\n        // chain the foreign exception, terminate it.\n        if (NULL != globals->propagatingExceptions)\n            std::terminate();\n        globals->propagatingExceptions = exception_header;\n    }\n    return true;\n}\n\n/*\nThe routine to be called after the cleanup has been performed.  It will get the\npropagating __cxa_exception from __cxa_eh_globals, and continue the stack\nunwinding with _Unwind_Resume.\n\nAccording to ARM EHABI 8.4.1, __cxa_end_cleanup() should not clobber any\nregister, thus we have to write this function in assembly so that we can save\n{r1, r2, r3}.  We don't have to save r0 because it is the return value and the\nfirst argument to _Unwind_Resume().  In addition, we are saving r4 in order to\nalign the stack to 16 bytes, even though it is a callee-save register.\n*/\n__attribute__((used)) static _Unwind_Exception *\n__cxa_end_cleanup_impl()\n{\n    __cxa_eh_globals* globals = __cxa_get_globals();\n    __cxa_exception* exception_header = globals->propagatingExceptions;\n    if (NULL == exception_header)\n    {\n        // It seems that __cxa_begin_cleanup() is not called properly.\n        // We have no choice but terminate the program now.\n        std::terminate();\n    }\n\n    if (isOurExceptionClass(&exception_header->unwindHeader))\n    {\n        --exception_header->propagationCount;\n        if (0 == exception_header->propagationCount)\n        {\n            globals->propagatingExceptions = exception_header->nextPropagatingException;\n            exception_header->nextPropagatingException = NULL;\n        }\n    }\n    else\n    {\n        globals->propagatingExceptions = NULL;\n    }\n    return &exception_header->unwindHeader;\n}\n\nasm (\n    \"\t.pushsection\t.text.__cxa_end_cleanup,\\\"ax\\\",%progbits\\n\"\n    \"\t.globl\t__cxa_end_cleanup\\n\"\n    \"\t.type\t__cxa_end_cleanup,%function\\n\"\n    \"__cxa_end_cleanup:\\n\"\n    \"\tpush\t{r1, r2, r3, r4}\\n\"\n    \"\tbl\t__cxa_end_cleanup_impl\\n\"\n    \"\tpop\t{r1, r2, r3, r4}\\n\"\n    \"\tbl\t_Unwind_Resume\\n\"\n    \"\tbl\tabort\\n\"\n    \"\t.popsection\"\n);\n#endif  // LIBCXXABI_ARM_EHABI\n    \n/*\nThis routine can catch foreign or native exceptions.  If native, the exception\ncan be a primary or dependent variety.  This routine may remain blissfully\nignorant of whether the native exception is primary or dependent.\n\nIf the exception is native:\n* Increment's the exception's handler count.\n* Push the exception on the stack of currently-caught exceptions if it is not \n  already there (from a rethrow).\n* Decrements the uncaught_exception count.\n* Returns the adjusted pointer to the exception object, which is stored in\n  the __cxa_exception by the personality routine.\n\nIf the exception is foreign, this means it did not originate from one of throw\nroutines.  The foreign exception does not necessarily have a __cxa_exception\nheader.  However we can catch it here with a catch (...), or with a call\nto terminate or unexpected during unwinding.\n* Do not try to increment the exception's handler count, we don't know where\n  it is.\n* Push the exception on the stack of currently-caught exceptions only if the\n  stack is empty.  The foreign exception has no way to link to the current\n  top of stack.  If the stack is not empty, call terminate.  Even with an\n  empty stack, this is hacked in by pushing a pointer to an imaginary\n  __cxa_exception block in front of the foreign exception.  It would be better\n  if the __cxa_eh_globals structure had a stack of _Unwind_Exception, but it\n  doesn't.  It has a stack of __cxa_exception (which has a next* in it).\n* Do not decrement the uncaught_exception count because we didn't increment it\n  in __cxa_throw (or one of our rethrow functions).\n* If we haven't terminated, assume the exception object is just past the \n  _Unwind_Exception and return a pointer to that.\n*/\nvoid*\n__cxa_begin_catch(void* unwind_arg) throw()\n{\n    _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg);\n    bool native_exception = isOurExceptionClass(unwind_exception);\n    __cxa_eh_globals* globals = __cxa_get_globals();\n    // exception_header is a hackish offset from a foreign exception, but it\n    //   works as long as we're careful not to try to access any __cxa_exception\n    //   parts.\n    __cxa_exception* exception_header =\n            cxa_exception_from_exception_unwind_exception\n            (\n                static_cast<_Unwind_Exception*>(unwind_exception)\n            );\n    if (native_exception)\n    {\n        // Increment the handler count, removing the flag about being rethrown\n        exception_header->handlerCount = exception_header->handlerCount < 0 ?\n            -exception_header->handlerCount + 1 : exception_header->handlerCount + 1;\n        //  place the exception on the top of the stack if it's not already\n        //    there by a previous rethrow\n        if (exception_header != globals->caughtExceptions)\n        {\n            exception_header->nextException = globals->caughtExceptions;\n            globals->caughtExceptions = exception_header;\n        }\n        globals->uncaughtExceptions -= 1;   // Not atomically, since globals are thread-local\n#if LIBCXXABI_ARM_EHABI\n        return reinterpret_cast<void*>(exception_header->unwindHeader.barrier_cache.bitpattern[0]);\n#else\n        return exception_header->adjustedPtr;\n#endif\n    }\n    // Else this is a foreign exception\n    // If the caughtExceptions stack is not empty, terminate\n    if (globals->caughtExceptions != 0)\n        std::terminate();\n    // Push the foreign exception on to the stack\n    globals->caughtExceptions = exception_header;\n    return unwind_exception + 1;\n}\n\n\n/*\nUpon exit for any reason, a handler must call:\n    void __cxa_end_catch ();\n\nThis routine can be called for either a native or foreign exception.\nFor a native exception:\n* Locates the most recently caught exception and decrements its handler count.\n* Removes the exception from the caught exception stack, if the handler count goes to zero.\n* If the handler count goes down to zero, and the exception was not re-thrown\n  by throw, it locates the primary exception (which may be the same as the one\n  it's handling) and decrements its reference count. If that reference count\n  goes to zero, the function destroys the exception. In any case, if the current\n  exception is a dependent exception, it destroys that.\n\nFor a foreign exception:\n* If it has been rethrown, there is nothing to do.\n* Otherwise delete the exception and pop the catch stack to empty.\n*/\nvoid __cxa_end_catch()\n{\n  static_assert(sizeof(__cxa_exception) == sizeof(__cxa_dependent_exception),\n                \"sizeof(__cxa_exception) must be equal to \"\n                \"sizeof(__cxa_dependent_exception)\");\n    static_assert(offsetof(__cxa_exception, referenceCount) ==\n                      offsetof(__cxa_dependent_exception, primaryException),\n                  \"the layout of __cxa_exception must match the layout of \"\n                  \"__cxa_dependent_exception\");\n    static_assert(offsetof(__cxa_exception, handlerCount) ==\n                      offsetof(__cxa_dependent_exception, handlerCount),\n                  \"the layout of __cxa_exception must match the layout of \"\n                  \"__cxa_dependent_exception\");\n    __cxa_eh_globals* globals = __cxa_get_globals_fast(); // __cxa_get_globals called in __cxa_begin_catch\n    __cxa_exception* exception_header = globals->caughtExceptions;\n    // If we've rethrown a foreign exception, then globals->caughtExceptions\n    //    will have been made an empty stack by __cxa_rethrow() and there is\n    //    nothing more to be done.  Do nothing!\n    if (NULL != exception_header)\n    {\n        bool native_exception = isOurExceptionClass(&exception_header->unwindHeader);\n        if (native_exception)\n        {\n            // This is a native exception\n            if (exception_header->handlerCount < 0)\n            {\n                //  The exception has been rethrown by __cxa_rethrow, so don't delete it\n                if (0 == incrementHandlerCount(exception_header))\n                {\n                    //  Remove from the chain of uncaught exceptions\n                    globals->caughtExceptions = exception_header->nextException;\n                    // but don't destroy\n                }\n                // Keep handlerCount negative in case there are nested catch's\n                //   that need to be told that this exception is rethrown.  Don't\n                //   erase this rethrow flag until the exception is recaught.\n            }\n            else\n            {\n                // The native exception has not been rethrown\n                if (0 == decrementHandlerCount(exception_header))\n                {\n                    //  Remove from the chain of uncaught exceptions\n                    globals->caughtExceptions = exception_header->nextException;\n                    // Destroy this exception, being careful to distinguish\n                    //    between dependent and primary exceptions\n                    if (isDependentException(&exception_header->unwindHeader))\n                    {\n                        // Reset exception_header to primaryException and deallocate the dependent exception\n                        __cxa_dependent_exception* dep_exception_header =\n                            reinterpret_cast<__cxa_dependent_exception*>(exception_header);\n                        exception_header =\n                            cxa_exception_from_thrown_object(dep_exception_header->primaryException);\n                        __cxa_free_dependent_exception(dep_exception_header);\n                    }\n                    // Destroy the primary exception only if its referenceCount goes to 0\n                    //    (this decrement must be atomic)\n                    __cxa_decrement_exception_refcount(thrown_object_from_cxa_exception(exception_header));\n                }\n            }\n        }       \n        else\n        {\n            // The foreign exception has not been rethrown.  Pop the stack\n            //    and delete it.  If there are nested catch's and they try\n            //    to touch a foreign exception in any way, that is undefined\n            //     behavior.  They likely can't since the only way to catch\n            //     a foreign exception is with catch (...)!\n            _Unwind_DeleteException(&globals->caughtExceptions->unwindHeader);\n            globals->caughtExceptions = 0;\n        }\n    }\n}\n\n// Note:  exception_header may be masquerading as a __cxa_dependent_exception\n//        and that's ok.  exceptionType is there too.\n//        However watch out for foreign exceptions.  Return null for them.\nstd::type_info * __cxa_current_exception_type() {\n//  get the current exception\n    __cxa_eh_globals *globals = __cxa_get_globals_fast();\n    if (NULL == globals)\n        return NULL;     //  If there have never been any exceptions, there are none now.\n    __cxa_exception *exception_header = globals->caughtExceptions;\n    if (NULL == exception_header)\n        return NULL;        //  No current exception\n    if (!isOurExceptionClass(&exception_header->unwindHeader))\n        return NULL;\n    return exception_header->exceptionType;\n}\n\n// 2.5.4 Rethrowing Exceptions\n/*  This routine can rethrow native or foreign exceptions.\nIf the exception is native:\n* marks the exception object on top of the caughtExceptions stack \n  (in an implementation-defined way) as being rethrown. \n* If the caughtExceptions stack is empty, it calls terminate() \n  (see [C++FDIS] [except.throw], 15.1.8). \n* It then calls _Unwind_RaiseException which should not return\n   (terminate if it does).\n  Note:  exception_header may be masquerading as a __cxa_dependent_exception\n         and that's ok.\n*/\nLIBCXXABI_NORETURN\nvoid\n__cxa_rethrow()\n{\n    __cxa_eh_globals* globals = __cxa_get_globals();\n    __cxa_exception* exception_header = globals->caughtExceptions;\n    if (NULL == exception_header)\n        std::terminate();      // throw; called outside of a exception handler\n    bool native_exception = isOurExceptionClass(&exception_header->unwindHeader);\n    if (native_exception)\n    {\n        //  Mark the exception as being rethrown (reverse the effects of __cxa_begin_catch)\n        exception_header->handlerCount = -exception_header->handlerCount;\n        globals->uncaughtExceptions += 1;\n        //  __cxa_end_catch will remove this exception from the caughtExceptions stack if necessary\n    }\n    else  // this is a foreign exception\n    {\n        // The only way to communicate to __cxa_end_catch that we've rethrown\n        //   a foreign exception, so don't delete us, is to pop the stack here\n        //   which must be empty afterwards.  Then __cxa_end_catch will do\n        //   nothing\n        globals->caughtExceptions = 0;\n    }\n#ifdef __USING_SJLJ_EXCEPTIONS__\n    _Unwind_SjLj_RaiseException(&exception_header->unwindHeader);\n#else\n    _Unwind_RaiseException(&exception_header->unwindHeader);\n#endif\n\n    //  If we get here, some kind of unwinding error has occurred.\n    //  There is some weird code generation bug happening with \n    //     Apple clang version 4.0 (tags/Apple/clang-418.0.2) (based on LLVM 3.1svn)\n    //     If we call failed_throw here.  Turns up with -O2 or higher, and -Os.\n    __cxa_begin_catch(&exception_header->unwindHeader);\n    if (native_exception)\n        std::__terminate(exception_header->terminateHandler);\n    // Foreign exception: can't get exception_header->terminateHandler\n    std::terminate();\n}\n\n/*\n    If thrown_object is not null, atomically increment the referenceCount field\n    of the __cxa_exception header associated with the thrown object referred to\n    by thrown_object.\n\n    Requires:  If thrown_object is not NULL, it is a native exception.\n*/\nvoid\n__cxa_increment_exception_refcount(void* thrown_object) throw()\n{\n    if (thrown_object != NULL )\n    {\n        __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);\n        __sync_add_and_fetch(&exception_header->referenceCount, 1);\n    }\n}\n\n/*\n    If thrown_object is not null, atomically decrement the referenceCount field\n    of the __cxa_exception header associated with the thrown object referred to\n    by thrown_object.  If the referenceCount drops to zero, destroy and\n    deallocate the exception.\n\n    Requires:  If thrown_object is not NULL, it is a native exception.\n*/\nvoid\n__cxa_decrement_exception_refcount(void* thrown_object) throw()\n{\n    if (thrown_object != NULL )\n    {\n        __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);\n        if (__sync_sub_and_fetch(&exception_header->referenceCount, size_t(1)) == 0)\n        {\n            if (NULL != exception_header->exceptionDestructor)\n                exception_header->exceptionDestructor(thrown_object);\n            __cxa_free_exception(thrown_object);\n        }\n    }\n}\n\n/*\n    Returns a pointer to the thrown object (if any) at the top of the\n    caughtExceptions stack.  Atomically increment the exception's referenceCount.\n    If there is no such thrown object or if the thrown object is foreign,\n    returns null.\n\n    We can use __cxa_get_globals_fast here to get the globals because if there have\n    been no exceptions thrown, ever, on this thread, we can return NULL without \n    the need to allocate the exception-handling globals.\n*/\nvoid*\n__cxa_current_primary_exception() throw()\n{\n//  get the current exception\n    __cxa_eh_globals* globals = __cxa_get_globals_fast();\n    if (NULL == globals)\n        return NULL;        //  If there are no globals, there is no exception\n    __cxa_exception* exception_header = globals->caughtExceptions;\n    if (NULL == exception_header)\n        return NULL;        //  No current exception\n    if (!isOurExceptionClass(&exception_header->unwindHeader))\n        return NULL;        // Can't capture a foreign exception (no way to refcount it)\n    if (isDependentException(&exception_header->unwindHeader)) {\n        __cxa_dependent_exception* dep_exception_header =\n            reinterpret_cast<__cxa_dependent_exception*>(exception_header);\n        exception_header = cxa_exception_from_thrown_object(dep_exception_header->primaryException);\n    }\n    void* thrown_object = thrown_object_from_cxa_exception(exception_header);\n    __cxa_increment_exception_refcount(thrown_object);\n    return thrown_object;\n}\n\n/*\n    If reason isn't _URC_FOREIGN_EXCEPTION_CAUGHT, then the terminateHandler\n    stored in exc is called.  Otherwise the referenceCount stored in the\n    primary exception is decremented, destroying the primary if necessary.\n    Finally the dependent exception is destroyed.\n*/\nstatic\nvoid\ndependent_exception_cleanup(_Unwind_Reason_Code reason, _Unwind_Exception* unwind_exception)\n{\n    __cxa_dependent_exception* dep_exception_header = \n                      reinterpret_cast<__cxa_dependent_exception*>(unwind_exception + 1) - 1;\n    if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason)\n        std::__terminate(dep_exception_header->terminateHandler);\n    __cxa_decrement_exception_refcount(dep_exception_header->primaryException);\n    __cxa_free_dependent_exception(dep_exception_header);\n}\n\n/*\n    If thrown_object is not null, allocate, initialize and throw a dependent\n    exception.\n*/\nvoid\n__cxa_rethrow_primary_exception(void* thrown_object)\n{\n    if ( thrown_object != NULL )\n    {\n        // thrown_object guaranteed to be native because\n        //   __cxa_current_primary_exception returns NULL for foreign exceptions\n        __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);\n        __cxa_dependent_exception* dep_exception_header =\n            static_cast<__cxa_dependent_exception*>(__cxa_allocate_dependent_exception());\n        dep_exception_header->primaryException = thrown_object;\n        __cxa_increment_exception_refcount(thrown_object);\n        dep_exception_header->exceptionType = exception_header->exceptionType;\n        dep_exception_header->unexpectedHandler = std::get_unexpected();\n        dep_exception_header->terminateHandler = std::get_terminate();\n        setDependentExceptionClass(&dep_exception_header->unwindHeader);\n        __cxa_get_globals()->uncaughtExceptions += 1;\n        dep_exception_header->unwindHeader.exception_cleanup = dependent_exception_cleanup;\n#ifdef __USING_SJLJ_EXCEPTIONS__\n        _Unwind_SjLj_RaiseException(&dep_exception_header->unwindHeader);\n#else\n        _Unwind_RaiseException(&dep_exception_header->unwindHeader);\n#endif\n        // Some sort of unwinding error.  Note that terminate is a handler.\n        __cxa_begin_catch(&dep_exception_header->unwindHeader);\n    }\n    // If we return client will call terminate()\n}\n\nbool\n__cxa_uncaught_exception() throw() { return __cxa_uncaught_exceptions() != 0; }\n\nunsigned int\n__cxa_uncaught_exceptions() throw()\n{\n    // This does not report foreign exceptions in flight\n    __cxa_eh_globals* globals = __cxa_get_globals_fast();\n    if (globals == 0)\n        return 0;\n    return globals->uncaughtExceptions;\n}\n\n}  // extern \"C\"\n\n#pragma GCC visibility pop\n\n}  // abi\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_exception.hpp",
    "content": "//===------------------------- cxa_exception.hpp --------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//  \n//  This file implements the \"Exception Handling APIs\"\n//  http://mentorembedded.github.io/cxx-abi/abi-eh.html\n//  \n//===----------------------------------------------------------------------===//\n\n#ifndef _CXA_EXCEPTION_H\n#define _CXA_EXCEPTION_H\n\n#include <exception> // for std::unexpected_handler and std::terminate_handler\n#include <cxxabi.h>\n#include \"unwind.h\"\n\nnamespace __cxxabiv1 {\n\n#pragma GCC visibility push(hidden)\n\nstatic const uint64_t kOurExceptionClass          = 0x434C4E47432B2B00; // CLNGC++\\0\nstatic const uint64_t kOurDependentExceptionClass = 0x434C4E47432B2B01; // CLNGC++\\1\nstatic const uint64_t get_vendor_and_language     = 0xFFFFFFFFFFFFFF00; // mask for CLNGC++\n\nstruct __cxa_exception {\n#if defined(__LP64__) || LIBCXXABI_ARM_EHABI\n    // This is a new field to support C++ 0x exception_ptr.\n    // For binary compatibility it is at the start of this\n    // struct which is prepended to the object thrown in\n    // __cxa_allocate_exception.\n    size_t referenceCount;\n#endif\n\n    //  Manage the exception object itself.\n    std::type_info *exceptionType;\n    void (*exceptionDestructor)(void *);\n    std::unexpected_handler unexpectedHandler;\n    std::terminate_handler  terminateHandler;\n\n    __cxa_exception *nextException;\n\n    int handlerCount;\n\n#if LIBCXXABI_ARM_EHABI\n    __cxa_exception* nextPropagatingException;\n    int propagationCount;\n#else\n    int handlerSwitchValue;\n    const unsigned char *actionRecord;\n    const unsigned char *languageSpecificData;\n    void *catchTemp;\n    void *adjustedPtr;\n#endif\n\n#if !defined(__LP64__) && !LIBCXXABI_ARM_EHABI\n    // This is a new field to support C++ 0x exception_ptr.\n    // For binary compatibility it is placed where the compiler\n    // previously adding padded to 64-bit align unwindHeader.\n    size_t referenceCount;\n#endif\n\n    _Unwind_Exception unwindHeader;\n};\n\n// http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html\n// The layout of this structure MUST match the layout of __cxa_exception, with\n// primaryException instead of referenceCount.\nstruct __cxa_dependent_exception {\n#if defined(__LP64__) || LIBCXXABI_ARM_EHABI\n    void* primaryException;\n#endif\n\n    std::type_info *exceptionType;\n    void (*exceptionDestructor)(void *);\n    std::unexpected_handler unexpectedHandler;\n    std::terminate_handler terminateHandler;\n\n    __cxa_exception *nextException;\n\n    int handlerCount;\n\n#if LIBCXXABI_ARM_EHABI\n    __cxa_exception* nextPropagatingException;\n    int propagationCount;\n#else\n    int handlerSwitchValue;\n    const unsigned char *actionRecord;\n    const unsigned char *languageSpecificData;\n    void * catchTemp;\n    void *adjustedPtr;\n#endif\n\n#if !defined(__LP64__) && !LIBCXXABI_ARM_EHABI\n    void* primaryException;\n#endif\n\n    _Unwind_Exception unwindHeader;\n};\n\nstruct __cxa_eh_globals {\n    __cxa_exception *   caughtExceptions;\n    unsigned int        uncaughtExceptions;\n#if LIBCXXABI_ARM_EHABI\n    __cxa_exception* propagatingExceptions;\n#endif\n};\n\n#pragma GCC visibility pop\n#pragma GCC visibility push(default)\n\nextern \"C\" __cxa_eh_globals * __cxa_get_globals      ();\nextern \"C\" __cxa_eh_globals * __cxa_get_globals_fast ();\n\nextern \"C\" void * __cxa_allocate_dependent_exception ();\nextern \"C\" void __cxa_free_dependent_exception (void * dependent_exception);\n\n#pragma GCC visibility pop\n\n}  // namespace __cxxabiv1\n\n#endif  // _CXA_EXCEPTION_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_exception_storage.cpp",
    "content": "//===--------------------- cxa_exception_storage.cpp ----------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//  \n//  This file implements the storage for the \"Caught Exception Stack\"\n//  http://mentorembedded.github.io/cxx-abi/abi-eh.html (section 2.2.2)\n//  \n//===----------------------------------------------------------------------===//\n\n#include \"cxa_exception.hpp\"\n\n#include \"config.h\"\n\n#if LIBCXXABI_HAS_NO_THREADS\n\nnamespace __cxxabiv1 {\nextern \"C\" {\n    static __cxa_eh_globals eh_globals;\n    __cxa_eh_globals *__cxa_get_globals() { return &eh_globals; }\n    __cxa_eh_globals *__cxa_get_globals_fast() { return &eh_globals; }\n    }\n}\n\n#elif defined(HAS_THREAD_LOCAL)\n\nnamespace __cxxabiv1 {\n\nnamespace {\n    __cxa_eh_globals * __globals () {\n        static thread_local __cxa_eh_globals eh_globals;\n        return &eh_globals;\n        }\n    }\n\nextern \"C\" {\n    __cxa_eh_globals * __cxa_get_globals      () { return __globals (); }\n    __cxa_eh_globals * __cxa_get_globals_fast () { return __globals (); }\n    }\n}\n\n#else\n\n#include <pthread.h>\n#include <cstdlib>          // for calloc, free\n#include \"abort_message.h\"\n\n//  In general, we treat all pthread errors as fatal.\n//  We cannot call std::terminate() because that will in turn\n//  call __cxa_get_globals() and cause infinite recursion.\n\nnamespace __cxxabiv1 {\nnamespace {\n    pthread_key_t  key_;\n    pthread_once_t flag_ = PTHREAD_ONCE_INIT;\n\n    void destruct_ (void *p) {\n        std::free ( p );\n        if ( 0 != ::pthread_setspecific ( key_, NULL ) ) \n            abort_message(\"cannot zero out thread value for __cxa_get_globals()\");\n        }\n\n    void construct_ () {\n        if ( 0 != pthread_key_create ( &key_, destruct_ ) )\n            abort_message(\"cannot create pthread key for __cxa_get_globals()\");\n        }\n}   \n\nextern \"C\" {\n    __cxa_eh_globals * __cxa_get_globals () {\n    //  Try to get the globals for this thread\n        __cxa_eh_globals* retVal = __cxa_get_globals_fast ();\n    \n    //  If this is the first time we've been asked for these globals, create them\n        if ( NULL == retVal ) {\n            retVal = static_cast<__cxa_eh_globals*>\n                        (std::calloc (1, sizeof (__cxa_eh_globals)));\n            if ( NULL == retVal )\n                abort_message(\"cannot allocate __cxa_eh_globals\");\n            if ( 0 != pthread_setspecific ( key_, retVal ) )\n               abort_message(\"pthread_setspecific failure in __cxa_get_globals()\");\n           }\n        return retVal;\n        }\n\n    // Note that this implementation will reliably return NULL if not\n    // preceded by a call to __cxa_get_globals().  This is an extension\n    // to the Itanium ABI and is taken advantage of in several places in\n    // libc++abi.\n    __cxa_eh_globals * __cxa_get_globals_fast () {\n    //  First time through, create the key.\n        if (0 != pthread_once(&flag_, construct_))\n            abort_message(\"pthread_once failure in __cxa_get_globals_fast()\");\n//        static int init = construct_();\n        return static_cast<__cxa_eh_globals*>(::pthread_getspecific(key_));\n        }\n    \n}\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_guard.cpp",
    "content": "//===---------------------------- cxa_guard.cpp ---------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"abort_message.h\"\n#include \"config.h\"\n\n#if !LIBCXXABI_HAS_NO_THREADS\n#  include <pthread.h>\n#endif\n#include <stdint.h>\n\n/*\n    This implementation must be careful to not call code external to this file\n    which will turn around and try to call __cxa_guard_acquire reentrantly.\n    For this reason, the headers of this file are as restricted as possible.\n    Previous implementations of this code for __APPLE__ have used\n    pthread_mutex_lock and the abort_message utility without problem.  This\n    implementation also uses pthread_cond_wait which has tested to not be a\n    problem.\n*/\n\nnamespace __cxxabiv1\n{\n\nnamespace\n{\n\n#ifdef __arm__\n\n// A 32-bit, 4-byte-aligned static data value. The least significant 2 bits must\n// be statically initialized to 0.\ntypedef uint32_t guard_type;\n\n// Test the lowest bit.\ninline bool is_initialized(guard_type* guard_object) {\n    return (*guard_object) & 1;\n}\n\ninline void set_initialized(guard_type* guard_object) {\n    *guard_object |= 1;\n}\n\n#else\n\ntypedef uint64_t guard_type;\n\nbool is_initialized(guard_type* guard_object) {\n    char* initialized = (char*)guard_object;\n    return *initialized;\n}\n\nvoid set_initialized(guard_type* guard_object) {\n    char* initialized = (char*)guard_object;\n    *initialized = 1;\n}\n\n#endif\n\n#if !LIBCXXABI_HAS_NO_THREADS\npthread_mutex_t guard_mut = PTHREAD_MUTEX_INITIALIZER;\npthread_cond_t  guard_cv  = PTHREAD_COND_INITIALIZER;\n#endif\n\n#if defined(__APPLE__) && !defined(__arm__)\n\ntypedef uint32_t lock_type;\n\n#if __LITTLE_ENDIAN__\n\ninline\nlock_type\nget_lock(uint64_t x)\n{\n    return static_cast<lock_type>(x >> 32);\n}\n\ninline\nvoid\nset_lock(uint64_t& x, lock_type y)\n{\n    x = static_cast<uint64_t>(y) << 32;\n}\n\n#else  // __LITTLE_ENDIAN__\n\ninline\nlock_type\nget_lock(uint64_t x)\n{\n    return static_cast<lock_type>(x);\n}\n\ninline\nvoid\nset_lock(uint64_t& x, lock_type y)\n{\n    x = y;\n}\n\n#endif  // __LITTLE_ENDIAN__\n\n#else  // !__APPLE__ || __arm__\n\ntypedef bool lock_type;\n\ninline\nlock_type\nget_lock(uint64_t x)\n{\n    union\n    {\n        uint64_t guard;\n        uint8_t lock[2];\n    } f = {x};\n    return f.lock[1] != 0;\n}\n\ninline\nvoid\nset_lock(uint64_t& x, lock_type y)\n{\n    union\n    {\n        uint64_t guard;\n        uint8_t lock[2];\n    } f = {0};\n    f.lock[1] = y;\n    x = f.guard;\n}\n\ninline\nlock_type\nget_lock(uint32_t x)\n{\n    union\n    {\n        uint32_t guard;\n        uint8_t lock[2];\n    } f = {x};\n    return f.lock[1] != 0;\n}\n\ninline\nvoid\nset_lock(uint32_t& x, lock_type y)\n{\n    union\n    {\n        uint32_t guard;\n        uint8_t lock[2];\n    } f = {0};\n    f.lock[1] = y;\n    x = f.guard;\n}\n\n#endif  // __APPLE__\n\n}  // unnamed namespace\n\nextern \"C\"\n{\n\n#if LIBCXXABI_HAS_NO_THREADS\nint __cxa_guard_acquire(guard_type* guard_object)\n{\n    return !is_initialized(guard_object);\n}\n\nvoid __cxa_guard_release(guard_type* guard_object)\n{\n    *guard_object = 0;\n    set_initialized(guard_object);\n}\n\nvoid __cxa_guard_abort(guard_type* guard_object)\n{\n    *guard_object = 0;\n}\n\n#else // !LIBCXXABI_HAS_NO_THREADS\n\nint __cxa_guard_acquire(guard_type* guard_object)\n{\n    char* initialized = (char*)guard_object;\n    if (pthread_mutex_lock(&guard_mut))\n        abort_message(\"__cxa_guard_acquire failed to acquire mutex\");\n    int result = *initialized == 0;\n    if (result)\n    {\n#if defined(__APPLE__) && !defined(__arm__)\n        const lock_type id = pthread_mach_thread_np(pthread_self());\n        lock_type lock = get_lock(*guard_object);\n        if (lock)\n        {\n            // if this thread set lock for this same guard_object, abort\n            if (lock == id)\n                abort_message(\"__cxa_guard_acquire detected deadlock\");\n            do\n            {\n                if (pthread_cond_wait(&guard_cv, &guard_mut))\n                    abort_message(\"__cxa_guard_acquire condition variable wait failed\");\n                lock = get_lock(*guard_object);\n            } while (lock);\n            result = !is_initialized(guard_object);\n            if (result)\n                set_lock(*guard_object, id);\n        }\n        else\n            set_lock(*guard_object, id);\n#else  // !__APPLE__ || __arm__\n        while (get_lock(*guard_object))\n            if (pthread_cond_wait(&guard_cv, &guard_mut))\n                abort_message(\"__cxa_guard_acquire condition variable wait failed\");\n        result = *initialized == 0;\n        if (result)\n            set_lock(*guard_object, true);\n#endif  // !__APPLE__ || __arm__\n    }\n    if (pthread_mutex_unlock(&guard_mut))\n        abort_message(\"__cxa_guard_acquire failed to release mutex\");\n    return result;\n}\n\nvoid __cxa_guard_release(guard_type* guard_object)\n{\n    if (pthread_mutex_lock(&guard_mut))\n        abort_message(\"__cxa_guard_release failed to acquire mutex\");\n    *guard_object = 0;\n    set_initialized(guard_object);\n    if (pthread_mutex_unlock(&guard_mut))\n        abort_message(\"__cxa_guard_release failed to release mutex\");\n    if (pthread_cond_broadcast(&guard_cv))\n        abort_message(\"__cxa_guard_release failed to broadcast condition variable\");\n}\n\nvoid __cxa_guard_abort(guard_type* guard_object)\n{\n    if (pthread_mutex_lock(&guard_mut))\n        abort_message(\"__cxa_guard_abort failed to acquire mutex\");\n    *guard_object = 0;\n    if (pthread_mutex_unlock(&guard_mut))\n        abort_message(\"__cxa_guard_abort failed to release mutex\");\n    if (pthread_cond_broadcast(&guard_cv))\n        abort_message(\"__cxa_guard_abort failed to broadcast condition variable\");\n}\n\n#endif // !LIBCXXABI_HAS_NO_THREADS\n\n}  // extern \"C\"\n\n}  // __cxxabiv1\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_handlers.cpp",
    "content": "//===------------------------- cxa_handlers.cpp ---------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//\n// This file implements the functionality associated with the terminate_handler,\n//   unexpected_handler, and new_handler.\n//===----------------------------------------------------------------------===//\n\n#include <stdexcept>\n#include <new>\n#include <exception>\n#include \"abort_message.h\"\n#include \"config.h\"\n#include \"cxxabi.h\"\n#include \"cxa_handlers.hpp\"\n#include \"cxa_exception.hpp\"\n#include \"private_typeinfo.h\"\n\nnamespace std\n{\n\nunexpected_handler\nget_unexpected() _NOEXCEPT\n{\n    return __sync_fetch_and_add(&__cxa_unexpected_handler, (unexpected_handler)0);\n//  The above is safe but overkill on x86\n//  Using of C++11 atomics this should be rewritten\n//  return __cxa_unexpected_handler.load(memory_order_acq);\n}\n\n__attribute__((visibility(\"hidden\"), noreturn))\nvoid\n__unexpected(unexpected_handler func)\n{\n    func();\n    // unexpected handler should not return\n    abort_message(\"unexpected_handler unexpectedly returned\");\n}\n\n__attribute__((noreturn))\nvoid\nunexpected()\n{\n    __unexpected(get_unexpected());\n}\n\nterminate_handler\nget_terminate() _NOEXCEPT\n{\n    return __sync_fetch_and_add(&__cxa_terminate_handler, (terminate_handler)0);\n//  The above is safe but overkill on x86\n//  Using of C++11 atomics this should be rewritten\n//  return __cxa_terminate_handler.load(memory_order_acq);\n}\n\n__attribute__((visibility(\"hidden\"), noreturn))\nvoid\n__terminate(terminate_handler func) _NOEXCEPT\n{\n#if __has_feature(cxx_exceptions)\n    try\n    {\n#endif  // __has_feature(cxx_exceptions)\n        func();\n        // handler should not return\n        abort_message(\"terminate_handler unexpectedly returned\");\n#if __has_feature(cxx_exceptions)\n    }\n    catch (...)\n    {\n        // handler should not throw exception\n        abort_message(\"terminate_handler unexpectedly threw an exception\");\n    }\n#endif  // #if __has_feature(cxx_exceptions)\n}\n\n__attribute__((noreturn))\nvoid\nterminate() _NOEXCEPT\n{\n    // If there might be an uncaught exception\n    using namespace __cxxabiv1;\n    __cxa_eh_globals* globals = __cxa_get_globals_fast();\n    if (globals)\n    {\n        __cxa_exception* exception_header = globals->caughtExceptions;\n        if (exception_header)\n        {\n            _Unwind_Exception* unwind_exception =\n                reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;\n            bool native_exception =\n                (unwind_exception->exception_class & get_vendor_and_language) ==\n                               (kOurExceptionClass & get_vendor_and_language);\n            if (native_exception)\n                __terminate(exception_header->terminateHandler);\n        }\n    }\n    __terminate(get_terminate());\n}\n\nextern \"C\" new_handler __cxa_new_handler = 0;\n// In the future these will become:\n// std::atomic<std::new_handler>  __cxa_new_handler(0);\n\nnew_handler\nset_new_handler(new_handler handler) _NOEXCEPT\n{\n    return __atomic_exchange_n(&__cxa_new_handler, handler, __ATOMIC_ACQ_REL);\n//  Using of C++11 atomics this should be rewritten\n//  return __cxa_new_handler.exchange(handler, memory_order_acq_rel);\n}\n\nnew_handler\nget_new_handler() _NOEXCEPT\n{\n    return __sync_fetch_and_add(&__cxa_new_handler, (new_handler)0);\n//  The above is safe but overkill on x86\n//  Using of C++11 atomics this should be rewritten\n//  return __cxa_new_handler.load(memory_order_acq);\n}\n\n}  // std\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_handlers.hpp",
    "content": "//===------------------------- cxa_handlers.cpp ---------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//\n// This file implements the functionality associated with the terminate_handler,\n//   unexpected_handler, and new_handler.\n//===----------------------------------------------------------------------===//\n\n#ifndef _CXA_HANDLERS_H\n#define _CXA_HANDLERS_H\n\n#include <exception>\n\nnamespace std\n{\n\n__attribute__((visibility(\"hidden\"), noreturn))\nvoid\n__unexpected(unexpected_handler func);\n\n__attribute__((visibility(\"hidden\"), noreturn))\nvoid\n__terminate(terminate_handler func) _NOEXCEPT;\n\n}  // std\n\nextern \"C\"\n{\n\nextern void (*__cxa_terminate_handler)();\nextern void (*__cxa_unexpected_handler)();\nextern void (*__cxa_new_handler)();\n\n/*\n\n    At some point in the future these three symbols will become\n    C++11 atomic variables:\n\n    extern std::atomic<std::terminate_handler>  __cxa_terminate_handler;\n    extern std::atomic<std::unexpected_handler> __cxa_unexpected_handler;\n    extern std::atomic<std::new_handler>        __cxa_new_handler;\n\n    This change will not impact their ABI.  But it will allow for a\n    portable performance optimization.\n\n*/\n\n} // extern \"C\"\n\n#endif  // _CXA_HANDLERS_H\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_new_delete.cpp",
    "content": "//===------------------------ cxa_new_delete.cpp --------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//\n// This file implements the new and delete operators.\n//===----------------------------------------------------------------------===//\n\n#define _LIBCPP_BUILDING_NEW\n\n#include <new>\n#include <cstdlib>\n\n/*\n[new.delete.single]\n\n* Executes a loop: Within the loop, the function first attempts to allocate\n  the requested storage. Whether the attempt involves a call to the Standard C\n  library function malloc is unspecified.\n\n* Returns a pointer to the allocated storage if the attempt is successful.\n  Otherwise, if the current new_handler (18.6.2.5) is a null pointer value,\n  throws bad_alloc.\n\n* Otherwise, the function calls the current new_handler function (18.6.2.3).\n  If the called function returns, the loop repeats.\n\n* The loop terminates when an attempt to allocate the requested storage is\n  successful or when a called new_handler function does not return.\n*/\n__attribute__((__weak__, __visibility__(\"default\")))\nvoid *\noperator new(std::size_t size)\n#if !__has_feature(cxx_noexcept)\n    throw(std::bad_alloc)\n#endif\n{\n    if (size == 0)\n        size = 1;\n    void* p;\n    while ((p = std::malloc(size)) == 0)\n    {\n        std::new_handler nh = std::get_new_handler();\n        if (nh)\n            nh();\n        else\n            throw std::bad_alloc();\n    }\n    return p;\n}\n\n/*\nNote:  The relationships among these operators is both carefully considered\nand standard in C++11.  Please do not change them without fully understanding\nthe consequences of doing so.  Reference:\nhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2158.html\n*/\n/*\n[new.delete.single]\n\nCalls operator new(size). If the call returns normally, returns the result of\nthat call. Otherwise, returns a null pointer.\n*/\n__attribute__((__weak__, __visibility__(\"default\")))\nvoid*\noperator new(size_t size, const std::nothrow_t&)\n#if __has_feature(cxx_noexcept)\n    noexcept\n#else\n    throw()\n#endif\n{\n    void* p = 0;\n    try\n    {\n        p = ::operator new(size);\n    }\n    catch (...)\n    {\n    }\n    return p;\n}\n\n/*\n[new.delete.array]\n\nReturns operator new(size).\n*/\n__attribute__((__weak__, __visibility__(\"default\")))\nvoid*\noperator new[](size_t size)\n#if !__has_feature(cxx_noexcept)\n    throw(std::bad_alloc)\n#endif\n{\n    return ::operator new(size);\n}\n\n/*\n[new.delete.array]\n\nCalls operator new[](size). If the call returns normally, returns the result\nof that call. Otherwise, returns a null pointer.\n*/\n__attribute__((__weak__, __visibility__(\"default\")))\nvoid*\noperator new[](size_t size, const std::nothrow_t&)\n#if __has_feature(cxx_noexcept)\n    noexcept\n#else\n    throw()\n#endif\n{\n    void* p = 0;\n    try\n    {\n        p = ::operator new[](size);\n    }\n    catch (...)\n    {\n    }\n    return p;\n}\n\n/*\n[new.delete.single]\n\nIf ptr is null, does nothing. Otherwise, reclaims the storage allocated by the\nearlier call to operator new.\n*/\n__attribute__((__weak__, __visibility__(\"default\")))\nvoid\noperator delete(void* ptr)\n#if __has_feature(cxx_noexcept)\n    noexcept\n#else\n    throw()\n#endif\n{\n    if (ptr)\n        std::free(ptr);\n}\n\n/*\n[new.delete.single]\n\ncalls operator delete(ptr)\n*/\n__attribute__((__weak__, __visibility__(\"default\")))\nvoid\noperator delete(void* ptr, const std::nothrow_t&)\n#if __has_feature(cxx_noexcept)\n    noexcept\n#else\n    throw()\n#endif\n{\n    ::operator delete(ptr);\n}\n\n/*\n[new.delete.array]\n\nCalls operator delete(ptr)\n*/\n__attribute__((__weak__, __visibility__(\"default\")))\nvoid\noperator delete[] (void* ptr)\n#if __has_feature(cxx_noexcept)\n    noexcept\n#else\n    throw()\n#endif\n{\n    ::operator delete(ptr);\n}\n\n/*\n[new.delete.array]\n\ncalls operator delete[](ptr)\n*/\n__attribute__((__weak__, __visibility__(\"default\")))\nvoid\noperator delete[] (void* ptr, const std::nothrow_t&)\n#if __has_feature(cxx_noexcept)\n    noexcept\n#else\n    throw()\n#endif\n{\n    ::operator delete[](ptr);\n}\n\nnamespace std\n{\n\n//  bad_alloc\n\nbad_alloc::bad_alloc() _NOEXCEPT\n{\n}\n\nbad_alloc::~bad_alloc() _NOEXCEPT\n{\n}\n\nconst char*\nbad_alloc::what() const _NOEXCEPT\n{\n    return \"std::bad_alloc\";\n}\n\n// bad_array_new_length\n\nbad_array_new_length::bad_array_new_length() _NOEXCEPT\n{\n}\n\nbad_array_new_length::~bad_array_new_length() _NOEXCEPT\n{\n}\n\nconst char*\nbad_array_new_length::what() const _NOEXCEPT\n{\n    return \"bad_array_new_length\";\n}\n\n// bad_array_length\n\n#ifndef _LIBCPP_BAD_ARRAY_LENGTH_DEFINED\n\nclass _LIBCPP_EXCEPTION_ABI bad_array_length\n    : public bad_alloc\n{\npublic:\n    bad_array_length() _NOEXCEPT;\n    virtual ~bad_array_length() _NOEXCEPT;\n    virtual const char* what() const _NOEXCEPT;\n};\n\n#endif  // _LIBCPP_BAD_ARRAY_LENGTH_DEFINED\n\nbad_array_length::bad_array_length() _NOEXCEPT\n{\n}\n\nbad_array_length::~bad_array_length() _NOEXCEPT\n{\n}\n\nconst char*\nbad_array_length::what() const _NOEXCEPT\n{\n    return \"bad_array_length\";\n}\n\n}  // std\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_personality.cpp",
    "content": "//===------------------------- cxa_exception.cpp --------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//  \n//  This file implements the \"Exception Handling APIs\"\n//  http://mentorembedded.github.io/cxx-abi/abi-eh.html\n//  http://www.intel.com/design/itanium/downloads/245358.htm\n//  \n//===----------------------------------------------------------------------===//\n\n#include <assert.h>\n#include <stdlib.h>\n#include <string.h>\n#include <typeinfo>\n\n#include \"config.h\"\n#include \"cxa_exception.hpp\"\n#include \"cxa_handlers.hpp\"\n#include \"private_typeinfo.h\"\n#include \"unwind.h\"\n\n/*\n    Exception Header Layout:\n\n+---------------------------+-----------------------------+---------------+\n| __cxa_exception           | _Unwind_Exception CLNGC++\\0 | thrown object |\n+---------------------------+-----------------------------+---------------+\n                                                          ^\n                                                          |\n  +-------------------------------------------------------+\n  |\n+---------------------------+-----------------------------+\n| __cxa_dependent_exception | _Unwind_Exception CLNGC++\\1 |\n+---------------------------+-----------------------------+\n\n    Exception Handling Table Layout:\n\n+-----------------+--------+\n| lpStartEncoding | (char) |\n+---------+-------+--------+---------------+-----------------------+\n| lpStart | (encoded with lpStartEncoding) | defaults to funcStart |\n+---------+-----+--------+-----------------+---------------+-------+\n| ttypeEncoding | (char) | Encoding of the type_info table |\n+---------------+-+------+----+----------------------------+----------------+\n| classInfoOffset | (ULEB128) | Offset to type_info table, defaults to null |\n+-----------------++--------+-+----------------------------+----------------+\n| callSiteEncoding | (char) | Encoding for Call Site Table |\n+------------------+--+-----+-----+------------------------+--------------------------+\n| callSiteTableLength | (ULEB128) | Call Site Table length, used to find Action table |\n+---------------------+-----------+---------------------------------------------------+\n#ifndef __USING_SJLJ_EXCEPTIONS__\n+---------------------+-----------+------------------------------------------------+\n| Beginning of Call Site Table            The current ip lies within the           |\n| ...                                     (start, length) range of one of these    |\n|                                         call sites. There may be action needed.  |\n| +-------------+---------------------------------+------------------------------+ |\n| | start       | (encoded with callSiteEncoding) | offset relative to funcStart | |\n| | length      | (encoded with callSiteEncoding) | length of code fragment      | |\n| | landingPad  | (encoded with callSiteEncoding) | offset relative to lpStart   | |\n| | actionEntry | (ULEB128)                       | Action Table Index 1-based   | |\n| |             |                                 | actionEntry == 0 -> cleanup  | |\n| +-------------+---------------------------------+------------------------------+ |\n| ...                                                                              |\n+----------------------------------------------------------------------------------+\n#else  // __USING_SJLJ_EXCEPTIONS__\n+---------------------+-----------+------------------------------------------------+\n| Beginning of Call Site Table            The current ip is a 1-based index into   |\n| ...                                     this table.  Or it is -1 meaning no      |\n|                                         action is needed.  Or it is 0 meaning    |\n|                                         terminate.                               |\n| +-------------+---------------------------------+------------------------------+ |\n| | landingPad  | (ULEB128)                       | offset relative to lpStart   | |\n| | actionEntry | (ULEB128)                       | Action Table Index 1-based   | |\n| |             |                                 | actionEntry == 0 -> cleanup  | |\n| +-------------+---------------------------------+------------------------------+ |\n| ...                                                                              |\n+----------------------------------------------------------------------------------+\n#endif  // __USING_SJLJ_EXCEPTIONS__\n+---------------------------------------------------------------------+\n| Beginning of Action Table       ttypeIndex == 0 : cleanup           |\n| ...                             ttypeIndex  > 0 : catch             |\n|                                 ttypeIndex  < 0 : exception spec    |\n| +--------------+-----------+--------------------------------------+ |\n| | ttypeIndex   | (SLEB128) | Index into type_info Table (1-based) | |\n| | actionOffset | (SLEB128) | Offset into next Action Table entry  | |\n| +--------------+-----------+--------------------------------------+ |\n| ...                                                                 |\n+---------------------------------------------------------------------+-----------------+\n| type_info Table, but classInfoOffset does *not* point here!                           |\n| +----------------+------------------------------------------------+-----------------+ |\n| | Nth type_info* | Encoded with ttypeEncoding, 0 means catch(...) | ttypeIndex == N | |\n| +----------------+------------------------------------------------+-----------------+ |\n| ...                                                                                   |\n| +----------------+------------------------------------------------+-----------------+ |\n| | 1st type_info* | Encoded with ttypeEncoding, 0 means catch(...) | ttypeIndex == 1 | |\n| +----------------+------------------------------------------------+-----------------+ |\n| +---------------------------------------+-----------+------------------------------+  |\n| | 1st ttypeIndex for 1st exception spec | (ULEB128) | classInfoOffset points here! |  |\n| | ...                                   | (ULEB128) |                              |  |\n| | Mth ttypeIndex for 1st exception spec | (ULEB128) |                              |  |\n| | 0                                     | (ULEB128) |                              |  |\n| +---------------------------------------+------------------------------------------+  |\n| ...                                                                                   |\n| +---------------------------------------+------------------------------------------+  |\n| | 0                                     | (ULEB128) | throw()                      |  |\n| +---------------------------------------+------------------------------------------+  |\n| ...                                                                                   |\n| +---------------------------------------+------------------------------------------+  |\n| | 1st ttypeIndex for Nth exception spec | (ULEB128) |                              |  |\n| | ...                                   | (ULEB128) |                              |  |\n| | Mth ttypeIndex for Nth exception spec | (ULEB128) |                              |  |\n| | 0                                     | (ULEB128) |                              |  |\n| +---------------------------------------+------------------------------------------+  |\n+---------------------------------------------------------------------------------------+\n\nNotes:\n\n*  ttypeIndex in the Action Table, and in the exception spec table, is an index,\n     not a byte count, if positive.  It is a negative index offset of\n     classInfoOffset and the sizeof entry depends on ttypeEncoding.\n   But if ttypeIndex is negative, it is a positive 1-based byte offset into the\n     type_info Table.\n   And if ttypeIndex is zero, it refers to a catch (...).\n\n*  landingPad can be 0, this implies there is nothing to be done.\n\n*  landingPad != 0 and actionEntry == 0 implies a cleanup needs to be done\n     @landingPad.\n\n*  A cleanup can also be found under landingPad != 0 and actionEntry != 0 in\n     the Action Table with ttypeIndex == 0.\n*/\n\nnamespace __cxxabiv1\n{\n\nnamespace\n{\n\ntemplate <class AsType>\nuintptr_t readPointerHelper(const uint8_t*& p) {\n    AsType value;\n    memcpy(&value, p, sizeof(AsType));\n    p += sizeof(AsType);\n    return static_cast<uintptr_t>(value);\n}\n\n} // end namespace\n\nextern \"C\"\n{\n\n// private API\n\n// Heavily borrowed from llvm/examples/ExceptionDemo/ExceptionDemo.cpp\n\n// DWARF Constants\nenum\n{\n    DW_EH_PE_absptr   = 0x00,\n    DW_EH_PE_uleb128  = 0x01,\n    DW_EH_PE_udata2   = 0x02,\n    DW_EH_PE_udata4   = 0x03,\n    DW_EH_PE_udata8   = 0x04,\n    DW_EH_PE_sleb128  = 0x09,\n    DW_EH_PE_sdata2   = 0x0A,\n    DW_EH_PE_sdata4   = 0x0B,\n    DW_EH_PE_sdata8   = 0x0C,\n    DW_EH_PE_pcrel    = 0x10,\n    DW_EH_PE_textrel  = 0x20,\n    DW_EH_PE_datarel  = 0x30,\n    DW_EH_PE_funcrel  = 0x40,\n    DW_EH_PE_aligned  = 0x50,\n    DW_EH_PE_indirect = 0x80,\n    DW_EH_PE_omit     = 0xFF\n};\n\n/// Read a uleb128 encoded value and advance pointer \n/// See Variable Length Data Appendix C in: \n/// @link http://dwarfstd.org/Dwarf4.pdf @unlink\n/// @param data reference variable holding memory pointer to decode from\n/// @returns decoded value\nstatic\nuintptr_t\nreadULEB128(const uint8_t** data)\n{\n    uintptr_t result = 0;\n    uintptr_t shift = 0;\n    unsigned char byte;\n    const uint8_t *p = *data;\n    do\n    {\n        byte = *p++;\n        result |= static_cast<uintptr_t>(byte & 0x7F) << shift;\n        shift += 7;\n    } while (byte & 0x80);\n    *data = p;\n    return result;\n}\n\n/// Read a sleb128 encoded value and advance pointer \n/// See Variable Length Data Appendix C in: \n/// @link http://dwarfstd.org/Dwarf4.pdf @unlink\n/// @param data reference variable holding memory pointer to decode from\n/// @returns decoded value\nstatic\nintptr_t\nreadSLEB128(const uint8_t** data)\n{\n    uintptr_t result = 0;\n    uintptr_t shift = 0;\n    unsigned char byte;\n    const uint8_t *p = *data;\n    do\n    {\n        byte = *p++;\n        result |= static_cast<uintptr_t>(byte & 0x7F) << shift;\n        shift += 7;\n    } while (byte & 0x80);\n    *data = p;\n    if ((byte & 0x40) && (shift < (sizeof(result) << 3)))\n        result |= static_cast<uintptr_t>(~0) << shift;\n    return static_cast<intptr_t>(result);\n}\n\n/// Read a pointer encoded value and advance pointer \n/// See Variable Length Data in: \n/// @link http://dwarfstd.org/Dwarf3.pdf @unlink\n/// @param data reference variable holding memory pointer to decode from\n/// @param encoding dwarf encoding type\n/// @returns decoded value\nstatic\nuintptr_t\nreadEncodedPointer(const uint8_t** data, uint8_t encoding)\n{\n    uintptr_t result = 0;\n    if (encoding == DW_EH_PE_omit) \n        return result;\n    const uint8_t* p = *data;\n    // first get value \n    switch (encoding & 0x0F)\n    {\n    case DW_EH_PE_absptr:\n        result = readPointerHelper<uintptr_t>(p);\n        break;\n    case DW_EH_PE_uleb128:\n        result = readULEB128(&p);\n        break;\n    case DW_EH_PE_sleb128:\n        result = static_cast<uintptr_t>(readSLEB128(&p));\n        break;\n    case DW_EH_PE_udata2:\n        result = readPointerHelper<uint16_t>(p);\n        break;\n    case DW_EH_PE_udata4:\n        result = readPointerHelper<uint32_t>(p);\n        break;\n    case DW_EH_PE_udata8:\n        result = readPointerHelper<uint64_t>(p);\n        break;\n    case DW_EH_PE_sdata2:\n        result = readPointerHelper<int16_t>(p);\n        break;\n    case DW_EH_PE_sdata4:\n        result = readPointerHelper<int32_t>(p);\n        break;\n    case DW_EH_PE_sdata8:\n        result = readPointerHelper<int64_t>(p);\n        break;\n    default:\n        // not supported \n        abort();\n        break;\n    }\n    // then add relative offset \n    switch (encoding & 0x70)\n    {\n    case DW_EH_PE_absptr:\n        // do nothing \n        break;\n    case DW_EH_PE_pcrel:\n        if (result)\n            result += (uintptr_t)(*data);\n        break;\n    case DW_EH_PE_textrel:\n    case DW_EH_PE_datarel:\n    case DW_EH_PE_funcrel:\n    case DW_EH_PE_aligned:\n    default:\n        // not supported \n        abort();\n        break;\n    }\n    // then apply indirection \n    if (result && (encoding & DW_EH_PE_indirect))\n        result = *((uintptr_t*)result);\n    *data = p;\n    return result;\n}\n\nstatic\nvoid\ncall_terminate(bool native_exception, _Unwind_Exception* unwind_exception)\n{\n    __cxa_begin_catch(unwind_exception);\n    if (native_exception)\n    {\n        // Use the stored terminate_handler if possible\n        __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;\n        std::__terminate(exception_header->terminateHandler);\n    }\n    std::terminate();\n}\n\n#if LIBCXXABI_ARM_EHABI\nstatic const void* read_target2_value(const void* ptr)\n{\n    uintptr_t offset = *reinterpret_cast<const uintptr_t*>(ptr);\n    if (!offset)\n        return 0;\n    // \"ARM EABI provides a TARGET2 relocation to describe these typeinfo\n    // pointers. The reason being it allows their precise semantics to be\n    // deferred to the linker. For bare-metal they turn into absolute\n    // relocations. For linux they turn into GOT-REL relocations.\"\n    // https://gcc.gnu.org/ml/gcc-patches/2009-08/msg00264.html\n#if LIBCXXABI_BAREMETAL\n    return reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(ptr) +\n                                         offset);\n#else\n    return *reinterpret_cast<const void **>(reinterpret_cast<uintptr_t>(ptr) +\n                                            offset);\n#endif\n}\n\nstatic const __shim_type_info*\nget_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo,\n                   uint8_t ttypeEncoding, bool native_exception,\n                   _Unwind_Exception* unwind_exception)\n{\n    if (classInfo == 0)\n    {\n        // this should not happen.  Indicates corrupted eh_table.\n        call_terminate(native_exception, unwind_exception);\n    }\n\n    assert(ttypeEncoding == DW_EH_PE_absptr && \"Unexpected TTypeEncoding\");\n    (void)ttypeEncoding;\n\n    const uint8_t* ttypePtr = classInfo - ttypeIndex * sizeof(uintptr_t);\n    return reinterpret_cast<const __shim_type_info *>(\n        read_target2_value(ttypePtr));\n}\n#else // !LIBCXXABI_ARM_EHABI\nstatic\nconst __shim_type_info*\nget_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo,\n                   uint8_t ttypeEncoding, bool native_exception,\n                   _Unwind_Exception* unwind_exception)\n{\n    if (classInfo == 0)\n    {\n        // this should not happen.  Indicates corrupted eh_table.\n        call_terminate(native_exception, unwind_exception);\n    }\n    switch (ttypeEncoding & 0x0F)\n    {\n    case DW_EH_PE_absptr:\n        ttypeIndex *= sizeof(void*);\n        break;\n    case DW_EH_PE_udata2:\n    case DW_EH_PE_sdata2:\n        ttypeIndex *= 2;\n        break;\n    case DW_EH_PE_udata4:\n    case DW_EH_PE_sdata4:\n        ttypeIndex *= 4;\n        break;\n    case DW_EH_PE_udata8:\n    case DW_EH_PE_sdata8:\n        ttypeIndex *= 8;\n        break;\n    default:\n        // this should not happen.   Indicates corrupted eh_table.\n        call_terminate(native_exception, unwind_exception);\n    }\n    classInfo -= ttypeIndex;\n    return (const __shim_type_info*)readEncodedPointer(&classInfo, ttypeEncoding);\n}\n#endif // !LIBCXXABI_ARM_EHABI\n\n/*\n    This is checking a thrown exception type, excpType, against a possibly empty\n    list of catchType's which make up an exception spec.\n\n    An exception spec acts like a catch handler, but in reverse.  This \"catch\n    handler\" will catch an excpType if and only if none of the catchType's in\n    the list will catch a excpType.  If any catchType in the list can catch an\n    excpType, then this exception spec does not catch the excpType.\n*/\n#if LIBCXXABI_ARM_EHABI\nstatic\nbool\nexception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo,\n                         uint8_t ttypeEncoding, const __shim_type_info* excpType,\n                         void* adjustedPtr, _Unwind_Exception* unwind_exception)\n{\n    if (classInfo == 0)\n    {\n        // this should not happen.   Indicates corrupted eh_table.\n        call_terminate(false, unwind_exception);\n    }\n\n    assert(ttypeEncoding == DW_EH_PE_absptr && \"Unexpected TTypeEncoding\");\n    (void)ttypeEncoding;\n\n    // specIndex is negative of 1-based byte offset into classInfo;\n    specIndex = -specIndex;\n    --specIndex;\n    const void** temp = reinterpret_cast<const void**>(\n        reinterpret_cast<uintptr_t>(classInfo) +\n        static_cast<uintptr_t>(specIndex) * sizeof(uintptr_t));\n    // If any type in the spec list can catch excpType, return false, else return true\n    //    adjustments to adjustedPtr are ignored.\n    while (true)\n    {\n        // ARM EHABI exception specification table (filter table) consists of\n        // several pointers which will directly point to the type info object\n        // (instead of ttypeIndex).  The table will be terminated with 0.\n        const void** ttypePtr = temp++;\n        if (*ttypePtr == 0)\n            break;\n        // We can get the __shim_type_info simply by performing a\n        // R_ARM_TARGET2 relocation, and cast the result to __shim_type_info.\n        const __shim_type_info* catchType =\n            static_cast<const __shim_type_info*>(read_target2_value(ttypePtr));\n        void* tempPtr = adjustedPtr;\n        if (catchType->can_catch(excpType, tempPtr))\n            return false;\n    }\n    return true;\n}\n#else\nstatic\nbool\nexception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo,\n                         uint8_t ttypeEncoding, const __shim_type_info* excpType,\n                         void* adjustedPtr, _Unwind_Exception* unwind_exception)\n{\n    if (classInfo == 0)\n    {\n        // this should not happen.   Indicates corrupted eh_table.\n        call_terminate(false, unwind_exception);\n    }\n    // specIndex is negative of 1-based byte offset into classInfo;\n    specIndex = -specIndex;\n    --specIndex;\n    const uint8_t* temp = classInfo + specIndex;\n    // If any type in the spec list can catch excpType, return false, else return true\n    //    adjustments to adjustedPtr are ignored.\n    while (true)\n    {\n        uint64_t ttypeIndex = readULEB128(&temp);\n        if (ttypeIndex == 0)\n            break;\n        const __shim_type_info* catchType = get_shim_type_info(ttypeIndex,\n                                                               classInfo,\n                                                               ttypeEncoding,\n                                                               true,\n                                                               unwind_exception);\n        void* tempPtr = adjustedPtr;\n        if (catchType->can_catch(excpType, tempPtr))\n            return false;\n    }\n    return true;\n}\n#endif\n\nstatic\nvoid*\nget_thrown_object_ptr(_Unwind_Exception* unwind_exception)\n{\n    // Even for foreign exceptions, the exception object is *probably* at unwind_exception + 1\n    //    Regardless, this library is prohibited from touching a foreign exception\n    void* adjustedPtr = unwind_exception + 1;\n    if (unwind_exception->exception_class == kOurDependentExceptionClass)\n        adjustedPtr = ((__cxa_dependent_exception*)adjustedPtr - 1)->primaryException;\n    return adjustedPtr;\n}\n\nnamespace\n{\n\nstruct scan_results\n{\n    int64_t        ttypeIndex;   // > 0 catch handler, < 0 exception spec handler, == 0 a cleanup\n    const uint8_t* actionRecord;         // Currently unused.  Retained to ease future maintenance.\n    const uint8_t* languageSpecificData;  // Needed only for __cxa_call_unexpected\n    uintptr_t      landingPad;   // null -> nothing found, else something found\n    void*          adjustedPtr;  // Used in cxa_exception.cpp\n    _Unwind_Reason_Code reason;  // One of _URC_FATAL_PHASE1_ERROR,\n                                 //        _URC_FATAL_PHASE2_ERROR,\n                                 //        _URC_CONTINUE_UNWIND,\n                                 //        _URC_HANDLER_FOUND\n};\n\n}  // unnamed namespace\n\nstatic\nvoid\nset_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context,\n              const scan_results& results)\n{\n    _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),\n                                 reinterpret_cast<uintptr_t>(unwind_exception));\n    _Unwind_SetGR(context, __builtin_eh_return_data_regno(1),\n                                    static_cast<uintptr_t>(results.ttypeIndex));\n    _Unwind_SetIP(context, results.landingPad);\n}\n\n/*\n    There are 3 types of scans needed:\n\n    1.  Scan for handler with native or foreign exception.  If handler found,\n        save state and return _URC_HANDLER_FOUND, else return _URC_CONTINUE_UNWIND.\n        May also report an error on invalid input.\n        May terminate for invalid exception table.\n        _UA_SEARCH_PHASE\n\n    2.  Scan for handler with foreign exception.  Must return _URC_HANDLER_FOUND,\n        or call terminate.\n        _UA_CLEANUP_PHASE && _UA_HANDLER_FRAME && !native_exception\n\n    3.  Scan for cleanups.  If a handler is found and this isn't forced unwind,\n        then terminate, otherwise ignore the handler and keep looking for cleanup.\n        If a cleanup is found, return _URC_HANDLER_FOUND, else return _URC_CONTINUE_UNWIND.\n        May also report an error on invalid input.\n        May terminate for invalid exception table.\n        _UA_CLEANUP_PHASE && !_UA_HANDLER_FRAME\n*/\n\nstatic void scan_eh_tab(scan_results &results, _Unwind_Action actions,\n                        bool native_exception,\n                        _Unwind_Exception *unwind_exception,\n                        _Unwind_Context *context) {\n    // Initialize results to found nothing but an error\n    results.ttypeIndex = 0;\n    results.actionRecord = 0;\n    results.languageSpecificData = 0;\n    results.landingPad = 0;\n    results.adjustedPtr = 0;\n    results.reason = _URC_FATAL_PHASE1_ERROR;\n    // Check for consistent actions\n    if (actions & _UA_SEARCH_PHASE)\n    {\n        // Do Phase 1\n        if (actions & (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME | _UA_FORCE_UNWIND))\n        {\n            // None of these flags should be set during Phase 1\n            //   Client error\n            results.reason = _URC_FATAL_PHASE1_ERROR;\n            return;\n        }\n    }\n    else if (actions & _UA_CLEANUP_PHASE)\n    {\n        if ((actions & _UA_HANDLER_FRAME) && (actions & _UA_FORCE_UNWIND))\n        {\n            // _UA_HANDLER_FRAME should only be set if phase 1 found a handler.\n            // If _UA_FORCE_UNWIND is set, phase 1 shouldn't have happened.\n            //    Client error\n            results.reason = _URC_FATAL_PHASE2_ERROR;\n            return;\n        }\n    }\n    else // Neither _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE is set\n    {\n        // One of these should be set.\n        //   Client error\n        results.reason = _URC_FATAL_PHASE1_ERROR;\n        return;\n    }\n    // Start scan by getting exception table address\n    const uint8_t *lsda = (const uint8_t *)_Unwind_GetLanguageSpecificData(context);\n    if (lsda == 0)\n    {\n        // There is no exception table\n        results.reason = _URC_CONTINUE_UNWIND;\n        return;\n    }\n    results.languageSpecificData = lsda;\n    // Get the current instruction pointer and offset it before next\n    // instruction in the current frame which threw the exception.\n    uintptr_t ip = _Unwind_GetIP(context) - 1;\n    // Get beginning current frame's code (as defined by the \n    // emitted dwarf code)\n    uintptr_t funcStart = _Unwind_GetRegionStart(context);\n#ifdef __USING_SJLJ_EXCEPTIONS__\n    if (ip == uintptr_t(-1))\n    {\n        // no action\n        results.reason = _URC_CONTINUE_UNWIND;\n        return;\n    }\n    else if (ip == 0)\n        call_terminate(native_exception, unwind_exception);\n    // ip is 1-based index into call site table\n#else  // !__USING_SJLJ_EXCEPTIONS__\n    uintptr_t ipOffset = ip - funcStart;\n#endif  // !defined(_USING_SLJL_EXCEPTIONS__)\n    const uint8_t* classInfo = NULL;\n    // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding\n    //       dwarf emission\n    // Parse LSDA header.\n    uint8_t lpStartEncoding = *lsda++;\n    const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);\n    if (lpStart == 0)\n        lpStart = (const uint8_t*)funcStart;\n    uint8_t ttypeEncoding = *lsda++;\n    if (ttypeEncoding != DW_EH_PE_omit)\n    {\n        // Calculate type info locations in emitted dwarf code which\n        // were flagged by type info arguments to llvm.eh.selector\n        // intrinsic\n        uintptr_t classInfoOffset = readULEB128(&lsda);\n        classInfo = lsda + classInfoOffset;\n    }\n    // Walk call-site table looking for range that \n    // includes current PC. \n    uint8_t callSiteEncoding = *lsda++;\n#ifdef __USING_SJLJ_EXCEPTIONS__\n    (void)callSiteEncoding;  // When using SjLj exceptions, callSiteEncoding is never used\n#endif\n    uint32_t callSiteTableLength = static_cast<uint32_t>(readULEB128(&lsda));\n    const uint8_t* callSiteTableStart = lsda;\n    const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength;\n    const uint8_t* actionTableStart = callSiteTableEnd;\n    const uint8_t* callSitePtr = callSiteTableStart;\n    while (callSitePtr < callSiteTableEnd)\n    {\n        // There is one entry per call site.\n#ifndef __USING_SJLJ_EXCEPTIONS__\n        // The call sites are non-overlapping in [start, start+length)\n        // The call sites are ordered in increasing value of start\n        uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding);\n        uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding);\n        uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);\n        uintptr_t actionEntry = readULEB128(&callSitePtr);\n        if ((start <= ipOffset) && (ipOffset < (start + length)))\n#else  // __USING_SJLJ_EXCEPTIONS__\n        // ip is 1-based index into this table\n        uintptr_t landingPad = readULEB128(&callSitePtr);\n        uintptr_t actionEntry = readULEB128(&callSitePtr);\n        if (--ip == 0)\n#endif  // __USING_SJLJ_EXCEPTIONS__\n        {\n            // Found the call site containing ip.\n#ifndef __USING_SJLJ_EXCEPTIONS__\n            if (landingPad == 0)\n            {\n                // No handler here\n                results.reason = _URC_CONTINUE_UNWIND;\n                return;\n            }\n            landingPad = (uintptr_t)lpStart + landingPad;\n#else  // __USING_SJLJ_EXCEPTIONS__\n            ++landingPad;\n#endif  // __USING_SJLJ_EXCEPTIONS__\n            if (actionEntry == 0)\n            {\n                // Found a cleanup\n                // If this is a type 1 or type 2 search, there are no handlers\n                // If this is a type 3 search, you want to install the cleanup.\n                if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME))\n                {\n                    results.ttypeIndex = 0;  // Redundant but clarifying\n                    results.landingPad = landingPad;\n                    results.reason = _URC_HANDLER_FOUND;\n                    return;\n                }\n                // No handler here\n                results.reason = _URC_CONTINUE_UNWIND;\n                return;\n            }\n            // Convert 1-based byte offset into\n            const uint8_t* action = actionTableStart + (actionEntry - 1);\n            // Scan action entries until you find a matching handler, cleanup, or the end of action list\n            while (true)\n            {\n                const uint8_t* actionRecord = action;\n                int64_t ttypeIndex = readSLEB128(&action);\n                if (ttypeIndex > 0)\n                {\n                    // Found a catch, does it actually catch?\n                    // First check for catch (...)\n                    const __shim_type_info* catchType =\n                        get_shim_type_info(static_cast<uint64_t>(ttypeIndex),\n                                           classInfo, ttypeEncoding,\n                                           native_exception, unwind_exception);\n                    if (catchType == 0)\n                    {\n                        // Found catch (...) catches everything, including foreign exceptions\n                        // If this is a type 1 search save state and return _URC_HANDLER_FOUND\n                        // If this is a type 2 search save state and return _URC_HANDLER_FOUND\n                        // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1!\n                        // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan\n                        if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME))\n                        {\n                            // Save state and return _URC_HANDLER_FOUND\n                            results.ttypeIndex = ttypeIndex;\n                            results.actionRecord = actionRecord;\n                            results.landingPad = landingPad;\n                            results.adjustedPtr = get_thrown_object_ptr(unwind_exception);\n                            results.reason = _URC_HANDLER_FOUND;\n                            return;\n                        }\n                        else if (!(actions & _UA_FORCE_UNWIND))\n                        {\n                            // It looks like the exception table has changed\n                            //    on us.  Likely stack corruption!\n                            call_terminate(native_exception, unwind_exception);\n                        }\n                    }\n                    // Else this is a catch (T) clause and will never\n                    //    catch a foreign exception\n                    else if (native_exception)\n                    {\n                        __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;\n                        void* adjustedPtr = get_thrown_object_ptr(unwind_exception);\n                        const __shim_type_info* excpType =\n                            static_cast<const __shim_type_info*>(exception_header->exceptionType);\n                        if (adjustedPtr == 0 || excpType == 0)\n                        {\n                            // Something very bad happened\n                            call_terminate(native_exception, unwind_exception);\n                        }\n                        if (catchType->can_catch(excpType, adjustedPtr))\n                        {\n                            // Found a matching handler\n                            // If this is a type 1 search save state and return _URC_HANDLER_FOUND\n                            // If this is a type 3 search and !_UA_FORCE_UNWIND, we should have found this in phase 1!\n                            // If this is a type 3 search and _UA_FORCE_UNWIND, ignore handler and continue scan\n                            if (actions & _UA_SEARCH_PHASE)\n                            {\n                                // Save state and return _URC_HANDLER_FOUND\n                                results.ttypeIndex = ttypeIndex;\n                                results.actionRecord = actionRecord;\n                                results.landingPad = landingPad;\n                                results.adjustedPtr = adjustedPtr;\n                                results.reason = _URC_HANDLER_FOUND;\n                                return;\n                            }\n                            else if (!(actions & _UA_FORCE_UNWIND))\n                            {\n                                // It looks like the exception table has changed\n                                //    on us.  Likely stack corruption!\n                                call_terminate(native_exception, unwind_exception);\n                            }\n                        }\n                    }\n                    // Scan next action ...\n                }\n                else if (ttypeIndex < 0)\n                {\n                    // Found an exception spec.  If this is a foreign exception,\n                    //   it is always caught.\n                    if (native_exception)\n                    {\n                        // Does the exception spec catch this native exception?\n                        __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;\n                        void* adjustedPtr = get_thrown_object_ptr(unwind_exception);\n                        const __shim_type_info* excpType =\n                            static_cast<const __shim_type_info*>(exception_header->exceptionType);\n                        if (adjustedPtr == 0 || excpType == 0)\n                        {\n                            // Something very bad happened\n                            call_terminate(native_exception, unwind_exception);\n                        }\n                        if (exception_spec_can_catch(ttypeIndex, classInfo,\n                                                     ttypeEncoding, excpType,\n                                                     adjustedPtr, unwind_exception))\n                        {\n                            // native exception caught by exception spec\n                            // If this is a type 1 search, save state and return _URC_HANDLER_FOUND\n                            // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1!\n                            // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan\n                            if (actions & _UA_SEARCH_PHASE)\n                            {\n                                // Save state and return _URC_HANDLER_FOUND\n                                results.ttypeIndex = ttypeIndex;\n                                results.actionRecord = actionRecord;\n                                results.landingPad = landingPad;\n                                results.adjustedPtr = adjustedPtr;\n                                results.reason = _URC_HANDLER_FOUND;\n                                return;\n                            }\n                            else if (!(actions & _UA_FORCE_UNWIND))\n                            {\n                                // It looks like the exception table has changed\n                                //    on us.  Likely stack corruption!\n                                call_terminate(native_exception, unwind_exception);\n                            }\n                        }\n                    }\n                    else\n                    {\n                        // foreign exception caught by exception spec\n                        // If this is a type 1 search, save state and return _URC_HANDLER_FOUND\n                        // If this is a type 2 search, save state and return _URC_HANDLER_FOUND\n                        // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1!\n                        // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan\n                        if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME))\n                        {\n                            // Save state and return _URC_HANDLER_FOUND\n                            results.ttypeIndex = ttypeIndex;\n                            results.actionRecord = actionRecord;\n                            results.landingPad = landingPad;\n                            results.adjustedPtr = get_thrown_object_ptr(unwind_exception);\n                            results.reason = _URC_HANDLER_FOUND;\n                            return;\n                        }\n                        else if (!(actions & _UA_FORCE_UNWIND))\n                        {\n                            // It looks like the exception table has changed\n                            //    on us.  Likely stack corruption!\n                            call_terminate(native_exception, unwind_exception);\n                        }\n                    }\n                    // Scan next action ...\n                }\n                else  // ttypeIndex == 0\n                {\n                    // Found a cleanup\n                    // If this is a type 1 search, ignore it and continue scan\n                    // If this is a type 2 search, ignore it and continue scan\n                    // If this is a type 3 search, save state and return _URC_HANDLER_FOUND\n                    if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME))\n                    {\n                        // Save state and return _URC_HANDLER_FOUND\n                        results.ttypeIndex = ttypeIndex;\n                        results.actionRecord = actionRecord;\n                        results.landingPad = landingPad;\n                        results.adjustedPtr = get_thrown_object_ptr(unwind_exception);\n                        results.reason = _URC_HANDLER_FOUND;\n                        return;\n                    }\n                }\n                const uint8_t* temp = action;\n                int64_t actionOffset = readSLEB128(&temp);\n                if (actionOffset == 0)\n                {\n                    // End of action list, no matching handler or cleanup found\n                    results.reason = _URC_CONTINUE_UNWIND;\n                    return;\n                }\n                // Go to next action\n                action += actionOffset;\n            }  // there is no break out of this loop, only return\n        }\n#ifndef __USING_SJLJ_EXCEPTIONS__\n        else if (ipOffset < start)\n        {\n            // There is no call site for this ip\n            // Something bad has happened.  We should never get here.\n            // Possible stack corruption.\n            call_terminate(native_exception, unwind_exception);\n        }\n#endif  // !__USING_SJLJ_EXCEPTIONS__\n    }  // there might be some tricky cases which break out of this loop\n\n    // It is possible that no eh table entry specify how to handle\n    // this exception. By spec, terminate it immediately.\n    call_terminate(native_exception, unwind_exception);\n}\n\n// public API\n\n/*\nThe personality function branches on actions like so:\n\n_UA_SEARCH_PHASE\n\n    If _UA_CLEANUP_PHASE or _UA_HANDLER_FRAME or _UA_FORCE_UNWIND there's\n      an error from above, return _URC_FATAL_PHASE1_ERROR.\n\n    Scan for anything that could stop unwinding:\n\n       1.  A catch clause that will catch this exception\n           (will never catch foreign).\n       2.  A catch (...) (will always catch foreign).\n       3.  An exception spec that will catch this exception\n           (will always catch foreign).\n    If a handler is found\n        If not foreign\n            Save state in header\n        return _URC_HANDLER_FOUND\n    Else a handler not found\n        return _URC_CONTINUE_UNWIND\n\n_UA_CLEANUP_PHASE\n\n    If _UA_HANDLER_FRAME\n        If _UA_FORCE_UNWIND\n            How did this happen?  return _URC_FATAL_PHASE2_ERROR\n        If foreign\n            Do _UA_SEARCH_PHASE to recover state\n        else\n            Recover state from header\n        Transfer control to landing pad.  return _URC_INSTALL_CONTEXT\n    \n    Else\n\n        This branch handles both normal C++ non-catching handlers (cleanups)\n          and forced unwinding.    \n        Scan for anything that can not stop unwinding:\n    \n            1.  A cleanup.\n\n        If a cleanup is found\n            transfer control to it. return _URC_INSTALL_CONTEXT\n        Else a cleanup is not found: return _URC_CONTINUE_UNWIND\n*/\n\n#if !LIBCXXABI_ARM_EHABI\n_Unwind_Reason_Code\n#ifdef __USING_SJLJ_EXCEPTIONS__\n__gxx_personality_sj0\n#else\n__gxx_personality_v0\n#endif\n                    (int version, _Unwind_Action actions, uint64_t exceptionClass,\n                     _Unwind_Exception* unwind_exception, _Unwind_Context* context)\n{\n    if (version != 1 || unwind_exception == 0 || context == 0)\n        return _URC_FATAL_PHASE1_ERROR;\n\n    bool native_exception = (exceptionClass     & get_vendor_and_language) ==\n                            (kOurExceptionClass & get_vendor_and_language);\n    scan_results results;\n    if (actions & _UA_SEARCH_PHASE)\n    {\n        // Phase 1 search:  All we're looking for in phase 1 is a handler that\n        //   halts unwinding\n        scan_eh_tab(results, actions, native_exception, unwind_exception, context);\n        if (results.reason == _URC_HANDLER_FOUND)\n        {\n            // Found one.  Can we cache the results somewhere to optimize phase 2?\n            if (native_exception)\n            {\n                __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;\n                exception_header->handlerSwitchValue = static_cast<int>(results.ttypeIndex);\n                exception_header->actionRecord = results.actionRecord;\n                exception_header->languageSpecificData = results.languageSpecificData;\n                exception_header->catchTemp = reinterpret_cast<void*>(results.landingPad);\n                exception_header->adjustedPtr = results.adjustedPtr;\n            }\n            return _URC_HANDLER_FOUND;\n        }\n        // Did not find a catching-handler.  Return the results of the scan\n        //    (normally _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE1_ERROR\n        //     if we were called improperly).\n        return results.reason;\n    }\n    if (actions & _UA_CLEANUP_PHASE)\n    {\n        // Phase 2 search:\n        //  Did we find a catching handler in phase 1?\n        if (actions & _UA_HANDLER_FRAME)\n        {\n            // Yes, phase 1 said we have a catching handler here.\n            // Did we cache the results of the scan?\n            if (native_exception)\n            {\n                // Yes, reload the results from the cache.\n                __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;\n                results.ttypeIndex = exception_header->handlerSwitchValue;\n                results.actionRecord = exception_header->actionRecord;\n                results.languageSpecificData = exception_header->languageSpecificData;\n                results.landingPad = reinterpret_cast<uintptr_t>(exception_header->catchTemp);\n                results.adjustedPtr = exception_header->adjustedPtr;\n            }\n            else\n            {\n                // No, do the scan again to reload the results.\n                scan_eh_tab(results, actions, native_exception, unwind_exception, context);\n                // Phase 1 told us we would find a handler.  Now in Phase 2 we\n                //   didn't find a handler.  The eh table should not be changing!\n                if (results.reason != _URC_HANDLER_FOUND)\n                    call_terminate(native_exception, unwind_exception);\n            }\n            // Jump to the handler\n            set_registers(unwind_exception, context, results);\n            return _URC_INSTALL_CONTEXT;\n        }\n        // Either we didn't do a phase 1 search (due to forced unwinding), or\n        //   phase 1 reported no catching-handlers.\n        // Search for a (non-catching) cleanup\n        scan_eh_tab(results, actions, native_exception, unwind_exception, context);\n        if (results.reason == _URC_HANDLER_FOUND)\n        {\n            // Found a non-catching handler.  Jump to it:\n            set_registers(unwind_exception, context, results);\n            return _URC_INSTALL_CONTEXT;\n        }\n        // Did not find a cleanup.  Return the results of the scan\n        //    (normally _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE2_ERROR\n        //     if we were called improperly).\n        return results.reason;\n    }\n    // We were called improperly: neither a phase 1 or phase 2 search\n    return _URC_FATAL_PHASE1_ERROR;\n}\n#else\n\nextern \"C\" _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception*,\n                                                  _Unwind_Context*);\n\n// Helper function to unwind one frame.\n// ARM EHABI 7.3 and 7.4: If the personality function returns _URC_CONTINUE_UNWIND, the\n// personality routine should update the virtual register set (VRS) according to the\n// corresponding frame unwinding instructions (ARM EHABI 9.3.)\nstatic _Unwind_Reason_Code continue_unwind(_Unwind_Exception* unwind_exception,\n                                           _Unwind_Context* context)\n{\n    if (__gnu_unwind_frame(unwind_exception, context) != _URC_OK)\n        return _URC_FAILURE;\n    return _URC_CONTINUE_UNWIND;\n}\n\n// ARM register names\n#if !LIBCXXABI_USE_LLVM_UNWINDER\nstatic const uint32_t REG_UCB = 12;  // Register to save _Unwind_Control_Block\n#endif\nstatic const uint32_t REG_SP = 13;\n\nstatic void save_results_to_barrier_cache(_Unwind_Exception* unwind_exception,\n                                          const scan_results& results)\n{\n    unwind_exception->barrier_cache.bitpattern[0] = (uint32_t)results.adjustedPtr;\n    unwind_exception->barrier_cache.bitpattern[1] = (uint32_t)results.actionRecord;\n    unwind_exception->barrier_cache.bitpattern[2] = (uint32_t)results.languageSpecificData;\n    unwind_exception->barrier_cache.bitpattern[3] = (uint32_t)results.landingPad;\n    unwind_exception->barrier_cache.bitpattern[4] = (uint32_t)results.ttypeIndex;\n}\n\nstatic void load_results_from_barrier_cache(scan_results& results,\n                                            const _Unwind_Exception* unwind_exception)\n{\n    results.adjustedPtr = (void*)unwind_exception->barrier_cache.bitpattern[0];\n    results.actionRecord = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[1];\n    results.languageSpecificData = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[2];\n    results.landingPad = (uintptr_t)unwind_exception->barrier_cache.bitpattern[3];\n    results.ttypeIndex = (int64_t)(int32_t)unwind_exception->barrier_cache.bitpattern[4];\n}\n\nextern \"C\" _Unwind_Reason_Code\n__gxx_personality_v0(_Unwind_State state,\n                     _Unwind_Exception* unwind_exception,\n                     _Unwind_Context* context)\n{\n    if (unwind_exception == 0 || context == 0)\n        return _URC_FATAL_PHASE1_ERROR;\n\n    bool native_exception = (unwind_exception->exception_class & get_vendor_and_language) ==\n                            (kOurExceptionClass & get_vendor_and_language);\n\n#if !LIBCXXABI_USE_LLVM_UNWINDER\n    // Copy the address of _Unwind_Control_Block to r12 so that\n    // _Unwind_GetLanguageSpecificData() and _Unwind_GetRegionStart() can\n    // return correct address.\n    _Unwind_SetGR(context, REG_UCB, reinterpret_cast<uint32_t>(unwind_exception));\n#endif\n\n    // Check the undocumented force unwinding behavior\n    bool is_force_unwinding = state & _US_FORCE_UNWIND;\n    state &= ~_US_FORCE_UNWIND;\n\n    scan_results results;\n    switch (state) {\n    case _US_VIRTUAL_UNWIND_FRAME:\n        if (is_force_unwinding)\n            return continue_unwind(unwind_exception, context);\n\n        // Phase 1 search:  All we're looking for in phase 1 is a handler that halts unwinding\n        scan_eh_tab(results, _UA_SEARCH_PHASE, native_exception, unwind_exception, context);\n        if (results.reason == _URC_HANDLER_FOUND)\n        {\n            unwind_exception->barrier_cache.sp = _Unwind_GetGR(context, REG_SP);\n            if (native_exception)\n                save_results_to_barrier_cache(unwind_exception, results);\n            return _URC_HANDLER_FOUND;\n        }\n        // Did not find the catch handler\n        if (results.reason == _URC_CONTINUE_UNWIND)\n            return continue_unwind(unwind_exception, context);\n        return results.reason;\n\n    case _US_UNWIND_FRAME_STARTING:\n        // TODO: Support force unwinding in the phase 2 search.\n        // NOTE: In order to call the cleanup functions, _Unwind_ForcedUnwind()\n        // will call this personality function with (_US_FORCE_UNWIND |\n        // _US_UNWIND_FRAME_STARTING).\n\n        // Phase 2 search\n        if (unwind_exception->barrier_cache.sp == _Unwind_GetGR(context, REG_SP))\n        {\n            // Found a catching handler in phase 1\n            if (native_exception)\n            {\n                // Load the result from the native exception barrier cache.\n                load_results_from_barrier_cache(results, unwind_exception);\n                results.reason = _URC_HANDLER_FOUND;\n            }\n            else\n            {\n                // Search for the catching handler again for the foreign exception.\n                scan_eh_tab(results, static_cast<_Unwind_Action>(_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME),\n                            native_exception, unwind_exception, context);\n                if (results.reason != _URC_HANDLER_FOUND)  // phase1 search should guarantee to find one\n                    call_terminate(native_exception, unwind_exception);\n            }\n\n            // Install the context for the catching handler\n            set_registers(unwind_exception, context, results);\n            return _URC_INSTALL_CONTEXT;\n        }\n\n        // Either we didn't do a phase 1 search (due to forced unwinding), or\n        //  phase 1 reported no catching-handlers.\n        // Search for a (non-catching) cleanup\n        scan_eh_tab(results, _UA_CLEANUP_PHASE, native_exception, unwind_exception, context);\n        if (results.reason == _URC_HANDLER_FOUND)\n        {\n            // Found a non-catching handler\n\n            // ARM EHABI 8.4.2: Before we can jump to the cleanup handler, we have to setup some\n            // internal data structures, so that __cxa_end_cleanup() can get unwind_exception from\n            // __cxa_get_globals().\n            __cxa_begin_cleanup(unwind_exception);\n\n            // Install the context for the cleanup handler\n            set_registers(unwind_exception, context, results);\n            return _URC_INSTALL_CONTEXT;\n        }\n\n        // Did not find any handler\n        if (results.reason == _URC_CONTINUE_UNWIND)\n            return continue_unwind(unwind_exception, context);\n        return results.reason;\n\n    case _US_UNWIND_FRAME_RESUME:\n        return continue_unwind(unwind_exception, context);\n    }\n\n    // We were called improperly: neither a phase 1 or phase 2 search\n    return _URC_FATAL_PHASE1_ERROR;\n}\n#endif\n\n\n__attribute__((noreturn))\nvoid\n__cxa_call_unexpected(void* arg)\n{\n    _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(arg);\n    if (unwind_exception == 0)\n        call_terminate(false, unwind_exception);\n    __cxa_begin_catch(unwind_exception);\n    bool native_old_exception =\n        (unwind_exception->exception_class & get_vendor_and_language) ==\n        (kOurExceptionClass                & get_vendor_and_language);\n    std::unexpected_handler u_handler;\n    std::terminate_handler t_handler;\n    __cxa_exception* old_exception_header = 0;\n    int64_t ttypeIndex;\n    const uint8_t* lsda;\n    if (native_old_exception)\n    {\n        old_exception_header = (__cxa_exception*)(unwind_exception+1) - 1;\n        t_handler = old_exception_header->terminateHandler;\n        u_handler = old_exception_header->unexpectedHandler;\n        // If std::__unexpected(u_handler) rethrows the same exception,\n        //   these values get overwritten by the rethrow.  So save them now:\n#if LIBCXXABI_ARM_EHABI\n        ttypeIndex = (int64_t)(int32_t)unwind_exception->barrier_cache.bitpattern[4];\n        lsda = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[2];\n#else\n        ttypeIndex = old_exception_header->handlerSwitchValue;\n        lsda = old_exception_header->languageSpecificData;\n#endif\n    }\n    else\n    {\n        t_handler = std::get_terminate();\n        u_handler = std::get_unexpected();\n    }\n    try\n    {\n        std::__unexpected(u_handler);\n    }\n    catch (...)\n    {\n        // If the old exception is foreign, then all we can do is terminate.\n        //   We have no way to recover the needed old exception spec.  There's\n        //   no way to pass that information here.  And the personality routine\n        //   can't call us directly and do anything but terminate() if we throw\n        //   from here.\n        if (native_old_exception)\n        {\n            // Have:\n            //   old_exception_header->languageSpecificData\n            //   old_exception_header->actionRecord\n            // Need\n            //   const uint8_t* classInfo\n            //   uint8_t ttypeEncoding\n            uint8_t lpStartEncoding = *lsda++;\n            const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);\n            (void)lpStart;  // purposefully unused.  Just needed to increment lsda.\n            uint8_t ttypeEncoding = *lsda++;\n            if (ttypeEncoding == DW_EH_PE_omit)\n                std::__terminate(t_handler);\n            uintptr_t classInfoOffset = readULEB128(&lsda);\n            const uint8_t* classInfo = lsda + classInfoOffset;\n            // Is this new exception catchable by the exception spec at ttypeIndex?\n            // The answer is obviously yes if the new and old exceptions are the same exception\n            // If no\n            //    throw;\n            __cxa_eh_globals* globals = __cxa_get_globals_fast();\n            __cxa_exception* new_exception_header = globals->caughtExceptions;\n            if (new_exception_header == 0)\n                // This shouldn't be able to happen!\n                std::__terminate(t_handler);\n            bool native_new_exception =\n                (new_exception_header->unwindHeader.exception_class & get_vendor_and_language) ==\n                                                (kOurExceptionClass & get_vendor_and_language);\n            void* adjustedPtr;\n            if (native_new_exception && (new_exception_header != old_exception_header))\n            {\n                const __shim_type_info* excpType =\n                    static_cast<const __shim_type_info*>(new_exception_header->exceptionType);\n                adjustedPtr =\n                    new_exception_header->unwindHeader.exception_class == kOurDependentExceptionClass ?\n                        ((__cxa_dependent_exception*)new_exception_header)->primaryException :\n                        new_exception_header + 1;\n                if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding,\n                                              excpType, adjustedPtr, unwind_exception))\n                {\n                    // We need to __cxa_end_catch, but for the old exception,\n                    //   not the new one.  This is a little tricky ...\n                    // Disguise new_exception_header as a rethrown exception, but\n                    //   don't actually rethrow it.  This means you can temporarily\n                    //   end the catch clause enclosing new_exception_header without\n                    //   __cxa_end_catch destroying new_exception_header.\n                    new_exception_header->handlerCount = -new_exception_header->handlerCount;\n                    globals->uncaughtExceptions += 1;\n                    // Call __cxa_end_catch for new_exception_header\n                    __cxa_end_catch();\n                    // Call __cxa_end_catch for old_exception_header\n                    __cxa_end_catch();\n                    // Renter this catch clause with new_exception_header\n                    __cxa_begin_catch(&new_exception_header->unwindHeader);\n                    // Rethrow new_exception_header\n                    throw;\n                }\n            }\n            // Will a std::bad_exception be catchable by the exception spec at\n            //   ttypeIndex?\n            // If no\n            //    throw std::bad_exception();\n            const __shim_type_info* excpType =\n                static_cast<const __shim_type_info*>(&typeid(std::bad_exception));\n            std::bad_exception be;\n            adjustedPtr = &be;\n            if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding,\n                                          excpType, adjustedPtr, unwind_exception))\n            {\n                // We need to __cxa_end_catch for both the old exception and the\n                //   new exception.  Technically we should do it in that order.\n                //   But it is expedient to do it in the opposite order:\n                // Call __cxa_end_catch for new_exception_header\n                __cxa_end_catch();\n                // Throw std::bad_exception will __cxa_end_catch for\n                //   old_exception_header\n                throw be;\n            }\n        }\n    }\n    std::__terminate(t_handler);\n}\n\n}  // extern \"C\"\n\n}  // __cxxabiv1\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_thread_atexit.cpp",
    "content": "//===----------------------- cxa_thread_atexit.cpp ------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"cxxabi.h\"\n\nnamespace __cxxabiv1 {\n\nextern \"C\" {\n\n#ifdef HAVE___CXA_THREAD_ATEXIT_IMPL\n\nint __cxa_thread_atexit(void (*dtor)(void *), void *obj,\n                        void *dso_symbol) throw() {\n  extern int __cxa_thread_atexit_impl(void (*)(void *), void *, void *);\n  return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);\n}\n\n#endif // HAVE__CXA_THREAD_ATEXIT_IMPL\n\n} // extern \"C\"\n\n} // namespace __cxxabiv1\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_unexpected.cpp",
    "content": "//===------------------------- cxa_unexpected.cpp -------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <exception>\n#include <cxxabi.h>\n#include \"cxa_exception.hpp\"\n\nnamespace __cxxabiv1\n{\n\n#pragma GCC visibility push(default)\n\nextern \"C\"\n{\n\n}\n\n#pragma GCC visibility pop\n\n}  // namespace __cxxabiv1\n\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_vector.cpp",
    "content": "//===-------------------------- cxa_vector.cpp ---------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//  \n//  This file implements the \"Array Construction and Destruction APIs\"\n//  http://mentorembedded.github.io/cxx-abi/abi.html#array-ctor\n//  \n//===----------------------------------------------------------------------===//\n\n#include \"cxxabi.h\"\n\n#include <exception>        // for std::terminate\n\nnamespace __cxxabiv1 {\n\n#if 0\n#pragma mark --Helper routines and classes --\n#endif\n\nnamespace {\n    inline static size_t __get_element_count ( void *p ) {\n        return static_cast <size_t *> (p)[-1];\n        }\n\n    inline static void __set_element_count ( void *p, size_t element_count ) {\n        static_cast <size_t *> (p)[-1] = element_count;\n        }\n\n\n//  A pair of classes to simplify exception handling and control flow.\n//  They get passed a block of memory in the constructor, and unless the\n//  'release' method is called, they deallocate the memory in the destructor.\n//  Preferred usage is to allocate some memory, attach it to one of these objects,\n//  and then, when all the operations to set up the memory block have succeeded,\n//  call 'release'. If any of the setup operations fail, or an exception is\n//  thrown, then the block is automatically deallocated.\n//\n//  The only difference between these two classes is the signature for the\n//  deallocation function (to match new2/new3 and delete2/delete3.\n    class st_heap_block2 {\n    public:\n        typedef void (*dealloc_f)(void *);\n        \n        st_heap_block2 ( dealloc_f dealloc, void *ptr ) \n            : dealloc_ ( dealloc ), ptr_ ( ptr ), enabled_ ( true ) {}\n        ~st_heap_block2 () { if ( enabled_ ) dealloc_ ( ptr_ ) ; }\n        void release () { enabled_ = false; }\n    \n    private:\n        dealloc_f dealloc_;\n        void *ptr_;\n        bool enabled_;\n    };\n    \n    class st_heap_block3 {\n    public:\n        typedef void (*dealloc_f)(void *, size_t);\n        \n        st_heap_block3 ( dealloc_f dealloc, void *ptr, size_t size ) \n            : dealloc_ ( dealloc ), ptr_ ( ptr ), size_ ( size ), enabled_ ( true ) {}\n        ~st_heap_block3 () { if ( enabled_ ) dealloc_ ( ptr_, size_ ) ; }\n        void release () { enabled_ = false; }\n    \n    private:\n        dealloc_f dealloc_;\n        void *ptr_;\n        size_t size_;\n        bool enabled_;\n    };\n\n    class st_cxa_cleanup {\n    public:\n        typedef void (*destruct_f)(void *);\n        \n        st_cxa_cleanup ( void *ptr, size_t &idx, size_t element_size, destruct_f destructor )\n            : ptr_ ( ptr ), idx_ ( idx ), element_size_ ( element_size ), \n                destructor_ ( destructor ), enabled_ ( true ) {}\n        ~st_cxa_cleanup () {\n            if ( enabled_ ) \n                __cxa_vec_cleanup ( ptr_, idx_, element_size_, destructor_ );\n            }\n        \n        void release () { enabled_ = false; }\n    \n    private:\n        void *ptr_;\n        size_t &idx_;\n        size_t element_size_;\n        destruct_f destructor_;\n        bool enabled_;\n    };\n    \n    class st_terminate {\n    public:\n        st_terminate ( bool enabled = true ) : enabled_ ( enabled ) {}\n        ~st_terminate () { if ( enabled_ ) std::terminate (); }\n        void release () { enabled_ = false; }\n    private:\n        bool enabled_ ;\n    };\n}\n\n#if 0\n#pragma mark --Externally visible routines--\n#endif\n\nextern \"C\" {\n\n// Equivalent to\n// \n//   __cxa_vec_new2(element_count, element_size, padding_size, constructor,\n//                  destructor, &::operator new[], &::operator delete[])\nvoid* __cxa_vec_new(\n    size_t element_count, size_t element_size, size_t padding_size, \n        void (*constructor)(void*), void (*destructor)(void*) ) {\n\n    return __cxa_vec_new2 ( element_count, element_size, padding_size, \n        constructor, destructor, &::operator new [], &::operator delete [] );\n}\n\n\n\n// Given the number and size of elements for an array and the non-negative\n// size of prefix padding for a cookie, allocate space (using alloc) for\n// the array preceded by the specified padding, initialize the cookie if\n// the padding is non-zero, and call the given constructor on each element.\n// Return the address of the array proper, after the padding.\n// \n// If alloc throws an exception, rethrow the exception. If alloc returns\n// NULL, return NULL. If the constructor throws an exception, call\n// destructor for any already constructed elements, and rethrow the\n// exception. If the destructor throws an exception, call std::terminate.\n// \n// The constructor may be NULL, in which case it must not be called. If the\n// padding_size is zero, the destructor may be NULL; in that case it must\n// not be called.\n// \n// Neither alloc nor dealloc may be NULL.\nvoid* __cxa_vec_new2(\n    size_t element_count, size_t element_size, size_t padding_size,\n        void  (*constructor)(void*), void  (*destructor)(void*),\n        void* (*alloc)(size_t), void  (*dealloc)(void*) ) {\n\n    const size_t heap_size = element_count * element_size + padding_size;\n    char * const heap_block = static_cast<char *> ( alloc ( heap_size ));\n    char *vec_base = heap_block;\n    \n    if ( NULL != vec_base ) {\n        st_heap_block2 heap ( dealloc, heap_block );\n\n    //  put the padding before the array elements\n        if ( 0 != padding_size ) {\n            vec_base += padding_size;\n            __set_element_count ( vec_base, element_count );\n        }\n            \n    //  Construct the elements\n        __cxa_vec_ctor ( vec_base, element_count, element_size, constructor, destructor );\n        heap.release ();    // We're good!\n    }\n    \n    return vec_base;\n}\n\n\n// Same as __cxa_vec_new2 except that the deallocation function takes both\n// the object address and its size.\nvoid* __cxa_vec_new3(\n    size_t element_count, size_t element_size, size_t padding_size,\n        void  (*constructor)(void*), void  (*destructor)(void*),\n        void* (*alloc)(size_t), void  (*dealloc)(void*, size_t) ) {\n\n    const size_t heap_size = element_count * element_size + padding_size;\n    char * const heap_block = static_cast<char *> ( alloc ( heap_size ));\n    char *vec_base = heap_block;\n    \n    if ( NULL != vec_base ) {\n        st_heap_block3 heap ( dealloc, heap_block, heap_size );\n\n    //  put the padding before the array elements\n        if ( 0 != padding_size ) {\n            vec_base += padding_size;\n            __set_element_count ( vec_base, element_count );\n        }\n            \n    //  Construct the elements\n        __cxa_vec_ctor ( vec_base, element_count, element_size, constructor, destructor );\n        heap.release ();    // We're good!\n    }\n    \n    return vec_base;\n}\n \n \n// Given the (data) addresses of a destination and a source array, an\n// element count and an element size, call the given copy constructor to\n// copy each element from the source array to the destination array. The\n// copy constructor's arguments are the destination address and source\n// address, respectively. If an exception occurs, call the given destructor\n// (if non-NULL) on each copied element and rethrow. If the destructor\n// throws an exception, call terminate(). The constructor and or destructor\n// pointers may be NULL. If either is NULL, no action is taken when it\n// would have been called.\n\nvoid __cxa_vec_cctor( void*  dest_array, void*  src_array, \n    size_t element_count, size_t element_size, \n        void  (*constructor) (void*, void*), void  (*destructor)(void*) ) {\n\n    if ( NULL != constructor ) {\n        size_t idx = 0;\n        char *src_ptr  = static_cast<char *>(src_array);\n        char *dest_ptr = static_cast<char *>(dest_array);\n        st_cxa_cleanup cleanup ( dest_array, idx, element_size, destructor );        \n\n        for ( idx = 0; idx < element_count; \n                    ++idx, src_ptr += element_size, dest_ptr += element_size )\n            constructor ( dest_ptr, src_ptr );\n        cleanup.release ();     // We're good!\n    }\n}\n\n\n// Given the (data) address of an array, not including any cookie padding,\n// and the number and size of its elements, call the given constructor on\n// each element. If the constructor throws an exception, call the given\n// destructor for any already-constructed elements, and rethrow the\n// exception. If the destructor throws an exception, call terminate(). The\n// constructor and/or destructor pointers may be NULL. If either is NULL,\n// no action is taken when it would have been called.\nvoid __cxa_vec_ctor(\n    void*  array_address, size_t element_count, size_t element_size, \n       void (*constructor)(void*), void (*destructor)(void*) ) {\n\n    if ( NULL != constructor ) {\n        size_t idx;\n        char *ptr = static_cast <char *> ( array_address );\n        st_cxa_cleanup cleanup ( array_address, idx, element_size, destructor );        \n        \n    //  Construct the elements\n        for ( idx = 0; idx < element_count; ++idx, ptr += element_size )\n            constructor ( ptr );\n        cleanup.release ();     // We're good!\n    }\n}\n\n// Given the (data) address of an array, the number of elements, and the\n// size of its elements, call the given destructor on each element. If the\n// destructor throws an exception, rethrow after destroying the remaining\n// elements if possible. If the destructor throws a second exception, call\n// terminate(). The destructor pointer may be NULL, in which case this\n// routine does nothing.\nvoid __cxa_vec_dtor(\n    void*  array_address, size_t element_count, size_t element_size, \n       void (*destructor)(void*) ) {\n    \n    if ( NULL != destructor ) {\n        char *ptr = static_cast <char *> (array_address);\n        size_t idx = element_count;\n        st_cxa_cleanup cleanup ( array_address, idx, element_size, destructor );        \n        {\n            st_terminate exception_guard (__cxa_uncaught_exception ());\n            ptr +=  element_count * element_size;   // one past the last element\n\n            while ( idx-- > 0 ) {\n                ptr -= element_size;\n                destructor ( ptr );\n            }\n            exception_guard.release (); //  We're good !\n        }\n        cleanup.release ();     // We're still good!\n    }\n}\n\n// Given the (data) address of an array, the number of elements, and the\n// size of its elements, call the given destructor on each element. If the\n// destructor throws an exception, call terminate(). The destructor pointer\n// may be NULL, in which case this routine does nothing.\nvoid __cxa_vec_cleanup( void* array_address, size_t element_count,\n        size_t element_size, void  (*destructor)(void*) ) {\n\n    if ( NULL != destructor ) {\n        char *ptr = static_cast <char *> (array_address);\n        size_t idx = element_count;\n        st_terminate exception_guard;\n        \n        ptr += element_count * element_size;    // one past the last element\n        while ( idx-- > 0 ) {\n            ptr -= element_size;\n            destructor ( ptr );\n            }\n        exception_guard.release ();     // We're done!\n    }\n}\n\n\n// If the array_address is NULL, return immediately. Otherwise, given the\n// (data) address of an array, the non-negative size of prefix padding for\n// the cookie, and the size of its elements, call the given destructor on\n// each element, using the cookie to determine the number of elements, and\n// then delete the space by calling ::operator delete[](void *). If the\n// destructor throws an exception, rethrow after (a) destroying the\n// remaining elements, and (b) deallocating the storage. If the destructor\n// throws a second exception, call terminate(). If padding_size is 0, the\n// destructor pointer must be NULL. If the destructor pointer is NULL, no\n// destructor call is to be made.\n// \n// The intent of this function is to permit an implementation to call this\n// function when confronted with an expression of the form delete[] p in\n// the source code, provided that the default deallocation function can be\n// used. Therefore, the semantics of this function are consistent with\n// those required by the standard. The requirement that the deallocation\n// function be called even if the destructor throws an exception derives\n// from the resolution to DR 353 to the C++ standard, which was adopted in\n// April, 2003.\nvoid __cxa_vec_delete( void* array_address,\n        size_t element_size, size_t padding_size, void  (*destructor)(void*) ) {\n\n    __cxa_vec_delete2 ( array_address, element_size, padding_size,\n               destructor, &::operator delete [] );\n}\n\n\n// Same as __cxa_vec_delete, except that the given function is used for\n// deallocation instead of the default delete function. If dealloc throws\n// an exception, the result is undefined. The dealloc pointer may not be\n// NULL.\nvoid __cxa_vec_delete2( void* array_address,\n        size_t element_size, size_t padding_size, \n        void  (*destructor)(void*), void  (*dealloc)(void*) ) {\n\n    if ( NULL != array_address ) {\n        char *vec_base   = static_cast <char *> (array_address);\n        char *heap_block = vec_base - padding_size;\n        st_heap_block2 heap ( dealloc, heap_block );\n        \n        if ( 0 != padding_size && NULL != destructor ) // call the destructors\n            __cxa_vec_dtor ( array_address, __get_element_count ( vec_base ), \n                                    element_size, destructor );\n    }\n}\n\n\n// Same as __cxa_vec_delete, except that the given function is used for\n// deallocation instead of the default delete function. The deallocation\n// function takes both the object address and its size. If dealloc throws\n// an exception, the result is undefined. The dealloc pointer may not be\n// NULL.\nvoid __cxa_vec_delete3( void* array_address, \n        size_t element_size, size_t padding_size, \n        void  (*destructor)(void*), void  (*dealloc) (void*, size_t)) {\n\n    if ( NULL != array_address ) {\n        char *vec_base   = static_cast <char *> (array_address);\n        char *heap_block = vec_base - padding_size;\n        const size_t element_count = padding_size ? __get_element_count ( vec_base ) : 0;\n        const size_t heap_block_size = element_size * element_count + padding_size;\n        st_heap_block3 heap ( dealloc, heap_block, heap_block_size );\n\n        if ( 0 != padding_size && NULL != destructor ) // call the destructors\n            __cxa_vec_dtor ( array_address, element_count, element_size, destructor );\n    }\n}\n\n\n}  // extern \"C\"\n\n}  // abi\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/cxa_virtual.cpp",
    "content": "//===-------------------------- cxa_virtual.cpp ---------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"cxxabi.h\"\n#include \"abort_message.h\"\n\nnamespace __cxxabiv1\n{\n\nextern \"C\"\n{\n\nLIBCXXABI_NORETURN\nvoid __cxa_pure_virtual(void) {\n    abort_message(\"Pure virtual function called!\");\n}\n\nLIBCXXABI_NORETURN\nvoid __cxa_deleted_virtual(void) {\n    abort_message(\"Deleted virtual function called!\");\n}\n\n}  // extern \"C\"\n\n}  // abi\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/exception.cpp",
    "content": "//===---------------------------- exception.cpp ---------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <exception>\n\n#pragma GCC visibility push(default)\n\nnamespace std\n{\n\n// exception\n\nexception::~exception() _NOEXCEPT\n{\n}\n\nconst char* exception::what() const _NOEXCEPT\n{\n  return \"std::exception\";\n}\n\n// bad_exception\n\nbad_exception::~bad_exception() _NOEXCEPT\n{\n}\n\nconst char* bad_exception::what() const _NOEXCEPT\n{\n  return \"std::bad_exception\";\n}\n\n}  // std\n\n#pragma GCC visibility pop\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/fallback_malloc.ipp",
    "content": "//===------------------------ fallback_malloc.ipp -------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//  \n//  This file implements the \"Exception Handling APIs\"\n//  http://mentorembedded.github.io/cxx-abi/abi-eh.html\n//  \n//===----------------------------------------------------------------------===//\n\n#include \"config.h\"\n\n//  A small, simple heap manager based (loosely) on \n//  the startup heap manager from FreeBSD, optimized for space.\n//\n//  Manages a fixed-size memory pool, supports malloc and free only.\n//  No support for realloc.\n//\n//  Allocates chunks in multiples of four bytes, with a four byte header\n//  for each chunk. The overhead of each chunk is kept low by keeping pointers\n//  as two byte offsets within the heap, rather than (4 or 8 byte) pointers.\n\nnamespace {\n\n// When POSIX threads are not available, make the mutex operations a nop\n#if LIBCXXABI_HAS_NO_THREADS\nstatic void * heap_mutex = 0;\n#else\nstatic pthread_mutex_t heap_mutex = PTHREAD_MUTEX_INITIALIZER;\n#endif\n\nclass mutexor {\npublic:\n#if LIBCXXABI_HAS_NO_THREADS\n    mutexor ( void * ) {}\n    ~mutexor () {}\n#else\n    mutexor ( pthread_mutex_t *m ) : mtx_(m) { pthread_mutex_lock ( mtx_ ); }\n    ~mutexor () { pthread_mutex_unlock ( mtx_ ); }\n#endif\nprivate:\n    mutexor ( const mutexor &rhs );\n    mutexor & operator = ( const mutexor &rhs );\n#if !LIBCXXABI_HAS_NO_THREADS\n    pthread_mutex_t *mtx_;\n#endif\n    };\n\n        \n#define HEAP_SIZE   512\nchar heap [ HEAP_SIZE ];\n\ntypedef unsigned short heap_offset;\ntypedef unsigned short heap_size;\n\nstruct heap_node {\n    heap_offset next_node;  // offset into heap\n    heap_size   len;        // size in units of \"sizeof(heap_node)\"\n};\n\nstatic const heap_node *list_end = (heap_node *) ( &heap [ HEAP_SIZE ] );   // one past the end of the heap\nstatic heap_node *freelist = NULL;\n\nheap_node *node_from_offset ( const heap_offset offset )\n    { return (heap_node *) ( heap + ( offset * sizeof (heap_node))); }\n\nheap_offset offset_from_node ( const heap_node *ptr )\n    { return static_cast<heap_offset>(static_cast<size_t>(reinterpret_cast<const char *>(ptr) - heap)  / sizeof (heap_node)); }\n \nvoid init_heap () {\n    freelist = (heap_node *) heap;\n    freelist->next_node = offset_from_node ( list_end );\n    freelist->len = HEAP_SIZE / sizeof (heap_node);\n    }\n    \n//  How big a chunk we allocate\nsize_t alloc_size (size_t len)\n    { return (len + sizeof(heap_node) - 1) / sizeof(heap_node) + 1; }\n\nbool is_fallback_ptr ( void *ptr )\n    { return ptr >= heap && ptr < ( heap + HEAP_SIZE ); }\n\nvoid *fallback_malloc(size_t len) {\n    heap_node *p, *prev;\n    const size_t nelems = alloc_size ( len );\n    mutexor mtx ( &heap_mutex );\n    \n    if ( NULL == freelist )\n        init_heap ();\n\n//  Walk the free list, looking for a \"big enough\" chunk\n    for (p = freelist, prev = 0; \n            p && p != list_end;     prev = p, p = node_from_offset ( p->next_node)) {\n\n        if (p->len > nelems) {  //  chunk is larger, shorten, and return the tail\n            heap_node *q;\n\n            p->len = static_cast<heap_size>(p->len - nelems);\n            q = p + p->len;\n            q->next_node = 0;\n            q->len = static_cast<heap_size>(nelems);\n            return (void *) (q + 1);\n        }\n        \n        if (p->len == nelems) { // exact size match\n            if (prev == 0)\n                freelist = node_from_offset(p->next_node);\n            else\n                prev->next_node = p->next_node;\n            p->next_node = 0;\n            return (void *) (p + 1);\n        }\n    }\n    return NULL;    // couldn't find a spot big enough\n}\n\n//  Return the start of the next block\nheap_node *after ( struct heap_node *p ) { return p + p->len; }\n\nvoid fallback_free (void *ptr) {\n    struct heap_node *cp = ((struct heap_node *) ptr) - 1;      // retrieve the chunk\n    struct heap_node *p, *prev;\n\n    mutexor mtx ( &heap_mutex );\n\n#ifdef DEBUG_FALLBACK_MALLOC\n        std::cout << \"Freeing item at \" << offset_from_node ( cp ) << \" of size \" << cp->len << std::endl;\n#endif\n\n    for (p = freelist, prev = 0; \n            p && p != list_end;     prev = p, p = node_from_offset (p->next_node)) {\n#ifdef DEBUG_FALLBACK_MALLOC\n        std::cout << \"  p, cp, after (p), after(cp) \"\n            << offset_from_node ( p ) << ' '\n            << offset_from_node ( cp ) << ' '\n            << offset_from_node ( after ( p )) << ' '\n            << offset_from_node ( after ( cp )) << std::endl;\n#endif\n        if ( after ( p ) == cp ) {\n#ifdef DEBUG_FALLBACK_MALLOC\n            std::cout << \"  Appending onto chunk at \" << offset_from_node ( p ) << std::endl;\n#endif\n            p->len = static_cast<heap_size>(p->len + cp->len);  // make the free heap_node larger\n            return;\n            }\n        else if ( after ( cp ) == p ) { // there's a free heap_node right after\n#ifdef DEBUG_FALLBACK_MALLOC\n            std::cout << \"  Appending free chunk at \" << offset_from_node ( p ) << std::endl;\n#endif\n            cp->len = static_cast<heap_size>(cp->len + p->len);\n            if ( prev == 0 ) {\n                freelist = cp;\n                cp->next_node = p->next_node;\n                }\n            else\n                prev->next_node = offset_from_node(cp);\n            return;\n            }\n        }\n//  Nothing to merge with, add it to the start of the free list\n#ifdef DEBUG_FALLBACK_MALLOC\n            std::cout << \"  Making new free list entry \" << offset_from_node ( cp ) << std::endl;\n#endif\n    cp->next_node = offset_from_node ( freelist );\n    freelist = cp;\n}\n\n#ifdef INSTRUMENT_FALLBACK_MALLOC\nsize_t print_free_list () {\n    struct heap_node *p, *prev;\n    heap_size total_free = 0;\n    if ( NULL == freelist )\n        init_heap ();\n    \n    for (p = freelist, prev = 0; \n            p && p != list_end;     prev = p, p = node_from_offset (p->next_node)) {\n        std::cout << ( prev == 0 ? \"\" : \"  \")  << \"Offset: \" << offset_from_node ( p ) \n                << \"\\tsize: \" << p->len << \" Next: \" << p->next_node << std::endl;\n        total_free += p->len;\n        }\n    std::cout << \"Total Free space: \" << total_free << std::endl;\n    return total_free;\n    }\n#endif\n}  // end unnamed namespace\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/private_typeinfo.cpp",
    "content": "//===----------------------- private_typeinfo.cpp -------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"private_typeinfo.h\"\n\n// The flag _LIBCXX_DYNAMIC_FALLBACK is used to make dynamic_cast more\n// forgiving when type_info's mistakenly have hidden visibility and thus\n// multiple type_infos can exist for a single type.\n// \n// When _LIBCXX_DYNAMIC_FALLBACK is defined, and only in the case where\n// there is a detected inconsistency in the type_info hierarchy during a\n// dynamic_cast, then the equality operation will fall back to using strcmp\n// on type_info names to determine type_info equality.\n// \n// This change happens *only* under dynamic_cast, and only when\n// dynamic_cast is faced with the choice:  abort, or possibly give back the\n// wrong answer.  If when the dynamic_cast is done with this fallback\n// algorithm and an inconsistency is still detected, dynamic_cast will call\n// abort with an appropriate message.\n// \n// The current implementation of _LIBCXX_DYNAMIC_FALLBACK requires a\n// printf-like function called syslog:\n// \n//     void syslog(int facility_priority, const char* format, ...);\n// \n// If you want this functionality but your platform doesn't have syslog,\n// just implement it in terms of fprintf(stderr, ...).\n// \n// _LIBCXX_DYNAMIC_FALLBACK is currently off by default.\n\n#ifdef _LIBCXX_DYNAMIC_FALLBACK\n#include \"abort_message.h\"\n#include <string.h>\n#include <sys/syslog.h>\n#endif\n\n// On Windows, typeids are different between DLLs and EXEs, so comparing\n// type_info* will work for typeids from the same compiled file but fail\n// for typeids from a DLL and an executable. Among other things, exceptions\n// are not caught by handlers since can_catch() returns false.\n//\n// Defining _LIBCXX_DYNAMIC_FALLBACK does not help since can_catch() calls \n// is_equal() with use_strcmp=false so the string names are not compared.\n\n#ifdef _WIN32\n#include <string.h>\n#endif\n\nnamespace __cxxabiv1\n{\n\n#pragma GCC visibility push(hidden)\n\n#ifdef _LIBCXX_DYNAMIC_FALLBACK\n\ninline\nbool\nis_equal(const std::type_info* x, const std::type_info* y, bool use_strcmp)\n{\n    if (!use_strcmp)\n        return x == y;\n    return strcmp(x->name(), y->name()) == 0;\n}\n\n#else  // !_LIBCXX_DYNAMIC_FALLBACK\n\ninline\nbool\nis_equal(const std::type_info* x, const std::type_info* y, bool)\n{\n#ifndef _WIN32\n    return x == y;\n#else\n    return (x == y) || (strcmp(x->name(), y->name()) == 0);\n#endif    \n}\n\n#endif  // _LIBCXX_DYNAMIC_FALLBACK\n\n// __shim_type_info\n\n__shim_type_info::~__shim_type_info()\n{\n}\n\nvoid __shim_type_info::noop1() const {}\nvoid __shim_type_info::noop2() const {}\n\n// __fundamental_type_info\n\n// This miraculously (compiler magic) emits the type_info's for:\n//   1. all of the fundamental types\n//   2. pointers to all of the fundamental types\n//   3. pointers to all of the const fundamental types\n__fundamental_type_info::~__fundamental_type_info()\n{\n}\n\n// __array_type_info\n\n__array_type_info::~__array_type_info()\n{\n}\n\n// __function_type_info\n\n__function_type_info::~__function_type_info()\n{\n}\n\n// __enum_type_info\n\n__enum_type_info::~__enum_type_info()\n{\n}\n\n// __class_type_info\n\n__class_type_info::~__class_type_info()\n{\n}\n\n// __si_class_type_info\n\n__si_class_type_info::~__si_class_type_info()\n{\n}\n\n// __vmi_class_type_info\n\n__vmi_class_type_info::~__vmi_class_type_info()\n{\n}\n\n// __pbase_type_info\n\n__pbase_type_info::~__pbase_type_info()\n{\n}\n\n// __pointer_type_info\n\n__pointer_type_info::~__pointer_type_info()\n{\n}\n\n// __pointer_to_member_type_info\n\n__pointer_to_member_type_info::~__pointer_to_member_type_info()\n{\n}\n\n// can_catch\n\n// A handler is a match for an exception object of type E if\n//   1. The handler is of type cv T or cv T& and E and T are the same type\n//      (ignoring the top-level cv-qualifiers), or\n//   2. the handler is of type cv T or cv T& and T is an unambiguous public\n//       base class of E, or\n//   3. the handler is of type cv1 T* cv2 and E is a pointer type that can be\n//      converted to the type of the handler by either or both of\n//      A. a standard pointer conversion (4.10) not involving conversions to\n//         pointers to private or protected or ambiguous classes\n//      B. a qualification conversion\n//   4. the handler is a pointer or pointer to member type and E is\n//      std::nullptr_t.\n\n// adjustedPtr:\n// \n// catch (A& a) : adjustedPtr == &a\n// catch (A* a) : adjustedPtr == a\n// catch (A** a) : adjustedPtr == a\n// \n// catch (D2& d2) : adjustedPtr == &d2  (d2 is base class of thrown object)\n// catch (D2* d2) : adjustedPtr == d2\n// catch (D2*& d2) : adjustedPtr == d2\n// \n// catch (...) : adjustedPtr == & of the exception\n\n// Handles bullet 1\nbool\n__fundamental_type_info::can_catch(const __shim_type_info* thrown_type,\n                                   void*&) const\n{\n    return is_equal(this, thrown_type, false);\n}\n\nbool\n__array_type_info::can_catch(const __shim_type_info*, void*&) const\n{\n    // We can get here if someone tries to catch an array by reference.\n    //   However if someone tries to throw an array, it immediately gets\n    //   converted to a pointer, which will not convert back to an array\n    //   at the catch clause.  So this can never catch anything.\n    return false;\n}\n\nbool\n__function_type_info::can_catch(const __shim_type_info*, void*&) const\n{\n    // We can get here if someone tries to catch a function by reference.\n    //   However if someone tries to throw a function, it immediately gets\n    //   converted to a pointer, which will not convert back to a function\n    //   at the catch clause.  So this can never catch anything.\n    return false;\n}\n\n// Handles bullet 1\nbool\n__enum_type_info::can_catch(const __shim_type_info* thrown_type,\n                            void*&) const\n{\n    return is_equal(this, thrown_type, false);\n}\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wmissing-field-initializers\"\n#endif\n\n// Handles bullets 1 and 2\nbool\n__class_type_info::can_catch(const __shim_type_info* thrown_type,\n                             void*& adjustedPtr) const\n{\n    // bullet 1\n    if (is_equal(this, thrown_type, false))\n        return true;\n    const __class_type_info* thrown_class_type =\n        dynamic_cast<const __class_type_info*>(thrown_type);\n    if (thrown_class_type == 0)\n        return false;\n    // bullet 2\n    __dynamic_cast_info info = {thrown_class_type, 0, this, -1, 0};\n    info.number_of_dst_type = 1;\n    thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path);\n    if (info.path_dst_ptr_to_static_ptr == public_path)\n    {\n        adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr);\n        return true;\n    }\n    return false;\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\nvoid\n__class_type_info::process_found_base_class(__dynamic_cast_info* info,\n                                               void* adjustedPtr,\n                                               int path_below) const\n{\n    if (info->dst_ptr_leading_to_static_ptr == 0)\n    {\n        // First time here\n        info->dst_ptr_leading_to_static_ptr = adjustedPtr;\n        info->path_dst_ptr_to_static_ptr = path_below;\n        info->number_to_static_ptr = 1;\n    }\n    else if (info->dst_ptr_leading_to_static_ptr == adjustedPtr)\n    {\n        // We've been here before.  Update path to \"most public\"\n        if (info->path_dst_ptr_to_static_ptr == not_public_path)\n            info->path_dst_ptr_to_static_ptr = path_below;\n    }\n    else\n    {\n        // We've detected an ambiguous cast from (thrown_class_type, adjustedPtr)\n        //   to a static_type\n        info->number_to_static_ptr += 1;\n        info->path_dst_ptr_to_static_ptr = not_public_path;\n        info->search_done = true;\n    }\n}\n\nvoid\n__class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,\n                                               void* adjustedPtr,\n                                               int path_below) const\n{\n    if (is_equal(this, info->static_type, false))\n        process_found_base_class(info, adjustedPtr, path_below);\n}\n\nvoid\n__si_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,\n                                                  void* adjustedPtr,\n                                                  int path_below) const\n{\n    if (is_equal(this, info->static_type, false))\n        process_found_base_class(info, adjustedPtr, path_below);\n    else\n        __base_type->has_unambiguous_public_base(info, adjustedPtr, path_below);\n}\n\nvoid\n__base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,\n                                                    void* adjustedPtr,\n                                                    int path_below) const\n{\n    ptrdiff_t offset_to_base = 0;\n    if (adjustedPtr != nullptr)\n    {\n        offset_to_base = __offset_flags >> __offset_shift;\n        if (__offset_flags & __virtual_mask)\n        {\n            const char* vtable = *static_cast<const char*const*>(adjustedPtr);\n            offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);\n        }\n    }\n    __base_type->has_unambiguous_public_base(\n            info,\n            static_cast<char*>(adjustedPtr) + offset_to_base,\n            (__offset_flags & __public_mask) ? path_below : not_public_path);\n}\n\nvoid\n__vmi_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,\n                                                   void* adjustedPtr,\n                                                   int path_below) const\n{\n    if (is_equal(this, info->static_type, false))\n        process_found_base_class(info, adjustedPtr, path_below);\n    else\n    {\n        typedef const __base_class_type_info* Iter;\n        const Iter e = __base_info + __base_count;\n        Iter p = __base_info;\n        p->has_unambiguous_public_base(info, adjustedPtr, path_below);\n        if (++p < e)\n        {\n            do\n            {\n                p->has_unambiguous_public_base(info, adjustedPtr, path_below);\n                if (info->search_done)\n                    break;\n            } while (++p < e);\n        }\n    }\n}\n\n// Handles bullets 1 and 4 for both pointers and member pointers\nbool\n__pbase_type_info::can_catch(const __shim_type_info* thrown_type,\n                             void*&) const\n{\n    return is_equal(this, thrown_type, false) ||\n           is_equal(thrown_type, &typeid(std::nullptr_t), false);\n}\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wmissing-field-initializers\"\n#endif\n\n// Handles bullets 1, 3 and 4\n// NOTE: It might not be safe to adjust the pointer if it is not not a pointer\n// type. Only adjust the pointer after we know it is safe to do so.\nbool\n__pointer_type_info::can_catch(const __shim_type_info* thrown_type,\n                               void*& adjustedPtr) const\n{\n    // bullets 1 and 4\n    if (__pbase_type_info::can_catch(thrown_type, adjustedPtr)) {\n        if (adjustedPtr != NULL)\n            adjustedPtr = *static_cast<void**>(adjustedPtr);\n        return true;\n    }\n    // bullet 3\n    const __pointer_type_info* thrown_pointer_type =\n        dynamic_cast<const __pointer_type_info*>(thrown_type);\n    if (thrown_pointer_type == 0)\n        return false;\n    // Do the dereference adjustment\n    if (adjustedPtr != NULL)\n        adjustedPtr = *static_cast<void**>(adjustedPtr);\n    // bullet 3B\n    if (thrown_pointer_type->__flags & ~__flags)\n        return false;\n    if (is_equal(__pointee, thrown_pointer_type->__pointee, false))\n        return true;\n    // bullet 3A\n    if (is_equal(__pointee, &typeid(void), false)) {\n        // pointers to functions cannot be converted to void*.\n        // pointers to member functions are not handled here.\n        const __function_type_info* thrown_function =\n            dynamic_cast<const __function_type_info*>(thrown_pointer_type->__pointee);\n        return (thrown_function == nullptr);\n    }\n    // Handle pointer to pointer\n    const __pointer_type_info* nested_pointer_type =\n        dynamic_cast<const __pointer_type_info*>(__pointee);\n    if (nested_pointer_type) {\n        if (~__flags & __const_mask) return false;\n        return nested_pointer_type->can_catch_nested(thrown_pointer_type->__pointee);\n    }\n\n    // Handle pointer to pointer to member\n    const __pointer_to_member_type_info* member_ptr_type =\n        dynamic_cast<const __pointer_to_member_type_info*>(__pointee);\n    if (member_ptr_type) {\n        if (~__flags & __const_mask) return false;\n        return member_ptr_type->can_catch_nested(thrown_pointer_type->__pointee);\n    }\n\n    // Handle pointer to class type\n    const __class_type_info* catch_class_type =\n        dynamic_cast<const __class_type_info*>(__pointee);\n    if (catch_class_type == 0)\n        return false;\n    const __class_type_info* thrown_class_type =\n        dynamic_cast<const __class_type_info*>(thrown_pointer_type->__pointee);\n    if (thrown_class_type == 0)\n        return false;\n    __dynamic_cast_info info = {thrown_class_type, 0, catch_class_type, -1, 0};\n    info.number_of_dst_type = 1;\n    thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path);\n    if (info.path_dst_ptr_to_static_ptr == public_path)\n    {\n        if (adjustedPtr != NULL)\n            adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr);\n        return true;\n    }\n    return false;\n}\n\nbool __pointer_type_info::can_catch_nested(\n    const __shim_type_info* thrown_type) const\n{\n  const __pointer_type_info* thrown_pointer_type =\n        dynamic_cast<const __pointer_type_info*>(thrown_type);\n    if (thrown_pointer_type == 0)\n        return false;\n    // bullet 3B\n    if (thrown_pointer_type->__flags & ~__flags)\n        return false;\n    if (is_equal(__pointee, thrown_pointer_type->__pointee, false))\n        return true;\n    // If the pointed to types differ then the catch type must be const\n    // qualified.\n    if (~__flags & __const_mask)\n        return false;\n\n    // Handle pointer to pointer\n    const __pointer_type_info* nested_pointer_type =\n        dynamic_cast<const __pointer_type_info*>(__pointee);\n    if (nested_pointer_type) {\n        return nested_pointer_type->can_catch_nested(\n            thrown_pointer_type->__pointee);\n    }\n\n    // Handle pointer to pointer to member\n    const __pointer_to_member_type_info* member_ptr_type =\n        dynamic_cast<const __pointer_to_member_type_info*>(__pointee);\n    if (member_ptr_type) {\n        return member_ptr_type->can_catch_nested(thrown_pointer_type->__pointee);\n    }\n\n    return false;\n}\n\nbool __pointer_to_member_type_info::can_catch(\n    const __shim_type_info* thrown_type, void*& adjustedPtr) const {\n    // bullets 1 and 4\n    if (__pbase_type_info::can_catch(thrown_type, adjustedPtr))\n        return true;\n\n    const __pointer_to_member_type_info* thrown_pointer_type =\n        dynamic_cast<const __pointer_to_member_type_info*>(thrown_type);\n    if (thrown_pointer_type == 0)\n        return false;\n    if (thrown_pointer_type->__flags & ~__flags)\n        return false;\n    if (!is_equal(__pointee, thrown_pointer_type->__pointee, false))\n        return false;\n    if (is_equal(__context, thrown_pointer_type->__context, false))\n        return true;\n\n    // [except.handle] does not allow the pointer-to-member conversions mentioned\n    // in [mem.conv] to take place. For this reason we don't check Derived->Base\n    // for Derived->Base conversions.\n\n    return false;\n}\n\nbool __pointer_to_member_type_info::can_catch_nested(\n    const __shim_type_info* thrown_type) const\n{\n    const __pointer_to_member_type_info* thrown_member_ptr_type =\n        dynamic_cast<const __pointer_to_member_type_info*>(thrown_type);\n    if (thrown_member_ptr_type == 0)\n        return false;\n    if (~__flags & thrown_member_ptr_type->__flags)\n        return false;\n    if (!is_equal(__pointee, thrown_member_ptr_type->__pointee, false))\n        return false;\n    if (!is_equal(__context, thrown_member_ptr_type->__context, false))\n        return false;\n    return true;\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n#pragma GCC visibility pop\n#pragma GCC visibility push(default)\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wmissing-field-initializers\"\n#endif\n\n// __dynamic_cast\n\n// static_ptr: pointer to an object of type static_type; nonnull, and since the\n//   object is polymorphic, *(void**)static_ptr is a virtual table pointer.\n//   static_ptr is &v in the expression dynamic_cast<T>(v).\n// static_type: static type of the object pointed to by static_ptr.\n// dst_type: destination type of the cast (the \"T\" in \"dynamic_cast<T>(v)\").\n// src2dst_offset: a static hint about the location of the\n//                 source subobject with respect to the complete object;\n//                 special negative values are:\n//                     -1: no hint\n//                     -2: static_type is not a public base of dst_type\n//                     -3: static_type is a multiple public base type but never a\n//                         virtual base type\n//                 otherwise, the static_type type is a unique public nonvirtual\n//                 base type of dst_type at offset src2dst_offset from the\n//                 origin of dst_type.\n//\n// (dynamic_ptr, dynamic_type) are the run time type of the complete object\n// referred to by static_ptr and a pointer to it.  These can be found from\n// static_ptr for polymorphic types.\n// static_type is guaranteed to be a polymorphic type.\n//\n// (dynamic_ptr, dynamic_type) is the root of a DAG that grows upward.  Each\n// node of the tree represents a base class/object of its parent (or parents) below.\n// Each node is uniquely represented by a pointer to the object, and a pointer\n// to a type_info - its type.  Different nodes may have the same pointer and\n// different nodes may have the same type.  But only one node has a specific\n// (pointer-value, type) pair.  In C++ two objects of the same type can not\n// share the same address.\n//\n// There are two flavors of nodes which have the type dst_type:\n//    1.  Those that are derived from (below) (static_ptr, static_type).\n//    2.  Those that are not derived from (below) (static_ptr, static_type).\n//\n// Invariants of the DAG:\n//\n// There is at least one path from the root (dynamic_ptr, dynamic_type) to\n// the node (static_ptr, static_type).  This path may or may not be public.\n// There may be more than one such path (some public some not).  Such a path may\n// or may not go through a node having type dst_type.\n//\n// No node of type T appears above a node of the same type.  That means that\n// there is only one node with dynamic_type.  And if dynamic_type == dst_type,\n// then there is only one dst_type in the DAG.\n//\n// No node of type dst_type appears above a node of type static_type.  Such\n// DAG's are possible in C++, but the compiler computes those dynamic_casts at\n// compile time, and only calls __dynamic_cast when dst_type lies below\n// static_type in the DAG.\n//\n// dst_type != static_type:  The compiler computes the dynamic_cast in this case too.\n// dynamic_type != static_type:  The compiler computes the dynamic_cast in this case too.\n//\n// Returns:\n//\n// If there is exactly one dst_type of flavor 1, and\n//    If there is a public path from that dst_type to (static_ptr, static_type), or\n//    If there are 0 dst_types of flavor 2, and there is a public path from\n//        (dynamic_ptr, dynamic_type) to (static_ptr, static_type) and a public\n//        path from (dynamic_ptr, dynamic_type) to the one dst_type, then return\n//        a pointer to that dst_type.\n// Else if there are 0 dst_types of flavor 1 and exactly 1 dst_type of flavor 2, and\n//    if there is a public path from (dynamic_ptr, dynamic_type) to\n//    (static_ptr, static_type) and a public path from (dynamic_ptr, dynamic_type)\n//    to the one dst_type, then return a pointer to that one dst_type.\n// Else return nullptr.\n//\n// If dynamic_type == dst_type, then the above algorithm collapses to the\n// following cheaper algorithm:\n//\n// If there is a public path from (dynamic_ptr, dynamic_type) to\n//    (static_ptr, static_type), then return dynamic_ptr.\n// Else return nullptr.\nextern \"C\"\nvoid*\n__dynamic_cast(const void* static_ptr,\n               const __class_type_info* static_type,\n               const __class_type_info* dst_type,\n               std::ptrdiff_t src2dst_offset)\n{\n    // Possible future optimization:  Take advantage of src2dst_offset\n    // Currently clang always sets src2dst_offset to -1 (no hint).\n\n    // Get (dynamic_ptr, dynamic_type) from static_ptr\n    void **vtable = *static_cast<void ** const *>(static_ptr);\n    ptrdiff_t offset_to_derived = reinterpret_cast<ptrdiff_t>(vtable[-2]);\n    const void* dynamic_ptr = static_cast<const char*>(static_ptr) + offset_to_derived;\n    const __class_type_info* dynamic_type = static_cast<const __class_type_info*>(vtable[-1]);\n\n    // Initialize answer to nullptr.  This will be changed from the search\n    //    results if a non-null answer is found.  Regardless, this is what will\n    //    be returned.\n    const void* dst_ptr = 0;\n    // Initialize info struct for this search.\n    __dynamic_cast_info info = {dst_type, static_ptr, static_type, src2dst_offset, 0};\n\n    // Find out if we can use a giant short cut in the search\n    if (is_equal(dynamic_type, dst_type, false))\n    {\n        // Using giant short cut.  Add that information to info.\n        info.number_of_dst_type = 1;\n        // Do the  search\n        dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false);\n#ifdef _LIBCXX_DYNAMIC_FALLBACK\n        // The following if should always be false because we should definitely\n        //   find (static_ptr, static_type), either on a public or private path\n        if (info.path_dst_ptr_to_static_ptr == unknown)\n        {\n            // We get here only if there is some kind of visibility problem\n            //   in client code.\n            syslog(LOG_ERR, \"dynamic_cast error 1: Both of the following type_info's \"\n                    \"should have public visibility.  At least one of them is hidden. %s\" \n                    \", %s.\\n\", static_type->name(), dynamic_type->name());\n            // Redo the search comparing type_info's using strcmp\n            info = {dst_type, static_ptr, static_type, src2dst_offset, 0};\n            info.number_of_dst_type = 1;\n            dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true);\n        }\n#endif  // _LIBCXX_DYNAMIC_FALLBACK\n        // Query the search.\n        if (info.path_dst_ptr_to_static_ptr == public_path)\n            dst_ptr = dynamic_ptr;\n    }\n    else\n    {\n        // Not using giant short cut.  Do the search\n        dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false);\n #ifdef _LIBCXX_DYNAMIC_FALLBACK\n        // The following if should always be false because we should definitely\n        //   find (static_ptr, static_type), either on a public or private path\n        if (info.path_dst_ptr_to_static_ptr == unknown &&\n            info.path_dynamic_ptr_to_static_ptr == unknown)\n        {\n            syslog(LOG_ERR, \"dynamic_cast error 2: One or more of the following type_info's \"\n                            \" has hidden visibility.  They should all have public visibility.  \"\n                            \" %s, %s, %s.\\n\", static_type->name(), dynamic_type->name(),\n                    dst_type->name());\n            // Redo the search comparing type_info's using strcmp\n            info = {dst_type, static_ptr, static_type, src2dst_offset, 0};\n            dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true);\n        }\n#endif  // _LIBCXX_DYNAMIC_FALLBACK\n        // Query the search.\n        switch (info.number_to_static_ptr)\n        {\n        case 0:\n            if (info.number_to_dst_ptr == 1 &&\n                    info.path_dynamic_ptr_to_static_ptr == public_path &&\n                    info.path_dynamic_ptr_to_dst_ptr == public_path)\n                dst_ptr = info.dst_ptr_not_leading_to_static_ptr;\n            break;\n        case 1:\n            if (info.path_dst_ptr_to_static_ptr == public_path ||\n                   (\n                       info.number_to_dst_ptr == 0 &&\n                       info.path_dynamic_ptr_to_static_ptr == public_path &&\n                       info.path_dynamic_ptr_to_dst_ptr == public_path\n                   )\n               )\n                dst_ptr = info.dst_ptr_leading_to_static_ptr;\n            break;\n        }\n    }\n    return const_cast<void*>(dst_ptr);\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n#pragma GCC visibility pop\n#pragma GCC visibility push(hidden)\n\n// Call this function when you hit a static_type which is a base (above) a dst_type.\n// Let caller know you hit a static_type.  But only start recording details if\n// this is (static_ptr, static_type) -- the node we are casting from.\n// If this is (static_ptr, static_type)\n//   Record the path (public or not) from the dst_type to here.  There may be\n//   multiple paths from the same dst_type to here, record the \"most public\" one.\n//   Record the dst_ptr as pointing to (static_ptr, static_type).\n//   If more than one (dst_ptr, dst_type) points to (static_ptr, static_type),\n//   then mark this dyanmic_cast as ambiguous and stop the search.\nvoid\n__class_type_info::process_static_type_above_dst(__dynamic_cast_info* info,\n                                                 const void* dst_ptr,\n                                                 const void* current_ptr,\n                                                 int path_below) const\n{\n    // Record that we found a static_type\n    info->found_any_static_type = true;\n    if (current_ptr == info->static_ptr)\n    {\n        // Record that we found (static_ptr, static_type)\n        info->found_our_static_ptr = true;\n        if (info->dst_ptr_leading_to_static_ptr == 0)\n        {\n            // First time here\n            info->dst_ptr_leading_to_static_ptr = dst_ptr;\n            info->path_dst_ptr_to_static_ptr = path_below;\n            info->number_to_static_ptr = 1;\n            // If there is only one dst_type in the entire tree and the path from\n            //    there to here is public then we are done!\n            if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path)\n                info->search_done = true;\n        }\n        else if (info->dst_ptr_leading_to_static_ptr == dst_ptr)\n        {\n            // We've been here before.  Update path to \"most public\"\n            if (info->path_dst_ptr_to_static_ptr == not_public_path)\n                info->path_dst_ptr_to_static_ptr = path_below;\n            // If there is only one dst_type in the entire tree and the path from\n            //    there to here is public then we are done!\n            if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path)\n                info->search_done = true;\n        }\n        else\n        {\n            // We've detected an ambiguous cast from (static_ptr, static_type)\n            //   to a dst_type\n            info->number_to_static_ptr += 1;\n            info->search_done = true;\n        }\n    }\n}\n\n// Call this function when you hit a static_type which is not a base (above) a dst_type.\n// If this is (static_ptr, static_type)\n//   Record the path (public or not) from (dynamic_ptr, dynamic_type) to here.  There may be\n//   multiple paths from (dynamic_ptr, dynamic_type) to here, record the \"most public\" one.\nvoid\n__class_type_info::process_static_type_below_dst(__dynamic_cast_info* info,\n                                                 const void* current_ptr,\n                                                 int path_below) const\n{\n    if (current_ptr == info->static_ptr)\n    {\n        // Record the most public path from (dynamic_ptr, dynamic_type) to\n        //                                  (static_ptr, static_type)\n        if (info->path_dynamic_ptr_to_static_ptr != public_path)\n            info->path_dynamic_ptr_to_static_ptr = path_below;\n    }\n}\n\n// Call this function when searching below a dst_type node.  This function searches\n// for a path to (static_ptr, static_type) and for paths to one or more dst_type nodes.\n// If it finds a static_type node, there is no need to further search base classes\n// above.\n// If it finds a dst_type node it should search base classes using search_above_dst\n// to find out if this dst_type points to (static_ptr, static_type) or not.\n// Either way, the dst_type is recorded as one of two \"flavors\":  one that does\n// or does not point to (static_ptr, static_type).\n// If this is neither a static_type nor a dst_type node, continue searching\n// base classes above.\n// All the hoopla surrounding the search code is doing nothing but looking for\n// excuses to stop the search prematurely (break out of the for-loop).  That is,\n// the algorithm below is simply an optimization of this:\n// void\n// __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info,\n//                                         const void* current_ptr,\n//                                         int path_below) const\n// {\n//     typedef const __base_class_type_info* Iter;\n//     if (this == info->static_type)\n//         process_static_type_below_dst(info, current_ptr, path_below);\n//     else if (this == info->dst_type)\n//     {\n//         // Record the most public access path that got us here\n//         if (info->path_dynamic_ptr_to_dst_ptr != public_path)\n//             info->path_dynamic_ptr_to_dst_ptr = path_below;\n//         bool does_dst_type_point_to_our_static_type = false;\n//         for (Iter p = __base_info, e= __base_info + __base_count; p < e; ++p)\n//         {\n//             p->search_above_dst(info, current_ptr, current_ptr, public_path);\n//             if (info->found_our_static_ptr)\n//                 does_dst_type_point_to_our_static_type = true;\n//             // break out early here if you can detect it doesn't matter if you do\n//         }\n//         if (!does_dst_type_point_to_our_static_type)\n//         {\n//             // We found a dst_type that doesn't point to (static_ptr, static_type)\n//             // So record the address of this dst_ptr and increment the\n//             // count of the number of such dst_types found in the tree.\n//             info->dst_ptr_not_leading_to_static_ptr = current_ptr;\n//             info->number_to_dst_ptr += 1;\n//         }\n//     }\n//     else\n//     {\n//         // This is not a static_type and not a dst_type.\n//         for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p)\n//         {\n//             p->search_below_dst(info, current_ptr, public_path);\n//             // break out early here if you can detect it doesn't matter if you do\n//         }\n//     }\n// }\nvoid\n__vmi_class_type_info::search_below_dst(__dynamic_cast_info* info,\n                                        const void* current_ptr,\n                                        int path_below,\n                                        bool use_strcmp) const\n{\n    typedef const __base_class_type_info* Iter;\n    if (is_equal(this, info->static_type, use_strcmp))\n        process_static_type_below_dst(info, current_ptr, path_below);\n    else if (is_equal(this, info->dst_type, use_strcmp))\n    {\n        // We've been here before if we've recorded current_ptr in one of these\n        //   two places:\n        if (current_ptr == info->dst_ptr_leading_to_static_ptr ||\n            current_ptr == info->dst_ptr_not_leading_to_static_ptr)\n        {\n            // We've seen this node before, and therefore have already searched\n            // its base classes above.\n            //  Update path to here that is \"most public\".\n            if (path_below == public_path)\n                info->path_dynamic_ptr_to_dst_ptr = public_path;\n        }\n        else  // We have haven't been here before\n        {\n            // Record the access path that got us here\n            //   If there is more than one dst_type this path doesn't matter.\n            info->path_dynamic_ptr_to_dst_ptr = path_below;\n            // Only search above here if dst_type derives from static_type, or\n            //    if it is unknown if dst_type derives from static_type.\n            if (info->is_dst_type_derived_from_static_type != no)\n            {\n                // Set up flags to record results from all base classes\n                bool is_dst_type_derived_from_static_type = false;\n                bool does_dst_type_point_to_our_static_type = false;\n                // We've found a dst_type with a potentially public path to here.\n                // We have to assume the path is public because it may become\n                //   public later (if we get back to here with a public path).\n                // We can stop looking above if:\n                //    1.  We've found a public path to (static_ptr, static_type).\n                //    2.  We've found an ambiguous cast from (static_ptr, static_type) to a dst_type.\n                //        This is detected at the (static_ptr, static_type).\n                //    3.  We can prove that there is no public path to (static_ptr, static_type)\n                //        above here.\n                const Iter e = __base_info + __base_count;\n                for (Iter p = __base_info; p < e; ++p)\n                {\n                    // Zero out found flags\n                    info->found_our_static_ptr = false;\n                    info->found_any_static_type = false;\n                    p->search_above_dst(info, current_ptr, current_ptr, public_path, use_strcmp);\n                    if (info->search_done)\n                        break;\n                    if (info->found_any_static_type)\n                    {\n                        is_dst_type_derived_from_static_type = true;\n                        if (info->found_our_static_ptr)\n                        {\n                            does_dst_type_point_to_our_static_type = true;\n                            // If we found what we're looking for, stop looking above.\n                            if (info->path_dst_ptr_to_static_ptr == public_path)\n                                break;\n                            // We found a private path to (static_ptr, static_type)\n                            //   If there is no diamond then there is only one path\n                            //   to (static_ptr, static_type) and we just found it.\n                            if (!(__flags & __diamond_shaped_mask))\n                                break;\n                        }\n                        else\n                        {\n                            // If we found a static_type that isn't the one we're looking\n                            //    for, and if there are no repeated types above here,\n                            //    then stop looking.\n                            if (!(__flags & __non_diamond_repeat_mask))\n                                break;\n                        }\n                    }\n                }\n                if (!does_dst_type_point_to_our_static_type)\n                {\n                    // We found a dst_type that doesn't point to (static_ptr, static_type)\n                    // So record the address of this dst_ptr and increment the\n                    // count of the number of such dst_types found in the tree.\n                    info->dst_ptr_not_leading_to_static_ptr = current_ptr;\n                    info->number_to_dst_ptr += 1;\n                    // If there exists another dst with a private path to\n                    //    (static_ptr, static_type), then the cast from \n                    //     (dynamic_ptr, dynamic_type) to dst_type is now ambiguous,\n                    //      so stop search.\n                    if (info->number_to_static_ptr == 1 &&\n                            info->path_dst_ptr_to_static_ptr == not_public_path)\n                        info->search_done = true;\n                }\n                // If we found no static_type,s then dst_type doesn't derive\n                //   from static_type, else it does.  Record this result so that\n                //   next time we hit a dst_type we will know not to search above\n                //   it if it doesn't derive from static_type.\n                if (is_dst_type_derived_from_static_type)\n                    info->is_dst_type_derived_from_static_type = yes;\n                else\n                    info->is_dst_type_derived_from_static_type = no;\n            }\n        }\n    }\n    else\n    {\n        // This is not a static_type and not a dst_type.\n        const Iter e = __base_info + __base_count;\n        Iter p = __base_info;\n        p->search_below_dst(info, current_ptr, path_below, use_strcmp);\n        if (++p < e)\n        {\n            if ((__flags & __diamond_shaped_mask) || info->number_to_static_ptr == 1)\n            {\n                // If there are multiple paths to a base above from here, or if\n                //    a dst_type pointing to (static_ptr, static_type) has been found,\n                //    then there is no way to break out of this loop early unless\n                //    something below detects the search is done.\n                do\n                {\n                    if (info->search_done)\n                        break;\n                    p->search_below_dst(info, current_ptr, path_below, use_strcmp);\n                } while (++p < e);\n            }\n            else if (__flags & __non_diamond_repeat_mask)\n            {\n                // There are not multiple paths to any base class from here and a\n                //   dst_type pointing to (static_ptr, static_type) has not yet been\n                //   found.\n                do\n                {\n                    if (info->search_done)\n                        break;\n                    // If we just found a dst_type with a public path to (static_ptr, static_type),\n                    //    then the only reason to continue the search is to make sure\n                    //    no other dst_type points to (static_ptr, static_type).\n                    //    If !diamond, then we don't need to search here.\n                    if (info->number_to_static_ptr == 1 &&\n                              info->path_dst_ptr_to_static_ptr == public_path)\n                        break;\n                    p->search_below_dst(info, current_ptr, path_below, use_strcmp);\n                } while (++p < e);\n            }\n            else\n            {\n                // There are no repeated types above this node.\n                // There are no nodes with multiple parents above this node.\n                // no dst_type has been found to (static_ptr, static_type)\n                do\n                {\n                    if (info->search_done)\n                        break;\n                    // If we just found a dst_type with a public path to (static_ptr, static_type),\n                    //    then the only reason to continue the search is to make sure sure\n                    //    no other dst_type points to (static_ptr, static_type).\n                    //    If !diamond, then we don't need to search here.\n                    // if we just found a dst_type with a private path to (static_ptr, static_type),\n                    //    then we're only looking for a public path to (static_ptr, static_type)\n                    //    and to check for other dst_types.\n                    //    If !diamond & !repeat, then there is not a pointer to (static_ptr, static_type)\n                    //    and not a dst_type under here.\n                    if (info->number_to_static_ptr == 1)\n                        break;\n                    p->search_below_dst(info, current_ptr, path_below, use_strcmp);\n                } while (++p < e);\n            }\n        }\n    }\n}\n\n// This is the same algorithm as __vmi_class_type_info::search_below_dst but\n//   simplified to the case that there is only a single base class.\nvoid\n__si_class_type_info::search_below_dst(__dynamic_cast_info* info,\n                                       const void* current_ptr,\n                                       int path_below,\n                                       bool use_strcmp) const\n{\n    if (is_equal(this, info->static_type, use_strcmp))\n        process_static_type_below_dst(info, current_ptr, path_below);\n    else if (is_equal(this, info->dst_type, use_strcmp))\n    {\n        // We've been here before if we've recorded current_ptr in one of these\n        //   two places:\n        if (current_ptr == info->dst_ptr_leading_to_static_ptr ||\n            current_ptr == info->dst_ptr_not_leading_to_static_ptr)\n        {\n            // We've seen this node before, and therefore have already searched\n            // its base classes above.\n            //  Update path to here that is \"most public\".\n            if (path_below == public_path)\n                info->path_dynamic_ptr_to_dst_ptr = public_path;\n        }\n        else  // We have haven't been here before\n        {\n            // Record the access path that got us here\n            //   If there is more than one dst_type this path doesn't matter.\n            info->path_dynamic_ptr_to_dst_ptr = path_below;\n            // Only search above here if dst_type derives from static_type, or\n            //    if it is unknown if dst_type derives from static_type.\n            if (info->is_dst_type_derived_from_static_type != no)\n            {\n                // Set up flags to record results from all base classes\n                bool is_dst_type_derived_from_static_type = false;\n                bool does_dst_type_point_to_our_static_type = false;\n                // Zero out found flags\n                info->found_our_static_ptr = false;\n                info->found_any_static_type = false;\n                __base_type->search_above_dst(info, current_ptr, current_ptr, public_path, use_strcmp);\n                if (info->found_any_static_type)\n                {\n                    is_dst_type_derived_from_static_type = true;\n                    if (info->found_our_static_ptr)\n                        does_dst_type_point_to_our_static_type = true;\n                }\n                if (!does_dst_type_point_to_our_static_type)\n                {\n                    // We found a dst_type that doesn't point to (static_ptr, static_type)\n                    // So record the address of this dst_ptr and increment the\n                    // count of the number of such dst_types found in the tree.\n                    info->dst_ptr_not_leading_to_static_ptr = current_ptr;\n                    info->number_to_dst_ptr += 1;\n                    // If there exists another dst with a private path to\n                    //    (static_ptr, static_type), then the cast from \n                    //     (dynamic_ptr, dynamic_type) to dst_type is now ambiguous.\n                    if (info->number_to_static_ptr == 1 &&\n                            info->path_dst_ptr_to_static_ptr == not_public_path)\n                        info->search_done = true;\n                }\n                // If we found no static_type,s then dst_type doesn't derive\n                //   from static_type, else it does.  Record this result so that\n                //   next time we hit a dst_type we will know not to search above\n                //   it if it doesn't derive from static_type.\n                if (is_dst_type_derived_from_static_type)\n                    info->is_dst_type_derived_from_static_type = yes;\n                else\n                    info->is_dst_type_derived_from_static_type = no;\n            }\n        }\n    }\n    else\n    {\n        // This is not a static_type and not a dst_type\n        __base_type->search_below_dst(info, current_ptr, path_below, use_strcmp);\n    }\n}\n\n// This is the same algorithm as __vmi_class_type_info::search_below_dst but\n//   simplified to the case that there is no base class.\nvoid\n__class_type_info::search_below_dst(__dynamic_cast_info* info,\n                                    const void* current_ptr,\n                                    int path_below,\n                                    bool use_strcmp) const\n{\n    if (is_equal(this, info->static_type, use_strcmp))\n        process_static_type_below_dst(info, current_ptr, path_below);\n    else if (is_equal(this, info->dst_type, use_strcmp))\n    {\n        // We've been here before if we've recorded current_ptr in one of these\n        //   two places:\n        if (current_ptr == info->dst_ptr_leading_to_static_ptr ||\n            current_ptr == info->dst_ptr_not_leading_to_static_ptr)\n        {\n            // We've seen this node before, and therefore have already searched\n            // its base classes above.\n            //  Update path to here that is \"most public\".\n            if (path_below == public_path)\n                info->path_dynamic_ptr_to_dst_ptr = public_path;\n        }\n        else  // We have haven't been here before\n        {\n            // Record the access path that got us here\n            //   If there is more than one dst_type this path doesn't matter.\n            info->path_dynamic_ptr_to_dst_ptr = path_below;\n            // We found a dst_type that doesn't point to (static_ptr, static_type)\n            // So record the address of this dst_ptr and increment the\n            // count of the number of such dst_types found in the tree.\n            info->dst_ptr_not_leading_to_static_ptr = current_ptr;\n            info->number_to_dst_ptr += 1;\n            // If there exists another dst with a private path to\n            //    (static_ptr, static_type), then the cast from \n            //     (dynamic_ptr, dynamic_type) to dst_type is now ambiguous.\n            if (info->number_to_static_ptr == 1 &&\n                    info->path_dst_ptr_to_static_ptr == not_public_path)\n                info->search_done = true;\n            // We found that dst_type does not derive from static_type\n            info->is_dst_type_derived_from_static_type = no;\n        }\n    }\n}\n\n// Call this function when searching above a dst_type node.  This function searches\n// for a public path to (static_ptr, static_type).\n// This function is guaranteed not to find a node of type dst_type.\n// Theoretically this is a very simple function which just stops if it finds a\n// static_type node:  All the hoopla surrounding the search code is doing\n// nothing but looking for excuses to stop the search prematurely (break out of\n// the for-loop).  That is, the algorithm below is simply an optimization of this:\n// void\n// __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info,\n//                                         const void* dst_ptr,\n//                                         const void* current_ptr,\n//                                         int path_below) const\n// {\n//     if (this == info->static_type)\n//         process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);\n//     else\n//     {\n//         typedef const __base_class_type_info* Iter;\n//         // This is not a static_type and not a dst_type\n//         for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p)\n//         {\n//             p->search_above_dst(info, dst_ptr, current_ptr, public_path);\n//             // break out early here if you can detect it doesn't matter if you do\n//         }\n//     }\n// }\nvoid\n__vmi_class_type_info::search_above_dst(__dynamic_cast_info* info,\n                                        const void* dst_ptr,\n                                        const void* current_ptr,\n                                        int path_below,\n                                        bool use_strcmp) const\n{\n    if (is_equal(this, info->static_type, use_strcmp))\n        process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);\n    else\n    {\n        typedef const __base_class_type_info* Iter;\n        // This is not a static_type and not a dst_type\n        // Save flags so they can be restored when returning to nodes below.\n        bool found_our_static_ptr = info->found_our_static_ptr;\n        bool found_any_static_type = info->found_any_static_type;\n        // We've found a dst_type below with a path to here.  If the path\n        //    to here is not public, there may be another path to here that\n        //    is public.  So we have to assume that the path to here is public.\n        //  We can stop looking above if:\n        //    1.  We've found a public path to (static_ptr, static_type).\n        //    2.  We've found an ambiguous cast from (static_ptr, static_type) to a dst_type.\n        //        This is detected at the (static_ptr, static_type).\n        //    3.  We can prove that there is no public path to (static_ptr, static_type)\n        //        above here.\n        const Iter e = __base_info + __base_count;\n        Iter p = __base_info;\n        // Zero out found flags\n        info->found_our_static_ptr = false;\n        info->found_any_static_type = false;\n        p->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp);\n        if (++p < e)\n        {\n            do\n            {\n                if (info->search_done)\n                    break;\n                if (info->found_our_static_ptr)\n                {\n                    // If we found what we're looking for, stop looking above.\n                    if (info->path_dst_ptr_to_static_ptr == public_path)\n                        break;\n                    // We found a private path to (static_ptr, static_type)\n                    //   If there is no diamond then there is only one path\n                    //   to (static_ptr, static_type) from here and we just found it.\n                    if (!(__flags & __diamond_shaped_mask))\n                        break;\n                }\n                else if (info->found_any_static_type)\n                {\n                    // If we found a static_type that isn't the one we're looking\n                    //    for, and if there are no repeated types above here,\n                    //    then stop looking.\n                    if (!(__flags & __non_diamond_repeat_mask))\n                        break;\n                }\n                // Zero out found flags\n                info->found_our_static_ptr = false;\n                info->found_any_static_type = false;\n                p->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp);\n            } while (++p < e);\n        }\n        // Restore flags\n        info->found_our_static_ptr = found_our_static_ptr;\n        info->found_any_static_type = found_any_static_type;\n    }\n}\n\n// This is the same algorithm as __vmi_class_type_info::search_above_dst but\n//   simplified to the case that there is only a single base class.\nvoid\n__si_class_type_info::search_above_dst(__dynamic_cast_info* info,\n                                       const void* dst_ptr,\n                                       const void* current_ptr,\n                                       int path_below,\n                                       bool use_strcmp) const\n{\n    if (is_equal(this, info->static_type, use_strcmp))\n        process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);\n    else\n        __base_type->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp);\n}\n\n// This is the same algorithm as __vmi_class_type_info::search_above_dst but\n//   simplified to the case that there is no base class.\nvoid\n__class_type_info::search_above_dst(__dynamic_cast_info* info,\n                                    const void* dst_ptr,\n                                    const void* current_ptr,\n                                    int path_below,\n                                    bool use_strcmp) const\n{\n    if (is_equal(this, info->static_type, use_strcmp))\n        process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);\n}\n\n// The search functions for __base_class_type_info are simply convenience\n//   functions for adjusting the current_ptr and path_below as the search is\n//   passed up to the base class node.\n\nvoid\n__base_class_type_info::search_above_dst(__dynamic_cast_info* info,\n                                         const void* dst_ptr,\n                                         const void* current_ptr,\n                                         int path_below,\n                                         bool use_strcmp) const\n{\n    ptrdiff_t offset_to_base = __offset_flags >> __offset_shift;\n    if (__offset_flags & __virtual_mask)\n    {\n        const char* vtable = *static_cast<const char*const*>(current_ptr);\n        offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);\n    }\n    __base_type->search_above_dst(info, dst_ptr,\n                                  static_cast<const char*>(current_ptr) + offset_to_base,\n                                  (__offset_flags & __public_mask) ?\n                                      path_below :\n                                      not_public_path,\n                                  use_strcmp);\n}\n\nvoid\n__base_class_type_info::search_below_dst(__dynamic_cast_info* info,\n                                         const void* current_ptr,\n                                         int path_below,\n                                         bool use_strcmp) const\n{\n    ptrdiff_t offset_to_base = __offset_flags >> __offset_shift;\n    if (__offset_flags & __virtual_mask)\n    {\n        const char* vtable = *static_cast<const char*const*>(current_ptr);\n        offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);\n    }\n    __base_type->search_below_dst(info,\n                                  static_cast<const char*>(current_ptr) + offset_to_base,\n                                  (__offset_flags & __public_mask) ?\n                                      path_below :\n                                      not_public_path,\n                                  use_strcmp);\n}\n\n#pragma GCC visibility pop\n\n}  // __cxxabiv1\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/private_typeinfo.h",
    "content": "//===------------------------ private_typeinfo.h --------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef __PRIVATE_TYPEINFO_H_\n#define __PRIVATE_TYPEINFO_H_\n\n#include <typeinfo>\n#include <cstddef>\n\nnamespace __cxxabiv1\n{\n\n#pragma GCC visibility push(hidden)\n\nclass __attribute__ ((__visibility__(\"default\"))) __shim_type_info\n    : public std::type_info\n{\npublic:\n     __attribute__ ((__visibility__(\"hidden\"))) virtual ~__shim_type_info();\n\n     __attribute__ ((__visibility__(\"hidden\"))) virtual void noop1() const;\n     __attribute__ ((__visibility__(\"hidden\"))) virtual void noop2() const;\n     __attribute__ ((__visibility__(\"hidden\"))) virtual bool can_catch(const __shim_type_info* thrown_type, void*& adjustedPtr) const = 0;\n};\n\nclass __attribute__ ((__visibility__(\"default\"))) __fundamental_type_info\n    : public __shim_type_info\n{\npublic:\n    __attribute__ ((__visibility__(\"hidden\"))) virtual ~__fundamental_type_info();\n    __attribute__ ((__visibility__(\"hidden\"))) virtual bool can_catch(const __shim_type_info*, void*&) const;\n};\n\nclass __attribute__ ((__visibility__(\"default\"))) __array_type_info\n    : public __shim_type_info\n{\npublic:\n    __attribute__ ((__visibility__(\"hidden\"))) virtual ~__array_type_info();\n    __attribute__ ((__visibility__(\"hidden\"))) virtual bool can_catch(const __shim_type_info*, void*&) const;\n};\n\nclass __attribute__ ((__visibility__(\"default\"))) __function_type_info\n    : public __shim_type_info\n{\npublic:\n    __attribute__ ((__visibility__(\"hidden\"))) virtual ~__function_type_info();\n    __attribute__ ((__visibility__(\"hidden\"))) virtual bool can_catch(const __shim_type_info*, void*&) const;\n};\n\nclass __attribute__ ((__visibility__(\"default\"))) __enum_type_info\n    : public __shim_type_info\n{\npublic:\n    __attribute__ ((__visibility__(\"hidden\"))) virtual ~__enum_type_info();\n    __attribute__ ((__visibility__(\"hidden\"))) virtual bool can_catch(const __shim_type_info*, void*&) const;\n};\n\nenum\n{\n    unknown = 0,\n    public_path,\n    not_public_path,\n    yes,\n    no\n};\n\nclass __attribute__ ((__visibility__(\"default\"))) __class_type_info;\n\nstruct __dynamic_cast_info\n{\n// const data supplied to the search:\n\n    const __class_type_info* dst_type;\n    const void* static_ptr;\n    const __class_type_info* static_type;\n    std::ptrdiff_t src2dst_offset;\n\n// Data that represents the answer:\n\n    // pointer to a dst_type which has (static_ptr, static_type) above it\n    const void* dst_ptr_leading_to_static_ptr;\n    // pointer to a dst_type which does not have (static_ptr, static_type) above it\n    const void* dst_ptr_not_leading_to_static_ptr;\n\n    // The following three paths are either unknown, public_path or not_public_path.\n    // access of path from dst_ptr_leading_to_static_ptr to (static_ptr, static_type)\n    int path_dst_ptr_to_static_ptr;\n    // access of path from (dynamic_ptr, dynamic_type) to (static_ptr, static_type)\n    //    when there is no dst_type along the path\n    int path_dynamic_ptr_to_static_ptr;\n    // access of path from (dynamic_ptr, dynamic_type) to dst_type\n    //    (not used if there is a (static_ptr, static_type) above a dst_type).\n    int path_dynamic_ptr_to_dst_ptr;\n\n    // Number of dst_types below (static_ptr, static_type)\n    int number_to_static_ptr;\n    // Number of dst_types not below (static_ptr, static_type)\n    int number_to_dst_ptr;\n\n// Data that helps stop the search before the entire tree is searched:\n\n    // is_dst_type_derived_from_static_type is either unknown, yes or no.\n    int is_dst_type_derived_from_static_type;\n    // Number of dst_type in tree.  If 0, then that means unknown.\n    int number_of_dst_type;\n    // communicates to a dst_type node that (static_ptr, static_type) was found\n    //    above it.\n    bool found_our_static_ptr;\n    // communicates to a dst_type node that a static_type was found\n    //    above it, but it wasn't (static_ptr, static_type)\n    bool found_any_static_type;\n    // Set whenever a search can be stopped\n    bool search_done;\n};\n\n// Has no base class\nclass __attribute__ ((__visibility__(\"default\"))) __class_type_info\n    : public __shim_type_info\n{\npublic:\n    __attribute__ ((__visibility__(\"hidden\"))) virtual ~__class_type_info();\n\n    __attribute__ ((__visibility__(\"hidden\")))\n        void process_static_type_above_dst(__dynamic_cast_info*, const void*, const void*, int) const;\n    __attribute__ ((__visibility__(\"hidden\")))\n        void process_static_type_below_dst(__dynamic_cast_info*, const void*, int) const;\n    __attribute__ ((__visibility__(\"hidden\")))\n        void process_found_base_class(__dynamic_cast_info*, void*, int) const;\n    __attribute__ ((__visibility__(\"hidden\")))\n        virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int, bool) const;\n    __attribute__ ((__visibility__(\"hidden\")))\n        virtual void search_below_dst(__dynamic_cast_info*, const void*, int, bool) const;\n    __attribute__ ((__visibility__(\"hidden\")))\n        virtual bool can_catch(const __shim_type_info*, void*&) const;\n    __attribute__ ((__visibility__(\"hidden\")))\n        virtual void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const;\n};\n\n// Has one non-virtual public base class at offset zero\nclass __attribute__ ((__visibility__(\"default\"))) __si_class_type_info\n    : public __class_type_info\n{\npublic:\n    const __class_type_info* __base_type;\n\n    __attribute__ ((__visibility__(\"hidden\"))) virtual ~__si_class_type_info();\n\n    __attribute__ ((__visibility__(\"hidden\")))\n        virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int, bool) const;\n    __attribute__ ((__visibility__(\"hidden\")))\n        virtual void search_below_dst(__dynamic_cast_info*, const void*, int, bool) const;\n    __attribute__ ((__visibility__(\"hidden\")))\n        virtual void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const;\n};\n\nstruct __base_class_type_info\n{\npublic:\n    const __class_type_info* __base_type;\n    long __offset_flags;\n\n    enum __offset_flags_masks\n    {\n        __virtual_mask = 0x1,\n        __public_mask  = 0x2, // base is public\n        __offset_shift = 8\n    };\n\n    void search_above_dst(__dynamic_cast_info*, const void*, const void*, int, bool) const;\n    void search_below_dst(__dynamic_cast_info*, const void*, int, bool) const;\n    void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const;\n};\n\n// Has one or more base classes\nclass __attribute__ ((__visibility__(\"default\"))) __vmi_class_type_info\n    : public __class_type_info\n{\npublic:\n    unsigned int __flags;\n    unsigned int __base_count;\n    __base_class_type_info __base_info[1];\n\n    enum __flags_masks\n    {\n        __non_diamond_repeat_mask = 0x1,  // has two or more distinct base class\n                                          //    objects of the same type\n        __diamond_shaped_mask     = 0x2   // has base class object with two or\n                                          //    more derived objects\n    };\n\n    __attribute__ ((__visibility__(\"hidden\"))) virtual ~__vmi_class_type_info();\n\n    __attribute__ ((__visibility__(\"hidden\")))\n        virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int, bool) const;\n    __attribute__ ((__visibility__(\"hidden\")))\n        virtual void search_below_dst(__dynamic_cast_info*, const void*, int, bool) const;\n    __attribute__ ((__visibility__(\"hidden\")))\n        virtual void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const;\n};\n\nclass __attribute__ ((__visibility__(\"default\"))) __pbase_type_info\n    : public __shim_type_info\n{\npublic:\n    unsigned int __flags;\n    const __shim_type_info* __pointee;\n\n    enum __masks\n    {\n        __const_mask            = 0x1,\n        __volatile_mask         = 0x2,\n        __restrict_mask         = 0x4,\n        __incomplete_mask       = 0x8,\n        __incomplete_class_mask = 0x10\n    };\n\n    __attribute__ ((__visibility__(\"hidden\"))) virtual ~__pbase_type_info();\n    __attribute__ ((__visibility__(\"hidden\"))) virtual bool can_catch(const __shim_type_info*, void*&) const;\n};\n\nclass __attribute__ ((__visibility__(\"default\"))) __pointer_type_info\n    : public __pbase_type_info\n{\npublic:\n    __attribute__ ((__visibility__(\"hidden\"))) virtual ~__pointer_type_info();\n    __attribute__ ((__visibility__(\"hidden\"))) virtual bool can_catch(const __shim_type_info*, void*&) const;\n    __attribute__ ((__visibility__(\"hidden\"))) bool can_catch_nested(const __shim_type_info*) const;\n};\n\nclass __attribute__ ((__visibility__(\"default\"))) __pointer_to_member_type_info\n    : public __pbase_type_info\n{\npublic:\n    const __class_type_info* __context;\n\n    __attribute__ ((__visibility__(\"hidden\"))) virtual ~__pointer_to_member_type_info();\n    __attribute__ ((__visibility__(\"hidden\"))) virtual bool can_catch(const __shim_type_info*, void*&) const;\n    __attribute__ ((__visibility__(\"hidden\"))) bool can_catch_nested(const __shim_type_info*) const;\n};\n\n#pragma GCC visibility pop\n\n}  // __cxxabiv1\n\n#endif  // __PRIVATE_TYPEINFO_H_\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/stdexcept.cpp",
    "content": "//===------------------------ stdexcept.cpp -------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include \"__refstring\"\n#include \"stdexcept\"\n#include \"new\"\n#include <cstdlib>\n#include <cstring>\n#include <cstdint>\n#include <cstddef>\n\nstatic_assert(sizeof(std::__libcpp_refstring) == sizeof(const char *), \"\");\n\nnamespace std  // purposefully not using versioning namespace\n{\n\nlogic_error::~logic_error() _NOEXCEPT {}\n\nconst char*\nlogic_error::what() const _NOEXCEPT\n{\n    return __imp_.c_str();\n}\n\nruntime_error::~runtime_error() _NOEXCEPT {}\n\nconst char*\nruntime_error::what() const _NOEXCEPT\n{\n    return __imp_.c_str();\n}\n\ndomain_error::~domain_error() _NOEXCEPT {}\ninvalid_argument::~invalid_argument() _NOEXCEPT {}\nlength_error::~length_error() _NOEXCEPT {}\nout_of_range::~out_of_range() _NOEXCEPT {}\n\nrange_error::~range_error() _NOEXCEPT {}\noverflow_error::~overflow_error() _NOEXCEPT {}\nunderflow_error::~underflow_error() _NOEXCEPT {}\n\n}  // std\n"
  },
  {
    "path": "atlas-aapt/external/libcxxabi/src/typeinfo.cpp",
    "content": "//===----------------------------- typeinfo.cpp ---------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <typeinfo>\n\nnamespace std\n{\n\n// type_info\n\ntype_info::~type_info()\n{\n}\n\n// bad_cast\n\nbad_cast::bad_cast() _NOEXCEPT\n{\n}\n\nbad_cast::~bad_cast() _NOEXCEPT\n{\n}\n\nconst char*\nbad_cast::what() const _NOEXCEPT\n{\n  return \"std::bad_cast\";\n}\n\n// bad_typeid\n\nbad_typeid::bad_typeid() _NOEXCEPT\n{\n}\n\nbad_typeid::~bad_typeid() _NOEXCEPT\n{\n}\n\nconst char*\nbad_typeid::what() const _NOEXCEPT\n{\n  return \"std::bad_typeid\";\n}\n\n}  // std\n"
  },
  {
    "path": "atlas-aapt/external/libpng/ANNOUNCE",
    "content": "Libpng 1.6.22beta03 - February 19, 2016\n\nThis is not intended to be a public release.  It will be replaced\nwithin a few weeks by a public version or by another test version.\n\nFiles available for download:\n\nSource files with LF line endings (for Unix/Linux) and with a\n\"configure\" script\n\n   1.6.22beta03.tar.xz (LZMA-compressed, recommended)\n   1.6.22beta03.tar.gz\n\nSource files with CRLF line endings (for Windows), without the\n\"configure\" script\n\n   lp1622b03.7z  (LZMA-compressed, recommended)\n   lp1622b03.zip\n\nOther information:\n\n   1.6.22beta03-README.txt\n   1.6.22beta03-LICENSE.txt\n   libpng-1.6.22beta03-*.asc (armored detached GPG signatures)\n\nChanges since the last public release (1.6.21):\n\nVersion 1.6.22beta01 [January 23, 2016]\n  Changed PNG_USE_MKSTEMP to __COVERITY__ to select alternate\n    \"tmpfile()\" implementation in contrib/libtests/pngstest.c\n  Fixed NO_STDIO build of pngunknown.c to skip calling png_init_io()\n    if there is no stdio.h support.\n  Added a png_image_write_to_memory() API and a number of assist macros\n    to allow an application that uses the simplified API write to bypass\n    stdio and write directly to memory.\n  Added some warnings (png.h) and some check code to detect *possible*\n    overflow in the ROW_STRIDE and simplified image SIZE macros.  This\n    disallows image width/height/format that *might* overflow.  This is\n    a quiet API change that limits in-memory image size (uncompressed) to\n    less than 4GByte and image row size (stride) to less than 2GByte.\n  Revised workaround for false-positive Coverity issue in pngvalid.c.\n\nVersion 1.6.22beta02 [February 8, 2016]\n  Only use exit(77) in configure builds.\n  Corrected error in PNG_IMAGE_PNG_SIZE_MAX. This new macro underreported\n    the palette size because it failed to take into account that the memory\n    palette has to be expanded to full RGB when it is written to PNG.\n  Updated CMakeLists.txt, added supporting scripts/gen*.cmake.in\n    and test.cmake.in (Roger Leigh).\n  Relaxed limit checks on gamma values in pngrtran.c. As suggested in\n    the comments gamma values outside the range currently permitted\n    by png_set_alpha_mode are useful for HDR data encoding.  These values\n    are already permitted by png_set_gamma so it is reasonable caution to\n    extend the png_set_alpha_mode range as HDR imaging systems are starting\n    to emerge.\n\nVersion 1.6.22beta03 [February 19, 2016]\n  Added a common-law trademark notice and export control information\n    to the LICENSE file, png.h, and the man page.\n  Restored \"& 0xff\" in png_save_uint_16() and png_save_uint_32() that\n    were accidentally removed from libpng-1.6.17. \n  Changed PNG_INFO_cHNK and PNG_FREE_cHNK from 0xnnnn to 0xnnnnU in png.h\n    (Robert C. Seacord).\n  Removed dubious \"#if INT_MAX\" test from png.h that was added to\n    libpng-1.6.19beta02 (John Bowler).\n  Add ${INCLUDES} in scripts/genout.cmake.in (Bug report by Nixon Kwok).\n  Updated LICENSE to say files in the contrib directory are not\n    necessarily under the libpng license, and that some makefiles have\n    other copyright owners.\n\nSend comments/corrections/commendations to png-mng-implement at lists.sf.net\n(subscription required; visit\nhttps://lists.sourceforge.net/lists/listinfo/png-mng-implement\nto subscribe)\nor to glennrp at users.sourceforge.net\n\nGlenn R-P\n"
  },
  {
    "path": "atlas-aapt/external/libpng/Android.mk",
    "content": "LOCAL_PATH:= $(call my-dir)\n\n# We need to build this for both the device (as a shared library)\n# and the host (as a static library for tools to use).\n\ncommon_SRC_FILES := \\\n    png.c \\\n    pngerror.c \\\n    pngget.c \\\n    pngmem.c \\\n    pngpread.c \\\n    pngread.c \\\n    pngrio.c \\\n    pngrtran.c \\\n    pngrutil.c \\\n    pngset.c \\\n    pngtrans.c \\\n    pngwio.c \\\n    pngwrite.c \\\n    pngwtran.c \\\n    pngwutil.c \\\n\nifeq ($(ARCH_ARM_HAVE_NEON),true)\nmy_cflags_arm := -DPNG_ARM_NEON_OPT=2\nendif\n\nmy_cflags_arm64 := -DPNG_ARM_NEON_OPT=2\n\nmy_src_files_arm := \\\n    arm/arm_init.c \\\n    arm/filter_neon.S \\\n    arm/filter_neon_intrinsics.c\n\nmy_cflags_intel := -DPNG_INTEL_SSE_OPT=1\n\nmy_src_files_intel := \\\n    contrib/intel/intel_init.c \\\n    contrib/intel/filter_sse2_intrinsics.c\n\ncommon_CFLAGS := -std=gnu89 -Wno-unused-parameter #-fvisibility=hidden ## -fomit-frame-pointer\n\n# For the host\n# =====================================================\n\ninclude $(CLEAR_VARS)\nLOCAL_SRC_FILES := $(common_SRC_FILES)\nLOCAL_SRC_FILES_x86 += $(my_src_files_intel)\nLOCAL_SRC_FILES_x86_64 += $(my_src_files_intel)\nLOCAL_CFLAGS += $(common_CFLAGS)\n\n# Disable optimizations because they crash on windows\n# LOCAL_CFLAGS_x86 += $(my_cflags_intel)\n# LOCAL_CFLAGS_x86_64 += $(my_cflags_intel)\n\nLOCAL_ASFLAGS += $(common_ASFLAGS)\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)\nLOCAL_STATIC_LIBRARIES := libz\nLOCAL_MODULE:= libpng\nLOCAL_MODULE_HOST_OS := darwin linux windows\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\n\n# For the device (static) for NDK\n# =====================================================\n\ninclude $(CLEAR_VARS)\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := $(common_SRC_FILES)\nLOCAL_SRC_FILES_arm := $(my_src_files_arm)\nLOCAL_SRC_FILES_arm64 := $(my_src_files_arm)\nLOCAL_SRC_FILES_x86 += $(my_src_files_intel)\nLOCAL_SRC_FILES_x86_64 += $(my_src_files_intel)\nLOCAL_CFLAGS += $(common_CFLAGS) -ftrapv\nLOCAL_CFLAGS_arm := $(my_cflags_arm)\nLOCAL_CFLAGS_arm64 := $(my_cflags_arm64)\nLOCAL_CFLAGS_x86 += $(my_cflags_intel)\nLOCAL_CFLAGS_x86_64 += $(my_cflags_intel)\nLOCAL_ASFLAGS += $(common_ASFLAGS)\nLOCAL_SANITIZE := never\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)\nLOCAL_SHARED_LIBRARIES := libz\nLOCAL_MODULE:= libpng_ndk\nLOCAL_SDK_VERSION := 14\ninclude $(BUILD_STATIC_LIBRARY)\n\n# For the device (static) for platform (retains fortify support)\n# =====================================================\n\ninclude $(CLEAR_VARS)\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := $(common_SRC_FILES)\nLOCAL_SRC_FILES_arm := $(my_src_files_arm)\nLOCAL_SRC_FILES_arm64 := $(my_src_files_arm)\nLOCAL_SRC_FILES_x86 += $(my_src_files_intel)\nLOCAL_SRC_FILES_x86_64 += $(my_src_files_intel)\nLOCAL_CFLAGS += $(common_CFLAGS) -ftrapv\nLOCAL_CFLAGS_arm := $(my_cflags_arm)\nLOCAL_CFLAGS_arm64 := $(my_cflags_arm64)\nLOCAL_CFLAGS_x86 += $(my_cflags_intel)\nLOCAL_CFLAGS_x86_64 += $(my_cflags_intel)\nLOCAL_ASFLAGS += $(common_ASFLAGS)\nLOCAL_SANITIZE := never\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)\nLOCAL_SHARED_LIBRARIES := libz\nLOCAL_MODULE:= libpng\ninclude $(BUILD_STATIC_LIBRARY)\n\n# For the device (shared)\n# =====================================================\n\ninclude $(CLEAR_VARS)\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := $(common_SRC_FILES)\nLOCAL_SRC_FILES_arm := $(my_src_files_arm)\nLOCAL_SRC_FILES_arm64 := $(my_src_files_arm)\nLOCAL_SRC_FILES_x86 += $(my_src_files_intel)\nLOCAL_SRC_FILES_x86_64 += $(my_src_files_intel)\nLOCAL_CFLAGS += $(common_CFLAGS) -ftrapv\nLOCAL_CFLAGS_arm := $(my_cflags_arm)\nLOCAL_CFLAGS_arm64 := $(my_cflags_arm64)\nLOCAL_CFLAGS_x86 += $(my_cflags_intel)\nLOCAL_CFLAGS_x86_64 += $(my_cflags_intel)\nLOCAL_ASFLAGS += $(common_ASFLAGS)\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)\nLOCAL_SHARED_LIBRARIES := libz\nLOCAL_MODULE:= libpng\ninclude $(BUILD_SHARED_LIBRARY)\n\n# For testing\n# =====================================================\n\ninclude $(CLEAR_VARS)\nLOCAL_CLANG := true\nLOCAL_SRC_FILES:= pngtest.c\nLOCAL_MODULE := pngtest\nLOCAL_SHARED_LIBRARIES:= libpng libz\nLOCAL_MODULE_TAGS := debug\ninclude $(BUILD_EXECUTABLE)\n"
  },
  {
    "path": "atlas-aapt/external/libpng/CHANGES",
    "content": "#if 0\nCHANGES - changes for libpng\n\nversion 0.1 [March 29, 1995]\n  initial work-in-progress release\n\nversion 0.2 [April 1, 1995]\n  added reader into png.h\n  fixed small problems in stub file\n\nversion 0.3 [April 8, 1995]\n  added pull reader\n  split up pngwrite.c to several files\n  added pnglib.txt\n  added example.c\n  cleaned up writer, adding a few new transformations\n  fixed some bugs in writer\n  interfaced with zlib 0.5\n  added K&R support\n  added check for 64 KB blocks for 16 bit machines\n\nversion 0.4 [April 26, 1995]\n  cleaned up code and commented code\n  simplified time handling into png_time\n  created png_color_16 and png_color_8 to handle color needs\n  cleaned up color type defines\n  fixed various bugs\n  made various names more consistent\n  interfaced with zlib 0.71\n  cleaned up zTXt reader and writer (using zlib's Reset functions)\n  split transformations into pngrtran.c and pngwtran.c\n\nversion 0.5 [April 30, 1995]\n  interfaced with zlib 0.8\n  fixed many reading and writing bugs\n  saved using 3 spaces instead of tabs\n\nversion 0.6 [May 1, 1995]\n  first beta release\n  added png_large_malloc() and png_large_free()\n  added png_size_t\n  cleaned up some compiler warnings\n  added png_start_read_image()\n\nversion 0.7 [June 24, 1995]\n  cleaned up lots of bugs\n  finished dithering and other stuff\n  added test program\n  changed name from pnglib to libpng\n\nversion 0.71 [June 26, 1995]\n  changed pngtest.png for zlib 0.93\n  fixed error in libpng.txt and example.c\n\nversion 0.8 [August 20, 1995]\n  cleaned up some bugs\n  added png_set_filler()\n  split up pngstub.c into pngmem.c, pngio.c, and pngerror.c\n  added #define's to remove unwanted code\n  moved png_info_init() to png.c\n  added old_size into png_realloc()\n  added functions to manually set filtering and compression info\n  changed compression parameters based on image type\n  optimized filter selection code\n  added version info\n  changed external functions passing floats to doubles (k&r problems?)\n  put all the configurable stuff in pngconf.h\n  enabled png_set_shift to work with paletted images on read\n  added png_read_update_info() - updates info structure with transformations\n\nVersion 0.81 [August, 1995]\n  incorporated Tim Wegner's medium model code (thanks, Tim)\n\nVersion 0.82 [September, 1995]\n  [unspecified changes]\n\nVersion 0.85 [December, 1995]\n  added more medium model code (almost everything's a far)\n  added i/o, error, and memory callback functions\n  fixed some bugs (16-bit, 4-bit interlaced, etc.)\n  added first run progressive reader (barely tested)\n\nVersion 0.86 [January, 1996]\n  fixed bugs\n  improved documentation\n\nVersion 0.87 [January, 1996]\n  fixed medium model bugs\n  fixed other bugs introduced in 0.85 and 0.86\n  added some minor documentation\n\nVersion 0.88 [January, 1996]\n  fixed progressive bugs\n  replaced tabs with spaces\n  cleaned up documentation\n  added callbacks for read/write and warning/error functions\n\nVersion 0.89 [June 5, 1996]\n  Added new initialization API to make libpng work better with shared libs\n    we now have png_create_read_struct(), png_create_write_struct(),\n    png_create_info_struct(), png_destroy_read_struct(), and\n    png_destroy_write_struct() instead of the separate calls to\n    malloc and png_read_init(), png_info_init(), and png_write_init()\n  Changed warning/error callback functions to fix bug - this means you\n    should use the new initialization API if you were using the old\n    png_set_message_fn() calls, and that the old API no longer exists\n    so that people are aware that they need to change their code\n  Changed filter selection API to allow selection of multiple filters\n    since it didn't work in previous versions of libpng anyways\n  Optimized filter selection code\n  Fixed png_set_background() to allow using an arbitrary RGB color for\n    paletted images\n  Fixed gamma and background correction for paletted images, so\n    png_correct_palette is not needed unless you are correcting an\n    external palette (you will need to #define PNG_CORRECT_PALETTE_SUPPORTED\n    in pngconf.h) - if nobody uses this, it may disappear in the future.\n  Fixed bug with Borland 64K memory allocation (Alexander Lehmann)\n  Fixed bug in interlace handling (Smarasderagd, I think)\n  Added more error checking for writing and image to reduce invalid files\n  Separated read and write functions so that they won't both be linked\n    into a binary when only reading or writing functionality is used\n  New pngtest image also has interlacing and zTXt\n  Updated documentation to reflect new API\n\nVersion 0.89c [June 17, 1996]\n  Bug fixes.\n\nVersion 0.90 [January, 1997]\n  Made CRC errors/warnings on critical and ancillary chunks configurable\n  libpng will use the zlib CRC routines by (compile-time) default\n  Changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner)\n  Added external C++ wrapper statements to png.h (Gilles Dauphin)\n  Allow PNG file to be read when some or all of file signature has already\n    been read from the beginning of the stream.  ****This affects the size\n    of info_struct and invalidates all programs that use a shared libpng****\n  Fixed png_filler() declarations\n  Fixed? background color conversions\n  Fixed order of error function pointers to match documentation\n  Current chunk name is now available in png_struct to reduce the number\n    of nearly identical error messages (will simplify multi-lingual\n    support when available)\n  Try to get ready for unknown-chunk callback functions:\n    - previously read critical chunks are flagged, so the chunk handling\n      routines can determine if the chunk is in the right place\n    - all chunk handling routines have the same prototypes, so we will\n      be able to handle all chunks via a callback mechanism\n  Try to fix Linux \"setjmp\" buffer size problems\n  Removed png_large_malloc, png_large_free, and png_realloc functions.\n\nVersion 0.95 [March, 1997]\n  Fixed bug in pngwutil.c allocating \"up_row\" twice and \"avg_row\" never\n  Fixed bug in PNG file signature compares when start != 0\n  Changed parameter type of png_set_filler(...filler...) from png_byte\n    to png_uint_32\n  Added test for MACOS to ensure that both math.h and fp.h are not #included\n  Added macros for libpng to be compiled as a Windows DLL (Andreas Kupries)\n  Added \"packswap\" transformation, which changes the endianness of\n    packed-pixel bytes (Kevin Bracey)\n  Added \"strip_alpha\" transformation, which removes the alpha channel of\n    input images without using it (not necessarily a good idea)\n  Added \"swap_alpha\" transformation, which puts the alpha channel in front\n    of the color bytes instead of after\n  Removed all implicit variable tests which assume NULL == 0 (I think)\n  Changed several variables to \"png_size_t\" to show 16/32-bit limitations\n  Added new pCAL chunk read/write support\n  Added experimental filter selection weighting (Greg Roelofs)\n  Removed old png_set_rgbx() and png_set_xrgb() functions that have been\n    obsolete for about 2 years now (use png_set_filler() instead)\n  Added macros to read 16- and 32-bit ints directly from buffer, to be\n    used only on those systems that support it (namely PowerPC and 680x0)\n    With some testing, this may become the default for MACOS/PPC systems.\n  Only calculate CRC on data if we are going to use it\n  Added macros for zTXt compression type PNG_zTXt_COMPRESSION_???\n  Added macros for simple libpng debugging output selectable at compile time\n  Removed PNG_READ_END_MODE in progressive reader (Smarasderagd)\n  More description of info_struct in libpng.txt and png.h\n  More instructions in example.c\n  More chunk types tested in pngtest.c\n  Renamed pngrcb.c to pngset.c, and all png_read_<chunk> functions to be\n    png_set_<chunk>.  We now have corresponding png_get_<chunk>\n    functions in pngget.c to get information in info_ptr.  This isolates\n    the application from the internal organization of png_info_struct\n    (good for shared library implementations).\n\nVersion 0.96 [May, 1997]\n  Fixed serious bug with < 8bpp images introduced in 0.95\n  Fixed 256-color transparency bug (Greg Roelofs)\n  Fixed up documentation (Greg Roelofs, Laszlo Nyul)\n  Fixed \"error\" in pngconf.h for Linux setjmp() behavior\n  Fixed DOS medium model support (Tim Wegner)\n  Fixed png_check_keyword() for case with error in static string text\n  Added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul)\n  Added typecasts to quiet compiler errors\n  Added more debugging info\n\nVersion 0.97 [January, 1998]\n  Removed PNG_USE_OWN_CRC capability\n  Relocated png_set_crc_action from pngrutil.c to pngrtran.c\n  Fixed typecasts of \"new_key\", etc. (Andreas Dilger)\n  Added RFC 1152 [sic] date support\n  Fixed bug in gamma handling of 4-bit grayscale\n  Added 2-bit grayscale gamma handling (Glenn R-P)\n  Added more typecasts. 65536L becomes (png_uint_32)65536L, etc. (Glenn R-P)\n  Minor corrections in libpng.txt\n  Added simple sRGB support (Glenn R-P)\n  Easier conditional compiling, e.g.,\n    define PNG_READ/WRITE_NOT_FULLY_SUPPORTED;\n    all configurable options can be selected from command-line instead\n    of having to edit pngconf.h (Glenn R-P)\n  Fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P)\n  Added more conditions for png_do_background, to avoid changing\n    black pixels to background when a background is supplied and\n    no pixels are transparent\n  Repaired PNG_NO_STDIO behavior\n  Tested NODIV support and made it default behavior (Greg Roelofs)\n  Added \"-m\" option and PNGTEST_DEBUG_MEMORY to pngtest (John Bowler)\n  Regularized version numbering scheme and bumped shared-library major\n    version number to 2 to avoid problems with libpng 0.89 apps\n    (Greg Roelofs)\n\nVersion 0.98 [January, 1998]\n  Cleaned up some typos in libpng.txt and in code documentation\n  Fixed memory leaks in pCAL chunk processing (Glenn R-P and John Bowler)\n  Cosmetic change \"display_gamma\" to \"screen_gamma\" in pngrtran.c\n  Changed recommendation about file_gamma for PC images to .51 from .45,\n    in example.c and libpng.txt, added comments to distinguish between\n    screen_gamma, viewing_gamma, and display_gamma.\n  Changed all references to RFC1152 to read RFC1123 and changed the\n    PNG_TIME_RFC1152_SUPPORTED macro to PNG_TIME_RFC1123_SUPPORTED\n  Added png_invert_alpha capability (Glenn R-P -- suggestion by Jon Vincent)\n  Changed srgb_intent from png_byte to int to avoid compiler bugs\n\nVersion 0.99 [January 30, 1998]\n  Free info_ptr->text instead of end_info_ptr->text in pngread.c (John Bowler)\n  Fixed a longstanding \"packswap\" bug in pngtrans.c\n  Fixed some inconsistencies in pngconf.h that prevented compiling with\n    PNG_READ_GAMMA_SUPPORTED and PNG_READ_hIST_SUPPORTED undefined\n  Fixed some typos and made other minor rearrangement of libpng.txt (Andreas)\n  Changed recommendation about file_gamma for PC images to .50 from .51 in\n    example.c and libpng.txt, and changed file_gamma for sRGB images to .45\n  Added a number of functions to access information from the png structure\n    png_get_image_height(), etc. (Glenn R-P, suggestion by Brad Pettit)\n  Added TARGET_MACOS similar to zlib-1.0.8\n  Define PNG_ALWAYS_EXTERN when __MWERKS__ && WIN32 are defined\n  Added type casting to all png_malloc() function calls\n\nVersion 0.99a [January 31, 1998]\n  Added type casts and parentheses to all returns that return a value.(Tim W.)\n\nVersion 0.99b [February 4, 1998]\n  Added type cast png_uint_32 on malloc function calls where needed.\n  Changed type of num_hist from png_uint_32 to int (same as num_palette).\n  Added checks for rowbytes overflow, in case png_size_t is less than 32 bits.\n  Renamed makefile.elf to makefile.lnx.\n\nVersion 0.99c [February 7, 1998]\n  More type casting.  Removed erroneous overflow test in pngmem.c.\n  Added png_buffered_memcpy() and png_buffered_memset(), apply them to rowbytes.\n  Added UNIX manual pages libpng.3 (incorporating libpng.txt) and  png.5.\n\nVersion 0.99d [February 11, 1998]\n  Renamed \"far_to_near()\" \"png_far_to_near()\"\n  Revised libpng.3\n  Version 99c \"buffered\" operations didn't work as intended.  Replaced them\n    with png_memcpy_check() and png_memset_check().\n  Added many \"if (png_ptr == NULL) return\" to quell compiler warnings about\n    unused png_ptr, mostly in pngget.c and pngset.c.\n  Check for overlength tRNS chunk present when indexed-color PLTE is read.\n  Cleaned up spelling errors in libpng.3/libpng.txt\n  Corrected a problem with png_get_tRNS() which returned undefined trans array\n\nVersion 0.99e [February 28, 1998]\n  Corrected png_get_tRNS() again.\n  Add parentheses for easier reading of pngget.c, fixed \"||\" should be \"&&\".\n  Touched up example.c to make more of it compileable, although the entire\n    file still can't be compiled (Willem van Schaik)\n  Fixed a bug in png_do_shift() (Bryan Tsai)\n  Added a space in png.h prototype for png_write_chunk_start()\n  Replaced pngtest.png with one created with zlib 1.1.1\n  Changed pngtest to report PASS even when file size is different (Jean-loup G.)\n  Corrected some logic errors in png_do_invert_alpha() (Chris Patterson)\n\nVersion 0.99f [March 5, 1998]\n  Corrected a bug in pngpread() introduced in version 99c (Kevin Bracey)\n  Moved makefiles into a \"scripts\" directory, and added INSTALL instruction file\n  Added makefile.os2 and pngos2.def (A. Zabolotny) and makefile.s2x (W. Sebok)\n  Added pointers to \"note on libpng versions\" in makefile.lnx and README\n  Added row callback feature when reading and writing nonprogressive rows\n    and added a test of this feature in pngtest.c\n  Added user transform callbacks, with test of the feature in pngtest.c\n\nVersion 0.99g [March 6, 1998, morning]\n  Minor changes to pngtest.c to suppress compiler warnings.\n  Removed \"beta\" language from documentation.\n\nVersion 0.99h [March 6, 1998, evening]\n  Minor changes to previous minor changes to pngtest.c\n  Changed PNG_READ_NOT_FULLY_SUPPORTED to PNG_READ_TRANSFORMS_NOT_SUPPORTED\n    and added PNG_PROGRESSIVE_READ_NOT_SUPPORTED macro\n  Added user transform capability\n\nVersion 1.00 [March 7, 1998]\n  Changed several typedefs in pngrutil.c\n  Added makefile.wat (Pawel Mrochen), updated makefile.tc3 (Willem van Schaik)\n  Replaced \"while(1)\" with \"for(;;)\"\n  Added PNGARG() to prototypes in pngtest.c and removed some prototypes\n  Updated some of the makefiles (Tom Lane)\n  Changed some typedefs (s_start, etc.) in pngrutil.c\n  Fixed dimensions of \"short_months\" array in pngwrite.c\n  Replaced ansi2knr.c with the one from jpeg-v6\n\nVersion 1.0.0 [March 8, 1998]\n  Changed name from 1.00 to 1.0.0 (Adam Costello)\n  Added smakefile.ppc (with SCOPTIONS.ppc) for Amiga PPC (Andreas Kleinert)\n\nVersion 1.0.0a [March 9, 1998]\n  Fixed three bugs in pngrtran.c to make gamma+background handling consistent\n    (Greg Roelofs)\n  Changed format of the PNG_LIBPNG_VER integer to xyyzz instead of xyz\n    for major, minor, and bugfix releases.  This is 10001. (Adam Costello,\n    Tom Lane)\n  Make months range from 1-12 in png_convert_to_rfc1123\n\nVersion 1.0.0b [March 13, 1998]\n  Quieted compiler complaints about two empty \"for\" loops in pngrutil.c\n  Minor changes to makefile.s2x\n  Removed #ifdef/#endif around a png_free() in pngread.c\n\nVersion 1.0.1 [March 14, 1998]\n  Changed makefile.s2x to reduce security risk of using a relative pathname\n  Fixed some typos in the documentation (Greg).\n  Fixed a problem with value of \"channels\" returned by png_read_update_info()\n\nVersion 1.0.1a [April 21, 1998]\n  Optimized Paeth calculations by replacing abs() function calls with intrinsics\n  plus other loop optimizations. Improves avg decoding speed by about 20%.\n  Commented out i386istic \"align\" compiler flags in makefile.lnx.\n  Reduced the default warning level in some makefiles, to make them consistent.\n  Removed references to IJG and JPEG in the ansi2knr.c copyright statement.\n  Fixed a bug in png_do_strip_filler with XXRRGGBB => RRGGBB transformation.\n  Added grayscale and 16-bit capability to png_do_read_filler().\n  Fixed a bug in pngset.c, introduced in version 0.99c, that sets rowbytes\n    too large when writing an image with bit_depth < 8 (Bob Dellaca).\n  Corrected some bugs in the experimental weighted filtering heuristics.\n  Moved a misplaced pngrutil code block that truncates tRNS if it has more\n    than num_palette entries -- test was done before num_palette was defined.\n  Fixed a png_convert_to_rfc1123() bug that converts day 31 to 0 (Steve Eddins).\n  Changed compiler flags in makefile.wat for better optimization\n    (Pawel Mrochen).\n\nVersion 1.0.1b [May 2, 1998]\n  Relocated png_do_gray_to_rgb() within png_do_read_transformations() (Greg).\n  Relocated the png_composite macros from pngrtran.c to png.h (Greg).\n  Added makefile.sco (contributed by Mike Hopkirk).\n  Fixed two bugs (missing definitions of \"istop\") introduced in libpng-1.0.1a.\n  Fixed a bug in pngrtran.c that would set channels=5 under some circumstances.\n  More work on the Paeth-filtering, achieving imperceptible speedup\n    (A Kleinert).\n  More work on loop optimization which may help when compiled with C++\n    compilers.\n  Added warnings when people try to use transforms they've defined out.\n  Collapsed 4 \"i\" and \"c\" loops into single \"i\" loops in pngrtran and pngwtran.\n  Revised paragraph about png_set_expand() in libpng.txt and libpng.3 (Greg)\n\nVersion 1.0.1c [May 11, 1998]\n  Fixed a bug in pngrtran.c (introduced in libpng-1.0.1a) where the masks for\n    filler bytes should have been 0xff instead of 0xf.\n  Added max_pixel_depth=32 in pngrutil.c when using FILLER with palette images.\n  Moved PNG_WRITE_WEIGHTED_FILTER_SUPPORTED and PNG_WRITE_FLUSH_SUPPORTED\n    out of the PNG_WRITE_TRANSFORMS_NOT_SUPPORTED block of pngconf.h\n  Added \"PNG_NO_WRITE_TRANSFORMS\" etc., as alternatives for *_NOT_SUPPORTED,\n    for consistency, in pngconf.h\n  Added individual \"ifndef PNG_NO_[CAPABILITY]\" in pngconf.h to make it easier\n    to remove unwanted capabilities via the compile line\n  Made some corrections to grammar (which, it's) in documentation (Greg).\n  Corrected example.c, use of row_pointers in png_write_image().\n\nVersion 1.0.1d [May 24, 1998]\n  Corrected several statements that used side effects illegally in pngrutil.c\n    and pngtrans.c, that were introduced in version 1.0.1b\n  Revised png_read_rows() to avoid repeated if-testing for NULL (A Kleinert)\n  More corrections to example.c, use of row_pointers in png_write_image()\n    and png_read_rows().\n  Added pngdll.mak and pngdef.pas to scripts directory, contributed by\n    Bob Dellaca, to make a png32bd.dll with Borland C++ 4.5\n  Fixed error in example.c with png_set_text: num_text is 3, not 2 (Guido V.)\n  Changed several loops from count-down to count-up, for consistency.\n\nVersion 1.0.1e [June 6, 1998]\n  Revised libpng.txt and libpng.3 description of png_set_read|write_fn(), and\n    added warnings when people try to set png_read_fn and png_write_fn in\n    the same structure.\n  Added a test such that png_do_gamma will be done when num_trans==0\n    for truecolor images that have defined a background.  This corrects an\n    error that was introduced in libpng-0.90 that can cause gamma processing\n    to be skipped.\n  Added tests in png.h to include \"trans\" and \"trans_values\" in structures\n    when PNG_READ_BACKGROUND_SUPPORTED or PNG_READ_EXPAND_SUPPORTED is defined.\n  Add png_free(png_ptr->time_buffer) in png_destroy_read_struct()\n  Moved png_convert_to_rfc_1123() from pngwrite.c to png.c\n  Added capability for user-provided malloc_fn() and free_fn() functions,\n    and revised pngtest.c to demonstrate their use, replacing the\n    PNGTEST_DEBUG_MEM feature.\n  Added makefile.w32, for Microsoft C++ 4.0 and later (Tim Wegner).\n\nVersion 1.0.2 [June 14, 1998]\n  Fixed two bugs in makefile.bor .\n\nVersion 1.0.2a [December 30, 1998]\n  Replaced and extended code that was removed from png_set_filler() in 1.0.1a.\n  Fixed a bug in png_do_filler() that made it fail to write filler bytes in\n    the left-most pixel of each row (Kevin Bracey).\n  Changed \"static pngcharp tIME_string\" to \"static char tIME_string[30]\"\n    in pngtest.c (Duncan Simpson).\n  Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk\n    even when no tIME chunk was present in the source file.\n  Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit.\n  Fixed a problem in png_read_push_finish_row(), which would not skip some\n    passes that it should skip, for images that are less than 3 pixels high.\n  Interchanged the order of calls to png_do_swap() and png_do_shift()\n    in pngwtran.c (John Cromer).\n  Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h .\n  Changed \"bad adaptive filter type\" from error to warning in pngrutil.c .\n  Fixed a documentation error about default filtering with 8-bit indexed-color.\n  Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO\n    (L. Peter Deutsch).\n  Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions.\n  Added png_get_copyright() and png_get_header_version() functions.\n  Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c\n  Added information about debugging in libpng.txt and libpng.3 .\n  Changed \"ln -sf\" to \"ln -s -f\" in makefile.s2x, makefile.lnx, and\n    makefile.sco.\n  Removed lines after Dynamic Dependencies\" in makefile.aco .\n  Revised makefile.dec to make a shared library (Jeremie Petit).\n  Removed trailing blanks from all files.\n\nVersion 1.0.2a [January 6, 1999]\n  Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h\n  Added \"if\" tests to silence complaints about unused png_ptr in png.h and png.c\n  Changed \"check_if_png\" function in example.c to return true (nonzero) if PNG.\n  Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig()\n    which is obsolete.\n\nVersion 1.0.3 [January 14, 1999]\n  Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice)\n  Added a statement of Y2K compliance in png.h, libpng.3, and Y2KINFO.\n\nVersion 1.0.3a [August 12, 1999]\n  Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning\n    if an attempt is made to read an interlaced image when it's not supported.\n  Added check if png_ptr->trans is defined before freeing it in pngread.c\n  Modified the Y2K statement to include versions back to version 0.71\n  Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c\n  Modified makefile.wat (added -zp8 flag, \".symbolic\", changed some comments)\n  Replaced leading blanks with tab characters in makefile.hux\n  Changed \"dworkin.wustl.edu\" to \"ccrc.wustl.edu\" in various documents.\n  Changed (float)red and (float)green to (double)red, (double)green\n    in png_set_rgb_to_gray() to avoid \"promotion\" problems in AIX.\n  Fixed a bug in pngconf.h that omitted <stdio.h> when PNG_DEBUG==0 (K Bracey).\n  Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt).\n  Updated documentation to refer to the PNG-1.2 specification.\n  Removed ansi2knr.c and left pointers to the latest source for ansi2knr.c\n    in makefile.knr, INSTALL, and README (L. Peter Deutsch)\n  Fixed bugs in calculation of the length of rowbytes when adding alpha\n    channels to 16-bit images, in pngrtran.c (Chris Nokleberg)\n  Added function png_set_user_transform_info() to store user_transform_ptr,\n    user_depth, and user_channels into the png_struct, and a function\n    png_get_user_transform_ptr() to retrieve the pointer (Chris Nokleberg)\n  Added function png_set_empty_plte_permitted() to make libpng useable\n    in MNG applications.\n  Corrected the typedef for png_free_ptr in png.h (Jesse Jones).\n  Correct gamma with srgb is 45455 instead of 45000 in pngrutil.c, to be\n    consistent with PNG-1.2, and allow variance of 500 before complaining.\n  Added assembler code contributed by Intel in file pngvcrd.c and modified\n    makefile.w32 to use it (Nirav Chhatrapati, INTEL Corporation,\n    Gilles Vollant)\n  Changed \"ln -s -f\" to \"ln -f -s\" in the makefiles to make Solaris happy.\n  Added some aliases for png_set_expand() in pngrtran.c, namely\n    png_set_expand_PLTE(), png_set_expand_depth(), and png_set_expand_tRNS()\n    (Greg Roelofs, in \"PNG: The Definitive Guide\").\n  Added makefile.beo for BEOS on X86, contributed by Sander Stok.\n\nVersion 1.0.3b [August 26, 1999]\n  Replaced 2147483647L several places with PNG_MAX_UINT macro, defined in png.h\n  Changed leading blanks to tabs in all makefiles.\n  Define PNG_USE_PNGVCRD in makefile.w32, to get MMX assembler code.\n  Made alternate versions of  png_set_expand() in pngrtran.c, namely\n    png_set_gray_1_2_4_to_8, png_set_palette_to_rgb, and png_set_tRNS_to_alpha\n    (Greg Roelofs, in \"PNG: The Definitive Guide\").  Deleted the 1.0.3a aliases.\n  Relocated start of 'extern \"C\"' block in png.h so it doesn't include pngconf.h\n  Revised calculation of num_blocks in pngmem.c to avoid a potentially\n    negative shift distance, whose results are undefined in the C language.\n  Added a check in pngset.c to prevent writing multiple tIME chunks.\n  Added a check in pngwrite.c to detect invalid small window_bits sizes.\n\nVersion 1.0.3d [September 4, 1999]\n  Fixed type casting of igamma in pngrutil.c\n  Added new png_expand functions to scripts/pngdef.pas and pngos2.def\n  Added a demo read_user_transform_fn that examines the row filters in pngtest.c\n\nVersion 1.0.4 [September 24, 1999, not distributed publicly]\n  Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined\n  Delete #define PNG_INTERNAL and include \"png.h\" from pngasmrd.h\n  Made several minor corrections to pngtest.c\n  Renamed the makefiles with longer but more user friendly extensions.\n  Copied the PNG copyright and license to a separate LICENSE file.\n  Revised documentation, png.h, and example.c to remove reference to\n    \"viewing_gamma\" which no longer appears in the PNG specification.\n  Revised pngvcrd.c to use MMX code for interlacing only on the final pass.\n  Updated pngvcrd.c to use the faster C filter algorithms from libpng-1.0.1a\n  Split makefile.win32vc into two versions, makefile.vcawin32 (uses MMX\n    assembler code) and makefile.vcwin32 (doesn't).\n  Added a CPU timing report to pngtest.c (enabled by defining PNGTEST_TIMING)\n  Added a copy of pngnow.png to the distribution.\n\nVersion 1.0.4a [September 25, 1999]\n  Increase max_pixel_depth in pngrutil.c if a user transform needs it.\n  Changed several division operations to right-shifts in pngvcrd.c\n\nVersion 1.0.4b [September 30, 1999]\n  Added parentheses in line 3732 of pngvcrd.c\n  Added a comment in makefile.linux warning about buggy -O3 in pgcc 2.95.1\n\nVersion 1.0.4c [October 1, 1999]\n  Added a \"png_check_version\" function in png.c and pngtest.c that will generate\n    a helpful compiler error if an old png.h is found in the search path.\n  Changed type of png_user_transform_depth|channels from int to png_byte.\n  Added \"Libpng is OSI Certified Open Source Software\" statement to png.h\n\nVersion 1.0.4d [October 6, 1999]\n  Changed 0.45 to 0.45455 in png_set_sRGB()\n  Removed unused PLTE entries from pngnow.png\n  Re-enabled some parts of pngvcrd.c (png_combine_row) that work properly.\n\nVersion 1.0.4e [October 10, 1999]\n  Fixed sign error in pngvcrd.c (Greg Roelofs)\n  Replaced some instances of memcpy with simple assignments in pngvcrd (GR-P)\n\nVersion 1.0.4f [October 15, 1999]\n  Surrounded example.c code with #if 0 .. #endif to prevent people from\n    inadvertently trying to compile it.\n  Changed png_get_header_version() from a function to a macro in png.h\n  Added type casting mostly in pngrtran.c and pngwtran.c\n  Removed some pointless \"ptr = NULL\" in pngmem.c\n  Added a \"contrib\" directory containing the source code from Greg's book.\n\nVersion 1.0.5 [October 15, 1999]\n  Minor editing of the INSTALL and README files.\n\nVersion 1.0.5a [October 23, 1999]\n  Added contrib/pngsuite and contrib/pngminus (Willem van Schaik)\n  Fixed a typo in the png_set_sRGB() function call in example.c (Jan Nijtmans)\n  Further optimization and bugfix of pngvcrd.c\n  Revised pngset.c so that it does not allocate or free memory in the user's\n    text_ptr structure.  Instead, it makes its own copy.\n  Created separate write_end_info_struct in pngtest.c for a more severe test.\n  Added code in pngwrite.c to free info_ptr->text[i].key to stop a memory leak.\n\nVersion 1.0.5b [November 23, 1999]\n  Moved PNG_FLAG_HAVE_CHUNK_HEADER, PNG_FLAG_BACKGROUND_IS_GRAY and\n    PNG_FLAG_WROTE_tIME from flags to mode.\n  Added png_write_info_before_PLTE() function.\n  Fixed some typecasting in contrib/gregbook/*.c\n  Updated scripts/makevms.com and added makevms.com to contrib/gregbook\n    and contrib/pngminus (Martin Zinser)\n\nVersion 1.0.5c [November 26, 1999]\n  Moved png_get_header_version from png.h to png.c, to accommodate ansi2knr.\n  Removed all global arrays (according to PNG_NO_GLOBAL_ARRAYS macro), to\n    accommodate making DLL's: Moved usr_png_ver from global variable to function\n    png_get_header_ver() in png.c.  Moved png_sig to png_sig_bytes in png.c and\n    eliminated use of png_sig in pngwutil.c.  Moved the various png_CHNK arrays\n    into pngtypes.h.  Eliminated use of global png_pass arrays.  Declared the\n    png_CHNK and png_pass arrays to be \"const\".  Made the global arrays\n    available to applications (although none are used in libpng itself) when\n    PNG_NO_GLOBAL_ARRAYS is not defined or when PNG_GLOBAL_ARRAYS is defined.\n  Removed some extraneous \"-I\" from contrib/pngminus/makefile.std\n  Changed the PNG_sRGB_INTENT macros in png.h to be consistent with PNG-1.2.\n  Change PNG_SRGB_INTENT to PNG_sRGB_INTENT in libpng.txt and libpng.3\n\nVersion 1.0.5d [November 29, 1999]\n  Add type cast (png_const_charp) two places in png.c\n  Eliminated pngtypes.h; use macros instead to declare PNG_CHNK arrays.\n  Renamed \"PNG_GLOBAL_ARRAYS\" to \"PNG_USE_GLOBAL_ARRAYS\" and made available\n    to applications a macro \"PNG_USE_LOCAL_ARRAYS\".\n  comment out (with #ifdef) all the new declarations when\n    PNG_USE_GLOBAL_ARRAYS is defined.\n  Added PNG_EXPORT_VAR macro to accommodate making DLL's.\n\nVersion 1.0.5e [November 30, 1999]\n  Added iCCP, iTXt, and sPLT support; added \"lang\" member to the png_text\n    structure; refactored the inflate/deflate support to make adding new chunks\n    with trailing compressed parts easier in the future, and added new functions\n    png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP,\n    png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond).\n  NOTE: Applications that write text chunks MUST define png_text->lang\n    before calling png_set_text(). It must be set to NULL if you want to\n    write tEXt or zTXt chunks.  If you want your application to be able to\n    run with older versions of libpng, use\n\n      #ifdef PNG_iTXt_SUPPORTED\n         png_text[i].lang = NULL;\n      #endif\n\n  Changed png_get_oFFs() and png_set_oFFs() to use signed rather than unsigned\n    offsets (Eric S. Raymond).\n  Combined PNG_READ_cHNK_SUPPORTED and PNG_WRITE_cHNK_SUPPORTED macros into\n    PNG_cHNK_SUPPORTED and combined the three types of PNG_text_SUPPORTED\n    macros, leaving the separate macros also available.\n  Removed comments on #endifs at the end of many short, non-nested #if-blocks.\n\nVersion 1.0.5f [December 6, 1999]\n  Changed makefile.solaris to issue a warning about potential problems when\n    the ucb \"ld\" is in the path ahead of the ccs \"ld\".\n  Removed \"- [date]\" from the \"synopsis\" line in libpng.3 and libpngpf.3.\n  Added sCAL chunk support (Eric S. Raymond).\n\nVersion 1.0.5g [December 7, 1999]\n  Fixed \"png_free_spallettes\" typo in png.h\n  Added code to handle new chunks in pngpread.c\n  Moved PNG_CHNK string macro definitions outside of PNG_NO_EXTERN block\n  Added \"translated_key\" to png_text structure and png_write_iTXt().\n  Added code in pngwrite.c to work around a newly discovered zlib bug.\n\nVersion 1.0.5h [December 10, 1999]\n  NOTE: regarding the note for version 1.0.5e, the following must also\n    be included in your code:\n        png_text[i].translated_key = NULL;\n  Unknown chunk handling is now supported.\n  Option to eliminate all floating point support was added.  Some new\n    fixed-point functions such as png_set_gAMA_fixed() were added.\n  Expanded tabs and removed trailing blanks in source files.\n\nVersion 1.0.5i [December 13, 1999]\n  Added some type casts to silence compiler warnings.\n  Renamed \"png_free_spalette\" to \"png_free_spalettes\" for consistency.\n  Removed leading blanks from a #define in pngvcrd.c\n  Added some parameters to the new png_set_keep_unknown_chunks() function.\n  Added a test for up->location != 0 in the first instance of writing\n    unknown chunks in pngwrite.c\n  Changed \"num\" to \"i\" in png_free_spalettes() and png_free_unknowns() to\n    prevent recursion.\n  Added png_free_hIST() function.\n  Various patches to fix bugs in the sCAL and integer cHRM processing,\n    and to add some convenience macros for use with sCAL.\n\nVersion 1.0.5j [December 21, 1999]\n  Changed \"unit\" parameter of png_write_sCAL from png_byte to int, to work\n    around buggy compilers.\n  Added new type \"png_fixed_point\" for integers that hold float*100000 values\n  Restored backward compatibility of tEXt/zTXt chunk processing:\n    Restored the first four members of png_text to the same order as v.1.0.5d.\n    Added members \"lang_key\" and \"itxt_length\" to png_text struct.  Set\n    text_length=0 when \"text\" contains iTXt data.  Use the \"compression\"\n    member to distinguish among tEXt/zTXt/iTXt types.  Added\n    PNG_ITXT_COMPRESSION_NONE (1) and PNG_ITXT_COMPRESSION_zTXt(2) macros.\n    The \"Note\" above, about backward incompatibility of libpng-1.0.5e, no\n    longer applies.\n  Fixed png_read|write_iTXt() to read|write parameters in the right order,\n    and to write the iTXt chunk after IDAT if it appears in the end_ptr.\n  Added pnggccrd.c, version of pngvcrd.c Intel assembler for gcc (Greg Roelofs)\n  Reversed the order of trying to write floating-point and fixed-point gAMA.\n\nVersion 1.0.5k [December 27, 1999]\n  Added many parentheses, e.g., \"if (a && b & c)\" becomes \"if (a && (b & c))\"\n  Added png_handle_as_unknown() function (Glenn)\n  Added png_free_chunk_list() function and chunk_list and num_chunk_list members\n    of png_ptr.\n  Eliminated erroneous warnings about multiple sPLT chunks and sPLT-after-PLTE.\n  Fixed a libpng-1.0.5h bug in pngrutil.c that was issuing erroneous warnings\n    about ignoring incorrect gAMA with sRGB (gAMA was in fact not ignored)\n  Added png_free_tRNS(); png_set_tRNS() now malloc's its own trans array (ESR).\n  Define png_get_int_32 when oFFs chunk is supported as well as when pCAL is.\n  Changed type of proflen from png_int_32 to png_uint_32 in png_get_iCCP().\n\nVersion 1.0.5l [January 1, 2000]\n  Added functions png_set_read_user_chunk_fn() and png_get_user_chunk_ptr()\n    for setting a callback function to handle unknown chunks and for\n    retrieving the associated user pointer (Glenn).\n\nVersion 1.0.5m [January 7, 2000]\n  Added high-level functions png_read_png(), png_write_png(), png_free_pixels().\n\nVersion 1.0.5n [January 9, 2000]\n  Added png_free_PLTE() function, and modified png_set_PLTE() to malloc its\n    own memory for info_ptr->palette.  This makes it safe for the calling\n    application to free its copy of the palette any time after it calls\n    png_set_PLTE().\n\nVersion 1.0.5o [January 20, 2000]\n  Cosmetic changes only (removed some trailing blanks and TABs)\n\nVersion 1.0.5p [January 31, 2000]\n  Renamed pngdll.mak to makefile.bd32\n  Cosmetic changes in pngtest.c\n\nVersion 1.0.5q [February 5, 2000]\n  Relocated the makefile.solaris warning about PATH problems.\n  Fixed pngvcrd.c bug by pushing/popping registers in mmxsupport (Bruce Oberg)\n  Revised makefile.gcmmx\n  Added PNG_SETJMP_SUPPORTED, PNG_SETJMP_NOT_SUPPORTED, and PNG_ABORT() macros\n\nVersion 1.0.5r [February 7, 2000]\n  Removed superfluous prototype for png_get_itxt from png.h\n  Fixed a bug in pngrtran.c that improperly expanded the background color.\n  Return *num_text=0 from png_get_text() when appropriate, and fix documentation\n    of png_get_text() in libpng.txt/libpng.3.\n\nVersion 1.0.5s [February 18, 2000]\n  Added \"png_jmp_env()\" macro to pngconf.h, to help people migrate to the\n    new error handler that's planned for the next libpng release, and changed\n    example.c, pngtest.c, and contrib programs to use this macro.\n  Revised some of the DLL-export macros in pngconf.h (Greg Roelofs)\n  Fixed a bug in png_read_png() that caused it to fail to expand some images\n    that it should have expanded.\n  Fixed some mistakes in the unused and undocumented INCH_CONVERSIONS functions\n    in pngget.c\n  Changed the allocation of palette, history, and trans arrays back to\n    the version 1.0.5 method (linking instead of copying) which restores\n    backward compatibility with version 1.0.5.  Added some remarks about\n    that in example.c.  Added \"free_me\" member to info_ptr and png_ptr\n    and added png_free_data() function.\n  Updated makefile.linux and makefile.gccmmx to make directories conditionally.\n  Made cosmetic changes to pngasmrd.h\n  Added png_set_rows() and png_get_rows(), for use with png_read|write_png().\n  Modified png_read_png() to allocate info_ptr->row_pointers only if it\n    hasn't already been allocated.\n\nVersion 1.0.5t [March 4, 2000]\n  Changed png_jmp_env() migration aiding macro to png_jmpbuf().\n  Fixed \"interlace\" typo (should be \"interlaced\") in contrib/gregbook/read2-x.c\n  Fixed bug with use of PNG_BEFORE_IHDR bit in png_ptr->mode, introduced when\n    PNG_FLAG_HAVE_CHUNK_HEADER was moved into png_ptr->mode in version 1.0.5b\n  Files in contrib/gregbook were revised to use png_jmpbuf() and to select\n    a 24-bit visual if one is available, and to allow abbreviated options.\n  Files in contrib/pngminus were revised to use the png_jmpbuf() macro.\n  Removed spaces in makefile.linux and makefile.gcmmx, introduced in 1.0.5s\n\nVersion 1.0.5u [March 5, 2000]\n  Simplified the code that detects old png.h in png.c and pngtest.c\n  Renamed png_spalette (_p, _pp) to png_sPLT_t (_tp, _tpp)\n  Increased precision of rgb_to_gray calculations from 8 to 15 bits and\n    added png_set_rgb_to_gray_fixed() function.\n  Added makefile.bc32 (32-bit Borland C++, C mode)\n\nVersion 1.0.5v [March 11, 2000]\n  Added some parentheses to the png_jmpbuf macro definition.\n  Updated references to the zlib home page, which has moved to freesoftware.com.\n  Corrected bugs in documentation regarding png_read_row() and png_write_row().\n  Updated documentation of png_rgb_to_gray calculations in libpng.3/libpng.txt.\n  Renamed makefile.borland,turboc3 back to makefile.bor,tc3 as in version 1.0.3,\n    revised borland makefiles; added makefile.ibmvac3 and makefile.gcc (Cosmin)\n\nVersion 1.0.6 [March 20, 2000]\n  Minor revisions of makefile.bor, libpng.txt, and gregbook/rpng2-win.c\n  Added makefile.sggcc (SGI IRIX with gcc)\n\nVersion 1.0.6d [April 7, 2000]\n  Changed sprintf() to strcpy() in png_write_sCAL_s() to work without STDIO\n  Added data_length parameter to png_decompress_chunk() function\n  Revised documentation to remove reference to abandoned png_free_chnk functions\n  Fixed an error in png_rgb_to_gray_fixed()\n  Revised example.c, usage of png_destroy_write_struct().\n  Renamed makefile.ibmvac3 to makefile.ibmc, added libpng.icc IBM project file\n  Added a check for info_ptr->free_me&PNG_FREE_TEXT when freeing text in png.c\n  Simplify png_sig_bytes() function to remove use of non-ISO-C strdup().\n\nVersion 1.0.6e [April 9, 2000]\n  Added png_data_freer() function.\n  In the code that checks for over-length tRNS chunks, added check of\n    info_ptr->num_trans as well as png_ptr->num_trans (Matthias Benckmann)\n  Minor revisions of libpng.txt/libpng.3.\n  Check for existing data and free it if the free_me flag is set, in png_set_*()\n    and png_handle_*().\n  Only define PNG_WEIGHTED_FILTERS_SUPPORTED when PNG_FLOATING_POINT_SUPPORTED\n    is defined.\n  Changed several instances of PNG_NO_CONSOLE_ID to PNG_NO_STDIO in pngrutil.c\n    and mentioned the purposes of the two macros in libpng.txt/libpng.3.\n\nVersion 1.0.6f [April 14, 2000]\n  Revised png_set_iCCP() and png_set_rows() to avoid prematurely freeing data.\n  Add checks in png_set_text() for NULL members of the input text structure.\n  Revised libpng.txt/libpng.3.\n  Removed superfluous prototype for png_set_iTXt from png.h\n  Removed \"else\" from pngread.c, after png_error(), and changed \"0\" to \"length\".\n  Changed several png_errors about malformed ancillary chunks to png_warnings.\n\nVersion 1.0.6g [April 24, 2000]\n  Added png_pass-* arrays to pnggccrd.c when PNG_USE_LOCAL_ARRAYS is defined.\n  Relocated paragraph about png_set_background() in libpng.3/libpng.txt\n    and other revisions (Matthias Benckmann)\n  Relocated info_ptr->free_me, png_ptr->free_me, and other info_ptr and\n    png_ptr members to restore binary compatibility with libpng-1.0.5\n    (breaks compatibility with libpng-1.0.6).\n\nVersion 1.0.6h [April 24, 2000]\n  Changed shared library so-number pattern from 2.x.y.z to xy.z (this builds\n    libpng.so.10 & libpng.so.10.6h instead of libpng.so.2 & libpng.so.2.1.0.6h)\n    This is a temporary change for test purposes.\n\nVersion 1.0.6i [May 2, 2000]\n  Rearranged some members at the end of png_info and png_struct, to put\n    unknown_chunks_num and free_me within the original size of the png_structs\n    and free_me, png_read_user_fn, and png_free_fn within the original png_info,\n    because some old applications allocate the structs directly instead of\n    using png_create_*().\n  Added documentation of user memory functions in libpng.txt/libpng.3\n  Modified png_read_png so that it will use user_allocated row_pointers\n    if present, unless free_me directs that it be freed, and added description\n    of the use of png_set_rows() and png_get_rows() in libpng.txt/libpng.3.\n  Added PNG_LEGACY_SUPPORTED macro, and #ifdef out all new (since version\n    1.00) members of png_struct and png_info, to regain binary compatibility\n    when you define this macro.  Capabilities lost in this event\n    are user transforms (new in version 1.0.0),the user transform pointer\n    (new in version 1.0.2), rgb_to_gray (new in 1.0.5), iCCP, sCAL, sPLT,\n    the high-level interface, and unknown chunks support (all new in 1.0.6).\n    This was necessary because of old applications that allocate the structs\n    directly as authors were instructed to do in libpng-0.88 and earlier,\n    instead of using png_create_*().\n  Added modes PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT which\n    can be used to detect codes that directly allocate the structs, and\n    code to check these modes in png_read_init() and png_write_init() and\n    generate a libpng error if the modes aren't set and PNG_LEGACY_SUPPORTED\n    was not defined.\n  Added makefile.intel and updated makefile.watcom (Pawel Mrochen)\n\nVersion 1.0.6j [May 3, 2000]\n  Overloaded png_read_init() and png_write_init() with macros that convert\n    calls to png_read_init_2() or png_write_init_2() that check the version\n    and structure sizes.\n\nVersion 1.0.7beta11 [May 7, 2000]\n  Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes\n    which are no longer used.\n  Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is\n    defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXT_SUPPORTED\n    is defined.\n  Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory\n    overrun when old applications fill the info_ptr->text structure directly.\n  Added PNGAPI macro, and added it to the definitions of all exported functions.\n  Relocated version macro definitions ahead of the includes of zlib.h and\n    pngconf.h in png.h.\n\nVersion 1.0.7beta12 [May 12, 2000]\n  Revised pngset.c to avoid a problem with expanding the png_debug macro.\n  Deleted some extraneous defines from pngconf.h\n  Made PNG_NO_CONSOLE_IO the default condition when PNG_BUILD_DLL is defined.\n  Use MSC _RPTn debugging instead of fprintf if _MSC_VER is defined.\n  Added png_access_version_number() function.\n  Check for mask&PNG_FREE_CHNK (for TEXT, SCAL, PCAL) in png_free_data().\n  Expanded libpng.3/libpng.txt information about png_data_freer().\n\nVersion 1.0.7beta14 [May 17, 2000] (beta13 was not published)\n  Changed pnggccrd.c and pngvcrd.c to handle bad adaptive filter types as\n    warnings instead of errors, as pngrutil.c does.\n  Set the PNG_INFO_IDAT valid flag in png_set_rows() so png_write_png()\n    will actually write IDATs.\n  Made the default PNG_USE_LOCAL_ARRAYS depend on PNG_DLL instead of WIN32.\n  Make png_free_data() ignore its final parameter except when freeing data\n    that can have multiple instances (text, sPLT, unknowns).\n  Fixed a new bug in png_set_rows().\n  Removed info_ptr->valid tests from png_free_data(), as in version 1.0.5.\n  Added png_set_invalid() function.\n  Fixed incorrect illustrations of png_destroy_write_struct() in example.c.\n\nVersion 1.0.7beta15 [May 30, 2000]\n  Revised the deliberately erroneous Linux setjmp code in pngconf.h to produce\n    fewer error messages.\n  Rearranged checks for Z_OK to check the most likely path first in pngpread.c\n    and pngwutil.c.\n  Added checks in pngtest.c for png_create_*() returning NULL, and mentioned\n    in libpng.txt/libpng.3 the need for applications to check this.\n  Changed names of png_default_*() functions in pngtest to pngtest_*().\n  Changed return type of png_get_x|y_offset_*() from png_uint_32 to png_int_32.\n  Fixed some bugs in the unused PNG_INCH_CONVERSIONS functions in pngget.c\n  Set each pointer to NULL after freeing it in png_free_data().\n  Worked around a problem in pngconf.h; AIX's strings.h defines an \"index\"\n    macro that conflicts with libpng's png_color_16.index. (Dimitri\n    Papadapoulos)\n  Added \"msvc\" directory with MSVC++ project files (Simon-Pierre Cadieux).\n\nVersion 1.0.7beta16 [June 4, 2000]\n  Revised the workaround of AIX string.h \"index\" bug.\n  Added a check for overlength PLTE chunk in pngrutil.c.\n  Added PNG_NO_POINTER_INDEXING macro to use array-indexing instead of pointer\n    indexing in pngrutil.c and pngwutil.c to accommodate a buggy compiler.\n  Added a warning in png_decompress_chunk() when it runs out of data, e.g.\n    when it tries to read an erroneous PhotoShop iCCP chunk.\n  Added PNG_USE_DLL macro.\n  Revised the copyright/disclaimer/license notice.\n  Added contrib/msvctest directory\n\nVersion 1.0.7rc1 [June 9, 2000]\n  Corrected the definition of PNG_TRANSFORM_INVERT_ALPHA  (0x0400 not 0x0200)\n  Added contrib/visupng directory (Willem van Schaik)\n\nVersion 1.0.7beta18 [June 23, 2000]\n  Revised PNGAPI definition, and pngvcrd.c to work with __GCC__\n    and do not redefine PNGAPI if it is passed in via a compiler directive.\n  Revised visupng/PngFile.c to remove returns from within the Try block.\n  Removed leading underscores from \"_PNG_H\" and \"_PNG_SAVE_BSD_SOURCE\" macros.\n  Updated contrib/visupng/cexcept.h to version 1.0.0.\n  Fixed bugs in pngwrite.c and pngwutil.c that prevented writing iCCP chunks.\n\nVersion 1.0.7rc2 [June 28, 2000]\n  Updated license to include disclaimers required by UCITA.\n  Fixed \"DJBPP\" typo in pnggccrd.c introduced in beta18.\n\nVersion 1.0.7 [July 1, 2000]\n  Revised the definition of \"trans_values\" in libpng.3/libpng.txt\n\nVersion 1.0.8beta1 [July 8, 2000]\n  Added png_free(png_ptr, key) two places in pngpread.c to stop memory leaks.\n  Changed PNG_NO_STDIO to PNG_NO_CONSOLE_IO, several places in pngrutil.c and\n    pngwutil.c.\n  Changed PNG_EXPORT_VAR to use PNG_IMPEXP, in pngconf.h.\n  Removed unused \"#include <assert.h>\" from png.c\n  Added WindowsCE support.\n  Revised pnggccrd.c to work with gcc-2.95.2 and in the Cygwin environment.\n\nVersion 1.0.8beta2 [July 10, 2000]\n  Added project files to the wince directory and made further revisions\n    of pngtest.c, pngrio.c, and pngwio.c in support of WindowsCE.\n\nVersion 1.0.8beta3 [July 11, 2000]\n  Only set the PNG_FLAG_FREE_TRNS or PNG_FREE_TRNS flag in png_handle_tRNS()\n    for indexed-color input files to avoid potential double-freeing trans array\n    under some unusual conditions; problem was introduced in version 1.0.6f.\n  Further revisions to pngtest.c and files in the wince subdirectory.\n\nVersion 1.0.8beta4 [July 14, 2000]\n  Added the files pngbar.png and pngbar.jpg to the distribution.\n  Added makefile.cygwin, and cygwin support in pngconf.h\n  Added PNG_NO_ZALLOC_ZERO macro (makes png_zalloc skip zeroing memory)\n\nVersion 1.0.8rc1 [July 16, 2000]\n  Revised png_debug() macros and statements to eliminate compiler warnings.\n\nVersion 1.0.8 [July 24, 2000]\n  Added png_flush() in pngwrite.c, after png_write_IEND().\n  Updated makefile.hpux to build a shared library.\n\nVersion 1.0.9beta1 [November 10, 2000]\n  Fixed typo in scripts/makefile.hpux\n  Updated makevms.com in scripts and contrib/* and contrib/* (Martin Zinser)\n  Fixed seqence-point bug in contrib/pngminus/png2pnm (Martin Zinser)\n  Changed \"cdrom.com\" in documentation to \"libpng.org\"\n  Revised pnggccrd.c to get it all working, and updated makefile.gcmmx (Greg).\n  Changed type of \"params\" from voidp to png_voidp in png_read|write_png().\n  Make sure PNGAPI and PNG_IMPEXP are defined in pngconf.h.\n  Revised the 3 instances of WRITEFILE in pngtest.c.\n  Relocated \"msvc\" and \"wince\" project subdirectories into \"dll\" subdirectory.\n  Updated png.rc in dll/msvc project\n  Revised makefile.dec to define and use LIBPATH and INCPATH\n  Increased size of global png_libpng_ver[] array from 12 to 18 chars.\n  Made global png_libpng_ver[], png_sig[] and png_pass_*[] arrays const.\n  Removed duplicate png_crc_finish() from png_handle_bKGD() function.\n  Added a warning when application calls png_read_update_info() multiple times.\n  Revised makefile.cygwin\n  Fixed bugs in iCCP support in pngrutil.c and pngwutil.c.\n  Replaced png_set_empty_plte_permitted() with png_permit_mng_features().\n\nVersion 1.0.9beta2 [November 19, 2000]\n  Renamed the \"dll\" subdirectory \"projects\".\n  Added borland project files to \"projects\" subdirectory.\n  Set VS_FF_PRERELEASE and VS_FF_PATCHED flags in msvc/png.rc when appropriate.\n  Add error message in png_set_compression_buffer_size() when malloc fails.\n\nVersion 1.0.9beta3 [November 23, 2000]\n  Revised PNG_LIBPNG_BUILD_TYPE macro in png.h, used in the msvc project.\n  Removed the png_flush() in pngwrite.c that crashes some applications\n    that don't set png_output_flush_fn.\n  Added makefile.macosx and makefile.aix to scripts directory.\n\nVersion 1.0.9beta4 [December 1, 2000]\n  Change png_chunk_warning to png_warning in png_check_keyword().\n  Increased the first part of msg buffer from 16 to 18 in png_chunk_error().\n\nVersion 1.0.9beta5 [December 15, 2000]\n  Added support for filter method 64 (for PNG datastreams embedded in MNG).\n\nVersion 1.0.9beta6 [December 18, 2000]\n  Revised png_set_filter() to accept filter method 64 when appropriate.\n  Added new PNG_HAVE_PNG_SIGNATURE bit to png_ptr->mode and use it to\n    help prevent applications from using MNG features in PNG datastreams.\n  Added png_permit_mng_features() function.\n  Revised libpng.3/libpng.txt.  Changed \"filter type\" to \"filter method\".\n\nVersion 1.0.9rc1 [December 23, 2000]\n  Revised test for PNG_HAVE_PNG_SIGNATURE in pngrutil.c\n  Fixed error handling of unknown compression type in png_decompress_chunk().\n  In pngconf.h, define __cdecl when _MSC_VER is defined.\n\nVersion 1.0.9beta7 [December 28, 2000]\n  Changed PNG_TEXT_COMPRESSION_zTXt to PNG_COMPRESSION_TYPE_BASE several places.\n  Revised memory management in png_set_hIST and png_handle_hIST in a backward\n    compatible manner.  PLTE and tRNS were revised similarly.\n  Revised the iCCP chunk reader to ignore trailing garbage.\n\nVersion 1.0.9beta8 [January 12, 2001]\n  Moved pngasmrd.h into pngconf.h.\n  Improved handling of out-of-spec garbage iCCP chunks generated by PhotoShop.\n\nVersion 1.0.9beta9 [January 15, 2001]\n  Added png_set_invalid, png_permit_mng_features, and png_mmx_supported to\n    wince and msvc project module definition files.\n  Minor revision of makefile.cygwin.\n  Fixed bug with progressive reading of narrow interlaced images in pngpread.c\n\nVersion 1.0.9beta10 [January 16, 2001]\n  Do not typedef png_FILE_p in pngconf.h when PNG_NO_STDIO is defined.\n  Fixed \"png_mmx_supported\" typo in project definition files.\n\nVersion 1.0.9beta11 [January 19, 2001]\n  Updated makefile.sgi to make shared library.\n  Removed png_mmx_support() function and disabled PNG_MNG_FEATURES_SUPPORTED\n    by default, for the benefit of DLL forward compatibility.  These will\n    be re-enabled in version 1.2.0.\n\nVersion 1.0.9rc2 [January 22, 2001]\n  Revised cygwin support.\n\nVersion 1.0.9 [January 31, 2001]\n  Added check of cygwin's ALL_STATIC in pngconf.h\n  Added \"-nommx\" parameter to contrib/gregbook/rpng2-win and rpng2-x demos.\n\nVersion 1.0.10beta1 [March 14, 2001]\n  Revised makefile.dec, makefile.sgi, and makefile.sggcc; added makefile.hpgcc.\n  Reformatted libpng.3 to eliminate bad line breaks.\n  Added checks for _mmx_supported in the read_filter_row function of pnggccrd.c\n  Added prototype for png_mmx_support() near the top of pnggccrd.c\n  Moved some error checking from png_handle_IHDR to png_set_IHDR.\n  Added PNG_NO_READ_SUPPORTED and PNG_NO_WRITE_SUPPORTED macros.\n  Revised png_mmx_support() function in pnggccrd.c\n  Restored version 1.0.8 PNG_WRITE_EMPTY_PLTE_SUPPORTED behavior in pngwutil.c\n  Fixed memory leak in contrib/visupng/PngFile.c\n  Fixed bugs in png_combine_row() in pnggccrd.c and pngvcrd.c (C version)\n  Added warnings when retrieving or setting gamma=0.\n  Increased the first part of msg buffer from 16 to 18 in png_chunk_warning().\n\nVersion 1.0.10rc1 [March 23, 2001]\n  Changed all instances of memcpy, strcpy, and strlen to png_memcpy, png_strcpy,\n    and png_strlen.\n  Revised png_mmx_supported() function in pnggccrd.c to return proper value.\n  Fixed bug in progressive reading (pngpread.c) with small images (height < 8).\n\nVersion 1.0.10 [March 30, 2001]\n  Deleted extraneous space (introduced in 1.0.9) from line 42 of makefile.cygwin\n  Added beos project files (Chris Herborth)\n\nVersion 1.0.11beta1 [April 3, 2001]\n  Added type casts on several png_malloc() calls (Dimitri Papadapoulos).\n  Removed a no-longer needed AIX work-around from pngconf.h\n  Changed several \"//\" single-line comments to C-style in pnggccrd.c\n\nVersion 1.0.11beta2 [April 11, 2001]\n  Removed PNGAPI from several functions whose prototypes did not have PNGAPI.\n  Updated scripts/pngos2.def\n\nVersion 1.0.11beta3 [April 14, 2001]\n  Added checking the results of many instances of png_malloc() for NULL\n\nVersion 1.0.11beta4 [April 20, 2001]\n  Undid the changes from version 1.0.11beta3.  Added a check for NULL return\n    from user's malloc_fn().\n  Removed some useless type casts of the NULL pointer.\n  Added makefile.netbsd\n\nVersion 1.0.11 [April 27, 2001]\n  Revised makefile.netbsd\n\nVersion 1.0.12beta1 [May 14, 2001]\n  Test for Windows platform in pngconf.h when including malloc.h (Emmanuel Blot)\n  Updated makefile.cygwin and handling of Cygwin's ALL_STATIC in pngconf.h\n  Added some never-to-be-executed code in pnggccrd.c to quiet compiler warnings.\n  Eliminated the png_error about apps using png_read|write_init().  Instead,\n    libpng will reallocate the png_struct and info_struct if they are too small.\n    This retains future binary compatibility for old applications written for\n    libpng-0.88 and earlier.\n\nVersion 1.2.0beta1 [May 6, 2001]\n  Bumped DLLNUM to 2.\n  Re-enabled PNG_MNG_FEATURES_SUPPORTED and enabled PNG_ASSEMBLER_CODE_SUPPORTED\n    by default.\n  Added runtime selection of MMX features.\n  Added png_set_strip_error_numbers function and related macros.\n\nVersion 1.2.0beta2 [May 7, 2001]\n  Finished merging 1.2.0beta1 with version 1.0.11\n  Added a check for attempts to read or write PLTE in grayscale PNG datastreams.\n\nVersion 1.2.0beta3 [May 17, 2001]\n  Enabled user memory function by default.\n  Modified png_create_struct so it passes user mem_ptr to user memory allocator.\n  Increased png_mng_features flag from png_byte to png_uint_32.\n  Bumped shared-library (so-number) and dll-number to 3.\n\nVersion 1.2.0beta4 [June 23, 2001]\n  Check for missing profile length field in iCCP chunk and free chunk_data\n    in case of truncated iCCP chunk.\n  Bumped shared-library number to 3 in makefile.sgi and makefile.sggcc\n  Bumped dll-number from 2 to 3 in makefile.cygwin\n  Revised contrib/gregbook/rpng*-x.c to avoid a memory leak and to exit cleanly\n    if user attempts to run it on an 8-bit display.\n  Updated contrib/gregbook\n  Use png_malloc instead of png_zalloc to allocate palette in pngset.c\n  Updated makefile.ibmc\n  Added some typecasts to eliminate gcc 3.0 warnings.  Changed prototypes\n    of png_write_oFFS width and height from png_uint_32 to png_int_32.\n  Updated example.c\n  Revised prototypes for png_debug_malloc and png_debug_free in pngtest.c\n\nVersion 1.2.0beta5 [August 8, 2001]\n  Revised contrib/gregbook\n  Revised makefile.gcmmx\n  Revised pnggccrd.c to conditionally compile some thread-unsafe code only\n    when PNG_THREAD_UNSAFE_OK is defined.\n  Added tests to prevent pngwutil.c from writing a bKGD or tRNS chunk with\n    value exceeding 2^bit_depth-1\n  Revised makefile.sgi and makefile.sggcc\n  Replaced calls to fprintf(stderr,...) with png_warning() in pnggccrd.c\n  Removed restriction that do_invert_mono only operate on 1-bit opaque files\n\nVersion 1.2.0 [September 1, 2001]\n  Changed a png_warning() to png_debug() in pnggccrd.c\n  Fixed contrib/gregbook/rpng-x.c, rpng2-x.c to avoid crash with XFreeGC().\n\nVersion 1.2.1beta1 [October 19, 2001]\n  Revised makefile.std in contrib/pngminus\n  Include background_1 in png_struct regardless of gamma support.\n  Revised makefile.netbsd and makefile.macosx, added makefile.darwin.\n  Revised example.c to provide more details about using row_callback().\n\nVersion 1.2.1beta2 [October 25, 2001]\n  Added type cast to each NULL appearing in a function call, except for\n    WINCE functions.\n  Added makefile.so9.\n\nVersion 1.2.1beta3 [October 27, 2001]\n  Removed type casts from all NULLs.\n  Simplified png_create_struct_2().\n\nVersion 1.2.1beta4 [November 7, 2001]\n  Revised png_create_info_struct() and png_creat_struct_2().\n  Added error message if png_write_info() was omitted.\n  Type cast NULLs appearing in function calls when _NO_PROTO or\n    PNG_TYPECAST_NULL is defined.\n\nVersion 1.2.1rc1 [November 24, 2001]\n  Type cast NULLs appearing in function calls except when PNG_NO_TYPECAST_NULL\n    is defined.\n  Changed typecast of \"size\" argument to png_size_t in pngmem.c calls to\n    the user malloc_fn, to agree with the prototype in png.h\n  Added a pop/push operation to pnggccrd.c, to preserve Eflag (Maxim Sobolev)\n  Updated makefile.sgi to recognize LIBPATH and INCPATH.\n  Updated various makefiles so \"make clean\" does not remove previous major\n    version of the shared library.\n\nVersion 1.2.1rc2 [December 4, 2001]\n  Always allocate 256-entry internal palette, hist, and trans arrays, to\n    avoid out-of-bounds memory reference caused by invalid PNG datastreams.\n  Added a check for prefix_length > data_length in iCCP chunk handler.\n\nVersion 1.2.1 [December 7, 2001]\n  None.\n\nVersion 1.2.2beta1 [February 22, 2002]\n  Fixed a bug with reading the length of iCCP profiles (Larry Reeves).\n  Revised makefile.linux, makefile.gcmmx, and makefile.sgi to generate\n    libpng.a, libpng12.so (not libpng.so.3), and libpng12/png.h\n  Revised makefile.darwin to remove \"-undefined suppress\" option.\n  Added checks for gamma and chromaticity values over 21474.83, which exceed\n    the limit for PNG unsigned 32-bit integers when encoded.\n  Revised calls to png_create_read_struct() and png_create_write_struct()\n    for simpler debugging.\n  Revised png_zalloc() so zlib handles errors (uses PNG_FLAG_MALLOC_NULL_MEM_OK)\n\nVersion 1.2.2beta2 [February 23, 2002]\n  Check chunk_length and idat_size for invalid (over PNG_MAX_UINT) lengths.\n  Check for invalid image dimensions in png_get_IHDR.\n  Added missing \"fi;\" in the install target of the SGI makefiles.\n  Added install-static to all makefiles that make shared libraries.\n  Always do gamma compensation when image is partially transparent.\n\nVersion 1.2.2beta3 [March 7, 2002]\n  Compute background.gray and background_1.gray even when color_type is RGB\n    in case image gets reduced to gray later.\n  Modified shared-library makefiles to install pkgconfig/libpngNN.pc.\n  Export (with PNGAPI) png_zalloc, png_zfree, and png_handle_as_unknown\n  Removed unused png_write_destroy_info prototype from png.h\n  Eliminated incorrect use of width_mmx from pnggccrd.c in pixel_bytes == 8 case\n  Added install-shared target to all makefiles that make shared libraries.\n  Stopped a double free of palette, hist, and trans when not using free_me.\n  Added makefile.32sunu for Sun Ultra 32 and makefile.64sunu for Sun Ultra 64.\n\nVersion 1.2.2beta4 [March 8, 2002]\n  Compute background.gray and background_1.gray even when color_type is RGB\n    in case image gets reduced to gray later (Jason Summers).\n  Relocated a misplaced /bin/rm in the \"install-shared\" makefile targets\n  Added PNG_1_0_X macro which can be used to build a 1.0.x-compatible library.\n\nVersion 1.2.2beta5 [March 26, 2002]\n  Added missing PNGAPI to several function definitions.\n  Check for invalid bit_depth or color_type in png_get_IHDR(), and\n    check for missing PLTE or IHDR in png_push_read_chunk() (Matthias Clasen).\n  Revised iTXt support to accept NULL for lang and lang_key.\n  Compute gamma for color components of background even when color_type is gray.\n  Changed \"()\" to \"{}\" in scripts/libpng.pc.in.\n  Revised makefiles to put png.h and pngconf.h only in $prefix/include/libpngNN\n  Revised makefiles to make symlink to libpng.so.NN in addition to libpngNN.so\n\nVersion 1.2.2beta6 [March 31, 2002]\n\nVersion 1.0.13beta1 [March 31, 2002]\n  Prevent png_zalloc() from trying to memset memory that it failed to acquire.\n  Add typecasts of PNG_MAX_UINT in pngset_cHRM_fixed() (Matt Holgate).\n  Ensure that the right function (user or default) is used to free the\n    png_struct after an error in png_create_read_struct_2().\n\nVersion 1.2.2rc1 [April 7, 2002]\n\nVersion 1.0.13rc1 [April 7, 2002]\n  Save the ebx register in pnggccrd.c (Sami Farin)\n  Add \"mem_ptr = png_ptr->mem_ptr\" in png_destroy_write_struct() (Paul Gardner).\n  Updated makefiles to put headers in include/libpng and remove old include/*.h.\n\nVersion 1.2.2 [April 15, 2002]\n\nVersion 1.0.13 [April 15, 2002]\n  Revised description of png_set_filter() in libpng.3/libpng.txt.\n  Revised makefile.netbsd and added makefile.neNNbsd and makefile.freebsd\n\nVersion 1.0.13patch01 [April 17, 2002]\n\nVersion 1.2.2patch01 [April 17, 2002]\n  Changed ${PNGMAJ}.${PNGVER} bug to ${PNGVER} in makefile.sgi and\n    makefile.sggcc\n  Fixed VER -> PNGVER typo in makefile.macosx and added install-static to\n    install\n  Added install: target to makefile.32sunu and makefile.64sunu\n\nVersion 1.0.13patch03 [April 18, 2002]\n\nVersion 1.2.2patch03 [April 18, 2002]\n  Revised 15 makefiles to link libpng.a to libpngNN.a and the include libpng\n  subdirectory to libpngNN subdirectory without the full pathname.\n  Moved generation of libpng.pc from \"install\" to \"all\" in 15 makefiles.\n\nVersion 1.2.3rc1 [April 28, 2002]\n  Added install-man target to 15 makefiles (Dimitri Papadopolous-Orfanos).\n  Added $(DESTDIR) feature to 24 makefiles (Tim Mooney)\n  Fixed bug with $prefix, should be $(prefix) in makefile.hpux.\n  Updated cygwin-specific portion of pngconf.h and revised makefile.cygwin\n  Added a link from libpngNN.pc to libpng.pc in 15 makefiles.\n  Added links from include/libpngNN/*.h to include/*.h in 24 makefiles.\n  Revised makefile.darwin to make relative links without full pathname.\n  Added setjmp() at the end of png_create_*_struct_2() in case user forgets\n    to put one in their application.\n  Restored png_zalloc() and png_zfree() prototypes to version 1.2.1 and\n    removed them from module definition files.\n\nVersion 1.2.3rc2 [May 1, 2002]\n  Fixed bug in reporting number of channels in pngget.c and pngset.c,\n    that was introduced in version 1.2.2beta5.\n  Exported png_zalloc(), png_zfree(), png_default_read(), png_default_write(),\n    png_default_flush(), and png_push_fill_buffer() and included them in\n    module definition files.\n  Added \"libpng.pc\" dependency to the \"install-shared\" target in 15 makefiles.\n\nVersion 1.2.3rc3 [May 1, 2002]\n  Revised prototype for png_default_flush()\n  Remove old libpng.pc and libpngNN.pc before installing new ones.\n\nVersion 1.2.3rc4 [May 2, 2002]\n  Typos in *.def files (png_default_read|write -> png_default_read|write_data)\n  In makefiles, changed rm libpng.NN.pc to rm libpngNN.pc\n  Added libpng-config and libpngNN-config and modified makefiles to install\n    them.\n  Changed $(MANPATH) to $(DESTDIR)$(MANPATH) in makefiles\n  Added \"Win32 DLL VB\" configuration to projects/msvc/libpng.dsp\n\nVersion 1.2.3rc5 [May 11, 2002]\n  Changed \"error\" and \"message\" in prototypes to \"error_message\" and\n    \"warning_message\" to avoid namespace conflict.\n  Revised 15 makefiles to build libpng-config from libpng-config-*.in\n  Once more restored png_zalloc and png_zfree to regular nonexported form.\n  Restored png_default_read|write_data, png_default_flush, png_read_fill_buffer\n    to nonexported form, but with PNGAPI, and removed them from module def\n    files.\n\nVersion 1.2.3rc6 [May 14, 2002]\n  Removed \"PNGAPI\" from png_zalloc() and png_zfree() in png.c\n  Changed \"Gz\" to \"Gd\" in projects/msvc/libpng.dsp and zlib.dsp.\n  Removed leftover libpng-config \"sed\" script from four makefiles.\n  Revised libpng-config creating script in 16 makefiles.\n\nVersion 1.2.3 [May 22, 2002]\n  Revised libpng-config target in makefile.cygwin.\n  Removed description of png_set_mem_fn() from documentation.\n  Revised makefile.freebsd.\n  Minor cosmetic changes to 15 makefiles, e.g., $(DI) = $(DESTDIR)/$(INCDIR).\n  Revised projects/msvc/README.txt\n  Changed -lpng to -lpngNN in LDFLAGS in several makefiles.\n\nVersion 1.2.4beta1 [May 24, 2002]\n  Added libpng.pc and libpng-config to \"all:\" target in 16 makefiles.\n  Fixed bug in 16 makefiles: $(DESTDIR)/$(LIBPATH) to $(DESTDIR)$(LIBPATH)\n  Added missing \"\\\" before closing double quote in makefile.gcmmx.\n  Plugged various memory leaks; added png_malloc_warn() and png_set_text_2()\n    functions.\n\nVersion 1.2.4beta2 [June 25, 2002]\n  Plugged memory leak of png_ptr->current_text (Matt Holgate).\n  Check for buffer overflow before reading CRC in pngpread.c (Warwick Allison)\n  Added -soname to the loader flags in makefile.dec, makefile.sgi, and\n    makefile.sggcc.\n  Added \"test-installed\" target to makefile.linux, makefile.gcmmx,\n    makefile.sgi, and makefile.sggcc.\n\nVersion 1.2.4beta3 [June 28, 2002]\n  Plugged memory leak of row_buf in pngtest.c when there is a png_error().\n  Detect buffer overflow in pngpread.c when IDAT is corrupted with extra data.\n  Added \"test-installed\" target to makefile.32sunu, makefile.64sunu,\n    makefile.beos, makefile.darwin, makefile.dec, makefile.macosx,\n    makefile.solaris, makefile.hpux, makefile.hpgcc, and makefile.so9.\n\nVersion 1.2.4rc1 and 1.0.14rc1 [July 2, 2002]\n  Added \"test-installed\" target to makefile.cygwin and makefile.sco.\n  Revised pnggccrd.c to be able to back out version 1.0.x via PNG_1_0_X macro.\n\nVersion 1.2.4 and 1.0.14 [July 8, 2002]\n  Changed png_warning() to png_error() when width is too large to process.\n\nVersion 1.2.4patch01 [July 20, 2002]\n  Revised makefile.cygwin to use DLL number 12 instead of 13.\n\nVersion 1.2.5beta1 [August 6, 2002]\n  Added code to contrib/gregbook/readpng2.c to ignore unused chunks.\n  Replaced toucan.png in contrib/gregbook (it has been corrupt since 1.0.11)\n  Removed some stray *.o files from contrib/gregbook.\n  Changed png_error() to png_warning() about \"Too much data\" in pngpread.c\n    and about \"Extra compressed data\" in pngrutil.c.\n  Prevent png_ptr->pass from exceeding 7 in png_push_finish_row().\n  Updated makefile.hpgcc\n  Updated png.c and pnggccrd.c handling of return from png_mmx_support()\n\nVersion 1.2.5beta2 [August 15, 2002]\n  Only issue png_warning() about \"Too much data\" in pngpread.c when avail_in\n    is nonzero.\n  Updated makefiles to install a separate libpng.so.3 with its own rpath.\n\nVersion 1.2.5rc1 and 1.0.15rc1 [August 24, 2002]\n  Revised makefiles to not remove previous minor versions of shared libraries.\n\nVersion 1.2.5rc2 and 1.0.15rc2 [September 16, 2002]\n  Revised 13 makefiles to remove \"-lz\" and \"-L$(ZLIBLIB)\", etc., from shared\n    library loader directive.\n  Added missing \"$OBJSDLL\" line to makefile.gcmmx.\n  Added missing \"; fi\" to makefile.32sunu.\n\nVersion 1.2.5rc3 and 1.0.15rc3 [September 18, 2002]\n  Revised libpng-config script.\n\nVersion 1.2.5 and 1.0.15 [October 3, 2002]\n  Revised makefile.macosx, makefile.darwin, makefile.hpgcc, and makefile.hpux,\n    and makefile.aix.\n  Relocated two misplaced PNGAPI lines in pngtest.c\n\nVersion 1.2.6beta1 [October 22, 2002]\n  Commented out warning about uninitialized mmx_support in pnggccrd.c.\n  Changed \"IBMCPP__\" flag to \"__IBMCPP__\" in pngconf.h.\n  Relocated two more misplaced PNGAPI lines in pngtest.c\n  Fixed memory overrun bug in png_do_read_filler() with 16-bit datastreams,\n    introduced in version 1.0.2.\n  Revised makefile.macosx, makefile.dec, makefile.aix, and makefile.32sunu.\n\nVersion 1.2.6beta2 [November 1, 2002]\n  Added libpng-config \"--ldopts\" output.\n  Added \"AR=ar\" and \"ARFLAGS=rc\" and changed \"ar rc\" to \"$(AR) $(ARFLAGS)\"\n    in makefiles.\n\nVersion 1.2.6beta3 [July 18, 2004]\n  Reverted makefile changes from version 1.2.6beta2 and some of the changes\n    from version 1.2.6beta1; these will be postponed until version 1.2.7.\n    Version 1.2.6 is going to be a simple bugfix release.\n  Changed the one instance of \"ln -sf\" to \"ln -f -s\" in each Sun makefile.\n  Fixed potential overrun in pngerror.c by using strncpy instead of memcpy.\n  Added \"#!/bin/sh\" at the top of configure, for recognition of the\n    'x' flag under Cygwin (Cosmin).\n  Optimized vacuous tests that silence compiler warnings, in png.c (Cosmin).\n  Added support for PNG_USER_CONFIG, in pngconf.h (Cosmin).\n  Fixed the special memory handler for Borland C under DOS, in pngmem.c\n    (Cosmin).\n  Removed some spurious assignments in pngrutil.c (Cosmin).\n  Replaced 65536 with 65536L, and 0xffff with 0xffffL, to silence warnings\n    on 16-bit platforms (Cosmin).\n  Enclosed shift op expressions in parentheses, to silence warnings (Cosmin).\n  Used proper type png_fixed_point, to avoid problems on 16-bit platforms,\n    in png_handle_sRGB() (Cosmin).\n  Added compression_type to png_struct, and optimized the window size\n    inside the deflate stream (Cosmin).\n  Fixed definition of isnonalpha(), in pngerror.c and pngrutil.c (Cosmin).\n  Fixed handling of unknown chunks that come after IDAT (Cosmin).\n  Allowed png_error() and png_warning() to work even if png_ptr == NULL\n    (Cosmin).\n  Replaced row_info->rowbytes with row_bytes in png_write_find_filter()\n    (Cosmin).\n  Fixed definition of PNG_LIBPNG_VER_DLLNUM (Simon-Pierre).\n  Used PNG_LIBPNG_VER and PNG_LIBPNG_VER_STRING instead of the hardcoded\n    values in png.c (Simon-Pierre, Cosmin).\n  Initialized png_libpng_ver[] with PNG_LIBPNG_VER_STRING (Simon-Pierre).\n  Replaced PNG_LIBPNG_VER_MAJOR with PNG_LIBPNG_VER_DLLNUM in png.rc\n    (Simon-Pierre).\n  Moved the definition of PNG_HEADER_VERSION_STRING near the definitions\n    of the other PNG_LIBPNG_VER_... symbols in png.h (Cosmin).\n  Relocated #ifndef PNGAPI guards in pngconf.h (Simon-Pierre, Cosmin).\n  Updated scripts/makefile.vc(a)win32 (Cosmin).\n  Updated the MSVC project (Simon-Pierre, Cosmin).\n  Updated the Borland C++ Builder project (Cosmin).\n  Avoided access to asm_flags in pngvcrd.c, if PNG_1_0_X is defined (Cosmin).\n  Commented out warning about uninitialized mmx_support in pngvcrd.c (Cosmin).\n  Removed scripts/makefile.bd32 and scripts/pngdef.pas (Cosmin).\n  Added extra guard around inclusion of Turbo C memory headers, in pngconf.h\n    (Cosmin).\n  Renamed projects/msvc/ to projects/visualc6/, and projects/borland/ to\n    projects/cbuilder5/ (Cosmin).\n  Moved projects/visualc6/png32ms.def to scripts/pngw32.def,\n    and projects/visualc6/png.rc to scripts/pngw32.rc (Cosmin).\n  Added projects/visualc6/pngtest.dsp; removed contrib/msvctest/ (Cosmin).\n  Changed line endings to DOS style in cbuilder5 and visualc6 files, even\n    in the tar.* distributions (Cosmin).\n  Updated contrib/visupng/VisualPng.dsp (Cosmin).\n  Updated contrib/visupng/cexcept.h to version 2.0.0 (Cosmin).\n  Added a separate distribution with \"configure\" and supporting files (Junichi).\n\nVersion 1.2.6beta4 [July 28, 2004]\n  Added user ability to change png_size_t via a PNG_SIZE_T macro.\n  Added png_sizeof() and png_convert_size() functions.\n  Added PNG_SIZE_MAX (maximum value of a png_size_t variable.\n  Added check in png_malloc_default() for (size_t)size != (png_uint_32)size\n    which would indicate an overflow.\n  Changed sPLT failure action from png_error to png_warning and abandon chunk.\n  Changed sCAL and iCCP failures from png_error to png_warning and abandon.\n  Added png_get_uint_31(png_ptr, buf) function.\n  Added PNG_UINT_32_MAX macro.\n  Renamed PNG_MAX_UINT to PNG_UINT_31_MAX.\n  Made png_zalloc() issue a png_warning and return NULL on potential\n    overflow.\n  Turn on PNG_NO_ZALLOC_ZERO by default in version 1.2.x\n  Revised \"clobber list\" in pnggccrd.c so it will compile under gcc-3.4.\n  Revised Borland portion of png_malloc() to return NULL or issue\n    png_error() according to setting of PNG_FLAG_MALLOC_NULL_MEM_OK.\n  Added PNG_NO_SEQUENTIAL_READ_SUPPORTED macro to conditionally remove\n    sequential read support.\n  Added some \"#if PNG_WRITE_SUPPORTED\" blocks.\n  Added #ifdef to remove some redundancy in png_malloc_default().\n  Use png_malloc instead of png_zalloc to allocate the pallete.\n\nVersion 1.0.16rc1 and 1.2.6rc1 [August 4, 2004]\n  Fixed buffer overflow vulnerability (CVE-2004-0597) in png_handle_tRNS().\n  Fixed NULL dereference vulnerability (CVE-2004-0598) in png_handle_iCCP().\n  Fixed integer overflow vulnerability (CVE-2004-0599) in png_read_png().\n  Fixed some harmless bugs in png_handle_sBIT, etc, that would cause\n    duplicate chunk types to go undetected.\n  Fixed some timestamps in the -config version\n  Rearranged order of processing of color types in png_handle_tRNS().\n  Added ROWBYTES macro to calculate rowbytes without integer overflow.\n  Updated makefile.darwin and removed makefile.macosx from scripts directory.\n  Imposed default one million column, one-million row limits on the image\n    dimensions, and added png_set_user_limits() function to override them.\n  Revised use of PNG_SET_USER_LIMITS_SUPPORTED macro.\n  Fixed wrong cast of returns from png_get_user_width|height_max().\n  Changed some \"keep the compiler happy\" from empty statements to returns,\n  Revised libpng.txt to remove 1.2.x stuff from the 1.0.x distribution\n\nVersion 1.0.16rc2 and 1.2.6rc2 [August 7, 2004]\n  Revised makefile.darwin and makefile.solaris.  Removed makefile.macosx.\n  Revised pngtest's png_debug_malloc() to use png_malloc() instead of\n    png_malloc_default() which is not supposed to be exported.\n  Fixed off-by-one error in one of the conversions to PNG_ROWBYTES() in\n    pngpread.c.  Bug was introduced in 1.2.6rc1.\n  Fixed bug in RGB to RGBX transformation introduced in 1.2.6rc1.\n  Fixed old bug in RGB to Gray transformation.\n  Fixed problem with 64-bit compilers by casting arguments to abs()\n    to png_int_32.\n  Changed \"ln -sf\" to \"ln -f -s\" in three makefiles (solaris, sco, so9).\n  Changed \"HANDLE_CHUNK_*\" to \"PNG_HANDLE_CHUNK_*\" (Cosmin)\n  Added \"-@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGMAJ)\" to 15 *NIX makefiles.\n  Added code to update the row_info->colortype in png_do_read_filler() (MSB).\n\nVersion 1.0.16rc3 and 1.2.6rc3 [August 9, 2004]\n  Eliminated use of \"abs()\" in testing cHRM and gAMA values, to avoid\n    trouble with some 64-bit compilers.  Created PNG_OUT_OF_RANGE() macro.\n  Revised documentation of png_set_keep_unknown_chunks().\n  Check handle_as_unknown status in pngpread.c, as in pngread.c previously.\n  Moved  \"PNG_HANDLE_CHUNK_*\" macros out of PNG_INTERNAL section of png.h\n  Added \"rim\" definitions for CONST4 and CONST6 in pnggccrd.c\n\nVersion 1.0.16rc4 and 1.2.6rc4 [August 10, 2004]\n  Fixed mistake in pngtest.c introduced in 1.2.6rc2 (declaration of\n    \"pinfo\" was out of place).\n\nVersion 1.0.16rc5 and 1.2.6rc5 [August 10, 2004]\n  Moved  \"PNG_HANDLE_CHUNK_*\" macros out of PNG_ASSEMBLER_CODE_SUPPORTED\n    section of png.h where they were inadvertently placed in version rc3.\n\nVersion 1.2.6 and 1.0.16 [August 15, 2004]\n  Revised pngtest so memory allocation testing is only done when PNG_DEBUG==1.\n\nVersion 1.2.7beta1 [August 26, 2004]\n  Removed unused pngasmrd.h file.\n  Removed references to uu.net for archived files.  Added references to\n    PNG Spec (second edition) and the PNG ISO/IEC Standard.\n  Added \"test-dd\" target in 15 makefiles, to run pngtest in DESTDIR.\n  Fixed bug with \"optimized window size\" in the IDAT datastream, that\n    causes libpng to write PNG files with incorrect zlib header bytes.\n\nVersion 1.2.7beta2 [August 28, 2004]\n  Fixed bug with sCAL chunk and big-endian machines (David Munro).\n  Undid new code added in 1.2.6rc2 to update the color_type in\n    png_set_filler().\n  Added png_set_add_alpha() that updates color type.\n\nVersion 1.0.17rc1 and 1.2.7rc1 [September 4, 2004]\n  Revised png_set_strip_filler() to not remove alpha if color_type has alpha.\n\nVersion 1.2.7 and 1.0.17 [September 12, 2004]\n  Added makefile.hp64\n  Changed projects/msvc/png32ms.def to scripts/png32ms.def in makefile.cygwin\n\nVersion 1.2.8beta1 [November 1, 2004]\n  Fixed bug in png_text_compress() that would fail to complete a large block.\n  Fixed bug, introduced in libpng-1.2.7, that overruns a buffer during\n    strip alpha operation in png_do_strip_filler().\n  Added PNG_1_2_X definition in pngconf.h\n  Use #ifdef to comment out png_info_init in png.c and png_read_init in\n    pngread.c (as of 1.3.0)\n\nVersion 1.2.8beta2 [November 2, 2004]\n  Reduce color_type to a nonalpha type after strip alpha operation in\n    png_do_strip_filler().\n\nVersion 1.2.8beta3 [November 3, 2004]\n  Revised definitions of PNG_MAX_UINT_32, PNG_MAX_SIZE, and PNG_MAXSUM\n\nVersion 1.2.8beta4 [November 12, 2004]\n  Fixed (again) definition of PNG_LIBPNG_VER_DLLNUM in png.h (Cosmin).\n  Added PNG_LIBPNG_BUILD_PRIVATE in png.h (Cosmin).\n  Set png_ptr->zstream.data_type to Z_BINARY, to avoid unnecessary detection\n    of data type in deflate (Cosmin).\n  Deprecated but continue to support SPECIALBUILD and PRIVATEBUILD in favor of\n    PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING.\n\nVersion 1.2.8beta5 [November 20, 2004]\n  Use png_ptr->flags instead of png_ptr->transformations to pass\n    PNG_STRIP_ALPHA info to png_do_strip_filler(), to preserve ABI\n    compatibility.\n  Revised handling of SPECIALBUILD, PRIVATEBUILD,\n    PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING.\n\nVersion 1.2.8rc1 [November 24, 2004]\n  Moved handling of BUILD macros from pngconf.h to png.h\n  Added definition of PNG_LIBPNG_BASE_TYPE in png.h, inadvertently\n    omitted from beta5.\n  Revised scripts/pngw32.rc\n  Despammed mailing addresses by masking \"@\" with \"at\".\n  Inadvertently installed a supposedly faster test version of pngrutil.c\n\nVersion 1.2.8rc2 [November 26, 2004]\n  Added two missing \"\\\" in png.h\n  Change tests in pngread.c and pngpread.c to\n    if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))\n       png_do_read_transformations(png_ptr);\n\nVersion 1.2.8rc3 [November 28, 2004]\n  Reverted pngrutil.c to version libpng-1.2.8beta5.\n  Added scripts/makefile.elf with supporting code in pngconf.h for symbol\n    versioning (John Bowler).\n\nVersion 1.2.8rc4 [November 29, 2004]\n  Added projects/visualc7 (Simon-pierre).\n\nVersion 1.2.8rc5 [November 29, 2004]\n  Fixed new typo in scripts/pngw32.rc\n\nVersion 1.2.8 [December 3, 2004]\n  Removed projects/visualc7, added projects/visualc71.\n\nVersion 1.2.9beta1 [February 21, 2006]\n  Initialized some structure members in pngwutil.c to avoid gcc-4.0.0 complaints\n  Revised man page and libpng.txt to make it clear that one should not call\n    png_read_end or png_write_end after png_read_png or png_write_png.\n  Updated references to png-mng-implement mailing list.\n  Fixed an incorrect typecast in pngrutil.c\n  Added PNG_NO_READ_SUPPORTED conditional for making a write-only library.\n  Added PNG_NO_WRITE_INTERLACING_SUPPORTED conditional.\n  Optimized alpha-inversion loops in pngwtran.c\n  Moved test for nonzero gamma outside of png_build_gamma_table() in pngrtran.c\n  Make sure num_trans is <= 256 before copying data in png_set_tRNS().\n  Make sure num_palette is <= 256 before copying data in png_set_PLTE().\n  Interchanged order of write_swap_alpha and write_invert_alpha transforms.\n  Added parentheses in the definition of PNG_LIBPNG_BUILD_TYPE (Cosmin).\n  Optimized zlib window flag (CINFO) in contrib/pngsuite/*.png (Cosmin).\n  Updated scripts/makefile.bc32 for Borland C++ 5.6 (Cosmin).\n  Exported png_get_uint_32, png_save_uint_32, png_get_uint_16, png_save_uint_16,\n    png_get_int_32, png_save_int_32, png_get_uint_31 (Cosmin).\n  Added type cast (png_byte) in png_write_sCAL() (Cosmin).\n  Fixed scripts/makefile.cygwin (Christian Biesinger, Cosmin).\n  Default iTXt support was inadvertently enabled.\n\nVersion 1.2.9beta2 [February 21, 2006]\n  Check for png_rgb_to_gray and png_gray_to_rgb read transformations before\n    checking for png_read_dither in pngrtran.c\n  Revised checking of chromaticity limits to accommodate extended RGB\n    colorspace (John Denker).\n  Changed line endings in some of the project files to CRLF, even in the\n    \"Unix\" tar distributions (Cosmin).\n  Made png_get_int_32 and png_save_int_32 always available (Cosmin).\n  Updated scripts/pngos2.def, scripts/pngw32.def and projects/wince/png32ce.def\n    with the newly exported functions.\n  Eliminated distributions without the \"configure\" script.\n  Updated INSTALL instructions.\n\nVersion 1.2.9beta3 [February 24, 2006]\n  Fixed CRCRLF line endings in contrib/visupng/VisualPng.dsp\n  Made libpng.pc respect EXEC_PREFIX (D. P. Kreil, J. Bowler)\n  Removed reference to pngasmrd.h from Makefile.am\n  Renamed CHANGES to ChangeLog.\n  Renamed LICENSE to COPYING.\n  Renamed ANNOUNCE to NEWS.\n  Created AUTHORS file.\n\nVersion 1.2.9beta4 [March 3, 2006]\n  Changed definition of PKGCONFIG from $prefix/lib to $libdir in configure.ac\n  Reverted to filenames LICENSE and ANNOUNCE; removed AUTHORS and COPYING.\n  Removed newline from the end of some error and warning messages.\n  Removed test for sqrt() from configure.ac and configure.\n  Made swap tables in pngtrans.c PNG_CONST (Carlo Bramix).\n  Disabled default iTXt support that was inadvertently enabled in\n    libpng-1.2.9beta1.\n  Added \"OS2\" to list of systems that don't need underscores, in pnggccrd.c\n  Removed libpng version and date from *.c files.\n\nVersion 1.2.9beta5 [March 4, 2006]\n  Removed trailing blanks from source files.\n  Put version and date of latest change in each source file, and changed\n    copyright year accordingly.\n  More cleanup of configure.ac, Makefile.am, and associated scripts.\n  Restored scripts/makefile.elf which was inadvertently deleted.\n\nVersion 1.2.9beta6 [March 6, 2006]\n  Fixed typo (RELEASE) in configuration files.\n\nVersion 1.2.9beta7 [March 7, 2006]\n  Removed libpng.vers and libpng.sym from libpng12_la_SOURCES in Makefile.am\n  Fixed inconsistent #ifdef's around png_sig_bytes() and png_set_sCAL_s()\n    in png.h.\n  Updated makefile.elf as suggested by debian.\n  Made cosmetic changes to some makefiles, adding LN_SF and other macros.\n  Made some makefiles accept \"exec_prefix\".\n\nVersion 1.2.9beta8 [March 9, 2006]\n  Fixed some \"#if defined (...\" which should be \"#if defined(...\"\n    Bug introduced in libpng-1.2.8.\n  Fixed inconsistency in definition of png_default_read_data()\n  Restored blank that was lost from makefile.sggcc \"clean\" target in beta7.\n  Revised calculation of \"current\" and \"major\" for irix in ltmain.sh\n  Changed \"mkdir\" to \"MKDIR_P\" in some makefiles.\n  Separated PNG_EXPAND and PNG_EXPAND_tRNS.\n  Added png_set_expand_gray_1_2_4_to_8() and deprecated\n    png_set_gray_1_2_4_to_8() which also expands tRNS to alpha.\n\nVersion 1.2.9beta9 [March 10, 2006]\n  Include \"config.h\" in pngconf.h when available.\n  Added some checks for NULL png_ptr or NULL info_ptr (timeless)\n\nVersion 1.2.9beta10 [March 20, 2006]\n  Removed extra CR from contrib/visualpng/VisualPng.dsw (Cosmin)\n  Made pnggccrd.c PIC-compliant (Christian Aichinger).\n  Added makefile.mingw (Wolfgang Glas).\n  Revised pngconf.h MMX checking.\n\nVersion 1.2.9beta11 [March 22, 2006]\n  Fixed out-of-order declaration in pngwrite.c that was introduced in beta9\n  Simplified some makefiles by using LIBSO, LIBSOMAJ, and LIBSOVER macros.\n\nVersion 1.2.9rc1 [March 31, 2006]\n  Defined PNG_USER_PRIVATEBUILD when including \"pngusr.h\" (Cosmin).\n  Removed nonsensical assertion check from pngtest.c (Cosmin).\n\nVersion 1.2.9 [April 14, 2006]\n  Revised makefile.beos and added \"none\" selector in ltmain.sh\n\nVersion 1.2.10beta1 [April 15, 2006]\n  Renamed \"config.h\" to \"png_conf.h\" and revised Makefile.am to add\n    -DPNG_BUILDING_LIBPNG to compile directive, and modified pngconf.h\n    to include png_conf.h only when PNG_BUILDING_LIBPNG is defined.\n\nVersion 1.2.10beta2 [April 15, 2006]\n  Manually updated Makefile.in and configure.  Changed png_conf.h.in\n    back to config.h.\n\nVersion 1.2.10beta3 [April 15, 2006]\n  Change png_conf.h back to config.h in pngconf.h.\n\nVersion 1.2.10beta4 [April 16, 2006]\n  Change PNG_BUILDING_LIBPNG to PNG_CONFIGURE_LIBPNG in config/Makefile*.\n\nVersion 1.2.10beta5 [April 16, 2006]\n  Added a configure check for compiling assembler code in pnggccrd.c\n\nVersion 1.2.10beta6 [April 17, 2006]\n  Revised the configure check for pnggccrd.c\n  Moved -DPNG_CONFIGURE_LIBPNG into @LIBPNG_DEFINES@\n  Added @LIBPNG_DEFINES@ to arguments when building libpng.sym\n\nVersion 1.2.10beta7 [April 18, 2006]\n  Change \"exec_prefix=$prefix\" to \"exec_prefix=$(prefix)\" in makefiles.\n\nVersion 1.2.10rc1 [April 19, 2006]\n  Ensure pngconf.h doesn't define both PNG_USE_PNGGCCRD and PNG_USE_PNGVCRD\n  Fixed \"LN_FS\" typo in makefile.sco and makefile.solaris.\n\nVersion 1.2.10rc2 [April 20, 2006]\n  Added a backslash between -DPNG_CONFIGURE_LIBPNG and -DPNG_NO_ASSEMBLER_CODE\n   in configure.ac and configure\n  Made the configure warning about versioned symbols less arrogant.\n\nVersion 1.2.10rc3 [April 21, 2006]\n  Added a note in libpng.txt that png_set_sig_bytes(8) can be used when\n    writing an embedded PNG without the 8-byte signature.\n  Revised makefiles and configure to avoid making links to libpng.so.*\n\nVersion 1.2.10 [April 23, 2006]\n  Reverted configure to \"rc2\" state.\n\nVersion 1.2.11beta1 [May 31, 2006]\n  scripts/libpng.pc.in contained \"configure\" style version info and would\n    not work with makefiles.\n  The shared-library makefiles were linking to libpng.so.0 instead of\n    libpng.so.3 compatibility as the library.\n\nVersion 1.2.11beta2 [June 2, 2006]\n  Increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid\n    buffer overflow.\n  Fixed bug in example.c (png_set_palette_rgb -> png_set_palette_to_rgb)\n\nVersion 1.2.11beta3 [June 5, 2006]\n  Prepended \"#! /bin/sh\" to ltmail.sh and contrib/pngminus/*.sh (Cosmin).\n  Removed the accidental leftover Makefile.in~ (Cosmin).\n  Avoided potential buffer overflow and optimized buffer in\n    png_write_sCAL(), png_write_sCAL_s() (Cosmin).\n  Removed the include directories and libraries from CFLAGS and LDFLAGS\n    in scripts/makefile.gcc (Nelson A. de Oliveira, Cosmin).\n\nVersion 1.2.11beta4 [June 6, 2006]\n  Allow zero-length IDAT chunks after the entire zlib datastream, but not\n    after another intervening chunk type.\n\nVersion 1.0.19rc1, 1.2.11rc1 [June 13, 2006]\n  Deleted extraneous square brackets from [config.h] in configure.ac\n\nVersion 1.0.19rc2, 1.2.11rc2 [June 14, 2006]\n  Added prototypes for PNG_INCH_CONVERSIONS functions to png.h\n  Revised INSTALL and autogen.sh\n  Fixed typo in several makefiles (-W1 should be -Wl)\n  Added typedef for png_int_32 and png_uint_32 on 64-bit systems.\n\nVersion 1.0.19rc3, 1.2.11rc3 [June 15, 2006]\n  Removed the new typedefs for 64-bit systems (delay until version 1.4.0)\n  Added one zero element to png_gamma_shift[] array in pngrtran.c to avoid\n    reading out of bounds.\n\nVersion 1.0.19rc4, 1.2.11rc4 [June 15, 2006]\n  Really removed the new typedefs for 64-bit systems.\n\nVersion 1.0.19rc5, 1.2.11rc5 [June 22, 2006]\n  Removed png_sig_bytes entry from scripts/pngw32.def\n\nVersion 1.0.19, 1.2.11 [June 26, 2006]\n  None.\n\nVersion 1.0.20, 1.2.12 [June 27, 2006]\n  Really increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid\n    buffer overflow.\n\nVersion 1.2.13beta1 [October 2, 2006]\n  Removed AC_FUNC_MALLOC from configure.ac\n  Work around Intel-Mac compiler bug by setting PNG_NO_MMX_CODE in pngconf.h\n  Change \"logical\" to \"bitwise\" throughout documentation.\n  Detect and fix attempt to write wrong iCCP profile length (CVE-2006-7244)\n\nVersion 1.0.21, 1.2.13 [November 14, 2006]\n  Fix potential buffer overflow in sPLT chunk handler.\n  Fix Makefile.am to not try to link to noexistent files.\n  Check all exported functions for NULL png_ptr.\n\nVersion 1.2.14beta1 [November 17, 2006]\n  Relocated three misplaced tests for NULL png_ptr.\n  Built Makefile.in with automake-1.9.6 instead of 1.9.2.\n  Build configure with autoconf-2.60 instead of 2.59\n\nVersion 1.2.14beta2 [November 17, 2006]\n  Added some typecasts in png_zalloc().\n\nVersion 1.2.14rc1 [November 20, 2006]\n  Changed \"strtod\" to \"png_strtod\" in pngrutil.c\n\nVersion 1.0.22, 1.2.14    [November 27, 2006]\n  Added missing \"$(srcdir)\" in Makefile.am and Makefile.in\n\nVersion 1.2.15beta1 [December 3, 2006]\n  Generated configure with autoconf-2.61 instead of 2.60\n  Revised configure.ac to update libpng.pc and libpng-config.\n\nVersion 1.2.15beta2 [December 3, 2006]\n  Always export MMX asm functions, just stubs if not building pnggccrd.c\n\nVersion 1.2.15beta3 [December 4, 2006]\n  Add \"png_bytep\" typecast to profile while calculating length in pngwutil.c\n\nVersion 1.2.15beta4 [December 7, 2006]\n  Added scripts/CMakeLists.txt\n  Changed PNG_NO_ASSEMBLER_CODE to PNG_NO_MMX_CODE in scripts, like 1.4.0beta\n\nVersion 1.2.15beta5 [December 7, 2006]\n  Changed some instances of PNG_ASSEMBLER_* to PNG_MMX_* in pnggccrd.c\n  Revised scripts/CMakeLists.txt\n\nVersion 1.2.15beta6 [December 13, 2006]\n  Revised scripts/CMakeLists.txt and configure.ac\n\nVersion 1.2.15rc1 [December 18, 2006]\n  Revised scripts/CMakeLists.txt\n\nVersion 1.2.15rc2 [December 21, 2006]\n  Added conditional #undef jmpbuf in pngtest.c to undo #define in AIX headers.\n  Added scripts/makefile.nommx\n\nVersion 1.2.15rc3 [December 25, 2006]\n  Fixed shared library numbering error that was introduced in 1.2.15beta6.\n\nVersion 1.2.15rc4 [December 27, 2006]\n  Fixed handling of rgb_to_gray when png_ptr->color.gray isn't set.\n\nVersion 1.2.15rc5 [December 31, 2006]\n  Revised handling of rgb_to_gray.\n\nVersion 1.2.15 [January 5, 2007]\n  Added some (unsigned long) typecasts in pngtest.c to avoid printing errors.\n\nVersion 1.2.16beta1 [January 6, 2007]\n  Fix bugs in makefile.nommx\n\nVersion 1.2.16beta2 [January 16, 2007]\n  Revised scripts/CMakeLists.txt\n\nVersion 1.2.16 [January 31, 2007]\n  No changes.\n\nVersion 1.2.17beta1 [March 6, 2007]\n  Revised scripts/CMakeLists.txt to install both shared and static libraries.\n  Deleted a redundant line from pngset.c.\n\nVersion 1.2.17beta2 [April 26, 2007]\n  Relocated misplaced test for png_ptr == NULL in pngpread.c\n  Change \"==\" to \"&\" for testing PNG_RGB_TO_GRAY_ERR & PNG_RGB_TO_GRAY_WARN\n    flags.\n  Changed remaining instances of PNG_ASSEMBLER_* to PNG_MMX_*\n  Added pngerror() when write_IHDR fails in deflateInit2().\n  Added \"const\" to some array declarations.\n  Mention examples of libpng usage in the libpng*.txt and libpng.3 documents.\n\nVersion 1.2.17rc1 [May 4, 2007]\n  No changes.\n\nVersion 1.2.17rc2 [May 8, 2007]\n  Moved several PNG_HAVE_* macros out of PNG_INTERNAL because applications\n    calling set_unknown_chunk_location() need them.\n  Changed transformation flag from PNG_EXPAND_tRNS to PNG_EXPAND in\n    png_set_expand_gray_1_2_4_to_8().\n  Added png_ptr->unknown_chunk to hold working unknown chunk data, so it\n    can be free'ed in case of error.  Revised unknown chunk handling in\n    pngrutil.c and pngpread.c to use this structure.\n\nVersion 1.2.17rc3 [May 8, 2007]\n  Revised symbol-handling in configure script.\n\nVersion 1.2.17rc4 [May 10, 2007]\n  Revised unknown chunk handling to avoid storing unknown critical chunks.\n\nVersion 1.0.25 [May 15, 2007]\nVersion 1.2.17 [May 15, 2007]\n  Added \"png_ptr->num_trans=0\" before error return in png_handle_tRNS,\n    to eliminate a vulnerability (CVE-2007-2445, CERT VU#684664)\n\nVersion 1.0.26 [May 15, 2007]\nVersion 1.2.18 [May 15, 2007]\n  Reverted the libpng-1.2.17rc3 change to symbol-handling in configure script\n\nVersion 1.2.19beta1 [May 18, 2007]\n  Changed \"const static\" to \"static PNG_CONST\" everywhere, mostly undoing\n    change of libpng-1.2.17beta2.  Changed other \"const\" to \"PNG_CONST\"\n  Changed some handling of unused parameters, to avoid compiler warnings.\n    \"if (unused == NULL) return;\" becomes \"unused = unused\".\n\nVersion 1.2.19beta2 [May 18, 2007]\n  Only use the valid bits of tRNS value in png_do_expand() (Brian Cartier)\n\nVersion 1.2.19beta3 [May 19, 2007]\n  Add some \"png_byte\" typecasts in png_check_keyword() and write new_key\n  instead of key in zTXt chunk (Kevin Ryde).\n\nVersion 1.2.19beta4 [May 21, 2007]\n  Add png_snprintf() function and use it in place of sprint() for improved\n    defense against buffer overflows.\n\nVersion 1.2.19beta5 [May 21, 2007]\n  Fixed png_handle_tRNS() to only use the valid bits of tRNS value.\n  Changed handling of more unused parameters, to avoid compiler warnings.\n  Removed some PNG_CONST in pngwutil.c to avoid compiler warnings.\n\nVersion 1.2.19beta6 [May 22, 2007]\n  Added some #ifdef PNG_MMX_CODE_SUPPORTED where needed in pngvcrd.c\n  Added a special \"_MSC_VER\" case that defines png_snprintf to _snprintf\n\nVersion 1.2.19beta7 [May 22, 2007]\n  Squelched png_squelch_warnings() in pnggccrd.c and added\n    an #ifdef PNG_MMX_CODE_SUPPORTED block around the declarations that caused\n    the warnings that png_squelch_warnings was squelching.\n\nVersion 1.2.19beta8 [May 22, 2007]\n  Removed __MMX__ from test in pngconf.h.\n\nVersion 1.2.19beta9 [May 23, 2007]\n  Made png_squelch_warnings() available via PNG_SQUELCH_WARNINGS macro.\n  Revised png_squelch_warnings() so it might work.\n  Updated makefile.sgcc and makefile.solaris; added makefile.solaris-x86.\n\nVersion 1.2.19beta10 [May 24, 2007]\n  Resquelched png_squelch_warnings(), use \"__attribute__((used))\" instead.\n\nVersion 1.4.0beta1 [April 20, 2006]\n  Enabled iTXt support (changes png_struct, thus requires so-number change).\n  Cleaned up PNG_ASSEMBLER_CODE_SUPPORTED vs PNG_MMX_CODE_SUPPORTED\n  Eliminated PNG_1_0_X and PNG_1_2_X macros.\n  Removed deprecated functions png_read_init, png_write_init, png_info_init,\n    png_permit_empty_plte, png_set_gray_1_2_4_to_8, png_check_sig, and\n    removed the deprecated macro PNG_MAX_UINT.\n  Moved \"PNG_INTERNAL\" parts of png.h and pngconf.h into pngintrn.h\n  Removed many WIN32_WCE #ifdefs (Cosmin).\n  Reduced dependency on C-runtime library when on Windows (Simon-Pierre)\n  Replaced sprintf() with png_sprintf() (Simon-Pierre)\n\nVersion 1.4.0beta2 [April 20, 2006]\n  Revised makefiles and configure to avoid making links to libpng.so.*\n  Moved some leftover MMX-related defines from pngconf.h to pngintrn.h\n  Updated scripts/pngos2.def, pngw32.def, and projects/wince/png32ce.def\n\nVersion 1.4.0beta3 [May 10, 2006]\n  Updated scripts/pngw32.def to comment out MMX functions.\n  Added PNG_NO_GET_INT_32 and PNG_NO_SAVE_INT_32 macros.\n  Scripts/libpng.pc.in contained \"configure\" style version info and would\n    not work with makefiles.\n  Revised pngconf.h and added pngconf.h.in, so makefiles and configure can\n    pass defines to libpng and applications.\n\nVersion 1.4.0beta4 [May 11, 2006]\n  Revised configure.ac, Makefile.am, and many of the makefiles to write\n    their defines in pngconf.h.\n\nVersion 1.4.0beta5 [May 15, 2006]\n  Added a missing semicolon in Makefile.am and Makefile.in\n  Deleted extraneous square brackets from configure.ac\n\nVersion 1.4.0beta6 [June 2, 2006]\n  Increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid\n    buffer overflow.\n  Changed sonum from 0 to 1.\n  Removed unused prototype for png_check_sig() from png.h\n\nVersion 1.4.0beta7 [June 16, 2006]\n  Exported png_write_sig (Cosmin).\n  Optimized buffer in png_handle_cHRM() (Cosmin).\n  Set pHYs = 2835 x 2835 pixels per meter, and added\n    sCAL = 0.352778e-3 x 0.352778e-3 meters, in pngtest.png (Cosmin).\n  Added png_set_benign_errors(), png_benign_error(), png_chunk_benign_error().\n  Added typedef for png_int_32 and png_uint_32 on 64-bit systems.\n  Added \"(unsigned long)\" typecast on png_uint_32 variables in printf lists.\n\nVersion 1.4.0beta8 [June 22, 2006]\n  Added demonstration of user chunk support in pngtest.c, to support the\n    public sTER chunk and a private vpAg chunk.\n\nVersion 1.4.0beta9 [July 3, 2006]\n  Removed ordinals from scripts/pngw32.def and removed png_info_int and\n    png_set_gray_1_2_4_to_8 entries.\n  Inline call of png_get_uint_32() in png_get_uint_31().\n  Use png_get_uint_31() to get vpAg width and height in pngtest.c\n  Removed WINCE and Netware projects.\n  Removed standalone Y2KINFO file.\n\nVersion 1.4.0beta10 [July 12, 2006]\n  Eliminated automatic copy of pngconf.h to pngconf.h.in from configure and\n    some makefiles, because it was not working reliably.  Instead, distribute\n    pngconf.h.in along with pngconf.h and cause configure and some of the\n    makefiles to update pngconf.h from pngconf.h.in.\n  Added pngconf.h to DEPENDENCIES in Makefile.am\n\nVersion 1.4.0beta11 [August 19, 2006]\n  Removed AC_FUNC_MALLOC from configure.ac.\n  Added a warning when writing iCCP profile with mismatched profile length.\n  Patched pnggccrd.c to assemble on x86_64 platforms.\n  Moved chunk header reading into a separate function png_read_chunk_header()\n    in pngrutil.c.  The chunk header (len+sig) is now serialized in a single\n    operation (Cosmin).\n  Implemented support for I/O states. Added png_ptr member io_state, and\n    functions png_get_io_chunk_name() and png_get_io_state() in pngget.c\n    (Cosmin).\n  Added png_get_io_chunk_name and png_get_io_state to scripts/*.def (Cosmin).\n  Renamed scripts/pngw32.* to scripts/pngwin.* (Cosmin).\n  Removed the include directories and libraries from CFLAGS and LDFLAGS\n    in scripts/makefile.gcc (Cosmin).\n  Used png_save_uint_32() to set vpAg width and height in pngtest.c (Cosmin).\n  Cast to proper type when getting/setting vpAg units in pngtest.c (Cosmin).\n  Added pngintrn.h to the Visual C++ projects (Cosmin).\n  Removed scripts/list (Cosmin).\n  Updated copyright year in scripts/pngwin.def (Cosmin).\n  Removed PNG_TYPECAST_NULL and used standard NULL consistently (Cosmin).\n  Disallowed the user to redefine png_size_t, and enforced a consistent use\n    of png_size_t across libpng (Cosmin).\n  Changed the type of png_ptr->rowbytes, PNG_ROWBYTES() and friends\n    to png_size_t (Cosmin).\n  Removed png_convert_size() and replaced png_sizeof with sizeof (Cosmin).\n  Removed some unnecessary type casts (Cosmin).\n  Changed prototype of png_get_compression_buffer_size() and\n    png_set_compression_buffer_size() to work with png_size_t instead of\n    png_uint_32 (Cosmin).\n  Removed png_memcpy_check() and png_memset_check() (Cosmin).\n  Fixed a typo (png_byte --> png_bytep) in libpng.3 and libpng.txt (Cosmin).\n  Clarified that png_zalloc() does not clear the allocated memory,\n    and png_zalloc() and png_zfree() cannot be PNGAPI (Cosmin).\n  Renamed png_mem_size_t to png_alloc_size_t, fixed its definition in\n    pngconf.h, and used it in all memory allocation functions (Cosmin).\n  Renamed pngintrn.h to pngpriv.h, added a comment at the top of the file\n    mentioning that the symbols declared in that file are private, and\n    updated the scripts and the Visual C++ projects accordingly (Cosmin).\n  Removed circular references between pngconf.h and pngconf.h.in in\n    scripts/makefile.vc*win32 (Cosmin).\n  Removing trailing '.' from the warning and error messages (Cosmin).\n  Added pngdefs.h that is built by makefile or configure, instead of\n    pngconf.h.in (Glenn).\n  Detect and fix attempt to write wrong iCCP profile length.\n\nVersion 1.4.0beta12 [October 19, 2006]\n  Changed \"logical\" to \"bitwise\" in the documentation.\n  Work around Intel-Mac compiler bug by setting PNG_NO_MMX_CODE in pngconf.h\n  Add a typecast to stifle compiler warning in pngrutil.c\n\nVersion 1.4.0beta13 [November 10, 2006]\n  Fix potential buffer overflow in sPLT chunk handler.\n  Fix Makefile.am to not try to link to noexistent files.\n\nVersion 1.4.0beta14 [November 15, 2006]\n  Check all exported functions for NULL png_ptr.\n\nVersion 1.4.0beta15 [November 17, 2006]\n  Relocated two misplaced tests for NULL png_ptr.\n  Built Makefile.in with automake-1.9.6 instead of 1.9.2.\n  Build configure with autoconf-2.60 instead of 2.59\n  Add \"install: all\" in Makefile.am so \"configure; make install\" will work.\n\nVersion 1.4.0beta16 [November 17, 2006]\n  Added a typecast in png_zalloc().\n\nVersion 1.4.0beta17 [December 4, 2006]\n  Changed \"new_key[79] = '\\0';\" to \"(*new_key)[79] = '\\0';\" in pngwutil.c\n  Add \"png_bytep\" typecast to profile while calculating length in pngwutil.c\n\nVersion 1.4.0beta18 [December 7, 2006]\n  Added scripts/CMakeLists.txt\n\nVersion 1.4.0beta19 [May 16, 2007]\n  Revised scripts/CMakeLists.txt\n  Rebuilt configure and Makefile.in with newer tools.\n  Added conditional #undef jmpbuf in pngtest.c to undo #define in AIX headers.\n  Added scripts/makefile.nommx\n\nVersion 1.4.0beta20 [July 9, 2008]\n  Moved several PNG_HAVE_* macros from pngpriv.h to png.h because applications\n    calling set_unknown_chunk_location() need them.\n  Moved several macro definitions from pngpriv.h to pngconf.h\n  Merge with changes to the 1.2.X branch, as of 1.2.30beta04.\n  Deleted all use of the MMX assembler code and Intel-licensed optimizations.\n  Revised makefile.mingw\n\nVersion 1.4.0beta21 [July 21, 2008]\n  Moved local array \"chunkdata\" from pngrutil.c to the png_struct, so\n    it will be freed by png_read_destroy() in case of a read error (Kurt\n    Christensen).\n\nVersion 1.4.0beta22 [July 21, 2008]\n  Change \"purpose\" and \"buffer\" to png_ptr->chunkdata to avoid memory leaking.\n\nVersion 1.4.0beta23 [July 22, 2008]\n  Change \"chunkdata = NULL\" to \"png_ptr->chunkdata = NULL\" several places in\n    png_decompress_chunk().\n\nVersion 1.4.0beta24 [July 25, 2008]\n  Change all remaining \"chunkdata\" to \"png_ptr->chunkdata\" in\n    png_decompress_chunk(), and remove \"chunkdata\" from parameter list.\n  Put a call to png_check_chunk_name() in png_read_chunk_header().\n  Revised png_check_chunk_name() to reject a name with a lowercase 3rd byte.\n  Removed two calls to png_check_chunk_name() occurring later in the process.\n  Define PNG_NO_ERROR_NUMBERS by default in pngconf.h\n\nVersion 1.4.0beta25 [July 30, 2008]\n  Added a call to png_check_chunk_name() in pngpread.c\n  Reverted png_check_chunk_name() to accept a name with a lowercase 3rd byte.\n  Added png_push_have_buffer() function to pngpread.c\n  Eliminated PNG_BIG_ENDIAN_SUPPORTED and associated png_get_* macros.\n  Made inline expansion of png_get_*() optional with PNG_USE_READ_MACROS.\n  Eliminated all PNG_USELESS_TESTS and PNG_CORRECT_PALETTE_SUPPORTED code.\n  Synced contrib directory and configure files with libpng-1.2.30beta06.\n  Eliminated no-longer-used pngdefs.h (but it's still built in the makefiles)\n  Relocated a misplaced \"#endif /* PNG_NO_WRITE_FILTER */\" in pngwutil.c\n\nVersion 1.4.0beta26 [August 4, 2008]\n  Removed png_push_have_buffer() function in pngpread.c.  It increased the\n    compiled library size slightly.\n  Changed \"-Wall\" to \"-W -Wall\" in the CFLAGS in all makefiles (Cosmin Truta)\n  Declared png_ptr \"volatile\" in pngread.c and pngwrite.c to avoid warnings.\n  Updated contrib/visupng/cexcept.h to version 2.0.1\n  Added PNG_LITERAL_CHARACTER macros for #, [, and ].\n\nVersion 1.4.0beta27 [August 5, 2008]\n  Revised usage of PNG_LITERAL_SHARP in pngerror.c.\n  Moved newline character from individual png_debug messages into the\n    png_debug macros.\n  Allow user to #define their own png_debug, png_debug1, and png_debug2.\n\nVersion 1.4.0beta28 [August 5, 2008]\n  Revised usage of PNG_LITERAL_SHARP in pngerror.c.\n  Added PNG_STRING_NEWLINE macro\n\nVersion 1.4.0beta29 [August 9, 2008]\n  Revised usage of PNG_STRING_NEWLINE to work on non-ISO compilers.\n  Added PNG_STRING_COPYRIGHT macro.\n  Added non-ISO versions of png_debug macros.\n\nVersion 1.4.0beta30 [August 14, 2008]\n  Added premultiplied alpha feature (Volker Wiendl).\n\nVersion 1.4.0beta31 [August 18, 2008]\n  Moved png_set_premultiply_alpha from pngtrans.c to pngrtran.c\n  Removed extra crc check at the end of png_handle_cHRM().  Bug introduced\n    in libpng-1.4.0beta20.\n\nVersion 1.4.0beta32 [August 19, 2008]\n  Added PNG_WRITE_FLUSH_SUPPORTED block around new png_flush() call.\n  Revised PNG_NO_STDIO version of png_write_flush()\n\nVersion 1.4.0beta33 [August 20, 2008]\n  Added png_get|set_chunk_cache_max() to limit the total number of sPLT,\n    text, and unknown chunks that can be stored.\n\nVersion 1.4.0beta34 [September 6, 2008]\n  Shortened tIME_string to 29 bytes in pngtest.c\n  Fixed off-by-one error introduced in png_push_read_zTXt() function in\n    libpng-1.2.30beta04/pngpread.c (Harald van Dijk)\n\nVersion 1.4.0beta35 [October 6, 2008]\n  Changed \"trans_values\" to \"trans_color\".\n  Changed so-number from 0 to 14.  Some OS do not like 0.\n  Revised makefile.darwin to fix shared library numbering.\n  Change png_set_gray_1_2_4_to_8() to png_set_expand_gray_1_2_4_to_8()\n    in example.c (debian bug report)\n\nVersion 1.4.0beta36 [October 25, 2008]\n  Sync with tEXt vulnerability fix in libpng-1.2.33rc02.\n\nVersion 1.4.0beta37 [November 13, 2008]\n  Added png_check_cHRM in png.c and moved checking from pngget.c, pngrutil.c,\n    and pngwrite.c\n\nVersion 1.4.0beta38 [November 22, 2008]\n  Added check for zero-area RGB cHRM triangle in png_check_cHRM() and\n    png_check_cHRM_fixed().\n\nVersion 1.4.0beta39 [November 23, 2008]\n  Revised png_warning() to write its message on standard output by default\n    when warning_fn is NULL.\n\nVersion 1.4.0beta40 [November 24, 2008]\n  Eliminated png_check_cHRM().  Instead, always use png_check_cHRM_fixed().\n  In png_check_cHRM_fixed(), ensure white_y is > 0, and removed redundant\n    check for all-zero coordinates that is detected by the triangle check.\n\nVersion 1.4.0beta41 [November 26, 2008]\n  Fixed string vs pointer-to-string error in png_check_keyword().\n  Rearranged test expressions in png_check_cHRM_fixed() to avoid internal\n    overflows.\n  Added PNG_NO_CHECK_cHRM conditional.\n\nVersion 1.4.0beta42, 43 [December 1, 2008]\n  Merge png_debug with version 1.2.34beta04.\n\nVersion 1.4.0beta44 [December 6, 2008]\n  Removed redundant check for key==NULL before calling png_check_keyword()\n    to ensure that new_key gets initialized and removed extra warning\n    (Merge with version 1.2.34beta05 -- Arvan Pritchard).\n\nVersion 1.4.0beta45 [December 9, 2008]\n  In png_write_png(), respect the placement of the filler bytes in an earlier\n    call to png_set_filler() (Jim Barry).\n\nVersion 1.4.0beta46 [December 10, 2008]\n  Undid previous change and added PNG_TRANSFORM_STRIP_FILLER_BEFORE and\n    PNG_TRANSFORM_STRIP_FILLER_AFTER conditionals and deprecated\n    PNG_TRANSFORM_STRIP_FILLER (Jim Barry).\n\nVersion 1.4.0beta47 [December 15, 2008]\n  Support for dithering was disabled by default, because it has never\n    been well tested and doesn't work very well.  The code has not\n    been removed, however, and can be enabled by building libpng with\n    PNG_READ_DITHER_SUPPORTED defined.\n\nVersion 1.4.0beta48 [February 14, 2009]\n  Added new exported function png_calloc().\n  Combined several instances of png_malloc(); png_memset() into png_calloc().\n  Removed prototype for png_freeptr() that was added in libpng-1.4.0beta24\n    but was never defined.\n\nVersion 1.4.0beta49 [February 28, 2009]\n  Added png_fileno() macro to pngconf.h, used in pngwio.c\n  Corrected order of #ifdef's in png_debug definition in png.h\n  Fixed bug introduced in libpng-1.4.0beta48 with the memset arguments\n    for pcal_params.\n  Fixed order of #ifdef directives in the png_debug defines in png.h\n    (bug introduced in libpng-1.2.34/1.4.0beta29).\n  Revised comments in png_set_read_fn() and png_set_write_fn().\n\nVersion 1.4.0beta50 [March 18, 2009]\n  Use png_calloc() instead of png_malloc() to allocate big_row_buf when\n    reading an interlaced file, to avoid a possible UMR.\n  Undid revision of PNG_NO_STDIO version of png_write_flush().  Users\n    having trouble with fflush() can build with PNG_NO_WRITE_FLUSH defined\n    or supply their own flush_fn() replacement.\n  Revised libpng*.txt and png.h documentation about use of png_write_flush()\n    and png_set_write_fn().\n  Removed fflush() from pngtest.c.\n  Added \"#define PNG_NO_WRITE_FLUSH\" to contrib/pngminim/encoder/pngusr.h\n\nVersion 1.4.0beta51 [March 21, 2009]\n  Removed new png_fileno() macro from pngconf.h .\n\nVersion 1.4.0beta52 [March 27, 2009]\n  Relocated png_do_chop() ahead of building gamma tables in pngrtran.c\n    This avoids building 16-bit gamma tables unnecessarily.\n  Removed fflush() from pngtest.c.\n  Added \"#define PNG_NO_WRITE_FLUSH\" to contrib/pngminim/encoder/pngusr.h\n  Added a section on differences between 1.0.x and 1.2.x to libpng.3/libpng.txt\n\nVersion 1.4.0beta53 [April 1, 2009]\n  Removed some remaining MMX macros from pngpriv.h\n  Fixed potential memory leak of \"new_name\" in png_write_iCCP() (Ralph Giles)\n\nVersion 1.4.0beta54 [April 13, 2009]\n  Added \"ifndef PNG_SKIP_SETJMP_CHECK\" block in pngconf.h to allow\n    application code writers to bypass the check for multiple inclusion\n    of setjmp.h when they know that it is safe to ignore the situation.\n  Eliminated internal use of setjmp() in pngread.c and pngwrite.c\n  Reordered ancillary chunks in pngtest.png to be the same as what\n    pngtest now produces, and made some cosmetic changes to pngtest output.\n  Eliminated deprecated png_read_init_3() and png_write_init_3() functions.\n\nVersion 1.4.0beta55 [April 15, 2009]\n  Simplified error handling in pngread.c and pngwrite.c by putting\n    the new png_read_cleanup() and png_write_cleanup() functions inline.\n\nVersion 1.4.0beta56 [April 25, 2009]\n  Renamed \"user_chunk_data\" to \"my_user_chunk_data\" in pngtest.c to suppress\n    \"shadowed declaration\" warning from gcc-4.3.3.\n  Renamed \"gamma\" to \"png_gamma\" in pngset.c to avoid \"shadowed declaration\"\n    warning about a global \"gamma\" variable in math.h on some platforms.\n\nVersion 1.4.0beta57 [May 2, 2009]\n  Removed prototype for png_freeptr() that was added in libpng-1.4.0beta24\n    but was never defined (again).\n  Rebuilt configure scripts with autoconf-2.63 instead of 2.62\n  Removed pngprefs.h and MMX from makefiles\n\nVersion 1.4.0beta58 [May 14, 2009]\n  Changed pngw32.def to pngwin.def in makefile.mingw (typo was introduced\n    in beta57).\n  Clarified usage of sig_bit versus sig_bit_p in example.c (Vincent Torri)\n\nVersion 1.4.0beta59 [May 15, 2009]\n  Reformated sources in libpng style (3-space intentation, comment format)\n  Fixed typo in libpng docs (PNG_FILTER_AVE should be PNG_FILTER_AVG)\n  Added sections about the git repository and our coding style to the\n    documentation\n  Relocated misplaced #endif in pngwrite.c, sCAL chunk handler.\n\nVersion 1.4.0beta60 [May 19, 2009]\n  Conditionally compile png_read_finish_row() which is not used by\n    progressive readers.\n  Added contrib/pngminim/preader to demonstrate building minimal progressive\n    decoder, based on contrib/gregbook with embedded libpng and zlib.\n\nVersion 1.4.0beta61 [May 20, 2009]\n  In contrib/pngminim/*, renamed \"makefile.std\" to \"makefile\", since there\n    is only one makefile in those directories, and revised the README files\n    accordingly.\n  More reformatting of comments, mostly to capitalize sentences.\n\nVersion 1.4.0beta62 [June 2, 2009]\n  Added \"#define PNG_NO_WRITE_SWAP\" to contrib/pngminim/encoder/pngusr.h\n    and \"define PNG_NO_READ_SWAP\" to decoder/pngusr.h and preader/pngusr.h\n  Reformatted several remaining \"else statement\" into two lines.\n  Added a section to the libpng documentation about using png_get_io_ptr()\n    in configure scripts to detect the presence of libpng.\n\nVersion 1.4.0beta63 [June 15, 2009]\n  Revised libpng*.txt and libpng.3 to mention calling png_set_IHDR()\n    multiple times and to specify the sample order in the tRNS chunk,\n    because the ISO PNG specification has a typo in the tRNS table.\n  Changed several PNG_UNKNOWN_CHUNK_SUPPORTED to\n    PNG_HANDLE_AS_UNKNOWN_SUPPORTED, to make the png_set_keep mechanism\n    available for ignoring known chunks even when not saving unknown chunks.\n  Adopted preference for consistent use of \"#ifdef\" and \"#ifndef\" versus\n    \"#if defined()\" and \"if !defined()\" where possible.\n\nVersion 1.4.0beta64 [June 24, 2009]\n  Eliminated PNG_LEGACY_SUPPORTED code.\n  Moved the various unknown chunk macro definitions outside of the\n    PNG_READ|WRITE_ANCILLARY_CHUNK_SUPPORTED blocks.\n\nVersion 1.4.0beta65 [June 26, 2009]\n  Added a reference to the libpng license in each file.\n\nVersion 1.4.0beta66 [June 27, 2009]\n  Refer to the libpng license instead of the libpng license in each file.\n\nVersion 1.4.0beta67 [July 6, 2009]\n  Relocated INVERT_ALPHA within png_read_png() and png_write_png().\n  Added high-level API transform PNG_TRANSFORM_GRAY_TO_RGB.\n  Added an \"xcode\" project to the projects directory (Alam Arias).\n\nVersion 1.4.0beta68 [July 19, 2009]\n  Avoid some tests in filter selection in pngwutil.c\n\nVersion 1.4.0beta69 [July 25, 2009]\n  Simplified the new filter-selection test.  This runs faster in the\n    common \"PNG_ALL_FILTERS\" and PNG_FILTER_NONE cases.\n  Removed extraneous declaration from the new call to png_read_gray_to_rgb()\n    (bug introduced in libpng-1.4.0beta67).\n  Fixed up xcode project (Alam Arias)\n  Added a prototype for png_64bit_product() in png.c\n\nVersion 1.4.0beta70 [July 27, 2009]\n  Avoid a possible NULL dereference in debug build, in png_set_text_2().\n    (bug introduced in libpng-0.95, discovered by Evan Rouault)\n\nVersion 1.4.0beta71 [July 29, 2009]\n  Rebuilt configure scripts with autoconf-2.64.\n\nVersion 1.4.0beta72 [August 1, 2009]\n  Replaced *.tar.lzma with *.tar.xz in distribution.  Get the xz codec\n    from <http://tukaani.org/xz>.\n\nVersion 1.4.0beta73 [August 1, 2009]\n  Reject attempt to write iCCP chunk with negative embedded profile length\n    (JD Chen) (CVE-2009-5063).\n\nVersion 1.4.0beta74 [August 8, 2009]\n  Changed png_ptr and info_ptr member \"trans\" to \"trans_alpha\".\n\nVersion 1.4.0beta75 [August 21, 2009]\n  Removed an extra png_debug() recently added to png_write_find_filter().\n  Fixed incorrect #ifdef in pngset.c regarding unknown chunk support.\n\nVersion 1.4.0beta76 [August 22, 2009]\n  Moved an incorrectly located test in png_read_row() in pngread.c\n\nVersion 1.4.0beta77 [August 27, 2009]\n  Removed lpXYZ.tar.bz2 (with CRLF), KNOWNBUG, libpng-x.y.z-KNOWNBUG.txt,\n    and the \"noconfig\" files from the distribution.\n  Moved CMakeLists.txt from scripts into the main libpng directory.\n  Various bugfixes and improvements to CMakeLists.txt (Philip Lowman)\n\nVersion 1.4.0beta78 [August 31, 2009]\n  Converted all PNG_NO_* tests to PNG_*_SUPPORTED everywhere except pngconf.h\n  Eliminated PNG_NO_FREE_ME and PNG_FREE_ME_SUPPORTED macros.\n  Use png_malloc plus a loop instead of png_calloc() to initialize\n    row_pointers in png_read_png().\n\nVersion 1.4.0beta79 [September 1, 2009]\n  Eliminated PNG_GLOBAL_ARRAYS and PNG_LOCAL_ARRAYS; always use local arrays.\n  Eliminated PNG_CALLOC_SUPPORTED macro and always provide png_calloc().\n\nVersion 1.4.0beta80 [September 17, 2009]\n  Removed scripts/libpng.icc\n  Changed typecast of filler from png_byte to png_uint_16 in png_set_filler().\n    (Dennis Gustafsson)\n  Fixed typo introduced in beta78 in pngtest.c (\"#if def \" should be \"#ifdef \")\n\nVersion 1.4.0beta81 [September 23, 2009]\n  Eliminated unused PNG_FLAG_FREE_* defines from pngpriv.h\n  Expanded TAB characters in pngrtran.c\n  Removed PNG_CONST from all \"PNG_CONST PNG_CHNK\" declarations to avoid\n    compiler complaints about doubly declaring things \"const\".\n  Changed all \"#if [!]defined(X)\" to \"if[n]def X\" where possible.\n  Eliminated unused png_ptr->row_buf_size\n\nVersion 1.4.0beta82 [September 25, 2009]\n  Moved redundant IHDR checking into new png_check_IHDR() in png.c\n    and report all errors found in the IHDR data.\n  Eliminated useless call to png_check_cHRM() from pngset.c\n\nVersion 1.4.0beta83 [September 25, 2009]\n  Revised png_check_IHDR() to eliminate bogus complaint about filter_type.\n\nVersion 1.4.0beta84 [September 30, 2009]\n  Fixed some inconsistent indentation in pngconf.h\n  Revised png_check_IHDR() to add a test for width variable less than 32-bit.\n\nVersion 1.4.0beta85 [October 1, 2009]\n  Revised png_check_IHDR() again, to check info_ptr members instead of\n    the contents of the returned parameters.\n\nVersion 1.4.0beta86 [October 9, 2009]\n  Updated the \"xcode\" project (Alam Arias).\n  Eliminated a shadowed declaration of \"pp\" in png_handle_sPLT().\n\nVersion 1.4.0rc01 [October 19, 2009]\n  Trivial cosmetic changes.\n\nVersion 1.4.0beta87 [October 30, 2009]\n  Moved version 1.4.0 back into beta.\n\nVersion 1.4.0beta88 [October 30, 2009]\n  Revised libpng*.txt section about differences between 1.2.x and 1.4.0\n    because most of the new features have now been ported back to 1.2.41\n\nVersion 1.4.0beta89 [November 1, 2009]\n  More bugfixes and improvements to CMakeLists.txt (Philip Lowman)\n  Removed a harmless extra png_set_invert_alpha() from pngwrite.c\n  Apply png_user_chunk_cache_max within png_decompress_chunk().\n  Merged libpng-1.2.41.txt with libpng-1.4.0.txt where appropriate.\n\nVersion 1.4.0beta90 [November 2, 2009]\n  Removed all remaining WIN32_WCE #ifdefs except those involving the\n    time.h \"tm\" structure\n\nVersion 1.4.0beta91 [November 3, 2009]\n  Updated scripts/pngw32.def and projects/wince/png32ce.def\n  Copied projects/wince/png32ce.def to the scripts directory.\n  Added scripts/makefile.wce\n  Patched ltmain.sh for wince support.\n  Added PNG_CONVERT_tIME_SUPPORTED macro.\n\nVersion 1.4.0beta92 [November 4, 2009]\n  Make inclusion of time.h in pngconf.h depend on PNG_CONVERT_tIME_SUPPORTED\n  Make #define PNG_CONVERT_tIME_SUPPORTED depend on PNG_WRITE_tIME_SUPPORTED\n  Revised libpng*.txt to describe differences from 1.2.40 to 1.4.0 (instead\n    of differences from 1.2.41 to 1.4.0)\n\nVersion 1.4.0beta93 [November 7, 2009]\n  Added PNG_DEPSTRUCT, PNG_DEPRECATED, PNG_USE_RESULT, PNG_NORETURN, and\n    PNG_ALLOCATED macros to detect deprecated direct access to the\n    png_struct or info_struct members and other deprecated usage in\n    applications (John Bowler).\n  Updated scripts/makefile* to add \"-DPNG_CONFIGURE_LIBPNG\" to CFLAGS,\n    to prevent warnings about direct access to png structs by libpng\n    functions while building libpng.  They need to be tested, especially\n    those using compilers other than gcc.\n  Updated projects/visualc6 and visualc71 with \"/d PNG_CONFIGURE_LIBPNG\".\n    They should work but still need to be updated to remove\n    references to pnggccrd.c or pngvcrd.c and ASM building.\n  Added README.txt to the beos, cbuilder5, netware, and xcode projects warning\n    that they need to be updated, to remove references to pnggccrd.c and\n    pngvcrd.c and to depend on pngpriv.h\n  Removed three direct references to read_info_ptr members in pngtest.c\n    that were detected by the new PNG_DEPSTRUCT macro.\n  Moved the png_debug macro definitions and the png_read_destroy(),\n    png_write_destroy() and png_far_to_near() prototypes from png.h\n    to pngpriv.h (John Bowler)\n  Moved the synopsis lines for png_read_destroy(), png_write_destroy()\n    png_debug(), png_debug1(), and png_debug2() from libpng.3 to libpngpf.3.\n\nVersion 1.4.0beta94 [November 9, 2009]\n  Removed the obsolete, unused pnggccrd.c and pngvcrd.c files.\n  Updated CMakeLists.txt to add \"-DPNG_CONFIGURE_LIBPNG\" to the definitions.\n  Removed dependency of pngtest.o on pngpriv.h in the makefiles.\n  Only #define PNG_DEPSTRUCT, etc. in pngconf.h if not already defined.\n\nVersion 1.4.0beta95 [November 10, 2009]\n  Changed png_check_sig() to !png_sig_cmp() in contrib programs.\n  Added -DPNG_CONFIGURE_LIBPNG to contrib/pngminm/*/makefile\n  Changed png_check_sig() to !png_sig_cmp() in contrib programs.\n  Corrected the png_get_IHDR() call in contrib/gregbook/readpng2.c\n  Changed pngminim/*/gather.sh to stop trying to remove pnggccrd.c and pngvcrd.c\n  Added dependency on pngpriv.h in contrib/pngminim/*/makefile\n\nVersion 1.4.0beta96 [November 12, 2009]\n  Renamed scripts/makefile.wce to scripts/makefile.cegcc\n  Revised Makefile.am to use libpng.sys while building libpng.so\n    so that only PNG_EXPORT functions are exported.\n  Removed the deprecated png_check_sig() function/macro.\n  Removed recently removed function names from scripts/*.def\n  Revised pngtest.png to put chunks in the same order written by pngtest\n    (evidently the same change made in libpng-1.0beta54 was lost).\n  Added PNG_PRIVATE macro definition in pngconf.h for possible future use.\n\nVersion 1.4.0beta97 [November 13, 2009]\n  Restored pngtest.png to the libpng-1.4.0beta7 version.\n  Removed projects/beos and netware.txt; no one seems to be supporting them.\n  Revised Makefile.in\n\nVersion 1.4.0beta98 [November 13, 2009]\n  Added the \"xcode\" project to zip distributions,\n  Fixed a typo in scripts/pngwin.def introduced in beta97.\n\nVersion 1.4.0beta99 [November 14, 2009]\n  Moved libpng-config.in and libpng.pc-configure.in out of the scripts\n    directory, to libpng-config.in and libpng-pc.in, respectively, and\n    modified Makefile.am and configure.ac accordingly.  Now \"configure\"\n    needs nothing from the \"scripts\" directory.\n  Avoid redefining PNG_CONST in pngconf.h\n\nVersion 1.4.0beta100 [November 14, 2009]\n  Removed ASM builds from projects/visualc6 and projects/visualc71\n  Removed scripts/makefile.nommx and makefile.vcawin32\n  Revised CMakeLists.txt to account for new location of libpng-config.in\n    and libpng-pc.in\n  Updated INSTALL to reflect removal and relocation of files.\n\nVersion 1.4.0beta101 [November 14, 2009]\n  Restored the binary files (*.jpg, *.png, some project files) that were\n    accidentally deleted from the zip and 7z distributions when the xcode\n    project was added.\n\nVersion 1.4.0beta102 [November 18, 2009]\n  Added libpng-config.in and libpng-pc.in to the zip and 7z distributions.\n  Fixed a typo in projects/visualc6/pngtest.dsp, introduced in beta100.\n  Moved descriptions of makefiles and other scripts out of INSTALL into\n    scripts/README.txt\n  Updated the copyright year in scripts/pngwin.rc from 2006 to 2009.\n\nVersion 1.4.0beta103 [November 21, 2009]\n  Removed obsolete comments about ASM from projects/visualc71/README_zlib.txt\n  Align row_buf on 16-byte boundary in memory.\n  Restored the PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED guard around the call\n    to png_flush() after png_write_IEND().  See 1.4.0beta32, 1.4.0beta50\n    changes above and 1.2.30, 1.2.30rc01 and rc03 in 1.2.41 CHANGES.  Someone\n    needs this feature.\n  Make the 'png_jmpbuf' macro expand to a call that records the correct\n    longjmp function as well as returning a pointer to the setjmp\n    jmp_buf buffer, and marked direct access to jmpbuf 'deprecated'.\n    (John Bowler)\n\nVersion 1.4.0beta104 [November 22, 2009]\n  Removed png_longjmp_ptr from scripts/*.def and libpng.3\n  Rebuilt configure scripts with autoconf-2.65\n\nVersion 1.4.0beta105 [November 25, 2009]\n  Use fast integer PNG_DIVIDE_BY_255() or PNG_DIVIDE_BY_65535()\n    to accomplish alpha premultiplication when\n    PNG_READ_COMPOSITE_NODIV_SUPPORTED is defined.\n  Changed \"/255\" to \"/255.0\" in background calculations to make it clear\n    that the 255 is used as a double.\n\nVersion 1.4.0beta106 [November 27, 2009]\n  Removed premultiplied alpha feature.\n\nVersion 1.4.0beta107 [December 4, 2009]\n  Updated README\n  Added \"#define PNG_NO_PEDANTIC_WARNINGS\" in the libpng source files.\n  Removed \"-DPNG_CONFIGURE_LIBPNG\" from the makefiles and projects.\n  Revised scripts/makefile.netbsd, makefile.openbsd, and makefile.sco\n    to put png.h and pngconf.h in $prefix/include, like the other scripts,\n    instead of in $prefix/include/libpng.  Also revised makefile.sco\n    to put them in $prefix/include/libpng15 instead of in\n    $prefix/include/libpng/libpng15.\n\nVersion 1.4.0beta108 [December 11, 2009]\n  Removed leftover \"-DPNG_CONFIGURE_LIBPNG\" from contrib/pngminim/*/makefile\n  Relocated png_do_chop() to its original position in pngrtran.c; the\n    change in version 1.2.41beta08 caused transparency to be handled wrong\n    in some 16-bit datastreams (Yusaku Sugai).\n\nVersion 1.4.0beta109 [December 13, 2009]\n  Added \"bit_depth\" parameter to the private png_build_gamma_table() function.\n  Pass bit_depth=8 to png_build_gamma_table() when bit_depth is 16 but the\n    PNG_16_TO_8 transform has been set, to avoid unnecessary build of 16-bit\n    tables.\n\nVersion 1.4.0rc02 [December 20, 2009]\n  Declared png_cleanup_needed \"volatile\" in pngread.c and pngwrite.c\n\nVersion 1.4.0rc03 [December 22, 2009]\n  Renamed libpng-pc.in back to libpng.pc.in and revised CMakeLists.txt\n    (revising the change in 1.4.0beta99)\n\nVersion 1.4.0rc04 [December 25, 2009]\n  Swapped PNG_UNKNOWN_CHUNKS_SUPPORTED and PNG_HANDLE_AS_UNKNOWN_SUPPORTED\n    in pngset.c to be consistent with other changes in version 1.2.38.\n\nVersion 1.4.0rc05 [December 25, 2009]\n  Changed \"libpng-pc.in\" to \"libpng.pc.in\" in configure.ac, configure, and\n    Makefile.in to be consistent with changes in libpng-1.4.0rc03\n\nVersion 1.4.0rc06 [December 29, 2009]\n  Reverted the gamma_table changes from libpng-1.4.0beta109.\n  Fixed some indentation errors.\n\nVersion 1.4.0rc07 [January 1, 2010]\n  Revised libpng*.txt and libpng.3 about 1.2.x->1.4.x differences.\n  Use png_calloc() instead of png_malloc(); png_memset() in pngrutil.c\n  Update copyright year to 2010.\n\nVersion 1.4.0rc08 [January 2, 2010]\n  Avoid deprecated references to png_ptr-io_ptr and png_ptr->error_ptr\n    in pngtest.c\n\nVersion 1.4.0 [January 3, 2010]\n  No changes.\n\nVersion 1.4.1beta01 [January 8, 2010]\n  Updated CMakeLists.txt for consistent indentation and to avoid an\n    unclosed if-statement warning (Philip Lowman).\n  Revised Makefile.am and Makefile.in to remove references to Y2KINFO,\n    KNOWNBUG, and libpng.la (Robert Schwebel).\n  Revised the makefiles to install the same files and symbolic\n    links as configure, except for libpng.la and libpng14.la.\n  Make png_set|get_compression_buffer_size() available even when\n    PNG_WRITE_SUPPORTED is not enabled.\n  Revised Makefile.am and Makefile.in to simplify their maintenance.\n  Revised scripts/makefile.linux to install a link to libpng14.so.14.1\n\nVersion 1.4.1beta02 [January 9, 2010]\n  Revised the rest of the makefiles to install a link to libpng14.so.14.1\n\nVersion 1.4.1beta03 [January 10, 2010]\n  Removed png_set_premultiply_alpha() from scripts/*.def\n\nVersion 1.4.1rc01 [January 16, 2010]\n  No changes.\n\nVersion 1.4.1beta04 [January 23, 2010]\n  Revised png_decompress_chunk() to improve speed and memory usage when\n    decoding large chunks.\n  Added png_set|get_chunk_malloc_max() functions.\n\nVersion 1.4.1beta05 [January 26, 2010]\n  Relocated \"int k\" declaration in pngtest.c to minimize its scope.\n\nVersion 1.4.1beta06 [January 28, 2010]\n  Revised png_decompress_chunk() to use a two-pass method suggested by\n    John Bowler.\n\nVersion 1.4.1beta07 [February 6, 2010]\n  Folded some long lines in the source files.\n  Added defineable PNG_USER_CHUNK_CACHE_MAX, PNG_USER_CHUNK_MALLOC_MAX,\n    and a PNG_USER_LIMITS_SUPPORTED flag.\n  Eliminated use of png_ptr->irowbytes and reused the slot in png_ptr as\n    png_ptr->png_user_chunk_malloc_max.\n  Revised png_push_save_buffer() to do fewer but larger png_malloc() calls.\n\nVersion 1.4.1beta08 [February 6, 2010]\n  Minor cleanup and updating of dates and copyright year.\n\nVersion 1.5.0beta01 [February 7, 2010]\n  Moved declaration of png_struct into private pngstruct.h and png_info\n    into pnginfo.h\n\nVersion 1.4.1beta09 and 1.5.0beta02 [February 7, 2010]\n  Reverted to original png_push_save_buffer() code.\n\nVersion 1.4.1beta10 and 1.5.0beta03 [February 8, 2010]\n  Return allocated \"old_buffer\" in png_push_save_buffer() before\n    calling png_error(), to avoid a potential memory leak.\n  Updated configure script to use SO number 15.\n\nVersion 1.5.0beta04 [February 9, 2010]\n  Removed malformed \"incomplete struct declaration\" of png_info from png.h\n\nVersion 1.5.0beta05 [February 12, 2010]\n  Removed PNG_DEPSTRUCT markup in pngstruct.h and pnginfo.h, and undid the\n    linewrapping that it entailed.\n  Revised comments in pngstruct.h and pnginfo.h and added pointers to\n    the libpng license.\n  Changed PNG_INTERNAL to PNG_EXPOSE_INTERNAL_STRUCTURES\n  Removed the cbuilder5 project, which has not been updated to 1.4.0.\n\nVersion 1.4.1beta12 and 1.5.0beta06 [February 14, 2010]\n  Fixed type declaration of png_get_chunk_malloc_max() in pngget.c (Daisuke\n    Nishikawa)\n\nVersion 1.5.0beta07 [omitted]\n\nVersion 1.5.0beta08 [February 19, 2010]\n  Changed #ifdef PNG_NO_STDIO_SUPPORTED to #ifdef PNG_NO_CONSOLE_IO_SUPPORTED\n    wherever png_snprintf() is used to construct error and warning messages.\n  Noted in scripts/makefile.mingw that it expects to be run under MSYS.\n  Removed obsolete unused MMX-querying support from contrib/gregbook\n  Added exported png_longjmp() function.\n  Removed the AIX redefinition of jmpbuf in png.h\n  Added -D_ALLSOURCE in configure.ac, makefile.aix, and CMakeLists.txt\n    when building on AIX.\n\nVersion 1.5.0beta09 [February 19, 2010]\n  Removed -D_ALLSOURCE from configure.ac, makefile.aix, and CMakeLists.txt.\n  Changed the name of png_ptr->jmpbuf to png_ptr->png_jmpbuf in pngstruct.h\n\nVersion 1.5.0beta10 [February 25, 2010]\n  Removed unused gzio.c from contrib/pngminim gather and makefile scripts\n  Removed replacement error handlers from contrib/gregbook.  Because of\n    the new png_longjmp() function they are no longer needed.\n\nVersion 1.5.0beta11 [March 6, 2010]\n  Removed checking for already-included setjmp.h from pngconf.h\n  Fixed inconsistent indentations and made numerous cosmetic changes.\n  Revised the \"SEE ALSO\" style of libpng.3, libpngpf.3, and png.5\n\nVersion 1.5.0beta12 [March 9, 2010]\n  Moved \"#include png.h\" inside pngpriv.h and removed \"#include png.h\" from\n    the source files, along with \"#define PNG_EXPOSE_INTERNAL_STRUCTURES\"\n    and \"#define PNG_NO_PEDANTIC_WARNINGS\" (John Bowler).\n  Created new pngdebug.h and moved debug definitions there.\n\nVersion 1.5.0beta13 [March 10, 2010]\n  Protect pngstruct.h, pnginfo.h, and pngdebug.h from being included twice.\n  Revise the \"#ifdef\" blocks in png_inflate() so it will compile when neither\n    PNG_USER_CHUNK_MALLOC_MAX nor PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED\n    is defined.\n  Removed unused png_measure_compressed_chunk() from pngpriv.h and libpngpf.3\n  Moved the 'config.h' support from pngconf.h to pngpriv.h\n  Removed PNGAPI from the png_longjmp_ptr typedef.\n  Eliminated dependence of pngtest.c on the private pngdebug.h file.\n  Make all png_debug macros into *unterminated* statements or\n    expressions (i.e. a trailing ';' must always be added) and correct\n    the format statements in various png_debug messages.\n\nVersion 1.5.0beta14 [March 14, 2010]\n  Removed direct access to png_ptr->io_ptr from the Windows code in pngtest.c\n  Revised Makefile.am to account for recent additions and replacements.\n  Corrected CE and OS/2 DEF files (scripts/png*def) for symbols removed and\n    added ordinal numbers to the Windows DEF file and corrected the duplicated\n    ordinal numbers on CE symbols that are commented out.\n  Added back in export symbols that can be present in the Windows build but\n    are disabled by default.\n  PNG_EXPORT changed to include an 'ordinal' field for DEF file generation.\n    PNG_CALLBACK added to make callback definitions uniform.  PNGAPI split\n    into PNGCAPI (base C form), PNGAPI (exports) and PNGCBAPI (callbacks),\n    and appropriate changes made to all files.  Cygwin builds re-hinged to\n    allow procedure call standard changes and to remove the need for the DEF\n    file (fixes build on Cygwin).\n  Enabled 'attribute' warnings that are relevant to library APIs and callbacks.\n  Changed rules for generation of the various symbol files and added a new\n    rule for a DEF file (which is also added to the distribution).\n  Updated the symbol file generation to stop it adding spurious spaces\n    to EOL (coming from preprocessor macro expansion).  Added a facility\n    to join tokens in the output and rewrite *.dfn to use this.\n  Eliminated scripts/*.def in favor of libpng.def; updated projects/visualc71\n    and removed scripts/makefile.cygwin.\n  Made PNG_BUILD_DLL safe: it can be set whenever a DLL is being built.\n  Removed the include of sys/types.h - apparently unnecessary now on the\n    platforms on which it happened (all but Mac OS and RISC OS).\n  Moved the Mac OS test into pngpriv.h (the only place it is used.)\n\nVersion 1.5.0beta15 [March 17, 2010]\n  Added symbols.chk target to Makefile.am to validate the symbols in png.h\n    against the new DEF file scripts/symbols.def.\n  Changed the default DEF file back to pngwin.def.\n  Removed makefile.mingw.\n  Eliminated PNG_NO_EXTERN and PNG_ALL_EXTERN\n\nVersion 1.5.0beta16 [April 1, 2010]\n  Make png_text_struct independent of PNG_iTXt_SUPPORTED, so that\n    fields are initialized in all configurations.  The READ/WRITE\n    macros (PNG_(READ|WRITE)_iTXt_SUPPORTED) still function as\n    before to disable code to actually read or write iTXt chunks\n    and iTXt_SUPPORTED can be used to detect presence of either\n    read or write support (but it is probably better to check for\n    the one actually required - read or write.)\n  Combined multiple png_warning() calls for a single error.\n  Restored the macro definition of png_check_sig().\n\nVersion 1.5.0beta17 [April 17, 2010]\n  Added some \"(long)\" typecasts to printf calls in png_handle_cHRM().\n  Documented the fact that png_set_dither() was disabled since libpng-1.4.0.\n  Reenabled png_set_dither() but renamed it to png_set_quantize() to reflect\n    more accurately what it actually does.  At the same time, renamed\n    the PNG_DITHER_[RED,GREEN_BLUE]_BITS macros to\n    PNG_QUANTIZE_[RED,GREEN,BLUE]_BITS.\n  Added some \"(long)\" typecasts to printf calls in png_handle_cHRM().\n  Freeze build-time only configuration in the build.\n    In all prior versions of libpng most configuration options\n    controlled by compiler #defines had to be repeated by the\n    application code that used libpng.  This patch changes this\n    so that compilation options that can only be changed at build\n    time are frozen in the build.  Options that are compiler\n    dependent (and those that are system dependent) are evaluated\n    each time - pngconf.h holds these.  Options that can be changed\n    per-file in the application are in png.h.  Frozen options are\n    in the new installed header file pnglibconf.h (John Bowler)\n  Removed the xcode project because it has not been updated to work\n    with libpng-1.5.0.\n  Removed the ability to include optional pngusr.h\n\nVersion 1.5.0beta18 [April 17, 2010]\n  Restored the ability to include optional pngusr.h\n  Moved replacements for png_error() and png_warning() from the\n    contrib/pngminim project to pngerror.c, for use when warnings or\n    errors are disabled via PNG_NO_WARN or PNG_NO_ERROR_TEXT, to avoid\n    storing unneeded error/warning text.\n  Updated contrib/pngminim project to work with the new pnglibconf.h\n  Added some PNG_NO_* defines to contrib/pngminim/*/pngusr.h to save space.\n\nVersion 1.5.0beta19 [April 24, 2010]\n  Added PNG_{READ,WRITE}_INT_FUNCTIONS_SUPPORTED.  This allows the functions\n    to read and write ints to be disabled independently of PNG_USE_READ_MACROS,\n    which allows libpng to be built with the functions even though the default\n    is to use the macros - this allows applications to choose at app build\n    time whether or not to use macros (previously impossible because the\n    functions weren't in the default build.)\n  Changed Windows calling convention back to __cdecl for API functions.\n    For Windows/x86 platforms only:\n      __stdcall is no longer needed for Visual Basic, so libpng-1.5.0 uses\n      __cdecl throughout (both API functions and callbacks) on Windows/x86\n      platforms.\n  Replaced visualc6 and visualc71 projects with new vstudio project\n  Relaxed the overly-restrictive permissions of some files.\n\nVersion 1.5.0beta20 [April 24, 2010]\n  Relaxed more overly-restrictive permissions of some files.\n\nVersion 1.5.0beta21 [April 27, 2010]\n  Removed some unwanted binary bytes and changed CRLF to NEWLINE in the new\n    vstudio project files, and some trivial editing of some files in the\n    scripts directory.\n  Set PNG_NO_READ_BGR, PNG_NO_IO_STATE, and PNG_NO_TIME_RFC1123 in\n    contrib/pngminim/decoder/pngusr.h to make a smaller decoder application.\n\nVersion 1.5.0beta22 [April 28, 2010]\n  Fixed dependencies of GET_INT_32 - it does not require READ_INT_FUNCTIONS\n    because it has a macro equivalent.\n  Improved the options.awk script; added an \"everything off\" option.\n  Revised contrib/pngminim to use the \"everything off\" option in pngusr.dfa.\n\nVersion 1.5.0beta23 [April 29, 2010]\n  Corrected PNG_REMOVED macro to take five arguments.\n    The macro was documented with two arguments (name,ordinal), however\n    the symbol checking .dfn files assumed five arguments.  The five\n    argument form seems more useful so it is changed to that.\n  Corrected PNG_UNKNOWN_CHUNKS_SUPPORTED to PNG_HANDLE_AS_UNKNOWN_SUPPORTED\n    in gregbook/readpng2.c\n  Corrected protection of png_get_user_transform_ptr. The API declaration in\n    png.h is removed if both READ and WRITE USER_TRANSFORM are turned off\n    but was left defined in pngtrans.c\n  Added logunsupported=1 to cause pnglibconf.h to document disabled options.\n    This makes the installed pnglibconf.h more readable but causes no\n    other change.  The intention is that users of libpng will find it\n    easier to understand if an API they need is missing.\n  Include png_reset_zstream() in png.c only when PNG_READ_SUPPORTED is defined.\n  Removed dummy_inflate.c from contrib/pngminim/encoder\n  Removed contrib/pngminim/*/gather.sh; gathering is now done in the makefile.\n\nVersion 1.5.0beta24 [May 7, 2010]\n  Use bitwise \"&\" instead of arithmetic mod in pngrutil.c calculation of the\n    offset of the png_ptr->rowbuf pointer into png_ptr->big_row_buf.\n  Added more blank lines for readability.\n\nVersion 1.5.0beta25 [June 18, 2010]\n  In pngpread.c: png_push_have_row() add check for new_row > height\n  Removed the now-redundant check for out-of-bounds new_row from example.c\n\nVersion 1.5.0beta26 [June 18, 2010]\n  In pngpread.c: png_push_process_row() add check for too many rows.\n\nVersion 1.5.0beta27 [June 18, 2010]\n  Removed the check added in beta25 as it is now redundant.\n\nVersion 1.5.0beta28 [June 20, 2010]\n  Rewrote png_process_IDAT_data to consistently treat extra data as warnings\n    and handle end conditions more cleanly.\n  Removed the new (beta26) check in png_push_process_row().\n\nVersion 1.5.0beta29 [June 21, 2010]\n  Revised scripts/options.awk to work on Sunos (but still doesn't work)\n  Added comment to options.awk and contrib/pngminim/*/makefile to try nawk.\n\nVersion 1.5.0beta30 [June 22, 2010]\n  Stop memory leak when reading a malformed sCAL chunk.\n\nVersion 1.5.0beta31 [June 26, 2010]\n  Revised pngpread.c patch of beta28 to avoid an endless loop.\n  Removed some trailing blanks.\n\nVersion 1.5.0beta32 [June 26, 2010]\n  Removed leftover scripts/options.patch and scripts/options.rej\n\nVersion 1.5.0beta33 [July 6, 3010]\n  Made FIXED and FLOATING options consistent in the APIs they enable and\n    disable.  Corrected scripts/options.awk to handle both command line\n    options and options specified in the .dfa files.\n  Changed char *msg to PNG_CONST char *msg in pngrutil.c\n  Make png_set_sRGB_gAMA_and_cHRM set values using either the fixed or\n    floating point APIs, but not both.\n  Reversed patch to remove error handler when the jmp_buf is stored in the\n    main program structure, not the png_struct.\n    The error handler is needed because the default handler in libpng will\n    always use the jmp_buf in the library control structure; this is never\n    set.  The gregbook code is a useful example because, even though it\n    uses setjmp/longjmp, it shows how error handling can be implemented\n    using control mechanisms not directly supported by libpng.  The\n    technique will work correctly with mechanisms such as Microsoft\n    Structure Exceptions or C++ exceptions (compiler willing - note that gcc\n    does not by default support interworking of C and C++ error handling.)\n  Reverted changes to call png_longjmp in contrib/gregbook where it is not\n    appropriate.  If mainprog->jmpbuf is used by setjmp, then png_longjmp\n    cannot be used.\n  Changed \"extern PNG_EXPORT\" to \"PNG_EXPORT\" in png.h (Jan Nijtmans)\n  Changed \"extern\" to \"PNG_EXTERN\" in pngpriv.h (except for the 'extern \"C\" {')\n\nVersion 1.5.0beta34 [July 12, 2010]\n  Put #ifndef PNG_EXTERN, #endif around the define PNG_EXTERN in pngpriv.h\n\nVersion 1.5.0beta35 [July 24, 2010]\n  Removed some newly-added TAB characters.\n  Added -DNO_PNG_SNPRINTF to CFLAGS in scripts/makefile.dj2\n  Moved the definition of png_snprintf() outside of the enclosing\n    #ifdef blocks in pngconf.h\n\nVersion 1.5.0beta36 [July 29, 2010]\n  Patches by John Bowler:\n  Fixed point APIs are now supported throughout (no missing APIs).\n  Internal fixed point arithmetic support exists for all internal floating\n    point operations.\n  sCAL validates the floating point strings it is passed.\n  Safe, albeit rudimentary, Watcom support is provided by PNG_API_RULE==2\n  Two new APIs exist to get the number of passes without turning on the\n    PNG_INTERLACE transform and to get the number of rows in the current\n    pass.\n  A new test program, pngvalid.c, validates the gamma code.\n  Errors in the 16-bit gamma correction (overflows) have been corrected.\n  cHRM chunk testing is done consistently (previously the floating point\n    API bypassed it, because the test really didn't work on FP, now the test\n    is performed on the actual values to be stored in the PNG file so it\n    works in the FP case too.)\n  Most floating point APIs now simply call the fixed point APIs after\n    converting the values to the fixed point form used in the PNG file.\n  The standard headers no longer include zlib.h, which is currently only\n    required for pngstruct.h and can therefore be internal.\n  Revised png_get_int_32 to undo the PNG two's complement representation of\n    negative numbers.\n\nVersion 1.5.0beta37 [July 30, 2010]\n  Added a typecast in png_get_int_32() in png.h and pngrutil.h to avoid\n    a compiler warning.\n  Replaced oFFs 0,0 with oFFs -10,20 in pngtest.png\n\nVersion 1.5.0beta38 [July 31, 2010]\n  Implemented remaining \"_fixed\" functions.\n  Corrected a number of recently introduced warnings mostly resulting from\n    safe but uncast assignments to shorter integers.  Also added a zlib\n    VStudio release library project because the latest zlib Official Windows\n    build does not include such a thing.\n  Revised png_get_int_16() to be similar to png_get_int_32().\n  Restored projects/visualc71.\n\nVersion 1.5.0beta39 [August 2, 2010]\n  VisualC/GCC warning fixes, VisualC build fixes\n  The changes include support for function attributes in VC in addition to\n    those already present in GCC - necessary because without these some\n    warnings are unavoidable.  Fixes include signed/unsigned fixes in\n    pngvalid and checks with gcc -Wall -Wextra -Wunused.\n  VC requires function attributes on function definitions as well as\n    declarations, PNG_FUNCTION has been added to enable this and the\n    relevant function definitions changed.\n\nVersion 1.5.0beta40 [August 6, 2010]\n  Correct use of _WINDOWS_ in pngconf.h\n  Removed png_mem_ #defines; they are no longer used.\n  Added the sRGB chunk to pngtest.png\n\nVersion 1.5.0beta41 [August 11, 2010]\n  Added the cHRM chunk to pngtest.png\n  Don't try to use version-script with cygwin/mingw.\n  Revised contrib/gregbook to work under cygwin/mingw.\n\nVersion 1.5.0beta42 [August 18, 2010]\n  Add .dll.a to the list of extensions to be symlinked by Makefile.am (Yaakov)\n  Made all API functions that have const arguments and constant string\n    literal pointers declare them (John Bowler).\n\nVersion 1.5.0beta43 [August 20, 2010]\n  Removed spurious tabs, shorten long lines (no source change)\n    Also added scripts/chkfmt to validate the format of all the files that can\n    reasonably be validated (it is suggested to run \"make distclean\" before\n    checking, because some machine generated files have long lines.)\n  Reformatted the CHANGES file to be more consistent throughout.\n  Made changes to address various issues identified by GCC, mostly\n    signed/unsigned and shortening problems on assignment but also a few\n    difficult to optimize (for GCC) loops.\n  Fixed non-GCC fixed point builds.  In png.c a declaration was misplaced\n    in an earlier update.  Fixed to declare the auto variables at the head.\n  Use cexcept.h in pngvalid.c.\n\nVersion 1.5.0beta44 [August 24, 2010]\n  Updated CMakeLists.txt to use CMAKE_INSTALL_LIBDIR variable; useful for\n    installing libpng in /usr/lib64 (Funda Wang).\n  Revised CMakeLists.txt to put the man pages in share/man/man* not man/man*\n  Revised CMakeLists.txt to make symlinks instead of copies when installing.\n  Changed PNG_LIB_NAME from pngNN to libpngNN in CMakeLists.txt (Philip Lowman)\n  Implemented memory checks within pngvalid\n  Reformatted/rearranged pngvalid.c to assist use of progressive reader.\n  Check interlaced images in pngvalid\n  Clarified pngusr.h comments in pnglibconf.dfa\n  Simplified the pngvalid error-handling code now that cexcept.h is in place.\n  Implemented progressive reader in pngvalid.c for standard tests\n  Implemented progressive read in pngvalid.c gamma tests\n  Turn on progressive reader in pngvalid.c by default and tidy code.\n\nVersion 1.5.0beta45 [August 26, 2010]\n  Added an explicit make step to projects/vstudio for pnglibconf.h\n    Also corrected zlib.vcxproj into which Visual Studio had introduced\n    what it calls an \"authoring error\".  The change to make pnglibconf.h\n    simply copies the file; in the future it may actually generate the\n    file from scripts/pnglibconf.dfa as the other build systems do.\n  Changed pngvalid to work when floating point APIs are disabled\n  Renamed the prebuilt scripts/pnglibconf.h to scripts/pnglibconf.h.prebuilt\n  Supply default values for PNG_USER_PRIVATEBUILD and PNG_USER_DLLFNAME_POSTFIX\n    in pngpriv.h in case the user neglected to define them in their pngusr.h\n\nVersion 1.5.0beta46 [August 28, 2010]\n  Added new private header files to libpng_sources in CMakeLists.txt\n  Added PNG_READ_16BIT, PNG_WRITE_16BIT, and PNG_16BIT options.\n  Added reference to scripts/pnglibconf.h.prebuilt in the visualc71 project.\n\nVersion 1.5.0beta47 [September 11, 2010]\n  Fixed a number of problems with 64-bit compilation reported by Visual\n    Studio 2010 (John Bowler).\n\nVersion 1.5.0beta48 [October 4, 2010]\n  Updated CMakeLists.txt (Philip Lowman).\n  Revised autogen.sh to recognize and use $AUTOCONF, $AUTOMAKE, $AUTOHEADER,\n    $AUTOPOINT, $ACLOCAL and $LIBTOOLIZE\n  Fixed problem with symbols creation in Makefile.am which was assuming that\n    all versions of ccp write to standard output by default (Martin Banky). The\n    bug was introduced in libpng-1.2.9beta5.\n  Removed unused mkinstalldirs.\n\nVersion 1.5.0beta49 [October 8, 2010]\n  Undid Makefile.am revision of 1.5.0beta48.\n\nVersion 1.5.0beta50 [October 14, 2010]\n  Revised Makefile.in to account for mkinstalldirs being removed.\n  Added some \"(unsigned long)\" typecasts in printf statements in pngvalid.c.\n  Suppressed a compiler warning in png_handle_sPLT().\n  Check for out-of-range text compression mode in png_set_text().\n\nVersion 1.5.0beta51 [October 15, 2010]\n  Changed embedded dates to \"(PENDING RELEASE) in beta releases (and future\n    rc releases) to minimize the difference between releases.\n\nVersion 1.5.0beta52 [October 16, 2010]\n  Restored some of the embedded dates (in png.h, png.c, documentation, etc.)\n\nVersion 1.5.0beta53 [October 18, 2010]\n  Updated INSTALL to mention using \"make maintainer-clean\" and to remove\n    obsolete statement about a custom ltmain.sh\n  Disabled \"color-tests\" by default in Makefile.am so it will work with\n    automake versions earlier than 1.11.1\n  Use document name \"libpng-manual.txt\" instead of \"libpng-<version>.txt\"\n    to simplify version differences.\n  Removed obsolete remarks about setjmp handling from INSTALL.\n  Revised and renamed the typedef in png.h and png.c that was designed\n    to catch library and header mismatch.\n\nVersion 1.5.0beta54 [November 10, 2010]\n  Require 48 bytes, not 64 bytes, for big_row_buf in overflow checks.\n  Used a consistent structure for the pngget.c functions.\n\nVersion 1.5.0beta55 [November 21, 2010]\n  Revised png_get_uint_32, png_get_int_32, png_get_uint_16 (Cosmin)\n  Moved reading of file signature into png_read_sig (Cosmin)\n  Fixed atomicity of chunk header serialization (Cosmin)\n  Added test for io_state in pngtest.c (Cosmin)\n  Added \"#!/bin/sh\" at the top of contrib/pngminim/*/gather.sh scripts.\n  Changes to remove gcc warnings (John Bowler)\n    Certain optional gcc warning flags resulted in warnings in libpng code.\n    With these changes only -Wconversion and -Wcast-qual cannot be turned on.\n    Changes are trivial rearrangements of code.  -Wconversion is not possible\n    for pngrutil.c (because of the widespread use of += et al on variables\n    smaller than (int) or (unsigned int)) and -Wcast-qual is not possible\n    with pngwio.c and pngwutil.c because the 'write' callback and zlib\n    compression both fail to declare their input buffers with 'const'.\n\nVersion 1.5.0beta56 [December 7, 2010]\n  Added the private PNG_UNUSED() macro definition in pngpriv.h.\n  Added some commentary about PNG_EXPORT in png.h and pngconf.h\n  Revised PNG_EXPORT() macro and added PNG_EXPORTA() macro, with the\n    objective of simplifying and improving the cosmetic appearance of png.h.\n  Fixed some incorrect \"=\" macro names in pnglibconf.dfa\n  Included documentation of changes in 1.5.0 from 1.4.x in libpng-manual.txt\n\nVersion 1.5.0beta57 [December 9, 2010]\n  Documented the pngvalid gamma error summary with additional comments and\n    print statements.\n  Improved missing symbol handling in checksym.awk; symbols missing in both\n    the old and new files can now be optionally ignored, treated as errors\n    or warnings.\n  Removed references to pngvcrd.c and pnggccrd.c from the vstudio project.\n  Updated \"libpng14\" to \"libpng15\" in the visualc71 project.\n  Enabled the strip16 tests in pngvalid.`\n  Don't display test results (except PASS/FAIL) when running \"make test\".\n    Instead put them in pngtest-log.txt\n  Added \"--with-zprefix=<string>\" to configure.ac\n  Updated the prebuilt configuration files to autoconf version 2.68\n\nVersion 1.5.0beta58 [December 19, 2010]\n  Fixed interlace image handling and add test cases (John Bowler)\n  Fixed the clean rule in Makefile.am to remove pngtest-log.txt\n  Made minor changes to work around warnings in gcc 3.4\n\nVersion 1.5.0rc01 [December 27, 2010]\n  No changes.\n\nVersion 1.5.0rc02 [December 27, 2010]\n  Eliminated references to the scripts/*.def files in project/visualc71.\n\nVersion 1.5.0rc03 [December 28, 2010]\n  Eliminated scripts/*.def and revised Makefile.am accordingly\n\nVersion 1.5.0rc04 [December 29, 2010]\n  Fixed bug in background transformation handling in pngrtran.c (it was\n    looking for the flag in png_ptr->transformations instead of in\n    png_ptr->flags) (David Raymond).\n\nVersion 1.5.0rc05 [December 31, 2010]\n  Fixed typo in a comment in CMakeLists.txt (libpng14 => libpng15) (Cosmin)\n\nVersion 1.5.0rc06 [January 4, 2011]\n  Changed the new configure option \"zprefix=string\" to \"zlib-prefix=string\"\n\nVersion 1.5.0rc07 [January 4, 2011]\n  Updated copyright year.\n\nVersion 1.5.0 [January 6, 2011]\n  No changes.\n\nversion 1.5.1beta01 [January 8, 2011]\n  Added description of png_set_crc_action() to the manual.\n  Added a note in the manual that the type of the iCCP profile was changed\n    from png_charpp to png_bytepp in png_get_iCCP().  This change happened\n    in version 1.5.0beta36 but is not noted in the CHANGES.  Similarly,\n    it was changed from png_charpp to png_const_bytepp in png_set_iCCP().\n  Ensure that png_rgb_to_gray ignores palette mapped images, if libpng\n    internally happens to call it with one, and fixed a failure to handle\n    palette mapped images correctly.  This fixes CVE-2690.\n\nVersion 1.5.1beta02 [January 14, 2011]\n  Fixed a bug in handling of interlaced images (bero at arklinux.org).\n  Updated CMakeLists.txt (Clifford Yapp)\n\nVersion 1.5.1beta03 [January 14, 2011]\n  Fixed typecasting of some png_debug() statements (Cosmin)\n\nVersion 1.5.1beta04 [January 16, 2011]\n  Updated documentation of png_set|get_tRNS() (Thomas Klausner).\n  Mentioned in the documentation that applications must #include \"zlib.h\"\n    if they need access to anything in zlib.h, and that a number of\n    macros such as png_memset() are no longer accessible by applications.\n  Corrected pngvalid gamma test \"sample\" function to access all of the color\n    samples of each pixel, instead of sampling the red channel three times.\n  Prefixed variable names index, div, exp, gamma with \"png_\" to avoid \"shadow\"\n    warnings, and (mistakenly) changed png_exp() to exp().\n\nVersion 1.5.1beta05 [January 16, 2011]\n  Changed variable names png_index, png_div, png_exp, and png_gamma to\n    char_index, divisor, exp_b10, and gamma_val, respectively, and\n    changed exp() back to png_exp().\n\nVersion 1.5.1beta06 [January 20, 2011]\n  Prevent png_push_crc_skip() from hanging while reading an unknown chunk\n    or an over-large compressed zTXt chunk with the progressive reader.\n  Eliminated more GCC \"shadow\" warnings.\n  Revised png_fixed() in png.c to avoid compiler warning about reaching the\n    end without returning anything.\n\nVersion 1.5.1beta07 [January 22, 2011]\n  In the manual, describe the png_get_IHDR() arguments in the correct order.\n  Added const_png_structp and const_png_infop types, and used them in\n    prototypes for most png_get_*() functions.\n\nVersion 1.5.1beta08 [January 23, 2011]\n  Added png_get_io_chunk_type() and deprecated png_get_io_chunk_name()\n  Added synopses for the IO_STATE functions and other missing synopses\n    to the manual. Removed the synopses from libpngpf.3 because they\n    were out of date and no longer useful.  Better information can be\n    obtained by reading the prototypes and comments in pngpriv.h\n  Attempted to fix cpp on Solaris with S. Studio 12 cc, fix build\n    Added a make macro DFNCPP that is a CPP that will accept the tokens in\n    a .dfn file and adds configure stuff to test for such a CPP.  ./configure\n    should fail if one is not available.\n  Corrected const_png_ in png.h to png_const_ to avoid polluting the namespace.\n  Added png_get_current_row_number and png_get_current_pass_number for the\n    benefit of the user transform callback.\n  Added png_process_data_pause and png_process_data_skip for the benefit of\n    progressive readers that need to stop data processing or want to optimize\n    skipping of unread data (e.g., if the reader marks a chunk to be skipped.)\n\nVersion 1.5.1beta09 [January 24, 2011]\n  Enhanced pngvalid, corrected an error in gray_to_rgb, corrected doc error.\n    pngvalid contains tests of transforms, which tests are currently disabled\n    because they are incompletely tested.  gray_to_rgb was failing to expand\n    the bit depth for smaller bit depth images; this seems to be a long\n    standing error and resulted, apparently, in invalid output\n    (CVE-2011-0408, CERT VU#643140).  The documentation did not accurately\n    describe what libpng really does when converting RGB to gray.\n\nVersion 1.5.1beta10 [January 27, 2010]\n  Fixed incorrect examples of callback prototypes in the manual, that were\n    introduced in libpng-1.0.0.\n  In addition the order of the png_get_uint macros with respect to the\n    relevant function definitions has been reversed.  This helps the\n    preprocessing of the symbol files be more robust.  Furthermore, the\n    symbol file preprocessing now uses -DPNG_NO_USE_READ_MACROS even when\n    the library may actually be built with PNG_USE_READ_MACROS; this stops\n    the read macros interfering with the symbol file format.\n  Made the manual, synopses, and function prototypes use the function\n    argument names file_gamma, int_file_gamma, and srgb_intent consistently.\n\nVersion 1.5.1beta11 [January 28, 2011]\n  Changed PNG_UNUSED from \"param=param;\" to \"{if(param){}}\".\n  Corrected local variable type in new API png_process_data_skip()\n    The type was self-evidently incorrect but only causes problems on 64-bit\n    architectures.\n  Added transform tests to pngvalid and simplified the arguments.\n\nVersion 1.5.1rc01 [January 29, 2011]\n  No changes.\n\nVersion 1.5.1rc02 [January 31, 2011]\n  Added a request in the manual that applications do not use \"png_\" or\n    \"PNG_\" to begin any of their own symbols.\n  Changed PNG_UNUSED to \"(void)param;\" and updated the commentary in pngpriv.h\n\nVersion 1.5.1 [February 3, 2011]\n  No changes.\n\nVersion 1.5.2beta01 [February 13, 2011]\n  More -Wshadow fixes for older gcc compilers.  Older gcc versions apparently\n    check formal parameters names in function declarations (as well as\n    definitions) to see if they match a name in the global namespace.\n  Revised PNG_EXPORTA macro to not use an empty parameter, to accommodate the\n    old VisualC++ preprocessor.\n  Turned on interlace handling in png_read_png().\n  Fixed gcc pendantic warnings.\n  Handle longjmp in Cygwin.\n  Fixed png_get_current_row_number() in the interlaced case.\n  Cleaned up ALPHA flags and transformations.\n  Implemented expansion to 16 bits.\n\nVersion 1.5.2beta02 [February 19, 2011]\n  Fixed mistake in the descriptions of user read_transform and write_transform\n    function prototypes in the manual.  The row_info struct is png_row_infop.\n  Reverted png_get_current_row_number() to previous (1.5.2beta01) behavior.\n  Corrected png_get_current_row_number documentation\n  Fixed the read/write row callback documentation.\n    This documents the current behavior, where the callback is called after\n    every row with information pertaining to the next row.\n\nVersion 1.5.2beta03 [March 3, 2011]\n  Fixed scripts/makefile.vcwin32\n  Updated contrib/pngsuite/README to add the word \"modify\".\n  Define PNG_ALLOCATED to blank when _MSC_VER<1300.\n\nVersion 1.5.2rc01 [March 19, 2011]\n  Define remaining attributes to blank when MSC_VER<1300.\n  ifdef out mask arrays in pngread.c when interlacing is not supported.\n\nVersion 1.5.2rc02 [March 22, 2011]\n  Added a hint to try CPP=/bin/cpp if \"cpp -E\" fails in scripts/pnglibconf.mak\n    and in contrib/pngminim/*/makefile, eg., on SunOS 5.10, and removed \"strip\"\n    from the makefiles.\n  Fixed a bug (present since libpng-1.0.7) that makes png_handle_sPLT() fail\n    to compile when PNG_NO_POINTER_INDEXING is defined (Chubanov Kirill)\n\nVersion 1.5.2rc03 [March 24, 2011]\n  Don't include standard header files in png.h while building the symbol table,\n    to avoid cpp failure on SunOS (introduced PNG_BUILDING_SYMBOL_TABLE macro).\n\nVersion 1.5.2 [March 31, 2011]\n  No changes.\n\nVersion 1.5.3beta01 [April 1, 2011]\n  Re-initialize the zlib compressor before compressing non-IDAT chunks.\n  Added API functions (png_set_text_compression_level() and four others) to\n    set parameters for zlib compression of non-IDAT chunks.\n\nVersion 1.5.3beta02 [April 3, 2011]\n  Updated scripts/symbols.def with new API functions.\n  Only compile the new zlib re-initializing code when text or iCCP is\n    supported, using PNG_WRITE_COMPRESSED_TEXT_SUPPORTED macro.\n  Improved the optimization of the zlib CMF byte (see libpng-1.2.6beta03).\n  Optimize the zlib CMF byte in non-IDAT compressed chunks\n\nVersion 1.5.3beta03 [April 16, 2011]\n  Fixed gcc -ansi -pedantic compile. A strict ANSI system does not have\n    snprintf, and the \"__STRICT_ANSI__\" detects that condition more reliably\n    than __STDC__ (John Bowler).\n  Removed the PNG_PTR_NORETURN attribute because it too dangerous. It tells\n    the compiler that a user supplied callback (the error handler) does not\n    return, yet there is no guarantee in practice that the application code\n    will correctly implement the error handler because the compiler only\n    issues a warning if there is a mistake (John Bowler).\n  Removed the no-longer-used PNG_DEPSTRUCT macro.\n  Updated the zlib version to 1.2.5 in the VStudio project.\n  Fixed 64-bit builds where png_uint_32 is smaller than png_size_t in\n    pngwutil.c (John Bowler).\n  Fixed bug with stripping the filler or alpha channel when writing, that\n    was introduced in libpng-1.5.2beta01 (bug report by Andrew Church).\n\nVersion 1.5.3beta04 [April 27, 2011]\n  Updated pngtest.png with the new zlib CMF optimization.\n  Cleaned up conditional compilation code and of background/gamma handling\n    Internal changes only except a new option to avoid compiling the\n    png_build_grayscale_palette API (which is not used at all internally.)\n    The main change is to move the transform tests (READ_TRANSFORMS,\n    WRITE_TRANSFORMS) up one level to the caller of the APIs.  This avoids\n    calls to spurious functions if all transforms are disabled and slightly\n    simplifies those functions.  Pngvalid modified to handle this.\n    A minor change is to stop the strip_16 and expand_16 interfaces from\n    disabling each other; this allows the future alpha premultiplication\n    code to use 16-bit intermediate values while still producing 8-bit output.\n    png_do_background and png_do_gamma have been simplified to take a single\n    pointer to the png_struct rather than pointers to every item required\n    from the png_struct. This makes no practical difference to the internal\n    code.\n  A serious bug in the pngvalid internal routine 'standard_display_init' has\n    been fixed - this failed to initialize the red channel and accidentally\n    initialized the alpha channel twice.\n  Changed png_struct jmp_buf member name from png_jmpbuf to tmp_jmpbuf to\n    avoid a possible clash with the png_jmpbuf macro on some platforms.\n\nVersion 1.5.3beta05 [May 6, 2011]\n  Added the \"_POSIX_SOURCE\" feature test macro to ensure libpng sees the\n    correct API. _POSIX_SOURCE is defined in pngpriv.h, pngtest.c and\n    pngvalid.c to ensure that POSIX conformant systems disable non-POSIX APIs.\n  Removed png_snprintf and added formatted warning messages.  This change adds\n    internal APIs to allow png_warning messages to have parameters without\n    requiring the host OS to implement snprintf.  As a side effect the\n    dependency of the tIME-supporting RFC1132 code on stdio is removed and\n    PNG_NO_WARNINGS does actually work now.\n  Pass \"\" instead of '\\0' to png_default_error() in png_err().  This mistake\n    was introduced in libpng-1.2.20beta01.  This fixes CVE-2011-2691.\n  Added PNG_WRITE_OPTIMIZE_CMF_SUPPORTED macro to make the zlib \"CMF\" byte\n    optimization configureable.\n  IDAT compression failed if preceded by a compressed text chunk (bug\n    introduced in libpng-1.5.3beta01-02).  This was because the attempt to\n    reset the zlib stream in png_write_IDAT happened after the first IDAT\n    chunk had been deflated - much too late.  In this change internal\n    functions were added to claim/release the z_stream and, hopefully, make\n    the code more robust.  Also deflateEnd checking is added - previously\n    libpng would ignore an error at the end of the stream.\n\nVersion 1.5.3beta06 [May 8, 2011]\n  Removed the -D_ALL_SOURCE from definitions for AIX in CMakeLists.txt\n  Implemented premultiplied alpha support: png_set_alpha_mode API\n\nVersion 1.5.3beta07 [May 11, 2011]\n  Added expand_16 support to the high level interface.\n  Added named value and 'flag' gamma support to png_set_gamma.  Made a minor\n    change from the previous (unreleased) ABI/API to hide the exact value used\n    for Macs - it's not a good idea to embed this in the ABI!\n  Moved macro definitions for PNG_HAVE_IHDR, PNG_HAVE_PLTE, and PNG_AFTER_IDAT\n    from pngpriv.h to png.h because they must be visible to applications\n    that call png_set_unknown_chunks().\n  Check for up->location !PNG_AFTER_IDAT when writing unknown chunks\n    before IDAT.\n\nVersion 1.5.3beta08 [May 16, 2011]\n  Improved \"pngvalid --speed\" to exclude more of pngvalid from the time.\n  Documented png_set_alpha_mode(), other changes in libpng.3/libpng-manual.txt\n  The cHRM chunk now sets the defaults for png_set_rgb_to_gray() (when negative\n    parameters are supplied by the caller), while in the absence of cHRM\n    sRGB/Rec 709 values are still used.  This introduced a divide-by-zero\n    bug in png_handle_cHRM().\n  The bKGD chunk no longer overwrites the background value set by\n    png_set_background(), allowing the latter to be used before the file\n    header is read. It never performed any useful function to override\n    the default anyway.\n  Added memory overwrite and palette image checks to pngvalid.c\n    Previously palette image code was poorly checked. Since the transformation\n    code has a special palette path in most cases this was a severe weakness.\n  Minor cleanup and some extra checking in pngrutil.c and pngrtran.c. When\n    expanding an indexed image, always expand to RGBA if transparency is\n    present.\n\nVersion 1.5.3beta09 [May 17, 2011]\n  Reversed earlier 1.5.3 change of transformation order; move png_expand_16\n    back where it was.  The change doesn't work because it requires 16-bit\n    gamma tables when the code only generates 8-bit ones.  This fails\n    silently; the libpng code just doesn't do any gamma correction.  Moving\n    the tests back leaves the old, inaccurate, 8-bit gamma calculations, but\n    these are clearly better than none!\n\nVersion 1.5.3beta10 [May 20, 2011]\n\n  png_set_background() and png_expand_16() did not work together correctly.\n    This problem is present in 1.5.2; if png_set_background is called with\n    need_expand false and the matching 16 bit color libpng erroneously just\n    treats it as an 8-bit color because of where png_do_expand_16 is in the\n    transform list.  This simple fix reduces the supplied colour to 8-bits,\n    so it gets smashed, but this is better than the current behavior.\n  Added tests for expand16, more fixes for palette image tests to pngvalid.\n    Corrects the code for palette image tests and disables attempts to\n    validate palette colors.\n\nVersion 1.5.3rc01 [June 3, 2011]\n  No changes.\n\nVersion 1.5.3rc02 [June 8, 2011]\n  Fixed uninitialized memory read in png_format_buffer() (Bug report by\n    Frank Busse, CVE-2011-2501, related to CVE-2004-0421).\n\nVersion 1.5.3beta11 [June 11, 2011]\n  Fixed png_handle_sCAL which is broken in 1.5. This fixes CVE 2011-2692.\n  Added sCAL to pngtest.png\n  Revised documentation about png_set_user_limits() to say that it also affects\n    png writing.\n  Revised handling of png_set_user_limits() so that it can increase the\n    limit beyond the PNG_USER_WIDTH|HEIGHT_MAX; previously it could only\n    reduce it.\n  Make the 16-to-8 scaling accurate. Dividing by 256 with no rounding is\n    wrong (high by one) 25% of the time. Dividing by 257 with rounding is\n    wrong in 128 out of 65536 cases. Getting the right answer all the time\n    without division is easy.\n  Added \"_SUPPORTED\" to the PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION macro.\n  Added projects/owatcom, an IDE project for OpenWatcom to replace\n    scripts/makefile.watcom.  This project works with OpenWatcom 1.9. The\n    IDE autogenerates appropriate makefiles (libpng.mk) for batch processing.\n    The project is configurable, unlike the Visual Studio project, so long\n    as the developer has an awk.\n  Changed png_set_gAMA to limit the gamma value range so that the inverse\n    of the stored value cannot overflow the fixed point representation,\n    and changed other things OpenWatcom warns about.\n  Revised pngvalid.c to test PNG_ALPHA_MODE_SUPPORTED correctly. This allows\n    pngvalid to build when ALPHA_MODE is not supported, which is required if\n    it is to build on libpng 1.4.\n  Removed string/memory macros that are no longer used and are not\n    necessarily fully supportable, particularly png_strncpy and png_snprintf.\n  Added log option to pngvalid.c and attempted to improve gamma messages.\n\nVersion 1.5.3 [omitted]\n  People found the presence of a beta release following an rc release\n    to be confusing; therefore we bump the version to libpng-1.5.4beta01\n    and there will be no libpng-1.5.3 release.\n\nVersion 1.5.4beta01 [June 14, 2011]\n  Made it possible to undefine PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED\n    to get the same (inaccurate) output as libpng-1.5.2 and earlier.\n  Moved definitions of PNG_HAVE_IHDR, PNG_AFTER_IDAT, and PNG_HAVE_PLTE\n    outside of an unknown-chunk block in png.h because they are also\n    needed for other uses.\n\nVersion 1.5.4beta02 [June 14, 2011]\n  Fixed and clarified LEGACY 16-to-8 scaling code.\n  Added png_set_chop_16() API, to match inaccurate results from previous\n    libpng versions.\n  Removed the ACCURATE and LEGACY options (they are no longer useable)\n  Use the old scaling method for background if png_set_chop_16() was\n    called.\n  Made png_set_chop_16() API removeable by disabling PNG_CHOP_16_TO_8_SUPPORTED\n\nVersion 1.5.4beta03 [June 15, 2011]\n  Fixed a problem in png_do_expand_palette() exposed by optimization in\n    1.5.3beta06\n  Also removed a spurious and confusing \"trans\" member (\"trans\") from png_info.\n  The palette expand optimization prevented expansion to an intermediate RGBA\n    form if tRNS was present but alpha was marked to be stripped; this exposed\n    a check for tRNS in png_do_expand_palette() which is inconsistent with the\n    code elsewhere in libpng.\n  Correction to the expand_16 code; removed extra instance of\n    png_set_scale_16_to_8 from pngpriv.h\n\nVersion 1.5.4beta04 [June 16, 2011]\n  Added a missing \"#ifdef PNG_READ_BACKGROUND_SUPPORTED/#endif\" in pngrtran.c\n  Added PNG_TRANSFORM_CHOP_16 to the high-level read transforms.\n  Made PNG_READ_16_TO_8_ACCURATE_SCALE configurable again.  If this is\n    not enabled, png_set_strip_16() and png_do_scale_16_to_8() aren't built.\n  Revised contrib/visupng, gregbook, and pngminim to demonstrate chop_16_to_8\n\nVersion 1.5.4beta05 [June 16, 2011]\n  Renamed png_set_strip_16() to png_set_scale_16() and renamed\n    png_set_chop_16() to png_set_strip(16) in an attempt to minimize the\n    behavior changes between libpng14 and libpng15.\n\nVersion 1.5.4beta06 [June 18, 2011]\n  Fixed new bug that was causing both strip_16 and scale_16 to be applied.\n\nVersion 1.5.4beta07 [June 19, 2011]\n  Fixed pngvalid, simplified macros, added checking for 0 in sCAL.\n    The ACCURATE scale macro is no longer defined in 1.5 - call the\n    png_scale_16_to_8 API.  Made sure that PNG_READ_16_TO_8 is still defined\n    if the png_strip_16_to_8 API is present.  png_check_fp_number now\n    maintains some state so that positive, negative and zero values are\n    identified.  sCAL uses these to be strictly spec conformant.\n\nVersion 1.5.4beta08 [June 23, 2011]\n  Fixed pngvalid if ACCURATE_SCALE is defined.\n  Updated scripts/pnglibconf.h.prebuilt.\n\nVersion 1.5.4rc01 [June 30, 2011]\n  Define PNG_ALLOCATED to \"restrict\" only if MSC_VER >= 1400.\n\nVersion 1.5.4 [July 7, 2011]\n  No changes.\n\nVersion 1.5.5beta01 [July 13, 2011]\n  Fixed some typos and made other minor changes in the manual.\n  Updated contrib/pngminus/makefile.std (Samuli Souminen)\n\nVersion 1.5.5beta02 [July 14, 2011]\n  Revised Makefile.am and Makefile.in to look in the right directory for\n    pnglibconf.h.prebuilt\n\nVersion 1.5.5beta03 [July 27, 2011]\n  Enabled compilation with g++ compiler.  This compiler does not recognize\n    the file extension, so it always compiles with C++ rules.  Made minor\n    changes to pngrutil.c to cast results where C++ expects it but C does not.\n  Minor editing of libpng.3 and libpng-manual.txt.\n\nVersion 1.5.5beta04 [July 29, 2011]\n  Revised CMakeLists.txt (Clifford Yapp)\n  Updated commentary about the png_rgb_to_gray() default coefficients\n    in the manual and in pngrtran.c\n\nVersion 1.5.5beta05 [August 17, 2011]\n  Prevent unexpected API exports from non-libpng DLLs on Windows.  The \"_DLL\"\n    is removed from the test of whether a DLL is being built (this erroneously\n    caused the libpng APIs to be marked as DLL exports in static builds under\n    Microsoft Visual Studio).  Almost all of the libpng building configuration\n    is moved from pngconf.h to pngpriv.h, but PNG_DLL_EXPORT remains in\n    pngconf.h, though, so that it is colocated with the import definition (it\n    is no longer used anywhere in the installed headers).  The VStudio project\n    definitions have been cleaned up: \"_USRDLL\" has been removed from the\n    static library builds (this was incorrect), and PNG_USE_DLL has been added\n    to pngvalid to test the functionality (pngtest does not supply it,\n    deliberately).  The spurious \"_EXPORTS\" has been removed from the\n    libpng build (all these errors were a result of copy/paste between project\n    configurations.)\n  Added new types and internal functions for CIE RGB end point handling to\n    pngpriv.h (functions yet to be implemented).\n\nVersion 1.5.5beta06 [August 26, 2011]\n  Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set in CMakeLists.txt\n    (Clifford Yap)\n  Fixes to rgb_to_gray and cHRM XYZ APIs (John Bowler):\n    The rgb_to_gray code had errors when combined with gamma correction.\n    Some pixels were treated as true grey when they weren't and such pixels\n    and true grey ones were not gamma corrected (the original value of the\n    red component was used instead).  APIs to get and set cHRM using color\n    space end points have been added and the rgb_to_gray code that defaults\n    based on cHRM, and the divide-by-zero bug in png_handle_cHRM (CERT\n    VU#477046, CVE-2011-3328, introduced in 1.5.4) have been corrected.\n  A considerable number of tests has been added to pngvalid for the\n    rgb_to_gray transform.\n  Arithmetic errors in rgb_to_gray whereby the calculated gray value was\n    truncated to the bit depth rather than rounded have been fixed except in\n    the 8-bit non-gamma-corrected case (where consistency seems more important\n    than correctness.)  The code still has considerable inaccuracies in the\n    8-bit case because 8-bit linear arithmetic is used.\n\nVersion 1.5.5beta07 [September 7, 2011]\n  Added \"$(ARCH)\" option to makefile.darwin\n  Added SunOS support to configure.ac and Makefile.am\n  Changed png_chunk_benign_error() to png_warning() in png.c, in\n    png_XYZ_from_xy_checked().\n\nVersion 1.5.5beta08 [September 10, 2011]\n  Fixed 64-bit compilation errors (gcc). The errors fixed relate\n    to conditions where types that are 32 bits in the GCC 32-bit\n    world (uLong and png_size_t) become 64 bits in the 64-bit\n    world.  This produces potential truncation errors which the\n    compiler correctly flags.\n  Relocated new HAVE_SOLARIS_LD definition in configure.ac\n  Constant changes for 64-bit compatibility (removal of L suffixes). The\n    16-bit cases still use \"L\" as we don't have a 16-bit test system.\n\nVersion 1.5.5rc01 [September 15, 2011]\n  Removed \"L\" suffixes in pngpriv.h\n\nVersion 1.5.5 [September 22, 2011]\n  No changes.\n\nVersion 1.5.6beta01 [September 22, 2011]\n  Fixed some 64-bit type conversion warnings in pngrtran.c\n  Moved row_info from png_struct to a local variable.\n  The various interlace mask arrays have been made into arrays of\n    bytes and made PNG_CONST and static (previously some arrays were\n    marked PNG_CONST and some weren't).\n  Additional checks have been added to the transform code to validate the\n    pixel depths after the transforms on both read and write.\n  Removed some redundant code from pngwrite.c, in png_destroy_write_struct().\n  Changed chunk reading/writing code to use png_uint_32 instead of png_byte[4].\n    This removes the need to allocate temporary strings for chunk names on\n    the stack in the read/write code.  Unknown chunk handling still uses the\n    string form because this is exposed in the API.\n\nVersion 1.5.6beta02 [September 26, 2011]\n  Added a note in the manual the png_read_update_info() must be called only\n    once with a particular info_ptr.\n  Fixed a typo in the definition of the new PNG_STRING_FROM_CHUNK(s,c) macro.\n\nVersion 1.5.6beta03 [September 28, 2011]\n  Revised test-pngtest.sh to report FAIL when pngtest fails.\n  Added \"--strict\" option to pngtest, to report FAIL when the failure is\n    only because the resulting valid files are different.\n  Revised CMakeLists.txt to work with mingw and removed some material from\n    CMakeLists.txt that is no longer useful in libpng-1.5.\n\nVersion 1.5.6beta04 [October 5, 2011]\n  Fixed typo in Makefile.in and Makefile.am (\"-M Wl\" should be \"-M -Wl\").\"\n\nVersion 1.5.6beta05 [October 12, 2011]\n  Speed up png_combine_row() for interlaced images. This reduces the generality\n    of the code, allowing it to be optimized for Adam7 interlace.  The masks\n    passed to png_combine_row() are now generated internally, avoiding\n    some code duplication and localizing the interlace handling somewhat.\n  Align png_struct::row_buf - previously it was always unaligned, caused by\n    a bug in the code that attempted to align it; the code needs to subtract\n    one from the pointer to take account of the filter byte prepended to\n    each row.\n  Optimized png_combine_row() when rows are aligned. This gains a small\n    percentage for 16-bit and 32-bit pixels in the typical case where the\n    output row buffers are appropriately aligned. The optimization was not\n    previously possible because the png_struct buffer was always misaligned.\n  Fixed bug in png_write_chunk_header() debug print, introduced in 1.5.6beta01.\n\nVersion 1.5.6beta06 [October 17, 2011]\n  Removed two redundant tests for unitialized row.\n  Fixed a relatively harmless memory overwrite in compressed text writing\n    with a 1 byte zlib buffer.\n  Add ability to call png_read_update_info multiple times to pngvalid.c.\n  Fixes for multiple calls to png_read_update_info. These fixes attend to\n    most of the errors revealed in pngvalid, however doing the gamma work\n    twice results in inaccuracies that can't be easily fixed.  There is now\n    a warning in the code if this is going to happen.\n  Turned on multiple png_read_update_info in pngvalid transform tests.\n  Prevent libpng from overwriting unused bits at the end of the image when\n    it is not byte aligned, while reading. Prior to libpng-1.5.6 libpng would\n    overwrite the partial byte at the end of each row if the row width was not\n    an exact multiple of 8 bits and the image is not interlaced.\n\nVersion 1.5.6beta07 [October 21, 2011]\n  Made png_ptr->prev_row an aligned pointer into png_ptr->big_prev_row\n    (Mans Rullgard).\n\nVersion 1.5.6rc01 [October 26, 2011]\n  Changed misleading \"Missing PLTE before cHRM\" warning to \"Out of place cHRM\"\n\nVersion 1.5.6rc02 [October 27, 2011]\n  Added LSR() macro to defend against buggy compilers that evaluate non-taken\n    code branches and complain about out-of-range shifts.\n\nVersion 1.5.6rc03 [October 28, 2011]\n  Renamed the LSR() macro to PNG_LSR() and added PNG_LSL() macro.\n  Fixed compiler warnings with Intel and MSYS compilers. The logical shift\n    fix for Microsoft Visual C is required by other compilers, so this\n    enables that fix for all compilers when using compile-time constants.\n    Under MSYS 'byte' is a name declared in a system header file, so we\n    changed the name of a local variable to avoid the warnings that result.\n  Added #define PNG_ALIGN_TYPE PNG_ALIGN_NONE to contrib/pngminim/*/pngusr.h\n\nVersion 1.5.6 [November 3, 2011]\n  No changes.\n\nVersion 1.5.7beta01 [November 4, 2011]\n  Added support for ARM processor, when decoding all PNG up-filtered rows\n    and any other-filtered rows with 3 or 4 bytes per pixel (Mans Rullgard).\n  Fixed bug in pngvalid on early allocation failure; fixed type cast in\n    pngmem.c; pngvalid would attempt to call png_error() if the allocation\n    of a png_struct or png_info failed. This would probably have led to a\n    crash.  The pngmem.c implementation of png_malloc() included a cast\n    to png_size_t which would fail on large allocations on 16-bit systems.\n  Fix for the preprocessor of the Intel C compiler. The preprocessor\n    splits adjacent @ signs with a space; this changes the concatentation\n    token from @-@-@ to PNG_JOIN; that should work with all compiler\n    preprocessors.\n  Paeth filter speed improvements from work by Siarhei Siamashka. This\n    changes the 'Paeth' reconstruction function to improve the GCC code\n    generation on x86. The changes are only part of the suggested ones;\n    just the changes that definitely improve speed and remain simple.\n    The changes also slightly increase the clarity of the code.\n\nVersion 1.5.7beta02 [November 11, 2011]\n  Check compression_type parameter in png_get_iCCP and remove spurious\n    casts. The compression_type parameter is always assigned to, so must\n    be non-NULL. The cast of the profile length potentially truncated the\n    value unnecessarily on a 16-bit int system, so the cast of the (byte)\n    compression type to (int) is specified by ANSI-C anyway.\n  Fixed FP division by zero in pngvalid.c; the 'test_pixel' code left\n    the sBIT fields in the test pixel as 0, which resulted in a floating\n    point division by zero which was irrelevant but causes systems where\n    FP exceptions cause a crash. Added code to pngvalid to turn on FP\n    exceptions if the appropriate glibc support is there to ensure this is\n    tested in the future.\n  Updated scripts/pnglibconf.mak and scripts/makefile.std to handle the\n    new PNG_JOIN macro.\n  Added versioning to pnglibconf.h comments.\n  Simplified read/write API initial version; basic read/write tested on\n    a variety of images, limited documentation (in the header file.)\n  Installed more accurate linear to sRGB conversion tables. The slightly\n    modified tables reduce the number of 16-bit values that\n    convert to an off-by-one 8-bit value.  The \"makesRGB.c\" code that was used\n    to generate the tables is now in a contrib/sRGBtables sub-directory.\n\nVersion 1.5.7beta03 [November 17, 2011]\n  Removed PNG_CONST from the sRGB table declarations in pngpriv.h and png.c\n  Added run-time detection of NEON support.\n  Added contrib/libtests; includes simplified API test and timing test and\n    a color conversion utility for rapid checking of failed 'pngstest' results.\n  Multiple transform bug fixes plus a work-round for double gamma correction.\n    libpng does not support more than one transform that requires linear data\n    at once - if this is tried typically the results is double gamma\n    correction. Since the simplified APIs can need rgb to gray combined with\n    a compose operation it is necessary to do one of these outside the main\n    libpng transform code. This check-in also contains fixes to various bugs\n    in the simplified APIs themselves and to some bugs in compose and rgb to\n    gray (on palette) itself.\n  Fixes for C++ compilation using g++ When libpng source is compiled\n    using g++. The compiler imposes C++ rules on the C source; thus it\n    is desireable to make the source work with either C or C++ rules\n    without throwing away useful error information.  This change adds\n    png_voidcast to allow C semantic (void*) cases or the corresponding\n    C++ static_cast operation, as appropriate.\n  Added --noexecstack to assembler file compilation. GCC does not set\n    this on assembler compilation, even though it does on C compilation.\n    This creates security issues if assembler code is enabled; the\n    work-around is to set it by default in the flags for $(CCAS)\n  Work around compilers that don't support declaration of const data. Some\n    compilers fault 'extern const' data declarations (because the data is\n    not initialized); this turns on const-ness only for compilers where\n    this is known to work.\n\nVersion 1.5.7beta04 [November 17, 2011]\n  Since the gcc driver does not recognize the --noexecstack flag, we must\n    use the -Wa prefix to have it passed through to the assembler.\n    Also removed a duplicate setting of this flag.\n  Added files that were omitted from the libpng-1.5.7beta03 zip distribution.\n\nVersion 1.5.7beta05 [November 25, 2011]\n  Removed \"zTXt\" from warning in generic chunk decompression function.\n  Validate time settings passed to png_set_tIME() and png_convert_to_rfc1123()\n    (Frank Busse). Note: This prevented CVE-2015-7981 from affecting\n    libpng-1.5.7 and later.\n  Added MINGW support to CMakeLists.txt\n  Reject invalid compression flag or method when reading the iTXt chunk.\n  Backed out 'simplified' API changes. The API seems too complex and there\n    is a lack of consensus or enthusiasm for the proposals.  The API also\n    reveals significant bugs inside libpng (double gamma correction and the\n    known bug of being unable to retrieve a corrected palette). It seems\n    better to wait until the bugs, at least, are corrected.\n  Moved pngvalid.c into contrib/libtests\n  Rebuilt Makefile.in, configure, etc., with autoconf-2.68\n\nVersion 1.5.7rc01 [December 1, 2011]\n  Replaced an \"#if\" with \"#ifdef\" in pngrtran.c\n  Revised #if PNG_DO_BC block in png.c (use #ifdef and add #else)\n\nVersion 1.5.7rc02 [December 5, 2011]\n  Revised project files and contrib/pngvalid/pngvalid.c to account for\n    the relocation of pngvalid into contrib/libtests.\n  Revised pngconf.h to use \" __declspec(restrict)\" only when MSC_VER >= 1400,\n    as in libpng-1.5.4.\n  Put CRLF line endings in the owatcom project files.\n\nVersion 1.5.7rc03 [December 7, 2011]\n  Updated CMakeLists.txt to account for the relocation of pngvalid.c\n\nVersion 1.5.7 [December 15, 2011]\n  Minor fixes to pngvalid.c for gcc 4.6.2 compatibility to remove warnings\n    reported by earlier versions.\n  Fixed minor memset/sizeof errors in pngvalid.c.\n\nVersion 1.6.0beta01 [December 15, 2011]\n  Removed machine-generated configure files from the GIT repository (they will\n    continue to appear in the tarball distributions and in the libpng15 and\n    earlier GIT branches).\n  Restored the new 'simplified' API, which was started in libpng-1.5.7beta02\n    but later deleted from libpng-1.5.7beta05.\n  Added example programs for the new 'simplified' API.\n  Added ANSI-C (C90) headers and require them, and take advantage of the\n    change. Also fixed some of the projects/* and contrib/* files that needed\n    updates for libpng16 and the move of pngvalid.c.\n    With this change the required ANSI-C header files are assumed to exist: the\n    implementation must provide float.h, limits.h, stdarg.h and stddef.h and\n    libpng relies on limits.h and stddef.h existing and behaving as defined\n    (the other two required headers aren't used).  Non-ANSI systems that don't\n    have stddef.h or limits.h will have to provide an appropriate fake\n    containing the relevant types and #defines.\n  Dropped support for 16-bit platforms. The use of FAR/far has been eliminated\n    and the definition of png_alloc_size_t is now controlled by a flag so\n    that 'small size_t' systems can select it if necessary.  Libpng 1.6 may\n    not currently work on such systems -- it seems likely that it will\n    ask 'malloc' for more than 65535 bytes with any image that has a\n    sufficiently large row size (rather than simply failing to read such\n    images).\n  New tools directory containing tools used to generate libpng code.\n  Fixed race conditions in parallel make builds. With higher degrees of\n    parallelism during 'make' the use of the same temporary file names such\n    as 'dfn*' can result in a race where a temporary file from one arm of the\n    build is deleted or overwritten in another arm.  This changes the\n    temporary files for suffix rules to always use $* and ensures that the\n    non-suffix rules use unique file names.\n\nVersion 1.6.0beta02 [December 21, 2011]\n  Correct configure builds where build and source directories are separate.\n    The include path of 'config.h' was erroneously made relative in pngvalid.c\n    in libpng 1.5.7.\n\nVersion 1.6.0beta03 [December 22, 2011]\n  Start-up code size improvements, error handler flexibility. These changes\n    alter how the tricky allocation of the initial png_struct and png_info\n    structures are handled. png_info is now handled in pretty much the same\n    way as everything else, except that the allocations handle NULL return\n    silently.  png_struct is changed in a similar way on allocation and on\n    deallocation a 'safety' error handler is put in place (which should never\n    be required).  The error handler itself is changed to permit mismatches\n    in the application and libpng error buffer size; however, this means a\n    silent change to the API to return the jmp_buf if the size doesn't match\n    the size from the libpng compilation; libpng now allocates the memory and\n    this may fail.  Overall these changes result in slight code size\n    reductions; however, this is a reduction in code that is always executed\n    so is particularly valuable.  Overall on a 64-bit system the libpng DLL\n    decreases in code size by 1733 bytes.  pngerror.o increases in size by\n    about 465 bytes because of the new functionality.\n  Added png_convert_to_rfc1123_buffer() and deprecated png_convert_to_rfc1123()\n    to avoid including a spurious buffer in the png_struct.\n\nVersion 1.6.0beta04 [December 30, 2011]\n  Regenerated configure scripts with automake-1.11.2\n  Eliminated png_info_destroy(). It is now used only in png.c and only calls\n    one other internal function and memset().\n  Enabled png_get_sCAL_fixed() if floating point APIs are enabled. Previously\n    it was disabled whenever internal fixed point arithmetic was selected,\n    which meant it didn't exist even on systems where FP was available but not\n    preferred.\n  Added pngvalid.c compile time checks for const APIs.\n  Implemented 'restrict' for png_info and png_struct. Because of the way\n    libpng works both png_info and png_struct are always accessed via a\n    single pointer.  This means adding C99 'restrict' to the pointer gives\n    the compiler some opportunity to optimize the code.  This change allows\n    that.\n  Moved AC_MSG_CHECKING([if libraries can be versioned]) later to the proper\n    location in configure.ac (Gilles Espinasse).\n  Changed png_memcpy to C assignment where appropriate. Changed all those\n    uses of png_memcpy that were doing a simple assignment to assignments\n    (all those cases where the thing being copied is a non-array C L-value).\n  Added some error checking to png_set_*() routines.\n  Removed the reference to the non-exported function png_memcpy() from\n    example.c.\n  Fixed the Visual C 64-bit build - it requires jmp_buf to be aligned, but\n    it had become misaligned.\n  Revised contrib/pngminus/pnm2png.c to avoid warnings when png_uint_32\n    and unsigned long are of different sizes.\n\nVersion 1.6.0beta05 [January 15, 2012]\n  Updated manual with description of the simplified API (copied from png.h)\n  Fix bug in pngerror.c: some long warnings were being improperly truncated\n    (CVE-2011-3464, bug introduced in libpng-1.5.3beta05).\n\nVersion 1.6.0beta06 [January 24, 2012]\n  Added palette support to the simplified APIs. This commit\n    changes some of the macro definitions in png.h, app code\n    may need corresponding changes.\n  Increased the formatted warning buffer to 192 bytes.\n  Added color-map support to simplified API. This is an initial version for\n    review; the documentation has not yet been updated.\n  Fixed Min/GW uninstall to remove libpng.dll.a\n\nVersion 1.6.0beta07 [January 28, 2012]\n  Eliminated Intel icc/icl compiler warnings. The Intel (GCC derived)\n    compiler issues slightly different warnings from those issued by the\n    current vesions of GCC. This eliminates those warnings by\n    adding/removing casts and small code rewrites.\n  Updated configure.ac from autoupdate: added --enable-werror option.\n    Also some layout regularization and removal of introduced tab characters\n    (replaced with 3-character indentation).  Obsolete macros identified by\n    autoupdate have been removed; the replacements are all in 2.59 so\n    the pre-req hasn't been changed.  --enable-werror checks for support\n    for -Werror (or the given argument) in the compiler.  This mimics the\n    gcc configure option by allowing -Werror to be turned on safely; without\n    the option the tests written in configure itself fail compilation because\n    they cause compiler warnings.\n  Rewrote autogen.sh to run autoreconf instead of running tools one-by-one.\n  Conditionalize the install rules for MINGW and CYGWIN in CMakeLists.txt and\n    set CMAKE_LIBRARY_OUTPUT_DIRECTORY to \"lib\" on all platforms (C. Yapp).\n  Freeze libtool files in the 'scripts' directory. This version of autogen.sh\n    attempts to dissuade people from running it when it is not, or should not,\n    be necessary.  In fact, autogen.sh does not work when run in a libpng\n    directory extracted from a tar distribution anymore. You must run it in\n    a GIT clone instead.\n  Added two images to contrib/pngsuite (1-bit and 2-bit transparent grayscale),\n    and renamed three whose names were inconsistent with those in\n    pngsuite/README.txt.\n\nVersion 1.6.0beta08 [February 1, 2012]\n  Fixed Image::colormap misalignment in pngstest.c\n  Check libtool/libtoolize version number (2.4.2) in configure.ac\n  Divide test-pngstest.sh into separate pngstest runs for basic and\n    transparent images.\n  Moved automake options to AM_INIT_AUTOMAKE in configure.ac\n  Added color-tests, silent-rules (Not yet implemented in Makefile.am) and\n    version checking to configure.ac\n  Improved pngstest speed by not doing redundant tests and add const to\n    the background parameter of png_image_finish_read. The --background\n    option is now done automagically only when required, so that commandline\n    option no longer exists.\n  Cleaned up pngpriv.h to consistently declare all functions and data.\n    Also eliminated PNG_CONST_DATA, which is apparently not needed but we\n    can't be sure until it is gone.\n  Added symbol prefixing that allows all the libpng external symbols\n    to be prefixed (suggested by Reuben Hawkins).\n  Updated \"ftbb*.png\" list in the owatcom and vstudio projects.\n  Fixed 'prefix' builds on clean systems. The generation of pngprefix.h\n    should not require itself.\n  Updated INSTALL to explain that autogen.sh must be run in a GIT clone,\n    not in a libpng directory extracted from a tar distribution.\n\nVersion 1.6.0beta09 [February 1, 2012]\n  Reverted the prebuilt configure files to libpng-1.6.0beta05 condition.\n\nVersion 1.6.0beta10 [February 3, 2012]\n  Added Z_SOLO for zlib-1.2.6+ and correct pngstest tests\n  Updated list of test images in CMakeLists.txt\n  Updated the prebuilt configure files to current condition.\n  Revised INSTALL information about autogen.sh; it works in tar distributions.\n\nVersion 1.6.0beta11 [February 16, 2012]\n  Fix character count in pngstest command in projects/owatcom/pngstest.tgt\n  Revised test-pngstest.sh to report PASS/FAIL for each image.\n  Updated documentation about the simplified API.\n  Corrected estimate of error in libpng png_set_rgb_to_gray API.  The API is\n    extremely inaccurate for sRGB conversions because it uses an 8-bit\n    intermediate linear value and it does not use the sRGB transform, so it\n    suffers from the known instability in gamma transforms for values close\n    to 0 (see Poynton).  The net result is that the calculation has a maximum\n    error of 14.99/255; 0.5/255^(1/2.2).  pngstest now uses 15 for the\n    permitted 8-bit error. This may still not be enough because of arithmetic\n    error.\n  Removed some unused arrays (with #ifdef) from png_read_push_finish_row().\n  Fixed a memory overwrite bug in simplified read of RGB PNG with\n    non-linear gamma Also bugs in the error checking in pngread.c and changed\n    quite a lot of the checks in pngstest.c to be correct; either correctly\n    written or not over-optimistic.  The pngstest changes are insufficient to\n    allow all possible RGB transforms to be passed; pngstest cmppixel needs\n    to be rewritten to make it clearer which errors it allows and then changed\n    to permit known inaccuracies.\n  Removed tests for no-longer-used *_EMPTY_PLTE_SUPPORTED from pngstruct.h\n  Fixed fixed/float API export conditionals. 1) If FIXED_POINT or\n    FLOATING_POINT options were switched off, png.h ended up with lone ';'\n    characters.  This is not valid ANSI-C outside a function.  The ';'\n    characters have been moved inside the definition of PNG_FP_EXPORT and\n    PNG_FIXED_EXPORT. 2) If either option was switched off, the declaration\n    of the corresponding functions were completely omitted, even though some\n    of them are still used internally.  The result is still valid, but\n    produces warnings from gcc with some warning options (including -Wall). The\n    fix is to cause png.h to declare the functions with PNG_INTERNAL_FUNCTION\n    when png.h is included from pngpriv.h.\n  Check for invalid palette index while reading paletted PNG.  When one is\n    found, issue a warning and increase png_ptr->num_palette accordingly.\n    Apps are responsible for checking to see if that happened.\n\nVersion 1.6.0beta12 [February 18, 2012]\n  Do not increase num_palette on invalid_index.\n  Relocated check for invalid palette index to pngrtran.c, after unpacking\n    the sub-8-bit pixels.\n  Fixed CVE-2011-3026 buffer overrun bug.  This bug was introduced when\n    iCCP chunk support was added at libpng-1.0.6. Deal more correctly with the\n    test on iCCP chunk length. Also removed spurious casts that may hide\n    problems on 16-bit systems.\n\nVersion 1.6.0beta13 [February 24, 2012]\n  Eliminated redundant png_push_read_tEXt|zTXt|iTXt|unknown code from\n    pngpread.c and use the sequential png_handle_tEXt, etc., in pngrutil.c;\n    now that png_ptr->buffer is inaccessible to applications, the special\n    handling is no longer useful.\n  Added PNG_SAFE_LIMITS feature to pnglibconf.dfa, pngpriv.h, and new\n    pngusr.dfa to reset the user limits to safe ones if PNG_SAFE_LIMITS is\n    defined.  To enable, use \"CPPFLAGS=-DPNG_SAFE_LIMITS_SUPPORTED=1\" on the\n    configure command or put #define PNG_SAFE_LIMITS_SUPPORTED in\n    pnglibconf.h.prebuilt and pnglibconf.h.\n\nVersion 1.6.0beta14 [February 27, 2012]\n  Added information about the new limits in the manual.\n  Updated Makefile.in\n\nVersion 1.6.0beta15 [March 2, 2012]\n  Removed unused \"current_text\" members of png_struct and the png_free()\n    of png_ptr->current_text from pngread.c\n  Rewrote pngstest.c for substantial speed improvement.\n  Fixed transparent pixel and 16-bit rgb tests in pngstest and removed a\n    spurious check in pngwrite.c\n  Added PNG_IMAGE_FLAG_FAST for the benefit of applications that store\n    intermediate files, or intermediate in-memory data, while processing\n    image data with the simplified API.  The option makes the files larger\n    but faster to write and read.  pngstest now uses this by default; this\n    can be disabled with the --slow option.\n  Improved pngstest fine tuning of error numbers, new test file generator.\n    The generator generates images that test the full range of sample values,\n    allow the error numbers in pngstest to be tuned and checked.  makepng\n    also allows generation of images with extra chunks, although this is\n    still work-in-progress.\n  Added check for invalid palette index while reading.\n  Fixed some bugs in ICC profile writing. The code should now accept\n    all potentially valid ICC profiles and reject obviously invalid ones.\n    It now uses png_error() to do so rather than casually writing a PNG\n    without the necessary color data.\n  Removed whitespace from the end of lines in all source files and scripts.\n\nVersion 1.6.0beta16 [March 6, 2012]\n  Relocated palette-index checking function from pngrutil.c to pngtrans.c\n  Added palette-index checking while writing.\n  Changed png_inflate() and calling routines to avoid overflow problems.\n    This is an intermediate check-in that solves the immediate problems and\n    introduces one performance improvement (avoiding a copy via png_ptr->zbuf.)\n    Further changes will be made to make ICC profile handling more secure.\n  Fixed build warnings (MSVC, GCC, GCC v3). Cygwin GCC with default options\n    declares 'index' as a global, causing a warning if it is used as a local\n    variable.  GCC 64-bit warns about assigning a (size_t) (unsigned 64-bit)\n    to an (int) (signed 32-bit).  MSVC, however, warns about using the\n    unary '-' operator on an unsigned value (even though it is well defined\n    by ANSI-C to be ~x+1).  The padding calculation was changed to use a\n    different method.  Removed the tests on png_ptr->pass.\n  Added contrib/libtests/tarith.c to test internal arithmetic functions from\n    png.c. This is a libpng maintainer program used to validate changes to the\n    internal arithmetic functions.\n  Made read 'inflate' handling like write 'deflate' handling. The read\n    code now claims and releases png_ptr->zstream, like the write code.\n    The bug whereby the progressive reader failed to release the zstream\n    is now fixed, all initialization is delayed, and the code checks for\n    changed parameters on deflate rather than always calling\n    deflatedEnd/deflateInit.\n  Validate the zTXt strings in pngvalid.\n  Added code to validate the windowBits value passed to deflateInit2().\n    If the call to deflateInit2() is wrong a png_warning will be issued\n    (in fact this is harmless, but the PNG data produced may be sub-optimal).\n\nVersion 1.6.0beta17 [March 10, 2012]\n  Fixed PNG_LIBPNG_BUILD_BASE_TYPE definition. \n  Reject all iCCP chunks after the first, even if the first one is invalid.\n  Deflate/inflate was reworked to move common zlib calls into single\n    functions [rw]util.c.  A new shared keyword check routine was also added\n    and the 'zbuf' is no longer allocated on progressive read.  It is now\n    possible to call png_inflate() incrementally.  A warning is no longer\n    issued if the language tag or translated keyword in the iTXt chunk\n    has zero length.\n  If benign errors are disabled use maximum window on ancilliary inflate.\n    This works round a bug introduced in 1.5.4 where compressed ancillary\n    chunks could end up with a too-small windowBits value in the deflate\n    header.\n\nVersion 1.6.0beta18 [March 16, 2012]\n  Issue a png_benign_error() instead of png_warning() about bad palette index.\n  In pngtest, treat benign errors as errors if \"-strict\" is present.\n  Fixed an off-by-one error in the palette index checking function.\n  Fixed a compiler warning under Cygwin (Windows-7, 32-bit system)\n  Revised example.c to put text strings in a temporary character array\n    instead of directly assigning string constants to png_textp members.\n    This avoids compiler warnings when -Wwrite-strings is enabled.\n  Added output flushing to aid debugging under Visual Studio. Unfortunately\n    this is necessary because the VS2010 output window otherwise simply loses\n    the error messages on error (they weren't flushed to the window before\n    the process exited, apparently!)\n  Added configuration support for benign errors and changed the read\n    default. Also changed some warnings in the iCCP and sRGB handling\n    from to benign errors. Configuration now makes read benign\n    errors warnings and write benign errors to errors by default (thus\n    changing the behavior on read).  The simplified API always forces\n    read benign errors to warnings (regardless of the system default, unless\n    this is disabled in which case the simplified API can't be built.)\n\nVersion 1.6.0beta19 [March 18, 2012]\n  Work around for duplicate row start calls; added warning messages.\n    This turns on PNG_FLAG_DETECT_UNINITIALIZED to detect app code that\n    fails to call one of the 'start' routines (not enabled in libpng-1.5\n    because it is technically an API change, since it did normally work\n    before.)  It also makes duplicate calls to png_read_start_row (an\n    internal function called at the start of the image read) benign, as\n    they were before changes to use png_inflate_claim. Somehow webkit is\n    causing this to happen; this is probably a mis-feature in the zlib\n    changes so this commit is only a work-round.\n  Removed erroneous setting of DETECT_UNINITIALIZED and added more\n    checks. The code now does a png_error if an attempt is made to do the\n    row initialization twice; this is an application error and it has\n    serious consequences because the transform data in png_struct is\n    changed by each call.\n  Added application error reporting and added chunk names to read\n    benign errors; also added --strict to pngstest - not enabled\n    yet because a warning is produced.\n  Avoid the double gamma correction warning in the simplified API.\n    This allows the --strict option to pass in the pngstest checks\n\nVersion 1.6.0beta20 [March 29, 2012]\n  Changed chunk handler warnings into benign errors, incrementally load iCCP\n  Added checksum-icc.c to contrib/tools\n  Prevent PNG_EXPAND+PNG_SHIFT doing the shift twice.\n  Recognize known sRGB ICC profiles while reading; prefer writing the\n    iCCP profile over writing the sRGB chunk, controlled by the\n    PNG_sRGB_PROFILE_CHECKS option.\n  Revised png_set_text_2() to avoid potential memory corruption (fixes\n    CVE-2011-3048, also known as CVE-2012-3425).\n\nVersion 1.6.0beta21 [April 27, 2012]\n  Revised scripts/makefile.darwin: use system zlib; remove quotes around\n    architecture list; add missing ppc architecture; add architecture options\n    to shared library link; don't try to create a shared lib based on missing\n    RELEASE variable.\n  Enable png_set_check_for_invalid_index() for both read and write.\n  Removed #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED in pngpriv.h around\n    declaration of png_handle_unknown().\n  Added -lssp_nonshared in a comment in scripts/makefile.freebsd\n    and changed deprecated NOOBJ and NOPROFILE to NO_OBJ and NO_PROFILE.\n\nVersion 1.6.0beta22 [May 23, 2012]\n  Removed need for -Wno-cast-align with clang.  clang correctly warns on\n    alignment increasing pointer casts when -Wcast-align is passed. This\n    fixes the cases that clang warns about either by eliminating the\n    casts from png_bytep to png_uint_16p (pngread.c), or, for pngrutil.c\n    where the cast is previously verified or pngstest.c where it is OK, by\n    introducing new png_aligncast macros to do the cast in a way that clang\n    accepts.\n\nVersion 1.6.0beta23 [June 6, 2012]\n  Revised CMakeLists.txt to not attempt to make a symlink under mingw.\n  Made fixes for new optimization warnings from gcc 4.7.0. The compiler\n    performs an optimization which is safe; however it then warns about it.\n    Changing the type of 'palette_number' in pngvalid.c removes the warning.\n  Do not depend upon a GCC feature macro being available for use in generating\n    the linker mapfile symbol prefix.\n  Improved performance of new do_check_palette_indexes() function (only\n    update the value when it actually increases, move test for whether\n    the check is wanted out of the function.\n\nVersion 1.6.0beta24 [June 7, 2012]\n  Don't check palette indexes if num_palette is 0 (as it can be in MNG files).\n\nVersion 1.6.0beta25 [June 16, 2012]\n  Revised png_set_keep_unknown_chunks() so num_chunks < 0 means ignore all\n    unknown chunks and all known chunks except for IHDR, PLTE, tRNS, IDAT,\n    and IEND.  Previously it only meant ignore all unknown chunks, the\n    same as num_chunks == 0. Revised png_image_skip_unused_chunks() to\n    provide a list of chunks to be processed instead of a list of chunks to\n    ignore.  Revised contrib/gregbook/readpng2.c accordingly.\n\nVersion 1.6.0beta26 [July 10, 2012]\n  Removed scripts/makefile.cegcc from the *.zip and *.7z distributions; it\n    depends on configure, which is not included in those archives.\n  Moved scripts/chkfmt to contrib/tools.\n  Changed \"a+w\" to \"u+w\" in Makefile.in to fix CVE-2012-3386.\n\nVersion 1.6.0beta27 [August 11, 2012]\n  Do not compile PNG_DEPRECATED, PNG_ALLOC and PNG_PRIVATE when __GNUC__ < 3.\n  Do not use __restrict when GNUC is <= 3.1\n  Removed references to png_zalloc() and png_zfree() from the manual.\n  Fixed configurations where floating point is completely disabled.  Because\n    of the changes to support symbol prefixing PNG_INTERNAL_FUNCTION declares\n    floating point APIs during libpng builds even if they are completely\n    disabled. This requires the png floating point types (png_double*) to be\n    declared even though the functions are never actually defined.  This\n    change provides a dummy definition so that the declarations work, yet any\n    implementation will fail to compile because of an incomplete type.\n  Re-eliminated the use of strcpy() in pngtest.c.  An unncessary use of\n    strcpy() was accidentally re-introduced in libpng16; this change replaces\n    it with strncpy().\n  Eliminated use of png_sizeof(); use sizeof() instead.\n  Use a consistent style for (sizeof type) and (sizeof (array))\n  Cleanup of png_set_filler().  This function does very different things on\n    read and write.  In libpng 1.6 the two cases can be distinguished and\n    considerable code cleanup, and extra error checking, is possible.  This\n    makes calls on the write side that have no effect be ignored with a\n    png_app_error(), which can be disabled in the app using\n    png_set_benign_errors(), and removes the spurious use of usr_channels\n    on the read side.\n  Insist on autotools 1.12.1 for git builds because there are security issues\n    with 1.12 and insisting on anything less would allow 1.12 to be used.\n  Removed info_ptr->signature[8] from WRITE-only builds.\n  Add some conditions for compiling png_fixed().  This is a small function\n    but it requires \"-lm\" on some platforms.\n  Cause pngtest --strict to fail on any warning from libpng (not just errors)\n    and cause it not to fail at the comparison step if libpng lacks support\n    for writing chunks that it reads from the input (currently only implemented\n    for compressed text chunks).\n  Make all three \"make check\" test programs work without READ or WRITE support.\n    Now \"make check\" will succeed even if libpng is compiled with -DPNG_NO_READ\n    or -DPNG_NO_WRITE.  The tests performed are reduced, but the basic reading\n    and writing of a PNG file is always tested by one or more of the tests.\n  Consistently use strlen(), memset(), memcpy(), and memcmp() instead of the\n    png_strlen(), png_memset(), png_memcpy(), and png_memcmp() macros.\n  Removed the png_sizeof(), png_strlen(), png_memset(), png_memcpy(), and\n    png_memcmp() macros.\n  Work around gcc 3.x and Microsoft Visual Studio 2010 complaints. Both object\n    to the split initialization of num_chunks.\n\nVersion 1.6.0beta28 [August 29, 2012]\n  Unknown handling fixes and clean up. This adds more correct option\n    control of the unknown handling, corrects the pre-existing bug where\n    the per-chunk 'keep' setting is ignored and makes it possible to skip\n    IDAT chunks in the sequential reader (broken in earlier 1.6 versions).\n    There is a new test program, test-unknown.c, which is a work in progress\n    (not currently part of the test suite).  Comments in the header files now\n    explain how the unknown handling works.\n  Allow fine grain control of unknown chunk APIs. This change allows\n    png_set_keep_unknown_chunks() to be turned off if not required and causes\n    both read and write to behave appropriately (on read this is only possible\n    if the user callback is used to handle unknown chunks).  The change\n    also removes the support for storing unknown chunks in the info_struct\n    if the only unknown handling enabled is via the callback, allowing libpng\n    to be configured with callback reading and none of the unnecessary code.\n  Corrected fix for unknown handling in pngtest. This reinstates the\n    libpng handling of unknown chunks other than vpAg and sTER (including\n    unsafe-to-copy chunks which were dropped before) and eliminates the\n    repositioning of vpAg and sTER in pngtest.png by changing pngtest.png\n    (so the chunks are where libpng would put them).\n  Added \"tunknown\" test and corrected a logic error in png_handle_unknown()\n    when SAVE support is absent.  Moved the shell test scripts for\n    contrib/libtests from the libpng top directory to contrib/libtests.\n    png_handle_unknown() must always read or skip the chunk, if\n    SAVE_UNKNOWN_CHUNKS is turned off *and* the application does not set\n    a user callback an unknown chunk will not be read, leading to a read\n    error, which was revealed by the \"tunknown\" test.\n  Cleaned up and corrected ICC profile handling.\n    contrib/libtests/makepng: corrected 'rgb' and 'gray' cases.  profile_error\n    messages could be truncated; made a correct buffer size calculation and\n    adjusted pngerror.c appropriately. png_icc_check_* checking improved;\n    changed the functions to receive the correct color type of the PNG on read\n    or write and check that it matches the color space of the profile (despite\n    what the comments said before, there is danger in assuming the app will\n    cope correctly with an RGB profile on a grayscale image and, since it\n    violates the PNG spec, allowing it is certain to produce inconsistent\n    app behavior and might even cause app crashes.) Check that profiles\n    contain the tags needed to process the PNG (tags all required by the ICC\n    spec). Removed unused PNG_STATIC from pngpriv.h.\n\nVersion 1.6.0beta29 [September 4, 2012]\n  Fixed the simplified API example programs to add the *colormap parameter\n    to several of he API and improved the error message if the version field\n    is not set.\n  Added contrib/examples/* to the *.zip and *.7z distributions.\n  Updated simplified API synopses and description of the png_image structure\n    in the manual.\n  Made makepng and pngtest produce identical PNGs, add \"--relaxed\" option\n    to pngtest. The \"--relaxed\" option turns off the benign errors that are\n    enabled by default in pre-RC builds. makepng can now write ICC profiles\n    where the length has not been extended to a multiple of 4, and pngtest\n    now intercepts all libpng errors, allowing the previously-introduced\n    \"--strict test\" on no warnings to actually work.\n  Improved ICC profile handling including cHRM chunk generation and fixed\n    Cygwin+MSVC build errors. The ICC profile handling now includes more\n    checking.  Several errors that caused rejection of the profile are now\n    handled with a warning in such a way that the invalid profiles will be\n    read by default in release (but not pre-RC) builds but will not be\n    written by default.  The easy part of handling the cHRM chunk is written,\n    where the ICC profile contains the required data.  The more difficult\n    part plus guessing a gAMA value requires code to pass selected RGB values\n    through the profile.\n\nVersion 1.6.0beta30 [October 24, 2012]\n  Changed ICC profile matrix/vector types to not depend on array type rules.\n    By the ANSI-C standard the new types should be identical to the previous\n    versions, and all known versions of gcc tested with the previous versions\n    except for GCC-4.2.1 work with this version.  The change makes the ANSI-C\n    rule that const applied to an array of elements applies instead to the\n    elements in the array moot by explicitly applying const to the base\n    elements of the png_icc_matrix and png_icc_vector types. The accidental\n    (harmless) 'const' previously applied to the parameters of two of the\n    functions have also been removed.\n  Added a work around for GCC 4.2 optimization bug.\n  Marked the broken (bad white point) original HP sRGB profiles correctly and\n    correct comments.\n  Added -DZ_SOLO to contrib/pngminim/*/makefile to work with zlib-1.2.7\n  Use /MDd for vstudio debug builds. Also added pngunkown to the vstudio\n    builds, fixed build errors and corrected a minor exit code error in\n    pngvalid if the 'touch' file name is invalid.\n  Add updated WARNING file to projects/vstudio from libpng 1.5/vstudio\n  Fixed build when using #define PNG_NO_READ_GAMMA in png_do_compose() in\n    pngrtran.c (Domani Hannes).\n\nVersion 1.6.0beta31 [November 1, 2012]\n  Undid the erroneous change to vstudio/pngvalid build in libpng-1.6.0beta30.\n  Made pngvalid so that it will build outside the libpng source tree.\n  Made builds -DPNG_NO_READ_GAMMA compile (the unit tests still fail).\n  Made PNG_NO_READ_GAMMA switch off interfaces that depend on READ_GAMMA.\n    Prior to 1.6.0 switching off READ_GAMMA did unpredictable things to the\n    interfaces that use it (specifically, png_do_background in 1.4 would\n    simply display composite for grayscale images but do composition\n    with the incorrect arithmetic for color ones). In 1.6 the semantic\n    of -DPNG_NO_READ_GAMMA is changed to simply disable any interface that\n    depends on it; this obliges people who set it to consider whether they\n    really want it off if they happen to use any of the interfaces in\n    question (typically most users who disable it won't).\n  Fixed GUIDs in projects/vstudio. Some were duplicated or missing,\n    resulting in VS2010 having to update the files.\n  Removed non-working ICC profile support code that was mostly added to\n    libpng-1.6.0beta29 and beta30. There was too much code for too little\n    gain; implementing full ICC color correction may be desireable but is left\n    up to applications.\n\nVersion 1.6.0beta32 [November 25, 2012]\n  Fixed an intermittent SEGV in pngstest due to an uninitialized array element.\n  Added the ability for contrib/libtests/makepng.c to make a PNG with just one\n    color. This is useful for debugging pngstest color inaccuracy reports.\n  Fixed error checking in the simplified write API (Olaf van der Spek)\n  Made png_user_version_check() ok to use with libpng version 1.10.x and later.\n\nVersion 1.6.0beta33 [December 15, 2012]\n  Fixed typo in png.c (PNG_SET_CHUNK_MALLOC_MAX should be PNG_CHUNK_MALLOC_MAX)\n    that causes the MALLOC_MAX limit not to work (John Bowler)\n  Change png_warning() to png_app_error() in pngwrite.c and comment the\n    fall-through condition.\n  Change png_warning() to png_app_warning() in png_write_tRNS().\n  Rearranged the ARM-NEON optimizations: Isolated the machine specific code\n    to the hardware subdirectory and added comments to pngrutil.c so that\n    implementors of other optimizations know what to do.\n  Fixed cases of unquoted DESTDIR in Makefile.am\n  Rebuilt Makefile.in, etc., with autoconf-2.69 and automake-1.12.5.\n\nVersion 1.6.0beta34 [December 19, 2012]\n  Cleaned up whitespace in the synopsis portion of the manpage \"libpng.3\"\n  Disassembled the version number in scripts/options.awk (necessary for\n    building on SunOs).\n\nVersion 1.6.0beta35 [December 23, 2012]\n  Made default Zlib compression settings be configurable. This adds #defines to\n    pnglibconf.h to control the defaults.\n  Fixed Windows build issues, enabled ARM compilation. Various warnings issued\n    by earlier versions of GCC fixed for Cygwin and Min/GW (which both use old\n    GCCs.) ARM support is enabled by default in zlib.props (unsupported by\n    Microsoft) and ARM compilation is made possible by deleting the check for\n    x86. The test programs cannot be run because they are not signed.\n\nVersion 1.6.0beta36 [January 2, 2013]\n  Discontinued distributing libpng-1.x.x.tar.bz2.\n  Discontinued distributing libpng-1.7.0-1.6.0-diff.txt and similar.\n  Rebuilt configure with autoconf-2.69 (inadvertently not done in beta33)\n  Fixed 'make distcheck' on SUN OS - libpng.so was not being removed\n\nVersion 1.6.0beta37 [January 10, 2013]\n  Fixed conceivable but difficult to repro overflow. Also added two test\n    programs to generate and test a PNG which should have the problem.\n\nVersion 1.6.0beta39 [January 19, 2013]\n  Again corrected attempt at overflow detection in png_set_unknown_chunks()\n  (CVE-2013-7353).  Added overflow detection in png_set_sPLT() and\n  png_set_text_2() (CVE-2013-7354).\n\nVersion 1.6.0beta40 [January 20, 2013]\n  Use consistent handling of overflows in text, sPLT and unknown png_set_* APIs\n\nVersion 1.6.0rc01 [January 26, 2013]\n  No changes.\n\nVersion 1.6.0rc02 [February 4, 2013]\n  Added png_get_palette_max() function.\n\nVersion 1.6.0rc03 [February 5, 2013]\n  Fixed the png_get_palette_max API.\n\nVersion 1.6.0rc04 [February 7, 2013]\n  Turn serial tests back on (recently turned off by autotools upgrade).\n\nVersion 1.6.0rc05 [February 8, 2013]\n  Update manual about png_get_palette_max().\n\nVersion 1.6.0rc06 [February 9, 2013]\n  Fixed missing dependency in --prefix builds The intermediate\n    internal 'prefix.h' file can only be generated correctly after\n    pnglibconf.h, however the dependency was not in Makefile.am.  The\n    symptoms are unpredictable depending on the order make chooses to\n    build pngprefix.h and pnglibconf.h, often the error goes unnoticed\n    because there is a system pnglibconf.h to use instead.\n\nVersion 1.6.0rc07 [February 10, 2013]\n  Enclosed the new png_get_palette_max in #ifdef PNG_GET_PALETTE_MAX_SUPPORTED\n    block, and revised pnglibconf.h and pnglibconf.h.prebuilt accordingly.\n\nVersion 1.6.0rc08 [February 10, 2013]\n  Fix typo in png.h #ifdef\n\nVersion 1.6.0 [February 14, 2013]\n  No changes.\n\nVersion 1.6.1beta01 [February 16, 2013]\n  Made symbol prefixing work with the ARM neon optimizations. Also allow\n    pngpriv.h to be included for preprocessor definitions only, so it can\n    be used in non-C/C++ files. Back ported from libpng 1.7.\n  Made sRGB check numbers consistent.\n  Ported libpng 1.5 options.awk/dfn file handling to 1.6, fixed one bug.\n  Removed cc -E workround, corrected png_get_palette_max API Tested on\n    SUN OS cc 5.9, which demonstrates the tokenization problem previously\n    avoided by using /lib/cpp.  Since all .dfn output is now protected in\n    double quotes unless it is to be macro substituted the fix should\n    work everywhere.\n  Enabled parallel tests - back ported from libpng-1.7.\n  scripts/pnglibconf.dfa formatting improvements back ported from libpng17.\n  Fixed a race condition in the creation of the build 'scripts' directory\n    while building with a parallel make.\n  Use approved/supported Android method to check for NEON, use Linux/POSIX\n    1003.1 API to check /proc/self/auxv avoiding buffer allocation and other\n    library calls (ported from libpng15).\n\nVersion 1.6.1beta02 [February 19, 2013]\n  Use parentheses more consistently in \"#if defined(MACRO)\" tests.\n  Folded long lines.\n  Reenabled code to allow zero length PLTE chunks for MNG.\n\nVersion 1.6.1beta03 [February 22, 2013]\n  Fixed ALIGNED_MEMORY support.\n  Added a new configure option:\n    --enable-arm-neon=always will stop the run-time checks. New checks\n    within arm/arm_init.c will cause the code not to be compiled unless\n    __ARM_NEON__ is set. This should make it fail safe (if someone asks\n    for it on then the build will fail if it can't be done.)\n  Updated the INSTALL document.\n\nVersion 1.6.1beta04 [February 27, 2013]\n  Revised INSTALL to recommend using CPPFLAGS instead of INCLUDES.\n  Revised scripts/makefile.freebsd to respect ZLIBLIB and ZLIBINC.\n  Revised scripts/dfn.awk to work with the buggy MSYS awk that has trouble\n    with CRLF line endings.\n\nVersion 1.6.1beta05 [March 1, 2013]\n  Avoid a possible memory leak in contrib/gregbook/readpng.c\n\nVersion 1.6.1beta06 [March 4, 2013]\n  Better documentation of unknown handling API interactions.\n  Corrected Android builds and corrected libpng.vers with symbol\n    prefixing.  It also makes those tests compile and link on Android.\n  Added an API png_set_option() to set optimization options externally,\n    providing an alternative and general solution for the non-portable\n    run-time tests used by the ARM Neon code, using the PNG_ARM_NEON option.\n  The order of settings vs options in pnglibconf.h is reversed to allow\n    settings to depend on options and options can now set (or override) the\n    defaults for settings.\n\nVersion 1.6.1beta07 [March 7, 2013]\n  Corrected simplified API default gamma for color-mapped output, added\n    a flag to change default. In 1.6.0 when the simplified API was used\n    to produce color-mapped output from an input image with no gamma\n    information the gamma assumed for the input could be different from\n    that assumed for non-color-mapped output.  In particular 16-bit depth\n    input files were assumed to be sRGB encoded, whereas in the 'direct'\n    case they were assumed to have linear data.  This was an error.  The\n    fix makes the simplified API treat all input files the same way and\n    adds a new flag to the png_image::flags member to allow the\n    application/user to specify that 16-bit files contain sRGB data\n    rather than the default linear.\n  Fixed bugs in the pngpixel and makepng test programs.\n\nVersion 1.6.1beta08 [March 7, 2013]\n  Fixed CMakelists.txt to allow building a single variant of the library\n    (Claudio Bley):\n  Introduced a PNG_LIB_TARGETS variable that lists all activated library\n    targets.  It is an error if this variable ends up empty, ie. you have\n    to build at least one library variant.\n  Made the *_COPY targets only depend on library targets actually being build.\n  Use PNG_LIB_TARGETS to unify a code path.\n  Changed the CREATE_SYMLINK macro to expect the full path to a file as the\n    first argument. When symlinking the filename component of that path is\n    determined and used as the link target.\n  Use copy_if_different in the CREATE_SYMLINK macro.\n\nVersion 1.6.1beta09 [March 13, 2013]\n  Eliminated two warnings from the Intel C compiler. The warnings are\n    technically valid, although a reasonable treatment of division would\n    show it to be incorrect.\n\nVersion 1.6.1rc01 [March 21, 2013]\n  No changes.\n\nVersion 1.6.1 [March 28, 2013]\n  No changes.\n\nVersion 1.6.2beta01 [April 14, 2013]\n  Updated documentation of 1.5.x to 1.6.x changes in iCCP chunk handling.\n  Fixed incorrect warning of excess deflate data. End condition - the\n    warning would be produced if the end of the deflate stream wasn't read\n    in the last row.  The warning is harmless.\n  Corrected the test on user transform changes on read. It was in the\n    png_set of the transform function, but that doesn't matter unless the\n    transform function changes the rowbuf size, and that is only valid if\n    transform_info is called.\n  Corrected a misplaced closing bracket in contrib/libtests/pngvalid.c\n    (Flavio Medeiros).\n  Corrected length written to uncompressed iTXt chunks (Samuli Suominen).\n    Bug was introduced in libpng-1.6.0.\n\nVersion 1.6.2rc01 [April 18, 2013]\n  Added contrib/tools/fixitxt.c, to repair the erroneous iTXt chunk length\n    written by libpng-1.6.0 and 1.6.1.\n  Disallow storing sRGB information when the sRGB is not supported.\n\nVersion 1.6.2rc02 [April 18, 2013]\n  Merge pngtest.c with libpng-1.7.0\n\nVersion 1.6.2rc03 [April 22, 2013]\n  Trivial spelling cleanup.\n\nVersion 1.6.2rc04 and 1.6.2rc05 [omitted]\n\nVersion 1.6.2rc06 [April 24, 2013]\n  Reverted to version 1.6.2rc03.  Recent changes to arm/neon support\n    have been ported to libpng-1.7.0beta09 and will reappear in version\n    1.6.3beta01.\n\nVersion 1.6.2 [April 25, 2013]\n  No changes.\n\nVersion 1.6.3beta01 [April 25, 2013]\n  Revised stack marking in arm/filter_neon.S and configure.ac.\n  Ensure that NEON filter stuff is completely disabled when switched 'off'.\n    Previously the ARM NEON specific files were still built if the option\n    was switched 'off' as opposed to being explicitly disabled.\n\nVersion 1.6.3beta02 [April 26, 2013]\n  Test for 'arm*' not just 'arm' in the host_cpu configure variable.\n  Rebuilt the configure scripts.\n\nVersion 1.6.3beta03 [April 30, 2013]\n  Expanded manual paragraph about writing private chunks, particularly\n    the need to call png_set_keep_unknown_chunks() when writing them.\n  Avoid dereferencing NULL pointer possibly returned from\n    png_create_write_struct() (Andrew Church).\n\nVersion 1.6.3beta05 [May 9, 2013]\n  Calculate our own zlib windowBits when decoding rather than trusting the\n    CMF bytes in the PNG datastream.\n  Added an option to force maximum window size for inflating, which was\n    the behavior of libpng15 and earlier, via a new PNG_MAXIMUM_INFLATE_WINDOW\n    option for png_set_options().\n  Added png-fix-itxt and png-fix-too-far-back to the built programs and\n    removed warnings from the source code and timepng that are revealed as\n    a result.\n  Detect wrong libpng versions linked to png-fix-too-far-back, which currently\n    only works with libpng versions that can be made to reliably fail when\n    the deflate data contains an out-of-window reference.  This means only\n    1.6 and later.\n  Fixed gnu issues: g++ needs a static_cast, gcc 4.4.7 has a broken warning\n    message which it is easier to work round than ignore.\n  Updated contrib/pngminus/pnm2png.c (Paul Stewart):\n    Check for EOF\n    Ignore \"#\" delimited comments in input file to pnm2png.c.\n    Fixed whitespace handling\n    Added a call to png_set_packing()\n    Initialize dimension values so if sscanf fails at least we have known\n      invalid values.\n  Attempt to detect configuration issues with png-fix-too-far-back, which\n    requires both the correct libpng and the correct zlib to function\n    correctly.\n  Check ZLIB_VERNUM for mismatches, enclose #error in quotes\n  Added information in the documentation about problems with and fixes for\n    the bad CRC and bad iTXt chunk situations.\n\nVersion 1.6.3beta06 [May 12, 2013]\n  Allow contrib/pngminus/pnm2png.c to compile without WRITE_INVERT and\n    WRITE_PACK supported (writes error message that it can't read P1 or\n    P4 PBM files).\n  Improved png-fix-too-far-back usage message, added --suffix option.\n  Revised contrib/pngminim/*/makefile to generate pnglibconf.h with the\n    right zlib header files.\n  Separated CPPFLAGS and CFLAGS in contrib/pngminim/*/makefile\n\nVersion 1.6.3beta07 [June 8, 2013]\n  Removed a redundant test in png_set_IHDR().\n  Added set(CMAKE_CONFIGURATION_TYPES ...) to CMakeLists.txt (Andrew Hundt)\n  Deleted set(CMAKE_BUILD_TYPE) block from CMakeLists.txt\n  Enclose the prototypes for the simplified write API in\n    #ifdef PNG_STDIO_SUPPORTED/#endif\n  Make ARM NEON support work at compile time (not just configure time).\n    This moves the test on __ARM_NEON__ into pngconf.h to avoid issues when\n    using a compiler that compiles for multiple architectures at one time.\n  Removed PNG_FILTER_OPTIMIZATIONS and PNG_ARM_NEON_SUPPORTED from\n    pnglibconf.h, allowing more of the decisions to be made internally\n    (pngpriv.h) during the compile.  Without this, symbol prefixing is broken\n    under certain circumstances on ARM platforms.  Now only the API parts of\n    the optimizations ('check' vs 'api') are exposed in the public header files\n    except that the new setting PNG_ARM_NEON_OPT documents how libpng makes the\n    decision about whether or not to use the optimizations.\n  Protect symbol prefixing against CC/CPPFLAGS/CFLAGS useage.\n    Previous iOS/Xcode fixes for the ARM NEON optimizations moved the test\n    on __ARM_NEON__ from configure time to compile time.  This breaks symbol\n    prefixing because the definition of the special png_init_filter_functions\n    call was hidden at configure time if the relevant compiler arguments are\n    passed in CFLAGS as opposed to CC.  This change attempts to avoid all\n    the confusion that would result by declaring the init function even when\n    it is not used, so that it will always get prefixed.\n\nVersion 1.6.3beta08 [June 18, 2013]\n  Revised libpng.3 so that \"doclifter\" can process it.\n\nVersion 1.6.3beta09 [June 27, 2013]\n  Revised example.c to illustrate use of PNG_DEFAULT_sRGB and PNG_GAMMA_MAC_18\n    as parameters for png_set_gamma().  These have been available since\n    libpng-1.5.4.\n  Renamed contrib/tools/png-fix-too-far-back.c to pngfix.c and revised it\n    to check all compressed chunks known to libpng.\n\nVersion 1.6.3beta10 [July 5, 2013]\n  Updated documentation to show default behavior of benign errors correctly.\n  Only compile ARM code when PNG_READ_SUPPORTED is defined.\n  Fixed undefined behavior in contrib/tools/pngfix.c and added new strip\n    option. pngfix relied on undefined behavior and even a simple change from\n    gcc to g++ caused it to fail.  The new strip option 'unsafe' has been\n    implemented and is the default if --max is given.  Option names have\n    been clarified, with --strip=transform now stripping the bKGD chunk,\n    which was stripped previously with --strip=unused.\n  Added all documented chunk types to pngpriv.h\n  Unified pngfix.c source with libpng17.\n\nVersion 1.6.3rc01 [July 11, 2013]\n  No changes.\n\nVersion 1.6.3 [July 18, 2013]\n  Revised manual about changes in iTXt chunk handling made in libpng-1.6.0.\n  Added \"/* SAFE */\" comments in pngrutil.c and pngrtran.c where warnings\n    may be erroneously issued by code-checking applications.\n\nVersion 1.6.4beta01 [August 21, 2013]\n  Added information about png_set_options() to the manual.\n  Delay calling png_init_filter_functions() until a row with nonzero filter\n    is found.\n\nVersion 1.6.4beta02 [August 30, 2013]\n  Fixed inconsistent conditional compilation of png_chunk_unknown_handling()\n    prototype, definition, and usage.  Made it depend on\n    PNG_HANDLE_AS_UNKNOWN_SUPPORTED everywhere.\n\nVersion 1.6.4rc01 [September 5, 2013]\n  No changes.\n\nVersion 1.6.4 [September 12, 2013]\n  No changes.\n\nVersion 1.6.5 [September 14, 2013]\n  Removed two stray lines of code from arm/arm_init.c.\n\nVersion 1.6.6 [September 16, 2013]\n  Removed two stray lines of code from arm/arm_init.c, again.\n\nVersion 1.6.7beta01 [September 30, 2013]\n  Revised unknown chunk code to correct several bugs in the NO_SAVE_/NO_WRITE\n    combination\n  Allow HANDLE_AS_UNKNOWN to work when other options are configured off. Also\n    fixed the pngminim makefiles to work when $(MAKEFLAGS) contains stuff\n    which terminates the make options (as by default in recent versions of\n    Gentoo).\n  Avoid up-cast warnings in pngvalid.c. On ARM the alignment requirements of\n    png_modifier are greater than that of png_store and as a consequence\n    compilation of pngvalid.c results in a warning about increased alignment\n    requirements because of the bare cast to (png_modifier*). The code is safe,\n    because the pointer is known to point to a stack allocated png_modifier,\n    but this change avoids the warning.\n  Fixed default behavior of ARM_NEON_API. If the ARM NEON API option was\n    compiled without the CHECK option it defaulted to on, not off.\n  Check user callback behavior in pngunknown.c. Previous versions compiled\n    if SAVE_UNKNOWN was not available but did nothing since the callback\n    was never implemented.\n  Merged pngunknown.c with 1.7 version and back ported 1.7 improvements/fixes\n\nVersion 1.6.7beta02 [October 12, 2013]\n  Made changes for compatibility with automake 1.14:\n    1) Added the 'compile' program to the list of programs that must be cleaned\n       in autogen.sh\n    2) Added 'subdir-objects' which causes .c files in sub-directories to be\n       compiled such that the corresponding .o files are also in the\n       sub-directory.  This is because automake 1.14 warns that the\n       current behavior of compiling to the top level directory may be removed\n       in the future.\n    3) Updated dependencies on pnglibconf.h to match the new .o locations and\n       added all the files in contrib/libtests and contrib/tools that depend\n       on pnglibconf.h\n    4) Added 'BUILD_SOURCES = pnglibconf.h'; this is the automake recommended\n       way of handling the dependencies of sources that are machine generated;\n       unfortunately it only works if the user does 'make all' or 'make check',\n       so the dependencies (3) are still required.\n  Cleaned up (char*) casts of zlib messages. The latest version of the Intel C\n    compiler complains about casting a string literal as (char*), so copied the\n    treatment of z_const from the library code into pngfix.c\n  Simplified error message code in pngunknown. The simplification has the\n    useful side effect of avoiding a bogus warning generated by the latest\n    version of the Intel C compiler (it objects to\n    condition ? string-literal : string-literal).\n  Make autogen.sh work with automake 1.13 as well as 1.14. Do this by always\n    removing the 1.14 'compile' script but never checking for it.\n\nVersion 1.6.7beta03 [October 19, 2013]\n  Added ARMv8 support (James Yu <james.yu at linaro.org>).  Added file\n    arm/filter_neon_intrinsics.c; enable with -mfpu=neon.\n  Revised pngvalid to generate size images with as many filters as it can\n    manage, limited by the number of rows.\n  Cleaned up ARM NEON compilation handling. The tests are now in pngpriv.h\n    and detect the broken GCC compilers.\n\nVersion 1.6.7beta04 [October 26, 2013]\n  Allow clang derived from older GCC versions to use ARM intrinsics. This\n    causes all clang builds that use -mfpu=neon to use the intrinsics code,\n    not the assembler code.  This has only been tested on iOS 7. It may be\n    necessary to exclude some earlier clang versions but this seems unlikely.\n  Changed NEON implementation selection mechanism. This allows assembler\n    or intrinsics to be turned on at compile time during the build by defining\n    PNG_ARM_NEON_IMPLEMENTATION to the correct value (2 or 1).  This macro\n    is undefined by default and the build type is selected in pngpriv.h.\n\nVersion 1.6.7rc01 [November 2, 2013]\n  No changes.\n\nVersion 1.6.7rc02 [November 7, 2013]\n  Fixed #include in filter_neon_intrinsics.c and ctype macros. The ctype char\n    checking macros take an unsigned char argument, not a signed char.\n\nVersion 1.6.7 [November 14, 2013]\n  No changes.\n\nVersion 1.6.8beta01 [November 24, 2013]\n  Moved prototype for png_handle_unknown() in pngpriv.h outside of\n    the #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED/#endif block.\n  Added \"-Wall\" to CFLAGS in contrib/pngminim/*/makefile\n  Conditionally compile some unused functions reported by -Wall in\n    pngminim.\n  Fixed 'minimal' builds. Various obviously useful minimal configurations\n    don't build because of missing contrib/libtests test programs and\n    overly complex dependencies in scripts/pnglibconf.dfa. This change\n    adds contrib/conftest/*.dfa files that can be used in automatic build\n    scripts to ensure that these configurations continue to build.\n  Enabled WRITE_INVERT and WRITE_PACK in contrib/pngminim/encoder.\n  Fixed pngvalid 'fail' function declaration on the Intel C Compiler.\n    This reverts to the previous 'static' implementation and works round\n    the 'unused static function' warning by using PNG_UNUSED().\n\nVersion 1.6.8beta02 [November 30, 2013]\n  Removed or marked PNG_UNUSED some harmless \"dead assignments\" reported\n    by clang scan-build.\n  Changed tabs to 3 spaces in png_debug macros and changed '\"%s\"m'\n    to '\"%s\" m' to improve portability among compilers.\n  Changed png_free_default() to free() in pngtest.c\n\nVersion 1.6.8rc01 [December 12, 2013]\n  Tidied up pngfix inits and fixed pngtest no-write builds.\n\nVersion 1.6.8rc02 [December 14, 2013]\n  Handle zero-length PLTE chunk or NULL palette with png_error()\n    instead of png_chunk_report(), which by default issues a warning\n    rather than an error, leading to later reading from a NULL pointer\n    (png_ptr->palette) in png_do_expand_palette(). This is CVE-2013-6954\n    and VU#650142.  Libpng-1.6.1 through 1.6.7 are vulnerable.\n    Libpng-1.6.0 and earlier do not have this bug.\n\nVersion 1.6.8 [December 19, 2013]\n  No changes.\n\nVersion 1.6.9beta01 [December 26, 2013]\n  Bookkeeping: Moved functions around (no changes). Moved transform\n    function definitions before the place where they are called so that\n    they can be made static. Move the intrapixel functions and the\n    grayscale palette builder out of the png?tran.c files. The latter\n    isn't a transform function and is no longer used internally, and the\n    former MNG specific functions are better placed in pngread/pngwrite.c\n  Made transform implementation functions static. This makes the internal\n    functions called by png_do_{read|write}_transformations static. On an\n    x86-64 DLL build (Gentoo Linux) this reduces the size of the text\n    segment of the DLL by 1208 bytes, about 0.6%. It also simplifies\n    maintenance by removing the declarations from pngpriv.h and allowing\n    easier changes to the internal interfaces.\n  Rebuilt configure scripts with automake-1.14.1 and autoconf-2.69\n    in the tar distributions.\n\nVersion 1.6.9beta02 [January 1, 2014]\n  Added checks for libpng 1.5 to pngvalid.c.  This supports the use of\n    this version of pngvalid in libpng 1.5\n  Merged with pngvalid.c from libpng-1.7 changes to create a single\n    pngvalid.c\n  Removed #error macro from contrib/tools/pngfix.c (Thomas Klausner).\n  Merged pngrio.c, pngtrans.c, pngwio.c, and pngerror.c with libpng-1.7.0\n  Merged libpng-1.7.0 changes to make no-interlace configurations work\n    with test programs.\n  Revised pngvalid.c to support libpng 1.5, which does not support the\n    PNG_MAXIMUM_INFLATE_WINDOW option, so #define it out when appropriate in\n    pngvalid.c\n  Allow unversioned links created on install to be disabled in configure.\n    In configure builds 'make install' changes/adds links like png.h\n    and libpng.a to point to the newly installed, versioned, files (e.g.\n    libpng17/png.h and libpng17.a). Three new configure options and some\n    rearrangement of Makefile.am allow creation of these links to be disabled.\n\nVersion 1.6.9beta03 [January 10, 2014]\n  Removed potentially misleading warning from png_check_IHDR().\n\nVersion 1.6.9beta04 [January 20, 2014]\n  Updated scripts/makefile.* to use CPPFLAGS (Cosmin).\n  Added clang attribute support (Cosmin).\n\nVersion 1.6.9rc01 [January 28, 2014]\n  No changes.\n\nVersion 1.6.9rc02 [January 30, 2014]\n  Quiet an uninitialized memory warning from VC2013 in png_get_png().\n\nVersion 1.6.9 [February 6, 2014]\n\nVersion 1.6.10beta01 [February 9, 2014]\n  Backported changes from libpng-1.7.0beta30 and beta31:\n  Fixed a large number of instances where PNGCBAPI was omitted from\n    function definitions.\n  Added pngimage test program for png_read_png() and png_write_png()\n    with two new test scripts.\n  Removed dependence on !PNG_READ_EXPAND_SUPPORTED for calling\n    png_set_packing() in png_read_png().\n  Fixed combination of ~alpha with shift. On read invert alpha, processing\n    occurred after shift processing, which causes the final values to be\n    outside the range that should be produced by the shift. Reversing the\n    order on read makes the two transforms work together correctly and mirrors\n    the order used on write.\n  Do not read invalid sBIT chunks. Previously libpng only checked sBIT\n    values on write, so a malicious PNG writer could therefore cause\n    the read code to return an invalid sBIT chunk, which might lead to\n    application errors or crashes.  Such chunks are now skipped (with\n    chunk_benign_error).\n  Make png_read_png() and png_write_png() prototypes in png.h depend\n    upon PNG_READ_SUPPORTED and PNG_WRITE_SUPPORTED.\n  Support builds with unsupported PNG_TRANSFORM_* values.  All of the\n    PNG_TRANSFORM_* values are always defined in png.h and, because they\n    are used for both read and write in some cases, it is not reliable\n    to #if out ones that are totally unsupported. This change adds error\n    detection in png_read_image() and png_write_image() to do a\n    png_app_error() if the app requests something that cannot be done\n    and it adds corresponding code to pngimage.c to handle such options\n    by not attempting to test them.\n\nVersion 1.6.10beta02 [February 23, 2014]\n  Moved redefines of png_error(), png_warning(), png_chunk_error(),\n    and png_chunk_warning() from pngpriv.h to png.h to make them visible\n    to libpng-calling applications.\n  Moved OS dependent code from arm/arm_init.c, to allow the included\n    implementation of the ARM NEON discovery function to be set at\n    build-time and provide sample implementations from the current code in the\n    contrib/arm-neon subdirectory. The __linux__ code has also been changed to\n    compile and link on Android by using /proc/cpuinfo, and the old linux code\n    is in contrib/arm-neon/linux-auxv.c.  The new code avoids POSIX and Linux\n    dependencies apart from opening /proc/cpuinfo and is C90 compliant.\n  Check for info_ptr == NULL early in png_read_end() so we don't need to\n    run all the png_handle_*() and depend on them to return if info_ptr == NULL.\n    This improves the performance of png_read_end(png_ptr, NULL) and makes\n    it more robust against future programming errors.\n  Check for __has_extension before using it in pngconf.h, to\n    support older Clang versions (Jeremy Sequoia).\n  Treat CRC error handling with png_set_crc_action(), instead of with\n    png_set_benign_errors(), which has been the case since libpng-1.6.0beta18.\n  Use a user warning handler in contrib/gregbook/readpng2.c instead of default,\n    so warnings will be put on stderr even if libpng has CONSOLE_IO disabled.\n  Added png_ptr->process_mode = PNG_READ_IDAT_MODE in png_push_read_chunk\n    after recognizing the IDAT chunk, which avoids an infinite loop while\n    reading a datastream whose first IDAT chunk is of zero-length.\n    This fixes CERT VU#684412 and CVE-2014-0333.\n  Don't recognize known sRGB profiles as sRGB if they have been hacked,\n    but don't reject them and don't issue a copyright violation warning.\n\nVersion 1.6.10beta03 [February 25, 2014]\n  Moved some documentation from png.h to libpng.3 and libpng-manual.txt\n  Minor editing of contrib/arm-neon/README and contrib/examples/*.c\n\nVersion 1.6.10rc01 [February 27, 2014]\n  Fixed typos in the manual and in scripts/pnglibconf.dfa (CFLAGS -> CPPFLAGS\n    and PNG_USR_CONFIG -> PNG_USER_CONFIG).\n\nVersion 1.6.10rc02 [February 28, 2014]\n  Removed unreachable return statement after png_chunk_error()\n    in pngrutil.c\n\nVersion 1.6.10rc03 [March 4, 2014]\n  Un-deprecated png_data_freer().\n\nVersion 1.6.10 [March 6, 2014]\n  No changes.\n\nVersion 1.6.11beta01 [March 17, 2014]\n  Use \"if (value != 0)\" instead of \"if (value)\" consistently.\n  Changed ZlibSrcDir from 1.2.5 to 1.2.8 in projects/vstudio.\n  Moved configuration information from the manual to the INSTALL file.\n\nVersion 1.6.11beta02 [April 6, 2014]\n  Removed #if/#else/#endif from inside two pow() calls in pngvalid.c because\n    they were handled improperly by Portland Group's PGI-14.1 - PGI-14.3\n    when using its \"__builtin_pow()\" function.\n  Silence 'unused parameter' build warnings (Cosmin Truta).\n  $(CP) is now used alongside $(RM_F).  Also, use 'copy' instead of 'cp'\n    where applicable, and applied other minor makefile changes (Cosmin).\n  Don't warn about invalid dimensions exceeding user limits (Cosmin).\n  Allow an easy replacement of the default pre-built configuration\n    header with a custom header, via the make PNGLIBCONF_H_PREBUILT\n    macro (Cosmin).\n\nVersion 1.6.11beta03 [April 6, 2014]\n  Fixed a typo in pngrutil.c, introduced in libpng-1.5.6, that interferes\n    with \"blocky\" expansion of sub-8-bit interlaced PNG files (Eric Huss).\n  Optionally use  __builtin_bswap16() in png_do_swap().\n\nVersion 1.6.11beta04 [April 19, 2014]\n  Made progressive reading of interlaced images consistent with the\n    behavior of the sequential reader and consistent with the manual, by\n    moving some code out of the PNG_READ_INTERLACING_SUPPORTED blocks. The\n    row_callback now receives the proper pass number and unexpanded rows, when\n    png_combine_row() isn't built or used, and png_set_interlace_handling()\n    is not called.\n  Allow PNG_sRGB_PROFILE_CHECKING = (-1) to mean no sRGB profile checking.\n\nVersion 1.6.11beta05 [April 26, 2014]\n  Do not reject ICC V2 profiles that lack padding (Kai-Uwe Behrmann).\n  Relocated closing bracket of the sRGB profile test loop to avoid getting\n    \"Not recognizing known sRGB profile that has been edited\" warning for\n    ICC V2 profiles that lack the MD5 signature in the profile header.\n\nVersion 1.6.11beta06 [May 19, 2014]\n  Added PNG_SKIP_sRGB_CHECK_PROFILE choice for png_set_option().\n\nVersion 1.6.11rc01 [May 27, 2014]\n  No changes.\n\nVersion 1.6.11rc02 [June 3, 2014]\n  Test ZLIB_VERNUM instead of PNG_ZLIB_VERNUM in contrib/tools/pngfix.c\n\nVersion 1.6.11 [June 5, 2014]\n  No changes.\n\nVersion 1.6.12rc01 [June 6, 2014]\n  Relocated new code from 1.6.11beta06 in png.c to a point after the\n    declarations (Max Stepin).\n\nVersion 1.6.12rc02 [June 7, 2014]\n  Changed file permissions of contrib/tools/intgamma.sh,\n    test-driver, and compile from 0644 to 0755 (Cosmin).\n\nVersion 1.6.12rc03 [June 8, 2014]\n  Ensure \"__has_attribute()\" macro exists before trying to use it with\n    old clang compilers (MacPorts Ticket #43939).\n\nVersion 1.6.12 [June 12, 2014]\n  No changes.\n\nVersion 1.6.13beta01 [July 4, 2014]\n  Quieted -Wsign-compare and -Wclobber compiler warnings in\n    contrib/pngminus/*.c\n  Added \"(void) png_ptr;\" where needed in contrib/gregbook to quiet\n    compiler complaints about unused pointers.\n  Split a long output string in contrib/gregbook/rpng2-x.c.\n  Added \"PNG_SET_OPTION\" requirement for sRGB chunk support to pnglibconf.dfa,\n    Needed for write-only support (John Bowler).\n  Changed \"if defined(__ARM_NEON__)\" to\n    \"if (defined(__ARM_NEON__) || defined(__ARM_NEON))\" (James Wu).\n  Fixed clang no-warning builds: png_digit was defined but never used.\n    \nVersion 1.6.13beta02 [July 21, 2014]\n  Fixed an incorrect separator (\"/\" should be \"\\\") in scripts/makefile.vcwin32\n    (bug report from Wolfgang S. Kechel).  Bug was introduced in libpng-1.6.11.\n    Also fixed makefile.bc32, makefile.bor, makefile.msc, makefile.intel, and\n    makefile.tc3 similarly.\n\nVersion 1.6.13beta03 [August 3, 2014]\n  Removed scripts/makefile.elf. It has not worked since libpng-1.5.0beta14\n    due to elimination of the PNG_FUNCTION_EXPORT and PNG_DATA_EXPORT\n    definitions from pngconf.h.\n  Ensure that CMakeLists.txt makes the target \"lib\" directory before making\n    symbolic link into it (SourceForge bug report #226 by Rolf Timmermans).\n\nVersion 1.6.13beta04 [August 8, 2014]\n  Added opinion that the ECCN (Export Control Classification Number) for\n    libpng is EAR99 to the README file.\n  Eliminated use of \"$<\" in makefile explicit rules, when copying\n    $PNGLIBCONF_H_PREBUILT.  This does not work on some versions of make;\n    bug introduced in libpng version 1.6.11.\n\nVersion 1.6.13rc01 [August 14, 2014]\n  Made \"ccopts\" agree with \"CFLAGS\" in scripts/makefile.hp* and makefile.*sunu\n\nVersion 1.6.13 [August 21, 2014]\n  No changes.\n\nVersion 1.6.14beta01 [September 14, 2014]\n  Guard usage of png_ptr->options with #ifdef PNG_SET_OPTION_SUPPORTED.\n  Do not build contrib/tools/pngfix.c when PNG_SETJMP_NOT_SUPPORTED,\n    to allow \"make\" to complete without setjmp support (bug report by\n    Claudio Fontana)\n  Add \"#include <setjmp.h>\" to contrib/tools/pngfix.c (John Bowler)\n\nVersion 1.6.14beta02 [September 18, 2014]\n  Use nanosleep() instead of usleep() in contrib/gregbook/rpng2-x.c\n    because usleep() is deprecated.\n  Define usleep() in contrib/gregbook/rpng2-x.c if not already defined\n    in unistd.h and nanosleep() is not available; fixes error introduced\n    in libpng-1.6.13.\n  Disable floating point exception handling in pngvalid.c when\n    PNG_FLOATING_ARITHMETIC is not supported (bug report by \"zootus\n    at users.sourceforge.net\").\n\nVersion 1.6.14beta03 [September 19, 2014]\n  Define FE_DIVBYZERO, FE_INVALID, and FE_OVERFLOW in pngvalid.c if not\n    already defined.  Revert floating point exception handling in pngvalid.c\n    to version 1.6.14beta01 behavior.\n\nVersion 1.6.14beta04 [September 27, 2014]\n  Fixed incorrect handling of the iTXt compression flag in pngrutil.c\n    (bug report by Shunsaku Hirata).  Bug was introduced in libpng-1.6.0.\n\nVersion 1.6.14beta05 [October 1, 2014]\n  Added \"option READ_iCCP enables READ_COMPRESSED_TEXT\" to pnglibconf.dfa\n\nVersion 1.6.14beta06 [October 5, 2014]\n  Removed unused \"text_len\" parameter from private function png_write_zTXt().\n  Conditionally compile some code in png_deflate_claim(), when\n    PNG_WARNINGS_SUPPORTED and PNG_ERROR_TEXT_SUPPORTED are disabled.\n  Replaced repeated code in pngpread.c with PNG_PUSH_SAVE_BUFFER_IF_FULL.\n  Added \"chunk iTXt enables TEXT\" and \"chunk zTXt enables TEXT\"\n    to pnglibconf.dfa.\n  Removed \"option READ_COMPRESSED_TEXT enables READ_TEXT\" from pnglibconf.dfa,\n    to make it possible to configure a libpng that supports iCCP but not TEXT.\n\nVersion 1.6.14beta07 [October 7, 2014]\n  Removed \"option WRITE_COMPRESSED_TEXT enables WRITE_TEXT\" from pnglibconf.dfa\n  Only mark text chunks as written after successfully writing them.\n\nVersion 1.6.14rc01 [October 15, 2014]\n  Fixed some typos in comments.\n\nVersion 1.6.14rc02 [October 17, 2014]\n  Changed png_convert_to_rfc_1123() to png_convert_to_rfc_1123_buffer()\n    in the manual, to reflect the change made in libpng-1.6.0.\n  Updated README file to explain that direct access to the png_struct\n    and info_struct members has not been permitted since libpng-1.5.0.\n\nVersion 1.6.14 [October 23, 2014]\n  No changes.\n\nVersion 1.6.15beta01 [October 29, 2014]\n  Changed \"if (!x)\" to \"if (x == 0)\" and \"if (x)\" to \"if (x != 0)\"\n  Simplified png_free_data().\n  Added missing \"ptr = NULL\" after some instances of png_free().\n\nVersion 1.6.15beta02 [November 1, 2014]\n  Changed remaining \"if (!x)\" to \"if (x == 0)\" and \"if (x)\" to \"if (x != 0)\"\n\nVersion 1.6.15beta03 [November 3, 2014]\n  Added PNG_USE_ARM_NEON configuration flag (Marcin Juszkiewicz).\n\nVersion 1.6.15beta04 [November 4, 2014]\n  Removed new PNG_USE_ARM_NEON configuration flag and made a one-line\n    revision to configure.ac to support ARM on aarch64 instead (John Bowler).\n\nVersion 1.6.15beta05 [November 5, 2014]\n  Use png_get_libpng_ver(NULL) instead of PNG_LIBPNG_VER_STRING in\n    example.c, pngtest.c, and applications in the contrib directory.\n  Avoid out-of-bounds memory access in png_user_version_check().\n  Simplified and future-proofed png_user_version_check().\n  Fixed GCC unsigned int->float warnings. Various versions of GCC\n    seem to generate warnings when an unsigned value is implicitly\n    converted to double. This is probably a GCC bug but this change\n    avoids the issue by explicitly converting to (int) where safe.\n  Free all allocated memory in pngimage. The file buffer cache was left\n    allocated at the end of the program, harmless but it causes memory\n    leak reports from clang.\n  Fixed array size calculations to avoid warnings. At various points\n    in the code the number of elements in an array is calculated using\n    sizeof.  This generates a compile time constant of type (size_t) which\n    is then typically assigned to an (unsigned int) or (int). Some versions\n    of GCC on 64-bit systems warn about the apparent narrowing, even though\n    the same compiler does apparently generate the correct, in-range,\n    numeric constant.  This adds appropriate, safe, casts to make the\n    warnings go away.\n\nVersion 1.6.15beta06 [November 6, 2014]\n  Reverted use png_get_libpng_ver(NULL) instead of PNG_LIBPNG_VER_STRING\n    in the manual, example.c, pngtest.c, and applications in the contrib\n    directory.  It was incorrect advice.\n\nVersion 1.6.15beta07 [November 7, 2014]\n  Removed #ifdef PNG_16BIT_SUPPORTED/#endif around png_product2(); it is\n    needed by png_reciprocal2().\n  Added #ifdef PNG_16BIT_SUPPORTED/#endif around png_log16bit() and\n    png_do_swap().\n  Changed all \"#endif /* PNG_FEATURE_SUPPORTED */\" to \"#endif /* FEATURE */\"\n\nVersion 1.6.15beta08 [November 8, 2014]\n  More housecleaning in *.h\n\nVersion 1.6.15rc01 [November 13, 2014]\n\nVersion 1.6.15rc02 [November 14, 2014]\n  The macros passed in the command line to Borland make were ignored if\n    similarly-named macros were already defined in makefiles. This behavior\n    is different from POSIX make and other make programs.  Surround the\n    macro definitions with ifndef guards (Cosmin).\n\nVersion 1.6.15rc03 [November 16, 2014]\n  Added \"-D_CRT_SECURE_NO_WARNINGS\" to CFLAGS in scripts/makefile.vcwin32.\n  Removed the obsolete $ARCH variable from scripts/makefile.darwin.\n\nVersion 1.6.15 [November 20, 2014]\n  No changes.\n\nVersion 1.6.16beta01 [December 14, 2014]\n  Added \".align 2\" to arm/filter_neon.S to support old GAS assemblers that\n    don't do alignment correctly.\n  Revised Makefile.am and scripts/symbols.dfn to work with MinGW/MSYS\n    (Bob Friesenhahn).\n\nVersion 1.6.16beta02 [December 15, 2014]\n  Revised Makefile.am and scripts/*.dfn again to work with MinGW/MSYS;\n    renamed scripts/*.dfn to scripts/*.c (John Bowler).\n\nVersion 1.6.16beta03 [December 21, 2014]\n  Quiet a \"comparison always true\" warning in pngstest.c (John Bowler).\n\nVersion 1.6.16rc01 [December 21, 2014]\n  Restored a test on width that was removed from png.c at libpng-1.6.9\n    (Bug report by Alex Eubanks, CVE-2015-0973).\n\nVersion 1.6.16rc02 [December 21, 2014]\n  Undid the update to pngrutil.c in 1.6.16rc01.\n\nVersion 1.6.16rc03 [December 21, 2014]\n  Fixed an overflow in png_combine_row() with very wide interlaced images\n    (Bug report and fix by John Bowler, CVE-2014-9495).\n\nVersion 1.6.16 [December 22, 2014]\n  No changes.\n\nVersion 1.6.17beta01 [January 29, 2015]\n  Removed duplicate PNG_SAFE_LIMITS_SUPPORTED handling from pngconf.h\n  Corrected the width limit calculation in png_check_IHDR().\n  Removed user limits from pngfix. Also pass NULL pointers to\n    png_read_row to skip the unnecessary row de-interlace stuff.\n  Added testing of png_set_packing() to pngvalid.c\n  Regenerated configure scripts in the *.tar distributions with libtool-2.4.4\n  Implement previously untested cases of libpng transforms in pngvalid.c\n  Fixed byte order in png_do_read_filler() with 16-bit input. Previously\n    the high and low bytes of the filler, from png_set_filler() or from\n    png_set_add_alpha(), were read in the wrong order.\n  Made the check for out-of-range values in png_set_tRNS() detect\n    values that are exactly 2^bit_depth, and work on 16-bit platforms.\n  Merged some parts of libpng-1.6.17beta01 and libpng-1.7.0beta47.\n  Added #ifndef __COVERITY__ where needed in png.c, pngrutil.c and\n    pngset.c to avoid warnings about dead code.\n  Added \"& 0xff\" to many instances of expressions that are typecast\n    to (png_byte), to avoid Coverity warnings.\n\nVersion 1.6.17beta02 [February 7, 2015]\n  Work around one more Coverity-scan dead-code warning.\n  Do not build png_product2() when it is unused.\n\nVersion 1.6.17beta03 [February 17, 2015]\n  Display user limits in the output from pngtest.\n  Eliminated the PNG_SAFE_LIMITS macro and restored the 1-million-column\n    and 1-million-row default limits in pnglibconf.dfa, that can be reset\n    by the user at build time or run time.  This provides a more robust\n    defense against DOS and as-yet undiscovered overflows.\n\nVersion 1.6.17beta04 [February 21, 2015]\n  Added PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED macro, on by default.\n  Allow user to call png_get_IHDR() with NULL arguments (Reuben Hawkins).\n  Rebuilt configure scripts with automake-1.15 and libtool-2.4.6\n\nVersion 1.6.17beta05 [February 25, 2015]\n  Restored compiling of png_reciprocal2 with PNG_NO_16BIT.\n\nVersion 1.6.17beta06 [February 27, 2015]\n  Moved png_set_filter() prototype into a PNG_WRITE_SUPPORTED block\n    of png.h.\n  Avoid runtime checks when converting integer to png_byte with\n    Visual Studio (Sergey Kosarevsky)\n\nVersion 1.6.17rc01 [March 4, 2015]\n  No changes.\n\nVersion 1.6.17rc02 [March 9, 2015]\n  Removed some comments that the configure script did not handle\n    properly from scripts/pnglibconf.dfa and pnglibconf.h.prebuilt.\n  Free the unknown_chunks structure even when it contains no data.\n\nVersion 1.6.17rc03 [March 12, 2015]\n  Updated CMakeLists.txt to add OSX framework, change YES/NO to ON/OFF\n    for consistency, and remove some useless tests (Alexey Petruchik).\n\nVersion 1.6.17rc04 [March 16, 2015]\n  Remove pnglibconf.h, pnglibconf.c, and pnglibconf.out instead of\n    pnglibconf.* in \"make clean\" (Cosmin).\n  Fix bug in calculation of maxbits, in png_write_sBIT, introduced\n    in libpng-1.6.17beta01 (John Bowler).\n\nVersion 1.6.17rc05 [March 21, 2015]\n  Define PNG_FILTER_* and PNG_FILTER_VALUE_* in png.h even when WRITE\n    is not supported (John Bowler).  This fixes an error introduced in\n    libpng-1.6.17beta06.\n  Reverted \"& 0xff\" additions of version 1.6.17beta01. Libpng passes\n    the Coverity scan without them.\n\nVersion 1.6.17rc06 [March 23, 2015]\n  Remove pnglibconf.dfn and pnglibconf.pre with \"make clean\".\n  Reformatted some \"&0xff\" instances to \"& 0xff\".\n  Fixed simplified 8-bit-linear to sRGB alpha. The calculated alpha\n    value was wrong.  It's not clear if this affected the final stored\n    value; in the obvious code path the upper and lower 8-bits of the\n    alpha value were identical and the alpha was truncated to 8-bits\n    rather than dividing by 257 (John Bowler).\n\nVersion 1.6.17 [March 26, 2015]\n  No changes.\n\nVersion 1.6.18beta01 [April 1, 2015]\n  Removed PNG_SET_CHUNK_[CACHE|MALLOC]_LIMIT_SUPPORTED macros.  They\n    have been combined with PNG_SET_USER_LIMITS_SUPPORTED (resolves\n    bug report by Andrew Church).\n  Fixed rgb_to_gray checks and added tRNS checks to pngvalid.c.  This\n    fixes some arithmetic errors that caused some tests to fail on\n    some 32-bit platforms (Bug reports by Peter Breitenlohner [i686]\n    and Petr Gajdos [i586]).\n\nVersion 1.6.18beta02 [April 26, 2015]\n  Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler\n    (Bug report by Viktor Szakats).\n\nVersion 1.6.18beta03 [May 6, 2015]\n  Replaced \"unexpected\" with an integer (0xabadca11) in pngset.c\n    where a long was expected, to avoid a compiler warning when PNG_DEBUG > 1.\n  Added contrib/examples/simpleover.c, to demonstrate how to handle\n    alpha compositing of multiple images, using the \"simplified API\"\n    and an example PNG generation tool, contrib/examples/genpng.c\n    (John Bowler).\n\nVersion 1.6.18beta04 [May 20, 2015]\n  PNG_RELEASE_BUILD replaces tests where the code depended on the build base\n    type and can be defined on the command line, allowing testing in beta\n    builds (John Bowler).\n  Avoid Coverity issue 80858 (REVERSE NULL) in pngtest.c PNG_DEBUG builds.\n  Avoid a harmless potential integer overflow in png_XYZ_from_xy() (Bug\n    report from Christopher Ferris).\n\nVersion 1.6.18beta05 [May 31, 2015]\n  Backport filter selection code from libpng-1.7.0beta51, to combine\n    sub_row, up_row, avg_row, and paeth_row into try_row and tst_row.\n  Changed png_voidcast(), etc., to voidcast(), etc., in contrib/tools/pngfix.c\n    to avoid confusion with the libpng private macros.\n  Fixed old cut&paste bug in the weighted filter selection code in\n    pngwutil.c, introduced in libpng-0.95, March 1997.\n\nVersion 1.6.18beta06 [June 1, 2015]\n  Removed WRITE_WEIGHTED_FILTERED code, to save a few kbytes of the\n    compiled library size. It never worked properly and as far as we can\n    tell, no one uses it. The png_set_filter_heuristics() and\n    png_set_filter_heuristics_fixed() APIs are retained but deprecated\n    and do nothing.\n\nVersion 1.6.18beta07 [June 6, 2015]\n  Removed non-working progressive reader 'skip' function. This\n    function has apparently never been used. It was implemented\n    to support back-door modification of png_struct in libpng-1.4.x\n    but (because it does nothing and cannot do anything) was apparently\n    never tested (John Bowler).\n  Fixed cexcept.h in which GCC 5 now reports that one of the auto\n    variables in the Try macro needs to be volatile to prevent value\n    being lost over the setjmp (John Bowler).\n  Fixed NO_WRITE_FILTER and -Wconversion build breaks (John Bowler).\n  Fix g++ build breaks (John Bowler).\n  Quieted some Coverity issues in pngfix.c, png-fix-itxt.c, pngvalid.c,\n    pngstest.c, and pngimage.c. Most seem harmless, but png-fix-itxt\n    would only work with iTXt chunks with length 255 or less.\n  Added #ifdef's to contrib/examples programs so people don't try\n    to compile them without the minimum required support enabled\n    (suggested by Flavio Medeiros).\n\nVersion 1.6.18beta08 [June 30, 2015]\n  Eliminated the final two Coverity defects (insecure temporary file\n    handling in contrib/libtests/pngstest.c; possible overflow of\n    unsigned char in contrib/tools/png-fix-itxt.c). To use the \"secure\"\n    file handling, define PNG_USE_MKSTEMP, otherwise \"tmpfile()\" will\n    be used.\n  Removed some unused WEIGHTED_FILTER macros from png.h and pngstruct.h\n\nVersion 1.6.18beta09 [July 5, 2015]\n  Removed some useless typecasts from contrib/tools/png-fix-itxt.c\n  Fixed a new signed-unsigned comparison in pngrtran.c (Max Stepin).\n  Replaced arbitrary use of 'extern' with #define PNG_LINKAGE_*.  To\n    preserve API compatibility, the new defines all default to \"extern\"\n    (requested by Jan Nijtmans).\n\nVersion 1.6.18rc01 [July 9, 2015]\n  Belatedly added Mans Rullgard and James Yu to the list of Contributing\n    Authors.\n\nVersion 1.6.18rc02 [July 12, 2015]\n  Restored unused FILTER_HEURISTIC macros removed at libpng-1.6.18beta08\n    to png.h to avoid compatibility warnings.\n\nVersion 1.6.18rc03 [July 15, 2015]\n  Minor changes to the man page\n\nVersion 1.6.18 [July 23, 2015]\n  No changes.\n\nVersion 1.6.19beta01 [July 30, 2015]\n  Updated obsolete information about the simplified API macros in the\n    manual pages (Bug report by Arc Riley).\n  Avoid potentially dereferencing NULL info_ptr in png_info_init_3().\n  Rearranged png.h to put the major sections in the same order as\n    in libpng17.\n  Eliminated unused PNG_COST_SHIFT, PNG_WEIGHT_SHIFT, PNG_COST_FACTOR, and\n    PNG_WEIGHT_FACTOR macros.\n  Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler\n    (Bug report by Viktor Szakats).  Several warnings remain and are\n    unavoidable, where we test for overflow.\n  Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c\n  Fixed uninitialized variable in contrib/gregbook/rpng2-x.c\n\nVersion 1.6.19beta02 [August 19, 2015]\n  Moved config.h.in~ from the \"libpng_autotools_files\" list to the\n    \"libpng_autotools_extra\" list in autogen.sh because it was causing a\n    false positive for missing files (bug report by Robert C. Seacord).\n  Removed unreachable \"break\" statements in png.c, pngread.c, and pngrtran.c\n    to suppress clang warnings (Bug report by Viktor Szakats).\n  Fixed some bad links in the man page.\n  Changed \"n bit\" to \"n-bit\" in comments.\n  Added signed/unsigned 16-bit safety net. This removes the dubious\n    0x8000 flag definitions on 16-bit systems. They aren't supported\n    yet the defs *probably* work, however it seems much safer to do this\n    and be advised if anyone, contrary to advice, is building libpng 1.6\n    on a 16-bit system. It also adds back various switch default clauses\n    for GCC; GCC errors out if they are not present (with an appropriately\n    high level of warnings).\n  Safely convert num_bytes to a png_byte in png_set_sig_bytes() (Robert\n    Seacord).\n  Fixed the recently reported 1's complement security issue by replacing\n    the value that is illegal in the PNG spec, in both signed and unsigned\n    values, with 0. Illegal unsigned values (anything greater than or equal\n    to  0x80000000) can still pass through, but since these are not illegal\n    in ANSI-C (unlike 0x80000000 in the signed case) the checking that\n    occurs later can catch them (John Bowler).\n\nVersion 1.6.19beta03 [September 26, 2015]\n  Fixed png_save_int_32 when int is not 2's complement (John Bowler).\n  Updated libpng16 with all the recent test changes from libpng17,\n    including changes to pngvalid.c to ensure that the original,\n    distributed, version of contrib/visupng/cexcept.h can be used\n    (John Bowler).\n  pngvalid contains the correction to the use of SAVE/STORE_\n    UNKNOWN_CHUNKS; a bug revealed by changes in libpng 1.7. More\n    tests contain the --strict option to detect warnings and the\n    pngvalid-standard test has been corrected so that it does not\n    turn on progressive-read. There is a separate test which does\n    that. (John Bowler)\n  Also made some signed/unsigned fixes.\n  Make pngstest error limits version specific. Splitting the machine\n    generated error structs out to a file allows the values to be updated\n    without changing pngstest.c itself. Since libpng 1.6 and 1.7 have\n    slightly different error limits this simplifies maintenance. The\n    makepngs.sh script has also been updated to more accurately reflect\n    current problems in libpng 1.7 (John Bowler).\n  Incorporated new test PNG files into make check.  tests/pngstest-*\n    are changed so that the new test files are divided into 8 groups by\n    gamma and alpha channel.  These tests have considerably better code\n    and pixel-value coverage than contrib/pngsuite; however,coverage is\n    still incomplete (John Bowler).\n  Removed the '--strict' in 1.6 because of the double-gamma-correction\n    warning, updated pngstest-errors.h for the errors detected with the\n    new contrib/testspngs PNG test files (John Bowler).\n\nVersion 1.6.19beta04 [October 15, 2015]\n  Worked around rgb-to-gray issues in libpng 1.6.  The previous\n    attempts to ignore the errors in the code aren't quite enough to\n    deal with the 'channel selection' encoding added to libpng 1.7; abort.\n    pngvalid.c is changed to drop this encoding in prior versions.\n  Fixed 'pow' macros in pngvalid.c. It is legal for 'pow' to be a\n    macro, therefore the argument list cannot contain preprocessing\n    directives.  Make sure pow is a function where this happens. This is\n    a minimal safe fix, the issue only arises in non-performance-critical\n    code (bug report by Curtis Leach, fix by John Bowler).\n  Added sPLT support to pngtest.c\n\nVersion 1.6.19rc01 [October 23, 2015]\n  No changes.\n\nVersion 1.6.19rc02 [October 31, 2015]\n  Prevent setting or writing over-length PLTE chunk (Cosmin Truta).\n  Silently truncate over-length PLTE chunk while reading.\n  Libpng incorrectly calculated the output rowbytes when the application\n    decreased either the number of channels or the bit depth (or both) in\n    a user transform.  This was safe; libpng overallocated buffer space\n   (potentially by quite a lot; up to 4 times the amount required) but,\n   from 1.5.4 on, resulted in a png_error (John Bowler).\n\nVersion 1.6.19rc03 [November 3, 2015]\n  Fixed some inconsequential cut-and-paste typos in png_set_cHRM_XYZ_fixed().\n  Clarified COPYRIGHT information to state explicitly that versions\n    are derived from previous versions.\n  Removed much of the long list of previous versions from png.h and\n    libpng.3.\n\nVersion 1.6.19rc04 [November 5, 2015]\n  Fixed new bug with CRC error after reading an over-length palette\n    (bug report by Cosmin Truta) (CVE-2015-8126).\n\nVersion 1.6.19 [November 12, 2015]\n  Cleaned up coding style in png_handle_PLTE().\n\nVersion 1.6.20beta01 [November 20, 2015]\n  Avoid potential pointer overflow/underflow in png_handle_sPLT() and\n    png_handle_pCAL() (Bug report by John Regehr).\n\nVersion 1.6.20beta02 [November 23, 2015]\n  Fixed incorrect implementation of png_set_PLTE() that uses png_ptr\n    not info_ptr, that left png_set_PLTE() open to the CVE-2015-8126\n    vulnerability.  Fixes CVE-2015-8472.\n\nVersion 1.6.20beta03 [November 24, 2015]\n  Backported tests from libpng-1.7.0beta69.\n\nVersion 1.6.20rc01 [November 26, 2015]\n  Fixed an error in handling of bad zlib CMINFO field in pngfix, found by\n    American Fuzzy Lop, reported by Brian Carpenter.  inflate() doesn't\n    immediately fault a bad CMINFO field; instead a 'too far back' error\n    happens later (at least some times).  pngfix failed to limit CMINFO to\n    the allowed values but then assumed that window_bits was in range,\n    triggering an assert. The bug is mostly harmless; the PNG file cannot\n    be fixed.\n\nVersion 1.6.20rc02 [November 29, 2015]\n  In libpng 1.6 zlib initialization was changed to use the window size\n    in the zlib stream, not a fixed value. This causes some invalid images,\n    where CINFO is too large, to display 'correctly' if the rest of the\n    data is valid.  This provides a workaround for zlib versions where the\n    error arises (ones that support the API change to use the window size\n    in the stream).\n\nVersion 1.6.20 [December 3, 2015]\n  No changes.\n\nVersion 1.6.21beta01 [December 11, 2015]\n  Fixed syntax \"$(command)\" in tests/pngstest that some shells other than\n    bash could not parse (Bug report by Nelson Beebe). Use `command` instead.\n\nVersion 1.6.21beta02 [December 14, 2015]\n  Moved png_check_keyword() from pngwutil.c to pngset.c\n  Removed LE/BE dependencies in pngvalid, to 'fix' the current problem\n    in the BigEndian tests by not testing it, making the BE code the same \n    as the LE version.\n  Fixes to pngvalid for various reduced build configurations (eliminate unused\n    statics) and a fix for the case in rgb_to_gray when the digitize option\n    reduces graylo to 0, producing a large error.\n\nVersion 1.6.21beta03 [December 18, 2015]\n  Widened the 'limit' check on the internally calculated error limits in\n    the 'DIGITIZE' case (the code used prior to 1.7 for rgb_to_gray error\n    checks) and changed the check to only operate in non-release builds\n    (base build type not RC or RELEASE.)\n  Fixed undefined behavior in pngvalid.c, undefined because\n    (png_byte) << shift is undefined if it changes the signed bit\n    (because png_byte is promoted to int). The libpng exported functions\n    png_get_uint_32 and png_get_uint_16 handle this. (Bug reported by\n    David Drysdale as a result of reports from UBSAN in clang 3.8).\n  This changes pngvalid to use BE random numbers; this used to produce\n    errors but these should not be fixed as a result of the previous changes.\n\nVersion 1.6.21rc01 [January 4, 2016]\n  In projects/vstudio, combined readme.txt and WARNING into README.txt\n\nVersion 1.6.21rc02 [January 7, 2016]\n  Relocated assert() in contrib/tools/pngfix.c, bug found by American\n    Fuzzy Lop, reported by Brian Carpenter.\n  Marked 'limit' UNUSED in transform_range_check().  This only affects\n    release builds.\n\nVersion 1.6.21 [January 15, 2016]\n  Worked around a false-positive Coverity issue in pngvalid.c.\n\nVersion 1.6.22beta01 [January 23, 2016]\n  Changed PNG_USE_MKSTEMP to __COVERITY__ to select alternate\n    \"tmpfile()\" implementation in contrib/libtests/pngstest.c\n  Fixed NO_STDIO build of pngunknown.c to skip calling png_init_io()\n    if there is no stdio.h support.\n  Added a png_image_write_to_memory() API and a number of assist macros\n    to allow an application that uses the simplified API write to bypass\n    stdio and write directly to memory.\n  Added some warnings (png.h) and some check code to detect *possible*\n    overflow in the ROW_STRIDE and simplified image SIZE macros.  This\n    disallows image width/height/format that *might* overflow.  This is\n    a quiet API change that limits in-memory image size (uncompressed) to\n    less than 4GByte and image row size (stride) to less than 2GByte.\n  Revised workaround for false-positive Coverity issue in pngvalid.c.\n\nVersion 1.6.22beta02 [February 8, 2016]\n  Only use exit(77) in configure builds.\n  Corrected error in PNG_IMAGE_PNG_SIZE_MAX. This new macro underreported\n    the palette size because it failed to take into account that the memory\n    palette has to be expanded to full RGB when it is written to PNG.\n  Updated CMakeLists.txt, added supporting scripts/gen*.cmake.in\n    and test.cmake.in (Roger Leigh).\n  Relaxed limit checks on gamma values in pngrtran.c. As suggested in\n    the comments gamma values outside the range currently permitted\n    by png_set_alpha_mode are useful for HDR data encoding.  These values\n    are already permitted by png_set_gamma so it is reasonable caution to\n    extend the png_set_alpha_mode range as HDR imaging systems are starting\n    to emerge.\n\nVersion 1.6.22beta03 [February 19, 2016]\n  Added a common-law trademark notice and export control information\n    to the LICENSE file, png.h, and the man page.\n  Restored \"& 0xff\" in png_save_uint_16() and png_save_uint_32() that\n    were accidentally removed from libpng-1.6.17. \n  Changed PNG_INFO_cHNK and PNG_FREE_cHNK from 0xnnnn to 0xnnnnU in png.h\n    (Robert C. Seacord).\n  Removed dubious \"#if INT_MAX\" test from png.h that was added to\n    libpng-1.6.19beta02 (John Bowler).\n  Add ${INCLUDES} in scripts/genout.cmake.in (Bug report by Nixon Kwok).\n  Updated LICENSE to say files in the contrib directory are not\n    necessarily under the libpng license, and that some makefiles have\n    other copyright owners.\n\nSend comments/corrections/commendations to png-mng-implement at lists.sf.net\n(subscription required; visit\nhttps://lists.sourceforge.net/lists/listinfo/png-mng-implement\nto subscribe)\nor to glennrp at users.sourceforge.net\n\nGlenn R-P\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/libpng/CMakeLists.txt",
    "content": "# CMakeLists.txt\n\n# Copyright (C) 2007,2009-2016 Glenn Randers-Pehrson\n# Written by Christian Ehrlicher, 2007\n# Revised by Roger Lowman, 2009-2010\n# Revised by Clifford Yapp, 2011-2012\n# Revised by Roger Leigh, 2016\n\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\ncmake_minimum_required(VERSION 2.8.3)\ncmake_policy(VERSION 2.8.3)\n\n# Set MacOSX @rpath usage globally.\nif (POLICY CMP0020)\n  cmake_policy(SET CMP0020 NEW)\nendif(POLICY CMP0020)\nif (POLICY CMP0042)\n  cmake_policy(SET CMP0042 NEW)\nendif(POLICY CMP0042)\n# Use new variable expansion policy.\nif (POLICY CMP0053)\n  cmake_policy(SET CMP0053 NEW)\nendif(POLICY CMP0053)\nif (POLICY CMP0054)\n  cmake_policy(SET CMP0054 NEW)\nendif(POLICY CMP0054)\n\nset(CMAKE_CONFIGURATION_TYPES \"Release;Debug;MinSizeRel;RelWithDebInfo\")\n\nproject(libpng C)\nenable_testing()\n\nset(PNGLIB_MAJOR 1)\nset(PNGLIB_MINOR 6)\nset(PNGLIB_RELEASE 22)\nset(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR})\nset(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE})\n\n# needed packages\nfind_package(ZLIB REQUIRED)\ninclude_directories(${ZLIB_INCLUDE_DIR})\n\nif(NOT WIN32)\n  find_library(M_LIBRARY\n    NAMES m\n    PATHS /usr/lib /usr/local/lib\n  )\n  if(NOT M_LIBRARY)\n    message(STATUS \"math lib 'libm' not found; floating point support disabled\")\n  endif()\nelse()\n  # not needed on windows\n  set(M_LIBRARY \"\")\nendif()\n\n# COMMAND LINE OPTIONS\noption(PNG_SHARED \"Build shared lib\" ON)\noption(PNG_STATIC \"Build static lib\" ON)\noption(PNG_TESTS  \"Build libpng tests\" ON)\n\n# Many more configuration options could be added here\noption(PNG_FRAMEWORK \"Build OS X framework\" OFF)\noption(PNG_DEBUG     \"Build with debug output\" OFF)\noption(PNGARG        \"Disable ANSI-C prototypes\" OFF)\n\nset(PNG_PREFIX \"\" CACHE STRING \"Prefix to add to the API function names\")\nset(DFA_XTRA \"\" CACHE FILEPATH \"File containing extra configuration settings\")\n\n# SET LIBNAME\nset(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR})\n\n# to distinguish between debug and release lib\nset(CMAKE_DEBUG_POSTFIX \"d\")\n\ninclude(CheckCSourceCompiles)\noption(ld-version-script \"Enable linker version script\" ON)\nif(ld-version-script AND NOT APPLE)\n  # Check if LD supports linker scripts.\n  file(WRITE \"${CMAKE_CURRENT_BINARY_DIR}/conftest.map\" \"VERS_1 {\n        global: sym;\n        local: *;\n};\n\nVERS_2 {\n        global: sym2;\n                main;\n} VERS_1;\n\")\n  set(CMAKE_REQUIRED_FLAGS_SAVE ${CMAKE_REQUIRED_FLAGS})\n  set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} \"-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/conftest.map'\")\n  check_c_source_compiles(\"void sym(void) {}\nvoid sym2(void) {}\nint main(void) {return 0;}\n\" HAVE_LD_VERSION_SCRIPT)\n  if(NOT HAVE_LD_VERSION_SCRIPT)\n    set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE} \"-Wl,-M -Wl,${CMAKE_CURRENT_BINARY_DIR}/conftest.map\")\n  check_c_source_compiles(\"void sym(void) {}\nvoid sym2(void) {}\nint main(void) {return 0;}\n\" HAVE_SOLARIS_LD_VERSION_SCRIPT)\n  endif()\n  set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE})\n  file(REMOVE \"${CMAKE_CURRENT_BINARY_DIR}/conftest.map\")\nendif()\n\n# Find symbol prefix.  Likely obsolete and unnecessary with recent\n# toolchains (it's not done in many other projects).\nfunction(symbol_prefix)\n  set(SYMBOL_PREFIX)\n\n  execute_process(COMMAND \"${CMAKE_C_COMPILER}\" \"-E\" \"-\"\n                  INPUT_FILE /dev/null\n                  OUTPUT_VARIABLE OUT\n                  RESULT_VARIABLE STATUS)\n\n  if(CPP_FAIL)\n    message(WARNING \"Failed to run the C preprocessor\")\n  endif()\n\n  string(REPLACE \"\\n\" \";\" OUT \"${OUT}\")\n  foreach(line ${OUT})\n    string(REGEX MATCH \"^PREFIX=\" found_match \"${line}\")\n    if(found_match)\n      STRING(REGEX REPLACE \"^PREFIX=(.*\\)\" \"\\\\1\" prefix \"${line}\")\n      string(REGEX MATCH \"__USER_LABEL_PREFIX__\" found_match \"${prefix}\")\n      if(found_match)\n        STRING(REGEX REPLACE \"(.*)__USER_LABEL_PREFIX__(.*)\" \"\\\\1\\\\2\" prefix \"${prefix}\")\n      endif()\n      set(SYMBOL_PREFIX \"${prefix}\")\n    endif()\n  endforeach()\n\n    message(STATUS \"Symbol prefix: ${SYMBOL_PREFIX}\")\n    set(SYMBOL_PREFIX \"${SYMBOL_PREFIX}\" PARENT_SCOPE)\nendfunction()\n\nif(UNIX)\n  symbol_prefix()\nendif()\n\nfind_program(AWK NAMES gawk awk)\n\ninclude_directories(${CMAKE_CURRENT_BINARY_DIR})\n\nif(NOT AWK)\n  # No awk available to generate sources; use pre-built pnglibconf.h\n  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt\n                 ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h)\n  add_custom_target(genfiles) # Dummy\nelse()\n  include(CMakeParseArguments)\n  # Generate .chk from .out with awk\n  # generate_chk(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]])\n  function(generate_chk)\n    set(options)\n    set(oneValueArgs INPUT OUTPUT)\n    set(multiValueArgs DEPENDS)\n    cmake_parse_arguments(_GC \"${options}\" \"${oneValueArgs}\" \"${multiValueArgs}\" ${ARGN})\n    if (NOT _GC_INPUT)\n      message(FATAL_ERROR \"Invalid arguments.  generate_out requires input.\")\n    endif()\n    if (NOT _GC_OUTPUT)\n      message(FATAL_ERROR \"Invalid arguments.  generate_out requires output.\")\n    endif()\n\n    add_custom_command(OUTPUT \"${_GC_OUTPUT}\"\n                       COMMAND \"${CMAKE_COMMAND}\"\n                               \"-DINPUT=${_GC_INPUT}\"\n                               \"-DOUTPUT=${_GC_OUTPUT}\"\n                               -P \"${CMAKE_CURRENT_BINARY_DIR}/scripts/genchk.cmake\"\n                       DEPENDS \"${_GC_INPUT}\" ${_GC_DEPENDS}\n                       WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")\n  endfunction()\n\n  # Generate .out from .c with awk\n  # generate_out(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]])\n  function(generate_out)\n    set(options)\n    set(oneValueArgs INPUT OUTPUT)\n    set(multiValueArgs DEPENDS)\n    cmake_parse_arguments(_GO \"${options}\" \"${oneValueArgs}\" \"${multiValueArgs}\" ${ARGN})\n    if (NOT _GO_INPUT)\n      message(FATAL_ERROR \"Invalid arguments.  generate_out requires input.\")\n    endif()\n    if (NOT _GO_OUTPUT)\n      message(FATAL_ERROR \"Invalid arguments.  generate_out requires output.\")\n    endif()\n\n    add_custom_command(OUTPUT \"${_GO_OUTPUT}\"\n                       COMMAND \"${CMAKE_COMMAND}\"\n                               \"-DINPUT=${_GO_INPUT}\"\n                               \"-DOUTPUT=${_GO_OUTPUT}\"\n                               -P \"${CMAKE_CURRENT_BINARY_DIR}/scripts/genout.cmake\"\n                       DEPENDS \"${_GO_INPUT}\" ${_GO_DEPENDS}\n                       WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")\n  endfunction()\n\n  # Generate specific source file with awk\n  # generate_source(OUTPUT outputfile [DEPENDS dep1 [dep2...]])\n  function(generate_source)\n    set(options)\n    set(oneValueArgs OUTPUT)\n    set(multiValueArgs DEPENDS)\n    cmake_parse_arguments(_GSO \"${options}\" \"${oneValueArgs}\" \"${multiValueArgs}\" ${ARGN})\n    if (NOT _GSO_OUTPUT)\n      message(FATAL_ERROR \"Invalid arguments.  generate_source requires output.\")\n    endif()\n\n    add_custom_command(OUTPUT \"${CMAKE_CURRENT_BINARY_DIR}/${_GSO_OUTPUT}\"\n                       COMMAND \"${CMAKE_COMMAND}\"\n                               \"-DOUTPUT=${_GSO_OUTPUT}\"\n                               -P \"${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake\"\n                       DEPENDS ${_GSO_DEPENDS}\n                       WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")\n  endfunction()\n\n  # Copy file\n  function(generate_copy source destination)\n    add_custom_command(OUTPUT \"${destination}\"\n                       COMMAND \"${CMAKE_COMMAND}\" -E remove \"${destination}\"\n                       COMMAND \"${CMAKE_COMMAND}\" -E copy \"${source}\"\n                                                          \"${destination}\"\n                       DEPENDS \"${source}\")\n  endfunction()\n\n  # Generate scripts/pnglibconf.h\n  generate_source(OUTPUT \"scripts/pnglibconf.c\"\n                  DEPENDS \"${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa\"\n                          \"${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk\"\n                          \"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h\")\n\n  # Generate pnglibconf.c\n  generate_source(OUTPUT \"pnglibconf.c\"\n                  DEPENDS \"${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa\"\n                          \"${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk\"\n                          \"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h\")\n\n  if(PNG_PREFIX)\n    set(PNGLIBCONF_H_EXTRA_DEPENDS\n        \"${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out\"\n        \"${CMAKE_CURRENT_SOURCE_DIR}/scripts/macro.lst\")\n    set(PNGPREFIX_H_EXTRA_DEPENDS\n        \"${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out\")\n  endif()\n\n  generate_out(INPUT \"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c\"\n               OUTPUT \"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out\")\n\n  # Generate pnglibconf.h\n  generate_source(OUTPUT \"pnglibconf.h\"\n                  DEPENDS \"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out\"\n                          ${PNGLIBCONF_H_EXTRA_DEPENDS})\n\n  generate_out(INPUT \"${CMAKE_CURRENT_SOURCE_DIR}/scripts/intprefix.c\"\n               OUTPUT \"${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out\"\n               DEPENDS \"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h\")\n\n  generate_out(INPUT \"${CMAKE_CURRENT_SOURCE_DIR}/scripts/prefix.c\"\n               OUTPUT \"${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out\"\n               DEPENDS \"${CMAKE_CURRENT_SOURCE_DIR}/png.h\"\n                       \"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h\"\n                       \"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out\")\n\n  # Generate pngprefix.h\n  generate_source(OUTPUT \"pngprefix.h\"\n                  DEPENDS ${PNGPREFIX_H_EXTRA_DEPENDS})\n\n  generate_out(INPUT \"${CMAKE_CURRENT_SOURCE_DIR}/scripts/sym.c\"\n               OUTPUT \"${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out\"\n               DEPENDS \"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h\")\n\n  generate_out(INPUT \"${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.c\"\n               OUTPUT \"${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out\"\n               DEPENDS \"${CMAKE_CURRENT_SOURCE_DIR}/png.h\"\n                       \"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h\"\n                       \"${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt\")\n\n  generate_out(INPUT \"${CMAKE_CURRENT_SOURCE_DIR}/scripts/vers.c\"\n               OUTPUT \"${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out\"\n               DEPENDS \"${CMAKE_CURRENT_SOURCE_DIR}/png.h\"\n                       \"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h\"\n                       \"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h\")\n\n  generate_chk(INPUT \"${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out\"\n               OUTPUT \"${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk\"\n               DEPENDS \"${CMAKE_CURRENT_SOURCE_DIR}/scripts/checksym.awk\"\n                       \"${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.def\")\n\n  add_custom_target(symbol-check DEPENDS\n                    \"${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk\")\n\n  generate_copy(\"${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out\"\n                \"${CMAKE_CURRENT_BINARY_DIR}/libpng.sym\")\n  generate_copy(\"${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out\"\n                \"${CMAKE_CURRENT_BINARY_DIR}/libpng.vers\")\n\n  add_custom_target(genvers DEPENDS \"${CMAKE_CURRENT_BINARY_DIR}/libpng.vers\")\n  add_custom_target(gensym DEPENDS \"${CMAKE_CURRENT_BINARY_DIR}/libpng.sym\")\n\n  add_custom_target(\"genprebuilt\"\n                    COMMAND \"${CMAKE_COMMAND}\"\n                            \"-DOUTPUT=scripts/pnglibconf.h.prebuilt\"\n                            -P \"${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake\"\n                    WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")\n\n  # A single target handles generation of all generated files.  If\n  # they are dependend upon separately by multiple targets, this\n  # confuses parallel make (it would require a separate top-level\n  # target for each file to track the dependencies properly).\n  add_custom_target(genfiles DEPENDS\n    \"${CMAKE_CURRENT_BINARY_DIR}/libpng.sym\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/libpng.vers\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out\")\nendif(NOT AWK)\n\n# OUR SOURCES\nset(libpng_public_hdrs\n  png.h\n  pngconf.h\n  \"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h\"\n)\nset(libpng_private_hdrs\n  pngpriv.h\n  pngdebug.h\n  pnginfo.h\n  pngstruct.h\n)\nif(AWK)\n  list(APPEND libpng_private_hdrs \"${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h\")\nendif()\nset(libpng_sources\n  ${libpng_public_hdrs}\n  ${libpng_private_hdrs}\n  png.c\n  pngerror.c\n  pngget.c\n  pngmem.c\n  pngpread.c\n  pngread.c\n  pngrio.c\n  pngrtran.c\n  pngrutil.c\n  pngset.c\n  pngtrans.c\n  pngwio.c\n  pngwrite.c\n  pngwtran.c\n  pngwutil.c\n)\nset(pngtest_sources\n  pngtest.c\n)\nset(pngvalid_sources\n  contrib/libtests/pngvalid.c\n)\nset(pngstest_sources\n  contrib/libtests/pngstest.c\n)\nset(pngunknown_sources\n  contrib/libtests/pngunknown.c\n)\nset(pngimage_sources\n  contrib/libtests/pngimage.c\n)\nset(pngfix_sources\n  contrib/tools/pngfix.c\n)\nset(png_fix_itxt_sources\n  contrib/tools/png-fix-itxt.c\n)\n\nif(MSVC)\n  add_definitions(-D_CRT_SECURE_NO_DEPRECATE)\nendif(MSVC)\n\nif(PNG_DEBUG)\n  add_definitions(-DPNG_DEBUG)\nendif()\n\n# NOW BUILD OUR TARGET\ninclude_directories(${CMAKE_CURRENT_SOURCE_DIR} ${ZLIB_INCLUDE_DIR})\n\nunset(PNG_LIB_TARGETS)\n\nif(PNG_SHARED)\n  add_library(png SHARED ${libpng_sources})\n  set(PNG_LIB_TARGETS png)\n  set_target_properties(png PROPERTIES OUTPUT_NAME ${PNG_LIB_NAME})\n  add_dependencies(png genfiles)\n  if(MSVC)\n    # msvc does not append 'lib' - do it here to have consistent name\n    set_target_properties(png PROPERTIES PREFIX \"lib\")\n    set_target_properties(png PROPERTIES IMPORT_PREFIX \"lib\")\n  endif()\n  target_link_libraries(png ${ZLIB_LIBRARY} ${M_LIBRARY})\n\n  if(UNIX AND AWK)\n    if(HAVE_LD_VERSION_SCRIPT)\n      set_target_properties(png PROPERTIES LINK_FLAGS\n        \"-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'\")\n    elseif(HAVE_SOLARIS_LD_VERSION_SCRIPT)\n      set_target_properties(png PROPERTIES LINK_FLAGS\n        \"-Wl,-M -Wl,'${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'\")\n    endif()\n  endif()\nendif()\n\nif(PNG_STATIC)\n  # does not work without changing name\n  set(PNG_LIB_NAME_STATIC png_static)\n  add_library(png_static STATIC ${libpng_sources})\n  add_dependencies(png_static genfiles)\n  # MSVC doesn't use a different file extension for shared vs. static\n  # libs.  We are able to change OUTPUT_NAME to remove the _static\n  # for all other platforms.\n  if(NOT MSVC)\n    set_target_properties(png_static PROPERTIES\n      OUTPUT_NAME \"${PNG_LIB_NAME}\"\n      CLEAN_DIRECT_OUTPUT 1)\n  else()\n    set_target_properties(png_static PROPERTIES\n      OUTPUT_NAME \"${PNG_LIB_NAME}_static\"\n      CLEAN_DIRECT_OUTPUT 1)\n  endif()\n  list(APPEND PNG_LIB_TARGETS png_static)\n  if(MSVC)\n    # msvc does not append 'lib' - do it here to have consistent name\n    set_target_properties(png_static PROPERTIES PREFIX \"lib\")\n  endif()\n  target_link_libraries(png_static ${ZLIB_LIBRARY} ${M_LIBRARY})\nendif()\n\nif(PNG_FRAMEWORK)\n  set(PNG_LIB_NAME_FRAMEWORK png_framework)\n  add_library(png_framework SHARED ${libpng_sources})\n  add_dependencies(png_framework genfiles)\n  list(APPEND PNG_LIB_TARGETS png_framework)\n  set_target_properties(png_framework PROPERTIES\n    FRAMEWORK TRUE\n    FRAMEWORK_VERSION ${PNGLIB_VERSION}\n    MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PNGLIB_MAJOR}.${PNGLIB_MINOR}\n    MACOSX_FRAMEWORK_BUNDLE_VERSION ${PNGLIB_VERSION}\n    MACOSX_FRAMEWORK_IDENTIFIER org.libpng.libpng\n    XCODE_ATTRIBUTE_INSTALL_PATH \"@rpath\"\n    PUBLIC_HEADER \"${libpng_public_hdrs}\"\n    OUTPUT_NAME png)\n  target_link_libraries(png_framework ${ZLIB_LIBRARY} ${M_LIBRARY})\nendif()\n\nif(NOT PNG_LIB_TARGETS)\n  message(SEND_ERROR\n    \"No library variant selected to build. \"\n    \"Please enable at least one of the following options: \"\n    \" PNG_STATIC, PNG_SHARED, PNG_FRAMEWORK\")\nendif()\n\nif(PNG_SHARED AND WIN32)\n  set_target_properties(png PROPERTIES DEFINE_SYMBOL PNG_BUILD_DLL)\nendif()\n\nfunction(png_add_test)\n  set(options)\n  set(oneValueArgs NAME COMMAND)\n  set(multiValueArgs OPTIONS FILES)\n  cmake_parse_arguments(_PAT \"${options}\" \"${oneValueArgs}\" \"${multiValueArgs}\" ${ARGN})\n\n  if (NOT _PAT_NAME)\n    message(FATAL_ERROR \"Invalid arguments.  png_add_test requires name.\")\n  endif()\n  if (NOT _PAT_COMMAND)\n    message(FATAL_ERROR \"Invalid arguments.  png_add_test requires command.\")\n  endif()\n\n  set(TEST_OPTIONS \"${_PAT_OPTIONS}\")\n  set(TEST_FILES \"${_PAT_FILES}\")\n\n  configure_file(\"${CMAKE_CURRENT_SOURCE_DIR}/scripts/test.cmake.in\"\n                 \"${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake\" @ONLY)\n  if(CMAKE_MAJOR_VERSION GREATER 2) # have generator expressions\n    add_test(NAME \"${_PAT_NAME}\"\n             COMMAND \"${CMAKE_COMMAND}\"\n             \"-DLIBPNG=$<TARGET_FILE:png>\"\n             \"-DTEST_COMMAND=$<TARGET_FILE:${_PAT_COMMAND}>\"\n             -P \"${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake\")\n  else() # old 2.x add_test; limited and won't work well on Windows\n    # Note LIBPNG is a dummy value as there are no generator expressions\n    add_test(\"${_PAT_NAME}\" \"${CMAKE_COMMAND}\"\n             \"-DLIBPNG=${CMAKE_CURRENT_BINARY_DIR}/libpng.so\"\n             \"-DTEST_COMMAND=./${_PAT_COMMAND}\"\n             -P \"${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake\")\n  endif()\nendfunction()\n\nif(PNG_TESTS AND PNG_SHARED)\n  # Find test PNG files by globbing, but sort lists to ensure\n  # consistency between different filesystems.\n  file(GLOB PNGSUITE_PNGS \"${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/*.png\")\n  list(SORT PNGSUITE_PNGS)\n  file(GLOB TEST_PNGS \"${CMAKE_CURRENT_SOURCE_DIR}/contrib/testpngs/*.png\")\n  list(SORT TEST_PNGS)\n\n  set(PNGTEST_PNG \"${CMAKE_CURRENT_SOURCE_DIR}/pngtest.png\")\n\n  add_executable(pngtest ${pngtest_sources})\n  target_link_libraries(pngtest png)\n\n  png_add_test(NAME pngtest COMMAND pngtest FILES \"${PNGTEST_PNG}\")\n\n  add_executable(pngvalid ${pngvalid_sources})\n  target_link_libraries(pngvalid png)\n\n  png_add_test(NAME pngvalid-gamma-16-to-8\n               COMMAND pngvalid OPTIONS --gamma-16-to-8)\n  png_add_test(NAME pngvalid-gamma-alpha-mode\n               COMMAND pngvalid OPTIONS --gamma-alpha-mode)\n  png_add_test(NAME pngvalid-gamma-background\n               COMMAND pngvalid OPTIONS --gamma-background)\n  png_add_test(NAME pngvalid-gamma-expand16-alpha-mode\n               COMMAND pngvalid OPTIONS --gamma-alpha-mode --expand16)\n  png_add_test(NAME pngvalid-gamma-expand16-background\n               COMMAND pngvalid OPTIONS --gamma-background --expand16)\n  png_add_test(NAME pngvalid-gamma-expand16-transform\n               COMMAND pngvalid OPTIONS --gamma-transform --expand16)\n  png_add_test(NAME pngvalid-gamma-sbit\n               COMMAND pngvalid OPTIONS --gamma-sbit)\n  png_add_test(NAME pngvalid-gamma-threshold\n               COMMAND pngvalid OPTIONS --gamma-threshold)\n  png_add_test(NAME pngvalid-gamma-transform\n               COMMAND pngvalid OPTIONS --gamma-transform)\n  png_add_test(NAME pngvalid-progressive-interlace-standard\n               COMMAND pngvalid OPTIONS --standard --progressive-read --interlace)\n  png_add_test(NAME pngvalid-progressive-size\n               COMMAND pngvalid OPTIONS --size --progressive-read)\n  png_add_test(NAME pngvalid-progressive-standard\n               COMMAND pngvalid OPTIONS --standard --progressive-read)\n  png_add_test(NAME pngvalid-standard\n               COMMAND pngvalid OPTIONS --standard)\n  png_add_test(NAME pngvalid-transform\n               COMMAND pngvalid OPTIONS --transform)\n\n  add_executable(pngstest ${pngstest_sources})\n  target_link_libraries(pngstest png)\n\n  foreach(gamma_type 1.8 linear none sRGB)\n    foreach(alpha_type none alpha)\n      set(PNGSTEST_FILES)\n      foreach(test_png ${TEST_PNGS})\n        string(REGEX MATCH \".*-linear[-.].*\" TEST_PNG_LINEAR \"${test_png}\")\n        string(REGEX MATCH \".*-sRGB[-.].*\" TEST_PNG_SRGB \"${test_png}\")\n        string(REGEX MATCH \".*-1.8[-.].*\" TEST_PNG_G18 \"${test_png}\")\n        string(REGEX MATCH \".*-alpha-.*\" TEST_PNG_ALPHA \"${test_png}\")\n\n        set(TEST_PNG_VALID TRUE)\n\n        if(TEST_PNG_ALPHA)\n          if (NOT \"${alpha_type}\" STREQUAL \"alpha\")\n            set(TEST_PNG_VALID FALSE)\n          endif()\n        else()\n          if (\"${alpha_type}\" STREQUAL \"alpha\")\n            set(TEST_PNG_VALID FALSE)\n          endif()\n        endif()\n\n        if(TEST_PNG_LINEAR)\n          if(NOT \"${gamma_type}\" STREQUAL \"linear\")\n            set(TEST_PNG_VALID FALSE)\n          endif()\n        elseif(TEST_PNG_SRGB)\n          if(NOT \"${gamma_type}\" STREQUAL \"sRGB\")\n            set(TEST_PNG_VALID FALSE)\n          endif()\n        elseif(TEST_PNG_G18)\n          if(NOT \"${gamma_type}\" STREQUAL \"1.8\")\n            set(TEST_PNG_VALID FALSE)\n          endif()\n        else()\n          if(NOT \"${gamma_type}\" STREQUAL \"none\")\n            set(TEST_PNG_VALID FALSE)\n          endif()\n        endif()\n\n        if(TEST_PNG_VALID)\n          list(APPEND PNGSTEST_FILES \"${test_png}\")\n        endif()\n      endforeach()\n      # Should already be sorted, but sort anyway to be certain.\n      list(SORT PNGSTEST_FILES)\n      png_add_test(NAME pngstest-${gamma_type}-${alpha_type}\n                   COMMAND pngstest\n                   OPTIONS --tmpfile \"${gamma_type}-${alpha_type}-\" --log\n                   FILES ${PNGSTEST_FILES})\n    endforeach()\n  endforeach()\n\n  add_executable(pngunknown ${pngunknown_sources})\n  target_link_libraries(pngunknown png)\n\n  png_add_test(NAME pngunknown-discard COMMAND pngunknown OPTIONS --strict default=discard FILES \"${PNGTEST_PNG}\")\n  png_add_test(NAME pngunknown-IDAT COMMAND pngunknown OPTIONS --strict default=discard IDAT=save FILES \"${PNGTEST_PNG}\")\n  png_add_test(NAME pngunknown-if-safe COMMAND pngunknown OPTIONS --strict default=if-safe FILES \"${PNGTEST_PNG}\")\n  png_add_test(NAME pngunknown-sAPI COMMAND pngunknown OPTIONS --strict bKGD=save cHRM=save gAMA=save all=discard iCCP=save sBIT=save sRGB=save FILES \"${PNGTEST_PNG}\")\n  png_add_test(NAME pngunknown-save COMMAND pngunknown OPTIONS --strict default=save FILES \"${PNGTEST_PNG}\")\n  png_add_test(NAME pngunknown-sTER COMMAND pngunknown OPTIONS --strict sTER=if-safe FILES \"${PNGTEST_PNG}\")\n  png_add_test(NAME pngunknown-vpAg COMMAND pngunknown OPTIONS --strict vpAg=if-safe FILES \"${PNGTEST_PNG}\")\n\n  add_executable(pngimage ${pngimage_sources})\n  target_link_libraries(pngimage png)\n\n  png_add_test(NAME pngimage-quick COMMAND pngimage OPTIONS --list-combos --log FILES ${PNGSUITE_PNGS})\n  png_add_test(NAME pngimage-full COMMAND pngimage OPTIONS --exhaustive --list-combos --log FILES ${PNGSUITE_PNGS})\nendif()\n\nif(PNG_SHARED)\n  add_executable(pngfix ${pngfix_sources})\n  target_link_libraries(pngfix png)\n  set(PNG_BIN_TARGETS pngfix)\n\n  add_executable(png-fix-itxt ${png_fix_itxt_sources})\n  target_link_libraries(png-fix-itxt ${ZLIB_LIBRARY} ${M_LIBRARY})\n  list(APPEND PNG_BIN_TARGETS png-fix-itxt)\nendif()\n\n# Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set\nIF(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)\n  SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY \"lib\")\nENDIF(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)\n\n# Set a variable with CMake code which:\n# Creates a symlink from src to dest (if possible) or alternatively\n# copies if different.\nmacro(CREATE_SYMLINK SRC_FILE DEST_FILE)\n  FILE(REMOVE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE})\n  if(WIN32 AND NOT CYGWIN AND NOT MSYS)\n    ADD_CUSTOM_COMMAND(\n        OUTPUT ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE}   ${CMAKE_CURRENT_BINARY_DIR}/${DEST_FILE}\n        COMMAND ${CMAKE_COMMAND} -E copy_if_different  \"${SRC_FILE}\" ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE}\n        COMMAND ${CMAKE_COMMAND} -E copy_if_different  \"${SRC_FILE}\" ${CMAKE_CURRENT_BINARY_DIR}/${DEST_FILE}\n        DEPENDS ${PNG_LIB_TARGETS}\n        )\n    ADD_CUSTOM_TARGET(${DEST_FILE}_COPY ALL DEPENDS ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE})\n  else(WIN32 AND NOT CYGWIN AND NOT MSYS)\n    get_filename_component(LINK_TARGET \"${SRC_FILE}\" NAME)\n    execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_LIBRARY_OUTPUT_DIRECTORY})\n    execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink \"${LINK_TARGET}\" ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})\n    execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink \"${LINK_TARGET}\" ${DEST_FILE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})\n  endif(WIN32 AND NOT CYGWIN AND NOT MSYS)\nendmacro()\n\n# Create source generation scripts.\nconfigure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genchk.cmake.in\n               ${CMAKE_CURRENT_BINARY_DIR}/scripts/genchk.cmake @ONLY)\nconfigure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genout.cmake.in\n               ${CMAKE_CURRENT_BINARY_DIR}/scripts/genout.cmake @ONLY)\nconfigure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/gensrc.cmake.in\n               ${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake @ONLY)\n\n\n# libpng is a library so default to 'lib'\nif(NOT DEFINED CMAKE_INSTALL_LIBDIR)\n  set(CMAKE_INSTALL_LIBDIR lib)\nendif(NOT DEFINED CMAKE_INSTALL_LIBDIR)\n\n# CREATE PKGCONFIG FILES\n# we use the same files like ./configure, so we have to set its vars\n# Only do this on Windows for Cygwin - the files don't make much sense outside\n# a UNIX look alike\nif(NOT WIN32 OR CYGWIN OR MINGW)\n  set(prefix      ${CMAKE_INSTALL_PREFIX})\n  set(exec_prefix ${CMAKE_INSTALL_PREFIX})\n  set(libdir      ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})\n  set(includedir  ${CMAKE_INSTALL_PREFIX}/include)\n  set(LIBS        \"-lz -lm\")\n  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng.pc.in\n    ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc @ONLY)\n  CREATE_SYMLINK(${PNGLIB_NAME}.pc libpng.pc)\n\n  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng-config.in\n    ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config @ONLY)\n  CREATE_SYMLINK(${PNGLIB_NAME}-config libpng-config)\nendif(NOT WIN32 OR CYGWIN OR MINGW)\n\n# SET UP LINKS\nif(PNG_SHARED)\n  set_target_properties(png PROPERTIES\n#   VERSION 16.${PNGLIB_RELEASE}.1.6.22beta03\n    VERSION 16.${PNGLIB_RELEASE}.0\n    SOVERSION 16\n    CLEAN_DIRECT_OUTPUT 1)\nendif()\n\n# If CMake > 2.4.x, we set a variable used below to export\n# targets to an export file.\n# TODO: Use VERSION_GREATER after our cmake_minimum_required >= 2.6.2\nif(CMAKE_MAJOR_VERSION GREATER 1 AND CMAKE_MINOR_VERSION GREATER 4)\n  set(PNG_EXPORT_RULE EXPORT libpng)\nelseif(CMAKE_MAJOR_VERSION GREATER 2) # future proof\n  set(PNG_EXPORT_RULE EXPORT libpng)\nendif()\n\n# INSTALL\nif(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )\n  install(TARGETS ${PNG_LIB_TARGETS}\n      ${PNG_EXPORT_RULE}\n      RUNTIME DESTINATION bin\n      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}\n      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}\n      FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR})\n\n  if(PNG_SHARED)\n    # Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin\n    if(CYGWIN OR MINGW)\n       get_target_property(BUILD_TARGET_LOCATION png LOCATION_${CMAKE_BUILD_TYPE})\n       CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_IMPORT_LIBRARY_SUFFIX})\n       install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_IMPORT_LIBRARY_SUFFIX}\n         DESTINATION ${CMAKE_INSTALL_LIBDIR})\n    endif(CYGWIN OR MINGW)\n\n    if(NOT WIN32)\n      get_target_property(BUILD_TARGET_LOCATION png LOCATION_${CMAKE_BUILD_TYPE})\n      CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_SHARED_LIBRARY_SUFFIX})\n      install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_SHARED_LIBRARY_SUFFIX}\n         DESTINATION ${CMAKE_INSTALL_LIBDIR})\n    endif(NOT WIN32)\n  endif(PNG_SHARED)\n\n  if(PNG_STATIC)\n    if(NOT WIN32 OR CYGWIN OR MINGW)\n      get_target_property(BUILD_TARGET_LOCATION png_static LOCATION_${CMAKE_BUILD_TYPE})\n      CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_STATIC_LIBRARY_SUFFIX})\n      install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_STATIC_LIBRARY_SUFFIX}\n         DESTINATION ${CMAKE_INSTALL_LIBDIR})\n    endif(NOT WIN32 OR CYGWIN OR MINGW)\n endif()\nendif()\n\nif(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )\n  install(FILES ${libpng_public_hdrs}   DESTINATION include)\n  install(FILES ${libpng_public_hdrs}   DESTINATION include/${PNGLIB_NAME})\nendif()\nif(NOT SKIP_INSTALL_EXECUTABLES AND NOT SKIP_INSTALL_ALL )\n  if(NOT WIN32 OR CYGWIN OR MINGW)\n    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config DESTINATION bin)\n    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config\n            DESTINATION bin)\n  endif(NOT WIN32 OR CYGWIN OR MINGW)\nendif()\n\nif(NOT SKIP_INSTALL_PROGRAMS AND NOT SKIP_INSTALL_ALL )\n  install(TARGETS ${PNG_BIN_TARGETS}\n      RUNTIME DESTINATION bin)\nendif()\n\nif(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )\n  # Install man pages\n  if(NOT PNG_MAN_DIR)\n    set(PNG_MAN_DIR \"share/man\")\n  endif()\n  install(FILES libpng.3 libpngpf.3      DESTINATION ${PNG_MAN_DIR}/man3)\n  install(FILES png.5                    DESTINATION ${PNG_MAN_DIR}/man5)\n  # Install pkg-config files\n  if(NOT WIN32 OR CYGWIN OR MINGW)\n    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng.pc\n            DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)\n    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config\n            DESTINATION bin)\n    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc\n            DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)\n    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config\n            DESTINATION bin)\n  endif(NOT WIN32 OR CYGWIN OR MINGW)\nendif()\n\n# On versions of CMake that support it, create an export file CMake\n# users can include() to import our targets\nif(PNG_EXPORT_RULE AND NOT SKIP_INSTALL_EXPORT AND NOT SKIP_INSTALL_ALL )\n  install(EXPORT libpng DESTINATION lib/libpng FILE lib${PNG_LIB_NAME}.cmake)\nendif()\n\n# what's with libpng-manual.txt and all the extra files?\n\n# UNINSTALL\n# do we need this?\n\n# DIST\n# do we need this?\n\n# to create msvc import lib for mingw compiled shared lib\n# pexports libpng.dll > libpng.def\n# lib /def:libpng.def /machine:x86\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/CleanSpec.mk",
    "content": "# Copyright (C) 2007 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n# If you don't need to do a full clean build but would like to touch\n# a file or delete some intermediate files, add a clean step to the end\n# of the list.  These steps will only be run once, if they haven't been\n# run before.\n#\n# E.g.:\n#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)\n#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)\n#\n# Always use \"touch -c\" and \"rm -f\" or \"rm -rf\" to gracefully deal with\n# files that are missing or have been moved.\n#\n# Use $(PRODUCT_OUT) to get to the \"out/target/product/blah/\" directory.\n# Use $(OUT_DIR) to refer to the \"out\" directory.\n#\n# If you need to re-do something that's already mentioned, just copy\n# the command and add it to the bottom of the list.  E.g., if a change\n# that you made last week required touching a file and a change you\n# made today requires touching the same file, just copy the old\n# touch step and add it to the end of the list.\n#\n# ************************************************\n# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST\n# ************************************************\n\n# For example:\n#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)\n#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)\n#$(call add-clean-step, find $(OUT_DIR) -type f -name \"IGTalkSession*\" -print0 | xargs -0 rm -f)\n#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)\n\n# ************************************************\n# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST\n# ************************************************\n"
  },
  {
    "path": "atlas-aapt/external/libpng/INSTALL",
    "content": "\nInstalling libpng\n\nContents\n\n   I. Simple installation\n  II. Rebuilding the configure scripts\n III. Using scripts/makefile*\n  IV. Using cmake\n   V. Directory structure\n  VI. Building with project files\n VII. Building with makefiles\nVIII. Configuring libpng for 16-bit platforms\n  IX. Configuring for DOS\n   X. Configuring for Medium Model\n  XI. Prepending a prefix to exported symbols\n XII. Configuring for compiler xxx:\nXIII. Removing unwanted object code\n XIV. Changes to the build and configuration of libpng in libpng-1.5.x\n  XV. Setjmp/longjmp issues\n XVI. Other sources of information about libpng\n\nI. Simple installation\n\nOn Unix/Linux and similar systems, you can simply type\n\n    ./configure [--prefix=/path]\n    make check\n    make install\n\nand ignore the rest of this document.  \"/path\" is the path to the directory\nwhere you want to install the libpng \"lib\", \"include\", and \"bin\"\nsubdirectories.\n\nIf you downloaded a GIT clone, you will need to run ./autogen.sh before\nrunning ./configure, to create \"configure\" and \"Makefile.in\" which are\nnot included in the GIT repository.\n\nNote that \"configure\" is only included in the \"*.tar\" distributions and not\nin the \"*.zip\" or \"*.7z\" distributions. If you downloaded one of those\ndistributions, see \"Building with project files\" or \"Building with makefiles\",\nbelow.\n\nII. Rebuilding the configure scripts\n\nIf configure does not work on your system, or if you have a need to\nchange configure.ac or Makefile.am, and you have a reasonably\nup-to-date set of tools, running ./autogen.sh in a git clone before\nrunning ./configure may fix the problem.  To be really sure that you\naren't using any of the included pre-built scripts, you can do this:\n\n    ./configure --enable-maintainer-mode\n    make maintainer-clean\n    ./autogen.sh --maintainer --clean\n    ./autogen.sh --maintainer\n    ./configure [--prefix=/path] [other options]\n    make\n    make install\n    make check\n\nIII. Using scripts/makefile*\n\nInstead, you can use one of the custom-built makefiles in the\n\"scripts\" directory\n\n    cp scripts/pnglibconf.h.prebuilt pnglibconf.h\n    cp scripts/makefile.system makefile\n    make test\n    make install\n\nThe files that are presently available in the scripts directory\nare listed and described in scripts/README.txt.\n\nOr you can use one of the \"projects\" in the \"projects\" directory.\n\nBefore installing libpng, you must first install zlib, if it\nis not already on your system.  zlib can usually be found\nwherever you got libpng; otherwise go to http://zlib.net.  You can place\nzlib in in the same directory as libpng or in another directory.\n\nIf your system already has a preinstalled zlib you will still need\nto have access to the zlib.h and zconf.h include files that\ncorrespond to the version of zlib that's installed.\n\nIf you wish to test with a particular zlib that is not first in the\nstandard library search path, put ZLIBLIB, ZLIBINC, CPPFLAGS, LDFLAGS,\nand LD_LIBRARY_PATH in your environment before running \"make test\"\nor \"make distcheck\":\n\nZLIBLIB=/path/to/lib export ZLIBLIB\nZLIBINC=/path/to/include export ZLIBINC\nCPPFLAGS=\"-I$ZLIBINC\" export CPPFLAGS\nLDFLAGS=\"-L$ZLIBLIB\" export LDFLAGS\nLD_LIBRARY_PATH=\"$ZLIBLIB:$LD_LIBRARY_PATH\" export LD_LIBRARY_PATH\n\nIf you are using one of the makefile scripts, put ZLIBLIB and ZLIBINC\nin your environment and type \"make ZLIBLIB=$ZLIBLIB ZLIBINC=$ZLIBINC test\".\n\nIV. Using cmake\n\nIf you want to use \"cmake\" (see www.cmake.org), type\n\n   cmake . -DCMAKE_INSTALL_PREFIX=/path\n   make\n   make install\n\nAs when using the simple configure method described above, \"/path\" points to\nthe installation directory where you want to put the libpng \"lib\", \"include\",\nand \"bin\" subdirectories.\n\nV. Directory structure\n\nYou can rename the directories that you downloaded (they\nmight be called \"libpng-x.y.z\" or \"libpngNN\" and \"zlib-1.2.8\"\nor \"zlib128\") so that you have directories called \"zlib\" and \"libpng\".\n\nYour directory structure should look like this:\n\n   ..       (the parent directory)\n      libpng  (this directory)\n          INSTALL (this file)\n          README\n          *.h, *.c  => libpng source files\n          CMakeLists.txt    =>  \"cmake\" script\n          configuration files:\n             configure.ac, configure, Makefile.am, Makefile.in,\n             autogen.sh, config.guess, ltmain.sh, missing, libpng.pc.in,\n             libpng-config.in, aclocal.m4, config.h.in, config.sub,\n             depcomp, install-sh, mkinstalldirs, test-pngtest.sh\n          contrib\n             arm-neon, conftest, examples, gregbook, libtests, pngminim,\n             pngminus, pngsuite, tools, visupng\n          projects\n             cbuilder5, owatcom, visualc71, vstudio, xcode\n          scripts\n             makefile.*\n             *.def (module definition files)\n             etc.\n          pngtest.png\n          etc.\n      zlib\n          README, *.h, *.c contrib, etc.\n\nIf the line endings in the files look funny, you may wish to get the other\ndistribution of libpng.  It is available in both tar.gz (UNIX style line\nendings) and zip (DOS style line endings) formats.\n\nVI. Building with project files\n\nIf you are building libpng with MSVC, you can enter the\nlibpng projects\\visualc71 or vstudio directory and follow the instructions\nin README.txt.\n\nOtherwise enter the zlib directory and follow the instructions in zlib/README,\nthen come back here and run \"configure\" or choose the appropriate\nmakefile.sys in the scripts directory.\n\nVII. Building with makefiles\n\nCopy the file (or files) that you need from the\nscripts directory into this directory, for example\n\n   MSDOS example: copy scripts\\makefile.msc makefile\n                  copy scripts\\pnglibconf.h.prebuilt pnglibconf.h\n   UNIX example:  cp scripts/makefile.std makefile\n                  cp scripts/pnglibconf.h.prebuilt pnglibconf.h\n\nRead the makefile to see if you need to change any source or\ntarget directories to match your preferences.\n\nThen read pnglibconf.dfa to see if you want to make any configuration\nchanges.\n\nThen just run \"make\" which will create the libpng library in\nthis directory and \"make test\" which will run a quick test that reads\nthe \"pngtest.png\" file and writes a \"pngout.png\" file that should be\nidentical to it.  Look for \"9782 zero samples\" in the output of the\ntest.  For more confidence, you can run another test by typing\n\"pngtest pngnow.png\" and looking for \"289 zero samples\" in the output.\nAlso, you can run \"pngtest -m contrib/pngsuite/*.png\" and compare\nyour output with the result shown in contrib/pngsuite/README.\n\nMost of the makefiles will allow you to run \"make install\" to\nput the library in its final resting place (if you want to\ndo that, run \"make install\" in the zlib directory first if necessary).\nSome also allow you to run \"make test-installed\" after you have\nrun \"make install\".\n\nVIII. Configuring libpng for 16-bit platforms\n\nYou will want to look into zconf.h to tell zlib (and thus libpng) that\nit cannot allocate more than 64K at a time.  Even if you can, the memory\nwon't be accessible.  So limit zlib and libpng to 64K by defining MAXSEG_64K.\n\nIX. Configuring for DOS\n\nFor DOS users who only have access to the lower 640K, you will\nhave to limit zlib's memory usage via a png_set_compression_mem_level()\ncall.  See zlib.h or zconf.h in the zlib library for more information.\n\nX. Configuring for Medium Model\n\nLibpng's support for medium model has been tested on most of the popular\ncompilers.  Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets\ndefined, and FAR gets defined to far in pngconf.h, and you should be\nall set.  Everything in the library (except for zlib's structure) is\nexpecting far data.  You must use the typedefs with the p or pp on\nthe end for pointers (or at least look at them and be careful).  Make\nnote that the rows of data are defined as png_bytepp, which is\nan \"unsigned char far * far *\".\n\nXI. Prepending a prefix to exported symbols\n\nStarting with libpng-1.6.0, you can configure libpng (when using the\n\"configure\" script) to prefix all exported symbols by means of the\nconfiguration option \"--with-libpng-prefix=FOO_\", where FOO_ can be any\nstring beginning with a letter and containing only uppercase\nand lowercase letters, digits, and the underscore (i.e., a C language\nidentifier).  This creates a set of macros in pnglibconf.h, so this is\ntransparent to applications; their function calls get transformed by\nthe macros to use the modified names.\n\nXII. Configuring for compiler xxx:\n\nAll includes for libpng are in pngconf.h.  If you need to add, change\nor delete an include, this is the place to do it.\nThe includes that are not needed outside libpng are placed in pngpriv.h,\nwhich is only used by the routines inside libpng itself.\nThe files in libpng proper only include pngpriv.h and png.h, which\nin turn includes pngconf.h and, as of libpng-1.5.0, pnglibconf.h.\nAs of libpng-1.5.0, pngpriv.h also includes three other private header\nfiles, pngstruct.h, pnginfo.h, and pngdebug.h, which contain material\nthat previously appeared in the public headers.\n\nXIII. Removing unwanted object code\n\nThere are a bunch of #define's in pngconf.h that control what parts of\nlibpng are compiled.  All the defines end in _SUPPORTED.  If you are\nnever going to use a capability, you can change the #define to #undef\nbefore recompiling libpng and save yourself code and data space, or\nyou can turn off individual capabilities with defines that begin with\nPNG_NO_.\n\nIn libpng-1.5.0 and later, the #define's are in pnglibconf.h instead.\n\nYou can also turn all of the transforms and ancillary chunk capabilities\noff en masse with compiler directives that define\nPNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,\nor all four, along with directives to turn on any of the capabilities that\nyou do want.  The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable the\nextra transformations but still leave the library fully capable of reading\nand writing PNG files with all known public chunks. Use of the\nPNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive produces a library\nthat is incapable of reading or writing ancillary chunks.  If you are\nnot using the progressive reading capability, you can turn that off\nwith PNG_NO_PROGRESSIVE_READ (don't confuse this with the INTERLACING\ncapability, which you'll still have).\n\nAll the reading and writing specific code are in separate files, so the\nlinker should only grab the files it needs.  However, if you want to\nmake sure, or if you are building a stand alone library, all the\nreading files start with \"pngr\" and all the writing files start with \"pngw\".\nThe files that don't match either (like png.c, pngtrans.c, etc.)\nare used for both reading and writing, and always need to be included.\nThe progressive reader is in pngpread.c\n\nIf you are creating or distributing a dynamically linked library (a .so\nor DLL file), you should not remove or disable any parts of the library,\nas this will cause applications linked with different versions of the\nlibrary to fail if they call functions not available in your library.\nThe size of the library itself should not be an issue, because only\nthose sections that are actually used will be loaded into memory.\n\nXIV. Changes to the build and configuration of libpng in libpng-1.5.x\n\nDetails of internal changes to the library code can be found in the CHANGES\nfile and in the GIT repository logs.  These will be of no concern to the vast\nmajority of library users or builders; however, the few who configure libpng\nto a non-default feature set may need to change how this is done.\n\nThere should be no need for library builders to alter build scripts if\nthese use the distributed build support - configure or the makefiles -\nhowever, users of the makefiles may care to update their build scripts\nto build pnglibconf.h where the corresponding makefile does not do so.\n\nBuilding libpng with a non-default configuration has changed completely.\nThe old method using pngusr.h should still work correctly even though the\nway pngusr.h is used in the build has been changed; however, library\nbuilders will probably want to examine the changes to take advantage of\nnew capabilities and to simplify their build system.\n\nA. Specific changes to library configuration capabilities\n\nThe exact mechanism used to control attributes of API functions has\nchanged.  A single set of operating system independent macro definitions\nis used and operating system specific directives are defined in\npnglibconf.h\n\nAs part of this the mechanism used to choose procedure call standards on\nthose systems that allow a choice has been changed.  At present this only\naffects certain Microsoft (DOS, Windows) and IBM (OS/2) operating systems\nrunning on Intel processors.  As before, PNGAPI is defined where required\nto control the exported API functions; however, two new macros, PNGCBAPI\nand PNGCAPI, are used instead for callback functions (PNGCBAPI) and\n(PNGCAPI) for functions that must match a C library prototype (currently\nonly png_longjmp_ptr, which must match the C longjmp function.)  The new\napproach is documented in pngconf.h\n\nDespite these changes, libpng 1.5.0 only supports the native C function\ncalling standard on those platforms tested so far (__cdecl on Microsoft\nWindows).  This is because the support requirements for alternative\ncalling conventions seem to no longer exist.  Developers who find it\nnecessary to set PNG_API_RULE to 1 should advise the mailing list\n(png-mng-implement) of this and library builders who use Openwatcom and\ntherefore set PNG_API_RULE to 2 should also contact the mailing list.\n\nB. Changes to the configuration mechanism\n\nPrior to libpng-1.5.0 library builders who needed to configure libpng\nhad either to modify the exported pngconf.h header file to add system\nspecific configuration or had to write feature selection macros into\npngusr.h and cause this to be included into pngconf.h by defining\nPNG_USER_CONFIG. The latter mechanism had the disadvantage that an\napplication built without PNG_USER_CONFIG defined would see the\nunmodified, default, libpng API and thus would probably fail to link.\n\nThese mechanisms still work in the configure build and in any makefile\nbuild that builds pnglibconf.h, although the feature selection macros\nhave changed somewhat as described above.  In 1.5.0, however, pngusr.h is\nprocessed only once, at the time the exported header file pnglibconf.h is\nbuilt.  pngconf.h no longer includes pngusr.h; therefore, pngusr.h is ignored\nafter the build of pnglibconf.h and it is never included in an application\nbuild.\n\nThe formerly used alternative of adding a list of feature macros to the\nCPPFLAGS setting in the build also still works; however, the macros will be\ncopied to pnglibconf.h and this may produce macro redefinition warnings\nwhen the individual C files are compiled.\n\nAll configuration now only works if pnglibconf.h is built from\nscripts/pnglibconf.dfa.  This requires the program awk.  Brian Kernighan\n(the original author of awk) maintains C source code of that awk and this\nand all known later implementations (often called by subtly different\nnames - nawk and gawk for example) are adequate to build pnglibconf.h.\nThe Sun Microsystems (now Oracle) program 'awk' is an earlier version\nand does not work; this may also apply to other systems that have a\nfunctioning awk called 'nawk'.\n\nConfiguration options are now documented in scripts/pnglibconf.dfa.  This\nfile also includes dependency information that ensures a configuration is\nconsistent; that is, if a feature is switched off, dependent features are\nalso switched off.  As a recommended alternative to using feature macros in\npngusr.h a system builder may also define equivalent options in pngusr.dfa\n(or, indeed, any file) and add that to the configuration by setting\nDFA_XTRA to the file name.  The makefiles in contrib/pngminim illustrate\nhow to do this, and also illustrate a case where pngusr.h is still required.\n\nAfter you have built libpng, the definitions that were recorded in\npnglibconf.h are available to your application (pnglibconf.h is included\nin png.h and gets installed alongside png.h and pngconf.h in your\n$PREFIX/include directory).  Do not edit pnglibconf.h after you have built\nlibpng, because than the settings would not accurately reflect the settings\nthat were used to build libpng.\n\nXV. Setjmp/longjmp issues\n\nLibpng uses setjmp()/longjmp() for error handling.  Unfortunately setjmp()\nis known to be not thread-safe on some platforms and we don't know of\nany platform where it is guaranteed to be thread-safe.  Therefore, if\nyour application is going to be using multiple threads, you should\nconfigure libpng with PNG_NO_SETJMP in your pngusr.dfa file, with\n-DPNG_NO_SETJMP on your compile line, or with\n\n  #undef PNG_SETJMP_SUPPORTED\n\nin your pnglibconf.h or pngusr.h.\n\nStarting with libpng-1.6.0, the library included a \"simplified API\".\nThis requires setjmp/longjmp, so you must either build the library\nwith PNG_SETJMP_SUPPORTED defined, or with PNG_SIMPLIFIED_READ_SUPPORTED\nand PNG_SIMPLIFIED_WRITE_SUPPORTED undefined.\n\nXVI. Other sources of information about libpng:\n\nFurther information can be found in the README and libpng-manual.txt\nfiles, in the individual makefiles, in png.h, and the manual pages\nlibpng.3 and png.5.\n\nUsing the ./configure script -- 16 December 2002.\n=================================================\n\nThe ./configure script should work compatibly with what scripts/makefile.*\ndid, however there are some options you might need to add to configure\nexplicitly, which previously was done semi-automatically (if you didn't edit\nscripts/makefile.* yourself, that is)\n\nCFLAGS=\"-Wall -O -funroll-loops \\\n-malign-loops=2 -malign-functions=2\" ./configure --prefix=/usr/include \\\n--with-pkgconfigdir=/usr/lib/pkgconfig --includedir=/usr/include\n\nYou can alternatively specify --includedir=/usr/include, /usr/local/include,\n/usr/include/libpng16, or whatever.\n\nIf you find that the configure script is out-of-date or is not supporting\nyour platform properly, try running autogen.sh to regenerate \"configure\",\n\"Makefile.in\", and the other configuration files. Then try configure again.\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/LICENSE",
    "content": "\nThis copy of the libpng notices is provided for your convenience.  In case of\nany discrepancy between this copy and the notices in the file png.h that is\nincluded in the libpng distribution, the latter shall prevail.\n\nCOPYRIGHT NOTICE, DISCLAIMER, and LICENSE:\n\nIf you modify libpng you may insert additional notices immediately following\nthis sentence.\n\nThis code is released under the libpng license.\n\nlibpng versions 1.0.7, July 1, 2000, through 1.6.22beta03, February 19, 2016, are\nCopyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are\nderived from libpng-1.0.6, and are distributed according to the same\ndisclaimer and license as libpng-1.0.6 with the following individuals\nadded to the list of Contributing Authors:\n\n   Simon-Pierre Cadieux\n   Eric S. Raymond\n   Mans Rullgard\n   Cosmin Truta\n   Gilles Vollant\n   James Yu\n\nand with the following additions to the disclaimer:\n\n   There is no warranty against interference with your enjoyment of the\n   library or against infringement.  There is no warranty that our\n   efforts or the library will fulfill any of your particular purposes\n   or needs.  This library is provided with all faults, and the entire\n   risk of satisfactory quality, performance, accuracy, and effort is with\n   the user.\n\nSome files in the \"contrib\" directory and some configure-generated\nfiles that are distributed with libpng have other copyright owners and\nare released under other open source licenses.\n\nlibpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are\nCopyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from\nlibpng-0.96, and are distributed according to the same disclaimer and\nlicense as libpng-0.96, with the following individuals added to the list\nof Contributing Authors:\n\n   Tom Lane\n   Glenn Randers-Pehrson\n   Willem van Schaik\n\nlibpng versions 0.89, June 1996, through 0.96, May 1997, are\nCopyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,\nand are distributed according to the same disclaimer and license as\nlibpng-0.88, with the following individuals added to the list of\nContributing Authors:\n\n   John Bowler\n   Kevin Bracey\n   Sam Bushell\n   Magnus Holmgren\n   Greg Roelofs\n   Tom Tanner\n\nSome files in the \"scripts\" directory have other copyright owners\nbut are released under this license.\n\nlibpng versions 0.5, May 1995, through 0.88, January 1996, are\nCopyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n\nFor the purposes of this copyright and license, \"Contributing Authors\"\nis defined as the following set of individuals:\n\n   Andreas Dilger\n   Dave Martindale\n   Guy Eric Schalnat\n   Paul Schmidt\n   Tim Wegner\n\nThe PNG Reference Library is supplied \"AS IS\".  The Contributing Authors\nand Group 42, Inc. disclaim all warranties, expressed or implied,\nincluding, without limitation, the warranties of merchantability and of\nfitness for any purpose.  The Contributing Authors and Group 42, Inc.\nassume no liability for direct, indirect, incidental, special, exemplary,\nor consequential damages, which may result from the use of the PNG\nReference Library, even if advised of the possibility of such damage.\n\nPermission is hereby granted to use, copy, modify, and distribute this\nsource code, or portions hereof, for any purpose, without fee, subject\nto the following restrictions:\n\n  1. The origin of this source code must not be misrepresented.\n\n  2. Altered versions must be plainly marked as such and must not\n     be misrepresented as being the original source.\n\n  3. This Copyright notice may not be removed or altered from any\n     source or altered source distribution.\n\nThe Contributing Authors and Group 42, Inc. specifically permit, without\nfee, and encourage the use of this source code as a component to\nsupporting the PNG file format in commercial products.  If you use this\nsource code in a product, acknowledgment is not required but would be\nappreciated.\n\nEND OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.\n\nTRADEMARK:\n\nThe name \"libpng\" has not been registered by the Copyright owner\nas a trademark in any jurisdiction.  However, because libpng has\nbeen distributed and maintained world-wide, continually since 1995,\nthe Copyright owner claims \"common-law trademark protection\" in any\njurisdiction where common-law trademark is recognized.\n\nOSI CERTIFICATION:\n\nLibpng is OSI Certified Open Source Software.  OSI Certified Open Source is\na certification mark of the Open Source Initiative. OSI has not addressed\nthe additional disclaimers inserted at version 1.0.7.\n\nEXPORT CONTROL:\n\nThe Copyright owner believes that the Export Control Classification\nNumber (ECCN) for libpng is EAR99, which means not subject to export\ncontrols or International Traffic in Arms Regulations (ITAR) because\nit is open source, publicly available software, that does not contain\nany encryption software.  See the EAR, paragraphs 734.3(b)(3) and\n734.7(b).\n\nGlenn Randers-Pehrson\nglennrp at users.sourceforge.net\nFebruary 19, 2016\n"
  },
  {
    "path": "atlas-aapt/external/libpng/MODULE_LICENSE_BSD_LIKE",
    "content": ""
  },
  {
    "path": "atlas-aapt/external/libpng/Makefile.am",
    "content": "# Makefile.am:\n#   Source file for Makefile.in (and hence Makefile)\n#\n\nPNGLIB_BASENAME= libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@\n\nACLOCAL_AMFLAGS = -I scripts\n\n# test programs - run on make check, make distcheck\ncheck_PROGRAMS= pngtest pngunknown pngstest pngvalid pngimage\n\n# Utilities - installed\nbin_PROGRAMS= pngfix png-fix-itxt\n\n# This ensures that pnglibconf.h gets built at the start of 'make all' or\n# 'make check', but it does not add dependencies to the individual programs,\n# this is done below.\n#\n# IMPORTANT: always add the object modules of new programs to the list below\n# because otherwise the sequence 'configure; make new-program' will *sometimes*\n# result in the installed (system) pnglibconf.h being used and the result is\n# always wrong and always very confusing.\nBUILT_SOURCES = pnglibconf.h\n\npngtest_SOURCES = pngtest.c\npngtest_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la\n\npngvalid_SOURCES = contrib/libtests/pngvalid.c\npngvalid_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la\n\npngstest_SOURCES = contrib/libtests/pngstest.c\npngstest_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la\n\npngunknown_SOURCES = contrib/libtests/pngunknown.c\npngunknown_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la\n\npngimage_SOURCES = contrib/libtests/pngimage.c\npngimage_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la\n\npngfix_SOURCES = contrib/tools/pngfix.c\npngfix_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la\n\npng_fix_itxt_SOURCES = contrib/tools/png-fix-itxt.c\n\n# Generally these are single line shell scripts to run a test with a particular\n# set of parameters:\nTESTS =\\\n   tests/pngtest\\\n   tests/pngvalid-gamma-16-to-8 tests/pngvalid-gamma-alpha-mode\\\n   tests/pngvalid-gamma-background tests/pngvalid-gamma-expand16-alpha-mode\\\n   tests/pngvalid-gamma-expand16-background\\\n   tests/pngvalid-gamma-expand16-transform tests/pngvalid-gamma-sbit\\\n   tests/pngvalid-gamma-threshold tests/pngvalid-gamma-transform\\\n   tests/pngvalid-progressive-size\\\n   tests/pngvalid-progressive-interlace-standard\\\n   tests/pngvalid-transform\\\n   tests/pngvalid-progressive-standard tests/pngvalid-standard\\\n   tests/pngstest-1.8 tests/pngstest-1.8-alpha tests/pngstest-linear\\\n   tests/pngstest-linear-alpha tests/pngstest-none tests/pngstest-none-alpha\\\n   tests/pngstest-sRGB tests/pngstest-sRGB-alpha tests/pngunknown-IDAT\\\n   tests/pngunknown-discard tests/pngunknown-if-safe tests/pngunknown-sAPI\\\n   tests/pngunknown-sTER tests/pngunknown-save tests/pngunknown-vpAg\\\n   tests/pngimage-quick tests/pngimage-full\n\n# man pages\ndist_man_MANS= libpng.3 libpngpf.3 png.5\n\n# generate the -config scripts if required\nbinconfigs= libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@-config\nEXTRA_SCRIPTS= libpng-config libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@-config\nbin_SCRIPTS= @binconfigs@\n\n# rules to build libpng, only build the old library on request\nlib_LTLIBRARIES=libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la\n# EXTRA_LTLIBRARIES= libpng.la\nlibpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = png.c pngerror.c\\\n\tpngget.c pngmem.c pngpread.c pngread.c pngrio.c pngrtran.c pngrutil.c\\\n\tpngset.c pngtrans.c pngwio.c pngwrite.c pngwtran.c pngwutil.c\\\n\tpng.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h pngusr.dfa\n\nif PNG_ARM_NEON\nlibpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += arm/arm_init.c\\\n\tarm/filter_neon.S arm/filter_neon_intrinsics.c\nendif\n\nnodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = pnglibconf.h\n\nlibpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS = -no-undefined -export-dynamic \\\n\t-version-number @PNGLIB_MAJOR@@PNGLIB_MINOR@:@PNGLIB_RELEASE@:0\n\nif HAVE_LD_VERSION_SCRIPT\n#   Versioned symbols and restricted exports\nif HAVE_SOLARIS_LD\n  libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS += -Wl,-M -Wl,libpng.vers\nelse\n  libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS += -Wl,--version-script=libpng.vers\nendif\n\n  libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = libpng.vers\nelse\n#   Only restricted exports when possible\n  libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS += -export-symbols libpng.sym\n  libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = libpng.sym\nendif\n\n#distribute headers in /usr/include/libpng/*\npkgincludedir= $(includedir)/$(PNGLIB_BASENAME)\npkginclude_HEADERS= png.h pngconf.h\nnodist_pkginclude_HEADERS= pnglibconf.h\n\n# pkg-config stuff, note that libpng.pc is always required in order\n# to get the correct library\npkgconfigdir = @pkgconfigdir@\npkgconfig_DATA = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.pc\n\n# Extra source distribution files, '${srcdir}' is used below to stop build files\n# from those directories being included.  This only works if the configure is\n# not done in the source directory!\nEXTRA_DIST= \\\n\tANNOUNCE CHANGES INSTALL LICENSE README TODO \\\n\tpngtest.png pngbar.png pngnow.png pngbar.jpg autogen.sh \\\n\t${srcdir}/contrib ${srcdir}/projects ${srcdir}/scripts \\\n\t$(TESTS) $(XFAIL_TESTS) tests/pngstest \\\n\tCMakeLists.txt example.c libpng-manual.txt\n\nSCRIPT_CLEANFILES=scripts/*.out scripts/*.chk\n\nCLEANFILES= *.tf? pngout.png libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.pc \\\n\tlibpng@PNGLIB_MAJOR@@PNGLIB_MINOR@-config libpng.vers libpng.sym \\\n\tcheck.new pnglibconf.h pngprefix.h symbols.new pngtest-log.txt \\\n\tpnglibconf.out pnglibconf.c pnglibconf.pre pnglibconf.dfn \\\n\t$(SCRIPT_CLEANFILES)\n\nMAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess config.h.in \\\nconfig.sub configure depcomp install-sh ltmain.sh missing\n\n# PNG_COPTS give extra options for the C compiler to be used on all compilation\n# steps (unless targe_CFLAGS is specified; that will take precedence over\n# AM_CFLAGS)\nPNG_COPTS = @PNG_COPTS@\nAM_CFLAGS = ${PNG_COPTS}\n\n# DFNCPP is normally just CPP - the C preprocessor - but on Solaris and maybe\n# other operating systems (NeXT?) the C preprocessor selected by configure\n# checks input tokens for validity - effectively it performs part of the ANSI-C\n# parsing - and therefore fails with the .df files.  configure.ac has special\n# checks for this and sets DFNCPP appropriately.\nDFNCPP = @DFNCPP@\n\nSUFFIXES = .chk .out\n\n$(PNGLIB_BASENAME).pc: libpng.pc\n\tcp libpng.pc $@\n\n$(PNGLIB_BASENAME)-config: libpng-config\n\tcp libpng-config $@\n\nscripts/sym.out scripts/vers.out: png.h pngconf.h pnglibconf.h\nscripts/prefix.out: png.h pngconf.h pnglibconf.out\nscripts/symbols.out: png.h pngconf.h $(srcdir)/scripts/pnglibconf.h.prebuilt\nscripts/intprefix.out: pnglibconf.h\n\nlibpng.sym: scripts/sym.out\n\trm -f $@\n\tcp $? $@\nlibpng.vers: scripts/vers.out\n\trm -f $@\n\tcp $? $@\n\nif DO_PNG_PREFIX\n# Rename functions in scripts/prefix.out with a PNG_PREFIX prefix.\n# Rename macros in scripts/macro.lst from PNG_PREFIXpng_ to PNG_ (the actual\n# implementation of the macro).\npnglibconf.h: pnglibconf.out scripts/prefix.out scripts/macro.lst\n\trm -f $@\n\t$(AWK) 's==0 && NR>1{print prev}\\\n\t   s==0{prev=$$0}\\\n\t   s==1{print \"#define\", $$1, \"@PNG_PREFIX@\" $$1}\\\n\t   s==2{print \"#define @PNG_PREFIX@png_\" $$1, \"PNG_\" $$1}\\\n\t   END{print prev}' s=0 pnglibconf.out s=1 scripts/prefix.out\\\n\t   s=2 ${srcdir}/scripts/macro.lst >pnglibconf.tf8\n\tmv pnglibconf.tf8 $@\n\npngprefix.h: scripts/intprefix.out\n\trm -f pngprefix.tf1\n\t$(AWK) '{print \"#define\", $$1, \"@PNG_PREFIX@\" $$1}' $? >pngprefix.tf1\n\tmv pngprefix.tf1 $@\nelse\npnglibconf.h: pnglibconf.out\n\trm -f $@\n\tcp $? $@\n\npngprefix.h: # is empty\n\t:>$@\nendif\n\n$(srcdir)/scripts/pnglibconf.h.prebuilt:\n\t@echo \"Attempting to build $@\" >&2\n\t@echo \"This is a machine generated file, but if you want to make\" >&2\n\t@echo \"a new one simply make 'scripts/pnglibconf.out', copy that\" >&2\n\t@echo \"AND set PNG_ZLIB_VERNUM to 0 (you MUST do this)\" >&2\n\t@exit 1\n\n# The following is necessary to ensure that the local pnglibconf.h is used, not\n# an installed one (this can happen immediately after on a clean system if\n# 'make test' is the first thing the user does.)  Only files which include\n# one of the png source files (typically png.h or pngpriv.h) need to be listed\n# here:\npngtest.o: pnglibconf.h\n\ncontrib/libtests/makepng.o: pnglibconf.h\ncontrib/libtests/pngstest.o: pnglibconf.h\ncontrib/libtests/pngunknown.o: pnglibconf.h\ncontrib/libtests/pngimage.o: pnglibconf.h\ncontrib/libtests/pngvalid.o: pnglibconf.h\ncontrib/libtests/readpng.o: pnglibconf.h\ncontrib/libtests/tarith.o: pnglibconf.h\ncontrib/libtests/timepng.o: pnglibconf.h\n\ncontrib/tools/makesRGB.o: pnglibconf.h\ncontrib/tools/pngfix.o: pnglibconf.h\n\n# We must use -DPNG_NO_USE_READ_MACROS here even when the library may actually\n# be built with PNG_USE_READ_MACROS; this prevents the read macros from\n# interfering with the symbol file format.\nSYMBOL_CFLAGS = -DPNGLIB_LIBNAME='PNG@PNGLIB_MAJOR@@PNGLIB_MINOR@_0'\\\n\t\t-DPNGLIB_VERSION='@PNGLIB_VERSION@'\\\n\t\t-DSYMBOL_PREFIX='$(SYMBOL_PREFIX)'\\\n\t\t-DPNG_NO_USE_READ_MACROS -DPNG_BUILDING_SYMBOL_TABLE\n\nif DO_PNG_PREFIX\nSYMBOL_CFLAGS += -DPNG_PREFIX='@PNG_PREFIX@'\nendif\n\n.c.out:\n\trm -f $@ $*.tf[12]\n\ttest -d scripts || mkdir scripts || test -d scripts\n\t$(DFNCPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)\\\n\t    $(CPPFLAGS) $(SYMBOL_CFLAGS) $< > $*.tf1\n\t$(AWK) -f \"${srcdir}/scripts/dfn.awk\" out=\"$*.tf2\" $*.tf1 1>&2\n\trm -f $*.tf1\n\tmv $*.tf2 $@\n\n# The .c file for pnglibconf.h is machine generated\npnglibconf.c: scripts/pnglibconf.dfa scripts/options.awk pngconf.h pngusr.dfa $(DFA_XTRA)\n\trm -f $@ $*.tf[45]\n\t$(AWK) -f ${srcdir}/scripts/options.awk out=$*.tf4 version=search\\\n\t    ${srcdir}/pngconf.h ${srcdir}/scripts/pnglibconf.dfa\\\n\t    ${srcdir}/pngusr.dfa $(DFA_XTRA) 1>&2\n\t$(AWK) -f ${srcdir}/scripts/options.awk out=$*.tf5 $*.tf4 1>&2\n\trm $*.tf4\n\tmv $*.tf5 $@\n\n# Symbol checks (.def and .out files should match)\nscripts/symbols.chk: scripts/checksym.awk scripts/symbols.def scripts/symbols.out\n\n.out.chk:\n\trm -f $@ $*.new\n\t$(AWK) -f ${srcdir}/scripts/checksym.awk ${srcdir}/scripts/${*F}.def\\\n\t    of=\"$*.new\" $< >&2\n\tmv $*.new $@\n\n# used on demand to regenerate the standard header, CPPFLAGS should\n# be empty - no non-standard defines\nscripts/pnglibconf.c: scripts/pnglibconf.dfa scripts/options.awk pngconf.h\n\trm -f $@ pnglibconf.tf[67]\n\ttest -z \"$(CPPFLAGS)\"\n\techo \"com @PNGLIB_VERSION@ STANDARD API DEFINITION\" |\\\n\t$(AWK) -f ${srcdir}/scripts/options.awk out=pnglibconf.tf6\\\n\t    logunsupported=1 version=search ${srcdir}/pngconf.h -\\\n\t    ${srcdir}/scripts/pnglibconf.dfa 1>&2\n\t$(AWK) -f ${srcdir}/scripts/options.awk out=pnglibconf.tf7\\\n\t    pnglibconf.tf6 1>&2\n\trm pnglibconf.tf6\n\tmv pnglibconf.tf7 $@\n\n$(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS): png.h pngconf.h \\\n\tpnglibconf.h pngpriv.h pngdebug.h pnginfo.h pngstruct.h pngprefix.h\n\ntest: check-am\n\n# Extra checks\ncheck: scripts/symbols.chk\n\n# Don't distribute the generated script files\ndist-hook:\n\tcd '$(top_distdir)'; rm -f $(SCRIPT_CLEANFILES)\n\n# Make links between installed files with release-specific names and the generic\n# file names.  If this install rule is run the generic names will be deleted and\n# recreated - this has obvious issues for systems with multiple installations.\n\ninstall-header-links:\n\t@set -ex; cd '$(DESTDIR)$(includedir)'; for f in $(HEADERS); do \\\n\t   rm -f \"$$f\"; $(LN_S) \"$(PNGLIB_BASENAME)/$$f\" \"$$f\"; done\n\nuninstall-header-links:\n\tcd '$(DESTDIR)$(includedir)'; rm -f $(HEADERS)\n\ninstall-libpng-pc:\n\t@set -ex; cd '$(DESTDIR)$(pkgconfigdir)'; rm -f libpng.pc; \\\n\t   $(LN_S) '$(PNGLIB_BASENAME).pc' libpng.pc\n\nuninstall-libpng-pc:\n\trm -f '$(DESTDIR)$(pkgconfigdir)/libpng.pc'\n\n# EXT_LIST is a list of the possibly library directory extensions, this exists\n# because we can't find a good way of discovering the file extensions that are\n# actually installed on a given system, so instead we check for every extension\n# we have seen.\n\nEXT_LIST = a dll.a so so.@PNGLIB_MAJOR@@PNGLIB_MINOR@.@PNGLIB_RELEASE@ la sl dylib\n\ninstall-library-links:\n\t@set -x; cd '$(DESTDIR)$(libdir)';\\\n\tfor ext in $(EXT_LIST); do\\\n\t   rm -f \"libpng.$$ext\";\\\n           if test -f \"$(PNGLIB_BASENAME).$$ext\"; then\\\n              $(LN_S) \"$(PNGLIB_BASENAME).$$ext\" \"libpng.$$ext\" || exit 1;\\\n           fi;\\\n\tdone\n\nuninstall-library-links:\n\t@set -x; cd '$(DESTDIR)$(libdir)'; for ext in $(EXT_LIST); do\\\n\t   rm -f \"libpng.$$ext\"; done\n\ninstall-libpng-config:\n\t@set -ex; cd '$(DESTDIR)$(bindir)'; rm -f libpng-config; \\\n\t   $(LN_S) '$(PNGLIB_BASENAME)-config' libpng-config\n\nuninstall-libpng-config:\n\trm -f '$(DESTDIR)$(bindir)/libpng-config'\n\nif DO_INSTALL_LINKS\n# If --enable-unversioned-links is specified the header and lib file links\n# will be automatically made on a 'make install':\n\ninstall-data-hook: install-header-links\nuninstall-hook: uninstall-header-links\ninstall-exec-hook: install-library-links\nuninstall-hook: uninstall-library-links\nendif\n\nif DO_INSTALL_LIBPNG_PC\n# Likewise, --install-pc causes libpng.pc to be constructed:\n\ninstall-data-hook: install-libpng-pc\nuninstall-hook: uninstall-libpng-pc\nendif\n\nif DO_INSTALL_LIBPNG_CONFIG\n# And --install-config:\n\ninstall-exec-hook: install-libpng-config\nuninstall-hook: uninstall-libpng-config\nendif\n\n# The following addition ensures that 'make all' always builds the test programs\n# too.  It used to, but some change either in libpng or configure stopped this\n# working.\nall-am: $(check_PROGRAMS)\n"
  },
  {
    "path": "atlas-aapt/external/libpng/README",
    "content": "README for libpng version 1.6.22beta03 - February 8, 2016 (shared library 16.0)\nSee the note about version numbers near the top of png.h\n\nSee INSTALL for instructions on how to install libpng.\n\nLibpng comes in several distribution formats.  Get libpng-*.tar.gz or\nlibpng-*.tar.xz or if you want UNIX-style line endings in the text files,\nor lpng*.7z or lpng*.zip if you want DOS-style line endings.\n\nVersion 0.89 was the first official release of libpng.  Don't let the\nfact that it's the first release fool you.  The libpng library has been in\nextensive use and testing since mid-1995.  By late 1997 it had\nfinally gotten to the stage where there hadn't been significant\nchanges to the API in some time, and people have a bad feeling about\nlibraries with versions < 1.0.  Version 1.0.0 was released in\nMarch 1998.\n\n****\nNote that some of the changes to the png_info structure render this\nversion of the library binary incompatible with libpng-0.89 or\nearlier versions if you are using a shared library.  The type of the\n\"filler\" parameter for png_set_filler() has changed from png_byte to\npng_uint_32, which will affect shared-library applications that use\nthis function.\n\nTo avoid problems with changes to the internals of png info_struct,\nnew APIs have been made available in 0.95 to avoid direct application\naccess to info_ptr.  These functions are the png_set_<chunk> and\npng_get_<chunk> functions.  These functions should be used when\naccessing/storing the info_struct data, rather than manipulating it\ndirectly, to avoid such problems in the future.\n\nIt is important to note that the APIs did not make current programs\nthat access the info struct directly incompatible with the new\nlibrary, through libpng-1.2.x.  In libpng-1.4.x, which was meant to\nbe a transitional release, members of the png_struct and the\ninfo_struct can still be accessed, but the compiler will issue a\nwarning about deprecated usage.  Since libpng-1.5.0, direct access\nto these structs is not allowed, and the definitions of the structs\nreside in private pngstruct.h and pnginfo.h header files that are not\naccessible to applications.  It is strongly suggested that new\nprograms use the new APIs (as shown in example.c and pngtest.c), and\nolder programs be converted to the new format, to facilitate upgrades\nin the future.\n****\n\nAdditions since 0.90 include the ability to compile libpng as a\nWindows DLL, and new APIs for accessing data in the info struct.\nExperimental functions include the ability to set weighting and cost\nfactors for row filter selection, direct reads of integers from buffers\non big-endian processors that support misaligned data access, faster\nmethods of doing alpha composition, and more accurate 16->8 bit color\nconversion.\n\nThe additions since 0.89 include the ability to read from a PNG stream\nwhich has had some (or all) of the signature bytes read by the calling\napplication.  This also allows the reading of embedded PNG streams that\ndo not have the PNG file signature.  As well, it is now possible to set\nthe library action on the detection of chunk CRC errors.  It is possible\nto set different actions based on whether the CRC error occurred in a\ncritical or an ancillary chunk.\n\nThe changes made to the library, and bugs fixed are based on discussions\non the PNG-implement mailing list and not on material submitted\nprivately to Guy, Andreas, or Glenn.  They will forward any good\nsuggestions to the list.\n\nFor a detailed description on using libpng, read libpng-manual.txt.  For\nexamples of libpng in a program, see example.c and pngtest.c.  For usage\ninformation and restrictions (what little they are) on libpng, see\npng.h.  For a description on using zlib (the compression library used by\nlibpng) and zlib's restrictions, see zlib.h\n\nI have included a general makefile, as well as several machine and\ncompiler specific ones, but you may have to modify one for your own needs.\n\nYou should use zlib 1.0.4 or later to run this, but it MAY work with\nversions as old as zlib 0.95.  Even so, there are bugs in older zlib\nversions which can cause the output of invalid compression streams for\nsome images.  You will definitely need zlib 1.0.4 or later if you are\ntaking advantage of the MS-DOS \"far\" structure allocation for the small\nand medium memory models.  You should also note that zlib is a\ncompression library that is useful for more things than just PNG files.\nYou can use zlib as a drop-in replacement for fread() and fwrite() if\nyou are so inclined.\n\nzlib should be available at the same place that libpng is, or at zlib.net.\n\nYou may also want a copy of the PNG specification.  It is available\nas an RFC, a W3C Recommendation, and an ISO/IEC Standard.  You can find\nthese at http://www.libpng.org/pub/png/documents/\n\nThis code is currently being archived at libpng.sf.net in the\n[DOWNLOAD] area, and at ftp://ftp.simplesystems.org.  If you can't find it\nin any of those places, e-mail me, and I'll help you find it.\n\nI am not a lawyer, but I believe that the Export Control Classification\nNumber (ECCN) for libpng is EAR99, which means not subject to export\ncontrols or International Traffic in Arms Regulations (ITAR) because it\nis open source, publicly available software, that does not contain any\nencryption software.  See the EAR, paragraphs 734.3(b)(3) and 734.7(b).\n\nIf you have any code changes, requests, problems, etc., please e-mail\nthem to me.  Also, I'd appreciate any make files or project files,\nand any modifications you needed to make to get libpng to compile,\nalong with a #define variable to tell what compiler/system you are on.\nIf you needed to add transformations to libpng, or wish libpng would\nprovide the image in a different way, drop me a note (and code, if\npossible), so I can consider supporting the transformation.\nFinally, if you get any warning messages when compiling libpng\n(note: not zlib), and they are easy to fix, I'd appreciate the\nfix.  Please mention \"libpng\" somewhere in the subject line.  Thanks.\n\nThis release was created and will be supported by myself (of course\nbased in a large way on Guy's and Andreas' earlier work), and the PNG\ndevelopment group.\n\nSend comments/corrections/commendations to png-mng-implement at\nlists.sourceforge.net (subscription required; visit\nhttps://lists.sourceforge.net/lists/listinfo/png-mng-implement\nto subscribe) or to glennrp at users.sourceforge.net\n\nYou can't reach Guy, the original libpng author, at the addresses\ngiven in previous versions of this document.  He and Andreas will\nread mail addressed to the png-implement list, however.\n\nPlease do not send general questions about PNG.  Send them to\npng-mng-misc at lists.sf.net (subscription required; visit\nhttps://lists.sourceforge.net/lists/listinfo/png-mng-misc to\nsubscribe).  If you have a question about something\nin the PNG specification that is related to using libpng, send it\nto me.  Send me any questions that start with \"I was using libpng,\nand ...\".  If in doubt, send questions to me.  I'll bounce them\nto others, if necessary.\n\nPlease do not send suggestions on how to change PNG.  We have\nbeen discussing PNG for twenty years now, and it is official and\nfinished.  If you have suggestions for libpng, however, I'll\ngladly listen.  Even if your suggestion is not used immediately,\nit may be used later.\n\nFiles in this distribution:\n\n      ANNOUNCE      =>  Announcement of this version, with recent changes\n      CHANGES       =>  Description of changes between libpng versions\n      KNOWNBUG      =>  List of known bugs and deficiencies\n      LICENSE       =>  License to use and redistribute libpng\n      README        =>  This file\n      TODO          =>  Things not implemented in the current library\n      Y2KINFO       =>  Statement of Y2K compliance\n      example.c     =>  Example code for using libpng functions\n      libpng.3      =>  manual page for libpng (includes libpng-manual.txt)\n      libpng-manual.txt  =>  Description of libpng and its functions\n      libpngpf.3    =>  manual page for libpng's private functions\n      png.5         =>  manual page for the PNG format\n      png.c         =>  Basic interface functions common to library\n      png.h         =>  Library function and interface declarations (public)\n      pngpriv.h     =>  Library function and interface declarations (private)\n      pngconf.h     =>  System specific library configuration (public)\n      pngstruct.h   =>  png_struct declaration (private)\n      pnginfo.h     =>  png_info struct declaration (private)\n      pngdebug.h    =>  debugging macros (private)\n      pngerror.c    =>  Error/warning message I/O functions\n      pngget.c      =>  Functions for retrieving info from struct\n      pngmem.c      =>  Memory handling functions\n      pngbar.png    =>  PNG logo, 88x31\n      pngnow.png    =>  PNG logo, 98x31\n      pngpread.c    =>  Progressive reading functions\n      pngread.c     =>  Read data/helper high-level functions\n      pngrio.c      =>  Lowest-level data read I/O functions\n      pngrtran.c    =>  Read data transformation functions\n      pngrutil.c    =>  Read data utility functions\n      pngset.c      =>  Functions for storing data into the info_struct\n      pngtest.c     =>  Library test program\n      pngtest.png   =>  Library test sample image\n      pngtrans.c    =>  Common data transformation functions\n      pngwio.c      =>  Lowest-level write I/O functions\n      pngwrite.c    =>  High-level write functions\n      pngwtran.c    =>  Write data transformations\n      pngwutil.c    =>  Write utility functions\n      arm           =>  Contains optimized code for the ARM platform\n      contrib       =>  Contributions\n       examples         =>  Example programs\n       gregbook         =>  source code for PNG reading and writing, from\n                            Greg Roelofs' \"PNG: The Definitive Guide\",\n                            O'Reilly, 1999\n       libtests         =>  Test programs\n       pngminim         =>  Minimal decoder, encoder, and progressive decoder\n                            programs demonstrating use of pngusr.dfa\n       pngminus         =>  Simple pnm2png and png2pnm programs\n       pngsuite         =>  Test images\n       tools            =>  Various tools\n       visupng          =>  Contains a MSVC workspace for VisualPng\n      projects      =>  Contains project files and workspaces for\n                        building a DLL\n       owatcom          =>  Contains a WATCOM project for building libpng\n       visualc71        =>  Contains a Microsoft Visual C++ (MSVC)\n                            workspace for building libpng and zlib\n       vstudio          =>  Contains a Microsoft Visual C++ (MSVC)\n                            workspace for building libpng and zlib\n      scripts       =>  Directory containing scripts for building libpng:\n                            (see scripts/README.txt for the list of scripts)\n\nGood luck, and happy coding.\n\n-Glenn Randers-Pehrson (current maintainer, since 1998)\n Internet: glennrp at users.sourceforge.net\n\n-Andreas Eric Dilger (former maintainer, 1996-1997)\n Internet: adilger at enel.ucalgary.ca\n Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/\n\n-Guy Eric Schalnat (original author and former maintainer, 1995-1996)\n (formerly of Group 42, Inc)\n Internet: gschal at infinet.com\n"
  },
  {
    "path": "atlas-aapt/external/libpng/README.android",
    "content": "Any Android specific modifications to upstream libpng (1.6.22beta) should\nbe listed here:\n\n(1) Android has added the following files.\n    pngusr.h\n    Android.mk\n    CleanSpec.mk\n    MODULE_LICENSE_BSD_LIKE\n    README.version\n\n(2) pnglibconf.h\n    This is copied from scripts/pnglibconf.h.prebuilt.\n    Android has undefined PNG_WARNINGS_SUPPORTED.\n\n(3) Removed contrib/testpngs/\n    There is no reason to check in all of these files if we won't\n    be using them.\n"
  },
  {
    "path": "atlas-aapt/external/libpng/README.version",
    "content": "URL: https://sourceforge.net/projects/libpng/files/libpng16/1.6.22beta02/libpng-1.6.22beta02.tar.gz/download\nVersion: 1.6.22beta\nBugComponent: 87896\n"
  },
  {
    "path": "atlas-aapt/external/libpng/TODO",
    "content": "/*\nTODO - list of things to do for libpng:\n\nFinal bug fixes.\nBetter C++ wrapper/full C++ implementation?\nFix problem with C++ and EXTERN \"C\".\ncHRM transformation.\nRemove setjmp/longjmp usage in favor of returning error codes.\nPalette creation.\nAdd \"grayscale->palette\" transformation and \"palette->grayscale\" detection.\nImproved dithering.\nMulti-lingual error and warning message support.\nComplete sRGB transformation (presently it simply uses gamma=0.45455).\nMake profile checking optional via a png_set_something() call.\nMan pages for function calls.\nBetter documentation.\nBetter filter selection\n   (counting huffman bits/precompression?  filter inertia?  filter costs?).\nHistogram creation.\nText conversion between different code pages (Latin-1 -> Mac and DOS).\nAvoid building gamma tables whenever possible.\nUse greater precision when changing to linear gamma for compositing against\n  background and doing rgb-to-gray transformation.\nInvestigate pre-incremented loop counters and other loop constructions.\nAdd interpolated method of handling interlacing.\nSwitch to the simpler zlib (zlib/libpng) license if legally possible.\nExtend pngvalid.c to validate more of the libpng transformations.\n\n*/\n"
  },
  {
    "path": "atlas-aapt/external/libpng/arm/arm_init.c",
    "content": "\n/* arm_init.c - NEON optimised filter functions\n *\n * Copyright (c) 2014 Glenn Randers-Pehrson\n * Written by Mans Rullgard, 2011.\n * Last changed in libpng 1.6.16 [December 22, 2014]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are\n * called.\n */\n#define _POSIX_SOURCE 1\n\n#include \"../pngpriv.h\"\n\n#ifdef PNG_READ_SUPPORTED\n\n#if PNG_ARM_NEON_OPT > 0\n#ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */\n/* WARNING: it is strongly recommended that you do not build libpng with\n * run-time checks for CPU features if at all possible.  In the case of the ARM\n * NEON instructions there is no processor-specific way of detecting the\n * presence of the required support, therefore run-time detection is extremely\n * OS specific.\n *\n * You may set the macro PNG_ARM_NEON_FILE to the file name of file containing\n * a fragment of C source code which defines the png_have_neon function.  There\n * are a number of implementations in contrib/arm-neon, but the only one that\n * has partial support is contrib/arm-neon/linux.c - a generic Linux\n * implementation which reads /proc/cpufino.\n */\n#ifndef PNG_ARM_NEON_FILE\n#  ifdef __linux__\n#     define PNG_ARM_NEON_FILE \"contrib/arm-neon/linux.c\"\n#  endif\n#endif\n\n#ifdef PNG_ARM_NEON_FILE\n\n#include <signal.h> /* for sig_atomic_t */\nstatic int png_have_neon(png_structp png_ptr);\n#include PNG_ARM_NEON_FILE\n\n#else  /* PNG_ARM_NEON_FILE */\n#  error \"PNG_ARM_NEON_FILE undefined: no support for run-time ARM NEON checks\"\n#endif /* PNG_ARM_NEON_FILE */\n#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */\n\n#ifndef PNG_ALIGNED_MEMORY_SUPPORTED\n#  error \"ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED\"\n#endif\n\nvoid\npng_init_filter_functions_neon(png_structp pp, unsigned int bpp)\n{\n   /* The switch statement is compiled in for ARM_NEON_API, the call to\n    * png_have_neon is compiled in for ARM_NEON_CHECK.  If both are defined\n    * the check is only performed if the API has not set the NEON option on\n    * or off explicitly.  In this case the check controls what happens.\n    *\n    * If the CHECK is not compiled in and the option is UNSET the behavior prior\n    * to 1.6.7 was to use the NEON code - this was a bug caused by having the\n    * wrong order of the 'ON' and 'default' cases.  UNSET now defaults to OFF,\n    * as documented in png.h\n    */\n#ifdef PNG_ARM_NEON_API_SUPPORTED\n   switch ((pp->options >> PNG_ARM_NEON) & 3)\n   {\n      case PNG_OPTION_UNSET:\n         /* Allow the run-time check to execute if it has been enabled -\n          * thus both API and CHECK can be turned on.  If it isn't supported\n          * this case will fall through to the 'default' below, which just\n          * returns.\n          */\n#endif /* PNG_ARM_NEON_API_SUPPORTED */\n#ifdef PNG_ARM_NEON_CHECK_SUPPORTED\n         {\n            static volatile sig_atomic_t no_neon = -1; /* not checked */\n\n            if (no_neon < 0)\n               no_neon = !png_have_neon(pp);\n\n            if (no_neon)\n               return;\n         }\n#ifdef PNG_ARM_NEON_API_SUPPORTED\n         break;\n#endif\n#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */\n\n#ifdef PNG_ARM_NEON_API_SUPPORTED\n      default: /* OFF or INVALID */\n         return;\n\n      case PNG_OPTION_ON:\n         /* Option turned on */\n         break;\n   }\n#endif\n\n   /* IMPORTANT: any new external functions used here must be declared using\n    * PNG_INTERNAL_FUNCTION in ../pngpriv.h.  This is required so that the\n    * 'prefix' option to configure works:\n    *\n    *    ./configure --with-libpng-prefix=foobar_\n    *\n    * Verify you have got this right by running the above command, doing a build\n    * and examining pngprefix.h; it must contain a #define for every external\n    * function you add.  (Notice that this happens automatically for the\n    * initialization function.)\n    */\n   pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon;\n\n   if (bpp == 3)\n   {\n      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon;\n      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon;\n      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =\n         png_read_filter_row_paeth3_neon;\n   }\n\n   else if (bpp == 4)\n   {\n      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon;\n      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon;\n      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =\n          png_read_filter_row_paeth4_neon;\n   }\n}\n#endif /* PNG_ARM_NEON_OPT > 0 */\n#endif /* READ */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/arm/filter_neon.S",
    "content": "\n/* filter_neon.S - NEON optimised filter functions\n *\n * Copyright (c) 2014 Glenn Randers-Pehrson\n * Written by Mans Rullgard, 2011.\n * Last changed in libpng 1.6.16 [December 22, 2014]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n/* This is required to get the symbol renames, which are #defines, and the\n * definitions (or not) of PNG_ARM_NEON_OPT and PNG_ARM_NEON_IMPLEMENTATION.\n */\n#define PNG_VERSION_INFO_ONLY\n#include \"../pngpriv.h\"\n\n#if defined(__linux__) && defined(__ELF__)\n.section .note.GNU-stack,\"\",%progbits /* mark stack as non-executable */\n#endif\n\n#ifdef PNG_READ_SUPPORTED\n\n/* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for\n * ARM64).  The code in arm/filter_neon_intrinsics.c supports ARM64, however it\n * only works if -mfpu=neon is specified on the GCC command line.  See pngpriv.h\n * for the logic which sets PNG_USE_ARM_NEON_ASM:\n */\n#if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */\n\n#if PNG_ARM_NEON_OPT > 0\n\n#ifdef __ELF__\n#   define ELF\n#else\n#   define ELF @\n#endif\n\n        .arch armv7-a\n        .fpu  neon\n\n.macro  func    name, export=0\n    .macro endfunc\nELF     .size   \\name, . - \\name\n        .endfunc\n        .purgem endfunc\n    .endm\n        .text\n\n        /* Explicitly specifying alignment here because some versions of\n         * GAS don't align code correctly.  This is harmless in correctly\n         * written versions of GAS.\n         */\n        .align 2\n\n    .if \\export\n        .global \\name\n    .endif\nELF     .type   \\name, STT_FUNC\n        .func   \\name\n\\name:\n.endm\n\nfunc    png_read_filter_row_sub4_neon, export=1\n        ldr             r3,  [r0, #4]           @ rowbytes\n        vmov.i8         d3,  #0\n1:\n        vld4.32         {d4[],d5[],d6[],d7[]},    [r1,:128]\n        vadd.u8         d0,  d3,  d4\n        vadd.u8         d1,  d0,  d5\n        vadd.u8         d2,  d1,  d6\n        vadd.u8         d3,  d2,  d7\n        vst4.32         {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!\n        subs            r3,  r3,  #16\n        bgt             1b\n\n        bx              lr\nendfunc\n\nfunc    png_read_filter_row_sub3_neon, export=1\n        ldr             r3,  [r0, #4]           @ rowbytes\n        vmov.i8         d3,  #0\n        mov             r0,  r1\n        mov             r2,  #3\n        mov             r12, #12\n        vld1.8          {q11},    [r0], r12\n1:\n        vext.8          d5,  d22, d23, #3\n        vadd.u8         d0,  d3,  d22\n        vext.8          d6,  d22, d23, #6\n        vadd.u8         d1,  d0,  d5\n        vext.8          d7,  d23, d23, #1\n        vld1.8          {q11},    [r0], r12\n        vst1.32         {d0[0]},  [r1,:32], r2\n        vadd.u8         d2,  d1,  d6\n        vst1.32         {d1[0]},  [r1], r2\n        vadd.u8         d3,  d2,  d7\n        vst1.32         {d2[0]},  [r1], r2\n        vst1.32         {d3[0]},  [r1], r2\n        subs            r3,  r3,  #12\n        bgt             1b\n\n        bx              lr\nendfunc\n\nfunc    png_read_filter_row_up_neon, export=1\n        ldr             r3,  [r0, #4]           @ rowbytes\n1:\n        vld1.8          {q0}, [r1,:128]\n        vld1.8          {q1}, [r2,:128]!\n        vadd.u8         q0,  q0,  q1\n        vst1.8          {q0}, [r1,:128]!\n        subs            r3,  r3,  #16\n        bgt             1b\n\n        bx              lr\nendfunc\n\nfunc    png_read_filter_row_avg4_neon, export=1\n        ldr             r12, [r0, #4]           @ rowbytes\n        vmov.i8         d3,  #0\n1:\n        vld4.32         {d4[],d5[],d6[],d7[]},    [r1,:128]\n        vld4.32         {d16[],d17[],d18[],d19[]},[r2,:128]!\n        vhadd.u8        d0,  d3,  d16\n        vadd.u8         d0,  d0,  d4\n        vhadd.u8        d1,  d0,  d17\n        vadd.u8         d1,  d1,  d5\n        vhadd.u8        d2,  d1,  d18\n        vadd.u8         d2,  d2,  d6\n        vhadd.u8        d3,  d2,  d19\n        vadd.u8         d3,  d3,  d7\n        vst4.32         {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!\n        subs            r12, r12, #16\n        bgt             1b\n\n        bx              lr\nendfunc\n\nfunc    png_read_filter_row_avg3_neon, export=1\n        push            {r4,lr}\n        ldr             r12, [r0, #4]           @ rowbytes\n        vmov.i8         d3,  #0\n        mov             r0,  r1\n        mov             r4,  #3\n        mov             lr,  #12\n        vld1.8          {q11},    [r0], lr\n1:\n        vld1.8          {q10},    [r2], lr\n        vext.8          d5,  d22, d23, #3\n        vhadd.u8        d0,  d3,  d20\n        vext.8          d17, d20, d21, #3\n        vadd.u8         d0,  d0,  d22\n        vext.8          d6,  d22, d23, #6\n        vhadd.u8        d1,  d0,  d17\n        vext.8          d18, d20, d21, #6\n        vadd.u8         d1,  d1,  d5\n        vext.8          d7,  d23, d23, #1\n        vld1.8          {q11},    [r0], lr\n        vst1.32         {d0[0]},  [r1,:32], r4\n        vhadd.u8        d2,  d1,  d18\n        vst1.32         {d1[0]},  [r1], r4\n        vext.8          d19, d21, d21, #1\n        vadd.u8         d2,  d2,  d6\n        vhadd.u8        d3,  d2,  d19\n        vst1.32         {d2[0]},  [r1], r4\n        vadd.u8         d3,  d3,  d7\n        vst1.32         {d3[0]},  [r1], r4\n        subs            r12, r12, #12\n        bgt             1b\n\n        pop             {r4,pc}\nendfunc\n\n.macro  paeth           rx,  ra,  rb,  rc\n        vaddl.u8        q12, \\ra, \\rb           @ a + b\n        vaddl.u8        q15, \\rc, \\rc           @ 2*c\n        vabdl.u8        q13, \\rb, \\rc           @ pa\n        vabdl.u8        q14, \\ra, \\rc           @ pb\n        vabd.u16        q15, q12, q15           @ pc\n        vcle.u16        q12, q13, q14           @ pa <= pb\n        vcle.u16        q13, q13, q15           @ pa <= pc\n        vcle.u16        q14, q14, q15           @ pb <= pc\n        vand            q12, q12, q13           @ pa <= pb && pa <= pc\n        vmovn.u16       d28, q14\n        vmovn.u16       \\rx, q12\n        vbsl            d28, \\rb, \\rc\n        vbsl            \\rx, \\ra, d28\n.endm\n\nfunc    png_read_filter_row_paeth4_neon, export=1\n        ldr             r12, [r0, #4]           @ rowbytes\n        vmov.i8         d3,  #0\n        vmov.i8         d20, #0\n1:\n        vld4.32         {d4[],d5[],d6[],d7[]},    [r1,:128]\n        vld4.32         {d16[],d17[],d18[],d19[]},[r2,:128]!\n        paeth           d0,  d3,  d16, d20\n        vadd.u8         d0,  d0,  d4\n        paeth           d1,  d0,  d17, d16\n        vadd.u8         d1,  d1,  d5\n        paeth           d2,  d1,  d18, d17\n        vadd.u8         d2,  d2,  d6\n        paeth           d3,  d2,  d19, d18\n        vmov            d20, d19\n        vadd.u8         d3,  d3,  d7\n        vst4.32         {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!\n        subs            r12, r12, #16\n        bgt             1b\n\n        bx              lr\nendfunc\n\nfunc    png_read_filter_row_paeth3_neon, export=1\n        push            {r4,lr}\n        ldr             r12, [r0, #4]           @ rowbytes\n        vmov.i8         d3,  #0\n        vmov.i8         d4,  #0\n        mov             r0,  r1\n        mov             r4,  #3\n        mov             lr,  #12\n        vld1.8          {q11},    [r0], lr\n1:\n        vld1.8          {q10},    [r2], lr\n        paeth           d0,  d3,  d20, d4\n        vext.8          d5,  d22, d23, #3\n        vadd.u8         d0,  d0,  d22\n        vext.8          d17, d20, d21, #3\n        paeth           d1,  d0,  d17, d20\n        vst1.32         {d0[0]},  [r1,:32], r4\n        vext.8          d6,  d22, d23, #6\n        vadd.u8         d1,  d1,  d5\n        vext.8          d18, d20, d21, #6\n        paeth           d2,  d1,  d18, d17\n        vext.8          d7,  d23, d23, #1\n        vld1.8          {q11},    [r0], lr\n        vst1.32         {d1[0]},  [r1], r4\n        vadd.u8         d2,  d2,  d6\n        vext.8          d19, d21, d21, #1\n        paeth           d3,  d2,  d19, d18\n        vst1.32         {d2[0]},  [r1], r4\n        vmov            d4,  d19\n        vadd.u8         d3,  d3,  d7\n        vst1.32         {d3[0]},  [r1], r4\n        subs            r12, r12, #12\n        bgt             1b\n\n        pop             {r4,pc}\nendfunc\n#endif /* PNG_ARM_NEON_OPT > 0 */\n#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */\n#endif /* READ */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/arm/filter_neon_intrinsics.c",
    "content": "\n/* filter_neon_intrinsics.c - NEON optimised filter functions\n *\n * Copyright (c) 2014 Glenn Randers-Pehrson\n * Written by James Yu <james.yu at linaro.org>, October 2013.\n * Based on filter_neon.S, written by Mans Rullgard, 2011.\n *\n * Last changed in libpng 1.6.16 [December 22, 2014]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n#include \"../pngpriv.h\"\n\n#ifdef PNG_READ_SUPPORTED\n\n/* This code requires -mfpu=neon on the command line: */\n#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */\n\n#include <arm_neon.h>\n\n/* libpng row pointers are not necessarily aligned to any particular boundary,\n * however this code will only work with appropriate alignment.  arm/arm_init.c\n * checks for this (and will not compile unless it is done). This code uses\n * variants of png_aligncast to avoid compiler warnings.\n */\n#define png_ptr(type,pointer) png_aligncast(type *,pointer)\n#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer)\n\n/* The following relies on a variable 'temp_pointer' being declared with type\n * 'type'.  This is written this way just to hide the GCC strict aliasing\n * warning; note that the code is safe because there never is an alias between\n * the input and output pointers.\n */\n#define png_ldr(type,pointer)\\\n   (temp_pointer = png_ptr(type,pointer), *temp_pointer)\n\n#if PNG_ARM_NEON_OPT > 0\n\nvoid\npng_read_filter_row_up_neon(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev_row)\n{\n   png_bytep rp = row;\n   png_bytep rp_stop = row + row_info->rowbytes;\n   png_const_bytep pp = prev_row;\n\n   for (; rp < rp_stop; rp += 16, pp += 16)\n   {\n      uint8x16_t qrp, qpp;\n\n      qrp = vld1q_u8(rp);\n      qpp = vld1q_u8(pp);\n      qrp = vaddq_u8(qrp, qpp);\n      vst1q_u8(rp, qrp);\n   }\n}\n\nvoid\npng_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev_row)\n{\n   png_bytep rp = row;\n   png_bytep rp_stop = row + row_info->rowbytes;\n\n   uint8x16_t vtmp = vld1q_u8(rp);\n   uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp);\n   uint8x8x2_t vrp = *vrpt;\n\n   uint8x8x4_t vdest;\n   vdest.val[3] = vdup_n_u8(0);\n\n   for (; rp < rp_stop;)\n   {\n      uint8x8_t vtmp1, vtmp2;\n      uint32x2_t *temp_pointer;\n\n      vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);\n      vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);\n      vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6);\n      vdest.val[1] = vadd_u8(vdest.val[0], vtmp1);\n\n      vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);\n      vdest.val[2] = vadd_u8(vdest.val[1], vtmp2);\n      vdest.val[3] = vadd_u8(vdest.val[2], vtmp1);\n\n      vtmp = vld1q_u8(rp + 12);\n      vrpt = png_ptr(uint8x8x2_t, &vtmp);\n      vrp = *vrpt;\n\n      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);\n      rp += 3;\n      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);\n      rp += 3;\n      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);\n      rp += 3;\n      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);\n      rp += 3;\n   }\n\n   PNG_UNUSED(prev_row)\n}\n\nvoid\npng_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev_row)\n{\n   png_bytep rp = row;\n   png_bytep rp_stop = row + row_info->rowbytes;\n\n   uint8x8x4_t vdest;\n   vdest.val[3] = vdup_n_u8(0);\n\n   for (; rp < rp_stop; rp += 16)\n   {\n      uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp));\n      uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp);\n      uint8x8x4_t vrp = *vrpt;\n      uint32x2x4_t *temp_pointer;\n\n      vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);\n      vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]);\n      vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]);\n      vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]);\n      vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);\n   }\n\n   PNG_UNUSED(prev_row)\n}\n\nvoid\npng_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev_row)\n{\n   png_bytep rp = row;\n   png_const_bytep pp = prev_row;\n   png_bytep rp_stop = row + row_info->rowbytes;\n\n   uint8x16_t vtmp;\n   uint8x8x2_t *vrpt;\n   uint8x8x2_t vrp;\n   uint8x8x4_t vdest;\n   vdest.val[3] = vdup_n_u8(0);\n\n   vtmp = vld1q_u8(rp);\n   vrpt = png_ptr(uint8x8x2_t,&vtmp);\n   vrp = *vrpt;\n\n   for (; rp < rp_stop; pp += 12)\n   {\n      uint8x8_t vtmp1, vtmp2, vtmp3;\n\n      uint8x8x2_t *vppt;\n      uint8x8x2_t vpp;\n\n      uint32x2_t *temp_pointer;\n\n      vtmp = vld1q_u8(pp);\n      vppt = png_ptr(uint8x8x2_t,&vtmp);\n      vpp = *vppt;\n\n      vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);\n      vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);\n      vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);\n\n      vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);\n      vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6);\n      vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2);\n      vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);\n\n      vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6);\n      vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);\n\n      vtmp = vld1q_u8(rp + 12);\n      vrpt = png_ptr(uint8x8x2_t,&vtmp);\n      vrp = *vrpt;\n\n      vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2);\n      vdest.val[2] = vadd_u8(vdest.val[2], vtmp3);\n\n      vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);\n\n      vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2);\n      vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);\n\n      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);\n      rp += 3;\n      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);\n      rp += 3;\n      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);\n      rp += 3;\n      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);\n      rp += 3;\n   }\n}\n\nvoid\npng_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev_row)\n{\n   png_bytep rp = row;\n   png_bytep rp_stop = row + row_info->rowbytes;\n   png_const_bytep pp = prev_row;\n\n   uint8x8x4_t vdest;\n   vdest.val[3] = vdup_n_u8(0);\n\n   for (; rp < rp_stop; rp += 16, pp += 16)\n   {\n      uint32x2x4_t vtmp;\n      uint8x8x4_t *vrpt, *vppt;\n      uint8x8x4_t vrp, vpp;\n      uint32x2x4_t *temp_pointer;\n\n      vtmp = vld4_u32(png_ptr(uint32_t,rp));\n      vrpt = png_ptr(uint8x8x4_t,&vtmp);\n      vrp = *vrpt;\n      vtmp = vld4_u32(png_ptrc(uint32_t,pp));\n      vppt = png_ptr(uint8x8x4_t,&vtmp);\n      vpp = *vppt;\n\n      vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);\n      vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);\n      vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]);\n      vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);\n      vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]);\n      vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);\n      vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]);\n      vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);\n\n      vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);\n   }\n}\n\nstatic uint8x8_t\npaeth(uint8x8_t a, uint8x8_t b, uint8x8_t c)\n{\n   uint8x8_t d, e;\n   uint16x8_t p1, pa, pb, pc;\n\n   p1 = vaddl_u8(a, b); /* a + b */\n   pc = vaddl_u8(c, c); /* c * 2 */\n   pa = vabdl_u8(b, c); /* pa */\n   pb = vabdl_u8(a, c); /* pb */\n   pc = vabdq_u16(p1, pc); /* pc */\n\n   p1 = vcleq_u16(pa, pb); /* pa <= pb */\n   pa = vcleq_u16(pa, pc); /* pa <= pc */\n   pb = vcleq_u16(pb, pc); /* pb <= pc */\n\n   p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */\n\n   d = vmovn_u16(pb);\n   e = vmovn_u16(p1);\n\n   d = vbsl_u8(d, b, c);\n   e = vbsl_u8(e, a, d);\n\n   return e;\n}\n\nvoid\npng_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev_row)\n{\n   png_bytep rp = row;\n   png_const_bytep pp = prev_row;\n   png_bytep rp_stop = row + row_info->rowbytes;\n\n   uint8x16_t vtmp;\n   uint8x8x2_t *vrpt;\n   uint8x8x2_t vrp;\n   uint8x8_t vlast = vdup_n_u8(0);\n   uint8x8x4_t vdest;\n   vdest.val[3] = vdup_n_u8(0);\n\n   vtmp = vld1q_u8(rp);\n   vrpt = png_ptr(uint8x8x2_t,&vtmp);\n   vrp = *vrpt;\n\n   for (; rp < rp_stop; pp += 12)\n   {\n      uint8x8x2_t *vppt;\n      uint8x8x2_t vpp;\n      uint8x8_t vtmp1, vtmp2, vtmp3;\n      uint32x2_t *temp_pointer;\n\n      vtmp = vld1q_u8(pp);\n      vppt = png_ptr(uint8x8x2_t,&vtmp);\n      vpp = *vppt;\n\n      vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast);\n      vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);\n\n      vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);\n      vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);\n      vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]);\n      vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);\n\n      vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6);\n      vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6);\n      vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2);\n      vdest.val[2] = vadd_u8(vdest.val[2], vtmp1);\n\n      vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);\n      vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);\n\n      vtmp = vld1q_u8(rp + 12);\n      vrpt = png_ptr(uint8x8x2_t,&vtmp);\n      vrp = *vrpt;\n\n      vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3);\n      vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);\n\n      vlast = vtmp2;\n\n      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);\n      rp += 3;\n      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);\n      rp += 3;\n      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);\n      rp += 3;\n      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);\n      rp += 3;\n   }\n}\n\nvoid\npng_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev_row)\n{\n   png_bytep rp = row;\n   png_bytep rp_stop = row + row_info->rowbytes;\n   png_const_bytep pp = prev_row;\n\n   uint8x8_t vlast = vdup_n_u8(0);\n   uint8x8x4_t vdest;\n   vdest.val[3] = vdup_n_u8(0);\n\n   for (; rp < rp_stop; rp += 16, pp += 16)\n   {\n      uint32x2x4_t vtmp;\n      uint8x8x4_t *vrpt, *vppt;\n      uint8x8x4_t vrp, vpp;\n      uint32x2x4_t *temp_pointer;\n\n      vtmp = vld4_u32(png_ptr(uint32_t,rp));\n      vrpt = png_ptr(uint8x8x4_t,&vtmp);\n      vrp = *vrpt;\n      vtmp = vld4_u32(png_ptrc(uint32_t,pp));\n      vppt = png_ptr(uint8x8x4_t,&vtmp);\n      vpp = *vppt;\n\n      vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast);\n      vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);\n      vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]);\n      vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);\n      vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]);\n      vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);\n      vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]);\n      vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);\n\n      vlast = vpp.val[3];\n\n      vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);\n   }\n}\n\n#endif /* PNG_ARM_NEON_OPT > 0 */\n#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */\n#endif /* READ */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/autogen.sh",
    "content": "#! /bin/sh\n#\n# Run 'autoreconf' to build 'configure', 'Makefile.in' and other configure\n# control files.\n#\n# The first time this is run on a GIT checkout the only files that exist are\n# configure.ac and Makefile.am; all of the autotools support scripts are\n# missing.  They are instantiated with autoreconf --force --install.\n#\n# For regular (\"tarball\") distributions all the files should exist.  We do not\n# want them to be updated *under any circumstances*.  It should never be\n# necessary to run autogen.sh because ./configure --enable-maintainer-mode says\n# what to do if Makefile.am or configure.ac are changed.\n#\n# It is *probably* OK to update the files on a GIT checkout, because they have\n# come from the local tools, but leave that to the user who is assumed to know\n# whether it is ok or required.\n#\n# This script is intended to work without arguments, there are, however, hidden\n# arguments (a) for use while testing the script and (b) to fix up systems that\n# have been broken.  If (b) is required the script prompts for the correct\n# options.  For this reason the options are *NOT* documented in the help; this\n# is deliberate; UTSL.\n#\nclean=\nmaintainer=\nwhile test $# -gt 0\ndo\n   case \"$1\" in\n      --maintainer)\n         maintainer=1;;\n\n      --clean)\n         clean=1;;\n\n      *)\n         exec >&2\n         echo \"$0: usage: ./autogen.sh\"\n         if test -d .git\n         then\n            echo \"  ./autogen.sh generates the configure script and\"\n            echo \"  Makefile.in, or refreshes them after changes to Makefile.am\"\n            echo \"  or configure.ac.  You may prefer to just run autoreconf.\"\n         elif test -z \"$maintainer\"\n         then\n            echo \"  DO NOT RUN THIS SCRIPT.\"\n            echo \"  If you need to change Makefile.am or configure.ac then you\"\n            echo \"  also need to run ./configure --enable-maintainer-mode and\"\n            echo \"  use the appropriate autotools, *NOT* this script, to update\"\n            echo \"  everything, please check the documentation of autoreconf.\"\n            echo \"  WARNING: libpng is intentionally generated with a known,\"\n            echo \"  fixed, set of autotools.  It is known *NOT* to work with\"\n            echo \"  the collection of autotools distributed on highly reputable\"\n            echo \"  operating systems.\"\n            echo \"  Remember: autotools is GNU software, you are expected to\"\n            echo \"  pay for support.\"\n         else\n            echo \"  You have run autogen.sh with --maintainer enabled and you\"\n            echo \"  are not using a GIT distribution, then you have given an\"\n            echo \"  unrecognized argument.  This is not good. --maintainer\"\n            echo \"  switches off any assumptions that you might not know what\"\n            echo \"  you are doing.\"\n         fi\n         exit 1;;\n   esac\n\n   shift\ndone\n#\n# First check for a set of the autotools files; if absent then this is assumed\n# to be a GIT version and the local autotools must be used.  If present this\n# is a tarball distribution and the script should not be used.  If partially\n# present bad things are happening.\n#\n# The autotools generated files:\nlibpng_autotools_files=\"Makefile.in aclocal.m4 config.guess config.h.in\n   config.sub configure depcomp install-sh ltmain.sh missing\\\n   test-driver\"\n#\n# Files generated by versions of configue >2.68 or automake >1.13 (i.e. later\n# versions than those required by configure.ac):\nlibpng_autotools_extra=\"compile config.h.in~\"\n#\n# These are separate because 'maintainer-clean' does not remove them.\nlibpng_libtool_files=\"scripts/libtool.m4 scripts/ltoptions.m4\\\n   scripts/ltsugar.m4 scripts/ltversion.m4 scripts/lt~obsolete.m4\"\n\nlibpng_autotools_dirs=\"autom4te.cache\" # not required\n#\n# The configure generated files:\nlibpng_configure_files=\"Makefile config.h config.log config.status\\\n   libpng-config libpng.pc libtool stamp-h1\"\n\nlibpng_configure_dirs=\".deps\"\n#\n# We must remove the configure generated files as well as the autotools\n# generated files if autotools are regenerated because otherwise if configure\n# has been run without \"--enable-maintainer-mode\" make can do a partial update\n# of Makefile.  These functions do the two bits of cleaning.\nclean_autotools(){\n   rm -rf $libpng_autotools_files $libpng_libtool_files $libpng_autotools_dirs\n   rm -rf $libpng_autotools_extra\n}\n\nclean_configure(){\n   rm -rf $libpng_configure_files $libpng_configure_dirs\n}\n#\n# Clean: remove everything (this is to help with testing)\nif test -n \"$clean\"\nthen\n   clean_configure\n   if test -n \"$maintainer\"\n   then\n      clean_autotools\n   fi\n\n   exit 0\nfi\n#\n# Validate the distribution.\nlibpng_autotools_file_found=\nlibpng_autotools_file_missing=\nfor file in $libpng_autotools_files\ndo\n   if test -f  \"$file\"\n   then\n      libpng_autotools_file_found=1\n   else\n      libpng_autotools_file_missing=1\n   fi\ndone\n#\n# Presence of one of these does not *invalidate* missing, but absence\n# invalidates found.\nfor file in $libpng_libtool_files\ndo\n   if test ! -f \"$file\"\n   then\n      libpng_autotools_file_missing=1\n   fi\ndone\n#\n# The cache directory doesn't matter - it will be regenerated and does not exist\n# anyway in a tarball.\n#\n# Either everything is missing or everything is there, the --maintainer option\n# just changes this so that the mode is set to generate all the files.\nmode=\nif test -z \"$libpng_autotools_file_found\" -o -n \"$maintainer\"\nthen\n   mode=\"autoreconf\"\nelse\n   if test -n \"$libpng_autotools_file_missing\"\n   then\n      mode=\"broken\"\n   else\n      mode=\"configure\"\n   fi\nfi\n#\n# So:\ncase \"$mode\" in\n   autoreconf)\n      # Clean in case configure files exist\n      clean_configure\n      clean_autotools\n      # Everything must be initialized, so use --force\n      if autoreconf --warnings=all --force --install\n      then\n         missing=\n         for file in $libpng_autotools_files\n         do\n            test -f \"$file\" || missing=1\n         done\n         # ignore the cache directory\n         test -z \"$missing\" || {\n            exec >&2\n            echo \"autoreconf was run, but did not produce all the expected\"\n            echo \"files.  It is likely that your autotools installation is\"\n            echo \"not compatible with that expected by libpng.\"\n            exit 1\n         }\n      else\n         exec >&2\n         echo \"autoreconf failed: your version of autotools is incompatible\"\n         echo \"with this libpng version.  Please use a distributed archive\"\n         echo \"(which includes the autotools generated files) and run configure\"\n         echo \"instead.\"\n         exit 1\n      fi;;\n\n   configure)\n      if test -d .git\n      then\n         exec >&2\n         echo \"ERROR: running autoreconf on an initialized sytem\"\n         echo \"  This is not necessary; it is only necessary to remake the\"\n         echo \"  autotools generated files if Makefile.am or configure.ac\"\n         echo \"  change and make does the right thing with:\"\n         echo\n         echo \"     ./configure --enable-maintainer-mode.\"\n         echo\n         echo \"  You can run autoreconf yourself if you don't like maintainer\"\n         echo \"  mode and you can also just run autoreconf -f -i to initialize\"\n         echo \"  everything in the first place; this script is only for\"\n         echo \"  compatibility with prior releases.\"\n         exit 1\n      else\n         exec >&2\n         echo \"autogen.sh is intended only to generate 'configure' on systems\"\n         echo \"that do not have it.  You have a complete 'configure', if you\"\n         echo \"need to change Makefile.am or configure.ac you also need to\"\n         echo \"run configure with the --enable-maintainer-mode option.\"\n         exit 1\n      fi;;\n\n   broken)\n      exec >&2\n      echo \"Your system has a partial set of autotools generated files.\"\n      echo \"autogen.sh is unable to proceed.  The full set of files is\"\n      echo \"contained in the libpng 'tar' distribution archive and you do\"\n      echo \"not need to run autogen.sh if you use it.\"\n      exit 1;;\nesac\n"
  },
  {
    "path": "atlas-aapt/external/libpng/configure.ac",
    "content": "# configure.ac\n\ndnl Process this file with autoconf to produce a configure script.\ndnl\ndnl Minor upgrades (compatible ABI): increment the package version\ndnl (third field in two places below) and set the PNGLIB_RELEASE\ndnl variable.\ndnl\ndnl Major upgrades (incompatible ABI): increment the package major\ndnl version (second field, or first if desired), set the minor\ndnl to 0, set PNGLIB_MAJOR below *and* follow the instructions in\ndnl Makefile.am to upgrade the package name.\n\ndnl This is here to prevent earlier autoconf from being used, it\ndnl should not be necessary to regenerate configure if the time\ndnl stamps are correct\nAC_PREREQ([2.68])\n\ndnl Version number stuff here:\n\nAC_INIT([libpng],[1.6.22beta03],[png-mng-implement@lists.sourceforge.net])\nAC_CONFIG_MACRO_DIR([scripts])\n\n# libpng does not follow GNU file name conventions (hence 'foreign')\n# color-tests requires automake 1.11 or later\n# silent-rules requires automake 1.11 or later\n# dist-xz requires automake 1.11 or later\n# 1.12.2 fixes a security issue in 1.11.2 and 1.12.1\n# 1.13 is required for parallel tests\nAM_INIT_AUTOMAKE([1.13 foreign dist-xz color-tests silent-rules subdir-objects])\n# The following line causes --disable-maintainer-mode to be the default to\n# configure, this is necessary because libpng distributions cannot rely on the\n# time stamps of the autotools generated files being correct\nAM_MAINTAINER_MODE\n\ndnl configure.ac and Makefile.am expect automake 1.11.2 or a compatible later\ndnl version; aclocal.m4 will generate a failure if you use a prior version of\ndnl automake, so the following is not necessary (and is not defined anyway):\ndnl AM_PREREQ([1.11.2])\ndnl stop configure from automagically running automake\n\nPNGLIB_VERSION=1.6.22beta03\nPNGLIB_MAJOR=1\nPNGLIB_MINOR=6\nPNGLIB_RELEASE=22\n\ndnl End of version number stuff\n\nAC_CONFIG_SRCDIR([pngget.c])\nAC_CONFIG_HEADERS([config.h])\n\n# Checks for programs.\nAC_LANG([C])\nAC_PROG_CC\nAM_PROG_AS\nLT_PATH_LD\nAC_PROG_CPP\nAC_PROG_AWK\nAC_PROG_INSTALL\nAC_PROG_LN_S\nAC_PROG_MAKE_SET\n\ndnl libtool/libtoolize; version 2.4.2 is the tested version, this or any\ndnl compatible later version may be used\nLT_INIT([win32-dll])\nLT_PREREQ([2.4.2])\n\n# Some awks crash when confronted with pnglibconf.dfa, do a test run now\n# to make sure this doesn't happen\nAC_MSG_CHECKING([that AWK works])\nif ${AWK} -f ${srcdir}/scripts/options.awk out=\"/dev/null\" version=search\\\n   ${srcdir}/pngconf.h ${srcdir}/scripts/pnglibconf.dfa\\\n   ${srcdir}/pngusr.dfa 1>&2\nthen\n   AC_MSG_RESULT([ok])\nelse\n   AC_MSG_FAILURE([failed], 1)\nfi\n\n# This is a remnant of the old cc -E validation, where it may have been\n# necessary to use a different preprocessor for .dfn files\nDFNCPP=\"$CPP\"\nAC_SUBST(DFNCPP)\n\n# -Werror cannot be passed to GCC in CFLAGS because configure will fail (it\n# checks the compiler with a program that generates a warning), add the\n# following option to deal with this\nAC_ARG_VAR(PNG_COPTS,\n   [additional flags for the C compiler, use this for options that would]\n   [cause configure itself to fail])\nAC_ARG_ENABLE(werror,\n   AS_HELP_STRING([[[--enable-werror[=OPT]]]],\n      [Pass -Werror or the given argument to the compiler if it is supported]),\n   [test \"$enable_werror\" = \"yes\" && enable_werror=\"-Werror\"\n    if test \"$enable_werror\" != \"no\"; then\n      sav_CFLAGS=\"$CFLAGS\"\n      CFLAGS=\"$enable_werror $CFLAGS\"\n      AC_MSG_CHECKING([if the compiler allows $enable_werror])\n      AC_COMPILE_IFELSE(\n         [AC_LANG_SOURCE([\n            [int main(int argc, char **argv){]\n            [return argv[argc-1][0];]\n            [}]])],\n         AC_MSG_RESULT(yes)\n         PNG_COPTS=\"$PNG_COPTS $enable_werror\",\n         AC_MSG_RESULT(no))\n      CFLAGS=\"$sav_CFLAGS\"\n    fi],)\n\n# Checks for header files.\nAC_HEADER_STDC\n\n# Checks for typedefs, structures, and compiler characteristics.\nAC_C_CONST\nAC_TYPE_SIZE_T\nAC_STRUCT_TM\nAC_C_RESTRICT\n\n# Checks for library functions.\nAC_FUNC_STRTOD\nAC_CHECK_FUNCS([memset], , AC_MSG_ERROR(memset not found in libc))\nAC_CHECK_FUNCS([pow], , AC_CHECK_LIB(m, pow, , AC_MSG_ERROR(cannot find pow)) )\nAC_ARG_WITH(zlib-prefix,\n   AS_HELP_STRING([[[--with-zlib-prefix]]],\n      [prefix that may have been used in installed zlib]),\n      [ZPREFIX=${withval}],\n      [ZPREFIX='z_'])\nAC_CHECK_LIB(z, zlibVersion, ,\n    AC_CHECK_LIB(z, ${ZPREFIX}zlibVersion, , AC_MSG_ERROR(zlib not installed)))\n\n# The following is for pngvalid, to ensure it catches FP errors even on\n# platforms that don't enable FP exceptions, the function appears in the math\n# library (typically), it's not an error if it is not found.\nAC_CHECK_LIB([m], [feenableexcept])\nAC_CHECK_FUNCS([feenableexcept])\n\nAC_MSG_CHECKING([if using Solaris linker])\nSLD=`$LD --version 2>&1 | grep Solaris`\nif test \"$SLD\"; then\n    have_solaris_ld=yes\n    AC_MSG_RESULT(yes)\nelse\n    have_solaris_ld=no\n    AC_MSG_RESULT(no)\nfi\nAM_CONDITIONAL(HAVE_SOLARIS_LD, test \"$have_solaris_ld\" = \"yes\")\n\nAC_MSG_CHECKING([if libraries can be versioned])\n# Special case for PE/COFF platforms: ld reports\n# support for version-script, but doesn't actually\n# DO anything with it.\ncase $host in\n*cygwin* | *mingw32* | *interix* )\n    have_ld_version_script=no\n    AC_MSG_RESULT(no)\n;;\n* )\n\nif test \"$have_solaris_ld\" = \"yes\"; then\n    GLD=`$LD --help < /dev/null 2>&1 | grep 'M mapfile'`\nelse\n    GLD=`$LD --help < /dev/null 2>/dev/null | grep version-script`\nfi\n\nif test \"$GLD\"; then\n    have_ld_version_script=yes\n    AC_MSG_RESULT(yes)\nelse\n    have_ld_version_script=no\n    AC_MSG_RESULT(no)\n    AC_MSG_WARN(*** You have not enabled versioned symbols.)\nfi\n;;\nesac\n\nAM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test \"$have_ld_version_script\" = \"yes\")\n\nif test \"$have_ld_version_script\" = \"yes\"; then\n    AC_MSG_CHECKING([for symbol prefix])\n    SYMBOL_PREFIX=`echo \"PREFIX=__USER_LABEL_PREFIX__\" \\\n                  | ${CPP-${CC-gcc} -E} - 2>&1 \\\n                  | ${EGREP-grep} \"^PREFIX=\" \\\n                  | ${SED-sed} -e \"s:^PREFIX=::\" -e \"s:__USER_LABEL_PREFIX__::\"`\n    AC_SUBST(SYMBOL_PREFIX)\n    AC_MSG_RESULT($SYMBOL_PREFIX)\nfi\n\n# Substitutions for .in files\nAC_SUBST(PNGLIB_VERSION)\nAC_SUBST(PNGLIB_MAJOR)\nAC_SUBST(PNGLIB_MINOR)\nAC_SUBST(PNGLIB_RELEASE)\n\n# Additional arguments (and substitutions)\n# Allow the pkg-config directory to be set\nAC_ARG_WITH(pkgconfigdir,\n   AS_HELP_STRING([[[--with-pkgconfigdir]]],\n      [Use the specified pkgconfig dir (default is libdir/pkgconfig)]),\n   [pkgconfigdir=${withval}],\n   [pkgconfigdir='${libdir}/pkgconfig'])\n\nAC_SUBST([pkgconfigdir])\nAC_MSG_NOTICE([[pkgconfig directory is ${pkgconfigdir}]])\n\n# Make the *-config binary config scripts optional\nAC_ARG_WITH(binconfigs,\n   AS_HELP_STRING([[[--with-binconfigs]]],\n      [Generate shell libpng-config scripts as well as pkg-config data]\n      [@<:@default=yes@:>@]),\n   [if test \"${withval}\" = no; then\n      binconfigs=\n      AC_MSG_NOTICE([[libpng-config scripts will not be built]])\n    else\n      binconfigs='${binconfigs}'\n    fi],\n   [binconfigs='${binconfigs}'])\nAC_SUBST([binconfigs])\n\n# Support for prefixes to the API function names; this will generate defines\n# at the start of the build to rename exported library functions\nAC_ARG_WITH(libpng-prefix,\n   AS_HELP_STRING([[[--with-libpng-prefix]]],\n      [prefix libpng exported function (API) names with the given value]),\n   [if test \"${withval:-no}\" != \"no\"; then\n      AC_SUBST([PNG_PREFIX], [${withval}])\n    fi])\nAM_CONDITIONAL([DO_PNG_PREFIX], [test \"${with_libpng_prefix:-no}\" != \"no\"])\n\n# Control over what links are made for installed files.  Versioned files are\n# always installed, when the following options are turned on corresponding\n# unversioned links are also created (normally as symbolic links):\nAC_ARG_ENABLE([unversioned-links],\n   AS_HELP_STRING([[[--enable-unversioned-links]]],\n      [Installed libpng header files are placed in a versioned subdirectory]\n      [and installed libpng library (including DLL) files are versioned.]\n      [If this option is enabled unversioned links will be created pointing to]\n      [the corresponding installed files.  If you use libpng.pc or]\n      [libpng-config for all builds you do not need these links, but if you]\n      [compile programs directly they will typically #include <png.h> and]\n      [link with -lpng; in that case you need the links.]\n      [The links can be installed manually using 'make install-header-links']\n      [and 'make install-library-links' and can be removed using the]\n      [corresponding uninstall- targets.  If you do enable this option every]\n      [libpng 'make install' will recreate the links to point to the just]\n      [installed version of libpng.  The default is to create the links;]\n      [use --disable-unversioned-links to change this]))\n\n# The AM_CONDITIONAL test is written so that the default is enabled;\n# --disable-unversioned-links must be given to turn the option off.\nAM_CONDITIONAL([DO_INSTALL_LINKS],[test \"$enable_unversioned_links\" != \"no\"])\n\nAC_ARG_ENABLE([unversioned-libpng-pc],\n   AS_HELP_STRING([[[--enable-unversioned-libpng-pc]]],\n      [Install the configuration file 'libpng.pc' as a link to the versioned]\n      [version.  This is done by default - use --disable-unversioned-libpng-pc]\n      [to change this.]))\nAM_CONDITIONAL([DO_INSTALL_LIBPNG_PC],\n   [test \"$enable_unversioned_libpng_pc\" != \"no\"])\n\nAC_ARG_ENABLE([unversioned-libpng-config],\n   AS_HELP_STRING([[[--enable-unversioned-libpng-config]]],\n      [Install the configuration file 'libpng-config' as a link to the]\n      [versioned version.  This is done by default - use]\n      [--disable-unversioned-libpng-config to change this.]))\nAM_CONDITIONAL([DO_INSTALL_LIBPNG_CONFIG],\n   [test \"$enable_unversioned_libpng_config\" != \"no\"])\n\n# HOST SPECIFIC OPTIONS\n# =====================\n#\n# ARM\n# ===\n#\n# ARM NEON (SIMD) support.\n\nAC_ARG_ENABLE([arm-neon],\n   AS_HELP_STRING([[[--enable-arm-neon]]],\n      [Enable ARM NEON optimizations: =no/off, check, api, yes/on:]\n      [no/off: disable the optimizations; check: use internal checking code]\n      [(deprecated and poorly supported); api: disable by default, enable by]\n      [a call to png_set_option; yes/on: turn on unconditionally.]\n      [If not specified: determined by the compiler.]),\n   [case \"$enableval\" in\n      no|off)\n         # disable the default enabling on __ARM_NEON__ systems:\n         AC_DEFINE([PNG_ARM_NEON_OPT], [0],\n                   [Disable ARM Neon optimizations])\n         # Prevent inclusion of the assembler files below:\n         enable_arm_neon=no;;\n      check)\n         AC_DEFINE([PNG_ARM_NEON_CHECK_SUPPORTED], [],\n                   [Check for ARM Neon support at run-time]);;\n      api)\n         AC_DEFINE([PNG_ARM_NEON_API_SUPPORTED], [],\n                   [Turn on ARM Neon optimizations at run-time]);;\n      yes|on)\n         AC_DEFINE([PNG_ARM_NEON_OPT], [2],\n                   [Enable ARM Neon optimizations])\n         AC_MSG_WARN([--enable-arm-neon: please specify 'check' or 'api', if]\n            [you want the optimizations unconditionally pass -mfpu=neon]\n            [to the compiler.]);;\n      *)\n         AC_MSG_ERROR([--enable-arm-neon=${enable_arm_neon}: invalid value])\n   esac])\n\n# Add ARM specific files to all builds where the host_cpu is arm ('arm*') or\n# where ARM optimizations were explicitly requested (this allows a fallback if a\n# future host CPU does not match 'arm*')\n\nAM_CONDITIONAL([PNG_ARM_NEON],\n   [test \"$enable_arm_neon\" != 'no' &&\n    case \"$host_cpu\" in\n      arm*|aarch64*) :;;\n      *)    test \"$enable_arm_neon\" != '';;\n    esac])\n\nAC_MSG_NOTICE([[Extra options for compiler: $PNG_COPTS]])\n\n# Config files, substituting as above\nAC_CONFIG_FILES([Makefile libpng.pc:libpng.pc.in])\nAC_CONFIG_FILES([libpng-config:libpng-config.in],\n   [chmod +x libpng-config])\n\nAC_OUTPUT\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/README.txt",
    "content": "\nThis \"contrib\" directory contains contributions which are not necessarily under\nthe libpng license, although all are open source.  They are not part of\nlibpng proper and are not used for building the library, although some are used\nfor testing the library via \"make check\".\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/arm-neon/README",
    "content": "OPERATING SYSTEM SPECIFIC ARM NEON DETECTION\n--------------------------------------------\n\nDetection of the ability to execute ARM NEON on an ARM processor requires\noperating system support.  (The information is not available in user mode.)\n\nHOW TO USE THIS\n---------------\n\nThis directory contains C code fragments that can be included in arm/arm_init.c\nby setting the macro PNG_ARM_NEON_FILE to the file name in \"\" or <> at build\ntime.  This setting is not recorded in pnglibconf.h and can be changed simply by\nrebuilding arm/arm_init.o with the required macro definition.\n\nFor any of this code to be used the ARM NEON code must be enabled and run time\nchecks must be supported.  I.e.:\n\n#if PNG_ARM_NEON_OPT > 0\n#ifdef PNG_ARM_NEON_CHECK_SUPPORTED\n\nThis is done in a 'configure' build by passing configure the argument:\n\n   --enable-arm-neon=check\n\nApart from the basic Linux implementation in contrib/arm-neon/linux.c this code\nis unsupported.  That means that it is not even compiled on a regular basis and\nmay be broken in any given minor release.\n\nFILE FORMAT\n-----------\n\nEach file documents its testing status as of the last time it was tested (which\nmay have been a long time ago):\n\nSTATUS: one of:\n   SUPPORTED: This indicates that the file is included in the regularly\n         performed test builds and bugs are fixed when discovered.\n   COMPILED: This indicates that the code did compile at least once.  See the\n         more detailed description for the extent to which the result was\n         successful.\n   TESTED: This means the code was fully compiled into the libpng test programs\n         and these were run at least once.\n\nBUG REPORTS: an email address to which to send reports of problems\n\nThe file is a fragment of C code. It should not define any 'extern' symbols;\neverything should be static.  It must define the function:\n\nstatic int png_have_neon(png_structp png_ptr);\n\nThat function must return 1 if ARM NEON instructions are supported, 0 if not.\nIt must not execute png_error unless it detects a bug.  A png_error will prevent\nthe reading of the PNG and in the future, writing too.\n\nBUG REPORTS\n-----------\n\nIf you mail a bug report for any file that is not SUPPORTED there may only be\nlimited response.  Consider fixing it and sending a patch to fix the problem -\nthis is more likely to result in action.\n\nCONTRIBUTIONS\n-------------\n\nYou may send contributions of new implementations to\npng-mng-implement@sourceforge.net.  Please write code in strict C90 C where\npossible.  Obviously OS dependencies are to be expected.  If you submit code you\nmust have the authors permission and it must have a license that is acceptable\nto the current maintainer; in particular that license must permit modification\nand redistribution.\n\nPlease try to make the contribution a single file and give the file a clear and\nunambiguous name that identifies the target OS.  If multiple files really are\nrequired put them all in a sub-directory.\n\nYou must also be prepared to handle bug reports from users of the code, either\nby joining the png-mng-implement mailing list or by providing an email for the\n\"BUG REPORTS\" entry or both.  Please make sure that the header of the file\ncontains the STATUS and BUG REPORTS fields as above.\n\nPlease list the OS requirements as precisely as possible.  Ideally you should\nalso list the environment in which the code has been tested and certainly list\nany environments where you suspect it might not work.\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/arm-neon/android-ndk.c",
    "content": "/* contrib/arm-neon/android-ndk.c\n *\n * Copyright (c) 2014 Glenn Randers-Pehrson\n * Written by John Bowler, 2014.\n * Last changed in libpng 1.6.10 [March 6, 2014]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * SEE contrib/arm-neon/README before reporting bugs\n *\n * STATUS: COMPILED, UNTESTED\n * BUG REPORTS: png-mng-implement@sourceforge.net\n *\n * png_have_neon implemented for the Android NDK, see:\n *\n * Documentation:\n *    http://www.kandroid.org/ndk/docs/CPU-ARM-NEON.html\n *    http://code.google.com/p/android/issues/detail?id=49065\n *\n * NOTE: this requires that libpng is built against the Android NDK and linked\n * with an implementation of the Android ARM 'cpu-features' library.  The code\n * has been compiled only, not linked: no version of the library has been found,\n * only the header files exist in the NDK.\n */\n#include <cpu-features.h>\n\nstatic int\npng_have_neon(png_structp png_ptr)\n{\n   /* This is a whole lot easier than the linux code, however it is probably\n    * implemented as below, therefore it is better to cache the result (these\n    * function calls may be slow!)\n    */\n   PNG_UNUSED(png_ptr)\n   return android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM &&\n      (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/arm-neon/linux-auxv.c",
    "content": "/* contrib/arm-neon/linux-auxv.c\n *\n * Copyright (c) 2014 Glenn Randers-Pehrson\n * Written by Mans Rullgard, 2011.\n * Last changed in libpng 1.6.10 [March 6, 2014]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * SEE contrib/arm-neon/README before reporting bugs\n *\n * STATUS: COMPILED, TESTED\n * BUG REPORTS: png-mng-implement@sourceforge.net\n *\n * png_have_neon implemented for Linux versions which allow access to\n * /proc/self/auxv.  This is probably faster, cleaner and safer than the code to\n * read /proc/cpuinfo in contrib/arm-neon/linux, however it is yet another piece\n * of potentially untested code and has more complex dependencies than the code\n * to read cpuinfo.\n *\n * This generic __linux__ implementation requires reading /proc/self/auxv and\n * looking at each element for one that records NEON capabilities.\n */\n#include <unistd.h> /* for POSIX 1003.1 */\n#include <errno.h>  /* for EINTR */\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <elf.h>\n#include <asm/hwcap.h>\n\n/* A read call may be interrupted, in which case it returns -1 and sets errno to\n * EINTR if nothing was done, otherwise (if something was done) a partial read\n * may result.\n */\nstatic size_t\nsafe_read(png_structp png_ptr, int fd, void *buffer_in, size_t nbytes)\n{\n   size_t ntotal = 0;\n   char *buffer = png_voidcast(char*, buffer_in);\n\n   while (nbytes > 0)\n   {\n      unsigned int nread;\n      int iread;\n\n      /* Passing nread > INT_MAX to read is implementation defined in POSIX\n       * 1003.1, therefore despite the unsigned argument portable code must\n       * limit the value to INT_MAX!\n       */\n      if (nbytes > INT_MAX)\n         nread = INT_MAX;\n\n      else\n         nread = (unsigned int)/*SAFE*/nbytes;\n\n      iread = read(fd, buffer, nread);\n\n      if (iread == -1)\n      {\n         /* This is the devil in the details, a read can terminate early with 0\n          * bytes read because of EINTR, yet it still returns -1 otherwise end\n          * of file cannot be distinguished.\n          */\n         if (errno != EINTR)\n         {\n            png_warning(png_ptr, \"/proc read failed\");\n            return 0; /* I.e., a permanent failure */\n         }\n      }\n\n      else if (iread < 0)\n      {\n         /* Not a valid 'read' result: */\n         png_warning(png_ptr, \"OS /proc read bug\");\n         return 0;\n      }\n\n      else if (iread > 0)\n      {\n         /* Continue reading until a permanent failure, or EOF */\n         buffer += iread;\n         nbytes -= (unsigned int)/*SAFE*/iread;\n         ntotal += (unsigned int)/*SAFE*/iread;\n      }\n\n      else\n         return ntotal;\n   }\n\n   return ntotal; /* nbytes == 0 */\n}\n\nstatic int\npng_have_neon(png_structp png_ptr)\n{\n   int fd = open(\"/proc/self/auxv\", O_RDONLY);\n   Elf32_auxv_t aux;\n\n   /* Failsafe: failure to open means no NEON */\n   if (fd == -1)\n   {\n      png_warning(png_ptr, \"/proc/self/auxv open failed\");\n      return 0;\n   }\n\n   while (safe_read(png_ptr, fd, &aux, sizeof aux) == sizeof aux)\n   {\n      if (aux.a_type == AT_HWCAP && (aux.a_un.a_val & HWCAP_NEON) != 0)\n      {\n         close(fd);\n         return 1;\n      }\n   }\n\n   close(fd);\n   return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/arm-neon/linux.c",
    "content": "/* contrib/arm-neon/linux.c\n *\n * Copyright (c) 2014 Glenn Randers-Pehrson\n * Written by John Bowler, 2014.\n * Last changed in libpng 1.6.16 [December 22, 2014]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * SEE contrib/arm-neon/README before reporting bugs\n *\n * STATUS: SUPPORTED\n * BUG REPORTS: png-mng-implement@sourceforge.net\n *\n * png_have_neon implemented for Linux by reading the widely available\n * pseudo-file /proc/cpuinfo.\n *\n * This code is strict ANSI-C and is probably moderately portable; it does\n * however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.\n */\n#include <stdio.h>\n\nstatic int\npng_have_neon(png_structp png_ptr)\n{\n   FILE *f = fopen(\"/proc/cpuinfo\", \"rb\");\n\n   if (f != NULL)\n   {\n      /* This is a simple state machine which reads the input byte-by-byte until\n       * it gets a match on the 'neon' feature or reaches the end of the stream.\n       */\n      static const char ch_feature[] = { 70, 69, 65, 84, 85, 82, 69, 83 };\n      static const char ch_neon[] = { 78, 69, 79, 78 };\n\n      enum\n      {\n         StartLine, Feature, Colon, StartTag, Neon, HaveNeon, SkipTag, SkipLine\n      }  state;\n      int counter;\n\n      for (state=StartLine, counter=0;;)\n      {\n         int ch = fgetc(f);\n\n         if (ch == EOF)\n         {\n            /* EOF means error or end-of-file, return false; neon at EOF is\n             * assumed to be a mistake.\n             */\n            fclose(f);\n            return 0;\n         }\n\n         switch (state)\n         {\n            case StartLine:\n               /* Match spaces at the start of line */\n               if (ch <= 32) /* skip control characters and space */\n                  break;\n\n               counter=0;\n               state = Feature;\n               /* FALL THROUGH */\n\n            case Feature:\n               /* Match 'FEATURE', ASCII case insensitive. */\n               if ((ch & ~0x20) == ch_feature[counter])\n               {\n                  if (++counter == (sizeof ch_feature))\n                     state = Colon;\n                  break;\n               }\n\n               /* did not match 'feature' */\n               state = SkipLine;\n               /* FALL THROUGH */\n\n            case SkipLine:\n            skipLine:\n               /* Skip everything until we see linefeed or carriage return */\n               if (ch != 10 && ch != 13)\n                  break;\n\n               state = StartLine;\n               break;\n\n            case Colon:\n               /* Match any number of space or tab followed by ':' */\n               if (ch == 32 || ch == 9)\n                  break;\n\n               if (ch == 58) /* i.e. ':' */\n               {\n                  state = StartTag;\n                  break;\n               }\n\n               /* Either a bad line format or a 'feature' prefix followed by\n                * other characters.\n                */\n               state = SkipLine;\n               goto skipLine;\n\n            case StartTag:\n               /* Skip space characters before a tag */\n               if (ch == 32 || ch == 9)\n                  break;\n\n               state = Neon;\n               counter = 0;\n               /* FALL THROUGH */\n\n            case Neon:\n               /* Look for 'neon' tag */\n               if ((ch & ~0x20) == ch_neon[counter])\n               {\n                  if (++counter == (sizeof ch_neon))\n                     state = HaveNeon;\n                  break;\n               }\n\n               state = SkipTag;\n               /* FALL THROUGH */\n\n            case SkipTag:\n               /* Skip non-space characters */\n               if (ch == 10 || ch == 13)\n                  state = StartLine;\n\n               else if (ch == 32 || ch == 9)\n                  state = StartTag;\n               break;\n\n            case HaveNeon:\n               /* Have seen a 'neon' prefix, but there must be a space or new\n                * line character to terminate it.\n                */\n               if (ch == 10 || ch == 13 || ch == 32 || ch == 9)\n               {\n                  fclose(f);\n                  return 1;\n               }\n\n               state = SkipTag;\n               break;\n\n            default:\n               png_error(png_ptr, \"png_have_neon: internal error (bug)\");\n         }\n      }\n   }\n\n#ifdef PNG_WARNINGS_SUPPORTED\n   else\n      png_warning(png_ptr, \"/proc/cpuinfo open failed\");\n#endif\n\n   return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/conftest/README",
    "content": "This directory contains test configuration files, currently always '.dfa' files\nintended to be used in the build by setting the make macro DFA_XTRA to the name\nof the file.\n\nThese files are used in release validation of the 'configure' builds of libpng\nby building 'make check', or 'make all-am' for cross-builds, with each .dfa\nfile.\n\nThe files in this directory may change between minor releases, however\ncontributions describing specific builds of libpng are welcomed.  There is no\nguarantee that libpng will continue to build with such configurations; support\nfor given configurations can be, and has been, dropped between successive minor\nreleases.  However if a .dfa file describing a configuration is not in this\ndirectory it is very unlikely that it will be tested before a minor release!\n\nYou can use these .dfa files as the basis of new configurations.  Files in this\ndirectory should not have any use restrictions or restrictive licenses.\n\nThis directory is not included in the .zip and .7z distributions, which do\nnot contain 'configure' scripts.\n\nDOCUMENTATION\n=============\n\nExamples:\n   ${srcdir}/pngusr.dfa\n   ${srcdir}/contrib/pngminim/*/pngusr.dfa\n\nDocumentation of the options:\n   ${srcdir}/scripts/pnglibconf.dfa\n\nDocumentation of the file format:\n   ${srcdir}/scripts/options.awk\n\nFILE NAMING\n===========\n\nFile names in this directory may NOT contain any of the five characters:\n\n   - , + * ?\n\nNeither may they contain any space character.\n\nWhile other characters may be used it is strongly suggested that file names be\nlimited to lower case Latiin alphabetic characters (a-z), digits (0-9) and, if\nnecessary the underscore (_) character.  File names should be about 8 characters\nlong (excluding the .dfa extension).  Submitted .dfa files should have names\nbetween 7 and 16 characters long, shorter names (6 characters or less) are\nreserved for standard tests.\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/conftest/read.dfa",
    "content": "# read.dfa\n#  Build time configuration of libpng\n#\n# Author: John Bowler\n# Copyright: (c) John Bowler, 2013\n# Usage rights:\n#  To the extent possible under law, the author has waived all copyright and\n#  related or neighboring rights to this work.  This work is published from:\n#  United States.\n#\n# Build libpng with basic read support.  This enables the lowest level libpng\n# read API - the one where the calling code has to use a loop to read each row.\n# At present this is the API used by most programs.\n#\n# Support is enabled only for those chunks and transformations that are\n# typically required - others can be added easily.\n#\n\neverything = off\n\n# The sequential read code is enabled here; the progressive code can be used\n# instead but there is no point enabling both.\n\noption SEQUENTIAL_READ on\n\n# Likewise it is pointless enabling both fixed and floating point APIs.  Choose\n# one or the other for both the API and the internal math.\n\n#Fixed point:\n#option FIXED_POINT on\n#option FLOATING_ARITHMETIC off\n\n#Floating point:\noption FLOATING_POINT on\noption FLOATING_ARITHMETIC on\n\n# Basic error handling, IO and user memory support.  The latter allows the\n# application program to provide its own implementations of 'malloc' and 'free'.\noption SETJMP on\noption STDIO on\noption USER_MEM on\n\n# To read the full set of PNG images correctly interlace, transparency and\n# 16-bit support is required.  The application can implement interlace itself,\n# but very few do and it's no longer possible to disable it when READ is\n# enabled.\noption READ_tRNS on\noption READ_16BIT on\n\n# Everything else is application dependent.  This file assumes the app handles\n# all the native PNG bit layouts, so it doesn't need any of layout change\n# transforms, but needs libpng to perform gamma correction.  It doesn't do any\n# colorspace stuff and ignores the 'significant bit' information.\n#\n# If your app always expands the image to a limited set of bit layouts you\n# probably want to consider using the simplified API instead of the low level\n# one - see png.h and s_read.dfa.\noption READ_GAMMA on\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/conftest/s_read.dfa",
    "content": "# s_read.dfa\n#  Build time configuration of libpng\n#\n# Author: John Bowler\n# Copyright: (c) John Bowler, 2013\n# Usage rights:\n#  To the extent possible under law, the author has waived all copyright and\n#  related or neighboring rights to this work.  This work is published from:\n#  United States.\n#\n# Build libpng with simplified read support (only).  This builds a minimal\n# libpng able to read all PNG formats and convert them into a small number of\n# well understood memory formats.\n#\n\neverything = off\n\noption SIMPLIFIED_READ on\n\n# It isn't necessary to chose fixed or floating point for the APIs because the\n# simplified API doesn't need fixed or floating point numbers.  It is necessary\n# to chose an internal math implementation.  The default (because of 'everything\n# = off') is fixed point - turn the floating point implementation on if you have\n# hardware floating point or prefer your software floating point implementation.\noption FLOATING_ARITHMETIC on\n\n# This is not strictly necessary, but without it the message strings in the API\n# will not be filled in\noption ERROR_TEXT on\n\n# Switching these options on enables the 'AFIRST' and 'BGR' formats - you don't\n# need this if you don't use them, they just allow the in-memory layout to be\n# changed to match common hardware formats.\noption SIMPLIFIED_READ_AFIRST on\noption SIMPLIFIED_READ_BGR on\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/conftest/s_write.dfa",
    "content": "# s_write.dfa\n#  Build time configuration of libpng\n#\n# Author: John Bowler\n# Copyright: (c) John Bowler, 2013\n# Usage rights:\n#  To the extent possible under law, the author has waived all copyright and\n#  related or neighboring rights to this work.  This work is published from:\n#  United States.\n#\n# Build libpng with (just) simplified write support\n#\n\neverything = off\n\noption SIMPLIFIED_WRITE on\n\n# It isn't necessary to chose fixed or floating point for the APIs because the\n# simplified API doesn't need fixed or floating point numbers.  It is necessary\n# to chose an internal math implementation.  The default (because of 'everything\n# = off') is fixed point - turn the floating point implementation on if you have\n# hardware floating point or prefer your software floating point implementation.\noption FLOATING_ARITHMETIC on\n\n# This is not strictly necessary, but without it the message strings in the API\n# will not be filled in\noption ERROR_TEXT on\n\n# Switching these options on enables the 'AFIRST' and 'BGR' formats - you don't\n# need this if you don't use them, they just allow the in-memory layout to be\n# changed to match common hardware formats.\noption SIMPLIFIED_WRITE_AFIRST on\noption SIMPLIFIED_WRITE_BGR on\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/conftest/simple.dfa",
    "content": "# simple.dfa\n#  Build time configuration of libpng\n#\n# Author: John Bowler\n# Copyright: (c) John Bowler, 2013\n# Usage rights:\n#  To the extent possible under law, the author has waived all copyright and\n#  related or neighboring rights to this work.  This work is published from:\n#  United States.\n#\n# Build libpng with just the simplified APIs (read and write).\n#\n\neverything = off\n\noption SIMPLIFIED_WRITE on\noption SIMPLIFIED_READ on\n\n# It isn't necessary to chose fixed or floating point for the APIs because the\n# simplified API doesn't need fixed or floating point numbers.  It is necessary\n# to chose an internal math implementation.  The default (because of 'everything\n# = off') is fixed point - turn the floating point implementation on if you have\n# hardware floating point or prefer your software floating point implementation.\noption FLOATING_ARITHMETIC on\n\n# This is not strictly necessary, but without it the message strings in the API\n# will not be filled in\noption ERROR_TEXT on\n\n# Switching these options on enables the 'AFIRST' and 'BGR' formats - you don't\n# need this if you don't use them, they just allow the in-memory layout to be\n# changed to match common hardware formats.\noption SIMPLIFIED_READ_AFIRST on\noption SIMPLIFIED_READ_BGR on\noption SIMPLIFIED_WRITE_AFIRST on\noption SIMPLIFIED_WRITE_BGR on\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/conftest/write.dfa",
    "content": "# write.dfa\n#  Build time configuration of libpng\n#\n# Author: John Bowler\n# Copyright: (c) John Bowler, 2013\n# Usage rights:\n#  To the extent possible under law, the author has waived all copyright and\n#  related or neighboring rights to this work.  This work is published from:\n#  United States.\n#\n# Build libpng with no read support and minimal write support.\n#\n\neverything = off\n\n# Switch on the write code - this makes a minimalist encoder\n\noption WRITE on\n\n# Choose fixed or floating point APIs and arithmetic.  The choices are\n# independent but normally they will match.  It is typically better to use the\n# floating point if you have floating point hardware.  If you don't know, or\n# (perhaps) to make libpng smaller used fixed point throughout.\n\n#Fixed point:\n#option FIXED_POINT on\n#option FLOATING_ARITHMETIC off\n\n#Floating point:\noption FLOATING_POINT on\noption FLOATING_ARITHMETIC on\n\n# Basic error handling, IO and user memory support.  The latter allows the\n# application program to provide its own implementations of 'malloc' and 'free'.\noption SETJMP on\noption STDIO on\noption USER_MEM on\n\n# Everything else is optional.  Unlike the read code in libpng the write code\n# does not need to deal with arbitrary formats, so only add support for things\n# you really do write!  For example you might only write sRGB images, sometimes\n# with transparency and never write 16 bit images, so:\noption WRITE_sRGB on\noption WRITE_tRNS on\n#option WRITE_16BIT off (this is the default with 'everything = off')\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/examples/README.txt",
    "content": "\nThis directory (contrib/examples) contains examples of libpng usage.\n\nNO COPYRIGHT RIGHTS ARE CLAIMED TO ANY OF THE FILES IN THIS DIRECTORY.\n\nTo the extent possible under law, the authors have waived all copyright and\nrelated or neighboring rights to this work.  This work is published from:\nUnited States.\n\nThe files may be used freely in any way.  The intention is that appropriate\nparts of the files be used in other libpng-using programs without any need for\nthe authors of the using code to seek copyright or license from the original\nauthors.\n\nThe source code and comments in this directory are the original work of the\npeople named below.  No other person or organization has made contributions to\nthe work in this directory.\n\nORIGINAL AUTHORS\n    The following people have contributed to the code in this directory.  None\n    of the people below claim any rights with regard to the contents of this\n    directory.\n\n    John Bowler <jbowler@acm.org>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/examples/iccfrompng.c",
    "content": "/*- iccfrompng\n *\n * COPYRIGHT: Written by John Cunningham Bowler, 2011.\n * To the extent possible under law, the author has waived all copyright and\n * related or neighboring rights to this work.  This work is published from:\n * United States.\n *\n * Extract any icc profiles found in the given PNG files.  This is a simple\n * example of a program that extracts information from the header of a PNG file\n * without processing the image.  Notice that some header information may occur\n * after the image data. Textual data and comments are an example; the approach\n * in this file won't work reliably for such data because it only looks for the\n * information in the section of the file that preceeds the image data.\n *\n * Compile and link against libpng and zlib, plus anything else required on the\n * system you use.\n *\n * To use supply a list of PNG files containing iCCP chunks, the chunks will be\n * extracted to a similarly named file with the extension replaced by 'icc',\n * which will be overwritten without warning.\n */\n#include <stdlib.h>\n#include <setjmp.h>\n#include <string.h>\n#include <stdio.h>\n\n#include <png.h>\n\nstatic int verbose = 1;\nstatic png_byte no_profile[] = \"no profile\";\n\nstatic png_bytep\nextract(FILE *fp, png_uint_32 *proflen)\n{\n   png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);\n   png_infop info_ptr = NULL;\n   png_bytep result = NULL;\n\n   /* Initialize for error or no profile: */\n   *proflen = 0;\n\n   if (png_ptr == NULL)\n   {\n      fprintf(stderr, \"iccfrompng: version library mismatch?\\n\");\n      return 0;\n   }\n\n   if (setjmp(png_jmpbuf(png_ptr)))\n   {\n      png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n      return 0;\n   }\n\n   png_init_io(png_ptr, fp);\n\n   info_ptr = png_create_info_struct(png_ptr);\n   if (info_ptr == NULL)\n      png_error(png_ptr, \"OOM allocating info structure\");\n\n   png_read_info(png_ptr, info_ptr);\n\n   {\n      png_charp name;\n      int compression_type;\n      png_bytep profile;\n\n      if (png_get_iCCP(png_ptr, info_ptr, &name, &compression_type, &profile,\n         proflen) & PNG_INFO_iCCP)\n      {\n         result = malloc(*proflen);\n         if (result != NULL)\n            memcpy(result, profile, *proflen);\n\n         else\n            png_error(png_ptr, \"OOM allocating profile buffer\");\n      }\n\n      else\n\tresult = no_profile;\n   }\n\n   png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n   return result;\n}\n\nstatic int\nextract_one_file(const char *filename)\n{\n   int result = 0;\n   FILE *fp = fopen(filename, \"rb\");\n\n   if (fp != NULL)\n   {\n      png_uint_32 proflen = 0;\n      png_bytep profile = extract(fp, &proflen);\n\n      if (profile != NULL && profile != no_profile)\n      {\n         size_t len;\n         char *output;\n\n         {\n            const char *ep = strrchr(filename, '.');\n\n            if (ep != NULL)\n               len = ep-filename;\n\n            else\n               len = strlen(filename);\n         }\n\n         output = malloc(len + 5);\n         if (output != NULL)\n         {\n            FILE *of;\n\n            memcpy(output, filename, len);\n            strcpy(output+len, \".icc\");\n\n            of = fopen(output, \"wb\");\n            if (of != NULL)\n            {\n               if (fwrite(profile, proflen, 1, of) == 1 &&\n                  fflush(of) == 0 &&\n                  fclose(of) == 0)\n               {\n                  if (verbose)\n                     printf(\"%s -> %s\\n\", filename, output);\n                  /* Success return */\n                  result = 1;\n               }\n\n               else\n               {\n                  fprintf(stderr, \"%s: error writing profile\\n\", output);\n                  if (remove(output))\n                     fprintf(stderr, \"%s: could not remove file\\n\", output);\n               }\n            }\n\n            else\n               fprintf(stderr, \"%s: failed to open output file\\n\", output);\n\n            free(output);\n         }\n\n         else\n            fprintf(stderr, \"%s: OOM allocating string!\\n\", filename);\n\n         free(profile);\n      }\n\n      else if (verbose && profile == no_profile)\n\tprintf(\"%s has no profile\\n\", filename);\n   }\n\n   else\n      fprintf(stderr, \"%s: could not open file\\n\", filename);\n\n   return result;\n}\n\nint\nmain(int argc, char **argv)\n{\n   int i;\n   int extracted = 0;\n\n   for (i=1; i<argc; ++i)\n   {\n      if (strcmp(argv[i], \"-q\") == 0)\n         verbose = 0;\n\n      else if (extract_one_file(argv[i]))\n         extracted = 1;\n   }\n\n   /* Exit code is true if any extract succeeds */\n   return extracted == 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/examples/pngpixel.c",
    "content": "/*- pngpixel\n *\n * COPYRIGHT: Written by John Cunningham Bowler, 2011.\n * To the extent possible under law, the author has waived all copyright and\n * related or neighboring rights to this work.  This work is published from:\n * United States.\n *\n * Read a single pixel value from a PNG file.\n *\n * This code illustrates basic 'by-row' reading of a PNG file using libpng.\n * Rows are read until a particular pixel is found; the value of this pixel is\n * then printed on stdout.\n *\n * The code illustrates how to do this on interlaced as well as non-interlaced\n * images.  Normally you would call png_set_interlace_handling() to have libpng\n * deal with the interlace for you, but that obliges you to buffer half of the\n * image to assemble the interlaced rows.  In this code\n * png_set_interlace_handling() is not called and, instead, the code handles the\n * interlace passes directly looking for the required pixel.\n */\n#include <stdlib.h>\n#include <stdio.h>\n#include <setjmp.h> /* required for error handling */\n\n/* Normally use <png.h> here to get the installed libpng, but this is done to\n * ensure the code picks up the local libpng implementation:\n */\n#include \"../../png.h\"\n\n/* Return component 'c' of pixel 'x' from the given row. */\nstatic unsigned int\ncomponent(png_const_bytep row, png_uint_32 x, unsigned int c,\n   unsigned int bit_depth, unsigned int channels)\n{\n   /* PNG images can be up to 2^31 pixels wide, but this means they can be up to\n    * 2^37 bits wide (for a 64-bit pixel - the largest possible) and hence 2^34\n    * bytes wide.  Since the row fitted into memory, however, the following must\n    * work:\n    */\n   png_uint_32 bit_offset_hi = bit_depth * ((x >> 6) * channels);\n   png_uint_32 bit_offset_lo = bit_depth * ((x & 0x3f) * channels + c);\n\n   row = (png_const_bytep)(((PNG_CONST png_byte (*)[8])row) + bit_offset_hi);\n   row += bit_offset_lo >> 3;\n   bit_offset_lo &= 0x07;\n\n   /* PNG pixels are packed into bytes to put the first pixel in the highest\n    * bits of the byte and into two bytes for 16-bit values with the high 8 bits\n    * first, so:\n    */\n   switch (bit_depth)\n   {\n      case 1: return (row[0] >> (7-bit_offset_lo)) & 0x01;\n      case 2: return (row[0] >> (6-bit_offset_lo)) & 0x03;\n      case 4: return (row[0] >> (4-bit_offset_lo)) & 0x0f;\n      case 8: return row[0];\n      case 16: return (row[0] << 8) + row[1];\n      default:\n         /* This should never happen; it indicates a bug in this program or in\n          * libpng itself:\n          */\n         fprintf(stderr, \"pngpixel: invalid bit depth %u\\n\", bit_depth);\n         exit(1);\n   }\n}\n\n/* Print a pixel from a row returned by libpng; determine the row format, find\n * the pixel, and print the relevant information to stdout.\n */\nstatic void\nprint_pixel(png_structp png_ptr, png_infop info_ptr, png_const_bytep row,\n   png_uint_32 x)\n{\n   PNG_CONST unsigned int bit_depth = png_get_bit_depth(png_ptr, info_ptr);\n\n   switch (png_get_color_type(png_ptr, info_ptr))\n   {\n      case PNG_COLOR_TYPE_GRAY:\n         printf(\"GRAY %u\\n\", component(row, x, 0, bit_depth, 1));\n         return;\n\n      /* The palette case is slightly more difficult - the palette and, if\n       * present, the tRNS ('transparency', though the values are really\n       * opacity) data must be read to give the full picture:\n       */\n      case PNG_COLOR_TYPE_PALETTE:\n         {\n            PNG_CONST unsigned int index = component(row, x, 0, bit_depth, 1);\n            png_colorp palette = NULL;\n            int num_palette = 0;\n\n            if ((png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) &\n               PNG_INFO_PLTE) && num_palette > 0 && palette != NULL)\n            {\n               png_bytep trans_alpha = NULL;\n               int num_trans = 0;\n               if ((png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans,\n                  NULL) & PNG_INFO_tRNS) && num_trans > 0 &&\n                  trans_alpha != NULL)\n                  printf(\"INDEXED %u = %d %d %d %d\\n\", index,\n                     palette[index].red, palette[index].green,\n                     palette[index].blue,\n                     index < num_trans ? trans_alpha[index] : 255);\n\n               else /* no transparency */\n                  printf(\"INDEXED %u = %d %d %d\\n\", index,\n                     palette[index].red, palette[index].green,\n                     palette[index].blue);\n            }\n\n            else\n               printf(\"INDEXED %u = invalid index\\n\", index);\n         }\n         return;\n\n      case PNG_COLOR_TYPE_RGB:\n         printf(\"RGB %u %u %u\\n\", component(row, x, 0, bit_depth, 3),\n            component(row, x, 1, bit_depth, 3),\n            component(row, x, 2, bit_depth, 3));\n         return;\n\n      case PNG_COLOR_TYPE_GRAY_ALPHA:\n         printf(\"GRAY+ALPHA %u %u\\n\", component(row, x, 0, bit_depth, 2),\n            component(row, x, 1, bit_depth, 2));\n         return;\n\n      case PNG_COLOR_TYPE_RGB_ALPHA:\n         printf(\"RGBA %u %u %u %u\\n\", component(row, x, 0, bit_depth, 4),\n            component(row, x, 1, bit_depth, 4),\n            component(row, x, 2, bit_depth, 4),\n            component(row, x, 3, bit_depth, 4));\n         return;\n\n      default:\n         png_error(png_ptr, \"pngpixel: invalid color type\");\n   }\n}\n\nint main(int argc, const char **argv)\n{\n   /* This program uses the default, <setjmp.h> based, libpng error handling\n    * mechanism, therefore any local variable that exists before the call to\n    * setjmp and is changed after the call to setjmp returns successfully must\n    * be declared with 'volatile' to ensure that their values don't get\n    * destroyed by longjmp:\n    */\n   volatile int result = 1/*fail*/;\n\n   if (argc == 4)\n   {\n      long x = atol(argv[1]);\n      long y = atol(argv[2]);\n      FILE *f = fopen(argv[3], \"rb\");\n      volatile png_bytep row = NULL;\n\n      if (f != NULL)\n      {\n         /* libpng requires a callback function for handling errors; this\n          * callback must not return.  The default callback function uses a\n          * stored <setjmp.h> style jmp_buf which is held in a png_struct and\n          * writes error messages to stderr.  Creating the png_struct is a\n          * little tricky; just copy the following code.\n          */\n         png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,\n            NULL, NULL, NULL);\n\n         if (png_ptr != NULL)\n         {\n            png_infop info_ptr = png_create_info_struct(png_ptr);\n\n            if (info_ptr != NULL)\n            {\n               /* Declare stack variables to hold pointers to locally allocated\n                * data.\n                */\n\n               /* Initialize the error control buffer: */\n               if (setjmp(png_jmpbuf(png_ptr)) == 0)\n               {\n                  png_uint_32 width, height;\n                  int bit_depth, color_type, interlace_method,\n                     compression_method, filter_method;\n                  png_bytep row_tmp;\n\n                  /* Now associate the recently opened (FILE*) with the default\n                   * libpng initialization functions.  Sometimes libpng is\n                   * compiled without stdio support (it can be difficult to do\n                   * in some environments); in that case you will have to write\n                   * your own read callback to read data from the (FILE*).\n                   */\n                  png_init_io(png_ptr, f);\n\n                  /* And read the first part of the PNG file - the header and\n                   * all the information up to the first pixel.\n                   */\n                  png_read_info(png_ptr, info_ptr);\n\n                  /* This fills in enough information to tell us the width of\n                   * each row in bytes, allocate the appropriate amount of\n                   * space.  In this case png_malloc is used - it will not\n                   * return if memory isn't available.\n                   */\n                  row = png_malloc(png_ptr, png_get_rowbytes(png_ptr,\n                     info_ptr));\n\n                  /* To avoid the overhead of using a volatile auto copy row_tmp\n                   * to a local here - just use row for the png_free below.\n                   */\n                  row_tmp = row;\n\n                  /* All the information we need is in the header is returned by\n                   * png_get_IHDR, if this fails we can now use 'png_error' to\n                   * signal the error and return control to the setjmp above.\n                   */\n                  if (png_get_IHDR(png_ptr, info_ptr, &width, &height,\n                     &bit_depth, &color_type, &interlace_method,\n                     &compression_method, &filter_method))\n                  {\n                     int passes, pass;\n\n                     /* png_set_interlace_handling returns the number of\n                      * passes required as well as turning on libpng's\n                      * handling, but since we do it ourselves this is\n                      * necessary:\n                      */\n                     switch (interlace_method)\n                     {\n                        case PNG_INTERLACE_NONE:\n                           passes = 1;\n                           break;\n\n                        case PNG_INTERLACE_ADAM7:\n                           passes = PNG_INTERLACE_ADAM7_PASSES;\n                           break;\n\n                        default:\n                           png_error(png_ptr, \"pngpixel: unknown interlace\");\n                     }\n\n                     /* Now read the pixels, pass-by-pass, row-by-row: */\n                     png_start_read_image(png_ptr);\n\n                     for (pass=0; pass<passes; ++pass)\n                     {\n                        png_uint_32 ystart, xstart, ystep, xstep;\n                        png_uint_32 py;\n\n                        if (interlace_method == PNG_INTERLACE_ADAM7)\n                        {\n                           /* Sometimes the whole pass is empty because the\n                            * image is too narrow or too short.  libpng\n                            * expects to be called for each row that is\n                            * present in the pass, so it may be necessary to\n                            * skip the loop below (over py) if the image is\n                            * too narrow.\n                            */\n                           if (PNG_PASS_COLS(width, pass) == 0)\n                              continue;\n\n                           /* We need the starting pixel and the offset\n                            * between each pixel in this pass; use the macros\n                            * in png.h:\n                            */\n                           xstart = PNG_PASS_START_COL(pass);\n                           ystart = PNG_PASS_START_ROW(pass);\n                           xstep = PNG_PASS_COL_OFFSET(pass);\n                           ystep = PNG_PASS_ROW_OFFSET(pass);\n                        }\n\n                        else\n                        {\n                           ystart = xstart = 0;\n                           ystep = xstep = 1;\n                        }\n\n                        /* To find the pixel, loop over 'py' for each pass\n                         * reading a row and then checking to see if it\n                         * contains the pixel.\n                         */\n                        for (py = ystart; py < height; py += ystep)\n                        {\n                           png_uint_32 px, ppx;\n\n                           /* png_read_row takes two pointers.  When libpng\n                            * handles the interlace the first is filled in\n                            * pixel-by-pixel, and the second receives the same\n                            * pixels but they are replicated across the\n                            * unwritten pixels so far for each pass.  When we\n                            * do the interlace, however, they just contain\n                            * the pixels from the interlace pass - giving\n                            * both is wasteful and pointless, so we pass a\n                            * NULL pointer.\n                            */\n                           png_read_row(png_ptr, row_tmp, NULL);\n\n                           /* Now find the pixel if it is in this row; there\n                            * are, of course, much better ways of doing this\n                            * than using a for loop:\n                            */\n                           if (y == py) for (px = xstart, ppx = 0;\n                              px < width; px += xstep, ++ppx) if (x == px)\n                           {\n                              /* 'ppx' is the index of the pixel in the row\n                               * buffer.\n                               */\n                              print_pixel(png_ptr, info_ptr, row_tmp, ppx);\n\n                              /* Now terminate the loops early - we have\n                               * found and handled the required data.\n                               */\n                              goto pass_loop_end;\n                           } /* x loop */\n                        } /* y loop */\n                     } /* pass loop */\n\n                     /* Finally free the temporary buffer: */\n                  pass_loop_end:\n                     row = NULL;\n                     png_free(png_ptr, row_tmp);\n                  }\n\n                  else\n                     png_error(png_ptr, \"pngpixel: png_get_IHDR failed\");\n\n               }\n\n               else\n               {\n                  /* Else libpng has raised an error.  An error message has\n                   * already been output, so it is only necessary to clean up\n                   * locally allocated data:\n                   */\n                  if (row != NULL)\n                  {\n                     /* The default implementation of png_free never errors out\n                      * (it just crashes if something goes wrong), but the safe\n                      * way of using it is still to clear 'row' before calling\n                      * png_free:\n                      */\n                     png_bytep row_tmp = row;\n                     row = NULL;\n                     png_free(png_ptr, row_tmp);\n                  }\n               }\n\n               png_destroy_info_struct(png_ptr, &info_ptr);\n            }\n\n            else\n               fprintf(stderr, \"pngpixel: out of memory allocating png_info\\n\");\n\n            png_destroy_read_struct(&png_ptr, NULL, NULL);\n         }\n\n         else\n            fprintf(stderr, \"pngpixel: out of memory allocating png_struct\\n\");\n      }\n\n      else\n         fprintf(stderr, \"pngpixel: %s: could not open file\\n\", argv[3]);\n   }\n\n   else\n      /* Wrong number of arguments */\n      fprintf(stderr, \"pngpixel: usage: pngpixel x y png-file\\n\");\n\n   return result;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/examples/pngtopng.c",
    "content": "/*- pngtopng\n *\n * COPYRIGHT: Written by John Cunningham Bowler, 2011.\n * To the extent possible under law, the author has waived all copyright and\n * related or neighboring rights to this work.  This work is published from:\n * United States.\n *\n * Read a PNG and write it out in a fixed format, using the 'simplified API'\n * that was introduced in libpng-1.6.0.\n *\n * This sample code is just the code from the top of 'example.c' with some error\n * handling added.  See example.c for more comments.\n */\n#include <stddef.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n/* Normally use <png.h> here to get the installed libpng, but this is done to\n * ensure the code picks up the local libpng implementation:\n */\n#include \"../../png.h\"\n\nint main(int argc, const char **argv)\n{\n   int result = 1;\n\n   if (argc == 3)\n   {\n      png_image image;\n\n      /* Only the image structure version number needs to be set. */\n      memset(&image, 0, sizeof image);\n      image.version = PNG_IMAGE_VERSION;\n\n      if (png_image_begin_read_from_file(&image, argv[1]))\n      {\n         png_bytep buffer;\n\n         /* Change this to try different formats!  If you set a colormap format\n          * then you must also supply a colormap below.\n          */\n         image.format = PNG_FORMAT_RGBA;\n\n         buffer = malloc(PNG_IMAGE_SIZE(image));\n\n         if (buffer != NULL)\n         {\n            if (png_image_finish_read(&image, NULL/*background*/, buffer,\n               0/*row_stride*/, NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP */))\n            {\n               if (png_image_write_to_file(&image, argv[2],\n                  0/*convert_to_8bit*/, buffer, 0/*row_stride*/,\n                  NULL/*colormap*/))\n                  result = 0;\n\n               else\n                  fprintf(stderr, \"pngtopng: write %s: %s\\n\", argv[2],\n                      image.message);\n\n               free(buffer);\n            }\n\n            else\n            {\n               fprintf(stderr, \"pngtopng: read %s: %s\\n\", argv[1],\n                   image.message);\n\n               /* This is the only place where a 'free' is required; libpng does\n                * the cleanup on error and success, but in this case we couldn't\n                * complete the read because of running out of memory.\n                */\n               png_image_free(&image);\n            }\n         }\n\n         else\n            fprintf(stderr, \"pngtopng: out of memory: %lu bytes\\n\",\n               (unsigned long)PNG_IMAGE_SIZE(image));\n      }\n\n      else\n         /* Failed to read the first argument: */\n         fprintf(stderr, \"pngtopng: %s: %s\\n\", argv[1], image.message);\n   }\n\n   else\n      /* Wrong number of arguments */\n      fprintf(stderr, \"pngtopng: usage: pngtopng input-file output-file\\n\");\n\n   return result;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/COPYING",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Library General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\f\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\f\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\f\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\f\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\f\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program; if not, write to the Free Software\n    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year  name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Library General\nPublic License instead of this License.\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/LICENSE",
    "content": "  ---------------------------------------------------------------------------\n\n      Copyright (c) 1998-2008 Greg Roelofs.  All rights reserved.\n\n      This software is provided \"as is,\" without warranty of any kind,\n      express or implied.  In no event shall the author or contributors\n      be held liable for any damages arising in any way from the use of\n      this software.\n\n      The contents of this file are DUAL-LICENSED.  You may modify and/or\n      redistribute this software according to the terms of one of the\n      following two licenses (at your option):\n\n\n      LICENSE 1 (\"BSD-like with advertising clause\"):\n\n      Permission is granted to anyone to use this software for any purpose,\n      including commercial applications, and to alter it and redistribute\n      it freely, subject to the following restrictions:\n\n      1. Redistributions of source code must retain the above copyright\n         notice, disclaimer, and this list of conditions.\n      2. Redistributions in binary form must reproduce the above copyright\n         notice, disclaimer, and this list of conditions in the documenta-\n         tion and/or other materials provided with the distribution.\n      3. All advertising materials mentioning features or use of this\n         software must display the following acknowledgment:\n\n            This product includes software developed by Greg Roelofs\n            and contributors for the book, \"PNG: The Definitive Guide,\"\n            published by O'Reilly and Associates.\n\n\n      LICENSE 2 (GNU GPL v2 or later):\n\n      This program is free software; you can redistribute it and/or modify\n      it under the terms of the GNU General Public License as published by\n      the Free Software Foundation; either version 2 of the License, or\n      (at your option) any later version.\n\n      This program is distributed in the hope that it will be useful,\n      but WITHOUT ANY WARRANTY; without even the implied warranty of\n      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n      GNU General Public License for more details.\n\n      You should have received a copy of the GNU General Public License\n      along with this program; if not, write to the Free Software Foundation,\n      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  ---------------------------------------------------------------------------\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/Makefile.mingw32",
    "content": "# Sample makefile for rpng-win / rpng2-win / wpng using mingw32-gcc and make.\n# Greg Roelofs\n# Last modified:  2 June 2007\n#\n#\tThe programs built by this makefile are described in the book,\n#\t\"PNG:  The Definitive Guide,\" by Greg Roelofs (O'Reilly and\n#\tAssociates, 1999).  Go buy a copy, eh?  Well, OK, it's not\n#\tgenerally for sale anymore, but it's the thought that counts,\n#\tright?  (Hint:  http://www.libpng.org/pub/png/book/ )\n#\n# Invoke this makefile from a DOS-prompt window via:\n#\n#\tmake -f Makefile.mingw32\n#\n# This makefile assumes libpng and zlib have already been built or downloaded\n# and are in subdirectories at the same level as the current subdirectory\n# (as indicated by the PNGDIR and ZDIR macros below).  It makes no assumptions\n# at all about the mingw32 installation tree (W32DIR).  Edit as appropriate.\n#\n# Note that the names of the dynamic and static libpng and zlib libraries\n# used below may change in later releases of the libraries.  This makefile\n# builds both statically and dynamically linked executables by default.\n# (You need only one set, but for testing it can be handy to have both.)\n\n\n# macros --------------------------------------------------------------------\n\n#PNGDIR = ../..#\t\tfor libpng-x.y.z/contrib/gregbook builds\nPNGDIR = ../libpng-win32\nPNGINC = -I$(PNGDIR)\nPNGLIBd = $(PNGDIR)/libpng.dll.a\t# dynamically linked\nPNGLIBs = $(PNGDIR)/libpng.a\t\t# statically linked, local libpng\n\n#ZDIR = ../../../zlib-win32#\tfor libpng-x.y.z/contrib/gregbook builds\nZDIR = ../zlib-win32\nZINC = -I$(ZDIR)\nZLIBd = $(ZDIR)/libzdll.a\nZLIBs = $(ZDIR)/libz.a\n\n# change this to be the path where mingw32 installs its stuff:\nW32DIR =\n#W32DIR = /usr/local/cross-tools/i386-mingw32msvc\nW32INC = -I$(W32DIR)/include\nW32LIB = $(W32DIR)/lib/libuser32.a $(W32DIR)/lib/libgdi32.a\n\nCC = gcc\n#CC = i386-mingw32msvc-gcc #\te.g., Linux -> Win32 cross-compilation\nLD = $(CC)\nRM = rm -f\nCPPFLAGS = $(INCS)\nCFLAGS = -O -Wall $(MINGW_CCFLAGS)\n# [note that -Wall is a gcc-specific compilation flag (\"most warnings on\")]\n# [-ansi, -pedantic and -W can also be used]\nLDFLAGS = $(MINGW_LDFLAGS)\nO = .o\nE = .exe\n\nINCS = $(PNGINC) $(ZINC) $(W32INC)\nRLIBSd = $(PNGLIBd) $(ZLIBd) $(W32LIB) -lm\nRLIBSs = $(PNGLIBs) $(ZLIBs) $(W32LIB) -lm\nWLIBSd = $(PNGLIBd) $(ZLIBd)\nWLIBSs = $(PNGLIBs) $(ZLIBs)\n\nRPNG   = rpng-win\nRPNG2  = rpng2-win\nWPNG   = wpng\n\nROBJSd  = $(RPNG)$(O) readpng.pic$(O)\nROBJS2d = $(RPNG2)$(O) readpng2.pic$(O)\nWOBJSd  = $(WPNG)$(O) writepng.pic$(O)\n\nRPNGs  = $(RPNG)-static\nRPNG2s = $(RPNG2)-static\nWPNGs  = $(WPNG)-static\n\nROBJSs  = $(RPNG)$(O) readpng$(O)\nROBJS2s = $(RPNG2)$(O) readpng2$(O)\nWOBJSs  = $(WPNG)$(O) writepng$(O)\n\nSTATIC_EXES  = $(RPNGs)$(E) $(RPNG2s)$(E) $(WPNGs)$(E)\nDYNAMIC_EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)\n\nEXES = $(STATIC_EXES) $(DYNAMIC_EXES)\n\n\n# implicit make rules -------------------------------------------------------\n\n.c$(O):\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $<\n\n%.pic$(O): %.c\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -DPNG_BUILD_DLL -o $@ $<\n\n\n# dependencies --------------------------------------------------------------\n\nall:  $(EXES)\n\n$(RPNGs)$(E): $(ROBJSs)\n\t$(LD) $(LDFLAGS) -o $@ $(ROBJSs) $(RLIBSs)\n\n$(RPNG)$(E): $(ROBJSd)\n\t$(LD) $(LDFLAGS) -o $@ $(ROBJSd) $(RLIBSd)\n\n$(RPNG2s)$(E): $(ROBJS2s)\n\t$(LD) $(LDFLAGS) -o $@ $(ROBJS2s) $(RLIBSs)\n\n$(RPNG2)$(E): $(ROBJS2d)\n\t$(LD) $(LDFLAGS) -o $@ $(ROBJS2d) $(RLIBSd)\n\n$(WPNGs)$(E): $(WOBJSs)\n\t$(LD) $(LDFLAGS) -o $@ $(WOBJSs) $(WLIBSs)\n\n$(WPNG)$(E): $(WOBJSd)\n\t$(LD) $(LDFLAGS) -o $@ $(WOBJSd) $(WLIBSd)\n\n$(RPNG)$(O):\t$(RPNG).c readpng.h\n$(RPNG2)$(O):\t$(RPNG2).c readpng2.h\n$(WPNG)$(O):\t$(WPNG).c writepng.h\n\nreadpng$(O) readpng.pic$(O):\treadpng.c readpng.h\nreadpng2$(O) readpng2.pic$(O):\treadpng2.c readpng2.h\nwritepng$(O) writepng.pic$(O):\twritepng.c writepng.h\n\n\n# maintenance ---------------------------------------------------------------\n\nclean:\n\t$(RM) $(EXES)\n\t$(RM) $(ROBJSs) $(ROBJS2s) $(WOBJSs)\n\t$(RM) $(ROBJSd) $(ROBJS2d) $(WOBJSd)\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/Makefile.sgi",
    "content": "# Sample makefile for rpng-x / rpng2-x / wpng for SGI using cc and make.\n# Greg Roelofs\n# Last modified:  7 March 2002\n#\n#\tThe programs built by this makefile are described in the book,\n#\t\"PNG:  The Definitive Guide,\" by Greg Roelofs (O'Reilly and\n#\tAssociates, 1999).  Go buy a copy, eh?  Buy some for friends\n#\tand family, too.  (Not that this is a blatant plug or anything.)\n#\n# Invoke this makefile from a shell prompt in the usual way; for example:\n#\n#\tmake -f Makefile.sgi\n#\n# This makefile assumes libpng and zlib have already been built or downloaded\n# and are both installed in /usr/local/{include,lib} (as indicated by the\n# PNG* and Z* macros below).  Edit as appropriate--choose only ONE each of\n# the PNGINC, PNGLIB, ZINC and ZLIB lines.\n#\n# This makefile builds dynamically linked executables (against libpng and zlib,\n# that is), but that can be changed by uncommenting the appropriate PNGLIB and\n# ZLIB lines.\n\n\n# macros --------------------------------------------------------------------\n\nPNGINC = -I/usr/local/include/libpng16\nPNGLIB = -L/usr/local/lib -lpng16\t  # dynamically linked against libpng\n#PNGLIB = /usr/local/lib/libpng16.a # statically linked against libpng\n# or:\n#PNGINC = -I../..\n#PNGLIB = -L../.. -lpng\n#PNGLIB = ../../libpng.a\n\nZINC = -I/usr/local/include\nZLIB = -L/usr/local/lib -lz\t\t# dynamically linked against zlib\n#ZLIB = /usr/local/lib/libz.a\t\t# statically linked against zlib\n#ZINC = -I../zlib\n#ZLIB = -L../zlib -lz\n#ZLIB = ../../../zlib/libz.a\n\nXINC = -I/usr/include/X11\t\t# old-style, stock X distributions\nXLIB = -L/usr/lib/X11 -lX11\n#XINC = -I/usr/openwin/include    \t# Sun workstations (OpenWindows)\n#XLIB = -L/usr/openwin/lib -lX11\n#XINC = -I/usr/X11R6/include\t\t# new X distributions (XFree86, etc.)\n#XLIB = -L/usr/X11R6/lib -lX11\n\nINCS = $(PNGINC) $(ZINC) $(XINC)\nRLIBS = $(PNGLIB) $(ZLIB) $(XLIB) -lm\nWLIBS = $(PNGLIB) $(ZLIB)\n\nCC = cc\nLD = cc\nRM = rm -f\n# ABI must be the same as that used to build libpng.\nABI =\nCPPFLAGS =\nCFLAGS = $(ABI) -O -fullwarn $(INCS)\nLDFLAGS = $(ABI)\nO = .o\nE =\n\nRPNG  = rpng-x\nRPNG2 = rpng2-x\nWPNG  = wpng\n\nROBJS  = $(RPNG)$(O) readpng$(O)\nROBJS2 = $(RPNG2)$(O) readpng2$(O)\nWOBJS  = $(WPNG)$(O) writepng$(O)\n\nEXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)\n\n\n# implicit make rules -------------------------------------------------------\n\n.c$(O):\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $<\n\n\n# dependencies --------------------------------------------------------------\n\nall:  $(EXES)\n\n$(RPNG)$(E): $(ROBJS)\n\t$(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBS)\n\n$(RPNG2)$(E): $(ROBJS2)\n\t$(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBS)\n\n$(WPNG)$(E): $(WOBJS)\n\t$(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBS)\n\n$(RPNG)$(O):\t$(RPNG).c readpng.h\n$(RPNG2)$(O):\t$(RPNG2).c readpng2.h\n$(WPNG)$(O):\t$(WPNG).c writepng.h\n\nreadpng$(O):\treadpng.c readpng.h\nreadpng2$(O):\treadpng2.c readpng2.h\nwritepng$(O):\twritepng.c writepng.h\n\n\n# maintenance ---------------------------------------------------------------\n\nclean:\n\t$(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS)\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/Makefile.unx",
    "content": "# Sample makefile for rpng-x / rpng2-x / wpng using gcc and make.\n# Greg Roelofs\n# Last modified:  2 June 2007\n#\n#\tThe programs built by this makefile are described in the book,\n#\t\"PNG:  The Definitive Guide,\" by Greg Roelofs (O'Reilly and\n#\tAssociates, 1999).  Go buy a copy, eh?  Well, OK, it's not\n#\tgenerally for sale anymore, but it's the thought that counts,\n#\tright?  (Hint:  http://www.libpng.org/pub/png/book/ )\n#\n# Invoke this makefile from a shell prompt in the usual way; for example:\n#\n#\tmake -f Makefile.unx\n#\n# This makefile assumes libpng and zlib have already been built or downloaded\n# and are installed in /usr/local/{include,lib} or as otherwise indicated by\n# the PNG* and Z* macros below.  Edit as appropriate--choose only ONE each of\n# the PNGINC, PNGLIBd, PNGLIBs, ZINC, ZLIBd and ZLIBs lines.\n#\n# This makefile builds both dynamically and statically linked executables\n# (against libpng and zlib, that is), but that can be changed by modifying\n# the \"EXES =\" line.  (You need only one set, but for testing it can be handy\n# to have both.)\n\n\n# macros --------------------------------------------------------------------\n\n#PNGDIR = /usr/local/lib\n#PNGINC = -I/usr/local/include/libpng16\n#PNGLIBd = -L$(PNGDIR) -lpng16 # dynamically linked, installed libpng\n#PNGLIBs = $(PNGDIR)/libpng16.a # statically linked, installed libpng\n# or:\nPNGDIR = ../..#\tthis one is for libpng-x.y.z/contrib/gregbook builds\n#PNGDIR = ../libpng\nPNGINC = -I$(PNGDIR)\nPNGLIBd = -Wl,-rpath,$(PNGDIR) -L$(PNGDIR) -lpng16\t# dynamically linked\nPNGLIBs = $(PNGDIR)/libpng.a\t\t# statically linked, local libpng\n\nZDIR = /usr/local/lib\n#ZDIR = /usr/lib64\nZINC = -I/usr/local/include\nZLIBd = -L$(ZDIR) -lz\t\t\t# dynamically linked against zlib\nZLIBs = $(ZDIR)/libz.a\t\t\t# statically linked against zlib\n# or:\n#ZDIR = ../zlib\n#ZINC = -I$(ZDIR)\n#ZLIBd = -Wl,-rpath,$(ZDIR) -L$(ZDIR) -lz  # -rpath allows in-place testing\n#ZLIBs = $(ZDIR)/libz.a\n\n#XINC = -I/usr/include\t\t\t# old-style, stock X distributions\n#XLIB = -L/usr/lib/X11 -lX11\t\t#  (including SGI IRIX)\n#XINC = -I/usr/openwin/include\t\t# Sun workstations (OpenWindows)\n#XLIB = -L/usr/openwin/lib -lX11\nXINC = -I/usr/X11R6/include\t\t# new X distributions (X.org, etc.)\nXLIB = -L/usr/X11R6/lib -lX11\n#XLIB = -L/usr/X11R6/lib64 -lX11\t# e.g., Red Hat on AMD64\n\nINCS = $(PNGINC) $(ZINC) $(XINC)\nRLIBSd = $(PNGLIBd) $(ZLIBd) $(XLIB) -lm\nRLIBSs = $(PNGLIBs) $(ZLIBs) $(XLIB) -lm\nWLIBSd = $(PNGLIBd) $(ZLIBd) -lm\nWLIBSs = $(PNGLIBs) $(ZLIBs) -lm\n\nCC = gcc\nLD = gcc\nRM = rm -f\nCPPFLAGS = $(INCS) -DFEATURE_LOOP\nCFLAGS = -O -Wall\n#CFLAGS = -O -W -Wall -Wextra -pedantic -ansi\n# [note that -Wall is a gcc-specific compilation flag (\"most warnings on\")]\n# [-ansi, -pedantic, -Wextra, and -W can also be used]\nLDFLAGS =\nO = .o\nE =\n\nRPNG   = rpng-x\nRPNG2  = rpng2-x\nWPNG   = wpng\n\nRPNGs  = $(RPNG)-static\nRPNG2s = $(RPNG2)-static\nWPNGs  = $(WPNG)-static\n\nROBJS  = $(RPNG)$(O) readpng$(O)\nROBJS2 = $(RPNG2)$(O) readpng2$(O)\nWOBJS  = $(WPNG)$(O) writepng$(O)\n\nSTATIC_EXES  = $(RPNGs)$(E) $(RPNG2s)$(E) $(WPNGs)$(E)\nDYNAMIC_EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)\n\nEXES = $(STATIC_EXES) $(DYNAMIC_EXES)\n\n\n# implicit make rules -------------------------------------------------------\n\n.c$(O):\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $<\n\n\n# dependencies --------------------------------------------------------------\n\nall:  $(EXES)\n\n$(RPNGs)$(E): $(ROBJS)\n\t$(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBSs)\n\n$(RPNG)$(E): $(ROBJS)\n\t$(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBSd)\n\n$(RPNG2s)$(E): $(ROBJS2)\n\t$(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBSs)\n\n$(RPNG2)$(E): $(ROBJS2)\n\t$(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBSd)\n\n$(WPNGs)$(E): $(WOBJS)\n\t$(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBSs)\n\n$(WPNG)$(E): $(WOBJS)\n\t$(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBSd)\n\n$(RPNG)$(O):\t$(RPNG).c readpng.h\n$(RPNG2)$(O):\t$(RPNG2).c readpng2.h\n$(WPNG)$(O):\t$(WPNG).c writepng.h\n\nreadpng$(O):\treadpng.c readpng.h\nreadpng2$(O):\treadpng2.c readpng2.h\nwritepng$(O):\twritepng.c writepng.h\n\n\n# maintenance ---------------------------------------------------------------\n\nclean:\n\t$(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS)\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/Makefile.w32",
    "content": "# Sample makefile for rpng-win / rpng2-win / wpng using MSVC and NMAKE.\n# Greg Roelofs\n# Last modified:  2 June 2007\n#\n#\tThe programs built by this makefile are described in the book,\n#\t\"PNG:  The Definitive Guide,\" by Greg Roelofs (O'Reilly and\n#\tAssociates, 1999).  Go buy a copy, eh?  Well, OK, it's not\n#\tgenerally for sale anymore, but it's the thought that counts,\n#\tright?  (Hint:  http://www.libpng.org/pub/png/book/ )\n#\n# Invoke this makefile from a DOS prompt window via:\n#\n#\t%devstudio%\\vc\\bin\\vcvars32.bat\n#\tnmake -nologo -f Makefile.w32\n#\n# where %devstudio% is the installation directory for MSVC / DevStudio.  If\n# you get \"environment out of space\" errors, create a desktop shortcut with\n# \"c:\\windows\\command.com /e:4096\" as the program command line and set the\n# working directory to this directory.  Then double-click to open the new\n# DOS-prompt window with a bigger environment and retry the commands above.\n#\n# This makefile assumes libpng and zlib have already been built or downloaded\n# and are in subdirectories at the same level as the current subdirectory\n# (as indicated by the PNGPATH and ZPATH macros below).  Edit as appropriate.\n#\n# Note that the names of the dynamic and static libpng and zlib libraries\n# used below may change in later releases of the libraries.  This makefile\n# builds statically linked executables, but that can be changed by uncom-\n# menting the appropriate PNGLIB and ZLIB lines.\n\n!include <ntwin32.mak>\n\n\n# macros --------------------------------------------------------------------\n\nPNGPATH = ../libpng\nPNGINC = -I$(PNGPATH)\n#PNGLIB = $(PNGPATH)/pngdll.lib\nPNGLIB = $(PNGPATH)/libpng.lib\n\nZPATH = ../zlib\nZINC = -I$(ZPATH)\n#ZLIB = $(ZPATH)/zlibdll.lib\nZLIB = $(ZPATH)/zlibstat.lib\n\nWINLIBS = -defaultlib:user32.lib gdi32.lib\n# [\"real\" apps may also need comctl32.lib, comdlg32.lib, winmm.lib, etc.]\n\nINCS = $(PNGINC) $(ZINC)\nRLIBS = $(PNGLIB) $(ZLIB) $(WINLIBS)\nWLIBS = $(PNGLIB) $(ZLIB)\n\nCC = cl\nLD = link\nRM = del\nCPPFLAGS = $(INCS)\nCFLAGS = -nologo -O -W3 $(cvars)\n# [note that -W3 is an MSVC-specific compilation flag (\"all warnings on\")]\n# [see %devstudio%\\vc\\include\\win32.mak for cvars macro definition]\nO = .obj\nE = .exe\n\nRLDFLAGS = -nologo -subsystem:windows\nWLDFLAGS = -nologo\n\nRPNG  = rpng-win\nRPNG2 = rpng2-win\nWPNG  = wpng\n\nROBJS  = $(RPNG)$(O) readpng$(O)\nROBJS2 = $(RPNG2)$(O) readpng2$(O)\nWOBJS  = $(WPNG)$(O) writepng$(O)\n\nEXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)\n\n\n# implicit make rules -------------------------------------------------------\n\n.c$(O):\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $<\n\n\n# dependencies --------------------------------------------------------------\n\nall:  $(EXES)\n\n$(RPNG)$(E): $(ROBJS)\n\t$(LD) $(RLDFLAGS) -out:$@ $(ROBJS) $(RLIBS)\n\n$(RPNG2)$(E): $(ROBJS2)\n\t$(LD) $(RLDFLAGS) -out:$@ $(ROBJS2) $(RLIBS)\n\n$(WPNG)$(E): $(WOBJS)\n\t$(LD) $(WLDFLAGS) -out:$@ $(WOBJS) $(WLIBS)\n\n$(RPNG)$(O):\t$(RPNG).c readpng.h\n$(RPNG2)$(O):\t$(RPNG2).c readpng2.h\n$(WPNG)$(O):\t$(WPNG).c writepng.h\n\nreadpng$(O):\treadpng.c readpng.h\nreadpng2$(O):\treadpng2.c readpng2.h\nwritepng$(O):\twritepng.c writepng.h\n\n\n# maintenance ---------------------------------------------------------------\n\nclean:\n#\tideally we could just do this:\n#\t$(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS)\n#\t...but the Windows \"DEL\" command is none too bright, so:\n\t$(RM) r*$(E)\n\t$(RM) w*$(E)\n\t$(RM) r*$(O)\n\t$(RM) w*$(O)\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/README",
    "content": "                     ===========================\n                      PNG: The Definitive Guide\n                     ===========================\n\n                             Source Code\n\nChapters 13, 14 and 15 of \"PNG: The Definitive Guide\" discuss three free,\ncross-platform demo programs that show how to use the libpng reference\nlibrary:  rpng, rpng2 and wpng.  rpng and rpng2 are viewers; the first is\na very simple example that that shows how a standard file-viewer might use\nlibpng, while the second is designed to process streaming data and shows\nhow a web browser might be written.  wpng is a simple command-line program\nthat reads binary PGM and PPM files (the ``raw'' grayscale and RGB subsets\nof PBMPLUS/NetPBM) and converts them to PNG.\n\nThe source code for all three demo programs currently compiles under\nUnix, OpenVMS, and 32-bit Windows.  (Special thanks to Martin Zinser,\nzinser@decus.de, for making the necessary changes for OpenVMS and for\nproviding an appropriate build script.)  Build instructions can be found\nbelow.\n\nFiles:\n\n   README             this file\n   LICENSE            terms of distribution and reuse (BSD-like or GNU GPL)\n   COPYING            GNU General Public License (GPL)\n\n   Makefile.unx       Unix makefile\n   Makefile.w32       Windows (MSVC) makefile\n   makevms.com        OpenVMS build script\n\n   rpng-win.c         Windows front end for the basic viewer\n   rpng-x.c           X Window System (Unix, OpenVMS) front end\n   readpng.c          generic back end for the basic viewer\n   readpng.h          header file for the basic viewer\n\n   rpng2-win.c        Windows front end for the progressive viewer\n   rpng2-x.c          X front end for the progressive viewer\n   readpng2.c         generic back end for the progressive viewer\n   readpng2.h         header file for the progressive viewer\n\n   wpng.c             generic (text) front end for the converter\n   writepng.c         generic back end for the converter\n   writepng.h         header file for the converter\n\n   toucan.png         transparent PNG for testing (by Stefan Schneider)\n\nNote that, although the programs are designed to be functional, their\nprimary purpose is to illustrate how to use libpng to add PNG support to\nother programs.  As such, their user interfaces are crude and definitely\nare not intended for everyday use.\n\nPlease see http://www.libpng.org/pub/png/pngbook.html for further infor-\nmation and links to the latest version of the source code, and Chapters\n13-15 of the book for detailed discussion of the three programs.\n\nGreg Roelofs\nhttp://pobox.com/~newt/greg_contact.html\n16 March 2008\n\n\nBUILD INSTRUCTIONS\n\n - Prerequisites (in order of compilation):\n\n      - zlib            http://zlib.net/\n      - libpng          http://www.libpng.org/pub/png/libpng.html\n      - pngbook         http://www.libpng.org/pub/png/book/sources.html\n\n     The pngbook demo programs are explicitly designed to demonstrate proper\n     coding techniques for using the libpng reference library.  As a result,\n     you need to download and build both zlib (on which libpng depends) and\n     libpng.  A common build setup is to place the zlib, libpng and pngbook\n     subdirectory trees (\"folders\") in the same parent directory.  Then the\n     libpng build can refer to files in ../zlib (or ..\\zlib or [-.zlib]),\n     and similarly for the pngbook build.\n\n     Note that all three packages are designed to be built from a command\n     line by default; those who wish to use a graphical or other integrated\n     development environments are on their own.\n\n\n - Unix:\n\n     Unpack the latest pngbook sources (which should correspond to this\n     README file) into a directory and change into that directory.\n\n     Copy Makefile.unx to Makefile and edit the PNG* and Z* variables\n     appropriately (possibly also the X* variables if necessary).\n\n     make\n\n     There is no \"install\" target, so copy the three executables somewhere\n     in your path or run them from the current directory.  All three will\n     print a basic usage screen when run without any command-line arguments;\n     see the book for more details.\n\n\n - Windows:\n\n     Unpack the latest pngbook sources (which should correspond to this\n     README file) into a folder, open a \"DOS shell\" or \"command prompt\"\n     or equivalent command-line window, and cd into the folder where you\n     unpacked the source code.\n\n     For MSVC, set up the necessary environment variables by invoking\n\n        %devstudio%\\vc\\bin\\vcvars32.bat\n\n     where where %devstudio% is the installation directory for MSVC /\n     DevStudio.  If you get \"environment out of space\" errors under 95/98,\n     create a desktop shortcut with \"c:\\windows\\command.com /e:4096\" as\n     the program command line and set the working directory to the pngbook\n     directory.  Then double-click to open the new DOS-prompt window with\n     a bigger environment and retry the commands above.\n\n     Copy Makefile.w32 to Makefile and edit the PNGPATH and ZPATH variables\n     appropriately (possibly also the \"INC\" and \"LIB\" variables if needed).\n     Note that the names of the dynamic and static libpng and zlib libraries\n     used in the makefile may change in later releases of the libraries.\n     Also note that, as of libpng version 1.0.5, MSVC DLL builds do not work.\n     This makefile therefore builds statically linked executables, but if\n     the DLL problems ever get fixed, uncommenting the appropriate PNGLIB\n     and ZLIB lines will build dynamically linked executables instead.\n\n     Do the build by typing\n\n        nmake\n\n     The result should be three executables:  rpng-win.exe, rpng2-win.exe,\n     and wpng.exe.  Copy them somewhere in your PATH or run them from the\n     current folder.  Like the Unix versions, the two windowed programs\n     (rpng and rpng2) now display a usage screen in a console window when\n     invoked without command-line arguments; this is new behavior as of\n     the June 2001 release.  Note that the programs use the Unix-style \"-\"\n     character to specify options, instead of the more common DOS/Windows\n     \"/\" character.  (For example:  \"rpng2-win -bgpat 4 foo.png\", not\n     \"rpng2-win /bgpat 4 foo.png\")\n\n\n - OpenVMS:\n\n     Unpack the pngbook sources into a subdirectory and change into that\n     subdirectory.\n\n     Edit makevms.com appropriately, specifically the zpath and pngpath\n     variables.\n\n     @makevms\n\n     To run the programs, they probably first need to be set up as \"foreign\n     symbols,\" with \"disk\" and \"dir\" set appropriately:\n\n     $ rpng  == \"$disk:[dir]rpng-x.exe\"\n     $ rpng2 == \"$disk:[dir]rpng2-x.exe\"\n     $ wpng  == \"$disk:[dir]wpng.exe\"\n\n     All three will print a basic usage screen when run without any command-\n     line arguments; see the book for more details.  Note that the options\n     style is Unix-like, i.e., preceded by \"-\" rather than \"/\".\n\n\nRUNNING THE PROGRAMS:  (VERY) BRIEF INTRO\n\n     rpng is a simple PNG viewer that can display transparent PNGs with a\n     specified background color; for example,\n\n        rpng -bgcolor \\#ff0000 toucan.png\n\n     would display the image with a red background.  rpng2 is a progressive\n     viewer that simulates a web browser in some respects; it can display\n     images against either a background color or a dynamically generated\n     background image.  For example:\n\n        rpng2 -bgpat 16 toucan.png\n\n     wpng is a purely command-line image converter from binary PBMPLUS/NetPBM\n     format (.pgm or .ppm) to PNG; for example,\n\n        wpng -time < toucan-notrans.ppm > toucan-notrans.png\n\n     would convert the specified PPM file (using redirection) to PNG, auto-\n     matically setting the PNG modification-time chunk.\n\n     All options can be abbreviated to the shortest unique value; for example,\n     \"-bgc\" for -bgcolor (versus \"-bgp\" for -bgpat), or \"-g\" for -gamma.\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/makevms.com",
    "content": "$!------------------------------------------------------------------------------\n$! make \"PNG: The Definitive Guide\" demo programs (for X) under OpenVMS\n$!\n$! Script created by Martin Zinser for libpng; modified by Greg Roelofs\n$! for standalone pngbook source distribution.\n$!\n$!\n$!    Set locations where zlib and libpng sources live.\n$!\n$ zpath   = \"\"\n$ pngpath = \"\"\n$!\n$ if f$search(\"[---.zlib]zlib.h\").nes.\"\" then zpath = \"[---.zlib]\"\n$ if f$search(\"[--]png.h\").nes.\"\" then pngpath = \"[--]\"\n$!\n$ if f$search(\"[-.zlib]zlib.h\").nes.\"\" then zpath = \"[-.zlib]\"\n$ if f$search(\"[-.libpng]png.h\").nes.\"\" then pngpath = \"[-.libpng]\"\n$!\n$ if zpath .eqs. \"\"\n$ then\n$   write sys$output \"zlib include not found. Exiting...\"\n$   exit 2\n$ endif\n$!\n$ if pngpath .eqs. \"\"\n$ then\n$   write sys$output \"libpng include not found. Exiting...\"\n$   exit 2\n$ endif\n$!\n$!    Look for the compiler used.\n$!\n$ ccopt=\"/include=(''zpath',''pngpath')\"\n$ if f$getsyi(\"HW_MODEL\").ge.1024\n$ then\n$  ccopt = \"/prefix=all\"+ccopt\n$  comp  = \"__decc__=1\"\n$  if f$trnlnm(\"SYS\").eqs.\"\" then define sys sys$library:\n$ else\n$  if f$search(\"SYS$SYSTEM:DECC$COMPILER.EXE\").eqs.\"\"\n$   then\n$    if f$trnlnm(\"SYS\").eqs.\"\" then define sys sys$library:\n$    if f$search(\"SYS$SYSTEM:VAXC.EXE\").eqs.\"\"\n$     then\n$      comp  = \"__gcc__=1\"\n$      CC :== GCC\n$     else\n$      comp = \"__vaxc__=1\"\n$     endif\n$   else\n$    if f$trnlnm(\"SYS\").eqs.\"\" then define sys decc$library_include:\n$    ccopt = \"/decc/prefix=all\"+ccopt\n$    comp  = \"__decc__=1\"\n$  endif\n$ endif\n$ open/write lopt lib.opt\n$ write lopt \"''pngpath'libpng.olb/lib\"\n$ write lopt \"''zpath'libz.olb/lib\"\n$ close lopt\n$ open/write xopt x11.opt\n$ write xopt \"sys$library:decw$xlibshr.exe/share\"\n$ close xopt\n$!\n$!    Build 'em.\n$!\n$ write sys$output \"Compiling PNG book programs ...\"\n$   CALL MAKE readpng.OBJ \"cc ''CCOPT' readpng\" -\n\treadpng.c readpng.h\n$   CALL MAKE readpng2.OBJ \"cc ''CCOPT' readpng2\" -\n\treadpng2.c readpng2.h\n$   CALL MAKE writepng.OBJ \"cc ''CCOPT' writepng\" -\n\twritepng.c writepng.h\n$   write sys$output \"Building rpng-x...\"\n$   CALL MAKE rpng-x.OBJ \"cc ''CCOPT' rpng-x\" -\n\trpng-x.c readpng.h\n$   call make rpng-x.exe -\n\t\"LINK rpng-x,readpng,lib.opt/opt,x11.opt/opt\" -\n\trpng-x.obj readpng.obj\n$   write sys$output \"Building rpng2-x...\"\n$   CALL MAKE rpng2-x.OBJ \"cc ''CCOPT' rpng2-x\" -\n\trpng2-x.c readpng2.h\n$   call make rpng2-x.exe -\n\t\"LINK rpng2-x,readpng2,lib.opt/opt,x11.opt/opt\" -\n\trpng2-x.obj readpng2.obj\n$   write sys$output \"Building wpng...\"\n$   CALL MAKE wpng.OBJ \"cc ''CCOPT' wpng\" -\n\twpng.c writepng.h\n$   call make wpng.exe -\n\t\"LINK wpng,writepng,lib.opt/opt\" -\n\twpng.obj writepng.obj\n$ exit\n$!\n$!\n$MAKE: SUBROUTINE   !SUBROUTINE TO CHECK DEPENDENCIES\n$ V = 'F$Verify(0)\n$! P1 = What we are trying to make\n$! P2 = Command to make it\n$! P3 - P8  What it depends on\n$\n$ If F$Search(P1) .Eqs. \"\" Then Goto Makeit\n$ Time = F$CvTime(F$File(P1,\"RDT\"))\n$arg=3\n$Loop:\n$       Argument = P'arg\n$       If Argument .Eqs. \"\" Then Goto Exit\n$       El=0\n$Loop2:\n$       File = F$Element(El,\" \",Argument)\n$       If File .Eqs. \" \" Then Goto Endl\n$       AFile = \"\"\n$Loop3:\n$       OFile = AFile\n$       AFile = F$Search(File)\n$       If AFile .Eqs. \"\" .Or. AFile .Eqs. OFile Then Goto NextEl\n$       If F$CvTime(F$File(AFile,\"RDT\")) .Ges. Time Then Goto Makeit\n$       Goto Loop3\n$NextEL:\n$       El = El + 1\n$       Goto Loop2\n$EndL:\n$ arg=arg+1\n$ If arg .Le. 8 Then Goto Loop\n$ Goto Exit\n$\n$Makeit:\n$ VV=F$VERIFY(0)\n$ write sys$output P2\n$ 'P2\n$ VV='F$Verify(VV)\n$Exit:\n$ If V Then Set Verify\n$ENDSUBROUTINE\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/readpng.c",
    "content": "/*---------------------------------------------------------------------------\n\n   rpng - simple PNG display program                              readpng.c\n\n  ---------------------------------------------------------------------------\n\n      Copyright (c) 1998-2007 Greg Roelofs.  All rights reserved.\n\n      This software is provided \"as is,\" without warranty of any kind,\n      express or implied.  In no event shall the author or contributors\n      be held liable for any damages arising in any way from the use of\n      this software.\n\n      The contents of this file are DUAL-LICENSED.  You may modify and/or\n      redistribute this software according to the terms of one of the\n      following two licenses (at your option):\n\n\n      LICENSE 1 (\"BSD-like with advertising clause\"):\n\n      Permission is granted to anyone to use this software for any purpose,\n      including commercial applications, and to alter it and redistribute\n      it freely, subject to the following restrictions:\n\n      1. Redistributions of source code must retain the above copyright\n         notice, disclaimer, and this list of conditions.\n      2. Redistributions in binary form must reproduce the above copyright\n         notice, disclaimer, and this list of conditions in the documenta-\n         tion and/or other materials provided with the distribution.\n      3. All advertising materials mentioning features or use of this\n         software must display the following acknowledgment:\n\n            This product includes software developed by Greg Roelofs\n            and contributors for the book, \"PNG: The Definitive Guide,\"\n            published by O'Reilly and Associates.\n\n\n      LICENSE 2 (GNU GPL v2 or later):\n\n      This program is free software; you can redistribute it and/or modify\n      it under the terms of the GNU General Public License as published by\n      the Free Software Foundation; either version 2 of the License, or\n      (at your option) any later version.\n\n      This program is distributed in the hope that it will be useful,\n      but WITHOUT ANY WARRANTY; without even the implied warranty of\n      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n      GNU General Public License for more details.\n\n      You should have received a copy of the GNU General Public License\n      along with this program; if not, write to the Free Software Foundation,\n      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  ---------------------------------------------------------------------------*/\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <zlib.h>\n\n#include \"png.h\"        /* libpng header */\n#include \"readpng.h\"    /* typedefs, common macros, public prototypes */\n\n/* future versions of libpng will provide this macro: */\n#ifndef png_jmpbuf\n#  define png_jmpbuf(png_ptr)   ((png_ptr)->jmpbuf)\n#endif\n\n\nstatic png_structp png_ptr = NULL;\nstatic png_infop info_ptr = NULL;\n\npng_uint_32  width, height;\nint  bit_depth, color_type;\nuch  *image_data = NULL;\n\n\nvoid readpng_version_info(void)\n{\n    fprintf(stderr, \"   Compiled with libpng %s; using libpng %s.\\n\",\n      PNG_LIBPNG_VER_STRING, png_libpng_ver);\n    fprintf(stderr, \"   Compiled with zlib %s; using zlib %s.\\n\",\n      ZLIB_VERSION, zlib_version);\n}\n\n\n/* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */\n\nint readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight)\n{\n    uch sig[8];\n\n\n    /* first do a quick check that the file really is a PNG image; could\n     * have used slightly more general png_sig_cmp() function instead */\n\n    fread(sig, 1, 8, infile);\n    if (png_sig_cmp(sig, 0, 8))\n        return 1;   /* bad signature */\n\n\n    /* could pass pointers to user-defined error handlers instead of NULLs: */\n\n    png_ptr = png_create_read_struct(png_get_libpng_ver(NULL), NULL, NULL,\n        NULL);\n    if (!png_ptr)\n        return 4;   /* out of memory */\n\n    info_ptr = png_create_info_struct(png_ptr);\n    if (!info_ptr) {\n        png_destroy_read_struct(&png_ptr, NULL, NULL);\n        return 4;   /* out of memory */\n    }\n\n\n    /* we could create a second info struct here (end_info), but it's only\n     * useful if we want to keep pre- and post-IDAT chunk info separated\n     * (mainly for PNG-aware image editors and converters) */\n\n\n    /* setjmp() must be called in every function that calls a PNG-reading\n     * libpng function */\n\n    if (setjmp(png_jmpbuf(png_ptr))) {\n        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n        return 2;\n    }\n\n\n    png_init_io(png_ptr, infile);\n    png_set_sig_bytes(png_ptr, 8);  /* we already read the 8 signature bytes */\n\n    png_read_info(png_ptr, info_ptr);  /* read all PNG info up to image data */\n\n\n    /* alternatively, could make separate calls to png_get_image_width(),\n     * etc., but want bit_depth and color_type for later [don't care about\n     * compression_type and filter_type => NULLs] */\n\n    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,\n      NULL, NULL, NULL);\n    *pWidth = width;\n    *pHeight = height;\n\n\n    /* OK, that's all we need for now; return happy */\n\n    return 0;\n}\n\n\n\n\n/* returns 0 if succeeds, 1 if fails due to no bKGD chunk, 2 if libpng error;\n * scales values to 8-bit if necessary */\n\nint readpng_get_bgcolor(uch *red, uch *green, uch *blue)\n{\n    png_color_16p pBackground;\n\n\n    /* setjmp() must be called in every function that calls a PNG-reading\n     * libpng function */\n\n    if (setjmp(png_jmpbuf(png_ptr))) {\n        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n        return 2;\n    }\n\n\n    if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD))\n        return 1;\n\n    /* it is not obvious from the libpng documentation, but this function\n     * takes a pointer to a pointer, and it always returns valid red, green\n     * and blue values, regardless of color_type: */\n\n    png_get_bKGD(png_ptr, info_ptr, &pBackground);\n\n\n    /* however, it always returns the raw bKGD data, regardless of any\n     * bit-depth transformations, so check depth and adjust if necessary */\n\n    if (bit_depth == 16) {\n        *red   = pBackground->red   >> 8;\n        *green = pBackground->green >> 8;\n        *blue  = pBackground->blue  >> 8;\n    } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {\n        if (bit_depth == 1)\n            *red = *green = *blue = pBackground->gray? 255 : 0;\n        else if (bit_depth == 2)\n            *red = *green = *blue = (255/3) * pBackground->gray;\n        else /* bit_depth == 4 */\n            *red = *green = *blue = (255/15) * pBackground->gray;\n    } else {\n        *red   = (uch)pBackground->red;\n        *green = (uch)pBackground->green;\n        *blue  = (uch)pBackground->blue;\n    }\n\n    return 0;\n}\n\n\n\n\n/* display_exponent == LUT_exponent * CRT_exponent */\n\nuch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)\n{\n    double  gamma;\n    png_uint_32  i, rowbytes;\n    png_bytepp  row_pointers = NULL;\n\n\n    /* setjmp() must be called in every function that calls a PNG-reading\n     * libpng function */\n\n    if (setjmp(png_jmpbuf(png_ptr))) {\n        free(image_data);\n        image_data = NULL;\n        free(row_pointers);\n        row_pointers = NULL;\n        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n        return NULL;\n    }\n\n\n    /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,\n     * transparency chunks to full alpha channel; strip 16-bit-per-sample\n     * images to 8 bits per sample; and convert grayscale to RGB[A] */\n\n    if (color_type == PNG_COLOR_TYPE_PALETTE)\n        png_set_expand(png_ptr);\n    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)\n        png_set_expand(png_ptr);\n    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))\n        png_set_expand(png_ptr);\n#ifdef PNG_READ_16_TO_8_SUPPORTED\n    if (bit_depth == 16)\n#  ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\n        png_set_scale_16(png_ptr);\n#  else\n        png_set_strip_16(png_ptr);\n#  endif\n#endif\n    if (color_type == PNG_COLOR_TYPE_GRAY ||\n        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n        png_set_gray_to_rgb(png_ptr);\n\n\n    /* unlike the example in the libpng documentation, we have *no* idea where\n     * this file may have come from--so if it doesn't have a file gamma, don't\n     * do any correction (\"do no harm\") */\n\n    if (png_get_gAMA(png_ptr, info_ptr, &gamma))\n        png_set_gamma(png_ptr, display_exponent, gamma);\n\n\n    /* all transformations have been registered; now update info_ptr data,\n     * get rowbytes and channels, and allocate image memory */\n\n    png_read_update_info(png_ptr, info_ptr);\n\n    *pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr);\n    *pChannels = (int)png_get_channels(png_ptr, info_ptr);\n\n    if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {\n        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n        return NULL;\n    }\n    if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) {\n        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n        free(image_data);\n        image_data = NULL;\n        return NULL;\n    }\n\n    Trace((stderr, \"readpng_get_image:  channels = %d, rowbytes = %ld, height = %ld\\n\",\n        *pChannels, rowbytes, height));\n\n\n    /* set the individual row_pointers to point at the correct offsets */\n\n    for (i = 0;  i < height;  ++i)\n        row_pointers[i] = image_data + i*rowbytes;\n\n\n    /* now we can go ahead and just read the whole image */\n\n    png_read_image(png_ptr, row_pointers);\n\n\n    /* and we're done!  (png_read_end() can be omitted if no processing of\n     * post-IDAT text/time/etc. is desired) */\n\n    free(row_pointers);\n    row_pointers = NULL;\n\n    png_read_end(png_ptr, NULL);\n\n    return image_data;\n}\n\n\nvoid readpng_cleanup(int free_image_data)\n{\n    if (free_image_data && image_data) {\n        free(image_data);\n        image_data = NULL;\n    }\n\n    if (png_ptr && info_ptr) {\n        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n        png_ptr = NULL;\n        info_ptr = NULL;\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/readpng.h",
    "content": "/*---------------------------------------------------------------------------\n\n   rpng - simple PNG display program                              readpng.h\n\n  ---------------------------------------------------------------------------\n\n      Copyright (c) 1998-2007 Greg Roelofs.  All rights reserved.\n\n      This software is provided \"as is,\" without warranty of any kind,\n      express or implied.  In no event shall the author or contributors\n      be held liable for any damages arising in any way from the use of\n      this software.\n\n      The contents of this file are DUAL-LICENSED.  You may modify and/or\n      redistribute this software according to the terms of one of the\n      following two licenses (at your option):\n\n\n      LICENSE 1 (\"BSD-like with advertising clause\"):\n\n      Permission is granted to anyone to use this software for any purpose,\n      including commercial applications, and to alter it and redistribute\n      it freely, subject to the following restrictions:\n\n      1. Redistributions of source code must retain the above copyright\n         notice, disclaimer, and this list of conditions.\n      2. Redistributions in binary form must reproduce the above copyright\n         notice, disclaimer, and this list of conditions in the documenta-\n         tion and/or other materials provided with the distribution.\n      3. All advertising materials mentioning features or use of this\n         software must display the following acknowledgment:\n\n            This product includes software developed by Greg Roelofs\n            and contributors for the book, \"PNG: The Definitive Guide,\"\n            published by O'Reilly and Associates.\n\n\n      LICENSE 2 (GNU GPL v2 or later):\n\n      This program is free software; you can redistribute it and/or modify\n      it under the terms of the GNU General Public License as published by\n      the Free Software Foundation; either version 2 of the License, or\n      (at your option) any later version.\n\n      This program is distributed in the hope that it will be useful,\n      but WITHOUT ANY WARRANTY; without even the implied warranty of\n      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n      GNU General Public License for more details.\n\n      You should have received a copy of the GNU General Public License\n      along with this program; if not, write to the Free Software Foundation,\n      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  ---------------------------------------------------------------------------*/\n\n#ifndef TRUE\n#  define TRUE 1\n#  define FALSE 0\n#endif\n\n#ifndef MAX\n#  define MAX(a,b)  ((a) > (b)? (a) : (b))\n#  define MIN(a,b)  ((a) < (b)? (a) : (b))\n#endif\n\n#ifdef DEBUG\n#  define Trace(x)  {fprintf x ; fflush(stderr); fflush(stdout);}\n#else\n#  define Trace(x)  ;\n#endif\n\ntypedef unsigned char   uch;\ntypedef unsigned short  ush;\ntypedef unsigned long   ulg;\n\n\n/* prototypes for public functions in readpng.c */\n\nvoid readpng_version_info(void);\n\nint readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight);\n\nint readpng_get_bgcolor(uch *bg_red, uch *bg_green, uch *bg_blue);\n\nuch *readpng_get_image(double display_exponent, int *pChannels,\n                       ulg *pRowbytes);\n\nvoid readpng_cleanup(int free_image_data);\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/readpng2.c",
    "content": "/*---------------------------------------------------------------------------\n\n   rpng2 - progressive-model PNG display program                 readpng2.c\n\n  ---------------------------------------------------------------------------\n\n      Copyright (c) 1998-2015 Greg Roelofs.  All rights reserved.\n\n      This software is provided \"as is,\" without warranty of any kind,\n      express or implied.  In no event shall the author or contributors\n      be held liable for any damages arising in any way from the use of\n      this software.\n\n      The contents of this file are DUAL-LICENSED.  You may modify and/or\n      redistribute this software according to the terms of one of the\n      following two licenses (at your option):\n\n\n      LICENSE 1 (\"BSD-like with advertising clause\"):\n\n      Permission is granted to anyone to use this software for any purpose,\n      including commercial applications, and to alter it and redistribute\n      it freely, subject to the following restrictions:\n\n      1. Redistributions of source code must retain the above copyright\n         notice, disclaimer, and this list of conditions.\n      2. Redistributions in binary form must reproduce the above copyright\n         notice, disclaimer, and this list of conditions in the documenta-\n         tion and/or other materials provided with the distribution.\n      3. All advertising materials mentioning features or use of this\n         software must display the following acknowledgment:\n\n            This product includes software developed by Greg Roelofs\n            and contributors for the book, \"PNG: The Definitive Guide,\"\n            published by O'Reilly and Associates.\n\n\n      LICENSE 2 (GNU GPL v2 or later):\n\n      This program is free software; you can redistribute it and/or modify\n      it under the terms of the GNU General Public License as published by\n      the Free Software Foundation; either version 2 of the License, or\n      (at your option) any later version.\n\n      This program is distributed in the hope that it will be useful,\n      but WITHOUT ANY WARRANTY; without even the implied warranty of\n      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n      GNU General Public License for more details.\n\n      You should have received a copy of the GNU General Public License\n      along with this program; if not, write to the Free Software Foundation,\n      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  ---------------------------------------------------------------------------\n\n   Changelog:\n     %RDATE% - Check return value of png_get_bKGD() (Glenn R-P)\n\n  ---------------------------------------------------------------------------*/\n\n\n#include <stdlib.h>     /* for exit() prototype */\n#include <setjmp.h>\n\n#include <zlib.h>\n#include \"png.h\"        /* libpng header from the local directory */\n#include \"readpng2.h\"   /* typedefs, common macros, public prototypes */\n\n\n/* local prototypes */\n\nstatic void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr);\nstatic void readpng2_row_callback(png_structp png_ptr, png_bytep new_row,\n                                 png_uint_32 row_num, int pass);\nstatic void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr);\nstatic void readpng2_error_handler(png_structp png_ptr, png_const_charp msg);\nstatic void readpng2_warning_handler(png_structp png_ptr, png_const_charp msg);\n\n\n\n\nvoid readpng2_version_info(void)\n{\n    fprintf(stderr, \"   Compiled with libpng %s; using libpng %s\\n\",\n      PNG_LIBPNG_VER_STRING, png_libpng_ver);\n\n    fprintf(stderr, \"   and with zlib %s; using zlib %s.\\n\",\n      ZLIB_VERSION, zlib_version);\n}\n\n\n\n\nint readpng2_check_sig(uch *sig, int num)\n{\n    return !png_sig_cmp(sig, 0, num);\n}\n\n\n\n\n/* returns 0 for success, 2 for libpng problem, 4 for out of memory */\n\nint readpng2_init(mainprog_info *mainprog_ptr)\n{\n    png_structp  png_ptr;       /* note:  temporary variables! */\n    png_infop  info_ptr;\n\n\n    /* could also replace libpng warning-handler (final NULL), but no need: */\n\n    png_ptr = png_create_read_struct(png_get_libpng_ver(NULL), mainprog_ptr,\n      readpng2_error_handler, readpng2_warning_handler);\n    if (!png_ptr)\n        return 4;   /* out of memory */\n\n    info_ptr = png_create_info_struct(png_ptr);\n    if (!info_ptr) {\n        png_destroy_read_struct(&png_ptr, NULL, NULL);\n        return 4;   /* out of memory */\n    }\n\n\n    /* we could create a second info struct here (end_info), but it's only\n     * useful if we want to keep pre- and post-IDAT chunk info separated\n     * (mainly for PNG-aware image editors and converters) */\n\n\n    /* setjmp() must be called in every function that calls a PNG-reading\n     * libpng function, unless an alternate error handler was installed--\n     * but compatible error handlers must either use longjmp() themselves\n     * (as in this program) or exit immediately, so here we are: */\n\n    if (setjmp(mainprog_ptr->jmpbuf)) {\n        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n        return 2;\n    }\n\n\n#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED\n    /* prepare the reader to ignore all recognized chunks whose data won't be\n     * used, i.e., all chunks recognized by libpng except for IHDR, PLTE, IDAT,\n     * IEND, tRNS, bKGD, gAMA, and sRGB (small performance improvement) */\n    {\n        /* These byte strings were copied from png.h.  If a future version\n         * of readpng2.c recognizes more chunks, add them to this list.\n         */\n        static PNG_CONST png_byte chunks_to_process[] = {\n            98,  75,  71,  68, '\\0',  /* bKGD */\n           103,  65,  77,  65, '\\0',  /* gAMA */\n           115,  82,  71,  66, '\\0',  /* sRGB */\n           };\n\n       /* Ignore all chunks except for IHDR, PLTE, tRNS, IDAT, and IEND */\n       png_set_keep_unknown_chunks(png_ptr, -1 /* PNG_HANDLE_CHUNK_NEVER */,\n          NULL, -1);\n\n       /* But do not ignore chunks in the \"chunks_to_process\" list */\n       png_set_keep_unknown_chunks(png_ptr,\n          0 /* PNG_HANDLE_CHUNK_AS_DEFAULT */, chunks_to_process,\n          sizeof(chunks_to_process)/5);\n    }\n#endif /* PNG_HANDLE_AS_UNKNOWN_SUPPORTED */\n\n\n    /* instead of doing png_init_io() here, now we set up our callback\n     * functions for progressive decoding */\n\n    png_set_progressive_read_fn(png_ptr, mainprog_ptr,\n      readpng2_info_callback, readpng2_row_callback, readpng2_end_callback);\n\n\n    /* make sure we save our pointers for use in readpng2_decode_data() */\n\n    mainprog_ptr->png_ptr = png_ptr;\n    mainprog_ptr->info_ptr = info_ptr;\n\n\n    /* and that's all there is to initialization */\n\n    return 0;\n}\n\n\n\n\n/* returns 0 for success, 2 for libpng (longjmp) problem */\n\nint readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length)\n{\n    png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;\n    png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;\n\n\n    /* setjmp() must be called in every function that calls a PNG-reading\n     * libpng function */\n\n    if (setjmp(mainprog_ptr->jmpbuf)) {\n        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n        mainprog_ptr->png_ptr = NULL;\n        mainprog_ptr->info_ptr = NULL;\n        return 2;\n    }\n\n\n    /* hand off the next chunk of input data to libpng for decoding */\n\n    png_process_data(png_ptr, info_ptr, rawbuf, length);\n\n    return 0;\n}\n\n\n\n\nstatic void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr)\n{\n    mainprog_info  *mainprog_ptr;\n    int  color_type, bit_depth;\n    png_uint_32 width, height;\n#ifdef PNG_FLOATING_POINT_SUPPORTED\n    double  gamma;\n#else\n    png_fixed_point gamma;\n#endif\n\n\n    /* setjmp() doesn't make sense here, because we'd either have to exit(),\n     * longjmp() ourselves, or return control to libpng, which doesn't want\n     * to see us again.  By not doing anything here, libpng will instead jump\n     * to readpng2_decode_data(), which can return an error value to the main\n     * program. */\n\n\n    /* retrieve the pointer to our special-purpose struct, using the png_ptr\n     * that libpng passed back to us (i.e., not a global this time--there's\n     * no real difference for a single image, but for a multithreaded browser\n     * decoding several PNG images at the same time, one needs to avoid mixing\n     * up different images' structs) */\n\n    mainprog_ptr = png_get_progressive_ptr(png_ptr);\n\n    if (mainprog_ptr == NULL) {         /* we be hosed */\n        fprintf(stderr,\n          \"readpng2 error:  main struct not recoverable in info_callback.\\n\");\n        fflush(stderr);\n        return;\n        /*\n         * Alternatively, we could call our error-handler just like libpng\n         * does, which would effectively terminate the program.  Since this\n         * can only happen if png_ptr gets redirected somewhere odd or the\n         * main PNG struct gets wiped, we're probably toast anyway.  (If\n         * png_ptr itself is NULL, we would not have been called.)\n         */\n    }\n\n\n    /* this is just like in the non-progressive case */\n\n    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,\n       NULL, NULL, NULL);\n    mainprog_ptr->width = (ulg)width;\n    mainprog_ptr->height = (ulg)height;\n\n\n    /* since we know we've read all of the PNG file's \"header\" (i.e., up\n     * to IDAT), we can check for a background color here */\n\n    if (mainprog_ptr->need_bgcolor)\n    {\n        png_color_16p pBackground;\n\n        /* it is not obvious from the libpng documentation, but this function\n         * takes a pointer to a pointer, and it always returns valid red,\n         * green and blue values, regardless of color_type: */\n        if (png_get_bKGD(png_ptr, info_ptr, &pBackground))\n        {\n\n           /* however, it always returns the raw bKGD data, regardless of any\n            * bit-depth transformations, so check depth and adjust if necessary\n            */\n           if (bit_depth == 16) {\n               mainprog_ptr->bg_red   = pBackground->red   >> 8;\n               mainprog_ptr->bg_green = pBackground->green >> 8;\n               mainprog_ptr->bg_blue  = pBackground->blue  >> 8;\n           } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {\n               if (bit_depth == 1)\n                   mainprog_ptr->bg_red = mainprog_ptr->bg_green =\n                     mainprog_ptr->bg_blue = pBackground->gray? 255 : 0;\n               else if (bit_depth == 2)\n                   mainprog_ptr->bg_red = mainprog_ptr->bg_green =\n                     mainprog_ptr->bg_blue = (255/3) * pBackground->gray;\n               else /* bit_depth == 4 */\n                   mainprog_ptr->bg_red = mainprog_ptr->bg_green =\n                     mainprog_ptr->bg_blue = (255/15) * pBackground->gray;\n           } else {\n               mainprog_ptr->bg_red   = (uch)pBackground->red;\n               mainprog_ptr->bg_green = (uch)pBackground->green;\n               mainprog_ptr->bg_blue  = (uch)pBackground->blue;\n           }\n        }\n    }\n\n\n    /* as before, let libpng expand palette images to RGB, low-bit-depth\n     * grayscale images to 8 bits, transparency chunks to full alpha channel;\n     * strip 16-bit-per-sample images to 8 bits per sample; and convert\n     * grayscale to RGB[A] */\n\n    if (color_type == PNG_COLOR_TYPE_PALETTE)\n        png_set_expand(png_ptr);\n    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)\n        png_set_expand(png_ptr);\n    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))\n        png_set_expand(png_ptr);\n#ifdef PNG_READ_16_TO_8_SUPPORTED\n    if (bit_depth == 16)\n#  ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\n        png_set_scale_16(png_ptr);\n#  else\n        png_set_strip_16(png_ptr);\n#  endif\n#endif\n    if (color_type == PNG_COLOR_TYPE_GRAY ||\n        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n        png_set_gray_to_rgb(png_ptr);\n\n\n    /* Unlike the basic viewer, which was designed to operate on local files,\n     * this program is intended to simulate a web browser--even though we\n     * actually read from a local file, too.  But because we are pretending\n     * that most of the images originate on the Internet, we follow the recom-\n     * mendation of the sRGB proposal and treat unlabelled images (no gAMA\n     * chunk) as existing in the sRGB color space.  That is, we assume that\n     * such images have a file gamma of 0.45455, which corresponds to a PC-like\n     * display system.  This change in assumptions will have no effect on a\n     * PC-like system, but on a Mac, SGI, NeXT or other system with a non-\n     * identity lookup table, it will darken unlabelled images, which effec-\n     * tively favors images from PC-like systems over those originating on\n     * the local platform.  Note that mainprog_ptr->display_exponent is the\n     * \"gamma\" value for the entire display system, i.e., the product of\n     * LUT_exponent and CRT_exponent. */\n\n#ifdef PNG_FLOATING_POINT_SUPPORTED\n    if (png_get_gAMA(png_ptr, info_ptr, &gamma))\n        png_set_gamma(png_ptr, mainprog_ptr->display_exponent, gamma);\n    else\n        png_set_gamma(png_ptr, mainprog_ptr->display_exponent, 0.45455);\n#else\n    if (png_get_gAMA_fixed(png_ptr, info_ptr, &gamma))\n        png_set_gamma_fixed(png_ptr,\n            (png_fixed_point)(100000*mainprog_ptr->display_exponent+.5), gamma);\n    else\n        png_set_gamma_fixed(png_ptr,\n            (png_fixed_point)(100000*mainprog_ptr->display_exponent+.5), 45455);\n#endif\n\n    /* we'll let libpng expand interlaced images, too */\n\n    mainprog_ptr->passes = png_set_interlace_handling(png_ptr);\n\n\n    /* all transformations have been registered; now update info_ptr data and\n     * then get rowbytes and channels */\n\n    png_read_update_info(png_ptr, info_ptr);\n\n    mainprog_ptr->rowbytes = (int)png_get_rowbytes(png_ptr, info_ptr);\n    mainprog_ptr->channels = png_get_channels(png_ptr, info_ptr);\n\n\n    /* Call the main program to allocate memory for the image buffer and\n     * initialize windows and whatnot.  (The old-style function-pointer\n     * invocation is used for compatibility with a few supposedly ANSI\n     * compilers that nevertheless barf on \"fn_ptr()\"-style syntax.) */\n\n    (*mainprog_ptr->mainprog_init)();\n\n\n    /* and that takes care of initialization */\n\n    return;\n}\n\n\n\n\n\nstatic void readpng2_row_callback(png_structp png_ptr, png_bytep new_row,\n                                  png_uint_32 row_num, int pass)\n{\n    mainprog_info  *mainprog_ptr;\n\n\n    /* first check whether the row differs from the previous pass; if not,\n     * nothing to combine or display */\n\n    if (!new_row)\n        return;\n\n\n    /* retrieve the pointer to our special-purpose struct so we can access\n     * the old rows and image-display callback function */\n\n    mainprog_ptr = png_get_progressive_ptr(png_ptr);\n\n\n    /* save the pass number for optional use by the front end */\n\n    mainprog_ptr->pass = pass;\n\n\n    /* have libpng either combine the new row data with the existing row data\n     * from previous passes (if interlaced) or else just copy the new row\n     * into the main program's image buffer */\n\n    png_progressive_combine_row(png_ptr, mainprog_ptr->row_pointers[row_num],\n      new_row);\n\n\n    /* finally, call the display routine in the main program with the number\n     * of the row we just updated */\n\n    (*mainprog_ptr->mainprog_display_row)(row_num);\n\n\n    /* and we're ready for more */\n\n    return;\n}\n\n\n\n\n\nstatic void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr)\n{\n    mainprog_info  *mainprog_ptr;\n\n\n    /* retrieve the pointer to our special-purpose struct */\n\n    mainprog_ptr = png_get_progressive_ptr(png_ptr);\n\n\n    /* let the main program know that it should flush any buffered image\n     * data to the display now and set a \"done\" flag or whatever, but note\n     * that it SHOULD NOT DESTROY THE PNG STRUCTS YET--in other words, do\n     * NOT call readpng2_cleanup() either here or in the finish_display()\n     * routine; wait until control returns to the main program via\n     * readpng2_decode_data() */\n\n    (*mainprog_ptr->mainprog_finish_display)();\n\n\n    /* all done */\n\n    (void)info_ptr; /* Unused */\n\n    return;\n}\n\n\n\n\n\nvoid readpng2_cleanup(mainprog_info *mainprog_ptr)\n{\n    png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;\n    png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;\n\n    if (png_ptr && info_ptr)\n        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n\n    mainprog_ptr->png_ptr = NULL;\n    mainprog_ptr->info_ptr = NULL;\n}\n\n\nstatic void readpng2_warning_handler(png_structp png_ptr, png_const_charp msg)\n{\n    fprintf(stderr, \"readpng2 libpng warning: %s\\n\", msg);\n    fflush(stderr);\n    (void)png_ptr; /* Unused */\n}\n\n\nstatic void readpng2_error_handler(png_structp png_ptr, png_const_charp msg)\n{\n    mainprog_info  *mainprog_ptr;\n\n    /* This function, aside from the extra step of retrieving the \"error\n     * pointer\" (below) and the fact that it exists within the application\n     * rather than within libpng, is essentially identical to libpng's\n     * default error handler.  The second point is critical:  since both\n     * setjmp() and longjmp() are called from the same code, they are\n     * guaranteed to have compatible notions of how big a jmp_buf is,\n     * regardless of whether _BSD_SOURCE or anything else has (or has not)\n     * been defined. */\n\n    fprintf(stderr, \"readpng2 libpng error: %s\\n\", msg);\n    fflush(stderr);\n\n    mainprog_ptr = png_get_error_ptr(png_ptr);\n    if (mainprog_ptr == NULL) {         /* we are completely hosed now */\n        fprintf(stderr,\n          \"readpng2 severe error:  jmpbuf not recoverable; terminating.\\n\");\n        fflush(stderr);\n        exit(99);\n    }\n\n    /* Now we have our data structure we can use the information in it\n     * to return control to our own higher level code (all the points\n     * where 'setjmp' is called in this file.)  This will work with other\n     * error handling mechanisms as well - libpng always calls png_error\n     * when it can proceed no further, thus, so long as the error handler\n     * is intercepted, application code can do its own error recovery.\n     */\n    longjmp(mainprog_ptr->jmpbuf, 1);\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/readpng2.h",
    "content": "/*---------------------------------------------------------------------------\n\n   rpng2 - progressive-model PNG display program                 readpng2.h\n\n  ---------------------------------------------------------------------------\n\n      Copyright (c) 1998-2008 Greg Roelofs.  All rights reserved.\n\n      This software is provided \"as is,\" without warranty of any kind,\n      express or implied.  In no event shall the author or contributors\n      be held liable for any damages arising in any way from the use of\n      this software.\n\n      The contents of this file are DUAL-LICENSED.  You may modify and/or\n      redistribute this software according to the terms of one of the\n      following two licenses (at your option):\n\n\n      LICENSE 1 (\"BSD-like with advertising clause\"):\n\n      Permission is granted to anyone to use this software for any purpose,\n      including commercial applications, and to alter it and redistribute\n      it freely, subject to the following restrictions:\n\n      1. Redistributions of source code must retain the above copyright\n         notice, disclaimer, and this list of conditions.\n      2. Redistributions in binary form must reproduce the above copyright\n         notice, disclaimer, and this list of conditions in the documenta-\n         tion and/or other materials provided with the distribution.\n      3. All advertising materials mentioning features or use of this\n         software must display the following acknowledgment:\n\n            This product includes software developed by Greg Roelofs\n            and contributors for the book, \"PNG: The Definitive Guide,\"\n            published by O'Reilly and Associates.\n\n\n      LICENSE 2 (GNU GPL v2 or later):\n\n      This program is free software; you can redistribute it and/or modify\n      it under the terms of the GNU General Public License as published by\n      the Free Software Foundation; either version 2 of the License, or\n      (at your option) any later version.\n\n      This program is distributed in the hope that it will be useful,\n      but WITHOUT ANY WARRANTY; without even the implied warranty of\n      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n      GNU General Public License for more details.\n\n      You should have received a copy of the GNU General Public License\n      along with this program; if not, write to the Free Software Foundation,\n      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  ---------------------------------------------------------------------------*/\n\n#ifndef TRUE\n#  define TRUE 1\n#  define FALSE 0\n#endif\n\n#ifndef MAX\n#  define MAX(a,b)  ((a) > (b)? (a) : (b))\n#  define MIN(a,b)  ((a) < (b)? (a) : (b))\n#endif\n\n#ifdef DEBUG\n#  define Trace(x)  {fprintf x ; fflush(stderr); fflush(stdout);}\n#else\n#  define Trace(x)  ;\n#endif\n\nenum rpng2_states {\n    kPreInit = 0,\n    kWindowInit,\n    kDone\n};\n\ntypedef unsigned char   uch;\ntypedef unsigned short  ush;\ntypedef unsigned long   ulg;\n\ntypedef struct _mainprog_info {\n    double display_exponent;\n    ulg width;\n    ulg height;\n    void *png_ptr;\n    void *info_ptr;\n    void (*mainprog_init)(void);\n    void (*mainprog_display_row)(ulg row_num);\n    void (*mainprog_finish_display)(void);\n    uch *image_data;\n    uch **row_pointers;\n    jmp_buf jmpbuf;\n    int passes;              /* not used */\n    int pass;\n    int rowbytes;\n    int channels;\n    int need_bgcolor;\n    int state;\n    uch bg_red;\n    uch bg_green;\n    uch bg_blue;\n} mainprog_info;\n\n\n/* prototypes for public functions in readpng2.c */\n\nvoid readpng2_version_info(void);\n\nint readpng2_check_sig(uch *sig, int num);\n\nint readpng2_init(mainprog_info *mainprog_ptr);\n\nint readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length);\n\nvoid readpng2_cleanup(mainprog_info *mainprog_ptr);\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/readppm.c",
    "content": "/*---------------------------------------------------------------------------\n\n   rpng - simple PNG display program                              readppm.c\n\n  ---------------------------------------------------------------------------\n\n   This is a special-purpose replacement for readpng.c that allows binary\n   PPM files to be used in place of PNG images.\n\n  ---------------------------------------------------------------------------\n\n      Copyright (c) 1998-2007 Greg Roelofs.  All rights reserved.\n\n      This software is provided \"as is,\" without warranty of any kind,\n      express or implied.  In no event shall the author or contributors\n      be held liable for any damages arising in any way from the use of\n      this software.\n\n      The contents of this file are DUAL-LICENSED.  You may modify and/or\n      redistribute this software according to the terms of one of the\n      following two licenses (at your option):\n\n\n      LICENSE 1 (\"BSD-like with advertising clause\"):\n\n      Permission is granted to anyone to use this software for any purpose,\n      including commercial applications, and to alter it and redistribute\n      it freely, subject to the following restrictions:\n\n      1. Redistributions of source code must retain the above copyright\n         notice, disclaimer, and this list of conditions.\n      2. Redistributions in binary form must reproduce the above copyright\n         notice, disclaimer, and this list of conditions in the documenta-\n         tion and/or other materials provided with the distribution.\n      3. All advertising materials mentioning features or use of this\n         software must display the following acknowledgment:\n\n            This product includes software developed by Greg Roelofs\n            and contributors for the book, \"PNG: The Definitive Guide,\"\n            published by O'Reilly and Associates.\n\n\n      LICENSE 2 (GNU GPL v2 or later):\n\n      This program is free software; you can redistribute it and/or modify\n      it under the terms of the GNU General Public License as published by\n      the Free Software Foundation; either version 2 of the License, or\n      (at your option) any later version.\n\n      This program is distributed in the hope that it will be useful,\n      but WITHOUT ANY WARRANTY; without even the implied warranty of\n      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n      GNU General Public License for more details.\n\n      You should have received a copy of the GNU General Public License\n      along with this program; if not, write to the Free Software Foundation,\n      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  ---------------------------------------------------------------------------*/\n\n#include <stdio.h>\n#include <stdlib.h>\n\n#include \"readpng.h\"    /* typedefs, common macros, public prototypes */\n\n\nulg  width, height;\nint  bit_depth, color_type, channels;\nuch  *image_data = NULL;\nFILE *saved_infile;\n\n\nvoid readpng_version_info()\n{\n    fprintf(stderr, \"   Compiled without libpng, zlib or PBMPLUS/NetPBM.\\n\");\n}\n\n\n/* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */\n\nint readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight)\n{\n    static uch ppmline[256];\n    int maxval;\n\n\n    saved_infile = infile;\n\n    fgets(ppmline, 256, infile);\n    if (ppmline[0] != 'P' || ppmline[1] != '6') {\n        fprintf(stderr, \"ERROR:  not a PPM file\\n\");\n        return 1;\n    }\n    /* possible color types:  P5 = grayscale (0), P6 = RGB (2), P8 = RGBA (6) */\n    if (ppmline[1] == '6') {\n        color_type = 2;\n        channels = 3;\n    } else if (ppmline[1] == '8') {\n        color_type = 6;\n        channels = 4;\n    } else /* if (ppmline[1] == '5') */ {\n        color_type = 0;\n        channels = 1;\n    }\n\n    do {\n        fgets(ppmline, 256, infile);\n    } while (ppmline[0] == '#');\n    sscanf(ppmline, \"%lu %lu\", &width, &height);\n\n    do {\n        fgets(ppmline, 256, infile);\n    } while (ppmline[0] == '#');\n    sscanf(ppmline, \"%d\", &maxval);\n    if (maxval != 255) {\n        fprintf(stderr, \"ERROR:  maxval = %d\\n\", maxval);\n        return 2;\n    }\n    bit_depth = 8;\n\n    *pWidth = width;\n    *pHeight = height;\n\n    return 0;\n}\n\n\n\n\n/* returns 0 if succeeds, 1 if fails due to no bKGD chunk, 2 if libpng error;\n * scales values to 8-bit if necessary */\n\nint readpng_get_bgcolor(uch *red, uch *green, uch *blue)\n{\n    return 1;\n}\n\n\n\n\n/* display_exponent == LUT_exponent * CRT_exponent */\n\nuch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)\n{\n    ulg  rowbytes;\n\n\n    /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,\n     * transparency chunks to full alpha channel; strip 16-bit-per-sample\n     * images to 8 bits per sample; and convert grayscale to RGB[A] */\n\n    /* GRR WARNING:  grayscale needs to be expanded and channels reset! */\n\n    *pRowbytes = rowbytes = channels*width;\n    *pChannels = channels;\n\n    if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {\n        return NULL;\n    }\n\n    Trace((stderr, \"readpng_get_image:  rowbytes = %ld, height = %ld\\n\", rowbytes, height));\n\n\n    /* now we can go ahead and just read the whole image */\n\n    if (fread(image_data, 1L, rowbytes*height, saved_infile) <\n       rowbytes*height) {\n        free (image_data);\n        image_data = NULL;\n        return NULL;\n    }\n\n    return image_data;\n}\n\n\nvoid readpng_cleanup(int free_image_data)\n{\n    if (free_image_data && image_data) {\n        free(image_data);\n        image_data = NULL;\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/rpng-win.c",
    "content": "/*---------------------------------------------------------------------------\n\n   rpng - simple PNG display program                             rpng-win.c\n\n   This program decodes and displays PNG images, with gamma correction and\n   optionally with a user-specified background color (in case the image has\n   transparency).  It is very nearly the most basic PNG viewer possible.\n   This version is for 32-bit Windows; it may compile under 16-bit Windows\n   with a little tweaking (or maybe not).\n\n   to do:\n    - handle quoted command-line args (especially filenames with spaces)\n    - have minimum window width:  oh well\n    - use %.1023s to simplify truncation of title-bar string?\n\n  ---------------------------------------------------------------------------\n\n   Changelog:\n    - 1.00:  initial public release\n    - 1.01:  modified to allow abbreviated options; fixed long/ulong mis-\n              match; switched to png_jmpbuf() macro\n    - 1.02:  added extra set of parentheses to png_jmpbuf() macro; fixed\n              command-line parsing bug\n    - 1.10:  enabled \"message window\"/console (thanks to David Geldreich)\n    - 2.00:  dual-licensed (added GNU GPL)\n    - 2.01:  fixed improper display of usage screen on PNG error(s)\n\n  ---------------------------------------------------------------------------\n\n      Copyright (c) 1998-2008 Greg Roelofs.  All rights reserved.\n\n      This software is provided \"as is,\" without warranty of any kind,\n      express or implied.  In no event shall the author or contributors\n      be held liable for any damages arising in any way from the use of\n      this software.\n\n      The contents of this file are DUAL-LICENSED.  You may modify and/or\n      redistribute this software according to the terms of one of the\n      following two licenses (at your option):\n\n\n      LICENSE 1 (\"BSD-like with advertising clause\"):\n\n      Permission is granted to anyone to use this software for any purpose,\n      including commercial applications, and to alter it and redistribute\n      it freely, subject to the following restrictions:\n\n      1. Redistributions of source code must retain the above copyright\n         notice, disclaimer, and this list of conditions.\n      2. Redistributions in binary form must reproduce the above copyright\n         notice, disclaimer, and this list of conditions in the documenta-\n         tion and/or other materials provided with the distribution.\n      3. All advertising materials mentioning features or use of this\n         software must display the following acknowledgment:\n\n            This product includes software developed by Greg Roelofs\n            and contributors for the book, \"PNG: The Definitive Guide,\"\n            published by O'Reilly and Associates.\n\n\n      LICENSE 2 (GNU GPL v2 or later):\n\n      This program is free software; you can redistribute it and/or modify\n      it under the terms of the GNU General Public License as published by\n      the Free Software Foundation; either version 2 of the License, or\n      (at your option) any later version.\n\n      This program is distributed in the hope that it will be useful,\n      but WITHOUT ANY WARRANTY; without even the implied warranty of\n      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n      GNU General Public License for more details.\n\n      You should have received a copy of the GNU General Public License\n      along with this program; if not, write to the Free Software Foundation,\n      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  ---------------------------------------------------------------------------*/\n\n#define PROGNAME  \"rpng-win\"\n#define LONGNAME  \"Simple PNG Viewer for Windows\"\n#define VERSION   \"2.01 of 16 March 2008\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <windows.h>\n#ifdef __CYGWIN__\n/* getch replacement. Turns out, we don't really need this,\n * but leave it here if we ever enable any of the uses of\n * _getch in the main code\n */\n#include <unistd.h>\n#include <termio.h>\n#include <sys/ioctl.h>\nint repl_getch( void )\n{\n  char ch;\n  int fd = fileno(stdin);\n  struct termio old_tty, new_tty;\n\n  ioctl(fd, TCGETA, &old_tty);\n  new_tty = old_tty;\n  new_tty.c_lflag &= ~(ICANON | ECHO | ISIG);\n  ioctl(fd, TCSETA, &new_tty);\n  fread(&ch, 1, sizeof(ch), stdin);\n  ioctl(fd, TCSETA, &old_tty);\n\n  return ch;\n}\n#define _getch repl_getch\n#else\n#include <conio.h>      /* only for _getch() */\n#endif\n\n/* #define DEBUG  :  this enables the Trace() macros */\n\n#include \"readpng.h\"    /* typedefs, common macros, readpng prototypes */\n\n\n/* could just include png.h, but this macro is the only thing we need\n * (name and typedefs changed to local versions); note that side effects\n * only happen with alpha (which could easily be avoided with\n * \"ush acopy = (alpha);\") */\n\n#define alpha_composite(composite, fg, alpha, bg) {               \\\n    ush temp = ((ush)(fg)*(ush)(alpha) +                          \\\n                (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128);  \\\n    (composite) = (uch)((temp + (temp >> 8)) >> 8);               \\\n}\n\n\n/* local prototypes */\nstatic int        rpng_win_create_window(HINSTANCE hInst, int showmode);\nstatic int        rpng_win_display_image(void);\nstatic void       rpng_win_cleanup(void);\nLRESULT CALLBACK  rpng_win_wndproc(HWND, UINT, WPARAM, LPARAM);\n\n\nstatic char titlebar[1024];\nstatic char *progname = PROGNAME;\nstatic char *appname = LONGNAME;\nstatic char *filename;\nstatic FILE *infile;\n\nstatic char *bgstr;\nstatic uch bg_red=0, bg_green=0, bg_blue=0;\n\nstatic double display_exponent;\n\nstatic ulg image_width, image_height, image_rowbytes;\nstatic int image_channels;\nstatic uch *image_data;\n\n/* Windows-specific variables */\nstatic ulg wimage_rowbytes;\nstatic uch *dib;\nstatic uch *wimage_data;\nstatic BITMAPINFOHEADER *bmih;\n\nstatic HWND global_hwnd;\n\n\n\n\nint WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)\n{\n    char *args[1024];                 /* arbitrary limit, but should suffice */\n    char *p, *q, **argv = args;\n    int argc = 0;\n    int rc, alen, flen;\n    int error = 0;\n    int have_bg = FALSE;\n    double LUT_exponent;              /* just the lookup table */\n    double CRT_exponent = 2.2;        /* just the monitor */\n    double default_display_exponent;  /* whole display system */\n    MSG msg;\n\n\n    filename = (char *)NULL;\n\n#ifndef __CYGWIN__\n    /* First reenable console output, which normally goes to the bit bucket\n     * for windowed apps.  Closing the console window will terminate the\n     * app.  Thanks to David.Geldreich@realviz.com for supplying the magical\n     * incantation. */\n\n    AllocConsole();\n    freopen(\"CONOUT$\", \"a\", stderr);\n    freopen(\"CONOUT$\", \"a\", stdout);\n#endif\n\n\n    /* Next set the default value for our display-system exponent, i.e.,\n     * the product of the CRT exponent and the exponent corresponding to\n     * the frame-buffer's lookup table (LUT), if any.  This is not an\n     * exhaustive list of LUT values (e.g., OpenStep has a lot of weird\n     * ones), but it should cover 99% of the current possibilities.  And\n     * yes, these ifdefs are completely wasted in a Windows program... */\n\n#if defined(NeXT)\n    LUT_exponent = 1.0 / 2.2;\n    /*\n    if (some_next_function_that_returns_gamma(&next_gamma))\n        LUT_exponent = 1.0 / next_gamma;\n     */\n#elif defined(sgi)\n    LUT_exponent = 1.0 / 1.7;\n    /* there doesn't seem to be any documented function to get the\n     * \"gamma\" value, so we do it the hard way */\n    infile = fopen(\"/etc/config/system.glGammaVal\", \"r\");\n    if (infile) {\n        double sgi_gamma;\n\n        fgets(tmpline, 80, infile);\n        fclose(infile);\n        sgi_gamma = atof(tmpline);\n        if (sgi_gamma > 0.0)\n            LUT_exponent = 1.0 / sgi_gamma;\n    }\n#elif defined(Macintosh)\n    LUT_exponent = 1.8 / 2.61;\n    /*\n    if (some_mac_function_that_returns_gamma(&mac_gamma))\n        LUT_exponent = mac_gamma / 2.61;\n     */\n#else\n    LUT_exponent = 1.0;   /* assume no LUT:  most PCs */\n#endif\n\n    /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */\n    default_display_exponent = LUT_exponent * CRT_exponent;\n\n\n    /* If the user has set the SCREEN_GAMMA environment variable as suggested\n     * (somewhat imprecisely) in the libpng documentation, use that; otherwise\n     * use the default value we just calculated.  Either way, the user may\n     * override this via a command-line option. */\n\n    if ((p = getenv(\"SCREEN_GAMMA\")) != NULL)\n        display_exponent = atof(p);\n    else\n        display_exponent = default_display_exponent;\n\n\n    /* Windows really hates command lines, so we have to set up our own argv.\n     * Note that we do NOT bother with quoted arguments here, so don't use\n     * filenames with spaces in 'em! */\n\n    argv[argc++] = PROGNAME;\n    p = cmd;\n    for (;;) {\n        if (*p == ' ')\n            while (*++p == ' ')\n                ;\n        /* now p points at the first non-space after some spaces */\n        if (*p == '\\0')\n            break;    /* nothing after the spaces:  done */\n        argv[argc++] = q = p;\n        while (*q && *q != ' ')\n            ++q;\n        /* now q points at a space or the end of the string */\n        if (*q == '\\0')\n            break;    /* last argv already terminated; quit */\n        *q = '\\0';    /* change space to terminator */\n        p = q + 1;\n    }\n    argv[argc] = NULL;   /* terminate the argv array itself */\n\n\n    /* Now parse the command line for options and the PNG filename. */\n\n    while (*++argv && !error) {\n        if (!strncmp(*argv, \"-gamma\", 2)) {\n            if (!*++argv)\n                ++error;\n            else {\n                display_exponent = atof(*argv);\n                if (display_exponent <= 0.0)\n                    ++error;\n            }\n        } else if (!strncmp(*argv, \"-bgcolor\", 2)) {\n            if (!*++argv)\n                ++error;\n            else {\n                bgstr = *argv;\n                if (strlen(bgstr) != 7 || bgstr[0] != '#')\n                    ++error;\n                else\n                    have_bg = TRUE;\n            }\n        } else {\n            if (**argv != '-') {\n                filename = *argv;\n                if (argv[1])   /* shouldn't be any more args after filename */\n                    ++error;\n            } else\n                ++error;   /* not expecting any other options */\n        }\n    }\n\n    if (!filename)\n        ++error;\n\n\n    /* print usage screen if any errors up to this point */\n\n    if (error) {\n#ifndef __CYGWIN__\n        int ch;\n#endif\n\n        fprintf(stderr, \"\\n%s %s:  %s\\n\\n\", PROGNAME, VERSION, appname);\n        readpng_version_info();\n        fprintf(stderr, \"\\n\"\n          \"Usage:  %s [-gamma exp] [-bgcolor bg] file.png\\n\"\n          \"    exp \\ttransfer-function exponent (``gamma'') of the display\\n\"\n          \"\\t\\t  system in floating-point format (e.g., ``%.1f''); equal\\n\"\n          \"\\t\\t  to the product of the lookup-table exponent (varies)\\n\"\n          \"\\t\\t  and the CRT exponent (usually 2.2); must be positive\\n\"\n          \"    bg  \\tdesired background color in 7-character hex RGB format\\n\"\n          \"\\t\\t  (e.g., ``#ff7700'' for orange:  same as HTML colors);\\n\"\n          \"\\t\\t  used with transparent images\\n\"\n          \"\\nPress Q, Esc or mouse button 1 after image is displayed to quit.\\n\"\n#ifndef __CYGWIN__\n          \"Press Q or Esc to quit this usage screen.\\n\"\n#endif\n          \"\\n\", PROGNAME, default_display_exponent);\n#ifndef __CYGWIN__\n        do\n            ch = _getch();\n        while (ch != 'q' && ch != 'Q' && ch != 0x1B);\n#endif\n        exit(1);\n    }\n\n\n    if (!(infile = fopen(filename, \"rb\"))) {\n        fprintf(stderr, PROGNAME \":  can't open PNG file [%s]\\n\", filename);\n        ++error;\n    } else {\n        if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) {\n            switch (rc) {\n                case 1:\n                    fprintf(stderr, PROGNAME\n                      \":  [%s] is not a PNG file: incorrect signature\\n\",\n                      filename);\n                    break;\n                case 2:\n                    fprintf(stderr, PROGNAME\n                      \":  [%s] has bad IHDR (libpng longjmp)\\n\", filename);\n                    break;\n                case 4:\n                    fprintf(stderr, PROGNAME \":  insufficient memory\\n\");\n                    break;\n                default:\n                    fprintf(stderr, PROGNAME\n                      \":  unknown readpng_init() error\\n\");\n                    break;\n            }\n            ++error;\n        }\n        if (error)\n            fclose(infile);\n    }\n\n\n    if (error) {\n#ifndef __CYGWIN__\n        int ch;\n#endif\n\n        fprintf(stderr, PROGNAME \":  aborting.\\n\");\n#ifndef __CYGWIN__\n        do\n            ch = _getch();\n        while (ch != 'q' && ch != 'Q' && ch != 0x1B);\n#endif\n        exit(2);\n    } else {\n        fprintf(stderr, \"\\n%s %s:  %s\\n\", PROGNAME, VERSION, appname);\n#ifndef __CYGWIN__\n        fprintf(stderr,\n          \"\\n   [console window:  closing this window will terminate %s]\\n\\n\",\n          PROGNAME);\n#endif\n    }\n\n\n    /* set the title-bar string, but make sure buffer doesn't overflow */\n\n    alen = strlen(appname);\n    flen = strlen(filename);\n    if (alen + flen + 3 > 1023)\n        sprintf(titlebar, \"%s:  ...%s\", appname, filename+(alen+flen+6-1023));\n    else\n        sprintf(titlebar, \"%s:  %s\", appname, filename);\n\n\n    /* if the user didn't specify a background color on the command line,\n     * check for one in the PNG file--if not, the initialized values of 0\n     * (black) will be used */\n\n    if (have_bg) {\n        unsigned r, g, b;   /* this approach quiets compiler warnings */\n\n        sscanf(bgstr+1, \"%2x%2x%2x\", &r, &g, &b);\n        bg_red   = (uch)r;\n        bg_green = (uch)g;\n        bg_blue  = (uch)b;\n    } else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) {\n        readpng_cleanup(TRUE);\n        fprintf(stderr, PROGNAME\n          \":  libpng error while checking for background color\\n\");\n        exit(2);\n    }\n\n\n    /* do the basic Windows initialization stuff, make the window and fill it\n     * with the background color */\n\n    if (rpng_win_create_window(hInst, showmode))\n        exit(2);\n\n\n    /* decode the image, all at once */\n\n    Trace((stderr, \"calling readpng_get_image()\\n\"))\n    image_data = readpng_get_image(display_exponent, &image_channels,\n      &image_rowbytes);\n    Trace((stderr, \"done with readpng_get_image()\\n\"))\n\n\n    /* done with PNG file, so clean up to minimize memory usage (but do NOT\n     * nuke image_data!) */\n\n    readpng_cleanup(FALSE);\n    fclose(infile);\n\n    if (!image_data) {\n        fprintf(stderr, PROGNAME \":  unable to decode PNG image\\n\");\n        exit(3);\n    }\n\n\n    /* display image (composite with background if requested) */\n\n    Trace((stderr, \"calling rpng_win_display_image()\\n\"))\n    if (rpng_win_display_image()) {\n        free(image_data);\n        exit(4);\n    }\n    Trace((stderr, \"done with rpng_win_display_image()\\n\"))\n\n\n    /* wait for the user to tell us when to quit */\n\n    printf(\n#ifndef __CYGWIN__\n      \"Done.  Press Q, Esc or mouse button 1 (within image window) to quit.\\n\"\n#else\n      \"Done.  Press mouse button 1 (within image window) to quit.\\n\"\n#endif\n    );\n    fflush(stdout);\n\n    while (GetMessage(&msg, NULL, 0, 0)) {\n        TranslateMessage(&msg);\n        DispatchMessage(&msg);\n    }\n\n\n    /* OK, we're done:  clean up all image and Windows resources and go away */\n\n    rpng_win_cleanup();\n\n    return msg.wParam;\n}\n\n\n\n\n\nstatic int rpng_win_create_window(HINSTANCE hInst, int showmode)\n{\n    uch *dest;\n    int extra_width, extra_height;\n    ulg i, j;\n    WNDCLASSEX wndclass;\n\n\n/*---------------------------------------------------------------------------\n    Allocate memory for the display-specific version of the image (round up\n    to multiple of 4 for Windows DIB).\n  ---------------------------------------------------------------------------*/\n\n    wimage_rowbytes = ((3*image_width + 3L) >> 2) << 2;\n\n    if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +\n                              wimage_rowbytes*image_height)))\n    {\n        return 4;   /* fail */\n    }\n\n/*---------------------------------------------------------------------------\n    Initialize the DIB.  Negative height means to use top-down BMP ordering\n    (must be uncompressed, but that's what we want).  Bit count of 1, 4 or 8\n    implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values\n    directly => wimage_data begins immediately after BMP header.\n  ---------------------------------------------------------------------------*/\n\n    memset(dib, 0, sizeof(BITMAPINFOHEADER));\n    bmih = (BITMAPINFOHEADER *)dib;\n    bmih->biSize = sizeof(BITMAPINFOHEADER);\n    bmih->biWidth = image_width;\n    bmih->biHeight = -((long)image_height);\n    bmih->biPlanes = 1;\n    bmih->biBitCount = 24;\n    bmih->biCompression = 0;\n    wimage_data = dib + sizeof(BITMAPINFOHEADER);\n\n/*---------------------------------------------------------------------------\n    Fill in background color (black by default); data are in BGR order.\n  ---------------------------------------------------------------------------*/\n\n    for (j = 0;  j < image_height;  ++j) {\n        dest = wimage_data + j*wimage_rowbytes;\n        for (i = image_width;  i > 0;  --i) {\n            *dest++ = bg_blue;\n            *dest++ = bg_green;\n            *dest++ = bg_red;\n        }\n    }\n\n/*---------------------------------------------------------------------------\n    Set the window parameters.\n  ---------------------------------------------------------------------------*/\n\n    memset(&wndclass, 0, sizeof(wndclass));\n\n    wndclass.cbSize = sizeof(wndclass);\n    wndclass.style = CS_HREDRAW | CS_VREDRAW;\n    wndclass.lpfnWndProc = rpng_win_wndproc;\n    wndclass.hInstance = hInst;\n    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);\n    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);\n    wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);\n    wndclass.lpszMenuName = NULL;\n    wndclass.lpszClassName = progname;\n    wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);\n\n    RegisterClassEx(&wndclass);\n\n/*---------------------------------------------------------------------------\n    Finally, create the window.\n  ---------------------------------------------------------------------------*/\n\n    extra_width  = 2*(GetSystemMetrics(SM_CXBORDER) +\n                      GetSystemMetrics(SM_CXDLGFRAME));\n    extra_height = 2*(GetSystemMetrics(SM_CYBORDER) +\n                      GetSystemMetrics(SM_CYDLGFRAME)) +\n                      GetSystemMetrics(SM_CYCAPTION);\n\n    global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW,\n      CW_USEDEFAULT, CW_USEDEFAULT, image_width+extra_width,\n      image_height+extra_height, NULL, NULL, hInst, NULL);\n\n    ShowWindow(global_hwnd, showmode);\n    UpdateWindow(global_hwnd);\n\n    return 0;\n\n} /* end function rpng_win_create_window() */\n\n\n\n\n\nstatic int rpng_win_display_image()\n{\n    uch *src, *dest;\n    uch r, g, b, a;\n    ulg i, row, lastrow;\n    RECT rect;\n\n\n    Trace((stderr, \"beginning display loop (image_channels == %d)\\n\",\n      image_channels))\n    Trace((stderr, \"(width = %ld, rowbytes = %ld, wimage_rowbytes = %d)\\n\",\n      image_width, image_rowbytes, wimage_rowbytes))\n\n\n/*---------------------------------------------------------------------------\n    Blast image data to buffer.  This whole routine takes place before the\n    message loop begins, so there's no real point in any pseudo-progressive\n    display...\n  ---------------------------------------------------------------------------*/\n\n    for (lastrow = row = 0;  row < image_height;  ++row) {\n        src = image_data + row*image_rowbytes;\n        dest = wimage_data + row*wimage_rowbytes;\n        if (image_channels == 3) {\n            for (i = image_width;  i > 0;  --i) {\n                r = *src++;\n                g = *src++;\n                b = *src++;\n                *dest++ = b;\n                *dest++ = g;   /* note reverse order */\n                *dest++ = r;\n            }\n        } else /* if (image_channels == 4) */ {\n            for (i = image_width;  i > 0;  --i) {\n                r = *src++;\n                g = *src++;\n                b = *src++;\n                a = *src++;\n                if (a == 255) {\n                    *dest++ = b;\n                    *dest++ = g;\n                    *dest++ = r;\n                } else if (a == 0) {\n                    *dest++ = bg_blue;\n                    *dest++ = bg_green;\n                    *dest++ = bg_red;\n                } else {\n                    /* this macro (copied from png.h) composites the\n                     * foreground and background values and puts the\n                     * result into the first argument; there are no\n                     * side effects with the first argument */\n                    alpha_composite(*dest++, b, a, bg_blue);\n                    alpha_composite(*dest++, g, a, bg_green);\n                    alpha_composite(*dest++, r, a, bg_red);\n                }\n            }\n        }\n        /* display after every 16 lines */\n        if (((row+1) & 0xf) == 0) {\n            rect.left = 0L;\n            rect.top = (LONG)lastrow;\n            rect.right = (LONG)image_width;      /* possibly off by one? */\n            rect.bottom = (LONG)lastrow + 16L;   /* possibly off by one? */\n            InvalidateRect(global_hwnd, &rect, FALSE);\n            UpdateWindow(global_hwnd);     /* similar to XFlush() */\n            lastrow = row + 1;\n        }\n    }\n\n    Trace((stderr, \"calling final image-flush routine\\n\"))\n    if (lastrow < image_height) {\n        rect.left = 0L;\n        rect.top = (LONG)lastrow;\n        rect.right = (LONG)image_width;      /* possibly off by one? */\n        rect.bottom = (LONG)image_height;    /* possibly off by one? */\n        InvalidateRect(global_hwnd, &rect, FALSE);\n        UpdateWindow(global_hwnd);     /* similar to XFlush() */\n    }\n\n/*\n    last param determines whether or not background is wiped before paint\n    InvalidateRect(global_hwnd, NULL, TRUE);\n    UpdateWindow(global_hwnd);\n */\n\n    return 0;\n}\n\n\n\n\n\nstatic void rpng_win_cleanup()\n{\n    if (image_data) {\n        free(image_data);\n        image_data = NULL;\n    }\n\n    if (dib) {\n        free(dib);\n        dib = NULL;\n    }\n}\n\n\n\n\n\nLRESULT CALLBACK rpng_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP)\n{\n    HDC         hdc;\n    PAINTSTRUCT ps;\n    int rc;\n\n    switch (iMsg) {\n        case WM_CREATE:\n            /* one-time processing here, if any */\n            return 0;\n\n        case WM_PAINT:\n            hdc = BeginPaint(hwnd, &ps);\n                    /*                    dest                          */\n            rc = StretchDIBits(hdc, 0, 0, image_width, image_height,\n                    /*                    source                        */\n                                    0, 0, image_width, image_height,\n                                    wimage_data, (BITMAPINFO *)bmih,\n                    /*              iUsage: no clue                     */\n                                    0, SRCCOPY);\n            EndPaint(hwnd, &ps);\n            return 0;\n\n        /* wait for the user to tell us when to quit */\n        case WM_CHAR:\n            switch (wP) {      /* only need one, so ignore repeat count */\n                case 'q':\n                case 'Q':\n                case 0x1B:     /* Esc key */\n                    PostQuitMessage(0);\n            }\n            return 0;\n\n        case WM_LBUTTONDOWN:   /* another way of quitting */\n        case WM_DESTROY:\n            PostQuitMessage(0);\n            return 0;\n    }\n\n    return DefWindowProc(hwnd, iMsg, wP, lP);\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/rpng-x.c",
    "content": "/*---------------------------------------------------------------------------\n\n   rpng - simple PNG display program                               rpng-x.c\n\n   This program decodes and displays PNG images, with gamma correction and\n   optionally with a user-specified background color (in case the image has\n   transparency).  It is very nearly the most basic PNG viewer possible.\n   This version is for the X Window System (tested by author under Unix and\n   by Martin Zinser under OpenVMS; may work under OS/2 with some tweaking).\n\n   to do:\n    - 8-bit (colormapped) X support\n    - use %.1023s to simplify truncation of title-bar string?\n\n  ---------------------------------------------------------------------------\n\n   Changelog:\n    - 1.01:  initial public release\n    - 1.02:  modified to allow abbreviated options; fixed long/ulong mis-\n              match; switched to png_jmpbuf() macro\n    - 1.10:  added support for non-default visuals; fixed X pixel-conversion\n    - 1.11:  added extra set of parentheses to png_jmpbuf() macro; fixed\n              command-line parsing bug\n    - 1.12:  fixed some small X memory leaks (thanks to Franois Petitjean)\n    - 1.13:  fixed XFreeGC() crash bug (thanks to Patrick Welche)\n    - 1.14:  added support for X resources (thanks to Gerhard Niklasch)\n    - 2.00:  dual-licensed (added GNU GPL)\n    - 2.01:  fixed improper display of usage screen on PNG error(s)\n    - 2.02:  Added \"void(argc);\" statement to quiet pedantic compiler warnings\n             about unused variable (GR-P)\n\n  ---------------------------------------------------------------------------\n\n      Copyright (c) 1998-2008 Greg Roelofs.  All rights reserved.\n\n      This software is provided \"as is,\" without warranty of any kind,\n      express or implied.  In no event shall the author or contributors\n      be held liable for any damages arising in any way from the use of\n      this software.\n\n      The contents of this file are DUAL-LICENSED.  You may modify and/or\n      redistribute this software according to the terms of one of the\n      following two licenses (at your option):\n\n\n      LICENSE 1 (\"BSD-like with advertising clause\"):\n\n      Permission is granted to anyone to use this software for any purpose,\n      including commercial applications, and to alter it and redistribute\n      it freely, subject to the following restrictions:\n\n      1. Redistributions of source code must retain the above copyright\n         notice, disclaimer, and this list of conditions.\n      2. Redistributions in binary form must reproduce the above copyright\n         notice, disclaimer, and this list of conditions in the documenta-\n         tion and/or other materials provided with the distribution.\n      3. All advertising materials mentioning features or use of this\n         software must display the following acknowledgment:\n\n            This product includes software developed by Greg Roelofs\n            and contributors for the book, \"PNG: The Definitive Guide,\"\n            published by O'Reilly and Associates.\n\n\n      LICENSE 2 (GNU GPL v2 or later):\n\n      This program is free software; you can redistribute it and/or modify\n      it under the terms of the GNU General Public License as published by\n      the Free Software Foundation; either version 2 of the License, or\n      (at your option) any later version.\n\n      This program is distributed in the hope that it will be useful,\n      but WITHOUT ANY WARRANTY; without even the implied warranty of\n      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n      GNU General Public License for more details.\n\n      You should have received a copy of the GNU General Public License\n      along with this program; if not, write to the Free Software Foundation,\n      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  ---------------------------------------------------------------------------*/\n\n#define PROGNAME  \"rpng-x\"\n#define LONGNAME  \"Simple PNG Viewer for X\"\n#define VERSION   \"2.02 of 15 June 2014\"\n#define RESNAME   \"rpng\"        /* our X resource application name */\n#define RESCLASS  \"Rpng\"        /* our X resource class name */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <X11/Xlib.h>\n#include <X11/Xutil.h>\n#include <X11/Xos.h>\n#include <X11/keysym.h>\n\n/* #define DEBUG  :  this enables the Trace() macros */\n\n#include \"readpng.h\"   /* typedefs, common macros, readpng prototypes */\n\n\n/* could just include png.h, but this macro is the only thing we need\n * (name and typedefs changed to local versions); note that side effects\n * only happen with alpha (which could easily be avoided with\n * \"ush acopy = (alpha);\") */\n\n#define alpha_composite(composite, fg, alpha, bg) {               \\\n    ush temp = ((ush)(fg)*(ush)(alpha) +                          \\\n                (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128);  \\\n    (composite) = (uch)((temp + (temp >> 8)) >> 8);               \\\n}\n\n\n/* local prototypes */\nstatic int  rpng_x_create_window(void);\nstatic int  rpng_x_display_image(void);\nstatic void rpng_x_cleanup(void);\nstatic int  rpng_x_msb(ulg u32val);\n\n\nstatic char titlebar[1024], *window_name = titlebar;\nstatic char *appname = LONGNAME;\nstatic char *icon_name = PROGNAME;\nstatic char *res_name = RESNAME;\nstatic char *res_class = RESCLASS;\nstatic char *filename;\nstatic FILE *infile;\n\nstatic char *bgstr;\nstatic uch bg_red=0, bg_green=0, bg_blue=0;\n\nstatic double display_exponent;\n\nstatic ulg image_width, image_height, image_rowbytes;\nstatic int image_channels;\nstatic uch *image_data;\n\n/* X-specific variables */\nstatic char *displayname;\nstatic XImage *ximage;\nstatic Display *display;\nstatic int depth;\nstatic Visual *visual;\nstatic XVisualInfo *visual_list;\nstatic int RShift, GShift, BShift;\nstatic ulg RMask, GMask, BMask;\nstatic Window window;\nstatic GC gc;\nstatic Colormap colormap;\n\nstatic int have_nondefault_visual = FALSE;\nstatic int have_colormap = FALSE;\nstatic int have_window = FALSE;\nstatic int have_gc = FALSE;\n/*\nulg numcolors=0, pixels[256];\nush reds[256], greens[256], blues[256];\n */\n\n\n\n\nint main(int argc, char **argv)\n{\n#ifdef sgi\n    char tmpline[80];\n#endif\n    char *p;\n    int rc, alen, flen;\n    int error = 0;\n    int have_bg = FALSE;\n    double LUT_exponent;               /* just the lookup table */\n    double CRT_exponent = 2.2;         /* just the monitor */\n    double default_display_exponent;   /* whole display system */\n    XEvent e;\n    KeySym k;\n\n\n    displayname = (char *)NULL;\n    filename = (char *)NULL;\n\n\n    /* First set the default value for our display-system exponent, i.e.,\n     * the product of the CRT exponent and the exponent corresponding to\n     * the frame-buffer's lookup table (LUT), if any.  This is not an\n     * exhaustive list of LUT values (e.g., OpenStep has a lot of weird\n     * ones), but it should cover 99% of the current possibilities. */\n\n#if defined(NeXT)\n    LUT_exponent = 1.0 / 2.2;\n    /*\n    if (some_next_function_that_returns_gamma(&next_gamma))\n        LUT_exponent = 1.0 / next_gamma;\n     */\n#elif defined(sgi)\n    LUT_exponent = 1.0 / 1.7;\n    /* there doesn't seem to be any documented function to get the\n     * \"gamma\" value, so we do it the hard way */\n    infile = fopen(\"/etc/config/system.glGammaVal\", \"r\");\n    if (infile) {\n        double sgi_gamma;\n\n        fgets(tmpline, 80, infile);\n        fclose(infile);\n        sgi_gamma = atof(tmpline);\n        if (sgi_gamma > 0.0)\n            LUT_exponent = 1.0 / sgi_gamma;\n    }\n#elif defined(Macintosh)\n    LUT_exponent = 1.8 / 2.61;\n    /*\n    if (some_mac_function_that_returns_gamma(&mac_gamma))\n        LUT_exponent = mac_gamma / 2.61;\n     */\n#else\n    LUT_exponent = 1.0;   /* assume no LUT:  most PCs */\n#endif\n\n    /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */\n    default_display_exponent = LUT_exponent * CRT_exponent;\n\n\n    /* If the user has set the SCREEN_GAMMA environment variable as suggested\n     * (somewhat imprecisely) in the libpng documentation, use that; otherwise\n     * use the default value we just calculated.  Either way, the user may\n     * override this via a command-line option. */\n\n    if ((p = getenv(\"SCREEN_GAMMA\")) != NULL)\n        display_exponent = atof(p);\n    else\n        display_exponent = default_display_exponent;\n\n\n    /* Now parse the command line for options and the PNG filename. */\n\n    while (*++argv && !error) {\n        if (!strncmp(*argv, \"-display\", 2)) {\n            if (!*++argv)\n                ++error;\n            else\n                displayname = *argv;\n        } else if (!strncmp(*argv, \"-gamma\", 2)) {\n            if (!*++argv)\n                ++error;\n            else {\n                display_exponent = atof(*argv);\n                if (display_exponent <= 0.0)\n                    ++error;\n            }\n        } else if (!strncmp(*argv, \"-bgcolor\", 2)) {\n            if (!*++argv)\n                ++error;\n            else {\n                bgstr = *argv;\n                if (strlen(bgstr) != 7 || bgstr[0] != '#')\n                    ++error;\n                else\n                    have_bg = TRUE;\n            }\n        } else {\n            if (**argv != '-') {\n                filename = *argv;\n                if (argv[1])   /* shouldn't be any more args after filename */\n                    ++error;\n            } else\n                ++error;   /* not expecting any other options */\n        }\n    }\n\n    if (!filename)\n        ++error;\n\n\n    /* print usage screen if any errors up to this point */\n\n    if (error) {\n        fprintf(stderr, \"\\n%s %s:  %s\\n\", PROGNAME, VERSION, appname);\n        readpng_version_info();\n        fprintf(stderr, \"\\n\"\n          \"Usage:  %s [-display xdpy] [-gamma exp] [-bgcolor bg] file.png\\n\"\n          \"    xdpy\\tname of the target X display (e.g., ``hostname:0'')\\n\"\n          \"    exp \\ttransfer-function exponent (``gamma'') of the display\\n\"\n          \"\\t\\t  system in floating-point format (e.g., ``%.1f''); equal\\n\",\n          PROGNAME, default_display_exponent);\n\n        fprintf(stderr, \"\\n\"\n          \"\\t\\t  to the product of the lookup-table exponent (varies)\\n\"\n          \"\\t\\t  and the CRT exponent (usually 2.2); must be positive\\n\"\n          \"    bg  \\tdesired background color in 7-character hex RGB format\\n\"\n          \"\\t\\t  (e.g., ``#ff7700'' for orange:  same as HTML colors);\\n\"\n          \"\\t\\t  used with transparent images\\n\"\n          \"\\nPress Q, Esc or mouse button 1 (within image window, after image\\n\"\n          \"is displayed) to quit.\\n\");\n        exit(1);\n    }\n\n\n    if (!(infile = fopen(filename, \"rb\"))) {\n        fprintf(stderr, PROGNAME \":  can't open PNG file [%s]\\n\", filename);\n        ++error;\n    } else {\n        if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) {\n            switch (rc) {\n                case 1:\n                    fprintf(stderr, PROGNAME\n                      \":  [%s] is not a PNG file: incorrect signature\\n\",\n                      filename);\n                    break;\n                case 2:\n                    fprintf(stderr, PROGNAME\n                      \":  [%s] has bad IHDR (libpng longjmp)\\n\", filename);\n                    break;\n                case 4:\n                    fprintf(stderr, PROGNAME \":  insufficient memory\\n\");\n                    break;\n                default:\n                    fprintf(stderr, PROGNAME\n                      \":  unknown readpng_init() error\\n\");\n                    break;\n            }\n            ++error;\n        } else {\n            display = XOpenDisplay(displayname);\n            if (!display) {\n                readpng_cleanup(TRUE);\n                fprintf(stderr, PROGNAME \":  can't open X display [%s]\\n\",\n                  displayname? displayname : \"default\");\n                ++error;\n            }\n        }\n        if (error)\n            fclose(infile);\n    }\n\n\n    if (error) {\n        fprintf(stderr, PROGNAME \":  aborting.\\n\");\n        exit(2);\n    }\n\n\n    /* set the title-bar string, but make sure buffer doesn't overflow */\n\n    alen = strlen(appname);\n    flen = strlen(filename);\n    if (alen + flen + 3 > 1023)\n        sprintf(titlebar, \"%s:  ...%s\", appname, filename+(alen+flen+6-1023));\n    else\n        sprintf(titlebar, \"%s:  %s\", appname, filename);\n\n\n    /* if the user didn't specify a background color on the command line,\n     * check for one in the PNG file--if not, the initialized values of 0\n     * (black) will be used */\n\n    if (have_bg) {\n        unsigned r, g, b;   /* this approach quiets compiler warnings */\n\n        sscanf(bgstr+1, \"%2x%2x%2x\", &r, &g, &b);\n        bg_red   = (uch)r;\n        bg_green = (uch)g;\n        bg_blue  = (uch)b;\n    } else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) {\n        readpng_cleanup(TRUE);\n        fprintf(stderr, PROGNAME\n          \":  libpng error while checking for background color\\n\");\n        exit(2);\n    }\n\n\n    /* do the basic X initialization stuff, make the window and fill it\n     * with the background color */\n\n    if (rpng_x_create_window())\n        exit(2);\n\n\n    /* decode the image, all at once */\n\n    Trace((stderr, \"calling readpng_get_image()\\n\"))\n    image_data = readpng_get_image(display_exponent, &image_channels,\n      &image_rowbytes);\n    Trace((stderr, \"done with readpng_get_image()\\n\"))\n\n\n    /* done with PNG file, so clean up to minimize memory usage (but do NOT\n     * nuke image_data!) */\n\n    readpng_cleanup(FALSE);\n    fclose(infile);\n\n    if (!image_data) {\n        fprintf(stderr, PROGNAME \":  unable to decode PNG image\\n\");\n        exit(3);\n    }\n\n\n    /* display image (composite with background if requested) */\n\n    Trace((stderr, \"calling rpng_x_display_image()\\n\"))\n    if (rpng_x_display_image()) {\n        free(image_data);\n        exit(4);\n    }\n    Trace((stderr, \"done with rpng_x_display_image()\\n\"))\n\n\n    /* wait for the user to tell us when to quit */\n\n    printf(\n      \"Done.  Press Q, Esc or mouse button 1 (within image window) to quit.\\n\");\n    fflush(stdout);\n\n    do\n        XNextEvent(display, &e);\n    while (!(e.type == ButtonPress && e.xbutton.button == Button1) &&\n           !(e.type == KeyPress &&    /*  v--- or 1 for shifted keys */\n             ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape) ));\n\n\n    /* OK, we're done:  clean up all image and X resources and go away */\n\n    rpng_x_cleanup();\n\n    (void)argc; /* Unused */\n\n    return 0;\n}\n\n\n\n\n\nstatic int rpng_x_create_window(void)\n{\n    uch *xdata;\n    int need_colormap = FALSE;\n    int screen, pad;\n    ulg bg_pixel = 0L;\n    ulg attrmask;\n    Window root;\n    XEvent e;\n    XGCValues gcvalues;\n    XSetWindowAttributes attr;\n    XTextProperty windowName, *pWindowName = &windowName;\n    XTextProperty iconName, *pIconName = &iconName;\n    XVisualInfo visual_info;\n    XSizeHints *size_hints;\n    XWMHints *wm_hints;\n    XClassHint *class_hints;\n\n\n    screen = DefaultScreen(display);\n    depth = DisplayPlanes(display, screen);\n    root = RootWindow(display, screen);\n\n#ifdef DEBUG\n    XSynchronize(display, True);\n#endif\n\n#if 0\n/* GRR:  add 8-bit support */\n    if (/* depth != 8 && */ depth != 16 && depth != 24 && depth != 32) {\n        fprintf(stderr,\n          \"screen depth %d not supported (only 16-, 24- or 32-bit TrueColor)\\n\",\n          depth);\n        return 2;\n    }\n\n    XMatchVisualInfo(display, screen, depth,\n      (depth == 8)? PseudoColor : TrueColor, &visual_info);\n    visual = visual_info.visual;\n#else\n    if (depth != 16 && depth != 24 && depth != 32) {\n        int visuals_matched = 0;\n\n        Trace((stderr, \"default depth is %d:  checking other visuals\\n\",\n          depth))\n\n        /* 24-bit first */\n        visual_info.screen = screen;\n        visual_info.depth = 24;\n        visual_list = XGetVisualInfo(display,\n          VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched);\n        if (visuals_matched == 0) {\n/* GRR:  add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */\n            fprintf(stderr, \"default screen depth %d not supported, and no\"\n              \" 24-bit visuals found\\n\", depth);\n            return 2;\n        }\n        Trace((stderr, \"XGetVisualInfo() returned %d 24-bit visuals\\n\",\n          visuals_matched))\n        visual = visual_list[0].visual;\n        depth = visual_list[0].depth;\n/*\n        colormap_size = visual_list[0].colormap_size;\n        visual_class = visual->class;\n        visualID = XVisualIDFromVisual(visual);\n */\n        have_nondefault_visual = TRUE;\n        need_colormap = TRUE;\n    } else {\n        XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info);\n        visual = visual_info.visual;\n    }\n#endif\n\n    RMask = visual->red_mask;\n    GMask = visual->green_mask;\n    BMask = visual->blue_mask;\n\n/* GRR:  add/check 8-bit support */\n    if (depth == 8 || need_colormap) {\n        colormap = XCreateColormap(display, root, visual, AllocNone);\n        if (!colormap) {\n            fprintf(stderr, \"XCreateColormap() failed\\n\");\n            return 2;\n        }\n        have_colormap = TRUE;\n    }\n    if (depth == 15 || depth == 16) {\n        RShift = 15 - rpng_x_msb(RMask);    /* these are right-shifts */\n        GShift = 15 - rpng_x_msb(GMask);\n        BShift = 15 - rpng_x_msb(BMask);\n    } else if (depth > 16) {\n#define NO_24BIT_MASKS\n#ifdef NO_24BIT_MASKS\n        RShift = rpng_x_msb(RMask) - 7;     /* these are left-shifts */\n        GShift = rpng_x_msb(GMask) - 7;\n        BShift = rpng_x_msb(BMask) - 7;\n#else\n        RShift = 7 - rpng_x_msb(RMask);     /* these are right-shifts, too */\n        GShift = 7 - rpng_x_msb(GMask);\n        BShift = 7 - rpng_x_msb(BMask);\n#endif\n    }\n    if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) {\n        fprintf(stderr, \"rpng internal logic error:  negative X shift(s)!\\n\");\n        return 2;\n    }\n\n/*---------------------------------------------------------------------------\n    Finally, create the window.\n  ---------------------------------------------------------------------------*/\n\n    attr.backing_store = Always;\n    attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;\n    attrmask = CWBackingStore | CWEventMask;\n    if (have_nondefault_visual) {\n        attr.colormap = colormap;\n        attr.background_pixel = 0;\n        attr.border_pixel = 1;\n        attrmask |= CWColormap | CWBackPixel | CWBorderPixel;\n    }\n\n    window = XCreateWindow(display, root, 0, 0, image_width, image_height, 0,\n      depth, InputOutput, visual, attrmask, &attr);\n\n    if (window == None) {\n        fprintf(stderr, \"XCreateWindow() failed\\n\");\n        return 2;\n    } else\n        have_window = TRUE;\n\n    if (depth == 8)\n        XSetWindowColormap(display, window, colormap);\n\n    if (!XStringListToTextProperty(&window_name, 1, pWindowName))\n        pWindowName = NULL;\n    if (!XStringListToTextProperty(&icon_name, 1, pIconName))\n        pIconName = NULL;\n\n    /* OK if any hints allocation fails; XSetWMProperties() allows NULLs */\n\n    if ((size_hints = XAllocSizeHints()) != NULL) {\n        /* window will not be resizable */\n        size_hints->flags = PMinSize | PMaxSize;\n        size_hints->min_width = size_hints->max_width = (int)image_width;\n        size_hints->min_height = size_hints->max_height = (int)image_height;\n    }\n\n    if ((wm_hints = XAllocWMHints()) != NULL) {\n        wm_hints->initial_state = NormalState;\n        wm_hints->input = True;\n     /* wm_hints->icon_pixmap = icon_pixmap; */\n        wm_hints->flags = StateHint | InputHint  /* | IconPixmapHint */ ;\n    }\n\n    if ((class_hints = XAllocClassHint()) != NULL) {\n        class_hints->res_name = res_name;\n        class_hints->res_class = res_class;\n    }\n\n    XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0,\n      size_hints, wm_hints, class_hints);\n\n    /* various properties and hints no longer needed; free memory */\n    if (pWindowName)\n       XFree(pWindowName->value);\n    if (pIconName)\n       XFree(pIconName->value);\n    if (size_hints)\n        XFree(size_hints);\n    if (wm_hints)\n       XFree(wm_hints);\n    if (class_hints)\n       XFree(class_hints);\n\n    XMapWindow(display, window);\n\n    gc = XCreateGC(display, window, 0, &gcvalues);\n    have_gc = TRUE;\n\n/*---------------------------------------------------------------------------\n    Fill window with the specified background color.\n  ---------------------------------------------------------------------------*/\n\n    if (depth == 24 || depth == 32) {\n        bg_pixel = ((ulg)bg_red   << RShift) |\n                   ((ulg)bg_green << GShift) |\n                   ((ulg)bg_blue  << BShift);\n    } else if (depth == 16) {\n        bg_pixel = ((((ulg)bg_red   << 8) >> RShift) & RMask) |\n                   ((((ulg)bg_green << 8) >> GShift) & GMask) |\n                   ((((ulg)bg_blue  << 8) >> BShift) & BMask);\n    } else /* depth == 8 */ {\n\n        /* GRR:  add 8-bit support */\n\n    }\n\n    XSetForeground(display, gc, bg_pixel);\n    XFillRectangle(display, window, gc, 0, 0, image_width, image_height);\n\n/*---------------------------------------------------------------------------\n    Wait for first Expose event to do any drawing, then flush.\n  ---------------------------------------------------------------------------*/\n\n    do\n        XNextEvent(display, &e);\n    while (e.type != Expose || e.xexpose.count);\n\n    XFlush(display);\n\n/*---------------------------------------------------------------------------\n    Allocate memory for the X- and display-specific version of the image.\n  ---------------------------------------------------------------------------*/\n\n    if (depth == 24 || depth == 32) {\n        xdata = (uch *)malloc(4*image_width*image_height);\n        pad = 32;\n    } else if (depth == 16) {\n        xdata = (uch *)malloc(2*image_width*image_height);\n        pad = 16;\n    } else /* depth == 8 */ {\n        xdata = (uch *)malloc(image_width*image_height);\n        pad = 8;\n    }\n\n    if (!xdata) {\n        fprintf(stderr, PROGNAME \":  unable to allocate image memory\\n\");\n        return 4;\n    }\n\n    ximage = XCreateImage(display, visual, depth, ZPixmap, 0,\n      (char *)xdata, image_width, image_height, pad, 0);\n\n    if (!ximage) {\n        fprintf(stderr, PROGNAME \":  XCreateImage() failed\\n\");\n        free(xdata);\n        return 3;\n    }\n\n    /* to avoid testing the byte order every pixel (or doubling the size of\n     * the drawing routine with a giant if-test), we arbitrarily set the byte\n     * order to MSBFirst and let Xlib worry about inverting things on little-\n     * endian machines (like Linux/x86, old VAXen, etc.)--this is not the most\n     * efficient approach (the giant if-test would be better), but in the\n     * interest of clarity, we take the easy way out... */\n\n    ximage->byte_order = MSBFirst;\n\n    return 0;\n\n} /* end function rpng_x_create_window() */\n\n\n\n\n\nstatic int rpng_x_display_image(void)\n{\n    uch *src;\n    char *dest;\n    uch r, g, b, a;\n    ulg i, row, lastrow = 0;\n    ulg pixel;\n    int ximage_rowbytes = ximage->bytes_per_line;\n/*  int bpp = ximage->bits_per_pixel;  */\n\n\n    Trace((stderr, \"beginning display loop (image_channels == %d)\\n\",\n      image_channels))\n    Trace((stderr, \"   (width = %ld, rowbytes = %ld, ximage_rowbytes = %d)\\n\",\n      image_width, image_rowbytes, ximage_rowbytes))\n    Trace((stderr, \"   (bpp = %d)\\n\", ximage->bits_per_pixel))\n    Trace((stderr, \"   (byte_order = %s)\\n\", ximage->byte_order == MSBFirst?\n      \"MSBFirst\" : (ximage->byte_order == LSBFirst? \"LSBFirst\" : \"unknown\")))\n\n    if (depth == 24 || depth == 32) {\n        ulg red, green, blue;\n\n        for (lastrow = row = 0;  row < image_height;  ++row) {\n            src = image_data + row*image_rowbytes;\n            dest = ximage->data + row*ximage_rowbytes;\n            if (image_channels == 3) {\n                for (i = image_width;  i > 0;  --i) {\n                    red   = *src++;\n                    green = *src++;\n                    blue  = *src++;\n#ifdef NO_24BIT_MASKS\n                    pixel = (red   << RShift) |\n                            (green << GShift) |\n                            (blue  << BShift);\n                    /* recall that we set ximage->byte_order = MSBFirst above */\n                    /* GRR BUG:  this assumes bpp == 32, but may be 24: */\n                    *dest++ = (char)((pixel >> 24) & 0xff);\n                    *dest++ = (char)((pixel >> 16) & 0xff);\n                    *dest++ = (char)((pixel >>  8) & 0xff);\n                    *dest++ = (char)( pixel        & 0xff);\n#else\n                    red   = (RShift < 0)? red   << (-RShift) : red   >> RShift;\n                    green = (GShift < 0)? green << (-GShift) : green >> GShift;\n                    blue  = (BShift < 0)? blue  << (-BShift) : blue  >> BShift;\n                    pixel = (red & RMask) | (green & GMask) | (blue & BMask);\n                    /* recall that we set ximage->byte_order = MSBFirst above */\n                    *dest++ = (char)((pixel >> 24) & 0xff);\n                    *dest++ = (char)((pixel >> 16) & 0xff);\n                    *dest++ = (char)((pixel >>  8) & 0xff);\n                    *dest++ = (char)( pixel        & 0xff);\n#endif\n                }\n            } else /* if (image_channels == 4) */ {\n                for (i = image_width;  i > 0;  --i) {\n                    r = *src++;\n                    g = *src++;\n                    b = *src++;\n                    a = *src++;\n                    if (a == 255) {\n                        red   = r;\n                        green = g;\n                        blue  = b;\n                    } else if (a == 0) {\n                        red   = bg_red;\n                        green = bg_green;\n                        blue  = bg_blue;\n                    } else {\n                        /* this macro (from png.h) composites the foreground\n                         * and background values and puts the result into the\n                         * first argument */\n                        alpha_composite(red,   r, a, bg_red);\n                        alpha_composite(green, g, a, bg_green);\n                        alpha_composite(blue,  b, a, bg_blue);\n                    }\n                    pixel = (red   << RShift) |\n                            (green << GShift) |\n                            (blue  << BShift);\n                    /* recall that we set ximage->byte_order = MSBFirst above */\n                    *dest++ = (char)((pixel >> 24) & 0xff);\n                    *dest++ = (char)((pixel >> 16) & 0xff);\n                    *dest++ = (char)((pixel >>  8) & 0xff);\n                    *dest++ = (char)( pixel        & 0xff);\n                }\n            }\n            /* display after every 16 lines */\n            if (((row+1) & 0xf) == 0) {\n                XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,\n                  (int)lastrow, image_width, 16);\n                XFlush(display);\n                lastrow = row + 1;\n            }\n        }\n\n    } else if (depth == 16) {\n        ush red, green, blue;\n\n        for (lastrow = row = 0;  row < image_height;  ++row) {\n            src = image_data + row*image_rowbytes;\n            dest = ximage->data + row*ximage_rowbytes;\n            if (image_channels == 3) {\n                for (i = image_width;  i > 0;  --i) {\n                    red   = ((ush)(*src) << 8);\n                    ++src;\n                    green = ((ush)(*src) << 8);\n                    ++src;\n                    blue  = ((ush)(*src) << 8);\n                    ++src;\n                    pixel = ((red   >> RShift) & RMask) |\n                            ((green >> GShift) & GMask) |\n                            ((blue  >> BShift) & BMask);\n                    /* recall that we set ximage->byte_order = MSBFirst above */\n                    *dest++ = (char)((pixel >>  8) & 0xff);\n                    *dest++ = (char)( pixel        & 0xff);\n                }\n            } else /* if (image_channels == 4) */ {\n                for (i = image_width;  i > 0;  --i) {\n                    r = *src++;\n                    g = *src++;\n                    b = *src++;\n                    a = *src++;\n                    if (a == 255) {\n                        red   = ((ush)r << 8);\n                        green = ((ush)g << 8);\n                        blue  = ((ush)b << 8);\n                    } else if (a == 0) {\n                        red   = ((ush)bg_red   << 8);\n                        green = ((ush)bg_green << 8);\n                        blue  = ((ush)bg_blue  << 8);\n                    } else {\n                        /* this macro (from png.h) composites the foreground\n                         * and background values and puts the result back into\n                         * the first argument (== fg byte here:  safe) */\n                        alpha_composite(r, r, a, bg_red);\n                        alpha_composite(g, g, a, bg_green);\n                        alpha_composite(b, b, a, bg_blue);\n                        red   = ((ush)r << 8);\n                        green = ((ush)g << 8);\n                        blue  = ((ush)b << 8);\n                    }\n                    pixel = ((red   >> RShift) & RMask) |\n                            ((green >> GShift) & GMask) |\n                            ((blue  >> BShift) & BMask);\n                    /* recall that we set ximage->byte_order = MSBFirst above */\n                    *dest++ = (char)((pixel >>  8) & 0xff);\n                    *dest++ = (char)( pixel        & 0xff);\n                }\n            }\n            /* display after every 16 lines */\n            if (((row+1) & 0xf) == 0) {\n                XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,\n                  (int)lastrow, image_width, 16);\n                XFlush(display);\n                lastrow = row + 1;\n            }\n        }\n\n    } else /* depth == 8 */ {\n\n        /* GRR:  add 8-bit support */\n\n    }\n\n    Trace((stderr, \"calling final XPutImage()\\n\"))\n    if (lastrow < image_height) {\n        XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,\n          (int)lastrow, image_width, image_height-lastrow);\n        XFlush(display);\n    }\n\n    return 0;\n}\n\n\n\n\nstatic void rpng_x_cleanup(void)\n{\n    if (image_data) {\n        free(image_data);\n        image_data = NULL;\n    }\n\n    if (ximage) {\n        if (ximage->data) {\n            free(ximage->data);           /* we allocated it, so we free it */\n            ximage->data = (char *)NULL;  /*  instead of XDestroyImage() */\n        }\n        XDestroyImage(ximage);\n        ximage = NULL;\n    }\n\n    if (have_gc)\n        XFreeGC(display, gc);\n\n    if (have_window)\n        XDestroyWindow(display, window);\n\n    if (have_colormap)\n        XFreeColormap(display, colormap);\n\n    if (have_nondefault_visual)\n        XFree(visual_list);\n}\n\n\n\n\n\nstatic int rpng_x_msb(ulg u32val)\n{\n    int i;\n\n    for (i = 31;  i >= 0;  --i) {\n        if (u32val & 0x80000000L)\n            break;\n        u32val <<= 1;\n    }\n    return i;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/rpng2-win.c",
    "content": "/*---------------------------------------------------------------------------\n\n   rpng2 - progressive-model PNG display program                rpng2-win.c\n\n   This program decodes and displays PNG files progressively, as if it were\n   a web browser (though the front end is only set up to read from files).\n   It supports gamma correction, user-specified background colors, and user-\n   specified background patterns (for transparent images).  This version is\n   for 32-bit Windows; it may compile under 16-bit Windows with a little\n   tweaking (or maybe not).  Thanks to Adam Costello and Pieter S. van der\n   Meulen for the \"diamond\" and \"radial waves\" patterns, respectively.\n\n   to do (someday, maybe):\n    - handle quoted command-line args (especially filenames with spaces)\n    - finish resizable checkerboard-gradient (sizes 4-128?)\n    - use %.1023s to simplify truncation of title-bar string?\n    - have minimum window width:  oh well\n\n  ---------------------------------------------------------------------------\n\n   Changelog:\n    - 1.01:  initial public release\n    - 1.02:  fixed cut-and-paste error in usage screen (oops...)\n    - 1.03:  modified to allow abbreviated options\n    - 1.04:  removed bogus extra argument from usage fprintf() [Glenn R-P?];\n              fixed command-line parsing bug\n    - 1.10:  enabled \"message window\"/console (thanks to David Geldreich)\n    - 1.20:  added runtime MMX-enabling/disabling and new -mmx* options\n    - 1.21:  made minor tweak to usage screen to fit within 25-line console\n    - 1.22:  added AMD64/EM64T support (__x86_64__)\n    - 2.00:  dual-licensed (added GNU GPL)\n    - 2.01:  fixed 64-bit typo in readpng2.c\n    - 2.02:  fixed improper display of usage screen on PNG error(s); fixed\n              unexpected-EOF and file-read-error cases\n    - 2.03:  removed runtime MMX-enabling/disabling and obsolete -mmx* options\n    - 2.04:\n             (GR-P)\n\n  ---------------------------------------------------------------------------\n\n      Copyright (c) 1998-2008 Greg Roelofs.  All rights reserved.\n\n      This software is provided \"as is,\" without warranty of any kind,\n      express or implied.  In no event shall the author or contributors\n      be held liable for any damages arising in any way from the use of\n      this software.\n\n      The contents of this file are DUAL-LICENSED.  You may modify and/or\n      redistribute this software according to the terms of one of the\n      following two licenses (at your option):\n\n\n      LICENSE 1 (\"BSD-like with advertising clause\"):\n\n      Permission is granted to anyone to use this software for any purpose,\n      including commercial applications, and to alter it and redistribute\n      it freely, subject to the following restrictions:\n\n      1. Redistributions of source code must retain the above copyright\n         notice, disclaimer, and this list of conditions.\n      2. Redistributions in binary form must reproduce the above copyright\n         notice, disclaimer, and this list of conditions in the documenta-\n         tion and/or other materials provided with the distribution.\n      3. All advertising materials mentioning features or use of this\n         software must display the following acknowledgment:\n\n            This product includes software developed by Greg Roelofs\n            and contributors for the book, \"PNG: The Definitive Guide,\"\n            published by O'Reilly and Associates.\n\n\n      LICENSE 2 (GNU GPL v2 or later):\n\n      This program is free software; you can redistribute it and/or modify\n      it under the terms of the GNU General Public License as published by\n      the Free Software Foundation; either version 2 of the License, or\n      (at your option) any later version.\n\n      This program is distributed in the hope that it will be useful,\n      but WITHOUT ANY WARRANTY; without even the implied warranty of\n      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n      GNU General Public License for more details.\n\n      You should have received a copy of the GNU General Public License\n      along with this program; if not, write to the Free Software Foundation,\n      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  ---------------------------------------------------------------------------*/\n\n#define PROGNAME  \"rpng2-win\"\n#define LONGNAME  \"Progressive PNG Viewer for Windows\"\n#define VERSION   \"2.02 of 16 March 2008\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <setjmp.h>    /* for jmpbuf declaration in readpng2.h */\n#include <time.h>\n#include <math.h>      /* only for PvdM background code */\n#include <windows.h>\n#ifdef __CYGWIN__\n/* getch replacement. Turns out, we don't really need this,\n * but leave it here if we ever enable any of the uses of\n * _getch in the main code\n */\n#include <unistd.h>\n#include <termio.h>\n#include <sys/ioctl.h>\nint repl_getch( void )\n{\n  char ch;\n  int fd = fileno(stdin);\n  struct termio old_tty, new_tty;\n\n  ioctl(fd, TCGETA, &old_tty);\n  new_tty = old_tty;\n  new_tty.c_lflag &= ~(ICANON | ECHO | ISIG);\n  ioctl(fd, TCSETA, &new_tty);\n  fread(&ch, 1, sizeof(ch), stdin);\n  ioctl(fd, TCSETA, &old_tty);\n\n  return ch;\n}\n#define _getch repl_getch\n#else\n#include <conio.h>     /* only for _getch() */\n#endif\n\n/* all for PvdM background code: */\n#ifndef PI\n#  define PI             3.141592653589793238\n#endif\n#define PI_2             (PI*0.5)\n#define INV_PI_360       (360.0 / PI)\n#define MAX(a,b)         (a>b?a:b)\n#define MIN(a,b)         (a<b?a:b)\n#define CLIP(a,min,max)  MAX(min,MIN((a),max))\n#define ABS(a)           ((a)<0?-(a):(a))\n#define CLIP8P(c)        MAX(0,(MIN((c),255)))   /* 8-bit pos. integer (uch) */\n#define ROUNDF(f)        ((int)(f + 0.5))\n\n#define rgb1_max   bg_freq\n#define rgb1_min   bg_gray\n#define rgb2_max   bg_bsat\n#define rgb2_min   bg_brot\n\n/* #define DEBUG */     /* this enables the Trace() macros */\n\n#include \"readpng2.h\"   /* typedefs, common macros, readpng2 prototypes */\n\n\n/* could just include png.h, but this macro is the only thing we need\n * (name and typedefs changed to local versions); note that side effects\n * only happen with alpha (which could easily be avoided with\n * \"ush acopy = (alpha);\") */\n\n#define alpha_composite(composite, fg, alpha, bg) {               \\\n    ush temp = ((ush)(fg)*(ush)(alpha) +                          \\\n                (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128);  \\\n    (composite) = (uch)((temp + (temp >> 8)) >> 8);               \\\n}\n\n\n#define INBUFSIZE 4096   /* with pseudo-timing on (1 sec delay/block), this\n                          *  block size corresponds roughly to a download\n                          *  speed 10% faster than theoretical 33.6K maximum\n                          *  (assuming 8 data bits, 1 stop bit and no other\n                          *  overhead) */\n\n/* local prototypes */\nstatic void       rpng2_win_init(void);\nstatic int        rpng2_win_create_window(void);\nstatic int        rpng2_win_load_bg_image(void);\nstatic void       rpng2_win_display_row(ulg row);\nstatic void       rpng2_win_finish_display(void);\nstatic void       rpng2_win_cleanup(void);\nLRESULT CALLBACK  rpng2_win_wndproc(HWND, UINT, WPARAM, LPARAM);\n\n\nstatic char titlebar[1024];\nstatic char *progname = PROGNAME;\nstatic char *appname = LONGNAME;\nstatic char *filename;\nstatic FILE *infile;\n\nstatic mainprog_info rpng2_info;\n\nstatic uch inbuf[INBUFSIZE];\nstatic int incount;\n\nstatic int pat = 6;         /* must be less than num_bgpat */\nstatic int bg_image = 0;\nstatic int bgscale = 16;\nstatic ulg bg_rowbytes;\nstatic uch *bg_data;\n\nstatic struct rgb_color {\n    uch r, g, b;\n} rgb[] = {\n    {  0,   0,   0},    /*  0:  black */\n    {255, 255, 255},    /*  1:  white */\n    {173, 132,  57},    /*  2:  tan */\n    { 64, 132,   0},    /*  3:  medium green */\n    {189, 117,   1},    /*  4:  gold */\n    {253, 249,   1},    /*  5:  yellow */\n    {  0,   0, 255},    /*  6:  blue */\n    {  0,   0, 120},    /*  7:  medium blue */\n    {255,   0, 255},    /*  8:  magenta */\n    { 64,   0,  64},    /*  9:  dark magenta */\n    {255,   0,   0},    /* 10:  red */\n    { 64,   0,   0},    /* 11:  dark red */\n    {255, 127,   0},    /* 12:  orange */\n    {192,  96,   0},    /* 13:  darker orange */\n    { 24,  60,   0},    /* 14:  dark green-yellow */\n    { 85, 125, 200}     /* 15:  ice blue */\n};\n/* not used for now, but should be for error-checking:\nstatic int num_rgb = sizeof(rgb) / sizeof(struct rgb_color);\n */\n\n/*\n    This whole struct is a fairly cheesy way to keep the number of\n    command-line options to a minimum.  The radial-waves background\n    type is a particularly poor fit to the integer elements of the\n    struct...but a few macros and a little fixed-point math will do\n    wonders for ya.\n\n    type bits:\n       F E D C B A 9 8 7 6 5 4 3 2 1 0\n                             | | | | |\n                             | | +-+-+-- 0 = sharp-edged checkerboard\n                             | |         1 = soft diamonds\n                             | |         2 = radial waves\n                             | |       3-7 = undefined\n                             | +-- gradient #2 inverted?\n                             +-- alternating columns inverted?\n */\nstatic struct background_pattern {\n    ush type;\n    int rgb1_max, rgb1_min;     /* or bg_freq, bg_gray */\n    int rgb2_max, rgb2_min;     /* or bg_bsat, bg_brot (both scaled by 10)*/\n} bg[] = {\n    {0+8,   2,0,  1,15},        /* checkered:  tan/black vs. white/ice blue */\n    {0+24,  2,0,  1,0},         /* checkered:  tan/black vs. white/black */\n    {0+8,   4,5,  0,2},         /* checkered:  gold/yellow vs. black/tan */\n    {0+8,   4,5,  0,6},         /* checkered:  gold/yellow vs. black/blue */\n    {0,     7,0,  8,9},         /* checkered:  deep blue/black vs. magenta */\n    {0+8,  13,0,  5,14},        /* checkered:  orange/black vs. yellow */\n    {0+8,  12,0, 10,11},        /* checkered:  orange/black vs. red */\n    {1,     7,0,  8,0},         /* diamonds:  deep blue/black vs. magenta */\n    {1,    12,0, 11,0},         /* diamonds:  orange vs. dark red */\n    {1,    10,0,  7,0},         /* diamonds:  red vs. medium blue */\n    {1,     4,0,  5,0},         /* diamonds:  gold vs. yellow */\n    {1,     3,0,  0,0},         /* diamonds:  medium green vs. black */\n    {2,    16, 100,  20,   0},  /* radial:  ~hard radial color-beams */\n    {2,    18, 100,  10,   2},  /* radial:  soft, curved radial color-beams */\n    {2,    16, 256, 100, 250},  /* radial:  very tight spiral */\n    {2, 10000, 256,  11,   0}   /* radial:  dipole-moire' (almost fractal) */\n};\nstatic int num_bgpat = sizeof(bg) / sizeof(struct background_pattern);\n\n\n/* Windows-specific global variables (could go in struct, but messy...) */\nstatic ulg wimage_rowbytes;\nstatic uch *dib;\nstatic uch *wimage_data;\nstatic BITMAPINFOHEADER *bmih;\n\nstatic HWND global_hwnd;\nstatic HINSTANCE global_hInst;\nstatic int global_showmode;\n\n\n\n\nint WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)\n{\n    char *args[1024];                 /* arbitrary limit, but should suffice */\n    char **argv = args;\n    char *p, *q, *bgstr = NULL;\n    int argc = 0;\n    int rc, alen, flen;\n    int error = 0;\n    int timing = FALSE;\n    int have_bg = FALSE;\n    double LUT_exponent;              /* just the lookup table */\n    double CRT_exponent = 2.2;        /* just the monitor */\n    double default_display_exponent;  /* whole display system */\n    MSG msg;\n\n\n    /* First initialize a few things, just to be sure--memset takes care of\n     * default background color (black), booleans (FALSE), pointers (NULL),\n     * etc. */\n\n    global_hInst = hInst;\n    global_showmode = showmode;\n    filename = (char *)NULL;\n    memset(&rpng2_info, 0, sizeof(mainprog_info));\n\n#ifndef __CYGWIN__\n    /* Next reenable console output, which normally goes to the bit bucket\n     * for windowed apps.  Closing the console window will terminate the\n     * app.  Thanks to David.Geldreich@realviz.com for supplying the magical\n     * incantation. */\n\n    AllocConsole();\n    freopen(\"CONOUT$\", \"a\", stderr);\n    freopen(\"CONOUT$\", \"a\", stdout);\n#endif\n\n    /* Set the default value for our display-system exponent, i.e., the\n     * product of the CRT exponent and the exponent corresponding to\n     * the frame-buffer's lookup table (LUT), if any.  This is not an\n     * exhaustive list of LUT values (e.g., OpenStep has a lot of weird\n     * ones), but it should cover 99% of the current possibilities.  And\n     * yes, these ifdefs are completely wasted in a Windows program... */\n\n#if defined(NeXT)\n    /* third-party utilities can modify the default LUT exponent */\n    LUT_exponent = 1.0 / 2.2;\n    /*\n    if (some_next_function_that_returns_gamma(&next_gamma))\n        LUT_exponent = 1.0 / next_gamma;\n     */\n#elif defined(sgi)\n    LUT_exponent = 1.0 / 1.7;\n    /* there doesn't seem to be any documented function to\n     * get the \"gamma\" value, so we do it the hard way */\n    infile = fopen(\"/etc/config/system.glGammaVal\", \"r\");\n    if (infile) {\n        double sgi_gamma;\n\n        fgets(tmpline, 80, infile);\n        fclose(infile);\n        sgi_gamma = atof(tmpline);\n        if (sgi_gamma > 0.0)\n            LUT_exponent = 1.0 / sgi_gamma;\n    }\n#elif defined(Macintosh)\n    LUT_exponent = 1.8 / 2.61;\n    /*\n    if (some_mac_function_that_returns_gamma(&mac_gamma))\n        LUT_exponent = mac_gamma / 2.61;\n     */\n#else\n    LUT_exponent = 1.0;   /* assume no LUT:  most PCs */\n#endif\n\n    /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */\n    default_display_exponent = LUT_exponent * CRT_exponent;\n\n\n    /* If the user has set the SCREEN_GAMMA environment variable as suggested\n     * (somewhat imprecisely) in the libpng documentation, use that; otherwise\n     * use the default value we just calculated.  Either way, the user may\n     * override this via a command-line option. */\n\n    if ((p = getenv(\"SCREEN_GAMMA\")) != NULL)\n        rpng2_info.display_exponent = atof(p);\n    else\n        rpng2_info.display_exponent = default_display_exponent;\n\n\n    /* Windows really hates command lines, so we have to set up our own argv.\n     * Note that we do NOT bother with quoted arguments here, so don't use\n     * filenames with spaces in 'em! */\n\n    argv[argc++] = PROGNAME;\n    p = cmd;\n    for (;;) {\n        if (*p == ' ')\n            while (*++p == ' ')\n                ;\n        /* now p points at the first non-space after some spaces */\n        if (*p == '\\0')\n            break;    /* nothing after the spaces:  done */\n        argv[argc++] = q = p;\n        while (*q && *q != ' ')\n            ++q;\n        /* now q points at a space or the end of the string */\n        if (*q == '\\0')\n            break;    /* last argv already terminated; quit */\n        *q = '\\0';    /* change space to terminator */\n        p = q + 1;\n    }\n    argv[argc] = NULL;   /* terminate the argv array itself */\n\n\n    /* Now parse the command line for options and the PNG filename. */\n\n    while (*++argv && !error) {\n        if (!strncmp(*argv, \"-gamma\", 2)) {\n            if (!*++argv)\n                ++error;\n            else {\n                rpng2_info.display_exponent = atof(*argv);\n                if (rpng2_info.display_exponent <= 0.0)\n                    ++error;\n            }\n        } else if (!strncmp(*argv, \"-bgcolor\", 4)) {\n            if (!*++argv)\n                ++error;\n            else {\n                bgstr = *argv;\n                if (strlen(bgstr) != 7 || bgstr[0] != '#')\n                    ++error;\n                else {\n                    have_bg = TRUE;\n                    bg_image = FALSE;\n                }\n            }\n        } else if (!strncmp(*argv, \"-bgpat\", 4)) {\n            if (!*++argv)\n                ++error;\n            else {\n                pat = atoi(*argv) - 1;\n                if (pat < 0 || pat >= num_bgpat)\n                    ++error;\n                else {\n                    bg_image = TRUE;\n                    have_bg = FALSE;\n                }\n            }\n        } else if (!strncmp(*argv, \"-timing\", 2)) {\n            timing = TRUE;\n        } else {\n            if (**argv != '-') {\n                filename = *argv;\n                if (argv[1])   /* shouldn't be any more args after filename */\n                    ++error;\n            } else\n                ++error;   /* not expecting any other options */\n        }\n    }\n\n    if (!filename)\n        ++error;\n\n\n    /* print usage screen if any errors up to this point */\n\n    if (error) {\n#ifndef __CYGWIN__\n        int ch;\n#endif\n\n        fprintf(stderr, \"\\n%s %s:  %s\\n\\n\", PROGNAME, VERSION, appname);\n        readpng2_version_info();\n        fprintf(stderr, \"\\n\"\n          \"Usage:  %s [-gamma exp] [-bgcolor bg | -bgpat pat] [-timing]\\n\"\n          \"        %*s file.png\\n\\n\"\n          \"    exp \\ttransfer-function exponent (``gamma'') of the display\\n\"\n          \"\\t\\t  system in floating-point format (e.g., ``%.1f''); equal\\n\"\n          \"\\t\\t  to the product of the lookup-table exponent (varies)\\n\"\n          \"\\t\\t  and the CRT exponent (usually 2.2); must be positive\\n\"\n          \"    bg  \\tdesired background color in 7-character hex RGB format\\n\"\n          \"\\t\\t  (e.g., ``#ff7700'' for orange:  same as HTML colors);\\n\"\n          \"\\t\\t  used with transparent images; overrides -bgpat option\\n\"\n          \"    pat \\tdesired background pattern number (1-%d); used with\\n\"\n          \"\\t\\t  transparent images; overrides -bgcolor option\\n\"\n          \"    -timing\\tenables delay for every block read, to simulate modem\\n\"\n          \"\\t\\t  download of image (~36 Kbps)\\n\"\n          \"\\nPress Q, Esc or mouse button 1 after image is displayed to quit.\\n\"\n#ifndef __CYGWIN__\n          \"Press Q or Esc to quit this usage screen. \",\n#else\n          ,\n#endif\n          PROGNAME,\n#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__)) && \\\n    !(defined(__CYGWIN__) || defined(__MINGW32__))\n          (int)strlen(PROGNAME), \" \",\n#endif\n          (int)strlen(PROGNAME), \" \", default_display_exponent, num_bgpat);\n        fflush(stderr);\n#ifndef __CYGWIN__\n        do\n            ch = _getch();\n        while (ch != 'q' && ch != 'Q' && ch != 0x1B);\n#endif\n        exit(1);\n    }\n\n\n    if (!(infile = fopen(filename, \"rb\"))) {\n        fprintf(stderr, PROGNAME \":  can't open PNG file [%s]\\n\", filename);\n        ++error;\n    } else {\n        incount = fread(inbuf, 1, INBUFSIZE, infile);\n        if (incount < 8 || !readpng2_check_sig(inbuf, 8)) {\n            fprintf(stderr, PROGNAME\n              \":  [%s] is not a PNG file: incorrect signature\\n\",\n              filename);\n            ++error;\n        } else if ((rc = readpng2_init(&rpng2_info)) != 0) {\n            switch (rc) {\n                case 2:\n                    fprintf(stderr, PROGNAME\n                      \":  [%s] has bad IHDR (libpng longjmp)\\n\", filename);\n                    break;\n                case 4:\n                    fprintf(stderr, PROGNAME \":  insufficient memory\\n\");\n                    break;\n                default:\n                    fprintf(stderr, PROGNAME\n                      \":  unknown readpng2_init() error\\n\");\n                    break;\n            }\n            ++error;\n        }\n        if (error)\n            fclose(infile);\n    }\n\n\n    if (error) {\n#ifndef __CYGWIN__\n        int ch;\n#endif\n\n        fprintf(stderr, PROGNAME \":  aborting.\\n\");\n#ifndef __CYGWIN__\n        do\n            ch = _getch();\n        while (ch != 'q' && ch != 'Q' && ch != 0x1B);\n#endif\n        exit(2);\n    } else {\n        fprintf(stderr, \"\\n%s %s:  %s\\n\", PROGNAME, VERSION, appname);\n#ifndef __CYGWIN__\n        fprintf(stderr,\n          \"\\n   [console window:  closing this window will terminate %s]\\n\\n\",\n          PROGNAME);\n#endif\n        fflush(stderr);\n    }\n\n\n    /* set the title-bar string, but make sure buffer doesn't overflow */\n\n    alen = strlen(appname);\n    flen = strlen(filename);\n    if (alen + flen + 3 > 1023)\n        sprintf(titlebar, \"%s:  ...%s\", appname, filename+(alen+flen+6-1023));\n    else\n        sprintf(titlebar, \"%s:  %s\", appname, filename);\n\n\n    /* set some final rpng2_info variables before entering main data loop */\n\n    if (have_bg) {\n        unsigned r, g, b;   /* this approach quiets compiler warnings */\n\n        sscanf(bgstr+1, \"%2x%2x%2x\", &r, &g, &b);\n        rpng2_info.bg_red   = (uch)r;\n        rpng2_info.bg_green = (uch)g;\n        rpng2_info.bg_blue  = (uch)b;\n    } else\n        rpng2_info.need_bgcolor = TRUE;\n\n    rpng2_info.state = kPreInit;\n    rpng2_info.mainprog_init = rpng2_win_init;\n    rpng2_info.mainprog_display_row = rpng2_win_display_row;\n    rpng2_info.mainprog_finish_display = rpng2_win_finish_display;\n\n\n    /* OK, this is the fun part:  call readpng2_decode_data() at the start of\n     * the loop to deal with our first buffer of data (read in above to verify\n     * that the file is a PNG image), then loop through the file and continue\n     * calling the same routine to handle each chunk of data.  It in turn\n     * passes the data to libpng, which will invoke one or more of our call-\n     * backs as decoded data become available.  We optionally call Sleep() for\n     * one second per iteration to simulate downloading the image via an analog\n     * modem. */\n\n    for (;;) {\n        Trace((stderr, \"about to call readpng2_decode_data()\\n\"))\n        if (readpng2_decode_data(&rpng2_info, inbuf, incount))\n            ++error;\n        Trace((stderr, \"done with readpng2_decode_data()\\n\"))\n\n        if (error || incount != INBUFSIZE || rpng2_info.state == kDone) {\n            if (rpng2_info.state == kDone) {\n                Trace((stderr, \"done decoding PNG image\\n\"))\n            } else if (ferror(infile)) {\n                fprintf(stderr, PROGNAME\n                  \":  error while reading PNG image file\\n\");\n                exit(3);\n            } else if (feof(infile)) {\n                fprintf(stderr, PROGNAME \":  end of file reached \"\n                  \"(unexpectedly) while reading PNG image file\\n\");\n                exit(3);\n            } else /* if (error) */ {\n                /* will print error message below */\n            }\n            break;\n        }\n\n        if (timing)\n            Sleep(1000L);\n\n        incount = fread(inbuf, 1, INBUFSIZE, infile);\n    }\n\n\n    /* clean up PNG stuff and report any decoding errors */\n\n    fclose(infile);\n    Trace((stderr, \"about to call readpng2_cleanup()\\n\"))\n    readpng2_cleanup(&rpng2_info);\n\n    if (error) {\n        fprintf(stderr, PROGNAME \":  libpng error while decoding PNG image\\n\");\n        exit(3);\n    }\n\n\n    /* wait for the user to tell us when to quit */\n\n    while (GetMessage(&msg, NULL, 0, 0)) {\n        TranslateMessage(&msg);\n        DispatchMessage(&msg);\n    }\n\n\n    /* we're done:  clean up all image and Windows resources and go away */\n\n    Trace((stderr, \"about to call rpng2_win_cleanup()\\n\"))\n    rpng2_win_cleanup();\n\n    return msg.wParam;\n}\n\n\n\n\n\n/* this function is called by readpng2_info_callback() in readpng2.c, which\n * in turn is called by libpng after all of the pre-IDAT chunks have been\n * read and processed--i.e., we now have enough info to finish initializing */\n\nstatic void rpng2_win_init()\n{\n    ulg i;\n    ulg rowbytes = rpng2_info.rowbytes;\n\n    Trace((stderr, \"beginning rpng2_win_init()\\n\"))\n    Trace((stderr, \"  rowbytes = %d\\n\", rpng2_info.rowbytes))\n    Trace((stderr, \"  width  = %ld\\n\", rpng2_info.width))\n    Trace((stderr, \"  height = %ld\\n\", rpng2_info.height))\n\n    rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height);\n    if (!rpng2_info.image_data) {\n        readpng2_cleanup(&rpng2_info);\n        return;\n    }\n\n    rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *));\n    if (!rpng2_info.row_pointers) {\n        free(rpng2_info.image_data);\n        rpng2_info.image_data = NULL;\n        readpng2_cleanup(&rpng2_info);\n        return;\n    }\n\n    for (i = 0;  i < rpng2_info.height;  ++i)\n        rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes;\n\n/*---------------------------------------------------------------------------\n    Do the basic Windows initialization stuff, make the window, and fill it\n    with the user-specified, file-specified or default background color.\n  ---------------------------------------------------------------------------*/\n\n    if (rpng2_win_create_window()) {\n        readpng2_cleanup(&rpng2_info);\n        return;\n    }\n\n    rpng2_info.state = kWindowInit;\n}\n\n\n\n\n\nstatic int rpng2_win_create_window()\n{\n    uch bg_red   = rpng2_info.bg_red;\n    uch bg_green = rpng2_info.bg_green;\n    uch bg_blue  = rpng2_info.bg_blue;\n    uch *dest;\n    int extra_width, extra_height;\n    ulg i, j;\n    WNDCLASSEX wndclass;\n    RECT rect;\n\n\n/*---------------------------------------------------------------------------\n    Allocate memory for the display-specific version of the image (round up\n    to multiple of 4 for Windows DIB).\n  ---------------------------------------------------------------------------*/\n\n    wimage_rowbytes = ((3*rpng2_info.width + 3L) >> 2) << 2;\n\n    if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +\n                              wimage_rowbytes*rpng2_info.height)))\n    {\n        return 4;   /* fail */\n    }\n\n/*---------------------------------------------------------------------------\n    Initialize the DIB.  Negative height means to use top-down BMP ordering\n    (must be uncompressed, but that's what we want).  Bit count of 1, 4 or 8\n    implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values\n    directly => wimage_data begins immediately after BMP header.\n  ---------------------------------------------------------------------------*/\n\n    memset(dib, 0, sizeof(BITMAPINFOHEADER));\n    bmih = (BITMAPINFOHEADER *)dib;\n    bmih->biSize = sizeof(BITMAPINFOHEADER);\n    bmih->biWidth = rpng2_info.width;\n    bmih->biHeight = -((long)rpng2_info.height);\n    bmih->biPlanes = 1;\n    bmih->biBitCount = 24;\n    bmih->biCompression = 0;\n    wimage_data = dib + sizeof(BITMAPINFOHEADER);\n\n/*---------------------------------------------------------------------------\n    Fill window with the specified background color (default is black), but\n    defer loading faked \"background image\" until window is displayed (may be\n    slow to compute).  Data are in BGR order.\n  ---------------------------------------------------------------------------*/\n\n    if (bg_image) {   /* just fill with black for now */\n        memset(wimage_data, 0, wimage_rowbytes*rpng2_info.height);\n    } else {\n        for (j = 0;  j < rpng2_info.height;  ++j) {\n            dest = wimage_data + j*wimage_rowbytes;\n            for (i = rpng2_info.width;  i > 0;  --i) {\n                *dest++ = bg_blue;\n                *dest++ = bg_green;\n                *dest++ = bg_red;\n            }\n        }\n    }\n\n/*---------------------------------------------------------------------------\n    Set the window parameters.\n  ---------------------------------------------------------------------------*/\n\n    memset(&wndclass, 0, sizeof(wndclass));\n\n    wndclass.cbSize = sizeof(wndclass);\n    wndclass.style = CS_HREDRAW | CS_VREDRAW;\n    wndclass.lpfnWndProc = rpng2_win_wndproc;\n    wndclass.hInstance = global_hInst;\n    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);\n    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);\n    wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);\n    wndclass.lpszMenuName = NULL;\n    wndclass.lpszClassName = progname;\n    wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);\n\n    RegisterClassEx(&wndclass);\n\n/*---------------------------------------------------------------------------\n    Finally, create the window.\n  ---------------------------------------------------------------------------*/\n\n    extra_width  = 2*(GetSystemMetrics(SM_CXBORDER) +\n                      GetSystemMetrics(SM_CXDLGFRAME));\n    extra_height = 2*(GetSystemMetrics(SM_CYBORDER) +\n                      GetSystemMetrics(SM_CYDLGFRAME)) +\n                      GetSystemMetrics(SM_CYCAPTION);\n\n    global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW,\n      CW_USEDEFAULT, CW_USEDEFAULT, rpng2_info.width+extra_width,\n      rpng2_info.height+extra_height, NULL, NULL, global_hInst, NULL);\n\n    ShowWindow(global_hwnd, global_showmode);\n    UpdateWindow(global_hwnd);\n\n/*---------------------------------------------------------------------------\n    Now compute the background image and display it.  If it fails (memory\n    allocation), revert to a plain background color.\n  ---------------------------------------------------------------------------*/\n\n    if (bg_image) {\n        static const char *msg = \"Computing background image...\";\n        int x, y, len = strlen(msg);\n        HDC hdc = GetDC(global_hwnd);\n        TEXTMETRIC tm;\n\n        GetTextMetrics(hdc, &tm);\n        x = (rpng2_info.width - len*tm.tmAveCharWidth)/2;\n        y = (rpng2_info.height - tm.tmHeight)/2;\n        SetBkMode(hdc, TRANSPARENT);\n        SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));\n        /* this can still begin out of bounds even if x is positive (???): */\n        TextOut(hdc, ((x < 0)? 0 : x), ((y < 0)? 0 : y), msg, len);\n        ReleaseDC(global_hwnd, hdc);\n\n        rpng2_win_load_bg_image();   /* resets bg_image if fails */\n    }\n\n    if (!bg_image) {\n        for (j = 0;  j < rpng2_info.height;  ++j) {\n            dest = wimage_data + j*wimage_rowbytes;\n            for (i = rpng2_info.width;  i > 0;  --i) {\n                *dest++ = bg_blue;\n                *dest++ = bg_green;\n                *dest++ = bg_red;\n            }\n        }\n    }\n\n    rect.left = 0L;\n    rect.top = 0L;\n    rect.right = (LONG)rpng2_info.width;       /* possibly off by one? */\n    rect.bottom = (LONG)rpng2_info.height;     /* possibly off by one? */\n    InvalidateRect(global_hwnd, &rect, FALSE);\n    UpdateWindow(global_hwnd);                 /* similar to XFlush() */\n\n    return 0;\n\n} /* end function rpng2_win_create_window() */\n\n\n\n\n\nstatic int rpng2_win_load_bg_image()\n{\n    uch *src, *dest;\n    uch r1, r2, g1, g2, b1, b2;\n    uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv;\n    int k, hmax, max;\n    int xidx, yidx, yidx_max = (bgscale-1);\n    int even_odd_vert, even_odd_horiz, even_odd;\n    int invert_gradient2 = (bg[pat].type & 0x08);\n    int invert_column;\n    ulg i, row;\n\n/*---------------------------------------------------------------------------\n    Allocate buffer for fake background image to be used with transparent\n    images; if this fails, revert to plain background color.\n  ---------------------------------------------------------------------------*/\n\n    bg_rowbytes = 3 * rpng2_info.width;\n    bg_data = (uch *)malloc(bg_rowbytes * rpng2_info.height);\n    if (!bg_data) {\n        fprintf(stderr, PROGNAME\n          \":  unable to allocate memory for background image\\n\");\n        bg_image = 0;\n        return 1;\n    }\n\n/*---------------------------------------------------------------------------\n    Vertical gradients (ramps) in NxN squares, alternating direction and\n    colors (N == bgscale).\n  ---------------------------------------------------------------------------*/\n\n    if ((bg[pat].type & 0x07) == 0) {\n        uch r1_min  = rgb[bg[pat].rgb1_min].r;\n        uch g1_min  = rgb[bg[pat].rgb1_min].g;\n        uch b1_min  = rgb[bg[pat].rgb1_min].b;\n        uch r2_min  = rgb[bg[pat].rgb2_min].r;\n        uch g2_min  = rgb[bg[pat].rgb2_min].g;\n        uch b2_min  = rgb[bg[pat].rgb2_min].b;\n        int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min;\n        int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min;\n        int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min;\n        int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min;\n        int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min;\n        int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min;\n\n        for (row = 0;  row < rpng2_info.height;  ++row) {\n            yidx = row % bgscale;\n            even_odd_vert = (row / bgscale) & 1;\n\n            r1 = r1_min + (r1_diff * yidx) / yidx_max;\n            g1 = g1_min + (g1_diff * yidx) / yidx_max;\n            b1 = b1_min + (b1_diff * yidx) / yidx_max;\n            r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max;\n            g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max;\n            b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max;\n\n            r2 = r2_min + (r2_diff * yidx) / yidx_max;\n            g2 = g2_min + (g2_diff * yidx) / yidx_max;\n            b2 = b2_min + (b2_diff * yidx) / yidx_max;\n            r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max;\n            g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max;\n            b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max;\n\n            dest = bg_data + row*bg_rowbytes;\n            for (i = 0;  i < rpng2_info.width;  ++i) {\n                even_odd_horiz = (i / bgscale) & 1;\n                even_odd = even_odd_vert ^ even_odd_horiz;\n                invert_column =\n                  (even_odd_horiz && (bg[pat].type & 0x10));\n                if (even_odd == 0) {         /* gradient #1 */\n                    if (invert_column) {\n                        *dest++ = r1_inv;\n                        *dest++ = g1_inv;\n                        *dest++ = b1_inv;\n                    } else {\n                        *dest++ = r1;\n                        *dest++ = g1;\n                        *dest++ = b1;\n                    }\n                } else {                     /* gradient #2 */\n                    if ((invert_column && invert_gradient2) ||\n                        (!invert_column && !invert_gradient2))\n                    {\n                        *dest++ = r2;        /* not inverted or */\n                        *dest++ = g2;        /*  doubly inverted */\n                        *dest++ = b2;\n                    } else {\n                        *dest++ = r2_inv;\n                        *dest++ = g2_inv;    /* singly inverted */\n                        *dest++ = b2_inv;\n                    }\n                }\n            }\n        }\n\n/*---------------------------------------------------------------------------\n    Soft gradient-diamonds with scale = bgscale.  Code contributed by Adam\n    M. Costello.\n  ---------------------------------------------------------------------------*/\n\n    } else if ((bg[pat].type & 0x07) == 1) {\n\n        hmax = (bgscale-1)/2;   /* half the max weight of a color */\n        max = 2*hmax;           /* the max weight of a color */\n\n        r1 = rgb[bg[pat].rgb1_max].r;\n        g1 = rgb[bg[pat].rgb1_max].g;\n        b1 = rgb[bg[pat].rgb1_max].b;\n        r2 = rgb[bg[pat].rgb2_max].r;\n        g2 = rgb[bg[pat].rgb2_max].g;\n        b2 = rgb[bg[pat].rgb2_max].b;\n\n        for (row = 0;  row < rpng2_info.height;  ++row) {\n            yidx = row % bgscale;\n            if (yidx > hmax)\n                yidx = bgscale-1 - yidx;\n            dest = bg_data + row*bg_rowbytes;\n            for (i = 0;  i < rpng2_info.width;  ++i) {\n                xidx = i % bgscale;\n                if (xidx > hmax)\n                    xidx = bgscale-1 - xidx;\n                k = xidx + yidx;\n                *dest++ = (k*r1 + (max-k)*r2) / max;\n                *dest++ = (k*g1 + (max-k)*g2) / max;\n                *dest++ = (k*b1 + (max-k)*b2) / max;\n            }\n        }\n\n/*---------------------------------------------------------------------------\n    Radial \"starburst\" with azimuthal sinusoids; [eventually number of sinu-\n    soids will equal bgscale?].  This one is slow but very cool.  Code con-\n    tributed by Pieter S. van der Meulen (originally in Smalltalk).\n  ---------------------------------------------------------------------------*/\n\n    } else if ((bg[pat].type & 0x07) == 2) {\n        uch ch;\n        int ii, x, y, hw, hh, grayspot;\n        double freq, rotate, saturate, gray, intensity;\n        double angle=0.0, aoffset=0.0, maxDist, dist;\n        double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t;\n\n        fprintf(stderr, \"%s:  computing radial background...\",\n          PROGNAME);\n        fflush(stderr);\n\n        hh = rpng2_info.height / 2;\n        hw = rpng2_info.width / 2;\n\n        /* variables for radial waves:\n         *   aoffset:  number of degrees to rotate hue [CURRENTLY NOT USED]\n         *   freq:  number of color beams originating from the center\n         *   grayspot:  size of the graying center area (anti-alias)\n         *   rotate:  rotation of the beams as a function of radius\n         *   saturate:  saturation of beams' shape azimuthally\n         */\n        angle = CLIP(angle, 0.0, 360.0);\n        grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw));\n        freq = MAX((double)bg[pat].bg_freq, 0.0);\n        saturate = (double)bg[pat].bg_bsat * 0.1;\n        rotate = (double)bg[pat].bg_brot * 0.1;\n        gray = 0.0;\n        intensity = 0.0;\n        maxDist = (double)((hw*hw) + (hh*hh));\n\n        for (row = 0;  row < rpng2_info.height;  ++row) {\n            y = row - hh;\n            dest = bg_data + row*bg_rowbytes;\n            for (i = 0;  i < rpng2_info.width;  ++i) {\n                x = i - hw;\n                angle = (x == 0)? PI_2 : atan((double)y / (double)x);\n                gray = (double)MAX(ABS(y), ABS(x)) / grayspot;\n                gray = MIN(1.0, gray);\n                dist = (double)((x*x) + (y*y)) / maxDist;\n                intensity = cos((angle+(rotate*dist*PI)) * freq) *\n                  gray * saturate;\n                intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5;\n                hue = (angle + PI) * INV_PI_360 + aoffset;\n                s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh));\n                s = MIN(MAX(s,0.0), 1.0);\n                v = MIN(MAX(intensity,0.0), 1.0);\n\n                if (s == 0.0) {\n                    ch = (uch)(v * 255.0);\n                    *dest++ = ch;\n                    *dest++ = ch;\n                    *dest++ = ch;\n                } else {\n                    if ((hue < 0.0) || (hue >= 360.0))\n                        hue -= (((int)(hue / 360.0)) * 360.0);\n                    hue /= 60.0;\n                    ii = (int)hue;\n                    f = hue - (double)ii;\n                    p = (1.0 - s) * v;\n                    q = (1.0 - (s * f)) * v;\n                    t = (1.0 - (s * (1.0 - f))) * v;\n                    if      (ii == 0) { red = v; green = t; blue = p; }\n                    else if (ii == 1) { red = q; green = v; blue = p; }\n                    else if (ii == 2) { red = p; green = v; blue = t; }\n                    else if (ii == 3) { red = p; green = q; blue = v; }\n                    else if (ii == 4) { red = t; green = p; blue = v; }\n                    else if (ii == 5) { red = v; green = p; blue = q; }\n                    *dest++ = (uch)(red * 255.0);\n                    *dest++ = (uch)(green * 255.0);\n                    *dest++ = (uch)(blue * 255.0);\n                }\n            }\n        }\n        fprintf(stderr, \"done.\\n\");\n        fflush(stderr);\n    }\n\n/*---------------------------------------------------------------------------\n    Blast background image to display buffer before beginning PNG decode;\n    calling function will handle invalidation and UpdateWindow() call.\n  ---------------------------------------------------------------------------*/\n\n    for (row = 0;  row < rpng2_info.height;  ++row) {\n        src = bg_data + row*bg_rowbytes;\n        dest = wimage_data + row*wimage_rowbytes;\n        for (i = rpng2_info.width;  i > 0;  --i) {\n            r1 = *src++;\n            g1 = *src++;\n            b1 = *src++;\n            *dest++ = b1;\n            *dest++ = g1;   /* note reverse order */\n            *dest++ = r1;\n        }\n    }\n\n    return 0;\n\n} /* end function rpng2_win_load_bg_image() */\n\n\n\n\n\nstatic void rpng2_win_display_row(ulg row)\n{\n    uch bg_red   = rpng2_info.bg_red;\n    uch bg_green = rpng2_info.bg_green;\n    uch bg_blue  = rpng2_info.bg_blue;\n    uch *src, *src2=NULL, *dest;\n    uch r, g, b, a;\n    ulg i;\n    static int rows=0;\n    static ulg firstrow;\n\n/*---------------------------------------------------------------------------\n    rows and firstrow simply track how many rows (and which ones) have not\n    yet been displayed; alternatively, we could call InvalidateRect() for\n    every row and not bother with the records-keeping.\n  ---------------------------------------------------------------------------*/\n\n    Trace((stderr, \"beginning rpng2_win_display_row()\\n\"))\n\n    if (rows == 0)\n        firstrow = row;   /* first row not yet displayed */\n\n    ++rows;   /* count of rows received but not yet displayed */\n\n/*---------------------------------------------------------------------------\n    Aside from the use of the rpng2_info struct and the lack of an outer\n    loop (over rows), this routine is identical to rpng_win_display_image()\n    in the non-progressive version of the program.\n  ---------------------------------------------------------------------------*/\n\n    src = rpng2_info.image_data + row*rpng2_info.rowbytes;\n    if (bg_image)\n        src2 = bg_data + row*bg_rowbytes;\n    dest = wimage_data + row*wimage_rowbytes;\n\n    if (rpng2_info.channels == 3) {\n        for (i = rpng2_info.width;  i > 0;  --i) {\n            r = *src++;\n            g = *src++;\n            b = *src++;\n            *dest++ = b;\n            *dest++ = g;   /* note reverse order */\n            *dest++ = r;\n        }\n    } else /* if (rpng2_info.channels == 4) */ {\n        for (i = rpng2_info.width;  i > 0;  --i) {\n            r = *src++;\n            g = *src++;\n            b = *src++;\n            a = *src++;\n            if (bg_image) {\n                bg_red   = *src2++;\n                bg_green = *src2++;\n                bg_blue  = *src2++;\n            }\n            if (a == 255) {\n                *dest++ = b;\n                *dest++ = g;\n                *dest++ = r;\n            } else if (a == 0) {\n                *dest++ = bg_blue;\n                *dest++ = bg_green;\n                *dest++ = bg_red;\n            } else {\n                /* this macro (copied from png.h) composites the\n                 * foreground and background values and puts the\n                 * result into the first argument; there are no\n                 * side effects with the first argument */\n                alpha_composite(*dest++, b, a, bg_blue);\n                alpha_composite(*dest++, g, a, bg_green);\n                alpha_composite(*dest++, r, a, bg_red);\n            }\n        }\n    }\n\n/*---------------------------------------------------------------------------\n    Display after every 16 rows or when on last row.  (Region may include\n    previously displayed lines due to interlacing--i.e., not contiguous.)\n  ---------------------------------------------------------------------------*/\n\n    if ((rows & 0xf) == 0 || row == rpng2_info.height-1) {\n        RECT rect;\n\n        rect.left = 0L;\n        rect.top = (LONG)firstrow;\n        rect.right = (LONG)rpng2_info.width;       /* possibly off by one? */\n        rect.bottom = (LONG)row + 1L;              /* possibly off by one? */\n        InvalidateRect(global_hwnd, &rect, FALSE);\n        UpdateWindow(global_hwnd);                 /* similar to XFlush() */\n        rows = 0;\n    }\n\n} /* end function rpng2_win_display_row() */\n\n\n\n\n\nstatic void rpng2_win_finish_display()\n{\n    Trace((stderr, \"beginning rpng2_win_finish_display()\\n\"))\n\n    /* last row has already been displayed by rpng2_win_display_row(), so\n     * we have nothing to do here except set a flag and let the user know\n     * that the image is done */\n\n    rpng2_info.state = kDone;\n    printf(\n#ifndef __CYGWIN__\n      \"Done.  Press Q, Esc or mouse button 1 (within image window) to quit.\\n\"\n#else\n      \"Done.  Press mouse button 1 (within image window) to quit.\\n\"\n#endif\n    );\n    fflush(stdout);\n}\n\n\n\n\n\nstatic void rpng2_win_cleanup()\n{\n    if (bg_image && bg_data) {\n        free(bg_data);\n        bg_data = NULL;\n    }\n\n    if (rpng2_info.image_data) {\n        free(rpng2_info.image_data);\n        rpng2_info.image_data = NULL;\n    }\n\n    if (rpng2_info.row_pointers) {\n        free(rpng2_info.row_pointers);\n        rpng2_info.row_pointers = NULL;\n    }\n\n    if (dib) {\n        free(dib);\n        dib = NULL;\n    }\n}\n\n\n\n\n\nLRESULT CALLBACK rpng2_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP)\n{\n    HDC         hdc;\n    PAINTSTRUCT ps;\n    int rc;\n\n    switch (iMsg) {\n        case WM_CREATE:\n            /* one-time processing here, if any */\n            return 0;\n\n        case WM_PAINT:\n            hdc = BeginPaint(hwnd, &ps);\n            rc = StretchDIBits(hdc, 0, 0, rpng2_info.width, rpng2_info.height,\n                                    0, 0, rpng2_info.width, rpng2_info.height,\n                                    wimage_data, (BITMAPINFO *)bmih,\n                                    0, SRCCOPY);\n            EndPaint(hwnd, &ps);\n            return 0;\n\n        /* wait for the user to tell us when to quit */\n        case WM_CHAR:\n            switch (wP) {       /* only need one, so ignore repeat count */\n                case 'q':\n                case 'Q':\n                case 0x1B:      /* Esc key */\n                    PostQuitMessage(0);\n            }\n            return 0;\n\n        case WM_LBUTTONDOWN:    /* another way of quitting */\n        case WM_DESTROY:\n            PostQuitMessage(0);\n            return 0;\n    }\n\n    return DefWindowProc(hwnd, iMsg, wP, lP);\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/rpng2-x.c",
    "content": "/*---------------------------------------------------------------------------\n\n   rpng2 - progressive-model PNG display program                  rpng2-x.c\n\n   This program decodes and displays PNG files progressively, as if it were\n   a web browser (though the front end is only set up to read from files).\n   It supports gamma correction, user-specified background colors, and user-\n   specified background patterns (for transparent images).  This version is\n   for the X Window System (tested by the author under Unix and by Martin\n   Zinser under OpenVMS; may work under OS/2 with a little tweaking).\n\n   Thanks to Adam Costello and Pieter S. van der Meulen for the \"diamond\"\n   and \"radial waves\" patterns, respectively.\n\n   to do (someday, maybe):\n    - fix expose/redraw code:  don't draw entire row if only part exposed\n    - 8-bit (colormapped) X support\n    - finish resizable checkerboard-gradient (sizes 4-128?)\n    - use %.1023s to simplify truncation of title-bar string?\n\n  ---------------------------------------------------------------------------\n\n   Changelog:\n    - 1.01:  initial public release\n    - 1.02:  modified to allow abbreviated options; fixed char/uchar mismatch\n    - 1.10:  added support for non-default visuals; fixed X pixel-conversion\n    - 1.11:  added -usleep option for demos; fixed command-line parsing bug\n    - 1.12:  added -pause option for demos and testing\n    - 1.20:  added runtime MMX-enabling/disabling and new -mmx* options\n    - 1.21:  fixed some small X memory leaks (thanks to Franois Petitjean)\n    - 1.22:  fixed XFreeGC() crash bug (thanks to Patrick Welche)\n    - 1.23:  added -bgpat 0 mode (std white/gray checkerboard, 8x8 squares)\n    - 1.30:  added -loop option for -bgpat (ifdef FEATURE_LOOP); fixed bpp =\n              24; added support for X resources (thanks to Gerhard Niklasch)\n    - 1.31:  added code to skip unused chunks (thanks to Glenn Randers-Pehrson)\n    - 1.32:  added AMD64/EM64T support (__x86_64__); added basic expose/redraw\n              handling\n    - 2.00:  dual-licensed (added GNU GPL)\n    - 2.01:  fixed 64-bit typo in readpng2.c; fixed -pause usage description\n    - 2.02:  fixed improper display of usage screen on PNG error(s); fixed\n              unexpected-EOF and file-read-error cases; fixed Trace() cut-and-\n              paste bugs\n    - 2.03:  deleted runtime MMX-enabling/disabling and obsolete -mmx* options\n    - 2.04:  Added \"void(foo);\" statements to quiet pedantic compiler warnings\n             about unused variables (GR-P)\n    - 2.05:  Use nanosleep() instead of usleep(), which is deprecated (GR-P).\n  ---------------------------------------------------------------------------\n\n      Copyright (c) 1998-2010, 2014-2015 Greg Roelofs.  All rights reserved.\n\n      This software is provided \"as is,\" without warranty of any kind,\n      express or implied.  In no event shall the author or contributors\n      be held liable for any damages arising in any way from the use of\n      this software.\n\n      The contents of this file are DUAL-LICENSED.  You may modify and/or\n      redistribute this software according to the terms of one of the\n      following two licenses (at your option):\n\n\n      LICENSE 1 (\"BSD-like with advertising clause\"):\n\n      Permission is granted to anyone to use this software for any purpose,\n      including commercial applications, and to alter it and redistribute\n      it freely, subject to the following restrictions:\n\n      1. Redistributions of source code must retain the above copyright\n         notice, disclaimer, and this list of conditions.\n      2. Redistributions in binary form must reproduce the above copyright\n         notice, disclaimer, and this list of conditions in the documenta-\n         tion and/or other materials provided with the distribution.\n      3. All advertising materials mentioning features or use of this\n         software must display the following acknowledgment:\n\n            This product includes software developed by Greg Roelofs\n            and contributors for the book, \"PNG: The Definitive Guide,\"\n            published by O'Reilly and Associates.\n\n\n      LICENSE 2 (GNU GPL v2 or later):\n\n      This program is free software; you can redistribute it and/or modify\n      it under the terms of the GNU General Public License as published by\n      the Free Software Foundation; either version 2 of the License, or\n      (at your option) any later version.\n\n      This program is distributed in the hope that it will be useful,\n      but WITHOUT ANY WARRANTY; without even the implied warranty of\n      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n      GNU General Public License for more details.\n\n      You should have received a copy of the GNU General Public License\n      along with this program; if not, write to the Free Software Foundation,\n      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  ---------------------------------------------------------------------------*/\n\n#define PROGNAME  \"rpng2-x\"\n#define LONGNAME  \"Progressive PNG Viewer for X\"\n#define VERSION   \"2.04 of 15 June 2014\"\n#define RESNAME   \"rpng2\"       /* our X resource application name */\n#define RESCLASS  \"Rpng\"       /* our X resource class name */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <ctype.h>\n#include <string.h>\n#include <setjmp.h>       /* for jmpbuf declaration in readpng2.h */\n#include <time.h>\n#include <math.h>         /* only for PvdM background code */\n#include <X11/Xlib.h>\n#include <X11/Xutil.h>\n#include <X11/Xos.h>\n#include <X11/keysym.h>   /* defines XK_* macros */\n\n#if _POSIX_C_SOURCE >= 199309L /* have nanosleep() */\n# undef usleep\n# define usleep(usec) {        \\\n   struct timespec ts;         \\\n   ts.tv_sec = 0;              \\\n   ts.tv_nsec = (usec) * 1000; \\\n   nanosleep(&ts, NULL); }\n#  endif\n\n#ifndef usleep /* have neither nanosleep() nor usleep() */\n#  define usleep(x) sleep(((x)+499999)/1000000)\n#endif\n\n#ifdef VMS\n#  include <unistd.h>\n#endif\n\n/* all for PvdM background code: */\n#ifndef PI\n#  define PI             3.141592653589793238\n#endif\n#define PI_2             (PI*0.5)\n#define INV_PI_360       (360.0 / PI)\n#define MAX(a,b)         (a>b?a:b)\n#define MIN(a,b)         (a<b?a:b)\n#define CLIP(a,min,max)  MAX(min,MIN((a),max))\n#define ABS(a)           ((a)<0?-(a):(a))\n#define CLIP8P(c)        MAX(0,(MIN((c),255)))   /* 8-bit pos. integer (uch) */\n#define ROUNDF(f)        ((int)(f + 0.5))\n\n#define QUIT(e,k) ((e.type == ButtonPress && e.xbutton.button == Button1) ||  \\\n                  (e.type == KeyPress &&   /*  v--- or 1 for shifted keys */  \\\n                  ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape)))\n\n#define NO_24BIT_MASKS /* undef case not fully written--only for redisplay() */\n\n#define rgb1_max   bg_freq\n#define rgb1_min   bg_gray\n#define rgb2_max   bg_bsat\n#define rgb2_min   bg_brot\n\n/* #define DEBUG */     /* this enables the Trace() macros */\n\n#include \"readpng2.h\"   /* typedefs, common macros, readpng2 prototypes */\n\n\n/* could just include png.h, but this macro is the only thing we need\n * (name and typedefs changed to local versions); note that side effects\n * only happen with alpha (which could easily be avoided with\n * \"ush acopy = (alpha);\") */\n\n#define alpha_composite(composite, fg, alpha, bg) {               \\\n    ush temp = ((ush)(fg)*(ush)(alpha) +                          \\\n                (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128);  \\\n    (composite) = (uch)((temp + (temp >> 8)) >> 8);               \\\n}\n\n\n#define INBUFSIZE 4096   /* with pseudo-timing on (1 sec delay/block), this\n                          *  block size corresponds roughly to a download\n                          *  speed 10% faster than theoretical 33.6K maximum\n                          *  (assuming 8 data bits, 1 stop bit and no other\n                          *  overhead) */\n\n/* local prototypes */\nstatic void rpng2_x_init (void);\nstatic int  rpng2_x_create_window (void);\nstatic int  rpng2_x_load_bg_image (void);\nstatic void rpng2_x_display_row (ulg row);\nstatic void rpng2_x_finish_display (void);\nstatic void rpng2_x_redisplay_image (ulg startcol, ulg startrow,\n                                     ulg width, ulg height);\n#ifdef FEATURE_LOOP\nstatic void rpng2_x_reload_bg_image (void);\nstatic int  is_number (char *p);\n#endif\nstatic void rpng2_x_cleanup (void);\nstatic int  rpng2_x_msb (ulg u32val);\n\n\nstatic char titlebar[1024], *window_name = titlebar;\nstatic char *appname = LONGNAME;\nstatic char *icon_name = PROGNAME;\nstatic char *res_name = RESNAME;\nstatic char *res_class = RESCLASS;\nstatic char *filename;\nstatic FILE *infile;\n\nstatic mainprog_info rpng2_info;\n\nstatic uch inbuf[INBUFSIZE];\nstatic int incount;\n\nstatic int pat = 6;        /* must be less than num_bgpat */\nstatic int bg_image = 0;\nstatic int bgscale, bgscale_default = 16;\nstatic ulg bg_rowbytes;\nstatic uch *bg_data;\n\nint pause_after_pass = FALSE;\nint demo_timing = FALSE;\nulg usleep_duration = 0L;\n\nstatic struct rgb_color {\n    uch r, g, b;\n} rgb[] = {\n    {  0,   0,   0},    /*  0:  black */\n    {255, 255, 255},    /*  1:  white */\n    {173, 132,  57},    /*  2:  tan */\n    { 64, 132,   0},    /*  3:  medium green */\n    {189, 117,   1},    /*  4:  gold */\n    {253, 249,   1},    /*  5:  yellow */\n    {  0,   0, 255},    /*  6:  blue */\n    {  0,   0, 120},    /*  7:  medium blue */\n    {255,   0, 255},    /*  8:  magenta */\n    { 64,   0,  64},    /*  9:  dark magenta */\n    {255,   0,   0},    /* 10:  red */\n    { 64,   0,   0},    /* 11:  dark red */\n    {255, 127,   0},    /* 12:  orange */\n    {192,  96,   0},    /* 13:  darker orange */\n    { 24,  60,   0},    /* 14:  dark green-yellow */\n    { 85, 125, 200},    /* 15:  ice blue */\n    {192, 192, 192}     /* 16:  Netscape/Mosaic gray */\n};\n/* not used for now, but should be for error-checking:\nstatic int num_rgb = sizeof(rgb) / sizeof(struct rgb_color);\n */\n\n/*\n    This whole struct is a fairly cheesy way to keep the number of\n    command-line options to a minimum.  The radial-waves background\n    type is a particularly poor fit to the integer elements of the\n    struct...but a few macros and a little fixed-point math will do\n    wonders for ya.\n\n    type bits:\n       F E D C B A 9 8 7 6 5 4 3 2 1 0\n                             | | | | |\n                             | | +-+-+-- 0 = sharp-edged checkerboard\n                             | |         1 = soft diamonds\n                             | |         2 = radial waves\n                             | |       3-7 = undefined\n                             | +-- gradient #2 inverted?\n                             +-- alternating columns inverted?\n */\nstatic struct background_pattern {\n    ush type;\n    int rgb1_max, rgb1_min;     /* or bg_freq, bg_gray */\n    int rgb2_max, rgb2_min;     /* or bg_bsat, bg_brot (both scaled by 10)*/\n} bg[] = {\n    {0,     1,1, 16,16},        /* checkered:  white vs. light gray (basic) */\n    {0+8,   2,0,  1,15},        /* checkered:  tan/black vs. white/ice blue */\n    {0+24,  2,0,  1,0},         /* checkered:  tan/black vs. white/black */\n    {0+8,   4,5,  0,2},         /* checkered:  gold/yellow vs. black/tan */\n    {0+8,   4,5,  0,6},         /* checkered:  gold/yellow vs. black/blue */\n    {0,     7,0,  8,9},         /* checkered:  deep blue/black vs. magenta */\n    {0+8,  13,0,  5,14},        /* checkered:  orange/black vs. yellow */\n    {0+8,  12,0, 10,11},        /* checkered:  orange/black vs. red */\n    {1,     7,0,  8,0},         /* diamonds:  deep blue/black vs. magenta */\n    {1,    12,0, 11,0},         /* diamonds:  orange vs. dark red */\n    {1,    10,0,  7,0},         /* diamonds:  red vs. medium blue */\n    {1,     4,0,  5,0},         /* diamonds:  gold vs. yellow */\n    {1,     3,0,  0,0},         /* diamonds:  medium green vs. black */\n    {2,    16, 100,  20,   0},  /* radial:  ~hard radial color-beams */\n    {2,    18, 100,  10,   2},  /* radial:  soft, curved radial color-beams */\n    {2,    16, 256, 100, 250},  /* radial:  very tight spiral */\n    {2, 10000, 256,  11,   0}   /* radial:  dipole-moire' (almost fractal) */\n};\nstatic int num_bgpat = sizeof(bg) / sizeof(struct background_pattern);\n\n\n/* X-specific variables */\nstatic char *displayname;\nstatic XImage *ximage;\nstatic Display *display;\nstatic int depth;\nstatic Visual *visual;\nstatic XVisualInfo *visual_list;\nstatic int RShift, GShift, BShift;\nstatic ulg RMask, GMask, BMask;\nstatic Window window;\nstatic GC gc;\nstatic Colormap colormap;\n\nstatic int have_nondefault_visual = FALSE;\nstatic int have_colormap = FALSE;\nstatic int have_window = FALSE;\nstatic int have_gc = FALSE;\n\n\n\n\nint main(int argc, char **argv)\n{\n#ifdef sgi\n    char tmpline[80];\n#endif\n    char *p, *bgstr = NULL;\n    int rc, alen, flen;\n    int error = 0;\n    int timing = FALSE;\n    int have_bg = FALSE;\n#ifdef FEATURE_LOOP\n    int loop = FALSE;\n    long loop_interval = -1;            /* seconds (100,000 max) */\n#endif\n    double LUT_exponent;                /* just the lookup table */\n    double CRT_exponent = 2.2;          /* just the monitor */\n    double default_display_exponent;    /* whole display system */\n    XEvent e;\n    KeySym k;\n\n\n    /* First initialize a few things, just to be sure--memset takes care of\n     * default background color (black), booleans (FALSE), pointers (NULL),\n     * etc. */\n\n    displayname = (char *)NULL;\n    filename = (char *)NULL;\n    memset(&rpng2_info, 0, sizeof(mainprog_info));\n\n\n    /* Set the default value for our display-system exponent, i.e., the\n     * product of the CRT exponent and the exponent corresponding to\n     * the frame-buffer's lookup table (LUT), if any.  This is not an\n     * exhaustive list of LUT values (e.g., OpenStep has a lot of weird\n     * ones), but it should cover 99% of the current possibilities. */\n\n#if defined(NeXT)\n    /* third-party utilities can modify the default LUT exponent */\n    LUT_exponent = 1.0 / 2.2;\n    /*\n    if (some_next_function_that_returns_gamma(&next_gamma))\n        LUT_exponent = 1.0 / next_gamma;\n     */\n#elif defined(sgi)\n    LUT_exponent = 1.0 / 1.7;\n    /* there doesn't seem to be any documented function to\n     * get the \"gamma\" value, so we do it the hard way */\n    infile = fopen(\"/etc/config/system.glGammaVal\", \"r\");\n    if (infile) {\n        double sgi_gamma;\n\n        fgets(tmpline, 80, infile);\n        fclose(infile);\n        sgi_gamma = atof(tmpline);\n        if (sgi_gamma > 0.0)\n            LUT_exponent = 1.0 / sgi_gamma;\n    }\n#elif defined(Macintosh)\n    LUT_exponent = 1.8 / 2.61;\n    /*\n    if (some_mac_function_that_returns_gamma(&mac_gamma))\n        LUT_exponent = mac_gamma / 2.61;\n     */\n#else\n    LUT_exponent = 1.0;   /* assume no LUT:  most PCs */\n#endif\n\n    /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */\n    default_display_exponent = LUT_exponent * CRT_exponent;\n\n\n    /* If the user has set the SCREEN_GAMMA environment variable as suggested\n     * (somewhat imprecisely) in the libpng documentation, use that; otherwise\n     * use the default value we just calculated.  Either way, the user may\n     * override this via a command-line option. */\n\n    if ((p = getenv(\"SCREEN_GAMMA\")) != NULL)\n        rpng2_info.display_exponent = atof(p);\n    else\n        rpng2_info.display_exponent = default_display_exponent;\n\n\n    /* Now parse the command line for options and the PNG filename. */\n\n    while (*++argv && !error) {\n        if (!strncmp(*argv, \"-display\", 2)) {\n            if (!*++argv)\n                ++error;\n            else\n                displayname = *argv;\n        } else if (!strncmp(*argv, \"-gamma\", 2)) {\n            if (!*++argv)\n                ++error;\n            else {\n                rpng2_info.display_exponent = atof(*argv);\n                if (rpng2_info.display_exponent <= 0.0)\n                    ++error;\n            }\n        } else if (!strncmp(*argv, \"-bgcolor\", 4)) {\n            if (!*++argv)\n                ++error;\n            else {\n                bgstr = *argv;\n                if (strlen(bgstr) != 7 || bgstr[0] != '#')\n                    ++error;\n                else {\n                    have_bg = TRUE;\n                    bg_image = FALSE;\n                }\n            }\n        } else if (!strncmp(*argv, \"-bgpat\", 4)) {\n            if (!*++argv)\n                ++error;\n            else {\n                pat = atoi(*argv);\n                if (pat >= 0 && pat < num_bgpat) {\n                    bg_image = TRUE;\n                    have_bg = FALSE;\n                } else\n                    ++error;\n            }\n        } else if (!strncmp(*argv, \"-usleep\", 2)) {\n            if (!*++argv)\n                ++error;\n            else {\n                usleep_duration = (ulg)atol(*argv);\n                demo_timing = TRUE;\n            }\n        } else if (!strncmp(*argv, \"-pause\", 2)) {\n            pause_after_pass = TRUE;\n        } else if (!strncmp(*argv, \"-timing\", 2)) {\n            timing = TRUE;\n#ifdef FEATURE_LOOP\n        } else if (!strncmp(*argv, \"-loop\", 2)) {\n            loop = TRUE;\n            if (!argv[1] || !is_number(argv[1]))\n                loop_interval = 2;\n            else {\n                ++argv;\n                loop_interval = atol(*argv);\n                if (loop_interval < 0)\n                    loop_interval = 2;\n                else if (loop_interval > 100000)   /* bit more than one day */\n                    loop_interval = 100000;\n            }\n#endif\n        } else {\n            if (**argv != '-') {\n                filename = *argv;\n                if (argv[1])   /* shouldn't be any more args after filename */\n                    ++error;\n            } else\n                ++error;   /* not expecting any other options */\n        }\n    }\n\n    if (!filename)\n        ++error;\n\n\n    /* print usage screen if any errors up to this point */\n\n    if (error) {\n        fprintf(stderr, \"\\n%s %s:  %s\\n\\n\", PROGNAME, VERSION, appname);\n        readpng2_version_info();\n        fprintf(stderr, \"\\n\"\n          \"Usage:   \");\n        fprintf(stderr,\n          \"%s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\\n\"\n          \"        %*s [-usleep dur | -timing] [-pause]\\n\",\n          PROGNAME, (int)strlen(PROGNAME), \" \");\n        fprintf(stderr,\n#ifdef FEATURE_LOOP\n          \"        [-loop [sec]]\"\n#endif\n          \" file.png\\n\\n\");\n        fprintf(stderr,\n          \"    xdpy\\tname of the target X display (e.g., ``hostname:0'')\\n\"\n          \"    exp \\ttransfer-function exponent (``gamma'') of the display\\n\"\n          \"\\t\\t  system in floating-point format (e.g., ``%.1f''); equal\\n\"\n          \"\\t\\t  to the product of the lookup-table exponent (varies)\\n\",\n          default_display_exponent);\n        fprintf(stderr,\n          \"\\t\\t  and the CRT exponent (usually 2.2); must be positive\\n\"\n          \"    bg  \\tdesired background color in 7-character hex RGB format\\n\"\n          \"\\t\\t  (e.g., ``#ff7700'' for orange:  same as HTML colors);\\n\"\n          \"\\t\\t  used with transparent images; overrides -bgpat\\n\"\n          \"    pat \\tdesired background pattern number (0-%d); used with\\n\"\n          \"\\t\\t  transparent images; overrides -bgcolor\\n\",\n          num_bgpat-1);\n#ifdef FEATURE_LOOP\n        fprintf(stderr,\n          \"    -loop\\tloops through background images after initial display\\n\"\n          \"\\t\\t  is complete (depends on -bgpat)\\n\"\n          \"    sec \\tseconds to display each background image (default = 2)\\n\");\n#endif\n        fprintf(stderr,\n          \"    dur \\tduration in microseconds to wait after displaying each\\n\"\n          \"\\t\\t  row (for demo purposes)\\n\"\n          \"    -timing\\tenables delay for every block read, to simulate modem\\n\"\n          \"\\t\\t  download of image (~36 Kbps)\\n\"\n          \"    -pause\\tpauses after displaying each pass until mouse clicked\\n\"\n          \"\\nPress Q, Esc or mouse button 1 (within image window, after image\\n\"\n          \"is displayed) to quit.\\n\");\n        exit(1);\n    }\n\n    if (!(infile = fopen(filename, \"rb\"))) {\n        fprintf(stderr, PROGNAME \":  can't open PNG file [%s]\\n\", filename);\n        ++error;\n    } else {\n        incount = fread(inbuf, 1, INBUFSIZE, infile);\n        if (incount < 8 || !readpng2_check_sig(inbuf, 8)) {\n            fprintf(stderr, PROGNAME\n              \":  [%s] is not a PNG file: incorrect signature\\n\",\n              filename);\n            ++error;\n        } else if ((rc = readpng2_init(&rpng2_info)) != 0) {\n            switch (rc) {\n                case 2:\n                    fprintf(stderr, PROGNAME\n                      \":  [%s] has bad IHDR (libpng longjmp)\\n\", filename);\n                    break;\n                case 4:\n                    fprintf(stderr, PROGNAME \":  insufficient memory\\n\");\n                    break;\n                default:\n                    fprintf(stderr, PROGNAME\n                      \":  unknown readpng2_init() error\\n\");\n                    break;\n            }\n            ++error;\n        } else {\n            Trace((stderr, \"about to call XOpenDisplay()\\n\"))\n            display = XOpenDisplay(displayname);\n            if (!display) {\n                readpng2_cleanup(&rpng2_info);\n                fprintf(stderr, PROGNAME \":  can't open X display [%s]\\n\",\n                  displayname? displayname : \"default\");\n                ++error;\n            }\n        }\n        if (error)\n            fclose(infile);\n    }\n\n\n    if (error) {\n        fprintf(stderr, PROGNAME \":  aborting.\\n\");\n        exit(2);\n    }\n\n\n    /* set the title-bar string, but make sure buffer doesn't overflow */\n\n    alen = strlen(appname);\n    flen = strlen(filename);\n    if (alen + flen + 3 > 1023)\n        sprintf(titlebar, \"%s:  ...%s\", appname, filename+(alen+flen+6-1023));\n    else\n        sprintf(titlebar, \"%s:  %s\", appname, filename);\n\n\n    /* set some final rpng2_info variables before entering main data loop */\n\n    if (have_bg) {\n        unsigned r, g, b;   /* this approach quiets compiler warnings */\n\n        sscanf(bgstr+1, \"%2x%2x%2x\", &r, &g, &b);\n        rpng2_info.bg_red   = (uch)r;\n        rpng2_info.bg_green = (uch)g;\n        rpng2_info.bg_blue  = (uch)b;\n    } else\n        rpng2_info.need_bgcolor = TRUE;\n\n    rpng2_info.state = kPreInit;\n    rpng2_info.mainprog_init = rpng2_x_init;\n    rpng2_info.mainprog_display_row = rpng2_x_display_row;\n    rpng2_info.mainprog_finish_display = rpng2_x_finish_display;\n\n\n    /* OK, this is the fun part:  call readpng2_decode_data() at the start of\n     * the loop to deal with our first buffer of data (read in above to verify\n     * that the file is a PNG image), then loop through the file and continue\n     * calling the same routine to handle each chunk of data.  It in turn\n     * passes the data to libpng, which will invoke one or more of our call-\n     * backs as decoded data become available.  We optionally call sleep() for\n     * one second per iteration to simulate downloading the image via an analog\n     * modem. */\n\n    for (;;) {\n        Trace((stderr, \"about to call readpng2_decode_data()\\n\"))\n        if (readpng2_decode_data(&rpng2_info, inbuf, incount))\n            ++error;\n        Trace((stderr, \"done with readpng2_decode_data()\\n\"))\n\n        if (error || incount != INBUFSIZE || rpng2_info.state == kDone) {\n            if (rpng2_info.state == kDone) {\n                Trace((stderr, \"done decoding PNG image\\n\"))\n            } else if (ferror(infile)) {\n                fprintf(stderr, PROGNAME\n                  \":  error while reading PNG image file\\n\");\n                exit(3);\n            } else if (feof(infile)) {\n                fprintf(stderr, PROGNAME \":  end of file reached \"\n                  \"(unexpectedly) while reading PNG image file\\n\");\n                exit(3);\n            } else /* if (error) */ {\n                /* will print error message below */\n            }\n            break;\n        }\n\n        if (timing)\n            sleep(1);\n\n        incount = fread(inbuf, 1, INBUFSIZE, infile);\n    }\n\n\n    /* clean up PNG stuff and report any decoding errors */\n\n    fclose(infile);\n    Trace((stderr, \"about to call readpng2_cleanup()\\n\"))\n    readpng2_cleanup(&rpng2_info);\n\n    if (error) {\n        fprintf(stderr, PROGNAME \":  libpng error while decoding PNG image\\n\");\n        exit(3);\n    }\n\n\n#ifdef FEATURE_LOOP\n\n    if (loop && bg_image) {\n        Trace((stderr, \"entering -loop loop (FEATURE_LOOP)\\n\"))\n        for (;;) {\n            int i, use_sleep;\n            struct timeval now, then;\n\n            /* get current time and add loop_interval to get target time */\n            if (gettimeofday(&then, NULL) == 0) {\n                then.tv_sec += loop_interval;\n                use_sleep = FALSE;\n            } else\n                use_sleep = TRUE;\n\n            /* do quick check for a quit event but don't wait for it */\n            /* GRR BUG:  should also check for Expose events and redraw... */\n            if (XCheckMaskEvent(display, KeyPressMask | ButtonPressMask, &e))\n                if (QUIT(e,k))\n                    break;\n\n            /* generate next background image */\n            if (++pat >= num_bgpat)\n                pat = 0;\n            rpng2_x_reload_bg_image();\n\n            /* wait for timeout, using whatever means are available */\n            if (use_sleep || gettimeofday(&now, NULL) != 0) {\n                for (i = loop_interval;  i > 0;  --i) {\n                    sleep(1);\n                    /* GRR BUG:  also need to check for Expose (and redraw!) */\n                    if (XCheckMaskEvent(display, KeyPressMask | ButtonPressMask,\n                        &e) && QUIT(e,k))\n                        break;\n                }\n            } else {\n                /* Y2038 BUG! */\n                if (now.tv_sec < then.tv_sec ||\n                    (now.tv_sec == then.tv_sec && now.tv_usec < then.tv_usec))\n                {\n                    int quit = FALSE;\n                    long seconds_to_go = then.tv_sec - now.tv_sec;\n                    long usleep_usec;\n\n                    /* basically chew up most of remaining loop-interval with\n                     *  calls to sleep(1) interleaved with checks for quit\n                     *  events, but also recalc time-to-go periodically; when\n                     *  done, clean up any remaining time with usleep() call\n                     *  (could also use SIGALRM, but signals are a pain...) */\n                    while (seconds_to_go-- > 1) {\n                        int seconds_done = 0;\n\n                        for (i = seconds_to_go;  i > 0 && !quit;  --i) {\n                            sleep(1);\n                            /* GRR BUG:  need to check for Expose and redraw */\n                            if (XCheckMaskEvent(display, KeyPressMask |\n                                ButtonPressMask, &e) && QUIT(e,k))\n                                quit = TRUE;\n                            if (++seconds_done > 1000)\n                                break;   /* time to redo seconds_to_go meas. */\n                        }\n                        if (quit)\n                            break;\n\n                        /* OK, more than 1000 seconds since last check:\n                         *  correct the time-to-go measurement for drift */\n                        if (gettimeofday(&now, NULL) == 0) {\n                            if (now.tv_sec >= then.tv_sec)\n                                break;\n                            seconds_to_go = then.tv_sec - now.tv_sec;\n                        } else\n                            ++seconds_to_go;  /* restore what we subtracted */\n                    }\n                    if (quit)\n                        break;   /* breaks outer do-loop, skips redisplay */\n\n                    /* since difference between \"now\" and \"then\" is already\n                     *  eaten up to within a couple of seconds, don't need to\n                     *  worry about overflow--but might have overshot (neg.) */\n                    if (gettimeofday(&now, NULL) == 0) {\n                        usleep_usec = 1000000L*(then.tv_sec - now.tv_sec) +\n                          then.tv_usec - now.tv_usec;\n                        if (usleep_usec > 0)\n                            usleep((ulg)usleep_usec);\n                    }\n                }\n            }\n\n            /* composite image against new background and display (note that\n             *  we do not take into account the time spent doing this...) */\n            rpng2_x_redisplay_image (0, 0, rpng2_info.width, rpng2_info.height);\n        }\n\n    } else /* FALL THROUGH and do the normal thing */\n\n#endif /* FEATURE_LOOP */\n\n    /* wait for the user to tell us when to quit */\n\n    if (rpng2_info.state >= kWindowInit) {\n        Trace((stderr, \"entering final wait-for-quit-event loop\\n\"))\n        do {\n            XNextEvent(display, &e);\n            if (e.type == Expose) {\n                XExposeEvent *ex = (XExposeEvent *)&e;\n                rpng2_x_redisplay_image (ex->x, ex->y, ex->width, ex->height);\n            }\n        } while (!QUIT(e,k));\n    } else {\n        fprintf(stderr, PROGNAME \":  init callback never called:  probable \"\n          \"libpng error while decoding PNG metadata\\n\");\n        exit(4);\n    }\n\n\n    /* we're done:  clean up all image and X resources and go away */\n\n    Trace((stderr, \"about to call rpng2_x_cleanup()\\n\"))\n    rpng2_x_cleanup();\n\n    (void)argc; /* Unused */\n\n    return 0;\n}\n\n\n\n\n\n/* this function is called by readpng2_info_callback() in readpng2.c, which\n * in turn is called by libpng after all of the pre-IDAT chunks have been\n * read and processed--i.e., we now have enough info to finish initializing */\n\nstatic void rpng2_x_init(void)\n{\n    ulg i;\n    ulg rowbytes = rpng2_info.rowbytes;\n\n    Trace((stderr, \"beginning rpng2_x_init()\\n\"))\n    Trace((stderr, \"  rowbytes = %d\\n\", rpng2_info.rowbytes))\n    Trace((stderr, \"  width  = %ld\\n\", rpng2_info.width))\n    Trace((stderr, \"  height = %ld\\n\", rpng2_info.height))\n\n    rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height);\n    if (!rpng2_info.image_data) {\n        readpng2_cleanup(&rpng2_info);\n        return;\n    }\n\n    rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *));\n    if (!rpng2_info.row_pointers) {\n        free(rpng2_info.image_data);\n        rpng2_info.image_data = NULL;\n        readpng2_cleanup(&rpng2_info);\n        return;\n    }\n\n    for (i = 0;  i < rpng2_info.height;  ++i)\n        rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes;\n\n\n    /* do the basic X initialization stuff, make the window, and fill it with\n     * the user-specified, file-specified or default background color or\n     * pattern */\n\n    if (rpng2_x_create_window()) {\n\n        /* GRR TEMPORARY HACK:  this is fundamentally no different from cases\n         * above; libpng should call our error handler to longjmp() back to us\n         * when png_ptr goes away.  If we/it segfault instead, seems like a\n         * libpng bug... */\n\n        /* we're here via libpng callback, so if window fails, clean and bail */\n        readpng2_cleanup(&rpng2_info);\n        rpng2_x_cleanup();\n        exit(2);\n    }\n\n    rpng2_info.state = kWindowInit;\n}\n\n\n\n\n\nstatic int rpng2_x_create_window(void)\n{\n    ulg bg_red   = rpng2_info.bg_red;\n    ulg bg_green = rpng2_info.bg_green;\n    ulg bg_blue  = rpng2_info.bg_blue;\n    ulg bg_pixel = 0L;\n    ulg attrmask;\n    int need_colormap = FALSE;\n    int screen, pad;\n    uch *xdata;\n    Window root;\n    XEvent e;\n    XGCValues gcvalues;\n    XSetWindowAttributes attr;\n    XTextProperty windowName, *pWindowName = &windowName;\n    XTextProperty iconName, *pIconName = &iconName;\n    XVisualInfo visual_info;\n    XSizeHints *size_hints;\n    XWMHints *wm_hints;\n    XClassHint *class_hints;\n\n\n    Trace((stderr, \"beginning rpng2_x_create_window()\\n\"))\n\n    screen = DefaultScreen(display);\n    depth = DisplayPlanes(display, screen);\n    root = RootWindow(display, screen);\n\n#ifdef DEBUG\n    XSynchronize(display, True);\n#endif\n\n    if (depth != 16 && depth != 24 && depth != 32) {\n        int visuals_matched = 0;\n\n        Trace((stderr, \"default depth is %d:  checking other visuals\\n\",\n          depth))\n\n        /* 24-bit first */\n        visual_info.screen = screen;\n        visual_info.depth = 24;\n        visual_list = XGetVisualInfo(display,\n          VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched);\n        if (visuals_matched == 0) {\n/* GRR:  add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */\n            fprintf(stderr, \"default screen depth %d not supported, and no\"\n              \" 24-bit visuals found\\n\", depth);\n            return 2;\n        }\n        Trace((stderr, \"XGetVisualInfo() returned %d 24-bit visuals\\n\",\n          visuals_matched))\n        visual = visual_list[0].visual;\n        depth = visual_list[0].depth;\n/*\n        colormap_size = visual_list[0].colormap_size;\n        visual_class = visual->class;\n        visualID = XVisualIDFromVisual(visual);\n */\n        have_nondefault_visual = TRUE;\n        need_colormap = TRUE;\n    } else {\n        XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info);\n        visual = visual_info.visual;\n    }\n\n    RMask = visual->red_mask;\n    GMask = visual->green_mask;\n    BMask = visual->blue_mask;\n\n/* GRR:  add/check 8-bit support */\n    if (depth == 8 || need_colormap) {\n        colormap = XCreateColormap(display, root, visual, AllocNone);\n        if (!colormap) {\n            fprintf(stderr, \"XCreateColormap() failed\\n\");\n            return 2;\n        }\n        have_colormap = TRUE;\n        if (depth == 8)\n            bg_image = FALSE;   /* gradient just wastes palette entries */\n    }\n    if (depth == 15 || depth == 16) {\n        RShift = 15 - rpng2_x_msb(RMask);    /* these are right-shifts */\n        GShift = 15 - rpng2_x_msb(GMask);\n        BShift = 15 - rpng2_x_msb(BMask);\n    } else if (depth > 16) {\n        RShift = rpng2_x_msb(RMask) - 7;     /* these are left-shifts */\n        GShift = rpng2_x_msb(GMask) - 7;\n        BShift = rpng2_x_msb(BMask) - 7;\n    }\n    if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) {\n        fprintf(stderr, \"rpng2 internal logic error:  negative X shift(s)!\\n\");\n        return 2;\n    }\n\n/*---------------------------------------------------------------------------\n    Finally, create the window.\n  ---------------------------------------------------------------------------*/\n\n    attr.backing_store = Always;\n    attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;\n    attrmask = CWBackingStore | CWEventMask;\n    if (have_nondefault_visual) {\n        attr.colormap = colormap;\n        attr.background_pixel = 0;\n        attr.border_pixel = 1;\n        attrmask |= CWColormap | CWBackPixel | CWBorderPixel;\n    }\n\n    window = XCreateWindow(display, root, 0, 0, rpng2_info.width,\n      rpng2_info.height, 0, depth, InputOutput, visual, attrmask, &attr);\n\n    if (window == None) {\n        fprintf(stderr, \"XCreateWindow() failed\\n\");\n        return 2;\n    } else\n        have_window = TRUE;\n\n    if (depth == 8)\n        XSetWindowColormap(display, window, colormap);\n\n    if (!XStringListToTextProperty(&window_name, 1, pWindowName))\n        pWindowName = NULL;\n    if (!XStringListToTextProperty(&icon_name, 1, pIconName))\n        pIconName = NULL;\n\n    /* OK if either hints allocation fails; XSetWMProperties() allows NULLs */\n\n    if ((size_hints = XAllocSizeHints()) != NULL) {\n        /* window will not be resizable */\n        size_hints->flags = PMinSize | PMaxSize;\n        size_hints->min_width = size_hints->max_width = (int)rpng2_info.width;\n        size_hints->min_height = size_hints->max_height =\n          (int)rpng2_info.height;\n    }\n\n    if ((wm_hints = XAllocWMHints()) != NULL) {\n        wm_hints->initial_state = NormalState;\n        wm_hints->input = True;\n     /* wm_hints->icon_pixmap = icon_pixmap; */\n        wm_hints->flags = StateHint | InputHint  /* | IconPixmapHint */ ;\n    }\n\n    if ((class_hints = XAllocClassHint()) != NULL) {\n        class_hints->res_name = res_name;\n        class_hints->res_class = res_class;\n    }\n\n    XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0,\n      size_hints, wm_hints, class_hints);\n\n    /* various properties and hints no longer needed; free memory */\n    if (pWindowName)\n       XFree(pWindowName->value);\n    if (pIconName)\n       XFree(pIconName->value);\n    if (size_hints)\n        XFree(size_hints);\n    if (wm_hints)\n       XFree(wm_hints);\n    if (class_hints)\n       XFree(class_hints);\n\n    XMapWindow(display, window);\n\n    gc = XCreateGC(display, window, 0, &gcvalues);\n    have_gc = TRUE;\n\n/*---------------------------------------------------------------------------\n    Allocate memory for the X- and display-specific version of the image.\n  ---------------------------------------------------------------------------*/\n\n    if (depth == 24 || depth == 32) {\n        xdata = (uch *)malloc(4*rpng2_info.width*rpng2_info.height);\n        pad = 32;\n    } else if (depth == 16) {\n        xdata = (uch *)malloc(2*rpng2_info.width*rpng2_info.height);\n        pad = 16;\n    } else /* depth == 8 */ {\n        xdata = (uch *)malloc(rpng2_info.width*rpng2_info.height);\n        pad = 8;\n    }\n\n    if (!xdata) {\n        fprintf(stderr, PROGNAME \":  unable to allocate image memory\\n\");\n        return 4;\n    }\n\n    ximage = XCreateImage(display, visual, depth, ZPixmap, 0,\n      (char *)xdata, rpng2_info.width, rpng2_info.height, pad, 0);\n\n    if (!ximage) {\n        fprintf(stderr, PROGNAME \":  XCreateImage() failed\\n\");\n        free(xdata);\n        return 3;\n    }\n\n    /* to avoid testing the byte order every pixel (or doubling the size of\n     * the drawing routine with a giant if-test), we arbitrarily set the byte\n     * order to MSBFirst and let Xlib worry about inverting things on little-\n     * endian machines (e.g., Linux/x86, old VAXen, etc.)--this is not the\n     * most efficient approach (the giant if-test would be better), but in\n     * the interest of clarity, we'll take the easy way out... */\n\n    ximage->byte_order = MSBFirst;\n\n/*---------------------------------------------------------------------------\n    Fill window with the specified background color (default is black) or\n    faked \"background image\" (but latter is disabled if 8-bit; gradients\n    just waste palette entries).\n  ---------------------------------------------------------------------------*/\n\n    if (bg_image)\n        rpng2_x_load_bg_image();    /* resets bg_image if fails */\n\n    if (!bg_image) {\n        if (depth == 24 || depth == 32) {\n            bg_pixel = (bg_red   << RShift) |\n                       (bg_green << GShift) |\n                       (bg_blue  << BShift);\n        } else if (depth == 16) {\n            bg_pixel = (((bg_red   << 8) >> RShift) & RMask) |\n                       (((bg_green << 8) >> GShift) & GMask) |\n                       (((bg_blue  << 8) >> BShift) & BMask);\n        } else /* depth == 8 */ {\n\n            /* GRR:  add 8-bit support */\n\n        }\n        XSetForeground(display, gc, bg_pixel);\n        XFillRectangle(display, window, gc, 0, 0, rpng2_info.width,\n          rpng2_info.height);\n    }\n\n/*---------------------------------------------------------------------------\n    Wait for first Expose event to do any drawing, then flush and return.\n  ---------------------------------------------------------------------------*/\n\n    do\n        XNextEvent(display, &e);\n    while (e.type != Expose || e.xexpose.count);\n\n    XFlush(display);\n\n    return 0;\n\n} /* end function rpng2_x_create_window() */\n\n\n\n\n\nstatic int rpng2_x_load_bg_image(void)\n{\n    uch *src;\n    char *dest;\n    uch r1, r2, g1, g2, b1, b2;\n    uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv;\n    int k, hmax, max;\n    int xidx, yidx, yidx_max;\n    int even_odd_vert, even_odd_horiz, even_odd;\n    int invert_gradient2 = (bg[pat].type & 0x08);\n    int invert_column;\n    int ximage_rowbytes = ximage->bytes_per_line;\n    ulg i, row;\n    ulg pixel;\n\n/*---------------------------------------------------------------------------\n    Allocate buffer for fake background image to be used with transparent\n    images; if this fails, revert to plain background color.\n  ---------------------------------------------------------------------------*/\n\n    bg_rowbytes = 3 * rpng2_info.width;\n    bg_data = (uch *)malloc(bg_rowbytes * rpng2_info.height);\n    if (!bg_data) {\n        fprintf(stderr, PROGNAME\n          \":  unable to allocate memory for background image\\n\");\n        bg_image = 0;\n        return 1;\n    }\n\n    bgscale = (pat == 0)? 8 : bgscale_default;\n    yidx_max = bgscale - 1;\n\n/*---------------------------------------------------------------------------\n    Vertical gradients (ramps) in NxN squares, alternating direction and\n    colors (N == bgscale).\n  ---------------------------------------------------------------------------*/\n\n    if ((bg[pat].type & 0x07) == 0) {\n        uch r1_min  = rgb[bg[pat].rgb1_min].r;\n        uch g1_min  = rgb[bg[pat].rgb1_min].g;\n        uch b1_min  = rgb[bg[pat].rgb1_min].b;\n        uch r2_min  = rgb[bg[pat].rgb2_min].r;\n        uch g2_min  = rgb[bg[pat].rgb2_min].g;\n        uch b2_min  = rgb[bg[pat].rgb2_min].b;\n        int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min;\n        int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min;\n        int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min;\n        int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min;\n        int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min;\n        int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min;\n\n        for (row = 0;  row < rpng2_info.height;  ++row) {\n            yidx = (int)(row % bgscale);\n            even_odd_vert = (int)((row / bgscale) & 1);\n\n            r1 = r1_min + (r1_diff * yidx) / yidx_max;\n            g1 = g1_min + (g1_diff * yidx) / yidx_max;\n            b1 = b1_min + (b1_diff * yidx) / yidx_max;\n            r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max;\n            g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max;\n            b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max;\n\n            r2 = r2_min + (r2_diff * yidx) / yidx_max;\n            g2 = g2_min + (g2_diff * yidx) / yidx_max;\n            b2 = b2_min + (b2_diff * yidx) / yidx_max;\n            r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max;\n            g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max;\n            b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max;\n\n            dest = (char *)bg_data + row*bg_rowbytes;\n            for (i = 0;  i < rpng2_info.width;  ++i) {\n                even_odd_horiz = (int)((i / bgscale) & 1);\n                even_odd = even_odd_vert ^ even_odd_horiz;\n                invert_column =\n                  (even_odd_horiz && (bg[pat].type & 0x10));\n                if (even_odd == 0) {        /* gradient #1 */\n                    if (invert_column) {\n                        *dest++ = r1_inv;\n                        *dest++ = g1_inv;\n                        *dest++ = b1_inv;\n                    } else {\n                        *dest++ = r1;\n                        *dest++ = g1;\n                        *dest++ = b1;\n                    }\n                } else {                    /* gradient #2 */\n                    if ((invert_column && invert_gradient2) ||\n                        (!invert_column && !invert_gradient2))\n                    {\n                        *dest++ = r2;       /* not inverted or */\n                        *dest++ = g2;       /*  doubly inverted */\n                        *dest++ = b2;\n                    } else {\n                        *dest++ = r2_inv;\n                        *dest++ = g2_inv;   /* singly inverted */\n                        *dest++ = b2_inv;\n                    }\n                }\n            }\n        }\n\n/*---------------------------------------------------------------------------\n    Soft gradient-diamonds with scale = bgscale.  Code contributed by Adam\n    M. Costello.\n  ---------------------------------------------------------------------------*/\n\n    } else if ((bg[pat].type & 0x07) == 1) {\n\n        hmax = (bgscale-1)/2;   /* half the max weight of a color */\n        max = 2*hmax;           /* the max weight of a color */\n\n        r1 = rgb[bg[pat].rgb1_max].r;\n        g1 = rgb[bg[pat].rgb1_max].g;\n        b1 = rgb[bg[pat].rgb1_max].b;\n        r2 = rgb[bg[pat].rgb2_max].r;\n        g2 = rgb[bg[pat].rgb2_max].g;\n        b2 = rgb[bg[pat].rgb2_max].b;\n\n        for (row = 0;  row < rpng2_info.height;  ++row) {\n            yidx = (int)(row % bgscale);\n            if (yidx > hmax)\n                yidx = bgscale-1 - yidx;\n            dest = (char *)bg_data + row*bg_rowbytes;\n            for (i = 0;  i < rpng2_info.width;  ++i) {\n                xidx = (int)(i % bgscale);\n                if (xidx > hmax)\n                    xidx = bgscale-1 - xidx;\n                k = xidx + yidx;\n                *dest++ = (k*r1 + (max-k)*r2) / max;\n                *dest++ = (k*g1 + (max-k)*g2) / max;\n                *dest++ = (k*b1 + (max-k)*b2) / max;\n            }\n        }\n\n/*---------------------------------------------------------------------------\n    Radial \"starburst\" with azimuthal sinusoids; [eventually number of sinu-\n    soids will equal bgscale?].  This one is slow but very cool.  Code con-\n    tributed by Pieter S. van der Meulen (originally in Smalltalk).\n  ---------------------------------------------------------------------------*/\n\n    } else if ((bg[pat].type & 0x07) == 2) {\n        uch ch;\n        int ii, x, y, hw, hh, grayspot;\n        double freq, rotate, saturate, gray, intensity;\n        double angle=0.0, aoffset=0.0, maxDist, dist;\n        double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t;\n\n        fprintf(stderr, \"%s:  computing radial background...\",\n          PROGNAME);\n        fflush(stderr);\n\n        hh = (int)(rpng2_info.height / 2);\n        hw = (int)(rpng2_info.width / 2);\n\n        /* variables for radial waves:\n         *   aoffset:  number of degrees to rotate hue [CURRENTLY NOT USED]\n         *   freq:  number of color beams originating from the center\n         *   grayspot:  size of the graying center area (anti-alias)\n         *   rotate:  rotation of the beams as a function of radius\n         *   saturate:  saturation of beams' shape azimuthally\n         */\n        angle = CLIP(angle, 0.0, 360.0);\n        grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw));\n        freq = MAX((double)bg[pat].bg_freq, 0.0);\n        saturate = (double)bg[pat].bg_bsat * 0.1;\n        rotate = (double)bg[pat].bg_brot * 0.1;\n        gray = 0.0;\n        intensity = 0.0;\n        maxDist = (double)((hw*hw) + (hh*hh));\n\n        for (row = 0;  row < rpng2_info.height;  ++row) {\n            y = (int)(row - hh);\n            dest = (char *)bg_data + row*bg_rowbytes;\n            for (i = 0;  i < rpng2_info.width;  ++i) {\n                x = (int)(i - hw);\n                angle = (x == 0)? PI_2 : atan((double)y / (double)x);\n                gray = (double)MAX(ABS(y), ABS(x)) / grayspot;\n                gray = MIN(1.0, gray);\n                dist = (double)((x*x) + (y*y)) / maxDist;\n                intensity = cos((angle+(rotate*dist*PI)) * freq) *\n                  gray * saturate;\n                intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5;\n                hue = (angle + PI) * INV_PI_360 + aoffset;\n                s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh));\n                s = MIN(MAX(s,0.0), 1.0);\n                v = MIN(MAX(intensity,0.0), 1.0);\n\n                if (s == 0.0) {\n                    ch = (uch)(v * 255.0);\n                    *dest++ = ch;\n                    *dest++ = ch;\n                    *dest++ = ch;\n                } else {\n                    if ((hue < 0.0) || (hue >= 360.0))\n                        hue -= (((int)(hue / 360.0)) * 360.0);\n                    hue /= 60.0;\n                    ii = (int)hue;\n                    f = hue - (double)ii;\n                    p = (1.0 - s) * v;\n                    q = (1.0 - (s * f)) * v;\n                    t = (1.0 - (s * (1.0 - f))) * v;\n                    if      (ii == 0) { red = v; green = t; blue = p; }\n                    else if (ii == 1) { red = q; green = v; blue = p; }\n                    else if (ii == 2) { red = p; green = v; blue = t; }\n                    else if (ii == 3) { red = p; green = q; blue = v; }\n                    else if (ii == 4) { red = t; green = p; blue = v; }\n                    else if (ii == 5) { red = v; green = p; blue = q; }\n                    *dest++ = (uch)(red * 255.0);\n                    *dest++ = (uch)(green * 255.0);\n                    *dest++ = (uch)(blue * 255.0);\n                }\n            }\n        }\n        fprintf(stderr, \"done.\\n\");\n        fflush(stderr);\n    }\n\n/*---------------------------------------------------------------------------\n    Blast background image to display buffer before beginning PNG decode.\n  ---------------------------------------------------------------------------*/\n\n    if (depth == 24 || depth == 32) {\n        ulg red, green, blue;\n        int bpp = ximage->bits_per_pixel;\n\n        for (row = 0;  row < rpng2_info.height;  ++row) {\n            src = bg_data + row*bg_rowbytes;\n            dest = ximage->data + row*ximage_rowbytes;\n            if (bpp == 32) {    /* slightly optimized version */\n                for (i = rpng2_info.width;  i > 0;  --i) {\n                    red   = *src++;\n                    green = *src++;\n                    blue  = *src++;\n                    pixel = (red   << RShift) |\n                            (green << GShift) |\n                            (blue  << BShift);\n                    /* recall that we set ximage->byte_order = MSBFirst above */\n                    *dest++ = (char)((pixel >> 24) & 0xff);\n                    *dest++ = (char)((pixel >> 16) & 0xff);\n                    *dest++ = (char)((pixel >>  8) & 0xff);\n                    *dest++ = (char)( pixel        & 0xff);\n                }\n            } else {\n                for (i = rpng2_info.width;  i > 0;  --i) {\n                    red   = *src++;\n                    green = *src++;\n                    blue  = *src++;\n                    pixel = (red   << RShift) |\n                            (green << GShift) |\n                            (blue  << BShift);\n                    /* recall that we set ximage->byte_order = MSBFirst above */\n                    /* GRR BUG?  this assumes bpp == 24 & bits are packed low */\n                    /*           (probably need to use RShift, RMask, etc.) */\n                    *dest++ = (char)((pixel >> 16) & 0xff);\n                    *dest++ = (char)((pixel >>  8) & 0xff);\n                    *dest++ = (char)( pixel        & 0xff);\n                }\n            }\n        }\n\n    } else if (depth == 16) {\n        ush red, green, blue;\n\n        for (row = 0;  row < rpng2_info.height;  ++row) {\n            src = bg_data + row*bg_rowbytes;\n            dest = ximage->data + row*ximage_rowbytes;\n            for (i = rpng2_info.width;  i > 0;  --i) {\n                red   = ((ush)(*src) << 8);  ++src;\n                green = ((ush)(*src) << 8);  ++src;\n                blue  = ((ush)(*src) << 8);  ++src;\n                pixel = ((red   >> RShift) & RMask) |\n                        ((green >> GShift) & GMask) |\n                        ((blue  >> BShift) & BMask);\n                /* recall that we set ximage->byte_order = MSBFirst above */\n                *dest++ = (char)((pixel >>  8) & 0xff);\n                *dest++ = (char)( pixel        & 0xff);\n            }\n        }\n\n    } else /* depth == 8 */ {\n\n        /* GRR:  add 8-bit support */\n\n    }\n\n    XPutImage(display, window, gc, ximage, 0, 0, 0, 0, rpng2_info.width,\n      rpng2_info.height);\n\n    return 0;\n\n} /* end function rpng2_x_load_bg_image() */\n\n\n\n\n\nstatic void rpng2_x_display_row(ulg row)\n{\n    uch bg_red   = rpng2_info.bg_red;\n    uch bg_green = rpng2_info.bg_green;\n    uch bg_blue  = rpng2_info.bg_blue;\n    uch *src, *src2=NULL;\n    char *dest;\n    uch r, g, b, a;\n    int ximage_rowbytes = ximage->bytes_per_line;\n    ulg i, pixel;\n    static int rows=0, prevpass=(-1);\n    static ulg firstrow;\n\n/*---------------------------------------------------------------------------\n    rows and firstrow simply track how many rows (and which ones) have not\n    yet been displayed; alternatively, we could call XPutImage() for every\n    row and not bother with the records-keeping.\n  ---------------------------------------------------------------------------*/\n\n    Trace((stderr, \"beginning rpng2_x_display_row()\\n\"))\n\n    if (rpng2_info.pass != prevpass) {\n        if (pause_after_pass && rpng2_info.pass > 0) {\n            XEvent e;\n            KeySym k;\n\n            fprintf(stderr,\n              \"%s:  end of pass %d of 7; click in image window to continue\\n\",\n              PROGNAME, prevpass + 1);\n            do\n                XNextEvent(display, &e);\n            while (!QUIT(e,k));\n        }\n        fprintf(stderr, \"%s:  pass %d of 7\\r\", PROGNAME, rpng2_info.pass + 1);\n        fflush(stderr);\n        prevpass = rpng2_info.pass;\n    }\n\n    if (rows == 0)\n        firstrow = row;   /* first row that is not yet displayed */\n\n    ++rows;   /* count of rows received but not yet displayed */\n\n/*---------------------------------------------------------------------------\n    Aside from the use of the rpng2_info struct, the lack of an outer loop\n    (over rows) and moving the XPutImage() call outside the \"if (depth)\"\n    tests, this routine is identical to rpng_x_display_image() in the non-\n    progressive version of the program.\n  ---------------------------------------------------------------------------*/\n\n    if (depth == 24 || depth == 32) {\n        ulg red, green, blue;\n        int bpp = ximage->bits_per_pixel;\n\n        src = rpng2_info.image_data + row*rpng2_info.rowbytes;\n        if (bg_image)\n            src2 = bg_data + row*bg_rowbytes;\n        dest = ximage->data + row*ximage_rowbytes;\n        if (rpng2_info.channels == 3) {\n            for (i = rpng2_info.width;  i > 0;  --i) {\n                red   = *src++;\n                green = *src++;\n                blue  = *src++;\n                pixel = (red   << RShift) |\n                        (green << GShift) |\n                        (blue  << BShift);\n                /* recall that we set ximage->byte_order = MSBFirst above */\n                if (bpp == 32) {\n                    *dest++ = (char)((pixel >> 24) & 0xff);\n                    *dest++ = (char)((pixel >> 16) & 0xff);\n                    *dest++ = (char)((pixel >>  8) & 0xff);\n                    *dest++ = (char)( pixel        & 0xff);\n                } else {\n                    /* GRR BUG?  this assumes bpp == 24 & bits are packed low */\n                    /*           (probably need to use RShift, RMask, etc.) */\n                    *dest++ = (char)((pixel >> 16) & 0xff);\n                    *dest++ = (char)((pixel >>  8) & 0xff);\n                    *dest++ = (char)( pixel        & 0xff);\n                }\n            }\n        } else /* if (rpng2_info.channels == 4) */ {\n            for (i = rpng2_info.width;  i > 0;  --i) {\n                r = *src++;\n                g = *src++;\n                b = *src++;\n                a = *src++;\n                if (bg_image) {\n                    bg_red   = *src2++;\n                    bg_green = *src2++;\n                    bg_blue  = *src2++;\n                }\n                if (a == 255) {\n                    red   = r;\n                    green = g;\n                    blue  = b;\n                } else if (a == 0) {\n                    red   = bg_red;\n                    green = bg_green;\n                    blue  = bg_blue;\n                } else {\n                    /* this macro (from png.h) composites the foreground\n                     * and background values and puts the result into the\n                     * first argument */\n                    alpha_composite(red,   r, a, bg_red);\n                    alpha_composite(green, g, a, bg_green);\n                    alpha_composite(blue,  b, a, bg_blue);\n                }\n                pixel = (red   << RShift) |\n                        (green << GShift) |\n                        (blue  << BShift);\n                /* recall that we set ximage->byte_order = MSBFirst above */\n                if (bpp == 32) {\n                    *dest++ = (char)((pixel >> 24) & 0xff);\n                    *dest++ = (char)((pixel >> 16) & 0xff);\n                    *dest++ = (char)((pixel >>  8) & 0xff);\n                    *dest++ = (char)( pixel        & 0xff);\n                } else {\n                    /* GRR BUG?  this assumes bpp == 24 & bits are packed low */\n                    /*           (probably need to use RShift, RMask, etc.) */\n                    *dest++ = (char)((pixel >> 16) & 0xff);\n                    *dest++ = (char)((pixel >>  8) & 0xff);\n                    *dest++ = (char)( pixel        & 0xff);\n                }\n            }\n        }\n\n    } else if (depth == 16) {\n        ush red, green, blue;\n\n        src = rpng2_info.row_pointers[row];\n        if (bg_image)\n            src2 = bg_data + row*bg_rowbytes;\n        dest = ximage->data + row*ximage_rowbytes;\n        if (rpng2_info.channels == 3) {\n            for (i = rpng2_info.width;  i > 0;  --i) {\n                red   = ((ush)(*src) << 8);\n                ++src;\n                green = ((ush)(*src) << 8);\n                ++src;\n                blue  = ((ush)(*src) << 8);\n                ++src;\n                pixel = ((red   >> RShift) & RMask) |\n                        ((green >> GShift) & GMask) |\n                        ((blue  >> BShift) & BMask);\n                /* recall that we set ximage->byte_order = MSBFirst above */\n                *dest++ = (char)((pixel >>  8) & 0xff);\n                *dest++ = (char)( pixel        & 0xff);\n            }\n        } else /* if (rpng2_info.channels == 4) */ {\n            for (i = rpng2_info.width;  i > 0;  --i) {\n                r = *src++;\n                g = *src++;\n                b = *src++;\n                a = *src++;\n                if (bg_image) {\n                    bg_red   = *src2++;\n                    bg_green = *src2++;\n                    bg_blue  = *src2++;\n                }\n                if (a == 255) {\n                    red   = ((ush)r << 8);\n                    green = ((ush)g << 8);\n                    blue  = ((ush)b << 8);\n                } else if (a == 0) {\n                    red   = ((ush)bg_red   << 8);\n                    green = ((ush)bg_green << 8);\n                    blue  = ((ush)bg_blue  << 8);\n                } else {\n                    /* this macro (from png.h) composites the foreground\n                     * and background values and puts the result back into\n                     * the first argument (== fg byte here:  safe) */\n                    alpha_composite(r, r, a, bg_red);\n                    alpha_composite(g, g, a, bg_green);\n                    alpha_composite(b, b, a, bg_blue);\n                    red   = ((ush)r << 8);\n                    green = ((ush)g << 8);\n                    blue  = ((ush)b << 8);\n                }\n                pixel = ((red   >> RShift) & RMask) |\n                        ((green >> GShift) & GMask) |\n                        ((blue  >> BShift) & BMask);\n                /* recall that we set ximage->byte_order = MSBFirst above */\n                *dest++ = (char)((pixel >>  8) & 0xff);\n                *dest++ = (char)( pixel        & 0xff);\n            }\n        }\n\n    } else /* depth == 8 */ {\n\n        /* GRR:  add 8-bit support */\n\n    }\n\n\n/*---------------------------------------------------------------------------\n    Display after every 16 rows or when on one of last two rows.  (Region\n    may include previously displayed lines due to interlacing--i.e., not\n    contiguous.  Also, second-to-last row is final one in interlaced images\n    with odd number of rows.)  For demos, flush (and delay) after every 16th\n    row so \"sparse\" passes don't go twice as fast.\n  ---------------------------------------------------------------------------*/\n\n    if (demo_timing && (row - firstrow >= 16 || row >= rpng2_info.height-2)) {\n        XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0,\n          (int)firstrow, rpng2_info.width, row - firstrow + 1);\n        XFlush(display);\n        rows = 0;\n        usleep(usleep_duration);\n    } else\n    if (!demo_timing && ((rows & 0xf) == 0 || row >= rpng2_info.height-2)) {\n        XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0,\n          (int)firstrow, rpng2_info.width, row - firstrow + 1);\n        XFlush(display);\n        rows = 0;\n    }\n\n}\n\n\n\n\n\nstatic void rpng2_x_finish_display(void)\n{\n    Trace((stderr, \"beginning rpng2_x_finish_display()\\n\"))\n\n    /* last row has already been displayed by rpng2_x_display_row(), so we\n     * have nothing to do here except set a flag and let the user know that\n     * the image is done */\n\n    rpng2_info.state = kDone;\n    printf(\n      \"Done.  Press Q, Esc or mouse button 1 (within image window) to quit.\\n\");\n    fflush(stdout);\n}\n\n\n\n\n\nstatic void rpng2_x_redisplay_image(ulg startcol, ulg startrow,\n                                    ulg width, ulg height)\n{\n    uch bg_red   = rpng2_info.bg_red;\n    uch bg_green = rpng2_info.bg_green;\n    uch bg_blue  = rpng2_info.bg_blue;\n    uch *src, *src2=NULL;\n    char *dest;\n    uch r, g, b, a;\n    ulg i, row, lastrow = 0;\n    ulg pixel;\n    int ximage_rowbytes = ximage->bytes_per_line;\n\n\n    Trace((stderr, \"beginning display loop (image_channels == %d)\\n\",\n      rpng2_info.channels))\n    Trace((stderr, \"   (width = %ld, rowbytes = %d, ximage_rowbytes = %d)\\n\",\n      rpng2_info.width, rpng2_info.rowbytes, ximage_rowbytes))\n    Trace((stderr, \"   (bpp = %d)\\n\", ximage->bits_per_pixel))\n    Trace((stderr, \"   (byte_order = %s)\\n\", ximage->byte_order == MSBFirst?\n      \"MSBFirst\" : (ximage->byte_order == LSBFirst? \"LSBFirst\" : \"unknown\")))\n\n/*---------------------------------------------------------------------------\n    Aside from the use of the rpng2_info struct and of src2 (for background\n    image), this routine is identical to rpng_x_display_image() in the non-\n    progressive version of the program--for the simple reason that redisplay\n    of the image against a new background happens after the image is fully\n    decoded and therefore is, by definition, non-progressive.\n  ---------------------------------------------------------------------------*/\n\n    if (depth == 24 || depth == 32) {\n        ulg red, green, blue;\n        int bpp = ximage->bits_per_pixel;\n\n        for (lastrow = row = startrow;  row < startrow+height;  ++row) {\n            src = rpng2_info.image_data + row*rpng2_info.rowbytes;\n            if (bg_image)\n                src2 = bg_data + row*bg_rowbytes;\n            dest = ximage->data + row*ximage_rowbytes;\n            if (rpng2_info.channels == 3) {\n                for (i = rpng2_info.width;  i > 0;  --i) {\n                    red   = *src++;\n                    green = *src++;\n                    blue  = *src++;\n#ifdef NO_24BIT_MASKS\n                    pixel = (red   << RShift) |\n                            (green << GShift) |\n                            (blue  << BShift);\n                    /* recall that we set ximage->byte_order = MSBFirst above */\n                    if (bpp == 32) {\n                        *dest++ = (char)((pixel >> 24) & 0xff);\n                        *dest++ = (char)((pixel >> 16) & 0xff);\n                        *dest++ = (char)((pixel >>  8) & 0xff);\n                        *dest++ = (char)( pixel        & 0xff);\n                    } else {\n                        /* this assumes bpp == 24 & bits are packed low */\n                        /* (probably need to use RShift, RMask, etc.) */\n                        *dest++ = (char)((pixel >> 16) & 0xff);\n                        *dest++ = (char)((pixel >>  8) & 0xff);\n                        *dest++ = (char)( pixel        & 0xff);\n                    }\n#else\n                    red   = (RShift < 0)? red   << (-RShift) : red   >> RShift;\n                    green = (GShift < 0)? green << (-GShift) : green >> GShift;\n                    blue  = (BShift < 0)? blue  << (-BShift) : blue  >> BShift;\n                    pixel = (red & RMask) | (green & GMask) | (blue & BMask);\n                    /* recall that we set ximage->byte_order = MSBFirst above */\n                    if (bpp == 32) {\n                        *dest++ = (char)((pixel >> 24) & 0xff);\n                        *dest++ = (char)((pixel >> 16) & 0xff);\n                        *dest++ = (char)((pixel >>  8) & 0xff);\n                        *dest++ = (char)( pixel        & 0xff);\n                    } else {\n                        /* GRR BUG */\n                        /* this assumes bpp == 24 & bits are packed low */\n                        /* (probably need to use RShift/RMask/etc. here, too) */\n                        *dest++ = (char)((pixel >> 16) & 0xff);\n                        *dest++ = (char)((pixel >>  8) & 0xff);\n                        *dest++ = (char)( pixel        & 0xff);\n                    }\n#endif\n                }\n\n            } else /* if (rpng2_info.channels == 4) */ {\n                for (i = rpng2_info.width;  i > 0;  --i) {\n                    r = *src++;\n                    g = *src++;\n                    b = *src++;\n                    a = *src++;\n                    if (bg_image) {\n                        bg_red   = *src2++;\n                        bg_green = *src2++;\n                        bg_blue  = *src2++;\n                    }\n                    if (a == 255) {\n                        red   = r;\n                        green = g;\n                        blue  = b;\n                    } else if (a == 0) {\n                        red   = bg_red;\n                        green = bg_green;\n                        blue  = bg_blue;\n                    } else {\n                        /* this macro (from png.h) composites the foreground\n                         * and background values and puts the result into the\n                         * first argument */\n                        alpha_composite(red,   r, a, bg_red);\n                        alpha_composite(green, g, a, bg_green);\n                        alpha_composite(blue,  b, a, bg_blue);\n                    }\n#ifdef NO_24BIT_MASKS\n                    pixel = (red   << RShift) |\n                            (green << GShift) |\n                            (blue  << BShift);\n                    /* recall that we set ximage->byte_order = MSBFirst above */\n                    if (bpp == 32) {\n                        *dest++ = (char)((pixel >> 24) & 0xff);\n                        *dest++ = (char)((pixel >> 16) & 0xff);\n                        *dest++ = (char)((pixel >>  8) & 0xff);\n                        *dest++ = (char)( pixel        & 0xff);\n                    } else {\n                        /* this assumes bpp == 24 & bits are packed low */\n                        /* (probably need to use RShift, RMask, etc.) */\n                        *dest++ = (char)((pixel >> 16) & 0xff);\n                        *dest++ = (char)((pixel >>  8) & 0xff);\n                        *dest++ = (char)( pixel        & 0xff);\n                    }\n#else\n                    red   = (RShift < 0)? red   << (-RShift) : red   >> RShift;\n                    green = (GShift < 0)? green << (-GShift) : green >> GShift;\n                    blue  = (BShift < 0)? blue  << (-BShift) : blue  >> BShift;\n                    pixel = (red & RMask) | (green & GMask) | (blue & BMask);\n                    /* recall that we set ximage->byte_order = MSBFirst above */\n                    if (bpp == 32) {\n                        *dest++ = (char)((pixel >> 24) & 0xff);\n                        *dest++ = (char)((pixel >> 16) & 0xff);\n                        *dest++ = (char)((pixel >>  8) & 0xff);\n                        *dest++ = (char)( pixel        & 0xff);\n                    } else {\n                        /* GRR BUG */\n                        /* this assumes bpp == 24 & bits are packed low */\n                        /* (probably need to use RShift/RMask/etc. here, too) */\n                        *dest++ = (char)((pixel >> 16) & 0xff);\n                        *dest++ = (char)((pixel >>  8) & 0xff);\n                        *dest++ = (char)( pixel        & 0xff);\n                    }\n#endif\n                }\n            }\n            /* display after every 16 lines */\n            if (((row+1) & 0xf) == 0) {\n                XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,\n                  (int)lastrow, rpng2_info.width, 16);\n                XFlush(display);\n                lastrow = row + 1;\n            }\n        }\n\n    } else if (depth == 16) {\n        ush red, green, blue;\n\n        for (lastrow = row = startrow;  row < startrow+height;  ++row) {\n            src = rpng2_info.row_pointers[row];\n            if (bg_image)\n                src2 = bg_data + row*bg_rowbytes;\n            dest = ximage->data + row*ximage_rowbytes;\n            if (rpng2_info.channels == 3) {\n                for (i = rpng2_info.width;  i > 0;  --i) {\n                    red   = ((ush)(*src) << 8);\n                    ++src;\n                    green = ((ush)(*src) << 8);\n                    ++src;\n                    blue  = ((ush)(*src) << 8);\n                    ++src;\n                    pixel = ((red   >> RShift) & RMask) |\n                            ((green >> GShift) & GMask) |\n                            ((blue  >> BShift) & BMask);\n                    /* recall that we set ximage->byte_order = MSBFirst above */\n                    *dest++ = (char)((pixel >>  8) & 0xff);\n                    *dest++ = (char)( pixel        & 0xff);\n                }\n            } else /* if (rpng2_info.channels == 4) */ {\n                for (i = rpng2_info.width;  i > 0;  --i) {\n                    r = *src++;\n                    g = *src++;\n                    b = *src++;\n                    a = *src++;\n                    if (bg_image) {\n                        bg_red   = *src2++;\n                        bg_green = *src2++;\n                        bg_blue  = *src2++;\n                    }\n                    if (a == 255) {\n                        red   = ((ush)r << 8);\n                        green = ((ush)g << 8);\n                        blue  = ((ush)b << 8);\n                    } else if (a == 0) {\n                        red   = ((ush)bg_red   << 8);\n                        green = ((ush)bg_green << 8);\n                        blue  = ((ush)bg_blue  << 8);\n                    } else {\n                        /* this macro (from png.h) composites the foreground\n                         * and background values and puts the result back into\n                         * the first argument (== fg byte here:  safe) */\n                        alpha_composite(r, r, a, bg_red);\n                        alpha_composite(g, g, a, bg_green);\n                        alpha_composite(b, b, a, bg_blue);\n                        red   = ((ush)r << 8);\n                        green = ((ush)g << 8);\n                        blue  = ((ush)b << 8);\n                    }\n                    pixel = ((red   >> RShift) & RMask) |\n                            ((green >> GShift) & GMask) |\n                            ((blue  >> BShift) & BMask);\n                    /* recall that we set ximage->byte_order = MSBFirst above */\n                    *dest++ = (char)((pixel >>  8) & 0xff);\n                    *dest++ = (char)( pixel        & 0xff);\n                }\n            }\n            /* display after every 16 lines */\n            if (((row+1) & 0xf) == 0) {\n                XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,\n                  (int)lastrow, rpng2_info.width, 16);\n                XFlush(display);\n                lastrow = row + 1;\n            }\n        }\n\n    } else /* depth == 8 */ {\n\n        /* GRR:  add 8-bit support */\n\n    }\n\n    Trace((stderr, \"calling final XPutImage()\\n\"))\n    if (lastrow < startrow+height) {\n        XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,\n          (int)lastrow, rpng2_info.width, rpng2_info.height-lastrow);\n        XFlush(display);\n    }\n\n    (void)startcol;\n    (void)width;\n\n} /* end function rpng2_x_redisplay_image() */\n\n\n\n\n\n#ifdef FEATURE_LOOP\n\nstatic void rpng2_x_reload_bg_image(void)\n{\n    char *dest;\n    uch r1, r2, g1, g2, b1, b2;\n    uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv;\n    int k, hmax, max;\n    int xidx, yidx, yidx_max;\n    int even_odd_vert, even_odd_horiz, even_odd;\n    int invert_gradient2 = (bg[pat].type & 0x08);\n    int invert_column;\n    ulg i, row;\n\n\n    bgscale = (pat == 0)? 8 : bgscale_default;\n    yidx_max = bgscale - 1;\n\n/*---------------------------------------------------------------------------\n    Vertical gradients (ramps) in NxN squares, alternating direction and\n    colors (N == bgscale).\n  ---------------------------------------------------------------------------*/\n\n    if ((bg[pat].type & 0x07) == 0) {\n        uch r1_min  = rgb[bg[pat].rgb1_min].r;\n        uch g1_min  = rgb[bg[pat].rgb1_min].g;\n        uch b1_min  = rgb[bg[pat].rgb1_min].b;\n        uch r2_min  = rgb[bg[pat].rgb2_min].r;\n        uch g2_min  = rgb[bg[pat].rgb2_min].g;\n        uch b2_min  = rgb[bg[pat].rgb2_min].b;\n        int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min;\n        int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min;\n        int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min;\n        int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min;\n        int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min;\n        int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min;\n\n        for (row = 0;  row < rpng2_info.height;  ++row) {\n            yidx = (int)(row % bgscale);\n            even_odd_vert = (int)((row / bgscale) & 1);\n\n            r1 = r1_min + (r1_diff * yidx) / yidx_max;\n            g1 = g1_min + (g1_diff * yidx) / yidx_max;\n            b1 = b1_min + (b1_diff * yidx) / yidx_max;\n            r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max;\n            g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max;\n            b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max;\n\n            r2 = r2_min + (r2_diff * yidx) / yidx_max;\n            g2 = g2_min + (g2_diff * yidx) / yidx_max;\n            b2 = b2_min + (b2_diff * yidx) / yidx_max;\n            r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max;\n            g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max;\n            b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max;\n\n            dest = (char *)bg_data + row*bg_rowbytes;\n            for (i = 0;  i < rpng2_info.width;  ++i) {\n                even_odd_horiz = (int)((i / bgscale) & 1);\n                even_odd = even_odd_vert ^ even_odd_horiz;\n                invert_column =\n                  (even_odd_horiz && (bg[pat].type & 0x10));\n                if (even_odd == 0) {        /* gradient #1 */\n                    if (invert_column) {\n                        *dest++ = r1_inv;\n                        *dest++ = g1_inv;\n                        *dest++ = b1_inv;\n                    } else {\n                        *dest++ = r1;\n                        *dest++ = g1;\n                        *dest++ = b1;\n                    }\n                } else {                    /* gradient #2 */\n                    if ((invert_column && invert_gradient2) ||\n                        (!invert_column && !invert_gradient2))\n                    {\n                        *dest++ = r2;       /* not inverted or */\n                        *dest++ = g2;       /*  doubly inverted */\n                        *dest++ = b2;\n                    } else {\n                        *dest++ = r2_inv;\n                        *dest++ = g2_inv;   /* singly inverted */\n                        *dest++ = b2_inv;\n                    }\n                }\n            }\n        }\n\n/*---------------------------------------------------------------------------\n    Soft gradient-diamonds with scale = bgscale.  Code contributed by Adam\n    M. Costello.\n  ---------------------------------------------------------------------------*/\n\n    } else if ((bg[pat].type & 0x07) == 1) {\n\n        hmax = (bgscale-1)/2;   /* half the max weight of a color */\n        max = 2*hmax;           /* the max weight of a color */\n\n        r1 = rgb[bg[pat].rgb1_max].r;\n        g1 = rgb[bg[pat].rgb1_max].g;\n        b1 = rgb[bg[pat].rgb1_max].b;\n        r2 = rgb[bg[pat].rgb2_max].r;\n        g2 = rgb[bg[pat].rgb2_max].g;\n        b2 = rgb[bg[pat].rgb2_max].b;\n\n        for (row = 0;  row < rpng2_info.height;  ++row) {\n            yidx = (int)(row % bgscale);\n            if (yidx > hmax)\n                yidx = bgscale-1 - yidx;\n            dest = (char *)bg_data + row*bg_rowbytes;\n            for (i = 0;  i < rpng2_info.width;  ++i) {\n                xidx = (int)(i % bgscale);\n                if (xidx > hmax)\n                    xidx = bgscale-1 - xidx;\n                k = xidx + yidx;\n                *dest++ = (k*r1 + (max-k)*r2) / max;\n                *dest++ = (k*g1 + (max-k)*g2) / max;\n                *dest++ = (k*b1 + (max-k)*b2) / max;\n            }\n        }\n\n/*---------------------------------------------------------------------------\n    Radial \"starburst\" with azimuthal sinusoids; [eventually number of sinu-\n    soids will equal bgscale?].  This one is slow but very cool.  Code con-\n    tributed by Pieter S. van der Meulen (originally in Smalltalk).\n  ---------------------------------------------------------------------------*/\n\n    } else if ((bg[pat].type & 0x07) == 2) {\n        uch ch;\n        int ii, x, y, hw, hh, grayspot;\n        double freq, rotate, saturate, gray, intensity;\n        double angle=0.0, aoffset=0.0, maxDist, dist;\n        double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t;\n\n        hh = (int)(rpng2_info.height / 2);\n        hw = (int)(rpng2_info.width / 2);\n\n        /* variables for radial waves:\n         *   aoffset:  number of degrees to rotate hue [CURRENTLY NOT USED]\n         *   freq:  number of color beams originating from the center\n         *   grayspot:  size of the graying center area (anti-alias)\n         *   rotate:  rotation of the beams as a function of radius\n         *   saturate:  saturation of beams' shape azimuthally\n         */\n        angle = CLIP(angle, 0.0, 360.0);\n        grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw));\n        freq = MAX((double)bg[pat].bg_freq, 0.0);\n        saturate = (double)bg[pat].bg_bsat * 0.1;\n        rotate = (double)bg[pat].bg_brot * 0.1;\n        gray = 0.0;\n        intensity = 0.0;\n        maxDist = (double)((hw*hw) + (hh*hh));\n\n        for (row = 0;  row < rpng2_info.height;  ++row) {\n            y = (int)(row - hh);\n            dest = (char *)bg_data + row*bg_rowbytes;\n            for (i = 0;  i < rpng2_info.width;  ++i) {\n                x = (int)(i - hw);\n                angle = (x == 0)? PI_2 : atan((double)y / (double)x);\n                gray = (double)MAX(ABS(y), ABS(x)) / grayspot;\n                gray = MIN(1.0, gray);\n                dist = (double)((x*x) + (y*y)) / maxDist;\n                intensity = cos((angle+(rotate*dist*PI)) * freq) *\n                  gray * saturate;\n                intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5;\n                hue = (angle + PI) * INV_PI_360 + aoffset;\n                s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh));\n                s = MIN(MAX(s,0.0), 1.0);\n                v = MIN(MAX(intensity,0.0), 1.0);\n\n                if (s == 0.0) {\n                    ch = (uch)(v * 255.0);\n                    *dest++ = ch;\n                    *dest++ = ch;\n                    *dest++ = ch;\n                } else {\n                    if ((hue < 0.0) || (hue >= 360.0))\n                        hue -= (((int)(hue / 360.0)) * 360.0);\n                    hue /= 60.0;\n                    ii = (int)hue;\n                    f = hue - (double)ii;\n                    p = (1.0 - s) * v;\n                    q = (1.0 - (s * f)) * v;\n                    t = (1.0 - (s * (1.0 - f))) * v;\n                    if      (ii == 0) { red = v; green = t; blue = p; }\n                    else if (ii == 1) { red = q; green = v; blue = p; }\n                    else if (ii == 2) { red = p; green = v; blue = t; }\n                    else if (ii == 3) { red = p; green = q; blue = v; }\n                    else if (ii == 4) { red = t; green = p; blue = v; }\n                    else if (ii == 5) { red = v; green = p; blue = q; }\n                    *dest++ = (uch)(red * 255.0);\n                    *dest++ = (uch)(green * 255.0);\n                    *dest++ = (uch)(blue * 255.0);\n                }\n            }\n        }\n    }\n\n} /* end function rpng2_x_reload_bg_image() */\n\n\n\n\n\nstatic int is_number(char *p)\n{\n    while (*p) {\n        if (!isdigit(*p))\n            return FALSE;\n        ++p;\n    }\n    return TRUE;\n}\n\n#endif /* FEATURE_LOOP */\n\n\n\n\n\nstatic void rpng2_x_cleanup(void)\n{\n    if (bg_image && bg_data) {\n        free(bg_data);\n        bg_data = NULL;\n    }\n\n    if (rpng2_info.image_data) {\n        free(rpng2_info.image_data);\n        rpng2_info.image_data = NULL;\n    }\n\n    if (rpng2_info.row_pointers) {\n        free(rpng2_info.row_pointers);\n        rpng2_info.row_pointers = NULL;\n    }\n\n    if (ximage) {\n        if (ximage->data) {\n            free(ximage->data);           /* we allocated it, so we free it */\n            ximage->data = (char *)NULL;  /*  instead of XDestroyImage() */\n        }\n        XDestroyImage(ximage);\n        ximage = NULL;\n    }\n\n    if (have_gc)\n        XFreeGC(display, gc);\n\n    if (have_window)\n        XDestroyWindow(display, window);\n\n    if (have_colormap)\n        XFreeColormap(display, colormap);\n\n    if (have_nondefault_visual)\n        XFree(visual_list);\n}\n\n\n\n\n\nstatic int rpng2_x_msb(ulg u32val)\n{\n    int i;\n\n    for (i = 31;  i >= 0;  --i) {\n        if (u32val & 0x80000000L)\n            break;\n        u32val <<= 1;\n    }\n    return i;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/wpng.c",
    "content": "/*---------------------------------------------------------------------------\n\n   wpng - simple PNG-writing program                                 wpng.c\n\n   This program converts certain NetPBM binary files (grayscale and RGB,\n   maxval = 255) to PNG.  Non-interlaced PNGs are written progressively;\n   interlaced PNGs are read and written in one memory-intensive blast.\n\n   Thanks to Jean-loup Gailly for providing the necessary trick to read\n   interactive text from the keyboard while stdin is redirected.  Thanks\n   to Cosmin Truta for Cygwin fixes.\n\n   NOTE:  includes provisional support for PNM type \"8\" (portable alphamap)\n          images, presumed to be a 32-bit interleaved RGBA format; no pro-\n          vision for possible interleaved grayscale+alpha (16-bit) format.\n          THIS IS UNLIKELY TO BECOME AN OFFICIAL NETPBM ALPHA FORMAT!\n\n   to do:\n    - delete output file if quit before calling any writepng routines\n    - process backspace with -text option under DOS/Win? (currently get ^H)\n\n  ---------------------------------------------------------------------------\n\n   Changelog:\n    - 1.01:  initial public release\n    - 1.02:  modified to allow abbreviated options\n    - 1.03:  removed extraneous character from usage screen; fixed bug in\n              command-line parsing\n    - 1.04:  fixed DOS/OS2/Win32 detection, including partial Cygwin fix\n              (see http://home.att.net/~perlspinr/diffs/GregBook_cygwin.diff)\n    - 2.00:  dual-licensed (added GNU GPL)\n\n        [REPORTED BUG (win32 only):  \"contrib/gregbook/wpng.c - cmd line\n         dose not work!  In order to do something useful I needed to redirect\n         both input and output, with cygwin and with bcc32 as well.  Under\n         Linux, the same wpng appears to work fine.  I don't know what is\n         the problem.\"]\n\n  ---------------------------------------------------------------------------\n\n      Copyright (c) 1998-2007 Greg Roelofs.  All rights reserved.\n\n      This software is provided \"as is,\" without warranty of any kind,\n      express or implied.  In no event shall the author or contributors\n      be held liable for any damages arising in any way from the use of\n      this software.\n\n      The contents of this file are DUAL-LICENSED.  You may modify and/or\n      redistribute this software according to the terms of one of the\n      following two licenses (at your option):\n\n\n      LICENSE 1 (\"BSD-like with advertising clause\"):\n\n      Permission is granted to anyone to use this software for any purpose,\n      including commercial applications, and to alter it and redistribute\n      it freely, subject to the following restrictions:\n\n      1. Redistributions of source code must retain the above copyright\n         notice, disclaimer, and this list of conditions.\n      2. Redistributions in binary form must reproduce the above copyright\n         notice, disclaimer, and this list of conditions in the documenta-\n         tion and/or other materials provided with the distribution.\n      3. All advertising materials mentioning features or use of this\n         software must display the following acknowledgment:\n\n            This product includes software developed by Greg Roelofs\n            and contributors for the book, \"PNG: The Definitive Guide,\"\n            published by O'Reilly and Associates.\n\n\n      LICENSE 2 (GNU GPL v2 or later):\n\n      This program is free software; you can redistribute it and/or modify\n      it under the terms of the GNU General Public License as published by\n      the Free Software Foundation; either version 2 of the License, or\n      (at your option) any later version.\n\n      This program is distributed in the hope that it will be useful,\n      but WITHOUT ANY WARRANTY; without even the implied warranty of\n      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n      GNU General Public License for more details.\n\n      You should have received a copy of the GNU General Public License\n      along with this program; if not, write to the Free Software Foundation,\n      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  ---------------------------------------------------------------------------*/\n\n#define PROGNAME  \"wpng\"\n#define VERSION   \"2.00 of 2 June 2007\"\n#define APPNAME   \"Simple PGM/PPM/PAM to PNG Converter\"\n\n#if defined(__MSDOS__) || defined(__OS2__)\n#  define DOS_OS2_W32\n#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)\n#  ifndef __GNUC__   /* treat Win32 native ports of gcc as Unix environments */\n#    define DOS_OS2_W32\n#  endif\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <setjmp.h>     /* for jmpbuf declaration in writepng.h */\n#include <time.h>\n\n#ifdef DOS_OS2_W32\n#  include <io.h>       /* for isatty(), setmode() prototypes */\n#  include <fcntl.h>    /* O_BINARY for fdopen() without text translation */\n#  ifdef __EMX__\n#    ifndef getch\n#      define getch() _read_kbd(0, 1, 0)    /* need getche() */\n#    endif\n#  else /* !__EMX__ */\n#    ifdef __GO32__\n#      include <pc.h>\n#      define getch() getkey()  /* GRR:  need getche() */\n#    else\n#      include <conio.h>        /* for getche() console input */\n#    endif\n#  endif /* ?__EMX__ */\n#  define FGETS(buf,len,stream)  dos_kbd_gets(buf,len)\n#else\n#  include <unistd.h>           /* for isatty() prototype */\n#  define FGETS fgets\n#endif\n\n/* #define DEBUG  :  this enables the Trace() macros */\n\n/* #define FORBID_LATIN1_CTRL  :  this requires the user to re-enter any\n   text that includes control characters discouraged by the PNG spec; text\n   that includes an escape character (27) must be re-entered regardless */\n\n#include \"writepng.h\"   /* typedefs, common macros, writepng prototypes */\n\n\n\n/* local prototypes */\n\nstatic int  wpng_isvalid_latin1(uch *p, int len);\nstatic void wpng_cleanup(void);\n\n#ifdef DOS_OS2_W32\n   static char *dos_kbd_gets(char *buf, int len);\n#endif\n\n\n\nstatic mainprog_info wpng_info;   /* lone global */\n\n\n\nint main(int argc, char **argv)\n{\n#ifndef DOS_OS2_W32\n    FILE *keybd;\n#endif\n#ifdef sgi\n    FILE *tmpfile;      /* or we could just use keybd, since no overlap */\n    char tmpline[80];\n#endif\n    char *inname = NULL, outname[256];\n    char *p, pnmchar, pnmline[256];\n    char *bgstr, *textbuf = NULL;\n    ulg rowbytes;\n    int rc, len = 0;\n    int error = 0;\n    int text = FALSE;\n    int maxval;\n    double LUT_exponent;                /* just the lookup table */\n    double CRT_exponent = 2.2;          /* just the monitor */\n    double default_display_exponent;    /* whole display system */\n    double default_gamma = 0.0;\n\n\n    wpng_info.infile = NULL;\n    wpng_info.outfile = NULL;\n    wpng_info.image_data = NULL;\n    wpng_info.row_pointers = NULL;\n    wpng_info.filter = FALSE;\n    wpng_info.interlaced = FALSE;\n    wpng_info.have_bg = FALSE;\n    wpng_info.have_time = FALSE;\n    wpng_info.have_text = 0;\n    wpng_info.gamma = 0.0;\n\n\n    /* First get the default value for our display-system exponent, i.e.,\n     * the product of the CRT exponent and the exponent corresponding to\n     * the frame-buffer's lookup table (LUT), if any.  If the PNM image\n     * looks correct on the user's display system, its file gamma is the\n     * inverse of this value.  (Note that this is not an exhaustive list\n     * of LUT values--e.g., OpenStep has a lot of weird ones--but it should\n     * cover 99% of the current possibilities.  This section must ensure\n     * that default_display_exponent is positive.) */\n\n#if defined(NeXT)\n    /* third-party utilities can modify the default LUT exponent */\n    LUT_exponent = 1.0 / 2.2;\n    /*\n    if (some_next_function_that_returns_gamma(&next_gamma))\n        LUT_exponent = 1.0 / next_gamma;\n     */\n#elif defined(sgi)\n    LUT_exponent = 1.0 / 1.7;\n    /* there doesn't seem to be any documented function to\n     * get the \"gamma\" value, so we do it the hard way */\n    tmpfile = fopen(\"/etc/config/system.glGammaVal\", \"r\");\n    if (tmpfile) {\n        double sgi_gamma;\n\n        fgets(tmpline, 80, tmpfile);\n        fclose(tmpfile);\n        sgi_gamma = atof(tmpline);\n        if (sgi_gamma > 0.0)\n            LUT_exponent = 1.0 / sgi_gamma;\n    }\n#elif defined(Macintosh)\n    LUT_exponent = 1.8 / 2.61;\n    /*\n    if (some_mac_function_that_returns_gamma(&mac_gamma))\n        LUT_exponent = mac_gamma / 2.61;\n     */\n#else\n    LUT_exponent = 1.0;   /* assume no LUT:  most PCs */\n#endif\n\n    /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */\n    default_display_exponent = LUT_exponent * CRT_exponent;\n\n\n    /* If the user has set the SCREEN_GAMMA environment variable as suggested\n     * (somewhat imprecisely) in the libpng documentation, use that; otherwise\n     * use the default value we just calculated.  Either way, the user may\n     * override this via a command-line option. */\n\n    if ((p = getenv(\"SCREEN_GAMMA\")) != NULL) {\n        double exponent = atof(p);\n\n        if (exponent > 0.0)\n            default_gamma = 1.0 / exponent;\n    }\n\n    if (default_gamma == 0.0)\n        default_gamma = 1.0 / default_display_exponent;\n\n\n    /* Now parse the command line for options and the PNM filename. */\n\n    while (*++argv && !error) {\n        if (!strncmp(*argv, \"-i\", 2)) {\n            wpng_info.interlaced = TRUE;\n        } else if (!strncmp(*argv, \"-time\", 3)) {\n            wpng_info.modtime = time(NULL);\n            wpng_info.have_time = TRUE;\n        } else if (!strncmp(*argv, \"-text\", 3)) {\n            text = TRUE;\n        } else if (!strncmp(*argv, \"-gamma\", 2)) {\n            if (!*++argv)\n                ++error;\n            else {\n                wpng_info.gamma = atof(*argv);\n                if (wpng_info.gamma <= 0.0)\n                    ++error;\n                else if (wpng_info.gamma > 1.01)\n                    fprintf(stderr, PROGNAME\n                      \" warning:  file gammas are usually less than 1.0\\n\");\n            }\n        } else if (!strncmp(*argv, \"-bgcolor\", 4)) {\n            if (!*++argv)\n                ++error;\n            else {\n                bgstr = *argv;\n                if (strlen(bgstr) != 7 || bgstr[0] != '#')\n                    ++error;\n                else {\n                    unsigned r, g, b;  /* this way quiets compiler warnings */\n\n                    sscanf(bgstr+1, \"%2x%2x%2x\", &r, &g, &b);\n                    wpng_info.bg_red   = (uch)r;\n                    wpng_info.bg_green = (uch)g;\n                    wpng_info.bg_blue  = (uch)b;\n                    wpng_info.have_bg = TRUE;\n                }\n            }\n        } else {\n            if (**argv != '-') {\n                inname = *argv;\n                if (argv[1])   /* shouldn't be any more args after filename */\n                    ++error;\n            } else\n                ++error;   /* not expecting any other options */\n        }\n    }\n\n\n    /* open the input and output files, or register an error and abort */\n\n    if (!inname) {\n        if (isatty(0)) {\n            fprintf(stderr, PROGNAME\n              \":  must give input filename or provide image data via stdin\\n\");\n            ++error;\n        } else {\n#ifdef DOS_OS2_W32\n            /* some buggy C libraries require BOTH setmode() and fdopen(bin) */\n            setmode(fileno(stdin), O_BINARY);\n            setmode(fileno(stdout), O_BINARY);\n#endif\n            if ((wpng_info.infile = fdopen(fileno(stdin), \"rb\")) == NULL) {\n                fprintf(stderr, PROGNAME\n                  \":  unable to reopen stdin in binary mode\\n\");\n                ++error;\n            } else\n            if ((wpng_info.outfile = fdopen(fileno(stdout), \"wb\")) == NULL) {\n                fprintf(stderr, PROGNAME\n                  \":  unable to reopen stdout in binary mode\\n\");\n                fclose(wpng_info.infile);\n                ++error;\n            } else\n                wpng_info.filter = TRUE;\n        }\n    } else if ((len = strlen(inname)) > 250) {\n        fprintf(stderr, PROGNAME \":  input filename is too long [%d chars]\\n\",\n          len);\n        ++error;\n    } else if (!(wpng_info.infile = fopen(inname, \"rb\"))) {\n        fprintf(stderr, PROGNAME \":  can't open input file [%s]\\n\", inname);\n        ++error;\n    }\n\n    if (!error) {\n        fgets(pnmline, 256, wpng_info.infile);\n        if (pnmline[0] != 'P' || ((pnmchar = pnmline[1]) != '5' &&\n            pnmchar != '6' && pnmchar != '8'))\n        {\n            fprintf(stderr, PROGNAME\n              \":  input file [%s] is not a binary PGM, PPM or PAM file\\n\",\n              inname);\n            ++error;\n        } else {\n            wpng_info.pnmtype = (int)(pnmchar - '0');\n            if (wpng_info.pnmtype != 8)\n                wpng_info.have_bg = FALSE;  /* no need for bg if opaque */\n            do {\n                fgets(pnmline, 256, wpng_info.infile);  /* lose any comments */\n            } while (pnmline[0] == '#');\n            sscanf(pnmline, \"%ld %ld\", &wpng_info.width, &wpng_info.height);\n            do {\n                fgets(pnmline, 256, wpng_info.infile);  /* more comment lines */\n            } while (pnmline[0] == '#');\n            sscanf(pnmline, \"%d\", &maxval);\n            if (wpng_info.width <= 0L || wpng_info.height <= 0L ||\n                maxval != 255)\n            {\n                fprintf(stderr, PROGNAME\n                  \":  only positive width/height, maxval == 255 allowed \\n\");\n                ++error;\n            }\n            wpng_info.sample_depth = 8;  /* <==> maxval 255 */\n\n            if (!wpng_info.filter) {\n                /* make outname from inname */\n                if ((p = strrchr(inname, '.')) == NULL ||\n                    (p - inname) != (len - 4))\n                {\n                    strcpy(outname, inname);\n                    strcpy(outname+len, \".png\");\n                } else {\n                    len -= 4;\n                    strncpy(outname, inname, len);\n                    strcpy(outname+len, \".png\");\n                }\n                /* check if outname already exists; if not, open */\n                if ((wpng_info.outfile = fopen(outname, \"rb\")) != NULL) {\n                    fprintf(stderr, PROGNAME \":  output file exists [%s]\\n\",\n                      outname);\n                    fclose(wpng_info.outfile);\n                    ++error;\n                } else if (!(wpng_info.outfile = fopen(outname, \"wb\"))) {\n                    fprintf(stderr, PROGNAME \":  can't open output file [%s]\\n\",\n                      outname);\n                    ++error;\n                }\n            }\n        }\n        if (error) {\n            fclose(wpng_info.infile);\n            wpng_info.infile = NULL;\n            if (wpng_info.filter) {\n                fclose(wpng_info.outfile);\n                wpng_info.outfile = NULL;\n            }\n        }\n    }\n\n\n    /* if we had any errors, print usage and die horrible death...arrr! */\n\n    if (error) {\n        fprintf(stderr, \"\\n%s %s:  %s\\n\", PROGNAME, VERSION, APPNAME);\n        writepng_version_info();\n        fprintf(stderr, \"\\n\"\n\"Usage:  %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] pnmfile\\n\"\n\"or: ... | %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] | ...\\n\"\n         \"    exp \\ttransfer-function exponent (``gamma'') of the image in\\n\"\n         \"\\t\\t  floating-point format (e.g., ``%.5f''); if image looks\\n\"\n         \"\\t\\t  correct on given display system, image gamma is equal to\\n\"\n         \"\\t\\t  inverse of display-system exponent, i.e., 1 / (LUT * CRT)\\n\"\n         \"\\t\\t  (where LUT = lookup-table exponent and CRT = CRT exponent;\\n\"\n         \"\\t\\t  first varies, second is usually 2.2, all are positive)\\n\"\n         \"    bg  \\tdesired background color for alpha-channel images, in\\n\"\n         \"\\t\\t  7-character hex RGB format (e.g., ``#ff7700'' for orange:\\n\"\n         \"\\t\\t  same as HTML colors)\\n\"\n         \"    -text\\tprompt interactively for text info (tEXt chunks)\\n\"\n         \"    -time\\tinclude a tIME chunk (last modification time)\\n\"\n         \"    -interlace\\twrite interlaced PNG image\\n\"\n         \"\\n\"\n\"pnmfile or stdin must be a binary PGM (`P5'), PPM (`P6') or (extremely\\n\"\n\"unofficial and unsupported!) PAM (`P8') file.  Currently it is required\\n\"\n\"to have maxval == 255 (i.e., no scaling).  If pnmfile is specified, it\\n\"\n\"is converted to the corresponding PNG file with the same base name but a\\n\"\n\"``.png'' extension; files read from stdin are converted and sent to stdout.\\n\"\n\"The conversion is progressive (low memory usage) unless interlacing is\\n\"\n\"requested; in that case the whole image will be buffered in memory and\\n\"\n\"written in one call.\\n\"\n         \"\\n\", PROGNAME, PROGNAME, default_gamma);\n        exit(1);\n    }\n\n\n    /* prepare the text buffers for libpng's use; note that even though\n     * PNG's png_text struct includes a length field, we don't have to fill\n     * it out */\n\n    if (text &&\n#ifndef DOS_OS2_W32\n        (keybd = fdopen(fileno(stderr), \"r\")) != NULL &&\n#endif\n        (textbuf = (char *)malloc((5 + 9)*75)) != NULL)\n    {\n        int i, valid, result;\n\n        fprintf(stderr,\n          \"Enter text info (no more than 72 characters per line);\\n\");\n        fprintf(stderr, \"to skip a field, hit the <Enter> key.\\n\");\n        /* note:  just <Enter> leaves len == 1 */\n\n        do {\n            valid = TRUE;\n            p = textbuf + TEXT_TITLE_OFFSET;\n            fprintf(stderr, \"  Title: \");\n            fflush(stderr);\n            if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {\n                if (p[len-1] == '\\n')\n                    p[--len] = '\\0';\n                wpng_info.title = p;\n                wpng_info.have_text |= TEXT_TITLE;\n                if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {\n                    fprintf(stderr, \"    \" PROGNAME \" warning:  character code\"\n                      \" %u is %sdiscouraged by the PNG\\n    specification \"\n                      \"[first occurrence was at character position #%d]\\n\",\n                      (unsigned)p[result], (p[result] == 27)? \"strongly \" : \"\",\n                      result+1);\n                    fflush(stderr);\n#ifdef FORBID_LATIN1_CTRL\n                    wpng_info.have_text &= ~TEXT_TITLE;\n                    valid = FALSE;\n#else\n                    if (p[result] == 27) {    /* escape character */\n                        wpng_info.have_text &= ~TEXT_TITLE;\n                        valid = FALSE;\n                    }\n#endif\n                }\n            }\n        } while (!valid);\n\n        do {\n            valid = TRUE;\n            p = textbuf + TEXT_AUTHOR_OFFSET;\n            fprintf(stderr, \"  Author: \");\n            fflush(stderr);\n            if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {\n                if (p[len-1] == '\\n')\n                    p[--len] = '\\0';\n                wpng_info.author = p;\n                wpng_info.have_text |= TEXT_AUTHOR;\n                if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {\n                    fprintf(stderr, \"    \" PROGNAME \" warning:  character code\"\n                      \" %u is %sdiscouraged by the PNG\\n    specification \"\n                      \"[first occurrence was at character position #%d]\\n\",\n                      (unsigned)p[result], (p[result] == 27)? \"strongly \" : \"\",\n                      result+1);\n                    fflush(stderr);\n#ifdef FORBID_LATIN1_CTRL\n                    wpng_info.have_text &= ~TEXT_AUTHOR;\n                    valid = FALSE;\n#else\n                    if (p[result] == 27) {    /* escape character */\n                        wpng_info.have_text &= ~TEXT_AUTHOR;\n                        valid = FALSE;\n                    }\n#endif\n                }\n            }\n        } while (!valid);\n\n        do {\n            valid = TRUE;\n            p = textbuf + TEXT_DESC_OFFSET;\n            fprintf(stderr, \"  Description (up to 9 lines):\\n\");\n            for (i = 1;  i < 10;  ++i) {\n                fprintf(stderr, \"    [%d] \", i);\n                fflush(stderr);\n                if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1)\n                    p += len;   /* now points at NULL; char before is newline */\n                else\n                    break;\n            }\n            if ((len = p - (textbuf + TEXT_DESC_OFFSET)) > 1) {\n                if (p[-1] == '\\n') {\n                    p[-1] = '\\0';\n                    --len;\n                }\n                wpng_info.desc = textbuf + TEXT_DESC_OFFSET;\n                wpng_info.have_text |= TEXT_DESC;\n                p = textbuf + TEXT_DESC_OFFSET;\n                if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {\n                    fprintf(stderr, \"    \" PROGNAME \" warning:  character code\"\n                      \" %u is %sdiscouraged by the PNG\\n    specification \"\n                      \"[first occurrence was at character position #%d]\\n\",\n                      (unsigned)p[result], (p[result] == 27)? \"strongly \" : \"\",\n                      result+1);\n                    fflush(stderr);\n#ifdef FORBID_LATIN1_CTRL\n                    wpng_info.have_text &= ~TEXT_DESC;\n                    valid = FALSE;\n#else\n                    if (p[result] == 27) {    /* escape character */\n                        wpng_info.have_text &= ~TEXT_DESC;\n                        valid = FALSE;\n                    }\n#endif\n                }\n            }\n        } while (!valid);\n\n        do {\n            valid = TRUE;\n            p = textbuf + TEXT_COPY_OFFSET;\n            fprintf(stderr, \"  Copyright: \");\n            fflush(stderr);\n            if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {\n                if (p[len-1] == '\\n')\n                    p[--len] = '\\0';\n                wpng_info.copyright = p;\n                wpng_info.have_text |= TEXT_COPY;\n                if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {\n                    fprintf(stderr, \"    \" PROGNAME \" warning:  character code\"\n                      \" %u is %sdiscouraged by the PNG\\n    specification \"\n                      \"[first occurrence was at character position #%d]\\n\",\n                      (unsigned)p[result], (p[result] == 27)? \"strongly \" : \"\",\n                      result+1);\n                    fflush(stderr);\n#ifdef FORBID_LATIN1_CTRL\n                    wpng_info.have_text &= ~TEXT_COPY;\n                    valid = FALSE;\n#else\n                    if (p[result] == 27) {    /* escape character */\n                        wpng_info.have_text &= ~TEXT_COPY;\n                        valid = FALSE;\n                    }\n#endif\n                }\n            }\n        } while (!valid);\n\n        do {\n            valid = TRUE;\n            p = textbuf + TEXT_EMAIL_OFFSET;\n            fprintf(stderr, \"  E-mail: \");\n            fflush(stderr);\n            if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {\n                if (p[len-1] == '\\n')\n                    p[--len] = '\\0';\n                wpng_info.email = p;\n                wpng_info.have_text |= TEXT_EMAIL;\n                if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {\n                    fprintf(stderr, \"    \" PROGNAME \" warning:  character code\"\n                      \" %u is %sdiscouraged by the PNG\\n    specification \"\n                      \"[first occurrence was at character position #%d]\\n\",\n                      (unsigned)p[result], (p[result] == 27)? \"strongly \" : \"\",\n                      result+1);\n                    fflush(stderr);\n#ifdef FORBID_LATIN1_CTRL\n                    wpng_info.have_text &= ~TEXT_EMAIL;\n                    valid = FALSE;\n#else\n                    if (p[result] == 27) {    /* escape character */\n                        wpng_info.have_text &= ~TEXT_EMAIL;\n                        valid = FALSE;\n                    }\n#endif\n                }\n            }\n        } while (!valid);\n\n        do {\n            valid = TRUE;\n            p = textbuf + TEXT_URL_OFFSET;\n            fprintf(stderr, \"  URL: \");\n            fflush(stderr);\n            if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {\n                if (p[len-1] == '\\n')\n                    p[--len] = '\\0';\n                wpng_info.url = p;\n                wpng_info.have_text |= TEXT_URL;\n                if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {\n                    fprintf(stderr, \"    \" PROGNAME \" warning:  character code\"\n                      \" %u is %sdiscouraged by the PNG\\n    specification \"\n                      \"[first occurrence was at character position #%d]\\n\",\n                      (unsigned)p[result], (p[result] == 27)? \"strongly \" : \"\",\n                      result+1);\n                    fflush(stderr);\n#ifdef FORBID_LATIN1_CTRL\n                    wpng_info.have_text &= ~TEXT_URL;\n                    valid = FALSE;\n#else\n                    if (p[result] == 27) {    /* escape character */\n                        wpng_info.have_text &= ~TEXT_URL;\n                        valid = FALSE;\n                    }\n#endif\n                }\n            }\n        } while (!valid);\n\n#ifndef DOS_OS2_W32\n        fclose(keybd);\n#endif\n\n    } else if (text) {\n        fprintf(stderr, PROGNAME \":  unable to allocate memory for text\\n\");\n        text = FALSE;\n        wpng_info.have_text = 0;\n    }\n\n\n    /* allocate libpng stuff, initialize transformations, write pre-IDAT data */\n\n    if ((rc = writepng_init(&wpng_info)) != 0) {\n        switch (rc) {\n            case 2:\n                fprintf(stderr, PROGNAME\n                  \":  libpng initialization problem (longjmp)\\n\");\n                break;\n            case 4:\n                fprintf(stderr, PROGNAME \":  insufficient memory\\n\");\n                break;\n            case 11:\n                fprintf(stderr, PROGNAME\n                  \":  internal logic error (unexpected PNM type)\\n\");\n                break;\n            default:\n                fprintf(stderr, PROGNAME\n                  \":  unknown writepng_init() error\\n\");\n                break;\n        }\n        exit(rc);\n    }\n\n\n    /* free textbuf, since it's a completely local variable and all text info\n     * has just been written to the PNG file */\n\n    if (text && textbuf) {\n        free(textbuf);\n        textbuf = NULL;\n    }\n\n\n    /* calculate rowbytes on basis of image type; note that this becomes much\n     * more complicated if we choose to support PBM type, ASCII PNM types, or\n     * 16-bit-per-sample binary data [currently not an official NetPBM type] */\n\n    if (wpng_info.pnmtype == 5)\n        rowbytes = wpng_info.width;\n    else if (wpng_info.pnmtype == 6)\n        rowbytes = wpng_info.width * 3;\n    else /* if (wpng_info.pnmtype == 8) */\n        rowbytes = wpng_info.width * 4;\n\n\n    /* read and write the image, either in its entirety (if writing interlaced\n     * PNG) or row by row (if non-interlaced) */\n\n    fprintf(stderr, \"Encoding image data...\\n\");\n    fflush(stderr);\n\n    if (wpng_info.interlaced) {\n        long i;\n        ulg bytes;\n        ulg image_bytes = rowbytes * wpng_info.height;   /* overflow? */\n\n        wpng_info.image_data = (uch *)malloc(image_bytes);\n        wpng_info.row_pointers = (uch **)malloc(wpng_info.height*sizeof(uch *));\n        if (wpng_info.image_data == NULL || wpng_info.row_pointers == NULL) {\n            fprintf(stderr, PROGNAME \":  insufficient memory for image data\\n\");\n            writepng_cleanup(&wpng_info);\n            wpng_cleanup();\n            exit(5);\n        }\n        for (i = 0;  i < wpng_info.height;  ++i)\n            wpng_info.row_pointers[i] = wpng_info.image_data + i*rowbytes;\n        bytes = fread(wpng_info.image_data, 1, image_bytes, wpng_info.infile);\n        if (bytes != image_bytes) {\n            fprintf(stderr, PROGNAME \":  expected %lu bytes, got %lu bytes\\n\",\n              image_bytes, bytes);\n            fprintf(stderr, \"  (continuing anyway)\\n\");\n        }\n        if (writepng_encode_image(&wpng_info) != 0) {\n            fprintf(stderr, PROGNAME\n              \":  libpng problem (longjmp) while writing image data\\n\");\n            writepng_cleanup(&wpng_info);\n            wpng_cleanup();\n            exit(2);\n        }\n\n    } else /* not interlaced:  write progressively (row by row) */ {\n        long j;\n        ulg bytes;\n\n        wpng_info.image_data = (uch *)malloc(rowbytes);\n        if (wpng_info.image_data == NULL) {\n            fprintf(stderr, PROGNAME \":  insufficient memory for row data\\n\");\n            writepng_cleanup(&wpng_info);\n            wpng_cleanup();\n            exit(5);\n        }\n        error = 0;\n        for (j = wpng_info.height;  j > 0L;  --j) {\n            bytes = fread(wpng_info.image_data, 1, rowbytes, wpng_info.infile);\n            if (bytes != rowbytes) {\n                fprintf(stderr, PROGNAME\n                  \":  expected %lu bytes, got %lu bytes (row %ld)\\n\", rowbytes,\n                  bytes, wpng_info.height-j);\n                ++error;\n                break;\n            }\n            if (writepng_encode_row(&wpng_info) != 0) {\n                fprintf(stderr, PROGNAME\n                  \":  libpng problem (longjmp) while writing row %ld\\n\",\n                  wpng_info.height-j);\n                ++error;\n                break;\n            }\n        }\n        if (error) {\n            writepng_cleanup(&wpng_info);\n            wpng_cleanup();\n            exit(2);\n        }\n        if (writepng_encode_finish(&wpng_info) != 0) {\n            fprintf(stderr, PROGNAME \":  error on final libpng call\\n\");\n            writepng_cleanup(&wpng_info);\n            wpng_cleanup();\n            exit(2);\n        }\n    }\n\n\n    /* OK, we're done (successfully):  clean up all resources and quit */\n\n    fprintf(stderr, \"Done.\\n\");\n    fflush(stderr);\n\n    writepng_cleanup(&wpng_info);\n    wpng_cleanup();\n\n    return 0;\n}\n\n\n\n\n\nstatic int wpng_isvalid_latin1(uch *p, int len)\n{\n    int i, result = -1;\n\n    for (i = 0;  i < len;  ++i) {\n        if (p[i] == 10 || (p[i] > 31 && p[i] < 127) || p[i] > 160)\n            continue;           /* character is completely OK */\n        if (result < 0 || (p[result] != 27 && p[i] == 27))\n            result = i;         /* mark location of first questionable one */\n    }                           /*  or of first escape character (bad) */\n\n    return result;\n}\n\n\n\n\n\nstatic void wpng_cleanup(void)\n{\n    if (wpng_info.outfile) {\n        fclose(wpng_info.outfile);\n        wpng_info.outfile = NULL;\n    }\n\n    if (wpng_info.infile) {\n        fclose(wpng_info.infile);\n        wpng_info.infile = NULL;\n    }\n\n    if (wpng_info.image_data) {\n        free(wpng_info.image_data);\n        wpng_info.image_data = NULL;\n    }\n\n    if (wpng_info.row_pointers) {\n        free(wpng_info.row_pointers);\n        wpng_info.row_pointers = NULL;\n    }\n}\n\n\n\n\n#ifdef DOS_OS2_W32\n\nstatic char *dos_kbd_gets(char *buf, int len)\n{\n    int ch, count=0;\n\n    do {\n        buf[count++] = ch = getche();\n    } while (ch != '\\r' && count < len-1);\n\n    buf[count--] = '\\0';        /* terminate string */\n    if (buf[count] == '\\r')     /* Enter key makes CR, so change to newline */\n        buf[count] = '\\n';\n\n    fprintf(stderr, \"\\n\");      /* Enter key does *not* cause a newline */\n    fflush(stderr);\n\n    return buf;\n}\n\n#endif /* DOS_OS2_W32 */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/writepng.c",
    "content": "/*---------------------------------------------------------------------------\n\n   wpng - simple PNG-writing program                             writepng.c\n\n  ---------------------------------------------------------------------------\n\n      Copyright (c) 1998-2007 Greg Roelofs.  All rights reserved.\n\n      This software is provided \"as is,\" without warranty of any kind,\n      express or implied.  In no event shall the author or contributors\n      be held liable for any damages arising in any way from the use of\n      this software.\n\n      The contents of this file are DUAL-LICENSED.  You may modify and/or\n      redistribute this software according to the terms of one of the\n      following two licenses (at your option):\n\n\n      LICENSE 1 (\"BSD-like with advertising clause\"):\n\n      Permission is granted to anyone to use this software for any purpose,\n      including commercial applications, and to alter it and redistribute\n      it freely, subject to the following restrictions:\n\n      1. Redistributions of source code must retain the above copyright\n         notice, disclaimer, and this list of conditions.\n      2. Redistributions in binary form must reproduce the above copyright\n         notice, disclaimer, and this list of conditions in the documenta-\n         tion and/or other materials provided with the distribution.\n      3. All advertising materials mentioning features or use of this\n         software must display the following acknowledgment:\n\n            This product includes software developed by Greg Roelofs\n            and contributors for the book, \"PNG: The Definitive Guide,\"\n            published by O'Reilly and Associates.\n\n\n      LICENSE 2 (GNU GPL v2 or later):\n\n      This program is free software; you can redistribute it and/or modify\n      it under the terms of the GNU General Public License as published by\n      the Free Software Foundation; either version 2 of the License, or\n      (at your option) any later version.\n\n      This program is distributed in the hope that it will be useful,\n      but WITHOUT ANY WARRANTY; without even the implied warranty of\n      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n      GNU General Public License for more details.\n\n      You should have received a copy of the GNU General Public License\n      along with this program; if not, write to the Free Software Foundation,\n      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  ---------------------------------------------------------------------------*/\n\n\n#include <stdlib.h>     /* for exit() prototype */\n#include <zlib.h>\n\n#include \"png.h\"        /* libpng header, includes setjmp.h */\n#include \"writepng.h\"   /* typedefs, common macros, public prototypes */\n\n\n/* local prototype */\n\nstatic void writepng_error_handler(png_structp png_ptr, png_const_charp msg);\n\n\n\nvoid writepng_version_info(void)\n{\n  fprintf(stderr, \"   Compiled with libpng %s; using libpng %s.\\n\",\n    PNG_LIBPNG_VER_STRING, png_libpng_ver);\n  fprintf(stderr, \"   Compiled with zlib %s; using zlib %s.\\n\",\n    ZLIB_VERSION, zlib_version);\n}\n\n\n\n\n/* returns 0 for success, 2 for libpng problem, 4 for out of memory, 11 for\n *  unexpected pnmtype; note that outfile might be stdout */\n\nint writepng_init(mainprog_info *mainprog_ptr)\n{\n    png_structp  png_ptr;       /* note:  temporary variables! */\n    png_infop  info_ptr;\n    int color_type, interlace_type;\n\n\n    /* could also replace libpng warning-handler (final NULL), but no need: */\n\n    png_ptr = png_create_write_struct(png_get_libpng_ver(NULL), mainprog_ptr,\n      writepng_error_handler, NULL);\n    if (!png_ptr)\n        return 4;   /* out of memory */\n\n    info_ptr = png_create_info_struct(png_ptr);\n    if (!info_ptr) {\n        png_destroy_write_struct(&png_ptr, NULL);\n        return 4;   /* out of memory */\n    }\n\n\n    /* setjmp() must be called in every function that calls a PNG-writing\n     * libpng function, unless an alternate error handler was installed--\n     * but compatible error handlers must either use longjmp() themselves\n     * (as in this program) or some other method to return control to\n     * application code, so here we go: */\n\n    if (setjmp(mainprog_ptr->jmpbuf)) {\n        png_destroy_write_struct(&png_ptr, &info_ptr);\n        return 2;\n    }\n\n\n    /* make sure outfile is (re)opened in BINARY mode */\n\n    png_init_io(png_ptr, mainprog_ptr->outfile);\n\n\n    /* set the compression levels--in general, always want to leave filtering\n     * turned on (except for palette images) and allow all of the filters,\n     * which is the default; want 32K zlib window, unless entire image buffer\n     * is 16K or smaller (unknown here)--also the default; usually want max\n     * compression (NOT the default); and remaining compression flags should\n     * be left alone */\n\n    png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);\n/*\n    >> this is default for no filtering; Z_FILTERED is default otherwise:\n    png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY);\n    >> these are all defaults:\n    png_set_compression_mem_level(png_ptr, 8);\n    png_set_compression_window_bits(png_ptr, 15);\n    png_set_compression_method(png_ptr, 8);\n */\n\n\n    /* set the image parameters appropriately */\n\n    if (mainprog_ptr->pnmtype == 5)\n        color_type = PNG_COLOR_TYPE_GRAY;\n    else if (mainprog_ptr->pnmtype == 6)\n        color_type = PNG_COLOR_TYPE_RGB;\n    else if (mainprog_ptr->pnmtype == 8)\n        color_type = PNG_COLOR_TYPE_RGB_ALPHA;\n    else {\n        png_destroy_write_struct(&png_ptr, &info_ptr);\n        return 11;\n    }\n\n    interlace_type = mainprog_ptr->interlaced? PNG_INTERLACE_ADAM7 :\n                                               PNG_INTERLACE_NONE;\n\n    png_set_IHDR(png_ptr, info_ptr, mainprog_ptr->width, mainprog_ptr->height,\n      mainprog_ptr->sample_depth, color_type, interlace_type,\n      PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);\n\n    if (mainprog_ptr->gamma > 0.0)\n        png_set_gAMA(png_ptr, info_ptr, mainprog_ptr->gamma);\n\n    if (mainprog_ptr->have_bg) {   /* we know it's RGBA, not gray+alpha */\n        png_color_16  background;\n\n        background.red = mainprog_ptr->bg_red;\n        background.green = mainprog_ptr->bg_green;\n        background.blue = mainprog_ptr->bg_blue;\n        png_set_bKGD(png_ptr, info_ptr, &background);\n    }\n\n    if (mainprog_ptr->have_time) {\n        png_time  modtime;\n\n        png_convert_from_time_t(&modtime, mainprog_ptr->modtime);\n        png_set_tIME(png_ptr, info_ptr, &modtime);\n    }\n\n    if (mainprog_ptr->have_text) {\n        png_text  text[6];\n        int  num_text = 0;\n\n        if (mainprog_ptr->have_text & TEXT_TITLE) {\n            text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;\n            text[num_text].key = \"Title\";\n            text[num_text].text = mainprog_ptr->title;\n            ++num_text;\n        }\n        if (mainprog_ptr->have_text & TEXT_AUTHOR) {\n            text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;\n            text[num_text].key = \"Author\";\n            text[num_text].text = mainprog_ptr->author;\n            ++num_text;\n        }\n        if (mainprog_ptr->have_text & TEXT_DESC) {\n            text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;\n            text[num_text].key = \"Description\";\n            text[num_text].text = mainprog_ptr->desc;\n            ++num_text;\n        }\n        if (mainprog_ptr->have_text & TEXT_COPY) {\n            text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;\n            text[num_text].key = \"Copyright\";\n            text[num_text].text = mainprog_ptr->copyright;\n            ++num_text;\n        }\n        if (mainprog_ptr->have_text & TEXT_EMAIL) {\n            text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;\n            text[num_text].key = \"E-mail\";\n            text[num_text].text = mainprog_ptr->email;\n            ++num_text;\n        }\n        if (mainprog_ptr->have_text & TEXT_URL) {\n            text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;\n            text[num_text].key = \"URL\";\n            text[num_text].text = mainprog_ptr->url;\n            ++num_text;\n        }\n        png_set_text(png_ptr, info_ptr, text, num_text);\n    }\n\n\n    /* write all chunks up to (but not including) first IDAT */\n\n    png_write_info(png_ptr, info_ptr);\n\n\n    /* if we wanted to write any more text info *after* the image data, we\n     * would set up text struct(s) here and call png_set_text() again, with\n     * just the new data; png_set_tIME() could also go here, but it would\n     * have no effect since we already called it above (only one tIME chunk\n     * allowed) */\n\n\n    /* set up the transformations:  for now, just pack low-bit-depth pixels\n     * into bytes (one, two or four pixels per byte) */\n\n    png_set_packing(png_ptr);\n/*  png_set_shift(png_ptr, &sig_bit);  to scale low-bit-depth values */\n\n\n    /* make sure we save our pointers for use in writepng_encode_image() */\n\n    mainprog_ptr->png_ptr = png_ptr;\n    mainprog_ptr->info_ptr = info_ptr;\n\n\n    /* OK, that's all we need to do for now; return happy */\n\n    return 0;\n}\n\n\n\n\n\n/* returns 0 for success, 2 for libpng (longjmp) problem */\n\nint writepng_encode_image(mainprog_info *mainprog_ptr)\n{\n    png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;\n    png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;\n\n\n    /* as always, setjmp() must be called in every function that calls a\n     * PNG-writing libpng function */\n\n    if (setjmp(mainprog_ptr->jmpbuf)) {\n        png_destroy_write_struct(&png_ptr, &info_ptr);\n        mainprog_ptr->png_ptr = NULL;\n        mainprog_ptr->info_ptr = NULL;\n        return 2;\n    }\n\n\n    /* and now we just write the whole image; libpng takes care of interlacing\n     * for us */\n\n    png_write_image(png_ptr, mainprog_ptr->row_pointers);\n\n\n    /* since that's it, we also close out the end of the PNG file now--if we\n     * had any text or time info to write after the IDATs, second argument\n     * would be info_ptr, but we optimize slightly by sending NULL pointer: */\n\n    png_write_end(png_ptr, NULL);\n\n    return 0;\n}\n\n\n\n\n\n/* returns 0 if succeeds, 2 if libpng problem */\n\nint writepng_encode_row(mainprog_info *mainprog_ptr)  /* NON-interlaced only! */\n{\n    png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;\n    png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;\n\n\n    /* as always, setjmp() must be called in every function that calls a\n     * PNG-writing libpng function */\n\n    if (setjmp(mainprog_ptr->jmpbuf)) {\n        png_destroy_write_struct(&png_ptr, &info_ptr);\n        mainprog_ptr->png_ptr = NULL;\n        mainprog_ptr->info_ptr = NULL;\n        return 2;\n    }\n\n\n    /* image_data points at our one row of image data */\n\n    png_write_row(png_ptr, mainprog_ptr->image_data);\n\n    return 0;\n}\n\n\n\n\n\n/* returns 0 if succeeds, 2 if libpng problem */\n\nint writepng_encode_finish(mainprog_info *mainprog_ptr)   /* NON-interlaced! */\n{\n    png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;\n    png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;\n\n\n    /* as always, setjmp() must be called in every function that calls a\n     * PNG-writing libpng function */\n\n    if (setjmp(mainprog_ptr->jmpbuf)) {\n        png_destroy_write_struct(&png_ptr, &info_ptr);\n        mainprog_ptr->png_ptr = NULL;\n        mainprog_ptr->info_ptr = NULL;\n        return 2;\n    }\n\n\n    /* close out PNG file; if we had any text or time info to write after\n     * the IDATs, second argument would be info_ptr: */\n\n    png_write_end(png_ptr, NULL);\n\n    return 0;\n}\n\n\n\n\n\nvoid writepng_cleanup(mainprog_info *mainprog_ptr)\n{\n    png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;\n    png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;\n\n    if (png_ptr && info_ptr)\n        png_destroy_write_struct(&png_ptr, &info_ptr);\n}\n\n\n\n\n\nstatic void writepng_error_handler(png_structp png_ptr, png_const_charp msg)\n{\n    mainprog_info  *mainprog_ptr;\n\n    /* This function, aside from the extra step of retrieving the \"error\n     * pointer\" (below) and the fact that it exists within the application\n     * rather than within libpng, is essentially identical to libpng's\n     * default error handler.  The second point is critical:  since both\n     * setjmp() and longjmp() are called from the same code, they are\n     * guaranteed to have compatible notions of how big a jmp_buf is,\n     * regardless of whether _BSD_SOURCE or anything else has (or has not)\n     * been defined. */\n\n    fprintf(stderr, \"writepng libpng error: %s\\n\", msg);\n    fflush(stderr);\n\n    mainprog_ptr = png_get_error_ptr(png_ptr);\n    if (mainprog_ptr == NULL) {         /* we are completely hosed now */\n        fprintf(stderr,\n          \"writepng severe error:  jmpbuf not recoverable; terminating.\\n\");\n        fflush(stderr);\n        exit(99);\n    }\n\n    /* Now we have our data structure we can use the information in it\n     * to return control to our own higher level code (all the points\n     * where 'setjmp' is called in this file.)  This will work with other\n     * error handling mechanisms as well - libpng always calls png_error\n     * when it can proceed no further, thus, so long as the error handler\n     * is intercepted, application code can do its own error recovery.\n     */\n    longjmp(mainprog_ptr->jmpbuf, 1);\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/gregbook/writepng.h",
    "content": "/*---------------------------------------------------------------------------\n\n   wpng - simple PNG-writing program                             writepng.h\n\n  ---------------------------------------------------------------------------\n\n      Copyright (c) 1998-2007 Greg Roelofs.  All rights reserved.\n\n      This software is provided \"as is,\" without warranty of any kind,\n      express or implied.  In no event shall the author or contributors\n      be held liable for any damages arising in any way from the use of\n      this software.\n\n      The contents of this file are DUAL-LICENSED.  You may modify and/or\n      redistribute this software according to the terms of one of the\n      following two licenses (at your option):\n\n\n      LICENSE 1 (\"BSD-like with advertising clause\"):\n\n      Permission is granted to anyone to use this software for any purpose,\n      including commercial applications, and to alter it and redistribute\n      it freely, subject to the following restrictions:\n\n      1. Redistributions of source code must retain the above copyright\n         notice, disclaimer, and this list of conditions.\n      2. Redistributions in binary form must reproduce the above copyright\n         notice, disclaimer, and this list of conditions in the documenta-\n         tion and/or other materials provided with the distribution.\n      3. All advertising materials mentioning features or use of this\n         software must display the following acknowledgment:\n\n            This product includes software developed by Greg Roelofs\n            and contributors for the book, \"PNG: The Definitive Guide,\"\n            published by O'Reilly and Associates.\n\n\n      LICENSE 2 (GNU GPL v2 or later):\n\n      This program is free software; you can redistribute it and/or modify\n      it under the terms of the GNU General Public License as published by\n      the Free Software Foundation; either version 2 of the License, or\n      (at your option) any later version.\n\n      This program is distributed in the hope that it will be useful,\n      but WITHOUT ANY WARRANTY; without even the implied warranty of\n      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n      GNU General Public License for more details.\n\n      You should have received a copy of the GNU General Public License\n      along with this program; if not, write to the Free Software Foundation,\n      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  ---------------------------------------------------------------------------*/\n\n#ifndef TRUE\n#  define TRUE 1\n#  define FALSE 0\n#endif\n\n#ifndef MAX\n#  define MAX(a,b)  ((a) > (b)? (a) : (b))\n#  define MIN(a,b)  ((a) < (b)? (a) : (b))\n#endif\n\n#ifdef DEBUG\n#  define Trace(x)  {fprintf x ; fflush(stderr); fflush(stdout);}\n#else\n#  define Trace(x)  ;\n#endif\n\n#define TEXT_TITLE    0x01\n#define TEXT_AUTHOR   0x02\n#define TEXT_DESC     0x04\n#define TEXT_COPY     0x08\n#define TEXT_EMAIL    0x10\n#define TEXT_URL      0x20\n\n#define TEXT_TITLE_OFFSET        0\n#define TEXT_AUTHOR_OFFSET      72\n#define TEXT_COPY_OFFSET     (2*72)\n#define TEXT_EMAIL_OFFSET    (3*72)\n#define TEXT_URL_OFFSET      (4*72)\n#define TEXT_DESC_OFFSET     (5*72)\n\ntypedef unsigned char   uch;\ntypedef unsigned short  ush;\ntypedef unsigned long   ulg;\n\ntypedef struct _mainprog_info {\n    double gamma;\n    long width;\n    long height;\n    time_t modtime;\n    FILE *infile;\n    FILE *outfile;\n    void *png_ptr;\n    void *info_ptr;\n    uch *image_data;\n    uch **row_pointers;\n    char *title;\n    char *author;\n    char *desc;\n    char *copyright;\n    char *email;\n    char *url;\n    int filter;    /* command-line-filter flag, not PNG row filter! */\n    int pnmtype;\n    int sample_depth;\n    int interlaced;\n    int have_bg;\n    int have_time;\n    int have_text;\n    jmp_buf jmpbuf;\n    uch bg_red;\n    uch bg_green;\n    uch bg_blue;\n} mainprog_info;\n\n\n/* prototypes for public functions in writepng.c */\n\nvoid writepng_version_info(void);\n\nint writepng_init(mainprog_info *mainprog_ptr);\n\nint writepng_encode_image(mainprog_info *mainprog_ptr);\n\nint writepng_encode_row(mainprog_info *mainprog_ptr);\n\nint writepng_encode_finish(mainprog_info *mainprog_ptr);\n\nvoid writepng_cleanup(mainprog_info *mainprog_ptr);\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/intel/INSTALL",
    "content": "\nCopyright (c) 2016 Google, Inc.\n\nTo enable SSE support, manually edit configure.ac and Makefile.am, following\nthe instructions in the configure.ac.patch and Makefile.am.patch files. \n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/intel/Makefile.am.patch",
    "content": "\n#\n# Copyright (c) 2016 Google, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n#\n\n# In order to compile Intel SSE optimizations for libpng, please add\n# the following code to Makefile.am directly beneath the\n# \"if PNG_ARM_NEON ... endif\" statement.\n\nif PNG_INTEL_SSE\nlibpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += contrib/intel/intel_init.c\\\n    contrib/intel/filter_sse2_intrinsics.c\nendif\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/intel/configure.ac.patch",
    "content": "#\n# Copyright (c) 2016 Google, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n#\n\n# In order to compile Intel SSE optimizations for libpng, please add\n# the following code to configure.ac under HOST SPECIFIC OPTIONS\n# directly beneath the section for ARM.\n\n# INTEL\n# ===\n#\n# INTEL SSE (SIMD) support.\n\nAC_ARG_ENABLE([intel-sse],\n   AS_HELP_STRING([[[--enable-intel-sse]]],\n      [Enable Intel SSE optimizations: =no/off, yes/on:]\n      [no/off: disable the optimizations;]\n      [yes/on: enable the optimizations.]\n      [If not specified: determined by the compiler.]),\n   [case \"$enableval\" in\n      no|off)\n         # disable the default enabling:\n         AC_DEFINE([PNG_INTEL_SSE_OPT], [0],\n                   [Disable Intel SSE optimizations])\n         # Prevent inclusion of the assembler files below:\n         enable_intel_sse=no;;\n      yes|on)\n         AC_DEFINE([PNG_INTEL_SSE_OPT], [1],\n                   [Enable Intel SSE optimizations]);;\n      *)\n         AC_MSG_ERROR([--enable-intel-sse=${enable_intel_sse}: invalid value])\n   esac])\n\n# Add Intel specific files to all builds where the host_cpu is Intel ('x86*')\n# or where Intel optimizations were explicitly requested (this allows a\n# fallback if a future host CPU does not match 'x86*')\nAM_CONDITIONAL([PNG_INTEL_SSE],\n   [test \"$enable_intel_sse\" != 'no' &&\n    case \"$host_cpu\" in\n      i?86|x86_64) :;;\n      *)    test \"$enable_intel_sse\" != '';;\n    esac])\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/intel/filter_sse2_intrinsics.c",
    "content": "\n/* filter_sse2_intrinsics.c - SSE2 optimized filter functions\n *\n * Copyright (c) 2016 Google, Inc.\n *\n * Last changed in libpng 1.6.22 [(PENDING RELEASE)]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n#include \"../../pngpriv.h\"\n\n#ifdef PNG_READ_SUPPORTED\n\n#if PNG_INTEL_SSE_IMPLEMENTATION > 0\n\n#include <immintrin.h>\n\n// Functions in this file look at most 3 pixels (a,b,c) to predict the 4th (d).\n// They're positioned like this:\n//    prev:  c b\n//    row:   a d\n// The Sub filter predicts d=a, Avg d=(a+b)/2, and Paeth predicts d to be\n// whichever of a, b, or c is closest to p=a+b-c.\n\nstatic __m128i load3(const void* p) {\n   png_uint_32 packed;\n   memcpy(&packed, p, 3);\n   return _mm_cvtsi32_si128(packed);\n}\n\nstatic __m128i load4(const void* p) {\n   return _mm_cvtsi32_si128(*(const int*)p);\n}\n\nstatic void store3(void* p, __m128i v) {\n   png_uint_32 packed = _mm_cvtsi128_si32(v);\n   memcpy(p, &packed, 3);\n}\n\nstatic void store4(void* p, __m128i v) {\n   *(int*)p = _mm_cvtsi128_si32(v);\n}\n\nvoid png_read_filter_row_sub3_sse2(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev)\n{\n   // The Sub filter predicts each pixel as the previous pixel, a.\n   // There is no pixel to the left of the first pixel.  It's encoded directly.\n   // That works with our main loop if we just say that left pixel was zero.\n   __m128i a, d = _mm_setzero_si128();\n\n   int rb = row_info->rowbytes;\n   while (rb > 0) {\n      a = d; d = load3(row);\n      d = _mm_add_epi8(d, a);\n      store3(row, d);\n\n      row += 3;\n      rb  -= 3;\n   }\n}\n\nvoid png_read_filter_row_sub4_sse2(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev)\n{\n   // The Sub filter predicts each pixel as the previous pixel, a.\n   // There is no pixel to the left of the first pixel.  It's encoded directly.\n   // That works with our main loop if we just say that left pixel was zero.\n   __m128i a, d = _mm_setzero_si128();\n\n   int rb = row_info->rowbytes;\n   while (rb > 0) {\n      a = d; d = load4(row);\n      d = _mm_add_epi8(d, a);\n      store4(row, d);\n\n      row += 4;\n      rb  -= 4;\n   }\n}\n\nvoid png_read_filter_row_avg3_sse2(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev)\n{\n   // The Avg filter predicts each pixel as the (truncated) average of a and b.\n   // There's no pixel to the left of the first pixel.  Luckily, it's\n   // predicted to be half of the pixel above it.  So again, this works\n   // perfectly with our loop if we make sure a starts at zero.\n   const __m128i zero = _mm_setzero_si128();\n   __m128i    b;\n   __m128i a, d = zero;\n\n   int rb = row_info->rowbytes;\n   while (rb > 0) {\n             b = load3(prev);\n      a = d; d = load3(row );\n\n      // PNG requires a truncating average, so we can't just use _mm_avg_epu8...\n      __m128i avg = _mm_avg_epu8(a,b);\n      // ...but we can fix it up by subtracting off 1 if it rounded up.\n      avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b),\n                                            _mm_set1_epi8(1)));\n\n      d = _mm_add_epi8(d, avg);\n      store3(row, d);\n\n      prev += 3;\n      row  += 3;\n      rb   -= 3;\n   }\n}\n\nvoid png_read_filter_row_avg4_sse2(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev)\n{\n   // The Avg filter predicts each pixel as the (truncated) average of a and b.\n   // There's no pixel to the left of the first pixel.  Luckily, it's\n   // predicted to be half of the pixel above it.  So again, this works\n   // perfectly with our loop if we make sure a starts at zero.\n   const __m128i zero = _mm_setzero_si128();\n   __m128i    b;\n   __m128i a, d = zero;\n\n   int rb = row_info->rowbytes;\n   while (rb > 0) {\n             b = load4(prev);\n      a = d; d = load4(row );\n\n      // PNG requires a truncating average, so we can't just use _mm_avg_epu8...\n      __m128i avg = _mm_avg_epu8(a,b);\n      // ...but we can fix it up by subtracting off 1 if it rounded up.\n      avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b),\n                                            _mm_set1_epi8(1)));\n\n      d = _mm_add_epi8(d, avg);\n      store4(row, d);\n\n      prev += 4;\n      row  += 4;\n      rb   -= 4;\n   }\n}\n\n// Returns |x| for 16-bit lanes.\nstatic __m128i abs_i16(__m128i x) {\n#if PNG_INTEL_SSE_IMPLEMENTATION >= 2\n   return _mm_abs_epi16(x);\n#else\n   // Read this all as, return x<0 ? -x : x.\n   // To negate two's complement, you flip all the bits then add 1.\n   __m128i is_negative = _mm_cmplt_epi16(x, _mm_setzero_si128());\n\n   // Flip negative lanes.\n   x = _mm_xor_si128(x, is_negative);\n\n   // +1 to negative lanes, else +0.\n   x = _mm_add_epi16(x, _mm_srli_epi16(is_negative, 15));\n   return x;\n#endif\n}\n\n// Bytewise c ? t : e.\nstatic __m128i if_then_else(__m128i c, __m128i t, __m128i e) {\n#if PNG_INTEL_SSE_IMPLEMENTATION >= 3\n   return _mm_blendv_epi8(e,t,c);\n#else\n   return _mm_or_si128(_mm_and_si128(c, t), _mm_andnot_si128(c, e));\n#endif\n}\n\nvoid png_read_filter_row_paeth3_sse2(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev)\n{\n   // Paeth tries to predict pixel d using the pixel to the left of it, a,\n   // and two pixels from the previous row, b and c:\n   //   prev: c b\n   //   row:  a d\n   // The Paeth function predicts d to be whichever of a, b, or c is nearest to\n   // p=a+b-c.\n\n   // The first pixel has no left context, and so uses an Up filter, p = b.\n   // This works naturally with our main loop's p = a+b-c if we force a and c\n   // to zero.\n   // Here we zero b and d, which become c and a respectively at the start of\n   // the loop.\n   const __m128i zero = _mm_setzero_si128();\n   __m128i c, b = zero,\n           a, d = zero;\n\n   int rb = row_info->rowbytes;\n   while (rb > 0) {\n      // It's easiest to do this math (particularly, deal with pc) with 16-bit\n      // intermediates.\n      c = b; b = _mm_unpacklo_epi8(load3(prev), zero);\n      a = d; d = _mm_unpacklo_epi8(load3(row ), zero);\n\n      // (p-a) == (a+b-c - a) == (b-c)\n      __m128i pa = _mm_sub_epi16(b,c);\n\n      // (p-b) == (a+b-c - b) == (a-c)\n      __m128i pb = _mm_sub_epi16(a,c);\n\n      // (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c)\n      __m128i pc = _mm_add_epi16(pa,pb);\n\n      pa = abs_i16(pa);  // |p-a|\n      pb = abs_i16(pb);  // |p-b|\n      pc = abs_i16(pc);  // |p-c|\n\n      __m128i smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));\n\n      // Paeth breaks ties favoring a over b over c.\n      __m128i nearest  = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,\n                         if_then_else(_mm_cmpeq_epi16(smallest, pb), b,\n                                                                     c));\n\n      // Note `_epi8`: we need addition to wrap modulo 255.\n      d = _mm_add_epi8(d, nearest);\n      store3(row, _mm_packus_epi16(d,d));\n\n      prev += 3;\n      row  += 3;\n      rb   -= 3;\n   }\n}\n\nvoid png_read_filter_row_paeth4_sse2(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev)\n{\n   // Paeth tries to predict pixel d using the pixel to the left of it, a,\n   // and two pixels from the previous row, b and c:\n   //   prev: c b\n   //   row:  a d\n   // The Paeth function predicts d to be whichever of a, b, or c is nearest to\n   // p=a+b-c.\n\n   // The first pixel has no left context, and so uses an Up filter, p = b.\n   // This works naturally with our main loop's p = a+b-c if we force a and c\n   // to zero.\n   // Here we zero b and d, which become c and a respectively at the start of\n   // the loop.\n   const __m128i zero = _mm_setzero_si128();\n   __m128i c, b = zero,\n           a, d = zero;\n\n   int rb = row_info->rowbytes;\n   while (rb > 0) {\n      // It's easiest to do this math (particularly, deal with pc) with 16-bit\n      // intermediates.\n      c = b; b = _mm_unpacklo_epi8(load4(prev), zero);\n      a = d; d = _mm_unpacklo_epi8(load4(row ), zero);\n\n      // (p-a) == (a+b-c - a) == (b-c)\n      __m128i pa = _mm_sub_epi16(b,c);\n\n      // (p-b) == (a+b-c - b) == (a-c)\n      __m128i pb = _mm_sub_epi16(a,c);\n\n      // (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c)\n      __m128i pc = _mm_add_epi16(pa,pb);\n\n      pa = abs_i16(pa);  // |p-a|\n      pb = abs_i16(pb);  // |p-b|\n      pc = abs_i16(pc);  // |p-c|\n\n      __m128i smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));\n\n      // Paeth breaks ties favoring a over b over c.\n      __m128i nearest  = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,\n                         if_then_else(_mm_cmpeq_epi16(smallest, pb), b,\n                                                                     c));\n\n      // Note `_epi8`: we need addition to wrap modulo 255.\n      d = _mm_add_epi8(d, nearest);\n      store4(row, _mm_packus_epi16(d,d));\n\n      prev += 4;\n      row  += 4;\n      rb   -= 4;\n   }\n}\n\n#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */\n#endif /* READ */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/intel/intel_init.c",
    "content": "\n/* intel_init.c - SSE2 optimized filter functions\n *\n * Copyright (c) 2016 Google, Inc.\n *\n * Last changed in libpng 1.6.22 [(PENDING RELEASE)]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n#include \"../../pngpriv.h\"\n\n#ifdef PNG_READ_SUPPORTED\n#if PNG_INTEL_SSE_IMPLEMENTATION > 0\n\nvoid\npng_init_filter_functions_sse2(png_structp pp, unsigned int bpp)\n{\n   // The techniques used to implement each of these filters in SSE operate on\n   // one pixel at a time.\n   // So they generally speed up 3bpp images about 3x, 4bpp images about 4x.\n   // They can scale up to 6 and 8 bpp images and down to 2 bpp images, \n   // but they'd not likely have any benefit for 1bpp images.\n   // Most of these can be implemented using only MMX and 64-bit registers,\n   // but they end up a bit slower than using the equally-ubiquitous SSE2.\n   if (bpp == 3)\n   {\n      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_sse2;\n      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_sse2;\n      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =\n         png_read_filter_row_paeth3_sse2;\n   }\n   else if (bpp == 4)\n   {\n      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_sse2;\n      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_sse2;\n      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =\n          png_read_filter_row_paeth4_sse2;\n   }\n\n   // No need optimize PNG_FILTER_VALUE_UP.  The compiler should autovectorize.\n}\n\n#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */\n#endif /* PNG_READ_SUPPORTED */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/libtests/fakepng.c",
    "content": "/* Fake a PNG - just write it out directly.\n *\n * COPYRIGHT: Written by John Cunningham Bowler, 2014.\n * To the extent possible under law, the author has waived all copyright and\n * related or neighboring rights to this work.  This work is published from:\n * United States.\n *\n */\n\n#include <stdio.h>\n#include <zlib.h> /* for crc32 */\n\nvoid\nput_uLong(uLong val)\n{\n   putchar(val >> 24);\n   putchar(val >> 16);\n   putchar(val >>  8);\n   putchar(val >>  0);\n}\n\nvoid\nput_chunk(const unsigned char *chunk, uInt length)\n{\n   uLong crc;\n\n   put_uLong(length-4); /* Exclude the tag */\n\n   fwrite(chunk, length, 1, stdout);\n\n   crc = crc32(0, Z_NULL, 0);\n   put_uLong(crc32(crc, chunk, length));\n}\n\nconst unsigned char signature[] =\n{\n   137, 80, 78, 71, 13, 10, 26, 10\n};\n\nconst unsigned char IHDR[] =\n{\n   73, 72, 68, 82, /* IHDR */\n   0, 0, 0, 1, /* width */\n   0, 0, 0, 1, /* height */\n   1, /* bit depth */\n   0, /* color type: greyscale */\n   0, /* compression method */\n   0, /* filter method */\n   0  /* interlace method: none */\n};\n\nconst unsigned char unknown[] =\n{\n   'u', 'n', 'K', 'n' /* \"unKn\" - private safe to copy */\n};\n\nint\nmain(void)\n{\n   fwrite(signature, sizeof signature, 1, stdout);\n   put_chunk(IHDR, sizeof IHDR);\n\n   for (;;)\n      put_chunk(unknown, sizeof unknown);\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/libtests/gentests.sh",
    "content": "#!/bin/sh\n#\n# Copyright (c) 2013 John Cunningham Bowler\n#\n# Last changed in libpng 1.6.0 [February 14, 2013]\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n#\n# Generate a set of PNG test images.  The images are generated in a\n# sub-directory called 'tests' by default, however a command line argument will\n# change that name.  The generation requires a built version of makepng in the\n# current directory.\n#\nusage(){\n   exec >&2\n   echo \"$0 [<directory>]\"\n   echo '  Generate a set of PNG test files in \"directory\" (\"tests\" by default)'\n   exit 1\n}\n\nmp=\"$PWD/makepng\"\ntest -x \"$mp\" || {\n   exec >&2\n   echo \"$0: the 'makepng' program must exist\"\n   echo \"  in the directory within which this program:\"\n   echo \"    $mp\"\n   echo \"  is executed\"\n   usage\n}\n\n# Just one argument: the directory\ntestdir=\"tests\"\ntest $# -gt 1 && {\n   testdir=\"$1\"\n   shift\n}\ntest $# -eq 0 || usage\n\n# Take care not to clobber something\nif test -e \"$testdir\"\nthen\n   test -d \"$testdir\" || usage\nelse\n   # mkdir -p isn't portable, so do the following\n   mkdir \"$testdir\" 2>/dev/null || mkdir -p \"$testdir\" || usage\nfi\n\n# This fails in a very satisfactory way if it's not accessible\ncd \"$testdir\"\n:>\"test$$.png\" || {\n   exec >&2\n   echo \"$testdir: directory not writable\"\n   usage\n}\nrm \"test$$.png\" || {\n   exec >&2\n   echo \"$testdir: you have create but not write privileges here.\"\n   echo \"  This is unexpected.  You have a spurion; \"'\"'\"test$$.png\"'\"'\".\"\n   echo \"  You need to remove this yourself.  Try a different directory.\"\n   exit 1\n}\n\n# Now call makepng ($mp) to create every file we can think of with a\n# reasonable name\ndoit(){\n   for gamma in \"\" --sRGB --linear --1.8\n   do\n      case \"$gamma\" in\n         \"\")\n            gname=;;\n         --sRGB)\n            gname=\"-srgb\";;\n         --linear)\n            gname=\"-lin\";;\n         --1.8)\n            gname=\"-18\";;\n         *)\n            gname=\"-$gamma\";;\n      esac\n      \"$mp\" $gamma \"$1\" \"$2\" \"test-$1-$2$gname.png\"\n   done\n}\n#\nfor ct in gray palette\ndo\n   for bd in 1 2 4 8\n   do\n      doit \"$ct\" \"$bd\"\n   done\ndone\n#\ndoit \"gray\" \"16\"\n#\nfor ct in gray-alpha rgb rgb-alpha\ndo\n   for bd in 8 16\n   do\n      doit \"$ct\" \"$bd\"\n   done\ndone\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/libtests/makepng.c",
    "content": "/* makepng.c */\n#define _ISOC99_SOURCE\n/* Copyright: */\n#define COPYRIGHT \"\\251 2013,2015 John Cunningham Bowler\"\n/*\n * Last changed in libpng 1.6.20 [November 24, 2015]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * Make a test PNG image.  The arguments are as follows:\n *\n *    makepng [--sRGB|--linear|--1.8] [--tRNS] [--nofilters] \\\n *       color-type bit-depth [file-name]\n *\n * The color-type may be numeric (and must match the numbers used by the PNG\n * specification) or one of the format names listed below.  The bit-depth is the\n * component bit depth, or the pixel bit-depth for a color-mapped image.\n *\n * Without any options no color-space information is written, with the options\n * an sRGB or the appropriate gAMA chunk is written.  \"1.8\" refers to the\n * display system used on older Apple computers to correct for high ambient\n * light levels in the viewing environment; it applies a transform of\n * approximately value^(1/1.45) to the color values and so a gAMA chunk of 65909\n * is written (1.45/2.2).\n *\n * The image data is generated internally.  Unless --color is given the images\n * used are as follows:\n *\n * 1 channel: a square image with a diamond, the least luminous colors are on\n *    the edge of the image, the most luminous in the center.\n *\n * 2 channels: the color channel increases in luminosity from top to bottom, the\n *    alpha channel increases in opacity from left to right.\n *\n * 3 channels: linear combinations of, from the top-left corner clockwise,\n *    black, green, white, red.\n *\n * 4 channels: linear combinations of, from the top-left corner clockwise,\n *    transparent, red, green, blue.\n *\n * For color-mapped images a four channel color-map is used and if --tRNS is\n * given the PNG file has a tRNS chunk, as follows:\n *\n * 1-bit: entry 0 is transparent-red, entry 1 is opaque-white\n * 2-bit: entry 0: transparent-green\n *        entry 1: 40%-red\n *        entry 2: 80%-blue\n *        entry 3: opaque-white\n * 4-bit: the 16 combinations of the 2-bit case\n * 8-bit: the 256 combinations of the 4-bit case\n *\n * The palette always has 2^bit-depth entries and the tRNS chunk one fewer.  The\n * image is the 1-channel diamond, but using palette index, not luminosity.\n *\n * For formats other than color-mapped ones if --tRNS is specified a tRNS chunk\n * is generated with all channels equal to the low bits of 0x0101.\n *\n * Image size is determined by the final pixel depth in bits, i.e. channels x\n * bit-depth, as follows:\n *\n * 8 bits or less:    64x64\n * 16 bits:           256x256\n * More than 16 bits: 1024x1024\n *\n * Row filtering is the libpng default but may be turned off (the 'none' filter\n * is used on every row) with the --nofilters option.\n *\n * The images are not interlaced.\n *\n * If file-name is given then the PNG is written to that file, else it is\n * written to stdout.  Notice that stdout is not supported on systems where, by\n * default, it assumes text output; this program makes no attempt to change the\n * text mode of stdout!\n *\n *    makepng --color=<color> ...\n *\n * If --color is given then the whole image has that color, color-mapped images\n * will have exactly one palette entry and all image files with be 16x16 in\n * size.  The color value is 1 to 4 decimal numbers as appropriate for the color\n * type.\n *\n *    makepng --small ...\n *\n * If --small is given the images are no larger than required to include every\n * possible pixel value for the format.\n *\n * For formats with pixels 8 bits or fewer in size the images consist of a\n * single row with 2^pixel-depth pixels, one of every possible value.\n *\n * For formats with 16-bit pixels a 256x256 image is generated containing every\n * possible pixel value.\n *\n * For larger pixel sizes a 256x256 image is generated where the first row\n * consists of each pixel that has identical byte values throughout the pixel\n * followed by rows where the byte values differ within the pixel.\n *\n * In all cases the pixel values are arranged in such a way that the SUB and UP\n * filters give byte sequences for maximal zlib compression.  By default (if\n * --nofilters is not given) the SUB filter is used on the first row and the UP\n * filter on all following rows.\n *\n * The --small option is meant to provide good test-case coverage, however the\n * images are not easy to examine visually.  Without the --small option the\n * images contain identical color values; the pixel values are adjusted\n * according to the gamma encoding with no gamma encoding being interpreted as\n * sRGB.\n *\n * LICENSING\n * =========\n *\n * This code is copyright of the authors, see the COPYRIGHT define above.  The\n * code is licensed as above, using the libpng license.  The code generates\n * images which are solely the product of the code; the options choose which of\n * the many possibilities to generate.  The images that result (but not the code\n * which generates them) are licensed as defined here:\n *\n * IMPORTANT: the COPYRIGHT #define must contain ISO-Latin-1 characters, the\n * IMAGE_LICENSING #define must contain UTF-8 characters.  The 'copyright'\n * symbol 0xA9U (\\251) in ISO-Latin-1 encoding and 0xC20xA9 (\\302\\251) in UTF-8.\n */\n#define IMAGE_LICENSING \"Dedicated to the public domain per Creative Commons \"\\\n    \"license \\\"CC0 1.0\\\"; https://creativecommons.org/publicdomain/zero/1.0/\"\n\n#include <stddef.h> /* for offsetof */\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <ctype.h>\n#include <math.h>\n#include <errno.h>\n#include <assert.h>\n#include <stdint.h>\n\n#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)\n#  include <config.h>\n#endif\n\n/* Define the following to use this test against your installed libpng, rather\n * than the one being built here:\n */\n#ifdef PNG_FREESTANDING_TESTS\n#  include <png.h>\n#else\n#  include \"../../png.h\"\n#endif\n\n#include <zlib.h>\n\n/* Work round for GCC complaints about casting a (double) function result to\n * an unsigned:\n */\nstatic unsigned int\nflooru(double d)\n{\n   d = floor(d);\n   return (unsigned int)d;\n}\n\nstatic png_byte\nfloorb(double d)\n{\n   d = floor(d);\n   return (png_byte)d;\n}\n\n/* This structure is used for inserting extra chunks (the --insert argument, not\n * documented above.)\n */\ntypedef struct chunk_insert\n{\n   struct chunk_insert *next;\n   void               (*insert)(png_structp, png_infop, int, png_charpp);\n   int                  nparams;\n   png_charp            parameters[1];\n} chunk_insert;\n\nstatic unsigned int\nchannels_of_type(int color_type)\n{\n   if (color_type & PNG_COLOR_MASK_PALETTE)\n      return 1;\n\n   else\n   {\n      int channels = 1;\n\n      if (color_type & PNG_COLOR_MASK_COLOR)\n         channels = 3;\n\n      if (color_type & PNG_COLOR_MASK_ALPHA)\n         return channels + 1;\n\n      else\n         return channels;\n   }\n}\n\nstatic unsigned int\npixel_depth_of_type(int color_type, int bit_depth)\n{\n   return channels_of_type(color_type) * bit_depth;\n}\n\nstatic unsigned int\nimage_size_of_type(int color_type, int bit_depth, unsigned int *colors,\n   int small)\n{\n   if (*colors)\n      return 16;\n\n   else\n   {\n      int pixel_depth = pixel_depth_of_type(color_type, bit_depth);\n\n      if (small)\n      {\n         if (pixel_depth <= 8) /* there will be one row */\n            return 1 << pixel_depth;\n\n         else\n            return 256;\n      }\n\n      else if (pixel_depth < 8)\n         return 64;\n\n      else if (pixel_depth > 16)\n         return 1024;\n\n      else\n         return 256;\n   }\n}\n\nstatic void\nset_color(png_colorp color, png_bytep trans, unsigned int red,\n   unsigned int green, unsigned int blue, unsigned int alpha,\n   png_const_bytep gamma_table)\n{\n   color->red = gamma_table[red];\n   color->green = gamma_table[green];\n   color->blue = gamma_table[blue];\n   *trans = (png_byte)alpha;\n}\n\nstatic int\ngenerate_palette(png_colorp palette, png_bytep trans, int bit_depth,\n   png_const_bytep gamma_table, unsigned int *colors)\n{\n   /*\n    * 1-bit: entry 0 is transparent-red, entry 1 is opaque-white\n    * 2-bit: entry 0: transparent-green\n    *        entry 1: 40%-red\n    *        entry 2: 80%-blue\n    *        entry 3: opaque-white\n    * 4-bit: the 16 combinations of the 2-bit case\n    * 8-bit: the 256 combinations of the 4-bit case\n    */\n   switch (colors[0])\n   {\n      default:\n         fprintf(stderr, \"makepng: --colors=...: invalid count %u\\n\",\n            colors[0]);\n         exit(1);\n\n      case 1:\n         set_color(palette+0, trans+0, colors[1], colors[1], colors[1], 255,\n            gamma_table);\n         return 1;\n\n      case 2:\n         set_color(palette+0, trans+0, colors[1], colors[1], colors[1],\n            colors[2], gamma_table);\n         return 1;\n\n      case 3:\n         set_color(palette+0, trans+0, colors[1], colors[2], colors[3], 255,\n            gamma_table);\n         return 1;\n\n      case 4:\n         set_color(palette+0, trans+0, colors[1], colors[2], colors[3],\n            colors[4], gamma_table);\n         return 1;\n\n      case 0:\n         if (bit_depth == 1)\n         {\n            set_color(palette+0, trans+0, 255, 0, 0, 0, gamma_table);\n            set_color(palette+1, trans+1, 255, 255, 255, 255, gamma_table);\n            return 2;\n         }\n\n         else\n         {\n            unsigned int size = 1U << (bit_depth/2); /* 2, 4 or 16 */\n            unsigned int x, y;\n            volatile unsigned int ip = 0;\n\n            for (x=0; x<size; ++x) for (y=0; y<size; ++y)\n            {\n               ip = x + (size * y);\n\n               /* size is at most 16, so the scaled value below fits in 16 bits\n                */\n#              define interp(pos, c1, c2) ((pos * c1) + ((size-pos) * c2))\n#              define xyinterp(x, y, c1, c2, c3, c4) (((size * size / 2) +\\\n                  (interp(x, c1, c2) * y + (size-y) * interp(x, c3, c4))) /\\\n                  (size*size))\n\n               set_color(palette+ip, trans+ip,\n                  /* color:    green, red,blue,white */\n                  xyinterp(x, y,   0, 255,   0, 255),\n                  xyinterp(x, y, 255,   0,   0, 255),\n                  xyinterp(x, y,   0,   0, 255, 255),\n                  /* alpha:        0, 102, 204, 255) */\n                  xyinterp(x, y,   0, 102, 204, 255),\n                  gamma_table);\n            }\n\n            return ip+1;\n         }\n   }\n}\n\nstatic void\nset_value(png_bytep row, size_t rowbytes, png_uint_32 x, unsigned int bit_depth,\n   png_uint_32 value, png_const_bytep gamma_table, double conv)\n{\n   unsigned int mask = (1U << bit_depth)-1;\n\n   x *= bit_depth;  /* Maximum x is 4*1024, maximum bit_depth is 16 */\n\n   if (value <= mask)\n   {\n      png_uint_32 offset = x >> 3;\n\n      if (offset < rowbytes && (bit_depth < 16 || offset+1 < rowbytes))\n      {\n         row += offset;\n\n         switch (bit_depth)\n         {\n            case 1:\n            case 2:\n            case 4:\n               /* Don't gamma correct - values get smashed */\n               {\n                  unsigned int shift = (8 - bit_depth) - (x & 0x7U);\n\n                  mask <<= shift;\n                  value = (value << shift) & mask;\n                  *row = (png_byte)((*row & ~mask) | value);\n               }\n               return;\n\n            default:\n               fprintf(stderr, \"makepng: bad bit depth (internal error)\\n\");\n               exit(1);\n\n            case 16:\n               value = flooru(65535*pow(value/65535.,conv)+.5);\n               *row++ = (png_byte)(value >> 8);\n               *row = (png_byte)value;\n               return;\n\n            case 8:\n               *row = gamma_table[value];\n               return;\n         }\n      }\n\n      else\n      {\n         fprintf(stderr, \"makepng: row buffer overflow (internal error)\\n\");\n         exit(1);\n      }\n   }\n\n   else\n   {\n      fprintf(stderr, \"makepng: component overflow (internal error)\\n\");\n      exit(1);\n   }\n}\n\nstatic int /* filter mask for row */\ngenerate_row(png_bytep row, size_t rowbytes, unsigned int y, int color_type,\n   int bit_depth, png_const_bytep gamma_table, double conv,\n   unsigned int *colors, int small)\n{\n   int filters = 0; /* file *MASK*, 0 means the default, not NONE */\n   png_uint_32 size_max =\n      image_size_of_type(color_type, bit_depth, colors, small)-1;\n   png_uint_32 depth_max = (1U << bit_depth)-1; /* up to 65536 */\n\n   if (colors[0] == 0) if (small)\n   {\n      unsigned int pixel_depth = pixel_depth_of_type(color_type, bit_depth);\n\n      /* For pixel depths less than 16 generate a single row containing all the\n       * possible pixel values.  For 16 generate all 65536 byte pair\n       * combinations in a 256x256 pixel array.\n       */\n      switch (pixel_depth)\n      {\n         case 1:\n            assert(y == 0 && rowbytes == 1 && size_max == 1);\n            row[0] = 0x6CU; /* binary: 01101100, only top 2 bits used */\n            filters = PNG_FILTER_NONE;\n            break;\n\n         case 2:\n            assert(y == 0 && rowbytes == 1 && size_max == 3);\n            row[0] = 0x1BU; /* binary 00011011, all bits used */\n            filters = PNG_FILTER_NONE;\n            break;\n\n         case 4:\n            assert(y == 0 && rowbytes == 8 && size_max == 15);\n            row[0] = 0x01U;\n            row[1] = 0x23U; /* SUB gives 0x22U for all following bytes */\n            row[2] = 0x45U;\n            row[3] = 0x67U;\n            row[4] = 0x89U;\n            row[5] = 0xABU;\n            row[6] = 0xCDU;\n            row[7] = 0xEFU;\n            filters = PNG_FILTER_SUB;\n            break;\n\n         case 8:\n            /* The row will have all the pixel values in order starting with\n             * '1', the SUB filter will change every byte into '1' (including\n             * the last, which generates pixel value '0').  Since the SUB filter\n             * has value 1 this should result in maximum compression.\n             */\n            assert(y == 0 && rowbytes == 256 && size_max == 255);\n            for (;;)\n            {\n               row[size_max] = 0xFFU & (size_max+1);\n               if (size_max == 0)\n                  break;\n               --size_max;\n            }\n            filters = PNG_FILTER_SUB;\n            break;\n\n         case 16:\n            /* Rows are generated such that each row has a constant difference\n             * between the first and second byte of each pixel and so that the\n             * difference increases by 1 at each row.  The rows start with the\n             * first byte value of 0 and the value increases to 255 across the\n             * row.\n             *\n             * The difference starts at 1, so the first row is:\n             *\n             *     0 1 1 2 2 3 3 4 ... 254 255 255 0\n             *\n             * This means that running the SUB filter on the first row produces:\n             *\n             *   [SUB==1] 0 1 0 1 0 1...\n             *\n             * Then the difference is 2 on the next row, giving:\n             *\n             *    0 2 1 3 2 4 3 5 ... 254 0 255 1\n             *\n             * When the UP filter is run on this libpng produces:\n             *\n             *   [UP ==2] 0 1 0 1 0 1...\n             *\n             * And so on for all the remain rows to the final two * rows:\n             *\n             *    row 254: 0 255 1 0 2 1 3 2 4 3 ... 254 253 255 254\n             *    row 255: 0   0 1 1 2 2 3 3 4 4 ... 254 254 255 255\n             */\n            assert(rowbytes == 512 && size_max == 255);\n            for (;;)\n            {\n               row[2*size_max  ] = 0xFFU & size_max;\n               row[2*size_max+1] = 0xFFU & (size_max+y+1);\n               if (size_max == 0)\n                  break;\n               --size_max;\n            }\n            /* The first row must include PNG_FILTER_UP so that libpng knows we\n             * need to keep it for the following row:\n             */\n            filters = (y == 0 ? PNG_FILTER_SUB+PNG_FILTER_UP : PNG_FILTER_UP);\n            break;\n\n         case 24:\n         case 32:\n         case 48:\n         case 64:\n            /* The rows are filled by an alogorithm similar to the above, in the\n             * first row pixel bytes are all equal, increasing from 0 by 1 for\n             * each pixel.  In the second row the bytes within a pixel are\n             * incremented 1,3,5,7,... from the previous row byte.  Using an odd\n             * number ensures all the possible byte values are used.\n             */\n            assert(size_max == 255 && rowbytes == 256*(pixel_depth>>3));\n            pixel_depth >>= 3; /* now in bytes */\n            while (rowbytes > 0)\n            {\n               const size_t pixel_index = --rowbytes/pixel_depth;\n\n               if (y == 0)\n                  row[rowbytes] = 0xFFU & pixel_index;\n\n               else\n               {\n                  const size_t byte_offset =\n                     rowbytes - pixel_index * pixel_depth;\n\n                  row[rowbytes] =\n                     0xFFU & (pixel_index + (byte_offset * 2*y) + 1);\n               }\n            }\n            filters = (y == 0 ? PNG_FILTER_SUB+PNG_FILTER_UP : PNG_FILTER_UP);\n            break;\n\n         default:\n            assert(0/*NOT REACHED*/);\n      }\n   }\n\n   else switch (channels_of_type(color_type))\n   {\n   /* 1 channel: a square image with a diamond, the least luminous colors are on\n    *    the edge of the image, the most luminous in the center.\n    */\n      case 1:\n         {\n            png_uint_32 x;\n            png_uint_32 base = 2*size_max - abs(2*y-size_max);\n\n            for (x=0; x<=size_max; ++x)\n            {\n               png_uint_32 luma = base - abs(2*x-size_max);\n\n               /* 'luma' is now in the range 0..2*size_max, we need\n                * 0..depth_max\n                */\n               luma = (luma*depth_max + size_max) / (2*size_max);\n               set_value(row, rowbytes, x, bit_depth, luma, gamma_table, conv);\n            }\n         }\n         break;\n\n   /* 2 channels: the color channel increases in luminosity from top to bottom,\n    *    the alpha channel increases in opacity from left to right.\n    */\n      case 2:\n         {\n            png_uint_32 alpha = (depth_max * y * 2 + size_max) / (2 * size_max);\n            png_uint_32 x;\n\n            for (x=0; x<=size_max; ++x)\n            {\n               set_value(row, rowbytes, 2*x, bit_depth,\n                  (depth_max * x * 2 + size_max) / (2 * size_max), gamma_table,\n                  conv);\n               set_value(row, rowbytes, 2*x+1, bit_depth, alpha, gamma_table,\n                  conv);\n            }\n         }\n         break;\n\n   /* 3 channels: linear combinations of, from the top-left corner clockwise,\n    *    black, green, white, red.\n    */\n      case 3:\n         {\n            /* x0: the black->red scale (the value of the red component) at the\n             *     start of the row (blue and green are 0).\n             * x1: the green->white scale (the value of the red and blue\n             *     components at the end of the row; green is depth_max).\n             */\n            png_uint_32 Y = (depth_max * y * 2 + size_max) / (2 * size_max);\n            png_uint_32 x;\n\n            /* Interpolate x/depth_max from start to end:\n             *\n             *        start end         difference\n             * red:     Y    Y            0\n             * green:   0   depth_max   depth_max\n             * blue:    0    Y            Y\n             */\n            for (x=0; x<=size_max; ++x)\n            {\n               set_value(row, rowbytes, 3*x+0, bit_depth, /* red */ Y,\n                     gamma_table, conv);\n               set_value(row, rowbytes, 3*x+1, bit_depth, /* green */\n                  (depth_max * x * 2 + size_max) / (2 * size_max),\n                  gamma_table, conv);\n               set_value(row, rowbytes, 3*x+2, bit_depth, /* blue */\n                  (Y * x * 2 + size_max) / (2 * size_max),\n                  gamma_table, conv);\n            }\n         }\n         break;\n\n   /* 4 channels: linear combinations of, from the top-left corner clockwise,\n    *    transparent, red, green, blue.\n    */\n      case 4:\n         {\n            /* x0: the transparent->blue scale (the value of the blue and alpha\n             *     components) at the start of the row (red and green are 0).\n             * x1: the red->green scale (the value of the red and green\n             *     components at the end of the row; blue is 0 and alpha is\n             *     depth_max).\n             */\n            png_uint_32 Y = (depth_max * y * 2 + size_max) / (2 * size_max);\n            png_uint_32 x;\n\n            /* Interpolate x/depth_max from start to end:\n             *\n             *        start    end       difference\n             * red:     0   depth_max-Y depth_max-Y\n             * green:   0       Y             Y\n             * blue:    Y       0            -Y\n             * alpha:   Y    depth_max  depth_max-Y\n             */\n            for (x=0; x<=size_max; ++x)\n            {\n               set_value(row, rowbytes, 4*x+0, bit_depth, /* red */\n                  ((depth_max-Y) * x * 2 + size_max) / (2 * size_max),\n                  gamma_table, conv);\n               set_value(row, rowbytes, 4*x+1, bit_depth, /* green */\n                  (Y * x * 2 + size_max) / (2 * size_max),\n                  gamma_table, conv);\n               set_value(row, rowbytes, 4*x+2, bit_depth, /* blue */\n                  Y - (Y * x * 2 + size_max) / (2 * size_max),\n                  gamma_table, conv);\n               set_value(row, rowbytes, 4*x+3, bit_depth, /* alpha */\n                  Y + ((depth_max-Y) * x * 2 + size_max) / (2 * size_max),\n                  gamma_table, conv);\n            }\n         }\n         break;\n\n      default:\n         fprintf(stderr, \"makepng: internal bad channel count\\n\");\n         exit(2);\n   }\n\n   else if (color_type & PNG_COLOR_MASK_PALETTE)\n   {\n      /* Palette with fixed color: the image rows are all 0 and the image width\n       * is 16.\n       */\n      memset(row, 0, rowbytes);\n   }\n\n   else if (colors[0] == channels_of_type(color_type))\n      switch (channels_of_type(color_type))\n      {\n         case 1:\n            {\n               const png_uint_32 luma = colors[1];\n               png_uint_32 x;\n\n               for (x=0; x<=size_max; ++x)\n                  set_value(row, rowbytes, x, bit_depth, luma, gamma_table,\n                     conv);\n            }\n            break;\n\n         case 2:\n            {\n               const png_uint_32 luma = colors[1];\n               const png_uint_32 alpha = colors[2];\n               png_uint_32 x;\n\n               for (x=0; x<size_max; ++x)\n               {\n                  set_value(row, rowbytes, 2*x, bit_depth, luma, gamma_table,\n                     conv);\n                  set_value(row, rowbytes, 2*x+1, bit_depth, alpha, gamma_table,\n                     conv);\n               }\n            }\n            break;\n\n         case 3:\n            {\n               const png_uint_32 red = colors[1];\n               const png_uint_32 green = colors[2];\n               const png_uint_32 blue = colors[3];\n               png_uint_32 x;\n\n               for (x=0; x<=size_max; ++x)\n               {\n                  set_value(row, rowbytes, 3*x+0, bit_depth, red, gamma_table,\n                     conv);\n                  set_value(row, rowbytes, 3*x+1, bit_depth, green, gamma_table,\n                     conv);\n                  set_value(row, rowbytes, 3*x+2, bit_depth, blue, gamma_table,\n                     conv);\n               }\n            }\n            break;\n\n         case 4:\n            {\n               const png_uint_32 red = colors[1];\n               const png_uint_32 green = colors[2];\n               const png_uint_32 blue = colors[3];\n               const png_uint_32 alpha = colors[4];\n               png_uint_32 x;\n\n               for (x=0; x<=size_max; ++x)\n               {\n                  set_value(row, rowbytes, 4*x+0, bit_depth, red, gamma_table,\n                     conv);\n                  set_value(row, rowbytes, 4*x+1, bit_depth, green, gamma_table,\n                     conv);\n                  set_value(row, rowbytes, 4*x+2, bit_depth, blue, gamma_table,\n                     conv);\n                  set_value(row, rowbytes, 4*x+3, bit_depth, alpha, gamma_table,\n                     conv);\n               }\n            }\n         break;\n\n         default:\n            fprintf(stderr, \"makepng: internal bad channel count\\n\");\n            exit(2);\n      }\n\n   else\n   {\n      fprintf(stderr,\n         \"makepng: --color: count(%u) does not match channels(%u)\\n\",\n         colors[0], channels_of_type(color_type));\n      exit(1);\n   }\n\n   return filters;\n}\n\n\nstatic void PNGCBAPI\nmakepng_warning(png_structp png_ptr, png_const_charp message)\n{\n   const char **ep = png_get_error_ptr(png_ptr);\n   const char *name;\n\n   if (ep != NULL && *ep != NULL)\n      name = *ep;\n\n   else\n      name = \"makepng\";\n\n  fprintf(stderr, \"%s: warning: %s\\n\", name, message);\n}\n\nstatic void PNGCBAPI\nmakepng_error(png_structp png_ptr, png_const_charp message)\n{\n   makepng_warning(png_ptr, message);\n   png_longjmp(png_ptr, 1);\n}\n\nstatic int /* 0 on success, else an error code */\nwrite_png(const char **name, FILE *fp, int color_type, int bit_depth,\n   volatile png_fixed_point gamma, chunk_insert * volatile insert,\n   unsigned int filters, unsigned int *colors, int small, int tRNS)\n{\n   png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,\n      name, makepng_error, makepng_warning);\n   volatile png_infop info_ptr = NULL;\n   volatile png_bytep row = NULL;\n\n   if (png_ptr == NULL)\n   {\n      fprintf(stderr, \"makepng: OOM allocating write structure\\n\");\n      return 1;\n   }\n\n   if (setjmp(png_jmpbuf(png_ptr)))\n   {\n      png_structp nv_ptr = png_ptr;\n      png_infop nv_info = info_ptr;\n\n      png_ptr = NULL;\n      info_ptr = NULL;\n      png_destroy_write_struct(&nv_ptr, &nv_info);\n      if (row != NULL) free(row);\n      return 1;\n   }\n\n   /* Allow benign errors so that we can write PNGs with errors */\n   png_set_benign_errors(png_ptr, 1/*allowed*/);\n\n   /* Max out the text compression level in an attempt to make the license\n    * small.   If --small then do the same for the IDAT.\n    */\n   if (small)\n      png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);\n\n   png_set_text_compression_level(png_ptr, Z_BEST_COMPRESSION);\n\n   png_init_io(png_ptr, fp);\n\n   info_ptr = png_create_info_struct(png_ptr);\n   if (info_ptr == NULL)\n      png_error(png_ptr, \"OOM allocating info structure\");\n\n   {\n      const unsigned int size =\n         image_size_of_type(color_type, bit_depth, colors, small);\n      unsigned int ysize;\n      png_fixed_point real_gamma = 45455; /* For sRGB */\n      png_byte gamma_table[256];\n      double conv;\n\n      /* Normally images are square, but with 'small' we want to simply generate\n       * all the pixel values, or all that we reasonably can:\n       */\n      if (small)\n      {\n         const unsigned int pixel_depth =\n            pixel_depth_of_type(color_type, bit_depth);\n\n         if (pixel_depth <= 8U)\n         {\n            assert(size == (1U<<pixel_depth));\n            ysize = 1U;\n         }\n\n         else\n         {\n            assert(size == 256U);\n            ysize = 256U;\n         }\n      }\n\n      else\n         ysize = size;\n\n      /* This function uses the libpng values used on read to carry extra\n       * information about the gamma:\n       */\n      if (gamma == PNG_GAMMA_MAC_18)\n         gamma = 65909;\n\n      else if (gamma > 0 && gamma < 1000)\n         gamma = PNG_FP_1;\n\n      if (gamma > 0)\n         real_gamma = gamma;\n\n      {\n         unsigned int i;\n\n         if (real_gamma == 45455) for (i=0; i<256; ++i)\n         {\n            gamma_table[i] = (png_byte)i;\n            conv = 1.;\n         }\n\n         else\n         {\n            /* Convert 'i' from sRGB (45455) to real_gamma, this makes\n             * the images look the same regardless of the gAMA chunk.\n             */\n            conv = real_gamma;\n            conv /= 45455;\n\n            gamma_table[0] = 0;\n\n            for (i=1; i<255; ++i)\n               gamma_table[i] = floorb(pow(i/255.,conv) * 255 + .5);\n\n            gamma_table[255] = 255;\n         }\n      }\n\n      png_set_IHDR(png_ptr, info_ptr, size, ysize, bit_depth, color_type,\n         PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);\n\n      if (color_type & PNG_COLOR_MASK_PALETTE)\n      {\n         int npalette;\n         png_color palette[256];\n         png_byte trans[256];\n\n         npalette = generate_palette(palette, trans, bit_depth, gamma_table,\n            colors);\n         png_set_PLTE(png_ptr, info_ptr, palette, npalette);\n\n         if (tRNS)\n            png_set_tRNS(png_ptr, info_ptr, trans, npalette-1,\n               NULL/*transparent color*/);\n\n         /* Reset gamma_table to prevent the image rows being changed */\n         for (npalette=0; npalette<256; ++npalette)\n            gamma_table[npalette] = (png_byte)npalette;\n      }\n\n      else if (tRNS)\n      {\n         png_color_16 col;\n\n         col.red = col.green = col.blue = col.gray =\n            0x0101U & ((1U<<bit_depth)-1U);\n         col.index = 0U;\n         png_set_tRNS(png_ptr, info_ptr, NULL/*trans*/, 1U, &col);\n      }\n\n      if (gamma == PNG_DEFAULT_sRGB)\n         png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_ABSOLUTE);\n\n      else if (gamma > 0) /* Else don't set color space information */\n      {\n         png_set_gAMA_fixed(png_ptr, info_ptr, real_gamma);\n\n         /* Just use the sRGB values here. */\n         png_set_cHRM_fixed(png_ptr, info_ptr,\n            /* color      x       y */\n            /* white */ 31270, 32900,\n            /* red   */ 64000, 33000,\n            /* green */ 30000, 60000,\n            /* blue  */ 15000,  6000\n         );\n      }\n\n      /* Insert extra information. */\n      while (insert != NULL)\n      {\n         insert->insert(png_ptr, info_ptr, insert->nparams, insert->parameters);\n         insert = insert->next;\n      }\n\n      /* Write the file header. */\n      png_write_info(png_ptr, info_ptr);\n\n      /* Restrict the filters */\n      png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, filters);\n\n      {\n#        ifdef PNG_WRITE_INTERLACING_SUPPORTED\n            int passes = png_set_interlace_handling(png_ptr);\n#        else /* !WRITE_INTERLACING */\n            int passes = 1;\n#        endif /* !WRITE_INTERLACING */\n         int pass;\n         png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);\n\n         row = malloc(rowbytes);\n\n         if (row == NULL)\n            png_error(png_ptr, \"OOM allocating row buffer\");\n\n         for (pass = 0; pass < passes; ++pass)\n         {\n            unsigned int y;\n\n            for (y=0; y<ysize; ++y)\n            {\n               unsigned int row_filters =\n                  generate_row(row, rowbytes, y, color_type, bit_depth,\n                        gamma_table, conv, colors, small);\n\n               if (row_filters != 0 && filters == PNG_ALL_FILTERS)\n                  png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, row_filters);\n\n               png_write_row(png_ptr, row);\n            }\n         }\n      }\n   }\n\n   /* Finish writing the file. */\n   png_write_end(png_ptr, info_ptr);\n\n   {\n      png_structp nv_ptr = png_ptr;\n      png_infop nv_info = info_ptr;\n\n      png_ptr = NULL;\n      info_ptr = NULL;\n      png_destroy_write_struct(&nv_ptr, &nv_info);\n   }\n   free(row);\n   return 0;\n}\n\n\nstatic size_t\nload_file(png_const_charp name, png_bytepp result)\n{\n   FILE *fp = tmpfile();\n\n   if (fp != NULL)\n   {\n      FILE *ip = fopen(name, \"rb\");\n\n      if (ip != NULL)\n      {\n         size_t total = 0;\n         int ch;\n\n         for (;;)\n         {\n            ch = getc(ip);\n            if (ch == EOF) break;\n            putc(ch, fp);\n            ++total;\n         }\n\n         if (ferror(ip))\n         {\n            perror(name);\n            fprintf(stderr, \"%s: read error\\n\", name);\n            (void)fclose(ip);\n         }\n\n         else\n         {\n            (void)fclose(ip);\n\n            if (ferror(fp))\n            {\n               perror(\"temporary file\");\n               fprintf(stderr, \"temporary file write error\\n\");\n            }\n\n            else\n            {\n               rewind(fp);\n\n               if (total > 0)\n               {\n                  /* Round up to a multiple of 4 here to allow an iCCP profile\n                   * to be padded to a 4x boundary.\n                   */\n                  png_bytep data = malloc((total+3)&~3);\n\n                  if (data != NULL)\n                  {\n                     size_t new_size = 0;\n\n                     for (;;)\n                     {\n                        ch = getc(fp);\n                        if (ch == EOF) break;\n                        data[new_size++] = (png_byte)ch;\n                     }\n\n                     if (ferror(fp) || new_size != total)\n                     {\n                        perror(\"temporary file\");\n                        fprintf(stderr, \"temporary file read error\\n\");\n                        free(data);\n                     }\n\n                     else\n                     {\n                        (void)fclose(fp);\n                        *result = data;\n                        return total;\n                     }\n                  }\n\n                  else\n                     fprintf(stderr, \"%s: out of memory loading file\\n\", name);\n               }\n\n               else\n                  fprintf(stderr, \"%s: empty file\\n\", name);\n            }\n         }\n      }\n\n      else\n      {\n         perror(name);\n         fprintf(stderr, \"%s: open failed\\n\", name);\n      }\n\n      fclose(fp);\n   }\n\n   else\n      fprintf(stderr, \"makepng: %s: could not open temporary file\\n\", name);\n\n   exit(1);\n   return 0;\n}\n\nstatic png_size_t\nload_fake(png_charp param, png_bytepp profile)\n{\n   char *endptr = NULL;\n   uint64_t size = strtoull(param, &endptr, 0/*base*/);\n\n   /* The 'fake' format is <number>*[string] */\n   if (endptr != NULL && *endptr == '*')\n   {\n      size_t len = strlen(++endptr);\n      size_t result = (size_t)size;\n\n      if (len == 0) len = 1; /* capture the terminating '\\0' */\n\n      /* Now repeat that string to fill 'size' bytes. */\n      if (result == size && (*profile = malloc(result)) != NULL)\n      {\n         png_bytep out = *profile;\n\n         if (len == 1)\n            memset(out, *endptr, result);\n\n         else\n         {\n            while (size >= len)\n            {\n               memcpy(out, endptr, len);\n               out += len;\n               size -= len;\n            }\n            memcpy(out, endptr, size);\n         }\n\n         return result;\n      }\n\n      else\n      {\n         fprintf(stderr, \"%s: size exceeds system limits\\n\", param);\n         exit(1);\n      }\n   }\n\n   return 0;\n}\n\nstatic void\ncheck_param_count(int nparams, int expect)\n{\n   if (nparams != expect)\n   {\n      fprintf(stderr, \"bad parameter count (internal error)\\n\");\n      exit(1);\n   }\n}\n\nstatic void\ninsert_iCCP(png_structp png_ptr, png_infop info_ptr, int nparams,\n   png_charpp params)\n{\n   png_bytep profile = NULL;\n   png_uint_32 proflen = 0;\n   int result;\n\n   check_param_count(nparams, 2);\n\n   switch (params[1][0])\n   {\n      case '<':\n         {\n            png_size_t filelen = load_file(params[1]+1, &profile);\n            if (filelen > 0xfffffffc) /* Maximum profile length */\n            {\n               fprintf(stderr, \"%s: file too long (%lu) for an ICC profile\\n\",\n                  params[1]+1, (unsigned long)filelen);\n               exit(1);\n            }\n\n            proflen = (png_uint_32)filelen;\n         }\n         break;\n\n      case '0': case '1': case '2': case '3': case '4':\n      case '5': case '6': case '7': case '8': case '9':\n         {\n            png_size_t fake_len = load_fake(params[1], &profile);\n\n            if (fake_len > 0) /* else a simple parameter */\n            {\n               if (fake_len > 0xffffffff) /* Maximum profile length */\n               {\n                  fprintf(stderr,\n                     \"%s: fake data too long (%lu) for an ICC profile\\n\",\n                     params[1], (unsigned long)fake_len);\n                  exit(1);\n               }\n               proflen = (png_uint_32)(fake_len & ~3U);\n               /* Always fix up the profile length. */\n               png_save_uint_32(profile, proflen);\n               break;\n            }\n         }\n\n      default:\n         fprintf(stderr, \"--insert iCCP \\\"%s\\\": unrecognized\\n\", params[1]);\n         fprintf(stderr, \"  use '<' to read a file: \\\"<filename\\\"\\n\");\n         exit(1);\n   }\n\n   result = 1;\n\n   if (proflen & 3)\n   {\n      fprintf(stderr,\n         \"makepng: --insert iCCP %s: profile length made a multiple of 4\\n\",\n         params[1]);\n\n      /* load_file allocates extra space for this padding, the ICC spec requires\n       * padding with zero bytes.\n       */\n      while (proflen & 3)\n         profile[proflen++] = 0;\n   }\n\n   if (profile != NULL && proflen > 3)\n   {\n      png_uint_32 prof_header = png_get_uint_32(profile);\n\n      if (prof_header != proflen)\n      {\n         fprintf(stderr, \"--insert iCCP %s: profile length field wrong:\\n\",\n            params[1]);\n         fprintf(stderr, \"  actual %lu, recorded value %lu (corrected)\\n\",\n            (unsigned long)proflen, (unsigned long)prof_header);\n         png_save_uint_32(profile, proflen);\n      }\n   }\n\n   if (result && profile != NULL && proflen >=4)\n      png_set_iCCP(png_ptr, info_ptr, params[0], PNG_COMPRESSION_TYPE_BASE,\n         profile, proflen);\n\n   if (profile)\n      free(profile);\n\n   if (!result)\n      exit(1);\n}\n\nstatic void\nclear_text(png_text *text, png_charp keyword)\n{\n   text->compression = -1; /* none */\n   text->key = keyword;\n   text->text = NULL;\n   text->text_length = 0; /* libpng calculates this */\n   text->itxt_length = 0; /* libpng calculates this */\n   text->lang = NULL;\n   text->lang_key = NULL;\n}\n\nstatic void\nset_text(png_structp png_ptr, png_infop info_ptr, png_textp text,\n   png_charp param)\n{\n   switch (param[0])\n   {\n      case '<':\n         {\n            png_bytep file = NULL;\n\n            text->text_length = load_file(param+1, &file);\n            text->text = (png_charp)file;\n         }\n         break;\n\n      case '0': case '1': case '2': case '3': case '4':\n      case '5': case '6': case '7': case '8': case '9':\n         {\n            png_bytep data = NULL;\n            png_size_t fake_len = load_fake(param, &data);\n\n            if (fake_len > 0) /* else a simple parameter */\n            {\n               text->text_length = fake_len;\n               text->text = (png_charp)data;\n               break;\n            }\n         }\n\n      default:\n         text->text = param;\n         break;\n   }\n\n   png_set_text(png_ptr, info_ptr, text, 1);\n\n   if (text->text != param)\n      free(text->text);\n}\n\nstatic void\ninsert_tEXt(png_structp png_ptr, png_infop info_ptr, int nparams,\n   png_charpp params)\n{\n   png_text text;\n\n   check_param_count(nparams, 2);\n   clear_text(&text, params[0]);\n   set_text(png_ptr, info_ptr, &text, params[1]);\n}\n\nstatic void\ninsert_zTXt(png_structp png_ptr, png_infop info_ptr, int nparams,\n   png_charpp params)\n{\n   png_text text;\n\n   check_param_count(nparams, 2);\n   clear_text(&text, params[0]);\n   text.compression = 0; /* deflate */\n   set_text(png_ptr, info_ptr, &text, params[1]);\n}\n\nstatic void\ninsert_iTXt(png_structp png_ptr, png_infop info_ptr, int nparams,\n   png_charpp params)\n{\n   png_text text;\n\n   check_param_count(nparams, 4);\n   clear_text(&text, params[0]);\n   text.compression = 2; /* iTXt + deflate */\n   text.lang = params[1];/* language tag */\n   text.lang_key = params[2]; /* translated keyword */\n   set_text(png_ptr, info_ptr, &text, params[3]);\n}\n\nstatic void\ninsert_hIST(png_structp png_ptr, png_infop info_ptr, int nparams,\n      png_charpp params)\n{\n   int i;\n   png_uint_16 freq[256];\n\n   /* libpng takes the count from the PLTE count; we don't check it here but we\n    * do set the array to 0 for unspecified entries.\n    */\n   memset(freq, 0, sizeof freq);\n   for (i=0; i<nparams; ++i)\n   {\n      char *endptr = NULL;\n      unsigned long int l = strtoul(params[i], &endptr, 0/*base*/);\n\n      if (params[i][0] && *endptr == 0 && l <= 65535)\n         freq[i] = (png_uint_16)l;\n\n      else\n      {\n         fprintf(stderr, \"hIST[%d]: %s: invalid frequency\\n\", i, params[i]);\n         exit(1);\n      }\n   }\n\n   png_set_hIST(png_ptr, info_ptr, freq);\n}\n\nstatic png_byte\nbval(png_const_structrp png_ptr, png_charp param, unsigned int maxval)\n{\n   char *endptr = NULL;\n   unsigned long int l = strtoul(param, &endptr, 0/*base*/);\n\n   if (param[0] && *endptr == 0 && l <= maxval)\n      return (png_byte)l;\n\n   else\n      png_error(png_ptr, \"sBIT: invalid sBIT value\");\n}\n\nstatic void\ninsert_sBIT(png_structp png_ptr, png_infop info_ptr, int nparams,\n      png_charpp params)\n{\n   const int ct = png_get_color_type(png_ptr, info_ptr);\n   const int c = (ct & PNG_COLOR_MASK_COLOR ? 3 : 1) +\n      (ct & PNG_COLOR_MASK_ALPHA ? 1 : 0);\n   const unsigned int maxval =\n      ct & PNG_COLOR_MASK_PALETTE ? 8U : png_get_bit_depth(png_ptr, info_ptr);\n   png_color_8 sBIT;\n\n   if (nparams != c)\n      png_error(png_ptr, \"sBIT: incorrect parameter count\");\n\n   if (ct & PNG_COLOR_MASK_COLOR)\n   {\n      sBIT.red = bval(png_ptr, params[0], maxval);\n      sBIT.green = bval(png_ptr, params[1], maxval);\n      sBIT.blue = bval(png_ptr, params[2], maxval);\n      sBIT.gray = 42;\n   }\n\n   else\n   {\n      sBIT.red = sBIT.green = sBIT.blue = 42;\n      sBIT.gray = bval(png_ptr, params[0], maxval);\n   }\n\n   if (ct & PNG_COLOR_MASK_ALPHA)\n      sBIT.alpha = bval(png_ptr, params[nparams-1], maxval);\n\n   else\n      sBIT.alpha = 42;\n\n   png_set_sBIT(png_ptr, info_ptr, &sBIT);\n}\n\n#if 0\nstatic void\ninsert_sPLT(png_structp png_ptr, png_infop info_ptr, int nparams, png_charpp params)\n{\n   fprintf(stderr, \"insert sPLT: NYI\\n\");\n}\n#endif\n\nstatic int\nfind_parameters(png_const_charp what, png_charp param, png_charp *list,\n   int nparams)\n{\n   /* Parameters are separated by '\\n' or ':' characters, up to nparams are\n    * accepted (more is an error) and the number found is returned.\n    */\n   int i;\n   for (i=0; *param && i<nparams; ++i)\n   {\n      list[i] = param;\n      while (*++param) if (*param == '\\n' || *param == ':')\n      {\n         *param++ = 0; /* Terminate last parameter */\n         break;        /* And start a new one. */\n      }\n   }\n\n   if (*param)\n   {\n      fprintf(stderr, \"--insert %s: too many parameters (%s)\\n\", what, param);\n      exit(1);\n   }\n\n   list[i] = NULL; /* terminates list */\n   return i; /* number of parameters filled in */\n}\n\nstatic void\nbad_parameter_count(png_const_charp what, int nparams)\n{\n   fprintf(stderr, \"--insert %s: bad parameter count %d\\n\", what, nparams);\n   exit(1);\n}\n\nstatic chunk_insert *\nmake_insert(png_const_charp what,\n   void (*insert)(png_structp, png_infop, int, png_charpp),\n   int nparams, png_charpp list)\n{\n   int i;\n   chunk_insert *cip;\n\n   cip = malloc(offsetof(chunk_insert,parameters) +\n      nparams * sizeof (png_charp));\n\n   if (cip == NULL)\n   {\n      fprintf(stderr, \"--insert %s: out of memory allocating %d parameters\\n\",\n         what, nparams);\n      exit(1);\n   }\n\n   cip->next = NULL;\n   cip->insert = insert;\n   cip->nparams = nparams;\n   for (i=0; i<nparams; ++i)\n      cip->parameters[i] = list[i];\n\n   return cip;\n}\n\nstatic chunk_insert *\nfind_insert(png_const_charp what, png_charp param)\n{\n   png_uint_32 chunk = 0;\n   png_charp parameter_list[1024];\n   int i, nparams;\n\n   /* Assemble the chunk name */\n   for (i=0; i<4; ++i)\n   {\n      char ch = what[i];\n\n      if ((ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122))\n         chunk = (chunk << 8) + what[i];\n\n      else\n         break;\n   }\n\n   if (i < 4 || what[4] != 0)\n   {\n      fprintf(stderr, \"makepng --insert \\\"%s\\\": invalid chunk name\\n\", what);\n      exit(1);\n   }\n\n   /* Assemble the parameter list. */\n   nparams = find_parameters(what, param, parameter_list, 1024);\n\n#  define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d))\n\n   switch (chunk)\n   {\n      case CHUNK(105,67,67,80):  /* iCCP */\n         if (nparams == 2)\n            return make_insert(what, insert_iCCP, nparams, parameter_list);\n         break;\n\n      case CHUNK(116,69,88,116): /* tEXt */\n         if (nparams == 2)\n            return make_insert(what, insert_tEXt, nparams, parameter_list);\n         break;\n\n      case CHUNK(122,84,88,116): /* zTXt */\n         if (nparams == 2)\n            return make_insert(what, insert_zTXt, nparams, parameter_list);\n         break;\n\n      case CHUNK(105,84,88,116): /* iTXt */\n         if (nparams == 4)\n            return make_insert(what, insert_iTXt, nparams, parameter_list);\n         break;\n\n      case CHUNK(104,73,83,84):  /* hIST */\n         if (nparams <= 256)\n            return make_insert(what, insert_hIST, nparams, parameter_list);\n         break;\n\n      case CHUNK(115,66,73,84): /* sBIT */\n         if (nparams <= 4)\n            return make_insert(what, insert_sBIT, nparams, parameter_list);\n         break;\n\n#if 0\n      case CHUNK(115,80,76,84):  /* sPLT */\n         return make_insert(what, insert_sPLT, nparams, parameter_list);\n#endif\n\n      default:\n         fprintf(stderr, \"makepng --insert \\\"%s\\\": unrecognized chunk name\\n\",\n            what);\n         exit(1);\n   }\n\n   bad_parameter_count(what, nparams);\n   return NULL;\n}\n\n/* This is necessary because libpng expects writeable strings for things like\n * text chunks (maybe this should be fixed...)\n */\nstatic png_charp\nstrstash(png_const_charp foo)\n{\n   /* The program indicates a memory allocation error by crashing, this is by\n    * design.\n    */\n   if (foo != NULL)\n   {\n      png_charp bar = malloc(strlen(foo)+1);\n      return strcpy(bar, foo);\n   }\n\n   return NULL;\n}\n\nstatic png_charp\nstrstash_list(const png_const_charp *text)\n{\n   size_t foo = 0;\n   png_charp result, bar;\n   const png_const_charp *line = text;\n\n   while (*line != NULL)\n      foo += strlen(*line++);\n\n   result = bar = malloc(foo+1);\n\n   line = text;\n   while (*line != NULL)\n   {\n      foo = strlen(*line);\n      memcpy(bar, *line++, foo);\n      bar += foo;\n   }\n\n   *bar = 0;\n   return result;\n}\n\n/* These are used to insert Copyright and Licence fields, they allow the text to\n * have \\n unlike the --insert option.\n */\nstatic chunk_insert *\nadd_tEXt(const char *key, const png_const_charp *text)\n{\n   static char what[5] = { 116, 69, 88, 116, 0 };\n   png_charp parameter_list[3];\n\n   parameter_list[0] = strstash(key);\n   parameter_list[1] = strstash_list(text);\n   parameter_list[2] = NULL;\n\n   return make_insert(what, insert_tEXt, 2, parameter_list);\n}\n\nstatic chunk_insert *\nadd_iTXt(const char *key, const char *language, const char *language_key,\n      const png_const_charp *text)\n{\n   static char what[5] = { 105, 84, 88, 116, 0 };\n   png_charp parameter_list[5];\n\n   parameter_list[0] = strstash(key);\n   parameter_list[1] = strstash(language);\n   parameter_list[2] = strstash(language_key);\n   parameter_list[3] = strstash_list(text);\n   parameter_list[4] = NULL;\n\n   return make_insert(what, insert_iTXt, 4, parameter_list);\n}\n\n/* This is a not-very-good parser for a sequence of numbers (including 0).  It\n * doesn't accept some apparently valid things, but it accepts all the sensible\n * combinations.\n */\nstatic void\nparse_color(char *arg, unsigned int *colors)\n{\n   unsigned int ncolors = 0;\n\n   while (*arg && ncolors < 4)\n   {\n      char *ep = arg;\n\n      unsigned long ul = strtoul(arg, &ep, 0);\n\n      if (ul > 65535)\n      {\n         fprintf(stderr, \"makepng --color=...'%s': too big\\n\", arg);\n         exit(1);\n      }\n\n      if (ep == arg)\n      {\n         fprintf(stderr, \"makepng --color=...'%s': not a valid color\\n\", arg);\n         exit(1);\n      }\n\n      if (*ep) ++ep; /* skip a separator */\n      arg = ep;\n\n      colors[++ncolors] = (unsigned int)ul; /* checked above */\n   }\n\n   if (*arg)\n   {\n      fprintf(stderr, \"makepng --color=...'%s': too many values\\n\", arg);\n      exit(1);\n   }\n\n   *colors = ncolors;\n}\n\nint\nmain(int argc, char **argv)\n{\n   FILE *fp = stdout;\n   const char *file_name = NULL;\n   int color_type = 8; /* invalid */\n   int bit_depth = 32; /* invalid */\n   int small = 0; /* make full size images */\n   int tRNS = 0; /* don't output a tRNS chunk */\n   unsigned int colors[5];\n   unsigned int filters = PNG_ALL_FILTERS;\n   png_fixed_point gamma = 0; /* not set */\n   chunk_insert *head_insert = NULL;\n   chunk_insert **insert_ptr = &head_insert;\n\n   memset(colors, 0, sizeof colors);\n\n   while (--argc > 0)\n   {\n      char *arg = *++argv;\n\n      if (strcmp(arg, \"--small\") == 0)\n      {\n         small = 1;\n         continue;\n      }\n\n      if (strcmp(arg, \"--tRNS\") == 0)\n      {\n         tRNS = 1;\n         continue;\n      }\n\n      if (strcmp(arg, \"--sRGB\") == 0)\n      {\n         gamma = PNG_DEFAULT_sRGB;\n         continue;\n      }\n\n      if (strcmp(arg, \"--linear\") == 0)\n      {\n         gamma = PNG_FP_1;\n         continue;\n      }\n\n      if (strcmp(arg, \"--1.8\") == 0)\n      {\n         gamma = PNG_GAMMA_MAC_18;\n         continue;\n      }\n\n      if (strcmp(arg, \"--nofilters\") == 0)\n      {\n         filters = PNG_FILTER_NONE;\n         continue;\n      }\n\n      if (strncmp(arg, \"--color=\", 8) == 0)\n      {\n          parse_color(arg+8, colors);\n          continue;\n      }\n\n      if (argc >= 3 && strcmp(arg, \"--insert\") == 0)\n      {\n         png_const_charp what = *++argv;\n         png_charp param = *++argv;\n         chunk_insert *new_insert;\n\n         argc -= 2;\n\n         new_insert = find_insert(what, param);\n\n         if (new_insert != NULL)\n         {\n            *insert_ptr = new_insert;\n            insert_ptr = &new_insert->next;\n         }\n\n         continue;\n      }\n\n      if (arg[0] == '-')\n      {\n         fprintf(stderr, \"makepng: %s: invalid option\\n\", arg);\n         exit(1);\n      }\n\n      if (strcmp(arg, \"palette\") == 0)\n      {\n         color_type = PNG_COLOR_TYPE_PALETTE;\n         continue;\n      }\n\n      if (strncmp(arg, \"gray\", 4) == 0)\n      {\n         if (arg[4] == 0)\n         {\n            color_type = PNG_COLOR_TYPE_GRAY;\n            continue;\n         }\n\n         else if (strcmp(arg+4, \"a\") == 0 ||\n            strcmp(arg+4, \"alpha\") == 0 ||\n            strcmp(arg+4, \"-alpha\") == 0)\n         {\n            color_type = PNG_COLOR_TYPE_GRAY_ALPHA;\n            continue;\n         }\n      }\n\n      if (strncmp(arg, \"rgb\", 3) == 0)\n      {\n         if (arg[3] == 0)\n         {\n            color_type = PNG_COLOR_TYPE_RGB;\n            continue;\n         }\n\n         else if (strcmp(arg+3, \"a\") == 0 ||\n            strcmp(arg+3, \"alpha\") == 0 ||\n            strcmp(arg+3, \"-alpha\") == 0)\n         {\n            color_type = PNG_COLOR_TYPE_RGB_ALPHA;\n            continue;\n         }\n      }\n\n      if (color_type == 8 && isdigit(arg[0]))\n      {\n         color_type = atoi(arg);\n         if (color_type < 0 || color_type > 6 || color_type == 1 ||\n            color_type == 5)\n         {\n            fprintf(stderr, \"makepng: %s: not a valid color type\\n\", arg);\n            exit(1);\n         }\n\n         continue;\n      }\n\n      if (bit_depth == 32 && isdigit(arg[0]))\n      {\n         bit_depth = atoi(arg);\n         if (bit_depth <= 0 || bit_depth > 16 ||\n            (bit_depth & -bit_depth) != bit_depth)\n         {\n            fprintf(stderr, \"makepng: %s: not a valid bit depth\\n\", arg);\n            exit(1);\n         }\n\n         continue;\n      }\n\n      if (argc == 1) /* It's the file name */\n      {\n         fp = fopen(arg, \"wb\");\n         if (fp == NULL)\n         {\n            fprintf(stderr, \"%s: %s: could not open\\n\", arg, strerror(errno));\n            exit(1);\n         }\n\n         file_name = arg;\n         continue;\n      }\n\n      fprintf(stderr, \"makepng: %s: unknown argument\\n\", arg);\n      exit(1);\n   } /* argument while loop */\n\n   if (color_type == 8 || bit_depth == 32)\n   {\n      fprintf(stderr, \"usage: makepng [--small] [--sRGB|--linear|--1.8] \"\n         \"[--color=...] color-type bit-depth [file-name]\\n\"\n         \"  Make a test PNG file, by default writes to stdout.\\n\"\n         \"  Other options are available, UTSL.\\n\");\n      exit(1);\n   }\n\n   /* Check the colors */\n   {\n      const unsigned int lim = (color_type == PNG_COLOR_TYPE_PALETTE ? 255U :\n         (1U<<bit_depth)-1);\n      unsigned int i;\n\n      for (i=1; i<=colors[0]; ++i)\n         if (colors[i] > lim)\n         {\n            fprintf(stderr, \"makepng: --color=...: %u out of range [0..%u]\\n\",\n               colors[i], lim);\n            exit(1);\n         }\n   }\n\n   /* small and colors are incomparible (will probably crash if both are used at\n    * the same time!)\n    */\n   if (small && colors[0] != 0)\n   {\n      fprintf(stderr, \"makepng: --color --small: only one at a time!\\n\");\n      exit(1);\n   }\n\n   /* Restrict the filters for more speed to those we know are used for the\n    * generated images.\n    */\n   if (filters == PNG_ALL_FILTERS && !small/*small provides defaults*/)\n   {\n      if ((color_type & PNG_COLOR_MASK_PALETTE) != 0 || bit_depth < 8)\n         filters = PNG_FILTER_NONE;\n\n      else if (color_type & PNG_COLOR_MASK_COLOR) /* rgb */\n      {\n         if (bit_depth == 8)\n            filters &= ~(PNG_FILTER_NONE | PNG_FILTER_AVG);\n\n         else\n            filters = PNG_FILTER_SUB | PNG_FILTER_PAETH;\n      }\n\n      else /* gray 8 or 16-bit */\n         filters &= ~PNG_FILTER_NONE;\n   }\n\n   /* Insert standard copyright and licence text. */\n   {\n      static png_const_charp copyright[] =\n      {\n         COPYRIGHT, /* ISO-Latin-1 */\n         NULL\n      };\n      static png_const_charp licensing[] =\n      {\n         IMAGE_LICENSING, /* UTF-8 */\n         NULL\n      };\n\n      chunk_insert *new_insert;\n\n      new_insert = add_tEXt(\"Copyright\", copyright);\n      if (new_insert != NULL)\n      {\n         *insert_ptr = new_insert;\n         insert_ptr = &new_insert->next;\n      }\n\n      new_insert = add_iTXt(\"Licensing\", \"en\", NULL, licensing);\n      if (new_insert != NULL)\n      {\n         *insert_ptr = new_insert;\n         insert_ptr = &new_insert->next;\n      }\n   }\n\n   {\n      int ret = write_png(&file_name, fp, color_type, bit_depth, gamma,\n         head_insert, filters, colors, small, tRNS);\n\n      if (ret != 0 && file_name != NULL)\n         remove(file_name);\n\n      return ret;\n   }\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/libtests/pngimage.c",
    "content": "/* pngimage.c\n *\n * Copyright (c) 2015,2016 John Cunningham Bowler\n *\n * Last changed in libpng 1.6.22 [(PENDING RELEASE)]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * Test the png_read_png and png_write_png interfaces.  Given a PNG file load it\n * using png_read_png and then write with png_write_png.  Test all possible\n * transforms.\n */\n#include <stdarg.h>\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <stdio.h>\n#include <assert.h>\n\n#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)\n#  include <config.h>\n#endif\n\n/* Define the following to use this test against your installed libpng, rather\n * than the one being built here:\n */\n#ifdef PNG_FREESTANDING_TESTS\n#  include <png.h>\n#else\n#  include \"../../png.h\"\n#endif\n\n#ifndef PNG_SETJMP_SUPPORTED\n#  include <setjmp.h> /* because png.h did *not* include this */\n#endif\n\n/* 1.6.1 added support for the configure test harness, which uses 77 to indicate\n * a skipped test, in earlier versions we need to succeed on a skipped test, so:\n */\n#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)\n#  define SKIP 77\n#else\n#  define SKIP 0\n#endif\n\n#if defined(PNG_INFO_IMAGE_SUPPORTED) && defined(PNG_SEQUENTIAL_READ_SUPPORTED)\\\n    && (defined(PNG_READ_PNG_SUPPORTED) || PNG_LIBPNG_VER < 10700)\n/* If a transform is valid on both read and write this implies that if the\n * transform is applied to read it must also be applied on write to produce\n * meaningful data.  This is because these transforms when performed on read\n * produce data with a memory format that does not correspond to a PNG format.\n *\n * Most of these transforms are invertible; after applying the transform on\n * write the result is the original PNG data that would have would have been\n * read if no transform were applied.\n *\n * The exception is _SHIFT, which destroys the low order bits marked as not\n * significant in a PNG with the sBIT chunk.\n *\n * The following table lists, for each transform, the conditions under which it\n * is expected to do anything.  Conditions are defined as follows:\n *\n * 1) Color mask bits required - simply a mask to AND with color_type; one of\n *    these must be present for the transform to fire, except that 0 means\n *    'always'.\n * 2) Color mask bits which must be absent - another mask - none of these must\n *    be present.\n * 3) Bit depths - a mask of component bit depths for the transform to fire.\n * 4) 'read' - the transform works in png_read_png.\n * 5) 'write' - the transform works in png_write_png.\n * 6) PNG_INFO_chunk; a mask of the chunks that must be present for the\n *    transform to fire.  All must be present - the requirement is that\n *    png_get_valid() & mask == mask, so if mask is 0 there is no requirement.\n *\n * The condition refers to the original image state - if multiple transforms are\n * used together it is possible to cause a transform that wouldn't fire on the\n * original image to fire.\n */\nstatic struct transform_info\n{\n   const char *name;\n   int         transform;\n   png_uint_32 valid_chunks;\n#     define CHUNK_NONE 0\n#     define CHUNK_sBIT PNG_INFO_sBIT\n#     define CHUNK_tRNS PNG_INFO_tRNS\n   png_byte    color_mask_required;\n   png_byte    color_mask_absent;\n#     define COLOR_MASK_X   0\n#     define COLOR_MASK_P   PNG_COLOR_MASK_PALETTE\n#     define COLOR_MASK_C   PNG_COLOR_MASK_COLOR\n#     define COLOR_MASK_A   PNG_COLOR_MASK_ALPHA\n#     define COLOR_MASK_ALL (PALETTE+COLOR+ALPHA)  /* absent = gray, no alpha */\n   png_byte    bit_depths;\n#     define BD_ALL  (1 + 2 + 4 + 8 + 16)\n#     define BD_PAL  (1 + 2 + 4 + 8)\n#     define BD_LOW  (1 + 2 + 4)\n#     define BD_16   16\n#     define BD_TRUE (8+16) /* i.e. true-color depths */\n   png_byte    when;\n#     define TRANSFORM_R  1\n#     define TRANSFORM_W  2\n#     define TRANSFORM_RW 3\n   png_byte    tested; /* the transform was tested somewhere */\n} transform_info[] =\n{\n   /* List ALL the PNG_TRANSFORM_ macros here.  Check for support using the READ\n    * macros; even if the transform is supported on write it cannot be tested\n    * without the read support.\n    */\n#  define T(name,chunk,cm_required,cm_absent,bd,when)\\\n   {  #name, PNG_TRANSFORM_ ## name, CHUNK_ ## chunk,\\\n      COLOR_MASK_ ## cm_required, COLOR_MASK_ ## cm_absent, BD_ ## bd,\\\n      TRANSFORM_ ## when, 0/*!tested*/ }\n\n#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED\n   T(STRIP_16,            NONE, X,   X,   16,  R),\n      /* drops the bottom 8 bits when bit depth is 16 */\n#endif\n#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED\n   T(STRIP_ALPHA,         NONE, A,   X,  ALL,  R),\n      /* removes the alpha channel if present */\n#endif\n#ifdef PNG_WRITE_PACK_SUPPORTED\n#  define TRANSFORM_RW_PACK TRANSFORM_RW\n#else\n#  define TRANSFORM_RW_PACK TRANSFORM_R\n#endif\n#ifdef PNG_READ_PACK_SUPPORTED\n   T(PACKING,             NONE, X,   X,  LOW, RW_PACK),\n      /* unpacks low-bit-depth components into 1 byte per component on read,\n       * reverses this on write.\n       */\n#endif\n#ifdef PNG_WRITE_PACKSWAP_SUPPORTED\n#  define TRANSFORM_RW_PACKSWAP TRANSFORM_RW\n#else\n#  define TRANSFORM_RW_PACKSWAP TRANSFORM_R\n#endif\n#ifdef PNG_READ_PACKSWAP_SUPPORTED\n   T(PACKSWAP,            NONE, X,   X,  LOW, RW_PACKSWAP),\n      /* reverses the order of low-bit-depth components packed into a byte */\n#endif\n#ifdef PNG_READ_EXPAND_SUPPORTED\n   T(EXPAND,              NONE, P,   X,  ALL,  R),\n      /* expands PLTE PNG files to RGB (no tRNS) or RGBA (tRNS) *\n       * Note that the 'EXPAND' transform does lots of different things: */\n   T(EXPAND,              NONE, X,   C,  ALL,  R),\n      /* expands grayscale PNG files to RGB, or RGBA */\n   T(EXPAND,              tRNS, X,   A,  ALL,  R),\n      /* expands the tRNS chunk in files without alpha */\n#endif\n#ifdef PNG_WRITE_INVERT_SUPPORTED\n#  define TRANSFORM_RW_INVERT TRANSFORM_RW\n#else\n#  define TRANSFORM_RW_INVERT TRANSFORM_R\n#endif\n#ifdef PNG_READ_INVERT_SUPPORTED\n   T(INVERT_MONO,         NONE, X,   C,  ALL, RW_INVERT),\n      /* converts gray-scale components to 1..0 from 0..1 */\n#endif\n#ifdef PNG_WRITE_SHIFT_SUPPORTED\n#  define TRANSFORM_RW_SHIFT TRANSFORM_RW\n#else\n#  define TRANSFORM_RW_SHIFT TRANSFORM_R\n#endif\n#ifdef PNG_READ_SHIFT_SUPPORTED\n   T(SHIFT,               sBIT, X,   X,  ALL, RW_SHIFT),\n      /* reduces component values to the original range based on the sBIT chunk,\n       * this is only partially reversible - the low bits are lost and cannot be\n       * recovered on write.  In fact write code replicates the bits to generate\n       * new low-order bits.\n       */\n#endif\n#ifdef PNG_WRITE_BGR_SUPPORTED\n#  define TRANSFORM_RW_BGR TRANSFORM_RW\n#else\n#  define TRANSFORM_RW_BGR TRANSFORM_R\n#endif\n#ifdef PNG_READ_BGR_SUPPORTED\n   T(BGR,                 NONE, C,   P, TRUE, RW_BGR),\n      /* reverses the rgb component values of true-color pixels */\n#endif\n#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED\n#  define TRANSFORM_RW_SWAP_ALPHA TRANSFORM_RW\n#else\n#  define TRANSFORM_RW_SWAP_ALPHA TRANSFORM_R\n#endif\n#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED\n   T(SWAP_ALPHA,          NONE, A,   X, TRUE, RW_SWAP_ALPHA),\n      /* swaps the alpha channel of RGBA or GA pixels to the front - ARGB or\n       * AG, on write reverses the process.\n       */\n#endif\n#ifdef PNG_WRITE_SWAP_SUPPORTED\n#  define TRANSFORM_RW_SWAP TRANSFORM_RW\n#else\n#  define TRANSFORM_RW_SWAP TRANSFORM_R\n#endif\n#ifdef PNG_READ_SWAP_SUPPORTED\n   T(SWAP_ENDIAN,         NONE, X,   P,   16, RW_SWAP),\n      /* byte-swaps 16-bit component values */\n#endif\n#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED\n#  define TRANSFORM_RW_INVERT_ALPHA TRANSFORM_RW\n#else\n#  define TRANSFORM_RW_INVERT_ALPHA TRANSFORM_R\n#endif\n#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED\n   T(INVERT_ALPHA,        NONE, A,   X, TRUE, RW_INVERT_ALPHA),\n      /* converts an alpha channel from 0..1 to 1..0 */\n#endif\n#ifdef PNG_WRITE_FILLER_SUPPORTED\n   T(STRIP_FILLER_BEFORE, NONE, A,   P, TRUE,  W), /* 'A' for a filler! */\n      /* on write skips a leading filler channel; testing requires data with a\n       * filler channel so this is produced from RGBA or GA images by removing\n       * the 'alpha' flag from the color type in place.\n       */\n   T(STRIP_FILLER_AFTER,  NONE, A,   P, TRUE,  W),\n      /* on write strips a trailing filler channel */\n#endif\n#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\n   T(GRAY_TO_RGB,         NONE, X,   C,  ALL,  R),\n      /* expands grayscale images to RGB, also causes the palette part of\n       * 'EXPAND' to happen.  Low bit depth grayscale images are expanded to\n       * 8-bits per component and no attempt is made to convert the image to a\n       * palette image.  While this transform is partially reversible\n       * png_write_png does not currently support this.\n       */\n   T(GRAY_TO_RGB,         NONE, P,   X,  ALL,  R),\n      /* The 'palette' side effect mentioned above; a bit bogus but this is the\n       * way the libpng code works.\n       */\n#endif\n#ifdef PNG_READ_EXPAND_16_SUPPORTED\n   T(EXPAND_16,           NONE, X,   X,  PAL,  R),\n      /* expands images to 16-bits per component, as a side effect expands\n       * palette images to RGB and expands the tRNS chunk if present, so it can\n       * modify 16-bit per component images as well:\n       */\n   T(EXPAND_16,           tRNS, X,   A,   16,  R),\n      /* side effect of EXPAND_16 - expands the tRNS chunk in an RGB or G 16-bit\n       * image.\n       */\n#endif\n#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\n   T(SCALE_16,            NONE, X,   X,   16,  R),\n      /* scales 16-bit components to 8-bits. */\n#endif\n\n   { NULL /*name*/, 0, 0, 0, 0, 0, 0, 0/*!tested*/ }\n\n#undef T\n};\n\n#define ARRAY_SIZE(a) ((sizeof a)/(sizeof a[0]))\n#define TTABLE_SIZE ARRAY_SIZE(transform_info)\n\n/* Some combinations of options that should be reversible are not; these cases\n * are bugs.\n */\nstatic int known_bad_combos[][2] =\n{\n   /* problem, antidote */\n   { PNG_TRANSFORM_SHIFT | PNG_TRANSFORM_INVERT_ALPHA, 0/*antidote*/ }\n};\n\nstatic int\nis_combo(int transforms)\n{\n   return transforms & (transforms-1); /* non-zero if more than one set bit */\n}\n\nstatic int\nfirst_transform(int transforms)\n{\n   return transforms & -transforms; /* lowest set bit */\n}\n\nstatic int\nis_bad_combo(int transforms)\n{\n   unsigned int i;\n\n   for (i=0; i<ARRAY_SIZE(known_bad_combos); ++i)\n   {\n      int combo = known_bad_combos[i][0];\n\n      if ((combo & transforms) == combo &&\n         (transforms & known_bad_combos[i][1]) == 0)\n         return 1;\n   }\n\n   return 0; /* combo is ok */\n}\n\nstatic const char *\ntransform_name(int t)\n   /* The name, if 't' has multiple bits set the name of the lowest set bit is\n    * returned.\n    */\n{\n   unsigned int i;\n\n   t &= -t; /* first set bit */\n\n   for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL)\n   {\n      if ((transform_info[i].transform & t) != 0)\n         return transform_info[i].name;\n   }\n\n   return \"invalid transform\";\n}\n\n/* Variables calculated by validate_T below and used to record all the supported\n * transforms.  Need (unsigned int) here because of the places where these\n * values are used (unsigned compares in the 'exhaustive' iterator.)\n */\nstatic unsigned int read_transforms, write_transforms, rw_transforms;\n\nstatic void\nvalidate_T(void)\n   /* Validate the above table - this just builds the above values */\n{\n   unsigned int i;\n\n   for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL)\n   {\n      if (transform_info[i].when & TRANSFORM_R)\n         read_transforms |= transform_info[i].transform;\n\n      if (transform_info[i].when & TRANSFORM_W)\n         write_transforms |= transform_info[i].transform;\n   }\n\n   /* Reversible transforms are those which are supported on both read and\n    * write.\n    */\n   rw_transforms = read_transforms & write_transforms;\n}\n\n/* FILE DATA HANDLING\n *    The original file is cached in memory.  During write the output file is\n *    written to memory.\n *\n *    In both cases the file data is held in a linked list of buffers - not all\n *    of these are in use at any time.\n */\n#define NEW(type) ((type *)malloc(sizeof (type)))\n#define DELETE(ptr) (free(ptr))\n\nstruct buffer_list\n{\n   struct buffer_list *next;         /* next buffer in list */\n   png_byte            buffer[1024]; /* the actual buffer */\n};\n\nstruct buffer\n{\n   struct buffer_list  *last;       /* last buffer in use */\n   size_t               end_count;  /* bytes in the last buffer */\n   struct buffer_list  *current;    /* current buffer being read */\n   size_t               read_count; /* count of bytes read from current */\n   struct buffer_list   first;      /* the very first buffer */\n};\n\nstatic void\nbuffer_init(struct buffer *buffer)\n   /* Call this only once for a given buffer */\n{\n   buffer->first.next = NULL;\n   buffer->last = NULL;\n   buffer->current = NULL;\n}\n\nstatic void\nbuffer_destroy_list(struct buffer_list *list)\n{\n   if (list != NULL)\n   {\n      struct buffer_list *next = list->next;\n      DELETE(list);\n      buffer_destroy_list(next);\n   }\n}\n\nstatic void\nbuffer_destroy(struct buffer *buffer)\n{\n   struct buffer_list *list = buffer->first.next;\n   buffer_init(buffer);\n   buffer_destroy_list(list);\n}\n\n#ifdef PNG_WRITE_SUPPORTED\nstatic void\nbuffer_start_write(struct buffer *buffer)\n{\n   buffer->last = &buffer->first;\n   buffer->end_count = 0;\n   buffer->current = NULL;\n}\n#endif\n\nstatic void\nbuffer_start_read(struct buffer *buffer)\n{\n   buffer->current = &buffer->first;\n   buffer->read_count = 0;\n}\n\n#ifdef ENOMEM /* required by POSIX 1003.1 */\n#  define MEMORY ENOMEM\n#else\n#  define MEMORY ERANGE /* required by ANSI-C */\n#endif\nstatic struct buffer *\nget_buffer(png_structp pp)\n   /* Used from libpng callbacks to get the current buffer */\n{\n   return (struct buffer*)png_get_io_ptr(pp);\n}\n\nstatic struct buffer_list *\nbuffer_extend(struct buffer_list *current)\n{\n   struct buffer_list *add;\n\n   assert(current->next == NULL);\n\n   add = NEW(struct buffer_list);\n   if (add == NULL)\n      return NULL;\n\n   add->next = NULL;\n   current->next = add;\n\n   return add;\n}\n\n/* Load a buffer from a file; does the equivalent of buffer_start_write.  On a\n * read error returns an errno value, else returns 0.\n */\nstatic int\nbuffer_from_file(struct buffer *buffer, FILE *fp)\n{\n   struct buffer_list *last = &buffer->first;\n   size_t count = 0;\n\n   for (;;)\n   {\n      size_t r = fread(last->buffer+count, 1/*size*/,\n         (sizeof last->buffer)-count, fp);\n\n      if (r > 0)\n      {\n         count += r;\n\n         if (count >= sizeof last->buffer)\n         {\n            assert(count == sizeof last->buffer);\n            count = 0;\n\n            if (last->next == NULL)\n            {\n               last = buffer_extend(last);\n               if (last == NULL)\n                  return MEMORY;\n            }\n\n            else\n               last = last->next;\n         }\n      }\n\n      else /* fread failed - probably end of file */\n      {\n         if (feof(fp))\n         {\n            buffer->last = last;\n            buffer->end_count = count;\n            return 0; /* no error */\n         }\n\n         /* Some kind of funky error; errno should be non-zero */\n         return errno == 0 ? ERANGE : errno;\n      }\n   }\n}\n\n/* This structure is used to control the test of a single file. */\ntypedef enum\n{\n   VERBOSE,        /* switches on all messages */\n   INFORMATION,\n   WARNINGS,       /* switches on warnings */\n   LIBPNG_WARNING,\n   APP_WARNING,\n   ERRORS,         /* just errors */\n   APP_FAIL,       /* continuable error - no need to longjmp */\n   LIBPNG_ERROR,   /* this and higher cause a longjmp */\n   LIBPNG_BUG,     /* erroneous behavior in libpng */\n   APP_ERROR,      /* such as out-of-memory in a callback */\n   QUIET,          /* no normal messages */\n   USER_ERROR,     /* such as file-not-found */\n   INTERNAL_ERROR\n} error_level;\n#define LEVEL_MASK      0xf   /* where the level is in 'options' */\n\n#define EXHAUSTIVE      0x010 /* Test all combinations of active options */\n#define STRICT          0x020 /* Fail on warnings as well as errors */\n#define LOG             0x040 /* Log pass/fail to stdout */\n#define CONTINUE        0x080 /* Continue on APP_FAIL errors */\n#define SKIP_BUGS       0x100 /* Skip over known bugs */\n#define LOG_SKIPPED     0x200 /* Log skipped bugs */\n#define FIND_BAD_COMBOS 0x400 /* Attempt to deduce bad combos */\n#define LIST_COMBOS     0x800 /* List combos by name */\n\n/* Result masks apply to the result bits in the 'results' field below; these\n * bits are simple 1U<<error_level.  A pass requires either nothing worse than\n * warnings (--relaxes) or nothing worse than information (--strict)\n */\n#define RESULT_STRICT(r)   (((r) & ~((1U<<WARNINGS)-1)) == 0)\n#define RESULT_RELAXED(r)  (((r) & ~((1U<<ERRORS)-1)) == 0)\n\nstruct display\n{\n   jmp_buf        error_return;      /* Where to go to on error */\n\n   const char    *filename;          /* The name of the original file */\n   const char    *operation;         /* Operation being performed */\n   int            transforms;        /* Transform used in operation */\n   png_uint_32    options;           /* See display_log below */\n   png_uint_32    results;           /* A mask of errors seen */\n\n\n   png_structp    original_pp;       /* used on the original read */\n   png_infop      original_ip;       /* set by the original read */\n\n   png_size_t     original_rowbytes; /* of the original rows: */\n   png_bytepp     original_rows;     /* from the original read */\n\n   /* Original chunks valid */\n   png_uint_32    chunks;\n\n   /* Original IHDR information */\n   png_uint_32    width;\n   png_uint_32    height;\n   int            bit_depth;\n   int            color_type;\n   int            interlace_method;\n   int            compression_method;\n   int            filter_method;\n\n   /* Derived information for the original image. */\n   int            active_transforms;  /* transforms that do something on read */\n   int            ignored_transforms; /* transforms that should do nothing */\n\n   /* Used on a read, both the original read and when validating a written\n    * image.\n    */\n   png_structp    read_pp;\n   png_infop      read_ip;\n\n#  ifdef PNG_WRITE_SUPPORTED\n      /* Used to write a new image (the original info_ptr is used) */\n      png_structp   write_pp;\n      struct buffer written_file;   /* where the file gets written */\n#  endif\n\n   struct buffer  original_file;     /* Data read from the original file */\n};\n\nstatic void\ndisplay_init(struct display *dp)\n   /* Call this only once right at the start to initialize the control\n    * structure, the (struct buffer) lists are maintained across calls - the\n    * memory is not freed.\n    */\n{\n   memset(dp, 0, sizeof *dp);\n   dp->options = WARNINGS; /* default to !verbose, !quiet */\n   dp->filename = NULL;\n   dp->operation = NULL;\n   dp->original_pp = NULL;\n   dp->original_ip = NULL;\n   dp->original_rows = NULL;\n   dp->read_pp = NULL;\n   dp->read_ip = NULL;\n   buffer_init(&dp->original_file);\n\n#  ifdef PNG_WRITE_SUPPORTED\n      dp->write_pp = NULL;\n      buffer_init(&dp->written_file);\n#  endif\n}\n\nstatic void\ndisplay_clean_read(struct display *dp)\n{\n   if (dp->read_pp != NULL)\n      png_destroy_read_struct(&dp->read_pp, &dp->read_ip, NULL);\n}\n\n#ifdef PNG_WRITE_SUPPORTED\nstatic void\ndisplay_clean_write(struct display *dp)\n{\n      if (dp->write_pp != NULL)\n         png_destroy_write_struct(&dp->write_pp, NULL);\n}\n#endif\n\nstatic void\ndisplay_clean(struct display *dp)\n{\n#  ifdef PNG_WRITE_SUPPORTED\n      display_clean_write(dp);\n#  endif\n   display_clean_read(dp);\n\n   dp->original_rowbytes = 0;\n   dp->original_rows = NULL;\n   dp->chunks = 0;\n\n   png_destroy_read_struct(&dp->original_pp, &dp->original_ip, NULL);\n   /* leave the filename for error detection */\n   dp->results = 0; /* reset for next time */\n}\n\nstatic void\ndisplay_destroy(struct display *dp)\n{\n    /* Release any memory held in the display. */\n#  ifdef PNG_WRITE_SUPPORTED\n      buffer_destroy(&dp->written_file);\n#  endif\n\n   buffer_destroy(&dp->original_file);\n}\n\nstatic struct display *\nget_dp(png_structp pp)\n   /* The display pointer is always stored in the png_struct error pointer */\n{\n   struct display *dp = (struct display*)png_get_error_ptr(pp);\n\n   if (dp == NULL)\n   {\n      fprintf(stderr, \"pngimage: internal error (no display)\\n\");\n      exit(99); /* prevents a crash */\n   }\n\n   return dp;\n}\n\n/* error handling */\n#ifdef __GNUC__\n#  define VGATTR __attribute__((__format__ (__printf__,3,4)))\n   /* Required to quiet GNUC warnings when the compiler sees a stdarg function\n    * that calls one of the stdio v APIs.\n    */\n#else\n#  define VGATTR\n#endif\nstatic void VGATTR\ndisplay_log(struct display *dp, error_level level, const char *fmt, ...)\n   /* 'level' is as above, fmt is a stdio style format string.  This routine\n    * does not return if level is above LIBPNG_WARNING\n    */\n{\n   dp->results |= 1U << level;\n\n   if (level > (error_level)(dp->options & LEVEL_MASK))\n   {\n      const char *lp;\n      va_list ap;\n\n      switch (level)\n      {\n         case INFORMATION:    lp = \"information\"; break;\n         case LIBPNG_WARNING: lp = \"warning(libpng)\"; break;\n         case APP_WARNING:    lp = \"warning(pngimage)\"; break;\n         case APP_FAIL:       lp = \"error(continuable)\"; break;\n         case LIBPNG_ERROR:   lp = \"error(libpng)\"; break;\n         case LIBPNG_BUG:     lp = \"bug(libpng)\"; break;\n         case APP_ERROR:      lp = \"error(pngimage)\"; break;\n         case USER_ERROR:     lp = \"error(user)\"; break;\n\n         case INTERNAL_ERROR: /* anything unexpected is an internal error: */\n         case VERBOSE: case WARNINGS: case ERRORS: case QUIET:\n         default:             lp = \"bug(pngimage)\"; break;\n      }\n\n      fprintf(stderr, \"%s: %s: %s\",\n         dp->filename != NULL ? dp->filename : \"<stdin>\", lp, dp->operation);\n\n      if (dp->transforms != 0)\n      {\n         int tr = dp->transforms;\n\n         if (is_combo(tr))\n         {\n            if (dp->options & LIST_COMBOS)\n            {\n               int trx = tr;\n\n               fprintf(stderr, \"(\");\n               if (trx)\n               {\n                  int start = 0;\n\n                  while (trx)\n                  {\n                     int trz = trx & -trx;\n\n                     if (start) fprintf(stderr, \"+\");\n                     fprintf(stderr, \"%s\", transform_name(trz));\n                     start = 1;\n                     trx &= ~trz;\n                  }\n               }\n\n               else\n                  fprintf(stderr, \"-\");\n               fprintf(stderr, \")\");\n            }\n\n            else\n               fprintf(stderr, \"(0x%x)\", tr);\n         }\n\n         else\n            fprintf(stderr, \"(%s)\", transform_name(tr));\n      }\n\n      fprintf(stderr, \": \");\n\n      va_start(ap, fmt);\n      vfprintf(stderr, fmt, ap);\n      va_end(ap);\n\n      fputc('\\n', stderr);\n   }\n   /* else do not output any message */\n\n   /* Errors cause this routine to exit to the fail code */\n   if (level > APP_FAIL || (level > ERRORS && !(dp->options & CONTINUE)))\n      longjmp(dp->error_return, level);\n}\n\n/* error handler callbacks for libpng */\nstatic void PNGCBAPI\ndisplay_warning(png_structp pp, png_const_charp warning)\n{\n   display_log(get_dp(pp), LIBPNG_WARNING, \"%s\", warning);\n}\n\nstatic void PNGCBAPI\ndisplay_error(png_structp pp, png_const_charp error)\n{\n   struct display *dp = get_dp(pp);\n\n   display_log(dp, LIBPNG_ERROR, \"%s\", error);\n}\n\nstatic void\ndisplay_cache_file(struct display *dp, const char *filename)\n   /* Does the initial cache of the file. */\n{\n   FILE *fp;\n   int ret;\n\n   dp->filename = filename;\n\n   if (filename != NULL)\n   {\n      fp = fopen(filename, \"rb\");\n      if (fp == NULL)\n         display_log(dp, USER_ERROR, \"open failed: %s\", strerror(errno));\n   }\n\n   else\n      fp = stdin;\n\n   ret = buffer_from_file(&dp->original_file, fp);\n\n   fclose(fp);\n\n   if (ret != 0)\n      display_log(dp, APP_ERROR, \"read failed: %s\", strerror(ret));\n}\n\nstatic void\nbuffer_read(struct display *dp, struct buffer *bp, png_bytep data,\n   png_size_t size)\n{\n   struct buffer_list *last = bp->current;\n   size_t read_count = bp->read_count;\n\n   while (size > 0)\n   {\n      size_t avail;\n\n      if (last == NULL ||\n         (last == bp->last && read_count >= bp->end_count))\n      {\n         display_log(dp, USER_ERROR, \"file truncated (%lu bytes)\",\n            (unsigned long)size);\n         /*NOTREACHED*/\n         break;\n      }\n\n      else if (read_count >= sizeof last->buffer)\n      {\n         /* Move to the next buffer: */\n         last = last->next;\n         read_count = 0;\n         bp->current = last; /* Avoid update outside the loop */\n\n         /* And do a sanity check (the EOF case is caught above) */\n         if (last == NULL)\n         {\n            display_log(dp, INTERNAL_ERROR, \"damaged buffer list\");\n            /*NOTREACHED*/\n            break;\n         }\n      }\n\n      avail = (sizeof last->buffer) - read_count;\n      if (avail > size)\n         avail = size;\n\n      memcpy(data, last->buffer + read_count, avail);\n      read_count += avail;\n      size -= avail;\n      data += avail;\n   }\n\n   bp->read_count = read_count;\n}\n\nstatic void PNGCBAPI\nread_function(png_structp pp, png_bytep data, png_size_t size)\n{\n   buffer_read(get_dp(pp), get_buffer(pp), data, size);\n}\n\nstatic void\nread_png(struct display *dp, struct buffer *bp, const char *operation,\n   int transforms)\n{\n   png_structp pp;\n   png_infop   ip;\n\n   /* This cleans out any previous read and sets operation and transforms to\n    * empty.\n    */\n   display_clean_read(dp);\n\n   if (operation != NULL) /* else this is a verify and do not overwrite info */\n   {\n      dp->operation = operation;\n      dp->transforms = transforms;\n   }\n\n   dp->read_pp = pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, dp,\n      display_error, display_warning);\n   if (pp == NULL)\n      display_log(dp, LIBPNG_ERROR, \"failed to create read struct\");\n\n   /* The png_read_png API requires us to make the info struct, but it does the\n    * call to png_read_info.\n    */\n   dp->read_ip = ip = png_create_info_struct(pp);\n   if (ip == NULL)\n      display_log(dp, LIBPNG_ERROR, \"failed to create info struct\");\n\n#  ifdef PNG_SET_USER_LIMITS_SUPPORTED\n      /* Remove the user limits, if any */\n      png_set_user_limits(pp, 0x7fffffff, 0x7fffffff);\n#  endif\n\n   /* Set the IO handling */\n   buffer_start_read(bp);\n   png_set_read_fn(pp, bp, read_function);\n\n   png_read_png(pp, ip, transforms, NULL/*params*/);\n\n#if 0 /* crazy debugging */\n   {\n      png_bytep pr = png_get_rows(pp, ip)[0];\n      size_t rb = png_get_rowbytes(pp, ip);\n      size_t cb;\n      char c = ' ';\n\n      fprintf(stderr, \"%.4x %2d (%3lu bytes):\", transforms, png_get_bit_depth(pp,ip), (unsigned long)rb);\n\n      for (cb=0; cb<rb; ++cb)\n         fputc(c, stderr), fprintf(stderr, \"%.2x\", pr[cb]), c='.';\n\n      fputc('\\n', stderr);\n   }\n#endif\n}\n\nstatic void\nupdate_display(struct display *dp)\n   /* called once after the first read to update all the info, original_pp and\n    * original_ip must have been filled in.\n    */\n{\n   png_structp pp;\n   png_infop   ip;\n\n   /* Now perform the initial read with a 0 tranform. */\n   read_png(dp, &dp->original_file, \"original read\", 0/*no transform*/);\n\n   /* Move the result to the 'original' fields */\n   dp->original_pp = pp = dp->read_pp, dp->read_pp = NULL;\n   dp->original_ip = ip = dp->read_ip, dp->read_ip = NULL;\n\n   dp->original_rowbytes = png_get_rowbytes(pp, ip);\n   if (dp->original_rowbytes == 0)\n      display_log(dp, LIBPNG_BUG, \"png_get_rowbytes returned 0\");\n\n   dp->chunks = png_get_valid(pp, ip, 0xffffffff);\n   if ((dp->chunks & PNG_INFO_IDAT) == 0) /* set by png_read_png */\n      display_log(dp, LIBPNG_BUG, \"png_read_png did not set IDAT flag\");\n\n   dp->original_rows = png_get_rows(pp, ip);\n   if (dp->original_rows == NULL)\n      display_log(dp, LIBPNG_BUG, \"png_read_png did not create row buffers\");\n\n   if (!png_get_IHDR(pp, ip,\n      &dp->width, &dp->height, &dp->bit_depth, &dp->color_type,\n      &dp->interlace_method, &dp->compression_method, &dp->filter_method))\n      display_log(dp, LIBPNG_BUG, \"png_get_IHDR failed\");\n\n   /* 'active' transforms are discovered based on the original image format;\n    * running one active transform can activate others.  At present the code\n    * does not attempt to determine the closure.\n    */\n   {\n      png_uint_32 chunks = dp->chunks;\n      int active = 0, inactive = 0;\n      int ct = dp->color_type;\n      int bd = dp->bit_depth;\n      unsigned int i;\n\n      for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL)\n      {\n         int transform = transform_info[i].transform;\n\n         if ((transform_info[i].valid_chunks == 0 ||\n               (transform_info[i].valid_chunks & chunks) != 0) &&\n            (transform_info[i].color_mask_required & ct) ==\n               transform_info[i].color_mask_required &&\n            (transform_info[i].color_mask_absent & ct) == 0 &&\n            (transform_info[i].bit_depths & bd) != 0 &&\n            (transform_info[i].when & TRANSFORM_R) != 0)\n            active |= transform;\n\n         else if ((transform_info[i].when & TRANSFORM_R) != 0)\n            inactive |= transform;\n      }\n\n      /* Some transforms appear multiple times in the table; the 'active' status\n       * is the logical OR of these and the inactive status must be adjusted to\n       * take this into account.\n       */\n      inactive &= ~active;\n\n      dp->active_transforms = active;\n      dp->ignored_transforms = inactive; /* excluding write-only transforms */\n   }\n}\n\nstatic int\ncompare_read(struct display *dp, int applied_transforms)\n{\n   /* Compare the png_info from read_ip with original_info */\n   size_t rowbytes;\n   png_uint_32 width, height;\n   int bit_depth, color_type;\n   int interlace_method, compression_method, filter_method;\n   const char *e = NULL;\n\n   png_get_IHDR(dp->read_pp, dp->read_ip, &width, &height, &bit_depth,\n      &color_type, &interlace_method, &compression_method, &filter_method);\n\n#  define C(item) if (item != dp->item) \\\n      display_log(dp, APP_WARNING, \"IHDR \" #item \"(%lu) changed to %lu\",\\\n         (unsigned long)dp->item, (unsigned long)item), e = #item\n\n   /* The IHDR should be identical: */\n   C(width);\n   C(height);\n   C(bit_depth);\n   C(color_type);\n   C(interlace_method);\n   C(compression_method);\n   C(filter_method);\n\n   /* 'e' remains set to the name of the last thing changed: */\n   if (e)\n      display_log(dp, APP_ERROR, \"IHDR changed (%s)\", e);\n\n   /* All the chunks from the original PNG should be preserved in the output PNG\n    * because the PNG format has not been changed.\n    */\n   {\n      unsigned long chunks =\n         png_get_valid(dp->read_pp, dp->read_ip, 0xffffffff);\n\n      if (chunks != dp->chunks)\n         display_log(dp, APP_FAIL, \"PNG chunks changed from 0x%lx to 0x%lx\",\n            (unsigned long)dp->chunks, chunks);\n   }\n\n   /* rowbytes should be the same */\n   rowbytes = png_get_rowbytes(dp->read_pp, dp->read_ip);\n\n   /* NOTE: on 64-bit systems this may trash the top bits of rowbytes,\n    * which could lead to weird error messages.\n    */\n   if (rowbytes != dp->original_rowbytes)\n      display_log(dp, APP_ERROR, \"PNG rowbytes changed from %lu to %lu\",\n         (unsigned long)dp->original_rowbytes, (unsigned long)rowbytes);\n\n   /* The rows should be the same too, unless the applied transforms includes\n    * the shift transform, in which case low bits may have been lost.\n    */\n   {\n      png_bytepp rows = png_get_rows(dp->read_pp, dp->read_ip);\n      unsigned int mask;  /* mask (if not zero) for the final byte */\n\n      if (bit_depth < 8)\n      {\n         /* Need the stray bits at the end, this depends only on the low bits\n          * of the image width; overflow does not matter.  If the width is an\n          * exact multiple of 8 bits this gives a mask of 0, not 0xff.\n          */\n         mask = 0xff & (0xff00 >> ((bit_depth * width) & 7));\n      }\n\n      else\n         mask = 0;\n\n      if (rows == NULL)\n         display_log(dp, LIBPNG_BUG, \"png_get_rows returned NULL\");\n\n      if ((applied_transforms & PNG_TRANSFORM_SHIFT) == 0 ||\n         (dp->active_transforms & PNG_TRANSFORM_SHIFT) == 0 ||\n         color_type == PNG_COLOR_TYPE_PALETTE)\n      {\n         unsigned long y;\n\n         for (y=0; y<height; ++y)\n         {\n            png_bytep row = rows[y];\n            png_bytep orig = dp->original_rows[y];\n\n            if (memcmp(row, orig, rowbytes-(mask != 0)) != 0 || (mask != 0 &&\n               ((row[rowbytes-1] & mask) != (orig[rowbytes-1] & mask))))\n            {\n               size_t x;\n\n               /* Find the first error */\n               for (x=0; x<rowbytes-1; ++x) if (row[x] != orig[x])\n                  break;\n\n               display_log(dp, APP_FAIL,\n                  \"byte(%lu,%lu) changed 0x%.2x -> 0x%.2x\",\n                  (unsigned long)x, (unsigned long)y, orig[x], row[x]);\n               return 0; /* don't keep reporting failed rows on 'continue' */\n            }\n         }\n      }\n\n      else\n      {\n         unsigned long y;\n         int bpp;   /* bits-per-pixel then bytes-per-pixel */\n         /* components are up to 8 bytes in size */\n         png_byte sig_bits[8];\n         png_color_8p sBIT;\n\n         if (png_get_sBIT(dp->read_pp, dp->read_ip, &sBIT) != PNG_INFO_sBIT)\n            display_log(dp, INTERNAL_ERROR,\n               \"active shift transform but no sBIT in file\");\n\n         switch (color_type)\n         {\n            case PNG_COLOR_TYPE_GRAY:\n               sig_bits[0] = sBIT->gray;\n               bpp = bit_depth;\n               break;\n\n            case PNG_COLOR_TYPE_GA:\n               sig_bits[0] = sBIT->gray;\n               sig_bits[1] = sBIT->alpha;\n               bpp = 2 * bit_depth;\n               break;\n\n            case PNG_COLOR_TYPE_RGB:\n               sig_bits[0] = sBIT->red;\n               sig_bits[1] = sBIT->green;\n               sig_bits[2] = sBIT->blue;\n               bpp = 3 * bit_depth;\n               break;\n\n            case PNG_COLOR_TYPE_RGBA:\n               sig_bits[0] = sBIT->red;\n               sig_bits[1] = sBIT->green;\n               sig_bits[2] = sBIT->blue;\n               sig_bits[3] = sBIT->alpha;\n               bpp = 4 * bit_depth;\n               break;\n\n            default:\n               display_log(dp, LIBPNG_ERROR, \"invalid colour type %d\",\n                  color_type);\n               /*NOTREACHED*/\n               bpp = 0;\n               break;\n         }\n\n         {\n            int b;\n\n            for (b=0; 8*b<bpp; ++b)\n            {\n               /* libpng should catch this; if not there is a security issue\n                * because an app (like this one) may overflow an array. In fact\n                * libpng doesn't catch this at present.\n                */\n               if (sig_bits[b] == 0 || sig_bits[b] > bit_depth/*!palette*/)\n                  display_log(dp, LIBPNG_BUG,\n                     \"invalid sBIT[%u]  value %d returned for PNG bit depth %d\",\n                     b, sig_bits[b], bit_depth);\n            }\n         }\n\n         if (bpp < 8 && bpp != bit_depth)\n         {\n            /* sanity check; this is a grayscale PNG; something is wrong in the\n             * code above.\n             */\n            display_log(dp, INTERNAL_ERROR, \"invalid bpp %u for bit_depth %u\",\n               bpp, bit_depth);\n         }\n\n         switch (bit_depth)\n         {\n            int b;\n\n            case 16: /* Two bytes per component, big-endian */\n               for (b = (bpp >> 4); b > 0; --b)\n               {\n                  unsigned int sig = (unsigned int)(0xffff0000 >> sig_bits[b]);\n\n                  sig_bits[2*b+1] = (png_byte)sig;\n                  sig_bits[2*b+0] = (png_byte)(sig >> 8); /* big-endian */\n               }\n               break;\n\n            case 8: /* One byte per component */\n               for (b=0; b*8 < bpp; ++b)\n                  sig_bits[b] = (png_byte)(0xff00 >> sig_bits[b]);\n               break;\n\n            case 1: /* allowed, but dumb */\n               /* Value is 1 */\n               sig_bits[0] = 0xff;\n               break;\n\n            case 2: /* Replicate 4 times */\n               /* Value is 1 or 2 */\n               b = 0x3 & ((0x3<<2) >> sig_bits[0]);\n               b |= b << 2;\n               b |= b << 4;\n               sig_bits[0] = (png_byte)b;\n               break;\n\n            case 4: /* Relicate twice */\n               /* Value is 1, 2, 3 or 4 */\n               b = 0xf & ((0xf << 4) >> sig_bits[0]);\n               b |= b << 4;\n               sig_bits[0] = (png_byte)b;\n               break;\n\n            default:\n               display_log(dp, LIBPNG_BUG, \"invalid bit depth %d\", bit_depth);\n               break;\n         }\n\n         /* Convert bpp to bytes; this gives '1' for low-bit depth grayscale,\n          * where there are multiple pixels per byte.\n          */\n         bpp = (bpp+7) >> 3;\n\n         /* The mask can be combined with sig_bits[0] */\n         if (mask != 0)\n         {\n            mask &= sig_bits[0];\n\n            if (bpp != 1 || mask == 0)\n               display_log(dp, INTERNAL_ERROR, \"mask calculation error %u, %u\",\n                  bpp, mask);\n         }\n\n         for (y=0; y<height; ++y)\n         {\n            png_bytep row = rows[y];\n            png_bytep orig = dp->original_rows[y];\n            unsigned long x;\n\n            for (x=0; x<(width-(mask!=0)); ++x)\n            {\n               int b;\n\n               for (b=0; b<bpp; ++b)\n               {\n                  if ((*row++ & sig_bits[b]) != (*orig++ & sig_bits[b]))\n                  {\n                     display_log(dp, APP_FAIL,\n                        \"significant bits at (%lu[%u],%lu) changed %.2x->%.2x\",\n                        x, b, y, orig[-1], row[-1]);\n                     return 0;\n                  }\n               }\n            }\n\n            if (mask != 0 && (*row & mask) != (*orig & mask))\n            {\n               display_log(dp, APP_FAIL,\n                  \"significant bits at (%lu[end],%lu) changed\", x, y);\n               return 0;\n            }\n         } /* for y */\n      }\n   }\n\n   return 1; /* compare succeeded */\n}\n\n#ifdef PNG_WRITE_SUPPORTED\nstatic void\nbuffer_write(struct display *dp, struct buffer *buffer, png_bytep data,\n   png_size_t size)\n   /* Generic write function used both from the write callback provided to\n    * libpng and from the generic read code.\n    */\n{\n   /* Write the data into the buffer, adding buffers as required */\n   struct buffer_list *last = buffer->last;\n   size_t end_count = buffer->end_count;\n\n   while (size > 0)\n   {\n      size_t avail;\n\n      if (end_count >= sizeof last->buffer)\n      {\n         if (last->next == NULL)\n         {\n            last = buffer_extend(last);\n\n            if (last == NULL)\n               display_log(dp, APP_ERROR, \"out of memory saving file\");\n         }\n\n         else\n            last = last->next;\n\n         buffer->last = last; /* avoid the need to rewrite every time */\n         end_count = 0;\n      }\n\n      avail = (sizeof last->buffer) - end_count;\n      if (avail > size)\n         avail = size;\n\n      memcpy(last->buffer + end_count, data, avail);\n      end_count += avail;\n      size -= avail;\n      data += avail;\n   }\n\n   buffer->end_count = end_count;\n}\n\nstatic void PNGCBAPI\nwrite_function(png_structp pp, png_bytep data, png_size_t size)\n{\n   buffer_write(get_dp(pp), get_buffer(pp), data, size);\n}\n\nstatic void\nwrite_png(struct display *dp, png_infop ip, int transforms)\n{\n   display_clean_write(dp); /* safety */\n\n   buffer_start_write(&dp->written_file);\n   dp->operation = \"write\";\n   dp->transforms = transforms;\n\n   dp->write_pp = png_create_write_struct(PNG_LIBPNG_VER_STRING, dp,\n      display_error, display_warning);\n\n   if (dp->write_pp == NULL)\n      display_log(dp, APP_ERROR, \"failed to create write png_struct\");\n\n   png_set_write_fn(dp->write_pp, &dp->written_file, write_function,\n      NULL/*flush*/);\n\n#  ifdef PNG_SET_USER_LIMITS_SUPPORTED\n      /* Remove the user limits, if any */\n      png_set_user_limits(dp->write_pp, 0x7fffffff, 0x7fffffff);\n#  endif\n\n   /* Certain transforms require the png_info to be zapped to allow the\n    * transform to work correctly.\n    */\n   if (transforms & (PNG_TRANSFORM_PACKING|\n                     PNG_TRANSFORM_STRIP_FILLER|\n                     PNG_TRANSFORM_STRIP_FILLER_BEFORE))\n   {\n      int ct = dp->color_type;\n\n      if (transforms & (PNG_TRANSFORM_STRIP_FILLER|\n                        PNG_TRANSFORM_STRIP_FILLER_BEFORE))\n         ct &= ~PNG_COLOR_MASK_ALPHA;\n\n      png_set_IHDR(dp->write_pp, ip, dp->width, dp->height, dp->bit_depth, ct,\n         dp->interlace_method, dp->compression_method, dp->filter_method);\n   }\n\n   png_write_png(dp->write_pp, ip, transforms, NULL/*params*/);\n\n   /* Clean it on the way out - if control returns to the caller then the\n    * written_file contains the required data.\n    */\n   display_clean_write(dp);\n}\n#endif /* WRITE_SUPPORTED */\n\nstatic int\nskip_transform(struct display *dp, int tr)\n   /* Helper to test for a bad combo and log it if it is skipped */\n{\n   if ((dp->options & SKIP_BUGS) != 0 && is_bad_combo(tr))\n   {\n      /* Log this to stdout if logging is on, otherwise just do an information\n       * display_log.\n       */\n      if ((dp->options & LOG_SKIPPED) != 0)\n      {\n         printf(\"SKIP: %s transforms \", dp->filename);\n\n         while (tr != 0)\n         {\n            int next = first_transform(tr);\n            tr &= ~next;\n\n            printf(\"%s\", transform_name(next));\n            if (tr != 0)\n               putchar('+');\n         }\n\n         putchar('\\n');\n      }\n\n      else\n         display_log(dp, INFORMATION, \"%s: skipped known bad combo 0x%x\",\n            dp->filename, tr);\n\n      return 1; /* skip */\n   }\n\n   return 0; /* don't skip */\n}\n\nstatic void\ntest_one_file(struct display *dp, const char *filename)\n{\n   /* First cache the file and update the display original file\n    * information for the new file.\n    */\n   dp->operation = \"cache file\";\n   dp->transforms = 0;\n   display_cache_file(dp, filename);\n   update_display(dp);\n\n   /* First test: if there are options that should be ignored for this file\n    * verify that they really are ignored.\n    */\n   if (dp->ignored_transforms != 0)\n   {\n      read_png(dp, &dp->original_file, \"ignored transforms\",\n         dp->ignored_transforms);\n\n      /* The result should be identical to the original_rows */\n      if (!compare_read(dp, 0/*transforms applied*/))\n         return; /* no point testing more */\n   }\n\n#ifdef PNG_WRITE_SUPPORTED\n   /* Second test: write the original PNG data out to a new file (to test the\n    * write side) then read the result back in and make sure that it hasn't\n    * changed.\n    */\n   dp->operation = \"write\";\n   write_png(dp, dp->original_ip, 0/*transforms*/);\n   read_png(dp, &dp->written_file, NULL, 0/*transforms*/);\n   if (!compare_read(dp, 0/*transforms applied*/))\n      return;\n#endif\n\n   /* Third test: the active options.  Test each in turn, or, with the\n    * EXHAUSTIVE option, test all possible combinations.\n    */\n   {\n      /* Use unsigned int here because the code below to increment through all\n       * the possibilities exhaustively has to use a compare and that must be\n       * unsigned, because some transforms are negative on a 16-bit system.\n       */\n      unsigned int active = dp->active_transforms;\n      const int exhaustive = (dp->options & EXHAUSTIVE) != 0;\n      unsigned int current = first_transform(active);\n      unsigned int bad_transforms = 0;\n      unsigned int bad_combo = ~0U;    /* bitwise AND of failing transforms */\n      unsigned int bad_combo_list = 0; /* bitwise OR of failures */\n\n      for (;;)\n      {\n         read_png(dp, &dp->original_file, \"active transforms\", current);\n\n         /* If this involved any irreversible transformations then if we write\n          * it out with just the reversible transformations and read it in again\n          * with the same transforms we should get the same thing.  At present\n          * this isn't done - it just seems like a waste of time and it would\n          * require two sets of read png_struct/png_info.\n          *\n          * If there were no irreversible transformations then if we write it\n          * out and read it back in again (without the reversible transforms)\n          * we should get back to the place where we started.\n          */\n#ifdef PNG_WRITE_SUPPORTED\n         if ((current & write_transforms) == current)\n         {\n            /* All transforms reversible: write the PNG with the transformations\n             * reversed, then read it back in with no transformations.  The\n             * result should be the same as the original apart from the loss of\n             * low order bits because of the SHIFT/sBIT transform.\n             */\n            dp->operation = \"reversible transforms\";\n            write_png(dp, dp->read_ip, current);\n\n            /* And if this is read back in, because all the transformations were\n             * reversible, the result should be the same.\n             */\n            read_png(dp, &dp->written_file, NULL, 0);\n            if (!compare_read(dp, current/*for the SHIFT/sBIT transform*/))\n            {\n               /* This set of transforms failed.  If a single bit is set - if\n                * there is just one transform - don't include this in further\n                * 'exhaustive' tests.  Notice that each transform is tested on\n                * its own before testing combos in the exhaustive case.\n                */\n               if (is_combo(current))\n               {\n                  bad_combo &= current;\n                  bad_combo_list |= current;\n               }\n\n               else\n                  bad_transforms |= current;\n            }\n         }\n#endif\n\n         /* Now move to the next transform */\n         if (exhaustive) /* all combinations */\n         {\n            unsigned int next = current;\n\n            do\n            {\n               if (next == read_transforms) /* Everything tested */\n                  goto combo;\n\n               ++next;\n            }  /* skip known bad combos if the relevant option is set; skip\n                * combos involving known bad single transforms in all cases.\n                */\n            while (  (next & read_transforms) <= current\n                  || (next & active) == 0 /* skip cases that do nothing */\n                  || (next & bad_transforms) != 0\n                  || skip_transform(dp, next));\n\n            assert((next & read_transforms) == next);\n            current = next;\n         }\n\n         else /* one at a time */\n         {\n            active &= ~current;\n\n            if (active == 0)\n               goto combo;\n\n            current = first_transform(active);\n         }\n      }\n\ncombo:\n      if (dp->options & FIND_BAD_COMBOS)\n      {\n         /* bad_combos identifies the combos that occur in all failing cases;\n          * bad_combo_list identifies transforms that do not prevent the\n          * failure.\n          */\n         if (bad_combo != ~0U)\n            printf(\"%s[0x%x]: PROBLEM: 0x%x[0x%x] ANTIDOTE: 0x%x\\n\",\n               dp->filename, active, bad_combo, bad_combo_list,\n               rw_transforms & ~bad_combo_list);\n\n         else\n            printf(\"%s: no %sbad combos found\\n\", dp->filename,\n               (dp->options & SKIP_BUGS) ? \"additional \" : \"\");\n      }\n   }\n}\n\nstatic int\ndo_test(struct display *dp, const char *file)\n   /* Exists solely to isolate the setjmp clobbers */\n{\n   int ret = setjmp(dp->error_return);\n\n   if (ret == 0)\n   {\n      test_one_file(dp, file);\n      return 0;\n   }\n\n   else if (ret < ERRORS) /* shouldn't longjmp on warnings */\n      display_log(dp, INTERNAL_ERROR, \"unexpected return code %d\", ret);\n\n   return ret;\n}\n\nint\nmain(const int argc, const char * const * const argv)\n{\n   /* For each file on the command line test it with a range of transforms */\n   int option_end, ilog = 0;\n   struct display d;\n\n   validate_T();\n   display_init(&d);\n\n   for (option_end=1; option_end<argc; ++option_end)\n   {\n      const char *name = argv[option_end];\n\n      if (strcmp(name, \"--verbose\") == 0)\n         d.options = (d.options & ~LEVEL_MASK) | VERBOSE;\n\n      else if (strcmp(name, \"--warnings\") == 0)\n         d.options = (d.options & ~LEVEL_MASK) | WARNINGS;\n\n      else if (strcmp(name, \"--errors\") == 0)\n         d.options = (d.options & ~LEVEL_MASK) | ERRORS;\n\n      else if (strcmp(name, \"--quiet\") == 0)\n         d.options = (d.options & ~LEVEL_MASK) | QUIET;\n\n      else if (strcmp(name, \"--exhaustive\") == 0)\n         d.options |= EXHAUSTIVE;\n\n      else if (strcmp(name, \"--fast\") == 0)\n         d.options &= ~EXHAUSTIVE;\n\n      else if (strcmp(name, \"--strict\") == 0)\n         d.options |= STRICT;\n\n      else if (strcmp(name, \"--relaxed\") == 0)\n         d.options &= ~STRICT;\n\n      else if (strcmp(name, \"--log\") == 0)\n      {\n         ilog = option_end; /* prevent display */\n         d.options |= LOG;\n      }\n\n      else if (strcmp(name, \"--nolog\") == 0)\n         d.options &= ~LOG;\n\n      else if (strcmp(name, \"--continue\") == 0)\n         d.options |= CONTINUE;\n\n      else if (strcmp(name, \"--stop\") == 0)\n         d.options &= ~CONTINUE;\n\n      else if (strcmp(name, \"--skip-bugs\") == 0)\n         d.options |= SKIP_BUGS;\n\n      else if (strcmp(name, \"--test-all\") == 0)\n         d.options &= ~SKIP_BUGS;\n\n      else if (strcmp(name, \"--log-skipped\") == 0)\n         d.options |= LOG_SKIPPED;\n\n      else if (strcmp(name, \"--nolog-skipped\") == 0)\n         d.options &= ~LOG_SKIPPED;\n\n      else if (strcmp(name, \"--find-bad-combos\") == 0)\n         d.options |= FIND_BAD_COMBOS;\n\n      else if (strcmp(name, \"--nofind-bad-combos\") == 0)\n         d.options &= ~FIND_BAD_COMBOS;\n\n      else if (strcmp(name, \"--list-combos\") == 0)\n         d.options |= LIST_COMBOS;\n\n      else if (strcmp(name, \"--nolist-combos\") == 0)\n         d.options &= ~LIST_COMBOS;\n\n      else if (name[0] == '-' && name[1] == '-')\n      {\n         fprintf(stderr, \"pngimage: %s: unknown option\\n\", name);\n         return 99;\n      }\n\n      else\n         break; /* Not an option */\n   }\n\n   {\n      int i;\n      int errors = 0;\n\n      for (i=option_end; i<argc; ++i)\n      {\n         {\n            int ret = do_test(&d, argv[i]);\n\n            if (ret > QUIET) /* abort on user or internal error */\n               return 99;\n         }\n\n         /* Here on any return, including failures, except user/internal issues\n          */\n         {\n            const int pass = (d.options & STRICT) ?\n               RESULT_STRICT(d.results) : RESULT_RELAXED(d.results);\n\n            if (!pass)\n               ++errors;\n\n            if (d.options & LOG)\n            {\n               int j;\n\n               printf(\"%s: pngimage \", pass ? \"PASS\" : \"FAIL\");\n\n               for (j=1; j<option_end; ++j) if (j != ilog)\n                  printf(\"%s \", argv[j]);\n\n               printf(\"%s\\n\", d.filename);\n            }\n         }\n\n         display_clean(&d);\n      }\n\n      /* Release allocated memory */\n      display_destroy(&d);\n\n      return errors != 0;\n   }\n}\n#else /* !INFO_IMAGE || !SEQUENTIAL_READ || !READ_PNG*/\nint\nmain(void)\n{\n   fprintf(stderr, \"pngimage: no support for png_read/write_image\\n\");\n   return SKIP;\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/libtests/pngstest-errors.h",
    "content": "/* contrib/libtests/pngstest-errors.h\n *\n * BUILT USING: libpng version 1.6.19beta03 - September 25, 2015\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * THIS IS A MACHINE GENERATED FILE: do not edit it directly!\n * Instead run:\n *\n *    pngstest --accumulate\n *\n * on as many PNG files as possible; at least PNGSuite and\n * contrib/libtests/testpngs.\n */\nstatic png_uint_16 gpc_error[16/*in*/][16/*out*/][4/*a*/] =\n{\n { /* input: sRGB-gray */\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 372, 0 }, { 0, 0, 372, 0 }, { 0, 0, 372, 0 }, { 0, 0, 372, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: sRGB-gray+alpha */\n  { 0, 19, 0, 0 }, { 0, 0, 0, 0 }, { 0, 20, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 897, 788, 0 }, { 0, 897, 788, 0 }, { 0, 897, 788, 0 }, { 0, 897, 788, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: sRGB-rgb */\n  { 0, 0, 19, 0 }, { 0, 0, 19, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 893, 0 }, { 0, 0, 893, 0 }, { 0, 0, 811, 0 }, { 0, 0, 811, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: sRGB-rgb+alpha */\n  { 0, 16, 17, 0 }, { 0, 17, 17, 0 }, { 0, 19, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 850, 875, 0 }, { 0, 850, 875, 0 }, { 0, 897, 788, 0 }, { 0, 897, 788, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: linear-gray */\n  { 0, 0, 9, 0 }, { 0, 0, 9, 0 }, { 0, 0, 9, 0 }, { 0, 0, 9, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: linear-gray+alpha */\n  { 0, 74, 9, 0 }, { 0, 20, 9, 0 }, { 0, 74, 9, 0 }, { 0, 20, 9, 0 },\n  { 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 }, { 0, 1, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: linear-rgb */\n  { 0, 0, 9, 0 }, { 0, 0, 9, 0 }, { 0, 0, 9, 0 }, { 0, 0, 9, 0 },\n  { 0, 0, 4, 0 }, { 0, 0, 4, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: linear-rgb+alpha */\n  { 0, 126, 143, 0 }, { 0, 11, 7, 0 }, { 0, 74, 9, 0 }, { 0, 17, 9, 0 },\n  { 0, 4, 4, 0 }, { 0, 5, 4, 0 }, { 0, 0, 0, 0 }, { 0, 1, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: color-mapped-sRGB-gray */\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: color-mapped-sRGB-gray+alpha */\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: color-mapped-sRGB-rgb */\n  { 0, 0, 13, 0 }, { 0, 0, 13, 0 }, { 0, 0, 9, 0 }, { 0, 0, 9, 0 },\n  { 0, 0, 673, 0 }, { 0, 0, 673, 0 }, { 0, 0, 674, 0 }, { 0, 0, 674, 0 },\n  { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 460, 0 }, { 0, 0, 460, 0 }, { 0, 0, 263, 0 }, { 0, 0, 263, 0 }\n }, { /* input: color-mapped-sRGB-rgb+alpha */\n  { 0, 6, 8, 0 }, { 0, 7, 8, 0 }, { 0, 75, 9, 0 }, { 0, 9, 9, 0 },\n  { 0, 585, 427, 0 }, { 0, 585, 427, 0 }, { 0, 717, 514, 0 }, { 0, 717, 514, 0 },\n  { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 13323, 460, 0 }, { 0, 427, 460, 0 }, { 0, 16480, 263, 0 }, { 0, 243, 263, 0 }\n }, { /* input: color-mapped-linear-gray */\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 282, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: color-mapped-linear-gray+alpha */\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 253, 282, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: color-mapped-linear-rgb */\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 265, 0 }, { 0, 0, 0, 0 }\n }, { /* input: color-mapped-linear-rgb+alpha */\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 243, 265, 0 }\n }\n};\nstatic png_uint_16 gpc_error_via_linear[16][4/*out*/][4] =\n{\n { /* input: sRGB-gray */\n  { 0, 0, 7, 0 }, { 0, 0, 7, 0 }, { 0, 0, 7, 0 }, { 0, 0, 7, 0 }\n }, { /* input: sRGB-gray+alpha */\n  { 0, 15, 15, 0 }, { 0, 186, 15, 0 }, { 0, 15, 15, 0 }, { 0, 186, 15, 0 }\n }, { /* input: sRGB-rgb */\n  { 0, 0, 20, 0 }, { 0, 0, 20, 0 }, { 0, 0, 15, 0 }, { 0, 0, 15, 0 }\n }, { /* input: sRGB-rgb+alpha */\n  { 0, 16, 17, 0 }, { 0, 187, 17, 0 }, { 0, 15, 15, 0 }, { 0, 186, 15, 0 }\n }, { /* input: linear-gray */\n  { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }\n }, { /* input: linear-gray+alpha */\n  { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }\n }, { /* input: linear-rgb */\n  { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }\n }, { /* input: linear-rgb+alpha */\n  { 0, 1, 1, 0 }, { 0, 9, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }\n }, { /* input: color-mapped-sRGB-gray */\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: color-mapped-sRGB-gray+alpha */\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: color-mapped-sRGB-rgb */\n  { 0, 0, 13, 0 }, { 0, 0, 13, 0 }, { 0, 0, 14, 0 }, { 0, 0, 14, 0 }\n }, { /* input: color-mapped-sRGB-rgb+alpha */\n  { 0, 4, 8, 0 }, { 0, 9, 8, 0 }, { 0, 9, 5, 0 }, { 0, 32, 5, 0 }\n }, { /* input: color-mapped-linear-gray */\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: color-mapped-linear-gray+alpha */\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: color-mapped-linear-rgb */\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }, { /* input: color-mapped-linear-rgb+alpha */\n  { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }\n }\n};\nstatic png_uint_16 gpc_error_to_colormap[8/*i*/][8/*o*/][4] =\n{\n { /* input: sRGB-gray */\n  { 0, 0, 9, 0 }, { 0, 0, 9, 0 }, { 0, 0, 9, 0 }, { 0, 0, 9, 0 },\n  { 0, 0, 560, 0 }, { 0, 0, 560, 0 }, { 0, 0, 560, 0 }, { 0, 0, 560, 0 }\n }, { /* input: sRGB-gray+alpha */\n  { 0, 19, 9, 0 }, { 0, 255, 9, 25 }, { 0, 88, 9, 0 }, { 0, 255, 9, 25 },\n  { 0, 1012, 928, 0 }, { 0, 16026, 928, 6425 }, { 0, 1012, 928, 0 }, { 0, 16026, 928, 6425 }\n }, { /* input: sRGB-rgb */\n  { 0, 0, 19, 0 }, { 0, 0, 19, 0 }, { 0, 0, 25, 0 }, { 0, 0, 25, 0 },\n  { 0, 0, 962, 0 }, { 0, 0, 962, 0 }, { 0, 0, 13677, 0 }, { 0, 0, 13677, 0 }\n }, { /* input: sRGB-rgb+alpha */\n  { 0, 63, 77, 0 }, { 0, 255, 19, 25 }, { 0, 225, 25, 0 }, { 0, 255, 25, 67 },\n  { 0, 17534, 18491, 0 }, { 0, 15736, 2824, 6425 }, { 0, 14019, 13677, 0 }, { 0, 50115, 13677, 17219 }\n }, { /* input: linear-gray */\n  { 0, 0, 73, 0 }, { 0, 0, 73, 0 }, { 0, 0, 73, 0 }, { 0, 0, 73, 0 },\n  { 0, 0, 18817, 0 }, { 0, 0, 18817, 0 }, { 0, 0, 18817, 0 }, { 0, 0, 18817, 0 }\n }, { /* input: linear-gray+alpha */\n  { 0, 74, 74, 0 }, { 0, 255, 74, 25 }, { 0, 99, 74, 0 }, { 0, 255, 74, 25 },\n  { 0, 18919, 18907, 0 }, { 0, 24549, 18907, 6553 }, { 0, 18919, 18907, 0 }, { 0, 24549, 18907, 6553 }\n }, { /* input: linear-rgb */\n  { 0, 0, 73, 0 }, { 0, 0, 73, 0 }, { 0, 0, 98, 0 }, { 0, 0, 98, 0 },\n  { 0, 0, 18664, 0 }, { 0, 0, 18664, 0 }, { 0, 0, 24998, 0 }, { 0, 0, 24998, 0 }\n }, { /* input: linear-rgb+alpha */\n  { 0, 181, 196, 0 }, { 0, 255, 61, 25 }, { 206, 187, 98, 0 }, { 0, 255, 98, 67 },\n  { 0, 18141, 18137, 0 }, { 0, 17494, 17504, 6553 }, { 0, 24979, 24992, 0 }, { 0, 49172, 24992, 17347 }\n }\n};\n/* END MACHINE GENERATED */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/libtests/pngstest.c",
    "content": "/*-\n * pngstest.c\n *\n * Copyright (c) 2013-2016 John Cunningham Bowler\n *\n * Last changed in libpng 1.6.22 [(PENDING RELEASE)]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * Test for the PNG 'simplified' APIs.\n */\n#define _ISOC90_SOURCE 1\n#define MALLOC_CHECK_ 2/*glibc facility: turn on debugging*/\n\n#include <stddef.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <errno.h>\n#include <ctype.h>\n#include <math.h>\n\n#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)\n#  include <config.h>\n#endif\n\n/* 1.6.1 added support for the configure test harness, which uses 77 to indicate\n * a skipped test, in earlier versions we need to succeed on a skipped test, so:\n */\n#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)\n#  define SKIP 77\n#else\n#  define SKIP 0\n#endif\n\n/* Define the following to use this test against your installed libpng, rather\n * than the one being built here:\n */\n#ifdef PNG_FREESTANDING_TESTS\n#  include <png.h>\n#else\n#  include \"../../png.h\"\n#endif\n\n#ifdef PNG_SIMPLIFIED_READ_SUPPORTED /* Else nothing can be done */\n#include \"../tools/sRGB.h\"\n\n/* KNOWN ISSUES\n *\n * These defines switch on alternate algorithms for format conversions to match\n * the current libpng implementation; they are set to allow pngstest to pass\n * even though libpng is producing answers that are not as correct as they\n * should be.\n */\n#define ALLOW_UNUSED_GPC 0\n   /* If true include unused static GPC functions and declare an external array\n    * of them to hide the fact that they are unused.  This is for development\n    * use while testing the correct function to use to take into account libpng\n    * misbehavior, such as using a simple power law to correct sRGB to linear.\n    */\n\n/* The following is to support direct compilation of this file as C++ */\n#ifdef __cplusplus\n#  define voidcast(type, value) static_cast<type>(value)\n#  define aligncastconst(type, value) \\\n      static_cast<type>(static_cast<const void*>(value))\n#else\n#  define voidcast(type, value) (value)\n#  define aligncastconst(type, value) ((const void*)(value))\n#endif /* __cplusplus */\n\n/* During parallel runs of pngstest each temporary file needs a unique name,\n * this is used to permit uniqueness using a command line argument which can be\n * up to 22 characters long.\n */\nstatic char tmpf[23] = \"TMP\";\n\n/* Generate random bytes.  This uses a boring repeatable algorithm and it\n * is implemented here so that it gives the same set of numbers on every\n * architecture.  It's a linear congruential generator (Knuth or Sedgewick\n * \"Algorithms\") but it comes from the 'feedback taps' table in Horowitz and\n * Hill, \"The Art of Electronics\".\n */\nstatic void\nmake_random_bytes(png_uint_32* seed, void* pv, size_t size)\n{\n   png_uint_32 u0 = seed[0], u1 = seed[1];\n   png_bytep bytes = voidcast(png_bytep, pv);\n\n   /* There are thirty three bits, the next bit in the sequence is bit-33 XOR\n    * bit-20.  The top 1 bit is in u1, the bottom 32 are in u0.\n    */\n   size_t i;\n   for (i=0; i<size; ++i)\n   {\n      /* First generate 8 new bits then shift them in at the end. */\n      png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff;\n      u1 <<= 8;\n      u1 |= u0 >> 24;\n      u0 <<= 8;\n      u0 |= u;\n      *bytes++ = (png_byte)u;\n   }\n\n   seed[0] = u0;\n   seed[1] = u1;\n}\n\nstatic png_uint_32 color_seed[2];\n\nstatic void\nreseed(void)\n{\n   color_seed[0] = 0x12345678U;\n   color_seed[1] = 0x9abcdefU;\n}\n\nstatic void\nrandom_color(png_colorp color)\n{\n   make_random_bytes(color_seed, color, sizeof *color);\n}\n\n/* Math support - neither Cygwin nor Visual Studio have C99 support and we need\n * a predictable rounding function, so make one here:\n */\nstatic double\nclosestinteger(double x)\n{\n   return floor(x + .5);\n}\n\n/* Cast support: remove GCC whines. */\nstatic png_byte\nu8d(double d)\n{\n   d = closestinteger(d);\n   return (png_byte)d;\n}\n\nstatic png_uint_16\nu16d(double d)\n{\n   d = closestinteger(d);\n   return (png_uint_16)d;\n}\n\n/* sRGB support: use exact calculations rounded to the nearest int, see the\n * fesetround() call in main().  sRGB_to_d optimizes the 8 to 16-bit conversion.\n */\nstatic double sRGB_to_d[256];\nstatic double g22_to_d[256];\n\nstatic void\ninit_sRGB_to_d(void)\n{\n   int i;\n\n   sRGB_to_d[0] = 0;\n   for (i=1; i<255; ++i)\n      sRGB_to_d[i] = linear_from_sRGB(i/255.);\n   sRGB_to_d[255] = 1;\n\n   g22_to_d[0] = 0;\n   for (i=1; i<255; ++i)\n      g22_to_d[i] = pow(i/255., 1/.45455);\n   g22_to_d[255] = 1;\n}\n\nstatic png_byte\nsRGB(double linear /*range 0.0 .. 1.0*/)\n{\n   return u8d(255 * sRGB_from_linear(linear));\n}\n\nstatic png_byte\nisRGB(int fixed_linear)\n{\n   return sRGB(fixed_linear / 65535.);\n}\n\n#if 0 /* not used */\nstatic png_byte\nunpremultiply(int component, int alpha)\n{\n   if (alpha <= component)\n      return 255; /* Arbitrary, but consistent with the libpng code */\n\n   else if (alpha >= 65535)\n      return isRGB(component);\n\n   else\n      return sRGB((double)component / alpha);\n}\n#endif\n\nstatic png_uint_16\nilinear(int fixed_srgb)\n{\n   return u16d(65535 * sRGB_to_d[fixed_srgb]);\n}\n\nstatic png_uint_16\nilineara(int fixed_srgb, int alpha)\n{\n   return u16d((257 * alpha) * sRGB_to_d[fixed_srgb]);\n}\n\nstatic png_uint_16\nilinear_g22(int fixed_srgb)\n{\n   return u16d(65535 * g22_to_d[fixed_srgb]);\n}\n\n#if ALLOW_UNUSED_GPC\nstatic png_uint_16\nilineara_g22(int fixed_srgb, int alpha)\n{\n   return u16d((257 * alpha) * g22_to_d[fixed_srgb]);\n}\n#endif\n\nstatic double\nYfromRGBint(int ir, int ig, int ib)\n{\n   double r = ir;\n   double g = ig;\n   double b = ib;\n   return YfromRGB(r, g, b);\n}\n\n#if 0 /* unused */\n/* The error that results from using a 2.2 power law in place of the correct\n * sRGB transform, given an 8-bit value which might be either sRGB or power-law.\n */\nstatic int\npower_law_error8(int value)\n{\n   if (value > 0 && value < 255)\n   {\n      double vd = value / 255.;\n      double e = fabs(\n         pow(sRGB_to_d[value], 1/2.2) - sRGB_from_linear(pow(vd, 2.2)));\n\n      /* Always allow an extra 1 here for rounding errors */\n      e = 1+floor(255 * e);\n      return (int)e;\n   }\n\n   return 0;\n}\n\nstatic int error_in_sRGB_roundtrip = 56; /* by experiment */\nstatic int\npower_law_error16(int value)\n{\n   if (value > 0 && value < 65535)\n   {\n      /* Round trip the value through an 8-bit representation but using\n       * non-matching to/from conversions.\n       */\n      double vd = value / 65535.;\n      double e = fabs(\n         pow(sRGB_from_linear(vd), 2.2) - linear_from_sRGB(pow(vd, 1/2.2)));\n\n      /* Always allow an extra 1 here for rounding errors */\n      e = error_in_sRGB_roundtrip+floor(65535 * e);\n      return (int)e;\n   }\n\n   return 0;\n}\n\nstatic int\ncompare_8bit(int v1, int v2, int error_limit, int multiple_algorithms)\n{\n   int e = abs(v1-v2);\n   int ev1, ev2;\n\n   if (e <= error_limit)\n      return 1;\n\n   if (!multiple_algorithms)\n      return 0;\n\n   ev1 = power_law_error8(v1);\n   if (e <= ev1)\n      return 1;\n\n   ev2 = power_law_error8(v2);\n   if (e <= ev2)\n      return 1;\n\n   return 0;\n}\n\nstatic int\ncompare_16bit(int v1, int v2, int error_limit, int multiple_algorithms)\n{\n   int e = abs(v1-v2);\n   int ev1, ev2;\n\n   if (e <= error_limit)\n      return 1;\n\n   /* \"multiple_algorithms\" in this case means that a color-map has been\n    * involved somewhere, so we can deduce that the values were forced to 8-bit\n    * (like the via_linear case for 8-bit.)\n    */\n   if (!multiple_algorithms)\n      return 0;\n\n   ev1 = power_law_error16(v1);\n   if (e <= ev1)\n      return 1;\n\n   ev2 = power_law_error16(v2);\n   if (e <= ev2)\n      return 1;\n\n   return 0;\n}\n#endif /* unused */\n\n#define USE_FILE 1       /* else memory */\n#define USE_STDIO 2      /* else use file name */\n#define STRICT 4         /* fail on warnings too */\n#define VERBOSE 8\n#define KEEP_TMPFILES 16 /* else delete temporary files */\n#define KEEP_GOING 32\n#define ACCUMULATE 64\n#define FAST_WRITE 128\n#define sRGB_16BIT 256\n#define NO_RESEED  512   /* do not reseed on each new file */\n#define GBG_ERROR 1024   /* do not ignore the gamma+background_rgb_to_gray\n                          * libpng warning. */\n\nstatic void\nprint_opts(png_uint_32 opts)\n{\n   if (opts & USE_FILE)\n      printf(\" --file\");\n   if (opts & USE_STDIO)\n      printf(\" --stdio\");\n   if (!(opts & STRICT))\n      printf(\" --nostrict\");\n   if (opts & VERBOSE)\n      printf(\" --verbose\");\n   if (opts & KEEP_TMPFILES)\n      printf(\" --preserve\");\n   if (opts & KEEP_GOING)\n      printf(\" --keep-going\");\n   if (opts & ACCUMULATE)\n      printf(\" --accumulate\");\n   if (!(opts & FAST_WRITE)) /* --fast is currently the default */\n      printf(\" --slow\");\n   if (opts & sRGB_16BIT)\n      printf(\" --sRGB-16bit\");\n   if (opts & NO_RESEED)\n      printf(\" --noreseed\");\n#if PNG_LIBPNG_VER < 10700 /* else on by default */\n   if (opts & GBG_ERROR)\n      printf(\" --fault-gbg-warning\");\n#endif\n}\n\n#define FORMAT_NO_CHANGE 0x80000000 /* additional flag */\n\n/* A name table for all the formats - defines the format of the '+' arguments to\n * pngstest.\n */\n#define FORMAT_COUNT 64\n#define FORMAT_MASK 0x3f\nstatic PNG_CONST char * PNG_CONST format_names[FORMAT_COUNT] =\n{\n   \"sRGB-gray\",\n   \"sRGB-gray+alpha\",\n   \"sRGB-rgb\",\n   \"sRGB-rgb+alpha\",\n   \"linear-gray\",\n   \"linear-gray+alpha\",\n   \"linear-rgb\",\n   \"linear-rgb+alpha\",\n\n   \"color-mapped-sRGB-gray\",\n   \"color-mapped-sRGB-gray+alpha\",\n   \"color-mapped-sRGB-rgb\",\n   \"color-mapped-sRGB-rgb+alpha\",\n   \"color-mapped-linear-gray\",\n   \"color-mapped-linear-gray+alpha\",\n   \"color-mapped-linear-rgb\",\n   \"color-mapped-linear-rgb+alpha\",\n\n   \"sRGB-gray\",\n   \"sRGB-gray+alpha\",\n   \"sRGB-bgr\",\n   \"sRGB-bgr+alpha\",\n   \"linear-gray\",\n   \"linear-gray+alpha\",\n   \"linear-bgr\",\n   \"linear-bgr+alpha\",\n\n   \"color-mapped-sRGB-gray\",\n   \"color-mapped-sRGB-gray+alpha\",\n   \"color-mapped-sRGB-bgr\",\n   \"color-mapped-sRGB-bgr+alpha\",\n   \"color-mapped-linear-gray\",\n   \"color-mapped-linear-gray+alpha\",\n   \"color-mapped-linear-bgr\",\n   \"color-mapped-linear-bgr+alpha\",\n\n   \"sRGB-gray\",\n   \"alpha+sRGB-gray\",\n   \"sRGB-rgb\",\n   \"alpha+sRGB-rgb\",\n   \"linear-gray\",\n   \"alpha+linear-gray\",\n   \"linear-rgb\",\n   \"alpha+linear-rgb\",\n\n   \"color-mapped-sRGB-gray\",\n   \"color-mapped-alpha+sRGB-gray\",\n   \"color-mapped-sRGB-rgb\",\n   \"color-mapped-alpha+sRGB-rgb\",\n   \"color-mapped-linear-gray\",\n   \"color-mapped-alpha+linear-gray\",\n   \"color-mapped-linear-rgb\",\n   \"color-mapped-alpha+linear-rgb\",\n\n   \"sRGB-gray\",\n   \"alpha+sRGB-gray\",\n   \"sRGB-bgr\",\n   \"alpha+sRGB-bgr\",\n   \"linear-gray\",\n   \"alpha+linear-gray\",\n   \"linear-bgr\",\n   \"alpha+linear-bgr\",\n\n   \"color-mapped-sRGB-gray\",\n   \"color-mapped-alpha+sRGB-gray\",\n   \"color-mapped-sRGB-bgr\",\n   \"color-mapped-alpha+sRGB-bgr\",\n   \"color-mapped-linear-gray\",\n   \"color-mapped-alpha+linear-gray\",\n   \"color-mapped-linear-bgr\",\n   \"color-mapped-alpha+linear-bgr\",\n};\n\n/* Decode an argument to a format number. */\nstatic png_uint_32\nformatof(const char *arg)\n{\n   char *ep;\n   unsigned long format = strtoul(arg, &ep, 0);\n\n   if (ep > arg && *ep == 0 && format < FORMAT_COUNT)\n      return (png_uint_32)format;\n\n   else for (format=0; format < FORMAT_COUNT; ++format)\n   {\n      if (strcmp(format_names[format], arg) == 0)\n         return (png_uint_32)format;\n   }\n\n   fprintf(stderr, \"pngstest: format name '%s' invalid\\n\", arg);\n   return FORMAT_COUNT;\n}\n\n/* Bitset/test functions for formats */\n#define FORMAT_SET_COUNT (FORMAT_COUNT / 32)\ntypedef struct\n{\n   png_uint_32 bits[FORMAT_SET_COUNT];\n}\nformat_list;\n\nstatic void format_init(format_list *pf)\n{\n   int i;\n   for (i=0; i<FORMAT_SET_COUNT; ++i)\n      pf->bits[i] = 0; /* All off */\n}\n\n#if 0 /* currently unused */\nstatic void format_clear(format_list *pf)\n{\n   int i;\n   for (i=0; i<FORMAT_SET_COUNT; ++i)\n      pf->bits[i] = 0;\n}\n#endif\n\nstatic int format_is_initial(format_list *pf)\n{\n   int i;\n   for (i=0; i<FORMAT_SET_COUNT; ++i)\n      if (pf->bits[i] != 0)\n         return 0;\n\n   return 1;\n}\n\nstatic int format_set(format_list *pf, png_uint_32 format)\n{\n   if (format < FORMAT_COUNT)\n      return pf->bits[format >> 5] |= ((png_uint_32)1) << (format & 31);\n\n   return 0;\n}\n\n#if 0 /* currently unused */\nstatic int format_unset(format_list *pf, png_uint_32 format)\n{\n   if (format < FORMAT_COUNT)\n      return pf->bits[format >> 5] &= ~((png_uint_32)1) << (format & 31);\n\n   return 0;\n}\n#endif\n\nstatic int format_isset(format_list *pf, png_uint_32 format)\n{\n   return format < FORMAT_COUNT &&\n      (pf->bits[format >> 5] & (((png_uint_32)1) << (format & 31))) != 0;\n}\n\nstatic void format_default(format_list *pf, int redundant)\n{\n   if (redundant)\n   {\n      int i;\n\n      /* set everything, including flags that are pointless */\n      for (i=0; i<FORMAT_SET_COUNT; ++i)\n         pf->bits[i] = ~(png_uint_32)0;\n   }\n\n   else\n   {\n      png_uint_32 f;\n\n      for (f=0; f<FORMAT_COUNT; ++f)\n      {\n         /* Eliminate redundant and unsupported settings. */\n#        ifdef PNG_FORMAT_BGR_SUPPORTED\n            /* BGR is meaningless if no color: */\n            if ((f & PNG_FORMAT_FLAG_COLOR) == 0 &&\n               (f & PNG_FORMAT_FLAG_BGR) != 0)\n#        else\n            if ((f & 0x10U/*HACK: fixed value*/) != 0)\n#        endif\n            continue;\n\n         /* AFIRST is meaningless if no alpha: */\n#        ifdef PNG_FORMAT_AFIRST_SUPPORTED\n            if ((f & PNG_FORMAT_FLAG_ALPHA) == 0 &&\n               (f & PNG_FORMAT_FLAG_AFIRST) != 0)\n#        else\n            if ((f & 0x20U/*HACK: fixed value*/) != 0)\n#        endif\n            continue;\n\n         format_set(pf, f);\n      }\n   }\n}\n\n/* THE Image STRUCTURE */\n/* The super-class of a png_image, contains the decoded image plus the input\n * data necessary to re-read the file with a different format.\n */\ntypedef struct\n{\n   png_image   image;\n   png_uint_32 opts;\n   const char *file_name;\n   int         stride_extra;\n   FILE       *input_file;\n   png_voidp   input_memory;\n   png_size_t  input_memory_size;\n   png_bytep   buffer;\n   ptrdiff_t   stride;\n   png_size_t  bufsize;\n   png_size_t  allocsize;\n   char        tmpfile_name[32];\n   png_uint_16 colormap[256*4];\n}\nImage;\n\n/* Initializer: also sets the permitted error limit for 16-bit operations. */\nstatic void\nnewimage(Image *image)\n{\n   memset(image, 0, sizeof *image);\n}\n\n/* Reset the image to be read again - only needs to rewind the FILE* at present.\n */\nstatic void\nresetimage(Image *image)\n{\n   if (image->input_file != NULL)\n      rewind(image->input_file);\n}\n\n/* Free the image buffer; the buffer is re-used on a re-read, this is just for\n * cleanup.\n */\nstatic void\nfreebuffer(Image *image)\n{\n   if (image->buffer) free(image->buffer);\n   image->buffer = NULL;\n   image->bufsize = 0;\n   image->allocsize = 0;\n}\n\n/* Delete function; cleans out all the allocated data and the temporary file in\n * the image.\n */\nstatic void\nfreeimage(Image *image)\n{\n   freebuffer(image);\n   png_image_free(&image->image);\n\n   if (image->input_file != NULL)\n   {\n      fclose(image->input_file);\n      image->input_file = NULL;\n   }\n\n   if (image->input_memory != NULL)\n   {\n      free(image->input_memory);\n      image->input_memory = NULL;\n      image->input_memory_size = 0;\n   }\n\n   if (image->tmpfile_name[0] != 0 && (image->opts & KEEP_TMPFILES) == 0)\n   {\n      (void)remove(image->tmpfile_name);\n      image->tmpfile_name[0] = 0;\n   }\n}\n\n/* This is actually a re-initializer; allows an image structure to be re-used by\n * freeing everything that relates to an old image.\n */\nstatic void initimage(Image *image, png_uint_32 opts, const char *file_name,\n   int stride_extra)\n{\n   freeimage(image);\n   memset(&image->image, 0, sizeof image->image);\n   image->opts = opts;\n   image->file_name = file_name;\n   image->stride_extra = stride_extra;\n}\n\n/* Make sure the image buffer is big enough; allows re-use of the buffer if the\n * image is re-read.\n */\n#define BUFFER_INIT8 73\nstatic void\nallocbuffer(Image *image)\n{\n   png_size_t size = PNG_IMAGE_BUFFER_SIZE(image->image, image->stride);\n\n   if (size+32 > image->bufsize)\n   {\n      freebuffer(image);\n      image->buffer = voidcast(png_bytep, malloc(size+32));\n      if (image->buffer == NULL)\n      {\n         fflush(stdout);\n         fprintf(stderr,\n            \"simpletest: out of memory allocating %lu(+32) byte buffer\\n\",\n            (unsigned long)size);\n         exit(1);\n      }\n      image->bufsize = size+32;\n   }\n\n   memset(image->buffer, 95, image->bufsize);\n   memset(image->buffer+16, BUFFER_INIT8, size);\n   image->allocsize = size;\n}\n\n/* Make sure 16 bytes match the given byte. */\nstatic int\ncheck16(png_const_bytep bp, int b)\n{\n   int i = 16;\n\n   do\n      if (*bp != b) return 1;\n   while (--i);\n\n   return 0;\n}\n\n/* Check for overwrite in the image buffer. */\nstatic void\ncheckbuffer(Image *image, const char *arg)\n{\n   if (check16(image->buffer, 95))\n   {\n      fflush(stdout);\n      fprintf(stderr, \"%s: overwrite at start of image buffer\\n\", arg);\n      exit(1);\n   }\n\n   if (check16(image->buffer+16+image->allocsize, 95))\n   {\n      fflush(stdout);\n      fprintf(stderr, \"%s: overwrite at end of image buffer\\n\", arg);\n      exit(1);\n   }\n}\n\n/* ERROR HANDLING */\n/* Log a terminal error, also frees the libpng part of the image if necessary.\n */\nstatic int\nlogerror(Image *image, const char *a1, const char *a2, const char *a3)\n{\n   fflush(stdout);\n   if (image->image.warning_or_error)\n      fprintf(stderr, \"%s%s%s: %s\\n\", a1, a2, a3, image->image.message);\n\n   else\n      fprintf(stderr, \"%s%s%s\\n\", a1, a2, a3);\n\n   if (image->image.opaque != NULL)\n   {\n      fprintf(stderr, \"%s: image opaque pointer non-NULL on error\\n\",\n         image->file_name);\n      png_image_free(&image->image);\n   }\n\n   return 0;\n}\n\n/* Log an error and close a file (just a utility to do both things in one\n * function call.)\n */\nstatic int\nlogclose(Image *image, FILE *f, const char *name, const char *operation)\n{\n   int e = errno;\n\n   fclose(f);\n   return logerror(image, name, operation, strerror(e));\n}\n\n/* Make sure the png_image has been freed - validates that libpng is doing what\n * the spec says and freeing the image.\n */\nstatic int\ncheckopaque(Image *image)\n{\n   if (image->image.opaque != NULL)\n   {\n      png_image_free(&image->image);\n      return logerror(image, image->file_name, \": opaque not NULL\", \"\");\n   }\n\n   /* Separate out the gamma+background_rgb_to_gray warning because it may\n    * produce opaque component errors:\n    */\n   else if (image->image.warning_or_error != 0 &&\n            (strcmp(image->image.message,\n               \"libpng does not support gamma+background+rgb_to_gray\") == 0 ?\n                  (image->opts & GBG_ERROR) != 0 : (image->opts & STRICT) != 0))\n      return logerror(image, image->file_name, (image->opts & GBG_ERROR) != 0 ?\n                      \" --fault-gbg-warning\" : \" --strict\", \"\");\n\n   else\n      return 1;\n}\n\n/* IMAGE COMPARISON/CHECKING */\n/* Compare the pixels of two images, which should be the same but aren't.  The\n * images must have been checked for a size match.\n */\ntypedef struct\n{\n   /* The components, for grayscale images the gray value is in 'g' and if alpha\n    * is not present 'a' is set to 255 or 65535 according to format.\n    */\n   int         r, g, b, a;\n} Pixel;\n\ntypedef struct\n{\n   /* The background as the original sRGB 8-bit value converted to the final\n    * integer format and as a double precision linear value in the range 0..1\n    * for with partially transparent pixels.\n    */\n   int ir, ig, ib;\n   double dr, dg, db; /* linear r,g,b scaled to 0..1 */\n} Background;\n\n/* Basic image formats; control the data but not the layout thereof. */\n#define BASE_FORMATS\\\n   (PNG_FORMAT_FLAG_ALPHA|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_LINEAR)\n\n/* Read a Pixel from a buffer.  The code below stores the correct routine for\n * the format in a function pointer, these are the routines:\n */\nstatic void\ngp_g8(Pixel *p, png_const_voidp pb)\n{\n   png_const_bytep pp = voidcast(png_const_bytep, pb);\n\n   p->r = p->g = p->b = pp[0];\n   p->a = 255;\n}\n\nstatic void\ngp_ga8(Pixel *p, png_const_voidp pb)\n{\n   png_const_bytep pp = voidcast(png_const_bytep, pb);\n\n   p->r = p->g = p->b = pp[0];\n   p->a = pp[1];\n}\n\n#ifdef PNG_FORMAT_AFIRST_SUPPORTED\nstatic void\ngp_ag8(Pixel *p, png_const_voidp pb)\n{\n   png_const_bytep pp = voidcast(png_const_bytep, pb);\n\n   p->r = p->g = p->b = pp[1];\n   p->a = pp[0];\n}\n#endif\n\nstatic void\ngp_rgb8(Pixel *p, png_const_voidp pb)\n{\n   png_const_bytep pp = voidcast(png_const_bytep, pb);\n\n   p->r = pp[0];\n   p->g = pp[1];\n   p->b = pp[2];\n   p->a = 255;\n}\n\n#ifdef PNG_FORMAT_BGR_SUPPORTED\nstatic void\ngp_bgr8(Pixel *p, png_const_voidp pb)\n{\n   png_const_bytep pp = voidcast(png_const_bytep, pb);\n\n   p->r = pp[2];\n   p->g = pp[1];\n   p->b = pp[0];\n   p->a = 255;\n}\n#endif\n\nstatic void\ngp_rgba8(Pixel *p, png_const_voidp pb)\n{\n   png_const_bytep pp = voidcast(png_const_bytep, pb);\n\n   p->r = pp[0];\n   p->g = pp[1];\n   p->b = pp[2];\n   p->a = pp[3];\n}\n\n#ifdef PNG_FORMAT_BGR_SUPPORTED\nstatic void\ngp_bgra8(Pixel *p, png_const_voidp pb)\n{\n   png_const_bytep pp = voidcast(png_const_bytep, pb);\n\n   p->r = pp[2];\n   p->g = pp[1];\n   p->b = pp[0];\n   p->a = pp[3];\n}\n#endif\n\n#ifdef PNG_FORMAT_AFIRST_SUPPORTED\nstatic void\ngp_argb8(Pixel *p, png_const_voidp pb)\n{\n   png_const_bytep pp = voidcast(png_const_bytep, pb);\n\n   p->r = pp[1];\n   p->g = pp[2];\n   p->b = pp[3];\n   p->a = pp[0];\n}\n#endif\n\n#if defined(PNG_FORMAT_AFIRST_SUPPORTED) && defined(PNG_FORMAT_BGR_SUPPORTED)\nstatic void\ngp_abgr8(Pixel *p, png_const_voidp pb)\n{\n   png_const_bytep pp = voidcast(png_const_bytep, pb);\n\n   p->r = pp[3];\n   p->g = pp[2];\n   p->b = pp[1];\n   p->a = pp[0];\n}\n#endif\n\nstatic void\ngp_g16(Pixel *p, png_const_voidp pb)\n{\n   png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);\n\n   p->r = p->g = p->b = pp[0];\n   p->a = 65535;\n}\n\nstatic void\ngp_ga16(Pixel *p, png_const_voidp pb)\n{\n   png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);\n\n   p->r = p->g = p->b = pp[0];\n   p->a = pp[1];\n}\n\n#ifdef PNG_FORMAT_AFIRST_SUPPORTED\nstatic void\ngp_ag16(Pixel *p, png_const_voidp pb)\n{\n   png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);\n\n   p->r = p->g = p->b = pp[1];\n   p->a = pp[0];\n}\n#endif\n\nstatic void\ngp_rgb16(Pixel *p, png_const_voidp pb)\n{\n   png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);\n\n   p->r = pp[0];\n   p->g = pp[1];\n   p->b = pp[2];\n   p->a = 65535;\n}\n\n#ifdef PNG_FORMAT_BGR_SUPPORTED\nstatic void\ngp_bgr16(Pixel *p, png_const_voidp pb)\n{\n   png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);\n\n   p->r = pp[2];\n   p->g = pp[1];\n   p->b = pp[0];\n   p->a = 65535;\n}\n#endif\n\nstatic void\ngp_rgba16(Pixel *p, png_const_voidp pb)\n{\n   png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);\n\n   p->r = pp[0];\n   p->g = pp[1];\n   p->b = pp[2];\n   p->a = pp[3];\n}\n\n#ifdef PNG_FORMAT_BGR_SUPPORTED\nstatic void\ngp_bgra16(Pixel *p, png_const_voidp pb)\n{\n   png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);\n\n   p->r = pp[2];\n   p->g = pp[1];\n   p->b = pp[0];\n   p->a = pp[3];\n}\n#endif\n\n#ifdef PNG_FORMAT_AFIRST_SUPPORTED\nstatic void\ngp_argb16(Pixel *p, png_const_voidp pb)\n{\n   png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);\n\n   p->r = pp[1];\n   p->g = pp[2];\n   p->b = pp[3];\n   p->a = pp[0];\n}\n#endif\n\n#if defined(PNG_FORMAT_AFIRST_SUPPORTED) && defined(PNG_FORMAT_BGR_SUPPORTED)\nstatic void\ngp_abgr16(Pixel *p, png_const_voidp pb)\n{\n   png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);\n\n   p->r = pp[3];\n   p->g = pp[2];\n   p->b = pp[1];\n   p->a = pp[0];\n}\n#endif\n\n/* Given a format, return the correct one of the above functions. */\nstatic void (*\nget_pixel(png_uint_32 format))(Pixel *p, png_const_voidp pb)\n{\n   /* The color-map flag is irrelevant here - the caller of the function\n    * returned must either pass the buffer or, for a color-mapped image, the\n    * correct entry in the color-map.\n    */\n   if (format & PNG_FORMAT_FLAG_LINEAR)\n   {\n      if (format & PNG_FORMAT_FLAG_COLOR)\n      {\n#        ifdef PNG_FORMAT_BGR_SUPPORTED\n            if (format & PNG_FORMAT_FLAG_BGR)\n            {\n               if (format & PNG_FORMAT_FLAG_ALPHA)\n               {\n#                 ifdef PNG_FORMAT_AFIRST_SUPPORTED\n                     if (format & PNG_FORMAT_FLAG_AFIRST)\n                        return gp_abgr16;\n\n                     else\n#                 endif\n                     return gp_bgra16;\n               }\n\n               else\n                  return gp_bgr16;\n            }\n\n            else\n#        endif\n         {\n            if (format & PNG_FORMAT_FLAG_ALPHA)\n            {\n#              ifdef PNG_FORMAT_AFIRST_SUPPORTED\n                  if (format & PNG_FORMAT_FLAG_AFIRST)\n                     return gp_argb16;\n\n                  else\n#              endif\n                  return gp_rgba16;\n            }\n\n            else\n               return gp_rgb16;\n         }\n      }\n\n      else\n      {\n         if (format & PNG_FORMAT_FLAG_ALPHA)\n         {\n#           ifdef PNG_FORMAT_AFIRST_SUPPORTED\n               if (format & PNG_FORMAT_FLAG_AFIRST)\n                  return gp_ag16;\n\n               else\n#           endif\n               return gp_ga16;\n         }\n\n         else\n            return gp_g16;\n      }\n   }\n\n   else\n   {\n      if (format & PNG_FORMAT_FLAG_COLOR)\n      {\n#        ifdef PNG_FORMAT_BGR_SUPPORTED\n            if (format & PNG_FORMAT_FLAG_BGR)\n            {\n               if (format & PNG_FORMAT_FLAG_ALPHA)\n               {\n#                 ifdef PNG_FORMAT_AFIRST_SUPPORTED\n                     if (format & PNG_FORMAT_FLAG_AFIRST)\n                        return gp_abgr8;\n\n                     else\n#                 endif\n                     return gp_bgra8;\n               }\n\n               else\n                  return gp_bgr8;\n            }\n\n            else\n#        endif\n         {\n            if (format & PNG_FORMAT_FLAG_ALPHA)\n            {\n#              ifdef PNG_FORMAT_AFIRST_SUPPORTED\n                  if (format & PNG_FORMAT_FLAG_AFIRST)\n                     return gp_argb8;\n\n                  else\n#              endif\n                  return gp_rgba8;\n            }\n\n            else\n               return gp_rgb8;\n         }\n      }\n\n      else\n      {\n         if (format & PNG_FORMAT_FLAG_ALPHA)\n         {\n#           ifdef PNG_FORMAT_AFIRST_SUPPORTED\n               if (format & PNG_FORMAT_FLAG_AFIRST)\n                  return gp_ag8;\n\n               else\n#           endif\n               return gp_ga8;\n         }\n\n         else\n            return gp_g8;\n      }\n   }\n}\n\n/* Convertion between pixel formats.  The code above effectively eliminates the\n * component ordering changes leaving three basic changes:\n *\n * 1) Remove an alpha channel by pre-multiplication or compositing on a\n *    background color.  (Adding an alpha channel is a no-op.)\n *\n * 2) Remove color by mapping to grayscale.  (Grayscale to color is a no-op.)\n *\n * 3) Convert between 8-bit and 16-bit components.  (Both directtions are\n *    relevant.)\n *\n * This gives the following base format conversion matrix:\n *\n *   OUT:    ----- 8-bit -----    ----- 16-bit -----\n *   IN     G    GA   RGB  RGBA  G    GA   RGB  RGBA\n *  8 G     .    .    .    .     lin  lin  lin  lin\n *  8 GA    bckg .    bckc .     pre' pre  pre' pre\n *  8 RGB   g8   g8   .    .     glin glin lin  lin\n *  8 RGBA  g8b  g8   bckc .     gpr' gpre pre' pre\n * 16 G     sRGB sRGB sRGB sRGB  .    .    .    .\n * 16 GA    b16g unpg b16c unpc  A    .    A    .\n * 16 RGB   sG   sG   sRGB sRGB  g16  g16  .    .\n * 16 RGBA  gb16 sGp  cb16 sCp   g16  g16' A    .\n *\n *  8-bit to 8-bit:\n * bckg: composite on gray background\n * bckc: composite on color background\n * g8:   convert sRGB components to sRGB grayscale\n * g8b:  convert sRGB components to grayscale and composite on gray background\n *\n *  8-bit to 16-bit:\n * lin:  make sRGB components linear, alpha := 65535\n * pre:  make sRGB components linear and premultiply by alpha  (scale alpha)\n * pre': as 'pre' but alpha := 65535\n * glin: make sRGB components linear, convert to grayscale, alpha := 65535\n * gpre: make sRGB components grayscale and linear and premultiply by alpha\n * gpr': as 'gpre' but alpha := 65535\n *\n *  16-bit to 8-bit:\n * sRGB: convert linear components to sRGB, alpha := 255\n * unpg: unpremultiply gray component and convert to sRGB (scale alpha)\n * unpc: unpremultiply color components and convert to sRGB (scale alpha)\n * b16g: composite linear onto gray background and convert the result to sRGB\n * b16c: composite linear onto color background and convert the result to sRGB\n * sG:   convert linear RGB to sRGB grayscale\n * sGp:  unpremultiply RGB then convert to sRGB grayscale\n * sCp:  unpremultiply RGB then convert to sRGB\n * gb16: composite linear onto background and convert to sRGB grayscale\n *       (order doesn't matter, the composite and grayscale operations permute)\n * cb16: composite linear onto background and convert to sRGB\n *\n *  16-bit to 16-bit:\n * A:    set alpha to 65535\n * g16:  convert linear RGB to linear grayscale (alpha := 65535)\n * g16': as 'g16' but alpha is unchanged\n */\n/* Simple copy: */\nstatic void\ngpc_noop(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n   out->r = in->r;\n   out->g = in->g;\n   out->b = in->b;\n   out->a = in->a;\n}\n\n#if ALLOW_UNUSED_GPC\nstatic void\ngpc_nop8(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n   if (in->a == 0)\n      out->r = out->g = out->b = 255;\n\n   else\n   {\n      out->r = in->r;\n      out->g = in->g;\n      out->b = in->b;\n   }\n\n   out->a = in->a;\n}\n#endif\n\n#if ALLOW_UNUSED_GPC\nstatic void\ngpc_nop6(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n   if (in->a == 0)\n      out->r = out->g = out->b = 65535;\n\n   else\n   {\n      out->r = in->r;\n      out->g = in->g;\n      out->b = in->b;\n   }\n\n   out->a = in->a;\n}\n#endif\n\n/* 8-bit to 8-bit conversions */\n/* bckg: composite on gray background */\nstatic void\ngpc_bckg(Pixel *out, const Pixel *in, const Background *back)\n{\n   if (in->a <= 0)\n      out->r = out->g = out->b = back->ig;\n\n   else if (in->a >= 255)\n      out->r = out->g = out->b = in->g;\n\n   else\n   {\n      double a = in->a / 255.;\n\n      out->r = out->g = out->b = sRGB(sRGB_to_d[in->g] * a + back->dg * (1-a));\n   }\n\n   out->a = 255;\n}\n\n/* bckc: composite on color background */\nstatic void\ngpc_bckc(Pixel *out, const Pixel *in, const Background *back)\n{\n   if (in->a <= 0)\n   {\n      out->r = back->ir;\n      out->g = back->ig;\n      out->b = back->ib;\n   }\n\n   else if (in->a >= 255)\n   {\n      out->r = in->r;\n      out->g = in->g;\n      out->b = in->b;\n   }\n\n   else\n   {\n      double a = in->a / 255.;\n\n      out->r = sRGB(sRGB_to_d[in->r] * a + back->dr * (1-a));\n      out->g = sRGB(sRGB_to_d[in->g] * a + back->dg * (1-a));\n      out->b = sRGB(sRGB_to_d[in->b] * a + back->db * (1-a));\n   }\n\n   out->a = 255;\n}\n\n/* g8: convert sRGB components to sRGB grayscale */\nstatic void\ngpc_g8(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   if (in->r == in->g && in->g == in->b)\n      out->r = out->g = out->b = in->g;\n\n   else\n      out->r = out->g = out->b =\n         sRGB(YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));\n\n   out->a = in->a;\n}\n\n/* g8b: convert sRGB components to grayscale and composite on gray background */\nstatic void\ngpc_g8b(Pixel *out, const Pixel *in, const Background *back)\n{\n   if (in->a <= 0)\n      out->r = out->g = out->b = back->ig;\n\n   else if (in->a >= 255)\n   {\n      if (in->r == in->g && in->g == in->b)\n         out->r = out->g = out->b = in->g;\n\n      else\n         out->r = out->g = out->b = sRGB(YfromRGB(\n            sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));\n   }\n\n   else\n   {\n      double a = in->a/255.;\n\n      out->r = out->g = out->b = sRGB(a * YfromRGB(sRGB_to_d[in->r],\n         sRGB_to_d[in->g], sRGB_to_d[in->b]) + back->dg * (1-a));\n   }\n\n   out->a = 255;\n}\n\n/* 8-bit to 16-bit conversions */\n/* lin: make sRGB components linear, alpha := 65535 */\nstatic void\ngpc_lin(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   out->r = ilinear(in->r);\n\n   if (in->g == in->r)\n   {\n      out->g = out->r;\n\n      if (in->b == in->r)\n         out->b = out->r;\n\n      else\n         out->b = ilinear(in->b);\n   }\n\n   else\n   {\n      out->g = ilinear(in->g);\n\n      if (in->b == in->r)\n         out->b = out->r;\n\n      else if (in->b == in->g)\n         out->b = out->g;\n\n      else\n         out->b = ilinear(in->b);\n   }\n\n   out->a = 65535;\n}\n\n/* pre: make sRGB components linear and premultiply by alpha (scale alpha) */\nstatic void\ngpc_pre(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   out->r = ilineara(in->r, in->a);\n\n   if (in->g == in->r)\n   {\n      out->g = out->r;\n\n      if (in->b == in->r)\n         out->b = out->r;\n\n      else\n         out->b = ilineara(in->b, in->a);\n   }\n\n   else\n   {\n      out->g = ilineara(in->g, in->a);\n\n      if (in->b == in->r)\n         out->b = out->r;\n\n      else if (in->b == in->g)\n         out->b = out->g;\n\n      else\n         out->b = ilineara(in->b, in->a);\n   }\n\n   out->a = in->a * 257;\n}\n\n/* pre': as 'pre' but alpha := 65535 */\nstatic void\ngpc_preq(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   out->r = ilineara(in->r, in->a);\n\n   if (in->g == in->r)\n   {\n      out->g = out->r;\n\n      if (in->b == in->r)\n         out->b = out->r;\n\n      else\n         out->b = ilineara(in->b, in->a);\n   }\n\n   else\n   {\n      out->g = ilineara(in->g, in->a);\n\n      if (in->b == in->r)\n         out->b = out->r;\n\n      else if (in->b == in->g)\n         out->b = out->g;\n\n      else\n         out->b = ilineara(in->b, in->a);\n   }\n\n   out->a = 65535;\n}\n\n/* glin: make sRGB components linear, convert to grayscale, alpha := 65535 */\nstatic void\ngpc_glin(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   if (in->r == in->g && in->g == in->b)\n      out->r = out->g = out->b = ilinear(in->g);\n\n   else\n      out->r = out->g = out->b = u16d(65535 *\n         YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));\n\n   out->a = 65535;\n}\n\n/* gpre: make sRGB components grayscale and linear and premultiply by alpha */\nstatic void\ngpc_gpre(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   if (in->r == in->g && in->g == in->b)\n      out->r = out->g = out->b = ilineara(in->g, in->a);\n\n   else\n      out->r = out->g = out->b = u16d(in->a * 257 *\n         YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));\n\n   out->a = 257 * in->a;\n}\n\n/* gpr': as 'gpre' but alpha := 65535 */\nstatic void\ngpc_gprq(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   if (in->r == in->g && in->g == in->b)\n      out->r = out->g = out->b = ilineara(in->g, in->a);\n\n   else\n      out->r = out->g = out->b = u16d(in->a * 257 *\n         YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));\n\n   out->a = 65535;\n}\n\n/* 8-bit to 16-bit conversions for gAMA 45455 encoded values */\n/* Lin: make gAMA 45455 components linear, alpha := 65535 */\nstatic void\ngpc_Lin(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   out->r = ilinear_g22(in->r);\n\n   if (in->g == in->r)\n   {\n      out->g = out->r;\n\n      if (in->b == in->r)\n         out->b = out->r;\n\n      else\n         out->b = ilinear_g22(in->b);\n   }\n\n   else\n   {\n      out->g = ilinear_g22(in->g);\n\n      if (in->b == in->r)\n         out->b = out->r;\n\n      else if (in->b == in->g)\n         out->b = out->g;\n\n      else\n         out->b = ilinear_g22(in->b);\n   }\n\n   out->a = 65535;\n}\n\n#if ALLOW_UNUSED_GPC\n/* Pre: make gAMA 45455 components linear and premultiply by alpha (scale alpha)\n */\nstatic void\ngpc_Pre(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   out->r = ilineara_g22(in->r, in->a);\n\n   if (in->g == in->r)\n   {\n      out->g = out->r;\n\n      if (in->b == in->r)\n         out->b = out->r;\n\n      else\n         out->b = ilineara_g22(in->b, in->a);\n   }\n\n   else\n   {\n      out->g = ilineara_g22(in->g, in->a);\n\n      if (in->b == in->r)\n         out->b = out->r;\n\n      else if (in->b == in->g)\n         out->b = out->g;\n\n      else\n         out->b = ilineara_g22(in->b, in->a);\n   }\n\n   out->a = in->a * 257;\n}\n#endif\n\n#if ALLOW_UNUSED_GPC\n/* Pre': as 'Pre' but alpha := 65535 */\nstatic void\ngpc_Preq(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   out->r = ilineara_g22(in->r, in->a);\n\n   if (in->g == in->r)\n   {\n      out->g = out->r;\n\n      if (in->b == in->r)\n         out->b = out->r;\n\n      else\n         out->b = ilineara_g22(in->b, in->a);\n   }\n\n   else\n   {\n      out->g = ilineara_g22(in->g, in->a);\n\n      if (in->b == in->r)\n         out->b = out->r;\n\n      else if (in->b == in->g)\n         out->b = out->g;\n\n      else\n         out->b = ilineara_g22(in->b, in->a);\n   }\n\n   out->a = 65535;\n}\n#endif\n\n#if ALLOW_UNUSED_GPC\n/* Glin: make gAMA 45455 components linear, convert to grayscale, alpha := 65535\n */\nstatic void\ngpc_Glin(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   if (in->r == in->g && in->g == in->b)\n      out->r = out->g = out->b = ilinear_g22(in->g);\n\n   else\n      out->r = out->g = out->b = u16d(65535 *\n         YfromRGB(g22_to_d[in->r], g22_to_d[in->g], g22_to_d[in->b]));\n\n   out->a = 65535;\n}\n#endif\n\n#if ALLOW_UNUSED_GPC\n/* Gpre: make gAMA 45455 components grayscale and linear and premultiply by\n * alpha.\n */\nstatic void\ngpc_Gpre(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   if (in->r == in->g && in->g == in->b)\n      out->r = out->g = out->b = ilineara_g22(in->g, in->a);\n\n   else\n      out->r = out->g = out->b = u16d(in->a * 257 *\n         YfromRGB(g22_to_d[in->r], g22_to_d[in->g], g22_to_d[in->b]));\n\n   out->a = 257 * in->a;\n}\n#endif\n\n#if ALLOW_UNUSED_GPC\n/* Gpr': as 'Gpre' but alpha := 65535 */\nstatic void\ngpc_Gprq(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   if (in->r == in->g && in->g == in->b)\n      out->r = out->g = out->b = ilineara_g22(in->g, in->a);\n\n   else\n      out->r = out->g = out->b = u16d(in->a * 257 *\n         YfromRGB(g22_to_d[in->r], g22_to_d[in->g], g22_to_d[in->b]));\n\n   out->a = 65535;\n}\n#endif\n\n/* 16-bit to 8-bit conversions */\n/* sRGB: convert linear components to sRGB, alpha := 255 */\nstatic void\ngpc_sRGB(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   out->r = isRGB(in->r);\n\n   if (in->g == in->r)\n   {\n      out->g = out->r;\n\n      if (in->b == in->r)\n         out->b = out->r;\n\n      else\n         out->b = isRGB(in->b);\n   }\n\n   else\n   {\n      out->g = isRGB(in->g);\n\n      if (in->b == in->r)\n         out->b = out->r;\n\n      else if (in->b == in->g)\n         out->b = out->g;\n\n      else\n         out->b = isRGB(in->b);\n   }\n\n   out->a = 255;\n}\n\n/* unpg: unpremultiply gray component and convert to sRGB (scale alpha) */\nstatic void\ngpc_unpg(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   if (in->a <= 128)\n   {\n      out->r = out->g = out->b = 255;\n      out->a = 0;\n   }\n\n   else\n   {\n      out->r = out->g = out->b = sRGB((double)in->g / in->a);\n      out->a = u8d(in->a / 257.);\n   }\n}\n\n/* unpc: unpremultiply color components and convert to sRGB (scale alpha) */\nstatic void\ngpc_unpc(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   if (in->a <= 128)\n   {\n      out->r = out->g = out->b = 255;\n      out->a = 0;\n   }\n\n   else\n   {\n      out->r = sRGB((double)in->r / in->a);\n      out->g = sRGB((double)in->g / in->a);\n      out->b = sRGB((double)in->b / in->a);\n      out->a = u8d(in->a / 257.);\n   }\n}\n\n/* b16g: composite linear onto gray background and convert the result to sRGB */\nstatic void\ngpc_b16g(Pixel *out, const Pixel *in, const Background *back)\n{\n   if (in->a <= 0)\n      out->r = out->g = out->b = back->ig;\n\n   else\n   {\n      double a = in->a/65535.;\n      double a1 = 1-a;\n\n      a /= 65535;\n      out->r = out->g = out->b = sRGB(in->g * a + back->dg * a1);\n   }\n\n   out->a = 255;\n}\n\n/* b16c: composite linear onto color background and convert the result to sRGB*/\nstatic void\ngpc_b16c(Pixel *out, const Pixel *in, const Background *back)\n{\n   if (in->a <= 0)\n   {\n      out->r = back->ir;\n      out->g = back->ig;\n      out->b = back->ib;\n   }\n\n   else\n   {\n      double a = in->a/65535.;\n      double a1 = 1-a;\n\n      a /= 65535;\n      out->r = sRGB(in->r * a + back->dr * a1);\n      out->g = sRGB(in->g * a + back->dg * a1);\n      out->b = sRGB(in->b * a + back->db * a1);\n   }\n\n   out->a = 255;\n}\n\n/* sG: convert linear RGB to sRGB grayscale */\nstatic void\ngpc_sG(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   out->r = out->g = out->b = sRGB(YfromRGBint(in->r, in->g, in->b)/65535);\n   out->a = 255;\n}\n\n/* sGp: unpremultiply RGB then convert to sRGB grayscale */\nstatic void\ngpc_sGp(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   if (in->a <= 128)\n   {\n      out->r = out->g = out->b = 255;\n      out->a = 0;\n   }\n\n   else\n   {\n      out->r = out->g = out->b = sRGB(YfromRGBint(in->r, in->g, in->b)/in->a);\n      out->a = u8d(in->a / 257.);\n   }\n}\n\n/* sCp: unpremultiply RGB then convert to sRGB */\nstatic void\ngpc_sCp(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n\n   if (in->a <= 128)\n   {\n      out->r = out->g = out->b = 255;\n      out->a = 0;\n   }\n\n   else\n   {\n      out->r = sRGB((double)in->r / in->a);\n      out->g = sRGB((double)in->g / in->a);\n      out->b = sRGB((double)in->b / in->a);\n      out->a = u8d(in->a / 257.);\n   }\n}\n\n/* gb16: composite linear onto background and convert to sRGB grayscale */\n/*  (order doesn't matter, the composite and grayscale operations permute) */\nstatic void\ngpc_gb16(Pixel *out, const Pixel *in, const Background *back)\n{\n   if (in->a <= 0)\n      out->r = out->g = out->b = back->ig;\n\n   else if (in->a >= 65535)\n      out->r = out->g = out->b = isRGB(in->g);\n\n   else\n   {\n      double a = in->a / 65535.;\n      double a1 = 1-a;\n\n      a /= 65535;\n      out->r = out->g = out->b = sRGB(in->g * a + back->dg * a1);\n   }\n\n   out->a = 255;\n}\n\n/* cb16: composite linear onto background and convert to sRGB */\nstatic void\ngpc_cb16(Pixel *out, const Pixel *in, const Background *back)\n{\n   if (in->a <= 0)\n   {\n      out->r = back->ir;\n      out->g = back->ig;\n      out->b = back->ib;\n   }\n\n   else if (in->a >= 65535)\n   {\n      out->r = isRGB(in->r);\n      out->g = isRGB(in->g);\n      out->b = isRGB(in->b);\n   }\n\n   else\n   {\n      double a = in->a / 65535.;\n      double a1 = 1-a;\n\n      a /= 65535;\n      out->r = sRGB(in->r * a + back->dr * a1);\n      out->g = sRGB(in->g * a + back->dg * a1);\n      out->b = sRGB(in->b * a + back->db * a1);\n   }\n\n   out->a = 255;\n}\n\n/* 16-bit to 16-bit conversions */\n/* A:    set alpha to 65535 */\nstatic void\ngpc_A(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n   out->r = in->r;\n   out->g = in->g;\n   out->b = in->b;\n   out->a = 65535;\n}\n\n/* g16:  convert linear RGB to linear grayscale (alpha := 65535) */\nstatic void\ngpc_g16(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n   out->r = out->g = out->b = u16d(YfromRGBint(in->r, in->g, in->b));\n   out->a = 65535;\n}\n\n/* g16': as 'g16' but alpha is unchanged */\nstatic void\ngpc_g16q(Pixel *out, const Pixel *in, const Background *back)\n{\n   (void)back;\n   out->r = out->g = out->b = u16d(YfromRGBint(in->r, in->g, in->b));\n   out->a = in->a;\n}\n\n#if ALLOW_UNUSED_GPC\n/* Unused functions (to hide them from GCC unused function warnings) */\nvoid (* const gpc_unused[])\n   (Pixel *out, const Pixel *in, const Background *back) =\n{\n   gpc_Pre, gpc_Preq, gpc_Glin, gpc_Gpre, gpc_Gprq, gpc_nop8, gpc_nop6\n};\n#endif\n\n/*   OUT:    ----- 8-bit -----    ----- 16-bit -----\n *   IN     G    GA   RGB  RGBA  G    GA   RGB  RGBA\n *  8 G     .    .    .    .     lin  lin  lin  lin\n *  8 GA    bckg .    bckc .     pre' pre  pre' pre\n *  8 RGB   g8   g8   .    .     glin glin lin  lin\n *  8 RGBA  g8b  g8   bckc .     gpr' gpre pre' pre\n * 16 G     sRGB sRGB sRGB sRGB  .    .    .    .\n * 16 GA    b16g unpg b16c unpc  A    .    A    .\n * 16 RGB   sG   sG   sRGB sRGB  g16  g16  .    .\n * 16 RGBA  gb16 sGp  cb16 sCp   g16  g16' A    .\n *\n * The matrix is held in an array indexed thus:\n *\n *   gpc_fn[out_format & BASE_FORMATS][in_format & BASE_FORMATS];\n */\n/* This will produce a compile time error if the FORMAT_FLAG values don't\n * match the above matrix!\n */\n#if PNG_FORMAT_FLAG_ALPHA == 1 && PNG_FORMAT_FLAG_COLOR == 2 &&\\\n   PNG_FORMAT_FLAG_LINEAR == 4\nstatic void (* const gpc_fn[8/*in*/][8/*out*/])\n   (Pixel *out, const Pixel *in, const Background *back) =\n{\n/*out: G-8     GA-8     RGB-8    RGBA-8    G-16     GA-16   RGB-16  RGBA-16 */\n   {gpc_noop,gpc_noop,gpc_noop,gpc_noop, gpc_Lin, gpc_Lin, gpc_Lin, gpc_Lin },\n   {gpc_bckg,gpc_noop,gpc_bckc,gpc_noop, gpc_preq,gpc_pre, gpc_preq,gpc_pre },\n   {gpc_g8,  gpc_g8,  gpc_noop,gpc_noop, gpc_glin,gpc_glin,gpc_lin, gpc_lin },\n   {gpc_g8b, gpc_g8,  gpc_bckc,gpc_noop, gpc_gprq,gpc_gpre,gpc_preq,gpc_pre },\n   {gpc_sRGB,gpc_sRGB,gpc_sRGB,gpc_sRGB, gpc_noop,gpc_noop,gpc_noop,gpc_noop},\n   {gpc_b16g,gpc_unpg,gpc_b16c,gpc_unpc, gpc_A,   gpc_noop,gpc_A,   gpc_noop},\n   {gpc_sG,  gpc_sG,  gpc_sRGB,gpc_sRGB, gpc_g16, gpc_g16, gpc_noop,gpc_noop},\n   {gpc_gb16,gpc_sGp, gpc_cb16,gpc_sCp,  gpc_g16, gpc_g16q,gpc_A,   gpc_noop}\n};\n\n/* The array is repeated for the cases where both the input and output are color\n * mapped because then different algorithms are used.\n */\nstatic void (* const gpc_fn_colormapped[8/*in*/][8/*out*/])\n   (Pixel *out, const Pixel *in, const Background *back) =\n{\n/*out: G-8     GA-8     RGB-8    RGBA-8    G-16     GA-16   RGB-16  RGBA-16 */\n   {gpc_noop,gpc_noop,gpc_noop,gpc_noop, gpc_lin, gpc_lin, gpc_lin, gpc_lin },\n   {gpc_bckg,gpc_noop,gpc_bckc,gpc_noop, gpc_preq,gpc_pre, gpc_preq,gpc_pre },\n   {gpc_g8,  gpc_g8,  gpc_noop,gpc_noop, gpc_glin,gpc_glin,gpc_lin, gpc_lin },\n   {gpc_g8b, gpc_g8,  gpc_bckc,gpc_noop, gpc_gprq,gpc_gpre,gpc_preq,gpc_pre },\n   {gpc_sRGB,gpc_sRGB,gpc_sRGB,gpc_sRGB, gpc_noop,gpc_noop,gpc_noop,gpc_noop},\n   {gpc_b16g,gpc_unpg,gpc_b16c,gpc_unpc, gpc_A,   gpc_noop,gpc_A,   gpc_noop},\n   {gpc_sG,  gpc_sG,  gpc_sRGB,gpc_sRGB, gpc_g16, gpc_g16, gpc_noop,gpc_noop},\n   {gpc_gb16,gpc_sGp, gpc_cb16,gpc_sCp,  gpc_g16, gpc_g16q,gpc_A,   gpc_noop}\n};\n\n/* The error arrays record the error in the same matrix; 64 entries, however\n * the different algorithms used in libpng for colormap and direct conversions\n * mean that four separate matrices are used (for each combination of\n * colormapped and direct.)\n *\n * In some cases the conversion between sRGB formats goes via a linear\n * intermediate; an sRGB to linear conversion (as above) is followed by a simple\n * linear to sRGB step with no other conversions.  This is done by a separate\n * error array from an arbitrary 'in' format to one of the four basic outputs\n * (since final output is always sRGB not colormapped).\n *\n * These arrays may be modified if the --accumulate flag is set during the run;\n * then instead of logging errors they are simply added in.\n *\n * The three entries are currently for transparent, partially transparent and\n * opaque input pixel values.  Notice that alpha should be exact in each case.\n *\n * Errors in alpha should only occur when converting from a direct format\n * to a colormapped format, when alpha is effectively smashed (so large\n * errors can occur.)  There should be no error in the '0' and 'opaque'\n * values.  The fourth entry in the array is used for the alpha error (and it\n * should always be zero for the 'via linear' case since this is never color\n * mapped.)\n *\n * Mapping to a colormap smashes the colors, it is necessary to have separate\n * values for these cases because they are much larger; it is very much\n * impossible to obtain a reasonable result, these are held in\n * gpc_error_to_colormap.\n */\n#if PNG_FORMAT_FLAG_COLORMAP == 8 /* extra check also required */\n#  include \"pngstest-errors.h\" /* machine generated */\n#endif /* COLORMAP flag check */\n#endif /* flag checks */\n\ntypedef struct\n{\n   /* Basic pixel information: */\n   Image*       in_image;   /* Input image */\n   const Image* out_image;  /* Output image */\n\n   /* 'background' is the value passed to the gpc_ routines, it may be NULL if\n    * it should not be used (*this* program has an error if it crashes as a\n    * result!)\n    */\n   Background        background_color;\n   const Background* background;\n\n   /* Precalculated values: */\n   int          in_opaque;   /* Value of input alpha that is opaque */\n   int          is_palette;  /* Sample values come from the palette */\n   int          accumulate;  /* Accumlate component errors (don't log) */\n   int          output_8bit; /* Output is 8-bit (else 16-bit) */\n\n   void (*in_gp)(Pixel*, png_const_voidp);\n   void (*out_gp)(Pixel*, png_const_voidp);\n\n   void (*transform)(Pixel *out, const Pixel *in, const Background *back);\n      /* A function to perform the required transform */\n\n   void (*from_linear)(Pixel *out, const Pixel *in, const Background *back);\n      /* For 'via_linear' transforms the final, from linear, step, else NULL */\n\n   png_uint_16 error[4];\n      /* Three error values for transparent, partially transparent and opaque\n       * input pixels (in turn).\n       */\n\n   png_uint_16 *error_ptr;\n      /* Where these are stored in the static array (for 'accumulate') */\n}\nTransform;\n\n/* Return a 'transform' as above for the given format conversion. */\nstatic void\ntransform_from_formats(Transform *result, Image *in_image,\n   const Image *out_image, png_const_colorp background, int via_linear)\n{\n   png_uint_32 in_format, out_format;\n   png_uint_32 in_base, out_base;\n\n   memset(result, 0, sizeof *result);\n\n   /* Store the original images for error messages */\n   result->in_image = in_image;\n   result->out_image = out_image;\n\n   in_format = in_image->image.format;\n   out_format = out_image->image.format;\n\n   if (in_format & PNG_FORMAT_FLAG_LINEAR)\n      result->in_opaque = 65535;\n   else\n      result->in_opaque = 255;\n\n   result->output_8bit = (out_format & PNG_FORMAT_FLAG_LINEAR) == 0;\n\n   result->is_palette = 0; /* set by caller if required */\n   result->accumulate = (in_image->opts & ACCUMULATE) != 0;\n\n   /* The loaders (which need the ordering information) */\n   result->in_gp = get_pixel(in_format);\n   result->out_gp = get_pixel(out_format);\n\n   /* Remove the ordering information: */\n   in_format &= BASE_FORMATS | PNG_FORMAT_FLAG_COLORMAP;\n   in_base = in_format & BASE_FORMATS;\n   out_format &= BASE_FORMATS | PNG_FORMAT_FLAG_COLORMAP;\n   out_base = out_format & BASE_FORMATS;\n\n   if (via_linear)\n   {\n      /* Check for an error in this program: */\n      if (out_format & (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLORMAP))\n      {\n         fprintf(stderr, \"internal transform via linear error 0x%x->0x%x\\n\",\n            in_format, out_format);\n         exit(1);\n      }\n\n      result->transform = gpc_fn[in_base][out_base | PNG_FORMAT_FLAG_LINEAR];\n      result->from_linear = gpc_fn[out_base | PNG_FORMAT_FLAG_LINEAR][out_base];\n      result->error_ptr = gpc_error_via_linear[in_format][out_format];\n   }\n\n   else if (~in_format & out_format & PNG_FORMAT_FLAG_COLORMAP)\n   {\n      /* The input is not colormapped but the output is, the errors will\n       * typically be large (only the grayscale-no-alpha case permits preserving\n       * even 8-bit values.)\n       */\n      result->transform = gpc_fn[in_base][out_base];\n      result->from_linear = NULL;\n      result->error_ptr = gpc_error_to_colormap[in_base][out_base];\n   }\n\n   else\n   {\n      /* The caller handles the colormap->pixel value conversion, so the\n       * transform function just gets a pixel value, however because libpng\n       * currently contains a different implementation for mapping a colormap if\n       * both input and output are colormapped we need different conversion\n       * functions to deal with errors in the libpng implementation.\n       */\n      if (in_format & out_format & PNG_FORMAT_FLAG_COLORMAP)\n         result->transform = gpc_fn_colormapped[in_base][out_base];\n      else\n         result->transform = gpc_fn[in_base][out_base];\n      result->from_linear = NULL;\n      result->error_ptr = gpc_error[in_format][out_format];\n   }\n\n   /* Follow the libpng simplified API rules to work out what to pass to the gpc\n    * routines as a background value, if one is not required pass NULL so that\n    * this program crashes in the even of a programming error.\n    */\n   result->background = NULL; /* default: not required */\n\n   /* Rule 1: background only need be supplied if alpha is to be removed */\n   if (in_format & ~out_format & PNG_FORMAT_FLAG_ALPHA)\n   {\n      /* The input value is 'NULL' to use the background and (otherwise) an sRGB\n       * background color (to use a solid color).  The code above uses a fixed\n       * byte value, BUFFER_INIT8, for buffer even for 16-bit output.  For\n       * linear (16-bit) output the sRGB background color is ignored; the\n       * composition is always on the background (so BUFFER_INIT8 * 257), except\n       * that for the colormap (i.e. linear colormapped output) black is used.\n       */\n      result->background = &result->background_color;\n\n      if (out_format & PNG_FORMAT_FLAG_LINEAR || via_linear)\n      {\n         if (out_format & PNG_FORMAT_FLAG_COLORMAP)\n         {\n            result->background_color.ir =\n               result->background_color.ig =\n               result->background_color.ib = 0;\n            result->background_color.dr =\n               result->background_color.dg =\n               result->background_color.db = 0;\n         }\n\n         else\n         {\n            result->background_color.ir =\n               result->background_color.ig =\n               result->background_color.ib = BUFFER_INIT8 * 257;\n            result->background_color.dr =\n               result->background_color.dg =\n               result->background_color.db = 0;\n         }\n      }\n\n      else /* sRGB output */\n      {\n         if (background != NULL)\n         {\n            if (out_format & PNG_FORMAT_FLAG_COLOR)\n            {\n               result->background_color.ir = background->red;\n               result->background_color.ig = background->green;\n               result->background_color.ib = background->blue;\n               /* TODO: sometimes libpng uses the power law conversion here, how\n                * to handle this?\n                */\n               result->background_color.dr = sRGB_to_d[background->red];\n               result->background_color.dg = sRGB_to_d[background->green];\n               result->background_color.db = sRGB_to_d[background->blue];\n            }\n\n            else /* grayscale: libpng only looks at 'g' */\n            {\n               result->background_color.ir =\n                  result->background_color.ig =\n                  result->background_color.ib = background->green;\n               /* TODO: sometimes libpng uses the power law conversion here, how\n                * to handle this?\n                */\n               result->background_color.dr =\n                  result->background_color.dg =\n                  result->background_color.db = sRGB_to_d[background->green];\n            }\n         }\n\n         else if ((out_format & PNG_FORMAT_FLAG_COLORMAP) == 0)\n         {\n            result->background_color.ir =\n               result->background_color.ig =\n               result->background_color.ib = BUFFER_INIT8;\n            /* TODO: sometimes libpng uses the power law conversion here, how\n             * to handle this?\n             */\n            result->background_color.dr =\n               result->background_color.dg =\n               result->background_color.db = sRGB_to_d[BUFFER_INIT8];\n         }\n\n         /* Else the output is colormapped and a background color must be\n          * provided; if pngstest crashes then that is a bug in this program\n          * (though libpng should png_error as well.)\n          */\n         else\n            result->background = NULL;\n      }\n   }\n\n   if (result->background == NULL)\n   {\n      result->background_color.ir =\n         result->background_color.ig =\n         result->background_color.ib = -1; /* not used */\n      result->background_color.dr =\n         result->background_color.dg =\n         result->background_color.db = 1E30; /* not used */\n   }\n\n\n   /* Copy the error values into the Transform: */\n   result->error[0] = result->error_ptr[0];\n   result->error[1] = result->error_ptr[1];\n   result->error[2] = result->error_ptr[2];\n   result->error[3] = result->error_ptr[3];\n}\n\n\n/* Compare two pixels.\n *\n * OLD error values:\nstatic int error_to_linear = 811; * by experiment *\nstatic int error_to_linear_grayscale = 424; * by experiment *\nstatic int error_to_sRGB = 6; * by experiment *\nstatic int error_to_sRGB_grayscale = 17; * libpng error by calculation +\n                                            2 by experiment *\nstatic int error_in_compose = 2; * by experiment *\nstatic int error_in_premultiply = 1;\n *\n * The following is *just* the result of a round trip from 8-bit sRGB to linear\n * then back to 8-bit sRGB when it is done by libpng.  There are two problems:\n *\n * 1) libpng currently uses a 2.2 power law with no linear segment, this results\n * in instability in the low values and even with 16-bit precision sRGB(1) ends\n * up mapping to sRGB(0) as a result of rounding in the 16-bit representation.\n * This gives an error of 1 in the handling of value 1 only.\n *\n * 2) libpng currently uses an intermediate 8-bit linear value in gamma\n * correction of 8-bit values.  This results in many more errors, the worse of\n * which is mapping sRGB(14) to sRGB(0).\n *\n * The general 'error_via_linear' is more complex because of pre-multiplication,\n * this compounds the 8-bit errors according to the alpha value of the pixel.\n * As a result 256 values are pre-calculated for error_via_linear.\n */\n#if 0\nstatic int error_in_libpng_gamma;\nstatic int error_via_linear[256]; /* Indexed by 8-bit alpha */\n\nstatic void\ninit_error_via_linear(void)\n{\n   int alpha;\n\n   error_via_linear[0] = 255; /* transparent pixel */\n\n   for (alpha=1; alpha<=255; ++alpha)\n   {\n      /* 16-bit values less than 128.5 get rounded to 8-bit 0 and so the worst\n       * case error arises with 16-bit 128.5, work out what sRGB\n       * (non-associated) value generates 128.5; any value less than this is\n       * going to map to 0, so the worst error is floor(value).\n       *\n       * Note that errors are considerably higher (more than a factor of 2)\n       * because libpng uses a simple power law for sRGB data at present.\n       *\n       * Add .1 for arithmetic errors inside libpng.\n       */\n      double v = floor(255*pow(.5/*(128.5 * 255 / 65535)*/ / alpha, 1/2.2)+.1);\n\n      error_via_linear[alpha] = (int)v;\n   }\n\n   /* This is actually 14.99, but, despite the closeness to 15, 14 seems to work\n    * ok in this case.\n    */\n   error_in_libpng_gamma = 14;\n}\n#endif\n\nstatic void\nprint_pixel(char string[64], const Pixel *pixel, png_uint_32 format)\n{\n   switch (format & (PNG_FORMAT_FLAG_ALPHA|PNG_FORMAT_FLAG_COLOR))\n   {\n      case 0:\n         sprintf(string, \"%s(%d)\", format_names[format], pixel->g);\n         break;\n\n      case PNG_FORMAT_FLAG_ALPHA:\n         sprintf(string, \"%s(%d,%d)\", format_names[format], pixel->g,\n            pixel->a);\n         break;\n\n      case PNG_FORMAT_FLAG_COLOR:\n         sprintf(string, \"%s(%d,%d,%d)\", format_names[format],\n            pixel->r, pixel->g, pixel->b);\n         break;\n\n      case PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA:\n         sprintf(string, \"%s(%d,%d,%d,%d)\", format_names[format],\n            pixel->r, pixel->g, pixel->b, pixel->a);\n         break;\n\n      default:\n         sprintf(string, \"invalid-format\");\n         break;\n   }\n}\n\nstatic int\nlogpixel(const Transform *transform, png_uint_32 x, png_uint_32 y,\n   const Pixel *in, const Pixel *calc, const Pixel *out, const char *reason)\n{\n   const png_uint_32 in_format = transform->in_image->image.format;\n   const png_uint_32 out_format = transform->out_image->image.format;\n\n   png_uint_32 back_format = out_format & ~PNG_FORMAT_FLAG_ALPHA;\n   const char *via_linear = \"\";\n\n   char pixel_in[64], pixel_calc[64], pixel_out[64], pixel_loc[64];\n   char background_info[100];\n\n   print_pixel(pixel_in, in, in_format);\n   print_pixel(pixel_calc, calc, out_format);\n   print_pixel(pixel_out, out, out_format);\n\n   if (transform->is_palette)\n      sprintf(pixel_loc, \"palette: %lu\", (unsigned long)y);\n   else\n      sprintf(pixel_loc, \"%lu,%lu\", (unsigned long)x, (unsigned long)y);\n\n   if (transform->from_linear != NULL)\n   {\n      via_linear = \" (via linear)\";\n      /* And as a result the *read* format which did any background processing\n       * was itself linear, so the background color information is also\n       * linear.\n       */\n      back_format |= PNG_FORMAT_FLAG_LINEAR;\n   }\n\n   if (transform->background != NULL)\n   {\n      Pixel back;\n      char pixel_back[64];\n\n      back.r = transform->background->ir;\n      back.g = transform->background->ig;\n      back.b = transform->background->ib;\n      back.a = -1; /* not used */\n\n      print_pixel(pixel_back, &back, back_format);\n      sprintf(background_info, \" on background %s\", pixel_back);\n   }\n\n   else\n      background_info[0] = 0;\n\n   if (transform->in_image->file_name != transform->out_image->file_name)\n   {\n      char error_buffer[512];\n      sprintf(error_buffer,\n         \"(%s) %s error%s:\\n %s%s ->\\n       %s\\n  not: %s.\\n\"\n         \"Use --preserve and examine: \", pixel_loc, reason, via_linear,\n         pixel_in, background_info, pixel_out, pixel_calc);\n      return logerror(transform->in_image, transform->in_image->file_name,\n         error_buffer, transform->out_image->file_name);\n   }\n\n   else\n   {\n      char error_buffer[512];\n      sprintf(error_buffer,\n         \"(%s) %s error%s:\\n %s%s ->\\n       %s\\n  not: %s.\\n\"\n         \" The error happened when reading the original file with this format.\",\n         pixel_loc, reason, via_linear, pixel_in, background_info, pixel_out,\n         pixel_calc);\n      return logerror(transform->in_image, transform->in_image->file_name,\n         error_buffer, \"\");\n   }\n}\n\nstatic int\ncmppixel(Transform *transform, png_const_voidp in, png_const_voidp out,\n   png_uint_32 x, png_uint_32 y/*or palette index*/)\n{\n   int maxerr;\n   png_const_charp errmsg;\n   Pixel pixel_in, pixel_calc, pixel_out;\n\n   transform->in_gp(&pixel_in, in);\n\n   if (transform->from_linear == NULL)\n      transform->transform(&pixel_calc, &pixel_in, transform->background);\n\n   else\n   {\n      transform->transform(&pixel_out, &pixel_in, transform->background);\n      transform->from_linear(&pixel_calc, &pixel_out, NULL);\n   }\n\n   transform->out_gp(&pixel_out, out);\n\n   /* Eliminate the case where the input and output values match exactly. */\n   if (pixel_calc.a == pixel_out.a && pixel_calc.r == pixel_out.r &&\n      pixel_calc.g == pixel_out.g && pixel_calc.b == pixel_out.b)\n      return 1;\n\n   /* Eliminate the case where the output pixel is transparent and the output\n    * is 8-bit - any component values are valid.  Don't check the input alpha\n    * here to also skip the 16-bit small alpha cases.\n    */\n   if (transform->output_8bit && pixel_calc.a == 0 && pixel_out.a == 0)\n      return 1;\n\n   /* Check for alpha errors first; an alpha error can damage the components too\n    * so avoid spurious checks on components if one is found.\n    */\n   errmsg = NULL;\n   {\n      int err_a = abs(pixel_calc.a-pixel_out.a);\n\n      if (err_a > transform->error[3])\n      {\n         /* If accumulating check the components too */\n         if (transform->accumulate)\n            transform->error[3] = (png_uint_16)err_a;\n\n         else\n            errmsg = \"alpha\";\n      }\n   }\n\n   /* Now if *either* of the output alphas are 0 but alpha is within tolerance\n    * eliminate the 8-bit component comparison.\n    */\n   if (errmsg == NULL && transform->output_8bit &&\n      (pixel_calc.a == 0 || pixel_out.a == 0))\n      return 1;\n\n   if (errmsg == NULL) /* else just signal an alpha error */\n   {\n      int err_r = abs(pixel_calc.r - pixel_out.r);\n      int err_g = abs(pixel_calc.g - pixel_out.g);\n      int err_b = abs(pixel_calc.b - pixel_out.b);\n      int limit;\n\n      if ((err_r | err_g | err_b) == 0)\n         return 1; /* exact match */\n\n      /* Mismatch on a component, check the input alpha */\n      if (pixel_in.a >= transform->in_opaque)\n      {\n         errmsg = \"opaque component\";\n         limit = 2; /* opaque */\n      }\n\n      else if (pixel_in.a > 0)\n      {\n         errmsg = \"alpha component\";\n         limit = 1; /* partially transparent */\n      }\n\n      else\n      {\n         errmsg = \"transparent component (background)\";\n         limit = 0; /* transparent */\n      }\n\n      maxerr = err_r;\n      if (maxerr < err_g) maxerr = err_g;\n      if (maxerr < err_b) maxerr = err_b;\n\n      if (maxerr <= transform->error[limit])\n         return 1; /* within the error limits */\n\n      /* Handle a component mis-match; log it, just return an error code, or\n       * accumulate it.\n       */\n      if (transform->accumulate)\n      {\n         transform->error[limit] = (png_uint_16)maxerr;\n         return 1; /* to cause the caller to keep going */\n      }\n   }\n\n   /* Failure to match and not accumulating, so the error must be logged. */\n   return logpixel(transform, x, y, &pixel_in, &pixel_calc, &pixel_out, errmsg);\n}\n\nstatic png_byte\ncomponent_loc(png_byte loc[4], png_uint_32 format)\n{\n   /* Given a format return the number of channels and the location of\n    * each channel.\n    *\n    * The mask 'loc' contains the component offset of the channels in the\n    * following order.  Note that if 'format' is grayscale the entries 1-3 must\n    * all contain the location of the gray channel.\n    *\n    * 0: alpha\n    * 1: red or gray\n    * 2: green or gray\n    * 3: blue or gray\n    */\n   png_byte channels;\n\n   if (format & PNG_FORMAT_FLAG_COLOR)\n   {\n      channels = 3;\n\n      loc[2] = 1;\n\n#     ifdef PNG_FORMAT_BGR_SUPPORTED\n         if (format & PNG_FORMAT_FLAG_BGR)\n         {\n            loc[1] = 2;\n            loc[3] = 0;\n         }\n\n         else\n#     endif\n      {\n         loc[1] = 0;\n         loc[3] = 2;\n      }\n   }\n\n   else\n   {\n      channels = 1;\n      loc[1] = loc[2] = loc[3] = 0;\n   }\n\n   if (format & PNG_FORMAT_FLAG_ALPHA)\n   {\n#     ifdef PNG_FORMAT_AFIRST_SUPPORTED\n         if (format & PNG_FORMAT_FLAG_AFIRST)\n         {\n            loc[0] = 0;\n            ++loc[1];\n            ++loc[2];\n            ++loc[3];\n         }\n\n         else\n#     endif\n         loc[0] = channels;\n\n      ++channels;\n   }\n\n   else\n      loc[0] = 4; /* not present */\n\n   return channels;\n}\n\n/* Compare two images, the original 'a', which was written out then read back in\n * to * give image 'b'.  The formats may have been changed.\n */\nstatic int\ncompare_two_images(Image *a, Image *b, int via_linear,\n   png_const_colorp background)\n{\n   ptrdiff_t stridea = a->stride;\n   ptrdiff_t strideb = b->stride;\n   png_const_bytep rowa = a->buffer+16;\n   png_const_bytep rowb = b->buffer+16;\n   const png_uint_32 width = a->image.width;\n   const png_uint_32 height = a->image.height;\n   const png_uint_32 formata = a->image.format;\n   const png_uint_32 formatb = b->image.format;\n   const unsigned int a_sample = PNG_IMAGE_SAMPLE_SIZE(formata);\n   const unsigned int b_sample = PNG_IMAGE_SAMPLE_SIZE(formatb);\n   int alpha_added, alpha_removed;\n   int bchannels;\n   int btoa[4];\n   png_uint_32 y;\n   Transform tr;\n\n   /* This should never happen: */\n   if (width != b->image.width || height != b->image.height)\n      return logerror(a, a->file_name, \": width x height changed: \",\n         b->file_name);\n\n   /* Set up the background and the transform */\n   transform_from_formats(&tr, a, b, background, via_linear);\n\n   /* Find the first row and inter-row space. */\n   if (!(formata & PNG_FORMAT_FLAG_COLORMAP) &&\n      (formata & PNG_FORMAT_FLAG_LINEAR))\n      stridea *= 2;\n\n   if (!(formatb & PNG_FORMAT_FLAG_COLORMAP) &&\n      (formatb & PNG_FORMAT_FLAG_LINEAR))\n      strideb *= 2;\n\n   if (stridea < 0) rowa += (height-1) * (-stridea);\n   if (strideb < 0) rowb += (height-1) * (-strideb);\n\n   /* First shortcut the two colormap case by comparing the image data; if it\n    * matches then we expect the colormaps to match, although this is not\n    * absolutely necessary for an image match.  If the colormaps fail to match\n    * then there is a problem in libpng.\n    */\n   if (formata & formatb & PNG_FORMAT_FLAG_COLORMAP)\n   {\n      /* Only check colormap entries that actually exist; */\n      png_const_bytep ppa, ppb;\n      int match;\n      png_byte in_use[256], amax = 0, bmax = 0;\n\n      memset(in_use, 0, sizeof in_use);\n\n      ppa = rowa;\n      ppb = rowb;\n\n      /* Do this the slow way to accumulate the 'in_use' flags, don't break out\n       * of the loop until the end; this validates the color-mapped data to\n       * ensure all pixels are valid color-map indexes.\n       */\n      for (y=0, match=1; y<height && match; ++y, ppa += stridea, ppb += strideb)\n      {\n         png_uint_32 x;\n\n         for (x=0; x<width; ++x)\n         {\n            png_byte bval = ppb[x];\n            png_byte aval = ppa[x];\n\n            if (bval > bmax)\n               bmax = bval;\n\n            if (bval != aval)\n               match = 0;\n\n            in_use[aval] = 1;\n            if (aval > amax)\n               amax = aval;\n         }\n      }\n\n      /* If the buffers match then the colormaps must too. */\n      if (match)\n      {\n         /* Do the color-maps match, entry by entry?  Only check the 'in_use'\n          * entries.  An error here should be logged as a color-map error.\n          */\n         png_const_bytep a_cmap = (png_const_bytep)a->colormap;\n         png_const_bytep b_cmap = (png_const_bytep)b->colormap;\n         int result = 1; /* match by default */\n\n         /* This is used in logpixel to get the error message correct. */\n         tr.is_palette = 1;\n\n         for (y=0; y<256; ++y, a_cmap += a_sample, b_cmap += b_sample)\n            if (in_use[y])\n         {\n            /* The colormap entries should be valid, but because libpng doesn't\n             * do any checking at present the original image may contain invalid\n             * pixel values.  These cause an error here (at present) unless\n             * accumulating errors in which case the program just ignores them.\n             */\n            if (y >= a->image.colormap_entries)\n            {\n               if ((a->opts & ACCUMULATE) == 0)\n               {\n                  char pindex[9];\n                  sprintf(pindex, \"%lu[%lu]\", (unsigned long)y,\n                     (unsigned long)a->image.colormap_entries);\n                  logerror(a, a->file_name, \": bad pixel index: \", pindex);\n               }\n               result = 0;\n            }\n\n            else if (y >= b->image.colormap_entries)\n            {\n               if ((b->opts & ACCUMULATE) == 0)\n                  {\n                  char pindex[9];\n                  sprintf(pindex, \"%lu[%lu]\", (unsigned long)y,\n                     (unsigned long)b->image.colormap_entries);\n                  logerror(b, b->file_name, \": bad pixel index: \", pindex);\n                  }\n               result = 0;\n            }\n\n            /* All the mismatches are logged here; there can only be 256! */\n            else if (!cmppixel(&tr, a_cmap, b_cmap, 0, y))\n               result = 0;\n         }\n\n         /* If reqested copy the error values back from the Transform. */\n         if (a->opts & ACCUMULATE)\n         {\n            tr.error_ptr[0] = tr.error[0];\n            tr.error_ptr[1] = tr.error[1];\n            tr.error_ptr[2] = tr.error[2];\n            tr.error_ptr[3] = tr.error[3];\n            result = 1; /* force a continue */\n         }\n\n         return result;\n      }\n\n      /* else the image buffers don't match pixel-wise so compare sample values\n       * instead, but first validate that the pixel indexes are in range (but\n       * only if not accumulating, when the error is ignored.)\n       */\n      else if ((a->opts & ACCUMULATE) == 0)\n      {\n         /* Check the original image first,\n          * TODO: deal with input images with bad pixel values?\n          */\n         if (amax >= a->image.colormap_entries)\n         {\n            char pindex[9];\n            sprintf(pindex, \"%d[%lu]\", amax,\n               (unsigned long)a->image.colormap_entries);\n            return logerror(a, a->file_name, \": bad pixel index: \", pindex);\n         }\n\n         else if (bmax >= b->image.colormap_entries)\n         {\n            char pindex[9];\n            sprintf(pindex, \"%d[%lu]\", bmax,\n               (unsigned long)b->image.colormap_entries);\n            return logerror(b, b->file_name, \": bad pixel index: \", pindex);\n         }\n      }\n   }\n\n   /* We can directly compare pixel values without the need to use the read\n    * or transform support (i.e. a memory compare) if:\n    *\n    * 1) The bit depth has not changed.\n    * 2) RGB to grayscale has not been done (the reverse is ok; we just compare\n    *    the three RGB values to the original grayscale.)\n    * 3) An alpha channel has not been removed from an 8-bit format, or the\n    *    8-bit alpha value of the pixel was 255 (opaque).\n    *\n    * If an alpha channel has been *added* then it must have the relevant opaque\n    * value (255 or 65535).\n    *\n    * The fist two the tests (in the order given above) (using the boolean\n    * equivalence !a && !b == !(a || b))\n    */\n   if (!(((formata ^ formatb) & PNG_FORMAT_FLAG_LINEAR) |\n      (formata & (formatb ^ PNG_FORMAT_FLAG_COLOR) & PNG_FORMAT_FLAG_COLOR)))\n   {\n      /* Was an alpha channel changed? */\n      const png_uint_32 alpha_changed = (formata ^ formatb) &\n         PNG_FORMAT_FLAG_ALPHA;\n\n      /* Was an alpha channel removed?  (The third test.)  If so the direct\n       * comparison is only possible if the input alpha is opaque.\n       */\n      alpha_removed = (formata & alpha_changed) != 0;\n\n      /* Was an alpha channel added? */\n      alpha_added = (formatb & alpha_changed) != 0;\n\n      /* The channels may have been moved between input and output, this finds\n       * out how, recording the result in the btoa array, which says where in\n       * 'a' to find each channel of 'b'.  If alpha was added then btoa[alpha]\n       * ends up as 4 (and is not used.)\n       */\n      {\n         int i;\n         png_byte aloc[4];\n         png_byte bloc[4];\n\n         /* The following are used only if the formats match, except that\n          * 'bchannels' is a flag for matching formats.  btoa[x] says, for each\n          * channel in b, where to find the corresponding value in a, for the\n          * bchannels.  achannels may be different for a gray to rgb transform\n          * (a will be 1 or 2, b will be 3 or 4 channels.)\n          */\n         (void)component_loc(aloc, formata);\n         bchannels = component_loc(bloc, formatb);\n\n         /* Hence the btoa array. */\n         for (i=0; i<4; ++i) if (bloc[i] < 4)\n            btoa[bloc[i]] = aloc[i]; /* may be '4' for alpha */\n\n         if (alpha_added)\n            alpha_added = bloc[0]; /* location of alpha channel in image b */\n\n         else\n            alpha_added = 4; /* Won't match an image b channel */\n\n         if (alpha_removed)\n            alpha_removed = aloc[0]; /* location of alpha channel in image a */\n\n         else\n            alpha_removed = 4;\n      }\n   }\n\n   else\n   {\n      /* Direct compare is not possible, cancel out all the corresponding local\n       * variables.\n       */\n      bchannels = 0;\n      alpha_removed = alpha_added = 4;\n      btoa[3] = btoa[2] = btoa[1] = btoa[0] = 4; /* 4 == not present */\n   }\n\n   for (y=0; y<height; ++y, rowa += stridea, rowb += strideb)\n   {\n      png_const_bytep ppa, ppb;\n      png_uint_32 x;\n\n      for (x=0, ppa=rowa, ppb=rowb; x<width; ++x)\n      {\n         png_const_bytep psa, psb;\n\n         if (formata & PNG_FORMAT_FLAG_COLORMAP)\n            psa = (png_const_bytep)a->colormap + a_sample * *ppa++;\n         else\n            psa = ppa, ppa += a_sample;\n\n         if (formatb & PNG_FORMAT_FLAG_COLORMAP)\n            psb = (png_const_bytep)b->colormap + b_sample * *ppb++;\n         else\n            psb = ppb, ppb += b_sample;\n\n         /* Do the fast test if possible. */\n         if (bchannels)\n         {\n            /* Check each 'b' channel against either the corresponding 'a'\n             * channel or the opaque alpha value, as appropriate.  If\n             * alpha_removed value is set (not 4) then also do this only if the\n             * 'a' alpha channel (alpha_removed) is opaque; only relevant for\n             * the 8-bit case.\n             */\n            if (formatb & PNG_FORMAT_FLAG_LINEAR) /* 16-bit checks */\n            {\n               png_const_uint_16p pua = aligncastconst(png_const_uint_16p, psa);\n               png_const_uint_16p pub = aligncastconst(png_const_uint_16p, psb);\n\n               switch (bchannels)\n               {\n                  case 4:\n                     if (pua[btoa[3]] != pub[3]) break;\n                  case 3:\n                     if (pua[btoa[2]] != pub[2]) break;\n                  case 2:\n                     if (pua[btoa[1]] != pub[1]) break;\n                  case 1:\n                     if (pua[btoa[0]] != pub[0]) break;\n                     if (alpha_added != 4 && pub[alpha_added] != 65535) break;\n                     continue; /* x loop */\n                  default:\n                     break; /* impossible */\n               }\n            }\n\n            else if (alpha_removed == 4 || psa[alpha_removed] == 255)\n            {\n               switch (bchannels)\n               {\n                  case 4:\n                     if (psa[btoa[3]] != psb[3]) break;\n                  case 3:\n                     if (psa[btoa[2]] != psb[2]) break;\n                  case 2:\n                     if (psa[btoa[1]] != psb[1]) break;\n                  case 1:\n                     if (psa[btoa[0]] != psb[0]) break;\n                     if (alpha_added != 4 && psb[alpha_added] != 255) break;\n                     continue; /* x loop */\n                  default:\n                     break; /* impossible */\n               }\n            }\n         }\n\n         /* If we get to here the fast match failed; do the slow match for this\n          * pixel.\n          */\n         if (!cmppixel(&tr, psa, psb, x, y) && (a->opts & KEEP_GOING) == 0)\n            return 0; /* error case */\n      }\n   }\n\n   /* If reqested copy the error values back from the Transform. */\n   if (a->opts & ACCUMULATE)\n   {\n      tr.error_ptr[0] = tr.error[0];\n      tr.error_ptr[1] = tr.error[1];\n      tr.error_ptr[2] = tr.error[2];\n      tr.error_ptr[3] = tr.error[3];\n   }\n\n   return 1;\n}\n\n/* Read the file; how the read gets done depends on which of input_file and\n * input_memory have been set.\n */\nstatic int\nread_file(Image *image, png_uint_32 format, png_const_colorp background)\n{\n   memset(&image->image, 0, sizeof image->image);\n   image->image.version = PNG_IMAGE_VERSION;\n\n   if (image->input_memory != NULL)\n   {\n      if (!png_image_begin_read_from_memory(&image->image, image->input_memory,\n         image->input_memory_size))\n         return logerror(image, \"memory init: \", image->file_name, \"\");\n   }\n\n#  ifdef PNG_STDIO_SUPPORTED\n      else if (image->input_file != NULL)\n      {\n         if (!png_image_begin_read_from_stdio(&image->image, image->input_file))\n            return logerror(image, \"stdio init: \", image->file_name, \"\");\n      }\n\n      else\n      {\n         if (!png_image_begin_read_from_file(&image->image, image->file_name))\n            return logerror(image, \"file init: \", image->file_name, \"\");\n      }\n#  else\n      else\n      {\n         return logerror(image, \"unsupported file/stdio init: \",\n            image->file_name, \"\");\n      }\n#  endif\n\n   /* This must be set after the begin_read call: */\n   if (image->opts & sRGB_16BIT)\n      image->image.flags |= PNG_IMAGE_FLAG_16BIT_sRGB;\n\n   /* Have an initialized image with all the data we need plus, maybe, an\n    * allocated file (myfile) or buffer (mybuffer) that need to be freed.\n    */\n   {\n      int result;\n      png_uint_32 image_format;\n\n      /* Print both original and output formats. */\n      image_format = image->image.format;\n\n      if (image->opts & VERBOSE)\n      {\n         printf(\"%s %lu x %lu %s -> %s\", image->file_name,\n            (unsigned long)image->image.width,\n            (unsigned long)image->image.height,\n            format_names[image_format & FORMAT_MASK],\n            (format & FORMAT_NO_CHANGE) != 0 || image->image.format == format\n            ? \"no change\" : format_names[format & FORMAT_MASK]);\n\n         if (background != NULL)\n            printf(\" background(%d,%d,%d)\\n\", background->red,\n               background->green, background->blue);\n         else\n            printf(\"\\n\");\n\n         fflush(stdout);\n      }\n\n      /* 'NO_CHANGE' combined with the color-map flag forces the base format\n       * flags to be set on read to ensure that the original representation is\n       * not lost in the pass through a colormap format.\n       */\n      if ((format & FORMAT_NO_CHANGE) != 0)\n      {\n         if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0 &&\n            (image_format & PNG_FORMAT_FLAG_COLORMAP) != 0)\n            format = (image_format & ~BASE_FORMATS) | (format & BASE_FORMATS);\n\n         else\n            format = image_format;\n      }\n\n      image->image.format = format;\n\n      image->stride = PNG_IMAGE_ROW_STRIDE(image->image) + image->stride_extra;\n      allocbuffer(image);\n\n      result = png_image_finish_read(&image->image, background,\n         image->buffer+16, (png_int_32)image->stride, image->colormap);\n\n      checkbuffer(image, image->file_name);\n\n      if (result)\n         return checkopaque(image);\n\n      else\n         return logerror(image, image->file_name, \": image read failed\", \"\");\n   }\n}\n\n/* Reads from a filename, which must be in image->file_name, but uses\n * image->opts to choose the method.  The file is always read in its native\n * format (the one the simplified API suggests).\n */\nstatic int\nread_one_file(Image *image)\n{\n   if (!(image->opts & USE_FILE) || (image->opts & USE_STDIO))\n   {\n      /* memory or stdio. */\n      FILE *f = fopen(image->file_name, \"rb\");\n\n      if (f != NULL)\n      {\n         if (image->opts & USE_FILE)\n            image->input_file = f;\n\n         else /* memory */\n         {\n            if (fseek(f, 0, SEEK_END) == 0)\n            {\n               long int cb = ftell(f);\n\n               if (cb > 0)\n               {\n#ifndef __COVERITY__\n                  if ((unsigned long int)cb <= (size_t)~(size_t)0)\n#endif\n                  {\n                     png_bytep b = voidcast(png_bytep, malloc((size_t)cb));\n\n                     if (b != NULL)\n                     {\n                        rewind(f);\n\n                        if (fread(b, (size_t)cb, 1, f) == 1)\n                        {\n                           fclose(f);\n                           image->input_memory_size = cb;\n                           image->input_memory = b;\n                        }\n\n                        else\n                        {\n                           free(b);\n                           return logclose(image, f, image->file_name,\n                              \": read failed: \");\n                        }\n                     }\n\n                     else\n                        return logclose(image, f, image->file_name,\n                           \": out of memory: \");\n                  }\n\n                  else\n                     return logclose(image, f, image->file_name,\n                        \": file too big for this architecture: \");\n                     /* cb is the length of the file as a (long) and\n                      * this is greater than the maximum amount of\n                      * memory that can be requested from malloc.\n                      */\n               }\n\n               else if (cb == 0)\n                  return logclose(image, f, image->file_name,\n                     \": zero length: \");\n\n               else\n                  return logclose(image, f, image->file_name,\n                     \": tell failed: \");\n            }\n\n            else\n               return logclose(image, f, image->file_name, \": seek failed: \");\n         }\n      }\n\n      else\n         return logerror(image, image->file_name, \": open failed: \",\n            strerror(errno));\n   }\n\n   return read_file(image, FORMAT_NO_CHANGE, NULL);\n}\n\n#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED\nstatic int\nwrite_one_file(Image *output, Image *image, int convert_to_8bit)\n{\n   if (image->opts & FAST_WRITE)\n      image->image.flags |= PNG_IMAGE_FLAG_FAST;\n\n   if (image->opts & USE_STDIO)\n   {\n#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED\n#ifndef __COVERITY__\n      FILE *f = tmpfile();\n#else\n      /* Experimental. Coverity says tmpfile() is insecure because it\n       * generates predictable names.\n       *\n       * It is possible to satisfy Coverity by using mkstemp(); however,\n       * any platform supporting mkstemp() undoubtedly has a secure tmpfile()\n       * implementation as well, and doesn't need the fix.  Note that\n       * the fix won't work on platforms that don't support mkstemp().\n       *\n       * https://www.securecoding.cert.org/confluence/display/c/\n       * FIO21-C.+Do+not+create+temporary+files+in+shared+directories\n       * says that most historic implementations of tmpfile() provide\n       * only a limited number of possible temporary file names\n       * (usually 26) before file names are recycled. That article also\n       * provides a secure solution that unfortunately depends upon mkstemp().\n       */\n      char tmpfile[] = \"pngstest-XXXXXX\";\n      int filedes;\n      FILE *f;\n      umask(0177);\n      filedes = mkstemp(tmpfile);\n      if (filedes < 0)\n        f = NULL;\n      else\n      {\n        f = fdopen(filedes,\"w+\");\n        /* Hide the filename immediately and ensure that the file does\n         * not exist after the program ends\n         */\n        (void) unlink(tmpfile);\n      }\n#endif\n\n      if (f != NULL)\n      {\n         if (png_image_write_to_stdio(&image->image, f, convert_to_8bit,\n            image->buffer+16, (png_int_32)image->stride, image->colormap))\n         {\n            if (fflush(f) == 0)\n            {\n               rewind(f);\n               initimage(output, image->opts, \"tmpfile\", image->stride_extra);\n               output->input_file = f;\n               if (!checkopaque(image))\n                  return 0;\n            }\n\n            else\n               return logclose(image, f, \"tmpfile\", \": flush: \");\n         }\n\n         else\n         {\n            fclose(f);\n            return logerror(image, \"tmpfile\", \": write failed\", \"\");\n         }\n      }\n\n      else\n         return logerror(image, \"tmpfile\", \": open: \", strerror(errno));\n#else /* SIMPLIFIED_WRITE_STDIO */\n      return logerror(image, \"tmpfile\", \": open: unsupported\", \"\");\n#endif /* SIMPLIFIED_WRITE_STDIO */\n   }\n\n   else if (image->opts & USE_FILE)\n   {\n#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED\n      static int counter = 0;\n      char name[32];\n\n      sprintf(name, \"%s%d.png\", tmpf, ++counter);\n\n      if (png_image_write_to_file(&image->image, name, convert_to_8bit,\n         image->buffer+16, (png_int_32)image->stride, image->colormap))\n      {\n         initimage(output, image->opts, output->tmpfile_name,\n            image->stride_extra);\n         /* Afterwards, or freeimage will delete it! */\n         strcpy(output->tmpfile_name, name);\n\n         if (!checkopaque(image))\n            return 0;\n      }\n\n      else\n         return logerror(image, name, \": write failed\", \"\");\n#else /* SIMPLIFIED_WRITE_STDIO */\n      return logerror(image, \"stdio\", \": open: unsupported\", \"\");\n#endif /* SIMPLIFIED_WRITE_STDIO */\n   }\n\n   else /* use memory */\n   {\n      png_alloc_size_t size;\n\n      if (png_image_write_get_memory_size(image->image, size, convert_to_8bit,\n               image->buffer+16, (png_int_32)image->stride, image->colormap))\n      {\n         /* This is non-fatal but ignoring it was causing serious problems in\n          * the macro to be ignored:\n          */\n         if (size > PNG_IMAGE_PNG_SIZE_MAX(image->image))\n            return logerror(image, \"memory\", \": PNG_IMAGE_SIZE_MAX wrong\", \"\");\n\n         initimage(output, image->opts, \"memory\", image->stride_extra);\n         output->input_memory = malloc(size);\n\n         if (output->input_memory != NULL)\n         {\n            output->input_memory_size = size;\n\n            if (png_image_write_to_memory(&image->image, output->input_memory,\n                  &output->input_memory_size, convert_to_8bit, image->buffer+16,\n                  (png_int_32)image->stride, image->colormap))\n            {\n               /* This is also non-fatal but it safes safer to error out anyway:\n                */\n               if (size != output->input_memory_size)\n                  return logerror(image, \"memory\", \": memory size wrong\", \"\");\n            }\n\n            else\n               return logerror(image, \"memory\", \": write failed\", \"\");\n         }\n\n         else\n            return logerror(image, \"memory\", \": out of memory\", \"\");\n      }\n\n      else\n         return logerror(image, \"memory\", \": get size:\", \"\");\n   }\n\n   /* 'output' has an initialized temporary image, read this back in and compare\n    * this against the original: there should be no change since the original\n    * format was written unmodified unless 'convert_to_8bit' was specified.\n    * However, if the original image was color-mapped, a simple read will zap\n    * the linear, color and maybe alpha flags, this will cause spurious failures\n    * under some circumstances.\n    */\n   if (read_file(output, image->image.format | FORMAT_NO_CHANGE, NULL))\n   {\n      png_uint_32 original_format = image->image.format;\n\n      if (convert_to_8bit)\n         original_format &= ~PNG_FORMAT_FLAG_LINEAR;\n\n      if ((output->image.format & BASE_FORMATS) !=\n         (original_format & BASE_FORMATS))\n         return logerror(image, image->file_name, \": format changed on read: \",\n            output->file_name);\n\n      return compare_two_images(image, output, 0/*via linear*/, NULL);\n   }\n\n   else\n      return logerror(output, output->tmpfile_name,\n         \": read of new file failed\", \"\");\n}\n#endif\n\nstatic int\ntestimage(Image *image, png_uint_32 opts, format_list *pf)\n{\n   int result;\n   Image copy;\n\n   /* Copy the original data, stealing it from 'image' */\n   checkopaque(image);\n   copy = *image;\n\n   copy.opts = opts;\n   copy.buffer = NULL;\n   copy.bufsize = 0;\n   copy.allocsize = 0;\n\n   image->input_file = NULL;\n   image->input_memory = NULL;\n   image->input_memory_size = 0;\n   image->tmpfile_name[0] = 0;\n\n   {\n      png_uint_32 counter;\n      Image output;\n\n      newimage(&output);\n\n      result = 1;\n\n      /* Use the low bit of 'counter' to indicate whether or not to do alpha\n       * removal with a background color or by composting onto the image; this\n       * step gets skipped if it isn't relevant\n       */\n      for (counter=0; counter<2*FORMAT_COUNT; ++counter)\n         if (format_isset(pf, counter >> 1))\n      {\n         png_uint_32 format = counter >> 1;\n\n         png_color background_color;\n         png_colorp background = NULL;\n\n         /* If there is a format change that removes the alpha channel then\n          * the background is relevant.  If the output is 8-bit color-mapped\n          * then a background color *must* be provided, otherwise there are\n          * two tests to do - one with a color, the other with NULL.  The\n          * NULL test happens second.\n          */\n         if ((counter & 1) == 0)\n         {\n            if ((format & PNG_FORMAT_FLAG_ALPHA) == 0 &&\n               (image->image.format & PNG_FORMAT_FLAG_ALPHA) != 0)\n            {\n               /* Alpha/transparency will be removed, the background is\n                * relevant: make it a color the first time\n                */\n               random_color(&background_color);\n               background = &background_color;\n\n               /* BUT if the output is to a color-mapped 8-bit format then\n                * the background must always be a color, so increment 'counter'\n                * to skip the NULL test.\n                */\n               if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0 &&\n                  (format & PNG_FORMAT_FLAG_LINEAR) == 0)\n                  ++counter;\n            }\n\n            /* Otherwise an alpha channel is not being eliminated, just leave\n             * background NULL and skip the (counter & 1) NULL test.\n             */\n            else\n               ++counter;\n         }\n         /* else just use NULL for background */\n\n         resetimage(&copy);\n         copy.opts = opts; /* in case read_file needs to change it */\n\n         result = read_file(&copy, format, background);\n         if (!result)\n            break;\n\n         /* Make sure the file just read matches the original file. */\n         result = compare_two_images(image, &copy, 0/*via linear*/, background);\n         if (!result)\n            break;\n\n#        ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED\n            /* Write the *copy* just made to a new file to make sure the write\n             * side works ok.  Check the conversion to sRGB if the copy is\n             * linear.\n             */\n            output.opts = opts;\n            result = write_one_file(&output, &copy, 0/*convert to 8bit*/);\n            if (!result)\n               break;\n\n            /* Validate against the original too; the background is needed here\n             * as well so that compare_two_images knows what color was used.\n             */\n            result = compare_two_images(image, &output, 0, background);\n            if (!result)\n               break;\n\n            if ((format & PNG_FORMAT_FLAG_LINEAR) != 0 &&\n               (format & PNG_FORMAT_FLAG_COLORMAP) == 0)\n            {\n               /* 'output' is linear, convert to the corresponding sRGB format.\n                */\n               output.opts = opts;\n               result = write_one_file(&output, &copy, 1/*convert to 8bit*/);\n               if (!result)\n                  break;\n\n               /* This may involve a conversion via linear; in the ideal world\n                * this would round-trip correctly, but libpng 1.5.7 is not the\n                * ideal world so allow a drift (error_via_linear).\n                *\n                * 'image' has an alpha channel but 'output' does not then there\n                * will a strip-alpha-channel operation (because 'output' is\n                * linear), handle this by composing on black when doing the\n                * comparison.\n                */\n               result = compare_two_images(image, &output, 1/*via_linear*/,\n                  background);\n               if (!result)\n                  break;\n            }\n#        endif /* PNG_SIMPLIFIED_WRITE_SUPPORTED */\n      }\n\n      freeimage(&output);\n   }\n\n   freeimage(&copy);\n\n   return result;\n}\n\nstatic int\ntest_one_file(const char *file_name, format_list *formats, png_uint_32 opts,\n   int stride_extra, int log_pass)\n{\n   int result;\n   Image image;\n\n   if (!(opts & NO_RESEED))\n      reseed(); /* ensure that the random numbers don't depend on file order */\n   newimage(&image);\n   initimage(&image, opts, file_name, stride_extra);\n   result = read_one_file(&image);\n   if (result)\n      result = testimage(&image, opts, formats);\n   freeimage(&image);\n\n   /* Ensure that stderr is flushed into any log file */\n   fflush(stderr);\n\n   if (log_pass)\n   {\n      if (result)\n         printf(\"PASS:\");\n\n      else\n         printf(\"FAIL:\");\n\n#     ifndef PNG_SIMPLIFIED_WRITE_SUPPORTED\n         printf(\" (no write)\");\n#     endif\n\n      print_opts(opts);\n      printf(\" %s\\n\", file_name);\n      /* stdout may not be line-buffered if it is piped to a file, so: */\n      fflush(stdout);\n   }\n\n   else if (!result)\n      exit(1);\n\n   return result;\n}\n\nint\nmain(int argc, char **argv)\n{\n   png_uint_32 opts = FAST_WRITE | STRICT;\n   format_list formats;\n   const char *touch = NULL;\n   int log_pass = 0;\n   int redundant = 0;\n   int stride_extra = 0;\n   int retval = 0;\n   int c;\n\n#if PNG_LIBPNG_VER >= 10700\n      /* This error should not exist in 1.7 or later: */\n      opts |= GBG_ERROR;\n#endif\n\n   init_sRGB_to_d();\n#if 0\n   init_error_via_linear();\n#endif\n   format_init(&formats);\n   reseed(); /* initialize random number seeds */\n\n   for (c=1; c<argc; ++c)\n   {\n      const char *arg = argv[c];\n\n      if (strcmp(arg, \"--log\") == 0)\n         log_pass = 1;\n      else if (strcmp(arg, \"--fresh\") == 0)\n      {\n         memset(gpc_error, 0, sizeof gpc_error);\n         memset(gpc_error_via_linear, 0, sizeof gpc_error_via_linear);\n      }\n      else if (strcmp(arg, \"--file\") == 0)\n#        ifdef PNG_STDIO_SUPPORTED\n            opts |= USE_FILE;\n#        else\n            return SKIP; /* skipped: no support */\n#        endif\n      else if (strcmp(arg, \"--memory\") == 0)\n         opts &= ~USE_FILE;\n      else if (strcmp(arg, \"--stdio\") == 0)\n#        ifdef PNG_STDIO_SUPPORTED\n            opts |= USE_STDIO;\n#        else\n            return SKIP; /* skipped: no support */\n#        endif\n      else if (strcmp(arg, \"--name\") == 0)\n         opts &= ~USE_STDIO;\n      else if (strcmp(arg, \"--verbose\") == 0)\n         opts |= VERBOSE;\n      else if (strcmp(arg, \"--quiet\") == 0)\n         opts &= ~VERBOSE;\n      else if (strcmp(arg, \"--preserve\") == 0)\n         opts |= KEEP_TMPFILES;\n      else if (strcmp(arg, \"--nopreserve\") == 0)\n         opts &= ~KEEP_TMPFILES;\n      else if (strcmp(arg, \"--keep-going\") == 0)\n         opts |= KEEP_GOING;\n      else if (strcmp(arg, \"--fast\") == 0)\n         opts |= FAST_WRITE;\n      else if (strcmp(arg, \"--slow\") == 0)\n         opts &= ~FAST_WRITE;\n      else if (strcmp(arg, \"--accumulate\") == 0)\n         opts |= ACCUMULATE;\n      else if (strcmp(arg, \"--redundant\") == 0)\n         redundant = 1;\n      else if (strcmp(arg, \"--stop\") == 0)\n         opts &= ~KEEP_GOING;\n      else if (strcmp(arg, \"--strict\") == 0)\n         opts |= STRICT;\n      else if (strcmp(arg, \"--nostrict\") == 0)\n         opts &= ~STRICT;\n      else if (strcmp(arg, \"--sRGB-16bit\") == 0)\n         opts |= sRGB_16BIT;\n      else if (strcmp(arg, \"--linear-16bit\") == 0)\n         opts &= ~sRGB_16BIT;\n      else if (strcmp(arg, \"--noreseed\") == 0)\n         opts |= NO_RESEED;\n      else if (strcmp(arg, \"--fault-gbg-warning\") == 0)\n         opts |= GBG_ERROR;\n      else if (strcmp(arg, \"--tmpfile\") == 0)\n      {\n         if (c+1 < argc)\n         {\n            if (strlen(argv[++c]) >= sizeof tmpf)\n            {\n               fflush(stdout);\n               fprintf(stderr, \"%s: %s is too long for a temp file prefix\\n\",\n                  argv[0], argv[c]);\n               exit(99);\n            }\n\n            /* Safe: checked above */\n            strncpy(tmpf, argv[c], sizeof (tmpf)-1);\n         }\n\n         else\n         {\n            fflush(stdout);\n            fprintf(stderr, \"%s: %s requires a temporary file prefix\\n\",\n               argv[0], arg);\n            exit(99);\n         }\n      }\n      else if (strcmp(arg, \"--touch\") == 0)\n      {\n         if (c+1 < argc)\n            touch = argv[++c];\n\n         else\n         {\n            fflush(stdout);\n            fprintf(stderr, \"%s: %s requires a file name argument\\n\",\n               argv[0], arg);\n            exit(99);\n         }\n      }\n      else if (arg[0] == '+')\n      {\n         png_uint_32 format = formatof(arg+1);\n\n         if (format > FORMAT_COUNT)\n            exit(99);\n\n         format_set(&formats, format);\n      }\n      else if (arg[0] == '-' && arg[1] != 0 && (arg[1] != '0' || arg[2] != 0))\n      {\n         fflush(stdout);\n         fprintf(stderr, \"%s: unknown option: %s\\n\", argv[0], arg);\n         exit(99);\n      }\n      else\n      {\n         if (format_is_initial(&formats))\n            format_default(&formats, redundant);\n\n         if (arg[0] == '-')\n         {\n            const int term = (arg[1] == '0' ? 0 : '\\n');\n            unsigned int ich = 0;\n\n            /* Loop reading files, use a static buffer to simplify this and just\n             * stop if the name gets to long.\n             */\n            static char buffer[4096];\n\n            do\n            {\n               int ch = getchar();\n\n               /* Don't allow '\\0' in file names, and terminate with '\\n' or,\n                * for -0, just '\\0' (use -print0 to find to make this work!)\n                */\n               if (ch == EOF || ch == term || ch == 0)\n               {\n                  buffer[ich] = 0;\n\n                  if (ich > 0 && !test_one_file(buffer, &formats, opts,\n                     stride_extra, log_pass))\n                     retval = 1;\n\n                  if (ch == EOF)\n                     break;\n\n                  ich = 0;\n                  --ich; /* so that the increment below sets it to 0 again */\n               }\n\n               else\n                  buffer[ich] = (char)ch;\n            } while (++ich < sizeof buffer);\n\n            if (ich)\n            {\n               buffer[32] = 0;\n               buffer[4095] = 0;\n               fprintf(stderr, \"%s...%s: file name too long\\n\", buffer,\n                  buffer+(4096-32));\n               exit(99);\n            }\n         }\n\n         else if (!test_one_file(arg, &formats, opts, stride_extra, log_pass))\n            retval = 1;\n      }\n   }\n\n   if (opts & ACCUMULATE)\n   {\n      unsigned int in;\n\n      printf(\"/* contrib/libtests/pngstest-errors.h\\n\");\n      printf(\" *\\n\");\n      printf(\" * BUILT USING:\" PNG_HEADER_VERSION_STRING);\n      printf(\" *\\n\");\n      printf(\" * This code is released under the libpng license.\\n\");\n      printf(\" * For conditions of distribution and use, see the disclaimer\\n\");\n      printf(\" * and license in png.h\\n\");\n      printf(\" *\\n\");\n      printf(\" * THIS IS A MACHINE GENERATED FILE: do not edit it directly!\\n\");\n      printf(\" * Instead run:\\n\");\n      printf(\" *\\n\");\n      printf(\" *    pngstest --accumulate\\n\");\n      printf(\" *\\n\");\n      printf(\" * on as many PNG files as possible; at least PNGSuite and\\n\");\n      printf(\" * contrib/libtests/testpngs.\\n\");\n      printf(\" */\\n\");\n\n      printf(\"static png_uint_16 gpc_error[16/*in*/][16/*out*/][4/*a*/] =\\n\");\n      printf(\"{\\n\");\n      for (in=0; in<16; ++in)\n      {\n         unsigned int out;\n         printf(\" { /* input: %s */\\n \", format_names[in]);\n         for (out=0; out<16; ++out)\n         {\n            unsigned int alpha;\n            printf(\" {\");\n            for (alpha=0; alpha<4; ++alpha)\n            {\n               printf(\" %d\", gpc_error[in][out][alpha]);\n               if (alpha < 3) putchar(',');\n            }\n            printf(\" }\");\n            if (out < 15)\n            {\n               putchar(',');\n               if (out % 4 == 3) printf(\"\\n \");\n            }\n         }\n         printf(\"\\n }\");\n\n         if (in < 15)\n            putchar(',');\n         else\n            putchar('\\n');\n      }\n      printf(\"};\\n\");\n\n      printf(\"static png_uint_16 gpc_error_via_linear[16][4/*out*/][4] =\\n\");\n      printf(\"{\\n\");\n      for (in=0; in<16; ++in)\n      {\n         unsigned int out;\n         printf(\" { /* input: %s */\\n \", format_names[in]);\n         for (out=0; out<4; ++out)\n         {\n            unsigned int alpha;\n            printf(\" {\");\n            for (alpha=0; alpha<4; ++alpha)\n            {\n               printf(\" %d\", gpc_error_via_linear[in][out][alpha]);\n               if (alpha < 3) putchar(',');\n            }\n            printf(\" }\");\n            if (out < 3)\n               putchar(',');\n         }\n         printf(\"\\n }\");\n\n         if (in < 15)\n            putchar(',');\n         else\n            putchar('\\n');\n      }\n      printf(\"};\\n\");\n\n      printf(\"static png_uint_16 gpc_error_to_colormap[8/*i*/][8/*o*/][4] =\\n\");\n      printf(\"{\\n\");\n      for (in=0; in<8; ++in)\n      {\n         unsigned int out;\n         printf(\" { /* input: %s */\\n \", format_names[in]);\n         for (out=0; out<8; ++out)\n         {\n            unsigned int alpha;\n            printf(\" {\");\n            for (alpha=0; alpha<4; ++alpha)\n            {\n               printf(\" %d\", gpc_error_to_colormap[in][out][alpha]);\n               if (alpha < 3) putchar(',');\n            }\n            printf(\" }\");\n            if (out < 7)\n            {\n               putchar(',');\n               if (out % 4 == 3) printf(\"\\n \");\n            }\n         }\n         printf(\"\\n }\");\n\n         if (in < 7)\n            putchar(',');\n         else\n            putchar('\\n');\n      }\n      printf(\"};\\n\");\n      printf(\"/* END MACHINE GENERATED */\\n\");\n   }\n\n   if (retval == 0 && touch != NULL)\n   {\n      FILE *fsuccess = fopen(touch, \"wt\");\n\n      if (fsuccess != NULL)\n      {\n         int error = 0;\n         fprintf(fsuccess, \"PNG simple API tests succeeded\\n\");\n         fflush(fsuccess);\n         error = ferror(fsuccess);\n\n         if (fclose(fsuccess) || error)\n         {\n            fflush(stdout);\n            fprintf(stderr, \"%s: write failed\\n\", touch);\n            exit(99);\n         }\n      }\n\n      else\n      {\n         fflush(stdout);\n         fprintf(stderr, \"%s: open failed\\n\", touch);\n         exit(99);\n      }\n   }\n\n   return retval;\n}\n\n#else /* !PNG_SIMPLIFIED_READ_SUPPORTED */\nint main(void)\n{\n   fprintf(stderr, \"pngstest: no read support in libpng, test skipped\\n\");\n   /* So the test is skipped: */\n   return SKIP;\n}\n#endif /* PNG_SIMPLIFIED_READ_SUPPORTED */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/libtests/pngunknown.c",
    "content": "\n/* pngunknown.c - test the read side unknown chunk handling\n *\n * Last changed in libpng 1.6.22 [(PENDING RELEASE)]\n * Copyright (c) 2015,2016 Glenn Randers-Pehrson\n * Written by John Cunningham Bowler\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * NOTES:\n *   This is a C program that is intended to be linked against libpng.  It\n *   allows the libpng unknown handling code to be tested by interpreting\n *   arguments to save or discard combinations of chunks.  The program is\n *   currently just a minimal validation for the built-in libpng facilities.\n */\n\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <setjmp.h>\n\n/* Define the following to use this test against your installed libpng, rather\n * than the one being built here:\n */\n#ifdef PNG_FREESTANDING_TESTS\n#  include <png.h>\n#else\n#  include \"../../png.h\"\n#endif\n\n/* 1.6.1 added support for the configure test harness, which uses 77 to indicate\n * a skipped test, in earlier versions we need to succeed on a skipped test, so:\n */\n#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)\n#  define SKIP 77\n#else\n#  define SKIP 0\n#endif\n\n\n/* Since this program tests the ability to change the unknown chunk handling\n * these must be defined:\n */\n#if defined(PNG_SET_UNKNOWN_CHUNKS_SUPPORTED) &&\\\n   defined(PNG_STDIO_SUPPORTED) &&\\\n   defined(PNG_READ_SUPPORTED)\n\n/* One of these must be defined to allow us to find out what happened.  It is\n * still useful to set unknown chunk handling without either of these in order\n * to cause *known* chunks to be discarded.  This can be a significant\n * efficiency gain, but it can't really be tested here.\n */\n#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) ||\\\n   defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED)\n\n#if PNG_LIBPNG_VER < 10500\n/* This deliberately lacks the PNG_CONST. */\ntypedef png_byte *png_const_bytep;\n\n/* This is copied from 1.5.1 png.h: */\n#define PNG_INTERLACE_ADAM7_PASSES 7\n#define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7)\n#define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7)\n#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)\n#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)\n#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\\\n   -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))\n#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\\\n   -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))\n#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \\\n   (((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))\n#define PNG_COL_FROM_PASS_COL(xIn, pass) \\\n   (((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))\n#define PNG_PASS_MASK(pass,off) ( \\\n   ((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \\\n   ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U))\n#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \\\n   ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)\n#define PNG_COL_IN_INTERLACE_PASS(x, pass) \\\n   ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)\n\n/* These are needed too for the default build: */\n#define PNG_WRITE_16BIT_SUPPORTED\n#define PNG_READ_16BIT_SUPPORTED\n\n/* This comes from pnglibconf.h afer 1.5: */\n#define PNG_FP_1 100000\n#define PNG_GAMMA_THRESHOLD_FIXED\\\n   ((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1))\n#endif\n\n#if PNG_LIBPNG_VER < 10600\n   /* 1.6.0 constifies many APIs. The following exists to allow pngvalid to be\n    * compiled against earlier versions.\n    */\n#  define png_const_structp png_structp\n#endif\n\n#if PNG_LIBPNG_VER < 10700\n   /* Copied from libpng 1.7.0 png.h */\n#define PNG_u2(b1, b2) (((unsigned int)(b1) << 8) + (b2))\n\n#define PNG_U16(b1, b2) ((png_uint_16)PNG_u2(b1, b2))\n#define PNG_U32(b1, b2, b3, b4)\\\n   (((png_uint_32)PNG_u2(b1, b2) << 16) + PNG_u2(b3, b4))\n\n/* Constants for known chunk types.\n */\n#define png_IDAT PNG_U32( 73,  68,  65,  84)\n#define png_IEND PNG_U32( 73,  69,  78,  68)\n#define png_IHDR PNG_U32( 73,  72,  68,  82)\n#define png_PLTE PNG_U32( 80,  76,  84,  69)\n#define png_bKGD PNG_U32( 98,  75,  71,  68)\n#define png_cHRM PNG_U32( 99,  72,  82,  77)\n#define png_fRAc PNG_U32(102,  82,  65,  99) /* registered, not defined */\n#define png_gAMA PNG_U32(103,  65,  77,  65)\n#define png_gIFg PNG_U32(103,  73,  70, 103)\n#define png_gIFt PNG_U32(103,  73,  70, 116) /* deprecated */\n#define png_gIFx PNG_U32(103,  73,  70, 120)\n#define png_hIST PNG_U32(104,  73,  83,  84)\n#define png_iCCP PNG_U32(105,  67,  67,  80)\n#define png_iTXt PNG_U32(105,  84,  88, 116)\n#define png_oFFs PNG_U32(111,  70,  70, 115)\n#define png_pCAL PNG_U32(112,  67,  65,  76)\n#define png_pHYs PNG_U32(112,  72,  89, 115)\n#define png_sBIT PNG_U32(115,  66,  73,  84)\n#define png_sCAL PNG_U32(115,  67,  65,  76)\n#define png_sPLT PNG_U32(115,  80,  76,  84)\n#define png_sRGB PNG_U32(115,  82,  71,  66)\n#define png_sTER PNG_U32(115,  84,  69,  82)\n#define png_tEXt PNG_U32(116,  69,  88, 116)\n#define png_tIME PNG_U32(116,  73,  77,  69)\n#define png_tRNS PNG_U32(116,  82,  78,  83)\n#define png_zTXt PNG_U32(122,  84,  88, 116)\n\n/* Test on flag values as defined in the spec (section 5.4): */\n#define PNG_CHUNK_ANCILLARY(c)    (1 & ((c) >> 29))\n#define PNG_CHUNK_CRITICAL(c)     (!PNG_CHUNK_ANCILLARY(c))\n#define PNG_CHUNK_PRIVATE(c)      (1 & ((c) >> 21))\n#define PNG_CHUNK_RESERVED(c)     (1 & ((c) >> 13))\n#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >>  5))\n\n#endif /* PNG_LIBPNG_VER < 10700 */\n\n#ifdef __cplusplus\n#  define this not_the_cpp_this\n#  define new not_the_cpp_new\n#  define voidcast(type, value) static_cast<type>(value)\n#else\n#  define voidcast(type, value) (value)\n#endif /* __cplusplus */\n\n/* Unused formal parameter errors are removed using the following macro which is\n * expected to have no bad effects on performance.\n */\n#ifndef UNUSED\n#  if defined(__GNUC__) || defined(_MSC_VER)\n#     define UNUSED(param) (void)param;\n#  else\n#     define UNUSED(param)\n#  endif\n#endif\n\n/* Types of chunks not known to libpng */\n#define png_vpAg PNG_U32(118, 112, 65, 103)\n\n/* Chunk information */\n#define PNG_INFO_tEXt 0x10000000U\n#define PNG_INFO_iTXt 0x20000000U\n#define PNG_INFO_zTXt 0x40000000U\n\n#define PNG_INFO_sTER 0x01000000U\n#define PNG_INFO_vpAg 0x02000000U\n\n#define ABSENT  0\n#define START   1\n#define END     2\n\nstatic struct\n{\n   char        name[5];\n   png_uint_32 flag;\n   png_uint_32 tag;\n   int         unknown;    /* Chunk not known to libpng */\n   int         all;        /* Chunk set by the '-1' option */\n   int         position;   /* position in pngtest.png */\n   int         keep;       /* unknown handling setting */\n} chunk_info[] = {\n   /* Critical chunks */\n   { \"IDAT\", PNG_INFO_IDAT, png_IDAT, 0, 0,  START, 0 }, /* must be [0] */\n   { \"PLTE\", PNG_INFO_PLTE, png_PLTE, 0, 0, ABSENT, 0 },\n\n   /* Non-critical chunks that libpng handles */\n   /* This is a mess but it seems to be the only way to do it - there is no way\n    * to check for a definition outside a #if.\n    */\n   { \"bKGD\", PNG_INFO_bKGD, png_bKGD,\n#     ifdef PNG_READ_bKGD_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1,  START, 0 },\n   { \"cHRM\", PNG_INFO_cHRM, png_cHRM,\n#     ifdef PNG_READ_cHRM_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1,  START, 0 },\n   { \"gAMA\", PNG_INFO_gAMA, png_gAMA,\n#     ifdef PNG_READ_gAMA_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1,  START, 0 },\n   { \"hIST\", PNG_INFO_hIST, png_hIST,\n#     ifdef PNG_READ_hIST_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1, ABSENT, 0 },\n   { \"iCCP\", PNG_INFO_iCCP, png_iCCP,\n#     ifdef PNG_READ_iCCP_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1, ABSENT, 0 },\n   { \"iTXt\", PNG_INFO_iTXt, png_iTXt,\n#     ifdef PNG_READ_iTXt_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1, ABSENT, 0 },\n   { \"oFFs\", PNG_INFO_oFFs, png_oFFs,\n#     ifdef PNG_READ_oFFs_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1,  START, 0 },\n   { \"pCAL\", PNG_INFO_pCAL, png_pCAL,\n#     ifdef PNG_READ_pCAL_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1,  START, 0 },\n   { \"pHYs\", PNG_INFO_pHYs, png_pHYs,\n#     ifdef PNG_READ_pHYs_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1,  START, 0 },\n   { \"sBIT\", PNG_INFO_sBIT, png_sBIT,\n#     ifdef PNG_READ_sBIT_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1,  START, 0 },\n   { \"sCAL\", PNG_INFO_sCAL, png_sCAL,\n#     ifdef PNG_READ_sCAL_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1,  START, 0 },\n   { \"sPLT\", PNG_INFO_sPLT, png_sPLT,\n#     ifdef PNG_READ_sPLT_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1, ABSENT, 0 },\n   { \"sRGB\", PNG_INFO_sRGB, png_sRGB,\n#     ifdef PNG_READ_sRGB_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1,  START, 0 },\n   { \"tEXt\", PNG_INFO_tEXt, png_tEXt,\n#     ifdef PNG_READ_tEXt_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1,  START, 0 },\n   { \"tIME\", PNG_INFO_tIME, png_tIME,\n#     ifdef PNG_READ_tIME_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1,  START, 0 },\n   { \"tRNS\", PNG_INFO_tRNS, png_tRNS,\n#     ifdef PNG_READ_tRNS_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      0, ABSENT, 0 },\n   { \"zTXt\", PNG_INFO_zTXt, png_zTXt,\n#     ifdef PNG_READ_zTXt_SUPPORTED\n         0,\n#     else\n         1,\n#     endif\n      1,    END, 0 },\n\n   /* No libpng handling */\n   { \"sTER\", PNG_INFO_sTER, png_sTER, 1, 1,  START, 0 },\n   { \"vpAg\", PNG_INFO_vpAg, png_vpAg, 1, 0,  START, 0 },\n};\n\n#define NINFO ((int)((sizeof chunk_info)/(sizeof chunk_info[0])))\n\nstatic void\nclear_keep(void)\n{\n   int i = NINFO;\n   while (--i >= 0)\n      chunk_info[i].keep = 0;\n}\n\nstatic int\nfind(const char *name)\n{\n   int i = NINFO;\n   while (--i >= 0)\n   {\n      if (memcmp(chunk_info[i].name, name, 4) == 0)\n         break;\n   }\n\n   return i;\n}\n\nstatic int\nfindb(const png_byte *name)\n{\n   int i = NINFO;\n   while (--i >= 0)\n   {\n      if (memcmp(chunk_info[i].name, name, 4) == 0)\n         break;\n   }\n\n   return i;\n}\n\nstatic int\nfind_by_flag(png_uint_32 flag)\n{\n   int i = NINFO;\n\n   while (--i >= 0) if (chunk_info[i].flag == flag) return i;\n\n   fprintf(stderr, \"pngunknown: internal error\\n\");\n   exit(4);\n}\n\nstatic int\nancillary(const char *name)\n{\n   return PNG_CHUNK_ANCILLARY(PNG_U32(name[0], name[1], name[2], name[3]));\n}\n\n#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED\nstatic int\nancillaryb(const png_byte *name)\n{\n   return PNG_CHUNK_ANCILLARY(PNG_U32(name[0], name[1], name[2], name[3]));\n}\n#endif\n\n/* Type of an error_ptr */\ntypedef struct\n{\n   jmp_buf     error_return;\n   png_structp png_ptr;\n   png_infop   info_ptr, end_ptr;\n   png_uint_32 before_IDAT;\n   png_uint_32 after_IDAT;\n   int         error_count;\n   int         warning_count;\n   int         keep; /* the default value */\n   const char *program;\n   const char *file;\n   const char *test;\n} display;\n\nstatic const char init[] = \"initialization\";\nstatic const char cmd[] = \"command line\";\n\nstatic void\ninit_display(display *d, const char *program)\n{\n   memset(d, 0, sizeof *d);\n   d->png_ptr = NULL;\n   d->info_ptr = d->end_ptr = NULL;\n   d->error_count = d->warning_count = 0;\n   d->program = program;\n   d->file = program;\n   d->test = init;\n}\n\nstatic void\nclean_display(display *d)\n{\n   png_destroy_read_struct(&d->png_ptr, &d->info_ptr, &d->end_ptr);\n\n   /* This must not happen - it might cause an app crash */\n   if (d->png_ptr != NULL || d->info_ptr != NULL || d->end_ptr != NULL)\n   {\n      fprintf(stderr, \"%s(%s): png_destroy_read_struct error\\n\", d->file,\n         d->test);\n      exit(1);\n   }\n}\n\nPNG_FUNCTION(void, display_exit, (display *d), static PNG_NORETURN)\n{\n   ++(d->error_count);\n\n   if (d->png_ptr != NULL)\n      clean_display(d);\n\n   /* During initialization and if this is a single command line argument set\n    * exit now - there is only one test, otherwise longjmp to do the next test.\n    */\n   if (d->test == init || d->test == cmd)\n      exit(1);\n\n   longjmp(d->error_return, 1);\n}\n\nstatic int\ndisplay_rc(const display *d, int strict)\n{\n   return d->error_count + (strict ? d->warning_count : 0);\n}\n\n/* libpng error and warning callbacks */\nPNG_FUNCTION(void, (PNGCBAPI error), (png_structp png_ptr, const char *message),\n   static PNG_NORETURN)\n{\n   display *d = (display*)png_get_error_ptr(png_ptr);\n\n   fprintf(stderr, \"%s(%s): libpng error: %s\\n\", d->file, d->test, message);\n   display_exit(d);\n}\n\nstatic void PNGCBAPI\nwarning(png_structp png_ptr, const char *message)\n{\n   display *d = (display*)png_get_error_ptr(png_ptr);\n\n   fprintf(stderr, \"%s(%s): libpng warning: %s\\n\", d->file, d->test, message);\n   ++(d->warning_count);\n}\n\nstatic png_uint_32\nget_valid(display *d, png_infop info_ptr)\n{\n   png_uint_32 flags = png_get_valid(d->png_ptr, info_ptr, (png_uint_32)~0);\n\n   /* Map the text chunks back into the flags */\n   {\n      png_textp text;\n      png_uint_32 ntext = png_get_text(d->png_ptr, info_ptr, &text, NULL);\n\n      while (ntext-- > 0) switch (text[ntext].compression)\n      {\n         case -1:\n            flags |= PNG_INFO_tEXt;\n            break;\n         case 0:\n            flags |= PNG_INFO_zTXt;\n            break;\n         case 1:\n         case 2:\n            flags |= PNG_INFO_iTXt;\n            break;\n         default:\n            fprintf(stderr, \"%s(%s): unknown text compression %d\\n\", d->file,\n               d->test, text[ntext].compression);\n            display_exit(d);\n      }\n   }\n\n   return flags;\n}\n\n#ifdef PNG_READ_USER_CHUNKS_SUPPORTED\nstatic int PNGCBAPI\nread_callback(png_structp pp, png_unknown_chunkp pc)\n{\n   /* This function mimics the behavior of png_set_keep_unknown_chunks by\n    * returning '0' to keep the chunk and '1' to discard it.\n    */\n   display *d = voidcast(display*, png_get_user_chunk_ptr(pp));\n   int chunk = findb(pc->name);\n   int keep, discard;\n\n   if (chunk < 0) /* not one in our list, so not a known chunk */\n      keep = d->keep;\n\n   else\n   {\n      keep = chunk_info[chunk].keep;\n      if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT)\n      {\n         /* See the comments in png.h - use the default for unknown chunks,\n          * do not keep known chunks.\n          */\n         if (chunk_info[chunk].unknown)\n            keep = d->keep;\n\n         else\n            keep = PNG_HANDLE_CHUNK_NEVER;\n      }\n   }\n\n   switch (keep)\n   {\n      default:\n         fprintf(stderr, \"%s(%s): %d: unrecognized chunk option\\n\", d->file,\n            d->test, chunk_info[chunk].keep);\n         display_exit(d);\n\n      case PNG_HANDLE_CHUNK_AS_DEFAULT:\n      case PNG_HANDLE_CHUNK_NEVER:\n         discard = 1/*handled; discard*/;\n         break;\n\n      case PNG_HANDLE_CHUNK_IF_SAFE:\n      case PNG_HANDLE_CHUNK_ALWAYS:\n         discard = 0/*not handled; keep*/;\n         break;\n   }\n\n   /* Also store information about this chunk in the display, the relevant flag\n    * is set if the chunk is to be kept ('not handled'.)\n    */\n   if (chunk >= 0) if (!discard) /* stupidity to stop a GCC warning */\n   {\n      png_uint_32 flag = chunk_info[chunk].flag;\n\n      if (pc->location & PNG_AFTER_IDAT)\n         d->after_IDAT |= flag;\n\n      else\n         d->before_IDAT |= flag;\n   }\n\n   /* However if there is no support to store unknown chunks don't ask libpng to\n    * do it; there will be an png_error.\n    */\n#  ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED\n      return discard;\n#  else\n      return 1; /*handled; discard*/\n#  endif\n}\n#endif /* READ_USER_CHUNKS_SUPPORTED */\n\n#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED\nstatic png_uint_32\nget_unknown(display *d, png_infop info_ptr, int after_IDAT)\n{\n   /* Create corresponding 'unknown' flags */\n   png_uint_32 flags = 0;\n\n   UNUSED(after_IDAT)\n\n   {\n      png_unknown_chunkp unknown;\n      int num_unknown = png_get_unknown_chunks(d->png_ptr, info_ptr, &unknown);\n\n      while (--num_unknown >= 0)\n      {\n         int chunk = findb(unknown[num_unknown].name);\n\n         /* Chunks not known to pngunknown must be validated here; since they\n          * must also be unknown to libpng the 'display->keep' behavior should\n          * have been used.\n          */\n         if (chunk < 0) switch (d->keep)\n         {\n            default: /* impossible */\n            case PNG_HANDLE_CHUNK_AS_DEFAULT:\n            case PNG_HANDLE_CHUNK_NEVER:\n               fprintf(stderr, \"%s(%s): %s: %s: unknown chunk saved\\n\",\n                  d->file, d->test, d->keep ? \"discard\" : \"default\",\n                  unknown[num_unknown].name);\n               ++(d->error_count);\n               break;\n\n            case PNG_HANDLE_CHUNK_IF_SAFE:\n               if (!ancillaryb(unknown[num_unknown].name))\n               {\n                  fprintf(stderr,\n                     \"%s(%s): if-safe: %s: unknown critical chunk saved\\n\",\n                     d->file, d->test, unknown[num_unknown].name);\n                  ++(d->error_count);\n                  break;\n               }\n               /* FALL THROUGH (safe) */\n            case PNG_HANDLE_CHUNK_ALWAYS:\n               break;\n         }\n\n         else\n            flags |= chunk_info[chunk].flag;\n      }\n   }\n\n   return flags;\n}\n#else /* SAVE_UNKNOWN_CHUNKS */\nstatic png_uint_32\nget_unknown(display *d, png_infop info_ptr, int after_IDAT)\n   /* Otherwise this will return the cached values set by any user callback */\n{\n   UNUSED(info_ptr);\n\n   if (after_IDAT)\n      return d->after_IDAT;\n\n   else\n      return d->before_IDAT;\n}\n\n#  ifndef PNG_READ_USER_CHUNKS_SUPPORTED\n      /* The #defines above should mean this is never reached, it's just here as\n       * a check to ensure the logic is correct.\n       */\n#     error No store support and no user chunk support, this will not work\n#  endif /* READ_USER_CHUNKS */\n#endif /* SAVE_UNKNOWN_CHUNKS */\n\nstatic int\ncheck(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/,\n   display *d, int set_callback)\n{\n   int i, npasses, ipass;\n   png_uint_32 height;\n\n   d->keep = PNG_HANDLE_CHUNK_AS_DEFAULT;\n   d->before_IDAT = 0;\n   d->after_IDAT = 0;\n\n   /* Some of these errors are permanently fatal and cause an exit here, others\n    * are per-test and cause an error return.\n    */\n   d->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, d, error,\n      warning);\n   if (d->png_ptr == NULL)\n   {\n      fprintf(stderr, \"%s(%s): could not allocate png struct\\n\", d->file,\n         d->test);\n      /* Terminate here, this error is not test specific. */\n      exit(1);\n   }\n\n   d->info_ptr = png_create_info_struct(d->png_ptr);\n   d->end_ptr = png_create_info_struct(d->png_ptr);\n   if (d->info_ptr == NULL || d->end_ptr == NULL)\n   {\n      fprintf(stderr, \"%s(%s): could not allocate png info\\n\", d->file,\n         d->test);\n      clean_display(d);\n      exit(1);\n   }\n\n   png_init_io(d->png_ptr, fp);\n\n#  ifdef PNG_READ_USER_CHUNKS_SUPPORTED\n      /* This is only done if requested by the caller; it interferes with the\n       * standard store/save mechanism.\n       */\n      if (set_callback)\n         png_set_read_user_chunk_fn(d->png_ptr, d, read_callback);\n#  else\n      UNUSED(set_callback)\n#  endif\n\n   /* Handle each argument in turn; multiple settings are possible for the same\n    * chunk and multiple calls will occur (the last one should override all\n    * preceding ones).\n    */\n   for (i=0; i<argc; ++i)\n   {\n      const char *equals = strchr(argv[i], '=');\n\n      if (equals != NULL)\n      {\n         int chunk, option;\n\n         if (strcmp(equals+1, \"default\") == 0)\n            option = PNG_HANDLE_CHUNK_AS_DEFAULT;\n         else if (strcmp(equals+1, \"discard\") == 0)\n            option = PNG_HANDLE_CHUNK_NEVER;\n         else if (strcmp(equals+1, \"if-safe\") == 0)\n            option = PNG_HANDLE_CHUNK_IF_SAFE;\n         else if (strcmp(equals+1, \"save\") == 0)\n            option = PNG_HANDLE_CHUNK_ALWAYS;\n         else\n         {\n            fprintf(stderr, \"%s(%s): %s: unrecognized chunk option\\n\", d->file,\n               d->test, argv[i]);\n            display_exit(d);\n         }\n\n         switch (equals - argv[i])\n         {\n            case 4: /* chunk name */\n               chunk = find(argv[i]);\n\n               if (chunk >= 0)\n               {\n                  /* These #if tests have the effect of skipping the arguments\n                   * if SAVE support is unavailable - we can't do a useful test\n                   * in this case, so we just check the arguments!  This could\n                   * be improved in the future by using the read callback.\n                   */\n#                 if PNG_LIBPNG_VER >= 10700 &&\\\n                     !defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED)\n                     if (option < PNG_HANDLE_CHUNK_IF_SAFE)\n#                 endif /* 1.7+ SAVE_UNKNOWN_CHUNKS */\n                  {\n                     png_byte name[5];\n\n                     memcpy(name, chunk_info[chunk].name, 5);\n                     png_set_keep_unknown_chunks(d->png_ptr, option, name, 1);\n                     chunk_info[chunk].keep = option;\n                  }\n                  continue;\n               }\n\n               break;\n\n            case 7: /* default */\n               if (memcmp(argv[i], \"default\", 7) == 0)\n               {\n#                 if PNG_LIBPNG_VER >= 10700 &&\\\n                     !defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED)\n                     if (option < PNG_HANDLE_CHUNK_IF_SAFE)\n#                 endif /* 1.7+ SAVE_UNKNOWN_CHUNKS */\n                     png_set_keep_unknown_chunks(d->png_ptr, option, NULL, 0);\n\n                  d->keep = option;\n                  continue;\n               }\n\n               break;\n\n            case 3: /* all */\n               if (memcmp(argv[i], \"all\", 3) == 0)\n               {\n#                 if PNG_LIBPNG_VER >= 10700 &&\\\n                     !defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED)\n                     if (option < PNG_HANDLE_CHUNK_IF_SAFE)\n#                 endif /* 1.7+ SAVE_UNKNOWN_CHUNKS */\n                     png_set_keep_unknown_chunks(d->png_ptr, option, NULL, -1);\n\n                  d->keep = option;\n\n                  for (chunk = 0; chunk < NINFO; ++chunk)\n                     if (chunk_info[chunk].all)\n                        chunk_info[chunk].keep = option;\n                  continue;\n               }\n\n               break;\n\n            default: /* some misplaced = */\n\n               break;\n         }\n      }\n\n      fprintf(stderr, \"%s(%s): %s: unrecognized chunk argument\\n\", d->file,\n         d->test, argv[i]);\n      display_exit(d);\n   }\n\n   png_read_info(d->png_ptr, d->info_ptr);\n\n   switch (png_get_interlace_type(d->png_ptr, d->info_ptr))\n   {\n      case PNG_INTERLACE_NONE:\n         npasses = 1;\n         break;\n\n      case PNG_INTERLACE_ADAM7:\n         npasses = PNG_INTERLACE_ADAM7_PASSES;\n         break;\n\n      default:\n         /* Hard error because it is not test specific */\n         fprintf(stderr, \"%s(%s): invalid interlace type\\n\", d->file, d->test);\n         clean_display(d);\n         exit(1);\n   }\n\n   /* Skip the image data, if IDAT is not being handled then don't do this\n    * because it will cause a CRC error.\n    */\n   if (chunk_info[0/*IDAT*/].keep == PNG_HANDLE_CHUNK_AS_DEFAULT)\n   {\n      png_start_read_image(d->png_ptr);\n      height = png_get_image_height(d->png_ptr, d->info_ptr);\n\n      if (npasses > 1)\n      {\n         png_uint_32 width = png_get_image_width(d->png_ptr, d->info_ptr);\n\n         for (ipass=0; ipass<npasses; ++ipass)\n         {\n            png_uint_32 wPass = PNG_PASS_COLS(width, ipass);\n\n            if (wPass > 0)\n            {\n               png_uint_32 y;\n\n               for (y=0; y<height; ++y) if (PNG_ROW_IN_INTERLACE_PASS(y, ipass))\n                  png_read_row(d->png_ptr, NULL, NULL);\n            }\n         }\n      } /* interlaced */\n\n      else /* not interlaced */\n      {\n         png_uint_32 y;\n\n         for (y=0; y<height; ++y)\n            png_read_row(d->png_ptr, NULL, NULL);\n      }\n   }\n\n   png_read_end(d->png_ptr, d->end_ptr);\n\n   flags[0] = get_valid(d, d->info_ptr);\n   flags[1] = get_unknown(d, d->info_ptr, 0/*before IDAT*/);\n\n   /* Only png_read_png sets PNG_INFO_IDAT! */\n   flags[chunk_info[0/*IDAT*/].keep != PNG_HANDLE_CHUNK_AS_DEFAULT] |=\n      PNG_INFO_IDAT;\n\n   flags[2] = get_valid(d, d->end_ptr);\n   flags[3] = get_unknown(d, d->end_ptr, 1/*after IDAT*/);\n\n   clean_display(d);\n\n   return d->keep;\n}\n\nstatic void\ncheck_error(display *d, png_uint_32 flags, const char *message)\n{\n   while (flags)\n   {\n      png_uint_32 flag = flags & -(png_int_32)flags;\n      int i = find_by_flag(flag);\n\n      fprintf(stderr, \"%s(%s): chunk %s: %s\\n\", d->file, d->test,\n         chunk_info[i].name, message);\n      ++(d->error_count);\n\n      flags &= ~flag;\n   }\n}\n\nstatic void\ncheck_handling(display *d, int def, png_uint_32 chunks, png_uint_32 known,\n   png_uint_32 unknown, const char *position, int set_callback)\n{\n   while (chunks)\n   {\n      png_uint_32 flag = chunks & -(png_int_32)chunks;\n      int i = find_by_flag(flag);\n      int keep = chunk_info[i].keep;\n      const char *type;\n      const char *errorx = NULL;\n\n      if (chunk_info[i].unknown)\n      {\n         if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT)\n         {\n            type = \"UNKNOWN (default)\";\n            keep = def;\n         }\n\n         else\n            type = \"UNKNOWN (specified)\";\n\n         if (flag & known)\n            errorx = \"chunk processed\";\n\n         else switch (keep)\n         {\n            case PNG_HANDLE_CHUNK_AS_DEFAULT:\n               if (flag & unknown)\n                  errorx = \"DEFAULT: unknown chunk saved\";\n               break;\n\n            case PNG_HANDLE_CHUNK_NEVER:\n               if (flag & unknown)\n                  errorx = \"DISCARD: unknown chunk saved\";\n               break;\n\n            case PNG_HANDLE_CHUNK_IF_SAFE:\n               if (ancillary(chunk_info[i].name))\n               {\n                  if (!(flag & unknown))\n                     errorx = \"IF-SAFE: unknown ancillary chunk lost\";\n               }\n\n               else if (flag & unknown)\n                  errorx = \"IF-SAFE: unknown critical chunk saved\";\n               break;\n\n            case PNG_HANDLE_CHUNK_ALWAYS:\n               if (!(flag & unknown))\n                  errorx = \"SAVE: unknown chunk lost\";\n               break;\n\n            default:\n               errorx = \"internal error: bad keep\";\n               break;\n         }\n      } /* unknown chunk */\n\n      else /* known chunk */\n      {\n         type = \"KNOWN\";\n\n         if (flag & known)\n         {\n            /* chunk was processed, it won't have been saved because that is\n             * caught below when checking for inconsistent processing.\n             */\n            if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT)\n               errorx = \"!DEFAULT: known chunk processed\";\n         }\n\n         else /* not processed */ switch (keep)\n         {\n            case PNG_HANDLE_CHUNK_AS_DEFAULT:\n               errorx = \"DEFAULT: known chunk not processed\";\n               break;\n\n            case PNG_HANDLE_CHUNK_NEVER:\n               if (flag & unknown)\n                  errorx = \"DISCARD: known chunk saved\";\n               break;\n\n            case PNG_HANDLE_CHUNK_IF_SAFE:\n               if (ancillary(chunk_info[i].name))\n               {\n                  if (!(flag & unknown))\n                     errorx = \"IF-SAFE: known ancillary chunk lost\";\n               }\n\n               else if (flag & unknown)\n                  errorx = \"IF-SAFE: known critical chunk saved\";\n               break;\n\n            case PNG_HANDLE_CHUNK_ALWAYS:\n               if (!(flag & unknown))\n                  errorx = \"SAVE: known chunk lost\";\n               break;\n\n            default:\n               errorx = \"internal error: bad keep (2)\";\n               break;\n         }\n      }\n\n      if (errorx != NULL)\n      {\n         ++(d->error_count);\n         fprintf(stderr, \"%s(%s%s): %s %s %s: %s\\n\", d->file, d->test,\n            set_callback ? \",callback\" : \"\",\n            type, chunk_info[i].name, position, errorx);\n      }\n\n      chunks &= ~flag;\n   }\n}\n\nstatic void\nperform_one_test(FILE *fp, int argc, const char **argv,\n   png_uint_32 *default_flags, display *d, int set_callback)\n{\n   int def;\n   png_uint_32 flags[2][4];\n\n   rewind(fp);\n   clear_keep();\n   memcpy(flags[0], default_flags, sizeof flags[0]);\n\n   def = check(fp, argc, argv, flags[1], d, set_callback);\n\n   /* If IDAT is being handled as unknown the image read is skipped and all the\n    * IDATs after the first end up in the end info struct, so in this case add\n    * IDAT to the list of unknowns.  (Do this after 'check' above sets the\n    * chunk_info 'keep' fields.)\n    *\n    * Note that the flag setting has to be in the 'known' field to avoid\n    * triggering the consistency check below and the flag must only be set if\n    * there are multiple IDATs, so if the check above did find an unknown IDAT\n    * after IDAT.\n    */\n   if (chunk_info[0/*IDAT*/].keep != PNG_HANDLE_CHUNK_AS_DEFAULT &&\n       (flags[1][3] & PNG_INFO_IDAT) != 0)\n      flags[0][2] |= PNG_INFO_IDAT;\n\n   /* Chunks should either be known or unknown, never both and this should apply\n    * whether the chunk is before or after the IDAT (actually, the app can\n    * probably change this by swapping the handling after the image, but this\n    * test does not do that.)\n    */\n   check_error(d, (flags[0][0]|flags[0][2]) & (flags[0][1]|flags[0][3]),\n      \"chunk handled inconsistently in count tests\");\n   check_error(d, (flags[1][0]|flags[1][2]) & (flags[1][1]|flags[1][3]),\n      \"chunk handled inconsistently in option tests\");\n\n   /* Now find out what happened to each chunk before and after the IDAT and\n    * determine if the behavior was correct.  First some basic sanity checks,\n    * any known chunk should be known in the original count, any unknown chunk\n    * should be either known or unknown in the original.\n    */\n   {\n      png_uint_32 test;\n\n      test = flags[1][0] & ~flags[0][0];\n      check_error(d, test, \"new known chunk before IDAT\");\n      test = flags[1][1] & ~(flags[0][0] | flags[0][1]);\n      check_error(d, test, \"new unknown chunk before IDAT\");\n      test = flags[1][2] & ~flags[0][2];\n      check_error(d, test, \"new known chunk after IDAT\");\n      test = flags[1][3] & ~(flags[0][2] | flags[0][3]);\n      check_error(d, test, \"new unknown chunk after IDAT\");\n   }\n\n   /* Now each chunk in the original list should have been handled according to\n    * the options set for that chunk, regardless of whether libpng knows about\n    * it or not.\n    */\n   check_handling(d, def, flags[0][0] | flags[0][1], flags[1][0], flags[1][1],\n      \"before IDAT\", set_callback);\n   check_handling(d, def, flags[0][2] | flags[0][3], flags[1][2], flags[1][3],\n      \"after IDAT\", set_callback);\n}\n\nstatic void\nperform_one_test_safe(FILE *fp, int argc, const char **argv,\n   png_uint_32 *default_flags, display *d, const char *test)\n{\n   if (setjmp(d->error_return) == 0)\n   {\n      d->test = test; /* allow use of d->error_return */\n#     ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED\n         perform_one_test(fp, argc, argv, default_flags, d, 0);\n#     endif\n#     ifdef PNG_READ_USER_CHUNKS_SUPPORTED\n         perform_one_test(fp, argc, argv, default_flags, d, 1);\n#     endif\n      d->test = init; /* prevent use of d->error_return */\n   }\n}\n\nstatic const char *standard_tests[] =\n{\n \"discard\", \"default=discard\", 0,\n \"save\", \"default=save\", 0,\n \"if-safe\", \"default=if-safe\", 0,\n \"vpAg\", \"vpAg=if-safe\", 0,\n \"sTER\", \"sTER=if-safe\", 0,\n \"IDAT\", \"default=discard\", \"IDAT=save\", 0,\n \"sAPI\", \"bKGD=save\", \"cHRM=save\", \"gAMA=save\", \"all=discard\", \"iCCP=save\",\n   \"sBIT=save\", \"sRGB=save\", 0,\n 0/*end*/\n};\n\nstatic PNG_NORETURN void\nusage(const char *program, const char *reason)\n{\n   fprintf(stderr, \"pngunknown: %s: usage:\\n %s [--strict] \"\n      \"--default|{(CHNK|default|all)=(default|discard|if-safe|save)} \"\n      \"testfile.png\\n\", reason, program);\n   exit(99);\n}\n\nint\nmain(int argc, const char **argv)\n{\n   FILE *fp;\n   png_uint_32 default_flags[4/*valid,unknown{before,after}*/];\n   int strict = 0, default_tests = 0;\n   const char *count_argv = \"default=save\";\n   const char *touch_file = NULL;\n   display d;\n\n   init_display(&d, argv[0]);\n\n   while (++argv, --argc > 0)\n   {\n      if (strcmp(*argv, \"--strict\") == 0)\n         strict = 1;\n\n      else if (strcmp(*argv, \"--default\") == 0)\n         default_tests = 1;\n\n      else if (strcmp(*argv, \"--touch\") == 0)\n      {\n         if (argc > 1)\n            touch_file = *++argv, --argc;\n\n         else\n            usage(d.program, \"--touch: missing file name\");\n      }\n\n      else\n         break;\n   }\n\n   /* A file name is required, but there should be no other arguments if\n    * --default was specified.\n    */\n   if (argc <= 0)\n      usage(d.program, \"missing test file\");\n\n   /* GCC BUG: if (default_tests && argc != 1) triggers some weird GCC argc\n    * optimization which causes warnings with -Wstrict-overflow!\n    */\n   else if (default_tests) if (argc != 1)\n      usage(d.program, \"extra arguments\");\n\n   /* The name of the test file is the last argument; remove it. */\n   d.file = argv[--argc];\n\n   fp = fopen(d.file, \"rb\");\n   if (fp == NULL)\n   {\n      perror(d.file);\n      exit(99);\n   }\n\n   /* First find all the chunks, known and unknown, in the test file, a failure\n    * here aborts the whole test.\n    *\n    * If 'save' is supported then the normal saving method should happen,\n    * otherwise if 'read' is supported then the read callback will do the\n    * same thing.  If both are supported the 'read' callback won't be\n    * instantiated by default.  If 'save' is *not* supported then a user\n    * callback is required even though we can call png_get_unknown_chunks.\n    */\n   if (check(fp, 1, &count_argv, default_flags, &d,\n#     ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED\n         0\n#     else\n         1\n#     endif\n      ) != PNG_HANDLE_CHUNK_ALWAYS)\n   {\n      fprintf(stderr, \"%s: %s: internal error\\n\", d.program, d.file);\n      exit(99);\n   }\n\n   /* Now find what the various supplied options cause to change: */\n   if (!default_tests)\n   {\n      d.test = cmd; /* acts as a flag to say exit, do not longjmp */\n#     ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED\n         perform_one_test(fp, argc, argv, default_flags, &d, 0);\n#     endif\n#     ifdef PNG_READ_USER_CHUNKS_SUPPORTED\n         perform_one_test(fp, argc, argv, default_flags, &d, 1);\n#     endif\n      d.test = init;\n   }\n\n   else\n   {\n      const char **test = standard_tests;\n\n      /* Set the exit_test pointer here so we can continue after a libpng error.\n       * NOTE: this leaks memory because the png_struct data from the failing\n       * test is never freed.\n       */\n      while (*test)\n      {\n         const char *this_test = *test++;\n         const char **next = test;\n         int count = display_rc(&d, strict), new_count;\n         const char *result;\n         int arg_count = 0;\n\n         while (*next) ++next, ++arg_count;\n\n         perform_one_test_safe(fp, arg_count, test, default_flags, &d,\n            this_test);\n\n         new_count = display_rc(&d, strict);\n\n         if (new_count == count)\n            result = \"PASS\";\n\n         else\n            result = \"FAIL\";\n\n         printf(\"%s: %s %s\\n\", result, d.program, this_test);\n\n         test = next+1;\n      }\n   }\n\n   fclose(fp);\n\n   if (display_rc(&d, strict) == 0)\n   {\n      /* Success, touch the success file if appropriate */\n      if (touch_file != NULL)\n      {\n         FILE *fsuccess = fopen(touch_file, \"wt\");\n\n         if (fsuccess != NULL)\n         {\n            int err = 0;\n            fprintf(fsuccess, \"PNG unknown tests succeeded\\n\");\n            fflush(fsuccess);\n            err = ferror(fsuccess);\n\n            if (fclose(fsuccess) || err)\n            {\n               fprintf(stderr, \"%s: write failed\\n\", touch_file);\n               exit(99);\n            }\n         }\n\n         else\n         {\n            fprintf(stderr, \"%s: open failed\\n\", touch_file);\n            exit(99);\n         }\n      }\n\n      return 0;\n   }\n\n   return 1;\n}\n\n#else /* !(READ_USER_CHUNKS || SAVE_UNKNOWN_CHUNKS) */\nint\nmain(void)\n{\n   fprintf(stderr,\n      \" test ignored: no support to find out about unknown chunks\\n\");\n   /* So the test is skipped: */\n   return SKIP;\n}\n#endif /* READ_USER_CHUNKS || SAVE_UNKNOWN_CHUNKS */\n\n#else /* !(SET_UNKNOWN_CHUNKS && READ) */\nint\nmain(void)\n{\n   fprintf(stderr,\n      \" test ignored: no support to modify unknown chunk handling\\n\");\n   /* So the test is skipped: */\n   return SKIP;\n}\n#endif /* SET_UNKNOWN_CHUNKS && READ*/\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/libtests/pngvalid.c",
    "content": "\n/* pngvalid.c - validate libpng by constructing then reading png files.\n *\n * Last changed in libpng 1.6.22 [(PENDING RELEASE)]\n * Copyright (c) 2014-2016 Glenn Randers-Pehrson\n * Written by John Cunningham Bowler\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * NOTES:\n *   This is a C program that is intended to be linked against libpng.  It\n *   generates bitmaps internally, stores them as PNG files (using the\n *   sequential write code) then reads them back (using the sequential\n *   read code) and validates that the result has the correct data.\n *\n *   The program can be modified and extended to test the correctness of\n *   transformations performed by libpng.\n */\n\n#define _POSIX_SOURCE 1\n#define _ISOC99_SOURCE 1 /* For floating point */\n#define _GNU_SOURCE 1 /* For the floating point exception extension */\n\n#include <signal.h>\n#include <stdio.h>\n\n#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)\n#  include <config.h>\n#endif\n\n#ifdef HAVE_FEENABLEEXCEPT /* from config.h, if included */\n#  include <fenv.h>\n#endif\n\n#ifndef FE_DIVBYZERO\n#  define FE_DIVBYZERO 0\n#endif\n#ifndef FE_INVALID\n#  define FE_INVALID 0\n#endif\n#ifndef FE_OVERFLOW\n#  define FE_OVERFLOW 0\n#endif\n\n/* Define the following to use this test against your installed libpng, rather\n * than the one being built here:\n */\n#ifdef PNG_FREESTANDING_TESTS\n#  include <png.h>\n#else\n#  include \"../../png.h\"\n#endif\n\n#ifdef PNG_ZLIB_HEADER\n#  include PNG_ZLIB_HEADER\n#else\n#  include <zlib.h>   /* For crc32 */\n#endif\n\n/* 1.6.1 added support for the configure test harness, which uses 77 to indicate\n * a skipped test, in earlier versions we need to succeed on a skipped test, so:\n */\n#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)\n#  define SKIP 77\n#else\n#  define SKIP 0\n#endif\n\n/* pngvalid requires write support and one of the fixed or floating point APIs.\n */\n#if defined(PNG_WRITE_SUPPORTED) &&\\\n   (defined(PNG_FIXED_POINT_SUPPORTED) || defined(PNG_FLOATING_POINT_SUPPORTED))\n\n#if PNG_LIBPNG_VER < 10500\n/* This deliberately lacks the const. */\ntypedef png_byte *png_const_bytep;\n\n/* This is copied from 1.5.1 png.h: */\n#define PNG_INTERLACE_ADAM7_PASSES 7\n#define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7)\n#define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7)\n#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)\n#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)\n#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\\\n   -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))\n#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\\\n   -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))\n#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \\\n   (((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))\n#define PNG_COL_FROM_PASS_COL(xIn, pass) \\\n   (((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))\n#define PNG_PASS_MASK(pass,off) ( \\\n   ((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \\\n   ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U))\n#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \\\n   ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)\n#define PNG_COL_IN_INTERLACE_PASS(x, pass) \\\n   ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)\n\n/* These are needed too for the default build: */\n#define PNG_WRITE_16BIT_SUPPORTED\n#define PNG_READ_16BIT_SUPPORTED\n\n/* This comes from pnglibconf.h afer 1.5: */\n#define PNG_FP_1 100000\n#define PNG_GAMMA_THRESHOLD_FIXED\\\n   ((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1))\n#endif\n\n#if PNG_LIBPNG_VER < 10600\n   /* 1.6.0 constifies many APIs, the following exists to allow pngvalid to be\n    * compiled against earlier versions.\n    */\n#  define png_const_structp png_structp\n#endif\n\n#ifndef RELEASE_BUILD\n   /* RELEASE_BUILD is true for releases and release candidates: */\n#  define RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC)\n#endif\n#if RELEASE_BUILD\n#   define debugonly(something)\n#else /* !RELEASE_BUILD */\n#   define debugonly(something) something\n#endif /* !RELEASE_BUILD */\n\n#include <float.h>  /* For floating point constants */\n#include <stdlib.h> /* For malloc */\n#include <string.h> /* For memcpy, memset */\n#include <math.h>   /* For floor */\n\n/* Unused formal parameter errors are removed using the following macro which is\n * expected to have no bad effects on performance.\n */\n#ifndef UNUSED\n#  if defined(__GNUC__) || defined(_MSC_VER)\n#     define UNUSED(param) (void)param;\n#  else\n#     define UNUSED(param)\n#  endif\n#endif\n\n/***************************** EXCEPTION HANDLING *****************************/\n#ifdef PNG_FREESTANDING_TESTS\n#  include <cexcept.h>\n#else\n#  include \"../visupng/cexcept.h\"\n#endif\n\n#ifdef __cplusplus\n#  define this not_the_cpp_this\n#  define new not_the_cpp_new\n#  define voidcast(type, value) static_cast<type>(value)\n#else\n#  define voidcast(type, value) (value)\n#endif /* __cplusplus */\n\nstruct png_store;\ndefine_exception_type(struct png_store*);\n\n/* The following are macros to reduce typing everywhere where the well known\n * name 'the_exception_context' must be defined.\n */\n#define anon_context(ps) struct exception_context *the_exception_context = \\\n   &(ps)->exception_context\n#define context(ps,fault) anon_context(ps); png_store *fault\n\n/* This macro returns the number of elements in an array as an (unsigned int),\n * it is necessary to avoid the inability of certain versions of GCC to use\n * the value of a compile-time constant when performing range checks.  It must\n * be passed an array name.\n */\n#define ARRAY_SIZE(a) ((unsigned int)((sizeof (a))/(sizeof (a)[0])))\n\n/* GCC BUG 66447 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66447) requires\n * some broken GCC versions to be fixed up to avoid invalid whining about auto\n * variables that are *not* changed within the scope of a setjmp being changed.\n *\n * Feel free to extend the list of broken versions.\n */\n#define is_gnu(major,minor)\\\n   (defined __GNUC__) && __GNUC__ == (major) && __GNUC_MINOR__ == (minor)\n#define is_gnu_patch(major,minor,patch)\\\n   is_gnu(major,minor) && __GNUC_PATCHLEVEL__ == 0\n/* For the moment just do it always; all versions of GCC seem to be broken: */\n#ifdef __GNUC__\n   const void * volatile make_volatile_for_gnu;\n#  define gnu_volatile(x) make_volatile_for_gnu = &x;\n#else /* !GNUC broken versions */\n#  define gnu_volatile(x)\n#endif /* !GNUC broken versions */\n\n/******************************* UTILITIES ************************************/\n/* Error handling is particularly problematic in production code - error\n * handlers often themselves have bugs which lead to programs that detect\n * minor errors crashing.  The following functions deal with one very\n * common class of errors in error handlers - attempting to format error or\n * warning messages into buffers that are too small.\n */\nstatic size_t safecat(char *buffer, size_t bufsize, size_t pos,\n   const char *cat)\n{\n   while (pos < bufsize && cat != NULL && *cat != 0)\n      buffer[pos++] = *cat++;\n\n   if (pos >= bufsize)\n      pos = bufsize-1;\n\n   buffer[pos] = 0;\n   return pos;\n}\n\nstatic size_t safecatn(char *buffer, size_t bufsize, size_t pos, int n)\n{\n   char number[64];\n   sprintf(number, \"%d\", n);\n   return safecat(buffer, bufsize, pos, number);\n}\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\nstatic size_t safecatd(char *buffer, size_t bufsize, size_t pos, double d,\n    int precision)\n{\n   char number[64];\n   sprintf(number, \"%.*f\", precision, d);\n   return safecat(buffer, bufsize, pos, number);\n}\n#endif\n\nstatic const char invalid[] = \"invalid\";\nstatic const char sep[] = \": \";\n\nstatic const char *colour_types[8] =\n{\n   \"grayscale\", invalid, \"truecolour\", \"indexed-colour\",\n   \"grayscale with alpha\", invalid, \"truecolour with alpha\", invalid\n};\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\n/* Convert a double precision value to fixed point. */\nstatic png_fixed_point\nfix(double d)\n{\n   d = floor(d * PNG_FP_1 + .5);\n   return (png_fixed_point)d;\n}\n#endif /* PNG_READ_SUPPORTED */\n\n/* Generate random bytes.  This uses a boring repeatable algorithm and it\n * is implemented here so that it gives the same set of numbers on every\n * architecture.  It's a linear congruential generator (Knuth or Sedgewick\n * \"Algorithms\") but it comes from the 'feedback taps' table in Horowitz and\n * Hill, \"The Art of Electronics\" (Pseudo-Random Bit Sequences and Noise\n * Generation.)\n */\nstatic void\nmake_random_bytes(png_uint_32* seed, void* pv, size_t size)\n{\n   png_uint_32 u0 = seed[0], u1 = seed[1];\n   png_bytep bytes = voidcast(png_bytep, pv);\n\n   /* There are thirty three bits, the next bit in the sequence is bit-33 XOR\n    * bit-20.  The top 1 bit is in u1, the bottom 32 are in u0.\n    */\n   size_t i;\n   for (i=0; i<size; ++i)\n   {\n      /* First generate 8 new bits then shift them in at the end. */\n      png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff;\n      u1 <<= 8;\n      u1 |= u0 >> 24;\n      u0 <<= 8;\n      u0 |= u;\n      *bytes++ = (png_byte)u;\n   }\n\n   seed[0] = u0;\n   seed[1] = u1;\n}\n\nstatic void\nmake_four_random_bytes(png_uint_32* seed, png_bytep bytes)\n{\n   make_random_bytes(seed, bytes, 4);\n}\n\n#if defined PNG_READ_SUPPORTED || defined PNG_WRITE_tRNS_SUPPORTED ||\\\n    defined PNG_WRITE_FILTER_SUPPORTED\nstatic void\nrandomize(void *pv, size_t size)\n{\n   static png_uint_32 random_seed[2] = {0x56789abc, 0xd};\n   make_random_bytes(random_seed, pv, size);\n}\n\n#define R8(this) randomize(&(this), sizeof (this))\n\nstatic void r16(png_uint_16p p16, size_t count)\n{\n   size_t i;\n\n   for (i=0; i<count; ++i)\n   {\n      unsigned char b2[2];\n      randomize(b2, sizeof b2);\n      *p16++ = png_get_uint_16(b2);\n   }\n}\n\n#define R16(this) r16(&(this), (sizeof (this))/(sizeof (png_uint_16)))\n#define R16_1(this) r16(&(this), (size_t) 1U)\n\n#if defined PNG_READ_RGB_TO_GRAY_SUPPORTED ||\\\n    defined PNG_READ_FILLER_SUPPORTED\nstatic void r32(png_uint_32p p32, size_t count)\n{\n   size_t i;\n\n   for (i=0; i<count; ++i)\n   {\n      unsigned char b4[4];\n      randomize(b4, sizeof b4);\n      *p32++ = png_get_uint_32(b4);\n   }\n}\n\n#define R32(this) r32(&(this), (sizeof (this))/(sizeof (png_uint_32)))\n#define R32_1(this) r32(&(this), (size_t) 1U)\n\n#endif /* READ_FILLER || READ_RGB_TO_GRAY */\n\n#endif /* READ || WRITE_tRNS || WRITE_FILTER */\n\n#if defined PNG_READ_TRANSFORMS_SUPPORTED ||\\\n    defined PNG_WRITE_FILTER_SUPPORTED\nstatic unsigned int\nrandom_mod(unsigned int max)\n{\n   png_uint_16 x;\n\n   R16_1(x);\n\n   return x % max; /* 0 .. max-1 */\n}\n#endif /* READ_TRANSFORMS || WRITE_FILTER */\n\n#if (defined PNG_READ_RGB_TO_GRAY_SUPPORTED) ||\\\n    (defined PNG_READ_FILLER_SUPPORTED)\nstatic int\nrandom_choice(void)\n{\n   unsigned char x;\n\n   R8(x);\n\n   return x & 1;\n}\n#endif /* READ_RGB_TO_GRAY || READ_FILLER */\n\n/* A numeric ID based on PNG file characteristics.  The 'do_interlace' field\n * simply records whether pngvalid did the interlace itself or whether it\n * was done by libpng.  Width and height must be less than 256.  'palette' is an\n * index of the palette to use for formats with a palette otherwise a boolean\n * indicating if a tRNS chunk was generated.\n */\n#define FILEID(col, depth, palette, interlace, width, height, do_interlace) \\\n   ((png_uint_32)((col) + ((depth)<<3) + ((palette)<<8) + ((interlace)<<13) + \\\n    (((do_interlace)!=0)<<15) + ((width)<<16) + ((height)<<24)))\n\n#define COL_FROM_ID(id) ((png_byte)((id)& 0x7U))\n#define DEPTH_FROM_ID(id) ((png_byte)(((id) >> 3) & 0x1fU))\n#define PALETTE_FROM_ID(id) (((id) >> 8) & 0x1f)\n#define INTERLACE_FROM_ID(id) ((png_byte)(((id) >> 13) & 0x3))\n#define DO_INTERLACE_FROM_ID(id) ((int)(((id)>>15) & 1))\n#define WIDTH_FROM_ID(id) (((id)>>16) & 0xff)\n#define HEIGHT_FROM_ID(id) (((id)>>24) & 0xff)\n\n/* Utility to construct a standard name for a standard image. */\nstatic size_t\nstandard_name(char *buffer, size_t bufsize, size_t pos, png_byte colour_type,\n    int bit_depth, unsigned int npalette, int interlace_type,\n    png_uint_32 w, png_uint_32 h, int do_interlace)\n{\n   pos = safecat(buffer, bufsize, pos, colour_types[colour_type]);\n   if (colour_type == 3) /* must have a palette */\n   {\n      pos = safecat(buffer, bufsize, pos, \"[\");\n      pos = safecatn(buffer, bufsize, pos, npalette);\n      pos = safecat(buffer, bufsize, pos, \"]\");\n   }\n\n   else if (npalette != 0)\n      pos = safecat(buffer, bufsize, pos, \"+tRNS\");\n\n   pos = safecat(buffer, bufsize, pos, \" \");\n   pos = safecatn(buffer, bufsize, pos, bit_depth);\n   pos = safecat(buffer, bufsize, pos, \" bit\");\n\n   if (interlace_type != PNG_INTERLACE_NONE)\n   {\n      pos = safecat(buffer, bufsize, pos, \" interlaced\");\n      if (do_interlace)\n         pos = safecat(buffer, bufsize, pos, \"(pngvalid)\");\n      else\n         pos = safecat(buffer, bufsize, pos, \"(libpng)\");\n   }\n\n   if (w > 0 || h > 0)\n   {\n      pos = safecat(buffer, bufsize, pos, \" \");\n      pos = safecatn(buffer, bufsize, pos, w);\n      pos = safecat(buffer, bufsize, pos, \"x\");\n      pos = safecatn(buffer, bufsize, pos, h);\n   }\n\n   return pos;\n}\n\nstatic size_t\nstandard_name_from_id(char *buffer, size_t bufsize, size_t pos, png_uint_32 id)\n{\n   return standard_name(buffer, bufsize, pos, COL_FROM_ID(id),\n      DEPTH_FROM_ID(id), PALETTE_FROM_ID(id), INTERLACE_FROM_ID(id),\n      WIDTH_FROM_ID(id), HEIGHT_FROM_ID(id), DO_INTERLACE_FROM_ID(id));\n}\n\n/* Convenience API and defines to list valid formats.  Note that 16 bit read and\n * write support is required to do 16 bit read tests (we must be able to make a\n * 16 bit image to test!)\n */\n#ifdef PNG_WRITE_16BIT_SUPPORTED\n#  define WRITE_BDHI 4\n#  ifdef PNG_READ_16BIT_SUPPORTED\n#     define READ_BDHI 4\n#     define DO_16BIT\n#  endif\n#else\n#  define WRITE_BDHI 3\n#endif\n#ifndef DO_16BIT\n#  define READ_BDHI 3\n#endif\n\n/* The following defines the number of different palettes to generate for\n * each log bit depth of a colour type 3 standard image.\n */\n#define PALETTE_COUNT(bit_depth) ((bit_depth) > 4 ? 1U : 16U)\n\nstatic int\nnext_format(png_bytep colour_type, png_bytep bit_depth,\n   unsigned int* palette_number, int low_depth_gray, int tRNS)\n{\n   if (*bit_depth == 0)\n   {\n      *colour_type = 0;\n      if (low_depth_gray)\n         *bit_depth = 1;\n      else\n         *bit_depth = 8;\n      *palette_number = 0;\n      return 1;\n   }\n\n   if  (*colour_type < 4/*no alpha channel*/)\n   {\n      /* Add multiple palettes for colour type 3, one image with tRNS\n       * and one without for other non-alpha formats:\n       */\n      unsigned int pn = ++*palette_number;\n      png_byte ct = *colour_type;\n\n      if (((ct == 0/*GRAY*/ || ct/*RGB*/ == 2) && tRNS && pn < 2) ||\n          (ct == 3/*PALETTE*/ && pn < PALETTE_COUNT(*bit_depth)))\n         return 1;\n\n      /* No: next bit depth */\n      *palette_number = 0;\n   }\n\n   *bit_depth = (png_byte)(*bit_depth << 1);\n\n   /* Palette images are restricted to 8 bit depth */\n   if (*bit_depth <= 8\n#ifdef DO_16BIT\n         || (*colour_type != 3 && *bit_depth <= 16)\n#endif\n      )\n      return 1;\n\n   /* Move to the next color type, or return 0 at the end. */\n   switch (*colour_type)\n   {\n      case 0:\n         *colour_type = 2;\n         *bit_depth = 8;\n         return 1;\n\n      case 2:\n         *colour_type = 3;\n         *bit_depth = 1;\n         return 1;\n\n      case 3:\n         *colour_type = 4;\n         *bit_depth = 8;\n         return 1;\n\n      case 4:\n         *colour_type = 6;\n         *bit_depth = 8;\n         return 1;\n\n      default:\n         return 0;\n   }\n}\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\nstatic unsigned int\nsample(png_const_bytep row, png_byte colour_type, png_byte bit_depth,\n    png_uint_32 x, unsigned int sample_index, int swap16, int littleendian)\n{\n   png_uint_32 bit_index, result;\n\n   /* Find a sample index for the desired sample: */\n   x *= bit_depth;\n   bit_index = x;\n\n   if ((colour_type & 1) == 0) /* !palette */\n   {\n      if (colour_type & 2)\n         bit_index *= 3;\n\n      if (colour_type & 4)\n         bit_index += x; /* Alpha channel */\n\n      /* Multiple channels; select one: */\n      if (colour_type & (2+4))\n         bit_index += sample_index * bit_depth;\n   }\n\n   /* Return the sample from the row as an integer. */\n   row += bit_index >> 3;\n   result = *row;\n\n   if (bit_depth == 8)\n      return result;\n\n   else if (bit_depth > 8)\n   {\n      if (swap16)\n         return (*++row << 8) + result;\n      else\n         return (result << 8) + *++row;\n   }\n\n   /* Less than 8 bits per sample.  By default PNG has the big end of\n    * the egg on the left of the screen, but if littleendian is set\n    * then the big end is on the right.\n    */\n   bit_index &= 7;\n\n   if (!littleendian)\n      bit_index = 8-bit_index-bit_depth;\n\n   return (result >> bit_index) & ((1U<<bit_depth)-1);\n}\n#endif /* PNG_READ_TRANSFORMS_SUPPORTED */\n\n/* Copy a single pixel, of a given size, from one buffer to another -\n * while this is basically bit addressed there is an implicit assumption\n * that pixels 8 or more bits in size are byte aligned and that pixels\n * do not otherwise cross byte boundaries.  (This is, so far as I know,\n * universally true in bitmap computer graphics.  [JCB 20101212])\n *\n * NOTE: The to and from buffers may be the same.\n */\nstatic void\npixel_copy(png_bytep toBuffer, png_uint_32 toIndex,\n   png_const_bytep fromBuffer, png_uint_32 fromIndex, unsigned int pixelSize,\n   int littleendian)\n{\n   /* Assume we can multiply by 'size' without overflow because we are\n    * just working in a single buffer.\n    */\n   toIndex *= pixelSize;\n   fromIndex *= pixelSize;\n   if (pixelSize < 8) /* Sub-byte */\n   {\n      /* Mask to select the location of the copied pixel: */\n      unsigned int destMask = ((1U<<pixelSize)-1) <<\n         (littleendian ? toIndex&7 : 8-pixelSize-(toIndex&7));\n      /* The following read the entire pixels and clears the extra: */\n      unsigned int destByte = toBuffer[toIndex >> 3] & ~destMask;\n      unsigned int sourceByte = fromBuffer[fromIndex >> 3];\n\n      /* Don't rely on << or >> supporting '0' here, just in case: */\n      fromIndex &= 7;\n      if (littleendian)\n      {\n         if (fromIndex > 0) sourceByte >>= fromIndex;\n         if ((toIndex & 7) > 0) sourceByte <<= toIndex & 7;\n      }\n\n      else\n      {\n         if (fromIndex > 0) sourceByte <<= fromIndex;\n         if ((toIndex & 7) > 0) sourceByte >>= toIndex & 7;\n      }\n\n      toBuffer[toIndex >> 3] = (png_byte)(destByte | (sourceByte & destMask));\n   }\n   else /* One or more bytes */\n      memmove(toBuffer+(toIndex>>3), fromBuffer+(fromIndex>>3), pixelSize>>3);\n}\n\n#ifdef PNG_READ_SUPPORTED\n/* Copy a complete row of pixels, taking into account potential partial\n * bytes at the end.\n */\nstatic void\nrow_copy(png_bytep toBuffer, png_const_bytep fromBuffer, unsigned int bitWidth,\n      int littleendian)\n{\n   memcpy(toBuffer, fromBuffer, bitWidth >> 3);\n\n   if ((bitWidth & 7) != 0)\n   {\n      unsigned int mask;\n\n      toBuffer += bitWidth >> 3;\n      fromBuffer += bitWidth >> 3;\n      if (littleendian)\n         mask = 0xff << (bitWidth & 7);\n      else\n         mask = 0xff >> (bitWidth & 7);\n      *toBuffer = (png_byte)((*toBuffer & mask) | (*fromBuffer & ~mask));\n   }\n}\n\n/* Compare pixels - they are assumed to start at the first byte in the\n * given buffers.\n */\nstatic int\npixel_cmp(png_const_bytep pa, png_const_bytep pb, png_uint_32 bit_width)\n{\n#if PNG_LIBPNG_VER < 10506\n   if (memcmp(pa, pb, bit_width>>3) == 0)\n   {\n      png_uint_32 p;\n\n      if ((bit_width & 7) == 0) return 0;\n\n      /* Ok, any differences? */\n      p = pa[bit_width >> 3];\n      p ^= pb[bit_width >> 3];\n\n      if (p == 0) return 0;\n\n      /* There are, but they may not be significant, remove the bits\n       * after the end (the low order bits in PNG.)\n       */\n      bit_width &= 7;\n      p >>= 8-bit_width;\n\n      if (p == 0) return 0;\n   }\n#else\n   /* From libpng-1.5.6 the overwrite should be fixed, so compare the trailing\n    * bits too:\n    */\n   if (memcmp(pa, pb, (bit_width+7)>>3) == 0)\n      return 0;\n#endif\n\n   /* Return the index of the changed byte. */\n   {\n      png_uint_32 where = 0;\n\n      while (pa[where] == pb[where]) ++where;\n      return 1+where;\n   }\n}\n#endif /* PNG_READ_SUPPORTED */\n\n/*************************** BASIC PNG FILE WRITING ***************************/\n/* A png_store takes data from the sequential writer or provides data\n * to the sequential reader.  It can also store the result of a PNG\n * write for later retrieval.\n */\n#define STORE_BUFFER_SIZE 500 /* arbitrary */\ntypedef struct png_store_buffer\n{\n   struct png_store_buffer*  prev;    /* NOTE: stored in reverse order */\n   png_byte                  buffer[STORE_BUFFER_SIZE];\n} png_store_buffer;\n\n#define FILE_NAME_SIZE 64\n\ntypedef struct store_palette_entry /* record of a single palette entry */\n{\n   png_byte red;\n   png_byte green;\n   png_byte blue;\n   png_byte alpha;\n} store_palette_entry, store_palette[256];\n\ntypedef struct png_store_file\n{\n   struct png_store_file*  next;      /* as many as you like... */\n   char                    name[FILE_NAME_SIZE];\n   png_uint_32             id;        /* must be correct (see FILEID) */\n   png_size_t              datacount; /* In this (the last) buffer */\n   png_store_buffer        data;      /* Last buffer in file */\n   int                     npalette;  /* Number of entries in palette */\n   store_palette_entry*    palette;   /* May be NULL */\n} png_store_file;\n\n/* The following is a pool of memory allocated by a single libpng read or write\n * operation.\n */\ntypedef struct store_pool\n{\n   struct png_store    *store;   /* Back pointer */\n   struct store_memory *list;    /* List of allocated memory */\n   png_byte             mark[4]; /* Before and after data */\n\n   /* Statistics for this run. */\n   png_alloc_size_t     max;     /* Maximum single allocation */\n   png_alloc_size_t     current; /* Current allocation */\n   png_alloc_size_t     limit;   /* Highest current allocation */\n   png_alloc_size_t     total;   /* Total allocation */\n\n   /* Overall statistics (retained across successive runs). */\n   png_alloc_size_t     max_max;\n   png_alloc_size_t     max_limit;\n   png_alloc_size_t     max_total;\n} store_pool;\n\ntypedef struct png_store\n{\n   /* For cexcept.h exception handling - simply store one of these;\n    * the context is a self pointer but it may point to a different\n    * png_store (in fact it never does in this program.)\n    */\n   struct exception_context\n                      exception_context;\n\n   unsigned int       verbose :1;\n   unsigned int       treat_warnings_as_errors :1;\n   unsigned int       expect_error :1;\n   unsigned int       expect_warning :1;\n   unsigned int       saw_warning :1;\n   unsigned int       speed :1;\n   unsigned int       progressive :1; /* use progressive read */\n   unsigned int       validated :1;   /* used as a temporary flag */\n   int                nerrors;\n   int                nwarnings;\n   int                noptions;       /* number of options below: */\n   struct {\n      unsigned char   option;         /* option number, 0..30 */\n      unsigned char   setting;        /* setting (unset,invalid,on,off) */\n   }                  options[16];\n   char               test[128];      /* Name of test */\n   char               error[256];\n\n   /* Read fields */\n   png_structp        pread;    /* Used to read a saved file */\n   png_infop          piread;\n   png_store_file*    current;  /* Set when reading */\n   png_store_buffer*  next;     /* Set when reading */\n   png_size_t         readpos;  /* Position in *next */\n   png_byte*          image;    /* Buffer for reading interlaced images */\n   png_size_t         cb_image; /* Size of this buffer */\n   png_size_t         cb_row;   /* Row size of the image(s) */\n   png_uint_32        image_h;  /* Number of rows in a single image */\n   store_pool         read_memory_pool;\n\n   /* Write fields */\n   png_store_file*    saved;\n   png_structp        pwrite;   /* Used when writing a new file */\n   png_infop          piwrite;\n   png_size_t         writepos; /* Position in .new */\n   char               wname[FILE_NAME_SIZE];\n   png_store_buffer   new;      /* The end of the new PNG file being written. */\n   store_pool         write_memory_pool;\n   store_palette_entry* palette;\n   int                  npalette;\n} png_store;\n\n/* Initialization and cleanup */\nstatic void\nstore_pool_mark(png_bytep mark)\n{\n   static png_uint_32 store_seed[2] = { 0x12345678, 1};\n\n   make_four_random_bytes(store_seed, mark);\n}\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\n/* Use this for random 32 bit values; this function makes sure the result is\n * non-zero.\n */\nstatic png_uint_32\nrandom_32(void)\n{\n\n   for (;;)\n   {\n      png_byte mark[4];\n      png_uint_32 result;\n\n      store_pool_mark(mark);\n      result = png_get_uint_32(mark);\n\n      if (result != 0)\n         return result;\n   }\n}\n#endif /* PNG_READ_SUPPORTED */\n\nstatic void\nstore_pool_init(png_store *ps, store_pool *pool)\n{\n   memset(pool, 0, sizeof *pool);\n\n   pool->store = ps;\n   pool->list = NULL;\n   pool->max = pool->current = pool->limit = pool->total = 0;\n   pool->max_max = pool->max_limit = pool->max_total = 0;\n   store_pool_mark(pool->mark);\n}\n\nstatic void\nstore_init(png_store* ps)\n{\n   memset(ps, 0, sizeof *ps);\n   init_exception_context(&ps->exception_context);\n   store_pool_init(ps, &ps->read_memory_pool);\n   store_pool_init(ps, &ps->write_memory_pool);\n   ps->verbose = 0;\n   ps->treat_warnings_as_errors = 0;\n   ps->expect_error = 0;\n   ps->expect_warning = 0;\n   ps->saw_warning = 0;\n   ps->speed = 0;\n   ps->progressive = 0;\n   ps->validated = 0;\n   ps->nerrors = ps->nwarnings = 0;\n   ps->pread = NULL;\n   ps->piread = NULL;\n   ps->saved = ps->current = NULL;\n   ps->next = NULL;\n   ps->readpos = 0;\n   ps->image = NULL;\n   ps->cb_image = 0;\n   ps->cb_row = 0;\n   ps->image_h = 0;\n   ps->pwrite = NULL;\n   ps->piwrite = NULL;\n   ps->writepos = 0;\n   ps->new.prev = NULL;\n   ps->palette = NULL;\n   ps->npalette = 0;\n   ps->noptions = 0;\n}\n\nstatic void\nstore_freebuffer(png_store_buffer* psb)\n{\n   if (psb->prev)\n   {\n      store_freebuffer(psb->prev);\n      free(psb->prev);\n      psb->prev = NULL;\n   }\n}\n\nstatic void\nstore_freenew(png_store *ps)\n{\n   store_freebuffer(&ps->new);\n   ps->writepos = 0;\n   if (ps->palette != NULL)\n   {\n      free(ps->palette);\n      ps->palette = NULL;\n      ps->npalette = 0;\n   }\n}\n\nstatic void\nstore_storenew(png_store *ps)\n{\n   png_store_buffer *pb;\n\n   if (ps->writepos != STORE_BUFFER_SIZE)\n      png_error(ps->pwrite, \"invalid store call\");\n\n   pb = voidcast(png_store_buffer*, malloc(sizeof *pb));\n\n   if (pb == NULL)\n      png_error(ps->pwrite, \"store new: OOM\");\n\n   *pb = ps->new;\n   ps->new.prev = pb;\n   ps->writepos = 0;\n}\n\nstatic void\nstore_freefile(png_store_file **ppf)\n{\n   if (*ppf != NULL)\n   {\n      store_freefile(&(*ppf)->next);\n\n      store_freebuffer(&(*ppf)->data);\n      (*ppf)->datacount = 0;\n      if ((*ppf)->palette != NULL)\n      {\n         free((*ppf)->palette);\n         (*ppf)->palette = NULL;\n         (*ppf)->npalette = 0;\n      }\n      free(*ppf);\n      *ppf = NULL;\n   }\n}\n\n/* Main interface to file storeage, after writing a new PNG file (see the API\n * below) call store_storefile to store the result with the given name and id.\n */\nstatic void\nstore_storefile(png_store *ps, png_uint_32 id)\n{\n   png_store_file *pf = voidcast(png_store_file*, malloc(sizeof *pf));\n   if (pf == NULL)\n      png_error(ps->pwrite, \"storefile: OOM\");\n   safecat(pf->name, sizeof pf->name, 0, ps->wname);\n   pf->id = id;\n   pf->data = ps->new;\n   pf->datacount = ps->writepos;\n   ps->new.prev = NULL;\n   ps->writepos = 0;\n   pf->palette = ps->palette;\n   pf->npalette = ps->npalette;\n   ps->palette = 0;\n   ps->npalette = 0;\n\n   /* And save it. */\n   pf->next = ps->saved;\n   ps->saved = pf;\n}\n\n/* Generate an error message (in the given buffer) */\nstatic size_t\nstore_message(png_store *ps, png_const_structp pp, char *buffer, size_t bufsize,\n   size_t pos, const char *msg)\n{\n   if (pp != NULL && pp == ps->pread)\n   {\n      /* Reading a file */\n      pos = safecat(buffer, bufsize, pos, \"read: \");\n\n      if (ps->current != NULL)\n      {\n         pos = safecat(buffer, bufsize, pos, ps->current->name);\n         pos = safecat(buffer, bufsize, pos, sep);\n      }\n   }\n\n   else if (pp != NULL && pp == ps->pwrite)\n   {\n      /* Writing a file */\n      pos = safecat(buffer, bufsize, pos, \"write: \");\n      pos = safecat(buffer, bufsize, pos, ps->wname);\n      pos = safecat(buffer, bufsize, pos, sep);\n   }\n\n   else\n   {\n      /* Neither reading nor writing (or a memory error in struct delete) */\n      pos = safecat(buffer, bufsize, pos, \"pngvalid: \");\n   }\n\n   if (ps->test[0] != 0)\n   {\n      pos = safecat(buffer, bufsize, pos, ps->test);\n      pos = safecat(buffer, bufsize, pos, sep);\n   }\n   pos = safecat(buffer, bufsize, pos, msg);\n   return pos;\n}\n\n/* Verbose output to the error stream: */\nstatic void\nstore_verbose(png_store *ps, png_const_structp pp, png_const_charp prefix,\n   png_const_charp message)\n{\n   char buffer[512];\n\n   if (prefix)\n      fputs(prefix, stderr);\n\n   (void)store_message(ps, pp, buffer, sizeof buffer, 0, message);\n   fputs(buffer, stderr);\n   fputc('\\n', stderr);\n}\n\n/* Log an error or warning - the relevant count is always incremented. */\nstatic void\nstore_log(png_store* ps, png_const_structp pp, png_const_charp message,\n   int is_error)\n{\n   /* The warning is copied to the error buffer if there are no errors and it is\n    * the first warning.  The error is copied to the error buffer if it is the\n    * first error (overwriting any prior warnings).\n    */\n   if (is_error ? (ps->nerrors)++ == 0 :\n       (ps->nwarnings)++ == 0 && ps->nerrors == 0)\n      store_message(ps, pp, ps->error, sizeof ps->error, 0, message);\n\n   if (ps->verbose)\n      store_verbose(ps, pp, is_error ? \"error: \" : \"warning: \", message);\n}\n\n#ifdef PNG_READ_SUPPORTED\n/* Internal error function, called with a png_store but no libpng stuff. */\nstatic void\ninternal_error(png_store *ps, png_const_charp message)\n{\n   store_log(ps, NULL, message, 1 /* error */);\n\n   /* And finally throw an exception. */\n   {\n      struct exception_context *the_exception_context = &ps->exception_context;\n      Throw ps;\n   }\n}\n#endif /* PNG_READ_SUPPORTED */\n\n/* Functions to use as PNG callbacks. */\nstatic void PNGCBAPI\nstore_error(png_structp ppIn, png_const_charp message) /* PNG_NORETURN */\n{\n   png_const_structp pp = ppIn;\n   png_store *ps = voidcast(png_store*, png_get_error_ptr(pp));\n\n   if (!ps->expect_error)\n      store_log(ps, pp, message, 1 /* error */);\n\n   /* And finally throw an exception. */\n   {\n      struct exception_context *the_exception_context = &ps->exception_context;\n      Throw ps;\n   }\n}\n\nstatic void PNGCBAPI\nstore_warning(png_structp ppIn, png_const_charp message)\n{\n   png_const_structp pp = ppIn;\n   png_store *ps = voidcast(png_store*, png_get_error_ptr(pp));\n\n   if (!ps->expect_warning)\n      store_log(ps, pp, message, 0 /* warning */);\n   else\n      ps->saw_warning = 1;\n}\n\n/* These somewhat odd functions are used when reading an image to ensure that\n * the buffer is big enough, the png_structp is for errors.\n */\n/* Return a single row from the correct image. */\nstatic png_bytep\nstore_image_row(const png_store* ps, png_const_structp pp, int nImage,\n   png_uint_32 y)\n{\n   png_size_t coffset = (nImage * ps->image_h + y) * (ps->cb_row + 5) + 2;\n\n   if (ps->image == NULL)\n      png_error(pp, \"no allocated image\");\n\n   if (coffset + ps->cb_row + 3 > ps->cb_image)\n      png_error(pp, \"image too small\");\n\n   return ps->image + coffset;\n}\n\nstatic void\nstore_image_free(png_store *ps, png_const_structp pp)\n{\n   if (ps->image != NULL)\n   {\n      png_bytep image = ps->image;\n\n      if (image[-1] != 0xed || image[ps->cb_image] != 0xfe)\n      {\n         if (pp != NULL)\n            png_error(pp, \"png_store image overwrite (1)\");\n         else\n            store_log(ps, NULL, \"png_store image overwrite (2)\", 1);\n      }\n\n      ps->image = NULL;\n      ps->cb_image = 0;\n      --image;\n      free(image);\n   }\n}\n\nstatic void\nstore_ensure_image(png_store *ps, png_const_structp pp, int nImages,\n   png_size_t cbRow, png_uint_32 cRows)\n{\n   png_size_t cb = nImages * cRows * (cbRow + 5);\n\n   if (ps->cb_image < cb)\n   {\n      png_bytep image;\n\n      store_image_free(ps, pp);\n\n      /* The buffer is deliberately mis-aligned. */\n      image = voidcast(png_bytep, malloc(cb+2));\n      if (image == NULL)\n      {\n         /* Called from the startup - ignore the error for the moment. */\n         if (pp == NULL)\n            return;\n\n         png_error(pp, \"OOM allocating image buffer\");\n      }\n\n      /* These magic tags are used to detect overwrites above. */\n      ++image;\n      image[-1] = 0xed;\n      image[cb] = 0xfe;\n\n      ps->image = image;\n      ps->cb_image = cb;\n   }\n\n   /* We have an adequate sized image; lay out the rows.  There are 2 bytes at\n    * the start and three at the end of each (this ensures that the row\n    * alignment starts out odd - 2+1 and changes for larger images on each row.)\n    */\n   ps->cb_row = cbRow;\n   ps->image_h = cRows;\n\n   /* For error checking, the whole buffer is set to 10110010 (0xb2 - 178).\n    * This deliberately doesn't match the bits in the size test image which are\n    * outside the image; these are set to 0xff (all 1).  To make the row\n    * comparison work in the 'size' test case the size rows are pre-initialized\n    * to the same value prior to calling 'standard_row'.\n    */\n   memset(ps->image, 178, cb);\n\n   /* Then put in the marks. */\n   while (--nImages >= 0)\n   {\n      png_uint_32 y;\n\n      for (y=0; y<cRows; ++y)\n      {\n         png_bytep row = store_image_row(ps, pp, nImages, y);\n\n         /* The markers: */\n         row[-2] = 190;\n         row[-1] = 239;\n         row[cbRow] = 222;\n         row[cbRow+1] = 173;\n         row[cbRow+2] = 17;\n      }\n   }\n}\n\n#ifdef PNG_READ_SUPPORTED\nstatic void\nstore_image_check(const png_store* ps, png_const_structp pp, int iImage)\n{\n   png_const_bytep image = ps->image;\n\n   if (image[-1] != 0xed || image[ps->cb_image] != 0xfe)\n      png_error(pp, \"image overwrite\");\n   else\n   {\n      png_size_t cbRow = ps->cb_row;\n      png_uint_32 rows = ps->image_h;\n\n      image += iImage * (cbRow+5) * ps->image_h;\n\n      image += 2; /* skip image first row markers */\n\n      while (rows-- > 0)\n      {\n         if (image[-2] != 190 || image[-1] != 239)\n            png_error(pp, \"row start overwritten\");\n\n         if (image[cbRow] != 222 || image[cbRow+1] != 173 ||\n            image[cbRow+2] != 17)\n            png_error(pp, \"row end overwritten\");\n\n         image += cbRow+5;\n      }\n   }\n}\n#endif /* PNG_READ_SUPPORTED */\n\nstatic void PNGCBAPI\nstore_write(png_structp ppIn, png_bytep pb, png_size_t st)\n{\n   png_const_structp pp = ppIn;\n   png_store *ps = voidcast(png_store*, png_get_io_ptr(pp));\n\n   if (ps->pwrite != pp)\n      png_error(pp, \"store state damaged\");\n\n   while (st > 0)\n   {\n      size_t cb;\n\n      if (ps->writepos >= STORE_BUFFER_SIZE)\n         store_storenew(ps);\n\n      cb = st;\n\n      if (cb > STORE_BUFFER_SIZE - ps->writepos)\n         cb = STORE_BUFFER_SIZE - ps->writepos;\n\n      memcpy(ps->new.buffer + ps->writepos, pb, cb);\n      pb += cb;\n      st -= cb;\n      ps->writepos += cb;\n   }\n}\n\nstatic void PNGCBAPI\nstore_flush(png_structp ppIn)\n{\n   UNUSED(ppIn) /*DOES NOTHING*/\n}\n\n#ifdef PNG_READ_SUPPORTED\nstatic size_t\nstore_read_buffer_size(png_store *ps)\n{\n   /* Return the bytes available for read in the current buffer. */\n   if (ps->next != &ps->current->data)\n      return STORE_BUFFER_SIZE;\n\n   return ps->current->datacount;\n}\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\n/* Return total bytes available for read. */\nstatic size_t\nstore_read_buffer_avail(png_store *ps)\n{\n   if (ps->current != NULL && ps->next != NULL)\n   {\n      png_store_buffer *next = &ps->current->data;\n      size_t cbAvail = ps->current->datacount;\n\n      while (next != ps->next && next != NULL)\n      {\n         next = next->prev;\n         cbAvail += STORE_BUFFER_SIZE;\n      }\n\n      if (next != ps->next)\n         png_error(ps->pread, \"buffer read error\");\n\n      if (cbAvail > ps->readpos)\n         return cbAvail - ps->readpos;\n   }\n\n   return 0;\n}\n#endif\n\nstatic int\nstore_read_buffer_next(png_store *ps)\n{\n   png_store_buffer *pbOld = ps->next;\n   png_store_buffer *pbNew = &ps->current->data;\n   if (pbOld != pbNew)\n   {\n      while (pbNew != NULL && pbNew->prev != pbOld)\n         pbNew = pbNew->prev;\n\n      if (pbNew != NULL)\n      {\n         ps->next = pbNew;\n         ps->readpos = 0;\n         return 1;\n      }\n\n      png_error(ps->pread, \"buffer lost\");\n   }\n\n   return 0; /* EOF or error */\n}\n\n/* Need separate implementation and callback to allow use of the same code\n * during progressive read, where the io_ptr is set internally by libpng.\n */\nstatic void\nstore_read_imp(png_store *ps, png_bytep pb, png_size_t st)\n{\n   if (ps->current == NULL || ps->next == NULL)\n      png_error(ps->pread, \"store state damaged\");\n\n   while (st > 0)\n   {\n      size_t cbAvail = store_read_buffer_size(ps) - ps->readpos;\n\n      if (cbAvail > 0)\n      {\n         if (cbAvail > st) cbAvail = st;\n         memcpy(pb, ps->next->buffer + ps->readpos, cbAvail);\n         st -= cbAvail;\n         pb += cbAvail;\n         ps->readpos += cbAvail;\n      }\n\n      else if (!store_read_buffer_next(ps))\n         png_error(ps->pread, \"read beyond end of file\");\n   }\n}\n\nstatic void PNGCBAPI\nstore_read(png_structp ppIn, png_bytep pb, png_size_t st)\n{\n   png_const_structp pp = ppIn;\n   png_store *ps = voidcast(png_store*, png_get_io_ptr(pp));\n\n   if (ps == NULL || ps->pread != pp)\n      png_error(pp, \"bad store read call\");\n\n   store_read_imp(ps, pb, st);\n}\n\nstatic void\nstore_progressive_read(png_store *ps, png_structp pp, png_infop pi)\n{\n   /* Notice that a call to store_read will cause this function to fail because\n    * readpos will be set.\n    */\n   if (ps->pread != pp || ps->current == NULL || ps->next == NULL)\n      png_error(pp, \"store state damaged (progressive)\");\n\n   do\n   {\n      if (ps->readpos != 0)\n         png_error(pp, \"store_read called during progressive read\");\n\n      png_process_data(pp, pi, ps->next->buffer, store_read_buffer_size(ps));\n   }\n   while (store_read_buffer_next(ps));\n}\n#endif /* PNG_READ_SUPPORTED */\n\n/* The caller must fill this in: */\nstatic store_palette_entry *\nstore_write_palette(png_store *ps, int npalette)\n{\n   if (ps->pwrite == NULL)\n      store_log(ps, NULL, \"attempt to write palette without write stream\", 1);\n\n   if (ps->palette != NULL)\n      png_error(ps->pwrite, \"multiple store_write_palette calls\");\n\n   /* This function can only return NULL if called with '0'! */\n   if (npalette > 0)\n   {\n      ps->palette = voidcast(store_palette_entry*, malloc(npalette *\n         sizeof *ps->palette));\n\n      if (ps->palette == NULL)\n         png_error(ps->pwrite, \"store new palette: OOM\");\n\n      ps->npalette = npalette;\n   }\n\n   return ps->palette;\n}\n\n#ifdef PNG_READ_SUPPORTED\nstatic store_palette_entry *\nstore_current_palette(png_store *ps, int *npalette)\n{\n   /* This is an internal error (the call has been made outside a read\n    * operation.)\n    */\n   if (ps->current == NULL)\n   {\n      store_log(ps, ps->pread, \"no current stream for palette\", 1);\n      return NULL;\n   }\n\n   /* The result may be null if there is no palette. */\n   *npalette = ps->current->npalette;\n   return ps->current->palette;\n}\n#endif /* PNG_READ_SUPPORTED */\n\n/***************************** MEMORY MANAGEMENT*** ***************************/\n#ifdef PNG_USER_MEM_SUPPORTED\n/* A store_memory is simply the header for an allocated block of memory.  The\n * pointer returned to libpng is just after the end of the header block, the\n * allocated memory is followed by a second copy of the 'mark'.\n */\ntypedef struct store_memory\n{\n   store_pool          *pool;    /* Originating pool */\n   struct store_memory *next;    /* Singly linked list */\n   png_alloc_size_t     size;    /* Size of memory allocated */\n   png_byte             mark[4]; /* ID marker */\n} store_memory;\n\n/* Handle a fatal error in memory allocation.  This calls png_error if the\n * libpng struct is non-NULL, else it outputs a message and returns.  This means\n * that a memory problem while libpng is running will abort (png_error) the\n * handling of particular file while one in cleanup (after the destroy of the\n * struct has returned) will simply keep going and free (or attempt to free)\n * all the memory.\n */\nstatic void\nstore_pool_error(png_store *ps, png_const_structp pp, const char *msg)\n{\n   if (pp != NULL)\n      png_error(pp, msg);\n\n   /* Else we have to do it ourselves.  png_error eventually calls store_log,\n    * above.  store_log accepts a NULL png_structp - it just changes what gets\n    * output by store_message.\n    */\n   store_log(ps, pp, msg, 1 /* error */);\n}\n\nstatic void\nstore_memory_free(png_const_structp pp, store_pool *pool, store_memory *memory)\n{\n   /* Note that pp may be NULL (see store_pool_delete below), the caller has\n    * found 'memory' in pool->list *and* unlinked this entry, so this is a valid\n    * pointer (for sure), but the contents may have been trashed.\n    */\n   if (memory->pool != pool)\n      store_pool_error(pool->store, pp, \"memory corrupted (pool)\");\n\n   else if (memcmp(memory->mark, pool->mark, sizeof memory->mark) != 0)\n      store_pool_error(pool->store, pp, \"memory corrupted (start)\");\n\n   /* It should be safe to read the size field now. */\n   else\n   {\n      png_alloc_size_t cb = memory->size;\n\n      if (cb > pool->max)\n         store_pool_error(pool->store, pp, \"memory corrupted (size)\");\n\n      else if (memcmp((png_bytep)(memory+1)+cb, pool->mark, sizeof pool->mark)\n         != 0)\n         store_pool_error(pool->store, pp, \"memory corrupted (end)\");\n\n      /* Finally give the library a chance to find problems too: */\n      else\n         {\n         pool->current -= cb;\n         free(memory);\n         }\n   }\n}\n\nstatic void\nstore_pool_delete(png_store *ps, store_pool *pool)\n{\n   if (pool->list != NULL)\n   {\n      fprintf(stderr, \"%s: %s %s: memory lost (list follows):\\n\", ps->test,\n         pool == &ps->read_memory_pool ? \"read\" : \"write\",\n         pool == &ps->read_memory_pool ? (ps->current != NULL ?\n            ps->current->name : \"unknown file\") : ps->wname);\n      ++ps->nerrors;\n\n      do\n      {\n         store_memory *next = pool->list;\n         pool->list = next->next;\n         next->next = NULL;\n\n         fprintf(stderr, \"\\t%lu bytes @ %p\\n\",\n             (unsigned long)next->size, (const void*)(next+1));\n         /* The NULL means this will always return, even if the memory is\n          * corrupted.\n          */\n         store_memory_free(NULL, pool, next);\n      }\n      while (pool->list != NULL);\n   }\n\n   /* And reset the other fields too for the next time. */\n   if (pool->max > pool->max_max) pool->max_max = pool->max;\n   pool->max = 0;\n   if (pool->current != 0) /* unexpected internal error */\n      fprintf(stderr, \"%s: %s %s: memory counter mismatch (internal error)\\n\",\n         ps->test, pool == &ps->read_memory_pool ? \"read\" : \"write\",\n         pool == &ps->read_memory_pool ? (ps->current != NULL ?\n            ps->current->name : \"unknown file\") : ps->wname);\n   pool->current = 0;\n\n   if (pool->limit > pool->max_limit)\n      pool->max_limit = pool->limit;\n\n   pool->limit = 0;\n\n   if (pool->total > pool->max_total)\n      pool->max_total = pool->total;\n\n   pool->total = 0;\n\n   /* Get a new mark too. */\n   store_pool_mark(pool->mark);\n}\n\n/* The memory callbacks: */\nstatic png_voidp PNGCBAPI\nstore_malloc(png_structp ppIn, png_alloc_size_t cb)\n{\n   png_const_structp pp = ppIn;\n   store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp));\n   store_memory *new = voidcast(store_memory*, malloc(cb + (sizeof *new) +\n      (sizeof pool->mark)));\n\n   if (new != NULL)\n   {\n      if (cb > pool->max)\n         pool->max = cb;\n\n      pool->current += cb;\n\n      if (pool->current > pool->limit)\n         pool->limit = pool->current;\n\n      pool->total += cb;\n\n      new->size = cb;\n      memcpy(new->mark, pool->mark, sizeof new->mark);\n      memcpy((png_byte*)(new+1) + cb, pool->mark, sizeof pool->mark);\n      new->pool = pool;\n      new->next = pool->list;\n      pool->list = new;\n      ++new;\n   }\n\n   else\n   {\n      /* NOTE: the PNG user malloc function cannot use the png_ptr it is passed\n       * other than to retrieve the allocation pointer!  libpng calls the\n       * store_malloc callback in two basic cases:\n       *\n       * 1) From png_malloc; png_malloc will do a png_error itself if NULL is\n       *    returned.\n       * 2) From png_struct or png_info structure creation; png_malloc is\n       *    to return so cleanup can be performed.\n       *\n       * To handle this store_malloc can log a message, but can't do anything\n       * else.\n       */\n      store_log(pool->store, pp, \"out of memory\", 1 /* is_error */);\n   }\n\n   return new;\n}\n\nstatic void PNGCBAPI\nstore_free(png_structp ppIn, png_voidp memory)\n{\n   png_const_structp pp = ppIn;\n   store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp));\n   store_memory *this = voidcast(store_memory*, memory), **test;\n\n   /* Because libpng calls store_free with a dummy png_struct when deleting\n    * png_struct or png_info via png_destroy_struct_2 it is necessary to check\n    * the passed in png_structp to ensure it is valid, and not pass it to\n    * png_error if it is not.\n    */\n   if (pp != pool->store->pread && pp != pool->store->pwrite)\n      pp = NULL;\n\n   /* First check that this 'memory' really is valid memory - it must be in the\n    * pool list.  If it is, use the shared memory_free function to free it.\n    */\n   --this;\n   for (test = &pool->list; *test != this; test = &(*test)->next)\n   {\n      if (*test == NULL)\n      {\n         store_pool_error(pool->store, pp, \"bad pointer to free\");\n         return;\n      }\n   }\n\n   /* Unlink this entry, *test == this. */\n   *test = this->next;\n   this->next = NULL;\n   store_memory_free(pp, pool, this);\n}\n#endif /* PNG_USER_MEM_SUPPORTED */\n\n/* Setup functions. */\n/* Cleanup when aborting a write or after storing the new file. */\nstatic void\nstore_write_reset(png_store *ps)\n{\n   if (ps->pwrite != NULL)\n   {\n      anon_context(ps);\n\n      Try\n         png_destroy_write_struct(&ps->pwrite, &ps->piwrite);\n\n      Catch_anonymous\n      {\n         /* memory corruption: continue. */\n      }\n\n      ps->pwrite = NULL;\n      ps->piwrite = NULL;\n   }\n\n   /* And make sure that all the memory has been freed - this will output\n    * spurious errors in the case of memory corruption above, but this is safe.\n    */\n#  ifdef PNG_USER_MEM_SUPPORTED\n      store_pool_delete(ps, &ps->write_memory_pool);\n#  endif\n\n   store_freenew(ps);\n}\n\n/* The following is the main write function, it returns a png_struct and,\n * optionally, a png_info suitable for writiing a new PNG file.  Use\n * store_storefile above to record this file after it has been written.  The\n * returned libpng structures as destroyed by store_write_reset above.\n */\nstatic png_structp\nset_store_for_write(png_store *ps, png_infopp ppi, const char *name)\n{\n   anon_context(ps);\n\n   Try\n   {\n      if (ps->pwrite != NULL)\n         png_error(ps->pwrite, \"write store already in use\");\n\n      store_write_reset(ps);\n      safecat(ps->wname, sizeof ps->wname, 0, name);\n\n      /* Don't do the slow memory checks if doing a speed test, also if user\n       * memory is not supported we can't do it anyway.\n       */\n#     ifdef PNG_USER_MEM_SUPPORTED\n         if (!ps->speed)\n            ps->pwrite = png_create_write_struct_2(PNG_LIBPNG_VER_STRING,\n               ps, store_error, store_warning, &ps->write_memory_pool,\n               store_malloc, store_free);\n\n         else\n#     endif\n         ps->pwrite = png_create_write_struct(PNG_LIBPNG_VER_STRING,\n            ps, store_error, store_warning);\n\n      png_set_write_fn(ps->pwrite, ps, store_write, store_flush);\n\n#     ifdef PNG_SET_OPTION_SUPPORTED\n         {\n            int opt;\n            for (opt=0; opt<ps->noptions; ++opt)\n               if (png_set_option(ps->pwrite, ps->options[opt].option,\n                  ps->options[opt].setting) == PNG_OPTION_INVALID)\n                  png_error(ps->pwrite, \"png option invalid\");\n         }\n#     endif\n\n      if (ppi != NULL)\n         *ppi = ps->piwrite = png_create_info_struct(ps->pwrite);\n   }\n\n   Catch_anonymous\n      return NULL;\n\n   return ps->pwrite;\n}\n\n/* Cleanup when finished reading (either due to error or in the success case).\n * This routine exists even when there is no read support to make the code\n * tidier (avoid a mass of ifdefs) and so easier to maintain.\n */\nstatic void\nstore_read_reset(png_store *ps)\n{\n#  ifdef PNG_READ_SUPPORTED\n      if (ps->pread != NULL)\n      {\n         anon_context(ps);\n\n         Try\n            png_destroy_read_struct(&ps->pread, &ps->piread, NULL);\n\n         Catch_anonymous\n         {\n            /* error already output: continue */\n         }\n\n         ps->pread = NULL;\n         ps->piread = NULL;\n      }\n#  endif\n\n#  ifdef PNG_USER_MEM_SUPPORTED\n      /* Always do this to be safe. */\n      store_pool_delete(ps, &ps->read_memory_pool);\n#  endif\n\n   ps->current = NULL;\n   ps->next = NULL;\n   ps->readpos = 0;\n   ps->validated = 0;\n}\n\n#ifdef PNG_READ_SUPPORTED\nstatic void\nstore_read_set(png_store *ps, png_uint_32 id)\n{\n   png_store_file *pf = ps->saved;\n\n   while (pf != NULL)\n   {\n      if (pf->id == id)\n      {\n         ps->current = pf;\n         ps->next = NULL;\n         store_read_buffer_next(ps);\n         return;\n      }\n\n      pf = pf->next;\n   }\n\n   {\n      size_t pos;\n      char msg[FILE_NAME_SIZE+64];\n\n      pos = standard_name_from_id(msg, sizeof msg, 0, id);\n      pos = safecat(msg, sizeof msg, pos, \": file not found\");\n      png_error(ps->pread, msg);\n   }\n}\n\n/* The main interface for reading a saved file - pass the id number of the file\n * to retrieve.  Ids must be unique or the earlier file will be hidden.  The API\n * returns a png_struct and, optionally, a png_info.  Both of these will be\n * destroyed by store_read_reset above.\n */\nstatic png_structp\nset_store_for_read(png_store *ps, png_infopp ppi, png_uint_32 id,\n   const char *name)\n{\n   /* Set the name for png_error */\n   safecat(ps->test, sizeof ps->test, 0, name);\n\n   if (ps->pread != NULL)\n      png_error(ps->pread, \"read store already in use\");\n\n   store_read_reset(ps);\n\n   /* Both the create APIs can return NULL if used in their default mode\n    * (because there is no other way of handling an error because the jmp_buf\n    * by default is stored in png_struct and that has not been allocated!)\n    * However, given that store_error works correctly in these circumstances\n    * we don't ever expect NULL in this program.\n    */\n#  ifdef PNG_USER_MEM_SUPPORTED\n      if (!ps->speed)\n         ps->pread = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, ps,\n             store_error, store_warning, &ps->read_memory_pool, store_malloc,\n             store_free);\n\n      else\n#  endif\n   ps->pread = png_create_read_struct(PNG_LIBPNG_VER_STRING, ps, store_error,\n      store_warning);\n\n   if (ps->pread == NULL)\n   {\n      struct exception_context *the_exception_context = &ps->exception_context;\n\n      store_log(ps, NULL, \"png_create_read_struct returned NULL (unexpected)\",\n         1 /*error*/);\n\n      Throw ps;\n   }\n\n#  ifdef PNG_SET_OPTION_SUPPORTED\n      {\n         int opt;\n         for (opt=0; opt<ps->noptions; ++opt)\n            if (png_set_option(ps->pread, ps->options[opt].option,\n               ps->options[opt].setting) == PNG_OPTION_INVALID)\n                  png_error(ps->pread, \"png option invalid\");\n      }\n#  endif\n\n   store_read_set(ps, id);\n\n   if (ppi != NULL)\n      *ppi = ps->piread = png_create_info_struct(ps->pread);\n\n   return ps->pread;\n}\n#endif /* PNG_READ_SUPPORTED */\n\n/* The overall cleanup of a store simply calls the above then removes all the\n * saved files.  This does not delete the store itself.\n */\nstatic void\nstore_delete(png_store *ps)\n{\n   store_write_reset(ps);\n   store_read_reset(ps);\n   store_freefile(&ps->saved);\n   store_image_free(ps, NULL);\n}\n\n/*********************** PNG FILE MODIFICATION ON READ ************************/\n/* Files may be modified on read.  The following structure contains a complete\n * png_store together with extra members to handle modification and a special\n * read callback for libpng.  To use this the 'modifications' field must be set\n * to a list of png_modification structures that actually perform the\n * modification, otherwise a png_modifier is functionally equivalent to a\n * png_store.  There is a special read function, set_modifier_for_read, which\n * replaces set_store_for_read.\n */\ntypedef enum modifier_state\n{\n   modifier_start,                        /* Initial value */\n   modifier_signature,                    /* Have a signature */\n   modifier_IHDR                          /* Have an IHDR */\n} modifier_state;\n\ntypedef struct CIE_color\n{\n   /* A single CIE tristimulus value, representing the unique response of a\n    * standard observer to a variety of light spectra.  The observer recognizes\n    * all spectra that produce this response as the same color, therefore this\n    * is effectively a description of a color.\n    */\n   double X, Y, Z;\n} CIE_color;\n\ntypedef struct color_encoding\n{\n   /* A description of an (R,G,B) encoding of color (as defined above); this\n    * includes the actual colors of the (R,G,B) triples (1,0,0), (0,1,0) and\n    * (0,0,1) plus an encoding value that is used to encode the linear\n    * components R, G and B to give the actual values R^gamma, G^gamma and\n    * B^gamma that are stored.\n    */\n   double    gamma;            /* Encoding (file) gamma of space */\n   CIE_color red, green, blue; /* End points */\n} color_encoding;\n\n#ifdef PNG_READ_SUPPORTED\n#if defined PNG_READ_TRANSFORMS_SUPPORTED && defined PNG_READ_cHRM_SUPPORTED\nstatic double\nchromaticity_x(CIE_color c)\n{\n   return c.X / (c.X + c.Y + c.Z);\n}\n\nstatic double\nchromaticity_y(CIE_color c)\n{\n   return c.Y / (c.X + c.Y + c.Z);\n}\n\nstatic CIE_color\nwhite_point(const color_encoding *encoding)\n{\n   CIE_color white;\n\n   white.X = encoding->red.X + encoding->green.X + encoding->blue.X;\n   white.Y = encoding->red.Y + encoding->green.Y + encoding->blue.Y;\n   white.Z = encoding->red.Z + encoding->green.Z + encoding->blue.Z;\n\n   return white;\n}\n#endif /* READ_TRANSFORMS && READ_cHRM */\n\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\nstatic void\nnormalize_color_encoding(color_encoding *encoding)\n{\n   const double whiteY = encoding->red.Y + encoding->green.Y +\n      encoding->blue.Y;\n\n   if (whiteY != 1)\n   {\n      encoding->red.X /= whiteY;\n      encoding->red.Y /= whiteY;\n      encoding->red.Z /= whiteY;\n      encoding->green.X /= whiteY;\n      encoding->green.Y /= whiteY;\n      encoding->green.Z /= whiteY;\n      encoding->blue.X /= whiteY;\n      encoding->blue.Y /= whiteY;\n      encoding->blue.Z /= whiteY;\n   }\n}\n#endif\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\nstatic size_t\nsafecat_color_encoding(char *buffer, size_t bufsize, size_t pos,\n   const color_encoding *e, double encoding_gamma)\n{\n   if (e != 0)\n   {\n      if (encoding_gamma != 0)\n         pos = safecat(buffer, bufsize, pos, \"(\");\n      pos = safecat(buffer, bufsize, pos, \"R(\");\n      pos = safecatd(buffer, bufsize, pos, e->red.X, 4);\n      pos = safecat(buffer, bufsize, pos, \",\");\n      pos = safecatd(buffer, bufsize, pos, e->red.Y, 4);\n      pos = safecat(buffer, bufsize, pos, \",\");\n      pos = safecatd(buffer, bufsize, pos, e->red.Z, 4);\n      pos = safecat(buffer, bufsize, pos, \"),G(\");\n      pos = safecatd(buffer, bufsize, pos, e->green.X, 4);\n      pos = safecat(buffer, bufsize, pos, \",\");\n      pos = safecatd(buffer, bufsize, pos, e->green.Y, 4);\n      pos = safecat(buffer, bufsize, pos, \",\");\n      pos = safecatd(buffer, bufsize, pos, e->green.Z, 4);\n      pos = safecat(buffer, bufsize, pos, \"),B(\");\n      pos = safecatd(buffer, bufsize, pos, e->blue.X, 4);\n      pos = safecat(buffer, bufsize, pos, \",\");\n      pos = safecatd(buffer, bufsize, pos, e->blue.Y, 4);\n      pos = safecat(buffer, bufsize, pos, \",\");\n      pos = safecatd(buffer, bufsize, pos, e->blue.Z, 4);\n      pos = safecat(buffer, bufsize, pos, \")\");\n      if (encoding_gamma != 0)\n         pos = safecat(buffer, bufsize, pos, \")\");\n   }\n\n   if (encoding_gamma != 0)\n   {\n      pos = safecat(buffer, bufsize, pos, \"^\");\n      pos = safecatd(buffer, bufsize, pos, encoding_gamma, 5);\n   }\n\n   return pos;\n}\n#endif /* READ_TRANSFORMS */\n#endif /* PNG_READ_SUPPORTED */\n\ntypedef struct png_modifier\n{\n   png_store               this;             /* I am a png_store */\n   struct png_modification *modifications;   /* Changes to make */\n\n   modifier_state           state;           /* My state */\n\n   /* Information from IHDR: */\n   png_byte                 bit_depth;       /* From IHDR */\n   png_byte                 colour_type;     /* From IHDR */\n\n   /* While handling PLTE, IDAT and IEND these chunks may be pended to allow\n    * other chunks to be inserted.\n    */\n   png_uint_32              pending_len;\n   png_uint_32              pending_chunk;\n\n   /* Test values */\n   double                   *gammas;\n   unsigned int              ngammas;\n   unsigned int              ngamma_tests;     /* Number of gamma tests to run*/\n   double                    current_gamma;    /* 0 if not set */\n   const color_encoding *encodings;\n   unsigned int              nencodings;\n   const color_encoding *current_encoding; /* If an encoding has been set */\n   unsigned int              encoding_counter; /* For iteration */\n   int                       encoding_ignored; /* Something overwrote it */\n\n   /* Control variables used to iterate through possible encodings, the\n    * following must be set to 0 and tested by the function that uses the\n    * png_modifier because the modifier only sets it to 1 (true.)\n    */\n   unsigned int              repeat :1;   /* Repeat this transform test. */\n   unsigned int              test_uses_encoding :1;\n\n   /* Lowest sbit to test (pre-1.7 libpng fails for sbit < 8) */\n   png_byte                 sbitlow;\n\n   /* Error control - these are the limits on errors accepted by the gamma tests\n    * below.\n    */\n   double                   maxout8;  /* Maximum output value error */\n   double                   maxabs8;  /* Absolute sample error 0..1 */\n   double                   maxcalc8; /* Absolute sample error 0..1 */\n   double                   maxpc8;   /* Percentage sample error 0..100% */\n   double                   maxout16; /* Maximum output value error */\n   double                   maxabs16; /* Absolute sample error 0..1 */\n   double                   maxcalc16;/* Absolute sample error 0..1 */\n   double                   maxcalcG; /* Absolute sample error 0..1 */\n   double                   maxpc16;  /* Percentage sample error 0..100% */\n\n   /* This is set by transforms that need to allow a higher limit, it is an\n    * internal check on pngvalid to ensure that the calculated error limits are\n    * not ridiculous; without this it is too easy to make a mistake in pngvalid\n    * that allows any value through.\n    *\n    * NOTE: this is not checked in release builds.\n    */\n   double                   limit;    /* limit on error values, normally 4E-3 */\n\n   /* Log limits - values above this are logged, but not necessarily\n    * warned.\n    */\n   double                   log8;     /* Absolute error in 8 bits to log */\n   double                   log16;    /* Absolute error in 16 bits to log */\n\n   /* Logged 8 and 16 bit errors ('output' values): */\n   double                   error_gray_2;\n   double                   error_gray_4;\n   double                   error_gray_8;\n   double                   error_gray_16;\n   double                   error_color_8;\n   double                   error_color_16;\n   double                   error_indexed;\n\n   /* Flags: */\n   /* Whether to call png_read_update_info, not png_read_start_image, and how\n    * many times to call it.\n    */\n   int                      use_update_info;\n\n   /* Whether or not to interlace. */\n   int                      interlace_type :9; /* int, but must store '1' */\n\n   /* Run the standard tests? */\n   unsigned int             test_standard :1;\n\n   /* Run the odd-sized image and interlace read/write tests? */\n   unsigned int             test_size :1;\n\n   /* Run tests on reading with a combination of transforms, */\n   unsigned int             test_transform :1;\n   unsigned int             test_tRNS :1; /* Includes tRNS images */\n\n   /* When to use the use_input_precision option, this controls the gamma\n    * validation code checks.  If set any value that is within the transformed\n    * range input-.5 to input+.5 will be accepted, otherwise the value must be\n    * within the normal limits.  It should not be necessary to set this; the\n    * result should always be exact within the permitted error limits.\n    */\n   unsigned int             use_input_precision :1;\n   unsigned int             use_input_precision_sbit :1;\n   unsigned int             use_input_precision_16to8 :1;\n\n   /* If set assume that the calculation bit depth is set by the input\n    * precision, not the output precision.\n    */\n   unsigned int             calculations_use_input_precision :1;\n\n   /* If set assume that the calculations are done in 16 bits even if the sample\n    * depth is 8 bits.\n    */\n   unsigned int             assume_16_bit_calculations :1;\n\n   /* Which gamma tests to run: */\n   unsigned int             test_gamma_threshold :1;\n   unsigned int             test_gamma_transform :1; /* main tests */\n   unsigned int             test_gamma_sbit :1;\n   unsigned int             test_gamma_scale16 :1;\n   unsigned int             test_gamma_background :1;\n   unsigned int             test_gamma_alpha_mode :1;\n   unsigned int             test_gamma_expand16 :1;\n   unsigned int             test_exhaustive :1;\n\n   /* Whether or not to run the low-bit-depth grayscale tests.  This fails on\n    * gamma images in some cases because of gross inaccuracies in the grayscale\n    * gamma handling for low bit depth.\n    */\n   unsigned int             test_lbg :1;\n   unsigned int             test_lbg_gamma_threshold :1;\n   unsigned int             test_lbg_gamma_transform :1;\n   unsigned int             test_lbg_gamma_sbit :1;\n   unsigned int             test_lbg_gamma_composition :1;\n\n   unsigned int             log :1;   /* Log max error */\n\n   /* Buffer information, the buffer size limits the size of the chunks that can\n    * be modified - they must fit (including header and CRC) into the buffer!\n    */\n   size_t                   flush;           /* Count of bytes to flush */\n   size_t                   buffer_count;    /* Bytes in buffer */\n   size_t                   buffer_position; /* Position in buffer */\n   png_byte                 buffer[1024];\n} png_modifier;\n\n/* This returns true if the test should be stopped now because it has already\n * failed and it is running silently.\n  */\nstatic int fail(png_modifier *pm)\n{\n   return !pm->log && !pm->this.verbose && (pm->this.nerrors > 0 ||\n       (pm->this.treat_warnings_as_errors && pm->this.nwarnings > 0));\n}\n\nstatic void\nmodifier_init(png_modifier *pm)\n{\n   memset(pm, 0, sizeof *pm);\n   store_init(&pm->this);\n   pm->modifications = NULL;\n   pm->state = modifier_start;\n   pm->sbitlow = 1U;\n   pm->ngammas = 0;\n   pm->ngamma_tests = 0;\n   pm->gammas = 0;\n   pm->current_gamma = 0;\n   pm->encodings = 0;\n   pm->nencodings = 0;\n   pm->current_encoding = 0;\n   pm->encoding_counter = 0;\n   pm->encoding_ignored = 0;\n   pm->repeat = 0;\n   pm->test_uses_encoding = 0;\n   pm->maxout8 = pm->maxpc8 = pm->maxabs8 = pm->maxcalc8 = 0;\n   pm->maxout16 = pm->maxpc16 = pm->maxabs16 = pm->maxcalc16 = 0;\n   pm->maxcalcG = 0;\n   pm->limit = 4E-3;\n   pm->log8 = pm->log16 = 0; /* Means 'off' */\n   pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0;\n   pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0;\n   pm->error_indexed = 0;\n   pm->use_update_info = 0;\n   pm->interlace_type = PNG_INTERLACE_NONE;\n   pm->test_standard = 0;\n   pm->test_size = 0;\n   pm->test_transform = 0;\n#  ifdef PNG_WRITE_tRNS_SUPPORTED\n      pm->test_tRNS = 1;\n#  else\n      pm->test_tRNS = 0;\n#  endif\n   pm->use_input_precision = 0;\n   pm->use_input_precision_sbit = 0;\n   pm->use_input_precision_16to8 = 0;\n   pm->calculations_use_input_precision = 0;\n   pm->assume_16_bit_calculations = 0;\n   pm->test_gamma_threshold = 0;\n   pm->test_gamma_transform = 0;\n   pm->test_gamma_sbit = 0;\n   pm->test_gamma_scale16 = 0;\n   pm->test_gamma_background = 0;\n   pm->test_gamma_alpha_mode = 0;\n   pm->test_gamma_expand16 = 0;\n   pm->test_lbg = 1;\n   pm->test_lbg_gamma_threshold = 1;\n   pm->test_lbg_gamma_transform = 1;\n   pm->test_lbg_gamma_sbit = 1;\n   pm->test_lbg_gamma_composition = 1;\n   pm->test_exhaustive = 0;\n   pm->log = 0;\n\n   /* Rely on the memset for all the other fields - there are no pointers */\n}\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\n\n/* This controls use of checks that explicitly know how libpng digitizes the\n * samples in calculations; setting this circumvents simple error limit checking\n * in the rgb_to_gray check, replacing it with an exact copy of the libpng 1.5\n * algorithm.\n */\n#define DIGITIZE PNG_LIBPNG_VER < 10700\n\n/* If pm->calculations_use_input_precision is set then operations will happen\n * with the precision of the input, not the precision of the output depth.\n *\n * If pm->assume_16_bit_calculations is set then even 8 bit calculations use 16\n * bit precision.  This only affects those of the following limits that pertain\n * to a calculation - not a digitization operation - unless the following API is\n * called directly.\n */\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\n#if DIGITIZE\nstatic double digitize(double value, int depth, int do_round)\n{\n   /* 'value' is in the range 0 to 1, the result is the same value rounded to a\n    * multiple of the digitization factor - 8 or 16 bits depending on both the\n    * sample depth and the 'assume' setting.  Digitization is normally by\n    * rounding and 'do_round' should be 1, if it is 0 the digitized value will\n    * be truncated.\n    */\n   const unsigned int digitization_factor = (1U << depth) -1;\n\n   /* Limiting the range is done as a convenience to the caller - it's easier to\n    * do it once here than every time at the call site.\n    */\n   if (value <= 0)\n      value = 0;\n\n   else if (value >= 1)\n      value = 1;\n\n   value *= digitization_factor;\n   if (do_round) value += .5;\n   return floor(value)/digitization_factor;\n}\n#endif\n#endif /* RGB_TO_GRAY */\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\nstatic double abserr(const png_modifier *pm, int in_depth, int out_depth)\n{\n   /* Absolute error permitted in linear values - affected by the bit depth of\n    * the calculations.\n    */\n   if (pm->assume_16_bit_calculations ||\n      (pm->calculations_use_input_precision ? in_depth : out_depth) == 16)\n      return pm->maxabs16;\n   else\n      return pm->maxabs8;\n}\n\nstatic double calcerr(const png_modifier *pm, int in_depth, int out_depth)\n{\n   /* Error in the linear composition arithmetic - only relevant when\n    * composition actually happens (0 < alpha < 1).\n    */\n   if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16)\n      return pm->maxcalc16;\n   else if (pm->assume_16_bit_calculations)\n      return pm->maxcalcG;\n   else\n      return pm->maxcalc8;\n}\n\nstatic double pcerr(const png_modifier *pm, int in_depth, int out_depth)\n{\n   /* Percentage error permitted in the linear values.  Note that the specified\n    * value is a percentage but this routine returns a simple number.\n    */\n   if (pm->assume_16_bit_calculations ||\n      (pm->calculations_use_input_precision ? in_depth : out_depth) == 16)\n      return pm->maxpc16 * .01;\n   else\n      return pm->maxpc8 * .01;\n}\n\n/* Output error - the error in the encoded value.  This is determined by the\n * digitization of the output so can be +/-0.5 in the actual output value.  In\n * the expand_16 case with the current code in libpng the expand happens after\n * all the calculations are done in 8 bit arithmetic, so even though the output\n * depth is 16 the output error is determined by the 8 bit calculation.\n *\n * This limit is not determined by the bit depth of internal calculations.\n *\n * The specified parameter does *not* include the base .5 digitization error but\n * it is added here.\n */\nstatic double outerr(const png_modifier *pm, int in_depth, int out_depth)\n{\n   /* There is a serious error in the 2 and 4 bit grayscale transform because\n    * the gamma table value (8 bits) is simply shifted, not rounded, so the\n    * error in 4 bit grayscale gamma is up to the value below.  This is a hack\n    * to allow pngvalid to succeed:\n    *\n    * TODO: fix this in libpng\n    */\n   if (out_depth == 2)\n      return .73182-.5;\n\n   if (out_depth == 4)\n      return .90644-.5;\n\n   if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16)\n      return pm->maxout16;\n\n   /* This is the case where the value was calculated at 8-bit precision then\n    * scaled to 16 bits.\n    */\n   else if (out_depth == 16)\n      return pm->maxout8 * 257;\n\n   else\n      return pm->maxout8;\n}\n\n/* This does the same thing as the above however it returns the value to log,\n * rather than raising a warning.  This is useful for debugging to track down\n * exactly what set of parameters cause high error values.\n */\nstatic double outlog(const png_modifier *pm, int in_depth, int out_depth)\n{\n   /* The command line parameters are either 8 bit (0..255) or 16 bit (0..65535)\n    * and so must be adjusted for low bit depth grayscale:\n    */\n   if (out_depth <= 8)\n   {\n      if (pm->log8 == 0) /* switched off */\n         return 256;\n\n      if (out_depth < 8)\n         return pm->log8 / 255 * ((1<<out_depth)-1);\n\n      return pm->log8;\n   }\n\n   if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16)\n   {\n      if (pm->log16 == 0)\n         return 65536;\n\n      return pm->log16;\n   }\n\n   /* This is the case where the value was calculated at 8-bit precision then\n    * scaled to 16 bits.\n    */\n   if (pm->log8 == 0)\n      return 65536;\n\n   return pm->log8 * 257;\n}\n\n/* This complements the above by providing the appropriate quantization for the\n * final value.  Normally this would just be quantization to an integral value,\n * but in the 8 bit calculation case it's actually quantization to a multiple of\n * 257!\n */\nstatic int output_quantization_factor(const png_modifier *pm, int in_depth,\n   int out_depth)\n{\n   if (out_depth == 16 && in_depth != 16 &&\n      pm->calculations_use_input_precision)\n      return 257;\n   else\n      return 1;\n}\n#endif /* PNG_READ_GAMMA_SUPPORTED */\n\n/* One modification structure must be provided for each chunk to be modified (in\n * fact more than one can be provided if multiple separate changes are desired\n * for a single chunk.)  Modifications include adding a new chunk when a\n * suitable chunk does not exist.\n *\n * The caller of modify_fn will reset the CRC of the chunk and record 'modified'\n * or 'added' as appropriate if the modify_fn returns 1 (true).  If the\n * modify_fn is NULL the chunk is simply removed.\n */\ntypedef struct png_modification\n{\n   struct png_modification *next;\n   png_uint_32              chunk;\n\n   /* If the following is NULL all matching chunks will be removed: */\n   int                    (*modify_fn)(struct png_modifier *pm,\n                               struct png_modification *me, int add);\n\n   /* If the following is set to PLTE, IDAT or IEND and the chunk has not been\n    * found and modified (and there is a modify_fn) the modify_fn will be called\n    * to add the chunk before the relevant chunk.\n    */\n   png_uint_32              add;\n   unsigned int             modified :1;     /* Chunk was modified */\n   unsigned int             added    :1;     /* Chunk was added */\n   unsigned int             removed  :1;     /* Chunk was removed */\n} png_modification;\n\nstatic void\nmodification_reset(png_modification *pmm)\n{\n   if (pmm != NULL)\n   {\n      pmm->modified = 0;\n      pmm->added = 0;\n      pmm->removed = 0;\n      modification_reset(pmm->next);\n   }\n}\n\nstatic void\nmodification_init(png_modification *pmm)\n{\n   memset(pmm, 0, sizeof *pmm);\n   pmm->next = NULL;\n   pmm->chunk = 0;\n   pmm->modify_fn = NULL;\n   pmm->add = 0;\n   modification_reset(pmm);\n}\n\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\nstatic void\nmodifier_current_encoding(const png_modifier *pm, color_encoding *ce)\n{\n   if (pm->current_encoding != 0)\n      *ce = *pm->current_encoding;\n\n   else\n      memset(ce, 0, sizeof *ce);\n\n   ce->gamma = pm->current_gamma;\n}\n#endif\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\nstatic size_t\nsafecat_current_encoding(char *buffer, size_t bufsize, size_t pos,\n   const png_modifier *pm)\n{\n   pos = safecat_color_encoding(buffer, bufsize, pos, pm->current_encoding,\n      pm->current_gamma);\n\n   if (pm->encoding_ignored)\n      pos = safecat(buffer, bufsize, pos, \"[overridden]\");\n\n   return pos;\n}\n#endif\n\n/* Iterate through the usefully testable color encodings.  An encoding is one\n * of:\n *\n * 1) Nothing (no color space, no gamma).\n * 2) Just a gamma value from the gamma array (including 1.0)\n * 3) A color space from the encodings array with the corresponding gamma.\n * 4) The same, but with gamma 1.0 (only really useful with 16 bit calculations)\n *\n * The iterator selects these in turn, the randomizer selects one at random,\n * which is used depends on the setting of the 'test_exhaustive' flag.  Notice\n * that this function changes the colour space encoding so it must only be\n * called on completion of the previous test.  This is what 'modifier_reset'\n * does, below.\n *\n * After the function has been called the 'repeat' flag will still be set; the\n * caller of modifier_reset must reset it at the start of each run of the test!\n */\nstatic unsigned int\nmodifier_total_encodings(const png_modifier *pm)\n{\n   return 1 +                 /* (1) nothing */\n      pm->ngammas +           /* (2) gamma values to test */\n      pm->nencodings +        /* (3) total number of encodings */\n      /* The following test only works after the first time through the\n       * png_modifier code because 'bit_depth' is set when the IHDR is read.\n       * modifier_reset, below, preserves the setting until after it has called\n       * the iterate function (also below.)\n       *\n       * For this reason do not rely on this function outside a call to\n       * modifier_reset.\n       */\n      ((pm->bit_depth == 16 || pm->assume_16_bit_calculations) ?\n         pm->nencodings : 0); /* (4) encodings with gamma == 1.0 */\n}\n\nstatic void\nmodifier_encoding_iterate(png_modifier *pm)\n{\n   if (!pm->repeat && /* Else something needs the current encoding again. */\n      pm->test_uses_encoding) /* Some transform is encoding dependent */\n   {\n      if (pm->test_exhaustive)\n      {\n         if (++pm->encoding_counter >= modifier_total_encodings(pm))\n            pm->encoding_counter = 0; /* This will stop the repeat */\n      }\n\n      else\n      {\n         /* Not exhaustive - choose an encoding at random; generate a number in\n          * the range 1..(max-1), so the result is always non-zero:\n          */\n         if (pm->encoding_counter == 0)\n            pm->encoding_counter = random_mod(modifier_total_encodings(pm)-1)+1;\n         else\n            pm->encoding_counter = 0;\n      }\n\n      if (pm->encoding_counter > 0)\n         pm->repeat = 1;\n   }\n\n   else if (!pm->repeat)\n      pm->encoding_counter = 0;\n}\n\nstatic void\nmodifier_reset(png_modifier *pm)\n{\n   store_read_reset(&pm->this);\n   pm->limit = 4E-3;\n   pm->pending_len = pm->pending_chunk = 0;\n   pm->flush = pm->buffer_count = pm->buffer_position = 0;\n   pm->modifications = NULL;\n   pm->state = modifier_start;\n   modifier_encoding_iterate(pm);\n   /* The following must be set in the next run.  In particular\n    * test_uses_encodings must be set in the _ini function of each transform\n    * that looks at the encodings.  (Not the 'add' function!)\n    */\n   pm->test_uses_encoding = 0;\n   pm->current_gamma = 0;\n   pm->current_encoding = 0;\n   pm->encoding_ignored = 0;\n   /* These only become value after IHDR is read: */\n   pm->bit_depth = pm->colour_type = 0;\n}\n\n/* The following must be called before anything else to get the encoding set up\n * on the modifier.  In particular it must be called before the transform init\n * functions are called.\n */\nstatic void\nmodifier_set_encoding(png_modifier *pm)\n{\n   /* Set the encoding to the one specified by the current encoding counter,\n    * first clear out all the settings - this corresponds to an encoding_counter\n    * of 0.\n    */\n   pm->current_gamma = 0;\n   pm->current_encoding = 0;\n   pm->encoding_ignored = 0; /* not ignored yet - happens in _ini functions. */\n\n   /* Now, if required, set the gamma and encoding fields. */\n   if (pm->encoding_counter > 0)\n   {\n      /* The gammas[] array is an array of screen gammas, not encoding gammas,\n       * so we need the inverse:\n       */\n      if (pm->encoding_counter <= pm->ngammas)\n         pm->current_gamma = 1/pm->gammas[pm->encoding_counter-1];\n\n      else\n      {\n         unsigned int i = pm->encoding_counter - pm->ngammas;\n\n         if (i >= pm->nencodings)\n         {\n            i %= pm->nencodings;\n            pm->current_gamma = 1; /* Linear, only in the 16 bit case */\n         }\n\n         else\n            pm->current_gamma = pm->encodings[i].gamma;\n\n         pm->current_encoding = pm->encodings + i;\n      }\n   }\n}\n\n/* Enquiry functions to find out what is set.  Notice that there is an implicit\n * assumption below that the first encoding in the list is the one for sRGB.\n */\nstatic int\nmodifier_color_encoding_is_sRGB(const png_modifier *pm)\n{\n   return pm->current_encoding != 0 && pm->current_encoding == pm->encodings &&\n      pm->current_encoding->gamma == pm->current_gamma;\n}\n\nstatic int\nmodifier_color_encoding_is_set(const png_modifier *pm)\n{\n   return pm->current_gamma != 0;\n}\n\n/* Convenience macros. */\n#define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d))\n#define CHUNK_IHDR CHUNK(73,72,68,82)\n#define CHUNK_PLTE CHUNK(80,76,84,69)\n#define CHUNK_IDAT CHUNK(73,68,65,84)\n#define CHUNK_IEND CHUNK(73,69,78,68)\n#define CHUNK_cHRM CHUNK(99,72,82,77)\n#define CHUNK_gAMA CHUNK(103,65,77,65)\n#define CHUNK_sBIT CHUNK(115,66,73,84)\n#define CHUNK_sRGB CHUNK(115,82,71,66)\n\n/* The guts of modification are performed during a read. */\nstatic void\nmodifier_crc(png_bytep buffer)\n{\n   /* Recalculate the chunk CRC - a complete chunk must be in\n    * the buffer, at the start.\n    */\n   uInt datalen = png_get_uint_32(buffer);\n   uLong crc = crc32(0, buffer+4, datalen+4);\n   /* The cast to png_uint_32 is safe because a crc32 is always a 32 bit value.\n    */\n   png_save_uint_32(buffer+datalen+8, (png_uint_32)crc);\n}\n\nstatic void\nmodifier_setbuffer(png_modifier *pm)\n{\n   modifier_crc(pm->buffer);\n   pm->buffer_count = png_get_uint_32(pm->buffer)+12;\n   pm->buffer_position = 0;\n}\n\n/* Separate the callback into the actual implementation (which is passed the\n * png_modifier explicitly) and the callback, which gets the modifier from the\n * png_struct.\n */\nstatic void\nmodifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st)\n{\n   while (st > 0)\n   {\n      size_t cb;\n      png_uint_32 len, chunk;\n      png_modification *mod;\n\n      if (pm->buffer_position >= pm->buffer_count) switch (pm->state)\n      {\n         static png_byte sign[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };\n         case modifier_start:\n            store_read_imp(&pm->this, pm->buffer, 8); /* size of signature. */\n            pm->buffer_count = 8;\n            pm->buffer_position = 0;\n\n            if (memcmp(pm->buffer, sign, 8) != 0)\n               png_error(pm->this.pread, \"invalid PNG file signature\");\n            pm->state = modifier_signature;\n            break;\n\n         case modifier_signature:\n            store_read_imp(&pm->this, pm->buffer, 13+12); /* size of IHDR */\n            pm->buffer_count = 13+12;\n            pm->buffer_position = 0;\n\n            if (png_get_uint_32(pm->buffer) != 13 ||\n                png_get_uint_32(pm->buffer+4) != CHUNK_IHDR)\n               png_error(pm->this.pread, \"invalid IHDR\");\n\n            /* Check the list of modifiers for modifications to the IHDR. */\n            mod = pm->modifications;\n            while (mod != NULL)\n            {\n               if (mod->chunk == CHUNK_IHDR && mod->modify_fn &&\n                   (*mod->modify_fn)(pm, mod, 0))\n                  {\n                  mod->modified = 1;\n                  modifier_setbuffer(pm);\n                  }\n\n               /* Ignore removal or add if IHDR! */\n               mod = mod->next;\n            }\n\n            /* Cache information from the IHDR (the modified one.) */\n            pm->bit_depth = pm->buffer[8+8];\n            pm->colour_type = pm->buffer[8+8+1];\n\n            pm->state = modifier_IHDR;\n            pm->flush = 0;\n            break;\n\n         case modifier_IHDR:\n         default:\n            /* Read a new chunk and process it until we see PLTE, IDAT or\n             * IEND.  'flush' indicates that there is still some data to\n             * output from the preceding chunk.\n             */\n            if ((cb = pm->flush) > 0)\n            {\n               if (cb > st) cb = st;\n               pm->flush -= cb;\n               store_read_imp(&pm->this, pb, cb);\n               pb += cb;\n               st -= cb;\n               if (st == 0) return;\n            }\n\n            /* No more bytes to flush, read a header, or handle a pending\n             * chunk.\n             */\n            if (pm->pending_chunk != 0)\n            {\n               png_save_uint_32(pm->buffer, pm->pending_len);\n               png_save_uint_32(pm->buffer+4, pm->pending_chunk);\n               pm->pending_len = 0;\n               pm->pending_chunk = 0;\n            }\n            else\n               store_read_imp(&pm->this, pm->buffer, 8);\n\n            pm->buffer_count = 8;\n            pm->buffer_position = 0;\n\n            /* Check for something to modify or a terminator chunk. */\n            len = png_get_uint_32(pm->buffer);\n            chunk = png_get_uint_32(pm->buffer+4);\n\n            /* Terminators first, they may have to be delayed for added\n             * chunks\n             */\n            if (chunk == CHUNK_PLTE || chunk == CHUNK_IDAT ||\n                chunk == CHUNK_IEND)\n            {\n               mod = pm->modifications;\n\n               while (mod != NULL)\n               {\n                  if ((mod->add == chunk ||\n                      (mod->add == CHUNK_PLTE && chunk == CHUNK_IDAT)) &&\n                      mod->modify_fn != NULL && !mod->modified && !mod->added)\n                  {\n                     /* Regardless of what the modify function does do not run\n                      * this again.\n                      */\n                     mod->added = 1;\n\n                     if ((*mod->modify_fn)(pm, mod, 1 /*add*/))\n                     {\n                        /* Reset the CRC on a new chunk */\n                        if (pm->buffer_count > 0)\n                           modifier_setbuffer(pm);\n\n                        else\n                           {\n                           pm->buffer_position = 0;\n                           mod->removed = 1;\n                           }\n\n                        /* The buffer has been filled with something (we assume)\n                         * so output this.  Pend the current chunk.\n                         */\n                        pm->pending_len = len;\n                        pm->pending_chunk = chunk;\n                        break; /* out of while */\n                     }\n                  }\n\n                  mod = mod->next;\n               }\n\n               /* Don't do any further processing if the buffer was modified -\n                * otherwise the code will end up modifying a chunk that was\n                * just added.\n                */\n               if (mod != NULL)\n                  break; /* out of switch */\n            }\n\n            /* If we get to here then this chunk may need to be modified.  To\n             * do this it must be less than 1024 bytes in total size, otherwise\n             * it just gets flushed.\n             */\n            if (len+12 <= sizeof pm->buffer)\n            {\n               store_read_imp(&pm->this, pm->buffer+pm->buffer_count,\n                   len+12-pm->buffer_count);\n               pm->buffer_count = len+12;\n\n               /* Check for a modification, else leave it be. */\n               mod = pm->modifications;\n               while (mod != NULL)\n               {\n                  if (mod->chunk == chunk)\n                  {\n                     if (mod->modify_fn == NULL)\n                     {\n                        /* Remove this chunk */\n                        pm->buffer_count = pm->buffer_position = 0;\n                        mod->removed = 1;\n                        break; /* Terminate the while loop */\n                     }\n\n                     else if ((*mod->modify_fn)(pm, mod, 0))\n                     {\n                        mod->modified = 1;\n                        /* The chunk may have been removed: */\n                        if (pm->buffer_count == 0)\n                        {\n                           pm->buffer_position = 0;\n                           break;\n                        }\n                        modifier_setbuffer(pm);\n                     }\n                  }\n\n                  mod = mod->next;\n               }\n            }\n\n            else\n               pm->flush = len+12 - pm->buffer_count; /* data + crc */\n\n            /* Take the data from the buffer (if there is any). */\n            break;\n      }\n\n      /* Here to read from the modifier buffer (not directly from\n       * the store, as in the flush case above.)\n       */\n      cb = pm->buffer_count - pm->buffer_position;\n\n      if (cb > st)\n         cb = st;\n\n      memcpy(pb, pm->buffer + pm->buffer_position, cb);\n      st -= cb;\n      pb += cb;\n      pm->buffer_position += cb;\n   }\n}\n\n/* The callback: */\nstatic void PNGCBAPI\nmodifier_read(png_structp ppIn, png_bytep pb, png_size_t st)\n{\n   png_const_structp pp = ppIn;\n   png_modifier *pm = voidcast(png_modifier*, png_get_io_ptr(pp));\n\n   if (pm == NULL || pm->this.pread != pp)\n      png_error(pp, \"bad modifier_read call\");\n\n   modifier_read_imp(pm, pb, st);\n}\n\n/* Like store_progressive_read but the data is getting changed as we go so we\n * need a local buffer.\n */\nstatic void\nmodifier_progressive_read(png_modifier *pm, png_structp pp, png_infop pi)\n{\n   if (pm->this.pread != pp || pm->this.current == NULL ||\n       pm->this.next == NULL)\n      png_error(pp, \"store state damaged (progressive)\");\n\n   /* This is another Horowitz and Hill random noise generator.  In this case\n    * the aim is to stress the progressive reader with truly horrible variable\n    * buffer sizes in the range 1..500, so a sequence of 9 bit random numbers\n    * is generated.  We could probably just count from 1 to 32767 and get as\n    * good a result.\n    */\n   for (;;)\n   {\n      static png_uint_32 noise = 1;\n      png_size_t cb, cbAvail;\n      png_byte buffer[512];\n\n      /* Generate 15 more bits of stuff: */\n      noise = (noise << 9) | ((noise ^ (noise >> (9-5))) & 0x1ff);\n      cb = noise & 0x1ff;\n\n      /* Check that this number of bytes are available (in the current buffer.)\n       * (This doesn't quite work - the modifier might delete a chunk; unlikely\n       * but possible, it doesn't happen at present because the modifier only\n       * adds chunks to standard images.)\n       */\n      cbAvail = store_read_buffer_avail(&pm->this);\n      if (pm->buffer_count > pm->buffer_position)\n         cbAvail += pm->buffer_count - pm->buffer_position;\n\n      if (cb > cbAvail)\n      {\n         /* Check for EOF: */\n         if (cbAvail == 0)\n            break;\n\n         cb = cbAvail;\n      }\n\n      modifier_read_imp(pm, buffer, cb);\n      png_process_data(pp, pi, buffer, cb);\n   }\n\n   /* Check the invariants at the end (if this fails it's a problem in this\n    * file!)\n    */\n   if (pm->buffer_count > pm->buffer_position ||\n       pm->this.next != &pm->this.current->data ||\n       pm->this.readpos < pm->this.current->datacount)\n      png_error(pp, \"progressive read implementation error\");\n}\n\n/* Set up a modifier. */\nstatic png_structp\nset_modifier_for_read(png_modifier *pm, png_infopp ppi, png_uint_32 id,\n    const char *name)\n{\n   /* Do this first so that the modifier fields are cleared even if an error\n    * happens allocating the png_struct.  No allocation is done here so no\n    * cleanup is required.\n    */\n   pm->state = modifier_start;\n   pm->bit_depth = 0;\n   pm->colour_type = 255;\n\n   pm->pending_len = 0;\n   pm->pending_chunk = 0;\n   pm->flush = 0;\n   pm->buffer_count = 0;\n   pm->buffer_position = 0;\n\n   return set_store_for_read(&pm->this, ppi, id, name);\n}\n\n\n/******************************** MODIFICATIONS *******************************/\n/* Standard modifications to add chunks.  These do not require the _SUPPORTED\n * macros because the chunks can be there regardless of whether this specific\n * libpng supports them.\n */\ntypedef struct gama_modification\n{\n   png_modification this;\n   png_fixed_point  gamma;\n} gama_modification;\n\nstatic int\ngama_modify(png_modifier *pm, png_modification *me, int add)\n{\n   UNUSED(add)\n   /* This simply dumps the given gamma value into the buffer. */\n   png_save_uint_32(pm->buffer, 4);\n   png_save_uint_32(pm->buffer+4, CHUNK_gAMA);\n   png_save_uint_32(pm->buffer+8, ((gama_modification*)me)->gamma);\n   return 1;\n}\n\nstatic void\ngama_modification_init(gama_modification *me, png_modifier *pm, double gammad)\n{\n   double g;\n\n   modification_init(&me->this);\n   me->this.chunk = CHUNK_gAMA;\n   me->this.modify_fn = gama_modify;\n   me->this.add = CHUNK_PLTE;\n   g = fix(gammad);\n   me->gamma = (png_fixed_point)g;\n   me->this.next = pm->modifications;\n   pm->modifications = &me->this;\n}\n\ntypedef struct chrm_modification\n{\n   png_modification          this;\n   const color_encoding *encoding;\n   png_fixed_point           wx, wy, rx, ry, gx, gy, bx, by;\n} chrm_modification;\n\nstatic int\nchrm_modify(png_modifier *pm, png_modification *me, int add)\n{\n   UNUSED(add)\n   /* As with gAMA this just adds the required cHRM chunk to the buffer. */\n   png_save_uint_32(pm->buffer   , 32);\n   png_save_uint_32(pm->buffer+ 4, CHUNK_cHRM);\n   png_save_uint_32(pm->buffer+ 8, ((chrm_modification*)me)->wx);\n   png_save_uint_32(pm->buffer+12, ((chrm_modification*)me)->wy);\n   png_save_uint_32(pm->buffer+16, ((chrm_modification*)me)->rx);\n   png_save_uint_32(pm->buffer+20, ((chrm_modification*)me)->ry);\n   png_save_uint_32(pm->buffer+24, ((chrm_modification*)me)->gx);\n   png_save_uint_32(pm->buffer+28, ((chrm_modification*)me)->gy);\n   png_save_uint_32(pm->buffer+32, ((chrm_modification*)me)->bx);\n   png_save_uint_32(pm->buffer+36, ((chrm_modification*)me)->by);\n   return 1;\n}\n\nstatic void\nchrm_modification_init(chrm_modification *me, png_modifier *pm,\n   const color_encoding *encoding)\n{\n   CIE_color white = white_point(encoding);\n\n   /* Original end points: */\n   me->encoding = encoding;\n\n   /* Chromaticities (in fixed point): */\n   me->wx = fix(chromaticity_x(white));\n   me->wy = fix(chromaticity_y(white));\n\n   me->rx = fix(chromaticity_x(encoding->red));\n   me->ry = fix(chromaticity_y(encoding->red));\n   me->gx = fix(chromaticity_x(encoding->green));\n   me->gy = fix(chromaticity_y(encoding->green));\n   me->bx = fix(chromaticity_x(encoding->blue));\n   me->by = fix(chromaticity_y(encoding->blue));\n\n   modification_init(&me->this);\n   me->this.chunk = CHUNK_cHRM;\n   me->this.modify_fn = chrm_modify;\n   me->this.add = CHUNK_PLTE;\n   me->this.next = pm->modifications;\n   pm->modifications = &me->this;\n}\n\ntypedef struct srgb_modification\n{\n   png_modification this;\n   png_byte         intent;\n} srgb_modification;\n\nstatic int\nsrgb_modify(png_modifier *pm, png_modification *me, int add)\n{\n   UNUSED(add)\n   /* As above, ignore add and just make a new chunk */\n   png_save_uint_32(pm->buffer, 1);\n   png_save_uint_32(pm->buffer+4, CHUNK_sRGB);\n   pm->buffer[8] = ((srgb_modification*)me)->intent;\n   return 1;\n}\n\nstatic void\nsrgb_modification_init(srgb_modification *me, png_modifier *pm, png_byte intent)\n{\n   modification_init(&me->this);\n   me->this.chunk = CHUNK_sBIT;\n\n   if (intent <= 3) /* if valid, else *delete* sRGB chunks */\n   {\n      me->this.modify_fn = srgb_modify;\n      me->this.add = CHUNK_PLTE;\n      me->intent = intent;\n   }\n\n   else\n   {\n      me->this.modify_fn = 0;\n      me->this.add = 0;\n      me->intent = 0;\n   }\n\n   me->this.next = pm->modifications;\n   pm->modifications = &me->this;\n}\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\ntypedef struct sbit_modification\n{\n   png_modification this;\n   png_byte         sbit;\n} sbit_modification;\n\nstatic int\nsbit_modify(png_modifier *pm, png_modification *me, int add)\n{\n   png_byte sbit = ((sbit_modification*)me)->sbit;\n   if (pm->bit_depth > sbit)\n   {\n      int cb = 0;\n      switch (pm->colour_type)\n      {\n         case 0:\n            cb = 1;\n            break;\n\n         case 2:\n         case 3:\n            cb = 3;\n            break;\n\n         case 4:\n            cb = 2;\n            break;\n\n         case 6:\n            cb = 4;\n            break;\n\n         default:\n            png_error(pm->this.pread,\n               \"unexpected colour type in sBIT modification\");\n      }\n\n      png_save_uint_32(pm->buffer, cb);\n      png_save_uint_32(pm->buffer+4, CHUNK_sBIT);\n\n      while (cb > 0)\n         (pm->buffer+8)[--cb] = sbit;\n\n      return 1;\n   }\n   else if (!add)\n   {\n      /* Remove the sBIT chunk */\n      pm->buffer_count = pm->buffer_position = 0;\n      return 1;\n   }\n   else\n      return 0; /* do nothing */\n}\n\nstatic void\nsbit_modification_init(sbit_modification *me, png_modifier *pm, png_byte sbit)\n{\n   modification_init(&me->this);\n   me->this.chunk = CHUNK_sBIT;\n   me->this.modify_fn = sbit_modify;\n   me->this.add = CHUNK_PLTE;\n   me->sbit = sbit;\n   me->this.next = pm->modifications;\n   pm->modifications = &me->this;\n}\n#endif /* PNG_READ_GAMMA_SUPPORTED */\n#endif /* PNG_READ_TRANSFORMS_SUPPORTED */\n\n/***************************** STANDARD PNG FILES *****************************/\n/* Standard files - write and save standard files. */\n/* There are two basic forms of standard images.  Those which attempt to have\n * all the possible pixel values (not possible for 16bpp images, but a range of\n * values are produced) and those which have a range of image sizes.  The former\n * are used for testing transforms, in particular gamma correction and bit\n * reduction and increase.  The latter are reserved for testing the behavior of\n * libpng with respect to 'odd' image sizes - particularly small images where\n * rows become 1 byte and interlace passes disappear.\n *\n * The first, most useful, set are the 'transform' images, the second set of\n * small images are the 'size' images.\n *\n * The transform files are constructed with rows which fit into a 1024 byte row\n * buffer.  This makes allocation easier below.  Further regardless of the file\n * format every row has 128 pixels (giving 1024 bytes for 64bpp formats).\n *\n * Files are stored with no gAMA or sBIT chunks, with a PLTE only when needed\n * and with an ID derived from the colour type, bit depth and interlace type\n * as above (FILEID).  The width (128) and height (variable) are not stored in\n * the FILEID - instead the fields are set to 0, indicating a transform file.\n *\n * The size files ar constructed with rows a maximum of 128 bytes wide, allowing\n * a maximum width of 16 pixels (for the 64bpp case.)  They also have a maximum\n * height of 16 rows.  The width and height are stored in the FILEID and, being\n * non-zero, indicate a size file.\n *\n * Because the PNG filter code is typically the largest CPU consumer within\n * libpng itself there is a tendency to attempt to optimize it.  This results in\n * special case code which needs to be validated.  To cause this to happen the\n * 'size' images are made to use each possible filter, in so far as this is\n * possible for smaller images.\n *\n * For palette image (colour type 3) multiple transform images are stored with\n * the same bit depth to allow testing of more colour combinations -\n * particularly important for testing the gamma code because libpng uses a\n * different code path for palette images.  For size images a single palette is\n * used.\n */\n\n/* Make a 'standard' palette.  Because there are only 256 entries in a palette\n * (maximum) this actually makes a random palette in the hope that enough tests\n * will catch enough errors.  (Note that the same palette isn't produced every\n * time for the same test - it depends on what previous tests have been run -\n * but a given set of arguments to pngvalid will always produce the same palette\n * at the same test!  This is why pseudo-random number generators are useful for\n * testing.)\n *\n * The store must be open for write when this is called, otherwise an internal\n * error will occur.  This routine contains its own magic number seed, so the\n * palettes generated don't change if there are intervening errors (changing the\n * calls to the store_mark seed.)\n */\nstatic store_palette_entry *\nmake_standard_palette(png_store* ps, int npalette, int do_tRNS)\n{\n   static png_uint_32 palette_seed[2] = { 0x87654321, 9 };\n\n   int i = 0;\n   png_byte values[256][4];\n\n   /* Always put in black and white plus the six primary and secondary colors.\n    */\n   for (; i<8; ++i)\n   {\n      values[i][1] = (png_byte)((i&1) ? 255U : 0U);\n      values[i][2] = (png_byte)((i&2) ? 255U : 0U);\n      values[i][3] = (png_byte)((i&4) ? 255U : 0U);\n   }\n\n   /* Then add 62 grays (one quarter of the remaining 256 slots). */\n   {\n      int j = 0;\n      png_byte random_bytes[4];\n      png_byte need[256];\n\n      need[0] = 0; /*got black*/\n      memset(need+1, 1, (sizeof need)-2); /*need these*/\n      need[255] = 0; /*but not white*/\n\n      while (i<70)\n      {\n         png_byte b;\n\n         if (j==0)\n         {\n            make_four_random_bytes(palette_seed, random_bytes);\n            j = 4;\n         }\n\n         b = random_bytes[--j];\n         if (need[b])\n         {\n            values[i][1] = b;\n            values[i][2] = b;\n            values[i++][3] = b;\n         }\n      }\n   }\n\n   /* Finally add 192 colors at random - don't worry about matches to things we\n    * already have, chance is less than 1/65536.  Don't worry about grays,\n    * chance is the same, so we get a duplicate or extra gray less than 1 time\n    * in 170.\n    */\n   for (; i<256; ++i)\n      make_four_random_bytes(palette_seed, values[i]);\n\n   /* Fill in the alpha values in the first byte.  Just use all possible values\n    * (0..255) in an apparently random order:\n    */\n   {\n      store_palette_entry *palette;\n      png_byte selector[4];\n\n      make_four_random_bytes(palette_seed, selector);\n\n      if (do_tRNS)\n         for (i=0; i<256; ++i)\n            values[i][0] = (png_byte)(i ^ selector[0]);\n\n      else\n         for (i=0; i<256; ++i)\n            values[i][0] = 255; /* no transparency/tRNS chunk */\n\n      /* 'values' contains 256 ARGB values, but we only need 'npalette'.\n       * 'npalette' will always be a power of 2: 2, 4, 16 or 256.  In the low\n       * bit depth cases select colors at random, else it is difficult to have\n       * a set of low bit depth palette test with any chance of a reasonable\n       * range of colors.  Do this by randomly permuting values into the low\n       * 'npalette' entries using an XOR mask generated here.  This also\n       * permutes the npalette == 256 case in a potentially useful way (there is\n       * no relationship between palette index and the color value therein!)\n       */\n      palette = store_write_palette(ps, npalette);\n\n      for (i=0; i<npalette; ++i)\n      {\n         palette[i].alpha = values[i ^ selector[1]][0];\n         palette[i].red   = values[i ^ selector[1]][1];\n         palette[i].green = values[i ^ selector[1]][2];\n         palette[i].blue  = values[i ^ selector[1]][3];\n      }\n\n      return palette;\n   }\n}\n\n/* Initialize a standard palette on a write stream.  The 'do_tRNS' argument\n * indicates whether or not to also set the tRNS chunk.\n */\n/* TODO: the png_structp here can probably be 'const' in the future */\nstatic void\ninit_standard_palette(png_store *ps, png_structp pp, png_infop pi, int npalette,\n   int do_tRNS)\n{\n   store_palette_entry *ppal = make_standard_palette(ps, npalette, do_tRNS);\n\n   {\n      int i;\n      png_color palette[256];\n\n      /* Set all entries to detect overread errors. */\n      for (i=0; i<npalette; ++i)\n      {\n         palette[i].red = ppal[i].red;\n         palette[i].green = ppal[i].green;\n         palette[i].blue = ppal[i].blue;\n      }\n\n      /* Just in case fill in the rest with detectable values: */\n      for (; i<256; ++i)\n         palette[i].red = palette[i].green = palette[i].blue = 42;\n\n      png_set_PLTE(pp, pi, palette, npalette);\n   }\n\n   if (do_tRNS)\n   {\n      int i, j;\n      png_byte tRNS[256];\n\n      /* Set all the entries, but skip trailing opaque entries */\n      for (i=j=0; i<npalette; ++i)\n         if ((tRNS[i] = ppal[i].alpha) < 255)\n            j = i+1;\n\n      /* Fill in the remainder with a detectable value: */\n      for (; i<256; ++i)\n         tRNS[i] = 24;\n\n#     ifdef PNG_WRITE_tRNS_SUPPORTED\n         if (j > 0)\n            png_set_tRNS(pp, pi, tRNS, j, 0/*color*/);\n#     endif\n   }\n}\n\n#ifdef PNG_WRITE_tRNS_SUPPORTED\nstatic void\nset_random_tRNS(png_structp pp, png_infop pi, const png_byte colour_type,\n   const int bit_depth)\n{\n   /* To make this useful the tRNS color needs to match at least one pixel.\n    * Random values are fine for gray, including the 16-bit case where we know\n    * that the test image contains all the gray values.  For RGB we need more\n    * method as only 65536 different RGB values are generated.\n    */\n   png_color_16 tRNS;\n   const png_uint_16 mask = (png_uint_16)((1U << bit_depth)-1);\n\n   R8(tRNS); /* makes unset fields random */\n\n   if (colour_type & 2/*RGB*/)\n   {\n      if (bit_depth == 8)\n      {\n         R16(tRNS.red);\n         R16(tRNS.green);\n         tRNS.blue = tRNS.red ^ tRNS.green;\n         tRNS.red &= mask;\n         tRNS.green &= mask;\n         tRNS.blue &= mask;\n      }\n\n      else /* bit_depth == 16 */\n      {\n         R16(tRNS.red);\n         tRNS.green = (png_uint_16)(tRNS.red * 257);\n         tRNS.blue = (png_uint_16)(tRNS.green * 17);\n      }\n   }\n\n   else\n   {\n      R16(tRNS.gray);\n      tRNS.gray &= mask;\n   }\n\n   png_set_tRNS(pp, pi, NULL, 0, &tRNS);\n}\n#endif\n\n/* The number of passes is related to the interlace type. There was no libpng\n * API to determine this prior to 1.5, so we need an inquiry function:\n */\nstatic int\nnpasses_from_interlace_type(png_const_structp pp, int interlace_type)\n{\n   switch (interlace_type)\n   {\n   default:\n      png_error(pp, \"invalid interlace type\");\n\n   case PNG_INTERLACE_NONE:\n      return 1;\n\n   case PNG_INTERLACE_ADAM7:\n      return PNG_INTERLACE_ADAM7_PASSES;\n   }\n}\n\nstatic unsigned int\nbit_size(png_const_structp pp, png_byte colour_type, png_byte bit_depth)\n{\n   switch (colour_type)\n   {\n      default: png_error(pp, \"invalid color type\");\n\n      case 0:  return bit_depth;\n\n      case 2:  return 3*bit_depth;\n\n      case 3:  return bit_depth;\n\n      case 4:  return 2*bit_depth;\n\n      case 6:  return 4*bit_depth;\n   }\n}\n\n#define TRANSFORM_WIDTH  128U\n#define TRANSFORM_ROWMAX (TRANSFORM_WIDTH*8U)\n#define SIZE_ROWMAX (16*8U) /* 16 pixels, max 8 bytes each - 128 bytes */\n#define STANDARD_ROWMAX TRANSFORM_ROWMAX /* The larger of the two */\n#define SIZE_HEIGHTMAX 16 /* Maximum range of size images */\n\nstatic size_t\ntransform_rowsize(png_const_structp pp, png_byte colour_type,\n   png_byte bit_depth)\n{\n   return (TRANSFORM_WIDTH * bit_size(pp, colour_type, bit_depth)) / 8;\n}\n\n/* transform_width(pp, colour_type, bit_depth) current returns the same number\n * every time, so just use a macro:\n */\n#define transform_width(pp, colour_type, bit_depth) TRANSFORM_WIDTH\n\nstatic png_uint_32\ntransform_height(png_const_structp pp, png_byte colour_type, png_byte bit_depth)\n{\n   switch (bit_size(pp, colour_type, bit_depth))\n   {\n      case 1:\n      case 2:\n      case 4:\n         return 1;   /* Total of 128 pixels */\n\n      case 8:\n         return 2;   /* Total of 256 pixels/bytes */\n\n      case 16:\n         return 512; /* Total of 65536 pixels */\n\n      case 24:\n      case 32:\n         return 512; /* 65536 pixels */\n\n      case 48:\n      case 64:\n         return 2048;/* 4 x 65536 pixels. */\n#        define TRANSFORM_HEIGHTMAX 2048\n\n      default:\n         return 0;   /* Error, will be caught later */\n   }\n}\n\n#ifdef PNG_READ_SUPPORTED\n/* The following can only be defined here, now we have the definitions\n * of the transform image sizes.\n */\nstatic png_uint_32\nstandard_width(png_const_structp pp, png_uint_32 id)\n{\n   png_uint_32 width = WIDTH_FROM_ID(id);\n   UNUSED(pp)\n\n   if (width == 0)\n      width = transform_width(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));\n\n   return width;\n}\n\nstatic png_uint_32\nstandard_height(png_const_structp pp, png_uint_32 id)\n{\n   png_uint_32 height = HEIGHT_FROM_ID(id);\n\n   if (height == 0)\n      height = transform_height(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));\n\n   return height;\n}\n\nstatic png_uint_32\nstandard_rowsize(png_const_structp pp, png_uint_32 id)\n{\n   png_uint_32 width = standard_width(pp, id);\n\n   /* This won't overflow: */\n   width *= bit_size(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));\n   return (width + 7) / 8;\n}\n#endif /* PNG_READ_SUPPORTED */\n\nstatic void\ntransform_row(png_const_structp pp, png_byte buffer[TRANSFORM_ROWMAX],\n   png_byte colour_type, png_byte bit_depth, png_uint_32 y)\n{\n   png_uint_32 v = y << 7;\n   png_uint_32 i = 0;\n\n   switch (bit_size(pp, colour_type, bit_depth))\n   {\n      case 1:\n         while (i<128/8) buffer[i] = (png_byte)(v & 0xff), v += 17, ++i;\n         return;\n\n      case 2:\n         while (i<128/4) buffer[i] = (png_byte)(v & 0xff), v += 33, ++i;\n         return;\n\n      case 4:\n         while (i<128/2) buffer[i] = (png_byte)(v & 0xff), v += 65, ++i;\n         return;\n\n      case 8:\n         /* 256 bytes total, 128 bytes in each row set as follows: */\n         while (i<128) buffer[i] = (png_byte)(v & 0xff), ++v, ++i;\n         return;\n\n      case 16:\n         /* Generate all 65536 pixel values in order, which includes the 8 bit\n          * GA case as well as the 16 bit G case.\n          */\n         while (i<128)\n         {\n            buffer[2*i] = (png_byte)((v>>8) & 0xff);\n            buffer[2*i+1] = (png_byte)(v & 0xff);\n            ++v;\n            ++i;\n         }\n\n         return;\n\n      case 24:\n         /* 65535 pixels, but rotate the values. */\n         while (i<128)\n         {\n            /* Three bytes per pixel, r, g, b, make b by r^g */\n            buffer[3*i+0] = (png_byte)((v >> 8) & 0xff);\n            buffer[3*i+1] = (png_byte)(v & 0xff);\n            buffer[3*i+2] = (png_byte)(((v >> 8) ^ v) & 0xff);\n            ++v;\n            ++i;\n         }\n\n         return;\n\n      case 32:\n         /* 65535 pixels, r, g, b, a; just replicate */\n         while (i<128)\n         {\n            buffer[4*i+0] = (png_byte)((v >> 8) & 0xff);\n            buffer[4*i+1] = (png_byte)(v & 0xff);\n            buffer[4*i+2] = (png_byte)((v >> 8) & 0xff);\n            buffer[4*i+3] = (png_byte)(v & 0xff);\n            ++v;\n            ++i;\n         }\n\n         return;\n\n      case 48:\n         /* y is maximum 2047, giving 4x65536 pixels, make 'r' increase by 1 at\n          * each pixel, g increase by 257 (0x101) and 'b' by 0x1111:\n          */\n         while (i<128)\n         {\n            png_uint_32 t = v++;\n            buffer[6*i+0] = (png_byte)((t >> 8) & 0xff);\n            buffer[6*i+1] = (png_byte)(t & 0xff);\n            t *= 257;\n            buffer[6*i+2] = (png_byte)((t >> 8) & 0xff);\n            buffer[6*i+3] = (png_byte)(t & 0xff);\n            t *= 17;\n            buffer[6*i+4] = (png_byte)((t >> 8) & 0xff);\n            buffer[6*i+5] = (png_byte)(t & 0xff);\n            ++i;\n         }\n\n         return;\n\n      case 64:\n         /* As above in the 32 bit case. */\n         while (i<128)\n         {\n            png_uint_32 t = v++;\n            buffer[8*i+0] = (png_byte)((t >> 8) & 0xff);\n            buffer[8*i+1] = (png_byte)(t & 0xff);\n            buffer[8*i+4] = (png_byte)((t >> 8) & 0xff);\n            buffer[8*i+5] = (png_byte)(t & 0xff);\n            t *= 257;\n            buffer[8*i+2] = (png_byte)((t >> 8) & 0xff);\n            buffer[8*i+3] = (png_byte)(t & 0xff);\n            buffer[8*i+6] = (png_byte)((t >> 8) & 0xff);\n            buffer[8*i+7] = (png_byte)(t & 0xff);\n            ++i;\n         }\n         return;\n\n      default:\n         break;\n   }\n\n   png_error(pp, \"internal error\");\n}\n\n/* This is just to do the right cast - could be changed to a function to check\n * 'bd' but there isn't much point.\n */\n#define DEPTH(bd) ((png_byte)(1U << (bd)))\n\n/* This is just a helper for compiling on minimal systems with no write\n * interlacing support.  If there is no write interlacing we can't generate test\n * cases with interlace:\n */\n#ifdef PNG_WRITE_INTERLACING_SUPPORTED\n#  define INTERLACE_LAST PNG_INTERLACE_LAST\n#  define check_interlace_type(type) ((void)(type))\n#  define set_write_interlace_handling(pp,type) png_set_interlace_handling(pp)\n#  define do_own_interlace 0\n#elif PNG_LIBPNG_VER < 10700\n#  define set_write_interlace_handling(pp,type) (1)\nstatic void\ncheck_interlace_type(int const interlace_type)\n{\n   /* Prior to 1.7.0 libpng does not support the write of an interlaced image\n    * unless PNG_WRITE_INTERLACING_SUPPORTED, even with do_interlace so the\n    * code here does the pixel interlace itself, so:\n    */\n   if (interlace_type != PNG_INTERLACE_NONE)\n   {\n      /* This is an internal error - --interlace tests should be skipped, not\n       * attempted.\n       */\n      fprintf(stderr, \"pngvalid: no interlace support\\n\");\n      exit(99);\n   }\n}\n#  define INTERLACE_LAST (PNG_INTERLACE_NONE+1)\n#  define do_own_interlace 0\n#else /* libpng 1.7+ */\n#  define set_write_interlace_handling(pp,type)\\\n      npasses_from_interlace_type(pp,type)\n#  define check_interlace_type(type) ((void)(type))\n#  define INTERLACE_LAST PNG_INTERLACE_LAST\n#  define do_own_interlace 1\n#endif /* WRITE_INTERLACING tests */\n\n#define CAN_WRITE_INTERLACE\\\n   PNG_LIBPNG_VER >= 10700 || defined PNG_WRITE_INTERLACING_SUPPORTED\n\n/* Do the same thing for read interlacing; this controls whether read tests do\n * their own de-interlace or use libpng.\n */\n#ifdef PNG_READ_INTERLACING_SUPPORTED\n#  define do_read_interlace 0\n#else /* no libpng read interlace support */\n#  define do_read_interlace 1\n#endif\n/* The following two routines use the PNG interlace support macros from\n * png.h to interlace or deinterlace rows.\n */\nstatic void\ninterlace_row(png_bytep buffer, png_const_bytep imageRow,\n   unsigned int pixel_size, png_uint_32 w, int pass, int littleendian)\n{\n   png_uint_32 xin, xout, xstep;\n\n   /* Note that this can, trivially, be optimized to a memcpy on pass 7, the\n    * code is presented this way to make it easier to understand.  In practice\n    * consult the code in the libpng source to see other ways of doing this.\n    *\n    * It is OK for buffer and imageRow to be identical, because 'xin' moves\n    * faster than 'xout' and we copy up.\n    */\n   xin = PNG_PASS_START_COL(pass);\n   xstep = 1U<<PNG_PASS_COL_SHIFT(pass);\n\n   for (xout=0; xin<w; xin+=xstep)\n   {\n      pixel_copy(buffer, xout, imageRow, xin, pixel_size, littleendian);\n      ++xout;\n   }\n}\n\n#ifdef PNG_READ_SUPPORTED\nstatic void\ndeinterlace_row(png_bytep buffer, png_const_bytep row,\n   unsigned int pixel_size, png_uint_32 w, int pass, int littleendian)\n{\n   /* The inverse of the above, 'row' is part of row 'y' of the output image,\n    * in 'buffer'.  The image is 'w' wide and this is pass 'pass', distribute\n    * the pixels of row into buffer and return the number written (to allow\n    * this to be checked).\n    */\n   png_uint_32 xin, xout, xstep;\n\n   xout = PNG_PASS_START_COL(pass);\n   xstep = 1U<<PNG_PASS_COL_SHIFT(pass);\n\n   for (xin=0; xout<w; xout+=xstep)\n   {\n      pixel_copy(buffer, xout, row, xin, pixel_size, littleendian);\n      ++xin;\n   }\n}\n#endif /* PNG_READ_SUPPORTED */\n\n/* Make a standardized image given an image colour type, bit depth and\n * interlace type.  The standard images have a very restricted range of\n * rows and heights and are used for testing transforms rather than image\n * layout details.  See make_size_images below for a way to make images\n * that test odd sizes along with the libpng interlace handling.\n */\n#ifdef PNG_WRITE_FILTER_SUPPORTED\nstatic void\nchoose_random_filter(png_structp pp, int start)\n{\n   /* Choose filters randomly except that on the very first row ensure that\n    * there is at least one previous row filter.\n    */\n   int filters = PNG_ALL_FILTERS & random_mod(256U);\n\n   /* There may be no filters; skip the setting. */\n   if (filters != 0)\n   {\n      if (start && filters < PNG_FILTER_UP)\n         filters |= PNG_FILTER_UP;\n\n      png_set_filter(pp, 0/*method*/, filters);\n   }\n}\n#else /* !WRITE_FILTER */\n#  define choose_random_filter(pp, start) ((void)0)\n#endif /* !WRITE_FILTER */\n\nstatic void\nmake_transform_image(png_store* const ps, png_byte const colour_type,\n    png_byte const bit_depth, unsigned int palette_number,\n    int interlace_type, png_const_charp name)\n{\n   context(ps, fault);\n\n   check_interlace_type(interlace_type);\n\n   Try\n   {\n      png_infop pi;\n      png_structp pp = set_store_for_write(ps, &pi, name);\n      png_uint_32 h, w;\n\n      /* In the event of a problem return control to the Catch statement below\n       * to do the clean up - it is not possible to 'return' directly from a Try\n       * block.\n       */\n      if (pp == NULL)\n         Throw ps;\n\n      w = transform_width(pp, colour_type, bit_depth);\n      h = transform_height(pp, colour_type, bit_depth);\n\n      png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type,\n         PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);\n\n#ifdef PNG_TEXT_SUPPORTED\n#  if defined(PNG_READ_zTXt_SUPPORTED) && defined(PNG_WRITE_zTXt_SUPPORTED)\n#     define TEXT_COMPRESSION PNG_TEXT_COMPRESSION_zTXt\n#  else\n#     define TEXT_COMPRESSION PNG_TEXT_COMPRESSION_NONE\n#  endif\n      {\n         static char key[] = \"image name\"; /* must be writeable */\n         size_t pos;\n         png_text text;\n         char copy[FILE_NAME_SIZE];\n\n         /* Use a compressed text string to test the correct interaction of text\n          * compression and IDAT compression.\n          */\n         text.compression = TEXT_COMPRESSION;\n         text.key = key;\n         /* Yuck: the text must be writable! */\n         pos = safecat(copy, sizeof copy, 0, ps->wname);\n         text.text = copy;\n         text.text_length = pos;\n         text.itxt_length = 0;\n         text.lang = 0;\n         text.lang_key = 0;\n\n         png_set_text(pp, pi, &text, 1);\n      }\n#endif\n\n      if (colour_type == 3) /* palette */\n         init_standard_palette(ps, pp, pi, 1U << bit_depth, 1/*do tRNS*/);\n\n#     ifdef PNG_WRITE_tRNS_SUPPORTED\n         else if (palette_number)\n            set_random_tRNS(pp, pi, colour_type, bit_depth);\n#     endif\n\n      png_write_info(pp, pi);\n\n      if (png_get_rowbytes(pp, pi) !=\n          transform_rowsize(pp, colour_type, bit_depth))\n         png_error(pp, \"transform row size incorrect\");\n\n      else\n      {\n         /* Somewhat confusingly this must be called *after* png_write_info\n          * because if it is called before, the information in *pp has not been\n          * updated to reflect the interlaced image.\n          */\n         int npasses = set_write_interlace_handling(pp, interlace_type);\n         int pass;\n\n         if (npasses != npasses_from_interlace_type(pp, interlace_type))\n            png_error(pp, \"write: png_set_interlace_handling failed\");\n\n         for (pass=0; pass<npasses; ++pass)\n         {\n            png_uint_32 y;\n\n            /* do_own_interlace is a pre-defined boolean (a #define) which is\n             * set if we have to work out the interlaced rows here.\n             */\n            for (y=0; y<h; ++y)\n            {\n               png_byte buffer[TRANSFORM_ROWMAX];\n\n               transform_row(pp, buffer, colour_type, bit_depth, y);\n\n#              if do_own_interlace\n                  /* If do_own_interlace *and* the image is interlaced we need a\n                   * reduced interlace row; this may be reduced to empty.\n                   */\n                  if (interlace_type == PNG_INTERLACE_ADAM7)\n                  {\n                     /* The row must not be written if it doesn't exist, notice\n                      * that there are two conditions here, either the row isn't\n                      * ever in the pass or the row would be but isn't wide\n                      * enough to contribute any pixels.  In fact the wPass test\n                      * can be used to skip the whole y loop in this case.\n                      */\n                     if (PNG_ROW_IN_INTERLACE_PASS(y, pass) &&\n                         PNG_PASS_COLS(w, pass) > 0)\n                        interlace_row(buffer, buffer,\n                              bit_size(pp, colour_type, bit_depth), w, pass,\n                              0/*data always bigendian*/);\n                     else\n                        continue;\n                  }\n#              endif /* do_own_interlace */\n\n               choose_random_filter(pp, pass == 0 && y == 0);\n               png_write_row(pp, buffer);\n            }\n         }\n      }\n\n#ifdef PNG_TEXT_SUPPORTED\n      {\n         static char key[] = \"end marker\";\n         static char comment[] = \"end\";\n         png_text text;\n\n         /* Use a compressed text string to test the correct interaction of text\n          * compression and IDAT compression.\n          */\n         text.compression = TEXT_COMPRESSION;\n         text.key = key;\n         text.text = comment;\n         text.text_length = (sizeof comment)-1;\n         text.itxt_length = 0;\n         text.lang = 0;\n         text.lang_key = 0;\n\n         png_set_text(pp, pi, &text, 1);\n      }\n#endif\n\n      png_write_end(pp, pi);\n\n      /* And store this under the appropriate id, then clean up. */\n      store_storefile(ps, FILEID(colour_type, bit_depth, palette_number,\n         interlace_type, 0, 0, 0));\n\n      store_write_reset(ps);\n   }\n\n   Catch(fault)\n   {\n      /* Use the png_store returned by the exception. This may help the compiler\n       * because 'ps' is not used in this branch of the setjmp.  Note that fault\n       * and ps will always be the same value.\n       */\n      store_write_reset(fault);\n   }\n}\n\nstatic void\nmake_transform_images(png_modifier *pm)\n{\n   png_byte colour_type = 0;\n   png_byte bit_depth = 0;\n   unsigned int palette_number = 0;\n\n   /* This is in case of errors. */\n   safecat(pm->this.test, sizeof pm->this.test, 0, \"make standard images\");\n\n   /* Use next_format to enumerate all the combinations we test, including\n    * generating multiple low bit depth palette images. Non-A images (palette\n    * and direct) are created with and without tRNS chunks.\n    */\n   while (next_format(&colour_type, &bit_depth, &palette_number, 1, 1))\n   {\n      int interlace_type;\n\n      for (interlace_type = PNG_INTERLACE_NONE;\n           interlace_type < INTERLACE_LAST; ++interlace_type)\n      {\n         char name[FILE_NAME_SIZE];\n\n         standard_name(name, sizeof name, 0, colour_type, bit_depth,\n            palette_number, interlace_type, 0, 0, do_own_interlace);\n         make_transform_image(&pm->this, colour_type, bit_depth, palette_number,\n            interlace_type, name);\n      }\n   }\n}\n\n/* Build a single row for the 'size' test images; this fills in only the\n * first bit_width bits of the sample row.\n */\nstatic void\nsize_row(png_byte buffer[SIZE_ROWMAX], png_uint_32 bit_width, png_uint_32 y)\n{\n   /* height is in the range 1 to 16, so: */\n   y = ((y & 1) << 7) + ((y & 2) << 6) + ((y & 4) << 5) + ((y & 8) << 4);\n   /* the following ensures bits are set in small images: */\n   y ^= 0xA5;\n\n   while (bit_width >= 8)\n      *buffer++ = (png_byte)y++, bit_width -= 8;\n\n   /* There may be up to 7 remaining bits, these go in the most significant\n    * bits of the byte.\n    */\n   if (bit_width > 0)\n   {\n      png_uint_32 mask = (1U<<(8-bit_width))-1;\n      *buffer = (png_byte)((*buffer & mask) | (y & ~mask));\n   }\n}\n\nstatic void\nmake_size_image(png_store* const ps, png_byte const colour_type,\n    png_byte const bit_depth, int const interlace_type,\n    png_uint_32 const w, png_uint_32 const h,\n    int const do_interlace)\n{\n   context(ps, fault);\n\n   check_interlace_type(interlace_type);\n\n   Try\n   {\n      png_infop pi;\n      png_structp pp;\n      unsigned int pixel_size;\n\n      /* Make a name and get an appropriate id for the store: */\n      char name[FILE_NAME_SIZE];\n      const png_uint_32 id = FILEID(colour_type, bit_depth, 0/*palette*/,\n         interlace_type, w, h, do_interlace);\n\n      standard_name_from_id(name, sizeof name, 0, id);\n      pp = set_store_for_write(ps, &pi, name);\n\n      /* In the event of a problem return control to the Catch statement below\n       * to do the clean up - it is not possible to 'return' directly from a Try\n       * block.\n       */\n      if (pp == NULL)\n         Throw ps;\n\n      png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type,\n         PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);\n\n#ifdef PNG_TEXT_SUPPORTED\n      {\n         static char key[] = \"image name\"; /* must be writeable */\n         size_t pos;\n         png_text text;\n         char copy[FILE_NAME_SIZE];\n\n         /* Use a compressed text string to test the correct interaction of text\n          * compression and IDAT compression.\n          */\n         text.compression = TEXT_COMPRESSION;\n         text.key = key;\n         /* Yuck: the text must be writable! */\n         pos = safecat(copy, sizeof copy, 0, ps->wname);\n         text.text = copy;\n         text.text_length = pos;\n         text.itxt_length = 0;\n         text.lang = 0;\n         text.lang_key = 0;\n\n         png_set_text(pp, pi, &text, 1);\n      }\n#endif\n\n      if (colour_type == 3) /* palette */\n         init_standard_palette(ps, pp, pi, 1U << bit_depth, 0/*do tRNS*/);\n\n      png_write_info(pp, pi);\n\n      /* Calculate the bit size, divide by 8 to get the byte size - this won't\n       * overflow because we know the w values are all small enough even for\n       * a system where 'unsigned int' is only 16 bits.\n       */\n      pixel_size = bit_size(pp, colour_type, bit_depth);\n      if (png_get_rowbytes(pp, pi) != ((w * pixel_size) + 7) / 8)\n         png_error(pp, \"size row size incorrect\");\n\n      else\n      {\n         int npasses = npasses_from_interlace_type(pp, interlace_type);\n         png_uint_32 y;\n         int pass;\n         png_byte image[16][SIZE_ROWMAX];\n\n         /* To help consistent error detection make the parts of this buffer\n          * that aren't set below all '1':\n          */\n         memset(image, 0xff, sizeof image);\n\n         if (!do_interlace &&\n             npasses != set_write_interlace_handling(pp, interlace_type))\n            png_error(pp, \"write: png_set_interlace_handling failed\");\n\n         /* Prepare the whole image first to avoid making it 7 times: */\n         for (y=0; y<h; ++y)\n            size_row(image[y], w * pixel_size, y);\n\n         for (pass=0; pass<npasses; ++pass)\n         {\n            /* The following two are for checking the macros: */\n            const png_uint_32 wPass = PNG_PASS_COLS(w, pass);\n\n            /* If do_interlace is set we don't call png_write_row for every\n             * row because some of them are empty.  In fact, for a 1x1 image,\n             * most of them are empty!\n             */\n            for (y=0; y<h; ++y)\n            {\n               png_const_bytep row = image[y];\n               png_byte tempRow[SIZE_ROWMAX];\n\n               /* If do_interlace *and* the image is interlaced we\n                * need a reduced interlace row; this may be reduced\n                * to empty.\n                */\n               if (do_interlace && interlace_type == PNG_INTERLACE_ADAM7)\n               {\n                  /* The row must not be written if it doesn't exist, notice\n                   * that there are two conditions here, either the row isn't\n                   * ever in the pass or the row would be but isn't wide\n                   * enough to contribute any pixels.  In fact the wPass test\n                   * can be used to skip the whole y loop in this case.\n                   */\n                  if (PNG_ROW_IN_INTERLACE_PASS(y, pass) && wPass > 0)\n                  {\n                     /* Set to all 1's for error detection (libpng tends to\n                      * set unset things to 0).\n                      */\n                     memset(tempRow, 0xff, sizeof tempRow);\n                     interlace_row(tempRow, row, pixel_size, w, pass,\n                           0/*data always bigendian*/);\n                     row = tempRow;\n                  }\n                  else\n                     continue;\n               }\n\n#           ifdef PNG_WRITE_FILTER_SUPPORTED\n               /* Only get to here if the row has some pixels in it, set the\n                * filters to 'all' for the very first row and thereafter to a\n                * single filter.  It isn't well documented, but png_set_filter\n                * does accept a filter number (per the spec) as well as a bit\n                * mask.\n                *\n                * The code now uses filters at random, except that on the first\n                * row of an image it ensures that a previous row filter is in\n                * the set so that libpng allocates the row buffer.\n                */\n               {\n                  int filters = 8 << random_mod(PNG_FILTER_VALUE_LAST);\n\n                  if (pass == 0 && y == 0 &&\n                      (filters < PNG_FILTER_UP || w == 1U))\n                     filters |= PNG_FILTER_UP;\n\n                  png_set_filter(pp, 0/*method*/, filters);\n               }\n#           endif\n\n               png_write_row(pp, row);\n            }\n         }\n      }\n\n#ifdef PNG_TEXT_SUPPORTED\n      {\n         static char key[] = \"end marker\";\n         static char comment[] = \"end\";\n         png_text text;\n\n         /* Use a compressed text string to test the correct interaction of text\n          * compression and IDAT compression.\n          */\n         text.compression = TEXT_COMPRESSION;\n         text.key = key;\n         text.text = comment;\n         text.text_length = (sizeof comment)-1;\n         text.itxt_length = 0;\n         text.lang = 0;\n         text.lang_key = 0;\n\n         png_set_text(pp, pi, &text, 1);\n      }\n#endif\n\n      png_write_end(pp, pi);\n\n      /* And store this under the appropriate id, then clean up. */\n      store_storefile(ps, id);\n\n      store_write_reset(ps);\n   }\n\n   Catch(fault)\n   {\n      /* Use the png_store returned by the exception. This may help the compiler\n       * because 'ps' is not used in this branch of the setjmp.  Note that fault\n       * and ps will always be the same value.\n       */\n      store_write_reset(fault);\n   }\n}\n\nstatic void\nmake_size(png_store* const ps, png_byte const colour_type, int bdlo,\n    int const bdhi)\n{\n   for (; bdlo <= bdhi; ++bdlo)\n   {\n      png_uint_32 width;\n\n      for (width = 1; width <= 16; ++width)\n      {\n         png_uint_32 height;\n\n         for (height = 1; height <= 16; ++height)\n         {\n            /* The four combinations of DIY interlace and interlace or not -\n             * no interlace + DIY should be identical to no interlace with\n             * libpng doing it.\n             */\n            make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE,\n               width, height, 0);\n            make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE,\n               width, height, 1);\n#        ifdef PNG_WRITE_INTERLACING_SUPPORTED\n            make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,\n               width, height, 0);\n#        endif\n#        if CAN_WRITE_INTERLACE\n            /* 1.7.0 removes the hack that prevented app write of an interlaced\n             * image if WRITE_INTERLACE was not supported\n             */\n            make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,\n               width, height, 1);\n#        endif\n         }\n      }\n   }\n}\n\nstatic void\nmake_size_images(png_store *ps)\n{\n   /* This is in case of errors. */\n   safecat(ps->test, sizeof ps->test, 0, \"make size images\");\n\n   /* Arguments are colour_type, low bit depth, high bit depth\n    */\n   make_size(ps, 0, 0, WRITE_BDHI);\n   make_size(ps, 2, 3, WRITE_BDHI);\n   make_size(ps, 3, 0, 3 /*palette: max 8 bits*/);\n   make_size(ps, 4, 3, WRITE_BDHI);\n   make_size(ps, 6, 3, WRITE_BDHI);\n}\n\n#ifdef PNG_READ_SUPPORTED\n/* Return a row based on image id and 'y' for checking: */\nstatic void\nstandard_row(png_const_structp pp, png_byte std[STANDARD_ROWMAX],\n   png_uint_32 id, png_uint_32 y)\n{\n   if (WIDTH_FROM_ID(id) == 0)\n      transform_row(pp, std, COL_FROM_ID(id), DEPTH_FROM_ID(id), y);\n   else\n      size_row(std, WIDTH_FROM_ID(id) * bit_size(pp, COL_FROM_ID(id),\n         DEPTH_FROM_ID(id)), y);\n}\n#endif /* PNG_READ_SUPPORTED */\n\n/* Tests - individual test cases */\n/* Like 'make_standard' but errors are deliberately introduced into the calls\n * to ensure that they get detected - it should not be possible to write an\n * invalid image with libpng!\n */\n/* TODO: the 'set' functions can probably all be made to take a\n * png_const_structp rather than a modifiable one.\n */\n#ifdef PNG_WARNINGS_SUPPORTED\nstatic void\nsBIT0_error_fn(png_structp pp, png_infop pi)\n{\n   /* 0 is invalid... */\n   png_color_8 bad;\n   bad.red = bad.green = bad.blue = bad.gray = bad.alpha = 0;\n   png_set_sBIT(pp, pi, &bad);\n}\n\nstatic void\nsBIT_error_fn(png_structp pp, png_infop pi)\n{\n   png_byte bit_depth;\n   png_color_8 bad;\n\n   if (png_get_color_type(pp, pi) == PNG_COLOR_TYPE_PALETTE)\n      bit_depth = 8;\n\n   else\n      bit_depth = png_get_bit_depth(pp, pi);\n\n   /* Now we know the bit depth we can easily generate an invalid sBIT entry */\n   bad.red = bad.green = bad.blue = bad.gray = bad.alpha =\n      (png_byte)(bit_depth+1);\n   png_set_sBIT(pp, pi, &bad);\n}\n\nstatic const struct\n{\n   void          (*fn)(png_structp, png_infop);\n   const char *msg;\n   unsigned int    warning :1; /* the error is a warning... */\n} error_test[] =\n    {\n       /* no warnings makes these errors undetectable prior to 1.7.0 */\n       { sBIT0_error_fn, \"sBIT(0): failed to detect error\",\n         PNG_LIBPNG_VER < 10700 },\n\n       { sBIT_error_fn, \"sBIT(too big): failed to detect error\",\n         PNG_LIBPNG_VER < 10700 },\n    };\n\nstatic void\nmake_error(png_store* const ps, png_byte const colour_type,\n    png_byte bit_depth, int interlace_type, int test, png_const_charp name)\n{\n   context(ps, fault);\n\n   check_interlace_type(interlace_type);\n\n   Try\n   {\n      png_infop pi;\n      const png_structp pp = set_store_for_write(ps, &pi, name);\n      png_uint_32 w, h;\n      gnu_volatile(pp)\n\n      if (pp == NULL)\n         Throw ps;\n\n      w = transform_width(pp, colour_type, bit_depth);\n      gnu_volatile(w)\n      h = transform_height(pp, colour_type, bit_depth);\n      gnu_volatile(h)\n      png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type,\n            PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);\n\n      if (colour_type == 3) /* palette */\n         init_standard_palette(ps, pp, pi, 1U << bit_depth, 0/*do tRNS*/);\n\n      /* Time for a few errors; these are in various optional chunks, the\n       * standard tests test the standard chunks pretty well.\n       */\n#     define exception__prev exception_prev_1\n#     define exception__env exception_env_1\n      Try\n      {\n         gnu_volatile(exception__prev)\n\n         /* Expect this to throw: */\n         ps->expect_error = !error_test[test].warning;\n         ps->expect_warning = error_test[test].warning;\n         ps->saw_warning = 0;\n         error_test[test].fn(pp, pi);\n\n         /* Normally the error is only detected here: */\n         png_write_info(pp, pi);\n\n         /* And handle the case where it was only a warning: */\n         if (ps->expect_warning && ps->saw_warning)\n            Throw ps;\n\n         /* If we get here there is a problem, we have success - no error or\n          * no warning - when we shouldn't have success.  Log an error.\n          */\n         store_log(ps, pp, error_test[test].msg, 1 /*error*/);\n      }\n\n      Catch (fault)\n      { /* expected exit */\n      }\n#undef exception__prev\n#undef exception__env\n\n      /* And clear these flags */\n      ps->expect_warning = 0;\n\n      if (ps->expect_error)\n         ps->expect_error = 0;\n\n      else\n      {\n         /* Now write the whole image, just to make sure that the detected, or\n          * undetected, errro has not created problems inside libpng.  This\n          * doesn't work if there was a png_error in png_write_info because that\n          * can abort before PLTE was written.\n          */\n         if (png_get_rowbytes(pp, pi) !=\n             transform_rowsize(pp, colour_type, bit_depth))\n            png_error(pp, \"row size incorrect\");\n\n         else\n         {\n            int npasses = set_write_interlace_handling(pp, interlace_type);\n            int pass;\n\n            if (npasses != npasses_from_interlace_type(pp, interlace_type))\n               png_error(pp, \"write: png_set_interlace_handling failed\");\n\n            for (pass=0; pass<npasses; ++pass)\n            {\n               png_uint_32 y;\n\n               for (y=0; y<h; ++y)\n               {\n                  png_byte buffer[TRANSFORM_ROWMAX];\n\n                  transform_row(pp, buffer, colour_type, bit_depth, y);\n\n#                 if do_own_interlace\n                     /* If do_own_interlace *and* the image is interlaced we\n                      * need a reduced interlace row; this may be reduced to\n                      * empty.\n                      */\n                     if (interlace_type == PNG_INTERLACE_ADAM7)\n                     {\n                        /* The row must not be written if it doesn't exist,\n                         * notice that there are two conditions here, either the\n                         * row isn't ever in the pass or the row would be but\n                         * isn't wide enough to contribute any pixels.  In fact\n                         * the wPass test can be used to skip the whole y loop\n                         * in this case.\n                         */\n                        if (PNG_ROW_IN_INTERLACE_PASS(y, pass) &&\n                            PNG_PASS_COLS(w, pass) > 0)\n                           interlace_row(buffer, buffer,\n                                 bit_size(pp, colour_type, bit_depth), w, pass,\n                                 0/*data always bigendian*/);\n                        else\n                           continue;\n                     }\n#                 endif /* do_own_interlace */\n\n                  png_write_row(pp, buffer);\n               }\n            }\n         } /* image writing */\n\n         png_write_end(pp, pi);\n      }\n\n      /* The following deletes the file that was just written. */\n      store_write_reset(ps);\n   }\n\n   Catch(fault)\n   {\n      store_write_reset(fault);\n   }\n}\n\nstatic int\nmake_errors(png_modifier* const pm, png_byte const colour_type,\n    int bdlo, int const bdhi)\n{\n   for (; bdlo <= bdhi; ++bdlo)\n   {\n      int interlace_type;\n\n      for (interlace_type = PNG_INTERLACE_NONE;\n           interlace_type < INTERLACE_LAST; ++interlace_type)\n      {\n         unsigned int test;\n         char name[FILE_NAME_SIZE];\n\n         standard_name(name, sizeof name, 0, colour_type, 1<<bdlo, 0,\n            interlace_type, 0, 0, do_own_interlace);\n\n         for (test=0; test<ARRAY_SIZE(error_test); ++test)\n         {\n            make_error(&pm->this, colour_type, DEPTH(bdlo), interlace_type,\n               test, name);\n\n            if (fail(pm))\n               return 0;\n         }\n      }\n   }\n\n   return 1; /* keep going */\n}\n#endif /* PNG_WARNINGS_SUPPORTED */\n\nstatic void\nperform_error_test(png_modifier *pm)\n{\n#ifdef PNG_WARNINGS_SUPPORTED /* else there are no cases that work! */\n   /* Need to do this here because we just write in this test. */\n   safecat(pm->this.test, sizeof pm->this.test, 0, \"error test\");\n\n   if (!make_errors(pm, 0, 0, WRITE_BDHI))\n      return;\n\n   if (!make_errors(pm, 2, 3, WRITE_BDHI))\n      return;\n\n   if (!make_errors(pm, 3, 0, 3))\n      return;\n\n   if (!make_errors(pm, 4, 3, WRITE_BDHI))\n      return;\n\n   if (!make_errors(pm, 6, 3, WRITE_BDHI))\n      return;\n#else\n   UNUSED(pm)\n#endif\n}\n\n/* This is just to validate the internal PNG formatting code - if this fails\n * then the warning messages the library outputs will probably be garbage.\n */\nstatic void\nperform_formatting_test(png_store *ps)\n{\n#ifdef PNG_TIME_RFC1123_SUPPORTED\n   /* The handle into the formatting code is the RFC1123 support; this test does\n    * nothing if that is compiled out.\n    */\n   context(ps, fault);\n\n   Try\n   {\n      png_const_charp correct = \"29 Aug 2079 13:53:60 +0000\";\n      png_const_charp result;\n#     if PNG_LIBPNG_VER >= 10600\n         char timestring[29];\n#     endif\n      png_structp pp;\n      png_time pt;\n\n      pp = set_store_for_write(ps, NULL, \"libpng formatting test\");\n\n      if (pp == NULL)\n         Throw ps;\n\n\n      /* Arbitrary settings: */\n      pt.year = 2079;\n      pt.month = 8;\n      pt.day = 29;\n      pt.hour = 13;\n      pt.minute = 53;\n      pt.second = 60; /* a leap second */\n\n#     if PNG_LIBPNG_VER < 10600\n         result = png_convert_to_rfc1123(pp, &pt);\n#     else\n         if (png_convert_to_rfc1123_buffer(timestring, &pt))\n            result = timestring;\n\n         else\n            result = NULL;\n#     endif\n\n      if (result == NULL)\n         png_error(pp, \"png_convert_to_rfc1123 failed\");\n\n      if (strcmp(result, correct) != 0)\n      {\n         size_t pos = 0;\n         char msg[128];\n\n         pos = safecat(msg, sizeof msg, pos, \"png_convert_to_rfc1123(\");\n         pos = safecat(msg, sizeof msg, pos, correct);\n         pos = safecat(msg, sizeof msg, pos, \") returned: '\");\n         pos = safecat(msg, sizeof msg, pos, result);\n         pos = safecat(msg, sizeof msg, pos, \"'\");\n\n         png_error(pp, msg);\n      }\n\n      store_write_reset(ps);\n   }\n\n   Catch(fault)\n   {\n      store_write_reset(fault);\n   }\n#else\n   UNUSED(ps)\n#endif\n}\n\n#ifdef PNG_READ_SUPPORTED\n/* Because we want to use the same code in both the progressive reader and the\n * sequential reader it is necessary to deal with the fact that the progressive\n * reader callbacks only have one parameter (png_get_progressive_ptr()), so this\n * must contain all the test parameters and all the local variables directly\n * accessible to the sequential reader implementation.\n *\n * The technique adopted is to reinvent part of what Dijkstra termed a\n * 'display'; an array of pointers to the stack frames of enclosing functions so\n * that a nested function definition can access the local (C auto) variables of\n * the functions that contain its definition.  In fact C provides the first\n * pointer (the local variables - the stack frame pointer) and the last (the\n * global variables - the BCPL global vector typically implemented as global\n * addresses), this code requires one more pointer to make the display - the\n * local variables (and function call parameters) of the function that actually\n * invokes either the progressive or sequential reader.\n *\n * Perhaps confusingly this technique is confounded with classes - the\n * 'standard_display' defined here is sub-classed as the 'gamma_display' below.\n * A gamma_display is a standard_display, taking advantage of the ANSI-C\n * requirement that the pointer to the first member of a structure must be the\n * same as the pointer to the structure.  This allows us to reuse standard_\n * functions in the gamma test code; something that could not be done with\n * nested functions!\n */\ntypedef struct standard_display\n{\n   png_store*  ps;             /* Test parameters (passed to the function) */\n   png_byte    colour_type;\n   png_byte    bit_depth;\n   png_byte    red_sBIT;       /* Input data sBIT values. */\n   png_byte    green_sBIT;\n   png_byte    blue_sBIT;\n   png_byte    alpha_sBIT;\n   png_byte    interlace_type;\n   png_byte    filler;         /* Output has a filler */\n   png_uint_32 id;             /* Calculated file ID */\n   png_uint_32 w;              /* Width of image */\n   png_uint_32 h;              /* Height of image */\n   int         npasses;        /* Number of interlaced passes */\n   png_uint_32 pixel_size;     /* Width of one pixel in bits */\n   png_uint_32 bit_width;      /* Width of output row in bits */\n   size_t      cbRow;          /* Bytes in a row of the output image */\n   int         do_interlace;   /* Do interlacing internally */\n   int         littleendian;   /* App (row) data is little endian */\n   int         is_transparent; /* Transparency information was present. */\n   int         has_tRNS;       /* color type GRAY or RGB with a tRNS chunk. */\n   int         speed;          /* Doing a speed test */\n   int         use_update_info;/* Call update_info, not start_image */\n   struct\n   {\n      png_uint_16 red;\n      png_uint_16 green;\n      png_uint_16 blue;\n   }           transparent;    /* The transparent color, if set. */\n   int         npalette;       /* Number of entries in the palette. */\n   store_palette\n               palette;\n} standard_display;\n\nstatic void\nstandard_display_init(standard_display *dp, png_store* ps, png_uint_32 id,\n   int do_interlace, int use_update_info)\n{\n   memset(dp, 0, sizeof *dp);\n\n   dp->ps = ps;\n   dp->colour_type = COL_FROM_ID(id);\n   dp->bit_depth = DEPTH_FROM_ID(id);\n   if (dp->bit_depth < 1 || dp->bit_depth > 16)\n      internal_error(ps, \"internal: bad bit depth\");\n   if (dp->colour_type == 3)\n      dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT = 8;\n   else\n      dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT =\n         dp->bit_depth;\n   dp->interlace_type = INTERLACE_FROM_ID(id);\n   check_interlace_type(dp->interlace_type);\n   dp->id = id;\n   /* All the rest are filled in after the read_info: */\n   dp->w = 0;\n   dp->h = 0;\n   dp->npasses = 0;\n   dp->pixel_size = 0;\n   dp->bit_width = 0;\n   dp->cbRow = 0;\n   dp->do_interlace = do_interlace;\n   dp->littleendian = 0;\n   dp->is_transparent = 0;\n   dp->speed = ps->speed;\n   dp->use_update_info = use_update_info;\n   dp->npalette = 0;\n   /* Preset the transparent color to black: */\n   memset(&dp->transparent, 0, sizeof dp->transparent);\n   /* Preset the palette to full intensity/opaque througout: */\n   memset(dp->palette, 0xff, sizeof dp->palette);\n}\n\n/* Initialize the palette fields - this must be done later because the palette\n * comes from the particular png_store_file that is selected.\n */\nstatic void\nstandard_palette_init(standard_display *dp)\n{\n   store_palette_entry *palette = store_current_palette(dp->ps, &dp->npalette);\n\n   /* The remaining entries remain white/opaque. */\n   if (dp->npalette > 0)\n   {\n      int i = dp->npalette;\n      memcpy(dp->palette, palette, i * sizeof *palette);\n\n      /* Check for a non-opaque palette entry: */\n      while (--i >= 0)\n         if (palette[i].alpha < 255)\n            break;\n\n#     ifdef __GNUC__\n         /* GCC can't handle the more obviously optimizable version. */\n         if (i >= 0)\n            dp->is_transparent = 1;\n         else\n            dp->is_transparent = 0;\n#     else\n         dp->is_transparent = (i >= 0);\n#     endif\n   }\n}\n\n/* Utility to read the palette from the PNG file and convert it into\n * store_palette format.  This returns 1 if there is any transparency in the\n * palette (it does not check for a transparent colour in the non-palette case.)\n */\nstatic int\nread_palette(store_palette palette, int *npalette, png_const_structp pp,\n   png_infop pi)\n{\n   png_colorp pal;\n   png_bytep trans_alpha;\n   int num;\n\n   pal = 0;\n   *npalette = -1;\n\n   if (png_get_PLTE(pp, pi, &pal, npalette) & PNG_INFO_PLTE)\n   {\n      int i = *npalette;\n\n      if (i <= 0 || i > 256)\n         png_error(pp, \"validate: invalid PLTE count\");\n\n      while (--i >= 0)\n      {\n         palette[i].red = pal[i].red;\n         palette[i].green = pal[i].green;\n         palette[i].blue = pal[i].blue;\n      }\n\n      /* Mark the remainder of the entries with a flag value (other than\n       * white/opaque which is the flag value stored above.)\n       */\n      memset(palette + *npalette, 126, (256-*npalette) * sizeof *palette);\n   }\n\n   else /* !png_get_PLTE */\n   {\n      if (*npalette != (-1))\n         png_error(pp, \"validate: invalid PLTE result\");\n      /* But there is no palette, so record this: */\n      *npalette = 0;\n      memset(palette, 113, sizeof (store_palette));\n   }\n\n   trans_alpha = 0;\n   num = 2; /* force error below */\n   if ((png_get_tRNS(pp, pi, &trans_alpha, &num, 0) & PNG_INFO_tRNS) != 0 &&\n      (trans_alpha != NULL || num != 1/*returns 1 for a transparent color*/) &&\n      /* Oops, if a palette tRNS gets expanded png_read_update_info (at least so\n       * far as 1.5.4) does not remove the trans_alpha pointer, only num_trans,\n       * so in the above call we get a success, we get a pointer (who knows what\n       * to) and we get num_trans == 0:\n       */\n      !(trans_alpha != NULL && num == 0)) /* TODO: fix this in libpng. */\n   {\n      int i;\n\n      /* Any of these are crash-worthy - given the implementation of\n       * png_get_tRNS up to 1.5 an app won't crash if it just checks the\n       * result above and fails to check that the variables it passed have\n       * actually been filled in!  Note that if the app were to pass the\n       * last, png_color_16p, variable too it couldn't rely on this.\n       */\n      if (trans_alpha == NULL || num <= 0 || num > 256 || num > *npalette)\n         png_error(pp, \"validate: unexpected png_get_tRNS (palette) result\");\n\n      for (i=0; i<num; ++i)\n         palette[i].alpha = trans_alpha[i];\n\n      for (num=*npalette; i<num; ++i)\n         palette[i].alpha = 255;\n\n      for (; i<256; ++i)\n         palette[i].alpha = 33; /* flag value */\n\n      return 1; /* transparency */\n   }\n\n   else\n   {\n      /* No palette transparency - just set the alpha channel to opaque. */\n      int i;\n\n      for (i=0, num=*npalette; i<num; ++i)\n         palette[i].alpha = 255;\n\n      for (; i<256; ++i)\n         palette[i].alpha = 55; /* flag value */\n\n      return 0; /* no transparency */\n   }\n}\n\n/* Utility to validate the palette if it should not have changed (the\n * non-transform case).\n */\nstatic void\nstandard_palette_validate(standard_display *dp, png_const_structp pp,\n   png_infop pi)\n{\n   int npalette;\n   store_palette palette;\n\n   if (read_palette(palette, &npalette, pp, pi) != dp->is_transparent)\n      png_error(pp, \"validate: palette transparency changed\");\n\n   if (npalette != dp->npalette)\n   {\n      size_t pos = 0;\n      char msg[64];\n\n      pos = safecat(msg, sizeof msg, pos, \"validate: palette size changed: \");\n      pos = safecatn(msg, sizeof msg, pos, dp->npalette);\n      pos = safecat(msg, sizeof msg, pos, \" -> \");\n      pos = safecatn(msg, sizeof msg, pos, npalette);\n      png_error(pp, msg);\n   }\n\n   {\n      int i = npalette; /* npalette is aliased */\n\n      while (--i >= 0)\n         if (palette[i].red != dp->palette[i].red ||\n            palette[i].green != dp->palette[i].green ||\n            palette[i].blue != dp->palette[i].blue ||\n            palette[i].alpha != dp->palette[i].alpha)\n            png_error(pp, \"validate: PLTE or tRNS chunk changed\");\n   }\n}\n\n/* By passing a 'standard_display' the progressive callbacks can be used\n * directly by the sequential code, the functions suffixed \"_imp\" are the\n * implementations, the functions without the suffix are the callbacks.\n *\n * The code for the info callback is split into two because this callback calls\n * png_read_update_info or png_start_read_image and what gets called depends on\n * whether the info needs updating (we want to test both calls in pngvalid.)\n */\nstatic void\nstandard_info_part1(standard_display *dp, png_structp pp, png_infop pi)\n{\n   if (png_get_bit_depth(pp, pi) != dp->bit_depth)\n      png_error(pp, \"validate: bit depth changed\");\n\n   if (png_get_color_type(pp, pi) != dp->colour_type)\n      png_error(pp, \"validate: color type changed\");\n\n   if (png_get_filter_type(pp, pi) != PNG_FILTER_TYPE_BASE)\n      png_error(pp, \"validate: filter type changed\");\n\n   if (png_get_interlace_type(pp, pi) != dp->interlace_type)\n      png_error(pp, \"validate: interlacing changed\");\n\n   if (png_get_compression_type(pp, pi) != PNG_COMPRESSION_TYPE_BASE)\n      png_error(pp, \"validate: compression type changed\");\n\n   dp->w = png_get_image_width(pp, pi);\n\n   if (dp->w != standard_width(pp, dp->id))\n      png_error(pp, \"validate: image width changed\");\n\n   dp->h = png_get_image_height(pp, pi);\n\n   if (dp->h != standard_height(pp, dp->id))\n      png_error(pp, \"validate: image height changed\");\n\n   /* Record (but don't check at present) the input sBIT according to the colour\n    * type information.\n    */\n   {\n      png_color_8p sBIT = 0;\n\n      if (png_get_sBIT(pp, pi, &sBIT) & PNG_INFO_sBIT)\n      {\n         int sBIT_invalid = 0;\n\n         if (sBIT == 0)\n            png_error(pp, \"validate: unexpected png_get_sBIT result\");\n\n         if (dp->colour_type & PNG_COLOR_MASK_COLOR)\n         {\n            if (sBIT->red == 0 || sBIT->red > dp->bit_depth)\n               sBIT_invalid = 1;\n            else\n               dp->red_sBIT = sBIT->red;\n\n            if (sBIT->green == 0 || sBIT->green > dp->bit_depth)\n               sBIT_invalid = 1;\n            else\n               dp->green_sBIT = sBIT->green;\n\n            if (sBIT->blue == 0 || sBIT->blue > dp->bit_depth)\n               sBIT_invalid = 1;\n            else\n               dp->blue_sBIT = sBIT->blue;\n         }\n\n         else /* !COLOR */\n         {\n            if (sBIT->gray == 0 || sBIT->gray > dp->bit_depth)\n               sBIT_invalid = 1;\n            else\n               dp->blue_sBIT = dp->green_sBIT = dp->red_sBIT = sBIT->gray;\n         }\n\n         /* All 8 bits in tRNS for a palette image are significant - see the\n          * spec.\n          */\n         if (dp->colour_type & PNG_COLOR_MASK_ALPHA)\n         {\n            if (sBIT->alpha == 0 || sBIT->alpha > dp->bit_depth)\n               sBIT_invalid = 1;\n            else\n               dp->alpha_sBIT = sBIT->alpha;\n         }\n\n         if (sBIT_invalid)\n            png_error(pp, \"validate: sBIT value out of range\");\n      }\n   }\n\n   /* Important: this is validating the value *before* any transforms have been\n    * put in place.  It doesn't matter for the standard tests, where there are\n    * no transforms, but it does for other tests where rowbytes may change after\n    * png_read_update_info.\n    */\n   if (png_get_rowbytes(pp, pi) != standard_rowsize(pp, dp->id))\n      png_error(pp, \"validate: row size changed\");\n\n   /* Validate the colour type 3 palette (this can be present on other color\n    * types.)\n    */\n   standard_palette_validate(dp, pp, pi);\n\n   /* In any case always check for a tranparent color (notice that the\n    * colour type 3 case must not give a successful return on the get_tRNS call\n    * with these arguments!)\n    */\n   {\n      png_color_16p trans_color = 0;\n\n      if (png_get_tRNS(pp, pi, 0, 0, &trans_color) & PNG_INFO_tRNS)\n      {\n         if (trans_color == 0)\n            png_error(pp, \"validate: unexpected png_get_tRNS (color) result\");\n\n         switch (dp->colour_type)\n         {\n         case 0:\n            dp->transparent.red = dp->transparent.green = dp->transparent.blue =\n               trans_color->gray;\n            dp->has_tRNS = 1;\n            break;\n\n         case 2:\n            dp->transparent.red = trans_color->red;\n            dp->transparent.green = trans_color->green;\n            dp->transparent.blue = trans_color->blue;\n            dp->has_tRNS = 1;\n            break;\n\n         case 3:\n            /* Not expected because it should result in the array case\n             * above.\n             */\n            png_error(pp, \"validate: unexpected png_get_tRNS result\");\n            break;\n\n         default:\n            png_error(pp, \"validate: invalid tRNS chunk with alpha image\");\n         }\n      }\n   }\n\n   /* Read the number of passes - expected to match the value used when\n    * creating the image (interlaced or not).  This has the side effect of\n    * turning on interlace handling (if do_interlace is not set.)\n    */\n   dp->npasses = npasses_from_interlace_type(pp, dp->interlace_type);\n   if (!dp->do_interlace)\n   {\n#     ifdef PNG_READ_INTERLACING_SUPPORTED\n         if (dp->npasses != png_set_interlace_handling(pp))\n            png_error(pp, \"validate: file changed interlace type\");\n#     else /* !READ_INTERLACING */\n         /* This should never happen: the relevant tests (!do_interlace) should\n          * not be run.\n          */\n         if (dp->npasses > 1)\n            png_error(pp, \"validate: no libpng interlace support\");\n#     endif /* !READ_INTERLACING */\n   }\n\n   /* Caller calls png_read_update_info or png_start_read_image now, then calls\n    * part2.\n    */\n}\n\n/* This must be called *after* the png_read_update_info call to get the correct\n * 'rowbytes' value, otherwise png_get_rowbytes will refer to the untransformed\n * image.\n */\nstatic void\nstandard_info_part2(standard_display *dp, png_const_structp pp,\n    png_const_infop pi, int nImages)\n{\n   /* Record cbRow now that it can be found. */\n   {\n      png_byte ct = png_get_color_type(pp, pi);\n      png_byte bd = png_get_bit_depth(pp, pi);\n\n      if (bd >= 8 && (ct == PNG_COLOR_TYPE_RGB || ct == PNG_COLOR_TYPE_GRAY) &&\n          dp->filler)\n          ct |= 4; /* handle filler as faked alpha channel */\n\n      dp->pixel_size = bit_size(pp, ct, bd);\n   }\n   dp->bit_width = png_get_image_width(pp, pi) * dp->pixel_size;\n   dp->cbRow = png_get_rowbytes(pp, pi);\n\n   /* Validate the rowbytes here again. */\n   if (dp->cbRow != (dp->bit_width+7)/8)\n      png_error(pp, \"bad png_get_rowbytes calculation\");\n\n   /* Then ensure there is enough space for the output image(s). */\n   store_ensure_image(dp->ps, pp, nImages, dp->cbRow, dp->h);\n}\n\nstatic void\nstandard_info_imp(standard_display *dp, png_structp pp, png_infop pi,\n    int nImages)\n{\n   /* Note that the validation routine has the side effect of turning on\n    * interlace handling in the subsequent code.\n    */\n   standard_info_part1(dp, pp, pi);\n\n   /* And the info callback has to call this (or png_read_update_info - see\n    * below in the png_modifier code for that variant.\n    */\n   if (dp->use_update_info)\n   {\n      /* For debugging the effect of multiple calls: */\n      int i = dp->use_update_info;\n      while (i-- > 0)\n         png_read_update_info(pp, pi);\n   }\n\n   else\n      png_start_read_image(pp);\n\n   /* Validate the height, width and rowbytes plus ensure that sufficient buffer\n    * exists for decoding the image.\n    */\n   standard_info_part2(dp, pp, pi, nImages);\n}\n\nstatic void PNGCBAPI\nstandard_info(png_structp pp, png_infop pi)\n{\n   standard_display *dp = voidcast(standard_display*,\n      png_get_progressive_ptr(pp));\n\n   /* Call with nImages==1 because the progressive reader can only produce one\n    * image.\n    */\n   standard_info_imp(dp, pp, pi, 1 /*only one image*/);\n}\n\nstatic void PNGCBAPI\nprogressive_row(png_structp ppIn, png_bytep new_row, png_uint_32 y, int pass)\n{\n   png_const_structp pp = ppIn;\n   const standard_display *dp = voidcast(standard_display*,\n      png_get_progressive_ptr(pp));\n\n   /* When handling interlacing some rows will be absent in each pass, the\n    * callback still gets called, but with a NULL pointer.  This is checked\n    * in the 'else' clause below.  We need our own 'cbRow', but we can't call\n    * png_get_rowbytes because we got no info structure.\n    */\n   if (new_row != NULL)\n   {\n      png_bytep row;\n\n      /* In the case where the reader doesn't do the interlace it gives\n       * us the y in the sub-image:\n       */\n      if (dp->do_interlace && dp->interlace_type == PNG_INTERLACE_ADAM7)\n      {\n#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED\n         /* Use this opportunity to validate the png 'current' APIs: */\n         if (y != png_get_current_row_number(pp))\n            png_error(pp, \"png_get_current_row_number is broken\");\n\n         if (pass != png_get_current_pass_number(pp))\n            png_error(pp, \"png_get_current_pass_number is broken\");\n#endif /* USER_TRANSFORM_INFO */\n\n         y = PNG_ROW_FROM_PASS_ROW(y, pass);\n      }\n\n      /* Validate this just in case. */\n      if (y >= dp->h)\n         png_error(pp, \"invalid y to progressive row callback\");\n\n      row = store_image_row(dp->ps, pp, 0, y);\n\n      /* Combine the new row into the old: */\n#ifdef PNG_READ_INTERLACING_SUPPORTED\n      if (dp->do_interlace)\n#endif /* READ_INTERLACING */\n      {\n         if (dp->interlace_type == PNG_INTERLACE_ADAM7)\n            deinterlace_row(row, new_row, dp->pixel_size, dp->w, pass,\n                  dp->littleendian);\n         else\n            row_copy(row, new_row, dp->pixel_size * dp->w, dp->littleendian);\n      }\n#ifdef PNG_READ_INTERLACING_SUPPORTED\n      else\n         png_progressive_combine_row(pp, row, new_row);\n#endif /* PNG_READ_INTERLACING_SUPPORTED */\n   }\n\n   else if (dp->interlace_type == PNG_INTERLACE_ADAM7 &&\n       PNG_ROW_IN_INTERLACE_PASS(y, pass) &&\n       PNG_PASS_COLS(dp->w, pass) > 0)\n      png_error(pp, \"missing row in progressive de-interlacing\");\n}\n\nstatic void\nsequential_row(standard_display *dp, png_structp pp, png_infop pi,\n    const int iImage, const int iDisplay)\n{\n   const int         npasses = dp->npasses;\n   const int         do_interlace = dp->do_interlace &&\n      dp->interlace_type == PNG_INTERLACE_ADAM7;\n   const png_uint_32 height = standard_height(pp, dp->id);\n   const png_uint_32 width = standard_width(pp, dp->id);\n   const png_store*  ps = dp->ps;\n   int pass;\n\n   for (pass=0; pass<npasses; ++pass)\n   {\n      png_uint_32 y;\n      png_uint_32 wPass = PNG_PASS_COLS(width, pass);\n\n      for (y=0; y<height; ++y)\n      {\n         if (do_interlace)\n         {\n            /* wPass may be zero or this row may not be in this pass.\n             * png_read_row must not be called in either case.\n             */\n            if (wPass > 0 && PNG_ROW_IN_INTERLACE_PASS(y, pass))\n            {\n               /* Read the row into a pair of temporary buffers, then do the\n                * merge here into the output rows.\n                */\n               png_byte row[STANDARD_ROWMAX], display[STANDARD_ROWMAX];\n\n               /* The following aids (to some extent) error detection - we can\n                * see where png_read_row wrote.  Use opposite values in row and\n                * display to make this easier.  Don't use 0xff (which is used in\n                * the image write code to fill unused bits) or 0 (which is a\n                * likely value to overwrite unused bits with).\n                */\n               memset(row, 0xc5, sizeof row);\n               memset(display, 0x5c, sizeof display);\n\n               png_read_row(pp, row, display);\n\n               if (iImage >= 0)\n                  deinterlace_row(store_image_row(ps, pp, iImage, y), row,\n                     dp->pixel_size, dp->w, pass, dp->littleendian);\n\n               if (iDisplay >= 0)\n                  deinterlace_row(store_image_row(ps, pp, iDisplay, y), display,\n                     dp->pixel_size, dp->w, pass, dp->littleendian);\n            }\n         }\n         else\n            png_read_row(pp,\n               iImage >= 0 ? store_image_row(ps, pp, iImage, y) : NULL,\n               iDisplay >= 0 ? store_image_row(ps, pp, iDisplay, y) : NULL);\n      }\n   }\n\n   /* And finish the read operation (only really necessary if the caller wants\n    * to find additional data in png_info from chunks after the last IDAT.)\n    */\n   png_read_end(pp, pi);\n}\n\n#ifdef PNG_TEXT_SUPPORTED\nstatic void\nstandard_check_text(png_const_structp pp, png_const_textp tp,\n   png_const_charp keyword, png_const_charp text)\n{\n   char msg[1024];\n   size_t pos = safecat(msg, sizeof msg, 0, \"text: \");\n   size_t ok;\n\n   pos = safecat(msg, sizeof msg, pos, keyword);\n   pos = safecat(msg, sizeof msg, pos, \": \");\n   ok = pos;\n\n   if (tp->compression != TEXT_COMPRESSION)\n   {\n      char buf[64];\n\n      sprintf(buf, \"compression [%d->%d], \", TEXT_COMPRESSION,\n         tp->compression);\n      pos = safecat(msg, sizeof msg, pos, buf);\n   }\n\n   if (tp->key == NULL || strcmp(tp->key, keyword) != 0)\n   {\n      pos = safecat(msg, sizeof msg, pos, \"keyword \\\"\");\n      if (tp->key != NULL)\n      {\n         pos = safecat(msg, sizeof msg, pos, tp->key);\n         pos = safecat(msg, sizeof msg, pos, \"\\\", \");\n      }\n\n      else\n         pos = safecat(msg, sizeof msg, pos, \"null, \");\n   }\n\n   if (tp->text == NULL)\n      pos = safecat(msg, sizeof msg, pos, \"text lost, \");\n\n   else\n   {\n      if (tp->text_length != strlen(text))\n      {\n         char buf[64];\n         sprintf(buf, \"text length changed[%lu->%lu], \",\n            (unsigned long)strlen(text), (unsigned long)tp->text_length);\n         pos = safecat(msg, sizeof msg, pos, buf);\n      }\n\n      if (strcmp(tp->text, text) != 0)\n      {\n         pos = safecat(msg, sizeof msg, pos, \"text becomes \\\"\");\n         pos = safecat(msg, sizeof msg, pos, tp->text);\n         pos = safecat(msg, sizeof msg, pos, \"\\\" (was \\\"\");\n         pos = safecat(msg, sizeof msg, pos, text);\n         pos = safecat(msg, sizeof msg, pos, \"\\\"), \");\n      }\n   }\n\n   if (tp->itxt_length != 0)\n      pos = safecat(msg, sizeof msg, pos, \"iTXt length set, \");\n\n   if (tp->lang != NULL)\n   {\n      pos = safecat(msg, sizeof msg, pos, \"iTXt language \\\"\");\n      pos = safecat(msg, sizeof msg, pos, tp->lang);\n      pos = safecat(msg, sizeof msg, pos, \"\\\", \");\n   }\n\n   if (tp->lang_key != NULL)\n   {\n      pos = safecat(msg, sizeof msg, pos, \"iTXt keyword \\\"\");\n      pos = safecat(msg, sizeof msg, pos, tp->lang_key);\n      pos = safecat(msg, sizeof msg, pos, \"\\\", \");\n   }\n\n   if (pos > ok)\n   {\n      msg[pos-2] = '\\0'; /* Remove the \", \" at the end */\n      png_error(pp, msg);\n   }\n}\n\nstatic void\nstandard_text_validate(standard_display *dp, png_const_structp pp,\n   png_infop pi, int check_end)\n{\n   png_textp tp = NULL;\n   png_uint_32 num_text = png_get_text(pp, pi, &tp, NULL);\n\n   if (num_text == 2 && tp != NULL)\n   {\n      standard_check_text(pp, tp, \"image name\", dp->ps->current->name);\n\n      /* This exists because prior to 1.5.18 the progressive reader left the\n       * png_struct z_stream unreset at the end of the image, so subsequent\n       * attempts to use it simply returns Z_STREAM_END.\n       */\n      if (check_end)\n         standard_check_text(pp, tp+1, \"end marker\", \"end\");\n   }\n\n   else\n   {\n      char msg[64];\n\n      sprintf(msg, \"expected two text items, got %lu\",\n         (unsigned long)num_text);\n      png_error(pp, msg);\n   }\n}\n#else\n#  define standard_text_validate(dp,pp,pi,check_end) ((void)0)\n#endif\n\nstatic void\nstandard_row_validate(standard_display *dp, png_const_structp pp,\n   int iImage, int iDisplay, png_uint_32 y)\n{\n   int where;\n   png_byte std[STANDARD_ROWMAX];\n\n   /* The row must be pre-initialized to the magic number here for the size\n    * tests to pass:\n    */\n   memset(std, 178, sizeof std);\n   standard_row(pp, std, dp->id, y);\n\n   /* At the end both the 'row' and 'display' arrays should end up identical.\n    * In earlier passes 'row' will be partially filled in, with only the pixels\n    * that have been read so far, but 'display' will have those pixels\n    * replicated to fill the unread pixels while reading an interlaced image.\n    */\n   if (iImage >= 0 &&\n      (where = pixel_cmp(std, store_image_row(dp->ps, pp, iImage, y),\n            dp->bit_width)) != 0)\n   {\n      char msg[64];\n      sprintf(msg, \"PNG image row[%lu][%d] changed from %.2x to %.2x\",\n         (unsigned long)y, where-1, std[where-1],\n         store_image_row(dp->ps, pp, iImage, y)[where-1]);\n      png_error(pp, msg);\n   }\n\n   if (iDisplay >= 0 &&\n      (where = pixel_cmp(std, store_image_row(dp->ps, pp, iDisplay, y),\n         dp->bit_width)) != 0)\n   {\n      char msg[64];\n      sprintf(msg, \"display row[%lu][%d] changed from %.2x to %.2x\",\n         (unsigned long)y, where-1, std[where-1],\n         store_image_row(dp->ps, pp, iDisplay, y)[where-1]);\n      png_error(pp, msg);\n   }\n}\n\nstatic void\nstandard_image_validate(standard_display *dp, png_const_structp pp, int iImage,\n    int iDisplay)\n{\n   png_uint_32 y;\n\n   if (iImage >= 0)\n      store_image_check(dp->ps, pp, iImage);\n\n   if (iDisplay >= 0)\n      store_image_check(dp->ps, pp, iDisplay);\n\n   for (y=0; y<dp->h; ++y)\n      standard_row_validate(dp, pp, iImage, iDisplay, y);\n\n   /* This avoids false positives if the validation code is never called! */\n   dp->ps->validated = 1;\n}\n\nstatic void PNGCBAPI\nstandard_end(png_structp ppIn, png_infop pi)\n{\n   png_const_structp pp = ppIn;\n   standard_display *dp = voidcast(standard_display*,\n      png_get_progressive_ptr(pp));\n\n   UNUSED(pi)\n\n   /* Validate the image - progressive reading only produces one variant for\n    * interlaced images.\n    */\n   standard_text_validate(dp, pp, pi,\n      PNG_LIBPNG_VER >= 10518/*check_end: see comments above*/);\n   standard_image_validate(dp, pp, 0, -1);\n}\n\n/* A single test run checking the standard image to ensure it is not damaged. */\nstatic void\nstandard_test(png_store* const psIn, png_uint_32 const id,\n   int do_interlace, int use_update_info)\n{\n   standard_display d;\n   context(psIn, fault);\n\n   /* Set up the display (stack frame) variables from the arguments to the\n    * function and initialize the locals that are filled in later.\n    */\n   standard_display_init(&d, psIn, id, do_interlace, use_update_info);\n\n   /* Everything is protected by a Try/Catch.  The functions called also\n    * typically have local Try/Catch blocks.\n    */\n   Try\n   {\n      png_structp pp;\n      png_infop pi;\n\n      /* Get a png_struct for reading the image. This will throw an error if it\n       * fails, so we don't need to check the result.\n       */\n      pp = set_store_for_read(d.ps, &pi, d.id,\n         d.do_interlace ?  (d.ps->progressive ?\n            \"pngvalid progressive deinterlacer\" :\n            \"pngvalid sequential deinterlacer\") : (d.ps->progressive ?\n               \"progressive reader\" : \"sequential reader\"));\n\n      /* Initialize the palette correctly from the png_store_file. */\n      standard_palette_init(&d);\n\n      /* Introduce the correct read function. */\n      if (d.ps->progressive)\n      {\n         png_set_progressive_read_fn(pp, &d, standard_info, progressive_row,\n            standard_end);\n\n         /* Now feed data into the reader until we reach the end: */\n         store_progressive_read(d.ps, pp, pi);\n      }\n      else\n      {\n         /* Note that this takes the store, not the display. */\n         png_set_read_fn(pp, d.ps, store_read);\n\n         /* Check the header values: */\n         png_read_info(pp, pi);\n\n         /* The code tests both versions of the images that the sequential\n          * reader can produce.\n          */\n         standard_info_imp(&d, pp, pi, 2 /*images*/);\n\n         /* Need the total bytes in the image below; we can't get to this point\n          * unless the PNG file values have been checked against the expected\n          * values.\n          */\n         {\n            sequential_row(&d, pp, pi, 0, 1);\n\n            /* After the last pass loop over the rows again to check that the\n             * image is correct.\n             */\n            if (!d.speed)\n            {\n               standard_text_validate(&d, pp, pi, 1/*check_end*/);\n               standard_image_validate(&d, pp, 0, 1);\n            }\n            else\n               d.ps->validated = 1;\n         }\n      }\n\n      /* Check for validation. */\n      if (!d.ps->validated)\n         png_error(pp, \"image read failed silently\");\n\n      /* Successful completion. */\n   }\n\n   Catch(fault)\n      d.ps = fault; /* make sure this hasn't been clobbered. */\n\n   /* In either case clean up the store. */\n   store_read_reset(d.ps);\n}\n\nstatic int\ntest_standard(png_modifier* const pm, png_byte const colour_type,\n    int bdlo, int const bdhi)\n{\n   for (; bdlo <= bdhi; ++bdlo)\n   {\n      int interlace_type;\n\n      for (interlace_type = PNG_INTERLACE_NONE;\n           interlace_type < INTERLACE_LAST; ++interlace_type)\n      {\n         standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,\n            interlace_type, 0, 0, 0), do_read_interlace, pm->use_update_info);\n\n         if (fail(pm))\n            return 0;\n      }\n   }\n\n   return 1; /* keep going */\n}\n\nstatic void\nperform_standard_test(png_modifier *pm)\n{\n   /* Test each colour type over the valid range of bit depths (expressed as\n    * log2(bit_depth) in turn, stop as soon as any error is detected.\n    */\n   if (!test_standard(pm, 0, 0, READ_BDHI))\n      return;\n\n   if (!test_standard(pm, 2, 3, READ_BDHI))\n      return;\n\n   if (!test_standard(pm, 3, 0, 3))\n      return;\n\n   if (!test_standard(pm, 4, 3, READ_BDHI))\n      return;\n\n   if (!test_standard(pm, 6, 3, READ_BDHI))\n      return;\n}\n\n\n/********************************** SIZE TESTS ********************************/\nstatic int\ntest_size(png_modifier* const pm, png_byte const colour_type,\n    int bdlo, int const bdhi)\n{\n   /* Run the tests on each combination.\n    *\n    * NOTE: on my 32 bit x86 each of the following blocks takes\n    * a total of 3.5 seconds if done across every combo of bit depth\n    * width and height.  This is a waste of time in practice, hence the\n    * hinc and winc stuff:\n    */\n   static const png_byte hinc[] = {1, 3, 11, 1, 5};\n   static const png_byte winc[] = {1, 9, 5, 7, 1};\n   const int save_bdlo = bdlo;\n\n   for (; bdlo <= bdhi; ++bdlo)\n   {\n      png_uint_32 h, w;\n\n      for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo])\n      {\n         /* First test all the 'size' images against the sequential\n          * reader using libpng to deinterlace (where required.)  This\n          * validates the write side of libpng.  There are four possibilities\n          * to validate.\n          */\n         standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,\n            PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/,\n            pm->use_update_info);\n\n         if (fail(pm))\n            return 0;\n\n         standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,\n            PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/,\n            pm->use_update_info);\n\n         if (fail(pm))\n            return 0;\n\n         /* Now validate the interlaced read side - do_interlace true,\n          * in the progressive case this does actually make a difference\n          * to the code used in the non-interlaced case too.\n          */\n         standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,\n            PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/,\n            pm->use_update_info);\n\n         if (fail(pm))\n            return 0;\n\n#     if CAN_WRITE_INTERLACE\n         /* Validate the pngvalid code itself: */\n         standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,\n            PNG_INTERLACE_ADAM7, w, h, 1), 1/*do_interlace*/,\n            pm->use_update_info);\n\n         if (fail(pm))\n            return 0;\n#     endif\n      }\n   }\n\n   /* Now do the tests of libpng interlace handling, after we have made sure\n    * that the pngvalid version works:\n    */\n   for (bdlo = save_bdlo; bdlo <= bdhi; ++bdlo)\n   {\n      png_uint_32 h, w;\n\n      for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo])\n      {\n#     ifdef PNG_READ_INTERLACING_SUPPORTED\n         /* Test with pngvalid generated interlaced images first; we have\n          * already verify these are ok (unless pngvalid has self-consistent\n          * read/write errors, which is unlikely), so this detects errors in the\n          * read side first:\n          */\n#     if CAN_WRITE_INTERLACE\n         standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,\n            PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/,\n            pm->use_update_info);\n\n         if (fail(pm))\n            return 0;\n#     endif\n#     endif /* READ_INTERLACING */\n\n#     ifdef PNG_WRITE_INTERLACING_SUPPORTED\n         /* Test the libpng write side against the pngvalid read side: */\n         standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,\n            PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/,\n            pm->use_update_info);\n\n         if (fail(pm))\n            return 0;\n#     endif\n\n#     ifdef PNG_READ_INTERLACING_SUPPORTED\n#     ifdef PNG_WRITE_INTERLACING_SUPPORTED\n         /* Test both together: */\n         standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,\n            PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/,\n            pm->use_update_info);\n\n         if (fail(pm))\n            return 0;\n#     endif\n#     endif /* READ_INTERLACING */\n      }\n   }\n\n   return 1; /* keep going */\n}\n\nstatic void\nperform_size_test(png_modifier *pm)\n{\n   /* Test each colour type over the valid range of bit depths (expressed as\n    * log2(bit_depth) in turn, stop as soon as any error is detected.\n    */\n   if (!test_size(pm, 0, 0, READ_BDHI))\n      return;\n\n   if (!test_size(pm, 2, 3, READ_BDHI))\n      return;\n\n   /* For the moment don't do the palette test - it's a waste of time when\n    * compared to the grayscale test.\n    */\n#if 0\n   if (!test_size(pm, 3, 0, 3))\n      return;\n#endif\n\n   if (!test_size(pm, 4, 3, READ_BDHI))\n      return;\n\n   if (!test_size(pm, 6, 3, READ_BDHI))\n      return;\n}\n\n\n/******************************* TRANSFORM TESTS ******************************/\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\n/* A set of tests to validate libpng image transforms.  The possibilities here\n * are legion because the transforms can be combined in a combinatorial\n * fashion.  To deal with this some measure of restraint is required, otherwise\n * the tests would take forever.\n */\ntypedef struct image_pixel\n{\n   /* A local (pngvalid) representation of a PNG pixel, in all its\n    * various forms.\n    */\n   unsigned int red, green, blue, alpha; /* For non-palette images. */\n   unsigned int palette_index;           /* For a palette image. */\n   png_byte     colour_type;             /* As in the spec. */\n   png_byte     bit_depth;               /* Defines bit size in row */\n   png_byte     sample_depth;            /* Scale of samples */\n   unsigned int have_tRNS :1;            /* tRNS chunk may need processing */\n   unsigned int swap_rgb :1;             /* RGB swapped to BGR */\n   unsigned int alpha_first :1;          /* Alpha at start, not end */\n   unsigned int alpha_inverted :1;       /* Alpha channel inverted */\n   unsigned int mono_inverted :1;        /* Gray channel inverted */\n   unsigned int swap16 :1;               /* Byte swap 16-bit components */\n   unsigned int littleendian :1;         /* High bits on right */\n   unsigned int sig_bits :1;             /* Pixel shifted (sig bits only) */\n\n   /* For checking the code calculates double precision floating point values\n    * along with an error value, accumulated from the transforms.  Because an\n    * sBIT setting allows larger error bounds (indeed, by the spec, apparently\n    * up to just less than +/-1 in the scaled value) the *lowest* sBIT for each\n    * channel is stored.  This sBIT value is folded in to the stored error value\n    * at the end of the application of the transforms to the pixel.\n    *\n    * If sig_bits is set above the red, green, blue and alpha values have been\n    * scaled so they only contain the significant bits of the component values.\n    */\n   double   redf, greenf, bluef, alphaf;\n   double   rede, greene, bluee, alphae;\n   png_byte red_sBIT, green_sBIT, blue_sBIT, alpha_sBIT;\n} image_pixel;\n\n/* Shared utility function, see below. */\nstatic void\nimage_pixel_setf(image_pixel *this, unsigned int rMax, unsigned int gMax,\n        unsigned int bMax, unsigned int aMax)\n{\n   this->redf = this->red / (double)rMax;\n   this->greenf = this->green / (double)gMax;\n   this->bluef = this->blue / (double)bMax;\n   this->alphaf = this->alpha / (double)aMax;\n\n   if (this->red < rMax)\n      this->rede = this->redf * DBL_EPSILON;\n   else\n      this->rede = 0;\n   if (this->green < gMax)\n      this->greene = this->greenf * DBL_EPSILON;\n   else\n      this->greene = 0;\n   if (this->blue < bMax)\n      this->bluee = this->bluef * DBL_EPSILON;\n   else\n      this->bluee = 0;\n   if (this->alpha < aMax)\n      this->alphae = this->alphaf * DBL_EPSILON;\n   else\n      this->alphae = 0;\n}\n\n/* Initialize the structure for the next pixel - call this before doing any\n * transforms and call it for each pixel since all the fields may need to be\n * reset.\n */\nstatic void\nimage_pixel_init(image_pixel *this, png_const_bytep row, png_byte colour_type,\n    png_byte bit_depth, png_uint_32 x, store_palette palette,\n    const image_pixel *format /*from pngvalid transform of input*/)\n{\n   const png_byte sample_depth = (png_byte)(colour_type ==\n      PNG_COLOR_TYPE_PALETTE ? 8 : bit_depth);\n   const unsigned int max = (1U<<sample_depth)-1;\n   const int swap16 = (format != 0 && format->swap16);\n   const int littleendian = (format != 0 && format->littleendian);\n   const int sig_bits = (format != 0 && format->sig_bits);\n\n   /* Initially just set everything to the same number and the alpha to opaque.\n    * Note that this currently assumes a simple palette where entry x has colour\n    * rgb(x,x,x)!\n    */\n   this->palette_index = this->red = this->green = this->blue =\n      sample(row, colour_type, bit_depth, x, 0, swap16, littleendian);\n   this->alpha = max;\n   this->red_sBIT = this->green_sBIT = this->blue_sBIT = this->alpha_sBIT =\n      sample_depth;\n\n   /* Then override as appropriate: */\n   if (colour_type == 3) /* palette */\n   {\n      /* This permits the caller to default to the sample value. */\n      if (palette != 0)\n      {\n         const unsigned int i = this->palette_index;\n\n         this->red = palette[i].red;\n         this->green = palette[i].green;\n         this->blue = palette[i].blue;\n         this->alpha = palette[i].alpha;\n      }\n   }\n\n   else /* not palette */\n   {\n      unsigned int i = 0;\n\n      if ((colour_type & 4) != 0 && format != 0 && format->alpha_first)\n      {\n         this->alpha = this->red;\n         /* This handles the gray case for 'AG' pixels */\n         this->palette_index = this->red = this->green = this->blue =\n            sample(row, colour_type, bit_depth, x, 1, swap16, littleendian);\n         i = 1;\n      }\n\n      if (colour_type & 2)\n      {\n         /* Green is second for both BGR and RGB: */\n         this->green = sample(row, colour_type, bit_depth, x, ++i, swap16,\n                 littleendian);\n\n         if (format != 0 && format->swap_rgb) /* BGR */\n             this->red = sample(row, colour_type, bit_depth, x, ++i, swap16,\n                     littleendian);\n         else\n             this->blue = sample(row, colour_type, bit_depth, x, ++i, swap16,\n                     littleendian);\n      }\n\n      else /* grayscale */ if (format != 0 && format->mono_inverted)\n         this->red = this->green = this->blue = this->red ^ max;\n\n      if ((colour_type & 4) != 0) /* alpha */\n      {\n         if (format == 0 || !format->alpha_first)\n             this->alpha = sample(row, colour_type, bit_depth, x, ++i, swap16,\n                     littleendian);\n\n         if (format != 0 && format->alpha_inverted)\n            this->alpha ^= max;\n      }\n   }\n\n   /* Calculate the scaled values, these are simply the values divided by\n    * 'max' and the error is initialized to the double precision epsilon value\n    * from the header file.\n    */\n   image_pixel_setf(this,\n      sig_bits ? (1U << format->red_sBIT)-1 : max,\n      sig_bits ? (1U << format->green_sBIT)-1 : max,\n      sig_bits ? (1U << format->blue_sBIT)-1 : max,\n      sig_bits ? (1U << format->alpha_sBIT)-1 : max);\n\n   /* Store the input information for use in the transforms - these will\n    * modify the information.\n    */\n   this->colour_type = colour_type;\n   this->bit_depth = bit_depth;\n   this->sample_depth = sample_depth;\n   this->have_tRNS = 0;\n   this->swap_rgb = 0;\n   this->alpha_first = 0;\n   this->alpha_inverted = 0;\n   this->mono_inverted = 0;\n   this->swap16 = 0;\n   this->littleendian = 0;\n   this->sig_bits = 0;\n}\n\n#if defined PNG_READ_EXPAND_SUPPORTED || defined PNG_READ_GRAY_TO_RGB_SUPPORTED\\\n   || defined PNG_READ_EXPAND_SUPPORTED || defined PNG_READ_EXPAND_16_SUPPORTED\\\n   || defined PNG_READ_BACKGROUND_SUPPORTED\n/* Convert a palette image to an rgb image.  This necessarily converts the tRNS\n * chunk at the same time, because the tRNS will be in palette form.  The way\n * palette validation works means that the original palette is never updated,\n * instead the image_pixel value from the row contains the RGB of the\n * corresponding palette entry and *this* is updated.  Consequently this routine\n * only needs to change the colour type information.\n */\nstatic void\nimage_pixel_convert_PLTE(image_pixel *this)\n{\n   if (this->colour_type == PNG_COLOR_TYPE_PALETTE)\n   {\n      if (this->have_tRNS)\n      {\n         this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;\n         this->have_tRNS = 0;\n      }\n      else\n         this->colour_type = PNG_COLOR_TYPE_RGB;\n\n      /* The bit depth of the row changes at this point too (notice that this is\n       * the row format, not the sample depth, which is separate.)\n       */\n      this->bit_depth = 8;\n   }\n}\n\n/* Add an alpha channel; this will import the tRNS information because tRNS is\n * not valid in an alpha image.  The bit depth will invariably be set to at\n * least 8 prior to 1.7.0.  Palette images will be converted to alpha (using\n * the above API).  With png_set_background the alpha channel is never expanded\n * but this routine is used by pngvalid to simplify code; 'for_background'\n * records this.\n */\nstatic void\nimage_pixel_add_alpha(image_pixel *this, const standard_display *display,\n   int for_background)\n{\n   if (this->colour_type == PNG_COLOR_TYPE_PALETTE)\n      image_pixel_convert_PLTE(this);\n\n   if ((this->colour_type & PNG_COLOR_MASK_ALPHA) == 0)\n   {\n      if (this->colour_type == PNG_COLOR_TYPE_GRAY)\n      {\n#        if PNG_LIBPNG_VER < 10700\n            if (!for_background && this->bit_depth < 8)\n               this->bit_depth = this->sample_depth = 8;\n#        endif\n\n         if (this->have_tRNS)\n         {\n            /* After 1.7 the expansion of bit depth only happens if there is a\n             * tRNS chunk to expand at this point.\n             */\n#           if PNG_LIBPNG_VER >= 10700\n               if (!for_background && this->bit_depth < 8)\n                  this->bit_depth = this->sample_depth = 8;\n#           endif\n\n            this->have_tRNS = 0;\n\n            /* Check the input, original, channel value here against the\n             * original tRNS gray chunk valie.\n             */\n            if (this->red == display->transparent.red)\n               this->alphaf = 0;\n            else\n               this->alphaf = 1;\n         }\n         else\n            this->alphaf = 1;\n\n         this->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;\n      }\n\n      else if (this->colour_type == PNG_COLOR_TYPE_RGB)\n      {\n         if (this->have_tRNS)\n         {\n            this->have_tRNS = 0;\n\n            /* Again, check the exact input values, not the current transformed\n             * value!\n             */\n            if (this->red == display->transparent.red &&\n               this->green == display->transparent.green &&\n               this->blue == display->transparent.blue)\n               this->alphaf = 0;\n            else\n               this->alphaf = 1;\n         }\n         else\n            this->alphaf = 1;\n\n         this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;\n      }\n\n      /* The error in the alpha is zero and the sBIT value comes from the\n       * original sBIT data (actually it will always be the original bit depth).\n       */\n      this->alphae = 0;\n      this->alpha_sBIT = display->alpha_sBIT;\n   }\n}\n#endif /* transforms that need image_pixel_add_alpha */\n\nstruct transform_display;\ntypedef struct image_transform\n{\n   /* The name of this transform: a string. */\n   const char *name;\n\n   /* Each transform can be disabled from the command line: */\n   int enable;\n\n   /* The global list of transforms; read only. */\n   struct image_transform *const list;\n\n   /* The global count of the number of times this transform has been set on an\n    * image.\n    */\n   unsigned int global_use;\n\n   /* The local count of the number of times this transform has been set. */\n   unsigned int local_use;\n\n   /* The next transform in the list, each transform must call its own next\n    * transform after it has processed the pixel successfully.\n    */\n   const struct image_transform *next;\n\n   /* A single transform for the image, expressed as a series of function\n    * callbacks and some space for values.\n    *\n    * First a callback to add any required modifications to the png_modifier;\n    * this gets called just before the modifier is set up for read.\n    */\n   void (*ini)(const struct image_transform *this,\n      struct transform_display *that);\n\n   /* And a callback to set the transform on the current png_read_struct:\n    */\n   void (*set)(const struct image_transform *this,\n      struct transform_display *that, png_structp pp, png_infop pi);\n\n   /* Then a transform that takes an input pixel in one PNG format or another\n    * and modifies it by a pngvalid implementation of the transform (thus\n    * duplicating the libpng intent without, we hope, duplicating the bugs\n    * in the libpng implementation!)  The png_structp is solely to allow error\n    * reporting via png_error and png_warning.\n    */\n   void (*mod)(const struct image_transform *this, image_pixel *that,\n      png_const_structp pp, const struct transform_display *display);\n\n   /* Add this transform to the list and return true if the transform is\n    * meaningful for this colour type and bit depth - if false then the\n    * transform should have no effect on the image so there's not a lot of\n    * point running it.\n    */\n   int (*add)(struct image_transform *this,\n      const struct image_transform **that, png_byte colour_type,\n      png_byte bit_depth);\n} image_transform;\n\ntypedef struct transform_display\n{\n   standard_display this;\n\n   /* Parameters */\n   png_modifier*              pm;\n   const image_transform* transform_list;\n   unsigned int max_gamma_8;\n\n   /* Local variables */\n   png_byte output_colour_type;\n   png_byte output_bit_depth;\n   png_byte unpacked;\n\n   /* Modifications (not necessarily used.) */\n   gama_modification gama_mod;\n   chrm_modification chrm_mod;\n   srgb_modification srgb_mod;\n} transform_display;\n\n/* Set sRGB, cHRM and gAMA transforms as required by the current encoding. */\nstatic void\ntransform_set_encoding(transform_display *this)\n{\n   /* Set up the png_modifier '_current' fields then use these to determine how\n    * to add appropriate chunks.\n    */\n   png_modifier *pm = this->pm;\n\n   modifier_set_encoding(pm);\n\n   if (modifier_color_encoding_is_set(pm))\n   {\n      if (modifier_color_encoding_is_sRGB(pm))\n         srgb_modification_init(&this->srgb_mod, pm, PNG_sRGB_INTENT_ABSOLUTE);\n\n      else\n      {\n         /* Set gAMA and cHRM separately. */\n         gama_modification_init(&this->gama_mod, pm, pm->current_gamma);\n\n         if (pm->current_encoding != 0)\n            chrm_modification_init(&this->chrm_mod, pm, pm->current_encoding);\n      }\n   }\n}\n\n/* Three functions to end the list: */\nstatic void\nimage_transform_ini_end(const image_transform *this,\n   transform_display *that)\n{\n   UNUSED(this)\n   UNUSED(that)\n}\n\nstatic void\nimage_transform_set_end(const image_transform *this,\n   transform_display *that, png_structp pp, png_infop pi)\n{\n   UNUSED(this)\n   UNUSED(that)\n   UNUSED(pp)\n   UNUSED(pi)\n}\n\n/* At the end of the list recalculate the output image pixel value from the\n * double precision values set up by the preceding 'mod' calls:\n */\nstatic unsigned int\nsample_scale(double sample_value, unsigned int scale)\n{\n   sample_value = floor(sample_value * scale + .5);\n\n   /* Return NaN as 0: */\n   if (!(sample_value > 0))\n      sample_value = 0;\n   else if (sample_value > scale)\n      sample_value = scale;\n\n   return (unsigned int)sample_value;\n}\n\nstatic void\nimage_transform_mod_end(const image_transform *this, image_pixel *that,\n    png_const_structp pp, const transform_display *display)\n{\n   const unsigned int scale = (1U<<that->sample_depth)-1;\n   const int sig_bits = that->sig_bits;\n\n   UNUSED(this)\n   UNUSED(pp)\n   UNUSED(display)\n\n   /* At the end recalculate the digitized red green and blue values according\n    * to the current sample_depth of the pixel.\n    *\n    * The sample value is simply scaled to the maximum, checking for over\n    * and underflow (which can both happen for some image transforms,\n    * including simple size scaling, though libpng doesn't do that at present.\n    */\n   that->red = sample_scale(that->redf, scale);\n\n   /* This is a bit bogus; really the above calculation should use the red_sBIT\n    * value, not sample_depth, but because libpng does png_set_shift by just\n    * shifting the bits we get errors if we don't do it the same way.\n    */\n   if (sig_bits && that->red_sBIT < that->sample_depth)\n      that->red >>= that->sample_depth - that->red_sBIT;\n\n   /* The error value is increased, at the end, according to the lowest sBIT\n    * value seen.  Common sense tells us that the intermediate integer\n    * representations are no more accurate than +/- 0.5 in the integral values,\n    * the sBIT allows the implementation to be worse than this.  In addition the\n    * PNG specification actually permits any error within the range (-1..+1),\n    * but that is ignored here.  Instead the final digitized value is compared,\n    * below to the digitized value of the error limits - this has the net effect\n    * of allowing (almost) +/-1 in the output value.  It's difficult to see how\n    * any algorithm that digitizes intermediate results can be more accurate.\n    */\n   that->rede += 1./(2*((1U<<that->red_sBIT)-1));\n\n   if (that->colour_type & PNG_COLOR_MASK_COLOR)\n   {\n      that->green = sample_scale(that->greenf, scale);\n      if (sig_bits && that->green_sBIT < that->sample_depth)\n         that->green >>= that->sample_depth - that->green_sBIT;\n\n      that->blue = sample_scale(that->bluef, scale);\n      if (sig_bits && that->blue_sBIT < that->sample_depth)\n         that->blue >>= that->sample_depth - that->blue_sBIT;\n\n      that->greene += 1./(2*((1U<<that->green_sBIT)-1));\n      that->bluee += 1./(2*((1U<<that->blue_sBIT)-1));\n   }\n   else\n   {\n      that->blue = that->green = that->red;\n      that->bluef = that->greenf = that->redf;\n      that->bluee = that->greene = that->rede;\n   }\n\n   if ((that->colour_type & PNG_COLOR_MASK_ALPHA) ||\n      that->colour_type == PNG_COLOR_TYPE_PALETTE)\n   {\n      that->alpha = sample_scale(that->alphaf, scale);\n      that->alphae += 1./(2*((1U<<that->alpha_sBIT)-1));\n   }\n   else\n   {\n      that->alpha = scale; /* opaque */\n      that->alphaf = 1;    /* Override this. */\n      that->alphae = 0;    /* It's exact ;-) */\n   }\n\n   if (sig_bits && that->alpha_sBIT < that->sample_depth)\n      that->alpha >>= that->sample_depth - that->alpha_sBIT;\n}\n\n/* Static 'end' structure: */\nstatic image_transform image_transform_end =\n{\n   \"(end)\", /* name */\n   1, /* enable */\n   0, /* list */\n   0, /* global_use */\n   0, /* local_use */\n   0, /* next */\n   image_transform_ini_end,\n   image_transform_set_end,\n   image_transform_mod_end,\n   0 /* never called, I want it to crash if it is! */\n};\n\n/* Reader callbacks and implementations, where they differ from the standard\n * ones.\n */\nstatic void\ntransform_display_init(transform_display *dp, png_modifier *pm, png_uint_32 id,\n    const image_transform *transform_list)\n{\n   memset(dp, 0, sizeof *dp);\n\n   /* Standard fields */\n   standard_display_init(&dp->this, &pm->this, id, do_read_interlace,\n      pm->use_update_info);\n\n   /* Parameter fields */\n   dp->pm = pm;\n   dp->transform_list = transform_list;\n   dp->max_gamma_8 = 16;\n\n   /* Local variable fields */\n   dp->output_colour_type = 255; /* invalid */\n   dp->output_bit_depth = 255;  /* invalid */\n   dp->unpacked = 0; /* not unpacked */\n}\n\nstatic void\ntransform_info_imp(transform_display *dp, png_structp pp, png_infop pi)\n{\n   /* Reuse the standard stuff as appropriate. */\n   standard_info_part1(&dp->this, pp, pi);\n\n   /* Now set the list of transforms. */\n   dp->transform_list->set(dp->transform_list, dp, pp, pi);\n\n   /* Update the info structure for these transforms: */\n   {\n      int i = dp->this.use_update_info;\n      /* Always do one call, even if use_update_info is 0. */\n      do\n         png_read_update_info(pp, pi);\n      while (--i > 0);\n   }\n\n   /* And get the output information into the standard_display */\n   standard_info_part2(&dp->this, pp, pi, 1/*images*/);\n\n   /* Plus the extra stuff we need for the transform tests: */\n   dp->output_colour_type = png_get_color_type(pp, pi);\n   dp->output_bit_depth = png_get_bit_depth(pp, pi);\n\n   /* If png_set_filler is in action then fake the output color type to include\n    * an alpha channel where appropriate.\n    */\n   if (dp->output_bit_depth >= 8 &&\n       (dp->output_colour_type == PNG_COLOR_TYPE_RGB ||\n        dp->output_colour_type == PNG_COLOR_TYPE_GRAY) && dp->this.filler)\n       dp->output_colour_type |= 4;\n\n   /* Validate the combination of colour type and bit depth that we are getting\n    * out of libpng; the semantics of something not in the PNG spec are, at\n    * best, unclear.\n    */\n   switch (dp->output_colour_type)\n   {\n   case PNG_COLOR_TYPE_PALETTE:\n      if (dp->output_bit_depth > 8) goto error;\n      /*FALL THROUGH*/\n   case PNG_COLOR_TYPE_GRAY:\n      if (dp->output_bit_depth == 1 || dp->output_bit_depth == 2 ||\n         dp->output_bit_depth == 4)\n         break;\n      /*FALL THROUGH*/\n   default:\n      if (dp->output_bit_depth == 8 || dp->output_bit_depth == 16)\n         break;\n      /*FALL THROUGH*/\n   error:\n      {\n         char message[128];\n         size_t pos;\n\n         pos = safecat(message, sizeof message, 0,\n            \"invalid final bit depth: colour type(\");\n         pos = safecatn(message, sizeof message, pos, dp->output_colour_type);\n         pos = safecat(message, sizeof message, pos, \") with bit depth: \");\n         pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);\n\n         png_error(pp, message);\n      }\n   }\n\n   /* Use a test pixel to check that the output agrees with what we expect -\n    * this avoids running the whole test if the output is unexpected.  This also\n    * checks for internal errors.\n    */\n   {\n      image_pixel test_pixel;\n\n      memset(&test_pixel, 0, sizeof test_pixel);\n      test_pixel.colour_type = dp->this.colour_type; /* input */\n      test_pixel.bit_depth = dp->this.bit_depth;\n      if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE)\n         test_pixel.sample_depth = 8;\n      else\n         test_pixel.sample_depth = test_pixel.bit_depth;\n      /* Don't need sBIT here, but it must be set to non-zero to avoid\n       * arithmetic overflows.\n       */\n      test_pixel.have_tRNS = dp->this.is_transparent != 0;\n      test_pixel.red_sBIT = test_pixel.green_sBIT = test_pixel.blue_sBIT =\n         test_pixel.alpha_sBIT = test_pixel.sample_depth;\n\n      dp->transform_list->mod(dp->transform_list, &test_pixel, pp, dp);\n\n      if (test_pixel.colour_type != dp->output_colour_type)\n      {\n         char message[128];\n         size_t pos = safecat(message, sizeof message, 0, \"colour type \");\n\n         pos = safecatn(message, sizeof message, pos, dp->output_colour_type);\n         pos = safecat(message, sizeof message, pos, \" expected \");\n         pos = safecatn(message, sizeof message, pos, test_pixel.colour_type);\n\n         png_error(pp, message);\n      }\n\n      if (test_pixel.bit_depth != dp->output_bit_depth)\n      {\n         char message[128];\n         size_t pos = safecat(message, sizeof message, 0, \"bit depth \");\n\n         pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);\n         pos = safecat(message, sizeof message, pos, \" expected \");\n         pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth);\n\n         png_error(pp, message);\n      }\n\n      /* If both bit depth and colour type are correct check the sample depth.\n       */\n      if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE &&\n          test_pixel.sample_depth != 8) /* oops - internal error! */\n         png_error(pp, \"pngvalid: internal: palette sample depth not 8\");\n      else if (dp->unpacked && test_pixel.bit_depth != 8)\n         png_error(pp, \"pngvalid: internal: bad unpacked pixel depth\");\n      else if (!dp->unpacked && test_pixel.colour_type != PNG_COLOR_TYPE_PALETTE\n              && test_pixel.bit_depth != test_pixel.sample_depth)\n      {\n         char message[128];\n         size_t pos = safecat(message, sizeof message, 0,\n            \"internal: sample depth \");\n\n         /* Because unless something has set 'unpacked' or the image is palette\n          * mapped we expect the transform to keep sample depth and bit depth\n          * the same.\n          */\n         pos = safecatn(message, sizeof message, pos, test_pixel.sample_depth);\n         pos = safecat(message, sizeof message, pos, \" expected \");\n         pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth);\n\n         png_error(pp, message);\n      }\n      else if (test_pixel.bit_depth != dp->output_bit_depth)\n      {\n         /* This could be a libpng error too; libpng has not produced what we\n          * expect for the output bit depth.\n          */\n         char message[128];\n         size_t pos = safecat(message, sizeof message, 0,\n            \"internal: bit depth \");\n\n         pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);\n         pos = safecat(message, sizeof message, pos, \" expected \");\n         pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth);\n\n         png_error(pp, message);\n      }\n   }\n}\n\nstatic void PNGCBAPI\ntransform_info(png_structp pp, png_infop pi)\n{\n   transform_info_imp(voidcast(transform_display*, png_get_progressive_ptr(pp)),\n      pp, pi);\n}\n\nstatic void\ntransform_range_check(png_const_structp pp, unsigned int r, unsigned int g,\n   unsigned int b, unsigned int a, unsigned int in_digitized, double in,\n   unsigned int out, png_byte sample_depth, double err, double limit,\n   const char *name, double digitization_error)\n{\n   /* Compare the scaled, digitzed, values of our local calculation (in+-err)\n    * with the digitized values libpng produced;  'sample_depth' is the actual\n    * digitization depth of the libpng output colors (the bit depth except for\n    * palette images where it is always 8.)  The check on 'err' is to detect\n    * internal errors in pngvalid itself.\n    */\n   unsigned int max = (1U<<sample_depth)-1;\n   double in_min = ceil((in-err)*max - digitization_error);\n   double in_max = floor((in+err)*max + digitization_error);\n   if (debugonly(err > limit ||) !(out >= in_min && out <= in_max))\n   {\n      char message[256];\n      size_t pos;\n\n      pos = safecat(message, sizeof message, 0, name);\n      pos = safecat(message, sizeof message, pos, \" output value error: rgba(\");\n      pos = safecatn(message, sizeof message, pos, r);\n      pos = safecat(message, sizeof message, pos, \",\");\n      pos = safecatn(message, sizeof message, pos, g);\n      pos = safecat(message, sizeof message, pos, \",\");\n      pos = safecatn(message, sizeof message, pos, b);\n      pos = safecat(message, sizeof message, pos, \",\");\n      pos = safecatn(message, sizeof message, pos, a);\n      pos = safecat(message, sizeof message, pos, \"): \");\n      pos = safecatn(message, sizeof message, pos, out);\n      pos = safecat(message, sizeof message, pos, \" expected: \");\n      pos = safecatn(message, sizeof message, pos, in_digitized);\n      pos = safecat(message, sizeof message, pos, \" (\");\n      pos = safecatd(message, sizeof message, pos, (in-err)*max, 3);\n      pos = safecat(message, sizeof message, pos, \"..\");\n      pos = safecatd(message, sizeof message, pos, (in+err)*max, 3);\n      pos = safecat(message, sizeof message, pos, \")\");\n\n      png_error(pp, message);\n   }\n\n   UNUSED(limit)\n}\n\nstatic void\ntransform_image_validate(transform_display *dp, png_const_structp pp,\n   png_infop pi)\n{\n   /* Constants for the loop below: */\n   const png_store* const ps = dp->this.ps;\n   const png_byte in_ct = dp->this.colour_type;\n   const png_byte in_bd = dp->this.bit_depth;\n   const png_uint_32 w = dp->this.w;\n   const png_uint_32 h = dp->this.h;\n   const png_byte out_ct = dp->output_colour_type;\n   const png_byte out_bd = dp->output_bit_depth;\n   const png_byte sample_depth = (png_byte)(out_ct ==\n      PNG_COLOR_TYPE_PALETTE ? 8 : out_bd);\n   const png_byte red_sBIT = dp->this.red_sBIT;\n   const png_byte green_sBIT = dp->this.green_sBIT;\n   const png_byte blue_sBIT = dp->this.blue_sBIT;\n   const png_byte alpha_sBIT = dp->this.alpha_sBIT;\n   const int have_tRNS = dp->this.is_transparent;\n   double digitization_error;\n\n   store_palette out_palette;\n   png_uint_32 y;\n\n   UNUSED(pi)\n\n   /* Check for row overwrite errors */\n   store_image_check(dp->this.ps, pp, 0);\n\n   /* Read the palette corresponding to the output if the output colour type\n    * indicates a palette, othewise set out_palette to garbage.\n    */\n   if (out_ct == PNG_COLOR_TYPE_PALETTE)\n   {\n      /* Validate that the palette count itself has not changed - this is not\n       * expected.\n       */\n      int npalette = (-1);\n\n      (void)read_palette(out_palette, &npalette, pp, pi);\n      if (npalette != dp->this.npalette)\n         png_error(pp, \"unexpected change in palette size\");\n\n      digitization_error = .5;\n   }\n   else\n   {\n      png_byte in_sample_depth;\n\n      memset(out_palette, 0x5e, sizeof out_palette);\n\n      /* use-input-precision means assume that if the input has 8 bit (or less)\n       * samples and the output has 16 bit samples the calculations will be done\n       * with 8 bit precision, not 16.\n       */\n      if (in_ct == PNG_COLOR_TYPE_PALETTE || in_bd < 16)\n         in_sample_depth = 8;\n      else\n         in_sample_depth = in_bd;\n\n      if (sample_depth != 16 || in_sample_depth > 8 ||\n         !dp->pm->calculations_use_input_precision)\n         digitization_error = .5;\n\n      /* Else calculations are at 8 bit precision, and the output actually\n       * consists of scaled 8-bit values, so scale .5 in 8 bits to the 16 bits:\n       */\n      else\n         digitization_error = .5 * 257;\n   }\n\n   for (y=0; y<h; ++y)\n   {\n      png_const_bytep const pRow = store_image_row(ps, pp, 0, y);\n      png_uint_32 x;\n\n      /* The original, standard, row pre-transforms. */\n      png_byte std[STANDARD_ROWMAX];\n\n      transform_row(pp, std, in_ct, in_bd, y);\n\n      /* Go through each original pixel transforming it and comparing with what\n       * libpng did to the same pixel.\n       */\n      for (x=0; x<w; ++x)\n      {\n         image_pixel in_pixel, out_pixel;\n         unsigned int r, g, b, a;\n\n         /* Find out what we think the pixel should be: */\n         image_pixel_init(&in_pixel, std, in_ct, in_bd, x, dp->this.palette,\n                 NULL);\n\n         in_pixel.red_sBIT = red_sBIT;\n         in_pixel.green_sBIT = green_sBIT;\n         in_pixel.blue_sBIT = blue_sBIT;\n         in_pixel.alpha_sBIT = alpha_sBIT;\n         in_pixel.have_tRNS = have_tRNS != 0;\n\n         /* For error detection, below. */\n         r = in_pixel.red;\n         g = in_pixel.green;\n         b = in_pixel.blue;\n         a = in_pixel.alpha;\n\n         /* This applies the transforms to the input data, including output\n          * format operations which must be used when reading the output\n          * pixel that libpng produces.\n          */\n         dp->transform_list->mod(dp->transform_list, &in_pixel, pp, dp);\n\n         /* Read the output pixel and compare it to what we got, we don't\n          * use the error field here, so no need to update sBIT.  in_pixel\n          * says whether we expect libpng to change the output format.\n          */\n         image_pixel_init(&out_pixel, pRow, out_ct, out_bd, x, out_palette,\n                 &in_pixel);\n\n         /* We don't expect changes to the index here even if the bit depth is\n          * changed.\n          */\n         if (in_ct == PNG_COLOR_TYPE_PALETTE &&\n            out_ct == PNG_COLOR_TYPE_PALETTE)\n         {\n            if (in_pixel.palette_index != out_pixel.palette_index)\n               png_error(pp, \"unexpected transformed palette index\");\n         }\n\n         /* Check the colours for palette images too - in fact the palette could\n          * be separately verified itself in most cases.\n          */\n         if (in_pixel.red != out_pixel.red)\n            transform_range_check(pp, r, g, b, a, in_pixel.red, in_pixel.redf,\n               out_pixel.red, sample_depth, in_pixel.rede,\n               dp->pm->limit + 1./(2*((1U<<in_pixel.red_sBIT)-1)), \"red/gray\",\n               digitization_error);\n\n         if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 &&\n            in_pixel.green != out_pixel.green)\n            transform_range_check(pp, r, g, b, a, in_pixel.green,\n               in_pixel.greenf, out_pixel.green, sample_depth, in_pixel.greene,\n               dp->pm->limit + 1./(2*((1U<<in_pixel.green_sBIT)-1)), \"green\",\n               digitization_error);\n\n         if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 &&\n            in_pixel.blue != out_pixel.blue)\n            transform_range_check(pp, r, g, b, a, in_pixel.blue, in_pixel.bluef,\n               out_pixel.blue, sample_depth, in_pixel.bluee,\n               dp->pm->limit + 1./(2*((1U<<in_pixel.blue_sBIT)-1)), \"blue\",\n               digitization_error);\n\n         if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0 &&\n            in_pixel.alpha != out_pixel.alpha)\n            transform_range_check(pp, r, g, b, a, in_pixel.alpha,\n               in_pixel.alphaf, out_pixel.alpha, sample_depth, in_pixel.alphae,\n               dp->pm->limit + 1./(2*((1U<<in_pixel.alpha_sBIT)-1)), \"alpha\",\n               digitization_error);\n      } /* pixel (x) loop */\n   } /* row (y) loop */\n\n   /* Record that something was actually checked to avoid a false positive. */\n   dp->this.ps->validated = 1;\n}\n\nstatic void PNGCBAPI\ntransform_end(png_structp ppIn, png_infop pi)\n{\n   png_const_structp pp = ppIn;\n   transform_display *dp = voidcast(transform_display*,\n      png_get_progressive_ptr(pp));\n\n   if (!dp->this.speed)\n      transform_image_validate(dp, pp, pi);\n   else\n      dp->this.ps->validated = 1;\n}\n\n/* A single test run. */\nstatic void\ntransform_test(png_modifier *pmIn, const png_uint_32 idIn,\n    const image_transform* transform_listIn, const char * const name)\n{\n   transform_display d;\n   context(&pmIn->this, fault);\n\n   transform_display_init(&d, pmIn, idIn, transform_listIn);\n\n   Try\n   {\n      size_t pos = 0;\n      png_structp pp;\n      png_infop pi;\n      char full_name[256];\n\n      /* Make sure the encoding fields are correct and enter the required\n       * modifications.\n       */\n      transform_set_encoding(&d);\n\n      /* Add any modifications required by the transform list. */\n      d.transform_list->ini(d.transform_list, &d);\n\n      /* Add the color space information, if any, to the name. */\n      pos = safecat(full_name, sizeof full_name, pos, name);\n      pos = safecat_current_encoding(full_name, sizeof full_name, pos, d.pm);\n\n      /* Get a png_struct for reading the image. */\n      pp = set_modifier_for_read(d.pm, &pi, d.this.id, full_name);\n      standard_palette_init(&d.this);\n\n#     if 0\n         /* Logging (debugging only) */\n         {\n            char buffer[256];\n\n            (void)store_message(&d.pm->this, pp, buffer, sizeof buffer, 0,\n               \"running test\");\n\n            fprintf(stderr, \"%s\\n\", buffer);\n         }\n#     endif\n\n      /* Introduce the correct read function. */\n      if (d.pm->this.progressive)\n      {\n         /* Share the row function with the standard implementation. */\n         png_set_progressive_read_fn(pp, &d, transform_info, progressive_row,\n            transform_end);\n\n         /* Now feed data into the reader until we reach the end: */\n         modifier_progressive_read(d.pm, pp, pi);\n      }\n      else\n      {\n         /* modifier_read expects a png_modifier* */\n         png_set_read_fn(pp, d.pm, modifier_read);\n\n         /* Check the header values: */\n         png_read_info(pp, pi);\n\n         /* Process the 'info' requirements. Only one image is generated */\n         transform_info_imp(&d, pp, pi);\n\n         sequential_row(&d.this, pp, pi, -1, 0);\n\n         if (!d.this.speed)\n            transform_image_validate(&d, pp, pi);\n         else\n            d.this.ps->validated = 1;\n      }\n\n      modifier_reset(d.pm);\n   }\n\n   Catch(fault)\n   {\n      modifier_reset(voidcast(png_modifier*,(void*)fault));\n   }\n}\n\n/* The transforms: */\n#define ITSTRUCT(name) image_transform_##name\n#define ITDATA(name) image_transform_data_##name\n#define image_transform_ini image_transform_default_ini\n#define IT(name)\\\nstatic image_transform ITSTRUCT(name) =\\\n{\\\n   #name,\\\n   1, /*enable*/\\\n   &PT, /*list*/\\\n   0, /*global_use*/\\\n   0, /*local_use*/\\\n   0, /*next*/\\\n   image_transform_ini,\\\n   image_transform_png_set_##name##_set,\\\n   image_transform_png_set_##name##_mod,\\\n   image_transform_png_set_##name##_add\\\n}\n#define PT ITSTRUCT(end) /* stores the previous transform */\n\n/* To save code: */\nextern void image_transform_default_ini(const image_transform *this,\n   transform_display *that); /* silence GCC warnings */\n\nvoid /* private, but almost always needed */\nimage_transform_default_ini(const image_transform *this,\n    transform_display *that)\n{\n   this->next->ini(this->next, that);\n}\n\n#ifdef PNG_READ_BACKGROUND_SUPPORTED\nstatic int\nimage_transform_default_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(colour_type)\n   UNUSED(bit_depth)\n\n   this->next = *that;\n   *that = this;\n\n   return 1;\n}\n#endif\n\n#ifdef PNG_READ_EXPAND_SUPPORTED\n/* png_set_palette_to_rgb */\nstatic void\nimage_transform_png_set_palette_to_rgb_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_palette_to_rgb(pp);\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_palette_to_rgb_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   if (that->colour_type == PNG_COLOR_TYPE_PALETTE)\n      image_pixel_convert_PLTE(that);\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_palette_to_rgb_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(bit_depth)\n\n   this->next = *that;\n   *that = this;\n\n   return colour_type == PNG_COLOR_TYPE_PALETTE;\n}\n\nIT(palette_to_rgb);\n#undef PT\n#define PT ITSTRUCT(palette_to_rgb)\n#endif /* PNG_READ_EXPAND_SUPPORTED */\n\n#ifdef PNG_READ_EXPAND_SUPPORTED\n/* png_set_tRNS_to_alpha */\nstatic void\nimage_transform_png_set_tRNS_to_alpha_set(const image_transform *this,\n   transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_tRNS_to_alpha(pp);\n\n   /* If there was a tRNS chunk that would get expanded and add an alpha\n    * channel is_transparent must be updated:\n    */\n   if (that->this.has_tRNS)\n      that->this.is_transparent = 1;\n\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_tRNS_to_alpha_mod(const image_transform *this,\n   image_pixel *that, png_const_structp pp,\n   const transform_display *display)\n{\n#if PNG_LIBPNG_VER < 10700\n   /* LIBPNG BUG: this always forces palette images to RGB. */\n   if (that->colour_type == PNG_COLOR_TYPE_PALETTE)\n      image_pixel_convert_PLTE(that);\n#endif\n\n   /* This effectively does an 'expand' only if there is some transparency to\n    * convert to an alpha channel.\n    */\n   if (that->have_tRNS)\n#     if PNG_LIBPNG_VER >= 10700\n         if (that->colour_type != PNG_COLOR_TYPE_PALETTE &&\n             (that->colour_type & PNG_COLOR_MASK_ALPHA) == 0)\n#     endif\n      image_pixel_add_alpha(that, &display->this, 0/*!for background*/);\n\n#if PNG_LIBPNG_VER < 10700\n   /* LIBPNG BUG: otherwise libpng still expands to 8 bits! */\n   else\n   {\n      if (that->bit_depth < 8)\n         that->bit_depth =8;\n      if (that->sample_depth < 8)\n         that->sample_depth = 8;\n   }\n#endif\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_tRNS_to_alpha_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(bit_depth)\n\n   this->next = *that;\n   *that = this;\n\n   /* We don't know yet whether there will be a tRNS chunk, but we know that\n    * this transformation should do nothing if there already is an alpha\n    * channel.  In addition, after the bug fix in 1.7.0, there is no longer\n    * any action on a palette image.\n    */\n   return\n#  if PNG_LIBPNG_VER >= 10700\n      colour_type != PNG_COLOR_TYPE_PALETTE &&\n#  endif\n   (colour_type & PNG_COLOR_MASK_ALPHA) == 0;\n}\n\nIT(tRNS_to_alpha);\n#undef PT\n#define PT ITSTRUCT(tRNS_to_alpha)\n#endif /* PNG_READ_EXPAND_SUPPORTED */\n\n#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\n/* png_set_gray_to_rgb */\nstatic void\nimage_transform_png_set_gray_to_rgb_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_gray_to_rgb(pp);\n   /* NOTE: this doesn't result in tRNS expansion. */\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_gray_to_rgb_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   /* NOTE: we can actually pend the tRNS processing at this point because we\n    * can correctly recognize the original pixel value even though we have\n    * mapped the one gray channel to the three RGB ones, but in fact libpng\n    * doesn't do this, so we don't either.\n    */\n   if ((that->colour_type & PNG_COLOR_MASK_COLOR) == 0 && that->have_tRNS)\n      image_pixel_add_alpha(that, &display->this, 0/*!for background*/);\n\n   /* Simply expand the bit depth and alter the colour type as required. */\n   if (that->colour_type == PNG_COLOR_TYPE_GRAY)\n   {\n      /* RGB images have a bit depth at least equal to '8' */\n      if (that->bit_depth < 8)\n         that->sample_depth = that->bit_depth = 8;\n\n      /* And just changing the colour type works here because the green and blue\n       * channels are being maintained in lock-step with the red/gray:\n       */\n      that->colour_type = PNG_COLOR_TYPE_RGB;\n   }\n\n   else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n      that->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_gray_to_rgb_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(bit_depth)\n\n   this->next = *that;\n   *that = this;\n\n   return (colour_type & PNG_COLOR_MASK_COLOR) == 0;\n}\n\nIT(gray_to_rgb);\n#undef PT\n#define PT ITSTRUCT(gray_to_rgb)\n#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */\n\n#ifdef PNG_READ_EXPAND_SUPPORTED\n/* png_set_expand */\nstatic void\nimage_transform_png_set_expand_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_expand(pp);\n\n   if (that->this.has_tRNS)\n      that->this.is_transparent = 1;\n\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_expand_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   /* The general expand case depends on what the colour type is: */\n   if (that->colour_type == PNG_COLOR_TYPE_PALETTE)\n      image_pixel_convert_PLTE(that);\n   else if (that->bit_depth < 8) /* grayscale */\n      that->sample_depth = that->bit_depth = 8;\n\n   if (that->have_tRNS)\n      image_pixel_add_alpha(that, &display->this, 0/*!for background*/);\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_expand_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(bit_depth)\n\n   this->next = *that;\n   *that = this;\n\n   /* 'expand' should do nothing for RGBA or GA input - no tRNS and the bit\n    * depth is at least 8 already.\n    */\n   return (colour_type & PNG_COLOR_MASK_ALPHA) == 0;\n}\n\nIT(expand);\n#undef PT\n#define PT ITSTRUCT(expand)\n#endif /* PNG_READ_EXPAND_SUPPORTED */\n\n#ifdef PNG_READ_EXPAND_SUPPORTED\n/* png_set_expand_gray_1_2_4_to_8\n * Pre 1.7.0 LIBPNG BUG: this just does an 'expand'\n */\nstatic void\nimage_transform_png_set_expand_gray_1_2_4_to_8_set(\n    const image_transform *this, transform_display *that, png_structp pp,\n    png_infop pi)\n{\n   png_set_expand_gray_1_2_4_to_8(pp);\n   /* NOTE: don't expect this to expand tRNS */\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_expand_gray_1_2_4_to_8_mod(\n    const image_transform *this, image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n#if PNG_LIBPNG_VER < 10700\n   image_transform_png_set_expand_mod(this, that, pp, display);\n#else\n   /* Only expand grayscale of bit depth less than 8: */\n   if (that->colour_type == PNG_COLOR_TYPE_GRAY &&\n       that->bit_depth < 8)\n      that->sample_depth = that->bit_depth = 8;\n\n   this->next->mod(this->next, that, pp, display);\n#endif /* 1.7 or later */\n}\n\nstatic int\nimage_transform_png_set_expand_gray_1_2_4_to_8_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n#if PNG_LIBPNG_VER < 10700\n   return image_transform_png_set_expand_add(this, that, colour_type,\n      bit_depth);\n#else\n   UNUSED(bit_depth)\n\n   this->next = *that;\n   *that = this;\n\n   /* This should do nothing unless the color type is gray and the bit depth is\n    * less than 8:\n    */\n   return colour_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8;\n#endif /* 1.7 or later */\n}\n\nIT(expand_gray_1_2_4_to_8);\n#undef PT\n#define PT ITSTRUCT(expand_gray_1_2_4_to_8)\n#endif /* PNG_READ_EXPAND_SUPPORTED */\n\n#ifdef PNG_READ_EXPAND_16_SUPPORTED\n/* png_set_expand_16 */\nstatic void\nimage_transform_png_set_expand_16_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_expand_16(pp);\n\n   /* NOTE: prior to 1.7 libpng does SET_EXPAND as well, so tRNS is expanded. */\n#  if PNG_LIBPNG_VER < 10700\n      if (that->this.has_tRNS)\n         that->this.is_transparent = 1;\n#  endif\n\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_expand_16_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   /* Expect expand_16 to expand everything to 16 bits as a result of also\n    * causing 'expand' to happen.\n    */\n   if (that->colour_type == PNG_COLOR_TYPE_PALETTE)\n      image_pixel_convert_PLTE(that);\n\n   if (that->have_tRNS)\n      image_pixel_add_alpha(that, &display->this, 0/*!for background*/);\n\n   if (that->bit_depth < 16)\n      that->sample_depth = that->bit_depth = 16;\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_expand_16_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(colour_type)\n\n   this->next = *that;\n   *that = this;\n\n   /* expand_16 does something unless the bit depth is already 16. */\n   return bit_depth < 16;\n}\n\nIT(expand_16);\n#undef PT\n#define PT ITSTRUCT(expand_16)\n#endif /* PNG_READ_EXPAND_16_SUPPORTED */\n\n#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED  /* API added in 1.5.4 */\n/* png_set_scale_16 */\nstatic void\nimage_transform_png_set_scale_16_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_scale_16(pp);\n#  if PNG_LIBPNG_VER < 10700\n      /* libpng will limit the gamma table size: */\n      that->max_gamma_8 = PNG_MAX_GAMMA_8;\n#  endif\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_scale_16_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   if (that->bit_depth == 16)\n   {\n      that->sample_depth = that->bit_depth = 8;\n      if (that->red_sBIT > 8) that->red_sBIT = 8;\n      if (that->green_sBIT > 8) that->green_sBIT = 8;\n      if (that->blue_sBIT > 8) that->blue_sBIT = 8;\n      if (that->alpha_sBIT > 8) that->alpha_sBIT = 8;\n   }\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_scale_16_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(colour_type)\n\n   this->next = *that;\n   *that = this;\n\n   return bit_depth > 8;\n}\n\nIT(scale_16);\n#undef PT\n#define PT ITSTRUCT(scale_16)\n#endif /* PNG_READ_SCALE_16_TO_8_SUPPORTED (1.5.4 on) */\n\n#ifdef PNG_READ_16_TO_8_SUPPORTED /* the default before 1.5.4 */\n/* png_set_strip_16 */\nstatic void\nimage_transform_png_set_strip_16_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_strip_16(pp);\n#  if PNG_LIBPNG_VER < 10700\n      /* libpng will limit the gamma table size: */\n      that->max_gamma_8 = PNG_MAX_GAMMA_8;\n#  endif\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_strip_16_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   if (that->bit_depth == 16)\n   {\n      that->sample_depth = that->bit_depth = 8;\n      if (that->red_sBIT > 8) that->red_sBIT = 8;\n      if (that->green_sBIT > 8) that->green_sBIT = 8;\n      if (that->blue_sBIT > 8) that->blue_sBIT = 8;\n      if (that->alpha_sBIT > 8) that->alpha_sBIT = 8;\n\n      /* Prior to 1.5.4 png_set_strip_16 would use an 'accurate' method if this\n       * configuration option is set.  From 1.5.4 the flag is never set and the\n       * 'scale' API (above) must be used.\n       */\n#     ifdef PNG_READ_ACCURATE_SCALE_SUPPORTED\n#        if PNG_LIBPNG_VER >= 10504\n#           error PNG_READ_ACCURATE_SCALE should not be set\n#        endif\n\n         /* The strip 16 algorithm drops the low 8 bits rather than calculating\n          * 1/257, so we need to adjust the permitted errors appropriately:\n          * Notice that this is only relevant prior to the addition of the\n          * png_set_scale_16 API in 1.5.4 (but 1.5.4+ always defines the above!)\n          */\n         {\n            const double d = (255-128.5)/65535;\n            that->rede += d;\n            that->greene += d;\n            that->bluee += d;\n            that->alphae += d;\n         }\n#     endif\n   }\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_strip_16_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(colour_type)\n\n   this->next = *that;\n   *that = this;\n\n   return bit_depth > 8;\n}\n\nIT(strip_16);\n#undef PT\n#define PT ITSTRUCT(strip_16)\n#endif /* PNG_READ_16_TO_8_SUPPORTED */\n\n#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED\n/* png_set_strip_alpha */\nstatic void\nimage_transform_png_set_strip_alpha_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_strip_alpha(pp);\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_strip_alpha_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n      that->colour_type = PNG_COLOR_TYPE_GRAY;\n   else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)\n      that->colour_type = PNG_COLOR_TYPE_RGB;\n\n   that->have_tRNS = 0;\n   that->alphaf = 1;\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_strip_alpha_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(bit_depth)\n\n   this->next = *that;\n   *that = this;\n\n   return (colour_type & PNG_COLOR_MASK_ALPHA) != 0;\n}\n\nIT(strip_alpha);\n#undef PT\n#define PT ITSTRUCT(strip_alpha)\n#endif /* PNG_READ_STRIP_ALPHA_SUPPORTED */\n\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\n/* png_set_rgb_to_gray(png_structp, int err_action, double red, double green)\n * png_set_rgb_to_gray_fixed(png_structp, int err_action, png_fixed_point red,\n *    png_fixed_point green)\n * png_get_rgb_to_gray_status\n *\n * The 'default' test here uses values known to be used inside libpng prior to\n * 1.7.0:\n *\n *   red:    6968\n *   green: 23434\n *   blue:   2366\n *\n * These values are being retained for compatibility, along with the somewhat\n * broken truncation calculation in the fast-and-inaccurate code path.  Older\n * versions of libpng will fail the accuracy tests below because they use the\n * truncation algorithm everywhere.\n */\n#define data ITDATA(rgb_to_gray)\nstatic struct\n{\n   double gamma;      /* File gamma to use in processing */\n\n   /* The following are the parameters for png_set_rgb_to_gray: */\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\n      double red_to_set;\n      double green_to_set;\n#  else\n      png_fixed_point red_to_set;\n      png_fixed_point green_to_set;\n#  endif\n\n   /* The actual coefficients: */\n   double red_coefficient;\n   double green_coefficient;\n   double blue_coefficient;\n\n   /* Set if the coeefficients have been overridden. */\n   int coefficients_overridden;\n} data;\n\n#undef image_transform_ini\n#define image_transform_ini image_transform_png_set_rgb_to_gray_ini\nstatic void\nimage_transform_png_set_rgb_to_gray_ini(const image_transform *this,\n    transform_display *that)\n{\n   png_modifier *pm = that->pm;\n   const color_encoding *e = pm->current_encoding;\n\n   UNUSED(this)\n\n   /* Since we check the encoding this flag must be set: */\n   pm->test_uses_encoding = 1;\n\n   /* If 'e' is not NULL chromaticity information is present and either a cHRM\n    * or an sRGB chunk will be inserted.\n    */\n   if (e != 0)\n   {\n      /* Coefficients come from the encoding, but may need to be normalized to a\n       * white point Y of 1.0\n       */\n      const double whiteY = e->red.Y + e->green.Y + e->blue.Y;\n\n      data.red_coefficient = e->red.Y;\n      data.green_coefficient = e->green.Y;\n      data.blue_coefficient = e->blue.Y;\n\n      if (whiteY != 1)\n      {\n         data.red_coefficient /= whiteY;\n         data.green_coefficient /= whiteY;\n         data.blue_coefficient /= whiteY;\n      }\n   }\n\n   else\n   {\n      /* The default (built in) coeffcients, as above: */\n#     if PNG_LIBPNG_VER < 10700\n         data.red_coefficient = 6968 / 32768.;\n         data.green_coefficient = 23434 / 32768.;\n         data.blue_coefficient = 2366 / 32768.;\n#     else\n         data.red_coefficient = .2126;\n         data.green_coefficient = .7152;\n         data.blue_coefficient = .0722;\n#     endif\n   }\n\n   data.gamma = pm->current_gamma;\n\n   /* If not set then the calculations assume linear encoding (implicitly): */\n   if (data.gamma == 0)\n      data.gamma = 1;\n\n   /* The arguments to png_set_rgb_to_gray can override the coefficients implied\n    * by the color space encoding.  If doing exhaustive checks do the override\n    * in each case, otherwise do it randomly.\n    */\n   if (pm->test_exhaustive)\n   {\n      /* First time in coefficients_overridden is 0, the following sets it to 1,\n       * so repeat if it is set.  If a test fails this may mean we subsequently\n       * skip a non-override test, ignore that.\n       */\n      data.coefficients_overridden = !data.coefficients_overridden;\n      pm->repeat = data.coefficients_overridden != 0;\n   }\n\n   else\n      data.coefficients_overridden = random_choice();\n\n   if (data.coefficients_overridden)\n   {\n      /* These values override the color encoding defaults, simply use random\n       * numbers.\n       */\n      png_uint_32 ru;\n      double total;\n\n      R32_1(ru);\n      data.green_coefficient = total = (ru & 0xffff) / 65535.;\n      ru >>= 16;\n      data.red_coefficient = (1 - total) * (ru & 0xffff) / 65535.;\n      total += data.red_coefficient;\n      data.blue_coefficient = 1 - total;\n\n#     ifdef PNG_FLOATING_POINT_SUPPORTED\n         data.red_to_set = data.red_coefficient;\n         data.green_to_set = data.green_coefficient;\n#     else\n         data.red_to_set = fix(data.red_coefficient);\n         data.green_to_set = fix(data.green_coefficient);\n#     endif\n\n      /* The following just changes the error messages: */\n      pm->encoding_ignored = 1;\n   }\n\n   else\n   {\n      data.red_to_set = -1;\n      data.green_to_set = -1;\n   }\n\n   /* Adjust the error limit in the png_modifier because of the larger errors\n    * produced in the digitization during the gamma handling.\n    */\n   if (data.gamma != 1) /* Use gamma tables */\n   {\n      if (that->this.bit_depth == 16 || pm->assume_16_bit_calculations)\n      {\n         /* The computations have the form:\n          *\n          *    r * rc + g * gc + b * bc\n          *\n          *  Each component of which is +/-1/65535 from the gamma_to_1 table\n          *  lookup, resulting in a base error of +/-6.  The gamma_from_1\n          *  conversion adds another +/-2 in the 16-bit case and\n          *  +/-(1<<(15-PNG_MAX_GAMMA_8)) in the 8-bit case.\n          */\n#        if PNG_LIBPNG_VER < 10700\n            if (that->this.bit_depth < 16)\n               that->max_gamma_8 = PNG_MAX_GAMMA_8;\n#        endif\n         that->pm->limit += pow(\n            (that->this.bit_depth == 16 || that->max_gamma_8 > 14 ?\n               8. :\n               6. + (1<<(15-that->max_gamma_8))\n            )/65535, data.gamma);\n      }\n\n      else\n      {\n         /* Rounding to 8 bits in the linear space causes massive errors which\n          * will trigger the error check in transform_range_check.  Fix that\n          * here by taking the gamma encoding into account.\n          *\n          * When DIGITIZE is set because a pre-1.7 version of libpng is being\n          * tested allow a bigger slack.\n          *\n          * NOTE: this number only affects the internal limit check in pngvalid,\n          * it has no effect on the limits applied to the libpng values.\n          */\n         that->pm->limit += pow(\n#        if DIGITIZE\n            2.0\n#        else\n            1.0\n#        endif\n            /255, data.gamma);\n      }\n   }\n\n   else\n   {\n      /* With no gamma correction a large error comes from the truncation of the\n       * calculation in the 8 bit case, allow for that here.\n       */\n      if (that->this.bit_depth != 16 && !pm->assume_16_bit_calculations)\n         that->pm->limit += 4E-3;\n   }\n}\n\nstatic void\nimage_transform_png_set_rgb_to_gray_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   const int error_action = 1; /* no error, no defines in png.h */\n\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\n      png_set_rgb_to_gray(pp, error_action, data.red_to_set, data.green_to_set);\n#  else\n      png_set_rgb_to_gray_fixed(pp, error_action, data.red_to_set,\n         data.green_to_set);\n#  endif\n\n#  ifdef PNG_READ_cHRM_SUPPORTED\n      if (that->pm->current_encoding != 0)\n      {\n         /* We have an encoding so a cHRM chunk may have been set; if so then\n          * check that the libpng APIs give the correct (X,Y,Z) values within\n          * some margin of error for the round trip through the chromaticity\n          * form.\n          */\n#        ifdef PNG_FLOATING_POINT_SUPPORTED\n#           define API_function png_get_cHRM_XYZ\n#           define API_form \"FP\"\n#           define API_type double\n#           define API_cvt(x) (x)\n#        else\n#           define API_function png_get_cHRM_XYZ_fixed\n#           define API_form \"fixed\"\n#           define API_type png_fixed_point\n#           define API_cvt(x) ((double)(x)/PNG_FP_1)\n#        endif\n\n         API_type rX, gX, bX;\n         API_type rY, gY, bY;\n         API_type rZ, gZ, bZ;\n\n         if ((API_function(pp, pi, &rX, &rY, &rZ, &gX, &gY, &gZ, &bX, &bY, &bZ)\n               & PNG_INFO_cHRM) != 0)\n         {\n            double maxe;\n            const char *el;\n            color_encoding e, o;\n\n            /* Expect libpng to return a normalized result, but the original\n             * color space encoding may not be normalized.\n             */\n            modifier_current_encoding(that->pm, &o);\n            normalize_color_encoding(&o);\n\n            /* Sanity check the pngvalid code - the coefficients should match\n             * the normalized Y values of the encoding unless they were\n             * overridden.\n             */\n            if (data.red_to_set == -1 && data.green_to_set == -1 &&\n               (fabs(o.red.Y - data.red_coefficient) > DBL_EPSILON ||\n               fabs(o.green.Y - data.green_coefficient) > DBL_EPSILON ||\n               fabs(o.blue.Y - data.blue_coefficient) > DBL_EPSILON))\n               png_error(pp, \"internal pngvalid cHRM coefficient error\");\n\n            /* Generate a colour space encoding. */\n            e.gamma = o.gamma; /* not used */\n            e.red.X = API_cvt(rX);\n            e.red.Y = API_cvt(rY);\n            e.red.Z = API_cvt(rZ);\n            e.green.X = API_cvt(gX);\n            e.green.Y = API_cvt(gY);\n            e.green.Z = API_cvt(gZ);\n            e.blue.X = API_cvt(bX);\n            e.blue.Y = API_cvt(bY);\n            e.blue.Z = API_cvt(bZ);\n\n            /* This should match the original one from the png_modifier, within\n             * the range permitted by the libpng fixed point representation.\n             */\n            maxe = 0;\n            el = \"-\"; /* Set to element name with error */\n\n#           define CHECK(col,x)\\\n            {\\\n               double err = fabs(o.col.x - e.col.x);\\\n               if (err > maxe)\\\n               {\\\n                  maxe = err;\\\n                  el = #col \"(\" #x \")\";\\\n               }\\\n            }\n\n            CHECK(red,X)\n            CHECK(red,Y)\n            CHECK(red,Z)\n            CHECK(green,X)\n            CHECK(green,Y)\n            CHECK(green,Z)\n            CHECK(blue,X)\n            CHECK(blue,Y)\n            CHECK(blue,Z)\n\n            /* Here in both fixed and floating cases to check the values read\n             * from the cHRm chunk.  PNG uses fixed point in the cHRM chunk, so\n             * we can't expect better than +/-.5E-5 on the result, allow 1E-5.\n             */\n            if (maxe >= 1E-5)\n            {\n               size_t pos = 0;\n               char buffer[256];\n\n               pos = safecat(buffer, sizeof buffer, pos, API_form);\n               pos = safecat(buffer, sizeof buffer, pos, \" cHRM \");\n               pos = safecat(buffer, sizeof buffer, pos, el);\n               pos = safecat(buffer, sizeof buffer, pos, \" error: \");\n               pos = safecatd(buffer, sizeof buffer, pos, maxe, 7);\n               pos = safecat(buffer, sizeof buffer, pos, \" \");\n               /* Print the color space without the gamma value: */\n               pos = safecat_color_encoding(buffer, sizeof buffer, pos, &o, 0);\n               pos = safecat(buffer, sizeof buffer, pos, \" -> \");\n               pos = safecat_color_encoding(buffer, sizeof buffer, pos, &e, 0);\n\n               png_error(pp, buffer);\n            }\n         }\n      }\n#  endif /* READ_cHRM */\n\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_rgb_to_gray_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   if ((that->colour_type & PNG_COLOR_MASK_COLOR) != 0)\n   {\n      double gray, err;\n\n#     if PNG_LIBPNG_VER < 10700\n         if (that->colour_type == PNG_COLOR_TYPE_PALETTE)\n            image_pixel_convert_PLTE(that);\n#     endif\n\n      /* Image now has RGB channels... */\n#  if DIGITIZE\n      {\n         png_modifier *pm = display->pm;\n         const unsigned int sample_depth = that->sample_depth;\n         const unsigned int calc_depth = (pm->assume_16_bit_calculations ? 16 :\n            sample_depth);\n         const unsigned int gamma_depth =\n            (sample_depth == 16 ?\n               display->max_gamma_8 :\n               (pm->assume_16_bit_calculations ?\n                  display->max_gamma_8 :\n                  sample_depth));\n         int isgray;\n         double r, g, b;\n         double rlo, rhi, glo, ghi, blo, bhi, graylo, grayhi;\n\n         /* Do this using interval arithmetic, otherwise it is too difficult to\n          * handle the errors correctly.\n          *\n          * To handle the gamma correction work out the upper and lower bounds\n          * of the digitized value.  Assume rounding here - normally the values\n          * will be identical after this operation if there is only one\n          * transform, feel free to delete the png_error checks on this below in\n          * the future (this is just me trying to ensure it works!)\n          *\n          * Interval arithmetic is exact, but to implement it it must be\n          * possible to control the floating point implementation rounding mode.\n          * This cannot be done in ANSI-C, so instead I reduce the 'lo' values\n          * by DBL_EPSILON and increase the 'hi' values by the same.\n          */\n#        define DD(v,d,r) (digitize(v*(1-DBL_EPSILON), d, r) * (1-DBL_EPSILON))\n#        define DU(v,d,r) (digitize(v*(1+DBL_EPSILON), d, r) * (1+DBL_EPSILON))\n\n         r = rlo = rhi = that->redf;\n         rlo -= that->rede;\n         rlo = DD(rlo, calc_depth, 1/*round*/);\n         rhi += that->rede;\n         rhi = DU(rhi, calc_depth, 1/*round*/);\n\n         g = glo = ghi = that->greenf;\n         glo -= that->greene;\n         glo = DD(glo, calc_depth, 1/*round*/);\n         ghi += that->greene;\n         ghi = DU(ghi, calc_depth, 1/*round*/);\n\n         b = blo = bhi = that->bluef;\n         blo -= that->bluee;\n         blo = DD(blo, calc_depth, 1/*round*/);\n         bhi += that->bluee;\n         bhi = DU(bhi, calc_depth, 1/*round*/);\n\n         isgray = r==g && g==b;\n\n         if (data.gamma != 1)\n         {\n            const double power = 1/data.gamma;\n            const double abse = .5/(sample_depth == 16 ? 65535 : 255);\n\n            /* If a gamma calculation is done it is done using lookup tables of\n             * precision gamma_depth, so the already digitized value above may\n             * need to be further digitized here.\n             */\n            if (gamma_depth != calc_depth)\n            {\n               rlo = DD(rlo, gamma_depth, 0/*truncate*/);\n               rhi = DU(rhi, gamma_depth, 0/*truncate*/);\n               glo = DD(glo, gamma_depth, 0/*truncate*/);\n               ghi = DU(ghi, gamma_depth, 0/*truncate*/);\n               blo = DD(blo, gamma_depth, 0/*truncate*/);\n               bhi = DU(bhi, gamma_depth, 0/*truncate*/);\n            }\n\n            /* 'abse' is the error in the gamma table calculation itself. */\n            r = pow(r, power);\n            rlo = DD(pow(rlo, power)-abse, calc_depth, 1);\n            rhi = DU(pow(rhi, power)+abse, calc_depth, 1);\n\n            g = pow(g, power);\n            glo = DD(pow(glo, power)-abse, calc_depth, 1);\n            ghi = DU(pow(ghi, power)+abse, calc_depth, 1);\n\n            b = pow(b, power);\n            blo = DD(pow(blo, power)-abse, calc_depth, 1);\n            bhi = DU(pow(bhi, power)+abse, calc_depth, 1);\n         }\n\n         /* Now calculate the actual gray values.  Although the error in the\n          * coefficients depends on whether they were specified on the command\n          * line (in which case truncation to 15 bits happened) or not (rounding\n          * was used) the maxium error in an individual coefficient is always\n          * 2/32768, because even in the rounding case the requirement that\n          * coefficients add up to 32768 can cause a larger rounding error.\n          *\n          * The only time when rounding doesn't occur in 1.5.5 and later is when\n          * the non-gamma code path is used for less than 16 bit data.\n          */\n         gray = r * data.red_coefficient + g * data.green_coefficient +\n            b * data.blue_coefficient;\n\n         {\n            const int do_round = data.gamma != 1 || calc_depth == 16;\n            const double ce = 2. / 32768;\n\n            graylo = DD(rlo * (data.red_coefficient-ce) +\n               glo * (data.green_coefficient-ce) +\n               blo * (data.blue_coefficient-ce), calc_depth, do_round);\n            if (graylo > gray) /* always accept the right answer */\n               graylo = gray;\n\n            grayhi = DU(rhi * (data.red_coefficient+ce) +\n               ghi * (data.green_coefficient+ce) +\n               bhi * (data.blue_coefficient+ce), calc_depth, do_round);\n            if (grayhi < gray)\n               grayhi = gray;\n         }\n\n         /* And invert the gamma. */\n         if (data.gamma != 1)\n         {\n            const double power = data.gamma;\n\n            /* And this happens yet again, shifting the values once more. */\n            if (gamma_depth != sample_depth)\n            {\n               rlo = DD(rlo, gamma_depth, 0/*truncate*/);\n               rhi = DU(rhi, gamma_depth, 0/*truncate*/);\n               glo = DD(glo, gamma_depth, 0/*truncate*/);\n               ghi = DU(ghi, gamma_depth, 0/*truncate*/);\n               blo = DD(blo, gamma_depth, 0/*truncate*/);\n               bhi = DU(bhi, gamma_depth, 0/*truncate*/);\n            }\n\n            gray = pow(gray, power);\n            graylo = DD(pow(graylo, power), sample_depth, 1);\n            grayhi = DU(pow(grayhi, power), sample_depth, 1);\n         }\n\n#        undef DD\n#        undef DU\n\n         /* Now the error can be calculated.\n          *\n          * If r==g==b because there is no overall gamma correction libpng\n          * currently preserves the original value.\n          */\n         if (isgray)\n            err = (that->rede + that->greene + that->bluee)/3;\n\n         else\n         {\n            err = fabs(grayhi-gray);\n\n            if (fabs(gray - graylo) > err)\n               err = fabs(graylo-gray);\n\n#if !RELEASE_BUILD\n            /* Check that this worked: */\n            if (err > pm->limit)\n            {\n               size_t pos = 0;\n               char buffer[128];\n\n               pos = safecat(buffer, sizeof buffer, pos, \"rgb_to_gray error \");\n               pos = safecatd(buffer, sizeof buffer, pos, err, 6);\n               pos = safecat(buffer, sizeof buffer, pos, \" exceeds limit \");\n               pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6);\n               png_warning(pp, buffer);\n               pm->limit = err;\n            }\n#endif /* !RELEASE_BUILD */\n         }\n      }\n#  else  /* !DIGITIZE */\n      {\n         double r = that->redf;\n         double re = that->rede;\n         double g = that->greenf;\n         double ge = that->greene;\n         double b = that->bluef;\n         double be = that->bluee;\n\n#        if PNG_LIBPNG_VER < 10700\n            /* The true gray case involves no math in earlier versions (not\n             * true, there was some if gamma correction was happening too.)\n             */\n            if (r == g && r == b)\n            {\n               gray = r;\n               err = re;\n               if (err < ge) err = ge;\n               if (err < be) err = be;\n            }\n\n            else\n#        endif /* before 1.7 */\n         if (data.gamma == 1)\n         {\n            /* There is no need to do the conversions to and from linear space,\n             * so the calculation should be a lot more accurate.  There is a\n             * built in error in the coefficients because they only have 15 bits\n             * and are adjusted to make sure they add up to 32768.  This\n             * involves a integer calculation with truncation of the form:\n             *\n             *     ((int)(coefficient * 100000) * 32768)/100000\n             *\n             * This is done to the red and green coefficients (the ones\n             * provided to the API) then blue is calculated from them so the\n             * result adds up to 32768.  In the worst case this can result in\n             * a -1 error in red and green and a +2 error in blue.  Consequently\n             * the worst case in the calculation below is 2/32768 error.\n             *\n             * TODO: consider fixing this in libpng by rounding the calculation\n             * limiting the error to 1/32768.\n             *\n             * Handling this by adding 2/32768 here avoids needing to increase\n             * the global error limits to take this into account.)\n             */\n            gray = r * data.red_coefficient + g * data.green_coefficient +\n               b * data.blue_coefficient;\n            err = re * data.red_coefficient + ge * data.green_coefficient +\n               be * data.blue_coefficient + 2./32768 + gray * 5 * DBL_EPSILON;\n         }\n\n         else\n         {\n            /* The calculation happens in linear space, and this produces much\n             * wider errors in the encoded space.  These are handled here by\n             * factoring the errors in to the calculation.  There are two table\n             * lookups in the calculation and each introduces a quantization\n             * error defined by the table size.\n             */\n            png_modifier *pm = display->pm;\n            double in_qe = (that->sample_depth > 8 ? .5/65535 : .5/255);\n            double out_qe = (that->sample_depth > 8 ? .5/65535 :\n               (pm->assume_16_bit_calculations ? .5/(1<<display->max_gamma_8) :\n               .5/255));\n            double rhi, ghi, bhi, grayhi;\n            double g1 = 1/data.gamma;\n\n            rhi = r + re + in_qe; if (rhi > 1) rhi = 1;\n            r -= re + in_qe; if (r < 0) r = 0;\n            ghi = g + ge + in_qe; if (ghi > 1) ghi = 1;\n            g -= ge + in_qe; if (g < 0) g = 0;\n            bhi = b + be + in_qe; if (bhi > 1) bhi = 1;\n            b -= be + in_qe; if (b < 0) b = 0;\n\n            r = pow(r, g1)*(1-DBL_EPSILON); rhi = pow(rhi, g1)*(1+DBL_EPSILON);\n            g = pow(g, g1)*(1-DBL_EPSILON); ghi = pow(ghi, g1)*(1+DBL_EPSILON);\n            b = pow(b, g1)*(1-DBL_EPSILON); bhi = pow(bhi, g1)*(1+DBL_EPSILON);\n\n            /* Work out the lower and upper bounds for the gray value in the\n             * encoded space, then work out an average and error.  Remove the\n             * previously added input quantization error at this point.\n             */\n            gray = r * data.red_coefficient + g * data.green_coefficient +\n               b * data.blue_coefficient - 2./32768 - out_qe;\n            if (gray <= 0)\n               gray = 0;\n            else\n            {\n               gray *= (1 - 6 * DBL_EPSILON);\n               gray = pow(gray, data.gamma) * (1-DBL_EPSILON);\n            }\n\n            grayhi = rhi * data.red_coefficient + ghi * data.green_coefficient +\n               bhi * data.blue_coefficient + 2./32768 + out_qe;\n            grayhi *= (1 + 6 * DBL_EPSILON);\n            if (grayhi >= 1)\n               grayhi = 1;\n            else\n               grayhi = pow(grayhi, data.gamma) * (1+DBL_EPSILON);\n\n            err = (grayhi - gray) / 2;\n            gray = (grayhi + gray) / 2;\n\n            if (err <= in_qe)\n               err = gray * DBL_EPSILON;\n\n            else\n               err -= in_qe;\n\n#if !RELEASE_BUILD\n            /* Validate that the error is within limits (this has caused\n             * problems before, it's much easier to detect them here.)\n             */\n            if (err > pm->limit)\n            {\n               size_t pos = 0;\n               char buffer[128];\n\n               pos = safecat(buffer, sizeof buffer, pos, \"rgb_to_gray error \");\n               pos = safecatd(buffer, sizeof buffer, pos, err, 6);\n               pos = safecat(buffer, sizeof buffer, pos, \" exceeds limit \");\n               pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6);\n               png_warning(pp, buffer);\n               pm->limit = err;\n            }\n#endif /* !RELEASE_BUILD */\n         }\n      }\n#  endif /* !DIGITIZE */\n\n      that->bluef = that->greenf = that->redf = gray;\n      that->bluee = that->greene = that->rede = err;\n\n      /* The sBIT is the minium of the three colour channel sBITs. */\n      if (that->red_sBIT > that->green_sBIT)\n         that->red_sBIT = that->green_sBIT;\n      if (that->red_sBIT > that->blue_sBIT)\n         that->red_sBIT = that->blue_sBIT;\n      that->blue_sBIT = that->green_sBIT = that->red_sBIT;\n\n      /* And remove the colour bit in the type: */\n      if (that->colour_type == PNG_COLOR_TYPE_RGB)\n         that->colour_type = PNG_COLOR_TYPE_GRAY;\n      else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)\n         that->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;\n   }\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_rgb_to_gray_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(bit_depth)\n\n   this->next = *that;\n   *that = this;\n\n   return (colour_type & PNG_COLOR_MASK_COLOR) != 0;\n}\n\n#undef data\nIT(rgb_to_gray);\n#undef PT\n#define PT ITSTRUCT(rgb_to_gray)\n#undef image_transform_ini\n#define image_transform_ini image_transform_default_ini\n#endif /* PNG_READ_RGB_TO_GRAY_SUPPORTED */\n\n#ifdef PNG_READ_BACKGROUND_SUPPORTED\n/* png_set_background(png_structp, png_const_color_16p background_color,\n *    int background_gamma_code, int need_expand, double background_gamma)\n * png_set_background_fixed(png_structp, png_const_color_16p background_color,\n *    int background_gamma_code, int need_expand,\n *    png_fixed_point background_gamma)\n *\n * This ignores the gamma (at present.)\n*/\n#define data ITDATA(background)\nstatic image_pixel data;\n\nstatic void\nimage_transform_png_set_background_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_byte colour_type, bit_depth;\n   png_byte random_bytes[8]; /* 8 bytes - 64 bits - the biggest pixel */\n   int expand;\n   png_color_16 back;\n\n   /* We need a background colour, because we don't know exactly what transforms\n    * have been set we have to supply the colour in the original file format and\n    * so we need to know what that is!  The background colour is stored in the\n    * transform_display.\n    */\n   R8(random_bytes);\n\n   /* Read the random value, for colour type 3 the background colour is actually\n    * expressed as a 24bit rgb, not an index.\n    */\n   colour_type = that->this.colour_type;\n   if (colour_type == 3)\n   {\n      colour_type = PNG_COLOR_TYPE_RGB;\n      bit_depth = 8;\n      expand = 0; /* passing in an RGB not a pixel index */\n   }\n\n   else\n   {\n      if (that->this.has_tRNS)\n         that->this.is_transparent = 1;\n\n      bit_depth = that->this.bit_depth;\n      expand = 1;\n   }\n\n   image_pixel_init(&data, random_bytes, colour_type,\n      bit_depth, 0/*x*/, 0/*unused: palette*/, NULL/*format*/);\n\n   /* Extract the background colour from this image_pixel, but make sure the\n    * unused fields of 'back' are garbage.\n    */\n   R8(back);\n\n   if (colour_type & PNG_COLOR_MASK_COLOR)\n   {\n      back.red = (png_uint_16)data.red;\n      back.green = (png_uint_16)data.green;\n      back.blue = (png_uint_16)data.blue;\n   }\n\n   else\n      back.gray = (png_uint_16)data.red;\n\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\n      png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0);\n#  else\n      png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0);\n#  endif\n\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_background_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   /* Check for tRNS first: */\n   if (that->have_tRNS && that->colour_type != PNG_COLOR_TYPE_PALETTE)\n      image_pixel_add_alpha(that, &display->this, 1/*for background*/);\n\n   /* This is only necessary if the alpha value is less than 1. */\n   if (that->alphaf < 1)\n   {\n      /* Now we do the background calculation without any gamma correction. */\n      if (that->alphaf <= 0)\n      {\n         that->redf = data.redf;\n         that->greenf = data.greenf;\n         that->bluef = data.bluef;\n\n         that->rede = data.rede;\n         that->greene = data.greene;\n         that->bluee = data.bluee;\n\n         that->red_sBIT= data.red_sBIT;\n         that->green_sBIT= data.green_sBIT;\n         that->blue_sBIT= data.blue_sBIT;\n      }\n\n      else /* 0 < alpha < 1 */\n      {\n         double alf = 1 - that->alphaf;\n\n         that->redf = that->redf * that->alphaf + data.redf * alf;\n         that->rede = that->rede * that->alphaf + data.rede * alf +\n            DBL_EPSILON;\n         that->greenf = that->greenf * that->alphaf + data.greenf * alf;\n         that->greene = that->greene * that->alphaf + data.greene * alf +\n            DBL_EPSILON;\n         that->bluef = that->bluef * that->alphaf + data.bluef * alf;\n         that->bluee = that->bluee * that->alphaf + data.bluee * alf +\n            DBL_EPSILON;\n      }\n\n      /* Remove the alpha type and set the alpha (not in that order.) */\n      that->alphaf = 1;\n      that->alphae = 0;\n   }\n\n   if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)\n      that->colour_type = PNG_COLOR_TYPE_RGB;\n   else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n      that->colour_type = PNG_COLOR_TYPE_GRAY;\n   /* PNG_COLOR_TYPE_PALETTE is not changed */\n\n   this->next->mod(this->next, that, pp, display);\n}\n\n#define image_transform_png_set_background_add image_transform_default_add\n\n#undef data\nIT(background);\n#undef PT\n#define PT ITSTRUCT(background)\n#endif /* PNG_READ_BACKGROUND_SUPPORTED */\n\n/* png_set_quantize(png_structp, png_colorp palette, int num_palette,\n *    int maximum_colors, png_const_uint_16p histogram, int full_quantize)\n *\n * Very difficult to validate this!\n */\n/*NOTE: TBD NYI */\n\n/* The data layout transforms are handled by swapping our own channel data,\n * necessarily these need to happen at the end of the transform list because the\n * semantic of the channels changes after these are executed.  Some of these,\n * like set_shift and set_packing, can't be done at present because they change\n * the layout of the data at the sub-sample level so sample() won't get the\n * right answer.\n */\n/* png_set_invert_alpha */\n#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED\n/* Invert the alpha channel\n *\n *  png_set_invert_alpha(png_structrp png_ptr)\n */\nstatic void\nimage_transform_png_set_invert_alpha_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_invert_alpha(pp);\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_invert_alpha_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   if (that->colour_type & 4)\n      that->alpha_inverted = 1;\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_invert_alpha_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(bit_depth)\n\n   this->next = *that;\n   *that = this;\n\n   /* Only has an effect on pixels with alpha: */\n   return (colour_type & 4) != 0;\n}\n\nIT(invert_alpha);\n#undef PT\n#define PT ITSTRUCT(invert_alpha)\n\n#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */\n\n/* png_set_bgr */\n#ifdef PNG_READ_BGR_SUPPORTED\n/* Swap R,G,B channels to order B,G,R.\n *\n *  png_set_bgr(png_structrp png_ptr)\n *\n * This only has an effect on RGB and RGBA pixels.\n */\nstatic void\nimage_transform_png_set_bgr_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_bgr(pp);\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_bgr_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   if (that->colour_type == PNG_COLOR_TYPE_RGB ||\n       that->colour_type == PNG_COLOR_TYPE_RGBA)\n       that->swap_rgb = 1;\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_bgr_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(bit_depth)\n\n   this->next = *that;\n   *that = this;\n\n   return colour_type == PNG_COLOR_TYPE_RGB ||\n       colour_type == PNG_COLOR_TYPE_RGBA;\n}\n\nIT(bgr);\n#undef PT\n#define PT ITSTRUCT(bgr)\n\n#endif /* PNG_READ_BGR_SUPPORTED */\n\n/* png_set_swap_alpha */\n#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED\n/* Put the alpha channel first.\n *\n *  png_set_swap_alpha(png_structrp png_ptr)\n *\n * This only has an effect on GA and RGBA pixels.\n */\nstatic void\nimage_transform_png_set_swap_alpha_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_swap_alpha(pp);\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_swap_alpha_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   if (that->colour_type == PNG_COLOR_TYPE_GA ||\n       that->colour_type == PNG_COLOR_TYPE_RGBA)\n      that->alpha_first = 1;\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_swap_alpha_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(bit_depth)\n\n   this->next = *that;\n   *that = this;\n\n   return colour_type == PNG_COLOR_TYPE_GA ||\n       colour_type == PNG_COLOR_TYPE_RGBA;\n}\n\nIT(swap_alpha);\n#undef PT\n#define PT ITSTRUCT(swap_alpha)\n\n#endif /* PNG_READ_SWAP_ALPHA_SUPPORTED */\n\n/* png_set_swap */\n#ifdef PNG_READ_SWAP_SUPPORTED\n/* Byte swap 16-bit components.\n *\n *  png_set_swap(png_structrp png_ptr)\n */\nstatic void\nimage_transform_png_set_swap_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_swap(pp);\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_swap_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   if (that->bit_depth == 16)\n      that->swap16 = 1;\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_swap_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(colour_type)\n\n   this->next = *that;\n   *that = this;\n\n   return bit_depth == 16;\n}\n\nIT(swap);\n#undef PT\n#define PT ITSTRUCT(swap)\n\n#endif /* PNG_READ_SWAP_SUPPORTED */\n\n#ifdef PNG_READ_FILLER_SUPPORTED\n/* Add a filler byte to 8-bit Gray or 24-bit RGB images.\n *\n *  png_set_filler, (png_structp png_ptr, png_uint_32 filler, int flags));\n *\n * Flags:\n *\n *  PNG_FILLER_BEFORE\n *  PNG_FILLER_AFTER\n */\n#define data ITDATA(filler)\nstatic struct\n{\n   png_uint_32 filler;\n   int         flags;\n} data;\n\nstatic void\nimage_transform_png_set_filler_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   /* Need a random choice for 'before' and 'after' as well as for the\n    * filler.  The 'filler' value has all 32 bits set, but only bit_depth\n    * will be used.  At this point we don't know bit_depth.\n    */\n   R32(data.filler);\n   data.flags = random_choice();\n\n   png_set_filler(pp, data.filler, data.flags);\n\n   /* The standard display handling stuff also needs to know that\n    * there is a filler, so set that here.\n    */\n   that->this.filler = 1;\n\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_filler_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   if (that->bit_depth >= 8 &&\n       (that->colour_type == PNG_COLOR_TYPE_RGB ||\n        that->colour_type == PNG_COLOR_TYPE_GRAY))\n   {\n      const unsigned int max = (1U << that->bit_depth)-1;\n      that->alpha = data.filler & max;\n      that->alphaf = ((double)that->alpha) / max;\n      that->alphae = 0;\n\n      /* The filler has been stored in the alpha channel, we must record\n       * that this has been done for the checking later on, the color\n       * type is faked to have an alpha channel, but libpng won't report\n       * this; the app has to know the extra channel is there and this\n       * was recording in standard_display::filler above.\n       */\n      that->colour_type |= 4; /* alpha added */\n      that->alpha_first = data.flags == PNG_FILLER_BEFORE;\n   }\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_filler_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   this->next = *that;\n   *that = this;\n\n   return bit_depth >= 8 && (colour_type == PNG_COLOR_TYPE_RGB ||\n           colour_type == PNG_COLOR_TYPE_GRAY);\n}\n\n#undef data\nIT(filler);\n#undef PT\n#define PT ITSTRUCT(filler)\n\n/* png_set_add_alpha, (png_structp png_ptr, png_uint_32 filler, int flags)); */\n/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */\n#define data ITDATA(add_alpha)\nstatic struct\n{\n   png_uint_32 filler;\n   int         flags;\n} data;\n\nstatic void\nimage_transform_png_set_add_alpha_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   /* Need a random choice for 'before' and 'after' as well as for the\n    * filler.  The 'filler' value has all 32 bits set, but only bit_depth\n    * will be used.  At this point we don't know bit_depth.\n    */\n   R32(data.filler);\n   data.flags = random_choice();\n\n   png_set_add_alpha(pp, data.filler, data.flags);\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_add_alpha_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   if (that->bit_depth >= 8 &&\n       (that->colour_type == PNG_COLOR_TYPE_RGB ||\n        that->colour_type == PNG_COLOR_TYPE_GRAY))\n   {\n      const unsigned int max = (1U << that->bit_depth)-1;\n      that->alpha = data.filler & max;\n      that->alphaf = ((double)that->alpha) / max;\n      that->alphae = 0;\n\n      that->colour_type |= 4; /* alpha added */\n      that->alpha_first = data.flags == PNG_FILLER_BEFORE;\n   }\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_add_alpha_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   this->next = *that;\n   *that = this;\n\n   return bit_depth >= 8 && (colour_type == PNG_COLOR_TYPE_RGB ||\n           colour_type == PNG_COLOR_TYPE_GRAY);\n}\n\n#undef data\nIT(add_alpha);\n#undef PT\n#define PT ITSTRUCT(add_alpha)\n\n#endif /* PNG_READ_FILLER_SUPPORTED */\n\n/* png_set_packing */\n#ifdef PNG_READ_PACK_SUPPORTED\n/* Use 1 byte per pixel in 1, 2, or 4-bit depth files.\n *\n *  png_set_packing(png_structrp png_ptr)\n *\n * This should only affect grayscale and palette images with less than 8 bits\n * per pixel.\n */\nstatic void\nimage_transform_png_set_packing_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_packing(pp);\n   that->unpacked = 1;\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_packing_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   /* The general expand case depends on what the colour type is,\n    * low bit-depth pixel values are unpacked into bytes without\n    * scaling, so sample_depth is not changed.\n    */\n   if (that->bit_depth < 8) /* grayscale or palette */\n      that->bit_depth = 8;\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_packing_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(colour_type)\n\n   this->next = *that;\n   *that = this;\n\n   /* Nothing should happen unless the bit depth is less than 8: */\n   return bit_depth < 8;\n}\n\nIT(packing);\n#undef PT\n#define PT ITSTRUCT(packing)\n\n#endif /* PNG_READ_PACK_SUPPORTED */\n\n/* png_set_packswap */\n#ifdef PNG_READ_PACKSWAP_SUPPORTED\n/* Swap pixels packed into bytes; reverses the order on screen so that\n * the high order bits correspond to the rightmost pixels.\n *\n *  png_set_packswap(png_structrp png_ptr)\n */\nstatic void\nimage_transform_png_set_packswap_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_packswap(pp);\n   that->this.littleendian = 1;\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_packswap_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   if (that->bit_depth < 8)\n      that->littleendian = 1;\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_packswap_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(colour_type)\n\n   this->next = *that;\n   *that = this;\n\n   return bit_depth < 8;\n}\n\nIT(packswap);\n#undef PT\n#define PT ITSTRUCT(packswap)\n\n#endif /* PNG_READ_PACKSWAP_SUPPORTED */\n\n\n/* png_set_invert_mono */\n#ifdef PNG_READ_INVERT_MONO_SUPPORTED\n/* Invert the gray channel\n *\n *  png_set_invert_mono(png_structrp png_ptr)\n */\nstatic void\nimage_transform_png_set_invert_mono_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_invert_mono(pp);\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_invert_mono_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   if (that->colour_type & 4)\n      that->mono_inverted = 1;\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_invert_mono_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(bit_depth)\n\n   this->next = *that;\n   *that = this;\n\n   /* Only has an effect on pixels with no colour: */\n   return (colour_type & 2) == 0;\n}\n\nIT(invert_mono);\n#undef PT\n#define PT ITSTRUCT(invert_mono)\n\n#endif /* PNG_READ_INVERT_MONO_SUPPORTED */\n\n#ifdef PNG_READ_SHIFT_SUPPORTED\n/* png_set_shift(png_structp, png_const_color_8p true_bits)\n *\n * The output pixels will be shifted by the given true_bits\n * values.\n */\n#define data ITDATA(shift)\nstatic png_color_8 data;\n\nstatic void\nimage_transform_png_set_shift_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   /* Get a random set of shifts.  The shifts need to do something\n    * to test the transform, so they are limited to the bit depth\n    * of the input image.  Notice that in the following the 'gray'\n    * field is randomized independently.  This acts as a check that\n    * libpng does use the correct field.\n    */\n   const unsigned int depth = that->this.bit_depth;\n\n   data.red = (png_byte)/*SAFE*/(random_mod(depth)+1);\n   data.green = (png_byte)/*SAFE*/(random_mod(depth)+1);\n   data.blue = (png_byte)/*SAFE*/(random_mod(depth)+1);\n   data.gray = (png_byte)/*SAFE*/(random_mod(depth)+1);\n   data.alpha = (png_byte)/*SAFE*/(random_mod(depth)+1);\n\n   png_set_shift(pp, &data);\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_shift_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   /* Copy the correct values into the sBIT fields, libpng does not do\n    * anything to palette data:\n    */\n   if (that->colour_type != PNG_COLOR_TYPE_PALETTE)\n   {\n       that->sig_bits = 1;\n\n       /* The sBIT fields are reset to the values previously sent to\n        * png_set_shift according to the colour type.\n        * does.\n        */\n       if (that->colour_type & 2) /* RGB channels */\n       {\n          that->red_sBIT = data.red;\n          that->green_sBIT = data.green;\n          that->blue_sBIT = data.blue;\n       }\n\n       else /* One grey channel */\n          that->red_sBIT = that->green_sBIT = that->blue_sBIT = data.gray;\n\n       that->alpha_sBIT = data.alpha;\n   }\n\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_shift_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   UNUSED(bit_depth)\n\n   this->next = *that;\n   *that = this;\n\n   return colour_type != PNG_COLOR_TYPE_PALETTE;\n}\n\nIT(shift);\n#undef PT\n#define PT ITSTRUCT(shift)\n\n#endif /* PNG_READ_SHIFT_SUPPORTED */\n\n#ifdef THIS_IS_THE_PROFORMA\nstatic void\nimage_transform_png_set_@_set(const image_transform *this,\n    transform_display *that, png_structp pp, png_infop pi)\n{\n   png_set_@(pp);\n   this->next->set(this->next, that, pp, pi);\n}\n\nstatic void\nimage_transform_png_set_@_mod(const image_transform *this,\n    image_pixel *that, png_const_structp pp,\n    const transform_display *display)\n{\n   this->next->mod(this->next, that, pp, display);\n}\n\nstatic int\nimage_transform_png_set_@_add(image_transform *this,\n    const image_transform **that, png_byte colour_type, png_byte bit_depth)\n{\n   this->next = *that;\n   *that = this;\n\n   return 1;\n}\n\nIT(@);\n#endif\n\n\n/* This may just be 'end' if all the transforms are disabled! */\nstatic image_transform *const image_transform_first = &PT;\n\nstatic void\ntransform_enable(const char *name)\n{\n   /* Everything starts out enabled, so if we see an 'enable' disabled\n    * everything else the first time round.\n    */\n   static int all_disabled = 0;\n   int found_it = 0;\n   image_transform *list = image_transform_first;\n\n   while (list != &image_transform_end)\n   {\n      if (strcmp(list->name, name) == 0)\n      {\n         list->enable = 1;\n         found_it = 1;\n      }\n      else if (!all_disabled)\n         list->enable = 0;\n\n      list = list->list;\n   }\n\n   all_disabled = 1;\n\n   if (!found_it)\n   {\n      fprintf(stderr, \"pngvalid: --transform-enable=%s: unknown transform\\n\",\n         name);\n      exit(99);\n   }\n}\n\nstatic void\ntransform_disable(const char *name)\n{\n   image_transform *list = image_transform_first;\n\n   while (list != &image_transform_end)\n   {\n      if (strcmp(list->name, name) == 0)\n      {\n         list->enable = 0;\n         return;\n      }\n\n      list = list->list;\n   }\n\n   fprintf(stderr, \"pngvalid: --transform-disable=%s: unknown transform\\n\",\n      name);\n   exit(99);\n}\n\nstatic void\nimage_transform_reset_count(void)\n{\n   image_transform *next = image_transform_first;\n   int count = 0;\n\n   while (next != &image_transform_end)\n   {\n      next->local_use = 0;\n      next->next = 0;\n      next = next->list;\n      ++count;\n   }\n\n   /* This can only happen if we every have more than 32 transforms (excluding\n    * the end) in the list.\n    */\n   if (count > 32) abort();\n}\n\nstatic int\nimage_transform_test_counter(png_uint_32 counter, unsigned int max)\n{\n   /* Test the list to see if there is any point contining, given a current\n    * counter and a 'max' value.\n    */\n   image_transform *next = image_transform_first;\n\n   while (next != &image_transform_end)\n   {\n      /* For max 0 or 1 continue until the counter overflows: */\n      counter >>= 1;\n\n      /* Continue if any entry hasn't reacked the max. */\n      if (max > 1 && next->local_use < max)\n         return 1;\n      next = next->list;\n   }\n\n   return max <= 1 && counter == 0;\n}\n\nstatic png_uint_32\nimage_transform_add(const image_transform **this, unsigned int max,\n   png_uint_32 counter, char *name, size_t sizeof_name, size_t *pos,\n   png_byte colour_type, png_byte bit_depth)\n{\n   for (;;) /* until we manage to add something */\n   {\n      png_uint_32 mask;\n      image_transform *list;\n\n      /* Find the next counter value, if the counter is zero this is the start\n       * of the list.  This routine always returns the current counter (not the\n       * next) so it returns 0 at the end and expects 0 at the beginning.\n       */\n      if (counter == 0) /* first time */\n      {\n         image_transform_reset_count();\n         if (max <= 1)\n            counter = 1;\n         else\n            counter = random_32();\n      }\n      else /* advance the counter */\n      {\n         switch (max)\n         {\n            case 0:  ++counter; break;\n            case 1:  counter <<= 1; break;\n            default: counter = random_32(); break;\n         }\n      }\n\n      /* Now add all these items, if possible */\n      *this = &image_transform_end;\n      list = image_transform_first;\n      mask = 1;\n\n      /* Go through the whole list adding anything that the counter selects: */\n      while (list != &image_transform_end)\n      {\n         if ((counter & mask) != 0 && list->enable &&\n             (max == 0 || list->local_use < max))\n         {\n            /* Candidate to add: */\n            if (list->add(list, this, colour_type, bit_depth) || max == 0)\n            {\n               /* Added, so add to the name too. */\n               *pos = safecat(name, sizeof_name, *pos, \" +\");\n               *pos = safecat(name, sizeof_name, *pos, list->name);\n            }\n\n            else\n            {\n               /* Not useful and max>0, so remove it from *this: */\n               *this = list->next;\n               list->next = 0;\n\n               /* And, since we know it isn't useful, stop it being added again\n                * in this run:\n                */\n               list->local_use = max;\n            }\n         }\n\n         mask <<= 1;\n         list = list->list;\n      }\n\n      /* Now if anything was added we have something to do. */\n      if (*this != &image_transform_end)\n         return counter;\n\n      /* Nothing added, but was there anything in there to add? */\n      if (!image_transform_test_counter(counter, max))\n         return 0;\n   }\n}\n\nstatic void\nperform_transform_test(png_modifier *pm)\n{\n   png_byte colour_type = 0;\n   png_byte bit_depth = 0;\n   unsigned int palette_number = 0;\n\n   while (next_format(&colour_type, &bit_depth, &palette_number, pm->test_lbg,\n            pm->test_tRNS))\n   {\n      png_uint_32 counter = 0;\n      size_t base_pos;\n      char name[64];\n\n      base_pos = safecat(name, sizeof name, 0, \"transform:\");\n\n      for (;;)\n      {\n         size_t pos = base_pos;\n         const image_transform *list = 0;\n\n         /* 'max' is currently hardwired to '1'; this should be settable on the\n          * command line.\n          */\n         counter = image_transform_add(&list, 1/*max*/, counter,\n            name, sizeof name, &pos, colour_type, bit_depth);\n\n         if (counter == 0)\n            break;\n\n         /* The command line can change this to checking interlaced images. */\n         do\n         {\n            pm->repeat = 0;\n            transform_test(pm, FILEID(colour_type, bit_depth, palette_number,\n               pm->interlace_type, 0, 0, 0), list, name);\n\n            if (fail(pm))\n               return;\n         }\n         while (pm->repeat);\n      }\n   }\n}\n#endif /* PNG_READ_TRANSFORMS_SUPPORTED */\n\n/********************************* GAMMA TESTS ********************************/\n#ifdef PNG_READ_GAMMA_SUPPORTED\n/* Reader callbacks and implementations, where they differ from the standard\n * ones.\n */\ntypedef struct gamma_display\n{\n   standard_display this;\n\n   /* Parameters */\n   png_modifier*    pm;\n   double           file_gamma;\n   double           screen_gamma;\n   double           background_gamma;\n   png_byte         sbit;\n   int              threshold_test;\n   int              use_input_precision;\n   int              scale16;\n   int              expand16;\n   int              do_background;\n   png_color_16     background_color;\n\n   /* Local variables */\n   double       maxerrout;\n   double       maxerrpc;\n   double       maxerrabs;\n} gamma_display;\n\n#define ALPHA_MODE_OFFSET 4\n\nstatic void\ngamma_display_init(gamma_display *dp, png_modifier *pm, png_uint_32 id,\n    double file_gamma, double screen_gamma, png_byte sbit, int threshold_test,\n    int use_input_precision, int scale16, int expand16,\n    int do_background, const png_color_16 *pointer_to_the_background_color,\n    double background_gamma)\n{\n   /* Standard fields */\n   standard_display_init(&dp->this, &pm->this, id, do_read_interlace,\n      pm->use_update_info);\n\n   /* Parameter fields */\n   dp->pm = pm;\n   dp->file_gamma = file_gamma;\n   dp->screen_gamma = screen_gamma;\n   dp->background_gamma = background_gamma;\n   dp->sbit = sbit;\n   dp->threshold_test = threshold_test;\n   dp->use_input_precision = use_input_precision;\n   dp->scale16 = scale16;\n   dp->expand16 = expand16;\n   dp->do_background = do_background;\n   if (do_background && pointer_to_the_background_color != 0)\n      dp->background_color = *pointer_to_the_background_color;\n   else\n      memset(&dp->background_color, 0, sizeof dp->background_color);\n\n   /* Local variable fields */\n   dp->maxerrout = dp->maxerrpc = dp->maxerrabs = 0;\n}\n\nstatic void\ngamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi)\n{\n   /* Reuse the standard stuff as appropriate. */\n   standard_info_part1(&dp->this, pp, pi);\n\n   /* If requested strip 16 to 8 bits - this is handled automagically below\n    * because the output bit depth is read from the library.  Note that there\n    * are interactions with sBIT but, internally, libpng makes sbit at most\n    * PNG_MAX_GAMMA_8 prior to 1.7 when doing the following.\n    */\n   if (dp->scale16)\n#     ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\n         png_set_scale_16(pp);\n#     else\n         /* The following works both in 1.5.4 and earlier versions: */\n#        ifdef PNG_READ_16_TO_8_SUPPORTED\n            png_set_strip_16(pp);\n#        else\n            png_error(pp, \"scale16 (16 to 8 bit conversion) not supported\");\n#        endif\n#     endif\n\n   if (dp->expand16)\n#     ifdef PNG_READ_EXPAND_16_SUPPORTED\n         png_set_expand_16(pp);\n#     else\n         png_error(pp, \"expand16 (8 to 16 bit conversion) not supported\");\n#     endif\n\n   if (dp->do_background >= ALPHA_MODE_OFFSET)\n   {\n#     ifdef PNG_READ_ALPHA_MODE_SUPPORTED\n      {\n         /* This tests the alpha mode handling, if supported. */\n         int mode = dp->do_background - ALPHA_MODE_OFFSET;\n\n         /* The gamma value is the output gamma, and is in the standard,\n          * non-inverted, represenation.  It provides a default for the PNG file\n          * gamma, but since the file has a gAMA chunk this does not matter.\n          */\n         const double sg = dp->screen_gamma;\n#        ifndef PNG_FLOATING_POINT_SUPPORTED\n            const png_fixed_point g = fix(sg);\n#        endif\n\n#        ifdef PNG_FLOATING_POINT_SUPPORTED\n            png_set_alpha_mode(pp, mode, sg);\n#        else\n            png_set_alpha_mode_fixed(pp, mode, g);\n#        endif\n\n         /* However, for the standard Porter-Duff algorithm the output defaults\n          * to be linear, so if the test requires non-linear output it must be\n          * corrected here.\n          */\n         if (mode == PNG_ALPHA_STANDARD && sg != 1)\n         {\n#           ifdef PNG_FLOATING_POINT_SUPPORTED\n               png_set_gamma(pp, sg, dp->file_gamma);\n#           else\n               png_fixed_point f = fix(dp->file_gamma);\n               png_set_gamma_fixed(pp, g, f);\n#           endif\n         }\n      }\n#     else\n         png_error(pp, \"alpha mode handling not supported\");\n#     endif\n   }\n\n   else\n   {\n      /* Set up gamma processing. */\n#     ifdef PNG_FLOATING_POINT_SUPPORTED\n         png_set_gamma(pp, dp->screen_gamma, dp->file_gamma);\n#     else\n      {\n         png_fixed_point s = fix(dp->screen_gamma);\n         png_fixed_point f = fix(dp->file_gamma);\n         png_set_gamma_fixed(pp, s, f);\n      }\n#     endif\n\n      if (dp->do_background)\n      {\n#     ifdef PNG_READ_BACKGROUND_SUPPORTED\n         /* NOTE: this assumes the caller provided the correct background gamma!\n          */\n         const double bg = dp->background_gamma;\n#        ifndef PNG_FLOATING_POINT_SUPPORTED\n            const png_fixed_point g = fix(bg);\n#        endif\n\n#        ifdef PNG_FLOATING_POINT_SUPPORTED\n            png_set_background(pp, &dp->background_color, dp->do_background,\n               0/*need_expand*/, bg);\n#        else\n            png_set_background_fixed(pp, &dp->background_color,\n               dp->do_background, 0/*need_expand*/, g);\n#        endif\n#     else\n         png_error(pp, \"png_set_background not supported\");\n#     endif\n      }\n   }\n\n   {\n      int i = dp->this.use_update_info;\n      /* Always do one call, even if use_update_info is 0. */\n      do\n         png_read_update_info(pp, pi);\n      while (--i > 0);\n   }\n\n   /* Now we may get a different cbRow: */\n   standard_info_part2(&dp->this, pp, pi, 1 /*images*/);\n}\n\nstatic void PNGCBAPI\ngamma_info(png_structp pp, png_infop pi)\n{\n   gamma_info_imp(voidcast(gamma_display*, png_get_progressive_ptr(pp)), pp,\n      pi);\n}\n\n/* Validate a single component value - the routine gets the input and output\n * sample values as unscaled PNG component values along with a cache of all the\n * information required to validate the values.\n */\ntypedef struct validate_info\n{\n   png_const_structp  pp;\n   gamma_display *dp;\n   png_byte sbit;\n   int use_input_precision;\n   int do_background;\n   int scale16;\n   unsigned int sbit_max;\n   unsigned int isbit_shift;\n   unsigned int outmax;\n\n   double gamma_correction; /* Overall correction required. */\n   double file_inverse;     /* Inverse of file gamma. */\n   double screen_gamma;\n   double screen_inverse;   /* Inverse of screen gamma. */\n\n   double background_red;   /* Linear background value, red or gray. */\n   double background_green;\n   double background_blue;\n\n   double maxabs;\n   double maxpc;\n   double maxcalc;\n   double maxout;\n   double maxout_total;     /* Total including quantization error */\n   double outlog;\n   int    outquant;\n}\nvalidate_info;\n\nstatic void\ninit_validate_info(validate_info *vi, gamma_display *dp, png_const_structp pp,\n    int in_depth, int out_depth)\n{\n   const unsigned int outmax = (1U<<out_depth)-1;\n\n   vi->pp = pp;\n   vi->dp = dp;\n\n   if (dp->sbit > 0 && dp->sbit < in_depth)\n   {\n      vi->sbit = dp->sbit;\n      vi->isbit_shift = in_depth - dp->sbit;\n   }\n\n   else\n   {\n      vi->sbit = (png_byte)in_depth;\n      vi->isbit_shift = 0;\n   }\n\n   vi->sbit_max = (1U << vi->sbit)-1;\n\n   /* This mimics the libpng threshold test, '0' is used to prevent gamma\n    * correction in the validation test.\n    */\n   vi->screen_gamma = dp->screen_gamma;\n   if (fabs(vi->screen_gamma-1) < PNG_GAMMA_THRESHOLD)\n      vi->screen_gamma = vi->screen_inverse = 0;\n   else\n      vi->screen_inverse = 1/vi->screen_gamma;\n\n   vi->use_input_precision = dp->use_input_precision;\n   vi->outmax = outmax;\n   vi->maxabs = abserr(dp->pm, in_depth, out_depth);\n   vi->maxpc = pcerr(dp->pm, in_depth, out_depth);\n   vi->maxcalc = calcerr(dp->pm, in_depth, out_depth);\n   vi->maxout = outerr(dp->pm, in_depth, out_depth);\n   vi->outquant = output_quantization_factor(dp->pm, in_depth, out_depth);\n   vi->maxout_total = vi->maxout + vi->outquant * .5;\n   vi->outlog = outlog(dp->pm, in_depth, out_depth);\n\n   if ((dp->this.colour_type & PNG_COLOR_MASK_ALPHA) != 0 ||\n      (dp->this.colour_type == 3 && dp->this.is_transparent) ||\n      ((dp->this.colour_type == 0 || dp->this.colour_type == 2) &&\n       dp->this.has_tRNS))\n   {\n      vi->do_background = dp->do_background;\n\n      if (vi->do_background != 0)\n      {\n         const double bg_inverse = 1/dp->background_gamma;\n         double r, g, b;\n\n         /* Caller must at least put the gray value into the red channel */\n         r = dp->background_color.red; r /= outmax;\n         g = dp->background_color.green; g /= outmax;\n         b = dp->background_color.blue; b /= outmax;\n\n#     if 0\n         /* libpng doesn't do this optimization, if we do pngvalid will fail.\n          */\n         if (fabs(bg_inverse-1) >= PNG_GAMMA_THRESHOLD)\n#     endif\n         {\n            r = pow(r, bg_inverse);\n            g = pow(g, bg_inverse);\n            b = pow(b, bg_inverse);\n         }\n\n         vi->background_red = r;\n         vi->background_green = g;\n         vi->background_blue = b;\n      }\n   }\n   else /* Do not expect any background processing */\n      vi->do_background = 0;\n\n   if (vi->do_background == 0)\n      vi->background_red = vi->background_green = vi->background_blue = 0;\n\n   vi->gamma_correction = 1/(dp->file_gamma*dp->screen_gamma);\n   if (fabs(vi->gamma_correction-1) < PNG_GAMMA_THRESHOLD)\n      vi->gamma_correction = 0;\n\n   vi->file_inverse = 1/dp->file_gamma;\n   if (fabs(vi->file_inverse-1) < PNG_GAMMA_THRESHOLD)\n      vi->file_inverse = 0;\n\n   vi->scale16 = dp->scale16;\n}\n\n/* This function handles composition of a single non-alpha component.  The\n * argument is the input sample value, in the range 0..1, and the alpha value.\n * The result is the composed, linear, input sample.  If alpha is less than zero\n * this is the alpha component and the function should not be called!\n */\nstatic double\ngamma_component_compose(int do_background, double input_sample, double alpha,\n   double background, int *compose)\n{\n   switch (do_background)\n   {\n#ifdef PNG_READ_BACKGROUND_SUPPORTED\n      case PNG_BACKGROUND_GAMMA_SCREEN:\n      case PNG_BACKGROUND_GAMMA_FILE:\n      case PNG_BACKGROUND_GAMMA_UNIQUE:\n         /* Standard PNG background processing. */\n         if (alpha < 1)\n         {\n            if (alpha > 0)\n            {\n               input_sample = input_sample * alpha + background * (1-alpha);\n               if (compose != NULL)\n                  *compose = 1;\n            }\n\n            else\n               input_sample = background;\n         }\n         break;\n#endif\n\n#ifdef PNG_READ_ALPHA_MODE_SUPPORTED\n      case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD:\n      case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN:\n         /* The components are premultiplied in either case and the output is\n          * gamma encoded (to get standard Porter-Duff we expect the output\n          * gamma to be set to 1.0!)\n          */\n      case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED:\n         /* The optimization is that the partial-alpha entries are linear\n          * while the opaque pixels are gamma encoded, but this only affects the\n          * output encoding.\n          */\n         if (alpha < 1)\n         {\n            if (alpha > 0)\n            {\n               input_sample *= alpha;\n               if (compose != NULL)\n                  *compose = 1;\n            }\n\n            else\n               input_sample = 0;\n         }\n         break;\n#endif\n\n      default:\n         /* Standard cases where no compositing is done (so the component\n          * value is already correct.)\n          */\n         UNUSED(alpha)\n         UNUSED(background)\n         UNUSED(compose)\n         break;\n   }\n\n   return input_sample;\n}\n\n/* This API returns the encoded *input* component, in the range 0..1 */\nstatic double\ngamma_component_validate(const char *name, const validate_info *vi,\n    const unsigned int id, const unsigned int od,\n    const double alpha /* <0 for the alpha channel itself */,\n    const double background /* component background value */)\n{\n   const unsigned int isbit = id >> vi->isbit_shift;\n   const unsigned int sbit_max = vi->sbit_max;\n   const unsigned int outmax = vi->outmax;\n   const int do_background = vi->do_background;\n\n   double i;\n\n   /* First check on the 'perfect' result obtained from the digitized input\n    * value, id, and compare this against the actual digitized result, 'od'.\n    * 'i' is the input result in the range 0..1:\n    */\n   i = isbit; i /= sbit_max;\n\n   /* Check for the fast route: if we don't do any background composition or if\n    * this is the alpha channel ('alpha' < 0) or if the pixel is opaque then\n    * just use the gamma_correction field to correct to the final output gamma.\n    */\n   if (alpha == 1 /* opaque pixel component */ || !do_background\n#ifdef PNG_READ_ALPHA_MODE_SUPPORTED\n      || do_background == ALPHA_MODE_OFFSET + PNG_ALPHA_PNG\n#endif\n      || (alpha < 0 /* alpha channel */\n#ifdef PNG_READ_ALPHA_MODE_SUPPORTED\n      && do_background != ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN\n#endif\n      ))\n   {\n      /* Then get the gamma corrected version of 'i' and compare to 'od', any\n       * error less than .5 is insignificant - just quantization of the output\n       * value to the nearest digital value (nevertheless the error is still\n       * recorded - it's interesting ;-)\n       */\n      double encoded_sample = i;\n      double encoded_error;\n\n      /* alpha less than 0 indicates the alpha channel, which is always linear\n       */\n      if (alpha >= 0 && vi->gamma_correction > 0)\n         encoded_sample = pow(encoded_sample, vi->gamma_correction);\n      encoded_sample *= outmax;\n\n      encoded_error = fabs(od-encoded_sample);\n\n      if (encoded_error > vi->dp->maxerrout)\n         vi->dp->maxerrout = encoded_error;\n\n      if (encoded_error < vi->maxout_total && encoded_error < vi->outlog)\n         return i;\n   }\n\n   /* The slow route - attempt to do linear calculations. */\n   /* There may be an error, or background processing is required, so calculate\n    * the actual sample values - unencoded light intensity values.  Note that in\n    * practice these are not completely unencoded because they include a\n    * 'viewing correction' to decrease or (normally) increase the perceptual\n    * contrast of the image.  There's nothing we can do about this - we don't\n    * know what it is - so assume the unencoded value is perceptually linear.\n    */\n   {\n      double input_sample = i; /* In range 0..1 */\n      double output, error, encoded_sample, encoded_error;\n      double es_lo, es_hi;\n      int compose = 0;           /* Set to one if composition done */\n      int output_is_encoded;     /* Set if encoded to screen gamma */\n      int log_max_error = 1;     /* Check maximum error values */\n      png_const_charp pass = 0;  /* Reason test passes (or 0 for fail) */\n\n      /* Convert to linear light (with the above caveat.)  The alpha channel is\n       * already linear.\n       */\n      if (alpha >= 0)\n      {\n         int tcompose;\n\n         if (vi->file_inverse > 0)\n            input_sample = pow(input_sample, vi->file_inverse);\n\n         /* Handle the compose processing: */\n         tcompose = 0;\n         input_sample = gamma_component_compose(do_background, input_sample,\n            alpha, background, &tcompose);\n\n         if (tcompose)\n            compose = 1;\n      }\n\n      /* And similarly for the output value, but we need to check the background\n       * handling to linearize it correctly.\n       */\n      output = od;\n      output /= outmax;\n\n      output_is_encoded = vi->screen_gamma > 0;\n\n      if (alpha < 0) /* The alpha channel */\n      {\n#ifdef PNG_READ_ALPHA_MODE_SUPPORTED\n         if (do_background != ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN)\n#endif\n         {\n            /* In all other cases the output alpha channel is linear already,\n             * don't log errors here, they are much larger in linear data.\n             */\n            output_is_encoded = 0;\n            log_max_error = 0;\n         }\n      }\n\n#ifdef PNG_READ_ALPHA_MODE_SUPPORTED\n      else /* A component */\n      {\n         if (do_background == ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED &&\n            alpha < 1) /* the optimized case - linear output */\n         {\n            if (alpha > 0) log_max_error = 0;\n            output_is_encoded = 0;\n         }\n      }\n#endif\n\n      if (output_is_encoded)\n         output = pow(output, vi->screen_gamma);\n\n      /* Calculate (or recalculate) the encoded_sample value and repeat the\n       * check above (unnecessary if we took the fast route, but harmless.)\n       */\n      encoded_sample = input_sample;\n      if (output_is_encoded)\n         encoded_sample = pow(encoded_sample, vi->screen_inverse);\n      encoded_sample *= outmax;\n\n      encoded_error = fabs(od-encoded_sample);\n\n      /* Don't log errors in the alpha channel, or the 'optimized' case,\n       * neither are significant to the overall perception.\n       */\n      if (log_max_error && encoded_error > vi->dp->maxerrout)\n         vi->dp->maxerrout = encoded_error;\n\n      if (encoded_error < vi->maxout_total)\n      {\n         if (encoded_error < vi->outlog)\n            return i;\n\n         /* Test passed but error is bigger than the log limit, record why the\n          * test passed:\n          */\n         pass = \"less than maxout:\\n\";\n      }\n\n      /* i: the original input value in the range 0..1\n       *\n       * pngvalid calculations:\n       *  input_sample: linear result; i linearized and composed, range 0..1\n       *  encoded_sample: encoded result; input_sample scaled to ouput bit depth\n       *\n       * libpng calculations:\n       *  output: linear result; od scaled to 0..1 and linearized\n       *  od: encoded result from libpng\n       */\n\n      /* Now we have the numbers for real errors, both absolute values as as a\n       * percentage of the correct value (output):\n       */\n      error = fabs(input_sample-output);\n\n      if (log_max_error && error > vi->dp->maxerrabs)\n         vi->dp->maxerrabs = error;\n\n      /* The following is an attempt to ignore the tendency of quantization to\n       * dominate the percentage errors for lower result values:\n       */\n      if (log_max_error && input_sample > .5)\n      {\n         double percentage_error = error/input_sample;\n         if (percentage_error > vi->dp->maxerrpc)\n            vi->dp->maxerrpc = percentage_error;\n      }\n\n      /* Now calculate the digitization limits for 'encoded_sample' using the\n       * 'max' values.  Note that maxout is in the encoded space but maxpc and\n       * maxabs are in linear light space.\n       *\n       * First find the maximum error in linear light space, range 0..1:\n       */\n      {\n         double tmp = input_sample * vi->maxpc;\n         if (tmp < vi->maxabs) tmp = vi->maxabs;\n         /* If 'compose' is true the composition was done in linear space using\n          * integer arithmetic.  This introduces an extra error of +/- 0.5 (at\n          * least) in the integer space used.  'maxcalc' records this, taking\n          * into account the possibility that even for 16 bit output 8 bit space\n          * may have been used.\n          */\n         if (compose && tmp < vi->maxcalc) tmp = vi->maxcalc;\n\n         /* The 'maxout' value refers to the encoded result, to compare with\n          * this encode input_sample adjusted by the maximum error (tmp) above.\n          */\n         es_lo = encoded_sample - vi->maxout;\n\n         if (es_lo > 0 && input_sample-tmp > 0)\n         {\n            double low_value = input_sample-tmp;\n            if (output_is_encoded)\n               low_value = pow(low_value, vi->screen_inverse);\n            low_value *= outmax;\n            if (low_value < es_lo) es_lo = low_value;\n\n            /* Quantize this appropriately: */\n            es_lo = ceil(es_lo / vi->outquant - .5) * vi->outquant;\n         }\n\n         else\n            es_lo = 0;\n\n         es_hi = encoded_sample + vi->maxout;\n\n         if (es_hi < outmax && input_sample+tmp < 1)\n         {\n            double high_value = input_sample+tmp;\n            if (output_is_encoded)\n               high_value = pow(high_value, vi->screen_inverse);\n            high_value *= outmax;\n            if (high_value > es_hi) es_hi = high_value;\n\n            es_hi = floor(es_hi / vi->outquant + .5) * vi->outquant;\n         }\n\n         else\n            es_hi = outmax;\n      }\n\n      /* The primary test is that the final encoded value returned by the\n       * library should be between the two limits (inclusive) that were\n       * calculated above.\n       */\n      if (od >= es_lo && od <= es_hi)\n      {\n         /* The value passes, but we may need to log the information anyway. */\n         if (encoded_error < vi->outlog)\n            return i;\n\n         if (pass == 0)\n            pass = \"within digitization limits:\\n\";\n      }\n\n      {\n         /* There has been an error in processing, or we need to log this\n          * value.\n          */\n         double is_lo, is_hi;\n\n         /* pass is set at this point if either of the tests above would have\n          * passed.  Don't do these additional tests here - just log the\n          * original [es_lo..es_hi] values.\n          */\n         if (pass == 0 && vi->use_input_precision && vi->dp->sbit)\n         {\n            /* Ok, something is wrong - this actually happens in current libpng\n             * 16-to-8 processing.  Assume that the input value (id, adjusted\n             * for sbit) can be anywhere between value-.5 and value+.5 - quite a\n             * large range if sbit is low.\n             *\n             * NOTE: at present because the libpng gamma table stuff has been\n             * changed to use a rounding algorithm to correct errors in 8-bit\n             * calculations the precise sbit calculation (a shift) has been\n             * lost.  This can result in up to a +/-1 error in the presence of\n             * an sbit less than the bit depth.\n             */\n#           if PNG_LIBPNG_VER < 10700\n#              define SBIT_ERROR .5\n#           else\n#              define SBIT_ERROR 1.\n#           endif\n            double tmp = (isbit - SBIT_ERROR)/sbit_max;\n\n            if (tmp <= 0)\n               tmp = 0;\n\n            else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1)\n               tmp = pow(tmp, vi->file_inverse);\n\n            tmp = gamma_component_compose(do_background, tmp, alpha, background,\n               NULL);\n\n            if (output_is_encoded && tmp > 0 && tmp < 1)\n               tmp = pow(tmp, vi->screen_inverse);\n\n            is_lo = ceil(outmax * tmp - vi->maxout_total);\n\n            if (is_lo < 0)\n               is_lo = 0;\n\n            tmp = (isbit + SBIT_ERROR)/sbit_max;\n\n            if (tmp >= 1)\n               tmp = 1;\n\n            else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1)\n               tmp = pow(tmp, vi->file_inverse);\n\n            tmp = gamma_component_compose(do_background, tmp, alpha, background,\n               NULL);\n\n            if (output_is_encoded && tmp > 0 && tmp < 1)\n               tmp = pow(tmp, vi->screen_inverse);\n\n            is_hi = floor(outmax * tmp + vi->maxout_total);\n\n            if (is_hi > outmax)\n               is_hi = outmax;\n\n            if (!(od < is_lo || od > is_hi))\n            {\n               if (encoded_error < vi->outlog)\n                  return i;\n\n               pass = \"within input precision limits:\\n\";\n            }\n\n            /* One last chance.  If this is an alpha channel and the 16to8\n             * option has been used and 'inaccurate' scaling is used then the\n             * bit reduction is obtained by simply using the top 8 bits of the\n             * value.\n             *\n             * This is only done for older libpng versions when the 'inaccurate'\n             * (chop) method of scaling was used.\n             */\n#           ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED\n#              if PNG_LIBPNG_VER < 10504\n                  /* This may be required for other components in the future,\n                   * but at present the presence of gamma correction effectively\n                   * prevents the errors in the component scaling (I don't quite\n                   * understand why, but since it's better this way I care not\n                   * to ask, JB 20110419.)\n                   */\n                  if (pass == 0 && alpha < 0 && vi->scale16 && vi->sbit > 8 &&\n                     vi->sbit + vi->isbit_shift == 16)\n                  {\n                     tmp = ((id >> 8) - .5)/255;\n\n                     if (tmp > 0)\n                     {\n                        is_lo = ceil(outmax * tmp - vi->maxout_total);\n                        if (is_lo < 0) is_lo = 0;\n                     }\n\n                     else\n                        is_lo = 0;\n\n                     tmp = ((id >> 8) + .5)/255;\n\n                     if (tmp < 1)\n                     {\n                        is_hi = floor(outmax * tmp + vi->maxout_total);\n                        if (is_hi > outmax) is_hi = outmax;\n                     }\n\n                     else\n                        is_hi = outmax;\n\n                     if (!(od < is_lo || od > is_hi))\n                     {\n                        if (encoded_error < vi->outlog)\n                           return i;\n\n                        pass = \"within 8 bit limits:\\n\";\n                     }\n                  }\n#              endif\n#           endif\n         }\n         else /* !use_input_precision */\n            is_lo = es_lo, is_hi = es_hi;\n\n         /* Attempt to output a meaningful error/warning message: the message\n          * output depends on the background/composite operation being performed\n          * because this changes what parameters were actually used above.\n          */\n         {\n            size_t pos = 0;\n            /* Need either 1/255 or 1/65535 precision here; 3 or 6 decimal\n             * places.  Just use outmax to work out which.\n             */\n            int precision = (outmax >= 1000 ? 6 : 3);\n            int use_input=1, use_background=0, do_compose=0;\n            char msg[256];\n\n            if (pass != 0)\n               pos = safecat(msg, sizeof msg, pos, \"\\n\\t\");\n\n            /* Set up the various flags, the output_is_encoded flag above\n             * is also used below.  do_compose is just a double check.\n             */\n            switch (do_background)\n            {\n#           ifdef PNG_READ_BACKGROUND_SUPPORTED\n               case PNG_BACKGROUND_GAMMA_SCREEN:\n               case PNG_BACKGROUND_GAMMA_FILE:\n               case PNG_BACKGROUND_GAMMA_UNIQUE:\n                  use_background = (alpha >= 0 && alpha < 1);\n                  /*FALL THROUGH*/\n#           endif\n#           ifdef PNG_READ_ALPHA_MODE_SUPPORTED\n               case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD:\n               case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN:\n               case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED:\n#           endif /* ALPHA_MODE_SUPPORTED */\n               do_compose = (alpha > 0 && alpha < 1);\n               use_input = (alpha != 0);\n               break;\n\n            default:\n               break;\n            }\n\n            /* Check the 'compose' flag */\n            if (compose != do_compose)\n               png_error(vi->pp, \"internal error (compose)\");\n\n            /* 'name' is the component name */\n            pos = safecat(msg, sizeof msg, pos, name);\n            pos = safecat(msg, sizeof msg, pos, \"(\");\n            pos = safecatn(msg, sizeof msg, pos, id);\n            if (use_input || pass != 0/*logging*/)\n            {\n               if (isbit != id)\n               {\n                  /* sBIT has reduced the precision of the input: */\n                  pos = safecat(msg, sizeof msg, pos, \", sbit(\");\n                  pos = safecatn(msg, sizeof msg, pos, vi->sbit);\n                  pos = safecat(msg, sizeof msg, pos, \"): \");\n                  pos = safecatn(msg, sizeof msg, pos, isbit);\n               }\n               pos = safecat(msg, sizeof msg, pos, \"/\");\n               /* The output is either \"id/max\" or \"id sbit(sbit): isbit/max\" */\n               pos = safecatn(msg, sizeof msg, pos, vi->sbit_max);\n            }\n            pos = safecat(msg, sizeof msg, pos, \")\");\n\n            /* A component may have been multiplied (in linear space) by the\n             * alpha value, 'compose' says whether this is relevant.\n             */\n            if (compose || pass != 0)\n            {\n               /* If any form of composition is being done report our\n                * calculated linear value here (the code above doesn't record\n                * the input value before composition is performed, so what\n                * gets reported is the value after composition.)\n                */\n               if (use_input || pass != 0)\n               {\n                  if (vi->file_inverse > 0)\n                  {\n                     pos = safecat(msg, sizeof msg, pos, \"^\");\n                     pos = safecatd(msg, sizeof msg, pos, vi->file_inverse, 2);\n                  }\n\n                  else\n                     pos = safecat(msg, sizeof msg, pos, \"[linear]\");\n\n                  pos = safecat(msg, sizeof msg, pos, \"*(alpha)\");\n                  pos = safecatd(msg, sizeof msg, pos, alpha, precision);\n               }\n\n               /* Now record the *linear* background value if it was used\n                * (this function is not passed the original, non-linear,\n                * value but it is contained in the test name.)\n                */\n               if (use_background)\n               {\n                  pos = safecat(msg, sizeof msg, pos, use_input ? \"+\" : \" \");\n                  pos = safecat(msg, sizeof msg, pos, \"(background)\");\n                  pos = safecatd(msg, sizeof msg, pos, background, precision);\n                  pos = safecat(msg, sizeof msg, pos, \"*\");\n                  pos = safecatd(msg, sizeof msg, pos, 1-alpha, precision);\n               }\n            }\n\n            /* Report the calculated value (input_sample) and the linearized\n             * libpng value (output) unless this is just a component gamma\n             * correction.\n             */\n            if (compose || alpha < 0 || pass != 0)\n            {\n               pos = safecat(msg, sizeof msg, pos,\n                  pass != 0 ? \" =\\n\\t\" : \" = \");\n               pos = safecatd(msg, sizeof msg, pos, input_sample, precision);\n               pos = safecat(msg, sizeof msg, pos, \" (libpng: \");\n               pos = safecatd(msg, sizeof msg, pos, output, precision);\n               pos = safecat(msg, sizeof msg, pos, \")\");\n\n               /* Finally report the output gamma encoding, if any. */\n               if (output_is_encoded)\n               {\n                  pos = safecat(msg, sizeof msg, pos, \" ^\");\n                  pos = safecatd(msg, sizeof msg, pos, vi->screen_inverse, 2);\n                  pos = safecat(msg, sizeof msg, pos, \"(to screen) =\");\n               }\n\n               else\n                  pos = safecat(msg, sizeof msg, pos, \" [screen is linear] =\");\n            }\n\n            if ((!compose && alpha >= 0) || pass != 0)\n            {\n               if (pass != 0) /* logging */\n                  pos = safecat(msg, sizeof msg, pos, \"\\n\\t[overall:\");\n\n               /* This is the non-composition case, the internal linear\n                * values are irrelevant (though the log below will reveal\n                * them.)  Output a much shorter warning/error message and report\n                * the overall gamma correction.\n                */\n               if (vi->gamma_correction > 0)\n               {\n                  pos = safecat(msg, sizeof msg, pos, \" ^\");\n                  pos = safecatd(msg, sizeof msg, pos, vi->gamma_correction, 2);\n                  pos = safecat(msg, sizeof msg, pos, \"(gamma correction) =\");\n               }\n\n               else\n                  pos = safecat(msg, sizeof msg, pos,\n                     \" [no gamma correction] =\");\n\n               if (pass != 0)\n                  pos = safecat(msg, sizeof msg, pos, \"]\");\n            }\n\n            /* This is our calculated encoded_sample which should (but does\n             * not) match od:\n             */\n            pos = safecat(msg, sizeof msg, pos, pass != 0 ? \"\\n\\t\" : \" \");\n            pos = safecatd(msg, sizeof msg, pos, is_lo, 1);\n            pos = safecat(msg, sizeof msg, pos, \" < \");\n            pos = safecatd(msg, sizeof msg, pos, encoded_sample, 1);\n            pos = safecat(msg, sizeof msg, pos, \" (libpng: \");\n            pos = safecatn(msg, sizeof msg, pos, od);\n            pos = safecat(msg, sizeof msg, pos, \")\");\n            pos = safecat(msg, sizeof msg, pos, \"/\");\n            pos = safecatn(msg, sizeof msg, pos, outmax);\n            pos = safecat(msg, sizeof msg, pos, \" < \");\n            pos = safecatd(msg, sizeof msg, pos, is_hi, 1);\n\n            if (pass == 0) /* The error condition */\n            {\n#              ifdef PNG_WARNINGS_SUPPORTED\n                  png_warning(vi->pp, msg);\n#              else\n                  store_warning(vi->pp, msg);\n#              endif\n            }\n\n            else /* logging this value */\n               store_verbose(&vi->dp->pm->this, vi->pp, pass, msg);\n         }\n      }\n   }\n\n   return i;\n}\n\nstatic void\ngamma_image_validate(gamma_display *dp, png_const_structp pp,\n   png_infop pi)\n{\n   /* Get some constants derived from the input and output file formats: */\n   const png_store* const ps = dp->this.ps;\n   const png_byte in_ct = dp->this.colour_type;\n   const png_byte in_bd = dp->this.bit_depth;\n   const png_uint_32 w = dp->this.w;\n   const png_uint_32 h = dp->this.h;\n   const size_t cbRow = dp->this.cbRow;\n   const png_byte out_ct = png_get_color_type(pp, pi);\n   const png_byte out_bd = png_get_bit_depth(pp, pi);\n\n   /* There are three sources of error, firstly the quantization in the\n    * file encoding, determined by sbit and/or the file depth, secondly\n    * the output (screen) gamma and thirdly the output file encoding.\n    *\n    * Since this API receives the screen and file gamma in double\n    * precision it is possible to calculate an exact answer given an input\n    * pixel value.  Therefore we assume that the *input* value is exact -\n    * sample/maxsample - calculate the corresponding gamma corrected\n    * output to the limits of double precision arithmetic and compare with\n    * what libpng returns.\n    *\n    * Since the library must quantize the output to 8 or 16 bits there is\n    * a fundamental limit on the accuracy of the output of +/-.5 - this\n    * quantization limit is included in addition to the other limits\n    * specified by the paramaters to the API.  (Effectively, add .5\n    * everywhere.)\n    *\n    * The behavior of the 'sbit' paramter is defined by section 12.5\n    * (sample depth scaling) of the PNG spec.  That section forces the\n    * decoder to assume that the PNG values have been scaled if sBIT is\n    * present:\n    *\n    *     png-sample = floor( input-sample * (max-out/max-in) + .5);\n    *\n    * This means that only a subset of the possible PNG values should\n    * appear in the input. However, the spec allows the encoder to use a\n    * variety of approximations to the above and doesn't require any\n    * restriction of the values produced.\n    *\n    * Nevertheless the spec requires that the upper 'sBIT' bits of the\n    * value stored in a PNG file be the original sample bits.\n    * Consequently the code below simply scales the top sbit bits by\n    * (1<<sbit)-1 to obtain an original sample value.\n    *\n    * Because there is limited precision in the input it is arguable that\n    * an acceptable result is any valid result from input-.5 to input+.5.\n    * The basic tests below do not do this, however if 'use_input_precision'\n    * is set a subsequent test is performed above.\n    */\n   const unsigned int samples_per_pixel = (out_ct & 2U) ? 3U : 1U;\n   int processing;\n   png_uint_32 y;\n   const store_palette_entry *in_palette = dp->this.palette;\n   const int in_is_transparent = dp->this.is_transparent;\n   int process_tRNS;\n   int out_npalette = -1;\n   int out_is_transparent = 0; /* Just refers to the palette case */\n   store_palette out_palette;\n   validate_info vi;\n\n   /* Check for row overwrite errors */\n   store_image_check(dp->this.ps, pp, 0);\n\n   /* Supply the input and output sample depths here - 8 for an indexed image,\n    * otherwise the bit depth.\n    */\n   init_validate_info(&vi, dp, pp, in_ct==3?8:in_bd, out_ct==3?8:out_bd);\n\n   processing = (vi.gamma_correction > 0 && !dp->threshold_test)\n      || in_bd != out_bd || in_ct != out_ct || vi.do_background;\n   process_tRNS = dp->this.has_tRNS && vi.do_background;\n\n   /* TODO: FIX THIS: MAJOR BUG!  If the transformations all happen inside\n    * the palette there is no way of finding out, because libpng fails to\n    * update the palette on png_read_update_info.  Indeed, libpng doesn't\n    * even do the required work until much later, when it doesn't have any\n    * info pointer.  Oops.  For the moment 'processing' is turned off if\n    * out_ct is palette.\n    */\n   if (in_ct == 3 && out_ct == 3)\n      processing = 0;\n\n   if (processing && out_ct == 3)\n      out_is_transparent = read_palette(out_palette, &out_npalette, pp, pi);\n\n   for (y=0; y<h; ++y)\n   {\n      png_const_bytep pRow = store_image_row(ps, pp, 0, y);\n      png_byte std[STANDARD_ROWMAX];\n\n      transform_row(pp, std, in_ct, in_bd, y);\n\n      if (processing)\n      {\n         unsigned int x;\n\n         for (x=0; x<w; ++x)\n         {\n            double alpha = 1; /* serves as a flag value */\n\n            /* Record the palette index for index images. */\n            const unsigned int in_index =\n               in_ct == 3 ? sample(std, 3, in_bd, x, 0, 0, 0) : 256;\n            const unsigned int out_index =\n               out_ct == 3 ? sample(std, 3, out_bd, x, 0, 0, 0) : 256;\n\n            /* Handle input alpha - png_set_background will cause the output\n             * alpha to disappear so there is nothing to check.\n             */\n            if ((in_ct & PNG_COLOR_MASK_ALPHA) != 0 ||\n                (in_ct == 3 && in_is_transparent))\n            {\n               const unsigned int input_alpha = in_ct == 3 ?\n                  dp->this.palette[in_index].alpha :\n                  sample(std, in_ct, in_bd, x, samples_per_pixel, 0, 0);\n\n               unsigned int output_alpha = 65536 /* as a flag value */;\n\n               if (out_ct == 3)\n               {\n                  if (out_is_transparent)\n                     output_alpha = out_palette[out_index].alpha;\n               }\n\n               else if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0)\n                  output_alpha = sample(pRow, out_ct, out_bd, x,\n                     samples_per_pixel, 0, 0);\n\n               if (output_alpha != 65536)\n                  alpha = gamma_component_validate(\"alpha\", &vi, input_alpha,\n                     output_alpha, -1/*alpha*/, 0/*background*/);\n\n               else /* no alpha in output */\n               {\n                  /* This is a copy of the calculation of 'i' above in order to\n                   * have the alpha value to use in the background calculation.\n                   */\n                  alpha = input_alpha >> vi.isbit_shift;\n                  alpha /= vi.sbit_max;\n               }\n            }\n\n            else if (process_tRNS)\n            {\n               /* alpha needs to be set appropriately for this pixel, it is\n                * currently 1 and needs to be 0 for an input pixel which matches\n                * the values in tRNS.\n                */\n               switch (in_ct)\n               {\n                  case 0: /* gray */\n                     if (sample(std, in_ct, in_bd, x, 0, 0, 0) ==\n                           dp->this.transparent.red)\n                        alpha = 0;\n                     break;\n\n                  case 2: /* RGB */\n                     if (sample(std, in_ct, in_bd, x, 0, 0, 0) ==\n                           dp->this.transparent.red &&\n                         sample(std, in_ct, in_bd, x, 1, 0, 0) ==\n                           dp->this.transparent.green &&\n                         sample(std, in_ct, in_bd, x, 2, 0, 0) ==\n                           dp->this.transparent.blue)\n                        alpha = 0;\n                     break;\n\n                  default:\n                     break;\n               }\n            }\n\n            /* Handle grayscale or RGB components. */\n            if ((in_ct & PNG_COLOR_MASK_COLOR) == 0) /* grayscale */\n               (void)gamma_component_validate(\"gray\", &vi,\n                  sample(std, in_ct, in_bd, x, 0, 0, 0),\n                  sample(pRow, out_ct, out_bd, x, 0, 0, 0),\n                  alpha/*component*/, vi.background_red);\n            else /* RGB or palette */\n            {\n               (void)gamma_component_validate(\"red\", &vi,\n                  in_ct == 3 ? in_palette[in_index].red :\n                     sample(std, in_ct, in_bd, x, 0, 0, 0),\n                  out_ct == 3 ? out_palette[out_index].red :\n                     sample(pRow, out_ct, out_bd, x, 0, 0, 0),\n                  alpha/*component*/, vi.background_red);\n\n               (void)gamma_component_validate(\"green\", &vi,\n                  in_ct == 3 ? in_palette[in_index].green :\n                     sample(std, in_ct, in_bd, x, 1, 0, 0),\n                  out_ct == 3 ? out_palette[out_index].green :\n                     sample(pRow, out_ct, out_bd, x, 1, 0, 0),\n                  alpha/*component*/, vi.background_green);\n\n               (void)gamma_component_validate(\"blue\", &vi,\n                  in_ct == 3 ? in_palette[in_index].blue :\n                     sample(std, in_ct, in_bd, x, 2, 0, 0),\n                  out_ct == 3 ? out_palette[out_index].blue :\n                     sample(pRow, out_ct, out_bd, x, 2, 0, 0),\n                  alpha/*component*/, vi.background_blue);\n            }\n         }\n      }\n\n      else if (memcmp(std, pRow, cbRow) != 0)\n      {\n         char msg[64];\n\n         /* No transform is expected on the threshold tests. */\n         sprintf(msg, \"gamma: below threshold row %lu changed\",\n            (unsigned long)y);\n\n         png_error(pp, msg);\n      }\n   } /* row (y) loop */\n\n   dp->this.ps->validated = 1;\n}\n\nstatic void PNGCBAPI\ngamma_end(png_structp ppIn, png_infop pi)\n{\n   png_const_structp pp = ppIn;\n   gamma_display *dp = voidcast(gamma_display*, png_get_progressive_ptr(pp));\n\n   if (!dp->this.speed)\n      gamma_image_validate(dp, pp, pi);\n   else\n      dp->this.ps->validated = 1;\n}\n\n/* A single test run checking a gamma transformation.\n *\n * maxabs: maximum absolute error as a fraction\n * maxout: maximum output error in the output units\n * maxpc:  maximum percentage error (as a percentage)\n */\nstatic void\ngamma_test(png_modifier *pmIn, const png_byte colour_typeIn,\n    const png_byte bit_depthIn, const int palette_numberIn,\n    const int interlace_typeIn,\n    const double file_gammaIn, const double screen_gammaIn,\n    const png_byte sbitIn, const int threshold_testIn,\n    const char *name,\n    const int use_input_precisionIn, const int scale16In,\n    const int expand16In, const int do_backgroundIn,\n    const png_color_16 *bkgd_colorIn, double bkgd_gammaIn)\n{\n   gamma_display d;\n   context(&pmIn->this, fault);\n\n   gamma_display_init(&d, pmIn, FILEID(colour_typeIn, bit_depthIn,\n      palette_numberIn, interlace_typeIn, 0, 0, 0),\n      file_gammaIn, screen_gammaIn, sbitIn,\n      threshold_testIn, use_input_precisionIn, scale16In,\n      expand16In, do_backgroundIn, bkgd_colorIn, bkgd_gammaIn);\n\n   Try\n   {\n      png_structp pp;\n      png_infop pi;\n      gama_modification gama_mod;\n      srgb_modification srgb_mod;\n      sbit_modification sbit_mod;\n\n      /* For the moment don't use the png_modifier support here. */\n      d.pm->encoding_counter = 0;\n      modifier_set_encoding(d.pm); /* Just resets everything */\n      d.pm->current_gamma = d.file_gamma;\n\n      /* Make an appropriate modifier to set the PNG file gamma to the\n       * given gamma value and the sBIT chunk to the given precision.\n       */\n      d.pm->modifications = NULL;\n      gama_modification_init(&gama_mod, d.pm, d.file_gamma);\n      srgb_modification_init(&srgb_mod, d.pm, 127 /*delete*/);\n      if (d.sbit > 0)\n         sbit_modification_init(&sbit_mod, d.pm, d.sbit);\n\n      modification_reset(d.pm->modifications);\n\n      /* Get a png_struct for reading the image. */\n      pp = set_modifier_for_read(d.pm, &pi, d.this.id, name);\n      standard_palette_init(&d.this);\n\n      /* Introduce the correct read function. */\n      if (d.pm->this.progressive)\n      {\n         /* Share the row function with the standard implementation. */\n         png_set_progressive_read_fn(pp, &d, gamma_info, progressive_row,\n            gamma_end);\n\n         /* Now feed data into the reader until we reach the end: */\n         modifier_progressive_read(d.pm, pp, pi);\n      }\n      else\n      {\n         /* modifier_read expects a png_modifier* */\n         png_set_read_fn(pp, d.pm, modifier_read);\n\n         /* Check the header values: */\n         png_read_info(pp, pi);\n\n         /* Process the 'info' requirements. Only one image is generated */\n         gamma_info_imp(&d, pp, pi);\n\n         sequential_row(&d.this, pp, pi, -1, 0);\n\n         if (!d.this.speed)\n            gamma_image_validate(&d, pp, pi);\n         else\n            d.this.ps->validated = 1;\n      }\n\n      modifier_reset(d.pm);\n\n      if (d.pm->log && !d.threshold_test && !d.this.speed)\n         fprintf(stderr, \"%d bit %s %s: max error %f (%.2g, %2g%%)\\n\",\n            d.this.bit_depth, colour_types[d.this.colour_type], name,\n            d.maxerrout, d.maxerrabs, 100*d.maxerrpc);\n\n      /* Log the summary values too. */\n      if (d.this.colour_type == 0 || d.this.colour_type == 4)\n      {\n         switch (d.this.bit_depth)\n         {\n         case 1:\n            break;\n\n         case 2:\n            if (d.maxerrout > d.pm->error_gray_2)\n               d.pm->error_gray_2 = d.maxerrout;\n\n            break;\n\n         case 4:\n            if (d.maxerrout > d.pm->error_gray_4)\n               d.pm->error_gray_4 = d.maxerrout;\n\n            break;\n\n         case 8:\n            if (d.maxerrout > d.pm->error_gray_8)\n               d.pm->error_gray_8 = d.maxerrout;\n\n            break;\n\n         case 16:\n            if (d.maxerrout > d.pm->error_gray_16)\n               d.pm->error_gray_16 = d.maxerrout;\n\n            break;\n\n         default:\n            png_error(pp, \"bad bit depth (internal: 1)\");\n         }\n      }\n\n      else if (d.this.colour_type == 2 || d.this.colour_type == 6)\n      {\n         switch (d.this.bit_depth)\n         {\n         case 8:\n\n            if (d.maxerrout > d.pm->error_color_8)\n               d.pm->error_color_8 = d.maxerrout;\n\n            break;\n\n         case 16:\n\n            if (d.maxerrout > d.pm->error_color_16)\n               d.pm->error_color_16 = d.maxerrout;\n\n            break;\n\n         default:\n            png_error(pp, \"bad bit depth (internal: 2)\");\n         }\n      }\n\n      else if (d.this.colour_type == 3)\n      {\n         if (d.maxerrout > d.pm->error_indexed)\n            d.pm->error_indexed = d.maxerrout;\n      }\n   }\n\n   Catch(fault)\n      modifier_reset(voidcast(png_modifier*,(void*)fault));\n}\n\nstatic void gamma_threshold_test(png_modifier *pm, png_byte colour_type,\n    png_byte bit_depth, int interlace_type, double file_gamma,\n    double screen_gamma)\n{\n   size_t pos = 0;\n   char name[64];\n   pos = safecat(name, sizeof name, pos, \"threshold \");\n   pos = safecatd(name, sizeof name, pos, file_gamma, 3);\n   pos = safecat(name, sizeof name, pos, \"/\");\n   pos = safecatd(name, sizeof name, pos, screen_gamma, 3);\n\n   (void)gamma_test(pm, colour_type, bit_depth, 0/*palette*/, interlace_type,\n      file_gamma, screen_gamma, 0/*sBIT*/, 1/*threshold test*/, name,\n      0 /*no input precision*/,\n      0 /*no scale16*/, 0 /*no expand16*/, 0 /*no background*/, 0 /*hence*/,\n      0 /*no background gamma*/);\n}\n\nstatic void\nperform_gamma_threshold_tests(png_modifier *pm)\n{\n   png_byte colour_type = 0;\n   png_byte bit_depth = 0;\n   unsigned int palette_number = 0;\n\n   /* Don't test more than one instance of each palette - it's pointless, in\n    * fact this test is somewhat excessive since libpng doesn't make this\n    * decision based on colour type or bit depth!\n    *\n    * CHANGED: now test two palettes and, as a side effect, images with and\n    * without tRNS.\n    */\n   while (next_format(&colour_type, &bit_depth, &palette_number,\n                      pm->test_lbg_gamma_threshold, pm->test_tRNS))\n      if (palette_number < 2)\n   {\n      double test_gamma = 1.0;\n      while (test_gamma >= .4)\n      {\n         /* There's little point testing the interlacing vs non-interlacing,\n          * but this can be set from the command line.\n          */\n         gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type,\n            test_gamma, 1/test_gamma);\n         test_gamma *= .95;\n      }\n\n      /* And a special test for sRGB */\n      gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type,\n          .45455, 2.2);\n\n      if (fail(pm))\n         return;\n   }\n}\n\nstatic void gamma_transform_test(png_modifier *pm,\n   const png_byte colour_type, const png_byte bit_depth,\n   const int palette_number,\n   const int interlace_type, const double file_gamma,\n   const double screen_gamma, const png_byte sbit,\n   const int use_input_precision, const int scale16)\n{\n   size_t pos = 0;\n   char name[64];\n\n   if (sbit != bit_depth && sbit != 0)\n   {\n      pos = safecat(name, sizeof name, pos, \"sbit(\");\n      pos = safecatn(name, sizeof name, pos, sbit);\n      pos = safecat(name, sizeof name, pos, \") \");\n   }\n\n   else\n      pos = safecat(name, sizeof name, pos, \"gamma \");\n\n   if (scale16)\n      pos = safecat(name, sizeof name, pos, \"16to8 \");\n\n   pos = safecatd(name, sizeof name, pos, file_gamma, 3);\n   pos = safecat(name, sizeof name, pos, \"->\");\n   pos = safecatd(name, sizeof name, pos, screen_gamma, 3);\n\n   gamma_test(pm, colour_type, bit_depth, palette_number, interlace_type,\n      file_gamma, screen_gamma, sbit, 0, name, use_input_precision,\n      scale16, pm->test_gamma_expand16, 0 , 0, 0);\n}\n\nstatic void perform_gamma_transform_tests(png_modifier *pm)\n{\n   png_byte colour_type = 0;\n   png_byte bit_depth = 0;\n   unsigned int palette_number = 0;\n\n   while (next_format(&colour_type, &bit_depth, &palette_number,\n                      pm->test_lbg_gamma_transform, pm->test_tRNS))\n   {\n      unsigned int i, j;\n\n      for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j)\n         if (i != j)\n         {\n            gamma_transform_test(pm, colour_type, bit_depth, palette_number,\n               pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], 0/*sBIT*/,\n               pm->use_input_precision, 0 /*do not scale16*/);\n\n            if (fail(pm))\n               return;\n         }\n   }\n}\n\nstatic void perform_gamma_sbit_tests(png_modifier *pm)\n{\n   png_byte sbit;\n\n   /* The only interesting cases are colour and grayscale, alpha is ignored here\n    * for overall speed.  Only bit depths where sbit is less than the bit depth\n    * are tested.\n    */\n   for (sbit=pm->sbitlow; sbit<(1<<READ_BDHI); ++sbit)\n   {\n      png_byte colour_type = 0, bit_depth = 0;\n      unsigned int npalette = 0;\n\n      while (next_format(&colour_type, &bit_depth, &npalette,\n                         pm->test_lbg_gamma_sbit, pm->test_tRNS))\n         if ((colour_type & PNG_COLOR_MASK_ALPHA) == 0 &&\n            ((colour_type == 3 && sbit < 8) ||\n            (colour_type != 3 && sbit < bit_depth)))\n      {\n         unsigned int i;\n\n         for (i=0; i<pm->ngamma_tests; ++i)\n         {\n            unsigned int j;\n\n            for (j=0; j<pm->ngamma_tests; ++j) if (i != j)\n            {\n               gamma_transform_test(pm, colour_type, bit_depth, npalette,\n                  pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],\n                  sbit, pm->use_input_precision_sbit, 0 /*scale16*/);\n\n               if (fail(pm))\n                  return;\n            }\n         }\n      }\n   }\n}\n\n/* Note that this requires a 16 bit source image but produces 8 bit output, so\n * we only need the 16bit write support, but the 16 bit images are only\n * generated if DO_16BIT is defined.\n */\n#ifdef DO_16BIT\nstatic void perform_gamma_scale16_tests(png_modifier *pm)\n{\n#  ifndef PNG_MAX_GAMMA_8\n#     define PNG_MAX_GAMMA_8 11\n#  endif\n#  if defined PNG_MAX_GAMMA_8 || PNG_LIBPNG_VER < 10700\n#     define SBIT_16_TO_8 PNG_MAX_GAMMA_8\n#  else\n#     define SBIT_16_TO_8 16\n#  endif\n   /* Include the alpha cases here. Note that sbit matches the internal value\n    * used by the library - otherwise we will get spurious errors from the\n    * internal sbit style approximation.\n    *\n    * The threshold test is here because otherwise the 16 to 8 conversion will\n    * proceed *without* gamma correction, and the tests above will fail (but not\n    * by much) - this could be fixed, it only appears with the -g option.\n    */\n   unsigned int i, j;\n   for (i=0; i<pm->ngamma_tests; ++i)\n   {\n      for (j=0; j<pm->ngamma_tests; ++j)\n      {\n         if (i != j &&\n             fabs(pm->gammas[j]/pm->gammas[i]-1) >= PNG_GAMMA_THRESHOLD)\n         {\n            gamma_transform_test(pm, 0, 16, 0, pm->interlace_type,\n               1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,\n               pm->use_input_precision_16to8, 1 /*scale16*/);\n\n            if (fail(pm))\n               return;\n\n            gamma_transform_test(pm, 2, 16, 0, pm->interlace_type,\n               1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,\n               pm->use_input_precision_16to8, 1 /*scale16*/);\n\n            if (fail(pm))\n               return;\n\n            gamma_transform_test(pm, 4, 16, 0, pm->interlace_type,\n               1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,\n               pm->use_input_precision_16to8, 1 /*scale16*/);\n\n            if (fail(pm))\n               return;\n\n            gamma_transform_test(pm, 6, 16, 0, pm->interlace_type,\n               1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,\n               pm->use_input_precision_16to8, 1 /*scale16*/);\n\n            if (fail(pm))\n               return;\n         }\n      }\n   }\n}\n#endif /* 16 to 8 bit conversion */\n\n#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\\\n   defined(PNG_READ_ALPHA_MODE_SUPPORTED)\nstatic void gamma_composition_test(png_modifier *pm,\n   const png_byte colour_type, const png_byte bit_depth,\n   const int palette_number,\n   const int interlace_type, const double file_gamma,\n   const double screen_gamma,\n   const int use_input_precision, const int do_background,\n   const int expand_16)\n{\n   size_t pos = 0;\n   png_const_charp base;\n   double bg;\n   char name[128];\n   png_color_16 background;\n\n   /* Make up a name and get an appropriate background gamma value. */\n   switch (do_background)\n   {\n      default:\n         base = \"\";\n         bg = 4; /* should not be used */\n         break;\n      case PNG_BACKGROUND_GAMMA_SCREEN:\n         base = \" bckg(Screen):\";\n         bg = 1/screen_gamma;\n         break;\n      case PNG_BACKGROUND_GAMMA_FILE:\n         base = \" bckg(File):\";\n         bg = file_gamma;\n         break;\n      case PNG_BACKGROUND_GAMMA_UNIQUE:\n         base = \" bckg(Unique):\";\n         /* This tests the handling of a unique value, the math is such that the\n          * value tends to be <1, but is neither screen nor file (even if they\n          * match!)\n          */\n         bg = (file_gamma + screen_gamma) / 3;\n         break;\n#ifdef PNG_READ_ALPHA_MODE_SUPPORTED\n      case ALPHA_MODE_OFFSET + PNG_ALPHA_PNG:\n         base = \" alpha(PNG)\";\n         bg = 4; /* should not be used */\n         break;\n      case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD:\n         base = \" alpha(Porter-Duff)\";\n         bg = 4; /* should not be used */\n         break;\n      case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED:\n         base = \" alpha(Optimized)\";\n         bg = 4; /* should not be used */\n         break;\n      case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN:\n         base = \" alpha(Broken)\";\n         bg = 4; /* should not be used */\n         break;\n#endif\n   }\n\n   /* Use random background values - the background is always presented in the\n    * output space (8 or 16 bit components).\n    */\n   if (expand_16 || bit_depth == 16)\n   {\n      png_uint_32 r = random_32();\n\n      background.red = (png_uint_16)r;\n      background.green = (png_uint_16)(r >> 16);\n      r = random_32();\n      background.blue = (png_uint_16)r;\n      background.gray = (png_uint_16)(r >> 16);\n\n      /* In earlier libpng versions, those where DIGITIZE is set, any background\n       * gamma correction in the expand16 case was done using 8-bit gamma\n       * correction tables, resulting in larger errors.  To cope with those\n       * cases use a 16-bit background value which will handle this gamma\n       * correction.\n       */\n#     if DIGITIZE\n         if (expand_16 && (do_background == PNG_BACKGROUND_GAMMA_UNIQUE ||\n                           do_background == PNG_BACKGROUND_GAMMA_FILE) &&\n            fabs(bg*screen_gamma-1) > PNG_GAMMA_THRESHOLD)\n         {\n            /* The background values will be looked up in an 8-bit table to do\n             * the gamma correction, so only select values which are an exact\n             * match for the 8-bit table entries:\n             */\n            background.red = (png_uint_16)((background.red >> 8) * 257);\n            background.green = (png_uint_16)((background.green >> 8) * 257);\n            background.blue = (png_uint_16)((background.blue >> 8) * 257);\n            background.gray = (png_uint_16)((background.gray >> 8) * 257);\n         }\n#     endif\n   }\n\n   else /* 8 bit colors */\n   {\n      png_uint_32 r = random_32();\n\n      background.red = (png_byte)r;\n      background.green = (png_byte)(r >> 8);\n      background.blue = (png_byte)(r >> 16);\n      background.gray = (png_byte)(r >> 24);\n   }\n\n   background.index = 193; /* rgb(193,193,193) to detect errors */\n\n   if (!(colour_type & PNG_COLOR_MASK_COLOR))\n   {\n      /* Because, currently, png_set_background is always called with\n       * 'need_expand' false in this case and because the gamma test itself\n       * doesn't cause an expand to 8-bit for lower bit depths the colour must\n       * be reduced to the correct range.\n       */\n      if (bit_depth < 8)\n         background.gray &= (png_uint_16)((1U << bit_depth)-1);\n\n      /* Grayscale input, we do not convert to RGB (TBD), so we must set the\n       * background to gray - else libpng seems to fail.\n       */\n      background.red = background.green = background.blue = background.gray;\n   }\n\n   pos = safecat(name, sizeof name, pos, \"gamma \");\n   pos = safecatd(name, sizeof name, pos, file_gamma, 3);\n   pos = safecat(name, sizeof name, pos, \"->\");\n   pos = safecatd(name, sizeof name, pos, screen_gamma, 3);\n\n   pos = safecat(name, sizeof name, pos, base);\n   if (do_background < ALPHA_MODE_OFFSET)\n   {\n      /* Include the background color and gamma in the name: */\n      pos = safecat(name, sizeof name, pos, \"(\");\n      /* This assumes no expand gray->rgb - the current code won't handle that!\n       */\n      if (colour_type & PNG_COLOR_MASK_COLOR)\n      {\n         pos = safecatn(name, sizeof name, pos, background.red);\n         pos = safecat(name, sizeof name, pos, \",\");\n         pos = safecatn(name, sizeof name, pos, background.green);\n         pos = safecat(name, sizeof name, pos, \",\");\n         pos = safecatn(name, sizeof name, pos, background.blue);\n      }\n      else\n         pos = safecatn(name, sizeof name, pos, background.gray);\n      pos = safecat(name, sizeof name, pos, \")^\");\n      pos = safecatd(name, sizeof name, pos, bg, 3);\n   }\n\n   gamma_test(pm, colour_type, bit_depth, palette_number, interlace_type,\n      file_gamma, screen_gamma, 0/*sBIT*/, 0, name, use_input_precision,\n      0/*strip 16*/, expand_16, do_background, &background, bg);\n}\n\n\nstatic void\nperform_gamma_composition_tests(png_modifier *pm, int do_background,\n   int expand_16)\n{\n   png_byte colour_type = 0;\n   png_byte bit_depth = 0;\n   unsigned int palette_number = 0;\n\n   /* Skip the non-alpha cases - there is no setting of a transparency colour at\n    * present.\n    *\n    * TODO: incorrect; the palette case sets tRNS and, now RGB and gray do,\n    * however the palette case fails miserably so is commented out below.\n    */\n   while (next_format(&colour_type, &bit_depth, &palette_number,\n                      pm->test_lbg_gamma_composition, pm->test_tRNS))\n      if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0\n#if 0 /* TODO: FIXME */\n          /*TODO: FIXME: this should work */\n          || colour_type == 3\n#endif\n          || (colour_type != 3 && palette_number != 0))\n   {\n      unsigned int i, j;\n\n      /* Don't skip the i==j case here - it's relevant. */\n      for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j)\n      {\n         gamma_composition_test(pm, colour_type, bit_depth, palette_number,\n            pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],\n            pm->use_input_precision, do_background, expand_16);\n\n         if (fail(pm))\n            return;\n      }\n   }\n}\n#endif /* READ_BACKGROUND || READ_ALPHA_MODE */\n\nstatic void\ninit_gamma_errors(png_modifier *pm)\n{\n   /* Use -1 to catch tests that were not actually run */\n   pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = -1.;\n   pm->error_color_8 = -1.;\n   pm->error_indexed = -1.;\n   pm->error_gray_16 = pm->error_color_16 = -1.;\n}\n\nstatic void\nprint_one(const char *leader, double err)\n{\n   if (err != -1.)\n      printf(\" %s %.5f\\n\", leader, err);\n}\n\nstatic void\nsummarize_gamma_errors(png_modifier *pm, png_const_charp who, int low_bit_depth,\n   int indexed)\n{\n   fflush(stderr);\n\n   if (who)\n      printf(\"\\nGamma correction with %s:\\n\", who);\n\n   else\n      printf(\"\\nBasic gamma correction:\\n\");\n\n   if (low_bit_depth)\n   {\n      print_one(\" 2 bit gray: \", pm->error_gray_2);\n      print_one(\" 4 bit gray: \", pm->error_gray_4);\n      print_one(\" 8 bit gray: \", pm->error_gray_8);\n      print_one(\" 8 bit color:\", pm->error_color_8);\n      if (indexed)\n         print_one(\" indexed:    \", pm->error_indexed);\n   }\n\n   print_one(\"16 bit gray: \", pm->error_gray_16);\n   print_one(\"16 bit color:\", pm->error_color_16);\n\n   fflush(stdout);\n}\n\nstatic void\nperform_gamma_test(png_modifier *pm, int summary)\n{\n   /*TODO: remove this*/\n   /* Save certain values for the temporary overrides below. */\n   unsigned int calculations_use_input_precision =\n      pm->calculations_use_input_precision;\n#  ifdef PNG_READ_BACKGROUND_SUPPORTED\n      double maxout8 = pm->maxout8;\n#  endif\n\n   /* First some arbitrary no-transform tests: */\n   if (!pm->this.speed && pm->test_gamma_threshold)\n   {\n      perform_gamma_threshold_tests(pm);\n\n      if (fail(pm))\n         return;\n   }\n\n   /* Now some real transforms. */\n   if (pm->test_gamma_transform)\n   {\n      if (summary)\n      {\n         fflush(stderr);\n         printf(\"Gamma correction error summary\\n\\n\");\n         printf(\"The printed value is the maximum error in the pixel values\\n\");\n         printf(\"calculated by the libpng gamma correction code.  The error\\n\");\n         printf(\"is calculated as the difference between the output pixel\\n\");\n         printf(\"value (always an integer) and the ideal value from the\\n\");\n         printf(\"libpng specification (typically not an integer).\\n\\n\");\n\n         printf(\"Expect this value to be less than .5 for 8 bit formats,\\n\");\n         printf(\"less than 1 for formats with fewer than 8 bits and a small\\n\");\n         printf(\"number (typically less than 5) for the 16 bit formats.\\n\");\n         printf(\"For performance reasons the value for 16 bit formats\\n\");\n         printf(\"increases when the image file includes an sBIT chunk.\\n\");\n         fflush(stdout);\n      }\n\n      init_gamma_errors(pm);\n      /*TODO: remove this.  Necessary because the current libpng\n       * implementation works in 8 bits:\n       */\n      if (pm->test_gamma_expand16)\n         pm->calculations_use_input_precision = 1;\n      perform_gamma_transform_tests(pm);\n      if (!calculations_use_input_precision)\n         pm->calculations_use_input_precision = 0;\n\n      if (summary)\n         summarize_gamma_errors(pm, 0/*who*/, 1/*low bit depth*/, 1/*indexed*/);\n\n      if (fail(pm))\n         return;\n   }\n\n   /* The sbit tests produce much larger errors: */\n   if (pm->test_gamma_sbit)\n   {\n      init_gamma_errors(pm);\n      perform_gamma_sbit_tests(pm);\n\n      if (summary)\n         summarize_gamma_errors(pm, \"sBIT\", pm->sbitlow < 8U, 1/*indexed*/);\n\n      if (fail(pm))\n         return;\n   }\n\n#ifdef DO_16BIT /* Should be READ_16BIT_SUPPORTED */\n   if (pm->test_gamma_scale16)\n   {\n      /* The 16 to 8 bit strip operations: */\n      init_gamma_errors(pm);\n      perform_gamma_scale16_tests(pm);\n\n      if (summary)\n      {\n         fflush(stderr);\n         printf(\"\\nGamma correction with 16 to 8 bit reduction:\\n\");\n         printf(\" 16 bit gray:  %.5f\\n\", pm->error_gray_16);\n         printf(\" 16 bit color: %.5f\\n\", pm->error_color_16);\n         fflush(stdout);\n      }\n\n      if (fail(pm))\n         return;\n   }\n#endif\n\n#ifdef PNG_READ_BACKGROUND_SUPPORTED\n   if (pm->test_gamma_background)\n   {\n      init_gamma_errors(pm);\n\n      /*TODO: remove this.  Necessary because the current libpng\n       * implementation works in 8 bits:\n       */\n      if (pm->test_gamma_expand16)\n      {\n         pm->calculations_use_input_precision = 1;\n         pm->maxout8 = .499; /* because the 16 bit background is smashed */\n      }\n      perform_gamma_composition_tests(pm, PNG_BACKGROUND_GAMMA_UNIQUE,\n         pm->test_gamma_expand16);\n      if (!calculations_use_input_precision)\n         pm->calculations_use_input_precision = 0;\n      pm->maxout8 = maxout8;\n\n      if (summary)\n         summarize_gamma_errors(pm, \"background\", 1, 0/*indexed*/);\n\n      if (fail(pm))\n         return;\n   }\n#endif\n\n#ifdef PNG_READ_ALPHA_MODE_SUPPORTED\n   if (pm->test_gamma_alpha_mode)\n   {\n      int do_background;\n\n      init_gamma_errors(pm);\n\n      /*TODO: remove this.  Necessary because the current libpng\n       * implementation works in 8 bits:\n       */\n      if (pm->test_gamma_expand16)\n         pm->calculations_use_input_precision = 1;\n      for (do_background = ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD;\n         do_background <= ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN && !fail(pm);\n         ++do_background)\n         perform_gamma_composition_tests(pm, do_background,\n            pm->test_gamma_expand16);\n      if (!calculations_use_input_precision)\n         pm->calculations_use_input_precision = 0;\n\n      if (summary)\n         summarize_gamma_errors(pm, \"alpha mode\", 1, 0/*indexed*/);\n\n      if (fail(pm))\n         return;\n   }\n#endif\n}\n#endif /* PNG_READ_GAMMA_SUPPORTED */\n#endif /* PNG_READ_SUPPORTED */\n\n/* INTERLACE MACRO VALIDATION */\n/* This is copied verbatim from the specification, it is simply the pass\n * number in which each pixel in each 8x8 tile appears.  The array must\n * be indexed adam7[y][x] and notice that the pass numbers are based at\n * 1, not 0 - the base libpng uses.\n */\nstatic const\npng_byte adam7[8][8] =\n{\n   { 1,6,4,6,2,6,4,6 },\n   { 7,7,7,7,7,7,7,7 },\n   { 5,6,5,6,5,6,5,6 },\n   { 7,7,7,7,7,7,7,7 },\n   { 3,6,4,6,3,6,4,6 },\n   { 7,7,7,7,7,7,7,7 },\n   { 5,6,5,6,5,6,5,6 },\n   { 7,7,7,7,7,7,7,7 }\n};\n\n/* This routine validates all the interlace support macros in png.h for\n * a variety of valid PNG widths and heights.  It uses a number of similarly\n * named internal routines that feed off the above array.\n */\nstatic png_uint_32\npng_pass_start_row(int pass)\n{\n   int x, y;\n   ++pass;\n   for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)\n      return y;\n   return 0xf;\n}\n\nstatic png_uint_32\npng_pass_start_col(int pass)\n{\n   int x, y;\n   ++pass;\n   for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)\n      return x;\n   return 0xf;\n}\n\nstatic int\npng_pass_row_shift(int pass)\n{\n   int x, y, base=(-1), inc=8;\n   ++pass;\n   for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)\n   {\n      if (base == (-1))\n         base = y;\n      else if (base == y)\n         {}\n      else if (inc == y-base)\n         base=y;\n      else if (inc == 8)\n         inc = y-base, base=y;\n      else if (inc != y-base)\n         return 0xff; /* error - more than one 'inc' value! */\n   }\n\n   if (base == (-1)) return 0xfe; /* error - no row in pass! */\n\n   /* The shift is always 1, 2 or 3 - no pass has all the rows! */\n   switch (inc)\n   {\ncase 2: return 1;\ncase 4: return 2;\ncase 8: return 3;\ndefault: break;\n   }\n\n   /* error - unrecognized 'inc' */\n   return (inc << 8) + 0xfd;\n}\n\nstatic int\npng_pass_col_shift(int pass)\n{\n   int x, y, base=(-1), inc=8;\n   ++pass;\n   for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)\n   {\n      if (base == (-1))\n         base = x;\n      else if (base == x)\n         {}\n      else if (inc == x-base)\n         base=x;\n      else if (inc == 8)\n         inc = x-base, base=x;\n      else if (inc != x-base)\n         return 0xff; /* error - more than one 'inc' value! */\n   }\n\n   if (base == (-1)) return 0xfe; /* error - no row in pass! */\n\n   /* The shift is always 1, 2 or 3 - no pass has all the rows! */\n   switch (inc)\n   {\ncase 1: return 0; /* pass 7 has all the columns */\ncase 2: return 1;\ncase 4: return 2;\ncase 8: return 3;\ndefault: break;\n   }\n\n   /* error - unrecognized 'inc' */\n   return (inc << 8) + 0xfd;\n}\n\nstatic png_uint_32\npng_row_from_pass_row(png_uint_32 yIn, int pass)\n{\n   /* By examination of the array: */\n   switch (pass)\n   {\ncase 0: return yIn * 8;\ncase 1: return yIn * 8;\ncase 2: return yIn * 8 + 4;\ncase 3: return yIn * 4;\ncase 4: return yIn * 4 + 2;\ncase 5: return yIn * 2;\ncase 6: return yIn * 2 + 1;\ndefault: break;\n   }\n\n   return 0xff; /* bad pass number */\n}\n\nstatic png_uint_32\npng_col_from_pass_col(png_uint_32 xIn, int pass)\n{\n   /* By examination of the array: */\n   switch (pass)\n   {\ncase 0: return xIn * 8;\ncase 1: return xIn * 8 + 4;\ncase 2: return xIn * 4;\ncase 3: return xIn * 4 + 2;\ncase 4: return xIn * 2;\ncase 5: return xIn * 2 + 1;\ncase 6: return xIn;\ndefault: break;\n   }\n\n   return 0xff; /* bad pass number */\n}\n\nstatic int\npng_row_in_interlace_pass(png_uint_32 y, int pass)\n{\n   /* Is row 'y' in pass 'pass'? */\n   int x;\n   y &= 7;\n   ++pass;\n   for (x=0; x<8; ++x) if (adam7[y][x] == pass)\n      return 1;\n\n   return 0;\n}\n\nstatic int\npng_col_in_interlace_pass(png_uint_32 x, int pass)\n{\n   /* Is column 'x' in pass 'pass'? */\n   int y;\n   x &= 7;\n   ++pass;\n   for (y=0; y<8; ++y) if (adam7[y][x] == pass)\n      return 1;\n\n   return 0;\n}\n\nstatic png_uint_32\npng_pass_rows(png_uint_32 height, int pass)\n{\n   png_uint_32 tiles = height>>3;\n   png_uint_32 rows = 0;\n   unsigned int x, y;\n\n   height &= 7;\n   ++pass;\n   for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)\n   {\n      rows += tiles;\n      if (y < height) ++rows;\n      break; /* i.e. break the 'x', column, loop. */\n   }\n\n   return rows;\n}\n\nstatic png_uint_32\npng_pass_cols(png_uint_32 width, int pass)\n{\n   png_uint_32 tiles = width>>3;\n   png_uint_32 cols = 0;\n   unsigned int x, y;\n\n   width &= 7;\n   ++pass;\n   for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)\n   {\n      cols += tiles;\n      if (x < width) ++cols;\n      break; /* i.e. break the 'y', row, loop. */\n   }\n\n   return cols;\n}\n\nstatic void\nperform_interlace_macro_validation(void)\n{\n   /* The macros to validate, first those that depend only on pass:\n    *\n    * PNG_PASS_START_ROW(pass)\n    * PNG_PASS_START_COL(pass)\n    * PNG_PASS_ROW_SHIFT(pass)\n    * PNG_PASS_COL_SHIFT(pass)\n    */\n   int pass;\n\n   for (pass=0; pass<7; ++pass)\n   {\n      png_uint_32 m, f, v;\n\n      m = PNG_PASS_START_ROW(pass);\n      f = png_pass_start_row(pass);\n      if (m != f)\n      {\n         fprintf(stderr, \"PNG_PASS_START_ROW(%d) = %u != %x\\n\", pass, m, f);\n         exit(99);\n      }\n\n      m = PNG_PASS_START_COL(pass);\n      f = png_pass_start_col(pass);\n      if (m != f)\n      {\n         fprintf(stderr, \"PNG_PASS_START_COL(%d) = %u != %x\\n\", pass, m, f);\n         exit(99);\n      }\n\n      m = PNG_PASS_ROW_SHIFT(pass);\n      f = png_pass_row_shift(pass);\n      if (m != f)\n      {\n         fprintf(stderr, \"PNG_PASS_ROW_SHIFT(%d) = %u != %x\\n\", pass, m, f);\n         exit(99);\n      }\n\n      m = PNG_PASS_COL_SHIFT(pass);\n      f = png_pass_col_shift(pass);\n      if (m != f)\n      {\n         fprintf(stderr, \"PNG_PASS_COL_SHIFT(%d) = %u != %x\\n\", pass, m, f);\n         exit(99);\n      }\n\n      /* Macros that depend on the image or sub-image height too:\n       *\n       * PNG_PASS_ROWS(height, pass)\n       * PNG_PASS_COLS(width, pass)\n       * PNG_ROW_FROM_PASS_ROW(yIn, pass)\n       * PNG_COL_FROM_PASS_COL(xIn, pass)\n       * PNG_ROW_IN_INTERLACE_PASS(y, pass)\n       * PNG_COL_IN_INTERLACE_PASS(x, pass)\n       */\n      for (v=0;;)\n      {\n         /* First the base 0 stuff: */\n         m = PNG_ROW_FROM_PASS_ROW(v, pass);\n         f = png_row_from_pass_row(v, pass);\n         if (m != f)\n         {\n            fprintf(stderr, \"PNG_ROW_FROM_PASS_ROW(%u, %d) = %u != %x\\n\",\n               v, pass, m, f);\n            exit(99);\n         }\n\n         m = PNG_COL_FROM_PASS_COL(v, pass);\n         f = png_col_from_pass_col(v, pass);\n         if (m != f)\n         {\n            fprintf(stderr, \"PNG_COL_FROM_PASS_COL(%u, %d) = %u != %x\\n\",\n               v, pass, m, f);\n            exit(99);\n         }\n\n         m = PNG_ROW_IN_INTERLACE_PASS(v, pass);\n         f = png_row_in_interlace_pass(v, pass);\n         if (m != f)\n         {\n            fprintf(stderr, \"PNG_ROW_IN_INTERLACE_PASS(%u, %d) = %u != %x\\n\",\n               v, pass, m, f);\n            exit(99);\n         }\n\n         m = PNG_COL_IN_INTERLACE_PASS(v, pass);\n         f = png_col_in_interlace_pass(v, pass);\n         if (m != f)\n         {\n            fprintf(stderr, \"PNG_COL_IN_INTERLACE_PASS(%u, %d) = %u != %x\\n\",\n               v, pass, m, f);\n            exit(99);\n         }\n\n         /* Then the base 1 stuff: */\n         ++v;\n         m = PNG_PASS_ROWS(v, pass);\n         f = png_pass_rows(v, pass);\n         if (m != f)\n         {\n            fprintf(stderr, \"PNG_PASS_ROWS(%u, %d) = %u != %x\\n\",\n               v, pass, m, f);\n            exit(99);\n         }\n\n         m = PNG_PASS_COLS(v, pass);\n         f = png_pass_cols(v, pass);\n         if (m != f)\n         {\n            fprintf(stderr, \"PNG_PASS_COLS(%u, %d) = %u != %x\\n\",\n               v, pass, m, f);\n            exit(99);\n         }\n\n         /* Move to the next v - the stepping algorithm starts skipping\n          * values above 1024.\n          */\n         if (v > 1024)\n         {\n            if (v == PNG_UINT_31_MAX)\n               break;\n\n            v = (v << 1) ^ v;\n            if (v >= PNG_UINT_31_MAX)\n               v = PNG_UINT_31_MAX-1;\n         }\n      }\n   }\n}\n\n/* Test color encodings. These values are back-calculated from the published\n * chromaticities.  The values are accurate to about 14 decimal places; 15 are\n * given.  These values are much more accurate than the ones given in the spec,\n * which typically don't exceed 4 decimal places.  This allows testing of the\n * libpng code to its theoretical accuracy of 4 decimal places.  (If pngvalid\n * used the published errors the 'slack' permitted would have to be +/-.5E-4 or\n * more.)\n *\n * The png_modifier code assumes that encodings[0] is sRGB and treats it\n * specially: do not change the first entry in this list!\n */\nstatic const color_encoding test_encodings[] =\n{\n/* sRGB: must be first in this list! */\n/*gamma:*/ { 1/2.2,\n/*red:  */ { 0.412390799265959, 0.212639005871510, 0.019330818715592 },\n/*green:*/ { 0.357584339383878, 0.715168678767756, 0.119194779794626 },\n/*blue: */ { 0.180480788401834, 0.072192315360734, 0.950532152249660} },\n/* Kodak ProPhoto (wide gamut) */\n/*gamma:*/ { 1/1.6 /*approximate: uses 1.8 power law compared to sRGB 2.4*/,\n/*red:  */ { 0.797760489672303, 0.288071128229293, 0.000000000000000 },\n/*green:*/ { 0.135185837175740, 0.711843217810102, 0.000000000000000 },\n/*blue: */ { 0.031349349581525, 0.000085653960605, 0.825104602510460} },\n/* Adobe RGB (1998) */\n/*gamma:*/ { 1/(2+51./256),\n/*red:  */ { 0.576669042910131, 0.297344975250536, 0.027031361386412 },\n/*green:*/ { 0.185558237906546, 0.627363566255466, 0.070688852535827 },\n/*blue: */ { 0.188228646234995, 0.075291458493998, 0.991337536837639} },\n/* Adobe Wide Gamut RGB */\n/*gamma:*/ { 1/(2+51./256),\n/*red:  */ { 0.716500716779386, 0.258728243040113, 0.000000000000000 },\n/*green:*/ { 0.101020574397477, 0.724682314948566, 0.051211818965388 },\n/*blue: */ { 0.146774385252705, 0.016589442011321, 0.773892783545073} },\n/* Fake encoding which selects just the green channel */\n/*gamma:*/ { 1.45/2.2, /* the 'Mac' gamma */\n/*red:  */ { 0.716500716779386, 0.000000000000000, 0.000000000000000 },\n/*green:*/ { 0.101020574397477, 1.000000000000000, 0.051211818965388 },\n/*blue: */ { 0.146774385252705, 0.000000000000000, 0.773892783545073} },\n};\n\n/* signal handler\n *\n * This attempts to trap signals and escape without crashing.  It needs a\n * context pointer so that it can throw an exception (call longjmp) to recover\n * from the condition; this is handled by making the png_modifier used by 'main'\n * into a global variable.\n */\nstatic png_modifier pm;\n\nstatic void signal_handler(int signum)\n{\n\n   size_t pos = 0;\n   char msg[64];\n\n   pos = safecat(msg, sizeof msg, pos, \"caught signal: \");\n\n   switch (signum)\n   {\n      case SIGABRT:\n         pos = safecat(msg, sizeof msg, pos, \"abort\");\n         break;\n\n      case SIGFPE:\n         pos = safecat(msg, sizeof msg, pos, \"floating point exception\");\n         break;\n\n      case SIGILL:\n         pos = safecat(msg, sizeof msg, pos, \"illegal instruction\");\n         break;\n\n      case SIGINT:\n         pos = safecat(msg, sizeof msg, pos, \"interrupt\");\n         break;\n\n      case SIGSEGV:\n         pos = safecat(msg, sizeof msg, pos, \"invalid memory access\");\n         break;\n\n      case SIGTERM:\n         pos = safecat(msg, sizeof msg, pos, \"termination request\");\n         break;\n\n      default:\n         pos = safecat(msg, sizeof msg, pos, \"unknown \");\n         pos = safecatn(msg, sizeof msg, pos, signum);\n         break;\n   }\n\n   store_log(&pm.this, NULL/*png_structp*/, msg, 1/*error*/);\n\n   /* And finally throw an exception so we can keep going, unless this is\n    * SIGTERM in which case stop now.\n    */\n   if (signum != SIGTERM)\n   {\n      struct exception_context *the_exception_context =\n         &pm.this.exception_context;\n\n      Throw &pm.this;\n   }\n\n   else\n      exit(1);\n}\n\n/* main program */\nint main(int argc, char **argv)\n{\n   int summary = 1;  /* Print the error summary at the end */\n   int memstats = 0; /* Print memory statistics at the end */\n\n   /* Create the given output file on success: */\n   const char *touch = NULL;\n\n   /* This is an array of standard gamma values (believe it or not I've seen\n    * every one of these mentioned somewhere.)\n    *\n    * In the following list the most useful values are first!\n    */\n   static double\n      gammas[]={2.2, 1.0, 2.2/1.45, 1.8, 1.5, 2.4, 2.5, 2.62, 2.9};\n\n   /* This records the command and arguments: */\n   size_t cp = 0;\n   char command[1024];\n\n   anon_context(&pm.this);\n\n   gnu_volatile(summary)\n   gnu_volatile(memstats)\n   gnu_volatile(touch)\n\n   /* Add appropriate signal handlers, just the ANSI specified ones: */\n   signal(SIGABRT, signal_handler);\n   signal(SIGFPE, signal_handler);\n   signal(SIGILL, signal_handler);\n   signal(SIGINT, signal_handler);\n   signal(SIGSEGV, signal_handler);\n   signal(SIGTERM, signal_handler);\n\n#ifdef HAVE_FEENABLEEXCEPT\n   /* Only required to enable FP exceptions on platforms where they start off\n    * disabled; this is not necessary but if it is not done pngvalid will likely\n    * end up ignoring FP conditions that other platforms fault.\n    */\n   feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);\n#endif\n\n   modifier_init(&pm);\n\n   /* Preallocate the image buffer, because we know how big it needs to be,\n    * note that, for testing purposes, it is deliberately mis-aligned by tag\n    * bytes either side.  All rows have an additional five bytes of padding for\n    * overwrite checking.\n    */\n   store_ensure_image(&pm.this, NULL, 2, TRANSFORM_ROWMAX, TRANSFORM_HEIGHTMAX);\n\n   /* Don't give argv[0], it's normally some horrible libtool string: */\n   cp = safecat(command, sizeof command, cp, \"pngvalid\");\n\n   /* Default to error on warning: */\n   pm.this.treat_warnings_as_errors = 1;\n\n   /* Default assume_16_bit_calculations appropriately; this tells the checking\n    * code that 16-bit arithmetic is used for 8-bit samples when it would make a\n    * difference.\n    */\n   pm.assume_16_bit_calculations = PNG_LIBPNG_VER >= 10700;\n\n   /* Currently 16 bit expansion happens at the end of the pipeline, so the\n    * calculations are done in the input bit depth not the output.\n    *\n    * TODO: fix this\n    */\n   pm.calculations_use_input_precision = 1U;\n\n   /* Store the test gammas */\n   pm.gammas = gammas;\n   pm.ngammas = ARRAY_SIZE(gammas);\n   pm.ngamma_tests = 0; /* default to off */\n\n   /* Low bit depth gray images don't do well in the gamma tests, until\n    * this is fixed turn them off for some gamma cases:\n    */\n#  ifdef PNG_WRITE_tRNS_SUPPORTED\n      pm.test_tRNS = 1;\n#  endif\n   pm.test_lbg = PNG_LIBPNG_VER >= 10600;\n   pm.test_lbg_gamma_threshold = 1;\n   pm.test_lbg_gamma_transform = PNG_LIBPNG_VER >= 10600;\n   pm.test_lbg_gamma_sbit = 1;\n   pm.test_lbg_gamma_composition = PNG_LIBPNG_VER >= 10700;\n\n   /* And the test encodings */\n   pm.encodings = test_encodings;\n   pm.nencodings = ARRAY_SIZE(test_encodings);\n\n#  if PNG_LIBPNG_VER < 10700\n      pm.sbitlow = 8U; /* because libpng doesn't do sBIT below 8! */\n#  else\n      pm.sbitlow = 1U;\n#  endif\n\n   /* The following allows results to pass if they correspond to anything in the\n    * transformed range [input-.5,input+.5]; this is is required because of the\n    * way libpng treates the 16_TO_8 flag when building the gamma tables in\n    * releases up to 1.6.0.\n    *\n    * TODO: review this\n    */\n   pm.use_input_precision_16to8 = 1U;\n   pm.use_input_precision_sbit = 1U; /* because libpng now rounds sBIT */\n\n   /* Some default values (set the behavior for 'make check' here).\n    * These values simply control the maximum error permitted in the gamma\n    * transformations.  The practial limits for human perception are described\n    * below (the setting for maxpc16), however for 8 bit encodings it isn't\n    * possible to meet the accepted capabilities of human vision - i.e. 8 bit\n    * images can never be good enough, regardless of encoding.\n    */\n   pm.maxout8 = .1;     /* Arithmetic error in *encoded* value */\n   pm.maxabs8 = .00005; /* 1/20000 */\n   pm.maxcalc8 = 1./255;  /* +/-1 in 8 bits for compose errors */\n   pm.maxpc8 = .499;    /* I.e., .499% fractional error */\n   pm.maxout16 = .499;  /* Error in *encoded* value */\n   pm.maxabs16 = .00005;/* 1/20000 */\n   pm.maxcalc16 =1./65535;/* +/-1 in 16 bits for compose errors */\n#  if PNG_LIBPNG_VER < 10700\n      pm.maxcalcG = 1./((1<<PNG_MAX_GAMMA_8)-1);\n#  else\n      pm.maxcalcG = 1./((1<<16)-1);\n#  endif\n\n   /* NOTE: this is a reasonable perceptual limit. We assume that humans can\n    * perceive light level differences of 1% over a 100:1 range, so we need to\n    * maintain 1 in 10000 accuracy (in linear light space), which is what the\n    * following guarantees.  It also allows significantly higher errors at\n    * higher 16 bit values, which is important for performance.  The actual\n    * maximum 16 bit error is about +/-1.9 in the fixed point implementation but\n    * this is only allowed for values >38149 by the following:\n    */\n   pm.maxpc16 = .005;   /* I.e., 1/200% - 1/20000 */\n\n   /* Now parse the command line options. */\n   while (--argc >= 1)\n   {\n      int catmore = 0; /* Set if the argument has an argument. */\n\n      /* Record each argument for posterity: */\n      cp = safecat(command, sizeof command, cp, \" \");\n      cp = safecat(command, sizeof command, cp, *++argv);\n\n      if (strcmp(*argv, \"-v\") == 0)\n         pm.this.verbose = 1;\n\n      else if (strcmp(*argv, \"-l\") == 0)\n         pm.log = 1;\n\n      else if (strcmp(*argv, \"-q\") == 0)\n         summary = pm.this.verbose = pm.log = 0;\n\n      else if (strcmp(*argv, \"-w\") == 0 ||\n               strcmp(*argv, \"--strict\") == 0)\n         pm.this.treat_warnings_as_errors = 1; /* NOTE: this is the default! */\n\n      else if (strcmp(*argv, \"--nostrict\") == 0)\n         pm.this.treat_warnings_as_errors = 0;\n\n      else if (strcmp(*argv, \"--speed\") == 0)\n         pm.this.speed = 1, pm.ngamma_tests = pm.ngammas, pm.test_standard = 0,\n            summary = 0;\n\n      else if (strcmp(*argv, \"--memory\") == 0)\n         memstats = 1;\n\n      else if (strcmp(*argv, \"--size\") == 0)\n         pm.test_size = 1;\n\n      else if (strcmp(*argv, \"--nosize\") == 0)\n         pm.test_size = 0;\n\n      else if (strcmp(*argv, \"--standard\") == 0)\n         pm.test_standard = 1;\n\n      else if (strcmp(*argv, \"--nostandard\") == 0)\n         pm.test_standard = 0;\n\n      else if (strcmp(*argv, \"--transform\") == 0)\n         pm.test_transform = 1;\n\n      else if (strcmp(*argv, \"--notransform\") == 0)\n         pm.test_transform = 0;\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\n      else if (strncmp(*argv, \"--transform-disable=\",\n         sizeof \"--transform-disable\") == 0)\n         {\n         pm.test_transform = 1;\n         transform_disable(*argv + sizeof \"--transform-disable\");\n         }\n\n      else if (strncmp(*argv, \"--transform-enable=\",\n         sizeof \"--transform-enable\") == 0)\n         {\n         pm.test_transform = 1;\n         transform_enable(*argv + sizeof \"--transform-enable\");\n         }\n#endif /* PNG_READ_TRANSFORMS_SUPPORTED */\n\n      else if (strcmp(*argv, \"--gamma\") == 0)\n         {\n         /* Just do two gamma tests here (2.2 and linear) for speed: */\n         pm.ngamma_tests = 2U;\n         pm.test_gamma_threshold = 1;\n         pm.test_gamma_transform = 1;\n         pm.test_gamma_sbit = 1;\n         pm.test_gamma_scale16 = 1;\n         pm.test_gamma_background = 1; /* composition */\n         pm.test_gamma_alpha_mode = 1;\n         }\n\n      else if (strcmp(*argv, \"--nogamma\") == 0)\n         pm.ngamma_tests = 0;\n\n      else if (strcmp(*argv, \"--gamma-threshold\") == 0)\n         pm.ngamma_tests = 2U, pm.test_gamma_threshold = 1;\n\n      else if (strcmp(*argv, \"--nogamma-threshold\") == 0)\n         pm.test_gamma_threshold = 0;\n\n      else if (strcmp(*argv, \"--gamma-transform\") == 0)\n         pm.ngamma_tests = 2U, pm.test_gamma_transform = 1;\n\n      else if (strcmp(*argv, \"--nogamma-transform\") == 0)\n         pm.test_gamma_transform = 0;\n\n      else if (strcmp(*argv, \"--gamma-sbit\") == 0)\n         pm.ngamma_tests = 2U, pm.test_gamma_sbit = 1;\n\n      else if (strcmp(*argv, \"--nogamma-sbit\") == 0)\n         pm.test_gamma_sbit = 0;\n\n      else if (strcmp(*argv, \"--gamma-16-to-8\") == 0)\n         pm.ngamma_tests = 2U, pm.test_gamma_scale16 = 1;\n\n      else if (strcmp(*argv, \"--nogamma-16-to-8\") == 0)\n         pm.test_gamma_scale16 = 0;\n\n      else if (strcmp(*argv, \"--gamma-background\") == 0)\n         pm.ngamma_tests = 2U, pm.test_gamma_background = 1;\n\n      else if (strcmp(*argv, \"--nogamma-background\") == 0)\n         pm.test_gamma_background = 0;\n\n      else if (strcmp(*argv, \"--gamma-alpha-mode\") == 0)\n         pm.ngamma_tests = 2U, pm.test_gamma_alpha_mode = 1;\n\n      else if (strcmp(*argv, \"--nogamma-alpha-mode\") == 0)\n         pm.test_gamma_alpha_mode = 0;\n\n      else if (strcmp(*argv, \"--expand16\") == 0)\n         pm.test_gamma_expand16 = 1;\n\n      else if (strcmp(*argv, \"--noexpand16\") == 0)\n         pm.test_gamma_expand16 = 0;\n\n      else if (strcmp(*argv, \"--low-depth-gray\") == 0)\n         pm.test_lbg = pm.test_lbg_gamma_threshold =\n            pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit =\n            pm.test_lbg_gamma_composition = 1;\n\n      else if (strcmp(*argv, \"--nolow-depth-gray\") == 0)\n         pm.test_lbg = pm.test_lbg_gamma_threshold =\n            pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit =\n            pm.test_lbg_gamma_composition = 0;\n\n#     ifdef PNG_WRITE_tRNS_SUPPORTED\n         else if (strcmp(*argv, \"--tRNS\") == 0)\n            pm.test_tRNS = 1;\n#     endif\n\n      else if (strcmp(*argv, \"--notRNS\") == 0)\n         pm.test_tRNS = 0;\n\n      else if (strcmp(*argv, \"--more-gammas\") == 0)\n         pm.ngamma_tests = 3U;\n\n      else if (strcmp(*argv, \"--all-gammas\") == 0)\n         pm.ngamma_tests = pm.ngammas;\n\n      else if (strcmp(*argv, \"--progressive-read\") == 0)\n         pm.this.progressive = 1;\n\n      else if (strcmp(*argv, \"--use-update-info\") == 0)\n         ++pm.use_update_info; /* Can call multiple times */\n\n      else if (strcmp(*argv, \"--interlace\") == 0)\n      {\n#        if CAN_WRITE_INTERLACE\n            pm.interlace_type = PNG_INTERLACE_ADAM7;\n#        else /* !CAN_WRITE_INTERLACE */\n            fprintf(stderr, \"pngvalid: no write interlace support\\n\");\n            return SKIP;\n#        endif /* !CAN_WRITE_INTERLACE */\n      }\n\n      else if (strcmp(*argv, \"--use-input-precision\") == 0)\n         pm.use_input_precision = 1U;\n\n      else if (strcmp(*argv, \"--use-calculation-precision\") == 0)\n         pm.use_input_precision = 0;\n\n      else if (strcmp(*argv, \"--calculations-use-input-precision\") == 0)\n         pm.calculations_use_input_precision = 1U;\n\n      else if (strcmp(*argv, \"--assume-16-bit-calculations\") == 0)\n         pm.assume_16_bit_calculations = 1U;\n\n      else if (strcmp(*argv, \"--calculations-follow-bit-depth\") == 0)\n         pm.calculations_use_input_precision =\n            pm.assume_16_bit_calculations = 0;\n\n      else if (strcmp(*argv, \"--exhaustive\") == 0)\n         pm.test_exhaustive = 1;\n\n      else if (argc > 1 && strcmp(*argv, \"--sbitlow\") == 0)\n         --argc, pm.sbitlow = (png_byte)atoi(*++argv), catmore = 1;\n\n      else if (argc > 1 && strcmp(*argv, \"--touch\") == 0)\n         --argc, touch = *++argv, catmore = 1;\n\n      else if (argc > 1 && strncmp(*argv, \"--max\", 5) == 0)\n      {\n         --argc;\n\n         if (strcmp(5+*argv, \"abs8\") == 0)\n            pm.maxabs8 = atof(*++argv);\n\n         else if (strcmp(5+*argv, \"abs16\") == 0)\n            pm.maxabs16 = atof(*++argv);\n\n         else if (strcmp(5+*argv, \"calc8\") == 0)\n            pm.maxcalc8 = atof(*++argv);\n\n         else if (strcmp(5+*argv, \"calc16\") == 0)\n            pm.maxcalc16 = atof(*++argv);\n\n         else if (strcmp(5+*argv, \"out8\") == 0)\n            pm.maxout8 = atof(*++argv);\n\n         else if (strcmp(5+*argv, \"out16\") == 0)\n            pm.maxout16 = atof(*++argv);\n\n         else if (strcmp(5+*argv, \"pc8\") == 0)\n            pm.maxpc8 = atof(*++argv);\n\n         else if (strcmp(5+*argv, \"pc16\") == 0)\n            pm.maxpc16 = atof(*++argv);\n\n         else\n         {\n            fprintf(stderr, \"pngvalid: %s: unknown 'max' option\\n\", *argv);\n            exit(99);\n         }\n\n         catmore = 1;\n      }\n\n      else if (strcmp(*argv, \"--log8\") == 0)\n         --argc, pm.log8 = atof(*++argv), catmore = 1;\n\n      else if (strcmp(*argv, \"--log16\") == 0)\n         --argc, pm.log16 = atof(*++argv), catmore = 1;\n\n#ifdef PNG_SET_OPTION_SUPPORTED\n      else if (strncmp(*argv, \"--option=\", 9) == 0)\n      {\n         /* Syntax of the argument is <option>:{on|off} */\n         const char *arg = 9+*argv;\n         unsigned char option=0, setting=0;\n\n#ifdef PNG_ARM_NEON\n         if (strncmp(arg, \"arm-neon:\", 9) == 0)\n            option = PNG_ARM_NEON, arg += 9;\n\n         else\n#endif\n#ifdef PNG_EXTENSIONS\n         if (strncmp(arg, \"extensions:\", 11) == 0)\n            option = PNG_EXTENSIONS, arg += 11;\n\n         else\n#endif\n#ifdef PNG_MAXIMUM_INFLATE_WINDOW\n         if (strncmp(arg, \"max-inflate-window:\", 19) == 0)\n            option = PNG_MAXIMUM_INFLATE_WINDOW, arg += 19;\n\n         else\n#endif\n         {\n            fprintf(stderr, \"pngvalid: %s: %s: unknown option\\n\", *argv, arg);\n            exit(99);\n         }\n\n         if (strcmp(arg, \"off\") == 0)\n            setting = PNG_OPTION_OFF;\n\n         else if (strcmp(arg, \"on\") == 0)\n            setting = PNG_OPTION_ON;\n\n         else\n         {\n            fprintf(stderr,\n               \"pngvalid: %s: %s: unknown setting (use 'on' or 'off')\\n\",\n               *argv, arg);\n            exit(99);\n         }\n\n         pm.this.options[pm.this.noptions].option = option;\n         pm.this.options[pm.this.noptions++].setting = setting;\n      }\n#endif /* PNG_SET_OPTION_SUPPORTED */\n\n      else\n      {\n         fprintf(stderr, \"pngvalid: %s: unknown argument\\n\", *argv);\n         exit(99);\n      }\n\n      if (catmore) /* consumed an extra *argv */\n      {\n         cp = safecat(command, sizeof command, cp, \" \");\n         cp = safecat(command, sizeof command, cp, *argv);\n      }\n   }\n\n   /* If pngvalid is run with no arguments default to a reasonable set of the\n    * tests.\n    */\n   if (pm.test_standard == 0 && pm.test_size == 0 && pm.test_transform == 0 &&\n      pm.ngamma_tests == 0)\n   {\n      /* Make this do all the tests done in the test shell scripts with the same\n       * parameters, where possible.  The limitation is that all the progressive\n       * read and interlace stuff has to be done in separate runs, so only the\n       * basic 'standard' and 'size' tests are done.\n       */\n      pm.test_standard = 1;\n      pm.test_size = 1;\n      pm.test_transform = 1;\n      pm.ngamma_tests = 2U;\n   }\n\n   if (pm.ngamma_tests > 0 &&\n      pm.test_gamma_threshold == 0 && pm.test_gamma_transform == 0 &&\n      pm.test_gamma_sbit == 0 && pm.test_gamma_scale16 == 0 &&\n      pm.test_gamma_background == 0 && pm.test_gamma_alpha_mode == 0)\n   {\n      pm.test_gamma_threshold = 1;\n      pm.test_gamma_transform = 1;\n      pm.test_gamma_sbit = 1;\n      pm.test_gamma_scale16 = 1;\n      pm.test_gamma_background = 1;\n      pm.test_gamma_alpha_mode = 1;\n   }\n\n   else if (pm.ngamma_tests == 0)\n   {\n      /* Nothing to test so turn everything off: */\n      pm.test_gamma_threshold = 0;\n      pm.test_gamma_transform = 0;\n      pm.test_gamma_sbit = 0;\n      pm.test_gamma_scale16 = 0;\n      pm.test_gamma_background = 0;\n      pm.test_gamma_alpha_mode = 0;\n   }\n\n   Try\n   {\n      /* Make useful base images */\n      make_transform_images(&pm);\n\n      /* Perform the standard and gamma tests. */\n      if (pm.test_standard)\n      {\n         perform_interlace_macro_validation();\n         perform_formatting_test(&pm.this);\n#        ifdef PNG_READ_SUPPORTED\n            perform_standard_test(&pm);\n#        endif\n         perform_error_test(&pm);\n      }\n\n      /* Various oddly sized images: */\n      if (pm.test_size)\n      {\n         make_size_images(&pm.this);\n#        ifdef PNG_READ_SUPPORTED\n            perform_size_test(&pm);\n#        endif\n      }\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\n      /* Combinatorial transforms: */\n      if (pm.test_transform)\n         perform_transform_test(&pm);\n#endif /* PNG_READ_TRANSFORMS_SUPPORTED */\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\n      if (pm.ngamma_tests > 0)\n         perform_gamma_test(&pm, summary);\n#endif\n   }\n\n   Catch_anonymous\n   {\n      fprintf(stderr, \"pngvalid: test aborted (probably failed in cleanup)\\n\");\n      if (!pm.this.verbose)\n      {\n         if (pm.this.error[0] != 0)\n            fprintf(stderr, \"pngvalid: first error: %s\\n\", pm.this.error);\n\n         fprintf(stderr, \"pngvalid: run with -v to see what happened\\n\");\n      }\n      exit(1);\n   }\n\n   if (summary)\n   {\n      printf(\"%s: %s (%s point arithmetic)\\n\",\n         (pm.this.nerrors || (pm.this.treat_warnings_as_errors &&\n            pm.this.nwarnings)) ? \"FAIL\" : \"PASS\",\n         command,\n#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || PNG_LIBPNG_VER < 10500\n         \"floating\"\n#else\n         \"fixed\"\n#endif\n         );\n   }\n\n   if (memstats)\n   {\n      printf(\"Allocated memory statistics (in bytes):\\n\"\n         \"\\tread  %lu maximum single, %lu peak, %lu total\\n\"\n         \"\\twrite %lu maximum single, %lu peak, %lu total\\n\",\n         (unsigned long)pm.this.read_memory_pool.max_max,\n         (unsigned long)pm.this.read_memory_pool.max_limit,\n         (unsigned long)pm.this.read_memory_pool.max_total,\n         (unsigned long)pm.this.write_memory_pool.max_max,\n         (unsigned long)pm.this.write_memory_pool.max_limit,\n         (unsigned long)pm.this.write_memory_pool.max_total);\n   }\n\n   /* Do this here to provoke memory corruption errors in memory not directly\n    * allocated by libpng - not a complete test, but better than nothing.\n    */\n   store_delete(&pm.this);\n\n   /* Error exit if there are any errors, and maybe if there are any\n    * warnings.\n    */\n   if (pm.this.nerrors || (pm.this.treat_warnings_as_errors &&\n       pm.this.nwarnings))\n   {\n      if (!pm.this.verbose)\n         fprintf(stderr, \"pngvalid: %s\\n\", pm.this.error);\n\n      fprintf(stderr, \"pngvalid: %d errors, %d warnings\\n\", pm.this.nerrors,\n          pm.this.nwarnings);\n\n      exit(1);\n   }\n\n   /* Success case. */\n   if (touch != NULL)\n   {\n      FILE *fsuccess = fopen(touch, \"wt\");\n\n      if (fsuccess != NULL)\n      {\n         int error = 0;\n         fprintf(fsuccess, \"PNG validation succeeded\\n\");\n         fflush(fsuccess);\n         error = ferror(fsuccess);\n\n         if (fclose(fsuccess) || error)\n         {\n            fprintf(stderr, \"%s: write failed\\n\", touch);\n            exit(1);\n         }\n      }\n\n      else\n      {\n         fprintf(stderr, \"%s: open failed\\n\", touch);\n         exit(1);\n      }\n   }\n\n   /* This is required because some very minimal configurations do not use it:\n    */\n   UNUSED(fail)\n   return 0;\n}\n#else /* write or low level APIs not supported */\nint main(void)\n{\n   fprintf(stderr,\n      \"pngvalid: no low level write support in libpng, all tests skipped\\n\");\n   /* So the test is skipped: */\n   return SKIP;\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/libtests/readpng.c",
    "content": "/* readpng.c\n *\n * Copyright (c) 2013 John Cunningham Bowler\n *\n * Last changed in libpng 1.6.1 [March 28, 2013]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * Load an arbitrary number of PNG files (from the command line, or, if there\n * are no arguments on the command line, from stdin) then run a time test by\n * reading each file by row.  The test does nothing with the read result and\n * does no transforms.  The only output is a time as a floating point number of\n * seconds with 9 decimal digits.\n */\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n\n#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)\n#  include <config.h>\n#endif\n\n/* Define the following to use this test against your installed libpng, rather\n * than the one being built here:\n */\n#ifdef PNG_FREESTANDING_TESTS\n#  include <png.h>\n#else\n#  include \"../../png.h\"\n#endif\n\nstatic int\nread_png(FILE *fp)\n{\n   png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);\n   png_infop info_ptr = NULL;\n   png_bytep row = NULL, display = NULL;\n\n   if (png_ptr == NULL)\n      return 0;\n\n   if (setjmp(png_jmpbuf(png_ptr)))\n   {\n      png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n      if (row != NULL) free(row);\n      if (display != NULL) free(display);\n      return 0;\n   }\n\n   png_init_io(png_ptr, fp);\n\n   info_ptr = png_create_info_struct(png_ptr);\n   if (info_ptr == NULL)\n      png_error(png_ptr, \"OOM allocating info structure\");\n\n   png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, NULL, 0);\n\n   png_read_info(png_ptr, info_ptr);\n\n   {\n      png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);\n\n      /* Failure to initialize these is harmless */\n      row = malloc(rowbytes);\n      display = malloc(rowbytes);\n\n      if (row == NULL || display == NULL)\n         png_error(png_ptr, \"OOM allocating row buffers\");\n\n      {\n         png_uint_32 height = png_get_image_height(png_ptr, info_ptr);\n#        ifdef PNG_READ_INTERLACING_SUPPORTED\n            int passes = png_set_interlace_handling(png_ptr);\n#        else /* !READ_INTERLACING */\n            int passes = png_get_interlace_type(png_ptr, info_ptr) ==\n               PNG_INTERLACE_ADAM7 ? PNG_INTERLACE_ADAM7_PASSES : 1;\n#        endif /* !READ_INTERLACING */\n         int pass;\n\n         png_start_read_image(png_ptr);\n\n         for (pass = 0; pass < passes; ++pass)\n         {\n            png_uint_32 y = height;\n\n#           ifndef PNG_READ_INTERLACING_SUPPORTED\n               if (passes == PNG_INTERLACE_ADAM7_PASSES)\n                  y = PNG_PASS_ROWS(y, pass);\n#           endif /* READ_INTERLACING */\n\n            /* NOTE: this trashes the row each time; interlace handling won't\n             * work, but this avoids memory thrashing for speed testing.\n             */\n            while (y-- > 0)\n               png_read_row(png_ptr, row, display);\n         }\n      }\n   }\n\n   /* Make sure to read to the end of the file: */\n   png_read_end(png_ptr, info_ptr);\n   png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n   free(row);\n   free(display);\n   return 1;\n}\n\nint\nmain(void)\n{\n   /* Exit code 0 on success. */\n   return !read_png(stdin);\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/libtests/tarith.c",
    "content": "\n/* tarith.c\n *\n * Copyright (c) 2011-2013 John Cunningham Bowler\n *\n * Last changed in libpng 1.6.0 [February 14, 2013]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * Test internal arithmetic functions of libpng.\n *\n * This code must be linked against a math library (-lm), but does not require\n * libpng or zlib to work.  Because it includes the complete source of 'png.c'\n * it tests the code with whatever compiler options are used to build it.\n * Changing these options can substantially change the errors in the\n * calculations that the compiler chooses!\n */\n#define _POSIX_SOURCE 1\n#define _ISOC99_SOURCE 1\n\n/* Obtain a copy of the code to be tested (plus other things), disabling\n * stuff that is not required.\n */\n#include <math.h>\n#include <stdlib.h>\n#include <ctype.h>\n#include <string.h>\n#include <assert.h>\n\n#include \"../../pngpriv.h\"\n\n#define png_error png_warning\n\nvoid png_warning(png_const_structrp png_ptr, png_const_charp msg)\n{\n   fprintf(stderr, \"validation: %s\\n\", msg);\n}\n\n#define png_fixed_error png_fixed_warning\n\nvoid png_fixed_warning(png_const_structrp png_ptr, png_const_charp msg)\n{\n   fprintf(stderr, \"overflow in: %s\\n\", msg);\n}\n\n#define png_set_error_fn(pp, ep, efp, wfp) ((void)0)\n#define png_malloc(pp, s) malloc(s)\n#define png_malloc_warn(pp, s) malloc(s)\n#define png_malloc_base(pp, s) malloc(s)\n#define png_calloc(pp, s) calloc(1, (s))\n#define png_free(pp, s) free(s)\n\n#define png_safecat(b, sb, pos, str) (pos)\n#define png_format_number(start, end, format, number) (start)\n\n#define crc32(crc, pp, s) (crc)\n#define inflateReset(zs) Z_OK\n\n#define png_create_struct(type) (0)\n#define png_destroy_struct(pp) ((void)0)\n#define png_create_struct_2(type, m, mm) (0)\n#define png_destroy_struct_2(pp, f, mm) ((void)0)\n\n#undef PNG_SIMPLIFIED_READ_SUPPORTED\n#undef PNG_SIMPLIFIED_WRITE_SUPPORTED\n#undef PNG_USER_MEM_SUPPORTED\n\n#include \"../../png.c\"\n\n/* Validate ASCII to fp routines. */\nstatic int verbose = 0;\n\nint validation_ascii_to_fp(int count, int argc, char **argv)\n{\n   int    showall = 0;\n   double max_error=2;      /* As a percentage error-in-last-digit/.5 */\n   double max_error_abs=17; /* Used when precision is DBL_DIG */\n   double max = 0;\n   double max_abs = 0;\n   double test = 0; /* Important to test this. */\n   int    precision = 5;\n   int    nonfinite = 0;\n   int    finite = 0;\n   int    ok = 0;\n   int    failcount = 0;\n   int    minorarith = 0;\n\n   while (--argc > 0)\n      if (strcmp(*++argv, \"-a\") == 0)\n         showall = 1;\n      else if (strcmp(*argv, \"-e\") == 0 && argc > 0)\n      {\n         --argc;\n         max_error = atof(*++argv);\n      }\n      else if (strcmp(*argv, \"-E\") == 0 && argc > 0)\n      {\n         --argc;\n         max_error_abs = atof(*++argv);\n      }\n      else\n      {\n         fprintf(stderr, \"unknown argument %s\\n\", *argv);\n         return 1;\n      }\n\n   do\n   {\n      png_size_t index;\n      int state, failed = 0;\n      char buffer[64];\n\n      if (isfinite(test))\n         ++finite;\n      else\n         ++nonfinite;\n\n      if (verbose)\n         fprintf(stderr, \"%.*g %d\\n\", DBL_DIG, test, precision);\n\n      /* Check for overflow in the buffer by setting a marker. */\n      memset(buffer, 71, sizeof buffer);\n\n      png_ascii_from_fp(0, buffer, precision+10, test, precision);\n\n      /* Allow for a three digit exponent, this stuff will fail if\n       * the exponent is bigger than this!\n       */\n      if (buffer[precision+7] != 71)\n      {\n         fprintf(stderr, \"%g[%d] -> '%s'[%lu] buffer overflow\\n\", test,\n            precision, buffer, (unsigned long)strlen(buffer));\n         failed = 1;\n      }\n\n      /* Following are used for the number parser below and must be\n       * initialized to zero.\n       */\n      state = 0;\n      index = 0;\n      if (!isfinite(test))\n      {\n         /* Expect 'inf' */\n         if (test >= 0 && strcmp(buffer, \"inf\") ||\n             test <  0 && strcmp(buffer, \"-inf\"))\n         {\n            fprintf(stderr, \"%g[%d] -> '%s' but expected 'inf'\\n\", test,\n               precision, buffer);\n            failed = 1;\n         }\n      }\n      else if (!png_check_fp_number(buffer, precision+10, &state, &index) ||\n          buffer[index] != 0)\n      {\n         fprintf(stderr, \"%g[%d] -> '%s' but has bad format ('%c')\\n\", test,\n         precision, buffer, buffer[index]);\n         failed = 1;\n      }\n      else if (PNG_FP_IS_NEGATIVE(state) && !(test < 0))\n      {\n         fprintf(stderr, \"%g[%d] -> '%s' but negative value not so reported\\n\",\n            test, precision, buffer);\n         failed = 1;\n         assert(!PNG_FP_IS_ZERO(state));\n         assert(!PNG_FP_IS_POSITIVE(state));\n      }\n      else if (PNG_FP_IS_ZERO(state) && !(test == 0))\n      {\n         fprintf(stderr, \"%g[%d] -> '%s' but zero value not so reported\\n\",\n            test, precision, buffer);\n         failed = 1;\n         assert(!PNG_FP_IS_NEGATIVE(state));\n         assert(!PNG_FP_IS_POSITIVE(state));\n      }\n      else if (PNG_FP_IS_POSITIVE(state) && !(test > 0))\n      {\n         fprintf(stderr, \"%g[%d] -> '%s' but postive value not so reported\\n\",\n            test, precision, buffer);\n         failed = 1;\n         assert(!PNG_FP_IS_NEGATIVE(state));\n         assert(!PNG_FP_IS_ZERO(state));\n      }\n      else\n      {\n         /* Check the result against the original. */\n         double out = atof(buffer);\n         double change = fabs((out - test)/test);\n         double allow = .5/pow(10,\n            (precision >= DBL_DIG) ? DBL_DIG-1 : precision-1);\n\n         /* NOTE: if you hit this error case are you compiling with gcc\n          * and -O0?  Try -O2 - the errors can accumulate if the FP\n          * code above is not optimized and may drift outside the .5 in\n          * DBL_DIG allowed.  In any case a small number of errors may\n          * occur (very small ones - 1 or 2%) because of rounding in the\n          * calculations, either in the conversion API or in atof.\n          */\n         if (change >= allow && (isfinite(out) ||\n             fabs(test/DBL_MAX) <= 1-allow))\n         {\n            double percent = (precision >= DBL_DIG) ? max_error_abs : max_error;\n            double allowp = (change-allow)*100/allow;\n\n            if (precision >= DBL_DIG)\n            {\n               if (max_abs < allowp) max_abs = allowp;\n            }\n\n            else\n            {\n               if (max < allowp) max = allowp;\n            }\n\n            if (showall || allowp >= percent)\n            {\n               fprintf(stderr,\n                  \"%.*g[%d] -> '%s' -> %.*g number changed (%g > %g (%d%%))\\n\",\n                  DBL_DIG, test, precision, buffer, DBL_DIG, out, change, allow,\n                  (int)round(allowp));\n               failed = 1;\n            }\n            else\n               ++minorarith;\n         }\n      }\n\n      if (failed)\n         ++failcount;\n      else\n         ++ok;\n\nskip:\n      /* Generate a new number and precision. */\n      precision = rand();\n      if (precision & 1) test = -test;\n      precision >>= 1;\n\n      /* Generate random numbers. */\n      if (test == 0 || !isfinite(test))\n         test = precision+1;\n      else\n      {\n         /* Derive the exponent from the previous rand() value. */\n         int exponent = precision % (DBL_MAX_EXP - DBL_MIN_EXP) + DBL_MIN_EXP;\n         int tmp;\n         test = frexp(test * rand(), &tmp);\n         test = ldexp(test, exponent);\n         precision >>= 8; /* arbitrary */\n      }\n\n      /* This limits the precision to 32 digits, enough for standard\n       * IEEE implementations which have at most 15 digits.\n       */\n      precision = (precision & 0x1f) + 1;\n   }\n   while (--count);\n\n   printf(\"Tested %d finite values, %d non-finite, %d OK (%d failed) %d minor \"\n      \"arithmetic errors\\n\", finite, nonfinite, ok, failcount, minorarith);\n   printf(\" Error with >=%d digit precision %.2f%%\\n\", DBL_DIG, max_abs);\n   printf(\" Error with < %d digit precision %.2f%%\\n\", DBL_DIG, max);\n\n   return 0;\n}\n\n/* Observe that valid FP numbers have the forms listed in the PNG extensions\n * specification:\n *\n * [+,-]{integer,integer.fraction,.fraction}[{e,E}[+,-]integer]\n *\n * Test each of these in turn, including invalid cases.\n */\ntypedef enum checkfp_state\n{\n   start, fraction, exponent, states\n} checkfp_state;\n\n/* The characters (other than digits) that characterize the states: */\nstatic const char none[] = \"\";\nstatic const char hexdigits[16] = \"0123456789ABCDEF\";\n\nstatic const struct\n{\n   const char *start; /* Characters valid at the start */\n   const char *end;   /* Valid characters that end the state */\n   const char *tests; /* Characters to test after 2 digits seen */\n}\nstate_characters[states] =\n{\n   /* start:    */ { \"+-.\", \".eE\", \"+-.e*0369\" },\n   /* fraction: */ { none, \"eE\",  \"+-.E#0147\" },\n   /* exponent: */ { \"+-\", none,  \"+-.eE^0258\" }\n};\n\ntypedef struct\n{\n   char number[1024];  /* Buffer for number being tested */\n   int  limit;         /* Command line limit */\n   int  verbose;       /* Shadows global variable */\n   int  ctimes;        /* Number of numbers tested */\n   int  cmillions;     /* Count of millions of numbers */\n   int  cinvalid;      /* Invalid strings checked */\n   int  cnoaccept;     /* Characters not accepted */\n}\ncheckfp_command;\n\ntypedef struct\n{\n   int           cnumber;          /* Index into number string */\n   checkfp_state check_state;      /* Current number state */\n   int           at_start;         /* At start (first character) of state */\n   int           cdigits_in_state; /* Digits seen in that state */\n   int           limit;            /* Limit on same for checking all chars */\n   int           state;            /* Current parser state */\n   int           is_negative;      /* Number is negative */\n   int           is_zero;          /* Number is (still) zero */\n   int           number_was_valid; /* Previous character validity */\n}\ncheckfp_control;\n\nstatic int check_all_characters(checkfp_command *co, checkfp_control c);\n\nstatic int check_some_characters(checkfp_command *co, checkfp_control c,\n   const char *tests);\n\nstatic int check_one_character(checkfp_command *co, checkfp_control c, int ch)\n{\n   /* Test this character (ch) to ensure the parser does the correct thing.\n    */\n   png_size_t index = 0;\n   const char test = (char)ch;\n   const int number_is_valid = png_check_fp_number(&test, 1, &c.state, &index);\n   const int character_accepted = (index == 1);\n\n   if (c.check_state != exponent && isdigit(ch) && ch != '0')\n      c.is_zero = 0;\n\n   if (c.check_state == start && c.at_start && ch == '-')\n      c.is_negative = 1;\n\n   if (isprint(ch))\n      co->number[c.cnumber++] = (char)ch;\n   else\n   {\n      co->number[c.cnumber++] = '<';\n      co->number[c.cnumber++] = hexdigits[(ch >> 4) & 0xf];\n      co->number[c.cnumber++] = hexdigits[ch & 0xf];\n      co->number[c.cnumber++] = '>';\n   }\n   co->number[c.cnumber] = 0;\n\n   if (co->verbose > 1)\n      fprintf(stderr, \"%s\\n\", co->number);\n\n   if (++(co->ctimes) == 1000000)\n   {\n      if (co->verbose == 1)\n         fputc('.', stderr);\n      co->ctimes = 0;\n      ++(co->cmillions);\n   }\n\n   if (!number_is_valid)\n      ++(co->cinvalid);\n\n   if (!character_accepted)\n      ++(co->cnoaccept);\n\n   /* This should never fail (it's a serious bug if it does): */\n   if (index != 0 && index != 1)\n   {\n      fprintf(stderr, \"%s: read beyond end of string (%lu)\\n\", co->number,\n         (unsigned long)index);\n      return 0;\n   }\n\n   /* Validate the new state, note that the PNG_FP_IS_ macros all return\n    * false unless the number is valid.\n    */\n   if (PNG_FP_IS_NEGATIVE(c.state) !=\n      (number_is_valid && !c.is_zero && c.is_negative))\n   {\n      fprintf(stderr, \"%s: negative when it is not\\n\", co->number);\n      return 0;\n   }\n\n   if (PNG_FP_IS_ZERO(c.state) != (number_is_valid && c.is_zero))\n   {\n      fprintf(stderr, \"%s: zero when it is not\\n\", co->number);\n      return 0;\n   }\n\n   if (PNG_FP_IS_POSITIVE(c.state) !=\n      (number_is_valid && !c.is_zero && !c.is_negative))\n   {\n      fprintf(stderr, \"%s: positive when it is not\\n\", co->number);\n      return 0;\n   }\n\n   /* Testing a digit */\n   if (isdigit(ch))\n   {\n      if (!character_accepted)\n      {\n         fprintf(stderr, \"%s: digit '%c' not accepted\\n\", co->number, ch);\n         return 0;\n      }\n\n      if (!number_is_valid)\n      {\n         fprintf(stderr, \"%s: saw a digit (%c) but number not valid\\n\",\n            co->number, ch);\n         return 0;\n      }\n\n      ++c.cdigits_in_state;\n      c.at_start = 0;\n      c.number_was_valid = 1;\n\n      /* Continue testing characters in this state.  Either test all of\n       * them or, if we have already seen one digit in this state, just test a\n       * limited set.\n       */\n      if (c.cdigits_in_state < 1)\n         return check_all_characters(co, c);\n\n      else\n         return check_some_characters(co, c,\n            state_characters[c.check_state].tests);\n   }\n\n   /* A non-digit; is it allowed here? */\n   else if (((ch == '+' || ch == '-') && c.check_state != fraction &&\n               c.at_start) ||\n            (ch == '.' && c.check_state == start) ||\n            ((ch == 'e' || ch == 'E') && c.number_was_valid &&\n               c.check_state != exponent))\n   {\n      if (!character_accepted)\n      {\n         fprintf(stderr, \"%s: character '%c' not accepted\\n\", co->number, ch);\n         return 0;\n      }\n\n      /* The number remains valid after start of fraction but nowhere else. */\n      if (number_is_valid && (c.check_state != start || ch != '.'))\n      {\n         fprintf(stderr, \"%s: saw a non-digit (%c) but number valid\\n\",\n            co->number, ch);\n         return 0;\n      }\n\n      c.number_was_valid = number_is_valid;\n\n      /* Check for a state change.  When changing to 'fraction' if the number\n       * is valid at this point set the at_start to false to allow an exponent\n       * 'e' to come next.\n       */\n      if (c.check_state == start && ch == '.')\n      {\n         c.check_state = fraction;\n         c.at_start = !number_is_valid;\n         c.cdigits_in_state = 0;\n         c.limit = co->limit;\n         return check_all_characters(co, c);\n      }\n\n      else if (c.check_state < exponent && (ch == 'e' || ch == 'E'))\n      {\n         c.check_state = exponent;\n         c.at_start = 1;\n         c.cdigits_in_state = 0;\n         c.limit = co->limit;\n         return check_all_characters(co, c);\n      }\n\n      /* Else it was a sign, and the state doesn't change. */\n      else\n      {\n         if (ch != '-' && ch != '+')\n         {\n            fprintf(stderr, \"checkfp: internal error (1)\\n\");\n            return 0;\n         }\n\n         c.at_start = 0;\n         return check_all_characters(co, c);\n      }\n   }\n\n   /* Testing an invalid character */\n   else\n   {\n      if (character_accepted)\n      {\n         fprintf(stderr, \"%s: character '%c' [0x%.2x] accepted\\n\", co->number,\n            ch, ch);\n         return 0;\n      }\n\n      if (number_is_valid != c.number_was_valid)\n      {\n         fprintf(stderr,\n            \"%s: character '%c' [0x%.2x] changed number validity\\n\", co->number,\n            ch, ch);\n         return 0;\n      }\n\n      /* Do nothing - the parser has stuck; return success and keep going with\n       * the next character.\n       */\n   }\n\n   /* Successful return (the caller will try the next character.) */\n   return 1;\n}\n\nstatic int check_all_characters(checkfp_command *co, checkfp_control c)\n{\n   int ch;\n\n   if (c.cnumber+4 < sizeof co->number) for (ch=0; ch<256; ++ch)\n   {\n      if (!check_one_character(co, c, ch))\n         return 0;\n   }\n\n   return 1;\n}\n\nstatic int check_some_characters(checkfp_command *co, checkfp_control c,\n   const char *tests)\n{\n   int i;\n\n   --(c.limit);\n\n   if (c.cnumber+4 < sizeof co->number && c.limit >= 0)\n   {\n      if (c.limit > 0) for (i=0; tests[i]; ++i)\n      {\n         if (!check_one_character(co, c, tests[i]))\n               return 0;\n      }\n\n      /* At the end check all the characters. */\n      else\n         return check_all_characters(co, c);\n   }\n\n   return 1;\n}\n\nint validation_checkfp(int count, int argc, char **argv)\n{\n   int result;\n   checkfp_command command;\n   checkfp_control control;\n\n   command.number[0] = 0;\n   command.limit = 3;\n   command.verbose = verbose;\n   command.ctimes = 0;\n   command.cmillions = 0;\n   command.cinvalid = 0;\n   command.cnoaccept = 0;\n\n   while (--argc > 0)\n   {\n      ++argv;\n      if (argc > 1 && strcmp(*argv, \"-l\") == 0)\n      {\n         --argc;\n         command.limit = atoi(*++argv);\n      }\n\n      else\n      {\n         fprintf(stderr, \"unknown argument %s\\n\", *argv);\n         return 1;\n      }\n   }\n\n   control.cnumber = 0;\n   control.check_state = start;\n   control.at_start = 1;\n   control.cdigits_in_state = 0;\n   control.limit = command.limit;\n   control.state = 0;\n   control.is_negative = 0;\n   control.is_zero = 1;\n   control.number_was_valid = 0;\n\n   result = check_all_characters(&command, control);\n\n   printf(\"checkfp: %s: checked %d,%.3d,%.3d,%.3d strings (%d invalid)\\n\",\n      result ? \"pass\" : \"FAIL\", command.cmillions / 1000,\n      command.cmillions % 1000, command.ctimes / 1000, command.ctimes % 1000,\n      command.cinvalid);\n\n   return result;\n}\n\nint validation_muldiv(int count, int argc, char **argv)\n{\n   int tested = 0;\n   int overflow = 0;\n   int error = 0;\n   int error64 = 0;\n   int passed = 0;\n   int randbits = 0;\n   png_uint_32 randbuffer;\n   png_fixed_point a;\n   png_int_32 times, div;\n\n   while (--argc > 0)\n      {\n         fprintf(stderr, \"unknown argument %s\\n\", *++argv);\n         return 1;\n      }\n\n   /* Find out about the random number generator. */\n   randbuffer = RAND_MAX;\n   while (randbuffer != 0) ++randbits, randbuffer >>= 1;\n   printf(\"Using random number generator that makes %d bits\\n\", randbits);\n   for (div=0; div<32; div += randbits)\n      randbuffer = (randbuffer << randbits) ^ rand();\n\n   a = 0;\n   times = div = 0;\n   do\n   {\n      png_fixed_point result;\n      /* NOTE: your mileage may vary, a type is required below that can\n       * hold 64 bits or more, if floating point is used a 64-bit or\n       * better mantissa is required.\n       */\n      long long int fp, fpround;\n      unsigned long hi, lo;\n      int ok;\n\n      /* Check the values, png_64bit_product can only handle positive\n       * numbers, so correct for that here.\n       */\n      {\n         long u1, u2;\n         int n = 0;\n         if (a < 0) u1 = -a, n = 1; else u1 = a;\n         if (times < 0) u2 = -times, n = !n; else u2 = times;\n         png_64bit_product(u1, u2, &hi, &lo);\n         if (n)\n         {\n            /* -x = ~x+1 */\n            lo = ((~lo) + 1) & 0xffffffff;\n            hi = ~hi;\n            if (lo == 0) ++hi;\n         }\n      }\n\n      fp = a;\n      fp *= times;\n      if ((fp & 0xffffffff) != lo || ((fp >> 32) & 0xffffffff) != hi)\n      {\n         fprintf(stderr, \"png_64bit_product %d * %d -> %lx|%.8lx not %llx\\n\",\n            a, times, hi, lo, fp);\n         ++error64;\n      }\n\n      if (div != 0)\n      {\n         /* Round - this is C round to zero. */\n         if ((fp < 0) != (div < 0))\n           fp -= div/2;\n         else\n           fp += div/2;\n\n         fp /= div;\n         fpround = fp;\n         /* Assume 2's complement here: */\n         ok = fpround <= PNG_UINT_31_MAX &&\n              fpround >= -1-(long long int)PNG_UINT_31_MAX;\n         if (!ok) ++overflow;\n      }\n      else\n        ok = 0, ++overflow, fpround = fp/*misleading*/;\n\n      if (verbose)\n         fprintf(stderr, \"TEST %d * %d / %d -> %lld (%s)\\n\", a, times, div,\n            fp, ok ? \"ok\" : \"overflow\");\n\n      ++tested;\n      if (png_muldiv(&result, a, times, div) != ok)\n      {\n         ++error;\n         if (ok)\n             fprintf(stderr, \"%d * %d / %d -> overflow (expected %lld)\\n\", a,\n                times, div, fp);\n         else\n             fprintf(stderr, \"%d * %d / %d -> %d (expected overflow %lld)\\n\", a,\n                times, div, result, fp);\n      }\n      else if (ok && result != fpround)\n      {\n         ++error;\n         fprintf(stderr, \"%d * %d / %d -> %d not %lld\\n\", a, times, div, result,\n            fp);\n      }\n      else\n         ++passed;\n\n      /* Generate three new values, this uses rand() and rand() only returns\n       * up to RAND_MAX.\n       */\n      /* CRUDE */\n      a += times;\n      times += div;\n      div = randbuffer;\n      randbuffer = (randbuffer << randbits) ^ rand();\n   }\n   while (--count > 0);\n\n   printf(\"%d tests including %d overflows, %d passed, %d failed (%d 64-bit \"\n      \"errors)\\n\", tested, overflow, passed, error, error64);\n   return 0;\n}\n\n/* When FP is on this just becomes a speed test - compile without FP to get real\n * validation.\n */\n#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED\n#define LN2 .000010576586617430806112933839 /* log(2)/65536 */\n#define L2INV 94548.46219969910586572651    /* 65536/log(2) */\n\n/* For speed testing, need the internal functions too: */\nstatic png_uint_32 png_log8bit(unsigned x)\n{\n   if (x > 0)\n      return (png_uint_32)floor(.5-log(x/255.)*L2INV);\n\n   return 0xffffffff;\n}\n\nstatic png_uint_32 png_log16bit(png_uint_32 x)\n{\n   if (x > 0)\n      return (png_uint_32)floor(.5-log(x/65535.)*L2INV);\n\n   return 0xffffffff;\n}\n\nstatic png_uint_32 png_exp(png_uint_32 x)\n{\n   return (png_uint_32)floor(.5 + exp(x * -LN2) * 0xffffffffU);\n}\n\nstatic png_byte png_exp8bit(png_uint_32 log)\n{\n   return (png_byte)floor(.5 + exp(log * -LN2) * 255);\n}\n\nstatic png_uint_16 png_exp16bit(png_uint_32 log)\n{\n   return (png_uint_16)floor(.5 + exp(log * -LN2) * 65535);\n}\n#endif /* FLOATING_ARITHMETIC */\n\nint validation_gamma(int argc, char **argv)\n{\n   double gamma[9] = { 2.2, 1.8, 1.52, 1.45, 1., 1/1.45, 1/1.52, 1/1.8, 1/2.2 };\n   double maxerr;\n   int i, silent=0, onlygamma=0;\n\n   /* Silence the output with -s, just test the gamma functions with -g: */\n   while (--argc > 0)\n      if (strcmp(*++argv, \"-s\") == 0)\n         silent = 1;\n      else if (strcmp(*argv, \"-g\") == 0)\n         onlygamma = 1;\n      else\n      {\n         fprintf(stderr, \"unknown argument %s\\n\", *argv);\n         return 1;\n      }\n\n   if (!onlygamma)\n   {\n      /* First validate the log functions: */\n      maxerr = 0;\n      for (i=0; i<256; ++i)\n      {\n         double correct = -log(i/255.)/log(2.)*65536;\n         double error = png_log8bit(i) - correct;\n\n         if (i != 0 && fabs(error) > maxerr)\n            maxerr = fabs(error);\n\n         if (i == 0 && png_log8bit(i) != 0xffffffff ||\n             i != 0 && png_log8bit(i) != floor(correct+.5))\n         {\n            fprintf(stderr, \"8-bit log error: %d: got %u, expected %f\\n\",\n               i, png_log8bit(i), correct);\n         }\n      }\n\n      if (!silent)\n         printf(\"maximum 8-bit log error = %f\\n\", maxerr);\n\n      maxerr = 0;\n      for (i=0; i<65536; ++i)\n      {\n         double correct = -log(i/65535.)/log(2.)*65536;\n         double error = png_log16bit(i) - correct;\n\n         if (i != 0 && fabs(error) > maxerr)\n            maxerr = fabs(error);\n\n         if (i == 0 && png_log16bit(i) != 0xffffffff ||\n             i != 0 && png_log16bit(i) != floor(correct+.5))\n         {\n            if (error > .68) /* By experiment error is less than .68 */\n            {\n               fprintf(stderr, \"16-bit log error: %d: got %u, expected %f\"\n                  \" error: %f\\n\", i, png_log16bit(i), correct, error);\n            }\n         }\n      }\n\n      if (!silent)\n         printf(\"maximum 16-bit log error = %f\\n\", maxerr);\n\n      /* Now exponentiations. */\n      maxerr = 0;\n      for (i=0; i<=0xfffff; ++i)\n      {\n         double correct = exp(-i/65536. * log(2.)) * (65536. * 65536);\n         double error = png_exp(i) - correct;\n\n         if (fabs(error) > maxerr)\n            maxerr = fabs(error);\n         if (fabs(error) > 1883) /* By experiment. */\n         {\n            fprintf(stderr, \"32-bit exp error: %d: got %u, expected %f\"\n                  \" error: %f\\n\", i, png_exp(i), correct, error);\n         }\n      }\n\n      if (!silent)\n         printf(\"maximum 32-bit exp error = %f\\n\", maxerr);\n\n      maxerr = 0;\n      for (i=0; i<=0xfffff; ++i)\n      {\n         double correct = exp(-i/65536. * log(2.)) * 255;\n         double error = png_exp8bit(i) - correct;\n\n         if (fabs(error) > maxerr)\n            maxerr = fabs(error);\n         if (fabs(error) > .50002) /* By experiment */\n         {\n            fprintf(stderr, \"8-bit exp error: %d: got %u, expected %f\"\n                  \" error: %f\\n\", i, png_exp8bit(i), correct, error);\n         }\n      }\n\n      if (!silent)\n         printf(\"maximum 8-bit exp error = %f\\n\", maxerr);\n\n      maxerr = 0;\n      for (i=0; i<=0xfffff; ++i)\n      {\n         double correct = exp(-i/65536. * log(2.)) * 65535;\n         double error = png_exp16bit(i) - correct;\n\n         if (fabs(error) > maxerr)\n            maxerr = fabs(error);\n         if (fabs(error) > .524) /* By experiment */\n         {\n            fprintf(stderr, \"16-bit exp error: %d: got %u, expected %f\"\n                  \" error: %f\\n\", i, png_exp16bit(i), correct, error);\n         }\n      }\n\n      if (!silent)\n         printf(\"maximum 16-bit exp error = %f\\n\", maxerr);\n   } /* !onlygamma */\n\n   /* Test the overall gamma correction. */\n   for (i=0; i<9; ++i)\n   {\n      unsigned j;\n      double g = gamma[i];\n      png_fixed_point gfp = floor(g * PNG_FP_1 + .5);\n\n      if (!silent)\n         printf(\"Test gamma %f\\n\", g);\n\n      maxerr = 0;\n      for (j=0; j<256; ++j)\n      {\n         double correct = pow(j/255., g) * 255;\n         png_byte out = png_gamma_8bit_correct(j, gfp);\n         double error = out - correct;\n\n         if (fabs(error) > maxerr)\n            maxerr = fabs(error);\n         if (out != floor(correct+.5))\n         {\n            fprintf(stderr, \"8bit %d ^ %f: got %d expected %f error %f\\n\",\n               j, g, out, correct, error);\n         }\n      }\n\n      if (!silent)\n         printf(\"gamma %f: maximum 8-bit error %f\\n\", g, maxerr);\n\n      maxerr = 0;\n      for (j=0; j<65536; ++j)\n      {\n         double correct = pow(j/65535., g) * 65535;\n         png_uint_16 out = png_gamma_16bit_correct(j, gfp);\n         double error = out - correct;\n\n         if (fabs(error) > maxerr)\n            maxerr = fabs(error);\n         if (fabs(error) > 1.62)\n         {\n            fprintf(stderr, \"16bit %d ^ %f: got %d expected %f error %f\\n\",\n               j, g, out, correct, error);\n         }\n      }\n\n      if (!silent)\n         printf(\"gamma %f: maximum 16-bit error %f\\n\", g, maxerr);\n   }\n\n   return 0;\n}\n\n/**************************** VALIDATION TESTS ********************************/\n/* Various validation routines are included herein, they require some\n * definition for png_warning and png_error, seetings of VALIDATION:\n *\n * 1: validates the ASCII to floating point conversions\n * 2: validates png_muldiv\n * 3: accuracy test of fixed point gamma tables\n */\n\n/* The following COUNT (10^8) takes about 1 hour on a 1GHz Pentium IV\n * processor.\n */\n#define COUNT 1000000000\n\nint main(int argc, char **argv)\n{\n   int count = COUNT;\n\n   while (argc > 1)\n   {\n      if (argc > 2 && strcmp(argv[1], \"-c\") == 0)\n      {\n         count = atoi(argv[2]);\n         argc -= 2;\n         argv += 2;\n      }\n\n      else if (strcmp(argv[1], \"-v\") == 0)\n      {\n         ++verbose;\n         --argc;\n         ++argv;\n      }\n\n      else\n         break;\n   }\n\n   if (count > 0 && argc > 1)\n   {\n      if (strcmp(argv[1], \"ascii\") == 0)\n         return validation_ascii_to_fp(count, argc-1, argv+1);\n      else if (strcmp(argv[1], \"checkfp\") == 0)\n         return validation_checkfp(count, argc-1, argv+1);\n      else if (strcmp(argv[1], \"muldiv\") == 0)\n         return validation_muldiv(count, argc-1, argv+1);\n      else if (strcmp(argv[1], \"gamma\") == 0)\n         return validation_gamma(argc-1, argv+1);\n   }\n\n   /* Bad argument: */\n   fprintf(stderr,\n      \"usage: tarith [-v] [-c count] {ascii,muldiv,gamma} [args]\\n\");\n   fprintf(stderr, \" arguments: ascii [-a (all results)] [-e error%%]\\n\");\n   fprintf(stderr, \"            checkfp [-l max-number-chars]\\n\");\n   fprintf(stderr, \"            muldiv\\n\");\n   fprintf(stderr, \"            gamma -s (silent) -g (only gamma; no log)\\n\");\n   return 1;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/libtests/timepng.c",
    "content": "/* timepng.c\n *\n * Copyright (c) 2013 John Cunningham Bowler\n *\n * Last changed in libpng 1.6.1 [March 28, 2013]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * Load an arbitrary number of PNG files (from the command line, or, if there\n * are no arguments on the command line, from stdin) then run a time test by\n * reading each file by row.  The test does nothing with the read result and\n * does no transforms.  The only output is a time as a floating point number of\n * seconds with 9 decimal digits.\n */\n#define _POSIX_C_SOURCE 199309L /* for clock_gettime */\n\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n\n#include <time.h>\n\n#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)\n#  include <config.h>\n#endif\n\n/* Define the following to use this test against your installed libpng, rather\n * than the one being built here:\n */\n#ifdef PNG_FREESTANDING_TESTS\n#  include <png.h>\n#else\n#  include \"../../png.h\"\n#endif\n\nstatic int read_png(FILE *fp)\n{\n   png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);\n   png_infop info_ptr = NULL;\n   png_bytep row = NULL, display = NULL;\n\n   if (png_ptr == NULL)\n      return 0;\n\n   if (setjmp(png_jmpbuf(png_ptr)))\n   {\n      png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n      if (row != NULL) free(row);\n      if (display != NULL) free(display);\n      return 0;\n   }\n\n   png_init_io(png_ptr, fp);\n\n   info_ptr = png_create_info_struct(png_ptr);\n   if (info_ptr == NULL)\n      png_error(png_ptr, \"OOM allocating info structure\");\n\n   png_read_info(png_ptr, info_ptr);\n\n   {\n      png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);\n\n      row = malloc(rowbytes);\n      display = malloc(rowbytes);\n\n      if (row == NULL || display == NULL)\n         png_error(png_ptr, \"OOM allocating row buffers\");\n\n      {\n         png_uint_32 height = png_get_image_height(png_ptr, info_ptr);\n         int passes = png_set_interlace_handling(png_ptr);\n         int pass;\n\n         png_start_read_image(png_ptr);\n\n         for (pass = 0; pass < passes; ++pass)\n         {\n            png_uint_32 y = height;\n\n            /* NOTE: this trashes the row each time; interlace handling won't\n             * work, but this avoids memory thrashing for speed testing.\n             */\n            while (y-- > 0)\n               png_read_row(png_ptr, row, display);\n         }\n      }\n   }\n\n   /* Make sure to read to the end of the file: */\n   png_read_end(png_ptr, info_ptr);\n   png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n   free(row);\n   free(display);\n   return 1;\n}\n\nstatic int mytime(struct timespec *t)\n{\n   /* Do the timing using clock_gettime and the per-process timer. */\n   if (!clock_gettime(CLOCK_PROCESS_CPUTIME_ID, t))\n      return 1;\n\n   perror(\"CLOCK_PROCESS_CPUTIME_ID\");\n   fprintf(stderr, \"timepng: could not get the time\\n\");\n   return 0;\n}\n\nstatic int perform_one_test(FILE *fp, int nfiles)\n{\n   int i;\n   struct timespec before, after;\n\n   /* Clear out all errors: */\n   rewind(fp);\n\n   if (mytime(&before))\n   {\n      for (i=0; i<nfiles; ++i)\n      {\n         if (read_png(fp))\n         {\n            if (ferror(fp))\n            {\n               perror(\"temporary file\");\n               fprintf(stderr, \"file %d: error reading PNG data\\n\", i);\n               return 0;\n            }\n         }\n\n         else\n         {\n            perror(\"temporary file\");\n            fprintf(stderr, \"file %d: error from libpng\\n\", i);\n            return 0;\n         }\n      }\n   }\n\n   else\n      return 0;\n\n   if (mytime(&after))\n   {\n      /* Work out the time difference and print it - this is the only output,\n       * so flush it immediately.\n       */\n      unsigned long s = after.tv_sec - before.tv_sec;\n      long ns = after.tv_nsec - before.tv_nsec;\n\n      if (ns < 0)\n      {\n         --s;\n         ns += 1000000000;\n\n         if (ns < 0)\n         {\n            fprintf(stderr, \"timepng: bad clock from kernel\\n\");\n            return 0;\n         }\n      }\n\n      printf(\"%lu.%.9ld\\n\", s, ns);\n      fflush(stdout);\n      if (ferror(stdout))\n      {\n         fprintf(stderr, \"timepng: error writing output\\n\");\n         return 0;\n      }\n\n      /* Successful return */\n      return 1;\n   }\n\n   else\n      return 0;\n}\n\nstatic int add_one_file(FILE *fp, char *name)\n{\n   FILE *ip = fopen(name, \"rb\");\n\n   if (ip != NULL)\n   {\n      int ch;\n      for (;;)\n      {\n         ch = getc(ip);\n         if (ch == EOF) break;\n         putc(ch, fp);\n      }\n\n      if (ferror(ip))\n      {\n         perror(name);\n         fprintf(stderr, \"%s: read error\\n\", name);\n         return 0;\n      }\n\n      (void)fclose(ip);\n\n      if (ferror(fp))\n      {\n         perror(\"temporary file\");\n         fprintf(stderr, \"temporary file write error\\n\");\n         return 0;\n      }\n   }\n\n   else\n   {\n      perror(name);\n      fprintf(stderr, \"%s: open failed\\n\", name);\n      return 0;\n   }\n\n   return 1;\n}\n\nint main(int argc, char **argv)\n{\n   int ok = 0;\n   FILE *fp = tmpfile();\n\n   if (fp != NULL)\n   {\n      int err = 0;\n      int nfiles = 0;\n\n      if (argc > 1)\n      {\n         int i;\n\n         for (i=1; i<argc; ++i)\n         {\n            if (add_one_file(fp, argv[i]))\n               ++nfiles;\n\n            else\n            {\n               err = 1;\n               break;\n            }\n         }\n      }\n\n      else\n      {\n         char filename[FILENAME_MAX+1];\n\n         while (fgets(filename, FILENAME_MAX+1, stdin))\n         {\n            size_t len = strlen(filename);\n\n            if (filename[len-1] == '\\n')\n            {\n               filename[len-1] = 0;\n               if (add_one_file(fp, filename))\n                  ++nfiles;\n\n               else\n               {\n                  err = 1;\n                  break;\n               }\n            }\n\n            else\n            {\n               fprintf(stderr, \"timepng: truncated file name ...%s\\n\",\n                  filename+len-32);\n               err = 1;\n               break;\n            }\n         }\n\n         if (ferror(stdin))\n         {\n            fprintf(stderr, \"timepng: stdin: read error\\n\");\n            err = 1;\n         }\n      }\n\n      if (!err)\n      {\n         if (nfiles > 0)\n            ok = perform_one_test(fp, nfiles);\n\n         else\n            fprintf(stderr, \"usage: timepng {files} or ls files | timepng\\n\");\n      }\n\n      (void)fclose(fp);\n   }\n\n   else\n      fprintf(stderr, \"timepng: could not open temporary file\\n\");\n\n   /* Exit code 0 on success. */\n   return ok == 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminim/README",
    "content": "\nThis demonstrates the use of PNG_USER_CONFIG, pngusr.h and pngusr.dfa\nto build minimal decoder, encoder, and progressive reader applications.\n\nSee the individual README and pngusr.dfa files for more explanation.\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminim/decoder/README",
    "content": "This demonstrates the use of PNG_USER_CONFIG, pngusr.h and pngusr.dfa\n\nThe makefile builds a minimal read-only decoder with embedded libpng\nand zlib.\n\nSpecify the location of the zlib source (1.2.1 or later) as ZLIBSRC\non the make command line.\n\nIf you prefer to use the shared libraries, go to contrib/pngminus\nand build the png2pnm application there.\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminim/decoder/makefile",
    "content": "# Makefile for PngMinus (pngm2pnm)\n# Linux / Unix\n\n#CC=cc\nCC=gcc\nLD=$(CC)\n\n# If awk fails try\n# make AWK=nawk\n\n# If cpp fails try\n# make CPP=/lib/cpp\n\nRM=rm -f\nCOPY=cp\n\nCPPFLAGS=-I. -DPNG_USER_CONFIG -DNO_GZCOMPRESS -DZ_SOLO -DNO_GZIP\nCFLAGS=-O1 -Wall\n\nC=.c\nO=.o\nL=.a\nE=\n\n# Where to find the source code:\nPNGSRC =../../..\nZLIBSRC=$(PNGSRC)/../zlib\nPROGSRC=$(PNGSRC)/contrib/pngminus\n\n# Zlib (minimal inflate requirements - crc32 is used by libpng)\n# zutil can be eliminated if you provide your own zcalloc and zcfree\nZSRCS  = adler32$(C) crc32$(C) \\\n\t inffast$(C) inflate$(C) inftrees$(C) \\\n\t zutil$(C)\n\n# Standard headers\nZH     = zlib.h crc32.h inffast.h inffixed.h \\\n\t inflate.h inftrees.h zutil.h\n\n# Machine generated headers\nZCONF  = zconf.h\n\n# Headers callers use\nZINC   = zlib.h $(ZCONF)\n\n# Headers the Zlib source uses\nZHDRS  = $(ZH) $(ZCONF)\n\nZOBJS  = adler32$(O) crc32$(O) \\\n\t inffast$(O) inflate$(O) inftrees$(O) \\\n\t zutil$(O)\n\n# libpng\nPNGSRCS=png$(C) pngerror$(C) pngget$(C) pngmem$(C) \\\n\tpngread$(C) pngrio$(C) pngrtran$(C) pngrutil$(C) \\\n\tpngset$(C) pngtrans$(C)\n\t\n# Standard headers\nPNGH   =png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h\n\n# Machine generated headers\nPNGCONF=pnglibconf.h\n\n# Headers callers use\nPNGINC= png.h pngconf.h pngusr.h $(PNGCONF)\n\n# Headers the PNG library uses\nPNGHDRS=$(PNGH) $(PNGCONF) pngusr.h\n\nPNGOBJS=png$(O) pngerror$(O) pngget$(O) pngmem$(O) \\\n\tpngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \\\n\tpngset$(O) pngtrans$(O)\n\nPROGSRCS= pngm2pnm$(C)\nPROGHDRS=\nPROGDOCS=\nPROGOBJS= pngm2pnm$(O)\n\nOBJS    = $(PROGOBJS) $(PNGOBJS) $(ZOBJS)\n\n# implicit make rules -------------------------------------------------------\n\n# note: dependencies do not work on implicit rule lines\n.c$(O):\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $<\n\n# dependencies\n\nall: pngm2pnm$(E)\n\npngm2pnm$(E): $(OBJS)\n\t$(LD) -o pngm2pnm$(E) $(OBJS)\n\n# The DFA_XTRA setting turns all libpng options off then\n# turns on those required for this minimal build.\n# The CPP_FLAGS setting causes pngusr.h to be included in\n# both the build of pnglibconf.h and, subsequently, when\n# building libpng itself.\n$(PNGCONF): $(PNGSRC)/scripts/pnglibconf.mak $(ZH)\\\n\t$(PNGSRC)/scripts/pnglibconf.dfa \\\n\t$(PNGSRC)/scripts/options.awk pngusr.h pngusr.dfa\n\t$(RM) pnglibconf.h pnglibconf.dfn\n\t$(MAKE) -f $(PNGSRC)/scripts/pnglibconf.mak $(MAKEFLAGS)\\\n\t    srcdir=$(PNGSRC) CPPFLAGS=\"-DPNG_USER_CONFIG -I.\"\\\n\t    DFA_XTRA=\"pngusr.dfa\" $@\n\nclean:\n\t$(MAKE) -f $(PNGSRC)/scripts/pnglibconf.mak $(MAKEFLAGS)\\\n\t    srcdir=$(PNGSRC) clean\n\t$(RM) pngm2pnm$(O)\n\t$(RM) pngm2pnm$(E)\n\t$(RM) $(OBJS)\n\n# distclean also removes the copied source and headers\ndistclean: clean\n\t$(RM) -r scripts # historical reasons\n\t$(RM) $(PNGSRCS) $(PNGH)\n\t$(RM) $(ZSRCS) $(ZH) $(ZCONF)\n\t$(RM) $(PROGSRCS) $(PROGHDRS) $(PROGDOCS)\n\n# Header file dependencies:\n$(PROGOBJS): $(PROGHDRS) $(PNGINC) $(ZINC)\n$(PNGOBJS): $(PNGHDRS) $(ZINC)\n$(ZOBJS): $(ZHDRS)\n\n# Gather the source code from the respective directories\n$(PNGSRCS) $(PNGH): $(PNGSRC)/$@\n\t$(RM) $@\n\t$(COPY) $(PNGSRC)/$@ $@\n\n# No dependency on the ZLIBSRC target so that it only needs\n# to be specified once.\n$(ZSRCS) $(ZH):\n\t$(RM) $@\n\t$(COPY) $(ZLIBSRC)/$@ $@\n\n# The unconfigured zconf.h varies in name according to the\n# zlib release\n$(ZCONF):\n\t$(RM) $@\n\t@for f in zconf.h.in zconf.in.h zconf.h; do\\\n\t    test -r $(ZLIBSRC)/$$f &&\\\n\t    echo $(COPY) $(ZLIBSRC)/$$f $@ &&\\\n\t    $(COPY) $(ZLIBSRC)/$$f $@ && exit 0;\\\n\tdone; echo copy: $(ZLIBSRC)/zconf.h not found; exit 1\n\npngm2pnm.c: $(PROGSRC)/png2pnm.c\n\t$(RM) $@\n\t$(COPY) $(PROGSRC)/png2pnm.c $@\n\n# End of makefile for pngm2pnm\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminim/decoder/pngusr.dfa",
    "content": "# pngminim/decoder/pngusr.dfa\n#\n# Copyright (c) 2010-2013 Glenn Randers-Pehrson\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# First all the build options off:\n\neverything = off\n\n# All that is required is some read code. This example switches\n# on the sequential read code (see ../preader for a progressive\n# read example).\n\noption SEQUENTIAL_READ on\n\n# You must choose fixed or floating point arithmetic:\n# option FLOATING_POINT on\n\noption FIXED_POINT on\n\n# You must chose the internal fixed point implementation or to\n# use the system floating point.  The latter is considerably\n# smaller (by about 1kbyte on an x86 system):\n# option FLOATING_ARITHMETIC on\n\noption FLOATING_ARITHMETIC off\n\n# Your program will probably need other options.  The example\n# program here, pngm2pnm, requires the following.  Take a look\n# at pnglibconf.h to find out the full set of what has to be\n# enabled to make the following work.\n\noption SETJMP on\noption STDIO on\noption READ_EXPAND on\noption READ_STRIP_16_TO_8 on\noption USER_LIMITS on\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminim/decoder/pngusr.h",
    "content": "/* minrdpngconf.h: headers to make a minimal png-read-only library\n *\n * Copyright (c) 2007, 2010-2013 Glenn Randers-Pehrson\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * Derived from pngcrush.h, Copyright 1998-2007, Glenn Randers-Pehrson\n */\n\n#ifndef MINRDPNGCONF_H\n#define MINRDPNGCONF_H\n\n/* To include pngusr.h set -DPNG_USER_CONFIG in CPPFLAGS */\n\n/* List options to turn off features of the build that do not\n * affect the API (so are not recorded in pnglibconf.h)\n */\n\n#define PNG_ALIGN_TYPE PNG_ALIGN_NONE\n\n#endif /* MINRDPNGCONF_H */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminim/encoder/README",
    "content": "This demonstrates the use of PNG_USER_CONFIG and pngusr.h\n\nThe makefile builds a minimal write-only encoder with embedded libpng\nand zlib.\n\nSpecify the location of the zlib source (1.2.1 or later) as ZLIBSRC\non the make command line.\n\nIf you prefer to use the shared libraries, go to contrib/pngminus\nand build the pnm2png application there.\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminim/encoder/makefile",
    "content": "# Makefile for PngMinus (pnm2pngm)\n# Linux / Unix\n\n#CC=cc\nCC=gcc\nLD=$(CC)\n\n# If awk fails try\n# make AWK=nawk\n\n# If cpp fails try\n# make CPP=/lib/cpp\n\nRM=rm -f\nCOPY=cp\n\nCPPFLAGS=-I. -DPNG_USER_CONFIG -DNO_GZCOMPRESS -DZ_SOLO -DNO_GZIP\nCFLAGS=-O1 -Wall\n\nC=.c\nO=.o\nL=.a\nE=\n\n# Where to find the source code:\nPNGSRC =../../..\nZLIBSRC=$(PNGSRC)/../zlib\nPROGSRC=$(PNGSRC)/contrib/pngminus\n\n# Zlib\nZSRCS  = adler32$(C) compress$(C) crc32$(C) deflate$(C) \\\n\t trees$(C) zutil$(C)\n\n# Standard headers\n#ZH     = zlib.h crc32.h deflate.h trees.h zutil.h\nZH     = zlib.h crc32.h deflate.h trees.h zutil.h\n\n# Machine generated headers\nZCONF  = zconf.h\n\n# Headers callers use\nZINC   = zlib.h $(ZCONF)\n\n# Headers the Zlib source uses\nZHDRS  = $(ZH) $(ZCONF)\n\n# compress is not required; it is needed to link the zlib\n# code because deflate defines an unused API function deflateBound\n# which itself calls compressBound from compress.\nZOBJS  = adler32$(O) compress$(O) crc32$(O) deflate$(O) \\\n\t trees$(O) zutil$(O)\n\n# libpng\nPNGSRCS=png$(C) pngerror$(C) pngget$(C) pngmem$(C) \\\n\tpngset$(C) pngtrans$(C) pngwio$(C) pngwrite$(C) \\\n\tpngwtran$(C) pngwutil$(C)\n\n# Standard headers\nPNGH   =png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h\n\n# Machine generated headers\nPNGCONF=pnglibconf.h\n\n# Headers callers use\nPNGINC= png.h pngconf.h pngusr.h $(PNGCONF)\n\n# Headers the PNG library uses\nPNGHDRS=$(PNGH) $(PNGCONF) pngusr.h\n\nPNGOBJS=png$(O) pngerror$(O) pngget$(O) pngmem$(O) \\\n\tpngset$(O) pngtrans$(O) pngwio$(O) pngwrite$(O) \\\n\tpngwtran$(O) pngwutil$(O)\n\nPROGSRCS= pnm2pngm$(C)\nPROGHDRS=\nPROGDOCS=\nPROGOBJS= pnm2pngm$(O)\n\nOBJS    = $(PROGOBJS) $(PNGOBJS) $(ZOBJS)\n\n# implicit make rules -------------------------------------------------------\n\n.c$(O):\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $<\n\n# dependencies\n\nall: pnm2pngm$(E)\n\npnm2pngm$(E): $(OBJS)\n\t$(LD) -o pnm2pngm$(E) $(OBJS)\n\n# The DFA_XTRA setting turns all libpng options off then\n# turns on those required for this minimal build.\n# The CPP_FLAGS setting causes pngusr.h to be included in\n# both the build of pnglibconf.h and, subsequently, when\n# building libpng itself.\n$(PNGCONF): $(PNGSRC)/scripts/pnglibconf.mak $(ZH)\\\n\t$(PNGSRC)/scripts/pnglibconf.dfa \\\n\t$(PNGSRC)/scripts/options.awk pngusr.h pngusr.dfa\n\t$(RM) pnglibconf.h pnglibconf.dfn\n\t$(MAKE) -f $(PNGSRC)/scripts/pnglibconf.mak $(MAKEFLAGS)\\\n\t    srcdir=$(PNGSRC) CPPFLAGS=\"-DPNG_USER_CONFIG -I.\"\\\n\t    DFA_XTRA=\"pngusr.dfa\" $@\n\nclean:\n\t$(MAKE) -f $(PNGSRC)/scripts/pnglibconf.mak $(MAKEFLAGS)\\\n\t    srcdir=$(PNGSRC) clean\n\t$(RM) pnm2pngm$(O)\n\t$(RM) pnm2pngm$(E)\n\t$(RM) $(OBJS)\n\n# distclean also removes the copied source and headers\ndistclean: clean\n\t$(RM) -r scripts # historical reasons\n\t$(RM) $(PNGSRCS) $(PNGH)\n\t$(RM) $(ZSRCS) $(ZH) $(ZCONF)\n\t$(RM) $(PROGSRCS) $(PROGHDRS) $(PROGDOCS)\n\n# Header file dependencies:\n$(PROGOBJS): $(PROGHDRS) $(PNGINC) $(ZINC)\n$(PNGOBJS): $(PNGHDRS) $(ZINC)\n$(ZOBJS): $(ZHDRS)\n\n# Gather the source code from the respective directories\n$(PNGSRCS) $(PNGH): $(PNGSRC)/$@\n\t$(RM) $@\n\t$(COPY) $(PNGSRC)/$@ $@\n\n# No dependency on the ZLIBSRC target so that it only needs\n# to be specified once.\n$(ZSRCS) $(ZH):\n\t$(RM) $@\n\t$(COPY) $(ZLIBSRC)/$@ $@\n\n# The unconfigured zconf.h varies in name according to the\n# zlib release\n$(ZCONF):\n\t$(RM) $@\n\t@for f in zconf.h.in zconf.in.h zconf.h; do\\\n\t    test -r $(ZLIBSRC)/$$f &&\\\n\t    echo $(COPY) $(ZLIBSRC)/$$f $@ &&\\\n\t    $(COPY) $(ZLIBSRC)/$$f $@ && exit 0;\\\n\tdone; echo copy: $(ZLIBSRC)/zconf.h not found; exit 1\n\npnm2pngm.c: $(PROGSRC)/pnm2png.c\n\t$(RM) $@\n\t$(COPY) $(PROGSRC)/pnm2png.c $@\n\n# End of makefile for pnm2pngm\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminim/encoder/pngusr.dfa",
    "content": "# pngminim/encoder/pngusr.dfa\n#\n# Copyright (c) 2010-2013 Glenn Randers-Pehrson\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# First all the build options off:\n\neverything = off\n\n# Switch on the write code - this makes a minimalist encoder\n\noption WRITE on\n\n# These 2 options are required if you need to read PBM (P1 or P4) files.\noption WRITE_INVERT on\noption WRITE_PACK on\n\n# You must choose fixed or floating point arithmetic:\n# option FLOATING_POINT on\n\noption FIXED_POINT on\n\n# You must chose the internal fixed point implementation or to\n# use the system floating point.  The latter is considerably\n# smaller (by about 1kbyte on an x86 system):\n# option FLOATING_ARITHMETIC on\n\noption FLOATING_ARITHMETIC off\n\n# Your program will probably need other options.  The example\n# program here, pnm2pngm, requires the following.  Take a look\n# at pnglibconf.h to find out the full set of what has to be\n# enabled to make the following work.\n\noption SETJMP on\noption STDIO on\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminim/encoder/pngusr.h",
    "content": "/* minwrpngconf.h: headers to make a minimal png-write-only library\n *\n * Copyright (c) 2007, 2010-2013 Glenn Randers-Pehrson\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * Derived from pngcrush.h, Copyright 1998-2007, Glenn Randers-Pehrson\n */\n\n#ifndef MINWRPNGCONF_H\n#define MINWRPNGCONF_H\n\n/* To include pngusr.h set -DPNG_USER_CONFIG in CPPFLAGS */\n\n/* List options to turn off features of the build that do not\n * affect the API (so are not recorded in pnglibconf.h)\n */\n\n#define PNG_ALIGN_TYPE PNG_ALIGN_NONE\n\n#endif /* MINWRPNGCONF_H */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminim/preader/README",
    "content": "This demonstrates the use of PNG_USER_CONFIG and pngusr.h\n\nThe makefile builds a minimal read-only progressive decoder with\nembedded libpng, zlib and your system's X library.\n\nSpecify the location of the zlib source (1.2.1 or later) as ZLIBSRC\non the make command line.\n\nEdit makefile if required, to find your X library and include files,\nthen\n\n    make ZLIBSRC=directory\n\nIf you prefer to use the shared libraries, go to contrib/gregbook\nand build the rpng2-x application there.\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminim/preader/makefile",
    "content": "# Makefile for PngMinus (rpng2)\n# Linux / Unix\n\n#CC=cc\nCC=gcc\nLD=$(CC)\n\n# If awk fails try\n# make AWK=nawk\n\n# If cpp fails try\n# make CPP=/lib/cpp\n\nRM=rm -f\nCOPY=cp\n\n#XINC = -I/usr/include\t\t\t# old-style, stock X distributions\n#XLIB = -L/usr/lib/X11 -lX11\t\t#  (including SGI IRIX)\n\n#XINC = -I/usr/openwin/include\t\t# Sun workstations (OpenWindows)\n#XLIB = -L/usr/openwin/lib -lX11\n\nXINC = -I/usr/X11R6/include\t\t# new X distributions (X.org, etc.)\nXLIB = -L/usr/X11R6/lib -lX11\n#XLIB = -L/usr/X11R6/lib64 -lX11\t# e.g., Red Hat on AMD64\n\n#XINC = -I/usr/local/include   \t\t# FreeBSD\n#XLIB = -L/usr/local/lib -lX11\n\n#LIBS = $(XLIB)\nLIBS = $(XLIB) -lm                      #platforms that need libm\n\nCPPFLAGS=-I. $(XINC) -DPNG_USER_CONFIG -DNO_GZCOMPRESS -DZ_SOLO -DNO_GZIP\nCFLAGS=-O1 -Wall\n\nC=.c\nO=.o\nL=.a\nE=\n\n# Where to find the source code:\nPNGSRC =../../..\nZLIBSRC=$(PNGSRC)/../zlib\nPROGSRC=$(PNGSRC)/contrib/gregbook\n\n# Zlib (minimal inflate requirements - crc32 is used by libpng)\n# zutil can be eliminated if you provide your own zcalloc and zcfree\nZSRCS  = adler32$(C) crc32$(C) \\\n\t inffast$(C) inflate$(C) inftrees$(C) \\\n\t zutil$(C)\n\n# Standard headers\nZH     = zlib.h crc32.h inffast.h inffixed.h \\\n\t inflate.h inftrees.h zutil.h\n\n# Machine generated headers\nZCONF  = zconf.h\n\n# Headers callers use\nZINC   = zlib.h $(ZCONF)\n\n# Headers the Zlib source uses\nZHDRS  = $(ZH) $(ZCONF)\n\nZOBJS  = adler32$(O) crc32$(O) \\\n\t inffast$(O) inflate$(O) inftrees$(O) \\\n\t zutil$(O)\n\n# libpng\nPNGSRCS=png$(C) pngerror$(C) pngget$(C) pngmem$(C) \\\n\tpngpread$(C) pngread$(C) pngrio$(C) pngrtran$(C) pngrutil$(C) \\\n\tpngset$(C) pngtrans$(C)\n\n# Standard headers\nPNGH   =png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h\n\n# Machine generated headers\nPNGCONF=pnglibconf.h\n\n# Headers callers use\nPNGINC= png.h pngconf.h pngusr.h $(PNGCONF)\n\n# Headers the PNG library uses\nPNGHDRS=$(PNGH) $(PNGCONF) pngusr.h\n\nPNGOBJS=png$(O) pngerror$(O) pngget$(O) pngmem$(O) \\\n\tpngpread$(O) pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \\\n\tpngset$(O) pngtrans$(O)\n\nPROGSRCS= rpng2-x$(C) readpng2$(C)\nPROGHDRS= readpng2.h\nPROGDOCS= COPYING LICENSE\nPROGOBJS= rpng2-x$(O) readpng2$(O)\n\nOBJS    = $(PROGOBJS) $(PNGOBJS) $(ZOBJS)\n\n# implicit make rules -------------------------------------------------------\n\n.c$(O):\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $<\n\n# dependencies\n\nall: $(PROGDOCS) rpng2-x$(E)\n\nrpng2-x$(E): $(OBJS)\n\t$(LD) -o rpng2-x$(E) $(OBJS) $(LIBS)\n\n# The DFA_XTRA setting turns all libpng options off then\n# turns on those required for this minimal build.\n# The CPP_FLAGS setting causes pngusr.h to be included in\n# both the build of pnglibconf.h and, subsequently, when\n# building libpng itself.\n$(PNGCONF): $(PNGSRC)/scripts/pnglibconf.mak $(ZH)\\\n\t$(PNGSRC)/scripts/pnglibconf.dfa \\\n\t$(PNGSRC)/scripts/options.awk pngusr.h pngusr.dfa\n\t$(RM) pnglibconf.h pnglibconf.dfn\n\t$(MAKE) -f $(PNGSRC)/scripts/pnglibconf.mak $(MAKEFLAGS)\\\n\t    srcdir=$(PNGSRC) CPPFLAGS=\"-DPNG_USER_CONFIG -I.\"\\\n\t    DFA_XTRA=\"pngusr.dfa\" $@\n\nclean:\n\t$(MAKE) -f $(PNGSRC)/scripts/pnglibconf.mak $(MAKEFLAGS)\\\n\t    srcdir=$(PNGSRC) clean\n\t$(RM) rpng2-x$(O)\n\t$(RM) rpng2-x$(E)\n\t$(RM) $(OBJS)\n\n# distclean also removes the copied source and headers\ndistclean: clean\n\t$(RM) -r scripts # historical reasons\n\t$(RM) $(PNGSRCS) $(PNGH)\n\t$(RM) $(ZSRCS) $(ZH) $(ZCONF)\n\t$(RM) $(PROGSRCS) $(PROGHDRS) $(PROGDOCS)\n\n# Header file dependencies:\n$(PROGOBJS): $(PROGHDRS) $(PNGINC) $(ZINC)\n$(PNGOBJS): $(PNGHDRS) $(ZINC)\n$(ZOBJS): $(ZHDRS)\n\n# Gather the source code from the respective directories\n$(PNGSRCS) $(PNGH): $(PNGSRC)/$@\n\t$(RM) $@\n\t$(COPY) $(PNGSRC)/$@ $@\n\n# No dependency on the ZLIBSRC target so that it only needs\n# to be specified once.\n$(ZSRCS) $(ZH):\n\t$(RM) $@\n\t$(COPY) $(ZLIBSRC)/$@ $@\n\n# The unconfigured zconf.h varies in name according to the\n# zlib release\n$(ZCONF):\n\t$(RM) $@\n\t@for f in zconf.h.in zconf.in.h zconf.h; do\\\n\t    test -r $(ZLIBSRC)/$$f &&\\\n\t    echo $(COPY) $(ZLIBSRC)/$$f $@ &&\\\n\t    $(COPY) $(ZLIBSRC)/$$f $@ && exit 0;\\\n\tdone; echo copy: $(ZLIBSRC)/zconf.h not found; exit 1\n\n$(PROGSRCS) $(PROGHDRS) $(PROGDOCS): $(PROGSRC)/$@\n\t$(RM) $@\n\t$(COPY) $(PROGSRC)/$@ $@\n\n# End of makefile for rpng2-x\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminim/preader/pngusr.dfa",
    "content": "# pngminim/preader/pngusr.dfa\n#\n# Copyright (c) 2010-2013 Glenn Randers-Pehrson\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# First all the build options off:\n\neverything = off\n\n# Just switch on the progressive read code\n\noption PROGRESSIVE_READ on\n\n# You may choose fixed or floating point APIs:\n# option FLOATING_POINT on\n\noption FIXED_POINT on\n\n# You must chose the internal fixed point implementation or to\n# use the system floating point.  The latter is considerably\n# smaller (by about 1kbyte on an x86 system):\n\noption FLOATING_ARITHMETIC on\n# option FLOATING_ARITHMETIC off\n\n# Your program will probably need other options.  The example\n# program here, rpng2-x, requires the following.  Take a look\n# at pnglibconf.h to find out the full set of what has to be\n# enabled to make the following work.\n\noption SETJMP on\noption STDIO on\noption READ_bKGD on\noption READ_GAMMA on\noption READ_EXPAND on\noption READ_STRIP_16_TO_8 on\noption READ_GRAY_TO_RGB on\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminim/preader/pngusr.h",
    "content": "/* minrdpngconf.h: headers to make a minimal png-read-only library\n *\n * Copyright (c) 2009, 2010-2013 Glenn Randers-Pehrson\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * Derived from pngcrush.h, Copyright 1998-2007, Glenn Randers-Pehrson\n */\n\n#ifndef MINPRDPNGCONF_H\n#define MINPRDPNGCONF_H\n\n/* To include pngusr.h set -DPNG_USER_CONFIG in CPPFLAGS */\n\n/* List options to turn off features of the build that do not\n * affect the API (so are not recorded in pnglibconf.h)\n */\n\n#define PNG_ALIGN_TYPE PNG_ALIGN_NONE\n\n#endif /* MINPRDPNGCONF_H */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminus/README",
    "content": "PngMinus\n--------\n(copyright Willem van Schaik, 1999)\n\n\nLicense\n-------\n\nPermission to use, copy, modify, and distribute this software and\nits documentation for any purpose and without fee is hereby granted,\nprovided that the above copyright notice appear in all copies and\nthat both that copyright notice and this permission notice appear in\nsupporting documentation. This software is provided \"as is\" without\nexpress or implied warranty.\n\n\nSome history\n------------\nSoon after the creation of PNG in 1995, the need was felt for a set of\npnmtopng / pngtopnm utilities. Independantly Alexander Lehmann and I\n(Willem van Schaik) started such a project. Luckily we discovered this\nand merged the two together into pnmtopng.tar.gz, which is available\nfrom a/o ftp://ftp.simplesystems.org/pub/libpng/png/.\n\nThese two utilities have many, many options and make use of most of the\nfeatures of PNG, like gamma, alpha, sbit, text-chunks, etc. This makes\nthe utilities quite complex and by now not anymore very maintainable.\nWhen we wrote these programs, libpng was still in an early stage.\nTherefore, lots of the functionality that we put in our software can now\nbe done using transform-functions in libpng.\n\nFinally, to compile these programs, you need to have installed and\ncompiled three libraries: libpng, zlib and netpbm. Especially the latter\nmakes the whole setup a bit bulky. But that's unavoidable given the many\nfeatures of pnmtopng.\n\n\nWhat now\n--------\nAt this moment libpng is in a very stable state and can do much of the\nwork done in pnmtopng. Also, pnmtopng needs to be upgraded to the new\ninterface of libpng. Hence, it is time for a rewrite from the ground up\nof pnmtopng and pngtopnm. This will happen in the near future (stay\ntuned). The new package will get a different name to distinguish it from\nthe old one: PngPlus.\n\nTo experiment a bit with the new interface of libpng, I started off with\na small prototype that contains only the basic functionality. It doesn't\nhave any of the options to read or write special chunks and it will do\nno gamma correction. But this makes it also a simple program that is\nquite easy to understand and can serve well as a template for other\nsoftware developments. (By now there are of course a couple of programs,\nlike Greg Roelofs' rpng/wpng, that can be used just as good.)\n\n\nCan and can not\n---------------\nAs this is the small brother of the future PngPlus, I called this fellow\nPngMinus. Because I started this development in good-old Turbo-C, I\navoided the use the netpbm library, which requires DOS extenders. Again,\nanother reason to call it PngMinus (minus netpbm :-). So, part of the\nprogram are some elementary routines to read / write pgm- and ppm-files.\nIt does not read b&w pbm-files.\n\nThe downside of this approach is that you can not use them on images\nthat require blocks of memory bigger than 64k (the DOS version). For\nlarger images you will get an out-of-memory error.\n\nAs said before, PngMinus doesn't correct for gamma. When reading\npng-files you can do this just as well by piping the output of png2pnm\nto pnmgamma, one of the standard PbmPlus tools. This same scenario will\nmost probably also be followed in the full-blown future PngPlus, with\nthe addition of course of the possibility to create gamma-chunks when\nwriting png-files.\n\nOn the other hand it supports alpha-channels. When reading a png-image\nyou can write the alpha-channel into a pgm-file. And when creating an\nRGB+A png-image, you just combine a ppm-file with a corresponding\npgm-file containing the alpha-channel. When reading, transparency chunks\nare converted into an alpha-channel and from there on treated the same\nway.\n\nFinally you can opt for writing ascii or binary pgm- and ppm-files. When\nthe bit-depth is 16, the format will always be ascii.\n\n\nUsing it\n--------\nTo distinguish them from pnmtopng and PngPlus, the utilities are named\npng2pnm and pnm2png (2 instead of to). The input- and output-files can\nbe given as parameters or through redirection. Therefore the programs\ncan be part of a pipe.\n\nTo list the options type \"png2pnm -h\" or \"pnm2png -h\".\n\n\nJust like Scandinavian furniture\n--------------------------------\nYou have to put it together yourself. I did test the software under\nMS-DOS with Turbo-C 3.0 and under RedHat Linux 4.2 with gcc. In both\ncases I used libpng-1.0.4 and zlib-1.1.3. Later versions should be OK,\nhowever some older libpng versions have a bug in pngmem.c when using\nTurbo-C 3.0 (see below).\n\nYou can build it using one of the two makefiles (make -f makefile.###)\nor use the batch/script files pngminus.bat / pngminus.sh. This assumes\nthat you have built the libraries in ../libpng and ../zlib. Using Linux,\nmake sure that you have built libpng with makefile.std and not\nmakefile.linux (also called .lnx in earlier versions of libpng). The\nlatter creates a .so shared-library, while the PngMinus makefile assumes\na normal .a static library.\n\nIf you create a ../pngsuite directory and then store the basn####.png\nfiles from PngSuite (http://www.schaik.com/pngsuite/) in there, you can\ntest in one go the proper functioning of PngMinus, see png2pnm.bat and\npnm2png.bat (or the .sh versions).\n\n\nWarranty\n-------\nPlease, remember that this was just a small experiment to learn a few\nthings. It will have many unforeseen features <vbg>. Who said bugs? Use\nit when you are in need for something simple or when you want to start\ndeveloping your own stuff.\n\n\nThe Turbo bug\n-------------\n** pngmem.old\n          hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);\n          hptr += 16L;\n** pngmem.c\n          hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);\n          hptr = hptr + 16L;\n**\n\n** pngmem.old\n          png_ptr->offset_table_ptr[i] = (png_bytep)hptr;\n          hptr += (png_uint_32)65536L;\n** pngmem.c\n          png_ptr->offset_table_ptr[i] = (png_bytep)hptr;\n          hptr = hptr + 65536L;\n**\n\n\nThe end\n-------\nWillem van Schaik\nmailto:willem@schaik.com\nhttp://www.schaik.com/png/\n-------\nOct 1999\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminus/makefile.std",
    "content": "# Makefile for PngMinus (png2pnm and pnm2png)\n# Linux / Unix\n\n#CC=cc\nCC=gcc\nLD=$(CC)\n\nRM=rm -f\n\n#PNGPATH = /usr/local\n#PNGINC = -I$(PNGPATH)/include/libpng16\n#PNGLIB = -L$(PNGPATH)/lib -lpng16\n#PNGLIBS = $(PNGPATH)/lib/libpng16.a\nPNGINC = -I../..\nPNGLIB = -L../.. -lpng\nPNGLIBS = ../../libpng.a\n\n#ZPATH = /usr/local\n#ZINC = -I$(ZPATH)/include\n#ZLIB = -L$(ZPATH)/lib -lz\n#ZLIBS = $(ZPATH)/lib/libz.a\nZINC = -I../../../zlib\nZLIB = -L../../../zlib -lz\nZLIBS = ../../../zlib/libz.a\n\nCPPFLAGS=$(PNGINC) $(ZINC)\nCFLAGS=\nLDLIBS=$(PNGLIB) $(ZLIB)\nLDLIBSS=$(PNGLIBS) $(ZLIBS)\nC=.c\nO=.o\nL=.a\nE=\n\n# dependencies\n\n#all: png2pnm$(E) pnm2png$(E)\nall: png2pnm$(E) pnm2png$(E) png2pnm-static$(E) pnm2png-static$(E)\n\npng2pnm$(O): png2pnm$(C)\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) png2pnm$(C)\n\npng2pnm$(E): png2pnm$(O)\n\t$(LD) $(LDFLAGS) -o png2pnm$(E) png2pnm$(O) $(LDLIBS) -lm\n\npng2pnm-static$(E): png2pnm$(O)\n\t$(LD) $(LDFLAGS) -o png2pnm-static$(E) png2pnm$(O) $(LDLIBSS) -lm\n\npnm2png$(O): pnm2png$(C)\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) pnm2png$(C)\n\npnm2png$(E): pnm2png$(O)\n\t$(LD) $(LDFLAGS) -o pnm2png$(E) pnm2png$(O) $(LDLIBS) -lm\n\npnm2png-static$(E): pnm2png$(O)\n\t$(LD) $(LDFLAGS) -o pnm2png-static$(E) pnm2png$(O) $(LDLIBSS) -lm\n\nclean:\n\t$(RM) png2pnm$(O)\n\t$(RM) pnm2png$(O)\n\t$(RM) png2pnm$(E)\n\t$(RM) pnm2png$(E)\n\t$(RM) png2pnm-static$(E)\n\t$(RM) pnm2png-static$(E)\n\n# End of makefile for png2pnm / pnm2png\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminus/makefile.tc3",
    "content": "# Makefile for PngMinus (png2pnm and pnm2png)\n# TurboC++ 3.0\n\nCC=tcc -Ic:\\tc3\\inc\nLD=tcc -Lc:\\tc3\\lib\nLB=tlib\nRM=del\nCP=copy\nMODEL=l\nCPPFLAGS=-I..\\libpng -I..\\zlib\nCFLAGS=-O -m$(MODEL)\nLDFLAGS=-m$(MODEL) -L..\\libpng -L..\\zlib\nC=.c\nO=.obj\nL=.lib\nE=.exe\n\n# dependencies\n\nall: png2pnm$(E) pnm2png$(E)\n\npng2pnm$(O): png2pnm$(C)\n        $(CC) -c $(CPPFLAGS) $(CFLAGS) png2pnm$(C)\n\npng2pnm$(E): png2pnm$(O)\n        $(LD) $(LDFLAGS) png2pnm$(O) libpng$(L) zlib$(L)\n\npnm2png$(O): pnm2png$(C)\n        $(CC) -c $(CPPFLAGS) $(CFLAGS) pnm2png$(C)\n\npnm2png$(E): pnm2png$(O)\n        $(LD) $(LDFLAGS) pnm2png$(O) libpng$(L) zlib$(L)\n\nclean:\n        $(RM) *$(O)\n        $(RM) *$(E)\n\n# End of makefile for png2pnm / pnm2png\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminus/makevms.com",
    "content": "$!------------------------------------------------------------------------------\n$! make Contrib programs of libpng under OpenVMS\n$!\n$!\n$! Look for the compiler used\n$!\n$ zlibsrc = \"[---.zlib]\"\n$ ccopt=\"/include=(''zlibsrc',[--])\"\n$ if f$getsyi(\"HW_MODEL\").ge.1024\n$ then\n$  ccopt = \"/prefix=all\"+ccopt\n$  comp  = \"__decc__=1\"\n$  if f$trnlnm(\"SYS\").eqs.\"\" then define sys sys$library:\n$ else\n$  if f$search(\"SYS$SYSTEM:DECC$COMPILER.EXE\").eqs.\"\"\n$   then\n$    if f$trnlnm(\"SYS\").eqs.\"\" then define sys sys$library:\n$    if f$search(\"SYS$SYSTEM:VAXC.EXE\").eqs.\"\"\n$     then\n$      comp  = \"__gcc__=1\"\n$      CC :== GCC\n$     else\n$      comp = \"__vaxc__=1\"\n$     endif\n$   else\n$    if f$trnlnm(\"SYS\").eqs.\"\" then define sys decc$library_include:\n$    ccopt = \"/decc/prefix=all\"+ccopt\n$    comp  = \"__decc__=1\"\n$  endif\n$ endif\n$ open/write lopt lib.opt\n$ write lopt \"[--]libpng.olb/lib\"\n$ write lopt \"''zlibsrc'libz.olb/lib\"\n$ close lopt\n$ open/write xopt x11.opt\n$ write xopt \"sys$library:decw$xlibshr.exe/share\"\n$ close xopt\n$ write sys$output \"Compiling PNG contrib programs ...\"\n$   write sys$output \"Building pnm2png...\"\n$   CALL MAKE pnm2png.OBJ \"cc ''CCOPT' pnm2png\" -\n\tpnm2png.c\n$   call make pnm2png.exe -\n\t\"LINK pnm2png,lib.opt/opt\" -\n\tpnm2png.obj\n$   write sys$output \"Building png2pnm...\"\n$   CALL MAKE png2pnm.OBJ \"cc ''CCOPT' png2pnm\" -\n\tpng2pnm.c\n$   call make png2pnm.exe -\n\t\"LINK png2pnm,lib.opt/opt\" -\n\tpng2pnm.obj\n$ exit\n$!\n$!\n$MAKE: SUBROUTINE   !SUBROUTINE TO CHECK DEPENDENCIES\n$ V = 'F$Verify(0)\n$! P1 = What we are trying to make\n$! P2 = Command to make it\n$! P3 - P8  What it depends on\n$\n$ If F$Search(P1) .Eqs. \"\" Then Goto Makeit\n$ Time = F$CvTime(F$File(P1,\"RDT\"))\n$arg=3\n$Loop:\n$       Argument = P'arg\n$       If Argument .Eqs. \"\" Then Goto Exit\n$       El=0\n$Loop2:\n$       File = F$Element(El,\" \",Argument)\n$       If File .Eqs. \" \" Then Goto Endl\n$       AFile = \"\"\n$Loop3:\n$       OFile = AFile\n$       AFile = F$Search(File)\n$       If AFile .Eqs. \"\" .Or. AFile .Eqs. OFile Then Goto NextEl\n$       If F$CvTime(F$File(AFile,\"RDT\")) .Ges. Time Then Goto Makeit\n$       Goto Loop3\n$NextEL:\n$       El = El + 1\n$       Goto Loop2\n$EndL:\n$ arg=arg+1\n$ If arg .Le. 8 Then Goto Loop\n$ Goto Exit\n$\n$Makeit:\n$ VV=F$VERIFY(0)\n$ write sys$output P2\n$ 'P2\n$ VV='F$Verify(VV)\n$Exit:\n$ If V Then Set Verify\n$ENDSUBROUTINE\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminus/png2pnm.bat",
    "content": "REM -- grayscale\npng2pnm.exe -noraw ..\\pngsuite\\basn0g01.png basn0g01.pgm\npng2pnm.exe -noraw ..\\pngsuite\\basn0g02.png basn0g02.pgm\npng2pnm.exe -noraw ..\\pngsuite\\basn0g04.png basn0g04.pgm\npng2pnm.exe -noraw ..\\pngsuite\\basn0g08.png basn0g08.pgm\npng2pnm.exe -noraw ..\\pngsuite\\basn0g16.png basn0g16.pgm\nREM -- full-color\npng2pnm.exe -noraw ..\\pngsuite\\basn2c08.png basn2c08.ppm\npng2pnm.exe -noraw ..\\pngsuite\\basn2c16.png basn2c16.ppm\nREM -- palletted\npng2pnm.exe -noraw ..\\pngsuite\\basn3p01.png basn3p01.ppm\npng2pnm.exe -noraw ..\\pngsuite\\basn3p02.png basn3p02.ppm\npng2pnm.exe -noraw ..\\pngsuite\\basn3p04.png basn3p04.ppm\npng2pnm.exe -noraw ..\\pngsuite\\basn3p08.png basn3p08.ppm\nREM -- gray with alpha-channel\npng2pnm.exe -noraw ..\\pngsuite\\basn4a08.png basn4a08.pgm\npng2pnm.exe -noraw ..\\pngsuite\\basn4a16.png basn4a16.pgm\nREM -- color with alpha-channel\npng2pnm.exe -noraw -alpha basn6a08.pgm ..\\pngsuite\\basn6a08.png basn6a08.ppm\npng2pnm.exe -noraw -alpha basn6a16.pgm ..\\pngsuite\\basn6a16.png basn6a16.ppm\nREM -- grayscale\npng2pnm.exe -raw ..\\pngsuite\\basn0g01.png rawn0g01.pgm\npng2pnm.exe -raw ..\\pngsuite\\basn0g02.png rawn0g02.pgm\npng2pnm.exe -raw ..\\pngsuite\\basn0g04.png rawn0g04.pgm\npng2pnm.exe -raw ..\\pngsuite\\basn0g08.png rawn0g08.pgm\npng2pnm.exe -raw ..\\pngsuite\\basn0g16.png rawn0g16.pgm\nREM -- full-color\npng2pnm.exe -raw ..\\pngsuite\\basn2c08.png rawn2c08.ppm\npng2pnm.exe -raw ..\\pngsuite\\basn2c16.png rawn2c16.ppm\nREM -- palletted\npng2pnm.exe -raw ..\\pngsuite\\basn3p01.png rawn3p01.ppm\npng2pnm.exe -raw ..\\pngsuite\\basn3p02.png rawn3p02.ppm\npng2pnm.exe -raw ..\\pngsuite\\basn3p04.png rawn3p04.ppm\npng2pnm.exe -raw ..\\pngsuite\\basn3p08.png rawn3p08.ppm\nREM -- gray with alpha-channel\npng2pnm.exe -raw ..\\pngsuite\\basn4a08.png rawn4a08.pgm\npng2pnm.exe -raw ..\\pngsuite\\basn4a16.png rawn4a16.pgm\nREM -- color with alpha-channel\npng2pnm.exe -noraw -alpha rawn6a08.pgm ..\\pngsuite\\basn6a08.png rawn6a08.ppm\npng2pnm.exe -noraw -alpha rawn6a16.pgm ..\\pngsuite\\basn6a16.png rawn6a16.ppm\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminus/png2pnm.c",
    "content": "/*\n *  png2pnm.c --- conversion from PNG-file to PGM/PPM-file\n *  copyright (C) 1999 by Willem van Schaik <willem@schaik.com>\n *\n *  version 1.0 - 1999.10.15 - First version.\n *\n *  Permission to use, copy, modify, and distribute this software and\n *  its documentation for any purpose and without fee is hereby granted,\n *  provided that the above copyright notice appear in all copies and\n *  that both that copyright notice and this permission notice appear in\n *  supporting documentation. This software is provided \"as is\" without\n *  express or implied warranty.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#ifdef __TURBOC__\n#include <mem.h>\n#include <fcntl.h>\n#endif\n#include <zlib.h>\n\n#ifndef BOOL\n#define BOOL unsigned char\n#endif\n#ifndef TRUE\n#define TRUE (BOOL) 1\n#endif\n#ifndef FALSE\n#define FALSE (BOOL) 0\n#endif\n\n#ifdef __TURBOC__\n#define STDIN  0\n#define STDOUT 1\n#define STDERR 2\n#endif\n\n/* to make png2pnm verbose so we can find problems (needs to be before png.h) */\n#ifndef PNG_DEBUG\n#define PNG_DEBUG 0\n#endif\n\n#include \"png.h\"\n\n/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */\n#ifndef png_jmpbuf\n#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)\n#endif\n\n/* function prototypes */\n\nint  main (int argc, char *argv[]);\nvoid usage ();\nBOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw,\n   BOOL alpha);\n\n/*\n *  main\n */\n\nint main(int argc, char *argv[])\n{\n  FILE *fp_rd = stdin;\n  FILE *fp_wr = stdout;\n  FILE *fp_al = NULL;\n  BOOL raw = TRUE;\n  BOOL alpha = FALSE;\n  int argi;\n\n  for (argi = 1; argi < argc; argi++)\n  {\n    if (argv[argi][0] == '-')\n    {\n      switch (argv[argi][1])\n      {\n        case 'n':\n          raw = FALSE;\n          break;\n        case 'r':\n          raw = TRUE;\n          break;\n        case 'a':\n          alpha = TRUE;\n          argi++;\n          if ((fp_al = fopen (argv[argi], \"wb\")) == NULL)\n          {\n            fprintf (stderr, \"PNM2PNG\\n\");\n            fprintf (stderr, \"Error:  can not create alpha-channel file %s\\n\",\n               argv[argi]);\n            exit (1);\n          }\n          break;\n        case 'h':\n        case '?':\n          usage();\n          exit(0);\n          break;\n        default:\n          fprintf (stderr, \"PNG2PNM\\n\");\n          fprintf (stderr, \"Error:  unknown option %s\\n\", argv[argi]);\n          usage();\n          exit(1);\n          break;\n      } /* end switch */\n    }\n    else if (fp_rd == stdin)\n    {\n      if ((fp_rd = fopen (argv[argi], \"rb\")) == NULL)\n      {\n             fprintf (stderr, \"PNG2PNM\\n\");\n            fprintf (stderr, \"Error:  file %s does not exist\\n\", argv[argi]);\n            exit (1);\n      }\n    }\n    else if (fp_wr == stdout)\n    {\n      if ((fp_wr = fopen (argv[argi], \"wb\")) == NULL)\n      {\n        fprintf (stderr, \"PNG2PNM\\n\");\n        fprintf (stderr, \"Error:  can not create file %s\\n\", argv[argi]);\n        exit (1);\n      }\n    }\n    else\n    {\n      fprintf (stderr, \"PNG2PNM\\n\");\n      fprintf (stderr, \"Error:  too many parameters\\n\");\n      usage();\n      exit(1);\n    }\n  } /* end for */\n\n#ifdef __TURBOC__\n  /* set stdin/stdout if required to binary */\n  if (fp_rd == stdin)\n  {\n    setmode (STDIN, O_BINARY);\n  }\n  if ((raw) && (fp_wr == stdout))\n  {\n    setmode (STDOUT, O_BINARY);\n  }\n#endif\n\n  /* call the conversion program itself */\n  if (png2pnm (fp_rd, fp_wr, fp_al, raw, alpha) == FALSE)\n  {\n    fprintf (stderr, \"PNG2PNM\\n\");\n    fprintf (stderr, \"Error:  unsuccessful conversion of PNG-image\\n\");\n    exit(1);\n  }\n\n  /* close input file */\n  fclose (fp_rd);\n  /* close output file */\n  fclose (fp_wr);\n  /* close alpha file */\n  if (alpha)\n    fclose (fp_al);\n\n  return 0;\n}\n\n/*\n *  usage\n */\n\nvoid usage()\n{\n  fprintf (stderr, \"PNG2PNM\\n\");\n  fprintf (stderr, \"   by Willem van Schaik, 1999\\n\");\n#ifdef __TURBOC__\n  fprintf (stderr, \"   for Turbo-C and Borland-C compilers\\n\");\n#else\n  fprintf (stderr, \"   for Linux (and Unix) compilers\\n\");\n#endif\n  fprintf (stderr, \"Usage:  png2pnm [options] <file>.png [<file>.pnm]\\n\");\n  fprintf (stderr, \"   or:  ... | png2pnm [options]\\n\");\n  fprintf (stderr, \"Options:\\n\");\n  fprintf (stderr,\n     \"   -r[aw]   write pnm-file in binary format (P4/P5/P6) (default)\\n\");\n  fprintf (stderr, \"   -n[oraw] write pnm-file in ascii format (P1/P2/P3)\\n\");\n  fprintf (stderr,\n     \"   -a[lpha] <file>.pgm write PNG alpha channel as pgm-file\\n\");\n  fprintf (stderr, \"   -h | -?  print this help-information\\n\");\n}\n\n/*\n *  png2pnm\n */\n\nBOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,\n    volatile BOOL raw, BOOL alpha)\n{\n  png_struct    *png_ptr = NULL;\n  png_info        *info_ptr = NULL;\n  png_byte      buf[8];\n  png_byte      *png_pixels = NULL;\n  png_byte      **row_pointers = NULL;\n  png_byte      *pix_ptr = NULL;\n  png_uint_32   row_bytes;\n\n  png_uint_32   width;\n  png_uint_32   height;\n  int           bit_depth;\n  int           channels;\n  int           color_type;\n  int           alpha_present;\n  int           row, col;\n  int           ret;\n  int           i;\n  long          dep_16;\n\n  /* read and check signature in PNG file */\n  ret = fread (buf, 1, 8, png_file);\n  if (ret != 8)\n    return FALSE;\n\n  ret = png_sig_cmp (buf, 0, 8);\n  if (ret)\n    return FALSE;\n\n  /* create png and info structures */\n\n  png_ptr = png_create_read_struct (png_get_libpng_ver(NULL),\n    NULL, NULL, NULL);\n  if (!png_ptr)\n    return FALSE;   /* out of memory */\n\n  info_ptr = png_create_info_struct (png_ptr);\n  if (!info_ptr)\n  {\n    png_destroy_read_struct (&png_ptr, NULL, NULL);\n    return FALSE;   /* out of memory */\n  }\n\n  if (setjmp (png_jmpbuf(png_ptr)))\n  {\n    png_destroy_read_struct (&png_ptr, &info_ptr, NULL);\n    return FALSE;\n  }\n\n  /* set up the input control for C streams */\n  png_init_io (png_ptr, png_file);\n  png_set_sig_bytes (png_ptr, 8);  /* we already read the 8 signature bytes */\n\n  /* read the file information */\n  png_read_info (png_ptr, info_ptr);\n\n  /* get size and bit-depth of the PNG-image */\n  png_get_IHDR (png_ptr, info_ptr,\n    &width, &height, &bit_depth, &color_type,\n    NULL, NULL, NULL);\n\n  /* set-up the transformations */\n\n  /* transform paletted images into full-color rgb */\n  if (color_type == PNG_COLOR_TYPE_PALETTE)\n    png_set_expand (png_ptr);\n  /* expand images to bit-depth 8 (only applicable for grayscale images) */\n  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)\n    png_set_expand (png_ptr);\n  /* transform transparency maps into full alpha-channel */\n  if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))\n    png_set_expand (png_ptr);\n\n#ifdef NJET\n  /* downgrade 16-bit images to 8-bit */\n  if (bit_depth == 16)\n    png_set_strip_16 (png_ptr);\n  /* transform grayscale images into full-color */\n  if (color_type == PNG_COLOR_TYPE_GRAY ||\n    color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n    png_set_gray_to_rgb (png_ptr);\n  /* only if file has a file gamma, we do a correction */\n  if (png_get_gAMA (png_ptr, info_ptr, &file_gamma))\n    png_set_gamma (png_ptr, (double) 2.2, file_gamma);\n#endif\n\n  /* all transformations have been registered; now update info_ptr data,\n   * get rowbytes and channels, and allocate image memory */\n\n  png_read_update_info (png_ptr, info_ptr);\n\n  /* get the new color-type and bit-depth (after expansion/stripping) */\n  png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,\n    NULL, NULL, NULL);\n\n  /* check for 16-bit files */\n  if (bit_depth == 16)\n  {\n    raw = FALSE;\n#ifdef __TURBOC__\n    pnm_file->flags &= ~((unsigned) _F_BIN);\n#endif\n  }\n\n  /* calculate new number of channels and store alpha-presence */\n  if (color_type == PNG_COLOR_TYPE_GRAY)\n    channels = 1;\n  else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n    channels = 2;\n  else if (color_type == PNG_COLOR_TYPE_RGB)\n    channels = 3;\n  else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n    channels = 4;\n  else\n    channels = 0; /* should never happen */\n  alpha_present = (channels - 1) % 2;\n\n  /* check if alpha is expected to be present in file */\n  if (alpha && !alpha_present)\n  {\n    fprintf (stderr, \"PNG2PNM\\n\");\n    fprintf (stderr, \"Error:  PNG-file doesn't contain alpha channel\\n\");\n    exit (1);\n  }\n\n  /* row_bytes is the width x number of channels x (bit-depth / 8) */\n  row_bytes = png_get_rowbytes (png_ptr, info_ptr);\n\n  if ((png_pixels = (png_byte *)\n     malloc (row_bytes * height * sizeof (png_byte))) == NULL) {\n    png_destroy_read_struct (&png_ptr, &info_ptr, NULL);\n    return FALSE;\n  }\n\n  if ((row_pointers = (png_byte **)\n     malloc (height * sizeof (png_bytep))) == NULL)\n  {\n    png_destroy_read_struct (&png_ptr, &info_ptr, NULL);\n    free (png_pixels);\n    png_pixels = NULL;\n    return FALSE;\n  }\n\n  /* set the individual row_pointers to point at the correct offsets */\n  for (i = 0; i < ((int) height); i++)\n    row_pointers[i] = png_pixels + i * row_bytes;\n\n  /* now we can go ahead and just read the whole image */\n  png_read_image (png_ptr, row_pointers);\n\n  /* read rest of file, and get additional chunks in info_ptr - REQUIRED */\n  png_read_end (png_ptr, info_ptr);\n\n  /* clean up after the read, and free any memory allocated - REQUIRED */\n  png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp) NULL);\n\n  /* write header of PNM file */\n\n  if ((color_type == PNG_COLOR_TYPE_GRAY) ||\n      (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))\n  {\n    fprintf (pnm_file, \"%s\\n\", (raw) ? \"P5\" : \"P2\");\n    fprintf (pnm_file, \"%d %d\\n\", (int) width, (int) height);\n    fprintf (pnm_file, \"%ld\\n\", ((1L << (int) bit_depth) - 1L));\n  }\n  else if ((color_type == PNG_COLOR_TYPE_RGB) ||\n           (color_type == PNG_COLOR_TYPE_RGB_ALPHA))\n  {\n    fprintf (pnm_file, \"%s\\n\", (raw) ? \"P6\" : \"P3\");\n    fprintf (pnm_file, \"%d %d\\n\", (int) width, (int) height);\n    fprintf (pnm_file, \"%ld\\n\", ((1L << (int) bit_depth) - 1L));\n  }\n\n  /* write header of PGM file with alpha channel */\n\n  if ((alpha) &&\n      ((color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||\n       (color_type == PNG_COLOR_TYPE_RGB_ALPHA)))\n  {\n    fprintf (alpha_file, \"%s\\n\", (raw) ? \"P5\" : \"P2\");\n    fprintf (alpha_file, \"%d %d\\n\", (int) width, (int) height);\n    fprintf (alpha_file, \"%ld\\n\", ((1L << (int) bit_depth) - 1L));\n  }\n\n  /* write data to PNM file */\n  pix_ptr = png_pixels;\n\n  for (row = 0; row < (int) height; row++)\n  {\n    for (col = 0; col < (int) width; col++)\n    {\n      for (i = 0; i < (channels - alpha_present); i++)\n      {\n        if (raw)\n          fputc ((int) *pix_ptr++ , pnm_file);\n        else\n          if (bit_depth == 16){\n            dep_16 = (long) *pix_ptr++;\n            fprintf (pnm_file, \"%ld \", (dep_16 << 8) + ((long) *pix_ptr++));\n          }\n          else\n            fprintf (pnm_file, \"%ld \", (long) *pix_ptr++);\n      }\n      if (alpha_present)\n      {\n        if (!alpha)\n        {\n          pix_ptr++; /* alpha */\n          if (bit_depth == 16)\n            pix_ptr++;\n        }\n        else /* output alpha-channel as pgm file */\n        {\n          if (raw)\n            fputc ((int) *pix_ptr++ , alpha_file);\n          else\n            if (bit_depth == 16){\n              dep_16 = (long) *pix_ptr++;\n              fprintf (alpha_file, \"%ld \", (dep_16 << 8) + (long) *pix_ptr++);\n            }\n            else\n              fprintf (alpha_file, \"%ld \", (long) *pix_ptr++);\n        }\n      } /* if alpha_present */\n\n      if (!raw)\n        if (col % 4 == 3)\n          fprintf (pnm_file, \"\\n\");\n    } /* end for col */\n\n    if (!raw)\n      if (col % 4 != 0)\n        fprintf (pnm_file, \"\\n\");\n  } /* end for row */\n\n  if (row_pointers != (unsigned char**) NULL)\n    free (row_pointers);\n  if (png_pixels != (unsigned char*) NULL)\n    free (png_pixels);\n\n  return TRUE;\n\n} /* end of source */\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminus/png2pnm.sh",
    "content": "#!/bin/sh\n# -- grayscale\n./png2pnm -noraw ../pngsuite/basn0g01.png basn0g01.pgm\n./png2pnm -noraw ../pngsuite/basn0g02.png basn0g02.pgm\n./png2pnm -noraw ../pngsuite/basn0g04.png basn0g04.pgm\n./png2pnm -noraw ../pngsuite/basn0g08.png basn0g08.pgm\n./png2pnm -noraw ../pngsuite/basn0g16.png basn0g16.pgm\n# -- full-color\n./png2pnm -noraw ../pngsuite/basn2c08.png basn2c08.ppm\n./png2pnm -noraw ../pngsuite/basn2c16.png basn2c16.ppm\n# -- palletted\n./png2pnm -noraw ../pngsuite/basn3p01.png basn3p01.ppm\n./png2pnm -noraw ../pngsuite/basn3p02.png basn3p02.ppm\n./png2pnm -noraw ../pngsuite/basn3p04.png basn3p04.ppm\n./png2pnm -noraw ../pngsuite/basn3p08.png basn3p08.ppm\n# -- gray with alpha-channel\n./png2pnm -noraw ../pngsuite/basn4a08.png basn4a08.pgm\n./png2pnm -noraw ../pngsuite/basn4a16.png basn4a16.pgm\n# -- color with alpha-channel\n./png2pnm -noraw -alpha basn6a08.pgm ../pngsuite/basn6a08.png basn6a08.ppm\n./png2pnm -noraw -alpha basn6a16.pgm ../pngsuite/basn6a16.png basn6a16.ppm\n# -- grayscale\n./png2pnm -raw ../pngsuite/basn0g01.png rawn0g01.pgm\n./png2pnm -raw ../pngsuite/basn0g02.png rawn0g02.pgm\n./png2pnm -raw ../pngsuite/basn0g04.png rawn0g04.pgm\n./png2pnm -raw ../pngsuite/basn0g08.png rawn0g08.pgm\n./png2pnm -raw ../pngsuite/basn0g16.png rawn0g16.pgm\n# -- full-color\n./png2pnm -raw ../pngsuite/basn2c08.png rawn2c08.ppm\n./png2pnm -raw ../pngsuite/basn2c16.png rawn2c16.ppm\n# -- palletted\n./png2pnm -raw ../pngsuite/basn3p01.png rawn3p01.ppm\n./png2pnm -raw ../pngsuite/basn3p02.png rawn3p02.ppm\n./png2pnm -raw ../pngsuite/basn3p04.png rawn3p04.ppm\n./png2pnm -raw ../pngsuite/basn3p08.png rawn3p08.ppm\n# -- gray with alpha-channel\n./png2pnm -raw ../pngsuite/basn4a08.png rawn4a08.pgm\n./png2pnm -raw ../pngsuite/basn4a16.png rawn4a16.pgm\n# -- color with alpha-channel\n./png2pnm -noraw -alpha rawn6a08.pgm ../pngsuite/basn6a08.png rawn6a08.ppm\n./png2pnm -noraw -alpha rawn6a16.pgm ../pngsuite/basn6a16.png rawn6a16.ppm\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminus/pngminus.bat",
    "content": "make -f makefile.tc3\ncall png2pnm.bat\ncall pnm2png.bat\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminus/pngminus.sh",
    "content": "#!/bin/sh\nmake -f makefile.std\nsh png2pnm.sh\nsh pnm2png.sh\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminus/pnm2png.bat",
    "content": "REM -- grayscale\npnm2png.exe basn0g01.pgm basn0g01.png\npnm2png.exe basn0g02.pgm basn0g02.png\npnm2png.exe basn0g04.pgm basn0g04.png\npnm2png.exe basn0g08.pgm basn0g08.png\npnm2png.exe basn0g16.pgm basn0g16.png\nREM -- full-color\npnm2png.exe basn2c08.ppm basn2c08.png\npnm2png.exe basn2c16.ppm basn2c16.png\nREM -- palletted\npnm2png.exe basn3p01.ppm basn3p01.png\npnm2png.exe basn3p02.ppm basn3p02.png\npnm2png.exe basn3p04.ppm basn3p04.png\npnm2png.exe basn3p08.ppm basn3p08.png\nREM -- gray with alpha-channel\npnm2png.exe -alpha basn6a08.pgm basn4a08.pgm basn4a08.png\npnm2png.exe -alpha basn6a16.pgm basn4a16.pgm basn4a16.png\nREM -- color with alpha-channel\npnm2png.exe -alpha basn6a08.pgm basn6a08.ppm basn6a08.png\npnm2png.exe -alpha basn6a16.pgm basn6a16.ppm basn6a16.png\nREM -- grayscale\npnm2png.exe rawn0g01.pgm rawn0g01.png\npnm2png.exe rawn0g02.pgm rawn0g02.png\npnm2png.exe rawn0g04.pgm rawn0g04.png\npnm2png.exe rawn0g08.pgm rawn0g08.png\npnm2png.exe rawn0g16.pgm rawn0g16.png\nREM -- full-color\npnm2png.exe rawn2c08.ppm rawn2c08.png\npnm2png.exe rawn2c16.ppm rawn2c16.png\nREM -- palletted\npnm2png.exe rawn3p01.ppm rawn3p01.png\npnm2png.exe rawn3p02.ppm rawn3p02.png\npnm2png.exe rawn3p04.ppm rawn3p04.png\npnm2png.exe rawn3p08.ppm rawn3p08.png\nREM -- gray with alpha-channel\npnm2png.exe -alpha rawn6a08.pgm rawn4a08.pgm rawn4a08.png\npnm2png.exe -alpha rawn6a16.pgm rawn4a16.pgm rawn4a16.png\nREM -- color with alpha-channel\npnm2png.exe -alpha rawn6a08.pgm rawn6a08.ppm rawn6a08.png\npnm2png.exe -alpha rawn6a16.pgm rawn6a16.ppm rawn6a16.png\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminus/pnm2png.c",
    "content": "/*\n *  pnm2png.c --- conversion from PBM/PGM/PPM-file to PNG-file\n *  copyright (C) 1999 by Willem van Schaik <willem@schaik.com>\n *\n *  version 1.0 - 1999.10.15 - First version.\n *  version 1.1 - 2015.07.29 - Fixed leaks (Glenn Randers-Pehrson)\n *\n *  Permission to use, copy, modify, and distribute this software and\n *  its documentation for any purpose and without fee is hereby granted,\n *  provided that the above copyright notice appear in all copies and\n *  that both that copyright notice and this permission notice appear in\n *  supporting documentation. This software is provided \"as is\" without\n *  express or implied warranty.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#ifdef __TURBOC__\n#include <mem.h>\n#include <fcntl.h>\n#endif\n#include <zlib.h>\n\n#ifndef BOOL\n#define BOOL unsigned char\n#endif\n#ifndef TRUE\n#define TRUE (BOOL) 1\n#endif\n#ifndef FALSE\n#define FALSE (BOOL) 0\n#endif\n\n#define STDIN  0\n#define STDOUT 1\n#define STDERR 2\n\n/* to make pnm2png verbose so we can find problems (needs to be before png.h) */\n#ifndef PNG_DEBUG\n#define PNG_DEBUG 0\n#endif\n\n#include \"png.h\"\n\n/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */\n#ifndef png_jmpbuf\n#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)\n#endif\n\n/* function prototypes */\n\nint  main (int argc, char *argv[]);\nvoid usage ();\nBOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,\n    BOOL alpha);\nvoid get_token(FILE *pnm_file, char *token);\npng_uint_32 get_data (FILE *pnm_file, int depth);\npng_uint_32 get_value (FILE *pnm_file, int depth);\n\n/*\n *  main\n */\n\nint main(int argc, char *argv[])\n{\n  FILE *fp_rd = stdin;\n  FILE *fp_al = NULL;\n  FILE *fp_wr = stdout;\n  BOOL interlace = FALSE;\n  BOOL alpha = FALSE;\n  int argi;\n\n  for (argi = 1; argi < argc; argi++)\n  {\n    if (argv[argi][0] == '-')\n    {\n      switch (argv[argi][1])\n      {\n        case 'i':\n          interlace = TRUE;\n          break;\n        case 'a':\n          alpha = TRUE;\n          argi++;\n          if ((fp_al = fopen (argv[argi], \"rb\")) == NULL)\n          {\n            fprintf (stderr, \"PNM2PNG\\n\");\n            fprintf (stderr, \"Error:  alpha-channel file %s does not exist\\n\",\n               argv[argi]);\n            exit (1);\n          }\n          break;\n        case 'h':\n        case '?':\n          usage();\n          exit(0);\n          break;\n        default:\n          fprintf (stderr, \"PNM2PNG\\n\");\n          fprintf (stderr, \"Error:  unknown option %s\\n\", argv[argi]);\n          usage();\n          exit(1);\n          break;\n      } /* end switch */\n    }\n    else if (fp_rd == stdin)\n    {\n      if ((fp_rd = fopen (argv[argi], \"rb\")) == NULL)\n      {\n        fprintf (stderr, \"PNM2PNG\\n\");\n        fprintf (stderr, \"Error:  file %s does not exist\\n\", argv[argi]);\n        exit (1);\n      }\n    }\n    else if (fp_wr == stdout)\n    {\n      if ((fp_wr = fopen (argv[argi], \"wb\")) == NULL)\n      {\n        fprintf (stderr, \"PNM2PNG\\n\");\n        fprintf (stderr, \"Error:  can not create PNG-file %s\\n\", argv[argi]);\n        exit (1);\n      }\n    }\n    else\n    {\n      fprintf (stderr, \"PNM2PNG\\n\");\n      fprintf (stderr, \"Error:  too many parameters\\n\");\n      usage();\n      exit (1);\n    }\n  } /* end for */\n\n#ifdef __TURBOC__\n  /* set stdin/stdout to binary, we're reading the PNM always! in binary format */\n  if (fp_rd == stdin)\n  {\n    setmode (STDIN, O_BINARY);\n  }\n  if (fp_wr == stdout)\n  {\n    setmode (STDOUT, O_BINARY);\n  }\n#endif\n\n  /* call the conversion program itself */\n  if (pnm2png (fp_rd, fp_wr, fp_al, interlace, alpha) == FALSE)\n  {\n    fprintf (stderr, \"PNM2PNG\\n\");\n    fprintf (stderr, \"Error:  unsuccessful converting to PNG-image\\n\");\n    exit (1);\n  }\n\n  /* close input file */\n  fclose (fp_rd);\n  /* close output file */\n  fclose (fp_wr);\n  /* close alpha file */\n  if (alpha)\n    fclose (fp_al);\n\n  return 0;\n}\n\n/*\n *  usage\n */\n\nvoid usage()\n{\n  fprintf (stderr, \"PNM2PNG\\n\");\n  fprintf (stderr, \"   by Willem van Schaik, 1999\\n\");\n#ifdef __TURBOC__\n  fprintf (stderr, \"   for Turbo-C and Borland-C compilers\\n\");\n#else\n  fprintf (stderr, \"   for Linux (and Unix) compilers\\n\");\n#endif\n  fprintf (stderr, \"Usage:  pnm2png [options] <file>.<pnm> [<file>.png]\\n\");\n  fprintf (stderr, \"   or:  ... | pnm2png [options]\\n\");\n  fprintf (stderr, \"Options:\\n\");\n  fprintf (stderr, \"   -i[nterlace]   write png-file with interlacing on\\n\");\n  fprintf (stderr,\n      \"   -a[lpha] <file>.pgm read PNG alpha channel as pgm-file\\n\");\n  fprintf (stderr, \"   -h | -?  print this help-information\\n\");\n}\n\n/*\n *  pnm2png\n */\n\nBOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,\n     BOOL alpha)\n{\n  png_struct    *png_ptr = NULL;\n  png_info      *info_ptr = NULL;\n  png_byte      *png_pixels = NULL;\n  png_byte      **row_pointers = NULL;\n  png_byte      *pix_ptr = NULL;\n  volatile png_uint_32   row_bytes;\n\n  char          type_token[16];\n  char          width_token[16];\n  char          height_token[16];\n  char          maxval_token[16];\n  volatile int    color_type=1;\n  unsigned long   ul_width=0, ul_alpha_width=0;\n  unsigned long   ul_height=0, ul_alpha_height=0;\n  unsigned long   ul_maxval=0;\n  volatile png_uint_32   width=0, height=0;\n  volatile png_uint_32   alpha_width=0, alpha_height=0;\n  png_uint_32   maxval;\n  volatile int           bit_depth = 0;\n  int           channels=0;\n  int           alpha_depth = 0;\n  int           alpha_present=0;\n  int           row, col;\n  BOOL          raw, alpha_raw = FALSE;\n#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)\n  BOOL          packed_bitmap = FALSE;\n#endif\n  png_uint_32   tmp16;\n  int           i;\n\n  /* read header of PNM file */\n\n  get_token(pnm_file, type_token);\n  if (type_token[0] != 'P')\n  {\n    return FALSE;\n  }\n  else if ((type_token[1] == '1') || (type_token[1] == '4'))\n  {\n#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)\n    raw = (type_token[1] == '4');\n    color_type = PNG_COLOR_TYPE_GRAY;\n    get_token(pnm_file, width_token);\n    sscanf (width_token, \"%lu\", &ul_width);\n    width = (png_uint_32) ul_width;\n    get_token(pnm_file, height_token);\n    sscanf (height_token, \"%lu\", &ul_height);\n    height = (png_uint_32) ul_height;\n    bit_depth = 1;\n    packed_bitmap = TRUE;\n#else\n    fprintf (stderr, \"PNM2PNG built without PNG_WRITE_INVERT_SUPPORTED and \\n\");\n    fprintf (stderr, \"PNG_WRITE_PACK_SUPPORTED can't read PBM (P1,P4) files\\n\");\n#endif\n  }\n  else if ((type_token[1] == '2') || (type_token[1] == '5'))\n  {\n    raw = (type_token[1] == '5');\n    color_type = PNG_COLOR_TYPE_GRAY;\n    get_token(pnm_file, width_token);\n    sscanf (width_token, \"%lu\", &ul_width);\n    width = (png_uint_32) ul_width;\n    get_token(pnm_file, height_token);\n    sscanf (height_token, \"%lu\", &ul_height);\n    height = (png_uint_32) ul_height;\n    get_token(pnm_file, maxval_token);\n    sscanf (maxval_token, \"%lu\", &ul_maxval);\n    maxval = (png_uint_32) ul_maxval;\n\n    if (maxval <= 1)\n      bit_depth = 1;\n    else if (maxval <= 3)\n      bit_depth = 2;\n    else if (maxval <= 15)\n      bit_depth = 4;\n    else if (maxval <= 255)\n      bit_depth = 8;\n    else /* if (maxval <= 65535) */\n      bit_depth = 16;\n  }\n  else if ((type_token[1] == '3') || (type_token[1] == '6'))\n  {\n    raw = (type_token[1] == '6');\n    color_type = PNG_COLOR_TYPE_RGB;\n    get_token(pnm_file, width_token);\n    sscanf (width_token, \"%lu\", &ul_width);\n    width = (png_uint_32) ul_width;\n    get_token(pnm_file, height_token);\n    sscanf (height_token, \"%lu\", &ul_height);\n    height = (png_uint_32) ul_height;\n    get_token(pnm_file, maxval_token);\n    sscanf (maxval_token, \"%lu\", &ul_maxval);\n    maxval = (png_uint_32) ul_maxval;\n    if (maxval <= 1)\n      bit_depth = 1;\n    else if (maxval <= 3)\n      bit_depth = 2;\n    else if (maxval <= 15)\n      bit_depth = 4;\n    else if (maxval <= 255)\n      bit_depth = 8;\n    else /* if (maxval <= 65535) */\n      bit_depth = 16;\n  }\n  else\n  {\n    return FALSE;\n  }\n\n  /* read header of PGM file with alpha channel */\n\n  if (alpha)\n  {\n    if (color_type == PNG_COLOR_TYPE_GRAY)\n      color_type = PNG_COLOR_TYPE_GRAY_ALPHA;\n    if (color_type == PNG_COLOR_TYPE_RGB)\n      color_type = PNG_COLOR_TYPE_RGB_ALPHA;\n\n    get_token(alpha_file, type_token);\n    if (type_token[0] != 'P')\n    {\n      return FALSE;\n    }\n    else if ((type_token[1] == '2') || (type_token[1] == '5'))\n    {\n      alpha_raw = (type_token[1] == '5');\n      get_token(alpha_file, width_token);\n      sscanf (width_token, \"%lu\", &ul_alpha_width);\n      alpha_width=(png_uint_32) ul_alpha_width;\n      if (alpha_width != width)\n        return FALSE;\n      get_token(alpha_file, height_token);\n      sscanf (height_token, \"%lu\", &ul_alpha_height);\n      alpha_height = (png_uint_32) ul_alpha_height;\n      if (alpha_height != height)\n        return FALSE;\n      get_token(alpha_file, maxval_token);\n      sscanf (maxval_token, \"%lu\", &ul_maxval);\n      maxval = (png_uint_32) ul_maxval;\n      if (maxval <= 1)\n        alpha_depth = 1;\n      else if (maxval <= 3)\n        alpha_depth = 2;\n      else if (maxval <= 15)\n        alpha_depth = 4;\n      else if (maxval <= 255)\n        alpha_depth = 8;\n      else /* if (maxval <= 65535) */\n        alpha_depth = 16;\n      if (alpha_depth != bit_depth)\n        return FALSE;\n    }\n    else\n    {\n      return FALSE;\n    }\n  } /* end if alpha */\n\n  /* calculate the number of channels and store alpha-presence */\n  if (color_type == PNG_COLOR_TYPE_GRAY)\n    channels = 1;\n  else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n    channels = 2;\n  else if (color_type == PNG_COLOR_TYPE_RGB)\n    channels = 3;\n  else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n    channels = 4;\n#if 0\n  else\n    channels = 0; /* cannot happen */\n#endif\n\n  alpha_present = (channels - 1) % 2;\n\n#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)\n  if (packed_bitmap)\n    /* row data is as many bytes as can fit width x channels x bit_depth */\n    row_bytes = (width * channels * bit_depth + 7) / 8;\n  else\n#endif\n    /* row_bytes is the width x number of channels x (bit-depth / 8) */\n    row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);\n\n  if ((png_pixels = (png_byte *)\n     malloc (row_bytes * height * sizeof (png_byte))) == NULL)\n    return FALSE;\n\n  /* read data from PNM file */\n  pix_ptr = png_pixels;\n\n  for (row = 0; row < (int) height; row++)\n  {\n#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)\n    if (packed_bitmap) {\n      for (i = 0; i < (int) row_bytes; i++)\n        /* png supports this format natively so no conversion is needed */\n        *pix_ptr++ = get_data (pnm_file, 8);\n    } else\n#endif\n    {\n      for (col = 0; col < (int) width; col++)\n      {\n        for (i = 0; i < (channels - alpha_present); i++)\n        {\n          if (raw)\n            *pix_ptr++ = get_data (pnm_file, bit_depth);\n          else\n            if (bit_depth <= 8)\n              *pix_ptr++ = get_value (pnm_file, bit_depth);\n            else\n            {\n              tmp16 = get_value (pnm_file, bit_depth);\n              *pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF);\n              pix_ptr++;\n              *pix_ptr = (png_byte) (tmp16 & 0xFF);\n              pix_ptr++;\n            }\n        }\n\n        if (alpha) /* read alpha-channel from pgm file */\n        {\n          if (alpha_raw)\n            *pix_ptr++ = get_data (alpha_file, alpha_depth);\n          else\n            if (alpha_depth <= 8)\n              *pix_ptr++ = get_value (alpha_file, bit_depth);\n            else\n            {\n              tmp16 = get_value (alpha_file, bit_depth);\n              *pix_ptr++ = (png_byte) ((tmp16 >> 8) & 0xFF);\n              *pix_ptr++ = (png_byte) (tmp16 & 0xFF);\n            }\n        } /* if alpha */\n      } /* if packed_bitmap */\n    } /* end for col */\n  } /* end for row */\n\n  /* prepare the standard PNG structures */\n  png_ptr = png_create_write_struct (png_get_libpng_ver(NULL), NULL, NULL,\n      NULL);\n  if (!png_ptr)\n  {\n    free (png_pixels);\n    png_pixels = NULL;\n    return FALSE;\n  }\n  info_ptr = png_create_info_struct (png_ptr);\n  if (!info_ptr)\n  {\n    png_destroy_write_struct (&png_ptr, (png_infopp) NULL);\n    free (png_pixels);\n    png_pixels = NULL;\n    return FALSE;\n  }\n\n#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)\n  if (packed_bitmap == TRUE)\n  {\n    png_set_packing (png_ptr);\n    png_set_invert_mono (png_ptr);\n  }\n#endif\n\n  /* setjmp() must be called in every function that calls a PNG-reading libpng function */\n  if (setjmp (png_jmpbuf(png_ptr)))\n  {\n    png_destroy_write_struct (&png_ptr, &info_ptr);\n    free (png_pixels);\n    png_pixels = NULL;\n    return FALSE;\n  }\n\n  /* initialize the png structure */\n  png_init_io (png_ptr, png_file);\n\n  /* we're going to write more or less the same PNG as the input file */\n  png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type,\n    (!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7,\n    PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);\n\n  /* write the file header information */\n  png_write_info (png_ptr, info_ptr);\n\n  /* if needed we will allocate memory for an new array of row-pointers */\n  if (row_pointers == (unsigned char**) NULL)\n  {\n    if ((row_pointers = (png_byte **)\n        malloc (height * sizeof (png_bytep))) == NULL)\n    {\n      png_destroy_write_struct (&png_ptr, &info_ptr);\n      free (png_pixels);\n      png_pixels = NULL;\n      return FALSE;\n    }\n  }\n\n  /* set the individual row_pointers to point at the correct offsets */\n  for (i = 0; i < (int) height; i++)\n    row_pointers[i] = png_pixels + i * row_bytes;\n\n  /* write out the entire image data in one call */\n  png_write_image (png_ptr, row_pointers);\n\n  /* write the additional chunks to the PNG file (not really needed) */\n  png_write_end (png_ptr, info_ptr);\n\n  /* clean up after the write, and free any memory allocated */\n  png_destroy_write_struct (&png_ptr, &info_ptr);\n\n  if (row_pointers != (unsigned char**) NULL)\n    free (row_pointers);\n  if (png_pixels != (unsigned char*) NULL)\n    free (png_pixels);\n\n  return TRUE;\n} /* end of pnm2png */\n\n/*\n * get_token() - gets the first string after whitespace\n */\n\nvoid get_token(FILE *pnm_file, char *token)\n{\n  int i = 0;\n  int ret;\n\n  /* remove white-space and comment lines */\n  do\n  {\n    ret = fgetc(pnm_file);\n    if (ret == '#') {\n      /* the rest of this line is a comment */\n      do\n      {\n        ret = fgetc(pnm_file);\n      }\n      while ((ret != '\\n') && (ret != '\\r') && (ret != EOF));\n    }\n    if (ret == EOF) break;\n    token[i] = (unsigned char) ret;\n  }\n  while ((token[i] == '\\n') || (token[i] == '\\r') || (token[i] == ' '));\n\n  /* read string */\n  do\n  {\n    ret = fgetc(pnm_file);\n    if (ret == EOF) break;\n    i++;\n    token[i] = (unsigned char) ret;\n  }\n  while ((token[i] != '\\n') && (token[i] != '\\r') && (token[i] != ' '));\n\n  token[i] = '\\0';\n\n  return;\n}\n\n/*\n * get_data() - takes first byte and converts into next pixel value,\n *        taking as much bits as defined by bit-depth and\n *        using the bit-depth to fill up a byte (0Ah -> AAh)\n */\n\npng_uint_32 get_data (FILE *pnm_file, int depth)\n{\n  static int bits_left = 0;\n  static int old_value = 0;\n  static int mask = 0;\n  int i;\n  png_uint_32 ret_value;\n\n  if (mask == 0)\n    for (i = 0; i < depth; i++)\n      mask = (mask >> 1) | 0x80;\n\n  if (bits_left <= 0)\n  {\n    old_value = fgetc (pnm_file);\n    bits_left = 8;\n  }\n\n  ret_value = old_value & mask;\n  for (i = 1; i < (8 / depth); i++)\n    ret_value = ret_value || (ret_value >> depth);\n\n  old_value = (old_value << depth) & 0xFF;\n  bits_left -= depth;\n\n  return ret_value;\n}\n\n/*\n * get_value() - takes first (numeric) string and converts into number,\n *         using the bit-depth to fill up a byte (0Ah -> AAh)\n */\n\npng_uint_32 get_value (FILE *pnm_file, int depth)\n{\n  static png_uint_32 mask = 0;\n  png_byte token[16];\n  unsigned long ul_ret_value;\n  png_uint_32 ret_value;\n  int i = 0;\n\n  if (mask == 0)\n    for (i = 0; i < depth; i++)\n      mask = (mask << 1) | 0x01;\n\n  get_token (pnm_file, (char *) token);\n  sscanf ((const char *) token, \"%lu\", &ul_ret_value);\n  ret_value = (png_uint_32) ul_ret_value;\n\n  ret_value &= mask;\n\n  if (depth < 8)\n    for (i = 0; i < (8 / depth); i++)\n      ret_value = (ret_value << depth) || ret_value;\n\n  return ret_value;\n}\n\n/* end of source */\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngminus/pnm2png.sh",
    "content": "#!/bin/sh\n# -- grayscale\n./pnm2png basn0g01.pgm basn0g01.png\n./pnm2png basn0g02.pgm basn0g02.png\n./pnm2png basn0g04.pgm basn0g04.png\n./pnm2png basn0g08.pgm basn0g08.png\n./pnm2png basn0g16.pgm basn0g16.png\n# -- full-color\n./pnm2png basn2c08.ppm basn2c08.png\n./pnm2png basn2c16.ppm basn2c16.png\n# -- palletted\n./pnm2png basn3p01.ppm basn3p01.png\n./pnm2png basn3p02.ppm basn3p02.png\n./pnm2png basn3p04.ppm basn3p04.png\n./pnm2png basn3p08.ppm basn3p08.png\n# -- gray with alpha-channel\n./pnm2png -alpha basn6a08.pgm basn4a08.pgm basn4a08.png\n./pnm2png -alpha basn6a16.pgm basn4a16.pgm basn4a16.png\n# -- color with alpha-channel\n./pnm2png -alpha basn6a08.pgm basn6a08.ppm basn6a08.png\n./pnm2png -alpha basn6a16.pgm basn6a16.ppm basn6a16.png\n# -- grayscale\n./pnm2png rawn0g01.pgm rawn0g01.png\n./pnm2png rawn0g02.pgm rawn0g02.png\n./pnm2png rawn0g04.pgm rawn0g04.png\n./pnm2png rawn0g08.pgm rawn0g08.png\n./pnm2png rawn0g16.pgm rawn0g16.png\n# -- full-color\n./pnm2png rawn2c08.ppm rawn2c08.png\n./pnm2png rawn2c16.ppm rawn2c16.png\n# -- palletted\n./pnm2png rawn3p01.ppm rawn3p01.png\n./pnm2png rawn3p02.ppm rawn3p02.png\n./pnm2png rawn3p04.ppm rawn3p04.png\n./pnm2png rawn3p08.ppm rawn3p08.png\n# -- gray with alpha-channel\n./pnm2png -alpha rawn6a08.pgm rawn4a08.pgm rawn4a08.png\n./pnm2png -alpha rawn6a16.pgm rawn4a16.pgm rawn4a16.png\n# -- color with alpha-channel\n./pnm2png -alpha rawn6a08.pgm rawn6a08.ppm rawn6a08.png\n./pnm2png -alpha rawn6a16.pgm rawn6a16.ppm rawn6a16.png\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/pngsuite/README",
    "content": "\npngsuite\n--------\nCopyright (c) Willem van Schaik, 1999, 2011, 2012\nTwo images (ftbbn0g01.png and ftbbn0g02.png) are by Glenn Randers-Pehrson, 2012\n\nPermission to use, copy, modify, and distribute these images for any\npurpose and without fee is hereby granted.\n\nThe 15 \"bas*.png\" images are part of the much larger PngSuite test-set of\nimages, available for developers of PNG supporting software. The\ncomplete set, available at http:/www.schaik.com/pngsuite/, contains\na variety of images to test interlacing, gamma settings, ancillary\nchunks, etc.\n\nThe \"ft*.png\" images are \"free/libre\" replacements for the transparent\ncorresponding t*.png images in the PngSuite.\n\nThe images in this directory represent the basic PNG color-types:\ngrayscale (1-16 bit deep), full color (8 or 16 bit), paletted\n(1-8 bit) and grayscale or color images with alpha channel. You\ncan use them to test the proper functioning of PNG software.\n\n    filename       depth type\n    ------------ ------ --------------\n    basn0g01.png   1-bit grayscale\n    basn0g02.png   2-bit grayscale\n    basn0g04.png   4-bit grayscale\n    basn0g08.png   8-bit grayscale\n    basn0g16.png  16-bit grayscale\n    basn2c08.png   8-bit truecolor\n    basn2c16.png  16-bit truecolor\n    basn3p01.png   1-bit paletted\n    basn3p02.png   2-bit paletted\n    basn3p04.png   4-bit paletted\n    basn3p08.png   8-bit paletted\n    basn4a08.png   8-bit gray with alpha\n    basn4a16.png  16-bit gray with alpha\n    basn6a08.png   8-bit RGBA\n    basn6a16.png  16-bit RGBA\n\n    ftbbn0g01.png  1-bit grayscale, black bKGD\n    ftbbn0g02.png  2-bit grayscale, black bKGD\n    ftbbn0g04.png  4-bit grayscale, black bKGD\n    ftbbn2c16.png 16-bit truecolor, black bKGD\n    ftbbn3p08.png  8-bit paletted, black bKGD\n    ftbgn2c16.png 16-bit truecolor, gray bKGD\n    ftbgn3p08.png  8-bit paletted, gray bKGD\n    ftbrn2c08.png  8-bit truecolor, red bKGD\n    ftbwn0g16.png 16-bit gray, white bKGD\n    ftbwn3p08.png  8-bit paletted, white bKGD\n    ftbyn3p08.png  8-bit paletted, yellow bKGD\n    ftp0n0g08.png  8-bit grayscale, opaque\n    ftp0n2c08.png  8-bit truecolor, opaque\n    ftp0n3p08.png  8-bit paletted, opaque\n    ftp1n3p08.png  8-bit paletted, no bKGD\n\nHere is the correct result of typing \"pngtest -m bas*.png\" in\nthis directory:\n\nTesting basn0g01.png: PASS (524 zero samples)\n Filter 0 was used 32 times\nTesting basn0g02.png: PASS (448 zero samples)\n Filter 0 was used 32 times\nTesting basn0g04.png: PASS (520 zero samples)\n Filter 0 was used 32 times\nTesting basn0g08.png: PASS (3 zero samples)\n Filter 1 was used 9 times\n Filter 4 was used 23 times\nTesting basn0g16.png: PASS (1 zero samples)\n Filter 1 was used 1 times\n Filter 2 was used 31 times\nTesting basn2c08.png: PASS (6 zero samples)\n Filter 1 was used 5 times\n Filter 4 was used 27 times\nTesting basn2c16.png: PASS (592 zero samples)\n Filter 1 was used 1 times\n Filter 4 was used 31 times\nTesting basn3p01.png: PASS (512 zero samples)\n Filter 0 was used 32 times\nTesting basn3p02.png: PASS (448 zero samples)\n Filter 0 was used 32 times\nTesting basn3p04.png: PASS (544 zero samples)\n Filter 0 was used 32 times\nTesting basn3p08.png: PASS (4 zero samples)\n Filter 0 was used 32 times\nTesting basn4a08.png: PASS (32 zero samples)\n Filter 1 was used 1 times\n Filter 4 was used 31 times\nTesting basn4a16.png: PASS (64 zero samples)\n Filter 0 was used 1 times\n Filter 1 was used 2 times\n Filter 2 was used 1 times\n Filter 4 was used 28 times\nTesting basn6a08.png: PASS (160 zero samples)\n Filter 1 was used 1 times\n Filter 4 was used 31 times\nTesting basn6a16.png: PASS (1072 zero samples)\n Filter 1 was used 4 times\n Filter 4 was used 28 times\nlibpng passes test\n\nWillem van Schaik\n<willem@schaik.com>\nOctober 1999\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/tools/README.txt",
    "content": "This directory (contrib/tools) contains tools used by the authors of libpng.\n\nCode and data placed in this directory is not required to build libpng,\nhowever the code in this directory has been used to generate data or code in\nthe body of the libpng source.  The source code identifies where this has\nbeen done.  Code in this directory may not compile on all operating systems\nthat libpng supports.\n\nNO COPYRIGHT RIGHTS ARE CLAIMED TO ANY OF THE FILES IN THIS DIRECTORY.\n\nTo the extent possible under law, the authors have waived all copyright and\nrelated or neighboring rights to this work.  This work is published from:\nUnited States.\n\nThe files may be used freely in any way.\n\nThe source code and comments in this directory are the original work of the\npeople named below.  No other person or organization has made contributions to\nthe work in this directory.\n\nORIGINAL AUTHORS\n    The following people have contributed to the code in this directory.  None\n    of the people below claim any rights with regard to the contents of this\n    directory.\n\n    John Bowler <jbowler@acm.org>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/tools/checksum-icc.c",
    "content": "/* checksum-icc.c\n *\n * Copyright (c) 2013 John Cunningham Bowler\n *\n * Last changed in libpng 1.6.0 [February 14, 2013]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * Generate crc32 and adler32 checksums of the given input files, used to\n * generate check-codes for use when matching ICC profiles within libpng.\n */\n#include <stdio.h>\n\n#include <zlib.h>\n\nstatic int\nread_one_file(FILE *ip, const char *name)\n{\n   uLong length = 0;\n   uLong a32 = adler32(0, NULL, 0);\n   uLong c32 = crc32(0, NULL, 0);\n   Byte header[132];\n\n   for (;;)\n   {\n      int ch = getc(ip);\n      Byte b;\n\n      if (ch == EOF) break;\n\n      b = (Byte)ch;\n\n      if (length < sizeof header)\n         header[length] = b;\n\n      ++length;\n      a32 = adler32(a32, &b, 1);\n      c32 = crc32(c32, &b, 1);\n   }\n\n   if (ferror(ip))\n      return 0;\n\n   /* Success */\n   printf(\"PNG_ICC_CHECKSUM(0x%8.8lx, 0x%8.8lx,\\n   PNG_MD5(\"\n      \"0x%2.2x%2.2x%2.2x%2.2x, 0x%2.2x%2.2x%2.2x%2.2x, 0x%2.2x%2.2x%2.2x%2.2x,\"\n      \" 0x%2.2x%2.2x%2.2x%2.2x), %d,\\n\"\n      \"   \\\"%4.4d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d\\\", %lu, \\\"%s\\\")\\n\",\n      (unsigned long)a32, (unsigned long)c32,\n      header[84], header[85], header[86], header[87],\n      header[88], header[89], header[90], header[91],\n      header[92], header[93], header[94], header[95],\n      header[96], header[97], header[98], header[99],\n#     define u16(x) (header[x] * 256 + header[x+1])\n#     define u32(x) (u16(x) * 65536 + u16(x+2))\n      u32(64), u16(24), u16(26), u16(28), u16(30), u16(32), u16(34),\n      (unsigned long)length, name);\n\n   return 1;\n}\n\nint main(int argc, char **argv)\n{\n   int err = 0;\n\n   printf(\"/* adler32, crc32, MD5[16], intent, date, length, file-name */\\n\");\n\n   if (argc > 1)\n   {\n      int i;\n\n      for (i=1; i<argc; ++i)\n      {\n         FILE *ip = fopen(argv[i], \"rb\");\n\n         if (ip == NULL || !read_one_file(ip, argv[i]))\n         {\n            err = 1;\n            perror(argv[i]);\n            fprintf(stderr, \"%s: read error\\n\", argv[i]);\n            printf(\"/* ERROR: %s */\\n\", argv[i]);\n         }\n\n         (void)fclose(ip);\n      }\n   }\n\n   else\n   {\n      if (!read_one_file(stdin, \"-\"))\n      {\n         err = 1;\n         perror(\"stdin\");\n         fprintf(stderr, \"stdin: read error\\n\");\n         printf(\"/* ERROR: stdin */\\n\");\n      }\n   }\n\n   return err;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/tools/chkfmt",
    "content": "#!/bin/sh\n#\n# Check the format of the source files in the current directory - checks for a\n# line length of 80 characters max and no tab characters.\n#\n# Optionally arguments are files or directories to check.\n#\n# -v: output the long lines (makes fixing them easier)\n# -e: spawn an editor for each file that needs a change ($EDITOR must be\n#     defined).  When using -e the script MUST be run from an interactive\n#     command line.\nverbose=\nedit=\nvers=\ntest \"$1\" = \"-v\" && {\n   shift\n   verbose=yes\n}\ntest \"$1\" = \"-e\" && {\n   shift\n   if test -n \"$EDITOR\"\n   then\n      edit=yes\n\n      # Copy the standard streams for the editor\n      exec 3>&0 4>&1 5>&2\n   else\n      echo \"chkfmt -e: EDITOR must be defined\" >&2\n      exit 1\n   fi\n}\n\n# Function to edit a single file - if the file isn't changed ask the user\n# whether or not to continue.  This stuff only works if the script is run from\n# the command line (otherwise, don't specify -e or you will be sorry).\ndoed(){\n   cp \"$file\" \"$file\".orig\n   \"$EDITOR\" \"$file\" 0>&3 1>&4 2>&5 3>&- 4>&- 5>&- || exit 1\n   if cmp -s \"$file\".orig \"$file\"\n   then\n      rm \"$file\".orig\n      echo -n \"$file: file not changed, type anything to continue: \" >&5\n      read ans 0>&3\n      test -n \"$ans\" || return 1\n   fi\n   return 0\n}\n\n# In beta versions the version string which appears in files can be a little\n# long and cause spuriously overlong lines.  To avoid this subtitute the version\n# string with a 'standard' version a.b.cc before checking for long lines.\nif test -r png.h\nthen\n   vers=\"`sed -n -e \\\n   's/^#define PNG_LIBPNG_VER_STRING .\\([0-9]\\.[0-9]\\.[0-9][0-9a-z]*\\).$/\\1/p' \\\n   png.h`\"\n   echo \"chkfmt: checking version $vers\"\nfi\nif test -z \"$vers\"\nthen\n   echo \"chkfmt: png.h not found, ignoring version number\" >&2\nfi\n\ntest -n \"$1\" || set -- .\nfind \"$@\" \\( -type d \\( -name '.git' -o -name '.libs' -o -name 'projects' \\) \\\n   -prune \\) -o \\( -type f \\\n   ! -name '*.[oa]' ! -name '*.l[oa]' !  -name '*.png' ! -name '*.out' \\\n   ! -name '*.jpg' ! -name '*.patch' ! -name '*.obj' ! -name '*.exe' \\\n   ! -name '*.com' ! -name '*.tar.*' ! -name '*.zip' ! -name '*.ico' \\\n   ! -name '*.res' ! -name '*.rc' ! -name '*.mms' ! -name '*.rej' \\\n   ! -name '*.dsp' ! -name '*.orig' ! -name '*.dfn' ! -name '*.swp' \\\n   ! -name '~*' ! -name '*.3' \\\n   ! -name 'missing' ! -name 'mkinstalldirs' ! -name 'depcomp' \\\n   ! -name 'aclocal.m4' ! -name 'install-sh' ! -name 'Makefile.in' \\\n   ! -name 'ltmain.sh' ! -name 'config*' -print \\) | {\n   st=0\n   while read file\n   do\n      case \"$file\" in\n      *.mak|*[Mm]akefile.*|*[Mm]akefile)\n         # Makefiles require tabs, dependency lines can be this long.\n         check_tabs=\n         line_length=100;;\n      *.awk)\n         # Includes literal tabs\n         check_tabs=\n         # The following is arbitrary\n         line_length=132;;\n      *contrib/*/*.[ch])\n         check_tabs=yes\n         line_length=96;;\n      *)\n         check_tabs=yes\n         line_length=80;;\n      esac\n\n      # Note that vers can only contain 0-9, . and a-z\n      if test -n \"$vers\"\n      then\n         sed -e \"s/$vers/a.b.cc/g\" \"$file\" >\"$file\".$$\n      else\n         cp \"$file\" \"$file\".$$\n      fi\n      splt=\"`fold -$line_length \"$file\".$$ | diff -c \"$file\".$$ -`\"\n      rm \"$file\".$$\n\n      if test -n \"$splt\"\n      then\n         echo \"$file: lines too long\"\n         st=1\n         if test -n \"$EDITOR\" -a -n \"$edit\"\n         then\n            doed \"$file\" || exit 1\n         elif test -n \"$verbose\"\n         then\n            echo \"$splt\"\n         fi\n      fi\n      if test -n \"$check_tabs\"\n      then\n         tab=\"`tr -c -d '\\t' <\"$file\"`\"\n         if test -n \"$tab\"\n         then\n            echo \"$file: file contains tab characters\"\n            st=1\n            if test -n \"$EDITOR\" -a -n \"$edit\"\n            then\n               doed \"$file\" || exit 1\n            elif test -n \"$verbose\"\n            then\n               echo \"$splt\"\n            fi\n         fi\n      fi\n   done\n   exit $st\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/tools/cvtcolor.c",
    "content": "/*-\n * convert.c\n *\n * Last changed in libpng 1.6.0 [February 14, 2013]\n *\n * COPYRIGHT: Written by John Cunningham Bowler, 2013.\n * To the extent possible under law, the author has waived all copyright and\n * related or neighboring rights to this work.  This work is published from:\n * United States.\n *\n * Convert 8-bit sRGB or 16-bit linear values to another format.\n */\n#define _ISOC99_SOURCE 1\n\n#include <stdlib.h>\n#include <string.h>\n#include <math.h>\n#include <stdio.h>\n\n#include <fenv.h>\n\n#include \"sRGB.h\"\n\nstatic void\nusage(const char *prog)\n{\n   fprintf(stderr,\n      \"%s: usage: %s [-linear|-sRGB] [-gray|-color] component{1,4}\\n\",\n      prog, prog);\n   exit(1);\n}\n\nunsigned long\ncomponent(const char *prog, const char *arg, int issRGB)\n{\n   char *ep;\n   unsigned long c = strtoul(arg, &ep, 0);\n\n   if (ep <= arg || *ep || c > 65535 || (issRGB && c > 255))\n   {\n      fprintf(stderr, \"%s: %s: invalid component value (%lu)\\n\", prog, arg, c);\n      usage(prog);\n   }\n\n   return c;\n}\n\nint\nmain(int argc, const char **argv)\n{\n   const char *prog = *argv++;\n   int to_linear = 0, to_gray = 0, to_color = 0;\n   int channels = 0;\n   double c[4];\n\n   /* FE_TONEAREST is the IEEE754 round to nearest, preferring even, mode; i.e.\n    * everything rounds to the nearest value except that '.5' rounds to the\n    * nearest even value.\n    */\n   fesetround(FE_TONEAREST);\n\n   c[3] = c[2] = c[1] = c[0] = 0;\n\n   while (--argc > 0 && **argv == '-')\n   {\n      const char *arg = 1+*argv++;\n\n      if (strcmp(arg, \"sRGB\") == 0)\n         to_linear = 0;\n\n      else if (strcmp(arg, \"linear\") == 0)\n         to_linear = 1;\n\n      else if (strcmp(arg, \"gray\") == 0)\n         to_gray = 1, to_color = 0;\n\n      else if (strcmp(arg, \"color\") == 0)\n         to_gray = 0, to_color = 1;\n\n      else\n         usage(prog);\n   }\n\n   switch (argc)\n   {\n      default:\n         usage(prog);\n         break;\n\n      case 4:\n         c[3] = component(prog, argv[3], to_linear);\n         ++channels;\n      case 3:\n         c[2] = component(prog, argv[2], to_linear);\n         ++channels;\n      case 2:\n         c[1] = component(prog, argv[1], to_linear);\n         ++channels;\n      case 1:\n         c[0] = component(prog, argv[0], to_linear);\n         ++channels;\n         break;\n      }\n\n   if (to_linear)\n   {\n      int i;\n      int components = channels;\n\n      if ((components & 1) == 0)\n         --components;\n\n      for (i=0; i<components; ++i) c[i] = linear_from_sRGB(c[i] / 255);\n      if (components < channels)\n         c[components] = c[components] / 255;\n   }\n\n   else\n   {\n      int i;\n      for (i=0; i<4; ++i) c[i] /= 65535;\n\n      if ((channels & 1) == 0)\n      {\n         double alpha = c[channels-1];\n\n         if (alpha > 0)\n            for (i=0; i<channels-1; ++i) c[i] /= alpha;\n         else\n            for (i=0; i<channels-1; ++i) c[i] = 1;\n      }\n   }\n\n   if (to_gray)\n   {\n      if (channels < 3)\n      {\n         fprintf(stderr, \"%s: too few channels (%d) for -gray\\n\",\n            prog, channels);\n         usage(prog);\n      }\n\n      c[0] = YfromRGB(c[0], c[1], c[2]);\n      channels -= 2;\n   }\n\n   if (to_color)\n   {\n      if (channels > 2)\n      {\n         fprintf(stderr, \"%s: too many channels (%d) for -color\\n\",\n            prog, channels);\n         usage(prog);\n      }\n\n      c[3] = c[1]; /* alpha, if present */\n      c[2] = c[1] = c[0];\n   }\n\n   if (to_linear)\n   {\n      int i;\n      if ((channels & 1) == 0)\n      {\n         double alpha = c[channels-1];\n         for (i=0; i<channels-1; ++i) c[i] *= alpha;\n      }\n\n      for (i=0; i<channels; ++i) c[i] = nearbyint(c[i] * 65535);\n   }\n\n   else /* to sRGB */\n   {\n      int i = (channels+1)&~1;\n      while (--i >= 0)\n         c[i] = sRGB_from_linear(c[i]);\n\n      for (i=0; i<channels; ++i) c[i] = nearbyint(c[i] * 255);\n   }\n\n   {\n      int i;\n      for (i=0; i<channels; ++i) printf(\" %g\", c[i]);\n   }\n   printf(\"\\n\");\n\n   return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/tools/genpng.c",
    "content": "/*- genpng\n *\n * COPYRIGHT: Written by John Cunningham Bowler, 2015.\n * To the extent possible under law, the author has waived all copyright and\n * related or neighboring rights to this work.  This work is published from:\n * United States.\n *\n * Generate a PNG with an alpha channel, correctly.\n *\n * This is a test case generator; the resultant PNG files are only of interest\n * to those of us who care about whether the edges of circles are green, red,\n * or yellow.\n *\n * The program generates an RGB+Alpha PNG of a given size containing the given\n * shapes on a transparent background:\n *\n *  genpng width height { shape }\n *    shape ::= color width shape x1 y1 x2 y2\n *\n * 'color' is:\n *\n *  black white red green yellow blue brown purple pink orange gray cyan\n *\n * The point is to have colors that are linguistically meaningful plus that old\n * bugbear of the department store dress murders, Cyan, the only color we argue\n * about.\n *\n * 'shape' is:\n *\n *  circle: an ellipse\n *  square: a rectangle\n *  line: a straight line\n *\n * Each shape is followed by four numbers, these are two points in the output\n * coordinate space (as real numbers) which describe the circle, square, or\n * line.  The shape is filled if it is preceded by 'filled' (not valid for\n * 'line') or is drawn with a line, in which case the width of the line must\n * precede the shape.\n *\n * The whole set of information can be repeated as many times as desired:\n *\n *    shape ::= color width shape x1 y1 x2 y2\n *\n *    color ::= black|white|red|green|yellow|blue\n *    color ::= brown|purple|pink|orange|gray|cyan\n *    width ::= filled\n *    width ::= <number>\n *    shape ::= circle|square|line\n *    x1    ::= <number>\n *    x2    ::= <number>\n *    y1    ::= <number>\n *    y2    ::= <number>\n *\n * The output PNG is generated by down-sampling a 4x supersampled image using\n * a bi-cubic filter.  The bi-cubic has a 2 (output) pixel width, so an 8x8\n * array of super-sampled points contribute to each output pixel.  The value of\n * a super-sampled point is found using an unfiltered, aliased, infinite\n * precision image: Each shape from the last to the first is checked to see if\n * the point is in the drawn area and, if it is, the color of the point is the\n * color of the shape and the alpha is 1, if not the previous shape is checked.\n *\n * This is an aliased algorithm because no filtering is done; a point is either\n * inside or outside each shape and 'close' points do not contribute to the\n * sample.  The down-sampling is relied on to correct the error of not using\n * a filter.\n *\n * The line end-caps are 'flat'; they go through the points.  The square line\n * joins are mitres; the outside of the lines are continued to the point of\n * intersection.\n */\n#include <stddef.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <math.h>\n\n/* Normally use <png.h> here to get the installed libpng, but this is done to\n * ensure the code picks up the local libpng implementation:\n */\n#include \"../../png.h\"\n\n#if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)\n\nstatic const struct color\n{\n   const char *name;\n   double      red;\n   double      green;\n   double      blue;\n} colors[] =\n/* color ::= black|white|red|green|yellow|blue\n * color ::= brown|purple|pink|orange|gray|cyan\n */\n{\n   { \"black\",   0,    0,  0 },\n   { \"white\",   1,    1,  1 },\n   { \"red\",     1,    0,  0 },\n   { \"green\",   0,    1,  0 },\n   { \"yellow\",  1,    1,  0 },\n   { \"blue\",    0,    0,  1 },\n   { \"brown\",  .5, .125,  0 },\n   { \"purple\",  1,    0,  1 },\n   { \"pink\",    1,   .5, .5 },\n   { \"orange\",  1,   .5,  0 },\n   { \"gray\",    0,   .5, .5 },\n   { \"cyan\",    0,    1,  1 }\n};\n#define color_count ((sizeof colors)/(sizeof colors[0]))\n\nstatic const struct color *\ncolor_of(const char *arg)\n{\n   int icolor = color_count;\n\n   while (--icolor >= 0)\n   {\n      if (strcmp(colors[icolor].name, arg) == 0)\n         return colors+icolor;\n   }\n\n   fprintf(stderr, \"genpng: invalid color %s\\n\", arg);\n   exit(1);\n}\n\nstatic double\nwidth_of(const char *arg)\n{\n   if (strcmp(arg, \"filled\") == 0)\n      return 0;\n\n   else\n   {\n      char *ep = NULL;\n      double w = strtod(arg, &ep);\n\n      if (ep != NULL && *ep == 0 && w > 0)\n         return w;\n   }\n\n   fprintf(stderr, \"genpng: invalid line width %s\\n\", arg);\n   exit(1);\n}\n\nstatic double\ncoordinate_of(const char *arg)\n{\n   char *ep = NULL;\n   double w = strtod(arg, &ep);\n\n   if (ep != NULL && *ep == 0)\n      return w;\n\n   fprintf(stderr, \"genpng: invalid coordinate value %s\\n\", arg);\n   exit(1);\n}\n\nstruct arg; /* forward declaration */\n\ntypedef int (*shape_fn_ptr)(const struct arg *arg, double x, double y);\n   /* A function to determine if (x,y) is inside the shape.\n    *\n    * There are two implementations:\n    *\n    *    inside_fn: returns true if the point is inside\n    *    check_fn:  returns;\n    *       -1: the point is outside the shape by more than the filter width (2)\n    *        0: the point may be inside the shape\n    *       +1: the point is inside the shape by more than the filter width\n    */\n#define OUTSIDE (-1)\n#define INSIDE  (1)\n\nstruct arg\n{\n   const struct color *color;\n   shape_fn_ptr        inside_fn;\n   shape_fn_ptr        check_fn;\n   double              width; /* line width, 0 for 'filled' */\n   double              x1, y1, x2, y2;\n};\n\n/* IMPLEMENTATION NOTE:\n *\n * We want the contribution of each shape to the sample corresponding to each\n * pixel.  This could be obtained by super sampling the image to infinite\n * dimensions, finding each point within the shape and assigning that a value\n * '1' while leaving every point outside the shape with value '0' then\n * downsampling to the image size with sinc; computationally very expensive.\n *\n * Approximations are as follows:\n *\n * 1) If the pixel coordinate is within the shape assume the sample has the\n *    shape color and is opaque, else assume there is no contribution from\n *    the shape.\n *\n *    This is the equivalent of aliased rendering or resampling an image with\n *    a block filter.  The maximum error in the calculated alpha (which will\n *    always be 0 or 1) is 0.5.\n *\n * 2) If the shape is within a square of size 1x1 centered on the pixel assume\n *    that the shape obscures an amount of the pixel equal to its area within\n *    that square.\n *\n *    This is the equivalent of 'pixel coverage' alpha calculation or resampling\n *    an image with a bi-linear filter.  The maximum error is over 0.2, but the\n *    results are often acceptable.\n *\n *    This can be approximated by applying (1) to a super-sampled image then\n *    downsampling with a bi-linear filter.  The error in the super-sampled\n *    image is 0.5 per sample, but the resampling reduces this.\n *\n * 3) Use a better filter with a super-sampled image; in the limit this is the\n *    sinc() approach.\n *\n * 4) Do the geometric calculation; a bivariate definite integral across the\n *    shape, unfortunately this means evaluating Si(x), the integral of sinc(x),\n *    which is still a lot of math.\n *\n * This code uses approach (3) with a bi-cubic filter and 8x super-sampling\n * and method (1) for the super-samples.  This means that the sample is either\n * 0 or 1, depending on whether the sub-pixel is within or outside the shape.\n * The bi-cubic weights are also fixed and the 16 required weights are\n * pre-computed here (note that the 'scale' setting will need to be changed if\n * 'super' is increased).\n *\n * The code also calculates a sum to the edge of the filter. This is not\n * currently used by could be used to optimize the calculation.\n */\n#if 0 /* bc code */\nscale=10\nsuper=8\ndefine bicubic(x) {\n   if (x <= 1) return (1.5*x - 2.5)*x*x + 1;\n   if (x <  2) return (((2.5 - 0.5*x)*x - 4)*x + 2);\n   return 0;\n}\ndefine sum(x) {\n   auto s;\n   s = 0;\n   while (x < 2*super) {\n      s = s + bicubic(x/super);\n      x = x + 1;\n   }\n   return s;\n}\ndefine results(x) {\n   auto b, s;\n   b = bicubic(x/super);\n   s = sum(x);\n\n   print \"   /*\", x, \"*/ { \", b, \", \", s, \" }\";\n   return 1;\n}\nx=0\nwhile (x<2*super) {\n   x = x + results(x)\n   if (x < 2*super) print \",\"\n   print \"\\n\"\n}\nquit\n#endif\n\n#define BICUBIC1(x) /*     |x| <= 1 */ ((1.5*(x)* - 2.5)*(x)*(x) + 1)\n#define BICUBIC2(x) /* 1 < |x| <  2 */ (((2.5 - 0.5*(x))*(x) - 4)*(x) + 2)\n#define FILTER_WEIGHT 9 /* Twice the first sum below */\n#define FILTER_WIDTH  2 /* Actually half the width; -2..+2 */\n#define FILTER_STEPS  8 /* steps per filter unit */\nstatic const double\nbicubic[16][2] =\n{\n   /* These numbers are exact; the weight for the filter is 1/9, but this\n    * would make the numbers inexact, so it is not included here.\n    */\n   /*          bicubic      sum        */\n   /* 0*/ { 1.0000000000, 4.5000000000 },\n   /* 1*/ {  .9638671875, 3.5000000000 },\n   /* 2*/ {  .8671875000, 2.5361328125 },\n   /* 3*/ {  .7275390625, 1.6689453125 },\n   /* 4*/ {  .5625000000,  .9414062500 },\n   /* 5*/ {  .3896484375,  .3789062500 },\n   /* 6*/ {  .2265625000, -.0107421875 },\n   /* 7*/ {  .0908203125, -.2373046875 },\n   /* 8*/ {            0, -.3281250000 },\n   /* 9*/ { -.0478515625, -.3281250000 },\n   /*10*/ { -.0703125000, -.2802734375 },\n   /*11*/ { -.0732421875, -.2099609375 },\n   /*12*/ { -.0625000000, -.1367187500 },\n   /*13*/ { -.0439453125, -.0742187500 },\n   /*14*/ { -.0234375000, -.0302734375 },\n   /*15*/ { -.0068359375, -.0068359375 }\n};\n\nstatic double\nalpha_calc(const struct arg *arg, double x, double y)\n{\n   /* For [x-2..x+2],[y-2,y+2] calculate the weighted bicubic given a function\n    * which tells us whether a point is inside or outside the shape.  First\n    * check if we need to do this at all:\n    */\n   switch (arg->check_fn(arg, x, y))\n   {\n      case OUTSIDE:\n         return 0; /* all samples outside the shape */\n\n      case INSIDE:\n         return 1; /* all samples inside the shape */\n\n      default:\n      {\n         int dy;\n         double alpha = 0;\n\n#        define FILTER_D (FILTER_WIDTH*FILTER_STEPS-1)\n         for (dy=-FILTER_D; dy<=FILTER_D; ++dy)\n         {\n            double wy = bicubic[abs(dy)][0];\n\n            if (wy != 0)\n            {\n               double alphay = 0;\n               int dx;\n\n               for (dx=-FILTER_D; dx<=FILTER_D; ++dx)\n               {\n                  double wx = bicubic[abs(dx)][0];\n\n                  if (wx != 0 && arg->inside_fn(arg, x+dx/16, y+dy/16))\n                     alphay += wx;\n               }\n\n               alpha += wy * alphay;\n            }\n         }\n\n         /* This needs to be weighted for each dimension: */\n         return alpha / (FILTER_WEIGHT*FILTER_WEIGHT);\n      }\n   }\n}\n\n/* These are the shape functions. */\n/* \"square\",\n * { inside_square_filled, check_square_filled },\n * { inside_square, check_square }\n */\nstatic int\nsquare_check(double x, double y, double x1, double y1, double x2, double y2)\n   /* Is x,y inside the square (x1,y1)..(x2,y2)? */\n{\n   /* Do a modified Cohen-Sutherland on one point, bit patterns that indicate\n    * 'outside' are:\n    *\n    *   x<x1 | x<y1 | x<x2 | x<y2\n    *    0      x      0      x     To the right\n    *    1      x      1      x     To the left\n    *    x      0      x      0     Below\n    *    x      1      x      1     Above\n    *\n    * So 'inside' is (x<x1) != (x<x2) && (y<y1) != (y<y2);\n    */\n   return ((x<x1) ^ (x<x2)) & ((y<y1) ^ (y<y2));\n}\n\nstatic int\ninside_square_filled(const struct arg *arg, double x, double y)\n{\n   return square_check(x, y, arg->x1, arg->y1, arg->x2, arg->y2);\n}\n\nstatic int\nsquare_check_line(const struct arg *arg, double x, double y, double w)\n   /* Check for a point being inside the boundaries implied by the given arg\n    * and assuming a width 2*w each side of the boundaries.  This returns the\n    * 'check' INSIDE/OUTSIDE/0 result but note the semantics:\n    *\n    *          +--------------+\n    *          |              |   OUTSIDE\n    *          |   INSIDE     |\n    *          |              |\n    *          +--------------+\n    *\n    * And '0' means within the line boundaries.\n    */\n{\n   double cx = (arg->x1+arg->x2)/2;\n   double wx = fabs(arg->x1-arg->x2)/2;\n   double cy = (arg->y1+arg->y2)/2;\n   double wy = fabs(arg->y1-arg->y2)/2;\n\n   if (square_check(x, y, cx-wx-w, cy-wy-w, cx+wx+w, cy+wy+w))\n   {\n      /* Inside, but maybe too far; check for the redundant case where\n       * the lines overlap:\n       */\n      wx -= w;\n      wy -= w;\n      if (wx > 0 && wy > 0 && square_check(x, y, cx-wx, cy-wy, cx+wx, cy+wy))\n         return INSIDE; /* between (inside) the boundary lines. */\n\n      return 0; /* inside the lines themselves. */\n   }\n\n   return OUTSIDE; /* outside the boundary lines. */\n}\n\nstatic int\ncheck_square_filled(const struct arg *arg, double x, double y)\n{\n   /* The filter extends +/-FILTER_WIDTH each side of each output point, so\n    * the check has to expand and contract the square by that amount; '0'\n    * means close enough to the edge of the square that the bicubic filter has\n    * to be run, OUTSIDE means alpha==0, INSIDE means alpha==1.\n    */\n   return square_check_line(arg, x, y, FILTER_WIDTH);\n}\n\nstatic int\ninside_square(const struct arg *arg, double x, double y)\n{\n   /* Return true if within the drawn lines, else false, no need to distinguish\n    * INSIDE vs OUTSIDE here:\n    */\n   return square_check_line(arg, x, y, arg->width/2) == 0;\n}\n\nstatic int\ncheck_square(const struct arg *arg, double x, double y)\n{\n   /* So for this function a result of 'INSIDE' means inside the actual lines.\n    */\n   double w = arg->width/2;\n\n   if (square_check_line(arg, x, y, w+FILTER_WIDTH) == 0)\n   {\n      /* Somewhere close to the boundary lines. If far enough inside one of\n       * them then we can return INSIDE:\n       */\n      w -= FILTER_WIDTH;\n\n      if (w > 0 && square_check_line(arg, x, y, w) == 0)\n         return INSIDE;\n\n      /* Point is somewhere in the filter region: */\n      return 0;\n   }\n\n   else /* Inside or outside the square by more than w+FILTER_WIDTH. */\n      return OUTSIDE;\n}\n\n/* \"circle\",\n * { inside_circle_filled, check_circle_filled },\n * { inside_circle, check_circle }\n *\n * The functions here are analoguous to the square ones; however, they check\n * the corresponding ellipse as opposed to the rectangle.\n */\nstatic int\ncircle_check(double x, double y, double x1, double y1, double x2, double y2)\n{\n   if (square_check(x, y, x1, y1, x2, y2))\n   {\n      /* Inside the square, so maybe inside the circle too: */\n      const double cx = (x1 + x2)/2;\n      const double cy = (y1 + y2)/2;\n      const double dx = x1 - x2;\n      const double dy = y1 - y2;\n\n      x = (x - cx)/dx;\n      y = (y - cy)/dy;\n\n      /* It is outside if the distance from the center is more than half the\n       * diameter:\n       */\n      return x*x+y*y < .25;\n   }\n\n   return 0; /* outside */\n}\n\nstatic int\ninside_circle_filled(const struct arg *arg, double x, double y)\n{\n   return circle_check(x, y, arg->x1, arg->y1, arg->x2, arg->y2);\n}\n\nstatic int\ncircle_check_line(const struct arg *arg, double x, double y, double w)\n   /* Check for a point being inside the boundaries implied by the given arg\n    * and assuming a width 2*w each side of the boundaries.  This function has\n    * the same semantic as square_check_line but tests the circle.\n    */\n{\n   double cx = (arg->x1+arg->x2)/2;\n   double wx = fabs(arg->x1-arg->x2)/2;\n   double cy = (arg->y1+arg->y2)/2;\n   double wy = fabs(arg->y1-arg->y2)/2;\n\n   if (circle_check(x, y, cx-wx-w, cy-wy-w, cx+wx+w, cy+wy+w))\n   {\n      /* Inside, but maybe too far; check for the redundant case where\n       * the lines overlap:\n       */\n      wx -= w;\n      wy -= w;\n      if (wx > 0 && wy > 0 && circle_check(x, y, cx-wx, cy-wy, cx+wx, cy+wy))\n         return INSIDE; /* between (inside) the boundary lines. */\n\n      return 0; /* inside the lines themselves. */\n   }\n\n   return OUTSIDE; /* outside the boundary lines. */\n}\n\nstatic int\ncheck_circle_filled(const struct arg *arg, double x, double y)\n{\n   return circle_check_line(arg, x, y, FILTER_WIDTH);\n}\n\nstatic int\ninside_circle(const struct arg *arg, double x, double y)\n{\n   return circle_check_line(arg, x, y, arg->width/2) == 0;\n}\n\nstatic int\ncheck_circle(const struct arg *arg, double x, double y)\n{\n   /* Exactly as the 'square' code.  */\n   double w = arg->width/2;\n\n   if (circle_check_line(arg, x, y, w+FILTER_WIDTH) == 0)\n   {\n      w -= FILTER_WIDTH;\n\n      if (w > 0 && circle_check_line(arg, x, y, w) == 0)\n         return INSIDE;\n\n      /* Point is somewhere in the filter region: */\n      return 0;\n   }\n\n   else /* Inside or outside the square by more than w+FILTER_WIDTH. */\n      return OUTSIDE;\n}\n\n/* \"line\",\n * { NULL, NULL },  There is no 'filled' line.\n * { inside_line, check_line }\n */\nstatic int\nline_check(double x, double y, double x1, double y1, double x2, double y2,\n   double w, double expand)\n{\n   /* Shift all the points to (arg->x1, arg->y1) */\n   double lx = x2 - x1;\n   double ly = y2 - y1;\n   double len2 = lx*lx + ly*ly;\n   double cross, dot;\n\n   x -= x1;\n   y -= y1;\n\n   /* The dot product is the distance down the line, the cross product is\n    * the distance away from the line:\n    *\n    *    distance = |cross| / sqrt(len2)\n    */\n   cross = x * ly - y * lx;\n\n   /* If 'distance' is more than w the point is definitely outside the line:\n    *\n    *     distance >= w\n    *     |cross|  >= w * sqrt(len2)\n    *     cross^2  >= w^2 * len2:\n    */\n   if (cross*cross >= (w+expand)*(w+expand)*len2)\n      return 0; /* outside */\n\n   /* Now find the distance *along* the line; this comes from the dot product\n    * lx.x+ly.y. The actual distance (in pixels) is:\n    *\n    *   distance = dot / sqrt(len2)\n    */\n   dot = lx * x + ly * y;\n\n   /* The test for 'outside' is:\n    *\n    *    distance < 0 || distance > sqrt(len2)\n    *                 -> dot / sqrt(len2) > sqrt(len2)\n    *                 -> dot > len2\n    *\n    * But 'expand' is used for the filter width and needs to be handled too:\n    */\n   return dot > -expand && dot < len2+expand;\n}\n\nstatic int\ninside_line(const struct arg *arg, double x, double y)\n{\n   return line_check(x, y, arg->x1, arg->y1, arg->x2, arg->y2, arg->width/2, 0);\n}\n\nstatic int\ncheck_line(const struct arg *arg, double x, double y)\n{\n   /* The end caps of the line must be checked too; it's not enough just to\n    * widen the line by FILTER_WIDTH; 'expand' exists for this purpose:\n    */\n   if (line_check(x, y, arg->x1, arg->y1, arg->x2, arg->y2, arg->width/2,\n       FILTER_WIDTH))\n   {\n      /* Inside the line+filter; far enough inside that the filter isn't\n       * required?\n       */\n      if (arg->width > 2*FILTER_WIDTH &&\n          line_check(x, y, arg->x1, arg->y1, arg->x2, arg->y2, arg->width/2,\n             -FILTER_WIDTH))\n         return INSIDE;\n\n      return 0;\n   }\n\n   return OUTSIDE;\n}\n\nstatic const struct\n{\n   const char    *name;\n   shape_fn_ptr   function[2/*fill,line*/][2];\n#  define         FN_INSIDE 0\n#  define         FN_CHECK 1\n} shape_defs[] =\n{\n   {  \"square\",\n      {  { inside_square_filled, check_square_filled },\n         { inside_square, check_square } }\n   },\n   {  \"circle\",\n      {  { inside_circle_filled, check_circle_filled },\n         { inside_circle, check_circle } }\n   },\n   {  \"line\",\n      {  { NULL, NULL },\n         { inside_line, check_line } }\n   }\n};\n\n#define shape_count ((sizeof shape_defs)/(sizeof shape_defs[0]))\n\nstatic shape_fn_ptr\nshape_of(const char *arg, double width, int f)\n{\n   unsigned int i;\n\n   for (i=0; i<shape_count; ++i) if (strcmp(shape_defs[i].name, arg) == 0)\n   {\n      shape_fn_ptr fn = shape_defs[i].function[width != 0][f];\n\n      if (fn != NULL)\n         return fn;\n\n      fprintf(stderr, \"genpng: %s %s not supported\\n\",\n         width == 0 ? \"filled\" : \"unfilled\", arg);\n      exit(1);\n   }\n\n   fprintf(stderr, \"genpng: %s: not a valid shape name\\n\", arg);\n   exit(1);\n}\n\nstatic void\nparse_arg(struct arg *arg, const char **argv/*7 arguments*/)\n{\n   /* shape ::= color width shape x1 y1 x2 y2 */\n   arg->color = color_of(argv[0]);\n   arg->width = width_of(argv[1]);\n   arg->inside_fn = shape_of(argv[2], arg->width, FN_INSIDE);\n   arg->check_fn = shape_of(argv[2], arg->width, FN_CHECK);\n   arg->x1 = coordinate_of(argv[3]);\n   arg->y1 = coordinate_of(argv[4]);\n   arg->x2 = coordinate_of(argv[5]);\n   arg->y2 = coordinate_of(argv[6]);\n}\n\nstatic png_uint_32\nread_wh(const char *name, const char *str)\n   /* read a PNG width or height */\n{\n   char *ep = NULL;\n   unsigned long ul = strtoul(str, &ep, 10);\n\n   if (ep != NULL && *ep == 0 && ul > 0 && ul <= 0x7fffffff)\n      return (png_uint_32)/*SAFE*/ul;\n\n   fprintf(stderr, \"genpng: %s: invalid number %s\\n\", name, str);\n   exit(1);\n}\n\nstatic void\npixel(png_uint_16p p, struct arg *args, int nargs, double x, double y)\n{\n   /* Fill in the pixel by checking each shape (args[nargs]) for effects on\n    * the corresponding sample:\n    */\n   double r=0, g=0, b=0, a=0;\n\n   while (--nargs >= 0 && a != 1)\n   {\n      /* NOTE: alpha_calc can return a value outside the range 0..1 with the\n       * bicubic filter.\n       */\n      const double alpha = alpha_calc(args+nargs, x, y) * (1-a);\n\n      r += alpha * args[nargs].color->red;\n      g += alpha * args[nargs].color->green;\n      b += alpha * args[nargs].color->blue;\n      a += alpha;\n   }\n\n   /* 'a' may be negative or greater than 1; if it is, negative clamp the\n    * pixel to 0 if >1 clamp r/g/b:\n    */\n   if (a > 0)\n   {\n      if (a > 1)\n      {\n         if (r > 1) r = 1;\n         if (g > 1) g = 1;\n         if (b > 1) b = 1;\n         a = 1;\n      }\n\n      /* And fill in the pixel: */\n      p[0] = (png_uint_16)/*SAFE*/round(r * 65535);\n      p[1] = (png_uint_16)/*SAFE*/round(g * 65535);\n      p[2] = (png_uint_16)/*SAFE*/round(b * 65535);\n      p[3] = (png_uint_16)/*SAFE*/round(a * 65535);\n   }\n\n   else\n      p[3] = p[2] = p[1] = p[0] = 0;\n}\n\nint\nmain(int argc, const char **argv)\n{\n   int convert_to_8bit = 0;\n\n   /* There is one option: --8bit: */\n   if (argc > 1 && strcmp(argv[1], \"--8bit\") == 0)\n      --argc, ++argv, convert_to_8bit = 1;\n\n   if (argc >= 3)\n   {\n      png_uint_16p buffer;\n      int nshapes;\n      png_image image;\n#     define max_shapes 256\n      struct arg arg_list[max_shapes];\n\n      /* The libpng Simplified API write code requires a fully initialized\n       * structure.\n       */\n      memset(&image, 0, sizeof image);\n      image.version = PNG_IMAGE_VERSION;\n      image.opaque = NULL;\n      image.width = read_wh(\"width\", argv[1]);\n      image.height = read_wh(\"height\", argv[2]);\n      image.format = PNG_FORMAT_LINEAR_RGB_ALPHA;\n      image.flags = 0;\n      image.colormap_entries = 0;\n\n      /* Check the remainder of the arguments */\n      for (nshapes=0; 3+7*(nshapes+1) <= argc && nshapes < max_shapes;\n           ++nshapes)\n         parse_arg(arg_list+nshapes, argv+3+7*nshapes);\n\n      if (3+7*nshapes != argc)\n      {\n         fprintf(stderr, \"genpng: %s: too many arguments\\n\", argv[3+7*nshapes]);\n         return 1;\n      }\n\n      /* Create the buffer: */\n      buffer = malloc(PNG_IMAGE_SIZE(image));\n\n      if (buffer != NULL)\n      {\n         png_uint_32 y;\n\n         /* Write each row... */\n         for (y=0; y<image.height; ++y)\n         {\n            png_uint_32 x;\n\n            /* Each pixel in each row: */\n            for (x=0; x<image.width; ++x)\n               pixel(buffer + 4*(x + y*image.width), arg_list, nshapes, x, y);\n         }\n\n         /* Write the result (to stdout) */\n         if (png_image_write_to_stdio(&image, stdout, convert_to_8bit,\n             buffer, 0/*row_stride*/, NULL/*colormap*/))\n         {\n            free(buffer);\n            return 0; /* success */\n         }\n\n         else\n            fprintf(stderr, \"genpng: write stdout: %s\\n\", image.message);\n\n         free(buffer);\n      }\n\n      else\n         fprintf(stderr, \"genpng: out of memory: %lu bytes\\n\",\n               (unsigned long)PNG_IMAGE_SIZE(image));\n   }\n\n   else\n   {\n      /* Wrong number of arguments */\n      fprintf(stderr, \"genpng: usage: genpng [--8bit] width height {shape}\\n\"\n         \" Generate a transparent PNG in RGBA (truecolor+alpha) format\\n\"\n         \" containing the given shape or shapes.  Shapes are defined:\\n\"\n         \"\\n\"\n         \"  shape ::= color width shape x1 y1 x2 y2\\n\"\n         \"  color ::= black|white|red|green|yellow|blue\\n\"\n         \"  color ::= brown|purple|pink|orange|gray|cyan\\n\"\n         \"  width ::= filled|<number>\\n\"\n         \"  shape ::= circle|square|line\\n\"\n         \"  x1,x2 ::= <number>\\n\"\n         \"  y1,y2 ::= <number>\\n\"\n         \"\\n\"\n         \" Numbers are floating point numbers describing points relative to\\n\"\n         \" the top left of the output PNG as pixel coordinates.  The 'width'\\n\"\n         \" parameter is either the width of the line (in output pixels) used\\n\"\n         \" to draw the shape or 'filled' to indicate that the shape should\\n\"\n         \" be filled with the color.\\n\"\n         \"\\n\"\n         \" Colors are interpreted loosely to give access to the eight full\\n\"\n         \" intensity RGB values:\\n\"\n         \"\\n\"\n         \"  black, red, green, blue, yellow, cyan, purple, white,\\n\"\n         \"\\n\"\n         \" Cyan is full intensity blue+green; RGB(0,1,1), plus the following\\n\"\n         \" lower intensity values:\\n\"\n         \"\\n\"\n         \"  brown:  red+orange:  RGB(0.5, 0.125, 0) (dark red+orange)\\n\"\n         \"  pink:   red+white:   RGB(1.0, 0.5,   0.5)\\n\"\n         \"  orange: red+yellow:  RGB(1.0, 0.5,   0)\\n\"\n         \"  gray:   black+white: RGB(0.5, 0.5,   0.5)\\n\"\n         \"\\n\"\n         \" The RGB values are selected to make detection of aliasing errors\\n\"\n         \" easy. The names are selected to make the description of errors\\n\"\n         \" easy.\\n\"\n         \"\\n\"\n         \" The PNG is written to stdout, if --8bit is given a 32bpp RGBA sRGB\\n\"\n         \" file is produced, otherwise a 64bpp RGBA linear encoded file is\\n\"\n         \" written.\\n\");\n   }\n\n   return 1;\n}\n#endif /* SIMPLIFIED_WRITE && STDIO */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/tools/intgamma.sh",
    "content": "#!/bin/sh\n#\n# intgamma.sh\n#\n# Last changed in libpng 1.6.0 [February 14, 2013]\n#\n# COPYRIGHT: Written by John Cunningham Bowler, 2013.\n# To the extent possible under law, the author has waived all copyright and\n# related or neighboring rights to this work.  This work is published from:\n# United States.\n#\n# Shell script to generate png.c 8-bit and 16-bit log tables (see the code in\n# png.c for details).\n#\n# This script uses the \"bc\" arbitrary precision calculator to calculate 32-bit\n# fixed point values of logarithms appropriate to finding the log of an 8-bit\n# (0..255) value and a similar table for the exponent calculation.\n#\n# \"bc\" must be on the path when the script is executed, and the math library\n# (-lm) must be available\n#\n# function to print out a list of numbers as integers; the function truncates\n# the integers which must be one-per-line\nfunction print(){\n   awk 'BEGIN{\n      str = \"\"\n   }\n   {\n      sub(\"\\\\.[0-9]*$\", \"\")\n      if ($0 == \"\")\n         $0 = \"0\"\n\n      if (str == \"\")\n         t = \"   \" $0 \"U\"\n      else\n         t = str \", \" $0 \"U\"\n\n      if (length(t) >= 80) {\n         print str \",\"\n         str = \"   \" $0 \"U\"\n      } else\n         str = t\n   }\n   END{\n      print str\n   }'\n}\n#\n# The logarithm table.\ncat <<END\n/* 8-bit log table: png_8bit_l2[128]\n * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to\n * 255, so it's the base 2 logarithm of a normalized 8-bit floating point\n * mantissa.  The numbers are 32-bit fractions.\n */\nstatic const png_uint_32\npng_8bit_l2[128] =\n{\nEND\n#\nbc -lqws <<END | print\nf=65536*65536/l(2)\nfor (i=128;i<256;++i) { .5 - l(i/255)*f; }\nEND\necho '};'\necho\n#\n# The exponent table.\ncat <<END\n/* The 'exp()' case must invert the above, taking a 20-bit fixed point\n * logarithmic value and returning a 16 or 8-bit number as appropriate.  In\n * each case only the low 16 bits are relevant - the fraction - since the\n * integer bits (the top 4) simply determine a shift.\n *\n * The worst case is the 16-bit distinction between 65535 and 65534; this\n * requires perhaps spurious accuracy in the decoding of the logarithm to\n * distinguish log2(65535/65534.5) - 10^-5 or 17 bits.  There is little chance\n * of getting this accuracy in practice.\n *\n * To deal with this the following exp() function works out the exponent of the\n * frational part of the logarithm by using an accurate 32-bit value from the\n * top four fractional bits then multiplying in the remaining bits.\n */\nstatic const png_uint_32\npng_32bit_exp[16] =\n{\nEND\n#\nbc -lqws <<END | print\nf=l(2)/16\nfor (i=0;i<16;++i) {\n   x = .5 + e(-i*f)*2^32;\n   if (x >= 2^32) x = 2^32-1;\n   x;\n}\nEND\necho '};'\necho\n#\n# And the table of adjustment values.\ncat <<END\n/* Adjustment table; provided to explain the numbers in the code below. */\n#if 0\nEND\nbc -lqws <<END | awk '{ printf \"%5d %s\\n\", 12-NR, $0 }'\nfor (i=11;i>=0;--i){\n   (1 - e(-(2^i)/65536*l(2))) * 2^(32-i)\n}\nEND\necho '#endif'\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/tools/makesRGB.c",
    "content": "/* makesRGB.c -- build sRGB-to-linear and linear-to-sRGB conversion tables\n *\n * Last changed in libpng 1.6.0 [February 14, 2013]\n *\n * COPYRIGHT: Written by John Cunningham Bowler, 2013.\n * To the extent possible under law, the author has waived all copyright and\n * related or neighboring rights to this work.  This work is published from:\n * United States.\n *\n * Make a table to convert 8-bit sRGB encoding values into the closest 16-bit\n * linear value.\n *\n * Make two tables to take a linear value scaled to 255*65535 and return an\n * approximation to the 8-bit sRGB encoded value.  Calculate the error in these\n * tables and display it.\n */\n#define _C99_SOURCE 1\n#include <stdio.h>\n#include <math.h>\n#include <stdlib.h>\n\n/* pngpriv.h includes the definition of 'PNG_sRGB_FROM_LINEAR' which is required\n * to verify the actual code.\n */\n#include \"../../pngpriv.h\"\n\n#include \"sRGB.h\"\n\n/* The tables are declared 'const' in pngpriv.h, so this redefines the tables to\n * be used.\n */\n#define png_sRGB_table sRGB_table\n#define png_sRGB_base sRGB_base\n#define png_sRGB_delta sRGB_delta\n\nstatic png_uint_16 png_sRGB_table[256];\nstatic png_uint_16 png_sRGB_base[512];\nstatic png_byte png_sRGB_delta[512];\n\nstatic const unsigned int max_input = 255*65535;\n\ndouble\nfsRGB(double l)\n{\n   return sRGB_from_linear(l/max_input);\n}\n\ndouble\nsRGB(unsigned int i)\n{\n   return fsRGB(i);\n}\n\ndouble\nfinvsRGB(unsigned int i)\n{\n   return 65535 * linear_from_sRGB(i/255.);\n}\n\npng_uint_16\ninvsRGB(unsigned int i)\n{\n   unsigned int x = nearbyint(finvsRGB(i));\n\n   if (x > 65535)\n   {\n      fprintf(stderr, \"invsRGB(%u) overflows to %u\\n\", i, x);\n      exit(1);\n   }\n\n   return (png_uint_16)x;\n}\n\nint\nmain(int argc, char **argv)\n{\n   unsigned int i, i16, ibase;\n   double min_error = 0;\n   double max_error = 0;\n   double min_error16 = 0;\n   double max_error16 = 0;\n   double adjust;\n   double adjust_lo = 0.4, adjust_hi = 0.6, adjust_mid = 0.5;\n   unsigned int ec_lo = 0, ec_hi = 0, ec_mid = 0;\n   unsigned int error_count = 0;\n   unsigned int error_count16 = 0;\n   int test_only = 0;\n\n   if (argc > 1)\n      test_only = strcmp(\"--test\", argv[1]) == 0;\n\n   /* Initialize the encoding table first. */\n   for (i=0; i<256; ++i)\n   {\n      png_sRGB_table[i] = invsRGB(i);\n   }\n\n   /* Now work out the decoding tables (this is where the error comes in because\n    * there are 512 set points and 512 straight lines between them.)\n    */\n   for (;;)\n   {\n      if (ec_lo == 0)\n         adjust = adjust_lo;\n\n      else if (ec_hi == 0)\n         adjust = adjust_hi;\n\n      else if (ec_mid == 0)\n         adjust = adjust_mid;\n\n      else if (ec_mid < ec_hi)\n         adjust = (adjust_mid + adjust_hi)/2;\n\n      else if (ec_mid < ec_lo)\n         adjust = (adjust_mid + adjust_lo)/2;\n\n      else\n      {\n         fprintf(stderr, \"not reached: %u .. %u .. %u\\n\", ec_lo, ec_mid, ec_hi);\n         exit(1);\n      }\n\n      /* Calculate the table using the current 'adjust' */\n      for (i=0; i<=511; ++i)\n      {\n         double lo = 255 * sRGB(i << 15);\n         double hi = 255 * sRGB((i+1) << 15);\n         unsigned int calc;\n\n         calc = nearbyint((lo+adjust) * 256);\n         if (calc > 65535)\n         {\n            fprintf(stderr, \"table[%d][0]: overflow %08x (%d)\\n\", i, calc,\n               calc);\n            exit(1);\n         }\n         png_sRGB_base[i] = calc;\n\n         calc = nearbyint((hi-lo) * 32);\n         if (calc > 255)\n         {\n            fprintf(stderr, \"table[%d][1]: overflow %08x (%d)\\n\", i, calc,\n               calc);\n            exit(1);\n         }\n         png_sRGB_delta[i] = calc;\n      }\n\n      /* Check the 16-bit linear values alone: */\n      error_count16 = 0;\n      for (i16=0; i16 <= 65535; ++i16)\n      {\n         unsigned int i = 255*i16;\n         unsigned int iexact = nearbyint(255*sRGB(i));\n         unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);\n\n         if (icalc != iexact)\n            ++error_count16;\n      }\n\n      /* Now try changing the adjustment. */\n      if (ec_lo == 0)\n         ec_lo = error_count16;\n\n      else if (ec_hi == 0)\n         ec_hi = error_count16;\n\n      else if (ec_mid == 0)\n      {\n         ec_mid = error_count16;\n         printf(\"/* initial error counts: %u .. %u .. %u */\\n\", ec_lo, ec_mid,\n            ec_hi);\n      }\n\n      else if (error_count16 < ec_mid)\n      {\n         printf(\"/* adjust (mid ): %f: %u -> %u */\\n\", adjust, ec_mid,\n            error_count16);\n         ec_mid = error_count16;\n         adjust_mid = adjust;\n      }\n\n      else if (adjust < adjust_mid && error_count16 < ec_lo)\n      {\n         printf(\"/* adjust (low ): %f: %u -> %u */\\n\", adjust, ec_lo,\n            error_count16);\n         ec_lo = error_count16;\n         adjust_lo = adjust;\n      }\n\n      else if (adjust > adjust_mid && error_count16 < ec_hi)\n      {\n         printf(\"/* adjust (high): %f: %u -> %u */\\n\", adjust, ec_hi,\n            error_count16);\n         ec_hi = error_count16;\n         adjust_hi = adjust;\n      }\n\n      else\n      {\n         adjust = adjust_mid;\n         printf(\"/* adjust: %f: %u */\\n\", adjust, ec_mid);\n         break;\n      }\n   }\n\n   /* For each entry in the table try to adjust it to minimize the error count\n    * in that entry.  Each entry corresponds to 128 input values.\n    */\n   for (ibase=0; ibase<65536; ibase+=128)\n   {\n      png_uint_16 base = png_sRGB_base[ibase >> 7], trybase = base, ob=base;\n      png_byte delta = png_sRGB_delta[ibase >> 7], trydelta = delta, od=delta;\n      unsigned int ecbase = 0, eco;\n\n      for (;;)\n      {\n         png_sRGB_base[ibase >> 7] = trybase;\n         png_sRGB_delta[ibase >> 7] = trydelta;\n\n         /* Check the 16-bit linear values alone: */\n         error_count16 = 0;\n         for (i16=ibase; i16 < ibase+128; ++i16)\n         {\n            unsigned int i = 255*i16;\n            unsigned int iexact = nearbyint(255*sRGB(i));\n            unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);\n\n            if (icalc != iexact)\n               ++error_count16;\n         }\n\n         if (error_count16 == 0)\n            break;\n\n         if (ecbase == 0)\n         {\n            eco = ecbase = error_count16;\n            ++trybase; /* First test */\n         }\n\n         else if (error_count16 < ecbase)\n         {\n            if (trybase > base)\n            {\n               base = trybase;\n               ++trybase;\n            }\n            else if (trybase < base)\n            {\n               base = trybase;\n               --trybase;\n            }\n            else if (trydelta > delta)\n            {\n               delta = trydelta;\n               ++trydelta;\n            }\n            else if (trydelta < delta)\n            {\n               delta = trydelta;\n               --trydelta;\n            }\n            else\n            {\n               fprintf(stderr, \"makesRGB: impossible\\n\");\n               exit(1);\n            }\n            ecbase = error_count16;\n         }\n\n         else\n         {\n            if (trybase > base)\n               trybase = base-1;\n            else if (trybase < base)\n            {\n               trybase = base;\n               ++trydelta;\n            }\n            else if (trydelta > delta)\n               trydelta = delta-1;\n            else if (trydelta < delta)\n               break; /* end of tests */\n         }\n      }\n\n      png_sRGB_base[ibase >> 7] = base;\n      png_sRGB_delta[ibase >> 7] = delta;\n      if (base != ob || delta != od)\n      {\n         printf(\"/* table[%u]={%u,%u} -> {%u,%u} %u -> %u errors */\\n\",\n            ibase>>7, ob, od, base, delta, eco, ecbase);\n      }\n      else if (0)\n         printf(\"/* table[%u]={%u,%u} %u errors */\\n\", ibase>>7, ob, od,\n            ecbase);\n   }\n\n   /* Only do the full (slow) test at the end: */\n   min_error = -.4999;\n   max_error = .4999;\n   error_count = 0;\n\n   for (i=0; i <= max_input; ++i)\n   {\n      unsigned int iexact = nearbyint(255*sRGB(i));\n      unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);\n\n      if (icalc != iexact)\n      {\n         double err = 255*sRGB(i) - icalc;\n\n         if (err > (max_error+.001) || err < (min_error-.001))\n         {\n            printf(\n               \"/* 0x%08x: exact: %3d, got: %3d [tables: %08x, %08x] (%f) */\\n\",\n               i, iexact, icalc, png_sRGB_base[i>>15],\n               png_sRGB_delta[i>>15], err);\n         }\n\n         ++error_count;\n         if (err > max_error)\n            max_error = err;\n         else if (err < min_error)\n            min_error = err;\n      }\n   }\n\n   /* Re-check the 16-bit cases too, including the warning if there is an error\n    * bigger than 1.\n    */\n   error_count16 = 0;\n   max_error16 = 0;\n   min_error16 = 0;\n   for (i16=0; i16 <= 65535; ++i16)\n   {\n      unsigned int i = 255*i16;\n      unsigned int iexact = nearbyint(255*sRGB(i));\n      unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);\n\n      if (icalc != iexact)\n      {\n         double err = 255*sRGB(i) - icalc;\n\n         ++error_count16;\n         if (err > max_error16)\n            max_error16 = err;\n         else if (err < min_error16)\n            min_error16 = err;\n\n         if (abs(icalc - iexact) > 1)\n            printf(\n               \"/* 0x%04x: exact: %3d, got: %3d [tables: %08x, %08x] (%f) */\\n\",\n               i16, iexact, icalc, png_sRGB_base[i>>15],\n               png_sRGB_delta[i>>15], err);\n      }\n   }\n\n   /* Check the round trip for each 8-bit sRGB value. */\n   for (i16=0; i16 <= 255; ++i16)\n   {\n      unsigned int i = 255 * png_sRGB_table[i16];\n      unsigned int iexact = nearbyint(255*sRGB(i));\n      unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);\n\n      if (i16 != iexact)\n      {\n         fprintf(stderr, \"8-bit rounding error: %d -> %d\\n\", i16, iexact);\n         exit(1);\n      }\n\n      if (icalc != i16)\n      {\n         double finv = finvsRGB(i16);\n\n         printf(\"/* 8-bit roundtrip error: %d -> %f -> %d(%f) */\\n\",\n            i16, finv, icalc, fsRGB(255*finv));\n      }\n   }\n\n\n   printf(\"/* error: %g - %g, %u (%g%%) of readings inexact */\\n\",\n      min_error, max_error, error_count, (100.*error_count)/max_input);\n   printf(\"/* 16-bit error: %g - %g, %u (%g%%) of readings inexact */\\n\",\n      min_error16, max_error16, error_count16, (100.*error_count16)/65535);\n\n   if (!test_only)\n   {\n      printf(\"PNG_CONST png_uint_16 png_sRGB_table[256] =\\n{\\n   \");\n      for (i=0; i<255; )\n      {\n         do\n         {\n            printf(\"%d,\", png_sRGB_table[i++]);\n         }\n         while ((i & 0x7) != 0 && i<255);\n         if (i<255) printf(\"\\n   \");\n      }\n      printf(\"%d\\n};\\n\\n\", png_sRGB_table[i]);\n\n\n      printf(\"PNG_CONST png_uint_16 png_sRGB_base[512] =\\n{\\n   \");\n      for (i=0; i<511; )\n      {\n         do\n         {\n            printf(\"%d,\", png_sRGB_base[i++]);\n         }\n         while ((i & 0x7) != 0 && i<511);\n         if (i<511) printf(\"\\n   \");\n      }\n      printf(\"%d\\n};\\n\\n\", png_sRGB_base[i]);\n\n      printf(\"PNG_CONST png_byte png_sRGB_delta[512] =\\n{\\n   \");\n      for (i=0; i<511; )\n      {\n         do\n         {\n            printf(\"%d,\", png_sRGB_delta[i++]);\n         }\n         while ((i & 0xf) != 0 && i<511);\n         if (i<511) printf(\"\\n   \");\n      }\n      printf(\"%d\\n};\\n\\n\", png_sRGB_delta[i]);\n   }\n\n   return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/tools/png-fix-itxt.c",
    "content": "\n/* png-fix-itxt version 1.0.0\n *\n * Copyright 2015 Glenn Randers-Pehrson\n * Last changed in libpng 1.6.18 [July 23, 2015]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * Usage:\n *\n *     png-fix-itxt.exe < bad.png > good.png\n *\n * Fixes a PNG file written with libpng-1.6.0 or 1.6.1 that has one or more\n * uncompressed iTXt chunks.  Assumes that the actual length is greater\n * than or equal to the value in the length byte, and that the CRC is\n * correct for the actual length.  This program hunts for the CRC and\n * adjusts the length byte accordingly.  It is not an error to process a\n * PNG file that has no iTXt chunks or one that has valid iTXt chunks;\n * such files will simply be copied.\n *\n * Requires zlib (for crc32 and Z_NULL); build with\n *\n *     gcc -O -o png-fix-itxt png-fix-itxt.c -lz\n *\n * If you need to handle iTXt chunks larger than 500000 kbytes you must\n * rebuild png-fix-itxt with a larger values of MAX_LENGTH (or a smaller value\n * if you know you will never encounter such huge iTXt chunks).\n */\n\n#include <stdio.h>\n#include <zlib.h>\n\n#define MAX_LENGTH 500000\n\n/* Read one character (inchar), also return octet (c), break if EOF */\n#define GETBREAK inchar=getchar(); \\\n                 c=(inchar & 0xffU);\\\n                 if (inchar != c) break\nint\nmain(void)\n{\n   unsigned int i;\n   unsigned char buf[MAX_LENGTH];\n   unsigned long crc;\n   unsigned char c;\n   int inchar;\n\n/* Skip 8-byte signature */\n   for (i=8; i; i--)\n   {\n      GETBREAK;\n      putchar(c);\n   }\n\nif (inchar == c) /* !EOF */\nfor (;;)\n {\n   /* Read the length */\n   unsigned long length; /* must be 32 bits! */\n   GETBREAK; buf[0] = c; length  = c; length <<= 8;\n   GETBREAK; buf[1] = c; length += c; length <<= 8;\n   GETBREAK; buf[2] = c; length += c; length <<= 8;\n   GETBREAK; buf[3] = c; length += c;\n\n   /* Read the chunkname */\n   GETBREAK; buf[4] = c;\n   GETBREAK; buf[5] = c;\n   GETBREAK; buf[6] = c;\n   GETBREAK; buf[7] = c;\n\n\n   /* The iTXt chunk type expressed as integers is (105, 84, 88, 116) */\n   if (buf[4] == 105 && buf[5] == 84 && buf[6] == 88 && buf[7] == 116)\n   {\n      if (length >= MAX_LENGTH-12)\n         break;  /* To do: handle this more gracefully */\n\n      /* Initialize the CRC */\n      crc = crc32(0, Z_NULL, 0);\n\n      /* Copy the data bytes */\n      for (i=8; i < length + 12; i++)\n      {\n         GETBREAK; buf[i] = c;\n      }\n\n      if (inchar != c) /* EOF */\n         break;\n\n      /* Calculate the CRC */\n      crc = crc32(crc, buf+4, (uInt)length+4);\n\n      for (;;)\n      {\n        /* Check the CRC */\n        if (((crc >> 24) & 0xffU) == buf[length+8] &&\n            ((crc >> 16) & 0xffU) == buf[length+9] &&\n            ((crc >>  8) & 0xffU) == buf[length+10] &&\n            ((crc      ) & 0xffU) == buf[length+11])\n           break;\n\n        length++;\n\n        if (length >= MAX_LENGTH-12)\n           break;\n\n        GETBREAK;\n        buf[length+11] = c;\n\n        /* Update the CRC */\n        crc = crc32(crc, buf+7+length, 1);\n      }\n\n      if (inchar != c) /* EOF */\n         break;\n\n      /* Update length bytes */\n      buf[0] = (unsigned char)((length >> 24) & 0xffU);\n      buf[1] = (unsigned char)((length >> 16) & 0xffU);\n      buf[2] = (unsigned char)((length >>  8) & 0xffU);\n      buf[3] = (unsigned char)((length      ) & 0xffU);\n\n      /* Write the fixed iTXt chunk (length, name, data, crc) */\n      for (i=0; i<length+12; i++)\n         putchar(buf[i]);\n   }\n\n   else\n   {\n      if (inchar != c) /* EOF */\n         break;\n\n      /* Copy bytes that were already read (length and chunk name) */\n      for (i=0; i<8; i++)\n         putchar(buf[i]);\n\n      /* Copy data bytes and CRC */\n      for (i=8; i< length+12; i++)\n      {\n         GETBREAK;\n         putchar(c);\n      }\n\n      if (inchar != c) /* EOF */\n      {\n         break;\n      }\n\n   /* The IEND chunk type expressed as integers is (73, 69, 78, 68) */\n      if (buf[4] == 73 && buf[5] == 69 && buf[6] == 78 && buf[7] == 68)\n         break;\n   }\n\n   if (inchar != c) /* EOF */\n      break;\n\n   if (buf[4] == 73 && buf[5] == 69 && buf[6] == 78 && buf[7] == 68)\n     break;\n }\n\n return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/tools/pngfix.c",
    "content": "/* pngfix.c\n *\n * Copyright (c) 2014-2016 John Cunningham Bowler\n *\n * Last changed in libpng 1.6.21 [January 15, 2016]\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * Tool to check and fix the zlib inflate 'too far back' problem.\n * See the usage message for more information.\n */\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <ctype.h>\n#include <limits.h>\n#include <errno.h>\n#include <assert.h>\n\n#define implies(x,y) assert(!(x) || (y))\n\n#ifdef __GNUC__\n   /* This is used to fix the error:\n    *\n    * pngfix.c:\n    * In function 'zlib_advance':\n    * pngfix.c:181:13: error: assuming signed overflow does not\n    *   occur when simplifying conditional to constant [-Werror=strict-overflow]\n    */\n#  define FIX_GCC volatile\n#else\n#  define FIX_GCC\n#endif\n\n#define PROGRAM_NAME \"pngfix\"\n\n/* Define the following to use this program against your installed libpng,\n * rather than the one being built here:\n */\n#ifdef PNG_FREESTANDING_TESTS\n#  include <png.h>\n#else\n#  include \"../../png.h\"\n#endif\n\n#if PNG_LIBPNG_VER < 10603 /* 1.6.3 */\n#  error \"pngfix will not work with libpng prior to 1.6.3\"\n#endif\n\n#ifdef PNG_SETJMP_SUPPORTED\n#include <setjmp.h>\n\n#if defined(PNG_READ_SUPPORTED) && defined(PNG_EASY_ACCESS_SUPPORTED) &&\\\n   (defined(PNG_READ_DEINTERLACE_SUPPORTED) ||\\\n    defined(PNG_READ_INTERLACING_SUPPORTED))\n\n/* zlib.h defines the structure z_stream, an instance of which is included\n * in this structure and is required for decompressing the LZ compressed\n * data in PNG files.\n */\n#ifndef ZLIB_CONST\n   /* We must ensure that zlib uses 'const' in declarations. */\n#  define ZLIB_CONST\n#endif\n#include <zlib.h>\n#ifdef const\n   /* zlib.h sometimes #defines const to nothing, undo this. */\n#  undef const\n#endif\n\n/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility\n * with older builds.\n */\n#if ZLIB_VERNUM < 0x1260\n#  define PNGZ_MSG_CAST(s) constcast(char*,s)\n#  define PNGZ_INPUT_CAST(b) constcast(png_bytep,b)\n#else\n#  define PNGZ_MSG_CAST(s) (s)\n#  define PNGZ_INPUT_CAST(b) (b)\n#endif\n\n#ifndef PNG_MAXIMUM_INFLATE_WINDOW\n#  error \"pngfix not supported in this libpng version\"\n#endif\n\n#if ZLIB_VERNUM >= 0x1240\n\n/* Copied from pngpriv.h */\n#ifdef __cplusplus\n#  define voidcast(type, value) static_cast<type>(value)\n#  define constcast(type, value) const_cast<type>(value)\n#  define aligncast(type, value) \\\n   static_cast<type>(static_cast<void*>(value))\n#  define aligncastconst(type, value) \\\n   static_cast<type>(static_cast<const void*>(value))\n#else\n#  define voidcast(type, value) (value)\n#  define constcast(type, value) ((type)(value))\n#  define aligncast(type, value) ((void*)(value))\n#  define aligncastconst(type, value) ((const void*)(value))\n#endif /* __cplusplus */\n\n#if PNG_LIBPNG_VER < 10700\n/* Chunk tags (copied from pngpriv.h) */\n#define PNG_32b(b,s) ((png_uint_32)(b) << (s))\n#define PNG_U32(b1,b2,b3,b4) \\\n   (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0))\n\n/* Constants for known chunk types. */\n#define png_IDAT PNG_U32( 73,  68,  65,  84)\n#define png_IEND PNG_U32( 73,  69,  78,  68)\n#define png_IHDR PNG_U32( 73,  72,  68,  82)\n#define png_PLTE PNG_U32( 80,  76,  84,  69)\n#define png_bKGD PNG_U32( 98,  75,  71,  68)\n#define png_cHRM PNG_U32( 99,  72,  82,  77)\n#define png_fRAc PNG_U32(102,  82,  65,  99) /* registered, not defined */\n#define png_gAMA PNG_U32(103,  65,  77,  65)\n#define png_gIFg PNG_U32(103,  73,  70, 103)\n#define png_gIFt PNG_U32(103,  73,  70, 116) /* deprecated */\n#define png_gIFx PNG_U32(103,  73,  70, 120)\n#define png_hIST PNG_U32(104,  73,  83,  84)\n#define png_iCCP PNG_U32(105,  67,  67,  80)\n#define png_iTXt PNG_U32(105,  84,  88, 116)\n#define png_oFFs PNG_U32(111,  70,  70, 115)\n#define png_pCAL PNG_U32(112,  67,  65,  76)\n#define png_pHYs PNG_U32(112,  72,  89, 115)\n#define png_sBIT PNG_U32(115,  66,  73,  84)\n#define png_sCAL PNG_U32(115,  67,  65,  76)\n#define png_sPLT PNG_U32(115,  80,  76,  84)\n#define png_sRGB PNG_U32(115,  82,  71,  66)\n#define png_sTER PNG_U32(115,  84,  69,  82)\n#define png_tEXt PNG_U32(116,  69,  88, 116)\n#define png_tIME PNG_U32(116,  73,  77,  69)\n#define png_tRNS PNG_U32(116,  82,  78,  83)\n#define png_zTXt PNG_U32(122,  84,  88, 116)\n#endif\n\n/* The 8-byte signature as a pair of 32-bit quantities */\n#define sig1 PNG_U32(137,  80,  78,  71)\n#define sig2 PNG_U32( 13,  10,  26,  10)\n\n/* Is the chunk critical? */\n#define CRITICAL(chunk) (((chunk) & PNG_U32(32,0,0,0)) == 0)\n\n/* Is it safe to copy? */\n#define SAFE_TO_COPY(chunk) (((chunk) & PNG_U32(0,0,0,32)) != 0)\n\n/* Fix ups for builds with limited read support */\n#ifndef PNG_ERROR_TEXT_SUPPORTED\n#  define png_error(a,b) png_err(a)\n#endif\n\n/********************************* UTILITIES **********************************/\n/* UNREACHED is a value to cause an assert to fail. Because of the way the\n * assert macro is written the string \"UNREACHED\" is produced in the error\n * message.\n */\n#define UNREACHED 0\n\n/* 80-bit number handling - a PNG image can be up to (2^31-1)x(2^31-1) 8-byte\n * (16-bit RGBA) pixels in size; that's less than 2^65 bytes or 2^68 bits, so\n * arithmetic of 80-bit numbers is sufficient.  This representation uses an\n * arbitrary length array of png_uint_16 digits (0..65535).  The representation\n * is little endian.\n *\n * The arithmetic functions take zero to two uarb values together with the\n * number of digits in those values and write the result to the given uarb\n * (always the first argument) returning the number of digits in the result.\n * If the result is negative the return value is also negative (this would\n * normally be an error).\n */\ntypedef png_uint_16  udigit; /* A 'unum' is an array of these */\ntypedef png_uint_16p uarb;\ntypedef png_const_uint_16p uarbc;\n\n#define UDIGITS(unum) ((sizeof unum)/(sizeof (udigit))\n   /* IMPORTANT: only apply this to an array, applied to a pointer the result\n    * will typically be '2', which is not useful.\n    */\n\nstatic int\nuarb_set(uarb result, png_alloc_size_t val)\n   /* Set (initialize) 'result' to 'val'.  The size required for 'result' must\n    * be determined by the caller from a knowledge of the maximum for 'val'.\n    */\n{\n   int ndigits = 0;\n\n   while (val > 0)\n   {\n      result[ndigits++] = (png_uint_16)(val & 0xffff);\n      val >>= 16;\n   }\n\n   return ndigits;\n}\n\nstatic int\nuarb_copy(uarb to, uarb from, int idigits)\n   /* Copy a uarb, may reduce the digit count */\n{\n   int d, odigits;\n\n   for (d=odigits=0; d<idigits; ++d)\n      if ((to[d] = from[d]) != 0)\n         odigits = d+1;\n\n   return odigits;\n}\n\nstatic int\nuarb_inc(uarb num, int in_digits, png_int_32 add)\n   /* This is a signed 32-bit add, except that to avoid overflow the value added\n    * or subtracted must be no more than 2^31-65536.  A negative result\n    * indicates a negative number (which is an error below).  The size of\n    * 'num' should be max(in_digits+1,2) for arbitrary 'add' but can be just\n    * in_digits+1 if add is known to be in the range -65535..65535.\n    */\n{\n   FIX_GCC int out_digits = 0;\n\n   while (out_digits < in_digits)\n   {\n      add += num[out_digits];\n      num[out_digits++] = (png_uint_16)(add & 0xffff);\n      add >>= 16;\n   }\n\n   while (add != 0 && add != (-1))\n   {\n      num[out_digits++] = (png_uint_16)(add & 0xffff);\n      add >>= 16;\n   }\n\n   if (add == 0)\n   {\n      while (out_digits > 0 && num[out_digits-1] == 0)\n         --out_digits;\n      return out_digits; /* may be 0 */\n   }\n\n   else /* negative result */\n   {\n      while (out_digits > 1 && num[out_digits-1] == 0xffff)\n         --out_digits;\n\n      return -out_digits;\n   }\n}\n\nstatic int\nuarb_add32(uarb num, int in_digits, png_uint_32 add)\n   /* As above but this works with any 32-bit value and only does 'add' */\n{\n   if (in_digits > 0)\n   {\n      in_digits = uarb_inc(num, in_digits, add & 0xffff);\n      return uarb_inc(num+1, in_digits-1, add >> 16)+1;\n   }\n\n   return uarb_set(num, add);\n}\n\nstatic int\nuarb_mult_digit(uarb acc, int a_digits, uarb num, FIX_GCC int n_digits,\n   png_uint_16 val)\n   /* Primitive one-digit multiply - 'val' must be 0..65535. Note that this\n    * primitive is a multiply and accumulate - the result of *num * val is added\n    * to *acc.\n    *\n    * This is a one-digit multiply, so the product may be up to one digit longer\n    * than 'num', however the add to 'acc' means that the caller must ensure\n    * that 'acc' is at least one digit longer than this *and* at least one digit\n    * longer than the current length of 'acc'.  (Or the caller must otherwise\n    * ensure 'adigits' is adequate from knowledge of the values.)\n    */\n{\n   /* The digits in *acc, *num and val are in the range 0..65535, so the\n    * result below is at most (65535*65535)+2*65635 = 65535*(65535+2), which is\n    * exactly 0xffffffff.\n    */\n   if (val > 0 && n_digits > 0) /* Else the product is 0 */\n   {\n      png_uint_32 carry = 0;\n      int out_digits = 0;\n\n      while (out_digits < n_digits || carry > 0)\n      {\n         if (out_digits < a_digits)\n            carry += acc[out_digits];\n\n         if (out_digits < n_digits)\n            carry += (png_uint_32)num[out_digits] * val;\n\n         acc[out_digits++] = (png_uint_16)(carry & 0xffff);\n         carry >>= 16;\n      }\n\n      /* So carry is 0 and all the input digits have been consumed. This means\n       * that it is possible to skip any remaining digits in acc.\n       */\n      if (out_digits > a_digits)\n         return out_digits;\n   }\n\n   return a_digits;\n}\n\nstatic int\nuarb_mult32(uarb acc, int a_digits, uarb num, int n_digits, png_uint_32 val)\n   /* calculate acc += num * val, 'val' may be any 32-bit value, 'acc' and 'num'\n    * may be any value, returns the number of digits in 'acc'.\n    */\n{\n   if (n_digits > 0 && val > 0)\n   {\n      a_digits = uarb_mult_digit(acc, a_digits, num, n_digits,\n         (png_uint_16)(val & 0xffff));\n\n      val >>= 16;\n      if (val > 0)\n         a_digits = uarb_mult_digit(acc+1, a_digits-1, num, n_digits,\n            (png_uint_16)val) + 1;\n\n      /* Because n_digits and val are >0 the following must be true: */\n      assert(a_digits > 0);\n   }\n\n   return a_digits;\n}\n\nstatic int\nuarb_shift(uarb inout, int ndigits, unsigned int right_shift)\n   /* Shift inout right by right_shift bits, right_shift must be in the range\n    * 1..15\n    */\n{\n   FIX_GCC int i = ndigits;\n   png_uint_16 carry = 0;\n\n   assert(right_shift >= 1 && right_shift <= 15);\n\n   while (--i >= 0)\n   {\n      png_uint_16 temp = (png_uint_16)(carry | (inout[i] >> right_shift));\n\n      /* Bottom bits to top bits of carry */\n      carry = (png_uint_16)((inout[i] << (16-right_shift)) & 0xffff);\n\n      inout[i] = temp;\n\n      /* The shift may reduce ndigits */\n      if (i == ndigits-1 && temp == 0)\n         ndigits = i;\n   }\n\n   return ndigits;\n}\n\nstatic int\nuarb_cmp(uarb a, int adigits, uarb b, int bdigits)\n   /* Return -1/0/+1 according as a<b/a==b/a>b */\n{\n   if (adigits < bdigits)\n      return -1;\n\n   if (adigits > bdigits)\n      return 1;\n\n   while (adigits-- > 0)\n      if (a[adigits] < b[adigits])\n         return -1;\n\n      else if (a[adigits] > b[adigits])\n         return 1;\n\n   return 0;\n}\n\n#if 0 /*UNUSED*/\nstatic int\nuarb_eq32(uarb num, int digits, png_uint_32 val)\n   /* Return true if the uarb is equal to 'val' */\n{\n   switch (digits)\n   {\n      case 0:  return val == 0;\n      case 1:  return val == num[0];\n      case 2:  return (val & 0xffff) == num[0] && (val >> 16) == num[1];\n      default: return 0;\n   }\n}\n#endif\n\nstatic void\nuarb_printx(uarb num, int digits, FILE *out)\n   /* Print 'num' as a hexadecimal number (easier than decimal!) */\n{\n   while (digits > 0)\n      if (num[--digits] > 0)\n      {\n         fprintf(out, \"0x%x\", num[digits]);\n\n         while (digits > 0)\n            fprintf(out, \"%.4x\", num[--digits]);\n      }\n\n      else if (digits == 0) /* the number is 0 */\n         fputs(\"0x0\", out);\n}\n\nstatic void\nuarb_print(uarb num, int digits, FILE *out)\n   /* Prints 'num' as a decimal if it will fit in an unsigned long, else as a\n    * hexadecimal number.  Notice that the results vary for images over 4GByte\n    * in a system dependent way, and the hexadecimal form doesn't work very well\n    * in awk script input.\n    *\n    *\n    * TODO: write uarb_div10\n    */\n{\n   if (digits * sizeof (udigit) > sizeof (unsigned long))\n      uarb_printx(num, digits, out);\n\n   else\n   {\n      unsigned long n = 0;\n\n      while (digits > 0)\n         n = (n << 16) + num[--digits];\n\n      fprintf(out, \"%lu\", n);\n   }\n}\n\n/* Generate random bytes.  This uses a boring repeatable algorithm and it\n * is implemented here so that it gives the same set of numbers on every\n * architecture.  It's a linear congruential generator (Knuth or Sedgewick\n * \"Algorithms\") but it comes from the 'feedback taps' table in Horowitz and\n * Hill, \"The Art of Electronics\" (Pseudo-Random Bit Sequences and Noise\n * Generation.)\n *\n * (Copied from contrib/libtests/pngvalid.c)\n */\nstatic void\nmake_random_bytes(png_uint_32* seed, void* pv, size_t size)\n{\n   png_uint_32 u0 = seed[0], u1 = seed[1];\n   png_bytep bytes = voidcast(png_bytep, pv);\n\n   /* There are thirty-three bits; the next bit in the sequence is bit-33 XOR\n    * bit-20.  The top 1 bit is in u1, the bottom 32 are in u0.\n    */\n   size_t i;\n   for (i=0; i<size; ++i)\n   {\n      /* First generate 8 new bits then shift them in at the end. */\n      png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff;\n      u1 <<= 8;\n      u1 |= u0 >> 24;\n      u0 <<= 8;\n      u0 |= u;\n      *bytes++ = (png_byte)u;\n   }\n\n   seed[0] = u0;\n   seed[1] = u1;\n}\n\n/* Clear an object to a random value. */\nstatic void\nclear(void *pv, size_t size)\n{\n   static png_uint_32 clear_seed[2] = { 0x12345678, 0x9abcdef0 };\n   make_random_bytes(clear_seed, pv, size);\n}\n\n#define CLEAR(object) clear(&(object), sizeof (object))\n\n/* Copied from unreleased 1.7 code.\n *\n * CRC checking uses a local pre-built implementation of the Ethernet CRC32.\n * This is to avoid a function call to the zlib DLL and to optimize the\n * byte-by-byte case.\n */\nstatic png_uint_32 crc_table[256] =\n{\n   0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,\n   0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,\n   0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,\n   0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,\n   0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,\n   0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,\n   0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,\n   0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,\n   0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,\n   0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,\n   0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,\n   0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,\n   0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,\n   0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,\n   0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,\n   0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,\n   0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,\n   0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,\n   0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,\n   0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,\n   0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,\n   0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,\n   0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,\n   0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n   0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,\n   0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,\n   0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,\n   0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,\n   0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,\n   0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,\n   0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,\n   0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,\n   0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,\n   0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,\n   0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,\n   0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,\n   0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,\n   0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,\n   0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,\n   0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,\n   0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,\n   0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,\n   0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,\n   0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,\n   0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,\n   0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,\n   0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,\n   0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n   0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,\n   0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,\n   0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,\n   0x2d02ef8d\n};\n\n/* The CRC calculated here *IS* conditioned, the corresponding value used by\n * zlib and the result value is obtained by XORing with CRC_INIT, which is also\n * the first value that must be passed in (for the first byte) to crc_one_byte.\n */\n#define CRC_INIT 0xffffffff\n\nstatic png_uint_32\ncrc_one_byte(png_uint_32 crc, int b)\n{\n   return crc_table[(crc ^ b) & 0xff] ^ (crc >> 8);\n}\n\nstatic png_uint_32\ncrc_init_4(png_uint_32 value)\n{\n   /* This is an alternative to the algorithm used in zlib, which requires four\n    * separate tables to parallelize the four byte operations, it only works for\n    * a CRC of the first four bytes of the stream, but this is what happens in\n    * the parser below where length+chunk-name is read and chunk-name used to\n    * initialize the CRC.  Notice that the calculation here avoids repeated\n    * conditioning (xor with 0xffffffff) by storing the conditioned value.\n    */\n   png_uint_32 crc = crc_table[(~value >> 24)] ^ 0xffffff;\n\n   crc = crc_table[(crc ^ (value >> 16)) & 0xff] ^ (crc >> 8);\n   crc = crc_table[(crc ^ (value >> 8)) & 0xff] ^ (crc >> 8);\n   return crc_table[(crc ^ value) & 0xff] ^ (crc >> 8);\n}\n\nstatic int\nchunk_type_valid(png_uint_32 c)\n   /* Bit whacking approach to chunk name validation that is intended to avoid\n    * branches.  The cost is that it uses a lot of 32-bit constants, which might\n    * be bad on some architectures.\n    */\n{\n   png_uint_32 t;\n\n   /* Remove bit 5 from all but the reserved byte; this means every\n    * 8-bit unit must be in the range 65-90 to be valid.  So bit 5\n    * must be zero, bit 6 must be set and bit 7 zero.\n    */\n   c &= ~PNG_U32(32,32,0,32);\n   t = (c & ~0x1f1f1f1f) ^ 0x40404040;\n\n   /* Subtract 65 for each 8-bit quantity, this must not overflow\n    * and each byte must then be in the range 0-25.\n    */\n   c -= PNG_U32(65,65,65,65);\n   t |=c ;\n\n   /* Subtract 26, handling the overflow which should set the top\n    * three bits of each byte.\n    */\n   c -= PNG_U32(25,25,25,26);\n   t |= ~c;\n\n   return (t & 0xe0e0e0e0) == 0;\n}\n\n/**************************** CONTROL INFORMATION *****************************/\n\n/* Information about a sequence of IDAT chunks, the chunks have been re-synced\n * using sync_stream below and the new lengths are recorded here.  Because the\n * number of chunks is unlimited this is handled using a linked list of these\n * structures.\n */\nstruct IDAT_list\n{\n   struct IDAT_list *next;     /* Linked list */\n   unsigned int      length;   /* Actual length of the array below */\n   unsigned int      count;    /* Number of entries that are valid */\n#     define IDAT_INIT_LENGTH 16\n   png_uint_32       lengths[IDAT_INIT_LENGTH];\n};\n\nstatic void\nIDAT_list_init(struct IDAT_list *list)\n{\n   CLEAR(*list);\n\n   list->next = NULL;\n   list->length = IDAT_INIT_LENGTH;\n}\n\nstatic size_t\nIDAT_list_size(struct IDAT_list *list, unsigned int length)\n   /* Return the size in bytes of an IDAT_list of the given length. */\n{\n   if (list != NULL)\n      length = list->length;\n\n   return sizeof *list - sizeof list->lengths +\n      length * sizeof list->lengths[0];\n}\n\nstatic void\nIDAT_list_end(struct IDAT_list *IDAT_list)\n{\n   struct IDAT_list *list = IDAT_list->next;\n\n   CLEAR(*IDAT_list);\n\n   while (list != NULL)\n   {\n      struct IDAT_list *next = list->next;\n\n      clear(list, IDAT_list_size(list, 0));\n      free(list);\n      list = next;\n   }\n}\n\nstatic struct IDAT_list *\nIDAT_list_extend(struct IDAT_list *tail)\n{\n   /* Use the previous cached value if available. */\n   struct IDAT_list *next = tail->next;\n\n   if (next == NULL)\n   {\n      /* Insert a new, malloc'ed, block of IDAT information buffers, this\n       * one twice as large as the previous one:\n       */\n      unsigned int length = 2 * tail->length;\n\n      if (length < tail->length) /* arithmetic overflow */\n         length = tail->length;\n\n      next = voidcast(IDAT_list*, malloc(IDAT_list_size(NULL, length)));\n      CLEAR(*next);\n\n      /* The caller must handle this: */\n      if (next == NULL)\n         return NULL;\n\n      next->next = NULL;\n      next->length = length;\n      tail->next = next;\n   }\n\n   return next;\n}\n\n/* GLOBAL CONTROL STRUCTURE */\nstruct global\n{\n   /* PUBLIC GLOBAL VARIABLES: OWNER INITIALIZE */\n   unsigned int   errors        :1; /* print file errors to stderr */\n   unsigned int   warnings      :1; /* print libpng warnings to stderr */\n   unsigned int   optimize_zlib :1; /* Run optimization search */\n   unsigned int   quiet         :2; /* don't output summaries */\n   unsigned int   verbose       :3; /* various internal tracking */\n   unsigned int   skip          :3; /* Non-critical chunks to skip */\n#     define SKIP_NONE      0\n#     define SKIP_BAD_CRC   1    /* Chunks with a bad CRC */\n#     define SKIP_UNSAFE    2    /* Chunks not safe to copy */\n#     define SKIP_UNUSED    3    /* Chunks not used by libpng */\n#     define SKIP_TRANSFORM 4    /* Chunks only used in transforms */\n#     define SKIP_COLOR     5    /* Everything but tRNS, sBIT, gAMA and sRGB */\n#     define SKIP_ALL       6    /* Everything but tRNS and sBIT */\n\n   png_uint_32    idat_max;         /* 0 to perform no re-chunking */\n\n   int            status_code;      /* Accumulated status code */\n#     define TOO_FAR_BACK   0x01 /* found a too-far-back error */\n#     define CRC_ERROR      0x02 /* fixed an invalid CRC */\n#     define STREAM_ERROR   0x04 /* damaged PNG stream (may be fixable) */\n#     define TRUNCATED      0x08 /* truncated but still readable */\n#     define FILE_ERROR     0x10 /* could not read the file */\n#     define WRITE_ERROR    0x20 /* write error (this terminates the read) */\n#     define INTERNAL_ERROR 0x40 /* internal limits/errors encountered */\n\n   /* PUBLIC GLOBAL VARIABLES: USED INTERNALLY BY IDAT READ CODE */\n   struct IDAT_list idat_cache;  /* Cache of file IDAT information buffers */\n      /* The structure is shared across all uses of this global control\n       * structure to avoid reallocation between IDAT streams.\n       */\n};\n\nstatic int\nglobal_end(struct global *global)\n{\n\n   int rc;\n\n   IDAT_list_end(&global->idat_cache);\n   rc = global->status_code;\n   CLEAR(*global);\n   return rc;\n}\n\nstatic void\nglobal_init(struct global *global)\n   /* Call this once (and only once) to initialize the control */\n{\n   CLEAR(*global);\n\n   /* Globals */\n   global->errors        = 0;\n   global->warnings      = 0;\n   global->quiet         = 0;\n   global->verbose       = 0;\n   global->idat_max      = 0;         /* no re-chunking of IDAT */\n   global->optimize_zlib = 0;\n   global->skip          = SKIP_NONE;\n   global->status_code   = 0;\n\n   IDAT_list_init(&global->idat_cache);\n}\n\nstatic int\nskip_chunk_type(const struct global *global, png_uint_32 type)\n   /* Return true if this chunk is to be skipped according to the --strip\n    * option.  This code needs to recognize all known ancillary chunks in order\n    * to handle the --strip=unsafe option.\n    */\n{\n   /* Never strip critical chunks: */\n   if (CRITICAL(type))\n      return 0;\n\n   switch (type)\n   {\n      /* Chunks that are treated as, effectively, critical because they affect\n       * correct interpretation of the pixel values:\n       */\n      case png_tRNS: case png_sBIT:\n         return 0;\n\n      /* Chunks that specify gamma encoding which should therefore only be\n       * removed the the user insists:\n       */\n      case png_gAMA: case png_sRGB:\n         if (global->skip >= SKIP_ALL)\n            return 1;\n         return 0;\n\n      /* Chunks that affect color interpretation - not used by libpng and rarely\n       * used by applications, but technically still required for correct\n       * interpretation of the image data:\n       */\n      case png_cHRM: case png_iCCP:\n         if (global->skip >= SKIP_COLOR)\n            return 1;\n         return 0;\n\n      /* Other chunks that are used by libpng in image transformations (as\n       * opposed to known chunks that have get/set APIs but are not otherwise\n       * used.)\n       */\n      case png_bKGD:\n         if (global->skip >= SKIP_TRANSFORM)\n            return 1;\n         return 0;\n\n      /* All other chunks that libpng knows about and affect neither image\n       * interpretation nor libpng transforms - chunks that are effectively\n       * unused by libpng even though libpng might recognize and store them.\n       */\n      case png_fRAc: case png_gIFg: case png_gIFt: case png_gIFx: case png_hIST:\n      case png_iTXt: case png_oFFs: case png_pCAL: case png_pHYs: case png_sCAL:\n      case png_sPLT: case png_sTER: case png_tEXt: case png_tIME: case png_zTXt:\n         if (global->skip >= SKIP_UNUSED)\n            return 1;\n         return 0;\n\n      /* Chunks that libpng does not know about (notice that this depends on the\n       * list above including all known chunks!)  The decision here depends on\n       * whether the safe-to-copy bit is set in the chunk type.\n       */\n      default:\n         if (SAFE_TO_COPY(type))\n         {\n            if (global->skip >= SKIP_UNUSED) /* as above */\n               return 1;\n         }\n\n         else if (global->skip >= SKIP_UNSAFE)\n            return 1;\n\n         return 0;\n   }\n}\n\n/* PER-FILE CONTROL STRUCTURE */\nstruct chunk;\nstruct IDAT;\nstruct file\n{\n   /* ANCESTORS */\n   struct global *global;\n\n   /* PUBLIC PER-FILE VARIABLES: CALLER INITIALIZE */\n   const char *   file_name;\n   const char *   out_name;      /* Name of output file (if required) */\n\n   /* PUBLIC PER-FILE VARIABLES: SET BY PNG READ CODE */\n   /* File specific result codes */\n   int            status_code;   /* Set to a bit mask of the following: */\n   int            read_errno;    /* Records a read error errno */\n   int            write_errno;   /* Records a write error errno */\n\n   /* IHDR information */\n   png_uint_32    width;\n   png_uint_32    height;\n   png_byte       bit_depth;\n   png_byte       color_type;\n   png_byte       compression_method;\n   png_byte       filter_method;\n   png_byte       interlace_method;\n\n   udigit         image_bytes[5];\n   int            image_digits;\n\n   /* PROTECTED PER-FILE VARIABLES: USED BY THE READ CODE */\n   FILE *         file;          /* Original PNG file */\n   FILE *         out;           /* If a new one is being written */\n   jmp_buf        jmpbuf;        /* Set while reading a PNG */\n\n   /* PROTECTED CHUNK SPECIFIC VARIABLES: USED BY CHUNK CODE */\n   /* The following variables are used during reading to record the length, type\n    * and data position of the *next* chunk or, right at the start, the\n    * signature (in length,type).\n    *\n    * When a chunk control structure is instantiated these values are copied\n    * into the structure and can then be overritten with the data for the next\n    * chunk.\n    */\n   fpos_t         data_pos;      /* Position of first byte of chunk data */\n   png_uint_32    length;        /* First word (length or signature start) */\n   png_uint_32    type;          /* Second word (type or signature end) */\n   png_uint_32    crc;           /* Running chunk CRC (used by read_chunk) */\n\n   /* These counts are maintained by the read and write routines below and are\n    * reset by the chunk handling code.  They record the total number of bytes\n    * read or written for the chunk, including the header (length,type) bytes.\n    */\n   png_uint_32    read_count;    /* Count of bytes read (in the chunk) */\n   png_uint_32    write_count;   /* Count of bytes written (in the chunk) */\n   int            state;         /* As defined here: */\n#     define STATE_SIGNATURE  0  /* The signature is being written */\n#     define STATE_CHUNKS     1  /* Non-IDAT chunks are being written */\n#     define STATE_IDAT       2  /* An IDAT stream is being written */\n\n   /* Two pointers used to enable clean-up in the event of fatal errors and to\n    * hold state about the parser process (only one of each at present.)\n    */\n   struct chunk * chunk;\n   struct IDAT *  idat;\n\n   /* Interface to allocate a new chunk or IDAT control structure.  The result\n    * is returned by setting one or other of the above variables.  Note that the\n    * relevant initializer is called by the allocator function.  The alloc_ptr\n    * is used only by the implementation of the allocate function.\n    */\n   void *         alloc_ptr;\n   void         (*alloc)(struct file*,int idat);\n                                  /* idat: allocate IDAT not chunk */\n};\n\n/* Valid longjmp (stop) codes are: */\n#define LIBPNG_WARNING_CODE   1 /* generic png_error */\n#define LIBPNG_ERROR_CODE     2 /* generic png_error */\n#define ZLIB_ERROR_CODE       3 /* generic zlib error */\n#define INVALID_ERROR_CODE    4 /* detected an invalid PNG */\n#define READ_ERROR_CODE       5 /* read failed */\n#define WRITE_ERROR_CODE      6 /* error in write */\n#define UNEXPECTED_ERROR_CODE 7 /* unexpected (internal?) error */\n\nstatic void\nemit_string(const char *str, FILE *out)\n   /* Print a string with spaces replaced by '_' and non-printing characters by\n    * an octal escape.\n    */\n{\n   for (; *str; ++str)\n      if (isgraph(UCHAR_MAX & *str))\n         putc(*str, out);\n\n      else if (isspace(UCHAR_MAX & *str))\n         putc('_', out);\n\n      else\n         fprintf(out, \"\\\\%.3o\", *str);\n}\n\nstatic const char *\nstrcode(int code)\n{\n   switch (code)\n   {\n      case LIBPNG_WARNING_CODE:   return \"warning\";\n      case LIBPNG_ERROR_CODE:     return \"libpng\";\n      case ZLIB_ERROR_CODE:       return \"zlib\";\n      case INVALID_ERROR_CODE:    return \"invalid\";\n      case READ_ERROR_CODE:       return \"read\";\n      case WRITE_ERROR_CODE:      return \"write\";\n      case UNEXPECTED_ERROR_CODE: return \"unexpected\";\n      default:                    return \"INVALID\";\n   }\n}\n\nstatic void\nemit_error(struct file *file, int code, const char *what)\n   /* Generic error message routine, takes a 'stop' code but can be used\n    * elsewhere.  Always outputs a message.\n    */\n{\n   const char *reason;\n   int err = 0;\n\n   switch (code)\n   {\n      case LIBPNG_WARNING_CODE:   reason = \"libpng warning:\"; break;\n      case LIBPNG_ERROR_CODE:     reason = \"libpng error:\"; break;\n      case ZLIB_ERROR_CODE:       reason = \"zlib error:\"; break;\n      case INVALID_ERROR_CODE:    reason = \"invalid\"; break;\n      case READ_ERROR_CODE:       reason = \"read failure:\";\n                                  err = file->read_errno;\n                                  break;\n      case WRITE_ERROR_CODE:      reason = \"write error\";\n                                  err = file->write_errno;\n                                  break;\n      case UNEXPECTED_ERROR_CODE: reason = \"unexpected error:\";\n                                  err = file->read_errno;\n                                  if (err == 0)\n                                     err = file->write_errno;\n                                  break;\n      default:                    reason = \"INVALID (internal error):\"; break;\n   }\n\n   if (err != 0)\n      fprintf(stderr, \"%s: %s %s [%s]\\n\", file->file_name, reason, what,\n         strerror(err));\n\n   else\n      fprintf(stderr, \"%s: %s %s\\n\", file->file_name, reason, what);\n}\n\nstatic void chunk_end(struct chunk **);\nstatic void IDAT_end(struct IDAT **);\n\nstatic int\nfile_end(struct file *file)\n{\n   int rc;\n\n   /* If either of the chunk pointers are set end them here, the IDAT structure\n    * must be deallocated first as it may deallocate the chunk structure.\n    */\n   if (file->idat != NULL)\n      IDAT_end(&file->idat);\n\n   if (file->chunk != NULL)\n      chunk_end(&file->chunk);\n\n   rc = file->status_code;\n\n   if (file->file != NULL)\n      (void)fclose(file->file);\n\n   if (file->out != NULL)\n   {\n      /* NOTE: this is bitwise |, all the following functions must execute and\n       * must succeed.\n       */\n      if (ferror(file->out) | fflush(file->out) | fclose(file->out))\n      {\n         perror(file->out_name);\n         emit_error(file, READ_ERROR_CODE, \"output write error\");\n         rc |= WRITE_ERROR;\n      }\n   }\n\n   /* Accumulate the result codes */\n   file->global->status_code |= rc;\n\n   CLEAR(*file);\n\n   return rc; /* status code: non-zero on read or write error */\n}\n\nstatic int\nfile_init(struct file *file, struct global *global, const char *file_name,\n   const char *out_name, void *alloc_ptr, void (*alloc)(struct file*,int))\n   /* Initialize a file control structure.  This will open the given files as\n    * well.  The status code returned is 0 on success, non zero (using the flags\n    * above) on a file open error.\n    */\n{\n   CLEAR(*file);\n   file->global = global;\n\n   file->file_name = file_name;\n   file->out_name = out_name;\n   file->status_code = 0;\n   file->read_errno = 0;\n   file->write_errno = 0;\n\n   file->file = NULL;\n   file->out = NULL;\n   /* jmpbuf is garbage: must be set by read_png */\n\n   file->read_count = 0;\n   file->state = STATE_SIGNATURE;\n\n   file->chunk = NULL;\n   file->idat = NULL;\n\n   file->alloc_ptr = alloc_ptr;\n   file->alloc = alloc;\n\n   /* Open the files: */\n   assert(file_name != NULL);\n   file->file = fopen(file_name, \"rb\");\n\n   if (file->file == NULL)\n   {\n      file->read_errno = errno;\n      file->status_code |= FILE_ERROR;\n      /* Always output: please give a readable file! */\n      perror(file_name);\n      return FILE_ERROR;\n   }\n\n   if (out_name != NULL)\n   {\n      file->out = fopen(out_name, \"wb\");\n\n      if (file->out == NULL)\n      {\n         file->write_errno = errno;\n         file->status_code |= WRITE_ERROR;\n         perror(out_name);\n         return WRITE_ERROR;\n      }\n   }\n\n   return 0;\n}\n\nstatic void\nlog_error(struct file *file, int code, const char *what)\n   /* Like emit_error but checks the global 'errors' flag */\n{\n   if (file->global->errors)\n      emit_error(file, code, what);\n}\n\nstatic char\ntype_char(png_uint_32 v)\n{\n   /* In fact because chunk::chunk_type is validated prior to any call to this\n    * function it will always return a-zA-Z, but the extra codes are just there\n    * to help in finding internal (programming) errors.  Note that the code only\n    * ever considers the low 7 bits of the value (so it is not necessary for the\n    * type_name function to mask of the byte.)\n    */\n   if (v & 32)\n      return \"!abcdefghijklmnopqrstuvwxyz56789\"[(v-96)&31];\n\n   else\n      return \"@ABCDEFGHIJKLMNOPQRSTUVWXYZ01234\"[(v-64)&31];\n}\n\nstatic void\ntype_name(png_uint_32 type, FILE *out)\n{\n   putc(type_char(type >> 24), out);\n   putc(type_char(type >> 16), out);\n   putc(type_char(type >>  8), out);\n   putc(type_char(type      ), out);\n}\n\nstatic void\ntype_sep(FILE *out)\n{\n   putc(':', out);\n   putc(' ', out);\n}\n\nstatic png_uint_32 current_type(struct file *file, int code);\n\nPNG_NORETURN static void\nstop(struct file *file, int code, const char *what)\n   /* Return control when a PNG file cannot be read. This outputs an 'ERR'\n    * summary line too.\n    */\n{\n   log_error(file, code, what);\n\n   /* The chunk being read is typically identified by file->chunk or, if this is\n    * NULL, by file->type.  This may be wrong if libpng reads ahead, but this\n    * only happens with IDAT where libpng reads the header then jumps around\n    * finding errors in the previous chunks.  We know that is happening because\n    * we are at the start of the IDAT (i.e. no IDAT data has yet been written.)\n    *\n    * SUMMARY FORMAT (stop):\n    *\n    * IDAT ERR status code read-errno write-errno message file\n    *\n    * 'uncompressed' will be 0 if there was a problem in the IHDR.  The errno\n    * values are emit_string(strerror(errno)).\n    */\n   if (file->global->quiet < 2) /* need two quiets to stop this. */\n   {\n      png_uint_32 type;\n\n      if (file->chunk != NULL)\n         type = current_type(file, code); /* Gropes in struct chunk and IDAT */\n\n      else\n         type = file->type;\n\n      if (type)\n         type_name(type, stdout);\n\n      else /* magic: an IDAT header, produces bogons for too many IDATs */\n         fputs(\"HEAD\", stdout); /* not a registered chunk! */\n\n      printf(\" ERR %.2x %s \", file->status_code, strcode(code));\n      /* This only works one strerror at a time, because of the way strerror is\n       * implemented.\n       */\n      emit_string(strerror(file->read_errno), stdout);\n      putc(' ', stdout);\n      emit_string(strerror(file->write_errno), stdout);\n      putc(' ', stdout);\n      emit_string(what, stdout);\n      putc(' ', stdout);\n      fputs(file->file_name, stdout);\n      putc('\\n', stdout);\n   }\n\n   file->status_code |= FILE_ERROR;\n   longjmp(file->jmpbuf, code);\n}\n\nPNG_NORETURN static void\nstop_invalid(struct file *file, const char *what)\n{\n   stop(file, INVALID_ERROR_CODE, what);\n}\n\nstatic void\ntype_message(struct file *file, png_uint_32 type, const char *what)\n   /* Error message for a chunk; the chunk name comes from 'type' */\n{\n   if (file->global->errors)\n   {\n      fputs(file->file_name, stderr);\n      type_sep(stderr);\n      type_name(type, stderr);\n      type_sep(stderr);\n      fputs(what, stderr);\n      putc('\\n', stderr);\n   }\n}\n\n/* Input file positioning - we jump around in the input file while reading\n * stuff, these wrappers deal with the error handling.\n */\nstatic void\nfile_getpos(struct file *file, fpos_t *pos)\n{\n   if (fgetpos(file->file, pos))\n   {\n      /* This is unexpected, so perror it */\n      perror(file->file_name);\n      stop(file, READ_ERROR_CODE, \"fgetpos\");\n   }\n}\n\nstatic void\nfile_setpos(struct file *file, const fpos_t *pos)\n{\n   if (fsetpos(file->file, pos))\n   {\n      perror(file->file_name);\n      stop(file, READ_ERROR_CODE, \"fsetpos\");\n   }\n}\n\nstatic void\ngetpos(struct file *file)\n   /* Get the current position and store it in 'data_pos'.  The corresponding\n    * setpos() function is chunk specific because it uses the copy of the\n    * position for the specific chunk.\n    */\n{\n   file_getpos(file, &file->data_pos);\n}\n\n\n/* Read utility - read a single byte, returns a value in the range 0..255 or EOF\n * on a read error.  In the latter case status_code and read_errno are updated\n * appropriately.\n */\nstatic int\nread_byte(struct file *file)\n{\n   int ch = getc(file->file);\n\n   if (ch >= 0 && ch <= 255)\n   {\n      ++(file->read_count);\n      return ch;\n   }\n\n   else if (ch != EOF)\n   {\n      file->status_code |= INTERNAL_ERROR;\n      file->read_errno = ERANGE; /* out of range character */\n\n      /* This is very unexpected; an error message is always output: */\n      emit_error(file, UNEXPECTED_ERROR_CODE, \"file read\");\n   }\n\n#  ifdef EINTR\n      else if (errno == EINTR) /* Interrupted, try again */\n      {\n         errno = 0;\n         return read_byte(file);\n      }\n#  endif\n\n   else\n   {\n      /* An error, it doesn't really matter what the error is but it gets\n       * recorded anyway.\n       */\n      if (ferror(file->file))\n         file->read_errno = errno;\n\n      else if (feof(file->file))\n         file->read_errno = 0; /* I.e. a regular EOF, no error */\n\n      else /* unexpected */\n         file->read_errno = EDOM;\n   }\n\n   /* 'TRUNCATED' is used for all cases of failure to read a byte, because of\n    * the way libpng works a byte read is never attempted unless the byte is\n    * expected to be there, so EOF should not occur.\n    */\n   file->status_code |= TRUNCATED;\n   return EOF;\n}\n\nstatic png_byte\nreread_byte(struct file *file)\n   /* Read a byte when an error is not expected to happen because the byte has\n    * been read before without error.\n    */\n{\n   int ch = getc(file->file);\n\n   if (errno != 0)\n      file->read_errno = errno;\n\n   if (ch < 0 || ch > 255)\n      stop(file, UNEXPECTED_ERROR_CODE, \"reread\");\n\n   return (png_byte)ch;\n}\n\nstatic png_uint_32\nreread_4(struct file *file)\n   /* The same but for a four byte quantity */\n{\n   png_uint_32 result = 0;\n   int i = 0;\n\n   while (++i <= 4)\n      result = (result << 8) + reread_byte(file);\n\n   return result;\n}\n\nstatic void\nskip_12(struct file *file)\n   /* Skip exactly 12 bytes in the input stream - used to skip a CRC and chunk\n    * header that has been read before.\n    */\n{\n   /* Since the chunks were read before this shouldn't fail: */\n   if (fseek(file->file, 12, SEEK_CUR) != 0)\n   {\n      if (errno != 0)\n         file->read_errno = errno;\n\n      stop(file, UNEXPECTED_ERROR_CODE, \"reskip\");\n   }\n}\n\nstatic void\nwrite_byte(struct file *file, int b)\n   /* Write one byte to the output - this causes a fatal error if the write\n    * fails and the read of this PNG file immediately terminates.  Just\n    * increments the write count if there is no output file.\n    */\n{\n   if (file->out != NULL)\n   {\n      if (putc(b, file->out) != b)\n      {\n         file->write_errno = errno;\n         file->status_code |= WRITE_ERROR;\n         stop(file, WRITE_ERROR_CODE, \"write byte\");\n      }\n   }\n\n   ++(file->write_count);\n}\n\n/* Derivatives of the read/write functions. */\nstatic unsigned int\nread_4(struct file *file, png_uint_32 *pu)\n   /* Read four bytes, returns the number of bytes read successfully and, if all\n    * four bytes are read, assigns the result to *pu.\n    */\n{\n   unsigned int i = 0;\n   png_uint_32 val = 0;\n\n   do\n   {\n      int ch = read_byte(file);\n\n      if (ch == EOF)\n         return i;\n\n      val = (val << 8) + ch;\n   } while (++i < 4);\n\n   *pu = val;\n   return i;\n}\n\n/* CRC handling - read but calculate the CRC while doing so. */\nstatic int\ncrc_read_many(struct file *file, png_uint_32 length)\n   /* Reads 'length' bytes and updates the CRC, returns true on success, false\n    * if the input is truncated.\n    */\n{\n   if (length > 0)\n   {\n      png_uint_32 crc = file->crc;\n\n      do\n      {\n         int ch = read_byte(file);\n\n         if (ch == EOF)\n            return 0; /* Truncated */\n\n         crc = crc_one_byte(crc, ch);\n      }\n      while (--length > 0);\n\n      file->crc = crc;\n   }\n\n   return 1; /* OK */\n}\n\nstatic int\ncalc_image_size(struct file *file)\n   /* Fill in the image_bytes field given the IHDR information, calls stop on\n    * error.\n    */\n{\n   png_uint_16 pd = file->bit_depth;\n\n   switch (file->color_type)\n   {\n      default:\n         stop_invalid(file, \"IHDR: colour type\");\n\n      invalid_bit_depth:\n         stop_invalid(file, \"IHDR: bit depth\");\n\n      case 0: /* g */\n         if (pd != 1 && pd != 2 && pd != 4 && pd != 8 && pd != 16)\n            goto invalid_bit_depth;\n         break;\n\n      case 3:\n         if (pd != 1 && pd != 2 && pd != 4 && pd != 8)\n            goto invalid_bit_depth;\n         break;\n\n      case 2: /* rgb */\n         if (pd != 8 && pd != 16)\n            goto invalid_bit_depth;\n\n         pd = (png_uint_16)(pd * 3);\n         break;\n\n      case 4: /* ga */\n         if (pd != 8 && pd != 16)\n            goto invalid_bit_depth;\n\n         pd = (png_uint_16)(pd * 2);\n         break;\n\n      case 6: /* rgba */\n         if (pd != 8 && pd != 16)\n            goto invalid_bit_depth;\n\n         pd = (png_uint_16)(pd * 4);\n         break;\n   }\n\n   if (file->width < 1 || file->width > 0x7fffffff)\n      stop_invalid(file, \"IHDR: width\");\n\n   else if (file->height < 1 || file->height > 0x7fffffff)\n      stop_invalid(file, \"IHDR: height\");\n\n   else if (file->compression_method != 0)\n      stop_invalid(file, \"IHDR: compression method\");\n\n   else if (file->filter_method != 0)\n      stop_invalid(file, \"IHDR: filter method\");\n\n   else switch (file->interlace_method)\n   {\n      case PNG_INTERLACE_ADAM7:\n         /* Interlacing makes the image larger because of the replication of\n          * both the filter byte and the padding to a byte boundary.\n          */\n         {\n            int pass;\n            int image_digits = 0;\n            udigit row_width[2], row_bytes[3];\n\n            for (pass=0; pass<=6; ++pass)\n            {\n               png_uint_32 pw = PNG_PASS_COLS(file->width, pass);\n\n               if (pw > 0)\n               {\n                  int  digits;\n\n                  /* calculate 1+((pw*pd+7)>>3) in row_bytes */\n                  digits = uarb_mult_digit(row_bytes, uarb_set(row_bytes, 7),\n                     row_width, uarb_set(row_width, pw), pd);\n                  digits = uarb_shift(row_bytes, digits, 3);\n                  digits = uarb_inc(row_bytes, digits, 1);\n\n                  /* Add row_bytes * pass-height to the file image_bytes field\n                   */\n                  image_digits = uarb_mult32(file->image_bytes, image_digits,\n                     row_bytes, digits,\n                     PNG_PASS_ROWS(file->height, pass));\n               }\n            }\n\n            file->image_digits = image_digits;\n         }\n         break;\n\n      case PNG_INTERLACE_NONE:\n         {\n            int  digits;\n            udigit row_width[2], row_bytes[3];\n\n            /* As above, but use image_width in place of the pass width: */\n            digits = uarb_mult_digit(row_bytes, uarb_set(row_bytes, 7),\n               row_width, uarb_set(row_width, file->width), pd);\n            digits = uarb_shift(row_bytes, digits, 3);\n            digits = uarb_inc(row_bytes, digits, 1);\n\n            /* Set row_bytes * image-height to the file image_bytes field */\n            file->image_digits = uarb_mult32(file->image_bytes, 0,\n               row_bytes, digits, file->height);\n         }\n         break;\n\n      default:\n         stop_invalid(file, \"IHDR: interlace method\");\n   }\n\n   assert(file->image_digits >= 1 && file->image_digits <= 5);\n   return 1;\n}\n\n/* PER-CHUNK CONTROL STRUCTURE\n * This structure is instantiated for each chunk, except for the IDAT chunks\n * where one chunk control structure is used for the whole of a single stream of\n * IDAT chunks (see the IDAT control structure below).\n */\nstruct chunk\n{\n   /* ANCESTORS */\n   struct file *         file;\n   struct global *       global;\n\n   /* PUBLIC IDAT INFORMATION: SET BY THE ZLIB CODE */\n   udigit         uncompressed_bytes[5];\n   int            uncompressed_digits;\n   udigit         compressed_bytes[5];\n   int            compressed_digits;\n\n   /* PUBLIC PER-CHUNK INFORMATION: USED BY CHUNK READ CODE */\n   /* This information is filled in by chunk_init from the data in the file\n    * control structure, but chunk_length may be changed later.\n    */\n   fpos_t         chunk_data_pos;    /* Position of first byte of chunk data */\n   png_uint_32    chunk_length;      /* From header (or modified below) */\n   png_uint_32    chunk_type;        /* From header */\n\n   /* PUBLIC PER-CHUNK INFORMATION: FOR THE CHUNK WRITE CODE */\n   png_uint_32    write_crc;         /* Output CRC (may differ from read_crc) */\n   png_uint_32    rewrite_offset;    /* Count of bytes before rewrite. */\n   int            rewrite_length;    /* Number of bytes left to change */\n   png_byte       rewrite_buffer[2]; /* Buffer of new byte values */\n};\n\nstatic void\nchunk_message(struct chunk *chunk, const char *message)\n{\n   type_message(chunk->file, chunk->chunk_type, message);\n}\n\nstatic void\nchunk_end(struct chunk **chunk_var)\n{\n   struct chunk *chunk = *chunk_var;\n\n   *chunk_var = NULL;\n   CLEAR(*chunk);\n}\n\nstatic void\nchunk_init(struct chunk * const chunk, struct file * const file)\n   /* When a chunk is initialized the file length/type/pos are copied into the\n    * corresponding chunk fields and the new chunk is registered in the file\n    * structure.  There can only be one chunk at a time.\n    *\n    * NOTE: this routine must onely be called from the file alloc routine!\n    */\n{\n   assert(file->chunk == NULL);\n\n   CLEAR(*chunk);\n\n   chunk->file = file;\n   chunk->global = file->global;\n\n   chunk->chunk_data_pos = file->data_pos;\n   chunk->chunk_length = file->length;\n   chunk->chunk_type = file->type;\n\n   /* Compresssed/uncompressed size information (from the zlib control structure\n    * that is used to check the compressed data in a chunk.)\n    */\n   chunk->uncompressed_digits = 0;\n   chunk->compressed_digits = 0;\n\n   file->chunk = chunk;\n}\n\nstatic png_uint_32\ncurrent_type(struct file *file, int code)\n   /* Guess the actual chunk type that causes a stop() */\n{\n   /* This may return png_IDAT for errors detected (late) in the header; that\n    * includes any inter-chunk consistency check that libpng performs.  Assume\n    * that if the chunk_type is png_IDAT and the file write count is 8 this is\n    * what is happening.\n    */\n   if (file->chunk != NULL)\n   {\n      png_uint_32 type = file->chunk->chunk_type;\n\n      /* This is probably wrong for the excess IDATs case, because then libpng\n       * whines about too many of them (apparently in some cases erroneously)\n       * when the header is read.\n       */\n      if (code <= LIBPNG_ERROR_CODE && type == png_IDAT &&\n         file->write_count == 8)\n         type = 0; /* magic */\n\n      return type;\n   }\n\n   else\n      return file->type;\n}\n\nstatic void\nsetpos(struct chunk *chunk)\n   /* Reset the position to 'chunk_data_pos' - the start of the data for this\n    * chunk.  As a side effect the read_count in the file is reset to 8, just\n    * after the length/type header.\n    */\n{\n   chunk->file->read_count = 8;\n   file_setpos(chunk->file, &chunk->chunk_data_pos);\n}\n\n/* Specific chunk handling - called for each chunk header, all special chunk\n * processing is initiated in these functions.\n */\n/* The next functions handle special processing for those chunks with LZ data,\n * the data is identified and checked for validity.  If there are problems which\n * cannot be corrected the routines return false, otherwise true (although\n * modification to the zlib header may be required.)\n *\n * The compressed data is in zlib format (RFC1950) and consequently has a\n * minimum length of 7 bytes.\n */\nstatic int zlib_check(struct file *file, png_uint_32 offset);\n\nstatic int\nprocess_zTXt_iCCP(struct file *file)\n   /* zTXt and iCCP have exactly the same form - keyword, null, compression\n    * method then compressed data.\n    */\n{\n   struct chunk *chunk = file->chunk;\n   png_uint_32 length;\n   png_uint_32 index = 0;\n\n   assert(chunk != NULL && file->idat == NULL);\n   length = chunk->chunk_length;\n   setpos(chunk);\n\n   while (length >= 9)\n   {\n      --length;\n      ++index;\n      if (reread_byte(file) == 0) /* keyword null terminator */\n      {\n         --length;\n         ++index;\n         (void)reread_byte(file); /* compression method */\n         return zlib_check(file, index);\n      }\n   }\n\n   chunk_message(chunk, \"too short\");\n   return 0; /* skip */\n}\n\nstatic int\nprocess_iTXt(struct file *file)\n{\n   /* Like zTXt but more fields. */\n   struct chunk *chunk = file->chunk;\n   png_uint_32 length;\n   png_uint_32 index = 0;\n\n   assert(chunk != NULL && file->idat == NULL);\n   length = chunk->chunk_length;\n   setpos(chunk);\n\n   while (length >= 5)\n   {\n      --length;\n      ++index;\n      if (reread_byte(file) == 0) /* keyword null terminator */\n      {\n         --length;\n         ++index;\n         if (reread_byte(file) == 0) /* uncompressed text */\n            return 1; /* nothing to check */\n\n         --length;\n         ++index;\n         (void)reread_byte(file); /* compression method */\n\n         /* Skip the language tag (null terminated). */\n         while (length >= 9)\n         {\n            --length;\n            ++index;\n            if (reread_byte(file) == 0) /* terminator */\n            {\n               /* Skip the translated keyword */\n               while (length >= 8)\n               {\n                  --length;\n                  ++index;\n                  if (reread_byte(file) == 0) /* terminator */\n                     return zlib_check(file, index);\n               }\n            }\n         }\n\n         /* Ran out of bytes in the compressed case. */\n         break;\n      }\n   }\n\n   log_error(file, INVALID_ERROR_CODE, \"iTXt chunk length\");\n\n   return 0; /* skip */\n}\n\n/* IDAT READ/WRITE CONTROL STRUCTURE */\nstruct IDAT\n{\n   /* ANCESTORS */\n   struct file *         file;\n   struct global *       global;\n\n   /* PROTECTED IDAT INFORMATION: SET BY THE IDAT READ CODE */\n   struct IDAT_list *idat_list_head; /* START of the list of IDAT information */\n   struct IDAT_list *idat_list_tail; /* *END* of the list of IDAT information */\n\n   /* PROTECTED IDAT INFORMATION: USED BY THE IDAT WRITE CODE */\n   struct IDAT_list *idat_cur;       /* Current list entry */\n   unsigned int      idat_count;     /* And the *current* index into the list */\n   png_uint_32       idat_index;     /* Index of *next* input byte to write */\n   png_uint_32       idat_length;    /* Cache of current chunk length */\n};\n\n/* NOTE: there is currently no IDAT_reset, so a stream cannot contain more than\n * one IDAT sequence (i.e. MNG is not supported).\n */\n\nstatic void\nIDAT_end(struct IDAT **idat_var)\n{\n   struct IDAT *idat = *idat_var;\n   struct file *file = idat->file;\n\n   *idat_var = NULL;\n\n   CLEAR(*idat);\n\n   assert(file->chunk != NULL);\n   chunk_end(&file->chunk);\n\n   /* Regardless of why the IDAT was killed set the state back to CHUNKS (it may\n    * already be CHUNKS because the state isn't changed until process_IDAT\n    * returns; a stop will cause IDAT_end to be entered in state CHUNKS!)\n    */\n   file->state = STATE_CHUNKS;\n}\n\nstatic void\nIDAT_init(struct IDAT * const idat, struct file * const file)\n   /* When the chunk is png_IDAT instantiate an IDAT control structure in place\n    * of a chunk control structure.  The IDAT will instantiate a chunk control\n    * structure using the file alloc routine.\n    *\n    * NOTE: this routine must only be called from the file alloc routine!\n    */\n{\n   assert(file->chunk == NULL);\n   assert(file->idat == NULL);\n\n   CLEAR(*idat);\n\n   idat->file = file;\n   idat->global = file->global;\n\n   /* Initialize the tail to the pre-allocated buffer and set the count to 0\n    * (empty.)\n    */\n   idat->global->idat_cache.count = 0;\n   idat->idat_list_head = idat->idat_list_tail = &idat->global->idat_cache;\n\n   /* Now the chunk.  The allocator calls the initializer of the new chunk and\n    * stores the result in file->chunk:\n    */\n   file->alloc(file, 0/*chunk*/);\n   assert(file->chunk != NULL);\n\n   /* And store this for cleanup (and to check for double alloc or failure to\n    * free.)\n    */\n   file->idat = idat;\n}\n\nstatic png_uint_32\nrechunk_length(struct IDAT *idat)\n   /* Return the length for the next IDAT chunk, taking into account\n    * rechunking.\n    */\n{\n   png_uint_32 len = idat->global->idat_max;\n\n   if (len == 0) /* use original chunk lengths */\n   {\n      const struct IDAT_list *cur;\n      unsigned int count;\n\n      if (idat->idat_index == 0) /* at the new chunk (first time) */\n         return idat->idat_length; /* use the cache */\n\n      /* Otherwise rechunk_length is called at the end of a chunk for the length\n       * of the next one.\n       */\n      cur = idat->idat_cur;\n      count = idat->idat_count;\n\n      assert(idat->idat_index == idat->idat_length &&\n         idat->idat_length == cur->lengths[count]);\n\n      /* Return length of the *next* chunk */\n      if (++count < cur->count)\n         return cur->lengths[count];\n\n      /* End of this list */\n      assert(cur != idat->idat_list_tail);\n      cur = cur->next;\n      assert(cur != NULL && cur->count > 0);\n      return cur->lengths[0];\n   }\n\n   else /* rechunking */\n   {\n      /* The chunk size is the lesser of file->idat_max and the number\n       * of remaining bytes.\n       */\n      png_uint_32 have = idat->idat_length - idat->idat_index;\n\n      if (len > have)\n      {\n         struct IDAT_list *cur = idat->idat_cur;\n         unsigned int j = idat->idat_count+1; /* the next IDAT in the list */\n\n         do\n         {\n            /* Add up the remaining bytes.  This can't overflow because the\n             * individual lengths are always <= 0x7fffffff, so when we add two\n             * of them overflow is not possible.\n             */\n            assert(cur != NULL);\n\n            for (;;)\n            {\n               /* NOTE: IDAT_list::count here, not IDAT_list::length */\n               for (; j < cur->count; ++j)\n               {\n                  have += cur->lengths[j];\n                  if (len <= have)\n                     return len;\n               }\n\n               /* If this was the end return the count of the available bytes */\n               if (cur == idat->idat_list_tail)\n                  return have;\n\n               cur = cur->next;\n               j = 0;\n            }\n         }\n         while (len > have);\n      }\n\n      return len;\n   }\n}\n\nstatic int\nprocess_IDAT(struct file *file)\n   /* Process the IDAT stream, this is the more complex than the preceding\n    * cases because the compressed data is spread across multiple IDAT chunks\n    * (typically).  Rechunking of the data is not handled here; all this\n    * function does is establish whether the zlib header needs to be modified.\n    *\n    * Initially the function returns false, indicating that the chunk should not\n    * be written.  It does this until the last IDAT chunk is passed in, then it\n    * checks the zlib data and returns true.\n    *\n    * It does not return false on a fatal error; it calls stop instead.\n    *\n    * The caller must have an instantiated (IDAT) control structure and it must\n    * have extent over the whole read of the IDAT stream.  For a PNG this means\n    * the whole PNG read, for MNG it could have lesser extent.\n    */\n{\n   struct IDAT_list *list;\n\n   assert(file->idat != NULL && file->chunk != NULL);\n\n   /* We need to first check the entire sequence of IDAT chunks to ensure the\n    * stream is in sync.  Do this by building a list of all the chunks and\n    * recording the length of each because the length may have been fixed up by\n    * sync_stream below.\n    *\n    * At the end of the list of chunks, where the type of the next chunk is not\n    * png_IDAT, process the whole stream using the list data to check validity\n    * then return control to the start and rewrite everything.\n    */\n   list = file->idat->idat_list_tail;\n\n   if (list->count == list->length)\n   {\n      list = IDAT_list_extend(list);\n\n      if (list == NULL)\n         stop(file, READ_ERROR_CODE, \"out of memory\");\n\n      /* Move to the next block */\n      list->count = 0;\n      file->idat->idat_list_tail = list;\n   }\n\n   /* And fill in the next IDAT information buffer. */\n   list->lengths[(list->count)++] = file->chunk->chunk_length;\n\n   /* The type of the next chunk was recorded in the file control structure by\n    * the caller, if this is png_IDAT return 'skip' to the caller.\n    */\n   if (file->type == png_IDAT)\n      return 0; /* skip this for the moment */\n\n   /* This is the final IDAT chunk, so run the tests to check for the too far\n    * back error and possibly optimize the window bits.  This means going back\n    * to the start of the first chunk data, which is stored in the original\n    * chunk allocation.\n    */\n   setpos(file->chunk);\n\n   if (zlib_check(file, 0))\n   {\n      struct IDAT *idat;\n      int cmp;\n\n      /* The IDAT stream was successfully uncompressed; see whether it\n       * contained the correct number of bytes of image data.\n       */\n      cmp = uarb_cmp(file->image_bytes, file->image_digits,\n         file->chunk->uncompressed_bytes, file->chunk->uncompressed_digits);\n\n      if (cmp < 0)\n         type_message(file, png_IDAT, \"extra uncompressed data\");\n\n      else if (cmp > 0)\n         stop(file, LIBPNG_ERROR_CODE, \"IDAT: uncompressed data too small\");\n\n      /* Return the stream to the start of the first IDAT chunk; the length\n       * is set in the write case below but the input chunk variables must be\n       * set (once) here:\n       */\n      setpos(file->chunk);\n\n      idat = file->idat;\n      idat->idat_cur = idat->idat_list_head;\n      idat->idat_length = idat->idat_cur->lengths[0];\n      idat->idat_count = 0; /* Count of chunks read in current list */\n      idat->idat_index = 0; /* Index into chunk data */\n\n      /* Update the chunk length to the correct value for the IDAT chunk: */\n      file->chunk->chunk_length = rechunk_length(idat);\n\n      /* Change the state to writing IDAT chunks */\n      file->state = STATE_IDAT;\n\n      return 1;\n   }\n\n   else /* Failure to decompress the IDAT stream; give up. */\n      stop(file, ZLIB_ERROR_CODE, \"could not uncompress IDAT\");\n}\n\n/* ZLIB CONTROL STRUCTURE */\nstruct zlib\n{\n   /* ANCESTORS */\n   struct IDAT *  idat;          /* NOTE: May be NULL */\n   struct chunk * chunk;\n   struct file *  file;\n   struct global *global;\n\n   /* GLOBAL ZLIB INFORMATION: SET BY THE CALLER */\n   png_uint_32    rewrite_offset;\n\n   /* GLOBAL ZLIB INFORMATION: SET BY THE ZLIB READ CODE */\n   udigit         compressed_bytes[5];\n   int            compressed_digits;\n   udigit         uncompressed_bytes[5];\n   int            uncompressed_digits;\n   int            file_bits;             /* window bits from the file */\n   int            ok_bits;               /* Set <16 on a successful read */\n   int            cksum;                 /* Set on a checksum error */\n\n   /* PROTECTED ZLIB INFORMATION: USED BY THE ZLIB ROUTINES */\n   z_stream       z;\n   png_uint_32    extra_bytes;   /* Count of extra compressed bytes */\n   int            state;\n   int            rc;            /* Last return code */\n   int            window_bits;   /* 0 if no change */\n   png_byte       header[2];\n};\n\nstatic const char *\nzlib_flevel(struct zlib *zlib)\n{\n   switch (zlib->header[1] >> 6)\n   {\n      case 0:  return \"supfast\";\n      case 1:  return \"stdfast\";\n      case 2:  return \"default\";\n      case 3:  return \"maximum\";\n      default: assert(UNREACHED);\n   }\n\n   return \"COMPILER BUG\";\n}\n\nstatic const char *\nzlib_rc(struct zlib *zlib)\n   /* Return a string for the zlib return code */\n{\n   switch (zlib->rc)\n   {\n      case Z_OK:              return \"Z_OK\";\n      case Z_STREAM_END:      return \"Z_STREAM_END\";\n      case Z_NEED_DICT:       return \"Z_NEED_DICT\";\n      case Z_ERRNO:           return \"Z_ERRNO\";\n      case Z_STREAM_ERROR:    return \"Z_STREAM_ERROR\";\n      case Z_DATA_ERROR:      return \"Z_DATA_ERROR\";\n      case Z_MEM_ERROR:       return \"Z_MEM_ERROR\";\n      case Z_BUF_ERROR:       return \"Z_BUF_ERROR\";\n      case Z_VERSION_ERROR:   return \"Z_VERSION_ERROR\";\n      default:                return \"Z_*INVALID_RC*\";\n   }\n}\n\nstatic void\nzlib_message(struct zlib *zlib, int unexpected)\n   /* Output a message given a zlib rc */\n{\n   if (zlib->global->errors)\n   {\n      const char *reason = zlib->z.msg;\n\n      if (reason == NULL)\n         reason = \"[no message]\";\n\n      fputs(zlib->file->file_name, stderr);\n      type_sep(stderr);\n      type_name(zlib->chunk->chunk_type, stderr);\n      fprintf(stderr, \": %szlib error: %d (%s) (%s)\\n\",\n         unexpected ? \"unexpected \" : \"\", zlib->rc, zlib_rc(zlib), reason);\n   }\n}\n\nstatic void\nzlib_end(struct zlib *zlib)\n{\n   /* Output the summary line now; this ensures a summary line always gets\n    * output regardless of the manner of exit.\n    */\n   if (!zlib->global->quiet)\n   {\n      if (zlib->ok_bits < 16) /* stream was read ok */\n      {\n         const char *reason;\n\n         if (zlib->cksum)\n            reason = \"CHK\"; /* checksum error */\n\n         else if (zlib->ok_bits > zlib->file_bits)\n            reason = \"TFB\"; /* fixing a too-far-back error */\n\n         else if (zlib->ok_bits == zlib->file_bits)\n            reason = \"OK \";\n\n         else\n            reason = \"OPT\"; /* optimizing window bits */\n\n         /* SUMMARY FORMAT (for a successful zlib inflate):\n          *\n          * IDAT reason flevel file-bits ok-bits compressed uncompressed file\n          */\n         type_name(zlib->chunk->chunk_type, stdout);\n         printf(\" %s %s %d %d \", reason, zlib_flevel(zlib), zlib->file_bits,\n            zlib->ok_bits);\n         uarb_print(zlib->compressed_bytes, zlib->compressed_digits, stdout);\n         putc(' ', stdout);\n         uarb_print(zlib->uncompressed_bytes, zlib->uncompressed_digits,\n            stdout);\n         putc(' ', stdout);\n         fputs(zlib->file->file_name, stdout);\n         putc('\\n', stdout);\n      }\n\n      else\n      {\n         /* This is a zlib read error; the chunk will be skipped.  For an IDAT\n          * stream this will also cause a fatal read error (via stop()).\n          *\n          * SUMMARY FORMAT:\n          *\n          * IDAT SKP flevel file-bits z-rc compressed message file\n          *\n          * z-rc is the zlib failure code; message is the error message with\n          * spaces replaced by '-'.  The compressed byte count indicates where\n          * in the zlib stream the error occurred.\n          */\n         type_name(zlib->chunk->chunk_type, stdout);\n         printf(\" SKP %s %d %s \", zlib_flevel(zlib), zlib->file_bits,\n            zlib_rc(zlib));\n         uarb_print(zlib->compressed_bytes, zlib->compressed_digits, stdout);\n         putc(' ', stdout);\n         emit_string(zlib->z.msg ? zlib->z.msg : \"[no_message]\", stdout);\n         putc(' ', stdout);\n         fputs(zlib->file->file_name, stdout);\n         putc('\\n', stdout);\n      }\n   }\n\n   if (zlib->state >= 0)\n   {\n      zlib->rc = inflateEnd(&zlib->z);\n\n      if (zlib->rc != Z_OK)\n         zlib_message(zlib, 1/*unexpected*/);\n   }\n\n   CLEAR(*zlib);\n}\n\nstatic int\nzlib_reset(struct zlib *zlib, int window_bits)\n   /* Reinitializes a zlib with a different window_bits */\n{\n   assert(zlib->state >= 0); /* initialized by zlib_init */\n\n   zlib->z.next_in = Z_NULL;\n   zlib->z.avail_in = 0;\n   zlib->z.next_out = Z_NULL;\n   zlib->z.avail_out = 0;\n\n   zlib->window_bits = window_bits;\n   zlib->compressed_digits = 0;\n   zlib->uncompressed_digits = 0;\n\n   zlib->state = 0; /* initialized, once */\n   zlib->rc = inflateReset2(&zlib->z, 0);\n   if (zlib->rc != Z_OK)\n   {\n      zlib_message(zlib, 1/*unexpected*/);\n      return 0;\n   }\n\n   return 1;\n}\n\nstatic int\nzlib_init(struct zlib *zlib, struct IDAT *idat, struct chunk *chunk,\n   int window_bits, png_uint_32 offset)\n   /* Initialize a zlib_control; the result is true/false */\n{\n   CLEAR(*zlib);\n\n   zlib->idat = idat;\n   zlib->chunk = chunk;\n   zlib->file = chunk->file;\n   zlib->global = chunk->global;\n   zlib->rewrite_offset = offset; /* never changed for this zlib */\n\n   /* *_out does not need to be set: */\n   zlib->z.next_in = Z_NULL;\n   zlib->z.avail_in = 0;\n   zlib->z.zalloc = Z_NULL;\n   zlib->z.zfree = Z_NULL;\n   zlib->z.opaque = Z_NULL;\n\n   zlib->state = -1;\n   zlib->window_bits = window_bits;\n\n   zlib->compressed_digits = 0;\n   zlib->uncompressed_digits = 0;\n\n   /* These values are sticky across reset (in addition to the stuff in the\n    * first block, which is actually constant.)\n    */\n   zlib->file_bits = 24;\n   zlib->ok_bits = 16; /* unset */\n   zlib->cksum = 0; /* set when a checksum error is detected */\n\n   /* '0' means use the header; inflateInit2 should always succeed because it\n    * does nothing apart from allocating the internal zstate.\n    */\n   zlib->rc = inflateInit2(&zlib->z, 0);\n   if (zlib->rc != Z_OK)\n   {\n      zlib_message(zlib, 1/*unexpected*/);\n      return 0;\n   }\n\n   else\n   {\n      zlib->state = 0; /* initialized */\n      return 1;\n   }\n}\n\nstatic int\nmax_window_bits(uarbc size, int ndigits)\n   /* Return the zlib stream window bits required for data of the given size. */\n{\n   png_uint_16 cb;\n\n   if (ndigits > 1)\n      return 15;\n\n   cb = size[0];\n\n   if (cb > 16384) return 15;\n   if (cb >  8192) return 14;\n   if (cb >  4096) return 13;\n   if (cb >  2048) return 12;\n   if (cb >  1024) return 11;\n   if (cb >   512) return 10;\n   if (cb >   256) return  9;\n   return 8;\n}\n\nstatic int\nzlib_advance(struct zlib *zlib, png_uint_32 nbytes)\n   /* Read nbytes compressed bytes; the stream will be initialized if required.\n    * Bytes are always being reread and errors are fatal.  The return code is as\n    * follows:\n    *\n    *    -1: saw the \"too far back\" error\n    *     0: ok, keep going\n    *     1: saw Z_STREAM_END (zlib->extra_bytes indicates too much data)\n    *     2: a zlib error that cannot be corrected (error message already\n    *        output if required.)\n    */\n#  define ZLIB_TOO_FAR_BACK (-1)\n#  define ZLIB_OK           0\n#  define ZLIB_STREAM_END   1\n#  define ZLIB_FATAL        2\n{\n   int state = zlib->state;\n   int endrc = ZLIB_OK;\n   png_uint_32 in_bytes = 0;\n   struct file *file = zlib->file;\n\n   assert(state >= 0);\n\n   while (in_bytes < nbytes && endrc == ZLIB_OK)\n   {\n      png_uint_32 out_bytes;\n      int flush;\n      png_byte bIn = reread_byte(file);\n      png_byte bOut;\n\n      switch (state)\n      {\n         case 0: /* first header byte */\n            {\n               int file_bits = 8+(bIn >> 4);\n               int new_bits = zlib->window_bits;\n\n               zlib->file_bits = file_bits;\n\n               /* Check against the existing value - it may not need to be\n                * changed.  Note that a bogus file_bits is allowed through once,\n                * to see if it works, but the window_bits value is set to 15,\n                * the maximum.\n                */\n               if (new_bits == 0) /* no change */\n                  zlib->window_bits = ((file_bits > 15) ? 15 : file_bits);\n\n               else if (new_bits != file_bits) /* rewrite required */\n                  bIn = (png_byte)((bIn & 0xf) + ((new_bits-8) << 4));\n            }\n\n            zlib->header[0] = bIn;\n            zlib->state = state = 1;\n            break;\n\n         case 1: /* second header byte */\n            {\n               int b2 = bIn & 0xe0; /* top 3 bits */\n\n               /* The checksum calculation, on the first 11 bits: */\n               b2 += 0x1f - ((zlib->header[0] << 8) + b2) % 0x1f;\n\n               /* Update the checksum byte if required: */\n               if (bIn != b2)\n               {\n                  /* If the first byte wasn't changed this indicates an error in\n                   * the checksum calculation; signal this by setting 'cksum'.\n                   */\n                  if (zlib->file_bits == zlib->window_bits)\n                     zlib->cksum = 1;\n\n                  bIn = (png_byte)b2;\n               }\n            }\n\n            zlib->header[1] = bIn;\n            zlib->state = state = 2;\n            break;\n\n         default: /* After the header bytes */\n            break;\n      }\n\n      /* For some streams, perhaps only those compressed with 'superfast\n       * compression' (which results in a lot of copying) Z_BUF_ERROR can happen\n       * immediately after all output has been flushed on the next input byte.\n       * This is handled below when Z_BUF_ERROR is detected by adding an output\n       * byte.\n       */\n      zlib->z.next_in = &bIn;\n      zlib->z.avail_in = 1;\n      zlib->z.next_out = &bOut;\n      zlib->z.avail_out = 0;     /* Initially */\n\n      /* Initially use Z_NO_FLUSH in an attempt to persuade zlib to look at this\n       * byte without confusing what is going on with output.\n       */\n      flush = Z_NO_FLUSH;\n      out_bytes = 0;\n\n      /* NOTE: expression 3 is only evaluted on 'continue', because of the\n       * 'break' at the end of this loop below.\n       */\n      for (;endrc == ZLIB_OK;\n         flush = Z_SYNC_FLUSH,\n         zlib->z.next_out = &bOut,\n         zlib->z.avail_out = 1,\n         ++out_bytes)\n      {\n         zlib->rc = inflate(&zlib->z, flush);\n         out_bytes -= zlib->z.avail_out;\n\n         switch (zlib->rc)\n         {\n            case Z_BUF_ERROR:\n               if (zlib->z.avail_out == 0)\n                  continue; /* Try another output byte. */\n\n               if (zlib->z.avail_in == 0)\n                  break; /* Try another input byte */\n\n               /* Both avail_out and avail_in are 1 yet zlib returned a code\n                * indicating no progress was possible.  This is unexpected.\n                */\n               zlib_message(zlib, 1/*unexpected*/);\n               endrc = ZLIB_FATAL; /* stop processing */\n               break;\n\n            case Z_OK:\n               /* Zlib is supposed to have made progress: */\n               assert(zlib->z.avail_out == 0 || zlib->z.avail_in == 0);\n               continue;\n\n            case Z_STREAM_END:\n               /* This is the successful end. */\n               zlib->state = 3; /* end of stream */\n               endrc = ZLIB_STREAM_END;\n               break;\n\n            case Z_NEED_DICT:\n               zlib_message(zlib, 0/*stream error*/);\n               endrc = ZLIB_FATAL;\n               break;\n\n            case Z_DATA_ERROR:\n               /* The too far back error can be corrected, others cannot: */\n               if (zlib->z.msg != NULL &&\n                  strcmp(zlib->z.msg, \"invalid distance too far back\") == 0)\n               {\n                  endrc = ZLIB_TOO_FAR_BACK;\n                  break;\n               }\n               /* FALL THROUGH */\n\n            default:\n               zlib_message(zlib, 0/*stream error*/);\n               endrc = ZLIB_FATAL;\n               break;\n         } /* switch (inflate rc) */\n\n         /* Control gets here when further output is not possible; endrc may\n          * still be ZLIB_OK if more input is required.\n          */\n         break;\n      } /* for (output bytes) */\n\n      /* Keep a running count of output byte produced: */\n      zlib->uncompressed_digits = uarb_add32(zlib->uncompressed_bytes,\n         zlib->uncompressed_digits, out_bytes);\n\n      /* Keep going, the loop will terminate when endrc is no longer set to\n       * ZLIB_OK or all the input bytes have been consumed; meanwhile keep\n       * adding input bytes.\n       */\n      assert(zlib->z.avail_in == 0 || endrc != ZLIB_OK);\n\n      in_bytes += 1 - zlib->z.avail_in;\n   } /* while (input bytes) */\n\n   assert(in_bytes == nbytes || endrc != ZLIB_OK);\n\n   /* Update the running total of input bytes consumed */\n   zlib->compressed_digits = uarb_add32(zlib->compressed_bytes,\n      zlib->compressed_digits, in_bytes - zlib->z.avail_in);\n\n   /* At the end of the stream update the chunk with the accumulated\n    * information if it is an improvement:\n    */\n   if (endrc == ZLIB_STREAM_END && zlib->window_bits < zlib->ok_bits)\n   {\n      struct chunk *chunk = zlib->chunk;\n\n      chunk->uncompressed_digits = uarb_copy(chunk->uncompressed_bytes,\n         zlib->uncompressed_bytes, zlib->uncompressed_digits);\n      chunk->compressed_digits = uarb_copy(chunk->compressed_bytes,\n         zlib->compressed_bytes, zlib->compressed_digits);\n      chunk->rewrite_buffer[0] = zlib->header[0];\n      chunk->rewrite_buffer[1] = zlib->header[1];\n\n      if (zlib->window_bits != zlib->file_bits || zlib->cksum)\n      {\n         /* A rewrite is required */\n         chunk->rewrite_offset = zlib->rewrite_offset;\n         chunk->rewrite_length = 2;\n      }\n\n      else\n      {\n         chunk->rewrite_offset = 0;\n         chunk->rewrite_length = 0;\n      }\n\n      if (in_bytes < nbytes)\n         chunk_message(chunk, \"extra compressed data\");\n\n      zlib->extra_bytes = nbytes - in_bytes;\n      zlib->ok_bits = zlib->window_bits;\n   }\n\n   return endrc;\n}\n\nstatic int\nzlib_run(struct zlib *zlib)\n   /* Like zlib_advance but also handles a stream of IDAT chunks. */\n{\n   /* The 'extra_bytes' field is set by zlib_advance if there is extra\n    * compressed data in the chunk it handles (if it sees Z_STREAM_END before\n    * all the input data has been used.)  This function uses the value to update\n    * the correct chunk length, so the problem should only ever be detected once\n    * for each chunk.  zlib_advance outputs the error message, though see the\n    * IDAT specific check below.\n    */\n   zlib->extra_bytes = 0;\n\n   if (zlib->idat != NULL)\n   {\n      struct IDAT_list *list = zlib->idat->idat_list_head;\n      struct IDAT_list *last = zlib->idat->idat_list_tail;\n      int        skip = 0;\n\n      /* 'rewrite_offset' is the offset of the LZ data within the chunk, for\n       * IDAT it should be 0:\n       */\n      assert(zlib->rewrite_offset == 0);\n\n      /* Process each IDAT_list in turn; the caller has left the stream\n       * positioned at the start of the first IDAT chunk data.\n       */\n      for (;;)\n      {\n         const unsigned int count = list->count;\n         unsigned int i;\n\n         for (i = 0; i<count; ++i)\n         {\n            int rc;\n\n            if (skip > 0) /* Skip CRC and next IDAT header */\n               skip_12(zlib->file);\n\n            skip = 12; /* for the next time */\n\n            rc = zlib_advance(zlib, list->lengths[i]);\n\n            switch (rc)\n            {\n               case ZLIB_OK: /* keep going */\n                  break;\n\n               case ZLIB_STREAM_END: /* stop */\n                  /* There may be extra chunks; if there are and one of them is\n                   * not zero length output the 'extra data' message.  Only do\n                   * this check if errors are being output.\n                   */\n                  if (zlib->global->errors && zlib->extra_bytes == 0)\n                  {\n                     struct IDAT_list *check = list;\n                     int j = i+1, jcount = count;\n\n                     for (;;)\n                     {\n                        for (; j<jcount; ++j)\n                           if (check->lengths[j] > 0)\n                           {\n                              chunk_message(zlib->chunk,\n                                 \"extra compressed data\");\n                              goto end_check;\n                           }\n\n                        if (check == last)\n                           break;\n\n                        check = check->next;\n                        jcount = check->count;\n                        j = 0;\n                     }\n                  }\n\n               end_check:\n                  /* Terminate the list at the current position, reducing the\n                   * length of the last IDAT too if required.\n                   */\n                  list->lengths[i] -= zlib->extra_bytes;\n                  list->count = i+1;\n                  zlib->idat->idat_list_tail = list;\n                  /* FALL THROUGH */\n\n               default:\n                  return rc;\n            }\n         }\n\n         /* At the end of the compressed data and Z_STREAM_END was not seen. */\n         if (list == last)\n            return ZLIB_OK;\n\n         list = list->next;\n      }\n   }\n\n   else\n   {\n      struct chunk *chunk = zlib->chunk;\n      int rc;\n\n      assert(zlib->rewrite_offset < chunk->chunk_length);\n\n      rc = zlib_advance(zlib, chunk->chunk_length - zlib->rewrite_offset);\n\n      /* The extra bytes in the chunk are handled now by adjusting the chunk\n       * length to exclude them; the zlib data is always stored at the end of\n       * the PNG chunk (although clearly this is not necessary.)  zlib_advance\n       * has already output a warning message.\n       */\n      chunk->chunk_length -= zlib->extra_bytes;\n      return rc;\n   }\n}\n\nstatic int /* global function; not a member function */\nzlib_check(struct file *file, png_uint_32 offset)\n   /* Check the stream of zlib compressed data in either idat (if given) or (if\n    * not) chunk.  In fact it is zlib_run that handles the difference in reading\n    * a single chunk and a list of IDAT chunks.\n    *\n    * In either case the input file must be positioned at the first byte of zlib\n    * compressed data (the first header byte).\n    *\n    * The return value is true on success, including the case where the zlib\n    * header may need to be rewritten, and false on an unrecoverable error.\n    *\n    * In the case of IDAT chunks 'offset' should be 0.\n    */\n{\n   fpos_t start_pos;\n   struct zlib zlib;\n\n   /* Record the start of the LZ data to allow a re-read. */\n   file_getpos(file, &start_pos);\n\n   /* First test the existing (file) window bits: */\n   if (zlib_init(&zlib, file->idat, file->chunk, 0/*window bits*/, offset))\n   {\n      int min_bits, max_bits, rc;\n\n      /* The first run using the existing window bits. */\n      rc = zlib_run(&zlib);\n\n      switch (rc)\n      {\n         case ZLIB_TOO_FAR_BACK:\n            /* too far back error */\n            file->status_code |= TOO_FAR_BACK;\n            min_bits = zlib.window_bits + 1;\n            max_bits = 15;\n            break;\n\n         case ZLIB_STREAM_END:\n            if (!zlib.global->optimize_zlib &&\n               zlib.window_bits == zlib.file_bits && !zlib.cksum)\n            {\n               /* The trivial case where the stream is ok and optimization was\n                * not requested.\n                */\n               zlib_end(&zlib);\n               return 1;\n            }\n\n            max_bits = max_window_bits(zlib.uncompressed_bytes,\n               zlib.uncompressed_digits);\n            if (zlib.ok_bits < max_bits)\n               max_bits = zlib.ok_bits;\n            min_bits = 8;\n\n            /* cksum is set if there is an error in the zlib header checksum\n             * calculation in the original file (and this may be the only reason\n             * a rewrite is required).  We can't rely on the file window bits in\n             * this case, so do the optimization anyway.\n             */\n            if (zlib.cksum)\n               chunk_message(zlib.chunk, \"zlib checkum\");\n            break;\n\n\n         case ZLIB_OK:\n            /* Truncated stream; unrecoverable, gets converted to ZLIB_FATAL */\n            zlib.z.msg = PNGZ_MSG_CAST(\"[truncated]\");\n            zlib_message(&zlib, 0/*expected*/);\n            /* FALL THROUGH */\n\n         default:\n            /* Unrecoverable error; skip the chunk; a zlib_message has already\n             * been output.\n             */\n            zlib_end(&zlib);\n            return 0;\n      }\n\n      /* Optimize window bits or fix a too-far-back error.  min_bits and\n       * max_bits have been set appropriately, ok_bits records the bit value\n       * known to work.\n       */\n      while (min_bits < max_bits || max_bits < zlib.ok_bits/*if 16*/)\n      {\n         int test_bits = (min_bits + max_bits) >> 1;\n\n         if (zlib_reset(&zlib, test_bits))\n         {\n            file_setpos(file, &start_pos);\n            rc = zlib_run(&zlib);\n\n            switch (rc)\n            {\n               case ZLIB_TOO_FAR_BACK:\n                  min_bits = test_bits+1;\n                  if (min_bits > max_bits)\n                  {\n                     /* This happens when the stream really is damaged and it\n                      * contains a distance code that addresses bytes before\n                      * the start of the uncompressed data.\n                      */\n                     assert(test_bits == 15);\n\n                     /* Output the error that wasn't output before: */\n                     if (zlib.z.msg == NULL)\n                        zlib.z.msg = PNGZ_MSG_CAST(\n                           \"invalid distance too far back\");\n                     zlib_message(&zlib, 0/*stream error*/);\n                     zlib_end(&zlib);\n                     return 0;\n                  }\n                  break;\n\n               case ZLIB_STREAM_END: /* success */\n                  max_bits = test_bits;\n                  break;\n\n               default:\n                  /* A fatal error; this happens if a too-far-back error was\n                   * hiding a more serious error, zlib_advance has already\n                   * output a zlib_message.\n                   */\n                  zlib_end(&zlib);\n                  return 0;\n            }\n         }\n\n         else /* inflateReset2 failed */\n         {\n            zlib_end(&zlib);\n            return 0;\n         }\n      }\n\n      /* The loop guarantees this */\n      assert(zlib.ok_bits == max_bits);\n      zlib_end(&zlib);\n      return 1;\n   }\n\n   else /* zlib initialization failed - skip the chunk */\n   {\n      zlib_end(&zlib);\n      return 0;\n   }\n}\n\n/***************************** LIBPNG CALLBACKS *******************************/\n/* The strategy here is to run a regular libpng PNG file read but examine the\n * input data (from the file) before passing it to libpng so as to be aware of\n * the state we expect libpng to be in.  Warning and error callbacks are also\n * intercepted so that they can be quieted and interpreted.  Interpretation\n * depends on a somewhat risky string match for known error messages; let us\n * hope that this can be fixed in the next version of libpng.\n *\n * The control structure is pointed to by the libpng error pointer.  It contains\n * that set of structures which must persist across multiple read callbacks,\n * which is pretty much everything except the 'zlib' control structure.\n *\n * The file structure is instantiated in the caller of the per-file routine, but\n * the per-file routine contains the chunk and IDAT control structures.\n */\n/* The three routines read_chunk, process_chunk and sync_stream can only be\n * called via a call to read_chunk and only exit at a return from process_chunk.\n * These routines could have been written as one confusing large routine,\n * instead this code relies on the compiler to do tail call elimination.  The\n * possible calls are as follows:\n *\n * read_chunk\n *    -> sync_stream\n *       -> process_chunk\n *    -> process_chunk\n *       -> read_chunk\n *       returns\n */\nstatic void read_chunk(struct file *file);\nstatic void\nprocess_chunk(struct file *file, png_uint_32 file_crc, png_uint_32 next_length,\n   png_uint_32 next_type)\n   /* Called when the chunk data has been read, next_length and next_type\n    * will be set for the next chunk (or 0 if this is IEND).\n    *\n    * When this routine returns, chunk_length and chunk_type will be set for the\n    * next chunk to write because if a chunk is skipped this return calls back\n    * to read_chunk.\n    */\n{\n   const png_uint_32 type = file->type;\n\n   if (file->global->verbose > 1)\n   {\n      fputs(\"  \", stderr);\n      type_name(file->type, stderr);\n      fprintf(stderr, \" %lu 0x%.8x 0x%.8x\\n\", (unsigned long)file->length,\n         file->crc ^ 0xffffffff, file_crc);\n   }\n\n   /* The basic structure seems correct but the CRC may not match, in this\n    * case assume that it is simply a bad CRC, either wrongly calculated or\n    * because of damaged stream data.\n    */\n   if ((file->crc ^ 0xffffffff) != file_crc)\n   {\n      /* The behavior is set by the 'skip' setting; if it is anything other\n       * than SKIP_BAD_CRC ignore the bad CRC and return the chunk, with a\n       * corrected CRC and possibly processed, to libpng.  Otherwise skip the\n       * chunk, which will result in a fatal error if the chunk is critical.\n       */\n      file->status_code |= CRC_ERROR;\n\n      /* Ignore the bad CRC  */\n      if (file->global->skip != SKIP_BAD_CRC)\n         type_message(file, type, \"bad CRC\");\n\n      /* This will cause an IEND with a bad CRC to stop */\n      else if (CRITICAL(type))\n         stop(file, READ_ERROR_CODE, \"bad CRC in critical chunk\");\n\n      else\n      {\n         type_message(file, type, \"skipped: bad CRC\");\n\n         /* NOTE: this cannot be reached for IEND because it is critical. */\n         goto skip_chunk;\n      }\n   }\n\n   /* Check for other 'skip' cases and handle these; these only apply to\n    * ancillary chunks (and not tRNS, which should probably have been a critical\n    * chunk.)\n    */\n   if (skip_chunk_type(file->global, type))\n      goto skip_chunk;\n\n   /* The chunk may still be skipped if problems are detected in the LZ data,\n    * however the LZ data check requires a chunk.  Handle this by instantiating\n    * a chunk unless an IDAT is already instantiated (IDAT control structures\n    * instantiate their own chunk.)\n    */\n   if (type != png_IDAT)\n      file->alloc(file, 0/*chunk*/);\n\n   else if (file->idat == NULL)\n      file->alloc(file, 1/*IDAT*/);\n\n   else\n   {\n      /* The chunk length must be updated for process_IDAT */\n      assert(file->chunk != NULL);\n      assert(file->chunk->chunk_type == png_IDAT);\n      file->chunk->chunk_length = file->length;\n   }\n\n   /* Record the 'next' information too, now that the original values for\n    * this chunk have been copied.  Notice that the IDAT chunks only make a\n    * copy of the position of the first chunk, this is fine - process_IDAT does\n    * not need the position of this chunk.\n    */\n   file->length = next_length;\n   file->type = next_type;\n   getpos(file);\n\n   /* Do per-type processing, note that if this code does not return from the\n    * function the chunk will be skipped.  The rewrite is cancelled here so that\n    * it can be set in the per-chunk processing.\n    */\n   file->chunk->rewrite_length = 0;\n   file->chunk->rewrite_offset = 0;\n   switch (type)\n   {\n      default:\n         return;\n\n      case png_IHDR:\n         /* Read this now and update the control structure with the information\n          * it contains.  The header is validated completely to ensure this is a\n          * PNG.\n          */\n         {\n            struct chunk *chunk = file->chunk;\n\n            if (chunk->chunk_length != 13)\n               stop_invalid(file, \"IHDR length\");\n\n            /* Read all the IHDR information and validate it. */\n            setpos(chunk);\n            file->width = reread_4(file);\n            file->height = reread_4(file);\n            file->bit_depth = reread_byte(file);\n            file->color_type = reread_byte(file);\n            file->compression_method = reread_byte(file);\n            file->filter_method = reread_byte(file);\n            file->interlace_method = reread_byte(file);\n\n            /* This validates all the fields, and calls stop_invalid if\n             * there is a problem.\n             */\n            calc_image_size(file);\n         }\n         return;\n\n         /* Ancillary chunks that require further processing: */\n      case png_zTXt: case png_iCCP:\n         if (process_zTXt_iCCP(file))\n            return;\n         chunk_end(&file->chunk);\n         file_setpos(file, &file->data_pos);\n         break;\n\n      case png_iTXt:\n         if (process_iTXt(file))\n            return;\n         chunk_end(&file->chunk);\n         file_setpos(file, &file->data_pos);\n         break;\n\n      case png_IDAT:\n         if (process_IDAT(file))\n            return;\n         /* First pass: */\n         assert(next_type == png_IDAT);\n         break;\n   }\n\n   /* Control reaches this point if the chunk must be skipped.  For chunks other\n    * than IDAT this means that the zlib compressed data is fatally damanged and\n    * the chunk will not be passed to libpng.  For IDAT it means that the end of\n    * the IDAT stream has not yet been reached and we must handle the next\n    * (IDAT) chunk.  If the LZ data in an IDAT stream cannot be read 'stop' must\n    * be used to halt parsing of the PNG.\n    */\n   read_chunk(file);\n   return;\n\n   /* This is the generic code to skip the current chunk; simply jump to the\n    * next one.\n    */\nskip_chunk:\n   file->length = next_length;\n   file->type = next_type;\n   getpos(file);\n   read_chunk(file);\n}\n\nstatic png_uint_32\nget32(png_bytep buffer, int offset)\n   /* Read a 32-bit value from an 8-byte circular buffer (used only below).\n    */\n{\n   return\n      (buffer[ offset    & 7] << 24) +\n      (buffer[(offset+1) & 7] << 16) +\n      (buffer[(offset+2) & 7] <<  8) +\n      (buffer[(offset+3) & 7]      );\n}\n\nstatic void\nsync_stream(struct file *file)\n   /* The stream seems to be messed up, attempt to resync from the current chunk\n    * header.  Executes stop on a fatal error, otherwise calls process_chunk.\n    */\n{\n   png_uint_32 file_crc;\n\n   file->status_code |= STREAM_ERROR;\n\n   if (file->global->verbose)\n   {\n      fputs(\" SYNC \", stderr);\n      type_name(file->type, stderr);\n      putc('\\n', stderr);\n   }\n\n   /* Return to the start of the chunk data */\n   file_setpos(file, &file->data_pos);\n   file->read_count = 8;\n\n   if (read_4(file, &file_crc) == 4) /* else completely truncated */\n   {\n      /* Ignore the recorded chunk length, proceed through the data looking for\n       * a leading sequence of bytes that match the CRC in the following four\n       * bytes.  Each time a match is found check the next 8 bytes for a valid\n       * length, chunk-type pair.\n       */\n      png_uint_32 length;\n      png_uint_32 type = file->type;\n      png_uint_32 crc = crc_init_4(type);\n      png_byte buffer[8];\n      unsigned int nread = 0, nused = 0;\n\n      for (length=0; length <= 0x7fffffff; ++length)\n      {\n         int ch;\n\n         if ((crc ^ 0xffffffff) == file_crc)\n         {\n            /* A match on the CRC; for IEND this is sufficient, but for anything\n             * else expect a following chunk header.\n             */\n            if (type == png_IEND)\n            {\n               file->length = length;\n               process_chunk(file, file_crc, 0, 0);\n               return;\n            }\n\n            else\n            {\n               /* Need 8 bytes */\n               while (nread < 8+nused)\n               {\n                  ch = read_byte(file);\n                  if (ch == EOF)\n                     goto truncated;\n                  buffer[(nread++) & 7] = (png_byte)ch;\n               }\n\n               /* Prevent overflow */\n               nread -= nused & ~7;\n               nused -= nused & ~7; /* or, nused &= 7 ;-) */\n\n               /* Examine the 8 bytes for a valid chunk header. */\n               {\n                  png_uint_32 next_length = get32(buffer, nused);\n\n                  if (next_length < 0x7fffffff)\n                  {\n                     png_uint_32 next_type = get32(buffer, nused+4);\n\n                     if (chunk_type_valid(next_type))\n                     {\n                        file->read_count -= 8;\n                        process_chunk(file, file_crc, next_length, next_type);\n                        return;\n                     }\n                  }\n\n                  /* Not valid, keep going. */\n               }\n            }\n         }\n\n         /* This catches up with the circular buffer which gets filled above\n          * while checking a chunk header.  This code is slightly tricky - if\n          * the chunk_type is IEND the buffer will never be used, if it is not\n          * the code will always read ahead exactly 8 bytes and pass this on to\n          * process_chunk.  So the invariant that IEND leaves the file position\n          * after the IEND CRC and other chunk leave it after the *next* chunk\n          * header is not broken.\n          */\n         if (nread <= nused)\n         {\n            ch = read_byte(file);\n\n            if (ch == EOF)\n               goto truncated;\n         }\n\n         else\n            ch = buffer[(++nused) & 7];\n\n         crc = crc_one_byte(crc, file_crc >> 24);\n         file_crc = (file_crc << 8) + ch;\n      }\n\n      /* Control gets to here if when 0x7fffffff bytes (plus 8) have been read,\n       * ok, treat this as a damaged stream too:\n       */\n   }\n\ntruncated:\n   stop(file, READ_ERROR_CODE, \"damaged PNG stream\");\n}\n\nstatic void\nread_chunk(struct file *file)\n   /* On entry file::data_pos must be set to the position of the first byte\n    * of the chunk data *and* the input file must be at this position.  This\n    * routine (via process_chunk) instantiates a chunk or IDAT control structure\n    * based on file::length and file::type and also resets these fields and\n    * file::data_pos for the chunk after this one.  For an IDAT chunk the whole\n    * stream of IDATs will be read, until something other than an IDAT is\n    * encountered, and the file fields will be set for the chunk after the end\n    * of the stream of IDATs.\n    *\n    * For IEND the file::type field will be set to 0, and nothing beyond the end\n    * of the IEND chunk will have been read.\n    */\n{\n   png_uint_32 length = file->length;\n   png_uint_32 type = file->type;\n\n   /* After IEND file::type is set to 0, if libpng attempts to read\n    * more data at this point this is a bug in libpng.\n    */\n   if (type == 0)\n      stop(file, UNEXPECTED_ERROR_CODE, \"read beyond IEND\");\n\n   if (file->global->verbose > 2)\n   {\n      fputs(\"   \", stderr);\n      type_name(type, stderr);\n      fprintf(stderr, \" %lu\\n\", (unsigned long)length);\n   }\n\n   /* Start the read_crc calculation with the chunk type, then read to the end\n    * of the chunk data (without processing it in any way) to check that it is\n    * all there and calculate the CRC.\n    */\n   file->crc = crc_init_4(type);\n   if (crc_read_many(file, length)) /* else it was truncated */\n   {\n      png_uint_32 file_crc; /* CRC read from file */\n      unsigned int nread = read_4(file, &file_crc);\n\n      if (nread == 4)\n      {\n         if (type != png_IEND) /* do not read beyond IEND */\n         {\n            png_uint_32 next_length;\n\n            nread += read_4(file, &next_length);\n            if (nread == 8 && next_length <= 0x7fffffff)\n            {\n               png_uint_32 next_type;\n\n               nread += read_4(file, &next_type);\n\n               if (nread == 12 && chunk_type_valid(next_type))\n               {\n                  /* Adjust the read count back to the correct value for this\n                   * chunk.\n                   */\n                  file->read_count -= 8;\n                  process_chunk(file, file_crc, next_length, next_type);\n                  return;\n               }\n            }\n         }\n\n         else /* IEND */\n         {\n            process_chunk(file, file_crc, 0, 0);\n            return;\n         }\n      }\n   }\n\n   /* Control gets to here if the the stream seems invalid or damaged in some\n    * way.  Either there was a problem reading all the expected data (this\n    * chunk's data, its CRC and the length and type of the next chunk) or the\n    * next chunk length/type are invalid.  Notice that the cases that end up\n    * here all correspond to cases that would otherwise terminate the read of\n    * the PNG file.\n    */\n   sync_stream(file);\n}\n\n/* This returns a file* from a png_struct in an implementation specific way. */\nstatic struct file *get_control(png_const_structrp png_ptr);\n\nstatic void PNGCBAPI\nerror_handler(png_structp png_ptr, png_const_charp message)\n{\n   stop(get_control(png_ptr),  LIBPNG_ERROR_CODE, message);\n}\n\nstatic void PNGCBAPI\nwarning_handler(png_structp png_ptr, png_const_charp message)\n{\n   struct file *file = get_control(png_ptr);\n\n   if (file->global->warnings)\n      emit_error(file, LIBPNG_WARNING_CODE, message);\n}\n\n/* Read callback - this is where the work gets done to check the stream before\n * passing it to libpng\n */\nstatic void PNGCBAPI\nread_callback(png_structp png_ptr, png_bytep buffer, size_t count)\n   /* Return 'count' bytes to libpng in 'buffer' */\n{\n   struct file *file = get_control(png_ptr);\n   png_uint_32 type, length; /* For the chunk be *WRITTEN* */\n   struct chunk *chunk;\n\n   /* libpng should always ask for at least one byte */\n   if (count == 0)\n      stop(file, UNEXPECTED_ERROR_CODE, \"read callback for 0 bytes\");\n\n   /* The callback always reads ahead by 8 bytes - the signature or chunk header\n    * - these bytes are stored in chunk_length and chunk_type.  This block is\n    * executed once for the signature and once for the first chunk right at the\n    * start.\n    */\n   if (file->read_count < 8)\n   {\n      assert(file->read_count == 0);\n      assert((file->status_code & TRUNCATED) == 0);\n\n      (void)read_4(file, &file->length);\n\n      if (file->read_count == 4)\n         (void)read_4(file, &file->type);\n\n      if (file->read_count < 8)\n      {\n         assert((file->status_code & TRUNCATED) != 0);\n         stop(file, READ_ERROR_CODE, \"not a PNG (too short)\");\n      }\n\n      if (file->state == STATE_SIGNATURE)\n      {\n         if (file->length != sig1 || file->type != sig2)\n            stop(file, LIBPNG_ERROR_CODE, \"not a PNG (signature)\");\n\n         /* Else write it (this is the initialization of write_count, prior to\n          * this it contains CLEAR garbage.)\n          */\n         file->write_count = 0;\n      }\n\n      else\n      {\n         assert(file->state == STATE_CHUNKS);\n\n         /* The first chunk must be a well formed IHDR (this could be relaxed to\n          * use the checks in process_chunk, but that seems unnecessary.)\n          */\n         if (file->length != 13 || file->type != png_IHDR)\n            stop(file, LIBPNG_ERROR_CODE, \"not a PNG (IHDR)\");\n\n         /* The position of the data must be stored too */\n         getpos(file);\n      }\n   }\n\n   /* Retrieve previous state (because the read callbacks are made pretty much\n    * byte-by-byte in the sequential reader prior to 1.7).\n    */\n   chunk = file->chunk;\n\n   if (chunk != NULL)\n   {\n      length = chunk->chunk_length;\n      type = chunk->chunk_type;\n   }\n\n   else\n   {\n      /* This is the signature case; for IDAT and other chunks these values will\n       * be overwritten when read_chunk is called below.\n       */\n      length = file->length;\n      type = file->type;\n   }\n\n   do\n   {\n      png_uint_32 b;\n\n      /* Complete the read of a chunk; as a side effect this also instantiates\n       * a chunk control structure and sets the file length/type/data_pos fields\n       * for the *NEXT* chunk header.\n       *\n       * NOTE: at an IDAT any following IDAT chunks will also be read and the\n       * next_ fields will refer to the chunk after the last IDAT.\n       *\n       * NOTE: read_chunk only returns when it has read a chunk that must now be\n       * written.\n       */\n      if (file->state != STATE_SIGNATURE && chunk == NULL)\n      {\n         assert(file->read_count == 8);\n         assert(file->idat == NULL);\n         read_chunk(file);\n         chunk = file->chunk;\n         assert(chunk != NULL);\n\n         /* Do the initialization that was not done before. */\n         length = chunk->chunk_length;\n         type = chunk->chunk_type;\n\n         /* And start writing the new chunk. */\n         file->write_count = 0;\n      }\n\n      /* The chunk_ fields describe a chunk that must be written, or hold the\n       * signature.  Write the header first.  In the signature case this\n       * rewrites the signature.\n       */\n      switch (file->write_count)\n      {\n         case 0: b = length >> 24; break;\n         case 1: b = length >> 16; break;\n         case 2: b = length >>  8; break;\n         case 3: b = length      ; break;\n\n         case 4: b = type >> 24; break;\n         case 5: b = type >> 16; break;\n         case 6: b = type >>  8; break;\n         case 7: b = type      ; break;\n\n         case 8:\n            /* The header has been written.  If this is really the signature\n             * that's all that is required and we can go to normal chunk\n             * processing.\n             */\n            if (file->state == STATE_SIGNATURE)\n            {\n               /* The signature has been written, the tail call to read_callback\n                * below (it's just a goto to the start with a decent compiler)\n                * will read the IHDR header ahead and validate it.\n                */\n               assert(length == sig1 && type == sig2);\n               file->read_count = 0; /* Forces a header read */\n               file->state = STATE_CHUNKS; /* IHDR: checked above */\n               read_callback(png_ptr, buffer, count);\n               return;\n            }\n\n            else\n            {\n               assert(chunk != NULL);\n\n               /* Set up for write, notice that repositioning the input stream\n                * is only necessary if something is to be read from it.  Also\n                * notice that for the IDAT stream this must only happen once -\n                * on the first IDAT - to get back to the start of the list and\n                * this is done inside process_IDAT:\n                */\n               chunk->write_crc = crc_init_4(type);\n               if (file->state != STATE_IDAT && length > 0)\n                  setpos(chunk);\n            }\n            /* FALL THROUGH */\n\n         default:\n            assert(chunk != NULL);\n\n            /* NOTE: the arithmetic below overflows and gives a large positive\n             * png_uint_32 value until the whole chunk data has been written.\n             */\n            switch (file->write_count - length)\n            {\n               /* Write the chunk data, normally this just comes from\n                * the file.  The only exception is for that part of a\n                * chunk which is zlib data and which must be rewritten,\n                * and IDAT chunks which can be completely\n                * reconstructed.\n                */\n               default:\n                  if (file->state == STATE_IDAT)\n                  {\n                     struct IDAT *idat = file->idat;\n\n                     assert(idat != NULL);\n\n                     /* Read an IDAT byte from the input stream of IDAT chunks.\n                      * Because the IDAT stream can be re-chunked this stream is\n                      * held in the struct IDAT members.  The chunk members, in\n                      * particular chunk_length (and therefore the length local)\n                      * refer to the output chunk.\n                      */\n                     while (idat->idat_index >= idat->idat_length)\n                     {\n                        /* Advance one chunk */\n                        struct IDAT_list *cur = idat->idat_cur;\n\n                        assert(idat->idat_index == idat->idat_length);\n                        assert(cur != NULL && cur->count > 0);\n\n                        /* NOTE: IDAT_list::count here, not IDAT_list::length */\n                        if (++(idat->idat_count) >= cur->count)\n                        {\n                           assert(idat->idat_count == cur->count);\n\n                           /* Move on to the next IDAT_list: */\n                           cur = cur->next;\n\n                           /* This is an internal error - read beyond the end of\n                            * the pre-calculated stream.\n                            */\n                           if (cur == NULL || cur->count == 0)\n                              stop(file, UNEXPECTED_ERROR_CODE,\n                                 \"read beyond end of IDAT\");\n\n                           idat->idat_count = 0;\n                           idat->idat_cur = cur;\n                        }\n\n                        idat->idat_index = 0;\n                        /* Zero length IDAT chunks are permitted, so the length\n                         * here may be 0.\n                         */\n                        idat->idat_length = cur->lengths[idat->idat_count];\n\n                        /* And skip 12 bytes to the next chunk data */\n                        skip_12(file);\n                     }\n\n                     /* The index is always that of the next byte, the rest of\n                      * the information is always the current IDAT chunk and the\n                      * current list.\n                      */\n                     ++(idat->idat_index);\n                  }\n\n                  /* Read the byte from the stream. */\n                  b = reread_byte(file);\n\n                  /* If the byte must be rewritten handle that here */\n                  if (chunk->rewrite_length > 0)\n                  {\n                     if (chunk->rewrite_offset > 0)\n                        --(chunk->rewrite_offset);\n\n                     else\n                     {\n                        b = chunk->rewrite_buffer[0];\n                        memmove(chunk->rewrite_buffer, chunk->rewrite_buffer+1,\n                           (sizeof chunk->rewrite_buffer)-\n                              (sizeof chunk->rewrite_buffer[0]));\n\n                        --(chunk->rewrite_length);\n                     }\n                  }\n\n                  chunk->write_crc = crc_one_byte(chunk->write_crc, b);\n                  break;\n\n               /* The CRC is written at:\n                *\n                *    chunk_write == chunk_length+8..chunk_length+11\n                *\n                * so 8 to 11.  The CRC is not (yet) conditioned.\n                */\n               case  8: b = chunk->write_crc >> 24; goto write_crc;\n               case  9: b = chunk->write_crc >> 16; goto write_crc;\n               case 10: b = chunk->write_crc >>  8; goto write_crc;\n               case 11:\n                  /* This must happen before the chunk_end below: */\n                  b = chunk->write_crc;\n\n                  if (file->global->verbose > 2)\n                  {\n                     fputs(\"   \", stderr);\n                     type_name(type, stderr);\n                     fprintf(stderr, \" %lu 0x%.8x\\n\", (unsigned long)length,\n                        chunk->write_crc ^ 0xffffffff);\n                  }\n\n                  /* The IDAT stream is written without a call to read_chunk\n                   * until the end is reached.  rechunk_length() calculates the\n                   * length of the output chunks.  Control gets to this point at\n                   * the end of an *output* chunk - the length calculated by\n                   * rechunk_length.  If this corresponds to the end of the\n                   * input stream stop writing IDAT chunks, otherwise continue.\n                   */\n                  if (file->state == STATE_IDAT &&\n                     (file->idat->idat_index < file->idat->idat_length ||\n                      1+file->idat->idat_count < file->idat->idat_cur->count ||\n                      file->idat->idat_cur != file->idat->idat_list_tail))\n                  {\n                     /* Write another IDAT chunk.  Call rechunk_length to\n                      * calculate the length required.\n                      */\n                     length = chunk->chunk_length = rechunk_length(file->idat);\n                     assert(type == png_IDAT);\n                     file->write_count = 0; /* for the new chunk */\n                     --(file->write_count); /* fake out the increment below */\n                  }\n\n                  else\n                  {\n                     /* Entered at the end of a non-IDAT chunk and at the end of\n                      * the IDAT stream.  The rewrite should have been cleared.\n                      */\n                     if (chunk->rewrite_length > 0 || chunk->rewrite_offset > 0)\n                        stop(file, UNEXPECTED_ERROR_CODE, \"pending rewrite\");\n\n                     /* This is the last byte so reset chunk_read for the next\n                      * chunk and move the input file to the position after the\n                      * *next* chunk header if required.\n                      */\n                     file->read_count = 8;\n                     file_setpos(file, &file->data_pos);\n\n                     if (file->idat == NULL)\n                        chunk_end(&file->chunk);\n\n                     else\n                        IDAT_end(&file->idat);\n                  }\n\n               write_crc:\n                  b ^= 0xff; /* conditioning */\n                  break;\n            }\n            break;\n      }\n\n      /* Write one byte */\n      b &= 0xff;\n      *buffer++ = (png_byte)b;\n      --count;\n      write_byte(file, (png_byte)b); /* increments chunk_write */\n   }\n   while (count > 0);\n}\n\n/* Bundle the file and an uninitialized chunk and IDAT control structure\n * together to allow implementation of the chunk/IDAT allocate routine.\n */\nstruct control\n{\n   struct file  file;\n   struct chunk chunk;\n   struct IDAT  idat;\n};\n\nstatic int\ncontrol_end(struct control *control)\n{\n   return file_end(&control->file);\n}\n\nstatic struct file *\nget_control(png_const_structrp png_ptr)\n{\n   /* This just returns the (file*).  The chunk and idat control structures\n    * don't always exist.\n    */\n   struct control *control = voidcast(struct control*,\n      png_get_error_ptr(png_ptr));\n   return &control->file;\n}\n\nstatic void\nallocate(struct file *file, int allocate_idat)\n{\n   struct control *control = voidcast(struct control*, file->alloc_ptr);\n\n   if (allocate_idat)\n   {\n      assert(file->idat == NULL);\n      IDAT_init(&control->idat, file);\n   }\n\n   else /* chunk */\n   {\n      assert(file->chunk == NULL);\n      chunk_init(&control->chunk, file);\n   }\n}\n\nstatic int\ncontrol_init(struct control *control, struct global *global,\n   const char *file_name, const char *out_name)\n   /* This wraps file_init(&control::file) and simply returns the result from\n    * file_init.\n    */\n{\n   return file_init(&control->file, global, file_name, out_name, control,\n      allocate);\n}\n\nstatic int\nread_png(struct control *control)\n   /* Read a PNG, return 0 on success else an error (status) code; a bit mask as\n    * defined for file::status_code as above.\n    */\n{\n   png_structp png_ptr;\n   png_infop info_ptr = NULL;\n   volatile int rc;\n\n   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, control,\n      error_handler, warning_handler);\n\n   if (png_ptr == NULL)\n   {\n      /* This is not really expected. */\n      log_error(&control->file, LIBPNG_ERROR_CODE, \"OOM allocating png_struct\");\n      control->file.status_code |= INTERNAL_ERROR;\n      return LIBPNG_ERROR_CODE;\n   }\n\n   rc = setjmp(control->file.jmpbuf);\n   if (rc == 0)\n   {\n#     ifdef PNG_SET_USER_LIMITS_SUPPORTED\n         /* Remove any limits on the size of PNG files that can be read,\n          * without this we may reject files based on built-in safety\n          * limits.\n          */\n         png_set_user_limits(png_ptr, 0x7fffffff, 0x7fffffff);\n         png_set_chunk_cache_max(png_ptr, 0);\n         png_set_chunk_malloc_max(png_ptr, 0);\n#     endif\n\n      png_set_read_fn(png_ptr, control, read_callback);\n\n      info_ptr = png_create_info_struct(png_ptr);\n      if (info_ptr == NULL)\n         png_error(png_ptr, \"OOM allocating info structure\");\n\n      if (control->file.global->verbose)\n         fprintf(stderr, \" INFO\\n\");\n\n      png_read_info(png_ptr, info_ptr);\n\n      {\n        png_uint_32 height = png_get_image_height(png_ptr, info_ptr);\n        int passes = png_set_interlace_handling(png_ptr);\n        int pass;\n\n        png_start_read_image(png_ptr);\n\n        for (pass = 0; pass < passes; ++pass)\n        {\n           png_uint_32 y = height;\n\n           /* NOTE: this skips asking libpng to return either version of\n            * the image row, but libpng still reads the rows.\n            */\n           while (y-- > 0)\n              png_read_row(png_ptr, NULL, NULL);\n        }\n      }\n\n      if (control->file.global->verbose)\n         fprintf(stderr, \" END\\n\");\n\n      /* Make sure to read to the end of the file: */\n      png_read_end(png_ptr, info_ptr);\n   }\n\n   png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n   return rc;\n}\n\nstatic int\none_file(struct global *global, const char *file_name, const char *out_name)\n{\n   int rc;\n   struct control control;\n\n   if (global->verbose)\n      fprintf(stderr, \"FILE %s -> %s\\n\", file_name,\n         out_name ? out_name : \"<none>\");\n\n   /* Although control_init can return a failure code the structure is always\n    * initialized, so control_end can be used to accumulate any status codes.\n    */\n   rc = control_init(&control, global, file_name, out_name);\n\n   if (rc == 0)\n      rc = read_png(&control);\n\n   rc |= control_end(&control);\n\n   return rc;\n}\n\nstatic void\nusage(const char *prog)\n{\n   /* ANSI C-90 limits strings to 509 characters, so use a string array: */\n   size_t i;\n   static const char *usage_string[] = {\n\"  Tests, optimizes and optionally fixes the zlib header in PNG files.\",\n\"  Optionally, when fixing, strips ancilliary chunks from the file.\",\n0,\n\"OPTIONS\",\n\"  OPERATION\",\n\"      By default files are just checked for readability with a summary of the\",\n\"      of zlib issues founds for each compressed chunk and the IDAT stream in\",\n\"      the file.\",\n\"    --optimize (-o):\",\n\"      Find the smallest deflate window size for the compressed data.\",\n\"    --strip=[none|crc|unsafe|unused|transform|color|all]:\",\n\"        none (default):   Retain all chunks.\",\n\"        crc:    Remove chunks with a bad CRC.\",\n\"        unsafe: Remove chunks that may be unsafe to retain if the image data\",\n\"                is modified.  This is set automatically if --max is given but\",\n\"                may be cancelled by a later --strip=none.\",\n\"        unused: Remove chunks not used by libpng when decoding an image.\",\n\"                This retains any chunks that might be used by libpng image\",\n\"                transformations.\",\n\"        transform: unused+bKGD.\",\n\"        color:  transform+iCCP and cHRM.\",\n\"        all:    color+gAMA and sRGB.\",\n\"      Only ancillary chunks are ever removed.  In addition the tRNS and sBIT\",\n\"      chunks are never removed as they affect exact interpretation of the\",\n\"      image pixel values.  The following known chunks are treated specially\",\n\"      by the above options:\",\n\"        gAMA, sRGB [all]: These specify the gamma encoding used for the pixel\",\n\"            values.\",\n\"        cHRM, iCCP [color]: These specify how colors are encoded.  iCCP also\",\n\"            specifies the exact encoding of a pixel value; however, in\",\n\"            practice most programs will ignore it.\",\n\"        bKGD [transform]: This is used by libpng transforms.\"\n\"    --max=<number>:\",\n\"      Use IDAT chunks sized <number>.  If no number is given the the IDAT\",\n\"      chunks will be the maximum size permitted; 2^31-1 bytes.  If the option\",\n\"      is omitted the original chunk sizes will not be changed.  When the\",\n\"      option is given --strip=unsafe is set automatically. This may be\",\n\"      cancelled if you know that all unknown unsafe-to-copy chunks really are\",\n\"      safe to copy across an IDAT size change.  This is true of all chunks\",\n\"      that have ever been formally proposed as PNG extensions.\",\n\"  MESSAGES\",\n\"      By default the program only outputs summaries for each file.\",\n\"    --quiet (-q):\",\n\"      Do not output the summaries except for files that cannot be read. With\",\n\"      two --quiets these are not output either.\",\n\"    --errors (-e):\",\n\"      Output errors from libpng and the program (except too-far-back).\",\n\"    --warnings (-w):\",\n\"      Output warnings from libpng.\",\n\"  OUTPUT\",\n\"      By default nothing is written.\",\n\"    --out=<file>:\",\n\"      Write the optimized/corrected version of the next PNG to <file>.  This\",\n\"      overrides the following two options\",\n\"    --suffix=<suffix>:\",\n\"      Set --out=<name><suffix> for all following files unless overridden on\",\n\"      a per-file basis by explicit --out.\",\n\"    --prefix=<prefix>:\",\n\"      Set --out=<prefix><name> for all the following files unless overridden\",\n\"      on a per-file basis by explicit --out.\",\n\"      These two options can be used together to produce a suffix and prefix.\",\n\"  INTERNAL OPTIONS\",\n#if 0 /*NYI*/\n#ifdef PNG_MAXIMUM_INFLATE_WINDOW\n\"    --test:\",\n\"      Test the PNG_MAXIMUM_INFLATE_WINDOW option.  Setting this disables\",\n\"      output as this would produce a broken file.\",\n#endif\n#endif\n0,\n\"EXIT CODES\",\n\"  *** SUBJECT TO CHANGE ***\",\n\"  The program exit code is value in the range 0..127 holding a bit mask of\",\n\"  the following codes.  Notice that the results for each file are combined\",\n\"  together - check one file at a time to get a meaningful error code!\",\n\"    0x01: The zlib too-far-back error existed in at least one chunk.\",\n\"    0x02: At least one chunk had a CRC error.\",\n\"    0x04: A chunk length was incorrect.\",\n\"    0x08: The file was truncated.\",\n\"  Errors less than 16 are potentially recoverable, for a single file if the\",\n\"  exit code is less than 16 the file could be read (with corrections if a\",\n\"  non-zero code is returned).\",\n\"    0x10: The file could not be read, even with corrections.\",\n\"    0x20: The output file could not be written.\",\n\"    0x40: An unexpected, potentially internal, error occurred.\",\n\"  If the command line arguments are incorrect the program exits with exit\",\n\"  255.  Some older operating systems only support 7-bit exit codes, on those\",\n\"  systems it is suggested that this program is first tested by supplying\",\n\"  invalid arguments.\",\n0,\n\"DESCRIPTION\",\n\"  \" PROGRAM_NAME \":\",\n\"  checks each PNG file on the command line for errors.  By default errors are\",\n\"  not output and the program just returns an exit code and prints a summary.\",\n\"  With the --quiet (-q) option the summaries are suppressed too and the\",\n\"  program only outputs unexpected errors (internal errors and file open\",\n\"  errors).\",\n\"  Various known problems in PNG files are fixed while the file is being read\",\n\"  The exit code says what problems were fixed.  In particular the zlib error:\",\n0,\n\"        \\\"invalid distance too far back\\\"\",\n0,\n\"  caused by an incorrect optimization of a zlib stream is fixed in any\",\n\"  compressed chunk in which it is encountered.  An integrity problem of the\",\n\"  PNG stream caused by a bug in libpng which wrote an incorrect chunk length\",\n\"  is also fixed.  Chunk CRC errors are automatically fixed up.\",\n0,\n\"  Setting one of the \\\"OUTPUT\\\" options causes the possibly modified file to\",\n\"  be written to a new file.\",\n0,\n\"  Notice that some PNG files with the zlib optimization problem can still be\",\n\"  read by libpng under some circumstances.  This program will still detect\",\n\"  and, if requested, correct the error.\",\n0,\n\"  The program will reliably process all files on the command line unless\",\n\"  either an invalid argument causes the usage message (this message) to be\",\n\"  produced or the program crashes.\",\n0,\n\"  The summary lines describe issues encountered with the zlib compressed\",\n\"  stream of a chunk.  They have the following format, which is SUBJECT TO\",\n\"  CHANGE in the future:\",\n0,\n\"     chunk reason comp-level p1 p2 p3 p4 file\",\n0,\n\"  p1 through p4 vary according to the 'reason'.  There are always 8 space\",\n\"  separated fields.  Reasons specific formats are:\",\n0,\n\"     chunk ERR status code read-errno write-errno message file\",\n\"     chunk SKP comp-level file-bits zlib-rc compressed message file\",\n\"     chunk ??? comp-level file-bits ok-bits compressed uncompress file\",\n0,\n\"  The various fields are\",\n0,\n\"$1 chunk:      The chunk type of a chunk in the file or 'HEAD' if a problem\",\n\"               is reported by libpng at the start of the IDAT stream.\",\n\"$2 reason:     One of:\",\n\"          CHK: A zlib header checksum was detected and fixed.\",\n\"          TFB: The zlib too far back error was detected and fixed.\",\n\"          OK : No errors were detected in the zlib stream and optimization\",\n\"               was not requested, or was not possible.\",\n\"          OPT: The zlib stream window bits value could be improved (and was).\",\n\"          SKP: The chunk was skipped because of a zlib issue (zlib-rc) with\",\n\"               explanation 'message'\",\n\"          ERR: The read of the file was aborted.  The parameters explain why.\",\n\"$3 status:     For 'ERR' the accumulated status code from 'EXIT CODES' above.\",\n\"               This is printed as a 2 digit hexadecimal value\",\n\"   comp-level: The recorded compression level (FLEVEL) of a zlib stream\",\n\"               expressed as a string {supfast,stdfast,default,maximum}\",\n\"$4 code:       The file exit code; where stop was called, as a fairly terse\",\n\"               string {warning,libpng,zlib,invalid,read,write,unexpected}.\",\n\"   file-bits:  The zlib window bits recorded in the file.\",\n\"$5 read-errno: A system errno value from a read translated by strerror(3).\",\n\"   zlib-rc:    A zlib return code as a string (see zlib.h).\",\n\"   ok-bits:    The smallest zlib window bits value that works.\",\n\"$6 write-errno:A system errno value from a write translated by strerror(3).\",\n\"   compressed: The count of compressed bytes in the zlib stream, when the\",\n\"               reason is 'SKP'; this is a count of the bytes read from the\",\n\"               stream when the fatal error was encountered.\",\n\"$7 message:    An error message (spaces replaced by _, as in all parameters),\",\n\"   uncompress: The count of bytes from uncompressing the zlib stream; this\",\n\"               may not be the same as the number of bytes in the image.\",\n\"$8 file:       The name of the file (this may contain spaces).\",\n};\n\n   fprintf(stderr, \"Usage: %s {[options] png-file}\\n\", prog);\n\n   for (i=0; i < (sizeof usage_string)/(sizeof usage_string[0]); ++i)\n   {\n      if (usage_string[i] != 0)\n         fputs(usage_string[i], stderr);\n\n      fputc('\\n', stderr);\n   }\n\n   exit(255);\n}\n\nint\nmain(int argc, const char **argv)\n{\n   char temp_name[FILENAME_MAX+1];\n   const char *  prog = *argv;\n   const char *  outfile = NULL;\n   const char *  suffix = NULL;\n   const char *  prefix = NULL;\n   int           done = 0; /* if at least one file is processed */\n   struct global global;\n\n   global_init(&global);\n\n   while (--argc > 0)\n   {\n      ++argv;\n\n      if (strcmp(*argv, \"--debug\") == 0)\n      {\n         /* To help debugging problems: */\n         global.errors = global.warnings = 1;\n         global.quiet = 0;\n         global.verbose = 7;\n      }\n\n      else if (strncmp(*argv, \"--max=\", 6) == 0)\n      {\n         global.idat_max = (png_uint_32)atol(6+*argv);\n\n         if (global.skip < SKIP_UNSAFE)\n            global.skip = SKIP_UNSAFE;\n      }\n\n      else if (strcmp(*argv, \"--max\") == 0)\n      {\n         global.idat_max = 0x7fffffff;\n\n         if (global.skip < SKIP_UNSAFE)\n            global.skip = SKIP_UNSAFE;\n      }\n\n      else if (strcmp(*argv, \"--optimize\") == 0 || strcmp(*argv, \"-o\") == 0)\n         global.optimize_zlib = 1;\n\n      else if (strncmp(*argv, \"--out=\", 6) == 0)\n         outfile = 6+*argv;\n\n      else if (strncmp(*argv, \"--suffix=\", 9) == 0)\n         suffix = 9+*argv;\n\n      else if (strncmp(*argv, \"--prefix=\", 9) == 0)\n         prefix = 9+*argv;\n\n      else if (strcmp(*argv, \"--strip=none\") == 0)\n         global.skip = SKIP_NONE;\n\n      else if (strcmp(*argv, \"--strip=crc\") == 0)\n         global.skip = SKIP_BAD_CRC;\n\n      else if (strcmp(*argv, \"--strip=unsafe\") == 0)\n         global.skip = SKIP_UNSAFE;\n\n      else if (strcmp(*argv, \"--strip=unused\") == 0)\n         global.skip = SKIP_UNUSED;\n\n      else if (strcmp(*argv, \"--strip=transform\") == 0)\n         global.skip = SKIP_TRANSFORM;\n\n      else if (strcmp(*argv, \"--strip=color\") == 0)\n         global.skip = SKIP_COLOR;\n\n      else if (strcmp(*argv, \"--strip=all\") == 0)\n         global.skip = SKIP_ALL;\n\n      else if (strcmp(*argv, \"--errors\") == 0 || strcmp(*argv, \"-e\") == 0)\n         global.errors = 1;\n\n      else if (strcmp(*argv, \"--warnings\") == 0 || strcmp(*argv, \"-w\") == 0)\n         global.warnings = 1;\n\n      else if (strcmp(*argv, \"--quiet\") == 0 || strcmp(*argv, \"-q\") == 0)\n      {\n         if (global.quiet)\n            global.quiet = 2;\n\n         else\n            global.quiet = 1;\n      }\n\n      else if (strcmp(*argv, \"--verbose\") == 0 || strcmp(*argv, \"-v\") == 0)\n         ++global.verbose;\n\n#if 0\n      /* NYI */\n#     ifdef PNG_MAXIMUM_INFLATE_WINDOW\n         else if (strcmp(*argv, \"--test\") == 0)\n            ++set_option;\n#     endif\n#endif\n\n      else if ((*argv)[0] == '-')\n         usage(prog);\n\n      else\n      {\n         size_t outlen = strlen(*argv);\n\n         if (outfile == NULL) /* else this takes precedence */\n         {\n            /* Consider the prefix/suffix options */\n            if (prefix != NULL)\n            {\n               size_t prefixlen = strlen(prefix);\n\n               if (prefixlen+outlen > FILENAME_MAX)\n               {\n                  fprintf(stderr, \"%s: output file name too long: %s%s%s\\n\",\n                     prog, prefix, *argv, suffix ? suffix : \"\");\n                  global.status_code |= WRITE_ERROR;\n                  continue;\n               }\n\n               memcpy(temp_name, prefix, prefixlen);\n               memcpy(temp_name+prefixlen, *argv, outlen);\n               outlen += prefixlen;\n               outfile = temp_name;\n            }\n\n            else if (suffix != NULL)\n               memcpy(temp_name, *argv, outlen);\n\n            temp_name[outlen] = 0;\n\n            if (suffix != NULL)\n            {\n               size_t suffixlen = strlen(suffix);\n\n               if (outlen+suffixlen > FILENAME_MAX)\n               {\n                  fprintf(stderr, \"%s: output file name too long: %s%s\\n\",\n                     prog, *argv, suffix);\n                  global.status_code |= WRITE_ERROR;\n                  continue;\n               }\n\n               memcpy(temp_name+outlen, suffix, suffixlen);\n               outlen += suffixlen;\n               temp_name[outlen] = 0;\n               outfile = temp_name;\n            }\n         }\n\n         (void)one_file(&global, *argv, outfile);\n         ++done;\n         outfile = NULL;\n      }\n   }\n\n   if (!done)\n      usage(prog);\n\n   return global_end(&global);\n}\n\n#else /* ZLIB_VERNUM < 0x1240 */\nint\nmain(void)\n{\n   fprintf(stderr,\n      \"pngfix needs libpng with a zlib >=1.2.4 (not 0x%x)\\n\",\n      ZLIB_VERNUM);\n   return 77;\n}\n#endif /* ZLIB_VERNUM */\n\n#else /* No read support */\n\nint\nmain(void)\n{\n   fprintf(stderr, \"pngfix does not work without read deinterlace support\\n\");\n   return 77;\n}\n#endif /* PNG_READ_SUPPORTED && PNG_EASY_ACCESS_SUPPORTED */\n#else /* No setjmp support */\nint\nmain(void)\n{\n   fprintf(stderr, \"pngfix does not work without setjmp support\\n\");\n   return 77;\n}\n#endif /* PNG_SETJMP_SUPPORTED */\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/tools/sRGB.h",
    "content": "/*-\n * sRGB.h\n *\n * Last changed in libpng 1.6.0 [February 14, 2013]\n *\n * COPYRIGHT: Written by John Cunningham Bowler, 2013.\n * To the extent possible under law, the author has waived all copyright and\n * related or neighboring rights to this work.  This work is published from:\n * United States.\n *\n * Utility file; not actually a header, this contains definitions of sRGB\n * calculation functions for inclusion in those test programs that need them.\n *\n * All routines take and return a floating point value in the range\n * 0 to 1.0, doing a calculation according to the sRGB specification\n * (in fact the source of the numbers is the wikipedia article at\n * http://en.wikipedia.org/wiki/SRGB).\n */\nstatic double\nsRGB_from_linear(double l)\n{\n   if (l <= 0.0031308)\n      l *= 12.92;\n\n   else\n      l = 1.055 * pow(l, 1/2.4) - 0.055;\n\n   return l;\n}\n\nstatic double\nlinear_from_sRGB(double s)\n{\n   if (s <= 0.04045)\n      return s / 12.92;\n\n   else\n      return pow((s+0.055)/1.055, 2.4);\n}\n\nstatic double\nYfromRGB(double r, double g, double b)\n{\n   /* Use the sRGB (rounded) coefficients for Rlinear, Glinear, Blinear to get\n    * the CIE Y value (also linear).\n    */\n   return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/visupng/PngFile.c",
    "content": "/*-------------------------------------\n *  PNGFILE.C -- Image File Functions\n *-------------------------------------\n *\n * Copyright 2000, Willem van Schaik.\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n#include <windows.h>\n#include <commdlg.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <zlib.h>\n\n#include \"png.h\"\n#include \"pngfile.h\"\n#include \"cexcept.h\"\n\ndefine_exception_type(const char *);\nextern struct exception_context the_exception_context[1];\nstruct exception_context the_exception_context[1];\npng_const_charp msg;\n\nstatic OPENFILENAME ofn;\n\nstatic png_structp png_ptr = NULL;\nstatic png_infop info_ptr = NULL;\n\n\n/* cexcept interface */\n\nstatic void\npng_cexcept_error(png_structp png_ptr, png_const_charp msg)\n{\n   if(png_ptr)\n     ;\n#ifdef PNG_CONSOLE_IO_SUPPORTED\n   fprintf(stderr, \"libpng error: %s\\n\", msg);\n#endif\n   {\n      Throw msg;\n   }\n}\n\n/* Windows open-file functions */\n\nvoid PngFileInitialize (HWND hwnd)\n{\n    static TCHAR szFilter[] = TEXT (\"PNG Files (*.PNG)\\0*.png\\0\")\n        TEXT (\"All Files (*.*)\\0*.*\\0\\0\");\n\n    ofn.lStructSize       = sizeof (OPENFILENAME);\n    ofn.hwndOwner         = hwnd;\n    ofn.hInstance         = NULL;\n    ofn.lpstrFilter       = szFilter;\n    ofn.lpstrCustomFilter = NULL;\n    ofn.nMaxCustFilter    = 0;\n    ofn.nFilterIndex      = 0;\n    ofn.lpstrFile         = NULL;          /* Set in Open and Close functions */\n    ofn.nMaxFile          = MAX_PATH;\n    ofn.lpstrFileTitle    = NULL;          /* Set in Open and Close functions */\n    ofn.nMaxFileTitle     = MAX_PATH;\n    ofn.lpstrInitialDir   = NULL;\n    ofn.lpstrTitle        = NULL;\n    ofn.Flags             = 0;             /* Set in Open and Close functions */\n    ofn.nFileOffset       = 0;\n    ofn.nFileExtension    = 0;\n    ofn.lpstrDefExt       = TEXT (\"png\");\n    ofn.lCustData         = 0;\n    ofn.lpfnHook          = NULL;\n    ofn.lpTemplateName    = NULL;\n}\n\nBOOL PngFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)\n{\n    ofn.hwndOwner         = hwnd;\n    ofn.lpstrFile         = pstrFileName;\n    ofn.lpstrFileTitle    = pstrTitleName;\n    ofn.Flags             = OFN_HIDEREADONLY;\n\n    return GetOpenFileName (&ofn);\n}\n\nBOOL PngFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)\n{\n    ofn.hwndOwner         = hwnd;\n    ofn.lpstrFile         = pstrFileName;\n    ofn.lpstrFileTitle    = pstrTitleName;\n    ofn.Flags             = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;\n\n    return GetSaveFileName (&ofn);\n}\n\n/* PNG image handler functions */\n\nBOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData,\n                   int *piWidth, int *piHeight, int *piChannels, png_color *pBkgColor)\n{\n    static FILE        *pfFile;\n    png_byte            pbSig[8];\n    int                 iBitDepth;\n    int                 iColorType;\n    double              dGamma;\n    png_color_16       *pBackground;\n    png_uint_32         ulChannels;\n    png_uint_32         ulRowBytes;\n    png_byte           *pbImageData = *ppbImageData;\n    static png_byte   **ppbRowPointers = NULL;\n    int                 i;\n\n    /* open the PNG input file */\n\n    if (!pstrFileName)\n    {\n        *ppbImageData = pbImageData = NULL;\n        return FALSE;\n    }\n\n    if (!(pfFile = fopen(pstrFileName, \"rb\")))\n    {\n        *ppbImageData = pbImageData = NULL;\n        return FALSE;\n    }\n\n    /* first check the eight byte PNG signature */\n\n    fread(pbSig, 1, 8, pfFile);\n    if (png_sig_cmp(pbSig, 0, 8))\n    {\n        *ppbImageData = pbImageData = NULL;\n        return FALSE;\n    }\n\n    /* create the two png(-info) structures */\n\n    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,\n      (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL);\n    if (!png_ptr)\n    {\n        *ppbImageData = pbImageData = NULL;\n        return FALSE;\n    }\n\n    info_ptr = png_create_info_struct(png_ptr);\n    if (!info_ptr)\n    {\n        png_destroy_read_struct(&png_ptr, NULL, NULL);\n        *ppbImageData = pbImageData = NULL;\n        return FALSE;\n    }\n\n    Try\n    {\n\n        /* initialize the png structure */\n\n#ifdef PNG_STDIO_SUPPORTED\n        png_init_io(png_ptr, pfFile);\n#else\n        png_set_read_fn(png_ptr, (png_voidp)pfFile, png_read_data);\n#endif\n\n        png_set_sig_bytes(png_ptr, 8);\n\n        /* read all PNG info up to image data */\n\n        png_read_info(png_ptr, info_ptr);\n\n        /* get width, height, bit-depth and color-type */\n\n        png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth,\n            &iColorType, NULL, NULL, NULL);\n\n        /* expand images of all color-type and bit-depth to 3x8-bit RGB */\n        /* let the library process alpha, transparency, background, etc. */\n\n#ifdef PNG_READ_16_TO_8_SUPPORTED\n    if (iBitDepth == 16)\n#  ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\n        png_set_scale_16(png_ptr);\n#  else\n        png_set_strip_16(png_ptr);\n#  endif\n#endif\n        if (iColorType == PNG_COLOR_TYPE_PALETTE)\n            png_set_expand(png_ptr);\n        if (iBitDepth < 8)\n            png_set_expand(png_ptr);\n        if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))\n            png_set_expand(png_ptr);\n        if (iColorType == PNG_COLOR_TYPE_GRAY ||\n            iColorType == PNG_COLOR_TYPE_GRAY_ALPHA)\n            png_set_gray_to_rgb(png_ptr);\n\n        /* set the background color to draw transparent and alpha images over */\n        if (png_get_bKGD(png_ptr, info_ptr, &pBackground))\n        {\n            png_set_background(png_ptr, pBackground, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);\n            pBkgColor->red   = (byte) pBackground->red;\n            pBkgColor->green = (byte) pBackground->green;\n            pBkgColor->blue  = (byte) pBackground->blue;\n        }\n        else\n        {\n            pBkgColor = NULL;\n        }\n\n        /* if required set gamma conversion */\n        if (png_get_gAMA(png_ptr, info_ptr, &dGamma))\n            png_set_gamma(png_ptr, (double) 2.2, dGamma);\n\n        /* after the transformations are registered, update info_ptr data */\n\n        png_read_update_info(png_ptr, info_ptr);\n\n        /* get again width, height and the new bit-depth and color-type */\n\n        png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth,\n            &iColorType, NULL, NULL, NULL);\n\n\n        /* row_bytes is the width x number of channels */\n\n        ulRowBytes = png_get_rowbytes(png_ptr, info_ptr);\n        ulChannels = png_get_channels(png_ptr, info_ptr);\n\n        *piChannels = ulChannels;\n\n        /* now we can allocate memory to store the image */\n\n        if (pbImageData)\n        {\n            free (pbImageData);\n            pbImageData = NULL;\n        }\n        if ((pbImageData = (png_byte *) malloc(ulRowBytes * (*piHeight)\n                            * sizeof(png_byte))) == NULL)\n        {\n            png_error(png_ptr, \"Visual PNG: out of memory\");\n        }\n        *ppbImageData = pbImageData;\n\n        /* and allocate memory for an array of row-pointers */\n\n        if ((ppbRowPointers = (png_bytepp) malloc((*piHeight)\n                            * sizeof(png_bytep))) == NULL)\n        {\n            png_error(png_ptr, \"Visual PNG: out of memory\");\n        }\n\n        /* set the individual row-pointers to point at the correct offsets */\n\n        for (i = 0; i < (*piHeight); i++)\n            ppbRowPointers[i] = pbImageData + i * ulRowBytes;\n\n        /* now we can go ahead and just read the whole image */\n\n        png_read_image(png_ptr, ppbRowPointers);\n\n        /* read the additional chunks in the PNG file (not really needed) */\n\n        png_read_end(png_ptr, NULL);\n\n        /* and we're done */\n\n        free (ppbRowPointers);\n        ppbRowPointers = NULL;\n\n        /* yepp, done */\n    }\n\n    Catch (msg)\n    {\n        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n\n        *ppbImageData = pbImageData = NULL;\n\n        if(ppbRowPointers)\n            free (ppbRowPointers);\n\n        fclose(pfFile);\n\n        return FALSE;\n    }\n\n    fclose (pfFile);\n\n    return TRUE;\n}\n\n\nBOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData,\n                   int iWidth, int iHeight, png_color bkgColor)\n{\n    const int           ciBitDepth = 8;\n    const int           ciChannels = 3;\n\n    static FILE        *pfFile;\n    png_uint_32         ulRowBytes;\n    static png_byte   **ppbRowPointers = NULL;\n    int                 i;\n\n    /* open the PNG output file */\n\n    if (!pstrFileName)\n        return FALSE;\n\n    if (!(pfFile = fopen(pstrFileName, \"wb\")))\n        return FALSE;\n\n    /* prepare the standard PNG structures */\n\n    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,\n      (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL);\n    if (!png_ptr)\n    {\n        fclose(pfFile);\n        return FALSE;\n    }\n\n    info_ptr = png_create_info_struct(png_ptr);\n    if (!info_ptr) {\n        fclose(pfFile);\n        png_destroy_write_struct(&png_ptr, (png_infopp) NULL);\n        return FALSE;\n    }\n\n    Try\n    {\n        /* initialize the png structure */\n\n#ifdef PNG_STDIO_SUPPORTED\n        png_init_io(png_ptr, pfFile);\n#else\n        png_set_write_fn(png_ptr, (png_voidp)pfFile, png_write_data, png_flush);\n#endif\n\n        /* we're going to write a very simple 3x8-bit RGB image */\n\n        png_set_IHDR(png_ptr, info_ptr, iWidth, iHeight, ciBitDepth,\n            PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,\n            PNG_FILTER_TYPE_BASE);\n\n        /* write the file header information */\n\n        png_write_info(png_ptr, info_ptr);\n\n        /* swap the BGR pixels in the DiData structure to RGB */\n\n        png_set_bgr(png_ptr);\n\n        /* row_bytes is the width x number of channels */\n\n        ulRowBytes = iWidth * ciChannels;\n\n        /* we can allocate memory for an array of row-pointers */\n\n        if ((ppbRowPointers = (png_bytepp) malloc(iHeight * sizeof(png_bytep))) == NULL)\n            Throw \"Visualpng: Out of memory\";\n\n        /* set the individual row-pointers to point at the correct offsets */\n\n        for (i = 0; i < iHeight; i++)\n            ppbRowPointers[i] = pDiData + i * (((ulRowBytes + 3) >> 2) << 2);\n\n        /* write out the entire image data in one call */\n\n        png_write_image (png_ptr, ppbRowPointers);\n\n        /* write the additional chunks to the PNG file (not really needed) */\n\n        png_write_end(png_ptr, info_ptr);\n\n        /* and we're done */\n\n        free (ppbRowPointers);\n        ppbRowPointers = NULL;\n\n        /* clean up after the write, and free any memory allocated */\n\n        png_destroy_write_struct(&png_ptr, (png_infopp) NULL);\n\n        /* yepp, done */\n    }\n\n    Catch (msg)\n    {\n        png_destroy_write_struct(&png_ptr, (png_infopp) NULL);\n\n        if(ppbRowPointers)\n            free (ppbRowPointers);\n\n        fclose(pfFile);\n\n        return FALSE;\n    }\n\n    fclose (pfFile);\n\n    return TRUE;\n}\n\n#ifndef PNG_STDIO_SUPPORTED\n\nstatic void\npng_read_data(png_structp png_ptr, png_bytep data, png_size_t length)\n{\n   png_size_t check;\n\n   /* fread() returns 0 on error, so it is OK to store this in a png_size_t\n    * instead of an int, which is what fread() actually returns.\n    */\n   check = (png_size_t)fread(data, (png_size_t)1, length,\n      (FILE *)png_ptr->io_ptr);\n\n   if (check != length)\n   {\n      png_error(png_ptr, \"Read Error\");\n   }\n}\n\nstatic void\npng_write_data(png_structp png_ptr, png_bytep data, png_size_t length)\n{\n   png_uint_32 check;\n\n   check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));\n   if (check != length)\n   {\n      png_error(png_ptr, \"Write Error\");\n   }\n}\n\nstatic void\npng_flush(png_structp png_ptr)\n{\n   FILE *io_ptr;\n   io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));\n   if (io_ptr != NULL)\n      fflush(io_ptr);\n}\n\n#endif\n\n/*-----------------\n *  end of source\n *-----------------\n */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/visupng/PngFile.h",
    "content": "/*------------------------------------------*/\n/*  PNGFILE.H -- Header File for pngfile.c*/\n/*------------------------------------------*/\n\n/* Copyright 2000, Willem van Schaik.*/\n\n/* This code is released under the libpng license.*/\n/* For conditions of distribution and use, see the disclaimer*/\n/* and license in png.h*/\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <windows.h>\n\nvoid PngFileInitialize (HWND hwnd) ;\nBOOL PngFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) ;\nBOOL PngFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) ;\n\nBOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData,\n                   int *piWidth, int *piHeight, int *piChannels, png_color *pBkgColor);\nBOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData,\n                   int iWidth, int iHeight, png_color BkgColor);\n\n#ifndef PNG_STDIO_SUPPORTED\nstatic void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length);\nstatic void png_write_data(png_structp png_ptr, png_bytep data, png_size_t length);\nstatic void png_flush(png_structp png_ptr);\n#endif\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/visupng/README.txt",
    "content": "Microsoft Developer Studio Build File, Format Version 6.00 for VisualPng\n------------------------------------------------------------------------\n\nCopyright 2000, Willem van Schaik.\n\nThis code is released under the libpng license.\nFor conditions of distribution and use, see the disclaimer\nand license in png.h\n\nAs a PNG .dll demo VisualPng is finished. More features would only hinder\nthe program's objective. However, further extensions (like support for other\ngraphics formats) are in development. To get these, or for pre-compiled\nbinaries, go to \"http://www.schaik.com/png/visualpng.html\".\n\n------------------------------------------------------------------------\n\nAssumes that\n\n   libpng DLLs and LIBs are in ..\\..\\projects\\msvc\\win32\\libpng\n   zlib DLLs and LIBs are in   ..\\..\\projects\\msvc\\win32\\zlib\n   libpng header files are in  ..\\..\\..\\libpng\n   zlib header files are in    ..\\..\\..\\zlib\n   the pngsuite images are in  ..\\pngsuite\n\nTo build:\n\n1) On the main menu Select \"Build|Set Active configuration\".\n   Choose the configuration that corresponds to the library you want to test.\n   This library must have been built using the libpng MS project located in\n   the \"..\\..\\mscv\" subdirectory.\n\n2) Select \"Build|Clean\"\n\n3) Select \"Build|Rebuild All\"\n\n4) After compiling and linking VisualPng will be started to view an image\n   from the PngSuite directory.  Press Ctrl-N (and Ctrl-V) for other images.\n\n\nTo install:\n\nWhen distributing VisualPng (or a further development) the following options\nare available:\n\n1) Build the program with the configuration \"Win32 LIB\" and you only need to\n   include the executable from the ./lib directory in your distribution.\n\n2) Build the program with the configuration \"Win32 DLL\" and you need to put\n   in your distribution the executable from the ./dll directory and the dll's\n   libpng1.dll, zlib.dll and msvcrt.dll.  These need to be in the user's PATH.\n\n\nWillem van Schaik\nCalgary, June 6th 2000\n\nP.S. VisualPng was written based on preliminary work of:\n\n    - Simon-Pierre Cadieux\n    - Glenn Randers-Pehrson\n    - Greg Roelofs\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/visupng/VisualPng.c",
    "content": "/*------------------------------------\n *  VisualPng.C -- Shows a PNG image\n *------------------------------------\n *\n * Copyright 2000, Willem van Schaik.\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n/* switches */\n\n/* defines */\n\n#define PROGNAME  \"VisualPng\"\n#define LONGNAME  \"Win32 Viewer for PNG-files\"\n#define VERSION   \"1.0 of 2000 June 07\"\n\n/* constants */\n\n#define MARGIN 8\n\n/* standard includes */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <windows.h>\n#include <zlib.h>\n\n/* application includes */\n\n#include \"png.h\"\n#include \"pngfile.h\"\n#include \"resource.h\"\n\n/* macros */\n\n/* function prototypes */\n\nLRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);\nBOOL    CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ;\n\nBOOL CenterAbout (HWND hwndChild, HWND hwndParent);\n\nBOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount,\n        int *pFileIndex);\n\nBOOL SearchPngList (TCHAR *pFileList, int FileCount, int *pFileIndex,\n        PTSTR pstrPrevName, PTSTR pstrNextName);\n\nBOOL LoadImageFile(HWND hwnd, PTSTR pstrPathName,\n        png_byte **ppbImage, int *pxImgSize, int *pyImgSize, int *piChannels,\n        png_color *pBkgColor);\n\nBOOL DisplayImage (HWND hwnd, BYTE **ppDib,\n        BYTE **ppDiData, int cxWinSize, int cyWinSize,\n        BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,\n        BOOL bStretched);\n\nBOOL InitBitmap (\n        BYTE *pDiData, int cxWinSize, int cyWinSize);\n\nBOOL FillBitmap (\n        BYTE *pDiData, int cxWinSize, int cyWinSize,\n        BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,\n        BOOL bStretched);\n\n/* a few global variables */\n\nstatic char *szProgName = PROGNAME;\nstatic char *szAppName = LONGNAME;\nstatic char *szIconName = PROGNAME;\nstatic char szCmdFileName [MAX_PATH];\n\n/* MAIN routine */\n\nint WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,\n                    PSTR szCmdLine, int iCmdShow)\n{\n    HACCEL   hAccel;\n    HWND     hwnd;\n    MSG      msg;\n    WNDCLASS wndclass;\n    int ixBorders, iyBorders;\n\n    wndclass.style         = CS_HREDRAW | CS_VREDRAW;\n    wndclass.lpfnWndProc   = WndProc;\n    wndclass.cbClsExtra    = 0;\n    wndclass.cbWndExtra    = 0;\n    wndclass.hInstance     = hInstance;\n    wndclass.hIcon         = LoadIcon (hInstance, szIconName) ;\n    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);\n    wndclass.hbrBackground = NULL; /* (HBRUSH) GetStockObject (GRAY_BRUSH); */\n    wndclass.lpszMenuName  = szProgName;\n    wndclass.lpszClassName = szProgName;\n\n    if (!RegisterClass (&wndclass))\n    {\n        MessageBox (NULL, TEXT (\"Error: this program requires Windows NT!\"),\n            szProgName, MB_ICONERROR);\n        return 0;\n    }\n\n    /* if filename given on commandline, store it */\n    if ((szCmdLine != NULL) && (*szCmdLine != '\\0'))\n        if (szCmdLine[0] == '\"')\n            strncpy (szCmdFileName, szCmdLine + 1, strlen(szCmdLine) - 2);\n        else\n            strcpy (szCmdFileName, szCmdLine);\n    else\n        strcpy (szCmdFileName, \"\");\n\n    /* calculate size of window-borders */\n    ixBorders = 2 * (GetSystemMetrics (SM_CXBORDER) +\n                     GetSystemMetrics (SM_CXDLGFRAME));\n    iyBorders = 2 * (GetSystemMetrics (SM_CYBORDER) +\n                     GetSystemMetrics (SM_CYDLGFRAME)) +\n                     GetSystemMetrics (SM_CYCAPTION) +\n                     GetSystemMetrics (SM_CYMENUSIZE) +\n                     1; /* WvS: don't ask me why?  */\n\n    hwnd = CreateWindow (szProgName, szAppName,\n        WS_OVERLAPPEDWINDOW,\n        CW_USEDEFAULT, CW_USEDEFAULT,\n        512 + 2 * MARGIN + ixBorders, 384 + 2 * MARGIN + iyBorders,\n/*      CW_USEDEFAULT, CW_USEDEFAULT, */\n        NULL, NULL, hInstance, NULL);\n\n    ShowWindow (hwnd, iCmdShow);\n    UpdateWindow (hwnd);\n\n    hAccel = LoadAccelerators (hInstance, szProgName);\n\n    while (GetMessage (&msg, NULL, 0, 0))\n    {\n        if (!TranslateAccelerator (hwnd, hAccel, &msg))\n        {\n            TranslateMessage (&msg);\n            DispatchMessage (&msg);\n        }\n    }\n    return msg.wParam;\n}\n\nLRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,\n        LPARAM lParam)\n{\n    static HINSTANCE          hInstance ;\n    static HDC                hdc;\n    static PAINTSTRUCT        ps;\n    static HMENU              hMenu;\n\n    static BITMAPFILEHEADER  *pbmfh;\n    static BITMAPINFOHEADER  *pbmih;\n    static BYTE              *pbImage;\n    static int                cxWinSize, cyWinSize;\n    static int                cxImgSize, cyImgSize;\n    static int                cImgChannels;\n    static png_color          bkgColor = {127, 127, 127};\n\n    static BOOL               bStretched = TRUE;\n\n    static BYTE              *pDib = NULL;\n    static BYTE              *pDiData = NULL;\n\n    static TCHAR              szImgPathName [MAX_PATH];\n    static TCHAR              szTitleName [MAX_PATH];\n\n    static TCHAR             *pPngFileList = NULL;\n    static int                iPngFileCount;\n    static int                iPngFileIndex;\n\n    BOOL                      bOk;\n\n    switch (message)\n    {\n    case WM_CREATE:\n        hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;\n        PngFileInitialize (hwnd);\n\n        strcpy (szImgPathName, \"\");\n\n        /* in case we process file given on command-line */\n\n        if (szCmdFileName[0] != '\\0')\n        {\n            strcpy (szImgPathName, szCmdFileName);\n\n            /* read the other png-files in the directory for later */\n            /* next/previous commands */\n\n            BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount,\n                          &iPngFileIndex);\n\n            /* load the image from file */\n\n            if (!LoadImageFile (hwnd, szImgPathName,\n                &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))\n                return 0;\n\n            /* invalidate the client area for later update */\n\n            InvalidateRect (hwnd, NULL, TRUE);\n\n            /* display the PNG into the DIBitmap */\n\n            DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,\n                pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);\n        }\n\n        return 0;\n\n    case WM_SIZE:\n        cxWinSize = LOWORD (lParam);\n        cyWinSize = HIWORD (lParam);\n\n        /* invalidate the client area for later update */\n\n        InvalidateRect (hwnd, NULL, TRUE);\n\n        /* display the PNG into the DIBitmap */\n\n        DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,\n            pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);\n\n        return 0;\n\n    case WM_INITMENUPOPUP:\n        hMenu = GetMenu (hwnd);\n\n        if (pbImage)\n            EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_ENABLED);\n        else\n            EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_GRAYED);\n\n        return 0;\n\n    case WM_COMMAND:\n        hMenu = GetMenu (hwnd);\n\n        switch (LOWORD (wParam))\n        {\n        case IDM_FILE_OPEN:\n\n            /* show the File Open dialog box */\n\n            if (!PngFileOpenDlg (hwnd, szImgPathName, szTitleName))\n                return 0;\n\n            /* read the other png-files in the directory for later */\n            /* next/previous commands */\n\n            BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount,\n                          &iPngFileIndex);\n\n            /* load the image from file */\n\n            if (!LoadImageFile (hwnd, szImgPathName,\n                &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))\n                return 0;\n\n            /* invalidate the client area for later update */\n\n            InvalidateRect (hwnd, NULL, TRUE);\n\n            /* display the PNG into the DIBitmap */\n\n            DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,\n                pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);\n\n            return 0;\n\n        case IDM_FILE_SAVE:\n\n            /* show the File Save dialog box */\n\n            if (!PngFileSaveDlg (hwnd, szImgPathName, szTitleName))\n                return 0;\n\n            /* save the PNG to a disk file */\n\n            SetCursor (LoadCursor (NULL, IDC_WAIT));\n            ShowCursor (TRUE);\n\n            bOk = PngSaveImage (szImgPathName, pDiData, cxWinSize, cyWinSize,\n                  bkgColor);\n\n            ShowCursor (FALSE);\n            SetCursor (LoadCursor (NULL, IDC_ARROW));\n\n            if (!bOk)\n                MessageBox (hwnd, TEXT (\"Error in saving the PNG image\"),\n                szProgName, MB_ICONEXCLAMATION | MB_OK);\n            return 0;\n\n        case IDM_FILE_NEXT:\n\n            /* read next entry in the directory */\n\n            if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex,\n                NULL, szImgPathName))\n            {\n                if (strcmp (szImgPathName, \"\") == 0)\n                    return 0;\n\n                /* load the image from file */\n\n                if (!LoadImageFile (hwnd, szImgPathName, &pbImage,\n                        &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))\n                    return 0;\n\n                /* invalidate the client area for later update */\n\n                InvalidateRect (hwnd, NULL, TRUE);\n\n                /* display the PNG into the DIBitmap */\n\n                DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,\n                    pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);\n            }\n\n            return 0;\n\n        case IDM_FILE_PREVIOUS:\n\n            /* read previous entry in the directory */\n\n            if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex,\n                szImgPathName, NULL))\n            {\n\n                if (strcmp (szImgPathName, \"\") == 0)\n                    return 0;\n\n                /* load the image from file */\n\n                if (!LoadImageFile (hwnd, szImgPathName, &pbImage, &cxImgSize,\n                    &cyImgSize, &cImgChannels, &bkgColor))\n                    return 0;\n\n                /* invalidate the client area for later update */\n\n                InvalidateRect (hwnd, NULL, TRUE);\n\n                /* display the PNG into the DIBitmap */\n\n                DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,\n                    pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);\n            }\n\n            return 0;\n\n        case IDM_FILE_EXIT:\n\n            /* more cleanup needed... */\n\n            /* free image buffer */\n\n            if (pDib != NULL)\n            {\n                free (pDib);\n                pDib = NULL;\n            }\n\n            /* free file-list */\n\n            if (pPngFileList != NULL)\n            {\n                free (pPngFileList);\n                pPngFileList = NULL;\n            }\n\n            /* let's go ... */\n\n            exit (0);\n\n            return 0;\n\n        case IDM_OPTIONS_STRETCH:\n            bStretched = !bStretched;\n            if (bStretched)\n                CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_CHECKED);\n            else\n                CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_UNCHECKED);\n\n            /* invalidate the client area for later update */\n\n            InvalidateRect (hwnd, NULL, TRUE);\n\n            /* display the PNG into the DIBitmap */\n\n            DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,\n                pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);\n\n            return 0;\n\n        case IDM_HELP_ABOUT:\n            DialogBox (hInstance, TEXT (\"AboutBox\"), hwnd, AboutDlgProc) ;\n            return 0;\n\n        } /* end switch */\n\n        break;\n\n    case WM_PAINT:\n        hdc = BeginPaint (hwnd, &ps);\n\n        if (pDib)\n            SetDIBitsToDevice (hdc, 0, 0, cxWinSize, cyWinSize, 0, 0,\n                0, cyWinSize, pDiData, (BITMAPINFO *) pDib, DIB_RGB_COLORS);\n\n        EndPaint (hwnd, &ps);\n        return 0;\n\n    case WM_DESTROY:\n        if (pbmfh)\n        {\n            free (pbmfh);\n            pbmfh = NULL;\n        }\n\n        PostQuitMessage (0);\n        return 0;\n    }\n\n    return DefWindowProc (hwnd, message, wParam, lParam);\n}\n\nBOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message,\n                            WPARAM wParam, LPARAM lParam)\n{\n     switch (message)\n     {\n     case WM_INITDIALOG :\n          ShowWindow (hDlg, SW_HIDE);\n          CenterAbout (hDlg, GetWindow (hDlg, GW_OWNER));\n          ShowWindow (hDlg, SW_SHOW);\n          return TRUE ;\n\n     case WM_COMMAND :\n          switch (LOWORD (wParam))\n          {\n          case IDOK :\n          case IDCANCEL :\n               EndDialog (hDlg, 0) ;\n               return TRUE ;\n          }\n          break ;\n     }\n     return FALSE ;\n}\n\n/*---------------\n *  CenterAbout\n *---------------\n */\nBOOL CenterAbout (HWND hwndChild, HWND hwndParent)\n{\n   RECT    rChild, rParent, rWorkArea;\n   int     wChild, hChild, wParent, hParent;\n   int     xNew, yNew;\n   BOOL  bResult;\n\n   /* Get the Height and Width of the child window */\n   GetWindowRect (hwndChild, &rChild);\n   wChild = rChild.right - rChild.left;\n   hChild = rChild.bottom - rChild.top;\n\n   /* Get the Height and Width of the parent window */\n   GetWindowRect (hwndParent, &rParent);\n   wParent = rParent.right - rParent.left;\n   hParent = rParent.bottom - rParent.top;\n\n   /* Get the limits of the 'workarea' */\n   bResult = SystemParametersInfo(\n      SPI_GETWORKAREA,  /* system parameter to query or set */\n      sizeof(RECT),\n      &rWorkArea,\n      0);\n   if (!bResult) {\n      rWorkArea.left = rWorkArea.top = 0;\n      rWorkArea.right = GetSystemMetrics(SM_CXSCREEN);\n      rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN);\n   }\n\n   /* Calculate new X position, then adjust for workarea */\n   xNew = rParent.left + ((wParent - wChild) /2);\n   if (xNew < rWorkArea.left) {\n      xNew = rWorkArea.left;\n   } else if ((xNew+wChild) > rWorkArea.right) {\n      xNew = rWorkArea.right - wChild;\n   }\n\n   /* Calculate new Y position, then adjust for workarea */\n   yNew = rParent.top  + ((hParent - hChild) /2);\n   if (yNew < rWorkArea.top) {\n      yNew = rWorkArea.top;\n   } else if ((yNew+hChild) > rWorkArea.bottom) {\n      yNew = rWorkArea.bottom - hChild;\n   }\n\n   /* Set it, and return */\n   return SetWindowPos (hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE |\n          SWP_NOZORDER);\n}\n\n/*----------------\n *  BuildPngList\n *----------------\n */\nBOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount,\n     int *pFileIndex)\n{\n    static TCHAR              szImgPathName [MAX_PATH];\n    static TCHAR              szImgFileName [MAX_PATH];\n    static TCHAR              szImgFindName [MAX_PATH];\n\n    WIN32_FIND_DATA           finddata;\n    HANDLE                    hFind;\n\n    static TCHAR              szTmp [MAX_PATH];\n    BOOL                      bOk;\n    int                       i, ii;\n    int                       j, jj;\n\n    /* free previous file-list */\n\n    if (*ppFileList != NULL)\n    {\n        free (*ppFileList);\n        *ppFileList = NULL;\n    }\n\n    /* extract foldername, filename and search-name */\n\n    strcpy (szImgPathName, pstrPathName);\n    strcpy (szImgFileName, strrchr (pstrPathName, '\\\\') + 1);\n\n    strcpy (szImgFindName, szImgPathName);\n    *(strrchr (szImgFindName, '\\\\') + 1) = '\\0';\n    strcat (szImgFindName, \"*.png\");\n\n    /* first cycle: count number of files in directory for memory allocation */\n\n    *pFileCount = 0;\n\n    hFind = FindFirstFile(szImgFindName, &finddata);\n    bOk = (hFind != (HANDLE) -1);\n\n    while (bOk)\n    {\n        *pFileCount += 1;\n        bOk = FindNextFile(hFind, &finddata);\n    }\n    FindClose(hFind);\n\n    /* allocation memory for file-list */\n\n    *ppFileList = (TCHAR *) malloc (*pFileCount * MAX_PATH);\n\n    /* second cycle: read directory and store filenames in file-list */\n\n    hFind = FindFirstFile(szImgFindName, &finddata);\n    bOk = (hFind != (HANDLE) -1);\n\n    i = 0;\n    ii = 0;\n    while (bOk)\n    {\n        strcpy (*ppFileList + ii, szImgPathName);\n        strcpy (strrchr(*ppFileList + ii, '\\\\') + 1, finddata.cFileName);\n\n        if (strcmp(pstrPathName, *ppFileList + ii) == 0)\n            *pFileIndex = i;\n\n        ii += MAX_PATH;\n        i++;\n\n        bOk = FindNextFile(hFind, &finddata);\n    }\n    FindClose(hFind);\n\n    /* finally we must sort the file-list */\n\n    for (i = 0; i < *pFileCount - 1; i++)\n    {\n        ii = i * MAX_PATH;\n        for (j = i+1; j < *pFileCount; j++)\n        {\n            jj = j * MAX_PATH;\n            if (strcmp (*ppFileList + ii, *ppFileList + jj) > 0)\n            {\n                strcpy (szTmp, *ppFileList + jj);\n                strcpy (*ppFileList + jj, *ppFileList + ii);\n                strcpy (*ppFileList + ii, szTmp);\n\n                /* check if this was the current image that we moved */\n\n                if (*pFileIndex == i)\n                    *pFileIndex = j;\n                else\n                    if (*pFileIndex == j)\n                        *pFileIndex = i;\n            }\n        }\n    }\n\n    return TRUE;\n}\n\n/*----------------\n *  SearchPngList\n *----------------\n */\n\nBOOL SearchPngList (\n        TCHAR *pFileList, int FileCount, int *pFileIndex,\n        PTSTR pstrPrevName, PTSTR pstrNextName)\n{\n    if (FileCount > 0)\n    {\n        /* get previous entry */\n\n        if (pstrPrevName != NULL)\n        {\n            if (*pFileIndex > 0)\n                *pFileIndex -= 1;\n            else\n                *pFileIndex = FileCount - 1;\n\n            strcpy (pstrPrevName, pFileList + (*pFileIndex * MAX_PATH));\n        }\n\n        /* get next entry */\n\n        if (pstrNextName != NULL)\n        {\n            if (*pFileIndex < FileCount - 1)\n                *pFileIndex += 1;\n            else\n                *pFileIndex = 0;\n\n            strcpy (pstrNextName, pFileList + (*pFileIndex * MAX_PATH));\n        }\n\n        return TRUE;\n    }\n    else\n    {\n        return FALSE;\n    }\n}\n\n/*-----------------\n *  LoadImageFile\n *-----------------\n */\n\nBOOL LoadImageFile (HWND hwnd, PTSTR pstrPathName,\n                png_byte **ppbImage, int *pxImgSize, int *pyImgSize,\n                int *piChannels, png_color *pBkgColor)\n{\n    static TCHAR szTmp [MAX_PATH];\n\n    /* if there's an existing PNG, free the memory */\n\n    if (*ppbImage)\n    {\n        free (*ppbImage);\n        *ppbImage = NULL;\n    }\n\n    /* Load the entire PNG into memory */\n\n    SetCursor (LoadCursor (NULL, IDC_WAIT));\n    ShowCursor (TRUE);\n\n    PngLoadImage (pstrPathName, ppbImage, pxImgSize, pyImgSize, piChannels,\n                  pBkgColor);\n\n    ShowCursor (FALSE);\n    SetCursor (LoadCursor (NULL, IDC_ARROW));\n\n    if (*ppbImage != NULL)\n    {\n        sprintf (szTmp, \"VisualPng - %s\", strrchr(pstrPathName, '\\\\') + 1);\n        SetWindowText (hwnd, szTmp);\n    }\n    else\n    {\n        MessageBox (hwnd, TEXT (\"Error in loading the PNG image\"),\n            szProgName, MB_ICONEXCLAMATION | MB_OK);\n        return FALSE;\n    }\n\n    return TRUE;\n}\n\n/*----------------\n *  DisplayImage\n *----------------\n */\nBOOL DisplayImage (HWND hwnd, BYTE **ppDib,\n        BYTE **ppDiData, int cxWinSize, int cyWinSize,\n        BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,\n        BOOL bStretched)\n{\n    BYTE                       *pDib = *ppDib;\n    BYTE                       *pDiData = *ppDiData;\n    /* BITMAPFILEHEADER        *pbmfh; */\n    BITMAPINFOHEADER           *pbmih;\n    WORD                        wDIRowBytes;\n    png_color                   bkgBlack = {0, 0, 0};\n    png_color                   bkgGray  = {127, 127, 127};\n    png_color                   bkgWhite = {255, 255, 255};\n\n    /* allocate memory for the Device Independant bitmap */\n\n    wDIRowBytes = (WORD) ((3 * cxWinSize + 3L) >> 2) << 2;\n\n    if (pDib)\n    {\n        free (pDib);\n        pDib = NULL;\n    }\n\n    if (!(pDib = (BYTE *) malloc (sizeof(BITMAPINFOHEADER) +\n        wDIRowBytes * cyWinSize)))\n    {\n        MessageBox (hwnd, TEXT (\"Error in displaying the PNG image\"),\n            szProgName, MB_ICONEXCLAMATION | MB_OK);\n        *ppDib = pDib = NULL;\n        return FALSE;\n    }\n    *ppDib = pDib;\n    memset (pDib, 0, sizeof(BITMAPINFOHEADER));\n\n    /* initialize the dib-structure */\n\n    pbmih = (BITMAPINFOHEADER *) pDib;\n    pbmih->biSize = sizeof(BITMAPINFOHEADER);\n    pbmih->biWidth = cxWinSize;\n    pbmih->biHeight = -((long) cyWinSize);\n    pbmih->biPlanes = 1;\n    pbmih->biBitCount = 24;\n    pbmih->biCompression = 0;\n    pDiData = pDib + sizeof(BITMAPINFOHEADER);\n    *ppDiData = pDiData;\n\n    /* first fill bitmap with gray and image border */\n\n    InitBitmap (pDiData, cxWinSize, cyWinSize);\n\n    /* then fill bitmap with image */\n\n    if (pbImage)\n    {\n        FillBitmap (\n            pDiData, cxWinSize, cyWinSize,\n            pbImage, cxImgSize, cyImgSize, cImgChannels,\n            bStretched);\n    }\n\n    return TRUE;\n}\n\n/*--------------\n *  InitBitmap\n *--------------\n */\nBOOL InitBitmap (BYTE *pDiData, int cxWinSize, int cyWinSize)\n{\n    BYTE *dst;\n    int x, y, col;\n\n    /* initialize the background with gray */\n\n    dst = pDiData;\n    for (y = 0; y < cyWinSize; y++)\n    {\n        col = 0;\n        for (x = 0; x < cxWinSize; x++)\n        {\n            /* fill with GRAY */\n            *dst++ = 127;\n            *dst++ = 127;\n            *dst++ = 127;\n            col += 3;\n        }\n        /* rows start on 4 byte boundaries */\n        while ((col % 4) != 0)\n        {\n            dst++;\n            col++;\n        }\n    }\n\n    return TRUE;\n}\n\n/*--------------\n *  FillBitmap\n *--------------\n */\nBOOL FillBitmap (\n        BYTE *pDiData, int cxWinSize, int cyWinSize,\n        BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,\n        BOOL bStretched)\n{\n    BYTE *pStretchedImage;\n    BYTE *pImg;\n    BYTE *src, *dst;\n    BYTE r, g, b, a;\n    const int cDIChannels = 3;\n    WORD wImgRowBytes;\n    WORD wDIRowBytes;\n    int cxNewSize, cyNewSize;\n    int cxImgPos, cyImgPos;\n    int xImg, yImg;\n    int xWin, yWin;\n    int xOld, yOld;\n    int xNew, yNew;\n\n    if (bStretched)\n    {\n        cxNewSize = cxWinSize - 2 * MARGIN;\n        cyNewSize = cyWinSize - 2 * MARGIN;\n\n        /* stretch the image to it's window determined size */\n\n        /* the following two are mathematically the same, but the first\n         * has side-effects because of rounding\n         */\n/*      if ((cyNewSize / cxNewSize) > (cyImgSize / cxImgSize)) */\n        if ((cyNewSize * cxImgSize) > (cyImgSize * cxNewSize))\n        {\n            cyNewSize = cxNewSize * cyImgSize / cxImgSize;\n            cxImgPos = MARGIN;\n            cyImgPos = (cyWinSize - cyNewSize) / 2;\n        }\n        else\n        {\n            cxNewSize = cyNewSize * cxImgSize / cyImgSize;\n            cyImgPos = MARGIN;\n            cxImgPos = (cxWinSize - cxNewSize) / 2;\n        }\n\n        pStretchedImage = malloc (cImgChannels * cxNewSize * cyNewSize);\n        pImg = pStretchedImage;\n\n        for (yNew = 0; yNew < cyNewSize; yNew++)\n        {\n            yOld = yNew * cyImgSize / cyNewSize;\n            for (xNew = 0; xNew < cxNewSize; xNew++)\n            {\n                xOld = xNew * cxImgSize / cxNewSize;\n\n                r = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 0);\n                g = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 1);\n                b = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 2);\n                *pImg++ = r;\n                *pImg++ = g;\n                *pImg++ = b;\n                if (cImgChannels == 4)\n                {\n                    a = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld)\n                        + 3);\n                    *pImg++ = a;\n                }\n            }\n        }\n\n        /* calculate row-bytes */\n\n        wImgRowBytes = cImgChannels * cxNewSize;\n        wDIRowBytes = (WORD) ((cDIChannels * cxWinSize + 3L) >> 2) << 2;\n\n        /* copy image to screen */\n\n        for (yImg = 0, yWin = cyImgPos; yImg < cyNewSize; yImg++, yWin++)\n        {\n            if (yWin >= cyWinSize - cyImgPos)\n                break;\n            src = pStretchedImage + yImg * wImgRowBytes;\n            dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels;\n\n            for (xImg = 0, xWin = cxImgPos; xImg < cxNewSize; xImg++, xWin++)\n            {\n                if (xWin >= cxWinSize - cxImgPos)\n                    break;\n                r = *src++;\n                g = *src++;\n                b = *src++;\n                *dst++ = b; /* note the reverse order  */\n                *dst++ = g;\n                *dst++ = r;\n                if (cImgChannels == 4)\n                {\n                    a = *src++;\n                }\n            }\n        }\n\n        /* free memory */\n\n        if (pStretchedImage != NULL)\n        {\n            free (pStretchedImage);\n            pStretchedImage = NULL;\n        }\n\n    }\n\n    /* process the image not-stretched */\n\n    else\n    {\n        /* calculate the central position */\n\n        cxImgPos = (cxWinSize - cxImgSize) / 2;\n        cyImgPos = (cyWinSize - cyImgSize) / 2;\n\n        /* check for image larger than window */\n\n        if (cxImgPos < MARGIN)\n            cxImgPos = MARGIN;\n        if (cyImgPos < MARGIN)\n            cyImgPos = MARGIN;\n\n        /* calculate both row-bytes */\n\n        wImgRowBytes = cImgChannels * cxImgSize;\n        wDIRowBytes = (WORD) ((cDIChannels * cxWinSize + 3L) >> 2) << 2;\n\n        /* copy image to screen */\n\n        for (yImg = 0, yWin = cyImgPos; yImg < cyImgSize; yImg++, yWin++)\n        {\n            if (yWin >= cyWinSize - MARGIN)\n                break;\n            src = pbImage + yImg * wImgRowBytes;\n            dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels;\n\n            for (xImg = 0, xWin = cxImgPos; xImg < cxImgSize; xImg++, xWin++)\n            {\n                if (xWin >= cxWinSize - MARGIN)\n                    break;\n                r = *src++;\n                g = *src++;\n                b = *src++;\n                *dst++ = b; /* note the reverse order  */\n                *dst++ = g;\n                *dst++ = r;\n                if (cImgChannels == 4)\n                {\n                    a = *src++;\n                }\n            }\n        }\n    }\n\n    return TRUE;\n}\n\n/*-----------------\n *  end of source\n *-----------------\n */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/visupng/VisualPng.dsp",
    "content": "# Microsoft Developer Studio Project File - Name=\"VisualPng\" - Package Owner=<4>\n# Microsoft Developer Studio Generated Build File, Format Version 6.00\n# ** DO NOT EDIT **\n\n# TARGTYPE \"Win32 (x86) Application\" 0x0101\n\nCFG=VisualPng - Win32 Debug\n!MESSAGE This is not a valid makefile. To build this project using NMAKE,\n!MESSAGE use the Export Makefile command and run\n!MESSAGE \n!MESSAGE NMAKE /f \"VisualPng.mak\".\n!MESSAGE \n!MESSAGE You can specify a configuration when running NMAKE\n!MESSAGE by defining the macro CFG on the command line. For example:\n!MESSAGE \n!MESSAGE NMAKE /f \"VisualPng.mak\" CFG=\"VisualPng - Win32 Debug\"\n!MESSAGE \n!MESSAGE Possible choices for configuration are:\n!MESSAGE \n!MESSAGE \"VisualPng - Win32 Release\" (based on \"Win32 (x86) Application\")\n!MESSAGE \"VisualPng - Win32 Debug\" (based on \"Win32 (x86) Application\")\n!MESSAGE \n\n# Begin Project\n# PROP AllowPerConfigDependencies 0\n# PROP Scc_ProjName \"\"\n# PROP Scc_LocalPath \"\"\nCPP=cl.exe\nMTL=midl.exe\nRSC=rc.exe\n\n!IF  \"$(CFG)\" == \"VisualPng - Win32 Release\"\n\n# PROP BASE Use_MFC 0\n# PROP BASE Use_Debug_Libraries 0\n# PROP BASE Output_Dir \"Release\"\n# PROP BASE Intermediate_Dir \"Release\"\n# PROP BASE Ignore_Export_Lib 0\n# PROP BASE Target_Dir \"\"\n# PROP Use_MFC 0\n# PROP Use_Debug_Libraries 0\n# PROP Output_Dir \"Release\"\n# PROP Intermediate_Dir \"Release\"\n# PROP Ignore_Export_Lib 0\n# PROP Target_Dir \"\"\n# ADD BASE CPP /nologo /W3 /O2 /I \"..\\..\" /I \"..\\..\\..\\zlib\" /D \"WIN32\" /D \"NDEBUG\" /D \"PNG_NO_STDIO\" /FD /c\n# SUBTRACT BASE CPP /YX\n# ADD CPP /nologo /MD /W3 /O2 /I \"..\\..\" /I \"..\\..\\..\\zlib\" /D \"WIN32\" /D \"NDEBUG\" /D \"PNG_NO_STDIO\" /FD /c\n# SUBTRACT CPP /YX\n# ADD BASE MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\n# ADD MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\n# ADD BASE RSC /l 0x409 /d \"NDEBUG\"\n# ADD RSC /l 0x409 /d \"NDEBUG\"\nBSC32=bscmake.exe\n# ADD BASE BSC32 /nologo\n# ADD BSC32 /nologo\nLINK32=link.exe\n# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386\n# ADD LINK32 ..\\..\\projects\\visualc6\\Win32_LIB_Release\\libpng.lib ..\\..\\..\\zlib\\projects\\visualc6\\Win32_LIB_Release\\zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386\n# Begin Special Build Tool\nOutDir=.\\Release\nSOURCE=\"$(InputPath)\"\nPostBuild_Cmds=$(outdir)\\VisualPng.exe ..\\..\\contrib\\pngsuite\\basn6a16.png\n# End Special Build Tool\n\n!ELSEIF  \"$(CFG)\" == \"VisualPng - Win32 Debug\"\n\n# PROP BASE Use_MFC 0\n# PROP BASE Use_Debug_Libraries 1\n# PROP BASE Output_Dir \"Debug\"\n# PROP BASE Intermediate_Dir \"Debug\"\n# PROP BASE Ignore_Export_Lib 0\n# PROP BASE Target_Dir \"\"\n# PROP Use_MFC 0\n# PROP Use_Debug_Libraries 1\n# PROP Output_Dir \"Debug\"\n# PROP Intermediate_Dir \"Debug\"\n# PROP Ignore_Export_Lib 0\n# PROP Target_Dir \"\"\n# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /I \"..\\..\" /I \"..\\..\\..\\zlib\" /D \"WIN32\" /D \"_DEBUG\" /D \"PNG_NO_STDIO\" /FD /GZ /c\n# SUBTRACT BASE CPP /YX\n# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I \"..\\..\" /I \"..\\..\\..\\zlib\" /D \"WIN32\" /D \"_DEBUG\" /D \"PNG_NO_STDIO\" /FD /GZ /c\n# SUBTRACT CPP /YX\n# ADD BASE MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\n# ADD MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32\n# ADD BASE RSC /l 0x409 /d \"_DEBUG\"\n# ADD RSC /l 0x409 /d \"_DEBUG\"\nBSC32=bscmake.exe\n# ADD BASE BSC32 /nologo\n# ADD BSC32 /nologo\nLINK32=link.exe\n# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept\n# ADD LINK32 ..\\..\\projects\\visualc6\\Win32_LIB_Release\\libpng.lib ..\\..\\..\\zlib\\projects\\visualc6\\Win32_LIB_Release\\zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:\"msvcrt.lib\" /pdbtype:sept\n# Begin Special Build Tool\nOutDir=.\\Debug\nSOURCE=\"$(InputPath)\"\nPostBuild_Cmds=$(outdir)\\VisualPng.exe ..\\..\\contrib\\pngsuite\\basn6a16.png\n# End Special Build Tool\n\n!ENDIF \n\n# Begin Target\n\n# Name \"VisualPng - Win32 Release\"\n# Name \"VisualPng - Win32 Debug\"\n# Begin Group \"Source Files\"\n\n# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat\"\n# Begin Source File\n\nSOURCE=.\\PngFile.c\n# End Source File\n# Begin Source File\n\nSOURCE=.\\VisualPng.c\n# End Source File\n# End Group\n# Begin Group \"Header Files\"\n\n# PROP Default_Filter \"h;hpp;hxx;hm;inl\"\n# Begin Source File\n\nSOURCE=.\\cexcept.h\n# End Source File\n# Begin Source File\n\nSOURCE=.\\PngFile.h\n# End Source File\n# Begin Source File\n\nSOURCE=.\\resource.h\n# End Source File\n# End Group\n# Begin Group \"Resource Files\"\n\n# PROP Default_Filter \"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\"\n# Begin Source File\n\nSOURCE=.\\VisualPng.ico\n# End Source File\n# Begin Source File\n\nSOURCE=.\\VisualPng.rc\n# End Source File\n# End Group\n# End Target\n# End Project\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/visupng/VisualPng.dsw",
    "content": "Microsoft Developer Studio Workspace File, Format Version 6.00\n# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\n\n###############################################################################\n\nProject: \"VisualPng\"=.\\VisualPng.dsp - Package Owner=<4>\n\nPackage=<5>\n{{{\n}}}\n\nPackage=<4>\n{{{\n}}}\n\n###############################################################################\n\nGlobal:\n\nPackage=<5>\n{{{\n}}}\n\nPackage=<3>\n{{{\n}}}\n\n###############################################################################\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/visupng/VisualPng.rc",
    "content": "//Microsoft Developer Studio generated resource script.\n//\n#include \"resource.h\"\n\n#define APSTUDIO_READONLY_SYMBOLS\n/////////////////////////////////////////////////////////////////////////////\n//\n// Generated from the TEXTINCLUDE 2 resource.\n//\n#include \"afxres.h\"\n\n/////////////////////////////////////////////////////////////////////////////\n#undef APSTUDIO_READONLY_SYMBOLS\n\n/////////////////////////////////////////////////////////////////////////////\n// English (U.S.) resources\n\n#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\n#ifdef _WIN32\nLANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\n#pragma code_page(1252)\n#endif //_WIN32\n\n#ifdef APSTUDIO_INVOKED\n/////////////////////////////////////////////////////////////////////////////\n//\n// TEXTINCLUDE\n//\n\n1 TEXTINCLUDE DISCARDABLE \nBEGIN\n    \"resource.h\\0\"\nEND\n\n2 TEXTINCLUDE DISCARDABLE \nBEGIN\n    \"#include \"\"afxres.h\"\"\\r\\n\"\n    \"\\0\"\nEND\n\n3 TEXTINCLUDE DISCARDABLE \nBEGIN\n    \"\\r\\n\"\n    \"\\0\"\nEND\n\n#endif    // APSTUDIO_INVOKED\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// Menu\n//\n\nVISUALPNG MENU DISCARDABLE \nBEGIN\n    POPUP \"&File\"\n    BEGIN\n        MENUITEM \"&Open Image...\\tCtrl+O\",      IDM_FILE_OPEN\n        MENUITEM \"Save &As...\",                 IDM_FILE_SAVE\n        MENUITEM SEPARATOR\n        MENUITEM \"&Next Image\\tCtrl+N\",         IDM_FILE_NEXT\n        MENUITEM \"Pre&vious Image\\tCtrl+V\",     IDM_FILE_PREVIOUS\n        MENUITEM SEPARATOR\n        MENUITEM \"E&xit\\tAlt+X\",                IDM_FILE_EXIT\n    END\n    POPUP \"&Options\"\n    BEGIN\n        MENUITEM \"&Stretch\",                    IDM_OPTIONS_STRETCH, CHECKED\n    END\n    POPUP \"&Help\"\n    BEGIN\n        MENUITEM \"&About\",                      IDM_HELP_ABOUT\n    END\nEND\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// Accelerator\n//\n\nVISUALPNG ACCELERATORS DISCARDABLE \nBEGIN\n    \"N\",            IDM_FILE_NEXT,          VIRTKEY, CONTROL, NOINVERT\n    \"O\",            IDM_FILE_OPEN,          VIRTKEY, CONTROL, NOINVERT\n    \"P\",            IDM_FILE_PREVIOUS,      VIRTKEY, CONTROL, NOINVERT\n    \"V\",            IDM_FILE_PREVIOUS,      VIRTKEY, CONTROL, NOINVERT\n    \"X\",            IDM_FILE_EXIT,          VIRTKEY, ALT, NOINVERT\nEND\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// Icon\n//\n\n// Icon with lowest ID value placed first to ensure application icon\n// remains consistent on all systems.\nVISUALPNG               ICON    DISCARDABLE     \"VisualPng.ico\"\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// Dialog\n//\n\nABOUTBOX DIALOG DISCARDABLE  0, 0, 186, 94\nSTYLE DS_MODALFRAME | WS_POPUP\nFONT 8, \"MS Sans Serif\"\nBEGIN\n    DEFPUSHBUTTON   \"OK\",IDOK,68,67,50,14\n    CTEXT           \"VisualPng 1.0  -  June 2000\",IDC_STATIC,49,14,88,8\n    LTEXT           \"a PNG image viewer\",IDC_STATIC,60,30,66,8\n    LTEXT           \"(c) Willem van Schaik, 2000\",IDC_STATIC,48,52,90,8\n    LTEXT           \"to demonstrate the use of libpng in Visual C\",\n                    IDC_STATIC,25,38,136,8\nEND\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// DESIGNINFO\n//\n\n#ifdef APSTUDIO_INVOKED\nGUIDELINES DESIGNINFO DISCARDABLE \nBEGIN\n    \"ABOUTBOX\", DIALOG\n    BEGIN\n        LEFTMARGIN, 7\n        RIGHTMARGIN, 179\n        TOPMARGIN, 7\n        BOTTOMMARGIN, 87\n    END\nEND\n#endif    // APSTUDIO_INVOKED\n\n#endif    // English (U.S.) resources\n/////////////////////////////////////////////////////////////////////////////\n\n\n\n#ifndef APSTUDIO_INVOKED\n/////////////////////////////////////////////////////////////////////////////\n//\n// Generated from the TEXTINCLUDE 3 resource.\n//\n\n\n/////////////////////////////////////////////////////////////////////////////\n#endif    // not APSTUDIO_INVOKED\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/visupng/cexcept.h",
    "content": "/*===\ncexcept.h 2.0.1 (2008-Jul-19-Sat)\nhttp://www.nicemice.net/cexcept/\nAdam M. Costello\nhttp://www.nicemice.net/amc/\n\nAn interface for exception-handling in ANSI C (C89 and subsequent ISO\nstandards), developed jointly with Cosmin Truta.\n\n    Copyright (c) 2000-2008 Adam M. Costello and Cosmin Truta.\n    This software may be modified only if its author and version\n    information is updated accurately, and may be redistributed\n    only if accompanied by this unaltered notice.  Subject to those\n    restrictions, permission is granted to anyone to do anything\n    with this software.  The copyright holders make no guarantees\n    regarding this software, and are not responsible for any damage\n    resulting from its use.\n\nThe cexcept interface is not compatible with and cannot interact\nwith system exceptions (like division by zero or memory segmentation\nviolation), compiler-generated exceptions (like C++ exceptions), or\nother exception-handling interfaces.\n\nWhen using this interface across multiple .c files, do not include\nthis header file directly.  Instead, create a wrapper header file that\nincludes this header file and then invokes the define_exception_type\nmacro (see below).  The .c files should then include that header file.\n\nThe interface consists of one type, one well-known name, and six macros.\n\n\ndefine_exception_type(type_name);\n\n    This macro is used like an external declaration.  It specifies\n    the type of object that gets copied from the exception thrower to\n    the exception catcher.  The type_name can be any type that can be\n    assigned to, that is, a non-constant arithmetic type, struct, union,\n    or pointer.  Examples:\n\n        define_exception_type(int);\n\n        enum exception { out_of_memory, bad_arguments, disk_full };\n        define_exception_type(enum exception);\n\n        struct exception { int code; const char *msg; };\n        define_exception_type(struct exception);\n\n    Because throwing an exception causes the object to be copied (not\n    just once, but twice), programmers may wish to consider size when\n    choosing the exception type.\n\n\nstruct exception_context;\n\n    This type may be used after the define_exception_type() macro has\n    been invoked.  A struct exception_context must be known to both\n    the thrower and the catcher.  It is expected that there be one\n    context for each thread that uses exceptions.  It would certainly\n    be dangerous for multiple threads to access the same context.\n    One thread can use multiple contexts, but that is likely to be\n    confusing and not typically useful.  The application can allocate\n    this structure in any way it pleases--automatic, static, or dynamic.\n    The application programmer should pretend not to know the structure\n    members, which are subject to change.\n\n\nstruct exception_context *the_exception_context;\n\n    The Try/Catch and Throw statements (described below) implicitly\n    refer to a context, using the name the_exception_context.  It is\n    the application's responsibility to make sure that this name yields\n    the address of a mutable (non-constant) struct exception_context\n    wherever those statements are used.  Subject to that constraint, the\n    application may declare a variable of this name anywhere it likes\n    (inside a function, in a parameter list, or externally), and may\n    use whatever storage class specifiers (static, extern, etc) or type\n    qualifiers (const, volatile, etc) it likes.  Examples:\n\n        static struct exception_context\n          * const the_exception_context = &foo;\n\n        { struct exception_context *the_exception_context = bar; ... }\n\n        int blah(struct exception_context *the_exception_context, ...);\n\n        extern struct exception_context the_exception_context[1];\n\n    The last example illustrates a trick that avoids creating a pointer\n    object separate from the structure object.\n\n    The name could even be a macro, for example:\n\n        struct exception_context ec_array[numthreads];\n        #define the_exception_context (ec_array + thread_id)\n\n    Be aware that the_exception_context is used several times by the\n    Try/Catch/Throw macros, so it shouldn't be expensive or have side\n    effects.  The expansion must be a drop-in replacement for an\n    identifier, so it's safest to put parentheses around it.\n\n\nvoid init_exception_context(struct exception_context *ec);\n\n    For context structures allocated statically (by an external\n    definition or using the \"static\" keyword), the implicit\n    initialization to all zeros is sufficient, but contexts allocated\n    by other means must be initialized using this macro before they\n    are used by a Try/Catch statement.  It does no harm to initialize\n    a context more than once (by using this macro on a statically\n    allocated context, or using this macro twice on the same context),\n    but a context must not be re-initialized after it has been used by a\n    Try/Catch statement.\n\n\nTry statement\nCatch (expression) statement\n\n    The Try/Catch/Throw macros are capitalized in order to avoid\n    confusion with the C++ keywords, which have subtly different\n    semantics.\n\n    A Try/Catch statement has a syntax similar to an if/else statement,\n    except that the parenthesized expression goes after the second\n    keyword rather than the first.  As with if/else, there are two\n    clauses, each of which may be a simple statement ending with a\n    semicolon or a brace-enclosed compound statement.  But whereas\n    the else clause is optional, the Catch clause is required.  The\n    expression must be a modifiable lvalue (something capable of being\n    assigned to) of the same type (disregarding type qualifiers) that\n    was passed to define_exception_type().\n\n    If a Throw that uses the same exception context as the Try/Catch is\n    executed within the Try clause (typically within a function called\n    by the Try clause), and the exception is not caught by a nested\n    Try/Catch statement, then a copy of the exception will be assigned\n    to the expression, and control will jump to the Catch clause.  If no\n    such Throw is executed, then the assignment is not performed, and\n    the Catch clause is not executed.\n\n    The expression is not evaluated unless and until the exception is\n    caught, which is significant if it has side effects, for example:\n\n        Try foo();\n        Catch (p[++i].e) { ... }\n\n    IMPORTANT: Jumping into or out of a Try clause (for example via\n    return, break, continue, goto, longjmp) is forbidden--the compiler\n    will not complain, but bad things will happen at run-time.  Jumping\n    into or out of a Catch clause is okay, and so is jumping around\n    inside a Try clause.  In many cases where one is tempted to return\n    from a Try clause, it will suffice to use Throw, and then return\n    from the Catch clause.  Another option is to set a flag variable and\n    use goto to jump to the end of the Try clause, then check the flag\n    after the Try/Catch statement.\n\n    IMPORTANT: The values of any non-volatile automatic variables\n    changed within the Try clause are undefined after an exception is\n    caught.  Therefore, variables modified inside the Try block whose\n    values are needed later outside the Try block must either use static\n    storage or be declared with the \"volatile\" type qualifier.\n\n\nThrow expression;\n\n    A Throw statement is very much like a return statement, except that\n    the expression is required.  Whereas return jumps back to the place\n    where the current function was called, Throw jumps back to the Catch\n    clause of the innermost enclosing Try clause.  The expression must\n    be compatible with the type passed to define_exception_type().  The\n    exception must be caught, otherwise the program may crash.\n\n    Slight limitation:  If the expression is a comma-expression, it must\n    be enclosed in parentheses.\n\n\nTry statement\nCatch_anonymous statement\n\n    When the value of the exception is not needed, a Try/Catch statement\n    can use Catch_anonymous instead of Catch (expression).\n\n\nEverything below this point is for the benefit of the compiler.  The\napplication programmer should pretend not to know any of it, because it\nis subject to change.\n\n===*/\n\n\n#ifndef CEXCEPT_H\n#define CEXCEPT_H\n\n\n#include <setjmp.h>\n\n#define define_exception_type(etype) \\\nstruct exception_context { \\\n  jmp_buf *penv; \\\n  int caught; \\\n  volatile struct { etype etmp; } v; \\\n}\n\n/* etmp must be volatile because the application might use automatic */\n/* storage for the_exception_context, and etmp is modified between   */\n/* the calls to setjmp() and longjmp().  A wrapper struct is used to */\n/* avoid warnings about a duplicate volatile qualifier in case etype */\n/* already includes it.                                              */\n\n#define init_exception_context(ec) ((void)((ec)->penv = 0))\n\n#define Try \\\n  { \\\n    jmp_buf *exception__prev, exception__env; \\\n    exception__prev = the_exception_context->penv; \\\n    the_exception_context->penv = &exception__env; \\\n    if (setjmp(exception__env) == 0) { \\\n      do\n\n#define exception__catch(action) \\\n      while (the_exception_context->caught = 0, \\\n             the_exception_context->caught); \\\n    } \\\n    else { \\\n      the_exception_context->caught = 1; \\\n    } \\\n    the_exception_context->penv = exception__prev; \\\n  } \\\n  if (!the_exception_context->caught || action) { } \\\n  else\n\n#define Catch(e) exception__catch(((e) = the_exception_context->v.etmp, 0))\n#define Catch_anonymous exception__catch(0)\n\n/* Try ends with do, and Catch begins with while(0) and ends with     */\n/* else, to ensure that Try/Catch syntax is similar to if/else        */\n/* syntax.                                                            */\n/*                                                                    */\n/* The 0 in while(0) is expressed as x=0,x in order to appease        */\n/* compilers that warn about constant expressions inside while().     */\n/* Most compilers should still recognize that the condition is always */\n/* false and avoid generating code for it.                            */\n\n#define Throw \\\n  for (;; longjmp(*the_exception_context->penv, 1)) \\\n    the_exception_context->v.etmp =\n\n\n#endif /* CEXCEPT_H */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/contrib/visupng/resource.h",
    "content": "//{{NO_DEPENDENCIES}}\n// Microsoft Developer Studio generated include file.\n// Used by VisualPng.rc\n//\n#define IDM_FILE_OPEN                   40001\n#define IDM_FILE_SAVE                   40002\n#define IDM_FILE_NEXT                   40003\n#define IDM_FILE_PREVIOUS               40004\n#define IDM_FILE_EXIT                   40005\n#define IDM_OPTIONS_BACKGROUND          40006\n#define IDM_OPTIONS_STRETCH             40007\n#define IDM_HELP_ABOUT                  40008\n\n// Next default values for new objects\n//\n#ifdef APSTUDIO_INVOKED\n#ifndef APSTUDIO_READONLY_SYMBOLS\n#define _APS_NEXT_RESOURCE_VALUE        113\n#define _APS_NEXT_COMMAND_VALUE         40009\n#define _APS_NEXT_CONTROL_VALUE         1001\n#define _APS_NEXT_SYMED_VALUE           101\n#endif\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/libpng/example.c",
    "content": "\n#if 0 /* in case someone actually tries to compile this */\n\n/* example.c - an example of using libpng\n * Last changed in libpng 1.6.15 [November 20, 2014]\n * Maintained 1998-2014 Glenn Randers-Pehrson\n * Maintained 1996, 1997 Andreas Dilger)\n * Written 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n * To the extent possible under law, the authors have waived\n * all copyright and related or neighboring rights to this file.\n * This work is published from: United States.\n */\n\n/* This is an example of how to use libpng to read and write PNG files.\n * The file libpng-manual.txt is much more verbose then this.  If you have not\n * read it, do so first.  This was designed to be a starting point of an\n * implementation.  This is not officially part of libpng, is hereby placed\n * in the public domain, and therefore does not require a copyright notice.\n *\n * This file does not currently compile, because it is missing certain\n * parts, like allocating memory to hold an image.  You will have to\n * supply these parts to get it to compile.  For an example of a minimal\n * working PNG reader/writer, see pngtest.c, included in this distribution;\n * see also the programs in the contrib directory.\n */\n\n/* The simple, but restricted, approach to reading a PNG file or data stream\n * just requires two function calls, as in the following complete program.\n * Writing a file just needs one function call, so long as the data has an\n * appropriate layout.\n *\n * The following code reads PNG image data from a file and writes it, in a\n * potentially new format, to a new file.  While this code will compile there is\n * minimal (insufficient) error checking; for a more realistic version look at\n * contrib/examples/pngtopng.c\n */\n#include <stddef.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <png.h>\n#include <zlib.h>\n\nint main(int argc, const char **argv)\n{\n   if (argc == 3)\n   {\n      png_image image; /* The control structure used by libpng */\n\n      /* Initialize the 'png_image' structure. */\n      memset(&image, 0, (sizeof image));\n      image.version = PNG_IMAGE_VERSION;\n\n      /* The first argument is the file to read: */\n      if (png_image_begin_read_from_file(&image, argv[1]) != 0)\n      {\n         png_bytep buffer;\n\n         /* Set the format in which to read the PNG file; this code chooses a\n          * simple sRGB format with a non-associated alpha channel, adequate to\n          * store most images.\n          */\n         image.format = PNG_FORMAT_RGBA;\n\n         /* Now allocate enough memory to hold the image in this format; the\n          * PNG_IMAGE_SIZE macro uses the information about the image (width,\n          * height and format) stored in 'image'.\n          */\n         buffer = malloc(PNG_IMAGE_SIZE(image));\n\n         /* If enough memory was available read the image in the desired format\n          * then write the result out to the new file.  'background' is not\n          * necessary when reading the image because the alpha channel is\n          * preserved; if it were to be removed, for example if we requested\n          * PNG_FORMAT_RGB, then either a solid background color would have to\n          * be supplied or the output buffer would have to be initialized to the\n          * actual background of the image.\n          *\n          * The fourth argument to png_image_finish_read is the 'row_stride' -\n          * this is the number of components allocated for the image in each\n          * row.  It has to be at least as big as the value returned by\n          * PNG_IMAGE_ROW_STRIDE, but if you just allocate space for the\n          * default, minimum, size using PNG_IMAGE_SIZE as above you can pass\n          * zero.\n          *\n          * The final argument is a pointer to a buffer for the colormap;\n          * colormaps have exactly the same format as a row of image pixels (so\n          * you choose what format to make the colormap by setting\n          * image.format).  A colormap is only returned if\n          * PNG_FORMAT_FLAG_COLORMAP is also set in image.format, so in this\n          * case NULL is passed as the final argument.  If you do want to force\n          * all images into an index/color-mapped format then you can use:\n          *\n          *    PNG_IMAGE_COLORMAP_SIZE(image)\n          *\n          * to find the maximum size of the colormap in bytes.\n          */\n         if (buffer != NULL &&\n            png_image_finish_read(&image, NULL/*background*/, buffer,\n               0/*row_stride*/, NULL/*colormap*/) != 0)\n         {\n            /* Now write the image out to the second argument.  In the write\n             * call 'convert_to_8bit' allows 16-bit data to be squashed down to\n             * 8 bits; this isn't necessary here because the original read was\n             * to the 8-bit format.\n             */\n            if (png_image_write_to_file(&image, argv[2], 0/*convert_to_8bit*/,\n               buffer, 0/*row_stride*/, NULL/*colormap*/) != 0)\n            {\n               /* The image has been written successfully. */\n               exit(0);\n            }\n         }\n\n         else\n         {\n            /* Calling png_free_image is optional unless the simplified API was\n             * not run to completion.  In this case if there wasn't enough\n             * memory for 'buffer' we didn't complete the read, so we must free\n             * the image:\n             */\n            if (buffer == NULL)\n               png_free_image(&image);\n\n            else\n               free(buffer);\n      }\n\n      /* Something went wrong reading or writing the image.  libpng stores a\n       * textual message in the 'png_image' structure:\n       */\n      fprintf(stderr, \"pngtopng: error: %s\\n\", image.message);\n      exit (1);\n   }\n\n   fprintf(stderr, \"pngtopng: usage: pngtopng input-file output-file\\n\");\n   exit(1);\n}\n\n/* That's it ;-)  Of course you probably want to do more with PNG files than\n * just converting them all to 32-bit RGBA PNG files; you can do that between\n * the call to png_image_finish_read and png_image_write_to_file.  You can also\n * ask for the image data to be presented in a number of different formats.  You\n * do this by simply changing the 'format' parameter set before allocating the\n * buffer.\n *\n * The format parameter consists of five flags that define various aspects of\n * the image, you can simply add these together to get the format or you can use\n * one of the predefined macros from png.h (as above):\n *\n * PNG_FORMAT_FLAG_COLOR: if set the image will have three color components per\n *    pixel (red, green and blue), if not set the image will just have one\n *    luminance (grayscale) component.\n *\n * PNG_FORMAT_FLAG_ALPHA: if set each pixel in the image will have an additional\n *    alpha value; a linear value that describes the degree the image pixel\n *    covers (overwrites) the contents of the existing pixel on the display.\n *\n * PNG_FORMAT_FLAG_LINEAR: if set the components of each pixel will be returned\n *    as a series of 16-bit linear values, if not set the components will be\n *    returned as a series of 8-bit values encoded according to the 'sRGB'\n *    standard.  The 8-bit format is the normal format for images intended for\n *    direct display, because almost all display devices do the inverse of the\n *    sRGB transformation to the data they receive.  The 16-bit format is more\n *    common for scientific data and image data that must be further processed;\n *    because it is linear simple math can be done on the component values.\n *    Regardless of the setting of this flag the alpha channel is always linear,\n *    although it will be 8 bits or 16 bits wide as specified by the flag.\n *\n * PNG_FORMAT_FLAG_BGR: if set the components of a color pixel will be returned\n *    in the order blue, then green, then red.  If not set the pixel components\n *    are in the order red, then green, then blue.\n *\n * PNG_FORMAT_FLAG_AFIRST: if set the alpha channel (if present) precedes the\n *    color or grayscale components.  If not set the alpha channel follows the\n *    components.\n *\n * You do not have to read directly from a file.  You can read from memory or,\n * on systems that support it, from a <stdio.h> FILE*.  This is controlled by\n * the particular png_image_read_from_ function you call at the start.  Likewise\n * on write you can write to a FILE* if your system supports it.  Check the\n * macro PNG_STDIO_SUPPORTED to see if stdio support has been included in your\n * libpng build.\n *\n * If you read 16-bit (PNG_FORMAT_FLAG_LINEAR) data you may need to write it in\n * the 8-bit format for display.  You do this by setting the convert_to_8bit\n * flag to 'true'.\n *\n * Don't repeatedly convert between the 8-bit and 16-bit forms.  There is\n * significant data loss when 16-bit data is converted to the 8-bit encoding and\n * the current libpng implementation of conversion to 16-bit is also\n * significantly lossy.  The latter will be fixed in the future, but the former\n * is unavoidable - the 8-bit format just doesn't have enough resolution.\n */\n\n/* If your program needs more information from the PNG data it reads, or if you\n * need to do more complex transformations, or minimize transformations, on the\n * data you read, then you must use one of the several lower level libpng\n * interfaces.\n *\n * All these interfaces require that you do your own error handling - your\n * program must be able to arrange for control to return to your own code any\n * time libpng encounters a problem.  There are several ways to do this, but the\n * standard way is to use the ANSI-C (C90) <setjmp.h> interface to establish a\n * return point within your own code.  You must do this if you do not use the\n * simplified interface (above).\n *\n * The first step is to include the header files you need, including the libpng\n * header file.  Include any standard headers and feature test macros your\n * program requires before including png.h:\n */\n#include <png.h>\n\n /* The png_jmpbuf() macro, used in error handling, became available in\n  * libpng version 1.0.6.  If you want to be able to run your code with older\n  * versions of libpng, you must define the macro yourself (but only if it\n  * is not already defined by libpng!).\n  */\n\n#ifndef png_jmpbuf\n#  define png_jmpbuf(png_ptr) ((png_ptr)->png_jmpbuf)\n#endif\n\n/* Check to see if a file is a PNG file using png_sig_cmp().  png_sig_cmp()\n * returns zero if the image is a PNG and nonzero if it isn't a PNG.\n *\n * The function check_if_png() shown here, but not used, returns nonzero (true)\n * if the file can be opened and is a PNG, 0 (false) otherwise.\n *\n * If this call is successful, and you are going to keep the file open,\n * you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once\n * you have created the png_ptr, so that libpng knows your application\n * has read that many bytes from the start of the file.  Make sure you\n * don't call png_set_sig_bytes() with more than 8 bytes read or give it\n * an incorrect number of bytes read, or you will either have read too\n * many bytes (your fault), or you are telling libpng to read the wrong\n * number of magic bytes (also your fault).\n *\n * Many applications already read the first 2 or 4 bytes from the start\n * of the image to determine the file type, so it would be easiest just\n * to pass the bytes to png_sig_cmp() or even skip that if you know\n * you have a PNG file, and call png_set_sig_bytes().\n */\n#define PNG_BYTES_TO_CHECK 4\nint check_if_png(char *file_name, FILE **fp)\n{\n   char buf[PNG_BYTES_TO_CHECK];\n\n   /* Open the prospective PNG file. */\n   if ((*fp = fopen(file_name, \"rb\")) == NULL)\n      return 0;\n\n   /* Read in some of the signature bytes */\n   if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK)\n      return 0;\n\n   /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.\n      Return nonzero (true) if they match */\n\n   return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));\n}\n\n/* Read a PNG file.  You may want to return an error code if the read\n * fails (depending upon the failure).  There are two \"prototypes\" given\n * here - one where we are given the filename, and we need to open the\n * file, and the other where we are given an open file (possibly with\n * some or all of the magic bytes read - see comments above).\n */\n#ifdef open_file /* prototype 1 */\nvoid read_png(char *file_name)  /* We need to open the file */\n{\n   png_structp png_ptr;\n   png_infop info_ptr;\n   int sig_read = 0;\n   png_uint_32 width, height;\n   int bit_depth, color_type, interlace_type;\n   FILE *fp;\n\n   if ((fp = fopen(file_name, \"rb\")) == NULL)\n      return (ERROR);\n\n#else no_open_file /* prototype 2 */\nvoid read_png(FILE *fp, int sig_read)  /* File is already open */\n{\n   png_structp png_ptr;\n   png_infop info_ptr;\n   png_uint_32 width, height;\n   int bit_depth, color_type, interlace_type;\n#endif no_open_file /* Only use one prototype! */\n\n   /* Create and initialize the png_struct with the desired error handler\n    * functions.  If you want to use the default stderr and longjump method,\n    * you can supply NULL for the last three parameters.  We also supply the\n    * the compiler header file version, so that we know if the application\n    * was compiled with a compatible version of the library.  REQUIRED\n    */\n   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,\n      png_voidp user_error_ptr, user_error_fn, user_warning_fn);\n\n   if (png_ptr == NULL)\n   {\n      fclose(fp);\n      return (ERROR);\n   }\n\n   /* Allocate/initialize the memory for image information.  REQUIRED. */\n   info_ptr = png_create_info_struct(png_ptr);\n   if (info_ptr == NULL)\n   {\n      fclose(fp);\n      png_destroy_read_struct(&png_ptr, NULL, NULL);\n      return (ERROR);\n   }\n\n   /* Set error handling if you are using the setjmp/longjmp method (this is\n    * the normal method of doing things with libpng).  REQUIRED unless you\n    * set up your own error handlers in the png_create_read_struct() earlier.\n    */\n\n   if (setjmp(png_jmpbuf(png_ptr)))\n   {\n      /* Free all of the memory associated with the png_ptr and info_ptr */\n      png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n      fclose(fp);\n      /* If we get here, we had a problem reading the file */\n      return (ERROR);\n   }\n\n   /* One of the following I/O initialization methods is REQUIRED */\n#ifdef streams /* PNG file I/O method 1 */\n   /* Set up the input control if you are using standard C streams */\n   png_init_io(png_ptr, fp);\n\n#else no_streams /* PNG file I/O method 2 */\n   /* If you are using replacement read functions, instead of calling\n    * png_init_io() here you would call:\n    */\n   png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);\n   /* where user_io_ptr is a structure you want available to the callbacks */\n#endif no_streams /* Use only one I/O method! */\n\n   /* If we have already read some of the signature */\n   png_set_sig_bytes(png_ptr, sig_read);\n\n#ifdef hilevel\n   /*\n    * If you have enough memory to read in the entire image at once,\n    * and you need to specify only transforms that can be controlled\n    * with one of the PNG_TRANSFORM_* bits (this presently excludes\n    * quantizing, filling, setting background, and doing gamma\n    * adjustment), then you can read the entire image (including\n    * pixels) into the info structure with this call:\n    */\n   png_read_png(png_ptr, info_ptr, png_transforms, NULL);\n\n#else\n   /* OK, you're doing it the hard way, with the lower-level functions */\n\n   /* The call to png_read_info() gives us all of the information from the\n    * PNG file before the first IDAT (image data chunk).  REQUIRED\n    */\n   png_read_info(png_ptr, info_ptr);\n\n   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,\n       &interlace_type, NULL, NULL);\n\n   /* Set up the data transformations you want.  Note that these are all\n    * optional.  Only call them if you want/need them.  Many of the\n    * transformations only work on specific types of images, and many\n    * are mutually exclusive.\n    */\n\n   /* Tell libpng to strip 16 bits/color files down to 8 bits/color.\n    * Use accurate scaling if it's available, otherwise just chop off the\n    * low byte.\n    */\n#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\n    png_set_scale_16(png_ptr);\n#else\n   png_set_strip_16(png_ptr);\n#endif\n\n   /* Strip alpha bytes from the input data without combining with the\n    * background (not recommended).\n    */\n   png_set_strip_alpha(png_ptr);\n\n   /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single\n    * byte into separate bytes (useful for paletted and grayscale images).\n    */\n   png_set_packing(png_ptr);\n\n   /* Change the order of packed pixels to least significant bit first\n    * (not useful if you are using png_set_packing). */\n   png_set_packswap(png_ptr);\n\n   /* Expand paletted colors into true RGB triplets */\n   if (color_type == PNG_COLOR_TYPE_PALETTE)\n      png_set_palette_to_rgb(png_ptr);\n\n   /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */\n   if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)\n      png_set_expand_gray_1_2_4_to_8(png_ptr);\n\n   /* Expand paletted or RGB images with transparency to full alpha channels\n    * so the data will be available as RGBA quartets.\n    */\n   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) != 0)\n      png_set_tRNS_to_alpha(png_ptr);\n\n   /* Set the background color to draw transparent and alpha images over.\n    * It is possible to set the red, green, and blue components directly\n    * for paletted images instead of supplying a palette index.  Note that\n    * even if the PNG file supplies a background, you are not required to\n    * use it - you should use the (solid) application background if it has one.\n    */\n\n   png_color_16 my_background, *image_background;\n\n   if (png_get_bKGD(png_ptr, info_ptr, &image_background) != 0)\n      png_set_background(png_ptr, image_background,\n                         PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);\n   else\n      png_set_background(png_ptr, &my_background,\n                         PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);\n\n   /* Some suggestions as to how to get a screen gamma value\n    *\n    * Note that screen gamma is the display_exponent, which includes\n    * the CRT_exponent and any correction for viewing conditions\n    */\n   if (/* We have a user-defined screen gamma value */)\n   {\n      screen_gamma = user-defined screen_gamma;\n   }\n   /* This is one way that applications share the same screen gamma value */\n   else if ((gamma_str = getenv(\"SCREEN_GAMMA\")) != NULL)\n   {\n      screen_gamma = atof(gamma_str);\n   }\n   /* If we don't have another value */\n   else\n   {\n      screen_gamma = PNG_DEFAULT_sRGB;  /* A good guess for a PC monitor\n                                           in a dimly lit room */\n      screen_gamma = PNG_GAMMA_MAC_18 or 1.0; /* Good guesses for Mac systems */\n   }\n\n   /* Tell libpng to handle the gamma conversion for you.  The final call\n    * is a good guess for PC generated images, but it should be configurable\n    * by the user at run time by the user.  It is strongly suggested that\n    * your application support gamma correction.\n    */\n\n   int intent;\n\n   if (png_get_sRGB(png_ptr, info_ptr, &intent) != 0)\n      png_set_gamma(png_ptr, screen_gamma, PNG_DEFAULT_sRGB);\n   else\n   {\n      double image_gamma;\n      if (png_get_gAMA(png_ptr, info_ptr, &image_gamma) != 0)\n         png_set_gamma(png_ptr, screen_gamma, image_gamma);\n      else\n         png_set_gamma(png_ptr, screen_gamma, 0.45455);\n   }\n\n#ifdef PNG_READ_QUANTIZE_SUPPORTED\n   /* Quantize RGB files down to 8-bit palette or reduce palettes\n    * to the number of colors available on your screen.\n    */\n   if ((color_type & PNG_COLOR_MASK_COLOR) != 0)\n   {\n      int num_palette;\n      png_colorp palette;\n\n      /* This reduces the image to the application supplied palette */\n      if (/* We have our own palette */)\n      {\n         /* An array of colors to which the image should be quantized */\n         png_color std_color_cube[MAX_SCREEN_COLORS];\n\n         png_set_quantize(png_ptr, std_color_cube, MAX_SCREEN_COLORS,\n            MAX_SCREEN_COLORS, NULL, 0);\n      }\n      /* This reduces the image to the palette supplied in the file */\n      else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) != 0)\n      {\n         png_uint_16p histogram = NULL;\n\n         png_get_hIST(png_ptr, info_ptr, &histogram);\n\n         png_set_quantize(png_ptr, palette, num_palette,\n                        max_screen_colors, histogram, 0);\n      }\n   }\n#endif /* READ_QUANTIZE */\n\n   /* Invert monochrome files to have 0 as white and 1 as black */\n   png_set_invert_mono(png_ptr);\n\n   /* If you want to shift the pixel values from the range [0,255] or\n    * [0,65535] to the original [0,7] or [0,31], or whatever range the\n    * colors were originally in:\n    */\n   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT) != 0)\n   {\n      png_color_8p sig_bit_p;\n\n      png_get_sBIT(png_ptr, info_ptr, &sig_bit_p);\n      png_set_shift(png_ptr, sig_bit_p);\n   }\n\n   /* Flip the RGB pixels to BGR (or RGBA to BGRA) */\n   if ((color_type & PNG_COLOR_MASK_COLOR) != 0)\n      png_set_bgr(png_ptr);\n\n   /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */\n   png_set_swap_alpha(png_ptr);\n\n   /* Swap bytes of 16-bit files to least significant byte first */\n   png_set_swap(png_ptr);\n\n   /* Add filler (or alpha) byte (before/after each RGB triplet) */\n   png_set_filler(png_ptr, 0xffff, PNG_FILLER_AFTER);\n\n#ifdef PNG_READ_INTERLACING_SUPPORTED\n   /* Turn on interlace handling.  REQUIRED if you are not using\n    * png_read_image().  To see how to handle interlacing passes,\n    * see the png_read_row() method below:\n    */\n   number_passes = png_set_interlace_handling(png_ptr);\n#else\n   number_passes = 1;\n#endif /* READ_INTERLACING */\n\n\n   /* Optional call to gamma correct and add the background to the palette\n    * and update info structure.  REQUIRED if you are expecting libpng to\n    * update the palette for you (ie you selected such a transform above).\n    */\n   png_read_update_info(png_ptr, info_ptr);\n\n   /* Allocate the memory to hold the image using the fields of info_ptr. */\n\n   /* The easiest way to read the image: */\n   png_bytep row_pointers[height];\n\n   /* Clear the pointer array */\n   for (row = 0; row < height; row++)\n      row_pointers[row] = NULL;\n\n   for (row = 0; row < height; row++)\n      row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr,\n         info_ptr));\n\n   /* Now it's time to read the image.  One of these methods is REQUIRED */\n#ifdef entire /* Read the entire image in one go */\n   png_read_image(png_ptr, row_pointers);\n\n#else no_entire /* Read the image one or more scanlines at a time */\n   /* The other way to read images - deal with interlacing: */\n\n   for (pass = 0; pass < number_passes; pass++)\n   {\n#ifdef single /* Read the image a single row at a time */\n      for (y = 0; y < height; y++)\n      {\n         png_read_rows(png_ptr, &row_pointers[y], NULL, 1);\n      }\n\n#else no_single /* Read the image several rows at a time */\n      for (y = 0; y < height; y += number_of_rows)\n      {\n#ifdef sparkle /* Read the image using the \"sparkle\" effect. */\n         png_read_rows(png_ptr, &row_pointers[y], NULL,\n            number_of_rows);\n#else no_sparkle /* Read the image using the \"rectangle\" effect */\n         png_read_rows(png_ptr, NULL, &row_pointers[y],\n            number_of_rows);\n#endif no_sparkle /* Use only one of these two methods */\n      }\n\n      /* If you want to display the image after every pass, do so here */\n#endif no_single /* Use only one of these two methods */\n   }\n#endif no_entire /* Use only one of these two methods */\n\n   /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */\n   png_read_end(png_ptr, info_ptr);\n#endif hilevel\n\n   /* At this point you have read the entire image */\n\n   /* Clean up after the read, and free any memory allocated - REQUIRED */\n   png_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n\n   /* Close the file */\n   fclose(fp);\n\n   /* That's it */\n   return (OK);\n}\n\n/* Progressively read a file */\n\nint\ninitialize_png_reader(png_structp *png_ptr, png_infop *info_ptr)\n{\n   /* Create and initialize the png_struct with the desired error handler\n    * functions.  If you want to use the default stderr and longjump method,\n    * you can supply NULL for the last three parameters.  We also check that\n    * the library version is compatible in case we are using dynamically\n    * linked libraries.\n    */\n   *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,\n       png_voidp user_error_ptr, user_error_fn, user_warning_fn);\n\n   if (*png_ptr == NULL)\n   {\n      *info_ptr = NULL;\n      return (ERROR);\n   }\n\n   *info_ptr = png_create_info_struct(png_ptr);\n\n   if (*info_ptr == NULL)\n   {\n      png_destroy_read_struct(png_ptr, info_ptr, NULL);\n      return (ERROR);\n   }\n\n   if (setjmp(png_jmpbuf((*png_ptr))))\n   {\n      png_destroy_read_struct(png_ptr, info_ptr, NULL);\n      return (ERROR);\n   }\n\n   /* This one's new.  You will need to provide all three\n    * function callbacks, even if you aren't using them all.\n    * If you aren't using all functions, you can specify NULL\n    * parameters.  Even when all three functions are NULL,\n    * you need to call png_set_progressive_read_fn().\n    * These functions shouldn't be dependent on global or\n    * static variables if you are decoding several images\n    * simultaneously.  You should store stream specific data\n    * in a separate struct, given as the second parameter,\n    * and retrieve the pointer from inside the callbacks using\n    * the function png_get_progressive_ptr(png_ptr).\n    */\n   png_set_progressive_read_fn(*png_ptr, (void *)stream_data,\n      info_callback, row_callback, end_callback);\n\n   return (OK);\n}\n\nint\nprocess_data(png_structp *png_ptr, png_infop *info_ptr,\n   png_bytep buffer, png_uint_32 length)\n{\n   if (setjmp(png_jmpbuf((*png_ptr))))\n   {\n      /* Free the png_ptr and info_ptr memory on error */\n      png_destroy_read_struct(png_ptr, info_ptr, NULL);\n      return (ERROR);\n   }\n\n   /* This one's new also.  Simply give it chunks of data as\n    * they arrive from the data stream (in order, of course).\n    * On segmented machines, don't give it any more than 64K.\n    * The library seems to run fine with sizes of 4K, although\n    * you can give it much less if necessary (I assume you can\n    * give it chunks of 1 byte, but I haven't tried with less\n    * than 256 bytes yet).  When this function returns, you may\n    * want to display any rows that were generated in the row\n    * callback, if you aren't already displaying them there.\n    */\n   png_process_data(*png_ptr, *info_ptr, buffer, length);\n   return (OK);\n}\n\ninfo_callback(png_structp png_ptr, png_infop info)\n{\n   /* Do any setup here, including setting any of the transformations\n    * mentioned in the Reading PNG files section.  For now, you _must_\n    * call either png_start_read_image() or png_read_update_info()\n    * after all the transformations are set (even if you don't set\n    * any).  You may start getting rows before png_process_data()\n    * returns, so this is your last chance to prepare for that.\n    */\n}\n\nrow_callback(png_structp png_ptr, png_bytep new_row,\n   png_uint_32 row_num, int pass)\n{\n   /*\n    * This function is called for every row in the image.  If the\n    * image is interlaced, and you turned on the interlace handler,\n    * this function will be called for every row in every pass.\n    *\n    * In this function you will receive a pointer to new row data from\n    * libpng called new_row that is to replace a corresponding row (of\n    * the same data format) in a buffer allocated by your application.\n    *\n    * The new row data pointer \"new_row\" may be NULL, indicating there is\n    * no new data to be replaced (in cases of interlace loading).\n    *\n    * If new_row is not NULL then you need to call\n    * png_progressive_combine_row() to replace the corresponding row as\n    * shown below:\n    */\n\n   /* Get pointer to corresponding row in our\n    * PNG read buffer.\n    */\n   png_bytep old_row = ((png_bytep *)our_data)[row_num];\n\n#ifdef PNG_READ_INTERLACING_SUPPORTED\n   /* If both rows are allocated then copy the new row\n    * data to the corresponding row data.\n    */\n   if ((old_row != NULL) && (new_row != NULL))\n   png_progressive_combine_row(png_ptr, old_row, new_row);\n\n   /*\n    * The rows and passes are called in order, so you don't really\n    * need the row_num and pass, but I'm supplying them because it\n    * may make your life easier.\n    *\n    * For the non-NULL rows of interlaced images, you must call\n    * png_progressive_combine_row() passing in the new row and the\n    * old row, as demonstrated above.  You can call this function for\n    * NULL rows (it will just return) and for non-interlaced images\n    * (it just does the memcpy for you) if it will make the code\n    * easier.  Thus, you can just do this for all cases:\n    */\n\n   png_progressive_combine_row(png_ptr, old_row, new_row);\n\n   /* where old_row is what was displayed for previous rows.  Note\n    * that the first pass (pass == 0 really) will completely cover\n    * the old row, so the rows do not have to be initialized.  After\n    * the first pass (and only for interlaced images), you will have\n    * to pass the current row as new_row, and the function will combine\n    * the old row and the new row.\n    */\n#endif /* READ_INTERLACING */\n}\n\nend_callback(png_structp png_ptr, png_infop info)\n{\n   /* This function is called when the whole image has been read,\n    * including any chunks after the image (up to and including\n    * the IEND).  You will usually have the same info chunk as you\n    * had in the header, although some data may have been added\n    * to the comments and time fields.\n    *\n    * Most people won't do much here, perhaps setting a flag that\n    * marks the image as finished.\n    */\n}\n\n/* Write a png file */\nvoid write_png(char *file_name /* , ... other image information ... */)\n{\n   FILE *fp;\n   png_structp png_ptr;\n   png_infop info_ptr;\n   png_colorp palette;\n\n   /* Open the file */\n   fp = fopen(file_name, \"wb\");\n   if (fp == NULL)\n      return (ERROR);\n\n   /* Create and initialize the png_struct with the desired error handler\n    * functions.  If you want to use the default stderr and longjump method,\n    * you can supply NULL for the last three parameters.  We also check that\n    * the library version is compatible with the one used at compile time,\n    * in case we are using dynamically linked libraries.  REQUIRED.\n    */\n   png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,\n      png_voidp user_error_ptr, user_error_fn, user_warning_fn);\n\n   if (png_ptr == NULL)\n   {\n      fclose(fp);\n      return (ERROR);\n   }\n\n   /* Allocate/initialize the image information data.  REQUIRED */\n   info_ptr = png_create_info_struct(png_ptr);\n   if (info_ptr == NULL)\n   {\n      fclose(fp);\n      png_destroy_write_struct(&png_ptr,  NULL);\n      return (ERROR);\n   }\n\n   /* Set error handling.  REQUIRED if you aren't supplying your own\n    * error handling functions in the png_create_write_struct() call.\n    */\n   if (setjmp(png_jmpbuf(png_ptr)))\n   {\n      /* If we get here, we had a problem writing the file */\n      fclose(fp);\n      png_destroy_write_struct(&png_ptr, &info_ptr);\n      return (ERROR);\n   }\n\n   /* One of the following I/O initialization functions is REQUIRED */\n\n#ifdef streams /* I/O initialization method 1 */\n   /* Set up the output control if you are using standard C streams */\n   png_init_io(png_ptr, fp);\n\n#else no_streams /* I/O initialization method 2 */\n   /* If you are using replacement write functions, instead of calling\n    * png_init_io() here you would call\n    */\n   png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn,\n      user_IO_flush_function);\n   /* where user_io_ptr is a structure you want available to the callbacks */\n#endif no_streams /* Only use one initialization method */\n\n#ifdef hilevel\n   /* This is the easy way.  Use it if you already have all the\n    * image info living in the structure.  You could \"|\" many\n    * PNG_TRANSFORM flags into the png_transforms integer here.\n    */\n   png_write_png(png_ptr, info_ptr, png_transforms, NULL);\n\n#else\n   /* This is the hard way */\n\n   /* Set the image information here.  Width and height are up to 2^31,\n    * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on\n    * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,\n    * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,\n    * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or\n    * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST\n    * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED\n    */\n   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???,\n      PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);\n\n   /* Set the palette if there is one.  REQUIRED for indexed-color images */\n   palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH\n             * (sizeof (png_color)));\n   /* ... Set palette colors ... */\n   png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);\n   /* You must not free palette here, because png_set_PLTE only makes a link to\n    * the palette that you malloced.  Wait until you are about to destroy\n    * the png structure.\n    */\n\n   /* Optional significant bit (sBIT) chunk */\n   png_color_8 sig_bit;\n\n   /* If we are dealing with a grayscale image then */\n   sig_bit.gray = true_bit_depth;\n\n   /* Otherwise, if we are dealing with a color image then */\n   sig_bit.red = true_red_bit_depth;\n   sig_bit.green = true_green_bit_depth;\n   sig_bit.blue = true_blue_bit_depth;\n\n   /* If the image has an alpha channel then */\n   sig_bit.alpha = true_alpha_bit_depth;\n\n   png_set_sBIT(png_ptr, info_ptr, &sig_bit);\n\n\n   /* Optional gamma chunk is strongly suggested if you have any guess\n    * as to the correct gamma of the image.\n    */\n   png_set_gAMA(png_ptr, info_ptr, gamma);\n\n   /* Optionally write comments into the image */\n   {\n      png_text text_ptr[3];\n\n      char key0[]=\"Title\";\n      char text0[]=\"Mona Lisa\";\n      text_ptr[0].key = key0;\n      text_ptr[0].text = text0;\n      text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;\n      text_ptr[0].itxt_length = 0;\n      text_ptr[0].lang = NULL;\n      text_ptr[0].lang_key = NULL;\n\n      char key1[]=\"Author\";\n      char text1[]=\"Leonardo DaVinci\";\n      text_ptr[1].key = key1;\n      text_ptr[1].text = text1;\n      text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;\n      text_ptr[1].itxt_length = 0;\n      text_ptr[1].lang = NULL;\n      text_ptr[1].lang_key = NULL;\n\n      char key2[]=\"Description\";\n      char text2[]=\"<long text>\";\n      text_ptr[2].key = key2;\n      text_ptr[2].text = text2;\n      text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;\n      text_ptr[2].itxt_length = 0;\n      text_ptr[2].lang = NULL;\n      text_ptr[2].lang_key = NULL;\n\n      png_set_text(write_ptr, write_info_ptr, text_ptr, 3);\n   }\n\n   /* Other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs */\n\n   /* Note that if sRGB is present the gAMA and cHRM chunks must be ignored\n    * on read and, if your application chooses to write them, they must\n    * be written in accordance with the sRGB profile\n    */\n\n   /* Write the file header information.  REQUIRED */\n   png_write_info(png_ptr, info_ptr);\n\n   /* If you want, you can write the info in two steps, in case you need to\n    * write your private chunk ahead of PLTE:\n    *\n    *   png_write_info_before_PLTE(write_ptr, write_info_ptr);\n    *   write_my_chunk();\n    *   png_write_info(png_ptr, info_ptr);\n    *\n    * However, given the level of known- and unknown-chunk support in 1.2.0\n    * and up, this should no longer be necessary.\n    */\n\n   /* Once we write out the header, the compression type on the text\n    * chunk gets changed to PNG_TEXT_COMPRESSION_NONE_WR or\n    * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again\n    * at the end.\n    */\n\n   /* Set up the transformations you want.  Note that these are\n    * all optional.  Only call them if you want them.\n    */\n\n   /* Invert monochrome pixels */\n   png_set_invert_mono(png_ptr);\n\n   /* Shift the pixels up to a legal bit depth and fill in\n    * as appropriate to correctly scale the image.\n    */\n   png_set_shift(png_ptr, &sig_bit);\n\n   /* Pack pixels into bytes */\n   png_set_packing(png_ptr);\n\n   /* Swap location of alpha bytes from ARGB to RGBA */\n   png_set_swap_alpha(png_ptr);\n\n   /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into\n    * RGB (4 channels -> 3 channels). The second parameter is not used.\n    */\n   png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);\n\n   /* Flip BGR pixels to RGB */\n   png_set_bgr(png_ptr);\n\n   /* Swap bytes of 16-bit files to most significant byte first */\n   png_set_swap(png_ptr);\n\n   /* Swap bits of 1-bit, 2-bit, 4-bit packed pixel formats */\n   png_set_packswap(png_ptr);\n\n   /* Turn on interlace handling if you are not using png_write_image() */\n   if (interlacing != 0)\n      number_passes = png_set_interlace_handling(png_ptr);\n\n   else\n      number_passes = 1;\n\n   /* The easiest way to write the image (you may have a different memory\n    * layout, however, so choose what fits your needs best).  You need to\n    * use the first method if you aren't handling interlacing yourself.\n    */\n   png_uint_32 k, height, width;\n\n   /* In this example, \"image\" is a one-dimensional array of bytes */\n   png_byte image[height*width*bytes_per_pixel];\n\n   png_bytep row_pointers[height];\n\n   if (height > PNG_UINT_32_MAX/(sizeof (png_bytep)))\n     png_error (png_ptr, \"Image is too tall to process in memory\");\n\n   /* Set up pointers into your \"image\" byte array */\n   for (k = 0; k < height; k++)\n     row_pointers[k] = image + k*width*bytes_per_pixel;\n\n   /* One of the following output methods is REQUIRED */\n\n#ifdef entire /* Write out the entire image data in one call */\n   png_write_image(png_ptr, row_pointers);\n\n   /* The other way to write the image - deal with interlacing */\n\n#else no_entire /* Write out the image data by one or more scanlines */\n\n   /* The number of passes is either 1 for non-interlaced images,\n    * or 7 for interlaced images.\n    */\n   for (pass = 0; pass < number_passes; pass++)\n   {\n      /* Write a few rows at a time. */\n      png_write_rows(png_ptr, &row_pointers[first_row], number_of_rows);\n\n      /* If you are only writing one row at a time, this works */\n      for (y = 0; y < height; y++)\n         png_write_rows(png_ptr, &row_pointers[y], 1);\n   }\n#endif no_entire /* Use only one output method */\n\n   /* You can write optional chunks like tEXt, zTXt, and tIME at the end\n    * as well.  Shouldn't be necessary in 1.2.0 and up as all the public\n    * chunks are supported and you can use png_set_unknown_chunks() to\n    * register unknown chunks into the info structure to be written out.\n    */\n\n   /* It is REQUIRED to call this to finish writing the rest of the file */\n   png_write_end(png_ptr, info_ptr);\n#endif hilevel\n\n   /* If you png_malloced a palette, free it here (don't free info_ptr->palette,\n    * as recommended in versions 1.0.5m and earlier of this example; if\n    * libpng mallocs info_ptr->palette, libpng will free it).  If you\n    * allocated it with malloc() instead of png_malloc(), use free() instead\n    * of png_free().\n    */\n   png_free(png_ptr, palette);\n   palette = NULL;\n\n   /* Similarly, if you png_malloced any data that you passed in with\n    * png_set_something(), such as a hist or trans array, free it here,\n    * when you can be sure that libpng is through with it.\n    */\n   png_free(png_ptr, trans);\n   trans = NULL;\n   /* Whenever you use png_free() it is a good idea to set the pointer to\n    * NULL in case your application inadvertently tries to png_free() it\n    * again.  When png_free() sees a NULL it returns without action, thus\n    * avoiding the double-free security problem.\n    */\n\n   /* Clean up after the write, and free any memory allocated */\n   png_destroy_write_struct(&png_ptr, &info_ptr);\n\n   /* Close the file */\n   fclose(fp);\n\n   /* That's it */\n   return (OK);\n}\n\n#endif /* if 0 */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/libpng-config.in",
    "content": "#! /bin/sh\n\n# libpng-config\n# provides configuration info for libpng.\n\n# Copyright (C) 2002, 2004, 2006, 2007 Glenn Randers-Pehrson\n\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Modeled after libxml-config.\n\nversion=\"@PNGLIB_VERSION@\"\nprefix=\"@prefix@\"\nexec_prefix=\"@exec_prefix@\"\nlibdir=\"@libdir@\"\nincludedir=\"@includedir@/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@\"\nlibs=\"-lpng@PNGLIB_MAJOR@@PNGLIB_MINOR@\"\nall_libs=\"-lpng@PNGLIB_MAJOR@@PNGLIB_MINOR@ @LIBS@\"\nI_opts=\"-I${includedir}\"\nL_opts=\"-L${libdir}\"\nR_opts=\"\"\ncppflags=\"\"\nccopts=\"\"\nldopts=\"\"\n\nusage()\n{\n    cat <<EOF\nUsage: $0 [OPTION] ...\n\nKnown values for OPTION are:\n\n  --prefix        print libpng prefix\n  --libdir        print path to directory containing library\n  --libs          print library linking information\n  --ccopts        print compiler options\n  --cppflags      print pre-processor flags\n  --cflags        print preprocessor flags, I_opts, and compiler options\n  --I_opts        print \"-I\" include options\n  --L_opts        print linker \"-L\" flags for dynamic linking\n  --R_opts        print dynamic linker \"-R\" or \"-rpath\" flags\n  --ldopts        print linker options\n  --ldflags       print linker flags (ldopts, L_opts, R_opts, and libs)\n  --static        revise subsequent outputs for static linking\n  --help          print this help and exit\n  --version       print version information\nEOF\n\n    exit $1\n}\n\nif test $# -eq 0; then\n    usage 1\nfi\n\nwhile test $# -gt 0; do\n    case \"$1\" in\n\n    --prefix)\n        echo ${prefix}\n        ;;\n\n    --version)\n        echo ${version}\n        exit 0\n        ;;\n\n    --help)\n        usage 0\n        ;;\n\n    --ccopts)\n        echo ${ccopts}\n        ;;\n\n    --cppflags)\n        echo ${cppflags}\n        ;;\n\n    --cflags)\n        echo ${I_opts} ${cppflags} ${ccopts}\n        ;;\n\n    --libdir)\n        echo ${libdir}\n        ;;\n\n    --libs)\n        echo ${libs}\n        ;;\n\n    --I_opts)\n        echo ${I_opts}\n        ;;\n\n    --L_opts)\n        echo ${L_opts}\n        ;;\n\n    --R_opts)\n        echo ${R_opts}\n        ;;\n\n    --ldopts)\n        echo ${ldopts}\n        ;;\n\n    --ldflags)\n        echo ${ldopts} ${L_opts} ${R_opts} ${libs}\n        ;;\n\n    --static)\n        R_opts=\"\"\n        libs=${all_libs}\n        ;;\n\n    *)\n        usage\n        exit 1\n        ;;\n    esac\n    shift\ndone\n\nexit 0\n"
  },
  {
    "path": "atlas-aapt/external/libpng/libpng-manual.txt",
    "content": "libpng-manual.txt - A description on how to use and modify libpng\n\n libpng version 1.6.22beta03 - February 19, 2016\n Updated and distributed by Glenn Randers-Pehrson\n <glennrp at users.sourceforge.net>\n Copyright (c) 1998-2016 Glenn Randers-Pehrson\n\n This document is released under the libpng license.\n For conditions of distribution and use, see the disclaimer\n and license in png.h\n\n Based on:\n\n libpng versions 0.97, January 1998, through 1.6.22beta03 - February 19, 2016\n Updated and distributed by Glenn Randers-Pehrson\n Copyright (c) 1998-2016 Glenn Randers-Pehrson\n\n libpng 1.0 beta 6 - version 0.96 - May 28, 1997\n Updated and distributed by Andreas Dilger\n Copyright (c) 1996, 1997 Andreas Dilger\n\n libpng 1.0 beta 2 - version 0.88 - January 26, 1996\n For conditions of distribution and use, see copyright\n notice in png.h. Copyright (c) 1995, 1996 Guy Eric\n Schalnat, Group 42, Inc.\n\n Updated/rewritten per request in the libpng FAQ\n Copyright (c) 1995, 1996 Frank J. T. Wojcik\n December 18, 1995 & January 20, 1996\n\n TABLE OF CONTENTS\n\n    I. Introduction\n   II. Structures\n  III. Reading\n   IV. Writing\n    V. Simplified API\n   VI. Modifying/Customizing libpng\n  VII. MNG support\n VIII. Changes to Libpng from version 0.88\n   IX. Changes to Libpng from version 1.0.x to 1.2.x\n    X. Changes to Libpng from version 1.0.x/1.2.x to 1.4.x\n   XI. Changes to Libpng from version 1.4.x to 1.5.x\n  XII. Changes to Libpng from version 1.5.x to 1.6.x\n XIII. Detecting libpng\n  XIV. Source code repository\n   XV. Coding style\n  XVI. Y2K Compliance in libpng\n\nI. Introduction\n\nThis file describes how to use and modify the PNG reference library\n(known as libpng) for your own use.  In addition to this\nfile, example.c is a good starting point for using the library, as\nit is heavily commented and should include everything most people\nwill need.  We assume that libpng is already installed; see the\nINSTALL file for instructions on how to configure and install libpng.\n\nFor examples of libpng usage, see the files \"example.c\", \"pngtest.c\",\nand the files in the \"contrib\" directory, all of which are included in\nthe libpng distribution.\n\nLibpng was written as a companion to the PNG specification, as a way\nof reducing the amount of time and effort it takes to support the PNG\nfile format in application programs.\n\nThe PNG specification (second edition), November 2003, is available as\na W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at\n<http://www.w3.org/TR/2003/REC-PNG-20031110/\nThe W3C and ISO documents have identical technical content.\n\nThe PNG-1.2 specification is available at\n<http://png-mng.sourceforge.net/pub/png/spec/1.2/>.\nIt is technically equivalent\nto the PNG specification (second edition) but has some additional material.\n\nThe PNG-1.0 specification is available as RFC 2083 \n<http://png-mng.sourceforge.net/pub/png/spec/1.0/> and as a\nW3C Recommendation <http://www.w3.org/TR/REC-png-961001>.\n\nSome additional chunks are described in the special-purpose public chunks\ndocuments at <http://www.libpng.org/pub/png/spec/register/>\n\nOther information\nabout PNG, and the latest version of libpng, can be found at the PNG home\npage, <http://www.libpng.org/pub/png/>.\n\nMost users will not have to modify the library significantly; advanced\nusers may want to modify it more.  All attempts were made to make it as\ncomplete as possible, while keeping the code easy to understand.\nCurrently, this library only supports C.  Support for other languages\nis being considered.\n\nLibpng has been designed to handle multiple sessions at one time,\nto be easily modifiable, to be portable to the vast majority of\nmachines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy\nto use.  The ultimate goal of libpng is to promote the acceptance of\nthe PNG file format in whatever way possible.  While there is still\nwork to be done (see the TODO file), libpng should cover the\nmajority of the needs of its users.\n\nLibpng uses zlib for its compression and decompression of PNG files.\nFurther information about zlib, and the latest version of zlib, can\nbe found at the zlib home page, <http://zlib.net/>.\nThe zlib compression utility is a general purpose utility that is\nuseful for more than PNG files, and can be used without libpng.\nSee the documentation delivered with zlib for more details.\nYou can usually find the source files for the zlib utility wherever you\nfind the libpng source files.\n\nLibpng is thread safe, provided the threads are using different\ninstances of the structures.  Each thread should have its own\npng_struct and png_info instances, and thus its own image.\nLibpng does not protect itself against two threads using the\nsame instance of a structure.\n\nII. Structures\n\nThere are two main structures that are important to libpng, png_struct\nand png_info.  Both are internal structures that are no longer exposed\nin the libpng interface (as of libpng 1.5.0).\n\nThe png_info structure is designed to provide information about the\nPNG file.  At one time, the fields of png_info were intended to be\ndirectly accessible to the user.  However, this tended to cause problems\nwith applications using dynamically loaded libraries, and as a result\na set of interface functions for png_info (the png_get_*() and png_set_*()\nfunctions) was developed, and direct access to the png_info fields was\ndeprecated..\n\nThe png_struct structure is the object used by the library to decode a\nsingle image.  As of 1.5.0 this structure is also not exposed.\n\nAlmost all libpng APIs require a pointer to a png_struct as the first argument.\nMany (in particular the png_set and png_get APIs) also require a pointer\nto png_info as the second argument.  Some application visible macros\ndefined in png.h designed for basic data access (reading and writing\nintegers in the PNG format) don't take a png_info pointer, but it's almost\nalways safe to assume that a (png_struct*) has to be passed to call an API\nfunction.\n\nYou can have more than one png_info structure associated with an image,\nas illustrated in pngtest.c, one for information valid prior to the\nIDAT chunks and another (called \"end_info\" below) for things after them.\n\nThe png.h header file is an invaluable reference for programming with libpng.\nAnd while I'm on the topic, make sure you include the libpng header file:\n\n#include <png.h>\n\nand also (as of libpng-1.5.0) the zlib header file, if you need it:\n\n#include <zlib.h>\n\nTypes\n\nThe png.h header file defines a number of integral types used by the\nAPIs.  Most of these are fairly obvious; for example types corresponding\nto integers of particular sizes and types for passing color values.\n\nOne exception is how non-integral numbers are handled.  For application\nconvenience most APIs that take such numbers have C (double) arguments;\nhowever, internally PNG, and libpng, use 32 bit signed integers and encode\nthe value by multiplying by 100,000.  As of libpng 1.5.0 a convenience\nmacro PNG_FP_1 is defined in png.h along with a type (png_fixed_point)\nwhich is simply (png_int_32).\n\nAll APIs that take (double) arguments also have a matching API that\ntakes the corresponding fixed point integer arguments.  The fixed point\nAPI has the same name as the floating point one with \"_fixed\" appended.\nThe actual range of values permitted in the APIs is frequently less than\nthe full range of (png_fixed_point) (-21474 to +21474).  When APIs require\na non-negative argument the type is recorded as png_uint_32 above.  Consult\nthe header file and the text below for more information.\n\nSpecial care must be take with sCAL chunk handling because the chunk itself\nuses non-integral values encoded as strings containing decimal floating point\nnumbers.  See the comments in the header file.\n\nConfiguration\n\nThe main header file function declarations are frequently protected by C\npreprocessing directives of the form:\n\n    #ifdef PNG_feature_SUPPORTED\n    declare-function\n    #endif\n    ...\n    #ifdef PNG_feature_SUPPORTED\n    use-function\n    #endif\n\nThe library can be built without support for these APIs, although a\nstandard build will have all implemented APIs.  Application programs\nshould check the feature macros before using an API for maximum\nportability.  From libpng 1.5.0 the feature macros set during the build\nof libpng are recorded in the header file \"pnglibconf.h\" and this file\nis always included by png.h.\n\nIf you don't need to change the library configuration from the default, skip to\nthe next section (\"Reading\").\n\nNotice that some of the makefiles in the 'scripts' directory and (in 1.5.0) all\nof the build project files in the 'projects' directory simply copy\nscripts/pnglibconf.h.prebuilt to pnglibconf.h.  This means that these build\nsystems do not permit easy auto-configuration of the library - they only\nsupport the default configuration.\n\nThe easiest way to make minor changes to the libpng configuration when\nauto-configuration is supported is to add definitions to the command line\nusing (typically) CPPFLAGS.  For example:\n\nCPPFLAGS=-DPNG_NO_FLOATING_ARITHMETIC\n\nwill change the internal libpng math implementation for gamma correction and\nother arithmetic calculations to fixed point, avoiding the need for fast\nfloating point support.  The result can be seen in the generated pnglibconf.h -\nmake sure it contains the changed feature macro setting.\n\nIf you need to make more extensive configuration changes - more than one or two\nfeature macro settings - you can either add -DPNG_USER_CONFIG to the build\ncommand line and put a list of feature macro settings in pngusr.h or you can set\nDFA_XTRA (a makefile variable) to a file containing the same information in the\nform of 'option' settings.\n\nA. Changing pnglibconf.h\n\nA variety of methods exist to build libpng.  Not all of these support\nreconfiguration of pnglibconf.h.  To reconfigure pnglibconf.h it must either be\nrebuilt from scripts/pnglibconf.dfa using awk or it must be edited by hand.\n\nHand editing is achieved by copying scripts/pnglibconf.h.prebuilt to\npnglibconf.h and changing the lines defining the supported features, paying\nvery close attention to the 'option' information in scripts/pnglibconf.dfa\nthat describes those features and their requirements.  This is easy to get\nwrong.\n\nB. Configuration using DFA_XTRA\n\nRebuilding from pnglibconf.dfa is easy if a functioning 'awk', or a later\nvariant such as 'nawk' or 'gawk', is available.  The configure build will\nautomatically find an appropriate awk and build pnglibconf.h.\nThe scripts/pnglibconf.mak file contains a set of make rules for doing the\nsame thing if configure is not used, and many of the makefiles in the scripts\ndirectory use this approach.\n\nWhen rebuilding simply write a new file containing changed options and set\nDFA_XTRA to the name of this file.  This causes the build to append the new file\nto the end of scripts/pnglibconf.dfa.  The pngusr.dfa file should contain lines\nof the following forms:\n\neverything = off\n\nThis turns all optional features off.  Include it at the start of pngusr.dfa to\nmake it easier to build a minimal configuration.  You will need to turn at least\nsome features on afterward to enable either reading or writing code, or both.\n\noption feature on\noption feature off\n\nEnable or disable a single feature.  This will automatically enable other\nfeatures required by a feature that is turned on or disable other features that\nrequire a feature which is turned off.  Conflicting settings will cause an error\nmessage to be emitted by awk.\n\nsetting feature default value\n\nChanges the default value of setting 'feature' to 'value'.  There are a small\nnumber of settings listed at the top of pnglibconf.h, they are documented in the\nsource code.  Most of these values have performance implications for the library\nbut most of them have no visible effect on the API.  Some can also be overridden\nfrom the API.\n\nThis method of building a customized pnglibconf.h is illustrated in\ncontrib/pngminim/*.  See the \"$(PNGCONF):\" target in the makefile and\npngusr.dfa in these directories.\n\nC. Configuration using PNG_USER_CONFIG\n\nIf -DPNG_USER_CONFIG is added to the CPPFLAGS when pnglibconf.h is built,\nthe file pngusr.h will automatically be included before the options in\nscripts/pnglibconf.dfa are processed.  Your pngusr.h file should contain only\nmacro definitions turning features on or off or setting settings.\n\nApart from the global setting \"everything = off\" all the options listed above\ncan be set using macros in pngusr.h:\n\n#define PNG_feature_SUPPORTED\n\nis equivalent to:\n\noption feature on\n\n#define PNG_NO_feature\n\nis equivalent to:\n\noption feature off\n\n#define PNG_feature value\n\nis equivalent to:\n\nsetting feature default value\n\nNotice that in both cases, pngusr.dfa and pngusr.h, the contents of the\npngusr file you supply override the contents of scripts/pnglibconf.dfa\n\nIf confusing or incomprehensible behavior results it is possible to\nexamine the intermediate file pnglibconf.dfn to find the full set of\ndependency information for each setting and option.  Simply locate the\nfeature in the file and read the C comments that precede it.\n\nThis method is also illustrated in the contrib/pngminim/* makefiles and\npngusr.h.\n\nIII. Reading\n\nWe'll now walk you through the possible functions to call when reading\nin a PNG file sequentially, briefly explaining the syntax and purpose\nof each one.  See example.c and png.h for more detail.  While\nprogressive reading is covered in the next section, you will still\nneed some of the functions discussed in this section to read a PNG\nfile.\n\nSetup\n\nYou will want to do the I/O initialization(*) before you get into libpng,\nso if it doesn't work, you don't have much to undo.  Of course, you\nwill also want to insure that you are, in fact, dealing with a PNG\nfile.  Libpng provides a simple check to see if a file is a PNG file.\nTo use it, pass in the first 1 to 8 bytes of the file to the function\npng_sig_cmp(), and it will return 0 (false) if the bytes match the\ncorresponding bytes of the PNG signature, or nonzero (true) otherwise.\nOf course, the more bytes you pass in, the greater the accuracy of the\nprediction.\n\nIf you are intending to keep the file pointer open for use in libpng,\nyou must ensure you don't read more than 8 bytes from the beginning\nof the file, and you also have to make a call to png_set_sig_bytes()\nwith the number of bytes you read from the beginning.  Libpng will\nthen only check the bytes (if any) that your program didn't read.\n\n(*): If you are not using the standard I/O functions, you will need\nto replace them with custom functions.  See the discussion under\nCustomizing libpng.\n\n    FILE *fp = fopen(file_name, \"rb\");\n    if (!fp)\n    {\n       return (ERROR);\n    }\n\n    if (fread(header, 1, number, fp) != number)\n    {\n       return (ERROR);\n    }\n\n    is_png = !png_sig_cmp(header, 0, number);\n    if (!is_png)\n    {\n       return (NOT_PNG);\n    }\n\nNext, png_struct and png_info need to be allocated and initialized.  In\norder to ensure that the size of these structures is correct even with a\ndynamically linked libpng, there are functions to initialize and\nallocate the structures.  We also pass the library version, optional\npointers to error handling functions, and a pointer to a data struct for\nuse by the error functions, if necessary (the pointer and functions can\nbe NULL if the default error handlers are to be used).  See the section\non Changes to Libpng below regarding the old initialization functions.\nThe structure allocation functions quietly return NULL if they fail to\ncreate the structure, so your application should check for that.\n\n    png_structp png_ptr = png_create_read_struct\n        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,\n        user_error_fn, user_warning_fn);\n\n    if (!png_ptr)\n       return (ERROR);\n\n    png_infop info_ptr = png_create_info_struct(png_ptr);\n\n    if (!info_ptr)\n    {\n       png_destroy_read_struct(&png_ptr,\n           (png_infopp)NULL, (png_infopp)NULL);\n       return (ERROR);\n    }\n\nIf you want to use your own memory allocation routines,\nuse a libpng that was built with PNG_USER_MEM_SUPPORTED defined, and use\npng_create_read_struct_2() instead of png_create_read_struct():\n\n    png_structp png_ptr = png_create_read_struct_2\n        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,\n        user_error_fn, user_warning_fn, (png_voidp)\n        user_mem_ptr, user_malloc_fn, user_free_fn);\n\nThe error handling routines passed to png_create_read_struct()\nand the memory alloc/free routines passed to png_create_struct_2()\nare only necessary if you are not using the libpng supplied error\nhandling and memory alloc/free functions.\n\nWhen libpng encounters an error, it expects to longjmp back\nto your routine.  Therefore, you will need to call setjmp and pass\nyour png_jmpbuf(png_ptr).  If you read the file from different\nroutines, you will need to update the longjmp buffer every time you enter\na new routine that will call a png_*() function.\n\nSee your documentation of setjmp/longjmp for your compiler for more\ninformation on setjmp/longjmp.  See the discussion on libpng error\nhandling in the Customizing Libpng section below for more information\non the libpng error handling.  If an error occurs, and libpng longjmp's\nback to your setjmp, you will want to call png_destroy_read_struct() to\nfree any memory.\n\n    if (setjmp(png_jmpbuf(png_ptr)))\n    {\n       png_destroy_read_struct(&png_ptr, &info_ptr,\n           &end_info);\n       fclose(fp);\n       return (ERROR);\n    }\n\nPass (png_infopp)NULL instead of &end_info if you didn't create\nan end_info structure.\n\nIf you would rather avoid the complexity of setjmp/longjmp issues,\nyou can compile libpng with PNG_NO_SETJMP, in which case\nerrors will result in a call to PNG_ABORT() which defaults to abort().\n\nYou can #define PNG_ABORT() to a function that does something\nmore useful than abort(), as long as your function does not\nreturn.\n\nNow you need to set up the input code.  The default for libpng is to\nuse the C function fread().  If you use this, you will need to pass a\nvalid FILE * in the function png_init_io().  Be sure that the file is\nopened in binary mode.  If you wish to handle reading data in another\nway, you need not call the png_init_io() function, but you must then\nimplement the libpng I/O methods discussed in the Customizing Libpng\nsection below.\n\n    png_init_io(png_ptr, fp);\n\nIf you had previously opened the file and read any of the signature from\nthe beginning in order to see if this was a PNG file, you need to let\nlibpng know that there are some bytes missing from the start of the file.\n\n    png_set_sig_bytes(png_ptr, number);\n\nYou can change the zlib compression buffer size to be used while\nreading compressed data with\n\n    png_set_compression_buffer_size(png_ptr, buffer_size);\n\nwhere the default size is 8192 bytes.  Note that the buffer size\nis changed immediately and the buffer is reallocated immediately,\ninstead of setting a flag to be acted upon later.\n\nIf you want CRC errors to be handled in a different manner than\nthe default, use\n\n    png_set_crc_action(png_ptr, crit_action, ancil_action);\n\nThe values for png_set_crc_action() say how libpng is to handle CRC errors in\nancillary and critical chunks, and whether to use the data contained\ntherein.  Note that it is impossible to \"discard\" data in a critical\nchunk.\n\nChoices for (int) crit_action are\n   PNG_CRC_DEFAULT      0  error/quit\n   PNG_CRC_ERROR_QUIT   1  error/quit\n   PNG_CRC_WARN_USE     3  warn/use data\n   PNG_CRC_QUIET_USE    4  quiet/use data\n   PNG_CRC_NO_CHANGE    5  use the current value\n\nChoices for (int) ancil_action are\n   PNG_CRC_DEFAULT      0  error/quit\n   PNG_CRC_ERROR_QUIT   1  error/quit\n   PNG_CRC_WARN_DISCARD 2  warn/discard data\n   PNG_CRC_WARN_USE     3  warn/use data\n   PNG_CRC_QUIET_USE    4  quiet/use data\n   PNG_CRC_NO_CHANGE    5  use the current value\n\nSetting up callback code\n\nYou can set up a callback function to handle any unknown chunks in the\ninput stream. You must supply the function\n\n    read_chunk_callback(png_structp png_ptr,\n         png_unknown_chunkp chunk);\n    {\n       /* The unknown chunk structure contains your\n          chunk data, along with similar data for any other\n          unknown chunks: */\n\n           png_byte name[5];\n           png_byte *data;\n           png_size_t size;\n\n       /* Note that libpng has already taken care of\n          the CRC handling */\n\n       /* put your code here.  Search for your chunk in the\n          unknown chunk structure, process it, and return one\n          of the following: */\n\n       return (-n); /* chunk had an error */\n       return (0); /* did not recognize */\n       return (n); /* success */\n    }\n\n(You can give your function another name that you like instead of\n\"read_chunk_callback\")\n\nTo inform libpng about your function, use\n\n    png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr,\n        read_chunk_callback);\n\nThis names not only the callback function, but also a user pointer that\nyou can retrieve with\n\n    png_get_user_chunk_ptr(png_ptr);\n\nIf you call the png_set_read_user_chunk_fn() function, then all unknown\nchunks which the callback does not handle will be saved when read.  You can\ncause them to be discarded by returning '1' (\"handled\") instead of '0'.  This\nbehavior will change in libpng 1.7 and the default handling set by the\npng_set_keep_unknown_chunks() function, described below, will be used when the\ncallback returns 0.  If you want the existing behavior you should set the global\ndefault to PNG_HANDLE_CHUNK_IF_SAFE now; this is compatible with all current\nversions of libpng and with 1.7.  Libpng 1.6 issues a warning if you keep the\ndefault, or PNG_HANDLE_CHUNK_NEVER, and the callback returns 0.\n\nAt this point, you can set up a callback function that will be\ncalled after each row has been read, which you can use to control\na progress meter or the like.  It's demonstrated in pngtest.c.\nYou must supply a function\n\n    void read_row_callback(png_structp png_ptr,\n       png_uint_32 row, int pass);\n    {\n      /* put your code here */\n    }\n\n(You can give it another name that you like instead of \"read_row_callback\")\n\nTo inform libpng about your function, use\n\n    png_set_read_status_fn(png_ptr, read_row_callback);\n\nWhen this function is called the row has already been completely processed and\nthe 'row' and 'pass' refer to the next row to be handled.  For the\nnon-interlaced case the row that was just handled is simply one less than the\npassed in row number, and pass will always be 0.  For the interlaced case the\nsame applies unless the row value is 0, in which case the row just handled was\nthe last one from one of the preceding passes.  Because interlacing may skip a\npass you cannot be sure that the preceding pass is just 'pass-1', if you really\nneed to know what the last pass is record (row,pass) from the callback and use\nthe last recorded value each time.\n\nAs with the user transform you can find the output row using the\nPNG_ROW_FROM_PASS_ROW macro.\n\nUnknown-chunk handling\n\nNow you get to set the way the library processes unknown chunks in the\ninput PNG stream. Both known and unknown chunks will be read.  Normal\nbehavior is that known chunks will be parsed into information in\nvarious info_ptr members while unknown chunks will be discarded. This\nbehavior can be wasteful if your application will never use some known\nchunk types. To change this, you can call:\n\n    png_set_keep_unknown_chunks(png_ptr, keep,\n        chunk_list, num_chunks);\n\n    keep       - 0: default unknown chunk handling\n                 1: ignore; do not keep\n                 2: keep only if safe-to-copy\n                 3: keep even if unsafe-to-copy\n\n               You can use these definitions:\n                 PNG_HANDLE_CHUNK_AS_DEFAULT   0\n                 PNG_HANDLE_CHUNK_NEVER        1\n                 PNG_HANDLE_CHUNK_IF_SAFE      2\n                 PNG_HANDLE_CHUNK_ALWAYS       3\n\n    chunk_list - list of chunks affected (a byte string,\n                 five bytes per chunk, NULL or '\\0' if\n                 num_chunks is positive; ignored if\n                 numchunks <= 0).\n\n    num_chunks - number of chunks affected; if 0, all\n                 unknown chunks are affected.  If positive,\n                 only the chunks in the list are affected,\n                 and if negative all unknown chunks and\n                 all known chunks except for the IHDR,\n                 PLTE, tRNS, IDAT, and IEND chunks are\n                 affected.\n\nUnknown chunks declared in this way will be saved as raw data onto a\nlist of png_unknown_chunk structures.  If a chunk that is normally\nknown to libpng is named in the list, it will be handled as unknown,\naccording to the \"keep\" directive.  If a chunk is named in successive\ninstances of png_set_keep_unknown_chunks(), the final instance will\ntake precedence.  The IHDR and IEND chunks should not be named in\nchunk_list; if they are, libpng will process them normally anyway.\nIf you know that your application will never make use of some particular\nchunks, use PNG_HANDLE_CHUNK_NEVER (or 1) as demonstrated below.\n\nHere is an example of the usage of png_set_keep_unknown_chunks(),\nwhere the private \"vpAg\" chunk will later be processed by a user chunk\ncallback function:\n\n    png_byte vpAg[5]={118, 112,  65, 103, (png_byte) '\\0'};\n\n    #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)\n      png_byte unused_chunks[]=\n      {\n        104,  73,  83,  84, (png_byte) '\\0',   /* hIST */\n        105,  84,  88, 116, (png_byte) '\\0',   /* iTXt */\n        112,  67,  65,  76, (png_byte) '\\0',   /* pCAL */\n        115,  67,  65,  76, (png_byte) '\\0',   /* sCAL */\n        115,  80,  76,  84, (png_byte) '\\0',   /* sPLT */\n        116,  73,  77,  69, (png_byte) '\\0',   /* tIME */\n      };\n    #endif\n\n    ...\n\n    #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)\n      /* ignore all unknown chunks\n       * (use global setting \"2\" for libpng16 and earlier):\n       */\n      png_set_keep_unknown_chunks(read_ptr, 2, NULL, 0);\n\n      /* except for vpAg: */\n      png_set_keep_unknown_chunks(read_ptr, 2, vpAg, 1);\n\n      /* also ignore unused known chunks: */\n      png_set_keep_unknown_chunks(read_ptr, 1, unused_chunks,\n         (int)(sizeof unused_chunks)/5);\n    #endif\n\nUser limits\n\nThe PNG specification allows the width and height of an image to be as\nlarge as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns.\nFor safety, libpng imposes a default limit of 1 million rows and columns.\nLarger images will be rejected immediately with a png_error() call. If\nyou wish to change these limits, you can use\n\n   png_set_user_limits(png_ptr, width_max, height_max);\n\nto set your own limits (libpng may reject some very wide images\nanyway because of potential buffer overflow conditions).\n\nYou should put this statement after you create the PNG structure and\nbefore calling png_read_info(), png_read_png(), or png_process_data().\n\nWhen writing a PNG datastream, put this statement before calling\npng_write_info() or png_write_png().\n\nIf you need to retrieve the limits that are being applied, use\n\n   width_max = png_get_user_width_max(png_ptr);\n   height_max = png_get_user_height_max(png_ptr);\n\nThe PNG specification sets no limit on the number of ancillary chunks\nallowed in a PNG datastream.  By default, libpng imposes a limit of\na total of 1000 sPLT, tEXt, iTXt, zTXt, and unknown chunks to be stored.\nIf you have set up both info_ptr and end_info_ptr, the limit applies\nseparately to each.  You can change the limit on the total number of such\nchunks that will be stored, with\n\n   png_set_chunk_cache_max(png_ptr, user_chunk_cache_max);\n\nwhere 0x7fffffffL means unlimited.  You can retrieve this limit with\n\n   chunk_cache_max = png_get_chunk_cache_max(png_ptr);\n\nLibpng imposes a limit of 8 Megabytes (8,000,000 bytes) on the amount of\nmemory that a compressed chunk other than IDAT can occupy, when decompressed.\nYou can change this limit with\n\n   png_set_chunk_malloc_max(png_ptr, user_chunk_malloc_max);\n\nand you can retrieve the limit with\n\n   chunk_malloc_max = png_get_chunk_malloc_max(png_ptr);\n\nAny chunks that would cause either of these limits to be exceeded will\nbe ignored.\n\nInformation about your system\n\nIf you intend to display the PNG or to incorporate it in other image data you\nneed to tell libpng information about your display or drawing surface so that\nlibpng can convert the values in the image to match the display.\n\nFrom libpng-1.5.4 this information can be set before reading the PNG file\nheader.  In earlier versions png_set_gamma() existed but behaved incorrectly if\ncalled before the PNG file header had been read and png_set_alpha_mode() did not\nexist.\n\nIf you need to support versions prior to libpng-1.5.4 test the version number\nas illustrated below using \"PNG_LIBPNG_VER >= 10504\" and follow the procedures\ndescribed in the appropriate manual page.\n\nYou give libpng the encoding expected by your system expressed as a 'gamma'\nvalue.  You can also specify a default encoding for the PNG file in\ncase the required information is missing from the file.  By default libpng\nassumes that the PNG data matches your system, to keep this default call:\n\n   png_set_gamma(png_ptr, screen_gamma, output_gamma);\n\nor you can use the fixed point equivalent:\n\n   png_set_gamma_fixed(png_ptr, PNG_FP_1*screen_gamma,\n      PNG_FP_1*output_gamma);\n\nIf you don't know the gamma for your system it is probably 2.2 - a good\napproximation to the IEC standard for display systems (sRGB).  If images are\ntoo contrasty or washed out you got the value wrong - check your system\ndocumentation!\n\nMany systems permit the system gamma to be changed via a lookup table in the\ndisplay driver, a few systems, including older Macs, change the response by\ndefault.  As of 1.5.4 three special values are available to handle common\nsituations:\n\n   PNG_DEFAULT_sRGB: Indicates that the system conforms to the\n                     IEC 61966-2-1 standard.  This matches almost\n                     all systems.\n   PNG_GAMMA_MAC_18: Indicates that the system is an older\n                     (pre Mac OS 10.6) Apple Macintosh system with\n                     the default settings.\n   PNG_GAMMA_LINEAR: Just the fixed point value for 1.0 - indicates\n                     that the system expects data with no gamma\n                     encoding.\n\nYou would use the linear (unencoded) value if you need to process the pixel\nvalues further because this avoids the need to decode and re-encode each\ncomponent value whenever arithmetic is performed.  A lot of graphics software\nuses linear values for this reason, often with higher precision component values\nto preserve overall accuracy.\n\n\nThe output_gamma value expresses how to decode the output values, not how\nthey are encoded.  The values used correspond to the normal numbers used to\ndescribe the overall gamma of a computer display system; for example 2.2 for\nan sRGB conformant system.  The values are scaled by 100000 in the _fixed\nversion of the API (so 220000 for sRGB.)\n\nThe inverse of the value is always used to provide a default for the PNG file\nencoding if it has no gAMA chunk and if png_set_gamma() has not been called\nto override the PNG gamma information.\n\nWhen the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode\nopaque pixels however pixels with lower alpha values are not encoded,\nregardless of the output gamma setting.\n\nWhen the standard Porter Duff handling is requested with mode 1 the output\nencoding is set to be linear and the output_gamma value is only relevant\nas a default for input data that has no gamma information.  The linear output\nencoding will be overridden if png_set_gamma() is called - the results may be\nhighly unexpected!\n\nThe following numbers are derived from the sRGB standard and the research\nbehind it.  sRGB is defined to be approximated by a PNG gAMA chunk value of\n0.45455 (1/2.2) for PNG.  The value implicitly includes any viewing\ncorrection required to take account of any differences in the color\nenvironment of the original scene and the intended display environment; the\nvalue expresses how to *decode* the image for display, not how the original\ndata was *encoded*.\n\nsRGB provides a peg for the PNG standard by defining a viewing environment.\nsRGB itself, and earlier TV standards, actually use a more complex transform\n(a linear portion then a gamma 2.4 power law) than PNG can express.  (PNG is\nlimited to simple power laws.)  By saying that an image for direct display on\nan sRGB conformant system should be stored with a gAMA chunk value of 45455\n(11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification\nmakes it possible to derive values for other display systems and\nenvironments.\n\nThe Mac value is deduced from the sRGB based on an assumption that the actual\nextra viewing correction used in early Mac display systems was implemented as\na power 1.45 lookup table.\n\nAny system where a programmable lookup table is used or where the behavior of\nthe final display device characteristics can be changed requires system\nspecific code to obtain the current characteristic.  However this can be\ndifficult and most PNG gamma correction only requires an approximate value.\n\nBy default, if png_set_alpha_mode() is not called, libpng assumes that all\nvalues are unencoded, linear, values and that the output device also has a\nlinear characteristic.  This is only very rarely correct - it is invariably\nbetter to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the\ndefault if you don't know what the right answer is!\n\nThe special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS\n10.6) which used a correction table to implement a somewhat lower gamma on an\notherwise sRGB system.\n\nBoth these values are reserved (not simple gamma values) in order to allow\nmore precise correction internally in the future.\n\nNOTE: the values can be passed to either the fixed or floating\npoint APIs, but the floating point API will also accept floating point\nvalues.\n\nThe second thing you may need to tell libpng about is how your system handles\nalpha channel information.  Some, but not all, PNG files contain an alpha\nchannel.  To display these files correctly you need to compose the data onto a\nsuitable background, as described in the PNG specification.\n\nLibpng only supports composing onto a single color (using png_set_background;\nsee below).  Otherwise you must do the composition yourself and, in this case,\nyou may need to call png_set_alpha_mode:\n\n   #if PNG_LIBPNG_VER >= 10504\n      png_set_alpha_mode(png_ptr, mode, screen_gamma);\n   #else\n      png_set_gamma(png_ptr, screen_gamma, 1.0/screen_gamma);\n   #endif\n\nThe screen_gamma value is the same as the argument to png_set_gamma; however,\nhow it affects the output depends on the mode.  png_set_alpha_mode() sets the\nfile gamma default to 1/screen_gamma, so normally you don't need to call\npng_set_gamma.  If you need different defaults call png_set_gamma() before\npng_set_alpha_mode() - if you call it after it will override the settings made\nby png_set_alpha_mode().\n\nThe mode is as follows:\n\n    PNG_ALPHA_PNG: The data is encoded according to the PNG\nspecification.  Red, green and blue, or gray, components are\ngamma encoded color values and are not premultiplied by the\nalpha value.  The alpha value is a linear measure of the\ncontribution of the pixel to the corresponding final output pixel.\n\nYou should normally use this format if you intend to perform\ncolor correction on the color values; most, maybe all, color\ncorrection software has no handling for the alpha channel and,\nanyway, the math to handle pre-multiplied component values is\nunnecessarily complex.\n\nBefore you do any arithmetic on the component values you need\nto remove the gamma encoding and multiply out the alpha\nchannel.  See the PNG specification for more detail.  It is\nimportant to note that when an image with an alpha channel is\nscaled, linear encoded, pre-multiplied component values must\nbe used!\n\nThe remaining modes assume you don't need to do any further color correction or\nthat if you do, your color correction software knows all about alpha (it\nprobably doesn't!).  They 'associate' the alpha with the color information by\nstoring color channel values that have been scaled by the alpha.  The\nadvantage is that the color channels can be resampled (the image can be\nscaled) in this form.  The disadvantage is that normal practice is to store\nlinear, not (gamma) encoded, values and this requires 16-bit channels for\nstill images rather than the 8-bit channels that are just about sufficient if\ngamma encoding is used.  In addition all non-transparent pixel values,\nincluding completely opaque ones, must be gamma encoded to produce the final\nimage.  These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes\ndescribed below (the latter being the two common names for associated alpha\ncolor channels). Note that PNG files always contain non-associated color\nchannels; png_set_alpha_mode() with one of the modes causes the decoder to\nconvert the pixels to an associated form before returning them to your\napplication. \n\nSince it is not necessary to perform arithmetic on opaque color values so\nlong as they are not to be resampled and are in the final color space it is\npossible to optimize the handling of alpha by storing the opaque pixels in\nthe PNG format (adjusted for the output color space) while storing partially\nopaque pixels in the standard, linear, format.  The accuracy required for\nstandard alpha composition is relatively low, because the pixels are\nisolated, therefore typically the accuracy loss in storing 8-bit linear\nvalues is acceptable.  (This is not true if the alpha channel is used to\nsimulate transparency over large areas - use 16 bits or the PNG mode in\nthis case!)  This is the 'OPTIMIZED' mode.  For this mode a pixel is\ntreated as opaque only if the alpha value is equal to the maximum value.\n\n    PNG_ALPHA_STANDARD:  The data libpng produces is encoded in the\nstandard way assumed by most correctly written graphics software.\nThe gamma encoding will be removed by libpng and the\nlinear component values will be pre-multiplied by the\nalpha channel.\n\nWith this format the final image must be re-encoded to\nmatch the display gamma before the image is displayed.\nIf your system doesn't do that, yet still seems to\nperform arithmetic on the pixels without decoding them,\nit is broken - check out the modes below.\n\nWith PNG_ALPHA_STANDARD libpng always produces linear\ncomponent values, whatever screen_gamma you supply.  The\nscreen_gamma value is, however, used as a default for\nthe file gamma if the PNG file has no gamma information.\n\nIf you call png_set_gamma() after png_set_alpha_mode() you\nwill override the linear encoding.  Instead the\npre-multiplied pixel values will be gamma encoded but\nthe alpha channel will still be linear.  This may\nactually match the requirements of some broken software,\nbut it is unlikely.\n\nWhile linear 8-bit data is often used it has\ninsufficient precision for any image with a reasonable\ndynamic range.  To avoid problems, and if your software\nsupports it, use png_set_expand_16() to force all\ncomponents to 16 bits.\n\n    PNG_ALPHA_OPTIMIZED: This mode is the same as PNG_ALPHA_STANDARD\nexcept that completely opaque pixels are gamma encoded according to\nthe screen_gamma value.  Pixels with alpha less than 1.0\nwill still have linear components.\n\nUse this format if you have control over your\ncompositing software and so don't do other arithmetic\n(such as scaling) on the data you get from libpng.  Your\ncompositing software can simply copy opaque pixels to\nthe output but still has linear values for the\nnon-opaque pixels.\n\nIn normal compositing, where the alpha channel encodes\npartial pixel coverage (as opposed to broad area\ntranslucency), the inaccuracies of the 8-bit\nrepresentation of non-opaque pixels are irrelevant.\n\nYou can also try this format if your software is broken;\nit might look better.\n\n    PNG_ALPHA_BROKEN: This is PNG_ALPHA_STANDARD; however, all component\nvalues, including the alpha channel are gamma encoded.  This is\nbroken because, in practice, no implementation that uses this choice\ncorrectly undoes the encoding before handling alpha composition.  Use this\nchoice only if other serious errors in the software or hardware you use\nmandate it.  In most cases of broken software or hardware the bug in the\nfinal display manifests as a subtle halo around composited parts of the\nimage.  You may not even perceive this as a halo; the composited part of\nthe image may simply appear separate from the background, as though it had\nbeen cut out of paper and pasted on afterward.\n\nIf you don't have to deal with bugs in software or hardware, or if you can fix\nthem, there are three recommended ways of using png_set_alpha_mode():\n\n   png_set_alpha_mode(png_ptr, PNG_ALPHA_PNG,\n       screen_gamma);\n\nYou can do color correction on the result (libpng does not currently\nsupport color correction internally).  When you handle the alpha channel\nyou need to undo the gamma encoding and multiply out the alpha.\n\n   png_set_alpha_mode(png_ptr, PNG_ALPHA_STANDARD,\n       screen_gamma);\n   png_set_expand_16(png_ptr);\n\nIf you are using the high level interface, don't call png_set_expand_16();\ninstead pass PNG_TRANSFORM_EXPAND_16 to the interface.\n\nWith this mode you can't do color correction, but you can do arithmetic,\nincluding composition and scaling, on the data without further processing.\n\n   png_set_alpha_mode(png_ptr, PNG_ALPHA_OPTIMIZED,\n       screen_gamma);\n\nYou can avoid the expansion to 16-bit components with this mode, but you\nlose the ability to scale the image or perform other linear arithmetic.\nAll you can do is compose the result onto a matching output.  Since this\nmode is libpng-specific you also need to write your own composition\nsoftware.\n\nThe following are examples of calls to png_set_alpha_mode to achieve the\nrequired overall gamma correction and, where necessary, alpha\npremultiplication.\n\n    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);\n\nThis is the default libpng handling of the alpha channel - it is not\npre-multiplied into the color components.  In addition the call states\nthat the output is for a sRGB system and causes all PNG files without gAMA\nchunks to be assumed to be encoded using sRGB.\n\n    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);\n\nIn this case the output is assumed to be something like an sRGB conformant\ndisplay preceeded by a power-law lookup table of power 1.45.  This is how\nearly Mac systems behaved.\n\n    png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);\n\nThis is the classic Jim Blinn approach and will work in academic\nenvironments where everything is done by the book.  It has the shortcoming\nof assuming that input PNG data with no gamma information is linear - this\nis unlikely to be correct unless the PNG files where generated locally.\nMost of the time the output precision will be so low as to show\nsignificant banding in dark areas of the image.\n\n    png_set_expand_16(pp);\n    png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB);\n\nThis is a somewhat more realistic Jim Blinn inspired approach.  PNG files\nare assumed to have the sRGB encoding if not marked with a gamma value and\nthe output is always 16 bits per component.  This permits accurate scaling\nand processing of the data.  If you know that your input PNG files were\ngenerated locally you might need to replace PNG_DEFAULT_sRGB with the\ncorrect value for your system.\n\n    png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);\n\nIf you just need to composite the PNG image onto an existing background\nand if you control the code that does this you can use the optimization\nsetting.  In this case you just copy completely opaque pixels to the\noutput.  For pixels that are not completely transparent (you just skip\nthose) you do the composition math using png_composite or png_composite_16\nbelow then encode the resultant 8-bit or 16-bit values to match the output\nencoding.\n\n    Other cases\n\nIf neither the PNG nor the standard linear encoding work for you because\nof the software or hardware you use then you have a big problem.  The PNG\ncase will probably result in halos around the image.  The linear encoding\nwill probably result in a washed out, too bright, image (it's actually too\ncontrasty.)  Try the ALPHA_OPTIMIZED mode above - this will probably\nsubstantially reduce the halos.  Alternatively try:\n\n    png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB);\n\nThis option will also reduce the halos, but there will be slight dark\nhalos round the opaque parts of the image where the background is light.\nIn the OPTIMIZED mode the halos will be light halos where the background\nis dark.  Take your pick - the halos are unavoidable unless you can get\nyour hardware/software fixed!  (The OPTIMIZED approach is slightly\nfaster.)\n\nWhen the default gamma of PNG files doesn't match the output gamma.\nIf you have PNG files with no gamma information png_set_alpha_mode allows\nyou to provide a default gamma, but it also sets the ouput gamma to the\nmatching value.  If you know your PNG files have a gamma that doesn't\nmatch the output you can take advantage of the fact that\npng_set_alpha_mode always sets the output gamma but only sets the PNG\ndefault if it is not already set:\n\n    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);\n    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);\n\nThe first call sets both the default and the output gamma values, the\nsecond call overrides the output gamma without changing the default.  This\nis easier than achieving the same effect with png_set_gamma.  You must use\nPNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will\nfire if more than one call to png_set_alpha_mode and png_set_background is\nmade in the same read operation, however multiple calls with PNG_ALPHA_PNG\nare ignored.\n\nIf you don't need, or can't handle, the alpha channel you can call\npng_set_background() to remove it by compositing against a fixed color.  Don't\ncall png_set_strip_alpha() to do this - it will leave spurious pixel values in\ntransparent parts of this image.\n\n   png_set_background(png_ptr, &background_color,\n       PNG_BACKGROUND_GAMMA_SCREEN, 0, 1);\n\nThe background_color is an RGB or grayscale value according to the data format\nlibpng will produce for you.  Because you don't yet know the format of the PNG\nfile, if you call png_set_background at this point you must arrange for the\nformat produced by libpng to always have 8-bit or 16-bit components and then\nstore the color as an 8-bit or 16-bit color as appropriate.  The color contains\nseparate gray and RGB component values, so you can let libpng produce gray or\nRGB output according to the input format, but low bit depth grayscale images\nmust always be converted to at least 8-bit format.  (Even though low bit depth\ngrayscale images can't have an alpha channel they can have a transparent\ncolor!)\n\nYou set the transforms you need later, either as flags to the high level\ninterface or libpng API calls for the low level interface.  For reference the\nsettings and API calls required are:\n\n8-bit values:\n   PNG_TRANSFORM_SCALE_16 | PNG_EXPAND\n   png_set_expand(png_ptr); png_set_scale_16(png_ptr);\n\n   If you must get exactly the same inaccurate results\n   produced by default in versions prior to libpng-1.5.4,\n   use PNG_TRANSFORM_STRIP_16 and png_set_strip_16(png_ptr)\n   instead.\n\n16-bit values:\n   PNG_TRANSFORM_EXPAND_16\n   png_set_expand_16(png_ptr);\n\nIn either case palette image data will be expanded to RGB.  If you just want\ncolor data you can add PNG_TRANSFORM_GRAY_TO_RGB or png_set_gray_to_rgb(png_ptr)\nto the list.\n\nCalling png_set_background before the PNG file header is read will not work\nprior to libpng-1.5.4.  Because the failure may result in unexpected warnings or\nerrors it is therefore much safer to call png_set_background after the head has\nbeen read.  Unfortunately this means that prior to libpng-1.5.4 it cannot be\nused with the high level interface.\n\nThe high-level read interface\n\nAt this point there are two ways to proceed; through the high-level\nread interface, or through a sequence of low-level read operations.\nYou can use the high-level interface if (a) you are willing to read\nthe entire image into memory, and (b) the input transformations\nyou want to do are limited to the following set:\n\n    PNG_TRANSFORM_IDENTITY      No transformation\n    PNG_TRANSFORM_SCALE_16      Strip 16-bit samples to\n                                8-bit accurately\n    PNG_TRANSFORM_STRIP_16      Chop 16-bit samples to\n                                8-bit less accurately\n    PNG_TRANSFORM_STRIP_ALPHA   Discard the alpha channel\n    PNG_TRANSFORM_PACKING       Expand 1, 2 and 4-bit\n                                samples to bytes\n    PNG_TRANSFORM_PACKSWAP      Change order of packed\n                                pixels to LSB first\n    PNG_TRANSFORM_EXPAND        Perform set_expand()\n    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images\n    PNG_TRANSFORM_SHIFT         Normalize pixels to the\n                                sBIT depth\n    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA\n                                to BGRA\n    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA\n                                to AG\n    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity\n                                to transparency\n    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples\n    PNG_TRANSFORM_GRAY_TO_RGB   Expand grayscale samples\n                                to RGB (or GA to RGBA)\n    PNG_TRANSFORM_EXPAND_16     Expand samples to 16 bits\n\n(This excludes setting a background color, doing gamma transformation,\nquantizing, and setting filler.)  If this is the case, simply do this:\n\n    png_read_png(png_ptr, info_ptr, png_transforms, NULL)\n\nwhere png_transforms is an integer containing the bitwise OR of some\nset of transformation flags.  This call is equivalent to png_read_info(),\nfollowed the set of transformations indicated by the transform mask,\nthen png_read_image(), and finally png_read_end().\n\n(The final parameter of this call is not yet used.  Someday it might point\nto transformation parameters required by some future input transform.)\n\nYou must use png_transforms and not call any png_set_transform() functions\nwhen you use png_read_png().\n\nAfter you have called png_read_png(), you can retrieve the image data\nwith\n\n   row_pointers = png_get_rows(png_ptr, info_ptr);\n\nwhere row_pointers is an array of pointers to the pixel data for each row:\n\n   png_bytep row_pointers[height];\n\nIf you know your image size and pixel size ahead of time, you can allocate\nrow_pointers prior to calling png_read_png() with\n\n   if (height > PNG_UINT_32_MAX/(sizeof (png_byte)))\n      png_error (png_ptr,\n          \"Image is too tall to process in memory\");\n\n   if (width > PNG_UINT_32_MAX/pixel_size)\n      png_error (png_ptr,\n          \"Image is too wide to process in memory\");\n\n   row_pointers = png_malloc(png_ptr,\n       height*(sizeof (png_bytep)));\n\n   for (int i=0; i<height, i++)\n      row_pointers[i]=NULL;  /* security precaution */\n\n   for (int i=0; i<height, i++)\n      row_pointers[i]=png_malloc(png_ptr,\n          width*pixel_size);\n\n   png_set_rows(png_ptr, info_ptr, &row_pointers);\n\nAlternatively you could allocate your image in one big block and define\nrow_pointers[i] to point into the proper places in your block.\n\nIf you use png_set_rows(), the application is responsible for freeing\nrow_pointers (and row_pointers[i], if they were separately allocated).\n\nIf you don't allocate row_pointers ahead of time, png_read_png() will\ndo it, and it'll be free'ed by libpng when you call png_destroy_*().\n\nThe low-level read interface\n\nIf you are going the low-level route, you are now ready to read all\nthe file information up to the actual image data.  You do this with a\ncall to png_read_info().\n\n    png_read_info(png_ptr, info_ptr);\n\nThis will process all chunks up to but not including the image data.\n\nThis also copies some of the data from the PNG file into the decode structure\nfor use in later transformations.  Important information copied in is:\n\n1) The PNG file gamma from the gAMA chunk.  This overwrites the default value\nprovided by an earlier call to png_set_gamma or png_set_alpha_mode.\n\n2) Prior to libpng-1.5.4 the background color from a bKGd chunk.  This\ndamages the information provided by an earlier call to png_set_background\nresulting in unexpected behavior.  Libpng-1.5.4 no longer does this.\n\n3) The number of significant bits in each component value.  Libpng uses this to\noptimize gamma handling by reducing the internal lookup table sizes.\n\n4) The transparent color information from a tRNS chunk.  This can be modified by\na later call to png_set_tRNS.\n\nQuerying the info structure\n\nFunctions are used to get the information from the info_ptr once it\nhas been read.  Note that these fields may not be completely filled\nin until png_read_end() has read the chunk data following the image.\n\n    png_get_IHDR(png_ptr, info_ptr, &width, &height,\n       &bit_depth, &color_type, &interlace_type,\n       &compression_type, &filter_method);\n\n    width          - holds the width of the image\n                     in pixels (up to 2^31).\n\n    height         - holds the height of the image\n                     in pixels (up to 2^31).\n\n    bit_depth      - holds the bit depth of one of the\n                     image channels.  (valid values are\n                     1, 2, 4, 8, 16 and depend also on\n                     the color_type.  See also\n                     significant bits (sBIT) below).\n\n    color_type     - describes which color/alpha channels\n                         are present.\n                     PNG_COLOR_TYPE_GRAY\n                        (bit depths 1, 2, 4, 8, 16)\n                     PNG_COLOR_TYPE_GRAY_ALPHA\n                        (bit depths 8, 16)\n                     PNG_COLOR_TYPE_PALETTE\n                        (bit depths 1, 2, 4, 8)\n                     PNG_COLOR_TYPE_RGB\n                        (bit_depths 8, 16)\n                     PNG_COLOR_TYPE_RGB_ALPHA\n                        (bit_depths 8, 16)\n\n                     PNG_COLOR_MASK_PALETTE\n                     PNG_COLOR_MASK_COLOR\n                     PNG_COLOR_MASK_ALPHA\n\n    interlace_type - (PNG_INTERLACE_NONE or\n                     PNG_INTERLACE_ADAM7)\n\n    compression_type - (must be PNG_COMPRESSION_TYPE_BASE\n                     for PNG 1.0)\n\n    filter_method  - (must be PNG_FILTER_TYPE_BASE\n                     for PNG 1.0, and can also be\n                     PNG_INTRAPIXEL_DIFFERENCING if\n                     the PNG datastream is embedded in\n                     a MNG-1.0 datastream)\n\n    Any of width, height, color_type, bit_depth,\n    interlace_type, compression_type, or filter_method can\n    be NULL if you are not interested in their values.\n\n    Note that png_get_IHDR() returns 32-bit data into\n    the application's width and height variables.\n    This is an unsafe situation if these are not png_uint_32\n    variables.  In such situations, the\n    png_get_image_width() and png_get_image_height()\n    functions described below are safer.\n\n    width            = png_get_image_width(png_ptr,\n                         info_ptr);\n\n    height           = png_get_image_height(png_ptr,\n                         info_ptr);\n\n    bit_depth        = png_get_bit_depth(png_ptr,\n                         info_ptr);\n\n    color_type       = png_get_color_type(png_ptr,\n                         info_ptr);\n\n    interlace_type   = png_get_interlace_type(png_ptr,\n                         info_ptr);\n\n    compression_type = png_get_compression_type(png_ptr,\n                         info_ptr);\n\n    filter_method    = png_get_filter_type(png_ptr,\n                         info_ptr);\n\n    channels = png_get_channels(png_ptr, info_ptr);\n\n    channels       - number of channels of info for the\n                     color type (valid values are 1 (GRAY,\n                     PALETTE), 2 (GRAY_ALPHA), 3 (RGB),\n                     4 (RGB_ALPHA or RGB + filler byte))\n\n    rowbytes = png_get_rowbytes(png_ptr, info_ptr);\n\n    rowbytes       - number of bytes needed to hold a row\n\n    signature = png_get_signature(png_ptr, info_ptr);\n\n    signature      - holds the signature read from the\n                     file (if any).  The data is kept in\n                     the same offset it would be if the\n                     whole signature were read (i.e. if an\n                     application had already read in 4\n                     bytes of signature before starting\n                     libpng, the remaining 4 bytes would\n                     be in signature[4] through signature[7]\n                     (see png_set_sig_bytes())).\n\nThese are also important, but their validity depends on whether the chunk\nhas been read.  The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and\npng_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the\ndata has been read, or zero if it is missing.  The parameters to the\npng_get_<chunk> are set directly if they are simple data types, or a\npointer into the info_ptr is returned for any complex types.\n\nThe colorspace data from gAMA, cHRM, sRGB, iCCP, and sBIT chunks\nis simply returned to give the application information about how the\nimage was encoded.  Libpng itself only does transformations using the file\ngamma when combining semitransparent pixels with the background color, and,\nsince libpng-1.6.0, when converting between 8-bit sRGB and 16-bit linear pixels\nwithin the simplified API.  Libpng also uses the file gamma when converting\nRGB to gray, beginning with libpng-1.0.5, if the application calls\npng_set_rgb_to_gray()).\n\n    png_get_PLTE(png_ptr, info_ptr, &palette,\n                     &num_palette);\n\n    palette        - the palette for the file\n                     (array of png_color)\n\n    num_palette    - number of entries in the palette\n\n    png_get_gAMA(png_ptr, info_ptr, &file_gamma);\n    png_get_gAMA_fixed(png_ptr, info_ptr, &int_file_gamma);\n\n    file_gamma     - the gamma at which the file is\n                     written (PNG_INFO_gAMA)\n\n    int_file_gamma - 100,000 times the gamma at which the\n                     file is written\n\n    png_get_cHRM(png_ptr, info_ptr,  &white_x, &white_y, &red_x,\n                     &red_y, &green_x, &green_y, &blue_x, &blue_y)\n    png_get_cHRM_XYZ(png_ptr, info_ptr, &red_X, &red_Y, &red_Z,\n                     &green_X, &green_Y, &green_Z, &blue_X, &blue_Y,\n                     &blue_Z)\n    png_get_cHRM_fixed(png_ptr, info_ptr, &int_white_x,\n                     &int_white_y, &int_red_x, &int_red_y,\n                     &int_green_x, &int_green_y, &int_blue_x,\n                     &int_blue_y)\n    png_get_cHRM_XYZ_fixed(png_ptr, info_ptr, &int_red_X, &int_red_Y,\n                     &int_red_Z, &int_green_X, &int_green_Y,\n                     &int_green_Z, &int_blue_X, &int_blue_Y,\n                     &int_blue_Z)\n\n    {white,red,green,blue}_{x,y}\n                     A color space encoding specified using the\n                     chromaticities of the end points and the\n                     white point. (PNG_INFO_cHRM)\n\n    {red,green,blue}_{X,Y,Z}\n                     A color space encoding specified using the\n                     encoding end points - the CIE tristimulus\n                     specification of the intended color of the red,\n                     green and blue channels in the PNG RGB data.\n                     The white point is simply the sum of the three\n                     end points. (PNG_INFO_cHRM)\n\n    png_get_sRGB(png_ptr, info_ptr, &srgb_intent);\n\n    srgb_intent -    the rendering intent (PNG_INFO_sRGB)\n                     The presence of the sRGB chunk\n                     means that the pixel data is in the\n                     sRGB color space.  This chunk also\n                     implies specific values of gAMA and\n                     cHRM.\n\n    png_get_iCCP(png_ptr, info_ptr, &name,\n       &compression_type, &profile, &proflen);\n\n    name             - The profile name.\n\n    compression_type - The compression type; always\n                       PNG_COMPRESSION_TYPE_BASE for PNG 1.0.\n                       You may give NULL to this argument to\n                       ignore it.\n\n    profile          - International Color Consortium color\n                       profile data. May contain NULs.\n\n    proflen          - length of profile data in bytes.\n\n    png_get_sBIT(png_ptr, info_ptr, &sig_bit);\n\n    sig_bit        - the number of significant bits for\n                     (PNG_INFO_sBIT) each of the gray,\n                     red, green, and blue channels,\n                     whichever are appropriate for the\n                     given color type (png_color_16)\n\n    png_get_tRNS(png_ptr, info_ptr, &trans_alpha,\n                     &num_trans, &trans_color);\n\n    trans_alpha    - array of alpha (transparency)\n                     entries for palette (PNG_INFO_tRNS)\n\n    num_trans      - number of transparent entries\n                     (PNG_INFO_tRNS)\n\n    trans_color    - graylevel or color sample values of\n                     the single transparent color for\n                     non-paletted images (PNG_INFO_tRNS)\n\n    png_get_hIST(png_ptr, info_ptr, &hist);\n                     (PNG_INFO_hIST)\n\n    hist           - histogram of palette (array of\n                     png_uint_16)\n\n    png_get_tIME(png_ptr, info_ptr, &mod_time);\n\n    mod_time       - time image was last modified\n                    (PNG_VALID_tIME)\n\n    png_get_bKGD(png_ptr, info_ptr, &background);\n\n    background     - background color (of type\n                     png_color_16p) (PNG_VALID_bKGD)\n                     valid 16-bit red, green and blue\n                     values, regardless of color_type\n\n    num_comments   = png_get_text(png_ptr, info_ptr,\n                     &text_ptr, &num_text);\n\n    num_comments   - number of comments\n\n    text_ptr       - array of png_text holding image\n                     comments\n\n    text_ptr[i].compression - type of compression used\n                 on \"text\" PNG_TEXT_COMPRESSION_NONE\n                           PNG_TEXT_COMPRESSION_zTXt\n                           PNG_ITXT_COMPRESSION_NONE\n                           PNG_ITXT_COMPRESSION_zTXt\n\n    text_ptr[i].key   - keyword for comment.  Must contain\n                         1-79 characters.\n\n    text_ptr[i].text  - text comments for current\n                         keyword.  Can be empty.\n\n    text_ptr[i].text_length - length of text string,\n                 after decompression, 0 for iTXt\n\n    text_ptr[i].itxt_length - length of itxt string,\n                 after decompression, 0 for tEXt/zTXt\n\n    text_ptr[i].lang  - language of comment (empty\n                         string for unknown).\n\n    text_ptr[i].lang_key  - keyword in UTF-8\n                         (empty string for unknown).\n\n    Note that the itxt_length, lang, and lang_key\n    members of the text_ptr structure only exist when the\n    library is built with iTXt chunk support.  Prior to\n    libpng-1.4.0 the library was built by default without\n    iTXt support. Also note that when iTXt is supported,\n    they contain NULL pointers when the \"compression\"\n    field contains PNG_TEXT_COMPRESSION_NONE or\n    PNG_TEXT_COMPRESSION_zTXt.\n\n    num_text       - number of comments (same as\n                     num_comments; you can put NULL here\n                     to avoid the duplication)\n\n    Note while png_set_text() will accept text, language,\n    and translated keywords that can be NULL pointers, the\n    structure returned by png_get_text will always contain\n    regular zero-terminated C strings.  They might be\n    empty strings but they will never be NULL pointers.\n\n    num_spalettes = png_get_sPLT(png_ptr, info_ptr,\n       &palette_ptr);\n\n    num_spalettes  - number of sPLT chunks read.\n\n    palette_ptr    - array of palette structures holding\n                     contents of one or more sPLT chunks\n                     read.\n\n    png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,\n       &unit_type);\n\n    offset_x       - positive offset from the left edge\n                     of the screen (can be negative)\n\n    offset_y       - positive offset from the top edge\n                     of the screen (can be negative)\n\n    unit_type      - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER\n\n    png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y,\n       &unit_type);\n\n    res_x          - pixels/unit physical resolution in\n                     x direction\n\n    res_y          - pixels/unit physical resolution in\n                     x direction\n\n    unit_type      - PNG_RESOLUTION_UNKNOWN,\n                     PNG_RESOLUTION_METER\n\n    png_get_sCAL(png_ptr, info_ptr, &unit, &width,\n       &height)\n\n    unit        - physical scale units (an integer)\n\n    width       - width of a pixel in physical scale units\n\n    height      - height of a pixel in physical scale units\n                 (width and height are doubles)\n\n    png_get_sCAL_s(png_ptr, info_ptr, &unit, &width,\n       &height)\n\n    unit        - physical scale units (an integer)\n\n    width       - width of a pixel in physical scale units\n                  (expressed as a string)\n\n    height      - height of a pixel in physical scale units\n                 (width and height are strings like \"2.54\")\n\n    num_unknown_chunks = png_get_unknown_chunks(png_ptr,\n       info_ptr, &unknowns)\n\n    unknowns          - array of png_unknown_chunk\n                        structures holding unknown chunks\n\n    unknowns[i].name  - name of unknown chunk\n\n    unknowns[i].data  - data of unknown chunk\n\n    unknowns[i].size  - size of unknown chunk's data\n\n    unknowns[i].location - position of chunk in file\n\n    The value of \"i\" corresponds to the order in which the\n    chunks were read from the PNG file or inserted with the\n    png_set_unknown_chunks() function.\n\n    The value of \"location\" is a bitwise \"or\" of\n\n         PNG_HAVE_IHDR  (0x01)\n         PNG_HAVE_PLTE  (0x02)\n         PNG_AFTER_IDAT (0x08)\n\nThe data from the pHYs chunk can be retrieved in several convenient\nforms:\n\n    res_x = png_get_x_pixels_per_meter(png_ptr,\n       info_ptr)\n\n    res_y = png_get_y_pixels_per_meter(png_ptr,\n       info_ptr)\n\n    res_x_and_y = png_get_pixels_per_meter(png_ptr,\n       info_ptr)\n\n    res_x = png_get_x_pixels_per_inch(png_ptr,\n       info_ptr)\n\n    res_y = png_get_y_pixels_per_inch(png_ptr,\n       info_ptr)\n\n    res_x_and_y = png_get_pixels_per_inch(png_ptr,\n       info_ptr)\n\n    aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,\n       info_ptr)\n\n    Each of these returns 0 [signifying \"unknown\"] if\n       the data is not present or if res_x is 0;\n       res_x_and_y is 0 if res_x != res_y\n\n    Note that because of the way the resolutions are\n       stored internally, the inch conversions won't\n       come out to exactly even number.  For example,\n       72 dpi is stored as 0.28346 pixels/meter, and\n       when this is retrieved it is 71.9988 dpi, so\n       be sure to round the returned value appropriately\n       if you want to display a reasonable-looking result.\n\nThe data from the oFFs chunk can be retrieved in several convenient\nforms:\n\n    x_offset = png_get_x_offset_microns(png_ptr, info_ptr);\n\n    y_offset = png_get_y_offset_microns(png_ptr, info_ptr);\n\n    x_offset = png_get_x_offset_inches(png_ptr, info_ptr);\n\n    y_offset = png_get_y_offset_inches(png_ptr, info_ptr);\n\n    Each of these returns 0 [signifying \"unknown\" if both\n       x and y are 0] if the data is not present or if the\n       chunk is present but the unit is the pixel.  The\n       remark about inexact inch conversions applies here\n       as well, because a value in inches can't always be\n       converted to microns and back without some loss\n       of precision.\n\nFor more information, see the\nPNG specification for chunk contents.  Be careful with trusting\nrowbytes, as some of the transformations could increase the space\nneeded to hold a row (expand, filler, gray_to_rgb, etc.).\nSee png_read_update_info(), below.\n\nA quick word about text_ptr and num_text.  PNG stores comments in\nkeyword/text pairs, one pair per chunk, with no limit on the number\nof text chunks, and a 2^31 byte limit on their size.  While there are\nsuggested keywords, there is no requirement to restrict the use to these\nstrings.  It is strongly suggested that keywords and text be sensible\nto humans (that's the point), so don't use abbreviations.  Non-printing\nsymbols are not allowed.  See the PNG specification for more details.\nThere is also no requirement to have text after the keyword.\n\nKeywords should be limited to 79 Latin-1 characters without leading or\ntrailing spaces, but non-consecutive spaces are allowed within the\nkeyword.  It is possible to have the same keyword any number of times.\nThe text_ptr is an array of png_text structures, each holding a\npointer to a language string, a pointer to a keyword and a pointer to\na text string.  The text string, language code, and translated\nkeyword may be empty or NULL pointers.  The keyword/text\npairs are put into the array in the order that they are received.\nHowever, some or all of the text chunks may be after the image, so, to\nmake sure you have read all the text chunks, don't mess with these\nuntil after you read the stuff after the image.  This will be\nmentioned again below in the discussion that goes with png_read_end().\n\nInput transformations\n\nAfter you've read the header information, you can set up the library\nto handle any special transformations of the image data.  The various\nways to transform the data will be described in the order that they\nshould occur.  This is important, as some of these change the color\ntype and/or bit depth of the data, and some others only work on\ncertain color types and bit depths.\n\nTransformations you request are ignored if they don't have any meaning for a\nparticular input data format.  However some transformations can have an effect\nas a result of a previous transformation.  If you specify a contradictory set of\ntransformations, for example both adding and removing the alpha channel, you\ncannot predict the final result.\n\nThe color used for the transparency values should be supplied in the same\nformat/depth as the current image data.  It is stored in the same format/depth\nas the image data in a tRNS chunk, so this is what libpng expects for this data.\n\nThe color used for the background value depends on the need_expand argument as\ndescribed below.\n\nData will be decoded into the supplied row buffers packed into bytes\nunless the library has been told to transform it into another format.\nFor example, 4 bit/pixel paletted or grayscale data will be returned\n2 pixels/byte with the leftmost pixel in the high-order bits of the byte,\nunless png_set_packing() is called.  8-bit RGB data will be stored\nin RGB RGB RGB format unless png_set_filler() or png_set_add_alpha()\nis called to insert filler bytes, either before or after each RGB triplet.\n\n16-bit RGB data will be returned RRGGBB RRGGBB, with the most significant\nbyte of the color value first, unless png_set_scale_16() is called to\ntransform it to regular RGB RGB triplets, or png_set_filler() or\npng_set_add alpha() is called to insert two filler bytes, either before\nor after each RRGGBB triplet.  Similarly, 8-bit or 16-bit grayscale data can\nbe modified with png_set_filler(), png_set_add_alpha(), png_set_strip_16(),\nor png_set_scale_16().\n\nThe following code transforms grayscale images of less than 8 to 8 bits,\nchanges paletted images to RGB, and adds a full alpha channel if there is\ntransparency information in a tRNS chunk.  This is most useful on\ngrayscale images with bit depths of 2 or 4 or if there is a multiple-image\nviewing application that wishes to treat all images in the same way.\n\n    if (color_type == PNG_COLOR_TYPE_PALETTE)\n        png_set_palette_to_rgb(png_ptr);\n\n    if (png_get_valid(png_ptr, info_ptr,\n        PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);\n\n    if (color_type == PNG_COLOR_TYPE_GRAY &&\n        bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr);\n\nThe first two functions are actually aliases for png_set_expand(), added\nin libpng version 1.0.4, with the function names expanded to improve code\nreadability.  In some future version they may actually do different\nthings.\n\nAs of libpng version 1.2.9, png_set_expand_gray_1_2_4_to_8() was\nadded.  It expands the sample depth without changing tRNS to alpha.\n\nAs of libpng version 1.5.2, png_set_expand_16() was added.  It behaves as\npng_set_expand(); however, the resultant channels have 16 bits rather than 8.\nUse this when the output color or gray channels are made linear to avoid fairly\nsevere accuracy loss.\n\n   if (bit_depth < 16)\n      png_set_expand_16(png_ptr);\n\nPNG can have files with 16 bits per channel.  If you only can handle\n8 bits per channel, this will strip the pixels down to 8-bit.\n\n    if (bit_depth == 16)\n#if PNG_LIBPNG_VER >= 10504\n       png_set_scale_16(png_ptr);\n#else\n       png_set_strip_16(png_ptr);\n#endif\n\n(The more accurate \"png_set_scale_16()\" API became available in libpng version\n1.5.4).\n\nIf you need to process the alpha channel on the image separately from the image\ndata (for example if you convert it to a bitmap mask) it is possible to have\nlibpng strip the channel leaving just RGB or gray data:\n\n    if (color_type & PNG_COLOR_MASK_ALPHA)\n       png_set_strip_alpha(png_ptr);\n\nIf you strip the alpha channel you need to find some other way of dealing with\nthe information.  If, instead, you want to convert the image to an opaque\nversion with no alpha channel use png_set_background; see below.\n\nAs of libpng version 1.5.2, almost all useful expansions are supported, the\nmajor ommissions are conversion of grayscale to indexed images (which can be\ndone trivially in the application) and conversion of indexed to grayscale (which\ncan be done by a trivial manipulation of the palette.)\n\nIn the following table, the 01 means grayscale with depth<8, 31 means\nindexed with depth<8, other numerals represent the color type, \"T\" means\nthe tRNS chunk is present, A means an alpha channel is present, and O\nmeans tRNS or alpha is present but all pixels in the image are opaque.\n\n  FROM  01  31   0  0T  0O   2  2T  2O   3  3T  3O  4A  4O  6A  6O\n   TO\n   01    -  [G]  -   -   -   -   -   -   -   -   -   -   -   -   -\n   31   [Q]  Q  [Q] [Q] [Q]  Q   Q   Q   Q   Q   Q  [Q] [Q]  Q   Q\n    0    1   G   +   .   .   G   G   G   G   G   G   B   B  GB  GB\n   0T    lt  Gt  t   +   .   Gt  G   G   Gt  G   G   Bt  Bt GBt GBt\n   0O    lt  Gt  t   .   +   Gt  Gt  G   Gt  Gt  G   Bt  Bt GBt GBt\n    2    C   P   C   C   C   +   .   .   C   -   -  CB  CB   B   B\n   2T    Ct  -   Ct  C   C   t   +   t   -   -   -  CBt CBt  Bt  Bt\n   2O    Ct  -   Ct  C   C   t   t   +   -   -   -  CBt CBt  Bt  Bt\n    3   [Q]  p  [Q] [Q] [Q]  Q   Q   Q   +   .   .  [Q] [Q]  Q   Q\n   3T   [Qt] p  [Qt][Q] [Q]  Qt  Qt  Qt  t   +   t  [Qt][Qt] Qt  Qt\n   3O   [Qt] p  [Qt][Q] [Q]  Qt  Qt  Qt  t   t   +  [Qt][Qt] Qt  Qt\n   4A    lA  G   A   T   T   GA  GT  GT  GA  GT  GT  +   BA  G  GBA\n   4O    lA GBA  A   T   T   GA  GT  GT  GA  GT  GT  BA  +  GBA  G\n   6A    CA  PA  CA  C   C   A   T  tT   PA  P   P   C  CBA  +   BA\n   6O    CA PBA  CA  C   C   A  tT   T   PA  P   P  CBA  C   BA  +\n\nWithin the matrix,\n     \"+\" identifies entries where 'from' and 'to' are the same.\n     \"-\" means the transformation is not supported.\n     \".\" means nothing is necessary (a tRNS chunk can just be ignored).\n     \"t\" means the transformation is obtained by png_set_tRNS.\n     \"A\" means the transformation is obtained by png_set_add_alpha().\n     \"X\" means the transformation is obtained by png_set_expand().\n     \"1\" means the transformation is obtained by\n         png_set_expand_gray_1_2_4_to_8() (and by png_set_expand()\n         if there is no transparency in the original or the final\n         format).\n     \"C\" means the transformation is obtained by png_set_gray_to_rgb().\n     \"G\" means the transformation is obtained by png_set_rgb_to_gray().\n     \"P\" means the transformation is obtained by\n         png_set_expand_palette_to_rgb().\n     \"p\" means the transformation is obtained by png_set_packing().\n     \"Q\" means the transformation is obtained by png_set_quantize().\n     \"T\" means the transformation is obtained by\n         png_set_tRNS_to_alpha().\n     \"B\" means the transformation is obtained by\n         png_set_background(), or png_strip_alpha().\n\nWhen an entry has multiple transforms listed all are required to cause the\nright overall transformation.  When two transforms are separated by a comma\neither will do the job.  When transforms are enclosed in [] the transform should\ndo the job but this is currently unimplemented - a different format will result\nif the suggested transformations are used.\n\nIn PNG files, the alpha channel in an image\nis the level of opacity.  If you need the alpha channel in an image to\nbe the level of transparency instead of opacity, you can invert the\nalpha channel (or the tRNS chunk data) after it's read, so that 0 is\nfully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit\nimages) is fully transparent, with\n\n    png_set_invert_alpha(png_ptr);\n\nPNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as\nthey can, resulting in, for example, 8 pixels per byte for 1 bit\nfiles.  This code expands to 1 pixel per byte without changing the\nvalues of the pixels:\n\n    if (bit_depth < 8)\n       png_set_packing(png_ptr);\n\nPNG files have possible bit depths of 1, 2, 4, 8, and 16.  All pixels\nstored in a PNG image have been \"scaled\" or \"shifted\" up to the next\nhigher possible bit depth (e.g. from 5 bits/sample in the range [0,31]\nto 8 bits/sample in the range [0, 255]).  However, it is also possible\nto convert the PNG pixel data back to the original bit depth of the\nimage.  This call reduces the pixels back down to the original bit depth:\n\n    png_color_8p sig_bit;\n\n    if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))\n       png_set_shift(png_ptr, sig_bit);\n\nPNG files store 3-color pixels in red, green, blue order.  This code\nchanges the storage of the pixels to blue, green, red:\n\n    if (color_type == PNG_COLOR_TYPE_RGB ||\n        color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n       png_set_bgr(png_ptr);\n\nPNG files store RGB pixels packed into 3 or 6 bytes. This code expands them\ninto 4 or 8 bytes for windowing systems that need them in this format:\n\n    if (color_type == PNG_COLOR_TYPE_RGB)\n       png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE);\n\nwhere \"filler\" is the 8-bit or 16-bit number to fill with, and the location\nis either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether\nyou want the filler before the RGB or after. When filling an 8-bit pixel,\nthe least significant 8 bits of the number are used, if a 16-bit number is\nsupplied.  This transformation does not affect images that already have full\nalpha channels.  To add an opaque alpha channel, use filler=0xffff and\nPNG_FILLER_AFTER which will generate RGBA pixels.\n\nNote that png_set_filler() does not change the color type.  If you want\nto do that, you can add a true alpha channel with\n\n    if (color_type == PNG_COLOR_TYPE_RGB ||\n       color_type == PNG_COLOR_TYPE_GRAY)\n       png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER);\n\nwhere \"filler\" contains the alpha value to assign to each pixel.\nThe png_set_add_alpha() function was added in libpng-1.2.7.\n\nIf you are reading an image with an alpha channel, and you need the\ndata as ARGB instead of the normal PNG format RGBA:\n\n    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n       png_set_swap_alpha(png_ptr);\n\nFor some uses, you may want a grayscale image to be represented as\nRGB.  This code will do that conversion:\n\n    if (color_type == PNG_COLOR_TYPE_GRAY ||\n        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n       png_set_gray_to_rgb(png_ptr);\n\nConversely, you can convert an RGB or RGBA image to grayscale or grayscale\nwith alpha.\n\n    if (color_type == PNG_COLOR_TYPE_RGB ||\n        color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n       png_set_rgb_to_gray(png_ptr, error_action,\n          double red_weight, double green_weight);\n\n    error_action = 1: silently do the conversion\n\n    error_action = 2: issue a warning if the original\n                      image has any pixel where\n                      red != green or red != blue\n\n    error_action = 3: issue an error and abort the\n                      conversion if the original\n                      image has any pixel where\n                      red != green or red != blue\n\n    red_weight:       weight of red component\n\n    green_weight:     weight of green component\n                      If either weight is negative, default\n                      weights are used.\n\nIn the corresponding fixed point API the red_weight and green_weight values are\nsimply scaled by 100,000:\n\n    png_set_rgb_to_gray(png_ptr, error_action,\n       png_fixed_point red_weight,\n       png_fixed_point green_weight);\n\nIf you have set error_action = 1 or 2, you can\nlater check whether the image really was gray, after processing\nthe image rows, with the png_get_rgb_to_gray_status(png_ptr) function.\nIt will return a png_byte that is zero if the image was gray or\n1 if there were any non-gray pixels.  Background and sBIT data\nwill be silently converted to grayscale, using the green channel\ndata for sBIT, regardless of the error_action setting.\n\nThe default values come from the PNG file cHRM chunk if present; otherwise, the\ndefaults correspond to the ITU-R recommendation 709, and also the sRGB color\nspace, as recommended in the Charles Poynton's Colour FAQ,\nCopyright (c) 2006-11-28 Charles Poynton, in section 9:\n\n<http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC9>\n\n    Y = 0.2126 * R + 0.7152 * G + 0.0722 * B\n\nPrevious versions of this document, 1998 through 2002, recommended a slightly\ndifferent formula:\n\n    Y = 0.212671 * R + 0.715160 * G + 0.072169 * B\n\nLibpng uses an integer approximation:\n\n    Y = (6968 * R + 23434 * G + 2366 * B)/32768\n\nThe calculation is done in a linear colorspace, if the image gamma\ncan be determined.\n\nThe png_set_background() function has been described already; it tells libpng to\ncomposite images with alpha or simple transparency against the supplied\nbackground color.  For compatibility with versions of libpng earlier than\nlibpng-1.5.4 it is recommended that you call the function after reading the file\nheader, even if you don't want to use the color in a bKGD chunk, if one exists.\n\nIf the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),\nyou may use this color, or supply another color more suitable for\nthe current display (e.g., the background color from a web page).  You\nneed to tell libpng how the color is represented, both the format of the\ncomponent values in the color (the number of bits) and the gamma encoding of the\ncolor.  The function takes two arguments, background_gamma_mode and need_expand\nto convey this information; however, only two combinations are likely to be\nuseful:\n\n    png_color_16 my_background;\n    png_color_16p image_background;\n\n    if (png_get_bKGD(png_ptr, info_ptr, &image_background))\n       png_set_background(png_ptr, image_background,\n           PNG_BACKGROUND_GAMMA_FILE, 1/*needs to be expanded*/, 1);\n    else\n       png_set_background(png_ptr, &my_background,\n           PNG_BACKGROUND_GAMMA_SCREEN, 0/*do not expand*/, 1);\n\nThe second call was described above - my_background is in the format of the\nfinal, display, output produced by libpng.  Because you now know the format of\nthe PNG it is possible to avoid the need to choose either 8-bit or 16-bit\noutput and to retain palette images (the palette colors will be modified\nappropriately and the tRNS chunk removed.)  However, if you are doing this,\ntake great care not to ask for transformations without checking first that\nthey apply!\n\nIn the first call the background color has the original bit depth and color type\nof the PNG file.  So, for palette images the color is supplied as a palette\nindex and for low bit greyscale images the color is a reduced bit value in\nimage_background->gray.\n\nIf you didn't call png_set_gamma() before reading the file header, for example\nif you need your code to remain compatible with older versions of libpng prior\nto libpng-1.5.4, this is the place to call it.\n\nDo not call it if you called png_set_alpha_mode(); doing so will damage the\nsettings put in place by png_set_alpha_mode().  (If png_set_alpha_mode() is\nsupported then you can certainly do png_set_gamma() before reading the PNG\nheader.)\n\nThis API unconditionally sets the screen and file gamma values, so it will\noverride the value in the PNG file unless it is called before the PNG file\nreading starts.  For this reason you must always call it with the PNG file\nvalue when you call it in this position:\n\n   if (png_get_gAMA(png_ptr, info_ptr, &file_gamma))\n      png_set_gamma(png_ptr, screen_gamma, file_gamma);\n\n   else\n      png_set_gamma(png_ptr, screen_gamma, 0.45455);\n\nIf you need to reduce an RGB file to a paletted file, or if a paletted\nfile has more entries than will fit on your screen, png_set_quantize()\nwill do that.  Note that this is a simple match quantization that merely\nfinds the closest color available.  This should work fairly well with\noptimized palettes, but fairly badly with linear color cubes.  If you\npass a palette that is larger than maximum_colors, the file will\nreduce the number of colors in the palette so it will fit into\nmaximum_colors.  If there is a histogram, libpng will use it to make\nmore intelligent choices when reducing the palette.  If there is no\nhistogram, it may not do as good a job.\n\n   if (color_type & PNG_COLOR_MASK_COLOR)\n   {\n      if (png_get_valid(png_ptr, info_ptr,\n          PNG_INFO_PLTE))\n      {\n         png_uint_16p histogram = NULL;\n\n         png_get_hIST(png_ptr, info_ptr,\n             &histogram);\n         png_set_quantize(png_ptr, palette, num_palette,\n            max_screen_colors, histogram, 1);\n      }\n\n      else\n      {\n         png_color std_color_cube[MAX_SCREEN_COLORS] =\n            { ... colors ... };\n\n         png_set_quantize(png_ptr, std_color_cube,\n            MAX_SCREEN_COLORS, MAX_SCREEN_COLORS,\n            NULL,0);\n      }\n   }\n\nPNG files describe monochrome as black being zero and white being one.\nThe following code will reverse this (make black be one and white be\nzero):\n\n   if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY)\n      png_set_invert_mono(png_ptr);\n\nThis function can also be used to invert grayscale and gray-alpha images:\n\n   if (color_type == PNG_COLOR_TYPE_GRAY ||\n       color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n      png_set_invert_mono(png_ptr);\n\nPNG files store 16-bit pixels in network byte order (big-endian,\nie. most significant bits first).  This code changes the storage to the\nother way (little-endian, i.e. least significant bits first, the\nway PCs store them):\n\n    if (bit_depth == 16)\n       png_set_swap(png_ptr);\n\nIf you are using packed-pixel images (1, 2, or 4 bits/pixel), and you\nneed to change the order the pixels are packed into bytes, you can use:\n\n    if (bit_depth < 8)\n       png_set_packswap(png_ptr);\n\nFinally, you can write your own transformation function if none of\nthe existing ones meets your needs.  This is done by setting a callback\nwith\n\n    png_set_read_user_transform_fn(png_ptr,\n        read_transform_fn);\n\nYou must supply the function\n\n    void read_transform_fn(png_structp png_ptr, png_row_infop\n        row_info, png_bytep data)\n\nSee pngtest.c for a working example.  Your function will be called\nafter all of the other transformations have been processed.  Take care with\ninterlaced images if you do the interlace yourself - the width of the row is the\nwidth in 'row_info', not the overall image width.\n\nIf supported, libpng provides two information routines that you can use to find\nwhere you are in processing the image:\n\n   png_get_current_pass_number(png_structp png_ptr);\n   png_get_current_row_number(png_structp png_ptr);\n\nDon't try using these outside a transform callback - firstly they are only\nsupported if user transforms are supported, secondly they may well return\nunexpected results unless the row is actually being processed at the moment they\nare called.\n\nWith interlaced\nimages the value returned is the row in the input sub-image image.  Use\nPNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to\nfind the output pixel (x,y) given an interlaced sub-image pixel (row,col,pass).\n\nThe discussion of interlace handling above contains more information on how to\nuse these values.\n\nYou can also set up a pointer to a user structure for use by your\ncallback function, and you can inform libpng that your transform\nfunction will change the number of channels or bit depth with the\nfunction\n\n    png_set_user_transform_info(png_ptr, user_ptr,\n        user_depth, user_channels);\n\nThe user's application, not libpng, is responsible for allocating and\nfreeing any memory required for the user structure.\n\nYou can retrieve the pointer via the function\npng_get_user_transform_ptr().  For example:\n\n    voidp read_user_transform_ptr =\n        png_get_user_transform_ptr(png_ptr);\n\nThe last thing to handle is interlacing; this is covered in detail below,\nbut you must call the function here if you want libpng to handle expansion\nof the interlaced image.\n\n    number_of_passes = png_set_interlace_handling(png_ptr);\n\nAfter setting the transformations, libpng can update your png_info\nstructure to reflect any transformations you've requested with this\ncall.\n\n    png_read_update_info(png_ptr, info_ptr);\n\nThis is most useful to update the info structure's rowbytes\nfield so you can use it to allocate your image memory.  This function\nwill also update your palette with the correct screen_gamma and\nbackground if these have been given with the calls above.  You may\nonly call png_read_update_info() once with a particular info_ptr.\n\nAfter you call png_read_update_info(), you can allocate any\nmemory you need to hold the image.  The row data is simply\nraw byte data for all forms of images.  As the actual allocation\nvaries among applications, no example will be given.  If you\nare allocating one large chunk, you will need to build an\narray of pointers to each row, as it will be needed for some\nof the functions below.\n\nRemember: Before you call png_read_update_info(), the png_get_*()\nfunctions return the values corresponding to the original PNG image.\nAfter you call png_read_update_info the values refer to the image\nthat libpng will output.  Consequently you must call all the png_set_\nfunctions before you call png_read_update_info().  This is particularly\nimportant for png_set_interlace_handling() - if you are going to call\npng_read_update_info() you must call png_set_interlace_handling() before\nit unless you want to receive interlaced output.\n\nReading image data\n\nAfter you've allocated memory, you can read the image data.\nThe simplest way to do this is in one function call.  If you are\nallocating enough memory to hold the whole image, you can just\ncall png_read_image() and libpng will read in all the image data\nand put it in the memory area supplied.  You will need to pass in\nan array of pointers to each row.\n\nThis function automatically handles interlacing, so you don't\nneed to call png_set_interlace_handling() (unless you call\npng_read_update_info()) or call this function multiple times, or any\nof that other stuff necessary with png_read_rows().\n\n   png_read_image(png_ptr, row_pointers);\n\nwhere row_pointers is:\n\n   png_bytep row_pointers[height];\n\nYou can point to void or char or whatever you use for pixels.\n\nIf you don't want to read in the whole image at once, you can\nuse png_read_rows() instead.  If there is no interlacing (check\ninterlace_type == PNG_INTERLACE_NONE), this is simple:\n\n    png_read_rows(png_ptr, row_pointers, NULL,\n        number_of_rows);\n\nwhere row_pointers is the same as in the png_read_image() call.\n\nIf you are doing this just one row at a time, you can do this with\na single row_pointer instead of an array of row_pointers:\n\n    png_bytep row_pointer = row;\n    png_read_row(png_ptr, row_pointer, NULL);\n\nIf the file is interlaced (interlace_type != 0 in the IHDR chunk), things\nget somewhat harder.  The only current (PNG Specification version 1.2)\ninterlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7);\na somewhat complicated 2D interlace scheme, known as Adam7, that\nbreaks down an image into seven smaller images of varying size, based\non an 8x8 grid.  This number is defined (from libpng 1.5) as\nPNG_INTERLACE_ADAM7_PASSES in png.h\n\nlibpng can fill out those images or it can give them to you \"as is\".\nIt is almost always better to have libpng handle the interlacing for you.\nIf you want the images filled out, there are two ways to do that.  The one\nmentioned in the PNG specification is to expand each pixel to cover\nthose pixels that have not been read yet (the \"rectangle\" method).\nThis results in a blocky image for the first pass, which gradually\nsmooths out as more pixels are read.  The other method is the \"sparkle\"\nmethod, where pixels are drawn only in their final locations, with the\nrest of the image remaining whatever colors they were initialized to\nbefore the start of the read.  The first method usually looks better,\nbut tends to be slower, as there are more pixels to put in the rows.\n\nIf, as is likely, you want libpng to expand the images, call this before\ncalling png_start_read_image() or png_read_update_info():\n\n    if (interlace_type == PNG_INTERLACE_ADAM7)\n       number_of_passes\n           = png_set_interlace_handling(png_ptr);\n\nThis will return the number of passes needed.  Currently, this is seven,\nbut may change if another interlace type is added.  This function can be\ncalled even if the file is not interlaced, where it will return one pass.\nYou then need to read the whole image 'number_of_passes' times.  Each time\nwill distribute the pixels from the current pass to the correct place in\nthe output image, so you need to supply the same rows to png_read_rows in\neach pass.\n\nIf you are not going to display the image after each pass, but are\ngoing to wait until the entire image is read in, use the sparkle\neffect.  This effect is faster and the end result of either method\nis exactly the same.  If you are planning on displaying the image\nafter each pass, the \"rectangle\" effect is generally considered the\nbetter looking one.\n\nIf you only want the \"sparkle\" effect, just call png_read_rows() as\nnormal, with the third parameter NULL.  Make sure you make pass over\nthe image number_of_passes times, and you don't change the data in the\nrows between calls.  You can change the locations of the data, just\nnot the data.  Each pass only writes the pixels appropriate for that\npass, and assumes the data from previous passes is still valid.\n\n    png_read_rows(png_ptr, row_pointers, NULL,\n        number_of_rows);\n\nIf you only want the first effect (the rectangles), do the same as\nbefore except pass the row buffer in the third parameter, and leave\nthe second parameter NULL.\n\n    png_read_rows(png_ptr, NULL, row_pointers,\n        number_of_rows);\n\nIf you don't want libpng to handle the interlacing details, just call\npng_read_rows() PNG_INTERLACE_ADAM7_PASSES times to read in all the images.\nEach of the images is a valid image by itself; however, you will almost\ncertainly need to distribute the pixels from each sub-image to the\ncorrect place.  This is where everything gets very tricky.\n\nIf you want to retrieve the separate images you must pass the correct\nnumber of rows to each successive call of png_read_rows().  The calculation\ngets pretty complicated for small images, where some sub-images may\nnot even exist because either their width or height ends up zero.\nlibpng provides two macros to help you in 1.5 and later versions:\n\n   png_uint_32 width = PNG_PASS_COLS(image_width, pass_number);\n   png_uint_32 height = PNG_PASS_ROWS(image_height, pass_number);\n\nRespectively these tell you the width and height of the sub-image\ncorresponding to the numbered pass.  'pass' is in in the range 0 to 6 -\nthis can be confusing because the specification refers to the same passes\nas 1 to 7!  Be careful, you must check both the width and height before\ncalling png_read_rows() and not call it for that pass if either is zero.\n\nYou can, of course, read each sub-image row by row.  If you want to\nproduce optimal code to make a pixel-by-pixel transformation of an\ninterlaced image this is the best approach; read each row of each pass,\ntransform it, and write it out to a new interlaced image.\n\nIf you want to de-interlace the image yourself libpng provides further\nmacros to help that tell you where to place the pixels in the output image.\nBecause the interlacing scheme is rectangular - sub-image pixels are always\narranged on a rectangular grid - all you need to know for each pass is the\nstarting column and row in the output image of the first pixel plus the\nspacing between each pixel.  As of libpng 1.5 there are four macros to\nretrieve this information:\n\n   png_uint_32 x = PNG_PASS_START_COL(pass);\n   png_uint_32 y = PNG_PASS_START_ROW(pass);\n   png_uint_32 xStep = 1U << PNG_PASS_COL_SHIFT(pass);\n   png_uint_32 yStep = 1U << PNG_PASS_ROW_SHIFT(pass);\n\nThese allow you to write the obvious loop:\n\n   png_uint_32 input_y = 0;\n   png_uint_32 output_y = PNG_PASS_START_ROW(pass);\n\n   while (output_y < output_image_height)\n   {\n      png_uint_32 input_x = 0;\n      png_uint_32 output_x = PNG_PASS_START_COL(pass);\n\n      while (output_x < output_image_width)\n      {\n         image[output_y][output_x] =\n             subimage[pass][input_y][input_x++];\n\n         output_x += xStep;\n      }\n\n      ++input_y;\n      output_y += yStep;\n   }\n\nNotice that the steps between successive output rows and columns are\nreturned as shifts.  This is possible because the pixels in the subimages\nare always a power of 2 apart - 1, 2, 4 or 8 pixels - in the original\nimage.  In practice you may need to directly calculate the output coordinate\ngiven an input coordinate.  libpng provides two further macros for this\npurpose:\n\n   png_uint_32 output_x = PNG_COL_FROM_PASS_COL(input_x, pass);\n   png_uint_32 output_y = PNG_ROW_FROM_PASS_ROW(input_y, pass);\n\nFinally a pair of macros are provided to tell you if a particular image\nrow or column appears in a given pass:\n\n   int col_in_pass = PNG_COL_IN_INTERLACE_PASS(output_x, pass);\n   int row_in_pass = PNG_ROW_IN_INTERLACE_PASS(output_y, pass);\n\nBear in mind that you will probably also need to check the width and height\nof the pass in addition to the above to be sure the pass even exists!\n\nWith any luck you are convinced by now that you don't want to do your own\ninterlace handling.  In reality normally the only good reason for doing this\nis if you are processing PNG files on a pixel-by-pixel basis and don't want\nto load the whole file into memory when it is interlaced.\n\nlibpng includes a test program, pngvalid, that illustrates reading and\nwriting of interlaced images.  If you can't get interlacing to work in your\ncode and don't want to leave it to libpng (the recommended approach), see\nhow pngvalid.c does it.\n\nFinishing a sequential read\n\nAfter you are finished reading the image through the\nlow-level interface, you can finish reading the file.\n\nIf you want to use a different crc action for handling CRC errors in\nchunks after the image data, you can call png_set_crc_action()\nagain at this point.\n\nIf you are interested in comments or time, which may be stored either\nbefore or after the image data, you should pass the separate png_info\nstruct if you want to keep the comments from before and after the image\nseparate.\n\n    png_infop end_info = png_create_info_struct(png_ptr);\n\n    if (!end_info)\n    {\n       png_destroy_read_struct(&png_ptr, &info_ptr,\n           (png_infopp)NULL);\n       return (ERROR);\n    }\n\n   png_read_end(png_ptr, end_info);\n\nIf you are not interested, you should still call png_read_end()\nbut you can pass NULL, avoiding the need to create an end_info structure.\nIf you do this, libpng will not process any chunks after IDAT other than\nskipping over them and perhaps (depending on whether you have called\npng_set_crc_action) checking their CRCs while looking for the IEND chunk.\n\n   png_read_end(png_ptr, (png_infop)NULL);\n\nIf you don't call png_read_end(), then your file pointer will be\nleft pointing to the first chunk after the last IDAT, which is probably\nnot what you want if you expect to read something beyond the end of\nthe PNG datastream.\n\nWhen you are done, you can free all memory allocated by libpng like this:\n\n   png_destroy_read_struct(&png_ptr, &info_ptr,\n       &end_info);\n\nor, if you didn't create an end_info structure,\n\n   png_destroy_read_struct(&png_ptr, &info_ptr,\n       (png_infopp)NULL);\n\nIt is also possible to individually free the info_ptr members that\npoint to libpng-allocated storage with the following function:\n\n    png_free_data(png_ptr, info_ptr, mask, seq)\n\n    mask - identifies data to be freed, a mask\n           containing the bitwise OR of one or\n           more of\n             PNG_FREE_PLTE, PNG_FREE_TRNS,\n             PNG_FREE_HIST, PNG_FREE_ICCP,\n             PNG_FREE_PCAL, PNG_FREE_ROWS,\n             PNG_FREE_SCAL, PNG_FREE_SPLT,\n             PNG_FREE_TEXT, PNG_FREE_UNKN,\n           or simply PNG_FREE_ALL\n\n    seq  - sequence number of item to be freed\n           (-1 for all items)\n\nThis function may be safely called when the relevant storage has\nalready been freed, or has not yet been allocated, or was allocated\nby the user and not by libpng,  and will in those cases do nothing.\nThe \"seq\" parameter is ignored if only one item of the selected data\ntype, such as PLTE, is allowed.  If \"seq\" is not -1, and multiple items\nare allowed for the data type identified in the mask, such as text or\nsPLT, only the n'th item in the structure is freed, where n is \"seq\".\n\nThe default behavior is only to free data that was allocated internally\nby libpng.  This can be changed, so that libpng will not free the data,\nor so that it will free data that was allocated by the user with png_malloc()\nor png_calloc() and passed in via a png_set_*() function, with\n\n    png_data_freer(png_ptr, info_ptr, freer, mask)\n\n    freer  - one of\n               PNG_DESTROY_WILL_FREE_DATA\n               PNG_SET_WILL_FREE_DATA\n               PNG_USER_WILL_FREE_DATA\n\n    mask   - which data elements are affected\n             same choices as in png_free_data()\n\nThis function only affects data that has already been allocated.\nYou can call this function after reading the PNG data but before calling\nany png_set_*() functions, to control whether the user or the png_set_*()\nfunction is responsible for freeing any existing data that might be present,\nand again after the png_set_*() functions to control whether the user\nor png_destroy_*() is supposed to free the data.  When the user assumes\nresponsibility for libpng-allocated data, the application must use\npng_free() to free it, and when the user transfers responsibility to libpng\nfor data that the user has allocated, the user must have used png_malloc()\nor png_calloc() to allocate it.\n\nIf you allocated your row_pointers in a single block, as suggested above in\nthe description of the high level read interface, you must not transfer\nresponsibility for freeing it to the png_set_rows or png_read_destroy function,\nbecause they would also try to free the individual row_pointers[i].\n\nIf you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword\nseparately, do not transfer responsibility for freeing text_ptr to libpng,\nbecause when libpng fills a png_text structure it combines these members with\nthe key member, and png_free_data() will free only text_ptr.key.  Similarly,\nif you transfer responsibility for free'ing text_ptr from libpng to your\napplication, your application must not separately free those members.\n\nThe png_free_data() function will turn off the \"valid\" flag for anything\nit frees.  If you need to turn the flag off for a chunk that was freed by\nyour application instead of by libpng, you can use\n\n    png_set_invalid(png_ptr, info_ptr, mask);\n\n    mask - identifies the chunks to be made invalid,\n           containing the bitwise OR of one or\n           more of\n             PNG_INFO_gAMA, PNG_INFO_sBIT,\n             PNG_INFO_cHRM, PNG_INFO_PLTE,\n             PNG_INFO_tRNS, PNG_INFO_bKGD,\n             PNG_INFO_hIST, PNG_INFO_pHYs,\n             PNG_INFO_oFFs, PNG_INFO_tIME,\n             PNG_INFO_pCAL, PNG_INFO_sRGB,\n             PNG_INFO_iCCP, PNG_INFO_sPLT,\n             PNG_INFO_sCAL, PNG_INFO_IDAT\n\nFor a more compact example of reading a PNG image, see the file example.c.\n\nReading PNG files progressively\n\nThe progressive reader is slightly different from the non-progressive\nreader.  Instead of calling png_read_info(), png_read_rows(), and\npng_read_end(), you make one call to png_process_data(), which calls\ncallbacks when it has the info, a row, or the end of the image.  You\nset up these callbacks with png_set_progressive_read_fn().  You don't\nhave to worry about the input/output functions of libpng, as you are\ngiving the library the data directly in png_process_data().  I will\nassume that you have read the section on reading PNG files above,\nso I will only highlight the differences (although I will show\nall of the code).\n\npng_structp png_ptr;\npng_infop info_ptr;\n\n /*  An example code fragment of how you would\n     initialize the progressive reader in your\n     application. */\n int\n initialize_png_reader()\n {\n    png_ptr = png_create_read_struct\n        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,\n         user_error_fn, user_warning_fn);\n\n    if (!png_ptr)\n        return (ERROR);\n\n    info_ptr = png_create_info_struct(png_ptr);\n\n    if (!info_ptr)\n    {\n       png_destroy_read_struct(&png_ptr,\n          (png_infopp)NULL, (png_infopp)NULL);\n       return (ERROR);\n    }\n\n    if (setjmp(png_jmpbuf(png_ptr)))\n    {\n       png_destroy_read_struct(&png_ptr, &info_ptr,\n          (png_infopp)NULL);\n       return (ERROR);\n    }\n\n    /* This one's new.  You can provide functions\n       to be called when the header info is valid,\n       when each row is completed, and when the image\n       is finished.  If you aren't using all functions,\n       you can specify NULL parameters.  Even when all\n       three functions are NULL, you need to call\n       png_set_progressive_read_fn().  You can use\n       any struct as the user_ptr (cast to a void pointer\n       for the function call), and retrieve the pointer\n       from inside the callbacks using the function\n\n          png_get_progressive_ptr(png_ptr);\n\n       which will return a void pointer, which you have\n       to cast appropriately.\n     */\n    png_set_progressive_read_fn(png_ptr, (void *)user_ptr,\n        info_callback, row_callback, end_callback);\n\n    return 0;\n }\n\n /* A code fragment that you call as you receive blocks\n   of data */\n int\n process_data(png_bytep buffer, png_uint_32 length)\n {\n    if (setjmp(png_jmpbuf(png_ptr)))\n    {\n       png_destroy_read_struct(&png_ptr, &info_ptr,\n           (png_infopp)NULL);\n       return (ERROR);\n    }\n\n    /* This one's new also.  Simply give it a chunk\n       of data from the file stream (in order, of\n       course).  On machines with segmented memory\n       models machines, don't give it any more than\n       64K.  The library seems to run fine with sizes\n       of 4K. Although you can give it much less if\n       necessary (I assume you can give it chunks of\n       1 byte, I haven't tried less than 256 bytes\n       yet).  When this function returns, you may\n       want to display any rows that were generated\n       in the row callback if you don't already do\n       so there.\n     */\n    png_process_data(png_ptr, info_ptr, buffer, length);\n\n    /* At this point you can call png_process_data_skip if\n       you want to handle data the library will skip yourself;\n       it simply returns the number of bytes to skip (and stops\n       libpng skipping that number of bytes on the next\n       png_process_data call).\n    return 0;\n }\n\n /* This function is called (as set by\n    png_set_progressive_read_fn() above) when enough data\n    has been supplied so all of the header has been\n    read.\n */\n void\n info_callback(png_structp png_ptr, png_infop info)\n {\n    /* Do any setup here, including setting any of\n       the transformations mentioned in the Reading\n       PNG files section.  For now, you _must_ call\n       either png_start_read_image() or\n       png_read_update_info() after all the\n       transformations are set (even if you don't set\n       any).  You may start getting rows before\n       png_process_data() returns, so this is your\n       last chance to prepare for that.\n\n       This is where you turn on interlace handling,\n       assuming you don't want to do it yourself.\n\n       If you need to you can stop the processing of\n       your original input data at this point by calling\n       png_process_data_pause.  This returns the number\n       of unprocessed bytes from the last png_process_data\n       call - it is up to you to ensure that the next call\n       sees these bytes again.  If you don't want to bother\n       with this you can get libpng to cache the unread\n       bytes by setting the 'save' parameter (see png.h) but\n       then libpng will have to copy the data internally.\n     */\n }\n\n /* This function is called when each row of image\n    data is complete */\n void\n row_callback(png_structp png_ptr, png_bytep new_row,\n    png_uint_32 row_num, int pass)\n {\n    /* If the image is interlaced, and you turned\n       on the interlace handler, this function will\n       be called for every row in every pass.  Some\n       of these rows will not be changed from the\n       previous pass.  When the row is not changed,\n       the new_row variable will be NULL.  The rows\n       and passes are called in order, so you don't\n       really need the row_num and pass, but I'm\n       supplying them because it may make your life\n       easier.\n\n       If you did not turn on interlace handling then\n       the callback is called for each row of each\n       sub-image when the image is interlaced.  In this\n       case 'row_num' is the row in the sub-image, not\n       the row in the output image as it is in all other\n       cases.\n\n       For the non-NULL rows of interlaced images when\n       you have switched on libpng interlace handling,\n       you must call png_progressive_combine_row()\n       passing in the row and the old row.  You can\n       call this function for NULL rows (it will just\n       return) and for non-interlaced images (it just\n       does the memcpy for you) if it will make the\n       code easier.  Thus, you can just do this for\n       all cases if you switch on interlace handling;\n     */\n\n        png_progressive_combine_row(png_ptr, old_row,\n          new_row);\n\n    /* where old_row is what was displayed\n       previously for the row.  Note that the first\n       pass (pass == 0, really) will completely cover\n       the old row, so the rows do not have to be\n       initialized.  After the first pass (and only\n       for interlaced images), you will have to pass\n       the current row, and the function will combine\n       the old row and the new row.\n\n       You can also call png_process_data_pause in this\n       callback - see above.\n    */\n }\n\n void\n end_callback(png_structp png_ptr, png_infop info)\n {\n    /* This function is called after the whole image\n       has been read, including any chunks after the\n       image (up to and including the IEND).  You\n       will usually have the same info chunk as you\n       had in the header, although some data may have\n       been added to the comments and time fields.\n\n       Most people won't do much here, perhaps setting\n       a flag that marks the image as finished.\n     */\n }\n\n\n\nIV. Writing\n\nMuch of this is very similar to reading.  However, everything of\nimportance is repeated here, so you won't have to constantly look\nback up in the reading section to understand writing.\n\nSetup\n\nYou will want to do the I/O initialization before you get into libpng,\nso if it doesn't work, you don't have anything to undo. If you are not\nusing the standard I/O functions, you will need to replace them with\ncustom writing functions.  See the discussion under Customizing libpng.\n\n    FILE *fp = fopen(file_name, \"wb\");\n\n    if (!fp)\n       return (ERROR);\n\nNext, png_struct and png_info need to be allocated and initialized.\nAs these can be both relatively large, you may not want to store these\non the stack, unless you have stack space to spare.  Of course, you\nwill want to check if they return NULL.  If you are also reading,\nyou won't want to name your read structure and your write structure\nboth \"png_ptr\"; you can call them anything you like, such as\n\"read_ptr\" and \"write_ptr\".  Look at pngtest.c, for example.\n\n    png_structp png_ptr = png_create_write_struct\n       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,\n        user_error_fn, user_warning_fn);\n\n    if (!png_ptr)\n       return (ERROR);\n\n    png_infop info_ptr = png_create_info_struct(png_ptr);\n    if (!info_ptr)\n    {\n       png_destroy_write_struct(&png_ptr,\n           (png_infopp)NULL);\n       return (ERROR);\n    }\n\nIf you want to use your own memory allocation routines,\ndefine PNG_USER_MEM_SUPPORTED and use\npng_create_write_struct_2() instead of png_create_write_struct():\n\n    png_structp png_ptr = png_create_write_struct_2\n       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,\n        user_error_fn, user_warning_fn, (png_voidp)\n        user_mem_ptr, user_malloc_fn, user_free_fn);\n\nAfter you have these structures, you will need to set up the\nerror handling.  When libpng encounters an error, it expects to\nlongjmp() back to your routine.  Therefore, you will need to call\nsetjmp() and pass the png_jmpbuf(png_ptr).  If you\nwrite the file from different routines, you will need to update\nthe png_jmpbuf(png_ptr) every time you enter a new routine that will\ncall a png_*() function.  See your documentation of setjmp/longjmp\nfor your compiler for more information on setjmp/longjmp.  See\nthe discussion on libpng error handling in the Customizing Libpng\nsection below for more information on the libpng error handling.\n\n    if (setjmp(png_jmpbuf(png_ptr)))\n    {\n    png_destroy_write_struct(&png_ptr, &info_ptr);\n       fclose(fp);\n       return (ERROR);\n    }\n    ...\n    return;\n\nIf you would rather avoid the complexity of setjmp/longjmp issues,\nyou can compile libpng with PNG_NO_SETJMP, in which case\nerrors will result in a call to PNG_ABORT() which defaults to abort().\n\nYou can #define PNG_ABORT() to a function that does something\nmore useful than abort(), as long as your function does not\nreturn.\n\nChecking for invalid palette index on write was added at libpng\n1.5.10.  If a pixel contains an invalid (out-of-range) index libpng issues\na benign error.  This is enabled by default because this condition is an\nerror according to the PNG specification, Clause 11.3.2, but the error can\nbe ignored in each png_ptr with\n\n   png_set_check_for_invalid_index(png_ptr, 0);\n\nIf the error is ignored, or if png_benign_error() treats it as a warning,\nany invalid pixels are written as-is by the encoder, resulting in an\ninvalid PNG datastream as output.  In this case the application is\nresponsible for ensuring that the pixel indexes are in range when it writes\na PLTE chunk with fewer entries than the bit depth would allow.\n\nNow you need to set up the output code.  The default for libpng is to\nuse the C function fwrite().  If you use this, you will need to pass a\nvalid FILE * in the function png_init_io().  Be sure that the file is\nopened in binary mode.  Again, if you wish to handle writing data in\nanother way, see the discussion on libpng I/O handling in the Customizing\nLibpng section below.\n\n    png_init_io(png_ptr, fp);\n\nIf you are embedding your PNG into a datastream such as MNG, and don't\nwant libpng to write the 8-byte signature, or if you have already\nwritten the signature in your application, use\n\n    png_set_sig_bytes(png_ptr, 8);\n\nto inform libpng that it should not write a signature.\n\nWrite callbacks\n\nAt this point, you can set up a callback function that will be\ncalled after each row has been written, which you can use to control\na progress meter or the like.  It's demonstrated in pngtest.c.\nYou must supply a function\n\n    void write_row_callback(png_structp png_ptr, png_uint_32 row,\n       int pass);\n    {\n      /* put your code here */\n    }\n\n(You can give it another name that you like instead of \"write_row_callback\")\n\nTo inform libpng about your function, use\n\n    png_set_write_status_fn(png_ptr, write_row_callback);\n\nWhen this function is called the row has already been completely processed and\nit has also been written out.  The 'row' and 'pass' refer to the next row to be\nhandled.  For the\nnon-interlaced case the row that was just handled is simply one less than the\npassed in row number, and pass will always be 0.  For the interlaced case the\nsame applies unless the row value is 0, in which case the row just handled was\nthe last one from one of the preceding passes.  Because interlacing may skip a\npass you cannot be sure that the preceding pass is just 'pass-1', if you really\nneed to know what the last pass is record (row,pass) from the callback and use\nthe last recorded value each time.\n\nAs with the user transform you can find the output row using the\nPNG_ROW_FROM_PASS_ROW macro.\n\nYou now have the option of modifying how the compression library will\nrun.  The following functions are mainly for testing, but may be useful\nin some cases, like if you need to write PNG files extremely fast and\nare willing to give up some compression, or if you want to get the\nmaximum possible compression at the expense of slower writing.  If you\nhave no special needs in this area, let the library do what it wants by\nnot calling this function at all, as it has been tuned to deliver a good\nspeed/compression ratio. The second parameter to png_set_filter() is\nthe filter method, for which the only valid values are 0 (as of the\nJuly 1999 PNG specification, version 1.2) or 64 (if you are writing\na PNG datastream that is to be embedded in a MNG datastream).  The third\nparameter is a flag that indicates which filter type(s) are to be tested\nfor each scanline.  See the PNG specification for details on the specific\nfilter types.\n\n\n    /* turn on or off filtering, and/or choose\n       specific filters.  You can use either a single\n       PNG_FILTER_VALUE_NAME or the bitwise OR of one\n       or more PNG_FILTER_NAME masks.\n     */\n    png_set_filter(png_ptr, 0,\n       PNG_FILTER_NONE  | PNG_FILTER_VALUE_NONE |\n       PNG_FILTER_SUB   | PNG_FILTER_VALUE_SUB  |\n       PNG_FILTER_UP    | PNG_FILTER_VALUE_UP   |\n       PNG_FILTER_AVG   | PNG_FILTER_VALUE_AVG  |\n       PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|\n       PNG_ALL_FILTERS);\n\nIf an application wants to start and stop using particular filters during\ncompression, it should start out with all of the filters (to ensure that\nthe previous row of pixels will be stored in case it's needed later),\nand then add and remove them after the start of compression.\n\nIf you are writing a PNG datastream that is to be embedded in a MNG\ndatastream, the second parameter can be either 0 or 64.\n\nThe png_set_compression_*() functions interface to the zlib compression\nlibrary, and should mostly be ignored unless you really know what you are\ndoing.  The only generally useful call is png_set_compression_level()\nwhich changes how much time zlib spends on trying to compress the image\ndata.  See the Compression Library (zlib.h and algorithm.txt, distributed\nwith zlib) for details on the compression levels.\n\n    #include zlib.h\n\n    /* Set the zlib compression level */\n    png_set_compression_level(png_ptr,\n        Z_BEST_COMPRESSION);\n\n    /* Set other zlib parameters for compressing IDAT */\n    png_set_compression_mem_level(png_ptr, 8);\n    png_set_compression_strategy(png_ptr,\n        Z_DEFAULT_STRATEGY);\n    png_set_compression_window_bits(png_ptr, 15);\n    png_set_compression_method(png_ptr, 8);\n    png_set_compression_buffer_size(png_ptr, 8192)\n\n    /* Set zlib parameters for text compression\n     * If you don't call these, the parameters\n     * fall back on those defined for IDAT chunks\n     */\n    png_set_text_compression_mem_level(png_ptr, 8);\n    png_set_text_compression_strategy(png_ptr,\n        Z_DEFAULT_STRATEGY);\n    png_set_text_compression_window_bits(png_ptr, 15);\n    png_set_text_compression_method(png_ptr, 8);\n\nSetting the contents of info for output\n\nYou now need to fill in the png_info structure with all the data you\nwish to write before the actual image.  Note that the only thing you\nare allowed to write after the image is the text chunks and the time\nchunk (as of PNG Specification 1.2, anyway).  See png_write_end() and\nthe latest PNG specification for more information on that.  If you\nwish to write them before the image, fill them in now, and flag that\ndata as being valid.  If you want to wait until after the data, don't\nfill them until png_write_end().  For all the fields in png_info and\ntheir data types, see png.h.  For explanations of what the fields\ncontain, see the PNG specification.\n\nSome of the more important parts of the png_info are:\n\n    png_set_IHDR(png_ptr, info_ptr, width, height,\n       bit_depth, color_type, interlace_type,\n       compression_type, filter_method)\n\n    width          - holds the width of the image\n                     in pixels (up to 2^31).\n\n    height         - holds the height of the image\n                     in pixels (up to 2^31).\n\n    bit_depth      - holds the bit depth of one of the\n                     image channels.\n                     (valid values are 1, 2, 4, 8, 16\n                     and depend also on the\n                     color_type.  See also significant\n                     bits (sBIT) below).\n\n    color_type     - describes which color/alpha\n                     channels are present.\n                     PNG_COLOR_TYPE_GRAY\n                        (bit depths 1, 2, 4, 8, 16)\n                     PNG_COLOR_TYPE_GRAY_ALPHA\n                        (bit depths 8, 16)\n                     PNG_COLOR_TYPE_PALETTE\n                        (bit depths 1, 2, 4, 8)\n                     PNG_COLOR_TYPE_RGB\n                        (bit_depths 8, 16)\n                     PNG_COLOR_TYPE_RGB_ALPHA\n                        (bit_depths 8, 16)\n\n                     PNG_COLOR_MASK_PALETTE\n                     PNG_COLOR_MASK_COLOR\n                     PNG_COLOR_MASK_ALPHA\n\n    interlace_type - PNG_INTERLACE_NONE or\n                     PNG_INTERLACE_ADAM7\n\n    compression_type - (must be\n                     PNG_COMPRESSION_TYPE_DEFAULT)\n\n    filter_method  - (must be PNG_FILTER_TYPE_DEFAULT\n                     or, if you are writing a PNG to\n                     be embedded in a MNG datastream,\n                     can also be\n                     PNG_INTRAPIXEL_DIFFERENCING)\n\nIf you call png_set_IHDR(), the call must appear before any of the\nother png_set_*() functions, because they might require access to some of\nthe IHDR settings.  The remaining png_set_*() functions can be called\nin any order.\n\nIf you wish, you can reset the compression_type, interlace_type, or\nfilter_method later by calling png_set_IHDR() again; if you do this, the\nwidth, height, bit_depth, and color_type must be the same in each call.\n\n    png_set_PLTE(png_ptr, info_ptr, palette,\n       num_palette);\n\n    palette        - the palette for the file\n                     (array of png_color)\n    num_palette    - number of entries in the palette\n\n\n    png_set_gAMA(png_ptr, info_ptr, file_gamma);\n    png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);\n\n    file_gamma     - the gamma at which the image was\n                     created (PNG_INFO_gAMA)\n\n    int_file_gamma - 100,000 times the gamma at which\n                     the image was created\n\n    png_set_cHRM(png_ptr, info_ptr,  white_x, white_y, red_x, red_y,\n                     green_x, green_y, blue_x, blue_y)\n    png_set_cHRM_XYZ(png_ptr, info_ptr, red_X, red_Y, red_Z, green_X,\n                     green_Y, green_Z, blue_X, blue_Y, blue_Z)\n    png_set_cHRM_fixed(png_ptr, info_ptr, int_white_x, int_white_y,\n                     int_red_x, int_red_y, int_green_x, int_green_y,\n                     int_blue_x, int_blue_y)\n    png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, int_red_X, int_red_Y,\n                     int_red_Z, int_green_X, int_green_Y, int_green_Z,\n                     int_blue_X, int_blue_Y, int_blue_Z)\n\n    {white,red,green,blue}_{x,y}\n                     A color space encoding specified using the chromaticities\n                     of the end points and the white point.\n\n    {red,green,blue}_{X,Y,Z}\n                     A color space encoding specified using the encoding end\n                     points - the CIE tristimulus specification of the intended\n                     color of the red, green and blue channels in the PNG RGB\n                     data.  The white point is simply the sum of the three end\n                     points.\n\n    png_set_sRGB(png_ptr, info_ptr, srgb_intent);\n\n    srgb_intent    - the rendering intent\n                     (PNG_INFO_sRGB) The presence of\n                     the sRGB chunk means that the pixel\n                     data is in the sRGB color space.\n                     This chunk also implies specific\n                     values of gAMA and cHRM.  Rendering\n                     intent is the CSS-1 property that\n                     has been defined by the International\n                     Color Consortium\n                     (http://www.color.org).\n                     It can be one of\n                     PNG_sRGB_INTENT_SATURATION,\n                     PNG_sRGB_INTENT_PERCEPTUAL,\n                     PNG_sRGB_INTENT_ABSOLUTE, or\n                     PNG_sRGB_INTENT_RELATIVE.\n\n\n    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,\n       srgb_intent);\n\n    srgb_intent    - the rendering intent\n                     (PNG_INFO_sRGB) The presence of the\n                     sRGB chunk means that the pixel\n                     data is in the sRGB color space.\n                     This function also causes gAMA and\n                     cHRM chunks with the specific values\n                     that are consistent with sRGB to be\n                     written.\n\n    png_set_iCCP(png_ptr, info_ptr, name, compression_type,\n                       profile, proflen);\n\n    name             - The profile name.\n\n    compression_type - The compression type; always\n                       PNG_COMPRESSION_TYPE_BASE for PNG 1.0.\n                       You may give NULL to this argument to\n                       ignore it.\n\n    profile          - International Color Consortium color\n                       profile data. May contain NULs.\n\n    proflen          - length of profile data in bytes.\n\n    png_set_sBIT(png_ptr, info_ptr, sig_bit);\n\n    sig_bit        - the number of significant bits for\n                     (PNG_INFO_sBIT) each of the gray, red,\n                     green, and blue channels, whichever are\n                     appropriate for the given color type\n                     (png_color_16)\n\n    png_set_tRNS(png_ptr, info_ptr, trans_alpha,\n       num_trans, trans_color);\n\n    trans_alpha    - array of alpha (transparency)\n                     entries for palette (PNG_INFO_tRNS)\n\n    num_trans      - number of transparent entries\n                     (PNG_INFO_tRNS)\n\n    trans_color    - graylevel or color sample values\n                     (in order red, green, blue) of the\n                     single transparent color for\n                     non-paletted images (PNG_INFO_tRNS)\n\n    png_set_hIST(png_ptr, info_ptr, hist);\n\n    hist           - histogram of palette (array of\n                     png_uint_16) (PNG_INFO_hIST)\n\n    png_set_tIME(png_ptr, info_ptr, mod_time);\n\n    mod_time       - time image was last modified\n                     (PNG_VALID_tIME)\n\n    png_set_bKGD(png_ptr, info_ptr, background);\n\n    background     - background color (of type\n                     png_color_16p) (PNG_VALID_bKGD)\n\n    png_set_text(png_ptr, info_ptr, text_ptr, num_text);\n\n    text_ptr       - array of png_text holding image\n                     comments\n\n    text_ptr[i].compression - type of compression used\n                 on \"text\" PNG_TEXT_COMPRESSION_NONE\n                           PNG_TEXT_COMPRESSION_zTXt\n                           PNG_ITXT_COMPRESSION_NONE\n                           PNG_ITXT_COMPRESSION_zTXt\n    text_ptr[i].key   - keyword for comment.  Must contain\n                 1-79 characters.\n    text_ptr[i].text  - text comments for current\n                         keyword.  Can be NULL or empty.\n    text_ptr[i].text_length - length of text string,\n                 after decompression, 0 for iTXt\n    text_ptr[i].itxt_length - length of itxt string,\n                 after decompression, 0 for tEXt/zTXt\n    text_ptr[i].lang  - language of comment (NULL or\n                         empty for unknown).\n    text_ptr[i].translated_keyword  - keyword in UTF-8 (NULL\n                         or empty for unknown).\n\n    Note that the itxt_length, lang, and lang_key\n    members of the text_ptr structure only exist when the\n    library is built with iTXt chunk support.  Prior to\n    libpng-1.4.0 the library was built by default without\n    iTXt support. Also note that when iTXt is supported,\n    they contain NULL pointers when the \"compression\"\n    field contains PNG_TEXT_COMPRESSION_NONE or\n    PNG_TEXT_COMPRESSION_zTXt.\n\n    num_text       - number of comments\n\n    png_set_sPLT(png_ptr, info_ptr, &palette_ptr,\n       num_spalettes);\n\n    palette_ptr    - array of png_sPLT_struct structures\n                     to be added to the list of palettes\n                     in the info structure.\n    num_spalettes  - number of palette structures to be\n                     added.\n\n    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,\n        unit_type);\n\n    offset_x  - positive offset from the left\n                     edge of the screen\n\n    offset_y  - positive offset from the top\n                     edge of the screen\n\n    unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER\n\n    png_set_pHYs(png_ptr, info_ptr, res_x, res_y,\n        unit_type);\n\n    res_x       - pixels/unit physical resolution\n                  in x direction\n\n    res_y       - pixels/unit physical resolution\n                  in y direction\n\n    unit_type   - PNG_RESOLUTION_UNKNOWN,\n                  PNG_RESOLUTION_METER\n\n    png_set_sCAL(png_ptr, info_ptr, unit, width, height)\n\n    unit        - physical scale units (an integer)\n\n    width       - width of a pixel in physical scale units\n\n    height      - height of a pixel in physical scale units\n                  (width and height are doubles)\n\n    png_set_sCAL_s(png_ptr, info_ptr, unit, width, height)\n\n    unit        - physical scale units (an integer)\n\n    width       - width of a pixel in physical scale units\n                  expressed as a string\n\n    height      - height of a pixel in physical scale units\n                 (width and height are strings like \"2.54\")\n\n    png_set_unknown_chunks(png_ptr, info_ptr, &unknowns,\n       num_unknowns)\n\n    unknowns          - array of png_unknown_chunk\n                        structures holding unknown chunks\n    unknowns[i].name  - name of unknown chunk\n    unknowns[i].data  - data of unknown chunk\n    unknowns[i].size  - size of unknown chunk's data\n    unknowns[i].location - position to write chunk in file\n                           0: do not write chunk\n                           PNG_HAVE_IHDR: before PLTE\n                           PNG_HAVE_PLTE: before IDAT\n                           PNG_AFTER_IDAT: after IDAT\n\nThe \"location\" member is set automatically according to\nwhat part of the output file has already been written.\nYou can change its value after calling png_set_unknown_chunks()\nas demonstrated in pngtest.c.  Within each of the \"locations\",\nthe chunks are sequenced according to their position in the\nstructure (that is, the value of \"i\", which is the order in which\nthe chunk was either read from the input file or defined with\npng_set_unknown_chunks).\n\nA quick word about text and num_text.  text is an array of png_text\nstructures.  num_text is the number of valid structures in the array.\nEach png_text structure holds a language code, a keyword, a text value,\nand a compression type.\n\nThe compression types have the same valid numbers as the compression\ntypes of the image data.  Currently, the only valid number is zero.\nHowever, you can store text either compressed or uncompressed, unlike\nimages, which always have to be compressed.  So if you don't want the\ntext compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.\nBecause tEXt and zTXt chunks don't have a language field, if you\nspecify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt\nany language code or translated keyword will not be written out.\n\nUntil text gets around a few hundred bytes, it is not worth compressing it.\nAfter the text has been written out to the file, the compression type\nis set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,\nso that it isn't written out again at the end (in case you are calling\npng_write_end() with the same struct).\n\nThe keywords that are given in the PNG Specification are:\n\n    Title            Short (one line) title or\n                     caption for image\n\n    Author           Name of image's creator\n\n    Description      Description of image (possibly long)\n\n    Copyright        Copyright notice\n\n    Creation Time    Time of original image creation\n                     (usually RFC 1123 format, see below)\n\n    Software         Software used to create the image\n\n    Disclaimer       Legal disclaimer\n\n    Warning          Warning of nature of content\n\n    Source           Device used to create the image\n\n    Comment          Miscellaneous comment; conversion\n                     from other image format\n\nThe keyword-text pairs work like this.  Keywords should be short\nsimple descriptions of what the comment is about.  Some typical\nkeywords are found in the PNG specification, as is some recommendations\non keywords.  You can repeat keywords in a file.  You can even write\nsome text before the image and some after.  For example, you may want\nto put a description of the image before the image, but leave the\ndisclaimer until after, so viewers working over modem connections\ndon't have to wait for the disclaimer to go over the modem before\nthey start seeing the image.  Finally, keywords should be full\nwords, not abbreviations.  Keywords and text are in the ISO 8859-1\n(Latin-1) character set (a superset of regular ASCII) and can not\ncontain NUL characters, and should not contain control or other\nunprintable characters.  To make the comments widely readable, stick\nwith basic ASCII, and avoid machine specific character set extensions\nlike the IBM-PC character set.  The keyword must be present, but\nyou can leave off the text string on non-compressed pairs.\nCompressed pairs must have a text string, as only the text string\nis compressed anyway, so the compression would be meaningless.\n\nPNG supports modification time via the png_time structure.  Two\nconversion routines are provided, png_convert_from_time_t() for\ntime_t and png_convert_from_struct_tm() for struct tm.  The\ntime_t routine uses gmtime().  You don't have to use either of\nthese, but if you wish to fill in the png_time structure directly,\nyou should provide the time in universal time (GMT) if possible\ninstead of your local time.  Note that the year number is the full\nyear (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and\nthat months start with 1.\n\nIf you want to store the time of the original image creation, you should\nuse a plain tEXt chunk with the \"Creation Time\" keyword.  This is\nnecessary because the \"creation time\" of a PNG image is somewhat vague,\ndepending on whether you mean the PNG file, the time the image was\ncreated in a non-PNG format, a still photo from which the image was\nscanned, or possibly the subject matter itself.  In order to facilitate\nmachine-readable dates, it is recommended that the \"Creation Time\"\ntEXt chunk use RFC 1123 format dates (e.g. \"22 May 1997 18:07:10 GMT\"),\nalthough this isn't a requirement.  Unlike the tIME chunk, the\n\"Creation Time\" tEXt chunk is not expected to be automatically changed\nby the software.  To facilitate the use of RFC 1123 dates, a function\npng_convert_to_rfc1123_buffer(buffer, png_timep) is provided to\nconvert from PNG time to an RFC 1123 format string.  The caller must provide\na writeable buffer of at least 29 bytes.\n\nWriting unknown chunks\n\nYou can use the png_set_unknown_chunks function to queue up private chunks\nfor writing.  You give it a chunk name, location, raw data, and a size.  You\nalso must use png_set_keep_unknown_chunks() to ensure that libpng will\nhandle them.  That's all there is to it.  The chunks will be written by the\nnext following png_write_info_before_PLTE, png_write_info, or png_write_end\nfunction, depending upon the specified location.  Any chunks previously\nread into the info structure's unknown-chunk list will also be written out\nin a sequence that satisfies the PNG specification's ordering rules.\n\nHere is an example of writing two private chunks, prVt and miNE:\n\n    #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED\n    /* Set unknown chunk data */\n    png_unknown_chunk unk_chunk[2];\n    strcpy((char *) unk_chunk[0].name, \"prVt\";\n    unk_chunk[0].data = (unsigned char *) \"PRIVATE DATA\";\n    unk_chunk[0].size = strlen(unk_chunk[0].data)+1;\n    unk_chunk[0].location = PNG_HAVE_IHDR;\n    strcpy((char *) unk_chunk[1].name, \"miNE\";\n    unk_chunk[1].data = (unsigned char *) \"MY CHUNK DATA\";\n    unk_chunk[1].size = strlen(unk_chunk[0].data)+1;\n    unk_chunk[1].location = PNG_AFTER_IDAT;\n    png_set_unknown_chunks(write_ptr, write_info_ptr,\n        unk_chunk, 2);\n    /* Needed because miNE is not safe-to-copy */\n    png_set_keep_unknown_chunks(png, PNG_HANDLE_CHUNK_ALWAYS,\n       (png_bytep) \"miNE\", 1);\n    # if PNG_LIBPNG_VER < 10600\n      /* Deal with unknown chunk location bug in 1.5.x and earlier */\n      png_set_unknown_chunk_location(png, info, 0, PNG_HAVE_IHDR);\n      png_set_unknown_chunk_location(png, info, 1, PNG_AFTER_IDAT);\n    # endif\n    # if PNG_LIBPNG_VER < 10500\n      /* PNG_AFTER_IDAT writes two copies of the chunk prior to libpng-1.5.0,\n       * one before IDAT and another after IDAT, so don't use it; only use\n       * PNG_HAVE_IHDR location.  This call resets the location previously\n       * set by assignment and png_set_unknown_chunk_location() for chunk 1.\n       */\n      png_set_unknown_chunk_location(png, info, 1, PNG_HAVE_IHDR);\n    # endif\n    #endif\n\nThe high-level write interface\n\nAt this point there are two ways to proceed; through the high-level\nwrite interface, or through a sequence of low-level write operations.\nYou can use the high-level interface if your image data is present\nin the info structure.  All defined output\ntransformations are permitted, enabled by the following masks.\n\n    PNG_TRANSFORM_IDENTITY      No transformation\n    PNG_TRANSFORM_PACKING       Pack 1, 2 and 4-bit samples\n    PNG_TRANSFORM_PACKSWAP      Change order of packed\n                                pixels to LSB first\n    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images\n    PNG_TRANSFORM_SHIFT         Normalize pixels to the\n                                sBIT depth\n    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA\n                                to BGRA\n    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA\n                                to AG\n    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity\n                                to transparency\n    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples\n    PNG_TRANSFORM_STRIP_FILLER        Strip out filler\n                                      bytes (deprecated).\n    PNG_TRANSFORM_STRIP_FILLER_BEFORE Strip out leading\n                                      filler bytes\n    PNG_TRANSFORM_STRIP_FILLER_AFTER  Strip out trailing\n                                      filler bytes\n\nIf you have valid image data in the info structure (you can use\npng_set_rows() to put image data in the info structure), simply do this:\n\n    png_write_png(png_ptr, info_ptr, png_transforms, NULL)\n\nwhere png_transforms is an integer containing the bitwise OR of some set of\ntransformation flags.  This call is equivalent to png_write_info(),\nfollowed the set of transformations indicated by the transform mask,\nthen png_write_image(), and finally png_write_end().\n\n(The final parameter of this call is not yet used.  Someday it might point\nto transformation parameters required by some future output transform.)\n\nYou must use png_transforms and not call any png_set_transform() functions\nwhen you use png_write_png().\n\nThe low-level write interface\n\nIf you are going the low-level route instead, you are now ready to\nwrite all the file information up to the actual image data.  You do\nthis with a call to png_write_info().\n\n    png_write_info(png_ptr, info_ptr);\n\nNote that there is one transformation you may need to do before\npng_write_info().  In PNG files, the alpha channel in an image is the\nlevel of opacity.  If your data is supplied as a level of transparency,\nyou can invert the alpha channel before you write it, so that 0 is\nfully transparent and 255 (in 8-bit or paletted images) or 65535\n(in 16-bit images) is fully opaque, with\n\n    png_set_invert_alpha(png_ptr);\n\nThis must appear before png_write_info() instead of later with the\nother transformations because in the case of paletted images the tRNS\nchunk data has to be inverted before the tRNS chunk is written.  If\nyour image is not a paletted image, the tRNS data (which in such cases\nrepresents a single color to be rendered as transparent) won't need to\nbe changed, and you can safely do this transformation after your\npng_write_info() call.\n\nIf you need to write a private chunk that you want to appear before\nthe PLTE chunk when PLTE is present, you can write the PNG info in\ntwo steps, and insert code to write your own chunk between them:\n\n    png_write_info_before_PLTE(png_ptr, info_ptr);\n    png_set_unknown_chunks(png_ptr, info_ptr, ...);\n    png_write_info(png_ptr, info_ptr);\n\nAfter you've written the file information, you can set up the library\nto handle any special transformations of the image data.  The various\nways to transform the data will be described in the order that they\nshould occur.  This is important, as some of these change the color\ntype and/or bit depth of the data, and some others only work on\ncertain color types and bit depths.  Even though each transformation\nchecks to see if it has data that it can do something with, you should\nmake sure to only enable a transformation if it will be valid for the\ndata.  For example, don't swap red and blue on grayscale data.\n\nPNG files store RGB pixels packed into 3 or 6 bytes.  This code tells\nthe library to strip input data that has 4 or 8 bytes per pixel down\nto 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2\nbytes per pixel).\n\n    png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);\n\nwhere the 0 is unused, and the location is either PNG_FILLER_BEFORE or\nPNG_FILLER_AFTER, depending upon whether the filler byte in the pixel\nis stored XRGB or RGBX.\n\nPNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as\nthey can, resulting in, for example, 8 pixels per byte for 1 bit files.\nIf the data is supplied at 1 pixel per byte, use this code, which will\ncorrectly pack the pixels into a single byte:\n\n    png_set_packing(png_ptr);\n\nPNG files reduce possible bit depths to 1, 2, 4, 8, and 16.  If your\ndata is of another bit depth, you can write an sBIT chunk into the\nfile so that decoders can recover the original data if desired.\n\n    /* Set the true bit depth of the image data */\n    if (color_type & PNG_COLOR_MASK_COLOR)\n    {\n       sig_bit.red = true_bit_depth;\n       sig_bit.green = true_bit_depth;\n       sig_bit.blue = true_bit_depth;\n    }\n\n    else\n    {\n       sig_bit.gray = true_bit_depth;\n    }\n\n    if (color_type & PNG_COLOR_MASK_ALPHA)\n    {\n       sig_bit.alpha = true_bit_depth;\n    }\n\n    png_set_sBIT(png_ptr, info_ptr, &sig_bit);\n\nIf the data is stored in the row buffer in a bit depth other than\none supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG),\nthis will scale the values to appear to be the correct bit depth as\nis required by PNG.\n\n    png_set_shift(png_ptr, &sig_bit);\n\nPNG files store 16-bit pixels in network byte order (big-endian,\nie. most significant bits first).  This code would be used if they are\nsupplied the other way (little-endian, i.e. least significant bits\nfirst, the way PCs store them):\n\n    if (bit_depth > 8)\n       png_set_swap(png_ptr);\n\nIf you are using packed-pixel images (1, 2, or 4 bits/pixel), and you\nneed to change the order the pixels are packed into bytes, you can use:\n\n    if (bit_depth < 8)\n       png_set_packswap(png_ptr);\n\nPNG files store 3 color pixels in red, green, blue order.  This code\nwould be used if they are supplied as blue, green, red:\n\n    png_set_bgr(png_ptr);\n\nPNG files describe monochrome as black being zero and white being\none. This code would be used if the pixels are supplied with this reversed\n(black being one and white being zero):\n\n    png_set_invert_mono(png_ptr);\n\nFinally, you can write your own transformation function if none of\nthe existing ones meets your needs.  This is done by setting a callback\nwith\n\n    png_set_write_user_transform_fn(png_ptr,\n       write_transform_fn);\n\nYou must supply the function\n\n    void write_transform_fn(png_structp png_ptr, png_row_infop\n       row_info, png_bytep data)\n\nSee pngtest.c for a working example.  Your function will be called\nbefore any of the other transformations are processed.  If supported\nlibpng also supplies an information routine that may be called from\nyour callback:\n\n   png_get_current_row_number(png_ptr);\n   png_get_current_pass_number(png_ptr);\n\nThis returns the current row passed to the transform.  With interlaced\nimages the value returned is the row in the input sub-image image.  Use\nPNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to\nfind the output pixel (x,y) given an interlaced sub-image pixel (row,col,pass).\n\nThe discussion of interlace handling above contains more information on how to\nuse these values.\n\nYou can also set up a pointer to a user structure for use by your\ncallback function.\n\n    png_set_user_transform_info(png_ptr, user_ptr, 0, 0);\n\nThe user_channels and user_depth parameters of this function are ignored\nwhen writing; you can set them to zero as shown.\n\nYou can retrieve the pointer via the function png_get_user_transform_ptr().\nFor example:\n\n    voidp write_user_transform_ptr =\n       png_get_user_transform_ptr(png_ptr);\n\nIt is possible to have libpng flush any pending output, either manually,\nor automatically after a certain number of lines have been written.  To\nflush the output stream a single time call:\n\n    png_write_flush(png_ptr);\n\nand to have libpng flush the output stream periodically after a certain\nnumber of scanlines have been written, call:\n\n    png_set_flush(png_ptr, nrows);\n\nNote that the distance between rows is from the last time png_write_flush()\nwas called, or the first row of the image if it has never been called.\nSo if you write 50 lines, and then png_set_flush 25, it will flush the\noutput on the next scanline, and every 25 lines thereafter, unless\npng_write_flush() is called before 25 more lines have been written.\nIf nrows is too small (less than about 10 lines for a 640 pixel wide\nRGB image) the image compression may decrease noticeably (although this\nmay be acceptable for real-time applications).  Infrequent flushing will\nonly degrade the compression performance by a few percent over images\nthat do not use flushing.\n\nWriting the image data\n\nThat's it for the transformations.  Now you can write the image data.\nThe simplest way to do this is in one function call.  If you have the\nwhole image in memory, you can just call png_write_image() and libpng\nwill write the image.  You will need to pass in an array of pointers to\neach row.  This function automatically handles interlacing, so you don't\nneed to call png_set_interlace_handling() or call this function multiple\ntimes, or any of that other stuff necessary with png_write_rows().\n\n    png_write_image(png_ptr, row_pointers);\n\nwhere row_pointers is:\n\n    png_byte *row_pointers[height];\n\nYou can point to void or char or whatever you use for pixels.\n\nIf you don't want to write the whole image at once, you can\nuse png_write_rows() instead.  If the file is not interlaced,\nthis is simple:\n\n    png_write_rows(png_ptr, row_pointers,\n       number_of_rows);\n\nrow_pointers is the same as in the png_write_image() call.\n\nIf you are just writing one row at a time, you can do this with\na single row_pointer instead of an array of row_pointers:\n\n    png_bytep row_pointer = row;\n\n    png_write_row(png_ptr, row_pointer);\n\nWhen the file is interlaced, things can get a good deal more complicated.\nThe only currently (as of the PNG Specification version 1.2, dated July\n1999) defined interlacing scheme for PNG files is the \"Adam7\" interlace\nscheme, that breaks down an image into seven smaller images of varying\nsize.  libpng will build these images for you, or you can do them\nyourself.  If you want to build them yourself, see the PNG specification\nfor details of which pixels to write when.\n\nIf you don't want libpng to handle the interlacing details, just\nuse png_set_interlace_handling() and call png_write_rows() the\ncorrect number of times to write all the sub-images\n(png_set_interlace_handling() returns the number of sub-images.)\n\nIf you want libpng to build the sub-images, call this before you start\nwriting any rows:\n\n    number_of_passes = png_set_interlace_handling(png_ptr);\n\nThis will return the number of passes needed.  Currently, this is seven,\nbut may change if another interlace type is added.\n\nThen write the complete image number_of_passes times.\n\n    png_write_rows(png_ptr, row_pointers, number_of_rows);\n\nThink carefully before you write an interlaced image.  Typically code that\nreads such images reads all the image data into memory, uncompressed, before\ndoing any processing.  Only code that can display an image on the fly can\ntake advantage of the interlacing and even then the image has to be exactly\nthe correct size for the output device, because scaling an image requires\nadjacent pixels and these are not available until all the passes have been\nread.\n\nIf you do write an interlaced image you will hardly ever need to handle\nthe interlacing yourself.  Call png_set_interlace_handling() and use the\napproach described above.\n\nThe only time it is conceivable that you will really need to write an\ninterlaced image pass-by-pass is when you have read one pass by pass and\nmade some pixel-by-pixel transformation to it, as described in the read\ncode above.  In this case use the PNG_PASS_ROWS and PNG_PASS_COLS macros\nto determine the size of each sub-image in turn and simply write the rows\nyou obtained from the read code.\n\nFinishing a sequential write\n\nAfter you are finished writing the image, you should finish writing\nthe file.  If you are interested in writing comments or time, you should\npass an appropriately filled png_info pointer.  If you are not interested,\nyou can pass NULL.\n\n    png_write_end(png_ptr, info_ptr);\n\nWhen you are done, you can free all memory used by libpng like this:\n\n    png_destroy_write_struct(&png_ptr, &info_ptr);\n\nIt is also possible to individually free the info_ptr members that\npoint to libpng-allocated storage with the following function:\n\n    png_free_data(png_ptr, info_ptr, mask, seq)\n\n    mask  - identifies data to be freed, a mask\n            containing the bitwise OR of one or\n            more of\n              PNG_FREE_PLTE, PNG_FREE_TRNS,\n              PNG_FREE_HIST, PNG_FREE_ICCP,\n              PNG_FREE_PCAL, PNG_FREE_ROWS,\n              PNG_FREE_SCAL, PNG_FREE_SPLT,\n              PNG_FREE_TEXT, PNG_FREE_UNKN,\n            or simply PNG_FREE_ALL\n\n    seq   - sequence number of item to be freed\n            (-1 for all items)\n\nThis function may be safely called when the relevant storage has\nalready been freed, or has not yet been allocated, or was allocated\nby the user  and not by libpng,  and will in those cases do nothing.\nThe \"seq\" parameter is ignored if only one item of the selected data\ntype, such as PLTE, is allowed.  If \"seq\" is not -1, and multiple items\nare allowed for the data type identified in the mask, such as text or\nsPLT, only the n'th item in the structure is freed, where n is \"seq\".\n\nIf you allocated data such as a palette that you passed in to libpng\nwith png_set_*, you must not free it until just before the call to\npng_destroy_write_struct().\n\nThe default behavior is only to free data that was allocated internally\nby libpng.  This can be changed, so that libpng will not free the data,\nor so that it will free data that was allocated by the user with png_malloc()\nor png_calloc() and passed in via a png_set_*() function, with\n\n    png_data_freer(png_ptr, info_ptr, freer, mask)\n\n    freer  - one of\n               PNG_DESTROY_WILL_FREE_DATA\n               PNG_SET_WILL_FREE_DATA\n               PNG_USER_WILL_FREE_DATA\n\n    mask   - which data elements are affected\n             same choices as in png_free_data()\n\nFor example, to transfer responsibility for some data from a read structure\nto a write structure, you could use\n\n    png_data_freer(read_ptr, read_info_ptr,\n       PNG_USER_WILL_FREE_DATA,\n       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)\n\n    png_data_freer(write_ptr, write_info_ptr,\n       PNG_DESTROY_WILL_FREE_DATA,\n       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)\n\nthereby briefly reassigning responsibility for freeing to the user but\nimmediately afterwards reassigning it once more to the write_destroy\nfunction.  Having done this, it would then be safe to destroy the read\nstructure and continue to use the PLTE, tRNS, and hIST data in the write\nstructure.\n\nThis function only affects data that has already been allocated.\nYou can call this function before calling after the png_set_*() functions\nto control whether the user or png_destroy_*() is supposed to free the data.\nWhen the user assumes responsibility for libpng-allocated data, the\napplication must use\npng_free() to free it, and when the user transfers responsibility to libpng\nfor data that the user has allocated, the user must have used png_malloc()\nor png_calloc() to allocate it.\n\nIf you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword\nseparately, do not transfer responsibility for freeing text_ptr to libpng,\nbecause when libpng fills a png_text structure it combines these members with\nthe key member, and png_free_data() will free only text_ptr.key.  Similarly,\nif you transfer responsibility for free'ing text_ptr from libpng to your\napplication, your application must not separately free those members.\nFor a more compact example of writing a PNG image, see the file example.c.\n\nV. Simplified API\n\nThe simplified API, which became available in libpng-1.6.0, hides the details\nof both libpng and the PNG file format itself.\nIt allows PNG files to be read into a very limited number of\nin-memory bitmap formats or to be written from the same formats.  If these\nformats do not accommodate your needs then you can, and should, use the more\nsophisticated APIs above - these support a wide variety of in-memory formats\nand a wide variety of sophisticated transformations to those formats as well\nas a wide variety of APIs to manipulate ancilliary information.\n\nTo read a PNG file using the simplified API:\n\n  1) Declare a 'png_image' structure (see below) on the stack, set the\n     version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL\n     (this is REQUIRED, your program may crash if you don't do it.)\n\n  2) Call the appropriate png_image_begin_read... function.\n\n  3) Set the png_image 'format' member to the required sample format.\n\n  4) Allocate a buffer for the image and, if required, the color-map.\n\n  5) Call png_image_finish_read to read the image and, if required, the\n     color-map into your buffers.\n\nThere are no restrictions on the format of the PNG input itself; all valid\ncolor types, bit depths, and interlace methods are acceptable, and the\ninput image is transformed as necessary to the requested in-memory format\nduring the png_image_finish_read() step.  The only caveat is that if you\nrequest a color-mapped image from a PNG that is full-color or makes\ncomplex use of an alpha channel the transformation is extremely lossy and the\nresult may look terrible.\n\nTo write a PNG file using the simplified API:\n\n  1) Declare a 'png_image' structure on the stack and memset()\n     it to all zero.\n\n  2) Initialize the members of the structure that describe the\n     image, setting the 'format' member to the format of the\n     image samples.\n\n  3) Call the appropriate png_image_write... function with a\n     pointer to the image and, if necessary, the color-map to write\n     the PNG data.\n\npng_image is a structure that describes the in-memory format of an image\nwhen it is being read or defines the in-memory format of an image that you\nneed to write.  The \"png_image\" structure contains the following members:\n\n   png_controlp opaque  Initialize to NULL, free with png_image_free\n   png_uint_32  version Set to PNG_IMAGE_VERSION\n   png_uint_32  width   Image width in pixels (columns)\n   png_uint_32  height  Image height in pixels (rows)\n   png_uint_32  format  Image format as defined below\n   png_uint_32  flags   A bit mask containing informational flags\n   png_uint_32  colormap_entries; Number of entries in the color-map\n   png_uint_32  warning_or_error;\n   char         message[64];\n\nIn the event of an error or warning the \"warning_or_error\"\nfield will be set to a non-zero value and the 'message' field will contain\na '\\0' terminated string with the libpng error or warning message.  If both\nwarnings and an error were encountered, only the error is recorded.  If there\nare multiple warnings, only the first one is recorded.\n\nThe upper 30 bits of the \"warning_or_error\" value are reserved; the low two\nbits contain a two bit code such that a value more than 1 indicates a failure\nin the API just called:\n\n   0 - no warning or error\n   1 - warning\n   2 - error\n   3 - error preceded by warning\n\nThe pixels (samples) of the image have one to four channels whose components\nhave original values in the range 0 to 1.0:\n\n  1: A single gray or luminance channel (G).\n  2: A gray/luminance channel and an alpha channel (GA).\n  3: Three red, green, blue color channels (RGB).\n  4: Three color channels and an alpha channel (RGBA).\n\nThe channels are encoded in one of two ways:\n\n  a) As a small integer, value 0..255, contained in a single byte.  For the\nalpha channel the original value is simply value/255.  For the color or\nluminance channels the value is encoded according to the sRGB specification\nand matches the 8-bit format expected by typical display devices.\n\nThe color/gray channels are not scaled (pre-multiplied) by the alpha\nchannel and are suitable for passing to color management software.\n\n  b) As a value in the range 0..65535, contained in a 2-byte integer, in\nthe native byte order of the platform on which the application is running.\nAll channels can be converted to the original value by dividing by 65535; all\nchannels are linear.  Color channels use the RGB encoding (RGB end-points) of\nthe sRGB specification.  This encoding is identified by the\nPNG_FORMAT_FLAG_LINEAR flag below.\n\nWhen the simplified API needs to convert between sRGB and linear colorspaces,\nthe actual sRGB transfer curve defined in the sRGB specification (see the\narticle at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2\napproximation used elsewhere in libpng.\n\nWhen an alpha channel is present it is expected to denote pixel coverage\nof the color or luminance channels and is returned as an associated alpha\nchannel: the color/gray channels are scaled (pre-multiplied) by the alpha\nvalue.\n\nThe samples are either contained directly in the image data, between 1 and 8\nbytes per pixel according to the encoding, or are held in a color-map indexed\nby bytes in the image data.  In the case of a color-map the color-map entries\nare individual samples, encoded as above, and the image data has one byte per\npixel to select the relevant sample from the color-map.\n\nPNG_FORMAT_*\n\nThe #defines to be used in png_image::format.  Each #define identifies a\nparticular layout of channel data and, if present, alpha values.  There are\nseparate defines for each of the two component encodings.\n\nA format is built up using single bit flag values.  All combinations are\nvalid.  Formats can be built up from the flag values or you can use one of\nthe predefined values below.  When testing formats always use the FORMAT_FLAG\nmacros to test for individual features - future versions of the library may\nadd new flags.\n\nWhen reading or writing color-mapped images the format should be set to the\nformat of the entries in the color-map then png_image_{read,write}_colormap\ncalled to read or write the color-map and set the format correctly for the\nimage data.  Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly!\n\nNOTE: libpng can be built with particular features disabled. If you see\ncompiler errors because the definition of one of the following flags has been\ncompiled out it is because libpng does not have the required support.  It is\npossible, however, for the libpng configuration to enable the format on just\nread or just write; in that case you may see an error at run time.\nYou can guard against this by checking for the definition of the\nappropriate \"_SUPPORTED\" macro, one of:\n\n   PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED\n\n   PNG_FORMAT_FLAG_ALPHA    format with an alpha channel\n   PNG_FORMAT_FLAG_COLOR    color format: otherwise grayscale\n   PNG_FORMAT_FLAG_LINEAR   2-byte channels else 1-byte\n   PNG_FORMAT_FLAG_COLORMAP image data is color-mapped\n   PNG_FORMAT_FLAG_BGR      BGR colors, else order is RGB\n   PNG_FORMAT_FLAG_AFIRST   alpha channel comes first\n\nSupported formats are as follows.  Future versions of libpng may support more\nformats; for compatibility with older versions simply check if the format\nmacro is defined using #ifdef.  These defines describe the in-memory layout\nof the components of the pixels of the image.\n\nFirst the single byte (sRGB) formats:\n\n   PNG_FORMAT_GRAY\n   PNG_FORMAT_GA\n   PNG_FORMAT_AG\n   PNG_FORMAT_RGB\n   PNG_FORMAT_BGR\n   PNG_FORMAT_RGBA\n   PNG_FORMAT_ARGB\n   PNG_FORMAT_BGRA\n   PNG_FORMAT_ABGR\n\nThen the linear 2-byte formats.  When naming these \"Y\" is used to\nindicate a luminance (gray) channel.  The component order within the pixel\nis always the same - there is no provision for swapping the order of the\ncomponents in the linear format.  The components are 16-bit integers in\nthe native byte order for your platform, and there is no provision for\nswapping the bytes to a different endian condition.\n\n   PNG_FORMAT_LINEAR_Y\n   PNG_FORMAT_LINEAR_Y_ALPHA\n   PNG_FORMAT_LINEAR_RGB\n   PNG_FORMAT_LINEAR_RGB_ALPHA\n\nWith color-mapped formats the image data is one byte for each pixel. The byte\nis an index into the color-map which is formatted as above.  To obtain a\ncolor-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP\nto one of the above definitions, or you can use one of the definitions below.\n\n   PNG_FORMAT_RGB_COLORMAP\n   PNG_FORMAT_BGR_COLORMAP\n   PNG_FORMAT_RGBA_COLORMAP\n   PNG_FORMAT_ARGB_COLORMAP\n   PNG_FORMAT_BGRA_COLORMAP\n   PNG_FORMAT_ABGR_COLORMAP\n\nPNG_IMAGE macros\n\nThese are convenience macros to derive information from a png_image\nstructure.  The PNG_IMAGE_SAMPLE_ macros return values appropriate to the\nactual image sample values - either the entries in the color-map or the\npixels in the image.  The PNG_IMAGE_PIXEL_ macros return corresponding values\nfor the pixels and will always return 1 for color-mapped formats.  The\nremaining macros return information about the rows in the image and the\ncomplete image.\n\nNOTE: All the macros that take a png_image::format parameter are compile time\nconstants if the format parameter is, itself, a constant.  Therefore these\nmacros can be used in array declarations and case labels where required.\nSimilarly the macros are also pre-processor constants (sizeof is not used) so\nthey can be used in #if tests.\n\n  PNG_IMAGE_SAMPLE_CHANNELS(fmt)\n    Returns the total number of channels in a given format: 1..4\n\n  PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\n    Returns the size in bytes of a single component of a pixel or color-map\n    entry (as appropriate) in the image: 1 or 2.\n\n  PNG_IMAGE_SAMPLE_SIZE(fmt)\n    This is the size of the sample data for one sample.  If the image is\n    color-mapped it is the size of one color-map entry (and image pixels are\n    one byte in size), otherwise it is the size of one image pixel.\n\n  PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\n    The maximum size of the color-map required by the format expressed in a\n    count of components.  This can be used to compile-time allocate a\n    color-map:\n\n    png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)];\n\n    png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)];\n\n    Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the\n    information from one of the png_image_begin_read_ APIs and dynamically\n    allocate the required memory.\n\n  PNG_IMAGE_COLORMAP_SIZE(fmt)\n   The size of the color-map required by the format; this is the size of the\n   color-map buffer passed to the png_image_{read,write}_colormap APIs. It is\n   a fixed number determined by the format so can easily be allocated on the\n   stack if necessary.\n\nCorresponding information about the pixels\n\n  PNG_IMAGE_PIXEL_CHANNELS(fmt)\n   The number of separate channels (components) in a pixel; 1 for a\n   color-mapped image.\n\n  PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\\\n   The size, in bytes, of each component in a pixel; 1 for a color-mapped\n   image.\n\n  PNG_IMAGE_PIXEL_SIZE(fmt)\n   The size, in bytes, of a complete pixel; 1 for a color-mapped image.\n\nInformation about the whole row, or whole image\n\n  PNG_IMAGE_ROW_STRIDE(image)\n   Returns the total number of components in a single row of the image; this\n   is the minimum 'row stride', the minimum count of components between each\n   row.  For a color-mapped image this is the minimum number of bytes in a\n   row.\n\n   If you need the stride measured in bytes, row_stride_bytes is\n   PNG_IMAGE_ROW_STRIDE(image) * PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\n   plus any padding bytes that your application might need, for example\n   to start the next row on a 4-byte boundary.\n\n  PNG_IMAGE_BUFFER_SIZE(image, row_stride)\n   Return the size, in bytes, of an image buffer given a png_image and a row\n   stride - the number of components to leave space for in each row.\n\n  PNG_IMAGE_SIZE(image)\n   Return the size, in bytes, of the image in memory given just a png_image;\n   the row stride is the minimum stride required for the image.\n\n  PNG_IMAGE_COLORMAP_SIZE(image)\n   Return the size, in bytes, of the color-map of this image.  If the image\n   format is not a color-map format this will return a size sufficient for\n   256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if\n   you don't want to allocate a color-map in this case.\n\nPNG_IMAGE_FLAG_*\n\nFlags containing additional information about the image are held in\nthe 'flags' field of png_image.\n\n  PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB == 0x01\n    This indicates the the RGB values of the in-memory bitmap do not\n    correspond to the red, green and blue end-points defined by sRGB.\n\n  PNG_IMAGE_FLAG_FAST == 0x02\n   On write emphasise speed over compression; the resultant PNG file will be\n   larger but will be produced significantly faster, particular for large\n   images.  Do not use this option for images which will be distributed, only\n   used it when producing intermediate files that will be read back in\n   repeatedly.  For a typical 24-bit image the option will double the read\n   speed at the cost of increasing the image size by 25%, however for many\n   more compressible images the PNG file can be 10 times larger with only a\n   slight speed gain.\n\n  PNG_IMAGE_FLAG_16BIT_sRGB == 0x04\n    On read if the image is a 16-bit per component image and there is no gAMA\n    or sRGB chunk assume that the components are sRGB encoded.  Notice that\n    images output by the simplified API always have gamma information; setting\n    this flag only affects the interpretation of 16-bit images from an\n    external source.  It is recommended that the application expose this flag\n    to the user; the user can normally easily recognize the difference between\n    linear and sRGB encoding.  This flag has no effect on write - the data\n    passed to the write APIs must have the correct encoding (as defined\n    above.)\n\n    If the flag is not set (the default) input 16-bit per component data is\n    assumed to be linear.\n\n    NOTE: the flag can only be set after the png_image_begin_read_ call,\n    because that call initializes the 'flags' field.\n\nREAD APIs\n\n   The png_image passed to the read APIs must have been initialized by setting\n   the png_controlp field 'opaque' to NULL (or, better, memset the whole thing.)\n\n   int png_image_begin_read_from_file( png_imagep image,\n     const char *file_name)\n\n     The named file is opened for read and the image header\n     is filled in from the PNG header in the file.\n\n   int png_image_begin_read_from_stdio (png_imagep image,\n     FILE* file)\n\n      The PNG header is read from the stdio FILE object.\n\n   int png_image_begin_read_from_memory(png_imagep image,\n      png_const_voidp memory, png_size_t size)\n\n      The PNG header is read from the given memory buffer.\n\n   int png_image_finish_read(png_imagep image,\n      png_colorp background, void *buffer,\n      png_int_32 row_stride, void *colormap));\n\n      Finish reading the image into the supplied buffer and\n      clean up the png_image structure.\n\n      row_stride is the step, in png_byte or png_uint_16 units\n      as appropriate, between adjacent rows.  A positive stride\n      indicates that the top-most row is first in the buffer -\n      the normal top-down arrangement.  A negative stride\n      indicates that the bottom-most row is first in the buffer.\n\n      background need only be supplied if an alpha channel must\n      be removed from a png_byte format and the removal is to be\n      done by compositing on a solid color; otherwise it may be\n      NULL and any composition will be done directly onto the\n      buffer.  The value is an sRGB color to use for the\n      background, for grayscale output the green channel is used.\n\n      For linear output removing the alpha channel is always done\n      by compositing on black.\n\n   void png_image_free(png_imagep image)\n\n      Free any data allocated by libpng in image->opaque,\n      setting the pointer to NULL.  May be called at any time\n      after the structure is initialized.\n\nWhen the simplified API needs to convert between sRGB and linear colorspaces,\nthe actual sRGB transfer curve defined in the sRGB specification (see the\narticle at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2\napproximation used elsewhere in libpng.\n\nWRITE APIS\n\nFor write you must initialize a png_image structure to describe the image to\nbe written:\n\n   version: must be set to PNG_IMAGE_VERSION\n   opaque: must be initialized to NULL\n   width: image width in pixels\n   height: image height in rows\n   format: the format of the data you wish to write\n   flags: set to 0 unless one of the defined flags applies; set\n      PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images\n      where the RGB values do not correspond to the colors in sRGB.\n   colormap_entries: set to the number of entries in the color-map (0 to 256)\n\n   int png_image_write_to_file, (png_imagep image,\n      const char *file, int convert_to_8bit, const void *buffer,\n      png_int_32 row_stride, const void *colormap));\n\n      Write the image to the named file.\n\n   int png_image_write_to_memory (png_imagep image, void *memory,\n      png_alloc_size_t * PNG_RESTRICT memory_bytes,\n      int convert_to_8_bit, const void *buffer, ptrdiff_t row_stride,\n      const void *colormap));\n\n      Write the image to memory.\n\n   int png_image_write_to_stdio(png_imagep image, FILE *file,\n      int convert_to_8_bit, const void *buffer,\n      png_int_32 row_stride, const void *colormap)\n\n      Write the image to the given (FILE*).\n\nWith all write APIs if image is in one of the linear formats with\n(png_uint_16) data then setting convert_to_8_bit will cause the output to be\na (png_byte) PNG gamma encoded according to the sRGB specification, otherwise\na 16-bit linear encoded PNG file is written.\n\nWith all APIs row_stride is handled as in the read APIs - it is the spacing\nfrom one row to the next in component sized units (float) and if negative\nindicates a bottom-up row layout in the buffer.  If you pass zero, libpng will\ncalculate the row_stride for you from the width and number of channels.\n\nNote that the write API does not support interlacing, sub-8-bit pixels,\nindexed (paletted) images, or most ancillary chunks.\n\nVI. Modifying/Customizing libpng\n\nThere are two issues here.  The first is changing how libpng does\nstandard things like memory allocation, input/output, and error handling.\nThe second deals with more complicated things like adding new chunks,\nadding new transformations, and generally changing how libpng works.\nBoth of those are compile-time issues; that is, they are generally\ndetermined at the time the code is written, and there is rarely a need\nto provide the user with a means of changing them.\n\nMemory allocation, input/output, and error handling\n\nAll of the memory allocation, input/output, and error handling in libpng\ngoes through callbacks that are user-settable.  The default routines are\nin pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively.  To change\nthese functions, call the appropriate png_set_*_fn() function.\n\nMemory allocation is done through the functions png_malloc(), png_calloc(),\nand png_free().  The png_malloc() and png_free() functions currently just\ncall the standard C functions and png_calloc() calls png_malloc() and then\nclears the newly allocated memory to zero; note that png_calloc(png_ptr, size)\nis not the same as the calloc(number, size) function provided by stdlib.h.\nThere is limited support for certain systems with segmented memory\narchitectures and the types of pointers declared by png.h match this; you\nwill have to use appropriate pointers in your application.  If you prefer\nto use a different method of allocating and freeing data, you can use\npng_create_read_struct_2() or png_create_write_struct_2() to register your\nown functions as described above.  These functions also provide a void\npointer that can be retrieved via\n\n    mem_ptr=png_get_mem_ptr(png_ptr);\n\nYour replacement memory functions must have prototypes as follows:\n\n    png_voidp malloc_fn(png_structp png_ptr,\n       png_alloc_size_t size);\n\n    void free_fn(png_structp png_ptr, png_voidp ptr);\n\nYour malloc_fn() must return NULL in case of failure.  The png_malloc()\nfunction will normally call png_error() if it receives a NULL from the\nsystem memory allocator or from your replacement malloc_fn().\n\nYour free_fn() will never be called with a NULL ptr, since libpng's\npng_free() checks for NULL before calling free_fn().\n\nInput/Output in libpng is done through png_read() and png_write(),\nwhich currently just call fread() and fwrite().  The FILE * is stored in\npng_struct and is initialized via png_init_io().  If you wish to change\nthe method of I/O, the library supplies callbacks that you can set\nthrough the function png_set_read_fn() and png_set_write_fn() at run\ntime, instead of calling the png_init_io() function.  These functions\nalso provide a void pointer that can be retrieved via the function\npng_get_io_ptr().  For example:\n\n    png_set_read_fn(png_structp read_ptr,\n        voidp read_io_ptr, png_rw_ptr read_data_fn)\n\n    png_set_write_fn(png_structp write_ptr,\n        voidp write_io_ptr, png_rw_ptr write_data_fn,\n        png_flush_ptr output_flush_fn);\n\n    voidp read_io_ptr = png_get_io_ptr(read_ptr);\n    voidp write_io_ptr = png_get_io_ptr(write_ptr);\n\nThe replacement I/O functions must have prototypes as follows:\n\n    void user_read_data(png_structp png_ptr,\n        png_bytep data, png_size_t length);\n\n    void user_write_data(png_structp png_ptr,\n        png_bytep data, png_size_t length);\n\n    void user_flush_data(png_structp png_ptr);\n\nThe user_read_data() function is responsible for detecting and\nhandling end-of-data errors.\n\nSupplying NULL for the read, write, or flush functions sets them back\nto using the default C stream functions, which expect the io_ptr to\npoint to a standard *FILE structure.  It is probably a mistake\nto use NULL for one of write_data_fn and output_flush_fn but not both\nof them, unless you have built libpng with PNG_NO_WRITE_FLUSH defined.\nIt is an error to read from a write stream, and vice versa.\n\nError handling in libpng is done through png_error() and png_warning().\nErrors handled through png_error() are fatal, meaning that png_error()\nshould never return to its caller.  Currently, this is handled via\nsetjmp() and longjmp() (unless you have compiled libpng with\nPNG_NO_SETJMP, in which case it is handled via PNG_ABORT()),\nbut you could change this to do things like exit() if you should wish,\nas long as your function does not return.\n\nOn non-fatal errors, png_warning() is called\nto print a warning message, and then control returns to the calling code.\nBy default png_error() and png_warning() print a message on stderr via\nfprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined\n(because you don't want the messages) or PNG_NO_STDIO defined (because\nfprintf() isn't available).  If you wish to change the behavior of the error\nfunctions, you will need to set up your own message callbacks.  These\nfunctions are normally supplied at the time that the png_struct is created.\nIt is also possible to redirect errors and warnings to your own replacement\nfunctions after png_create_*_struct() has been called by calling:\n\n    png_set_error_fn(png_structp png_ptr,\n        png_voidp error_ptr, png_error_ptr error_fn,\n        png_error_ptr warning_fn);\n\n    png_voidp error_ptr = png_get_error_ptr(png_ptr);\n\nIf NULL is supplied for either error_fn or warning_fn, then the libpng\ndefault function will be used, calling fprintf() and/or longjmp() if a\nproblem is encountered.  The replacement error functions should have\nparameters as follows:\n\n    void user_error_fn(png_structp png_ptr,\n        png_const_charp error_msg);\n\n    void user_warning_fn(png_structp png_ptr,\n        png_const_charp warning_msg);\n\nThe motivation behind using setjmp() and longjmp() is the C++ throw and\ncatch exception handling methods.  This makes the code much easier to write,\nas there is no need to check every return code of every function call.\nHowever, there are some uncertainties about the status of local variables\nafter a longjmp, so the user may want to be careful about doing anything\nafter setjmp returns non-zero besides returning itself.  Consult your\ncompiler documentation for more details.  For an alternative approach, you\nmay wish to use the \"cexcept\" facility (see http://cexcept.sourceforge.net),\nwhich is illustrated in pngvalid.c and in contrib/visupng.\n\nBeginning in libpng-1.4.0, the png_set_benign_errors() API became available.\nYou can use this to handle certain errors (normally handled as errors)\nas warnings.\n\n    png_set_benign_errors (png_ptr, int allowed);\n\n    allowed: 0: treat png_benign_error() as an error.\n             1: treat png_benign_error() as a warning.\n\nAs of libpng-1.6.0, the default condition is to treat benign errors as\nwarnings while reading and as errors while writing.\n\nCustom chunks\n\nIf you need to read or write custom chunks, you may need to get deeper\ninto the libpng code.  The library now has mechanisms for storing\nand writing chunks of unknown type; you can even declare callbacks\nfor custom chunks.  However, this may not be good enough if the\nlibrary code itself needs to know about interactions between your\nchunk and existing `intrinsic' chunks.\n\nIf you need to write a new intrinsic chunk, first read the PNG\nspecification. Acquire a first level of understanding of how it works.\nPay particular attention to the sections that describe chunk names,\nand look at how other chunks were designed, so you can do things\nsimilarly.  Second, check out the sections of libpng that read and\nwrite chunks.  Try to find a chunk that is similar to yours and use\nit as a template.  More details can be found in the comments inside\nthe code.  It is best to handle private or unknown chunks in a generic method,\nvia callback functions, instead of by modifying libpng functions. This\nis illustrated in pngtest.c, which uses a callback function to handle a\nprivate \"vpAg\" chunk and the new \"sTER\" chunk, which are both unknown to\nlibpng.\n\nIf you wish to write your own transformation for the data, look through\nthe part of the code that does the transformations, and check out some of\nthe simpler ones to get an idea of how they work.  Try to find a similar\ntransformation to the one you want to add and copy off of it.  More details\ncan be found in the comments inside the code itself.\n\nConfiguring for gui/windowing platforms:\n\nYou will need to write new error and warning functions that use the GUI\ninterface, as described previously, and set them to be the error and\nwarning functions at the time that png_create_*_struct() is called,\nin order to have them available during the structure initialization.\nThey can be changed later via png_set_error_fn().  On some compilers,\nyou may also have to change the memory allocators (png_malloc, etc.).\n\nConfiguring zlib:\n\nThere are special functions to configure the compression.  Perhaps the\nmost useful one changes the compression level, which currently uses\ninput compression values in the range 0 - 9.  The library normally\nuses the default compression level (Z_DEFAULT_COMPRESSION = 6).  Tests\nhave shown that for a large majority of images, compression values in\nthe range 3-6 compress nearly as well as higher levels, and do so much\nfaster.  For online applications it may be desirable to have maximum speed\n(Z_BEST_SPEED = 1).  With versions of zlib after v0.99, you can also\nspecify no compression (Z_NO_COMPRESSION = 0), but this would create\nfiles larger than just storing the raw bitmap.  You can specify the\ncompression level by calling:\n\n    #include zlib.h\n    png_set_compression_level(png_ptr, level);\n\nAnother useful one is to reduce the memory level used by the library.\nThe memory level defaults to 8, but it can be lowered if you are\nshort on memory (running DOS, for example, where you only have 640K).\nNote that the memory level does have an effect on compression; among\nother things, lower levels will result in sections of incompressible\ndata being emitted in smaller stored blocks, with a correspondingly\nlarger relative overhead of up to 15% in the worst case.\n\n    #include zlib.h\n    png_set_compression_mem_level(png_ptr, level);\n\nThe other functions are for configuring zlib.  They are not recommended\nfor normal use and may result in writing an invalid PNG file.  See\nzlib.h for more information on what these mean.\n\n    #include zlib.h\n    png_set_compression_strategy(png_ptr,\n        strategy);\n\n    png_set_compression_window_bits(png_ptr,\n        window_bits);\n\n    png_set_compression_method(png_ptr, method);\n\nThis controls the size of the IDAT chunks (default 8192):\n\n    png_set_compression_buffer_size(png_ptr, size);\n\nAs of libpng version 1.5.4, additional APIs became\navailable to set these separately for non-IDAT\ncompressed chunks such as zTXt, iTXt, and iCCP:\n\n    #include zlib.h\n    #if PNG_LIBPNG_VER >= 10504\n    png_set_text_compression_level(png_ptr, level);\n\n    png_set_text_compression_mem_level(png_ptr, level);\n\n    png_set_text_compression_strategy(png_ptr,\n        strategy);\n\n    png_set_text_compression_window_bits(png_ptr,\n        window_bits);\n\n    png_set_text_compression_method(png_ptr, method);\n    #endif\n\nControlling row filtering\n\nIf you want to control whether libpng uses filtering or not, which\nfilters are used, and how it goes about picking row filters, you\ncan call one of these functions.  The selection and configuration\nof row filters can have a significant impact on the size and\nencoding speed and a somewhat lesser impact on the decoding speed\nof an image.  Filtering is enabled by default for RGB and grayscale\nimages (with and without alpha), but not for paletted images nor\nfor any images with bit depths less than 8 bits/pixel.\n\nThe 'method' parameter sets the main filtering method, which is\ncurrently only '0' in the PNG 1.2 specification.  The 'filters'\nparameter sets which filter(s), if any, should be used for each\nscanline.  Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS\nto turn filtering on and off, respectively.\n\nIndividual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,\nPNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise\nORed together with '|' to specify one or more filters to use.\nThese filters are described in more detail in the PNG specification.\nIf you intend to change the filter type during the course of writing\nthe image, you should start with flags set for all of the filters\nyou intend to use so that libpng can initialize its internal\nstructures appropriately for all of the filter types.  (Note that this\nmeans the first row must always be adaptively filtered, because libpng\ncurrently does not allocate the filter buffers until png_write_row()\nis called for the first time.)\n\n    filters = PNG_FILTER_NONE | PNG_FILTER_SUB\n              PNG_FILTER_UP | PNG_FILTER_AVG |\n              PNG_FILTER_PAETH | PNG_ALL_FILTERS;\n\n    png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,\n       filters);\n              The second parameter can also be\n              PNG_INTRAPIXEL_DIFFERENCING if you are\n              writing a PNG to be embedded in a MNG\n              datastream.  This parameter must be the\n              same as the value of filter_method used\n              in png_set_IHDR().\n\nRequesting debug printout\n\nThe macro definition PNG_DEBUG can be used to request debugging\nprintout.  Set it to an integer value in the range 0 to 3.  Higher\nnumbers result in increasing amounts of debugging information.  The\ninformation is printed to the \"stderr\" file, unless another file\nname is specified in the PNG_DEBUG_FILE macro definition.\n\nWhen PNG_DEBUG > 0, the following functions (macros) become available:\n\n   png_debug(level, message)\n   png_debug1(level, message, p1)\n   png_debug2(level, message, p1, p2)\n\nin which \"level\" is compared to PNG_DEBUG to decide whether to print\nthe message, \"message\" is the formatted string to be printed,\nand p1 and p2 are parameters that are to be embedded in the string\naccording to printf-style formatting directives.  For example,\n\n   png_debug1(2, \"foo=%d\", foo);\n\nis expanded to\n\n   if (PNG_DEBUG > 2)\n      fprintf(PNG_DEBUG_FILE, \"foo=%d\\n\", foo);\n\nWhen PNG_DEBUG is defined but is zero, the macros aren't defined, but you\ncan still use PNG_DEBUG to control your own debugging:\n\n   #ifdef PNG_DEBUG\n       fprintf(stderr, ...\n   #endif\n\nWhen PNG_DEBUG = 1, the macros are defined, but only png_debug statements\nhaving level = 0 will be printed.  There aren't any such statements in\nthis version of libpng, but if you insert some they will be printed.\n\nVII.  MNG support\n\nThe MNG specification (available at http://www.libpng.org/pub/mng) allows\ncertain extensions to PNG for PNG images that are embedded in MNG datastreams.\nLibpng can support some of these extensions.  To enable them, use the\npng_permit_mng_features() function:\n\n   feature_set = png_permit_mng_features(png_ptr, mask)\n\n   mask is a png_uint_32 containing the bitwise OR of the\n        features you want to enable.  These include\n        PNG_FLAG_MNG_EMPTY_PLTE\n        PNG_FLAG_MNG_FILTER_64\n        PNG_ALL_MNG_FEATURES\n\n   feature_set is a png_uint_32 that is the bitwise AND of\n      your mask with the set of MNG features that is\n      supported by the version of libpng that you are using.\n\nIt is an error to use this function when reading or writing a standalone\nPNG file with the PNG 8-byte signature.  The PNG datastream must be wrapped\nin a MNG datastream.  As a minimum, it must have the MNG 8-byte signature\nand the MHDR and MEND chunks.  Libpng does not provide support for these\nor any other MNG chunks; your application must provide its own support for\nthem.  You may wish to consider using libmng (available at\nhttp://www.libmng.com) instead.\n\nVIII.  Changes to Libpng from version 0.88\n\nIt should be noted that versions of libpng later than 0.96 are not\ndistributed by the original libpng author, Guy Schalnat, nor by\nAndreas Dilger, who had taken over from Guy during 1996 and 1997, and\ndistributed versions 0.89 through 0.96, but rather by another member\nof the original PNG Group, Glenn Randers-Pehrson.  Guy and Andreas are\nstill alive and well, but they have moved on to other things.\n\nThe old libpng functions png_read_init(), png_write_init(),\npng_info_init(), png_read_destroy(), and png_write_destroy() have been\nmoved to PNG_INTERNAL in version 0.95 to discourage their use.  These\nfunctions will be removed from libpng version 1.4.0.\n\nThe preferred method of creating and initializing the libpng structures is\nvia the png_create_read_struct(), png_create_write_struct(), and\npng_create_info_struct() because they isolate the size of the structures\nfrom the application, allow version error checking, and also allow the\nuse of custom error handling routines during the initialization, which\nthe old functions do not.  The functions png_read_destroy() and\npng_write_destroy() do not actually free the memory that libpng\nallocated for these structs, but just reset the data structures, so they\ncan be used instead of png_destroy_read_struct() and\npng_destroy_write_struct() if you feel there is too much system overhead\nallocating and freeing the png_struct for each image read.\n\nSetting the error callbacks via png_set_message_fn() before\npng_read_init() as was suggested in libpng-0.88 is no longer supported\nbecause this caused applications that do not use custom error functions\nto fail if the png_ptr was not initialized to zero.  It is still possible\nto set the error callbacks AFTER png_read_init(), or to change them with\npng_set_error_fn(), which is essentially the same function, but with a new\nname to force compilation errors with applications that try to use the old\nmethod.\n\nSupport for the sCAL, iCCP, iTXt, and sPLT chunks was added at libpng-1.0.6;\nhowever, iTXt support was not enabled by default.\n\nStarting with version 1.0.7, you can find out which version of the library\nyou are using at run-time:\n\n   png_uint_32 libpng_vn = png_access_version_number();\n\nThe number libpng_vn is constructed from the major version, minor\nversion with leading zero, and release number with leading zero,\n(e.g., libpng_vn for version 1.0.7 is 10007).\n\nNote that this function does not take a png_ptr, so you can call it\nbefore you've created one.\n\nYou can also check which version of png.h you used when compiling your\napplication:\n\n   png_uint_32 application_vn = PNG_LIBPNG_VER;\n\nIX.  Changes to Libpng from version 1.0.x to 1.2.x\n\nSupport for user memory management was enabled by default.  To\naccomplish this, the functions png_create_read_struct_2(),\npng_create_write_struct_2(), png_set_mem_fn(), png_get_mem_ptr(),\npng_malloc_default(), and png_free_default() were added.\n\nSupport for the iTXt chunk has been enabled by default as of\nversion 1.2.41.\n\nSupport for certain MNG features was enabled.\n\nSupport for numbered error messages was added.  However, we never got\naround to actually numbering the error messages.  The function\npng_set_strip_error_numbers() was added (Note: the prototype for this\nfunction was inadvertently removed from png.h in PNG_NO_ASSEMBLER_CODE\nbuilds of libpng-1.2.15.  It was restored in libpng-1.2.36).\n\nThe png_malloc_warn() function was added at libpng-1.2.3.  This issues\na png_warning and returns NULL instead of aborting when it fails to\nacquire the requested memory allocation.\n\nSupport for setting user limits on image width and height was enabled\nby default.  The functions png_set_user_limits(), png_get_user_width_max(),\nand png_get_user_height_max() were added at libpng-1.2.6.\n\nThe png_set_add_alpha() function was added at libpng-1.2.7.\n\nThe function png_set_expand_gray_1_2_4_to_8() was added at libpng-1.2.9.\nUnlike png_set_gray_1_2_4_to_8(), the new function does not expand the\ntRNS chunk to alpha. The png_set_gray_1_2_4_to_8() function is\ndeprecated.\n\nA number of macro definitions in support of runtime selection of\nassembler code features (especially Intel MMX code support) were\nadded at libpng-1.2.0:\n\n    PNG_ASM_FLAG_MMX_SUPPORT_COMPILED\n    PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU\n    PNG_ASM_FLAG_MMX_READ_COMBINE_ROW\n    PNG_ASM_FLAG_MMX_READ_INTERLACE\n    PNG_ASM_FLAG_MMX_READ_FILTER_SUB\n    PNG_ASM_FLAG_MMX_READ_FILTER_UP\n    PNG_ASM_FLAG_MMX_READ_FILTER_AVG\n    PNG_ASM_FLAG_MMX_READ_FILTER_PAETH\n    PNG_ASM_FLAGS_INITIALIZED\n    PNG_MMX_READ_FLAGS\n    PNG_MMX_FLAGS\n    PNG_MMX_WRITE_FLAGS\n    PNG_MMX_FLAGS\n\nWe added the following functions in support of runtime\nselection of assembler code features:\n\n    png_get_mmx_flagmask()\n    png_set_mmx_thresholds()\n    png_get_asm_flags()\n    png_get_mmx_bitdepth_threshold()\n    png_get_mmx_rowbytes_threshold()\n    png_set_asm_flags()\n\nWe replaced all of these functions with simple stubs in libpng-1.2.20,\nwhen the Intel assembler code was removed due to a licensing issue.\n\nThese macros are deprecated:\n\n    PNG_READ_TRANSFORMS_NOT_SUPPORTED\n    PNG_PROGRESSIVE_READ_NOT_SUPPORTED\n    PNG_NO_SEQUENTIAL_READ_SUPPORTED\n    PNG_WRITE_TRANSFORMS_NOT_SUPPORTED\n    PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED\n    PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED\n\nThey have been replaced, respectively, by:\n\n    PNG_NO_READ_TRANSFORMS\n    PNG_NO_PROGRESSIVE_READ\n    PNG_NO_SEQUENTIAL_READ\n    PNG_NO_WRITE_TRANSFORMS\n    PNG_NO_READ_ANCILLARY_CHUNKS\n    PNG_NO_WRITE_ANCILLARY_CHUNKS\n\nPNG_MAX_UINT was replaced with PNG_UINT_31_MAX.  It has been\ndeprecated since libpng-1.0.16 and libpng-1.2.6.\n\nThe function\n    png_check_sig(sig, num)\nwas replaced with\n    !png_sig_cmp(sig, 0, num)\nIt has been deprecated since libpng-0.90.\n\nThe function\n    png_set_gray_1_2_4_to_8()\nwhich also expands tRNS to alpha was replaced with\n    png_set_expand_gray_1_2_4_to_8()\nwhich does not. It has been deprecated since libpng-1.0.18 and 1.2.9.\n\nX.  Changes to Libpng from version 1.0.x/1.2.x to 1.4.x\n\nPrivate libpng prototypes and macro definitions were moved from\npng.h and pngconf.h into a new pngpriv.h header file.\n\nFunctions png_set_benign_errors(), png_benign_error(), and\npng_chunk_benign_error() were added.\n\nSupport for setting the maximum amount of memory that the application\nwill allocate for reading chunks was added, as a security measure.\nThe functions png_set_chunk_cache_max() and png_get_chunk_cache_max()\nwere added to the library.\n\nWe implemented support for I/O states by adding png_ptr member io_state\nand functions png_get_io_chunk_name() and png_get_io_state() in pngget.c\n\nWe added PNG_TRANSFORM_GRAY_TO_RGB to the available high-level\ninput transforms.\n\nChecking for and reporting of errors in the IHDR chunk is more thorough.\n\nSupport for global arrays was removed, to improve thread safety.\n\nSome obsolete/deprecated macros and functions have been removed.\n\nTypecasted NULL definitions such as\n   #define png_voidp_NULL            (png_voidp)NULL\nwere eliminated.  If you used these in your application, just use\nNULL instead.\n\nThe png_struct and info_struct members \"trans\" and \"trans_values\" were\nchanged to \"trans_alpha\" and \"trans_color\", respectively.\n\nThe obsolete, unused pnggccrd.c and pngvcrd.c files and related makefiles\nwere removed.\n\nThe PNG_1_0_X and PNG_1_2_X macros were eliminated.\n\nThe PNG_LEGACY_SUPPORTED macro was eliminated.\n\nMany WIN32_WCE #ifdefs were removed.\n\nThe functions png_read_init(info_ptr), png_write_init(info_ptr),\npng_info_init(info_ptr), png_read_destroy(), and png_write_destroy()\nhave been removed.  They have been deprecated since libpng-0.95.\n\nThe png_permit_empty_plte() was removed. It has been deprecated\nsince libpng-1.0.9.  Use png_permit_mng_features() instead.\n\nWe removed the obsolete stub functions png_get_mmx_flagmask(),\npng_set_mmx_thresholds(), png_get_asm_flags(),\npng_get_mmx_bitdepth_threshold(), png_get_mmx_rowbytes_threshold(),\npng_set_asm_flags(), and png_mmx_supported()\n\nWe removed the obsolete png_check_sig(), png_memcpy_check(), and\npng_memset_check() functions.  Instead use !png_sig_cmp(), memcpy(),\nand memset(), respectively.\n\nThe function png_set_gray_1_2_4_to_8() was removed. It has been\ndeprecated since libpng-1.0.18 and 1.2.9, when it was replaced with\npng_set_expand_gray_1_2_4_to_8() because the former function also\nexpanded any tRNS chunk to an alpha channel.\n\nMacros for png_get_uint_16, png_get_uint_32, and png_get_int_32\nwere added and are used by default instead of the corresponding\nfunctions. Unfortunately,\nfrom libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the\nfunction) incorrectly returned a value of type png_uint_32.\n\nWe changed the prototype for png_malloc() from\n    png_malloc(png_structp png_ptr, png_uint_32 size)\nto\n    png_malloc(png_structp png_ptr, png_alloc_size_t size)\n\nThis also applies to the prototype for the user replacement malloc_fn().\n\nThe png_calloc() function was added and is used in place of\nof \"png_malloc(); memset();\" except in the case in png_read_png()\nwhere the array consists of pointers; in this case a \"for\" loop is used\nafter the png_malloc() to set the pointers to NULL, to give robust.\nbehavior in case the application runs out of memory part-way through\nthe process.\n\nWe changed the prototypes of png_get_compression_buffer_size() and\npng_set_compression_buffer_size() to work with png_size_t instead of\npng_uint_32.\n\nSupport for numbered error messages was removed by default, since we\nnever got around to actually numbering the error messages. The function\npng_set_strip_error_numbers() was removed from the library by default.\n\nThe png_zalloc() and png_zfree() functions are no longer exported.\nThe png_zalloc() function no longer zeroes out the memory that it\nallocates.  Applications that called png_zalloc(png_ptr, number, size)\ncan call png_calloc(png_ptr, number*size) instead, and can call\npng_free() instead of png_zfree().\n\nSupport for dithering was disabled by default in libpng-1.4.0, because\nit has not been well tested and doesn't actually \"dither\".\nThe code was not\nremoved, however, and could be enabled by building libpng with\nPNG_READ_DITHER_SUPPORTED defined.  In libpng-1.4.2, this support\nwas re-enabled, but the function was renamed png_set_quantize() to\nreflect more accurately what it actually does.  At the same time,\nthe PNG_DITHER_[RED,GREEN_BLUE]_BITS macros were also renamed to\nPNG_QUANTIZE_[RED,GREEN,BLUE]_BITS, and PNG_READ_DITHER_SUPPORTED\nwas renamed to PNG_READ_QUANTIZE_SUPPORTED.\n\nWe removed the trailing '.' from the warning and error messages.\n\nXI.  Changes to Libpng from version 1.4.x to 1.5.x\n\nFrom libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the\nfunction) incorrectly returned a value of type png_uint_32.\nThe incorrect macro was removed from libpng-1.4.5.\n\nChecking for invalid palette index on write was added at libpng\n1.5.10.  If a pixel contains an invalid (out-of-range) index libpng issues\na benign error.  This is enabled by default because this condition is an\nerror according to the PNG specification, Clause 11.3.2, but the error can\nbe ignored in each png_ptr with\n\n   png_set_check_for_invalid_index(png_ptr, allowed);\n\n      allowed  - one of\n                 0: disable benign error (accept the\n                    invalid data without warning).\n                 1: enable benign error (treat the\n                    invalid data as an error or a\n                    warning).\n\nIf the error is ignored, or if png_benign_error() treats it as a warning,\nany invalid pixels are decoded as opaque black by the decoder and written\nas-is by the encoder.\n\nRetrieving the maximum palette index found was added at libpng-1.5.15.\nThis statement must appear after png_read_png() or png_read_image() while\nreading, and after png_write_png() or png_write_image() while writing.\n\n   int max_palette = png_get_palette_max(png_ptr, info_ptr);\n\nThis will return the maximum palette index found in the image, or \"-1\" if\nthe palette was not checked, or \"0\" if no palette was found.  Note that this\ndoes not account for any palette index used by ancillary chunks such as the\nbKGD chunk; you must check those separately to determine the maximum\npalette index actually used.\n\nThere are no substantial API changes between the non-deprecated parts of\nthe 1.4.5 API and the 1.5.0 API; however, the ability to directly access\nmembers of the main libpng control structures, png_struct and png_info,\ndeprecated in earlier versions of libpng, has been completely removed from\nlibpng 1.5, and new private \"pngstruct.h\", \"pnginfo.h\", and \"pngdebug.h\"\nheader files were created.\n\nWe no longer include zlib.h in png.h.  The include statement has been moved\nto pngstruct.h, where it is not accessible by applications. Applications that\nneed access to information in zlib.h will need to add the '#include \"zlib.h\"'\ndirective.  It does not matter whether this is placed prior to or after\nthe '\"#include png.h\"' directive.\n\nThe png_sprintf(), png_strcpy(), and png_strncpy() macros are no longer used\nand were removed.\n\nWe moved the png_strlen(), png_memcpy(), png_memset(), and png_memcmp()\nmacros into a private header file (pngpriv.h) that is not accessible to\napplications.\n\nIn png_get_iCCP, the type of \"profile\" was changed from png_charpp\nto png_bytepp, and in png_set_iCCP, from png_charp to png_const_bytep.\n\nThere are changes of form in png.h, including new and changed macros to\ndeclare parts of the API.  Some API functions with arguments that are\npointers to data not modified within the function have been corrected to\ndeclare these arguments with PNG_CONST.\n\nMuch of the internal use of C macros to control the library build has also\nchanged and some of this is visible in the exported header files, in\nparticular the use of macros to control data and API elements visible\nduring application compilation may require significant revision to\napplication code.  (It is extremely rare for an application to do this.)\n\nAny program that compiled against libpng 1.4 and did not use deprecated\nfeatures or access internal library structures should compile and work\nagainst libpng 1.5, except for the change in the prototype for\npng_get_iCCP() and png_set_iCCP() API functions mentioned above.\n\nlibpng 1.5.0 adds PNG_ PASS macros to help in the reading and writing of\ninterlaced images.  The macros return the number of rows and columns in\neach pass and information that can be used to de-interlace and (if\nabsolutely necessary) interlace an image.\n\nlibpng 1.5.0 adds an API png_longjmp(png_ptr, value).  This API calls\nthe application-provided png_longjmp_ptr on the internal, but application\ninitialized, longjmp buffer.  It is provided as a convenience to avoid\nthe need to use the png_jmpbuf macro, which had the unnecessary side\neffect of resetting the internal png_longjmp_ptr value.\n\nlibpng 1.5.0 includes a complete fixed point API.  By default this is\npresent along with the corresponding floating point API.  In general the\nfixed point API is faster and smaller than the floating point one because\nthe PNG file format used fixed point, not floating point.  This applies\neven if the library uses floating point in internal calculations.  A new\nmacro, PNG_FLOATING_ARITHMETIC_SUPPORTED, reveals whether the library\nuses floating point arithmetic (the default) or fixed point arithmetic\ninternally for performance critical calculations such as gamma correction.\nIn some cases, the gamma calculations may produce slightly different\nresults.  This has changed the results in png_rgb_to_gray and in alpha\ncomposition (png_set_background for example). This applies even if the\noriginal image was already linear (gamma == 1.0) and, therefore, it is\nnot necessary to linearize the image.  This is because libpng has *not*\nbeen changed to optimize that case correctly, yet.\n\nFixed point support for the sCAL chunk comes with an important caveat;\nthe sCAL specification uses a decimal encoding of floating point values\nand the accuracy of PNG fixed point values is insufficient for\nrepresentation of these values. Consequently a \"string\" API\n(png_get_sCAL_s and png_set_sCAL_s) is the only reliable way of reading\narbitrary sCAL chunks in the absence of either the floating point API or\ninternal floating point calculations.  Starting with libpng-1.5.0, both\nof these functions are present when PNG_sCAL_SUPPORTED is defined.  Prior\nto libpng-1.5.0, their presence also depended upon PNG_FIXED_POINT_SUPPORTED\nbeing defined and PNG_FLOATING_POINT_SUPPORTED not being defined.\n\nApplications no longer need to include the optional distribution header\nfile pngusr.h or define the corresponding macros during application\nbuild in order to see the correct variant of the libpng API.  From 1.5.0\napplication code can check for the corresponding _SUPPORTED macro:\n\n#ifdef PNG_INCH_CONVERSIONS_SUPPORTED\n   /* code that uses the inch conversion APIs. */\n#endif\n\nThis macro will only be defined if the inch conversion functions have been\ncompiled into libpng.  The full set of macros, and whether or not support\nhas been compiled in, are available in the header file pnglibconf.h.\nThis header file is specific to the libpng build.  Notice that prior to\n1.5.0 the _SUPPORTED macros would always have the default definition unless\nreset by pngusr.h or by explicit settings on the compiler command line.\nThese settings may produce compiler warnings or errors in 1.5.0 because\nof macro redefinition.\n\nApplications can now choose whether to use these macros or to call the\ncorresponding function by defining PNG_USE_READ_MACROS or\nPNG_NO_USE_READ_MACROS before including png.h.  Notice that this is\nonly supported from 1.5.0; defining PNG_NO_USE_READ_MACROS prior to 1.5.0\nwill lead to a link failure.\n\nPrior to libpng-1.5.4, the zlib compressor used the same set of parameters\nwhen compressing the IDAT data and textual data such as zTXt and iCCP.\nIn libpng-1.5.4 we reinitialized the zlib stream for each type of data.\nWe added five png_set_text_*() functions for setting the parameters to\nuse with textual data.\n\nPrior to libpng-1.5.4, the PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED\noption was off by default, and slightly inaccurate scaling occurred.\nThis option can no longer be turned off, and the choice of accurate\nor inaccurate 16-to-8 scaling is by using the new png_set_scale_16_to_8()\nAPI for accurate scaling or the old png_set_strip_16_to_8() API for simple\nchopping.  In libpng-1.5.4, the PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED\nmacro became PNG_READ_SCALE_16_TO_8_SUPPORTED, and the PNG_READ_16_TO_8\nmacro became PNG_READ_STRIP_16_TO_8_SUPPORTED, to enable the two\npng_set_*_16_to_8() functions separately.\n\nPrior to libpng-1.5.4, the png_set_user_limits() function could only be\nused to reduce the width and height limits from the value of\nPNG_USER_WIDTH_MAX and PNG_USER_HEIGHT_MAX, although this document said\nthat it could be used to override them.  Now this function will reduce or\nincrease the limits.\n\nStarting in libpng-1.5.10, the user limits can be set en masse with the\nconfiguration option PNG_SAFE_LIMITS_SUPPORTED.  If this option is enabled,\na set of \"safe\" limits is applied in pngpriv.h.  These can be overridden by\napplication calls to png_set_user_limits(), png_set_user_chunk_cache_max(),\nand/or png_set_user_malloc_max() that increase or decrease the limits.  Also,\nin libpng-1.5.10 the default width and height limits were increased\nfrom 1,000,000 to 0x7fffffff (i.e., made unlimited).  Therefore, the\nlimits are now\n                               default      safe\n   png_user_width_max        0x7fffffff    1,000,000\n   png_user_height_max       0x7fffffff    1,000,000\n   png_user_chunk_cache_max  0 (unlimited)   128\n   png_user_chunk_malloc_max 0 (unlimited) 8,000,000\n\nThe png_set_option() function (and the \"options\" member of the png struct) was\nadded to libpng-1.5.15, with option PNG_ARM_NEON.\n\nThe library now supports a complete fixed point implementation and can\nthus be used on systems that have no floating point support or very\nlimited or slow support.  Previously gamma correction, an essential part\nof complete PNG support, required reasonably fast floating point.\n\nAs part of this the choice of internal implementation has been made\nindependent of the choice of fixed versus floating point APIs and all the\nmissing fixed point APIs have been implemented.\n\nThe exact mechanism used to control attributes of API functions has\nchanged, as described in the INSTALL file.\n\nA new test program, pngvalid, is provided in addition to pngtest.\npngvalid validates the arithmetic accuracy of the gamma correction\ncalculations and includes a number of validations of the file format.\nA subset of the full range of tests is run when \"make check\" is done\n(in the 'configure' build.)  pngvalid also allows total allocated memory\nusage to be evaluated and performs additional memory overwrite validation.\n\nMany changes to individual feature macros have been made. The following\nare the changes most likely to be noticed by library builders who\nconfigure libpng:\n\n1) All feature macros now have consistent naming:\n\n#define PNG_NO_feature turns the feature off\n#define PNG_feature_SUPPORTED turns the feature on\n\npnglibconf.h contains one line for each feature macro which is either:\n\n#define PNG_feature_SUPPORTED\n\nif the feature is supported or:\n\n/*#undef PNG_feature_SUPPORTED*/\n\nif it is not.  Library code consistently checks for the 'SUPPORTED' macro.\nIt does not, and libpng applications should not, check for the 'NO' macro\nwhich will not normally be defined even if the feature is not supported.\nThe 'NO' macros are only used internally for setting or not setting the\ncorresponding 'SUPPORTED' macros.\n\nCompatibility with the old names is provided as follows:\n\nPNG_INCH_CONVERSIONS turns on PNG_INCH_CONVERSIONS_SUPPORTED\n\nAnd the following definitions disable the corresponding feature:\n\nPNG_SETJMP_NOT_SUPPORTED disables SETJMP\nPNG_READ_TRANSFORMS_NOT_SUPPORTED disables READ_TRANSFORMS\nPNG_NO_READ_COMPOSITED_NODIV disables READ_COMPOSITE_NODIV\nPNG_WRITE_TRANSFORMS_NOT_SUPPORTED disables WRITE_TRANSFORMS\nPNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED disables READ_ANCILLARY_CHUNKS\nPNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED disables WRITE_ANCILLARY_CHUNKS\n\nLibrary builders should remove use of the above, inconsistent, names.\n\n2) Warning and error message formatting was previously conditional on\nthe STDIO feature. The library has been changed to use the\nCONSOLE_IO feature instead. This means that if CONSOLE_IO is disabled\nthe library no longer uses the printf(3) functions, even though the\ndefault read/write implementations use (FILE) style stdio.h functions.\n\n3) Three feature macros now control the fixed/floating point decisions:\n\nPNG_FLOATING_POINT_SUPPORTED enables the floating point APIs\n\nPNG_FIXED_POINT_SUPPORTED enables the fixed point APIs; however, in\npractice these are normally required internally anyway (because the PNG\nfile format is fixed point), therefore in most cases PNG_NO_FIXED_POINT\nmerely stops the function from being exported.\n\nPNG_FLOATING_ARITHMETIC_SUPPORTED chooses between the internal floating\npoint implementation or the fixed point one.  Typically the fixed point\nimplementation is larger and slower than the floating point implementation\non a system that supports floating point; however, it may be faster on a\nsystem which lacks floating point hardware and therefore uses a software\nemulation.\n\n4) Added PNG_{READ,WRITE}_INT_FUNCTIONS_SUPPORTED.  This allows the\nfunctions to read and write ints to be disabled independently of\nPNG_USE_READ_MACROS, which allows libpng to be built with the functions\neven though the default is to use the macros - this allows applications\nto choose at app buildtime whether or not to use macros (previously\nimpossible because the functions weren't in the default build.)\n\nXII.  Changes to Libpng from version 1.5.x to 1.6.x\n\nA \"simplified API\" has been added (see documentation in png.h and a simple\nexample in contrib/examples/pngtopng.c).  The new publicly visible API\nincludes the following:\n\n   macros:\n     PNG_FORMAT_*\n     PNG_IMAGE_*\n   structures:\n     png_control\n     png_image\n   read functions\n     png_image_begin_read_from_file()\n     png_image_begin_read_from_stdio()\n     png_image_begin_read_from_memory()\n     png_image_finish_read()\n     png_image_free()\n   write functions\n     png_image_write_to_file()\n     png_image_write_to_memory()\n     png_image_write_to_stdio()\n\nStarting with libpng-1.6.0, you can configure libpng to prefix all exported\nsymbols, using the PNG_PREFIX macro.\n\nWe no longer include string.h in png.h.  The include statement has been moved\nto pngpriv.h, where it is not accessible by applications.  Applications that\nneed access to information in string.h must add an '#include <string.h>'\ndirective.  It does not matter whether this is placed prior to or after\nthe '#include \"png.h\"' directive.\n\nThe following API are now DEPRECATED:\n   png_info_init_3()\n   png_convert_to_rfc1123() which has been replaced\n     with png_convert_to_rfc1123_buffer()\n   png_malloc_default()\n   png_free_default()\n   png_reset_zstream()\n\nThe following have been removed:\n   png_get_io_chunk_name(), which has been replaced\n     with png_get_io_chunk_type().  The new\n     function returns a 32-bit integer instead of\n     a string.\n   The png_sizeof(), png_strlen(), png_memcpy(), png_memcmp(), and\n     png_memset() macros are no longer used in the libpng sources and\n     have been removed.  These had already been made invisible to applications\n     (i.e., defined in the private pngpriv.h header file) since libpng-1.5.0.\n\nThe signatures of many exported functions were changed, such that\n   png_structp became png_structrp or png_const_structrp\n   png_infop became png_inforp or png_const_inforp\nwhere \"rp\" indicates a \"restricted pointer\".\n\nDropped support for 16-bit platforms. The support for FAR/far types has\nbeen eliminated and the definition of png_alloc_size_t is now controlled\nby a flag so that 'small size_t' systems can select it if necessary.\n\nError detection in some chunks has improved; in particular the iCCP chunk\nreader now does pretty complete validation of the basic format.  Some bad\nprofiles that were previously accepted are now accepted with a warning or\nrejected, depending upon the png_set_benign_errors() setting, in particular\nthe very old broken Microsoft/HP 3144-byte sRGB profile.  Starting with\nlibpng-1.6.11, recognizing and checking sRGB profiles can be avoided by\nmeans of\n\n    #if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && \\\n        defined(PNG_SET_OPTION_SUPPORTED)\n       png_set_option(png_ptr, PNG_SKIP_sRGB_CHECK_PROFILE,\n           PNG_OPTION_ON);\n    #endif\n\nIt's not a good idea to do this if you are using the \"simplified API\",\nwhich needs to be able to recognize sRGB profiles conveyed via the iCCP\nchunk.\n\nThe PNG spec requirement that only grayscale profiles may appear in images\nwith color type 0 or 4 and that even if the image only contains gray pixels,\nonly RGB profiles may appear in images with color type 2, 3, or 6, is now\nenforced.  The sRGB chunk is allowed to appear in images with any color type\nand is interpreted by libpng to convey a one-tracer-curve gray profile or a\nthree-tracer-curve RGB profile as appropriate.\n\nLibpng 1.5.x erroneously used /MD for Debug DLL builds; if you used the debug\nbuilds in your app and you changed your app to use /MD you will need to\nchange it back to /MDd for libpng 1.6.x.\n\nPrior to libpng-1.6.0 a warning would be issued if the iTXt chunk contained\nan empty language field or an empty translated keyword.  Both of these\nare allowed by the PNG specification, so these warnings are no longer issued.\n\nThe library now issues an error if the application attempts to set a\ntransform after it calls png_read_update_info() or if it attempts to call\nboth png_read_update_info() and png_start_read_image() or to call either\nof them more than once.\n\nThe default condition for benign_errors is now to treat benign errors as\nwarnings while reading and as errors while writing.\n\nThe library now issues a warning if both background processing and RGB to\ngray are used when gamma correction happens. As with previous versions of\nthe library the results are numerically very incorrect in this case.\n\nThere are some minor arithmetic changes in some transforms such as\npng_set_background(), that might be detected by certain regression tests.\n\nUnknown chunk handling has been improved internally, without any API change.\nThis adds more correct option control of the unknown handling, corrects\na pre-existing bug where the per-chunk 'keep' setting is ignored, and makes\nit possible to skip IDAT chunks in the sequential reader.\n\nThe machine-generated configure files are no longer included in branches\nlibpng16 and later of the GIT repository.  They continue to be included\nin the tarball releases, however.\n\nLibpng-1.6.0 through 1.6.2 used the CMF bytes at the beginning of the IDAT\nstream to set the size of the sliding window for reading instead of using the\ndefault 32-kbyte sliding window size.  It was discovered that there are\nhundreds of PNG files in the wild that have incorrect CMF bytes that caused\nzlib to issue the \"invalid distance too far back\" error and reject the file.\nLibpng-1.6.3 and later calculate their own safe CMF from the image dimensions,\nprovide a way to revert to the libpng-1.5.x behavior (ignoring the CMF bytes\nand using a 32-kbyte sliding window), by using\n\n    png_set_option(png_ptr, PNG_MAXIMUM_INFLATE_WINDOW,\n        PNG_OPTION_ON);\n\nand provide a tool (contrib/tools/pngfix) for rewriting a PNG file while\noptimizing the CMF bytes in its IDAT chunk correctly.\n\nLibpng-1.6.0 and libpng-1.6.1 wrote uncompressed iTXt chunks with the wrong\nlength, which resulted in PNG files that cannot be read beyond the bad iTXt\nchunk.  This error was fixed in libpng-1.6.3, and a tool (called\ncontrib/tools/png-fix-itxt) has been added to the libpng distribution.\n\nStarting with libpng-1.6.17, the PNG_SAFE_LIMITS macro was eliminated\nand safe limits are used by default (users who need larger limits\ncan still override them at compile time or run time, as described above).\n\nThe new limits are\n                                default   spec limit\n   png_user_width_max         1,000,000  2,147,483,647\n   png_user_height_max        1,000,000  2,147,483,647\n   png_user_chunk_cache_max         128  unlimited\n   png_user_chunk_malloc_max  8,000,000  unlimited\n\nStarting with libpng-1.6.18, a PNG_RELEASE_BUILD macro was added, which allows\nlibrary builders to control compilation for an installed system (a release build).\nIt can be set for testing debug or beta builds to ensure that they will compile\nwhen the build type is switched to RC or STABLE. In essence this overrides the\nPNG_LIBPNG_BUILD_BASE_TYPE definition which is not directly user controllable.\n\nStarting with libpng-1.6.19, attempting to set an over-length PLTE chunk\nis an error. Previously this requirement of the PNG specification was not\nenforced, and the palette was always limited to 256 entries. An over-length\nPLTE chunk found in an input PNG is silently truncated.\n\nXIII.  Detecting libpng\n\nThe png_get_io_ptr() function has been present since libpng-0.88, has never\nchanged, and is unaffected by conditional compilation macros.  It is the\nbest choice for use in configure scripts for detecting the presence of any\nlibpng version since 0.88.  In an autoconf \"configure.in\" you could use\n\n    AC_CHECK_LIB(png, png_get_io_ptr, ...\n\nXV. Source code repository\n\nSince about February 2009, version 1.2.34, libpng has been under \"git\" source\ncontrol.  The git repository was built from old libpng-x.y.z.tar.gz files\ngoing back to version 0.70.  You can access the git repository (read only)\nat\n\n    git://git.code.sf.net/p/libpng/code\n\nor you can browse it with a web browser by selecting the \"code\" button at\n\n    https://sourceforge.net/projects/libpng\n\nPatches can be sent to glennrp at users.sourceforge.net or to\npng-mng-implement at lists.sourceforge.net or you can upload them to\nthe libpng bug tracker at\n\n    http://libpng.sourceforge.net\n\nWe also accept patches built from the tar or zip distributions, and\nsimple verbal discriptions of bug fixes, reported either to the\nSourceForge bug tracker, to the png-mng-implement at lists.sf.net\nmailing list, or directly to glennrp.\n\nXV. Coding style\n\nOur coding style is similar to the \"Allman\" style\n(See http://en.wikipedia.org/wiki/Indent_style#Allman_style), with curly\nbraces on separate lines:\n\n    if (condition)\n    {\n       action;\n    }\n\n    else if (another condition)\n    {\n       another action;\n    }\n\nThe braces can be omitted from simple one-line actions:\n\n    if (condition)\n       return (0);\n\nWe use 3-space indentation, except for continued statements which\nare usually indented the same as the first line of the statement\nplus four more spaces.\n\nFor macro definitions we use 2-space indentation, always leaving the \"#\"\nin the first column.\n\n    #ifndef PNG_NO_FEATURE\n    #  ifndef PNG_FEATURE_SUPPORTED\n    #    define PNG_FEATURE_SUPPORTED\n    #  endif\n    #endif\n\nComments appear with the leading \"/*\" at the same indentation as\nthe statement that follows the comment:\n\n    /* Single-line comment */\n    statement;\n\n    /* This is a multiple-line\n     * comment.\n     */\n    statement;\n\nVery short comments can be placed after the end of the statement\nto which they pertain:\n\n    statement;    /* comment */\n\nWe don't use C++ style (\"//\") comments. We have, however,\nused them in the past in some now-abandoned MMX assembler\ncode.\n\nFunctions and their curly braces are not indented, and\nexported functions are marked with PNGAPI:\n\n /* This is a public function that is visible to\n  * application programmers. It does thus-and-so.\n  */\n void PNGAPI\n png_exported_function(png_ptr, png_info, foo)\n {\n    body;\n }\n\nThe return type and decorations are placed on a separate line\nahead of the function name, as illustrated above.\n\nThe prototypes for all exported functions appear in png.h,\nabove the comment that says\n\n    /* Maintainer: Put new public prototypes here ... */\n\nWe mark all non-exported functions with \"/* PRIVATE */\"\":\n\n void /* PRIVATE */\n png_non_exported_function(png_ptr, png_info, foo)\n {\n    body;\n }\n\nThe prototypes for non-exported functions (except for those in\npngtest) appear in pngpriv.h above the comment that says\n\n  /* Maintainer: Put new private prototypes here ^ */\n\nTo avoid polluting the global namespace, the names of all exported\nfunctions and variables begin with \"png_\", and all publicly visible C\npreprocessor macros begin with \"PNG\".  We request that applications that\nuse libpng *not* begin any of their own symbols with either of these strings.\n\nWe put a space after the \"sizeof\" operator and we omit the\noptional parentheses around its argument when the argument\nis an expression, not a type name, and we always enclose the\nsizeof operator, with its argument, in parentheses:\n\n  (sizeof (png_uint_32))\n  (sizeof array)\n\nPrior to libpng-1.6.0 we used a \"png_sizeof()\" macro, formatted as\nthough it were a function.\n\nControl keywords if, for, while, and switch are always followed by a space\nto distinguish them from function calls, which have no trailing space. \n\nWe put a space after each comma and after each semicolon\nin \"for\" statements, and we put spaces before and after each\nC binary operator and after \"for\" or \"while\", and before\n\"?\".  We don't put a space between a typecast and the expression\nbeing cast, nor do we put one between a function name and the\nleft parenthesis that follows it:\n\n    for (i = 2; i > 0; --i)\n       y[i] = a(x) + (int)b;\n\nWe prefer #ifdef and #ifndef to #if defined() and #if !defined()\nwhen there is only one macro being tested.  We always use parentheses\nwith \"defined\".\n\nWe express integer constants that are used as bit masks in hex format,\nwith an even number of lower-case hex digits, and to make them unsigned\n(e.g., 0x00U, 0xffU, 0x0100U) and long if they are greater than 0x7fff\n(e.g., 0xffffUL).\n\nWe prefer to use underscores rather than camelCase in names, except\nfor a few type names that we inherit from zlib.h.\n\nWe prefer \"if (something != 0)\" and \"if (something == 0)\"\nover \"if (something)\" and if \"(!something)\", respectively.\n\nWe do not use the TAB character for indentation in the C sources.\n\nLines do not exceed 80 characters.\n\nOther rules can be inferred by inspecting the libpng source.\n\nXVI. Y2K Compliance in libpng\n\nSince the PNG Development group is an ad-hoc body, we can't make\nan official declaration.\n\nThis is your unofficial assurance that libpng from version 0.71 and\nupward through 1.6.22beta03 are Y2K compliant.  It is my belief that earlier\nversions were also Y2K compliant.\n\nLibpng only has two year fields.  One is a 2-byte unsigned integer\nthat will hold years up to 65535.  The other, which is deprecated,\nholds the date in text format, and will hold years up to 9999.\n\nThe integer is\n    \"png_uint_16 year\" in png_time_struct.\n\nThe string is\n    \"char time_buffer[29]\" in png_struct.  This is no longer used\nin libpng-1.6.x and will be removed from libpng-1.7.0.\n\nThere are seven time-related functions:\n\n    png_convert_to_rfc_1123_buffer() in png.c\n      (formerly png_convert_to_rfc_1152() in error, and\n      also formerly png_convert_to_rfc_1123())\n    png_convert_from_struct_tm() in pngwrite.c, called\n      in pngwrite.c\n    png_convert_from_time_t() in pngwrite.c\n    png_get_tIME() in pngget.c\n    png_handle_tIME() in pngrutil.c, called in pngread.c\n    png_set_tIME() in pngset.c\n    png_write_tIME() in pngwutil.c, called in pngwrite.c\n\nAll appear to handle dates properly in a Y2K environment.  The\npng_convert_from_time_t() function calls gmtime() to convert from system\nclock time, which returns (year - 1900), which we properly convert to\nthe full 4-digit year.  There is a possibility that applications using\nlibpng are not passing 4-digit years into the png_convert_to_rfc_1123()\nfunction, or that they are incorrectly passing only a 2-digit year\ninstead of \"year - 1900\" into the png_convert_from_struct_tm() function,\nbut this is not under our control.  The libpng documentation has always\nstated that it works with 4-digit years, and the APIs have been\ndocumented as such.\n\nThe tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned\ninteger to hold the year, and can hold years as large as 65535.\n\nzlib, upon which libpng depends, is also Y2K compliant.  It contains\nno date-related code.\n\n\n   Glenn Randers-Pehrson\n   libpng maintainer\n   PNG Development Group\n"
  },
  {
    "path": "atlas-aapt/external/libpng/libpng.3",
    "content": ".TH LIBPNG 3 \"February 19, 2016\"\n.SH NAME\nlibpng \\- Portable Network Graphics (PNG) Reference Library 1.6.22beta03\n.SH SYNOPSIS\n\\fB\n#include <png.h>\\fP\n\n\\fBpng_uint_32 png_access_version_number \\fI(void\\fP\\fB);\\fP\n\n\\fBvoid png_benign_error (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_charp \\fIerror\\fP\\fB);\\fP\n\n\\fBvoid png_build_grayscale_palette (int \\fP\\fIbit_depth\\fP\\fB, png_colorp \\fIpalette\\fP\\fB);\\fP\n\n\\fBpng_voidp png_calloc (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_alloc_size_t \\fIsize\\fP\\fB);\\fP\n\n\\fBvoid png_chunk_benign_error (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_charp \\fIerror\\fP\\fB);\\fP\n\n\\fBvoid png_chunk_error (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_charp \\fIerror\\fP\\fB);\\fP\n\n\\fBvoid png_chunk_warning (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_charp \\fImessage\\fP\\fB);\\fP\n\n\\fBvoid png_convert_from_struct_tm (png_timep \\fP\\fIptime\\fP\\fB, struct tm FAR * \\fIttime\\fP\\fB);\\fP\n\n\\fBvoid png_convert_from_time_t (png_timep \\fP\\fIptime\\fP\\fB, time_t \\fIttime\\fP\\fB);\\fP\n\n\\fBpng_charp png_convert_to_rfc1123 (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_timep \\fIptime\\fP\\fB);\\fP\n\n\\fBpng_infop png_create_info_struct (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_structp png_create_read_struct (png_const_charp \\fP\\fIuser_png_ver\\fP\\fB, png_voidp \\fP\\fIerror_ptr\\fP\\fB, png_error_ptr \\fP\\fIerror_fn\\fP\\fB, png_error_ptr \\fIwarn_fn\\fP\\fB);\\fP\n\n\\fBpng_structp png_create_read_struct_2 (png_const_charp \\fP\\fIuser_png_ver\\fP\\fB, png_voidp \\fP\\fIerror_ptr\\fP\\fB, png_error_ptr \\fP\\fIerror_fn\\fP\\fB, png_error_ptr \\fP\\fIwarn_fn\\fP\\fB, png_voidp \\fP\\fImem_ptr\\fP\\fB, png_malloc_ptr \\fP\\fImalloc_fn\\fP\\fB, png_free_ptr \\fIfree_fn\\fP\\fB);\\fP\n\n\\fBpng_structp png_create_write_struct (png_const_charp \\fP\\fIuser_png_ver\\fP\\fB, png_voidp \\fP\\fIerror_ptr\\fP\\fB, png_error_ptr \\fP\\fIerror_fn\\fP\\fB, png_error_ptr \\fIwarn_fn\\fP\\fB);\\fP\n\n\\fBpng_structp png_create_write_struct_2 (png_const_charp \\fP\\fIuser_png_ver\\fP\\fB, png_voidp \\fP\\fIerror_ptr\\fP\\fB, png_error_ptr \\fP\\fIerror_fn\\fP\\fB, png_error_ptr \\fP\\fIwarn_fn\\fP\\fB, png_voidp \\fP\\fImem_ptr\\fP\\fB, png_malloc_ptr \\fP\\fImalloc_fn\\fP\\fB, png_free_ptr \\fIfree_fn\\fP\\fB);\\fP\n\n\\fBvoid png_data_freer (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, int \\fP\\fIfreer\\fP\\fB, png_uint_32 \\fImask)\\fP\\fB);\\fP\n\n\\fBvoid png_destroy_info_struct (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infopp \\fIinfo_ptr_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_destroy_read_struct (png_structpp \\fP\\fIpng_ptr_ptr\\fP\\fB, png_infopp \\fP\\fIinfo_ptr_ptr\\fP\\fB, png_infopp \\fIend_info_ptr_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_destroy_write_struct (png_structpp \\fP\\fIpng_ptr_ptr\\fP\\fB, png_infopp \\fIinfo_ptr_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_err (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_error (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_charp \\fIerror\\fP\\fB);\\fP\n\n\\fBvoid png_free (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_voidp \\fIptr\\fP\\fB);\\fP\n\n\\fBvoid png_free_chunk_list (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_free_default (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_voidp \\fIptr\\fP\\fB);\\fP\n\n\\fBvoid png_free_data (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, int \\fInum\\fP\\fB);\\fP\n\n\\fBpng_byte png_get_bit_depth (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_bKGD (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_color_16p \\fI*background\\fP\\fB);\\fP\n\n\\fBpng_byte png_get_channels (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_cHRM (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, double \\fP\\fI*white_x\\fP\\fB, double \\fP\\fI*white_y\\fP\\fB, double \\fP\\fI*red_x\\fP\\fB, double \\fP\\fI*red_y\\fP\\fB, double \\fP\\fI*green_x\\fP\\fB, double \\fP\\fI*green_y\\fP\\fB, double \\fP\\fI*blue_x\\fP\\fB, double \\fI*blue_y\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_cHRM_fixed (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, png_uint_32 \\fP\\fI*white_x\\fP\\fB, png_uint_32 \\fP\\fI*white_y\\fP\\fB, png_uint_32 \\fP\\fI*red_x\\fP\\fB, png_uint_32 \\fP\\fI*red_y\\fP\\fB, png_uint_32 \\fP\\fI*green_x\\fP\\fB, png_uint_32 \\fP\\fI*green_y\\fP\\fB, png_uint_32 \\fP\\fI*blue_x\\fP\\fB, png_uint_32 \\fI*blue_y\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_cHRM_XYZ (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, double \\fP\\fI*red_X\\fP\\fB, double \\fP\\fI*red_Y\\fP\\fB, double \\fP\\fI*red_Z\\fP\\fB, double \\fP\\fI*green_X\\fP\\fB, double \\fP\\fI*green_Y\\fP\\fB, double \\fP\\fI*green_Z\\fP\\fB, double \\fP\\fI*blue_X\\fP\\fB, double \\fP\\fI*blue_Y\\fP\\fB, double \\fI*blue_Z\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_cHRM_XYZ_fixed (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, png_fixed_point \\fP\\fI*int_red_X\\fP\\fB, png_fixed_point \\fP\\fI*int_red_Y\\fP\\fB, png_fixed_point \\fP\\fI*int_red_Z\\fP\\fB, png_fixed_point \\fP\\fI*int_green_X\\fP\\fB, png_fixed_point \\fP\\fI*int_green_Y\\fP\\fB, png_fixed_point \\fP\\fI*int_green_Z\\fP\\fB, png_fixed_point \\fP\\fI*int_blue_X\\fP\\fB, png_fixed_point \\fP\\fI*int_blue_Y\\fP\\fB, png_fixed_point \\fI*int_blue_Z\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_chunk_cache_max (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_alloc_size_t png_get_chunk_malloc_max (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_byte png_get_color_type (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_compression_buffer_size (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_byte png_get_compression_type (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_byte png_get_copyright (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_current_row_number \\fI(png_const_structp\\fP\\fB);\\fP\n\n\\fBpng_byte png_get_current_pass_number \\fI(png_const_structp\\fP\\fB);\\fP\n\n\\fBpng_voidp png_get_error_ptr (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_byte png_get_filter_type (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_gAMA (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, double \\fI*file_gamma\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_gAMA_fixed (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, png_uint_32 \\fI*int_file_gamma\\fP\\fB);\\fP\n\n\\fBpng_byte png_get_header_ver (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_byte png_get_header_version (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_hIST (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, png_uint_16p \\fI*hist\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_iCCP (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, png_charpp \\fP\\fIname\\fP\\fB, int \\fP\\fI*compression_type\\fP\\fB, png_bytepp \\fP\\fIprofile\\fP\\fB, png_uint_32 \\fI*proflen\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_IHDR (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_uint_32 \\fP\\fI*width\\fP\\fB, png_uint_32 \\fP\\fI*height\\fP\\fB, int \\fP\\fI*bit_depth\\fP\\fB, int \\fP\\fI*color_type\\fP\\fB, int \\fP\\fI*interlace_type\\fP\\fB, int \\fP\\fI*compression_type\\fP\\fB, int \\fI*filter_type\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_image_height (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_image_width (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_int_32 png_get_int_32 (png_bytep \\fIbuf\\fP\\fB);\\fP\n\n\\fBpng_byte png_get_interlace_type (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_io_chunk_type (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_voidp png_get_io_ptr (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_io_state (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_byte png_get_libpng_ver (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBint png_get_palette_max(png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_voidp png_get_mem_ptr (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_oFFs (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, png_uint_32 \\fP\\fI*offset_x\\fP\\fB, png_uint_32 \\fP\\fI*offset_y\\fP\\fB, int \\fI*unit_type\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_pCAL (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, png_charp \\fP\\fI*purpose\\fP\\fB, png_int_32 \\fP\\fI*X0\\fP\\fB, png_int_32 \\fP\\fI*X1\\fP\\fB, int \\fP\\fI*type\\fP\\fB, int \\fP\\fI*nparams\\fP\\fB, png_charp \\fP\\fI*units\\fP\\fB, png_charpp \\fI*params\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_pHYs (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, png_uint_32 \\fP\\fI*res_x\\fP\\fB, png_uint_32 \\fP\\fI*res_y\\fP\\fB, int \\fI*unit_type\\fP\\fB);\\fP\n\n\\fBfloat png_get_pixel_aspect_ratio (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_pHYs_dpi (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, png_uint_32 \\fP\\fI*res_x\\fP\\fB, png_uint_32 \\fP\\fI*res_y\\fP\\fB, int \\fI*unit_type\\fP\\fB);\\fP\n\n\\fBpng_fixed_point png_get_pixel_aspect_ratio_fixed (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_pixels_per_inch (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_pixels_per_meter (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_voidp png_get_progressive_ptr (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_PLTE (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, png_colorp \\fP\\fI*palette\\fP\\fB, int \\fI*num_palette\\fP\\fB);\\fP\n\n\\fBpng_byte png_get_rgb_to_gray_status (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_rowbytes (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_bytepp png_get_rows (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_sBIT (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_color_8p \\fI*sig_bit\\fP\\fB);\\fP\n\n\\fBvoid png_get_sCAL (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, int* \\fP\\fIunit\\fP\\fB, double* \\fP\\fIwidth\\fP\\fB, double* \\fIheight\\fP\\fB);\\fP\n\n\\fBvoid png_get_sCAL_fixed (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, int* \\fP\\fIunit\\fP\\fB, png_fixed_pointp \\fP\\fIwidth\\fP\\fB, png_fixed_pointp \\fIheight\\fP\\fB);\\fP\n\n\\fBvoid png_get_sCAL_s (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, int* \\fP\\fIunit\\fP\\fB, png_charpp \\fP\\fIwidth\\fP\\fB, png_charpp \\fIheight\\fP\\fB);\\fP\n\n\\fBpng_bytep png_get_signature (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_sPLT (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, png_spalette_p \\fI*splt_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_sRGB (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, int \\fI*file_srgb_intent\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_text (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, png_textp \\fP\\fI*text_ptr\\fP\\fB, int \\fI*num_text\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_tIME (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_timep \\fI*mod_time\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_tRNS (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_bytep \\fP\\fI*trans_alpha\\fP\\fB, int \\fP\\fI*num_trans\\fP\\fB, png_color_16p \\fI*trans_color\\fP\\fB);\\fP\n\n\\fB/* This function is really an inline macro. \\fI*/\n\n\\fBpng_uint_16 png_get_uint_16 (png_bytep \\fIbuf\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_uint_31 (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_bytep \\fIbuf\\fP\\fB);\\fP\n\n\\fB/* This function is really an inline macro. \\fI*/\n\n\\fBpng_uint_32 png_get_uint_32 (png_bytep \\fIbuf\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_unknown_chunks (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, png_unknown_chunkpp \\fIunknowns\\fP\\fB);\\fP\n\n\\fBpng_voidp png_get_user_chunk_ptr (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_user_height_max (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_voidp png_get_user_transform_ptr (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_user_width_max (png_const_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_valid (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fP\\fIinfo_ptr\\fP\\fB, png_uint_32 \\fIflag\\fP\\fB);\\fP\n\n\\fBfloat png_get_x_offset_inches (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_fixed_point png_get_x_offset_inches_fixed (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_int_32 png_get_x_offset_microns (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_int_32 png_get_x_offset_pixels (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_x_pixels_per_inch (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_x_pixels_per_meter (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBfloat png_get_y_offset_inches (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_fixed_point png_get_y_offset_inches_fixed (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_int_32 png_get_y_offset_microns (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_int_32 png_get_y_offset_pixels (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_y_pixels_per_inch (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_get_y_pixels_per_meter (png_const_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBint png_handle_as_unknown (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_bytep \\fIchunk_name\\fP\\fB);\\fP\n\n\\fBint png_image_begin_read_from_file (png_imagep \\fP\\fIimage\\fP\\fB, const char \\fI*file_name\\fP\\fB);\\fP\n\n\\fBint png_image_begin_read_from_stdio (png_imagep \\fP\\fIimage\\fP\\fB, FILE* \\fIfile\\fP\\fB);\\fP\n\n\\fBint, png_image_begin_read_from_memory (png_imagep \\fP\\fIimage\\fP\\fB, png_const_voidp \\fP\\fImemory\\fP\\fB, png_size_t \\fIsize\\fP\\fB);\\fP\n\n\\fBint png_image_finish_read (png_imagep \\fP\\fIimage\\fP\\fB, png_colorp \\fP\\fIbackground\\fP\\fB, void \\fP\\fI*buffer\\fP\\fB, png_int_32 \\fP\\fIrow_stride\\fP\\fB, void \\fI*colormap\\fP\\fB);\\fP\n\n\\fBvoid png_image_free (png_imagep \\fIimage\\fP\\fB);\\fP\n\n\\fBint png_image_write_to_file (png_imagep \\fP\\fIimage\\fP\\fB, const char \\fP\\fI*file\\fP\\fB, int \\fP\\fIconvert_to_8bit\\fP\\fB, const void \\fP\\fI*buffer\\fP\\fB, png_int_32 \\fP\\fIrow_stride\\fP\\fB, void \\fI*colormap\\fP\\fB);\\fP\n\n\\fBint png_image_write_to_memory (png_imagep \\fP\\fIimage\\fP\\fB, void \\fP\\fI*memory\\fP\\fB, png_alloc_size_t * PNG_RESTRICT \\fP\\fImemory_bytes\\fP\\fB, int \\fP\\fIconvert_to_8_bit\\fP\\fB, const void \\fP\\fI*buffer\\fP\\fB, png_int_32 \\fP\\fIrow_stride\\fP\\fB, const void \\fI*colormap)\\fP\\fB);\\fP\n\n\\fBint png_image_write_to_stdio (png_imagep \\fP\\fIimage\\fP\\fB, FILE \\fP\\fI*file\\fP\\fB, int \\fP\\fIconvert_to_8_bit\\fP\\fB, const void \\fP\\fI*buffer\\fP\\fB, png_int_32 \\fP\\fIrow_stride\\fP\\fB, void \\fI*colormap)\\fP\\fB);\\fP\n\n\\fBvoid png_info_init_3 (png_infopp \\fP\\fIinfo_ptr\\fP\\fB, png_size_t \\fIpng_info_struct_size\\fP\\fB);\\fP\n\n\\fBvoid png_init_io (png_structp \\fP\\fIpng_ptr\\fP\\fB, FILE \\fI*fp\\fP\\fB);\\fP\n\n\\fBvoid png_longjmp (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fIval\\fP\\fB);\\fP\n\n\\fBpng_voidp png_malloc (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_alloc_size_t \\fIsize\\fP\\fB);\\fP\n\n\\fBpng_voidp png_malloc_default (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_alloc_size_t \\fIsize\\fP\\fB);\\fP\n\n\\fBpng_voidp png_malloc_warn (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_alloc_size_t \\fIsize\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_permit_mng_features (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_uint_32 \\fImng_features_permitted\\fP\\fB);\\fP\n\n\\fBvoid png_process_data (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_bytep \\fP\\fIbuffer\\fP\\fB, png_size_t \\fIbuffer_size\\fP\\fB);\\fP\n\n\\fBpng_size_t png_process_data_pause \\fP\\fI(png_structp\\fP\\fB, int \\fIsave\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_process_data_skip \\fI(png_structp\\fP\\fB);\\fP\n\n\\fBvoid png_progressive_combine_row (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_bytep \\fP\\fIold_row\\fP\\fB, png_bytep \\fInew_row\\fP\\fB);\\fP\n\n\\fBvoid png_read_end (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_read_image (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_bytepp \\fIimage\\fP\\fB);\\fP\n\n\\fBvoid png_read_info (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_read_png (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, int \\fP\\fItransforms\\fP\\fB, png_voidp \\fIparams\\fP\\fB);\\fP\n\n\\fBvoid png_read_row (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_bytep \\fP\\fIrow\\fP\\fB, png_bytep \\fIdisplay_row\\fP\\fB);\\fP\n\n\\fBvoid png_read_rows (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_bytepp \\fP\\fIrow\\fP\\fB, png_bytepp \\fP\\fIdisplay_row\\fP\\fB, png_uint_32 \\fInum_rows\\fP\\fB);\\fP\n\n\\fBvoid png_read_update_info (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBint png_reset_zstream (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_save_int_32 (png_bytep \\fP\\fIbuf\\fP\\fB, png_int_32 \\fIi\\fP\\fB);\\fP\n\n\\fBvoid png_save_uint_16 (png_bytep \\fP\\fIbuf\\fP\\fB, unsigned int \\fIi\\fP\\fB);\\fP\n\n\\fBvoid png_save_uint_32 (png_bytep \\fP\\fIbuf\\fP\\fB, png_uint_32 \\fIi\\fP\\fB);\\fP\n\n\\fBvoid png_set_add_alpha (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_uint_32 \\fP\\fIfiller\\fP\\fB, int \\fIflags\\fP\\fB);\\fP\n\n\\fBvoid png_set_alpha_mode (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fP\\fImode\\fP\\fB, double \\fIoutput_gamma\\fP\\fB);\\fP\n\n\\fBvoid png_set_alpha_mode_fixed (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fP\\fImode\\fP\\fB, png_fixed_point \\fIoutput_gamma\\fP\\fB);\\fP\n\n\\fBvoid png_set_background (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_color_16p \\fP\\fIbackground_color\\fP\\fB, int \\fP\\fIbackground_gamma_code\\fP\\fB, int \\fP\\fIneed_expand\\fP\\fB, double \\fIbackground_gamma\\fP\\fB);\\fP\n\n\\fBvoid png_set_background_fixed (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_color_16p \\fP\\fIbackground_color\\fP\\fB, int \\fP\\fIbackground_gamma_code\\fP\\fB, int \\fP\\fIneed_expand\\fP\\fB, png_uint_32 \\fIbackground_gamma\\fP\\fB);\\fP\n\n\\fBvoid png_set_benign_errors (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fIallowed\\fP\\fB);\\fP\n\n\\fBvoid png_set_bgr (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_bKGD (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_color_16p \\fIbackground\\fP\\fB);\\fP\n\n\\fBvoid png_set_check_for_invalid_index(png_structrp \\fP\\fIpng_ptr\\fP\\fB, int \\fIallowed\\fP\\fB);\\fP\n\n\\fBvoid png_set_cHRM (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, double \\fP\\fIwhite_x\\fP\\fB, double \\fP\\fIwhite_y\\fP\\fB, double \\fP\\fIred_x\\fP\\fB, double \\fP\\fIred_y\\fP\\fB, double \\fP\\fIgreen_x\\fP\\fB, double \\fP\\fIgreen_y\\fP\\fB, double \\fP\\fIblue_x\\fP\\fB, double \\fIblue_y\\fP\\fB);\\fP\n\n\\fBvoid png_set_cHRM_fixed (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_uint_32 \\fP\\fIwhite_x\\fP\\fB, png_uint_32 \\fP\\fIwhite_y\\fP\\fB, png_uint_32 \\fP\\fIred_x\\fP\\fB, png_uint_32 \\fP\\fIred_y\\fP\\fB, png_uint_32 \\fP\\fIgreen_x\\fP\\fB, png_uint_32 \\fP\\fIgreen_y\\fP\\fB, png_uint_32 \\fP\\fIblue_x\\fP\\fB, png_uint_32 \\fIblue_y\\fP\\fB);\\fP\n\n\\fBvoid png_set_cHRM_XYZ (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, double \\fP\\fIred_X\\fP\\fB, double \\fP\\fIred_Y\\fP\\fB, double \\fP\\fIred_Z\\fP\\fB, double \\fP\\fIgreen_X\\fP\\fB, double \\fP\\fIgreen_Y\\fP\\fB, double \\fP\\fIgreen_Z\\fP\\fB, double \\fP\\fIblue_X\\fP\\fB, double \\fP\\fIblue_Y\\fP\\fB, double \\fIblue_Z\\fP\\fB);\\fP\n\n\\fBvoid png_set_cHRM_XYZ_fixed (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_fixed_point \\fP\\fIint_red_X\\fP\\fB, png_fixed_point \\fP\\fIint_red_Y\\fP\\fB, png_fixed_point \\fP\\fIint_red_Z\\fP\\fB, png_fixed_point \\fP\\fIint_green_X\\fP\\fB, png_fixed_point \\fP\\fIint_green_Y\\fP\\fB, png_fixed_point \\fP\\fIint_green_Z\\fP\\fB, png_fixed_point \\fP\\fIint_blue_X\\fP\\fB, png_fixed_point \\fP\\fIint_blue_Y\\fP\\fB, png_fixed_point \\fIint_blue_Z\\fP\\fB);\\fP\n\n\\fBvoid png_set_chunk_cache_max (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_uint_32 \\fIuser_chunk_cache_max\\fP\\fB);\\fP\n\n\\fBvoid png_set_compression_level (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fIlevel\\fP\\fB);\\fP\n\n\\fBvoid png_set_compression_mem_level (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fImem_level\\fP\\fB);\\fP\n\n\\fBvoid png_set_compression_method (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fImethod\\fP\\fB);\\fP\n\n\\fBvoid png_set_compression_strategy (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fIstrategy\\fP\\fB);\\fP\n\n\\fBvoid png_set_compression_window_bits (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fIwindow_bits\\fP\\fB);\\fP\n\n\\fBvoid png_set_crc_action (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fP\\fIcrit_action\\fP\\fB, int \\fIancil_action\\fP\\fB);\\fP\n\n\\fBvoid png_set_error_fn (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_voidp \\fP\\fIerror_ptr\\fP\\fB, png_error_ptr \\fP\\fIerror_fn\\fP\\fB, png_error_ptr \\fIwarning_fn\\fP\\fB);\\fP\n\n\\fBvoid png_set_expand (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_expand_16 (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_expand_gray_1_2_4_to_8 (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_filler (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_uint_32 \\fP\\fIfiller\\fP\\fB, int \\fIflags\\fP\\fB);\\fP\n\n\\fBvoid png_set_filter (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fP\\fImethod\\fP\\fB, int \\fIfilters\\fP\\fB);\\fP\n\n\\fBvoid png_set_filter_heuristics (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fP\\fIheuristic_method\\fP\\fB, int \\fP\\fInum_weights\\fP\\fB, png_doublep \\fP\\fIfilter_weights\\fP\\fB, png_doublep \\fIfilter_costs\\fP\\fB);\\fP\n\n\\fBvoid png_set_filter_heuristics_fixed (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fP\\fIheuristic_method\\fP\\fB, int \\fP\\fInum_weights\\fP\\fB, png_fixed_point_p \\fP\\fIfilter_weights\\fP\\fB, png_fixed_point_p \\fIfilter_costs\\fP\\fB);\\fP\n\n\\fBvoid png_set_flush (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fInrows\\fP\\fB);\\fP\n\n\\fBvoid png_set_gamma (png_structp \\fP\\fIpng_ptr\\fP\\fB, double \\fP\\fIscreen_gamma\\fP\\fB, double \\fIdefault_file_gamma\\fP\\fB);\\fP\n\n\\fBvoid png_set_gamma_fixed (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_uint_32 \\fP\\fIscreen_gamma\\fP\\fB, png_uint_32 \\fIdefault_file_gamma\\fP\\fB);\\fP\n\n\\fBvoid png_set_gAMA (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, double \\fIfile_gamma\\fP\\fB);\\fP\n\n\\fBvoid png_set_gAMA_fixed (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_uint_32 \\fIfile_gamma\\fP\\fB);\\fP\n\n\\fBvoid png_set_gray_1_2_4_to_8 (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_gray_to_rgb (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_hIST (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_uint_16p \\fIhist\\fP\\fB);\\fP\n\n\\fBvoid png_set_iCCP (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_const_charp \\fP\\fIname\\fP\\fB, int \\fP\\fIcompression_type\\fP\\fB, png_const_bytep \\fP\\fIprofile\\fP\\fB, png_uint_32 \\fIproflen\\fP\\fB);\\fP\n\n\\fBint png_set_interlace_handling (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_invalid (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, int \\fImask\\fP\\fB);\\fP\n\n\\fBvoid png_set_invert_alpha (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_invert_mono (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_IHDR (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_uint_32 \\fP\\fIwidth\\fP\\fB, png_uint_32 \\fP\\fIheight\\fP\\fB, int \\fP\\fIbit_depth\\fP\\fB, int \\fP\\fIcolor_type\\fP\\fB, int \\fP\\fIinterlace_type\\fP\\fB, int \\fP\\fIcompression_type\\fP\\fB, int \\fIfilter_type\\fP\\fB);\\fP\n\n\\fBvoid png_set_keep_unknown_chunks (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fP\\fIkeep\\fP\\fB, png_bytep \\fP\\fIchunk_list\\fP\\fB, int \\fInum_chunks\\fP\\fB);\\fP\n\n\\fBjmp_buf* png_set_longjmp_fn (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_longjmp_ptr \\fP\\fIlongjmp_fn\\fP\\fB, size_t \\fIjmp_buf_size\\fP\\fB);\\fP\n\n\\fBvoid png_set_chunk_malloc_max (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_alloc_size_t \\fIuser_chunk_cache_max\\fP\\fB);\\fP\n\n\\fBvoid png_set_compression_buffer_size (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_uint_32 \\fIsize\\fP\\fB);\\fP\n\n\\fBvoid png_set_mem_fn (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_voidp \\fP\\fImem_ptr\\fP\\fB, png_malloc_ptr \\fP\\fImalloc_fn\\fP\\fB, png_free_ptr \\fIfree_fn\\fP\\fB);\\fP\n\n\\fBvoid png_set_oFFs (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_uint_32 \\fP\\fIoffset_x\\fP\\fB, png_uint_32 \\fP\\fIoffset_y\\fP\\fB, int \\fIunit_type\\fP\\fB);\\fP\n\n\\fBint png_set_option(png_structrp \\fP\\fIpng_ptr\\fP\\fB, int \\fP\\fIoption\\fP\\fB, int \\fIonoff\\fP\\fB);\\fP\n\n\\fBvoid png_set_packing (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_packswap (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_palette_to_rgb (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_pCAL (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_charp \\fP\\fIpurpose\\fP\\fB, png_int_32 \\fP\\fIX0\\fP\\fB, png_int_32 \\fP\\fIX1\\fP\\fB, int \\fP\\fItype\\fP\\fB, int \\fP\\fInparams\\fP\\fB, png_charp \\fP\\fIunits\\fP\\fB, png_charpp \\fIparams\\fP\\fB);\\fP\n\n\\fBvoid png_set_pHYs (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_uint_32 \\fP\\fIres_x\\fP\\fB, png_uint_32 \\fP\\fIres_y\\fP\\fB, int \\fIunit_type\\fP\\fB);\\fP\n\n\\fBvoid png_set_progressive_read_fn (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_voidp \\fP\\fIprogressive_ptr\\fP\\fB, png_progressive_info_ptr \\fP\\fIinfo_fn\\fP\\fB, png_progressive_row_ptr \\fP\\fIrow_fn\\fP\\fB, png_progressive_end_ptr \\fIend_fn\\fP\\fB);\\fP\n\n\\fBvoid png_set_PLTE (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_colorp \\fP\\fIpalette\\fP\\fB, int \\fInum_palette\\fP\\fB);\\fP\n\n\\fBvoid png_set_quantize (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_colorp \\fP\\fIpalette\\fP\\fB, int \\fP\\fInum_palette\\fP\\fB, int \\fP\\fImaximum_colors\\fP\\fB, png_uint_16p \\fP\\fIhistogram\\fP\\fB, int \\fIfull_quantize\\fP\\fB);\\fP\n\n\\fBvoid png_set_read_fn (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_voidp \\fP\\fIio_ptr\\fP\\fB, png_rw_ptr \\fIread_data_fn\\fP\\fB);\\fP\n\n\\fBvoid png_set_read_status_fn (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_read_status_ptr \\fIread_row_fn\\fP\\fB);\\fP\n\n\\fBvoid png_set_read_user_chunk_fn (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_voidp \\fP\\fIuser_chunk_ptr\\fP\\fB, png_user_chunk_ptr \\fIread_user_chunk_fn\\fP\\fB);\\fP\n\n\\fBvoid png_set_read_user_transform_fn (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_user_transform_ptr \\fIread_user_transform_fn\\fP\\fB);\\fP\n\n\\fBvoid png_set_rgb_to_gray (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fP\\fIerror_action\\fP\\fB, double \\fP\\fIred\\fP\\fB, double \\fIgreen\\fP\\fB);\\fP\n\n\\fBvoid png_set_rgb_to_gray_fixed (png_structp \\fP\\fIpng_ptr\\fP\\fB, int error_action png_uint_32 \\fP\\fIred\\fP\\fB, png_uint_32 \\fIgreen\\fP\\fB);\\fP\n\n\\fBvoid png_set_rows (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_bytepp \\fIrow_pointers\\fP\\fB);\\fP\n\n\\fBvoid png_set_sBIT (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_color_8p \\fIsig_bit\\fP\\fB);\\fP\n\n\\fBvoid png_set_sCAL (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, int \\fP\\fIunit\\fP\\fB, double \\fP\\fIwidth\\fP\\fB, double \\fIheight\\fP\\fB);\\fP\n\n\\fBvoid png_set_sCAL_fixed (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, int \\fP\\fIunit\\fP\\fB, png_fixed_point \\fP\\fIwidth\\fP\\fB, png_fixed_point \\fIheight\\fP\\fB);\\fP\n\n\\fBvoid png_set_sCAL_s (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, int \\fP\\fIunit\\fP\\fB, png_charp \\fP\\fIwidth\\fP\\fB, png_charp \\fIheight\\fP\\fB);\\fP\n\n\\fBvoid png_set_scale_16 (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_shift (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_color_8p \\fItrue_bits\\fP\\fB);\\fP\n\n\\fBvoid png_set_sig_bytes (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fInum_bytes\\fP\\fB);\\fP\n\n\\fBvoid png_set_sPLT (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_spalette_p \\fP\\fIsplt_ptr\\fP\\fB, int \\fInum_spalettes\\fP\\fB);\\fP\n\n\\fBvoid png_set_sRGB (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, int \\fIsrgb_intent\\fP\\fB);\\fP\n\n\\fBvoid png_set_sRGB_gAMA_and_cHRM (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, int \\fIsrgb_intent\\fP\\fB);\\fP\n\n\\fBvoid png_set_strip_16 (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_strip_alpha (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_strip_error_numbers (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_uint_32 \\fIstrip_mode\\fP\\fB);\\fP\n\n\\fBvoid png_set_swap (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_swap_alpha (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_set_text (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_textp \\fP\\fItext_ptr\\fP\\fB, int \\fInum_text\\fP\\fB);\\fP\n\n\\fBvoid png_set_text_compression_level (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fIlevel\\fP\\fB);\\fP\n\n\\fBvoid png_set_text_compression_mem_level (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fImem_level\\fP\\fB);\\fP\n\n\\fBvoid png_set_text_compression_strategy (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fIstrategy\\fP\\fB);\\fP\n\n\\fBvoid png_set_text_compression_window_bits (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fIwindow_bits\\fP\\fB);\\fP\n\n\\fBvoid \\fP\\fIpng_set_text_compression_method\\fP\\fB, (png_structp \\fP\\fIpng_ptr\\fP\\fB, int \\fImethod)\\fP\\fB);\\fP\n\n\\fBvoid png_set_tIME (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_timep \\fImod_time\\fP\\fB);\\fP\n\n\\fBvoid png_set_tRNS (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_bytep \\fP\\fItrans_alpha\\fP\\fB, int \\fP\\fInum_trans\\fP\\fB, png_color_16p \\fItrans_color\\fP\\fB);\\fP\n\n\\fBvoid png_set_tRNS_to_alpha (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBpng_uint_32 png_set_unknown_chunks (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, png_unknown_chunkp \\fP\\fIunknowns\\fP\\fB, int \\fP\\fInum\\fP\\fB, int \\fIlocation\\fP\\fB);\\fP\n\n\\fBvoid png_set_unknown_chunk_location (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, int \\fP\\fIchunk\\fP\\fB, int \\fIlocation\\fP\\fB);\\fP\n\n\\fBvoid png_set_user_limits (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_uint_32 \\fP\\fIuser_width_max\\fP\\fB, png_uint_32 \\fIuser_height_max\\fP\\fB);\\fP\n\n\\fBvoid png_set_user_transform_info (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_voidp \\fP\\fIuser_transform_ptr\\fP\\fB, int \\fP\\fIuser_transform_depth\\fP\\fB, int \\fIuser_transform_channels\\fP\\fB);\\fP\n\n\\fBvoid png_set_write_fn (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_voidp \\fP\\fIio_ptr\\fP\\fB, png_rw_ptr \\fP\\fIwrite_data_fn\\fP\\fB, png_flush_ptr \\fIoutput_flush_fn\\fP\\fB);\\fP\n\n\\fBvoid png_set_write_status_fn (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_write_status_ptr \\fIwrite_row_fn\\fP\\fB);\\fP\n\n\\fBvoid png_set_write_user_transform_fn (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_user_transform_ptr \\fIwrite_user_transform_fn\\fP\\fB);\\fP\n\n\\fBint png_sig_cmp (png_bytep \\fP\\fIsig\\fP\\fB, png_size_t \\fP\\fIstart\\fP\\fB, png_size_t \\fInum_to_check\\fP\\fB);\\fP\n\n\\fBvoid png_start_read_image (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_warning (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_const_charp \\fImessage\\fP\\fB);\\fP\n\n\\fBvoid png_write_chunk (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_bytep \\fP\\fIchunk_name\\fP\\fB, png_bytep \\fP\\fIdata\\fP\\fB, png_size_t \\fIlength\\fP\\fB);\\fP\n\n\\fBvoid png_write_chunk_data (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_bytep \\fP\\fIdata\\fP\\fB, png_size_t \\fIlength\\fP\\fB);\\fP\n\n\\fBvoid png_write_chunk_end (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_write_chunk_start (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_bytep \\fP\\fIchunk_name\\fP\\fB, png_uint_32 \\fIlength\\fP\\fB);\\fP\n\n\\fBvoid png_write_end (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_write_flush (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_write_image (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_bytepp \\fIimage\\fP\\fB);\\fP\n\n\\fBvoid png_write_info (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_write_info_before_PLTE (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fIinfo_ptr\\fP\\fB);\\fP\n\n\\fBvoid png_write_png (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_infop \\fP\\fIinfo_ptr\\fP\\fB, int \\fP\\fItransforms\\fP\\fB, png_voidp \\fIparams\\fP\\fB);\\fP\n\n\\fBvoid png_write_row (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_bytep \\fIrow\\fP\\fB);\\fP\n\n\\fBvoid png_write_rows (png_structp \\fP\\fIpng_ptr\\fP\\fB, png_bytepp \\fP\\fIrow\\fP\\fB, png_uint_32 \\fInum_rows\\fP\\fB);\\fP\n\n\\fBvoid png_write_sig (png_structp \\fIpng_ptr\\fP\\fB);\\fP\n\n.SH DESCRIPTION\nThe\n.I libpng\nlibrary supports encoding, decoding, and various manipulations of\nthe Portable Network Graphics (PNG) format image files.  It uses the\n.IR zlib(3)\ncompression library.\nFollowing is a copy of the libpng-manual.txt file that accompanies libpng.\n.SH LIBPNG.TXT\nlibpng-manual.txt - A description on how to use and modify libpng\n\n libpng version 1.6.22beta03 - February 19, 2016\n Updated and distributed by Glenn Randers-Pehrson\n <glennrp at users.sourceforge.net>\n Copyright (c) 1998-2016 Glenn Randers-Pehrson\n\n This document is released under the libpng license.\n For conditions of distribution and use, see the disclaimer\n and license in png.h\n\n Based on:\n\n libpng versions 0.97, January 1998, through 1.6.22beta03 - February 19, 2016\n Updated and distributed by Glenn Randers-Pehrson\n Copyright (c) 1998-2016 Glenn Randers-Pehrson\n\n libpng 1.0 beta 6 - version 0.96 - May 28, 1997\n Updated and distributed by Andreas Dilger\n Copyright (c) 1996, 1997 Andreas Dilger\n\n libpng 1.0 beta 2 - version 0.88 - January 26, 1996\n For conditions of distribution and use, see copyright\n notice in png.h. Copyright (c) 1995, 1996 Guy Eric\n Schalnat, Group 42, Inc.\n\n Updated/rewritten per request in the libpng FAQ\n Copyright (c) 1995, 1996 Frank J. T. Wojcik\n December 18, 1995 & January 20, 1996\n\n TABLE OF CONTENTS\n\n    I. Introduction\n   II. Structures\n  III. Reading\n   IV. Writing\n    V. Simplified API\n   VI. Modifying/Customizing libpng\n  VII. MNG support\n VIII. Changes to Libpng from version 0.88\n   IX. Changes to Libpng from version 1.0.x to 1.2.x\n    X. Changes to Libpng from version 1.0.x/1.2.x to 1.4.x\n   XI. Changes to Libpng from version 1.4.x to 1.5.x\n  XII. Changes to Libpng from version 1.5.x to 1.6.x\n XIII. Detecting libpng\n  XIV. Source code repository\n   XV. Coding style\n  XVI. Y2K Compliance in libpng\n\n.SH I. Introduction\n\nThis file describes how to use and modify the PNG reference library\n(known as libpng) for your own use.  In addition to this\nfile, example.c is a good starting point for using the library, as\nit is heavily commented and should include everything most people\nwill need.  We assume that libpng is already installed; see the\nINSTALL file for instructions on how to configure and install libpng.\n\nFor examples of libpng usage, see the files \"example.c\", \"pngtest.c\",\nand the files in the \"contrib\" directory, all of which are included in\nthe libpng distribution.\n\nLibpng was written as a companion to the PNG specification, as a way\nof reducing the amount of time and effort it takes to support the PNG\nfile format in application programs.\n\nThe PNG specification (second edition), November 2003, is available as\na W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at\n<http://www.w3.org/TR/2003/REC-PNG-20031110/\nThe W3C and ISO documents have identical technical content.\n\nThe PNG-1.2 specification is available at\n<http://png-mng.sourceforge.net/pub/png/spec/1.2/>.\nIt is technically equivalent\nto the PNG specification (second edition) but has some additional material.\n\nThe PNG-1.0 specification is available as RFC 2083 \n<http://png-mng.sourceforge.net/pub/png/spec/1.0/> and as a\nW3C Recommendation <http://www.w3.org/TR/REC-png-961001>.\n\nSome additional chunks are described in the special-purpose public chunks\ndocuments at <http://www.libpng.org/pub/png/spec/register/>\n\nOther information\nabout PNG, and the latest version of libpng, can be found at the PNG home\npage, <http://www.libpng.org/pub/png/>.\n\nMost users will not have to modify the library significantly; advanced\nusers may want to modify it more.  All attempts were made to make it as\ncomplete as possible, while keeping the code easy to understand.\nCurrently, this library only supports C.  Support for other languages\nis being considered.\n\nLibpng has been designed to handle multiple sessions at one time,\nto be easily modifiable, to be portable to the vast majority of\nmachines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy\nto use.  The ultimate goal of libpng is to promote the acceptance of\nthe PNG file format in whatever way possible.  While there is still\nwork to be done (see the TODO file), libpng should cover the\nmajority of the needs of its users.\n\nLibpng uses zlib for its compression and decompression of PNG files.\nFurther information about zlib, and the latest version of zlib, can\nbe found at the zlib home page, <http://zlib.net/>.\nThe zlib compression utility is a general purpose utility that is\nuseful for more than PNG files, and can be used without libpng.\nSee the documentation delivered with zlib for more details.\nYou can usually find the source files for the zlib utility wherever you\nfind the libpng source files.\n\nLibpng is thread safe, provided the threads are using different\ninstances of the structures.  Each thread should have its own\npng_struct and png_info instances, and thus its own image.\nLibpng does not protect itself against two threads using the\nsame instance of a structure.\n\n.SH II. Structures\n\nThere are two main structures that are important to libpng, png_struct\nand png_info.  Both are internal structures that are no longer exposed\nin the libpng interface (as of libpng 1.5.0).\n\nThe png_info structure is designed to provide information about the\nPNG file.  At one time, the fields of png_info were intended to be\ndirectly accessible to the user.  However, this tended to cause problems\nwith applications using dynamically loaded libraries, and as a result\na set of interface functions for png_info (the png_get_*() and png_set_*()\nfunctions) was developed, and direct access to the png_info fields was\ndeprecated..\n\nThe png_struct structure is the object used by the library to decode a\nsingle image.  As of 1.5.0 this structure is also not exposed.\n\nAlmost all libpng APIs require a pointer to a png_struct as the first argument.\nMany (in particular the png_set and png_get APIs) also require a pointer\nto png_info as the second argument.  Some application visible macros\ndefined in png.h designed for basic data access (reading and writing\nintegers in the PNG format) don't take a png_info pointer, but it's almost\nalways safe to assume that a (png_struct*) has to be passed to call an API\nfunction.\n\nYou can have more than one png_info structure associated with an image,\nas illustrated in pngtest.c, one for information valid prior to the\nIDAT chunks and another (called \"end_info\" below) for things after them.\n\nThe png.h header file is an invaluable reference for programming with libpng.\nAnd while I'm on the topic, make sure you include the libpng header file:\n\n#include <png.h>\n\nand also (as of libpng-1.5.0) the zlib header file, if you need it:\n\n#include <zlib.h>\n\n.SS Types\n\nThe png.h header file defines a number of integral types used by the\nAPIs.  Most of these are fairly obvious; for example types corresponding\nto integers of particular sizes and types for passing color values.\n\nOne exception is how non-integral numbers are handled.  For application\nconvenience most APIs that take such numbers have C (double) arguments;\nhowever, internally PNG, and libpng, use 32 bit signed integers and encode\nthe value by multiplying by 100,000.  As of libpng 1.5.0 a convenience\nmacro PNG_FP_1 is defined in png.h along with a type (png_fixed_point)\nwhich is simply (png_int_32).\n\nAll APIs that take (double) arguments also have a matching API that\ntakes the corresponding fixed point integer arguments.  The fixed point\nAPI has the same name as the floating point one with \"_fixed\" appended.\nThe actual range of values permitted in the APIs is frequently less than\nthe full range of (png_fixed_point) (\\-21474 to +21474).  When APIs require\na non-negative argument the type is recorded as png_uint_32 above.  Consult\nthe header file and the text below for more information.\n\nSpecial care must be take with sCAL chunk handling because the chunk itself\nuses non-integral values encoded as strings containing decimal floating point\nnumbers.  See the comments in the header file.\n\n.SS Configuration\n\nThe main header file function declarations are frequently protected by C\npreprocessing directives of the form:\n\n    #ifdef PNG_feature_SUPPORTED\n    declare-function\n    #endif\n    ...\n    #ifdef PNG_feature_SUPPORTED\n    use-function\n    #endif\n\nThe library can be built without support for these APIs, although a\nstandard build will have all implemented APIs.  Application programs\nshould check the feature macros before using an API for maximum\nportability.  From libpng 1.5.0 the feature macros set during the build\nof libpng are recorded in the header file \"pnglibconf.h\" and this file\nis always included by png.h.\n\nIf you don't need to change the library configuration from the default, skip to\nthe next section (\"Reading\").\n\nNotice that some of the makefiles in the 'scripts' directory and (in 1.5.0) all\nof the build project files in the 'projects' directory simply copy\nscripts/pnglibconf.h.prebuilt to pnglibconf.h.  This means that these build\nsystems do not permit easy auto-configuration of the library - they only\nsupport the default configuration.\n\nThe easiest way to make minor changes to the libpng configuration when\nauto-configuration is supported is to add definitions to the command line\nusing (typically) CPPFLAGS.  For example:\n\nCPPFLAGS=\\-DPNG_NO_FLOATING_ARITHMETIC\n\nwill change the internal libpng math implementation for gamma correction and\nother arithmetic calculations to fixed point, avoiding the need for fast\nfloating point support.  The result can be seen in the generated pnglibconf.h -\nmake sure it contains the changed feature macro setting.\n\nIf you need to make more extensive configuration changes - more than one or two\nfeature macro settings - you can either add \\-DPNG_USER_CONFIG to the build\ncommand line and put a list of feature macro settings in pngusr.h or you can set\nDFA_XTRA (a makefile variable) to a file containing the same information in the\nform of 'option' settings.\n\nA. Changing pnglibconf.h\n\nA variety of methods exist to build libpng.  Not all of these support\nreconfiguration of pnglibconf.h.  To reconfigure pnglibconf.h it must either be\nrebuilt from scripts/pnglibconf.dfa using awk or it must be edited by hand.\n\nHand editing is achieved by copying scripts/pnglibconf.h.prebuilt to\npnglibconf.h and changing the lines defining the supported features, paying\nvery close attention to the 'option' information in scripts/pnglibconf.dfa\nthat describes those features and their requirements.  This is easy to get\nwrong.\n\nB. Configuration using DFA_XTRA\n\nRebuilding from pnglibconf.dfa is easy if a functioning 'awk', or a later\nvariant such as 'nawk' or 'gawk', is available.  The configure build will\nautomatically find an appropriate awk and build pnglibconf.h.\nThe scripts/pnglibconf.mak file contains a set of make rules for doing the\nsame thing if configure is not used, and many of the makefiles in the scripts\ndirectory use this approach.\n\nWhen rebuilding simply write a new file containing changed options and set\nDFA_XTRA to the name of this file.  This causes the build to append the new file\nto the end of scripts/pnglibconf.dfa.  The pngusr.dfa file should contain lines\nof the following forms:\n\neverything = off\n\nThis turns all optional features off.  Include it at the start of pngusr.dfa to\nmake it easier to build a minimal configuration.  You will need to turn at least\nsome features on afterward to enable either reading or writing code, or both.\n\noption feature on\noption feature off\n\nEnable or disable a single feature.  This will automatically enable other\nfeatures required by a feature that is turned on or disable other features that\nrequire a feature which is turned off.  Conflicting settings will cause an error\nmessage to be emitted by awk.\n\nsetting feature default value\n\nChanges the default value of setting 'feature' to 'value'.  There are a small\nnumber of settings listed at the top of pnglibconf.h, they are documented in the\nsource code.  Most of these values have performance implications for the library\nbut most of them have no visible effect on the API.  Some can also be overridden\nfrom the API.\n\nThis method of building a customized pnglibconf.h is illustrated in\ncontrib/pngminim/*.  See the \"$(PNGCONF):\" target in the makefile and\npngusr.dfa in these directories.\n\nC. Configuration using PNG_USER_CONFIG\n\nIf \\-DPNG_USER_CONFIG is added to the CPPFLAGS when pnglibconf.h is built,\nthe file pngusr.h will automatically be included before the options in\nscripts/pnglibconf.dfa are processed.  Your pngusr.h file should contain only\nmacro definitions turning features on or off or setting settings.\n\nApart from the global setting \"everything = off\" all the options listed above\ncan be set using macros in pngusr.h:\n\n#define PNG_feature_SUPPORTED\n\nis equivalent to:\n\noption feature on\n\n#define PNG_NO_feature\n\nis equivalent to:\n\noption feature off\n\n#define PNG_feature value\n\nis equivalent to:\n\nsetting feature default value\n\nNotice that in both cases, pngusr.dfa and pngusr.h, the contents of the\npngusr file you supply override the contents of scripts/pnglibconf.dfa\n\nIf confusing or incomprehensible behavior results it is possible to\nexamine the intermediate file pnglibconf.dfn to find the full set of\ndependency information for each setting and option.  Simply locate the\nfeature in the file and read the C comments that precede it.\n\nThis method is also illustrated in the contrib/pngminim/* makefiles and\npngusr.h.\n\n.SH III. Reading\n\nWe'll now walk you through the possible functions to call when reading\nin a PNG file sequentially, briefly explaining the syntax and purpose\nof each one.  See example.c and png.h for more detail.  While\nprogressive reading is covered in the next section, you will still\nneed some of the functions discussed in this section to read a PNG\nfile.\n\n.SS Setup\n\nYou will want to do the I/O initialization(*) before you get into libpng,\nso if it doesn't work, you don't have much to undo.  Of course, you\nwill also want to insure that you are, in fact, dealing with a PNG\nfile.  Libpng provides a simple check to see if a file is a PNG file.\nTo use it, pass in the first 1 to 8 bytes of the file to the function\npng_sig_cmp(), and it will return 0 (false) if the bytes match the\ncorresponding bytes of the PNG signature, or nonzero (true) otherwise.\nOf course, the more bytes you pass in, the greater the accuracy of the\nprediction.\n\nIf you are intending to keep the file pointer open for use in libpng,\nyou must ensure you don't read more than 8 bytes from the beginning\nof the file, and you also have to make a call to png_set_sig_bytes()\nwith the number of bytes you read from the beginning.  Libpng will\nthen only check the bytes (if any) that your program didn't read.\n\n(*): If you are not using the standard I/O functions, you will need\nto replace them with custom functions.  See the discussion under\nCustomizing libpng.\n\n    FILE *fp = fopen(file_name, \"rb\");\n    if (!fp)\n    {\n       return (ERROR);\n    }\n\n    if (fread(header, 1, number, fp) != number)\n    {\n       return (ERROR);\n    }\n\n    is_png = !png_sig_cmp(header, 0, number);\n    if (!is_png)\n    {\n       return (NOT_PNG);\n    }\n\nNext, png_struct and png_info need to be allocated and initialized.  In\norder to ensure that the size of these structures is correct even with a\ndynamically linked libpng, there are functions to initialize and\nallocate the structures.  We also pass the library version, optional\npointers to error handling functions, and a pointer to a data struct for\nuse by the error functions, if necessary (the pointer and functions can\nbe NULL if the default error handlers are to be used).  See the section\non Changes to Libpng below regarding the old initialization functions.\nThe structure allocation functions quietly return NULL if they fail to\ncreate the structure, so your application should check for that.\n\n    png_structp png_ptr = png_create_read_struct\n        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,\n        user_error_fn, user_warning_fn);\n\n    if (!png_ptr)\n       return (ERROR);\n\n    png_infop info_ptr = png_create_info_struct(png_ptr);\n\n    if (!info_ptr)\n    {\n       png_destroy_read_struct(&png_ptr,\n           (png_infopp)NULL, (png_infopp)NULL);\n       return (ERROR);\n    }\n\nIf you want to use your own memory allocation routines,\nuse a libpng that was built with PNG_USER_MEM_SUPPORTED defined, and use\npng_create_read_struct_2() instead of png_create_read_struct():\n\n    png_structp png_ptr = png_create_read_struct_2\n        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,\n        user_error_fn, user_warning_fn, (png_voidp)\n        user_mem_ptr, user_malloc_fn, user_free_fn);\n\nThe error handling routines passed to png_create_read_struct()\nand the memory alloc/free routines passed to png_create_struct_2()\nare only necessary if you are not using the libpng supplied error\nhandling and memory alloc/free functions.\n\nWhen libpng encounters an error, it expects to longjmp back\nto your routine.  Therefore, you will need to call setjmp and pass\nyour png_jmpbuf(png_ptr).  If you read the file from different\nroutines, you will need to update the longjmp buffer every time you enter\na new routine that will call a png_*() function.\n\nSee your documentation of setjmp/longjmp for your compiler for more\ninformation on setjmp/longjmp.  See the discussion on libpng error\nhandling in the Customizing Libpng section below for more information\non the libpng error handling.  If an error occurs, and libpng longjmp's\nback to your setjmp, you will want to call png_destroy_read_struct() to\nfree any memory.\n\n    if (setjmp(png_jmpbuf(png_ptr)))\n    {\n       png_destroy_read_struct(&png_ptr, &info_ptr,\n           &end_info);\n       fclose(fp);\n       return (ERROR);\n    }\n\nPass (png_infopp)NULL instead of &end_info if you didn't create\nan end_info structure.\n\nIf you would rather avoid the complexity of setjmp/longjmp issues,\nyou can compile libpng with PNG_NO_SETJMP, in which case\nerrors will result in a call to PNG_ABORT() which defaults to abort().\n\nYou can #define PNG_ABORT() to a function that does something\nmore useful than abort(), as long as your function does not\nreturn.\n\nNow you need to set up the input code.  The default for libpng is to\nuse the C function fread().  If you use this, you will need to pass a\nvalid FILE * in the function png_init_io().  Be sure that the file is\nopened in binary mode.  If you wish to handle reading data in another\nway, you need not call the png_init_io() function, but you must then\nimplement the libpng I/O methods discussed in the Customizing Libpng\nsection below.\n\n    png_init_io(png_ptr, fp);\n\nIf you had previously opened the file and read any of the signature from\nthe beginning in order to see if this was a PNG file, you need to let\nlibpng know that there are some bytes missing from the start of the file.\n\n    png_set_sig_bytes(png_ptr, number);\n\nYou can change the zlib compression buffer size to be used while\nreading compressed data with\n\n    png_set_compression_buffer_size(png_ptr, buffer_size);\n\nwhere the default size is 8192 bytes.  Note that the buffer size\nis changed immediately and the buffer is reallocated immediately,\ninstead of setting a flag to be acted upon later.\n\nIf you want CRC errors to be handled in a different manner than\nthe default, use\n\n    png_set_crc_action(png_ptr, crit_action, ancil_action);\n\nThe values for png_set_crc_action() say how libpng is to handle CRC errors in\nancillary and critical chunks, and whether to use the data contained\ntherein.  Note that it is impossible to \"discard\" data in a critical\nchunk.\n\nChoices for (int) crit_action are\n   PNG_CRC_DEFAULT      0  error/quit\n   PNG_CRC_ERROR_QUIT   1  error/quit\n   PNG_CRC_WARN_USE     3  warn/use data\n   PNG_CRC_QUIET_USE    4  quiet/use data\n   PNG_CRC_NO_CHANGE    5  use the current value\n\nChoices for (int) ancil_action are\n   PNG_CRC_DEFAULT      0  error/quit\n   PNG_CRC_ERROR_QUIT   1  error/quit\n   PNG_CRC_WARN_DISCARD 2  warn/discard data\n   PNG_CRC_WARN_USE     3  warn/use data\n   PNG_CRC_QUIET_USE    4  quiet/use data\n   PNG_CRC_NO_CHANGE    5  use the current value\n\n.SS Setting up callback code\n\nYou can set up a callback function to handle any unknown chunks in the\ninput stream. You must supply the function\n\n    read_chunk_callback(png_structp png_ptr,\n         png_unknown_chunkp chunk);\n    {\n       /* The unknown chunk structure contains your\n          chunk data, along with similar data for any other\n          unknown chunks: */\n\n           png_byte name[5];\n           png_byte *data;\n           png_size_t size;\n\n       /* Note that libpng has already taken care of\n          the CRC handling */\n\n       /* put your code here.  Search for your chunk in the\n          unknown chunk structure, process it, and return one\n          of the following: */\n\n       return (\\-n); /* chunk had an error */\n       return (0); /* did not recognize */\n       return (n); /* success */\n    }\n\n(You can give your function another name that you like instead of\n\"read_chunk_callback\")\n\nTo inform libpng about your function, use\n\n    png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr,\n        read_chunk_callback);\n\nThis names not only the callback function, but also a user pointer that\nyou can retrieve with\n\n    png_get_user_chunk_ptr(png_ptr);\n\nIf you call the png_set_read_user_chunk_fn() function, then all unknown\nchunks which the callback does not handle will be saved when read.  You can\ncause them to be discarded by returning '1' (\"handled\") instead of '0'.  This\nbehavior will change in libpng 1.7 and the default handling set by the\npng_set_keep_unknown_chunks() function, described below, will be used when the\ncallback returns 0.  If you want the existing behavior you should set the global\ndefault to PNG_HANDLE_CHUNK_IF_SAFE now; this is compatible with all current\nversions of libpng and with 1.7.  Libpng 1.6 issues a warning if you keep the\ndefault, or PNG_HANDLE_CHUNK_NEVER, and the callback returns 0.\n\nAt this point, you can set up a callback function that will be\ncalled after each row has been read, which you can use to control\na progress meter or the like.  It's demonstrated in pngtest.c.\nYou must supply a function\n\n    void read_row_callback(png_structp png_ptr,\n       png_uint_32 row, int pass);\n    {\n      /* put your code here */\n    }\n\n(You can give it another name that you like instead of \"read_row_callback\")\n\nTo inform libpng about your function, use\n\n    png_set_read_status_fn(png_ptr, read_row_callback);\n\nWhen this function is called the row has already been completely processed and\nthe 'row' and 'pass' refer to the next row to be handled.  For the\nnon-interlaced case the row that was just handled is simply one less than the\npassed in row number, and pass will always be 0.  For the interlaced case the\nsame applies unless the row value is 0, in which case the row just handled was\nthe last one from one of the preceding passes.  Because interlacing may skip a\npass you cannot be sure that the preceding pass is just 'pass\\-1', if you really\nneed to know what the last pass is record (row,pass) from the callback and use\nthe last recorded value each time.\n\nAs with the user transform you can find the output row using the\nPNG_ROW_FROM_PASS_ROW macro.\n\n.SS Unknown-chunk handling\n\nNow you get to set the way the library processes unknown chunks in the\ninput PNG stream. Both known and unknown chunks will be read.  Normal\nbehavior is that known chunks will be parsed into information in\nvarious info_ptr members while unknown chunks will be discarded. This\nbehavior can be wasteful if your application will never use some known\nchunk types. To change this, you can call:\n\n    png_set_keep_unknown_chunks(png_ptr, keep,\n        chunk_list, num_chunks);\n\n    keep       - 0: default unknown chunk handling\n                 1: ignore; do not keep\n                 2: keep only if safe-to-copy\n                 3: keep even if unsafe-to-copy\n\n               You can use these definitions:\n                 PNG_HANDLE_CHUNK_AS_DEFAULT   0\n                 PNG_HANDLE_CHUNK_NEVER        1\n                 PNG_HANDLE_CHUNK_IF_SAFE      2\n                 PNG_HANDLE_CHUNK_ALWAYS       3\n\n    chunk_list - list of chunks affected (a byte string,\n                 five bytes per chunk, NULL or '\\0' if\n                 num_chunks is positive; ignored if\n                 numchunks <= 0).\n\n    num_chunks - number of chunks affected; if 0, all\n                 unknown chunks are affected.  If positive,\n                 only the chunks in the list are affected,\n                 and if negative all unknown chunks and\n                 all known chunks except for the IHDR,\n                 PLTE, tRNS, IDAT, and IEND chunks are\n                 affected.\n\nUnknown chunks declared in this way will be saved as raw data onto a\nlist of png_unknown_chunk structures.  If a chunk that is normally\nknown to libpng is named in the list, it will be handled as unknown,\naccording to the \"keep\" directive.  If a chunk is named in successive\ninstances of png_set_keep_unknown_chunks(), the final instance will\ntake precedence.  The IHDR and IEND chunks should not be named in\nchunk_list; if they are, libpng will process them normally anyway.\nIf you know that your application will never make use of some particular\nchunks, use PNG_HANDLE_CHUNK_NEVER (or 1) as demonstrated below.\n\nHere is an example of the usage of png_set_keep_unknown_chunks(),\nwhere the private \"vpAg\" chunk will later be processed by a user chunk\ncallback function:\n\n    png_byte vpAg[5]={118, 112,  65, 103, (png_byte) '\\0'};\n\n    #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)\n      png_byte unused_chunks[]=\n      {\n        104,  73,  83,  84, (png_byte) '\\0',   /* hIST */\n        105,  84,  88, 116, (png_byte) '\\0',   /* iTXt */\n        112,  67,  65,  76, (png_byte) '\\0',   /* pCAL */\n        115,  67,  65,  76, (png_byte) '\\0',   /* sCAL */\n        115,  80,  76,  84, (png_byte) '\\0',   /* sPLT */\n        116,  73,  77,  69, (png_byte) '\\0',   /* tIME */\n      };\n    #endif\n\n    ...\n\n    #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)\n      /* ignore all unknown chunks\n       * (use global setting \"2\" for libpng16 and earlier):\n       */\n      png_set_keep_unknown_chunks(read_ptr, 2, NULL, 0);\n\n      /* except for vpAg: */\n      png_set_keep_unknown_chunks(read_ptr, 2, vpAg, 1);\n\n      /* also ignore unused known chunks: */\n      png_set_keep_unknown_chunks(read_ptr, 1, unused_chunks,\n         (int)(sizeof unused_chunks)/5);\n    #endif\n\n.SS User limits\n\nThe PNG specification allows the width and height of an image to be as\nlarge as 2^(31\\-1 (0x7fffffff), or about 2.147 billion rows and columns.\nFor safety, libpng imposes a default limit of 1 million rows and columns.\nLarger images will be rejected immediately with a png_error() call. If\nyou wish to change these limits, you can use\n\n   png_set_user_limits(png_ptr, width_max, height_max);\n\nto set your own limits (libpng may reject some very wide images\nanyway because of potential buffer overflow conditions).\n\nYou should put this statement after you create the PNG structure and\nbefore calling png_read_info(), png_read_png(), or png_process_data().\n\nWhen writing a PNG datastream, put this statement before calling\npng_write_info() or png_write_png().\n\nIf you need to retrieve the limits that are being applied, use\n\n   width_max = png_get_user_width_max(png_ptr);\n   height_max = png_get_user_height_max(png_ptr);\n\nThe PNG specification sets no limit on the number of ancillary chunks\nallowed in a PNG datastream.  By default, libpng imposes a limit of\na total of 1000 sPLT, tEXt, iTXt, zTXt, and unknown chunks to be stored.\nIf you have set up both info_ptr and end_info_ptr, the limit applies\nseparately to each.  You can change the limit on the total number of such\nchunks that will be stored, with\n\n   png_set_chunk_cache_max(png_ptr, user_chunk_cache_max);\n\nwhere 0x7fffffffL means unlimited.  You can retrieve this limit with\n\n   chunk_cache_max = png_get_chunk_cache_max(png_ptr);\n\nLibpng imposes a limit of 8 Megabytes (8,000,000 bytes) on the amount of\nmemory that a compressed chunk other than IDAT can occupy, when decompressed.\nYou can change this limit with\n\n   png_set_chunk_malloc_max(png_ptr, user_chunk_malloc_max);\n\nand you can retrieve the limit with\n\n   chunk_malloc_max = png_get_chunk_malloc_max(png_ptr);\n\nAny chunks that would cause either of these limits to be exceeded will\nbe ignored.\n\n.SS Information about your system\n\nIf you intend to display the PNG or to incorporate it in other image data you\nneed to tell libpng information about your display or drawing surface so that\nlibpng can convert the values in the image to match the display.\n\nFrom libpng-1.5.4 this information can be set before reading the PNG file\nheader.  In earlier versions png_set_gamma() existed but behaved incorrectly if\ncalled before the PNG file header had been read and png_set_alpha_mode() did not\nexist.\n\nIf you need to support versions prior to libpng-1.5.4 test the version number\nas illustrated below using \"PNG_LIBPNG_VER >= 10504\" and follow the procedures\ndescribed in the appropriate manual page.\n\nYou give libpng the encoding expected by your system expressed as a 'gamma'\nvalue.  You can also specify a default encoding for the PNG file in\ncase the required information is missing from the file.  By default libpng\nassumes that the PNG data matches your system, to keep this default call:\n\n   png_set_gamma(png_ptr, screen_gamma, output_gamma);\n\nor you can use the fixed point equivalent:\n\n   png_set_gamma_fixed(png_ptr, PNG_FP_1*screen_gamma,\n      PNG_FP_1*output_gamma);\n\nIf you don't know the gamma for your system it is probably 2.2 - a good\napproximation to the IEC standard for display systems (sRGB).  If images are\ntoo contrasty or washed out you got the value wrong - check your system\ndocumentation!\n\nMany systems permit the system gamma to be changed via a lookup table in the\ndisplay driver, a few systems, including older Macs, change the response by\ndefault.  As of 1.5.4 three special values are available to handle common\nsituations:\n\n   PNG_DEFAULT_sRGB: Indicates that the system conforms to the\n                     IEC 61966-2-1 standard.  This matches almost\n                     all systems.\n   PNG_GAMMA_MAC_18: Indicates that the system is an older\n                     (pre Mac OS 10.6) Apple Macintosh system with\n                     the default settings.\n   PNG_GAMMA_LINEAR: Just the fixed point value for 1.0 - indicates\n                     that the system expects data with no gamma\n                     encoding.\n\nYou would use the linear (unencoded) value if you need to process the pixel\nvalues further because this avoids the need to decode and re-encode each\ncomponent value whenever arithmetic is performed.  A lot of graphics software\nuses linear values for this reason, often with higher precision component values\nto preserve overall accuracy.\n\n\nThe output_gamma value expresses how to decode the output values, not how\nthey are encoded.  The values used correspond to the normal numbers used to\ndescribe the overall gamma of a computer display system; for example 2.2 for\nan sRGB conformant system.  The values are scaled by 100000 in the _fixed\nversion of the API (so 220000 for sRGB.)\n\nThe inverse of the value is always used to provide a default for the PNG file\nencoding if it has no gAMA chunk and if png_set_gamma() has not been called\nto override the PNG gamma information.\n\nWhen the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode\nopaque pixels however pixels with lower alpha values are not encoded,\nregardless of the output gamma setting.\n\nWhen the standard Porter Duff handling is requested with mode 1 the output\nencoding is set to be linear and the output_gamma value is only relevant\nas a default for input data that has no gamma information.  The linear output\nencoding will be overridden if png_set_gamma() is called - the results may be\nhighly unexpected!\n\nThe following numbers are derived from the sRGB standard and the research\nbehind it.  sRGB is defined to be approximated by a PNG gAMA chunk value of\n0.45455 (1/2.2) for PNG.  The value implicitly includes any viewing\ncorrection required to take account of any differences in the color\nenvironment of the original scene and the intended display environment; the\nvalue expresses how to *decode* the image for display, not how the original\ndata was *encoded*.\n\nsRGB provides a peg for the PNG standard by defining a viewing environment.\nsRGB itself, and earlier TV standards, actually use a more complex transform\n(a linear portion then a gamma 2.4 power law) than PNG can express.  (PNG is\nlimited to simple power laws.)  By saying that an image for direct display on\nan sRGB conformant system should be stored with a gAMA chunk value of 45455\n(11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification\nmakes it possible to derive values for other display systems and\nenvironments.\n\nThe Mac value is deduced from the sRGB based on an assumption that the actual\nextra viewing correction used in early Mac display systems was implemented as\na power 1.45 lookup table.\n\nAny system where a programmable lookup table is used or where the behavior of\nthe final display device characteristics can be changed requires system\nspecific code to obtain the current characteristic.  However this can be\ndifficult and most PNG gamma correction only requires an approximate value.\n\nBy default, if png_set_alpha_mode() is not called, libpng assumes that all\nvalues are unencoded, linear, values and that the output device also has a\nlinear characteristic.  This is only very rarely correct - it is invariably\nbetter to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the\ndefault if you don't know what the right answer is!\n\nThe special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS\n10.6) which used a correction table to implement a somewhat lower gamma on an\notherwise sRGB system.\n\nBoth these values are reserved (not simple gamma values) in order to allow\nmore precise correction internally in the future.\n\nNOTE: the values can be passed to either the fixed or floating\npoint APIs, but the floating point API will also accept floating point\nvalues.\n\nThe second thing you may need to tell libpng about is how your system handles\nalpha channel information.  Some, but not all, PNG files contain an alpha\nchannel.  To display these files correctly you need to compose the data onto a\nsuitable background, as described in the PNG specification.\n\nLibpng only supports composing onto a single color (using png_set_background;\nsee below).  Otherwise you must do the composition yourself and, in this case,\nyou may need to call png_set_alpha_mode:\n\n   #if PNG_LIBPNG_VER >= 10504\n      png_set_alpha_mode(png_ptr, mode, screen_gamma);\n   #else\n      png_set_gamma(png_ptr, screen_gamma, 1.0/screen_gamma);\n   #endif\n\nThe screen_gamma value is the same as the argument to png_set_gamma; however,\nhow it affects the output depends on the mode.  png_set_alpha_mode() sets the\nfile gamma default to 1/screen_gamma, so normally you don't need to call\npng_set_gamma.  If you need different defaults call png_set_gamma() before\npng_set_alpha_mode() - if you call it after it will override the settings made\nby png_set_alpha_mode().\n\nThe mode is as follows:\n\n    PNG_ALPHA_PNG: The data is encoded according to the PNG\nspecification.  Red, green and blue, or gray, components are\ngamma encoded color values and are not premultiplied by the\nalpha value.  The alpha value is a linear measure of the\ncontribution of the pixel to the corresponding final output pixel.\n\nYou should normally use this format if you intend to perform\ncolor correction on the color values; most, maybe all, color\ncorrection software has no handling for the alpha channel and,\nanyway, the math to handle pre-multiplied component values is\nunnecessarily complex.\n\nBefore you do any arithmetic on the component values you need\nto remove the gamma encoding and multiply out the alpha\nchannel.  See the PNG specification for more detail.  It is\nimportant to note that when an image with an alpha channel is\nscaled, linear encoded, pre-multiplied component values must\nbe used!\n\nThe remaining modes assume you don't need to do any further color correction or\nthat if you do, your color correction software knows all about alpha (it\nprobably doesn't!).  They 'associate' the alpha with the color information by\nstoring color channel values that have been scaled by the alpha.  The\nadvantage is that the color channels can be resampled (the image can be\nscaled) in this form.  The disadvantage is that normal practice is to store\nlinear, not (gamma) encoded, values and this requires 16-bit channels for\nstill images rather than the 8-bit channels that are just about sufficient if\ngamma encoding is used.  In addition all non-transparent pixel values,\nincluding completely opaque ones, must be gamma encoded to produce the final\nimage.  These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes\ndescribed below (the latter being the two common names for associated alpha\ncolor channels). Note that PNG files always contain non-associated color\nchannels; png_set_alpha_mode() with one of the modes causes the decoder to\nconvert the pixels to an associated form before returning them to your\napplication. \n\nSince it is not necessary to perform arithmetic on opaque color values so\nlong as they are not to be resampled and are in the final color space it is\npossible to optimize the handling of alpha by storing the opaque pixels in\nthe PNG format (adjusted for the output color space) while storing partially\nopaque pixels in the standard, linear, format.  The accuracy required for\nstandard alpha composition is relatively low, because the pixels are\nisolated, therefore typically the accuracy loss in storing 8-bit linear\nvalues is acceptable.  (This is not true if the alpha channel is used to\nsimulate transparency over large areas - use 16 bits or the PNG mode in\nthis case!)  This is the 'OPTIMIZED' mode.  For this mode a pixel is\ntreated as opaque only if the alpha value is equal to the maximum value.\n\n    PNG_ALPHA_STANDARD:  The data libpng produces is encoded in the\nstandard way assumed by most correctly written graphics software.\nThe gamma encoding will be removed by libpng and the\nlinear component values will be pre-multiplied by the\nalpha channel.\n\nWith this format the final image must be re-encoded to\nmatch the display gamma before the image is displayed.\nIf your system doesn't do that, yet still seems to\nperform arithmetic on the pixels without decoding them,\nit is broken - check out the modes below.\n\nWith PNG_ALPHA_STANDARD libpng always produces linear\ncomponent values, whatever screen_gamma you supply.  The\nscreen_gamma value is, however, used as a default for\nthe file gamma if the PNG file has no gamma information.\n\nIf you call png_set_gamma() after png_set_alpha_mode() you\nwill override the linear encoding.  Instead the\npre-multiplied pixel values will be gamma encoded but\nthe alpha channel will still be linear.  This may\nactually match the requirements of some broken software,\nbut it is unlikely.\n\nWhile linear 8-bit data is often used it has\ninsufficient precision for any image with a reasonable\ndynamic range.  To avoid problems, and if your software\nsupports it, use png_set_expand_16() to force all\ncomponents to 16 bits.\n\n    PNG_ALPHA_OPTIMIZED: This mode is the same as PNG_ALPHA_STANDARD\nexcept that completely opaque pixels are gamma encoded according to\nthe screen_gamma value.  Pixels with alpha less than 1.0\nwill still have linear components.\n\nUse this format if you have control over your\ncompositing software and so don't do other arithmetic\n(such as scaling) on the data you get from libpng.  Your\ncompositing software can simply copy opaque pixels to\nthe output but still has linear values for the\nnon-opaque pixels.\n\nIn normal compositing, where the alpha channel encodes\npartial pixel coverage (as opposed to broad area\ntranslucency), the inaccuracies of the 8-bit\nrepresentation of non-opaque pixels are irrelevant.\n\nYou can also try this format if your software is broken;\nit might look better.\n\n    PNG_ALPHA_BROKEN: This is PNG_ALPHA_STANDARD; however, all component\nvalues, including the alpha channel are gamma encoded.  This is\nbroken because, in practice, no implementation that uses this choice\ncorrectly undoes the encoding before handling alpha composition.  Use this\nchoice only if other serious errors in the software or hardware you use\nmandate it.  In most cases of broken software or hardware the bug in the\nfinal display manifests as a subtle halo around composited parts of the\nimage.  You may not even perceive this as a halo; the composited part of\nthe image may simply appear separate from the background, as though it had\nbeen cut out of paper and pasted on afterward.\n\nIf you don't have to deal with bugs in software or hardware, or if you can fix\nthem, there are three recommended ways of using png_set_alpha_mode():\n\n   png_set_alpha_mode(png_ptr, PNG_ALPHA_PNG,\n       screen_gamma);\n\nYou can do color correction on the result (libpng does not currently\nsupport color correction internally).  When you handle the alpha channel\nyou need to undo the gamma encoding and multiply out the alpha.\n\n   png_set_alpha_mode(png_ptr, PNG_ALPHA_STANDARD,\n       screen_gamma);\n   png_set_expand_16(png_ptr);\n\nIf you are using the high level interface, don't call png_set_expand_16();\ninstead pass PNG_TRANSFORM_EXPAND_16 to the interface.\n\nWith this mode you can't do color correction, but you can do arithmetic,\nincluding composition and scaling, on the data without further processing.\n\n   png_set_alpha_mode(png_ptr, PNG_ALPHA_OPTIMIZED,\n       screen_gamma);\n\nYou can avoid the expansion to 16-bit components with this mode, but you\nlose the ability to scale the image or perform other linear arithmetic.\nAll you can do is compose the result onto a matching output.  Since this\nmode is libpng-specific you also need to write your own composition\nsoftware.\n\nThe following are examples of calls to png_set_alpha_mode to achieve the\nrequired overall gamma correction and, where necessary, alpha\npremultiplication.\n\n    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);\n\nThis is the default libpng handling of the alpha channel - it is not\npre-multiplied into the color components.  In addition the call states\nthat the output is for a sRGB system and causes all PNG files without gAMA\nchunks to be assumed to be encoded using sRGB.\n\n    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);\n\nIn this case the output is assumed to be something like an sRGB conformant\ndisplay preceeded by a power-law lookup table of power 1.45.  This is how\nearly Mac systems behaved.\n\n    png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);\n\nThis is the classic Jim Blinn approach and will work in academic\nenvironments where everything is done by the book.  It has the shortcoming\nof assuming that input PNG data with no gamma information is linear - this\nis unlikely to be correct unless the PNG files where generated locally.\nMost of the time the output precision will be so low as to show\nsignificant banding in dark areas of the image.\n\n    png_set_expand_16(pp);\n    png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB);\n\nThis is a somewhat more realistic Jim Blinn inspired approach.  PNG files\nare assumed to have the sRGB encoding if not marked with a gamma value and\nthe output is always 16 bits per component.  This permits accurate scaling\nand processing of the data.  If you know that your input PNG files were\ngenerated locally you might need to replace PNG_DEFAULT_sRGB with the\ncorrect value for your system.\n\n    png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);\n\nIf you just need to composite the PNG image onto an existing background\nand if you control the code that does this you can use the optimization\nsetting.  In this case you just copy completely opaque pixels to the\noutput.  For pixels that are not completely transparent (you just skip\nthose) you do the composition math using png_composite or png_composite_16\nbelow then encode the resultant 8-bit or 16-bit values to match the output\nencoding.\n\n    Other cases\n\nIf neither the PNG nor the standard linear encoding work for you because\nof the software or hardware you use then you have a big problem.  The PNG\ncase will probably result in halos around the image.  The linear encoding\nwill probably result in a washed out, too bright, image (it's actually too\ncontrasty.)  Try the ALPHA_OPTIMIZED mode above - this will probably\nsubstantially reduce the halos.  Alternatively try:\n\n    png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB);\n\nThis option will also reduce the halos, but there will be slight dark\nhalos round the opaque parts of the image where the background is light.\nIn the OPTIMIZED mode the halos will be light halos where the background\nis dark.  Take your pick - the halos are unavoidable unless you can get\nyour hardware/software fixed!  (The OPTIMIZED approach is slightly\nfaster.)\n\nWhen the default gamma of PNG files doesn't match the output gamma.\nIf you have PNG files with no gamma information png_set_alpha_mode allows\nyou to provide a default gamma, but it also sets the ouput gamma to the\nmatching value.  If you know your PNG files have a gamma that doesn't\nmatch the output you can take advantage of the fact that\npng_set_alpha_mode always sets the output gamma but only sets the PNG\ndefault if it is not already set:\n\n    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);\n    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);\n\nThe first call sets both the default and the output gamma values, the\nsecond call overrides the output gamma without changing the default.  This\nis easier than achieving the same effect with png_set_gamma.  You must use\nPNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will\nfire if more than one call to png_set_alpha_mode and png_set_background is\nmade in the same read operation, however multiple calls with PNG_ALPHA_PNG\nare ignored.\n\nIf you don't need, or can't handle, the alpha channel you can call\npng_set_background() to remove it by compositing against a fixed color.  Don't\ncall png_set_strip_alpha() to do this - it will leave spurious pixel values in\ntransparent parts of this image.\n\n   png_set_background(png_ptr, &background_color,\n       PNG_BACKGROUND_GAMMA_SCREEN, 0, 1);\n\nThe background_color is an RGB or grayscale value according to the data format\nlibpng will produce for you.  Because you don't yet know the format of the PNG\nfile, if you call png_set_background at this point you must arrange for the\nformat produced by libpng to always have 8-bit or 16-bit components and then\nstore the color as an 8-bit or 16-bit color as appropriate.  The color contains\nseparate gray and RGB component values, so you can let libpng produce gray or\nRGB output according to the input format, but low bit depth grayscale images\nmust always be converted to at least 8-bit format.  (Even though low bit depth\ngrayscale images can't have an alpha channel they can have a transparent\ncolor!)\n\nYou set the transforms you need later, either as flags to the high level\ninterface or libpng API calls for the low level interface.  For reference the\nsettings and API calls required are:\n\n8-bit values:\n   PNG_TRANSFORM_SCALE_16 | PNG_EXPAND\n   png_set_expand(png_ptr); png_set_scale_16(png_ptr);\n\n   If you must get exactly the same inaccurate results\n   produced by default in versions prior to libpng-1.5.4,\n   use PNG_TRANSFORM_STRIP_16 and png_set_strip_16(png_ptr)\n   instead.\n\n16-bit values:\n   PNG_TRANSFORM_EXPAND_16\n   png_set_expand_16(png_ptr);\n\nIn either case palette image data will be expanded to RGB.  If you just want\ncolor data you can add PNG_TRANSFORM_GRAY_TO_RGB or png_set_gray_to_rgb(png_ptr)\nto the list.\n\nCalling png_set_background before the PNG file header is read will not work\nprior to libpng-1.5.4.  Because the failure may result in unexpected warnings or\nerrors it is therefore much safer to call png_set_background after the head has\nbeen read.  Unfortunately this means that prior to libpng-1.5.4 it cannot be\nused with the high level interface.\n\n.SS The high-level read interface\n\nAt this point there are two ways to proceed; through the high-level\nread interface, or through a sequence of low-level read operations.\nYou can use the high-level interface if (a) you are willing to read\nthe entire image into memory, and (b) the input transformations\nyou want to do are limited to the following set:\n\n    PNG_TRANSFORM_IDENTITY      No transformation\n    PNG_TRANSFORM_SCALE_16      Strip 16-bit samples to\n                                8-bit accurately\n    PNG_TRANSFORM_STRIP_16      Chop 16-bit samples to\n                                8-bit less accurately\n    PNG_TRANSFORM_STRIP_ALPHA   Discard the alpha channel\n    PNG_TRANSFORM_PACKING       Expand 1, 2 and 4-bit\n                                samples to bytes\n    PNG_TRANSFORM_PACKSWAP      Change order of packed\n                                pixels to LSB first\n    PNG_TRANSFORM_EXPAND        Perform set_expand()\n    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images\n    PNG_TRANSFORM_SHIFT         Normalize pixels to the\n                                sBIT depth\n    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA\n                                to BGRA\n    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA\n                                to AG\n    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity\n                                to transparency\n    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples\n    PNG_TRANSFORM_GRAY_TO_RGB   Expand grayscale samples\n                                to RGB (or GA to RGBA)\n    PNG_TRANSFORM_EXPAND_16     Expand samples to 16 bits\n\n(This excludes setting a background color, doing gamma transformation,\nquantizing, and setting filler.)  If this is the case, simply do this:\n\n    png_read_png(png_ptr, info_ptr, png_transforms, NULL)\n\nwhere png_transforms is an integer containing the bitwise OR of some\nset of transformation flags.  This call is equivalent to png_read_info(),\nfollowed the set of transformations indicated by the transform mask,\nthen png_read_image(), and finally png_read_end().\n\n(The final parameter of this call is not yet used.  Someday it might point\nto transformation parameters required by some future input transform.)\n\nYou must use png_transforms and not call any png_set_transform() functions\nwhen you use png_read_png().\n\nAfter you have called png_read_png(), you can retrieve the image data\nwith\n\n   row_pointers = png_get_rows(png_ptr, info_ptr);\n\nwhere row_pointers is an array of pointers to the pixel data for each row:\n\n   png_bytep row_pointers[height];\n\nIf you know your image size and pixel size ahead of time, you can allocate\nrow_pointers prior to calling png_read_png() with\n\n   if (height > PNG_UINT_32_MAX/(sizeof (png_byte)))\n      png_error (png_ptr,\n          \"Image is too tall to process in memory\");\n\n   if (width > PNG_UINT_32_MAX/pixel_size)\n      png_error (png_ptr,\n          \"Image is too wide to process in memory\");\n\n   row_pointers = png_malloc(png_ptr,\n       height*(sizeof (png_bytep)));\n\n   for (int i=0; i<height, i++)\n      row_pointers[i]=NULL;  /* security precaution */\n\n   for (int i=0; i<height, i++)\n      row_pointers[i]=png_malloc(png_ptr,\n          width*pixel_size);\n\n   png_set_rows(png_ptr, info_ptr, &row_pointers);\n\nAlternatively you could allocate your image in one big block and define\nrow_pointers[i] to point into the proper places in your block.\n\nIf you use png_set_rows(), the application is responsible for freeing\nrow_pointers (and row_pointers[i], if they were separately allocated).\n\nIf you don't allocate row_pointers ahead of time, png_read_png() will\ndo it, and it'll be free'ed by libpng when you call png_destroy_*().\n\n.SS The low-level read interface\n\nIf you are going the low-level route, you are now ready to read all\nthe file information up to the actual image data.  You do this with a\ncall to png_read_info().\n\n    png_read_info(png_ptr, info_ptr);\n\nThis will process all chunks up to but not including the image data.\n\nThis also copies some of the data from the PNG file into the decode structure\nfor use in later transformations.  Important information copied in is:\n\n1) The PNG file gamma from the gAMA chunk.  This overwrites the default value\nprovided by an earlier call to png_set_gamma or png_set_alpha_mode.\n\n2) Prior to libpng-1.5.4 the background color from a bKGd chunk.  This\ndamages the information provided by an earlier call to png_set_background\nresulting in unexpected behavior.  Libpng-1.5.4 no longer does this.\n\n3) The number of significant bits in each component value.  Libpng uses this to\noptimize gamma handling by reducing the internal lookup table sizes.\n\n4) The transparent color information from a tRNS chunk.  This can be modified by\na later call to png_set_tRNS.\n\n.SS Querying the info structure\n\nFunctions are used to get the information from the info_ptr once it\nhas been read.  Note that these fields may not be completely filled\nin until png_read_end() has read the chunk data following the image.\n\n    png_get_IHDR(png_ptr, info_ptr, &width, &height,\n       &bit_depth, &color_type, &interlace_type,\n       &compression_type, &filter_method);\n\n    width          - holds the width of the image\n                     in pixels (up to 2^31).\n\n    height         - holds the height of the image\n                     in pixels (up to 2^31).\n\n    bit_depth      - holds the bit depth of one of the\n                     image channels.  (valid values are\n                     1, 2, 4, 8, 16 and depend also on\n                     the color_type.  See also\n                     significant bits (sBIT) below).\n\n    color_type     - describes which color/alpha channels\n                         are present.\n                     PNG_COLOR_TYPE_GRAY\n                        (bit depths 1, 2, 4, 8, 16)\n                     PNG_COLOR_TYPE_GRAY_ALPHA\n                        (bit depths 8, 16)\n                     PNG_COLOR_TYPE_PALETTE\n                        (bit depths 1, 2, 4, 8)\n                     PNG_COLOR_TYPE_RGB\n                        (bit_depths 8, 16)\n                     PNG_COLOR_TYPE_RGB_ALPHA\n                        (bit_depths 8, 16)\n\n                     PNG_COLOR_MASK_PALETTE\n                     PNG_COLOR_MASK_COLOR\n                     PNG_COLOR_MASK_ALPHA\n\n    interlace_type - (PNG_INTERLACE_NONE or\n                     PNG_INTERLACE_ADAM7)\n\n    compression_type - (must be PNG_COMPRESSION_TYPE_BASE\n                     for PNG 1.0)\n\n    filter_method  - (must be PNG_FILTER_TYPE_BASE\n                     for PNG 1.0, and can also be\n                     PNG_INTRAPIXEL_DIFFERENCING if\n                     the PNG datastream is embedded in\n                     a MNG-1.0 datastream)\n\n    Any of width, height, color_type, bit_depth,\n    interlace_type, compression_type, or filter_method can\n    be NULL if you are not interested in their values.\n\n    Note that png_get_IHDR() returns 32-bit data into\n    the application's width and height variables.\n    This is an unsafe situation if these are not png_uint_32\n    variables.  In such situations, the\n    png_get_image_width() and png_get_image_height()\n    functions described below are safer.\n\n    width            = png_get_image_width(png_ptr,\n                         info_ptr);\n\n    height           = png_get_image_height(png_ptr,\n                         info_ptr);\n\n    bit_depth        = png_get_bit_depth(png_ptr,\n                         info_ptr);\n\n    color_type       = png_get_color_type(png_ptr,\n                         info_ptr);\n\n    interlace_type   = png_get_interlace_type(png_ptr,\n                         info_ptr);\n\n    compression_type = png_get_compression_type(png_ptr,\n                         info_ptr);\n\n    filter_method    = png_get_filter_type(png_ptr,\n                         info_ptr);\n\n    channels = png_get_channels(png_ptr, info_ptr);\n\n    channels       - number of channels of info for the\n                     color type (valid values are 1 (GRAY,\n                     PALETTE), 2 (GRAY_ALPHA), 3 (RGB),\n                     4 (RGB_ALPHA or RGB + filler byte))\n\n    rowbytes = png_get_rowbytes(png_ptr, info_ptr);\n\n    rowbytes       - number of bytes needed to hold a row\n\n    signature = png_get_signature(png_ptr, info_ptr);\n\n    signature      - holds the signature read from the\n                     file (if any).  The data is kept in\n                     the same offset it would be if the\n                     whole signature were read (i.e. if an\n                     application had already read in 4\n                     bytes of signature before starting\n                     libpng, the remaining 4 bytes would\n                     be in signature[4] through signature[7]\n                     (see png_set_sig_bytes())).\n\nThese are also important, but their validity depends on whether the chunk\nhas been read.  The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and\npng_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the\ndata has been read, or zero if it is missing.  The parameters to the\npng_get_<chunk> are set directly if they are simple data types, or a\npointer into the info_ptr is returned for any complex types.\n\nThe colorspace data from gAMA, cHRM, sRGB, iCCP, and sBIT chunks\nis simply returned to give the application information about how the\nimage was encoded.  Libpng itself only does transformations using the file\ngamma when combining semitransparent pixels with the background color, and,\nsince libpng-1.6.0, when converting between 8-bit sRGB and 16-bit linear pixels\nwithin the simplified API.  Libpng also uses the file gamma when converting\nRGB to gray, beginning with libpng-1.0.5, if the application calls\npng_set_rgb_to_gray()).\n\n    png_get_PLTE(png_ptr, info_ptr, &palette,\n                     &num_palette);\n\n    palette        - the palette for the file\n                     (array of png_color)\n\n    num_palette    - number of entries in the palette\n\n    png_get_gAMA(png_ptr, info_ptr, &file_gamma);\n    png_get_gAMA_fixed(png_ptr, info_ptr, &int_file_gamma);\n\n    file_gamma     - the gamma at which the file is\n                     written (PNG_INFO_gAMA)\n\n    int_file_gamma - 100,000 times the gamma at which the\n                     file is written\n\n    png_get_cHRM(png_ptr, info_ptr,  &white_x, &white_y, &red_x,\n                     &red_y, &green_x, &green_y, &blue_x, &blue_y)\n    png_get_cHRM_XYZ(png_ptr, info_ptr, &red_X, &red_Y, &red_Z,\n                     &green_X, &green_Y, &green_Z, &blue_X, &blue_Y,\n                     &blue_Z)\n    png_get_cHRM_fixed(png_ptr, info_ptr, &int_white_x,\n                     &int_white_y, &int_red_x, &int_red_y,\n                     &int_green_x, &int_green_y, &int_blue_x,\n                     &int_blue_y)\n    png_get_cHRM_XYZ_fixed(png_ptr, info_ptr, &int_red_X, &int_red_Y,\n                     &int_red_Z, &int_green_X, &int_green_Y,\n                     &int_green_Z, &int_blue_X, &int_blue_Y,\n                     &int_blue_Z)\n\n    {white,red,green,blue}_{x,y}\n                     A color space encoding specified using the\n                     chromaticities of the end points and the\n                     white point. (PNG_INFO_cHRM)\n\n    {red,green,blue}_{X,Y,Z}\n                     A color space encoding specified using the\n                     encoding end points - the CIE tristimulus\n                     specification of the intended color of the red,\n                     green and blue channels in the PNG RGB data.\n                     The white point is simply the sum of the three\n                     end points. (PNG_INFO_cHRM)\n\n    png_get_sRGB(png_ptr, info_ptr, &srgb_intent);\n\n    srgb_intent -    the rendering intent (PNG_INFO_sRGB)\n                     The presence of the sRGB chunk\n                     means that the pixel data is in the\n                     sRGB color space.  This chunk also\n                     implies specific values of gAMA and\n                     cHRM.\n\n    png_get_iCCP(png_ptr, info_ptr, &name,\n       &compression_type, &profile, &proflen);\n\n    name             - The profile name.\n\n    compression_type - The compression type; always\n                       PNG_COMPRESSION_TYPE_BASE for PNG 1.0.\n                       You may give NULL to this argument to\n                       ignore it.\n\n    profile          - International Color Consortium color\n                       profile data. May contain NULs.\n\n    proflen          - length of profile data in bytes.\n\n    png_get_sBIT(png_ptr, info_ptr, &sig_bit);\n\n    sig_bit        - the number of significant bits for\n                     (PNG_INFO_sBIT) each of the gray,\n                     red, green, and blue channels,\n                     whichever are appropriate for the\n                     given color type (png_color_16)\n\n    png_get_tRNS(png_ptr, info_ptr, &trans_alpha,\n                     &num_trans, &trans_color);\n\n    trans_alpha    - array of alpha (transparency)\n                     entries for palette (PNG_INFO_tRNS)\n\n    num_trans      - number of transparent entries\n                     (PNG_INFO_tRNS)\n\n    trans_color    - graylevel or color sample values of\n                     the single transparent color for\n                     non-paletted images (PNG_INFO_tRNS)\n\n    png_get_hIST(png_ptr, info_ptr, &hist);\n                     (PNG_INFO_hIST)\n\n    hist           - histogram of palette (array of\n                     png_uint_16)\n\n    png_get_tIME(png_ptr, info_ptr, &mod_time);\n\n    mod_time       - time image was last modified\n                    (PNG_VALID_tIME)\n\n    png_get_bKGD(png_ptr, info_ptr, &background);\n\n    background     - background color (of type\n                     png_color_16p) (PNG_VALID_bKGD)\n                     valid 16-bit red, green and blue\n                     values, regardless of color_type\n\n    num_comments   = png_get_text(png_ptr, info_ptr,\n                     &text_ptr, &num_text);\n\n    num_comments   - number of comments\n\n    text_ptr       - array of png_text holding image\n                     comments\n\n    text_ptr[i].compression - type of compression used\n                 on \"text\" PNG_TEXT_COMPRESSION_NONE\n                           PNG_TEXT_COMPRESSION_zTXt\n                           PNG_ITXT_COMPRESSION_NONE\n                           PNG_ITXT_COMPRESSION_zTXt\n\n    text_ptr[i].key   - keyword for comment.  Must contain\n                         1-79 characters.\n\n    text_ptr[i].text  - text comments for current\n                         keyword.  Can be empty.\n\n    text_ptr[i].text_length - length of text string,\n                 after decompression, 0 for iTXt\n\n    text_ptr[i].itxt_length - length of itxt string,\n                 after decompression, 0 for tEXt/zTXt\n\n    text_ptr[i].lang  - language of comment (empty\n                         string for unknown).\n\n    text_ptr[i].lang_key  - keyword in UTF-8\n                         (empty string for unknown).\n\n    Note that the itxt_length, lang, and lang_key\n    members of the text_ptr structure only exist when the\n    library is built with iTXt chunk support.  Prior to\n    libpng-1.4.0 the library was built by default without\n    iTXt support. Also note that when iTXt is supported,\n    they contain NULL pointers when the \"compression\"\n    field contains PNG_TEXT_COMPRESSION_NONE or\n    PNG_TEXT_COMPRESSION_zTXt.\n\n    num_text       - number of comments (same as\n                     num_comments; you can put NULL here\n                     to avoid the duplication)\n\n    Note while png_set_text() will accept text, language,\n    and translated keywords that can be NULL pointers, the\n    structure returned by png_get_text will always contain\n    regular zero-terminated C strings.  They might be\n    empty strings but they will never be NULL pointers.\n\n    num_spalettes = png_get_sPLT(png_ptr, info_ptr,\n       &palette_ptr);\n\n    num_spalettes  - number of sPLT chunks read.\n\n    palette_ptr    - array of palette structures holding\n                     contents of one or more sPLT chunks\n                     read.\n\n    png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,\n       &unit_type);\n\n    offset_x       - positive offset from the left edge\n                     of the screen (can be negative)\n\n    offset_y       - positive offset from the top edge\n                     of the screen (can be negative)\n\n    unit_type      - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER\n\n    png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y,\n       &unit_type);\n\n    res_x          - pixels/unit physical resolution in\n                     x direction\n\n    res_y          - pixels/unit physical resolution in\n                     x direction\n\n    unit_type      - PNG_RESOLUTION_UNKNOWN,\n                     PNG_RESOLUTION_METER\n\n    png_get_sCAL(png_ptr, info_ptr, &unit, &width,\n       &height)\n\n    unit        - physical scale units (an integer)\n\n    width       - width of a pixel in physical scale units\n\n    height      - height of a pixel in physical scale units\n                 (width and height are doubles)\n\n    png_get_sCAL_s(png_ptr, info_ptr, &unit, &width,\n       &height)\n\n    unit        - physical scale units (an integer)\n\n    width       - width of a pixel in physical scale units\n                  (expressed as a string)\n\n    height      - height of a pixel in physical scale units\n                 (width and height are strings like \"2.54\")\n\n    num_unknown_chunks = png_get_unknown_chunks(png_ptr,\n       info_ptr, &unknowns)\n\n    unknowns          - array of png_unknown_chunk\n                        structures holding unknown chunks\n\n    unknowns[i].name  - name of unknown chunk\n\n    unknowns[i].data  - data of unknown chunk\n\n    unknowns[i].size  - size of unknown chunk's data\n\n    unknowns[i].location - position of chunk in file\n\n    The value of \"i\" corresponds to the order in which the\n    chunks were read from the PNG file or inserted with the\n    png_set_unknown_chunks() function.\n\n    The value of \"location\" is a bitwise \"or\" of\n\n         PNG_HAVE_IHDR  (0x01)\n         PNG_HAVE_PLTE  (0x02)\n         PNG_AFTER_IDAT (0x08)\n\nThe data from the pHYs chunk can be retrieved in several convenient\nforms:\n\n    res_x = png_get_x_pixels_per_meter(png_ptr,\n       info_ptr)\n\n    res_y = png_get_y_pixels_per_meter(png_ptr,\n       info_ptr)\n\n    res_x_and_y = png_get_pixels_per_meter(png_ptr,\n       info_ptr)\n\n    res_x = png_get_x_pixels_per_inch(png_ptr,\n       info_ptr)\n\n    res_y = png_get_y_pixels_per_inch(png_ptr,\n       info_ptr)\n\n    res_x_and_y = png_get_pixels_per_inch(png_ptr,\n       info_ptr)\n\n    aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,\n       info_ptr)\n\n    Each of these returns 0 [signifying \"unknown\"] if\n       the data is not present or if res_x is 0;\n       res_x_and_y is 0 if res_x != res_y\n\n    Note that because of the way the resolutions are\n       stored internally, the inch conversions won't\n       come out to exactly even number.  For example,\n       72 dpi is stored as 0.28346 pixels/meter, and\n       when this is retrieved it is 71.9988 dpi, so\n       be sure to round the returned value appropriately\n       if you want to display a reasonable-looking result.\n\nThe data from the oFFs chunk can be retrieved in several convenient\nforms:\n\n    x_offset = png_get_x_offset_microns(png_ptr, info_ptr);\n\n    y_offset = png_get_y_offset_microns(png_ptr, info_ptr);\n\n    x_offset = png_get_x_offset_inches(png_ptr, info_ptr);\n\n    y_offset = png_get_y_offset_inches(png_ptr, info_ptr);\n\n    Each of these returns 0 [signifying \"unknown\" if both\n       x and y are 0] if the data is not present or if the\n       chunk is present but the unit is the pixel.  The\n       remark about inexact inch conversions applies here\n       as well, because a value in inches can't always be\n       converted to microns and back without some loss\n       of precision.\n\nFor more information, see the\nPNG specification for chunk contents.  Be careful with trusting\nrowbytes, as some of the transformations could increase the space\nneeded to hold a row (expand, filler, gray_to_rgb, etc.).\nSee png_read_update_info(), below.\n\nA quick word about text_ptr and num_text.  PNG stores comments in\nkeyword/text pairs, one pair per chunk, with no limit on the number\nof text chunks, and a 2^31 byte limit on their size.  While there are\nsuggested keywords, there is no requirement to restrict the use to these\nstrings.  It is strongly suggested that keywords and text be sensible\nto humans (that's the point), so don't use abbreviations.  Non-printing\nsymbols are not allowed.  See the PNG specification for more details.\nThere is also no requirement to have text after the keyword.\n\nKeywords should be limited to 79 Latin-1 characters without leading or\ntrailing spaces, but non-consecutive spaces are allowed within the\nkeyword.  It is possible to have the same keyword any number of times.\nThe text_ptr is an array of png_text structures, each holding a\npointer to a language string, a pointer to a keyword and a pointer to\na text string.  The text string, language code, and translated\nkeyword may be empty or NULL pointers.  The keyword/text\npairs are put into the array in the order that they are received.\nHowever, some or all of the text chunks may be after the image, so, to\nmake sure you have read all the text chunks, don't mess with these\nuntil after you read the stuff after the image.  This will be\nmentioned again below in the discussion that goes with png_read_end().\n\n.SS Input transformations\n\nAfter you've read the header information, you can set up the library\nto handle any special transformations of the image data.  The various\nways to transform the data will be described in the order that they\nshould occur.  This is important, as some of these change the color\ntype and/or bit depth of the data, and some others only work on\ncertain color types and bit depths.\n\nTransformations you request are ignored if they don't have any meaning for a\nparticular input data format.  However some transformations can have an effect\nas a result of a previous transformation.  If you specify a contradictory set of\ntransformations, for example both adding and removing the alpha channel, you\ncannot predict the final result.\n\nThe color used for the transparency values should be supplied in the same\nformat/depth as the current image data.  It is stored in the same format/depth\nas the image data in a tRNS chunk, so this is what libpng expects for this data.\n\nThe color used for the background value depends on the need_expand argument as\ndescribed below.\n\nData will be decoded into the supplied row buffers packed into bytes\nunless the library has been told to transform it into another format.\nFor example, 4 bit/pixel paletted or grayscale data will be returned\n2 pixels/byte with the leftmost pixel in the high-order bits of the byte,\nunless png_set_packing() is called.  8-bit RGB data will be stored\nin RGB RGB RGB format unless png_set_filler() or png_set_add_alpha()\nis called to insert filler bytes, either before or after each RGB triplet.\n\n16-bit RGB data will be returned RRGGBB RRGGBB, with the most significant\nbyte of the color value first, unless png_set_scale_16() is called to\ntransform it to regular RGB RGB triplets, or png_set_filler() or\npng_set_add alpha() is called to insert two filler bytes, either before\nor after each RRGGBB triplet.  Similarly, 8-bit or 16-bit grayscale data can\nbe modified with png_set_filler(), png_set_add_alpha(), png_set_strip_16(),\nor png_set_scale_16().\n\nThe following code transforms grayscale images of less than 8 to 8 bits,\nchanges paletted images to RGB, and adds a full alpha channel if there is\ntransparency information in a tRNS chunk.  This is most useful on\ngrayscale images with bit depths of 2 or 4 or if there is a multiple-image\nviewing application that wishes to treat all images in the same way.\n\n    if (color_type == PNG_COLOR_TYPE_PALETTE)\n        png_set_palette_to_rgb(png_ptr);\n\n    if (png_get_valid(png_ptr, info_ptr,\n        PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);\n\n    if (color_type == PNG_COLOR_TYPE_GRAY &&\n        bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr);\n\nThe first two functions are actually aliases for png_set_expand(), added\nin libpng version 1.0.4, with the function names expanded to improve code\nreadability.  In some future version they may actually do different\nthings.\n\nAs of libpng version 1.2.9, png_set_expand_gray_1_2_4_to_8() was\nadded.  It expands the sample depth without changing tRNS to alpha.\n\nAs of libpng version 1.5.2, png_set_expand_16() was added.  It behaves as\npng_set_expand(); however, the resultant channels have 16 bits rather than 8.\nUse this when the output color or gray channels are made linear to avoid fairly\nsevere accuracy loss.\n\n   if (bit_depth < 16)\n      png_set_expand_16(png_ptr);\n\nPNG can have files with 16 bits per channel.  If you only can handle\n8 bits per channel, this will strip the pixels down to 8-bit.\n\n    if (bit_depth == 16)\n#if PNG_LIBPNG_VER >= 10504\n       png_set_scale_16(png_ptr);\n#else\n       png_set_strip_16(png_ptr);\n#endif\n\n(The more accurate \"png_set_scale_16()\" API became available in libpng version\n1.5.4).\n\nIf you need to process the alpha channel on the image separately from the image\ndata (for example if you convert it to a bitmap mask) it is possible to have\nlibpng strip the channel leaving just RGB or gray data:\n\n    if (color_type & PNG_COLOR_MASK_ALPHA)\n       png_set_strip_alpha(png_ptr);\n\nIf you strip the alpha channel you need to find some other way of dealing with\nthe information.  If, instead, you want to convert the image to an opaque\nversion with no alpha channel use png_set_background; see below.\n\nAs of libpng version 1.5.2, almost all useful expansions are supported, the\nmajor ommissions are conversion of grayscale to indexed images (which can be\ndone trivially in the application) and conversion of indexed to grayscale (which\ncan be done by a trivial manipulation of the palette.)\n\nIn the following table, the 01 means grayscale with depth<8, 31 means\nindexed with depth<8, other numerals represent the color type, \"T\" means\nthe tRNS chunk is present, A means an alpha channel is present, and O\nmeans tRNS or alpha is present but all pixels in the image are opaque.\n\n  FROM  01  31   0  0T  0O   2  2T  2O   3  3T  3O  4A  4O  6A  6O\n   TO\n   01    -  [G]  -   -   -   -   -   -   -   -   -   -   -   -   -\n   31   [Q]  Q  [Q] [Q] [Q]  Q   Q   Q   Q   Q   Q  [Q] [Q]  Q   Q\n    0    1   G   +   .   .   G   G   G   G   G   G   B   B  GB  GB\n   0T    lt  Gt  t   +   .   Gt  G   G   Gt  G   G   Bt  Bt GBt GBt\n   0O    lt  Gt  t   .   +   Gt  Gt  G   Gt  Gt  G   Bt  Bt GBt GBt\n    2    C   P   C   C   C   +   .   .   C   -   -  CB  CB   B   B\n   2T    Ct  -   Ct  C   C   t   +   t   -   -   -  CBt CBt  Bt  Bt\n   2O    Ct  -   Ct  C   C   t   t   +   -   -   -  CBt CBt  Bt  Bt\n    3   [Q]  p  [Q] [Q] [Q]  Q   Q   Q   +   .   .  [Q] [Q]  Q   Q\n   3T   [Qt] p  [Qt][Q] [Q]  Qt  Qt  Qt  t   +   t  [Qt][Qt] Qt  Qt\n   3O   [Qt] p  [Qt][Q] [Q]  Qt  Qt  Qt  t   t   +  [Qt][Qt] Qt  Qt\n   4A    lA  G   A   T   T   GA  GT  GT  GA  GT  GT  +   BA  G  GBA\n   4O    lA GBA  A   T   T   GA  GT  GT  GA  GT  GT  BA  +  GBA  G\n   6A    CA  PA  CA  C   C   A   T  tT   PA  P   P   C  CBA  +   BA\n   6O    CA PBA  CA  C   C   A  tT   T   PA  P   P  CBA  C   BA  +\n\nWithin the matrix,\n     \"+\" identifies entries where 'from' and 'to' are the same.\n     \"-\" means the transformation is not supported.\n     \".\" means nothing is necessary (a tRNS chunk can just be ignored).\n     \"t\" means the transformation is obtained by png_set_tRNS.\n     \"A\" means the transformation is obtained by png_set_add_alpha().\n     \"X\" means the transformation is obtained by png_set_expand().\n     \"1\" means the transformation is obtained by\n         png_set_expand_gray_1_2_4_to_8() (and by png_set_expand()\n         if there is no transparency in the original or the final\n         format).\n     \"C\" means the transformation is obtained by png_set_gray_to_rgb().\n     \"G\" means the transformation is obtained by png_set_rgb_to_gray().\n     \"P\" means the transformation is obtained by\n         png_set_expand_palette_to_rgb().\n     \"p\" means the transformation is obtained by png_set_packing().\n     \"Q\" means the transformation is obtained by png_set_quantize().\n     \"T\" means the transformation is obtained by\n         png_set_tRNS_to_alpha().\n     \"B\" means the transformation is obtained by\n         png_set_background(), or png_strip_alpha().\n\nWhen an entry has multiple transforms listed all are required to cause the\nright overall transformation.  When two transforms are separated by a comma\neither will do the job.  When transforms are enclosed in [] the transform should\ndo the job but this is currently unimplemented - a different format will result\nif the suggested transformations are used.\n\nIn PNG files, the alpha channel in an image\nis the level of opacity.  If you need the alpha channel in an image to\nbe the level of transparency instead of opacity, you can invert the\nalpha channel (or the tRNS chunk data) after it's read, so that 0 is\nfully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit\nimages) is fully transparent, with\n\n    png_set_invert_alpha(png_ptr);\n\nPNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as\nthey can, resulting in, for example, 8 pixels per byte for 1 bit\nfiles.  This code expands to 1 pixel per byte without changing the\nvalues of the pixels:\n\n    if (bit_depth < 8)\n       png_set_packing(png_ptr);\n\nPNG files have possible bit depths of 1, 2, 4, 8, and 16.  All pixels\nstored in a PNG image have been \"scaled\" or \"shifted\" up to the next\nhigher possible bit depth (e.g. from 5 bits/sample in the range [0,31]\nto 8 bits/sample in the range [0, 255]).  However, it is also possible\nto convert the PNG pixel data back to the original bit depth of the\nimage.  This call reduces the pixels back down to the original bit depth:\n\n    png_color_8p sig_bit;\n\n    if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))\n       png_set_shift(png_ptr, sig_bit);\n\nPNG files store 3-color pixels in red, green, blue order.  This code\nchanges the storage of the pixels to blue, green, red:\n\n    if (color_type == PNG_COLOR_TYPE_RGB ||\n        color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n       png_set_bgr(png_ptr);\n\nPNG files store RGB pixels packed into 3 or 6 bytes. This code expands them\ninto 4 or 8 bytes for windowing systems that need them in this format:\n\n    if (color_type == PNG_COLOR_TYPE_RGB)\n       png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE);\n\nwhere \"filler\" is the 8-bit or 16-bit number to fill with, and the location\nis either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether\nyou want the filler before the RGB or after. When filling an 8-bit pixel,\nthe least significant 8 bits of the number are used, if a 16-bit number is\nsupplied.  This transformation does not affect images that already have full\nalpha channels.  To add an opaque alpha channel, use filler=0xffff and\nPNG_FILLER_AFTER which will generate RGBA pixels.\n\nNote that png_set_filler() does not change the color type.  If you want\nto do that, you can add a true alpha channel with\n\n    if (color_type == PNG_COLOR_TYPE_RGB ||\n       color_type == PNG_COLOR_TYPE_GRAY)\n       png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER);\n\nwhere \"filler\" contains the alpha value to assign to each pixel.\nThe png_set_add_alpha() function was added in libpng-1.2.7.\n\nIf you are reading an image with an alpha channel, and you need the\ndata as ARGB instead of the normal PNG format RGBA:\n\n    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n       png_set_swap_alpha(png_ptr);\n\nFor some uses, you may want a grayscale image to be represented as\nRGB.  This code will do that conversion:\n\n    if (color_type == PNG_COLOR_TYPE_GRAY ||\n        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n       png_set_gray_to_rgb(png_ptr);\n\nConversely, you can convert an RGB or RGBA image to grayscale or grayscale\nwith alpha.\n\n    if (color_type == PNG_COLOR_TYPE_RGB ||\n        color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n       png_set_rgb_to_gray(png_ptr, error_action,\n          double red_weight, double green_weight);\n\n    error_action = 1: silently do the conversion\n\n    error_action = 2: issue a warning if the original\n                      image has any pixel where\n                      red != green or red != blue\n\n    error_action = 3: issue an error and abort the\n                      conversion if the original\n                      image has any pixel where\n                      red != green or red != blue\n\n    red_weight:       weight of red component\n\n    green_weight:     weight of green component\n                      If either weight is negative, default\n                      weights are used.\n\nIn the corresponding fixed point API the red_weight and green_weight values are\nsimply scaled by 100,000:\n\n    png_set_rgb_to_gray(png_ptr, error_action,\n       png_fixed_point red_weight,\n       png_fixed_point green_weight);\n\nIf you have set error_action = 1 or 2, you can\nlater check whether the image really was gray, after processing\nthe image rows, with the png_get_rgb_to_gray_status(png_ptr) function.\nIt will return a png_byte that is zero if the image was gray or\n1 if there were any non-gray pixels.  Background and sBIT data\nwill be silently converted to grayscale, using the green channel\ndata for sBIT, regardless of the error_action setting.\n\nThe default values come from the PNG file cHRM chunk if present; otherwise, the\ndefaults correspond to the ITU-R recommendation 709, and also the sRGB color\nspace, as recommended in the Charles Poynton's Colour FAQ,\nCopyright (c) 2006-11-28 Charles Poynton, in section 9:\n\n<http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC9>\n\n    Y = 0.2126 * R + 0.7152 * G + 0.0722 * B\n\nPrevious versions of this document, 1998 through 2002, recommended a slightly\ndifferent formula:\n\n    Y = 0.212671 * R + 0.715160 * G + 0.072169 * B\n\nLibpng uses an integer approximation:\n\n    Y = (6968 * R + 23434 * G + 2366 * B)/32768\n\nThe calculation is done in a linear colorspace, if the image gamma\ncan be determined.\n\nThe png_set_background() function has been described already; it tells libpng to\ncomposite images with alpha or simple transparency against the supplied\nbackground color.  For compatibility with versions of libpng earlier than\nlibpng-1.5.4 it is recommended that you call the function after reading the file\nheader, even if you don't want to use the color in a bKGD chunk, if one exists.\n\nIf the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),\nyou may use this color, or supply another color more suitable for\nthe current display (e.g., the background color from a web page).  You\nneed to tell libpng how the color is represented, both the format of the\ncomponent values in the color (the number of bits) and the gamma encoding of the\ncolor.  The function takes two arguments, background_gamma_mode and need_expand\nto convey this information; however, only two combinations are likely to be\nuseful:\n\n    png_color_16 my_background;\n    png_color_16p image_background;\n\n    if (png_get_bKGD(png_ptr, info_ptr, &image_background))\n       png_set_background(png_ptr, image_background,\n           PNG_BACKGROUND_GAMMA_FILE, 1/*needs to be expanded*/, 1);\n    else\n       png_set_background(png_ptr, &my_background,\n           PNG_BACKGROUND_GAMMA_SCREEN, 0/*do not expand*/, 1);\n\nThe second call was described above - my_background is in the format of the\nfinal, display, output produced by libpng.  Because you now know the format of\nthe PNG it is possible to avoid the need to choose either 8-bit or 16-bit\noutput and to retain palette images (the palette colors will be modified\nappropriately and the tRNS chunk removed.)  However, if you are doing this,\ntake great care not to ask for transformations without checking first that\nthey apply!\n\nIn the first call the background color has the original bit depth and color type\nof the PNG file.  So, for palette images the color is supplied as a palette\nindex and for low bit greyscale images the color is a reduced bit value in\nimage_background->gray.\n\nIf you didn't call png_set_gamma() before reading the file header, for example\nif you need your code to remain compatible with older versions of libpng prior\nto libpng-1.5.4, this is the place to call it.\n\nDo not call it if you called png_set_alpha_mode(); doing so will damage the\nsettings put in place by png_set_alpha_mode().  (If png_set_alpha_mode() is\nsupported then you can certainly do png_set_gamma() before reading the PNG\nheader.)\n\nThis API unconditionally sets the screen and file gamma values, so it will\noverride the value in the PNG file unless it is called before the PNG file\nreading starts.  For this reason you must always call it with the PNG file\nvalue when you call it in this position:\n\n   if (png_get_gAMA(png_ptr, info_ptr, &file_gamma))\n      png_set_gamma(png_ptr, screen_gamma, file_gamma);\n\n   else\n      png_set_gamma(png_ptr, screen_gamma, 0.45455);\n\nIf you need to reduce an RGB file to a paletted file, or if a paletted\nfile has more entries than will fit on your screen, png_set_quantize()\nwill do that.  Note that this is a simple match quantization that merely\nfinds the closest color available.  This should work fairly well with\noptimized palettes, but fairly badly with linear color cubes.  If you\npass a palette that is larger than maximum_colors, the file will\nreduce the number of colors in the palette so it will fit into\nmaximum_colors.  If there is a histogram, libpng will use it to make\nmore intelligent choices when reducing the palette.  If there is no\nhistogram, it may not do as good a job.\n\n   if (color_type & PNG_COLOR_MASK_COLOR)\n   {\n      if (png_get_valid(png_ptr, info_ptr,\n          PNG_INFO_PLTE))\n      {\n         png_uint_16p histogram = NULL;\n\n         png_get_hIST(png_ptr, info_ptr,\n             &histogram);\n         png_set_quantize(png_ptr, palette, num_palette,\n            max_screen_colors, histogram, 1);\n      }\n\n      else\n      {\n         png_color std_color_cube[MAX_SCREEN_COLORS] =\n            { ... colors ... };\n\n         png_set_quantize(png_ptr, std_color_cube,\n            MAX_SCREEN_COLORS, MAX_SCREEN_COLORS,\n            NULL,0);\n      }\n   }\n\nPNG files describe monochrome as black being zero and white being one.\nThe following code will reverse this (make black be one and white be\nzero):\n\n   if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY)\n      png_set_invert_mono(png_ptr);\n\nThis function can also be used to invert grayscale and gray-alpha images:\n\n   if (color_type == PNG_COLOR_TYPE_GRAY ||\n       color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n      png_set_invert_mono(png_ptr);\n\nPNG files store 16-bit pixels in network byte order (big-endian,\nie. most significant bits first).  This code changes the storage to the\nother way (little-endian, i.e. least significant bits first, the\nway PCs store them):\n\n    if (bit_depth == 16)\n       png_set_swap(png_ptr);\n\nIf you are using packed-pixel images (1, 2, or 4 bits/pixel), and you\nneed to change the order the pixels are packed into bytes, you can use:\n\n    if (bit_depth < 8)\n       png_set_packswap(png_ptr);\n\nFinally, you can write your own transformation function if none of\nthe existing ones meets your needs.  This is done by setting a callback\nwith\n\n    png_set_read_user_transform_fn(png_ptr,\n        read_transform_fn);\n\nYou must supply the function\n\n    void read_transform_fn(png_structp png_ptr, png_row_infop\n        row_info, png_bytep data)\n\nSee pngtest.c for a working example.  Your function will be called\nafter all of the other transformations have been processed.  Take care with\ninterlaced images if you do the interlace yourself - the width of the row is the\nwidth in 'row_info', not the overall image width.\n\nIf supported, libpng provides two information routines that you can use to find\nwhere you are in processing the image:\n\n   png_get_current_pass_number(png_structp png_ptr);\n   png_get_current_row_number(png_structp png_ptr);\n\nDon't try using these outside a transform callback - firstly they are only\nsupported if user transforms are supported, secondly they may well return\nunexpected results unless the row is actually being processed at the moment they\nare called.\n\nWith interlaced\nimages the value returned is the row in the input sub-image image.  Use\nPNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to\nfind the output pixel (x,y) given an interlaced sub-image pixel (row,col,pass).\n\nThe discussion of interlace handling above contains more information on how to\nuse these values.\n\nYou can also set up a pointer to a user structure for use by your\ncallback function, and you can inform libpng that your transform\nfunction will change the number of channels or bit depth with the\nfunction\n\n    png_set_user_transform_info(png_ptr, user_ptr,\n        user_depth, user_channels);\n\nThe user's application, not libpng, is responsible for allocating and\nfreeing any memory required for the user structure.\n\nYou can retrieve the pointer via the function\npng_get_user_transform_ptr().  For example:\n\n    voidp read_user_transform_ptr =\n        png_get_user_transform_ptr(png_ptr);\n\nThe last thing to handle is interlacing; this is covered in detail below,\nbut you must call the function here if you want libpng to handle expansion\nof the interlaced image.\n\n    number_of_passes = png_set_interlace_handling(png_ptr);\n\nAfter setting the transformations, libpng can update your png_info\nstructure to reflect any transformations you've requested with this\ncall.\n\n    png_read_update_info(png_ptr, info_ptr);\n\nThis is most useful to update the info structure's rowbytes\nfield so you can use it to allocate your image memory.  This function\nwill also update your palette with the correct screen_gamma and\nbackground if these have been given with the calls above.  You may\nonly call png_read_update_info() once with a particular info_ptr.\n\nAfter you call png_read_update_info(), you can allocate any\nmemory you need to hold the image.  The row data is simply\nraw byte data for all forms of images.  As the actual allocation\nvaries among applications, no example will be given.  If you\nare allocating one large chunk, you will need to build an\narray of pointers to each row, as it will be needed for some\nof the functions below.\n\nRemember: Before you call png_read_update_info(), the png_get_*()\nfunctions return the values corresponding to the original PNG image.\nAfter you call png_read_update_info the values refer to the image\nthat libpng will output.  Consequently you must call all the png_set_\nfunctions before you call png_read_update_info().  This is particularly\nimportant for png_set_interlace_handling() - if you are going to call\npng_read_update_info() you must call png_set_interlace_handling() before\nit unless you want to receive interlaced output.\n\n.SS Reading image data\n\nAfter you've allocated memory, you can read the image data.\nThe simplest way to do this is in one function call.  If you are\nallocating enough memory to hold the whole image, you can just\ncall png_read_image() and libpng will read in all the image data\nand put it in the memory area supplied.  You will need to pass in\nan array of pointers to each row.\n\nThis function automatically handles interlacing, so you don't\nneed to call png_set_interlace_handling() (unless you call\npng_read_update_info()) or call this function multiple times, or any\nof that other stuff necessary with png_read_rows().\n\n   png_read_image(png_ptr, row_pointers);\n\nwhere row_pointers is:\n\n   png_bytep row_pointers[height];\n\nYou can point to void or char or whatever you use for pixels.\n\nIf you don't want to read in the whole image at once, you can\nuse png_read_rows() instead.  If there is no interlacing (check\ninterlace_type == PNG_INTERLACE_NONE), this is simple:\n\n    png_read_rows(png_ptr, row_pointers, NULL,\n        number_of_rows);\n\nwhere row_pointers is the same as in the png_read_image() call.\n\nIf you are doing this just one row at a time, you can do this with\na single row_pointer instead of an array of row_pointers:\n\n    png_bytep row_pointer = row;\n    png_read_row(png_ptr, row_pointer, NULL);\n\nIf the file is interlaced (interlace_type != 0 in the IHDR chunk), things\nget somewhat harder.  The only current (PNG Specification version 1.2)\ninterlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7);\na somewhat complicated 2D interlace scheme, known as Adam7, that\nbreaks down an image into seven smaller images of varying size, based\non an 8x8 grid.  This number is defined (from libpng 1.5) as\nPNG_INTERLACE_ADAM7_PASSES in png.h\n\nlibpng can fill out those images or it can give them to you \"as is\".\nIt is almost always better to have libpng handle the interlacing for you.\nIf you want the images filled out, there are two ways to do that.  The one\nmentioned in the PNG specification is to expand each pixel to cover\nthose pixels that have not been read yet (the \"rectangle\" method).\nThis results in a blocky image for the first pass, which gradually\nsmooths out as more pixels are read.  The other method is the \"sparkle\"\nmethod, where pixels are drawn only in their final locations, with the\nrest of the image remaining whatever colors they were initialized to\nbefore the start of the read.  The first method usually looks better,\nbut tends to be slower, as there are more pixels to put in the rows.\n\nIf, as is likely, you want libpng to expand the images, call this before\ncalling png_start_read_image() or png_read_update_info():\n\n    if (interlace_type == PNG_INTERLACE_ADAM7)\n       number_of_passes\n           = png_set_interlace_handling(png_ptr);\n\nThis will return the number of passes needed.  Currently, this is seven,\nbut may change if another interlace type is added.  This function can be\ncalled even if the file is not interlaced, where it will return one pass.\nYou then need to read the whole image 'number_of_passes' times.  Each time\nwill distribute the pixels from the current pass to the correct place in\nthe output image, so you need to supply the same rows to png_read_rows in\neach pass.\n\nIf you are not going to display the image after each pass, but are\ngoing to wait until the entire image is read in, use the sparkle\neffect.  This effect is faster and the end result of either method\nis exactly the same.  If you are planning on displaying the image\nafter each pass, the \"rectangle\" effect is generally considered the\nbetter looking one.\n\nIf you only want the \"sparkle\" effect, just call png_read_rows() as\nnormal, with the third parameter NULL.  Make sure you make pass over\nthe image number_of_passes times, and you don't change the data in the\nrows between calls.  You can change the locations of the data, just\nnot the data.  Each pass only writes the pixels appropriate for that\npass, and assumes the data from previous passes is still valid.\n\n    png_read_rows(png_ptr, row_pointers, NULL,\n        number_of_rows);\n\nIf you only want the first effect (the rectangles), do the same as\nbefore except pass the row buffer in the third parameter, and leave\nthe second parameter NULL.\n\n    png_read_rows(png_ptr, NULL, row_pointers,\n        number_of_rows);\n\nIf you don't want libpng to handle the interlacing details, just call\npng_read_rows() PNG_INTERLACE_ADAM7_PASSES times to read in all the images.\nEach of the images is a valid image by itself; however, you will almost\ncertainly need to distribute the pixels from each sub-image to the\ncorrect place.  This is where everything gets very tricky.\n\nIf you want to retrieve the separate images you must pass the correct\nnumber of rows to each successive call of png_read_rows().  The calculation\ngets pretty complicated for small images, where some sub-images may\nnot even exist because either their width or height ends up zero.\nlibpng provides two macros to help you in 1.5 and later versions:\n\n   png_uint_32 width = PNG_PASS_COLS(image_width, pass_number);\n   png_uint_32 height = PNG_PASS_ROWS(image_height, pass_number);\n\nRespectively these tell you the width and height of the sub-image\ncorresponding to the numbered pass.  'pass' is in in the range 0 to 6 -\nthis can be confusing because the specification refers to the same passes\nas 1 to 7!  Be careful, you must check both the width and height before\ncalling png_read_rows() and not call it for that pass if either is zero.\n\nYou can, of course, read each sub-image row by row.  If you want to\nproduce optimal code to make a pixel-by-pixel transformation of an\ninterlaced image this is the best approach; read each row of each pass,\ntransform it, and write it out to a new interlaced image.\n\nIf you want to de-interlace the image yourself libpng provides further\nmacros to help that tell you where to place the pixels in the output image.\nBecause the interlacing scheme is rectangular - sub-image pixels are always\narranged on a rectangular grid - all you need to know for each pass is the\nstarting column and row in the output image of the first pixel plus the\nspacing between each pixel.  As of libpng 1.5 there are four macros to\nretrieve this information:\n\n   png_uint_32 x = PNG_PASS_START_COL(pass);\n   png_uint_32 y = PNG_PASS_START_ROW(pass);\n   png_uint_32 xStep = 1U << PNG_PASS_COL_SHIFT(pass);\n   png_uint_32 yStep = 1U << PNG_PASS_ROW_SHIFT(pass);\n\nThese allow you to write the obvious loop:\n\n   png_uint_32 input_y = 0;\n   png_uint_32 output_y = PNG_PASS_START_ROW(pass);\n\n   while (output_y < output_image_height)\n   {\n      png_uint_32 input_x = 0;\n      png_uint_32 output_x = PNG_PASS_START_COL(pass);\n\n      while (output_x < output_image_width)\n      {\n         image[output_y][output_x] =\n             subimage[pass][input_y][input_x++];\n\n         output_x += xStep;\n      }\n\n      ++input_y;\n      output_y += yStep;\n   }\n\nNotice that the steps between successive output rows and columns are\nreturned as shifts.  This is possible because the pixels in the subimages\nare always a power of 2 apart - 1, 2, 4 or 8 pixels - in the original\nimage.  In practice you may need to directly calculate the output coordinate\ngiven an input coordinate.  libpng provides two further macros for this\npurpose:\n\n   png_uint_32 output_x = PNG_COL_FROM_PASS_COL(input_x, pass);\n   png_uint_32 output_y = PNG_ROW_FROM_PASS_ROW(input_y, pass);\n\nFinally a pair of macros are provided to tell you if a particular image\nrow or column appears in a given pass:\n\n   int col_in_pass = PNG_COL_IN_INTERLACE_PASS(output_x, pass);\n   int row_in_pass = PNG_ROW_IN_INTERLACE_PASS(output_y, pass);\n\nBear in mind that you will probably also need to check the width and height\nof the pass in addition to the above to be sure the pass even exists!\n\nWith any luck you are convinced by now that you don't want to do your own\ninterlace handling.  In reality normally the only good reason for doing this\nis if you are processing PNG files on a pixel-by-pixel basis and don't want\nto load the whole file into memory when it is interlaced.\n\nlibpng includes a test program, pngvalid, that illustrates reading and\nwriting of interlaced images.  If you can't get interlacing to work in your\ncode and don't want to leave it to libpng (the recommended approach), see\nhow pngvalid.c does it.\n\n.SS Finishing a sequential read\n\nAfter you are finished reading the image through the\nlow-level interface, you can finish reading the file.\n\nIf you want to use a different crc action for handling CRC errors in\nchunks after the image data, you can call png_set_crc_action()\nagain at this point.\n\nIf you are interested in comments or time, which may be stored either\nbefore or after the image data, you should pass the separate png_info\nstruct if you want to keep the comments from before and after the image\nseparate.\n\n    png_infop end_info = png_create_info_struct(png_ptr);\n\n    if (!end_info)\n    {\n       png_destroy_read_struct(&png_ptr, &info_ptr,\n           (png_infopp)NULL);\n       return (ERROR);\n    }\n\n   png_read_end(png_ptr, end_info);\n\nIf you are not interested, you should still call png_read_end()\nbut you can pass NULL, avoiding the need to create an end_info structure.\nIf you do this, libpng will not process any chunks after IDAT other than\nskipping over them and perhaps (depending on whether you have called\npng_set_crc_action) checking their CRCs while looking for the IEND chunk.\n\n   png_read_end(png_ptr, (png_infop)NULL);\n\nIf you don't call png_read_end(), then your file pointer will be\nleft pointing to the first chunk after the last IDAT, which is probably\nnot what you want if you expect to read something beyond the end of\nthe PNG datastream.\n\nWhen you are done, you can free all memory allocated by libpng like this:\n\n   png_destroy_read_struct(&png_ptr, &info_ptr,\n       &end_info);\n\nor, if you didn't create an end_info structure,\n\n   png_destroy_read_struct(&png_ptr, &info_ptr,\n       (png_infopp)NULL);\n\nIt is also possible to individually free the info_ptr members that\npoint to libpng-allocated storage with the following function:\n\n    png_free_data(png_ptr, info_ptr, mask, seq)\n\n    mask - identifies data to be freed, a mask\n           containing the bitwise OR of one or\n           more of\n             PNG_FREE_PLTE, PNG_FREE_TRNS,\n             PNG_FREE_HIST, PNG_FREE_ICCP,\n             PNG_FREE_PCAL, PNG_FREE_ROWS,\n             PNG_FREE_SCAL, PNG_FREE_SPLT,\n             PNG_FREE_TEXT, PNG_FREE_UNKN,\n           or simply PNG_FREE_ALL\n\n    seq  - sequence number of item to be freed\n           (\\-1 for all items)\n\nThis function may be safely called when the relevant storage has\nalready been freed, or has not yet been allocated, or was allocated\nby the user and not by libpng,  and will in those cases do nothing.\nThe \"seq\" parameter is ignored if only one item of the selected data\ntype, such as PLTE, is allowed.  If \"seq\" is not \\-1, and multiple items\nare allowed for the data type identified in the mask, such as text or\nsPLT, only the n'th item in the structure is freed, where n is \"seq\".\n\nThe default behavior is only to free data that was allocated internally\nby libpng.  This can be changed, so that libpng will not free the data,\nor so that it will free data that was allocated by the user with png_malloc()\nor png_calloc() and passed in via a png_set_*() function, with\n\n    png_data_freer(png_ptr, info_ptr, freer, mask)\n\n    freer  - one of\n               PNG_DESTROY_WILL_FREE_DATA\n               PNG_SET_WILL_FREE_DATA\n               PNG_USER_WILL_FREE_DATA\n\n    mask   - which data elements are affected\n             same choices as in png_free_data()\n\nThis function only affects data that has already been allocated.\nYou can call this function after reading the PNG data but before calling\nany png_set_*() functions, to control whether the user or the png_set_*()\nfunction is responsible for freeing any existing data that might be present,\nand again after the png_set_*() functions to control whether the user\nor png_destroy_*() is supposed to free the data.  When the user assumes\nresponsibility for libpng-allocated data, the application must use\npng_free() to free it, and when the user transfers responsibility to libpng\nfor data that the user has allocated, the user must have used png_malloc()\nor png_calloc() to allocate it.\n\nIf you allocated your row_pointers in a single block, as suggested above in\nthe description of the high level read interface, you must not transfer\nresponsibility for freeing it to the png_set_rows or png_read_destroy function,\nbecause they would also try to free the individual row_pointers[i].\n\nIf you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword\nseparately, do not transfer responsibility for freeing text_ptr to libpng,\nbecause when libpng fills a png_text structure it combines these members with\nthe key member, and png_free_data() will free only text_ptr.key.  Similarly,\nif you transfer responsibility for free'ing text_ptr from libpng to your\napplication, your application must not separately free those members.\n\nThe png_free_data() function will turn off the \"valid\" flag for anything\nit frees.  If you need to turn the flag off for a chunk that was freed by\nyour application instead of by libpng, you can use\n\n    png_set_invalid(png_ptr, info_ptr, mask);\n\n    mask - identifies the chunks to be made invalid,\n           containing the bitwise OR of one or\n           more of\n             PNG_INFO_gAMA, PNG_INFO_sBIT,\n             PNG_INFO_cHRM, PNG_INFO_PLTE,\n             PNG_INFO_tRNS, PNG_INFO_bKGD,\n             PNG_INFO_hIST, PNG_INFO_pHYs,\n             PNG_INFO_oFFs, PNG_INFO_tIME,\n             PNG_INFO_pCAL, PNG_INFO_sRGB,\n             PNG_INFO_iCCP, PNG_INFO_sPLT,\n             PNG_INFO_sCAL, PNG_INFO_IDAT\n\nFor a more compact example of reading a PNG image, see the file example.c.\n\n.SS Reading PNG files progressively\n\nThe progressive reader is slightly different from the non-progressive\nreader.  Instead of calling png_read_info(), png_read_rows(), and\npng_read_end(), you make one call to png_process_data(), which calls\ncallbacks when it has the info, a row, or the end of the image.  You\nset up these callbacks with png_set_progressive_read_fn().  You don't\nhave to worry about the input/output functions of libpng, as you are\ngiving the library the data directly in png_process_data().  I will\nassume that you have read the section on reading PNG files above,\nso I will only highlight the differences (although I will show\nall of the code).\n\npng_structp png_ptr;\npng_infop info_ptr;\n\n /*  An example code fragment of how you would\n     initialize the progressive reader in your\n     application. */\n int\n initialize_png_reader()\n {\n    png_ptr = png_create_read_struct\n        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,\n         user_error_fn, user_warning_fn);\n\n    if (!png_ptr)\n        return (ERROR);\n\n    info_ptr = png_create_info_struct(png_ptr);\n\n    if (!info_ptr)\n    {\n       png_destroy_read_struct(&png_ptr,\n          (png_infopp)NULL, (png_infopp)NULL);\n       return (ERROR);\n    }\n\n    if (setjmp(png_jmpbuf(png_ptr)))\n    {\n       png_destroy_read_struct(&png_ptr, &info_ptr,\n          (png_infopp)NULL);\n       return (ERROR);\n    }\n\n    /* This one's new.  You can provide functions\n       to be called when the header info is valid,\n       when each row is completed, and when the image\n       is finished.  If you aren't using all functions,\n       you can specify NULL parameters.  Even when all\n       three functions are NULL, you need to call\n       png_set_progressive_read_fn().  You can use\n       any struct as the user_ptr (cast to a void pointer\n       for the function call), and retrieve the pointer\n       from inside the callbacks using the function\n\n          png_get_progressive_ptr(png_ptr);\n\n       which will return a void pointer, which you have\n       to cast appropriately.\n     */\n    png_set_progressive_read_fn(png_ptr, (void *)user_ptr,\n        info_callback, row_callback, end_callback);\n\n    return 0;\n }\n\n /* A code fragment that you call as you receive blocks\n   of data */\n int\n process_data(png_bytep buffer, png_uint_32 length)\n {\n    if (setjmp(png_jmpbuf(png_ptr)))\n    {\n       png_destroy_read_struct(&png_ptr, &info_ptr,\n           (png_infopp)NULL);\n       return (ERROR);\n    }\n\n    /* This one's new also.  Simply give it a chunk\n       of data from the file stream (in order, of\n       course).  On machines with segmented memory\n       models machines, don't give it any more than\n       64K.  The library seems to run fine with sizes\n       of 4K. Although you can give it much less if\n       necessary (I assume you can give it chunks of\n       1 byte, I haven't tried less than 256 bytes\n       yet).  When this function returns, you may\n       want to display any rows that were generated\n       in the row callback if you don't already do\n       so there.\n     */\n    png_process_data(png_ptr, info_ptr, buffer, length);\n\n    /* At this point you can call png_process_data_skip if\n       you want to handle data the library will skip yourself;\n       it simply returns the number of bytes to skip (and stops\n       libpng skipping that number of bytes on the next\n       png_process_data call).\n    return 0;\n }\n\n /* This function is called (as set by\n    png_set_progressive_read_fn() above) when enough data\n    has been supplied so all of the header has been\n    read.\n */\n void\n info_callback(png_structp png_ptr, png_infop info)\n {\n    /* Do any setup here, including setting any of\n       the transformations mentioned in the Reading\n       PNG files section.  For now, you _must_ call\n       either png_start_read_image() or\n       png_read_update_info() after all the\n       transformations are set (even if you don't set\n       any).  You may start getting rows before\n       png_process_data() returns, so this is your\n       last chance to prepare for that.\n\n       This is where you turn on interlace handling,\n       assuming you don't want to do it yourself.\n\n       If you need to you can stop the processing of\n       your original input data at this point by calling\n       png_process_data_pause.  This returns the number\n       of unprocessed bytes from the last png_process_data\n       call - it is up to you to ensure that the next call\n       sees these bytes again.  If you don't want to bother\n       with this you can get libpng to cache the unread\n       bytes by setting the 'save' parameter (see png.h) but\n       then libpng will have to copy the data internally.\n     */\n }\n\n /* This function is called when each row of image\n    data is complete */\n void\n row_callback(png_structp png_ptr, png_bytep new_row,\n    png_uint_32 row_num, int pass)\n {\n    /* If the image is interlaced, and you turned\n       on the interlace handler, this function will\n       be called for every row in every pass.  Some\n       of these rows will not be changed from the\n       previous pass.  When the row is not changed,\n       the new_row variable will be NULL.  The rows\n       and passes are called in order, so you don't\n       really need the row_num and pass, but I'm\n       supplying them because it may make your life\n       easier.\n\n       If you did not turn on interlace handling then\n       the callback is called for each row of each\n       sub-image when the image is interlaced.  In this\n       case 'row_num' is the row in the sub-image, not\n       the row in the output image as it is in all other\n       cases.\n\n       For the non-NULL rows of interlaced images when\n       you have switched on libpng interlace handling,\n       you must call png_progressive_combine_row()\n       passing in the row and the old row.  You can\n       call this function for NULL rows (it will just\n       return) and for non-interlaced images (it just\n       does the memcpy for you) if it will make the\n       code easier.  Thus, you can just do this for\n       all cases if you switch on interlace handling;\n     */\n\n        png_progressive_combine_row(png_ptr, old_row,\n          new_row);\n\n    /* where old_row is what was displayed\n       previously for the row.  Note that the first\n       pass (pass == 0, really) will completely cover\n       the old row, so the rows do not have to be\n       initialized.  After the first pass (and only\n       for interlaced images), you will have to pass\n       the current row, and the function will combine\n       the old row and the new row.\n\n       You can also call png_process_data_pause in this\n       callback - see above.\n    */\n }\n\n void\n end_callback(png_structp png_ptr, png_infop info)\n {\n    /* This function is called after the whole image\n       has been read, including any chunks after the\n       image (up to and including the IEND).  You\n       will usually have the same info chunk as you\n       had in the header, although some data may have\n       been added to the comments and time fields.\n\n       Most people won't do much here, perhaps setting\n       a flag that marks the image as finished.\n     */\n }\n\n\n\n.SH IV. Writing\n\nMuch of this is very similar to reading.  However, everything of\nimportance is repeated here, so you won't have to constantly look\nback up in the reading section to understand writing.\n\n.SS Setup\n\nYou will want to do the I/O initialization before you get into libpng,\nso if it doesn't work, you don't have anything to undo. If you are not\nusing the standard I/O functions, you will need to replace them with\ncustom writing functions.  See the discussion under Customizing libpng.\n\n    FILE *fp = fopen(file_name, \"wb\");\n\n    if (!fp)\n       return (ERROR);\n\nNext, png_struct and png_info need to be allocated and initialized.\nAs these can be both relatively large, you may not want to store these\non the stack, unless you have stack space to spare.  Of course, you\nwill want to check if they return NULL.  If you are also reading,\nyou won't want to name your read structure and your write structure\nboth \"png_ptr\"; you can call them anything you like, such as\n\"read_ptr\" and \"write_ptr\".  Look at pngtest.c, for example.\n\n    png_structp png_ptr = png_create_write_struct\n       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,\n        user_error_fn, user_warning_fn);\n\n    if (!png_ptr)\n       return (ERROR);\n\n    png_infop info_ptr = png_create_info_struct(png_ptr);\n    if (!info_ptr)\n    {\n       png_destroy_write_struct(&png_ptr,\n           (png_infopp)NULL);\n       return (ERROR);\n    }\n\nIf you want to use your own memory allocation routines,\ndefine PNG_USER_MEM_SUPPORTED and use\npng_create_write_struct_2() instead of png_create_write_struct():\n\n    png_structp png_ptr = png_create_write_struct_2\n       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,\n        user_error_fn, user_warning_fn, (png_voidp)\n        user_mem_ptr, user_malloc_fn, user_free_fn);\n\nAfter you have these structures, you will need to set up the\nerror handling.  When libpng encounters an error, it expects to\nlongjmp() back to your routine.  Therefore, you will need to call\nsetjmp() and pass the png_jmpbuf(png_ptr).  If you\nwrite the file from different routines, you will need to update\nthe png_jmpbuf(png_ptr) every time you enter a new routine that will\ncall a png_*() function.  See your documentation of setjmp/longjmp\nfor your compiler for more information on setjmp/longjmp.  See\nthe discussion on libpng error handling in the Customizing Libpng\nsection below for more information on the libpng error handling.\n\n    if (setjmp(png_jmpbuf(png_ptr)))\n    {\n    png_destroy_write_struct(&png_ptr, &info_ptr);\n       fclose(fp);\n       return (ERROR);\n    }\n    ...\n    return;\n\nIf you would rather avoid the complexity of setjmp/longjmp issues,\nyou can compile libpng with PNG_NO_SETJMP, in which case\nerrors will result in a call to PNG_ABORT() which defaults to abort().\n\nYou can #define PNG_ABORT() to a function that does something\nmore useful than abort(), as long as your function does not\nreturn.\n\nChecking for invalid palette index on write was added at libpng\n1.5.10.  If a pixel contains an invalid (out-of-range) index libpng issues\na benign error.  This is enabled by default because this condition is an\nerror according to the PNG specification, Clause 11.3.2, but the error can\nbe ignored in each png_ptr with\n\n   png_set_check_for_invalid_index(png_ptr, 0);\n\nIf the error is ignored, or if png_benign_error() treats it as a warning,\nany invalid pixels are written as-is by the encoder, resulting in an\ninvalid PNG datastream as output.  In this case the application is\nresponsible for ensuring that the pixel indexes are in range when it writes\na PLTE chunk with fewer entries than the bit depth would allow.\n\nNow you need to set up the output code.  The default for libpng is to\nuse the C function fwrite().  If you use this, you will need to pass a\nvalid FILE * in the function png_init_io().  Be sure that the file is\nopened in binary mode.  Again, if you wish to handle writing data in\nanother way, see the discussion on libpng I/O handling in the Customizing\nLibpng section below.\n\n    png_init_io(png_ptr, fp);\n\nIf you are embedding your PNG into a datastream such as MNG, and don't\nwant libpng to write the 8-byte signature, or if you have already\nwritten the signature in your application, use\n\n    png_set_sig_bytes(png_ptr, 8);\n\nto inform libpng that it should not write a signature.\n\n.SS Write callbacks\n\nAt this point, you can set up a callback function that will be\ncalled after each row has been written, which you can use to control\na progress meter or the like.  It's demonstrated in pngtest.c.\nYou must supply a function\n\n    void write_row_callback(png_structp png_ptr, png_uint_32 row,\n       int pass);\n    {\n      /* put your code here */\n    }\n\n(You can give it another name that you like instead of \"write_row_callback\")\n\nTo inform libpng about your function, use\n\n    png_set_write_status_fn(png_ptr, write_row_callback);\n\nWhen this function is called the row has already been completely processed and\nit has also been written out.  The 'row' and 'pass' refer to the next row to be\nhandled.  For the\nnon-interlaced case the row that was just handled is simply one less than the\npassed in row number, and pass will always be 0.  For the interlaced case the\nsame applies unless the row value is 0, in which case the row just handled was\nthe last one from one of the preceding passes.  Because interlacing may skip a\npass you cannot be sure that the preceding pass is just 'pass\\-1', if you really\nneed to know what the last pass is record (row,pass) from the callback and use\nthe last recorded value each time.\n\nAs with the user transform you can find the output row using the\nPNG_ROW_FROM_PASS_ROW macro.\n\nYou now have the option of modifying how the compression library will\nrun.  The following functions are mainly for testing, but may be useful\nin some cases, like if you need to write PNG files extremely fast and\nare willing to give up some compression, or if you want to get the\nmaximum possible compression at the expense of slower writing.  If you\nhave no special needs in this area, let the library do what it wants by\nnot calling this function at all, as it has been tuned to deliver a good\nspeed/compression ratio. The second parameter to png_set_filter() is\nthe filter method, for which the only valid values are 0 (as of the\nJuly 1999 PNG specification, version 1.2) or 64 (if you are writing\na PNG datastream that is to be embedded in a MNG datastream).  The third\nparameter is a flag that indicates which filter type(s) are to be tested\nfor each scanline.  See the PNG specification for details on the specific\nfilter types.\n\n\n    /* turn on or off filtering, and/or choose\n       specific filters.  You can use either a single\n       PNG_FILTER_VALUE_NAME or the bitwise OR of one\n       or more PNG_FILTER_NAME masks.\n     */\n    png_set_filter(png_ptr, 0,\n       PNG_FILTER_NONE  | PNG_FILTER_VALUE_NONE |\n       PNG_FILTER_SUB   | PNG_FILTER_VALUE_SUB  |\n       PNG_FILTER_UP    | PNG_FILTER_VALUE_UP   |\n       PNG_FILTER_AVG   | PNG_FILTER_VALUE_AVG  |\n       PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|\n       PNG_ALL_FILTERS);\n\nIf an application wants to start and stop using particular filters during\ncompression, it should start out with all of the filters (to ensure that\nthe previous row of pixels will be stored in case it's needed later),\nand then add and remove them after the start of compression.\n\nIf you are writing a PNG datastream that is to be embedded in a MNG\ndatastream, the second parameter can be either 0 or 64.\n\nThe png_set_compression_*() functions interface to the zlib compression\nlibrary, and should mostly be ignored unless you really know what you are\ndoing.  The only generally useful call is png_set_compression_level()\nwhich changes how much time zlib spends on trying to compress the image\ndata.  See the Compression Library (zlib.h and algorithm.txt, distributed\nwith zlib) for details on the compression levels.\n\n    #include zlib.h\n\n    /* Set the zlib compression level */\n    png_set_compression_level(png_ptr,\n        Z_BEST_COMPRESSION);\n\n    /* Set other zlib parameters for compressing IDAT */\n    png_set_compression_mem_level(png_ptr, 8);\n    png_set_compression_strategy(png_ptr,\n        Z_DEFAULT_STRATEGY);\n    png_set_compression_window_bits(png_ptr, 15);\n    png_set_compression_method(png_ptr, 8);\n    png_set_compression_buffer_size(png_ptr, 8192)\n\n    /* Set zlib parameters for text compression\n     * If you don't call these, the parameters\n     * fall back on those defined for IDAT chunks\n     */\n    png_set_text_compression_mem_level(png_ptr, 8);\n    png_set_text_compression_strategy(png_ptr,\n        Z_DEFAULT_STRATEGY);\n    png_set_text_compression_window_bits(png_ptr, 15);\n    png_set_text_compression_method(png_ptr, 8);\n\n.SS Setting the contents of info for output\n\nYou now need to fill in the png_info structure with all the data you\nwish to write before the actual image.  Note that the only thing you\nare allowed to write after the image is the text chunks and the time\nchunk (as of PNG Specification 1.2, anyway).  See png_write_end() and\nthe latest PNG specification for more information on that.  If you\nwish to write them before the image, fill them in now, and flag that\ndata as being valid.  If you want to wait until after the data, don't\nfill them until png_write_end().  For all the fields in png_info and\ntheir data types, see png.h.  For explanations of what the fields\ncontain, see the PNG specification.\n\nSome of the more important parts of the png_info are:\n\n    png_set_IHDR(png_ptr, info_ptr, width, height,\n       bit_depth, color_type, interlace_type,\n       compression_type, filter_method)\n\n    width          - holds the width of the image\n                     in pixels (up to 2^31).\n\n    height         - holds the height of the image\n                     in pixels (up to 2^31).\n\n    bit_depth      - holds the bit depth of one of the\n                     image channels.\n                     (valid values are 1, 2, 4, 8, 16\n                     and depend also on the\n                     color_type.  See also significant\n                     bits (sBIT) below).\n\n    color_type     - describes which color/alpha\n                     channels are present.\n                     PNG_COLOR_TYPE_GRAY\n                        (bit depths 1, 2, 4, 8, 16)\n                     PNG_COLOR_TYPE_GRAY_ALPHA\n                        (bit depths 8, 16)\n                     PNG_COLOR_TYPE_PALETTE\n                        (bit depths 1, 2, 4, 8)\n                     PNG_COLOR_TYPE_RGB\n                        (bit_depths 8, 16)\n                     PNG_COLOR_TYPE_RGB_ALPHA\n                        (bit_depths 8, 16)\n\n                     PNG_COLOR_MASK_PALETTE\n                     PNG_COLOR_MASK_COLOR\n                     PNG_COLOR_MASK_ALPHA\n\n    interlace_type - PNG_INTERLACE_NONE or\n                     PNG_INTERLACE_ADAM7\n\n    compression_type - (must be\n                     PNG_COMPRESSION_TYPE_DEFAULT)\n\n    filter_method  - (must be PNG_FILTER_TYPE_DEFAULT\n                     or, if you are writing a PNG to\n                     be embedded in a MNG datastream,\n                     can also be\n                     PNG_INTRAPIXEL_DIFFERENCING)\n\nIf you call png_set_IHDR(), the call must appear before any of the\nother png_set_*() functions, because they might require access to some of\nthe IHDR settings.  The remaining png_set_*() functions can be called\nin any order.\n\nIf you wish, you can reset the compression_type, interlace_type, or\nfilter_method later by calling png_set_IHDR() again; if you do this, the\nwidth, height, bit_depth, and color_type must be the same in each call.\n\n    png_set_PLTE(png_ptr, info_ptr, palette,\n       num_palette);\n\n    palette        - the palette for the file\n                     (array of png_color)\n    num_palette    - number of entries in the palette\n\n\n    png_set_gAMA(png_ptr, info_ptr, file_gamma);\n    png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);\n\n    file_gamma     - the gamma at which the image was\n                     created (PNG_INFO_gAMA)\n\n    int_file_gamma - 100,000 times the gamma at which\n                     the image was created\n\n    png_set_cHRM(png_ptr, info_ptr,  white_x, white_y, red_x, red_y,\n                     green_x, green_y, blue_x, blue_y)\n    png_set_cHRM_XYZ(png_ptr, info_ptr, red_X, red_Y, red_Z, green_X,\n                     green_Y, green_Z, blue_X, blue_Y, blue_Z)\n    png_set_cHRM_fixed(png_ptr, info_ptr, int_white_x, int_white_y,\n                     int_red_x, int_red_y, int_green_x, int_green_y,\n                     int_blue_x, int_blue_y)\n    png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, int_red_X, int_red_Y,\n                     int_red_Z, int_green_X, int_green_Y, int_green_Z,\n                     int_blue_X, int_blue_Y, int_blue_Z)\n\n    {white,red,green,blue}_{x,y}\n                     A color space encoding specified using the chromaticities\n                     of the end points and the white point.\n\n    {red,green,blue}_{X,Y,Z}\n                     A color space encoding specified using the encoding end\n                     points - the CIE tristimulus specification of the intended\n                     color of the red, green and blue channels in the PNG RGB\n                     data.  The white point is simply the sum of the three end\n                     points.\n\n    png_set_sRGB(png_ptr, info_ptr, srgb_intent);\n\n    srgb_intent    - the rendering intent\n                     (PNG_INFO_sRGB) The presence of\n                     the sRGB chunk means that the pixel\n                     data is in the sRGB color space.\n                     This chunk also implies specific\n                     values of gAMA and cHRM.  Rendering\n                     intent is the CSS-1 property that\n                     has been defined by the International\n                     Color Consortium\n                     (http://www.color.org).\n                     It can be one of\n                     PNG_sRGB_INTENT_SATURATION,\n                     PNG_sRGB_INTENT_PERCEPTUAL,\n                     PNG_sRGB_INTENT_ABSOLUTE, or\n                     PNG_sRGB_INTENT_RELATIVE.\n\n\n    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,\n       srgb_intent);\n\n    srgb_intent    - the rendering intent\n                     (PNG_INFO_sRGB) The presence of the\n                     sRGB chunk means that the pixel\n                     data is in the sRGB color space.\n                     This function also causes gAMA and\n                     cHRM chunks with the specific values\n                     that are consistent with sRGB to be\n                     written.\n\n    png_set_iCCP(png_ptr, info_ptr, name, compression_type,\n                       profile, proflen);\n\n    name             - The profile name.\n\n    compression_type - The compression type; always\n                       PNG_COMPRESSION_TYPE_BASE for PNG 1.0.\n                       You may give NULL to this argument to\n                       ignore it.\n\n    profile          - International Color Consortium color\n                       profile data. May contain NULs.\n\n    proflen          - length of profile data in bytes.\n\n    png_set_sBIT(png_ptr, info_ptr, sig_bit);\n\n    sig_bit        - the number of significant bits for\n                     (PNG_INFO_sBIT) each of the gray, red,\n                     green, and blue channels, whichever are\n                     appropriate for the given color type\n                     (png_color_16)\n\n    png_set_tRNS(png_ptr, info_ptr, trans_alpha,\n       num_trans, trans_color);\n\n    trans_alpha    - array of alpha (transparency)\n                     entries for palette (PNG_INFO_tRNS)\n\n    num_trans      - number of transparent entries\n                     (PNG_INFO_tRNS)\n\n    trans_color    - graylevel or color sample values\n                     (in order red, green, blue) of the\n                     single transparent color for\n                     non-paletted images (PNG_INFO_tRNS)\n\n    png_set_hIST(png_ptr, info_ptr, hist);\n\n    hist           - histogram of palette (array of\n                     png_uint_16) (PNG_INFO_hIST)\n\n    png_set_tIME(png_ptr, info_ptr, mod_time);\n\n    mod_time       - time image was last modified\n                     (PNG_VALID_tIME)\n\n    png_set_bKGD(png_ptr, info_ptr, background);\n\n    background     - background color (of type\n                     png_color_16p) (PNG_VALID_bKGD)\n\n    png_set_text(png_ptr, info_ptr, text_ptr, num_text);\n\n    text_ptr       - array of png_text holding image\n                     comments\n\n    text_ptr[i].compression - type of compression used\n                 on \"text\" PNG_TEXT_COMPRESSION_NONE\n                           PNG_TEXT_COMPRESSION_zTXt\n                           PNG_ITXT_COMPRESSION_NONE\n                           PNG_ITXT_COMPRESSION_zTXt\n    text_ptr[i].key   - keyword for comment.  Must contain\n                 1-79 characters.\n    text_ptr[i].text  - text comments for current\n                         keyword.  Can be NULL or empty.\n    text_ptr[i].text_length - length of text string,\n                 after decompression, 0 for iTXt\n    text_ptr[i].itxt_length - length of itxt string,\n                 after decompression, 0 for tEXt/zTXt\n    text_ptr[i].lang  - language of comment (NULL or\n                         empty for unknown).\n    text_ptr[i].translated_keyword  - keyword in UTF-8 (NULL\n                         or empty for unknown).\n\n    Note that the itxt_length, lang, and lang_key\n    members of the text_ptr structure only exist when the\n    library is built with iTXt chunk support.  Prior to\n    libpng-1.4.0 the library was built by default without\n    iTXt support. Also note that when iTXt is supported,\n    they contain NULL pointers when the \"compression\"\n    field contains PNG_TEXT_COMPRESSION_NONE or\n    PNG_TEXT_COMPRESSION_zTXt.\n\n    num_text       - number of comments\n\n    png_set_sPLT(png_ptr, info_ptr, &palette_ptr,\n       num_spalettes);\n\n    palette_ptr    - array of png_sPLT_struct structures\n                     to be added to the list of palettes\n                     in the info structure.\n    num_spalettes  - number of palette structures to be\n                     added.\n\n    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,\n        unit_type);\n\n    offset_x  - positive offset from the left\n                     edge of the screen\n\n    offset_y  - positive offset from the top\n                     edge of the screen\n\n    unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER\n\n    png_set_pHYs(png_ptr, info_ptr, res_x, res_y,\n        unit_type);\n\n    res_x       - pixels/unit physical resolution\n                  in x direction\n\n    res_y       - pixels/unit physical resolution\n                  in y direction\n\n    unit_type   - PNG_RESOLUTION_UNKNOWN,\n                  PNG_RESOLUTION_METER\n\n    png_set_sCAL(png_ptr, info_ptr, unit, width, height)\n\n    unit        - physical scale units (an integer)\n\n    width       - width of a pixel in physical scale units\n\n    height      - height of a pixel in physical scale units\n                  (width and height are doubles)\n\n    png_set_sCAL_s(png_ptr, info_ptr, unit, width, height)\n\n    unit        - physical scale units (an integer)\n\n    width       - width of a pixel in physical scale units\n                  expressed as a string\n\n    height      - height of a pixel in physical scale units\n                 (width and height are strings like \"2.54\")\n\n    png_set_unknown_chunks(png_ptr, info_ptr, &unknowns,\n       num_unknowns)\n\n    unknowns          - array of png_unknown_chunk\n                        structures holding unknown chunks\n    unknowns[i].name  - name of unknown chunk\n    unknowns[i].data  - data of unknown chunk\n    unknowns[i].size  - size of unknown chunk's data\n    unknowns[i].location - position to write chunk in file\n                           0: do not write chunk\n                           PNG_HAVE_IHDR: before PLTE\n                           PNG_HAVE_PLTE: before IDAT\n                           PNG_AFTER_IDAT: after IDAT\n\nThe \"location\" member is set automatically according to\nwhat part of the output file has already been written.\nYou can change its value after calling png_set_unknown_chunks()\nas demonstrated in pngtest.c.  Within each of the \"locations\",\nthe chunks are sequenced according to their position in the\nstructure (that is, the value of \"i\", which is the order in which\nthe chunk was either read from the input file or defined with\npng_set_unknown_chunks).\n\nA quick word about text and num_text.  text is an array of png_text\nstructures.  num_text is the number of valid structures in the array.\nEach png_text structure holds a language code, a keyword, a text value,\nand a compression type.\n\nThe compression types have the same valid numbers as the compression\ntypes of the image data.  Currently, the only valid number is zero.\nHowever, you can store text either compressed or uncompressed, unlike\nimages, which always have to be compressed.  So if you don't want the\ntext compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.\nBecause tEXt and zTXt chunks don't have a language field, if you\nspecify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt\nany language code or translated keyword will not be written out.\n\nUntil text gets around a few hundred bytes, it is not worth compressing it.\nAfter the text has been written out to the file, the compression type\nis set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,\nso that it isn't written out again at the end (in case you are calling\npng_write_end() with the same struct).\n\nThe keywords that are given in the PNG Specification are:\n\n    Title            Short (one line) title or\n                     caption for image\n\n    Author           Name of image's creator\n\n    Description      Description of image (possibly long)\n\n    Copyright        Copyright notice\n\n    Creation Time    Time of original image creation\n                     (usually RFC 1123 format, see below)\n\n    Software         Software used to create the image\n\n    Disclaimer       Legal disclaimer\n\n    Warning          Warning of nature of content\n\n    Source           Device used to create the image\n\n    Comment          Miscellaneous comment; conversion\n                     from other image format\n\nThe keyword-text pairs work like this.  Keywords should be short\nsimple descriptions of what the comment is about.  Some typical\nkeywords are found in the PNG specification, as is some recommendations\non keywords.  You can repeat keywords in a file.  You can even write\nsome text before the image and some after.  For example, you may want\nto put a description of the image before the image, but leave the\ndisclaimer until after, so viewers working over modem connections\ndon't have to wait for the disclaimer to go over the modem before\nthey start seeing the image.  Finally, keywords should be full\nwords, not abbreviations.  Keywords and text are in the ISO 8859-1\n(Latin-1) character set (a superset of regular ASCII) and can not\ncontain NUL characters, and should not contain control or other\nunprintable characters.  To make the comments widely readable, stick\nwith basic ASCII, and avoid machine specific character set extensions\nlike the IBM-PC character set.  The keyword must be present, but\nyou can leave off the text string on non-compressed pairs.\nCompressed pairs must have a text string, as only the text string\nis compressed anyway, so the compression would be meaningless.\n\nPNG supports modification time via the png_time structure.  Two\nconversion routines are provided, png_convert_from_time_t() for\ntime_t and png_convert_from_struct_tm() for struct tm.  The\ntime_t routine uses gmtime().  You don't have to use either of\nthese, but if you wish to fill in the png_time structure directly,\nyou should provide the time in universal time (GMT) if possible\ninstead of your local time.  Note that the year number is the full\nyear (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and\nthat months start with 1.\n\nIf you want to store the time of the original image creation, you should\nuse a plain tEXt chunk with the \"Creation Time\" keyword.  This is\nnecessary because the \"creation time\" of a PNG image is somewhat vague,\ndepending on whether you mean the PNG file, the time the image was\ncreated in a non-PNG format, a still photo from which the image was\nscanned, or possibly the subject matter itself.  In order to facilitate\nmachine-readable dates, it is recommended that the \"Creation Time\"\ntEXt chunk use RFC 1123 format dates (e.g. \"22 May 1997 18:07:10 GMT\"),\nalthough this isn't a requirement.  Unlike the tIME chunk, the\n\"Creation Time\" tEXt chunk is not expected to be automatically changed\nby the software.  To facilitate the use of RFC 1123 dates, a function\npng_convert_to_rfc1123_buffer(buffer, png_timep) is provided to\nconvert from PNG time to an RFC 1123 format string.  The caller must provide\na writeable buffer of at least 29 bytes.\n\n.SS Writing unknown chunks\n\nYou can use the png_set_unknown_chunks function to queue up private chunks\nfor writing.  You give it a chunk name, location, raw data, and a size.  You\nalso must use png_set_keep_unknown_chunks() to ensure that libpng will\nhandle them.  That's all there is to it.  The chunks will be written by the\nnext following png_write_info_before_PLTE, png_write_info, or png_write_end\nfunction, depending upon the specified location.  Any chunks previously\nread into the info structure's unknown-chunk list will also be written out\nin a sequence that satisfies the PNG specification's ordering rules.\n\nHere is an example of writing two private chunks, prVt and miNE:\n\n    #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED\n    /* Set unknown chunk data */\n    png_unknown_chunk unk_chunk[2];\n    strcpy((char *) unk_chunk[0].name, \"prVt\";\n    unk_chunk[0].data = (unsigned char *) \"PRIVATE DATA\";\n    unk_chunk[0].size = strlen(unk_chunk[0].data)+1;\n    unk_chunk[0].location = PNG_HAVE_IHDR;\n    strcpy((char *) unk_chunk[1].name, \"miNE\";\n    unk_chunk[1].data = (unsigned char *) \"MY CHUNK DATA\";\n    unk_chunk[1].size = strlen(unk_chunk[0].data)+1;\n    unk_chunk[1].location = PNG_AFTER_IDAT;\n    png_set_unknown_chunks(write_ptr, write_info_ptr,\n        unk_chunk, 2);\n    /* Needed because miNE is not safe-to-copy */\n    png_set_keep_unknown_chunks(png, PNG_HANDLE_CHUNK_ALWAYS,\n       (png_bytep) \"miNE\", 1);\n    # if PNG_LIBPNG_VER < 10600\n      /* Deal with unknown chunk location bug in 1.5.x and earlier */\n      png_set_unknown_chunk_location(png, info, 0, PNG_HAVE_IHDR);\n      png_set_unknown_chunk_location(png, info, 1, PNG_AFTER_IDAT);\n    # endif\n    # if PNG_LIBPNG_VER < 10500\n      /* PNG_AFTER_IDAT writes two copies of the chunk prior to libpng-1.5.0,\n       * one before IDAT and another after IDAT, so don't use it; only use\n       * PNG_HAVE_IHDR location.  This call resets the location previously\n       * set by assignment and png_set_unknown_chunk_location() for chunk 1.\n       */\n      png_set_unknown_chunk_location(png, info, 1, PNG_HAVE_IHDR);\n    # endif\n    #endif\n\n.SS The high-level write interface\n\nAt this point there are two ways to proceed; through the high-level\nwrite interface, or through a sequence of low-level write operations.\nYou can use the high-level interface if your image data is present\nin the info structure.  All defined output\ntransformations are permitted, enabled by the following masks.\n\n    PNG_TRANSFORM_IDENTITY      No transformation\n    PNG_TRANSFORM_PACKING       Pack 1, 2 and 4-bit samples\n    PNG_TRANSFORM_PACKSWAP      Change order of packed\n                                pixels to LSB first\n    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images\n    PNG_TRANSFORM_SHIFT         Normalize pixels to the\n                                sBIT depth\n    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA\n                                to BGRA\n    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA\n                                to AG\n    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity\n                                to transparency\n    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples\n    PNG_TRANSFORM_STRIP_FILLER        Strip out filler\n                                      bytes (deprecated).\n    PNG_TRANSFORM_STRIP_FILLER_BEFORE Strip out leading\n                                      filler bytes\n    PNG_TRANSFORM_STRIP_FILLER_AFTER  Strip out trailing\n                                      filler bytes\n\nIf you have valid image data in the info structure (you can use\npng_set_rows() to put image data in the info structure), simply do this:\n\n    png_write_png(png_ptr, info_ptr, png_transforms, NULL)\n\nwhere png_transforms is an integer containing the bitwise OR of some set of\ntransformation flags.  This call is equivalent to png_write_info(),\nfollowed the set of transformations indicated by the transform mask,\nthen png_write_image(), and finally png_write_end().\n\n(The final parameter of this call is not yet used.  Someday it might point\nto transformation parameters required by some future output transform.)\n\nYou must use png_transforms and not call any png_set_transform() functions\nwhen you use png_write_png().\n\n.SS The low-level write interface\n\nIf you are going the low-level route instead, you are now ready to\nwrite all the file information up to the actual image data.  You do\nthis with a call to png_write_info().\n\n    png_write_info(png_ptr, info_ptr);\n\nNote that there is one transformation you may need to do before\npng_write_info().  In PNG files, the alpha channel in an image is the\nlevel of opacity.  If your data is supplied as a level of transparency,\nyou can invert the alpha channel before you write it, so that 0 is\nfully transparent and 255 (in 8-bit or paletted images) or 65535\n(in 16-bit images) is fully opaque, with\n\n    png_set_invert_alpha(png_ptr);\n\nThis must appear before png_write_info() instead of later with the\nother transformations because in the case of paletted images the tRNS\nchunk data has to be inverted before the tRNS chunk is written.  If\nyour image is not a paletted image, the tRNS data (which in such cases\nrepresents a single color to be rendered as transparent) won't need to\nbe changed, and you can safely do this transformation after your\npng_write_info() call.\n\nIf you need to write a private chunk that you want to appear before\nthe PLTE chunk when PLTE is present, you can write the PNG info in\ntwo steps, and insert code to write your own chunk between them:\n\n    png_write_info_before_PLTE(png_ptr, info_ptr);\n    png_set_unknown_chunks(png_ptr, info_ptr, ...);\n    png_write_info(png_ptr, info_ptr);\n\nAfter you've written the file information, you can set up the library\nto handle any special transformations of the image data.  The various\nways to transform the data will be described in the order that they\nshould occur.  This is important, as some of these change the color\ntype and/or bit depth of the data, and some others only work on\ncertain color types and bit depths.  Even though each transformation\nchecks to see if it has data that it can do something with, you should\nmake sure to only enable a transformation if it will be valid for the\ndata.  For example, don't swap red and blue on grayscale data.\n\nPNG files store RGB pixels packed into 3 or 6 bytes.  This code tells\nthe library to strip input data that has 4 or 8 bytes per pixel down\nto 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2\nbytes per pixel).\n\n    png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);\n\nwhere the 0 is unused, and the location is either PNG_FILLER_BEFORE or\nPNG_FILLER_AFTER, depending upon whether the filler byte in the pixel\nis stored XRGB or RGBX.\n\nPNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as\nthey can, resulting in, for example, 8 pixels per byte for 1 bit files.\nIf the data is supplied at 1 pixel per byte, use this code, which will\ncorrectly pack the pixels into a single byte:\n\n    png_set_packing(png_ptr);\n\nPNG files reduce possible bit depths to 1, 2, 4, 8, and 16.  If your\ndata is of another bit depth, you can write an sBIT chunk into the\nfile so that decoders can recover the original data if desired.\n\n    /* Set the true bit depth of the image data */\n    if (color_type & PNG_COLOR_MASK_COLOR)\n    {\n       sig_bit.red = true_bit_depth;\n       sig_bit.green = true_bit_depth;\n       sig_bit.blue = true_bit_depth;\n    }\n\n    else\n    {\n       sig_bit.gray = true_bit_depth;\n    }\n\n    if (color_type & PNG_COLOR_MASK_ALPHA)\n    {\n       sig_bit.alpha = true_bit_depth;\n    }\n\n    png_set_sBIT(png_ptr, info_ptr, &sig_bit);\n\nIf the data is stored in the row buffer in a bit depth other than\none supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG),\nthis will scale the values to appear to be the correct bit depth as\nis required by PNG.\n\n    png_set_shift(png_ptr, &sig_bit);\n\nPNG files store 16-bit pixels in network byte order (big-endian,\nie. most significant bits first).  This code would be used if they are\nsupplied the other way (little-endian, i.e. least significant bits\nfirst, the way PCs store them):\n\n    if (bit_depth > 8)\n       png_set_swap(png_ptr);\n\nIf you are using packed-pixel images (1, 2, or 4 bits/pixel), and you\nneed to change the order the pixels are packed into bytes, you can use:\n\n    if (bit_depth < 8)\n       png_set_packswap(png_ptr);\n\nPNG files store 3 color pixels in red, green, blue order.  This code\nwould be used if they are supplied as blue, green, red:\n\n    png_set_bgr(png_ptr);\n\nPNG files describe monochrome as black being zero and white being\none. This code would be used if the pixels are supplied with this reversed\n(black being one and white being zero):\n\n    png_set_invert_mono(png_ptr);\n\nFinally, you can write your own transformation function if none of\nthe existing ones meets your needs.  This is done by setting a callback\nwith\n\n    png_set_write_user_transform_fn(png_ptr,\n       write_transform_fn);\n\nYou must supply the function\n\n    void write_transform_fn(png_structp png_ptr, png_row_infop\n       row_info, png_bytep data)\n\nSee pngtest.c for a working example.  Your function will be called\nbefore any of the other transformations are processed.  If supported\nlibpng also supplies an information routine that may be called from\nyour callback:\n\n   png_get_current_row_number(png_ptr);\n   png_get_current_pass_number(png_ptr);\n\nThis returns the current row passed to the transform.  With interlaced\nimages the value returned is the row in the input sub-image image.  Use\nPNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to\nfind the output pixel (x,y) given an interlaced sub-image pixel (row,col,pass).\n\nThe discussion of interlace handling above contains more information on how to\nuse these values.\n\nYou can also set up a pointer to a user structure for use by your\ncallback function.\n\n    png_set_user_transform_info(png_ptr, user_ptr, 0, 0);\n\nThe user_channels and user_depth parameters of this function are ignored\nwhen writing; you can set them to zero as shown.\n\nYou can retrieve the pointer via the function png_get_user_transform_ptr().\nFor example:\n\n    voidp write_user_transform_ptr =\n       png_get_user_transform_ptr(png_ptr);\n\nIt is possible to have libpng flush any pending output, either manually,\nor automatically after a certain number of lines have been written.  To\nflush the output stream a single time call:\n\n    png_write_flush(png_ptr);\n\nand to have libpng flush the output stream periodically after a certain\nnumber of scanlines have been written, call:\n\n    png_set_flush(png_ptr, nrows);\n\nNote that the distance between rows is from the last time png_write_flush()\nwas called, or the first row of the image if it has never been called.\nSo if you write 50 lines, and then png_set_flush 25, it will flush the\noutput on the next scanline, and every 25 lines thereafter, unless\npng_write_flush() is called before 25 more lines have been written.\nIf nrows is too small (less than about 10 lines for a 640 pixel wide\nRGB image) the image compression may decrease noticeably (although this\nmay be acceptable for real-time applications).  Infrequent flushing will\nonly degrade the compression performance by a few percent over images\nthat do not use flushing.\n\n.SS Writing the image data\n\nThat's it for the transformations.  Now you can write the image data.\nThe simplest way to do this is in one function call.  If you have the\nwhole image in memory, you can just call png_write_image() and libpng\nwill write the image.  You will need to pass in an array of pointers to\neach row.  This function automatically handles interlacing, so you don't\nneed to call png_set_interlace_handling() or call this function multiple\ntimes, or any of that other stuff necessary with png_write_rows().\n\n    png_write_image(png_ptr, row_pointers);\n\nwhere row_pointers is:\n\n    png_byte *row_pointers[height];\n\nYou can point to void or char or whatever you use for pixels.\n\nIf you don't want to write the whole image at once, you can\nuse png_write_rows() instead.  If the file is not interlaced,\nthis is simple:\n\n    png_write_rows(png_ptr, row_pointers,\n       number_of_rows);\n\nrow_pointers is the same as in the png_write_image() call.\n\nIf you are just writing one row at a time, you can do this with\na single row_pointer instead of an array of row_pointers:\n\n    png_bytep row_pointer = row;\n\n    png_write_row(png_ptr, row_pointer);\n\nWhen the file is interlaced, things can get a good deal more complicated.\nThe only currently (as of the PNG Specification version 1.2, dated July\n1999) defined interlacing scheme for PNG files is the \"Adam7\" interlace\nscheme, that breaks down an image into seven smaller images of varying\nsize.  libpng will build these images for you, or you can do them\nyourself.  If you want to build them yourself, see the PNG specification\nfor details of which pixels to write when.\n\nIf you don't want libpng to handle the interlacing details, just\nuse png_set_interlace_handling() and call png_write_rows() the\ncorrect number of times to write all the sub-images\n(png_set_interlace_handling() returns the number of sub-images.)\n\nIf you want libpng to build the sub-images, call this before you start\nwriting any rows:\n\n    number_of_passes = png_set_interlace_handling(png_ptr);\n\nThis will return the number of passes needed.  Currently, this is seven,\nbut may change if another interlace type is added.\n\nThen write the complete image number_of_passes times.\n\n    png_write_rows(png_ptr, row_pointers, number_of_rows);\n\nThink carefully before you write an interlaced image.  Typically code that\nreads such images reads all the image data into memory, uncompressed, before\ndoing any processing.  Only code that can display an image on the fly can\ntake advantage of the interlacing and even then the image has to be exactly\nthe correct size for the output device, because scaling an image requires\nadjacent pixels and these are not available until all the passes have been\nread.\n\nIf you do write an interlaced image you will hardly ever need to handle\nthe interlacing yourself.  Call png_set_interlace_handling() and use the\napproach described above.\n\nThe only time it is conceivable that you will really need to write an\ninterlaced image pass-by-pass is when you have read one pass by pass and\nmade some pixel-by-pixel transformation to it, as described in the read\ncode above.  In this case use the PNG_PASS_ROWS and PNG_PASS_COLS macros\nto determine the size of each sub-image in turn and simply write the rows\nyou obtained from the read code.\n\n.SS Finishing a sequential write\n\nAfter you are finished writing the image, you should finish writing\nthe file.  If you are interested in writing comments or time, you should\npass an appropriately filled png_info pointer.  If you are not interested,\nyou can pass NULL.\n\n    png_write_end(png_ptr, info_ptr);\n\nWhen you are done, you can free all memory used by libpng like this:\n\n    png_destroy_write_struct(&png_ptr, &info_ptr);\n\nIt is also possible to individually free the info_ptr members that\npoint to libpng-allocated storage with the following function:\n\n    png_free_data(png_ptr, info_ptr, mask, seq)\n\n    mask  - identifies data to be freed, a mask\n            containing the bitwise OR of one or\n            more of\n              PNG_FREE_PLTE, PNG_FREE_TRNS,\n              PNG_FREE_HIST, PNG_FREE_ICCP,\n              PNG_FREE_PCAL, PNG_FREE_ROWS,\n              PNG_FREE_SCAL, PNG_FREE_SPLT,\n              PNG_FREE_TEXT, PNG_FREE_UNKN,\n            or simply PNG_FREE_ALL\n\n    seq   - sequence number of item to be freed\n            (\\-1 for all items)\n\nThis function may be safely called when the relevant storage has\nalready been freed, or has not yet been allocated, or was allocated\nby the user  and not by libpng,  and will in those cases do nothing.\nThe \"seq\" parameter is ignored if only one item of the selected data\ntype, such as PLTE, is allowed.  If \"seq\" is not \\-1, and multiple items\nare allowed for the data type identified in the mask, such as text or\nsPLT, only the n'th item in the structure is freed, where n is \"seq\".\n\nIf you allocated data such as a palette that you passed in to libpng\nwith png_set_*, you must not free it until just before the call to\npng_destroy_write_struct().\n\nThe default behavior is only to free data that was allocated internally\nby libpng.  This can be changed, so that libpng will not free the data,\nor so that it will free data that was allocated by the user with png_malloc()\nor png_calloc() and passed in via a png_set_*() function, with\n\n    png_data_freer(png_ptr, info_ptr, freer, mask)\n\n    freer  - one of\n               PNG_DESTROY_WILL_FREE_DATA\n               PNG_SET_WILL_FREE_DATA\n               PNG_USER_WILL_FREE_DATA\n\n    mask   - which data elements are affected\n             same choices as in png_free_data()\n\nFor example, to transfer responsibility for some data from a read structure\nto a write structure, you could use\n\n    png_data_freer(read_ptr, read_info_ptr,\n       PNG_USER_WILL_FREE_DATA,\n       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)\n\n    png_data_freer(write_ptr, write_info_ptr,\n       PNG_DESTROY_WILL_FREE_DATA,\n       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)\n\nthereby briefly reassigning responsibility for freeing to the user but\nimmediately afterwards reassigning it once more to the write_destroy\nfunction.  Having done this, it would then be safe to destroy the read\nstructure and continue to use the PLTE, tRNS, and hIST data in the write\nstructure.\n\nThis function only affects data that has already been allocated.\nYou can call this function before calling after the png_set_*() functions\nto control whether the user or png_destroy_*() is supposed to free the data.\nWhen the user assumes responsibility for libpng-allocated data, the\napplication must use\npng_free() to free it, and when the user transfers responsibility to libpng\nfor data that the user has allocated, the user must have used png_malloc()\nor png_calloc() to allocate it.\n\nIf you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword\nseparately, do not transfer responsibility for freeing text_ptr to libpng,\nbecause when libpng fills a png_text structure it combines these members with\nthe key member, and png_free_data() will free only text_ptr.key.  Similarly,\nif you transfer responsibility for free'ing text_ptr from libpng to your\napplication, your application must not separately free those members.\nFor a more compact example of writing a PNG image, see the file example.c.\n\n.SH V. Simplified API\n\nThe simplified API, which became available in libpng-1.6.0, hides the details\nof both libpng and the PNG file format itself.\nIt allows PNG files to be read into a very limited number of\nin-memory bitmap formats or to be written from the same formats.  If these\nformats do not accommodate your needs then you can, and should, use the more\nsophisticated APIs above - these support a wide variety of in-memory formats\nand a wide variety of sophisticated transformations to those formats as well\nas a wide variety of APIs to manipulate ancilliary information.\n\nTo read a PNG file using the simplified API:\n\n  1) Declare a 'png_image' structure (see below) on the stack, set the\n     version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL\n     (this is REQUIRED, your program may crash if you don't do it.)\n\n  2) Call the appropriate png_image_begin_read... function.\n\n  3) Set the png_image 'format' member to the required sample format.\n\n  4) Allocate a buffer for the image and, if required, the color-map.\n\n  5) Call png_image_finish_read to read the image and, if required, the\n     color-map into your buffers.\n\nThere are no restrictions on the format of the PNG input itself; all valid\ncolor types, bit depths, and interlace methods are acceptable, and the\ninput image is transformed as necessary to the requested in-memory format\nduring the png_image_finish_read() step.  The only caveat is that if you\nrequest a color-mapped image from a PNG that is full-color or makes\ncomplex use of an alpha channel the transformation is extremely lossy and the\nresult may look terrible.\n\nTo write a PNG file using the simplified API:\n\n  1) Declare a 'png_image' structure on the stack and memset()\n     it to all zero.\n\n  2) Initialize the members of the structure that describe the\n     image, setting the 'format' member to the format of the\n     image samples.\n\n  3) Call the appropriate png_image_write... function with a\n     pointer to the image and, if necessary, the color-map to write\n     the PNG data.\n\npng_image is a structure that describes the in-memory format of an image\nwhen it is being read or defines the in-memory format of an image that you\nneed to write.  The \"png_image\" structure contains the following members:\n\n   png_controlp opaque  Initialize to NULL, free with png_image_free\n   png_uint_32  version Set to PNG_IMAGE_VERSION\n   png_uint_32  width   Image width in pixels (columns)\n   png_uint_32  height  Image height in pixels (rows)\n   png_uint_32  format  Image format as defined below\n   png_uint_32  flags   A bit mask containing informational flags\n   png_uint_32  colormap_entries; Number of entries in the color-map\n   png_uint_32  warning_or_error;\n   char         message[64];\n\nIn the event of an error or warning the \"warning_or_error\"\nfield will be set to a non-zero value and the 'message' field will contain\na '\\0' terminated string with the libpng error or warning message.  If both\nwarnings and an error were encountered, only the error is recorded.  If there\nare multiple warnings, only the first one is recorded.\n\nThe upper 30 bits of the \"warning_or_error\" value are reserved; the low two\nbits contain a two bit code such that a value more than 1 indicates a failure\nin the API just called:\n\n   0 - no warning or error\n   1 - warning\n   2 - error\n   3 - error preceded by warning\n\nThe pixels (samples) of the image have one to four channels whose components\nhave original values in the range 0 to 1.0:\n\n  1: A single gray or luminance channel (G).\n  2: A gray/luminance channel and an alpha channel (GA).\n  3: Three red, green, blue color channels (RGB).\n  4: Three color channels and an alpha channel (RGBA).\n\nThe channels are encoded in one of two ways:\n\n  a) As a small integer, value 0..255, contained in a single byte.  For the\nalpha channel the original value is simply value/255.  For the color or\nluminance channels the value is encoded according to the sRGB specification\nand matches the 8-bit format expected by typical display devices.\n\nThe color/gray channels are not scaled (pre-multiplied) by the alpha\nchannel and are suitable for passing to color management software.\n\n  b) As a value in the range 0..65535, contained in a 2-byte integer, in\nthe native byte order of the platform on which the application is running.\nAll channels can be converted to the original value by dividing by 65535; all\nchannels are linear.  Color channels use the RGB encoding (RGB end-points) of\nthe sRGB specification.  This encoding is identified by the\nPNG_FORMAT_FLAG_LINEAR flag below.\n\nWhen the simplified API needs to convert between sRGB and linear colorspaces,\nthe actual sRGB transfer curve defined in the sRGB specification (see the\narticle at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2\napproximation used elsewhere in libpng.\n\nWhen an alpha channel is present it is expected to denote pixel coverage\nof the color or luminance channels and is returned as an associated alpha\nchannel: the color/gray channels are scaled (pre-multiplied) by the alpha\nvalue.\n\nThe samples are either contained directly in the image data, between 1 and 8\nbytes per pixel according to the encoding, or are held in a color-map indexed\nby bytes in the image data.  In the case of a color-map the color-map entries\nare individual samples, encoded as above, and the image data has one byte per\npixel to select the relevant sample from the color-map.\n\nPNG_FORMAT_*\n\nThe #defines to be used in png_image::format.  Each #define identifies a\nparticular layout of channel data and, if present, alpha values.  There are\nseparate defines for each of the two component encodings.\n\nA format is built up using single bit flag values.  All combinations are\nvalid.  Formats can be built up from the flag values or you can use one of\nthe predefined values below.  When testing formats always use the FORMAT_FLAG\nmacros to test for individual features - future versions of the library may\nadd new flags.\n\nWhen reading or writing color-mapped images the format should be set to the\nformat of the entries in the color-map then png_image_{read,write}_colormap\ncalled to read or write the color-map and set the format correctly for the\nimage data.  Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly!\n\nNOTE: libpng can be built with particular features disabled. If you see\ncompiler errors because the definition of one of the following flags has been\ncompiled out it is because libpng does not have the required support.  It is\npossible, however, for the libpng configuration to enable the format on just\nread or just write; in that case you may see an error at run time.\nYou can guard against this by checking for the definition of the\nappropriate \"_SUPPORTED\" macro, one of:\n\n   PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED\n\n   PNG_FORMAT_FLAG_ALPHA    format with an alpha channel\n   PNG_FORMAT_FLAG_COLOR    color format: otherwise grayscale\n   PNG_FORMAT_FLAG_LINEAR   2-byte channels else 1-byte\n   PNG_FORMAT_FLAG_COLORMAP image data is color-mapped\n   PNG_FORMAT_FLAG_BGR      BGR colors, else order is RGB\n   PNG_FORMAT_FLAG_AFIRST   alpha channel comes first\n\nSupported formats are as follows.  Future versions of libpng may support more\nformats; for compatibility with older versions simply check if the format\nmacro is defined using #ifdef.  These defines describe the in-memory layout\nof the components of the pixels of the image.\n\nFirst the single byte (sRGB) formats:\n\n   PNG_FORMAT_GRAY\n   PNG_FORMAT_GA\n   PNG_FORMAT_AG\n   PNG_FORMAT_RGB\n   PNG_FORMAT_BGR\n   PNG_FORMAT_RGBA\n   PNG_FORMAT_ARGB\n   PNG_FORMAT_BGRA\n   PNG_FORMAT_ABGR\n\nThen the linear 2-byte formats.  When naming these \"Y\" is used to\nindicate a luminance (gray) channel.  The component order within the pixel\nis always the same - there is no provision for swapping the order of the\ncomponents in the linear format.  The components are 16-bit integers in\nthe native byte order for your platform, and there is no provision for\nswapping the bytes to a different endian condition.\n\n   PNG_FORMAT_LINEAR_Y\n   PNG_FORMAT_LINEAR_Y_ALPHA\n   PNG_FORMAT_LINEAR_RGB\n   PNG_FORMAT_LINEAR_RGB_ALPHA\n\nWith color-mapped formats the image data is one byte for each pixel. The byte\nis an index into the color-map which is formatted as above.  To obtain a\ncolor-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP\nto one of the above definitions, or you can use one of the definitions below.\n\n   PNG_FORMAT_RGB_COLORMAP\n   PNG_FORMAT_BGR_COLORMAP\n   PNG_FORMAT_RGBA_COLORMAP\n   PNG_FORMAT_ARGB_COLORMAP\n   PNG_FORMAT_BGRA_COLORMAP\n   PNG_FORMAT_ABGR_COLORMAP\n\nPNG_IMAGE macros\n\nThese are convenience macros to derive information from a png_image\nstructure.  The PNG_IMAGE_SAMPLE_ macros return values appropriate to the\nactual image sample values - either the entries in the color-map or the\npixels in the image.  The PNG_IMAGE_PIXEL_ macros return corresponding values\nfor the pixels and will always return 1 for color-mapped formats.  The\nremaining macros return information about the rows in the image and the\ncomplete image.\n\nNOTE: All the macros that take a png_image::format parameter are compile time\nconstants if the format parameter is, itself, a constant.  Therefore these\nmacros can be used in array declarations and case labels where required.\nSimilarly the macros are also pre-processor constants (sizeof is not used) so\nthey can be used in #if tests.\n\n  PNG_IMAGE_SAMPLE_CHANNELS(fmt)\n    Returns the total number of channels in a given format: 1..4\n\n  PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\n    Returns the size in bytes of a single component of a pixel or color-map\n    entry (as appropriate) in the image: 1 or 2.\n\n  PNG_IMAGE_SAMPLE_SIZE(fmt)\n    This is the size of the sample data for one sample.  If the image is\n    color-mapped it is the size of one color-map entry (and image pixels are\n    one byte in size), otherwise it is the size of one image pixel.\n\n  PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\n    The maximum size of the color-map required by the format expressed in a\n    count of components.  This can be used to compile-time allocate a\n    color-map:\n\n    png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)];\n\n    png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)];\n\n    Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the\n    information from one of the png_image_begin_read_ APIs and dynamically\n    allocate the required memory.\n\n  PNG_IMAGE_COLORMAP_SIZE(fmt)\n   The size of the color-map required by the format; this is the size of the\n   color-map buffer passed to the png_image_{read,write}_colormap APIs. It is\n   a fixed number determined by the format so can easily be allocated on the\n   stack if necessary.\n\nCorresponding information about the pixels\n\n  PNG_IMAGE_PIXEL_CHANNELS(fmt)\n   The number of separate channels (components) in a pixel; 1 for a\n   color-mapped image.\n\n  PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\\\n   The size, in bytes, of each component in a pixel; 1 for a color-mapped\n   image.\n\n  PNG_IMAGE_PIXEL_SIZE(fmt)\n   The size, in bytes, of a complete pixel; 1 for a color-mapped image.\n\nInformation about the whole row, or whole image\n\n  PNG_IMAGE_ROW_STRIDE(image)\n   Returns the total number of components in a single row of the image; this\n   is the minimum 'row stride', the minimum count of components between each\n   row.  For a color-mapped image this is the minimum number of bytes in a\n   row.\n\n   If you need the stride measured in bytes, row_stride_bytes is\n   PNG_IMAGE_ROW_STRIDE(image) * PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\n   plus any padding bytes that your application might need, for example\n   to start the next row on a 4-byte boundary.\n\n  PNG_IMAGE_BUFFER_SIZE(image, row_stride)\n   Return the size, in bytes, of an image buffer given a png_image and a row\n   stride - the number of components to leave space for in each row.\n\n  PNG_IMAGE_SIZE(image)\n   Return the size, in bytes, of the image in memory given just a png_image;\n   the row stride is the minimum stride required for the image.\n\n  PNG_IMAGE_COLORMAP_SIZE(image)\n   Return the size, in bytes, of the color-map of this image.  If the image\n   format is not a color-map format this will return a size sufficient for\n   256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if\n   you don't want to allocate a color-map in this case.\n\nPNG_IMAGE_FLAG_*\n\nFlags containing additional information about the image are held in\nthe 'flags' field of png_image.\n\n  PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB == 0x01\n    This indicates the the RGB values of the in-memory bitmap do not\n    correspond to the red, green and blue end-points defined by sRGB.\n\n  PNG_IMAGE_FLAG_FAST == 0x02\n   On write emphasise speed over compression; the resultant PNG file will be\n   larger but will be produced significantly faster, particular for large\n   images.  Do not use this option for images which will be distributed, only\n   used it when producing intermediate files that will be read back in\n   repeatedly.  For a typical 24-bit image the option will double the read\n   speed at the cost of increasing the image size by 25%, however for many\n   more compressible images the PNG file can be 10 times larger with only a\n   slight speed gain.\n\n  PNG_IMAGE_FLAG_16BIT_sRGB == 0x04\n    On read if the image is a 16-bit per component image and there is no gAMA\n    or sRGB chunk assume that the components are sRGB encoded.  Notice that\n    images output by the simplified API always have gamma information; setting\n    this flag only affects the interpretation of 16-bit images from an\n    external source.  It is recommended that the application expose this flag\n    to the user; the user can normally easily recognize the difference between\n    linear and sRGB encoding.  This flag has no effect on write - the data\n    passed to the write APIs must have the correct encoding (as defined\n    above.)\n\n    If the flag is not set (the default) input 16-bit per component data is\n    assumed to be linear.\n\n    NOTE: the flag can only be set after the png_image_begin_read_ call,\n    because that call initializes the 'flags' field.\n\nREAD APIs\n\n   The png_image passed to the read APIs must have been initialized by setting\n   the png_controlp field 'opaque' to NULL (or, better, memset the whole thing.)\n\n   int png_image_begin_read_from_file( png_imagep image,\n     const char *file_name)\n\n     The named file is opened for read and the image header\n     is filled in from the PNG header in the file.\n\n   int png_image_begin_read_from_stdio (png_imagep image,\n     FILE* file)\n\n      The PNG header is read from the stdio FILE object.\n\n   int png_image_begin_read_from_memory(png_imagep image,\n      png_const_voidp memory, png_size_t size)\n\n      The PNG header is read from the given memory buffer.\n\n   int png_image_finish_read(png_imagep image,\n      png_colorp background, void *buffer,\n      png_int_32 row_stride, void *colormap));\n\n      Finish reading the image into the supplied buffer and\n      clean up the png_image structure.\n\n      row_stride is the step, in png_byte or png_uint_16 units\n      as appropriate, between adjacent rows.  A positive stride\n      indicates that the top-most row is first in the buffer -\n      the normal top-down arrangement.  A negative stride\n      indicates that the bottom-most row is first in the buffer.\n\n      background need only be supplied if an alpha channel must\n      be removed from a png_byte format and the removal is to be\n      done by compositing on a solid color; otherwise it may be\n      NULL and any composition will be done directly onto the\n      buffer.  The value is an sRGB color to use for the\n      background, for grayscale output the green channel is used.\n\n      For linear output removing the alpha channel is always done\n      by compositing on black.\n\n   void png_image_free(png_imagep image)\n\n      Free any data allocated by libpng in image->opaque,\n      setting the pointer to NULL.  May be called at any time\n      after the structure is initialized.\n\nWhen the simplified API needs to convert between sRGB and linear colorspaces,\nthe actual sRGB transfer curve defined in the sRGB specification (see the\narticle at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2\napproximation used elsewhere in libpng.\n\nWRITE APIS\n\nFor write you must initialize a png_image structure to describe the image to\nbe written:\n\n   version: must be set to PNG_IMAGE_VERSION\n   opaque: must be initialized to NULL\n   width: image width in pixels\n   height: image height in rows\n   format: the format of the data you wish to write\n   flags: set to 0 unless one of the defined flags applies; set\n      PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images\n      where the RGB values do not correspond to the colors in sRGB.\n   colormap_entries: set to the number of entries in the color-map (0 to 256)\n\n   int png_image_write_to_file, (png_imagep image,\n      const char *file, int convert_to_8bit, const void *buffer,\n      png_int_32 row_stride, const void *colormap));\n\n      Write the image to the named file.\n\n   int png_image_write_to_memory (png_imagep image, void *memory,\n      png_alloc_size_t * PNG_RESTRICT memory_bytes,\n      int convert_to_8_bit, const void *buffer, ptrdiff_t row_stride,\n      const void *colormap));\n\n      Write the image to memory.\n\n   int png_image_write_to_stdio(png_imagep image, FILE *file,\n      int convert_to_8_bit, const void *buffer,\n      png_int_32 row_stride, const void *colormap)\n\n      Write the image to the given (FILE*).\n\nWith all write APIs if image is in one of the linear formats with\n(png_uint_16) data then setting convert_to_8_bit will cause the output to be\na (png_byte) PNG gamma encoded according to the sRGB specification, otherwise\na 16-bit linear encoded PNG file is written.\n\nWith all APIs row_stride is handled as in the read APIs - it is the spacing\nfrom one row to the next in component sized units (float) and if negative\nindicates a bottom-up row layout in the buffer.  If you pass zero, libpng will\ncalculate the row_stride for you from the width and number of channels.\n\nNote that the write API does not support interlacing, sub-8-bit pixels,\nindexed (paletted) images, or most ancillary chunks.\n\n.SH VI. Modifying/Customizing libpng\n\nThere are two issues here.  The first is changing how libpng does\nstandard things like memory allocation, input/output, and error handling.\nThe second deals with more complicated things like adding new chunks,\nadding new transformations, and generally changing how libpng works.\nBoth of those are compile-time issues; that is, they are generally\ndetermined at the time the code is written, and there is rarely a need\nto provide the user with a means of changing them.\n\nMemory allocation, input/output, and error handling\n\nAll of the memory allocation, input/output, and error handling in libpng\ngoes through callbacks that are user-settable.  The default routines are\nin pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively.  To change\nthese functions, call the appropriate png_set_*_fn() function.\n\nMemory allocation is done through the functions png_malloc(), png_calloc(),\nand png_free().  The png_malloc() and png_free() functions currently just\ncall the standard C functions and png_calloc() calls png_malloc() and then\nclears the newly allocated memory to zero; note that png_calloc(png_ptr, size)\nis not the same as the calloc(number, size) function provided by stdlib.h.\nThere is limited support for certain systems with segmented memory\narchitectures and the types of pointers declared by png.h match this; you\nwill have to use appropriate pointers in your application.  If you prefer\nto use a different method of allocating and freeing data, you can use\npng_create_read_struct_2() or png_create_write_struct_2() to register your\nown functions as described above.  These functions also provide a void\npointer that can be retrieved via\n\n    mem_ptr=png_get_mem_ptr(png_ptr);\n\nYour replacement memory functions must have prototypes as follows:\n\n    png_voidp malloc_fn(png_structp png_ptr,\n       png_alloc_size_t size);\n\n    void free_fn(png_structp png_ptr, png_voidp ptr);\n\nYour malloc_fn() must return NULL in case of failure.  The png_malloc()\nfunction will normally call png_error() if it receives a NULL from the\nsystem memory allocator or from your replacement malloc_fn().\n\nYour free_fn() will never be called with a NULL ptr, since libpng's\npng_free() checks for NULL before calling free_fn().\n\nInput/Output in libpng is done through png_read() and png_write(),\nwhich currently just call fread() and fwrite().  The FILE * is stored in\npng_struct and is initialized via png_init_io().  If you wish to change\nthe method of I/O, the library supplies callbacks that you can set\nthrough the function png_set_read_fn() and png_set_write_fn() at run\ntime, instead of calling the png_init_io() function.  These functions\nalso provide a void pointer that can be retrieved via the function\npng_get_io_ptr().  For example:\n\n    png_set_read_fn(png_structp read_ptr,\n        voidp read_io_ptr, png_rw_ptr read_data_fn)\n\n    png_set_write_fn(png_structp write_ptr,\n        voidp write_io_ptr, png_rw_ptr write_data_fn,\n        png_flush_ptr output_flush_fn);\n\n    voidp read_io_ptr = png_get_io_ptr(read_ptr);\n    voidp write_io_ptr = png_get_io_ptr(write_ptr);\n\nThe replacement I/O functions must have prototypes as follows:\n\n    void user_read_data(png_structp png_ptr,\n        png_bytep data, png_size_t length);\n\n    void user_write_data(png_structp png_ptr,\n        png_bytep data, png_size_t length);\n\n    void user_flush_data(png_structp png_ptr);\n\nThe user_read_data() function is responsible for detecting and\nhandling end-of-data errors.\n\nSupplying NULL for the read, write, or flush functions sets them back\nto using the default C stream functions, which expect the io_ptr to\npoint to a standard *FILE structure.  It is probably a mistake\nto use NULL for one of write_data_fn and output_flush_fn but not both\nof them, unless you have built libpng with PNG_NO_WRITE_FLUSH defined.\nIt is an error to read from a write stream, and vice versa.\n\nError handling in libpng is done through png_error() and png_warning().\nErrors handled through png_error() are fatal, meaning that png_error()\nshould never return to its caller.  Currently, this is handled via\nsetjmp() and longjmp() (unless you have compiled libpng with\nPNG_NO_SETJMP, in which case it is handled via PNG_ABORT()),\nbut you could change this to do things like exit() if you should wish,\nas long as your function does not return.\n\nOn non-fatal errors, png_warning() is called\nto print a warning message, and then control returns to the calling code.\nBy default png_error() and png_warning() print a message on stderr via\nfprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined\n(because you don't want the messages) or PNG_NO_STDIO defined (because\nfprintf() isn't available).  If you wish to change the behavior of the error\nfunctions, you will need to set up your own message callbacks.  These\nfunctions are normally supplied at the time that the png_struct is created.\nIt is also possible to redirect errors and warnings to your own replacement\nfunctions after png_create_*_struct() has been called by calling:\n\n    png_set_error_fn(png_structp png_ptr,\n        png_voidp error_ptr, png_error_ptr error_fn,\n        png_error_ptr warning_fn);\n\n    png_voidp error_ptr = png_get_error_ptr(png_ptr);\n\nIf NULL is supplied for either error_fn or warning_fn, then the libpng\ndefault function will be used, calling fprintf() and/or longjmp() if a\nproblem is encountered.  The replacement error functions should have\nparameters as follows:\n\n    void user_error_fn(png_structp png_ptr,\n        png_const_charp error_msg);\n\n    void user_warning_fn(png_structp png_ptr,\n        png_const_charp warning_msg);\n\nThe motivation behind using setjmp() and longjmp() is the C++ throw and\ncatch exception handling methods.  This makes the code much easier to write,\nas there is no need to check every return code of every function call.\nHowever, there are some uncertainties about the status of local variables\nafter a longjmp, so the user may want to be careful about doing anything\nafter setjmp returns non-zero besides returning itself.  Consult your\ncompiler documentation for more details.  For an alternative approach, you\nmay wish to use the \"cexcept\" facility (see http://cexcept.sourceforge.net),\nwhich is illustrated in pngvalid.c and in contrib/visupng.\n\nBeginning in libpng-1.4.0, the png_set_benign_errors() API became available.\nYou can use this to handle certain errors (normally handled as errors)\nas warnings.\n\n    png_set_benign_errors (png_ptr, int allowed);\n\n    allowed: 0: treat png_benign_error() as an error.\n             1: treat png_benign_error() as a warning.\n\nAs of libpng-1.6.0, the default condition is to treat benign errors as\nwarnings while reading and as errors while writing.\n\n.SS Custom chunks\n\nIf you need to read or write custom chunks, you may need to get deeper\ninto the libpng code.  The library now has mechanisms for storing\nand writing chunks of unknown type; you can even declare callbacks\nfor custom chunks.  However, this may not be good enough if the\nlibrary code itself needs to know about interactions between your\nchunk and existing `intrinsic' chunks.\n\nIf you need to write a new intrinsic chunk, first read the PNG\nspecification. Acquire a first level of understanding of how it works.\nPay particular attention to the sections that describe chunk names,\nand look at how other chunks were designed, so you can do things\nsimilarly.  Second, check out the sections of libpng that read and\nwrite chunks.  Try to find a chunk that is similar to yours and use\nit as a template.  More details can be found in the comments inside\nthe code.  It is best to handle private or unknown chunks in a generic method,\nvia callback functions, instead of by modifying libpng functions. This\nis illustrated in pngtest.c, which uses a callback function to handle a\nprivate \"vpAg\" chunk and the new \"sTER\" chunk, which are both unknown to\nlibpng.\n\nIf you wish to write your own transformation for the data, look through\nthe part of the code that does the transformations, and check out some of\nthe simpler ones to get an idea of how they work.  Try to find a similar\ntransformation to the one you want to add and copy off of it.  More details\ncan be found in the comments inside the code itself.\n\n.SS Configuring for gui/windowing platforms:\n\nYou will need to write new error and warning functions that use the GUI\ninterface, as described previously, and set them to be the error and\nwarning functions at the time that png_create_*_struct() is called,\nin order to have them available during the structure initialization.\nThey can be changed later via png_set_error_fn().  On some compilers,\nyou may also have to change the memory allocators (png_malloc, etc.).\n\n.SS Configuring zlib:\n\nThere are special functions to configure the compression.  Perhaps the\nmost useful one changes the compression level, which currently uses\ninput compression values in the range 0 - 9.  The library normally\nuses the default compression level (Z_DEFAULT_COMPRESSION = 6).  Tests\nhave shown that for a large majority of images, compression values in\nthe range 3-6 compress nearly as well as higher levels, and do so much\nfaster.  For online applications it may be desirable to have maximum speed\n(Z_BEST_SPEED = 1).  With versions of zlib after v0.99, you can also\nspecify no compression (Z_NO_COMPRESSION = 0), but this would create\nfiles larger than just storing the raw bitmap.  You can specify the\ncompression level by calling:\n\n    #include zlib.h\n    png_set_compression_level(png_ptr, level);\n\nAnother useful one is to reduce the memory level used by the library.\nThe memory level defaults to 8, but it can be lowered if you are\nshort on memory (running DOS, for example, where you only have 640K).\nNote that the memory level does have an effect on compression; among\nother things, lower levels will result in sections of incompressible\ndata being emitted in smaller stored blocks, with a correspondingly\nlarger relative overhead of up to 15% in the worst case.\n\n    #include zlib.h\n    png_set_compression_mem_level(png_ptr, level);\n\nThe other functions are for configuring zlib.  They are not recommended\nfor normal use and may result in writing an invalid PNG file.  See\nzlib.h for more information on what these mean.\n\n    #include zlib.h\n    png_set_compression_strategy(png_ptr,\n        strategy);\n\n    png_set_compression_window_bits(png_ptr,\n        window_bits);\n\n    png_set_compression_method(png_ptr, method);\n\nThis controls the size of the IDAT chunks (default 8192):\n\n    png_set_compression_buffer_size(png_ptr, size);\n\nAs of libpng version 1.5.4, additional APIs became\navailable to set these separately for non-IDAT\ncompressed chunks such as zTXt, iTXt, and iCCP:\n\n    #include zlib.h\n    #if PNG_LIBPNG_VER >= 10504\n    png_set_text_compression_level(png_ptr, level);\n\n    png_set_text_compression_mem_level(png_ptr, level);\n\n    png_set_text_compression_strategy(png_ptr,\n        strategy);\n\n    png_set_text_compression_window_bits(png_ptr,\n        window_bits);\n\n    png_set_text_compression_method(png_ptr, method);\n    #endif\n\n.SS Controlling row filtering\n\nIf you want to control whether libpng uses filtering or not, which\nfilters are used, and how it goes about picking row filters, you\ncan call one of these functions.  The selection and configuration\nof row filters can have a significant impact on the size and\nencoding speed and a somewhat lesser impact on the decoding speed\nof an image.  Filtering is enabled by default for RGB and grayscale\nimages (with and without alpha), but not for paletted images nor\nfor any images with bit depths less than 8 bits/pixel.\n\nThe 'method' parameter sets the main filtering method, which is\ncurrently only '0' in the PNG 1.2 specification.  The 'filters'\nparameter sets which filter(s), if any, should be used for each\nscanline.  Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS\nto turn filtering on and off, respectively.\n\nIndividual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,\nPNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise\nORed together with '|' to specify one or more filters to use.\nThese filters are described in more detail in the PNG specification.\nIf you intend to change the filter type during the course of writing\nthe image, you should start with flags set for all of the filters\nyou intend to use so that libpng can initialize its internal\nstructures appropriately for all of the filter types.  (Note that this\nmeans the first row must always be adaptively filtered, because libpng\ncurrently does not allocate the filter buffers until png_write_row()\nis called for the first time.)\n\n    filters = PNG_FILTER_NONE | PNG_FILTER_SUB\n              PNG_FILTER_UP | PNG_FILTER_AVG |\n              PNG_FILTER_PAETH | PNG_ALL_FILTERS;\n\n    png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,\n       filters);\n              The second parameter can also be\n              PNG_INTRAPIXEL_DIFFERENCING if you are\n              writing a PNG to be embedded in a MNG\n              datastream.  This parameter must be the\n              same as the value of filter_method used\n              in png_set_IHDR().\n\n.SS Requesting debug printout\n\nThe macro definition PNG_DEBUG can be used to request debugging\nprintout.  Set it to an integer value in the range 0 to 3.  Higher\nnumbers result in increasing amounts of debugging information.  The\ninformation is printed to the \"stderr\" file, unless another file\nname is specified in the PNG_DEBUG_FILE macro definition.\n\nWhen PNG_DEBUG > 0, the following functions (macros) become available:\n\n   png_debug(level, message)\n   png_debug1(level, message, p1)\n   png_debug2(level, message, p1, p2)\n\nin which \"level\" is compared to PNG_DEBUG to decide whether to print\nthe message, \"message\" is the formatted string to be printed,\nand p1 and p2 are parameters that are to be embedded in the string\naccording to printf-style formatting directives.  For example,\n\n   png_debug1(2, \"foo=%d\", foo);\n\nis expanded to\n\n   if (PNG_DEBUG > 2)\n      fprintf(PNG_DEBUG_FILE, \"foo=%d\\en\", foo);\n\nWhen PNG_DEBUG is defined but is zero, the macros aren't defined, but you\ncan still use PNG_DEBUG to control your own debugging:\n\n   #ifdef PNG_DEBUG\n       fprintf(stderr, ...\n   #endif\n\nWhen PNG_DEBUG = 1, the macros are defined, but only png_debug statements\nhaving level = 0 will be printed.  There aren't any such statements in\nthis version of libpng, but if you insert some they will be printed.\n\n.SH VII.  MNG support\n\nThe MNG specification (available at http://www.libpng.org/pub/mng) allows\ncertain extensions to PNG for PNG images that are embedded in MNG datastreams.\nLibpng can support some of these extensions.  To enable them, use the\npng_permit_mng_features() function:\n\n   feature_set = png_permit_mng_features(png_ptr, mask)\n\n   mask is a png_uint_32 containing the bitwise OR of the\n        features you want to enable.  These include\n        PNG_FLAG_MNG_EMPTY_PLTE\n        PNG_FLAG_MNG_FILTER_64\n        PNG_ALL_MNG_FEATURES\n\n   feature_set is a png_uint_32 that is the bitwise AND of\n      your mask with the set of MNG features that is\n      supported by the version of libpng that you are using.\n\nIt is an error to use this function when reading or writing a standalone\nPNG file with the PNG 8-byte signature.  The PNG datastream must be wrapped\nin a MNG datastream.  As a minimum, it must have the MNG 8-byte signature\nand the MHDR and MEND chunks.  Libpng does not provide support for these\nor any other MNG chunks; your application must provide its own support for\nthem.  You may wish to consider using libmng (available at\nhttp://www.libmng.com) instead.\n\n.SH VIII.  Changes to Libpng from version 0.88\n\nIt should be noted that versions of libpng later than 0.96 are not\ndistributed by the original libpng author, Guy Schalnat, nor by\nAndreas Dilger, who had taken over from Guy during 1996 and 1997, and\ndistributed versions 0.89 through 0.96, but rather by another member\nof the original PNG Group, Glenn Randers-Pehrson.  Guy and Andreas are\nstill alive and well, but they have moved on to other things.\n\nThe old libpng functions png_read_init(), png_write_init(),\npng_info_init(), png_read_destroy(), and png_write_destroy() have been\nmoved to PNG_INTERNAL in version 0.95 to discourage their use.  These\nfunctions will be removed from libpng version 1.4.0.\n\nThe preferred method of creating and initializing the libpng structures is\nvia the png_create_read_struct(), png_create_write_struct(), and\npng_create_info_struct() because they isolate the size of the structures\nfrom the application, allow version error checking, and also allow the\nuse of custom error handling routines during the initialization, which\nthe old functions do not.  The functions png_read_destroy() and\npng_write_destroy() do not actually free the memory that libpng\nallocated for these structs, but just reset the data structures, so they\ncan be used instead of png_destroy_read_struct() and\npng_destroy_write_struct() if you feel there is too much system overhead\nallocating and freeing the png_struct for each image read.\n\nSetting the error callbacks via png_set_message_fn() before\npng_read_init() as was suggested in libpng-0.88 is no longer supported\nbecause this caused applications that do not use custom error functions\nto fail if the png_ptr was not initialized to zero.  It is still possible\nto set the error callbacks AFTER png_read_init(), or to change them with\npng_set_error_fn(), which is essentially the same function, but with a new\nname to force compilation errors with applications that try to use the old\nmethod.\n\nSupport for the sCAL, iCCP, iTXt, and sPLT chunks was added at libpng-1.0.6;\nhowever, iTXt support was not enabled by default.\n\nStarting with version 1.0.7, you can find out which version of the library\nyou are using at run-time:\n\n   png_uint_32 libpng_vn = png_access_version_number();\n\nThe number libpng_vn is constructed from the major version, minor\nversion with leading zero, and release number with leading zero,\n(e.g., libpng_vn for version 1.0.7 is 10007).\n\nNote that this function does not take a png_ptr, so you can call it\nbefore you've created one.\n\nYou can also check which version of png.h you used when compiling your\napplication:\n\n   png_uint_32 application_vn = PNG_LIBPNG_VER;\n\n.SH IX.  Changes to Libpng from version 1.0.x to 1.2.x\n\nSupport for user memory management was enabled by default.  To\naccomplish this, the functions png_create_read_struct_2(),\npng_create_write_struct_2(), png_set_mem_fn(), png_get_mem_ptr(),\npng_malloc_default(), and png_free_default() were added.\n\nSupport for the iTXt chunk has been enabled by default as of\nversion 1.2.41.\n\nSupport for certain MNG features was enabled.\n\nSupport for numbered error messages was added.  However, we never got\naround to actually numbering the error messages.  The function\npng_set_strip_error_numbers() was added (Note: the prototype for this\nfunction was inadvertently removed from png.h in PNG_NO_ASSEMBLER_CODE\nbuilds of libpng-1.2.15.  It was restored in libpng-1.2.36).\n\nThe png_malloc_warn() function was added at libpng-1.2.3.  This issues\na png_warning and returns NULL instead of aborting when it fails to\nacquire the requested memory allocation.\n\nSupport for setting user limits on image width and height was enabled\nby default.  The functions png_set_user_limits(), png_get_user_width_max(),\nand png_get_user_height_max() were added at libpng-1.2.6.\n\nThe png_set_add_alpha() function was added at libpng-1.2.7.\n\nThe function png_set_expand_gray_1_2_4_to_8() was added at libpng-1.2.9.\nUnlike png_set_gray_1_2_4_to_8(), the new function does not expand the\ntRNS chunk to alpha. The png_set_gray_1_2_4_to_8() function is\ndeprecated.\n\nA number of macro definitions in support of runtime selection of\nassembler code features (especially Intel MMX code support) were\nadded at libpng-1.2.0:\n\n    PNG_ASM_FLAG_MMX_SUPPORT_COMPILED\n    PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU\n    PNG_ASM_FLAG_MMX_READ_COMBINE_ROW\n    PNG_ASM_FLAG_MMX_READ_INTERLACE\n    PNG_ASM_FLAG_MMX_READ_FILTER_SUB\n    PNG_ASM_FLAG_MMX_READ_FILTER_UP\n    PNG_ASM_FLAG_MMX_READ_FILTER_AVG\n    PNG_ASM_FLAG_MMX_READ_FILTER_PAETH\n    PNG_ASM_FLAGS_INITIALIZED\n    PNG_MMX_READ_FLAGS\n    PNG_MMX_FLAGS\n    PNG_MMX_WRITE_FLAGS\n    PNG_MMX_FLAGS\n\nWe added the following functions in support of runtime\nselection of assembler code features:\n\n    png_get_mmx_flagmask()\n    png_set_mmx_thresholds()\n    png_get_asm_flags()\n    png_get_mmx_bitdepth_threshold()\n    png_get_mmx_rowbytes_threshold()\n    png_set_asm_flags()\n\nWe replaced all of these functions with simple stubs in libpng-1.2.20,\nwhen the Intel assembler code was removed due to a licensing issue.\n\nThese macros are deprecated:\n\n    PNG_READ_TRANSFORMS_NOT_SUPPORTED\n    PNG_PROGRESSIVE_READ_NOT_SUPPORTED\n    PNG_NO_SEQUENTIAL_READ_SUPPORTED\n    PNG_WRITE_TRANSFORMS_NOT_SUPPORTED\n    PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED\n    PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED\n\nThey have been replaced, respectively, by:\n\n    PNG_NO_READ_TRANSFORMS\n    PNG_NO_PROGRESSIVE_READ\n    PNG_NO_SEQUENTIAL_READ\n    PNG_NO_WRITE_TRANSFORMS\n    PNG_NO_READ_ANCILLARY_CHUNKS\n    PNG_NO_WRITE_ANCILLARY_CHUNKS\n\nPNG_MAX_UINT was replaced with PNG_UINT_31_MAX.  It has been\ndeprecated since libpng-1.0.16 and libpng-1.2.6.\n\nThe function\n    png_check_sig(sig, num)\nwas replaced with\n    !png_sig_cmp(sig, 0, num)\nIt has been deprecated since libpng-0.90.\n\nThe function\n    png_set_gray_1_2_4_to_8()\nwhich also expands tRNS to alpha was replaced with\n    png_set_expand_gray_1_2_4_to_8()\nwhich does not. It has been deprecated since libpng-1.0.18 and 1.2.9.\n\n.SH X.  Changes to Libpng from version 1.0.x/1.2.x to 1.4.x\n\nPrivate libpng prototypes and macro definitions were moved from\npng.h and pngconf.h into a new pngpriv.h header file.\n\nFunctions png_set_benign_errors(), png_benign_error(), and\npng_chunk_benign_error() were added.\n\nSupport for setting the maximum amount of memory that the application\nwill allocate for reading chunks was added, as a security measure.\nThe functions png_set_chunk_cache_max() and png_get_chunk_cache_max()\nwere added to the library.\n\nWe implemented support for I/O states by adding png_ptr member io_state\nand functions png_get_io_chunk_name() and png_get_io_state() in pngget.c\n\nWe added PNG_TRANSFORM_GRAY_TO_RGB to the available high-level\ninput transforms.\n\nChecking for and reporting of errors in the IHDR chunk is more thorough.\n\nSupport for global arrays was removed, to improve thread safety.\n\nSome obsolete/deprecated macros and functions have been removed.\n\nTypecasted NULL definitions such as\n   #define png_voidp_NULL            (png_voidp)NULL\nwere eliminated.  If you used these in your application, just use\nNULL instead.\n\nThe png_struct and info_struct members \"trans\" and \"trans_values\" were\nchanged to \"trans_alpha\" and \"trans_color\", respectively.\n\nThe obsolete, unused pnggccrd.c and pngvcrd.c files and related makefiles\nwere removed.\n\nThe PNG_1_0_X and PNG_1_2_X macros were eliminated.\n\nThe PNG_LEGACY_SUPPORTED macro was eliminated.\n\nMany WIN32_WCE #ifdefs were removed.\n\nThe functions png_read_init(info_ptr), png_write_init(info_ptr),\npng_info_init(info_ptr), png_read_destroy(), and png_write_destroy()\nhave been removed.  They have been deprecated since libpng-0.95.\n\nThe png_permit_empty_plte() was removed. It has been deprecated\nsince libpng-1.0.9.  Use png_permit_mng_features() instead.\n\nWe removed the obsolete stub functions png_get_mmx_flagmask(),\npng_set_mmx_thresholds(), png_get_asm_flags(),\npng_get_mmx_bitdepth_threshold(), png_get_mmx_rowbytes_threshold(),\npng_set_asm_flags(), and png_mmx_supported()\n\nWe removed the obsolete png_check_sig(), png_memcpy_check(), and\npng_memset_check() functions.  Instead use !png_sig_cmp(), memcpy(),\nand memset(), respectively.\n\nThe function png_set_gray_1_2_4_to_8() was removed. It has been\ndeprecated since libpng-1.0.18 and 1.2.9, when it was replaced with\npng_set_expand_gray_1_2_4_to_8() because the former function also\nexpanded any tRNS chunk to an alpha channel.\n\nMacros for png_get_uint_16, png_get_uint_32, and png_get_int_32\nwere added and are used by default instead of the corresponding\nfunctions. Unfortunately,\nfrom libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the\nfunction) incorrectly returned a value of type png_uint_32.\n\nWe changed the prototype for png_malloc() from\n    png_malloc(png_structp png_ptr, png_uint_32 size)\nto\n    png_malloc(png_structp png_ptr, png_alloc_size_t size)\n\nThis also applies to the prototype for the user replacement malloc_fn().\n\nThe png_calloc() function was added and is used in place of\nof \"png_malloc(); memset();\" except in the case in png_read_png()\nwhere the array consists of pointers; in this case a \"for\" loop is used\nafter the png_malloc() to set the pointers to NULL, to give robust.\nbehavior in case the application runs out of memory part-way through\nthe process.\n\nWe changed the prototypes of png_get_compression_buffer_size() and\npng_set_compression_buffer_size() to work with png_size_t instead of\npng_uint_32.\n\nSupport for numbered error messages was removed by default, since we\nnever got around to actually numbering the error messages. The function\npng_set_strip_error_numbers() was removed from the library by default.\n\nThe png_zalloc() and png_zfree() functions are no longer exported.\nThe png_zalloc() function no longer zeroes out the memory that it\nallocates.  Applications that called png_zalloc(png_ptr, number, size)\ncan call png_calloc(png_ptr, number*size) instead, and can call\npng_free() instead of png_zfree().\n\nSupport for dithering was disabled by default in libpng-1.4.0, because\nit has not been well tested and doesn't actually \"dither\".\nThe code was not\nremoved, however, and could be enabled by building libpng with\nPNG_READ_DITHER_SUPPORTED defined.  In libpng-1.4.2, this support\nwas re-enabled, but the function was renamed png_set_quantize() to\nreflect more accurately what it actually does.  At the same time,\nthe PNG_DITHER_[RED,GREEN_BLUE]_BITS macros were also renamed to\nPNG_QUANTIZE_[RED,GREEN,BLUE]_BITS, and PNG_READ_DITHER_SUPPORTED\nwas renamed to PNG_READ_QUANTIZE_SUPPORTED.\n\nWe removed the trailing '.' from the warning and error messages.\n\n.SH XI.  Changes to Libpng from version 1.4.x to 1.5.x\n\nFrom libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the\nfunction) incorrectly returned a value of type png_uint_32.\nThe incorrect macro was removed from libpng-1.4.5.\n\nChecking for invalid palette index on write was added at libpng\n1.5.10.  If a pixel contains an invalid (out-of-range) index libpng issues\na benign error.  This is enabled by default because this condition is an\nerror according to the PNG specification, Clause 11.3.2, but the error can\nbe ignored in each png_ptr with\n\n   png_set_check_for_invalid_index(png_ptr, allowed);\n\n      allowed  - one of\n                 0: disable benign error (accept the\n                    invalid data without warning).\n                 1: enable benign error (treat the\n                    invalid data as an error or a\n                    warning).\n\nIf the error is ignored, or if png_benign_error() treats it as a warning,\nany invalid pixels are decoded as opaque black by the decoder and written\nas-is by the encoder.\n\nRetrieving the maximum palette index found was added at libpng-1.5.15.\nThis statement must appear after png_read_png() or png_read_image() while\nreading, and after png_write_png() or png_write_image() while writing.\n\n   int max_palette = png_get_palette_max(png_ptr, info_ptr);\n\nThis will return the maximum palette index found in the image, or \"\\-1\" if\nthe palette was not checked, or \"0\" if no palette was found.  Note that this\ndoes not account for any palette index used by ancillary chunks such as the\nbKGD chunk; you must check those separately to determine the maximum\npalette index actually used.\n\nThere are no substantial API changes between the non-deprecated parts of\nthe 1.4.5 API and the 1.5.0 API; however, the ability to directly access\nmembers of the main libpng control structures, png_struct and png_info,\ndeprecated in earlier versions of libpng, has been completely removed from\nlibpng 1.5, and new private \"pngstruct.h\", \"pnginfo.h\", and \"pngdebug.h\"\nheader files were created.\n\nWe no longer include zlib.h in png.h.  The include statement has been moved\nto pngstruct.h, where it is not accessible by applications. Applications that\nneed access to information in zlib.h will need to add the '#include \"zlib.h\"'\ndirective.  It does not matter whether this is placed prior to or after\nthe '\"#include png.h\"' directive.\n\nThe png_sprintf(), png_strcpy(), and png_strncpy() macros are no longer used\nand were removed.\n\nWe moved the png_strlen(), png_memcpy(), png_memset(), and png_memcmp()\nmacros into a private header file (pngpriv.h) that is not accessible to\napplications.\n\nIn png_get_iCCP, the type of \"profile\" was changed from png_charpp\nto png_bytepp, and in png_set_iCCP, from png_charp to png_const_bytep.\n\nThere are changes of form in png.h, including new and changed macros to\ndeclare parts of the API.  Some API functions with arguments that are\npointers to data not modified within the function have been corrected to\ndeclare these arguments with PNG_CONST.\n\nMuch of the internal use of C macros to control the library build has also\nchanged and some of this is visible in the exported header files, in\nparticular the use of macros to control data and API elements visible\nduring application compilation may require significant revision to\napplication code.  (It is extremely rare for an application to do this.)\n\nAny program that compiled against libpng 1.4 and did not use deprecated\nfeatures or access internal library structures should compile and work\nagainst libpng 1.5, except for the change in the prototype for\npng_get_iCCP() and png_set_iCCP() API functions mentioned above.\n\nlibpng 1.5.0 adds PNG_ PASS macros to help in the reading and writing of\ninterlaced images.  The macros return the number of rows and columns in\neach pass and information that can be used to de-interlace and (if\nabsolutely necessary) interlace an image.\n\nlibpng 1.5.0 adds an API png_longjmp(png_ptr, value).  This API calls\nthe application-provided png_longjmp_ptr on the internal, but application\ninitialized, longjmp buffer.  It is provided as a convenience to avoid\nthe need to use the png_jmpbuf macro, which had the unnecessary side\neffect of resetting the internal png_longjmp_ptr value.\n\nlibpng 1.5.0 includes a complete fixed point API.  By default this is\npresent along with the corresponding floating point API.  In general the\nfixed point API is faster and smaller than the floating point one because\nthe PNG file format used fixed point, not floating point.  This applies\neven if the library uses floating point in internal calculations.  A new\nmacro, PNG_FLOATING_ARITHMETIC_SUPPORTED, reveals whether the library\nuses floating point arithmetic (the default) or fixed point arithmetic\ninternally for performance critical calculations such as gamma correction.\nIn some cases, the gamma calculations may produce slightly different\nresults.  This has changed the results in png_rgb_to_gray and in alpha\ncomposition (png_set_background for example). This applies even if the\noriginal image was already linear (gamma == 1.0) and, therefore, it is\nnot necessary to linearize the image.  This is because libpng has *not*\nbeen changed to optimize that case correctly, yet.\n\nFixed point support for the sCAL chunk comes with an important caveat;\nthe sCAL specification uses a decimal encoding of floating point values\nand the accuracy of PNG fixed point values is insufficient for\nrepresentation of these values. Consequently a \"string\" API\n(png_get_sCAL_s and png_set_sCAL_s) is the only reliable way of reading\narbitrary sCAL chunks in the absence of either the floating point API or\ninternal floating point calculations.  Starting with libpng-1.5.0, both\nof these functions are present when PNG_sCAL_SUPPORTED is defined.  Prior\nto libpng-1.5.0, their presence also depended upon PNG_FIXED_POINT_SUPPORTED\nbeing defined and PNG_FLOATING_POINT_SUPPORTED not being defined.\n\nApplications no longer need to include the optional distribution header\nfile pngusr.h or define the corresponding macros during application\nbuild in order to see the correct variant of the libpng API.  From 1.5.0\napplication code can check for the corresponding _SUPPORTED macro:\n\n#ifdef PNG_INCH_CONVERSIONS_SUPPORTED\n   /* code that uses the inch conversion APIs. */\n#endif\n\nThis macro will only be defined if the inch conversion functions have been\ncompiled into libpng.  The full set of macros, and whether or not support\nhas been compiled in, are available in the header file pnglibconf.h.\nThis header file is specific to the libpng build.  Notice that prior to\n1.5.0 the _SUPPORTED macros would always have the default definition unless\nreset by pngusr.h or by explicit settings on the compiler command line.\nThese settings may produce compiler warnings or errors in 1.5.0 because\nof macro redefinition.\n\nApplications can now choose whether to use these macros or to call the\ncorresponding function by defining PNG_USE_READ_MACROS or\nPNG_NO_USE_READ_MACROS before including png.h.  Notice that this is\nonly supported from 1.5.0; defining PNG_NO_USE_READ_MACROS prior to 1.5.0\nwill lead to a link failure.\n\nPrior to libpng-1.5.4, the zlib compressor used the same set of parameters\nwhen compressing the IDAT data and textual data such as zTXt and iCCP.\nIn libpng-1.5.4 we reinitialized the zlib stream for each type of data.\nWe added five png_set_text_*() functions for setting the parameters to\nuse with textual data.\n\nPrior to libpng-1.5.4, the PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED\noption was off by default, and slightly inaccurate scaling occurred.\nThis option can no longer be turned off, and the choice of accurate\nor inaccurate 16-to-8 scaling is by using the new png_set_scale_16_to_8()\nAPI for accurate scaling or the old png_set_strip_16_to_8() API for simple\nchopping.  In libpng-1.5.4, the PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED\nmacro became PNG_READ_SCALE_16_TO_8_SUPPORTED, and the PNG_READ_16_TO_8\nmacro became PNG_READ_STRIP_16_TO_8_SUPPORTED, to enable the two\npng_set_*_16_to_8() functions separately.\n\nPrior to libpng-1.5.4, the png_set_user_limits() function could only be\nused to reduce the width and height limits from the value of\nPNG_USER_WIDTH_MAX and PNG_USER_HEIGHT_MAX, although this document said\nthat it could be used to override them.  Now this function will reduce or\nincrease the limits.\n\nStarting in libpng-1.5.10, the user limits can be set en masse with the\nconfiguration option PNG_SAFE_LIMITS_SUPPORTED.  If this option is enabled,\na set of \"safe\" limits is applied in pngpriv.h.  These can be overridden by\napplication calls to png_set_user_limits(), png_set_user_chunk_cache_max(),\nand/or png_set_user_malloc_max() that increase or decrease the limits.  Also,\nin libpng-1.5.10 the default width and height limits were increased\nfrom 1,000,000 to 0x7fffffff (i.e., made unlimited).  Therefore, the\nlimits are now\n                               default      safe\n   png_user_width_max        0x7fffffff    1,000,000\n   png_user_height_max       0x7fffffff    1,000,000\n   png_user_chunk_cache_max  0 (unlimited)   128\n   png_user_chunk_malloc_max 0 (unlimited) 8,000,000\n\nThe png_set_option() function (and the \"options\" member of the png struct) was\nadded to libpng-1.5.15, with option PNG_ARM_NEON.\n\nThe library now supports a complete fixed point implementation and can\nthus be used on systems that have no floating point support or very\nlimited or slow support.  Previously gamma correction, an essential part\nof complete PNG support, required reasonably fast floating point.\n\nAs part of this the choice of internal implementation has been made\nindependent of the choice of fixed versus floating point APIs and all the\nmissing fixed point APIs have been implemented.\n\nThe exact mechanism used to control attributes of API functions has\nchanged, as described in the INSTALL file.\n\nA new test program, pngvalid, is provided in addition to pngtest.\npngvalid validates the arithmetic accuracy of the gamma correction\ncalculations and includes a number of validations of the file format.\nA subset of the full range of tests is run when \"make check\" is done\n(in the 'configure' build.)  pngvalid also allows total allocated memory\nusage to be evaluated and performs additional memory overwrite validation.\n\nMany changes to individual feature macros have been made. The following\nare the changes most likely to be noticed by library builders who\nconfigure libpng:\n\n1) All feature macros now have consistent naming:\n\n#define PNG_NO_feature turns the feature off\n#define PNG_feature_SUPPORTED turns the feature on\n\npnglibconf.h contains one line for each feature macro which is either:\n\n#define PNG_feature_SUPPORTED\n\nif the feature is supported or:\n\n/*#undef PNG_feature_SUPPORTED*/\n\nif it is not.  Library code consistently checks for the 'SUPPORTED' macro.\nIt does not, and libpng applications should not, check for the 'NO' macro\nwhich will not normally be defined even if the feature is not supported.\nThe 'NO' macros are only used internally for setting or not setting the\ncorresponding 'SUPPORTED' macros.\n\nCompatibility with the old names is provided as follows:\n\nPNG_INCH_CONVERSIONS turns on PNG_INCH_CONVERSIONS_SUPPORTED\n\nAnd the following definitions disable the corresponding feature:\n\nPNG_SETJMP_NOT_SUPPORTED disables SETJMP\nPNG_READ_TRANSFORMS_NOT_SUPPORTED disables READ_TRANSFORMS\nPNG_NO_READ_COMPOSITED_NODIV disables READ_COMPOSITE_NODIV\nPNG_WRITE_TRANSFORMS_NOT_SUPPORTED disables WRITE_TRANSFORMS\nPNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED disables READ_ANCILLARY_CHUNKS\nPNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED disables WRITE_ANCILLARY_CHUNKS\n\nLibrary builders should remove use of the above, inconsistent, names.\n\n2) Warning and error message formatting was previously conditional on\nthe STDIO feature. The library has been changed to use the\nCONSOLE_IO feature instead. This means that if CONSOLE_IO is disabled\nthe library no longer uses the printf(3) functions, even though the\ndefault read/write implementations use (FILE) style stdio.h functions.\n\n3) Three feature macros now control the fixed/floating point decisions:\n\nPNG_FLOATING_POINT_SUPPORTED enables the floating point APIs\n\nPNG_FIXED_POINT_SUPPORTED enables the fixed point APIs; however, in\npractice these are normally required internally anyway (because the PNG\nfile format is fixed point), therefore in most cases PNG_NO_FIXED_POINT\nmerely stops the function from being exported.\n\nPNG_FLOATING_ARITHMETIC_SUPPORTED chooses between the internal floating\npoint implementation or the fixed point one.  Typically the fixed point\nimplementation is larger and slower than the floating point implementation\non a system that supports floating point; however, it may be faster on a\nsystem which lacks floating point hardware and therefore uses a software\nemulation.\n\n4) Added PNG_{READ,WRITE}_INT_FUNCTIONS_SUPPORTED.  This allows the\nfunctions to read and write ints to be disabled independently of\nPNG_USE_READ_MACROS, which allows libpng to be built with the functions\neven though the default is to use the macros - this allows applications\nto choose at app buildtime whether or not to use macros (previously\nimpossible because the functions weren't in the default build.)\n\n.SH XII.  Changes to Libpng from version 1.5.x to 1.6.x\n\nA \"simplified API\" has been added (see documentation in png.h and a simple\nexample in contrib/examples/pngtopng.c).  The new publicly visible API\nincludes the following:\n\n   macros:\n     PNG_FORMAT_*\n     PNG_IMAGE_*\n   structures:\n     png_control\n     png_image\n   read functions\n     png_image_begin_read_from_file()\n     png_image_begin_read_from_stdio()\n     png_image_begin_read_from_memory()\n     png_image_finish_read()\n     png_image_free()\n   write functions\n     png_image_write_to_file()\n     png_image_write_to_memory()\n     png_image_write_to_stdio()\n\nStarting with libpng-1.6.0, you can configure libpng to prefix all exported\nsymbols, using the PNG_PREFIX macro.\n\nWe no longer include string.h in png.h.  The include statement has been moved\nto pngpriv.h, where it is not accessible by applications.  Applications that\nneed access to information in string.h must add an '#include <string.h>'\ndirective.  It does not matter whether this is placed prior to or after\nthe '#include \"png.h\"' directive.\n\nThe following API are now DEPRECATED:\n   png_info_init_3()\n   png_convert_to_rfc1123() which has been replaced\n     with png_convert_to_rfc1123_buffer()\n   png_malloc_default()\n   png_free_default()\n   png_reset_zstream()\n\nThe following have been removed:\n   png_get_io_chunk_name(), which has been replaced\n     with png_get_io_chunk_type().  The new\n     function returns a 32-bit integer instead of\n     a string.\n   The png_sizeof(), png_strlen(), png_memcpy(), png_memcmp(), and\n     png_memset() macros are no longer used in the libpng sources and\n     have been removed.  These had already been made invisible to applications\n     (i.e., defined in the private pngpriv.h header file) since libpng-1.5.0.\n\nThe signatures of many exported functions were changed, such that\n   png_structp became png_structrp or png_const_structrp\n   png_infop became png_inforp or png_const_inforp\nwhere \"rp\" indicates a \"restricted pointer\".\n\nDropped support for 16-bit platforms. The support for FAR/far types has\nbeen eliminated and the definition of png_alloc_size_t is now controlled\nby a flag so that 'small size_t' systems can select it if necessary.\n\nError detection in some chunks has improved; in particular the iCCP chunk\nreader now does pretty complete validation of the basic format.  Some bad\nprofiles that were previously accepted are now accepted with a warning or\nrejected, depending upon the png_set_benign_errors() setting, in particular\nthe very old broken Microsoft/HP 3144-byte sRGB profile.  Starting with\nlibpng-1.6.11, recognizing and checking sRGB profiles can be avoided by\nmeans of\n\n    #if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && \\\n        defined(PNG_SET_OPTION_SUPPORTED)\n       png_set_option(png_ptr, PNG_SKIP_sRGB_CHECK_PROFILE,\n           PNG_OPTION_ON);\n    #endif\n\nIt's not a good idea to do this if you are using the \"simplified API\",\nwhich needs to be able to recognize sRGB profiles conveyed via the iCCP\nchunk.\n\nThe PNG spec requirement that only grayscale profiles may appear in images\nwith color type 0 or 4 and that even if the image only contains gray pixels,\nonly RGB profiles may appear in images with color type 2, 3, or 6, is now\nenforced.  The sRGB chunk is allowed to appear in images with any color type\nand is interpreted by libpng to convey a one-tracer-curve gray profile or a\nthree-tracer-curve RGB profile as appropriate.\n\nLibpng 1.5.x erroneously used /MD for Debug DLL builds; if you used the debug\nbuilds in your app and you changed your app to use /MD you will need to\nchange it back to /MDd for libpng 1.6.x.\n\nPrior to libpng-1.6.0 a warning would be issued if the iTXt chunk contained\nan empty language field or an empty translated keyword.  Both of these\nare allowed by the PNG specification, so these warnings are no longer issued.\n\nThe library now issues an error if the application attempts to set a\ntransform after it calls png_read_update_info() or if it attempts to call\nboth png_read_update_info() and png_start_read_image() or to call either\nof them more than once.\n\nThe default condition for benign_errors is now to treat benign errors as\nwarnings while reading and as errors while writing.\n\nThe library now issues a warning if both background processing and RGB to\ngray are used when gamma correction happens. As with previous versions of\nthe library the results are numerically very incorrect in this case.\n\nThere are some minor arithmetic changes in some transforms such as\npng_set_background(), that might be detected by certain regression tests.\n\nUnknown chunk handling has been improved internally, without any API change.\nThis adds more correct option control of the unknown handling, corrects\na pre-existing bug where the per-chunk 'keep' setting is ignored, and makes\nit possible to skip IDAT chunks in the sequential reader.\n\nThe machine-generated configure files are no longer included in branches\nlibpng16 and later of the GIT repository.  They continue to be included\nin the tarball releases, however.\n\nLibpng-1.6.0 through 1.6.2 used the CMF bytes at the beginning of the IDAT\nstream to set the size of the sliding window for reading instead of using the\ndefault 32-kbyte sliding window size.  It was discovered that there are\nhundreds of PNG files in the wild that have incorrect CMF bytes that caused\nzlib to issue the \"invalid distance too far back\" error and reject the file.\nLibpng-1.6.3 and later calculate their own safe CMF from the image dimensions,\nprovide a way to revert to the libpng-1.5.x behavior (ignoring the CMF bytes\nand using a 32-kbyte sliding window), by using\n\n    png_set_option(png_ptr, PNG_MAXIMUM_INFLATE_WINDOW,\n        PNG_OPTION_ON);\n\nand provide a tool (contrib/tools/pngfix) for rewriting a PNG file while\noptimizing the CMF bytes in its IDAT chunk correctly.\n\nLibpng-1.6.0 and libpng-1.6.1 wrote uncompressed iTXt chunks with the wrong\nlength, which resulted in PNG files that cannot be read beyond the bad iTXt\nchunk.  This error was fixed in libpng-1.6.3, and a tool (called\ncontrib/tools/png-fix-itxt) has been added to the libpng distribution.\n\nStarting with libpng-1.6.17, the PNG_SAFE_LIMITS macro was eliminated\nand safe limits are used by default (users who need larger limits\ncan still override them at compile time or run time, as described above).\n\nThe new limits are\n                                default   spec limit\n   png_user_width_max         1,000,000  2,147,483,647\n   png_user_height_max        1,000,000  2,147,483,647\n   png_user_chunk_cache_max         128  unlimited\n   png_user_chunk_malloc_max  8,000,000  unlimited\n\nStarting with libpng-1.6.18, a PNG_RELEASE_BUILD macro was added, which allows\nlibrary builders to control compilation for an installed system (a release build).\nIt can be set for testing debug or beta builds to ensure that they will compile\nwhen the build type is switched to RC or STABLE. In essence this overrides the\nPNG_LIBPNG_BUILD_BASE_TYPE definition which is not directly user controllable.\n\nStarting with libpng-1.6.19, attempting to set an over-length PLTE chunk\nis an error. Previously this requirement of the PNG specification was not\nenforced, and the palette was always limited to 256 entries. An over-length\nPLTE chunk found in an input PNG is silently truncated.\n\n.SH XIII.  Detecting libpng\n\nThe png_get_io_ptr() function has been present since libpng-0.88, has never\nchanged, and is unaffected by conditional compilation macros.  It is the\nbest choice for use in configure scripts for detecting the presence of any\nlibpng version since 0.88.  In an autoconf \"configure.in\" you could use\n\n    AC_CHECK_LIB(png, png_get_io_ptr, ...\n\n.SH XV. Source code repository\n\nSince about February 2009, version 1.2.34, libpng has been under \"git\" source\ncontrol.  The git repository was built from old libpng-x.y.z.tar.gz files\ngoing back to version 0.70.  You can access the git repository (read only)\nat\n\n    git://git.code.sf.net/p/libpng/code\n\nor you can browse it with a web browser by selecting the \"code\" button at\n\n    https://sourceforge.net/projects/libpng\n\nPatches can be sent to glennrp at users.sourceforge.net or to\npng-mng-implement at lists.sourceforge.net or you can upload them to\nthe libpng bug tracker at\n\n    http://libpng.sourceforge.net\n\nWe also accept patches built from the tar or zip distributions, and\nsimple verbal discriptions of bug fixes, reported either to the\nSourceForge bug tracker, to the png-mng-implement at lists.sf.net\nmailing list, or directly to glennrp.\n\n.SH XV. Coding style\n\nOur coding style is similar to the \"Allman\" style\n(See http://en.wikipedia.org/wiki/Indent_style#Allman_style), with curly\nbraces on separate lines:\n\n    if (condition)\n    {\n       action;\n    }\n\n    else if (another condition)\n    {\n       another action;\n    }\n\nThe braces can be omitted from simple one-line actions:\n\n    if (condition)\n       return (0);\n\nWe use 3-space indentation, except for continued statements which\nare usually indented the same as the first line of the statement\nplus four more spaces.\n\nFor macro definitions we use 2-space indentation, always leaving the \"#\"\nin the first column.\n\n    #ifndef PNG_NO_FEATURE\n    #  ifndef PNG_FEATURE_SUPPORTED\n    #    define PNG_FEATURE_SUPPORTED\n    #  endif\n    #endif\n\nComments appear with the leading \"/*\" at the same indentation as\nthe statement that follows the comment:\n\n    /* Single-line comment */\n    statement;\n\n    /* This is a multiple-line\n     * comment.\n     */\n    statement;\n\nVery short comments can be placed after the end of the statement\nto which they pertain:\n\n    statement;    /* comment */\n\nWe don't use C++ style (\"//\") comments. We have, however,\nused them in the past in some now-abandoned MMX assembler\ncode.\n\nFunctions and their curly braces are not indented, and\nexported functions are marked with PNGAPI:\n\n /* This is a public function that is visible to\n  * application programmers. It does thus-and-so.\n  */\n void PNGAPI\n png_exported_function(png_ptr, png_info, foo)\n {\n    body;\n }\n\nThe return type and decorations are placed on a separate line\nahead of the function name, as illustrated above.\n\nThe prototypes for all exported functions appear in png.h,\nabove the comment that says\n\n    /* Maintainer: Put new public prototypes here ... */\n\nWe mark all non-exported functions with \"/* PRIVATE */\"\":\n\n void /* PRIVATE */\n png_non_exported_function(png_ptr, png_info, foo)\n {\n    body;\n }\n\nThe prototypes for non-exported functions (except for those in\npngtest) appear in pngpriv.h above the comment that says\n\n  /* Maintainer: Put new private prototypes here ^ */\n\nTo avoid polluting the global namespace, the names of all exported\nfunctions and variables begin with \"png_\", and all publicly visible C\npreprocessor macros begin with \"PNG\".  We request that applications that\nuse libpng *not* begin any of their own symbols with either of these strings.\n\nWe put a space after the \"sizeof\" operator and we omit the\noptional parentheses around its argument when the argument\nis an expression, not a type name, and we always enclose the\nsizeof operator, with its argument, in parentheses:\n\n  (sizeof (png_uint_32))\n  (sizeof array)\n\nPrior to libpng-1.6.0 we used a \"png_sizeof()\" macro, formatted as\nthough it were a function.\n\nControl keywords if, for, while, and switch are always followed by a space\nto distinguish them from function calls, which have no trailing space. \n\nWe put a space after each comma and after each semicolon\nin \"for\" statements, and we put spaces before and after each\nC binary operator and after \"for\" or \"while\", and before\n\"?\".  We don't put a space between a typecast and the expression\nbeing cast, nor do we put one between a function name and the\nleft parenthesis that follows it:\n\n    for (i = 2; i > 0; \\-\\-i)\n       y[i] = a(x) + (int)b;\n\nWe prefer #ifdef and #ifndef to #if defined() and #if !defined()\nwhen there is only one macro being tested.  We always use parentheses\nwith \"defined\".\n\nWe express integer constants that are used as bit masks in hex format,\nwith an even number of lower-case hex digits, and to make them unsigned\n(e.g., 0x00U, 0xffU, 0x0100U) and long if they are greater than 0x7fff\n(e.g., 0xffffUL).\n\nWe prefer to use underscores rather than camelCase in names, except\nfor a few type names that we inherit from zlib.h.\n\nWe prefer \"if (something != 0)\" and \"if (something == 0)\"\nover \"if (something)\" and if \"(!something)\", respectively.\n\nWe do not use the TAB character for indentation in the C sources.\n\nLines do not exceed 80 characters.\n\nOther rules can be inferred by inspecting the libpng source.\n\n.SH XVI. Y2K Compliance in libpng\n\nSince the PNG Development group is an ad-hoc body, we can't make\nan official declaration.\n\nThis is your unofficial assurance that libpng from version 0.71 and\nupward through 1.6.22beta03 are Y2K compliant.  It is my belief that earlier\nversions were also Y2K compliant.\n\nLibpng only has two year fields.  One is a 2-byte unsigned integer\nthat will hold years up to 65535.  The other, which is deprecated,\nholds the date in text format, and will hold years up to 9999.\n\nThe integer is\n    \"png_uint_16 year\" in png_time_struct.\n\nThe string is\n    \"char time_buffer[29]\" in png_struct.  This is no longer used\nin libpng-1.6.x and will be removed from libpng-1.7.0.\n\nThere are seven time-related functions:\n\n    png_convert_to_rfc_1123_buffer() in png.c\n      (formerly png_convert_to_rfc_1152() in error, and\n      also formerly png_convert_to_rfc_1123())\n    png_convert_from_struct_tm() in pngwrite.c, called\n      in pngwrite.c\n    png_convert_from_time_t() in pngwrite.c\n    png_get_tIME() in pngget.c\n    png_handle_tIME() in pngrutil.c, called in pngread.c\n    png_set_tIME() in pngset.c\n    png_write_tIME() in pngwutil.c, called in pngwrite.c\n\nAll appear to handle dates properly in a Y2K environment.  The\npng_convert_from_time_t() function calls gmtime() to convert from system\nclock time, which returns (year - 1900), which we properly convert to\nthe full 4-digit year.  There is a possibility that applications using\nlibpng are not passing 4-digit years into the png_convert_to_rfc_1123()\nfunction, or that they are incorrectly passing only a 2-digit year\ninstead of \"year - 1900\" into the png_convert_from_struct_tm() function,\nbut this is not under our control.  The libpng documentation has always\nstated that it works with 4-digit years, and the APIs have been\ndocumented as such.\n\nThe tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned\ninteger to hold the year, and can hold years as large as 65535.\n\nzlib, upon which libpng depends, is also Y2K compliant.  It contains\nno date-related code.\n\n\n   Glenn Randers-Pehrson\n   libpng maintainer\n   PNG Development Group\n\n.SH NOTE\n\nNote about libpng version numbers:\n\nDue to various miscommunications, unforeseen code incompatibilities\nand occasional factors outside the authors' control, version numbering\non the library has not always been consistent and straightforward.\nThe following table summarizes matters since version 0.89c, which was\nthe first widely used release:\n\n source             png.h  png.h  shared-lib\n version            string   int  version\n -------            ------  ----- ----------\n 0.89c \"1.0 beta 3\"     0.89      89  1.0.89\n 0.90  \"1.0 beta 4\"     0.90      90  0.90  [should have been 2.0.90]\n 0.95  \"1.0 beta 5\"     0.95      95  0.95  [should have been 2.0.95]\n 0.96  \"1.0 beta 6\"     0.96      96  0.96  [should have been 2.0.96]\n 0.97b \"1.00.97 beta 7\" 1.00.97   97  1.0.1 [should have been 2.0.97]\n 0.97c                  0.97      97  2.0.97\n 0.98                   0.98      98  2.0.98\n 0.99                   0.99      98  2.0.99\n 0.99a-m                0.99      99  2.0.99\n 1.00                   1.00     100  2.1.0 [100 should be 10000]\n 1.0.0      (from here on, the   100  2.1.0 [100 should be 10000]\n 1.0.1       png.h string is   10001  2.1.0\n 1.0.1a-e    identical to the  10002  from here on, the shared library\n 1.0.2       source version)   10002  is 2.V where V is the source code\n 1.0.2a-b                      10003  version, except as noted.\n 1.0.3                         10003\n 1.0.3a-d                      10004\n 1.0.4                         10004\n 1.0.4a-f                      10005\n 1.0.5 (+ 2 patches)           10005\n 1.0.5a-d                      10006\n 1.0.5e-r                      10100 (not source compatible)\n 1.0.5s-v                      10006 (not binary compatible)\n 1.0.6 (+ 3 patches)           10006 (still binary incompatible)\n 1.0.6d-f                      10007 (still binary incompatible)\n 1.0.6g                        10007\n 1.0.6h                        10007  10.6h (testing xy.z so-numbering)\n 1.0.6i                        10007  10.6i\n 1.0.6j                        10007  2.1.0.6j (incompatible with 1.0.0)\n 1.0.7beta11-14        DLLNUM  10007  2.1.0.7beta11-14 (binary compatible)\n 1.0.7beta15-18           1    10007  2.1.0.7beta15-18 (binary compatible)\n 1.0.7rc1-2               1    10007  2.1.0.7rc1-2 (binary compatible)\n 1.0.7                    1    10007  (still compatible)\n ...\n 1.0.19                  10    10019  10.so.0.19[.0]\n ...\n 1.2.53                  13    10253  12.so.0.53[.0]\n ...\n 1.5.23                  15    10523  15.so.15.23[.0]\n ...\n 1.6.22                  16    10622  16.so.16.22[.0]\n\nHenceforth the source version will match the shared-library minor\nand patch numbers; the shared-library major version number will be\nused for changes in backward compatibility, as it is intended.  The\nPNG_PNGLIB_VER macro, which is not used within libpng but is available\nfor applications, is an unsigned integer of the form xyyzz corresponding\nto the source version x.y.z (leading zeros in y and z).  Beta versions\nwere given the previous public release number plus a letter, until\nversion 1.0.6j; from then on they were given the upcoming public\nrelease number plus \"betaNN\" or \"rcNN\".\n\n.SH \"SEE ALSO\"\n.IR libpngpf(3) \", \" png(5)\n.LP\n.IR libpng :\n.IP\nhttp://libpng.sourceforge.net (follow the [DOWNLOAD] link)\nhttp://www.libpng.org/pub/png\n\n.LP\n.IR zlib :\n.IP\n(generally) at the same location as\n.I libpng\nor at\n.br\nftp://ftp.info-zip.org/pub/infozip/zlib\n\n.LP\n.IR PNG specification: RFC 2083\n.IP\n(generally) at the same location as\n.I libpng\nor at\n.br\nftp://ftp.rfc-editor.org:/in-notes/rfc2083.txt\n.br\nor (as a W3C Recommendation) at\n.br\nhttp://www.w3.org/TR/REC-png.html\n\n.LP\nIn the case of any inconsistency between the PNG specification\nand this library, the specification takes precedence.\n\n.SH AUTHORS\nThis man page: Glenn Randers-Pehrson\n<glennrp at users.sourceforge.net>\n\nThe contributing authors would like to thank all those who helped\nwith testing, bug fixes, and patience.  This wouldn't have been\npossible without all of you.\n\nThanks to Frank J. T. Wojcik for helping with the documentation.\n\nLibpng version 1.6.22beta03 - February 19, 2016:\nInitially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.\nCurrently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net).\n\nSupported by the PNG development group\n.br\npng-mng-implement at lists.sf.net\n(subscription required; visit\npng-mng-implement at lists.sourceforge.net (subscription required; visit\nhttps://lists.sourceforge.net/lists/listinfo/png-mng-implement\nto subscribe).\n\n.SH NOTICES:\n\nThis copy of the libpng notices is provided for your convenience.  In case of\nany discrepancy between this copy and the notices in the file png.h that is\nincluded in the libpng distribution, the latter shall prevail.\n\nCOPYRIGHT NOTICE, DISCLAIMER, and LICENSE:\n\nIf you modify libpng you may insert additional notices immediately following\nthis sentence.\n\nThis code is released under the libpng license.\n\nlibpng versions 1.0.7, July 1, 2000, through 1.6.22beta03, February 19, 2016, are\nCopyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are\nderived from libpng-1.0.6, and are distributed according to the same\ndisclaimer and license as libpng-1.0.6 with the following individuals\nadded to the list of Contributing Authors:\n\n   Simon-Pierre Cadieux\n   Eric S. Raymond\n   Mans Rullgard\n   Cosmin Truta\n   Gilles Vollant\n   James Yu\n\nand with the following additions to the disclaimer:\n\n   There is no warranty against interference with your enjoyment of the\n   library or against infringement.  There is no warranty that our\n   efforts or the library will fulfill any of your particular purposes\n   or needs.  This library is provided with all faults, and the entire\n   risk of satisfactory quality, performance, accuracy, and effort is with\n   the user.\n\nSome files in the \"contrib\" directory and some configure-generated\nfiles that are distributed with libpng have other copyright owners and\nare released under other open source licenses.\n\nlibpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are\nCopyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from\nlibpng-0.96, and are distributed according to the same disclaimer and\nlicense as libpng-0.96, with the following individuals added to the list\nof Contributing Authors:\n\n   Tom Lane\n   Glenn Randers-Pehrson\n   Willem van Schaik\n\nlibpng versions 0.89, June 1996, through 0.96, May 1997, are\nCopyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,\nand are distributed according to the same disclaimer and license as\nlibpng-0.88, with the following individuals added to the list of\nContributing Authors:\n\n   John Bowler\n   Kevin Bracey\n   Sam Bushell\n   Magnus Holmgren\n   Greg Roelofs\n   Tom Tanner\n\nSome files in the \"scripts\" directory have other copyright owners\nbut are released under this license.\n\nlibpng versions 0.5, May 1995, through 0.88, January 1996, are\nCopyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n\nFor the purposes of this copyright and license, \"Contributing Authors\"\nis defined as the following set of individuals:\n\n   Andreas Dilger\n   Dave Martindale\n   Guy Eric Schalnat\n   Paul Schmidt\n   Tim Wegner\n\nThe PNG Reference Library is supplied \"AS IS\".  The Contributing Authors\nand Group 42, Inc. disclaim all warranties, expressed or implied,\nincluding, without limitation, the warranties of merchantability and of\nfitness for any purpose.  The Contributing Authors and Group 42, Inc.\nassume no liability for direct, indirect, incidental, special, exemplary,\nor consequential damages, which may result from the use of the PNG\nReference Library, even if advised of the possibility of such damage.\n\nPermission is hereby granted to use, copy, modify, and distribute this\nsource code, or portions hereof, for any purpose, without fee, subject\nto the following restrictions:\n\n  1. The origin of this source code must not be misrepresented.\n\n  2. Altered versions must be plainly marked as such and must not\n     be misrepresented as being the original source.\n\n  3. This Copyright notice may not be removed or altered from any\n     source or altered source distribution.\n\nThe Contributing Authors and Group 42, Inc. specifically permit, without\nfee, and encourage the use of this source code as a component to\nsupporting the PNG file format in commercial products.  If you use this\nsource code in a product, acknowledgment is not required but would be\nappreciated.\n\nEND OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.\n\nTRADEMARK:\n\nThe name \"libpng\" has not been registered by the Copyright owner\nas a trademark in any jurisdiction.  However, because libpng has\nbeen distributed and maintained world-wide, continually since 1995,\nthe Copyright owner claims \"common-law trademark protection\" in any\njurisdiction where common-law trademark is recognized.\n\nOSI CERTIFICATION:\n\nLibpng is OSI Certified Open Source Software.  OSI Certified Open Source is\na certification mark of the Open Source Initiative. OSI has not addressed\nthe additional disclaimers inserted at version 1.0.7.\n\nEXPORT CONTROL:\n\nThe Copyright owner believes that the Export Control Classification\nNumber (ECCN) for libpng is EAR99, which means not subject to export\ncontrols or International Traffic in Arms Regulations (ITAR) because\nit is open source, publicly available software, that does not contain\nany encryption software.  See the EAR, paragraphs 734.3(b)(3) and\n734.7(b).\n\nA \"png_get_copyright\" function is available, for convenient use in \"about\"\nboxes and the like:\n\n   printf(\"%s\", png_get_copyright(NULL));\n\nAlso, the PNG logo (in PNG format, of course) is supplied in the\nfiles \"pngbar.png\" and \"pngbar.jpg (88x31) and \"pngnow.png\" (98x31).\n\nGlenn Randers-Pehrson\nglennrp at users.sourceforge.net\nFebruary 19, 2016\n\n.\\\" end of man page\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/libpng.pc.in",
    "content": "prefix=@prefix@\nexec_prefix=@exec_prefix@\nlibdir=@libdir@\nincludedir=@includedir@/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@\n\nName: libpng\nDescription: Loads and saves PNG files\nVersion: @PNGLIB_VERSION@\nLibs: -L${libdir} -lpng@PNGLIB_MAJOR@@PNGLIB_MINOR@\nLibs.private: @LIBS@\nCflags: -I${includedir}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/libpngpf.3",
    "content": ".TH LIBPNGPF 3 \"February 8, 2016\"\n.SH NAME\nlibpng \\- Portable Network Graphics (PNG) Reference Library 1.6.22beta03\n(private functions)\n.SH SYNOPSIS\n\\fB#include \\fI\"pngpriv.h\"\n\n\\fBAs of libpng version \\fP\\fI1.5.1\\fP\\fB, this section is no longer \\fP\\fImaintained\\fP\\fB, now that the private function prototypes are hidden in pngpriv.h and not accessible to applications. Look in pngpriv.h for the prototypes and a short description of each \\fIfunction.\n\n.SH DESCRIPTION\nThe functions previously listed here are used privately by libpng and are not\navailable for use by applications.  They are not \"exported\" to applications\nusing shared libraries.\n\n.SH SEE ALSO\n.BR \"png\"(5), \" libpng\"(3), \" zlib\"(3), \" deflate\"(5), \" \" and \" zlib\"(5)\n.SH AUTHOR\nGlenn Randers-Pehrson\n"
  },
  {
    "path": "atlas-aapt/external/libpng/png.5",
    "content": ".TH PNG 5 \"February 8, 2016\"\n.SH NAME\npng \\- Portable Network Graphics (PNG) format\n.SH DESCRIPTION\nPNG (Portable Network Graphics) is an extensible file format for the\nlossless, portable, well-compressed storage of raster images. PNG provides\na patent-free replacement for GIF and can also replace many\ncommon uses of TIFF. Indexed-color, grayscale, and truecolor images are\nsupported, plus an optional alpha channel. Sample depths range from\n1 to 16 bits.\n.br\n\nPNG is designed to work well in online viewing applications, such as the\nWorld Wide Web, so it is fully streamable with a progressive display\noption. PNG is robust, providing both full file integrity checking and\nfast, simple detection of common transmission errors. Also, PNG can store\ngamma and chromaticity data for improved color matching on heterogeneous\nplatforms.\n\n.SH \"SEE ALSO\"\n.BR \"libpng\"(3), \" libpngpf\"(3), \" zlib\"(3), \" deflate\"(5), \" \" and \" zlib\"(5)\n.LP\nPNG specification (second edition), November 2003:\n.IP\n.br\n  <http://www.w3.org/TR/2003/REC-PNG-20031110/\nPNG 1.2 specification, July 1999:\n.IP\n.br\nhttp://png-mng.sourceforge.net/pub/png/spec/1.2/\n.LP\nPNG 1.0 specification, October 1996:\n.IP\n.br\nRFC 2083\n.IP\n.br\nftp://ds.internic.net/rfc/rfc2083.txt\n.br\nor (as a W3C Recommendation) at\n.br\nhttp://www.w3.org/TR/REC-png-961001\n.SH AUTHORS\nThis man page: Glenn Randers-Pehrson\n.LP\nPortable Network Graphics (PNG) Specification (Second Edition)\nInformation technology - Computer graphics and image processing -\nPortable Network Graphics (PNG): Functional specification.\nISO/IEC 15948:2003 (E) (November 10, 2003): David Duce and others.\n.LP\nPortable Network Graphics (PNG) Specification Version 1.2 (July 8, 1999):\nGlenn Randers-Pehrson and others (png-list).\n.LP\nPortable Network Graphics (PNG) Specification Version 1.0 (October 1, 1996):\nThomas Boutell and others (png-list).\n.LP\n\n\n.SH COPYRIGHT NOTICE\n.LP\nThis man page is Copyright (c) 1998-2006 Glenn Randers-Pehrson.  See png.h\nfor conditions of use and distribution.\n.LP\nThe PNG Specification (Second Edition) is\nCopyright (c) 2003 W3C. (MIT, ERCIM, Keio), All Rights Reserved.\n.LP\nThe PNG-1.2 specification is copyright (c) 1999 Glenn Randers-Pehrson.\nSee the specification for conditions of use and distribution.\n.LP\nThe PNG-1.0 specification is copyright (c) 1996 Massachusetts Institute of\nTechnology.  See the specification for conditions of use and distribution.\n.LP\n.\\\" end of man page\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/png.c",
    "content": "\n/* png.c - location for general purpose libpng functions\n *\n * Last changed in libpng 1.6.19 [November 12, 2015]\n * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n#include \"pngpriv.h\"\n\n/* Generate a compiler error if there is an old png.h in the search path. */\ntypedef png_libpng_version_1_6_22beta03 Your_png_h_is_not_version_1_6_22beta03;\n\n/* Tells libpng that we have already handled the first \"num_bytes\" bytes\n * of the PNG file signature.  If the PNG data is embedded into another\n * stream we can set num_bytes = 8 so that libpng will not attempt to read\n * or write any of the magic bytes before it starts on the IHDR.\n */\n\n#ifdef PNG_READ_SUPPORTED\nvoid PNGAPI\npng_set_sig_bytes(png_structrp png_ptr, int num_bytes)\n{\n   unsigned int nb = (unsigned int)num_bytes;\n\n   png_debug(1, \"in png_set_sig_bytes\");\n\n   if (png_ptr == NULL)\n      return;\n\n   if (num_bytes < 0)\n      nb = 0;\n\n   if (nb > 8)\n      png_error(png_ptr, \"Too many bytes for PNG signature\");\n\n   png_ptr->sig_bytes = (png_byte)nb;\n}\n\n/* Checks whether the supplied bytes match the PNG signature.  We allow\n * checking less than the full 8-byte signature so that those apps that\n * already read the first few bytes of a file to determine the file type\n * can simply check the remaining bytes for extra assurance.  Returns\n * an integer less than, equal to, or greater than zero if sig is found,\n * respectively, to be less than, to match, or be greater than the correct\n * PNG signature (this is the same behavior as strcmp, memcmp, etc).\n */\nint PNGAPI\npng_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)\n{\n   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};\n\n   if (num_to_check > 8)\n      num_to_check = 8;\n\n   else if (num_to_check < 1)\n      return (-1);\n\n   if (start > 7)\n      return (-1);\n\n   if (start + num_to_check > 8)\n      num_to_check = 8 - start;\n\n   return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check)));\n}\n\n#endif /* READ */\n\n#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)\n/* Function to allocate memory for zlib */\nPNG_FUNCTION(voidpf /* PRIVATE */,\npng_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)\n{\n   png_alloc_size_t num_bytes = size;\n\n   if (png_ptr == NULL)\n      return NULL;\n\n   if (items >= (~(png_alloc_size_t)0)/size)\n   {\n      png_warning (png_voidcast(png_structrp, png_ptr),\n         \"Potential overflow in png_zalloc()\");\n      return NULL;\n   }\n\n   num_bytes *= items;\n   return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes);\n}\n\n/* Function to free memory for zlib */\nvoid /* PRIVATE */\npng_zfree(voidpf png_ptr, voidpf ptr)\n{\n   png_free(png_voidcast(png_const_structrp,png_ptr), ptr);\n}\n\n/* Reset the CRC variable to 32 bits of 1's.  Care must be taken\n * in case CRC is > 32 bits to leave the top bits 0.\n */\nvoid /* PRIVATE */\npng_reset_crc(png_structrp png_ptr)\n{\n   /* The cast is safe because the crc is a 32-bit value. */\n   png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0);\n}\n\n/* Calculate the CRC over a section of data.  We can only pass as\n * much data to this routine as the largest single buffer size.  We\n * also check that this data will actually be used before going to the\n * trouble of calculating it.\n */\nvoid /* PRIVATE */\npng_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length)\n{\n   int need_crc = 1;\n\n   if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)\n   {\n      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==\n          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))\n         need_crc = 0;\n   }\n\n   else /* critical */\n   {\n      if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)\n         need_crc = 0;\n   }\n\n   /* 'uLong' is defined in zlib.h as unsigned long; this means that on some\n    * systems it is a 64-bit value.  crc32, however, returns 32 bits so the\n    * following cast is safe.  'uInt' may be no more than 16 bits, so it is\n    * necessary to perform a loop here.\n    */\n   if (need_crc != 0 && length > 0)\n   {\n      uLong crc = png_ptr->crc; /* Should never issue a warning */\n\n      do\n      {\n         uInt safe_length = (uInt)length;\n#ifndef __COVERITY__\n         if (safe_length == 0)\n            safe_length = (uInt)-1; /* evil, but safe */\n#endif\n\n         crc = crc32(crc, ptr, safe_length);\n\n         /* The following should never issue compiler warnings; if they do the\n          * target system has characteristics that will probably violate other\n          * assumptions within the libpng code.\n          */\n         ptr += safe_length;\n         length -= safe_length;\n      }\n      while (length > 0);\n\n      /* And the following is always safe because the crc is only 32 bits. */\n      png_ptr->crc = (png_uint_32)crc;\n   }\n}\n\n/* Check a user supplied version number, called from both read and write\n * functions that create a png_struct.\n */\nint\npng_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)\n{\n     /* Libpng versions 1.0.0 and later are binary compatible if the version\n      * string matches through the second '.'; we must recompile any\n      * applications that use any older library version.\n      */\n\n   if (user_png_ver != NULL)\n   {\n      int i = -1;\n      int found_dots = 0;\n\n      do\n      {\n         i++;\n         if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i])\n            png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;\n         if (user_png_ver[i] == '.')\n            found_dots++;\n      } while (found_dots < 2 && user_png_ver[i] != 0 &&\n            PNG_LIBPNG_VER_STRING[i] != 0);\n   }\n\n   else\n      png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;\n\n   if ((png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) != 0)\n   {\n#ifdef PNG_WARNINGS_SUPPORTED\n      size_t pos = 0;\n      char m[128];\n\n      pos = png_safecat(m, (sizeof m), pos,\n          \"Application built with libpng-\");\n      pos = png_safecat(m, (sizeof m), pos, user_png_ver);\n      pos = png_safecat(m, (sizeof m), pos, \" but running with \");\n      pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING);\n      PNG_UNUSED(pos)\n\n      png_warning(png_ptr, m);\n#endif\n\n#ifdef PNG_ERROR_NUMBERS_SUPPORTED\n      png_ptr->flags = 0;\n#endif\n\n      return 0;\n   }\n\n   /* Success return. */\n   return 1;\n}\n\n/* Generic function to create a png_struct for either read or write - this\n * contains the common initialization.\n */\nPNG_FUNCTION(png_structp /* PRIVATE */,\npng_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,\n    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,\n    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)\n{\n   png_struct create_struct;\n#  ifdef PNG_SETJMP_SUPPORTED\n      jmp_buf create_jmp_buf;\n#  endif\n\n   /* This temporary stack-allocated structure is used to provide a place to\n    * build enough context to allow the user provided memory allocator (if any)\n    * to be called.\n    */\n   memset(&create_struct, 0, (sizeof create_struct));\n\n   /* Added at libpng-1.2.6 */\n#  ifdef PNG_USER_LIMITS_SUPPORTED\n      create_struct.user_width_max = PNG_USER_WIDTH_MAX;\n      create_struct.user_height_max = PNG_USER_HEIGHT_MAX;\n\n#     ifdef PNG_USER_CHUNK_CACHE_MAX\n      /* Added at libpng-1.2.43 and 1.4.0 */\n      create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;\n#     endif\n\n#     ifdef PNG_USER_CHUNK_MALLOC_MAX\n      /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists\n       * in png_struct regardless.\n       */\n      create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;\n#     endif\n#  endif\n\n   /* The following two API calls simply set fields in png_struct, so it is safe\n    * to do them now even though error handling is not yet set up.\n    */\n#  ifdef PNG_USER_MEM_SUPPORTED\n      png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn);\n#  else\n      PNG_UNUSED(mem_ptr)\n      PNG_UNUSED(malloc_fn)\n      PNG_UNUSED(free_fn)\n#  endif\n\n   /* (*error_fn) can return control to the caller after the error_ptr is set,\n    * this will result in a memory leak unless the error_fn does something\n    * extremely sophisticated.  The design lacks merit but is implicit in the\n    * API.\n    */\n   png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn);\n\n#  ifdef PNG_SETJMP_SUPPORTED\n      if (!setjmp(create_jmp_buf))\n#  endif\n      {\n#  ifdef PNG_SETJMP_SUPPORTED\n         /* Temporarily fake out the longjmp information until we have\n          * successfully completed this function.  This only works if we have\n          * setjmp() support compiled in, but it is safe - this stuff should\n          * never happen.\n          */\n         create_struct.jmp_buf_ptr = &create_jmp_buf;\n         create_struct.jmp_buf_size = 0; /*stack allocation*/\n         create_struct.longjmp_fn = longjmp;\n#  endif\n         /* Call the general version checker (shared with read and write code):\n          */\n         if (png_user_version_check(&create_struct, user_png_ver) != 0)\n         {\n            png_structrp png_ptr = png_voidcast(png_structrp,\n               png_malloc_warn(&create_struct, (sizeof *png_ptr)));\n\n            if (png_ptr != NULL)\n            {\n               /* png_ptr->zstream holds a back-pointer to the png_struct, so\n                * this can only be done now:\n                */\n               create_struct.zstream.zalloc = png_zalloc;\n               create_struct.zstream.zfree = png_zfree;\n               create_struct.zstream.opaque = png_ptr;\n\n#              ifdef PNG_SETJMP_SUPPORTED\n               /* Eliminate the local error handling: */\n               create_struct.jmp_buf_ptr = NULL;\n               create_struct.jmp_buf_size = 0;\n               create_struct.longjmp_fn = 0;\n#              endif\n\n               *png_ptr = create_struct;\n\n               /* This is the successful return point */\n               return png_ptr;\n            }\n         }\n      }\n\n   /* A longjmp because of a bug in the application storage allocator or a\n    * simple failure to allocate the png_struct.\n    */\n   return NULL;\n}\n\n/* Allocate the memory for an info_struct for the application. */\nPNG_FUNCTION(png_infop,PNGAPI\npng_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED)\n{\n   png_inforp info_ptr;\n\n   png_debug(1, \"in png_create_info_struct\");\n\n   if (png_ptr == NULL)\n      return NULL;\n\n   /* Use the internal API that does not (or at least should not) error out, so\n    * that this call always returns ok.  The application typically sets up the\n    * error handling *after* creating the info_struct because this is the way it\n    * has always been done in 'example.c'.\n    */\n   info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,\n      (sizeof *info_ptr)));\n\n   if (info_ptr != NULL)\n      memset(info_ptr, 0, (sizeof *info_ptr));\n\n   return info_ptr;\n}\n\n/* This function frees the memory associated with a single info struct.\n * Normally, one would use either png_destroy_read_struct() or\n * png_destroy_write_struct() to free an info struct, but this may be\n * useful for some applications.  From libpng 1.6.0 this function is also used\n * internally to implement the png_info release part of the 'struct' destroy\n * APIs.  This ensures that all possible approaches free the same data (all of\n * it).\n */\nvoid PNGAPI\npng_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr)\n{\n   png_inforp info_ptr = NULL;\n\n   png_debug(1, \"in png_destroy_info_struct\");\n\n   if (png_ptr == NULL)\n      return;\n\n   if (info_ptr_ptr != NULL)\n      info_ptr = *info_ptr_ptr;\n\n   if (info_ptr != NULL)\n   {\n      /* Do this first in case of an error below; if the app implements its own\n       * memory management this can lead to png_free calling png_error, which\n       * will abort this routine and return control to the app error handler.\n       * An infinite loop may result if it then tries to free the same info\n       * ptr.\n       */\n      *info_ptr_ptr = NULL;\n\n      png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);\n      memset(info_ptr, 0, (sizeof *info_ptr));\n      png_free(png_ptr, info_ptr);\n   }\n}\n\n/* Initialize the info structure.  This is now an internal function (0.89)\n * and applications using it are urged to use png_create_info_struct()\n * instead.  Use deprecated in 1.6.0, internal use removed (used internally it\n * is just a memset).\n *\n * NOTE: it is almost inconceivable that this API is used because it bypasses\n * the user-memory mechanism and the user error handling/warning mechanisms in\n * those cases where it does anything other than a memset.\n */\nPNG_FUNCTION(void,PNGAPI\npng_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),\n   PNG_DEPRECATED)\n{\n   png_inforp info_ptr = *ptr_ptr;\n\n   png_debug(1, \"in png_info_init_3\");\n\n   if (info_ptr == NULL)\n      return;\n\n   if ((sizeof (png_info)) > png_info_struct_size)\n   {\n      *ptr_ptr = NULL;\n      /* The following line is why this API should not be used: */\n      free(info_ptr);\n      info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,\n         (sizeof *info_ptr)));\n      if (info_ptr == NULL)\n         return;\n      *ptr_ptr = info_ptr;\n   }\n\n   /* Set everything to 0 */\n   memset(info_ptr, 0, (sizeof *info_ptr));\n}\n\n/* The following API is not called internally */\nvoid PNGAPI\npng_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,\n   int freer, png_uint_32 mask)\n{\n   png_debug(1, \"in png_data_freer\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   if (freer == PNG_DESTROY_WILL_FREE_DATA)\n      info_ptr->free_me |= mask;\n\n   else if (freer == PNG_USER_WILL_FREE_DATA)\n      info_ptr->free_me &= ~mask;\n\n   else\n      png_error(png_ptr, \"Unknown freer parameter in png_data_freer\");\n}\n\nvoid PNGAPI\npng_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,\n   int num)\n{\n   png_debug(1, \"in png_free_data\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n#ifdef PNG_TEXT_SUPPORTED\n   /* Free text item num or (if num == -1) all text items */\n   if (info_ptr->text != 0 &&\n       ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0)\n   {\n      if (num != -1)\n      {\n         png_free(png_ptr, info_ptr->text[num].key);\n         info_ptr->text[num].key = NULL;\n      }\n\n      else\n      {\n         int i;\n\n         for (i = 0; i < info_ptr->num_text; i++)\n            png_free(png_ptr, info_ptr->text[i].key);\n\n         png_free(png_ptr, info_ptr->text);\n         info_ptr->text = NULL;\n         info_ptr->num_text = 0;\n      }\n   }\n#endif\n\n#ifdef PNG_tRNS_SUPPORTED\n   /* Free any tRNS entry */\n   if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0)\n   {\n      info_ptr->valid &= ~PNG_INFO_tRNS;\n      png_free(png_ptr, info_ptr->trans_alpha);\n      info_ptr->trans_alpha = NULL;\n      info_ptr->num_trans = 0;\n   }\n#endif\n\n#ifdef PNG_sCAL_SUPPORTED\n   /* Free any sCAL entry */\n   if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0)\n   {\n      png_free(png_ptr, info_ptr->scal_s_width);\n      png_free(png_ptr, info_ptr->scal_s_height);\n      info_ptr->scal_s_width = NULL;\n      info_ptr->scal_s_height = NULL;\n      info_ptr->valid &= ~PNG_INFO_sCAL;\n   }\n#endif\n\n#ifdef PNG_pCAL_SUPPORTED\n   /* Free any pCAL entry */\n   if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0)\n   {\n      png_free(png_ptr, info_ptr->pcal_purpose);\n      png_free(png_ptr, info_ptr->pcal_units);\n      info_ptr->pcal_purpose = NULL;\n      info_ptr->pcal_units = NULL;\n\n      if (info_ptr->pcal_params != NULL)\n         {\n            int i;\n\n            for (i = 0; i < info_ptr->pcal_nparams; i++)\n               png_free(png_ptr, info_ptr->pcal_params[i]);\n\n            png_free(png_ptr, info_ptr->pcal_params);\n            info_ptr->pcal_params = NULL;\n         }\n      info_ptr->valid &= ~PNG_INFO_pCAL;\n   }\n#endif\n\n#ifdef PNG_iCCP_SUPPORTED\n   /* Free any profile entry */\n   if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0)\n   {\n      png_free(png_ptr, info_ptr->iccp_name);\n      png_free(png_ptr, info_ptr->iccp_profile);\n      info_ptr->iccp_name = NULL;\n      info_ptr->iccp_profile = NULL;\n      info_ptr->valid &= ~PNG_INFO_iCCP;\n   }\n#endif\n\n#ifdef PNG_sPLT_SUPPORTED\n   /* Free a given sPLT entry, or (if num == -1) all sPLT entries */\n   if (info_ptr->splt_palettes != 0 &&\n       ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0)\n   {\n      if (num != -1)\n      {\n         png_free(png_ptr, info_ptr->splt_palettes[num].name);\n         png_free(png_ptr, info_ptr->splt_palettes[num].entries);\n         info_ptr->splt_palettes[num].name = NULL;\n         info_ptr->splt_palettes[num].entries = NULL;\n      }\n\n      else\n      {\n         int i;\n\n         for (i = 0; i < info_ptr->splt_palettes_num; i++)\n         {\n            png_free(png_ptr, info_ptr->splt_palettes[i].name);\n            png_free(png_ptr, info_ptr->splt_palettes[i].entries);\n         }\n\n         png_free(png_ptr, info_ptr->splt_palettes);\n         info_ptr->splt_palettes = NULL;\n         info_ptr->splt_palettes_num = 0;\n         info_ptr->valid &= ~PNG_INFO_sPLT;\n      }\n   }\n#endif\n\n#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED\n   if (info_ptr->unknown_chunks != 0 &&\n       ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0)\n   {\n      if (num != -1)\n      {\n          png_free(png_ptr, info_ptr->unknown_chunks[num].data);\n          info_ptr->unknown_chunks[num].data = NULL;\n      }\n\n      else\n      {\n         int i;\n\n         for (i = 0; i < info_ptr->unknown_chunks_num; i++)\n            png_free(png_ptr, info_ptr->unknown_chunks[i].data);\n\n         png_free(png_ptr, info_ptr->unknown_chunks);\n         info_ptr->unknown_chunks = NULL;\n         info_ptr->unknown_chunks_num = 0;\n      }\n   }\n#endif\n\n#ifdef PNG_hIST_SUPPORTED\n   /* Free any hIST entry */\n   if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)\n   {\n      png_free(png_ptr, info_ptr->hist);\n      info_ptr->hist = NULL;\n      info_ptr->valid &= ~PNG_INFO_hIST;\n   }\n#endif\n\n   /* Free any PLTE entry that was internally allocated */\n   if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0)\n   {\n      png_free(png_ptr, info_ptr->palette);\n      info_ptr->palette = NULL;\n      info_ptr->valid &= ~PNG_INFO_PLTE;\n      info_ptr->num_palette = 0;\n   }\n\n#ifdef PNG_INFO_IMAGE_SUPPORTED\n   /* Free any image bits attached to the info structure */\n   if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0)\n   {\n      if (info_ptr->row_pointers != 0)\n      {\n         png_uint_32 row;\n         for (row = 0; row < info_ptr->height; row++)\n            png_free(png_ptr, info_ptr->row_pointers[row]);\n\n         png_free(png_ptr, info_ptr->row_pointers);\n         info_ptr->row_pointers = NULL;\n      }\n      info_ptr->valid &= ~PNG_INFO_IDAT;\n   }\n#endif\n\n   if (num != -1)\n      mask &= ~PNG_FREE_MUL;\n\n   info_ptr->free_me &= ~mask;\n}\n#endif /* READ || WRITE */\n\n/* This function returns a pointer to the io_ptr associated with the user\n * functions.  The application should free any memory associated with this\n * pointer before png_write_destroy() or png_read_destroy() are called.\n */\npng_voidp PNGAPI\npng_get_io_ptr(png_const_structrp png_ptr)\n{\n   if (png_ptr == NULL)\n      return (NULL);\n\n   return (png_ptr->io_ptr);\n}\n\n#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)\n#  ifdef PNG_STDIO_SUPPORTED\n/* Initialize the default input/output functions for the PNG file.  If you\n * use your own read or write routines, you can call either png_set_read_fn()\n * or png_set_write_fn() instead of png_init_io().  If you have defined\n * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a\n * function of your own because \"FILE *\" isn't necessarily available.\n */\nvoid PNGAPI\npng_init_io(png_structrp png_ptr, png_FILE_p fp)\n{\n   png_debug(1, \"in png_init_io\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->io_ptr = (png_voidp)fp;\n}\n#  endif\n\n#  ifdef PNG_SAVE_INT_32_SUPPORTED\n/* PNG signed integers are saved in 32-bit 2's complement format.  ANSI C-90\n * defines a cast of a signed integer to an unsigned integer either to preserve\n * the value, if it is positive, or to calculate:\n *\n *     (UNSIGNED_MAX+1) + integer\n *\n * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the\n * negative integral value is added the result will be an unsigned value\n * correspnding to the 2's complement representation.\n */\nvoid PNGAPI\npng_save_int_32(png_bytep buf, png_int_32 i)\n{\n   png_save_uint_32(buf, i);\n}\n#  endif\n\n#  ifdef PNG_TIME_RFC1123_SUPPORTED\n/* Convert the supplied time into an RFC 1123 string suitable for use in\n * a \"Creation Time\" or other text-based time string.\n */\nint PNGAPI\npng_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)\n{\n   static PNG_CONST char short_months[12][4] =\n        {\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\n         \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"};\n\n   if (out == NULL)\n      return 0;\n\n   if (ptime->year > 9999 /* RFC1123 limitation */ ||\n       ptime->month == 0    ||  ptime->month > 12  ||\n       ptime->day   == 0    ||  ptime->day   > 31  ||\n       ptime->hour  > 23    ||  ptime->minute > 59 ||\n       ptime->second > 60)\n      return 0;\n\n   {\n      size_t pos = 0;\n      char number_buf[5]; /* enough for a four-digit year */\n\n#     define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string))\n#     define APPEND_NUMBER(format, value)\\\n         APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value)))\n#     define APPEND(ch) if (pos < 28) out[pos++] = (ch)\n\n      APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day);\n      APPEND(' ');\n      APPEND_STRING(short_months[(ptime->month - 1)]);\n      APPEND(' ');\n      APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year);\n      APPEND(' ');\n      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour);\n      APPEND(':');\n      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute);\n      APPEND(':');\n      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);\n      APPEND_STRING(\" +0000\"); /* This reliably terminates the buffer */\n      PNG_UNUSED (pos)\n\n#     undef APPEND\n#     undef APPEND_NUMBER\n#     undef APPEND_STRING\n   }\n\n   return 1;\n}\n\n#    if PNG_LIBPNG_VER < 10700\n/* To do: remove the following from libpng-1.7 */\n/* Original API that uses a private buffer in png_struct.\n * Deprecated because it causes png_struct to carry a spurious temporary\n * buffer (png_struct::time_buffer), better to have the caller pass this in.\n */\npng_const_charp PNGAPI\npng_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime)\n{\n   if (png_ptr != NULL)\n   {\n      /* The only failure above if png_ptr != NULL is from an invalid ptime */\n      if (png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime) == 0)\n         png_warning(png_ptr, \"Ignoring invalid time value\");\n\n      else\n         return png_ptr->time_buffer;\n   }\n\n   return NULL;\n}\n#    endif /* LIBPNG_VER < 10700 */\n#  endif /* TIME_RFC1123 */\n\n#endif /* READ || WRITE */\n\npng_const_charp PNGAPI\npng_get_copyright(png_const_structrp png_ptr)\n{\n   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */\n#ifdef PNG_STRING_COPYRIGHT\n   return PNG_STRING_COPYRIGHT\n#else\n#  ifdef __STDC__\n   return PNG_STRING_NEWLINE \\\n      \"libpng version 1.6.22beta03 - February 8, 2016\" PNG_STRING_NEWLINE \\\n      \"Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson\" \\\n      PNG_STRING_NEWLINE \\\n      \"Copyright (c) 1996-1997 Andreas Dilger\" PNG_STRING_NEWLINE \\\n      \"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\" \\\n      PNG_STRING_NEWLINE;\n#  else\n   return \"libpng version 1.6.22beta03 - February 8, 2016\\\n      Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson\\\n      Copyright (c) 1996-1997 Andreas Dilger\\\n      Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\";\n#  endif\n#endif\n}\n\n/* The following return the library version as a short string in the\n * format 1.0.0 through 99.99.99zz.  To get the version of *.h files\n * used with your application, print out PNG_LIBPNG_VER_STRING, which\n * is defined in png.h.\n * Note: now there is no difference between png_get_libpng_ver() and\n * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,\n * it is guaranteed that png.c uses the correct version of png.h.\n */\npng_const_charp PNGAPI\npng_get_libpng_ver(png_const_structrp png_ptr)\n{\n   /* Version of *.c files used when building libpng */\n   return png_get_header_ver(png_ptr);\n}\n\npng_const_charp PNGAPI\npng_get_header_ver(png_const_structrp png_ptr)\n{\n   /* Version of *.h files used when building libpng */\n   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */\n   return PNG_LIBPNG_VER_STRING;\n}\n\npng_const_charp PNGAPI\npng_get_header_version(png_const_structrp png_ptr)\n{\n   /* Returns longer string containing both version and date */\n   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */\n#ifdef __STDC__\n   return PNG_HEADER_VERSION_STRING\n#  ifndef PNG_READ_SUPPORTED\n      \" (NO READ SUPPORT)\"\n#  endif\n      PNG_STRING_NEWLINE;\n#else\n   return PNG_HEADER_VERSION_STRING;\n#endif\n}\n\n#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED\n/* NOTE: this routine is not used internally! */\n/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth\n * large of png_color.  This lets grayscale images be treated as\n * paletted.  Most useful for gamma correction and simplification\n * of code.  This API is not used internally.\n */\nvoid PNGAPI\npng_build_grayscale_palette(int bit_depth, png_colorp palette)\n{\n   int num_palette;\n   int color_inc;\n   int i;\n   int v;\n\n   png_debug(1, \"in png_do_build_grayscale_palette\");\n\n   if (palette == NULL)\n      return;\n\n   switch (bit_depth)\n   {\n      case 1:\n         num_palette = 2;\n         color_inc = 0xff;\n         break;\n\n      case 2:\n         num_palette = 4;\n         color_inc = 0x55;\n         break;\n\n      case 4:\n         num_palette = 16;\n         color_inc = 0x11;\n         break;\n\n      case 8:\n         num_palette = 256;\n         color_inc = 1;\n         break;\n\n      default:\n         num_palette = 0;\n         color_inc = 0;\n         break;\n   }\n\n   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)\n   {\n      palette[i].red = (png_byte)(v & 0xff);\n      palette[i].green = (png_byte)(v & 0xff);\n      palette[i].blue = (png_byte)(v & 0xff);\n   }\n}\n#endif\n\n#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED\nint PNGAPI\npng_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)\n{\n   /* Check chunk_name and return \"keep\" value if it's on the list, else 0 */\n   png_const_bytep p, p_end;\n\n   if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0)\n      return PNG_HANDLE_CHUNK_AS_DEFAULT;\n\n   p_end = png_ptr->chunk_list;\n   p = p_end + png_ptr->num_chunk_list*5; /* beyond end */\n\n   /* The code is the fifth byte after each four byte string.  Historically this\n    * code was always searched from the end of the list, this is no longer\n    * necessary because the 'set' routine handles duplicate entries correcty.\n    */\n   do /* num_chunk_list > 0, so at least one */\n   {\n      p -= 5;\n\n      if (memcmp(chunk_name, p, 4) == 0)\n         return p[4];\n   }\n   while (p > p_end);\n\n   /* This means that known chunks should be processed and unknown chunks should\n    * be handled according to the value of png_ptr->unknown_default; this can be\n    * confusing because, as a result, there are two levels of defaulting for\n    * unknown chunks.\n    */\n   return PNG_HANDLE_CHUNK_AS_DEFAULT;\n}\n\n#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\\\n   defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)\nint /* PRIVATE */\npng_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name)\n{\n   png_byte chunk_string[5];\n\n   PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name);\n   return png_handle_as_unknown(png_ptr, chunk_string);\n}\n#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */\n#endif /* SET_UNKNOWN_CHUNKS */\n\n#ifdef PNG_READ_SUPPORTED\n/* This function, added to libpng-1.0.6g, is untested. */\nint PNGAPI\npng_reset_zstream(png_structrp png_ptr)\n{\n   if (png_ptr == NULL)\n      return Z_STREAM_ERROR;\n\n   /* WARNING: this resets the window bits to the maximum! */\n   return (inflateReset(&png_ptr->zstream));\n}\n#endif /* READ */\n\n/* This function was added to libpng-1.0.7 */\npng_uint_32 PNGAPI\npng_access_version_number(void)\n{\n   /* Version of *.c files used when building libpng */\n   return((png_uint_32)PNG_LIBPNG_VER);\n}\n\n#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)\n/* Ensure that png_ptr->zstream.msg holds some appropriate error message string.\n * If it doesn't 'ret' is used to set it to something appropriate, even in cases\n * like Z_OK or Z_STREAM_END where the error code is apparently a success code.\n */\nvoid /* PRIVATE */\npng_zstream_error(png_structrp png_ptr, int ret)\n{\n   /* Translate 'ret' into an appropriate error string, priority is given to the\n    * one in zstream if set.  This always returns a string, even in cases like\n    * Z_OK or Z_STREAM_END where the error code is a success code.\n    */\n   if (png_ptr->zstream.msg == NULL) switch (ret)\n   {\n      default:\n      case Z_OK:\n         png_ptr->zstream.msg = PNGZ_MSG_CAST(\"unexpected zlib return code\");\n         break;\n\n      case Z_STREAM_END:\n         /* Normal exit */\n         png_ptr->zstream.msg = PNGZ_MSG_CAST(\"unexpected end of LZ stream\");\n         break;\n\n      case Z_NEED_DICT:\n         /* This means the deflate stream did not have a dictionary; this\n          * indicates a bogus PNG.\n          */\n         png_ptr->zstream.msg = PNGZ_MSG_CAST(\"missing LZ dictionary\");\n         break;\n\n      case Z_ERRNO:\n         /* gz APIs only: should not happen */\n         png_ptr->zstream.msg = PNGZ_MSG_CAST(\"zlib IO error\");\n         break;\n\n      case Z_STREAM_ERROR:\n         /* internal libpng error */\n         png_ptr->zstream.msg = PNGZ_MSG_CAST(\"bad parameters to zlib\");\n         break;\n\n      case Z_DATA_ERROR:\n         png_ptr->zstream.msg = PNGZ_MSG_CAST(\"damaged LZ stream\");\n         break;\n\n      case Z_MEM_ERROR:\n         png_ptr->zstream.msg = PNGZ_MSG_CAST(\"insufficient memory\");\n         break;\n\n      case Z_BUF_ERROR:\n         /* End of input or output; not a problem if the caller is doing\n          * incremental read or write.\n          */\n         png_ptr->zstream.msg = PNGZ_MSG_CAST(\"truncated\");\n         break;\n\n      case Z_VERSION_ERROR:\n         png_ptr->zstream.msg = PNGZ_MSG_CAST(\"unsupported zlib version\");\n         break;\n\n      case PNG_UNEXPECTED_ZLIB_RETURN:\n         /* Compile errors here mean that zlib now uses the value co-opted in\n          * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above\n          * and change pngpriv.h.  Note that this message is \"... return\",\n          * whereas the default/Z_OK one is \"... return code\".\n          */\n         png_ptr->zstream.msg = PNGZ_MSG_CAST(\"unexpected zlib return\");\n         break;\n   }\n}\n\n/* png_convert_size: a PNGAPI but no longer in png.h, so deleted\n * at libpng 1.5.5!\n */\n\n/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */\n#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */\nstatic int\npng_colorspace_check_gamma(png_const_structrp png_ptr,\n   png_colorspacerp colorspace, png_fixed_point gAMA, int from)\n   /* This is called to check a new gamma value against an existing one.  The\n    * routine returns false if the new gamma value should not be written.\n    *\n    * 'from' says where the new gamma value comes from:\n    *\n    *    0: the new gamma value is the libpng estimate for an ICC profile\n    *    1: the new gamma value comes from a gAMA chunk\n    *    2: the new gamma value comes from an sRGB chunk\n    */\n{\n   png_fixed_point gtest;\n\n   if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&\n      (png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) == 0  ||\n      png_gamma_significant(gtest) != 0))\n   {\n      /* Either this is an sRGB image, in which case the calculated gamma\n       * approximation should match, or this is an image with a profile and the\n       * value libpng calculates for the gamma of the profile does not match the\n       * value recorded in the file.  The former, sRGB, case is an error, the\n       * latter is just a warning.\n       */\n      if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)\n      {\n         png_chunk_report(png_ptr, \"gamma value does not match sRGB\",\n            PNG_CHUNK_ERROR);\n         /* Do not overwrite an sRGB value */\n         return from == 2;\n      }\n\n      else /* sRGB tag not involved */\n      {\n         png_chunk_report(png_ptr, \"gamma value does not match libpng estimate\",\n            PNG_CHUNK_WARNING);\n         return from == 1;\n      }\n   }\n\n   return 1;\n}\n\nvoid /* PRIVATE */\npng_colorspace_set_gamma(png_const_structrp png_ptr,\n   png_colorspacerp colorspace, png_fixed_point gAMA)\n{\n   /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't\n    * occur.  Since the fixed point representation is asymetrical it is\n    * possible for 1/gamma to overflow the limit of 21474 and this means the\n    * gamma value must be at least 5/100000 and hence at most 20000.0.  For\n    * safety the limits here are a little narrower.  The values are 0.00016 to\n    * 6250.0, which are truly ridiculous gamma values (and will produce\n    * displays that are all black or all white.)\n    *\n    * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk\n    * handling code, which only required the value to be >0.\n    */\n   png_const_charp errmsg;\n\n   if (gAMA < 16 || gAMA > 625000000)\n      errmsg = \"gamma value out of range\";\n\n#  ifdef PNG_READ_gAMA_SUPPORTED\n   /* Allow the application to set the gamma value more than once */\n   else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&\n      (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0)\n      errmsg = \"duplicate\";\n#  endif\n\n   /* Do nothing if the colorspace is already invalid */\n   else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)\n      return;\n\n   else\n   {\n      if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA,\n          1/*from gAMA*/) != 0)\n      {\n         /* Store this gamma value. */\n         colorspace->gamma = gAMA;\n         colorspace->flags |=\n            (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA);\n      }\n\n      /* At present if the check_gamma test fails the gamma of the colorspace is\n       * not updated however the colorspace is not invalidated.  This\n       * corresponds to the case where the existing gamma comes from an sRGB\n       * chunk or profile.  An error message has already been output.\n       */\n      return;\n   }\n\n   /* Error exit - errmsg has been set. */\n   colorspace->flags |= PNG_COLORSPACE_INVALID;\n   png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR);\n}\n\nvoid /* PRIVATE */\npng_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr)\n{\n   if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)\n   {\n      /* Everything is invalid */\n      info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB|\n         PNG_INFO_iCCP);\n\n#     ifdef PNG_COLORSPACE_SUPPORTED\n      /* Clean up the iCCP profile now if it won't be used. */\n      png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/);\n#     else\n      PNG_UNUSED(png_ptr)\n#     endif\n   }\n\n   else\n   {\n#     ifdef PNG_COLORSPACE_SUPPORTED\n      /* Leave the INFO_iCCP flag set if the pngset.c code has already set\n       * it; this allows a PNG to contain a profile which matches sRGB and\n       * yet still have that profile retrievable by the application.\n       */\n      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0)\n         info_ptr->valid |= PNG_INFO_sRGB;\n\n      else\n         info_ptr->valid &= ~PNG_INFO_sRGB;\n\n      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)\n         info_ptr->valid |= PNG_INFO_cHRM;\n\n      else\n         info_ptr->valid &= ~PNG_INFO_cHRM;\n#     endif\n\n      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0)\n         info_ptr->valid |= PNG_INFO_gAMA;\n\n      else\n         info_ptr->valid &= ~PNG_INFO_gAMA;\n   }\n}\n\n#ifdef PNG_READ_SUPPORTED\nvoid /* PRIVATE */\npng_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr)\n{\n   if (info_ptr == NULL) /* reduce code size; check here not in the caller */\n      return;\n\n   info_ptr->colorspace = png_ptr->colorspace;\n   png_colorspace_sync_info(png_ptr, info_ptr);\n}\n#endif\n#endif /* GAMMA */\n\n#ifdef PNG_COLORSPACE_SUPPORTED\n/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for\n * cHRM, as opposed to using chromaticities.  These internal APIs return\n * non-zero on a parameter error.  The X, Y and Z values are required to be\n * positive and less than 1.0.\n */\nstatic int\npng_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)\n{\n   png_int_32 d, dwhite, whiteX, whiteY;\n\n   d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z;\n   if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0)\n      return 1;\n   if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0)\n      return 1;\n   dwhite = d;\n   whiteX = XYZ->red_X;\n   whiteY = XYZ->red_Y;\n\n   d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z;\n   if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0)\n      return 1;\n   if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0)\n      return 1;\n   dwhite += d;\n   whiteX += XYZ->green_X;\n   whiteY += XYZ->green_Y;\n\n   d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z;\n   if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0)\n      return 1;\n   if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0)\n      return 1;\n   dwhite += d;\n   whiteX += XYZ->blue_X;\n   whiteY += XYZ->blue_Y;\n\n   /* The reference white is simply the sum of the end-point (X,Y,Z) vectors,\n    * thus:\n    */\n   if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0)\n      return 1;\n   if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0)\n      return 1;\n\n   return 0;\n}\n\nstatic int\npng_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)\n{\n   png_fixed_point red_inverse, green_inverse, blue_scale;\n   png_fixed_point left, right, denominator;\n\n   /* Check xy and, implicitly, z.  Note that wide gamut color spaces typically\n    * have end points with 0 tristimulus values (these are impossible end\n    * points, but they are used to cover the possible colors).  We check\n    * xy->whitey against 5, not 0, to avoid a possible integer overflow.\n    */\n   if (xy->redx   < 0 || xy->redx > PNG_FP_1) return 1;\n   if (xy->redy   < 0 || xy->redy > PNG_FP_1-xy->redx) return 1;\n   if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1;\n   if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1;\n   if (xy->bluex  < 0 || xy->bluex > PNG_FP_1) return 1;\n   if (xy->bluey  < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1;\n   if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1;\n   if (xy->whitey < 5 || xy->whitey > PNG_FP_1-xy->whitex) return 1;\n\n   /* The reverse calculation is more difficult because the original tristimulus\n    * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8\n    * derived values were recorded in the cHRM chunk;\n    * (red,green,blue,white)x(x,y).  This loses one degree of freedom and\n    * therefore an arbitrary ninth value has to be introduced to undo the\n    * original transformations.\n    *\n    * Think of the original end-points as points in (X,Y,Z) space.  The\n    * chromaticity values (c) have the property:\n    *\n    *           C\n    *   c = ---------\n    *       X + Y + Z\n    *\n    * For each c (x,y,z) from the corresponding original C (X,Y,Z).  Thus the\n    * three chromaticity values (x,y,z) for each end-point obey the\n    * relationship:\n    *\n    *   x + y + z = 1\n    *\n    * This describes the plane in (X,Y,Z) space that intersects each axis at the\n    * value 1.0; call this the chromaticity plane.  Thus the chromaticity\n    * calculation has scaled each end-point so that it is on the x+y+z=1 plane\n    * and chromaticity is the intersection of the vector from the origin to the\n    * (X,Y,Z) value with the chromaticity plane.\n    *\n    * To fully invert the chromaticity calculation we would need the three\n    * end-point scale factors, (red-scale, green-scale, blue-scale), but these\n    * were not recorded.  Instead we calculated the reference white (X,Y,Z) and\n    * recorded the chromaticity of this.  The reference white (X,Y,Z) would have\n    * given all three of the scale factors since:\n    *\n    *    color-C = color-c * color-scale\n    *    white-C = red-C + green-C + blue-C\n    *            = red-c*red-scale + green-c*green-scale + blue-c*blue-scale\n    *\n    * But cHRM records only white-x and white-y, so we have lost the white scale\n    * factor:\n    *\n    *    white-C = white-c*white-scale\n    *\n    * To handle this the inverse transformation makes an arbitrary assumption\n    * about white-scale:\n    *\n    *    Assume: white-Y = 1.0\n    *    Hence:  white-scale = 1/white-y\n    *    Or:     red-Y + green-Y + blue-Y = 1.0\n    *\n    * Notice the last statement of the assumption gives an equation in three of\n    * the nine values we want to calculate.  8 more equations come from the\n    * above routine as summarised at the top above (the chromaticity\n    * calculation):\n    *\n    *    Given: color-x = color-X / (color-X + color-Y + color-Z)\n    *    Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0\n    *\n    * This is 9 simultaneous equations in the 9 variables \"color-C\" and can be\n    * solved by Cramer's rule.  Cramer's rule requires calculating 10 9x9 matrix\n    * determinants, however this is not as bad as it seems because only 28 of\n    * the total of 90 terms in the various matrices are non-zero.  Nevertheless\n    * Cramer's rule is notoriously numerically unstable because the determinant\n    * calculation involves the difference of large, but similar, numbers.  It is\n    * difficult to be sure that the calculation is stable for real world values\n    * and it is certain that it becomes unstable where the end points are close\n    * together.\n    *\n    * So this code uses the perhaps slightly less optimal but more\n    * understandable and totally obvious approach of calculating color-scale.\n    *\n    * This algorithm depends on the precision in white-scale and that is\n    * (1/white-y), so we can immediately see that as white-y approaches 0 the\n    * accuracy inherent in the cHRM chunk drops off substantially.\n    *\n    * libpng arithmetic: a simple inversion of the above equations\n    * ------------------------------------------------------------\n    *\n    *    white_scale = 1/white-y\n    *    white-X = white-x * white-scale\n    *    white-Y = 1.0\n    *    white-Z = (1 - white-x - white-y) * white_scale\n    *\n    *    white-C = red-C + green-C + blue-C\n    *            = red-c*red-scale + green-c*green-scale + blue-c*blue-scale\n    *\n    * This gives us three equations in (red-scale,green-scale,blue-scale) where\n    * all the coefficients are now known:\n    *\n    *    red-x*red-scale + green-x*green-scale + blue-x*blue-scale\n    *       = white-x/white-y\n    *    red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1\n    *    red-z*red-scale + green-z*green-scale + blue-z*blue-scale\n    *       = (1 - white-x - white-y)/white-y\n    *\n    * In the last equation color-z is (1 - color-x - color-y) so we can add all\n    * three equations together to get an alternative third:\n    *\n    *    red-scale + green-scale + blue-scale = 1/white-y = white-scale\n    *\n    * So now we have a Cramer's rule solution where the determinants are just\n    * 3x3 - far more tractible.  Unfortunately 3x3 determinants still involve\n    * multiplication of three coefficients so we can't guarantee to avoid\n    * overflow in the libpng fixed point representation.  Using Cramer's rule in\n    * floating point is probably a good choice here, but it's not an option for\n    * fixed point.  Instead proceed to simplify the first two equations by\n    * eliminating what is likely to be the largest value, blue-scale:\n    *\n    *    blue-scale = white-scale - red-scale - green-scale\n    *\n    * Hence:\n    *\n    *    (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale =\n    *                (white-x - blue-x)*white-scale\n    *\n    *    (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale =\n    *                1 - blue-y*white-scale\n    *\n    * And now we can trivially solve for (red-scale,green-scale):\n    *\n    *    green-scale =\n    *                (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale\n    *                -----------------------------------------------------------\n    *                                  green-x - blue-x\n    *\n    *    red-scale =\n    *                1 - blue-y*white-scale - (green-y - blue-y) * green-scale\n    *                ---------------------------------------------------------\n    *                                  red-y - blue-y\n    *\n    * Hence:\n    *\n    *    red-scale =\n    *          ( (green-x - blue-x) * (white-y - blue-y) -\n    *            (green-y - blue-y) * (white-x - blue-x) ) / white-y\n    * -------------------------------------------------------------------------\n    *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)\n    *\n    *    green-scale =\n    *          ( (red-y - blue-y) * (white-x - blue-x) -\n    *            (red-x - blue-x) * (white-y - blue-y) ) / white-y\n    * -------------------------------------------------------------------------\n    *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)\n    *\n    * Accuracy:\n    * The input values have 5 decimal digits of accuracy.  The values are all in\n    * the range 0 < value < 1, so simple products are in the same range but may\n    * need up to 10 decimal digits to preserve the original precision and avoid\n    * underflow.  Because we are using a 32-bit signed representation we cannot\n    * match this; the best is a little over 9 decimal digits, less than 10.\n    *\n    * The approach used here is to preserve the maximum precision within the\n    * signed representation.  Because the red-scale calculation above uses the\n    * difference between two products of values that must be in the range -1..+1\n    * it is sufficient to divide the product by 7; ceil(100,000/32767*2).  The\n    * factor is irrelevant in the calculation because it is applied to both\n    * numerator and denominator.\n    *\n    * Note that the values of the differences of the products of the\n    * chromaticities in the above equations tend to be small, for example for\n    * the sRGB chromaticities they are:\n    *\n    * red numerator:    -0.04751\n    * green numerator:  -0.08788\n    * denominator:      -0.2241 (without white-y multiplication)\n    *\n    *  The resultant Y coefficients from the chromaticities of some widely used\n    *  color space definitions are (to 15 decimal places):\n    *\n    *  sRGB\n    *    0.212639005871510 0.715168678767756 0.072192315360734\n    *  Kodak ProPhoto\n    *    0.288071128229293 0.711843217810102 0.000085653960605\n    *  Adobe RGB\n    *    0.297344975250536 0.627363566255466 0.075291458493998\n    *  Adobe Wide Gamut RGB\n    *    0.258728243040113 0.724682314948566 0.016589442011321\n    */\n   /* By the argument, above overflow should be impossible here. The return\n    * value of 2 indicates an internal error to the caller.\n    */\n   if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0)\n      return 2;\n   if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0)\n      return 2;\n   denominator = left - right;\n\n   /* Now find the red numerator. */\n   if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)\n      return 2;\n   if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0)\n      return 2;\n\n   /* Overflow is possible here and it indicates an extreme set of PNG cHRM\n    * chunk values.  This calculation actually returns the reciprocal of the\n    * scale value because this allows us to delay the multiplication of white-y\n    * into the denominator, which tends to produce a small number.\n    */\n   if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 ||\n       red_inverse <= xy->whitey /* r+g+b scales = white scale */)\n      return 1;\n\n   /* Similarly for green_inverse: */\n   if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0)\n      return 2;\n   if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)\n      return 2;\n   if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 ||\n       green_inverse <= xy->whitey)\n      return 1;\n\n   /* And the blue scale, the checks above guarantee this can't overflow but it\n    * can still produce 0 for extreme cHRM values.\n    */\n   blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) -\n       png_reciprocal(green_inverse);\n   if (blue_scale <= 0)\n      return 1;\n\n\n   /* And fill in the png_XYZ: */\n   if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0)\n      return 1;\n   if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0)\n      return 1;\n   if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1,\n       red_inverse) == 0)\n      return 1;\n\n   if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0)\n      return 1;\n   if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0)\n      return 1;\n   if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1,\n       green_inverse) == 0)\n      return 1;\n\n   if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0)\n      return 1;\n   if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0)\n      return 1;\n   if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale,\n       PNG_FP_1) == 0)\n      return 1;\n\n   return 0; /*success*/\n}\n\nstatic int\npng_XYZ_normalize(png_XYZ *XYZ)\n{\n   png_int_32 Y;\n\n   if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 ||\n      XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 ||\n      XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0)\n      return 1;\n\n   /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1.\n    * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore\n    * relying on addition of two positive values producing a negative one is not\n    * safe.\n    */\n   Y = XYZ->red_Y;\n   if (0x7fffffff - Y < XYZ->green_X)\n      return 1;\n   Y += XYZ->green_Y;\n   if (0x7fffffff - Y < XYZ->blue_X)\n      return 1;\n   Y += XYZ->blue_Y;\n\n   if (Y != PNG_FP_1)\n   {\n      if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0)\n         return 1;\n      if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0)\n         return 1;\n      if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0)\n         return 1;\n\n      if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0)\n         return 1;\n      if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0)\n         return 1;\n      if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0)\n         return 1;\n\n      if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0)\n         return 1;\n      if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0)\n         return 1;\n      if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0)\n         return 1;\n   }\n\n   return 0;\n}\n\nstatic int\npng_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta)\n{\n   /* Allow an error of +/-0.01 (absolute value) on each chromaticity */\n   if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) ||\n       PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) ||\n       PNG_OUT_OF_RANGE(xy1->redx,   xy2->redx,  delta) ||\n       PNG_OUT_OF_RANGE(xy1->redy,   xy2->redy,  delta) ||\n       PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) ||\n       PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) ||\n       PNG_OUT_OF_RANGE(xy1->bluex,  xy2->bluex, delta) ||\n       PNG_OUT_OF_RANGE(xy1->bluey,  xy2->bluey, delta))\n      return 0;\n   return 1;\n}\n\n/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM\n * chunk chromaticities.  Earlier checks used to simply look for the overflow\n * condition (where the determinant of the matrix to solve for XYZ ends up zero\n * because the chromaticity values are not all distinct.)  Despite this it is\n * theoretically possible to produce chromaticities that are apparently valid\n * but that rapidly degrade to invalid, potentially crashing, sets because of\n * arithmetic inaccuracies when calculations are performed on them.  The new\n * check is to round-trip xy -> XYZ -> xy and then check that the result is\n * within a small percentage of the original.\n */\nstatic int\npng_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy)\n{\n   int result;\n   png_xy xy_test;\n\n   /* As a side-effect this routine also returns the XYZ endpoints. */\n   result = png_XYZ_from_xy(XYZ, xy);\n   if (result != 0)\n      return result;\n\n   result = png_xy_from_XYZ(&xy_test, XYZ);\n   if (result != 0)\n      return result;\n\n   if (png_colorspace_endpoints_match(xy, &xy_test,\n       5/*actually, the math is pretty accurate*/) != 0)\n      return 0;\n\n   /* Too much slip */\n   return 1;\n}\n\n/* This is the check going the other way.  The XYZ is modified to normalize it\n * (another side-effect) and the xy chromaticities are returned.\n */\nstatic int\npng_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ)\n{\n   int result;\n   png_XYZ XYZtemp;\n\n   result = png_XYZ_normalize(XYZ);\n   if (result != 0)\n      return result;\n\n   result = png_xy_from_XYZ(xy, XYZ);\n   if (result != 0)\n      return result;\n\n   XYZtemp = *XYZ;\n   return png_colorspace_check_xy(&XYZtemp, xy);\n}\n\n/* Used to check for an endpoint match against sRGB */\nstatic const png_xy sRGB_xy = /* From ITU-R BT.709-3 */\n{\n   /* color      x       y */\n   /* red   */ 64000, 33000,\n   /* green */ 30000, 60000,\n   /* blue  */ 15000,  6000,\n   /* white */ 31270, 32900\n};\n\nstatic int\npng_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,\n   png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,\n   int preferred)\n{\n   if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)\n      return 0;\n\n   /* The consistency check is performed on the chromaticities; this factors out\n    * variations because of the normalization (or not) of the end point Y\n    * values.\n    */\n   if (preferred < 2 &&\n       (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)\n   {\n      /* The end points must be reasonably close to any we already have.  The\n       * following allows an error of up to +/-.001\n       */\n      if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy,\n          100) == 0)\n      {\n         colorspace->flags |= PNG_COLORSPACE_INVALID;\n         png_benign_error(png_ptr, \"inconsistent chromaticities\");\n         return 0; /* failed */\n      }\n\n      /* Only overwrite with preferred values */\n      if (preferred == 0)\n         return 1; /* ok, but no change */\n   }\n\n   colorspace->end_points_xy = *xy;\n   colorspace->end_points_XYZ = *XYZ;\n   colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS;\n\n   /* The end points are normally quoted to two decimal digits, so allow +/-0.01\n    * on this test.\n    */\n   if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0)\n      colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB;\n\n   else\n      colorspace->flags &= PNG_COLORSPACE_CANCEL(\n         PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);\n\n   return 2; /* ok and changed */\n}\n\nint /* PRIVATE */\npng_colorspace_set_chromaticities(png_const_structrp png_ptr,\n   png_colorspacerp colorspace, const png_xy *xy, int preferred)\n{\n   /* We must check the end points to ensure they are reasonable - in the past\n    * color management systems have crashed as a result of getting bogus\n    * colorant values, while this isn't the fault of libpng it is the\n    * responsibility of libpng because PNG carries the bomb and libpng is in a\n    * position to protect against it.\n    */\n   png_XYZ XYZ;\n\n   switch (png_colorspace_check_xy(&XYZ, xy))\n   {\n      case 0: /* success */\n         return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,\n            preferred);\n\n      case 1:\n         /* We can't invert the chromaticities so we can't produce value XYZ\n          * values.  Likely as not a color management system will fail too.\n          */\n         colorspace->flags |= PNG_COLORSPACE_INVALID;\n         png_benign_error(png_ptr, \"invalid chromaticities\");\n         break;\n\n      default:\n         /* libpng is broken; this should be a warning but if it happens we\n          * want error reports so for the moment it is an error.\n          */\n         colorspace->flags |= PNG_COLORSPACE_INVALID;\n         png_error(png_ptr, \"internal error checking chromaticities\");\n   }\n\n   return 0; /* failed */\n}\n\nint /* PRIVATE */\npng_colorspace_set_endpoints(png_const_structrp png_ptr,\n   png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)\n{\n   png_XYZ XYZ = *XYZ_in;\n   png_xy xy;\n\n   switch (png_colorspace_check_XYZ(&xy, &XYZ))\n   {\n      case 0:\n         return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,\n            preferred);\n\n      case 1:\n         /* End points are invalid. */\n         colorspace->flags |= PNG_COLORSPACE_INVALID;\n         png_benign_error(png_ptr, \"invalid end points\");\n         break;\n\n      default:\n         colorspace->flags |= PNG_COLORSPACE_INVALID;\n         png_error(png_ptr, \"internal error checking chromaticities\");\n   }\n\n   return 0; /* failed */\n}\n\n#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED)\n/* Error message generation */\nstatic char\npng_icc_tag_char(png_uint_32 byte)\n{\n   byte &= 0xff;\n   if (byte >= 32 && byte <= 126)\n      return (char)byte;\n   else\n      return '?';\n}\n\nstatic void\npng_icc_tag_name(char *name, png_uint_32 tag)\n{\n   name[0] = '\\'';\n   name[1] = png_icc_tag_char(tag >> 24);\n   name[2] = png_icc_tag_char(tag >> 16);\n   name[3] = png_icc_tag_char(tag >>  8);\n   name[4] = png_icc_tag_char(tag      );\n   name[5] = '\\'';\n}\n\nstatic int\nis_ICC_signature_char(png_alloc_size_t it)\n{\n   return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) ||\n      (it >= 97 && it <= 122);\n}\n\nstatic int\nis_ICC_signature(png_alloc_size_t it)\n{\n   return is_ICC_signature_char(it >> 24) /* checks all the top bits */ &&\n      is_ICC_signature_char((it >> 16) & 0xff) &&\n      is_ICC_signature_char((it >> 8) & 0xff) &&\n      is_ICC_signature_char(it & 0xff);\n}\n\nstatic int\npng_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,\n   png_const_charp name, png_alloc_size_t value, png_const_charp reason)\n{\n   size_t pos;\n   char message[196]; /* see below for calculation */\n\n   if (colorspace != NULL)\n      colorspace->flags |= PNG_COLORSPACE_INVALID;\n\n   pos = png_safecat(message, (sizeof message), 0, \"profile '\"); /* 9 chars */\n   pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */\n   pos = png_safecat(message, (sizeof message), pos, \"': \"); /* +2 = 90 */\n   if (is_ICC_signature(value) != 0)\n   {\n      /* So 'value' is at most 4 bytes and the following cast is safe */\n      png_icc_tag_name(message+pos, (png_uint_32)value);\n      pos += 6; /* total +8; less than the else clause */\n      message[pos++] = ':';\n      message[pos++] = ' ';\n   }\n#  ifdef PNG_WARNINGS_SUPPORTED\n   else\n      {\n         char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/\n\n         pos = png_safecat(message, (sizeof message), pos,\n            png_format_number(number, number+(sizeof number),\n               PNG_NUMBER_FORMAT_x, value));\n         pos = png_safecat(message, (sizeof message), pos, \"h: \"); /*+2 = 116*/\n      }\n#  endif\n   /* The 'reason' is an arbitrary message, allow +79 maximum 195 */\n   pos = png_safecat(message, (sizeof message), pos, reason);\n   PNG_UNUSED(pos)\n\n   /* This is recoverable, but make it unconditionally an app_error on write to\n    * avoid writing invalid ICC profiles into PNG files (i.e., we handle them\n    * on read, with a warning, but on write unless the app turns off\n    * application errors the PNG won't be written.)\n    */\n   png_chunk_report(png_ptr, message,\n      (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);\n\n   return 0;\n}\n#endif /* sRGB || iCCP */\n\n#ifdef PNG_sRGB_SUPPORTED\nint /* PRIVATE */\npng_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,\n   int intent)\n{\n   /* sRGB sets known gamma, end points and (from the chunk) intent. */\n   /* IMPORTANT: these are not necessarily the values found in an ICC profile\n    * because ICC profiles store values adapted to a D50 environment; it is\n    * expected that the ICC profile mediaWhitePointTag will be D50; see the\n    * checks and code elsewhere to understand this better.\n    *\n    * These XYZ values, which are accurate to 5dp, produce rgb to gray\n    * coefficients of (6968,23435,2366), which are reduced (because they add up\n    * to 32769 not 32768) to (6968,23434,2366).  These are the values that\n    * libpng has traditionally used (and are the best values given the 15bit\n    * algorithm used by the rgb to gray code.)\n    */\n   static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */\n   {\n      /* color      X      Y      Z */\n      /* red   */ 41239, 21264,  1933,\n      /* green */ 35758, 71517, 11919,\n      /* blue  */ 18048,  7219, 95053\n   };\n\n   /* Do nothing if the colorspace is already invalidated. */\n   if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)\n      return 0;\n\n   /* Check the intent, then check for existing settings.  It is valid for the\n    * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must\n    * be consistent with the correct values.  If, however, this function is\n    * called below because an iCCP chunk matches sRGB then it is quite\n    * conceivable that an older app recorded incorrect gAMA and cHRM because of\n    * an incorrect calculation based on the values in the profile - this does\n    * *not* invalidate the profile (though it still produces an error, which can\n    * be ignored.)\n    */\n   if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)\n      return png_icc_profile_error(png_ptr, colorspace, \"sRGB\",\n         (unsigned)intent, \"invalid sRGB rendering intent\");\n\n   if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&\n      colorspace->rendering_intent != intent)\n      return png_icc_profile_error(png_ptr, colorspace, \"sRGB\",\n         (unsigned)intent, \"inconsistent rendering intents\");\n\n   if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)\n   {\n      png_benign_error(png_ptr, \"duplicate sRGB information ignored\");\n      return 0;\n   }\n\n   /* If the standard sRGB cHRM chunk does not match the one from the PNG file\n    * warn but overwrite the value with the correct one.\n    */\n   if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&\n      !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,\n         100))\n      png_chunk_report(png_ptr, \"cHRM chunk does not match sRGB\",\n         PNG_CHUNK_ERROR);\n\n   /* This check is just done for the error reporting - the routine always\n    * returns true when the 'from' argument corresponds to sRGB (2).\n    */\n   (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,\n      2/*from sRGB*/);\n\n   /* intent: bugs in GCC force 'int' to be used as the parameter type. */\n   colorspace->rendering_intent = (png_uint_16)intent;\n   colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT;\n\n   /* endpoints */\n   colorspace->end_points_xy = sRGB_xy;\n   colorspace->end_points_XYZ = sRGB_XYZ;\n   colorspace->flags |=\n      (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);\n\n   /* gamma */\n   colorspace->gamma = PNG_GAMMA_sRGB_INVERSE;\n   colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA;\n\n   /* Finally record that we have an sRGB profile */\n   colorspace->flags |=\n      (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB);\n\n   return 1; /* set */\n}\n#endif /* sRGB */\n\n#ifdef PNG_iCCP_SUPPORTED\n/* Encoded value of D50 as an ICC XYZNumber.  From the ICC 2010 spec the value\n * is XYZ(0.9642,1.0,0.8249), which scales to:\n *\n *    (63189.8112, 65536, 54060.6464)\n */\nstatic const png_byte D50_nCIEXYZ[12] =\n   { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };\n\nint /* PRIVATE */\npng_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,\n   png_const_charp name, png_uint_32 profile_length)\n{\n   if (profile_length < 132)\n      return png_icc_profile_error(png_ptr, colorspace, name, profile_length,\n         \"too short\");\n\n   return 1;\n}\n\nint /* PRIVATE */\npng_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,\n   png_const_charp name, png_uint_32 profile_length,\n   png_const_bytep profile/* first 132 bytes only */, int color_type)\n{\n   png_uint_32 temp;\n\n   /* Length check; this cannot be ignored in this code because profile_length\n    * is used later to check the tag table, so even if the profile seems over\n    * long profile_length from the caller must be correct.  The caller can fix\n    * this up on read or write by just passing in the profile header length.\n    */\n   temp = png_get_uint_32(profile);\n   if (temp != profile_length)\n      return png_icc_profile_error(png_ptr, colorspace, name, temp,\n         \"length does not match profile\");\n\n   temp = (png_uint_32) (*(profile+8));\n   if (temp > 3 && (profile_length & 3))\n      return png_icc_profile_error(png_ptr, colorspace, name, profile_length,\n         \"invalid length\");\n\n   temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */\n   if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */\n      profile_length < 132+12*temp) /* truncated tag table */\n      return png_icc_profile_error(png_ptr, colorspace, name, temp,\n         \"tag count too large\");\n\n   /* The 'intent' must be valid or we can't store it, ICC limits the intent to\n    * 16 bits.\n    */\n   temp = png_get_uint_32(profile+64);\n   if (temp >= 0xffff) /* The ICC limit */\n      return png_icc_profile_error(png_ptr, colorspace, name, temp,\n         \"invalid rendering intent\");\n\n   /* This is just a warning because the profile may be valid in future\n    * versions.\n    */\n   if (temp >= PNG_sRGB_INTENT_LAST)\n      (void)png_icc_profile_error(png_ptr, NULL, name, temp,\n         \"intent outside defined range\");\n\n   /* At this point the tag table can't be checked because it hasn't necessarily\n    * been loaded; however, various header fields can be checked.  These checks\n    * are for values permitted by the PNG spec in an ICC profile; the PNG spec\n    * restricts the profiles that can be passed in an iCCP chunk (they must be\n    * appropriate to processing PNG data!)\n    */\n\n   /* Data checks (could be skipped).  These checks must be independent of the\n    * version number; however, the version number doesn't accomodate changes in\n    * the header fields (just the known tags and the interpretation of the\n    * data.)\n    */\n   temp = png_get_uint_32(profile+36); /* signature 'ascp' */\n   if (temp != 0x61637370)\n      return png_icc_profile_error(png_ptr, colorspace, name, temp,\n         \"invalid signature\");\n\n   /* Currently the PCS illuminant/adopted white point (the computational\n    * white point) are required to be D50,\n    * however the profile contains a record of the illuminant so perhaps ICC\n    * expects to be able to change this in the future (despite the rationale in\n    * the introduction for using a fixed PCS adopted white.)  Consequently the\n    * following is just a warning.\n    */\n   if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)\n      (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,\n         \"PCS illuminant is not D50\");\n\n   /* The PNG spec requires this:\n    * \"If the iCCP chunk is present, the image samples conform to the colour\n    * space represented by the embedded ICC profile as defined by the\n    * International Color Consortium [ICC]. The colour space of the ICC profile\n    * shall be an RGB colour space for colour images (PNG colour types 2, 3, and\n    * 6), or a greyscale colour space for greyscale images (PNG colour types 0\n    * and 4).\"\n    *\n    * This checking code ensures the embedded profile (on either read or write)\n    * conforms to the specification requirements.  Notice that an ICC 'gray'\n    * color-space profile contains the information to transform the monochrome\n    * data to XYZ or L*a*b (according to which PCS the profile uses) and this\n    * should be used in preference to the standard libpng K channel replication\n    * into R, G and B channels.\n    *\n    * Previously it was suggested that an RGB profile on grayscale data could be\n    * handled.  However it it is clear that using an RGB profile in this context\n    * must be an error - there is no specification of what it means.  Thus it is\n    * almost certainly more correct to ignore the profile.\n    */\n   temp = png_get_uint_32(profile+16); /* data colour space field */\n   switch (temp)\n   {\n      case 0x52474220: /* 'RGB ' */\n         if ((color_type & PNG_COLOR_MASK_COLOR) == 0)\n            return png_icc_profile_error(png_ptr, colorspace, name, temp,\n               \"RGB color space not permitted on grayscale PNG\");\n         break;\n\n      case 0x47524159: /* 'GRAY' */\n         if ((color_type & PNG_COLOR_MASK_COLOR) != 0)\n            return png_icc_profile_error(png_ptr, colorspace, name, temp,\n               \"Gray color space not permitted on RGB PNG\");\n         break;\n\n      default:\n         return png_icc_profile_error(png_ptr, colorspace, name, temp,\n            \"invalid ICC profile color space\");\n   }\n\n   /* It is up to the application to check that the profile class matches the\n    * application requirements; the spec provides no guidance, but it's pretty\n    * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer\n    * ('prtr') or 'spac' (for generic color spaces).  Issue a warning in these\n    * cases.  Issue an error for device link or abstract profiles - these don't\n    * contain the records necessary to transform the color-space to anything\n    * other than the target device (and not even that for an abstract profile).\n    * Profiles of these classes may not be embedded in images.\n    */\n   temp = png_get_uint_32(profile+12); /* profile/device class */\n   switch (temp)\n   {\n      case 0x73636e72: /* 'scnr' */\n      case 0x6d6e7472: /* 'mntr' */\n      case 0x70727472: /* 'prtr' */\n      case 0x73706163: /* 'spac' */\n         /* All supported */\n         break;\n\n      case 0x61627374: /* 'abst' */\n         /* May not be embedded in an image */\n         return png_icc_profile_error(png_ptr, colorspace, name, temp,\n            \"invalid embedded Abstract ICC profile\");\n\n      case 0x6c696e6b: /* 'link' */\n         /* DeviceLink profiles cannot be interpreted in a non-device specific\n          * fashion, if an app uses the AToB0Tag in the profile the results are\n          * undefined unless the result is sent to the intended device,\n          * therefore a DeviceLink profile should not be found embedded in a\n          * PNG.\n          */\n         return png_icc_profile_error(png_ptr, colorspace, name, temp,\n            \"unexpected DeviceLink ICC profile class\");\n\n      case 0x6e6d636c: /* 'nmcl' */\n         /* A NamedColor profile is also device specific, however it doesn't\n          * contain an AToB0 tag that is open to misinterpretation.  Almost\n          * certainly it will fail the tests below.\n          */\n         (void)png_icc_profile_error(png_ptr, NULL, name, temp,\n            \"unexpected NamedColor ICC profile class\");\n         break;\n\n      default:\n         /* To allow for future enhancements to the profile accept unrecognized\n          * profile classes with a warning, these then hit the test below on the\n          * tag content to ensure they are backward compatible with one of the\n          * understood profiles.\n          */\n         (void)png_icc_profile_error(png_ptr, NULL, name, temp,\n            \"unrecognized ICC profile class\");\n         break;\n   }\n\n   /* For any profile other than a device link one the PCS must be encoded\n    * either in XYZ or Lab.\n    */\n   temp = png_get_uint_32(profile+20);\n   switch (temp)\n   {\n      case 0x58595a20: /* 'XYZ ' */\n      case 0x4c616220: /* 'Lab ' */\n         break;\n\n      default:\n         return png_icc_profile_error(png_ptr, colorspace, name, temp,\n            \"unexpected ICC PCS encoding\");\n   }\n\n   return 1;\n}\n\nint /* PRIVATE */\npng_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,\n   png_const_charp name, png_uint_32 profile_length,\n   png_const_bytep profile /* header plus whole tag table */)\n{\n   png_uint_32 tag_count = png_get_uint_32(profile+128);\n   png_uint_32 itag;\n   png_const_bytep tag = profile+132; /* The first tag */\n\n   /* First scan all the tags in the table and add bits to the icc_info value\n    * (temporarily in 'tags').\n    */\n   for (itag=0; itag < tag_count; ++itag, tag += 12)\n   {\n      png_uint_32 tag_id = png_get_uint_32(tag+0);\n      png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */\n      png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */\n\n      /* The ICC specification does not exclude zero length tags, therefore the\n       * start might actually be anywhere if there is no data, but this would be\n       * a clear abuse of the intent of the standard so the start is checked for\n       * being in range.  All defined tag types have an 8 byte header - a 4 byte\n       * type signature then 0.\n       */\n      if ((tag_start & 3) != 0)\n      {\n         /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is\n          * only a warning here because libpng does not care about the\n          * alignment.\n          */\n         (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,\n            \"ICC profile tag start not a multiple of 4\");\n      }\n\n      /* This is a hard error; potentially it can cause read outside the\n       * profile.\n       */\n      if (tag_start > profile_length || tag_length > profile_length - tag_start)\n         return png_icc_profile_error(png_ptr, colorspace, name, tag_id,\n            \"ICC profile tag outside profile\");\n   }\n\n   return 1; /* success, maybe with warnings */\n}\n\n#ifdef PNG_sRGB_SUPPORTED\n#if PNG_sRGB_PROFILE_CHECKS >= 0\n/* Information about the known ICC sRGB profiles */\nstatic const struct\n{\n   png_uint_32 adler, crc, length;\n   png_uint_32 md5[4];\n   png_byte    have_md5;\n   png_byte    is_broken;\n   png_uint_16 intent;\n\n#  define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0)\n#  define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\\\n      { adler, crc, length, md5, broke, intent },\n\n} png_sRGB_checks[] =\n{\n   /* This data comes from contrib/tools/checksum-icc run on downloads of\n    * all four ICC sRGB profiles from www.color.org.\n    */\n   /* adler32, crc32, MD5[4], intent, date, length, file-name */\n   PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,\n      PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,\n      \"2009/03/27 21:36:31\", 3048, \"sRGB_IEC61966-2-1_black_scaled.icc\")\n\n   /* ICC sRGB v2 perceptual no black-compensation: */\n   PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,\n      PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,\n      \"2009/03/27 21:37:45\", 3052, \"sRGB_IEC61966-2-1_no_black_scaling.icc\")\n\n   PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,\n      PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,\n      \"2009/08/10 17:28:01\", 60988, \"sRGB_v4_ICC_preference_displayclass.icc\")\n\n   /* ICC sRGB v4 perceptual */\n   PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,\n      PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,\n      \"2007/07/25 00:05:37\", 60960, \"sRGB_v4_ICC_preference.icc\")\n\n   /* The following profiles have no known MD5 checksum. If there is a match\n    * on the (empty) MD5 the other fields are used to attempt a match and\n    * a warning is produced.  The first two of these profiles have a 'cprt' tag\n    * which suggests that they were also made by Hewlett Packard.\n    */\n   PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,\n      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,\n      \"2004/07/21 18:57:42\", 3024, \"sRGB_IEC61966-2-1_noBPC.icc\")\n\n   /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not\n    * match the D50 PCS illuminant in the header (it is in fact the D65 values,\n    * so the white point is recorded as the un-adapted value.)  The profiles\n    * below only differ in one byte - the intent - and are basically the same as\n    * the previous profile except for the mediaWhitePointTag error and a missing\n    * chromaticAdaptationTag.\n    */\n   PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,\n      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,\n      \"1998/02/09 06:49:00\", 3144, \"HP-Microsoft sRGB v2 perceptual\")\n\n   PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,\n      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,\n      \"1998/02/09 06:49:00\", 3144, \"HP-Microsoft sRGB v2 media-relative\")\n};\n\nstatic int\npng_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,\n   png_const_bytep profile, uLong adler)\n{\n   /* The quick check is to verify just the MD5 signature and trust the\n    * rest of the data.  Because the profile has already been verified for\n    * correctness this is safe.  png_colorspace_set_sRGB will check the 'intent'\n    * field too, so if the profile has been edited with an intent not defined\n    * by sRGB (but maybe defined by a later ICC specification) the read of\n    * the profile will fail at that point.\n    */\n\n   png_uint_32 length = 0;\n   png_uint_32 intent = 0x10000; /* invalid */\n#if PNG_sRGB_PROFILE_CHECKS > 1\n   uLong crc = 0; /* the value for 0 length data */\n#endif\n   unsigned int i;\n\n#ifdef PNG_SET_OPTION_SUPPORTED\n   /* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to \"on\" */\n   if (((png_ptr->options >> PNG_SKIP_sRGB_CHECK_PROFILE) & 3) ==\n               PNG_OPTION_ON)\n      return 0;\n#endif\n\n   for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i)\n   {\n      if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] &&\n         png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] &&\n         png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] &&\n         png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3])\n      {\n         /* This may be one of the old HP profiles without an MD5, in that\n          * case we can only use the length and Adler32 (note that these\n          * are not used by default if there is an MD5!)\n          */\n#        if PNG_sRGB_PROFILE_CHECKS == 0\n            if (png_sRGB_checks[i].have_md5 != 0)\n               return 1+png_sRGB_checks[i].is_broken;\n#        endif\n\n         /* Profile is unsigned or more checks have been configured in. */\n         if (length == 0)\n         {\n            length = png_get_uint_32(profile);\n            intent = png_get_uint_32(profile+64);\n         }\n\n         /* Length *and* intent must match */\n         if (length == (png_uint_32) png_sRGB_checks[i].length &&\n            intent == (png_uint_32) png_sRGB_checks[i].intent)\n         {\n            /* Now calculate the adler32 if not done already. */\n            if (adler == 0)\n            {\n               adler = adler32(0, NULL, 0);\n               adler = adler32(adler, profile, length);\n            }\n\n            if (adler == png_sRGB_checks[i].adler)\n            {\n               /* These basic checks suggest that the data has not been\n                * modified, but if the check level is more than 1 perform\n                * our own crc32 checksum on the data.\n                */\n#              if PNG_sRGB_PROFILE_CHECKS > 1\n                  if (crc == 0)\n                  {\n                     crc = crc32(0, NULL, 0);\n                     crc = crc32(crc, profile, length);\n                  }\n\n                  /* So this check must pass for the 'return' below to happen.\n                   */\n                  if (crc == png_sRGB_checks[i].crc)\n#              endif\n               {\n                  if (png_sRGB_checks[i].is_broken != 0)\n                  {\n                     /* These profiles are known to have bad data that may cause\n                      * problems if they are used, therefore attempt to\n                      * discourage their use, skip the 'have_md5' warning below,\n                      * which is made irrelevant by this error.\n                      */\n                     png_chunk_report(png_ptr, \"known incorrect sRGB profile\",\n                        PNG_CHUNK_ERROR);\n                  }\n\n                  /* Warn that this being done; this isn't even an error since\n                   * the profile is perfectly valid, but it would be nice if\n                   * people used the up-to-date ones.\n                   */\n                  else if (png_sRGB_checks[i].have_md5 == 0)\n                  {\n                     png_chunk_report(png_ptr,\n                        \"out-of-date sRGB profile with no signature\",\n                        PNG_CHUNK_WARNING);\n                  }\n\n                  return 1+png_sRGB_checks[i].is_broken;\n               }\n            }\n\n# if PNG_sRGB_PROFILE_CHECKS > 0\n         /* The signature matched, but the profile had been changed in some\n          * way.  This probably indicates a data error or uninformed hacking.\n          * Fall through to \"no match\".\n          */\n         png_chunk_report(png_ptr,\n             \"Not recognizing known sRGB profile that has been edited\",\n             PNG_CHUNK_WARNING);\n         break;\n# endif\n         }\n      }\n   }\n\n   return 0; /* no match */\n}\n#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */\n\nvoid /* PRIVATE */\npng_icc_set_sRGB(png_const_structrp png_ptr,\n   png_colorspacerp colorspace, png_const_bytep profile, uLong adler)\n{\n   /* Is this profile one of the known ICC sRGB profiles?  If it is, just set\n    * the sRGB information.\n    */\n#if PNG_sRGB_PROFILE_CHECKS >= 0\n   if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0)\n#endif\n      (void)png_colorspace_set_sRGB(png_ptr, colorspace,\n         (int)/*already checked*/png_get_uint_32(profile+64));\n}\n#endif /* sRGB */\n\nint /* PRIVATE */\npng_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,\n   png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,\n   int color_type)\n{\n   if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)\n      return 0;\n\n   if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&\n       png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,\n          color_type) != 0 &&\n       png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,\n          profile) != 0)\n   {\n#     ifdef PNG_sRGB_SUPPORTED\n         /* If no sRGB support, don't try storing sRGB information */\n         png_icc_set_sRGB(png_ptr, colorspace, profile, 0);\n#     endif\n      return 1;\n   }\n\n   /* Failure case */\n   return 0;\n}\n#endif /* iCCP */\n\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\nvoid /* PRIVATE */\npng_colorspace_set_rgb_coefficients(png_structrp png_ptr)\n{\n   /* Set the rgb_to_gray coefficients from the colorspace. */\n   if (png_ptr->rgb_to_gray_coefficients_set == 0 &&\n      (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)\n   {\n      /* png_set_background has not been called, get the coefficients from the Y\n       * values of the colorspace colorants.\n       */\n      png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y;\n      png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y;\n      png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y;\n      png_fixed_point total = r+g+b;\n\n      if (total > 0 &&\n         r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 &&\n         g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 &&\n         b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 &&\n         r+g+b <= 32769)\n      {\n         /* We allow 0 coefficients here.  r+g+b may be 32769 if two or\n          * all of the coefficients were rounded up.  Handle this by\n          * reducing the *largest* coefficient by 1; this matches the\n          * approach used for the default coefficients in pngrtran.c\n          */\n         int add = 0;\n\n         if (r+g+b > 32768)\n            add = -1;\n         else if (r+g+b < 32768)\n            add = 1;\n\n         if (add != 0)\n         {\n            if (g >= r && g >= b)\n               g += add;\n            else if (r >= g && r >= b)\n               r += add;\n            else\n               b += add;\n         }\n\n         /* Check for an internal error. */\n         if (r+g+b != 32768)\n            png_error(png_ptr,\n               \"internal error handling cHRM coefficients\");\n\n         else\n         {\n            png_ptr->rgb_to_gray_red_coeff   = (png_uint_16)r;\n            png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;\n         }\n      }\n\n      /* This is a png_error at present even though it could be ignored -\n       * it should never happen, but it is important that if it does, the\n       * bug is fixed.\n       */\n      else\n         png_error(png_ptr, \"internal error handling cHRM->XYZ\");\n   }\n}\n#endif /* READ_RGB_TO_GRAY */\n\n#endif /* COLORSPACE */\n\n#ifdef __GNUC__\n/* This exists solely to work round a warning from GNU C. */\nstatic int /* PRIVATE */\npng_gt(size_t a, size_t b)\n{\n    return a > b;\n}\n#else\n#   define png_gt(a,b) ((a) > (b))\n#endif\n\nvoid /* PRIVATE */\npng_check_IHDR(png_const_structrp png_ptr,\n   png_uint_32 width, png_uint_32 height, int bit_depth,\n   int color_type, int interlace_type, int compression_type,\n   int filter_type)\n{\n   int error = 0;\n\n   /* Check for width and height valid values */\n   if (width == 0)\n   {\n      png_warning(png_ptr, \"Image width is zero in IHDR\");\n      error = 1;\n   }\n\n   if (width > PNG_UINT_31_MAX)\n   {\n      png_warning(png_ptr, \"Invalid image width in IHDR\");\n      error = 1;\n   }\n\n   if (png_gt(((width + 7) & (~7)),\n       ((PNG_SIZE_MAX\n           - 48        /* big_row_buf hack */\n           - 1)        /* filter byte */\n           / 8)        /* 8-byte RGBA pixels */\n           - 1))       /* extra max_pixel_depth pad */\n   {\n      /* The size of the row must be within the limits of this architecture.\n       * Because the read code can perform arbitrary transformations the\n       * maximum size is checked here.  Because the code in png_read_start_row\n       * adds extra space \"for safety's sake\" in several places a conservative\n       * limit is used here.\n       *\n       * NOTE: it would be far better to check the size that is actually used,\n       * but the effect in the real world is minor and the changes are more\n       * extensive, therefore much more dangerous and much more difficult to\n       * write in a way that avoids compiler warnings.\n       */\n      png_warning(png_ptr, \"Image width is too large for this architecture\");\n      error = 1;\n   }\n\n#ifdef PNG_SET_USER_LIMITS_SUPPORTED\n   if (width > png_ptr->user_width_max)\n#else\n   if (width > PNG_USER_WIDTH_MAX)\n#endif\n   {\n      png_warning(png_ptr, \"Image width exceeds user limit in IHDR\");\n      error = 1;\n   }\n\n   if (height == 0)\n   {\n      png_warning(png_ptr, \"Image height is zero in IHDR\");\n      error = 1;\n   }\n\n   if (height > PNG_UINT_31_MAX)\n   {\n      png_warning(png_ptr, \"Invalid image height in IHDR\");\n      error = 1;\n   }\n\n#ifdef PNG_SET_USER_LIMITS_SUPPORTED\n   if (height > png_ptr->user_height_max)\n#else\n   if (height > PNG_USER_HEIGHT_MAX)\n#endif\n   {\n      png_warning(png_ptr, \"Image height exceeds user limit in IHDR\");\n      error = 1;\n   }\n\n   /* Check other values */\n   if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&\n       bit_depth != 8 && bit_depth != 16)\n   {\n      png_warning(png_ptr, \"Invalid bit depth in IHDR\");\n      error = 1;\n   }\n\n   if (color_type < 0 || color_type == 1 ||\n       color_type == 5 || color_type > 6)\n   {\n      png_warning(png_ptr, \"Invalid color type in IHDR\");\n      error = 1;\n   }\n\n   if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||\n       ((color_type == PNG_COLOR_TYPE_RGB ||\n         color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||\n         color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))\n   {\n      png_warning(png_ptr, \"Invalid color type/bit depth combination in IHDR\");\n      error = 1;\n   }\n\n   if (interlace_type >= PNG_INTERLACE_LAST)\n   {\n      png_warning(png_ptr, \"Unknown interlace method in IHDR\");\n      error = 1;\n   }\n\n   if (compression_type != PNG_COMPRESSION_TYPE_BASE)\n   {\n      png_warning(png_ptr, \"Unknown compression method in IHDR\");\n      error = 1;\n   }\n\n#ifdef PNG_MNG_FEATURES_SUPPORTED\n   /* Accept filter_method 64 (intrapixel differencing) only if\n    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and\n    * 2. Libpng did not read a PNG signature (this filter_method is only\n    *    used in PNG datastreams that are embedded in MNG datastreams) and\n    * 3. The application called png_permit_mng_features with a mask that\n    *    included PNG_FLAG_MNG_FILTER_64 and\n    * 4. The filter_method is 64 and\n    * 5. The color_type is RGB or RGBA\n    */\n   if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 &&\n       png_ptr->mng_features_permitted != 0)\n      png_warning(png_ptr, \"MNG features are not allowed in a PNG datastream\");\n\n   if (filter_type != PNG_FILTER_TYPE_BASE)\n   {\n      if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&\n          (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&\n          ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&\n          (color_type == PNG_COLOR_TYPE_RGB ||\n          color_type == PNG_COLOR_TYPE_RGB_ALPHA)))\n      {\n         png_warning(png_ptr, \"Unknown filter method in IHDR\");\n         error = 1;\n      }\n\n      if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0)\n      {\n         png_warning(png_ptr, \"Invalid filter method in IHDR\");\n         error = 1;\n      }\n   }\n\n#else\n   if (filter_type != PNG_FILTER_TYPE_BASE)\n   {\n      png_warning(png_ptr, \"Unknown filter method in IHDR\");\n      error = 1;\n   }\n#endif\n\n   if (error == 1)\n      png_error(png_ptr, \"Invalid IHDR data\");\n}\n\n#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)\n/* ASCII to fp functions */\n/* Check an ASCII formated floating point value, see the more detailed\n * comments in pngpriv.h\n */\n/* The following is used internally to preserve the sticky flags */\n#define png_fp_add(state, flags) ((state) |= (flags))\n#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))\n\nint /* PRIVATE */\npng_check_fp_number(png_const_charp string, png_size_t size, int *statep,\n   png_size_tp whereami)\n{\n   int state = *statep;\n   png_size_t i = *whereami;\n\n   while (i < size)\n   {\n      int type;\n      /* First find the type of the next character */\n      switch (string[i])\n      {\n      case 43:  type = PNG_FP_SAW_SIGN;                   break;\n      case 45:  type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break;\n      case 46:  type = PNG_FP_SAW_DOT;                    break;\n      case 48:  type = PNG_FP_SAW_DIGIT;                  break;\n      case 49: case 50: case 51: case 52:\n      case 53: case 54: case 55: case 56:\n      case 57:  type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break;\n      case 69:\n      case 101: type = PNG_FP_SAW_E;                      break;\n      default:  goto PNG_FP_End;\n      }\n\n      /* Now deal with this type according to the current\n       * state, the type is arranged to not overlap the\n       * bits of the PNG_FP_STATE.\n       */\n      switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY))\n      {\n      case PNG_FP_INTEGER + PNG_FP_SAW_SIGN:\n         if ((state & PNG_FP_SAW_ANY) != 0)\n            goto PNG_FP_End; /* not a part of the number */\n\n         png_fp_add(state, type);\n         break;\n\n      case PNG_FP_INTEGER + PNG_FP_SAW_DOT:\n         /* Ok as trailer, ok as lead of fraction. */\n         if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */\n            goto PNG_FP_End;\n\n         else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */\n            png_fp_add(state, type);\n\n         else\n            png_fp_set(state, PNG_FP_FRACTION | type);\n\n         break;\n\n      case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT:\n         if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */\n            png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT);\n\n         png_fp_add(state, type | PNG_FP_WAS_VALID);\n\n         break;\n\n      case PNG_FP_INTEGER + PNG_FP_SAW_E:\n         if ((state & PNG_FP_SAW_DIGIT) == 0)\n            goto PNG_FP_End;\n\n         png_fp_set(state, PNG_FP_EXPONENT);\n\n         break;\n\n   /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN:\n         goto PNG_FP_End; ** no sign in fraction */\n\n   /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT:\n         goto PNG_FP_End; ** Because SAW_DOT is always set */\n\n      case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT:\n         png_fp_add(state, type | PNG_FP_WAS_VALID);\n         break;\n\n      case PNG_FP_FRACTION + PNG_FP_SAW_E:\n         /* This is correct because the trailing '.' on an\n          * integer is handled above - so we can only get here\n          * with the sequence \".E\" (with no preceding digits).\n          */\n         if ((state & PNG_FP_SAW_DIGIT) == 0)\n            goto PNG_FP_End;\n\n         png_fp_set(state, PNG_FP_EXPONENT);\n\n         break;\n\n      case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN:\n         if ((state & PNG_FP_SAW_ANY) != 0)\n            goto PNG_FP_End; /* not a part of the number */\n\n         png_fp_add(state, PNG_FP_SAW_SIGN);\n\n         break;\n\n   /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT:\n         goto PNG_FP_End; */\n\n      case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT:\n         png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID);\n\n         break;\n\n   /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E:\n         goto PNG_FP_End; */\n\n      default: goto PNG_FP_End; /* I.e. break 2 */\n      }\n\n      /* The character seems ok, continue. */\n      ++i;\n   }\n\nPNG_FP_End:\n   /* Here at the end, update the state and return the correct\n    * return code.\n    */\n   *statep = state;\n   *whereami = i;\n\n   return (state & PNG_FP_SAW_DIGIT) != 0;\n}\n\n\n/* The same but for a complete string. */\nint\npng_check_fp_string(png_const_charp string, png_size_t size)\n{\n   int        state=0;\n   png_size_t char_index=0;\n\n   if (png_check_fp_number(string, size, &state, &char_index) != 0 &&\n      (char_index == size || string[char_index] == 0))\n      return state /* must be non-zero - see above */;\n\n   return 0; /* i.e. fail */\n}\n#endif /* pCAL || sCAL */\n\n#ifdef PNG_sCAL_SUPPORTED\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\n/* Utility used below - a simple accurate power of ten from an integral\n * exponent.\n */\nstatic double\npng_pow10(int power)\n{\n   int recip = 0;\n   double d = 1;\n\n   /* Handle negative exponent with a reciprocal at the end because\n    * 10 is exact whereas .1 is inexact in base 2\n    */\n   if (power < 0)\n   {\n      if (power < DBL_MIN_10_EXP) return 0;\n      recip = 1, power = -power;\n   }\n\n   if (power > 0)\n   {\n      /* Decompose power bitwise. */\n      double mult = 10;\n      do\n      {\n         if (power & 1) d *= mult;\n         mult *= mult;\n         power >>= 1;\n      }\n      while (power > 0);\n\n      if (recip != 0) d = 1/d;\n   }\n   /* else power is 0 and d is 1 */\n\n   return d;\n}\n\n/* Function to format a floating point value in ASCII with a given\n * precision.\n */\nvoid /* PRIVATE */\npng_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,\n    double fp, unsigned int precision)\n{\n   /* We use standard functions from math.h, but not printf because\n    * that would require stdio.  The caller must supply a buffer of\n    * sufficient size or we will png_error.  The tests on size and\n    * the space in ascii[] consumed are indicated below.\n    */\n   if (precision < 1)\n      precision = DBL_DIG;\n\n   /* Enforce the limit of the implementation precision too. */\n   if (precision > DBL_DIG+1)\n      precision = DBL_DIG+1;\n\n   /* Basic sanity checks */\n   if (size >= precision+5) /* See the requirements below. */\n   {\n      if (fp < 0)\n      {\n         fp = -fp;\n         *ascii++ = 45; /* '-'  PLUS 1 TOTAL 1 */\n         --size;\n      }\n\n      if (fp >= DBL_MIN && fp <= DBL_MAX)\n      {\n         int exp_b10;   /* A base 10 exponent */\n         double base;   /* 10^exp_b10 */\n\n         /* First extract a base 10 exponent of the number,\n          * the calculation below rounds down when converting\n          * from base 2 to base 10 (multiply by log10(2) -\n          * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to\n          * be increased.  Note that the arithmetic shift\n          * performs a floor() unlike C arithmetic - using a\n          * C multiply would break the following for negative\n          * exponents.\n          */\n         (void)frexp(fp, &exp_b10); /* exponent to base 2 */\n\n         exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */\n\n         /* Avoid underflow here. */\n         base = png_pow10(exp_b10); /* May underflow */\n\n         while (base < DBL_MIN || base < fp)\n         {\n            /* And this may overflow. */\n            double test = png_pow10(exp_b10+1);\n\n            if (test <= DBL_MAX)\n               ++exp_b10, base = test;\n\n            else\n               break;\n         }\n\n         /* Normalize fp and correct exp_b10, after this fp is in the\n          * range [.1,1) and exp_b10 is both the exponent and the digit\n          * *before* which the decimal point should be inserted\n          * (starting with 0 for the first digit).  Note that this\n          * works even if 10^exp_b10 is out of range because of the\n          * test on DBL_MAX above.\n          */\n         fp /= base;\n         while (fp >= 1) fp /= 10, ++exp_b10;\n\n         /* Because of the code above fp may, at this point, be\n          * less than .1, this is ok because the code below can\n          * handle the leading zeros this generates, so no attempt\n          * is made to correct that here.\n          */\n\n         {\n            unsigned int czero, clead, cdigits;\n            char exponent[10];\n\n            /* Allow up to two leading zeros - this will not lengthen\n             * the number compared to using E-n.\n             */\n            if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */\n            {\n               czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */\n               exp_b10 = 0;      /* Dot added below before first output. */\n            }\n            else\n               czero = 0;    /* No zeros to add */\n\n            /* Generate the digit list, stripping trailing zeros and\n             * inserting a '.' before a digit if the exponent is 0.\n             */\n            clead = czero; /* Count of leading zeros */\n            cdigits = 0;   /* Count of digits in list. */\n\n            do\n            {\n               double d;\n\n               fp *= 10;\n               /* Use modf here, not floor and subtract, so that\n                * the separation is done in one step.  At the end\n                * of the loop don't break the number into parts so\n                * that the final digit is rounded.\n                */\n               if (cdigits+czero+1 < precision+clead)\n                  fp = modf(fp, &d);\n\n               else\n               {\n                  d = floor(fp + .5);\n\n                  if (d > 9)\n                  {\n                     /* Rounding up to 10, handle that here. */\n                     if (czero > 0)\n                     {\n                        --czero, d = 1;\n                        if (cdigits == 0) --clead;\n                     }\n                     else\n                     {\n                        while (cdigits > 0 && d > 9)\n                        {\n                           int ch = *--ascii;\n\n                           if (exp_b10 != (-1))\n                              ++exp_b10;\n\n                           else if (ch == 46)\n                           {\n                              ch = *--ascii, ++size;\n                              /* Advance exp_b10 to '1', so that the\n                               * decimal point happens after the\n                               * previous digit.\n                               */\n                              exp_b10 = 1;\n                           }\n\n                           --cdigits;\n                           d = ch - 47;  /* I.e. 1+(ch-48) */\n                        }\n\n                        /* Did we reach the beginning? If so adjust the\n                         * exponent but take into account the leading\n                         * decimal point.\n                         */\n                        if (d > 9)  /* cdigits == 0 */\n                        {\n                           if (exp_b10 == (-1))\n                           {\n                              /* Leading decimal point (plus zeros?), if\n                               * we lose the decimal point here it must\n                               * be reentered below.\n                               */\n                              int ch = *--ascii;\n\n                              if (ch == 46)\n                                 ++size, exp_b10 = 1;\n\n                              /* Else lost a leading zero, so 'exp_b10' is\n                               * still ok at (-1)\n                               */\n                           }\n                           else\n                              ++exp_b10;\n\n                           /* In all cases we output a '1' */\n                           d = 1;\n                        }\n                     }\n                  }\n                  fp = 0; /* Guarantees termination below. */\n               }\n\n               if (d == 0)\n               {\n                  ++czero;\n                  if (cdigits == 0) ++clead;\n               }\n               else\n               {\n                  /* Included embedded zeros in the digit count. */\n                  cdigits += czero - clead;\n                  clead = 0;\n\n                  while (czero > 0)\n                  {\n                     /* exp_b10 == (-1) means we just output the decimal\n                      * place - after the DP don't adjust 'exp_b10' any\n                      * more!\n                      */\n                     if (exp_b10 != (-1))\n                     {\n                        if (exp_b10 == 0) *ascii++ = 46, --size;\n                        /* PLUS 1: TOTAL 4 */\n                        --exp_b10;\n                     }\n                     *ascii++ = 48, --czero;\n                  }\n\n                  if (exp_b10 != (-1))\n                  {\n                     if (exp_b10 == 0)\n                        *ascii++ = 46, --size; /* counted above */\n\n                     --exp_b10;\n                  }\n                  *ascii++ = (char)(48 + (int)d), ++cdigits;\n               }\n            }\n            while (cdigits+czero < precision+clead && fp > DBL_MIN);\n\n            /* The total output count (max) is now 4+precision */\n\n            /* Check for an exponent, if we don't need one we are\n             * done and just need to terminate the string.  At\n             * this point exp_b10==(-1) is effectively if flag - it got\n             * to '-1' because of the decrement after outputting\n             * the decimal point above (the exponent required is\n             * *not* -1!)\n             */\n            if (exp_b10 >= (-1) && exp_b10 <= 2)\n            {\n               /* The following only happens if we didn't output the\n                * leading zeros above for negative exponent, so this\n                * doesn't add to the digit requirement.  Note that the\n                * two zeros here can only be output if the two leading\n                * zeros were *not* output, so this doesn't increase\n                * the output count.\n                */\n               while (--exp_b10 >= 0) *ascii++ = 48;\n\n               *ascii = 0;\n\n               /* Total buffer requirement (including the '\\0') is\n                * 5+precision - see check at the start.\n                */\n               return;\n            }\n\n            /* Here if an exponent is required, adjust size for\n             * the digits we output but did not count.  The total\n             * digit output here so far is at most 1+precision - no\n             * decimal point and no leading or trailing zeros have\n             * been output.\n             */\n            size -= cdigits;\n\n            *ascii++ = 69, --size;    /* 'E': PLUS 1 TOTAL 2+precision */\n\n            /* The following use of an unsigned temporary avoids ambiguities in\n             * the signed arithmetic on exp_b10 and permits GCC at least to do\n             * better optimization.\n             */\n            {\n               unsigned int uexp_b10;\n\n               if (exp_b10 < 0)\n               {\n                  *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */\n                  uexp_b10 = -exp_b10;\n               }\n\n               else\n                  uexp_b10 = exp_b10;\n\n               cdigits = 0;\n\n               while (uexp_b10 > 0)\n               {\n                  exponent[cdigits++] = (char)(48 + uexp_b10 % 10);\n                  uexp_b10 /= 10;\n               }\n            }\n\n            /* Need another size check here for the exponent digits, so\n             * this need not be considered above.\n             */\n            if (size > cdigits)\n            {\n               while (cdigits > 0) *ascii++ = exponent[--cdigits];\n\n               *ascii = 0;\n\n               return;\n            }\n         }\n      }\n      else if (!(fp >= DBL_MIN))\n      {\n         *ascii++ = 48; /* '0' */\n         *ascii = 0;\n         return;\n      }\n      else\n      {\n         *ascii++ = 105; /* 'i' */\n         *ascii++ = 110; /* 'n' */\n         *ascii++ = 102; /* 'f' */\n         *ascii = 0;\n         return;\n      }\n   }\n\n   /* Here on buffer too small. */\n   png_error(png_ptr, \"ASCII conversion buffer too small\");\n}\n\n#  endif /* FLOATING_POINT */\n\n#  ifdef PNG_FIXED_POINT_SUPPORTED\n/* Function to format a fixed point value in ASCII.\n */\nvoid /* PRIVATE */\npng_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,\n    png_size_t size, png_fixed_point fp)\n{\n   /* Require space for 10 decimal digits, a decimal point, a minus sign and a\n    * trailing \\0, 13 characters:\n    */\n   if (size > 12)\n   {\n      png_uint_32 num;\n\n      /* Avoid overflow here on the minimum integer. */\n      if (fp < 0)\n         *ascii++ = 45, num = -fp;\n      else\n         num = fp;\n\n      if (num <= 0x80000000) /* else overflowed */\n      {\n         unsigned int ndigits = 0, first = 16 /* flag value */;\n         char digits[10];\n\n         while (num)\n         {\n            /* Split the low digit off num: */\n            unsigned int tmp = num/10;\n            num -= tmp*10;\n            digits[ndigits++] = (char)(48 + num);\n            /* Record the first non-zero digit, note that this is a number\n             * starting at 1, it's not actually the array index.\n             */\n            if (first == 16 && num > 0)\n               first = ndigits;\n            num = tmp;\n         }\n\n         if (ndigits > 0)\n         {\n            while (ndigits > 5) *ascii++ = digits[--ndigits];\n            /* The remaining digits are fractional digits, ndigits is '5' or\n             * smaller at this point.  It is certainly not zero.  Check for a\n             * non-zero fractional digit:\n             */\n            if (first <= 5)\n            {\n               unsigned int i;\n               *ascii++ = 46; /* decimal point */\n               /* ndigits may be <5 for small numbers, output leading zeros\n                * then ndigits digits to first:\n                */\n               i = 5;\n               while (ndigits < i) *ascii++ = 48, --i;\n               while (ndigits >= first) *ascii++ = digits[--ndigits];\n               /* Don't output the trailing zeros! */\n            }\n         }\n         else\n            *ascii++ = 48;\n\n         /* And null terminate the string: */\n         *ascii = 0;\n         return;\n      }\n   }\n\n   /* Here on buffer too small. */\n   png_error(png_ptr, \"ASCII conversion buffer too small\");\n}\n#   endif /* FIXED_POINT */\n#endif /* SCAL */\n\n#if defined(PNG_FLOATING_POINT_SUPPORTED) && \\\n   !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \\\n   (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \\\n   defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \\\n   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \\\n   (defined(PNG_sCAL_SUPPORTED) && \\\n   defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))\npng_fixed_point\npng_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)\n{\n   double r = floor(100000 * fp + .5);\n\n   if (r > 2147483647. || r < -2147483648.)\n      png_fixed_error(png_ptr, text);\n\n#  ifndef PNG_ERROR_TEXT_SUPPORTED\n   PNG_UNUSED(text)\n#  endif\n\n   return (png_fixed_point)r;\n}\n#endif\n\n#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\\\n    defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)\n/* muldiv functions */\n/* This API takes signed arguments and rounds the result to the nearest\n * integer (or, for a fixed point number - the standard argument - to\n * the nearest .00001).  Overflow and divide by zero are signalled in\n * the result, a boolean - true on success, false on overflow.\n */\nint\npng_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,\n    png_int_32 divisor)\n{\n   /* Return a * times / divisor, rounded. */\n   if (divisor != 0)\n   {\n      if (a == 0 || times == 0)\n      {\n         *res = 0;\n         return 1;\n      }\n      else\n      {\n#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED\n         double r = a;\n         r *= times;\n         r /= divisor;\n         r = floor(r+.5);\n\n         /* A png_fixed_point is a 32-bit integer. */\n         if (r <= 2147483647. && r >= -2147483648.)\n         {\n            *res = (png_fixed_point)r;\n            return 1;\n         }\n#else\n         int negative = 0;\n         png_uint_32 A, T, D;\n         png_uint_32 s16, s32, s00;\n\n         if (a < 0)\n            negative = 1, A = -a;\n         else\n            A = a;\n\n         if (times < 0)\n            negative = !negative, T = -times;\n         else\n            T = times;\n\n         if (divisor < 0)\n            negative = !negative, D = -divisor;\n         else\n            D = divisor;\n\n         /* Following can't overflow because the arguments only\n          * have 31 bits each, however the result may be 32 bits.\n          */\n         s16 = (A >> 16) * (T & 0xffff) +\n                           (A & 0xffff) * (T >> 16);\n         /* Can't overflow because the a*times bit is only 30\n          * bits at most.\n          */\n         s32 = (A >> 16) * (T >> 16) + (s16 >> 16);\n         s00 = (A & 0xffff) * (T & 0xffff);\n\n         s16 = (s16 & 0xffff) << 16;\n         s00 += s16;\n\n         if (s00 < s16)\n            ++s32; /* carry */\n\n         if (s32 < D) /* else overflow */\n         {\n            /* s32.s00 is now the 64-bit product, do a standard\n             * division, we know that s32 < D, so the maximum\n             * required shift is 31.\n             */\n            int bitshift = 32;\n            png_fixed_point result = 0; /* NOTE: signed */\n\n            while (--bitshift >= 0)\n            {\n               png_uint_32 d32, d00;\n\n               if (bitshift > 0)\n                  d32 = D >> (32-bitshift), d00 = D << bitshift;\n\n               else\n                  d32 = 0, d00 = D;\n\n               if (s32 > d32)\n               {\n                  if (s00 < d00) --s32; /* carry */\n                  s32 -= d32, s00 -= d00, result += 1<<bitshift;\n               }\n\n               else\n                  if (s32 == d32 && s00 >= d00)\n                     s32 = 0, s00 -= d00, result += 1<<bitshift;\n            }\n\n            /* Handle the rounding. */\n            if (s00 >= (D >> 1))\n               ++result;\n\n            if (negative != 0)\n               result = -result;\n\n            /* Check for overflow. */\n            if ((negative != 0 && result <= 0) ||\n                (negative == 0 && result >= 0))\n            {\n               *res = result;\n               return 1;\n            }\n         }\n#endif\n      }\n   }\n\n   return 0;\n}\n#endif /* READ_GAMMA || INCH_CONVERSIONS */\n\n#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)\n/* The following is for when the caller doesn't much care about the\n * result.\n */\npng_fixed_point\npng_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times,\n    png_int_32 divisor)\n{\n   png_fixed_point result;\n\n   if (png_muldiv(&result, a, times, divisor) != 0)\n      return result;\n\n   png_warning(png_ptr, \"fixed point overflow ignored\");\n   return 0;\n}\n#endif\n\n#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */\n/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */\npng_fixed_point\npng_reciprocal(png_fixed_point a)\n{\n#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED\n   double r = floor(1E10/a+.5);\n\n   if (r <= 2147483647. && r >= -2147483648.)\n      return (png_fixed_point)r;\n#else\n   png_fixed_point res;\n\n   if (png_muldiv(&res, 100000, 100000, a) != 0)\n      return res;\n#endif\n\n   return 0; /* error/overflow */\n}\n\n/* This is the shared test on whether a gamma value is 'significant' - whether\n * it is worth doing gamma correction.\n */\nint /* PRIVATE */\npng_gamma_significant(png_fixed_point gamma_val)\n{\n   return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED ||\n       gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED;\n}\n#endif\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\n#ifdef PNG_16BIT_SUPPORTED\n/* A local convenience routine. */\nstatic png_fixed_point\npng_product2(png_fixed_point a, png_fixed_point b)\n{\n   /* The required result is 1/a * 1/b; the following preserves accuracy. */\n#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED\n   double r = a * 1E-5;\n   r *= b;\n   r = floor(r+.5);\n\n   if (r <= 2147483647. && r >= -2147483648.)\n      return (png_fixed_point)r;\n#else\n   png_fixed_point res;\n\n   if (png_muldiv(&res, a, b, 100000) != 0)\n      return res;\n#endif\n\n   return 0; /* overflow */\n}\n#endif /* 16BIT */\n\n/* The inverse of the above. */\npng_fixed_point\npng_reciprocal2(png_fixed_point a, png_fixed_point b)\n{\n   /* The required result is 1/a * 1/b; the following preserves accuracy. */\n#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED\n   if (a != 0 && b != 0)\n   {\n      double r = 1E15/a;\n      r /= b;\n      r = floor(r+.5);\n\n      if (r <= 2147483647. && r >= -2147483648.)\n         return (png_fixed_point)r;\n   }\n#else\n   /* This may overflow because the range of png_fixed_point isn't symmetric,\n    * but this API is only used for the product of file and screen gamma so it\n    * doesn't matter that the smallest number it can produce is 1/21474, not\n    * 1/100000\n    */\n   png_fixed_point res = png_product2(a, b);\n\n   if (res != 0)\n      return png_reciprocal(res);\n#endif\n\n   return 0; /* overflow */\n}\n#endif /* READ_GAMMA */\n\n#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */\n#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED\n/* Fixed point gamma.\n *\n * The code to calculate the tables used below can be found in the shell script\n * contrib/tools/intgamma.sh\n *\n * To calculate gamma this code implements fast log() and exp() calls using only\n * fixed point arithmetic.  This code has sufficient precision for either 8-bit\n * or 16-bit sample values.\n *\n * The tables used here were calculated using simple 'bc' programs, but C double\n * precision floating point arithmetic would work fine.\n *\n * 8-bit log table\n *   This is a table of -log(value/255)/log(2) for 'value' in the range 128 to\n *   255, so it's the base 2 logarithm of a normalized 8-bit floating point\n *   mantissa.  The numbers are 32-bit fractions.\n */\nstatic const png_uint_32\npng_8bit_l2[128] =\n{\n   4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U,\n   3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U,\n   3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U,\n   3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U,\n   3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U,\n   2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U,\n   2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U,\n   2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U,\n   2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U,\n   2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U,\n   1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U,\n   1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U,\n   1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U,\n   1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U,\n   1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U,\n   971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U,\n   803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U,\n   639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U,\n   479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U,\n   324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U,\n   172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U,\n   24347096U, 0U\n\n#if 0\n   /* The following are the values for 16-bit tables - these work fine for the\n    * 8-bit conversions but produce very slightly larger errors in the 16-bit\n    * log (about 1.2 as opposed to 0.7 absolute error in the final value).  To\n    * use these all the shifts below must be adjusted appropriately.\n    */\n   65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054,\n   57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803,\n   50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068,\n   43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782,\n   37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887,\n   31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339,\n   25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098,\n   20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132,\n   15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415,\n   10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523,\n   6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495,\n   1119, 744, 372\n#endif\n};\n\nstatic png_int_32\npng_log8bit(unsigned int x)\n{\n   unsigned int lg2 = 0;\n   /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log,\n    * because the log is actually negate that means adding 1.  The final\n    * returned value thus has the range 0 (for 255 input) to 7.994 (for 1\n    * input), return -1 for the overflow (log 0) case, - so the result is\n    * always at most 19 bits.\n    */\n   if ((x &= 0xff) == 0)\n      return -1;\n\n   if ((x & 0xf0) == 0)\n      lg2  = 4, x <<= 4;\n\n   if ((x & 0xc0) == 0)\n      lg2 += 2, x <<= 2;\n\n   if ((x & 0x80) == 0)\n      lg2 += 1, x <<= 1;\n\n   /* result is at most 19 bits, so this cast is safe: */\n   return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16));\n}\n\n/* The above gives exact (to 16 binary places) log2 values for 8-bit images,\n * for 16-bit images we use the most significant 8 bits of the 16-bit value to\n * get an approximation then multiply the approximation by a correction factor\n * determined by the remaining up to 8 bits.  This requires an additional step\n * in the 16-bit case.\n *\n * We want log2(value/65535), we have log2(v'/255), where:\n *\n *    value = v' * 256 + v''\n *          = v' * f\n *\n * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128\n * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less\n * than 258.  The final factor also needs to correct for the fact that our 8-bit\n * value is scaled by 255, whereas the 16-bit values must be scaled by 65535.\n *\n * This gives a final formula using a calculated value 'x' which is value/v' and\n * scaling by 65536 to match the above table:\n *\n *   log2(x/257) * 65536\n *\n * Since these numbers are so close to '1' we can use simple linear\n * interpolation between the two end values 256/257 (result -368.61) and 258/257\n * (result 367.179).  The values used below are scaled by a further 64 to give\n * 16-bit precision in the interpolation:\n *\n * Start (256): -23591\n * Zero  (257):      0\n * End   (258):  23499\n */\n#ifdef PNG_16BIT_SUPPORTED\nstatic png_int_32\npng_log16bit(png_uint_32 x)\n{\n   unsigned int lg2 = 0;\n\n   /* As above, but now the input has 16 bits. */\n   if ((x &= 0xffff) == 0)\n      return -1;\n\n   if ((x & 0xff00) == 0)\n      lg2  = 8, x <<= 8;\n\n   if ((x & 0xf000) == 0)\n      lg2 += 4, x <<= 4;\n\n   if ((x & 0xc000) == 0)\n      lg2 += 2, x <<= 2;\n\n   if ((x & 0x8000) == 0)\n      lg2 += 1, x <<= 1;\n\n   /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional\n    * value.\n    */\n   lg2 <<= 28;\n   lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4;\n\n   /* Now we need to interpolate the factor, this requires a division by the top\n    * 8 bits.  Do this with maximum precision.\n    */\n   x = ((x << 16) + (x >> 9)) / (x >> 8);\n\n   /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24,\n    * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly\n    * 16 bits to interpolate to get the low bits of the result.  Round the\n    * answer.  Note that the end point values are scaled by 64 to retain overall\n    * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust\n    * the overall scaling by 6-12.  Round at every step.\n    */\n   x -= 1U << 24;\n\n   if (x <= 65536U) /* <= '257' */\n      lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12);\n\n   else\n      lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12);\n\n   /* Safe, because the result can't have more than 20 bits: */\n   return (png_int_32)((lg2 + 2048) >> 12);\n}\n#endif /* 16BIT */\n\n/* The 'exp()' case must invert the above, taking a 20-bit fixed point\n * logarithmic value and returning a 16 or 8-bit number as appropriate.  In\n * each case only the low 16 bits are relevant - the fraction - since the\n * integer bits (the top 4) simply determine a shift.\n *\n * The worst case is the 16-bit distinction between 65535 and 65534. This\n * requires perhaps spurious accuracy in the decoding of the logarithm to\n * distinguish log2(65535/65534.5) - 10^-5 or 17 bits.  There is little chance\n * of getting this accuracy in practice.\n *\n * To deal with this the following exp() function works out the exponent of the\n * frational part of the logarithm by using an accurate 32-bit value from the\n * top four fractional bits then multiplying in the remaining bits.\n */\nstatic const png_uint_32\npng_32bit_exp[16] =\n{\n   /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */\n   4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U,\n   3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U,\n   2553802834U, 2445529972U, 2341847524U, 2242560872U\n};\n\n/* Adjustment table; provided to explain the numbers in the code below. */\n#if 0\nfor (i=11;i>=0;--i){ print i, \" \", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), \"\\n\"}\n   11 44937.64284865548751208448\n   10 45180.98734845585101160448\n    9 45303.31936980687359311872\n    8 45364.65110595323018870784\n    7 45395.35850361789624614912\n    6 45410.72259715102037508096\n    5 45418.40724413220722311168\n    4 45422.25021786898173001728\n    3 45424.17186732298419044352\n    2 45425.13273269940811464704\n    1 45425.61317555035558641664\n    0 45425.85339951654943850496\n#endif\n\nstatic png_uint_32\npng_exp(png_fixed_point x)\n{\n   if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */\n   {\n      /* Obtain a 4-bit approximation */\n      png_uint_32 e = png_32bit_exp[(x >> 12) & 0x0f];\n\n      /* Incorporate the low 12 bits - these decrease the returned value by\n       * multiplying by a number less than 1 if the bit is set.  The multiplier\n       * is determined by the above table and the shift. Notice that the values\n       * converge on 45426 and this is used to allow linear interpolation of the\n       * low bits.\n       */\n      if (x & 0x800)\n         e -= (((e >> 16) * 44938U) +  16U) >> 5;\n\n      if (x & 0x400)\n         e -= (((e >> 16) * 45181U) +  32U) >> 6;\n\n      if (x & 0x200)\n         e -= (((e >> 16) * 45303U) +  64U) >> 7;\n\n      if (x & 0x100)\n         e -= (((e >> 16) * 45365U) + 128U) >> 8;\n\n      if (x & 0x080)\n         e -= (((e >> 16) * 45395U) + 256U) >> 9;\n\n      if (x & 0x040)\n         e -= (((e >> 16) * 45410U) + 512U) >> 10;\n\n      /* And handle the low 6 bits in a single block. */\n      e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9;\n\n      /* Handle the upper bits of x. */\n      e >>= x >> 16;\n      return e;\n   }\n\n   /* Check for overflow */\n   if (x <= 0)\n      return png_32bit_exp[0];\n\n   /* Else underflow */\n   return 0;\n}\n\nstatic png_byte\npng_exp8bit(png_fixed_point lg2)\n{\n   /* Get a 32-bit value: */\n   png_uint_32 x = png_exp(lg2);\n\n   /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that the\n    * second, rounding, step can't overflow because of the first, subtraction,\n    * step.\n    */\n   x -= x >> 8;\n   return (png_byte)(((x + 0x7fffffU) >> 24) & 0xff);\n}\n\n#ifdef PNG_16BIT_SUPPORTED\nstatic png_uint_16\npng_exp16bit(png_fixed_point lg2)\n{\n   /* Get a 32-bit value: */\n   png_uint_32 x = png_exp(lg2);\n\n   /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */\n   x -= x >> 16;\n   return (png_uint_16)((x + 32767U) >> 16);\n}\n#endif /* 16BIT */\n#endif /* FLOATING_ARITHMETIC */\n\npng_byte\npng_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)\n{\n   if (value > 0 && value < 255)\n   {\n#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED\n         /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly\n          * convert this to a floating point value.  This includes values that\n          * would overflow if 'value' were to be converted to 'int'.\n          *\n          * Apparently GCC, however, does an intermediate conversion to (int)\n          * on some (ARM) but not all (x86) platforms, possibly because of\n          * hardware FP limitations.  (E.g. if the hardware conversion always\n          * assumes the integer register contains a signed value.)  This results\n          * in ANSI-C undefined behavior for large values.\n          *\n          * Other implementations on the same machine might actually be ANSI-C90\n          * conformant and therefore compile spurious extra code for the large\n          * values.\n          *\n          * We can be reasonably sure that an unsigned to float conversion\n          * won't be faster than an int to float one.  Therefore this code\n          * assumes responsibility for the undefined behavior, which it knows\n          * can't happen because of the check above.\n          *\n          * Note the argument to this routine is an (unsigned int) because, on\n          * 16-bit platforms, it is assigned a value which might be out of\n          * range for an (int); that would result in undefined behavior in the\n          * caller if the *argument* ('value') were to be declared (int).\n          */\n         double r = floor(255*pow((int)/*SAFE*/value/255.,gamma_val*.00001)+.5);\n         return (png_byte)r;\n#     else\n         png_int_32 lg2 = png_log8bit(value);\n         png_fixed_point res;\n\n         if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)\n            return png_exp8bit(res);\n\n         /* Overflow. */\n         value = 0;\n#     endif\n   }\n\n   return (png_byte)(value & 0xff);\n}\n\n#ifdef PNG_16BIT_SUPPORTED\npng_uint_16\npng_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)\n{\n   if (value > 0 && value < 65535)\n   {\n#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED\n         /* The same (unsigned int)->(double) constraints apply here as above,\n          * however in this case the (unsigned int) to (int) conversion can\n          * overflow on an ANSI-C90 compliant system so the cast needs to ensure\n          * that this is not possible.\n          */\n         double r = floor(65535*pow((png_int_32)value/65535.,\n                     gamma_val*.00001)+.5);\n         return (png_uint_16)r;\n#     else\n         png_int_32 lg2 = png_log16bit(value);\n         png_fixed_point res;\n\n         if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)\n            return png_exp16bit(res);\n\n         /* Overflow. */\n         value = 0;\n#     endif\n   }\n\n   return (png_uint_16)value;\n}\n#endif /* 16BIT */\n\n/* This does the right thing based on the bit_depth field of the\n * png_struct, interpreting values as 8-bit or 16-bit.  While the result\n * is nominally a 16-bit value if bit depth is 8 then the result is\n * 8-bit (as are the arguments.)\n */\npng_uint_16 /* PRIVATE */\npng_gamma_correct(png_structrp png_ptr, unsigned int value,\n    png_fixed_point gamma_val)\n{\n   if (png_ptr->bit_depth == 8)\n      return png_gamma_8bit_correct(value, gamma_val);\n\n#ifdef PNG_16BIT_SUPPORTED\n   else\n      return png_gamma_16bit_correct(value, gamma_val);\n#else\n      /* should not reach this */\n      return 0;\n#endif /* 16BIT */\n}\n\n#ifdef PNG_16BIT_SUPPORTED\n/* Internal function to build a single 16-bit table - the table consists of\n * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount\n * to shift the input values right (or 16-number_of_signifiant_bits).\n *\n * The caller is responsible for ensuring that the table gets cleaned up on\n * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument\n * should be somewhere that will be cleaned.\n */\nstatic void\npng_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,\n   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)\n{\n   /* Various values derived from 'shift': */\n   PNG_CONST unsigned int num = 1U << (8U - shift);\n#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED\n   /* CSE the division and work round wacky GCC warnings (see the comments\n    * in png_gamma_8bit_correct for where these come from.)\n    */\n   PNG_CONST double fmax = 1./(((png_int_32)1 << (16U - shift))-1);\n#endif\n   PNG_CONST unsigned int max = (1U << (16U - shift))-1U;\n   PNG_CONST unsigned int max_by_2 = 1U << (15U-shift);\n   unsigned int i;\n\n   png_uint_16pp table = *ptable =\n       (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));\n\n   for (i = 0; i < num; i++)\n   {\n      png_uint_16p sub_table = table[i] =\n          (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16)));\n\n      /* The 'threshold' test is repeated here because it can arise for one of\n       * the 16-bit tables even if the others don't hit it.\n       */\n      if (png_gamma_significant(gamma_val) != 0)\n      {\n         /* The old code would overflow at the end and this would cause the\n          * 'pow' function to return a result >1, resulting in an\n          * arithmetic error.  This code follows the spec exactly; ig is\n          * the recovered input sample, it always has 8-16 bits.\n          *\n          * We want input * 65535/max, rounded, the arithmetic fits in 32\n          * bits (unsigned) so long as max <= 32767.\n          */\n         unsigned int j;\n         for (j = 0; j < 256; j++)\n         {\n            png_uint_32 ig = (j << (8-shift)) + i;\n#           ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED\n               /* Inline the 'max' scaling operation: */\n               /* See png_gamma_8bit_correct for why the cast to (int) is\n                * required here.\n                */\n               double d = floor(65535.*pow(ig*fmax, gamma_val*.00001)+.5);\n               sub_table[j] = (png_uint_16)d;\n#           else\n               if (shift != 0)\n                  ig = (ig * 65535U + max_by_2)/max;\n\n               sub_table[j] = png_gamma_16bit_correct(ig, gamma_val);\n#           endif\n         }\n      }\n      else\n      {\n         /* We must still build a table, but do it the fast way. */\n         unsigned int j;\n\n         for (j = 0; j < 256; j++)\n         {\n            png_uint_32 ig = (j << (8-shift)) + i;\n\n            if (shift != 0)\n               ig = (ig * 65535U + max_by_2)/max;\n\n            sub_table[j] = (png_uint_16)ig;\n         }\n      }\n   }\n}\n\n/* NOTE: this function expects the *inverse* of the overall gamma transformation\n * required.\n */\nstatic void\npng_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,\n   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)\n{\n   PNG_CONST unsigned int num = 1U << (8U - shift);\n   PNG_CONST unsigned int max = (1U << (16U - shift))-1U;\n   unsigned int i;\n   png_uint_32 last;\n\n   png_uint_16pp table = *ptable =\n       (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));\n\n   /* 'num' is the number of tables and also the number of low bits of low\n    * bits of the input 16-bit value used to select a table.  Each table is\n    * itself indexed by the high 8 bits of the value.\n    */\n   for (i = 0; i < num; i++)\n      table[i] = (png_uint_16p)png_malloc(png_ptr,\n          256 * (sizeof (png_uint_16)));\n\n   /* 'gamma_val' is set to the reciprocal of the value calculated above, so\n    * pow(out,g) is an *input* value.  'last' is the last input value set.\n    *\n    * In the loop 'i' is used to find output values.  Since the output is\n    * 8-bit there are only 256 possible values.  The tables are set up to\n    * select the closest possible output value for each input by finding\n    * the input value at the boundary between each pair of output values\n    * and filling the table up to that boundary with the lower output\n    * value.\n    *\n    * The boundary values are 0.5,1.5..253.5,254.5.  Since these are 9-bit\n    * values the code below uses a 16-bit value in i; the values start at\n    * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last\n    * entries are filled with 255).  Start i at 128 and fill all 'last'\n    * table entries <= 'max'\n    */\n   last = 0;\n   for (i = 0; i < 255; ++i) /* 8-bit output value */\n   {\n      /* Find the corresponding maximum input value */\n      png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */\n\n      /* Find the boundary value in 16 bits: */\n      png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val);\n\n      /* Adjust (round) to (16-shift) bits: */\n      bound = (bound * max + 32768U)/65535U + 1U;\n\n      while (last < bound)\n      {\n         table[last & (0xffU >> shift)][last >> (8U - shift)] = out;\n         last++;\n      }\n   }\n\n   /* And fill in the final entries. */\n   while (last < (num << 8))\n   {\n      table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U;\n      last++;\n   }\n}\n#endif /* 16BIT */\n\n/* Build a single 8-bit table: same as the 16-bit case but much simpler (and\n * typically much faster).  Note that libpng currently does no sBIT processing\n * (apparently contrary to the spec) so a 256-entry table is always generated.\n */\nstatic void\npng_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,\n   PNG_CONST png_fixed_point gamma_val)\n{\n   unsigned int i;\n   png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256);\n\n   if (png_gamma_significant(gamma_val) != 0)\n      for (i=0; i<256; i++)\n         table[i] = png_gamma_8bit_correct(i, gamma_val);\n\n   else\n      for (i=0; i<256; ++i)\n         table[i] = (png_byte)(i & 0xff);\n}\n\n/* Used from png_read_destroy and below to release the memory used by the gamma\n * tables.\n */\nvoid /* PRIVATE */\npng_destroy_gamma_table(png_structrp png_ptr)\n{\n   png_free(png_ptr, png_ptr->gamma_table);\n   png_ptr->gamma_table = NULL;\n\n#ifdef PNG_16BIT_SUPPORTED\n   if (png_ptr->gamma_16_table != NULL)\n   {\n      int i;\n      int istop = (1 << (8 - png_ptr->gamma_shift));\n      for (i = 0; i < istop; i++)\n      {\n         png_free(png_ptr, png_ptr->gamma_16_table[i]);\n      }\n   png_free(png_ptr, png_ptr->gamma_16_table);\n   png_ptr->gamma_16_table = NULL;\n   }\n#endif /* 16BIT */\n\n#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \\\n   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \\\n   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)\n   png_free(png_ptr, png_ptr->gamma_from_1);\n   png_ptr->gamma_from_1 = NULL;\n   png_free(png_ptr, png_ptr->gamma_to_1);\n   png_ptr->gamma_to_1 = NULL;\n\n#ifdef PNG_16BIT_SUPPORTED\n   if (png_ptr->gamma_16_from_1 != NULL)\n   {\n      int i;\n      int istop = (1 << (8 - png_ptr->gamma_shift));\n      for (i = 0; i < istop; i++)\n      {\n         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);\n      }\n   png_free(png_ptr, png_ptr->gamma_16_from_1);\n   png_ptr->gamma_16_from_1 = NULL;\n   }\n   if (png_ptr->gamma_16_to_1 != NULL)\n   {\n      int i;\n      int istop = (1 << (8 - png_ptr->gamma_shift));\n      for (i = 0; i < istop; i++)\n      {\n         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);\n      }\n   png_free(png_ptr, png_ptr->gamma_16_to_1);\n   png_ptr->gamma_16_to_1 = NULL;\n   }\n#endif /* 16BIT */\n#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */\n}\n\n/* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit\n * tables, we don't make a full table if we are reducing to 8-bit in\n * the future.  Note also how the gamma_16 tables are segmented so that\n * we don't need to allocate > 64K chunks for a full 16-bit table.\n */\nvoid /* PRIVATE */\npng_build_gamma_table(png_structrp png_ptr, int bit_depth)\n{\n  png_debug(1, \"in png_build_gamma_table\");\n\n  /* Remove any existing table; this copes with multiple calls to\n   * png_read_update_info.  The warning is because building the gamma tables\n   * multiple times is a performance hit - it's harmless but the ability to call\n   * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible\n   * to warn if the app introduces such a hit.\n   */\n  if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)\n  {\n    png_warning(png_ptr, \"gamma table being rebuilt\");\n    png_destroy_gamma_table(png_ptr);\n  }\n\n  if (bit_depth <= 8)\n  {\n     png_build_8bit_table(png_ptr, &png_ptr->gamma_table,\n         png_ptr->screen_gamma > 0 ?  png_reciprocal2(png_ptr->colorspace.gamma,\n         png_ptr->screen_gamma) : PNG_FP_1);\n\n#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \\\n   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \\\n   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)\n     if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)\n     {\n        png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,\n            png_reciprocal(png_ptr->colorspace.gamma));\n\n        png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,\n            png_ptr->screen_gamma > 0 ?  png_reciprocal(png_ptr->screen_gamma) :\n            png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);\n     }\n#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */\n  }\n#ifdef PNG_16BIT_SUPPORTED\n  else\n  {\n     png_byte shift, sig_bit;\n\n     if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)\n     {\n        sig_bit = png_ptr->sig_bit.red;\n\n        if (png_ptr->sig_bit.green > sig_bit)\n           sig_bit = png_ptr->sig_bit.green;\n\n        if (png_ptr->sig_bit.blue > sig_bit)\n           sig_bit = png_ptr->sig_bit.blue;\n     }\n     else\n        sig_bit = png_ptr->sig_bit.gray;\n\n     /* 16-bit gamma code uses this equation:\n      *\n      *   ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]\n      *\n      * Where 'iv' is the input color value and 'ov' is the output value -\n      * pow(iv, gamma).\n      *\n      * Thus the gamma table consists of up to 256 256-entry tables.  The table\n      * is selected by the (8-gamma_shift) most significant of the low 8 bits of\n      * the color value then indexed by the upper 8 bits:\n      *\n      *   table[low bits][high 8 bits]\n      *\n      * So the table 'n' corresponds to all those 'iv' of:\n      *\n      *   <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>\n      *\n      */\n     if (sig_bit > 0 && sig_bit < 16U)\n        /* shift == insignificant bits */\n        shift = (png_byte)((16U - sig_bit) & 0xff);\n\n     else\n        shift = 0; /* keep all 16 bits */\n\n     if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)\n     {\n        /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively\n         * the significant bits in the *input* when the output will\n         * eventually be 8 bits.  By default it is 11.\n         */\n        if (shift < (16U - PNG_MAX_GAMMA_8))\n           shift = (16U - PNG_MAX_GAMMA_8);\n     }\n\n     if (shift > 8U)\n        shift = 8U; /* Guarantees at least one table! */\n\n     png_ptr->gamma_shift = shift;\n\n     /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now\n      * PNG_COMPOSE).  This effectively smashed the background calculation for\n      * 16-bit output because the 8-bit table assumes the result will be reduced\n      * to 8 bits.\n      */\n     if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)\n         png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,\n         png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,\n         png_ptr->screen_gamma) : PNG_FP_1);\n\n     else\n         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,\n         png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,\n         png_ptr->screen_gamma) : PNG_FP_1);\n\n#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \\\n   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \\\n   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)\n     if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)\n     {\n        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,\n            png_reciprocal(png_ptr->colorspace.gamma));\n\n        /* Notice that the '16 from 1' table should be full precision, however\n         * the lookup on this table still uses gamma_shift, so it can't be.\n         * TODO: fix this.\n         */\n        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,\n            png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :\n            png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);\n     }\n#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */\n  }\n#endif /* 16BIT */\n}\n#endif /* READ_GAMMA */\n\n/* HARDWARE OR SOFTWARE OPTION SUPPORT */\n#ifdef PNG_SET_OPTION_SUPPORTED\nint PNGAPI\npng_set_option(png_structrp png_ptr, int option, int onoff)\n{\n   if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT &&\n      (option & 1) == 0)\n   {\n      int mask = 3 << option;\n      int setting = (2 + (onoff != 0)) << option;\n      int current = png_ptr->options;\n\n      png_ptr->options = (png_byte)(((current & ~mask) | setting) & 0xff);\n\n      return (current & mask) >> option;\n   }\n\n   return PNG_OPTION_INVALID;\n}\n#endif\n\n/* sRGB support */\n#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\\\n   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)\n/* sRGB conversion tables; these are machine generated with the code in\n * contrib/tools/makesRGB.c.  The actual sRGB transfer curve defined in the\n * specification (see the article at http://en.wikipedia.org/wiki/SRGB)\n * is used, not the gamma=1/2.2 approximation use elsewhere in libpng.\n * The sRGB to linear table is exact (to the nearest 16-bit linear fraction).\n * The inverse (linear to sRGB) table has accuracies as follows:\n *\n * For all possible (255*65535+1) input values:\n *\n *    error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact\n *\n * For the input values corresponding to the 65536 16-bit values:\n *\n *    error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact\n *\n * In all cases the inexact readings are only off by one.\n */\n\n#ifdef PNG_SIMPLIFIED_READ_SUPPORTED\n/* The convert-to-sRGB table is only currently required for read. */\nconst png_uint_16 png_sRGB_table[256] =\n{\n   0,20,40,60,80,99,119,139,\n   159,179,199,219,241,264,288,313,\n   340,367,396,427,458,491,526,562,\n   599,637,677,718,761,805,851,898,\n   947,997,1048,1101,1156,1212,1270,1330,\n   1391,1453,1517,1583,1651,1720,1790,1863,\n   1937,2013,2090,2170,2250,2333,2418,2504,\n   2592,2681,2773,2866,2961,3058,3157,3258,\n   3360,3464,3570,3678,3788,3900,4014,4129,\n   4247,4366,4488,4611,4736,4864,4993,5124,\n   5257,5392,5530,5669,5810,5953,6099,6246,\n   6395,6547,6700,6856,7014,7174,7335,7500,\n   7666,7834,8004,8177,8352,8528,8708,8889,\n   9072,9258,9445,9635,9828,10022,10219,10417,\n   10619,10822,11028,11235,11446,11658,11873,12090,\n   12309,12530,12754,12980,13209,13440,13673,13909,\n   14146,14387,14629,14874,15122,15371,15623,15878,\n   16135,16394,16656,16920,17187,17456,17727,18001,\n   18277,18556,18837,19121,19407,19696,19987,20281,\n   20577,20876,21177,21481,21787,22096,22407,22721,\n   23038,23357,23678,24002,24329,24658,24990,25325,\n   25662,26001,26344,26688,27036,27386,27739,28094,\n   28452,28813,29176,29542,29911,30282,30656,31033,\n   31412,31794,32179,32567,32957,33350,33745,34143,\n   34544,34948,35355,35764,36176,36591,37008,37429,\n   37852,38278,38706,39138,39572,40009,40449,40891,\n   41337,41785,42236,42690,43147,43606,44069,44534,\n   45002,45473,45947,46423,46903,47385,47871,48359,\n   48850,49344,49841,50341,50844,51349,51858,52369,\n   52884,53401,53921,54445,54971,55500,56032,56567,\n   57105,57646,58190,58737,59287,59840,60396,60955,\n   61517,62082,62650,63221,63795,64372,64952,65535\n};\n#endif /* SIMPLIFIED_READ */\n\n/* The base/delta tables are required for both read and write (but currently\n * only the simplified versions.)\n */\nconst png_uint_16 png_sRGB_base[512] =\n{\n   128,1782,3383,4644,5675,6564,7357,8074,\n   8732,9346,9921,10463,10977,11466,11935,12384,\n   12816,13233,13634,14024,14402,14769,15125,15473,\n   15812,16142,16466,16781,17090,17393,17690,17981,\n   18266,18546,18822,19093,19359,19621,19879,20133,\n   20383,20630,20873,21113,21349,21583,21813,22041,\n   22265,22487,22707,22923,23138,23350,23559,23767,\n   23972,24175,24376,24575,24772,24967,25160,25352,\n   25542,25730,25916,26101,26284,26465,26645,26823,\n   27000,27176,27350,27523,27695,27865,28034,28201,\n   28368,28533,28697,28860,29021,29182,29341,29500,\n   29657,29813,29969,30123,30276,30429,30580,30730,\n   30880,31028,31176,31323,31469,31614,31758,31902,\n   32045,32186,32327,32468,32607,32746,32884,33021,\n   33158,33294,33429,33564,33697,33831,33963,34095,\n   34226,34357,34486,34616,34744,34873,35000,35127,\n   35253,35379,35504,35629,35753,35876,35999,36122,\n   36244,36365,36486,36606,36726,36845,36964,37083,\n   37201,37318,37435,37551,37668,37783,37898,38013,\n   38127,38241,38354,38467,38580,38692,38803,38915,\n   39026,39136,39246,39356,39465,39574,39682,39790,\n   39898,40005,40112,40219,40325,40431,40537,40642,\n   40747,40851,40955,41059,41163,41266,41369,41471,\n   41573,41675,41777,41878,41979,42079,42179,42279,\n   42379,42478,42577,42676,42775,42873,42971,43068,\n   43165,43262,43359,43456,43552,43648,43743,43839,\n   43934,44028,44123,44217,44311,44405,44499,44592,\n   44685,44778,44870,44962,45054,45146,45238,45329,\n   45420,45511,45601,45692,45782,45872,45961,46051,\n   46140,46229,46318,46406,46494,46583,46670,46758,\n   46846,46933,47020,47107,47193,47280,47366,47452,\n   47538,47623,47709,47794,47879,47964,48048,48133,\n   48217,48301,48385,48468,48552,48635,48718,48801,\n   48884,48966,49048,49131,49213,49294,49376,49458,\n   49539,49620,49701,49782,49862,49943,50023,50103,\n   50183,50263,50342,50422,50501,50580,50659,50738,\n   50816,50895,50973,51051,51129,51207,51285,51362,\n   51439,51517,51594,51671,51747,51824,51900,51977,\n   52053,52129,52205,52280,52356,52432,52507,52582,\n   52657,52732,52807,52881,52956,53030,53104,53178,\n   53252,53326,53400,53473,53546,53620,53693,53766,\n   53839,53911,53984,54056,54129,54201,54273,54345,\n   54417,54489,54560,54632,54703,54774,54845,54916,\n   54987,55058,55129,55199,55269,55340,55410,55480,\n   55550,55620,55689,55759,55828,55898,55967,56036,\n   56105,56174,56243,56311,56380,56448,56517,56585,\n   56653,56721,56789,56857,56924,56992,57059,57127,\n   57194,57261,57328,57395,57462,57529,57595,57662,\n   57728,57795,57861,57927,57993,58059,58125,58191,\n   58256,58322,58387,58453,58518,58583,58648,58713,\n   58778,58843,58908,58972,59037,59101,59165,59230,\n   59294,59358,59422,59486,59549,59613,59677,59740,\n   59804,59867,59930,59993,60056,60119,60182,60245,\n   60308,60370,60433,60495,60558,60620,60682,60744,\n   60806,60868,60930,60992,61054,61115,61177,61238,\n   61300,61361,61422,61483,61544,61605,61666,61727,\n   61788,61848,61909,61969,62030,62090,62150,62211,\n   62271,62331,62391,62450,62510,62570,62630,62689,\n   62749,62808,62867,62927,62986,63045,63104,63163,\n   63222,63281,63340,63398,63457,63515,63574,63632,\n   63691,63749,63807,63865,63923,63981,64039,64097,\n   64155,64212,64270,64328,64385,64443,64500,64557,\n   64614,64672,64729,64786,64843,64900,64956,65013,\n   65070,65126,65183,65239,65296,65352,65409,65465\n};\n\nconst png_byte png_sRGB_delta[512] =\n{\n   207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54,\n   52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36,\n   35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28,\n   28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24,\n   23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21,\n   21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19,\n   19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17,\n   17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16,\n   16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15,\n   15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14,\n   14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13,\n   13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,\n   12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,\n   12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11,\n   11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,\n   11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,\n   11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,\n   10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,\n   10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,\n   10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,\n   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,\n   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,\n   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,\n   9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,\n   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,\n   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,\n   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,\n   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,\n   8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,\n   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7\n};\n#endif /* SIMPLIFIED READ/WRITE sRGB support */\n\n/* SIMPLIFIED READ/WRITE SUPPORT */\n#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\\\n   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)\nstatic int\npng_image_free_function(png_voidp argument)\n{\n   png_imagep image = png_voidcast(png_imagep, argument);\n   png_controlp cp = image->opaque;\n   png_control c;\n\n   /* Double check that we have a png_ptr - it should be impossible to get here\n    * without one.\n    */\n   if (cp->png_ptr == NULL)\n      return 0;\n\n   /* First free any data held in the control structure. */\n#  ifdef PNG_STDIO_SUPPORTED\n      if (cp->owned_file != 0)\n      {\n         FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr);\n         cp->owned_file = 0;\n\n         /* Ignore errors here. */\n         if (fp != NULL)\n         {\n            cp->png_ptr->io_ptr = NULL;\n            (void)fclose(fp);\n         }\n      }\n#  endif\n\n   /* Copy the control structure so that the original, allocated, version can be\n    * safely freed.  Notice that a png_error here stops the remainder of the\n    * cleanup, but this is probably fine because that would indicate bad memory\n    * problems anyway.\n    */\n   c = *cp;\n   image->opaque = &c;\n   png_free(c.png_ptr, cp);\n\n   /* Then the structures, calling the correct API. */\n   if (c.for_write != 0)\n   {\n#     ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED\n         png_destroy_write_struct(&c.png_ptr, &c.info_ptr);\n#     else\n         png_error(c.png_ptr, \"simplified write not supported\");\n#     endif\n   }\n   else\n   {\n#     ifdef PNG_SIMPLIFIED_READ_SUPPORTED\n         png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL);\n#     else\n         png_error(c.png_ptr, \"simplified read not supported\");\n#     endif\n   }\n\n   /* Success. */\n   return 1;\n}\n\nvoid PNGAPI\npng_image_free(png_imagep image)\n{\n   /* Safely call the real function, but only if doing so is safe at this point\n    * (if not inside an error handling context).  Otherwise assume\n    * png_safe_execute will call this API after the return.\n    */\n   if (image != NULL && image->opaque != NULL &&\n      image->opaque->error_buf == NULL)\n   {\n      /* Ignore errors here: */\n      (void)png_safe_execute(image, png_image_free_function, image);\n      image->opaque = NULL;\n   }\n}\n\nint /* PRIVATE */\npng_image_error(png_imagep image, png_const_charp error_message)\n{\n   /* Utility to log an error. */\n   png_safecat(image->message, (sizeof image->message), 0, error_message);\n   image->warning_or_error |= PNG_IMAGE_ERROR;\n   png_image_free(image);\n   return 0;\n}\n\n#endif /* SIMPLIFIED READ/WRITE */\n#endif /* READ || WRITE */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/png.h",
    "content": "\n/* png.h - header file for PNG reference library\n *\n * libpng version 1.6.22beta03, February 19, 2016\n *\n * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license (See LICENSE, below)\n *\n * Authors and maintainers:\n *   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat\n *   libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger\n *   libpng versions 0.97, January 1998, through 1.6.22beta03, February 19, 2016:\n *     Glenn Randers-Pehrson.\n *   See also \"Contributing Authors\", below.\n */\n\n/*\n * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:\n *\n * If you modify libpng you may insert additional notices immediately following\n * this sentence.\n *\n * This code is released under the libpng license.\n *\n * Some files in the \"contrib\" directory and some configure-generated\n * files that are distributed with libpng have other copyright owners and\n * are released under other open source licenses.\n *\n * libpng versions 1.0.7, July 1, 2000, through 1.6.22beta03, February 19, 2016, are\n * Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are\n * derived from libpng-1.0.6, and are distributed according to the same\n * disclaimer and license as libpng-1.0.6 with the following individuals\n * added to the list of Contributing Authors:\n *\n *    Simon-Pierre Cadieux\n *    Eric S. Raymond\n *    Mans Rullgard\n *    Cosmin Truta\n *    Gilles Vollant\n *    James Yu\n *\n * and with the following additions to the disclaimer:\n *\n *    There is no warranty against interference with your enjoyment of the\n *    library or against infringement.  There is no warranty that our\n *    efforts or the library will fulfill any of your particular purposes\n *    or needs.  This library is provided with all faults, and the entire\n *    risk of satisfactory quality, performance, accuracy, and effort is with\n *    the user.\n *\n * Some files in the \"contrib\" directory have other copyright owners and\n * are released under other open source licenses.\n *\n *\n * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are\n * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from\n * libpng-0.96, and are distributed according to the same disclaimer and\n * license as libpng-0.96, with the following individuals added to the list\n * of Contributing Authors:\n *\n *    Tom Lane\n *    Glenn Randers-Pehrson\n *    Willem van Schaik\n *\n * Some files in the \"scripts\" directory have different copyright owners\n * but are also released under this license.\n *\n * libpng versions 0.89, June 1996, through 0.96, May 1997, are\n * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,\n * and are distributed according to the same disclaimer and license as\n * libpng-0.88, with the following individuals added to the list of\n * Contributing Authors:\n *\n *    John Bowler\n *    Kevin Bracey\n *    Sam Bushell\n *    Magnus Holmgren\n *    Greg Roelofs\n *    Tom Tanner\n *\n * Some files in the \"scripts\" directory have other copyright owners\n * but are released under this license.\n *\n * libpng versions 0.5, May 1995, through 0.88, January 1996, are\n * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n *\n * For the purposes of this copyright and license, \"Contributing Authors\"\n * is defined as the following set of individuals:\n *\n *    Andreas Dilger\n *    Dave Martindale\n *    Guy Eric Schalnat\n *    Paul Schmidt\n *    Tim Wegner\n *\n * The PNG Reference Library is supplied \"AS IS\".  The Contributing Authors\n * and Group 42, Inc. disclaim all warranties, expressed or implied,\n * including, without limitation, the warranties of merchantability and of\n * fitness for any purpose.  The Contributing Authors and Group 42, Inc.\n * assume no liability for direct, indirect, incidental, special, exemplary,\n * or consequential damages, which may result from the use of the PNG\n * Reference Library, even if advised of the possibility of such damage.\n *\n * Permission is hereby granted to use, copy, modify, and distribute this\n * source code, or portions hereof, for any purpose, without fee, subject\n * to the following restrictions:\n *\n *   1. The origin of this source code must not be misrepresented.\n *\n *   2. Altered versions must be plainly marked as such and must not\n *      be misrepresented as being the original source.\n *\n *   3. This Copyright notice may not be removed or altered from any\n *      source or altered source distribution.\n *\n * The Contributing Authors and Group 42, Inc. specifically permit, without\n * fee, and encourage the use of this source code as a component to\n * supporting the PNG file format in commercial products.  If you use this\n * source code in a product, acknowledgment is not required but would be\n * appreciated.\n *\n * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.\n *\n * TRADEMARK:\n *\n * The name \"libpng\" has not been registered by the Copyright owner\n * as a trademark in any jurisdiction.  However, because libpng has\n * been distributed and maintained world-wide, continually since 1995,\n * the Copyright owner claims \"common-law trademark protection\" in any\n * jurisdiction where common-law trademark is recognized.\n *\n * OSI CERTIFICATION:\n *\n * Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is\n * a certification mark of the Open Source Initiative. OSI has not addressed\n * the additional disclaimers inserted at version 1.0.7.\n *\n * EXPORT CONTROL:\n *\n * The Copyright owner believes that the Export Control Classification\n * Number (ECCN) for libpng is EAR99, which means not subject to export\n * controls or International Traffic in Arms Regulations (ITAR) because\n * it is open source, publicly available software, that does not contain\n * any encryption software.  See the EAR, paragraphs 734.3(b)(3) and\n * 734.7(b).\n */\n\n/*\n * A \"png_get_copyright\" function is available, for convenient use in \"about\"\n * boxes and the like:\n *\n *    printf(\"%s\", png_get_copyright(NULL));\n *\n * Also, the PNG logo (in PNG format, of course) is supplied in the\n * files \"pngbar.png\" and \"pngbar.jpg (88x31) and \"pngnow.png\" (98x31).\n */\n\n/*\n * The contributing authors would like to thank all those who helped\n * with testing, bug fixes, and patience.  This wouldn't have been\n * possible without all of you.\n *\n * Thanks to Frank J. T. Wojcik for helping with the documentation.\n */\n\n/* Note about libpng version numbers:\n *\n *    Due to various miscommunications, unforeseen code incompatibilities\n *    and occasional factors outside the authors' control, version numbering\n *    on the library has not always been consistent and straightforward.\n *    The following table summarizes matters since version 0.89c, which was\n *    the first widely used release:\n *\n *    source                 png.h  png.h  shared-lib\n *    version                string   int  version\n *    -------                ------ -----  ----------\n *    0.89c \"1.0 beta 3\"     0.89      89  1.0.89\n *    0.90  \"1.0 beta 4\"     0.90      90  0.90  [should have been 2.0.90]\n *    0.95  \"1.0 beta 5\"     0.95      95  0.95  [should have been 2.0.95]\n *    0.96  \"1.0 beta 6\"     0.96      96  0.96  [should have been 2.0.96]\n *    0.97b \"1.00.97 beta 7\" 1.00.97   97  1.0.1 [should have been 2.0.97]\n *    0.97c                  0.97      97  2.0.97\n *    0.98                   0.98      98  2.0.98\n *    0.99                   0.99      98  2.0.99\n *    0.99a-m                0.99      99  2.0.99\n *    1.00                   1.00     100  2.1.0 [100 should be 10000]\n *    1.0.0      (from here on, the   100  2.1.0 [100 should be 10000]\n *    1.0.1       png.h string is   10001  2.1.0\n *    1.0.1a-e    identical to the  10002  from here on, the shared library\n *    1.0.2       source version)   10002  is 2.V where V is the source code\n *    1.0.2a-b                      10003  version, except as noted.\n *    1.0.3                         10003\n *    1.0.3a-d                      10004\n *    1.0.4                         10004\n *    1.0.4a-f                      10005\n *    1.0.5 (+ 2 patches)           10005\n *    1.0.5a-d                      10006\n *    1.0.5e-r                      10100 (not source compatible)\n *    1.0.5s-v                      10006 (not binary compatible)\n *    1.0.6 (+ 3 patches)           10006 (still binary incompatible)\n *    1.0.6d-f                      10007 (still binary incompatible)\n *    1.0.6g                        10007\n *    1.0.6h                        10007  10.6h (testing xy.z so-numbering)\n *    1.0.6i                        10007  10.6i\n *    1.0.6j                        10007  2.1.0.6j (incompatible with 1.0.0)\n *    1.0.7beta11-14        DLLNUM  10007  2.1.0.7beta11-14 (binary compatible)\n *    1.0.7beta15-18           1    10007  2.1.0.7beta15-18 (binary compatible)\n *    1.0.7rc1-2               1    10007  2.1.0.7rc1-2 (binary compatible)\n *    1.0.7                    1    10007  (still compatible)\n *    ...\n *    1.0.19                  10    10019  10.so.0.19[.0]\n *    ...\n *    1.2.53                  13    10253  12.so.0.53[.0]\n *    ...\n *    1.5.23                  15    10523  15.so.15.23[.0]\n *    ...\n *    1.6.22                  16    10622  16.so.16.22[.0]\n *\n *    Henceforth the source version will match the shared-library major\n *    and minor numbers; the shared-library major version number will be\n *    used for changes in backward compatibility, as it is intended.  The\n *    PNG_LIBPNG_VER macro, which is not used within libpng but is available\n *    for applications, is an unsigned integer of the form xyyzz corresponding\n *    to the source version x.y.z (leading zeros in y and z).  Beta versions\n *    were given the previous public release number plus a letter, until\n *    version 1.0.6j; from then on they were given the upcoming public\n *    release number plus \"betaNN\" or \"rcNN\".\n *\n *    Binary incompatibility exists only when applications make direct access\n *    to the info_ptr or png_ptr members through png.h, and the compiled\n *    application is loaded with a different version of the library.\n *\n *    DLLNUM will change each time there are forward or backward changes\n *    in binary compatibility (e.g., when a new feature is added).\n *\n * See libpng.txt or libpng.3 for more information.  The PNG specification\n * is available as a W3C Recommendation and as an ISO Specification,\n * <http://www.w3.org/TR/2003/REC-PNG-20031110/\n */\n\n/*\n * Y2K compliance in libpng:\n * =========================\n *\n *    February 19, 2016\n *\n *    Since the PNG Development group is an ad-hoc body, we can't make\n *    an official declaration.\n *\n *    This is your unofficial assurance that libpng from version 0.71 and\n *    upward through 1.6.22beta03 are Y2K compliant.  It is my belief that\n *    earlier versions were also Y2K compliant.\n *\n *    Libpng only has two year fields.  One is a 2-byte unsigned integer\n *    that will hold years up to 65535.  The other, which is deprecated,\n *    holds the date in text format, and will hold years up to 9999.\n *\n *    The integer is\n *        \"png_uint_16 year\" in png_time_struct.\n *\n *    The string is\n *        \"char time_buffer[29]\" in png_struct.  This is no longer used\n *    in libpng-1.6.x and will be removed from libpng-1.7.0.\n *\n *    There are seven time-related functions:\n *        png.c: png_convert_to_rfc_1123_buffer() in png.c\n *          (formerly png_convert_to_rfc_1123() prior to libpng-1.5.x and\n *          png_convert_to_rfc_1152() in error prior to libpng-0.98)\n *        png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c\n *        png_convert_from_time_t() in pngwrite.c\n *        png_get_tIME() in pngget.c\n *        png_handle_tIME() in pngrutil.c, called in pngread.c\n *        png_set_tIME() in pngset.c\n *        png_write_tIME() in pngwutil.c, called in pngwrite.c\n *\n *    All handle dates properly in a Y2K environment.  The\n *    png_convert_from_time_t() function calls gmtime() to convert from system\n *    clock time, which returns (year - 1900), which we properly convert to\n *    the full 4-digit year.  There is a possibility that libpng applications\n *    are not passing 4-digit years into the png_convert_to_rfc_1123_buffer()\n *    function, or that they are incorrectly passing only a 2-digit year\n *    instead of \"year - 1900\" into the png_convert_from_struct_tm() function,\n *    but this is not under our control.  The libpng documentation has always\n *    stated that it works with 4-digit years, and the APIs have been\n *    documented as such.\n *\n *    The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned\n *    integer to hold the year, and can hold years as large as 65535.\n *\n *    zlib, upon which libpng depends, is also Y2K compliant.  It contains\n *    no date-related code.\n *\n *       Glenn Randers-Pehrson\n *       libpng maintainer\n *       PNG Development Group\n */\n\n#ifndef PNG_H\n#define PNG_H\n\n/* This is not the place to learn how to use libpng. The file libpng-manual.txt\n * describes how to use libpng, and the file example.c summarizes it\n * with some code on which to build.  This file is useful for looking\n * at the actual function definitions and structure components.  If that\n * file has been stripped from your copy of libpng, you can find it at\n * <http://www.libpng.org/pub/png/libpng-manual.txt>\n *\n * If you just need to read a PNG file and don't want to read the documentation\n * skip to the end of this file and read the section entitled 'simplified API'.\n */\n\n/* Version information for png.h - this should match the version in png.c */\n#define PNG_LIBPNG_VER_STRING \"1.6.22beta03\"\n#define PNG_HEADER_VERSION_STRING \\\n     \" libpng version 1.6.22beta03 - February 19, 2016\\n\"\n\n#define PNG_LIBPNG_VER_SONUM   16\n#define PNG_LIBPNG_VER_DLLNUM  16\n\n/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */\n#define PNG_LIBPNG_VER_MAJOR   1\n#define PNG_LIBPNG_VER_MINOR   6\n#define PNG_LIBPNG_VER_RELEASE 22\n\n/* This should match the numeric part of the final component of\n * PNG_LIBPNG_VER_STRING, omitting any leading zero:\n */\n\n#define PNG_LIBPNG_VER_BUILD  03\n\n/* Release Status */\n#define PNG_LIBPNG_BUILD_ALPHA    1\n#define PNG_LIBPNG_BUILD_BETA     2\n#define PNG_LIBPNG_BUILD_RC       3\n#define PNG_LIBPNG_BUILD_STABLE   4\n#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7\n\n/* Release-Specific Flags */\n#define PNG_LIBPNG_BUILD_PATCH    8 /* Can be OR'ed with\n                                       PNG_LIBPNG_BUILD_STABLE only */\n#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with\n                                       PNG_LIBPNG_BUILD_SPECIAL */\n#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with\n                                       PNG_LIBPNG_BUILD_PRIVATE */\n\n#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_BETA\n\n/* Careful here.  At one time, Guy wanted to use 082, but that would be octal.\n * We must not include leading zeros.\n * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only\n * version 1.0.0 was mis-numbered 100 instead of 10000).  From\n * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=release\n */\n#define PNG_LIBPNG_VER 10622 /* 1.6.22 */\n\n/* Library configuration: these options cannot be changed after\n * the library has been built.\n */\n#ifndef PNGLCONF_H\n    /* If pnglibconf.h is missing, you can\n     * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h\n     */\n#   include \"pnglibconf.h\"\n#endif\n\n#ifndef PNG_VERSION_INFO_ONLY\n   /* Machine specific configuration. */\n#  include \"pngconf.h\"\n#endif\n\n/*\n * Added at libpng-1.2.8\n *\n * Ref MSDN: Private as priority over Special\n * VS_FF_PRIVATEBUILD File *was not* built using standard release\n * procedures. If this value is given, the StringFileInfo block must\n * contain a PrivateBuild string.\n *\n * VS_FF_SPECIALBUILD File *was* built by the original company using\n * standard release procedures but is a variation of the standard\n * file of the same version number. If this value is given, the\n * StringFileInfo block must contain a SpecialBuild string.\n */\n\n#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */\n#  define PNG_LIBPNG_BUILD_TYPE \\\n       (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE)\n#else\n#  ifdef PNG_LIBPNG_SPECIALBUILD\n#    define PNG_LIBPNG_BUILD_TYPE \\\n         (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL)\n#  else\n#    define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE)\n#  endif\n#endif\n\n#ifndef PNG_VERSION_INFO_ONLY\n\n/* Inhibit C++ name-mangling for libpng functions but not for system calls. */\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/* Version information for C files, stored in png.c.  This had better match\n * the version above.\n */\n#define png_libpng_ver png_get_header_ver(NULL)\n\n/* This file is arranged in several sections:\n *\n * 1. [omitted]\n * 2. Any configuration options that can be specified by for the application\n *    code when it is built.  (Build time configuration is in pnglibconf.h)\n * 3. Type definitions (base types are defined in pngconf.h), structure\n *    definitions.\n * 4. Exported library functions.\n * 5. Simplified API.\n * 6. Implementation options.\n *\n * The library source code has additional files (principally pngpriv.h) that\n * allow configuration of the library.\n */\n\n/* Section 1: [omitted] */\n\n/* Section 2: run time configuration\n * See pnglibconf.h for build time configuration\n *\n * Run time configuration allows the application to choose between\n * implementations of certain arithmetic APIs.  The default is set\n * at build time and recorded in pnglibconf.h, but it is safe to\n * override these (and only these) settings.  Note that this won't\n * change what the library does, only application code, and the\n * settings can (and probably should) be made on a per-file basis\n * by setting the #defines before including png.h\n *\n * Use macros to read integers from PNG data or use the exported\n * functions?\n *   PNG_USE_READ_MACROS: use the macros (see below)  Note that\n *     the macros evaluate their argument multiple times.\n *   PNG_NO_USE_READ_MACROS: call the relevant library function.\n *\n * Use the alternative algorithm for compositing alpha samples that\n * does not use division?\n *   PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division'\n *      algorithm.\n *   PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm.\n *\n * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is\n * false?\n *   PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error\n *      APIs to png_warning.\n * Otherwise the calls are mapped to png_error.\n */\n\n/* Section 3: type definitions, including structures and compile time\n * constants.\n * See pngconf.h for base types that vary by machine/system\n */\n\n/* This triggers a compiler error in png.c, if png.c and png.h\n * do not agree upon the version number.\n */\ntypedef char* png_libpng_version_1_6_22beta03;\n\n/* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.\n *\n * png_struct is the cache of information used while reading or writing a single\n * PNG file.  One of these is always required, although the simplified API\n * (below) hides the creation and destruction of it.\n */\ntypedef struct png_struct_def png_struct;\ntypedef const png_struct * png_const_structp;\ntypedef png_struct * png_structp;\ntypedef png_struct * * png_structpp;\n\n/* png_info contains information read from or to be written to a PNG file.  One\n * or more of these must exist while reading or creating a PNG file.  The\n * information is not used by libpng during read but is used to control what\n * gets written when a PNG file is created.  \"png_get_\" function calls read\n * information during read and \"png_set_\" functions calls write information\n * when creating a PNG.\n * been moved into a separate header file that is not accessible to\n * applications.  Read libpng-manual.txt or libpng.3 for more info.\n */\ntypedef struct png_info_def png_info;\ntypedef png_info * png_infop;\ntypedef const png_info * png_const_infop;\ntypedef png_info * * png_infopp;\n\n/* Types with names ending 'p' are pointer types.  The corresponding types with\n * names ending 'rp' are identical pointer types except that the pointer is\n * marked 'restrict', which means that it is the only pointer to the object\n * passed to the function.  Applications should not use the 'restrict' types;\n * it is always valid to pass 'p' to a pointer with a function argument of the\n * corresponding 'rp' type.  Different compilers have different rules with\n * regard to type matching in the presence of 'restrict'.  For backward\n * compatibility libpng callbacks never have 'restrict' in their parameters and,\n * consequentially, writing portable application code is extremely difficult if\n * an attempt is made to use 'restrict'.\n */\ntypedef png_struct * PNG_RESTRICT png_structrp;\ntypedef const png_struct * PNG_RESTRICT png_const_structrp;\ntypedef png_info * PNG_RESTRICT png_inforp;\ntypedef const png_info * PNG_RESTRICT png_const_inforp;\n\n/* Three color definitions.  The order of the red, green, and blue, (and the\n * exact size) is not important, although the size of the fields need to\n * be png_byte or png_uint_16 (as defined below).\n */\ntypedef struct png_color_struct\n{\n   png_byte red;\n   png_byte green;\n   png_byte blue;\n} png_color;\ntypedef png_color * png_colorp;\ntypedef const png_color * png_const_colorp;\ntypedef png_color * * png_colorpp;\n\ntypedef struct png_color_16_struct\n{\n   png_byte index;    /* used for palette files */\n   png_uint_16 red;   /* for use in red green blue files */\n   png_uint_16 green;\n   png_uint_16 blue;\n   png_uint_16 gray;  /* for use in grayscale files */\n} png_color_16;\ntypedef png_color_16 * png_color_16p;\ntypedef const png_color_16 * png_const_color_16p;\ntypedef png_color_16 * * png_color_16pp;\n\ntypedef struct png_color_8_struct\n{\n   png_byte red;   /* for use in red green blue files */\n   png_byte green;\n   png_byte blue;\n   png_byte gray;  /* for use in grayscale files */\n   png_byte alpha; /* for alpha channel files */\n} png_color_8;\ntypedef png_color_8 * png_color_8p;\ntypedef const png_color_8 * png_const_color_8p;\ntypedef png_color_8 * * png_color_8pp;\n\n/*\n * The following two structures are used for the in-core representation\n * of sPLT chunks.\n */\ntypedef struct png_sPLT_entry_struct\n{\n   png_uint_16 red;\n   png_uint_16 green;\n   png_uint_16 blue;\n   png_uint_16 alpha;\n   png_uint_16 frequency;\n} png_sPLT_entry;\ntypedef png_sPLT_entry * png_sPLT_entryp;\ntypedef const png_sPLT_entry * png_const_sPLT_entryp;\ntypedef png_sPLT_entry * * png_sPLT_entrypp;\n\n/*  When the depth of the sPLT palette is 8 bits, the color and alpha samples\n *  occupy the LSB of their respective members, and the MSB of each member\n *  is zero-filled.  The frequency member always occupies the full 16 bits.\n */\n\ntypedef struct png_sPLT_struct\n{\n   png_charp name;           /* palette name */\n   png_byte depth;           /* depth of palette samples */\n   png_sPLT_entryp entries;  /* palette entries */\n   png_int_32 nentries;      /* number of palette entries */\n} png_sPLT_t;\ntypedef png_sPLT_t * png_sPLT_tp;\ntypedef const png_sPLT_t * png_const_sPLT_tp;\ntypedef png_sPLT_t * * png_sPLT_tpp;\n\n#ifdef PNG_TEXT_SUPPORTED\n/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,\n * and whether that contents is compressed or not.  The \"key\" field\n * points to a regular zero-terminated C string.  The \"text\" fields can be a\n * regular C string, an empty string, or a NULL pointer.\n * However, the structure returned by png_get_text() will always contain\n * the \"text\" field as a regular zero-terminated C string (possibly\n * empty), never a NULL pointer, so it can be safely used in printf() and\n * other string-handling functions.  Note that the \"itxt_length\", \"lang\", and\n * \"lang_key\" members of the structure only exist when the library is built\n * with iTXt chunk support.  Prior to libpng-1.4.0 the library was built by\n * default without iTXt support. Also note that when iTXt *is* supported,\n * the \"lang\" and \"lang_key\" fields contain NULL pointers when the\n * \"compression\" field contains * PNG_TEXT_COMPRESSION_NONE or\n * PNG_TEXT_COMPRESSION_zTXt. Note that the \"compression value\" is not the\n * same as what appears in the PNG tEXt/zTXt/iTXt chunk's \"compression flag\"\n * which is always 0 or 1, or its \"compression method\" which is always 0.\n */\ntypedef struct png_text_struct\n{\n   int  compression;       /* compression value:\n                             -1: tEXt, none\n                              0: zTXt, deflate\n                              1: iTXt, none\n                              2: iTXt, deflate  */\n   png_charp key;          /* keyword, 1-79 character description of \"text\" */\n   png_charp text;         /* comment, may be an empty string (ie \"\")\n                              or a NULL pointer */\n   png_size_t text_length; /* length of the text string */\n   png_size_t itxt_length; /* length of the itxt string */\n   png_charp lang;         /* language code, 0-79 characters\n                              or a NULL pointer */\n   png_charp lang_key;     /* keyword translated UTF-8 string, 0 or more\n                              chars or a NULL pointer */\n} png_text;\ntypedef png_text * png_textp;\ntypedef const png_text * png_const_textp;\ntypedef png_text * * png_textpp;\n#endif\n\n/* Supported compression types for text in PNG files (tEXt, and zTXt).\n * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */\n#define PNG_TEXT_COMPRESSION_NONE_WR -3\n#define PNG_TEXT_COMPRESSION_zTXt_WR -2\n#define PNG_TEXT_COMPRESSION_NONE    -1\n#define PNG_TEXT_COMPRESSION_zTXt     0\n#define PNG_ITXT_COMPRESSION_NONE     1\n#define PNG_ITXT_COMPRESSION_zTXt     2\n#define PNG_TEXT_COMPRESSION_LAST     3  /* Not a valid value */\n\n/* png_time is a way to hold the time in an machine independent way.\n * Two conversions are provided, both from time_t and struct tm.  There\n * is no portable way to convert to either of these structures, as far\n * as I know.  If you know of a portable way, send it to me.  As a side\n * note - PNG has always been Year 2000 compliant!\n */\ntypedef struct png_time_struct\n{\n   png_uint_16 year; /* full year, as in, 1995 */\n   png_byte month;   /* month of year, 1 - 12 */\n   png_byte day;     /* day of month, 1 - 31 */\n   png_byte hour;    /* hour of day, 0 - 23 */\n   png_byte minute;  /* minute of hour, 0 - 59 */\n   png_byte second;  /* second of minute, 0 - 60 (for leap seconds) */\n} png_time;\ntypedef png_time * png_timep;\ntypedef const png_time * png_const_timep;\ntypedef png_time * * png_timepp;\n\n#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\\\n   defined(PNG_USER_CHUNKS_SUPPORTED)\n/* png_unknown_chunk is a structure to hold queued chunks for which there is\n * no specific support.  The idea is that we can use this to queue\n * up private chunks for output even though the library doesn't actually\n * know about their semantics.\n *\n * The data in the structure is set by libpng on read and used on write.\n */\ntypedef struct png_unknown_chunk_t\n{\n    png_byte name[5]; /* Textual chunk name with '\\0' terminator */\n    png_byte *data;   /* Data, should not be modified on read! */\n    png_size_t size;\n\n    /* On write 'location' must be set using the flag values listed below.\n     * Notice that on read it is set by libpng however the values stored have\n     * more bits set than are listed below.  Always treat the value as a\n     * bitmask.  On write set only one bit - setting multiple bits may cause the\n     * chunk to be written in multiple places.\n     */\n    png_byte location; /* mode of operation at read time */\n}\npng_unknown_chunk;\n\ntypedef png_unknown_chunk * png_unknown_chunkp;\ntypedef const png_unknown_chunk * png_const_unknown_chunkp;\ntypedef png_unknown_chunk * * png_unknown_chunkpp;\n#endif\n\n/* Flag values for the unknown chunk location byte. */\n#define PNG_HAVE_IHDR  0x01\n#define PNG_HAVE_PLTE  0x02\n#define PNG_AFTER_IDAT 0x08\n\n/* Maximum positive integer used in PNG is (2^31)-1 */\n#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)\n#define PNG_UINT_32_MAX ((png_uint_32)(-1))\n#define PNG_SIZE_MAX ((png_size_t)(-1))\n\n/* These are constants for fixed point values encoded in the\n * PNG specification manner (x100000)\n */\n#define PNG_FP_1    100000\n#define PNG_FP_HALF  50000\n#define PNG_FP_MAX  ((png_fixed_point)0x7fffffffL)\n#define PNG_FP_MIN  (-PNG_FP_MAX)\n\n/* These describe the color_type field in png_info. */\n/* color type masks */\n#define PNG_COLOR_MASK_PALETTE    1\n#define PNG_COLOR_MASK_COLOR      2\n#define PNG_COLOR_MASK_ALPHA      4\n\n/* color types.  Note that not all combinations are legal */\n#define PNG_COLOR_TYPE_GRAY 0\n#define PNG_COLOR_TYPE_PALETTE  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)\n#define PNG_COLOR_TYPE_RGB        (PNG_COLOR_MASK_COLOR)\n#define PNG_COLOR_TYPE_RGB_ALPHA  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)\n#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)\n/* aliases */\n#define PNG_COLOR_TYPE_RGBA  PNG_COLOR_TYPE_RGB_ALPHA\n#define PNG_COLOR_TYPE_GA  PNG_COLOR_TYPE_GRAY_ALPHA\n\n/* This is for compression type. PNG 1.0-1.2 only define the single type. */\n#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */\n#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE\n\n/* This is for filter type. PNG 1.0-1.2 only define the single type. */\n#define PNG_FILTER_TYPE_BASE      0 /* Single row per-byte filtering */\n#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */\n#define PNG_FILTER_TYPE_DEFAULT   PNG_FILTER_TYPE_BASE\n\n/* These are for the interlacing type.  These values should NOT be changed. */\n#define PNG_INTERLACE_NONE        0 /* Non-interlaced image */\n#define PNG_INTERLACE_ADAM7       1 /* Adam7 interlacing */\n#define PNG_INTERLACE_LAST        2 /* Not a valid value */\n\n/* These are for the oFFs chunk.  These values should NOT be changed. */\n#define PNG_OFFSET_PIXEL          0 /* Offset in pixels */\n#define PNG_OFFSET_MICROMETER     1 /* Offset in micrometers (1/10^6 meter) */\n#define PNG_OFFSET_LAST           2 /* Not a valid value */\n\n/* These are for the pCAL chunk.  These values should NOT be changed. */\n#define PNG_EQUATION_LINEAR       0 /* Linear transformation */\n#define PNG_EQUATION_BASE_E       1 /* Exponential base e transform */\n#define PNG_EQUATION_ARBITRARY    2 /* Arbitrary base exponential transform */\n#define PNG_EQUATION_HYPERBOLIC   3 /* Hyperbolic sine transformation */\n#define PNG_EQUATION_LAST         4 /* Not a valid value */\n\n/* These are for the sCAL chunk.  These values should NOT be changed. */\n#define PNG_SCALE_UNKNOWN         0 /* unknown unit (image scale) */\n#define PNG_SCALE_METER           1 /* meters per pixel */\n#define PNG_SCALE_RADIAN          2 /* radians per pixel */\n#define PNG_SCALE_LAST            3 /* Not a valid value */\n\n/* These are for the pHYs chunk.  These values should NOT be changed. */\n#define PNG_RESOLUTION_UNKNOWN    0 /* pixels/unknown unit (aspect ratio) */\n#define PNG_RESOLUTION_METER      1 /* pixels/meter */\n#define PNG_RESOLUTION_LAST       2 /* Not a valid value */\n\n/* These are for the sRGB chunk.  These values should NOT be changed. */\n#define PNG_sRGB_INTENT_PERCEPTUAL 0\n#define PNG_sRGB_INTENT_RELATIVE   1\n#define PNG_sRGB_INTENT_SATURATION 2\n#define PNG_sRGB_INTENT_ABSOLUTE   3\n#define PNG_sRGB_INTENT_LAST       4 /* Not a valid value */\n\n/* This is for text chunks */\n#define PNG_KEYWORD_MAX_LENGTH     79\n\n/* Maximum number of entries in PLTE/sPLT/tRNS arrays */\n#define PNG_MAX_PALETTE_LENGTH    256\n\n/* These determine if an ancillary chunk's data has been successfully read\n * from the PNG header, or if the application has filled in the corresponding\n * data in the info_struct to be written into the output file.  The values\n * of the PNG_INFO_<chunk> defines should NOT be changed.\n */\n#define PNG_INFO_gAMA 0x0001U\n#define PNG_INFO_sBIT 0x0002U\n#define PNG_INFO_cHRM 0x0004U\n#define PNG_INFO_PLTE 0x0008U\n#define PNG_INFO_tRNS 0x0010U\n#define PNG_INFO_bKGD 0x0020U\n#define PNG_INFO_hIST 0x0040U\n#define PNG_INFO_pHYs 0x0080U\n#define PNG_INFO_oFFs 0x0100U\n#define PNG_INFO_tIME 0x0200U\n#define PNG_INFO_pCAL 0x0400U\n#define PNG_INFO_sRGB 0x0800U  /* GR-P, 0.96a */\n#define PNG_INFO_iCCP 0x1000U  /* ESR, 1.0.6 */\n#define PNG_INFO_sPLT 0x2000U  /* ESR, 1.0.6 */\n#define PNG_INFO_sCAL 0x4000U  /* ESR, 1.0.6 */\n#define PNG_INFO_IDAT 0x8000U  /* ESR, 1.0.6 */\n\n/* This is used for the transformation routines, as some of them\n * change these values for the row.  It also should enable using\n * the routines for other purposes.\n */\ntypedef struct png_row_info_struct\n{\n   png_uint_32 width;    /* width of row */\n   png_size_t rowbytes;  /* number of bytes in row */\n   png_byte color_type;  /* color type of row */\n   png_byte bit_depth;   /* bit depth of row */\n   png_byte channels;    /* number of channels (1, 2, 3, or 4) */\n   png_byte pixel_depth; /* bits per pixel (depth * channels) */\n} png_row_info;\n\ntypedef png_row_info * png_row_infop;\ntypedef png_row_info * * png_row_infopp;\n\n/* These are the function types for the I/O functions and for the functions\n * that allow the user to override the default I/O functions with his or her\n * own.  The png_error_ptr type should match that of user-supplied warning\n * and error functions, while the png_rw_ptr type should match that of the\n * user read/write data functions.  Note that the 'write' function must not\n * modify the buffer it is passed. The 'read' function, on the other hand, is\n * expected to return the read data in the buffer.\n */\ntypedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp));\ntypedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t));\ntypedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp));\ntypedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32,\n    int));\ntypedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32,\n    int));\n\n#ifdef PNG_PROGRESSIVE_READ_SUPPORTED\ntypedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));\ntypedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));\n\n/* The following callback receives png_uint_32 row_number, int pass for the\n * png_bytep data of the row.  When transforming an interlaced image the\n * row number is the row number within the sub-image of the interlace pass, so\n * the value will increase to the height of the sub-image (not the full image)\n * then reset to 0 for the next pass.\n *\n * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to\n * find the output pixel (x,y) given an interlaced sub-image pixel\n * (row,col,pass).  (See below for these macros.)\n */\ntypedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep,\n    png_uint_32, int));\n#endif\n\n#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \\\n    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)\ntypedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop,\n    png_bytep));\n#endif\n\n#ifdef PNG_USER_CHUNKS_SUPPORTED\ntypedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp,\n    png_unknown_chunkp));\n#endif\n#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED\n/* not used anywhere */\n/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */\n#endif\n\n#ifdef PNG_SETJMP_SUPPORTED\n/* This must match the function definition in <setjmp.h>, and the application\n * must include this before png.h to obtain the definition of jmp_buf.  The\n * function is required to be PNG_NORETURN, but this is not checked.  If the\n * function does return the application will crash via an abort() or similar\n * system level call.\n *\n * If you get a warning here while building the library you may need to make\n * changes to ensure that pnglibconf.h records the calling convention used by\n * your compiler.  This may be very difficult - try using a different compiler\n * to build the library!\n */\nPNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef);\n#endif\n\n/* Transform masks for the high-level interface */\n#define PNG_TRANSFORM_IDENTITY       0x0000    /* read and write */\n#define PNG_TRANSFORM_STRIP_16       0x0001    /* read only */\n#define PNG_TRANSFORM_STRIP_ALPHA    0x0002    /* read only */\n#define PNG_TRANSFORM_PACKING        0x0004    /* read and write */\n#define PNG_TRANSFORM_PACKSWAP       0x0008    /* read and write */\n#define PNG_TRANSFORM_EXPAND         0x0010    /* read only */\n#define PNG_TRANSFORM_INVERT_MONO    0x0020    /* read and write */\n#define PNG_TRANSFORM_SHIFT          0x0040    /* read and write */\n#define PNG_TRANSFORM_BGR            0x0080    /* read and write */\n#define PNG_TRANSFORM_SWAP_ALPHA     0x0100    /* read and write */\n#define PNG_TRANSFORM_SWAP_ENDIAN    0x0200    /* read and write */\n#define PNG_TRANSFORM_INVERT_ALPHA   0x0400    /* read and write */\n#define PNG_TRANSFORM_STRIP_FILLER   0x0800    /* write only */\n/* Added to libpng-1.2.34 */\n#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER\n#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */\n/* Added to libpng-1.4.0 */\n#define PNG_TRANSFORM_GRAY_TO_RGB   0x2000      /* read only */\n/* Added to libpng-1.5.4 */\n#define PNG_TRANSFORM_EXPAND_16     0x4000      /* read only */\n#if INT_MAX >= 0x8000 /* else this might break */\n#define PNG_TRANSFORM_SCALE_16      0x8000      /* read only */\n#endif\n\n/* Flags for MNG supported features */\n#define PNG_FLAG_MNG_EMPTY_PLTE     0x01\n#define PNG_FLAG_MNG_FILTER_64      0x04\n#define PNG_ALL_MNG_FEATURES        0x05\n\n/* NOTE: prior to 1.5 these functions had no 'API' style declaration,\n * this allowed the zlib default functions to be used on Windows\n * platforms.  In 1.5 the zlib default malloc (which just calls malloc and\n * ignores the first argument) should be completely compatible with the\n * following.\n */\ntypedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp,\n    png_alloc_size_t));\ntypedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp));\n\n/* Section 4: exported functions\n * Here are the function definitions most commonly used.  This is not\n * the place to find out how to use libpng.  See libpng-manual.txt for the\n * full explanation, see example.c for the summary.  This just provides\n * a simple one line description of the use of each function.\n *\n * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in\n * pngconf.h and in the *.dfn files in the scripts directory.\n *\n *   PNG_EXPORT(ordinal, type, name, (args));\n *\n *       ordinal:    ordinal that is used while building\n *                   *.def files. The ordinal value is only\n *                   relevant when preprocessing png.h with\n *                   the *.dfn files for building symbol table\n *                   entries, and are removed by pngconf.h.\n *       type:       return type of the function\n *       name:       function name\n *       args:       function arguments, with types\n *\n * When we wish to append attributes to a function prototype we use\n * the PNG_EXPORTA() macro instead.\n *\n *   PNG_EXPORTA(ordinal, type, name, (args), attributes);\n *\n *       ordinal, type, name, and args: same as in PNG_EXPORT().\n *       attributes: function attributes\n */\n\n/* Returns the version number of the library */\nPNG_EXPORT(1, png_uint_32, png_access_version_number, (void));\n\n/* Tell lib we have already handled the first <num_bytes> magic bytes.\n * Handling more than 8 bytes from the beginning of the file is an error.\n */\nPNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes));\n\n/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a\n * PNG file.  Returns zero if the supplied bytes match the 8-byte PNG\n * signature, and non-zero otherwise.  Having num_to_check == 0 or\n * start > 7 will always fail (ie return non-zero).\n */\nPNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start,\n    png_size_t num_to_check));\n\n/* Simple signature checking function.  This is the same as calling\n * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).\n */\n#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n))\n\n/* Allocate and initialize png_ptr struct for reading, and any other memory. */\nPNG_EXPORTA(4, png_structp, png_create_read_struct,\n    (png_const_charp user_png_ver, png_voidp error_ptr,\n    png_error_ptr error_fn, png_error_ptr warn_fn),\n    PNG_ALLOCATED);\n\n/* Allocate and initialize png_ptr struct for writing, and any other memory */\nPNG_EXPORTA(5, png_structp, png_create_write_struct,\n    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,\n    png_error_ptr warn_fn),\n    PNG_ALLOCATED);\n\nPNG_EXPORT(6, png_size_t, png_get_compression_buffer_size,\n    (png_const_structrp png_ptr));\n\nPNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr,\n    png_size_t size));\n\n/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp\n * match up.\n */\n#ifdef PNG_SETJMP_SUPPORTED\n/* This function returns the jmp_buf built in to *png_ptr.  It must be\n * supplied with an appropriate 'longjmp' function to use on that jmp_buf\n * unless the default error function is overridden in which case NULL is\n * acceptable.  The size of the jmp_buf is checked against the actual size\n * allocated by the library - the call will return NULL on a mismatch\n * indicating an ABI mismatch.\n */\nPNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr,\n    png_longjmp_ptr longjmp_fn, size_t jmp_buf_size));\n#  define png_jmpbuf(png_ptr) \\\n      (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf))))\n#else\n#  define png_jmpbuf(png_ptr) \\\n      (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP)\n#endif\n/* This function should be used by libpng applications in place of\n * longjmp(png_ptr->jmpbuf, val).  If longjmp_fn() has been set, it\n * will use it; otherwise it will call PNG_ABORT().  This function was\n * added in libpng-1.5.0.\n */\nPNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val),\n    PNG_NORETURN);\n\n#ifdef PNG_READ_SUPPORTED\n/* Reset the compression stream */\nPNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED);\n#endif\n\n/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */\n#ifdef PNG_USER_MEM_SUPPORTED\nPNG_EXPORTA(11, png_structp, png_create_read_struct_2,\n    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,\n    png_error_ptr warn_fn,\n    png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),\n    PNG_ALLOCATED);\nPNG_EXPORTA(12, png_structp, png_create_write_struct_2,\n    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,\n    png_error_ptr warn_fn,\n    png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),\n    PNG_ALLOCATED);\n#endif\n\n/* Write the PNG file signature. */\nPNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr));\n\n/* Write a PNG chunk - size, type, (optional) data, CRC. */\nPNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep\n    chunk_name, png_const_bytep data, png_size_t length));\n\n/* Write the start of a PNG chunk - length and chunk name. */\nPNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr,\n    png_const_bytep chunk_name, png_uint_32 length));\n\n/* Write the data of a PNG chunk started with png_write_chunk_start(). */\nPNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr,\n    png_const_bytep data, png_size_t length));\n\n/* Finish a chunk started with png_write_chunk_start() (includes CRC). */\nPNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr));\n\n/* Allocate and initialize the info structure */\nPNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr),\n    PNG_ALLOCATED);\n\n/* DEPRECATED: this function allowed init structures to be created using the\n * default allocation method (typically malloc).  Use is deprecated in 1.6.0 and\n * the API will be removed in the future.\n */\nPNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr,\n    png_size_t png_info_struct_size), PNG_DEPRECATED);\n\n/* Writes all the PNG information before the image. */\nPNG_EXPORT(20, void, png_write_info_before_PLTE,\n    (png_structrp png_ptr, png_const_inforp info_ptr));\nPNG_EXPORT(21, void, png_write_info,\n    (png_structrp png_ptr, png_const_inforp info_ptr));\n\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n/* Read the information before the actual image data. */\nPNG_EXPORT(22, void, png_read_info,\n    (png_structrp png_ptr, png_inforp info_ptr));\n#endif\n\n#ifdef PNG_TIME_RFC1123_SUPPORTED\n   /* Convert to a US string format: there is no localization support in this\n    * routine.  The original implementation used a 29 character buffer in\n    * png_struct, this will be removed in future versions.\n    */\n#if PNG_LIBPNG_VER < 10700\n/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */\nPNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr,\n    png_const_timep ptime),PNG_DEPRECATED);\n#endif\nPNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29],\n    png_const_timep ptime));\n#endif\n\n#ifdef PNG_CONVERT_tIME_SUPPORTED\n/* Convert from a struct tm to png_time */\nPNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime,\n    const struct tm * ttime));\n\n/* Convert from time_t to png_time.  Uses gmtime() */\nPNG_EXPORT(25, void, png_convert_from_time_t, (png_timep ptime, time_t ttime));\n#endif /* CONVERT_tIME */\n\n#ifdef PNG_READ_EXPAND_SUPPORTED\n/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */\nPNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr));\nPNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr));\nPNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr));\nPNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr));\n#endif\n\n#ifdef PNG_READ_EXPAND_16_SUPPORTED\n/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion\n * of a tRNS chunk if present.\n */\nPNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr));\n#endif\n\n#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)\n/* Use blue, green, red order for pixels. */\nPNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr));\n#endif\n\n#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\n/* Expand the grayscale to 24-bit RGB if necessary. */\nPNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr));\n#endif\n\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\n/* Reduce RGB to grayscale. */\n#define PNG_ERROR_ACTION_NONE  1\n#define PNG_ERROR_ACTION_WARN  2\n#define PNG_ERROR_ACTION_ERROR 3\n#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/\n\nPNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr,\n    int error_action, double red, double green))\nPNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr,\n    int error_action, png_fixed_point red, png_fixed_point green))\n\nPNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp\n    png_ptr));\n#endif\n\n#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED\nPNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth,\n    png_colorp palette));\n#endif\n\n#ifdef PNG_READ_ALPHA_MODE_SUPPORTED\n/* How the alpha channel is interpreted - this affects how the color channels\n * of a PNG file are returned to the calling application when an alpha channel,\n * or a tRNS chunk in a palette file, is present.\n *\n * This has no effect on the way pixels are written into a PNG output\n * datastream. The color samples in a PNG datastream are never premultiplied\n * with the alpha samples.\n *\n * The default is to return data according to the PNG specification: the alpha\n * channel is a linear measure of the contribution of the pixel to the\n * corresponding composited pixel, and the color channels are unassociated\n * (not premultiplied).  The gamma encoded color channels must be scaled\n * according to the contribution and to do this it is necessary to undo\n * the encoding, scale the color values, perform the composition and reencode\n * the values.  This is the 'PNG' mode.\n *\n * The alternative is to 'associate' the alpha with the color information by\n * storing color channel values that have been scaled by the alpha.\n * image.  These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes\n * (the latter being the two common names for associated alpha color channels).\n *\n * For the 'OPTIMIZED' mode, a pixel is treated as opaque only if the alpha\n * value is equal to the maximum value.\n *\n * The final choice is to gamma encode the alpha channel as well.  This is\n * broken because, in practice, no implementation that uses this choice\n * correctly undoes the encoding before handling alpha composition.  Use this\n * choice only if other serious errors in the software or hardware you use\n * mandate it; the typical serious error is for dark halos to appear around\n * opaque areas of the composited PNG image because of arithmetic overflow.\n *\n * The API function png_set_alpha_mode specifies which of these choices to use\n * with an enumerated 'mode' value and the gamma of the required output:\n */\n#define PNG_ALPHA_PNG           0 /* according to the PNG standard */\n#define PNG_ALPHA_STANDARD      1 /* according to Porter/Duff */\n#define PNG_ALPHA_ASSOCIATED    1 /* as above; this is the normal practice */\n#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */\n#define PNG_ALPHA_OPTIMIZED     2 /* 'PNG' for opaque pixels, else 'STANDARD' */\n#define PNG_ALPHA_BROKEN        3 /* the alpha channel is gamma encoded */\n\nPNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode,\n    double output_gamma))\nPNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr,\n    int mode, png_fixed_point output_gamma))\n#endif\n\n#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED)\n/* The output_gamma value is a screen gamma in libpng terminology: it expresses\n * how to decode the output values, not how they are encoded.\n */\n#define PNG_DEFAULT_sRGB -1       /* sRGB gamma and color space */\n#define PNG_GAMMA_MAC_18 -2       /* Old Mac '1.8' gamma and color space */\n#define PNG_GAMMA_sRGB   220000   /* Television standards--matches sRGB gamma */\n#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */\n#endif\n\n/* The following are examples of calls to png_set_alpha_mode to achieve the\n * required overall gamma correction and, where necessary, alpha\n * premultiplication.\n *\n * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);\n *    This is the default libpng handling of the alpha channel - it is not\n *    pre-multiplied into the color components.  In addition the call states\n *    that the output is for a sRGB system and causes all PNG files without gAMA\n *    chunks to be assumed to be encoded using sRGB.\n *\n * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);\n *    In this case the output is assumed to be something like an sRGB conformant\n *    display preceeded by a power-law lookup table of power 1.45.  This is how\n *    early Mac systems behaved.\n *\n * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);\n *    This is the classic Jim Blinn approach and will work in academic\n *    environments where everything is done by the book.  It has the shortcoming\n *    of assuming that input PNG data with no gamma information is linear - this\n *    is unlikely to be correct unless the PNG files where generated locally.\n *    Most of the time the output precision will be so low as to show\n *    significant banding in dark areas of the image.\n *\n * png_set_expand_16(pp);\n * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB);\n *    This is a somewhat more realistic Jim Blinn inspired approach.  PNG files\n *    are assumed to have the sRGB encoding if not marked with a gamma value and\n *    the output is always 16 bits per component.  This permits accurate scaling\n *    and processing of the data.  If you know that your input PNG files were\n *    generated locally you might need to replace PNG_DEFAULT_sRGB with the\n *    correct value for your system.\n *\n * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);\n *    If you just need to composite the PNG image onto an existing background\n *    and if you control the code that does this you can use the optimization\n *    setting.  In this case you just copy completely opaque pixels to the\n *    output.  For pixels that are not completely transparent (you just skip\n *    those) you do the composition math using png_composite or png_composite_16\n *    below then encode the resultant 8-bit or 16-bit values to match the output\n *    encoding.\n *\n * Other cases\n *    If neither the PNG nor the standard linear encoding work for you because\n *    of the software or hardware you use then you have a big problem.  The PNG\n *    case will probably result in halos around the image.  The linear encoding\n *    will probably result in a washed out, too bright, image (it's actually too\n *    contrasty.)  Try the ALPHA_OPTIMIZED mode above - this will probably\n *    substantially reduce the halos.  Alternatively try:\n *\n * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB);\n *    This option will also reduce the halos, but there will be slight dark\n *    halos round the opaque parts of the image where the background is light.\n *    In the OPTIMIZED mode the halos will be light halos where the background\n *    is dark.  Take your pick - the halos are unavoidable unless you can get\n *    your hardware/software fixed!  (The OPTIMIZED approach is slightly\n *    faster.)\n *\n * When the default gamma of PNG files doesn't match the output gamma.\n *    If you have PNG files with no gamma information png_set_alpha_mode allows\n *    you to provide a default gamma, but it also sets the ouput gamma to the\n *    matching value.  If you know your PNG files have a gamma that doesn't\n *    match the output you can take advantage of the fact that\n *    png_set_alpha_mode always sets the output gamma but only sets the PNG\n *    default if it is not already set:\n *\n * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);\n * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);\n *    The first call sets both the default and the output gamma values, the\n *    second call overrides the output gamma without changing the default.  This\n *    is easier than achieving the same effect with png_set_gamma.  You must use\n *    PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will\n *    fire if more than one call to png_set_alpha_mode and png_set_background is\n *    made in the same read operation, however multiple calls with PNG_ALPHA_PNG\n *    are ignored.\n */\n\n#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED\nPNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr));\n#endif\n\n#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \\\n    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)\nPNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr));\n#endif\n\n#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \\\n    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)\nPNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr));\n#endif\n\n#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)\n/* Add a filler byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */\nPNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler,\n    int flags));\n/* The values of the PNG_FILLER_ defines should NOT be changed */\n#  define PNG_FILLER_BEFORE 0\n#  define PNG_FILLER_AFTER 1\n/* Add an alpha byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */\nPNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr,\n    png_uint_32 filler, int flags));\n#endif /* READ_FILLER || WRITE_FILLER */\n\n#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)\n/* Swap bytes in 16-bit depth files. */\nPNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr));\n#endif\n\n#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)\n/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */\nPNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr));\n#endif\n\n#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \\\n    defined(PNG_WRITE_PACKSWAP_SUPPORTED)\n/* Swap packing order of pixels in bytes. */\nPNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr));\n#endif\n\n#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)\n/* Converts files to legal bit depths. */\nPNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p\n    true_bits));\n#endif\n\n#if defined(PNG_READ_INTERLACING_SUPPORTED) || \\\n    defined(PNG_WRITE_INTERLACING_SUPPORTED)\n/* Have the code handle the interlacing.  Returns the number of passes.\n * MUST be called before png_read_update_info or png_start_read_image,\n * otherwise it will not have the desired effect.  Note that it is still\n * necessary to call png_read_row or png_read_rows png_get_image_height\n * times for each pass.\n*/\nPNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr));\n#endif\n\n#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)\n/* Invert monochrome files */\nPNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr));\n#endif\n\n#ifdef PNG_READ_BACKGROUND_SUPPORTED\n/* Handle alpha and tRNS by replacing with a background color.  Prior to\n * libpng-1.5.4 this API must not be called before the PNG file header has been\n * read.  Doing so will result in unexpected behavior and possible warnings or\n * errors if the PNG file contains a bKGD chunk.\n */\nPNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr,\n    png_const_color_16p background_color, int background_gamma_code,\n    int need_expand, double background_gamma))\nPNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr,\n    png_const_color_16p background_color, int background_gamma_code,\n    int need_expand, png_fixed_point background_gamma))\n#endif\n#ifdef PNG_READ_BACKGROUND_SUPPORTED\n#  define PNG_BACKGROUND_GAMMA_UNKNOWN 0\n#  define PNG_BACKGROUND_GAMMA_SCREEN  1\n#  define PNG_BACKGROUND_GAMMA_FILE    2\n#  define PNG_BACKGROUND_GAMMA_UNIQUE  3\n#endif\n\n#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\n/* Scale a 16-bit depth file down to 8-bit, accurately. */\nPNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr));\n#endif\n\n#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED\n#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */\n/* Strip the second byte of information from a 16-bit depth file. */\nPNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr));\n#endif\n\n#ifdef PNG_READ_QUANTIZE_SUPPORTED\n/* Turn on quantizing, and reduce the palette to the number of colors\n * available.\n */\nPNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr,\n    png_colorp palette, int num_palette, int maximum_colors,\n    png_const_uint_16p histogram, int full_quantize));\n#endif\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\n/* The threshold on gamma processing is configurable but hard-wired into the\n * library.  The following is the floating point variant.\n */\n#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001)\n\n/* Handle gamma correction. Screen_gamma=(display_exponent).\n * NOTE: this API simply sets the screen and file gamma values. It will\n * therefore override the value for gamma in a PNG file if it is called after\n * the file header has been read - use with care  - call before reading the PNG\n * file for best results!\n *\n * These routines accept the same gamma values as png_set_alpha_mode (described\n * above).  The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either\n * API (floating point or fixed.)  Notice, however, that the 'file_gamma' value\n * is the inverse of a 'screen gamma' value.\n */\nPNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr,\n    double screen_gamma, double override_file_gamma))\nPNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr,\n    png_fixed_point screen_gamma, png_fixed_point override_file_gamma))\n#endif\n\n#ifdef PNG_WRITE_FLUSH_SUPPORTED\n/* Set how many lines between output flushes - 0 for no flushing */\nPNG_EXPORT(51, void, png_set_flush, (png_structrp png_ptr, int nrows));\n/* Flush the current PNG output buffer */\nPNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr));\n#endif\n\n/* Optional update palette with requested transformations */\nPNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr));\n\n/* Optional call to update the users info structure */\nPNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr,\n    png_inforp info_ptr));\n\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n/* Read one or more rows of image data. */\nPNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row,\n    png_bytepp display_row, png_uint_32 num_rows));\n#endif\n\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n/* Read a row of data. */\nPNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row,\n    png_bytep display_row));\n#endif\n\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n/* Read the whole image into memory at once. */\nPNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image));\n#endif\n\n/* Write a row of image data */\nPNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr,\n    png_const_bytep row));\n\n/* Write a few rows of image data: (*row) is not written; however, the type\n * is declared as writeable to maintain compatibility with previous versions\n * of libpng and to allow the 'display_row' array from read_rows to be passed\n * unchanged to write_rows.\n */\nPNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row,\n    png_uint_32 num_rows));\n\n/* Write the image data */\nPNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image));\n\n/* Write the end of the PNG file. */\nPNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr,\n    png_inforp info_ptr));\n\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n/* Read the end of the PNG file. */\nPNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr));\n#endif\n\n/* Free any memory associated with the png_info_struct */\nPNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr,\n    png_infopp info_ptr_ptr));\n\n/* Free any memory associated with the png_struct and the png_info_structs */\nPNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr,\n    png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));\n\n/* Free any memory associated with the png_struct and the png_info_structs */\nPNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr,\n    png_infopp info_ptr_ptr));\n\n/* Set the libpng method of handling chunk CRC errors */\nPNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action,\n    int ancil_action));\n\n/* Values for png_set_crc_action() say how to handle CRC errors in\n * ancillary and critical chunks, and whether to use the data contained\n * therein.  Note that it is impossible to \"discard\" data in a critical\n * chunk.  For versions prior to 0.90, the action was always error/quit,\n * whereas in version 0.90 and later, the action for CRC errors in ancillary\n * chunks is warn/discard.  These values should NOT be changed.\n *\n *      value                       action:critical     action:ancillary\n */\n#define PNG_CRC_DEFAULT       0  /* error/quit          warn/discard data */\n#define PNG_CRC_ERROR_QUIT    1  /* error/quit          error/quit        */\n#define PNG_CRC_WARN_DISCARD  2  /* (INVALID)           warn/discard data */\n#define PNG_CRC_WARN_USE      3  /* warn/use data       warn/use data     */\n#define PNG_CRC_QUIET_USE     4  /* quiet/use data      quiet/use data    */\n#define PNG_CRC_NO_CHANGE     5  /* use current value   use current value */\n\n#ifdef PNG_WRITE_SUPPORTED\n/* These functions give the user control over the scan-line filtering in\n * libpng and the compression methods used by zlib.  These functions are\n * mainly useful for testing, as the defaults should work with most users.\n * Those users who are tight on memory or want faster performance at the\n * expense of compression can modify them.  See the compression library\n * header file (zlib.h) for an explination of the compression functions.\n */\n\n/* Set the filtering method(s) used by libpng.  Currently, the only valid\n * value for \"method\" is 0.\n */\nPNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method,\n    int filters));\n#endif /* WRITE */\n\n/* Flags for png_set_filter() to say which filters to use.  The flags\n * are chosen so that they don't conflict with real filter types\n * below, in case they are supplied instead of the #defined constants.\n * These values should NOT be changed.\n */\n#define PNG_NO_FILTERS     0x00\n#define PNG_FILTER_NONE    0x08\n#define PNG_FILTER_SUB     0x10\n#define PNG_FILTER_UP      0x20\n#define PNG_FILTER_AVG     0x40\n#define PNG_FILTER_PAETH   0x80\n#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \\\n                         PNG_FILTER_AVG | PNG_FILTER_PAETH)\n\n/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.\n * These defines should NOT be changed.\n */\n#define PNG_FILTER_VALUE_NONE  0\n#define PNG_FILTER_VALUE_SUB   1\n#define PNG_FILTER_VALUE_UP    2\n#define PNG_FILTER_VALUE_AVG   3\n#define PNG_FILTER_VALUE_PAETH 4\n#define PNG_FILTER_VALUE_LAST  5\n\n#ifdef PNG_WRITE_SUPPORTED\n#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */\nPNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr,\n    int heuristic_method, int num_weights, png_const_doublep filter_weights,\n    png_const_doublep filter_costs))\nPNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed,\n    (png_structrp png_ptr, int heuristic_method, int num_weights,\n    png_const_fixed_point_p filter_weights,\n    png_const_fixed_point_p filter_costs))\n#endif /* WRITE_WEIGHTED_FILTER */\n\n/* The following are no longer used and will be removed from libpng-1.7: */\n#define PNG_FILTER_HEURISTIC_DEFAULT    0  /* Currently \"UNWEIGHTED\" */\n#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1  /* Used by libpng < 0.95 */\n#define PNG_FILTER_HEURISTIC_WEIGHTED   2  /* Experimental feature */\n#define PNG_FILTER_HEURISTIC_LAST       3  /* Not a valid value */\n\n/* Set the library compression level.  Currently, valid values range from\n * 0 - 9, corresponding directly to the zlib compression levels 0 - 9\n * (0 - no compression, 9 - \"maximal\" compression).  Note that tests have\n * shown that zlib compression levels 3-6 usually perform as well as level 9\n * for PNG images, and do considerably fewer caclulations.  In the future,\n * these values may not correspond directly to the zlib compression levels.\n */\n#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED\nPNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr,\n    int level));\n\nPNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr,\n    int mem_level));\n\nPNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp png_ptr,\n    int strategy));\n\n/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a\n * smaller value of window_bits if it can do so safely.\n */\nPNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr,\n    int window_bits));\n\nPNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr,\n    int method));\n#endif /* WRITE_CUSTOMIZE_COMPRESSION */\n\n#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED\n/* Also set zlib parameters for compressing non-IDAT chunks */\nPNG_EXPORT(222, void, png_set_text_compression_level, (png_structrp png_ptr,\n    int level));\n\nPNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr,\n    int mem_level));\n\nPNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp png_ptr,\n    int strategy));\n\n/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a\n * smaller value of window_bits if it can do so safely.\n */\nPNG_EXPORT(225, void, png_set_text_compression_window_bits,\n    (png_structrp png_ptr, int window_bits));\n\nPNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr,\n    int method));\n#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */\n#endif /* WRITE */\n\n/* These next functions are called for input/output, memory, and error\n * handling.  They are in the file pngrio.c, pngwio.c, and pngerror.c,\n * and call standard C I/O routines such as fread(), fwrite(), and\n * fprintf().  These functions can be made to use other I/O routines\n * at run time for those applications that need to handle I/O in a\n * different manner by calling png_set_???_fn().  See libpng-manual.txt for\n * more information.\n */\n\n#ifdef PNG_STDIO_SUPPORTED\n/* Initialize the input/output for the PNG file to the default functions. */\nPNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp));\n#endif\n\n/* Replace the (error and abort), and warning functions with user\n * supplied functions.  If no messages are to be printed you must still\n * write and use replacement functions. The replacement error_fn should\n * still do a longjmp to the last setjmp location if you are using this\n * method of error handling.  If error_fn or warning_fn is NULL, the\n * default function will be used.\n */\n\nPNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr,\n    png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));\n\n/* Return the user pointer associated with the error functions */\nPNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr));\n\n/* Replace the default data output functions with a user supplied one(s).\n * If buffered output is not used, then output_flush_fn can be set to NULL.\n * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time\n * output_flush_fn will be ignored (and thus can be NULL).\n * It is probably a mistake to use NULL for output_flush_fn if\n * write_data_fn is not also NULL unless you have built libpng with\n * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's\n * default flush function, which uses the standard *FILE structure, will\n * be used.\n */\nPNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr,\n    png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));\n\n/* Replace the default data input function with a user supplied one. */\nPNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr,\n    png_rw_ptr read_data_fn));\n\n/* Return the user pointer associated with the I/O functions */\nPNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr));\n\nPNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr,\n    png_read_status_ptr read_row_fn));\n\nPNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr,\n    png_write_status_ptr write_row_fn));\n\n#ifdef PNG_USER_MEM_SUPPORTED\n/* Replace the default memory allocation functions with user supplied one(s). */\nPNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr,\n    png_malloc_ptr malloc_fn, png_free_ptr free_fn));\n/* Return the user pointer associated with the memory functions */\nPNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr));\n#endif\n\n#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED\nPNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr,\n    png_user_transform_ptr read_user_transform_fn));\n#endif\n\n#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED\nPNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr,\n    png_user_transform_ptr write_user_transform_fn));\n#endif\n\n#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED\nPNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr,\n    png_voidp user_transform_ptr, int user_transform_depth,\n    int user_transform_channels));\n/* Return the user pointer associated with the user transform functions */\nPNG_EXPORT(87, png_voidp, png_get_user_transform_ptr,\n    (png_const_structrp png_ptr));\n#endif\n\n#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED\n/* Return information about the row currently being processed.  Note that these\n * APIs do not fail but will return unexpected results if called outside a user\n * transform callback.  Also note that when transforming an interlaced image the\n * row number is the row number within the sub-image of the interlace pass, so\n * the value will increase to the height of the sub-image (not the full image)\n * then reset to 0 for the next pass.\n *\n * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to\n * find the output pixel (x,y) given an interlaced sub-image pixel\n * (row,col,pass).  (See below for these macros.)\n */\nPNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp));\nPNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp));\n#endif\n\n#ifdef PNG_READ_USER_CHUNKS_SUPPORTED\n/* This callback is called only for *unknown* chunks.  If\n * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known\n * chunks to be treated as unknown, however in this case the callback must do\n * any processing required by the chunk (e.g. by calling the appropriate\n * png_set_ APIs.)\n *\n * There is no write support - on write, by default, all the chunks in the\n * 'unknown' list are written in the specified position.\n *\n * The integer return from the callback function is interpreted thus:\n *\n * negative: An error occurred; png_chunk_error will be called.\n *     zero: The chunk was not handled, the chunk will be saved. A critical\n *           chunk will cause an error at this point unless it is to be saved.\n * positive: The chunk was handled, libpng will ignore/discard it.\n *\n * See \"INTERACTION WTIH USER CHUNK CALLBACKS\" below for important notes about\n * how this behavior will change in libpng 1.7\n */\nPNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr,\n    png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));\n#endif\n\n#ifdef PNG_USER_CHUNKS_SUPPORTED\nPNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr));\n#endif\n\n#ifdef PNG_PROGRESSIVE_READ_SUPPORTED\n/* Sets the function callbacks for the push reader, and a pointer to a\n * user-defined structure available to the callback functions.\n */\nPNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr,\n    png_voidp progressive_ptr, png_progressive_info_ptr info_fn,\n    png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn));\n\n/* Returns the user pointer associated with the push read functions */\nPNG_EXPORT(91, png_voidp, png_get_progressive_ptr,\n    (png_const_structrp png_ptr));\n\n/* Function to be called when data becomes available */\nPNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr,\n    png_inforp info_ptr, png_bytep buffer, png_size_t buffer_size));\n\n/* A function which may be called *only* within png_process_data to stop the\n * processing of any more data.  The function returns the number of bytes\n * remaining, excluding any that libpng has cached internally.  A subsequent\n * call to png_process_data must supply these bytes again.  If the argument\n * 'save' is set to true the routine will first save all the pending data and\n * will always return 0.\n */\nPNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structrp, int save));\n\n/* A function which may be called *only* outside (after) a call to\n * png_process_data.  It returns the number of bytes of data to skip in the\n * input.  Normally it will return 0, but if it returns a non-zero value the\n * application must skip than number of bytes of input data and pass the\n * following data to the next call to png_process_data.\n */\nPNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp));\n\n/* Function that combines rows.  'new_row' is a flag that should come from\n * the callback and be non-NULL if anything needs to be done; the library\n * stores its own version of the new data internally and ignores the passed\n * in value.\n */\nPNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr,\n    png_bytep old_row, png_const_bytep new_row));\n#endif /* PROGRESSIVE_READ */\n\nPNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr,\n    png_alloc_size_t size), PNG_ALLOCATED);\n/* Added at libpng version 1.4.0 */\nPNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr,\n    png_alloc_size_t size), PNG_ALLOCATED);\n\n/* Added at libpng version 1.2.4 */\nPNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr,\n    png_alloc_size_t size), PNG_ALLOCATED);\n\n/* Frees a pointer allocated by png_malloc() */\nPNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr));\n\n/* Free data that was allocated internally */\nPNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 free_me, int num));\n\n/* Reassign responsibility for freeing existing data, whether allocated\n * by libpng or by the application; this works on the png_info structure passed\n * in, it does not change the state for other png_info structures.\n *\n * It is unlikely that this function works correctly as of 1.6.0 and using it\n * may result either in memory leaks or double free of allocated data.\n */\nPNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr,\n    png_inforp info_ptr, int freer, png_uint_32 mask));\n\n/* Assignments for png_data_freer */\n#define PNG_DESTROY_WILL_FREE_DATA 1\n#define PNG_SET_WILL_FREE_DATA 1\n#define PNG_USER_WILL_FREE_DATA 2\n/* Flags for png_ptr->free_me and info_ptr->free_me */\n#define PNG_FREE_HIST 0x0008U\n#define PNG_FREE_ICCP 0x0010U\n#define PNG_FREE_SPLT 0x0020U\n#define PNG_FREE_ROWS 0x0040U\n#define PNG_FREE_PCAL 0x0080U\n#define PNG_FREE_SCAL 0x0100U\n#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED\n#  define PNG_FREE_UNKN 0x0200U\n#endif\n/*      PNG_FREE_LIST 0x0400U   removed in 1.6.0 because it is ignored */\n#define PNG_FREE_PLTE 0x1000U\n#define PNG_FREE_TRNS 0x2000U\n#define PNG_FREE_TEXT 0x4000U\n#define PNG_FREE_ALL  0x7fffU\n#define PNG_FREE_MUL  0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */\n\n#ifdef PNG_USER_MEM_SUPPORTED\nPNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr,\n    png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED);\nPNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr,\n    png_voidp ptr), PNG_DEPRECATED);\n#endif\n\n#ifdef PNG_ERROR_TEXT_SUPPORTED\n/* Fatal error in PNG image of libpng - can't continue */\nPNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr,\n    png_const_charp error_message), PNG_NORETURN);\n\n/* The same, but the chunk name is prepended to the error string. */\nPNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr,\n    png_const_charp error_message), PNG_NORETURN);\n\n#else\n/* Fatal error in PNG image of libpng - can't continue */\nPNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN);\n#  define png_error(s1,s2) png_err(s1)\n#  define png_chunk_error(s1,s2) png_err(s1)\n#endif\n\n#ifdef PNG_WARNINGS_SUPPORTED\n/* Non-fatal error in libpng.  Can continue, but may have a problem. */\nPNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr,\n    png_const_charp warning_message));\n\n/* Non-fatal error in libpng, chunk name is prepended to message. */\nPNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr,\n    png_const_charp warning_message));\n#else\n#  define png_warning(s1,s2) ((void)(s1))\n#  define png_chunk_warning(s1,s2) ((void)(s1))\n#endif\n\n#ifdef PNG_BENIGN_ERRORS_SUPPORTED\n/* Benign error in libpng.  Can continue, but may have a problem.\n * User can choose whether to handle as a fatal error or as a warning. */\nPNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr,\n    png_const_charp warning_message));\n\n#ifdef PNG_READ_SUPPORTED\n/* Same, chunk name is prepended to message (only during read) */\nPNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr,\n    png_const_charp warning_message));\n#endif\n\nPNG_EXPORT(109, void, png_set_benign_errors,\n    (png_structrp png_ptr, int allowed));\n#else\n#  ifdef PNG_ALLOW_BENIGN_ERRORS\n#    define png_benign_error png_warning\n#    define png_chunk_benign_error png_chunk_warning\n#  else\n#    define png_benign_error png_error\n#    define png_chunk_benign_error png_chunk_error\n#  endif\n#endif\n\n/* The png_set_<chunk> functions are for storing values in the png_info_struct.\n * Similarly, the png_get_<chunk> calls are used to read values from the\n * png_info_struct, either storing the parameters in the passed variables, or\n * setting pointers into the png_info_struct where the data is stored.  The\n * png_get_<chunk> functions return a non-zero value if the data was available\n * in info_ptr, or return zero and do not change any of the parameters if the\n * data was not available.\n *\n * These functions should be used instead of directly accessing png_info\n * to avoid problems with future changes in the size and internal layout of\n * png_info_struct.\n */\n/* Returns \"flag\" if chunk data is valid in info_ptr. */\nPNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr, png_uint_32 flag));\n\n/* Returns number of bytes needed to hold a transformed row. */\nPNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr));\n\n#ifdef PNG_INFO_IMAGE_SUPPORTED\n/* Returns row_pointers, which is an array of pointers to scanlines that was\n * returned from png_read_png().\n */\nPNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr));\n\n/* Set row_pointers, which is an array of pointers to scanlines for use\n * by png_write_png().\n */\nPNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_bytepp row_pointers));\n#endif\n\n/* Returns number of color channels in image. */\nPNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr));\n\n#ifdef PNG_EASY_ACCESS_SUPPORTED\n/* Returns image width in pixels. */\nPNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr));\n\n/* Returns image height in pixels. */\nPNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr));\n\n/* Returns image bit_depth. */\nPNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr));\n\n/* Returns image color_type. */\nPNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr));\n\n/* Returns image filter_type. */\nPNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr));\n\n/* Returns image interlace_type. */\nPNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr));\n\n/* Returns image compression_type. */\nPNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr));\n\n/* Returns image resolution in pixels per meter, from pHYs chunk data. */\nPNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr));\nPNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr));\nPNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr));\n\n/* Returns pixel aspect ratio, computed from pHYs chunk data.  */\nPNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr))\nPNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr))\n\n/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */\nPNG_EXPORT(126, png_int_32, png_get_x_offset_pixels,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr));\nPNG_EXPORT(127, png_int_32, png_get_y_offset_pixels,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr));\nPNG_EXPORT(128, png_int_32, png_get_x_offset_microns,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr));\nPNG_EXPORT(129, png_int_32, png_get_y_offset_microns,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr));\n\n#endif /* EASY_ACCESS */\n\n#ifdef PNG_READ_SUPPORTED\n/* Returns pointer to signature string read from PNG header */\nPNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr));\n#endif\n\n#ifdef PNG_bKGD_SUPPORTED\nPNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_color_16p *background));\n#endif\n\n#ifdef PNG_bKGD_SUPPORTED\nPNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_const_color_16p background));\n#endif\n\n#ifdef PNG_cHRM_SUPPORTED\nPNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x,\n    double *red_y, double *green_x, double *green_y, double *blue_x,\n    double *blue_y))\nPNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z,\n    double *green_X, double *green_Y, double *green_Z, double *blue_X,\n    double *blue_Y, double *blue_Z))\nPNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr,\n    png_fixed_point *int_white_x, png_fixed_point *int_white_y,\n    png_fixed_point *int_red_x, png_fixed_point *int_red_y,\n    png_fixed_point *int_green_x, png_fixed_point *int_green_y,\n    png_fixed_point *int_blue_x, png_fixed_point *int_blue_y))\nPNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr,\n    png_fixed_point *int_red_X, png_fixed_point *int_red_Y,\n    png_fixed_point *int_red_Z, png_fixed_point *int_green_X,\n    png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,\n    png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,\n    png_fixed_point *int_blue_Z))\n#endif\n\n#ifdef PNG_cHRM_SUPPORTED\nPNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr,\n    png_inforp info_ptr,\n    double white_x, double white_y, double red_x, double red_y, double green_x,\n    double green_y, double blue_x, double blue_y))\nPNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr,\n    png_inforp info_ptr, double red_X, double red_Y, double red_Z,\n    double green_X, double green_Y, double green_Z, double blue_X,\n    double blue_Y, double blue_Z))\nPNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_fixed_point int_white_x,\n    png_fixed_point int_white_y, png_fixed_point int_red_x,\n    png_fixed_point int_red_y, png_fixed_point int_green_x,\n    png_fixed_point int_green_y, png_fixed_point int_blue_x,\n    png_fixed_point int_blue_y))\nPNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y,\n    png_fixed_point int_red_Z, png_fixed_point int_green_X,\n    png_fixed_point int_green_Y, png_fixed_point int_green_Z,\n    png_fixed_point int_blue_X, png_fixed_point int_blue_Y,\n    png_fixed_point int_blue_Z))\n#endif\n\n#ifdef PNG_gAMA_SUPPORTED\nPNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr, double *file_gamma))\nPNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr,\n    png_fixed_point *int_file_gamma))\n#endif\n\n#ifdef PNG_gAMA_SUPPORTED\nPNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr,\n    png_inforp info_ptr, double file_gamma))\nPNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_fixed_point int_file_gamma))\n#endif\n\n#ifdef PNG_hIST_SUPPORTED\nPNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_uint_16p *hist));\n#endif\n\n#ifdef PNG_hIST_SUPPORTED\nPNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_const_uint_16p hist));\n#endif\n\nPNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height,\n    int *bit_depth, int *color_type, int *interlace_method,\n    int *compression_method, int *filter_method));\n\nPNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,\n    int color_type, int interlace_method, int compression_method,\n    int filter_method));\n\n#ifdef PNG_oFFs_SUPPORTED\nPNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr,\n   png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,\n   int *unit_type));\n#endif\n\n#ifdef PNG_oFFs_SUPPORTED\nPNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y,\n    int unit_type));\n#endif\n\n#ifdef PNG_pCAL_SUPPORTED\nPNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_charp *purpose, png_int_32 *X0,\n    png_int_32 *X1, int *type, int *nparams, png_charp *units,\n    png_charpp *params));\n#endif\n\n#ifdef PNG_pCAL_SUPPORTED\nPNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1,\n    int type, int nparams, png_const_charp units, png_charpp params));\n#endif\n\n#ifdef PNG_pHYs_SUPPORTED\nPNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,\n    int *unit_type));\n#endif\n\n#ifdef PNG_pHYs_SUPPORTED\nPNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));\n#endif\n\nPNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr,\n   png_inforp info_ptr, png_colorp *palette, int *num_palette));\n\nPNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr,\n    png_inforp info_ptr, png_const_colorp palette, int num_palette));\n\n#ifdef PNG_sBIT_SUPPORTED\nPNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_color_8p *sig_bit));\n#endif\n\n#ifdef PNG_sBIT_SUPPORTED\nPNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_const_color_8p sig_bit));\n#endif\n\n#ifdef PNG_sRGB_SUPPORTED\nPNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr, int *file_srgb_intent));\n#endif\n\n#ifdef PNG_sRGB_SUPPORTED\nPNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr,\n    png_inforp info_ptr, int srgb_intent));\nPNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr,\n    png_inforp info_ptr, int srgb_intent));\n#endif\n\n#ifdef PNG_iCCP_SUPPORTED\nPNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_charpp name, int *compression_type,\n    png_bytepp profile, png_uint_32 *proflen));\n#endif\n\n#ifdef PNG_iCCP_SUPPORTED\nPNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_const_charp name, int compression_type,\n    png_const_bytep profile, png_uint_32 proflen));\n#endif\n\n#ifdef PNG_sPLT_SUPPORTED\nPNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_sPLT_tpp entries));\n#endif\n\n#ifdef PNG_sPLT_SUPPORTED\nPNG_EXPORT(161, void, png_set_sPLT, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_const_sPLT_tp entries, int nentries));\n#endif\n\n#ifdef PNG_TEXT_SUPPORTED\n/* png_get_text also returns the number of text chunks in *num_text */\nPNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_textp *text_ptr, int *num_text));\n#endif\n\n/* Note while png_set_text() will accept a structure whose text,\n * language, and  translated keywords are NULL pointers, the structure\n * returned by png_get_text will always contain regular\n * zero-terminated C strings.  They might be empty strings but\n * they will never be NULL pointers.\n */\n\n#ifdef PNG_TEXT_SUPPORTED\nPNG_EXPORT(163, void, png_set_text, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_const_textp text_ptr, int num_text));\n#endif\n\n#ifdef PNG_tIME_SUPPORTED\nPNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_timep *mod_time));\n#endif\n\n#ifdef PNG_tIME_SUPPORTED\nPNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_const_timep mod_time));\n#endif\n\n#ifdef PNG_tRNS_SUPPORTED\nPNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans,\n    png_color_16p *trans_color));\n#endif\n\n#ifdef PNG_tRNS_SUPPORTED\nPNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr,\n    png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans,\n    png_const_color_16p trans_color));\n#endif\n\n#ifdef PNG_sCAL_SUPPORTED\nPNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr, int *unit, double *width, double *height))\n#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \\\n   defined(PNG_FLOATING_POINT_SUPPORTED)\n/* NOTE: this API is currently implemented using floating point arithmetic,\n * consequently it can only be used on systems with floating point support.\n * In any case the range of values supported by png_fixed_point is small and it\n * is highly recommended that png_get_sCAL_s be used instead.\n */\nPNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit,\n    png_fixed_point *width, png_fixed_point *height))\n#endif\nPNG_EXPORT(169, png_uint_32, png_get_sCAL_s,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit,\n    png_charpp swidth, png_charpp sheight));\n\nPNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr,\n    png_inforp info_ptr, int unit, double width, double height))\nPNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr,\n   png_inforp info_ptr, int unit, png_fixed_point width,\n   png_fixed_point height))\nPNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr,\n    png_inforp info_ptr, int unit,\n    png_const_charp swidth, png_const_charp sheight));\n#endif /* sCAL */\n\n#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED\n/* Provide the default handling for all unknown chunks or, optionally, for\n * specific unknown chunks.\n *\n * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was\n * ignored and the default was used, the per-chunk setting only had an effect on\n * write.  If you wish to have chunk-specific handling on read in code that must\n * work on earlier versions you must use a user chunk callback to specify the\n * desired handling (keep or discard.)\n *\n * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below.  The\n * parameter is interpreted as follows:\n *\n * READ:\n *    PNG_HANDLE_CHUNK_AS_DEFAULT:\n *       Known chunks: do normal libpng processing, do not keep the chunk (but\n *          see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED)\n *       Unknown chunks: for a specific chunk use the global default, when used\n *          as the default discard the chunk data.\n *    PNG_HANDLE_CHUNK_NEVER:\n *       Discard the chunk data.\n *    PNG_HANDLE_CHUNK_IF_SAFE:\n *       Keep the chunk data if the chunk is not critical else raise a chunk\n *       error.\n *    PNG_HANDLE_CHUNK_ALWAYS:\n *       Keep the chunk data.\n *\n * If the chunk data is saved it can be retrieved using png_get_unknown_chunks,\n * below.  Notice that specifying \"AS_DEFAULT\" as a global default is equivalent\n * to specifying \"NEVER\", however when \"AS_DEFAULT\" is used for specific chunks\n * it simply resets the behavior to the libpng default.\n *\n * INTERACTION WTIH USER CHUNK CALLBACKS:\n * The per-chunk handling is always used when there is a png_user_chunk_ptr\n * callback and the callback returns 0; the chunk is then always stored *unless*\n * it is critical and the per-chunk setting is other than ALWAYS.  Notice that\n * the global default is *not* used in this case.  (In effect the per-chunk\n * value is incremented to at least IF_SAFE.)\n *\n * IMPORTANT NOTE: this behavior will change in libpng 1.7 - the global and\n * per-chunk defaults will be honored.  If you want to preserve the current\n * behavior when your callback returns 0 you must set PNG_HANDLE_CHUNK_IF_SAFE\n * as the default - if you don't do this libpng 1.6 will issue a warning.\n *\n * If you want unhandled unknown chunks to be discarded in libpng 1.6 and\n * earlier simply return '1' (handled).\n *\n * PNG_HANDLE_AS_UNKNOWN_SUPPORTED:\n *    If this is *not* set known chunks will always be handled by libpng and\n *    will never be stored in the unknown chunk list.  Known chunks listed to\n *    png_set_keep_unknown_chunks will have no effect.  If it is set then known\n *    chunks listed with a keep other than AS_DEFAULT will *never* be processed\n *    by libpng, in addition critical chunks must either be processed by the\n *    callback or saved.\n *\n *    The IHDR and IEND chunks must not be listed.  Because this turns off the\n *    default handling for chunks that would otherwise be recognized the\n *    behavior of libpng transformations may well become incorrect!\n *\n * WRITE:\n *    When writing chunks the options only apply to the chunks specified by\n *    png_set_unknown_chunks (below), libpng will *always* write known chunks\n *    required by png_set_ calls and will always write the core critical chunks\n *    (as required for PLTE).\n *\n *    Each chunk in the png_set_unknown_chunks list is looked up in the\n *    png_set_keep_unknown_chunks list to find the keep setting, this is then\n *    interpreted as follows:\n *\n *    PNG_HANDLE_CHUNK_AS_DEFAULT:\n *       Write safe-to-copy chunks and write other chunks if the global\n *       default is set to _ALWAYS, otherwise don't write this chunk.\n *    PNG_HANDLE_CHUNK_NEVER:\n *       Do not write the chunk.\n *    PNG_HANDLE_CHUNK_IF_SAFE:\n *       Write the chunk if it is safe-to-copy, otherwise do not write it.\n *    PNG_HANDLE_CHUNK_ALWAYS:\n *       Write the chunk.\n *\n * Note that the default behavior is effectively the opposite of the read case -\n * in read unknown chunks are not stored by default, in write they are written\n * by default.  Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different\n * - on write the safe-to-copy bit is checked, on read the critical bit is\n * checked and on read if the chunk is critical an error will be raised.\n *\n * num_chunks:\n * ===========\n *    If num_chunks is positive, then the \"keep\" parameter specifies the manner\n *    for handling only those chunks appearing in the chunk_list array,\n *    otherwise the chunk list array is ignored.\n *\n *    If num_chunks is 0 the \"keep\" parameter specifies the default behavior for\n *    unknown chunks, as described above.\n *\n *    If num_chunks is negative, then the \"keep\" parameter specifies the manner\n *    for handling all unknown chunks plus all chunks recognized by libpng\n *    except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to\n *    be processed by libpng.\n */\nPNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,\n    int keep, png_const_bytep chunk_list, int num_chunks));\n\n/* The \"keep\" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned;\n * the result is therefore true (non-zero) if special handling is required,\n * false for the default handling.\n */\nPNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr,\n    png_const_bytep chunk_name));\n#endif\n\n#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED\nPNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_const_unknown_chunkp unknowns,\n    int num_unknowns));\n   /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added\n    * unknowns to the location currently stored in the png_struct.  This is\n    * invariably the wrong value on write.  To fix this call the following API\n    * for each chunk in the list with the correct location.  If you know your\n    * code won't be compiled on earlier versions you can rely on\n    * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing\n    * the correct thing.\n    */\n\nPNG_EXPORT(175, void, png_set_unknown_chunk_location,\n    (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location));\n\nPNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr,\n    png_inforp info_ptr, png_unknown_chunkpp entries));\n#endif\n\n/* Png_free_data() will turn off the \"valid\" flag for anything it frees.\n * If you need to turn it off for a chunk that your application has freed,\n * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK);\n */\nPNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr,\n    png_inforp info_ptr, int mask));\n\n#ifdef PNG_INFO_IMAGE_SUPPORTED\n/* The \"params\" pointer is currently not used and is for future expansion. */\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\nPNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr,\n    int transforms, png_voidp params));\n#endif\n#ifdef PNG_WRITE_SUPPORTED\nPNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr,\n    int transforms, png_voidp params));\n#endif\n#endif\n\nPNG_EXPORT(180, png_const_charp, png_get_copyright,\n    (png_const_structrp png_ptr));\nPNG_EXPORT(181, png_const_charp, png_get_header_ver,\n    (png_const_structrp png_ptr));\nPNG_EXPORT(182, png_const_charp, png_get_header_version,\n    (png_const_structrp png_ptr));\nPNG_EXPORT(183, png_const_charp, png_get_libpng_ver,\n    (png_const_structrp png_ptr));\n\n#ifdef PNG_MNG_FEATURES_SUPPORTED\nPNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr,\n    png_uint_32 mng_features_permitted));\n#endif\n\n/* For use in png_set_keep_unknown, added to version 1.2.6 */\n#define PNG_HANDLE_CHUNK_AS_DEFAULT   0\n#define PNG_HANDLE_CHUNK_NEVER        1\n#define PNG_HANDLE_CHUNK_IF_SAFE      2\n#define PNG_HANDLE_CHUNK_ALWAYS       3\n#define PNG_HANDLE_CHUNK_LAST         4\n\n/* Strip the prepended error numbers (\"#nnn \") from error and warning\n * messages before passing them to the error or warning handler.\n */\n#ifdef PNG_ERROR_NUMBERS_SUPPORTED\nPNG_EXPORT(185, void, png_set_strip_error_numbers, (png_structrp png_ptr,\n    png_uint_32 strip_mode));\n#endif\n\n/* Added in libpng-1.2.6 */\n#ifdef PNG_SET_USER_LIMITS_SUPPORTED\nPNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr,\n    png_uint_32 user_width_max, png_uint_32 user_height_max));\nPNG_EXPORT(187, png_uint_32, png_get_user_width_max,\n    (png_const_structrp png_ptr));\nPNG_EXPORT(188, png_uint_32, png_get_user_height_max,\n    (png_const_structrp png_ptr));\n/* Added in libpng-1.4.0 */\nPNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr,\n    png_uint_32 user_chunk_cache_max));\nPNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max,\n    (png_const_structrp png_ptr));\n/* Added in libpng-1.4.1 */\nPNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr,\n    png_alloc_size_t user_chunk_cache_max));\nPNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max,\n    (png_const_structrp png_ptr));\n#endif\n\n#if defined(PNG_INCH_CONVERSIONS_SUPPORTED)\nPNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr));\n\nPNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr));\n\nPNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr));\n\nPNG_FP_EXPORT(196, float, png_get_x_offset_inches,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr))\n#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */\nPNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr))\n#endif\n\nPNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr))\n#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */\nPNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed,\n    (png_const_structrp png_ptr, png_const_inforp info_ptr))\n#endif\n\n#  ifdef PNG_pHYs_SUPPORTED\nPNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr,\n    png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,\n    int *unit_type));\n#  endif /* pHYs */\n#endif  /* INCH_CONVERSIONS */\n\n/* Added in libpng-1.4.0 */\n#ifdef PNG_IO_STATE_SUPPORTED\nPNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr));\n\n/* Removed from libpng 1.6; use png_get_io_chunk_type. */\nPNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr),\n    PNG_DEPRECATED)\n\nPNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,\n    (png_const_structrp png_ptr));\n\n/* The flags returned by png_get_io_state() are the following: */\n#  define PNG_IO_NONE        0x0000   /* no I/O at this moment */\n#  define PNG_IO_READING     0x0001   /* currently reading */\n#  define PNG_IO_WRITING     0x0002   /* currently writing */\n#  define PNG_IO_SIGNATURE   0x0010   /* currently at the file signature */\n#  define PNG_IO_CHUNK_HDR   0x0020   /* currently at the chunk header */\n#  define PNG_IO_CHUNK_DATA  0x0040   /* currently at the chunk data */\n#  define PNG_IO_CHUNK_CRC   0x0080   /* currently at the chunk crc */\n#  define PNG_IO_MASK_OP     0x000f   /* current operation: reading/writing */\n#  define PNG_IO_MASK_LOC    0x00f0   /* current location: sig/hdr/data/crc */\n#endif /* IO_STATE */\n\n/* Interlace support.  The following macros are always defined so that if\n * libpng interlace handling is turned off the macros may be used to handle\n * interlaced images within the application.\n */\n#define PNG_INTERLACE_ADAM7_PASSES 7\n\n/* Two macros to return the first row and first column of the original,\n * full, image which appears in a given pass.  'pass' is in the range 0\n * to 6 and the result is in the range 0 to 7.\n */\n#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7)\n#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7)\n\n/* A macro to return the offset between pixels in the output row for a pair of\n * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that\n * follows.  Note that ROW_OFFSET is the offset from one row to the next whereas\n * COL_OFFSET is from one column to the next, within a row.\n */\n#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8)\n#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1))\n\n/* Two macros to help evaluate the number of rows or columns in each\n * pass.  This is expressed as a shift - effectively log2 of the number or\n * rows or columns in each 8x8 tile of the original image.\n */\n#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)\n#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)\n\n/* Hence two macros to determine the number of rows or columns in a given\n * pass of an image given its height or width.  In fact these macros may\n * return non-zero even though the sub-image is empty, because the other\n * dimension may be empty for a small image.\n */\n#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\\\n   -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))\n#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\\\n   -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))\n\n/* For the reader row callbacks (both progressive and sequential) it is\n * necessary to find the row in the output image given a row in an interlaced\n * image, so two more macros:\n */\n#define PNG_ROW_FROM_PASS_ROW(y_in, pass) \\\n   (((y_in)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))\n#define PNG_COL_FROM_PASS_COL(x_in, pass) \\\n   (((x_in)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))\n\n/* Two macros which return a boolean (0 or 1) saying whether the given row\n * or column is in a particular pass.  These use a common utility macro that\n * returns a mask for a given pass - the offset 'off' selects the row or\n * column version.  The mask has the appropriate bit set for each column in\n * the tile.\n */\n#define PNG_PASS_MASK(pass,off) ( \\\n   ((0x110145AF>>(((7-(off))-(pass))<<2)) & 0xF) | \\\n   ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0))\n\n#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \\\n   ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)\n#define PNG_COL_IN_INTERLACE_PASS(x, pass) \\\n   ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)\n\n#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED\n/* With these routines we avoid an integer divide, which will be slower on\n * most machines.  However, it does take more operations than the corresponding\n * divide method, so it may be slower on a few RISC systems.  There are two\n * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.\n *\n * Note that the rounding factors are NOT supposed to be the same!  128 and\n * 32768 are correct for the NODIV code; 127 and 32767 are correct for the\n * standard method.\n *\n * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]\n */\n\n /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */\n\n#  define png_composite(composite, fg, alpha, bg)         \\\n     { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \\\n           * (png_uint_16)(alpha)                         \\\n           + (png_uint_16)(bg)*(png_uint_16)(255          \\\n           - (png_uint_16)(alpha)) + 128);                \\\n       (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); }\n\n#  define png_composite_16(composite, fg, alpha, bg)       \\\n     { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg)  \\\n           * (png_uint_32)(alpha)                          \\\n           + (png_uint_32)(bg)*(65535                      \\\n           - (png_uint_32)(alpha)) + 32768);               \\\n       (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); }\n\n#else  /* Standard method using integer division */\n\n#  define png_composite(composite, fg, alpha, bg)                        \\\n     (composite) =                                                       \\\n         (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) +  \\\n         (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \\\n         127) / 255))\n\n#  define png_composite_16(composite, fg, alpha, bg)                         \\\n     (composite) =                                                           \\\n         (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \\\n         (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) +     \\\n         32767) / 65535))\n#endif /* READ_COMPOSITE_NODIV */\n\n#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED\nPNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf));\nPNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf));\nPNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf));\n#endif\n\nPNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr,\n    png_const_bytep buf));\n/* No png_get_int_16 -- may be added if there's a real need for it. */\n\n/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */\n#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED\nPNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i));\n#endif\n#ifdef PNG_SAVE_INT_32_SUPPORTED\nPNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i));\n#endif\n\n/* Place a 16-bit number into a buffer in PNG byte order.\n * The parameter is declared unsigned int, not png_uint_16,\n * just to avoid potential problems on pre-ANSI C compilers.\n */\n#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED\nPNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));\n/* No png_save_int_16 -- may be added if there's a real need for it. */\n#endif\n\n#ifdef PNG_USE_READ_MACROS\n/* Inline macros to do direct reads of bytes from the input buffer.\n * The png_get_int_32() routine assumes we are using two's complement\n * format for negative values, which is almost certainly true.\n */\n#  define PNG_get_uint_32(buf) \\\n     (((png_uint_32)(*(buf)) << 24) + \\\n      ((png_uint_32)(*((buf) + 1)) << 16) + \\\n      ((png_uint_32)(*((buf) + 2)) << 8) + \\\n      ((png_uint_32)(*((buf) + 3))))\n\n   /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the\n    * function) incorrectly returned a value of type png_uint_32.\n    */\n#  define PNG_get_uint_16(buf) \\\n     ((png_uint_16) \\\n      (((unsigned int)(*(buf)) << 8) + \\\n       ((unsigned int)(*((buf) + 1)))))\n\n#  define PNG_get_int_32(buf) \\\n     ((png_int_32)((*(buf) & 0x80) \\\n      ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \\\n      : (png_int_32)png_get_uint_32(buf)))\n\n   /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,\n    * but defining a macro name prefixed with PNG_PREFIX.\n    */\n#  ifndef PNG_PREFIX\n#     define png_get_uint_32(buf) PNG_get_uint_32(buf)\n#     define png_get_uint_16(buf) PNG_get_uint_16(buf)\n#     define png_get_int_32(buf)  PNG_get_int_32(buf)\n#  endif\n#else\n#  ifdef PNG_PREFIX\n      /* No macros; revert to the (redefined) function */\n#     define PNG_get_uint_32 (png_get_uint_32)\n#     define PNG_get_uint_16 (png_get_uint_16)\n#     define PNG_get_int_32  (png_get_int_32)\n#  endif\n#endif\n\n#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED\nPNG_EXPORT(242, void, png_set_check_for_invalid_index,\n    (png_structrp png_ptr, int allowed));\n#  ifdef PNG_GET_PALETTE_MAX_SUPPORTED\nPNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr,\n    png_const_infop info_ptr));\n#  endif\n#endif /* CHECK_FOR_INVALID_INDEX */\n\n/*******************************************************************************\n * Section 5: SIMPLIFIED API\n *******************************************************************************\n *\n * Please read the documentation in libpng-manual.txt (TODO: write said\n * documentation) if you don't understand what follows.\n *\n * The simplified API hides the details of both libpng and the PNG file format\n * itself.  It allows PNG files to be read into a very limited number of\n * in-memory bitmap formats or to be written from the same formats.  If these\n * formats do not accomodate your needs then you can, and should, use the more\n * sophisticated APIs above - these support a wide variety of in-memory formats\n * and a wide variety of sophisticated transformations to those formats as well\n * as a wide variety of APIs to manipulate ancillary information.\n *\n * To read a PNG file using the simplified API:\n *\n * 1) Declare a 'png_image' structure (see below) on the stack, set the\n *    version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL\n *    (this is REQUIRED, your program may crash if you don't do it.)\n * 2) Call the appropriate png_image_begin_read... function.\n * 3) Set the png_image 'format' member to the required sample format.\n * 4) Allocate a buffer for the image and, if required, the color-map.\n * 5) Call png_image_finish_read to read the image and, if required, the\n *    color-map into your buffers.\n *\n * There are no restrictions on the format of the PNG input itself; all valid\n * color types, bit depths, and interlace methods are acceptable, and the\n * input image is transformed as necessary to the requested in-memory format\n * during the png_image_finish_read() step.  The only caveat is that if you\n * request a color-mapped image from a PNG that is full-color or makes\n * complex use of an alpha channel the transformation is extremely lossy and the\n * result may look terrible.\n *\n * To write a PNG file using the simplified API:\n *\n * 1) Declare a 'png_image' structure on the stack and memset() it to all zero.\n * 2) Initialize the members of the structure that describe the image, setting\n *    the 'format' member to the format of the image samples.\n * 3) Call the appropriate png_image_write... function with a pointer to the\n *    image and, if necessary, the color-map to write the PNG data.\n *\n * png_image is a structure that describes the in-memory format of an image\n * when it is being read or defines the in-memory format of an image that you\n * need to write:\n */\n#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \\\n    defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)\n\n#define PNG_IMAGE_VERSION 1\n\ntypedef struct png_control *png_controlp;\ntypedef struct\n{\n   png_controlp opaque;    /* Initialize to NULL, free with png_image_free */\n   png_uint_32  version;   /* Set to PNG_IMAGE_VERSION */\n   png_uint_32  width;     /* Image width in pixels (columns) */\n   png_uint_32  height;    /* Image height in pixels (rows) */\n   png_uint_32  format;    /* Image format as defined below */\n   png_uint_32  flags;     /* A bit mask containing informational flags */\n   png_uint_32  colormap_entries;\n                           /* Number of entries in the color-map */\n\n   /* In the event of an error or warning the following field will be set to a\n    * non-zero value and the 'message' field will contain a '\\0' terminated\n    * string with the libpng error or warning message.  If both warnings and\n    * an error were encountered, only the error is recorded.  If there\n    * are multiple warnings, only the first one is recorded.\n    *\n    * The upper 30 bits of this value are reserved, the low two bits contain\n    * a value as follows:\n    */\n#  define PNG_IMAGE_WARNING 1\n#  define PNG_IMAGE_ERROR 2\n   /*\n    * The result is a two-bit code such that a value more than 1 indicates\n    * a failure in the API just called:\n    *\n    *    0 - no warning or error\n    *    1 - warning\n    *    2 - error\n    *    3 - error preceded by warning\n    */\n#  define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1)\n\n   png_uint_32  warning_or_error;\n\n   char         message[64];\n} png_image, *png_imagep;\n\n/* The samples of the image have one to four channels whose components have\n * original values in the range 0 to 1.0:\n *\n * 1: A single gray or luminance channel (G).\n * 2: A gray/luminance channel and an alpha channel (GA).\n * 3: Three red, green, blue color channels (RGB).\n * 4: Three color channels and an alpha channel (RGBA).\n *\n * The components are encoded in one of two ways:\n *\n * a) As a small integer, value 0..255, contained in a single byte.  For the\n * alpha channel the original value is simply value/255.  For the color or\n * luminance channels the value is encoded according to the sRGB specification\n * and matches the 8-bit format expected by typical display devices.\n *\n * The color/gray channels are not scaled (pre-multiplied) by the alpha\n * channel and are suitable for passing to color management software.\n *\n * b) As a value in the range 0..65535, contained in a 2-byte integer.  All\n * channels can be converted to the original value by dividing by 65535; all\n * channels are linear.  Color channels use the RGB encoding (RGB end-points) of\n * the sRGB specification.  This encoding is identified by the\n * PNG_FORMAT_FLAG_LINEAR flag below.\n *\n * When the simplified API needs to convert between sRGB and linear colorspaces,\n * the actual sRGB transfer curve defined in the sRGB specification (see the\n * article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2\n * approximation used elsewhere in libpng.\n *\n * When an alpha channel is present it is expected to denote pixel coverage\n * of the color or luminance channels and is returned as an associated alpha\n * channel: the color/gray channels are scaled (pre-multiplied) by the alpha\n * value.\n *\n * The samples are either contained directly in the image data, between 1 and 8\n * bytes per pixel according to the encoding, or are held in a color-map indexed\n * by bytes in the image data.  In the case of a color-map the color-map entries\n * are individual samples, encoded as above, and the image data has one byte per\n * pixel to select the relevant sample from the color-map.\n */\n\n/* PNG_FORMAT_*\n *\n * #defines to be used in png_image::format.  Each #define identifies a\n * particular layout of sample data and, if present, alpha values.  There are\n * separate defines for each of the two component encodings.\n *\n * A format is built up using single bit flag values.  All combinations are\n * valid.  Formats can be built up from the flag values or you can use one of\n * the predefined values below.  When testing formats always use the FORMAT_FLAG\n * macros to test for individual features - future versions of the library may\n * add new flags.\n *\n * When reading or writing color-mapped images the format should be set to the\n * format of the entries in the color-map then png_image_{read,write}_colormap\n * called to read or write the color-map and set the format correctly for the\n * image data.  Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly!\n *\n * NOTE: libpng can be built with particular features disabled. If you see\n * compiler errors because the definition of one of the following flags has been\n * compiled out it is because libpng does not have the required support.  It is\n * possible, however, for the libpng configuration to enable the format on just\n * read or just write; in that case you may see an error at run time.  You can\n * guard against this by checking for the definition of the appropriate\n * \"_SUPPORTED\" macro, one of:\n *\n *    PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED\n */\n#define PNG_FORMAT_FLAG_ALPHA    0x01U /* format with an alpha channel */\n#define PNG_FORMAT_FLAG_COLOR    0x02U /* color format: otherwise grayscale */\n#define PNG_FORMAT_FLAG_LINEAR   0x04U /* 2-byte channels else 1-byte */\n#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */\n\n#ifdef PNG_FORMAT_BGR_SUPPORTED\n#  define PNG_FORMAT_FLAG_BGR    0x10U /* BGR colors, else order is RGB */\n#endif\n\n#ifdef PNG_FORMAT_AFIRST_SUPPORTED\n#  define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */\n#endif\n\n/* Commonly used formats have predefined macros.\n *\n * First the single byte (sRGB) formats:\n */\n#define PNG_FORMAT_GRAY 0\n#define PNG_FORMAT_GA   PNG_FORMAT_FLAG_ALPHA\n#define PNG_FORMAT_AG   (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST)\n#define PNG_FORMAT_RGB  PNG_FORMAT_FLAG_COLOR\n#define PNG_FORMAT_BGR  (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR)\n#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA)\n#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST)\n#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA)\n#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST)\n\n/* Then the linear 2-byte formats.  When naming these \"Y\" is used to\n * indicate a luminance (gray) channel.\n */\n#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR\n#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA)\n#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR)\n#define PNG_FORMAT_LINEAR_RGB_ALPHA \\\n   (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA)\n\n/* With color-mapped formats the image data is one byte for each pixel, the byte\n * is an index into the color-map which is formatted as above.  To obtain a\n * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP\n * to one of the above definitions, or you can use one of the definitions below.\n */\n#define PNG_FORMAT_RGB_COLORMAP  (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP)\n#define PNG_FORMAT_BGR_COLORMAP  (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP)\n#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP)\n#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP)\n#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP)\n#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP)\n\n/* PNG_IMAGE macros\n *\n * These are convenience macros to derive information from a png_image\n * structure.  The PNG_IMAGE_SAMPLE_ macros return values appropriate to the\n * actual image sample values - either the entries in the color-map or the\n * pixels in the image.  The PNG_IMAGE_PIXEL_ macros return corresponding values\n * for the pixels and will always return 1 for color-mapped formats.  The\n * remaining macros return information about the rows in the image and the\n * complete image.\n *\n * NOTE: All the macros that take a png_image::format parameter are compile time\n * constants if the format parameter is, itself, a constant.  Therefore these\n * macros can be used in array declarations and case labels where required.\n * Similarly the macros are also pre-processor constants (sizeof is not used) so\n * they can be used in #if tests.\n *\n * First the information about the samples.\n */\n#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\\\n   (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1)\n   /* Return the total number of channels in a given format: 1..4 */\n\n#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\\\n   ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1)\n   /* Return the size in bytes of a single component of a pixel or color-map\n    * entry (as appropriate) in the image: 1 or 2.\n    */\n\n#define PNG_IMAGE_SAMPLE_SIZE(fmt)\\\n   (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt))\n   /* This is the size of the sample data for one sample.  If the image is\n    * color-mapped it is the size of one color-map entry (and image pixels are\n    * one byte in size), otherwise it is the size of one image pixel.\n    */\n\n#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\\\n   (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256)\n   /* The maximum size of the color-map required by the format expressed in a\n    * count of components.  This can be used to compile-time allocate a\n    * color-map:\n    *\n    * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)];\n    *\n    * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)];\n    *\n    * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the\n    * information from one of the png_image_begin_read_ APIs and dynamically\n    * allocate the required memory.\n    */\n\n/* Corresponding information about the pixels */\n#define PNG_IMAGE_PIXEL_(test,fmt)\\\n   (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt))\n\n#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\\\n   PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt)\n   /* The number of separate channels (components) in a pixel; 1 for a\n    * color-mapped image.\n    */\n\n#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\\\n   PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt)\n   /* The size, in bytes, of each component in a pixel; 1 for a color-mapped\n    * image.\n    */\n\n#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt)\n   /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */\n\n/* Information about the whole row, or whole image */\n#define PNG_IMAGE_ROW_STRIDE(image)\\\n   (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width)\n   /* Return the total number of components in a single row of the image; this\n    * is the minimum 'row stride', the minimum count of components between each\n    * row.  For a color-mapped image this is the minimum number of bytes in a\n    * row.\n    *\n    * WARNING: this macro overflows for some images with more than one component\n    * and very large image widths.  libpng will refuse to process an image where\n    * this macro would overflow.\n    */\n\n#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\\\n   (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride))\n   /* Return the size, in bytes, of an image buffer given a png_image and a row\n    * stride - the number of components to leave space for in each row.\n    *\n    * WARNING: this macro overflows a 32-bit integer for some large PNG images,\n    * libpng will refuse to process an image where such an overflow would occur.\n    */\n\n#define PNG_IMAGE_SIZE(image)\\\n   PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image))\n   /* Return the size, in bytes, of the image in memory given just a png_image;\n    * the row stride is the minimum stride required for the image.\n    */\n\n#define PNG_IMAGE_COLORMAP_SIZE(image)\\\n   (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries)\n   /* Return the size, in bytes, of the color-map of this image.  If the image\n    * format is not a color-map format this will return a size sufficient for\n    * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if\n    * you don't want to allocate a color-map in this case.\n    */\n\n/* PNG_IMAGE_FLAG_*\n *\n * Flags containing additional information about the image are held in the\n * 'flags' field of png_image.\n */\n#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01\n   /* This indicates the the RGB values of the in-memory bitmap do not\n    * correspond to the red, green and blue end-points defined by sRGB.\n    */\n\n#define PNG_IMAGE_FLAG_FAST 0x02\n   /* On write emphasise speed over compression; the resultant PNG file will be\n    * larger but will be produced significantly faster, particular for large\n    * images.  Do not use this option for images which will be distributed, only\n    * used it when producing intermediate files that will be read back in\n    * repeatedly.  For a typical 24-bit image the option will double the read\n    * speed at the cost of increasing the image size by 25%, however for many\n    * more compressible images the PNG file can be 10 times larger with only a\n    * slight speed gain.\n    */\n\n#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04\n   /* On read if the image is a 16-bit per component image and there is no gAMA\n    * or sRGB chunk assume that the components are sRGB encoded.  Notice that\n    * images output by the simplified API always have gamma information; setting\n    * this flag only affects the interpretation of 16-bit images from an\n    * external source.  It is recommended that the application expose this flag\n    * to the user; the user can normally easily recognize the difference between\n    * linear and sRGB encoding.  This flag has no effect on write - the data\n    * passed to the write APIs must have the correct encoding (as defined\n    * above.)\n    *\n    * If the flag is not set (the default) input 16-bit per component data is\n    * assumed to be linear.\n    *\n    * NOTE: the flag can only be set after the png_image_begin_read_ call,\n    * because that call initializes the 'flags' field.\n    */\n\n#ifdef PNG_SIMPLIFIED_READ_SUPPORTED\n/* READ APIs\n * ---------\n *\n * The png_image passed to the read APIs must have been initialized by setting\n * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.)\n */\n#ifdef PNG_STDIO_SUPPORTED\nPNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image,\n   const char *file_name));\n   /* The named file is opened for read and the image header is filled in\n    * from the PNG header in the file.\n    */\n\nPNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image,\n   FILE* file));\n   /* The PNG header is read from the stdio FILE object. */\n#endif /* STDIO */\n\nPNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image,\n   png_const_voidp memory, png_size_t size));\n   /* The PNG header is read from the given memory buffer. */\n\nPNG_EXPORT(237, int, png_image_finish_read, (png_imagep image,\n   png_const_colorp background, void *buffer, png_int_32 row_stride,\n   void *colormap));\n   /* Finish reading the image into the supplied buffer and clean up the\n    * png_image structure.\n    *\n    * row_stride is the step, in byte or 2-byte units as appropriate,\n    * between adjacent rows.  A positive stride indicates that the top-most row\n    * is first in the buffer - the normal top-down arrangement.  A negative\n    * stride indicates that the bottom-most row is first in the buffer.\n    *\n    * background need only be supplied if an alpha channel must be removed from\n    * a png_byte format and the removal is to be done by compositing on a solid\n    * color; otherwise it may be NULL and any composition will be done directly\n    * onto the buffer.  The value is an sRGB color to use for the background,\n    * for grayscale output the green channel is used.\n    *\n    * background must be supplied when an alpha channel must be removed from a\n    * single byte color-mapped output format, in other words if:\n    *\n    * 1) The original format from png_image_begin_read_from_* had\n    *    PNG_FORMAT_FLAG_ALPHA set.\n    * 2) The format set by the application does not.\n    * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and\n    *    PNG_FORMAT_FLAG_LINEAR *not* set.\n    *\n    * For linear output removing the alpha channel is always done by compositing\n    * on black and background is ignored.\n    *\n    * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set.  It must\n    * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE.\n    * image->colormap_entries will be updated to the actual number of entries\n    * written to the colormap; this may be less than the original value.\n    */\n\nPNG_EXPORT(238, void, png_image_free, (png_imagep image));\n   /* Free any data allocated by libpng in image->opaque, setting the pointer to\n    * NULL.  May be called at any time after the structure is initialized.\n    */\n#endif /* SIMPLIFIED_READ */\n\n#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED\n/* WRITE APIS\n * ----------\n * For write you must initialize a png_image structure to describe the image to\n * be written.  To do this use memset to set the whole structure to 0 then\n * initialize fields describing your image.\n *\n * version: must be set to PNG_IMAGE_VERSION\n * opaque: must be initialized to NULL\n * width: image width in pixels\n * height: image height in rows\n * format: the format of the data (image and color-map) you wish to write\n * flags: set to 0 unless one of the defined flags applies; set\n *    PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB\n *    values do not correspond to the colors in sRGB.\n * colormap_entries: set to the number of entries in the color-map (0 to 256)\n */\n#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED\nPNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image,\n   const char *file, int convert_to_8bit, const void *buffer,\n   png_int_32 row_stride, const void *colormap));\n   /* Write the image to the named file. */\n\nPNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,\n   int convert_to_8_bit, const void *buffer, png_int_32 row_stride,\n   const void *colormap));\n   /* Write the image to the given (FILE*). */\n#endif /* SIMPLIFIED_WRITE_STDIO */\n\n/* With all write APIs if image is in one of the linear formats with 16-bit\n * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG\n * gamma encoded according to the sRGB specification, otherwise a 16-bit linear\n * encoded PNG file is written.\n *\n * With color-mapped data formats the colormap parameter point to a color-map\n * with at least image->colormap_entries encoded in the specified format.  If\n * the format is linear the written PNG color-map will be converted to sRGB\n * regardless of the convert_to_8_bit flag.\n *\n * With all APIs row_stride is handled as in the read APIs - it is the spacing\n * from one row to the next in component sized units (1 or 2 bytes) and if\n * negative indicates a bottom-up row layout in the buffer.  If row_stride is\n * zero, libpng will calculate it for you from the image width and number of\n * channels.\n *\n * Note that the write API does not support interlacing, sub-8-bit pixels or\n * most ancillary chunks.  If you need to write text chunks (e.g. for copyright\n * notices) you need to use one of the other APIs.\n */\n\nPNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,\n   png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8_bit,\n   const void *buffer, png_int_32 row_stride, const void *colormap));\n   /* Write the image to the given memory buffer.  The function both writes the\n    * whole PNG data stream to *memory and updates *memory_bytes with the count\n    * of bytes written.\n    *\n    * 'memory' may be NULL.  In this case *memory_bytes is not read however on\n    * success the number of bytes which would have been written will still be\n    * stored in *memory_bytes.  On failure *memory_bytes will contain 0.\n    *\n    * If 'memory' is not NULL it must point to memory[*memory_bytes] of\n    * writeable memory.\n    *\n    * If the function returns success memory[*memory_bytes] (if 'memory' is not\n    * NULL) contains the written PNG data.  *memory_bytes will always be less\n    * than or equal to the original value.\n    *\n    * If the function returns false and *memory_bytes was not changed an error\n    * occured during write.  If *memory_bytes was changed, or is not 0 if\n    * 'memory' was NULL, the write would have succeeded but for the memory\n    * buffer being too small.  *memory_bytes contains the required number of\n    * bytes and will be bigger that the original value.\n    */\n\n#define png_image_write_get_memory_size(image, size, convert_to_8_bit, buffer,\\\n   row_stride, colormap)\\\n   png_image_write_to_memory(&(image), 0, &(size), convert_to_8_bit, buffer,\\\n         row_stride, colormap)\n   /* Return the amount of memory in 'size' required to compress this image.\n    * The png_image structure 'image' must be filled in as in the above\n    * function and must not be changed before the actual write call, the buffer\n    * and all other parameters must also be identical to that in the final\n    * write call.  The 'size' variable need not be initialized.\n    *\n    * NOTE: the macro returns true/false, if false is returned 'size' will be\n    * set to zero and the write failed and probably will fail if tried again.\n    */\n\n/* You can pre-allocate the buffer by making sure it is of sufficient size\n * regardless of the amount of compression achieved.  The buffer size will\n * always be bigger than the original image and it will never be filled.  The\n * following macros are provided to assist in allocating the buffer.\n */\n#define PNG_IMAGE_DATA_SIZE(image) (PNG_IMAGE_SIZE(image)+(image).height)\n   /* The number of uncompressed bytes in the PNG byte encoding of the image;\n    * uncompressing the PNG IDAT data will give this number of bytes.\n    *\n    * NOTE: while PNG_IMAGE_SIZE cannot overflow for an image in memory this\n    * macro can because of the extra bytes used in the PNG byte encoding.  You\n    * need to avoid this macro if your image size approaches 2^30 in width or\n    * height.  The same goes for the remainder of these macros; they all produce\n    * bigger numbers than the actual in-memory image size.\n    */\n#ifndef PNG_ZLIB_MAX_SIZE\n#  define PNG_ZLIB_MAX_SIZE(b) ((b)+(((b)+7U)>>3)+(((b)+63U)>>6)+11U)\n   /* An upper bound on the number of compressed bytes given 'b' uncompressed\n    * bytes.  This is based on deflateBounds() in zlib; different\n    * implementations of zlib compression may conceivably produce more data so\n    * if your zlib implementation is not zlib itself redefine this macro\n    * appropriately.\n    */\n#endif\n\n#define PNG_IMAGE_COMPRESSED_SIZE_MAX(image)\\\n   PNG_ZLIB_MAX_SIZE((png_alloc_size_t)PNG_IMAGE_DATA_SIZE(image))\n   /* An upper bound on the size of the data in the PNG IDAT chunks. */\n\n#define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\\\n   ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\\\n    (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\\\n     12U+3U*(image).colormap_entries/*PLTE data*/+\\\n     (((image).format&PNG_FORMAT_FLAG_ALPHA)?\\\n      12U/*tRNS*/+(image).colormap_entries:0U):0U)+\\\n    12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size))\n   /* A helper for the following macro; if your compiler cannot handle the\n    * following macro use this one with the result of\n    * PNG_IMAGE_COMPRESSED_SIZE_MAX(image) as the second argument (most\n    * compilers should handle this just fine.)\n    */\n\n#define PNG_IMAGE_PNG_SIZE_MAX(image)\\\n   PNG_IMAGE_PNG_SIZE_MAX_(image, PNG_IMAGE_COMPRESSED_SIZE_MAX(image))\n   /* An upper bound on the total length of the PNG data stream for 'image'.\n    * The result is of type png_alloc_size_t, on 32-bit systems this may\n    * overflow even though PNG_IMAGE_DATA_SIZE does not overflow; the write will\n    * run out of buffer space but return a corrected size which should work.\n    */\n#endif /* SIMPLIFIED_WRITE */\n/*******************************************************************************\n *  END OF SIMPLIFIED API\n ******************************************************************************/\n#endif /* SIMPLIFIED_{READ|WRITE} */\n\n/*******************************************************************************\n * Section 6: IMPLEMENTATION OPTIONS\n *******************************************************************************\n *\n * Support for arbitrary implementation-specific optimizations.  The API allows\n * particular options to be turned on or off.  'Option' is the number of the\n * option and 'onoff' is 0 (off) or non-0 (on).  The value returned is given\n * by the PNG_OPTION_ defines below.\n *\n * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions,\n *           are detected at run time, however sometimes it may be impossible\n *           to do this in user mode, in which case it is necessary to discover\n *           the capabilities in an OS specific way.  Such capabilities are\n *           listed here when libpng has support for them and must be turned\n *           ON by the application if present.\n *\n * SOFTWARE: sometimes software optimizations actually result in performance\n *           decrease on some architectures or systems, or with some sets of\n *           PNG images.  'Software' options allow such optimizations to be\n *           selected at run time.\n */\n#ifdef PNG_SET_OPTION_SUPPORTED\n#ifdef PNG_ARM_NEON_API_SUPPORTED\n#  define PNG_ARM_NEON   0 /* HARDWARE: ARM Neon SIMD instructions supported */\n#endif\n#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */\n#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */\n#define PNG_OPTION_NEXT  6 /* Next option - numbers must be even */\n\n/* Return values: NOTE: there are four values and 'off' is *not* zero */\n#define PNG_OPTION_UNSET   0 /* Unset - defaults to off */\n#define PNG_OPTION_INVALID 1 /* Option number out of range */\n#define PNG_OPTION_OFF     2\n#define PNG_OPTION_ON      3\n\nPNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option,\n   int onoff));\n#endif /* SET_OPTION */\n\n/*******************************************************************************\n *  END OF HARDWARE AND SOFTWARE OPTIONS\n ******************************************************************************/\n\n/* Maintainer: Put new public prototypes here ^, in libpng.3, in project\n * defs, and in scripts/symbols.def.\n */\n\n/* The last ordinal number (this is the *last* one already used; the next\n * one to use is one more than this.)\n */\n#ifdef PNG_EXPORT_LAST_ORDINAL\n  PNG_EXPORT_LAST_ORDINAL(245);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* PNG_VERSION_INFO_ONLY */\n/* Do not put anything past this line */\n#endif /* PNG_H */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngconf.h",
    "content": "\n/* pngconf.h - machine configurable file for libpng\n *\n * libpng version 1.6.22beta03, February 8, 2016\n *\n * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * Any machine specific code is near the front of this file, so if you\n * are configuring libpng for a machine, you may want to read the section\n * starting here down to where it starts to typedef png_color, png_text,\n * and png_info.\n */\n\n#ifndef PNGCONF_H\n#define PNGCONF_H\n\n#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */\n\n/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 (\"ISOC90\") compliant C\n * compiler for correct compilation.  The following header files are required by\n * the standard.  If your compiler doesn't provide these header files, or they\n * do not match the standard, you will need to provide/improve them.\n */\n#include <limits.h>\n#include <stddef.h>\n\n/* Library header files.  These header files are all defined by ISOC90; libpng\n * expects conformant implementations, however, an ISOC90 conformant system need\n * not provide these header files if the functionality cannot be implemented.\n * In this case it will be necessary to disable the relevant parts of libpng in\n * the build of pnglibconf.h.\n *\n * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not\n * include this unnecessary header file.\n */\n\n#ifdef PNG_STDIO_SUPPORTED\n   /* Required for the definition of FILE: */\n#  include <stdio.h>\n#endif\n\n#ifdef PNG_SETJMP_SUPPORTED\n   /* Required for the definition of jmp_buf and the declaration of longjmp: */\n#  include <setjmp.h>\n#endif\n\n#ifdef PNG_CONVERT_tIME_SUPPORTED\n   /* Required for struct tm: */\n#  include <time.h>\n#endif\n\n#endif /* PNG_BUILDING_SYMBOL_TABLE */\n\n/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using\n * PNG_NO_CONST; this is no longer supported except for data declarations which\n * apparently still cause problems in 2011 on some compilers.\n */\n#define PNG_CONST const /* backward compatibility only */\n\n/* This controls optimization of the reading of 16-bit and 32-bit values\n * from PNG files.  It can be set on a per-app-file basis - it\n * just changes whether a macro is used when the function is called.\n * The library builder sets the default; if read functions are not\n * built into the library the macro implementation is forced on.\n */\n#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED\n#  define PNG_USE_READ_MACROS\n#endif\n#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS)\n#  if PNG_DEFAULT_READ_MACROS\n#    define PNG_USE_READ_MACROS\n#  endif\n#endif\n\n/* COMPILER SPECIFIC OPTIONS.\n *\n * These options are provided so that a variety of difficult compilers\n * can be used.  Some are fixed at build time (e.g. PNG_API_RULE\n * below) but still have compiler specific implementations, others\n * may be changed on a per-file basis when compiling against libpng.\n */\n\n/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect\n * against legacy (pre ISOC90) compilers that did not understand function\n * prototypes.  It is not required for modern C compilers.\n */\n#ifndef PNGARG\n#  define PNGARG(arglist) arglist\n#endif\n\n/* Function calling conventions.\n * =============================\n * Normally it is not necessary to specify to the compiler how to call\n * a function - it just does it - however on x86 systems derived from\n * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems\n * and some others) there are multiple ways to call a function and the\n * default can be changed on the compiler command line.  For this reason\n * libpng specifies the calling convention of every exported function and\n * every function called via a user supplied function pointer.  This is\n * done in this file by defining the following macros:\n *\n * PNGAPI    Calling convention for exported functions.\n * PNGCBAPI  Calling convention for user provided (callback) functions.\n * PNGCAPI   Calling convention used by the ANSI-C library (required\n *           for longjmp callbacks and sometimes used internally to\n *           specify the calling convention for zlib).\n *\n * These macros should never be overridden.  If it is necessary to\n * change calling convention in a private build this can be done\n * by setting PNG_API_RULE (which defaults to 0) to one of the values\n * below to select the correct 'API' variants.\n *\n * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout.\n *                This is correct in every known environment.\n * PNG_API_RULE=1 Use the operating system convention for PNGAPI and\n *                the 'C' calling convention (from PNGCAPI) for\n *                callbacks (PNGCBAPI).  This is no longer required\n *                in any known environment - if it has to be used\n *                please post an explanation of the problem to the\n *                libpng mailing list.\n *\n * These cases only differ if the operating system does not use the C\n * calling convention, at present this just means the above cases\n * (x86 DOS/Windows sytems) and, even then, this does not apply to\n * Cygwin running on those systems.\n *\n * Note that the value must be defined in pnglibconf.h so that what\n * the application uses to call the library matches the conventions\n * set when building the library.\n */\n\n/* Symbol export\n * =============\n * When building a shared library it is almost always necessary to tell\n * the compiler which symbols to export.  The png.h macro 'PNG_EXPORT'\n * is used to mark the symbols.  On some systems these symbols can be\n * extracted at link time and need no special processing by the compiler,\n * on other systems the symbols are flagged by the compiler and just\n * the declaration requires a special tag applied (unfortunately) in a\n * compiler dependent way.  Some systems can do either.\n *\n * A small number of older systems also require a symbol from a DLL to\n * be flagged to the program that calls it.  This is a problem because\n * we do not know in the header file included by application code that\n * the symbol will come from a shared library, as opposed to a statically\n * linked one.  For this reason the application must tell us by setting\n * the magic flag PNG_USE_DLL to turn on the special processing before\n * it includes png.h.\n *\n * Four additional macros are used to make this happen:\n *\n * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from\n *            the build or imported if PNG_USE_DLL is set - compiler\n *            and system specific.\n *\n * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to\n *                       'type', compiler specific.\n *\n * PNG_DLL_EXPORT Set to the magic to use during a libpng build to\n *                make a symbol exported from the DLL.  Not used in the\n *                public header files; see pngpriv.h for how it is used\n *                in the libpng build.\n *\n * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come\n *                from a DLL - used to define PNG_IMPEXP when\n *                PNG_USE_DLL is set.\n */\n\n/* System specific discovery.\n * ==========================\n * This code is used at build time to find PNG_IMPEXP, the API settings\n * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL\n * import processing is possible.  On Windows systems it also sets\n * compiler-specific macros to the values required to change the calling\n * conventions of the various functions.\n */\n#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\\\n    defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)\n  /* Windows system (DOS doesn't support DLLs).  Includes builds under Cygwin or\n   * MinGW on any architecture currently supported by Windows.  Also includes\n   * Watcom builds but these need special treatment because they are not\n   * compatible with GCC or Visual C because of different calling conventions.\n   */\n#  if PNG_API_RULE == 2\n    /* If this line results in an error, either because __watcall is not\n     * understood or because of a redefine just below you cannot use *this*\n     * build of the library with the compiler you are using.  *This* build was\n     * build using Watcom and applications must also be built using Watcom!\n     */\n#    define PNGCAPI __watcall\n#  endif\n\n#  if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))\n#    define PNGCAPI __cdecl\n#    if PNG_API_RULE == 1\n       /* If this line results in an error __stdcall is not understood and\n        * PNG_API_RULE should not have been set to '1'.\n        */\n#      define PNGAPI __stdcall\n#    endif\n#  else\n    /* An older compiler, or one not detected (erroneously) above,\n     * if necessary override on the command line to get the correct\n     * variants for the compiler.\n     */\n#    ifndef PNGCAPI\n#      define PNGCAPI _cdecl\n#    endif\n#    if PNG_API_RULE == 1 && !defined(PNGAPI)\n#      define PNGAPI _stdcall\n#    endif\n#  endif /* compiler/api */\n\n  /* NOTE: PNGCBAPI always defaults to PNGCAPI. */\n\n#  if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD)\n#     error \"PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed\"\n#  endif\n\n#  if (defined(_MSC_VER) && _MSC_VER < 800) ||\\\n      (defined(__BORLANDC__) && __BORLANDC__ < 0x500)\n    /* older Borland and MSC\n     * compilers used '__export' and required this to be after\n     * the type.\n     */\n#    ifndef PNG_EXPORT_TYPE\n#      define PNG_EXPORT_TYPE(type) type PNG_IMPEXP\n#    endif\n#    define PNG_DLL_EXPORT __export\n#  else /* newer compiler */\n#    define PNG_DLL_EXPORT __declspec(dllexport)\n#    ifndef PNG_DLL_IMPORT\n#      define PNG_DLL_IMPORT __declspec(dllimport)\n#    endif\n#  endif /* compiler */\n\n#else /* !Windows */\n#  if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)\n#    define PNGAPI _System\n#  else /* !Windows/x86 && !OS/2 */\n    /* Use the defaults, or define PNG*API on the command line (but\n     * this will have to be done for every compile!)\n     */\n#  endif /* other system, !OS/2 */\n#endif /* !Windows/x86 */\n\n/* Now do all the defaulting . */\n#ifndef PNGCAPI\n#  define PNGCAPI\n#endif\n#ifndef PNGCBAPI\n#  define PNGCBAPI PNGCAPI\n#endif\n#ifndef PNGAPI\n#  define PNGAPI PNGCAPI\n#endif\n\n/* PNG_IMPEXP may be set on the compilation system command line or (if not set)\n * then in an internal header file when building the library, otherwise (when\n * using the library) it is set here.\n */\n#ifndef PNG_IMPEXP\n#  if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)\n     /* This forces use of a DLL, disallowing static linking */\n#    define PNG_IMPEXP PNG_DLL_IMPORT\n#  endif\n\n#  ifndef PNG_IMPEXP\n#    define PNG_IMPEXP\n#  endif\n#endif\n\n/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat\n * 'attributes' as a storage class - the attributes go at the start of the\n * function definition, and attributes are always appended regardless of the\n * compiler.  This considerably simplifies these macros but may cause problems\n * if any compilers both need function attributes and fail to handle them as\n * a storage class (this is unlikely.)\n */\n#ifndef PNG_FUNCTION\n#  define PNG_FUNCTION(type, name, args, attributes) attributes type name args\n#endif\n\n#ifndef PNG_EXPORT_TYPE\n#  define PNG_EXPORT_TYPE(type) PNG_IMPEXP type\n#endif\n\n   /* The ordinal value is only relevant when preprocessing png.h for symbol\n    * table entries, so we discard it here.  See the .dfn files in the\n    * scripts directory.\n    */\n\n#ifndef PNG_EXPORTA\n#  define PNG_EXPORTA(ordinal, type, name, args, attributes) \\\n      PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), PNGARG(args), \\\n      PNG_LINKAGE_API attributes)\n#endif\n\n/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument,\n * so make something non-empty to satisfy the requirement:\n */\n#define PNG_EMPTY /*empty list*/\n\n#define PNG_EXPORT(ordinal, type, name, args) \\\n   PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY)\n\n/* Use PNG_REMOVED to comment out a removed interface. */\n#ifndef PNG_REMOVED\n#  define PNG_REMOVED(ordinal, type, name, args, attributes)\n#endif\n\n#ifndef PNG_CALLBACK\n#  define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args)\n#endif\n\n/* Support for compiler specific function attributes.  These are used\n * so that where compiler support is available incorrect use of API\n * functions in png.h will generate compiler warnings.\n *\n * Added at libpng-1.2.41.\n */\n\n#ifndef PNG_NO_PEDANTIC_WARNINGS\n#  ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED\n#    define PNG_PEDANTIC_WARNINGS_SUPPORTED\n#  endif\n#endif\n\n#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED\n  /* Support for compiler specific function attributes.  These are used\n   * so that where compiler support is available, incorrect use of API\n   * functions in png.h will generate compiler warnings.  Added at libpng\n   * version 1.2.41.  Disabling these removes the warnings but may also produce\n   * less efficient code.\n   */\n#  if defined(__clang__) && defined(__has_attribute)\n     /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */\n#    if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)\n#      define PNG_USE_RESULT __attribute__((__warn_unused_result__))\n#    endif\n#    if !defined(PNG_NORETURN) && __has_attribute(__noreturn__)\n#      define PNG_NORETURN __attribute__((__noreturn__))\n#    endif\n#    if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__)\n#      define PNG_ALLOCATED __attribute__((__malloc__))\n#    endif\n#    if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__)\n#      define PNG_DEPRECATED __attribute__((__deprecated__))\n#    endif\n#    if !defined(PNG_PRIVATE)\n#      ifdef __has_extension\n#        if __has_extension(attribute_unavailable_with_message)\n#          define PNG_PRIVATE __attribute__((__unavailable__(\\\n             \"This function is not exported by libpng.\")))\n#        endif\n#      endif\n#    endif\n#    ifndef PNG_RESTRICT\n#      define PNG_RESTRICT __restrict\n#    endif\n\n#  elif defined(__GNUC__)\n#    ifndef PNG_USE_RESULT\n#      define PNG_USE_RESULT __attribute__((__warn_unused_result__))\n#    endif\n#    ifndef PNG_NORETURN\n#      define PNG_NORETURN   __attribute__((__noreturn__))\n#    endif\n#    if __GNUC__ >= 3\n#      ifndef PNG_ALLOCATED\n#        define PNG_ALLOCATED  __attribute__((__malloc__))\n#      endif\n#      ifndef PNG_DEPRECATED\n#        define PNG_DEPRECATED __attribute__((__deprecated__))\n#      endif\n#      ifndef PNG_PRIVATE\n#        if 0 /* Doesn't work so we use deprecated instead*/\n#          define PNG_PRIVATE \\\n            __attribute__((warning(\"This function is not exported by libpng.\")))\n#        else\n#          define PNG_PRIVATE \\\n            __attribute__((__deprecated__))\n#        endif\n#      endif\n#      if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1))\n#        ifndef PNG_RESTRICT\n#          define PNG_RESTRICT __restrict\n#        endif\n#      endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */\n#    endif /* __GNUC__ >= 3 */\n\n#  elif defined(_MSC_VER)  && (_MSC_VER >= 1300)\n#    ifndef PNG_USE_RESULT\n#      define PNG_USE_RESULT /* not supported */\n#    endif\n#    ifndef PNG_NORETURN\n#      define PNG_NORETURN   __declspec(noreturn)\n#    endif\n#    ifndef PNG_ALLOCATED\n#      if (_MSC_VER >= 1400)\n#        define PNG_ALLOCATED __declspec(restrict)\n#      endif\n#    endif\n#    ifndef PNG_DEPRECATED\n#      define PNG_DEPRECATED __declspec(deprecated)\n#    endif\n#    ifndef PNG_PRIVATE\n#      define PNG_PRIVATE __declspec(deprecated)\n#    endif\n#    ifndef PNG_RESTRICT\n#      if (_MSC_VER >= 1400)\n#        define PNG_RESTRICT __restrict\n#      endif\n#    endif\n\n#  elif defined(__WATCOMC__)\n#    ifndef PNG_RESTRICT\n#      define PNG_RESTRICT __restrict\n#    endif\n#  endif\n#endif /* PNG_PEDANTIC_WARNINGS */\n\n#ifndef PNG_DEPRECATED\n#  define PNG_DEPRECATED  /* Use of this function is deprecated */\n#endif\n#ifndef PNG_USE_RESULT\n#  define PNG_USE_RESULT  /* The result of this function must be checked */\n#endif\n#ifndef PNG_NORETURN\n#  define PNG_NORETURN    /* This function does not return */\n#endif\n#ifndef PNG_ALLOCATED\n#  define PNG_ALLOCATED   /* The result of the function is new memory */\n#endif\n#ifndef PNG_PRIVATE\n#  define PNG_PRIVATE     /* This is a private libpng function */\n#endif\n#ifndef PNG_RESTRICT\n#  define PNG_RESTRICT    /* The C99 \"restrict\" feature */\n#endif\n\n#ifndef PNG_FP_EXPORT     /* A floating point API. */\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\n#     define PNG_FP_EXPORT(ordinal, type, name, args)\\\n         PNG_EXPORT(ordinal, type, name, args);\n#  else                   /* No floating point APIs */\n#     define PNG_FP_EXPORT(ordinal, type, name, args)\n#  endif\n#endif\n#ifndef PNG_FIXED_EXPORT  /* A fixed point API. */\n#  ifdef PNG_FIXED_POINT_SUPPORTED\n#     define PNG_FIXED_EXPORT(ordinal, type, name, args)\\\n         PNG_EXPORT(ordinal, type, name, args);\n#  else                   /* No fixed point APIs */\n#     define PNG_FIXED_EXPORT(ordinal, type, name, args)\n#  endif\n#endif\n\n#ifndef PNG_BUILDING_SYMBOL_TABLE\n/* Some typedefs to get us started.  These should be safe on most of the common\n * platforms.\n *\n * png_uint_32 and png_int_32 may, currently, be larger than required to hold a\n * 32-bit value however this is not normally advisable.\n *\n * png_uint_16 and png_int_16 should always be two bytes in size - this is\n * verified at library build time.\n *\n * png_byte must always be one byte in size.\n *\n * The checks below use constants from limits.h, as defined by the ISOC90\n * standard.\n */\n#if CHAR_BIT == 8 && UCHAR_MAX == 255\n   typedef unsigned char png_byte;\n#else\n#  error \"libpng requires 8-bit bytes\"\n#endif\n\n#if INT_MIN == -32768 && INT_MAX == 32767\n   typedef int png_int_16;\n#elif SHRT_MIN == -32768 && SHRT_MAX == 32767\n   typedef short png_int_16;\n#else\n#  error \"libpng requires a signed 16-bit type\"\n#endif\n\n#if UINT_MAX == 65535\n   typedef unsigned int png_uint_16;\n#elif USHRT_MAX == 65535\n   typedef unsigned short png_uint_16;\n#else\n#  error \"libpng requires an unsigned 16-bit type\"\n#endif\n\n#if INT_MIN < -2147483646 && INT_MAX > 2147483646\n   typedef int png_int_32;\n#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646\n   typedef long int png_int_32;\n#else\n#  error \"libpng requires a signed 32-bit (or more) type\"\n#endif\n\n#if UINT_MAX > 4294967294\n   typedef unsigned int png_uint_32;\n#elif ULONG_MAX > 4294967294\n   typedef unsigned long int png_uint_32;\n#else\n#  error \"libpng requires an unsigned 32-bit (or more) type\"\n#endif\n\n/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however,\n * requires an ISOC90 compiler and relies on consistent behavior of sizeof.\n */\ntypedef size_t png_size_t;\ntypedef ptrdiff_t png_ptrdiff_t;\n\n/* libpng needs to know the maximum value of 'size_t' and this controls the\n * definition of png_alloc_size_t, below.  This maximum value of size_t limits\n * but does not control the maximum allocations the library makes - there is\n * direct application control of this through png_set_user_limits().\n */\n#ifndef PNG_SMALL_SIZE_T\n   /* Compiler specific tests for systems where size_t is known to be less than\n    * 32 bits (some of these systems may no longer work because of the lack of\n    * 'far' support; see above.)\n    */\n#  if (defined(__TURBOC__) && !defined(__FLAT__)) ||\\\n   (defined(_MSC_VER) && defined(MAXSEG_64K))\n#     define PNG_SMALL_SIZE_T\n#  endif\n#endif\n\n/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no\n * smaller than png_uint_32.  Casts from png_size_t or png_uint_32 to\n * png_alloc_size_t are not necessary; in fact, it is recommended not to use\n * them at all so that the compiler can complain when something turns out to be\n * problematic.\n *\n * Casts in the other direction (from png_alloc_size_t to png_size_t or\n * png_uint_32) should be explicitly applied; however, we do not expect to\n * encounter practical situations that require such conversions.\n *\n * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than\n * 4294967295 - i.e. less than the maximum value of png_uint_32.\n */\n#ifdef PNG_SMALL_SIZE_T\n   typedef png_uint_32 png_alloc_size_t;\n#else\n   typedef png_size_t png_alloc_size_t;\n#endif\n\n/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler\n * implementations of Intel CPU specific support of user-mode segmented address\n * spaces, where 16-bit pointers address more than 65536 bytes of memory using\n * separate 'segment' registers.  The implementation requires two different\n * types of pointer (only one of which includes the segment value.)\n *\n * If required this support is available in version 1.2 of libpng and may be\n * available in versions through 1.5, although the correctness of the code has\n * not been verified recently.\n */\n\n/* Typedef for floating-point numbers that are converted to fixed-point with a\n * multiple of 100,000, e.g., gamma\n */\ntypedef png_int_32 png_fixed_point;\n\n/* Add typedefs for pointers */\ntypedef void                  * png_voidp;\ntypedef const void            * png_const_voidp;\ntypedef png_byte              * png_bytep;\ntypedef const png_byte        * png_const_bytep;\ntypedef png_uint_32           * png_uint_32p;\ntypedef const png_uint_32     * png_const_uint_32p;\ntypedef png_int_32            * png_int_32p;\ntypedef const png_int_32      * png_const_int_32p;\ntypedef png_uint_16           * png_uint_16p;\ntypedef const png_uint_16     * png_const_uint_16p;\ntypedef png_int_16            * png_int_16p;\ntypedef const png_int_16      * png_const_int_16p;\ntypedef char                  * png_charp;\ntypedef const char            * png_const_charp;\ntypedef png_fixed_point       * png_fixed_point_p;\ntypedef const png_fixed_point * png_const_fixed_point_p;\ntypedef png_size_t            * png_size_tp;\ntypedef const png_size_t      * png_const_size_tp;\n\n#ifdef PNG_STDIO_SUPPORTED\ntypedef FILE            * png_FILE_p;\n#endif\n\n#ifdef PNG_FLOATING_POINT_SUPPORTED\ntypedef double       * png_doublep;\ntypedef const double * png_const_doublep;\n#endif\n\n/* Pointers to pointers; i.e. arrays */\ntypedef png_byte        * * png_bytepp;\ntypedef png_uint_32     * * png_uint_32pp;\ntypedef png_int_32      * * png_int_32pp;\ntypedef png_uint_16     * * png_uint_16pp;\ntypedef png_int_16      * * png_int_16pp;\ntypedef const char      * * png_const_charpp;\ntypedef char            * * png_charpp;\ntypedef png_fixed_point * * png_fixed_point_pp;\n#ifdef PNG_FLOATING_POINT_SUPPORTED\ntypedef double          * * png_doublepp;\n#endif\n\n/* Pointers to pointers to pointers; i.e., pointer to array */\ntypedef char            * * * png_charppp;\n\n#endif /* PNG_BUILDING_SYMBOL_TABLE */\n\n#endif /* PNGCONF_H */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngdebug.h",
    "content": "\n/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c\n *\n * Last changed in libpng 1.6.8 [December 19, 2013]\n * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n/* Define PNG_DEBUG at compile time for debugging information.  Higher\n * numbers for PNG_DEBUG mean more debugging information.  This has\n * only been added since version 0.95 so it is not implemented throughout\n * libpng yet, but more support will be added as needed.\n *\n * png_debug[1-2]?(level, message ,arg{0-2})\n *   Expands to a statement (either a simple expression or a compound\n *   do..while(0) statement) that outputs a message with parameter\n *   substitution if PNG_DEBUG is defined to 2 or more.  If PNG_DEBUG\n *   is undefined, 0 or 1 every png_debug expands to a simple expression\n *   (actually ((void)0)).\n *\n *   level: level of detail of message, starting at 0.  A level 'n'\n *          message is preceded by 'n' 3-space indentations (not implemented\n *          on Microsoft compilers unless PNG_DEBUG_FILE is also\n *          defined, to allow debug DLL compilation with no standard IO).\n *   message: a printf(3) style text string.  A trailing '\\n' is added\n *            to the message.\n *   arg: 0 to 2 arguments for printf(3) style substitution in message.\n */\n#ifndef PNGDEBUG_H\n#define PNGDEBUG_H\n/* These settings control the formatting of messages in png.c and pngerror.c */\n/* Moved to pngdebug.h at 1.5.0 */\n#  ifndef PNG_LITERAL_SHARP\n#    define PNG_LITERAL_SHARP 0x23\n#  endif\n#  ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET\n#    define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b\n#  endif\n#  ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET\n#    define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d\n#  endif\n#  ifndef PNG_STRING_NEWLINE\n#    define PNG_STRING_NEWLINE \"\\n\"\n#  endif\n\n#ifdef PNG_DEBUG\n#  if (PNG_DEBUG > 0)\n#    if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)\n#      include <crtdbg.h>\n#      if (PNG_DEBUG > 1)\n#        ifndef _DEBUG\n#          define _DEBUG\n#        endif\n#        ifndef png_debug\n#          define png_debug(l,m)  _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE)\n#        endif\n#        ifndef png_debug1\n#          define png_debug1(l,m,p1)  _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1)\n#        endif\n#        ifndef png_debug2\n#          define png_debug2(l,m,p1,p2) \\\n             _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2)\n#        endif\n#      endif\n#    else /* PNG_DEBUG_FILE || !_MSC_VER */\n#      ifndef PNG_STDIO_SUPPORTED\n#        include <stdio.h> /* not included yet */\n#      endif\n#      ifndef PNG_DEBUG_FILE\n#        define PNG_DEBUG_FILE stderr\n#      endif /* PNG_DEBUG_FILE */\n\n#      if (PNG_DEBUG > 1)\n#        ifdef __STDC__\n#          ifndef png_debug\n#            define png_debug(l,m) \\\n       do { \\\n       int num_tabs=l; \\\n       fprintf(PNG_DEBUG_FILE,\"%s\" m PNG_STRING_NEWLINE,(num_tabs==1 ? \"   \" : \\\n         (num_tabs==2 ? \"      \" : (num_tabs>2 ? \"         \" : \"\")))); \\\n       } while (0)\n#          endif\n#          ifndef png_debug1\n#            define png_debug1(l,m,p1) \\\n       do { \\\n       int num_tabs=l; \\\n       fprintf(PNG_DEBUG_FILE,\"%s\" m PNG_STRING_NEWLINE,(num_tabs==1 ? \"   \" : \\\n         (num_tabs==2 ? \"      \" : (num_tabs>2 ? \"         \" : \"\"))),p1); \\\n       } while (0)\n#          endif\n#          ifndef png_debug2\n#            define png_debug2(l,m,p1,p2) \\\n       do { \\\n       int num_tabs=l; \\\n       fprintf(PNG_DEBUG_FILE,\"%s\" m PNG_STRING_NEWLINE,(num_tabs==1 ? \"   \" : \\\n         (num_tabs==2 ? \"      \" : (num_tabs>2 ? \"         \" : \"\"))),p1,p2);\\\n       } while (0)\n#          endif\n#        else /* __STDC __ */\n#          ifndef png_debug\n#            define png_debug(l,m) \\\n       do { \\\n       int num_tabs=l; \\\n       char format[256]; \\\n       snprintf(format,256,\"%s%s%s\",(num_tabs==1 ? \"\\t\" : \\\n         (num_tabs==2 ? \"\\t\\t\":(num_tabs>2 ? \"\\t\\t\\t\":\"\"))), \\\n         m,PNG_STRING_NEWLINE); \\\n       fprintf(PNG_DEBUG_FILE,format); \\\n       } while (0)\n#          endif\n#          ifndef png_debug1\n#            define png_debug1(l,m,p1) \\\n       do { \\\n       int num_tabs=l; \\\n       char format[256]; \\\n       snprintf(format,256,\"%s%s%s\",(num_tabs==1 ? \"\\t\" : \\\n         (num_tabs==2 ? \"\\t\\t\":(num_tabs>2 ? \"\\t\\t\\t\":\"\"))), \\\n         m,PNG_STRING_NEWLINE); \\\n       fprintf(PNG_DEBUG_FILE,format,p1); \\\n       } while (0)\n#          endif\n#          ifndef png_debug2\n#            define png_debug2(l,m,p1,p2) \\\n       do { \\\n       int num_tabs=l; \\\n       char format[256]; \\\n       snprintf(format,256,\"%s%s%s\",(num_tabs==1 ? \"\\t\" : \\\n         (num_tabs==2 ? \"\\t\\t\":(num_tabs>2 ? \"\\t\\t\\t\":\"\"))), \\\n         m,PNG_STRING_NEWLINE); \\\n       fprintf(PNG_DEBUG_FILE,format,p1,p2); \\\n       } while (0)\n#          endif\n#        endif /* __STDC __ */\n#      endif /* (PNG_DEBUG > 1) */\n\n#    endif /* _MSC_VER */\n#  endif /* (PNG_DEBUG > 0) */\n#endif /* PNG_DEBUG */\n#ifndef png_debug\n#  define png_debug(l, m) ((void)0)\n#endif\n#ifndef png_debug1\n#  define png_debug1(l, m, p1) ((void)0)\n#endif\n#ifndef png_debug2\n#  define png_debug2(l, m, p1, p2) ((void)0)\n#endif\n#endif /* PNGDEBUG_H */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngerror.c",
    "content": "\n/* pngerror.c - stub functions for i/o and memory allocation\n *\n * Last changed in libpng 1.6.15 [November 20, 2014]\n * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * This file provides a location for all error handling.  Users who\n * need special error handling are expected to write replacement functions\n * and use png_set_error_fn() to use those functions.  See the instructions\n * at each function.\n */\n\n#include \"pngpriv.h\"\n\n#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)\n\nstatic PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,\n    png_const_charp error_message)),PNG_NORETURN);\n\n#ifdef PNG_WARNINGS_SUPPORTED\nstatic void /* PRIVATE */\npng_default_warning PNGARG((png_const_structrp png_ptr,\n   png_const_charp warning_message));\n#endif /* WARNINGS */\n\n/* This function is called whenever there is a fatal error.  This function\n * should not be changed.  If there is a need to handle errors differently,\n * you should supply a replacement error function and use png_set_error_fn()\n * to replace the error function at run-time.\n */\n#ifdef PNG_ERROR_TEXT_SUPPORTED\nPNG_FUNCTION(void,PNGAPI\npng_error,(png_const_structrp png_ptr, png_const_charp error_message),\n   PNG_NORETURN)\n{\n#ifdef PNG_ERROR_NUMBERS_SUPPORTED\n   char msg[16];\n   if (png_ptr != NULL)\n   {\n      if ((png_ptr->flags &\n         (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0\n      {\n         if (*error_message == PNG_LITERAL_SHARP)\n         {\n            /* Strip \"#nnnn \" from beginning of error message. */\n            int offset;\n            for (offset = 1; offset<15; offset++)\n               if (error_message[offset] == ' ')\n                  break;\n\n            if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)\n            {\n               int i;\n               for (i = 0; i < offset - 1; i++)\n                  msg[i] = error_message[i + 1];\n               msg[i - 1] = '\\0';\n               error_message = msg;\n            }\n\n            else\n               error_message += offset;\n      }\n\n      else\n      {\n         if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)\n         {\n            msg[0] = '0';\n            msg[1] = '\\0';\n            error_message = msg;\n         }\n       }\n     }\n   }\n#endif\n   if (png_ptr != NULL && png_ptr->error_fn != NULL)\n      (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr),\n          error_message);\n\n   /* If the custom handler doesn't exist, or if it returns,\n      use the default handler, which will not return. */\n   png_default_error(png_ptr, error_message);\n}\n#else\nPNG_FUNCTION(void,PNGAPI\npng_err,(png_const_structrp png_ptr),PNG_NORETURN)\n{\n   /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed\n    * erroneously as '\\0', instead of the empty string \"\".  This was\n    * apparently an error, introduced in libpng-1.2.20, and png_default_error\n    * will crash in this case.\n    */\n   if (png_ptr != NULL && png_ptr->error_fn != NULL)\n      (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), \"\");\n\n   /* If the custom handler doesn't exist, or if it returns,\n      use the default handler, which will not return. */\n   png_default_error(png_ptr, \"\");\n}\n#endif /* ERROR_TEXT */\n\n/* Utility to safely appends strings to a buffer.  This never errors out so\n * error checking is not required in the caller.\n */\nsize_t\npng_safecat(png_charp buffer, size_t bufsize, size_t pos,\n   png_const_charp string)\n{\n   if (buffer != NULL && pos < bufsize)\n   {\n      if (string != NULL)\n         while (*string != '\\0' && pos < bufsize-1)\n           buffer[pos++] = *string++;\n\n      buffer[pos] = '\\0';\n   }\n\n   return pos;\n}\n\n#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)\n/* Utility to dump an unsigned value into a buffer, given a start pointer and\n * and end pointer (which should point just *beyond* the end of the buffer!)\n * Returns the pointer to the start of the formatted string.\n */\npng_charp\npng_format_number(png_const_charp start, png_charp end, int format,\n   png_alloc_size_t number)\n{\n   int count = 0;    /* number of digits output */\n   int mincount = 1; /* minimum number required */\n   int output = 0;   /* digit output (for the fixed point format) */\n\n   *--end = '\\0';\n\n   /* This is written so that the loop always runs at least once, even with\n    * number zero.\n    */\n   while (end > start && (number != 0 || count < mincount))\n   {\n\n      static const char digits[] = \"0123456789ABCDEF\";\n\n      switch (format)\n      {\n         case PNG_NUMBER_FORMAT_fixed:\n            /* Needs five digits (the fraction) */\n            mincount = 5;\n            if (output != 0 || number % 10 != 0)\n            {\n               *--end = digits[number % 10];\n               output = 1;\n            }\n            number /= 10;\n            break;\n\n         case PNG_NUMBER_FORMAT_02u:\n            /* Expects at least 2 digits. */\n            mincount = 2;\n            /* FALL THROUGH */\n\n         case PNG_NUMBER_FORMAT_u:\n            *--end = digits[number % 10];\n            number /= 10;\n            break;\n\n         case PNG_NUMBER_FORMAT_02x:\n            /* This format expects at least two digits */\n            mincount = 2;\n            /* FALL THROUGH */\n\n         case PNG_NUMBER_FORMAT_x:\n            *--end = digits[number & 0xf];\n            number >>= 4;\n            break;\n\n         default: /* an error */\n            number = 0;\n            break;\n      }\n\n      /* Keep track of the number of digits added */\n      ++count;\n\n      /* Float a fixed number here: */\n      if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start))\n      {\n         /* End of the fraction, but maybe nothing was output?  In that case\n          * drop the decimal point.  If the number is a true zero handle that\n          * here.\n          */\n         if (output != 0)\n            *--end = '.';\n         else if (number == 0) /* and !output */\n            *--end = '0';\n      }\n   }\n\n   return end;\n}\n#endif\n\n#ifdef PNG_WARNINGS_SUPPORTED\n/* This function is called whenever there is a non-fatal error.  This function\n * should not be changed.  If there is a need to handle warnings differently,\n * you should supply a replacement warning function and use\n * png_set_error_fn() to replace the warning function at run-time.\n */\nvoid PNGAPI\npng_warning(png_const_structrp png_ptr, png_const_charp warning_message)\n{\n   int offset = 0;\n   if (png_ptr != NULL)\n   {\n#ifdef PNG_ERROR_NUMBERS_SUPPORTED\n   if ((png_ptr->flags &\n       (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)\n#endif\n      {\n         if (*warning_message == PNG_LITERAL_SHARP)\n         {\n            for (offset = 1; offset < 15; offset++)\n               if (warning_message[offset] == ' ')\n                  break;\n         }\n      }\n   }\n   if (png_ptr != NULL && png_ptr->warning_fn != NULL)\n      (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),\n         warning_message + offset);\n   else\n      png_default_warning(png_ptr, warning_message + offset);\n}\n\n/* These functions support 'formatted' warning messages with up to\n * PNG_WARNING_PARAMETER_COUNT parameters.  In the format string the parameter\n * is introduced by @<number>, where 'number' starts at 1.  This follows the\n * standard established by X/Open for internationalizable error messages.\n */\nvoid\npng_warning_parameter(png_warning_parameters p, int number,\n   png_const_charp string)\n{\n   if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)\n      (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);\n}\n\nvoid\npng_warning_parameter_unsigned(png_warning_parameters p, int number, int format,\n   png_alloc_size_t value)\n{\n   char buffer[PNG_NUMBER_BUFFER_SIZE];\n   png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));\n}\n\nvoid\npng_warning_parameter_signed(png_warning_parameters p, int number, int format,\n   png_int_32 value)\n{\n   png_alloc_size_t u;\n   png_charp str;\n   char buffer[PNG_NUMBER_BUFFER_SIZE];\n\n   /* Avoid overflow by doing the negate in a png_alloc_size_t: */\n   u = (png_alloc_size_t)value;\n   if (value < 0)\n      u = ~u + 1;\n\n   str = PNG_FORMAT_NUMBER(buffer, format, u);\n\n   if (value < 0 && str > buffer)\n      *--str = '-';\n\n   png_warning_parameter(p, number, str);\n}\n\nvoid\npng_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,\n   png_const_charp message)\n{\n   /* The internal buffer is just 192 bytes - enough for all our messages,\n    * overflow doesn't happen because this code checks!  If someone figures\n    * out how to send us a message longer than 192 bytes, all that will\n    * happen is that the message will be truncated appropriately.\n    */\n   size_t i = 0; /* Index in the msg[] buffer: */\n   char msg[192];\n\n   /* Each iteration through the following loop writes at most one character\n    * to msg[i++] then returns here to validate that there is still space for\n    * the trailing '\\0'.  It may (in the case of a parameter) read more than\n    * one character from message[]; it must check for '\\0' and continue to the\n    * test if it finds the end of string.\n    */\n   while (i<(sizeof msg)-1 && *message != '\\0')\n   {\n      /* '@' at end of string is now just printed (previously it was skipped);\n       * it is an error in the calling code to terminate the string with @.\n       */\n      if (p != NULL && *message == '@' && message[1] != '\\0')\n      {\n         int parameter_char = *++message; /* Consume the '@' */\n         static const char valid_parameters[] = \"123456789\";\n         int parameter = 0;\n\n         /* Search for the parameter digit, the index in the string is the\n          * parameter to use.\n          */\n         while (valid_parameters[parameter] != parameter_char &&\n            valid_parameters[parameter] != '\\0')\n            ++parameter;\n\n         /* If the parameter digit is out of range it will just get printed. */\n         if (parameter < PNG_WARNING_PARAMETER_COUNT)\n         {\n            /* Append this parameter */\n            png_const_charp parm = p[parameter];\n            png_const_charp pend = p[parameter] + (sizeof p[parameter]);\n\n            /* No need to copy the trailing '\\0' here, but there is no guarantee\n             * that parm[] has been initialized, so there is no guarantee of a\n             * trailing '\\0':\n             */\n            while (i<(sizeof msg)-1 && *parm != '\\0' && parm < pend)\n               msg[i++] = *parm++;\n\n            /* Consume the parameter digit too: */\n            ++message;\n            continue;\n         }\n\n         /* else not a parameter and there is a character after the @ sign; just\n          * copy that.  This is known not to be '\\0' because of the test above.\n          */\n      }\n\n      /* At this point *message can't be '\\0', even in the bad parameter case\n       * above where there is a lone '@' at the end of the message string.\n       */\n      msg[i++] = *message++;\n   }\n\n   /* i is always less than (sizeof msg), so: */\n   msg[i] = '\\0';\n\n   /* And this is the formatted message. It may be larger than\n    * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these\n    * are not (currently) formatted.\n    */\n   png_warning(png_ptr, msg);\n}\n#endif /* WARNINGS */\n\n#ifdef PNG_BENIGN_ERRORS_SUPPORTED\nvoid PNGAPI\npng_benign_error(png_const_structrp png_ptr, png_const_charp error_message)\n{\n   if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)\n   {\n#     ifdef PNG_READ_SUPPORTED\n         if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&\n            png_ptr->chunk_name != 0)\n            png_chunk_warning(png_ptr, error_message);\n         else\n#     endif\n      png_warning(png_ptr, error_message);\n   }\n\n   else\n   {\n#     ifdef PNG_READ_SUPPORTED\n         if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&\n            png_ptr->chunk_name != 0)\n            png_chunk_error(png_ptr, error_message);\n         else\n#     endif\n      png_error(png_ptr, error_message);\n   }\n\n#  ifndef PNG_ERROR_TEXT_SUPPORTED\n      PNG_UNUSED(error_message)\n#  endif\n}\n\nvoid /* PRIVATE */\npng_app_warning(png_const_structrp png_ptr, png_const_charp error_message)\n{\n  if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)\n     png_warning(png_ptr, error_message);\n  else\n     png_error(png_ptr, error_message);\n\n#  ifndef PNG_ERROR_TEXT_SUPPORTED\n      PNG_UNUSED(error_message)\n#  endif\n}\n\nvoid /* PRIVATE */\npng_app_error(png_const_structrp png_ptr, png_const_charp error_message)\n{\n  if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)\n     png_warning(png_ptr, error_message);\n  else\n     png_error(png_ptr, error_message);\n\n#  ifndef PNG_ERROR_TEXT_SUPPORTED\n      PNG_UNUSED(error_message)\n#  endif\n}\n#endif /* BENIGN_ERRORS */\n\n#define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */\n#if defined(PNG_WARNINGS_SUPPORTED) || \\\n   (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED))\n/* These utilities are used internally to build an error message that relates\n * to the current chunk.  The chunk name comes from png_ptr->chunk_name,\n * which is used to prefix the message.  The message is limited in length\n * to 63 bytes. The name characters are output as hex digits wrapped in []\n * if the character is invalid.\n */\n#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))\nstatic PNG_CONST char png_digit[16] = {\n   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n   'A', 'B', 'C', 'D', 'E', 'F'\n};\n\nstatic void /* PRIVATE */\npng_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp\n    error_message)\n{\n   png_uint_32 chunk_name = png_ptr->chunk_name;\n   int iout = 0, ishift = 24;\n\n   while (ishift >= 0)\n   {\n      int c = (int)(chunk_name >> ishift) & 0xff;\n\n      ishift -= 8;\n      if (isnonalpha(c) != 0)\n      {\n         buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;\n         buffer[iout++] = png_digit[(c & 0xf0) >> 4];\n         buffer[iout++] = png_digit[c & 0x0f];\n         buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;\n      }\n\n      else\n      {\n         buffer[iout++] = (char)c;\n      }\n   }\n\n   if (error_message == NULL)\n      buffer[iout] = '\\0';\n\n   else\n   {\n      int iin = 0;\n\n      buffer[iout++] = ':';\n      buffer[iout++] = ' ';\n\n      while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\\0')\n         buffer[iout++] = error_message[iin++];\n\n      /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */\n      buffer[iout] = '\\0';\n   }\n}\n#endif /* WARNINGS || ERROR_TEXT */\n\n#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)\nPNG_FUNCTION(void,PNGAPI\npng_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),\n   PNG_NORETURN)\n{\n   char msg[18+PNG_MAX_ERROR_TEXT];\n   if (png_ptr == NULL)\n      png_error(png_ptr, error_message);\n\n   else\n   {\n      png_format_buffer(png_ptr, msg, error_message);\n      png_error(png_ptr, msg);\n   }\n}\n#endif /* READ && ERROR_TEXT */\n\n#ifdef PNG_WARNINGS_SUPPORTED\nvoid PNGAPI\npng_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message)\n{\n   char msg[18+PNG_MAX_ERROR_TEXT];\n   if (png_ptr == NULL)\n      png_warning(png_ptr, warning_message);\n\n   else\n   {\n      png_format_buffer(png_ptr, msg, warning_message);\n      png_warning(png_ptr, msg);\n   }\n}\n#endif /* WARNINGS */\n\n#ifdef PNG_READ_SUPPORTED\n#ifdef PNG_BENIGN_ERRORS_SUPPORTED\nvoid PNGAPI\npng_chunk_benign_error(png_const_structrp png_ptr, png_const_charp\n    error_message)\n{\n   if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)\n      png_chunk_warning(png_ptr, error_message);\n\n   else\n      png_chunk_error(png_ptr, error_message);\n\n#  ifndef PNG_ERROR_TEXT_SUPPORTED\n      PNG_UNUSED(error_message)\n#  endif\n}\n#endif\n#endif /* READ */\n\nvoid /* PRIVATE */\npng_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)\n{\n#  ifndef PNG_WARNINGS_SUPPORTED\n      PNG_UNUSED(message)\n#  endif\n\n   /* This is always supported, but for just read or just write it\n    * unconditionally does the right thing.\n    */\n#  if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)\n      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)\n#  endif\n\n#  ifdef PNG_READ_SUPPORTED\n      {\n         if (error < PNG_CHUNK_ERROR)\n            png_chunk_warning(png_ptr, message);\n\n         else\n            png_chunk_benign_error(png_ptr, message);\n      }\n#  endif\n\n#  if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)\n      else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)\n#  endif\n\n#  ifdef PNG_WRITE_SUPPORTED\n      {\n         if (error < PNG_CHUNK_WRITE_ERROR)\n            png_app_warning(png_ptr, message);\n\n         else\n            png_app_error(png_ptr, message);\n      }\n#  endif\n}\n\n#ifdef PNG_ERROR_TEXT_SUPPORTED\n#ifdef PNG_FLOATING_POINT_SUPPORTED\nPNG_FUNCTION(void,\npng_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)\n{\n#  define fixed_message \"fixed point overflow in \"\n#  define fixed_message_ln ((sizeof fixed_message)-1)\n   int  iin;\n   char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];\n   memcpy(msg, fixed_message, fixed_message_ln);\n   iin = 0;\n   if (name != NULL)\n      while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)\n      {\n         msg[fixed_message_ln + iin] = name[iin];\n         ++iin;\n      }\n   msg[fixed_message_ln + iin] = 0;\n   png_error(png_ptr, msg);\n}\n#endif\n#endif\n\n#ifdef PNG_SETJMP_SUPPORTED\n/* This API only exists if ANSI-C style error handling is used,\n * otherwise it is necessary for png_default_error to be overridden.\n */\njmp_buf* PNGAPI\npng_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,\n    size_t jmp_buf_size)\n{\n   /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value\n    * and it must not change after that.  Libpng doesn't care how big the\n    * buffer is, just that it doesn't change.\n    *\n    * If the buffer size is no *larger* than the size of jmp_buf when libpng is\n    * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0\n    * semantics that this call will not fail.  If the size is larger, however,\n    * the buffer is allocated and this may fail, causing the function to return\n    * NULL.\n    */\n   if (png_ptr == NULL)\n      return NULL;\n\n   if (png_ptr->jmp_buf_ptr == NULL)\n   {\n      png_ptr->jmp_buf_size = 0; /* not allocated */\n\n      if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local))\n         png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local;\n\n      else\n      {\n         png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,\n            png_malloc_warn(png_ptr, jmp_buf_size));\n\n         if (png_ptr->jmp_buf_ptr == NULL)\n            return NULL; /* new NULL return on OOM */\n\n         png_ptr->jmp_buf_size = jmp_buf_size;\n      }\n   }\n\n   else /* Already allocated: check the size */\n   {\n      size_t size = png_ptr->jmp_buf_size;\n\n      if (size == 0)\n      {\n         size = (sizeof png_ptr->jmp_buf_local);\n         if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local)\n         {\n            /* This is an internal error in libpng: somehow we have been left\n             * with a stack allocated jmp_buf when the application regained\n             * control.  It's always possible to fix this up, but for the moment\n             * this is a png_error because that makes it easy to detect.\n             */\n            png_error(png_ptr, \"Libpng jmp_buf still allocated\");\n            /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */\n         }\n      }\n\n      if (size != jmp_buf_size)\n      {\n         png_warning(png_ptr, \"Application jmp_buf size changed\");\n         return NULL; /* caller will probably crash: no choice here */\n      }\n   }\n\n   /* Finally fill in the function, now we have a satisfactory buffer. It is\n    * valid to change the function on every call.\n    */\n   png_ptr->longjmp_fn = longjmp_fn;\n   return png_ptr->jmp_buf_ptr;\n}\n\nvoid /* PRIVATE */\npng_free_jmpbuf(png_structrp png_ptr)\n{\n   if (png_ptr != NULL)\n   {\n      jmp_buf *jb = png_ptr->jmp_buf_ptr;\n\n      /* A size of 0 is used to indicate a local, stack, allocation of the\n       * pointer; used here and in png.c\n       */\n      if (jb != NULL && png_ptr->jmp_buf_size > 0)\n      {\n\n         /* This stuff is so that a failure to free the error control structure\n          * does not leave libpng in a state with no valid error handling: the\n          * free always succeeds, if there is an error it gets ignored.\n          */\n         if (jb != &png_ptr->jmp_buf_local)\n         {\n            /* Make an internal, libpng, jmp_buf to return here */\n            jmp_buf free_jmp_buf;\n\n            if (!setjmp(free_jmp_buf))\n            {\n               png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */\n               png_ptr->jmp_buf_size = 0; /* stack allocation */\n               png_ptr->longjmp_fn = longjmp;\n               png_free(png_ptr, jb); /* Return to setjmp on error */\n            }\n         }\n      }\n\n      /* *Always* cancel everything out: */\n      png_ptr->jmp_buf_size = 0;\n      png_ptr->jmp_buf_ptr = NULL;\n      png_ptr->longjmp_fn = 0;\n   }\n}\n#endif\n\n/* This is the default error handling function.  Note that replacements for\n * this function MUST NOT RETURN, or the program will likely crash.  This\n * function is used by default, or if the program supplies NULL for the\n * error function pointer in png_set_error_fn().\n */\nstatic PNG_FUNCTION(void /* PRIVATE */,\npng_default_error,(png_const_structrp png_ptr, png_const_charp error_message),\n   PNG_NORETURN)\n{\n#ifdef PNG_CONSOLE_IO_SUPPORTED\n#ifdef PNG_ERROR_NUMBERS_SUPPORTED\n   /* Check on NULL only added in 1.5.4 */\n   if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)\n   {\n      /* Strip \"#nnnn \" from beginning of error message. */\n      int offset;\n      char error_number[16];\n      for (offset = 0; offset<15; offset++)\n      {\n         error_number[offset] = error_message[offset + 1];\n         if (error_message[offset] == ' ')\n            break;\n      }\n\n      if ((offset > 1) && (offset < 15))\n      {\n         error_number[offset - 1] = '\\0';\n         fprintf(stderr, \"libpng error no. %s: %s\",\n             error_number, error_message + offset + 1);\n         fprintf(stderr, PNG_STRING_NEWLINE);\n      }\n\n      else\n      {\n         fprintf(stderr, \"libpng error: %s, offset=%d\",\n             error_message, offset);\n         fprintf(stderr, PNG_STRING_NEWLINE);\n      }\n   }\n   else\n#endif\n   {\n      fprintf(stderr, \"libpng error: %s\", error_message ? error_message :\n         \"undefined\");\n      fprintf(stderr, PNG_STRING_NEWLINE);\n   }\n#else\n   PNG_UNUSED(error_message) /* Make compiler happy */\n#endif\n   png_longjmp(png_ptr, 1);\n}\n\nPNG_FUNCTION(void,PNGAPI\npng_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)\n{\n#ifdef PNG_SETJMP_SUPPORTED\n   if (png_ptr != NULL && png_ptr->longjmp_fn != NULL &&\n       png_ptr->jmp_buf_ptr != NULL)\n      png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);\n#else\n   PNG_UNUSED(png_ptr)\n   PNG_UNUSED(val)\n#endif\n\n   /* If control reaches this point, png_longjmp() must not return. The only\n    * choice is to terminate the whole process (or maybe the thread); to do\n    * this the ANSI-C abort() function is used unless a different method is\n    * implemented by overriding the default configuration setting for\n    * PNG_ABORT().\n    */\n   PNG_ABORT();\n}\n\n#ifdef PNG_WARNINGS_SUPPORTED\n/* This function is called when there is a warning, but the library thinks\n * it can continue anyway.  Replacement functions don't have to do anything\n * here if you don't want them to.  In the default configuration, png_ptr is\n * not used, but it is passed in case it may be useful.\n */\nstatic void /* PRIVATE */\npng_default_warning(png_const_structrp png_ptr, png_const_charp warning_message)\n{\n#ifdef PNG_CONSOLE_IO_SUPPORTED\n#  ifdef PNG_ERROR_NUMBERS_SUPPORTED\n   if (*warning_message == PNG_LITERAL_SHARP)\n   {\n      int offset;\n      char warning_number[16];\n      for (offset = 0; offset < 15; offset++)\n      {\n         warning_number[offset] = warning_message[offset + 1];\n         if (warning_message[offset] == ' ')\n            break;\n      }\n\n      if ((offset > 1) && (offset < 15))\n      {\n         warning_number[offset + 1] = '\\0';\n         fprintf(stderr, \"libpng warning no. %s: %s\",\n             warning_number, warning_message + offset);\n         fprintf(stderr, PNG_STRING_NEWLINE);\n      }\n\n      else\n      {\n         fprintf(stderr, \"libpng warning: %s\",\n             warning_message);\n         fprintf(stderr, PNG_STRING_NEWLINE);\n      }\n   }\n   else\n#  endif\n\n   {\n      fprintf(stderr, \"libpng warning: %s\", warning_message);\n      fprintf(stderr, PNG_STRING_NEWLINE);\n   }\n#else\n   PNG_UNUSED(warning_message) /* Make compiler happy */\n#endif\n   PNG_UNUSED(png_ptr) /* Make compiler happy */\n}\n#endif /* WARNINGS */\n\n/* This function is called when the application wants to use another method\n * of handling errors and warnings.  Note that the error function MUST NOT\n * return to the calling routine or serious problems will occur.  The return\n * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1)\n */\nvoid PNGAPI\npng_set_error_fn(png_structrp png_ptr, png_voidp error_ptr,\n    png_error_ptr error_fn, png_error_ptr warning_fn)\n{\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->error_ptr = error_ptr;\n   png_ptr->error_fn = error_fn;\n#ifdef PNG_WARNINGS_SUPPORTED\n   png_ptr->warning_fn = warning_fn;\n#else\n   PNG_UNUSED(warning_fn)\n#endif\n}\n\n\n/* This function returns a pointer to the error_ptr associated with the user\n * functions.  The application should free any memory associated with this\n * pointer before png_write_destroy and png_read_destroy are called.\n */\npng_voidp PNGAPI\npng_get_error_ptr(png_const_structrp png_ptr)\n{\n   if (png_ptr == NULL)\n      return NULL;\n\n   return ((png_voidp)png_ptr->error_ptr);\n}\n\n\n#ifdef PNG_ERROR_NUMBERS_SUPPORTED\nvoid PNGAPI\npng_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)\n{\n   if (png_ptr != NULL)\n   {\n      png_ptr->flags &=\n         ((~(PNG_FLAG_STRIP_ERROR_NUMBERS |\n         PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);\n   }\n}\n#endif\n\n#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\\\n   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)\n   /* Currently the above both depend on SETJMP_SUPPORTED, however it would be\n    * possible to implement without setjmp support just so long as there is some\n    * way to handle the error return here:\n    */\nPNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI\npng_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),\n   PNG_NORETURN)\n{\n   const png_const_structrp png_ptr = png_nonconst_ptr;\n   png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);\n\n   /* An error is always logged here, overwriting anything (typically a warning)\n    * that is already there:\n    */\n   if (image != NULL)\n   {\n      png_safecat(image->message, (sizeof image->message), 0, error_message);\n      image->warning_or_error |= PNG_IMAGE_ERROR;\n\n      /* Retrieve the jmp_buf from within the png_control, making this work for\n       * C++ compilation too is pretty tricky: C++ wants a pointer to the first\n       * element of a jmp_buf, but C doesn't tell us the type of that.\n       */\n      if (image->opaque != NULL && image->opaque->error_buf != NULL)\n         longjmp(png_control_jmp_buf(image->opaque), 1);\n\n      /* Missing longjmp buffer, the following is to help debugging: */\n      {\n         size_t pos = png_safecat(image->message, (sizeof image->message), 0,\n            \"bad longjmp: \");\n         png_safecat(image->message, (sizeof image->message), pos,\n             error_message);\n      }\n   }\n\n   /* Here on an internal programming error. */\n   abort();\n}\n\n#ifdef PNG_WARNINGS_SUPPORTED\nvoid /* PRIVATE */ PNGCBAPI\npng_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)\n{\n   const png_const_structrp png_ptr = png_nonconst_ptr;\n   png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);\n\n   /* A warning is only logged if there is no prior warning or error. */\n   if (image->warning_or_error == 0)\n   {\n      png_safecat(image->message, (sizeof image->message), 0, warning_message);\n      image->warning_or_error |= PNG_IMAGE_WARNING;\n   }\n}\n#endif\n\nint /* PRIVATE */\npng_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg)\n{\n   volatile png_imagep image = image_in;\n   volatile int result;\n   volatile png_voidp saved_error_buf;\n   jmp_buf safe_jmpbuf;\n\n   /* Safely execute function(arg) with png_error returning to this function. */\n   saved_error_buf = image->opaque->error_buf;\n   result = setjmp(safe_jmpbuf) == 0;\n\n   if (result != 0)\n   {\n\n      image->opaque->error_buf = safe_jmpbuf;\n      result = function(arg);\n   }\n\n   image->opaque->error_buf = saved_error_buf;\n\n   /* And do the cleanup prior to any failure return. */\n   if (result == 0)\n      png_image_free(image);\n\n   return result;\n}\n#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */\n#endif /* READ || WRITE */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngget.c",
    "content": "\n/* pngget.c - retrieval of values from info struct\n *\n * Last changed in libpng 1.6.17 [March 26, 2015]\n * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n */\n\n#include \"pngpriv.h\"\n\n#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)\n\npng_uint_32 PNGAPI\npng_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr,\n    png_uint_32 flag)\n{\n   if (png_ptr != NULL && info_ptr != NULL)\n      return(info_ptr->valid & flag);\n\n   return(0);\n}\n\npng_size_t PNGAPI\npng_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   if (png_ptr != NULL && info_ptr != NULL)\n      return(info_ptr->rowbytes);\n\n   return(0);\n}\n\n#ifdef PNG_INFO_IMAGE_SUPPORTED\npng_bytepp PNGAPI\npng_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   if (png_ptr != NULL && info_ptr != NULL)\n      return(info_ptr->row_pointers);\n\n   return(0);\n}\n#endif\n\n#ifdef PNG_EASY_ACCESS_SUPPORTED\n/* Easy access to info, added in libpng-0.99 */\npng_uint_32 PNGAPI\npng_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   if (png_ptr != NULL && info_ptr != NULL)\n      return info_ptr->width;\n\n   return (0);\n}\n\npng_uint_32 PNGAPI\npng_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   if (png_ptr != NULL && info_ptr != NULL)\n      return info_ptr->height;\n\n   return (0);\n}\n\npng_byte PNGAPI\npng_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   if (png_ptr != NULL && info_ptr != NULL)\n      return info_ptr->bit_depth;\n\n   return (0);\n}\n\npng_byte PNGAPI\npng_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   if (png_ptr != NULL && info_ptr != NULL)\n      return info_ptr->color_type;\n\n   return (0);\n}\n\npng_byte PNGAPI\npng_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   if (png_ptr != NULL && info_ptr != NULL)\n      return info_ptr->filter_type;\n\n   return (0);\n}\n\npng_byte PNGAPI\npng_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   if (png_ptr != NULL && info_ptr != NULL)\n      return info_ptr->interlace_type;\n\n   return (0);\n}\n\npng_byte PNGAPI\npng_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   if (png_ptr != NULL && info_ptr != NULL)\n      return info_ptr->compression_type;\n\n   return (0);\n}\n\npng_uint_32 PNGAPI\npng_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp\n   info_ptr)\n{\n#ifdef PNG_pHYs_SUPPORTED\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_pHYs) != 0)\n      {\n         png_debug1(1, \"in %s retrieval function\",\n             \"png_get_x_pixels_per_meter\");\n\n         if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)\n            return (info_ptr->x_pixels_per_unit);\n      }\n#else\n   PNG_UNUSED(png_ptr)\n   PNG_UNUSED(info_ptr)\n#endif\n\n   return (0);\n}\n\npng_uint_32 PNGAPI\npng_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp\n    info_ptr)\n{\n#ifdef PNG_pHYs_SUPPORTED\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_pHYs) != 0)\n   {\n      png_debug1(1, \"in %s retrieval function\",\n          \"png_get_y_pixels_per_meter\");\n\n      if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)\n         return (info_ptr->y_pixels_per_unit);\n   }\n#else\n   PNG_UNUSED(png_ptr)\n   PNG_UNUSED(info_ptr)\n#endif\n\n   return (0);\n}\n\npng_uint_32 PNGAPI\npng_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n#ifdef PNG_pHYs_SUPPORTED\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_pHYs) != 0)\n   {\n      png_debug1(1, \"in %s retrieval function\", \"png_get_pixels_per_meter\");\n\n      if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER &&\n          info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit)\n         return (info_ptr->x_pixels_per_unit);\n   }\n#else\n   PNG_UNUSED(png_ptr)\n   PNG_UNUSED(info_ptr)\n#endif\n\n   return (0);\n}\n\n#ifdef PNG_FLOATING_POINT_SUPPORTED\nfloat PNGAPI\npng_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp\n   info_ptr)\n{\n#ifdef PNG_READ_pHYs_SUPPORTED\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_pHYs) != 0)\n   {\n      png_debug1(1, \"in %s retrieval function\", \"png_get_aspect_ratio\");\n\n      if (info_ptr->x_pixels_per_unit != 0)\n         return ((float)((float)info_ptr->y_pixels_per_unit\n             /(float)info_ptr->x_pixels_per_unit));\n   }\n#else\n   PNG_UNUSED(png_ptr)\n   PNG_UNUSED(info_ptr)\n#endif\n\n   return ((float)0.0);\n}\n#endif\n\n#ifdef PNG_FIXED_POINT_SUPPORTED\npng_fixed_point PNGAPI\npng_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr,\n    png_const_inforp info_ptr)\n{\n#ifdef PNG_READ_pHYs_SUPPORTED\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_pHYs) != 0 &&\n       info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 &&\n       info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX &&\n       info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX)\n   {\n      png_fixed_point res;\n\n      png_debug1(1, \"in %s retrieval function\", \"png_get_aspect_ratio_fixed\");\n\n      /* The following casts work because a PNG 4 byte integer only has a valid\n       * range of 0..2^31-1; otherwise the cast might overflow.\n       */\n      if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1,\n          (png_int_32)info_ptr->x_pixels_per_unit) != 0)\n         return res;\n   }\n#else\n   PNG_UNUSED(png_ptr)\n   PNG_UNUSED(info_ptr)\n#endif\n\n   return 0;\n}\n#endif\n\npng_int_32 PNGAPI\npng_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n#ifdef PNG_oFFs_SUPPORTED\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_oFFs) != 0)\n   {\n      png_debug1(1, \"in %s retrieval function\", \"png_get_x_offset_microns\");\n\n      if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)\n         return (info_ptr->x_offset);\n   }\n#else\n   PNG_UNUSED(png_ptr)\n   PNG_UNUSED(info_ptr)\n#endif\n\n   return (0);\n}\n\npng_int_32 PNGAPI\npng_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n#ifdef PNG_oFFs_SUPPORTED\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_oFFs) != 0)\n   {\n      png_debug1(1, \"in %s retrieval function\", \"png_get_y_offset_microns\");\n\n      if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)\n         return (info_ptr->y_offset);\n   }\n#else\n   PNG_UNUSED(png_ptr)\n   PNG_UNUSED(info_ptr)\n#endif\n\n   return (0);\n}\n\npng_int_32 PNGAPI\npng_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n#ifdef PNG_oFFs_SUPPORTED\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_oFFs) != 0)\n   {\n      png_debug1(1, \"in %s retrieval function\", \"png_get_x_offset_pixels\");\n\n      if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)\n         return (info_ptr->x_offset);\n   }\n#else\n   PNG_UNUSED(png_ptr)\n   PNG_UNUSED(info_ptr)\n#endif\n\n   return (0);\n}\n\npng_int_32 PNGAPI\npng_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n#ifdef PNG_oFFs_SUPPORTED\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_oFFs) != 0)\n   {\n      png_debug1(1, \"in %s retrieval function\", \"png_get_y_offset_pixels\");\n\n      if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)\n         return (info_ptr->y_offset);\n   }\n#else\n   PNG_UNUSED(png_ptr)\n   PNG_UNUSED(info_ptr)\n#endif\n\n   return (0);\n}\n\n#ifdef PNG_INCH_CONVERSIONS_SUPPORTED\nstatic png_uint_32\nppi_from_ppm(png_uint_32 ppm)\n{\n#if 0\n   /* The conversion is *(2.54/100), in binary (32 digits):\n    * .00000110100000001001110101001001\n    */\n   png_uint_32 t1001, t1101;\n   ppm >>= 1;                  /* .1 */\n   t1001 = ppm + (ppm >> 3);   /* .1001 */\n   t1101 = t1001 + (ppm >> 1); /* .1101 */\n   ppm >>= 20;                 /* .000000000000000000001 */\n   t1101 += t1101 >> 15;       /* .1101000000000001101 */\n   t1001 >>= 11;               /* .000000000001001 */\n   t1001 += t1001 >> 12;       /* .000000000001001000000001001 */\n   ppm += t1001;               /* .000000000001001000001001001 */\n   ppm += t1101;               /* .110100000001001110101001001 */\n   return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */\n#else\n   /* The argument is a PNG unsigned integer, so it is not permitted\n    * to be bigger than 2^31.\n    */\n   png_fixed_point result;\n   if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,\n       5000) != 0)\n      return result;\n\n   /* Overflow. */\n   return 0;\n#endif\n}\n\npng_uint_32 PNGAPI\npng_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr));\n}\n\npng_uint_32 PNGAPI\npng_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr));\n}\n\npng_uint_32 PNGAPI\npng_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr));\n}\n\n#ifdef PNG_FIXED_POINT_SUPPORTED\nstatic png_fixed_point\npng_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns)\n{\n   /* Convert from metres * 1,000,000 to inches * 100,000, meters to\n    * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127.\n    * Notice that this can overflow - a warning is output and 0 is\n    * returned.\n    */\n   return png_muldiv_warn(png_ptr, microns, 500, 127);\n}\n\npng_fixed_point PNGAPI\npng_get_x_offset_inches_fixed(png_const_structrp png_ptr,\n    png_const_inforp info_ptr)\n{\n   return png_fixed_inches_from_microns(png_ptr,\n       png_get_x_offset_microns(png_ptr, info_ptr));\n}\n#endif\n\n#ifdef PNG_FIXED_POINT_SUPPORTED\npng_fixed_point PNGAPI\npng_get_y_offset_inches_fixed(png_const_structrp png_ptr,\n    png_const_inforp info_ptr)\n{\n   return png_fixed_inches_from_microns(png_ptr,\n       png_get_y_offset_microns(png_ptr, info_ptr));\n}\n#endif\n\n#ifdef PNG_FLOATING_POINT_SUPPORTED\nfloat PNGAPI\npng_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   /* To avoid the overflow do the conversion directly in floating\n    * point.\n    */\n   return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937);\n}\n#endif\n\n#ifdef PNG_FLOATING_POINT_SUPPORTED\nfloat PNGAPI\npng_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   /* To avoid the overflow do the conversion directly in floating\n    * point.\n    */\n   return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937);\n}\n#endif\n\n#ifdef PNG_pHYs_SUPPORTED\npng_uint_32 PNGAPI\npng_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,\n    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)\n{\n   png_uint_32 retval = 0;\n\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_pHYs) != 0)\n   {\n      png_debug1(1, \"in %s retrieval function\", \"pHYs\");\n\n      if (res_x != NULL)\n      {\n         *res_x = info_ptr->x_pixels_per_unit;\n         retval |= PNG_INFO_pHYs;\n      }\n\n      if (res_y != NULL)\n      {\n         *res_y = info_ptr->y_pixels_per_unit;\n         retval |= PNG_INFO_pHYs;\n      }\n\n      if (unit_type != NULL)\n      {\n         *unit_type = (int)info_ptr->phys_unit_type;\n         retval |= PNG_INFO_pHYs;\n\n         if (*unit_type == 1)\n         {\n            if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);\n            if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);\n         }\n      }\n   }\n\n   return (retval);\n}\n#endif /* pHYs */\n#endif  /* INCH_CONVERSIONS */\n\n/* png_get_channels really belongs in here, too, but it's been around longer */\n\n#endif  /* EASY_ACCESS */\n\n\npng_byte PNGAPI\npng_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   if (png_ptr != NULL && info_ptr != NULL)\n      return(info_ptr->channels);\n\n   return (0);\n}\n\n#ifdef PNG_READ_SUPPORTED\npng_const_bytep PNGAPI\npng_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)\n{\n   if (png_ptr != NULL && info_ptr != NULL)\n      return(info_ptr->signature);\n\n   return (NULL);\n}\n#endif\n\n#ifdef PNG_bKGD_SUPPORTED\npng_uint_32 PNGAPI\npng_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,\n   png_color_16p *background)\n{\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_bKGD) != 0 &&\n       background != NULL)\n   {\n      png_debug1(1, \"in %s retrieval function\", \"bKGD\");\n\n      *background = &(info_ptr->background);\n      return (PNG_INFO_bKGD);\n   }\n\n   return (0);\n}\n#endif\n\n#ifdef PNG_cHRM_SUPPORTED\n/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the\n * same time to correct the rgb grayscale coefficient defaults obtained from the\n * cHRM chunk in 1.5.4\n */\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\npng_uint_32 PNGAPI\npng_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,\n    double *white_x, double *white_y, double *red_x, double *red_y,\n    double *green_x, double *green_y, double *blue_x, double *blue_y)\n{\n   /* Quiet API change: this code used to only return the end points if a cHRM\n    * chunk was present, but the end points can also come from iCCP or sRGB\n    * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and\n    * the png_set_ APIs merely check that set end points are mutually\n    * consistent.\n    */\n   if (png_ptr != NULL && info_ptr != NULL &&\n      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)\n   {\n      png_debug1(1, \"in %s retrieval function\", \"cHRM\");\n\n      if (white_x != NULL)\n         *white_x = png_float(png_ptr,\n            info_ptr->colorspace.end_points_xy.whitex, \"cHRM white X\");\n      if (white_y != NULL)\n         *white_y = png_float(png_ptr,\n            info_ptr->colorspace.end_points_xy.whitey, \"cHRM white Y\");\n      if (red_x != NULL)\n         *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,\n            \"cHRM red X\");\n      if (red_y != NULL)\n         *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,\n            \"cHRM red Y\");\n      if (green_x != NULL)\n         *green_x = png_float(png_ptr,\n            info_ptr->colorspace.end_points_xy.greenx, \"cHRM green X\");\n      if (green_y != NULL)\n         *green_y = png_float(png_ptr,\n            info_ptr->colorspace.end_points_xy.greeny, \"cHRM green Y\");\n      if (blue_x != NULL)\n         *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,\n            \"cHRM blue X\");\n      if (blue_y != NULL)\n         *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,\n            \"cHRM blue Y\");\n      return (PNG_INFO_cHRM);\n   }\n\n   return (0);\n}\n\npng_uint_32 PNGAPI\npng_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,\n   double *red_X, double *red_Y, double *red_Z, double *green_X,\n   double *green_Y, double *green_Z, double *blue_X, double *blue_Y,\n   double *blue_Z)\n{\n   if (png_ptr != NULL && info_ptr != NULL &&\n      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)\n   {\n      png_debug1(1, \"in %s retrieval function\", \"cHRM_XYZ(float)\");\n\n      if (red_X != NULL)\n         *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,\n            \"cHRM red X\");\n      if (red_Y != NULL)\n         *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,\n            \"cHRM red Y\");\n      if (red_Z != NULL)\n         *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,\n            \"cHRM red Z\");\n      if (green_X != NULL)\n         *green_X = png_float(png_ptr,\n            info_ptr->colorspace.end_points_XYZ.green_X, \"cHRM green X\");\n      if (green_Y != NULL)\n         *green_Y = png_float(png_ptr,\n            info_ptr->colorspace.end_points_XYZ.green_Y, \"cHRM green Y\");\n      if (green_Z != NULL)\n         *green_Z = png_float(png_ptr,\n            info_ptr->colorspace.end_points_XYZ.green_Z, \"cHRM green Z\");\n      if (blue_X != NULL)\n         *blue_X = png_float(png_ptr,\n            info_ptr->colorspace.end_points_XYZ.blue_X, \"cHRM blue X\");\n      if (blue_Y != NULL)\n         *blue_Y = png_float(png_ptr,\n            info_ptr->colorspace.end_points_XYZ.blue_Y, \"cHRM blue Y\");\n      if (blue_Z != NULL)\n         *blue_Z = png_float(png_ptr,\n            info_ptr->colorspace.end_points_XYZ.blue_Z, \"cHRM blue Z\");\n      return (PNG_INFO_cHRM);\n   }\n\n   return (0);\n}\n#  endif\n\n#  ifdef PNG_FIXED_POINT_SUPPORTED\npng_uint_32 PNGAPI\npng_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,\n    png_fixed_point *int_red_X, png_fixed_point *int_red_Y,\n    png_fixed_point *int_red_Z, png_fixed_point *int_green_X,\n    png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,\n    png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,\n    png_fixed_point *int_blue_Z)\n{\n   if (png_ptr != NULL && info_ptr != NULL &&\n      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)\n   {\n      png_debug1(1, \"in %s retrieval function\", \"cHRM_XYZ\");\n\n      if (int_red_X != NULL)\n         *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X;\n      if (int_red_Y != NULL)\n         *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y;\n      if (int_red_Z != NULL)\n         *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z;\n      if (int_green_X != NULL)\n         *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X;\n      if (int_green_Y != NULL)\n         *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y;\n      if (int_green_Z != NULL)\n         *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z;\n      if (int_blue_X != NULL)\n         *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X;\n      if (int_blue_Y != NULL)\n         *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y;\n      if (int_blue_Z != NULL)\n         *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z;\n      return (PNG_INFO_cHRM);\n   }\n\n   return (0);\n}\n\npng_uint_32 PNGAPI\npng_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,\n    png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,\n    png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,\n    png_fixed_point *blue_x, png_fixed_point *blue_y)\n{\n   png_debug1(1, \"in %s retrieval function\", \"cHRM\");\n\n   if (png_ptr != NULL && info_ptr != NULL &&\n      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)\n   {\n      if (white_x != NULL)\n         *white_x = info_ptr->colorspace.end_points_xy.whitex;\n      if (white_y != NULL)\n         *white_y = info_ptr->colorspace.end_points_xy.whitey;\n      if (red_x != NULL)\n         *red_x = info_ptr->colorspace.end_points_xy.redx;\n      if (red_y != NULL)\n         *red_y = info_ptr->colorspace.end_points_xy.redy;\n      if (green_x != NULL)\n         *green_x = info_ptr->colorspace.end_points_xy.greenx;\n      if (green_y != NULL)\n         *green_y = info_ptr->colorspace.end_points_xy.greeny;\n      if (blue_x != NULL)\n         *blue_x = info_ptr->colorspace.end_points_xy.bluex;\n      if (blue_y != NULL)\n         *blue_y = info_ptr->colorspace.end_points_xy.bluey;\n      return (PNG_INFO_cHRM);\n   }\n\n   return (0);\n}\n#  endif\n#endif\n\n#ifdef PNG_gAMA_SUPPORTED\n#  ifdef PNG_FIXED_POINT_SUPPORTED\npng_uint_32 PNGAPI\npng_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,\n    png_fixed_point *file_gamma)\n{\n   png_debug1(1, \"in %s retrieval function\", \"gAMA\");\n\n   if (png_ptr != NULL && info_ptr != NULL &&\n      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&\n      file_gamma != NULL)\n   {\n      *file_gamma = info_ptr->colorspace.gamma;\n      return (PNG_INFO_gAMA);\n   }\n\n   return (0);\n}\n#  endif\n\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\npng_uint_32 PNGAPI\npng_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,\n    double *file_gamma)\n{\n   png_debug1(1, \"in %s retrieval function\", \"gAMA(float)\");\n\n   if (png_ptr != NULL && info_ptr != NULL &&\n      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&\n      file_gamma != NULL)\n   {\n      *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,\n         \"png_get_gAMA\");\n      return (PNG_INFO_gAMA);\n   }\n\n   return (0);\n}\n#  endif\n#endif\n\n#ifdef PNG_sRGB_SUPPORTED\npng_uint_32 PNGAPI\npng_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr,\n    int *file_srgb_intent)\n{\n   png_debug1(1, \"in %s retrieval function\", \"sRGB\");\n\n   if (png_ptr != NULL && info_ptr != NULL &&\n      (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL)\n   {\n      *file_srgb_intent = info_ptr->colorspace.rendering_intent;\n      return (PNG_INFO_sRGB);\n   }\n\n   return (0);\n}\n#endif\n\n#ifdef PNG_iCCP_SUPPORTED\npng_uint_32 PNGAPI\npng_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_charpp name, int *compression_type,\n    png_bytepp profile, png_uint_32 *proflen)\n{\n   png_debug1(1, \"in %s retrieval function\", \"iCCP\");\n\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_iCCP) != 0 &&\n       name != NULL && compression_type != NULL && profile != NULL &&\n           proflen != NULL)\n   {\n      *name = info_ptr->iccp_name;\n      *profile = info_ptr->iccp_profile;\n      *proflen = png_get_uint_32(info_ptr->iccp_profile);\n      /* This is somewhat irrelevant since the profile data returned has\n       * actually been uncompressed.\n       */\n      *compression_type = PNG_COMPRESSION_TYPE_BASE;\n      return (PNG_INFO_iCCP);\n   }\n\n   return (0);\n}\n#endif\n\n#ifdef PNG_sPLT_SUPPORTED\nint PNGAPI\npng_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_sPLT_tpp spalettes)\n{\n   if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)\n   {\n      *spalettes = info_ptr->splt_palettes;\n      return info_ptr->splt_palettes_num;\n   }\n\n   return (0);\n}\n#endif\n\n#ifdef PNG_hIST_SUPPORTED\npng_uint_32 PNGAPI\npng_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_uint_16p *hist)\n{\n   png_debug1(1, \"in %s retrieval function\", \"hIST\");\n\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL)\n   {\n      *hist = info_ptr->hist;\n      return (PNG_INFO_hIST);\n   }\n\n   return (0);\n}\n#endif\n\npng_uint_32 PNGAPI\npng_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,\n    png_uint_32 *width, png_uint_32 *height, int *bit_depth,\n    int *color_type, int *interlace_type, int *compression_type,\n    int *filter_type)\n{\n   png_debug1(1, \"in %s retrieval function\", \"IHDR\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return (0);\n\n   if (width != NULL)\n       *width = info_ptr->width;\n\n   if (height != NULL)\n       *height = info_ptr->height;\n\n   if (bit_depth != NULL)\n       *bit_depth = info_ptr->bit_depth;\n\n   if (color_type != NULL)\n       *color_type = info_ptr->color_type;\n\n   if (compression_type != NULL)\n      *compression_type = info_ptr->compression_type;\n\n   if (filter_type != NULL)\n      *filter_type = info_ptr->filter_type;\n\n   if (interlace_type != NULL)\n      *interlace_type = info_ptr->interlace_type;\n\n   /* This is redundant if we can be sure that the info_ptr values were all\n    * assigned in png_set_IHDR().  We do the check anyhow in case an\n    * application has ignored our advice not to mess with the members\n    * of info_ptr directly.\n    */\n   png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height,\n       info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,\n       info_ptr->compression_type, info_ptr->filter_type);\n\n   return (1);\n}\n\n#ifdef PNG_oFFs_SUPPORTED\npng_uint_32 PNGAPI\npng_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr,\n    png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)\n{\n   png_debug1(1, \"in %s retrieval function\", \"oFFs\");\n\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_oFFs) != 0 &&\n       offset_x != NULL && offset_y != NULL && unit_type != NULL)\n   {\n      *offset_x = info_ptr->x_offset;\n      *offset_y = info_ptr->y_offset;\n      *unit_type = (int)info_ptr->offset_unit_type;\n      return (PNG_INFO_oFFs);\n   }\n\n   return (0);\n}\n#endif\n\n#ifdef PNG_pCAL_SUPPORTED\npng_uint_32 PNGAPI\npng_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,\n    png_charp *units, png_charpp *params)\n{\n   png_debug1(1, \"in %s retrieval function\", \"pCAL\");\n\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_pCAL) != 0 &&\n       purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&\n       nparams != NULL && units != NULL && params != NULL)\n   {\n      *purpose = info_ptr->pcal_purpose;\n      *X0 = info_ptr->pcal_X0;\n      *X1 = info_ptr->pcal_X1;\n      *type = (int)info_ptr->pcal_type;\n      *nparams = (int)info_ptr->pcal_nparams;\n      *units = info_ptr->pcal_units;\n      *params = info_ptr->pcal_params;\n      return (PNG_INFO_pCAL);\n   }\n\n   return (0);\n}\n#endif\n\n#ifdef PNG_sCAL_SUPPORTED\n#  ifdef PNG_FIXED_POINT_SUPPORTED\n#    if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \\\n         defined(PNG_FLOATING_POINT_SUPPORTED)\npng_uint_32 PNGAPI\npng_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,\n    int *unit, png_fixed_point *width, png_fixed_point *height)\n{\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_sCAL) != 0)\n   {\n      *unit = info_ptr->scal_unit;\n      /*TODO: make this work without FP support; the API is currently eliminated\n       * if neither floating point APIs nor internal floating point arithmetic\n       * are enabled.\n       */\n      *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), \"sCAL width\");\n      *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),\n         \"sCAL height\");\n      return (PNG_INFO_sCAL);\n   }\n\n   return(0);\n}\n#    endif /* FLOATING_ARITHMETIC */\n#  endif /* FIXED_POINT */\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\npng_uint_32 PNGAPI\npng_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr,\n    int *unit, double *width, double *height)\n{\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_sCAL) != 0)\n   {\n      *unit = info_ptr->scal_unit;\n      *width = atof(info_ptr->scal_s_width);\n      *height = atof(info_ptr->scal_s_height);\n      return (PNG_INFO_sCAL);\n   }\n\n   return(0);\n}\n#  endif /* FLOATING POINT */\npng_uint_32 PNGAPI\npng_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr,\n    int *unit, png_charpp width, png_charpp height)\n{\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_sCAL) != 0)\n   {\n      *unit = info_ptr->scal_unit;\n      *width = info_ptr->scal_s_width;\n      *height = info_ptr->scal_s_height;\n      return (PNG_INFO_sCAL);\n   }\n\n   return(0);\n}\n#endif /* sCAL */\n\n#ifdef PNG_pHYs_SUPPORTED\npng_uint_32 PNGAPI\npng_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr,\n    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)\n{\n   png_uint_32 retval = 0;\n\n   png_debug1(1, \"in %s retrieval function\", \"pHYs\");\n\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_pHYs) != 0)\n   {\n      if (res_x != NULL)\n      {\n         *res_x = info_ptr->x_pixels_per_unit;\n         retval |= PNG_INFO_pHYs;\n      }\n\n      if (res_y != NULL)\n      {\n         *res_y = info_ptr->y_pixels_per_unit;\n         retval |= PNG_INFO_pHYs;\n      }\n\n      if (unit_type != NULL)\n      {\n         *unit_type = (int)info_ptr->phys_unit_type;\n         retval |= PNG_INFO_pHYs;\n      }\n   }\n\n   return (retval);\n}\n#endif /* pHYs */\n\npng_uint_32 PNGAPI\npng_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_colorp *palette, int *num_palette)\n{\n   png_debug1(1, \"in %s retrieval function\", \"PLTE\");\n\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL)\n   {\n      *palette = info_ptr->palette;\n      *num_palette = info_ptr->num_palette;\n      png_debug1(3, \"num_palette = %d\", *num_palette);\n      return (PNG_INFO_PLTE);\n   }\n\n   return (0);\n}\n\n#ifdef PNG_sBIT_SUPPORTED\npng_uint_32 PNGAPI\npng_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_color_8p *sig_bit)\n{\n   png_debug1(1, \"in %s retrieval function\", \"sBIT\");\n\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL)\n   {\n      *sig_bit = &(info_ptr->sig_bit);\n      return (PNG_INFO_sBIT);\n   }\n\n   return (0);\n}\n#endif\n\n#ifdef PNG_TEXT_SUPPORTED\nint PNGAPI\npng_get_text(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_textp *text_ptr, int *num_text)\n{\n   if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)\n   {\n      png_debug1(1, \"in 0x%lx retrieval function\",\n         (unsigned long)png_ptr->chunk_name);\n\n      if (text_ptr != NULL)\n         *text_ptr = info_ptr->text;\n\n      if (num_text != NULL)\n         *num_text = info_ptr->num_text;\n\n      return info_ptr->num_text;\n   }\n\n   if (num_text != NULL)\n      *num_text = 0;\n\n   return(0);\n}\n#endif\n\n#ifdef PNG_tIME_SUPPORTED\npng_uint_32 PNGAPI\npng_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_timep *mod_time)\n{\n   png_debug1(1, \"in %s retrieval function\", \"tIME\");\n\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL)\n   {\n      *mod_time = &(info_ptr->mod_time);\n      return (PNG_INFO_tIME);\n   }\n\n   return (0);\n}\n#endif\n\n#ifdef PNG_tRNS_SUPPORTED\npng_uint_32 PNGAPI\npng_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)\n{\n   png_uint_32 retval = 0;\n   if (png_ptr != NULL && info_ptr != NULL &&\n       (info_ptr->valid & PNG_INFO_tRNS) != 0)\n   {\n      png_debug1(1, \"in %s retrieval function\", \"tRNS\");\n\n      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n      {\n         if (trans_alpha != NULL)\n         {\n            *trans_alpha = info_ptr->trans_alpha;\n            retval |= PNG_INFO_tRNS;\n         }\n\n         if (trans_color != NULL)\n            *trans_color = &(info_ptr->trans_color);\n      }\n\n      else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */\n      {\n         if (trans_color != NULL)\n         {\n            *trans_color = &(info_ptr->trans_color);\n            retval |= PNG_INFO_tRNS;\n         }\n\n         if (trans_alpha != NULL)\n            *trans_alpha = NULL;\n      }\n\n      if (num_trans != NULL)\n      {\n         *num_trans = info_ptr->num_trans;\n         retval |= PNG_INFO_tRNS;\n      }\n   }\n\n   return (retval);\n}\n#endif\n\n#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED\nint PNGAPI\npng_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_unknown_chunkpp unknowns)\n{\n   if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)\n   {\n      *unknowns = info_ptr->unknown_chunks;\n      return info_ptr->unknown_chunks_num;\n   }\n\n   return (0);\n}\n#endif\n\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\npng_byte PNGAPI\npng_get_rgb_to_gray_status (png_const_structrp png_ptr)\n{\n   return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0);\n}\n#endif\n\n#ifdef PNG_USER_CHUNKS_SUPPORTED\npng_voidp PNGAPI\npng_get_user_chunk_ptr(png_const_structrp png_ptr)\n{\n   return (png_ptr ? png_ptr->user_chunk_ptr : NULL);\n}\n#endif\n\npng_size_t PNGAPI\npng_get_compression_buffer_size(png_const_structrp png_ptr)\n{\n   if (png_ptr == NULL)\n      return 0;\n\n#ifdef PNG_WRITE_SUPPORTED\n      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)\n#endif\n   {\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n         return png_ptr->IDAT_read_size;\n#else\n         return PNG_IDAT_READ_SIZE;\n#endif\n   }\n\n#ifdef PNG_WRITE_SUPPORTED\n      else\n         return png_ptr->zbuffer_size;\n#endif\n}\n\n#ifdef PNG_SET_USER_LIMITS_SUPPORTED\n/* These functions were added to libpng 1.2.6 and were enabled\n * by default in libpng-1.4.0 */\npng_uint_32 PNGAPI\npng_get_user_width_max (png_const_structrp png_ptr)\n{\n   return (png_ptr ? png_ptr->user_width_max : 0);\n}\n\npng_uint_32 PNGAPI\npng_get_user_height_max (png_const_structrp png_ptr)\n{\n   return (png_ptr ? png_ptr->user_height_max : 0);\n}\n\n/* This function was added to libpng 1.4.0 */\npng_uint_32 PNGAPI\npng_get_chunk_cache_max (png_const_structrp png_ptr)\n{\n   return (png_ptr ? png_ptr->user_chunk_cache_max : 0);\n}\n\n/* This function was added to libpng 1.4.1 */\npng_alloc_size_t PNGAPI\npng_get_chunk_malloc_max (png_const_structrp png_ptr)\n{\n   return (png_ptr ? png_ptr->user_chunk_malloc_max : 0);\n}\n#endif /* SET_USER_LIMITS */\n\n/* These functions were added to libpng 1.4.0 */\n#ifdef PNG_IO_STATE_SUPPORTED\npng_uint_32 PNGAPI\npng_get_io_state (png_const_structrp png_ptr)\n{\n   return png_ptr->io_state;\n}\n\npng_uint_32 PNGAPI\npng_get_io_chunk_type (png_const_structrp png_ptr)\n{\n   return png_ptr->chunk_name;\n}\n#endif /* IO_STATE */\n\n#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED\n#  ifdef PNG_GET_PALETTE_MAX_SUPPORTED\nint PNGAPI\npng_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr)\n{\n   if (png_ptr != NULL && info_ptr != NULL)\n      return png_ptr->num_palette_max;\n\n   return (-1);\n}\n#  endif\n#endif\n\n#endif /* READ || WRITE */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pnginfo.h",
    "content": "\n/* pnginfo.h - header file for PNG reference library\n *\n * Last changed in libpng 1.6.1 [March 28, 2013]\n * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n /* png_info is a structure that holds the information in a PNG file so\n * that the application can find out the characteristics of the image.\n * If you are reading the file, this structure will tell you what is\n * in the PNG file.  If you are writing the file, fill in the information\n * you want to put into the PNG file, using png_set_*() functions, then\n * call png_write_info().\n *\n * The names chosen should be very close to the PNG specification, so\n * consult that document for information about the meaning of each field.\n *\n * With libpng < 0.95, it was only possible to directly set and read the\n * the values in the png_info_struct, which meant that the contents and\n * order of the values had to remain fixed.  With libpng 0.95 and later,\n * however, there are now functions that abstract the contents of\n * png_info_struct from the application, so this makes it easier to use\n * libpng with dynamic libraries, and even makes it possible to use\n * libraries that don't have all of the libpng ancillary chunk-handing\n * functionality.  In libpng-1.5.0 this was moved into a separate private\n * file that is not visible to applications.\n *\n * The following members may have allocated storage attached that should be\n * cleaned up before the structure is discarded: palette, trans, text,\n * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,\n * splt_palettes, scal_unit, row_pointers, and unknowns.   By default, these\n * are automatically freed when the info structure is deallocated, if they were\n * allocated internally by libpng.  This behavior can be changed by means\n * of the png_data_freer() function.\n *\n * More allocation details: all the chunk-reading functions that\n * change these members go through the corresponding png_set_*\n * functions.  A function to clear these members is available: see\n * png_free_data().  The png_set_* functions do not depend on being\n * able to point info structure members to any of the storage they are\n * passed (they make their own copies), EXCEPT that the png_set_text\n * functions use the same storage passed to them in the text_ptr or\n * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns\n * functions do not make their own copies.\n */\n#ifndef PNGINFO_H\n#define PNGINFO_H\n\nstruct png_info_def\n{\n   /* The following are necessary for every PNG file */\n   png_uint_32 width;  /* width of image in pixels (from IHDR) */\n   png_uint_32 height; /* height of image in pixels (from IHDR) */\n   png_uint_32 valid;  /* valid chunk data (see PNG_INFO_ below) */\n   png_size_t rowbytes; /* bytes needed to hold an untransformed row */\n   png_colorp palette;      /* array of color values (valid & PNG_INFO_PLTE) */\n   png_uint_16 num_palette; /* number of color entries in \"palette\" (PLTE) */\n   png_uint_16 num_trans;   /* number of transparent palette color (tRNS) */\n   png_byte bit_depth;      /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */\n   png_byte color_type;     /* see PNG_COLOR_TYPE_ below (from IHDR) */\n   /* The following three should have been named *_method not *_type */\n   png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */\n   png_byte filter_type;    /* must be PNG_FILTER_TYPE_BASE (from IHDR) */\n   png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */\n\n   /* The following are set by png_set_IHDR, called from the application on\n    * write, but the are never actually used by the write code.\n    */\n   png_byte channels;       /* number of data channels per pixel (1, 2, 3, 4) */\n   png_byte pixel_depth;    /* number of bits per pixel */\n   png_byte spare_byte;     /* to align the data, and for future use */\n\n#ifdef PNG_READ_SUPPORTED\n   /* This is never set during write */\n   png_byte signature[8];   /* magic bytes read by libpng from start of file */\n#endif\n\n   /* The rest of the data is optional.  If you are reading, check the\n    * valid field to see if the information in these are valid.  If you\n    * are writing, set the valid field to those chunks you want written,\n    * and initialize the appropriate fields below.\n    */\n\n#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)\n   /* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are\n    * defined.  When COLORSPACE is switched on all the colorspace-defining\n    * chunks should be enabled, when GAMMA is switched on all the gamma-defining\n    * chunks should be enabled.  If this is not done it becomes possible to read\n    * inconsistent PNG files and assign a probably incorrect interpretation to\n    * the information.  (In other words, by carefully choosing which chunks to\n    * recognize the system configuration can select an interpretation for PNG\n    * files containing ambiguous data and this will result in inconsistent\n    * behavior between different libpng builds!)\n    */\n   png_colorspace colorspace;\n#endif\n\n#ifdef PNG_iCCP_SUPPORTED\n   /* iCCP chunk data. */\n   png_charp iccp_name;     /* profile name */\n   png_bytep iccp_profile;  /* International Color Consortium profile data */\n   png_uint_32 iccp_proflen;  /* ICC profile data length */\n#endif\n\n#ifdef PNG_TEXT_SUPPORTED\n   /* The tEXt, and zTXt chunks contain human-readable textual data in\n    * uncompressed, compressed, and optionally compressed forms, respectively.\n    * The data in \"text\" is an array of pointers to uncompressed,\n    * null-terminated C strings. Each chunk has a keyword that describes the\n    * textual data contained in that chunk.  Keywords are not required to be\n    * unique, and the text string may be empty.  Any number of text chunks may\n    * be in an image.\n    */\n   int num_text; /* number of comments read or comments to write */\n   int max_text; /* current size of text array */\n   png_textp text; /* array of comments read or comments to write */\n#endif /* TEXT */\n\n#ifdef PNG_tIME_SUPPORTED\n   /* The tIME chunk holds the last time the displayed image data was\n    * modified.  See the png_time struct for the contents of this struct.\n    */\n   png_time mod_time;\n#endif\n\n#ifdef PNG_sBIT_SUPPORTED\n   /* The sBIT chunk specifies the number of significant high-order bits\n    * in the pixel data.  Values are in the range [1, bit_depth], and are\n    * only specified for the channels in the pixel data.  The contents of\n    * the low-order bits is not specified.  Data is valid if\n    * (valid & PNG_INFO_sBIT) is non-zero.\n    */\n   png_color_8 sig_bit; /* significant bits in color channels */\n#endif\n\n#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \\\ndefined(PNG_READ_BACKGROUND_SUPPORTED)\n   /* The tRNS chunk supplies transparency data for paletted images and\n    * other image types that don't need a full alpha channel.  There are\n    * \"num_trans\" transparency values for a paletted image, stored in the\n    * same order as the palette colors, starting from index 0.  Values\n    * for the data are in the range [0, 255], ranging from fully transparent\n    * to fully opaque, respectively.  For non-paletted images, there is a\n    * single color specified that should be treated as fully transparent.\n    * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.\n    */\n   png_bytep trans_alpha;    /* alpha values for paletted image */\n   png_color_16 trans_color; /* transparent color for non-palette image */\n#endif\n\n#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)\n   /* The bKGD chunk gives the suggested image background color if the\n    * display program does not have its own background color and the image\n    * is needs to composited onto a background before display.  The colors\n    * in \"background\" are normally in the same color space/depth as the\n    * pixel data.  Data is valid if (valid & PNG_INFO_bKGD) is non-zero.\n    */\n   png_color_16 background;\n#endif\n\n#ifdef PNG_oFFs_SUPPORTED\n   /* The oFFs chunk gives the offset in \"offset_unit_type\" units rightwards\n    * and downwards from the top-left corner of the display, page, or other\n    * application-specific co-ordinate space.  See the PNG_OFFSET_ defines\n    * below for the unit types.  Valid if (valid & PNG_INFO_oFFs) non-zero.\n    */\n   png_int_32 x_offset; /* x offset on page */\n   png_int_32 y_offset; /* y offset on page */\n   png_byte offset_unit_type; /* offset units type */\n#endif\n\n#ifdef PNG_pHYs_SUPPORTED\n   /* The pHYs chunk gives the physical pixel density of the image for\n    * display or printing in \"phys_unit_type\" units (see PNG_RESOLUTION_\n    * defines below).  Data is valid if (valid & PNG_INFO_pHYs) is non-zero.\n    */\n   png_uint_32 x_pixels_per_unit; /* horizontal pixel density */\n   png_uint_32 y_pixels_per_unit; /* vertical pixel density */\n   png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */\n#endif\n\n#ifdef PNG_hIST_SUPPORTED\n   /* The hIST chunk contains the relative frequency or importance of the\n    * various palette entries, so that a viewer can intelligently select a\n    * reduced-color palette, if required.  Data is an array of \"num_palette\"\n    * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)\n    * is non-zero.\n    */\n   png_uint_16p hist;\n#endif\n\n#ifdef PNG_pCAL_SUPPORTED\n   /* The pCAL chunk describes a transformation between the stored pixel\n    * values and original physical data values used to create the image.\n    * The integer range [0, 2^bit_depth - 1] maps to the floating-point\n    * range given by [pcal_X0, pcal_X1], and are further transformed by a\n    * (possibly non-linear) transformation function given by \"pcal_type\"\n    * and \"pcal_params\" into \"pcal_units\".  Please see the PNG_EQUATION_\n    * defines below, and the PNG-Group's PNG extensions document for a\n    * complete description of the transformations and how they should be\n    * implemented, and for a description of the ASCII parameter strings.\n    * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.\n    */\n   png_charp pcal_purpose;  /* pCAL chunk description string */\n   png_int_32 pcal_X0;      /* minimum value */\n   png_int_32 pcal_X1;      /* maximum value */\n   png_charp pcal_units;    /* Latin-1 string giving physical units */\n   png_charpp pcal_params;  /* ASCII strings containing parameter values */\n   png_byte pcal_type;      /* equation type (see PNG_EQUATION_ below) */\n   png_byte pcal_nparams;   /* number of parameters given in pcal_params */\n#endif\n\n/* New members added in libpng-1.0.6 */\n   png_uint_32 free_me;     /* flags items libpng is responsible for freeing */\n\n#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED\n   /* Storage for unknown chunks that the library doesn't recognize. */\n   png_unknown_chunkp unknown_chunks;\n\n   /* The type of this field is limited by the type of\n    * png_struct::user_chunk_cache_max, else overflow can occur.\n    */\n   int                unknown_chunks_num;\n#endif\n\n#ifdef PNG_sPLT_SUPPORTED\n   /* Data on sPLT chunks (there may be more than one). */\n   png_sPLT_tp splt_palettes;\n   int         splt_palettes_num; /* Match type returned by png_get API */\n#endif\n\n#ifdef PNG_sCAL_SUPPORTED\n   /* The sCAL chunk describes the actual physical dimensions of the\n    * subject matter of the graphic.  The chunk contains a unit specification\n    * a byte value, and two ASCII strings representing floating-point\n    * values.  The values are width and height corresponsing to one pixel\n    * in the image.  Data values are valid if (valid & PNG_INFO_sCAL) is\n    * non-zero.\n    */\n   png_byte scal_unit;         /* unit of physical scale */\n   png_charp scal_s_width;     /* string containing height */\n   png_charp scal_s_height;    /* string containing width */\n#endif\n\n#ifdef PNG_INFO_IMAGE_SUPPORTED\n   /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS)\n      non-zero */\n   /* Data valid if (valid & PNG_INFO_IDAT) non-zero */\n   png_bytepp row_pointers;        /* the image bits */\n#endif\n\n};\n#endif /* PNGINFO_H */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pnglibconf.h",
    "content": "/* libpng 1.6.22beta03 STANDARD API DEFINITION */\n\n/* pnglibconf.h - library build configuration */\n\n/* Libpng version 1.6.22beta03 - February 8, 2016 */\n\n/* Copyright (c) 1998-2015 Glenn Randers-Pehrson */\n\n/* This code is released under the libpng license. */\n/* For conditions of distribution and use, see the disclaimer */\n/* and license in png.h */\n\n/* pnglibconf.h */\n/* Machine generated file: DO NOT EDIT */\n/* Derived from: scripts/pnglibconf.dfa */\n#ifndef PNGLCONF_H\n#define PNGLCONF_H\n/* options */\n#define PNG_16BIT_SUPPORTED\n#define PNG_ALIGNED_MEMORY_SUPPORTED\n/*#undef PNG_ARM_NEON_API_SUPPORTED*/\n/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/\n#define PNG_BENIGN_ERRORS_SUPPORTED\n#define PNG_BENIGN_READ_ERRORS_SUPPORTED\n/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/\n#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED\n#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED\n#define PNG_COLORSPACE_SUPPORTED\n#define PNG_CONSOLE_IO_SUPPORTED\n#define PNG_CONVERT_tIME_SUPPORTED\n#define PNG_EASY_ACCESS_SUPPORTED\n/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/\n#define PNG_ERROR_TEXT_SUPPORTED\n#define PNG_FIXED_POINT_SUPPORTED\n#define PNG_FLOATING_ARITHMETIC_SUPPORTED\n#define PNG_FLOATING_POINT_SUPPORTED\n#define PNG_FORMAT_AFIRST_SUPPORTED\n#define PNG_FORMAT_BGR_SUPPORTED\n#define PNG_GAMMA_SUPPORTED\n#define PNG_GET_PALETTE_MAX_SUPPORTED\n#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED\n#define PNG_INCH_CONVERSIONS_SUPPORTED\n#define PNG_INFO_IMAGE_SUPPORTED\n#define PNG_IO_STATE_SUPPORTED\n#define PNG_MNG_FEATURES_SUPPORTED\n#define PNG_POINTER_INDEXING_SUPPORTED\n#define PNG_PROGRESSIVE_READ_SUPPORTED\n#define PNG_READ_16BIT_SUPPORTED\n#define PNG_READ_ALPHA_MODE_SUPPORTED\n#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED\n#define PNG_READ_BACKGROUND_SUPPORTED\n#define PNG_READ_BGR_SUPPORTED\n#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED\n#define PNG_READ_COMPOSITE_NODIV_SUPPORTED\n#define PNG_READ_COMPRESSED_TEXT_SUPPORTED\n#define PNG_READ_EXPAND_16_SUPPORTED\n#define PNG_READ_EXPAND_SUPPORTED\n#define PNG_READ_FILLER_SUPPORTED\n#define PNG_READ_GAMMA_SUPPORTED\n#define PNG_READ_GET_PALETTE_MAX_SUPPORTED\n#define PNG_READ_GRAY_TO_RGB_SUPPORTED\n#define PNG_READ_INTERLACING_SUPPORTED\n#define PNG_READ_INT_FUNCTIONS_SUPPORTED\n#define PNG_READ_INVERT_ALPHA_SUPPORTED\n#define PNG_READ_INVERT_SUPPORTED\n#define PNG_READ_OPT_PLTE_SUPPORTED\n#define PNG_READ_PACKSWAP_SUPPORTED\n#define PNG_READ_PACK_SUPPORTED\n#define PNG_READ_QUANTIZE_SUPPORTED\n#define PNG_READ_RGB_TO_GRAY_SUPPORTED\n#define PNG_READ_SCALE_16_TO_8_SUPPORTED\n#define PNG_READ_SHIFT_SUPPORTED\n#define PNG_READ_STRIP_16_TO_8_SUPPORTED\n#define PNG_READ_STRIP_ALPHA_SUPPORTED\n#define PNG_READ_SUPPORTED\n#define PNG_READ_SWAP_ALPHA_SUPPORTED\n#define PNG_READ_SWAP_SUPPORTED\n#define PNG_READ_TEXT_SUPPORTED\n#define PNG_READ_TRANSFORMS_SUPPORTED\n#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED\n#define PNG_READ_USER_CHUNKS_SUPPORTED\n#define PNG_READ_USER_TRANSFORM_SUPPORTED\n#define PNG_READ_bKGD_SUPPORTED\n#define PNG_READ_cHRM_SUPPORTED\n#define PNG_READ_gAMA_SUPPORTED\n#define PNG_READ_hIST_SUPPORTED\n#define PNG_READ_iCCP_SUPPORTED\n#define PNG_READ_iTXt_SUPPORTED\n#define PNG_READ_oFFs_SUPPORTED\n#define PNG_READ_pCAL_SUPPORTED\n#define PNG_READ_pHYs_SUPPORTED\n#define PNG_READ_sBIT_SUPPORTED\n#define PNG_READ_sCAL_SUPPORTED\n#define PNG_READ_sPLT_SUPPORTED\n#define PNG_READ_sRGB_SUPPORTED\n#define PNG_READ_tEXt_SUPPORTED\n#define PNG_READ_tIME_SUPPORTED\n#define PNG_READ_tRNS_SUPPORTED\n#define PNG_READ_zTXt_SUPPORTED\n#define PNG_SAVE_INT_32_SUPPORTED\n#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED\n#define PNG_SEQUENTIAL_READ_SUPPORTED\n#define PNG_SETJMP_SUPPORTED\n#define PNG_SET_OPTION_SUPPORTED\n#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED\n#define PNG_SET_USER_LIMITS_SUPPORTED\n#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED\n#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED\n#define PNG_SIMPLIFIED_READ_SUPPORTED\n#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED\n#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED\n#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED\n#define PNG_SIMPLIFIED_WRITE_SUPPORTED\n#define PNG_STDIO_SUPPORTED\n#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED\n#define PNG_TEXT_SUPPORTED\n#define PNG_TIME_RFC1123_SUPPORTED\n#define PNG_UNKNOWN_CHUNKS_SUPPORTED\n#define PNG_USER_CHUNKS_SUPPORTED\n#define PNG_USER_LIMITS_SUPPORTED\n#define PNG_USER_MEM_SUPPORTED\n#define PNG_USER_TRANSFORM_INFO_SUPPORTED\n#define PNG_USER_TRANSFORM_PTR_SUPPORTED\n/*#undef PNG_WARNINGS_SUPPORTED*/\n#define PNG_WRITE_16BIT_SUPPORTED\n#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED\n#define PNG_WRITE_BGR_SUPPORTED\n#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED\n#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED\n#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED\n#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED\n#define PNG_WRITE_FILLER_SUPPORTED\n#define PNG_WRITE_FILTER_SUPPORTED\n#define PNG_WRITE_FLUSH_SUPPORTED\n#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED\n#define PNG_WRITE_INTERLACING_SUPPORTED\n#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED\n#define PNG_WRITE_INVERT_ALPHA_SUPPORTED\n#define PNG_WRITE_INVERT_SUPPORTED\n#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED\n#define PNG_WRITE_PACKSWAP_SUPPORTED\n#define PNG_WRITE_PACK_SUPPORTED\n#define PNG_WRITE_SHIFT_SUPPORTED\n#define PNG_WRITE_SUPPORTED\n#define PNG_WRITE_SWAP_ALPHA_SUPPORTED\n#define PNG_WRITE_SWAP_SUPPORTED\n#define PNG_WRITE_TEXT_SUPPORTED\n#define PNG_WRITE_TRANSFORMS_SUPPORTED\n#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED\n#define PNG_WRITE_USER_TRANSFORM_SUPPORTED\n#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED\n#define PNG_WRITE_bKGD_SUPPORTED\n#define PNG_WRITE_cHRM_SUPPORTED\n#define PNG_WRITE_gAMA_SUPPORTED\n#define PNG_WRITE_hIST_SUPPORTED\n#define PNG_WRITE_iCCP_SUPPORTED\n#define PNG_WRITE_iTXt_SUPPORTED\n#define PNG_WRITE_oFFs_SUPPORTED\n#define PNG_WRITE_pCAL_SUPPORTED\n#define PNG_WRITE_pHYs_SUPPORTED\n#define PNG_WRITE_sBIT_SUPPORTED\n#define PNG_WRITE_sCAL_SUPPORTED\n#define PNG_WRITE_sPLT_SUPPORTED\n#define PNG_WRITE_sRGB_SUPPORTED\n#define PNG_WRITE_tEXt_SUPPORTED\n#define PNG_WRITE_tIME_SUPPORTED\n#define PNG_WRITE_tRNS_SUPPORTED\n#define PNG_WRITE_zTXt_SUPPORTED\n#define PNG_bKGD_SUPPORTED\n#define PNG_cHRM_SUPPORTED\n#define PNG_gAMA_SUPPORTED\n#define PNG_hIST_SUPPORTED\n#define PNG_iCCP_SUPPORTED\n#define PNG_iTXt_SUPPORTED\n#define PNG_oFFs_SUPPORTED\n#define PNG_pCAL_SUPPORTED\n#define PNG_pHYs_SUPPORTED\n#define PNG_sBIT_SUPPORTED\n#define PNG_sCAL_SUPPORTED\n#define PNG_sPLT_SUPPORTED\n#define PNG_sRGB_SUPPORTED\n#define PNG_tEXt_SUPPORTED\n#define PNG_tIME_SUPPORTED\n#define PNG_tRNS_SUPPORTED\n#define PNG_zTXt_SUPPORTED\n/* end of options */\n/* settings */\n#define PNG_API_RULE 0\n#define PNG_DEFAULT_READ_MACROS 1\n#define PNG_GAMMA_THRESHOLD_FIXED 5000\n#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE\n#define PNG_INFLATE_BUF_SIZE 1024\n#define PNG_LINKAGE_API extern\n#define PNG_LINKAGE_CALLBACK extern\n#define PNG_LINKAGE_DATA extern\n#define PNG_LINKAGE_FUNCTION extern\n#define PNG_MAX_GAMMA_8 11\n#define PNG_QUANTIZE_BLUE_BITS 5\n#define PNG_QUANTIZE_GREEN_BITS 5\n#define PNG_QUANTIZE_RED_BITS 5\n#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)\n#define PNG_TEXT_Z_DEFAULT_STRATEGY 0\n#define PNG_USER_CHUNK_CACHE_MAX 1000\n#define PNG_USER_CHUNK_MALLOC_MAX 8000000\n#define PNG_USER_HEIGHT_MAX 1000000\n#define PNG_USER_WIDTH_MAX 1000000\n#define PNG_ZBUF_SIZE 8192\n#define PNG_ZLIB_VERNUM 0 /* unknown */\n#define PNG_Z_DEFAULT_COMPRESSION (-1)\n#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0\n#define PNG_Z_DEFAULT_STRATEGY 1\n#define PNG_sCAL_PRECISION 5\n#define PNG_sRGB_PROFILE_CHECKS 2\n/* end of settings */\n#endif /* PNGLCONF_H */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngmem.c",
    "content": "\n/* pngmem.c - stub functions for memory allocation\n *\n * Last changed in libpng 1.6.15 [November 20, 2014]\n * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * This file provides a location for all memory allocation.  Users who\n * need special memory handling are expected to supply replacement\n * functions for png_malloc() and png_free(), and to use\n * png_create_read_struct_2() and png_create_write_struct_2() to\n * identify the replacement functions.\n */\n\n#include \"pngpriv.h\"\n\n#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)\n/* Free a png_struct */\nvoid /* PRIVATE */\npng_destroy_png_struct(png_structrp png_ptr)\n{\n   if (png_ptr != NULL)\n   {\n      /* png_free might call png_error and may certainly call\n       * png_get_mem_ptr, so fake a temporary png_struct to support this.\n       */\n      png_struct dummy_struct = *png_ptr;\n      memset(png_ptr, 0, (sizeof *png_ptr));\n      png_free(&dummy_struct, png_ptr);\n\n#     ifdef PNG_SETJMP_SUPPORTED\n         /* We may have a jmp_buf left to deallocate. */\n         png_free_jmpbuf(&dummy_struct);\n#     endif\n   }\n}\n\n/* Allocate memory.  For reasonable files, size should never exceed\n * 64K.  However, zlib may allocate more than 64K if you don't tell\n * it not to.  See zconf.h and png.h for more information.  zlib does\n * need to allocate exactly 64K, so whatever you call here must\n * have the ability to do that.\n */\nPNG_FUNCTION(png_voidp,PNGAPI\npng_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)\n{\n   png_voidp ret;\n\n   ret = png_malloc(png_ptr, size);\n\n   if (ret != NULL)\n      memset(ret, 0, size);\n\n   return ret;\n}\n\n/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of\n * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED.\n * Checking and error handling must happen outside this routine; it returns NULL\n * if the allocation cannot be done (for any reason.)\n */\nPNG_FUNCTION(png_voidp /* PRIVATE */,\npng_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),\n   PNG_ALLOCATED)\n{\n   /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS\n    * allocators have also been removed in 1.6.0, so any 16-bit system now has\n    * to implement a user memory handler.  This checks to be sure it isn't\n    * called with big numbers.\n    */\n#ifndef PNG_USER_MEM_SUPPORTED\n   PNG_UNUSED(png_ptr)\n#endif\n\n   /* Some compilers complain that this is always true.  However, it\n    * can be false when integer overflow happens.\n    */\n   if (size > 0 && size <= PNG_SIZE_MAX\n#     ifdef PNG_MAX_MALLOC_64K\n         && size <= 65536U\n#     endif\n      )\n   {\n#ifdef PNG_USER_MEM_SUPPORTED\n      if (png_ptr != NULL && png_ptr->malloc_fn != NULL)\n         return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);\n\n      else\n#endif\n         return malloc((size_t)size); /* checked for truncation above */\n   }\n\n   else\n      return NULL;\n}\n\n#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\\\n   defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)\n/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7\n * that arises because of the checks in png_realloc_array that are repeated in\n * png_malloc_array.\n */\nstatic png_voidp\npng_malloc_array_checked(png_const_structrp png_ptr, int nelements,\n   size_t element_size)\n{\n   png_alloc_size_t req = nelements; /* known to be > 0 */\n\n   if (req <= PNG_SIZE_MAX/element_size)\n      return png_malloc_base(png_ptr, req * element_size);\n\n   /* The failure case when the request is too large */\n   return NULL;\n}\n\nPNG_FUNCTION(png_voidp /* PRIVATE */,\npng_malloc_array,(png_const_structrp png_ptr, int nelements,\n   size_t element_size),PNG_ALLOCATED)\n{\n   if (nelements <= 0 || element_size == 0)\n      png_error(png_ptr, \"internal error: array alloc\");\n\n   return png_malloc_array_checked(png_ptr, nelements, element_size);\n}\n\nPNG_FUNCTION(png_voidp /* PRIVATE */,\npng_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,\n   int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)\n{\n   /* These are internal errors: */\n   if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||\n      (old_array == NULL && old_elements > 0))\n      png_error(png_ptr, \"internal error: array realloc\");\n\n   /* Check for overflow on the elements count (so the caller does not have to\n    * check.)\n    */\n   if (add_elements <= INT_MAX - old_elements)\n   {\n      png_voidp new_array = png_malloc_array_checked(png_ptr,\n         old_elements+add_elements, element_size);\n\n      if (new_array != NULL)\n      {\n         /* Because png_malloc_array worked the size calculations below cannot\n          * overflow.\n          */\n         if (old_elements > 0)\n            memcpy(new_array, old_array, element_size*(unsigned)old_elements);\n\n         memset((char*)new_array + element_size*(unsigned)old_elements, 0,\n            element_size*(unsigned)add_elements);\n\n         return new_array;\n      }\n   }\n\n   return NULL; /* error */\n}\n#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */\n\n/* Various functions that have different error handling are derived from this.\n * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate\n * function png_malloc_default is also provided.\n */\nPNG_FUNCTION(png_voidp,PNGAPI\npng_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)\n{\n   png_voidp ret;\n\n   if (png_ptr == NULL)\n      return NULL;\n\n   ret = png_malloc_base(png_ptr, size);\n\n   if (ret == NULL)\n       png_error(png_ptr, \"Out of memory\"); /* 'm' means png_malloc */\n\n   return ret;\n}\n\n#ifdef PNG_USER_MEM_SUPPORTED\nPNG_FUNCTION(png_voidp,PNGAPI\npng_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),\n   PNG_ALLOCATED PNG_DEPRECATED)\n{\n   png_voidp ret;\n\n   if (png_ptr == NULL)\n      return NULL;\n\n   /* Passing 'NULL' here bypasses the application provided memory handler. */\n   ret = png_malloc_base(NULL/*use malloc*/, size);\n\n   if (ret == NULL)\n      png_error(png_ptr, \"Out of Memory\"); /* 'M' means png_malloc_default */\n\n   return ret;\n}\n#endif /* USER_MEM */\n\n/* This function was added at libpng version 1.2.3.  The png_malloc_warn()\n * function will issue a png_warning and return NULL instead of issuing a\n * png_error, if it fails to allocate the requested memory.\n */\nPNG_FUNCTION(png_voidp,PNGAPI\npng_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),\n   PNG_ALLOCATED)\n{\n   if (png_ptr != NULL)\n   {\n      png_voidp ret = png_malloc_base(png_ptr, size);\n\n      if (ret != NULL)\n         return ret;\n\n      png_warning(png_ptr, \"Out of memory\");\n   }\n\n   return NULL;\n}\n\n/* Free a pointer allocated by png_malloc().  If ptr is NULL, return\n * without taking any action.\n */\nvoid PNGAPI\npng_free(png_const_structrp png_ptr, png_voidp ptr)\n{\n   if (png_ptr == NULL || ptr == NULL)\n      return;\n\n#ifdef PNG_USER_MEM_SUPPORTED\n   if (png_ptr->free_fn != NULL)\n      png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr);\n\n   else\n      png_free_default(png_ptr, ptr);\n}\n\nPNG_FUNCTION(void,PNGAPI\npng_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED)\n{\n   if (png_ptr == NULL || ptr == NULL)\n      return;\n#endif /* USER_MEM */\n\n   free(ptr);\n}\n\n#ifdef PNG_USER_MEM_SUPPORTED\n/* This function is called when the application wants to use another method\n * of allocating and freeing memory.\n */\nvoid PNGAPI\npng_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr\n  malloc_fn, png_free_ptr free_fn)\n{\n   if (png_ptr != NULL)\n   {\n      png_ptr->mem_ptr = mem_ptr;\n      png_ptr->malloc_fn = malloc_fn;\n      png_ptr->free_fn = free_fn;\n   }\n}\n\n/* This function returns a pointer to the mem_ptr associated with the user\n * functions.  The application should free any memory associated with this\n * pointer before png_write_destroy and png_read_destroy are called.\n */\npng_voidp PNGAPI\npng_get_mem_ptr(png_const_structrp png_ptr)\n{\n   if (png_ptr == NULL)\n      return NULL;\n\n   return png_ptr->mem_ptr;\n}\n#endif /* USER_MEM */\n#endif /* READ || WRITE */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngpread.c",
    "content": "\n/* pngpread.c - read a png file in push mode\n *\n * Last changed in libpng 1.6.18 [July 23, 2015]\n * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n#include \"pngpriv.h\"\n\n#ifdef PNG_PROGRESSIVE_READ_SUPPORTED\n\n/* Push model modes */\n#define PNG_READ_SIG_MODE   0\n#define PNG_READ_CHUNK_MODE 1\n#define PNG_READ_IDAT_MODE  2\n#define PNG_READ_tEXt_MODE  4\n#define PNG_READ_zTXt_MODE  5\n#define PNG_READ_DONE_MODE  6\n#define PNG_READ_iTXt_MODE  7\n#define PNG_ERROR_MODE      8\n\n#define PNG_PUSH_SAVE_BUFFER_IF_FULL \\\nif (png_ptr->push_length + 4 > png_ptr->buffer_size) \\\n   { png_push_save_buffer(png_ptr); return; }\n#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \\\nif (png_ptr->buffer_size < N) \\\n   { png_push_save_buffer(png_ptr); return; }\n\nvoid PNGAPI\npng_process_data(png_structrp png_ptr, png_inforp info_ptr,\n    png_bytep buffer, png_size_t buffer_size)\n{\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   png_push_restore_buffer(png_ptr, buffer, buffer_size);\n\n   while (png_ptr->buffer_size)\n   {\n      png_process_some_data(png_ptr, info_ptr);\n   }\n}\n\npng_size_t PNGAPI\npng_process_data_pause(png_structrp png_ptr, int save)\n{\n   if (png_ptr != NULL)\n   {\n      /* It's easiest for the caller if we do the save; then the caller doesn't\n       * have to supply the same data again:\n       */\n      if (save != 0)\n         png_push_save_buffer(png_ptr);\n      else\n      {\n         /* This includes any pending saved bytes: */\n         png_size_t remaining = png_ptr->buffer_size;\n         png_ptr->buffer_size = 0;\n\n         /* So subtract the saved buffer size, unless all the data\n          * is actually 'saved', in which case we just return 0\n          */\n         if (png_ptr->save_buffer_size < remaining)\n            return remaining - png_ptr->save_buffer_size;\n      }\n   }\n\n   return 0;\n}\n\npng_uint_32 PNGAPI\npng_process_data_skip(png_structrp png_ptr)\n{\n  /* TODO: Deprecate and remove this API.\n   * Somewhere the implementation of this seems to have been lost,\n   * or abandoned.  It was only to support some internal back-door access\n   * to png_struct) in libpng-1.4.x.\n   */\n   png_app_warning(png_ptr,\n\"png_process_data_skip is not implemented in any current version of libpng\");\n   return 0;\n}\n\n/* What we do with the incoming data depends on what we were previously\n * doing before we ran out of data...\n */\nvoid /* PRIVATE */\npng_process_some_data(png_structrp png_ptr, png_inforp info_ptr)\n{\n   if (png_ptr == NULL)\n      return;\n\n   switch (png_ptr->process_mode)\n   {\n      case PNG_READ_SIG_MODE:\n      {\n         png_push_read_sig(png_ptr, info_ptr);\n         break;\n      }\n\n      case PNG_READ_CHUNK_MODE:\n      {\n         png_push_read_chunk(png_ptr, info_ptr);\n         break;\n      }\n\n      case PNG_READ_IDAT_MODE:\n      {\n         png_push_read_IDAT(png_ptr);\n         break;\n      }\n\n      default:\n      {\n         png_ptr->buffer_size = 0;\n         break;\n      }\n   }\n}\n\n/* Read any remaining signature bytes from the stream and compare them with\n * the correct PNG signature.  It is possible that this routine is called\n * with bytes already read from the signature, either because they have been\n * checked by the calling application, or because of multiple calls to this\n * routine.\n */\nvoid /* PRIVATE */\npng_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)\n{\n   png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */\n       num_to_check = 8 - num_checked;\n\n   if (png_ptr->buffer_size < num_to_check)\n   {\n      num_to_check = png_ptr->buffer_size;\n   }\n\n   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),\n       num_to_check);\n   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);\n\n   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))\n   {\n      if (num_checked < 4 &&\n          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))\n         png_error(png_ptr, \"Not a PNG file\");\n\n      else\n         png_error(png_ptr, \"PNG file corrupted by ASCII conversion\");\n   }\n   else\n   {\n      if (png_ptr->sig_bytes >= 8)\n      {\n         png_ptr->process_mode = PNG_READ_CHUNK_MODE;\n      }\n   }\n}\n\nvoid /* PRIVATE */\npng_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)\n{\n   png_uint_32 chunk_name;\n#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED\n   int keep; /* unknown handling method */\n#endif\n\n   /* First we make sure we have enough data for the 4-byte chunk name\n    * and the 4-byte chunk length before proceeding with decoding the\n    * chunk data.  To fully decode each of these chunks, we also make\n    * sure we have enough data in the buffer for the 4-byte CRC at the\n    * end of every chunk (except IDAT, which is handled separately).\n    */\n   if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)\n   {\n      png_byte chunk_length[4];\n      png_byte chunk_tag[4];\n\n      PNG_PUSH_SAVE_BUFFER_IF_LT(8)\n      png_push_fill_buffer(png_ptr, chunk_length, 4);\n      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);\n      png_reset_crc(png_ptr);\n      png_crc_read(png_ptr, chunk_tag, 4);\n      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);\n      png_check_chunk_name(png_ptr, png_ptr->chunk_name);\n      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;\n   }\n\n   chunk_name = png_ptr->chunk_name;\n\n   if (chunk_name == png_IDAT)\n   {\n      if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)\n         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;\n\n      /* If we reach an IDAT chunk, this means we have read all of the\n       * header chunks, and we can start reading the image (or if this\n       * is called after the image has been read - we have an error).\n       */\n      if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n         png_error(png_ptr, \"Missing IHDR before IDAT\");\n\n      else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&\n          (png_ptr->mode & PNG_HAVE_PLTE) == 0)\n         png_error(png_ptr, \"Missing PLTE before IDAT\");\n\n      png_ptr->mode |= PNG_HAVE_IDAT;\n      png_ptr->process_mode = PNG_READ_IDAT_MODE;\n\n      if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)\n         if (png_ptr->push_length == 0)\n            return;\n\n      if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)\n         png_benign_error(png_ptr, \"Too many IDATs found\");\n   }\n\n   if (chunk_name == png_IHDR)\n   {\n      if (png_ptr->push_length != 13)\n         png_error(png_ptr, \"Invalid IHDR length\");\n\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n   else if (chunk_name == png_IEND)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);\n\n      png_ptr->process_mode = PNG_READ_DONE_MODE;\n      png_push_have_end(png_ptr, info_ptr);\n   }\n\n#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED\n   else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep);\n\n      if (chunk_name == png_PLTE)\n         png_ptr->mode |= PNG_HAVE_PLTE;\n   }\n#endif\n\n   else if (chunk_name == png_PLTE)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n   else if (chunk_name == png_IDAT)\n   {\n      png_ptr->idat_size = png_ptr->push_length;\n      png_ptr->process_mode = PNG_READ_IDAT_MODE;\n      png_push_have_info(png_ptr, info_ptr);\n      png_ptr->zstream.avail_out =\n          (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,\n          png_ptr->iwidth) + 1;\n      png_ptr->zstream.next_out = png_ptr->row_buf;\n      return;\n   }\n\n#ifdef PNG_READ_gAMA_SUPPORTED\n   else if (png_ptr->chunk_name == png_gAMA)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_sBIT_SUPPORTED\n   else if (png_ptr->chunk_name == png_sBIT)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_cHRM_SUPPORTED\n   else if (png_ptr->chunk_name == png_cHRM)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_sRGB_SUPPORTED\n   else if (chunk_name == png_sRGB)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_iCCP_SUPPORTED\n   else if (png_ptr->chunk_name == png_iCCP)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_sPLT_SUPPORTED\n   else if (chunk_name == png_sPLT)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_tRNS_SUPPORTED\n   else if (chunk_name == png_tRNS)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_bKGD_SUPPORTED\n   else if (chunk_name == png_bKGD)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_hIST_SUPPORTED\n   else if (chunk_name == png_hIST)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_pHYs_SUPPORTED\n   else if (chunk_name == png_pHYs)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_oFFs_SUPPORTED\n   else if (chunk_name == png_oFFs)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);\n   }\n#endif\n\n#ifdef PNG_READ_pCAL_SUPPORTED\n   else if (chunk_name == png_pCAL)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_sCAL_SUPPORTED\n   else if (chunk_name == png_sCAL)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_tIME_SUPPORTED\n   else if (chunk_name == png_tIME)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_tEXt_SUPPORTED\n   else if (chunk_name == png_tEXt)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_zTXt_SUPPORTED\n   else if (chunk_name == png_zTXt)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);\n   }\n\n#endif\n#ifdef PNG_READ_iTXt_SUPPORTED\n   else if (chunk_name == png_iTXt)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);\n   }\n#endif\n\n   else\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_FULL\n      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,\n         PNG_HANDLE_CHUNK_AS_DEFAULT);\n   }\n\n   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;\n}\n\nvoid PNGCBAPI\npng_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)\n{\n   png_bytep ptr;\n\n   if (png_ptr == NULL)\n      return;\n\n   ptr = buffer;\n   if (png_ptr->save_buffer_size != 0)\n   {\n      png_size_t save_size;\n\n      if (length < png_ptr->save_buffer_size)\n         save_size = length;\n\n      else\n         save_size = png_ptr->save_buffer_size;\n\n      memcpy(ptr, png_ptr->save_buffer_ptr, save_size);\n      length -= save_size;\n      ptr += save_size;\n      png_ptr->buffer_size -= save_size;\n      png_ptr->save_buffer_size -= save_size;\n      png_ptr->save_buffer_ptr += save_size;\n   }\n   if (length != 0 && png_ptr->current_buffer_size != 0)\n   {\n      png_size_t save_size;\n\n      if (length < png_ptr->current_buffer_size)\n         save_size = length;\n\n      else\n         save_size = png_ptr->current_buffer_size;\n\n      memcpy(ptr, png_ptr->current_buffer_ptr, save_size);\n      png_ptr->buffer_size -= save_size;\n      png_ptr->current_buffer_size -= save_size;\n      png_ptr->current_buffer_ptr += save_size;\n   }\n}\n\nvoid /* PRIVATE */\npng_push_save_buffer(png_structrp png_ptr)\n{\n   if (png_ptr->save_buffer_size != 0)\n   {\n      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)\n      {\n         png_size_t i, istop;\n         png_bytep sp;\n         png_bytep dp;\n\n         istop = png_ptr->save_buffer_size;\n         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;\n             i < istop; i++, sp++, dp++)\n         {\n            *dp = *sp;\n         }\n      }\n   }\n   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >\n       png_ptr->save_buffer_max)\n   {\n      png_size_t new_max;\n      png_bytep old_buffer;\n\n      if (png_ptr->save_buffer_size > PNG_SIZE_MAX -\n          (png_ptr->current_buffer_size + 256))\n      {\n         png_error(png_ptr, \"Potential overflow of save_buffer\");\n      }\n\n      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;\n      old_buffer = png_ptr->save_buffer;\n      png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,\n          (png_size_t)new_max);\n\n      if (png_ptr->save_buffer == NULL)\n      {\n         png_free(png_ptr, old_buffer);\n         png_error(png_ptr, \"Insufficient memory for save_buffer\");\n      }\n\n      memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);\n      png_free(png_ptr, old_buffer);\n      png_ptr->save_buffer_max = new_max;\n   }\n   if (png_ptr->current_buffer_size)\n   {\n      memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,\n         png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);\n      png_ptr->save_buffer_size += png_ptr->current_buffer_size;\n      png_ptr->current_buffer_size = 0;\n   }\n   png_ptr->save_buffer_ptr = png_ptr->save_buffer;\n   png_ptr->buffer_size = 0;\n}\n\nvoid /* PRIVATE */\npng_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,\n   png_size_t buffer_length)\n{\n   png_ptr->current_buffer = buffer;\n   png_ptr->current_buffer_size = buffer_length;\n   png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;\n   png_ptr->current_buffer_ptr = png_ptr->current_buffer;\n}\n\nvoid /* PRIVATE */\npng_push_read_IDAT(png_structrp png_ptr)\n{\n   if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)\n   {\n      png_byte chunk_length[4];\n      png_byte chunk_tag[4];\n\n      /* TODO: this code can be commoned up with the same code in push_read */\n      PNG_PUSH_SAVE_BUFFER_IF_LT(8)\n      png_push_fill_buffer(png_ptr, chunk_length, 4);\n      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);\n      png_reset_crc(png_ptr);\n      png_crc_read(png_ptr, chunk_tag, 4);\n      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);\n      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;\n\n      if (png_ptr->chunk_name != png_IDAT)\n      {\n         png_ptr->process_mode = PNG_READ_CHUNK_MODE;\n\n         if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)\n            png_error(png_ptr, \"Not enough compressed data\");\n\n         return;\n      }\n\n      png_ptr->idat_size = png_ptr->push_length;\n   }\n\n   if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)\n   {\n      png_size_t save_size = png_ptr->save_buffer_size;\n      png_uint_32 idat_size = png_ptr->idat_size;\n\n      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they\n       * are of different types and we don't know which variable has the fewest\n       * bits.  Carefully select the smaller and cast it to the type of the\n       * larger - this cannot overflow.  Do not cast in the following test - it\n       * will break on either 16-bit or 64-bit platforms.\n       */\n      if (idat_size < save_size)\n         save_size = (png_size_t)idat_size;\n\n      else\n         idat_size = (png_uint_32)save_size;\n\n      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);\n\n      png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);\n\n      png_ptr->idat_size -= idat_size;\n      png_ptr->buffer_size -= save_size;\n      png_ptr->save_buffer_size -= save_size;\n      png_ptr->save_buffer_ptr += save_size;\n   }\n\n   if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0)\n   {\n      png_size_t save_size = png_ptr->current_buffer_size;\n      png_uint_32 idat_size = png_ptr->idat_size;\n\n      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they\n       * are of different types and we don't know which variable has the fewest\n       * bits.  Carefully select the smaller and cast it to the type of the\n       * larger - this cannot overflow.\n       */\n      if (idat_size < save_size)\n         save_size = (png_size_t)idat_size;\n\n      else\n         idat_size = (png_uint_32)save_size;\n\n      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);\n\n      png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);\n\n      png_ptr->idat_size -= idat_size;\n      png_ptr->buffer_size -= save_size;\n      png_ptr->current_buffer_size -= save_size;\n      png_ptr->current_buffer_ptr += save_size;\n   }\n\n   if (png_ptr->idat_size == 0)\n   {\n      PNG_PUSH_SAVE_BUFFER_IF_LT(4)\n      png_crc_finish(png_ptr, 0);\n      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;\n      png_ptr->mode |= PNG_AFTER_IDAT;\n      png_ptr->zowner = 0;\n   }\n}\n\nvoid /* PRIVATE */\npng_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,\n   png_size_t buffer_length)\n{\n   /* The caller checks for a non-zero buffer length. */\n   if (!(buffer_length > 0) || buffer == NULL)\n      png_error(png_ptr, \"No IDAT data (internal error)\");\n\n   /* This routine must process all the data it has been given\n    * before returning, calling the row callback as required to\n    * handle the uncompressed results.\n    */\n   png_ptr->zstream.next_in = buffer;\n   /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */\n   png_ptr->zstream.avail_in = (uInt)buffer_length;\n\n   /* Keep going until the decompressed data is all processed\n    * or the stream marked as finished.\n    */\n   while (png_ptr->zstream.avail_in > 0 &&\n      (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)\n   {\n      int ret;\n\n      /* We have data for zlib, but we must check that zlib\n       * has someplace to put the results.  It doesn't matter\n       * if we don't expect any results -- it may be the input\n       * data is just the LZ end code.\n       */\n      if (!(png_ptr->zstream.avail_out > 0))\n      {\n         /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */\n         png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,\n             png_ptr->iwidth) + 1);\n\n         png_ptr->zstream.next_out = png_ptr->row_buf;\n      }\n\n      /* Using Z_SYNC_FLUSH here means that an unterminated\n       * LZ stream (a stream with a missing end code) can still\n       * be handled, otherwise (Z_NO_FLUSH) a future zlib\n       * implementation might defer output and therefore\n       * change the current behavior (see comments in inflate.c\n       * for why this doesn't happen at present with zlib 1.2.5).\n       */\n      ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH);\n\n      /* Check for any failure before proceeding. */\n      if (ret != Z_OK && ret != Z_STREAM_END)\n      {\n         /* Terminate the decompression. */\n         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;\n         png_ptr->zowner = 0;\n\n         /* This may be a truncated stream (missing or\n          * damaged end code).  Treat that as a warning.\n          */\n         if (png_ptr->row_number >= png_ptr->num_rows ||\n             png_ptr->pass > 6)\n            png_warning(png_ptr, \"Truncated compressed data in IDAT\");\n\n         else\n            png_error(png_ptr, \"Decompression error in IDAT\");\n\n         /* Skip the check on unprocessed input */\n         return;\n      }\n\n      /* Did inflate output any data? */\n      if (png_ptr->zstream.next_out != png_ptr->row_buf)\n      {\n         /* Is this unexpected data after the last row?\n          * If it is, artificially terminate the LZ output\n          * here.\n          */\n         if (png_ptr->row_number >= png_ptr->num_rows ||\n             png_ptr->pass > 6)\n         {\n            /* Extra data. */\n            png_warning(png_ptr, \"Extra compressed data in IDAT\");\n            png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;\n            png_ptr->zowner = 0;\n\n            /* Do no more processing; skip the unprocessed\n             * input check below.\n             */\n            return;\n         }\n\n         /* Do we have a complete row? */\n         if (png_ptr->zstream.avail_out == 0)\n            png_push_process_row(png_ptr);\n      }\n\n      /* And check for the end of the stream. */\n      if (ret == Z_STREAM_END)\n         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;\n   }\n\n   /* All the data should have been processed, if anything\n    * is left at this point we have bytes of IDAT data\n    * after the zlib end code.\n    */\n   if (png_ptr->zstream.avail_in > 0)\n      png_warning(png_ptr, \"Extra compression data in IDAT\");\n}\n\nvoid /* PRIVATE */\npng_push_process_row(png_structrp png_ptr)\n{\n   /* 1.5.6: row_info moved out of png_struct to a local here. */\n   png_row_info row_info;\n\n   row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */\n   row_info.color_type = png_ptr->color_type;\n   row_info.bit_depth = png_ptr->bit_depth;\n   row_info.channels = png_ptr->channels;\n   row_info.pixel_depth = png_ptr->pixel_depth;\n   row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);\n\n   if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)\n   {\n      if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)\n         png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,\n            png_ptr->prev_row + 1, png_ptr->row_buf[0]);\n      else\n         png_error(png_ptr, \"bad adaptive filter value\");\n   }\n\n   /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before\n    * 1.5.6, while the buffer really is this big in current versions of libpng\n    * it may not be in the future, so this was changed just to copy the\n    * interlaced row count:\n    */\n   memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\n   if (png_ptr->transformations != 0)\n      png_do_read_transformations(png_ptr, &row_info);\n#endif\n\n   /* The transformed pixel depth should match the depth now in row_info. */\n   if (png_ptr->transformed_pixel_depth == 0)\n   {\n      png_ptr->transformed_pixel_depth = row_info.pixel_depth;\n      if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)\n         png_error(png_ptr, \"progressive row overflow\");\n   }\n\n   else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)\n      png_error(png_ptr, \"internal progressive row size calculation error\");\n\n\n#ifdef PNG_READ_INTERLACING_SUPPORTED\n   /* Expand interlaced rows to full size */\n   if (png_ptr->interlaced != 0 &&\n       (png_ptr->transformations & PNG_INTERLACE) != 0)\n   {\n      if (png_ptr->pass < 6)\n         png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,\n            png_ptr->transformations);\n\n      switch (png_ptr->pass)\n      {\n         case 0:\n         {\n            int i;\n            for (i = 0; i < 8 && png_ptr->pass == 0; i++)\n            {\n               png_push_have_row(png_ptr, png_ptr->row_buf + 1);\n               png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */\n            }\n\n            if (png_ptr->pass == 2) /* Pass 1 might be empty */\n            {\n               for (i = 0; i < 4 && png_ptr->pass == 2; i++)\n               {\n                  png_push_have_row(png_ptr, NULL);\n                  png_read_push_finish_row(png_ptr);\n               }\n            }\n\n            if (png_ptr->pass == 4 && png_ptr->height <= 4)\n            {\n               for (i = 0; i < 2 && png_ptr->pass == 4; i++)\n               {\n                  png_push_have_row(png_ptr, NULL);\n                  png_read_push_finish_row(png_ptr);\n               }\n            }\n\n            if (png_ptr->pass == 6 && png_ptr->height <= 4)\n            {\n                png_push_have_row(png_ptr, NULL);\n                png_read_push_finish_row(png_ptr);\n            }\n\n            break;\n         }\n\n         case 1:\n         {\n            int i;\n            for (i = 0; i < 8 && png_ptr->pass == 1; i++)\n            {\n               png_push_have_row(png_ptr, png_ptr->row_buf + 1);\n               png_read_push_finish_row(png_ptr);\n            }\n\n            if (png_ptr->pass == 2) /* Skip top 4 generated rows */\n            {\n               for (i = 0; i < 4 && png_ptr->pass == 2; i++)\n               {\n                  png_push_have_row(png_ptr, NULL);\n                  png_read_push_finish_row(png_ptr);\n               }\n            }\n\n            break;\n         }\n\n         case 2:\n         {\n            int i;\n\n            for (i = 0; i < 4 && png_ptr->pass == 2; i++)\n            {\n               png_push_have_row(png_ptr, png_ptr->row_buf + 1);\n               png_read_push_finish_row(png_ptr);\n            }\n\n            for (i = 0; i < 4 && png_ptr->pass == 2; i++)\n            {\n               png_push_have_row(png_ptr, NULL);\n               png_read_push_finish_row(png_ptr);\n            }\n\n            if (png_ptr->pass == 4) /* Pass 3 might be empty */\n            {\n               for (i = 0; i < 2 && png_ptr->pass == 4; i++)\n               {\n                  png_push_have_row(png_ptr, NULL);\n                  png_read_push_finish_row(png_ptr);\n               }\n            }\n\n            break;\n         }\n\n         case 3:\n         {\n            int i;\n\n            for (i = 0; i < 4 && png_ptr->pass == 3; i++)\n            {\n               png_push_have_row(png_ptr, png_ptr->row_buf + 1);\n               png_read_push_finish_row(png_ptr);\n            }\n\n            if (png_ptr->pass == 4) /* Skip top two generated rows */\n            {\n               for (i = 0; i < 2 && png_ptr->pass == 4; i++)\n               {\n                  png_push_have_row(png_ptr, NULL);\n                  png_read_push_finish_row(png_ptr);\n               }\n            }\n\n            break;\n         }\n\n         case 4:\n         {\n            int i;\n\n            for (i = 0; i < 2 && png_ptr->pass == 4; i++)\n            {\n               png_push_have_row(png_ptr, png_ptr->row_buf + 1);\n               png_read_push_finish_row(png_ptr);\n            }\n\n            for (i = 0; i < 2 && png_ptr->pass == 4; i++)\n            {\n               png_push_have_row(png_ptr, NULL);\n               png_read_push_finish_row(png_ptr);\n            }\n\n            if (png_ptr->pass == 6) /* Pass 5 might be empty */\n            {\n               png_push_have_row(png_ptr, NULL);\n               png_read_push_finish_row(png_ptr);\n            }\n\n            break;\n         }\n\n         case 5:\n         {\n            int i;\n\n            for (i = 0; i < 2 && png_ptr->pass == 5; i++)\n            {\n               png_push_have_row(png_ptr, png_ptr->row_buf + 1);\n               png_read_push_finish_row(png_ptr);\n            }\n\n            if (png_ptr->pass == 6) /* Skip top generated row */\n            {\n               png_push_have_row(png_ptr, NULL);\n               png_read_push_finish_row(png_ptr);\n            }\n\n            break;\n         }\n\n         default:\n         case 6:\n         {\n            png_push_have_row(png_ptr, png_ptr->row_buf + 1);\n            png_read_push_finish_row(png_ptr);\n\n            if (png_ptr->pass != 6)\n               break;\n\n            png_push_have_row(png_ptr, NULL);\n            png_read_push_finish_row(png_ptr);\n         }\n      }\n   }\n   else\n#endif\n   {\n      png_push_have_row(png_ptr, png_ptr->row_buf + 1);\n      png_read_push_finish_row(png_ptr);\n   }\n}\n\nvoid /* PRIVATE */\npng_read_push_finish_row(png_structrp png_ptr)\n{\n#ifdef PNG_READ_INTERLACING_SUPPORTED\n   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */\n\n   /* Start of interlace block */\n   static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};\n\n   /* Offset to next interlace block */\n   static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};\n\n   /* Start of interlace block in the y direction */\n   static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};\n\n   /* Offset to next interlace block in the y direction */\n   static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};\n\n   /* Height of interlace block.  This is not currently used - if you need\n    * it, uncomment it here and in png.h\n   static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};\n   */\n#endif\n\n   png_ptr->row_number++;\n   if (png_ptr->row_number < png_ptr->num_rows)\n      return;\n\n#ifdef PNG_READ_INTERLACING_SUPPORTED\n   if (png_ptr->interlaced != 0)\n   {\n      png_ptr->row_number = 0;\n      memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);\n\n      do\n      {\n         png_ptr->pass++;\n         if ((png_ptr->pass == 1 && png_ptr->width < 5) ||\n             (png_ptr->pass == 3 && png_ptr->width < 3) ||\n             (png_ptr->pass == 5 && png_ptr->width < 2))\n            png_ptr->pass++;\n\n         if (png_ptr->pass > 7)\n            png_ptr->pass--;\n\n         if (png_ptr->pass >= 7)\n            break;\n\n         png_ptr->iwidth = (png_ptr->width +\n             png_pass_inc[png_ptr->pass] - 1 -\n             png_pass_start[png_ptr->pass]) /\n             png_pass_inc[png_ptr->pass];\n\n         if ((png_ptr->transformations & PNG_INTERLACE) != 0)\n            break;\n\n         png_ptr->num_rows = (png_ptr->height +\n             png_pass_yinc[png_ptr->pass] - 1 -\n             png_pass_ystart[png_ptr->pass]) /\n             png_pass_yinc[png_ptr->pass];\n\n      } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);\n   }\n#endif /* READ_INTERLACING */\n}\n\nvoid /* PRIVATE */\npng_push_have_info(png_structrp png_ptr, png_inforp info_ptr)\n{\n   if (png_ptr->info_fn != NULL)\n      (*(png_ptr->info_fn))(png_ptr, info_ptr);\n}\n\nvoid /* PRIVATE */\npng_push_have_end(png_structrp png_ptr, png_inforp info_ptr)\n{\n   if (png_ptr->end_fn != NULL)\n      (*(png_ptr->end_fn))(png_ptr, info_ptr);\n}\n\nvoid /* PRIVATE */\npng_push_have_row(png_structrp png_ptr, png_bytep row)\n{\n   if (png_ptr->row_fn != NULL)\n      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,\n         (int)png_ptr->pass);\n}\n\n#ifdef PNG_READ_INTERLACING_SUPPORTED\nvoid PNGAPI\npng_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row,\n    png_const_bytep new_row)\n{\n   if (png_ptr == NULL)\n      return;\n\n   /* new_row is a flag here - if it is NULL then the app callback was called\n    * from an empty row (see the calls to png_struct::row_fn below), otherwise\n    * it must be png_ptr->row_buf+1\n    */\n   if (new_row != NULL)\n      png_combine_row(png_ptr, old_row, 1/*blocky display*/);\n}\n#endif /* READ_INTERLACING */\n\nvoid PNGAPI\npng_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr,\n    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,\n    png_progressive_end_ptr end_fn)\n{\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->info_fn = info_fn;\n   png_ptr->row_fn = row_fn;\n   png_ptr->end_fn = end_fn;\n\n   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);\n}\n\npng_voidp PNGAPI\npng_get_progressive_ptr(png_const_structrp png_ptr)\n{\n   if (png_ptr == NULL)\n      return (NULL);\n\n   return png_ptr->io_ptr;\n}\n#endif /* PROGRESSIVE_READ */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngpriv.h",
    "content": "\n/* pngpriv.h - private declarations for use inside libpng\n *\n * Last changed in libpng 1.6.21 [(PENDING RELEASE)]\n * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n/* The symbols declared in this file (including the functions declared\n * as extern) are PRIVATE.  They are not part of the libpng public\n * interface, and are not recommended for use by regular applications.\n * Some of them may become public in the future; others may stay private,\n * change in an incompatible way, or even disappear.\n * Although the libpng users are not forbidden to include this header,\n * they should be well aware of the issues that may arise from doing so.\n */\n\n#ifndef PNGPRIV_H\n#define PNGPRIV_H\n\n/* Feature Test Macros.  The following are defined here to ensure that correctly\n * implemented libraries reveal the APIs libpng needs to build and hide those\n * that are not needed and potentially damaging to the compilation.\n *\n * Feature Test Macros must be defined before any system header is included (see\n * POSIX 1003.1 2.8.2 \"POSIX Symbols.\"\n *\n * These macros only have an effect if the operating system supports either\n * POSIX 1003.1 or C99, or both.  On other operating systems (particularly\n * Windows/Visual Studio) there is no effect; the OS specific tests below are\n * still required (as of 2011-05-02.)\n */\n#define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */\n\n#ifndef PNG_VERSION_INFO_ONLY\n/* Standard library headers not required by png.h: */\n#  include <stdlib.h>\n#  include <string.h>\n#endif\n\n#define PNGLIB_BUILD /*libpng is being built, not used*/\n\n/* If HAVE_CONFIG_H is defined during the build then the build system must\n * provide an appropriate \"config.h\" file on the include path.  The header file\n * must provide definitions as required below (search for \"HAVE_CONFIG_H\");\n * see configure.ac for more details of the requirements.  The macro\n * \"PNG_NO_CONFIG_H\" is provided for maintainers to test for dependencies on\n * 'configure'; define this macro to prevent the configure build including the\n * configure generated config.h.  Libpng is expected to compile without *any*\n * special build system support on a reasonably ANSI-C compliant system.\n */\n#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)\n#  include <config.h>\n\n   /* Pick up the definition of 'restrict' from config.h if it was read: */\n#  define PNG_RESTRICT restrict\n#endif\n\n/* To support symbol prefixing it is necessary to know *before* including png.h\n * whether the fixed point (and maybe other) APIs are exported, because if they\n * are not internal definitions may be required.  This is handled below just\n * before png.h is included, but load the configuration now if it is available.\n */\n#ifndef PNGLCONF_H\n#  include \"pnglibconf.h\"\n#endif\n\n/* Local renames may change non-exported API functions from png.h */\n#if defined(PNG_PREFIX) && !defined(PNGPREFIX_H)\n#  include \"pngprefix.h\"\n#endif\n\n#ifdef PNG_USER_CONFIG\n#  include \"pngusr.h\"\n   /* These should have been defined in pngusr.h */\n#  ifndef PNG_USER_PRIVATEBUILD\n#    define PNG_USER_PRIVATEBUILD \"Custom libpng build\"\n#  endif\n#  ifndef PNG_USER_DLLFNAME_POSTFIX\n#    define PNG_USER_DLLFNAME_POSTFIX \"Cb\"\n#  endif\n#endif\n\n/* Compile time options.\n * =====================\n * In a multi-arch build the compiler may compile the code several times for the\n * same object module, producing different binaries for different architectures.\n * When this happens configure-time setting of the target host options cannot be\n * done and this interferes with the handling of the ARM NEON optimizations, and\n * possibly other similar optimizations.  Put additional tests here; in general\n * this is needed when the same option can be changed at both compile time and\n * run time depending on the target OS (i.e. iOS vs Android.)\n *\n * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because\n * this is not possible with certain compilers (Oracle SUN OS CC), as a result\n * it is necessary to ensure that all extern functions that *might* be used\n * regardless of $(CFLAGS) get declared in this file.  The test on __ARM_NEON__\n * below is one example of this behavior because it is controlled by the\n * presence or not of -mfpu=neon on the GCC command line, it is possible to do\n * this in $(CC), e.g. \"CC=gcc -mfpu=neon\", but people who build libpng rarely\n * do this.\n */\n#ifndef PNG_ARM_NEON_OPT\n   /* ARM NEON optimizations are being controlled by the compiler settings,\n    * typically the target FPU.  If the FPU has been set to NEON (-mfpu=neon\n    * with GCC) then the compiler will define __ARM_NEON__ and we can rely\n    * unconditionally on NEON instructions not crashing, otherwise we must\n    * disable use of NEON instructions.\n    *\n    * NOTE: at present these optimizations depend on 'ALIGNED_MEMORY', so they\n    * can only be turned on automatically if that is supported too.  If\n    * PNG_ARM_NEON_OPT is set in CPPFLAGS (to >0) then arm/arm_init.c will fail\n    * to compile with an appropriate #error if ALIGNED_MEMORY has been turned\n    * off.\n    *\n    * Note that gcc-4.9 defines __ARM_NEON instead of the deprecated\n    * __ARM_NEON__, so we check both variants.\n    *\n    * To disable ARM_NEON optimizations entirely, and skip compiling the\n    * associated assembler code, pass --enable-arm-neon=no to configure\n    * or put -DPNG_ARM_NEON_OPT=0 in CPPFLAGS.\n    */\n#  if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \\\n   defined(PNG_ALIGNED_MEMORY_SUPPORTED)\n#     define PNG_ARM_NEON_OPT 2\n#  else\n#     define PNG_ARM_NEON_OPT 0\n#  endif\n#endif\n\n#if PNG_ARM_NEON_OPT > 0\n   /* NEON optimizations are to be at least considered by libpng, so enable the\n    * callbacks to do this.\n    */\n#  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon\n\n   /* By default the 'intrinsics' code in arm/filter_neon_intrinsics.c is used\n    * if possible - if __ARM_NEON__ is set and the compiler version is not known\n    * to be broken.  This is controlled by PNG_ARM_NEON_IMPLEMENTATION which can\n    * be:\n    *\n    *    1  The intrinsics code (the default with __ARM_NEON__)\n    *    2  The hand coded assembler (the default without __ARM_NEON__)\n    *\n    * It is possible to set PNG_ARM_NEON_IMPLEMENTATION in CPPFLAGS, however\n    * this is *NOT* supported and may cease to work even after a minor revision\n    * to libpng.  It *is* valid to do this for testing purposes, e.g. speed\n    * testing or a new compiler, but the results should be communicated to the\n    * libpng implementation list for incorporation in the next minor release.\n    */\n#  ifndef PNG_ARM_NEON_IMPLEMENTATION\n#     if defined(__ARM_NEON__) || defined(__ARM_NEON)\n#        if defined(__clang__)\n            /* At present it is unknown by the libpng developers which versions\n             * of clang support the intrinsics, however some or perhaps all\n             * versions do not work with the assembler so this may be\n             * irrelevant, so just use the default (do nothing here.)\n             */\n#        elif defined(__GNUC__)\n            /* GCC 4.5.4 NEON support is known to be broken.  4.6.3 is known to\n             * work, so if this *is* GCC, or G++, look for a version >4.5\n             */\n#           if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)\n#              define PNG_ARM_NEON_IMPLEMENTATION 2\n#           endif /* no GNUC support */\n#        endif /* __GNUC__ */\n#     else /* !defined __ARM_NEON__ */\n         /* The 'intrinsics' code simply won't compile without this -mfpu=neon:\n          */\n#        define PNG_ARM_NEON_IMPLEMENTATION 2\n#     endif /* __ARM_NEON__ */\n#  endif /* !PNG_ARM_NEON_IMPLEMENTATION */\n\n#  ifndef PNG_ARM_NEON_IMPLEMENTATION\n      /* Use the intrinsics code by default. */\n#     define PNG_ARM_NEON_IMPLEMENTATION 1\n#  endif\n#endif /* PNG_ARM_NEON_OPT > 0 */\n\n#ifndef PNG_INTEL_SSE_OPT\n#   ifdef PNG_INTEL_SSE\n      /* Only check for SSE if the build configuration has been modified to\n       * enable SSE optimizations.  This means that these optimizations will\n       * be off by default.  See contrib/intel for more details.\n       */\n#     if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \\\n       defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \\\n       (defined(_M_IX86_FP) && _M_IX86_FP >= 2)\n#         define PNG_INTEL_SSE_OPT 1\n#      endif\n#   endif\n#endif\n\n#if PNG_INTEL_SSE_OPT > 0\n#   ifndef PNG_INTEL_SSE_IMPLEMENTATION\n#      if defined(__SSE4_1__) || defined(__AVX__)\n          /* We are not actually using AVX, but checking for AVX is the best\n             way we can detect SSE4.1 and SSSE3 on MSVC.\n          */\n#         define PNG_INTEL_SSE_IMPLEMENTATION 3\n#      elif defined(__SSSE3__)\n#         define PNG_INTEL_SSE_IMPLEMENTATION 2\n#      elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \\\n       (defined(_M_IX86_FP) && _M_IX86_FP >= 2)\n#         define PNG_INTEL_SSE_IMPLEMENTATION 1\n#      else\n#         define PNG_INTEL_SSE_IMPLEMENTATION 0\n#      endif\n#   endif\n\n#   if PNG_INTEL_SSE_IMPLEMENTATION > 0\n#      define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2\n#   endif\n#endif\n\n/* Is this a build of a DLL where compilation of the object modules requires\n * different preprocessor settings to those required for a simple library?  If\n * so PNG_BUILD_DLL must be set.\n *\n * If libpng is used inside a DLL but that DLL does not export the libpng APIs\n * PNG_BUILD_DLL must not be set.  To avoid the code below kicking in build a\n * static library of libpng then link the DLL against that.\n */\n#ifndef PNG_BUILD_DLL\n#  ifdef DLL_EXPORT\n      /* This is set by libtool when files are compiled for a DLL; libtool\n       * always compiles twice, even on systems where it isn't necessary.  Set\n       * PNG_BUILD_DLL in case it is necessary:\n       */\n#     define PNG_BUILD_DLL\n#  else\n#     ifdef _WINDLL\n         /* This is set by the Microsoft Visual Studio IDE in projects that\n          * build a DLL.  It can't easily be removed from those projects (it\n          * isn't visible in the Visual Studio UI) so it is a fairly reliable\n          * indication that PNG_IMPEXP needs to be set to the DLL export\n          * attributes.\n          */\n#        define PNG_BUILD_DLL\n#     else\n#        ifdef __DLL__\n            /* This is set by the Borland C system when compiling for a DLL\n             * (as above.)\n             */\n#           define PNG_BUILD_DLL\n#        else\n            /* Add additional compiler cases here. */\n#        endif\n#     endif\n#  endif\n#endif /* Setting PNG_BUILD_DLL if required */\n\n/* See pngconf.h for more details: the builder of the library may set this on\n * the command line to the right thing for the specific compilation system or it\n * may be automagically set above (at present we know of no system where it does\n * need to be set on the command line.)\n *\n * PNG_IMPEXP must be set here when building the library to prevent pngconf.h\n * setting it to the \"import\" setting for a DLL build.\n */\n#ifndef PNG_IMPEXP\n#  ifdef PNG_BUILD_DLL\n#     define PNG_IMPEXP PNG_DLL_EXPORT\n#  else\n      /* Not building a DLL, or the DLL doesn't require specific export\n       * definitions.\n       */\n#     define PNG_IMPEXP\n#  endif\n#endif\n\n/* No warnings for private or deprecated functions in the build: */\n#ifndef PNG_DEPRECATED\n#  define PNG_DEPRECATED\n#endif\n#ifndef PNG_PRIVATE\n#  define PNG_PRIVATE\n#endif\n\n/* Symbol preprocessing support.\n *\n * To enable listing global, but internal, symbols the following macros should\n * always be used to declare an extern data or function object in this file.\n */\n#ifndef PNG_INTERNAL_DATA\n#  define PNG_INTERNAL_DATA(type, name, array) PNG_LINKAGE_DATA type name array\n#endif\n\n#ifndef PNG_INTERNAL_FUNCTION\n#  define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\\\n      PNG_LINKAGE_FUNCTION PNG_FUNCTION(type, name, args, PNG_EMPTY attributes)\n#endif\n\n#ifndef PNG_INTERNAL_CALLBACK\n#  define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\\\n      PNG_LINKAGE_CALLBACK PNG_FUNCTION(type, (PNGCBAPI name), args,\\\n         PNG_EMPTY attributes)\n#endif\n\n/* If floating or fixed point APIs are disabled they may still be compiled\n * internally.  To handle this make sure they are declared as the appropriate\n * internal extern function (otherwise the symbol prefixing stuff won't work and\n * the functions will be used without definitions.)\n *\n * NOTE: although all the API functions are declared here they are not all\n * actually built!  Because the declarations are still made it is necessary to\n * fake out types that they depend on.\n */\n#ifndef PNG_FP_EXPORT\n#  ifndef PNG_FLOATING_POINT_SUPPORTED\n#     define PNG_FP_EXPORT(ordinal, type, name, args)\\\n         PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY);\n#     ifndef PNG_VERSION_INFO_ONLY\n         typedef struct png_incomplete png_double;\n         typedef png_double*           png_doublep;\n         typedef const png_double*     png_const_doublep;\n         typedef png_double**          png_doublepp;\n#     endif\n#  endif\n#endif\n#ifndef PNG_FIXED_EXPORT\n#  ifndef PNG_FIXED_POINT_SUPPORTED\n#     define PNG_FIXED_EXPORT(ordinal, type, name, args)\\\n         PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY);\n#  endif\n#endif\n\n#include \"png.h\"\n\n/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */\n#ifndef PNG_DLL_EXPORT\n#  define PNG_DLL_EXPORT\n#endif\n\n/* This is a global switch to set the compilation for an installed system\n * (a release build).  It can be set for testing debug builds to ensure that\n * they will compile when the build type is switched to RC or STABLE, the\n * default is just to use PNG_LIBPNG_BUILD_BASE_TYPE.  Set this in CPPFLAGS\n * with either:\n *\n *   -DPNG_RELEASE_BUILD Turns on the release compile path\n *   -DPNG_RELEASE_BUILD=0 Turns it off\n * or in your pngusr.h with\n *   #define PNG_RELEASE_BUILD=1 Turns on the release compile path\n *   #define PNG_RELEASE_BUILD=0 Turns it off\n */\n#ifndef PNG_RELEASE_BUILD\n#  define PNG_RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC)\n#endif\n\n/* SECURITY and SAFETY:\n *\n * libpng is built with support for internal limits on image dimensions and\n * memory usage.  These are documented in scripts/pnglibconf.dfa of the\n * source and recorded in the machine generated header file pnglibconf.h.\n */\n\n/* If you are running on a machine where you cannot allocate more\n * than 64K of memory at once, uncomment this.  While libpng will not\n * normally need that much memory in a chunk (unless you load up a very\n * large file), zlib needs to know how big of a chunk it can use, and\n * libpng thus makes sure to check any memory allocation to verify it\n * will fit into memory.\n *\n * zlib provides 'MAXSEG_64K' which, if defined, indicates the\n * same limit and pngconf.h (already included) sets the limit\n * if certain operating systems are detected.\n */\n#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)\n#  define PNG_MAX_MALLOC_64K\n#endif\n\n#ifndef PNG_UNUSED\n/* Unused formal parameter warnings are silenced using the following macro\n * which is expected to have no bad effects on performance (optimizing\n * compilers will probably remove it entirely).  Note that if you replace\n * it with something other than whitespace, you must include the terminating\n * semicolon.\n */\n#  define PNG_UNUSED(param) (void)param;\n#endif\n\n/* Just a little check that someone hasn't tried to define something\n * contradictory.\n */\n#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)\n#  undef PNG_ZBUF_SIZE\n#  define PNG_ZBUF_SIZE 65536L\n#endif\n\n/* If warnings or errors are turned off the code is disabled or redirected here.\n * From 1.5.4 functions have been added to allow very limited formatting of\n * error and warning messages - this code will also be disabled here.\n */\n#ifdef PNG_WARNINGS_SUPPORTED\n#  define PNG_WARNING_PARAMETERS(p) png_warning_parameters p;\n#else\n#  define png_warning_parameter(p,number,string) ((void)0)\n#  define png_warning_parameter_unsigned(p,number,format,value) ((void)0)\n#  define png_warning_parameter_signed(p,number,format,value) ((void)0)\n#  define png_formatted_warning(pp,p,message) ((void)(pp))\n#  define PNG_WARNING_PARAMETERS(p)\n#endif\n#ifndef PNG_ERROR_TEXT_SUPPORTED\n#  define png_fixed_error(s1,s2) png_err(s1)\n#endif\n\n/* C allows up-casts from (void*) to any pointer and (const void*) to any\n * pointer to a const object.  C++ regards this as a type error and requires an\n * explicit, static, cast and provides the static_cast<> rune to ensure that\n * const is not cast away.\n */\n#ifdef __cplusplus\n#  define png_voidcast(type, value) static_cast<type>(value)\n#  define png_constcast(type, value) const_cast<type>(value)\n#  define png_aligncast(type, value) \\\n   static_cast<type>(static_cast<void*>(value))\n#  define png_aligncastconst(type, value) \\\n   static_cast<type>(static_cast<const void*>(value))\n#else\n#  define png_voidcast(type, value) (value)\n#  define png_constcast(type, value) ((type)(value))\n#  define png_aligncast(type, value) ((void*)(value))\n#  define png_aligncastconst(type, value) ((const void*)(value))\n#endif /* __cplusplus */\n\n/* Some fixed point APIs are still required even if not exported because\n * they get used by the corresponding floating point APIs.  This magic\n * deals with this:\n */\n#ifdef PNG_FIXED_POINT_SUPPORTED\n#  define PNGFAPI PNGAPI\n#else\n#  define PNGFAPI /* PRIVATE */\n#endif\n\n#ifndef PNG_VERSION_INFO_ONLY\n/* Other defines specific to compilers can go here.  Try to keep\n * them inside an appropriate ifdef/endif pair for portability.\n */\n#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\\\n    defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)\n   /* png.c requires the following ANSI-C constants if the conversion of\n    * floating point to ASCII is implemented therein:\n    *\n    *  DBL_DIG  Maximum number of decimal digits (can be set to any constant)\n    *  DBL_MIN  Smallest normalized fp number (can be set to an arbitrary value)\n    *  DBL_MAX  Maximum floating point number (can be set to an arbitrary value)\n    */\n#  include <float.h>\n\n#  if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \\\n    defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)\n     /* We need to check that <math.h> hasn't already been included earlier\n      * as it seems it doesn't agree with <fp.h>, yet we should really use\n      * <fp.h> if possible.\n      */\n#    if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)\n#      include <fp.h>\n#    endif\n#  else\n#    include <math.h>\n#  endif\n#  if defined(_AMIGA) && defined(__SASC) && defined(_M68881)\n     /* Amiga SAS/C: We must include builtin FPU functions when compiling using\n      * MATH=68881\n      */\n#    include <m68881.h>\n#  endif\n#endif\n\n/* This provides the non-ANSI (far) memory allocation routines. */\n#if defined(__TURBOC__) && defined(__MSDOS__)\n#  include <mem.h>\n#  include <alloc.h>\n#endif\n\n#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \\\n    defined(_WIN32) || defined(__WIN32__)\n#  include <windows.h>  /* defines _WINDOWS_ macro */\n#endif\n#endif /* PNG_VERSION_INFO_ONLY */\n\n/* Moved here around 1.5.0beta36 from pngconf.h */\n/* Users may want to use these so they are not private.  Any library\n * functions that are passed far data must be model-independent.\n */\n\n/* Memory model/platform independent fns */\n#ifndef PNG_ABORT\n#  ifdef _WINDOWS_\n#    define PNG_ABORT() ExitProcess(0)\n#  else\n#    define PNG_ABORT() abort()\n#  endif\n#endif\n\n/* These macros may need to be architecture dependent. */\n#define PNG_ALIGN_NONE   0 /* do not use data alignment */\n#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */\n#ifdef offsetof\n#  define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */\n#else\n#  define PNG_ALIGN_OFFSET -1 /* prevent the use of this */\n#endif\n#define PNG_ALIGN_SIZE   3 /* use sizeof to determine alignment */\n\n#ifndef PNG_ALIGN_TYPE\n   /* Default to using aligned access optimizations and requiring alignment to a\n    * multiple of the data type size.  Override in a compiler specific fashion\n    * if necessary by inserting tests here:\n    */\n#  define PNG_ALIGN_TYPE PNG_ALIGN_SIZE\n#endif\n\n#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE\n   /* This is used because in some compiler implementations non-aligned\n    * structure members are supported, so the offsetof approach below fails.\n    * Set PNG_ALIGN_SIZE=0 for compiler combinations where unaligned access\n    * is good for performance.  Do not do this unless you have tested the result\n    * and understand it.\n    */\n#  define png_alignof(type) (sizeof (type))\n#else\n#  if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET\n#     define png_alignof(type) offsetof(struct{char c; type t;}, t)\n#  else\n#     if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS\n#        define png_alignof(type) (1)\n#     endif\n      /* Else leave png_alignof undefined to prevent use thereof */\n#  endif\n#endif\n\n/* This implicitly assumes alignment is always to a power of 2. */\n#ifdef png_alignof\n#  define png_isaligned(ptr, type)\\\n   ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0)\n#else\n#  define png_isaligned(ptr, type) 0\n#endif\n\n/* End of memory model/platform independent support */\n/* End of 1.5.0beta36 move from pngconf.h */\n\n/* CONSTANTS and UTILITY MACROS\n * These are used internally by libpng and not exposed in the API\n */\n\n/* Various modes of operation.  Note that after an init, mode is set to\n * zero automatically when the structure is created.  Three of these\n * are defined in png.h because they need to be visible to applications\n * that call png_set_unknown_chunk().\n */\n/* #define PNG_HAVE_IHDR            0x01 (defined in png.h) */\n/* #define PNG_HAVE_PLTE            0x02 (defined in png.h) */\n#define PNG_HAVE_IDAT               0x04\n/* #define PNG_AFTER_IDAT           0x08 (defined in png.h) */\n#define PNG_HAVE_IEND               0x10\n                   /*               0x20 (unused) */\n                   /*               0x40 (unused) */\n                   /*               0x80 (unused) */\n#define PNG_HAVE_CHUNK_HEADER      0x100\n#define PNG_WROTE_tIME             0x200\n#define PNG_WROTE_INFO_BEFORE_PLTE 0x400\n#define PNG_BACKGROUND_IS_GRAY     0x800\n#define PNG_HAVE_PNG_SIGNATURE    0x1000\n#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */\n                   /*             0x4000 (unused) */\n#define PNG_IS_READ_STRUCT        0x8000 /* Else is a write struct */\n\n/* Flags for the transformations the PNG library does on the image data */\n#define PNG_BGR                 0x0001\n#define PNG_INTERLACE           0x0002\n#define PNG_PACK                0x0004\n#define PNG_SHIFT               0x0008\n#define PNG_SWAP_BYTES          0x0010\n#define PNG_INVERT_MONO         0x0020\n#define PNG_QUANTIZE            0x0040\n#define PNG_COMPOSE             0x0080     /* Was PNG_BACKGROUND */\n#define PNG_BACKGROUND_EXPAND   0x0100\n#define PNG_EXPAND_16           0x0200     /* Added to libpng 1.5.2 */\n#define PNG_16_TO_8             0x0400     /* Becomes 'chop' in 1.5.4 */\n#define PNG_RGBA                0x0800\n#define PNG_EXPAND              0x1000\n#define PNG_GAMMA               0x2000\n#define PNG_GRAY_TO_RGB         0x4000\n#define PNG_FILLER              0x8000\n#define PNG_PACKSWAP           0x10000\n#define PNG_SWAP_ALPHA         0x20000\n#define PNG_STRIP_ALPHA        0x40000\n#define PNG_INVERT_ALPHA       0x80000\n#define PNG_USER_TRANSFORM    0x100000\n#define PNG_RGB_TO_GRAY_ERR   0x200000\n#define PNG_RGB_TO_GRAY_WARN  0x400000\n#define PNG_RGB_TO_GRAY       0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */\n#define PNG_ENCODE_ALPHA      0x800000 /* Added to libpng-1.5.4 */\n#define PNG_ADD_ALPHA        0x1000000 /* Added to libpng-1.2.7 */\n#define PNG_EXPAND_tRNS      0x2000000 /* Added to libpng-1.2.9 */\n#define PNG_SCALE_16_TO_8    0x4000000 /* Added to libpng-1.5.4 */\n                       /*    0x8000000 unused */\n                       /*   0x10000000 unused */\n                       /*   0x20000000 unused */\n                       /*   0x40000000 unused */\n/* Flags for png_create_struct */\n#define PNG_STRUCT_PNG   0x0001\n#define PNG_STRUCT_INFO  0x0002\n\n/* Flags for the png_ptr->flags rather than declaring a byte for each one */\n#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001\n#define PNG_FLAG_ZSTREAM_INITIALIZED      0x0002 /* Added to libpng-1.6.0 */\n                                  /*      0x0004    unused */\n#define PNG_FLAG_ZSTREAM_ENDED            0x0008 /* Added to libpng-1.6.0 */\n                                  /*      0x0010    unused */\n                                  /*      0x0020    unused */\n#define PNG_FLAG_ROW_INIT                 0x0040\n#define PNG_FLAG_FILLER_AFTER             0x0080\n#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100\n#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200\n#define PNG_FLAG_CRC_CRITICAL_USE         0x0400\n#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800\n#define PNG_FLAG_ASSUME_sRGB              0x1000 /* Added to libpng-1.5.4 */\n#define PNG_FLAG_OPTIMIZE_ALPHA           0x2000 /* Added to libpng-1.5.4 */\n#define PNG_FLAG_DETECT_UNINITIALIZED     0x4000 /* Added to libpng-1.5.4 */\n/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000 */\n/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS      0x10000 */\n#define PNG_FLAG_LIBRARY_MISMATCH        0x20000\n#define PNG_FLAG_STRIP_ERROR_NUMBERS     0x40000\n#define PNG_FLAG_STRIP_ERROR_TEXT        0x80000\n#define PNG_FLAG_BENIGN_ERRORS_WARN     0x100000 /* Added to libpng-1.4.0 */\n#define PNG_FLAG_APP_WARNINGS_WARN      0x200000 /* Added to libpng-1.6.0 */\n#define PNG_FLAG_APP_ERRORS_WARN        0x400000 /* Added to libpng-1.6.0 */\n                                  /*    0x800000    unused */\n                                  /*   0x1000000    unused */\n                                  /*   0x2000000    unused */\n                                  /*   0x4000000    unused */\n                                  /*   0x8000000    unused */\n                                  /*  0x10000000    unused */\n                                  /*  0x20000000    unused */\n                                  /*  0x40000000    unused */\n\n#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \\\n                                     PNG_FLAG_CRC_ANCILLARY_NOWARN)\n\n#define PNG_FLAG_CRC_CRITICAL_MASK  (PNG_FLAG_CRC_CRITICAL_USE | \\\n                                     PNG_FLAG_CRC_CRITICAL_IGNORE)\n\n#define PNG_FLAG_CRC_MASK           (PNG_FLAG_CRC_ANCILLARY_MASK | \\\n                                     PNG_FLAG_CRC_CRITICAL_MASK)\n\n/* Save typing and make code easier to understand */\n\n#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \\\n   abs((int)((c1).green) - (int)((c2).green)) + \\\n   abs((int)((c1).blue) - (int)((c2).blue)))\n\n/* Added to libpng-1.6.0: scale a 16-bit value in the range 0..65535 to 0..255\n * by dividing by 257 *with rounding*.  This macro is exact for the given range.\n * See the discourse in pngrtran.c png_do_scale_16_to_8.  The values in the\n * macro were established by experiment (modifying the added value).  The macro\n * has a second variant that takes a value already scaled by 255 and divides by\n * 65535 - this has a maximum error of .502.  Over the range 0..65535*65535 it\n * only gives off-by-one errors and only for 0.5% (1 in 200) of the values.\n */\n#define PNG_DIV65535(v24) (((v24) + 32895) >> 16)\n#define PNG_DIV257(v16) PNG_DIV65535((png_uint_32)(v16) * 255)\n\n/* Added to libpng-1.2.6 JB */\n#define PNG_ROWBYTES(pixel_bits, width) \\\n    ((pixel_bits) >= 8 ? \\\n    ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \\\n    (( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) )\n\n/* PNG_OUT_OF_RANGE returns true if value is outside the range\n * ideal-delta..ideal+delta.  Each argument is evaluated twice.\n * \"ideal\" and \"delta\" should be constants, normally simple\n * integers, \"value\" a variable. Added to libpng-1.2.6 JB\n */\n#define PNG_OUT_OF_RANGE(value, ideal, delta) \\\n   ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )\n\n/* Conversions between fixed and floating point, only defined if\n * required (to make sure the code doesn't accidentally use float\n * when it is supposedly disabled.)\n */\n#ifdef PNG_FLOATING_POINT_SUPPORTED\n/* The floating point conversion can't overflow, though it can and\n * does lose accuracy relative to the original fixed point value.\n * In practice this doesn't matter because png_fixed_point only\n * stores numbers with very low precision.  The png_ptr and s\n * arguments are unused by default but are there in case error\n * checking becomes a requirement.\n */\n#define png_float(png_ptr, fixed, s) (.00001 * (fixed))\n\n/* The fixed point conversion performs range checking and evaluates\n * its argument multiple times, so must be used with care.  The\n * range checking uses the PNG specification values for a signed\n * 32-bit fixed point value except that the values are deliberately\n * rounded-to-zero to an integral value - 21474 (21474.83 is roughly\n * (2^31-1) * 100000). 's' is a string that describes the value being\n * converted.\n *\n * NOTE: this macro will raise a png_error if the range check fails,\n * therefore it is normally only appropriate to use this on values\n * that come from API calls or other sources where an out of range\n * error indicates a programming error, not a data error!\n *\n * NOTE: by default this is off - the macro is not used - because the\n * function call saves a lot of code.\n */\n#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED\n#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\\\n    ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0))\n#endif\n/* else the corresponding function is defined below, inside the scope of the\n * cplusplus test.\n */\n#endif\n\n/* Constants for known chunk types.  If you need to add a chunk, define the name\n * here.  For historical reasons these constants have the form png_<name>; i.e.\n * the prefix is lower case.  Please use decimal values as the parameters to\n * match the ISO PNG specification and to avoid relying on the C locale\n * interpretation of character values.\n *\n * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values\n * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string\n * to be generated if required.\n *\n * PNG_32b correctly produces a value shifted by up to 24 bits, even on\n * architectures where (int) is only 16 bits.\n */\n#define PNG_32b(b,s) ((png_uint_32)(b) << (s))\n#define PNG_U32(b1,b2,b3,b4) \\\n   (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0))\n\n/* Constants for known chunk types.\n *\n * MAINTAINERS: If you need to add a chunk, define the name here.\n * For historical reasons these constants have the form png_<name>; i.e.\n * the prefix is lower case.  Please use decimal values as the parameters to\n * match the ISO PNG specification and to avoid relying on the C locale\n * interpretation of character values.  Please keep the list sorted.\n *\n * Notice that PNG_U32 is used to define a 32-bit value for the 4 byte chunk\n * type.  In fact the specification does not express chunk types this way,\n * however using a 32-bit value means that the chunk type can be read from the\n * stream using exactly the same code as used for a 32-bit unsigned value and\n * can be examined far more efficiently (using one arithmetic compare).\n *\n * Prior to 1.5.6 the chunk type constants were expressed as C strings.  The\n * libpng API still uses strings for 'unknown' chunks and a macro,\n * PNG_STRING_FROM_CHUNK, allows a string to be generated if required.  Notice\n * that for portable code numeric values must still be used; the string \"IHDR\"\n * is not portable and neither is PNG_U32('I', 'H', 'D', 'R').\n *\n * In 1.7.0 the definitions will be made public in png.h to avoid having to\n * duplicate the same definitions in application code.\n */\n#define png_IDAT PNG_U32( 73,  68,  65,  84)\n#define png_IEND PNG_U32( 73,  69,  78,  68)\n#define png_IHDR PNG_U32( 73,  72,  68,  82)\n#define png_PLTE PNG_U32( 80,  76,  84,  69)\n#define png_bKGD PNG_U32( 98,  75,  71,  68)\n#define png_cHRM PNG_U32( 99,  72,  82,  77)\n#define png_fRAc PNG_U32(102,  82,  65,  99) /* registered, not defined */\n#define png_gAMA PNG_U32(103,  65,  77,  65)\n#define png_gIFg PNG_U32(103,  73,  70, 103)\n#define png_gIFt PNG_U32(103,  73,  70, 116) /* deprecated */\n#define png_gIFx PNG_U32(103,  73,  70, 120)\n#define png_hIST PNG_U32(104,  73,  83,  84)\n#define png_iCCP PNG_U32(105,  67,  67,  80)\n#define png_iTXt PNG_U32(105,  84,  88, 116)\n#define png_oFFs PNG_U32(111,  70,  70, 115)\n#define png_pCAL PNG_U32(112,  67,  65,  76)\n#define png_pHYs PNG_U32(112,  72,  89, 115)\n#define png_sBIT PNG_U32(115,  66,  73,  84)\n#define png_sCAL PNG_U32(115,  67,  65,  76)\n#define png_sPLT PNG_U32(115,  80,  76,  84)\n#define png_sRGB PNG_U32(115,  82,  71,  66)\n#define png_sTER PNG_U32(115,  84,  69,  82)\n#define png_tEXt PNG_U32(116,  69,  88, 116)\n#define png_tIME PNG_U32(116,  73,  77,  69)\n#define png_tRNS PNG_U32(116,  82,  78,  83)\n#define png_zTXt PNG_U32(122,  84,  88, 116)\n\n/* The following will work on (signed char*) strings, whereas the get_uint_32\n * macro will fail on top-bit-set values because of the sign extension.\n */\n#define PNG_CHUNK_FROM_STRING(s)\\\n   PNG_U32(0xff & (s)[0], 0xff & (s)[1], 0xff & (s)[2], 0xff & (s)[3])\n\n/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is\n * signed and the argument is a (char[])  This macro will fail miserably on\n * systems where (char) is more than 8 bits.\n */\n#define PNG_STRING_FROM_CHUNK(s,c)\\\n   (void)(((char*)(s))[0]=(char)(((c)>>24) & 0xff), \\\n   ((char*)(s))[1]=(char)(((c)>>16) & 0xff),\\\n   ((char*)(s))[2]=(char)(((c)>>8) & 0xff), \\\n   ((char*)(s))[3]=(char)((c & 0xff)))\n\n/* Do the same but terminate with a null character. */\n#define PNG_CSTRING_FROM_CHUNK(s,c)\\\n   (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0)\n\n/* Test on flag values as defined in the spec (section 5.4): */\n#define PNG_CHUNK_ANCILLARY(c)   (1 & ((c) >> 29))\n#define PNG_CHUNK_CRITICAL(c)     (!PNG_CHUNK_ANCILLARY(c))\n#define PNG_CHUNK_PRIVATE(c)      (1 & ((c) >> 21))\n#define PNG_CHUNK_RESERVED(c)     (1 & ((c) >> 13))\n#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >>  5))\n\n/* Gamma values (new at libpng-1.5.4): */\n#define PNG_GAMMA_MAC_OLD 151724  /* Assume '1.8' is really 2.2/1.45! */\n#define PNG_GAMMA_MAC_INVERSE 65909\n#define PNG_GAMMA_sRGB_INVERSE 45455\n\n/* Almost everything below is C specific; the #defines above can be used in\n * non-C code (so long as it is C-preprocessed) the rest of this stuff cannot.\n */\n#ifndef PNG_VERSION_INFO_ONLY\n\n#include \"pngstruct.h\"\n#include \"pnginfo.h\"\n\n/* Validate the include paths - the include path used to generate pnglibconf.h\n * must match that used in the build, or we must be using pnglibconf.h.prebuilt:\n */\n#if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM\n#  error ZLIB_VERNUM != PNG_ZLIB_VERNUM \\\n      \"-I (include path) error: see the notes in pngpriv.h\"\n   /* This means that when pnglibconf.h was built the copy of zlib.h that it\n    * used is not the same as the one being used here.  Because the build of\n    * libpng makes decisions to use inflateInit2 and inflateReset2 based on the\n    * zlib version number and because this affects handling of certain broken\n    * PNG files the -I directives must match.\n    *\n    * The most likely explanation is that you passed a -I in CFLAGS. This will\n    * not work; all the preprocessor directories and in particular all the -I\n    * directives must be in CPPFLAGS.\n    */\n#endif\n\n/* This is used for 16-bit gamma tables -- only the top level pointers are\n * const; this could be changed:\n */\ntypedef const png_uint_16p * png_const_uint_16pp;\n\n/* Added to libpng-1.5.7: sRGB conversion tables */\n#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\\\n   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)\n#ifdef PNG_SIMPLIFIED_READ_SUPPORTED\nPNG_INTERNAL_DATA(const png_uint_16, png_sRGB_table, [256]);\n   /* Convert from an sRGB encoded value 0..255 to a 16-bit linear value,\n    * 0..65535.  This table gives the closest 16-bit answers (no errors).\n    */\n#endif\n\nPNG_INTERNAL_DATA(const png_uint_16, png_sRGB_base, [512]);\nPNG_INTERNAL_DATA(const png_byte, png_sRGB_delta, [512]);\n\n#define PNG_sRGB_FROM_LINEAR(linear) \\\n  ((png_byte)(0xff & ((png_sRGB_base[(linear)>>15] \\\n   + ((((linear) & 0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8)))\n   /* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB\n    * encoded value with maximum error 0.646365.  Note that the input is not a\n    * 16-bit value; it has been multiplied by 255! */\n#endif /* SIMPLIFIED_READ/WRITE */\n\n\n/* Inhibit C++ name-mangling for libpng functions but not for system calls. */\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/* Internal functions; these are not exported from a DLL however because they\n * are used within several of the C source files they have to be C extern.\n *\n * All of these functions must be declared with PNG_INTERNAL_FUNCTION.\n */\n\n/* Zlib support */\n#define PNG_UNEXPECTED_ZLIB_RETURN (-7)\nPNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret),\n   PNG_EMPTY);\n   /* Used by the zlib handling functions to ensure that z_stream::msg is always\n    * set before they return.\n    */\n\n#ifdef PNG_WRITE_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr,\n   png_compression_bufferp *list),PNG_EMPTY);\n   /* Free the buffer list used by the compressed write code. */\n#endif\n\n#if defined(PNG_FLOATING_POINT_SUPPORTED) && \\\n   !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \\\n   (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \\\n   defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \\\n   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \\\n   (defined(PNG_sCAL_SUPPORTED) && \\\n   defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))\nPNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr,\n   double fp, png_const_charp text),PNG_EMPTY);\n#endif\n\n/* Check the user version string for compatibility, returns false if the version\n * numbers aren't compatible.\n */\nPNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr,\n   png_const_charp user_png_ver),PNG_EMPTY);\n\n/* Internal base allocator - no messages, NULL on failure to allocate.  This\n * does, however, call the application provided allocator and that could call\n * png_error (although that would be a bug in the application implementation.)\n */\nPNG_INTERNAL_FUNCTION(png_voidp,png_malloc_base,(png_const_structrp png_ptr,\n   png_alloc_size_t size),PNG_ALLOCATED);\n\n#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\\\n   defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)\n/* Internal array allocator, outputs no error or warning messages on failure,\n * just returns NULL.\n */\nPNG_INTERNAL_FUNCTION(png_voidp,png_malloc_array,(png_const_structrp png_ptr,\n   int nelements, size_t element_size),PNG_ALLOCATED);\n\n/* The same but an existing array is extended by add_elements.  This function\n * also memsets the new elements to 0 and copies the old elements.  The old\n * array is not freed or altered.\n */\nPNG_INTERNAL_FUNCTION(png_voidp,png_realloc_array,(png_const_structrp png_ptr,\n   png_const_voidp array, int old_elements, int add_elements,\n   size_t element_size),PNG_ALLOCATED);\n#endif /* text, sPLT or unknown chunks */\n\n/* Magic to create a struct when there is no struct to call the user supplied\n * memory allocators.  Because error handling has not been set up the memory\n * handlers can't safely call png_error, but this is an obscure and undocumented\n * restriction so libpng has to assume that the 'free' handler, at least, might\n * call png_error.\n */\nPNG_INTERNAL_FUNCTION(png_structp,png_create_png_struct,\n   (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,\n    png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn,\n    png_free_ptr free_fn),PNG_ALLOCATED);\n\n/* Free memory from internal libpng struct */\nPNG_INTERNAL_FUNCTION(void,png_destroy_png_struct,(png_structrp png_ptr),\n   PNG_EMPTY);\n\n/* Free an allocated jmp_buf (always succeeds) */\nPNG_INTERNAL_FUNCTION(void,png_free_jmpbuf,(png_structrp png_ptr),PNG_EMPTY);\n\n/* Function to allocate memory for zlib.  PNGAPI is disallowed. */\nPNG_INTERNAL_FUNCTION(voidpf,png_zalloc,(voidpf png_ptr, uInt items, uInt size),\n   PNG_ALLOCATED);\n\n/* Function to free memory for zlib.  PNGAPI is disallowed. */\nPNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY);\n\n/* Next four functions are used internally as callbacks.  PNGCBAPI is required\n * but not PNG_EXPORT.  PNGAPI added at libpng version 1.2.3, changed to\n * PNGCBAPI at 1.5.0\n */\n\nPNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr,\n    png_bytep data, png_size_t length),PNG_EMPTY);\n\n#ifdef PNG_PROGRESSIVE_READ_SUPPORTED\nPNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr,\n    png_bytep buffer, png_size_t length),PNG_EMPTY);\n#endif\n\nPNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr,\n    png_bytep data, png_size_t length),PNG_EMPTY);\n\n#ifdef PNG_WRITE_FLUSH_SUPPORTED\n#  ifdef PNG_STDIO_SUPPORTED\nPNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_flush,(png_structp png_ptr),\n   PNG_EMPTY);\n#  endif\n#endif\n\n/* Reset the CRC variable */\nPNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY);\n\n/* Write the \"data\" buffer to whatever output you are using */\nPNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr,\n    png_const_bytep data, png_size_t length),PNG_EMPTY);\n\n/* Read and check the PNG file signature */\nPNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr,\n   png_inforp info_ptr),PNG_EMPTY);\n\n/* Read the chunk header (length + type name) */\nPNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr),\n   PNG_EMPTY);\n\n/* Read data from whatever input you are using into the \"data\" buffer */\nPNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data,\n    png_size_t length),PNG_EMPTY);\n\n/* Read bytes into buf, and update png_ptr->crc */\nPNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf,\n    png_uint_32 length),PNG_EMPTY);\n\n/* Read \"skip\" bytes, read the file crc, and (optionally) verify png_ptr->crc */\nPNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr,\n   png_uint_32 skip),PNG_EMPTY);\n\n/* Read the CRC from the file and compare it to the libpng calculated CRC */\nPNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY);\n\n/* Calculate the CRC over a section of data.  Note that we are only\n * passing a maximum of 64K on systems that have this as a memory limit,\n * since this is the maximum buffer size we can specify.\n */\nPNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr,\n   png_const_bytep ptr, png_size_t length),PNG_EMPTY);\n\n#ifdef PNG_WRITE_FLUSH_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY);\n#endif\n\n/* Write various chunks */\n\n/* Write the IHDR chunk, and update the png_struct with the necessary\n * information.\n */\nPNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp png_ptr,\n   png_uint_32 width, png_uint_32 height, int bit_depth, int color_type,\n   int compression_method, int filter_method, int interlace_method),PNG_EMPTY);\n\nPNG_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr,\n   png_const_colorp palette, png_uint_32 num_pal),PNG_EMPTY);\n\nPNG_INTERNAL_FUNCTION(void,png_compress_IDAT,(png_structrp png_ptr,\n   png_const_bytep row_data, png_alloc_size_t row_data_length, int flush),\n   PNG_EMPTY);\n\nPNG_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY);\n\n#ifdef PNG_WRITE_gAMA_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_gAMA_fixed,(png_structrp png_ptr,\n    png_fixed_point file_gamma),PNG_EMPTY);\n#endif\n\n#ifdef PNG_WRITE_sBIT_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr,\n    png_const_color_8p sbit, int color_type),PNG_EMPTY);\n#endif\n\n#ifdef PNG_WRITE_cHRM_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr,\n    const png_xy *xy), PNG_EMPTY);\n    /* The xy value must have been previously validated */\n#endif\n\n#ifdef PNG_WRITE_sRGB_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr,\n    int intent),PNG_EMPTY);\n#endif\n\n#ifdef PNG_WRITE_iCCP_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,\n   png_const_charp name, png_const_bytep profile), PNG_EMPTY);\n   /* The profile must have been previously validated for correctness, the\n    * length comes from the first four bytes.  Only the base, deflate,\n    * compression is supported.\n    */\n#endif\n\n#ifdef PNG_WRITE_sPLT_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr,\n    png_const_sPLT_tp palette),PNG_EMPTY);\n#endif\n\n#ifdef PNG_WRITE_tRNS_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_tRNS,(png_structrp png_ptr,\n    png_const_bytep trans, png_const_color_16p values, int number,\n    int color_type),PNG_EMPTY);\n#endif\n\n#ifdef PNG_WRITE_bKGD_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_bKGD,(png_structrp png_ptr,\n    png_const_color_16p values, int color_type),PNG_EMPTY);\n#endif\n\n#ifdef PNG_WRITE_hIST_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr,\n    png_const_uint_16p hist, int num_hist),PNG_EMPTY);\n#endif\n\n/* Chunks that have keywords */\n#ifdef PNG_WRITE_tEXt_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr,\n   png_const_charp key, png_const_charp text, png_size_t text_len),PNG_EMPTY);\n#endif\n\n#ifdef PNG_WRITE_zTXt_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_zTXt,(png_structrp png_ptr, png_const_charp\n    key, png_const_charp text, int compression),PNG_EMPTY);\n#endif\n\n#ifdef PNG_WRITE_iTXt_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_iTXt,(png_structrp png_ptr,\n    int compression, png_const_charp key, png_const_charp lang,\n    png_const_charp lang_key, png_const_charp text),PNG_EMPTY);\n#endif\n\n#ifdef PNG_TEXT_SUPPORTED  /* Added at version 1.0.14 and 1.2.4 */\nPNG_INTERNAL_FUNCTION(int,png_set_text_2,(png_const_structrp png_ptr,\n    png_inforp info_ptr, png_const_textp text_ptr, int num_text),PNG_EMPTY);\n#endif\n\n#ifdef PNG_WRITE_oFFs_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_oFFs,(png_structrp png_ptr,\n    png_int_32 x_offset, png_int_32 y_offset, int unit_type),PNG_EMPTY);\n#endif\n\n#ifdef PNG_WRITE_pCAL_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_pCAL,(png_structrp png_ptr,\n    png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,\n    png_const_charp units, png_charpp params),PNG_EMPTY);\n#endif\n\n#ifdef PNG_WRITE_pHYs_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_pHYs,(png_structrp png_ptr,\n    png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,\n    int unit_type),PNG_EMPTY);\n#endif\n\n#ifdef PNG_WRITE_tIME_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_tIME,(png_structrp png_ptr,\n    png_const_timep mod_time),PNG_EMPTY);\n#endif\n\n#ifdef PNG_WRITE_sCAL_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_write_sCAL_s,(png_structrp png_ptr,\n    int unit, png_const_charp width, png_const_charp height),PNG_EMPTY);\n#endif\n\n/* Called when finished processing a row of data */\nPNG_INTERNAL_FUNCTION(void,png_write_finish_row,(png_structrp png_ptr),\n    PNG_EMPTY);\n\n/* Internal use only.   Called before first row of data */\nPNG_INTERNAL_FUNCTION(void,png_write_start_row,(png_structrp png_ptr),\n    PNG_EMPTY);\n\n/* Combine a row of data, dealing with alpha, etc. if requested.  'row' is an\n * array of png_ptr->width pixels.  If the image is not interlaced or this\n * is the final pass this just does a memcpy, otherwise the \"display\" flag\n * is used to determine whether to copy pixels that are not in the current pass.\n *\n * Because 'png_do_read_interlace' (below) replicates pixels this allows this\n * function to achieve the documented 'blocky' appearance during interlaced read\n * if display is 1 and the 'sparkle' appearance, where existing pixels in 'row'\n * are not changed if they are not in the current pass, when display is 0.\n *\n * 'display' must be 0 or 1, otherwise the memcpy will be done regardless.\n *\n * The API always reads from the png_struct row buffer and always assumes that\n * it is full width (png_do_read_interlace has already been called.)\n *\n * This function is only ever used to write to row buffers provided by the\n * caller of the relevant libpng API and the row must have already been\n * transformed by the read transformations.\n *\n * The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed\n * bitmasks for use within the code, otherwise runtime generated masks are used.\n * The default is compile time masks.\n */\n#ifndef PNG_USE_COMPILE_TIME_MASKS\n#  define PNG_USE_COMPILE_TIME_MASKS 1\n#endif\nPNG_INTERNAL_FUNCTION(void,png_combine_row,(png_const_structrp png_ptr,\n    png_bytep row, int display),PNG_EMPTY);\n\n#ifdef PNG_READ_INTERLACING_SUPPORTED\n/* Expand an interlaced row: the 'row_info' describes the pass data that has\n * been read in and must correspond to the pixels in 'row', the pixels are\n * expanded (moved apart) in 'row' to match the final layout, when doing this\n * the pixels are *replicated* to the intervening space.  This is essential for\n * the correct operation of png_combine_row, above.\n */\nPNG_INTERNAL_FUNCTION(void,png_do_read_interlace,(png_row_infop row_info,\n    png_bytep row, int pass, png_uint_32 transformations),PNG_EMPTY);\n#endif\n\n/* GRR TO DO (2.0 or whenever):  simplify other internal calling interfaces */\n\n#ifdef PNG_WRITE_INTERLACING_SUPPORTED\n/* Grab pixels out of a row for an interlaced pass */\nPNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info,\n    png_bytep row, int pass),PNG_EMPTY);\n#endif\n\n/* Unfilter a row: check the filter value before calling this, there is no point\n * calling it for PNG_FILTER_VALUE_NONE.\n */\nPNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop\n    row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY);\n\nPNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info,\n    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop\n    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_neon,(png_row_infop\n    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_neon,(png_row_infop\n    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon,(png_row_infop\n    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop\n    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop\n    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);\n\nPNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_sse2,(png_row_infop\n    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_sse2,(png_row_infop\n    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_sse2,(png_row_infop\n    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_sse2,(png_row_infop\n    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_sse2,(png_row_infop\n    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop\n    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);\n\n/* Choose the best filter to use and filter the row data */\nPNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,\n    png_row_infop row_info),PNG_EMPTY);\n\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr,\n   png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY);\n   /* Read 'avail_out' bytes of data from the IDAT stream.  If the output buffer\n    * is NULL the function checks, instead, for the end of the stream.  In this\n    * case a benign error will be issued if the stream end is not found or if\n    * extra data has to be consumed.\n    */\nPNG_INTERNAL_FUNCTION(void,png_read_finish_IDAT,(png_structrp png_ptr),\n   PNG_EMPTY);\n   /* This cleans up when the IDAT LZ stream does not end when the last image\n    * byte is read; there is still some pending input.\n    */\n\nPNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),\n   PNG_EMPTY);\n   /* Finish a row while reading, dealing with interlacing passes, etc. */\n#endif /* SEQUENTIAL_READ */\n\n/* Initialize the row buffers, etc. */\nPNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);\n\n#if PNG_ZLIB_VERNUM >= 0x1240\nPNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush),\n      PNG_EMPTY);\n#  define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush)\n#else /* Zlib < 1.2.4 */\n#  define PNG_INFLATE(pp, flush) inflate(&(pp)->zstream, flush)\n#endif /* Zlib < 1.2.4 */\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\n/* Optional call to update the users info structure */\nPNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr,\n    png_inforp info_ptr),PNG_EMPTY);\n#endif\n\n/* Shared transform functions, defined in pngtran.c */\n#if defined(PNG_WRITE_FILLER_SUPPORTED) || \\\n    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)\nPNG_INTERNAL_FUNCTION(void,png_do_strip_channel,(png_row_infop row_info,\n    png_bytep row, int at_start),PNG_EMPTY);\n#endif\n\n#ifdef PNG_16BIT_SUPPORTED\n#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)\nPNG_INTERNAL_FUNCTION(void,png_do_swap,(png_row_infop row_info,\n    png_bytep row),PNG_EMPTY);\n#endif\n#endif\n\n#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \\\n    defined(PNG_WRITE_PACKSWAP_SUPPORTED)\nPNG_INTERNAL_FUNCTION(void,png_do_packswap,(png_row_infop row_info,\n    png_bytep row),PNG_EMPTY);\n#endif\n\n#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)\nPNG_INTERNAL_FUNCTION(void,png_do_invert,(png_row_infop row_info,\n    png_bytep row),PNG_EMPTY);\n#endif\n\n#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)\nPNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info,\n    png_bytep row),PNG_EMPTY);\n#endif\n\n/* The following decodes the appropriate chunks, and does error correction,\n * then calls the appropriate callback for the chunk if it is valid.\n */\n\n/* Decode the IHDR chunk */\nPNG_INTERNAL_FUNCTION(void,png_handle_IHDR,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_handle_PLTE,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_handle_IEND,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n\n#ifdef PNG_READ_bKGD_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_bKGD,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_cHRM_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_gAMA_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_hIST_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_hIST,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_iCCP_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_iCCP,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif /* READ_iCCP */\n\n#ifdef PNG_READ_iTXt_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_iTXt,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_oFFs_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_oFFs,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_pCAL_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_pCAL,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_pHYs_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_pHYs,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_sBIT_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_sBIT,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_sCAL_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_sCAL,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_sPLT_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_sPLT,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif /* READ_sPLT */\n\n#ifdef PNG_READ_sRGB_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_sRGB,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_tEXt_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_tEXt,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_tIME_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_tIME,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_tRNS_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_tRNS,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_zTXt_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\n#endif\n\nPNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_structrp png_ptr,\n    png_uint_32 chunk_name),PNG_EMPTY);\n\nPNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);\n   /* This is the function that gets called for unknown chunks.  The 'keep'\n    * argument is either non-zero for a known chunk that has been set to be\n    * handled as unknown or zero for an unknown chunk.  By default the function\n    * just skips the chunk or errors out if it is critical.\n    */\n\n#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\\\n    defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)\nPNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling,\n    (png_const_structrp png_ptr, png_uint_32 chunk_name),PNG_EMPTY);\n   /* Exactly as the API png_handle_as_unknown() except that the argument is a\n    * 32-bit chunk name, not a string.\n    */\n#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */\n\n/* Handle the transformations for reading and writing */\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_do_read_transformations,(png_structrp png_ptr,\n   png_row_infop row_info),PNG_EMPTY);\n#endif\n#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_do_write_transformations,(png_structrp png_ptr,\n   png_row_infop row_info),PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_init_read_transformations,(png_structrp png_ptr),\n    PNG_EMPTY);\n#endif\n\n#ifdef PNG_PROGRESSIVE_READ_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_push_read_chunk,(png_structrp png_ptr,\n    png_inforp info_ptr),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_push_read_sig,(png_structrp png_ptr,\n    png_inforp info_ptr),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr),\n    PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr,\n    png_bytep buffer, png_size_t buffer_length),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr,\n    png_bytep buffer, png_size_t buffer_length),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr),\n    PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr,\n   png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr,\n   png_inforp info_ptr),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr,\n   png_inforp info_ptr),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr,\n     png_bytep row),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr,\n    png_inforp info_ptr),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr,\n    png_inforp info_ptr),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr),\n    PNG_EMPTY);\n#  ifdef PNG_READ_tEXt_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_push_handle_tEXt,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_push_read_tEXt,(png_structrp png_ptr,\n    png_inforp info_ptr),PNG_EMPTY);\n#  endif\n#  ifdef PNG_READ_zTXt_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_push_handle_zTXt,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_push_read_zTXt,(png_structrp png_ptr,\n    png_inforp info_ptr),PNG_EMPTY);\n#  endif\n#  ifdef PNG_READ_iTXt_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_push_handle_iTXt,(png_structrp png_ptr,\n    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_push_read_iTXt,(png_structrp png_ptr,\n    png_inforp info_ptr),PNG_EMPTY);\n#  endif\n\n#endif /* PROGRESSIVE_READ */\n\n/* Added at libpng version 1.6.0 */\n#ifdef PNG_GAMMA_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr,\n    png_colorspacerp colorspace, png_fixed_point gAMA), PNG_EMPTY);\n   /* Set the colorspace gamma with a value provided by the application or by\n    * the gAMA chunk on read.  The value will override anything set by an ICC\n    * profile.\n    */\n\nPNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr,\n    png_inforp info_ptr), PNG_EMPTY);\n    /* Synchronize the info 'valid' flags with the colorspace */\n\nPNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr,\n    png_inforp info_ptr), PNG_EMPTY);\n    /* Copy the png_struct colorspace to the info_struct and call the above to\n     * synchronize the flags.  Checks for NULL info_ptr and does nothing.\n     */\n#endif\n\n/* Added at libpng version 1.4.0 */\n#ifdef PNG_COLORSPACE_SUPPORTED\n/* These internal functions are for maintaining the colorspace structure within\n * a png_info or png_struct (or, indeed, both).\n */\nPNG_INTERNAL_FUNCTION(int,png_colorspace_set_chromaticities,\n   (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_xy *xy,\n    int preferred), PNG_EMPTY);\n\nPNG_INTERNAL_FUNCTION(int,png_colorspace_set_endpoints,\n   (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_XYZ *XYZ,\n    int preferred), PNG_EMPTY);\n\n#ifdef PNG_sRGB_SUPPORTED\nPNG_INTERNAL_FUNCTION(int,png_colorspace_set_sRGB,(png_const_structrp png_ptr,\n   png_colorspacerp colorspace, int intent), PNG_EMPTY);\n   /* This does set the colorspace gAMA and cHRM values too, but doesn't set the\n    * flags to write them, if it returns false there was a problem and an error\n    * message has already been output (but the colorspace may still need to be\n    * synced to record the invalid flag).\n    */\n#endif /* sRGB */\n\n#ifdef PNG_iCCP_SUPPORTED\nPNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr,\n   png_colorspacerp colorspace, png_const_charp name,\n   png_uint_32 profile_length, png_const_bytep profile, int color_type),\n   PNG_EMPTY);\n   /* The 'name' is used for information only */\n\n/* Routines for checking parts of an ICC profile. */\nPNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,\n   png_colorspacerp colorspace, png_const_charp name,\n   png_uint_32 profile_length), PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,\n   png_colorspacerp colorspace, png_const_charp name,\n   png_uint_32 profile_length,\n   png_const_bytep profile /* first 132 bytes only */, int color_type),\n   PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr,\n   png_colorspacerp colorspace, png_const_charp name,\n   png_uint_32 profile_length,\n   png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY);\n#ifdef PNG_sRGB_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_icc_set_sRGB,(\n   png_const_structrp png_ptr, png_colorspacerp colorspace,\n   png_const_bytep profile, uLong adler), PNG_EMPTY);\n   /* 'adler' is the Adler32 checksum of the uncompressed profile data. It may\n    * be zero to indicate that it is not available.  It is used, if provided,\n    * as a fast check on the profile when checking to see if it is sRGB.\n    */\n#endif\n#endif /* iCCP */\n\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_colorspace_set_rgb_coefficients,\n   (png_structrp png_ptr), PNG_EMPTY);\n   /* Set the rgb_to_gray coefficients from the colorspace Y values */\n#endif /* READ_RGB_TO_GRAY */\n#endif /* COLORSPACE */\n\n/* Added at libpng version 1.4.0 */\nPNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr,\n    png_uint_32 width, png_uint_32 height, int bit_depth,\n    int color_type, int interlace_type, int compression_type,\n    int filter_type),PNG_EMPTY);\n\n/* Added at libpng version 1.5.10 */\n#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \\\n    defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)\nPNG_INTERNAL_FUNCTION(void,png_do_check_palette_indexes,\n   (png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY);\n#endif\n\n#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)\nPNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp png_ptr,\n   png_const_charp name),PNG_NORETURN);\n#endif\n\n/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite\n * the end.  Always leaves the buffer nul terminated.  Never errors out (and\n * there is no error code.)\n */\nPNG_INTERNAL_FUNCTION(size_t,png_safecat,(png_charp buffer, size_t bufsize,\n   size_t pos, png_const_charp string),PNG_EMPTY);\n\n/* Various internal functions to handle formatted warning messages, currently\n * only implemented for warnings.\n */\n#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)\n/* Utility to dump an unsigned value into a buffer, given a start pointer and\n * and end pointer (which should point just *beyond* the end of the buffer!)\n * Returns the pointer to the start of the formatted string.  This utility only\n * does unsigned values.\n */\nPNG_INTERNAL_FUNCTION(png_charp,png_format_number,(png_const_charp start,\n   png_charp end, int format, png_alloc_size_t number),PNG_EMPTY);\n\n/* Convenience macro that takes an array: */\n#define PNG_FORMAT_NUMBER(buffer,format,number) \\\n   png_format_number(buffer, buffer + (sizeof buffer), format, number)\n\n/* Suggested size for a number buffer (enough for 64 bits and a sign!) */\n#define PNG_NUMBER_BUFFER_SIZE 24\n\n/* These are the integer formats currently supported, the name is formed from\n * the standard printf(3) format string.\n */\n#define PNG_NUMBER_FORMAT_u     1 /* chose unsigned API! */\n#define PNG_NUMBER_FORMAT_02u   2\n#define PNG_NUMBER_FORMAT_d     1 /* chose signed API! */\n#define PNG_NUMBER_FORMAT_02d   2\n#define PNG_NUMBER_FORMAT_x     3\n#define PNG_NUMBER_FORMAT_02x   4\n#define PNG_NUMBER_FORMAT_fixed 5 /* choose the signed API */\n#endif\n\n#ifdef PNG_WARNINGS_SUPPORTED\n/* New defines and members adding in libpng-1.5.4 */\n#  define PNG_WARNING_PARAMETER_SIZE 32\n#  define PNG_WARNING_PARAMETER_COUNT 8 /* Maximum 9; see pngerror.c */\n\n/* An l-value of this type has to be passed to the APIs below to cache the\n * values of the parameters to a formatted warning message.\n */\ntypedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][\n   PNG_WARNING_PARAMETER_SIZE];\n\nPNG_INTERNAL_FUNCTION(void,png_warning_parameter,(png_warning_parameters p,\n   int number, png_const_charp string),PNG_EMPTY);\n   /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters,\n    * including the trailing '\\0'.\n    */\nPNG_INTERNAL_FUNCTION(void,png_warning_parameter_unsigned,\n   (png_warning_parameters p, int number, int format, png_alloc_size_t value),\n   PNG_EMPTY);\n   /* Use png_alloc_size_t because it is an unsigned type as big as any we\n    * need to output.  Use the following for a signed value.\n    */\nPNG_INTERNAL_FUNCTION(void,png_warning_parameter_signed,\n   (png_warning_parameters p, int number, int format, png_int_32 value),\n   PNG_EMPTY);\n\nPNG_INTERNAL_FUNCTION(void,png_formatted_warning,(png_const_structrp png_ptr,\n   png_warning_parameters p, png_const_charp message),PNG_EMPTY);\n   /* 'message' follows the X/Open approach of using @1, @2 to insert\n    * parameters previously supplied using the above functions.  Errors in\n    * specifying the parameters will simply result in garbage substitutions.\n    */\n#endif\n\n#ifdef PNG_BENIGN_ERRORS_SUPPORTED\n/* Application errors (new in 1.6); use these functions (declared below) for\n * errors in the parameters or order of API function calls on read.  The\n * 'warning' should be used for an error that can be handled completely; the\n * 'error' for one which can be handled safely but which may lose application\n * information or settings.\n *\n * By default these both result in a png_error call prior to release, while in a\n * released version the 'warning' is just a warning.  However if the application\n * explicitly disables benign errors (explicitly permitting the code to lose\n * information) they both turn into warnings.\n *\n * If benign errors aren't supported they end up as the corresponding base call\n * (png_warning or png_error.)\n */\nPNG_INTERNAL_FUNCTION(void,png_app_warning,(png_const_structrp png_ptr,\n   png_const_charp message),PNG_EMPTY);\n   /* The application provided invalid parameters to an API function or called\n    * an API function at the wrong time, libpng can completely recover.\n    */\n\nPNG_INTERNAL_FUNCTION(void,png_app_error,(png_const_structrp png_ptr,\n   png_const_charp message),PNG_EMPTY);\n   /* As above but libpng will ignore the call, or attempt some other partial\n    * recovery from the error.\n    */\n#else\n#  define png_app_warning(pp,s) png_warning(pp,s)\n#  define png_app_error(pp,s) png_error(pp,s)\n#endif\n\nPNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr,\n   png_const_charp message, int error),PNG_EMPTY);\n   /* Report a recoverable issue in chunk data.  On read this is used to report\n    * a problem found while reading a particular chunk and the\n    * png_chunk_benign_error or png_chunk_warning function is used as\n    * appropriate.  On write this is used to report an error that comes from\n    * data set via an application call to a png_set_ API and png_app_error or\n    * png_app_warning is used as appropriate.\n    *\n    * The 'error' parameter must have one of the following values:\n    */\n#define PNG_CHUNK_WARNING     0 /* never an error */\n#define PNG_CHUNK_WRITE_ERROR 1 /* an error only on write */\n#define PNG_CHUNK_ERROR       2 /* always an error */\n\n/* ASCII to FP interfaces, currently only implemented if sCAL\n * support is required.\n */\n#if defined(PNG_sCAL_SUPPORTED)\n/* MAX_DIGITS is actually the maximum number of characters in an sCAL\n * width or height, derived from the precision (number of significant\n * digits - a build time settable option) and assumptions about the\n * maximum ridiculous exponent.\n */\n#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/)\n\n#ifdef PNG_FLOATING_POINT_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr,\n   png_charp ascii, png_size_t size, double fp, unsigned int precision),\n   PNG_EMPTY);\n#endif /* FLOATING_POINT */\n\n#ifdef PNG_FIXED_POINT_SUPPORTED\nPNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr,\n   png_charp ascii, png_size_t size, png_fixed_point fp),PNG_EMPTY);\n#endif /* FIXED_POINT */\n#endif /* sCAL */\n\n#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)\n/* An internal API to validate the format of a floating point number.\n * The result is the index of the next character.  If the number is\n * not valid it will be the index of a character in the supposed number.\n *\n * The format of a number is defined in the PNG extensions specification\n * and this API is strictly conformant to that spec, not anyone elses!\n *\n * The format as a regular expression is:\n *\n * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)?\n *\n * or:\n *\n * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)?\n *\n * The complexity is that either integer or fraction must be present and the\n * fraction is permitted to have no digits only if the integer is present.\n *\n * NOTE: The dangling E problem.\n *   There is a PNG valid floating point number in the following:\n *\n *       PNG floating point numbers are not greedy.\n *\n *   Working this out requires *TWO* character lookahead (because of the\n *   sign), the parser does not do this - it will fail at the 'r' - this\n *   doesn't matter for PNG sCAL chunk values, but it requires more care\n *   if the value were ever to be embedded in something more complex.  Use\n *   ANSI-C strtod if you need the lookahead.\n */\n/* State table for the parser. */\n#define PNG_FP_INTEGER    0  /* before or in integer */\n#define PNG_FP_FRACTION   1  /* before or in fraction */\n#define PNG_FP_EXPONENT   2  /* before or in exponent */\n#define PNG_FP_STATE      3  /* mask for the above */\n#define PNG_FP_SAW_SIGN   4  /* Saw +/- in current state */\n#define PNG_FP_SAW_DIGIT  8  /* Saw a digit in current state */\n#define PNG_FP_SAW_DOT   16  /* Saw a dot in current state */\n#define PNG_FP_SAW_E     32  /* Saw an E (or e) in current state */\n#define PNG_FP_SAW_ANY   60  /* Saw any of the above 4 */\n\n/* These three values don't affect the parser.  They are set but not used.\n */\n#define PNG_FP_WAS_VALID 64  /* Preceding substring is a valid fp number */\n#define PNG_FP_NEGATIVE 128  /* A negative number, including \"-0\" */\n#define PNG_FP_NONZERO  256  /* A non-zero value */\n#define PNG_FP_STICKY   448  /* The above three flags */\n\n/* This is available for the caller to store in 'state' if required.  Do not\n * call the parser after setting it (the parser sometimes clears it.)\n */\n#define PNG_FP_INVALID  512  /* Available for callers as a distinct value */\n\n/* Result codes for the parser (boolean - true meants ok, false means\n * not ok yet.)\n */\n#define PNG_FP_MAYBE      0  /* The number may be valid in the future */\n#define PNG_FP_OK         1  /* The number is valid */\n\n/* Tests on the sticky non-zero and negative flags.  To pass these checks\n * the state must also indicate that the whole number is valid - this is\n * achieved by testing PNG_FP_SAW_DIGIT (see the implementation for why this\n * is equivalent to PNG_FP_OK above.)\n */\n#define PNG_FP_NZ_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NEGATIVE | PNG_FP_NONZERO)\n   /* NZ_MASK: the string is valid and a non-zero negative value */\n#define PNG_FP_Z_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NONZERO)\n   /* Z MASK: the string is valid and a non-zero value. */\n   /* PNG_FP_SAW_DIGIT: the string is valid. */\n#define PNG_FP_IS_ZERO(state) (((state) & PNG_FP_Z_MASK) == PNG_FP_SAW_DIGIT)\n#define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK)\n#define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK)\n\n/* The actual parser.  This can be called repeatedly. It updates\n * the index into the string and the state variable (which must\n * be initialized to 0).  It returns a result code, as above.  There\n * is no point calling the parser any more if it fails to advance to\n * the end of the string - it is stuck on an invalid character (or\n * terminated by '\\0').\n *\n * Note that the pointer will consume an E or even an E+ and then leave\n * a 'maybe' state even though a preceding integer.fraction is valid.\n * The PNG_FP_WAS_VALID flag indicates that a preceding substring was\n * a valid number.  It's possible to recover from this by calling\n * the parser again (from the start, with state 0) but with a string\n * that omits the last character (i.e. set the size to the index of\n * the problem character.)  This has not been tested within libpng.\n */\nPNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string,\n   png_size_t size, int *statep, png_size_tp whereami),PNG_EMPTY);\n\n/* This is the same but it checks a complete string and returns true\n * only if it just contains a floating point number.  As of 1.5.4 this\n * function also returns the state at the end of parsing the number if\n * it was valid (otherwise it returns 0.)  This can be used for testing\n * for negative or zero values using the sticky flag.\n */\nPNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string,\n   png_size_t size),PNG_EMPTY);\n#endif /* pCAL || sCAL */\n\n#if defined(PNG_GAMMA_SUPPORTED) ||\\\n    defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)\n/* Added at libpng version 1.5.0 */\n/* This is a utility to provide a*times/div (rounded) and indicate\n * if there is an overflow.  The result is a boolean - false (0)\n * for overflow, true (1) if no overflow, in which case *res\n * holds the result.\n */\nPNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a,\n   png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY);\n#endif\n\n#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)\n/* Same deal, but issue a warning on overflow and return 0. */\nPNG_INTERNAL_FUNCTION(png_fixed_point,png_muldiv_warn,\n   (png_const_structrp png_ptr, png_fixed_point a, png_int_32 multiplied_by,\n   png_int_32 divided_by),PNG_EMPTY);\n#endif\n\n#ifdef PNG_GAMMA_SUPPORTED\n/* Calculate a reciprocal - used for gamma values.  This returns\n * 0 if the argument is 0 in order to maintain an undefined value;\n * there are no warnings.\n */\nPNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a),\n   PNG_EMPTY);\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\n/* The same but gives a reciprocal of the product of two fixed point\n * values.  Accuracy is suitable for gamma calculations but this is\n * not exact - use png_muldiv for that.  Only required at present on read.\n */\nPNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal2,(png_fixed_point a,\n   png_fixed_point b),PNG_EMPTY);\n#endif\n\n/* Return true if the gamma value is significantly different from 1.0 */\nPNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value),\n   PNG_EMPTY);\n#endif\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\n/* Internal fixed point gamma correction.  These APIs are called as\n * required to convert single values - they don't need to be fast,\n * they are not used when processing image pixel values.\n *\n * While the input is an 'unsigned' value it must actually be the\n * correct bit value - 0..255 or 0..65535 as required.\n */\nPNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_correct,(png_structrp png_ptr,\n   unsigned int value, png_fixed_point gamma_value),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,(unsigned int value,\n   png_fixed_point gamma_value),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(unsigned int value,\n   png_fixed_point gamma_value),PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr),\n   PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void,png_build_gamma_table,(png_structrp png_ptr,\n   int bit_depth),PNG_EMPTY);\n#endif\n\n/* SIMPLIFIED READ/WRITE SUPPORT */\n#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\\\n   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)\n/* The internal structure that png_image::opaque points to. */\ntypedef struct png_control\n{\n   png_structp png_ptr;\n   png_infop   info_ptr;\n   png_voidp   error_buf;           /* Always a jmp_buf at present. */\n\n   png_const_bytep memory;          /* Memory buffer. */\n   png_size_t      size;            /* Size of the memory buffer. */\n\n   unsigned int for_write       :1; /* Otherwise it is a read structure */\n   unsigned int owned_file      :1; /* We own the file in io_ptr */\n} png_control;\n\n/* Return the pointer to the jmp_buf from a png_control: necessary because C\n * does not reveal the type of the elements of jmp_buf.\n */\n#ifdef __cplusplus\n#  define png_control_jmp_buf(pc) (((jmp_buf*)((pc)->error_buf))[0])\n#else\n#  define png_control_jmp_buf(pc) ((pc)->error_buf)\n#endif\n\n/* Utility to safely execute a piece of libpng code catching and logging any\n * errors that might occur.  Returns true on success, false on failure (either\n * of the function or as a result of a png_error.)\n */\nPNG_INTERNAL_CALLBACK(void,png_safe_error,(png_structp png_ptr,\n   png_const_charp error_message),PNG_NORETURN);\n\n#ifdef PNG_WARNINGS_SUPPORTED\nPNG_INTERNAL_CALLBACK(void,png_safe_warning,(png_structp png_ptr,\n   png_const_charp warning_message),PNG_EMPTY);\n#else\n#  define png_safe_warning 0/*dummy argument*/\n#endif\n\nPNG_INTERNAL_FUNCTION(int,png_safe_execute,(png_imagep image,\n   int (*function)(png_voidp), png_voidp arg),PNG_EMPTY);\n\n/* Utility to log an error; this also cleans up the png_image; the function\n * always returns 0 (false).\n */\nPNG_INTERNAL_FUNCTION(int,png_image_error,(png_imagep image,\n   png_const_charp error_message),PNG_EMPTY);\n\n#ifndef PNG_SIMPLIFIED_READ_SUPPORTED\n/* png_image_free is used by the write code but not exported */\nPNG_INTERNAL_FUNCTION(void, png_image_free, (png_imagep image), PNG_EMPTY);\n#endif /* !SIMPLIFIED_READ */\n\n#endif /* SIMPLIFIED READ/WRITE */\n\n/* These are initialization functions for hardware specific PNG filter\n * optimizations; list these here then select the appropriate one at compile\n * time using the macro PNG_FILTER_OPTIMIZATIONS.  If the macro is not defined\n * the generic code is used.\n */\n#ifdef PNG_FILTER_OPTIMIZATIONS\nPNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr,\n   unsigned int bpp), PNG_EMPTY);\n   /* Just declare the optimization that will be used */\n#else\n   /* List *all* the possible optimizations here - this branch is required if\n    * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in\n    * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing.\n    */\nPNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,\n   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);\nPNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2,\n   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);\n#endif\n\nPNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,\n   png_const_charp key, png_bytep new_key), PNG_EMPTY);\n\n/* Maintainer: Put new private prototypes here ^ */\n\n#include \"pngdebug.h\"\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* PNG_VERSION_INFO_ONLY */\n#endif /* PNGPRIV_H */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngread.c",
    "content": "\n/* pngread.c - read a PNG file\n *\n * Last changed in libpng 1.6.17 [March 26, 2015]\n * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * This file contains routines that an application calls directly to\n * read a PNG file or stream.\n */\n\n#include \"pngpriv.h\"\n#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)\n#  include <errno.h>\n#endif\n\n#ifdef PNG_READ_SUPPORTED\n\n/* Create a PNG structure for reading, and allocate any memory needed. */\nPNG_FUNCTION(png_structp,PNGAPI\npng_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,\n    png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)\n{\n#ifndef PNG_USER_MEM_SUPPORTED\n   png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,\n      error_fn, warn_fn, NULL, NULL, NULL);\n#else\n   return png_create_read_struct_2(user_png_ver, error_ptr, error_fn,\n       warn_fn, NULL, NULL, NULL);\n}\n\n/* Alternate create PNG structure for reading, and allocate any memory\n * needed.\n */\nPNG_FUNCTION(png_structp,PNGAPI\npng_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,\n    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,\n    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)\n{\n   png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,\n      error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);\n#endif /* USER_MEM */\n\n   if (png_ptr != NULL)\n   {\n      png_ptr->mode = PNG_IS_READ_STRUCT;\n\n      /* Added in libpng-1.6.0; this can be used to detect a read structure if\n       * required (it will be zero in a write structure.)\n       */\n#     ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n         png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE;\n#     endif\n\n#     ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED\n         png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;\n\n         /* In stable builds only warn if an application error can be completely\n          * handled.\n          */\n#        if PNG_RELEASE_BUILD\n            png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;\n#        endif\n#     endif\n\n      /* TODO: delay this, it can be done in png_init_io (if the app doesn't\n       * do it itself) avoiding setting the default function if it is not\n       * required.\n       */\n      png_set_read_fn(png_ptr, NULL, NULL);\n   }\n\n   return png_ptr;\n}\n\n\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n/* Read the information before the actual image data.  This has been\n * changed in v0.90 to allow reading a file that already has the magic\n * bytes read from the stream.  You can tell libpng how many bytes have\n * been read from the beginning of the stream (up to the maximum of 8)\n * via png_set_sig_bytes(), and we will only check the remaining bytes\n * here.  The application can then have access to the signature bytes we\n * read if it is determined that this isn't a valid PNG file.\n */\nvoid PNGAPI\npng_read_info(png_structrp png_ptr, png_inforp info_ptr)\n{\n#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED\n   int keep;\n#endif\n\n   png_debug(1, \"in png_read_info\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   /* Read and check the PNG file signature. */\n   png_read_sig(png_ptr, info_ptr);\n\n   for (;;)\n   {\n      png_uint_32 length = png_read_chunk_header(png_ptr);\n      png_uint_32 chunk_name = png_ptr->chunk_name;\n\n      /* IDAT logic needs to happen here to simplify getting the two flags\n       * right.\n       */\n      if (chunk_name == png_IDAT)\n      {\n         if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n            png_chunk_error(png_ptr, \"Missing IHDR before IDAT\");\n\n         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&\n             (png_ptr->mode & PNG_HAVE_PLTE) == 0)\n            png_chunk_error(png_ptr, \"Missing PLTE before IDAT\");\n\n         else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)\n            png_chunk_benign_error(png_ptr, \"Too many IDATs found\");\n\n         png_ptr->mode |= PNG_HAVE_IDAT;\n      }\n\n      else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)\n         png_ptr->mode |= PNG_AFTER_IDAT;\n\n      /* This should be a binary subdivision search or a hash for\n       * matching the chunk name rather than a linear search.\n       */\n      if (chunk_name == png_IHDR)\n         png_handle_IHDR(png_ptr, info_ptr, length);\n\n      else if (chunk_name == png_IEND)\n         png_handle_IEND(png_ptr, info_ptr, length);\n\n#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED\n      else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)\n      {\n         png_handle_unknown(png_ptr, info_ptr, length, keep);\n\n         if (chunk_name == png_PLTE)\n            png_ptr->mode |= PNG_HAVE_PLTE;\n\n         else if (chunk_name == png_IDAT)\n         {\n            png_ptr->idat_size = 0; /* It has been consumed */\n            break;\n         }\n      }\n#endif\n      else if (chunk_name == png_PLTE)\n         png_handle_PLTE(png_ptr, info_ptr, length);\n\n      else if (chunk_name == png_IDAT)\n      {\n         png_ptr->idat_size = length;\n         break;\n      }\n\n#ifdef PNG_READ_bKGD_SUPPORTED\n      else if (chunk_name == png_bKGD)\n         png_handle_bKGD(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_cHRM_SUPPORTED\n      else if (chunk_name == png_cHRM)\n         png_handle_cHRM(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_gAMA_SUPPORTED\n      else if (chunk_name == png_gAMA)\n         png_handle_gAMA(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_hIST_SUPPORTED\n      else if (chunk_name == png_hIST)\n         png_handle_hIST(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_oFFs_SUPPORTED\n      else if (chunk_name == png_oFFs)\n         png_handle_oFFs(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_pCAL_SUPPORTED\n      else if (chunk_name == png_pCAL)\n         png_handle_pCAL(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_sCAL_SUPPORTED\n      else if (chunk_name == png_sCAL)\n         png_handle_sCAL(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_pHYs_SUPPORTED\n      else if (chunk_name == png_pHYs)\n         png_handle_pHYs(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_sBIT_SUPPORTED\n      else if (chunk_name == png_sBIT)\n         png_handle_sBIT(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_sRGB_SUPPORTED\n      else if (chunk_name == png_sRGB)\n         png_handle_sRGB(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_iCCP_SUPPORTED\n      else if (chunk_name == png_iCCP)\n         png_handle_iCCP(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_sPLT_SUPPORTED\n      else if (chunk_name == png_sPLT)\n         png_handle_sPLT(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_tEXt_SUPPORTED\n      else if (chunk_name == png_tEXt)\n         png_handle_tEXt(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_tIME_SUPPORTED\n      else if (chunk_name == png_tIME)\n         png_handle_tIME(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_tRNS_SUPPORTED\n      else if (chunk_name == png_tRNS)\n         png_handle_tRNS(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_zTXt_SUPPORTED\n      else if (chunk_name == png_zTXt)\n         png_handle_zTXt(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_iTXt_SUPPORTED\n      else if (chunk_name == png_iTXt)\n         png_handle_iTXt(png_ptr, info_ptr, length);\n#endif\n\n      else\n         png_handle_unknown(png_ptr, info_ptr, length,\n            PNG_HANDLE_CHUNK_AS_DEFAULT);\n   }\n}\n#endif /* SEQUENTIAL_READ */\n\n/* Optional call to update the users info_ptr structure */\nvoid PNGAPI\npng_read_update_info(png_structrp png_ptr, png_inforp info_ptr)\n{\n   png_debug(1, \"in png_read_update_info\");\n\n   if (png_ptr != NULL)\n   {\n      if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)\n      {\n         png_read_start_row(png_ptr);\n\n#        ifdef PNG_READ_TRANSFORMS_SUPPORTED\n            png_read_transform_info(png_ptr, info_ptr);\n#        else\n            PNG_UNUSED(info_ptr)\n#        endif\n      }\n\n      /* New in 1.6.0 this avoids the bug of doing the initializations twice */\n      else\n         png_app_error(png_ptr,\n            \"png_read_update_info/png_start_read_image: duplicate call\");\n   }\n}\n\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n/* Initialize palette, background, etc, after transformations\n * are set, but before any reading takes place.  This allows\n * the user to obtain a gamma-corrected palette, for example.\n * If the user doesn't call this, we will do it ourselves.\n */\nvoid PNGAPI\npng_start_read_image(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_start_read_image\");\n\n   if (png_ptr != NULL)\n   {\n      if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)\n         png_read_start_row(png_ptr);\n\n      /* New in 1.6.0 this avoids the bug of doing the initializations twice */\n      else\n         png_app_error(png_ptr,\n            \"png_start_read_image/png_read_update_info: duplicate call\");\n   }\n}\n#endif /* SEQUENTIAL_READ */\n\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n#ifdef PNG_MNG_FEATURES_SUPPORTED\n/* Undoes intrapixel differencing,\n * NOTE: this is apparently only supported in the 'sequential' reader.\n */\nstatic void\npng_do_read_intrapixel(png_row_infop row_info, png_bytep row)\n{\n   png_debug(1, \"in png_do_read_intrapixel\");\n\n   if (\n       (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)\n   {\n      int bytes_per_pixel;\n      png_uint_32 row_width = row_info->width;\n\n      if (row_info->bit_depth == 8)\n      {\n         png_bytep rp;\n         png_uint_32 i;\n\n         if (row_info->color_type == PNG_COLOR_TYPE_RGB)\n            bytes_per_pixel = 3;\n\n         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n            bytes_per_pixel = 4;\n\n         else\n            return;\n\n         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)\n         {\n            *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);\n            *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);\n         }\n      }\n      else if (row_info->bit_depth == 16)\n      {\n         png_bytep rp;\n         png_uint_32 i;\n\n         if (row_info->color_type == PNG_COLOR_TYPE_RGB)\n            bytes_per_pixel = 6;\n\n         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n            bytes_per_pixel = 8;\n\n         else\n            return;\n\n         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)\n         {\n            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);\n            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);\n            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);\n            png_uint_32 red  = (s0 + s1 + 65536) & 0xffff;\n            png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;\n            *(rp    ) = (png_byte)((red >> 8) & 0xff);\n            *(rp + 1) = (png_byte)(red & 0xff);\n            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);\n            *(rp + 5) = (png_byte)(blue & 0xff);\n         }\n      }\n   }\n}\n#endif /* MNG_FEATURES */\n\nvoid PNGAPI\npng_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)\n{\n   png_row_info row_info;\n\n   if (png_ptr == NULL)\n      return;\n\n   png_debug2(1, \"in png_read_row (row %lu, pass %d)\",\n       (unsigned long)png_ptr->row_number, png_ptr->pass);\n\n   /* png_read_start_row sets the information (in particular iwidth) for this\n    * interlace pass.\n    */\n   if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)\n      png_read_start_row(png_ptr);\n\n   /* 1.5.6: row_info moved out of png_struct to a local here. */\n   row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */\n   row_info.color_type = png_ptr->color_type;\n   row_info.bit_depth = png_ptr->bit_depth;\n   row_info.channels = png_ptr->channels;\n   row_info.pixel_depth = png_ptr->pixel_depth;\n   row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);\n\n#ifdef PNG_WARNINGS_SUPPORTED\n   if (png_ptr->row_number == 0 && png_ptr->pass == 0)\n   {\n   /* Check for transforms that have been set but were defined out */\n#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)\n   if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)\n      png_warning(png_ptr, \"PNG_READ_INVERT_SUPPORTED is not defined\");\n#endif\n\n#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)\n   if ((png_ptr->transformations & PNG_FILLER) != 0)\n      png_warning(png_ptr, \"PNG_READ_FILLER_SUPPORTED is not defined\");\n#endif\n\n#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \\\n    !defined(PNG_READ_PACKSWAP_SUPPORTED)\n   if ((png_ptr->transformations & PNG_PACKSWAP) != 0)\n      png_warning(png_ptr, \"PNG_READ_PACKSWAP_SUPPORTED is not defined\");\n#endif\n\n#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)\n   if ((png_ptr->transformations & PNG_PACK) != 0)\n      png_warning(png_ptr, \"PNG_READ_PACK_SUPPORTED is not defined\");\n#endif\n\n#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)\n   if ((png_ptr->transformations & PNG_SHIFT) != 0)\n      png_warning(png_ptr, \"PNG_READ_SHIFT_SUPPORTED is not defined\");\n#endif\n\n#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)\n   if ((png_ptr->transformations & PNG_BGR) != 0)\n      png_warning(png_ptr, \"PNG_READ_BGR_SUPPORTED is not defined\");\n#endif\n\n#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)\n   if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)\n      png_warning(png_ptr, \"PNG_READ_SWAP_SUPPORTED is not defined\");\n#endif\n   }\n#endif /* WARNINGS */\n\n#ifdef PNG_READ_INTERLACING_SUPPORTED\n   /* If interlaced and we do not need a new row, combine row and return.\n    * Notice that the pixels we have from previous rows have been transformed\n    * already; we can only combine like with like (transformed or\n    * untransformed) and, because of the libpng API for interlaced images, this\n    * means we must transform before de-interlacing.\n    */\n   if (png_ptr->interlaced != 0 &&\n       (png_ptr->transformations & PNG_INTERLACE) != 0)\n   {\n      switch (png_ptr->pass)\n      {\n         case 0:\n            if (png_ptr->row_number & 0x07)\n            {\n               if (dsp_row != NULL)\n                  png_combine_row(png_ptr, dsp_row, 1/*display*/);\n               png_read_finish_row(png_ptr);\n               return;\n            }\n            break;\n\n         case 1:\n            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)\n            {\n               if (dsp_row != NULL)\n                  png_combine_row(png_ptr, dsp_row, 1/*display*/);\n\n               png_read_finish_row(png_ptr);\n               return;\n            }\n            break;\n\n         case 2:\n            if ((png_ptr->row_number & 0x07) != 4)\n            {\n               if (dsp_row != NULL && (png_ptr->row_number & 4))\n                  png_combine_row(png_ptr, dsp_row, 1/*display*/);\n\n               png_read_finish_row(png_ptr);\n               return;\n            }\n            break;\n\n         case 3:\n            if ((png_ptr->row_number & 3) || png_ptr->width < 3)\n            {\n               if (dsp_row != NULL)\n                  png_combine_row(png_ptr, dsp_row, 1/*display*/);\n\n               png_read_finish_row(png_ptr);\n               return;\n            }\n            break;\n\n         case 4:\n            if ((png_ptr->row_number & 3) != 2)\n            {\n               if (dsp_row != NULL && (png_ptr->row_number & 2))\n                  png_combine_row(png_ptr, dsp_row, 1/*display*/);\n\n               png_read_finish_row(png_ptr);\n               return;\n            }\n            break;\n\n         case 5:\n            if ((png_ptr->row_number & 1) || png_ptr->width < 2)\n            {\n               if (dsp_row != NULL)\n                  png_combine_row(png_ptr, dsp_row, 1/*display*/);\n\n               png_read_finish_row(png_ptr);\n               return;\n            }\n            break;\n\n         default:\n         case 6:\n            if ((png_ptr->row_number & 1) == 0)\n            {\n               png_read_finish_row(png_ptr);\n               return;\n            }\n            break;\n      }\n   }\n#endif\n\n   if ((png_ptr->mode & PNG_HAVE_IDAT) == 0)\n      png_error(png_ptr, \"Invalid attempt to read row data\");\n\n   /* Fill the row with IDAT data: */\n   png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1);\n\n   if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)\n   {\n      if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)\n         png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,\n            png_ptr->prev_row + 1, png_ptr->row_buf[0]);\n      else\n         png_error(png_ptr, \"bad adaptive filter value\");\n   }\n\n   /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before\n    * 1.5.6, while the buffer really is this big in current versions of libpng\n    * it may not be in the future, so this was changed just to copy the\n    * interlaced count:\n    */\n   memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);\n\n#ifdef PNG_MNG_FEATURES_SUPPORTED\n   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&\n       (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))\n   {\n      /* Intrapixel differencing */\n      png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1);\n   }\n#endif\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\n   if (png_ptr->transformations)\n      png_do_read_transformations(png_ptr, &row_info);\n#endif\n\n   /* The transformed pixel depth should match the depth now in row_info. */\n   if (png_ptr->transformed_pixel_depth == 0)\n   {\n      png_ptr->transformed_pixel_depth = row_info.pixel_depth;\n      if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)\n         png_error(png_ptr, \"sequential row overflow\");\n   }\n\n   else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)\n      png_error(png_ptr, \"internal sequential row size calculation error\");\n\n#ifdef PNG_READ_INTERLACING_SUPPORTED\n   /* Expand interlaced rows to full size */\n   if (png_ptr->interlaced != 0 &&\n      (png_ptr->transformations & PNG_INTERLACE) != 0)\n   {\n      if (png_ptr->pass < 6)\n         png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,\n            png_ptr->transformations);\n\n      if (dsp_row != NULL)\n         png_combine_row(png_ptr, dsp_row, 1/*display*/);\n\n      if (row != NULL)\n         png_combine_row(png_ptr, row, 0/*row*/);\n   }\n\n   else\n#endif\n   {\n      if (row != NULL)\n         png_combine_row(png_ptr, row, -1/*ignored*/);\n\n      if (dsp_row != NULL)\n         png_combine_row(png_ptr, dsp_row, -1/*ignored*/);\n   }\n   png_read_finish_row(png_ptr);\n\n   if (png_ptr->read_row_fn != NULL)\n      (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);\n\n}\n#endif /* SEQUENTIAL_READ */\n\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n/* Read one or more rows of image data.  If the image is interlaced,\n * and png_set_interlace_handling() has been called, the rows need to\n * contain the contents of the rows from the previous pass.  If the\n * image has alpha or transparency, and png_handle_alpha()[*] has been\n * called, the rows contents must be initialized to the contents of the\n * screen.\n *\n * \"row\" holds the actual image, and pixels are placed in it\n * as they arrive.  If the image is displayed after each pass, it will\n * appear to \"sparkle\" in.  \"display_row\" can be used to display a\n * \"chunky\" progressive image, with finer detail added as it becomes\n * available.  If you do not want this \"chunky\" display, you may pass\n * NULL for display_row.  If you do not want the sparkle display, and\n * you have not called png_handle_alpha(), you may pass NULL for rows.\n * If you have called png_handle_alpha(), and the image has either an\n * alpha channel or a transparency chunk, you must provide a buffer for\n * rows.  In this case, you do not have to provide a display_row buffer\n * also, but you may.  If the image is not interlaced, or if you have\n * not called png_set_interlace_handling(), the display_row buffer will\n * be ignored, so pass NULL to it.\n *\n * [*] png_handle_alpha() does not exist yet, as of this version of libpng\n */\n\nvoid PNGAPI\npng_read_rows(png_structrp png_ptr, png_bytepp row,\n    png_bytepp display_row, png_uint_32 num_rows)\n{\n   png_uint_32 i;\n   png_bytepp rp;\n   png_bytepp dp;\n\n   png_debug(1, \"in png_read_rows\");\n\n   if (png_ptr == NULL)\n      return;\n\n   rp = row;\n   dp = display_row;\n   if (rp != NULL && dp != NULL)\n      for (i = 0; i < num_rows; i++)\n      {\n         png_bytep rptr = *rp++;\n         png_bytep dptr = *dp++;\n\n         png_read_row(png_ptr, rptr, dptr);\n      }\n\n   else if (rp != NULL)\n      for (i = 0; i < num_rows; i++)\n      {\n         png_bytep rptr = *rp;\n         png_read_row(png_ptr, rptr, NULL);\n         rp++;\n      }\n\n   else if (dp != NULL)\n      for (i = 0; i < num_rows; i++)\n      {\n         png_bytep dptr = *dp;\n         png_read_row(png_ptr, NULL, dptr);\n         dp++;\n      }\n}\n#endif /* SEQUENTIAL_READ */\n\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n/* Read the entire image.  If the image has an alpha channel or a tRNS\n * chunk, and you have called png_handle_alpha()[*], you will need to\n * initialize the image to the current image that PNG will be overlaying.\n * We set the num_rows again here, in case it was incorrectly set in\n * png_read_start_row() by a call to png_read_update_info() or\n * png_start_read_image() if png_set_interlace_handling() wasn't called\n * prior to either of these functions like it should have been.  You can\n * only call this function once.  If you desire to have an image for\n * each pass of a interlaced image, use png_read_rows() instead.\n *\n * [*] png_handle_alpha() does not exist yet, as of this version of libpng\n */\nvoid PNGAPI\npng_read_image(png_structrp png_ptr, png_bytepp image)\n{\n   png_uint_32 i, image_height;\n   int pass, j;\n   png_bytepp rp;\n\n   png_debug(1, \"in png_read_image\");\n\n   if (png_ptr == NULL)\n      return;\n\n#ifdef PNG_READ_INTERLACING_SUPPORTED\n   if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)\n   {\n      pass = png_set_interlace_handling(png_ptr);\n      /* And make sure transforms are initialized. */\n      png_start_read_image(png_ptr);\n   }\n   else\n   {\n      if (png_ptr->interlaced != 0 &&\n          (png_ptr->transformations & PNG_INTERLACE) == 0)\n      {\n         /* Caller called png_start_read_image or png_read_update_info without\n          * first turning on the PNG_INTERLACE transform.  We can fix this here,\n          * but the caller should do it!\n          */\n         png_warning(png_ptr, \"Interlace handling should be turned on when \"\n            \"using png_read_image\");\n         /* Make sure this is set correctly */\n         png_ptr->num_rows = png_ptr->height;\n      }\n\n      /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in\n       * the above error case.\n       */\n      pass = png_set_interlace_handling(png_ptr);\n   }\n#else\n   if (png_ptr->interlaced)\n      png_error(png_ptr,\n          \"Cannot read interlaced image -- interlace handler disabled\");\n\n   pass = 1;\n#endif\n\n   image_height=png_ptr->height;\n\n   for (j = 0; j < pass; j++)\n   {\n      rp = image;\n      for (i = 0; i < image_height; i++)\n      {\n         png_read_row(png_ptr, *rp, NULL);\n         rp++;\n      }\n   }\n}\n#endif /* SEQUENTIAL_READ */\n\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n/* Read the end of the PNG file.  Will not read past the end of the\n * file, will verify the end is accurate, and will read any comments\n * or time information at the end of the file, if info is not NULL.\n */\nvoid PNGAPI\npng_read_end(png_structrp png_ptr, png_inforp info_ptr)\n{\n#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED\n   int keep;\n#endif\n\n   png_debug(1, \"in png_read_end\");\n\n   if (png_ptr == NULL)\n      return;\n\n   /* If png_read_end is called in the middle of reading the rows there may\n    * still be pending IDAT data and an owned zstream.  Deal with this here.\n    */\n#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED\n   if (png_chunk_unknown_handling(png_ptr, png_IDAT) == 0)\n#endif\n      png_read_finish_IDAT(png_ptr);\n\n#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED\n   /* Report invalid palette index; added at libng-1.5.10 */\n   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&\n      png_ptr->num_palette_max > png_ptr->num_palette)\n     png_benign_error(png_ptr, \"Read palette index exceeding num_palette\");\n#endif\n\n   do\n   {\n      png_uint_32 length = png_read_chunk_header(png_ptr);\n      png_uint_32 chunk_name = png_ptr->chunk_name;\n\n      if (chunk_name == png_IEND)\n         png_handle_IEND(png_ptr, info_ptr, length);\n\n      else if (chunk_name == png_IHDR)\n         png_handle_IHDR(png_ptr, info_ptr, length);\n\n      else if (info_ptr == NULL)\n         png_crc_finish(png_ptr, length);\n\n#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED\n      else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)\n      {\n         if (chunk_name == png_IDAT)\n         {\n            if ((length > 0) ||\n                (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)\n               png_benign_error(png_ptr, \"Too many IDATs found\");\n         }\n         png_handle_unknown(png_ptr, info_ptr, length, keep);\n         if (chunk_name == png_PLTE)\n            png_ptr->mode |= PNG_HAVE_PLTE;\n      }\n#endif\n\n      else if (chunk_name == png_IDAT)\n      {\n         /* Zero length IDATs are legal after the last IDAT has been\n          * read, but not after other chunks have been read.\n          */\n         if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)\n            png_benign_error(png_ptr, \"Too many IDATs found\");\n\n         png_crc_finish(png_ptr, length);\n      }\n      else if (chunk_name == png_PLTE)\n         png_handle_PLTE(png_ptr, info_ptr, length);\n\n#ifdef PNG_READ_bKGD_SUPPORTED\n      else if (chunk_name == png_bKGD)\n         png_handle_bKGD(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_cHRM_SUPPORTED\n      else if (chunk_name == png_cHRM)\n         png_handle_cHRM(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_gAMA_SUPPORTED\n      else if (chunk_name == png_gAMA)\n         png_handle_gAMA(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_hIST_SUPPORTED\n      else if (chunk_name == png_hIST)\n         png_handle_hIST(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_oFFs_SUPPORTED\n      else if (chunk_name == png_oFFs)\n         png_handle_oFFs(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_pCAL_SUPPORTED\n      else if (chunk_name == png_pCAL)\n         png_handle_pCAL(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_sCAL_SUPPORTED\n      else if (chunk_name == png_sCAL)\n         png_handle_sCAL(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_pHYs_SUPPORTED\n      else if (chunk_name == png_pHYs)\n         png_handle_pHYs(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_sBIT_SUPPORTED\n      else if (chunk_name == png_sBIT)\n         png_handle_sBIT(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_sRGB_SUPPORTED\n      else if (chunk_name == png_sRGB)\n         png_handle_sRGB(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_iCCP_SUPPORTED\n      else if (chunk_name == png_iCCP)\n         png_handle_iCCP(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_sPLT_SUPPORTED\n      else if (chunk_name == png_sPLT)\n         png_handle_sPLT(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_tEXt_SUPPORTED\n      else if (chunk_name == png_tEXt)\n         png_handle_tEXt(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_tIME_SUPPORTED\n      else if (chunk_name == png_tIME)\n         png_handle_tIME(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_tRNS_SUPPORTED\n      else if (chunk_name == png_tRNS)\n         png_handle_tRNS(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_zTXt_SUPPORTED\n      else if (chunk_name == png_zTXt)\n         png_handle_zTXt(png_ptr, info_ptr, length);\n#endif\n\n#ifdef PNG_READ_iTXt_SUPPORTED\n      else if (chunk_name == png_iTXt)\n         png_handle_iTXt(png_ptr, info_ptr, length);\n#endif\n\n      else\n         png_handle_unknown(png_ptr, info_ptr, length,\n            PNG_HANDLE_CHUNK_AS_DEFAULT);\n   } while ((png_ptr->mode & PNG_HAVE_IEND) == 0);\n}\n#endif /* SEQUENTIAL_READ */\n\n/* Free all memory used in the read struct */\nstatic void\npng_read_destroy(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_read_destroy\");\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\n   png_destroy_gamma_table(png_ptr);\n#endif\n\n   png_free(png_ptr, png_ptr->big_row_buf);\n   png_ptr->big_row_buf = NULL;\n   png_free(png_ptr, png_ptr->big_prev_row);\n   png_ptr->big_prev_row = NULL;\n   png_free(png_ptr, png_ptr->read_buffer);\n   png_ptr->read_buffer = NULL;\n\n#ifdef PNG_READ_QUANTIZE_SUPPORTED\n   png_free(png_ptr, png_ptr->palette_lookup);\n   png_ptr->palette_lookup = NULL;\n   png_free(png_ptr, png_ptr->quantize_index);\n   png_ptr->quantize_index = NULL;\n#endif\n\n   if ((png_ptr->free_me & PNG_FREE_PLTE) != 0)\n   {\n      png_zfree(png_ptr, png_ptr->palette);\n      png_ptr->palette = NULL;\n   }\n   png_ptr->free_me &= ~PNG_FREE_PLTE;\n\n#if defined(PNG_tRNS_SUPPORTED) || \\\n    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)\n   if ((png_ptr->free_me & PNG_FREE_TRNS) != 0)\n   {\n      png_free(png_ptr, png_ptr->trans_alpha);\n      png_ptr->trans_alpha = NULL;\n   }\n   png_ptr->free_me &= ~PNG_FREE_TRNS;\n#endif\n\n   inflateEnd(&png_ptr->zstream);\n\n#ifdef PNG_PROGRESSIVE_READ_SUPPORTED\n   png_free(png_ptr, png_ptr->save_buffer);\n   png_ptr->save_buffer = NULL;\n#endif\n\n#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) && \\\n   defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)\n   png_free(png_ptr, png_ptr->unknown_chunk.data);\n   png_ptr->unknown_chunk.data = NULL;\n#endif\n\n#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED\n   png_free(png_ptr, png_ptr->chunk_list);\n   png_ptr->chunk_list = NULL;\n#endif\n\n   /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error\n    * callbacks are still set at this point.  They are required to complete the\n    * destruction of the png_struct itself.\n    */\n}\n\n/* Free all memory used by the read */\nvoid PNGAPI\npng_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,\n    png_infopp end_info_ptr_ptr)\n{\n   png_structrp png_ptr = NULL;\n\n   png_debug(1, \"in png_destroy_read_struct\");\n\n   if (png_ptr_ptr != NULL)\n      png_ptr = *png_ptr_ptr;\n\n   if (png_ptr == NULL)\n      return;\n\n   /* libpng 1.6.0: use the API to destroy info structs to ensure consistent\n    * behavior.  Prior to 1.6.0 libpng did extra 'info' destruction in this API.\n    * The extra was, apparently, unnecessary yet this hides memory leak bugs.\n    */\n   png_destroy_info_struct(png_ptr, end_info_ptr_ptr);\n   png_destroy_info_struct(png_ptr, info_ptr_ptr);\n\n   *png_ptr_ptr = NULL;\n   png_read_destroy(png_ptr);\n   png_destroy_png_struct(png_ptr);\n}\n\nvoid PNGAPI\npng_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn)\n{\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->read_row_fn = read_row_fn;\n}\n\n\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n#ifdef PNG_INFO_IMAGE_SUPPORTED\nvoid PNGAPI\npng_read_png(png_structrp png_ptr, png_inforp info_ptr,\n                           int transforms,\n                           voidp params)\n{\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   /* png_read_info() gives us all of the information from the\n    * PNG file before the first IDAT (image data chunk).\n    */\n   png_read_info(png_ptr, info_ptr);\n   if (info_ptr->height > PNG_UINT_32_MAX/(sizeof (png_bytep)))\n      png_error(png_ptr, \"Image is too high to process with png_read_png()\");\n\n   /* -------------- image transformations start here ------------------- */\n   /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM\n    * is not implemented.  This will only happen in de-configured (non-default)\n    * libpng builds.  The results can be unexpected - png_read_png may return\n    * short or mal-formed rows because the transform is skipped.\n    */\n\n   /* Tell libpng to strip 16-bit/color files down to 8 bits per color.\n    */\n   if ((transforms & PNG_TRANSFORM_SCALE_16) != 0)\n      /* Added at libpng-1.5.4. \"strip_16\" produces the same result that it\n       * did in earlier versions, while \"scale_16\" is now more accurate.\n       */\n#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\n      png_set_scale_16(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_SCALE_16 not supported\");\n#endif\n\n   /* If both SCALE and STRIP are required pngrtran will effectively cancel the\n    * latter by doing SCALE first.  This is ok and allows apps not to check for\n    * which is supported to get the right answer.\n    */\n   if ((transforms & PNG_TRANSFORM_STRIP_16) != 0)\n#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED\n      png_set_strip_16(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_STRIP_16 not supported\");\n#endif\n\n   /* Strip alpha bytes from the input data without combining with\n    * the background (not recommended).\n    */\n   if ((transforms & PNG_TRANSFORM_STRIP_ALPHA) != 0)\n#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED\n      png_set_strip_alpha(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_STRIP_ALPHA not supported\");\n#endif\n\n   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single\n    * byte into separate bytes (useful for paletted and grayscale images).\n    */\n   if ((transforms & PNG_TRANSFORM_PACKING) != 0)\n#ifdef PNG_READ_PACK_SUPPORTED\n      png_set_packing(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_PACKING not supported\");\n#endif\n\n   /* Change the order of packed pixels to least significant bit first\n    * (not useful if you are using png_set_packing).\n    */\n   if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0)\n#ifdef PNG_READ_PACKSWAP_SUPPORTED\n      png_set_packswap(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_PACKSWAP not supported\");\n#endif\n\n   /* Expand paletted colors into true RGB triplets\n    * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel\n    * Expand paletted or RGB images with transparency to full alpha\n    * channels so the data will be available as RGBA quartets.\n    */\n   if ((transforms & PNG_TRANSFORM_EXPAND) != 0)\n#ifdef PNG_READ_EXPAND_SUPPORTED\n      png_set_expand(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_EXPAND not supported\");\n#endif\n\n   /* We don't handle background color or gamma transformation or quantizing.\n    */\n\n   /* Invert monochrome files to have 0 as white and 1 as black\n    */\n   if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0)\n#ifdef PNG_READ_INVERT_SUPPORTED\n      png_set_invert_mono(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_INVERT_MONO not supported\");\n#endif\n\n   /* If you want to shift the pixel values from the range [0,255] or\n    * [0,65535] to the original [0,7] or [0,31], or whatever range the\n    * colors were originally in:\n    */\n   if ((transforms & PNG_TRANSFORM_SHIFT) != 0)\n#ifdef PNG_READ_SHIFT_SUPPORTED\n      if ((info_ptr->valid & PNG_INFO_sBIT) != 0)\n         png_set_shift(png_ptr, &info_ptr->sig_bit);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_SHIFT not supported\");\n#endif\n\n   /* Flip the RGB pixels to BGR (or RGBA to BGRA) */\n   if ((transforms & PNG_TRANSFORM_BGR) != 0)\n#ifdef PNG_READ_BGR_SUPPORTED\n      png_set_bgr(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_BGR not supported\");\n#endif\n\n   /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */\n   if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0)\n#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED\n      png_set_swap_alpha(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_SWAP_ALPHA not supported\");\n#endif\n\n   /* Swap bytes of 16-bit files to least significant byte first */\n   if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0)\n#ifdef PNG_READ_SWAP_SUPPORTED\n      png_set_swap(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_SWAP_ENDIAN not supported\");\n#endif\n\n/* Added at libpng-1.2.41 */\n   /* Invert the alpha channel from opacity to transparency */\n   if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0)\n#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED\n      png_set_invert_alpha(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_INVERT_ALPHA not supported\");\n#endif\n\n/* Added at libpng-1.2.41 */\n   /* Expand grayscale image to RGB */\n   if ((transforms & PNG_TRANSFORM_GRAY_TO_RGB) != 0)\n#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\n      png_set_gray_to_rgb(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_GRAY_TO_RGB not supported\");\n#endif\n\n/* Added at libpng-1.5.4 */\n   if ((transforms & PNG_TRANSFORM_EXPAND_16) != 0)\n#ifdef PNG_READ_EXPAND_16_SUPPORTED\n      png_set_expand_16(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_EXPAND_16 not supported\");\n#endif\n\n   /* We don't handle adding filler bytes */\n\n   /* We use png_read_image and rely on that for interlace handling, but we also\n    * call png_read_update_info therefore must turn on interlace handling now:\n    */\n   (void)png_set_interlace_handling(png_ptr);\n\n   /* Optional call to gamma correct and add the background to the palette\n    * and update info structure.  REQUIRED if you are expecting libpng to\n    * update the palette for you (i.e., you selected such a transform above).\n    */\n   png_read_update_info(png_ptr, info_ptr);\n\n   /* -------------- image transformations end here ------------------- */\n\n   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);\n   if (info_ptr->row_pointers == NULL)\n   {\n      png_uint_32 iptr;\n\n      info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr,\n          info_ptr->height * (sizeof (png_bytep))));\n\n      for (iptr=0; iptr<info_ptr->height; iptr++)\n         info_ptr->row_pointers[iptr] = NULL;\n\n      info_ptr->free_me |= PNG_FREE_ROWS;\n\n      for (iptr = 0; iptr < info_ptr->height; iptr++)\n         info_ptr->row_pointers[iptr] = png_voidcast(png_bytep,\n             png_malloc(png_ptr, info_ptr->rowbytes));\n   }\n\n   png_read_image(png_ptr, info_ptr->row_pointers);\n   info_ptr->valid |= PNG_INFO_IDAT;\n\n   /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */\n   png_read_end(png_ptr, info_ptr);\n\n   PNG_UNUSED(params)\n}\n#endif /* INFO_IMAGE */\n#endif /* SEQUENTIAL_READ */\n\n#ifdef PNG_SIMPLIFIED_READ_SUPPORTED\n/* SIMPLIFIED READ\n *\n * This code currently relies on the sequential reader, though it could easily\n * be made to work with the progressive one.\n */\n/* Arguments to png_image_finish_read: */\n\n/* Encoding of PNG data (used by the color-map code) */\n#  define P_NOTSET  0 /* File encoding not yet known */\n#  define P_sRGB    1 /* 8-bit encoded to sRGB gamma */\n#  define P_LINEAR  2 /* 16-bit linear: not encoded, NOT pre-multiplied! */\n#  define P_FILE    3 /* 8-bit encoded to file gamma, not sRGB or linear */\n#  define P_LINEAR8 4 /* 8-bit linear: only from a file value */\n\n/* Color-map processing: after libpng has run on the PNG image further\n * processing may be needed to convert the data to color-map indices.\n */\n#define PNG_CMAP_NONE      0\n#define PNG_CMAP_GA        1 /* Process GA data to a color-map with alpha */\n#define PNG_CMAP_TRANS     2 /* Process GA data to a background index */\n#define PNG_CMAP_RGB       3 /* Process RGB data */\n#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */\n\n/* The following document where the background is for each processing case. */\n#define PNG_CMAP_NONE_BACKGROUND      256\n#define PNG_CMAP_GA_BACKGROUND        231\n#define PNG_CMAP_TRANS_BACKGROUND     254\n#define PNG_CMAP_RGB_BACKGROUND       256\n#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216\n\ntypedef struct\n{\n   /* Arguments: */\n   png_imagep image;\n   png_voidp  buffer;\n   png_int_32 row_stride;\n   png_voidp  colormap;\n   png_const_colorp background;\n   /* Local variables: */\n   png_voidp       local_row;\n   png_voidp       first_row;\n   ptrdiff_t       row_bytes;           /* step between rows */\n   int             file_encoding;       /* E_ values above */\n   png_fixed_point gamma_to_linear;     /* For P_FILE, reciprocal of gamma */\n   int             colormap_processing; /* PNG_CMAP_ values above */\n} png_image_read_control;\n\n/* Do all the *safe* initialization - 'safe' means that png_error won't be\n * called, so setting up the jmp_buf is not required.  This means that anything\n * called from here must *not* call png_malloc - it has to call png_malloc_warn\n * instead so that control is returned safely back to this routine.\n */\nstatic int\npng_image_read_init(png_imagep image)\n{\n   if (image->opaque == NULL)\n   {\n      png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image,\n          png_safe_error, png_safe_warning);\n\n      /* And set the rest of the structure to NULL to ensure that the various\n       * fields are consistent.\n       */\n      memset(image, 0, (sizeof *image));\n      image->version = PNG_IMAGE_VERSION;\n\n      if (png_ptr != NULL)\n      {\n         png_infop info_ptr = png_create_info_struct(png_ptr);\n\n         if (info_ptr != NULL)\n         {\n            png_controlp control = png_voidcast(png_controlp,\n               png_malloc_warn(png_ptr, (sizeof *control)));\n\n            if (control != NULL)\n            {\n               memset(control, 0, (sizeof *control));\n\n               control->png_ptr = png_ptr;\n               control->info_ptr = info_ptr;\n               control->for_write = 0;\n\n               image->opaque = control;\n               return 1;\n            }\n\n            /* Error clean up */\n            png_destroy_info_struct(png_ptr, &info_ptr);\n         }\n\n         png_destroy_read_struct(&png_ptr, NULL, NULL);\n      }\n\n      return png_image_error(image, \"png_image_read: out of memory\");\n   }\n\n   return png_image_error(image, \"png_image_read: opaque pointer not NULL\");\n}\n\n/* Utility to find the base format of a PNG file from a png_struct. */\nstatic png_uint_32\npng_image_format(png_structrp png_ptr)\n{\n   png_uint_32 format = 0;\n\n   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)\n      format |= PNG_FORMAT_FLAG_COLOR;\n\n   if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)\n      format |= PNG_FORMAT_FLAG_ALPHA;\n\n   /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS\n    * sets the png_struct fields; that's all we are interested in here.  The\n    * precise interaction with an app call to png_set_tRNS and PNG file reading\n    * is unclear.\n    */\n   else if (png_ptr->num_trans > 0)\n      format |= PNG_FORMAT_FLAG_ALPHA;\n\n   if (png_ptr->bit_depth == 16)\n      format |= PNG_FORMAT_FLAG_LINEAR;\n\n   if ((png_ptr->color_type & PNG_COLOR_MASK_PALETTE) != 0)\n      format |= PNG_FORMAT_FLAG_COLORMAP;\n\n   return format;\n}\n\n/* Is the given gamma significantly different from sRGB?  The test is the same\n * one used in pngrtran.c when deciding whether to do gamma correction.  The\n * arithmetic optimizes the division by using the fact that the inverse of the\n * file sRGB gamma is 2.2\n */\nstatic int\npng_gamma_not_sRGB(png_fixed_point g)\n{\n   if (g < PNG_FP_1)\n   {\n      /* An uninitialized gamma is assumed to be sRGB for the simplified API. */\n      if (g == 0)\n         return 0;\n\n      return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */);\n   }\n\n   return 1;\n}\n\n/* Do the main body of a 'png_image_begin_read' function; read the PNG file\n * header and fill in all the information.  This is executed in a safe context,\n * unlike the init routine above.\n */\nstatic int\npng_image_read_header(png_voidp argument)\n{\n   png_imagep image = png_voidcast(png_imagep, argument);\n   png_structrp png_ptr = image->opaque->png_ptr;\n   png_inforp info_ptr = image->opaque->info_ptr;\n\n   png_set_benign_errors(png_ptr, 1/*warn*/);\n   png_read_info(png_ptr, info_ptr);\n\n   /* Do this the fast way; just read directly out of png_struct. */\n   image->width = png_ptr->width;\n   image->height = png_ptr->height;\n\n   {\n      png_uint_32 format = png_image_format(png_ptr);\n\n      image->format = format;\n\n#ifdef PNG_COLORSPACE_SUPPORTED\n      /* Does the colorspace match sRGB?  If there is no color endpoint\n       * (colorant) information assume yes, otherwise require the\n       * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set.  If the\n       * colorspace has been determined to be invalid ignore it.\n       */\n      if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags\n         & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB|\n            PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS))\n         image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB;\n#endif\n   }\n\n   /* We need the maximum number of entries regardless of the format the\n    * application sets here.\n    */\n   {\n      png_uint_32 cmap_entries;\n\n      switch (png_ptr->color_type)\n      {\n         case PNG_COLOR_TYPE_GRAY:\n            cmap_entries = 1U << png_ptr->bit_depth;\n            break;\n\n         case PNG_COLOR_TYPE_PALETTE:\n            cmap_entries = png_ptr->num_palette;\n            break;\n\n         default:\n            cmap_entries = 256;\n            break;\n      }\n\n      if (cmap_entries > 256)\n         cmap_entries = 256;\n\n      image->colormap_entries = cmap_entries;\n   }\n\n   return 1;\n}\n\n#ifdef PNG_STDIO_SUPPORTED\nint PNGAPI\npng_image_begin_read_from_stdio(png_imagep image, FILE* file)\n{\n   if (image != NULL && image->version == PNG_IMAGE_VERSION)\n   {\n      if (file != NULL)\n      {\n         if (png_image_read_init(image) != 0)\n         {\n            /* This is slightly evil, but png_init_io doesn't do anything other\n             * than this and we haven't changed the standard IO functions so\n             * this saves a 'safe' function.\n             */\n            image->opaque->png_ptr->io_ptr = file;\n            return png_safe_execute(image, png_image_read_header, image);\n         }\n      }\n\n      else\n         return png_image_error(image,\n            \"png_image_begin_read_from_stdio: invalid argument\");\n   }\n\n   else if (image != NULL)\n      return png_image_error(image,\n         \"png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION\");\n\n   return 0;\n}\n\nint PNGAPI\npng_image_begin_read_from_file(png_imagep image, const char *file_name)\n{\n   if (image != NULL && image->version == PNG_IMAGE_VERSION)\n   {\n      if (file_name != NULL)\n      {\n         FILE *fp = fopen(file_name, \"rb\");\n\n         if (fp != NULL)\n         {\n            if (png_image_read_init(image) != 0)\n            {\n               image->opaque->png_ptr->io_ptr = fp;\n               image->opaque->owned_file = 1;\n               return png_safe_execute(image, png_image_read_header, image);\n            }\n\n            /* Clean up: just the opened file. */\n            (void)fclose(fp);\n         }\n\n         else\n            return png_image_error(image, strerror(errno));\n      }\n\n      else\n         return png_image_error(image,\n            \"png_image_begin_read_from_file: invalid argument\");\n   }\n\n   else if (image != NULL)\n      return png_image_error(image,\n         \"png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION\");\n\n   return 0;\n}\n#endif /* STDIO */\n\nstatic void PNGCBAPI\npng_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need)\n{\n   if (png_ptr != NULL)\n   {\n      png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr);\n      if (image != NULL)\n      {\n         png_controlp cp = image->opaque;\n         if (cp != NULL)\n         {\n            png_const_bytep memory = cp->memory;\n            png_size_t size = cp->size;\n\n            if (memory != NULL && size >= need)\n            {\n               memcpy(out, memory, need);\n               cp->memory = memory + need;\n               cp->size = size - need;\n               return;\n            }\n\n            png_error(png_ptr, \"read beyond end of data\");\n         }\n      }\n\n      png_error(png_ptr, \"invalid memory read\");\n   }\n}\n\nint PNGAPI png_image_begin_read_from_memory(png_imagep image,\n   png_const_voidp memory, png_size_t size)\n{\n   if (image != NULL && image->version == PNG_IMAGE_VERSION)\n   {\n      if (memory != NULL && size > 0)\n      {\n         if (png_image_read_init(image) != 0)\n         {\n            /* Now set the IO functions to read from the memory buffer and\n             * store it into io_ptr.  Again do this in-place to avoid calling a\n             * libpng function that requires error handling.\n             */\n            image->opaque->memory = png_voidcast(png_const_bytep, memory);\n            image->opaque->size = size;\n            image->opaque->png_ptr->io_ptr = image;\n            image->opaque->png_ptr->read_data_fn = png_image_memory_read;\n\n            return png_safe_execute(image, png_image_read_header, image);\n         }\n      }\n\n      else\n         return png_image_error(image,\n            \"png_image_begin_read_from_memory: invalid argument\");\n   }\n\n   else if (image != NULL)\n      return png_image_error(image,\n         \"png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION\");\n\n   return 0;\n}\n\n/* Utility function to skip chunks that are not used by the simplified image\n * read functions and an appropriate macro to call it.\n */\n#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED\nstatic void\npng_image_skip_unused_chunks(png_structrp png_ptr)\n{\n   /* Prepare the reader to ignore all recognized chunks whose data will not\n    * be used, i.e., all chunks recognized by libpng except for those\n    * involved in basic image reading:\n    *\n    *    IHDR, PLTE, IDAT, IEND\n    *\n    * Or image data handling:\n    *\n    *    tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT.\n    *\n    * This provides a small performance improvement and eliminates any\n    * potential vulnerability to security problems in the unused chunks.\n    *\n    * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored\n    * too.  This allows the simplified API to be compiled without iCCP support,\n    * however if the support is there the chunk is still checked to detect\n    * errors (which are unfortunately quite common.)\n    */\n   {\n         static PNG_CONST png_byte chunks_to_process[] = {\n            98,  75,  71,  68, '\\0',  /* bKGD */\n            99,  72,  82,  77, '\\0',  /* cHRM */\n           103,  65,  77,  65, '\\0',  /* gAMA */\n#        ifdef PNG_READ_iCCP_SUPPORTED\n           105,  67,  67,  80, '\\0',  /* iCCP */\n#        endif\n           115,  66,  73,  84, '\\0',  /* sBIT */\n           115,  82,  71,  66, '\\0',  /* sRGB */\n           };\n\n       /* Ignore unknown chunks and all other chunks except for the\n        * IHDR, PLTE, tRNS, IDAT, and IEND chunks.\n        */\n       png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER,\n         NULL, -1);\n\n       /* But do not ignore image data handling chunks */\n       png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT,\n         chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);\n    }\n}\n\n#  define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p)\n#else\n#  define PNG_SKIP_CHUNKS(p) ((void)0)\n#endif /* HANDLE_AS_UNKNOWN */\n\n/* The following macro gives the exact rounded answer for all values in the\n * range 0..255 (it actually divides by 51.2, but the rounding still generates\n * the correct numbers 0..5\n */\n#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8)\n\n/* Utility functions to make particular color-maps */\nstatic void\nset_file_encoding(png_image_read_control *display)\n{\n   png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma;\n   if (png_gamma_significant(g) != 0)\n   {\n      if (png_gamma_not_sRGB(g) != 0)\n      {\n         display->file_encoding = P_FILE;\n         display->gamma_to_linear = png_reciprocal(g);\n      }\n\n      else\n         display->file_encoding = P_sRGB;\n   }\n\n   else\n      display->file_encoding = P_LINEAR8;\n}\n\nstatic unsigned int\ndecode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)\n{\n   if (encoding == P_FILE) /* double check */\n      encoding = display->file_encoding;\n\n   if (encoding == P_NOTSET) /* must be the file encoding */\n   {\n      set_file_encoding(display);\n      encoding = display->file_encoding;\n   }\n\n   switch (encoding)\n   {\n      case P_FILE:\n         value = png_gamma_16bit_correct(value*257, display->gamma_to_linear);\n         break;\n\n      case P_sRGB:\n         value = png_sRGB_table[value];\n         break;\n\n      case P_LINEAR:\n         break;\n\n      case P_LINEAR8:\n         value *= 257;\n         break;\n\n#ifdef __GNUC__\n      default:\n         png_error(display->image->opaque->png_ptr,\n            \"unexpected encoding (internal error)\");\n#endif\n   }\n\n   return value;\n}\n\nstatic png_uint_32\npng_colormap_compose(png_image_read_control *display,\n   png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,\n   png_uint_32 background, int encoding)\n{\n   /* The file value is composed on the background, the background has the given\n    * encoding and so does the result, the file is encoded with P_FILE and the\n    * file and alpha are 8-bit values.  The (output) encoding will always be\n    * P_LINEAR or P_sRGB.\n    */\n   png_uint_32 f = decode_gamma(display, foreground, foreground_encoding);\n   png_uint_32 b = decode_gamma(display, background, encoding);\n\n   /* The alpha is always an 8-bit value (it comes from the palette), the value\n    * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires.\n    */\n   f = f * alpha + b * (255-alpha);\n\n   if (encoding == P_LINEAR)\n   {\n      /* Scale to 65535; divide by 255, approximately (in fact this is extremely\n       * accurate, it divides by 255.00000005937181414556, with no overflow.)\n       */\n      f *= 257; /* Now scaled by 65535 */\n      f += f >> 16;\n      f = (f+32768) >> 16;\n   }\n\n   else /* P_sRGB */\n      f = PNG_sRGB_FROM_LINEAR(f);\n\n   return f;\n}\n\n/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must\n * be 8-bit.\n */\nstatic void\npng_create_colormap_entry(png_image_read_control *display,\n   png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,\n   png_uint_32 alpha, int encoding)\n{\n   png_imagep image = display->image;\n   const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ?\n      P_LINEAR : P_sRGB;\n   const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&\n      (red != green || green != blue);\n\n   if (ip > 255)\n      png_error(image->opaque->png_ptr, \"color-map index out of range\");\n\n   /* Update the cache with whether the file gamma is significantly different\n    * from sRGB.\n    */\n   if (encoding == P_FILE)\n   {\n      if (display->file_encoding == P_NOTSET)\n         set_file_encoding(display);\n\n      /* Note that the cached value may be P_FILE too, but if it is then the\n       * gamma_to_linear member has been set.\n       */\n      encoding = display->file_encoding;\n   }\n\n   if (encoding == P_FILE)\n   {\n      png_fixed_point g = display->gamma_to_linear;\n\n      red = png_gamma_16bit_correct(red*257, g);\n      green = png_gamma_16bit_correct(green*257, g);\n      blue = png_gamma_16bit_correct(blue*257, g);\n\n      if (convert_to_Y != 0 || output_encoding == P_LINEAR)\n      {\n         alpha *= 257;\n         encoding = P_LINEAR;\n      }\n\n      else\n      {\n         red = PNG_sRGB_FROM_LINEAR(red * 255);\n         green = PNG_sRGB_FROM_LINEAR(green * 255);\n         blue = PNG_sRGB_FROM_LINEAR(blue * 255);\n         encoding = P_sRGB;\n      }\n   }\n\n   else if (encoding == P_LINEAR8)\n   {\n      /* This encoding occurs quite frequently in test cases because PngSuite\n       * includes a gAMA 1.0 chunk with most images.\n       */\n      red *= 257;\n      green *= 257;\n      blue *= 257;\n      alpha *= 257;\n      encoding = P_LINEAR;\n   }\n\n   else if (encoding == P_sRGB &&\n       (convert_to_Y  != 0 || output_encoding == P_LINEAR))\n   {\n      /* The values are 8-bit sRGB values, but must be converted to 16-bit\n       * linear.\n       */\n      red = png_sRGB_table[red];\n      green = png_sRGB_table[green];\n      blue = png_sRGB_table[blue];\n      alpha *= 257;\n      encoding = P_LINEAR;\n   }\n\n   /* This is set if the color isn't gray but the output is. */\n   if (encoding == P_LINEAR)\n   {\n      if (convert_to_Y != 0)\n      {\n         /* NOTE: these values are copied from png_do_rgb_to_gray */\n         png_uint_32 y = (png_uint_32)6968 * red  + (png_uint_32)23434 * green +\n            (png_uint_32)2366 * blue;\n\n         if (output_encoding == P_LINEAR)\n            y = (y + 16384) >> 15;\n\n         else\n         {\n            /* y is scaled by 32768, we need it scaled by 255: */\n            y = (y + 128) >> 8;\n            y *= 255;\n            y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7);\n            alpha = PNG_DIV257(alpha);\n            encoding = P_sRGB;\n         }\n\n         blue = red = green = y;\n      }\n\n      else if (output_encoding == P_sRGB)\n      {\n         red = PNG_sRGB_FROM_LINEAR(red * 255);\n         green = PNG_sRGB_FROM_LINEAR(green * 255);\n         blue = PNG_sRGB_FROM_LINEAR(blue * 255);\n         alpha = PNG_DIV257(alpha);\n         encoding = P_sRGB;\n      }\n   }\n\n   if (encoding != output_encoding)\n      png_error(image->opaque->png_ptr, \"bad encoding (internal error)\");\n\n   /* Store the value. */\n   {\n#     ifdef PNG_FORMAT_AFIRST_SUPPORTED\n         const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 &&\n            (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;\n#     else\n#        define afirst 0\n#     endif\n#     ifdef PNG_FORMAT_BGR_SUPPORTED\n         const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;\n#     else\n#        define bgr 0\n#     endif\n\n      if (output_encoding == P_LINEAR)\n      {\n         png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap);\n\n         entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);\n\n         /* The linear 16-bit values must be pre-multiplied by the alpha channel\n          * value, if less than 65535 (this is, effectively, composite on black\n          * if the alpha channel is removed.)\n          */\n         switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))\n         {\n            case 4:\n               entry[afirst ? 0 : 3] = (png_uint_16)alpha;\n               /* FALL THROUGH */\n\n            case 3:\n               if (alpha < 65535)\n               {\n                  if (alpha > 0)\n                  {\n                     blue = (blue * alpha + 32767U)/65535U;\n                     green = (green * alpha + 32767U)/65535U;\n                     red = (red * alpha + 32767U)/65535U;\n                  }\n\n                  else\n                     red = green = blue = 0;\n               }\n               entry[afirst + (2 ^ bgr)] = (png_uint_16)blue;\n               entry[afirst + 1] = (png_uint_16)green;\n               entry[afirst + bgr] = (png_uint_16)red;\n               break;\n\n            case 2:\n               entry[1 ^ afirst] = (png_uint_16)alpha;\n               /* FALL THROUGH */\n\n            case 1:\n               if (alpha < 65535)\n               {\n                  if (alpha > 0)\n                     green = (green * alpha + 32767U)/65535U;\n\n                  else\n                     green = 0;\n               }\n               entry[afirst] = (png_uint_16)green;\n               break;\n\n            default:\n               break;\n         }\n      }\n\n      else /* output encoding is P_sRGB */\n      {\n         png_bytep entry = png_voidcast(png_bytep, display->colormap);\n\n         entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);\n\n         switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))\n         {\n            case 4:\n               entry[afirst ? 0 : 3] = (png_byte)alpha;\n            case 3:\n               entry[afirst + (2 ^ bgr)] = (png_byte)blue;\n               entry[afirst + 1] = (png_byte)green;\n               entry[afirst + bgr] = (png_byte)red;\n               break;\n\n            case 2:\n               entry[1 ^ afirst] = (png_byte)alpha;\n            case 1:\n               entry[afirst] = (png_byte)green;\n               break;\n\n            default:\n               break;\n         }\n      }\n\n#     ifdef afirst\n#        undef afirst\n#     endif\n#     ifdef bgr\n#        undef bgr\n#     endif\n   }\n}\n\nstatic int\nmake_gray_file_colormap(png_image_read_control *display)\n{\n   unsigned int i;\n\n   for (i=0; i<256; ++i)\n      png_create_colormap_entry(display, i, i, i, i, 255, P_FILE);\n\n   return i;\n}\n\nstatic int\nmake_gray_colormap(png_image_read_control *display)\n{\n   unsigned int i;\n\n   for (i=0; i<256; ++i)\n      png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB);\n\n   return i;\n}\n#define PNG_GRAY_COLORMAP_ENTRIES 256\n\nstatic int\nmake_ga_colormap(png_image_read_control *display)\n{\n   unsigned int i, a;\n\n   /* Alpha is retained, the output will be a color-map with entries\n    * selected by six levels of alpha.  One transparent entry, 6 gray\n    * levels for all the intermediate alpha values, leaving 230 entries\n    * for the opaque grays.  The color-map entries are the six values\n    * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the\n    * relevant entry.\n    *\n    * if (alpha > 229) // opaque\n    * {\n    *    // The 231 entries are selected to make the math below work:\n    *    base = 0;\n    *    entry = (231 * gray + 128) >> 8;\n    * }\n    * else if (alpha < 26) // transparent\n    * {\n    *    base = 231;\n    *    entry = 0;\n    * }\n    * else // partially opaque\n    * {\n    *    base = 226 + 6 * PNG_DIV51(alpha);\n    *    entry = PNG_DIV51(gray);\n    * }\n    */\n   i = 0;\n   while (i < 231)\n   {\n      unsigned int gray = (i * 256 + 115) / 231;\n      png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB);\n   }\n\n   /* 255 is used here for the component values for consistency with the code\n    * that undoes premultiplication in pngwrite.c.\n    */\n   png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB);\n\n   for (a=1; a<5; ++a)\n   {\n      unsigned int g;\n\n      for (g=0; g<6; ++g)\n         png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51,\n            P_sRGB);\n   }\n\n   return i;\n}\n\n#define PNG_GA_COLORMAP_ENTRIES 256\n\nstatic int\nmake_rgb_colormap(png_image_read_control *display)\n{\n   unsigned int i, r;\n\n   /* Build a 6x6x6 opaque RGB cube */\n   for (i=r=0; r<6; ++r)\n   {\n      unsigned int g;\n\n      for (g=0; g<6; ++g)\n      {\n         unsigned int b;\n\n         for (b=0; b<6; ++b)\n            png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255,\n               P_sRGB);\n      }\n   }\n\n   return i;\n}\n\n#define PNG_RGB_COLORMAP_ENTRIES 216\n\n/* Return a palette index to the above palette given three 8-bit sRGB values. */\n#define PNG_RGB_INDEX(r,g,b) \\\n   ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b)))\n\nstatic int\npng_image_read_colormap(png_voidp argument)\n{\n   png_image_read_control *display =\n      png_voidcast(png_image_read_control*, argument);\n   const png_imagep image = display->image;\n\n   const png_structrp png_ptr = image->opaque->png_ptr;\n   const png_uint_32 output_format = image->format;\n   const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ?\n      P_LINEAR : P_sRGB;\n\n   unsigned int cmap_entries;\n   unsigned int output_processing;        /* Output processing option */\n   unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */\n\n   /* Background information; the background color and the index of this color\n    * in the color-map if it exists (else 256).\n    */\n   unsigned int background_index = 256;\n   png_uint_32 back_r, back_g, back_b;\n\n   /* Flags to accumulate things that need to be done to the input. */\n   int expand_tRNS = 0;\n\n   /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is\n    * very difficult to do, the results look awful, and it is difficult to see\n    * what possible use it is because the application can't control the\n    * color-map.\n    */\n   if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 ||\n         png_ptr->num_trans > 0) /* alpha in input */ &&\n      ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */)\n   {\n      if (output_encoding == P_LINEAR) /* compose on black */\n         back_b = back_g = back_r = 0;\n\n      else if (display->background == NULL /* no way to remove it */)\n         png_error(png_ptr,\n            \"a background color must be supplied to remove alpha/transparency\");\n\n      /* Get a copy of the background color (this avoids repeating the checks\n       * below.)  The encoding is 8-bit sRGB or 16-bit linear, depending on the\n       * output format.\n       */\n      else\n      {\n         back_g = display->background->green;\n         if ((output_format & PNG_FORMAT_FLAG_COLOR) != 0)\n         {\n            back_r = display->background->red;\n            back_b = display->background->blue;\n         }\n         else\n            back_b = back_r = back_g;\n      }\n   }\n\n   else if (output_encoding == P_LINEAR)\n      back_b = back_r = back_g = 65535;\n\n   else\n      back_b = back_r = back_g = 255;\n\n   /* Default the input file gamma if required - this is necessary because\n    * libpng assumes that if no gamma information is present the data is in the\n    * output format, but the simplified API deduces the gamma from the input\n    * format.\n    */\n   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0)\n   {\n      /* Do this directly, not using the png_colorspace functions, to ensure\n       * that it happens even if the colorspace is invalid (though probably if\n       * it is the setting will be ignored)  Note that the same thing can be\n       * achieved at the application interface with png_set_gAMA.\n       */\n      if (png_ptr->bit_depth == 16 &&\n         (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)\n         png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR;\n\n      else\n         png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE;\n\n      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;\n   }\n\n   /* Decide what to do based on the PNG color type of the input data.  The\n    * utility function png_create_colormap_entry deals with most aspects of the\n    * output transformations; this code works out how to produce bytes of\n    * color-map entries from the original format.\n    */\n   switch (png_ptr->color_type)\n   {\n      case PNG_COLOR_TYPE_GRAY:\n         if (png_ptr->bit_depth <= 8)\n         {\n            /* There at most 256 colors in the output, regardless of\n             * transparency.\n             */\n            unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0;\n\n            cmap_entries = 1U << png_ptr->bit_depth;\n            if (cmap_entries > image->colormap_entries)\n               png_error(png_ptr, \"gray[8] color-map: too few entries\");\n\n            step = 255 / (cmap_entries - 1);\n            output_processing = PNG_CMAP_NONE;\n\n            /* If there is a tRNS chunk then this either selects a transparent\n             * value or, if the output has no alpha, the background color.\n             */\n            if (png_ptr->num_trans > 0)\n            {\n               trans = png_ptr->trans_color.gray;\n\n               if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0)\n                  back_alpha = output_encoding == P_LINEAR ? 65535 : 255;\n            }\n\n            /* png_create_colormap_entry just takes an RGBA and writes the\n             * corresponding color-map entry using the format from 'image',\n             * including the required conversion to sRGB or linear as\n             * appropriate.  The input values are always either sRGB (if the\n             * gamma correction flag is 0) or 0..255 scaled file encoded values\n             * (if the function must gamma correct them).\n             */\n            for (i=val=0; i<cmap_entries; ++i, val += step)\n            {\n               /* 'i' is a file value.  While this will result in duplicated\n                * entries for 8-bit non-sRGB encoded files it is necessary to\n                * have non-gamma corrected values to do tRNS handling.\n                */\n               if (i != trans)\n                  png_create_colormap_entry(display, i, val, val, val, 255,\n                     P_FILE/*8-bit with file gamma*/);\n\n               /* Else this entry is transparent.  The colors don't matter if\n                * there is an alpha channel (back_alpha == 0), but it does no\n                * harm to pass them in; the values are not set above so this\n                * passes in white.\n                *\n                * NOTE: this preserves the full precision of the application\n                * supplied background color when it is used.\n                */\n               else\n                  png_create_colormap_entry(display, i, back_r, back_g, back_b,\n                     back_alpha, output_encoding);\n            }\n\n            /* We need libpng to preserve the original encoding. */\n            data_encoding = P_FILE;\n\n            /* The rows from libpng, while technically gray values, are now also\n             * color-map indices; however, they may need to be expanded to 1\n             * byte per pixel.  This is what png_set_packing does (i.e., it\n             * unpacks the bit values into bytes.)\n             */\n            if (png_ptr->bit_depth < 8)\n               png_set_packing(png_ptr);\n         }\n\n         else /* bit depth is 16 */\n         {\n            /* The 16-bit input values can be converted directly to 8-bit gamma\n             * encoded values; however, if a tRNS chunk is present 257 color-map\n             * entries are required.  This means that the extra entry requires\n             * special processing; add an alpha channel, sacrifice gray level\n             * 254 and convert transparent (alpha==0) entries to that.\n             *\n             * Use libpng to chop the data to 8 bits.  Convert it to sRGB at the\n             * same time to minimize quality loss.  If a tRNS chunk is present\n             * this means libpng must handle it too; otherwise it is impossible\n             * to do the exact match on the 16-bit value.\n             *\n             * If the output has no alpha channel *and* the background color is\n             * gray then it is possible to let libpng handle the substitution by\n             * ensuring that the corresponding gray level matches the background\n             * color exactly.\n             */\n            data_encoding = P_sRGB;\n\n            if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)\n               png_error(png_ptr, \"gray[16] color-map: too few entries\");\n\n            cmap_entries = make_gray_colormap(display);\n\n            if (png_ptr->num_trans > 0)\n            {\n               unsigned int back_alpha;\n\n               if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)\n                  back_alpha = 0;\n\n               else\n               {\n                  if (back_r == back_g && back_g == back_b)\n                  {\n                     /* Background is gray; no special processing will be\n                      * required.\n                      */\n                     png_color_16 c;\n                     png_uint_32 gray = back_g;\n\n                     if (output_encoding == P_LINEAR)\n                     {\n                        gray = PNG_sRGB_FROM_LINEAR(gray * 255);\n\n                        /* And make sure the corresponding palette entry\n                         * matches.\n                         */\n                        png_create_colormap_entry(display, gray, back_g, back_g,\n                           back_g, 65535, P_LINEAR);\n                     }\n\n                     /* The background passed to libpng, however, must be the\n                      * sRGB value.\n                      */\n                     c.index = 0; /*unused*/\n                     c.gray = c.red = c.green = c.blue = (png_uint_16)gray;\n\n                     /* NOTE: does this work without expanding tRNS to alpha?\n                      * It should be the color->gray case below apparently\n                      * doesn't.\n                      */\n                     png_set_background_fixed(png_ptr, &c,\n                        PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,\n                        0/*gamma: not used*/);\n\n                     output_processing = PNG_CMAP_NONE;\n                     break;\n                  }\n#ifdef __COVERITY__\n                 /* Coverity claims that output_encoding cannot be 2 (P_LINEAR)\n                  * here.\n                  */\n                  back_alpha = 255;\n#else\n                  back_alpha = output_encoding == P_LINEAR ? 65535 : 255;\n#endif\n               }\n\n               /* output_processing means that the libpng-processed row will be\n                * 8-bit GA and it has to be processing to single byte color-map\n                * values.  Entry 254 is replaced by either a completely\n                * transparent entry or by the background color at full\n                * precision (and the background color is not a simple gray\n                * level in this case.)\n                */\n               expand_tRNS = 1;\n               output_processing = PNG_CMAP_TRANS;\n               background_index = 254;\n\n               /* And set (overwrite) color-map entry 254 to the actual\n                * background color at full precision.\n                */\n               png_create_colormap_entry(display, 254, back_r, back_g, back_b,\n                  back_alpha, output_encoding);\n            }\n\n            else\n               output_processing = PNG_CMAP_NONE;\n         }\n         break;\n\n      case PNG_COLOR_TYPE_GRAY_ALPHA:\n         /* 8-bit or 16-bit PNG with two channels - gray and alpha.  A minimum\n          * of 65536 combinations.  If, however, the alpha channel is to be\n          * removed there are only 256 possibilities if the background is gray.\n          * (Otherwise there is a subset of the 65536 possibilities defined by\n          * the triangle between black, white and the background color.)\n          *\n          * Reduce 16-bit files to 8-bit and sRGB encode the result.  No need to\n          * worry about tRNS matching - tRNS is ignored if there is an alpha\n          * channel.\n          */\n         data_encoding = P_sRGB;\n\n         if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)\n         {\n            if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)\n               png_error(png_ptr, \"gray+alpha color-map: too few entries\");\n\n            cmap_entries = make_ga_colormap(display);\n\n            background_index = PNG_CMAP_GA_BACKGROUND;\n            output_processing = PNG_CMAP_GA;\n         }\n\n         else /* alpha is removed */\n         {\n            /* Alpha must be removed as the PNG data is processed when the\n             * background is a color because the G and A channels are\n             * independent and the vector addition (non-parallel vectors) is a\n             * 2-D problem.\n             *\n             * This can be reduced to the same algorithm as above by making a\n             * colormap containing gray levels (for the opaque grays), a\n             * background entry (for a transparent pixel) and a set of four six\n             * level color values, one set for each intermediate alpha value.\n             * See the comments in make_ga_colormap for how this works in the\n             * per-pixel processing.\n             *\n             * If the background is gray, however, we only need a 256 entry gray\n             * level color map.  It is sufficient to make the entry generated\n             * for the background color be exactly the color specified.\n             */\n            if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 ||\n               (back_r == back_g && back_g == back_b))\n            {\n               /* Background is gray; no special processing will be required. */\n               png_color_16 c;\n               png_uint_32 gray = back_g;\n\n               if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)\n                  png_error(png_ptr, \"gray-alpha color-map: too few entries\");\n\n               cmap_entries = make_gray_colormap(display);\n\n               if (output_encoding == P_LINEAR)\n               {\n                  gray = PNG_sRGB_FROM_LINEAR(gray * 255);\n\n                  /* And make sure the corresponding palette entry matches. */\n                  png_create_colormap_entry(display, gray, back_g, back_g,\n                     back_g, 65535, P_LINEAR);\n               }\n\n               /* The background passed to libpng, however, must be the sRGB\n                * value.\n                */\n               c.index = 0; /*unused*/\n               c.gray = c.red = c.green = c.blue = (png_uint_16)gray;\n\n               png_set_background_fixed(png_ptr, &c,\n                  PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,\n                  0/*gamma: not used*/);\n\n               output_processing = PNG_CMAP_NONE;\n            }\n\n            else\n            {\n               png_uint_32 i, a;\n\n               /* This is the same as png_make_ga_colormap, above, except that\n                * the entries are all opaque.\n                */\n               if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)\n                  png_error(png_ptr, \"ga-alpha color-map: too few entries\");\n\n               i = 0;\n               while (i < 231)\n               {\n                  png_uint_32 gray = (i * 256 + 115) / 231;\n                  png_create_colormap_entry(display, i++, gray, gray, gray,\n                     255, P_sRGB);\n               }\n\n               /* NOTE: this preserves the full precision of the application\n                * background color.\n                */\n               background_index = i;\n               png_create_colormap_entry(display, i++, back_r, back_g, back_b,\n#ifdef __COVERITY__\n                 /* Coverity claims that output_encoding cannot be 2 (P_LINEAR)\n                  * here.\n                  */ 255U,\n#else\n                  output_encoding == P_LINEAR ? 65535U : 255U,\n#endif\n                  output_encoding);\n\n               /* For non-opaque input composite on the sRGB background - this\n                * requires inverting the encoding for each component.  The input\n                * is still converted to the sRGB encoding because this is a\n                * reasonable approximate to the logarithmic curve of human\n                * visual sensitivity, at least over the narrow range which PNG\n                * represents.  Consequently 'G' is always sRGB encoded, while\n                * 'A' is linear.  We need the linear background colors.\n                */\n               if (output_encoding == P_sRGB) /* else already linear */\n               {\n                  /* This may produce a value not exactly matching the\n                   * background, but that's ok because these numbers are only\n                   * used when alpha != 0\n                   */\n                  back_r = png_sRGB_table[back_r];\n                  back_g = png_sRGB_table[back_g];\n                  back_b = png_sRGB_table[back_b];\n               }\n\n               for (a=1; a<5; ++a)\n               {\n                  unsigned int g;\n\n                  /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled\n                   * by an 8-bit alpha value (0..255).\n                   */\n                  png_uint_32 alpha = 51 * a;\n                  png_uint_32 back_rx = (255-alpha) * back_r;\n                  png_uint_32 back_gx = (255-alpha) * back_g;\n                  png_uint_32 back_bx = (255-alpha) * back_b;\n\n                  for (g=0; g<6; ++g)\n                  {\n                     png_uint_32 gray = png_sRGB_table[g*51] * alpha;\n\n                     png_create_colormap_entry(display, i++,\n                        PNG_sRGB_FROM_LINEAR(gray + back_rx),\n                        PNG_sRGB_FROM_LINEAR(gray + back_gx),\n                        PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);\n                  }\n               }\n\n               cmap_entries = i;\n               output_processing = PNG_CMAP_GA;\n            }\n         }\n         break;\n\n      case PNG_COLOR_TYPE_RGB:\n      case PNG_COLOR_TYPE_RGB_ALPHA:\n         /* Exclude the case where the output is gray; we can always handle this\n          * with the cases above.\n          */\n         if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0)\n         {\n            /* The color-map will be grayscale, so we may as well convert the\n             * input RGB values to a simple grayscale and use the grayscale\n             * code above.\n             *\n             * NOTE: calling this apparently damages the recognition of the\n             * transparent color in background color handling; call\n             * png_set_tRNS_to_alpha before png_set_background_fixed.\n             */\n            png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,\n               -1);\n            data_encoding = P_sRGB;\n\n            /* The output will now be one or two 8-bit gray or gray+alpha\n             * channels.  The more complex case arises when the input has alpha.\n             */\n            if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||\n               png_ptr->num_trans > 0) &&\n               (output_format & PNG_FORMAT_FLAG_ALPHA) != 0)\n            {\n               /* Both input and output have an alpha channel, so no background\n                * processing is required; just map the GA bytes to the right\n                * color-map entry.\n                */\n               expand_tRNS = 1;\n\n               if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)\n                  png_error(png_ptr, \"rgb[ga] color-map: too few entries\");\n\n               cmap_entries = make_ga_colormap(display);\n               background_index = PNG_CMAP_GA_BACKGROUND;\n               output_processing = PNG_CMAP_GA;\n            }\n\n            else\n            {\n               /* Either the input or the output has no alpha channel, so there\n                * will be no non-opaque pixels in the color-map; it will just be\n                * grayscale.\n                */\n               if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)\n                  png_error(png_ptr, \"rgb[gray] color-map: too few entries\");\n\n               /* Ideally this code would use libpng to do the gamma correction,\n                * but if an input alpha channel is to be removed we will hit the\n                * libpng bug in gamma+compose+rgb-to-gray (the double gamma\n                * correction bug).  Fix this by dropping the gamma correction in\n                * this case and doing it in the palette; this will result in\n                * duplicate palette entries, but that's better than the\n                * alternative of double gamma correction.\n                */\n               if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||\n                  png_ptr->num_trans > 0) &&\n                  png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0)\n               {\n                  cmap_entries = make_gray_file_colormap(display);\n                  data_encoding = P_FILE;\n               }\n\n               else\n                  cmap_entries = make_gray_colormap(display);\n\n               /* But if the input has alpha or transparency it must be removed\n                */\n               if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||\n                  png_ptr->num_trans > 0)\n               {\n                  png_color_16 c;\n                  png_uint_32 gray = back_g;\n\n                  /* We need to ensure that the application background exists in\n                   * the colormap and that completely transparent pixels map to\n                   * it.  Achieve this simply by ensuring that the entry\n                   * selected for the background really is the background color.\n                   */\n                  if (data_encoding == P_FILE) /* from the fixup above */\n                  {\n                     /* The app supplied a gray which is in output_encoding, we\n                      * need to convert it to a value of the input (P_FILE)\n                      * encoding then set this palette entry to the required\n                      * output encoding.\n                      */\n                     if (output_encoding == P_sRGB)\n                        gray = png_sRGB_table[gray]; /* now P_LINEAR */\n\n                     gray = PNG_DIV257(png_gamma_16bit_correct(gray,\n                        png_ptr->colorspace.gamma)); /* now P_FILE */\n\n                     /* And make sure the corresponding palette entry contains\n                      * exactly the required sRGB value.\n                      */\n                     png_create_colormap_entry(display, gray, back_g, back_g,\n                        back_g, 0/*unused*/, output_encoding);\n                  }\n\n                  else if (output_encoding == P_LINEAR)\n                  {\n                     gray = PNG_sRGB_FROM_LINEAR(gray * 255);\n\n                     /* And make sure the corresponding palette entry matches.\n                      */\n                     png_create_colormap_entry(display, gray, back_g, back_g,\n                        back_g, 0/*unused*/, P_LINEAR);\n                  }\n\n                  /* The background passed to libpng, however, must be the\n                   * output (normally sRGB) value.\n                   */\n                  c.index = 0; /*unused*/\n                  c.gray = c.red = c.green = c.blue = (png_uint_16)gray;\n\n                  /* NOTE: the following is apparently a bug in libpng. Without\n                   * it the transparent color recognition in\n                   * png_set_background_fixed seems to go wrong.\n                   */\n                  expand_tRNS = 1;\n                  png_set_background_fixed(png_ptr, &c,\n                     PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,\n                     0/*gamma: not used*/);\n               }\n\n               output_processing = PNG_CMAP_NONE;\n            }\n         }\n\n         else /* output is color */\n         {\n            /* We could use png_quantize here so long as there is no transparent\n             * color or alpha; png_quantize ignores alpha.  Easier overall just\n             * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube.\n             * Consequently we always want libpng to produce sRGB data.\n             */\n            data_encoding = P_sRGB;\n\n            /* Is there any transparency or alpha? */\n            if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||\n               png_ptr->num_trans > 0)\n            {\n               /* Is there alpha in the output too?  If so all four channels are\n                * processed into a special RGB cube with alpha support.\n                */\n               if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)\n               {\n                  png_uint_32 r;\n\n                  if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)\n                     png_error(png_ptr, \"rgb+alpha color-map: too few entries\");\n\n                  cmap_entries = make_rgb_colormap(display);\n\n                  /* Add a transparent entry. */\n                  png_create_colormap_entry(display, cmap_entries, 255, 255,\n                     255, 0, P_sRGB);\n\n                  /* This is stored as the background index for the processing\n                   * algorithm.\n                   */\n                  background_index = cmap_entries++;\n\n                  /* Add 27 r,g,b entries each with alpha 0.5. */\n                  for (r=0; r<256; r = (r << 1) | 0x7f)\n                  {\n                     png_uint_32 g;\n\n                     for (g=0; g<256; g = (g << 1) | 0x7f)\n                     {\n                        png_uint_32 b;\n\n                        /* This generates components with the values 0, 127 and\n                         * 255\n                         */\n                        for (b=0; b<256; b = (b << 1) | 0x7f)\n                           png_create_colormap_entry(display, cmap_entries++,\n                              r, g, b, 128, P_sRGB);\n                     }\n                  }\n\n                  expand_tRNS = 1;\n                  output_processing = PNG_CMAP_RGB_ALPHA;\n               }\n\n               else\n               {\n                  /* Alpha/transparency must be removed.  The background must\n                   * exist in the color map (achieved by setting adding it after\n                   * the 666 color-map).  If the standard processing code will\n                   * pick up this entry automatically that's all that is\n                   * required; libpng can be called to do the background\n                   * processing.\n                   */\n                  unsigned int sample_size =\n                     PNG_IMAGE_SAMPLE_SIZE(output_format);\n                  png_uint_32 r, g, b; /* sRGB background */\n\n                  if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)\n                     png_error(png_ptr, \"rgb-alpha color-map: too few entries\");\n\n                  cmap_entries = make_rgb_colormap(display);\n\n                  png_create_colormap_entry(display, cmap_entries, back_r,\n                        back_g, back_b, 0/*unused*/, output_encoding);\n\n                  if (output_encoding == P_LINEAR)\n                  {\n                     r = PNG_sRGB_FROM_LINEAR(back_r * 255);\n                     g = PNG_sRGB_FROM_LINEAR(back_g * 255);\n                     b = PNG_sRGB_FROM_LINEAR(back_b * 255);\n                  }\n\n                  else\n                  {\n                     r = back_r;\n                     g = back_g;\n                     b = back_g;\n                  }\n\n                  /* Compare the newly-created color-map entry with the one the\n                   * PNG_CMAP_RGB algorithm will use.  If the two entries don't\n                   * match, add the new one and set this as the background\n                   * index.\n                   */\n                  if (memcmp((png_const_bytep)display->colormap +\n                        sample_size * cmap_entries,\n                     (png_const_bytep)display->colormap +\n                        sample_size * PNG_RGB_INDEX(r,g,b),\n                     sample_size) != 0)\n                  {\n                     /* The background color must be added. */\n                     background_index = cmap_entries++;\n\n                     /* Add 27 r,g,b entries each with created by composing with\n                      * the background at alpha 0.5.\n                      */\n                     for (r=0; r<256; r = (r << 1) | 0x7f)\n                     {\n                        for (g=0; g<256; g = (g << 1) | 0x7f)\n                        {\n                           /* This generates components with the values 0, 127\n                            * and 255\n                            */\n                           for (b=0; b<256; b = (b << 1) | 0x7f)\n                              png_create_colormap_entry(display, cmap_entries++,\n                                 png_colormap_compose(display, r, P_sRGB, 128,\n                                    back_r, output_encoding),\n                                 png_colormap_compose(display, g, P_sRGB, 128,\n                                    back_g, output_encoding),\n                                 png_colormap_compose(display, b, P_sRGB, 128,\n                                    back_b, output_encoding),\n                                 0/*unused*/, output_encoding);\n                        }\n                     }\n\n                     expand_tRNS = 1;\n                     output_processing = PNG_CMAP_RGB_ALPHA;\n                  }\n\n                  else /* background color is in the standard color-map */\n                  {\n                     png_color_16 c;\n\n                     c.index = 0; /*unused*/\n                     c.red = (png_uint_16)back_r;\n                     c.gray = c.green = (png_uint_16)back_g;\n                     c.blue = (png_uint_16)back_b;\n\n                     png_set_background_fixed(png_ptr, &c,\n                        PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,\n                        0/*gamma: not used*/);\n\n                     output_processing = PNG_CMAP_RGB;\n                  }\n               }\n            }\n\n            else /* no alpha or transparency in the input */\n            {\n               /* Alpha in the output is irrelevant, simply map the opaque input\n                * pixels to the 6x6x6 color-map.\n                */\n               if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries)\n                  png_error(png_ptr, \"rgb color-map: too few entries\");\n\n               cmap_entries = make_rgb_colormap(display);\n               output_processing = PNG_CMAP_RGB;\n            }\n         }\n         break;\n\n      case PNG_COLOR_TYPE_PALETTE:\n         /* It's already got a color-map.  It may be necessary to eliminate the\n          * tRNS entries though.\n          */\n         {\n            unsigned int num_trans = png_ptr->num_trans;\n            png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL;\n            png_const_colorp colormap = png_ptr->palette;\n            const int do_background = trans != NULL &&\n               (output_format & PNG_FORMAT_FLAG_ALPHA) == 0;\n            unsigned int i;\n\n            /* Just in case: */\n            if (trans == NULL)\n               num_trans = 0;\n\n            output_processing = PNG_CMAP_NONE;\n            data_encoding = P_FILE; /* Don't change from color-map indices */\n            cmap_entries = png_ptr->num_palette;\n            if (cmap_entries > 256)\n               cmap_entries = 256;\n\n            if (cmap_entries > image->colormap_entries)\n               png_error(png_ptr, \"palette color-map: too few entries\");\n\n            for (i=0; i < cmap_entries; ++i)\n            {\n               if (do_background != 0 && i < num_trans && trans[i] < 255)\n               {\n                  if (trans[i] == 0)\n                     png_create_colormap_entry(display, i, back_r, back_g,\n                        back_b, 0, output_encoding);\n\n                  else\n                  {\n                     /* Must compose the PNG file color in the color-map entry\n                      * on the sRGB color in 'back'.\n                      */\n                     png_create_colormap_entry(display, i,\n                        png_colormap_compose(display, colormap[i].red, P_FILE,\n                           trans[i], back_r, output_encoding),\n                        png_colormap_compose(display, colormap[i].green, P_FILE,\n                           trans[i], back_g, output_encoding),\n                        png_colormap_compose(display, colormap[i].blue, P_FILE,\n                           trans[i], back_b, output_encoding),\n                        output_encoding == P_LINEAR ? trans[i] * 257U :\n                           trans[i],\n                        output_encoding);\n                  }\n               }\n\n               else\n                  png_create_colormap_entry(display, i, colormap[i].red,\n                     colormap[i].green, colormap[i].blue,\n                     i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);\n            }\n\n            /* The PNG data may have indices packed in fewer than 8 bits, it\n             * must be expanded if so.\n             */\n            if (png_ptr->bit_depth < 8)\n               png_set_packing(png_ptr);\n         }\n         break;\n\n      default:\n         png_error(png_ptr, \"invalid PNG color type\");\n         /*NOT REACHED*/\n   }\n\n   /* Now deal with the output processing */\n   if (expand_tRNS != 0 && png_ptr->num_trans > 0 &&\n       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0)\n      png_set_tRNS_to_alpha(png_ptr);\n\n   switch (data_encoding)\n   {\n      case P_sRGB:\n         /* Change to 8-bit sRGB */\n         png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);\n         /* FALL THROUGH */\n\n      case P_FILE:\n         if (png_ptr->bit_depth > 8)\n            png_set_scale_16(png_ptr);\n         break;\n\n#ifdef __GNUC__\n      default:\n         png_error(png_ptr, \"bad data option (internal error)\");\n#endif\n   }\n\n   if (cmap_entries > 256 || cmap_entries > image->colormap_entries)\n      png_error(png_ptr, \"color map overflow (BAD internal error)\");\n\n   image->colormap_entries = cmap_entries;\n\n   /* Double check using the recorded background index */\n   switch (output_processing)\n   {\n      case PNG_CMAP_NONE:\n         if (background_index != PNG_CMAP_NONE_BACKGROUND)\n            goto bad_background;\n         break;\n\n      case PNG_CMAP_GA:\n         if (background_index != PNG_CMAP_GA_BACKGROUND)\n            goto bad_background;\n         break;\n\n      case PNG_CMAP_TRANS:\n         if (background_index >= cmap_entries ||\n            background_index != PNG_CMAP_TRANS_BACKGROUND)\n            goto bad_background;\n         break;\n\n      case PNG_CMAP_RGB:\n         if (background_index != PNG_CMAP_RGB_BACKGROUND)\n            goto bad_background;\n         break;\n\n      case PNG_CMAP_RGB_ALPHA:\n         if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND)\n            goto bad_background;\n         break;\n\n      default:\n         png_error(png_ptr, \"bad processing option (internal error)\");\n\n      bad_background:\n         png_error(png_ptr, \"bad background index (internal error)\");\n   }\n\n   display->colormap_processing = output_processing;\n\n   return 1/*ok*/;\n}\n\n/* The final part of the color-map read called from png_image_finish_read. */\nstatic int\npng_image_read_and_map(png_voidp argument)\n{\n   png_image_read_control *display = png_voidcast(png_image_read_control*,\n      argument);\n   png_imagep image = display->image;\n   png_structrp png_ptr = image->opaque->png_ptr;\n   int passes;\n\n   /* Called when the libpng data must be transformed into the color-mapped\n    * form.  There is a local row buffer in display->local and this routine must\n    * do the interlace handling.\n    */\n   switch (png_ptr->interlaced)\n   {\n      case PNG_INTERLACE_NONE:\n         passes = 1;\n         break;\n\n      case PNG_INTERLACE_ADAM7:\n         passes = PNG_INTERLACE_ADAM7_PASSES;\n         break;\n\n      default:\n         png_error(png_ptr, \"unknown interlace type\");\n   }\n\n   {\n      png_uint_32  height = image->height;\n      png_uint_32  width = image->width;\n      int          proc = display->colormap_processing;\n      png_bytep    first_row = png_voidcast(png_bytep, display->first_row);\n      ptrdiff_t    step_row = display->row_bytes;\n      int pass;\n\n      for (pass = 0; pass < passes; ++pass)\n      {\n         unsigned int     startx, stepx, stepy;\n         png_uint_32      y;\n\n         if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)\n         {\n            /* The row may be empty for a short image: */\n            if (PNG_PASS_COLS(width, pass) == 0)\n               continue;\n\n            startx = PNG_PASS_START_COL(pass);\n            stepx = PNG_PASS_COL_OFFSET(pass);\n            y = PNG_PASS_START_ROW(pass);\n            stepy = PNG_PASS_ROW_OFFSET(pass);\n         }\n\n         else\n         {\n            y = 0;\n            startx = 0;\n            stepx = stepy = 1;\n         }\n\n         for (; y<height; y += stepy)\n         {\n            png_bytep inrow = png_voidcast(png_bytep, display->local_row);\n            png_bytep outrow = first_row + y * step_row;\n            png_const_bytep end_row = outrow + width;\n\n            /* Read read the libpng data into the temporary buffer. */\n            png_read_row(png_ptr, inrow, NULL);\n\n            /* Now process the row according to the processing option, note\n             * that the caller verifies that the format of the libpng output\n             * data is as required.\n             */\n            outrow += startx;\n            switch (proc)\n            {\n               case PNG_CMAP_GA:\n                  for (; outrow < end_row; outrow += stepx)\n                  {\n                     /* The data is always in the PNG order */\n                     unsigned int gray = *inrow++;\n                     unsigned int alpha = *inrow++;\n                     unsigned int entry;\n\n                     /* NOTE: this code is copied as a comment in\n                      * make_ga_colormap above.  Please update the\n                      * comment if you change this code!\n                      */\n                     if (alpha > 229) /* opaque */\n                     {\n                        entry = (231 * gray + 128) >> 8;\n                     }\n                     else if (alpha < 26) /* transparent */\n                     {\n                        entry = 231;\n                     }\n                     else /* partially opaque */\n                     {\n                        entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray);\n                     }\n\n                     *outrow = (png_byte)entry;\n                  }\n                  break;\n\n               case PNG_CMAP_TRANS:\n                  for (; outrow < end_row; outrow += stepx)\n                  {\n                     png_byte gray = *inrow++;\n                     png_byte alpha = *inrow++;\n\n                     if (alpha == 0)\n                        *outrow = PNG_CMAP_TRANS_BACKGROUND;\n\n                     else if (gray != PNG_CMAP_TRANS_BACKGROUND)\n                        *outrow = gray;\n\n                     else\n                        *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1);\n                  }\n                  break;\n\n               case PNG_CMAP_RGB:\n                  for (; outrow < end_row; outrow += stepx)\n                  {\n                     *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]);\n                     inrow += 3;\n                  }\n                  break;\n\n               case PNG_CMAP_RGB_ALPHA:\n                  for (; outrow < end_row; outrow += stepx)\n                  {\n                     unsigned int alpha = inrow[3];\n\n                     /* Because the alpha entries only hold alpha==0.5 values\n                      * split the processing at alpha==0.25 (64) and 0.75\n                      * (196).\n                      */\n\n                     if (alpha >= 196)\n                        *outrow = PNG_RGB_INDEX(inrow[0], inrow[1],\n                           inrow[2]);\n\n                     else if (alpha < 64)\n                        *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND;\n\n                     else\n                     {\n                        /* Likewise there are three entries for each of r, g\n                         * and b.  We could select the entry by popcount on\n                         * the top two bits on those architectures that\n                         * support it, this is what the code below does,\n                         * crudely.\n                         */\n                        unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1;\n\n                        /* Here are how the values map:\n                         *\n                         * 0x00 .. 0x3f -> 0\n                         * 0x40 .. 0xbf -> 1\n                         * 0xc0 .. 0xff -> 2\n                         *\n                         * So, as above with the explicit alpha checks, the\n                         * breakpoints are at 64 and 196.\n                         */\n                        if (inrow[0] & 0x80) back_i += 9; /* red */\n                        if (inrow[0] & 0x40) back_i += 9;\n                        if (inrow[0] & 0x80) back_i += 3; /* green */\n                        if (inrow[0] & 0x40) back_i += 3;\n                        if (inrow[0] & 0x80) back_i += 1; /* blue */\n                        if (inrow[0] & 0x40) back_i += 1;\n\n                        *outrow = (png_byte)back_i;\n                     }\n\n                     inrow += 4;\n                  }\n                  break;\n\n               default:\n                  break;\n            }\n         }\n      }\n   }\n\n   return 1;\n}\n\nstatic int\npng_image_read_colormapped(png_voidp argument)\n{\n   png_image_read_control *display = png_voidcast(png_image_read_control*,\n      argument);\n   png_imagep image = display->image;\n   png_controlp control = image->opaque;\n   png_structrp png_ptr = control->png_ptr;\n   png_inforp info_ptr = control->info_ptr;\n\n   int passes = 0; /* As a flag */\n\n   PNG_SKIP_CHUNKS(png_ptr);\n\n   /* Update the 'info' structure and make sure the result is as required; first\n    * make sure to turn on the interlace handling if it will be required\n    * (because it can't be turned on *after* the call to png_read_update_info!)\n    */\n   if (display->colormap_processing == PNG_CMAP_NONE)\n      passes = png_set_interlace_handling(png_ptr);\n\n   png_read_update_info(png_ptr, info_ptr);\n\n   /* The expected output can be deduced from the colormap_processing option. */\n   switch (display->colormap_processing)\n   {\n      case PNG_CMAP_NONE:\n         /* Output must be one channel and one byte per pixel, the output\n          * encoding can be anything.\n          */\n         if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||\n            info_ptr->color_type == PNG_COLOR_TYPE_GRAY) &&\n            info_ptr->bit_depth == 8)\n            break;\n\n         goto bad_output;\n\n      case PNG_CMAP_TRANS:\n      case PNG_CMAP_GA:\n         /* Output must be two channels and the 'G' one must be sRGB, the latter\n          * can be checked with an exact number because it should have been set\n          * to this number above!\n          */\n         if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&\n            info_ptr->bit_depth == 8 &&\n            png_ptr->screen_gamma == PNG_GAMMA_sRGB &&\n            image->colormap_entries == 256)\n            break;\n\n         goto bad_output;\n\n      case PNG_CMAP_RGB:\n         /* Output must be 8-bit sRGB encoded RGB */\n         if (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&\n            info_ptr->bit_depth == 8 &&\n            png_ptr->screen_gamma == PNG_GAMMA_sRGB &&\n            image->colormap_entries == 216)\n            break;\n\n         goto bad_output;\n\n      case PNG_CMAP_RGB_ALPHA:\n         /* Output must be 8-bit sRGB encoded RGBA */\n         if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&\n            info_ptr->bit_depth == 8 &&\n            png_ptr->screen_gamma == PNG_GAMMA_sRGB &&\n            image->colormap_entries == 244 /* 216 + 1 + 27 */)\n            break;\n\n         /* goto bad_output; */\n         /* FALL THROUGH */\n\n      default:\n      bad_output:\n         png_error(png_ptr, \"bad color-map processing (internal error)\");\n   }\n\n   /* Now read the rows.  Do this here if it is possible to read directly into\n    * the output buffer, otherwise allocate a local row buffer of the maximum\n    * size libpng requires and call the relevant processing routine safely.\n    */\n   {\n      png_voidp first_row = display->buffer;\n      ptrdiff_t row_bytes = display->row_stride;\n\n      /* The following expression is designed to work correctly whether it gives\n       * a signed or an unsigned result.\n       */\n      if (row_bytes < 0)\n      {\n         char *ptr = png_voidcast(char*, first_row);\n         ptr += (image->height-1) * (-row_bytes);\n         first_row = png_voidcast(png_voidp, ptr);\n      }\n\n      display->first_row = first_row;\n      display->row_bytes = row_bytes;\n   }\n\n   if (passes == 0)\n   {\n      int result;\n      png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));\n\n      display->local_row = row;\n      result = png_safe_execute(image, png_image_read_and_map, display);\n      display->local_row = NULL;\n      png_free(png_ptr, row);\n\n      return result;\n   }\n\n   else\n   {\n      png_alloc_size_t row_bytes = display->row_bytes;\n\n      while (--passes >= 0)\n      {\n         png_uint_32      y = image->height;\n         png_bytep        row = png_voidcast(png_bytep, display->first_row);\n\n         while (y-- > 0)\n         {\n            png_read_row(png_ptr, row, NULL);\n            row += row_bytes;\n         }\n      }\n\n      return 1;\n   }\n}\n\n/* Just the row reading part of png_image_read. */\nstatic int\npng_image_read_composite(png_voidp argument)\n{\n   png_image_read_control *display = png_voidcast(png_image_read_control*,\n      argument);\n   png_imagep image = display->image;\n   png_structrp png_ptr = image->opaque->png_ptr;\n   int passes;\n\n   switch (png_ptr->interlaced)\n   {\n      case PNG_INTERLACE_NONE:\n         passes = 1;\n         break;\n\n      case PNG_INTERLACE_ADAM7:\n         passes = PNG_INTERLACE_ADAM7_PASSES;\n         break;\n\n      default:\n         png_error(png_ptr, \"unknown interlace type\");\n   }\n\n   {\n      png_uint_32  height = image->height;\n      png_uint_32  width = image->width;\n      ptrdiff_t    step_row = display->row_bytes;\n      unsigned int channels =\n          (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;\n      int pass;\n\n      for (pass = 0; pass < passes; ++pass)\n      {\n         unsigned int     startx, stepx, stepy;\n         png_uint_32      y;\n\n         if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)\n         {\n            /* The row may be empty for a short image: */\n            if (PNG_PASS_COLS(width, pass) == 0)\n               continue;\n\n            startx = PNG_PASS_START_COL(pass) * channels;\n            stepx = PNG_PASS_COL_OFFSET(pass) * channels;\n            y = PNG_PASS_START_ROW(pass);\n            stepy = PNG_PASS_ROW_OFFSET(pass);\n         }\n\n         else\n         {\n            y = 0;\n            startx = 0;\n            stepx = channels;\n            stepy = 1;\n         }\n\n         for (; y<height; y += stepy)\n         {\n            png_bytep inrow = png_voidcast(png_bytep, display->local_row);\n            png_bytep outrow;\n            png_const_bytep end_row;\n\n            /* Read the row, which is packed: */\n            png_read_row(png_ptr, inrow, NULL);\n\n            outrow = png_voidcast(png_bytep, display->first_row);\n            outrow += y * step_row;\n            end_row = outrow + width * channels;\n\n            /* Now do the composition on each pixel in this row. */\n            outrow += startx;\n            for (; outrow < end_row; outrow += stepx)\n            {\n               png_byte alpha = inrow[channels];\n\n               if (alpha > 0) /* else no change to the output */\n               {\n                  unsigned int c;\n\n                  for (c=0; c<channels; ++c)\n                  {\n                     png_uint_32 component = inrow[c];\n\n                     if (alpha < 255) /* else just use component */\n                     {\n                        /* This is PNG_OPTIMIZED_ALPHA, the component value\n                         * is a linear 8-bit value.  Combine this with the\n                         * current outrow[c] value which is sRGB encoded.\n                         * Arithmetic here is 16-bits to preserve the output\n                         * values correctly.\n                         */\n                        component *= 257*255; /* =65535 */\n                        component += (255-alpha)*png_sRGB_table[outrow[c]];\n\n                        /* So 'component' is scaled by 255*65535 and is\n                         * therefore appropriate for the sRGB to linear\n                         * conversion table.\n                         */\n                        component = PNG_sRGB_FROM_LINEAR(component);\n                     }\n\n                     outrow[c] = (png_byte)component;\n                  }\n               }\n\n               inrow += channels+1; /* components and alpha channel */\n            }\n         }\n      }\n   }\n\n   return 1;\n}\n\n/* The do_local_background case; called when all the following transforms are to\n * be done:\n *\n * PNG_RGB_TO_GRAY\n * PNG_COMPOSITE\n * PNG_GAMMA\n *\n * This is a work-around for the fact that both the PNG_RGB_TO_GRAY and\n * PNG_COMPOSITE code performs gamma correction, so we get double gamma\n * correction.  The fix-up is to prevent the PNG_COMPOSITE operation from\n * happening inside libpng, so this routine sees an 8 or 16-bit gray+alpha\n * row and handles the removal or pre-multiplication of the alpha channel.\n */\nstatic int\npng_image_read_background(png_voidp argument)\n{\n   png_image_read_control *display = png_voidcast(png_image_read_control*,\n      argument);\n   png_imagep image = display->image;\n   png_structrp png_ptr = image->opaque->png_ptr;\n   png_inforp info_ptr = image->opaque->info_ptr;\n   png_uint_32 height = image->height;\n   png_uint_32 width = image->width;\n   int pass, passes;\n\n   /* Double check the convoluted logic below.  We expect to get here with\n    * libpng doing rgb to gray and gamma correction but background processing\n    * left to the png_image_read_background function.  The rows libpng produce\n    * might be 8 or 16-bit but should always have two channels; gray plus alpha.\n    */\n   if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)\n      png_error(png_ptr, \"lost rgb to gray\");\n\n   if ((png_ptr->transformations & PNG_COMPOSE) != 0)\n      png_error(png_ptr, \"unexpected compose\");\n\n   if (png_get_channels(png_ptr, info_ptr) != 2)\n      png_error(png_ptr, \"lost/gained channels\");\n\n   /* Expect the 8-bit case to always remove the alpha channel */\n   if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 &&\n      (image->format & PNG_FORMAT_FLAG_ALPHA) != 0)\n      png_error(png_ptr, \"unexpected 8-bit transformation\");\n\n   switch (png_ptr->interlaced)\n   {\n      case PNG_INTERLACE_NONE:\n         passes = 1;\n         break;\n\n      case PNG_INTERLACE_ADAM7:\n         passes = PNG_INTERLACE_ADAM7_PASSES;\n         break;\n\n      default:\n         png_error(png_ptr, \"unknown interlace type\");\n   }\n\n   /* Use direct access to info_ptr here because otherwise the simplified API\n    * would require PNG_EASY_ACCESS_SUPPORTED (just for this.)  Note this is\n    * checking the value after libpng expansions, not the original value in the\n    * PNG.\n    */\n   switch (info_ptr->bit_depth)\n   {\n      case 8:\n         /* 8-bit sRGB gray values with an alpha channel; the alpha channel is\n          * to be removed by composing on a background: either the row if\n          * display->background is NULL or display->background->green if not.\n          * Unlike the code above ALPHA_OPTIMIZED has *not* been done.\n          */\n         {\n            png_bytep first_row = png_voidcast(png_bytep, display->first_row);\n            ptrdiff_t step_row = display->row_bytes;\n\n            for (pass = 0; pass < passes; ++pass)\n            {\n               png_bytep        row = png_voidcast(png_bytep,\n                                                   display->first_row);\n               unsigned int     startx, stepx, stepy;\n               png_uint_32      y;\n\n               if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)\n               {\n                  /* The row may be empty for a short image: */\n                  if (PNG_PASS_COLS(width, pass) == 0)\n                     continue;\n\n                  startx = PNG_PASS_START_COL(pass);\n                  stepx = PNG_PASS_COL_OFFSET(pass);\n                  y = PNG_PASS_START_ROW(pass);\n                  stepy = PNG_PASS_ROW_OFFSET(pass);\n               }\n\n               else\n               {\n                  y = 0;\n                  startx = 0;\n                  stepx = stepy = 1;\n               }\n\n               if (display->background == NULL)\n               {\n                  for (; y<height; y += stepy)\n                  {\n                     png_bytep inrow = png_voidcast(png_bytep,\n                        display->local_row);\n                     png_bytep outrow = first_row + y * step_row;\n                     png_const_bytep end_row = outrow + width;\n\n                     /* Read the row, which is packed: */\n                     png_read_row(png_ptr, inrow, NULL);\n\n                     /* Now do the composition on each pixel in this row. */\n                     outrow += startx;\n                     for (; outrow < end_row; outrow += stepx)\n                     {\n                        png_byte alpha = inrow[1];\n\n                        if (alpha > 0) /* else no change to the output */\n                        {\n                           png_uint_32 component = inrow[0];\n\n                           if (alpha < 255) /* else just use component */\n                           {\n                              /* Since PNG_OPTIMIZED_ALPHA was not set it is\n                               * necessary to invert the sRGB transfer\n                               * function and multiply the alpha out.\n                               */\n                              component = png_sRGB_table[component] * alpha;\n                              component += png_sRGB_table[outrow[0]] *\n                                 (255-alpha);\n                              component = PNG_sRGB_FROM_LINEAR(component);\n                           }\n\n                           outrow[0] = (png_byte)component;\n                        }\n\n                        inrow += 2; /* gray and alpha channel */\n                     }\n                  }\n               }\n\n               else /* constant background value */\n               {\n                  png_byte background8 = display->background->green;\n                  png_uint_16 background = png_sRGB_table[background8];\n\n                  for (; y<height; y += stepy)\n                  {\n                     png_bytep inrow = png_voidcast(png_bytep,\n                        display->local_row);\n                     png_bytep outrow = first_row + y * step_row;\n                     png_const_bytep end_row = outrow + width;\n\n                     /* Read the row, which is packed: */\n                     png_read_row(png_ptr, inrow, NULL);\n\n                     /* Now do the composition on each pixel in this row. */\n                     outrow += startx;\n                     for (; outrow < end_row; outrow += stepx)\n                     {\n                        png_byte alpha = inrow[1];\n\n                        if (alpha > 0) /* else use background */\n                        {\n                           png_uint_32 component = inrow[0];\n\n                           if (alpha < 255) /* else just use component */\n                           {\n                              component = png_sRGB_table[component] * alpha;\n                              component += background * (255-alpha);\n                              component = PNG_sRGB_FROM_LINEAR(component);\n                           }\n\n                           outrow[0] = (png_byte)component;\n                        }\n\n                        else\n                           outrow[0] = background8;\n\n                        inrow += 2; /* gray and alpha channel */\n                     }\n\n                     row += display->row_bytes;\n                  }\n               }\n            }\n         }\n         break;\n\n      case 16:\n         /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must\n          * still be done and, maybe, the alpha channel removed.  This code also\n          * handles the alpha-first option.\n          */\n         {\n            png_uint_16p first_row = png_voidcast(png_uint_16p,\n               display->first_row);\n            /* The division by two is safe because the caller passed in a\n             * stride which was multiplied by 2 (below) to get row_bytes.\n             */\n            ptrdiff_t    step_row = display->row_bytes / 2;\n            int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;\n            unsigned int outchannels = 1+preserve_alpha;\n            int swap_alpha = 0;\n\n#           ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED\n               if (preserve_alpha != 0 &&\n                   (image->format & PNG_FORMAT_FLAG_AFIRST) != 0)\n                  swap_alpha = 1;\n#           endif\n\n            for (pass = 0; pass < passes; ++pass)\n            {\n               unsigned int     startx, stepx, stepy;\n               png_uint_32      y;\n\n               /* The 'x' start and step are adjusted to output components here.\n                */\n               if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)\n               {\n                  /* The row may be empty for a short image: */\n                  if (PNG_PASS_COLS(width, pass) == 0)\n                     continue;\n\n                  startx = PNG_PASS_START_COL(pass) * outchannels;\n                  stepx = PNG_PASS_COL_OFFSET(pass) * outchannels;\n                  y = PNG_PASS_START_ROW(pass);\n                  stepy = PNG_PASS_ROW_OFFSET(pass);\n               }\n\n               else\n               {\n                  y = 0;\n                  startx = 0;\n                  stepx = outchannels;\n                  stepy = 1;\n               }\n\n               for (; y<height; y += stepy)\n               {\n                  png_const_uint_16p inrow;\n                  png_uint_16p outrow = first_row + y*step_row;\n                  png_uint_16p end_row = outrow + width * outchannels;\n\n                  /* Read the row, which is packed: */\n                  png_read_row(png_ptr, png_voidcast(png_bytep,\n                     display->local_row), NULL);\n                  inrow = png_voidcast(png_const_uint_16p, display->local_row);\n\n                  /* Now do the pre-multiplication on each pixel in this row.\n                   */\n                  outrow += startx;\n                  for (; outrow < end_row; outrow += stepx)\n                  {\n                     png_uint_32 component = inrow[0];\n                     png_uint_16 alpha = inrow[1];\n\n                     if (alpha > 0) /* else 0 */\n                     {\n                        if (alpha < 65535) /* else just use component */\n                        {\n                           component *= alpha;\n                           component += 32767;\n                           component /= 65535;\n                        }\n                     }\n\n                     else\n                        component = 0;\n\n                     outrow[swap_alpha] = (png_uint_16)component;\n                     if (preserve_alpha != 0)\n                        outrow[1 ^ swap_alpha] = alpha;\n\n                     inrow += 2; /* components and alpha channel */\n                  }\n               }\n            }\n         }\n         break;\n\n#ifdef __GNUC__\n      default:\n         png_error(png_ptr, \"unexpected bit depth\");\n#endif\n   }\n\n   return 1;\n}\n\n/* The guts of png_image_finish_read as a png_safe_execute callback. */\nstatic int\npng_image_read_direct(png_voidp argument)\n{\n   png_image_read_control *display = png_voidcast(png_image_read_control*,\n      argument);\n   png_imagep image = display->image;\n   png_structrp png_ptr = image->opaque->png_ptr;\n   png_inforp info_ptr = image->opaque->info_ptr;\n\n   png_uint_32 format = image->format;\n   int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0;\n   int do_local_compose = 0;\n   int do_local_background = 0; /* to avoid double gamma correction bug */\n   int passes = 0;\n\n   /* Add transforms to ensure the correct output format is produced then check\n    * that the required implementation support is there.  Always expand; always\n    * need 8 bits minimum, no palette and expanded tRNS.\n    */\n   png_set_expand(png_ptr);\n\n   /* Now check the format to see if it was modified. */\n   {\n      png_uint_32 base_format = png_image_format(png_ptr) &\n         ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */;\n      png_uint_32 change = format ^ base_format;\n      png_fixed_point output_gamma;\n      int mode; /* alpha mode */\n\n      /* Do this first so that we have a record if rgb to gray is happening. */\n      if ((change & PNG_FORMAT_FLAG_COLOR) != 0)\n      {\n         /* gray<->color transformation required. */\n         if ((format & PNG_FORMAT_FLAG_COLOR) != 0)\n            png_set_gray_to_rgb(png_ptr);\n\n         else\n         {\n            /* libpng can't do both rgb to gray and\n             * background/pre-multiplication if there is also significant gamma\n             * correction, because both operations require linear colors and\n             * the code only supports one transform doing the gamma correction.\n             * Handle this by doing the pre-multiplication or background\n             * operation in this code, if necessary.\n             *\n             * TODO: fix this by rewriting pngrtran.c (!)\n             *\n             * For the moment (given that fixing this in pngrtran.c is an\n             * enormous change) 'do_local_background' is used to indicate that\n             * the problem exists.\n             */\n            if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)\n               do_local_background = 1/*maybe*/;\n\n            png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE,\n               PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);\n         }\n\n         change &= ~PNG_FORMAT_FLAG_COLOR;\n      }\n\n      /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise.\n       */\n      {\n         png_fixed_point input_gamma_default;\n\n         if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 &&\n             (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)\n            input_gamma_default = PNG_GAMMA_LINEAR;\n         else\n            input_gamma_default = PNG_DEFAULT_sRGB;\n\n         /* Call png_set_alpha_mode to set the default for the input gamma; the\n          * output gamma is set by a second call below.\n          */\n         png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default);\n      }\n\n      if (linear != 0)\n      {\n         /* If there *is* an alpha channel in the input it must be multiplied\n          * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG.\n          */\n         if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)\n            mode = PNG_ALPHA_STANDARD; /* associated alpha */\n\n         else\n            mode = PNG_ALPHA_PNG;\n\n         output_gamma = PNG_GAMMA_LINEAR;\n      }\n\n      else\n      {\n         mode = PNG_ALPHA_PNG;\n         output_gamma = PNG_DEFAULT_sRGB;\n      }\n\n      /* If 'do_local_background' is set check for the presence of gamma\n       * correction; this is part of the work-round for the libpng bug\n       * described above.\n       *\n       * TODO: fix libpng and remove this.\n       */\n      if (do_local_background != 0)\n      {\n         png_fixed_point gtest;\n\n         /* This is 'png_gamma_threshold' from pngrtran.c; the test used for\n          * gamma correction, the screen gamma hasn't been set on png_struct\n          * yet; it's set below.  png_struct::gamma, however, is set to the\n          * final value.\n          */\n         if (png_muldiv(&gtest, output_gamma, png_ptr->colorspace.gamma,\n               PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0)\n            do_local_background = 0;\n\n         else if (mode == PNG_ALPHA_STANDARD)\n         {\n            do_local_background = 2/*required*/;\n            mode = PNG_ALPHA_PNG; /* prevent libpng doing it */\n         }\n\n         /* else leave as 1 for the checks below */\n      }\n\n      /* If the bit-depth changes then handle that here. */\n      if ((change & PNG_FORMAT_FLAG_LINEAR) != 0)\n      {\n         if (linear != 0 /*16-bit output*/)\n            png_set_expand_16(png_ptr);\n\n         else /* 8-bit output */\n            png_set_scale_16(png_ptr);\n\n         change &= ~PNG_FORMAT_FLAG_LINEAR;\n      }\n\n      /* Now the background/alpha channel changes. */\n      if ((change & PNG_FORMAT_FLAG_ALPHA) != 0)\n      {\n         /* Removing an alpha channel requires composition for the 8-bit\n          * formats; for the 16-bit it is already done, above, by the\n          * pre-multiplication and the channel just needs to be stripped.\n          */\n         if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)\n         {\n            /* If RGB->gray is happening the alpha channel must be left and the\n             * operation completed locally.\n             *\n             * TODO: fix libpng and remove this.\n             */\n            if (do_local_background != 0)\n               do_local_background = 2/*required*/;\n\n            /* 16-bit output: just remove the channel */\n            else if (linear != 0) /* compose on black (well, pre-multiply) */\n               png_set_strip_alpha(png_ptr);\n\n            /* 8-bit output: do an appropriate compose */\n            else if (display->background != NULL)\n            {\n               png_color_16 c;\n\n               c.index = 0; /*unused*/\n               c.red = display->background->red;\n               c.green = display->background->green;\n               c.blue = display->background->blue;\n               c.gray = display->background->green;\n\n               /* This is always an 8-bit sRGB value, using the 'green' channel\n                * for gray is much better than calculating the luminance here;\n                * we can get off-by-one errors in that calculation relative to\n                * the app expectations and that will show up in transparent\n                * pixels.\n                */\n               png_set_background_fixed(png_ptr, &c,\n                  PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,\n                  0/*gamma: not used*/);\n            }\n\n            else /* compose on row: implemented below. */\n            {\n               do_local_compose = 1;\n               /* This leaves the alpha channel in the output, so it has to be\n                * removed by the code below.  Set the encoding to the 'OPTIMIZE'\n                * one so the code only has to hack on the pixels that require\n                * composition.\n                */\n               mode = PNG_ALPHA_OPTIMIZED;\n            }\n         }\n\n         else /* output needs an alpha channel */\n         {\n            /* This is tricky because it happens before the swap operation has\n             * been accomplished; however, the swap does *not* swap the added\n             * alpha channel (weird API), so it must be added in the correct\n             * place.\n             */\n            png_uint_32 filler; /* opaque filler */\n            int where;\n\n            if (linear != 0)\n               filler = 65535;\n\n            else\n               filler = 255;\n\n#           ifdef PNG_FORMAT_AFIRST_SUPPORTED\n               if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)\n               {\n                  where = PNG_FILLER_BEFORE;\n                  change &= ~PNG_FORMAT_FLAG_AFIRST;\n               }\n\n               else\n#           endif\n               where = PNG_FILLER_AFTER;\n\n            png_set_add_alpha(png_ptr, filler, where);\n         }\n\n         /* This stops the (irrelevant) call to swap_alpha below. */\n         change &= ~PNG_FORMAT_FLAG_ALPHA;\n      }\n\n      /* Now set the alpha mode correctly; this is always done, even if there is\n       * no alpha channel in either the input or the output because it correctly\n       * sets the output gamma.\n       */\n      png_set_alpha_mode_fixed(png_ptr, mode, output_gamma);\n\n#     ifdef PNG_FORMAT_BGR_SUPPORTED\n         if ((change & PNG_FORMAT_FLAG_BGR) != 0)\n         {\n            /* Check only the output format; PNG is never BGR; don't do this if\n             * the output is gray, but fix up the 'format' value in that case.\n             */\n            if ((format & PNG_FORMAT_FLAG_COLOR) != 0)\n               png_set_bgr(png_ptr);\n\n            else\n               format &= ~PNG_FORMAT_FLAG_BGR;\n\n            change &= ~PNG_FORMAT_FLAG_BGR;\n         }\n#     endif\n\n#     ifdef PNG_FORMAT_AFIRST_SUPPORTED\n         if ((change & PNG_FORMAT_FLAG_AFIRST) != 0)\n         {\n            /* Only relevant if there is an alpha channel - it's particularly\n             * important to handle this correctly because do_local_compose may\n             * be set above and then libpng will keep the alpha channel for this\n             * code to remove.\n             */\n            if ((format & PNG_FORMAT_FLAG_ALPHA) != 0)\n            {\n               /* Disable this if doing a local background,\n                * TODO: remove this when local background is no longer required.\n                */\n               if (do_local_background != 2)\n                  png_set_swap_alpha(png_ptr);\n            }\n\n            else\n               format &= ~PNG_FORMAT_FLAG_AFIRST;\n\n            change &= ~PNG_FORMAT_FLAG_AFIRST;\n         }\n#     endif\n\n      /* If the *output* is 16-bit then we need to check for a byte-swap on this\n       * architecture.\n       */\n      if (linear != 0)\n      {\n         PNG_CONST png_uint_16 le = 0x0001;\n\n         if ((*(png_const_bytep) & le) != 0)\n            png_set_swap(png_ptr);\n      }\n\n      /* If change is not now 0 some transformation is missing - error out. */\n      if (change != 0)\n         png_error(png_ptr, \"png_read_image: unsupported transformation\");\n   }\n\n   PNG_SKIP_CHUNKS(png_ptr);\n\n   /* Update the 'info' structure and make sure the result is as required; first\n    * make sure to turn on the interlace handling if it will be required\n    * (because it can't be turned on *after* the call to png_read_update_info!)\n    *\n    * TODO: remove the do_local_background fixup below.\n    */\n   if (do_local_compose == 0 && do_local_background != 2)\n      passes = png_set_interlace_handling(png_ptr);\n\n   png_read_update_info(png_ptr, info_ptr);\n\n   {\n      png_uint_32 info_format = 0;\n\n      if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)\n         info_format |= PNG_FORMAT_FLAG_COLOR;\n\n      if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)\n      {\n         /* do_local_compose removes this channel below. */\n         if (do_local_compose == 0)\n         {\n            /* do_local_background does the same if required. */\n            if (do_local_background != 2 ||\n               (format & PNG_FORMAT_FLAG_ALPHA) != 0)\n               info_format |= PNG_FORMAT_FLAG_ALPHA;\n         }\n      }\n\n      else if (do_local_compose != 0) /* internal error */\n         png_error(png_ptr, \"png_image_read: alpha channel lost\");\n\n      if (info_ptr->bit_depth == 16)\n         info_format |= PNG_FORMAT_FLAG_LINEAR;\n\n#     ifdef PNG_FORMAT_BGR_SUPPORTED\n         if ((png_ptr->transformations & PNG_BGR) != 0)\n            info_format |= PNG_FORMAT_FLAG_BGR;\n#     endif\n\n#     ifdef PNG_FORMAT_AFIRST_SUPPORTED\n         if (do_local_background == 2)\n         {\n            if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)\n               info_format |= PNG_FORMAT_FLAG_AFIRST;\n         }\n\n         if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 ||\n            ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 &&\n            (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0))\n         {\n            if (do_local_background == 2)\n               png_error(png_ptr, \"unexpected alpha swap transformation\");\n\n            info_format |= PNG_FORMAT_FLAG_AFIRST;\n         }\n#     endif\n\n      /* This is actually an internal error. */\n      if (info_format != format)\n         png_error(png_ptr, \"png_read_image: invalid transformations\");\n   }\n\n   /* Now read the rows.  If do_local_compose is set then it is necessary to use\n    * a local row buffer.  The output will be GA, RGBA or BGRA and must be\n    * converted to G, RGB or BGR as appropriate.  The 'local_row' member of the\n    * display acts as a flag.\n    */\n   {\n      png_voidp first_row = display->buffer;\n      ptrdiff_t row_bytes = display->row_stride;\n\n      if (linear != 0)\n         row_bytes *= 2;\n\n      /* The following expression is designed to work correctly whether it gives\n       * a signed or an unsigned result.\n       */\n      if (row_bytes < 0)\n      {\n         char *ptr = png_voidcast(char*, first_row);\n         ptr += (image->height-1) * (-row_bytes);\n         first_row = png_voidcast(png_voidp, ptr);\n      }\n\n      display->first_row = first_row;\n      display->row_bytes = row_bytes;\n   }\n\n   if (do_local_compose != 0)\n   {\n      int result;\n      png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));\n\n      display->local_row = row;\n      result = png_safe_execute(image, png_image_read_composite, display);\n      display->local_row = NULL;\n      png_free(png_ptr, row);\n\n      return result;\n   }\n\n   else if (do_local_background == 2)\n   {\n      int result;\n      png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));\n\n      display->local_row = row;\n      result = png_safe_execute(image, png_image_read_background, display);\n      display->local_row = NULL;\n      png_free(png_ptr, row);\n\n      return result;\n   }\n\n   else\n   {\n      png_alloc_size_t row_bytes = display->row_bytes;\n\n      while (--passes >= 0)\n      {\n         png_uint_32      y = image->height;\n         png_bytep        row = png_voidcast(png_bytep, display->first_row);\n\n         while (y-- > 0)\n         {\n            png_read_row(png_ptr, row, NULL);\n            row += row_bytes;\n         }\n      }\n\n      return 1;\n   }\n}\n\nint PNGAPI\npng_image_finish_read(png_imagep image, png_const_colorp background,\n   void *buffer, png_int_32 row_stride, void *colormap)\n{\n   if (image != NULL && image->version == PNG_IMAGE_VERSION)\n   {\n      /* Check for row_stride overflow.  This check is not performed on the\n       * original PNG format because it may not occur in the output PNG format\n       * and libpng deals with the issues of reading the original.\n       */\n      const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);\n\n      if (image->width <= 0x7FFFFFFFU/channels) /* no overflow */\n      {\n         png_uint_32 check;\n         const png_uint_32 png_row_stride = image->width * channels;\n\n         if (row_stride == 0)\n            row_stride = (png_int_32)/*SAFE*/png_row_stride;\n\n         if (row_stride < 0)\n            check = -row_stride;\n\n         else\n            check = row_stride;\n\n         if (image->opaque != NULL && buffer != NULL && check >= png_row_stride)\n         {\n            /* Now check for overflow of the image buffer calculation; this\n             * limits the whole image size to 32 bits for API compatibility with\n             * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.\n             */\n            if (image->height <= 0xFFFFFFFF/png_row_stride)\n            {\n               if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||\n                  (image->colormap_entries > 0 && colormap != NULL))\n               {\n                  int result;\n                  png_image_read_control display;\n\n                  memset(&display, 0, (sizeof display));\n                  display.image = image;\n                  display.buffer = buffer;\n                  display.row_stride = row_stride;\n                  display.colormap = colormap;\n                  display.background = background;\n                  display.local_row = NULL;\n\n                  /* Choose the correct 'end' routine; for the color-map case\n                   * all the setup has already been done.\n                   */\n                  if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0)\n                     result = png_safe_execute(image,\n                                    png_image_read_colormap, &display) &&\n                              png_safe_execute(image,\n                                    png_image_read_colormapped, &display);\n\n                  else\n                     result =\n                        png_safe_execute(image,\n                              png_image_read_direct, &display);\n\n                  png_image_free(image);\n                  return result;\n               }\n\n               else\n                  return png_image_error(image,\n                     \"png_image_finish_read[color-map]: no color-map\");\n            }\n\n            else\n               return png_image_error(image,\n                  \"png_image_finish_read: image too large\");\n         }\n\n         else\n            return png_image_error(image,\n               \"png_image_finish_read: invalid argument\");\n      }\n\n      else\n         return png_image_error(image,\n            \"png_image_finish_read: row_stride too large\");\n   }\n\n   else if (image != NULL)\n      return png_image_error(image,\n         \"png_image_finish_read: damaged PNG_IMAGE_VERSION\");\n\n   return 0;\n}\n\n#endif /* SIMPLIFIED_READ */\n#endif /* READ */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngrio.c",
    "content": "\n/* pngrio.c - functions for data input\n *\n * Last changed in libpng 1.6.17 [March 26, 2015]\n * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * This file provides a location for all input.  Users who need\n * special handling are expected to write a function that has the same\n * arguments as this and performs a similar function, but that possibly\n * has a different input method.  Note that you shouldn't change this\n * function, but rather write a replacement function and then make\n * libpng use it at run time with png_set_read_fn(...).\n */\n\n#include \"pngpriv.h\"\n\n#ifdef PNG_READ_SUPPORTED\n\n/* Read the data from whatever input you are using.  The default routine\n * reads from a file pointer.  Note that this routine sometimes gets called\n * with very small lengths, so you should implement some kind of simple\n * buffering if you are using unbuffered reads.  This should never be asked\n * to read more than 64K on a 16-bit machine.\n */\nvoid /* PRIVATE */\npng_read_data(png_structrp png_ptr, png_bytep data, png_size_t length)\n{\n   png_debug1(4, \"reading %d bytes\", (int)length);\n\n   if (png_ptr->read_data_fn != NULL)\n      (*(png_ptr->read_data_fn))(png_ptr, data, length);\n\n   else\n      png_error(png_ptr, \"Call to NULL read function\");\n}\n\n#ifdef PNG_STDIO_SUPPORTED\n/* This is the function that does the actual reading of data.  If you are\n * not reading from a standard C stream, you should create a replacement\n * read_data function and use it at run time with png_set_read_fn(), rather\n * than changing the library.\n */\nvoid PNGCBAPI\npng_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)\n{\n   png_size_t check;\n\n   if (png_ptr == NULL)\n      return;\n\n   /* fread() returns 0 on error, so it is OK to store this in a png_size_t\n    * instead of an int, which is what fread() actually returns.\n    */\n   check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr));\n\n   if (check != length)\n      png_error(png_ptr, \"Read Error\");\n}\n#endif\n\n/* This function allows the application to supply a new input function\n * for libpng if standard C streams aren't being used.\n *\n * This function takes as its arguments:\n *\n * png_ptr      - pointer to a png input data structure\n *\n * io_ptr       - pointer to user supplied structure containing info about\n *                the input functions.  May be NULL.\n *\n * read_data_fn - pointer to a new input function that takes as its\n *                arguments a pointer to a png_struct, a pointer to\n *                a location where input data can be stored, and a 32-bit\n *                unsigned int that is the number of bytes to be read.\n *                To exit and output any fatal error messages the new write\n *                function should call png_error(png_ptr, \"Error msg\").\n *                May be NULL, in which case libpng's default function will\n *                be used.\n */\nvoid PNGAPI\npng_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,\n   png_rw_ptr read_data_fn)\n{\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->io_ptr = io_ptr;\n\n#ifdef PNG_STDIO_SUPPORTED\n   if (read_data_fn != NULL)\n      png_ptr->read_data_fn = read_data_fn;\n\n   else\n      png_ptr->read_data_fn = png_default_read_data;\n#else\n   png_ptr->read_data_fn = read_data_fn;\n#endif\n\n#ifdef PNG_WRITE_SUPPORTED\n   /* It is an error to write to a read device */\n   if (png_ptr->write_data_fn != NULL)\n   {\n      png_ptr->write_data_fn = NULL;\n      png_warning(png_ptr,\n          \"Can't set both read_data_fn and write_data_fn in the\"\n          \" same structure\");\n   }\n#endif\n\n#ifdef PNG_WRITE_FLUSH_SUPPORTED\n   png_ptr->output_flush_fn = NULL;\n#endif\n}\n#endif /* READ */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngrtran.c",
    "content": "\n/* pngrtran.c - transforms the data in a row for PNG readers\n *\n * Last changed in libpng 1.6.22 [(PENDING RELEASE)]\n * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * This file contains functions optionally called by an application\n * in order to tell libpng how to handle data when reading a PNG.\n * Transformations that are used in both reading and writing are\n * in pngtrans.c.\n */\n\n#include \"pngpriv.h\"\n\n#ifdef PNG_READ_SUPPORTED\n\n/* Set the action on getting a CRC error for an ancillary or critical chunk. */\nvoid PNGAPI\npng_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)\n{\n   png_debug(1, \"in png_set_crc_action\");\n\n   if (png_ptr == NULL)\n      return;\n\n   /* Tell libpng how we react to CRC errors in critical chunks */\n   switch (crit_action)\n   {\n      case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */\n         break;\n\n      case PNG_CRC_WARN_USE:                               /* Warn/use data */\n         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;\n         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;\n         break;\n\n      case PNG_CRC_QUIET_USE:                             /* Quiet/use data */\n         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;\n         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |\n                           PNG_FLAG_CRC_CRITICAL_IGNORE;\n         break;\n\n      case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */\n         png_warning(png_ptr,\n            \"Can't discard critical data on CRC error\");\n      case PNG_CRC_ERROR_QUIT:                                /* Error/quit */\n\n      case PNG_CRC_DEFAULT:\n      default:\n         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;\n         break;\n   }\n\n   /* Tell libpng how we react to CRC errors in ancillary chunks */\n   switch (ancil_action)\n   {\n      case PNG_CRC_NO_CHANGE:                       /* Leave setting as is */\n         break;\n\n      case PNG_CRC_WARN_USE:                              /* Warn/use data */\n         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;\n         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;\n         break;\n\n      case PNG_CRC_QUIET_USE:                            /* Quiet/use data */\n         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;\n         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |\n                           PNG_FLAG_CRC_ANCILLARY_NOWARN;\n         break;\n\n      case PNG_CRC_ERROR_QUIT:                               /* Error/quit */\n         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;\n         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;\n         break;\n\n      case PNG_CRC_WARN_DISCARD:                      /* Warn/discard data */\n\n      case PNG_CRC_DEFAULT:\n      default:\n         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;\n         break;\n   }\n}\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\n/* Is it OK to set a transformation now?  Only if png_start_read_image or\n * png_read_update_info have not been called.  It is not necessary for the IHDR\n * to have been read in all cases; the need_IHDR parameter allows for this\n * check too.\n */\nstatic int\npng_rtran_ok(png_structrp png_ptr, int need_IHDR)\n{\n   if (png_ptr != NULL)\n   {\n      if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)\n         png_app_error(png_ptr,\n            \"invalid after png_start_read_image or png_read_update_info\");\n\n      else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)\n         png_app_error(png_ptr, \"invalid before the PNG header has been read\");\n\n      else\n      {\n         /* Turn on failure to initialize correctly for all transforms. */\n         png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;\n\n         return 1; /* Ok */\n      }\n   }\n\n   return 0; /* no png_error possible! */\n}\n#endif\n\n#ifdef PNG_READ_BACKGROUND_SUPPORTED\n/* Handle alpha and tRNS via a background color */\nvoid PNGFAPI\npng_set_background_fixed(png_structrp png_ptr,\n    png_const_color_16p background_color, int background_gamma_code,\n    int need_expand, png_fixed_point background_gamma)\n{\n   png_debug(1, \"in png_set_background_fixed\");\n\n   if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL)\n      return;\n\n   if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)\n   {\n      png_warning(png_ptr, \"Application must supply a known background gamma\");\n      return;\n   }\n\n   png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA;\n   png_ptr->transformations &= ~PNG_ENCODE_ALPHA;\n   png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\n\n   png_ptr->background = *background_color;\n   png_ptr->background_gamma = background_gamma;\n   png_ptr->background_gamma_type = (png_byte)(background_gamma_code);\n   if (need_expand != 0)\n      png_ptr->transformations |= PNG_BACKGROUND_EXPAND;\n   else\n      png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;\n}\n\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\nvoid PNGAPI\npng_set_background(png_structrp png_ptr,\n    png_const_color_16p background_color, int background_gamma_code,\n    int need_expand, double background_gamma)\n{\n   png_set_background_fixed(png_ptr, background_color, background_gamma_code,\n      need_expand, png_fixed(png_ptr, background_gamma, \"png_set_background\"));\n}\n#  endif  /* FLOATING_POINT */\n#endif /* READ_BACKGROUND */\n\n/* Scale 16-bit depth files to 8-bit depth.  If both of these are set then the\n * one that pngrtran does first (scale) happens.  This is necessary to allow the\n * TRANSFORM and API behavior to be somewhat consistent, and it's simpler.\n */\n#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\nvoid PNGAPI\npng_set_scale_16(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_scale_16\");\n\n   if (png_rtran_ok(png_ptr, 0) == 0)\n      return;\n\n   png_ptr->transformations |= PNG_SCALE_16_TO_8;\n}\n#endif\n\n#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED\n/* Chop 16-bit depth files to 8-bit depth */\nvoid PNGAPI\npng_set_strip_16(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_strip_16\");\n\n   if (png_rtran_ok(png_ptr, 0) == 0)\n      return;\n\n   png_ptr->transformations |= PNG_16_TO_8;\n}\n#endif\n\n#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED\nvoid PNGAPI\npng_set_strip_alpha(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_strip_alpha\");\n\n   if (png_rtran_ok(png_ptr, 0) == 0)\n      return;\n\n   png_ptr->transformations |= PNG_STRIP_ALPHA;\n}\n#endif\n\n#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)\nstatic png_fixed_point\ntranslate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,\n   int is_screen)\n{\n   /* Check for flag values.  The main reason for having the old Mac value as a\n    * flag is that it is pretty near impossible to work out what the correct\n    * value is from Apple documentation - a working Mac system is needed to\n    * discover the value!\n    */\n   if (output_gamma == PNG_DEFAULT_sRGB ||\n      output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)\n   {\n      /* If there is no sRGB support this just sets the gamma to the standard\n       * sRGB value.  (This is a side effect of using this function!)\n       */\n#     ifdef PNG_READ_sRGB_SUPPORTED\n         png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;\n#     else\n         PNG_UNUSED(png_ptr)\n#     endif\n      if (is_screen != 0)\n         output_gamma = PNG_GAMMA_sRGB;\n      else\n         output_gamma = PNG_GAMMA_sRGB_INVERSE;\n   }\n\n   else if (output_gamma == PNG_GAMMA_MAC_18 ||\n      output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)\n   {\n      if (is_screen != 0)\n         output_gamma = PNG_GAMMA_MAC_OLD;\n      else\n         output_gamma = PNG_GAMMA_MAC_INVERSE;\n   }\n\n   return output_gamma;\n}\n\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\nstatic png_fixed_point\nconvert_gamma_value(png_structrp png_ptr, double output_gamma)\n{\n   /* The following silently ignores cases where fixed point (times 100,000)\n    * gamma values are passed to the floating point API.  This is safe and it\n    * means the fixed point constants work just fine with the floating point\n    * API.  The alternative would just lead to undetected errors and spurious\n    * bug reports.  Negative values fail inside the _fixed API unless they\n    * correspond to the flag values.\n    */\n   if (output_gamma > 0 && output_gamma < 128)\n      output_gamma *= PNG_FP_1;\n\n   /* This preserves -1 and -2 exactly: */\n   output_gamma = floor(output_gamma + .5);\n\n   if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN)\n      png_fixed_error(png_ptr, \"gamma value\");\n\n   return (png_fixed_point)output_gamma;\n}\n#  endif\n#endif /* READ_ALPHA_MODE || READ_GAMMA */\n\n#ifdef PNG_READ_ALPHA_MODE_SUPPORTED\nvoid PNGFAPI\npng_set_alpha_mode_fixed(png_structrp png_ptr, int mode,\n   png_fixed_point output_gamma)\n{\n   int compose = 0;\n   png_fixed_point file_gamma;\n\n   png_debug(1, \"in png_set_alpha_mode\");\n\n   if (png_rtran_ok(png_ptr, 0) == 0)\n      return;\n\n   output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);\n\n   /* Validate the value to ensure it is in a reasonable range. The value\n    * is expected to be 1 or greater, but this range test allows for some\n    * viewing correction values.  The intent is to weed out users of this API\n    * who use the inverse of the gamma value accidentally!  Since some of these\n    * values are reasonable this may have to be changed:\n    *\n    * 1.6.x: changed from 0.07..3 to 0.01..100 (to accomodate the optimal 16-bit\n    * gamma of 36, and its reciprocal.)\n    */\n   if (output_gamma < 1000 || output_gamma > 10000000)\n      png_error(png_ptr, \"output gamma out of expected range\");\n\n   /* The default file gamma is the inverse of the output gamma; the output\n    * gamma may be changed below so get the file value first:\n    */\n   file_gamma = png_reciprocal(output_gamma);\n\n   /* There are really 8 possibilities here, composed of any combination\n    * of:\n    *\n    *    premultiply the color channels\n    *    do not encode non-opaque pixels\n    *    encode the alpha as well as the color channels\n    *\n    * The differences disappear if the input/output ('screen') gamma is 1.0,\n    * because then the encoding is a no-op and there is only the choice of\n    * premultiplying the color channels or not.\n    *\n    * png_set_alpha_mode and png_set_background interact because both use\n    * png_compose to do the work.  Calling both is only useful when\n    * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along\n    * with a default gamma value.  Otherwise PNG_COMPOSE must not be set.\n    */\n   switch (mode)\n   {\n      case PNG_ALPHA_PNG:        /* default: png standard */\n         /* No compose, but it may be set by png_set_background! */\n         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;\n         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\n         break;\n\n      case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */\n         compose = 1;\n         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;\n         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\n         /* The output is linear: */\n         output_gamma = PNG_FP_1;\n         break;\n\n      case PNG_ALPHA_OPTIMIZED:  /* associated, non-opaque pixels linear */\n         compose = 1;\n         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;\n         png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;\n         /* output_gamma records the encoding of opaque pixels! */\n         break;\n\n      case PNG_ALPHA_BROKEN:     /* associated, non-linear, alpha encoded */\n         compose = 1;\n         png_ptr->transformations |= PNG_ENCODE_ALPHA;\n         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\n         break;\n\n      default:\n         png_error(png_ptr, \"invalid alpha mode\");\n   }\n\n   /* Only set the default gamma if the file gamma has not been set (this has\n    * the side effect that the gamma in a second call to png_set_alpha_mode will\n    * be ignored.)\n    */\n   if (png_ptr->colorspace.gamma == 0)\n   {\n      png_ptr->colorspace.gamma = file_gamma;\n      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;\n   }\n\n   /* But always set the output gamma: */\n   png_ptr->screen_gamma = output_gamma;\n\n   /* Finally, if pre-multiplying, set the background fields to achieve the\n    * desired result.\n    */\n   if (compose != 0)\n   {\n      /* And obtain alpha pre-multiplication by composing on black: */\n      memset(&png_ptr->background, 0, (sizeof png_ptr->background));\n      png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */\n      png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;\n      png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;\n\n      if ((png_ptr->transformations & PNG_COMPOSE) != 0)\n         png_error(png_ptr,\n            \"conflicting calls to set alpha mode and background\");\n\n      png_ptr->transformations |= PNG_COMPOSE;\n   }\n}\n\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\nvoid PNGAPI\npng_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)\n{\n   png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,\n      output_gamma));\n}\n#  endif\n#endif\n\n#ifdef PNG_READ_QUANTIZE_SUPPORTED\n/* Dither file to 8-bit.  Supply a palette, the current number\n * of elements in the palette, the maximum number of elements\n * allowed, and a histogram if possible.  If the current number\n * of colors is greater than the maximum number, the palette will be\n * modified to fit in the maximum number.  \"full_quantize\" indicates\n * whether we need a quantizing cube set up for RGB images, or if we\n * simply are reducing the number of colors in a paletted image.\n */\n\ntypedef struct png_dsort_struct\n{\n   struct png_dsort_struct * next;\n   png_byte left;\n   png_byte right;\n} png_dsort;\ntypedef png_dsort *   png_dsortp;\ntypedef png_dsort * * png_dsortpp;\n\nvoid PNGAPI\npng_set_quantize(png_structrp png_ptr, png_colorp palette,\n    int num_palette, int maximum_colors, png_const_uint_16p histogram,\n    int full_quantize)\n{\n   png_debug(1, \"in png_set_quantize\");\n\n   if (png_rtran_ok(png_ptr, 0) == 0)\n      return;\n\n   png_ptr->transformations |= PNG_QUANTIZE;\n\n   if (full_quantize == 0)\n   {\n      int i;\n\n      png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,\n          (png_uint_32)(num_palette * (sizeof (png_byte))));\n      for (i = 0; i < num_palette; i++)\n         png_ptr->quantize_index[i] = (png_byte)i;\n   }\n\n   if (num_palette > maximum_colors)\n   {\n      if (histogram != NULL)\n      {\n         /* This is easy enough, just throw out the least used colors.\n          * Perhaps not the best solution, but good enough.\n          */\n\n         int i;\n\n         /* Initialize an array to sort colors */\n         png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,\n             (png_uint_32)(num_palette * (sizeof (png_byte))));\n\n         /* Initialize the quantize_sort array */\n         for (i = 0; i < num_palette; i++)\n            png_ptr->quantize_sort[i] = (png_byte)i;\n\n         /* Find the least used palette entries by starting a\n          * bubble sort, and running it until we have sorted\n          * out enough colors.  Note that we don't care about\n          * sorting all the colors, just finding which are\n          * least used.\n          */\n\n         for (i = num_palette - 1; i >= maximum_colors; i--)\n         {\n            int done; /* To stop early if the list is pre-sorted */\n            int j;\n\n            done = 1;\n            for (j = 0; j < i; j++)\n            {\n               if (histogram[png_ptr->quantize_sort[j]]\n                   < histogram[png_ptr->quantize_sort[j + 1]])\n               {\n                  png_byte t;\n\n                  t = png_ptr->quantize_sort[j];\n                  png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];\n                  png_ptr->quantize_sort[j + 1] = t;\n                  done = 0;\n               }\n            }\n\n            if (done != 0)\n               break;\n         }\n\n         /* Swap the palette around, and set up a table, if necessary */\n         if (full_quantize != 0)\n         {\n            int j = num_palette;\n\n            /* Put all the useful colors within the max, but don't\n             * move the others.\n             */\n            for (i = 0; i < maximum_colors; i++)\n            {\n               if ((int)png_ptr->quantize_sort[i] >= maximum_colors)\n               {\n                  do\n                     j--;\n                  while ((int)png_ptr->quantize_sort[j] >= maximum_colors);\n\n                  palette[i] = palette[j];\n               }\n            }\n         }\n         else\n         {\n            int j = num_palette;\n\n            /* Move all the used colors inside the max limit, and\n             * develop a translation table.\n             */\n            for (i = 0; i < maximum_colors; i++)\n            {\n               /* Only move the colors we need to */\n               if ((int)png_ptr->quantize_sort[i] >= maximum_colors)\n               {\n                  png_color tmp_color;\n\n                  do\n                     j--;\n                  while ((int)png_ptr->quantize_sort[j] >= maximum_colors);\n\n                  tmp_color = palette[j];\n                  palette[j] = palette[i];\n                  palette[i] = tmp_color;\n                  /* Indicate where the color went */\n                  png_ptr->quantize_index[j] = (png_byte)i;\n                  png_ptr->quantize_index[i] = (png_byte)j;\n               }\n            }\n\n            /* Find closest color for those colors we are not using */\n            for (i = 0; i < num_palette; i++)\n            {\n               if ((int)png_ptr->quantize_index[i] >= maximum_colors)\n               {\n                  int min_d, k, min_k, d_index;\n\n                  /* Find the closest color to one we threw out */\n                  d_index = png_ptr->quantize_index[i];\n                  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);\n                  for (k = 1, min_k = 0; k < maximum_colors; k++)\n                  {\n                     int d;\n\n                     d = PNG_COLOR_DIST(palette[d_index], palette[k]);\n\n                     if (d < min_d)\n                     {\n                        min_d = d;\n                        min_k = k;\n                     }\n                  }\n                  /* Point to closest color */\n                  png_ptr->quantize_index[i] = (png_byte)min_k;\n               }\n            }\n         }\n         png_free(png_ptr, png_ptr->quantize_sort);\n         png_ptr->quantize_sort = NULL;\n      }\n      else\n      {\n         /* This is much harder to do simply (and quickly).  Perhaps\n          * we need to go through a median cut routine, but those\n          * don't always behave themselves with only a few colors\n          * as input.  So we will just find the closest two colors,\n          * and throw out one of them (chosen somewhat randomly).\n          * [We don't understand this at all, so if someone wants to\n          *  work on improving it, be our guest - AED, GRP]\n          */\n         int i;\n         int max_d;\n         int num_new_palette;\n         png_dsortp t;\n         png_dsortpp hash;\n\n         t = NULL;\n\n         /* Initialize palette index arrays */\n         png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,\n             (png_uint_32)(num_palette * (sizeof (png_byte))));\n         png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,\n             (png_uint_32)(num_palette * (sizeof (png_byte))));\n\n         /* Initialize the sort array */\n         for (i = 0; i < num_palette; i++)\n         {\n            png_ptr->index_to_palette[i] = (png_byte)i;\n            png_ptr->palette_to_index[i] = (png_byte)i;\n         }\n\n         hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *\n             (sizeof (png_dsortp))));\n\n         num_new_palette = num_palette;\n\n         /* Initial wild guess at how far apart the farthest pixel\n          * pair we will be eliminating will be.  Larger\n          * numbers mean more areas will be allocated, Smaller\n          * numbers run the risk of not saving enough data, and\n          * having to do this all over again.\n          *\n          * I have not done extensive checking on this number.\n          */\n         max_d = 96;\n\n         while (num_new_palette > maximum_colors)\n         {\n            for (i = 0; i < num_new_palette - 1; i++)\n            {\n               int j;\n\n               for (j = i + 1; j < num_new_palette; j++)\n               {\n                  int d;\n\n                  d = PNG_COLOR_DIST(palette[i], palette[j]);\n\n                  if (d <= max_d)\n                  {\n\n                     t = (png_dsortp)png_malloc_warn(png_ptr,\n                         (png_uint_32)(sizeof (png_dsort)));\n\n                     if (t == NULL)\n                         break;\n\n                     t->next = hash[d];\n                     t->left = (png_byte)i;\n                     t->right = (png_byte)j;\n                     hash[d] = t;\n                  }\n               }\n               if (t == NULL)\n                  break;\n            }\n\n            if (t != NULL)\n            for (i = 0; i <= max_d; i++)\n            {\n               if (hash[i] != NULL)\n               {\n                  png_dsortp p;\n\n                  for (p = hash[i]; p; p = p->next)\n                  {\n                     if ((int)png_ptr->index_to_palette[p->left]\n                         < num_new_palette &&\n                         (int)png_ptr->index_to_palette[p->right]\n                         < num_new_palette)\n                     {\n                        int j, next_j;\n\n                        if (num_new_palette & 0x01)\n                        {\n                           j = p->left;\n                           next_j = p->right;\n                        }\n                        else\n                        {\n                           j = p->right;\n                           next_j = p->left;\n                        }\n\n                        num_new_palette--;\n                        palette[png_ptr->index_to_palette[j]]\n                            = palette[num_new_palette];\n                        if (full_quantize == 0)\n                        {\n                           int k;\n\n                           for (k = 0; k < num_palette; k++)\n                           {\n                              if (png_ptr->quantize_index[k] ==\n                                  png_ptr->index_to_palette[j])\n                                 png_ptr->quantize_index[k] =\n                                     png_ptr->index_to_palette[next_j];\n\n                              if ((int)png_ptr->quantize_index[k] ==\n                                  num_new_palette)\n                                 png_ptr->quantize_index[k] =\n                                     png_ptr->index_to_palette[j];\n                           }\n                        }\n\n                        png_ptr->index_to_palette[png_ptr->palette_to_index\n                            [num_new_palette]] = png_ptr->index_to_palette[j];\n\n                        png_ptr->palette_to_index[png_ptr->index_to_palette[j]]\n                            = png_ptr->palette_to_index[num_new_palette];\n\n                        png_ptr->index_to_palette[j] =\n                            (png_byte)num_new_palette;\n\n                        png_ptr->palette_to_index[num_new_palette] =\n                            (png_byte)j;\n                     }\n                     if (num_new_palette <= maximum_colors)\n                        break;\n                  }\n                  if (num_new_palette <= maximum_colors)\n                     break;\n               }\n            }\n\n            for (i = 0; i < 769; i++)\n            {\n               if (hash[i] != NULL)\n               {\n                  png_dsortp p = hash[i];\n                  while (p)\n                  {\n                     t = p->next;\n                     png_free(png_ptr, p);\n                     p = t;\n                  }\n               }\n               hash[i] = 0;\n            }\n            max_d += 96;\n         }\n         png_free(png_ptr, hash);\n         png_free(png_ptr, png_ptr->palette_to_index);\n         png_free(png_ptr, png_ptr->index_to_palette);\n         png_ptr->palette_to_index = NULL;\n         png_ptr->index_to_palette = NULL;\n      }\n      num_palette = maximum_colors;\n   }\n   if (png_ptr->palette == NULL)\n   {\n      png_ptr->palette = palette;\n   }\n   png_ptr->num_palette = (png_uint_16)num_palette;\n\n   if (full_quantize != 0)\n   {\n      int i;\n      png_bytep distance;\n      int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +\n          PNG_QUANTIZE_BLUE_BITS;\n      int num_red = (1 << PNG_QUANTIZE_RED_BITS);\n      int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);\n      int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);\n      png_size_t num_entries = ((png_size_t)1 << total_bits);\n\n      png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,\n          (png_uint_32)(num_entries * (sizeof (png_byte))));\n\n      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *\n          (sizeof (png_byte))));\n\n      memset(distance, 0xff, num_entries * (sizeof (png_byte)));\n\n      for (i = 0; i < num_palette; i++)\n      {\n         int ir, ig, ib;\n         int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));\n         int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));\n         int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));\n\n         for (ir = 0; ir < num_red; ir++)\n         {\n            /* int dr = abs(ir - r); */\n            int dr = ((ir > r) ? ir - r : r - ir);\n            int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +\n                PNG_QUANTIZE_GREEN_BITS));\n\n            for (ig = 0; ig < num_green; ig++)\n            {\n               /* int dg = abs(ig - g); */\n               int dg = ((ig > g) ? ig - g : g - ig);\n               int dt = dr + dg;\n               int dm = ((dr > dg) ? dr : dg);\n               int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);\n\n               for (ib = 0; ib < num_blue; ib++)\n               {\n                  int d_index = index_g | ib;\n                  /* int db = abs(ib - b); */\n                  int db = ((ib > b) ? ib - b : b - ib);\n                  int dmax = ((dm > db) ? dm : db);\n                  int d = dmax + dt + db;\n\n                  if (d < (int)distance[d_index])\n                  {\n                     distance[d_index] = (png_byte)d;\n                     png_ptr->palette_lookup[d_index] = (png_byte)i;\n                  }\n               }\n            }\n         }\n      }\n\n      png_free(png_ptr, distance);\n   }\n}\n#endif /* READ_QUANTIZE */\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\nvoid PNGFAPI\npng_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,\n   png_fixed_point file_gamma)\n{\n   png_debug(1, \"in png_set_gamma_fixed\");\n\n   if (png_rtran_ok(png_ptr, 0) == 0)\n      return;\n\n   /* New in libpng-1.5.4 - reserve particular negative values as flags. */\n   scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);\n   file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);\n\n   /* Checking the gamma values for being >0 was added in 1.5.4 along with the\n    * premultiplied alpha support; this actually hides an undocumented feature\n    * of the previous implementation which allowed gamma processing to be\n    * disabled in background handling.  There is no evidence (so far) that this\n    * was being used; however, png_set_background itself accepted and must still\n    * accept '0' for the gamma value it takes, because it isn't always used.\n    *\n    * Since this is an API change (albeit a very minor one that removes an\n    * undocumented API feature) the following checks were only enabled in\n    * libpng-1.6.0.\n    */\n   if (file_gamma <= 0)\n      png_error(png_ptr, \"invalid file gamma in png_set_gamma\");\n\n   if (scrn_gamma <= 0)\n      png_error(png_ptr, \"invalid screen gamma in png_set_gamma\");\n\n   /* Set the gamma values unconditionally - this overrides the value in the PNG\n    * file if a gAMA chunk was present.  png_set_alpha_mode provides a\n    * different, easier, way to default the file gamma.\n    */\n   png_ptr->colorspace.gamma = file_gamma;\n   png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;\n   png_ptr->screen_gamma = scrn_gamma;\n}\n\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\nvoid PNGAPI\npng_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)\n{\n   png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),\n      convert_gamma_value(png_ptr, file_gamma));\n}\n#  endif /* FLOATING_POINT */\n#endif /* READ_GAMMA */\n\n#ifdef PNG_READ_EXPAND_SUPPORTED\n/* Expand paletted images to RGB, expand grayscale images of\n * less than 8-bit depth to 8-bit depth, and expand tRNS chunks\n * to alpha channels.\n */\nvoid PNGAPI\npng_set_expand(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_expand\");\n\n   if (png_rtran_ok(png_ptr, 0) == 0)\n      return;\n\n   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);\n}\n\n/* GRR 19990627:  the following three functions currently are identical\n *  to png_set_expand().  However, it is entirely reasonable that someone\n *  might wish to expand an indexed image to RGB but *not* expand a single,\n *  fully transparent palette entry to a full alpha channel--perhaps instead\n *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace\n *  the transparent color with a particular RGB value, or drop tRNS entirely.\n *  IOW, a future version of the library may make the transformations flag\n *  a bit more fine-grained, with separate bits for each of these three\n *  functions.\n *\n *  More to the point, these functions make it obvious what libpng will be\n *  doing, whereas \"expand\" can (and does) mean any number of things.\n *\n *  GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified\n *  to expand only the sample depth but not to expand the tRNS to alpha\n *  and its name was changed to png_set_expand_gray_1_2_4_to_8().\n */\n\n/* Expand paletted images to RGB. */\nvoid PNGAPI\npng_set_palette_to_rgb(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_palette_to_rgb\");\n\n   if (png_rtran_ok(png_ptr, 0) == 0)\n      return;\n\n   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);\n}\n\n/* Expand grayscale images of less than 8-bit depth to 8 bits. */\nvoid PNGAPI\npng_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_expand_gray_1_2_4_to_8\");\n\n   if (png_rtran_ok(png_ptr, 0) == 0)\n      return;\n\n   png_ptr->transformations |= PNG_EXPAND;\n}\n\n/* Expand tRNS chunks to alpha channels. */\nvoid PNGAPI\npng_set_tRNS_to_alpha(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_tRNS_to_alpha\");\n\n   if (png_rtran_ok(png_ptr, 0) == 0)\n      return;\n\n   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);\n}\n#endif /* READ_EXPAND */\n\n#ifdef PNG_READ_EXPAND_16_SUPPORTED\n/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise\n * it may not work correctly.)\n */\nvoid PNGAPI\npng_set_expand_16(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_expand_16\");\n\n   if (png_rtran_ok(png_ptr, 0) == 0)\n      return;\n\n   png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);\n}\n#endif\n\n#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\nvoid PNGAPI\npng_set_gray_to_rgb(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_gray_to_rgb\");\n\n   if (png_rtran_ok(png_ptr, 0) == 0)\n      return;\n\n   /* Because rgb must be 8 bits or more: */\n   png_set_expand_gray_1_2_4_to_8(png_ptr);\n   png_ptr->transformations |= PNG_GRAY_TO_RGB;\n}\n#endif\n\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\nvoid PNGFAPI\npng_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,\n    png_fixed_point red, png_fixed_point green)\n{\n   png_debug(1, \"in png_set_rgb_to_gray\");\n\n   /* Need the IHDR here because of the check on color_type below. */\n   /* TODO: fix this */\n   if (png_rtran_ok(png_ptr, 1) == 0)\n      return;\n\n   switch (error_action)\n   {\n      case PNG_ERROR_ACTION_NONE:\n         png_ptr->transformations |= PNG_RGB_TO_GRAY;\n         break;\n\n      case PNG_ERROR_ACTION_WARN:\n         png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;\n         break;\n\n      case PNG_ERROR_ACTION_ERROR:\n         png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;\n         break;\n\n      default:\n         png_error(png_ptr, \"invalid error action to rgb_to_gray\");\n   }\n\n   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n#ifdef PNG_READ_EXPAND_SUPPORTED\n      png_ptr->transformations |= PNG_EXPAND;\n#else\n   {\n      /* Make this an error in 1.6 because otherwise the application may assume\n       * that it just worked and get a memory overwrite.\n       */\n      png_error(png_ptr,\n        \"Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED\");\n\n      /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */\n   }\n#endif\n   {\n      if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)\n      {\n         png_uint_16 red_int, green_int;\n\n         /* NOTE: this calculation does not round, but this behavior is retained\n          * for consistency; the inaccuracy is very small.  The code here always\n          * overwrites the coefficients, regardless of whether they have been\n          * defaulted or set already.\n          */\n         red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);\n         green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);\n\n         png_ptr->rgb_to_gray_red_coeff   = red_int;\n         png_ptr->rgb_to_gray_green_coeff = green_int;\n         png_ptr->rgb_to_gray_coefficients_set = 1;\n      }\n\n      else\n      {\n         if (red >= 0 && green >= 0)\n            png_app_warning(png_ptr,\n               \"ignoring out of range rgb_to_gray coefficients\");\n\n         /* Use the defaults, from the cHRM chunk if set, else the historical\n          * values which are close to the sRGB/HDTV/ITU-Rec 709 values.  See\n          * png_do_rgb_to_gray for more discussion of the values.  In this case\n          * the coefficients are not marked as 'set' and are not overwritten if\n          * something has already provided a default.\n          */\n         if (png_ptr->rgb_to_gray_red_coeff == 0 &&\n            png_ptr->rgb_to_gray_green_coeff == 0)\n         {\n            png_ptr->rgb_to_gray_red_coeff   = 6968;\n            png_ptr->rgb_to_gray_green_coeff = 23434;\n            /* png_ptr->rgb_to_gray_blue_coeff  = 2366; */\n         }\n      }\n   }\n}\n\n#ifdef PNG_FLOATING_POINT_SUPPORTED\n/* Convert a RGB image to a grayscale of the same width.  This allows us,\n * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.\n */\n\nvoid PNGAPI\npng_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,\n   double green)\n{\n   png_set_rgb_to_gray_fixed(png_ptr, error_action,\n      png_fixed(png_ptr, red, \"rgb to gray red coefficient\"),\n      png_fixed(png_ptr, green, \"rgb to gray green coefficient\"));\n}\n#endif /* FLOATING POINT */\n\n#endif /* RGB_TO_GRAY */\n\n#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \\\n    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)\nvoid PNGAPI\npng_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr\n    read_user_transform_fn)\n{\n   png_debug(1, \"in png_set_read_user_transform_fn\");\n\n#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED\n   png_ptr->transformations |= PNG_USER_TRANSFORM;\n   png_ptr->read_user_transform_fn = read_user_transform_fn;\n#endif\n}\n#endif\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\n#ifdef PNG_READ_GAMMA_SUPPORTED\n/* In the case of gamma transformations only do transformations on images where\n * the [file] gamma and screen_gamma are not close reciprocals, otherwise it\n * slows things down slightly, and also needlessly introduces small errors.\n */\nstatic int /* PRIVATE */\npng_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)\n{\n   /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma\n    * correction as a difference of the overall transform from 1.0\n    *\n    * We want to compare the threshold with s*f - 1, if we get\n    * overflow here it is because of wacky gamma values so we\n    * turn on processing anyway.\n    */\n   png_fixed_point gtest;\n   return !png_muldiv(&gtest, screen_gamma, file_gamma, PNG_FP_1) ||\n       png_gamma_significant(gtest);\n}\n#endif\n\n/* Initialize everything needed for the read.  This includes modifying\n * the palette.\n */\n\n/* For the moment 'png_init_palette_transformations' and\n * 'png_init_rgb_transformations' only do some flag canceling optimizations.\n * The intent is that these two routines should have palette or rgb operations\n * extracted from 'png_init_read_transformations'.\n */\nstatic void /* PRIVATE */\npng_init_palette_transformations(png_structrp png_ptr)\n{\n   /* Called to handle the (input) palette case.  In png_do_read_transformations\n    * the first step is to expand the palette if requested, so this code must\n    * take care to only make changes that are invariant with respect to the\n    * palette expansion, or only do them if there is no expansion.\n    *\n    * STRIP_ALPHA has already been handled in the caller (by setting num_trans\n    * to 0.)\n    */\n   int input_has_alpha = 0;\n   int input_has_transparency = 0;\n\n   if (png_ptr->num_trans > 0)\n   {\n      int i;\n\n      /* Ignore if all the entries are opaque (unlikely!) */\n      for (i=0; i<png_ptr->num_trans; ++i)\n      {\n         if (png_ptr->trans_alpha[i] == 255)\n            continue;\n         else if (png_ptr->trans_alpha[i] == 0)\n            input_has_transparency = 1;\n         else\n         {\n            input_has_transparency = 1;\n            input_has_alpha = 1;\n            break;\n         }\n      }\n   }\n\n   /* If no alpha we can optimize. */\n   if (input_has_alpha == 0)\n   {\n      /* Any alpha means background and associative alpha processing is\n       * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA\n       * and ENCODE_ALPHA are irrelevant.\n       */\n      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;\n      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\n\n      if (input_has_transparency == 0)\n         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);\n   }\n\n#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)\n   /* png_set_background handling - deals with the complexity of whether the\n    * background color is in the file format or the screen format in the case\n    * where an 'expand' will happen.\n    */\n\n   /* The following code cannot be entered in the alpha pre-multiplication case\n    * because PNG_BACKGROUND_EXPAND is cancelled below.\n    */\n   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&\n       (png_ptr->transformations & PNG_EXPAND) != 0)\n   {\n      {\n         png_ptr->background.red   =\n             png_ptr->palette[png_ptr->background.index].red;\n         png_ptr->background.green =\n             png_ptr->palette[png_ptr->background.index].green;\n         png_ptr->background.blue  =\n             png_ptr->palette[png_ptr->background.index].blue;\n\n#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED\n        if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)\n        {\n           if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)\n           {\n              /* Invert the alpha channel (in tRNS) unless the pixels are\n               * going to be expanded, in which case leave it for later\n               */\n              int i, istop = png_ptr->num_trans;\n\n              for (i=0; i<istop; i++)\n                 png_ptr->trans_alpha[i] = (png_byte)(255 -\n                    png_ptr->trans_alpha[i]);\n           }\n        }\n#endif /* READ_INVERT_ALPHA */\n      }\n   } /* background expand and (therefore) no alpha association. */\n#endif /* READ_EXPAND && READ_BACKGROUND */\n}\n\nstatic void /* PRIVATE */\npng_init_rgb_transformations(png_structrp png_ptr)\n{\n   /* Added to libpng-1.5.4: check the color type to determine whether there\n    * is any alpha or transparency in the image and simply cancel the\n    * background and alpha mode stuff if there isn't.\n    */\n   int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;\n   int input_has_transparency = png_ptr->num_trans > 0;\n\n   /* If no alpha we can optimize. */\n   if (input_has_alpha == 0)\n   {\n      /* Any alpha means background and associative alpha processing is\n       * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA\n       * and ENCODE_ALPHA are irrelevant.\n       */\n#     ifdef PNG_READ_ALPHA_MODE_SUPPORTED\n         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;\n         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\n#     endif\n\n      if (input_has_transparency == 0)\n         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);\n   }\n\n#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)\n   /* png_set_background handling - deals with the complexity of whether the\n    * background color is in the file format or the screen format in the case\n    * where an 'expand' will happen.\n    */\n\n   /* The following code cannot be entered in the alpha pre-multiplication case\n    * because PNG_BACKGROUND_EXPAND is cancelled below.\n    */\n   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&\n       (png_ptr->transformations & PNG_EXPAND) != 0 &&\n       (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)\n       /* i.e., GRAY or GRAY_ALPHA */\n   {\n      {\n         /* Expand background and tRNS chunks */\n         int gray = png_ptr->background.gray;\n         int trans_gray = png_ptr->trans_color.gray;\n\n         switch (png_ptr->bit_depth)\n         {\n            case 1:\n               gray *= 0xff;\n               trans_gray *= 0xff;\n               break;\n\n            case 2:\n               gray *= 0x55;\n               trans_gray *= 0x55;\n               break;\n\n            case 4:\n               gray *= 0x11;\n               trans_gray *= 0x11;\n               break;\n\n            default:\n\n            case 8:\n               /* FALL THROUGH (Already 8 bits) */\n\n            case 16:\n               /* Already a full 16 bits */\n               break;\n         }\n\n         png_ptr->background.red = png_ptr->background.green =\n            png_ptr->background.blue = (png_uint_16)gray;\n\n         if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)\n         {\n            png_ptr->trans_color.red = png_ptr->trans_color.green =\n               png_ptr->trans_color.blue = (png_uint_16)trans_gray;\n         }\n      }\n   } /* background expand and (therefore) no alpha association. */\n#endif /* READ_EXPAND && READ_BACKGROUND */\n}\n\nvoid /* PRIVATE */\npng_init_read_transformations(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_init_read_transformations\");\n\n   /* This internal function is called from png_read_start_row in pngrutil.c\n    * and it is called before the 'rowbytes' calculation is done, so the code\n    * in here can change or update the transformations flags.\n    *\n    * First do updates that do not depend on the details of the PNG image data\n    * being processed.\n    */\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\n   /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds\n    * png_set_alpha_mode and this is another source for a default file gamma so\n    * the test needs to be performed later - here.  In addition prior to 1.5.4\n    * the tests were repeated for the PALETTE color type here - this is no\n    * longer necessary (and doesn't seem to have been necessary before.)\n    */\n   {\n      /* The following temporary indicates if overall gamma correction is\n       * required.\n       */\n      int gamma_correction = 0;\n\n      if (png_ptr->colorspace.gamma != 0) /* has been set */\n      {\n         if (png_ptr->screen_gamma != 0) /* screen set too */\n            gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,\n               png_ptr->screen_gamma);\n\n         else\n            /* Assume the output matches the input; a long time default behavior\n             * of libpng, although the standard has nothing to say about this.\n             */\n            png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma);\n      }\n\n      else if (png_ptr->screen_gamma != 0)\n         /* The converse - assume the file matches the screen, note that this\n          * perhaps undesireable default can (from 1.5.4) be changed by calling\n          * png_set_alpha_mode (even if the alpha handling mode isn't required\n          * or isn't changed from the default.)\n          */\n         png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma);\n\n      else /* neither are set */\n         /* Just in case the following prevents any processing - file and screen\n          * are both assumed to be linear and there is no way to introduce a\n          * third gamma value other than png_set_background with 'UNIQUE', and,\n          * prior to 1.5.4\n          */\n         png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1;\n\n      /* We have a gamma value now. */\n      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;\n\n      /* Now turn the gamma transformation on or off as appropriate.  Notice\n       * that PNG_GAMMA just refers to the file->screen correction.  Alpha\n       * composition may independently cause gamma correction because it needs\n       * linear data (e.g. if the file has a gAMA chunk but the screen gamma\n       * hasn't been specified.)  In any case this flag may get turned off in\n       * the code immediately below if the transform can be handled outside the\n       * row loop.\n       */\n      if (gamma_correction != 0)\n         png_ptr->transformations |= PNG_GAMMA;\n\n      else\n         png_ptr->transformations &= ~PNG_GAMMA;\n   }\n#endif\n\n   /* Certain transformations have the effect of preventing other\n    * transformations that happen afterward in png_do_read_transformations;\n    * resolve the interdependencies here.  From the code of\n    * png_do_read_transformations the order is:\n    *\n    *  1) PNG_EXPAND (including PNG_EXPAND_tRNS)\n    *  2) PNG_STRIP_ALPHA (if no compose)\n    *  3) PNG_RGB_TO_GRAY\n    *  4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY\n    *  5) PNG_COMPOSE\n    *  6) PNG_GAMMA\n    *  7) PNG_STRIP_ALPHA (if compose)\n    *  8) PNG_ENCODE_ALPHA\n    *  9) PNG_SCALE_16_TO_8\n    * 10) PNG_16_TO_8\n    * 11) PNG_QUANTIZE (converts to palette)\n    * 12) PNG_EXPAND_16\n    * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY\n    * 14) PNG_INVERT_MONO\n    * 15) PNG_INVERT_ALPHA\n    * 16) PNG_SHIFT\n    * 17) PNG_PACK\n    * 18) PNG_BGR\n    * 19) PNG_PACKSWAP\n    * 20) PNG_FILLER (includes PNG_ADD_ALPHA)\n    * 21) PNG_SWAP_ALPHA\n    * 22) PNG_SWAP_BYTES\n    * 23) PNG_USER_TRANSFORM [must be last]\n    */\n#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED\n   if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&\n       (png_ptr->transformations & PNG_COMPOSE) == 0)\n   {\n      /* Stripping the alpha channel happens immediately after the 'expand'\n       * transformations, before all other transformation, so it cancels out\n       * the alpha handling.  It has the side effect negating the effect of\n       * PNG_EXPAND_tRNS too:\n       */\n      png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |\n         PNG_EXPAND_tRNS);\n      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\n\n      /* Kill the tRNS chunk itself too.  Prior to 1.5.4 this did not happen\n       * so transparency information would remain just so long as it wasn't\n       * expanded.  This produces unexpected API changes if the set of things\n       * that do PNG_EXPAND_tRNS changes (perfectly possible given the\n       * documentation - which says ask for what you want, accept what you\n       * get.)  This makes the behavior consistent from 1.5.4:\n       */\n      png_ptr->num_trans = 0;\n   }\n#endif /* STRIP_ALPHA supported, no COMPOSE */\n\n#ifdef PNG_READ_ALPHA_MODE_SUPPORTED\n   /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA\n    * settings will have no effect.\n    */\n   if (png_gamma_significant(png_ptr->screen_gamma) == 0)\n   {\n      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;\n      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\n   }\n#endif\n\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\n   /* Make sure the coefficients for the rgb to gray conversion are set\n    * appropriately.\n    */\n   if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)\n      png_colorspace_set_rgb_coefficients(png_ptr);\n#endif\n\n#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\n#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)\n   /* Detect gray background and attempt to enable optimization for\n    * gray --> RGB case.\n    *\n    * Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or\n    * RGB_ALPHA (in which case need_expand is superfluous anyway), the\n    * background color might actually be gray yet not be flagged as such.\n    * This is not a problem for the current code, which uses\n    * PNG_BACKGROUND_IS_GRAY only to decide when to do the\n    * png_do_gray_to_rgb() transformation.\n    *\n    * TODO: this code needs to be revised to avoid the complexity and\n    * interdependencies.  The color type of the background should be recorded in\n    * png_set_background, along with the bit depth, then the code has a record\n    * of exactly what color space the background is currently in.\n    */\n   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0)\n   {\n      /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if\n       * the file was grayscale the background value is gray.\n       */\n      if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)\n         png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;\n   }\n\n   else if ((png_ptr->transformations & PNG_COMPOSE) != 0)\n   {\n      /* PNG_COMPOSE: png_set_background was called with need_expand false,\n       * so the color is in the color space of the output or png_set_alpha_mode\n       * was called and the color is black.  Ignore RGB_TO_GRAY because that\n       * happens before GRAY_TO_RGB.\n       */\n      if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)\n      {\n         if (png_ptr->background.red == png_ptr->background.green &&\n             png_ptr->background.red == png_ptr->background.blue)\n         {\n            png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;\n            png_ptr->background.gray = png_ptr->background.red;\n         }\n      }\n   }\n#endif /* READ_EXPAND && READ_BACKGROUND */\n#endif /* READ_GRAY_TO_RGB */\n\n   /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations\n    * can be performed directly on the palette, and some (such as rgb to gray)\n    * can be optimized inside the palette.  This is particularly true of the\n    * composite (background and alpha) stuff, which can be pretty much all done\n    * in the palette even if the result is expanded to RGB or gray afterward.\n    *\n    * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and\n    * earlier and the palette stuff is actually handled on the first row.  This\n    * leads to the reported bug that the palette returned by png_get_PLTE is not\n    * updated.\n    */\n   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n      png_init_palette_transformations(png_ptr);\n\n   else\n      png_init_rgb_transformations(png_ptr);\n\n#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \\\n   defined(PNG_READ_EXPAND_16_SUPPORTED)\n   if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&\n       (png_ptr->transformations & PNG_COMPOSE) != 0 &&\n       (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&\n       png_ptr->bit_depth != 16)\n   {\n      /* TODO: fix this.  Because the expand_16 operation is after the compose\n       * handling the background color must be 8, not 16, bits deep, but the\n       * application will supply a 16-bit value so reduce it here.\n       *\n       * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at\n       * present, so that case is ok (until do_expand_16 is moved.)\n       *\n       * NOTE: this discards the low 16 bits of the user supplied background\n       * color, but until expand_16 works properly there is no choice!\n       */\n#     define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x))\n      CHOP(png_ptr->background.red);\n      CHOP(png_ptr->background.green);\n      CHOP(png_ptr->background.blue);\n      CHOP(png_ptr->background.gray);\n#     undef CHOP\n   }\n#endif /* READ_BACKGROUND && READ_EXPAND_16 */\n\n#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \\\n   (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \\\n   defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))\n   if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 &&\n       (png_ptr->transformations & PNG_COMPOSE) != 0 &&\n       (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&\n       png_ptr->bit_depth == 16)\n   {\n      /* On the other hand, if a 16-bit file is to be reduced to 8-bits per\n       * component this will also happen after PNG_COMPOSE and so the background\n       * color must be pre-expanded here.\n       *\n       * TODO: fix this too.\n       */\n      png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257);\n      png_ptr->background.green =\n         (png_uint_16)(png_ptr->background.green * 257);\n      png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257);\n      png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257);\n   }\n#endif\n\n   /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the\n    * background support (see the comments in scripts/pnglibconf.dfa), this\n    * allows pre-multiplication of the alpha channel to be implemented as\n    * compositing on black.  This is probably sub-optimal and has been done in\n    * 1.5.4 betas simply to enable external critique and testing (i.e. to\n    * implement the new API quickly, without lots of internal changes.)\n    */\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\n#  ifdef PNG_READ_BACKGROUND_SUPPORTED\n      /* Includes ALPHA_MODE */\n      png_ptr->background_1 = png_ptr->background;\n#  endif\n\n   /* This needs to change - in the palette image case a whole set of tables are\n    * built when it would be quicker to just calculate the correct value for\n    * each palette entry directly.  Also, the test is too tricky - why check\n    * PNG_RGB_TO_GRAY if PNG_GAMMA is not set?  The answer seems to be that\n    * PNG_GAMMA is cancelled even if the gamma is known?  The test excludes the\n    * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction\n    * the gamma tables will not be built even if composition is required on a\n    * gamma encoded value.\n    *\n    * In 1.5.4 this is addressed below by an additional check on the individual\n    * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the\n    * tables.\n    */\n   if ((png_ptr->transformations & PNG_GAMMA) != 0 ||\n       ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 &&\n        (png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||\n         png_gamma_significant(png_ptr->screen_gamma) != 0)) ||\n        ((png_ptr->transformations & PNG_COMPOSE) != 0 &&\n         (png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||\n          png_gamma_significant(png_ptr->screen_gamma) != 0\n#  ifdef PNG_READ_BACKGROUND_SUPPORTED\n         || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE &&\n           png_gamma_significant(png_ptr->background_gamma) != 0)\n#  endif\n        )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&\n       png_gamma_significant(png_ptr->screen_gamma) != 0))\n   {\n      png_build_gamma_table(png_ptr, png_ptr->bit_depth);\n\n#ifdef PNG_READ_BACKGROUND_SUPPORTED\n      if ((png_ptr->transformations & PNG_COMPOSE) != 0)\n      {\n         /* Issue a warning about this combination: because RGB_TO_GRAY is\n          * optimized to do the gamma transform if present yet do_background has\n          * to do the same thing if both options are set a\n          * double-gamma-correction happens.  This is true in all versions of\n          * libpng to date.\n          */\n         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)\n            png_warning(png_ptr,\n               \"libpng does not support gamma+background+rgb_to_gray\");\n\n         if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0)\n         {\n            /* We don't get to here unless there is a tRNS chunk with non-opaque\n             * entries - see the checking code at the start of this function.\n             */\n            png_color back, back_1;\n            png_colorp palette = png_ptr->palette;\n            int num_palette = png_ptr->num_palette;\n            int i;\n            if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)\n            {\n\n               back.red = png_ptr->gamma_table[png_ptr->background.red];\n               back.green = png_ptr->gamma_table[png_ptr->background.green];\n               back.blue = png_ptr->gamma_table[png_ptr->background.blue];\n\n               back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];\n               back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];\n               back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];\n            }\n            else\n            {\n               png_fixed_point g, gs;\n\n               switch (png_ptr->background_gamma_type)\n               {\n                  case PNG_BACKGROUND_GAMMA_SCREEN:\n                     g = (png_ptr->screen_gamma);\n                     gs = PNG_FP_1;\n                     break;\n\n                  case PNG_BACKGROUND_GAMMA_FILE:\n                     g = png_reciprocal(png_ptr->colorspace.gamma);\n                     gs = png_reciprocal2(png_ptr->colorspace.gamma,\n                        png_ptr->screen_gamma);\n                     break;\n\n                  case PNG_BACKGROUND_GAMMA_UNIQUE:\n                     g = png_reciprocal(png_ptr->background_gamma);\n                     gs = png_reciprocal2(png_ptr->background_gamma,\n                        png_ptr->screen_gamma);\n                     break;\n                  default:\n                     g = PNG_FP_1;    /* back_1 */\n                     gs = PNG_FP_1;   /* back */\n                     break;\n               }\n\n               if (png_gamma_significant(gs) != 0)\n               {\n                  back.red = png_gamma_8bit_correct(png_ptr->background.red,\n                      gs);\n                  back.green = png_gamma_8bit_correct(png_ptr->background.green,\n                      gs);\n                  back.blue = png_gamma_8bit_correct(png_ptr->background.blue,\n                      gs);\n               }\n\n               else\n               {\n                  back.red   = (png_byte)png_ptr->background.red;\n                  back.green = (png_byte)png_ptr->background.green;\n                  back.blue  = (png_byte)png_ptr->background.blue;\n               }\n\n               if (png_gamma_significant(g) != 0)\n               {\n                  back_1.red = png_gamma_8bit_correct(png_ptr->background.red,\n                     g);\n                  back_1.green = png_gamma_8bit_correct(\n                     png_ptr->background.green, g);\n                  back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,\n                     g);\n               }\n\n               else\n               {\n                  back_1.red   = (png_byte)png_ptr->background.red;\n                  back_1.green = (png_byte)png_ptr->background.green;\n                  back_1.blue  = (png_byte)png_ptr->background.blue;\n               }\n            }\n\n            for (i = 0; i < num_palette; i++)\n            {\n               if (i < (int)png_ptr->num_trans &&\n                   png_ptr->trans_alpha[i] != 0xff)\n               {\n                  if (png_ptr->trans_alpha[i] == 0)\n                  {\n                     palette[i] = back;\n                  }\n                  else /* if (png_ptr->trans_alpha[i] != 0xff) */\n                  {\n                     png_byte v, w;\n\n                     v = png_ptr->gamma_to_1[palette[i].red];\n                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);\n                     palette[i].red = png_ptr->gamma_from_1[w];\n\n                     v = png_ptr->gamma_to_1[palette[i].green];\n                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);\n                     palette[i].green = png_ptr->gamma_from_1[w];\n\n                     v = png_ptr->gamma_to_1[palette[i].blue];\n                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);\n                     palette[i].blue = png_ptr->gamma_from_1[w];\n                  }\n               }\n               else\n               {\n                  palette[i].red = png_ptr->gamma_table[palette[i].red];\n                  palette[i].green = png_ptr->gamma_table[palette[i].green];\n                  palette[i].blue = png_ptr->gamma_table[palette[i].blue];\n               }\n            }\n\n            /* Prevent the transformations being done again.\n             *\n             * NOTE: this is highly dubious; it removes the transformations in\n             * place.  This seems inconsistent with the general treatment of the\n             * transformations elsewhere.\n             */\n            png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);\n         } /* color_type == PNG_COLOR_TYPE_PALETTE */\n\n         /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */\n         else /* color_type != PNG_COLOR_TYPE_PALETTE */\n         {\n            int gs_sig, g_sig;\n            png_fixed_point g = PNG_FP_1;  /* Correction to linear */\n            png_fixed_point gs = PNG_FP_1; /* Correction to screen */\n\n            switch (png_ptr->background_gamma_type)\n            {\n               case PNG_BACKGROUND_GAMMA_SCREEN:\n                  g = png_ptr->screen_gamma;\n                  /* gs = PNG_FP_1; */\n                  break;\n\n               case PNG_BACKGROUND_GAMMA_FILE:\n                  g = png_reciprocal(png_ptr->colorspace.gamma);\n                  gs = png_reciprocal2(png_ptr->colorspace.gamma,\n                     png_ptr->screen_gamma);\n                  break;\n\n               case PNG_BACKGROUND_GAMMA_UNIQUE:\n                  g = png_reciprocal(png_ptr->background_gamma);\n                  gs = png_reciprocal2(png_ptr->background_gamma,\n                      png_ptr->screen_gamma);\n                  break;\n\n               default:\n                  png_error(png_ptr, \"invalid background gamma type\");\n            }\n\n            g_sig = png_gamma_significant(g);\n            gs_sig = png_gamma_significant(gs);\n\n            if (g_sig != 0)\n               png_ptr->background_1.gray = png_gamma_correct(png_ptr,\n                   png_ptr->background.gray, g);\n\n            if (gs_sig != 0)\n               png_ptr->background.gray = png_gamma_correct(png_ptr,\n                   png_ptr->background.gray, gs);\n\n            if ((png_ptr->background.red != png_ptr->background.green) ||\n                (png_ptr->background.red != png_ptr->background.blue) ||\n                (png_ptr->background.red != png_ptr->background.gray))\n            {\n               /* RGB or RGBA with color background */\n               if (g_sig != 0)\n               {\n                  png_ptr->background_1.red = png_gamma_correct(png_ptr,\n                      png_ptr->background.red, g);\n\n                  png_ptr->background_1.green = png_gamma_correct(png_ptr,\n                      png_ptr->background.green, g);\n\n                  png_ptr->background_1.blue = png_gamma_correct(png_ptr,\n                      png_ptr->background.blue, g);\n               }\n\n               if (gs_sig != 0)\n               {\n                  png_ptr->background.red = png_gamma_correct(png_ptr,\n                      png_ptr->background.red, gs);\n\n                  png_ptr->background.green = png_gamma_correct(png_ptr,\n                      png_ptr->background.green, gs);\n\n                  png_ptr->background.blue = png_gamma_correct(png_ptr,\n                      png_ptr->background.blue, gs);\n               }\n            }\n\n            else\n            {\n               /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */\n               png_ptr->background_1.red = png_ptr->background_1.green\n                   = png_ptr->background_1.blue = png_ptr->background_1.gray;\n\n               png_ptr->background.red = png_ptr->background.green\n                   = png_ptr->background.blue = png_ptr->background.gray;\n            }\n\n            /* The background is now in screen gamma: */\n            png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;\n         } /* color_type != PNG_COLOR_TYPE_PALETTE */\n      }/* png_ptr->transformations & PNG_BACKGROUND */\n\n      else\n      /* Transformation does not include PNG_BACKGROUND */\n#endif /* READ_BACKGROUND */\n      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\n         /* RGB_TO_GRAY needs to have non-gamma-corrected values! */\n         && ((png_ptr->transformations & PNG_EXPAND) == 0 ||\n         (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)\n#endif\n         )\n      {\n         png_colorp palette = png_ptr->palette;\n         int num_palette = png_ptr->num_palette;\n         int i;\n\n         /* NOTE: there are other transformations that should probably be in\n          * here too.\n          */\n         for (i = 0; i < num_palette; i++)\n         {\n            palette[i].red = png_ptr->gamma_table[palette[i].red];\n            palette[i].green = png_ptr->gamma_table[palette[i].green];\n            palette[i].blue = png_ptr->gamma_table[palette[i].blue];\n         }\n\n         /* Done the gamma correction. */\n         png_ptr->transformations &= ~PNG_GAMMA;\n      } /* color_type == PALETTE && !PNG_BACKGROUND transformation */\n   }\n#ifdef PNG_READ_BACKGROUND_SUPPORTED\n   else\n#endif\n#endif /* READ_GAMMA */\n\n#ifdef PNG_READ_BACKGROUND_SUPPORTED\n   /* No GAMMA transformation (see the hanging else 4 lines above) */\n   if ((png_ptr->transformations & PNG_COMPOSE) != 0 &&\n       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))\n   {\n      int i;\n      int istop = (int)png_ptr->num_trans;\n      png_color back;\n      png_colorp palette = png_ptr->palette;\n\n      back.red   = (png_byte)png_ptr->background.red;\n      back.green = (png_byte)png_ptr->background.green;\n      back.blue  = (png_byte)png_ptr->background.blue;\n\n      for (i = 0; i < istop; i++)\n      {\n         if (png_ptr->trans_alpha[i] == 0)\n         {\n            palette[i] = back;\n         }\n\n         else if (png_ptr->trans_alpha[i] != 0xff)\n         {\n            /* The png_composite() macro is defined in png.h */\n            png_composite(palette[i].red, palette[i].red,\n                png_ptr->trans_alpha[i], back.red);\n\n            png_composite(palette[i].green, palette[i].green,\n                png_ptr->trans_alpha[i], back.green);\n\n            png_composite(palette[i].blue, palette[i].blue,\n                png_ptr->trans_alpha[i], back.blue);\n         }\n      }\n\n      png_ptr->transformations &= ~PNG_COMPOSE;\n   }\n#endif /* READ_BACKGROUND */\n\n#ifdef PNG_READ_SHIFT_SUPPORTED\n   if ((png_ptr->transformations & PNG_SHIFT) != 0 &&\n       (png_ptr->transformations & PNG_EXPAND) == 0 &&\n       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))\n   {\n      int i;\n      int istop = png_ptr->num_palette;\n      int shift = 8 - png_ptr->sig_bit.red;\n\n      png_ptr->transformations &= ~PNG_SHIFT;\n\n      /* significant bits can be in the range 1 to 7 for a meaninful result, if\n       * the number of significant bits is 0 then no shift is done (this is an\n       * error condition which is silently ignored.)\n       */\n      if (shift > 0 && shift < 8)\n         for (i=0; i<istop; ++i)\n         {\n            int component = png_ptr->palette[i].red;\n\n            component >>= shift;\n            png_ptr->palette[i].red = (png_byte)component;\n         }\n\n      shift = 8 - png_ptr->sig_bit.green;\n      if (shift > 0 && shift < 8)\n         for (i=0; i<istop; ++i)\n         {\n            int component = png_ptr->palette[i].green;\n\n            component >>= shift;\n            png_ptr->palette[i].green = (png_byte)component;\n         }\n\n      shift = 8 - png_ptr->sig_bit.blue;\n      if (shift > 0 && shift < 8)\n         for (i=0; i<istop; ++i)\n         {\n            int component = png_ptr->palette[i].blue;\n\n            component >>= shift;\n            png_ptr->palette[i].blue = (png_byte)component;\n         }\n   }\n#endif  /* READ_SHIFT */\n}\n\n/* Modify the info structure to reflect the transformations.  The\n * info should be updated so a PNG file could be written with it,\n * assuming the transformations result in valid PNG data.\n */\nvoid /* PRIVATE */\npng_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)\n{\n   png_debug(1, \"in png_read_transform_info\");\n\n#ifdef PNG_READ_EXPAND_SUPPORTED\n   if ((png_ptr->transformations & PNG_EXPAND) != 0)\n   {\n      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n      {\n         /* This check must match what actually happens in\n          * png_do_expand_palette; if it ever checks the tRNS chunk to see if\n          * it is all opaque we must do the same (at present it does not.)\n          */\n         if (png_ptr->num_trans > 0)\n            info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;\n\n         else\n            info_ptr->color_type = PNG_COLOR_TYPE_RGB;\n\n         info_ptr->bit_depth = 8;\n         info_ptr->num_trans = 0;\n\n         if (png_ptr->palette == NULL)\n            png_error (png_ptr, \"Palette is NULL in indexed image\");\n      }\n      else\n      {\n         if (png_ptr->num_trans != 0)\n         {\n            if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0)\n               info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;\n         }\n         if (info_ptr->bit_depth < 8)\n            info_ptr->bit_depth = 8;\n\n         info_ptr->num_trans = 0;\n      }\n   }\n#endif\n\n#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\\\n   defined(PNG_READ_ALPHA_MODE_SUPPORTED)\n   /* The following is almost certainly wrong unless the background value is in\n    * the screen space!\n    */\n   if ((png_ptr->transformations & PNG_COMPOSE) != 0)\n      info_ptr->background = png_ptr->background;\n#endif\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\n   /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4),\n    * however it seems that the code in png_init_read_transformations, which has\n    * been called before this from png_read_update_info->png_read_start_row\n    * sometimes does the gamma transform and cancels the flag.\n    *\n    * TODO: this looks wrong; the info_ptr should end up with a gamma equal to\n    * the screen_gamma value.  The following probably results in weirdness if\n    * the info_ptr is used by the app after the rows have been read.\n    */\n   info_ptr->colorspace.gamma = png_ptr->colorspace.gamma;\n#endif\n\n   if (info_ptr->bit_depth == 16)\n   {\n#  ifdef PNG_READ_16BIT_SUPPORTED\n#     ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\n         if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)\n            info_ptr->bit_depth = 8;\n#     endif\n\n#     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED\n         if ((png_ptr->transformations & PNG_16_TO_8) != 0)\n            info_ptr->bit_depth = 8;\n#     endif\n\n#  else\n      /* No 16-bit support: force chopping 16-bit input down to 8, in this case\n       * the app program can chose if both APIs are available by setting the\n       * correct scaling to use.\n       */\n#     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED\n         /* For compatibility with previous versions use the strip method by\n          * default.  This code works because if PNG_SCALE_16_TO_8 is already\n          * set the code below will do that in preference to the chop.\n          */\n         png_ptr->transformations |= PNG_16_TO_8;\n         info_ptr->bit_depth = 8;\n#     else\n\n#        ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\n            png_ptr->transformations |= PNG_SCALE_16_TO_8;\n            info_ptr->bit_depth = 8;\n#        else\n\n            CONFIGURATION ERROR: you must enable at least one 16 to 8 method\n#        endif\n#    endif\n#endif /* !READ_16BIT */\n   }\n\n#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\n   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)\n      info_ptr->color_type = (png_byte)(info_ptr->color_type |\n         PNG_COLOR_MASK_COLOR);\n#endif\n\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\n   if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)\n      info_ptr->color_type = (png_byte)(info_ptr->color_type &\n         ~PNG_COLOR_MASK_COLOR);\n#endif\n\n#ifdef PNG_READ_QUANTIZE_SUPPORTED\n   if ((png_ptr->transformations & PNG_QUANTIZE) != 0)\n   {\n      if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||\n          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&\n          png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8)\n      {\n         info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;\n      }\n   }\n#endif\n\n#ifdef PNG_READ_EXPAND_16_SUPPORTED\n   if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&\n       info_ptr->bit_depth == 8 &&\n       info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)\n   {\n      info_ptr->bit_depth = 16;\n   }\n#endif\n\n#ifdef PNG_READ_PACK_SUPPORTED\n   if ((png_ptr->transformations & PNG_PACK) != 0 &&\n       (info_ptr->bit_depth < 8))\n      info_ptr->bit_depth = 8;\n#endif\n\n   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n      info_ptr->channels = 1;\n\n   else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)\n      info_ptr->channels = 3;\n\n   else\n      info_ptr->channels = 1;\n\n#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED\n   if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0)\n   {\n      info_ptr->color_type = (png_byte)(info_ptr->color_type &\n         ~PNG_COLOR_MASK_ALPHA);\n      info_ptr->num_trans = 0;\n   }\n#endif\n\n   if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)\n      info_ptr->channels++;\n\n#ifdef PNG_READ_FILLER_SUPPORTED\n   /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */\n   if ((png_ptr->transformations & PNG_FILLER) != 0 &&\n       (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||\n       info_ptr->color_type == PNG_COLOR_TYPE_GRAY))\n   {\n      info_ptr->channels++;\n      /* If adding a true alpha channel not just filler */\n      if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0)\n         info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;\n   }\n#endif\n\n#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \\\ndefined(PNG_READ_USER_TRANSFORM_SUPPORTED)\n   if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)\n   {\n      if (png_ptr->user_transform_depth != 0)\n         info_ptr->bit_depth = png_ptr->user_transform_depth;\n\n      if (png_ptr->user_transform_channels != 0)\n         info_ptr->channels = png_ptr->user_transform_channels;\n   }\n#endif\n\n   info_ptr->pixel_depth = (png_byte)(info_ptr->channels *\n       info_ptr->bit_depth);\n\n   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);\n\n   /* Adding in 1.5.4: cache the above value in png_struct so that we can later\n    * check in png_rowbytes that the user buffer won't get overwritten.  Note\n    * that the field is not always set - if png_read_update_info isn't called\n    * the application has to either not do any transforms or get the calculation\n    * right itself.\n    */\n   png_ptr->info_rowbytes = info_ptr->rowbytes;\n\n#ifndef PNG_READ_EXPAND_SUPPORTED\n   if (png_ptr != NULL)\n      return;\n#endif\n}\n\n#ifdef PNG_READ_PACK_SUPPORTED\n/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,\n * without changing the actual values.  Thus, if you had a row with\n * a bit depth of 1, you would end up with bytes that only contained\n * the numbers 0 or 1.  If you would rather they contain 0 and 255, use\n * png_do_shift() after this.\n */\nstatic void\npng_do_unpack(png_row_infop row_info, png_bytep row)\n{\n   png_debug(1, \"in png_do_unpack\");\n\n   if (row_info->bit_depth < 8)\n   {\n      png_uint_32 i;\n      png_uint_32 row_width=row_info->width;\n\n      switch (row_info->bit_depth)\n      {\n         case 1:\n         {\n            png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);\n            png_bytep dp = row + (png_size_t)row_width - 1;\n            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);\n            for (i = 0; i < row_width; i++)\n            {\n               *dp = (png_byte)((*sp >> shift) & 0x01);\n\n               if (shift == 7)\n               {\n                  shift = 0;\n                  sp--;\n               }\n\n               else\n                  shift++;\n\n               dp--;\n            }\n            break;\n         }\n\n         case 2:\n         {\n\n            png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);\n            png_bytep dp = row + (png_size_t)row_width - 1;\n            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);\n            for (i = 0; i < row_width; i++)\n            {\n               *dp = (png_byte)((*sp >> shift) & 0x03);\n\n               if (shift == 6)\n               {\n                  shift = 0;\n                  sp--;\n               }\n\n               else\n                  shift += 2;\n\n               dp--;\n            }\n            break;\n         }\n\n         case 4:\n         {\n            png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);\n            png_bytep dp = row + (png_size_t)row_width - 1;\n            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);\n            for (i = 0; i < row_width; i++)\n            {\n               *dp = (png_byte)((*sp >> shift) & 0x0f);\n\n               if (shift == 4)\n               {\n                  shift = 0;\n                  sp--;\n               }\n\n               else\n                  shift = 4;\n\n               dp--;\n            }\n            break;\n         }\n\n         default:\n            break;\n      }\n      row_info->bit_depth = 8;\n      row_info->pixel_depth = (png_byte)(8 * row_info->channels);\n      row_info->rowbytes = row_width * row_info->channels;\n   }\n}\n#endif\n\n#ifdef PNG_READ_SHIFT_SUPPORTED\n/* Reverse the effects of png_do_shift.  This routine merely shifts the\n * pixels back to their significant bits values.  Thus, if you have\n * a row of bit depth 8, but only 5 are significant, this will shift\n * the values back to 0 through 31.\n */\nstatic void\npng_do_unshift(png_row_infop row_info, png_bytep row,\n    png_const_color_8p sig_bits)\n{\n   int color_type;\n\n   png_debug(1, \"in png_do_unshift\");\n\n   /* The palette case has already been handled in the _init routine. */\n   color_type = row_info->color_type;\n\n   if (color_type != PNG_COLOR_TYPE_PALETTE)\n   {\n      int shift[4];\n      int channels = 0;\n      int bit_depth = row_info->bit_depth;\n\n      if ((color_type & PNG_COLOR_MASK_COLOR) != 0)\n      {\n         shift[channels++] = bit_depth - sig_bits->red;\n         shift[channels++] = bit_depth - sig_bits->green;\n         shift[channels++] = bit_depth - sig_bits->blue;\n      }\n\n      else\n      {\n         shift[channels++] = bit_depth - sig_bits->gray;\n      }\n\n      if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)\n      {\n         shift[channels++] = bit_depth - sig_bits->alpha;\n      }\n\n      {\n         int c, have_shift;\n\n         for (c = have_shift = 0; c < channels; ++c)\n         {\n            /* A shift of more than the bit depth is an error condition but it\n             * gets ignored here.\n             */\n            if (shift[c] <= 0 || shift[c] >= bit_depth)\n               shift[c] = 0;\n\n            else\n               have_shift = 1;\n         }\n\n         if (have_shift == 0)\n            return;\n      }\n\n      switch (bit_depth)\n      {\n         default:\n         /* Must be 1bpp gray: should not be here! */\n            /* NOTREACHED */\n            break;\n\n         case 2:\n         /* Must be 2bpp gray */\n         /* assert(channels == 1 && shift[0] == 1) */\n         {\n            png_bytep bp = row;\n            png_bytep bp_end = bp + row_info->rowbytes;\n\n            while (bp < bp_end)\n            {\n               int b = (*bp >> 1) & 0x55;\n               *bp++ = (png_byte)b;\n            }\n            break;\n         }\n\n         case 4:\n         /* Must be 4bpp gray */\n         /* assert(channels == 1) */\n         {\n            png_bytep bp = row;\n            png_bytep bp_end = bp + row_info->rowbytes;\n            int gray_shift = shift[0];\n            int mask =  0xf >> gray_shift;\n\n            mask |= mask << 4;\n\n            while (bp < bp_end)\n            {\n               int b = (*bp >> gray_shift) & mask;\n               *bp++ = (png_byte)b;\n            }\n            break;\n         }\n\n         case 8:\n         /* Single byte components, G, GA, RGB, RGBA */\n         {\n            png_bytep bp = row;\n            png_bytep bp_end = bp + row_info->rowbytes;\n            int channel = 0;\n\n            while (bp < bp_end)\n            {\n               int b = *bp >> shift[channel];\n               if (++channel >= channels)\n                  channel = 0;\n               *bp++ = (png_byte)b;\n            }\n            break;\n         }\n\n#ifdef PNG_READ_16BIT_SUPPORTED\n         case 16:\n         /* Double byte components, G, GA, RGB, RGBA */\n         {\n            png_bytep bp = row;\n            png_bytep bp_end = bp + row_info->rowbytes;\n            int channel = 0;\n\n            while (bp < bp_end)\n            {\n               int value = (bp[0] << 8) + bp[1];\n\n               value >>= shift[channel];\n               if (++channel >= channels)\n                  channel = 0;\n               *bp++ = (png_byte)(value >> 8);\n               *bp++ = (png_byte)value;\n            }\n            break;\n         }\n#endif\n      }\n   }\n}\n#endif\n\n#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\n/* Scale rows of bit depth 16 down to 8 accurately */\nstatic void\npng_do_scale_16_to_8(png_row_infop row_info, png_bytep row)\n{\n   png_debug(1, \"in png_do_scale_16_to_8\");\n\n   if (row_info->bit_depth == 16)\n   {\n      png_bytep sp = row; /* source */\n      png_bytep dp = row; /* destination */\n      png_bytep ep = sp + row_info->rowbytes; /* end+1 */\n\n      while (sp < ep)\n      {\n         /* The input is an array of 16-bit components, these must be scaled to\n          * 8 bits each.  For a 16-bit value V the required value (from the PNG\n          * specification) is:\n          *\n          *    (V * 255) / 65535\n          *\n          * This reduces to round(V / 257), or floor((V + 128.5)/257)\n          *\n          * Represent V as the two byte value vhi.vlo.  Make a guess that the\n          * result is the top byte of V, vhi, then the correction to this value\n          * is:\n          *\n          *    error = floor(((V-vhi.vhi) + 128.5) / 257)\n          *          = floor(((vlo-vhi) + 128.5) / 257)\n          *\n          * This can be approximated using integer arithmetic (and a signed\n          * shift):\n          *\n          *    error = (vlo-vhi+128) >> 8;\n          *\n          * The approximate differs from the exact answer only when (vlo-vhi) is\n          * 128; it then gives a correction of +1 when the exact correction is\n          * 0.  This gives 128 errors.  The exact answer (correct for all 16-bit\n          * input values) is:\n          *\n          *    error = (vlo-vhi+128)*65535 >> 24;\n          *\n          * An alternative arithmetic calculation which also gives no errors is:\n          *\n          *    (V * 255 + 32895) >> 16\n          */\n\n         png_int_32 tmp = *sp++; /* must be signed! */\n         tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;\n         *dp++ = (png_byte)tmp;\n      }\n\n      row_info->bit_depth = 8;\n      row_info->pixel_depth = (png_byte)(8 * row_info->channels);\n      row_info->rowbytes = row_info->width * row_info->channels;\n   }\n}\n#endif\n\n#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED\nstatic void\n/* Simply discard the low byte.  This was the default behavior prior\n * to libpng-1.5.4.\n */\npng_do_chop(png_row_infop row_info, png_bytep row)\n{\n   png_debug(1, \"in png_do_chop\");\n\n   if (row_info->bit_depth == 16)\n   {\n      png_bytep sp = row; /* source */\n      png_bytep dp = row; /* destination */\n      png_bytep ep = sp + row_info->rowbytes; /* end+1 */\n\n      while (sp < ep)\n      {\n         *dp++ = *sp;\n         sp += 2; /* skip low byte */\n      }\n\n      row_info->bit_depth = 8;\n      row_info->pixel_depth = (png_byte)(8 * row_info->channels);\n      row_info->rowbytes = row_info->width * row_info->channels;\n   }\n}\n#endif\n\n#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED\nstatic void\npng_do_read_swap_alpha(png_row_infop row_info, png_bytep row)\n{\n   png_debug(1, \"in png_do_read_swap_alpha\");\n\n   {\n      png_uint_32 row_width = row_info->width;\n      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n      {\n         /* This converts from RGBA to ARGB */\n         if (row_info->bit_depth == 8)\n         {\n            png_bytep sp = row + row_info->rowbytes;\n            png_bytep dp = sp;\n            png_byte save;\n            png_uint_32 i;\n\n            for (i = 0; i < row_width; i++)\n            {\n               save = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = save;\n            }\n         }\n\n#ifdef PNG_READ_16BIT_SUPPORTED\n         /* This converts from RRGGBBAA to AARRGGBB */\n         else\n         {\n            png_bytep sp = row + row_info->rowbytes;\n            png_bytep dp = sp;\n            png_byte save[2];\n            png_uint_32 i;\n\n            for (i = 0; i < row_width; i++)\n            {\n               save[0] = *(--sp);\n               save[1] = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = save[0];\n               *(--dp) = save[1];\n            }\n         }\n#endif\n      }\n\n      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n      {\n         /* This converts from GA to AG */\n         if (row_info->bit_depth == 8)\n         {\n            png_bytep sp = row + row_info->rowbytes;\n            png_bytep dp = sp;\n            png_byte save;\n            png_uint_32 i;\n\n            for (i = 0; i < row_width; i++)\n            {\n               save = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = save;\n            }\n         }\n\n#ifdef PNG_READ_16BIT_SUPPORTED\n         /* This converts from GGAA to AAGG */\n         else\n         {\n            png_bytep sp = row + row_info->rowbytes;\n            png_bytep dp = sp;\n            png_byte save[2];\n            png_uint_32 i;\n\n            for (i = 0; i < row_width; i++)\n            {\n               save[0] = *(--sp);\n               save[1] = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = save[0];\n               *(--dp) = save[1];\n            }\n         }\n#endif\n      }\n   }\n}\n#endif\n\n#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED\nstatic void\npng_do_read_invert_alpha(png_row_infop row_info, png_bytep row)\n{\n   png_uint_32 row_width;\n   png_debug(1, \"in png_do_read_invert_alpha\");\n\n   row_width = row_info->width;\n   if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n   {\n      if (row_info->bit_depth == 8)\n      {\n         /* This inverts the alpha channel in RGBA */\n         png_bytep sp = row + row_info->rowbytes;\n         png_bytep dp = sp;\n         png_uint_32 i;\n\n         for (i = 0; i < row_width; i++)\n         {\n            *(--dp) = (png_byte)(255 - *(--sp));\n\n/*          This does nothing:\n            *(--dp) = *(--sp);\n            *(--dp) = *(--sp);\n            *(--dp) = *(--sp);\n            We can replace it with:\n*/\n            sp-=3;\n            dp=sp;\n         }\n      }\n\n#ifdef PNG_READ_16BIT_SUPPORTED\n      /* This inverts the alpha channel in RRGGBBAA */\n      else\n      {\n         png_bytep sp = row + row_info->rowbytes;\n         png_bytep dp = sp;\n         png_uint_32 i;\n\n         for (i = 0; i < row_width; i++)\n         {\n            *(--dp) = (png_byte)(255 - *(--sp));\n            *(--dp) = (png_byte)(255 - *(--sp));\n\n/*          This does nothing:\n            *(--dp) = *(--sp);\n            *(--dp) = *(--sp);\n            *(--dp) = *(--sp);\n            *(--dp) = *(--sp);\n            *(--dp) = *(--sp);\n            *(--dp) = *(--sp);\n            We can replace it with:\n*/\n            sp-=6;\n            dp=sp;\n         }\n      }\n#endif\n   }\n   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n   {\n      if (row_info->bit_depth == 8)\n      {\n         /* This inverts the alpha channel in GA */\n         png_bytep sp = row + row_info->rowbytes;\n         png_bytep dp = sp;\n         png_uint_32 i;\n\n         for (i = 0; i < row_width; i++)\n         {\n            *(--dp) = (png_byte)(255 - *(--sp));\n            *(--dp) = *(--sp);\n         }\n      }\n\n#ifdef PNG_READ_16BIT_SUPPORTED\n      else\n      {\n         /* This inverts the alpha channel in GGAA */\n         png_bytep sp  = row + row_info->rowbytes;\n         png_bytep dp = sp;\n         png_uint_32 i;\n\n         for (i = 0; i < row_width; i++)\n         {\n            *(--dp) = (png_byte)(255 - *(--sp));\n            *(--dp) = (png_byte)(255 - *(--sp));\n/*\n            *(--dp) = *(--sp);\n            *(--dp) = *(--sp);\n*/\n            sp-=2;\n            dp=sp;\n         }\n      }\n#endif\n   }\n}\n#endif\n\n#ifdef PNG_READ_FILLER_SUPPORTED\n/* Add filler channel if we have RGB color */\nstatic void\npng_do_read_filler(png_row_infop row_info, png_bytep row,\n    png_uint_32 filler, png_uint_32 flags)\n{\n   png_uint_32 i;\n   png_uint_32 row_width = row_info->width;\n\n#ifdef PNG_READ_16BIT_SUPPORTED\n   png_byte hi_filler = (png_byte)(filler>>8);\n#endif\n   png_byte lo_filler = (png_byte)filler;\n\n   png_debug(1, \"in png_do_read_filler\");\n\n   if (\n       row_info->color_type == PNG_COLOR_TYPE_GRAY)\n   {\n      if (row_info->bit_depth == 8)\n      {\n         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)\n         {\n            /* This changes the data from G to GX */\n            png_bytep sp = row + (png_size_t)row_width;\n            png_bytep dp =  sp + (png_size_t)row_width;\n            for (i = 1; i < row_width; i++)\n            {\n               *(--dp) = lo_filler;\n               *(--dp) = *(--sp);\n            }\n            *(--dp) = lo_filler;\n            row_info->channels = 2;\n            row_info->pixel_depth = 16;\n            row_info->rowbytes = row_width * 2;\n         }\n\n         else\n         {\n            /* This changes the data from G to XG */\n            png_bytep sp = row + (png_size_t)row_width;\n            png_bytep dp = sp  + (png_size_t)row_width;\n            for (i = 0; i < row_width; i++)\n            {\n               *(--dp) = *(--sp);\n               *(--dp) = lo_filler;\n            }\n            row_info->channels = 2;\n            row_info->pixel_depth = 16;\n            row_info->rowbytes = row_width * 2;\n         }\n      }\n\n#ifdef PNG_READ_16BIT_SUPPORTED\n      else if (row_info->bit_depth == 16)\n      {\n         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)\n         {\n            /* This changes the data from GG to GGXX */\n            png_bytep sp = row + (png_size_t)row_width * 2;\n            png_bytep dp = sp  + (png_size_t)row_width * 2;\n            for (i = 1; i < row_width; i++)\n            {\n               *(--dp) = lo_filler;\n               *(--dp) = hi_filler;\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n            }\n            *(--dp) = lo_filler;\n            *(--dp) = hi_filler;\n            row_info->channels = 2;\n            row_info->pixel_depth = 32;\n            row_info->rowbytes = row_width * 4;\n         }\n\n         else\n         {\n            /* This changes the data from GG to XXGG */\n            png_bytep sp = row + (png_size_t)row_width * 2;\n            png_bytep dp = sp  + (png_size_t)row_width * 2;\n            for (i = 0; i < row_width; i++)\n            {\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = lo_filler;\n               *(--dp) = hi_filler;\n            }\n            row_info->channels = 2;\n            row_info->pixel_depth = 32;\n            row_info->rowbytes = row_width * 4;\n         }\n      }\n#endif\n   } /* COLOR_TYPE == GRAY */\n   else if (row_info->color_type == PNG_COLOR_TYPE_RGB)\n   {\n      if (row_info->bit_depth == 8)\n      {\n         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)\n         {\n            /* This changes the data from RGB to RGBX */\n            png_bytep sp = row + (png_size_t)row_width * 3;\n            png_bytep dp = sp  + (png_size_t)row_width;\n            for (i = 1; i < row_width; i++)\n            {\n               *(--dp) = lo_filler;\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n            }\n            *(--dp) = lo_filler;\n            row_info->channels = 4;\n            row_info->pixel_depth = 32;\n            row_info->rowbytes = row_width * 4;\n         }\n\n         else\n         {\n            /* This changes the data from RGB to XRGB */\n            png_bytep sp = row + (png_size_t)row_width * 3;\n            png_bytep dp = sp + (png_size_t)row_width;\n            for (i = 0; i < row_width; i++)\n            {\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = lo_filler;\n            }\n            row_info->channels = 4;\n            row_info->pixel_depth = 32;\n            row_info->rowbytes = row_width * 4;\n         }\n      }\n\n#ifdef PNG_READ_16BIT_SUPPORTED\n      else if (row_info->bit_depth == 16)\n      {\n         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)\n         {\n            /* This changes the data from RRGGBB to RRGGBBXX */\n            png_bytep sp = row + (png_size_t)row_width * 6;\n            png_bytep dp = sp  + (png_size_t)row_width * 2;\n            for (i = 1; i < row_width; i++)\n            {\n               *(--dp) = lo_filler;\n               *(--dp) = hi_filler;\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n            }\n            *(--dp) = lo_filler;\n            *(--dp) = hi_filler;\n            row_info->channels = 4;\n            row_info->pixel_depth = 64;\n            row_info->rowbytes = row_width * 8;\n         }\n\n         else\n         {\n            /* This changes the data from RRGGBB to XXRRGGBB */\n            png_bytep sp = row + (png_size_t)row_width * 6;\n            png_bytep dp = sp  + (png_size_t)row_width * 2;\n            for (i = 0; i < row_width; i++)\n            {\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = *(--sp);\n               *(--dp) = lo_filler;\n               *(--dp) = hi_filler;\n            }\n\n            row_info->channels = 4;\n            row_info->pixel_depth = 64;\n            row_info->rowbytes = row_width * 8;\n         }\n      }\n#endif\n   } /* COLOR_TYPE == RGB */\n}\n#endif\n\n#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\n/* Expand grayscale files to RGB, with or without alpha */\nstatic void\npng_do_gray_to_rgb(png_row_infop row_info, png_bytep row)\n{\n   png_uint_32 i;\n   png_uint_32 row_width = row_info->width;\n\n   png_debug(1, \"in png_do_gray_to_rgb\");\n\n   if (row_info->bit_depth >= 8 &&\n       (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0)\n   {\n      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)\n      {\n         if (row_info->bit_depth == 8)\n         {\n            /* This changes G to RGB */\n            png_bytep sp = row + (png_size_t)row_width - 1;\n            png_bytep dp = sp  + (png_size_t)row_width * 2;\n            for (i = 0; i < row_width; i++)\n            {\n               *(dp--) = *sp;\n               *(dp--) = *sp;\n               *(dp--) = *(sp--);\n            }\n         }\n\n         else\n         {\n            /* This changes GG to RRGGBB */\n            png_bytep sp = row + (png_size_t)row_width * 2 - 1;\n            png_bytep dp = sp  + (png_size_t)row_width * 4;\n            for (i = 0; i < row_width; i++)\n            {\n               *(dp--) = *sp;\n               *(dp--) = *(sp - 1);\n               *(dp--) = *sp;\n               *(dp--) = *(sp - 1);\n               *(dp--) = *(sp--);\n               *(dp--) = *(sp--);\n            }\n         }\n      }\n\n      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n      {\n         if (row_info->bit_depth == 8)\n         {\n            /* This changes GA to RGBA */\n            png_bytep sp = row + (png_size_t)row_width * 2 - 1;\n            png_bytep dp = sp  + (png_size_t)row_width * 2;\n            for (i = 0; i < row_width; i++)\n            {\n               *(dp--) = *(sp--);\n               *(dp--) = *sp;\n               *(dp--) = *sp;\n               *(dp--) = *(sp--);\n            }\n         }\n\n         else\n         {\n            /* This changes GGAA to RRGGBBAA */\n            png_bytep sp = row + (png_size_t)row_width * 4 - 1;\n            png_bytep dp = sp  + (png_size_t)row_width * 4;\n            for (i = 0; i < row_width; i++)\n            {\n               *(dp--) = *(sp--);\n               *(dp--) = *(sp--);\n               *(dp--) = *sp;\n               *(dp--) = *(sp - 1);\n               *(dp--) = *sp;\n               *(dp--) = *(sp - 1);\n               *(dp--) = *(sp--);\n               *(dp--) = *(sp--);\n            }\n         }\n      }\n      row_info->channels = (png_byte)(row_info->channels + 2);\n      row_info->color_type |= PNG_COLOR_MASK_COLOR;\n      row_info->pixel_depth = (png_byte)(row_info->channels *\n          row_info->bit_depth);\n      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);\n   }\n}\n#endif\n\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\n/* Reduce RGB files to grayscale, with or without alpha\n * using the equation given in Poynton's ColorFAQ of 1998-01-04 at\n * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008 but\n * versions dated 1998 through November 2002 have been archived at\n * http://web.archive.org/web/20000816232553/http://www.inforamp.net/\n * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )\n * Charles Poynton poynton at poynton.com\n *\n *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B\n *\n *  which can be expressed with integers as\n *\n *     Y = (6969 * R + 23434 * G + 2365 * B)/32768\n *\n * Poynton's current link (as of January 2003 through July 2011):\n * <http://www.poynton.com/notes/colour_and_gamma/>\n * has changed the numbers slightly:\n *\n *     Y = 0.2126*R + 0.7152*G + 0.0722*B\n *\n *  which can be expressed with integers as\n *\n *     Y = (6966 * R + 23436 * G + 2366 * B)/32768\n *\n *  Historically, however, libpng uses numbers derived from the ITU-R Rec 709\n *  end point chromaticities and the D65 white point.  Depending on the\n *  precision used for the D65 white point this produces a variety of different\n *  numbers, however if the four decimal place value used in ITU-R Rec 709 is\n *  used (0.3127,0.3290) the Y calculation would be:\n *\n *     Y = (6968 * R + 23435 * G + 2366 * B)/32768\n *\n *  While this is correct the rounding results in an overflow for white, because\n *  the sum of the rounded coefficients is 32769, not 32768.  Consequently\n *  libpng uses, instead, the closest non-overflowing approximation:\n *\n *     Y = (6968 * R + 23434 * G + 2366 * B)/32768\n *\n *  Starting with libpng-1.5.5, if the image being converted has a cHRM chunk\n *  (including an sRGB chunk) then the chromaticities are used to calculate the\n *  coefficients.  See the chunk handling in pngrutil.c for more information.\n *\n *  In all cases the calculation is to be done in a linear colorspace.  If no\n *  gamma information is available to correct the encoding of the original RGB\n *  values this results in an implicit assumption that the original PNG RGB\n *  values were linear.\n *\n *  Other integer coefficents can be used via png_set_rgb_to_gray().  Because\n *  the API takes just red and green coefficients the blue coefficient is\n *  calculated to make the sum 32768.  This will result in different rounding\n *  to that used above.\n */\nstatic int\npng_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)\n\n{\n   int rgb_error = 0;\n\n   png_debug(1, \"in png_do_rgb_to_gray\");\n\n   if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 &&\n       (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)\n   {\n      PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;\n      PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;\n      PNG_CONST png_uint_32 bc = 32768 - rc - gc;\n      PNG_CONST png_uint_32 row_width = row_info->width;\n      PNG_CONST int have_alpha =\n         (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;\n\n      if (row_info->bit_depth == 8)\n      {\n#ifdef PNG_READ_GAMMA_SUPPORTED\n         /* Notice that gamma to/from 1 are not necessarily inverses (if\n          * there is an overall gamma correction).  Prior to 1.5.5 this code\n          * checked the linearized values for equality; this doesn't match\n          * the documentation, the original values must be checked.\n          */\n         if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)\n         {\n            png_bytep sp = row;\n            png_bytep dp = row;\n            png_uint_32 i;\n\n            for (i = 0; i < row_width; i++)\n            {\n               png_byte red   = *(sp++);\n               png_byte green = *(sp++);\n               png_byte blue  = *(sp++);\n\n               if (red != green || red != blue)\n               {\n                  red = png_ptr->gamma_to_1[red];\n                  green = png_ptr->gamma_to_1[green];\n                  blue = png_ptr->gamma_to_1[blue];\n\n                  rgb_error |= 1;\n                  *(dp++) = png_ptr->gamma_from_1[\n                      (rc*red + gc*green + bc*blue + 16384)>>15];\n               }\n\n               else\n               {\n                  /* If there is no overall correction the table will not be\n                   * set.\n                   */\n                  if (png_ptr->gamma_table != NULL)\n                     red = png_ptr->gamma_table[red];\n\n                  *(dp++) = red;\n               }\n\n               if (have_alpha != 0)\n                  *(dp++) = *(sp++);\n            }\n         }\n         else\n#endif\n         {\n            png_bytep sp = row;\n            png_bytep dp = row;\n            png_uint_32 i;\n\n            for (i = 0; i < row_width; i++)\n            {\n               png_byte red   = *(sp++);\n               png_byte green = *(sp++);\n               png_byte blue  = *(sp++);\n\n               if (red != green || red != blue)\n               {\n                  rgb_error |= 1;\n                  /* NOTE: this is the historical approach which simply\n                   * truncates the results.\n                   */\n                  *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);\n               }\n\n               else\n                  *(dp++) = red;\n\n               if (have_alpha != 0)\n                  *(dp++) = *(sp++);\n            }\n         }\n      }\n\n      else /* RGB bit_depth == 16 */\n      {\n#ifdef PNG_READ_GAMMA_SUPPORTED\n         if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)\n         {\n            png_bytep sp = row;\n            png_bytep dp = row;\n            png_uint_32 i;\n\n            for (i = 0; i < row_width; i++)\n            {\n               png_uint_16 red, green, blue, w;\n               png_byte hi,lo;\n\n               hi=*(sp)++; lo=*(sp)++; red   = (png_uint_16)((hi << 8) | (lo));\n               hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));\n               hi=*(sp)++; lo=*(sp)++; blue  = (png_uint_16)((hi << 8) | (lo));\n\n               if (red == green && red == blue)\n               {\n                  if (png_ptr->gamma_16_table != NULL)\n                     w = png_ptr->gamma_16_table[(red & 0xff)\n                         >> png_ptr->gamma_shift][red >> 8];\n\n                  else\n                     w = red;\n               }\n\n               else\n               {\n                  png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red & 0xff)\n                      >> png_ptr->gamma_shift][red>>8];\n                  png_uint_16 green_1 =\n                      png_ptr->gamma_16_to_1[(green & 0xff) >>\n                      png_ptr->gamma_shift][green>>8];\n                  png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue & 0xff)\n                      >> png_ptr->gamma_shift][blue>>8];\n                  png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1\n                      + bc*blue_1 + 16384)>>15);\n                  w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >>\n                      png_ptr->gamma_shift][gray16 >> 8];\n                  rgb_error |= 1;\n               }\n\n               *(dp++) = (png_byte)((w>>8) & 0xff);\n               *(dp++) = (png_byte)(w & 0xff);\n\n               if (have_alpha != 0)\n               {\n                  *(dp++) = *(sp++);\n                  *(dp++) = *(sp++);\n               }\n            }\n         }\n         else\n#endif\n         {\n            png_bytep sp = row;\n            png_bytep dp = row;\n            png_uint_32 i;\n\n            for (i = 0; i < row_width; i++)\n            {\n               png_uint_16 red, green, blue, gray16;\n               png_byte hi,lo;\n\n               hi=*(sp)++; lo=*(sp)++; red   = (png_uint_16)((hi << 8) | (lo));\n               hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));\n               hi=*(sp)++; lo=*(sp)++; blue  = (png_uint_16)((hi << 8) | (lo));\n\n               if (red != green || red != blue)\n                  rgb_error |= 1;\n\n               /* From 1.5.5 in the 16-bit case do the accurate conversion even\n                * in the 'fast' case - this is because this is where the code\n                * ends up when handling linear 16-bit data.\n                */\n               gray16  = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>\n                  15);\n               *(dp++) = (png_byte)((gray16 >> 8) & 0xff);\n               *(dp++) = (png_byte)(gray16 & 0xff);\n\n               if (have_alpha != 0)\n               {\n                  *(dp++) = *(sp++);\n                  *(dp++) = *(sp++);\n               }\n            }\n         }\n      }\n\n      row_info->channels = (png_byte)(row_info->channels - 2);\n      row_info->color_type = (png_byte)(row_info->color_type &\n          ~PNG_COLOR_MASK_COLOR);\n      row_info->pixel_depth = (png_byte)(row_info->channels *\n          row_info->bit_depth);\n      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);\n   }\n   return rgb_error;\n}\n#endif\n\n#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\\\n   defined(PNG_READ_ALPHA_MODE_SUPPORTED)\n/* Replace any alpha or transparency with the supplied background color.\n * \"background\" is already in the screen gamma, while \"background_1\" is\n * at a gamma of 1.0.  Paletted files have already been taken care of.\n */\nstatic void\npng_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)\n{\n#ifdef PNG_READ_GAMMA_SUPPORTED\n   png_const_bytep gamma_table = png_ptr->gamma_table;\n   png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;\n   png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;\n   png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;\n   png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;\n   png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1;\n   int gamma_shift = png_ptr->gamma_shift;\n   int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;\n#endif\n\n   png_bytep sp;\n   png_uint_32 i;\n   png_uint_32 row_width = row_info->width;\n   int shift;\n\n   png_debug(1, \"in png_do_compose\");\n\n   {\n      switch (row_info->color_type)\n      {\n         case PNG_COLOR_TYPE_GRAY:\n         {\n            switch (row_info->bit_depth)\n            {\n               case 1:\n               {\n                  sp = row;\n                  shift = 7;\n                  for (i = 0; i < row_width; i++)\n                  {\n                     if ((png_uint_16)((*sp >> shift) & 0x01)\n                        == png_ptr->trans_color.gray)\n                     {\n                        unsigned int tmp = *sp & (0x7f7f >> (7 - shift));\n                        tmp |= png_ptr->background.gray << shift;\n                        *sp = (png_byte)(tmp & 0xff);\n                     }\n\n                     if (shift == 0)\n                     {\n                        shift = 7;\n                        sp++;\n                     }\n\n                     else\n                        shift--;\n                  }\n                  break;\n               }\n\n               case 2:\n               {\n#ifdef PNG_READ_GAMMA_SUPPORTED\n                  if (gamma_table != NULL)\n                  {\n                     sp = row;\n                     shift = 6;\n                     for (i = 0; i < row_width; i++)\n                     {\n                        if ((png_uint_16)((*sp >> shift) & 0x03)\n                            == png_ptr->trans_color.gray)\n                        {\n                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));\n                           tmp |= png_ptr->background.gray << shift;\n                           *sp = (png_byte)(tmp & 0xff);\n                        }\n\n                        else\n                        {\n                           unsigned int p = (*sp >> shift) & 0x03;\n                           unsigned int g = (gamma_table [p | (p << 2) |\n                               (p << 4) | (p << 6)] >> 6) & 0x03;\n                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));\n                           tmp |= g << shift;\n                           *sp = (png_byte)(tmp & 0xff);\n                        }\n\n                        if (shift == 0)\n                        {\n                           shift = 6;\n                           sp++;\n                        }\n\n                        else\n                           shift -= 2;\n                     }\n                  }\n\n                  else\n#endif\n                  {\n                     sp = row;\n                     shift = 6;\n                     for (i = 0; i < row_width; i++)\n                     {\n                        if ((png_uint_16)((*sp >> shift) & 0x03)\n                            == png_ptr->trans_color.gray)\n                        {\n                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));\n                           tmp |= png_ptr->background.gray << shift;\n                           *sp = (png_byte)(tmp & 0xff);\n                        }\n\n                        if (shift == 0)\n                        {\n                           shift = 6;\n                           sp++;\n                        }\n\n                        else\n                           shift -= 2;\n                     }\n                  }\n                  break;\n               }\n\n               case 4:\n               {\n#ifdef PNG_READ_GAMMA_SUPPORTED\n                  if (gamma_table != NULL)\n                  {\n                     sp = row;\n                     shift = 4;\n                     for (i = 0; i < row_width; i++)\n                     {\n                        if ((png_uint_16)((*sp >> shift) & 0x0f)\n                            == png_ptr->trans_color.gray)\n                        {\n                           unsigned int tmp = *sp & (0x0f0f >> (4 - shift));\n                           tmp |= png_ptr->background.gray << shift;\n                           *sp = (png_byte)(tmp & 0xff);\n                        }\n\n                        else\n                        {\n                           unsigned int p = (*sp >> shift) & 0x0f;\n                           unsigned int g = (gamma_table[p | (p << 4)] >> 4) &\n                              0x0f;\n                           unsigned int tmp = *sp & (0x0f0f >> (4 - shift));\n                           tmp |= g << shift;\n                           *sp = (png_byte)(tmp & 0xff);\n                        }\n\n                        if (shift == 0)\n                        {\n                           shift = 4;\n                           sp++;\n                        }\n\n                        else\n                           shift -= 4;\n                     }\n                  }\n\n                  else\n#endif\n                  {\n                     sp = row;\n                     shift = 4;\n                     for (i = 0; i < row_width; i++)\n                     {\n                        if ((png_uint_16)((*sp >> shift) & 0x0f)\n                            == png_ptr->trans_color.gray)\n                        {\n                           unsigned int tmp = *sp & (0x0f0f >> (4 - shift));\n                           tmp |= png_ptr->background.gray << shift;\n                           *sp = (png_byte)(tmp & 0xff);\n                        }\n\n                        if (shift == 0)\n                        {\n                           shift = 4;\n                           sp++;\n                        }\n\n                        else\n                           shift -= 4;\n                     }\n                  }\n                  break;\n               }\n\n               case 8:\n               {\n#ifdef PNG_READ_GAMMA_SUPPORTED\n                  if (gamma_table != NULL)\n                  {\n                     sp = row;\n                     for (i = 0; i < row_width; i++, sp++)\n                     {\n                        if (*sp == png_ptr->trans_color.gray)\n                           *sp = (png_byte)png_ptr->background.gray;\n\n                        else\n                           *sp = gamma_table[*sp];\n                     }\n                  }\n                  else\n#endif\n                  {\n                     sp = row;\n                     for (i = 0; i < row_width; i++, sp++)\n                     {\n                        if (*sp == png_ptr->trans_color.gray)\n                           *sp = (png_byte)png_ptr->background.gray;\n                     }\n                  }\n                  break;\n               }\n\n               case 16:\n               {\n#ifdef PNG_READ_GAMMA_SUPPORTED\n                  if (gamma_16 != NULL)\n                  {\n                     sp = row;\n                     for (i = 0; i < row_width; i++, sp += 2)\n                     {\n                        png_uint_16 v;\n\n                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));\n\n                        if (v == png_ptr->trans_color.gray)\n                        {\n                           /* Background is already in screen gamma */\n                           *sp = (png_byte)((png_ptr->background.gray >> 8)\n                                & 0xff);\n                           *(sp + 1) = (png_byte)(png_ptr->background.gray\n                                & 0xff);\n                        }\n\n                        else\n                        {\n                           v = gamma_16[*(sp + 1) >> gamma_shift][*sp];\n                           *sp = (png_byte)((v >> 8) & 0xff);\n                           *(sp + 1) = (png_byte)(v & 0xff);\n                        }\n                     }\n                  }\n                  else\n#endif\n                  {\n                     sp = row;\n                     for (i = 0; i < row_width; i++, sp += 2)\n                     {\n                        png_uint_16 v;\n\n                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));\n\n                        if (v == png_ptr->trans_color.gray)\n                        {\n                           *sp = (png_byte)((png_ptr->background.gray >> 8)\n                                & 0xff);\n                           *(sp + 1) = (png_byte)(png_ptr->background.gray\n                                & 0xff);\n                        }\n                     }\n                  }\n                  break;\n               }\n\n               default:\n                  break;\n            }\n            break;\n         }\n\n         case PNG_COLOR_TYPE_RGB:\n         {\n            if (row_info->bit_depth == 8)\n            {\n#ifdef PNG_READ_GAMMA_SUPPORTED\n               if (gamma_table != NULL)\n               {\n                  sp = row;\n                  for (i = 0; i < row_width; i++, sp += 3)\n                  {\n                     if (*sp == png_ptr->trans_color.red &&\n                         *(sp + 1) == png_ptr->trans_color.green &&\n                         *(sp + 2) == png_ptr->trans_color.blue)\n                     {\n                        *sp = (png_byte)png_ptr->background.red;\n                        *(sp + 1) = (png_byte)png_ptr->background.green;\n                        *(sp + 2) = (png_byte)png_ptr->background.blue;\n                     }\n\n                     else\n                     {\n                        *sp = gamma_table[*sp];\n                        *(sp + 1) = gamma_table[*(sp + 1)];\n                        *(sp + 2) = gamma_table[*(sp + 2)];\n                     }\n                  }\n               }\n               else\n#endif\n               {\n                  sp = row;\n                  for (i = 0; i < row_width; i++, sp += 3)\n                  {\n                     if (*sp == png_ptr->trans_color.red &&\n                         *(sp + 1) == png_ptr->trans_color.green &&\n                         *(sp + 2) == png_ptr->trans_color.blue)\n                     {\n                        *sp = (png_byte)png_ptr->background.red;\n                        *(sp + 1) = (png_byte)png_ptr->background.green;\n                        *(sp + 2) = (png_byte)png_ptr->background.blue;\n                     }\n                  }\n               }\n            }\n            else /* if (row_info->bit_depth == 16) */\n            {\n#ifdef PNG_READ_GAMMA_SUPPORTED\n               if (gamma_16 != NULL)\n               {\n                  sp = row;\n                  for (i = 0; i < row_width; i++, sp += 6)\n                  {\n                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));\n\n                     png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)\n                         + *(sp + 3));\n\n                     png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)\n                         + *(sp + 5));\n\n                     if (r == png_ptr->trans_color.red &&\n                         g == png_ptr->trans_color.green &&\n                         b == png_ptr->trans_color.blue)\n                     {\n                        /* Background is already in screen gamma */\n                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);\n                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);\n                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)\n                                & 0xff);\n                        *(sp + 3) = (png_byte)(png_ptr->background.green\n                                & 0xff);\n                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)\n                                & 0xff);\n                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);\n                     }\n\n                     else\n                     {\n                        png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];\n                        *sp = (png_byte)((v >> 8) & 0xff);\n                        *(sp + 1) = (png_byte)(v & 0xff);\n\n                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];\n                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);\n                        *(sp + 3) = (png_byte)(v & 0xff);\n\n                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];\n                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);\n                        *(sp + 5) = (png_byte)(v & 0xff);\n                     }\n                  }\n               }\n\n               else\n#endif\n               {\n                  sp = row;\n                  for (i = 0; i < row_width; i++, sp += 6)\n                  {\n                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));\n\n                     png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)\n                         + *(sp + 3));\n\n                     png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)\n                         + *(sp + 5));\n\n                     if (r == png_ptr->trans_color.red &&\n                         g == png_ptr->trans_color.green &&\n                         b == png_ptr->trans_color.blue)\n                     {\n                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);\n                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);\n                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)\n                                & 0xff);\n                        *(sp + 3) = (png_byte)(png_ptr->background.green\n                                & 0xff);\n                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)\n                                & 0xff);\n                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);\n                     }\n                  }\n               }\n            }\n            break;\n         }\n\n         case PNG_COLOR_TYPE_GRAY_ALPHA:\n         {\n            if (row_info->bit_depth == 8)\n            {\n#ifdef PNG_READ_GAMMA_SUPPORTED\n               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&\n                   gamma_table != NULL)\n               {\n                  sp = row;\n                  for (i = 0; i < row_width; i++, sp += 2)\n                  {\n                     png_uint_16 a = *(sp + 1);\n\n                     if (a == 0xff)\n                        *sp = gamma_table[*sp];\n\n                     else if (a == 0)\n                     {\n                        /* Background is already in screen gamma */\n                        *sp = (png_byte)png_ptr->background.gray;\n                     }\n\n                     else\n                     {\n                        png_byte v, w;\n\n                        v = gamma_to_1[*sp];\n                        png_composite(w, v, a, png_ptr->background_1.gray);\n                        if (optimize == 0)\n                           w = gamma_from_1[w];\n                        *sp = w;\n                     }\n                  }\n               }\n               else\n#endif\n               {\n                  sp = row;\n                  for (i = 0; i < row_width; i++, sp += 2)\n                  {\n                     png_byte a = *(sp + 1);\n\n                     if (a == 0)\n                        *sp = (png_byte)png_ptr->background.gray;\n\n                     else if (a < 0xff)\n                        png_composite(*sp, *sp, a, png_ptr->background.gray);\n                  }\n               }\n            }\n            else /* if (png_ptr->bit_depth == 16) */\n            {\n#ifdef PNG_READ_GAMMA_SUPPORTED\n               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&\n                   gamma_16_to_1 != NULL)\n               {\n                  sp = row;\n                  for (i = 0; i < row_width; i++, sp += 4)\n                  {\n                     png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)\n                         + *(sp + 3));\n\n                     if (a == (png_uint_16)0xffff)\n                     {\n                        png_uint_16 v;\n\n                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];\n                        *sp = (png_byte)((v >> 8) & 0xff);\n                        *(sp + 1) = (png_byte)(v & 0xff);\n                     }\n\n                     else if (a == 0)\n                     {\n                        /* Background is already in screen gamma */\n                        *sp = (png_byte)((png_ptr->background.gray >> 8)\n                                & 0xff);\n                        *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);\n                     }\n\n                     else\n                     {\n                        png_uint_16 g, v, w;\n\n                        g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];\n                        png_composite_16(v, g, a, png_ptr->background_1.gray);\n                        if (optimize != 0)\n                           w = v;\n                        else\n                           w = gamma_16_from_1[(v & 0xff) >>\n                               gamma_shift][v >> 8];\n                        *sp = (png_byte)((w >> 8) & 0xff);\n                        *(sp + 1) = (png_byte)(w & 0xff);\n                     }\n                  }\n               }\n               else\n#endif\n               {\n                  sp = row;\n                  for (i = 0; i < row_width; i++, sp += 4)\n                  {\n                     png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)\n                         + *(sp + 3));\n\n                     if (a == 0)\n                     {\n                        *sp = (png_byte)((png_ptr->background.gray >> 8)\n                                & 0xff);\n                        *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);\n                     }\n\n                     else if (a < 0xffff)\n                     {\n                        png_uint_16 g, v;\n\n                        g = (png_uint_16)(((*sp) << 8) + *(sp + 1));\n                        png_composite_16(v, g, a, png_ptr->background.gray);\n                        *sp = (png_byte)((v >> 8) & 0xff);\n                        *(sp + 1) = (png_byte)(v & 0xff);\n                     }\n                  }\n               }\n            }\n            break;\n         }\n\n         case PNG_COLOR_TYPE_RGB_ALPHA:\n         {\n            if (row_info->bit_depth == 8)\n            {\n#ifdef PNG_READ_GAMMA_SUPPORTED\n               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&\n                   gamma_table != NULL)\n               {\n                  sp = row;\n                  for (i = 0; i < row_width; i++, sp += 4)\n                  {\n                     png_byte a = *(sp + 3);\n\n                     if (a == 0xff)\n                     {\n                        *sp = gamma_table[*sp];\n                        *(sp + 1) = gamma_table[*(sp + 1)];\n                        *(sp + 2) = gamma_table[*(sp + 2)];\n                     }\n\n                     else if (a == 0)\n                     {\n                        /* Background is already in screen gamma */\n                        *sp = (png_byte)png_ptr->background.red;\n                        *(sp + 1) = (png_byte)png_ptr->background.green;\n                        *(sp + 2) = (png_byte)png_ptr->background.blue;\n                     }\n\n                     else\n                     {\n                        png_byte v, w;\n\n                        v = gamma_to_1[*sp];\n                        png_composite(w, v, a, png_ptr->background_1.red);\n                        if (optimize == 0) w = gamma_from_1[w];\n                        *sp = w;\n\n                        v = gamma_to_1[*(sp + 1)];\n                        png_composite(w, v, a, png_ptr->background_1.green);\n                        if (optimize == 0) w = gamma_from_1[w];\n                        *(sp + 1) = w;\n\n                        v = gamma_to_1[*(sp + 2)];\n                        png_composite(w, v, a, png_ptr->background_1.blue);\n                        if (optimize == 0) w = gamma_from_1[w];\n                        *(sp + 2) = w;\n                     }\n                  }\n               }\n               else\n#endif\n               {\n                  sp = row;\n                  for (i = 0; i < row_width; i++, sp += 4)\n                  {\n                     png_byte a = *(sp + 3);\n\n                     if (a == 0)\n                     {\n                        *sp = (png_byte)png_ptr->background.red;\n                        *(sp + 1) = (png_byte)png_ptr->background.green;\n                        *(sp + 2) = (png_byte)png_ptr->background.blue;\n                     }\n\n                     else if (a < 0xff)\n                     {\n                        png_composite(*sp, *sp, a, png_ptr->background.red);\n\n                        png_composite(*(sp + 1), *(sp + 1), a,\n                            png_ptr->background.green);\n\n                        png_composite(*(sp + 2), *(sp + 2), a,\n                            png_ptr->background.blue);\n                     }\n                  }\n               }\n            }\n            else /* if (row_info->bit_depth == 16) */\n            {\n#ifdef PNG_READ_GAMMA_SUPPORTED\n               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&\n                   gamma_16_to_1 != NULL)\n               {\n                  sp = row;\n                  for (i = 0; i < row_width; i++, sp += 8)\n                  {\n                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))\n                         << 8) + (png_uint_16)(*(sp + 7)));\n\n                     if (a == (png_uint_16)0xffff)\n                     {\n                        png_uint_16 v;\n\n                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];\n                        *sp = (png_byte)((v >> 8) & 0xff);\n                        *(sp + 1) = (png_byte)(v & 0xff);\n\n                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];\n                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);\n                        *(sp + 3) = (png_byte)(v & 0xff);\n\n                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];\n                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);\n                        *(sp + 5) = (png_byte)(v & 0xff);\n                     }\n\n                     else if (a == 0)\n                     {\n                        /* Background is already in screen gamma */\n                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);\n                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);\n                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)\n                                & 0xff);\n                        *(sp + 3) = (png_byte)(png_ptr->background.green\n                                & 0xff);\n                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)\n                                & 0xff);\n                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);\n                     }\n\n                     else\n                     {\n                        png_uint_16 v, w;\n\n                        v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];\n                        png_composite_16(w, v, a, png_ptr->background_1.red);\n                        if (optimize == 0)\n                           w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>\n                                8];\n                        *sp = (png_byte)((w >> 8) & 0xff);\n                        *(sp + 1) = (png_byte)(w & 0xff);\n\n                        v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];\n                        png_composite_16(w, v, a, png_ptr->background_1.green);\n                        if (optimize == 0)\n                           w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>\n                                8];\n\n                        *(sp + 2) = (png_byte)((w >> 8) & 0xff);\n                        *(sp + 3) = (png_byte)(w & 0xff);\n\n                        v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];\n                        png_composite_16(w, v, a, png_ptr->background_1.blue);\n                        if (optimize == 0)\n                           w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>\n                                8];\n\n                        *(sp + 4) = (png_byte)((w >> 8) & 0xff);\n                        *(sp + 5) = (png_byte)(w & 0xff);\n                     }\n                  }\n               }\n\n               else\n#endif\n               {\n                  sp = row;\n                  for (i = 0; i < row_width; i++, sp += 8)\n                  {\n                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))\n                         << 8) + (png_uint_16)(*(sp + 7)));\n\n                     if (a == 0)\n                     {\n                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);\n                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);\n                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)\n                                & 0xff);\n                        *(sp + 3) = (png_byte)(png_ptr->background.green\n                                & 0xff);\n                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)\n                                & 0xff);\n                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);\n                     }\n\n                     else if (a < 0xffff)\n                     {\n                        png_uint_16 v;\n\n                        png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));\n                        png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)\n                            + *(sp + 3));\n                        png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)\n                            + *(sp + 5));\n\n                        png_composite_16(v, r, a, png_ptr->background.red);\n                        *sp = (png_byte)((v >> 8) & 0xff);\n                        *(sp + 1) = (png_byte)(v & 0xff);\n\n                        png_composite_16(v, g, a, png_ptr->background.green);\n                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);\n                        *(sp + 3) = (png_byte)(v & 0xff);\n\n                        png_composite_16(v, b, a, png_ptr->background.blue);\n                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);\n                        *(sp + 5) = (png_byte)(v & 0xff);\n                     }\n                  }\n               }\n            }\n            break;\n         }\n\n         default:\n            break;\n      }\n   }\n}\n#endif /* READ_BACKGROUND || READ_ALPHA_MODE */\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\n/* Gamma correct the image, avoiding the alpha channel.  Make sure\n * you do this after you deal with the transparency issue on grayscale\n * or RGB images. If your bit depth is 8, use gamma_table, if it\n * is 16, use gamma_16_table and gamma_shift.  Build these with\n * build_gamma_table().\n */\nstatic void\npng_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)\n{\n   png_const_bytep gamma_table = png_ptr->gamma_table;\n   png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;\n   int gamma_shift = png_ptr->gamma_shift;\n\n   png_bytep sp;\n   png_uint_32 i;\n   png_uint_32 row_width=row_info->width;\n\n   png_debug(1, \"in png_do_gamma\");\n\n   if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||\n       (row_info->bit_depth == 16 && gamma_16_table != NULL)))\n   {\n      switch (row_info->color_type)\n      {\n         case PNG_COLOR_TYPE_RGB:\n         {\n            if (row_info->bit_depth == 8)\n            {\n               sp = row;\n               for (i = 0; i < row_width; i++)\n               {\n                  *sp = gamma_table[*sp];\n                  sp++;\n                  *sp = gamma_table[*sp];\n                  sp++;\n                  *sp = gamma_table[*sp];\n                  sp++;\n               }\n            }\n\n            else /* if (row_info->bit_depth == 16) */\n            {\n               sp = row;\n               for (i = 0; i < row_width; i++)\n               {\n                  png_uint_16 v;\n\n                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];\n                  *sp = (png_byte)((v >> 8) & 0xff);\n                  *(sp + 1) = (png_byte)(v & 0xff);\n                  sp += 2;\n\n                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];\n                  *sp = (png_byte)((v >> 8) & 0xff);\n                  *(sp + 1) = (png_byte)(v & 0xff);\n                  sp += 2;\n\n                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];\n                  *sp = (png_byte)((v >> 8) & 0xff);\n                  *(sp + 1) = (png_byte)(v & 0xff);\n                  sp += 2;\n               }\n            }\n            break;\n         }\n\n         case PNG_COLOR_TYPE_RGB_ALPHA:\n         {\n            if (row_info->bit_depth == 8)\n            {\n               sp = row;\n               for (i = 0; i < row_width; i++)\n               {\n                  *sp = gamma_table[*sp];\n                  sp++;\n\n                  *sp = gamma_table[*sp];\n                  sp++;\n\n                  *sp = gamma_table[*sp];\n                  sp++;\n\n                  sp++;\n               }\n            }\n\n            else /* if (row_info->bit_depth == 16) */\n            {\n               sp = row;\n               for (i = 0; i < row_width; i++)\n               {\n                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];\n                  *sp = (png_byte)((v >> 8) & 0xff);\n                  *(sp + 1) = (png_byte)(v & 0xff);\n                  sp += 2;\n\n                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];\n                  *sp = (png_byte)((v >> 8) & 0xff);\n                  *(sp + 1) = (png_byte)(v & 0xff);\n                  sp += 2;\n\n                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];\n                  *sp = (png_byte)((v >> 8) & 0xff);\n                  *(sp + 1) = (png_byte)(v & 0xff);\n                  sp += 4;\n               }\n            }\n            break;\n         }\n\n         case PNG_COLOR_TYPE_GRAY_ALPHA:\n         {\n            if (row_info->bit_depth == 8)\n            {\n               sp = row;\n               for (i = 0; i < row_width; i++)\n               {\n                  *sp = gamma_table[*sp];\n                  sp += 2;\n               }\n            }\n\n            else /* if (row_info->bit_depth == 16) */\n            {\n               sp = row;\n               for (i = 0; i < row_width; i++)\n               {\n                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];\n                  *sp = (png_byte)((v >> 8) & 0xff);\n                  *(sp + 1) = (png_byte)(v & 0xff);\n                  sp += 4;\n               }\n            }\n            break;\n         }\n\n         case PNG_COLOR_TYPE_GRAY:\n         {\n            if (row_info->bit_depth == 2)\n            {\n               sp = row;\n               for (i = 0; i < row_width; i += 4)\n               {\n                  int a = *sp & 0xc0;\n                  int b = *sp & 0x30;\n                  int c = *sp & 0x0c;\n                  int d = *sp & 0x03;\n\n                  *sp = (png_byte)(\n                      ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|\n                      ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|\n                      ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|\n                      ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));\n                  sp++;\n               }\n            }\n\n            if (row_info->bit_depth == 4)\n            {\n               sp = row;\n               for (i = 0; i < row_width; i += 2)\n               {\n                  int msb = *sp & 0xf0;\n                  int lsb = *sp & 0x0f;\n\n                  *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)\n                      | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));\n                  sp++;\n               }\n            }\n\n            else if (row_info->bit_depth == 8)\n            {\n               sp = row;\n               for (i = 0; i < row_width; i++)\n               {\n                  *sp = gamma_table[*sp];\n                  sp++;\n               }\n            }\n\n            else if (row_info->bit_depth == 16)\n            {\n               sp = row;\n               for (i = 0; i < row_width; i++)\n               {\n                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];\n                  *sp = (png_byte)((v >> 8) & 0xff);\n                  *(sp + 1) = (png_byte)(v & 0xff);\n                  sp += 2;\n               }\n            }\n            break;\n         }\n\n         default:\n            break;\n      }\n   }\n}\n#endif\n\n#ifdef PNG_READ_ALPHA_MODE_SUPPORTED\n/* Encode the alpha channel to the output gamma (the input channel is always\n * linear.)  Called only with color types that have an alpha channel.  Needs the\n * from_1 tables.\n */\nstatic void\npng_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)\n{\n   png_uint_32 row_width = row_info->width;\n\n   png_debug(1, \"in png_do_encode_alpha\");\n\n   if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)\n   {\n      if (row_info->bit_depth == 8)\n      {\n         PNG_CONST png_bytep table = png_ptr->gamma_from_1;\n\n         if (table != NULL)\n         {\n            PNG_CONST int step =\n               (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;\n\n            /* The alpha channel is the last component: */\n            row += step - 1;\n\n            for (; row_width > 0; --row_width, row += step)\n               *row = table[*row];\n\n            return;\n         }\n      }\n\n      else if (row_info->bit_depth == 16)\n      {\n         PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;\n         PNG_CONST int gamma_shift = png_ptr->gamma_shift;\n\n         if (table != NULL)\n         {\n            PNG_CONST int step =\n               (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;\n\n            /* The alpha channel is the last component: */\n            row += step - 2;\n\n            for (; row_width > 0; --row_width, row += step)\n            {\n               png_uint_16 v;\n\n               v = table[*(row + 1) >> gamma_shift][*row];\n               *row = (png_byte)((v >> 8) & 0xff);\n               *(row + 1) = (png_byte)(v & 0xff);\n            }\n\n            return;\n         }\n      }\n   }\n\n   /* Only get to here if called with a weird row_info; no harm has been done,\n    * so just issue a warning.\n    */\n   png_warning(png_ptr, \"png_do_encode_alpha: unexpected call\");\n}\n#endif\n\n#ifdef PNG_READ_EXPAND_SUPPORTED\n/* Expands a palette row to an RGB or RGBA row depending\n * upon whether you supply trans and num_trans.\n */\nstatic void\npng_do_expand_palette(png_row_infop row_info, png_bytep row,\n   png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)\n{\n   int shift, value;\n   png_bytep sp, dp;\n   png_uint_32 i;\n   png_uint_32 row_width=row_info->width;\n\n   png_debug(1, \"in png_do_expand_palette\");\n\n   if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)\n   {\n      if (row_info->bit_depth < 8)\n      {\n         switch (row_info->bit_depth)\n         {\n            case 1:\n            {\n               sp = row + (png_size_t)((row_width - 1) >> 3);\n               dp = row + (png_size_t)row_width - 1;\n               shift = 7 - (int)((row_width + 7) & 0x07);\n               for (i = 0; i < row_width; i++)\n               {\n                  if ((*sp >> shift) & 0x01)\n                     *dp = 1;\n\n                  else\n                     *dp = 0;\n\n                  if (shift == 7)\n                  {\n                     shift = 0;\n                     sp--;\n                  }\n\n                  else\n                     shift++;\n\n                  dp--;\n               }\n               break;\n            }\n\n            case 2:\n            {\n               sp = row + (png_size_t)((row_width - 1) >> 2);\n               dp = row + (png_size_t)row_width - 1;\n               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);\n               for (i = 0; i < row_width; i++)\n               {\n                  value = (*sp >> shift) & 0x03;\n                  *dp = (png_byte)value;\n                  if (shift == 6)\n                  {\n                     shift = 0;\n                     sp--;\n                  }\n\n                  else\n                     shift += 2;\n\n                  dp--;\n               }\n               break;\n            }\n\n            case 4:\n            {\n               sp = row + (png_size_t)((row_width - 1) >> 1);\n               dp = row + (png_size_t)row_width - 1;\n               shift = (int)((row_width & 0x01) << 2);\n               for (i = 0; i < row_width; i++)\n               {\n                  value = (*sp >> shift) & 0x0f;\n                  *dp = (png_byte)value;\n                  if (shift == 4)\n                  {\n                     shift = 0;\n                     sp--;\n                  }\n\n                  else\n                     shift += 4;\n\n                  dp--;\n               }\n               break;\n            }\n\n            default:\n               break;\n         }\n         row_info->bit_depth = 8;\n         row_info->pixel_depth = 8;\n         row_info->rowbytes = row_width;\n      }\n\n      if (row_info->bit_depth == 8)\n      {\n         {\n            if (num_trans > 0)\n            {\n               sp = row + (png_size_t)row_width - 1;\n               dp = row + (png_size_t)(row_width << 2) - 1;\n\n               for (i = 0; i < row_width; i++)\n               {\n                  if ((int)(*sp) >= num_trans)\n                     *dp-- = 0xff;\n\n                  else\n                     *dp-- = trans_alpha[*sp];\n\n                  *dp-- = palette[*sp].blue;\n                  *dp-- = palette[*sp].green;\n                  *dp-- = palette[*sp].red;\n                  sp--;\n               }\n               row_info->bit_depth = 8;\n               row_info->pixel_depth = 32;\n               row_info->rowbytes = row_width * 4;\n               row_info->color_type = 6;\n               row_info->channels = 4;\n            }\n\n            else\n            {\n               sp = row + (png_size_t)row_width - 1;\n               dp = row + (png_size_t)(row_width * 3) - 1;\n\n               for (i = 0; i < row_width; i++)\n               {\n                  *dp-- = palette[*sp].blue;\n                  *dp-- = palette[*sp].green;\n                  *dp-- = palette[*sp].red;\n                  sp--;\n               }\n\n               row_info->bit_depth = 8;\n               row_info->pixel_depth = 24;\n               row_info->rowbytes = row_width * 3;\n               row_info->color_type = 2;\n               row_info->channels = 3;\n            }\n         }\n      }\n   }\n}\n\n/* If the bit depth < 8, it is expanded to 8.  Also, if the already\n * expanded transparency value is supplied, an alpha channel is built.\n */\nstatic void\npng_do_expand(png_row_infop row_info, png_bytep row,\n    png_const_color_16p trans_color)\n{\n   int shift, value;\n   png_bytep sp, dp;\n   png_uint_32 i;\n   png_uint_32 row_width=row_info->width;\n\n   png_debug(1, \"in png_do_expand\");\n\n   {\n      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)\n      {\n         unsigned int gray = trans_color != NULL ? trans_color->gray : 0;\n\n         if (row_info->bit_depth < 8)\n         {\n            switch (row_info->bit_depth)\n            {\n               case 1:\n               {\n                  gray = (gray & 0x01) * 0xff;\n                  sp = row + (png_size_t)((row_width - 1) >> 3);\n                  dp = row + (png_size_t)row_width - 1;\n                  shift = 7 - (int)((row_width + 7) & 0x07);\n                  for (i = 0; i < row_width; i++)\n                  {\n                     if ((*sp >> shift) & 0x01)\n                        *dp = 0xff;\n\n                     else\n                        *dp = 0;\n\n                     if (shift == 7)\n                     {\n                        shift = 0;\n                        sp--;\n                     }\n\n                     else\n                        shift++;\n\n                     dp--;\n                  }\n                  break;\n               }\n\n               case 2:\n               {\n                  gray = (gray & 0x03) * 0x55;\n                  sp = row + (png_size_t)((row_width - 1) >> 2);\n                  dp = row + (png_size_t)row_width - 1;\n                  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);\n                  for (i = 0; i < row_width; i++)\n                  {\n                     value = (*sp >> shift) & 0x03;\n                     *dp = (png_byte)(value | (value << 2) | (value << 4) |\n                        (value << 6));\n                     if (shift == 6)\n                     {\n                        shift = 0;\n                        sp--;\n                     }\n\n                     else\n                        shift += 2;\n\n                     dp--;\n                  }\n                  break;\n               }\n\n               case 4:\n               {\n                  gray = (gray & 0x0f) * 0x11;\n                  sp = row + (png_size_t)((row_width - 1) >> 1);\n                  dp = row + (png_size_t)row_width - 1;\n                  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);\n                  for (i = 0; i < row_width; i++)\n                  {\n                     value = (*sp >> shift) & 0x0f;\n                     *dp = (png_byte)(value | (value << 4));\n                     if (shift == 4)\n                     {\n                        shift = 0;\n                        sp--;\n                     }\n\n                     else\n                        shift = 4;\n\n                     dp--;\n                  }\n                  break;\n               }\n\n               default:\n                  break;\n            }\n\n            row_info->bit_depth = 8;\n            row_info->pixel_depth = 8;\n            row_info->rowbytes = row_width;\n         }\n\n         if (trans_color != NULL)\n         {\n            if (row_info->bit_depth == 8)\n            {\n               gray = gray & 0xff;\n               sp = row + (png_size_t)row_width - 1;\n               dp = row + (png_size_t)(row_width << 1) - 1;\n\n               for (i = 0; i < row_width; i++)\n               {\n                  if ((*sp & 0xffU) == gray)\n                     *dp-- = 0;\n\n                  else\n                     *dp-- = 0xff;\n\n                  *dp-- = *sp--;\n               }\n            }\n\n            else if (row_info->bit_depth == 16)\n            {\n               unsigned int gray_high = (gray >> 8) & 0xff;\n               unsigned int gray_low = gray & 0xff;\n               sp = row + row_info->rowbytes - 1;\n               dp = row + (row_info->rowbytes << 1) - 1;\n               for (i = 0; i < row_width; i++)\n               {\n                  if ((*(sp - 1) & 0xffU) == gray_high &&\n                      (*(sp) & 0xffU) == gray_low)\n                  {\n                     *dp-- = 0;\n                     *dp-- = 0;\n                  }\n\n                  else\n                  {\n                     *dp-- = 0xff;\n                     *dp-- = 0xff;\n                  }\n\n                  *dp-- = *sp--;\n                  *dp-- = *sp--;\n               }\n            }\n\n            row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;\n            row_info->channels = 2;\n            row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);\n            row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,\n               row_width);\n         }\n      }\n      else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&\n          trans_color != NULL)\n      {\n         if (row_info->bit_depth == 8)\n         {\n            png_byte red = (png_byte)(trans_color->red & 0xff);\n            png_byte green = (png_byte)(trans_color->green & 0xff);\n            png_byte blue = (png_byte)(trans_color->blue & 0xff);\n            sp = row + (png_size_t)row_info->rowbytes - 1;\n            dp = row + (png_size_t)(row_width << 2) - 1;\n            for (i = 0; i < row_width; i++)\n            {\n               if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)\n                  *dp-- = 0;\n\n               else\n                  *dp-- = 0xff;\n\n               *dp-- = *sp--;\n               *dp-- = *sp--;\n               *dp-- = *sp--;\n            }\n         }\n         else if (row_info->bit_depth == 16)\n         {\n            png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);\n            png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);\n            png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);\n            png_byte red_low = (png_byte)(trans_color->red & 0xff);\n            png_byte green_low = (png_byte)(trans_color->green & 0xff);\n            png_byte blue_low = (png_byte)(trans_color->blue & 0xff);\n            sp = row + row_info->rowbytes - 1;\n            dp = row + (png_size_t)(row_width << 3) - 1;\n            for (i = 0; i < row_width; i++)\n            {\n               if (*(sp - 5) == red_high &&\n                   *(sp - 4) == red_low &&\n                   *(sp - 3) == green_high &&\n                   *(sp - 2) == green_low &&\n                   *(sp - 1) == blue_high &&\n                   *(sp    ) == blue_low)\n               {\n                  *dp-- = 0;\n                  *dp-- = 0;\n               }\n\n               else\n               {\n                  *dp-- = 0xff;\n                  *dp-- = 0xff;\n               }\n\n               *dp-- = *sp--;\n               *dp-- = *sp--;\n               *dp-- = *sp--;\n               *dp-- = *sp--;\n               *dp-- = *sp--;\n               *dp-- = *sp--;\n            }\n         }\n         row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;\n         row_info->channels = 4;\n         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);\n         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);\n      }\n   }\n}\n#endif\n\n#ifdef PNG_READ_EXPAND_16_SUPPORTED\n/* If the bit depth is 8 and the color type is not a palette type expand the\n * whole row to 16 bits.  Has no effect otherwise.\n */\nstatic void\npng_do_expand_16(png_row_infop row_info, png_bytep row)\n{\n   if (row_info->bit_depth == 8 &&\n      row_info->color_type != PNG_COLOR_TYPE_PALETTE)\n   {\n      /* The row have a sequence of bytes containing [0..255] and we need\n       * to turn it into another row containing [0..65535], to do this we\n       * calculate:\n       *\n       *  (input / 255) * 65535\n       *\n       *  Which happens to be exactly input * 257 and this can be achieved\n       *  simply by byte replication in place (copying backwards).\n       */\n      png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */\n      png_byte *dp = sp + row_info->rowbytes;  /* destination, end + 1 */\n      while (dp > sp)\n         dp[-2] = dp[-1] = *--sp, dp -= 2;\n\n      row_info->rowbytes *= 2;\n      row_info->bit_depth = 16;\n      row_info->pixel_depth = (png_byte)(row_info->channels * 16);\n   }\n}\n#endif\n\n#ifdef PNG_READ_QUANTIZE_SUPPORTED\nstatic void\npng_do_quantize(png_row_infop row_info, png_bytep row,\n    png_const_bytep palette_lookup, png_const_bytep quantize_lookup)\n{\n   png_bytep sp, dp;\n   png_uint_32 i;\n   png_uint_32 row_width=row_info->width;\n\n   png_debug(1, \"in png_do_quantize\");\n\n   if (row_info->bit_depth == 8)\n   {\n      if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)\n      {\n         int r, g, b, p;\n         sp = row;\n         dp = row;\n         for (i = 0; i < row_width; i++)\n         {\n            r = *sp++;\n            g = *sp++;\n            b = *sp++;\n\n            /* This looks real messy, but the compiler will reduce\n             * it down to a reasonable formula.  For example, with\n             * 5 bits per color, we get:\n             * p = (((r >> 3) & 0x1f) << 10) |\n             *    (((g >> 3) & 0x1f) << 5) |\n             *    ((b >> 3) & 0x1f);\n             */\n            p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &\n                ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<\n                (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |\n                (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &\n                ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<\n                (PNG_QUANTIZE_BLUE_BITS)) |\n                ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &\n                ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));\n\n            *dp++ = palette_lookup[p];\n         }\n\n         row_info->color_type = PNG_COLOR_TYPE_PALETTE;\n         row_info->channels = 1;\n         row_info->pixel_depth = row_info->bit_depth;\n         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);\n      }\n\n      else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&\n         palette_lookup != NULL)\n      {\n         int r, g, b, p;\n         sp = row;\n         dp = row;\n         for (i = 0; i < row_width; i++)\n         {\n            r = *sp++;\n            g = *sp++;\n            b = *sp++;\n            sp++;\n\n            p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &\n                ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<\n                (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |\n                (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &\n                ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<\n                (PNG_QUANTIZE_BLUE_BITS)) |\n                ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &\n                ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));\n\n            *dp++ = palette_lookup[p];\n         }\n\n         row_info->color_type = PNG_COLOR_TYPE_PALETTE;\n         row_info->channels = 1;\n         row_info->pixel_depth = row_info->bit_depth;\n         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);\n      }\n\n      else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&\n         quantize_lookup)\n      {\n         sp = row;\n\n         for (i = 0; i < row_width; i++, sp++)\n         {\n            *sp = quantize_lookup[*sp];\n         }\n      }\n   }\n}\n#endif /* READ_QUANTIZE */\n\n/* Transform the row.  The order of transformations is significant,\n * and is very touchy.  If you add a transformation, take care to\n * decide how it fits in with the other transformations here.\n */\nvoid /* PRIVATE */\npng_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)\n{\n   png_debug(1, \"in png_do_read_transformations\");\n\n   if (png_ptr->row_buf == NULL)\n   {\n      /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this\n       * error is incredibly rare and incredibly easy to debug without this\n       * information.\n       */\n      png_error(png_ptr, \"NULL row buffer\");\n   }\n\n   /* The following is debugging; prior to 1.5.4 the code was never compiled in;\n    * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro\n    * PNG_WARN_UNINITIALIZED_ROW removed.  In 1.6 the new flag is set only for\n    * all transformations, however in practice the ROW_INIT always gets done on\n    * demand, if necessary.\n    */\n   if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&\n       (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)\n   {\n      /* Application has failed to call either png_read_start_image() or\n       * png_read_update_info() after setting transforms that expand pixels.\n       * This check added to libpng-1.2.19 (but not enabled until 1.5.4).\n       */\n      png_error(png_ptr, \"Uninitialized row\");\n   }\n\n#ifdef PNG_READ_EXPAND_SUPPORTED\n   if ((png_ptr->transformations & PNG_EXPAND) != 0)\n   {\n      if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)\n      {\n         png_do_expand_palette(row_info, png_ptr->row_buf + 1,\n             png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);\n      }\n\n      else\n      {\n         if (png_ptr->num_trans != 0 &&\n             (png_ptr->transformations & PNG_EXPAND_tRNS) != 0)\n            png_do_expand(row_info, png_ptr->row_buf + 1,\n                &(png_ptr->trans_color));\n\n         else\n            png_do_expand(row_info, png_ptr->row_buf + 1,\n                NULL);\n      }\n   }\n#endif\n\n#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED\n   if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&\n       (png_ptr->transformations & PNG_COMPOSE) == 0 &&\n       (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||\n       row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))\n      png_do_strip_channel(row_info, png_ptr->row_buf + 1,\n         0 /* at_start == false, because SWAP_ALPHA happens later */);\n#endif\n\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\n   if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)\n   {\n      int rgb_error =\n          png_do_rgb_to_gray(png_ptr, row_info,\n              png_ptr->row_buf + 1);\n\n      if (rgb_error != 0)\n      {\n         png_ptr->rgb_to_gray_status=1;\n         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==\n             PNG_RGB_TO_GRAY_WARN)\n            png_warning(png_ptr, \"png_do_rgb_to_gray found nongray pixel\");\n\n         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==\n             PNG_RGB_TO_GRAY_ERR)\n            png_error(png_ptr, \"png_do_rgb_to_gray found nongray pixel\");\n      }\n   }\n#endif\n\n/* From Andreas Dilger e-mail to png-implement, 26 March 1998:\n *\n *   In most cases, the \"simple transparency\" should be done prior to doing\n *   gray-to-RGB, or you will have to test 3x as many bytes to check if a\n *   pixel is transparent.  You would also need to make sure that the\n *   transparency information is upgraded to RGB.\n *\n *   To summarize, the current flow is:\n *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite\n *                                   with background \"in place\" if transparent,\n *                                   convert to RGB if necessary\n *   - Gray + alpha -> composite with gray background and remove alpha bytes,\n *                                   convert to RGB if necessary\n *\n *   To support RGB backgrounds for gray images we need:\n *   - Gray + simple transparency -> convert to RGB + simple transparency,\n *                                   compare 3 or 6 bytes and composite with\n *                                   background \"in place\" if transparent\n *                                   (3x compare/pixel compared to doing\n *                                   composite with gray bkgrnd)\n *   - Gray + alpha -> convert to RGB + alpha, composite with background and\n *                                   remove alpha bytes (3x float\n *                                   operations/pixel compared with composite\n *                                   on gray background)\n *\n *  Greg's change will do this.  The reason it wasn't done before is for\n *  performance, as this increases the per-pixel operations.  If we would check\n *  in advance if the background was gray or RGB, and position the gray-to-RGB\n *  transform appropriately, then it would save a lot of work/time.\n */\n\n#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\n   /* If gray -> RGB, do so now only if background is non-gray; else do later\n    * for performance reasons\n    */\n   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&\n       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0)\n      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);\n#endif\n\n#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\\\n   defined(PNG_READ_ALPHA_MODE_SUPPORTED)\n   if ((png_ptr->transformations & PNG_COMPOSE) != 0)\n      png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);\n#endif\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\n   if ((png_ptr->transformations & PNG_GAMMA) != 0 &&\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\n      /* Because RGB_TO_GRAY does the gamma transform. */\n      (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 &&\n#endif\n#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\\\n   defined(PNG_READ_ALPHA_MODE_SUPPORTED)\n      /* Because PNG_COMPOSE does the gamma transform if there is something to\n       * do (if there is an alpha channel or transparency.)\n       */\n       !((png_ptr->transformations & PNG_COMPOSE) != 0 &&\n       ((png_ptr->num_trans != 0) ||\n       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) &&\n#endif\n      /* Because png_init_read_transformations transforms the palette, unless\n       * RGB_TO_GRAY will do the transform.\n       */\n       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))\n      png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);\n#endif\n\n#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED\n   if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&\n       (png_ptr->transformations & PNG_COMPOSE) != 0 &&\n       (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||\n       row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))\n      png_do_strip_channel(row_info, png_ptr->row_buf + 1,\n          0 /* at_start == false, because SWAP_ALPHA happens later */);\n#endif\n\n#ifdef PNG_READ_ALPHA_MODE_SUPPORTED\n   if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&\n       (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)\n      png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);\n#endif\n\n#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\n   if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)\n      png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);\n#endif\n\n#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED\n   /* There is no harm in doing both of these because only one has any effect,\n    * by putting the 'scale' option first if the app asks for scale (either by\n    * calling the API or in a TRANSFORM flag) this is what happens.\n    */\n   if ((png_ptr->transformations & PNG_16_TO_8) != 0)\n      png_do_chop(row_info, png_ptr->row_buf + 1);\n#endif\n\n#ifdef PNG_READ_QUANTIZE_SUPPORTED\n   if ((png_ptr->transformations & PNG_QUANTIZE) != 0)\n   {\n      png_do_quantize(row_info, png_ptr->row_buf + 1,\n          png_ptr->palette_lookup, png_ptr->quantize_index);\n\n      if (row_info->rowbytes == 0)\n         png_error(png_ptr, \"png_do_quantize returned rowbytes=0\");\n   }\n#endif /* READ_QUANTIZE */\n\n#ifdef PNG_READ_EXPAND_16_SUPPORTED\n   /* Do the expansion now, after all the arithmetic has been done.  Notice\n    * that previous transformations can handle the PNG_EXPAND_16 flag if this\n    * is efficient (particularly true in the case of gamma correction, where\n    * better accuracy results faster!)\n    */\n   if ((png_ptr->transformations & PNG_EXPAND_16) != 0)\n      png_do_expand_16(row_info, png_ptr->row_buf + 1);\n#endif\n\n#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\n   /* NOTE: moved here in 1.5.4 (from much later in this list.) */\n   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&\n       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0)\n      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);\n#endif\n\n#ifdef PNG_READ_INVERT_SUPPORTED\n   if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)\n      png_do_invert(row_info, png_ptr->row_buf + 1);\n#endif\n\n#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED\n   if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)\n      png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);\n#endif\n\n#ifdef PNG_READ_SHIFT_SUPPORTED\n   if ((png_ptr->transformations & PNG_SHIFT) != 0)\n      png_do_unshift(row_info, png_ptr->row_buf + 1,\n          &(png_ptr->shift));\n#endif\n\n#ifdef PNG_READ_PACK_SUPPORTED\n   if ((png_ptr->transformations & PNG_PACK) != 0)\n      png_do_unpack(row_info, png_ptr->row_buf + 1);\n#endif\n\n#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED\n   /* Added at libpng-1.5.10 */\n   if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&\n       png_ptr->num_palette_max >= 0)\n      png_do_check_palette_indexes(png_ptr, row_info);\n#endif\n\n#ifdef PNG_READ_BGR_SUPPORTED\n   if ((png_ptr->transformations & PNG_BGR) != 0)\n      png_do_bgr(row_info, png_ptr->row_buf + 1);\n#endif\n\n#ifdef PNG_READ_PACKSWAP_SUPPORTED\n   if ((png_ptr->transformations & PNG_PACKSWAP) != 0)\n      png_do_packswap(row_info, png_ptr->row_buf + 1);\n#endif\n\n#ifdef PNG_READ_FILLER_SUPPORTED\n   if ((png_ptr->transformations & PNG_FILLER) != 0)\n      png_do_read_filler(row_info, png_ptr->row_buf + 1,\n          (png_uint_32)png_ptr->filler, png_ptr->flags);\n#endif\n\n#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED\n   if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)\n      png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);\n#endif\n\n#ifdef PNG_READ_16BIT_SUPPORTED\n#ifdef PNG_READ_SWAP_SUPPORTED\n   if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)\n      png_do_swap(row_info, png_ptr->row_buf + 1);\n#endif\n#endif\n\n#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED\n   if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)\n   {\n      if (png_ptr->read_user_transform_fn != NULL)\n         (*(png_ptr->read_user_transform_fn)) /* User read transform function */\n             (png_ptr,     /* png_ptr */\n             row_info,     /* row_info: */\n                /*  png_uint_32 width;       width of row */\n                /*  png_size_t rowbytes;     number of bytes in row */\n                /*  png_byte color_type;     color type of pixels */\n                /*  png_byte bit_depth;      bit depth of samples */\n                /*  png_byte channels;       number of channels (1-4) */\n                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */\n             png_ptr->row_buf + 1);    /* start of pixel data for row */\n#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED\n      if (png_ptr->user_transform_depth != 0)\n         row_info->bit_depth = png_ptr->user_transform_depth;\n\n      if (png_ptr->user_transform_channels != 0)\n         row_info->channels = png_ptr->user_transform_channels;\n#endif\n      row_info->pixel_depth = (png_byte)(row_info->bit_depth *\n          row_info->channels);\n\n      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);\n   }\n#endif\n}\n\n#endif /* READ_TRANSFORMS */\n#endif /* READ */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngrutil.c",
    "content": "\n/* pngrutil.c - utilities to read a PNG file\n *\n * Last changed in libpng 1.6.20 [December 3, 2014]\n * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * This file contains routines that are only called from within\n * libpng itself during the course of reading an image.\n */\n\n#include \"pngpriv.h\"\n\n#ifdef PNG_READ_SUPPORTED\n\npng_uint_32 PNGAPI\npng_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf)\n{\n   png_uint_32 uval = png_get_uint_32(buf);\n\n   if (uval > PNG_UINT_31_MAX)\n      png_error(png_ptr, \"PNG unsigned integer out of range\");\n\n   return (uval);\n}\n\n#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)\n/* The following is a variation on the above for use with the fixed\n * point values used for gAMA and cHRM.  Instead of png_error it\n * issues a warning and returns (-1) - an invalid value because both\n * gAMA and cHRM use *unsigned* integers for fixed point values.\n */\n#define PNG_FIXED_ERROR (-1)\n\nstatic png_fixed_point /* PRIVATE */\npng_get_fixed_point(png_structrp png_ptr, png_const_bytep buf)\n{\n   png_uint_32 uval = png_get_uint_32(buf);\n\n   if (uval <= PNG_UINT_31_MAX)\n      return (png_fixed_point)uval; /* known to be in range */\n\n   /* The caller can turn off the warning by passing NULL. */\n   if (png_ptr != NULL)\n      png_warning(png_ptr, \"PNG fixed point integer out of range\");\n\n   return PNG_FIXED_ERROR;\n}\n#endif\n\n#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED\n/* NOTE: the read macros will obscure these definitions, so that if\n * PNG_USE_READ_MACROS is set the library will not use them internally,\n * but the APIs will still be available externally.\n *\n * The parentheses around \"PNGAPI function_name\" in the following three\n * functions are necessary because they allow the macros to co-exist with\n * these (unused but exported) functions.\n */\n\n/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */\npng_uint_32 (PNGAPI\npng_get_uint_32)(png_const_bytep buf)\n{\n   png_uint_32 uval =\n       ((png_uint_32)(*(buf    )) << 24) +\n       ((png_uint_32)(*(buf + 1)) << 16) +\n       ((png_uint_32)(*(buf + 2)) <<  8) +\n       ((png_uint_32)(*(buf + 3))      ) ;\n\n   return uval;\n}\n\n/* Grab a signed 32-bit integer from a buffer in big-endian format.  The\n * data is stored in the PNG file in two's complement format and there\n * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore\n * the following code does a two's complement to native conversion.\n */\npng_int_32 (PNGAPI\npng_get_int_32)(png_const_bytep buf)\n{\n   png_uint_32 uval = png_get_uint_32(buf);\n   if ((uval & 0x80000000) == 0) /* non-negative */\n      return uval;\n\n   uval = (uval ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */\n   if ((uval & 0x80000000) == 0) /* no overflow */\n       return -(png_int_32)uval;\n   /* The following has to be safe; this function only gets called on PNG data\n    * and if we get here that data is invalid.  0 is the most safe value and\n    * if not then an attacker would surely just generate a PNG with 0 instead.\n    */\n   return 0;\n}\n\n/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */\npng_uint_16 (PNGAPI\npng_get_uint_16)(png_const_bytep buf)\n{\n   /* ANSI-C requires an int value to accomodate at least 16 bits so this\n    * works and allows the compiler not to worry about possible narrowing\n    * on 32-bit systems.  (Pre-ANSI systems did not make integers smaller\n    * than 16 bits either.)\n    */\n   unsigned int val =\n       ((unsigned int)(*buf) << 8) +\n       ((unsigned int)(*(buf + 1)));\n\n   return (png_uint_16)val;\n}\n\n#endif /* READ_INT_FUNCTIONS */\n\n/* Read and check the PNG file signature */\nvoid /* PRIVATE */\npng_read_sig(png_structrp png_ptr, png_inforp info_ptr)\n{\n   png_size_t num_checked, num_to_check;\n\n   /* Exit if the user application does not expect a signature. */\n   if (png_ptr->sig_bytes >= 8)\n      return;\n\n   num_checked = png_ptr->sig_bytes;\n   num_to_check = 8 - num_checked;\n\n#ifdef PNG_IO_STATE_SUPPORTED\n   png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;\n#endif\n\n   /* The signature must be serialized in a single I/O call. */\n   png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);\n   png_ptr->sig_bytes = 8;\n\n   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0)\n   {\n      if (num_checked < 4 &&\n          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))\n         png_error(png_ptr, \"Not a PNG file\");\n      else\n         png_error(png_ptr, \"PNG file corrupted by ASCII conversion\");\n   }\n   if (num_checked < 3)\n      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;\n}\n\n/* Read the chunk header (length + type name).\n * Put the type name into png_ptr->chunk_name, and return the length.\n */\npng_uint_32 /* PRIVATE */\npng_read_chunk_header(png_structrp png_ptr)\n{\n   png_byte buf[8];\n   png_uint_32 length;\n\n#ifdef PNG_IO_STATE_SUPPORTED\n   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;\n#endif\n\n   /* Read the length and the chunk name.\n    * This must be performed in a single I/O call.\n    */\n   png_read_data(png_ptr, buf, 8);\n   length = png_get_uint_31(png_ptr, buf);\n\n   /* Put the chunk name into png_ptr->chunk_name. */\n   png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);\n\n   png_debug2(0, \"Reading %lx chunk, length = %lu\",\n       (unsigned long)png_ptr->chunk_name, (unsigned long)length);\n\n   /* Reset the crc and run it over the chunk name. */\n   png_reset_crc(png_ptr);\n   png_calculate_crc(png_ptr, buf + 4, 4);\n\n   /* Check to see if chunk name is valid. */\n   png_check_chunk_name(png_ptr, png_ptr->chunk_name);\n\n#ifdef PNG_IO_STATE_SUPPORTED\n   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;\n#endif\n\n   return length;\n}\n\n/* Read data, and (optionally) run it through the CRC. */\nvoid /* PRIVATE */\npng_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length)\n{\n   if (png_ptr == NULL)\n      return;\n\n   png_read_data(png_ptr, buf, length);\n   png_calculate_crc(png_ptr, buf, length);\n}\n\n/* Optionally skip data and then check the CRC.  Depending on whether we\n * are reading an ancillary or critical chunk, and how the program has set\n * things up, we may calculate the CRC on the data and print a message.\n * Returns '1' if there was a CRC error, '0' otherwise.\n */\nint /* PRIVATE */\npng_crc_finish(png_structrp png_ptr, png_uint_32 skip)\n{\n   /* The size of the local buffer for inflate is a good guess as to a\n    * reasonable size to use for buffering reads from the application.\n    */\n   while (skip > 0)\n   {\n      png_uint_32 len;\n      png_byte tmpbuf[PNG_INFLATE_BUF_SIZE];\n\n      len = (sizeof tmpbuf);\n      if (len > skip)\n         len = skip;\n      skip -= len;\n\n      png_crc_read(png_ptr, tmpbuf, len);\n   }\n\n   if (png_crc_error(png_ptr) != 0)\n   {\n      if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ?\n          (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0 :\n          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE) != 0)\n      {\n         png_chunk_warning(png_ptr, \"CRC error\");\n      }\n\n      else\n         png_chunk_error(png_ptr, \"CRC error\");\n\n      return (1);\n   }\n\n   return (0);\n}\n\n/* Compare the CRC stored in the PNG file with that calculated by libpng from\n * the data it has read thus far.\n */\nint /* PRIVATE */\npng_crc_error(png_structrp png_ptr)\n{\n   png_byte crc_bytes[4];\n   png_uint_32 crc;\n   int need_crc = 1;\n\n   if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)\n   {\n      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==\n          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))\n         need_crc = 0;\n   }\n\n   else /* critical */\n   {\n      if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)\n         need_crc = 0;\n   }\n\n#ifdef PNG_IO_STATE_SUPPORTED\n   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;\n#endif\n\n   /* The chunk CRC must be serialized in a single I/O call. */\n   png_read_data(png_ptr, crc_bytes, 4);\n\n   if (need_crc != 0)\n   {\n      crc = png_get_uint_32(crc_bytes);\n      return ((int)(crc != png_ptr->crc));\n   }\n\n   else\n      return (0);\n}\n\n#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\\\n    defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\\\n    defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\\\n    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED)\n/* Manage the read buffer; this simply reallocates the buffer if it is not small\n * enough (or if it is not allocated).  The routine returns a pointer to the\n * buffer; if an error occurs and 'warn' is set the routine returns NULL, else\n * it will call png_error (via png_malloc) on failure.  (warn == 2 means\n * 'silent').\n */\nstatic png_bytep\npng_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn)\n{\n   png_bytep buffer = png_ptr->read_buffer;\n\n   if (buffer != NULL && new_size > png_ptr->read_buffer_size)\n   {\n      png_ptr->read_buffer = NULL;\n      png_ptr->read_buffer = NULL;\n      png_ptr->read_buffer_size = 0;\n      png_free(png_ptr, buffer);\n      buffer = NULL;\n   }\n\n   if (buffer == NULL)\n   {\n      buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size));\n\n      if (buffer != NULL)\n      {\n         png_ptr->read_buffer = buffer;\n         png_ptr->read_buffer_size = new_size;\n      }\n\n      else if (warn < 2) /* else silent */\n      {\n         if (warn != 0)\n             png_chunk_warning(png_ptr, \"insufficient memory to read chunk\");\n\n         else\n             png_chunk_error(png_ptr, \"insufficient memory to read chunk\");\n      }\n   }\n\n   return buffer;\n}\n#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */\n\n/* png_inflate_claim: claim the zstream for some nefarious purpose that involves\n * decompression.  Returns Z_OK on success, else a zlib error code.  It checks\n * the owner but, in final release builds, just issues a warning if some other\n * chunk apparently owns the stream.  Prior to release it does a png_error.\n */\nstatic int\npng_inflate_claim(png_structrp png_ptr, png_uint_32 owner)\n{\n   if (png_ptr->zowner != 0)\n   {\n      char msg[64];\n\n      PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner);\n      /* So the message that results is \"<chunk> using zstream\"; this is an\n       * internal error, but is very useful for debugging.  i18n requirements\n       * are minimal.\n       */\n      (void)png_safecat(msg, (sizeof msg), 4, \" using zstream\");\n#if PNG_RELEASE_BUILD\n      png_chunk_warning(png_ptr, msg);\n      png_ptr->zowner = 0;\n#else\n      png_chunk_error(png_ptr, msg);\n#endif\n   }\n\n   /* Implementation note: unlike 'png_deflate_claim' this internal function\n    * does not take the size of the data as an argument.  Some efficiency could\n    * be gained by using this when it is known *if* the zlib stream itself does\n    * not record the number; however, this is an illusion: the original writer\n    * of the PNG may have selected a lower window size, and we really must\n    * follow that because, for systems with with limited capabilities, we\n    * would otherwise reject the application's attempts to use a smaller window\n    * size (zlib doesn't have an interface to say \"this or lower\"!).\n    *\n    * inflateReset2 was added to zlib 1.2.4; before this the window could not be\n    * reset, therefore it is necessary to always allocate the maximum window\n    * size with earlier zlibs just in case later compressed chunks need it.\n    */\n   {\n      int ret; /* zlib return code */\n#if PNG_ZLIB_VERNUM >= 0x1240\n\n# if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW)\n      int window_bits;\n\n      if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) ==\n          PNG_OPTION_ON)\n      {\n         window_bits = 15;\n         png_ptr->zstream_start = 0; /* fixed window size */\n      }\n\n      else\n      {\n         window_bits = 0;\n         png_ptr->zstream_start = 1;\n      }\n# else\n#   define window_bits 0\n# endif\n#endif\n\n      /* Set this for safety, just in case the previous owner left pointers to\n       * memory allocations.\n       */\n      png_ptr->zstream.next_in = NULL;\n      png_ptr->zstream.avail_in = 0;\n      png_ptr->zstream.next_out = NULL;\n      png_ptr->zstream.avail_out = 0;\n\n      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)\n      {\n#if PNG_ZLIB_VERNUM < 0x1240\n         ret = inflateReset(&png_ptr->zstream);\n#else\n         ret = inflateReset2(&png_ptr->zstream, window_bits);\n#endif\n      }\n\n      else\n      {\n#if PNG_ZLIB_VERNUM < 0x1240\n         ret = inflateInit(&png_ptr->zstream);\n#else\n         ret = inflateInit2(&png_ptr->zstream, window_bits);\n#endif\n\n         if (ret == Z_OK)\n            png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;\n      }\n\n      if (ret == Z_OK)\n         png_ptr->zowner = owner;\n\n      else\n         png_zstream_error(png_ptr, ret);\n\n      return ret;\n   }\n\n#ifdef window_bits\n# undef window_bits\n#endif\n}\n\n#if PNG_ZLIB_VERNUM >= 0x1240\n/* Handle the start of the inflate stream if we called inflateInit2(strm,0);\n * in this case some zlib versions skip validation of the CINFO field and, in\n * certain circumstances, libpng may end up displaying an invalid image, in\n * contrast to implementations that call zlib in the normal way (e.g. libpng\n * 1.5).\n */\nint /* PRIVATE */\npng_zlib_inflate(png_structrp png_ptr, int flush)\n{\n   if (png_ptr->zstream_start && png_ptr->zstream.avail_in > 0)\n   {\n      if ((*png_ptr->zstream.next_in >> 4) > 7)\n      {\n         png_ptr->zstream.msg = \"invalid window size (libpng)\";\n         return Z_DATA_ERROR;\n      }\n\n      png_ptr->zstream_start = 0;\n   }\n\n   return inflate(&png_ptr->zstream, flush);\n}\n#endif /* Zlib >= 1.2.4 */\n\n#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED\n/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to\n * allow the caller to do multiple calls if required.  If the 'finish' flag is\n * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must\n * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and\n * Z_OK or Z_STREAM_END will be returned on success.\n *\n * The input and output sizes are updated to the actual amounts of data consumed\n * or written, not the amount available (as in a z_stream).  The data pointers\n * are not changed, so the next input is (data+input_size) and the next\n * available output is (output+output_size).\n */\nstatic int\npng_inflate(png_structrp png_ptr, png_uint_32 owner, int finish,\n    /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr,\n    /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr)\n{\n   if (png_ptr->zowner == owner) /* Else not claimed */\n   {\n      int ret;\n      png_alloc_size_t avail_out = *output_size_ptr;\n      png_uint_32 avail_in = *input_size_ptr;\n\n      /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it\n       * can't even necessarily handle 65536 bytes) because the type uInt is\n       * \"16 bits or more\".  Consequently it is necessary to chunk the input to\n       * zlib.  This code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the\n       * maximum value that can be stored in a uInt.)  It is possible to set\n       * ZLIB_IO_MAX to a lower value in pngpriv.h and this may sometimes have\n       * a performance advantage, because it reduces the amount of data accessed\n       * at each step and that may give the OS more time to page it in.\n       */\n      png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input);\n      /* avail_in and avail_out are set below from 'size' */\n      png_ptr->zstream.avail_in = 0;\n      png_ptr->zstream.avail_out = 0;\n\n      /* Read directly into the output if it is available (this is set to\n       * a local buffer below if output is NULL).\n       */\n      if (output != NULL)\n         png_ptr->zstream.next_out = output;\n\n      do\n      {\n         uInt avail;\n         Byte local_buffer[PNG_INFLATE_BUF_SIZE];\n\n         /* zlib INPUT BUFFER */\n         /* The setting of 'avail_in' used to be outside the loop; by setting it\n          * inside it is possible to chunk the input to zlib and simply rely on\n          * zlib to advance the 'next_in' pointer.  This allows arbitrary\n          * amounts of data to be passed through zlib at the unavoidable cost of\n          * requiring a window save (memcpy of up to 32768 output bytes)\n          * every ZLIB_IO_MAX input bytes.\n          */\n         avail_in += png_ptr->zstream.avail_in; /* not consumed last time */\n\n         avail = ZLIB_IO_MAX;\n\n         if (avail_in < avail)\n            avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */\n\n         avail_in -= avail;\n         png_ptr->zstream.avail_in = avail;\n\n         /* zlib OUTPUT BUFFER */\n         avail_out += png_ptr->zstream.avail_out; /* not written last time */\n\n         avail = ZLIB_IO_MAX; /* maximum zlib can process */\n\n         if (output == NULL)\n         {\n            /* Reset the output buffer each time round if output is NULL and\n             * make available the full buffer, up to 'remaining_space'\n             */\n            png_ptr->zstream.next_out = local_buffer;\n            if ((sizeof local_buffer) < avail)\n               avail = (sizeof local_buffer);\n         }\n\n         if (avail_out < avail)\n            avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */\n\n         png_ptr->zstream.avail_out = avail;\n         avail_out -= avail;\n\n         /* zlib inflate call */\n         /* In fact 'avail_out' may be 0 at this point, that happens at the end\n          * of the read when the final LZ end code was not passed at the end of\n          * the previous chunk of input data.  Tell zlib if we have reached the\n          * end of the output buffer.\n          */\n         ret = PNG_INFLATE(png_ptr, avail_out > 0 ? Z_NO_FLUSH :\n             (finish ? Z_FINISH : Z_SYNC_FLUSH));\n      } while (ret == Z_OK);\n\n      /* For safety kill the local buffer pointer now */\n      if (output == NULL)\n         png_ptr->zstream.next_out = NULL;\n\n      /* Claw back the 'size' and 'remaining_space' byte counts. */\n      avail_in += png_ptr->zstream.avail_in;\n      avail_out += png_ptr->zstream.avail_out;\n\n      /* Update the input and output sizes; the updated values are the amount\n       * consumed or written, effectively the inverse of what zlib uses.\n       */\n      if (avail_out > 0)\n         *output_size_ptr -= avail_out;\n\n      if (avail_in > 0)\n         *input_size_ptr -= avail_in;\n\n      /* Ensure png_ptr->zstream.msg is set (even in the success case!) */\n      png_zstream_error(png_ptr, ret);\n      return ret;\n   }\n\n   else\n   {\n      /* This is a bad internal error.  The recovery assigns to the zstream msg\n       * pointer, which is not owned by the caller, but this is safe; it's only\n       * used on errors!\n       */\n      png_ptr->zstream.msg = PNGZ_MSG_CAST(\"zstream unclaimed\");\n      return Z_STREAM_ERROR;\n   }\n}\n\n/*\n * Decompress trailing data in a chunk.  The assumption is that read_buffer\n * points at an allocated area holding the contents of a chunk with a\n * trailing compressed part.  What we get back is an allocated area\n * holding the original prefix part and an uncompressed version of the\n * trailing part (the malloc area passed in is freed).\n */\nstatic int\npng_decompress_chunk(png_structrp png_ptr,\n   png_uint_32 chunklength, png_uint_32 prefix_size,\n   png_alloc_size_t *newlength /* must be initialized to the maximum! */,\n   int terminate /*add a '\\0' to the end of the uncompressed data*/)\n{\n   /* TODO: implement different limits for different types of chunk.\n    *\n    * The caller supplies *newlength set to the maximum length of the\n    * uncompressed data, but this routine allocates space for the prefix and\n    * maybe a '\\0' terminator too.  We have to assume that 'prefix_size' is\n    * limited only by the maximum chunk size.\n    */\n   png_alloc_size_t limit = PNG_SIZE_MAX;\n\n# ifdef PNG_SET_USER_LIMITS_SUPPORTED\n   if (png_ptr->user_chunk_malloc_max > 0 &&\n       png_ptr->user_chunk_malloc_max < limit)\n      limit = png_ptr->user_chunk_malloc_max;\n# elif PNG_USER_CHUNK_MALLOC_MAX > 0\n   if (PNG_USER_CHUNK_MALLOC_MAX < limit)\n      limit = PNG_USER_CHUNK_MALLOC_MAX;\n# endif\n\n   if (limit >= prefix_size + (terminate != 0))\n   {\n      int ret;\n\n      limit -= prefix_size + (terminate != 0);\n\n      if (limit < *newlength)\n         *newlength = limit;\n\n      /* Now try to claim the stream. */\n      ret = png_inflate_claim(png_ptr, png_ptr->chunk_name);\n\n      if (ret == Z_OK)\n      {\n         png_uint_32 lzsize = chunklength - prefix_size;\n\n         ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,\n            /* input: */ png_ptr->read_buffer + prefix_size, &lzsize,\n            /* output: */ NULL, newlength);\n\n         if (ret == Z_STREAM_END)\n         {\n            /* Use 'inflateReset' here, not 'inflateReset2' because this\n             * preserves the previously decided window size (otherwise it would\n             * be necessary to store the previous window size.)  In practice\n             * this doesn't matter anyway, because png_inflate will call inflate\n             * with Z_FINISH in almost all cases, so the window will not be\n             * maintained.\n             */\n            if (inflateReset(&png_ptr->zstream) == Z_OK)\n            {\n               /* Because of the limit checks above we know that the new,\n                * expanded, size will fit in a size_t (let alone an\n                * png_alloc_size_t).  Use png_malloc_base here to avoid an\n                * extra OOM message.\n                */\n               png_alloc_size_t new_size = *newlength;\n               png_alloc_size_t buffer_size = prefix_size + new_size +\n                  (terminate != 0);\n               png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr,\n                  buffer_size));\n\n               if (text != NULL)\n               {\n                  ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,\n                     png_ptr->read_buffer + prefix_size, &lzsize,\n                     text + prefix_size, newlength);\n\n                  if (ret == Z_STREAM_END)\n                  {\n                     if (new_size == *newlength)\n                     {\n                        if (terminate != 0)\n                           text[prefix_size + *newlength] = 0;\n\n                        if (prefix_size > 0)\n                           memcpy(text, png_ptr->read_buffer, prefix_size);\n\n                        {\n                           png_bytep old_ptr = png_ptr->read_buffer;\n\n                           png_ptr->read_buffer = text;\n                           png_ptr->read_buffer_size = buffer_size;\n                           text = old_ptr; /* freed below */\n                        }\n                     }\n\n                     else\n                     {\n                        /* The size changed on the second read, there can be no\n                         * guarantee that anything is correct at this point.\n                         * The 'msg' pointer has been set to \"unexpected end of\n                         * LZ stream\", which is fine, but return an error code\n                         * that the caller won't accept.\n                         */\n                        ret = PNG_UNEXPECTED_ZLIB_RETURN;\n                     }\n                  }\n\n                  else if (ret == Z_OK)\n                     ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */\n\n                  /* Free the text pointer (this is the old read_buffer on\n                   * success)\n                   */\n                  png_free(png_ptr, text);\n\n                  /* This really is very benign, but it's still an error because\n                   * the extra space may otherwise be used as a Trojan Horse.\n                   */\n                  if (ret == Z_STREAM_END &&\n                     chunklength - prefix_size != lzsize)\n                     png_chunk_benign_error(png_ptr, \"extra compressed data\");\n               }\n\n               else\n               {\n                  /* Out of memory allocating the buffer */\n                  ret = Z_MEM_ERROR;\n                  png_zstream_error(png_ptr, Z_MEM_ERROR);\n               }\n            }\n\n            else\n            {\n               /* inflateReset failed, store the error message */\n               png_zstream_error(png_ptr, ret);\n\n               if (ret == Z_STREAM_END)\n                  ret = PNG_UNEXPECTED_ZLIB_RETURN;\n            }\n         }\n\n         else if (ret == Z_OK)\n            ret = PNG_UNEXPECTED_ZLIB_RETURN;\n\n         /* Release the claimed stream */\n         png_ptr->zowner = 0;\n      }\n\n      else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */\n         ret = PNG_UNEXPECTED_ZLIB_RETURN;\n\n      return ret;\n   }\n\n   else\n   {\n      /* Application/configuration limits exceeded */\n      png_zstream_error(png_ptr, Z_MEM_ERROR);\n      return Z_MEM_ERROR;\n   }\n}\n#endif /* READ_COMPRESSED_TEXT */\n\n#ifdef PNG_READ_iCCP_SUPPORTED\n/* Perform a partial read and decompress, producing 'avail_out' bytes and\n * reading from the current chunk as required.\n */\nstatic int\npng_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,\n   png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size,\n   int finish)\n{\n   if (png_ptr->zowner == png_ptr->chunk_name)\n   {\n      int ret;\n\n      /* next_in and avail_in must have been initialized by the caller. */\n      png_ptr->zstream.next_out = next_out;\n      png_ptr->zstream.avail_out = 0; /* set in the loop */\n\n      do\n      {\n         if (png_ptr->zstream.avail_in == 0)\n         {\n            if (read_size > *chunk_bytes)\n               read_size = (uInt)*chunk_bytes;\n            *chunk_bytes -= read_size;\n\n            if (read_size > 0)\n               png_crc_read(png_ptr, read_buffer, read_size);\n\n            png_ptr->zstream.next_in = read_buffer;\n            png_ptr->zstream.avail_in = read_size;\n         }\n\n         if (png_ptr->zstream.avail_out == 0)\n         {\n            uInt avail = ZLIB_IO_MAX;\n            if (avail > *out_size)\n               avail = (uInt)*out_size;\n            *out_size -= avail;\n\n            png_ptr->zstream.avail_out = avail;\n         }\n\n         /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all\n          * the available output is produced; this allows reading of truncated\n          * streams.\n          */\n         ret = PNG_INFLATE(png_ptr,\n            *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));\n      }\n      while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0));\n\n      *out_size += png_ptr->zstream.avail_out;\n      png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */\n\n      /* Ensure the error message pointer is always set: */\n      png_zstream_error(png_ptr, ret);\n      return ret;\n   }\n\n   else\n   {\n      png_ptr->zstream.msg = PNGZ_MSG_CAST(\"zstream unclaimed\");\n      return Z_STREAM_ERROR;\n   }\n}\n#endif\n\n/* Read and check the IDHR chunk */\n\nvoid /* PRIVATE */\npng_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_byte buf[13];\n   png_uint_32 width, height;\n   int bit_depth, color_type, compression_type, filter_type;\n   int interlace_type;\n\n   png_debug(1, \"in png_handle_IHDR\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) != 0)\n      png_chunk_error(png_ptr, \"out of place\");\n\n   /* Check the length */\n   if (length != 13)\n      png_chunk_error(png_ptr, \"invalid\");\n\n   png_ptr->mode |= PNG_HAVE_IHDR;\n\n   png_crc_read(png_ptr, buf, 13);\n   png_crc_finish(png_ptr, 0);\n\n   width = png_get_uint_31(png_ptr, buf);\n   height = png_get_uint_31(png_ptr, buf + 4);\n   bit_depth = buf[8];\n   color_type = buf[9];\n   compression_type = buf[10];\n   filter_type = buf[11];\n   interlace_type = buf[12];\n\n   /* Set internal variables */\n   png_ptr->width = width;\n   png_ptr->height = height;\n   png_ptr->bit_depth = (png_byte)bit_depth;\n   png_ptr->interlaced = (png_byte)interlace_type;\n   png_ptr->color_type = (png_byte)color_type;\n#ifdef PNG_MNG_FEATURES_SUPPORTED\n   png_ptr->filter_type = (png_byte)filter_type;\n#endif\n   png_ptr->compression_type = (png_byte)compression_type;\n\n   /* Find number of channels */\n   switch (png_ptr->color_type)\n   {\n      default: /* invalid, png_set_IHDR calls png_error */\n      case PNG_COLOR_TYPE_GRAY:\n      case PNG_COLOR_TYPE_PALETTE:\n         png_ptr->channels = 1;\n         break;\n\n      case PNG_COLOR_TYPE_RGB:\n         png_ptr->channels = 3;\n         break;\n\n      case PNG_COLOR_TYPE_GRAY_ALPHA:\n         png_ptr->channels = 2;\n         break;\n\n      case PNG_COLOR_TYPE_RGB_ALPHA:\n         png_ptr->channels = 4;\n         break;\n   }\n\n   /* Set up other useful info */\n   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->channels);\n   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);\n   png_debug1(3, \"bit_depth = %d\", png_ptr->bit_depth);\n   png_debug1(3, \"channels = %d\", png_ptr->channels);\n   png_debug1(3, \"rowbytes = %lu\", (unsigned long)png_ptr->rowbytes);\n   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,\n       color_type, interlace_type, compression_type, filter_type);\n}\n\n/* Read and check the palette */\nvoid /* PRIVATE */\npng_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_color palette[PNG_MAX_PALETTE_LENGTH];\n   int max_palette_length, num, i;\n#ifdef PNG_POINTER_INDEXING_SUPPORTED\n   png_colorp pal_ptr;\n#endif\n\n   png_debug(1, \"in png_handle_PLTE\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   /* Moved to before the 'after IDAT' check below because otherwise duplicate\n    * PLTE chunks are potentially ignored (the spec says there shall not be more\n    * than one PLTE, the error is not treated as benign, so this check trumps\n    * the requirement that PLTE appears before IDAT.)\n    */\n   else if ((png_ptr->mode & PNG_HAVE_PLTE) != 0)\n      png_chunk_error(png_ptr, \"duplicate\");\n\n   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)\n   {\n      /* This is benign because the non-benign error happened before, when an\n       * IDAT was encountered in a color-mapped image with no PLTE.\n       */\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of place\");\n      return;\n   }\n\n   png_ptr->mode |= PNG_HAVE_PLTE;\n\n   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"ignored in grayscale PNG\");\n      return;\n   }\n\n#ifndef PNG_READ_OPT_PLTE_SUPPORTED\n   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)\n   {\n      png_crc_finish(png_ptr, length);\n      return;\n   }\n#endif\n\n   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)\n   {\n      png_crc_finish(png_ptr, length);\n\n      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)\n         png_chunk_benign_error(png_ptr, \"invalid\");\n\n      else\n         png_chunk_error(png_ptr, \"invalid\");\n\n      return;\n   }\n\n   /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */\n   num = (int)length / 3;\n\n   /* If the palette has 256 or fewer entries but is too large for the bit\n    * depth, we don't issue an error, to preserve the behavior of previous\n    * libpng versions. We silently truncate the unused extra palette entries\n    * here.\n    */\n   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n      max_palette_length = (1 << png_ptr->bit_depth);\n   else\n      max_palette_length = PNG_MAX_PALETTE_LENGTH;\n\n   if (num > max_palette_length)\n      num = max_palette_length;\n\n#ifdef PNG_POINTER_INDEXING_SUPPORTED\n   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)\n   {\n      png_byte buf[3];\n\n      png_crc_read(png_ptr, buf, 3);\n      pal_ptr->red = buf[0];\n      pal_ptr->green = buf[1];\n      pal_ptr->blue = buf[2];\n   }\n#else\n   for (i = 0; i < num; i++)\n   {\n      png_byte buf[3];\n\n      png_crc_read(png_ptr, buf, 3);\n      /* Don't depend upon png_color being any order */\n      palette[i].red = buf[0];\n      palette[i].green = buf[1];\n      palette[i].blue = buf[2];\n   }\n#endif\n\n   /* If we actually need the PLTE chunk (ie for a paletted image), we do\n    * whatever the normal CRC configuration tells us.  However, if we\n    * have an RGB image, the PLTE can be considered ancillary, so\n    * we will act as though it is.\n    */\n#ifndef PNG_READ_OPT_PLTE_SUPPORTED\n   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n#endif\n   {\n      png_crc_finish(png_ptr, (int) length - num * 3);\n   }\n\n#ifndef PNG_READ_OPT_PLTE_SUPPORTED\n   else if (png_crc_error(png_ptr) != 0)  /* Only if we have a CRC error */\n   {\n      /* If we don't want to use the data from an ancillary chunk,\n       * we have two options: an error abort, or a warning and we\n       * ignore the data in this chunk (which should be OK, since\n       * it's considered ancillary for a RGB or RGBA image).\n       *\n       * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the\n       * chunk type to determine whether to check the ancillary or the critical\n       * flags.\n       */\n      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE) == 0)\n      {\n         if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) != 0)\n            return;\n\n         else\n            png_chunk_error(png_ptr, \"CRC error\");\n      }\n\n      /* Otherwise, we (optionally) emit a warning and use the chunk. */\n      else if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0)\n         png_chunk_warning(png_ptr, \"CRC error\");\n   }\n#endif\n\n   /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its\n    * own copy of the palette.  This has the side effect that when png_start_row\n    * is called (this happens after any call to png_read_update_info) the\n    * info_ptr palette gets changed.  This is extremely unexpected and\n    * confusing.\n    *\n    * Fix this by not sharing the palette in this way.\n    */\n   png_set_PLTE(png_ptr, info_ptr, palette, num);\n\n   /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before\n    * IDAT.  Prior to 1.6.0 this was not checked; instead the code merely\n    * checked the apparent validity of a tRNS chunk inserted before PLTE on a\n    * palette PNG.  1.6.0 attempts to rigorously follow the standard and\n    * therefore does a benign error if the erroneous condition is detected *and*\n    * cancels the tRNS if the benign error returns.  The alternative is to\n    * amend the standard since it would be rather hypocritical of the standards\n    * maintainers to ignore it.\n    */\n#ifdef PNG_READ_tRNS_SUPPORTED\n   if (png_ptr->num_trans > 0 ||\n       (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0))\n   {\n      /* Cancel this because otherwise it would be used if the transforms\n       * require it.  Don't cancel the 'valid' flag because this would prevent\n       * detection of duplicate chunks.\n       */\n      png_ptr->num_trans = 0;\n\n      if (info_ptr != NULL)\n         info_ptr->num_trans = 0;\n\n      png_chunk_benign_error(png_ptr, \"tRNS must be after\");\n   }\n#endif\n\n#ifdef PNG_READ_hIST_SUPPORTED\n   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0)\n      png_chunk_benign_error(png_ptr, \"hIST must be after\");\n#endif\n\n#ifdef PNG_READ_bKGD_SUPPORTED\n   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0)\n      png_chunk_benign_error(png_ptr, \"bKGD must be after\");\n#endif\n}\n\nvoid /* PRIVATE */\npng_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_debug(1, \"in png_handle_IEND\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0 ||\n       (png_ptr->mode & PNG_HAVE_IDAT) == 0)\n      png_chunk_error(png_ptr, \"out of place\");\n\n   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);\n\n   png_crc_finish(png_ptr, length);\n\n   if (length != 0)\n      png_chunk_benign_error(png_ptr, \"invalid\");\n\n   PNG_UNUSED(info_ptr)\n}\n\n#ifdef PNG_READ_gAMA_SUPPORTED\nvoid /* PRIVATE */\npng_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_fixed_point igamma;\n   png_byte buf[4];\n\n   png_debug(1, \"in png_handle_gAMA\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of place\");\n      return;\n   }\n\n   if (length != 4)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"invalid\");\n      return;\n   }\n\n   png_crc_read(png_ptr, buf, 4);\n\n   if (png_crc_finish(png_ptr, 0) != 0)\n      return;\n\n   igamma = png_get_fixed_point(NULL, buf);\n\n   png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma);\n   png_colorspace_sync(png_ptr, info_ptr);\n}\n#endif\n\n#ifdef PNG_READ_sBIT_SUPPORTED\nvoid /* PRIVATE */\npng_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   unsigned int truelen, i;\n   png_byte sample_depth;\n   png_byte buf[4];\n\n   png_debug(1, \"in png_handle_sBIT\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of place\");\n      return;\n   }\n\n   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"duplicate\");\n      return;\n   }\n\n   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n   {\n      truelen = 3;\n      sample_depth = 8;\n   }\n\n   else\n   {\n      truelen = png_ptr->channels;\n      sample_depth = png_ptr->bit_depth;\n   }\n\n   if (length != truelen || length > 4)\n   {\n      png_chunk_benign_error(png_ptr, \"invalid\");\n      png_crc_finish(png_ptr, length);\n      return;\n   }\n\n   buf[0] = buf[1] = buf[2] = buf[3] = sample_depth;\n   png_crc_read(png_ptr, buf, truelen);\n\n   if (png_crc_finish(png_ptr, 0) != 0)\n      return;\n\n   for (i=0; i<truelen; ++i)\n   {\n      if (buf[i] == 0 || buf[i] > sample_depth)\n      {\n         png_chunk_benign_error(png_ptr, \"invalid\");\n         return;\n      }\n   }\n\n   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)\n   {\n      png_ptr->sig_bit.red = buf[0];\n      png_ptr->sig_bit.green = buf[1];\n      png_ptr->sig_bit.blue = buf[2];\n      png_ptr->sig_bit.alpha = buf[3];\n   }\n\n   else\n   {\n      png_ptr->sig_bit.gray = buf[0];\n      png_ptr->sig_bit.red = buf[0];\n      png_ptr->sig_bit.green = buf[0];\n      png_ptr->sig_bit.blue = buf[0];\n      png_ptr->sig_bit.alpha = buf[1];\n   }\n\n   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));\n}\n#endif\n\n#ifdef PNG_READ_cHRM_SUPPORTED\nvoid /* PRIVATE */\npng_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_byte buf[32];\n   png_xy xy;\n\n   png_debug(1, \"in png_handle_cHRM\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of place\");\n      return;\n   }\n\n   if (length != 32)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"invalid\");\n      return;\n   }\n\n   png_crc_read(png_ptr, buf, 32);\n\n   if (png_crc_finish(png_ptr, 0) != 0)\n      return;\n\n   xy.whitex = png_get_fixed_point(NULL, buf);\n   xy.whitey = png_get_fixed_point(NULL, buf + 4);\n   xy.redx   = png_get_fixed_point(NULL, buf + 8);\n   xy.redy   = png_get_fixed_point(NULL, buf + 12);\n   xy.greenx = png_get_fixed_point(NULL, buf + 16);\n   xy.greeny = png_get_fixed_point(NULL, buf + 20);\n   xy.bluex  = png_get_fixed_point(NULL, buf + 24);\n   xy.bluey  = png_get_fixed_point(NULL, buf + 28);\n\n   if (xy.whitex == PNG_FIXED_ERROR ||\n       xy.whitey == PNG_FIXED_ERROR ||\n       xy.redx   == PNG_FIXED_ERROR ||\n       xy.redy   == PNG_FIXED_ERROR ||\n       xy.greenx == PNG_FIXED_ERROR ||\n       xy.greeny == PNG_FIXED_ERROR ||\n       xy.bluex  == PNG_FIXED_ERROR ||\n       xy.bluey  == PNG_FIXED_ERROR)\n   {\n      png_chunk_benign_error(png_ptr, \"invalid values\");\n      return;\n   }\n\n   /* If a colorspace error has already been output skip this chunk */\n   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)\n      return;\n\n   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0)\n   {\n      png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;\n      png_colorspace_sync(png_ptr, info_ptr);\n      png_chunk_benign_error(png_ptr, \"duplicate\");\n      return;\n   }\n\n   png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;\n   (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy,\n      1/*prefer cHRM values*/);\n   png_colorspace_sync(png_ptr, info_ptr);\n}\n#endif\n\n#ifdef PNG_READ_sRGB_SUPPORTED\nvoid /* PRIVATE */\npng_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_byte intent;\n\n   png_debug(1, \"in png_handle_sRGB\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of place\");\n      return;\n   }\n\n   if (length != 1)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"invalid\");\n      return;\n   }\n\n   png_crc_read(png_ptr, &intent, 1);\n\n   if (png_crc_finish(png_ptr, 0) != 0)\n      return;\n\n   /* If a colorspace error has already been output skip this chunk */\n   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)\n      return;\n\n   /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect\n    * this.\n    */\n   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) != 0)\n   {\n      png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;\n      png_colorspace_sync(png_ptr, info_ptr);\n      png_chunk_benign_error(png_ptr, \"too many profiles\");\n      return;\n   }\n\n   (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent);\n   png_colorspace_sync(png_ptr, info_ptr);\n}\n#endif /* READ_sRGB */\n\n#ifdef PNG_READ_iCCP_SUPPORTED\nvoid /* PRIVATE */\npng_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n/* Note: this does not properly handle profiles that are > 64K under DOS */\n{\n   png_const_charp errmsg = NULL; /* error message output, or no error */\n   int finished = 0; /* crc checked */\n\n   png_debug(1, \"in png_handle_iCCP\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of place\");\n      return;\n   }\n\n   /* Consistent with all the above colorspace handling an obviously *invalid*\n    * chunk is just ignored, so does not invalidate the color space.  An\n    * alternative is to set the 'invalid' flags at the start of this routine\n    * and only clear them in they were not set before and all the tests pass.\n    * The minimum 'deflate' stream is assumed to be just the 2 byte header and\n    * 4 byte checksum.  The keyword must be at least one character and there is\n    * a terminator (0) byte and the compression method.\n    */\n   if (length < 9)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"too short\");\n      return;\n   }\n\n   /* If a colorspace error has already been output skip this chunk */\n   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      return;\n   }\n\n   /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect\n    * this.\n    */\n   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0)\n   {\n      uInt read_length, keyword_length;\n      char keyword[81];\n\n      /* Find the keyword; the keyword plus separator and compression method\n       * bytes can be at most 81 characters long.\n       */\n      read_length = 81; /* maximum */\n      if (read_length > length)\n         read_length = (uInt)length;\n\n      png_crc_read(png_ptr, (png_bytep)keyword, read_length);\n      length -= read_length;\n\n      keyword_length = 0;\n      while (keyword_length < 80 && keyword_length < read_length &&\n         keyword[keyword_length] != 0)\n         ++keyword_length;\n\n      /* TODO: make the keyword checking common */\n      if (keyword_length >= 1 && keyword_length <= 79)\n      {\n         /* We only understand '0' compression - deflate - so if we get a\n          * different value we can't safely decode the chunk.\n          */\n         if (keyword_length+1 < read_length &&\n            keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE)\n         {\n            read_length -= keyword_length+2;\n\n            if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK)\n            {\n               Byte profile_header[132];\n               Byte local_buffer[PNG_INFLATE_BUF_SIZE];\n               png_alloc_size_t size = (sizeof profile_header);\n\n               png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2);\n               png_ptr->zstream.avail_in = read_length;\n               (void)png_inflate_read(png_ptr, local_buffer,\n                  (sizeof local_buffer), &length, profile_header, &size,\n                  0/*finish: don't, because the output is too small*/);\n\n               if (size == 0)\n               {\n                  /* We have the ICC profile header; do the basic header checks.\n                   */\n                  const png_uint_32 profile_length =\n                     png_get_uint_32(profile_header);\n\n                  if (png_icc_check_length(png_ptr, &png_ptr->colorspace,\n                     keyword, profile_length) != 0)\n                  {\n                     /* The length is apparently ok, so we can check the 132\n                      * byte header.\n                      */\n                     if (png_icc_check_header(png_ptr, &png_ptr->colorspace,\n                        keyword, profile_length, profile_header,\n                        png_ptr->color_type) != 0)\n                     {\n                        /* Now read the tag table; a variable size buffer is\n                         * needed at this point, allocate one for the whole\n                         * profile.  The header check has already validated\n                         * that none of these stuff will overflow.\n                         */\n                        const png_uint_32 tag_count = png_get_uint_32(\n                           profile_header+128);\n                        png_bytep profile = png_read_buffer(png_ptr,\n                           profile_length, 2/*silent*/);\n\n                        if (profile != NULL)\n                        {\n                           memcpy(profile, profile_header,\n                              (sizeof profile_header));\n\n                           size = 12 * tag_count;\n\n                           (void)png_inflate_read(png_ptr, local_buffer,\n                              (sizeof local_buffer), &length,\n                              profile + (sizeof profile_header), &size, 0);\n\n                           /* Still expect a buffer error because we expect\n                            * there to be some tag data!\n                            */\n                           if (size == 0)\n                           {\n                              if (png_icc_check_tag_table(png_ptr,\n                                 &png_ptr->colorspace, keyword, profile_length,\n                                 profile) != 0)\n                              {\n                                 /* The profile has been validated for basic\n                                  * security issues, so read the whole thing in.\n                                  */\n                                 size = profile_length - (sizeof profile_header)\n                                    - 12 * tag_count;\n\n                                 (void)png_inflate_read(png_ptr, local_buffer,\n                                    (sizeof local_buffer), &length,\n                                    profile + (sizeof profile_header) +\n                                    12 * tag_count, &size, 1/*finish*/);\n\n                                 if (length > 0 && !(png_ptr->flags &\n                                       PNG_FLAG_BENIGN_ERRORS_WARN))\n                                    errmsg = \"extra compressed data\";\n\n                                 /* But otherwise allow extra data: */\n                                 else if (size == 0)\n                                 {\n                                    if (length > 0)\n                                    {\n                                       /* This can be handled completely, so\n                                        * keep going.\n                                        */\n                                       png_chunk_warning(png_ptr,\n                                          \"extra compressed data\");\n                                    }\n\n                                    png_crc_finish(png_ptr, length);\n                                    finished = 1;\n\n#                                   ifdef PNG_sRGB_SUPPORTED\n                                    /* Check for a match against sRGB */\n                                    png_icc_set_sRGB(png_ptr,\n                                       &png_ptr->colorspace, profile,\n                                       png_ptr->zstream.adler);\n#                                   endif\n\n                                    /* Steal the profile for info_ptr. */\n                                    if (info_ptr != NULL)\n                                    {\n                                       png_free_data(png_ptr, info_ptr,\n                                          PNG_FREE_ICCP, 0);\n\n                                       info_ptr->iccp_name = png_voidcast(char*,\n                                          png_malloc_base(png_ptr,\n                                          keyword_length+1));\n                                       if (info_ptr->iccp_name != NULL)\n                                       {\n                                          memcpy(info_ptr->iccp_name, keyword,\n                                             keyword_length+1);\n                                          info_ptr->iccp_proflen =\n                                             profile_length;\n                                          info_ptr->iccp_profile = profile;\n                                          png_ptr->read_buffer = NULL; /*steal*/\n                                          info_ptr->free_me |= PNG_FREE_ICCP;\n                                          info_ptr->valid |= PNG_INFO_iCCP;\n                                       }\n\n                                       else\n                                       {\n                                          png_ptr->colorspace.flags |=\n                                             PNG_COLORSPACE_INVALID;\n                                          errmsg = \"out of memory\";\n                                       }\n                                    }\n\n                                    /* else the profile remains in the read\n                                     * buffer which gets reused for subsequent\n                                     * chunks.\n                                     */\n\n                                    if (info_ptr != NULL)\n                                       png_colorspace_sync(png_ptr, info_ptr);\n\n                                    if (errmsg == NULL)\n                                    {\n                                       png_ptr->zowner = 0;\n                                       return;\n                                    }\n                                 }\n\n                                 else if (size > 0)\n                                    errmsg = \"truncated\";\n\n#ifndef __COVERITY__\n                                 else\n                                    errmsg = png_ptr->zstream.msg;\n#endif\n                              }\n\n                              /* else png_icc_check_tag_table output an error */\n                           }\n\n                           else /* profile truncated */\n                              errmsg = png_ptr->zstream.msg;\n                        }\n\n                        else\n                           errmsg = \"out of memory\";\n                     }\n\n                     /* else png_icc_check_header output an error */\n                  }\n\n                  /* else png_icc_check_length output an error */\n               }\n\n               else /* profile truncated */\n                  errmsg = png_ptr->zstream.msg;\n\n               /* Release the stream */\n               png_ptr->zowner = 0;\n            }\n\n            else /* png_inflate_claim failed */\n               errmsg = png_ptr->zstream.msg;\n         }\n\n         else\n            errmsg = \"bad compression method\"; /* or missing */\n      }\n\n      else\n         errmsg = \"bad keyword\";\n   }\n\n   else\n      errmsg = \"too many profiles\";\n\n   /* Failure: the reason is in 'errmsg' */\n   if (finished == 0)\n      png_crc_finish(png_ptr, length);\n\n   png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;\n   png_colorspace_sync(png_ptr, info_ptr);\n   if (errmsg != NULL) /* else already output */\n      png_chunk_benign_error(png_ptr, errmsg);\n}\n#endif /* READ_iCCP */\n\n#ifdef PNG_READ_sPLT_SUPPORTED\nvoid /* PRIVATE */\npng_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n/* Note: this does not properly handle chunks that are > 64K under DOS */\n{\n   png_bytep entry_start, buffer;\n   png_sPLT_t new_palette;\n   png_sPLT_entryp pp;\n   png_uint_32 data_length;\n   int entry_size, i;\n   png_uint_32 skip = 0;\n   png_uint_32 dl;\n   png_size_t max_dl;\n\n   png_debug(1, \"in png_handle_sPLT\");\n\n#ifdef PNG_USER_LIMITS_SUPPORTED\n   if (png_ptr->user_chunk_cache_max != 0)\n   {\n      if (png_ptr->user_chunk_cache_max == 1)\n      {\n         png_crc_finish(png_ptr, length);\n         return;\n      }\n\n      if (--png_ptr->user_chunk_cache_max == 1)\n      {\n         png_warning(png_ptr, \"No space in chunk cache for sPLT\");\n         png_crc_finish(png_ptr, length);\n         return;\n      }\n   }\n#endif\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of place\");\n      return;\n   }\n\n#ifdef PNG_MAX_MALLOC_64K\n   if (length > 65535U)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"too large to fit in memory\");\n      return;\n   }\n#endif\n\n   buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);\n   if (buffer == NULL)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of memory\");\n      return;\n   }\n\n\n   /* WARNING: this may break if size_t is less than 32 bits; it is assumed\n    * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a\n    * potential breakage point if the types in pngconf.h aren't exactly right.\n    */\n   png_crc_read(png_ptr, buffer, length);\n\n   if (png_crc_finish(png_ptr, skip) != 0)\n      return;\n\n   buffer[length] = 0;\n\n   for (entry_start = buffer; *entry_start; entry_start++)\n      /* Empty loop to find end of name */ ;\n\n   ++entry_start;\n\n   /* A sample depth should follow the separator, and we should be on it  */\n   if (length < 2U || entry_start > buffer + (length - 2U))\n   {\n      png_warning(png_ptr, \"malformed sPLT chunk\");\n      return;\n   }\n\n   new_palette.depth = *entry_start++;\n   entry_size = (new_palette.depth == 8 ? 6 : 10);\n   /* This must fit in a png_uint_32 because it is derived from the original\n    * chunk data length.\n    */\n   data_length = length - (png_uint_32)(entry_start - buffer);\n\n   /* Integrity-check the data length */\n   if ((data_length % entry_size) != 0)\n   {\n      png_warning(png_ptr, \"sPLT chunk has bad length\");\n      return;\n   }\n\n   dl = (png_int_32)(data_length / entry_size);\n   max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry));\n\n   if (dl > max_dl)\n   {\n      png_warning(png_ptr, \"sPLT chunk too long\");\n      return;\n   }\n\n   new_palette.nentries = (png_int_32)(data_length / entry_size);\n\n   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(\n       png_ptr, new_palette.nentries * (sizeof (png_sPLT_entry)));\n\n   if (new_palette.entries == NULL)\n   {\n      png_warning(png_ptr, \"sPLT chunk requires too much memory\");\n      return;\n   }\n\n#ifdef PNG_POINTER_INDEXING_SUPPORTED\n   for (i = 0; i < new_palette.nentries; i++)\n   {\n      pp = new_palette.entries + i;\n\n      if (new_palette.depth == 8)\n      {\n         pp->red = *entry_start++;\n         pp->green = *entry_start++;\n         pp->blue = *entry_start++;\n         pp->alpha = *entry_start++;\n      }\n\n      else\n      {\n         pp->red   = png_get_uint_16(entry_start); entry_start += 2;\n         pp->green = png_get_uint_16(entry_start); entry_start += 2;\n         pp->blue  = png_get_uint_16(entry_start); entry_start += 2;\n         pp->alpha = png_get_uint_16(entry_start); entry_start += 2;\n      }\n\n      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;\n   }\n#else\n   pp = new_palette.entries;\n\n   for (i = 0; i < new_palette.nentries; i++)\n   {\n\n      if (new_palette.depth == 8)\n      {\n         pp[i].red   = *entry_start++;\n         pp[i].green = *entry_start++;\n         pp[i].blue  = *entry_start++;\n         pp[i].alpha = *entry_start++;\n      }\n\n      else\n      {\n         pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;\n         pp[i].green = png_get_uint_16(entry_start); entry_start += 2;\n         pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;\n         pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;\n      }\n\n      pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;\n   }\n#endif\n\n   /* Discard all chunk data except the name and stash that */\n   new_palette.name = (png_charp)buffer;\n\n   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);\n\n   png_free(png_ptr, new_palette.entries);\n}\n#endif /* READ_sPLT */\n\n#ifdef PNG_READ_tRNS_SUPPORTED\nvoid /* PRIVATE */\npng_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];\n\n   png_debug(1, \"in png_handle_tRNS\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of place\");\n      return;\n   }\n\n   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"duplicate\");\n      return;\n   }\n\n   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)\n   {\n      png_byte buf[2];\n\n      if (length != 2)\n      {\n         png_crc_finish(png_ptr, length);\n         png_chunk_benign_error(png_ptr, \"invalid\");\n         return;\n      }\n\n      png_crc_read(png_ptr, buf, 2);\n      png_ptr->num_trans = 1;\n      png_ptr->trans_color.gray = png_get_uint_16(buf);\n   }\n\n   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)\n   {\n      png_byte buf[6];\n\n      if (length != 6)\n      {\n         png_crc_finish(png_ptr, length);\n         png_chunk_benign_error(png_ptr, \"invalid\");\n         return;\n      }\n\n      png_crc_read(png_ptr, buf, length);\n      png_ptr->num_trans = 1;\n      png_ptr->trans_color.red = png_get_uint_16(buf);\n      png_ptr->trans_color.green = png_get_uint_16(buf + 2);\n      png_ptr->trans_color.blue = png_get_uint_16(buf + 4);\n   }\n\n   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n   {\n      if ((png_ptr->mode & PNG_HAVE_PLTE) == 0)\n      {\n         /* TODO: is this actually an error in the ISO spec? */\n         png_crc_finish(png_ptr, length);\n         png_chunk_benign_error(png_ptr, \"out of place\");\n         return;\n      }\n\n      if (length > (unsigned int) png_ptr->num_palette ||\n         length > (unsigned int) PNG_MAX_PALETTE_LENGTH ||\n         length == 0)\n      {\n         png_crc_finish(png_ptr, length);\n         png_chunk_benign_error(png_ptr, \"invalid\");\n         return;\n      }\n\n      png_crc_read(png_ptr, readbuf, length);\n      png_ptr->num_trans = (png_uint_16)length;\n   }\n\n   else\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"invalid with alpha channel\");\n      return;\n   }\n\n   if (png_crc_finish(png_ptr, 0) != 0)\n   {\n      png_ptr->num_trans = 0;\n      return;\n   }\n\n   /* TODO: this is a horrible side effect in the palette case because the\n    * png_struct ends up with a pointer to the tRNS buffer owned by the\n    * png_info.  Fix this.\n    */\n   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,\n       &(png_ptr->trans_color));\n}\n#endif\n\n#ifdef PNG_READ_bKGD_SUPPORTED\nvoid /* PRIVATE */\npng_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   unsigned int truelen;\n   png_byte buf[6];\n   png_color_16 background;\n\n   png_debug(1, \"in png_handle_bKGD\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 ||\n       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&\n       (png_ptr->mode & PNG_HAVE_PLTE) == 0))\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of place\");\n      return;\n   }\n\n   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"duplicate\");\n      return;\n   }\n\n   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n      truelen = 1;\n\n   else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)\n      truelen = 6;\n\n   else\n      truelen = 2;\n\n   if (length != truelen)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"invalid\");\n      return;\n   }\n\n   png_crc_read(png_ptr, buf, truelen);\n\n   if (png_crc_finish(png_ptr, 0) != 0)\n      return;\n\n   /* We convert the index value into RGB components so that we can allow\n    * arbitrary RGB values for background when we have transparency, and\n    * so it is easy to determine the RGB values of the background color\n    * from the info_ptr struct.\n    */\n   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n   {\n      background.index = buf[0];\n\n      if (info_ptr != NULL && info_ptr->num_palette != 0)\n      {\n         if (buf[0] >= info_ptr->num_palette)\n         {\n            png_chunk_benign_error(png_ptr, \"invalid index\");\n            return;\n         }\n\n         background.red = (png_uint_16)png_ptr->palette[buf[0]].red;\n         background.green = (png_uint_16)png_ptr->palette[buf[0]].green;\n         background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;\n      }\n\n      else\n         background.red = background.green = background.blue = 0;\n\n      background.gray = 0;\n   }\n\n   else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */\n   {\n      background.index = 0;\n      background.red =\n      background.green =\n      background.blue =\n      background.gray = png_get_uint_16(buf);\n   }\n\n   else\n   {\n      background.index = 0;\n      background.red = png_get_uint_16(buf);\n      background.green = png_get_uint_16(buf + 2);\n      background.blue = png_get_uint_16(buf + 4);\n      background.gray = 0;\n   }\n\n   png_set_bKGD(png_ptr, info_ptr, &background);\n}\n#endif\n\n#ifdef PNG_READ_hIST_SUPPORTED\nvoid /* PRIVATE */\npng_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   unsigned int num, i;\n   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];\n\n   png_debug(1, \"in png_handle_hIST\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 ||\n       (png_ptr->mode & PNG_HAVE_PLTE) == 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of place\");\n      return;\n   }\n\n   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"duplicate\");\n      return;\n   }\n\n   num = length / 2 ;\n\n   if (num != (unsigned int) png_ptr->num_palette ||\n       num > (unsigned int) PNG_MAX_PALETTE_LENGTH)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"invalid\");\n      return;\n   }\n\n   for (i = 0; i < num; i++)\n   {\n      png_byte buf[2];\n\n      png_crc_read(png_ptr, buf, 2);\n      readbuf[i] = png_get_uint_16(buf);\n   }\n\n   if (png_crc_finish(png_ptr, 0) != 0)\n      return;\n\n   png_set_hIST(png_ptr, info_ptr, readbuf);\n}\n#endif\n\n#ifdef PNG_READ_pHYs_SUPPORTED\nvoid /* PRIVATE */\npng_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_byte buf[9];\n   png_uint_32 res_x, res_y;\n   int unit_type;\n\n   png_debug(1, \"in png_handle_pHYs\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of place\");\n      return;\n   }\n\n   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"duplicate\");\n      return;\n   }\n\n   if (length != 9)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"invalid\");\n      return;\n   }\n\n   png_crc_read(png_ptr, buf, 9);\n\n   if (png_crc_finish(png_ptr, 0) != 0)\n      return;\n\n   res_x = png_get_uint_32(buf);\n   res_y = png_get_uint_32(buf + 4);\n   unit_type = buf[8];\n   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);\n}\n#endif\n\n#ifdef PNG_READ_oFFs_SUPPORTED\nvoid /* PRIVATE */\npng_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_byte buf[9];\n   png_int_32 offset_x, offset_y;\n   int unit_type;\n\n   png_debug(1, \"in png_handle_oFFs\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of place\");\n      return;\n   }\n\n   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"duplicate\");\n      return;\n   }\n\n   if (length != 9)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"invalid\");\n      return;\n   }\n\n   png_crc_read(png_ptr, buf, 9);\n\n   if (png_crc_finish(png_ptr, 0) != 0)\n      return;\n\n   offset_x = png_get_int_32(buf);\n   offset_y = png_get_int_32(buf + 4);\n   unit_type = buf[8];\n   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);\n}\n#endif\n\n#ifdef PNG_READ_pCAL_SUPPORTED\n/* Read the pCAL chunk (described in the PNG Extensions document) */\nvoid /* PRIVATE */\npng_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_int_32 X0, X1;\n   png_byte type, nparams;\n   png_bytep buffer, buf, units, endptr;\n   png_charpp params;\n   int i;\n\n   png_debug(1, \"in png_handle_pCAL\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of place\");\n      return;\n   }\n\n   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"duplicate\");\n      return;\n   }\n\n   png_debug1(2, \"Allocating and reading pCAL chunk data (%u bytes)\",\n       length + 1);\n\n   buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);\n\n   if (buffer == NULL)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of memory\");\n      return;\n   }\n\n   png_crc_read(png_ptr, buffer, length);\n\n   if (png_crc_finish(png_ptr, 0) != 0)\n      return;\n\n   buffer[length] = 0; /* Null terminate the last string */\n\n   png_debug(3, \"Finding end of pCAL purpose string\");\n   for (buf = buffer; *buf; buf++)\n      /* Empty loop */ ;\n\n   endptr = buffer + length;\n\n   /* We need to have at least 12 bytes after the purpose string\n    * in order to get the parameter information.\n    */\n   if (endptr - buf <= 12)\n   {\n      png_chunk_benign_error(png_ptr, \"invalid\");\n      return;\n   }\n\n   png_debug(3, \"Reading pCAL X0, X1, type, nparams, and units\");\n   X0 = png_get_int_32((png_bytep)buf+1);\n   X1 = png_get_int_32((png_bytep)buf+5);\n   type = buf[9];\n   nparams = buf[10];\n   units = buf + 11;\n\n   png_debug(3, \"Checking pCAL equation type and number of parameters\");\n   /* Check that we have the right number of parameters for known\n    * equation types.\n    */\n   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||\n       (type == PNG_EQUATION_BASE_E && nparams != 3) ||\n       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||\n       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))\n   {\n      png_chunk_benign_error(png_ptr, \"invalid parameter count\");\n      return;\n   }\n\n   else if (type >= PNG_EQUATION_LAST)\n   {\n      png_chunk_benign_error(png_ptr, \"unrecognized equation type\");\n   }\n\n   for (buf = units; *buf; buf++)\n      /* Empty loop to move past the units string. */ ;\n\n   png_debug(3, \"Allocating pCAL parameters array\");\n\n   params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,\n       nparams * (sizeof (png_charp))));\n\n   if (params == NULL)\n   {\n      png_chunk_benign_error(png_ptr, \"out of memory\");\n      return;\n   }\n\n   /* Get pointers to the start of each parameter string. */\n   for (i = 0; i < nparams; i++)\n   {\n      buf++; /* Skip the null string terminator from previous parameter. */\n\n      png_debug1(3, \"Reading pCAL parameter %d\", i);\n\n      for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++)\n         /* Empty loop to move past each parameter string */ ;\n\n      /* Make sure we haven't run out of data yet */\n      if (buf > endptr)\n      {\n         png_free(png_ptr, params);\n         png_chunk_benign_error(png_ptr, \"invalid data\");\n         return;\n      }\n   }\n\n   png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams,\n      (png_charp)units, params);\n\n   png_free(png_ptr, params);\n}\n#endif\n\n#ifdef PNG_READ_sCAL_SUPPORTED\n/* Read the sCAL chunk */\nvoid /* PRIVATE */\npng_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_bytep buffer;\n   png_size_t i;\n   int state;\n\n   png_debug(1, \"in png_handle_sCAL\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of place\");\n      return;\n   }\n\n   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"duplicate\");\n      return;\n   }\n\n   /* Need unit type, width, \\0, height: minimum 4 bytes */\n   else if (length < 4)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"invalid\");\n      return;\n   }\n\n   png_debug1(2, \"Allocating and reading sCAL chunk data (%u bytes)\",\n      length + 1);\n\n   buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);\n\n   if (buffer == NULL)\n   {\n      png_chunk_benign_error(png_ptr, \"out of memory\");\n      png_crc_finish(png_ptr, length);\n      return;\n   }\n\n   png_crc_read(png_ptr, buffer, length);\n   buffer[length] = 0; /* Null terminate the last string */\n\n   if (png_crc_finish(png_ptr, 0) != 0)\n      return;\n\n   /* Validate the unit. */\n   if (buffer[0] != 1 && buffer[0] != 2)\n   {\n      png_chunk_benign_error(png_ptr, \"invalid unit\");\n      return;\n   }\n\n   /* Validate the ASCII numbers, need two ASCII numbers separated by\n    * a '\\0' and they need to fit exactly in the chunk data.\n    */\n   i = 1;\n   state = 0;\n\n   if (png_check_fp_number((png_const_charp)buffer, length, &state, &i) == 0 ||\n       i >= length || buffer[i++] != 0)\n      png_chunk_benign_error(png_ptr, \"bad width format\");\n\n   else if (PNG_FP_IS_POSITIVE(state) == 0)\n      png_chunk_benign_error(png_ptr, \"non-positive width\");\n\n   else\n   {\n      png_size_t heighti = i;\n\n      state = 0;\n      if (png_check_fp_number((png_const_charp)buffer, length,\n          &state, &i) == 0 || i != length)\n         png_chunk_benign_error(png_ptr, \"bad height format\");\n\n      else if (PNG_FP_IS_POSITIVE(state) == 0)\n         png_chunk_benign_error(png_ptr, \"non-positive height\");\n\n      else\n         /* This is the (only) success case. */\n         png_set_sCAL_s(png_ptr, info_ptr, buffer[0],\n            (png_charp)buffer+1, (png_charp)buffer+heighti);\n   }\n}\n#endif\n\n#ifdef PNG_READ_tIME_SUPPORTED\nvoid /* PRIVATE */\npng_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_byte buf[7];\n   png_time mod_time;\n\n   png_debug(1, \"in png_handle_tIME\");\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) != 0)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"duplicate\");\n      return;\n   }\n\n   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)\n      png_ptr->mode |= PNG_AFTER_IDAT;\n\n   if (length != 7)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"invalid\");\n      return;\n   }\n\n   png_crc_read(png_ptr, buf, 7);\n\n   if (png_crc_finish(png_ptr, 0) != 0)\n      return;\n\n   mod_time.second = buf[6];\n   mod_time.minute = buf[5];\n   mod_time.hour = buf[4];\n   mod_time.day = buf[3];\n   mod_time.month = buf[2];\n   mod_time.year = png_get_uint_16(buf);\n\n   png_set_tIME(png_ptr, info_ptr, &mod_time);\n}\n#endif\n\n#ifdef PNG_READ_tEXt_SUPPORTED\n/* Note: this does not properly handle chunks that are > 64K under DOS */\nvoid /* PRIVATE */\npng_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_text  text_info;\n   png_bytep buffer;\n   png_charp key;\n   png_charp text;\n   png_uint_32 skip = 0;\n\n   png_debug(1, \"in png_handle_tEXt\");\n\n#ifdef PNG_USER_LIMITS_SUPPORTED\n   if (png_ptr->user_chunk_cache_max != 0)\n   {\n      if (png_ptr->user_chunk_cache_max == 1)\n      {\n         png_crc_finish(png_ptr, length);\n         return;\n      }\n\n      if (--png_ptr->user_chunk_cache_max == 1)\n      {\n         png_crc_finish(png_ptr, length);\n         png_chunk_benign_error(png_ptr, \"no space in chunk cache\");\n         return;\n      }\n   }\n#endif\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)\n      png_ptr->mode |= PNG_AFTER_IDAT;\n\n#ifdef PNG_MAX_MALLOC_64K\n   if (length > 65535U)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"too large to fit in memory\");\n      return;\n   }\n#endif\n\n   buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);\n\n   if (buffer == NULL)\n   {\n     png_chunk_benign_error(png_ptr, \"out of memory\");\n     return;\n   }\n\n   png_crc_read(png_ptr, buffer, length);\n\n   if (png_crc_finish(png_ptr, skip) != 0)\n      return;\n\n   key = (png_charp)buffer;\n   key[length] = 0;\n\n   for (text = key; *text; text++)\n      /* Empty loop to find end of key */ ;\n\n   if (text != key + length)\n      text++;\n\n   text_info.compression = PNG_TEXT_COMPRESSION_NONE;\n   text_info.key = key;\n   text_info.lang = NULL;\n   text_info.lang_key = NULL;\n   text_info.itxt_length = 0;\n   text_info.text = text;\n   text_info.text_length = strlen(text);\n\n   if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) != 0)\n      png_warning(png_ptr, \"Insufficient memory to process text chunk\");\n}\n#endif\n\n#ifdef PNG_READ_zTXt_SUPPORTED\n/* Note: this does not correctly handle chunks that are > 64K under DOS */\nvoid /* PRIVATE */\npng_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_const_charp errmsg = NULL;\n   png_bytep       buffer;\n   png_uint_32     keyword_length;\n\n   png_debug(1, \"in png_handle_zTXt\");\n\n#ifdef PNG_USER_LIMITS_SUPPORTED\n   if (png_ptr->user_chunk_cache_max != 0)\n   {\n      if (png_ptr->user_chunk_cache_max == 1)\n      {\n         png_crc_finish(png_ptr, length);\n         return;\n      }\n\n      if (--png_ptr->user_chunk_cache_max == 1)\n      {\n         png_crc_finish(png_ptr, length);\n         png_chunk_benign_error(png_ptr, \"no space in chunk cache\");\n         return;\n      }\n   }\n#endif\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)\n      png_ptr->mode |= PNG_AFTER_IDAT;\n\n   buffer = png_read_buffer(png_ptr, length, 2/*silent*/);\n\n   if (buffer == NULL)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of memory\");\n      return;\n   }\n\n   png_crc_read(png_ptr, buffer, length);\n\n   if (png_crc_finish(png_ptr, 0) != 0)\n      return;\n\n   /* TODO: also check that the keyword contents match the spec! */\n   for (keyword_length = 0;\n      keyword_length < length && buffer[keyword_length] != 0;\n      ++keyword_length)\n      /* Empty loop to find end of name */ ;\n\n   if (keyword_length > 79 || keyword_length < 1)\n      errmsg = \"bad keyword\";\n\n   /* zTXt must have some LZ data after the keyword, although it may expand to\n    * zero bytes; we need a '\\0' at the end of the keyword, the compression type\n    * then the LZ data:\n    */\n   else if (keyword_length + 3 > length)\n      errmsg = \"truncated\";\n\n   else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE)\n      errmsg = \"unknown compression type\";\n\n   else\n   {\n      png_alloc_size_t uncompressed_length = PNG_SIZE_MAX;\n\n      /* TODO: at present png_decompress_chunk imposes a single application\n       * level memory limit, this should be split to different values for iCCP\n       * and text chunks.\n       */\n      if (png_decompress_chunk(png_ptr, length, keyword_length+2,\n         &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)\n      {\n         png_text text;\n\n         /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except\n          * for the extra compression type byte and the fact that it isn't\n          * necessarily '\\0' terminated.\n          */\n         buffer = png_ptr->read_buffer;\n         buffer[uncompressed_length+(keyword_length+2)] = 0;\n\n         text.compression = PNG_TEXT_COMPRESSION_zTXt;\n         text.key = (png_charp)buffer;\n         text.text = (png_charp)(buffer + keyword_length+2);\n         text.text_length = uncompressed_length;\n         text.itxt_length = 0;\n         text.lang = NULL;\n         text.lang_key = NULL;\n\n         if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0)\n            errmsg = \"insufficient memory\";\n      }\n\n      else\n         errmsg = png_ptr->zstream.msg;\n   }\n\n   if (errmsg != NULL)\n      png_chunk_benign_error(png_ptr, errmsg);\n}\n#endif\n\n#ifdef PNG_READ_iTXt_SUPPORTED\n/* Note: this does not correctly handle chunks that are > 64K under DOS */\nvoid /* PRIVATE */\npng_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)\n{\n   png_const_charp errmsg = NULL;\n   png_bytep buffer;\n   png_uint_32 prefix_length;\n\n   png_debug(1, \"in png_handle_iTXt\");\n\n#ifdef PNG_USER_LIMITS_SUPPORTED\n   if (png_ptr->user_chunk_cache_max != 0)\n   {\n      if (png_ptr->user_chunk_cache_max == 1)\n      {\n         png_crc_finish(png_ptr, length);\n         return;\n      }\n\n      if (--png_ptr->user_chunk_cache_max == 1)\n      {\n         png_crc_finish(png_ptr, length);\n         png_chunk_benign_error(png_ptr, \"no space in chunk cache\");\n         return;\n      }\n   }\n#endif\n\n   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)\n      png_chunk_error(png_ptr, \"missing IHDR\");\n\n   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)\n      png_ptr->mode |= PNG_AFTER_IDAT;\n\n   buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);\n\n   if (buffer == NULL)\n   {\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"out of memory\");\n      return;\n   }\n\n   png_crc_read(png_ptr, buffer, length);\n\n   if (png_crc_finish(png_ptr, 0) != 0)\n      return;\n\n   /* First the keyword. */\n   for (prefix_length=0;\n      prefix_length < length && buffer[prefix_length] != 0;\n      ++prefix_length)\n      /* Empty loop */ ;\n\n   /* Perform a basic check on the keyword length here. */\n   if (prefix_length > 79 || prefix_length < 1)\n      errmsg = \"bad keyword\";\n\n   /* Expect keyword, compression flag, compression type, language, translated\n    * keyword (both may be empty but are 0 terminated) then the text, which may\n    * be empty.\n    */\n   else if (prefix_length + 5 > length)\n      errmsg = \"truncated\";\n\n   else if (buffer[prefix_length+1] == 0 ||\n      (buffer[prefix_length+1] == 1 &&\n      buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE))\n   {\n      int compressed = buffer[prefix_length+1] != 0;\n      png_uint_32 language_offset, translated_keyword_offset;\n      png_alloc_size_t uncompressed_length = 0;\n\n      /* Now the language tag */\n      prefix_length += 3;\n      language_offset = prefix_length;\n\n      for (; prefix_length < length && buffer[prefix_length] != 0;\n         ++prefix_length)\n         /* Empty loop */ ;\n\n      /* WARNING: the length may be invalid here, this is checked below. */\n      translated_keyword_offset = ++prefix_length;\n\n      for (; prefix_length < length && buffer[prefix_length] != 0;\n         ++prefix_length)\n         /* Empty loop */ ;\n\n      /* prefix_length should now be at the trailing '\\0' of the translated\n       * keyword, but it may already be over the end.  None of this arithmetic\n       * can overflow because chunks are at most 2^31 bytes long, but on 16-bit\n       * systems the available allocation may overflow.\n       */\n      ++prefix_length;\n\n      if (compressed == 0 && prefix_length <= length)\n         uncompressed_length = length - prefix_length;\n\n      else if (compressed != 0 && prefix_length < length)\n      {\n         uncompressed_length = PNG_SIZE_MAX;\n\n         /* TODO: at present png_decompress_chunk imposes a single application\n          * level memory limit, this should be split to different values for\n          * iCCP and text chunks.\n          */\n         if (png_decompress_chunk(png_ptr, length, prefix_length,\n            &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)\n            buffer = png_ptr->read_buffer;\n\n         else\n            errmsg = png_ptr->zstream.msg;\n      }\n\n      else\n         errmsg = \"truncated\";\n\n      if (errmsg == NULL)\n      {\n         png_text text;\n\n         buffer[uncompressed_length+prefix_length] = 0;\n\n         if (compressed == 0)\n            text.compression = PNG_ITXT_COMPRESSION_NONE;\n\n         else\n            text.compression = PNG_ITXT_COMPRESSION_zTXt;\n\n         text.key = (png_charp)buffer;\n         text.lang = (png_charp)buffer + language_offset;\n         text.lang_key = (png_charp)buffer + translated_keyword_offset;\n         text.text = (png_charp)buffer + prefix_length;\n         text.text_length = 0;\n         text.itxt_length = uncompressed_length;\n\n         if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0)\n            errmsg = \"insufficient memory\";\n      }\n   }\n\n   else\n      errmsg = \"bad compression info\";\n\n   if (errmsg != NULL)\n      png_chunk_benign_error(png_ptr, errmsg);\n}\n#endif\n\n#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED\n/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */\nstatic int\npng_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)\n{\n   png_alloc_size_t limit = PNG_SIZE_MAX;\n\n   if (png_ptr->unknown_chunk.data != NULL)\n   {\n      png_free(png_ptr, png_ptr->unknown_chunk.data);\n      png_ptr->unknown_chunk.data = NULL;\n   }\n\n#  ifdef PNG_SET_USER_LIMITS_SUPPORTED\n   if (png_ptr->user_chunk_malloc_max > 0 &&\n       png_ptr->user_chunk_malloc_max < limit)\n      limit = png_ptr->user_chunk_malloc_max;\n\n#  elif PNG_USER_CHUNK_MALLOC_MAX > 0\n   if (PNG_USER_CHUNK_MALLOC_MAX < limit)\n      limit = PNG_USER_CHUNK_MALLOC_MAX;\n#  endif\n\n   if (length <= limit)\n   {\n      PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);\n      /* The following is safe because of the PNG_SIZE_MAX init above */\n      png_ptr->unknown_chunk.size = (png_size_t)length/*SAFE*/;\n      /* 'mode' is a flag array, only the bottom four bits matter here */\n      png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/;\n\n      if (length == 0)\n         png_ptr->unknown_chunk.data = NULL;\n\n      else\n      {\n         /* Do a 'warn' here - it is handled below. */\n         png_ptr->unknown_chunk.data = png_voidcast(png_bytep,\n            png_malloc_warn(png_ptr, length));\n      }\n   }\n\n   if (png_ptr->unknown_chunk.data == NULL && length > 0)\n   {\n      /* This is benign because we clean up correctly */\n      png_crc_finish(png_ptr, length);\n      png_chunk_benign_error(png_ptr, \"unknown chunk exceeds memory limits\");\n      return 0;\n   }\n\n   else\n   {\n      if (length > 0)\n         png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length);\n      png_crc_finish(png_ptr, 0);\n      return 1;\n   }\n}\n#endif /* READ_UNKNOWN_CHUNKS */\n\n/* Handle an unknown, or known but disabled, chunk */\nvoid /* PRIVATE */\npng_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,\n   png_uint_32 length, int keep)\n{\n   int handled = 0; /* the chunk was handled */\n\n   png_debug(1, \"in png_handle_unknown\");\n\n#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED\n   /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing\n    * the bug which meant that setting a non-default behavior for a specific\n    * chunk would be ignored (the default was always used unless a user\n    * callback was installed).\n    *\n    * 'keep' is the value from the png_chunk_unknown_handling, the setting for\n    * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it\n    * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here.\n    * This is just an optimization to avoid multiple calls to the lookup\n    * function.\n    */\n#  ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED\n#     ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED\n   keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name);\n#     endif\n#  endif\n\n   /* One of the following methods will read the chunk or skip it (at least one\n    * of these is always defined because this is the only way to switch on\n    * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)\n    */\n#  ifdef PNG_READ_USER_CHUNKS_SUPPORTED\n   /* The user callback takes precedence over the chunk keep value, but the\n    * keep value is still required to validate a save of a critical chunk.\n    */\n   if (png_ptr->read_user_chunk_fn != NULL)\n   {\n      if (png_cache_unknown_chunk(png_ptr, length) != 0)\n      {\n         /* Callback to user unknown chunk handler */\n         int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr,\n            &png_ptr->unknown_chunk);\n\n         /* ret is:\n          * negative: An error occurred; png_chunk_error will be called.\n          *     zero: The chunk was not handled, the chunk will be discarded\n          *           unless png_set_keep_unknown_chunks has been used to set\n          *           a 'keep' behavior for this particular chunk, in which\n          *           case that will be used.  A critical chunk will cause an\n          *           error at this point unless it is to be saved.\n          * positive: The chunk was handled, libpng will ignore/discard it.\n          */\n         if (ret < 0)\n            png_chunk_error(png_ptr, \"error in user chunk\");\n\n         else if (ret == 0)\n         {\n            /* If the keep value is 'default' or 'never' override it, but\n             * still error out on critical chunks unless the keep value is\n             * 'always'  While this is weird it is the behavior in 1.4.12.\n             * A possible improvement would be to obey the value set for the\n             * chunk, but this would be an API change that would probably\n             * damage some applications.\n             *\n             * The png_app_warning below catches the case that matters, where\n             * the application has not set specific save or ignore for this\n             * chunk or global save or ignore.\n             */\n            if (keep < PNG_HANDLE_CHUNK_IF_SAFE)\n            {\n#              ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED\n               if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE)\n               {\n                  png_chunk_warning(png_ptr, \"Saving unknown chunk:\");\n                  png_app_warning(png_ptr,\n                     \"forcing save of an unhandled chunk;\"\n                     \" please call png_set_keep_unknown_chunks\");\n                     /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */\n               }\n#              endif\n               keep = PNG_HANDLE_CHUNK_IF_SAFE;\n            }\n         }\n\n         else /* chunk was handled */\n         {\n            handled = 1;\n            /* Critical chunks can be safely discarded at this point. */\n            keep = PNG_HANDLE_CHUNK_NEVER;\n         }\n      }\n\n      else\n         keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */\n   }\n\n   else\n   /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */\n#  endif /* READ_USER_CHUNKS */\n\n#  ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED\n   {\n      /* keep is currently just the per-chunk setting, if there was no\n       * setting change it to the global default now (not that this may\n       * still be AS_DEFAULT) then obtain the cache of the chunk if required,\n       * if not simply skip the chunk.\n       */\n      if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT)\n         keep = png_ptr->unknown_default;\n\n      if (keep == PNG_HANDLE_CHUNK_ALWAYS ||\n         (keep == PNG_HANDLE_CHUNK_IF_SAFE &&\n          PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))\n      {\n         if (png_cache_unknown_chunk(png_ptr, length) == 0)\n            keep = PNG_HANDLE_CHUNK_NEVER;\n      }\n\n      else\n         png_crc_finish(png_ptr, length);\n   }\n#  else\n#     ifndef PNG_READ_USER_CHUNKS_SUPPORTED\n#        error no method to support READ_UNKNOWN_CHUNKS\n#     endif\n\n   {\n      /* If here there is no read callback pointer set and no support is\n       * compiled in to just save the unknown chunks, so simply skip this\n       * chunk.  If 'keep' is something other than AS_DEFAULT or NEVER then\n       * the app has erroneously asked for unknown chunk saving when there\n       * is no support.\n       */\n      if (keep > PNG_HANDLE_CHUNK_NEVER)\n         png_app_error(png_ptr, \"no unknown chunk support available\");\n\n      png_crc_finish(png_ptr, length);\n   }\n#  endif\n\n#  ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED\n   /* Now store the chunk in the chunk list if appropriate, and if the limits\n    * permit it.\n    */\n   if (keep == PNG_HANDLE_CHUNK_ALWAYS ||\n      (keep == PNG_HANDLE_CHUNK_IF_SAFE &&\n       PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))\n   {\n#     ifdef PNG_USER_LIMITS_SUPPORTED\n      switch (png_ptr->user_chunk_cache_max)\n      {\n         case 2:\n            png_ptr->user_chunk_cache_max = 1;\n            png_chunk_benign_error(png_ptr, \"no space in chunk cache\");\n            /* FALL THROUGH */\n         case 1:\n            /* NOTE: prior to 1.6.0 this case resulted in an unknown critical\n             * chunk being skipped, now there will be a hard error below.\n             */\n            break;\n\n         default: /* not at limit */\n            --(png_ptr->user_chunk_cache_max);\n            /* FALL THROUGH */\n         case 0: /* no limit */\n#  endif /* USER_LIMITS */\n            /* Here when the limit isn't reached or when limits are compiled\n             * out; store the chunk.\n             */\n            png_set_unknown_chunks(png_ptr, info_ptr,\n               &png_ptr->unknown_chunk, 1);\n            handled = 1;\n#  ifdef PNG_USER_LIMITS_SUPPORTED\n            break;\n      }\n#  endif\n   }\n#  else /* no store support: the chunk must be handled by the user callback */\n   PNG_UNUSED(info_ptr)\n#  endif\n\n   /* Regardless of the error handling below the cached data (if any) can be\n    * freed now.  Notice that the data is not freed if there is a png_error, but\n    * it will be freed by destroy_read_struct.\n    */\n   if (png_ptr->unknown_chunk.data != NULL)\n      png_free(png_ptr, png_ptr->unknown_chunk.data);\n   png_ptr->unknown_chunk.data = NULL;\n\n#else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */\n   /* There is no support to read an unknown chunk, so just skip it. */\n   png_crc_finish(png_ptr, length);\n   PNG_UNUSED(info_ptr)\n   PNG_UNUSED(keep)\n#endif /* !READ_UNKNOWN_CHUNKS */\n\n   /* Check for unhandled critical chunks */\n   if (handled == 0 && PNG_CHUNK_CRITICAL(png_ptr->chunk_name))\n      png_chunk_error(png_ptr, \"unhandled critical chunk\");\n}\n\n/* This function is called to verify that a chunk name is valid.\n * This function can't have the \"critical chunk check\" incorporated\n * into it, since in the future we will need to be able to call user\n * functions to handle unknown critical chunks after we check that\n * the chunk name itself is valid.\n */\n\n/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is:\n *\n * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))\n */\n\nvoid /* PRIVATE */\npng_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name)\n{\n   int i;\n\n   png_debug(1, \"in png_check_chunk_name\");\n\n   for (i=1; i<=4; ++i)\n   {\n      int c = chunk_name & 0xff;\n\n      if (c < 65 || c > 122 || (c > 90 && c < 97))\n         png_chunk_error(png_ptr, \"invalid chunk type\");\n\n      chunk_name >>= 8;\n   }\n}\n\n/* Combines the row recently read in with the existing pixels in the row.  This\n * routine takes care of alpha and transparency if requested.  This routine also\n * handles the two methods of progressive display of interlaced images,\n * depending on the 'display' value; if 'display' is true then the whole row\n * (dp) is filled from the start by replicating the available pixels.  If\n * 'display' is false only those pixels present in the pass are filled in.\n */\nvoid /* PRIVATE */\npng_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)\n{\n   unsigned int pixel_depth = png_ptr->transformed_pixel_depth;\n   png_const_bytep sp = png_ptr->row_buf + 1;\n   png_alloc_size_t row_width = png_ptr->width;\n   unsigned int pass = png_ptr->pass;\n   png_bytep end_ptr = 0;\n   png_byte end_byte = 0;\n   unsigned int end_mask;\n\n   png_debug(1, \"in png_combine_row\");\n\n   /* Added in 1.5.6: it should not be possible to enter this routine until at\n    * least one row has been read from the PNG data and transformed.\n    */\n   if (pixel_depth == 0)\n      png_error(png_ptr, \"internal row logic error\");\n\n   /* Added in 1.5.4: the pixel depth should match the information returned by\n    * any call to png_read_update_info at this point.  Do not continue if we got\n    * this wrong.\n    */\n   if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes !=\n          PNG_ROWBYTES(pixel_depth, row_width))\n      png_error(png_ptr, \"internal row size calculation error\");\n\n   /* Don't expect this to ever happen: */\n   if (row_width == 0)\n      png_error(png_ptr, \"internal row width error\");\n\n   /* Preserve the last byte in cases where only part of it will be overwritten,\n    * the multiply below may overflow, we don't care because ANSI-C guarantees\n    * we get the low bits.\n    */\n   end_mask = (pixel_depth * row_width) & 7;\n   if (end_mask != 0)\n   {\n      /* end_ptr == NULL is a flag to say do nothing */\n      end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1;\n      end_byte = *end_ptr;\n#     ifdef PNG_READ_PACKSWAP_SUPPORTED\n      if ((png_ptr->transformations & PNG_PACKSWAP) != 0)\n         /* little-endian byte */\n         end_mask = 0xff << end_mask;\n\n      else /* big-endian byte */\n#     endif\n      end_mask = 0xff >> end_mask;\n      /* end_mask is now the bits to *keep* from the destination row */\n   }\n\n   /* For non-interlaced images this reduces to a memcpy(). A memcpy()\n    * will also happen if interlacing isn't supported or if the application\n    * does not call png_set_interlace_handling().  In the latter cases the\n    * caller just gets a sequence of the unexpanded rows from each interlace\n    * pass.\n    */\n#ifdef PNG_READ_INTERLACING_SUPPORTED\n   if (png_ptr->interlaced != 0 &&\n       (png_ptr->transformations & PNG_INTERLACE) != 0 &&\n       pass < 6 && (display == 0 ||\n       /* The following copies everything for 'display' on passes 0, 2 and 4. */\n       (display == 1 && (pass & 1) != 0)))\n   {\n      /* Narrow images may have no bits in a pass; the caller should handle\n       * this, but this test is cheap:\n       */\n      if (row_width <= PNG_PASS_START_COL(pass))\n         return;\n\n      if (pixel_depth < 8)\n      {\n         /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit\n          * into 32 bits, then a single loop over the bytes using the four byte\n          * values in the 32-bit mask can be used.  For the 'display' option the\n          * expanded mask may also not require any masking within a byte.  To\n          * make this work the PACKSWAP option must be taken into account - it\n          * simply requires the pixels to be reversed in each byte.\n          *\n          * The 'regular' case requires a mask for each of the first 6 passes,\n          * the 'display' case does a copy for the even passes in the range\n          * 0..6.  This has already been handled in the test above.\n          *\n          * The masks are arranged as four bytes with the first byte to use in\n          * the lowest bits (little-endian) regardless of the order (PACKSWAP or\n          * not) of the pixels in each byte.\n          *\n          * NOTE: the whole of this logic depends on the caller of this function\n          * only calling it on rows appropriate to the pass.  This function only\n          * understands the 'x' logic; the 'y' logic is handled by the caller.\n          *\n          * The following defines allow generation of compile time constant bit\n          * masks for each pixel depth and each possibility of swapped or not\n          * swapped bytes.  Pass 'p' is in the range 0..6; 'x', a pixel index,\n          * is in the range 0..7; and the result is 1 if the pixel is to be\n          * copied in the pass, 0 if not.  'S' is for the sparkle method, 'B'\n          * for the block method.\n          *\n          * With some compilers a compile time expression of the general form:\n          *\n          *    (shift >= 32) ? (a >> (shift-32)) : (b >> shift)\n          *\n          * Produces warnings with values of 'shift' in the range 33 to 63\n          * because the right hand side of the ?: expression is evaluated by\n          * the compiler even though it isn't used.  Microsoft Visual C (various\n          * versions) and the Intel C compiler are known to do this.  To avoid\n          * this the following macros are used in 1.5.6.  This is a temporary\n          * solution to avoid destabilizing the code during the release process.\n          */\n#        if PNG_USE_COMPILE_TIME_MASKS\n#           define PNG_LSR(x,s) ((x)>>((s) & 0x1f))\n#           define PNG_LSL(x,s) ((x)<<((s) & 0x1f))\n#        else\n#           define PNG_LSR(x,s) ((x)>>(s))\n#           define PNG_LSL(x,s) ((x)<<(s))\n#        endif\n#        define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\\\n           PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1)\n#        define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\\\n           PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1)\n\n         /* Return a mask for pass 'p' pixel 'x' at depth 'd'.  The mask is\n          * little endian - the first pixel is at bit 0 - however the extra\n          * parameter 's' can be set to cause the mask position to be swapped\n          * within each byte, to match the PNG format.  This is done by XOR of\n          * the shift with 7, 6 or 4 for bit depths 1, 2 and 4.\n          */\n#        define PIXEL_MASK(p,x,d,s) \\\n            (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0))))\n\n         /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask.\n          */\n#        define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)\n#        define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)\n\n         /* Combine 8 of these to get the full mask.  For the 1-bpp and 2-bpp\n          * cases the result needs replicating, for the 4-bpp case the above\n          * generates a full 32 bits.\n          */\n#        define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1)))\n\n#        define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\\\n            S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\\\n            S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d)\n\n#        define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\\\n            B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\\\n            B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d)\n\n#if PNG_USE_COMPILE_TIME_MASKS\n         /* Utility macros to construct all the masks for a depth/swap\n          * combination.  The 's' parameter says whether the format is PNG\n          * (big endian bytes) or not.  Only the three odd-numbered passes are\n          * required for the display/block algorithm.\n          */\n#        define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\\\n            S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) }\n\n#        define B_MASKS(d,s) { B_MASK(1,d,s), B_MASK(3,d,s), B_MASK(5,d,s) }\n\n#        define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2))\n\n         /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and\n          * then pass:\n          */\n         static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =\n         {\n            /* Little-endian byte masks for PACKSWAP */\n            { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) },\n            /* Normal (big-endian byte) masks - PNG format */\n            { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) }\n         };\n\n         /* display_mask has only three entries for the odd passes, so index by\n          * pass>>1.\n          */\n         static PNG_CONST png_uint_32 display_mask[2][3][3] =\n         {\n            /* Little-endian byte masks for PACKSWAP */\n            { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) },\n            /* Normal (big-endian byte) masks - PNG format */\n            { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) }\n         };\n\n#        define MASK(pass,depth,display,png)\\\n            ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\\\n               row_mask[png][DEPTH_INDEX(depth)][pass])\n\n#else /* !PNG_USE_COMPILE_TIME_MASKS */\n         /* This is the runtime alternative: it seems unlikely that this will\n          * ever be either smaller or faster than the compile time approach.\n          */\n#        define MASK(pass,depth,display,png)\\\n            ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png))\n#endif /* !USE_COMPILE_TIME_MASKS */\n\n         /* Use the appropriate mask to copy the required bits.  In some cases\n          * the byte mask will be 0 or 0xff; optimize these cases.  row_width is\n          * the number of pixels, but the code copies bytes, so it is necessary\n          * to special case the end.\n          */\n         png_uint_32 pixels_per_byte = 8 / pixel_depth;\n         png_uint_32 mask;\n\n#        ifdef PNG_READ_PACKSWAP_SUPPORTED\n         if ((png_ptr->transformations & PNG_PACKSWAP) != 0)\n            mask = MASK(pass, pixel_depth, display, 0);\n\n         else\n#        endif\n         mask = MASK(pass, pixel_depth, display, 1);\n\n         for (;;)\n         {\n            png_uint_32 m;\n\n            /* It doesn't matter in the following if png_uint_32 has more than\n             * 32 bits because the high bits always match those in m<<24; it is,\n             * however, essential to use OR here, not +, because of this.\n             */\n            m = mask;\n            mask = (m >> 8) | (m << 24); /* rotate right to good compilers */\n            m &= 0xff;\n\n            if (m != 0) /* something to copy */\n            {\n               if (m != 0xff)\n                  *dp = (png_byte)((*dp & ~m) | (*sp & m));\n               else\n                  *dp = *sp;\n            }\n\n            /* NOTE: this may overwrite the last byte with garbage if the image\n             * is not an exact number of bytes wide; libpng has always done\n             * this.\n             */\n            if (row_width <= pixels_per_byte)\n               break; /* May need to restore part of the last byte */\n\n            row_width -= pixels_per_byte;\n            ++dp;\n            ++sp;\n         }\n      }\n\n      else /* pixel_depth >= 8 */\n      {\n         unsigned int bytes_to_copy, bytes_to_jump;\n\n         /* Validate the depth - it must be a multiple of 8 */\n         if (pixel_depth & 7)\n            png_error(png_ptr, \"invalid user transform pixel depth\");\n\n         pixel_depth >>= 3; /* now in bytes */\n         row_width *= pixel_depth;\n\n         /* Regardless of pass number the Adam 7 interlace always results in a\n          * fixed number of pixels to copy then to skip.  There may be a\n          * different number of pixels to skip at the start though.\n          */\n         {\n            unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth;\n\n            row_width -= offset;\n            dp += offset;\n            sp += offset;\n         }\n\n         /* Work out the bytes to copy. */\n         if (display != 0)\n         {\n            /* When doing the 'block' algorithm the pixel in the pass gets\n             * replicated to adjacent pixels.  This is why the even (0,2,4,6)\n             * passes are skipped above - the entire expanded row is copied.\n             */\n            bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth;\n\n            /* But don't allow this number to exceed the actual row width. */\n            if (bytes_to_copy > row_width)\n               bytes_to_copy = (unsigned int)/*SAFE*/row_width;\n         }\n\n         else /* normal row; Adam7 only ever gives us one pixel to copy. */\n            bytes_to_copy = pixel_depth;\n\n         /* In Adam7 there is a constant offset between where the pixels go. */\n         bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth;\n\n         /* And simply copy these bytes.  Some optimization is possible here,\n          * depending on the value of 'bytes_to_copy'.  Special case the low\n          * byte counts, which we know to be frequent.\n          *\n          * Notice that these cases all 'return' rather than 'break' - this\n          * avoids an unnecessary test on whether to restore the last byte\n          * below.\n          */\n         switch (bytes_to_copy)\n         {\n            case 1:\n               for (;;)\n               {\n                  *dp = *sp;\n\n                  if (row_width <= bytes_to_jump)\n                     return;\n\n                  dp += bytes_to_jump;\n                  sp += bytes_to_jump;\n                  row_width -= bytes_to_jump;\n               }\n\n            case 2:\n               /* There is a possibility of a partial copy at the end here; this\n                * slows the code down somewhat.\n                */\n               do\n               {\n                  dp[0] = sp[0], dp[1] = sp[1];\n\n                  if (row_width <= bytes_to_jump)\n                     return;\n\n                  sp += bytes_to_jump;\n                  dp += bytes_to_jump;\n                  row_width -= bytes_to_jump;\n               }\n               while (row_width > 1);\n\n               /* And there can only be one byte left at this point: */\n               *dp = *sp;\n               return;\n\n            case 3:\n               /* This can only be the RGB case, so each copy is exactly one\n                * pixel and it is not necessary to check for a partial copy.\n                */\n               for (;;)\n               {\n                  dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2];\n\n                  if (row_width <= bytes_to_jump)\n                     return;\n\n                  sp += bytes_to_jump;\n                  dp += bytes_to_jump;\n                  row_width -= bytes_to_jump;\n               }\n\n            default:\n#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE\n               /* Check for double byte alignment and, if possible, use a\n                * 16-bit copy.  Don't attempt this for narrow images - ones that\n                * are less than an interlace panel wide.  Don't attempt it for\n                * wide bytes_to_copy either - use the memcpy there.\n                */\n               if (bytes_to_copy < 16 /*else use memcpy*/ &&\n                   png_isaligned(dp, png_uint_16) &&\n                   png_isaligned(sp, png_uint_16) &&\n                   bytes_to_copy % (sizeof (png_uint_16)) == 0 &&\n                   bytes_to_jump % (sizeof (png_uint_16)) == 0)\n               {\n                  /* Everything is aligned for png_uint_16 copies, but try for\n                   * png_uint_32 first.\n                   */\n                  if (png_isaligned(dp, png_uint_32) != 0 &&\n                      png_isaligned(sp, png_uint_32) != 0 &&\n                      bytes_to_copy % (sizeof (png_uint_32)) == 0 &&\n                      bytes_to_jump % (sizeof (png_uint_32)) == 0)\n                  {\n                     png_uint_32p dp32 = png_aligncast(png_uint_32p,dp);\n                     png_const_uint_32p sp32 = png_aligncastconst(\n                         png_const_uint_32p, sp);\n                     size_t skip = (bytes_to_jump-bytes_to_copy) /\n                         (sizeof (png_uint_32));\n\n                     do\n                     {\n                        size_t c = bytes_to_copy;\n                        do\n                        {\n                           *dp32++ = *sp32++;\n                           c -= (sizeof (png_uint_32));\n                        }\n                        while (c > 0);\n\n                        if (row_width <= bytes_to_jump)\n                           return;\n\n                        dp32 += skip;\n                        sp32 += skip;\n                        row_width -= bytes_to_jump;\n                     }\n                     while (bytes_to_copy <= row_width);\n\n                     /* Get to here when the row_width truncates the final copy.\n                      * There will be 1-3 bytes left to copy, so don't try the\n                      * 16-bit loop below.\n                      */\n                     dp = (png_bytep)dp32;\n                     sp = (png_const_bytep)sp32;\n                     do\n                        *dp++ = *sp++;\n                     while (--row_width > 0);\n                     return;\n                  }\n\n                  /* Else do it in 16-bit quantities, but only if the size is\n                   * not too large.\n                   */\n                  else\n                  {\n                     png_uint_16p dp16 = png_aligncast(png_uint_16p, dp);\n                     png_const_uint_16p sp16 = png_aligncastconst(\n                        png_const_uint_16p, sp);\n                     size_t skip = (bytes_to_jump-bytes_to_copy) /\n                        (sizeof (png_uint_16));\n\n                     do\n                     {\n                        size_t c = bytes_to_copy;\n                        do\n                        {\n                           *dp16++ = *sp16++;\n                           c -= (sizeof (png_uint_16));\n                        }\n                        while (c > 0);\n\n                        if (row_width <= bytes_to_jump)\n                           return;\n\n                        dp16 += skip;\n                        sp16 += skip;\n                        row_width -= bytes_to_jump;\n                     }\n                     while (bytes_to_copy <= row_width);\n\n                     /* End of row - 1 byte left, bytes_to_copy > row_width: */\n                     dp = (png_bytep)dp16;\n                     sp = (png_const_bytep)sp16;\n                     do\n                        *dp++ = *sp++;\n                     while (--row_width > 0);\n                     return;\n                  }\n               }\n#endif /* ALIGN_TYPE code */\n\n               /* The true default - use a memcpy: */\n               for (;;)\n               {\n                  memcpy(dp, sp, bytes_to_copy);\n\n                  if (row_width <= bytes_to_jump)\n                     return;\n\n                  sp += bytes_to_jump;\n                  dp += bytes_to_jump;\n                  row_width -= bytes_to_jump;\n                  if (bytes_to_copy > row_width)\n                     bytes_to_copy = (unsigned int)/*SAFE*/row_width;\n               }\n         }\n\n         /* NOT REACHED*/\n      } /* pixel_depth >= 8 */\n\n      /* Here if pixel_depth < 8 to check 'end_ptr' below. */\n   }\n   else\n#endif /* READ_INTERLACING */\n\n   /* If here then the switch above wasn't used so just memcpy the whole row\n    * from the temporary row buffer (notice that this overwrites the end of the\n    * destination row if it is a partial byte.)\n    */\n   memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width));\n\n   /* Restore the overwritten bits from the last byte if necessary. */\n   if (end_ptr != NULL)\n      *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask));\n}\n\n#ifdef PNG_READ_INTERLACING_SUPPORTED\nvoid /* PRIVATE */\npng_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,\n   png_uint_32 transformations /* Because these may affect the byte layout */)\n{\n   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */\n   /* Offset to next interlace block */\n   static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};\n\n   png_debug(1, \"in png_do_read_interlace\");\n   if (row != NULL && row_info != NULL)\n   {\n      png_uint_32 final_width;\n\n      final_width = row_info->width * png_pass_inc[pass];\n\n      switch (row_info->pixel_depth)\n      {\n         case 1:\n         {\n            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);\n            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);\n            int sshift, dshift;\n            int s_start, s_end, s_inc;\n            int jstop = png_pass_inc[pass];\n            png_byte v;\n            png_uint_32 i;\n            int j;\n\n#ifdef PNG_READ_PACKSWAP_SUPPORTED\n            if ((transformations & PNG_PACKSWAP) != 0)\n            {\n                sshift = (int)((row_info->width + 7) & 0x07);\n                dshift = (int)((final_width + 7) & 0x07);\n                s_start = 7;\n                s_end = 0;\n                s_inc = -1;\n            }\n\n            else\n#endif\n            {\n                sshift = 7 - (int)((row_info->width + 7) & 0x07);\n                dshift = 7 - (int)((final_width + 7) & 0x07);\n                s_start = 0;\n                s_end = 7;\n                s_inc = 1;\n            }\n\n            for (i = 0; i < row_info->width; i++)\n            {\n               v = (png_byte)((*sp >> sshift) & 0x01);\n               for (j = 0; j < jstop; j++)\n               {\n                  unsigned int tmp = *dp & (0x7f7f >> (7 - dshift));\n                  tmp |= v << dshift;\n                  *dp = (png_byte)(tmp & 0xff);\n\n                  if (dshift == s_end)\n                  {\n                     dshift = s_start;\n                     dp--;\n                  }\n\n                  else\n                     dshift += s_inc;\n               }\n\n               if (sshift == s_end)\n               {\n                  sshift = s_start;\n                  sp--;\n               }\n\n               else\n                  sshift += s_inc;\n            }\n            break;\n         }\n\n         case 2:\n         {\n            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);\n            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);\n            int sshift, dshift;\n            int s_start, s_end, s_inc;\n            int jstop = png_pass_inc[pass];\n            png_uint_32 i;\n\n#ifdef PNG_READ_PACKSWAP_SUPPORTED\n            if ((transformations & PNG_PACKSWAP) != 0)\n            {\n               sshift = (int)(((row_info->width + 3) & 0x03) << 1);\n               dshift = (int)(((final_width + 3) & 0x03) << 1);\n               s_start = 6;\n               s_end = 0;\n               s_inc = -2;\n            }\n\n            else\n#endif\n            {\n               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);\n               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);\n               s_start = 0;\n               s_end = 6;\n               s_inc = 2;\n            }\n\n            for (i = 0; i < row_info->width; i++)\n            {\n               png_byte v;\n               int j;\n\n               v = (png_byte)((*sp >> sshift) & 0x03);\n               for (j = 0; j < jstop; j++)\n               {\n                  unsigned int tmp = *dp & (0x3f3f >> (6 - dshift));\n                  tmp |= v << dshift;\n                  *dp = (png_byte)(tmp & 0xff);\n\n                  if (dshift == s_end)\n                  {\n                     dshift = s_start;\n                     dp--;\n                  }\n\n                  else\n                     dshift += s_inc;\n               }\n\n               if (sshift == s_end)\n               {\n                  sshift = s_start;\n                  sp--;\n               }\n\n               else\n                  sshift += s_inc;\n            }\n            break;\n         }\n\n         case 4:\n         {\n            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);\n            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);\n            int sshift, dshift;\n            int s_start, s_end, s_inc;\n            png_uint_32 i;\n            int jstop = png_pass_inc[pass];\n\n#ifdef PNG_READ_PACKSWAP_SUPPORTED\n            if ((transformations & PNG_PACKSWAP) != 0)\n            {\n               sshift = (int)(((row_info->width + 1) & 0x01) << 2);\n               dshift = (int)(((final_width + 1) & 0x01) << 2);\n               s_start = 4;\n               s_end = 0;\n               s_inc = -4;\n            }\n\n            else\n#endif\n            {\n               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);\n               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);\n               s_start = 0;\n               s_end = 4;\n               s_inc = 4;\n            }\n\n            for (i = 0; i < row_info->width; i++)\n            {\n               png_byte v = (png_byte)((*sp >> sshift) & 0x0f);\n               int j;\n\n               for (j = 0; j < jstop; j++)\n               {\n                  unsigned int tmp = *dp & (0xf0f >> (4 - dshift));\n                  tmp |= v << dshift;\n                  *dp = (png_byte)(tmp & 0xff);\n\n                  if (dshift == s_end)\n                  {\n                     dshift = s_start;\n                     dp--;\n                  }\n\n                  else\n                     dshift += s_inc;\n               }\n\n               if (sshift == s_end)\n               {\n                  sshift = s_start;\n                  sp--;\n               }\n\n               else\n                  sshift += s_inc;\n            }\n            break;\n         }\n\n         default:\n         {\n            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);\n\n            png_bytep sp = row + (png_size_t)(row_info->width - 1)\n                * pixel_bytes;\n\n            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;\n\n            int jstop = png_pass_inc[pass];\n            png_uint_32 i;\n\n            for (i = 0; i < row_info->width; i++)\n            {\n               png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */\n               int j;\n\n               memcpy(v, sp, pixel_bytes);\n\n               for (j = 0; j < jstop; j++)\n               {\n                  memcpy(dp, v, pixel_bytes);\n                  dp -= pixel_bytes;\n               }\n\n               sp -= pixel_bytes;\n            }\n            break;\n         }\n      }\n\n      row_info->width = final_width;\n      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);\n   }\n#ifndef PNG_READ_PACKSWAP_SUPPORTED\n   PNG_UNUSED(transformations)  /* Silence compiler warning */\n#endif\n}\n#endif /* READ_INTERLACING */\n\nstatic void\npng_read_filter_row_sub(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev_row)\n{\n   png_size_t i;\n   png_size_t istop = row_info->rowbytes;\n   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;\n   png_bytep rp = row + bpp;\n\n   PNG_UNUSED(prev_row)\n\n   for (i = bpp; i < istop; i++)\n   {\n      *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);\n      rp++;\n   }\n}\n\nstatic void\npng_read_filter_row_up(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev_row)\n{\n   png_size_t i;\n   png_size_t istop = row_info->rowbytes;\n   png_bytep rp = row;\n   png_const_bytep pp = prev_row;\n\n   for (i = 0; i < istop; i++)\n   {\n      *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);\n      rp++;\n   }\n}\n\nstatic void\npng_read_filter_row_avg(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev_row)\n{\n   png_size_t i;\n   png_bytep rp = row;\n   png_const_bytep pp = prev_row;\n   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;\n   png_size_t istop = row_info->rowbytes - bpp;\n\n   for (i = 0; i < bpp; i++)\n   {\n      *rp = (png_byte)(((int)(*rp) +\n         ((int)(*pp++) / 2 )) & 0xff);\n\n      rp++;\n   }\n\n   for (i = 0; i < istop; i++)\n   {\n      *rp = (png_byte)(((int)(*rp) +\n         (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);\n\n      rp++;\n   }\n}\n\nstatic void\npng_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev_row)\n{\n   png_bytep rp_end = row + row_info->rowbytes;\n   int a, c;\n\n   /* First pixel/byte */\n   c = *prev_row++;\n   a = *row + c;\n   *row++ = (png_byte)a;\n\n   /* Remainder */\n   while (row < rp_end)\n   {\n      int b, pa, pb, pc, p;\n\n      a &= 0xff; /* From previous iteration or start */\n      b = *prev_row++;\n\n      p = b - c;\n      pc = a - c;\n\n#ifdef PNG_USE_ABS\n      pa = abs(p);\n      pb = abs(pc);\n      pc = abs(p + pc);\n#else\n      pa = p < 0 ? -p : p;\n      pb = pc < 0 ? -pc : pc;\n      pc = (p + pc) < 0 ? -(p + pc) : p + pc;\n#endif\n\n      /* Find the best predictor, the least of pa, pb, pc favoring the earlier\n       * ones in the case of a tie.\n       */\n      if (pb < pa) pa = pb, a = b;\n      if (pc < pa) a = c;\n\n      /* Calculate the current pixel in a, and move the previous row pixel to c\n       * for the next time round the loop\n       */\n      c = b;\n      a += *row;\n      *row++ = (png_byte)a;\n   }\n}\n\nstatic void\npng_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,\n   png_const_bytep prev_row)\n{\n   int bpp = (row_info->pixel_depth + 7) >> 3;\n   png_bytep rp_end = row + bpp;\n\n   /* Process the first pixel in the row completely (this is the same as 'up'\n    * because there is only one candidate predictor for the first row).\n    */\n   while (row < rp_end)\n   {\n      int a = *row + *prev_row++;\n      *row++ = (png_byte)a;\n   }\n\n   /* Remainder */\n   rp_end += row_info->rowbytes - bpp;\n\n   while (row < rp_end)\n   {\n      int a, b, c, pa, pb, pc, p;\n\n      c = *(prev_row - bpp);\n      a = *(row - bpp);\n      b = *prev_row++;\n\n      p = b - c;\n      pc = a - c;\n\n#ifdef PNG_USE_ABS\n      pa = abs(p);\n      pb = abs(pc);\n      pc = abs(p + pc);\n#else\n      pa = p < 0 ? -p : p;\n      pb = pc < 0 ? -pc : pc;\n      pc = (p + pc) < 0 ? -(p + pc) : p + pc;\n#endif\n\n      if (pb < pa) pa = pb, a = b;\n      if (pc < pa) a = c;\n\n      a += *row;\n      *row++ = (png_byte)a;\n   }\n}\n\nstatic void\npng_init_filter_functions(png_structrp pp)\n   /* This function is called once for every PNG image (except for PNG images\n    * that only use PNG_FILTER_VALUE_NONE for all rows) to set the\n    * implementations required to reverse the filtering of PNG rows.  Reversing\n    * the filter is the first transformation performed on the row data.  It is\n    * performed in place, therefore an implementation can be selected based on\n    * the image pixel format.  If the implementation depends on image width then\n    * take care to ensure that it works correctly if the image is interlaced -\n    * interlacing causes the actual row width to vary.\n    */\n{\n   unsigned int bpp = (pp->pixel_depth + 7) >> 3;\n\n   pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub;\n   pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up;\n   pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg;\n   if (bpp == 1)\n      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =\n         png_read_filter_row_paeth_1byte_pixel;\n   else\n      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =\n         png_read_filter_row_paeth_multibyte_pixel;\n\n#ifdef PNG_FILTER_OPTIMIZATIONS\n   /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to\n    * call to install hardware optimizations for the above functions; simply\n    * replace whatever elements of the pp->read_filter[] array with a hardware\n    * specific (or, for that matter, generic) optimization.\n    *\n    * To see an example of this examine what configure.ac does when\n    * --enable-arm-neon is specified on the command line.\n    */\n   PNG_FILTER_OPTIMIZATIONS(pp, bpp);\n#endif\n}\n\nvoid /* PRIVATE */\npng_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row,\n   png_const_bytep prev_row, int filter)\n{\n   /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define\n    * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic\n    * implementations.  See png_init_filter_functions above.\n    */\n   if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST)\n   {\n      if (pp->read_filter[0] == NULL)\n         png_init_filter_functions(pp);\n\n      pp->read_filter[filter-1](row_info, row, prev_row);\n   }\n}\n\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\nvoid /* PRIVATE */\npng_read_IDAT_data(png_structrp png_ptr, png_bytep output,\n   png_alloc_size_t avail_out)\n{\n   /* Loop reading IDATs and decompressing the result into output[avail_out] */\n   png_ptr->zstream.next_out = output;\n   png_ptr->zstream.avail_out = 0; /* safety: set below */\n\n   if (output == NULL)\n      avail_out = 0;\n\n   do\n   {\n      int ret;\n      png_byte tmpbuf[PNG_INFLATE_BUF_SIZE];\n\n      if (png_ptr->zstream.avail_in == 0)\n      {\n         uInt avail_in;\n         png_bytep buffer;\n\n         while (png_ptr->idat_size == 0)\n         {\n            png_crc_finish(png_ptr, 0);\n\n            png_ptr->idat_size = png_read_chunk_header(png_ptr);\n            /* This is an error even in the 'check' case because the code just\n             * consumed a non-IDAT header.\n             */\n            if (png_ptr->chunk_name != png_IDAT)\n               png_error(png_ptr, \"Not enough image data\");\n         }\n\n         avail_in = png_ptr->IDAT_read_size;\n\n         if (avail_in > png_ptr->idat_size)\n            avail_in = (uInt)png_ptr->idat_size;\n\n         /* A PNG with a gradually increasing IDAT size will defeat this attempt\n          * to minimize memory usage by causing lots of re-allocs, but\n          * realistically doing IDAT_read_size re-allocs is not likely to be a\n          * big problem.\n          */\n         buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/);\n\n         png_crc_read(png_ptr, buffer, avail_in);\n         png_ptr->idat_size -= avail_in;\n\n         png_ptr->zstream.next_in = buffer;\n         png_ptr->zstream.avail_in = avail_in;\n      }\n\n      /* And set up the output side. */\n      if (output != NULL) /* standard read */\n      {\n         uInt out = ZLIB_IO_MAX;\n\n         if (out > avail_out)\n            out = (uInt)avail_out;\n\n         avail_out -= out;\n         png_ptr->zstream.avail_out = out;\n      }\n\n      else /* after last row, checking for end */\n      {\n         png_ptr->zstream.next_out = tmpbuf;\n         png_ptr->zstream.avail_out = (sizeof tmpbuf);\n      }\n\n      /* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the\n       * process.  If the LZ stream is truncated the sequential reader will\n       * terminally damage the stream, above, by reading the chunk header of the\n       * following chunk (it then exits with png_error).\n       *\n       * TODO: deal more elegantly with truncated IDAT lists.\n       */\n      ret = PNG_INFLATE(png_ptr, Z_NO_FLUSH);\n\n      /* Take the unconsumed output back. */\n      if (output != NULL)\n         avail_out += png_ptr->zstream.avail_out;\n\n      else /* avail_out counts the extra bytes */\n         avail_out += (sizeof tmpbuf) - png_ptr->zstream.avail_out;\n\n      png_ptr->zstream.avail_out = 0;\n\n      if (ret == Z_STREAM_END)\n      {\n         /* Do this for safety; we won't read any more into this row. */\n         png_ptr->zstream.next_out = NULL;\n\n         png_ptr->mode |= PNG_AFTER_IDAT;\n         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;\n\n         if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0)\n            png_chunk_benign_error(png_ptr, \"Extra compressed data\");\n         break;\n      }\n\n      if (ret != Z_OK)\n      {\n         png_zstream_error(png_ptr, ret);\n\n         if (output != NULL)\n            png_chunk_error(png_ptr, png_ptr->zstream.msg);\n\n         else /* checking */\n         {\n            png_chunk_benign_error(png_ptr, png_ptr->zstream.msg);\n            return;\n         }\n      }\n   } while (avail_out > 0);\n\n   if (avail_out > 0)\n   {\n      /* The stream ended before the image; this is the same as too few IDATs so\n       * should be handled the same way.\n       */\n      if (output != NULL)\n         png_error(png_ptr, \"Not enough image data\");\n\n      else /* the deflate stream contained extra data */\n         png_chunk_benign_error(png_ptr, \"Too much image data\");\n   }\n}\n\nvoid /* PRIVATE */\npng_read_finish_IDAT(png_structrp png_ptr)\n{\n   /* We don't need any more data and the stream should have ended, however the\n    * LZ end code may actually not have been processed.  In this case we must\n    * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk\n    * may still remain to be consumed.\n    */\n   if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)\n   {\n      /* The NULL causes png_read_IDAT_data to swallow any remaining bytes in\n       * the compressed stream, but the stream may be damaged too, so even after\n       * this call we may need to terminate the zstream ownership.\n       */\n      png_read_IDAT_data(png_ptr, NULL, 0);\n      png_ptr->zstream.next_out = NULL; /* safety */\n\n      /* Now clear everything out for safety; the following may not have been\n       * done.\n       */\n      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)\n      {\n         png_ptr->mode |= PNG_AFTER_IDAT;\n         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;\n      }\n   }\n\n   /* If the zstream has not been released do it now *and* terminate the reading\n    * of the final IDAT chunk.\n    */\n   if (png_ptr->zowner == png_IDAT)\n   {\n      /* Always do this; the pointers otherwise point into the read buffer. */\n      png_ptr->zstream.next_in = NULL;\n      png_ptr->zstream.avail_in = 0;\n\n      /* Now we no longer own the zstream. */\n      png_ptr->zowner = 0;\n\n      /* The slightly weird semantics of the sequential IDAT reading is that we\n       * are always in or at the end of an IDAT chunk, so we always need to do a\n       * crc_finish here.  If idat_size is non-zero we also need to read the\n       * spurious bytes at the end of the chunk now.\n       */\n      (void)png_crc_finish(png_ptr, png_ptr->idat_size);\n   }\n}\n\nvoid /* PRIVATE */\npng_read_finish_row(png_structrp png_ptr)\n{\n   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */\n\n   /* Start of interlace block */\n   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};\n\n   /* Offset to next interlace block */\n   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};\n\n   /* Start of interlace block in the y direction */\n   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};\n\n   /* Offset to next interlace block in the y direction */\n   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};\n\n   png_debug(1, \"in png_read_finish_row\");\n   png_ptr->row_number++;\n   if (png_ptr->row_number < png_ptr->num_rows)\n      return;\n\n   if (png_ptr->interlaced != 0)\n   {\n      png_ptr->row_number = 0;\n\n      /* TO DO: don't do this if prev_row isn't needed (requires\n       * read-ahead of the next row's filter byte.\n       */\n      memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);\n\n      do\n      {\n         png_ptr->pass++;\n\n         if (png_ptr->pass >= 7)\n            break;\n\n         png_ptr->iwidth = (png_ptr->width +\n            png_pass_inc[png_ptr->pass] - 1 -\n            png_pass_start[png_ptr->pass]) /\n            png_pass_inc[png_ptr->pass];\n\n         if ((png_ptr->transformations & PNG_INTERLACE) == 0)\n         {\n            png_ptr->num_rows = (png_ptr->height +\n                png_pass_yinc[png_ptr->pass] - 1 -\n                png_pass_ystart[png_ptr->pass]) /\n                png_pass_yinc[png_ptr->pass];\n         }\n\n         else  /* if (png_ptr->transformations & PNG_INTERLACE) */\n            break; /* libpng deinterlacing sees every row */\n\n      } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0);\n\n      if (png_ptr->pass < 7)\n         return;\n   }\n\n   /* Here after at the end of the last row of the last pass. */\n   png_read_finish_IDAT(png_ptr);\n}\n#endif /* SEQUENTIAL_READ */\n\nvoid /* PRIVATE */\npng_read_start_row(png_structrp png_ptr)\n{\n   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */\n\n   /* Start of interlace block */\n   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};\n\n   /* Offset to next interlace block */\n   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};\n\n   /* Start of interlace block in the y direction */\n   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};\n\n   /* Offset to next interlace block in the y direction */\n   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};\n\n   int max_pixel_depth;\n   png_size_t row_bytes;\n\n   png_debug(1, \"in png_read_start_row\");\n\n#ifdef PNG_READ_TRANSFORMS_SUPPORTED\n   png_init_read_transformations(png_ptr);\n#endif\n   if (png_ptr->interlaced != 0)\n   {\n      if ((png_ptr->transformations & PNG_INTERLACE) == 0)\n         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -\n             png_pass_ystart[0]) / png_pass_yinc[0];\n\n      else\n         png_ptr->num_rows = png_ptr->height;\n\n      png_ptr->iwidth = (png_ptr->width +\n          png_pass_inc[png_ptr->pass] - 1 -\n          png_pass_start[png_ptr->pass]) /\n          png_pass_inc[png_ptr->pass];\n   }\n\n   else\n   {\n      png_ptr->num_rows = png_ptr->height;\n      png_ptr->iwidth = png_ptr->width;\n   }\n\n   max_pixel_depth = png_ptr->pixel_depth;\n\n   /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of\n    * calculations to calculate the final pixel depth, then\n    * png_do_read_transforms actually does the transforms.  This means that the\n    * code which effectively calculates this value is actually repeated in three\n    * separate places.  They must all match.  Innocent changes to the order of\n    * transformations can and will break libpng in a way that causes memory\n    * overwrites.\n    *\n    * TODO: fix this.\n    */\n#ifdef PNG_READ_PACK_SUPPORTED\n   if ((png_ptr->transformations & PNG_PACK) != 0 && png_ptr->bit_depth < 8)\n      max_pixel_depth = 8;\n#endif\n\n#ifdef PNG_READ_EXPAND_SUPPORTED\n   if ((png_ptr->transformations & PNG_EXPAND) != 0)\n   {\n      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n      {\n         if (png_ptr->num_trans != 0)\n            max_pixel_depth = 32;\n\n         else\n            max_pixel_depth = 24;\n      }\n\n      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)\n      {\n         if (max_pixel_depth < 8)\n            max_pixel_depth = 8;\n\n         if (png_ptr->num_trans != 0)\n            max_pixel_depth *= 2;\n      }\n\n      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)\n      {\n         if (png_ptr->num_trans != 0)\n         {\n            max_pixel_depth *= 4;\n            max_pixel_depth /= 3;\n         }\n      }\n   }\n#endif\n\n#ifdef PNG_READ_EXPAND_16_SUPPORTED\n   if ((png_ptr->transformations & PNG_EXPAND_16) != 0)\n   {\n#  ifdef PNG_READ_EXPAND_SUPPORTED\n      /* In fact it is an error if it isn't supported, but checking is\n       * the safe way.\n       */\n      if ((png_ptr->transformations & PNG_EXPAND) != 0)\n      {\n         if (png_ptr->bit_depth < 16)\n            max_pixel_depth *= 2;\n      }\n      else\n#  endif\n      png_ptr->transformations &= ~PNG_EXPAND_16;\n   }\n#endif\n\n#ifdef PNG_READ_FILLER_SUPPORTED\n   if ((png_ptr->transformations & (PNG_FILLER)) != 0)\n   {\n      if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)\n      {\n         if (max_pixel_depth <= 8)\n            max_pixel_depth = 16;\n\n         else\n            max_pixel_depth = 32;\n      }\n\n      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB ||\n         png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n      {\n         if (max_pixel_depth <= 32)\n            max_pixel_depth = 32;\n\n         else\n            max_pixel_depth = 64;\n      }\n   }\n#endif\n\n#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\n   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)\n   {\n      if (\n#ifdef PNG_READ_EXPAND_SUPPORTED\n          (png_ptr->num_trans != 0 &&\n          (png_ptr->transformations & PNG_EXPAND) != 0) ||\n#endif\n#ifdef PNG_READ_FILLER_SUPPORTED\n          (png_ptr->transformations & (PNG_FILLER)) != 0 ||\n#endif\n          png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n      {\n         if (max_pixel_depth <= 16)\n            max_pixel_depth = 32;\n\n         else\n            max_pixel_depth = 64;\n      }\n\n      else\n      {\n         if (max_pixel_depth <= 8)\n         {\n            if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n               max_pixel_depth = 32;\n\n            else\n               max_pixel_depth = 24;\n         }\n\n         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n            max_pixel_depth = 64;\n\n         else\n            max_pixel_depth = 48;\n      }\n   }\n#endif\n\n#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \\\ndefined(PNG_USER_TRANSFORM_PTR_SUPPORTED)\n   if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)\n   {\n      int user_pixel_depth = png_ptr->user_transform_depth *\n         png_ptr->user_transform_channels;\n\n      if (user_pixel_depth > max_pixel_depth)\n         max_pixel_depth = user_pixel_depth;\n   }\n#endif\n\n   /* This value is stored in png_struct and double checked in the row read\n    * code.\n    */\n   png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth;\n   png_ptr->transformed_pixel_depth = 0; /* calculated on demand */\n\n   /* Align the width on the next larger 8 pixels.  Mainly used\n    * for interlacing\n    */\n   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));\n   /* Calculate the maximum bytes needed, adding a byte and a pixel\n    * for safety's sake\n    */\n   row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +\n       1 + ((max_pixel_depth + 7) >> 3);\n\n#ifdef PNG_MAX_MALLOC_64K\n   if (row_bytes > (png_uint_32)65536L)\n      png_error(png_ptr, \"This image requires a row greater than 64KB\");\n#endif\n\n   if (row_bytes + 48 > png_ptr->old_big_row_buf_size)\n   {\n     png_free(png_ptr, png_ptr->big_row_buf);\n     png_free(png_ptr, png_ptr->big_prev_row);\n\n     if (png_ptr->interlaced != 0)\n        png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,\n            row_bytes + 48);\n\n     else\n        png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);\n\n     png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);\n\n#ifdef PNG_ALIGNED_MEMORY_SUPPORTED\n     /* Use 16-byte aligned memory for row_buf with at least 16 bytes\n      * of padding before and after row_buf; treat prev_row similarly.\n      * NOTE: the alignment is to the start of the pixels, one beyond the start\n      * of the buffer, because of the filter byte.  Prior to libpng 1.5.6 this\n      * was incorrect; the filter byte was aligned, which had the exact\n      * opposite effect of that intended.\n      */\n     {\n        png_bytep temp = png_ptr->big_row_buf + 32;\n        int extra = (int)((temp - (png_bytep)0) & 0x0f);\n        png_ptr->row_buf = temp - extra - 1/*filter byte*/;\n\n        temp = png_ptr->big_prev_row + 32;\n        extra = (int)((temp - (png_bytep)0) & 0x0f);\n        png_ptr->prev_row = temp - extra - 1/*filter byte*/;\n     }\n\n#else\n     /* Use 31 bytes of padding before and 17 bytes after row_buf. */\n     png_ptr->row_buf = png_ptr->big_row_buf + 31;\n     png_ptr->prev_row = png_ptr->big_prev_row + 31;\n#endif\n     png_ptr->old_big_row_buf_size = row_bytes + 48;\n   }\n\n#ifdef PNG_MAX_MALLOC_64K\n   if (png_ptr->rowbytes > 65535)\n      png_error(png_ptr, \"This image requires a row greater than 64KB\");\n\n#endif\n   if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1))\n      png_error(png_ptr, \"Row has too many bytes to allocate in memory\");\n\n   memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);\n\n   png_debug1(3, \"width = %u,\", png_ptr->width);\n   png_debug1(3, \"height = %u,\", png_ptr->height);\n   png_debug1(3, \"iwidth = %u,\", png_ptr->iwidth);\n   png_debug1(3, \"num_rows = %u,\", png_ptr->num_rows);\n   png_debug1(3, \"rowbytes = %lu,\", (unsigned long)png_ptr->rowbytes);\n   png_debug1(3, \"irowbytes = %lu\",\n       (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);\n\n   /* The sequential reader needs a buffer for IDAT, but the progressive reader\n    * does not, so free the read buffer now regardless; the sequential reader\n    * reallocates it on demand.\n    */\n   if (png_ptr->read_buffer != 0)\n   {\n      png_bytep buffer = png_ptr->read_buffer;\n\n      png_ptr->read_buffer_size = 0;\n      png_ptr->read_buffer = NULL;\n      png_free(png_ptr, buffer);\n   }\n\n   /* Finally claim the zstream for the inflate of the IDAT data, use the bits\n    * value from the stream (note that this will result in a fatal error if the\n    * IDAT stream has a bogus deflate header window_bits value, but this should\n    * not be happening any longer!)\n    */\n   if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK)\n      png_error(png_ptr, png_ptr->zstream.msg);\n\n   png_ptr->flags |= PNG_FLAG_ROW_INIT;\n}\n#endif /* READ */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngset.c",
    "content": "\n/* pngset.c - storage of image information into info struct\n *\n * Last changed in libpng 1.6.21 [(PENDING RELEASE)]\n * Copyright (c) 1998-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * The functions here are used during reads to store data from the file\n * into the info struct, and during writes to store application data\n * into the info struct for writing into the file.  This abstracts the\n * info struct and allows us to change the structure in the future.\n */\n\n#include \"pngpriv.h\"\n\n#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)\n\n#ifdef PNG_bKGD_SUPPORTED\nvoid PNGAPI\npng_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_const_color_16p background)\n{\n   png_debug1(1, \"in %s storage function\", \"bKGD\");\n\n   if (png_ptr == NULL || info_ptr == NULL || background == NULL)\n      return;\n\n   info_ptr->background = *background;\n   info_ptr->valid |= PNG_INFO_bKGD;\n}\n#endif\n\n#ifdef PNG_cHRM_SUPPORTED\nvoid PNGFAPI\npng_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,\n    png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,\n    png_fixed_point blue_x, png_fixed_point blue_y)\n{\n   png_xy xy;\n\n   png_debug1(1, \"in %s storage function\", \"cHRM fixed\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   xy.redx = red_x;\n   xy.redy = red_y;\n   xy.greenx = green_x;\n   xy.greeny = green_y;\n   xy.bluex = blue_x;\n   xy.bluey = blue_y;\n   xy.whitex = white_x;\n   xy.whitey = white_y;\n\n   if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy,\n       2/* override with app values*/) != 0)\n      info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;\n\n   png_colorspace_sync_info(png_ptr, info_ptr);\n}\n\nvoid PNGFAPI\npng_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_fixed_point int_red_X, png_fixed_point int_red_Y,\n    png_fixed_point int_red_Z, png_fixed_point int_green_X,\n    png_fixed_point int_green_Y, png_fixed_point int_green_Z,\n    png_fixed_point int_blue_X, png_fixed_point int_blue_Y,\n    png_fixed_point int_blue_Z)\n{\n   png_XYZ XYZ;\n\n   png_debug1(1, \"in %s storage function\", \"cHRM XYZ fixed\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   XYZ.red_X = int_red_X;\n   XYZ.red_Y = int_red_Y;\n   XYZ.red_Z = int_red_Z;\n   XYZ.green_X = int_green_X;\n   XYZ.green_Y = int_green_Y;\n   XYZ.green_Z = int_green_Z;\n   XYZ.blue_X = int_blue_X;\n   XYZ.blue_Y = int_blue_Y;\n   XYZ.blue_Z = int_blue_Z;\n\n   if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace,\n       &XYZ, 2) != 0)\n      info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;\n\n   png_colorspace_sync_info(png_ptr, info_ptr);\n}\n\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\nvoid PNGAPI\npng_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,\n    double white_x, double white_y, double red_x, double red_y,\n    double green_x, double green_y, double blue_x, double blue_y)\n{\n   png_set_cHRM_fixed(png_ptr, info_ptr,\n      png_fixed(png_ptr, white_x, \"cHRM White X\"),\n      png_fixed(png_ptr, white_y, \"cHRM White Y\"),\n      png_fixed(png_ptr, red_x, \"cHRM Red X\"),\n      png_fixed(png_ptr, red_y, \"cHRM Red Y\"),\n      png_fixed(png_ptr, green_x, \"cHRM Green X\"),\n      png_fixed(png_ptr, green_y, \"cHRM Green Y\"),\n      png_fixed(png_ptr, blue_x, \"cHRM Blue X\"),\n      png_fixed(png_ptr, blue_y, \"cHRM Blue Y\"));\n}\n\nvoid PNGAPI\npng_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,\n    double red_Y, double red_Z, double green_X, double green_Y, double green_Z,\n    double blue_X, double blue_Y, double blue_Z)\n{\n   png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,\n      png_fixed(png_ptr, red_X, \"cHRM Red X\"),\n      png_fixed(png_ptr, red_Y, \"cHRM Red Y\"),\n      png_fixed(png_ptr, red_Z, \"cHRM Red Z\"),\n      png_fixed(png_ptr, green_X, \"cHRM Green X\"),\n      png_fixed(png_ptr, green_Y, \"cHRM Green Y\"),\n      png_fixed(png_ptr, green_Z, \"cHRM Green Z\"),\n      png_fixed(png_ptr, blue_X, \"cHRM Blue X\"),\n      png_fixed(png_ptr, blue_Y, \"cHRM Blue Y\"),\n      png_fixed(png_ptr, blue_Z, \"cHRM Blue Z\"));\n}\n#  endif /* FLOATING_POINT */\n\n#endif /* cHRM */\n\n#ifdef PNG_gAMA_SUPPORTED\nvoid PNGFAPI\npng_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_fixed_point file_gamma)\n{\n   png_debug1(1, \"in %s storage function\", \"gAMA\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma);\n   png_colorspace_sync_info(png_ptr, info_ptr);\n}\n\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\nvoid PNGAPI\npng_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma)\n{\n   png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,\n       \"png_set_gAMA\"));\n}\n#  endif\n#endif\n\n#ifdef PNG_hIST_SUPPORTED\nvoid PNGAPI\npng_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_const_uint_16p hist)\n{\n   int i;\n\n   png_debug1(1, \"in %s storage function\", \"hIST\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   if (info_ptr->num_palette == 0 || info_ptr->num_palette\n       > PNG_MAX_PALETTE_LENGTH)\n   {\n      png_warning(png_ptr,\n          \"Invalid palette size, hIST allocation skipped\");\n\n      return;\n   }\n\n   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);\n\n   /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in\n    * version 1.2.1\n    */\n   info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr,\n       PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16))));\n\n   if (info_ptr->hist == NULL)\n   {\n      png_warning(png_ptr, \"Insufficient memory for hIST chunk data\");\n\n      return;\n   }\n\n   info_ptr->free_me |= PNG_FREE_HIST;\n\n   for (i = 0; i < info_ptr->num_palette; i++)\n      info_ptr->hist[i] = hist[i];\n\n   info_ptr->valid |= PNG_INFO_hIST;\n}\n#endif\n\nvoid PNGAPI\npng_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_uint_32 width, png_uint_32 height, int bit_depth,\n    int color_type, int interlace_type, int compression_type,\n    int filter_type)\n{\n   png_debug1(1, \"in %s storage function\", \"IHDR\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   info_ptr->width = width;\n   info_ptr->height = height;\n   info_ptr->bit_depth = (png_byte)bit_depth;\n   info_ptr->color_type = (png_byte)color_type;\n   info_ptr->compression_type = (png_byte)compression_type;\n   info_ptr->filter_type = (png_byte)filter_type;\n   info_ptr->interlace_type = (png_byte)interlace_type;\n\n   png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,\n       info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,\n       info_ptr->compression_type, info_ptr->filter_type);\n\n   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n      info_ptr->channels = 1;\n\n   else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)\n      info_ptr->channels = 3;\n\n   else\n      info_ptr->channels = 1;\n\n   if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)\n      info_ptr->channels++;\n\n   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);\n\n   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);\n}\n\n#ifdef PNG_oFFs_SUPPORTED\nvoid PNGAPI\npng_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_int_32 offset_x, png_int_32 offset_y, int unit_type)\n{\n   png_debug1(1, \"in %s storage function\", \"oFFs\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   info_ptr->x_offset = offset_x;\n   info_ptr->y_offset = offset_y;\n   info_ptr->offset_unit_type = (png_byte)unit_type;\n   info_ptr->valid |= PNG_INFO_oFFs;\n}\n#endif\n\n#ifdef PNG_pCAL_SUPPORTED\nvoid PNGAPI\npng_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,\n    int nparams, png_const_charp units, png_charpp params)\n{\n   png_size_t length;\n   int i;\n\n   png_debug1(1, \"in %s storage function\", \"pCAL\");\n\n   if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL\n       || (nparams > 0 && params == NULL))\n      return;\n\n   length = strlen(purpose) + 1;\n   png_debug1(3, \"allocating purpose for info (%lu bytes)\",\n       (unsigned long)length);\n\n   /* TODO: validate format of calibration name and unit name */\n\n   /* Check that the type matches the specification. */\n   if (type < 0 || type > 3)\n      png_error(png_ptr, \"Invalid pCAL equation type\");\n\n   if (nparams < 0 || nparams > 255)\n      png_error(png_ptr, \"Invalid pCAL parameter count\");\n\n   /* Validate params[nparams] */\n   for (i=0; i<nparams; ++i)\n   {\n      if (params[i] == NULL ||\n          !png_check_fp_string(params[i], strlen(params[i])))\n         png_error(png_ptr, \"Invalid format for pCAL parameter\");\n   }\n\n   info_ptr->pcal_purpose = png_voidcast(png_charp,\n       png_malloc_warn(png_ptr, length));\n\n   if (info_ptr->pcal_purpose == NULL)\n   {\n      png_warning(png_ptr, \"Insufficient memory for pCAL purpose\");\n\n      return;\n   }\n\n   memcpy(info_ptr->pcal_purpose, purpose, length);\n\n   png_debug(3, \"storing X0, X1, type, and nparams in info\");\n   info_ptr->pcal_X0 = X0;\n   info_ptr->pcal_X1 = X1;\n   info_ptr->pcal_type = (png_byte)type;\n   info_ptr->pcal_nparams = (png_byte)nparams;\n\n   length = strlen(units) + 1;\n   png_debug1(3, \"allocating units for info (%lu bytes)\",\n     (unsigned long)length);\n\n   info_ptr->pcal_units = png_voidcast(png_charp,\n      png_malloc_warn(png_ptr, length));\n\n   if (info_ptr->pcal_units == NULL)\n   {\n      png_warning(png_ptr, \"Insufficient memory for pCAL units\");\n\n      return;\n   }\n\n   memcpy(info_ptr->pcal_units, units, length);\n\n   info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,\n       (png_size_t)((nparams + 1) * (sizeof (png_charp)))));\n\n   if (info_ptr->pcal_params == NULL)\n   {\n      png_warning(png_ptr, \"Insufficient memory for pCAL params\");\n\n      return;\n   }\n\n   memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp)));\n\n   for (i = 0; i < nparams; i++)\n   {\n      length = strlen(params[i]) + 1;\n      png_debug2(3, \"allocating parameter %d for info (%lu bytes)\", i,\n          (unsigned long)length);\n\n      info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);\n\n      if (info_ptr->pcal_params[i] == NULL)\n      {\n         png_warning(png_ptr, \"Insufficient memory for pCAL parameter\");\n\n         return;\n      }\n\n      memcpy(info_ptr->pcal_params[i], params[i], length);\n   }\n\n   info_ptr->valid |= PNG_INFO_pCAL;\n   info_ptr->free_me |= PNG_FREE_PCAL;\n}\n#endif\n\n#ifdef PNG_sCAL_SUPPORTED\nvoid PNGAPI\npng_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,\n    int unit, png_const_charp swidth, png_const_charp sheight)\n{\n   png_size_t lengthw = 0, lengthh = 0;\n\n   png_debug1(1, \"in %s storage function\", \"sCAL\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   /* Double check the unit (should never get here with an invalid\n    * unit unless this is an API call.)\n    */\n   if (unit != 1 && unit != 2)\n      png_error(png_ptr, \"Invalid sCAL unit\");\n\n   if (swidth == NULL || (lengthw = strlen(swidth)) == 0 ||\n       swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw))\n      png_error(png_ptr, \"Invalid sCAL width\");\n\n   if (sheight == NULL || (lengthh = strlen(sheight)) == 0 ||\n       sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))\n      png_error(png_ptr, \"Invalid sCAL height\");\n\n   info_ptr->scal_unit = (png_byte)unit;\n\n   ++lengthw;\n\n   png_debug1(3, \"allocating unit for info (%u bytes)\", (unsigned int)lengthw);\n\n   info_ptr->scal_s_width = png_voidcast(png_charp,\n      png_malloc_warn(png_ptr, lengthw));\n\n   if (info_ptr->scal_s_width == NULL)\n   {\n      png_warning(png_ptr, \"Memory allocation failed while processing sCAL\");\n\n      return;\n   }\n\n   memcpy(info_ptr->scal_s_width, swidth, lengthw);\n\n   ++lengthh;\n\n   png_debug1(3, \"allocating unit for info (%u bytes)\", (unsigned int)lengthh);\n\n   info_ptr->scal_s_height = png_voidcast(png_charp,\n      png_malloc_warn(png_ptr, lengthh));\n\n   if (info_ptr->scal_s_height == NULL)\n   {\n      png_free (png_ptr, info_ptr->scal_s_width);\n      info_ptr->scal_s_width = NULL;\n\n      png_warning(png_ptr, \"Memory allocation failed while processing sCAL\");\n\n      return;\n   }\n\n   memcpy(info_ptr->scal_s_height, sheight, lengthh);\n\n   info_ptr->valid |= PNG_INFO_sCAL;\n   info_ptr->free_me |= PNG_FREE_SCAL;\n}\n\n#  ifdef PNG_FLOATING_POINT_SUPPORTED\nvoid PNGAPI\npng_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit,\n    double width, double height)\n{\n   png_debug1(1, \"in %s storage function\", \"sCAL\");\n\n   /* Check the arguments. */\n   if (width <= 0)\n      png_warning(png_ptr, \"Invalid sCAL width ignored\");\n\n   else if (height <= 0)\n      png_warning(png_ptr, \"Invalid sCAL height ignored\");\n\n   else\n   {\n      /* Convert 'width' and 'height' to ASCII. */\n      char swidth[PNG_sCAL_MAX_DIGITS+1];\n      char sheight[PNG_sCAL_MAX_DIGITS+1];\n\n      png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width,\n         PNG_sCAL_PRECISION);\n      png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,\n         PNG_sCAL_PRECISION);\n\n      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);\n   }\n}\n#  endif\n\n#  ifdef PNG_FIXED_POINT_SUPPORTED\nvoid PNGAPI\npng_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit,\n    png_fixed_point width, png_fixed_point height)\n{\n   png_debug1(1, \"in %s storage function\", \"sCAL\");\n\n   /* Check the arguments. */\n   if (width <= 0)\n      png_warning(png_ptr, \"Invalid sCAL width ignored\");\n\n   else if (height <= 0)\n      png_warning(png_ptr, \"Invalid sCAL height ignored\");\n\n   else\n   {\n      /* Convert 'width' and 'height' to ASCII. */\n      char swidth[PNG_sCAL_MAX_DIGITS+1];\n      char sheight[PNG_sCAL_MAX_DIGITS+1];\n\n      png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width);\n      png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height);\n\n      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);\n   }\n}\n#  endif\n#endif\n\n#ifdef PNG_pHYs_SUPPORTED\nvoid PNGAPI\npng_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_uint_32 res_x, png_uint_32 res_y, int unit_type)\n{\n   png_debug1(1, \"in %s storage function\", \"pHYs\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   info_ptr->x_pixels_per_unit = res_x;\n   info_ptr->y_pixels_per_unit = res_y;\n   info_ptr->phys_unit_type = (png_byte)unit_type;\n   info_ptr->valid |= PNG_INFO_pHYs;\n}\n#endif\n\nvoid PNGAPI\npng_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,\n    png_const_colorp palette, int num_palette)\n{\n\n   png_uint_32 max_palette_length;\n\n   png_debug1(1, \"in %s storage function\", \"PLTE\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?\n      (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;\n\n   if (num_palette < 0 || num_palette > (int) max_palette_length)\n   {\n      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n         png_error(png_ptr, \"Invalid palette length\");\n\n      else\n      {\n         png_warning(png_ptr, \"Invalid palette length\");\n\n         return;\n      }\n   }\n\n   if ((num_palette > 0 && palette == NULL) ||\n      (num_palette == 0\n#        ifdef PNG_MNG_FEATURES_SUPPORTED\n            && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0\n#        endif\n      ))\n   {\n      png_error(png_ptr, \"Invalid palette\");\n   }\n\n   /* It may not actually be necessary to set png_ptr->palette here;\n    * we do it for backward compatibility with the way the png_handle_tRNS\n    * function used to do the allocation.\n    *\n    * 1.6.0: the above statement appears to be incorrect; something has to set\n    * the palette inside png_struct on read.\n    */\n   png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);\n\n   /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead\n    * of num_palette entries, in case of an invalid PNG file or incorrect\n    * call to png_set_PLTE() with too-large sample values.\n    */\n   png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,\n       PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));\n\n   if (num_palette > 0)\n      memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color)));\n   info_ptr->palette = png_ptr->palette;\n   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;\n\n   info_ptr->free_me |= PNG_FREE_PLTE;\n\n   info_ptr->valid |= PNG_INFO_PLTE;\n}\n\n#ifdef PNG_sBIT_SUPPORTED\nvoid PNGAPI\npng_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_const_color_8p sig_bit)\n{\n   png_debug1(1, \"in %s storage function\", \"sBIT\");\n\n   if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL)\n      return;\n\n   info_ptr->sig_bit = *sig_bit;\n   info_ptr->valid |= PNG_INFO_sBIT;\n}\n#endif\n\n#ifdef PNG_sRGB_SUPPORTED\nvoid PNGAPI\npng_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent)\n{\n   png_debug1(1, \"in %s storage function\", \"sRGB\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent);\n   png_colorspace_sync_info(png_ptr, info_ptr);\n}\n\nvoid PNGAPI\npng_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,\n    int srgb_intent)\n{\n   png_debug1(1, \"in %s storage function\", \"sRGB_gAMA_and_cHRM\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace,\n       srgb_intent) != 0)\n   {\n      /* This causes the gAMA and cHRM to be written too */\n      info_ptr->colorspace.flags |=\n         PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;\n   }\n\n   png_colorspace_sync_info(png_ptr, info_ptr);\n}\n#endif /* sRGB */\n\n\n#ifdef PNG_iCCP_SUPPORTED\nvoid PNGAPI\npng_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_const_charp name, int compression_type,\n    png_const_bytep profile, png_uint_32 proflen)\n{\n   png_charp new_iccp_name;\n   png_bytep new_iccp_profile;\n   png_size_t length;\n\n   png_debug1(1, \"in %s storage function\", \"iCCP\");\n\n   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)\n      return;\n\n   if (compression_type != PNG_COMPRESSION_TYPE_BASE)\n      png_app_error(png_ptr, \"Invalid iCCP compression method\");\n\n   /* Set the colorspace first because this validates the profile; do not\n    * override previously set app cHRM or gAMA here (because likely as not the\n    * application knows better than libpng what the correct values are.)  Pass\n    * the info_ptr color_type field to png_colorspace_set_ICC because in the\n    * write case it has not yet been stored in png_ptr.\n    */\n   {\n      int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,\n         proflen, profile, info_ptr->color_type);\n\n      png_colorspace_sync_info(png_ptr, info_ptr);\n\n      /* Don't do any of the copying if the profile was bad, or inconsistent. */\n      if (result == 0)\n         return;\n\n      /* But do write the gAMA and cHRM chunks from the profile. */\n      info_ptr->colorspace.flags |=\n         PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;\n   }\n\n   length = strlen(name)+1;\n   new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length));\n\n   if (new_iccp_name == NULL)\n   {\n      png_benign_error(png_ptr, \"Insufficient memory to process iCCP chunk\");\n\n      return;\n   }\n\n   memcpy(new_iccp_name, name, length);\n   new_iccp_profile = png_voidcast(png_bytep,\n      png_malloc_warn(png_ptr, proflen));\n\n   if (new_iccp_profile == NULL)\n   {\n      png_free(png_ptr, new_iccp_name);\n      png_benign_error(png_ptr,\n          \"Insufficient memory to process iCCP profile\");\n\n      return;\n   }\n\n   memcpy(new_iccp_profile, profile, proflen);\n\n   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);\n\n   info_ptr->iccp_proflen = proflen;\n   info_ptr->iccp_name = new_iccp_name;\n   info_ptr->iccp_profile = new_iccp_profile;\n   info_ptr->free_me |= PNG_FREE_ICCP;\n   info_ptr->valid |= PNG_INFO_iCCP;\n}\n#endif\n\n#ifdef PNG_TEXT_SUPPORTED\nvoid PNGAPI\npng_set_text(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_const_textp text_ptr, int num_text)\n{\n   int ret;\n   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);\n\n   if (ret != 0)\n      png_error(png_ptr, \"Insufficient memory to store text\");\n}\n\nint /* PRIVATE */\npng_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_const_textp text_ptr, int num_text)\n{\n   int i;\n\n   png_debug1(1, \"in %lx storage function\", png_ptr == NULL ? 0xabadca11U :\n      (unsigned long)png_ptr->chunk_name);\n\n   if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL)\n      return(0);\n\n   /* Make sure we have enough space in the \"text\" array in info_struct\n    * to hold all of the incoming text_ptr objects.  This compare can't overflow\n    * because max_text >= num_text (anyway, subtract of two positive integers\n    * can't overflow in any case.)\n    */\n   if (num_text > info_ptr->max_text - info_ptr->num_text)\n   {\n      int old_num_text = info_ptr->num_text;\n      int max_text;\n      png_textp new_text = NULL;\n\n      /* Calculate an appropriate max_text, checking for overflow. */\n      max_text = old_num_text;\n      if (num_text <= INT_MAX - max_text)\n      {\n         max_text += num_text;\n\n         /* Round up to a multiple of 8 */\n         if (max_text < INT_MAX-8)\n            max_text = (max_text + 8) & ~0x7;\n\n         else\n            max_text = INT_MAX;\n\n         /* Now allocate a new array and copy the old members in; this does all\n          * the overflow checks.\n          */\n         new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,\n            info_ptr->text, old_num_text, max_text-old_num_text,\n            sizeof *new_text));\n      }\n\n      if (new_text == NULL)\n      {\n         png_chunk_report(png_ptr, \"too many text chunks\",\n            PNG_CHUNK_WRITE_ERROR);\n\n         return 1;\n      }\n\n      png_free(png_ptr, info_ptr->text);\n\n      info_ptr->text = new_text;\n      info_ptr->free_me |= PNG_FREE_TEXT;\n      info_ptr->max_text = max_text;\n      /* num_text is adjusted below as the entries are copied in */\n\n      png_debug1(3, \"allocated %d entries for info_ptr->text\", max_text);\n   }\n\n   for (i = 0; i < num_text; i++)\n   {\n      size_t text_length, key_len;\n      size_t lang_len, lang_key_len;\n      png_textp textp = &(info_ptr->text[info_ptr->num_text]);\n\n      if (text_ptr[i].key == NULL)\n          continue;\n\n      if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||\n          text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)\n      {\n         png_chunk_report(png_ptr, \"text compression mode is out of range\",\n            PNG_CHUNK_WRITE_ERROR);\n         continue;\n      }\n\n      key_len = strlen(text_ptr[i].key);\n\n      if (text_ptr[i].compression <= 0)\n      {\n         lang_len = 0;\n         lang_key_len = 0;\n      }\n\n      else\n#  ifdef PNG_iTXt_SUPPORTED\n      {\n         /* Set iTXt data */\n\n         if (text_ptr[i].lang != NULL)\n            lang_len = strlen(text_ptr[i].lang);\n\n         else\n            lang_len = 0;\n\n         if (text_ptr[i].lang_key != NULL)\n            lang_key_len = strlen(text_ptr[i].lang_key);\n\n         else\n            lang_key_len = 0;\n      }\n#  else /* iTXt */\n      {\n         png_chunk_report(png_ptr, \"iTXt chunk not supported\",\n            PNG_CHUNK_WRITE_ERROR);\n         continue;\n      }\n#  endif\n\n      if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\\0')\n      {\n         text_length = 0;\n#  ifdef PNG_iTXt_SUPPORTED\n         if (text_ptr[i].compression > 0)\n            textp->compression = PNG_ITXT_COMPRESSION_NONE;\n\n         else\n#  endif\n            textp->compression = PNG_TEXT_COMPRESSION_NONE;\n      }\n\n      else\n      {\n         text_length = strlen(text_ptr[i].text);\n         textp->compression = text_ptr[i].compression;\n      }\n\n      textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr,\n          key_len + text_length + lang_len + lang_key_len + 4));\n\n      if (textp->key == NULL)\n      {\n         png_chunk_report(png_ptr, \"text chunk: out of memory\",\n               PNG_CHUNK_WRITE_ERROR);\n\n         return 1;\n      }\n\n      png_debug2(2, \"Allocated %lu bytes at %p in png_set_text\",\n          (unsigned long)(png_uint_32)\n          (key_len + lang_len + lang_key_len + text_length + 4),\n          textp->key);\n\n      memcpy(textp->key, text_ptr[i].key, key_len);\n      *(textp->key + key_len) = '\\0';\n\n      if (text_ptr[i].compression > 0)\n      {\n         textp->lang = textp->key + key_len + 1;\n         memcpy(textp->lang, text_ptr[i].lang, lang_len);\n         *(textp->lang + lang_len) = '\\0';\n         textp->lang_key = textp->lang + lang_len + 1;\n         memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);\n         *(textp->lang_key + lang_key_len) = '\\0';\n         textp->text = textp->lang_key + lang_key_len + 1;\n      }\n\n      else\n      {\n         textp->lang=NULL;\n         textp->lang_key=NULL;\n         textp->text = textp->key + key_len + 1;\n      }\n\n      if (text_length != 0)\n         memcpy(textp->text, text_ptr[i].text, text_length);\n\n      *(textp->text + text_length) = '\\0';\n\n#  ifdef PNG_iTXt_SUPPORTED\n      if (textp->compression > 0)\n      {\n         textp->text_length = 0;\n         textp->itxt_length = text_length;\n      }\n\n      else\n#  endif\n      {\n         textp->text_length = text_length;\n         textp->itxt_length = 0;\n      }\n\n      info_ptr->num_text++;\n      png_debug1(3, \"transferred text chunk %d\", info_ptr->num_text);\n   }\n\n   return(0);\n}\n#endif\n\n#ifdef PNG_tIME_SUPPORTED\nvoid PNGAPI\npng_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_const_timep mod_time)\n{\n   png_debug1(1, \"in %s storage function\", \"tIME\");\n\n   if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL ||\n       (png_ptr->mode & PNG_WROTE_tIME) != 0)\n      return;\n\n   if (mod_time->month == 0   || mod_time->month > 12  ||\n       mod_time->day   == 0   || mod_time->day   > 31  ||\n       mod_time->hour  > 23   || mod_time->minute > 59 ||\n       mod_time->second > 60)\n   {\n      png_warning(png_ptr, \"Ignoring invalid time value\");\n\n      return;\n   }\n\n   info_ptr->mod_time = *mod_time;\n   info_ptr->valid |= PNG_INFO_tIME;\n}\n#endif\n\n#ifdef PNG_tRNS_SUPPORTED\nvoid PNGAPI\npng_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,\n    png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color)\n{\n   png_debug1(1, \"in %s storage function\", \"tRNS\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n\n      return;\n\n   if (trans_alpha != NULL)\n   {\n       /* It may not actually be necessary to set png_ptr->trans_alpha here;\n        * we do it for backward compatibility with the way the png_handle_tRNS\n        * function used to do the allocation.\n        *\n        * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively\n        * relies on png_set_tRNS storing the information in png_struct\n        * (otherwise it won't be there for the code in pngrtran.c).\n        */\n\n       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);\n\n       /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */\n       png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep,\n         png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));\n\n       if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)\n          memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);\n   }\n\n   if (trans_color != NULL)\n   {\n#ifdef PNG_WARNINGS_SUPPORTED\n      if (info_ptr->bit_depth < 16)\n      {\n         int sample_max = (1 << info_ptr->bit_depth) - 1;\n\n         if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&\n             trans_color->gray > sample_max) ||\n             (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&\n             (trans_color->red > sample_max ||\n             trans_color->green > sample_max ||\n             trans_color->blue > sample_max)))\n            png_warning(png_ptr,\n               \"tRNS chunk has out-of-range samples for bit_depth\");\n      }\n#endif\n\n      info_ptr->trans_color = *trans_color;\n\n      if (num_trans == 0)\n         num_trans = 1;\n   }\n\n   info_ptr->num_trans = (png_uint_16)num_trans;\n\n   if (num_trans != 0)\n   {\n      info_ptr->valid |= PNG_INFO_tRNS;\n      info_ptr->free_me |= PNG_FREE_TRNS;\n   }\n}\n#endif\n\n#ifdef PNG_sPLT_SUPPORTED\nvoid PNGAPI\npng_set_sPLT(png_const_structrp png_ptr,\n    png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)\n/*\n *  entries        - array of png_sPLT_t structures\n *                   to be added to the list of palettes\n *                   in the info structure.\n *\n *  nentries       - number of palette structures to be\n *                   added.\n */\n{\n   png_sPLT_tp np;\n\n   if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL)\n      return;\n\n   /* Use the internal realloc function, which checks for all the possible\n    * overflows.  Notice that the parameters are (int) and (size_t)\n    */\n   np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,\n      info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,\n      sizeof *np));\n\n   if (np == NULL)\n   {\n      /* Out of memory or too many chunks */\n      png_chunk_report(png_ptr, \"too many sPLT chunks\", PNG_CHUNK_WRITE_ERROR);\n\n      return;\n   }\n\n   png_free(png_ptr, info_ptr->splt_palettes);\n   info_ptr->splt_palettes = np;\n   info_ptr->free_me |= PNG_FREE_SPLT;\n\n   np += info_ptr->splt_palettes_num;\n\n   do\n   {\n      png_size_t length;\n\n      /* Skip invalid input entries */\n      if (entries->name == NULL || entries->entries == NULL)\n      {\n         /* png_handle_sPLT doesn't do this, so this is an app error */\n         png_app_error(png_ptr, \"png_set_sPLT: invalid sPLT\");\n         /* Just skip the invalid entry */\n         continue;\n      }\n\n      np->depth = entries->depth;\n\n      /* In the event of out-of-memory just return - there's no point keeping\n       * on trying to add sPLT chunks.\n       */\n      length = strlen(entries->name) + 1;\n      np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length));\n\n      if (np->name == NULL)\n         break;\n\n      memcpy(np->name, entries->name, length);\n\n      /* IMPORTANT: we have memory now that won't get freed if something else\n       * goes wrong; this code must free it.  png_malloc_array produces no\n       * warnings; use a png_chunk_report (below) if there is an error.\n       */\n      np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr,\n          entries->nentries, sizeof (png_sPLT_entry)));\n\n      if (np->entries == NULL)\n      {\n         png_free(png_ptr, np->name);\n         np->name = NULL;\n         break;\n      }\n\n      np->nentries = entries->nentries;\n      /* This multiply can't overflow because png_malloc_array has already\n       * checked it when doing the allocation.\n       */\n      memcpy(np->entries, entries->entries,\n         entries->nentries * sizeof (png_sPLT_entry));\n\n      /* Note that 'continue' skips the advance of the out pointer and out\n       * count, so an invalid entry is not added.\n       */\n      info_ptr->valid |= PNG_INFO_sPLT;\n      ++(info_ptr->splt_palettes_num);\n      ++np;\n   }\n   while (++entries, --nentries);\n\n   if (nentries > 0)\n      png_chunk_report(png_ptr, \"sPLT out of memory\", PNG_CHUNK_WRITE_ERROR);\n}\n#endif /* sPLT */\n\n#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED\nstatic png_byte\ncheck_location(png_const_structrp png_ptr, int location)\n{\n   location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT);\n\n   /* New in 1.6.0; copy the location and check it.  This is an API\n    * change; previously the app had to use the\n    * png_set_unknown_chunk_location API below for each chunk.\n    */\n   if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0)\n   {\n      /* Write struct, so unknown chunks come from the app */\n      png_app_warning(png_ptr,\n         \"png_set_unknown_chunks now expects a valid location\");\n      /* Use the old behavior */\n      location = (png_byte)(png_ptr->mode &\n         (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));\n   }\n\n   /* This need not be an internal error - if the app calls\n    * png_set_unknown_chunks on a read pointer it must get the location right.\n    */\n   if (location == 0)\n      png_error(png_ptr, \"invalid location in png_set_unknown_chunks\");\n\n   /* Now reduce the location to the top-most set bit by removing each least\n    * significant bit in turn.\n    */\n   while (location != (location & -location))\n      location &= ~(location & -location);\n\n   /* The cast is safe because 'location' is a bit mask and only the low four\n    * bits are significant.\n    */\n   return (png_byte)location;\n}\n\nvoid PNGAPI\npng_set_unknown_chunks(png_const_structrp png_ptr,\n   png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)\n{\n   png_unknown_chunkp np;\n\n   if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 ||\n       unknowns == NULL)\n      return;\n\n   /* Check for the failure cases where support has been disabled at compile\n    * time.  This code is hardly ever compiled - it's here because\n    * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this\n    * code) but may be meaningless if the read or write handling of unknown\n    * chunks is not compiled in.\n    */\n#  if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \\\n      defined(PNG_READ_SUPPORTED)\n      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)\n      {\n         png_app_error(png_ptr, \"no unknown chunk support on read\");\n\n         return;\n      }\n#  endif\n#  if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \\\n      defined(PNG_WRITE_SUPPORTED)\n      if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)\n      {\n         png_app_error(png_ptr, \"no unknown chunk support on write\");\n\n         return;\n      }\n#  endif\n\n   /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that\n    * unknown critical chunks could be lost with just a warning resulting in\n    * undefined behavior.  Now png_chunk_report is used to provide behavior\n    * appropriate to read or write.\n    */\n   np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,\n         info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,\n         sizeof *np));\n\n   if (np == NULL)\n   {\n      png_chunk_report(png_ptr, \"too many unknown chunks\",\n         PNG_CHUNK_WRITE_ERROR);\n\n      return;\n   }\n\n   png_free(png_ptr, info_ptr->unknown_chunks);\n   info_ptr->unknown_chunks = np; /* safe because it is initialized */\n   info_ptr->free_me |= PNG_FREE_UNKN;\n\n   np += info_ptr->unknown_chunks_num;\n\n   /* Increment unknown_chunks_num each time round the loop to protect the\n    * just-allocated chunk data.\n    */\n   for (; num_unknowns > 0; --num_unknowns, ++unknowns)\n   {\n      memcpy(np->name, unknowns->name, (sizeof np->name));\n      np->name[(sizeof np->name)-1] = '\\0';\n      np->location = check_location(png_ptr, unknowns->location);\n\n      if (unknowns->size == 0)\n      {\n         np->data = NULL;\n         np->size = 0;\n      }\n\n      else\n      {\n         np->data = png_voidcast(png_bytep,\n            png_malloc_base(png_ptr, unknowns->size));\n\n         if (np->data == NULL)\n         {\n            png_chunk_report(png_ptr, \"unknown chunk: out of memory\",\n               PNG_CHUNK_WRITE_ERROR);\n            /* But just skip storing the unknown chunk */\n            continue;\n         }\n\n         memcpy(np->data, unknowns->data, unknowns->size);\n         np->size = unknowns->size;\n      }\n\n      /* These increments are skipped on out-of-memory for the data - the\n       * unknown chunk entry gets overwritten if the png_chunk_report returns.\n       * This is correct in the read case (the chunk is just dropped.)\n       */\n      ++np;\n      ++(info_ptr->unknown_chunks_num);\n   }\n}\n\nvoid PNGAPI\npng_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr,\n    int chunk, int location)\n{\n   /* This API is pretty pointless in 1.6.0 because the location can be set\n    * before the call to png_set_unknown_chunks.\n    *\n    * TODO: add a png_app_warning in 1.7\n    */\n   if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 &&\n      chunk < info_ptr->unknown_chunks_num)\n   {\n      if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0)\n      {\n         png_app_error(png_ptr, \"invalid unknown chunk location\");\n         /* Fake out the pre 1.6.0 behavior: */\n         if ((location & PNG_HAVE_IDAT) != 0) /* undocumented! */\n            location = PNG_AFTER_IDAT;\n\n         else\n            location = PNG_HAVE_IHDR; /* also undocumented */\n      }\n\n      info_ptr->unknown_chunks[chunk].location =\n         check_location(png_ptr, location);\n   }\n}\n#endif /* STORE_UNKNOWN_CHUNKS */\n\n#ifdef PNG_MNG_FEATURES_SUPPORTED\npng_uint_32 PNGAPI\npng_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features)\n{\n   png_debug(1, \"in png_permit_mng_features\");\n\n   if (png_ptr == NULL)\n      return 0;\n\n   png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES;\n\n   return png_ptr->mng_features_permitted;\n}\n#endif\n\n#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED\nstatic unsigned int\nadd_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep)\n{\n   unsigned int i;\n\n   /* Utility function: update the 'keep' state of a chunk if it is already in\n    * the list, otherwise add it to the list.\n    */\n   for (i=0; i<count; ++i, list += 5)\n   {\n      if (memcmp(list, add, 4) == 0)\n      {\n         list[4] = (png_byte)keep;\n\n         return count;\n      }\n   }\n\n   if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT)\n   {\n      ++count;\n      memcpy(list, add, 4);\n      list[4] = (png_byte)keep;\n   }\n\n   return count;\n}\n\nvoid PNGAPI\npng_set_keep_unknown_chunks(png_structrp png_ptr, int keep,\n    png_const_bytep chunk_list, int num_chunks_in)\n{\n   png_bytep new_list;\n   unsigned int num_chunks, old_num_chunks;\n\n   if (png_ptr == NULL)\n      return;\n\n   if (keep < 0 || keep >= PNG_HANDLE_CHUNK_LAST)\n   {\n      png_app_error(png_ptr, \"png_set_keep_unknown_chunks: invalid keep\");\n\n      return;\n   }\n\n   if (num_chunks_in <= 0)\n   {\n      png_ptr->unknown_default = keep;\n\n      /* '0' means just set the flags, so stop here */\n      if (num_chunks_in == 0)\n        return;\n   }\n\n   if (num_chunks_in < 0)\n   {\n      /* Ignore all unknown chunks and all chunks recognized by\n       * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND\n       */\n      static PNG_CONST png_byte chunks_to_ignore[] = {\n         98,  75,  71,  68, '\\0',  /* bKGD */\n         99,  72,  82,  77, '\\0',  /* cHRM */\n        103,  65,  77,  65, '\\0',  /* gAMA */\n        104,  73,  83,  84, '\\0',  /* hIST */\n        105,  67,  67,  80, '\\0',  /* iCCP */\n        105,  84,  88, 116, '\\0',  /* iTXt */\n        111,  70,  70, 115, '\\0',  /* oFFs */\n        112,  67,  65,  76, '\\0',  /* pCAL */\n        112,  72,  89, 115, '\\0',  /* pHYs */\n        115,  66,  73,  84, '\\0',  /* sBIT */\n        115,  67,  65,  76, '\\0',  /* sCAL */\n        115,  80,  76,  84, '\\0',  /* sPLT */\n        115,  84,  69,  82, '\\0',  /* sTER */\n        115,  82,  71,  66, '\\0',  /* sRGB */\n        116,  69,  88, 116, '\\0',  /* tEXt */\n        116,  73,  77,  69, '\\0',  /* tIME */\n        122,  84,  88, 116, '\\0'   /* zTXt */\n      };\n\n      chunk_list = chunks_to_ignore;\n      num_chunks = (unsigned int)/*SAFE*/(sizeof chunks_to_ignore)/5U;\n   }\n\n   else /* num_chunks_in > 0 */\n   {\n      if (chunk_list == NULL)\n      {\n         /* Prior to 1.6.0 this was silently ignored, now it is an app_error\n          * which can be switched off.\n          */\n         png_app_error(png_ptr, \"png_set_keep_unknown_chunks: no chunk list\");\n\n         return;\n      }\n\n      num_chunks = num_chunks_in;\n   }\n\n   old_num_chunks = png_ptr->num_chunk_list;\n   if (png_ptr->chunk_list == NULL)\n      old_num_chunks = 0;\n\n   /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow.\n    */\n   if (num_chunks + old_num_chunks > UINT_MAX/5)\n   {\n      png_app_error(png_ptr, \"png_set_keep_unknown_chunks: too many chunks\");\n\n      return;\n   }\n\n   /* If these chunks are being reset to the default then no more memory is\n    * required because add_one_chunk above doesn't extend the list if the 'keep'\n    * parameter is the default.\n    */\n   if (keep != 0)\n   {\n      new_list = png_voidcast(png_bytep, png_malloc(png_ptr,\n          5 * (num_chunks + old_num_chunks)));\n\n      if (old_num_chunks > 0)\n         memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks);\n   }\n\n   else if (old_num_chunks > 0)\n      new_list = png_ptr->chunk_list;\n\n   else\n      new_list = NULL;\n\n   /* Add the new chunks together with each one's handling code.  If the chunk\n    * already exists the code is updated, otherwise the chunk is added to the\n    * end.  (In libpng 1.6.0 order no longer matters because this code enforces\n    * the earlier convention that the last setting is the one that is used.)\n    */\n   if (new_list != NULL)\n   {\n      png_const_bytep inlist;\n      png_bytep outlist;\n      unsigned int i;\n\n      for (i=0; i<num_chunks; ++i)\n      {\n         old_num_chunks = add_one_chunk(new_list, old_num_chunks,\n            chunk_list+5*i, keep);\n      }\n\n      /* Now remove any spurious 'default' entries. */\n      num_chunks = 0;\n      for (i=0, inlist=outlist=new_list; i<old_num_chunks; ++i, inlist += 5)\n      {\n         if (inlist[4])\n         {\n            if (outlist != inlist)\n               memcpy(outlist, inlist, 5);\n            outlist += 5;\n            ++num_chunks;\n         }\n      }\n\n      /* This means the application has removed all the specialized handling. */\n      if (num_chunks == 0)\n      {\n         if (png_ptr->chunk_list != new_list)\n            png_free(png_ptr, new_list);\n\n         new_list = NULL;\n      }\n   }\n\n   else\n      num_chunks = 0;\n\n   png_ptr->num_chunk_list = num_chunks;\n\n   if (png_ptr->chunk_list != new_list)\n   {\n      if (png_ptr->chunk_list != NULL)\n         png_free(png_ptr, png_ptr->chunk_list);\n\n      png_ptr->chunk_list = new_list;\n   }\n}\n#endif\n\n#ifdef PNG_READ_USER_CHUNKS_SUPPORTED\nvoid PNGAPI\npng_set_read_user_chunk_fn(png_structrp png_ptr, png_voidp user_chunk_ptr,\n    png_user_chunk_ptr read_user_chunk_fn)\n{\n   png_debug(1, \"in png_set_read_user_chunk_fn\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->read_user_chunk_fn = read_user_chunk_fn;\n   png_ptr->user_chunk_ptr = user_chunk_ptr;\n}\n#endif\n\n#ifdef PNG_INFO_IMAGE_SUPPORTED\nvoid PNGAPI\npng_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,\n    png_bytepp row_pointers)\n{\n   png_debug1(1, \"in %s storage function\", \"rows\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   if (info_ptr->row_pointers != NULL &&\n       (info_ptr->row_pointers != row_pointers))\n      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);\n\n   info_ptr->row_pointers = row_pointers;\n\n   if (row_pointers != NULL)\n      info_ptr->valid |= PNG_INFO_IDAT;\n}\n#endif\n\nvoid PNGAPI\npng_set_compression_buffer_size(png_structrp png_ptr, png_size_t size)\n{\n    if (png_ptr == NULL)\n       return;\n\n    if (size == 0 || size > PNG_UINT_31_MAX)\n       png_error(png_ptr, \"invalid compression buffer size\");\n\n#  ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)\n      {\n         png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */\n         return;\n      }\n#  endif\n\n#  ifdef PNG_WRITE_SUPPORTED\n      if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)\n      {\n         if (png_ptr->zowner != 0)\n         {\n            png_warning(png_ptr,\n              \"Compression buffer size cannot be changed because it is in use\");\n\n            return;\n         }\n\n#ifndef __COVERITY__\n         /* Some compilers complain that this is always false.  However, it\n          * can be true when integer overflow happens.\n          */\n         if (size > ZLIB_IO_MAX)\n         {\n            png_warning(png_ptr,\n               \"Compression buffer size limited to system maximum\");\n            size = ZLIB_IO_MAX; /* must fit */\n         }\n#endif\n\n         if (size < 6)\n         {\n            /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH\n             * if this is permitted.\n             */\n            png_warning(png_ptr,\n               \"Compression buffer size cannot be reduced below 6\");\n\n            return;\n         }\n\n         if (png_ptr->zbuffer_size != size)\n         {\n            png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);\n            png_ptr->zbuffer_size = (uInt)size;\n         }\n      }\n#  endif\n}\n\nvoid PNGAPI\npng_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask)\n{\n   if (png_ptr != NULL && info_ptr != NULL)\n      info_ptr->valid &= ~mask;\n}\n\n\n#ifdef PNG_SET_USER_LIMITS_SUPPORTED\n/* This function was added to libpng 1.2.6 */\nvoid PNGAPI\npng_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max,\n    png_uint_32 user_height_max)\n{\n   /* Images with dimensions larger than these limits will be\n    * rejected by png_set_IHDR().  To accept any PNG datastream\n    * regardless of dimensions, set both limits to 0x7fffffff.\n    */\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->user_width_max = user_width_max;\n   png_ptr->user_height_max = user_height_max;\n}\n\n/* This function was added to libpng 1.4.0 */\nvoid PNGAPI\npng_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max)\n{\n   if (png_ptr != NULL)\n      png_ptr->user_chunk_cache_max = user_chunk_cache_max;\n}\n\n/* This function was added to libpng 1.4.1 */\nvoid PNGAPI\npng_set_chunk_malloc_max (png_structrp png_ptr,\n    png_alloc_size_t user_chunk_malloc_max)\n{\n   if (png_ptr != NULL)\n      png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;\n}\n#endif /* ?SET_USER_LIMITS */\n\n\n#ifdef PNG_BENIGN_ERRORS_SUPPORTED\nvoid PNGAPI\npng_set_benign_errors(png_structrp png_ptr, int allowed)\n{\n   png_debug(1, \"in png_set_benign_errors\");\n\n   /* If allowed is 1, png_benign_error() is treated as a warning.\n    *\n    * If allowed is 0, png_benign_error() is treated as an error (which\n    * is the default behavior if png_set_benign_errors() is not called).\n    */\n\n   if (allowed != 0)\n      png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN |\n         PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN;\n\n   else\n      png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN |\n         PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN);\n}\n#endif /* BENIGN_ERRORS */\n\n#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED\n   /* Whether to report invalid palette index; added at libng-1.5.10.\n    * It is possible for an indexed (color-type==3) PNG file to contain\n    * pixels with invalid (out-of-range) indexes if the PLTE chunk has\n    * fewer entries than the image's bit-depth would allow. We recover\n    * from this gracefully by filling any incomplete palette with zeros\n    * (opaque black).  By default, when this occurs libpng will issue\n    * a benign error.  This API can be used to override that behavior.\n    */\nvoid PNGAPI\npng_set_check_for_invalid_index(png_structrp png_ptr, int allowed)\n{\n   png_debug(1, \"in png_set_check_for_invalid_index\");\n\n   if (allowed > 0)\n      png_ptr->num_palette_max = 0;\n\n   else\n      png_ptr->num_palette_max = -1;\n}\n#endif\n\n#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) || \\\n    defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)\n/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,\n * and if invalid, correct the keyword rather than discarding the entire\n * chunk.  The PNG 1.0 specification requires keywords 1-79 characters in\n * length, forbids leading or trailing whitespace, multiple internal spaces,\n * and the non-break space (0x80) from ISO 8859-1.  Returns keyword length.\n *\n * The 'new_key' buffer must be 80 characters in size (for the keyword plus a\n * trailing '\\0').  If this routine returns 0 then there was no keyword, or a\n * valid one could not be generated, and the caller must png_error.\n */\npng_uint_32 /* PRIVATE */\npng_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)\n{\n   png_const_charp orig_key = key;\n   png_uint_32 key_len = 0;\n   int bad_character = 0;\n   int space = 1;\n\n   png_debug(1, \"in png_check_keyword\");\n\n   if (key == NULL)\n   {\n      *new_key = 0;\n      return 0;\n   }\n\n   while (*key && key_len < 79)\n   {\n      png_byte ch = (png_byte)*key++;\n\n      if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))\n         *new_key++ = ch, ++key_len, space = 0;\n\n      else if (space == 0)\n      {\n         /* A space or an invalid character when one wasn't seen immediately\n          * before; output just a space.\n          */\n         *new_key++ = 32, ++key_len, space = 1;\n\n         /* If the character was not a space then it is invalid. */\n         if (ch != 32)\n            bad_character = ch;\n      }\n\n      else if (bad_character == 0)\n         bad_character = ch; /* just skip it, record the first error */\n   }\n\n   if (key_len > 0 && space != 0) /* trailing space */\n   {\n      --key_len, --new_key;\n      if (bad_character == 0)\n         bad_character = 32;\n   }\n\n   /* Terminate the keyword */\n   *new_key = 0;\n\n   if (key_len == 0)\n      return 0;\n\n#ifdef PNG_WARNINGS_SUPPORTED\n   /* Try to only output one warning per keyword: */\n   if (*key != 0) /* keyword too long */\n      png_warning(png_ptr, \"keyword truncated\");\n\n   else if (bad_character != 0)\n   {\n      PNG_WARNING_PARAMETERS(p)\n\n      png_warning_parameter(p, 1, orig_key);\n      png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character);\n\n      png_formatted_warning(png_ptr, p, \"keyword \\\"@1\\\": bad character '0x@2'\");\n   }\n#endif /* WARNINGS */\n\n   return key_len;\n}\n#endif /* TEXT || pCAL || iCCP || sPLT */\n#endif /* READ || WRITE */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngstruct.h",
    "content": "\n/* pngstruct.h - header file for PNG reference library\n *\n * Last changed in libpng 1.6.18 [July 23, 2015]\n * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n/* The structure that holds the information to read and write PNG files.\n * The only people who need to care about what is inside of this are the\n * people who will be modifying the library for their own special needs.\n * It should NOT be accessed directly by an application.\n */\n\n#ifndef PNGSTRUCT_H\n#define PNGSTRUCT_H\n/* zlib.h defines the structure z_stream, an instance of which is included\n * in this structure and is required for decompressing the LZ compressed\n * data in PNG files.\n */\n#ifndef ZLIB_CONST\n   /* We must ensure that zlib uses 'const' in declarations. */\n#  define ZLIB_CONST\n#endif\n#include \"zlib.h\"\n#ifdef const\n   /* zlib.h sometimes #defines const to nothing, undo this. */\n#  undef const\n#endif\n\n/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility\n * with older builds.\n */\n#if ZLIB_VERNUM < 0x1260\n#  define PNGZ_MSG_CAST(s) png_constcast(char*,s)\n#  define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b)\n#else\n#  define PNGZ_MSG_CAST(s) (s)\n#  define PNGZ_INPUT_CAST(b) (b)\n#endif\n\n/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib\n * can handle at once.  This type need be no larger than 16 bits (so maximum of\n * 65535), this define allows us to discover how big it is, but limited by the\n * maximuum for png_size_t.  The value can be overriden in a library build\n * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably\n * lower value (e.g. 255 works).  A lower value may help memory usage (slightly)\n * and may even improve performance on some systems (and degrade it on others.)\n */\n#ifndef ZLIB_IO_MAX\n#  define ZLIB_IO_MAX ((uInt)-1)\n#endif\n\n#ifdef PNG_WRITE_SUPPORTED\n/* The type of a compression buffer list used by the write code. */\ntypedef struct png_compression_buffer\n{\n   struct png_compression_buffer *next;\n   png_byte                       output[1]; /* actually zbuf_size */\n} png_compression_buffer, *png_compression_bufferp;\n\n#define PNG_COMPRESSION_BUFFER_SIZE(pp)\\\n   (offsetof(png_compression_buffer, output) + (pp)->zbuffer_size)\n#endif\n\n/* Colorspace support; structures used in png_struct, png_info and in internal\n * functions to hold and communicate information about the color space.\n *\n * PNG_COLORSPACE_SUPPORTED is only required if the application will perform\n * colorspace corrections, otherwise all the colorspace information can be\n * skipped and the size of libpng can be reduced (significantly) by compiling\n * out the colorspace support.\n */\n#ifdef PNG_COLORSPACE_SUPPORTED\n/* The chromaticities of the red, green and blue colorants and the chromaticity\n * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)).\n */\ntypedef struct png_xy\n{\n   png_fixed_point redx, redy;\n   png_fixed_point greenx, greeny;\n   png_fixed_point bluex, bluey;\n   png_fixed_point whitex, whitey;\n} png_xy;\n\n/* The same data as above but encoded as CIE XYZ values.  When this data comes\n * from chromaticities the sum of the Y values is assumed to be 1.0\n */\ntypedef struct png_XYZ\n{\n   png_fixed_point red_X, red_Y, red_Z;\n   png_fixed_point green_X, green_Y, green_Z;\n   png_fixed_point blue_X, blue_Y, blue_Z;\n} png_XYZ;\n#endif /* COLORSPACE */\n\n#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)\n/* A colorspace is all the above plus, potentially, profile information;\n * however at present libpng does not use the profile internally so it is only\n * stored in the png_info struct (if iCCP is supported.)  The rendering intent\n * is retained here and is checked.\n *\n * The file gamma encoding information is also stored here and gamma correction\n * is done by libpng, whereas color correction must currently be done by the\n * application.\n */\ntypedef struct png_colorspace\n{\n#ifdef PNG_GAMMA_SUPPORTED\n   png_fixed_point gamma;        /* File gamma */\n#endif\n\n#ifdef PNG_COLORSPACE_SUPPORTED\n   png_xy      end_points_xy;    /* End points as chromaticities */\n   png_XYZ     end_points_XYZ;   /* End points as CIE XYZ colorant values */\n   png_uint_16 rendering_intent; /* Rendering intent of a profile */\n#endif\n\n   /* Flags are always defined to simplify the code. */\n   png_uint_16 flags;            /* As defined below */\n} png_colorspace, * PNG_RESTRICT png_colorspacerp;\n\ntypedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp;\n\n/* General flags for the 'flags' field */\n#define PNG_COLORSPACE_HAVE_GAMMA           0x0001\n#define PNG_COLORSPACE_HAVE_ENDPOINTS       0x0002\n#define PNG_COLORSPACE_HAVE_INTENT          0x0004\n#define PNG_COLORSPACE_FROM_gAMA            0x0008\n#define PNG_COLORSPACE_FROM_cHRM            0x0010\n#define PNG_COLORSPACE_FROM_sRGB            0x0020\n#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040\n#define PNG_COLORSPACE_MATCHES_sRGB         0x0080 /* exact match on profile */\n#define PNG_COLORSPACE_INVALID              0x8000\n#define PNG_COLORSPACE_CANCEL(flags)        (0xffff ^ (flags))\n#endif /* COLORSPACE || GAMMA */\n\nstruct png_struct_def\n{\n#ifdef PNG_SETJMP_SUPPORTED\n   jmp_buf jmp_buf_local;     /* New name in 1.6.0 for jmp_buf in png_struct */\n   png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */\n   jmp_buf *jmp_buf_ptr;      /* passed to longjmp_fn */\n   size_t jmp_buf_size;       /* size of the above, if allocated */\n#endif\n   png_error_ptr error_fn;    /* function for printing errors and aborting */\n#ifdef PNG_WARNINGS_SUPPORTED\n   png_error_ptr warning_fn;  /* function for printing warnings */\n#endif\n   png_voidp error_ptr;       /* user supplied struct for error functions */\n   png_rw_ptr write_data_fn;  /* function for writing output data */\n   png_rw_ptr read_data_fn;   /* function for reading input data */\n   png_voidp io_ptr;          /* ptr to application struct for I/O functions */\n\n#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED\n   png_user_transform_ptr read_user_transform_fn; /* user read transform */\n#endif\n\n#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED\n   png_user_transform_ptr write_user_transform_fn; /* user write transform */\n#endif\n\n/* These were added in libpng-1.0.2 */\n#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED\n#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \\\n    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)\n   png_voidp user_transform_ptr; /* user supplied struct for user transform */\n   png_byte user_transform_depth;    /* bit depth of user transformed pixels */\n   png_byte user_transform_channels; /* channels in user transformed pixels */\n#endif\n#endif\n\n   png_uint_32 mode;          /* tells us where we are in the PNG file */\n   png_uint_32 flags;         /* flags indicating various things to libpng */\n   png_uint_32 transformations; /* which transformations to perform */\n\n   png_uint_32 zowner;        /* ID (chunk type) of zstream owner, 0 if none */\n   z_stream    zstream;       /* decompression structure */\n\n#ifdef PNG_WRITE_SUPPORTED\n   png_compression_bufferp zbuffer_list; /* Created on demand during write */\n   uInt                    zbuffer_size; /* size of the actual buffer */\n\n   int zlib_level;            /* holds zlib compression level */\n   int zlib_method;           /* holds zlib compression method */\n   int zlib_window_bits;      /* holds zlib compression window bits */\n   int zlib_mem_level;        /* holds zlib compression memory level */\n   int zlib_strategy;         /* holds zlib compression strategy */\n#endif\n/* Added at libpng 1.5.4 */\n#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED\n   int zlib_text_level;            /* holds zlib compression level */\n   int zlib_text_method;           /* holds zlib compression method */\n   int zlib_text_window_bits;      /* holds zlib compression window bits */\n   int zlib_text_mem_level;        /* holds zlib compression memory level */\n   int zlib_text_strategy;         /* holds zlib compression strategy */\n#endif\n/* End of material added at libpng 1.5.4 */\n/* Added at libpng 1.6.0 */\n#ifdef PNG_WRITE_SUPPORTED\n   int zlib_set_level;        /* Actual values set into the zstream on write */\n   int zlib_set_method;\n   int zlib_set_window_bits;\n   int zlib_set_mem_level;\n   int zlib_set_strategy;\n#endif\n\n   png_uint_32 width;         /* width of image in pixels */\n   png_uint_32 height;        /* height of image in pixels */\n   png_uint_32 num_rows;      /* number of rows in current pass */\n   png_uint_32 usr_width;     /* width of row at start of write */\n   png_size_t rowbytes;       /* size of row in bytes */\n   png_uint_32 iwidth;        /* width of current interlaced row in pixels */\n   png_uint_32 row_number;    /* current row in interlace pass */\n   png_uint_32 chunk_name;    /* PNG_CHUNK() id of current chunk */\n   png_bytep prev_row;        /* buffer to save previous (unfiltered) row.\n                               * While reading this is a pointer into\n                               * big_prev_row; while writing it is separately\n                               * allocated if needed.\n                               */\n   png_bytep row_buf;         /* buffer to save current (unfiltered) row.\n                               * While reading, this is a pointer into\n                               * big_row_buf; while writing it is separately\n                               * allocated.\n                               */\n#ifdef PNG_WRITE_FILTER_SUPPORTED\n   png_bytep try_row;    /* buffer to save trial row when filtering */\n   png_bytep tst_row;    /* buffer to save best trial row when filtering */\n#endif\n   png_size_t info_rowbytes;  /* Added in 1.5.4: cache of updated row bytes */\n\n   png_uint_32 idat_size;     /* current IDAT size for read */\n   png_uint_32 crc;           /* current chunk CRC value */\n   png_colorp palette;        /* palette from the input file */\n   png_uint_16 num_palette;   /* number of color entries in palette */\n\n/* Added at libpng-1.5.10 */\n#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED\n   int num_palette_max;       /* maximum palette index found in IDAT */\n#endif\n\n   png_uint_16 num_trans;     /* number of transparency values */\n   png_byte compression;      /* file compression type (always 0) */\n   png_byte filter;           /* file filter type (always 0) */\n   png_byte interlaced;       /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */\n   png_byte pass;             /* current interlace pass (0 - 6) */\n   png_byte do_filter;        /* row filter flags (see PNG_FILTER_ below ) */\n   png_byte color_type;       /* color type of file */\n   png_byte bit_depth;        /* bit depth of file */\n   png_byte usr_bit_depth;    /* bit depth of users row: write only */\n   png_byte pixel_depth;      /* number of bits per pixel */\n   png_byte channels;         /* number of channels in file */\n#ifdef PNG_WRITE_SUPPORTED\n   png_byte usr_channels;     /* channels at start of write: write only */\n#endif\n   png_byte sig_bytes;        /* magic bytes read/written from start of file */\n   png_byte maximum_pixel_depth;\n                              /* pixel depth used for the row buffers */\n   png_byte transformed_pixel_depth;\n                              /* pixel depth after read/write transforms */\n#if PNG_ZLIB_VERNUM >= 0x1240\n   png_byte zstream_start;    /* at start of an input zlib stream */\n#endif /* Zlib >= 1.2.4 */\n#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)\n   png_uint_16 filler;           /* filler bytes for pixel expansion */\n#endif\n\n#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\\\n   defined(PNG_READ_ALPHA_MODE_SUPPORTED)\n   png_byte background_gamma_type;\n   png_fixed_point background_gamma;\n   png_color_16 background;   /* background color in screen gamma space */\n#ifdef PNG_READ_GAMMA_SUPPORTED\n   png_color_16 background_1; /* background normalized to gamma 1.0 */\n#endif\n#endif /* bKGD */\n\n#ifdef PNG_WRITE_FLUSH_SUPPORTED\n   png_flush_ptr output_flush_fn; /* Function for flushing output */\n   png_uint_32 flush_dist;    /* how many rows apart to flush, 0 - no flush */\n   png_uint_32 flush_rows;    /* number of rows written since last flush */\n#endif\n\n#ifdef PNG_READ_GAMMA_SUPPORTED\n   int gamma_shift;      /* number of \"insignificant\" bits in 16-bit gamma */\n   png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */\n\n   png_bytep gamma_table;     /* gamma table for 8-bit depth files */\n   png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */\n#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \\\n   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \\\n   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)\n   png_bytep gamma_from_1;    /* converts from 1.0 to screen */\n   png_bytep gamma_to_1;      /* converts from file to 1.0 */\n   png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */\n   png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */\n#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */\n#endif\n\n#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)\n   png_color_8 sig_bit;       /* significant bits in each available channel */\n#endif\n\n#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)\n   png_color_8 shift;         /* shift for significant bit tranformation */\n#endif\n\n#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \\\n || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)\n   png_bytep trans_alpha;           /* alpha values for paletted files */\n   png_color_16 trans_color;  /* transparent color for non-paletted files */\n#endif\n\n   png_read_status_ptr read_row_fn;   /* called after each row is decoded */\n   png_write_status_ptr write_row_fn; /* called after each row is encoded */\n#ifdef PNG_PROGRESSIVE_READ_SUPPORTED\n   png_progressive_info_ptr info_fn; /* called after header data fully read */\n   png_progressive_row_ptr row_fn;   /* called after a prog. row is decoded */\n   png_progressive_end_ptr end_fn;   /* called after image is complete */\n   png_bytep save_buffer_ptr;        /* current location in save_buffer */\n   png_bytep save_buffer;            /* buffer for previously read data */\n   png_bytep current_buffer_ptr;     /* current location in current_buffer */\n   png_bytep current_buffer;         /* buffer for recently used data */\n   png_uint_32 push_length;          /* size of current input chunk */\n   png_uint_32 skip_length;          /* bytes to skip in input data */\n   png_size_t save_buffer_size;      /* amount of data now in save_buffer */\n   png_size_t save_buffer_max;       /* total size of save_buffer */\n   png_size_t buffer_size;           /* total amount of available input data */\n   png_size_t current_buffer_size;   /* amount of data now in current_buffer */\n   int process_mode;                 /* what push library is currently doing */\n   int cur_palette;                  /* current push library palette index */\n\n#endif /* PROGRESSIVE_READ */\n\n#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)\n/* For the Borland special 64K segment handler */\n   png_bytepp offset_table_ptr;\n   png_bytep offset_table;\n   png_uint_16 offset_table_number;\n   png_uint_16 offset_table_count;\n   png_uint_16 offset_table_count_free;\n#endif\n\n#ifdef PNG_READ_QUANTIZE_SUPPORTED\n   png_bytep palette_lookup; /* lookup table for quantizing */\n   png_bytep quantize_index; /* index translation for palette files */\n#endif\n\n/* Options */\n#ifdef PNG_SET_OPTION_SUPPORTED\n   png_byte options;           /* On/off state (up to 4 options) */\n#endif\n\n#if PNG_LIBPNG_VER < 10700\n/* To do: remove this from libpng-1.7 */\n#ifdef PNG_TIME_RFC1123_SUPPORTED\n   char time_buffer[29]; /* String to hold RFC 1123 time text */\n#endif\n#endif\n\n/* New members added in libpng-1.0.6 */\n\n   png_uint_32 free_me;    /* flags items libpng is responsible for freeing */\n\n#ifdef PNG_USER_CHUNKS_SUPPORTED\n   png_voidp user_chunk_ptr;\n#ifdef PNG_READ_USER_CHUNKS_SUPPORTED\n   png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */\n#endif\n#endif\n\n#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED\n   int          unknown_default; /* As PNG_HANDLE_* */\n   unsigned int num_chunk_list;  /* Number of entries in the list */\n   png_bytep    chunk_list;      /* List of png_byte[5]; the textual chunk name\n                                  * followed by a PNG_HANDLE_* byte */\n#endif\n\n/* New members added in libpng-1.0.3 */\n#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\n   png_byte rgb_to_gray_status;\n   /* Added in libpng 1.5.5 to record setting of coefficients: */\n   png_byte rgb_to_gray_coefficients_set;\n   /* These were changed from png_byte in libpng-1.0.6 */\n   png_uint_16 rgb_to_gray_red_coeff;\n   png_uint_16 rgb_to_gray_green_coeff;\n   /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */\n#endif\n\n/* New member added in libpng-1.0.4 (renamed in 1.0.9) */\n#if defined(PNG_MNG_FEATURES_SUPPORTED)\n/* Changed from png_byte to png_uint_32 at version 1.2.0 */\n   png_uint_32 mng_features_permitted;\n#endif\n\n/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */\n#ifdef PNG_MNG_FEATURES_SUPPORTED\n   png_byte filter_type;\n#endif\n\n/* New members added in libpng-1.2.0 */\n\n/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */\n#ifdef PNG_USER_MEM_SUPPORTED\n   png_voidp mem_ptr;             /* user supplied struct for mem functions */\n   png_malloc_ptr malloc_fn;      /* function for allocating memory */\n   png_free_ptr free_fn;          /* function for freeing memory */\n#endif\n\n/* New member added in libpng-1.0.13 and 1.2.0 */\n   png_bytep big_row_buf;         /* buffer to save current (unfiltered) row */\n\n#ifdef PNG_READ_QUANTIZE_SUPPORTED\n/* The following three members were added at version 1.0.14 and 1.2.4 */\n   png_bytep quantize_sort;          /* working sort array */\n   png_bytep index_to_palette;       /* where the original index currently is\n                                        in the palette */\n   png_bytep palette_to_index;       /* which original index points to this\n                                         palette color */\n#endif\n\n/* New members added in libpng-1.0.16 and 1.2.6 */\n   png_byte compression_type;\n\n#ifdef PNG_USER_LIMITS_SUPPORTED\n   png_uint_32 user_width_max;\n   png_uint_32 user_height_max;\n\n   /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown\n    * chunks that can be stored (0 means unlimited).\n    */\n   png_uint_32 user_chunk_cache_max;\n\n   /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk\n    * can occupy when decompressed.  0 means unlimited.\n    */\n   png_alloc_size_t user_chunk_malloc_max;\n#endif\n\n/* New member added in libpng-1.0.25 and 1.2.17 */\n#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED\n   /* Temporary storage for unknown chunk that the library doesn't recognize,\n    * used while reading the chunk.\n    */\n   png_unknown_chunk unknown_chunk;\n#endif\n\n/* New member added in libpng-1.2.26 */\n  png_size_t old_big_row_buf_size;\n\n#ifdef PNG_READ_SUPPORTED\n/* New member added in libpng-1.2.30 */\n  png_bytep        read_buffer;      /* buffer for reading chunk data */\n  png_alloc_size_t read_buffer_size; /* current size of the buffer */\n#endif\n#ifdef PNG_SEQUENTIAL_READ_SUPPORTED\n  uInt             IDAT_read_size;   /* limit on read buffer size for IDAT */\n#endif\n\n#ifdef PNG_IO_STATE_SUPPORTED\n/* New member added in libpng-1.4.0 */\n   png_uint_32 io_state;\n#endif\n\n/* New member added in libpng-1.5.6 */\n   png_bytep big_prev_row;\n\n/* New member added in libpng-1.5.7 */\n   void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info,\n      png_bytep row, png_const_bytep prev_row);\n\n#ifdef PNG_READ_SUPPORTED\n#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)\n   png_colorspace   colorspace;\n#endif\n#endif\n};\n#endif /* PNGSTRUCT_H */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngtest.c",
    "content": "\n/* pngtest.c - a simple test program to test libpng\n *\n * Last changed in libpng 1.5.25 [December 3, 2015]\n * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * This program reads in a PNG image, writes it out again, and then\n * compares the two files.  If the files are identical, this shows that\n * the basic chunk handling, filtering, and (de)compression code is working\n * properly.  It does not currently test all of the transforms, although\n * it probably should.\n *\n * The program will report \"FAIL\" in certain legitimate cases:\n * 1) when the compression level or filter selection method is changed.\n * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192.\n * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks\n *    exist in the input file.\n * 4) others not listed here...\n * In these cases, it is best to check with another tool such as \"pngcheck\"\n * to see what the differences between the two files are.\n *\n * If a filename is given on the command-line, then this file is used\n * for the input, rather than the default \"pngtest.png\".  This allows\n * testing a wide variety of files easily.  You can also test a number\n * of files at once by typing \"pngtest -m file1.png file2.png ...\"\n */\n\n#define _POSIX_SOURCE 1\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n/* Defined so I can write to a file on gui/windowing platforms */\n/*  #define STDERR stderr  */\n#define STDERR stdout   /* For DOS */\n\n#include \"png.h\"\n\n/* 1.6.1 added support for the configure test harness, which uses 77 to indicate\n * a skipped test, in earlier versions we need to succeed on a skipped test, so:\n */\n#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)\n#  define SKIP 77\n#else\n#  define SKIP 0\n#endif\n\n/* Known chunks that exist in pngtest.png must be supported or pngtest will fail\n * simply as a result of re-ordering them.  This may be fixed in 1.7\n *\n * pngtest allocates a single row buffer for each row and overwrites it,\n * therefore if the write side doesn't support the writing of interlaced images\n * nothing can be done for an interlaced image (and the code below will fail\n * horribly trying to write extra data after writing garbage).\n */\n#if defined PNG_READ_SUPPORTED && /* else nothing can be done */\\\n   defined PNG_READ_bKGD_SUPPORTED &&\\\n   defined PNG_READ_cHRM_SUPPORTED &&\\\n   defined PNG_READ_gAMA_SUPPORTED &&\\\n   defined PNG_READ_oFFs_SUPPORTED &&\\\n   defined PNG_READ_pCAL_SUPPORTED &&\\\n   defined PNG_READ_pHYs_SUPPORTED &&\\\n   defined PNG_READ_sBIT_SUPPORTED &&\\\n   defined PNG_READ_sCAL_SUPPORTED &&\\\n   defined PNG_READ_sRGB_SUPPORTED &&\\\n   defined PNG_READ_sPLT_SUPPORTED &&\\\n   defined PNG_READ_tEXt_SUPPORTED &&\\\n   defined PNG_READ_tIME_SUPPORTED &&\\\n   defined PNG_READ_zTXt_SUPPORTED &&\\\n   (defined PNG_WRITE_INTERLACING_SUPPORTED || PNG_LIBPNG_VER >= 10700)\n\n#ifdef PNG_ZLIB_HEADER\n#  include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */\n#else\n#  include \"zlib.h\"\n#endif\n\n/* Copied from pngpriv.h but only used in error messages below. */\n#ifndef PNG_ZBUF_SIZE\n#  define PNG_ZBUF_SIZE 8192\n#endif\n#define FCLOSE(file) fclose(file)\n\n#ifndef PNG_STDIO_SUPPORTED\ntypedef FILE                * png_FILE_p;\n#endif\n\n/* Makes pngtest verbose so we can find problems. */\n#ifndef PNG_DEBUG\n#  define PNG_DEBUG 0\n#endif\n\n#if PNG_DEBUG > 1\n#  define pngtest_debug(m)        ((void)fprintf(stderr, m \"\\n\"))\n#  define pngtest_debug1(m,p1)    ((void)fprintf(stderr, m \"\\n\", p1))\n#  define pngtest_debug2(m,p1,p2) ((void)fprintf(stderr, m \"\\n\", p1, p2))\n#else\n#  define pngtest_debug(m)        ((void)0)\n#  define pngtest_debug1(m,p1)    ((void)0)\n#  define pngtest_debug2(m,p1,p2) ((void)0)\n#endif\n\n#if !PNG_DEBUG\n#  define SINGLE_ROWBUF_ALLOC  /* Makes buffer overruns easier to nail */\n#endif\n\n#ifndef PNG_UNUSED\n#  define PNG_UNUSED(param) (void)param;\n#endif\n\n/* Turn on CPU timing\n#define PNGTEST_TIMING\n*/\n\n#ifndef PNG_FLOATING_POINT_SUPPORTED\n#undef PNGTEST_TIMING\n#endif\n\n#ifdef PNGTEST_TIMING\nstatic float t_start, t_stop, t_decode, t_encode, t_misc;\n#include <time.h>\n#endif\n\n#ifdef PNG_TIME_RFC1123_SUPPORTED\n#define PNG_tIME_STRING_LENGTH 29\nstatic int tIME_chunk_present = 0;\nstatic char tIME_string[PNG_tIME_STRING_LENGTH] = \"tIME chunk is not present\";\n\n#if PNG_LIBPNG_VER < 10619\n#define png_convert_to_rfc1123_buffer(ts, t) tIME_to_str(read_ptr, ts, t)\n\nstatic int\ntIME_to_str(png_structp png_ptr, png_charp ts, png_const_timep t)\n{\n    png_const_charp str = png_convert_to_rfc1123(png_ptr, t);\n\n    if (str == NULL)\n        return 0;\n\n    strcpy(ts, str);\n    return 1;\n}\n#endif /* older libpng */\n#endif\n\nstatic int verbose = 0;\nstatic int strict = 0;\nstatic int relaxed = 0;\nstatic int unsupported_chunks = 0; /* chunk unsupported by libpng in input */\nstatic int error_count = 0; /* count calls to png_error */\nstatic int warning_count = 0; /* count calls to png_warning */\n\n/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */\n#ifndef png_jmpbuf\n#  define png_jmpbuf(png_ptr) png_ptr->jmpbuf\n#endif\n\n/* Defines for unknown chunk handling if required. */\n#ifndef PNG_HANDLE_CHUNK_ALWAYS\n#  define PNG_HANDLE_CHUNK_ALWAYS       3\n#endif\n#ifndef PNG_HANDLE_CHUNK_IF_SAFE\n#  define PNG_HANDLE_CHUNK_IF_SAFE      2\n#endif\n\n/* Utility to save typing/errors, the argument must be a name */\n#define MEMZERO(var) ((void)memset(&var, 0, sizeof var))\n\n/* Example of using row callbacks to make a simple progress meter */\nstatic int status_pass = 1;\nstatic int status_dots_requested = 0;\nstatic int status_dots = 1;\n\nstatic void PNGCBAPI\nread_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)\n{\n   if (png_ptr == NULL || row_number > PNG_UINT_31_MAX)\n      return;\n\n   if (status_pass != pass)\n   {\n      fprintf(stdout, \"\\n Pass %d: \", pass);\n      status_pass = pass;\n      status_dots = 31;\n   }\n\n   status_dots--;\n\n   if (status_dots == 0)\n   {\n      fprintf(stdout, \"\\n         \");\n      status_dots=30;\n   }\n\n   fprintf(stdout, \"r\");\n}\n\n#ifdef PNG_WRITE_SUPPORTED\nstatic void PNGCBAPI\nwrite_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)\n{\n   if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7)\n      return;\n\n   fprintf(stdout, \"w\");\n}\n#endif\n\n\n#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED\n/* Example of using a user transform callback (doesn't do anything at present).\n */\nstatic void PNGCBAPI\nread_user_callback(png_structp png_ptr, png_row_infop row_info, png_bytep data)\n{\n   PNG_UNUSED(png_ptr)\n   PNG_UNUSED(row_info)\n   PNG_UNUSED(data)\n}\n#endif\n\n#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED\n/* Example of using user transform callback (we don't transform anything,\n * but merely count the zero samples)\n */\n\nstatic png_uint_32 zero_samples;\n\nstatic void PNGCBAPI\ncount_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)\n{\n   png_bytep dp = data;\n   if (png_ptr == NULL)\n      return;\n\n   /* Contents of row_info:\n    *  png_uint_32 width      width of row\n    *  png_uint_32 rowbytes   number of bytes in row\n    *  png_byte color_type    color type of pixels\n    *  png_byte bit_depth     bit depth of samples\n    *  png_byte channels      number of channels (1-4)\n    *  png_byte pixel_depth   bits per pixel (depth*channels)\n    */\n\n    /* Counts the number of zero samples (or zero pixels if color_type is 3 */\n\n    if (row_info->color_type == 0 || row_info->color_type == 3)\n    {\n       int pos = 0;\n       png_uint_32 n, nstop;\n\n       for (n = 0, nstop=row_info->width; n<nstop; n++)\n       {\n          if (row_info->bit_depth == 1)\n          {\n             if (((*dp << pos++ ) & 0x80) == 0)\n                zero_samples++;\n\n             if (pos == 8)\n             {\n                pos = 0;\n                dp++;\n             }\n          }\n\n          if (row_info->bit_depth == 2)\n          {\n             if (((*dp << (pos+=2)) & 0xc0) == 0)\n                zero_samples++;\n\n             if (pos == 8)\n             {\n                pos = 0;\n                dp++;\n             }\n          }\n\n          if (row_info->bit_depth == 4)\n          {\n             if (((*dp << (pos+=4)) & 0xf0) == 0)\n                zero_samples++;\n\n             if (pos == 8)\n             {\n                pos = 0;\n                dp++;\n             }\n          }\n\n          if (row_info->bit_depth == 8)\n             if (*dp++ == 0)\n                zero_samples++;\n\n          if (row_info->bit_depth == 16)\n          {\n             if ((*dp | *(dp+1)) == 0)\n                zero_samples++;\n             dp+=2;\n          }\n       }\n    }\n    else /* Other color types */\n    {\n       png_uint_32 n, nstop;\n       int channel;\n       int color_channels = row_info->channels;\n       if (row_info->color_type > 3)\n          color_channels--;\n\n       for (n = 0, nstop=row_info->width; n<nstop; n++)\n       {\n          for (channel = 0; channel < color_channels; channel++)\n          {\n             if (row_info->bit_depth == 8)\n                if (*dp++ == 0)\n                   zero_samples++;\n\n             if (row_info->bit_depth == 16)\n             {\n                if ((*dp | *(dp+1)) == 0)\n                   zero_samples++;\n\n                dp+=2;\n             }\n          }\n          if (row_info->color_type > 3)\n          {\n             dp++;\n             if (row_info->bit_depth == 16)\n                dp++;\n          }\n       }\n    }\n}\n#endif /* WRITE_USER_TRANSFORM */\n\n#ifndef PNG_STDIO_SUPPORTED\n/* START of code to validate stdio-free compilation */\n/* These copies of the default read/write functions come from pngrio.c and\n * pngwio.c.  They allow \"don't include stdio\" testing of the library.\n * This is the function that does the actual reading of data.  If you are\n * not reading from a standard C stream, you should create a replacement\n * read_data function and use it at run time with png_set_read_fn(), rather\n * than changing the library.\n */\n\n#ifdef PNG_IO_STATE_SUPPORTED\nvoid\npngtest_check_io_state(png_structp png_ptr, png_size_t data_length,\n   png_uint_32 io_op);\nvoid\npngtest_check_io_state(png_structp png_ptr, png_size_t data_length,\n   png_uint_32 io_op)\n{\n   png_uint_32 io_state = png_get_io_state(png_ptr);\n   int err = 0;\n\n   /* Check if the current operation (reading / writing) is as expected. */\n   if ((io_state & PNG_IO_MASK_OP) != io_op)\n      png_error(png_ptr, \"Incorrect operation in I/O state\");\n\n   /* Check if the buffer size specific to the current location\n    * (file signature / header / data / crc) is as expected.\n    */\n   switch (io_state & PNG_IO_MASK_LOC)\n   {\n   case PNG_IO_SIGNATURE:\n      if (data_length > 8)\n         err = 1;\n      break;\n   case PNG_IO_CHUNK_HDR:\n      if (data_length != 8)\n         err = 1;\n      break;\n   case PNG_IO_CHUNK_DATA:\n      break;  /* no restrictions here */\n   case PNG_IO_CHUNK_CRC:\n      if (data_length != 4)\n         err = 1;\n      break;\n   default:\n      err = 1;  /* uninitialized */\n   }\n   if (err != 0)\n      png_error(png_ptr, \"Bad I/O state or buffer size\");\n}\n#endif\n\nstatic void PNGCBAPI\npngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)\n{\n   png_size_t check = 0;\n   png_voidp io_ptr;\n\n   /* fread() returns 0 on error, so it is OK to store this in a png_size_t\n    * instead of an int, which is what fread() actually returns.\n    */\n   io_ptr = png_get_io_ptr(png_ptr);\n   if (io_ptr != NULL)\n   {\n      check = fread(data, 1, length, (png_FILE_p)io_ptr);\n   }\n\n   if (check != length)\n   {\n      png_error(png_ptr, \"Read Error\");\n   }\n\n#ifdef PNG_IO_STATE_SUPPORTED\n   pngtest_check_io_state(png_ptr, length, PNG_IO_READING);\n#endif\n}\n\n#ifdef PNG_WRITE_FLUSH_SUPPORTED\nstatic void PNGCBAPI\npngtest_flush(png_structp png_ptr)\n{\n   /* Do nothing; fflush() is said to be just a waste of energy. */\n   PNG_UNUSED(png_ptr)   /* Stifle compiler warning */\n}\n#endif\n\n/* This is the function that does the actual writing of data.  If you are\n * not writing to a standard C stream, you should create a replacement\n * write_data function and use it at run time with png_set_write_fn(), rather\n * than changing the library.\n */\nstatic void PNGCBAPI\npngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)\n{\n   png_size_t check;\n\n   check = fwrite(data, 1, length, (png_FILE_p)png_get_io_ptr(png_ptr));\n\n   if (check != length)\n   {\n      png_error(png_ptr, \"Write Error\");\n   }\n\n#ifdef PNG_IO_STATE_SUPPORTED\n   pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING);\n#endif\n}\n#endif /* !STDIO */\n\n/* This function is called when there is a warning, but the library thinks\n * it can continue anyway.  Replacement functions don't have to do anything\n * here if you don't want to.  In the default configuration, png_ptr is\n * not used, but it is passed in case it may be useful.\n */\ntypedef struct\n{\n   PNG_CONST char *file_name;\n}  pngtest_error_parameters;\n\nstatic void PNGCBAPI\npngtest_warning(png_structp png_ptr, png_const_charp message)\n{\n   PNG_CONST char *name = \"UNKNOWN (ERROR!)\";\n   pngtest_error_parameters *test =\n      (pngtest_error_parameters*)png_get_error_ptr(png_ptr);\n\n   ++warning_count;\n\n   if (test != NULL && test->file_name != NULL)\n      name = test->file_name;\n\n   fprintf(STDERR, \"%s: libpng warning: %s\\n\", name, message);\n}\n\n/* This is the default error handling function.  Note that replacements for\n * this function MUST NOT RETURN, or the program will likely crash.  This\n * function is used by default, or if the program supplies NULL for the\n * error function pointer in png_set_error_fn().\n */\nstatic void PNGCBAPI\npngtest_error(png_structp png_ptr, png_const_charp message)\n{\n   ++error_count;\n\n   pngtest_warning(png_ptr, message);\n   /* We can return because png_error calls the default handler, which is\n    * actually OK in this case.\n    */\n}\n\n/* END of code to validate stdio-free compilation */\n\n/* START of code to validate memory allocation and deallocation */\n#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG\n\n/* Allocate memory.  For reasonable files, size should never exceed\n * 64K.  However, zlib may allocate more than 64K if you don't tell\n * it not to.  See zconf.h and png.h for more information.  zlib does\n * need to allocate exactly 64K, so whatever you call here must\n * have the ability to do that.\n *\n * This piece of code can be compiled to validate max 64K allocations\n * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K.\n */\ntypedef struct memory_information\n{\n   png_alloc_size_t          size;\n   png_voidp                 pointer;\n   struct memory_information *next;\n} memory_information;\ntypedef memory_information *memory_infop;\n\nstatic memory_infop pinformation = NULL;\nstatic int current_allocation = 0;\nstatic int maximum_allocation = 0;\nstatic int total_allocation = 0;\nstatic int num_allocations = 0;\n\npng_voidp PNGCBAPI png_debug_malloc PNGARG((png_structp png_ptr,\n    png_alloc_size_t size));\nvoid PNGCBAPI png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr));\n\npng_voidp\nPNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size)\n{\n\n   /* png_malloc has already tested for NULL; png_create_struct calls\n    * png_debug_malloc directly, with png_ptr == NULL which is OK\n    */\n\n   if (size == 0)\n      return (NULL);\n\n   /* This calls the library allocator twice, once to get the requested\n      buffer and once to get a new free list entry. */\n   {\n      /* Disable malloc_fn and free_fn */\n      memory_infop pinfo;\n      png_set_mem_fn(png_ptr, NULL, NULL, NULL);\n      pinfo = (memory_infop)png_malloc(png_ptr,\n         (sizeof *pinfo));\n      pinfo->size = size;\n      current_allocation += size;\n      total_allocation += size;\n      num_allocations ++;\n\n      if (current_allocation > maximum_allocation)\n         maximum_allocation = current_allocation;\n\n      pinfo->pointer = png_malloc(png_ptr, size);\n      /* Restore malloc_fn and free_fn */\n\n      png_set_mem_fn(png_ptr,\n          NULL, png_debug_malloc, png_debug_free);\n\n      if (size != 0 && pinfo->pointer == NULL)\n      {\n         current_allocation -= size;\n         total_allocation -= size;\n         png_error(png_ptr,\n           \"out of memory in pngtest->png_debug_malloc\");\n      }\n\n      pinfo->next = pinformation;\n      pinformation = pinfo;\n      /* Make sure the caller isn't assuming zeroed memory. */\n      memset(pinfo->pointer, 0xdd, pinfo->size);\n\n      if (verbose != 0)\n         printf(\"png_malloc %lu bytes at %p\\n\", (unsigned long)size,\n            pinfo->pointer);\n\n      return (png_voidp)(pinfo->pointer);\n   }\n}\n\n/* Free a pointer.  It is removed from the list at the same time. */\nvoid PNGCBAPI\npng_debug_free(png_structp png_ptr, png_voidp ptr)\n{\n   if (png_ptr == NULL)\n      fprintf(STDERR, \"NULL pointer to png_debug_free.\\n\");\n\n   if (ptr == 0)\n   {\n#if 0 /* This happens all the time. */\n      fprintf(STDERR, \"WARNING: freeing NULL pointer\\n\");\n#endif\n      return;\n   }\n\n   /* Unlink the element from the list. */\n   if (pinformation != NULL)\n   {\n      memory_infop *ppinfo = &pinformation;\n\n      for (;;)\n      {\n         memory_infop pinfo = *ppinfo;\n\n         if (pinfo->pointer == ptr)\n         {\n            *ppinfo = pinfo->next;\n            current_allocation -= pinfo->size;\n            if (current_allocation < 0)\n               fprintf(STDERR, \"Duplicate free of memory\\n\");\n            /* We must free the list element too, but first kill\n               the memory that is to be freed. */\n            memset(ptr, 0x55, pinfo->size);\n            free(pinfo);\n            pinfo = NULL;\n            break;\n         }\n\n         if (pinfo->next == NULL)\n         {\n            fprintf(STDERR, \"Pointer %p not found\\n\", ptr);\n            break;\n         }\n\n         ppinfo = &pinfo->next;\n      }\n   }\n\n   /* Finally free the data. */\n   if (verbose != 0)\n      printf(\"Freeing %p\\n\", ptr);\n\n   if (ptr != NULL)\n      free(ptr);\n   ptr = NULL;\n}\n#endif /* USER_MEM && DEBUG */\n/* END of code to test memory allocation/deallocation */\n\n\n#ifdef PNG_READ_USER_CHUNKS_SUPPORTED\n/* Demonstration of user chunk support of the sTER and vpAg chunks */\n\n/* (sTER is a public chunk not yet known by libpng.  vpAg is a private\nchunk used in ImageMagick to store \"virtual page\" size).  */\n\nstatic struct user_chunk_data\n{\n   png_const_infop info_ptr;\n   png_uint_32     vpAg_width, vpAg_height;\n   png_byte        vpAg_units;\n   png_byte        sTER_mode;\n   int             location[2];\n}\nuser_chunk_data;\n\n/* Used for location and order; zero means nothing. */\n#define have_sTER   0x01\n#define have_vpAg   0x02\n#define before_PLTE 0x10\n#define before_IDAT 0x20\n#define after_IDAT  0x40\n\nstatic void\ninit_callback_info(png_const_infop info_ptr)\n{\n   MEMZERO(user_chunk_data);\n   user_chunk_data.info_ptr = info_ptr;\n}\n\nstatic int\nset_location(png_structp png_ptr, struct user_chunk_data *data, int what)\n{\n   int location;\n\n   if ((data->location[0] & what) != 0 || (data->location[1] & what) != 0)\n      return 0; /* already have one of these */\n\n   /* Find where we are (the code below zeroes info_ptr to indicate that the\n    * chunks before the first IDAT have been read.)\n    */\n   if (data->info_ptr == NULL) /* after IDAT */\n      location = what | after_IDAT;\n\n   else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE) != 0)\n      location = what | before_IDAT;\n\n   else\n      location = what | before_PLTE;\n\n   if (data->location[0] == 0)\n      data->location[0] = location;\n\n   else\n      data->location[1] = location;\n\n   return 1; /* handled */\n}\n\nstatic int PNGCBAPI\nread_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk)\n{\n   struct user_chunk_data *my_user_chunk_data =\n      (struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr);\n\n   if (my_user_chunk_data == NULL)\n      png_error(png_ptr, \"lost user chunk pointer\");\n\n   /* Return one of the following:\n    *    return (-n);  chunk had an error\n    *    return (0);  did not recognize\n    *    return (n);  success\n    *\n    * The unknown chunk structure contains the chunk data:\n    * png_byte name[5];\n    * png_byte *data;\n    * png_size_t size;\n    *\n    * Note that libpng has already taken care of the CRC handling.\n    */\n\n   if (chunk->name[0] == 115 && chunk->name[1] ==  84 &&     /* s  T */\n       chunk->name[2] ==  69 && chunk->name[3] ==  82)       /* E  R */\n      {\n         /* Found sTER chunk */\n         if (chunk->size != 1)\n            return (-1); /* Error return */\n\n         if (chunk->data[0] != 0 && chunk->data[0] != 1)\n            return (-1);  /* Invalid mode */\n\n         if (set_location(png_ptr, my_user_chunk_data, have_sTER) != 0)\n         {\n            my_user_chunk_data->sTER_mode=chunk->data[0];\n            return (1);\n         }\n\n         else\n            return (0); /* duplicate sTER - give it to libpng */\n      }\n\n   if (chunk->name[0] != 118 || chunk->name[1] != 112 ||    /* v  p */\n       chunk->name[2] !=  65 || chunk->name[3] != 103)      /* A  g */\n      return (0); /* Did not recognize */\n\n   /* Found ImageMagick vpAg chunk */\n\n   if (chunk->size != 9)\n      return (-1); /* Error return */\n\n   if (set_location(png_ptr, my_user_chunk_data, have_vpAg) == 0)\n      return (0);  /* duplicate vpAg */\n\n   my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data);\n   my_user_chunk_data->vpAg_height = png_get_uint_31(png_ptr, chunk->data + 4);\n   my_user_chunk_data->vpAg_units = chunk->data[8];\n\n   return (1);\n}\n\n#ifdef PNG_WRITE_SUPPORTED\nstatic void\nwrite_sTER_chunk(png_structp write_ptr)\n{\n   png_byte sTER[5] = {115,  84,  69,  82, '\\0'};\n\n   if (verbose != 0)\n      fprintf(STDERR, \"\\n stereo mode = %d\\n\", user_chunk_data.sTER_mode);\n\n   png_write_chunk(write_ptr, sTER, &user_chunk_data.sTER_mode, 1);\n}\n\nstatic void\nwrite_vpAg_chunk(png_structp write_ptr)\n{\n   png_byte vpAg[5] = {118, 112,  65, 103, '\\0'};\n\n   png_byte vpag_chunk_data[9];\n\n   if (verbose != 0)\n      fprintf(STDERR, \" vpAg = %lu x %lu, units = %d\\n\",\n        (unsigned long)user_chunk_data.vpAg_width,\n        (unsigned long)user_chunk_data.vpAg_height,\n        user_chunk_data.vpAg_units);\n\n   png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width);\n   png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height);\n   vpag_chunk_data[8] = user_chunk_data.vpAg_units;\n   png_write_chunk(write_ptr, vpAg, vpag_chunk_data, 9);\n}\n\nstatic void\nwrite_chunks(png_structp write_ptr, int location)\n{\n   int i;\n\n   /* Notice that this preserves the original chunk order, however chunks\n    * intercepted by the callback will be written *after* chunks passed to\n    * libpng.  This will actually reverse a pair of sTER chunks or a pair of\n    * vpAg chunks, resulting in an error later.  This is not worth worrying\n    * about - the chunks should not be duplicated!\n    */\n   for (i=0; i<2; ++i)\n   {\n      if (user_chunk_data.location[i] == (location | have_sTER))\n         write_sTER_chunk(write_ptr);\n\n      else if (user_chunk_data.location[i] == (location | have_vpAg))\n         write_vpAg_chunk(write_ptr);\n   }\n}\n#endif /* WRITE */\n#else /* !READ_USER_CHUNKS */\n#  define write_chunks(pp,loc) ((void)0)\n#endif\n/* END of code to demonstrate user chunk support */\n\n/* START of code to check that libpng has the required text support; this only\n * checks for the write support because if read support is missing the chunk\n * will simply not be reported back to pngtest.\n */\n#ifdef PNG_TEXT_SUPPORTED\nstatic void\npngtest_check_text_support(png_structp png_ptr, png_textp text_ptr,\n   int num_text)\n{\n   while (num_text > 0)\n   {\n      switch (text_ptr[--num_text].compression)\n      {\n         case PNG_TEXT_COMPRESSION_NONE:\n            break;\n\n         case PNG_TEXT_COMPRESSION_zTXt:\n#           ifndef PNG_WRITE_zTXt_SUPPORTED\n               ++unsupported_chunks;\n               /* In libpng 1.7 this now does an app-error, so stop it: */\n               text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE;\n#           endif\n            break;\n\n         case PNG_ITXT_COMPRESSION_NONE:\n         case PNG_ITXT_COMPRESSION_zTXt:\n#           ifndef PNG_WRITE_iTXt_SUPPORTED\n               ++unsupported_chunks;\n               text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE;\n#           endif\n            break;\n\n         default:\n            /* This is an error */\n            png_error(png_ptr, \"invalid text chunk compression field\");\n            break;\n      }\n   }\n}\n#endif\n/* END of code to check that libpng has the required text support */\n\n/* Test one file */\nstatic int\ntest_one_file(PNG_CONST char *inname, PNG_CONST char *outname)\n{\n   static png_FILE_p fpin;\n   static png_FILE_p fpout;  /* \"static\" prevents setjmp corruption */\n   pngtest_error_parameters error_parameters;\n   png_structp read_ptr;\n   png_infop read_info_ptr, end_info_ptr;\n#ifdef PNG_WRITE_SUPPORTED\n   png_structp write_ptr;\n   png_infop write_info_ptr;\n   png_infop write_end_info_ptr;\n#ifdef PNG_WRITE_FILTER_SUPPORTED\n   int interlace_preserved = 1;\n#endif /* WRITE_FILTER */\n#else /* !WRITE */\n   png_structp write_ptr = NULL;\n   png_infop write_info_ptr = NULL;\n   png_infop write_end_info_ptr = NULL;\n#endif /* !WRITE */\n   png_bytep row_buf;\n   png_uint_32 y;\n   png_uint_32 width, height;\n   volatile int num_passes;\n   int pass;\n   int bit_depth, color_type;\n\n   row_buf = NULL;\n   error_parameters.file_name = inname;\n\n   if ((fpin = fopen(inname, \"rb\")) == NULL)\n   {\n      fprintf(STDERR, \"Could not find input file %s\\n\", inname);\n      return (1);\n   }\n\n   if ((fpout = fopen(outname, \"wb\")) == NULL)\n   {\n      fprintf(STDERR, \"Could not open output file %s\\n\", outname);\n      FCLOSE(fpin);\n      return (1);\n   }\n\n   pngtest_debug(\"Allocating read and write structures\");\n#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG\n   read_ptr =\n      png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL,\n      NULL, NULL, NULL, png_debug_malloc, png_debug_free);\n#else\n   read_ptr =\n      png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);\n#endif\n   png_set_error_fn(read_ptr, &error_parameters, pngtest_error,\n      pngtest_warning);\n\n#ifdef PNG_WRITE_SUPPORTED\n#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG\n   write_ptr =\n      png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL,\n      NULL, NULL, NULL, png_debug_malloc, png_debug_free);\n#else\n   write_ptr =\n      png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);\n#endif\n   png_set_error_fn(write_ptr, &error_parameters, pngtest_error,\n      pngtest_warning);\n#endif\n   pngtest_debug(\"Allocating read_info, write_info and end_info structures\");\n   read_info_ptr = png_create_info_struct(read_ptr);\n   end_info_ptr = png_create_info_struct(read_ptr);\n#ifdef PNG_WRITE_SUPPORTED\n   write_info_ptr = png_create_info_struct(write_ptr);\n   write_end_info_ptr = png_create_info_struct(write_ptr);\n#endif\n\n#ifdef PNG_READ_USER_CHUNKS_SUPPORTED\n   init_callback_info(read_info_ptr);\n   png_set_read_user_chunk_fn(read_ptr, &user_chunk_data,\n     read_user_chunk_callback);\n#endif\n\n#ifdef PNG_SETJMP_SUPPORTED\n   pngtest_debug(\"Setting jmpbuf for read struct\");\n   if (setjmp(png_jmpbuf(read_ptr)))\n   {\n      fprintf(STDERR, \"%s -> %s: libpng read error\\n\", inname, outname);\n      png_free(read_ptr, row_buf);\n      row_buf = NULL;\n      png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);\n#ifdef PNG_WRITE_SUPPORTED\n      png_destroy_info_struct(write_ptr, &write_end_info_ptr);\n      png_destroy_write_struct(&write_ptr, &write_info_ptr);\n#endif\n      FCLOSE(fpin);\n      FCLOSE(fpout);\n      return (1);\n   }\n\n#ifdef PNG_WRITE_SUPPORTED\n   pngtest_debug(\"Setting jmpbuf for write struct\");\n\n   if (setjmp(png_jmpbuf(write_ptr)))\n   {\n      fprintf(STDERR, \"%s -> %s: libpng write error\\n\", inname, outname);\n      png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);\n      png_destroy_info_struct(write_ptr, &write_end_info_ptr);\n#ifdef PNG_WRITE_SUPPORTED\n      png_destroy_write_struct(&write_ptr, &write_info_ptr);\n#endif\n      FCLOSE(fpin);\n      FCLOSE(fpout);\n      return (1);\n   }\n#endif\n#endif\n\n   if (strict != 0)\n   {\n      /* Treat png_benign_error() as errors on read */\n      png_set_benign_errors(read_ptr, 0);\n\n#ifdef PNG_WRITE_SUPPORTED\n      /* Treat them as errors on write */\n      png_set_benign_errors(write_ptr, 0);\n#endif\n\n      /* if strict is not set, then app warnings and errors are treated as\n       * warnings in release builds, but not in unstable builds; this can be\n       * changed with '--relaxed'.\n       */\n   }\n\n   else if (relaxed != 0)\n   {\n      /* Allow application (pngtest) errors and warnings to pass */\n      png_set_benign_errors(read_ptr, 1);\n\n#ifdef PNG_WRITE_SUPPORTED\n      png_set_benign_errors(write_ptr, 1);\n#endif\n   }\n\n   pngtest_debug(\"Initializing input and output streams\");\n#ifdef PNG_STDIO_SUPPORTED\n   png_init_io(read_ptr, fpin);\n#  ifdef PNG_WRITE_SUPPORTED\n   png_init_io(write_ptr, fpout);\n#  endif\n#else\n   png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);\n#  ifdef PNG_WRITE_SUPPORTED\n   png_set_write_fn(write_ptr, (png_voidp)fpout,  pngtest_write_data,\n#    ifdef PNG_WRITE_FLUSH_SUPPORTED\n      pngtest_flush);\n#    else\n      NULL);\n#    endif\n#  endif\n#endif\n\n   if (status_dots_requested == 1)\n   {\n#ifdef PNG_WRITE_SUPPORTED\n      png_set_write_status_fn(write_ptr, write_row_callback);\n#endif\n      png_set_read_status_fn(read_ptr, read_row_callback);\n   }\n\n   else\n   {\n#ifdef PNG_WRITE_SUPPORTED\n      png_set_write_status_fn(write_ptr, NULL);\n#endif\n      png_set_read_status_fn(read_ptr, NULL);\n   }\n\n#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED\n   png_set_read_user_transform_fn(read_ptr, read_user_callback);\n#endif\n#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED\n   zero_samples = 0;\n   png_set_write_user_transform_fn(write_ptr, count_zero_samples);\n#endif\n\n#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED\n   /* Preserve all the unknown chunks, if possible.  If this is disabled then,\n    * even if the png_{get,set}_unknown_chunks stuff is enabled, we can't use\n    * libpng to *save* the unknown chunks on read (because we can't switch the\n    * save option on!)\n    *\n    * Notice that if SET_UNKNOWN_CHUNKS is *not* supported read will discard all\n    * unknown chunks and write will write them all.\n    */\n#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED\n   png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,\n      NULL, 0);\n#endif\n#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED\n   png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS,\n      NULL, 0);\n#endif\n#endif\n\n   pngtest_debug(\"Reading info struct\");\n   png_read_info(read_ptr, read_info_ptr);\n\n#ifdef PNG_READ_USER_CHUNKS_SUPPORTED\n   /* This is a bit of a hack; there is no obvious way in the callback function\n    * to determine that the chunks before the first IDAT have been read, so\n    * remove the info_ptr (which is only used to determine position relative to\n    * PLTE) here to indicate that we are after the IDAT.\n    */\n   user_chunk_data.info_ptr = NULL;\n#endif\n\n   pngtest_debug(\"Transferring info struct\");\n   {\n      int interlace_type, compression_type, filter_type;\n\n      if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,\n          &color_type, &interlace_type, &compression_type, &filter_type) != 0)\n      {\n         png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,\n            color_type, interlace_type, compression_type, filter_type);\n         /* num_passes may not be available below if interlace support is not\n          * provided by libpng for both read and write.\n          */\n         switch (interlace_type)\n         {\n            case PNG_INTERLACE_NONE:\n               num_passes = 1;\n               break;\n\n            case PNG_INTERLACE_ADAM7:\n               num_passes = 7;\n               break;\n\n            default:\n               png_error(read_ptr, \"invalid interlace type\");\n               /*NOT REACHED*/\n         }\n      }\n\n      else\n         png_error(read_ptr, \"png_get_IHDR failed\");\n   }\n#ifdef PNG_FIXED_POINT_SUPPORTED\n#ifdef PNG_cHRM_SUPPORTED\n   {\n      png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,\n         blue_y;\n\n      if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y,\n         &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)\n      {\n         png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,\n            red_y, green_x, green_y, blue_x, blue_y);\n      }\n   }\n#endif\n#ifdef PNG_gAMA_SUPPORTED\n   {\n      png_fixed_point gamma;\n\n      if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0)\n         png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);\n   }\n#endif\n#else /* Use floating point versions */\n#ifdef PNG_FLOATING_POINT_SUPPORTED\n#ifdef PNG_cHRM_SUPPORTED\n   {\n      double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,\n         blue_y;\n\n      if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,\n         &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)\n      {\n         png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,\n            red_y, green_x, green_y, blue_x, blue_y);\n      }\n   }\n#endif\n#ifdef PNG_gAMA_SUPPORTED\n   {\n      double gamma;\n\n      if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0)\n         png_set_gAMA(write_ptr, write_info_ptr, gamma);\n   }\n#endif\n#endif /* Floating point */\n#endif /* Fixed point */\n#ifdef PNG_iCCP_SUPPORTED\n   {\n      png_charp name;\n      png_bytep profile;\n      png_uint_32 proflen;\n      int compression_type;\n\n      if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,\n                      &profile, &proflen) != 0)\n      {\n         png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,\n                      profile, proflen);\n      }\n   }\n#endif\n#ifdef PNG_sRGB_SUPPORTED\n   {\n      int intent;\n\n      if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0)\n         png_set_sRGB(write_ptr, write_info_ptr, intent);\n   }\n#endif\n   {\n      png_colorp palette;\n      int num_palette;\n\n      if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0)\n         png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);\n   }\n#ifdef PNG_bKGD_SUPPORTED\n   {\n      png_color_16p background;\n\n      if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0)\n      {\n         png_set_bKGD(write_ptr, write_info_ptr, background);\n      }\n   }\n#endif\n#ifdef PNG_hIST_SUPPORTED\n   {\n      png_uint_16p hist;\n\n      if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0)\n         png_set_hIST(write_ptr, write_info_ptr, hist);\n   }\n#endif\n#ifdef PNG_oFFs_SUPPORTED\n   {\n      png_int_32 offset_x, offset_y;\n      int unit_type;\n\n      if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y,\n          &unit_type) != 0)\n      {\n         png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);\n      }\n   }\n#endif\n#ifdef PNG_pCAL_SUPPORTED\n   {\n      png_charp purpose, units;\n      png_charpp params;\n      png_int_32 X0, X1;\n      int type, nparams;\n\n      if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,\n         &nparams, &units, &params) != 0)\n      {\n         png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,\n            nparams, units, params);\n      }\n   }\n#endif\n#ifdef PNG_pHYs_SUPPORTED\n   {\n      png_uint_32 res_x, res_y;\n      int unit_type;\n\n      if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y,\n          &unit_type) != 0)\n         png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);\n   }\n#endif\n#ifdef PNG_sBIT_SUPPORTED\n   {\n      png_color_8p sig_bit;\n\n      if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0)\n         png_set_sBIT(write_ptr, write_info_ptr, sig_bit);\n   }\n#endif\n#ifdef PNG_sCAL_SUPPORTED\n#if defined(PNG_FLOATING_POINT_SUPPORTED) && \\\n   defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)\n   {\n      int unit;\n      double scal_width, scal_height;\n\n      if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,\n         &scal_height) != 0)\n      {\n         png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);\n      }\n   }\n#else\n#ifdef PNG_FIXED_POINT_SUPPORTED\n   {\n      int unit;\n      png_charp scal_width, scal_height;\n\n      if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,\n          &scal_height) != 0)\n      {\n         png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width,\n             scal_height);\n      }\n   }\n#endif\n#endif\n#endif\n\n#ifdef PNG_sPLT_SUPPORTED\n   {\n       png_sPLT_tp entries;\n\n       int num_entries = (int) png_get_sPLT(read_ptr, read_info_ptr, &entries);\n       if (num_entries)\n       {\n           png_set_sPLT(write_ptr, write_info_ptr, entries, num_entries);\n       }\n   }\n#endif\n\n#ifdef PNG_TEXT_SUPPORTED\n   {\n      png_textp text_ptr;\n      int num_text;\n\n      if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)\n      {\n         pngtest_debug1(\"Handling %d iTXt/tEXt/zTXt chunks\", num_text);\n\n         pngtest_check_text_support(read_ptr, text_ptr, num_text);\n\n         if (verbose != 0)\n         {\n            int i;\n\n            printf(\"\\n\");\n            for (i=0; i<num_text; i++)\n            {\n               printf(\"   Text compression[%d]=%d\\n\",\n                     i, text_ptr[i].compression);\n            }\n         }\n\n         png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);\n      }\n   }\n#endif\n#ifdef PNG_tIME_SUPPORTED\n   {\n      png_timep mod_time;\n\n      if (png_get_tIME(read_ptr, read_info_ptr, &mod_time) != 0)\n      {\n         png_set_tIME(write_ptr, write_info_ptr, mod_time);\n#ifdef PNG_TIME_RFC1123_SUPPORTED\n         if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0)\n            tIME_string[(sizeof tIME_string) - 1] = '\\0';\n\n         else\n         {\n            strncpy(tIME_string, \"*** invalid time ***\", (sizeof tIME_string));\n            tIME_string[(sizeof tIME_string) - 1] = '\\0';\n         }\n\n         tIME_chunk_present++;\n#endif /* TIME_RFC1123 */\n      }\n   }\n#endif\n#ifdef PNG_tRNS_SUPPORTED\n   {\n      png_bytep trans_alpha;\n      int num_trans;\n      png_color_16p trans_color;\n\n      if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans,\n         &trans_color) != 0)\n      {\n         int sample_max = (1 << bit_depth);\n         /* libpng doesn't reject a tRNS chunk with out-of-range samples */\n         if (!((color_type == PNG_COLOR_TYPE_GRAY &&\n             (int)trans_color->gray > sample_max) ||\n             (color_type == PNG_COLOR_TYPE_RGB &&\n             ((int)trans_color->red > sample_max ||\n             (int)trans_color->green > sample_max ||\n             (int)trans_color->blue > sample_max))))\n            png_set_tRNS(write_ptr, write_info_ptr, trans_alpha, num_trans,\n               trans_color);\n      }\n   }\n#endif\n#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED\n   {\n      png_unknown_chunkp unknowns;\n      int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr,\n         &unknowns);\n\n      if (num_unknowns != 0)\n      {\n         png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,\n           num_unknowns);\n#if PNG_LIBPNG_VER < 10600\n         /* Copy the locations from the read_info_ptr.  The automatically\n          * generated locations in write_end_info_ptr are wrong prior to 1.6.0\n          * because they are reset from the write pointer (removed in 1.6.0).\n          */\n         {\n            int i;\n            for (i = 0; i < num_unknowns; i++)\n              png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,\n                unknowns[i].location);\n         }\n#endif\n      }\n   }\n#endif\n\n#ifdef PNG_WRITE_SUPPORTED\n   pngtest_debug(\"Writing info struct\");\n\n   /* Write the info in two steps so that if we write the 'unknown' chunks here\n    * they go to the correct place.\n    */\n   png_write_info_before_PLTE(write_ptr, write_info_ptr);\n\n   write_chunks(write_ptr, before_PLTE); /* before PLTE */\n\n   png_write_info(write_ptr, write_info_ptr);\n\n   write_chunks(write_ptr, before_IDAT); /* after PLTE */\n#endif\n\n#ifdef SINGLE_ROWBUF_ALLOC\n   pngtest_debug(\"Allocating row buffer...\");\n   row_buf = (png_bytep)png_malloc(read_ptr,\n      png_get_rowbytes(read_ptr, read_info_ptr));\n\n   pngtest_debug1(\"\\t0x%08lx\", (unsigned long)row_buf);\n#endif /* SINGLE_ROWBUF_ALLOC */\n   pngtest_debug(\"Writing row data\");\n\n#if defined(PNG_READ_INTERLACING_SUPPORTED) &&\\\n   defined(PNG_WRITE_INTERLACING_SUPPORTED)\n   /* Both must be defined for libpng to be able to handle the interlace,\n    * otherwise it gets handled below by simply reading and writing the passes\n    * directly.\n    */\n   if (png_set_interlace_handling(read_ptr) != num_passes)\n      png_error(write_ptr,\n            \"png_set_interlace_handling(read): wrong pass count \");\n   if (png_set_interlace_handling(write_ptr) != num_passes)\n      png_error(write_ptr,\n            \"png_set_interlace_handling(write): wrong pass count \");\n#else /* png_set_interlace_handling not called on either read or write */\n#  define calc_pass_height\n#endif /* not using libpng interlace handling */\n\n#ifdef PNGTEST_TIMING\n   t_stop = (float)clock();\n   t_misc += (t_stop - t_start);\n   t_start = t_stop;\n#endif\n   for (pass = 0; pass < num_passes; pass++)\n   {\n#     ifdef calc_pass_height\n         png_uint_32 pass_height;\n\n         if (num_passes == 7) /* interlaced */\n         {\n            if (PNG_PASS_COLS(width, pass) > 0)\n               pass_height = PNG_PASS_ROWS(height, pass);\n\n            else\n               pass_height = 0;\n         }\n\n         else /* not interlaced */\n            pass_height = height;\n#     else\n#        define pass_height height\n#     endif\n\n      pngtest_debug1(\"Writing row data for pass %d\", pass);\n      for (y = 0; y < pass_height; y++)\n      {\n#ifndef SINGLE_ROWBUF_ALLOC\n         pngtest_debug2(\"Allocating row buffer (pass %d, y = %u)...\", pass, y);\n\n         row_buf = (png_bytep)png_malloc(read_ptr,\n            png_get_rowbytes(read_ptr, read_info_ptr));\n\n         pngtest_debug2(\"\\t0x%08lx (%lu bytes)\", (unsigned long)row_buf,\n            (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));\n\n#endif /* !SINGLE_ROWBUF_ALLOC */\n         png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);\n\n#ifdef PNG_WRITE_SUPPORTED\n#ifdef PNGTEST_TIMING\n         t_stop = (float)clock();\n         t_decode += (t_stop - t_start);\n         t_start = t_stop;\n#endif\n         png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);\n#ifdef PNGTEST_TIMING\n         t_stop = (float)clock();\n         t_encode += (t_stop - t_start);\n         t_start = t_stop;\n#endif\n#endif /* WRITE */\n\n#ifndef SINGLE_ROWBUF_ALLOC\n         pngtest_debug2(\"Freeing row buffer (pass %d, y = %u)\", pass, y);\n         png_free(read_ptr, row_buf);\n         row_buf = NULL;\n#endif /* !SINGLE_ROWBUF_ALLOC */\n      }\n   }\n\n#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED\n#  ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED\n      png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);\n#  endif\n#  ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED\n      png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);\n#  endif\n#endif\n\n   pngtest_debug(\"Reading and writing end_info data\");\n\n   png_read_end(read_ptr, end_info_ptr);\n#ifdef PNG_TEXT_SUPPORTED\n   {\n      png_textp text_ptr;\n      int num_text;\n\n      if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0)\n      {\n         pngtest_debug1(\"Handling %d iTXt/tEXt/zTXt chunks\", num_text);\n\n         pngtest_check_text_support(read_ptr, text_ptr, num_text);\n\n         if (verbose != 0)\n         {\n            int i;\n\n            printf(\"\\n\");\n            for (i=0; i<num_text; i++)\n            {\n               printf(\"   Text compression[%d]=%d\\n\",\n                     i, text_ptr[i].compression);\n            }\n         }\n\n         png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text);\n      }\n   }\n#endif\n#ifdef PNG_tIME_SUPPORTED\n   {\n      png_timep mod_time;\n\n      if (png_get_tIME(read_ptr, end_info_ptr, &mod_time) != 0)\n      {\n         png_set_tIME(write_ptr, write_end_info_ptr, mod_time);\n#ifdef PNG_TIME_RFC1123_SUPPORTED\n         if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0)\n            tIME_string[(sizeof tIME_string) - 1] = '\\0';\n\n         else\n         {\n            strncpy(tIME_string, \"*** invalid time ***\", sizeof tIME_string);\n            tIME_string[(sizeof tIME_string)-1] = '\\0';\n         }\n\n         tIME_chunk_present++;\n#endif /* TIME_RFC1123 */\n      }\n   }\n#endif\n#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED\n   {\n      png_unknown_chunkp unknowns;\n      int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr,\n         &unknowns);\n\n      if (num_unknowns != 0)\n      {\n         png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,\n           num_unknowns);\n#if PNG_LIBPNG_VER < 10600\n         /* Copy the locations from the read_info_ptr.  The automatically\n          * generated locations in write_end_info_ptr are wrong prior to 1.6.0\n          * because they are reset from the write pointer (removed in 1.6.0).\n          */\n         {\n            int i;\n            for (i = 0; i < num_unknowns; i++)\n              png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,\n                unknowns[i].location);\n         }\n#endif\n      }\n   }\n#endif\n\n#ifdef PNG_WRITE_SUPPORTED\n#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED\n   /* Normally one would use Z_DEFAULT_STRATEGY for text compression.\n    * This is here just to make pngtest replicate the results from libpng\n    * versions prior to 1.5.4, and to test this new API.\n    */\n   png_set_text_compression_strategy(write_ptr, Z_FILTERED);\n#endif\n\n   /* When the unknown vpAg/sTER chunks are written by pngtest the only way to\n    * do it is to write them *before* calling png_write_end.  When unknown\n    * chunks are written by libpng, however, they are written just before IEND.\n    * There seems to be no way round this, however vpAg/sTER are not expected\n    * after IDAT.\n    */\n   write_chunks(write_ptr, after_IDAT);\n\n   png_write_end(write_ptr, write_end_info_ptr);\n#endif\n\n#ifdef PNG_EASY_ACCESS_SUPPORTED\n   if (verbose != 0)\n   {\n      png_uint_32 iwidth, iheight;\n      iwidth = png_get_image_width(write_ptr, write_info_ptr);\n      iheight = png_get_image_height(write_ptr, write_info_ptr);\n      fprintf(STDERR, \"\\n Image width = %lu, height = %lu\\n\",\n         (unsigned long)iwidth, (unsigned long)iheight);\n   }\n#endif\n\n   pngtest_debug(\"Destroying data structs\");\n#ifdef SINGLE_ROWBUF_ALLOC\n   pngtest_debug(\"destroying row_buf for read_ptr\");\n   png_free(read_ptr, row_buf);\n   row_buf = NULL;\n#endif /* SINGLE_ROWBUF_ALLOC */\n   pngtest_debug(\"destroying read_ptr, read_info_ptr, end_info_ptr\");\n   png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);\n#ifdef PNG_WRITE_SUPPORTED\n   pngtest_debug(\"destroying write_end_info_ptr\");\n   png_destroy_info_struct(write_ptr, &write_end_info_ptr);\n   pngtest_debug(\"destroying write_ptr, write_info_ptr\");\n   png_destroy_write_struct(&write_ptr, &write_info_ptr);\n#endif\n   pngtest_debug(\"Destruction complete.\");\n\n   FCLOSE(fpin);\n   FCLOSE(fpout);\n\n   /* Summarize any warnings or errors and in 'strict' mode fail the test.\n    * Unsupported chunks can result in warnings, in that case ignore the strict\n    * setting, otherwise fail the test on warnings as well as errors.\n    */\n   if (error_count > 0)\n   {\n      /* We don't really expect to get here because of the setjmp handling\n       * above, but this is safe.\n       */\n      fprintf(STDERR, \"\\n  %s: %d libpng errors found (%d warnings)\",\n         inname, error_count, warning_count);\n\n      if (strict != 0)\n         return (1);\n   }\n\n#  ifdef PNG_WRITE_SUPPORTED\n      /* If there is no write support nothing was written! */\n      else if (unsupported_chunks > 0)\n      {\n         fprintf(STDERR, \"\\n  %s: unsupported chunks (%d)%s\",\n            inname, unsupported_chunks, strict ? \": IGNORED --strict!\" : \"\");\n      }\n#  endif\n\n   else if (warning_count > 0)\n   {\n      fprintf(STDERR, \"\\n  %s: %d libpng warnings found\",\n         inname, warning_count);\n\n      if (strict != 0)\n         return (1);\n   }\n\n   pngtest_debug(\"Opening files for comparison\");\n   if ((fpin = fopen(inname, \"rb\")) == NULL)\n   {\n      fprintf(STDERR, \"Could not find file %s\\n\", inname);\n      return (1);\n   }\n\n   if ((fpout = fopen(outname, \"rb\")) == NULL)\n   {\n      fprintf(STDERR, \"Could not find file %s\\n\", outname);\n      FCLOSE(fpin);\n      return (1);\n   }\n\n#if defined (PNG_WRITE_SUPPORTED) /* else nothing was written */ &&\\\n    defined (PNG_WRITE_FILTER_SUPPORTED)\n   if (interlace_preserved != 0) /* else the files will be changed */\n   {\n      for (;;)\n      {\n         static int wrote_question = 0;\n         png_size_t num_in, num_out;\n         char inbuf[256], outbuf[256];\n\n         num_in = fread(inbuf, 1, sizeof inbuf, fpin);\n         num_out = fread(outbuf, 1, sizeof outbuf, fpout);\n\n         if (num_in != num_out)\n         {\n            fprintf(STDERR, \"\\nFiles %s and %s are of a different size\\n\",\n                    inname, outname);\n\n            if (wrote_question == 0 && unsupported_chunks == 0)\n            {\n               fprintf(STDERR,\n         \"   Was %s written with the same maximum IDAT chunk size (%d bytes),\",\n                 inname, PNG_ZBUF_SIZE);\n               fprintf(STDERR,\n                 \"\\n   filtering heuristic (libpng default), compression\");\n               fprintf(STDERR,\n                 \" level (zlib default),\\n   and zlib version (%s)?\\n\\n\",\n                 ZLIB_VERSION);\n               wrote_question = 1;\n            }\n\n            FCLOSE(fpin);\n            FCLOSE(fpout);\n\n            if (strict != 0 && unsupported_chunks == 0)\n              return (1);\n\n            else\n              return (0);\n         }\n\n         if (num_in == 0)\n            break;\n\n         if (memcmp(inbuf, outbuf, num_in))\n         {\n            fprintf(STDERR, \"\\nFiles %s and %s are different\\n\", inname,\n               outname);\n\n            if (wrote_question == 0 && unsupported_chunks == 0)\n            {\n               fprintf(STDERR,\n         \"   Was %s written with the same maximum IDAT chunk size (%d bytes),\",\n                    inname, PNG_ZBUF_SIZE);\n               fprintf(STDERR,\n                 \"\\n   filtering heuristic (libpng default), compression\");\n               fprintf(STDERR,\n                 \" level (zlib default),\\n   and zlib version (%s)?\\n\\n\",\n                 ZLIB_VERSION);\n               wrote_question = 1;\n            }\n\n            FCLOSE(fpin);\n            FCLOSE(fpout);\n\n            /* NOTE: the unsupported_chunks escape is permitted here because\n             * unsupported text chunk compression will result in the compression\n             * mode being changed (to NONE) yet, in the test case, the result\n             * can be exactly the same size!\n             */\n            if (strict != 0 && unsupported_chunks == 0)\n              return (1);\n\n            else\n              return (0);\n         }\n      }\n   }\n#endif /* WRITE && WRITE_FILTER */\n\n   FCLOSE(fpin);\n   FCLOSE(fpout);\n\n   return (0);\n}\n\n/* Input and output filenames */\n#ifdef RISCOS\nstatic PNG_CONST char *inname = \"pngtest/png\";\nstatic PNG_CONST char *outname = \"pngout/png\";\n#else\nstatic PNG_CONST char *inname = \"pngtest.png\";\nstatic PNG_CONST char *outname = \"pngout.png\";\n#endif\n\nint\nmain(int argc, char *argv[])\n{\n   int multiple = 0;\n   int ierror = 0;\n\n   png_structp dummy_ptr;\n\n   fprintf(STDERR, \"\\n Testing libpng version %s\\n\", PNG_LIBPNG_VER_STRING);\n   fprintf(STDERR, \"   with zlib   version %s\\n\", ZLIB_VERSION);\n   fprintf(STDERR, \"%s\", png_get_copyright(NULL));\n   /* Show the version of libpng used in building the library */\n   fprintf(STDERR, \" library (%lu):%s\",\n      (unsigned long)png_access_version_number(),\n      png_get_header_version(NULL));\n\n   /* Show the version of libpng used in building the application */\n   fprintf(STDERR, \" pngtest (%lu):%s\", (unsigned long)PNG_LIBPNG_VER,\n      PNG_HEADER_VERSION_STRING);\n\n   /* Do some consistency checking on the memory allocation settings, I'm\n    * not sure this matters, but it is nice to know, the first of these\n    * tests should be impossible because of the way the macros are set\n    * in pngconf.h\n    */\n#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)\n      fprintf(STDERR, \" NOTE: Zlib compiled for max 64k, libpng not\\n\");\n#endif\n   /* I think the following can happen. */\n#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)\n      fprintf(STDERR, \" NOTE: libpng compiled for max 64k, zlib not\\n\");\n#endif\n\n   if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))\n   {\n      fprintf(STDERR,\n         \"Warning: versions are different between png.h and png.c\\n\");\n      fprintf(STDERR, \"  png.h version: %s\\n\", PNG_LIBPNG_VER_STRING);\n      fprintf(STDERR, \"  png.c version: %s\\n\\n\", png_libpng_ver);\n      ++ierror;\n   }\n\n   if (argc > 1)\n   {\n      if (strcmp(argv[1], \"-m\") == 0)\n      {\n         multiple = 1;\n         status_dots_requested = 0;\n      }\n\n      else if (strcmp(argv[1], \"-mv\") == 0 ||\n               strcmp(argv[1], \"-vm\") == 0 )\n      {\n         multiple = 1;\n         verbose = 1;\n         status_dots_requested = 1;\n      }\n\n      else if (strcmp(argv[1], \"-v\") == 0)\n      {\n         verbose = 1;\n         status_dots_requested = 1;\n         inname = argv[2];\n      }\n\n      else if (strcmp(argv[1], \"--strict\") == 0)\n      {\n         status_dots_requested = 0;\n         verbose = 1;\n         inname = argv[2];\n         strict++;\n         relaxed = 0;\n      }\n\n      else if (strcmp(argv[1], \"--relaxed\") == 0)\n      {\n         status_dots_requested = 0;\n         verbose = 1;\n         inname = argv[2];\n         strict = 0;\n         relaxed++;\n      }\n\n      else\n      {\n         inname = argv[1];\n         status_dots_requested = 0;\n      }\n   }\n\n   if (multiple == 0 && argc == 3 + verbose)\n     outname = argv[2 + verbose];\n\n   if ((multiple == 0 && argc > 3 + verbose) ||\n       (multiple != 0 && argc < 2))\n   {\n     fprintf(STDERR,\n       \"usage: %s [infile.png] [outfile.png]\\n\\t%s -m {infile.png}\\n\",\n        argv[0], argv[0]);\n     fprintf(STDERR,\n       \"  reads/writes one PNG file (without -m) or multiple files (-m)\\n\");\n     fprintf(STDERR,\n       \"  with -m %s is used as a temporary file\\n\", outname);\n     exit(1);\n   }\n\n   if (multiple != 0)\n   {\n      int i;\n#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG\n      int allocation_now = current_allocation;\n#endif\n      for (i=2; i<argc; ++i)\n      {\n         int kerror;\n         fprintf(STDERR, \"\\n Testing %s:\", argv[i]);\n#if PNG_DEBUG > 0\n         fprintf(STDERR, \"\\n\");\n#endif\n         kerror = test_one_file(argv[i], outname);\n         if (kerror == 0)\n         {\n#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED\n            fprintf(STDERR, \"\\n PASS (%lu zero samples)\\n\",\n               (unsigned long)zero_samples);\n#else\n            fprintf(STDERR, \" PASS\\n\");\n#endif\n#ifdef PNG_TIME_RFC1123_SUPPORTED\n            if (tIME_chunk_present != 0)\n               fprintf(STDERR, \" tIME = %s\\n\", tIME_string);\n\n            tIME_chunk_present = 0;\n#endif /* TIME_RFC1123 */\n         }\n\n         else\n         {\n            fprintf(STDERR, \" FAIL\\n\");\n            ierror += kerror;\n         }\n#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG\n         if (allocation_now != current_allocation)\n            fprintf(STDERR, \"MEMORY ERROR: %d bytes lost\\n\",\n               current_allocation - allocation_now);\n\n         if (current_allocation != 0)\n         {\n            memory_infop pinfo = pinformation;\n\n            fprintf(STDERR, \"MEMORY ERROR: %d bytes still allocated\\n\",\n               current_allocation);\n\n            while (pinfo != NULL)\n            {\n               fprintf(STDERR, \" %lu bytes at %p\\n\",\n                 (unsigned long)pinfo->size,\n                 pinfo->pointer);\n               pinfo = pinfo->next;\n            }\n         }\n#endif\n      }\n#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG\n         fprintf(STDERR, \" Current memory allocation: %10d bytes\\n\",\n            current_allocation);\n         fprintf(STDERR, \" Maximum memory allocation: %10d bytes\\n\",\n            maximum_allocation);\n         fprintf(STDERR, \" Total   memory allocation: %10d bytes\\n\",\n            total_allocation);\n         fprintf(STDERR, \"     Number of allocations: %10d\\n\",\n            num_allocations);\n#endif\n   }\n\n   else\n   {\n      int i;\n      for (i = 0; i<3; ++i)\n      {\n         int kerror;\n#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG\n         int allocation_now = current_allocation;\n#endif\n         if (i == 1)\n            status_dots_requested = 1;\n\n         else if (verbose == 0)\n            status_dots_requested = 0;\n\n         if (i == 0 || verbose == 1 || ierror != 0)\n         {\n            fprintf(STDERR, \"\\n Testing %s:\", inname);\n#if PNG_DEBUG > 0\n            fprintf(STDERR, \"\\n\");\n#endif\n         }\n\n         kerror = test_one_file(inname, outname);\n\n         if (kerror == 0)\n         {\n            if (verbose == 1 || i == 2)\n            {\n#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED\n                fprintf(STDERR, \"\\n PASS (%lu zero samples)\\n\",\n                   (unsigned long)zero_samples);\n#else\n                fprintf(STDERR, \" PASS\\n\");\n#endif\n#ifdef PNG_TIME_RFC1123_SUPPORTED\n             if (tIME_chunk_present != 0)\n                fprintf(STDERR, \" tIME = %s\\n\", tIME_string);\n#endif /* TIME_RFC1123 */\n            }\n         }\n\n         else\n         {\n            if (verbose == 0 && i != 2)\n            {\n               fprintf(STDERR, \"\\n Testing %s:\", inname);\n#if PNG_DEBUG > 0\n               fprintf(STDERR, \"\\n\");\n#endif\n            }\n\n            fprintf(STDERR, \" FAIL\\n\");\n            ierror += kerror;\n         }\n#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG\n         if (allocation_now != current_allocation)\n             fprintf(STDERR, \"MEMORY ERROR: %d bytes lost\\n\",\n               current_allocation - allocation_now);\n\n         if (current_allocation != 0)\n         {\n             memory_infop pinfo = pinformation;\n\n             fprintf(STDERR, \"MEMORY ERROR: %d bytes still allocated\\n\",\n                current_allocation);\n\n             while (pinfo != NULL)\n             {\n                fprintf(STDERR, \" %lu bytes at %p\\n\",\n                   (unsigned long)pinfo->size, pinfo->pointer);\n                pinfo = pinfo->next;\n             }\n          }\n#endif\n       }\n#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG\n       fprintf(STDERR, \" Current memory allocation: %10d bytes\\n\",\n          current_allocation);\n       fprintf(STDERR, \" Maximum memory allocation: %10d bytes\\n\",\n          maximum_allocation);\n       fprintf(STDERR, \" Total   memory allocation: %10d bytes\\n\",\n          total_allocation);\n       fprintf(STDERR, \"     Number of allocations: %10d\\n\",\n            num_allocations);\n#endif\n   }\n\n#ifdef PNGTEST_TIMING\n   t_stop = (float)clock();\n   t_misc += (t_stop - t_start);\n   t_start = t_stop;\n   fprintf(STDERR, \" CPU time used = %.3f seconds\",\n      (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);\n   fprintf(STDERR, \" (decoding %.3f,\\n\",\n      t_decode/(float)CLOCKS_PER_SEC);\n   fprintf(STDERR, \"        encoding %.3f ,\",\n      t_encode/(float)CLOCKS_PER_SEC);\n   fprintf(STDERR, \" other %.3f seconds)\\n\\n\",\n      t_misc/(float)CLOCKS_PER_SEC);\n#endif\n\n   if (ierror == 0)\n      fprintf(STDERR, \" libpng passes test\\n\");\n\n   else\n      fprintf(STDERR, \" libpng FAILS test\\n\");\n\n   dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);\n   fprintf(STDERR, \" Default limits:\\n\");\n   fprintf(STDERR, \"  width_max  = %lu\\n\",\n      (unsigned long) png_get_user_width_max(dummy_ptr));\n   fprintf(STDERR, \"  height_max = %lu\\n\",\n      (unsigned long) png_get_user_height_max(dummy_ptr));\n   if (png_get_chunk_cache_max(dummy_ptr) == 0)\n      fprintf(STDERR, \"  cache_max  = unlimited\\n\");\n   else\n      fprintf(STDERR, \"  cache_max  = %lu\\n\",\n         (unsigned long) png_get_chunk_cache_max(dummy_ptr));\n   if (png_get_chunk_malloc_max(dummy_ptr) == 0)\n      fprintf(STDERR, \"  malloc_max = unlimited\\n\");\n   else\n      fprintf(STDERR, \"  malloc_max = %lu\\n\",\n         (unsigned long) png_get_chunk_malloc_max(dummy_ptr));\n   png_destroy_read_struct(&dummy_ptr, NULL, NULL);\n\n   return (int)(ierror != 0);\n}\n#else\nint\nmain(void)\n{\n   fprintf(STDERR,\n      \" test ignored because libpng was not built with read support\\n\");\n   /* And skip this test */\n   return SKIP;\n}\n#endif\n\n/* Generate a compiler error if there is an old png.h in the search path. */\ntypedef png_libpng_version_1_6_22beta03 Your_png_h_is_not_version_1_6_22beta03;\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngtrans.c",
    "content": "\n/* pngtrans.c - transforms the data in a row (used by both readers and writers)\n *\n * Last changed in libpng 1.6.18 [July 23, 2015]\n * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n#include \"pngpriv.h\"\n\n#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)\n\n#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)\n/* Turn on BGR-to-RGB mapping */\nvoid PNGAPI\npng_set_bgr(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_bgr\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->transformations |= PNG_BGR;\n}\n#endif\n\n#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)\n/* Turn on 16-bit byte swapping */\nvoid PNGAPI\npng_set_swap(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_swap\");\n\n   if (png_ptr == NULL)\n      return;\n\n   if (png_ptr->bit_depth == 16)\n      png_ptr->transformations |= PNG_SWAP_BYTES;\n}\n#endif\n\n#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)\n/* Turn on pixel packing */\nvoid PNGAPI\npng_set_packing(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_packing\");\n\n   if (png_ptr == NULL)\n      return;\n\n   if (png_ptr->bit_depth < 8)\n   {\n      png_ptr->transformations |= PNG_PACK;\n#     ifdef PNG_WRITE_SUPPORTED\n         png_ptr->usr_bit_depth = 8;\n#     endif\n   }\n}\n#endif\n\n#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)\n/* Turn on packed pixel swapping */\nvoid PNGAPI\npng_set_packswap(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_packswap\");\n\n   if (png_ptr == NULL)\n      return;\n\n   if (png_ptr->bit_depth < 8)\n      png_ptr->transformations |= PNG_PACKSWAP;\n}\n#endif\n\n#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)\nvoid PNGAPI\npng_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)\n{\n   png_debug(1, \"in png_set_shift\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->transformations |= PNG_SHIFT;\n   png_ptr->shift = *true_bits;\n}\n#endif\n\n#if defined(PNG_READ_INTERLACING_SUPPORTED) || \\\n    defined(PNG_WRITE_INTERLACING_SUPPORTED)\nint PNGAPI\npng_set_interlace_handling(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_interlace handling\");\n\n   if (png_ptr != 0 && png_ptr->interlaced != 0)\n   {\n      png_ptr->transformations |= PNG_INTERLACE;\n      return (7);\n   }\n\n   return (1);\n}\n#endif\n\n#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)\n/* Add a filler byte on read, or remove a filler or alpha byte on write.\n * The filler type has changed in v0.95 to allow future 2-byte fillers\n * for 48-bit input data, as well as to avoid problems with some compilers\n * that don't like bytes as parameters.\n */\nvoid PNGAPI\npng_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)\n{\n   png_debug(1, \"in png_set_filler\");\n\n   if (png_ptr == NULL)\n      return;\n\n   /* In libpng 1.6 it is possible to determine whether this is a read or write\n    * operation and therefore to do more checking here for a valid call.\n    */\n   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)\n   {\n#     ifdef PNG_READ_FILLER_SUPPORTED\n         /* On read png_set_filler is always valid, regardless of the base PNG\n          * format, because other transformations can give a format where the\n          * filler code can execute (basically an 8 or 16-bit component RGB or G\n          * format.)\n          *\n          * NOTE: usr_channels is not used by the read code!  (This has led to\n          * confusion in the past.)  The filler is only used in the read code.\n          */\n         png_ptr->filler = (png_uint_16)filler;\n#     else\n         png_app_error(png_ptr, \"png_set_filler not supported on read\");\n         PNG_UNUSED(filler) /* not used in the write case */\n         return;\n#     endif\n   }\n\n   else /* write */\n   {\n#     ifdef PNG_WRITE_FILLER_SUPPORTED\n         /* On write the usr_channels parameter must be set correctly at the\n          * start to record the number of channels in the app-supplied data.\n          */\n         switch (png_ptr->color_type)\n         {\n            case PNG_COLOR_TYPE_RGB:\n               png_ptr->usr_channels = 4;\n               break;\n\n            case PNG_COLOR_TYPE_GRAY:\n               if (png_ptr->bit_depth >= 8)\n               {\n                  png_ptr->usr_channels = 2;\n                  break;\n               }\n\n               else\n               {\n                  /* There simply isn't any code in libpng to strip out bits\n                   * from bytes when the components are less than a byte in\n                   * size!\n                   */\n                  png_app_error(png_ptr,\n                     \"png_set_filler is invalid for low bit depth gray output\");\n                  return;\n               }\n\n            default:\n               png_app_error(png_ptr,\n                  \"png_set_filler: inappropriate color type\");\n               return;\n         }\n#     else\n         png_app_error(png_ptr, \"png_set_filler not supported on write\");\n         return;\n#     endif\n   }\n\n   /* Here on success - libpng supports the operation, set the transformation\n    * and the flag to say where the filler channel is.\n    */\n   png_ptr->transformations |= PNG_FILLER;\n\n   if (filler_loc == PNG_FILLER_AFTER)\n      png_ptr->flags |= PNG_FLAG_FILLER_AFTER;\n\n   else\n      png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;\n}\n\n/* Added to libpng-1.2.7 */\nvoid PNGAPI\npng_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)\n{\n   png_debug(1, \"in png_set_add_alpha\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_set_filler(png_ptr, filler, filler_loc);\n   /* The above may fail to do anything. */\n   if ((png_ptr->transformations & PNG_FILLER) != 0)\n      png_ptr->transformations |= PNG_ADD_ALPHA;\n}\n\n#endif\n\n#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \\\n    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)\nvoid PNGAPI\npng_set_swap_alpha(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_swap_alpha\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->transformations |= PNG_SWAP_ALPHA;\n}\n#endif\n\n#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \\\n    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)\nvoid PNGAPI\npng_set_invert_alpha(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_invert_alpha\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->transformations |= PNG_INVERT_ALPHA;\n}\n#endif\n\n#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)\nvoid PNGAPI\npng_set_invert_mono(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_set_invert_mono\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->transformations |= PNG_INVERT_MONO;\n}\n\n/* Invert monochrome grayscale data */\nvoid /* PRIVATE */\npng_do_invert(png_row_infop row_info, png_bytep row)\n{\n   png_debug(1, \"in png_do_invert\");\n\n  /* This test removed from libpng version 1.0.13 and 1.2.0:\n   *   if (row_info->bit_depth == 1 &&\n   */\n   if (row_info->color_type == PNG_COLOR_TYPE_GRAY)\n   {\n      png_bytep rp = row;\n      png_size_t i;\n      png_size_t istop = row_info->rowbytes;\n\n      for (i = 0; i < istop; i++)\n      {\n         *rp = (png_byte)(~(*rp));\n         rp++;\n      }\n   }\n\n   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&\n      row_info->bit_depth == 8)\n   {\n      png_bytep rp = row;\n      png_size_t i;\n      png_size_t istop = row_info->rowbytes;\n\n      for (i = 0; i < istop; i += 2)\n      {\n         *rp = (png_byte)(~(*rp));\n         rp += 2;\n      }\n   }\n\n#ifdef PNG_16BIT_SUPPORTED\n   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&\n      row_info->bit_depth == 16)\n   {\n      png_bytep rp = row;\n      png_size_t i;\n      png_size_t istop = row_info->rowbytes;\n\n      for (i = 0; i < istop; i += 4)\n      {\n         *rp = (png_byte)(~(*rp));\n         *(rp + 1) = (png_byte)(~(*(rp + 1)));\n         rp += 4;\n      }\n   }\n#endif\n}\n#endif\n\n#ifdef PNG_16BIT_SUPPORTED\n#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)\n/* Swaps byte order on 16-bit depth images */\nvoid /* PRIVATE */\npng_do_swap(png_row_infop row_info, png_bytep row)\n{\n   png_debug(1, \"in png_do_swap\");\n\n   if (row_info->bit_depth == 16)\n   {\n      png_bytep rp = row;\n      png_uint_32 i;\n      png_uint_32 istop= row_info->width * row_info->channels;\n\n      for (i = 0; i < istop; i++, rp += 2)\n      {\n#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED\n         /* Feature added to libpng-1.6.11 for testing purposes, not\n          * enabled by default.\n          */\n         *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp);\n#else\n         png_byte t = *rp;\n         *rp = *(rp + 1);\n         *(rp + 1) = t;\n#endif\n      }\n   }\n}\n#endif\n#endif\n\n#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)\nstatic PNG_CONST png_byte onebppswaptable[256] = {\n   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,\n   0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,\n   0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,\n   0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,\n   0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,\n   0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,\n   0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,\n   0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,\n   0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,\n   0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,\n   0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,\n   0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,\n   0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,\n   0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,\n   0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,\n   0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,\n   0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,\n   0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,\n   0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,\n   0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,\n   0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,\n   0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,\n   0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,\n   0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,\n   0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,\n   0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,\n   0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,\n   0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,\n   0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,\n   0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,\n   0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,\n   0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF\n};\n\nstatic PNG_CONST png_byte twobppswaptable[256] = {\n   0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,\n   0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,\n   0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,\n   0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,\n   0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,\n   0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,\n   0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,\n   0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,\n   0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,\n   0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,\n   0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,\n   0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,\n   0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,\n   0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,\n   0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,\n   0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,\n   0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,\n   0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,\n   0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,\n   0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,\n   0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,\n   0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,\n   0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,\n   0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,\n   0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,\n   0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,\n   0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,\n   0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,\n   0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,\n   0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,\n   0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,\n   0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF\n};\n\nstatic PNG_CONST png_byte fourbppswaptable[256] = {\n   0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,\n   0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,\n   0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,\n   0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,\n   0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,\n   0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,\n   0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,\n   0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,\n   0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,\n   0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,\n   0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,\n   0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,\n   0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,\n   0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,\n   0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,\n   0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,\n   0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,\n   0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,\n   0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,\n   0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,\n   0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,\n   0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,\n   0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,\n   0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,\n   0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,\n   0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,\n   0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,\n   0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,\n   0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,\n   0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,\n   0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,\n   0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF\n};\n\n/* Swaps pixel packing order within bytes */\nvoid /* PRIVATE */\npng_do_packswap(png_row_infop row_info, png_bytep row)\n{\n   png_debug(1, \"in png_do_packswap\");\n\n   if (row_info->bit_depth < 8)\n   {\n      png_bytep rp;\n      png_const_bytep end, table;\n\n      end = row + row_info->rowbytes;\n\n      if (row_info->bit_depth == 1)\n         table = onebppswaptable;\n\n      else if (row_info->bit_depth == 2)\n         table = twobppswaptable;\n\n      else if (row_info->bit_depth == 4)\n         table = fourbppswaptable;\n\n      else\n         return;\n\n      for (rp = row; rp < end; rp++)\n         *rp = table[*rp];\n   }\n}\n#endif /* PACKSWAP || WRITE_PACKSWAP */\n\n#if defined(PNG_WRITE_FILLER_SUPPORTED) || \\\n    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)\n/* Remove a channel - this used to be 'png_do_strip_filler' but it used a\n * somewhat weird combination of flags to determine what to do.  All the calls\n * to png_do_strip_filler are changed in 1.5.2 to call this instead with the\n * correct arguments.\n *\n * The routine isn't general - the channel must be the channel at the start or\n * end (not in the middle) of each pixel.\n */\nvoid /* PRIVATE */\npng_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)\n{\n   png_bytep sp = row; /* source pointer */\n   png_bytep dp = row; /* destination pointer */\n   png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */\n\n   /* At the start sp will point to the first byte to copy and dp to where\n    * it is copied to.  ep always points just beyond the end of the row, so\n    * the loop simply copies (channels-1) channels until sp reaches ep.\n    *\n    * at_start:        0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.\n    *            nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.\n    */\n\n   /* GA, GX, XG cases */\n   if (row_info->channels == 2)\n   {\n      if (row_info->bit_depth == 8)\n      {\n         if (at_start != 0) /* Skip initial filler */\n            ++sp;\n         else          /* Skip initial channel and, for sp, the filler */\n            sp += 2, ++dp;\n\n         /* For a 1 pixel wide image there is nothing to do */\n         while (sp < ep)\n            *dp++ = *sp, sp += 2;\n\n         row_info->pixel_depth = 8;\n      }\n\n      else if (row_info->bit_depth == 16)\n      {\n         if (at_start != 0) /* Skip initial filler */\n            sp += 2;\n         else          /* Skip initial channel and, for sp, the filler */\n            sp += 4, dp += 2;\n\n         while (sp < ep)\n            *dp++ = *sp++, *dp++ = *sp, sp += 3;\n\n         row_info->pixel_depth = 16;\n      }\n\n      else\n         return; /* bad bit depth */\n\n      row_info->channels = 1;\n\n      /* Finally fix the color type if it records an alpha channel */\n      if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n         row_info->color_type = PNG_COLOR_TYPE_GRAY;\n   }\n\n   /* RGBA, RGBX, XRGB cases */\n   else if (row_info->channels == 4)\n   {\n      if (row_info->bit_depth == 8)\n      {\n         if (at_start != 0) /* Skip initial filler */\n            ++sp;\n         else          /* Skip initial channels and, for sp, the filler */\n            sp += 4, dp += 3;\n\n         /* Note that the loop adds 3 to dp and 4 to sp each time. */\n         while (sp < ep)\n            *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;\n\n         row_info->pixel_depth = 24;\n      }\n\n      else if (row_info->bit_depth == 16)\n      {\n         if (at_start != 0) /* Skip initial filler */\n            sp += 2;\n         else          /* Skip initial channels and, for sp, the filler */\n            sp += 8, dp += 6;\n\n         while (sp < ep)\n         {\n            /* Copy 6 bytes, skip 2 */\n            *dp++ = *sp++, *dp++ = *sp++;\n            *dp++ = *sp++, *dp++ = *sp++;\n            *dp++ = *sp++, *dp++ = *sp, sp += 3;\n         }\n\n         row_info->pixel_depth = 48;\n      }\n\n      else\n         return; /* bad bit depth */\n\n      row_info->channels = 3;\n\n      /* Finally fix the color type if it records an alpha channel */\n      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n         row_info->color_type = PNG_COLOR_TYPE_RGB;\n   }\n\n   else\n      return; /* The filler channel has gone already */\n\n   /* Fix the rowbytes value. */\n   row_info->rowbytes = dp-row;\n}\n#endif\n\n#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)\n/* Swaps red and blue bytes within a pixel */\nvoid /* PRIVATE */\npng_do_bgr(png_row_infop row_info, png_bytep row)\n{\n   png_debug(1, \"in png_do_bgr\");\n\n   if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)\n   {\n      png_uint_32 row_width = row_info->width;\n      if (row_info->bit_depth == 8)\n      {\n         if (row_info->color_type == PNG_COLOR_TYPE_RGB)\n         {\n            png_bytep rp;\n            png_uint_32 i;\n\n            for (i = 0, rp = row; i < row_width; i++, rp += 3)\n            {\n               png_byte save = *rp;\n               *rp = *(rp + 2);\n               *(rp + 2) = save;\n            }\n         }\n\n         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n         {\n            png_bytep rp;\n            png_uint_32 i;\n\n            for (i = 0, rp = row; i < row_width; i++, rp += 4)\n            {\n               png_byte save = *rp;\n               *rp = *(rp + 2);\n               *(rp + 2) = save;\n            }\n         }\n      }\n\n#ifdef PNG_16BIT_SUPPORTED\n      else if (row_info->bit_depth == 16)\n      {\n         if (row_info->color_type == PNG_COLOR_TYPE_RGB)\n         {\n            png_bytep rp;\n            png_uint_32 i;\n\n            for (i = 0, rp = row; i < row_width; i++, rp += 6)\n            {\n               png_byte save = *rp;\n               *rp = *(rp + 4);\n               *(rp + 4) = save;\n               save = *(rp + 1);\n               *(rp + 1) = *(rp + 5);\n               *(rp + 5) = save;\n            }\n         }\n\n         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n         {\n            png_bytep rp;\n            png_uint_32 i;\n\n            for (i = 0, rp = row; i < row_width; i++, rp += 8)\n            {\n               png_byte save = *rp;\n               *rp = *(rp + 4);\n               *(rp + 4) = save;\n               save = *(rp + 1);\n               *(rp + 1) = *(rp + 5);\n               *(rp + 5) = save;\n            }\n         }\n      }\n#endif\n   }\n}\n#endif /* READ_BGR || WRITE_BGR */\n\n#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \\\n    defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)\n/* Added at libpng-1.5.10 */\nvoid /* PRIVATE */\npng_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)\n{\n   if (png_ptr->num_palette < (1 << row_info->bit_depth) &&\n      png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */\n   {\n      /* Calculations moved outside switch in an attempt to stop different\n       * compiler warnings.  'padding' is in *bits* within the last byte, it is\n       * an 'int' because pixel_depth becomes an 'int' in the expression below,\n       * and this calculation is used because it avoids warnings that other\n       * forms produced on either GCC or MSVC.\n       */\n      int padding = (-row_info->pixel_depth * row_info->width) & 7;\n      png_bytep rp = png_ptr->row_buf + row_info->rowbytes;\n\n      switch (row_info->bit_depth)\n      {\n         case 1:\n         {\n            /* in this case, all bytes must be 0 so we don't need\n             * to unpack the pixels except for the rightmost one.\n             */\n            for (; rp > png_ptr->row_buf; rp--)\n            {\n              if ((*rp >> padding) != 0)\n                 png_ptr->num_palette_max = 1;\n              padding = 0;\n            }\n\n            break;\n         }\n\n         case 2:\n         {\n            for (; rp > png_ptr->row_buf; rp--)\n            {\n              int i = ((*rp >> padding) & 0x03);\n\n              if (i > png_ptr->num_palette_max)\n                 png_ptr->num_palette_max = i;\n\n              i = (((*rp >> padding) >> 2) & 0x03);\n\n              if (i > png_ptr->num_palette_max)\n                 png_ptr->num_palette_max = i;\n\n              i = (((*rp >> padding) >> 4) & 0x03);\n\n              if (i > png_ptr->num_palette_max)\n                 png_ptr->num_palette_max = i;\n\n              i = (((*rp >> padding) >> 6) & 0x03);\n\n              if (i > png_ptr->num_palette_max)\n                 png_ptr->num_palette_max = i;\n\n              padding = 0;\n            }\n\n            break;\n         }\n\n         case 4:\n         {\n            for (; rp > png_ptr->row_buf; rp--)\n            {\n              int i = ((*rp >> padding) & 0x0f);\n\n              if (i > png_ptr->num_palette_max)\n                 png_ptr->num_palette_max = i;\n\n              i = (((*rp >> padding) >> 4) & 0x0f);\n\n              if (i > png_ptr->num_palette_max)\n                 png_ptr->num_palette_max = i;\n\n              padding = 0;\n            }\n\n            break;\n         }\n\n         case 8:\n         {\n            for (; rp > png_ptr->row_buf; rp--)\n            {\n               if (*rp > png_ptr->num_palette_max)\n                  png_ptr->num_palette_max = (int) *rp;\n            }\n\n            break;\n         }\n\n         default:\n            break;\n      }\n   }\n}\n#endif /* CHECK_FOR_INVALID_INDEX */\n\n#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \\\n    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)\n#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED\nvoid PNGAPI\npng_set_user_transform_info(png_structrp png_ptr, png_voidp\n   user_transform_ptr, int user_transform_depth, int user_transform_channels)\n{\n   png_debug(1, \"in png_set_user_transform_info\");\n\n   if (png_ptr == NULL)\n      return;\n\n#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED\n   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&\n      (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)\n   {\n      png_app_error(png_ptr,\n            \"info change after png_start_read_image or png_read_update_info\");\n      return;\n   }\n#endif\n\n   png_ptr->user_transform_ptr = user_transform_ptr;\n   png_ptr->user_transform_depth = (png_byte)user_transform_depth;\n   png_ptr->user_transform_channels = (png_byte)user_transform_channels;\n}\n#endif\n\n/* This function returns a pointer to the user_transform_ptr associated with\n * the user transform functions.  The application should free any memory\n * associated with this pointer before png_write_destroy and png_read_destroy\n * are called.\n */\n#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED\npng_voidp PNGAPI\npng_get_user_transform_ptr(png_const_structrp png_ptr)\n{\n   if (png_ptr == NULL)\n      return (NULL);\n\n   return png_ptr->user_transform_ptr;\n}\n#endif\n\n#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED\npng_uint_32 PNGAPI\npng_get_current_row_number(png_const_structrp png_ptr)\n{\n   /* See the comments in png.h - this is the sub-image row when reading an\n    * interlaced image.\n    */\n   if (png_ptr != NULL)\n      return png_ptr->row_number;\n\n   return PNG_UINT_32_MAX; /* help the app not to fail silently */\n}\n\npng_byte PNGAPI\npng_get_current_pass_number(png_const_structrp png_ptr)\n{\n   if (png_ptr != NULL)\n      return png_ptr->pass;\n   return 8; /* invalid */\n}\n#endif /* USER_TRANSFORM_INFO */\n#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */\n#endif /* READ || WRITE */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngusr.dfa",
    "content": "# pngusr.dfa\n#\n# Build time configuration of libpng\n#\n# Enter build configuration options in this file\n#\n# Security settings: by default these limits are unset, you can change them\n# here by entering the appropriate values as #defines preceded by '@' (to cause,\n# them to be passed through to the build of pnglibconf.h), for example:\n#\n# @# define PNG_USER_WIDTH_MAX 65535\n# @# define PNG_USER_HEIGHT_MAX 65535\n# @# define PNG_USER_CHUNK_CACHE_MAX 256\n# @# define PNG_USER_CHUNK_MALLOC_MAX 640000\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngusr.h",
    "content": "#define PNG_USER_PRIVATEBUILD \"Skia build; no MNG features\"\n#define PNG_USER_DLLFNAME_POSTFIX \"Sk\"\n#define PNG_NO_MNG_FEATURES\n#define PNG_NO_READ_GAMMA\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngwio.c",
    "content": "\n/* pngwio.c - functions for data output\n *\n * Last changed in libpng 1.6.15 [November 20, 2014]\n * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n *\n * This file provides a location for all output.  Users who need\n * special handling are expected to write functions that have the same\n * arguments as these and perform similar functions, but that possibly\n * use different output methods.  Note that you shouldn't change these\n * functions, but rather write replacement functions and then change\n * them at run time with png_set_write_fn(...).\n */\n\n#include \"pngpriv.h\"\n\n#ifdef PNG_WRITE_SUPPORTED\n\n/* Write the data to whatever output you are using.  The default routine\n * writes to a file pointer.  Note that this routine sometimes gets called\n * with very small lengths, so you should implement some kind of simple\n * buffering if you are using unbuffered writes.  This should never be asked\n * to write more than 64K on a 16-bit machine.\n */\n\nvoid /* PRIVATE */\npng_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length)\n{\n   /* NOTE: write_data_fn must not change the buffer! */\n   if (png_ptr->write_data_fn != NULL )\n      (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),\n         length);\n\n   else\n      png_error(png_ptr, \"Call to NULL write function\");\n}\n\n#ifdef PNG_STDIO_SUPPORTED\n/* This is the function that does the actual writing of data.  If you are\n * not writing to a standard C stream, you should create a replacement\n * write_data function and use it at run time with png_set_write_fn(), rather\n * than changing the library.\n */\nvoid PNGCBAPI\npng_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)\n{\n   png_size_t check;\n\n   if (png_ptr == NULL)\n      return;\n\n   check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));\n\n   if (check != length)\n      png_error(png_ptr, \"Write Error\");\n}\n#endif\n\n/* This function is called to output any data pending writing (normally\n * to disk).  After png_flush is called, there should be no data pending\n * writing in any buffers.\n */\n#ifdef PNG_WRITE_FLUSH_SUPPORTED\nvoid /* PRIVATE */\npng_flush(png_structrp png_ptr)\n{\n   if (png_ptr->output_flush_fn != NULL)\n      (*(png_ptr->output_flush_fn))(png_ptr);\n}\n\n#  ifdef PNG_STDIO_SUPPORTED\nvoid PNGCBAPI\npng_default_flush(png_structp png_ptr)\n{\n   png_FILE_p io_ptr;\n\n   if (png_ptr == NULL)\n      return;\n\n   io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr));\n   fflush(io_ptr);\n}\n#  endif\n#endif\n\n/* This function allows the application to supply new output functions for\n * libpng if standard C streams aren't being used.\n *\n * This function takes as its arguments:\n * png_ptr       - pointer to a png output data structure\n * io_ptr        - pointer to user supplied structure containing info about\n *                 the output functions.  May be NULL.\n * write_data_fn - pointer to a new output function that takes as its\n *                 arguments a pointer to a png_struct, a pointer to\n *                 data to be written, and a 32-bit unsigned int that is\n *                 the number of bytes to be written.  The new write\n *                 function should call png_error(png_ptr, \"Error msg\")\n *                 to exit and output any fatal error messages.  May be\n *                 NULL, in which case libpng's default function will\n *                 be used.\n * flush_data_fn - pointer to a new flush function that takes as its\n *                 arguments a pointer to a png_struct.  After a call to\n *                 the flush function, there should be no data in any buffers\n *                 or pending transmission.  If the output method doesn't do\n *                 any buffering of output, a function prototype must still be\n *                 supplied although it doesn't have to do anything.  If\n *                 PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile\n *                 time, output_flush_fn will be ignored, although it must be\n *                 supplied for compatibility.  May be NULL, in which case\n *                 libpng's default function will be used, if\n *                 PNG_WRITE_FLUSH_SUPPORTED is defined.  This is not\n *                 a good idea if io_ptr does not point to a standard\n *                 *FILE structure.\n */\nvoid PNGAPI\npng_set_write_fn(png_structrp png_ptr, png_voidp io_ptr,\n    png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)\n{\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->io_ptr = io_ptr;\n\n#ifdef PNG_STDIO_SUPPORTED\n   if (write_data_fn != NULL)\n      png_ptr->write_data_fn = write_data_fn;\n\n   else\n      png_ptr->write_data_fn = png_default_write_data;\n#else\n   png_ptr->write_data_fn = write_data_fn;\n#endif\n\n#ifdef PNG_WRITE_FLUSH_SUPPORTED\n#  ifdef PNG_STDIO_SUPPORTED\n\n   if (output_flush_fn != NULL)\n      png_ptr->output_flush_fn = output_flush_fn;\n\n   else\n      png_ptr->output_flush_fn = png_default_flush;\n\n#  else\n   png_ptr->output_flush_fn = output_flush_fn;\n#  endif\n#else\n   PNG_UNUSED(output_flush_fn)\n#endif /* WRITE_FLUSH */\n\n#ifdef PNG_READ_SUPPORTED\n   /* It is an error to read while writing a png file */\n   if (png_ptr->read_data_fn != NULL)\n   {\n      png_ptr->read_data_fn = NULL;\n\n      png_warning(png_ptr,\n          \"Can't set both read_data_fn and write_data_fn in the\"\n          \" same structure\");\n   }\n#endif\n}\n#endif /* WRITE */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngwrite.c",
    "content": "\n/* pngwrite.c - general routines to write a PNG file\n *\n * Last changed in libpng 1.6.19 [November 12, 2015]\n * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n#include \"pngpriv.h\"\n#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED\n#  include <errno.h>\n#endif /* SIMPLIFIED_WRITE_STDIO */\n\n#ifdef PNG_WRITE_SUPPORTED\n\n#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED\n/* Write out all the unknown chunks for the current given location */\nstatic void\nwrite_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,\n   unsigned int where)\n{\n   if (info_ptr->unknown_chunks_num != 0)\n   {\n      png_const_unknown_chunkp up;\n\n      png_debug(5, \"writing extra chunks\");\n\n      for (up = info_ptr->unknown_chunks;\n           up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;\n           ++up)\n         if ((up->location & where) != 0)\n      {\n         /* If per-chunk unknown chunk handling is enabled use it, otherwise\n          * just write the chunks the application has set.\n          */\n#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED\n         int keep = png_handle_as_unknown(png_ptr, up->name);\n\n         /* NOTE: this code is radically different from the read side in the\n          * matter of handling an ancillary unknown chunk.  In the read side\n          * the default behavior is to discard it, in the code below the default\n          * behavior is to write it.  Critical chunks are, however, only\n          * written if explicitly listed or if the default is set to write all\n          * unknown chunks.\n          *\n          * The default handling is also slightly weird - it is not possible to\n          * stop the writing of all unsafe-to-copy chunks!\n          *\n          * TODO: REVIEW: this would seem to be a bug.\n          */\n         if (keep != PNG_HANDLE_CHUNK_NEVER &&\n             ((up->name[3] & 0x20) /* safe-to-copy overrides everything */ ||\n              keep == PNG_HANDLE_CHUNK_ALWAYS ||\n              (keep == PNG_HANDLE_CHUNK_AS_DEFAULT &&\n               png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS)))\n#endif\n         {\n            /* TODO: review, what is wrong with a zero length unknown chunk? */\n            if (up->size == 0)\n               png_warning(png_ptr, \"Writing zero-length unknown chunk\");\n\n            png_write_chunk(png_ptr, up->name, up->data, up->size);\n         }\n      }\n   }\n}\n#endif /* WRITE_UNKNOWN_CHUNKS */\n\n/* Writes all the PNG information.  This is the suggested way to use the\n * library.  If you have a new chunk to add, make a function to write it,\n * and put it in the correct location here.  If you want the chunk written\n * after the image data, put it in png_write_end().  I strongly encourage\n * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing\n * the chunk, as that will keep the code from breaking if you want to just\n * write a plain PNG file.  If you have long comments, I suggest writing\n * them in png_write_end(), and compressing them.\n */\nvoid PNGAPI\npng_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)\n{\n   png_debug(1, \"in png_write_info_before_PLTE\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0)\n   {\n      /* Write PNG signature */\n      png_write_sig(png_ptr);\n\n#ifdef PNG_MNG_FEATURES_SUPPORTED\n      if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && \\\n          png_ptr->mng_features_permitted != 0)\n      {\n         png_warning(png_ptr,\n             \"MNG features are not allowed in a PNG datastream\");\n         png_ptr->mng_features_permitted = 0;\n      }\n#endif\n\n      /* Write IHDR information. */\n      png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,\n          info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,\n          info_ptr->filter_type,\n#ifdef PNG_WRITE_INTERLACING_SUPPORTED\n          info_ptr->interlace_type\n#else\n          0\n#endif\n         );\n\n      /* The rest of these check to see if the valid field has the appropriate\n       * flag set, and if it does, writes the chunk.\n       *\n       * 1.6.0: COLORSPACE support controls the writing of these chunks too, and\n       * the chunks will be written if the WRITE routine is there and\n       * information * is available in the COLORSPACE. (See\n       * png_colorspace_sync_info in png.c for where the valid flags get set.)\n       *\n       * Under certain circumstances the colorspace can be invalidated without\n       * syncing the info_struct 'valid' flags; this happens if libpng detects\n       * an error and calls png_error while the color space is being set, yet\n       * the application continues writing the PNG.  So check the 'invalid'\n       * flag here too.\n       */\n#ifdef PNG_GAMMA_SUPPORTED\n#  ifdef PNG_WRITE_gAMA_SUPPORTED\n      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&\n          (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) != 0 &&\n          (info_ptr->valid & PNG_INFO_gAMA) != 0)\n         png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma);\n#  endif\n#endif\n\n#ifdef PNG_COLORSPACE_SUPPORTED\n      /* Write only one of sRGB or an ICC profile.  If a profile was supplied\n       * and it matches one of the known sRGB ones issue a warning.\n       */\n#  ifdef PNG_WRITE_iCCP_SUPPORTED\n         if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&\n             (info_ptr->valid & PNG_INFO_iCCP) != 0)\n         {\n#    ifdef PNG_WRITE_sRGB_SUPPORTED\n               if ((info_ptr->valid & PNG_INFO_sRGB) != 0)\n                  png_app_warning(png_ptr,\n                     \"profile matches sRGB but writing iCCP instead\");\n#     endif\n\n            png_write_iCCP(png_ptr, info_ptr->iccp_name,\n               info_ptr->iccp_profile);\n         }\n#     ifdef PNG_WRITE_sRGB_SUPPORTED\n         else\n#     endif\n#  endif\n\n#  ifdef PNG_WRITE_sRGB_SUPPORTED\n         if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&\n             (info_ptr->valid & PNG_INFO_sRGB) != 0)\n            png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent);\n#  endif /* WRITE_sRGB */\n#endif /* COLORSPACE */\n\n#ifdef PNG_WRITE_sBIT_SUPPORTED\n         if ((info_ptr->valid & PNG_INFO_sBIT) != 0)\n            png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);\n#endif\n\n#ifdef PNG_COLORSPACE_SUPPORTED\n#  ifdef PNG_WRITE_cHRM_SUPPORTED\n         if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&\n             (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0 &&\n             (info_ptr->valid & PNG_INFO_cHRM) != 0)\n            png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy);\n#  endif\n#endif\n\n#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED\n         write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR);\n#endif\n\n      png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;\n   }\n}\n\nvoid PNGAPI\npng_write_info(png_structrp png_ptr, png_const_inforp info_ptr)\n{\n#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)\n   int i;\n#endif\n\n   png_debug(1, \"in png_write_info\");\n\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   png_write_info_before_PLTE(png_ptr, info_ptr);\n\n   if ((info_ptr->valid & PNG_INFO_PLTE) != 0)\n      png_write_PLTE(png_ptr, info_ptr->palette,\n          (png_uint_32)info_ptr->num_palette);\n\n   else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n      png_error(png_ptr, \"Valid palette required for paletted images\");\n\n#ifdef PNG_WRITE_tRNS_SUPPORTED\n   if ((info_ptr->valid & PNG_INFO_tRNS) !=0)\n   {\n#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED\n      /* Invert the alpha channel (in tRNS) */\n      if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0 &&\n          info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n      {\n         int j, jend;\n\n         jend = info_ptr->num_trans;\n         if (jend > PNG_MAX_PALETTE_LENGTH)\n            jend = PNG_MAX_PALETTE_LENGTH;\n\n         for (j = 0; j<jend; ++j)\n            info_ptr->trans_alpha[j] =\n               (png_byte)(255 - info_ptr->trans_alpha[j]);\n      }\n#endif\n      png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color),\n          info_ptr->num_trans, info_ptr->color_type);\n   }\n#endif\n#ifdef PNG_WRITE_bKGD_SUPPORTED\n   if ((info_ptr->valid & PNG_INFO_bKGD) != 0)\n      png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);\n#endif\n\n#ifdef PNG_WRITE_hIST_SUPPORTED\n   if ((info_ptr->valid & PNG_INFO_hIST) != 0)\n      png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);\n#endif\n\n#ifdef PNG_WRITE_oFFs_SUPPORTED\n   if ((info_ptr->valid & PNG_INFO_oFFs) != 0)\n      png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,\n          info_ptr->offset_unit_type);\n#endif\n\n#ifdef PNG_WRITE_pCAL_SUPPORTED\n   if ((info_ptr->valid & PNG_INFO_pCAL) != 0)\n      png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,\n          info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,\n          info_ptr->pcal_units, info_ptr->pcal_params);\n#endif\n\n#ifdef PNG_WRITE_sCAL_SUPPORTED\n   if ((info_ptr->valid & PNG_INFO_sCAL) != 0)\n      png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,\n          info_ptr->scal_s_width, info_ptr->scal_s_height);\n#endif /* sCAL */\n\n#ifdef PNG_WRITE_pHYs_SUPPORTED\n   if ((info_ptr->valid & PNG_INFO_pHYs) != 0)\n      png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,\n          info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);\n#endif /* pHYs */\n\n#ifdef PNG_WRITE_tIME_SUPPORTED\n   if ((info_ptr->valid & PNG_INFO_tIME) != 0)\n   {\n      png_write_tIME(png_ptr, &(info_ptr->mod_time));\n      png_ptr->mode |= PNG_WROTE_tIME;\n   }\n#endif /* tIME */\n\n#ifdef PNG_WRITE_sPLT_SUPPORTED\n   if ((info_ptr->valid & PNG_INFO_sPLT) != 0)\n      for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)\n         png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);\n#endif /* sPLT */\n\n#ifdef PNG_WRITE_TEXT_SUPPORTED\n   /* Check to see if we need to write text chunks */\n   for (i = 0; i < info_ptr->num_text; i++)\n   {\n      png_debug2(2, \"Writing header text chunk %d, type %d\", i,\n          info_ptr->text[i].compression);\n      /* An internationalized chunk? */\n      if (info_ptr->text[i].compression > 0)\n      {\n#ifdef PNG_WRITE_iTXt_SUPPORTED\n         /* Write international chunk */\n         png_write_iTXt(png_ptr,\n             info_ptr->text[i].compression,\n             info_ptr->text[i].key,\n             info_ptr->text[i].lang,\n             info_ptr->text[i].lang_key,\n             info_ptr->text[i].text);\n         /* Mark this chunk as written */\n         if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)\n            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;\n         else\n            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;\n#else\n         png_warning(png_ptr, \"Unable to write international text\");\n#endif\n      }\n\n      /* If we want a compressed text chunk */\n      else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)\n      {\n#ifdef PNG_WRITE_zTXt_SUPPORTED\n         /* Write compressed chunk */\n         png_write_zTXt(png_ptr, info_ptr->text[i].key,\n             info_ptr->text[i].text, info_ptr->text[i].compression);\n         /* Mark this chunk as written */\n         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;\n#else\n         png_warning(png_ptr, \"Unable to write compressed text\");\n#endif\n      }\n\n      else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)\n      {\n#ifdef PNG_WRITE_tEXt_SUPPORTED\n         /* Write uncompressed chunk */\n         png_write_tEXt(png_ptr, info_ptr->text[i].key,\n             info_ptr->text[i].text,\n             0);\n         /* Mark this chunk as written */\n         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;\n#else\n         /* Can't get here */\n         png_warning(png_ptr, \"Unable to write uncompressed text\");\n#endif\n      }\n   }\n#endif /* tEXt */\n\n#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED\n   write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_PLTE);\n#endif\n}\n\n/* Writes the end of the PNG file.  If you don't want to write comments or\n * time information, you can pass NULL for info.  If you already wrote these\n * in png_write_info(), do not write them again here.  If you have long\n * comments, I suggest writing them here, and compressing them.\n */\nvoid PNGAPI\npng_write_end(png_structrp png_ptr, png_inforp info_ptr)\n{\n   png_debug(1, \"in png_write_end\");\n\n   if (png_ptr == NULL)\n      return;\n\n   if ((png_ptr->mode & PNG_HAVE_IDAT) == 0)\n      png_error(png_ptr, \"No IDATs written into file\");\n\n#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED\n   if (png_ptr->num_palette_max > png_ptr->num_palette)\n      png_benign_error(png_ptr, \"Wrote palette index exceeding num_palette\");\n#endif\n\n   /* See if user wants us to write information chunks */\n   if (info_ptr != NULL)\n   {\n#ifdef PNG_WRITE_TEXT_SUPPORTED\n      int i; /* local index variable */\n#endif\n#ifdef PNG_WRITE_tIME_SUPPORTED\n      /* Check to see if user has supplied a time chunk */\n      if ((info_ptr->valid & PNG_INFO_tIME) != 0 &&\n          (png_ptr->mode & PNG_WROTE_tIME) == 0)\n         png_write_tIME(png_ptr, &(info_ptr->mod_time));\n\n#endif\n#ifdef PNG_WRITE_TEXT_SUPPORTED\n      /* Loop through comment chunks */\n      for (i = 0; i < info_ptr->num_text; i++)\n      {\n         png_debug2(2, \"Writing trailer text chunk %d, type %d\", i,\n            info_ptr->text[i].compression);\n         /* An internationalized chunk? */\n         if (info_ptr->text[i].compression > 0)\n         {\n#ifdef PNG_WRITE_iTXt_SUPPORTED\n            /* Write international chunk */\n            png_write_iTXt(png_ptr,\n                info_ptr->text[i].compression,\n                info_ptr->text[i].key,\n                info_ptr->text[i].lang,\n                info_ptr->text[i].lang_key,\n                info_ptr->text[i].text);\n            /* Mark this chunk as written */\n            if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)\n               info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;\n            else\n               info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;\n#else\n            png_warning(png_ptr, \"Unable to write international text\");\n#endif\n         }\n\n         else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)\n         {\n#ifdef PNG_WRITE_zTXt_SUPPORTED\n            /* Write compressed chunk */\n            png_write_zTXt(png_ptr, info_ptr->text[i].key,\n                info_ptr->text[i].text, info_ptr->text[i].compression);\n            /* Mark this chunk as written */\n            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;\n#else\n            png_warning(png_ptr, \"Unable to write compressed text\");\n#endif\n         }\n\n         else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)\n         {\n#ifdef PNG_WRITE_tEXt_SUPPORTED\n            /* Write uncompressed chunk */\n            png_write_tEXt(png_ptr, info_ptr->text[i].key,\n                info_ptr->text[i].text, 0);\n            /* Mark this chunk as written */\n            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;\n#else\n            png_warning(png_ptr, \"Unable to write uncompressed text\");\n#endif\n         }\n      }\n#endif\n#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED\n      write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT);\n#endif\n   }\n\n   png_ptr->mode |= PNG_AFTER_IDAT;\n\n   /* Write end of PNG file */\n   png_write_IEND(png_ptr);\n\n   /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03,\n    * and restored again in libpng-1.2.30, may cause some applications that\n    * do not set png_ptr->output_flush_fn to crash.  If your application\n    * experiences a problem, please try building libpng with\n    * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to\n    * png-mng-implement at lists.sf.net .\n    */\n#ifdef PNG_WRITE_FLUSH_SUPPORTED\n#  ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED\n   png_flush(png_ptr);\n#  endif\n#endif\n}\n\n#ifdef PNG_CONVERT_tIME_SUPPORTED\nvoid PNGAPI\npng_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime)\n{\n   png_debug(1, \"in png_convert_from_struct_tm\");\n\n   ptime->year = (png_uint_16)(1900 + ttime->tm_year);\n   ptime->month = (png_byte)(ttime->tm_mon + 1);\n   ptime->day = (png_byte)ttime->tm_mday;\n   ptime->hour = (png_byte)ttime->tm_hour;\n   ptime->minute = (png_byte)ttime->tm_min;\n   ptime->second = (png_byte)ttime->tm_sec;\n}\n\nvoid PNGAPI\npng_convert_from_time_t(png_timep ptime, time_t ttime)\n{\n   struct tm *tbuf;\n\n   png_debug(1, \"in png_convert_from_time_t\");\n\n   tbuf = gmtime(&ttime);\n   png_convert_from_struct_tm(ptime, tbuf);\n}\n#endif\n\n/* Initialize png_ptr structure, and allocate any memory needed */\nPNG_FUNCTION(png_structp,PNGAPI\npng_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr,\n    png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)\n{\n#ifndef PNG_USER_MEM_SUPPORTED\n   png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,\n       error_fn, warn_fn, NULL, NULL, NULL);\n#else\n   return png_create_write_struct_2(user_png_ver, error_ptr, error_fn,\n       warn_fn, NULL, NULL, NULL);\n}\n\n/* Alternate initialize png_ptr structure, and allocate any memory needed */\nPNG_FUNCTION(png_structp,PNGAPI\npng_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,\n    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,\n    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)\n{\n   png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,\n       error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);\n#endif /* USER_MEM */\n   if (png_ptr != NULL)\n   {\n      /* Set the zlib control values to defaults; they can be overridden by the\n       * application after the struct has been created.\n       */\n      png_ptr->zbuffer_size = PNG_ZBUF_SIZE;\n\n      /* The 'zlib_strategy' setting is irrelevant because png_default_claim in\n       * pngwutil.c defaults it according to whether or not filters will be\n       * used, and ignores this setting.\n       */\n      png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY;\n      png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION;\n      png_ptr->zlib_mem_level = 8;\n      png_ptr->zlib_window_bits = 15;\n      png_ptr->zlib_method = 8;\n\n#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED\n      png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY;\n      png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION;\n      png_ptr->zlib_text_mem_level = 8;\n      png_ptr->zlib_text_window_bits = 15;\n      png_ptr->zlib_text_method = 8;\n#endif /* WRITE_COMPRESSED_TEXT */\n\n      /* This is a highly dubious configuration option; by default it is off,\n       * but it may be appropriate for private builds that are testing\n       * extensions not conformant to the current specification, or of\n       * applications that must not fail to write at all costs!\n       */\n#ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED\n      /* In stable builds only warn if an application error can be completely\n       * handled.\n       */\n      png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;\n#endif\n\n      /* App warnings are warnings in release (or release candidate) builds but\n       * are errors during development.\n       */\n#if PNG_RELEASE_BUILD\n      png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;\n#endif\n\n      /* TODO: delay this, it can be done in png_init_io() (if the app doesn't\n       * do it itself) avoiding setting the default function if it is not\n       * required.\n       */\n      png_set_write_fn(png_ptr, NULL, NULL, NULL);\n   }\n\n   return png_ptr;\n}\n\n\n/* Write a few rows of image data.  If the image is interlaced,\n * either you will have to write the 7 sub images, or, if you\n * have called png_set_interlace_handling(), you will have to\n * \"write\" the image seven times.\n */\nvoid PNGAPI\npng_write_rows(png_structrp png_ptr, png_bytepp row,\n    png_uint_32 num_rows)\n{\n   png_uint_32 i; /* row counter */\n   png_bytepp rp; /* row pointer */\n\n   png_debug(1, \"in png_write_rows\");\n\n   if (png_ptr == NULL)\n      return;\n\n   /* Loop through the rows */\n   for (i = 0, rp = row; i < num_rows; i++, rp++)\n   {\n      png_write_row(png_ptr, *rp);\n   }\n}\n\n/* Write the image.  You only need to call this function once, even\n * if you are writing an interlaced image.\n */\nvoid PNGAPI\npng_write_image(png_structrp png_ptr, png_bytepp image)\n{\n   png_uint_32 i; /* row index */\n   int pass, num_pass; /* pass variables */\n   png_bytepp rp; /* points to current row */\n\n   if (png_ptr == NULL)\n      return;\n\n   png_debug(1, \"in png_write_image\");\n\n#ifdef PNG_WRITE_INTERLACING_SUPPORTED\n   /* Initialize interlace handling.  If image is not interlaced,\n    * this will set pass to 1\n    */\n   num_pass = png_set_interlace_handling(png_ptr);\n#else\n   num_pass = 1;\n#endif\n   /* Loop through passes */\n   for (pass = 0; pass < num_pass; pass++)\n   {\n      /* Loop through image */\n      for (i = 0, rp = image; i < png_ptr->height; i++, rp++)\n      {\n         png_write_row(png_ptr, *rp);\n      }\n   }\n}\n\n#ifdef PNG_MNG_FEATURES_SUPPORTED\n/* Performs intrapixel differencing  */\nstatic void\npng_do_write_intrapixel(png_row_infop row_info, png_bytep row)\n{\n   png_debug(1, \"in png_do_write_intrapixel\");\n\n   if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)\n   {\n      int bytes_per_pixel;\n      png_uint_32 row_width = row_info->width;\n      if (row_info->bit_depth == 8)\n      {\n         png_bytep rp;\n         png_uint_32 i;\n\n         if (row_info->color_type == PNG_COLOR_TYPE_RGB)\n            bytes_per_pixel = 3;\n\n         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n            bytes_per_pixel = 4;\n\n         else\n            return;\n\n         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)\n         {\n            *(rp)     = (png_byte)(*rp       - *(rp + 1));\n            *(rp + 2) = (png_byte)(*(rp + 2) - *(rp + 1));\n         }\n      }\n\n#ifdef PNG_WRITE_16BIT_SUPPORTED\n      else if (row_info->bit_depth == 16)\n      {\n         png_bytep rp;\n         png_uint_32 i;\n\n         if (row_info->color_type == PNG_COLOR_TYPE_RGB)\n            bytes_per_pixel = 6;\n\n         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n            bytes_per_pixel = 8;\n\n         else\n            return;\n\n         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)\n         {\n            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);\n            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);\n            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);\n            png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);\n            png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);\n            *(rp    ) = (png_byte)(red >> 8);\n            *(rp + 1) = (png_byte)red;\n            *(rp + 4) = (png_byte)(blue >> 8);\n            *(rp + 5) = (png_byte)blue;\n         }\n      }\n#endif /* WRITE_16BIT */\n   }\n}\n#endif /* MNG_FEATURES */\n\n/* Called by user to write a row of image data */\nvoid PNGAPI\npng_write_row(png_structrp png_ptr, png_const_bytep row)\n{\n   /* 1.5.6: moved from png_struct to be a local structure: */\n   png_row_info row_info;\n\n   if (png_ptr == NULL)\n      return;\n\n   png_debug2(1, \"in png_write_row (row %u, pass %d)\",\n      png_ptr->row_number, png_ptr->pass);\n\n   /* Initialize transformations and other stuff if first time */\n   if (png_ptr->row_number == 0 && png_ptr->pass == 0)\n   {\n      /* Make sure we wrote the header info */\n      if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0)\n         png_error(png_ptr,\n             \"png_write_info was never called before png_write_row\");\n\n      /* Check for transforms that have been set but were defined out */\n#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)\n      if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)\n         png_warning(png_ptr, \"PNG_WRITE_INVERT_SUPPORTED is not defined\");\n#endif\n\n#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)\n      if ((png_ptr->transformations & PNG_FILLER) != 0)\n         png_warning(png_ptr, \"PNG_WRITE_FILLER_SUPPORTED is not defined\");\n#endif\n#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \\\n    defined(PNG_READ_PACKSWAP_SUPPORTED)\n      if ((png_ptr->transformations & PNG_PACKSWAP) != 0)\n         png_warning(png_ptr,\n             \"PNG_WRITE_PACKSWAP_SUPPORTED is not defined\");\n#endif\n\n#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)\n      if ((png_ptr->transformations & PNG_PACK) != 0)\n         png_warning(png_ptr, \"PNG_WRITE_PACK_SUPPORTED is not defined\");\n#endif\n\n#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)\n      if ((png_ptr->transformations & PNG_SHIFT) != 0)\n         png_warning(png_ptr, \"PNG_WRITE_SHIFT_SUPPORTED is not defined\");\n#endif\n\n#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)\n      if ((png_ptr->transformations & PNG_BGR) != 0)\n         png_warning(png_ptr, \"PNG_WRITE_BGR_SUPPORTED is not defined\");\n#endif\n\n#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)\n      if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)\n         png_warning(png_ptr, \"PNG_WRITE_SWAP_SUPPORTED is not defined\");\n#endif\n\n      png_write_start_row(png_ptr);\n   }\n\n#ifdef PNG_WRITE_INTERLACING_SUPPORTED\n   /* If interlaced and not interested in row, return */\n   if (png_ptr->interlaced != 0 &&\n       (png_ptr->transformations & PNG_INTERLACE) != 0)\n   {\n      switch (png_ptr->pass)\n      {\n         case 0:\n            if ((png_ptr->row_number & 0x07) != 0)\n            {\n               png_write_finish_row(png_ptr);\n               return;\n            }\n            break;\n\n         case 1:\n            if ((png_ptr->row_number & 0x07) != 0 || png_ptr->width < 5)\n            {\n               png_write_finish_row(png_ptr);\n               return;\n            }\n            break;\n\n         case 2:\n            if ((png_ptr->row_number & 0x07) != 4)\n            {\n               png_write_finish_row(png_ptr);\n               return;\n            }\n            break;\n\n         case 3:\n            if ((png_ptr->row_number & 0x03) != 0 || png_ptr->width < 3)\n            {\n               png_write_finish_row(png_ptr);\n               return;\n            }\n            break;\n\n         case 4:\n            if ((png_ptr->row_number & 0x03) != 2)\n            {\n               png_write_finish_row(png_ptr);\n               return;\n            }\n            break;\n\n         case 5:\n            if ((png_ptr->row_number & 0x01) != 0 || png_ptr->width < 2)\n            {\n               png_write_finish_row(png_ptr);\n               return;\n            }\n            break;\n\n         case 6:\n            if ((png_ptr->row_number & 0x01) == 0)\n            {\n               png_write_finish_row(png_ptr);\n               return;\n            }\n            break;\n\n         default: /* error: ignore it */\n            break;\n      }\n   }\n#endif\n\n   /* Set up row info for transformations */\n   row_info.color_type = png_ptr->color_type;\n   row_info.width = png_ptr->usr_width;\n   row_info.channels = png_ptr->usr_channels;\n   row_info.bit_depth = png_ptr->usr_bit_depth;\n   row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels);\n   row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);\n\n   png_debug1(3, \"row_info->color_type = %d\", row_info.color_type);\n   png_debug1(3, \"row_info->width = %u\", row_info.width);\n   png_debug1(3, \"row_info->channels = %d\", row_info.channels);\n   png_debug1(3, \"row_info->bit_depth = %d\", row_info.bit_depth);\n   png_debug1(3, \"row_info->pixel_depth = %d\", row_info.pixel_depth);\n   png_debug1(3, \"row_info->rowbytes = %lu\", (unsigned long)row_info.rowbytes);\n\n   /* Copy user's row into buffer, leaving room for filter byte. */\n   memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes);\n\n#ifdef PNG_WRITE_INTERLACING_SUPPORTED\n   /* Handle interlacing */\n   if (png_ptr->interlaced && png_ptr->pass < 6 &&\n       (png_ptr->transformations & PNG_INTERLACE) != 0)\n   {\n      png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass);\n      /* This should always get caught above, but still ... */\n      if (row_info.width == 0)\n      {\n         png_write_finish_row(png_ptr);\n         return;\n      }\n   }\n#endif\n\n#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED\n   /* Handle other transformations */\n   if (png_ptr->transformations != 0)\n      png_do_write_transformations(png_ptr, &row_info);\n#endif\n\n   /* At this point the row_info pixel depth must match the 'transformed' depth,\n    * which is also the output depth.\n    */\n   if (row_info.pixel_depth != png_ptr->pixel_depth ||\n       row_info.pixel_depth != png_ptr->transformed_pixel_depth)\n      png_error(png_ptr, \"internal write transform logic error\");\n\n#ifdef PNG_MNG_FEATURES_SUPPORTED\n   /* Write filter_method 64 (intrapixel differencing) only if\n    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and\n    * 2. Libpng did not write a PNG signature (this filter_method is only\n    *    used in PNG datastreams that are embedded in MNG datastreams) and\n    * 3. The application called png_permit_mng_features with a mask that\n    *    included PNG_FLAG_MNG_FILTER_64 and\n    * 4. The filter_method is 64 and\n    * 5. The color_type is RGB or RGBA\n    */\n   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&\n       (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))\n   {\n      /* Intrapixel differencing */\n      png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1);\n   }\n#endif\n\n/* Added at libpng-1.5.10 */\n#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED\n   /* Check for out-of-range palette index */\n   if (row_info.color_type == PNG_COLOR_TYPE_PALETTE &&\n       png_ptr->num_palette_max >= 0)\n      png_do_check_palette_indexes(png_ptr, &row_info);\n#endif\n\n   /* Find a filter if necessary, filter the row and write it out. */\n   png_write_find_filter(png_ptr, &row_info);\n\n   if (png_ptr->write_row_fn != NULL)\n      (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);\n}\n\n#ifdef PNG_WRITE_FLUSH_SUPPORTED\n/* Set the automatic flush interval or 0 to turn flushing off */\nvoid PNGAPI\npng_set_flush(png_structrp png_ptr, int nrows)\n{\n   png_debug(1, \"in png_set_flush\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);\n}\n\n/* Flush the current output buffers now */\nvoid PNGAPI\npng_write_flush(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_write_flush\");\n\n   if (png_ptr == NULL)\n      return;\n\n   /* We have already written out all of the data */\n   if (png_ptr->row_number >= png_ptr->num_rows)\n      return;\n\n   png_compress_IDAT(png_ptr, NULL, 0, Z_SYNC_FLUSH);\n   png_ptr->flush_rows = 0;\n   png_flush(png_ptr);\n}\n#endif /* WRITE_FLUSH */\n\n/* Free any memory used in png_ptr struct without freeing the struct itself. */\nstatic void\npng_write_destroy(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_write_destroy\");\n\n   /* Free any memory zlib uses */\n   if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)\n      deflateEnd(&png_ptr->zstream);\n\n   /* Free our memory.  png_free checks NULL for us. */\n   png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);\n   png_free(png_ptr, png_ptr->row_buf);\n   png_ptr->row_buf = NULL;\n#ifdef PNG_WRITE_FILTER_SUPPORTED\n   png_free(png_ptr, png_ptr->prev_row);\n   png_free(png_ptr, png_ptr->try_row);\n   png_free(png_ptr, png_ptr->tst_row);\n   png_ptr->prev_row = NULL;\n   png_ptr->try_row = NULL;\n   png_ptr->tst_row = NULL;\n#endif\n\n#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED\n   png_free(png_ptr, png_ptr->chunk_list);\n   png_ptr->chunk_list = NULL;\n#endif\n\n   /* The error handling and memory handling information is left intact at this\n    * point: the jmp_buf may still have to be freed.  See png_destroy_png_struct\n    * for how this happens.\n    */\n}\n\n/* Free all memory used by the write.\n * In libpng 1.6.0 this API changed quietly to no longer accept a NULL value for\n * *png_ptr_ptr.  Prior to 1.6.0 it would accept such a value and it would free\n * the passed in info_structs but it would quietly fail to free any of the data\n * inside them.  In 1.6.0 it quietly does nothing (it has to be quiet because it\n * has no png_ptr.)\n */\nvoid PNGAPI\npng_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)\n{\n   png_debug(1, \"in png_destroy_write_struct\");\n\n   if (png_ptr_ptr != NULL)\n   {\n      png_structrp png_ptr = *png_ptr_ptr;\n\n      if (png_ptr != NULL) /* added in libpng 1.6.0 */\n      {\n         png_destroy_info_struct(png_ptr, info_ptr_ptr);\n\n         *png_ptr_ptr = NULL;\n         png_write_destroy(png_ptr);\n         png_destroy_png_struct(png_ptr);\n      }\n   }\n}\n\n/* Allow the application to select one or more row filters to use. */\nvoid PNGAPI\npng_set_filter(png_structrp png_ptr, int method, int filters)\n{\n   png_debug(1, \"in png_set_filter\");\n\n   if (png_ptr == NULL)\n      return;\n\n#ifdef PNG_MNG_FEATURES_SUPPORTED\n   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&\n       (method == PNG_INTRAPIXEL_DIFFERENCING))\n      method = PNG_FILTER_TYPE_BASE;\n\n#endif\n   if (method == PNG_FILTER_TYPE_BASE)\n   {\n      switch (filters & (PNG_ALL_FILTERS | 0x07))\n      {\n#ifdef PNG_WRITE_FILTER_SUPPORTED\n         case 5:\n         case 6:\n         case 7: png_app_error(png_ptr, \"Unknown row filter for method 0\");\n            /* FALL THROUGH */\n#endif /* WRITE_FILTER */\n         case PNG_FILTER_VALUE_NONE:\n            png_ptr->do_filter = PNG_FILTER_NONE; break;\n\n#ifdef PNG_WRITE_FILTER_SUPPORTED\n         case PNG_FILTER_VALUE_SUB:\n            png_ptr->do_filter = PNG_FILTER_SUB; break;\n\n         case PNG_FILTER_VALUE_UP:\n            png_ptr->do_filter = PNG_FILTER_UP; break;\n\n         case PNG_FILTER_VALUE_AVG:\n            png_ptr->do_filter = PNG_FILTER_AVG; break;\n\n         case PNG_FILTER_VALUE_PAETH:\n            png_ptr->do_filter = PNG_FILTER_PAETH; break;\n\n         default:\n            png_ptr->do_filter = (png_byte)filters; break;\n#else\n         default:\n            png_app_error(png_ptr, \"Unknown row filter for method 0\");\n#endif /* WRITE_FILTER */\n      }\n\n#ifdef PNG_WRITE_FILTER_SUPPORTED\n      /* If we have allocated the row_buf, this means we have already started\n       * with the image and we should have allocated all of the filter buffers\n       * that have been selected.  If prev_row isn't already allocated, then\n       * it is too late to start using the filters that need it, since we\n       * will be missing the data in the previous row.  If an application\n       * wants to start and stop using particular filters during compression,\n       * it should start out with all of the filters, and then remove them\n       * or add them back after the start of compression.\n       *\n       * NOTE: this is a nasty constraint on the code, because it means that the\n       * prev_row buffer must be maintained even if there are currently no\n       * 'prev_row' requiring filters active.\n       */\n      if (png_ptr->row_buf != NULL)\n      {\n         int num_filters;\n         png_alloc_size_t buf_size;\n\n         /* Repeat the checks in png_write_start_row; 1 pixel high or wide\n          * images cannot benefit from certain filters.  If this isn't done here\n          * the check below will fire on 1 pixel high images.\n          */\n         if (png_ptr->height == 1)\n            filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);\n\n         if (png_ptr->width == 1)\n            filters &= ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH);\n\n         if ((filters & (PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH)) != 0\n            && png_ptr->prev_row == NULL)\n         {\n            /* This is the error case, however it is benign - the previous row\n             * is not available so the filter can't be used.  Just warn here.\n             */\n            png_app_warning(png_ptr,\n               \"png_set_filter: UP/AVG/PAETH cannot be added after start\");\n            filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);\n         }\n\n         num_filters = 0;\n\n         if (filters & PNG_FILTER_SUB)\n            num_filters++;\n\n         if (filters & PNG_FILTER_UP)\n            num_filters++;\n\n         if (filters & PNG_FILTER_AVG)\n            num_filters++;\n\n         if (filters & PNG_FILTER_PAETH)\n            num_filters++;\n\n         /* Allocate needed row buffers if they have not already been\n          * allocated.\n          */\n         buf_size = PNG_ROWBYTES(png_ptr->usr_channels * png_ptr->usr_bit_depth,\n             png_ptr->width) + 1;\n\n         if (png_ptr->try_row == NULL)\n            png_ptr->try_row = png_voidcast(png_bytep,\n               png_malloc(png_ptr, buf_size));\n\n         if (num_filters > 1)\n         {\n            if (png_ptr->tst_row == NULL)\n               png_ptr->tst_row = png_voidcast(png_bytep,\n                  png_malloc(png_ptr, buf_size));\n         }\n      }\n      png_ptr->do_filter = (png_byte)filters;\n#endif\n   }\n   else\n      png_error(png_ptr, \"Unknown custom filter method\");\n}\n\n#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */\n/* Provide floating and fixed point APIs */\n#ifdef PNG_FLOATING_POINT_SUPPORTED\nvoid PNGAPI\npng_set_filter_heuristics(png_structrp png_ptr, int heuristic_method,\n    int num_weights, png_const_doublep filter_weights,\n    png_const_doublep filter_costs)\n{\n   PNG_UNUSED(png_ptr)\n   PNG_UNUSED(heuristic_method)\n   PNG_UNUSED(num_weights)\n   PNG_UNUSED(filter_weights)\n   PNG_UNUSED(filter_costs)\n}\n#endif /* FLOATING_POINT */\n\n#ifdef PNG_FIXED_POINT_SUPPORTED\nvoid PNGAPI\npng_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method,\n    int num_weights, png_const_fixed_point_p filter_weights,\n    png_const_fixed_point_p filter_costs)\n{\n   PNG_UNUSED(png_ptr)\n   PNG_UNUSED(heuristic_method)\n   PNG_UNUSED(num_weights)\n   PNG_UNUSED(filter_weights)\n   PNG_UNUSED(filter_costs)\n}\n#endif /* FIXED_POINT */\n#endif /* WRITE_WEIGHTED_FILTER */\n\n#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED\nvoid PNGAPI\npng_set_compression_level(png_structrp png_ptr, int level)\n{\n   png_debug(1, \"in png_set_compression_level\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->zlib_level = level;\n}\n\nvoid PNGAPI\npng_set_compression_mem_level(png_structrp png_ptr, int mem_level)\n{\n   png_debug(1, \"in png_set_compression_mem_level\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->zlib_mem_level = mem_level;\n}\n\nvoid PNGAPI\npng_set_compression_strategy(png_structrp png_ptr, int strategy)\n{\n   png_debug(1, \"in png_set_compression_strategy\");\n\n   if (png_ptr == NULL)\n      return;\n\n   /* The flag setting here prevents the libpng dynamic selection of strategy.\n    */\n   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;\n   png_ptr->zlib_strategy = strategy;\n}\n\n/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a\n * smaller value of window_bits if it can do so safely.\n */\nvoid PNGAPI\npng_set_compression_window_bits(png_structrp png_ptr, int window_bits)\n{\n   if (png_ptr == NULL)\n      return;\n\n   /* Prior to 1.6.0 this would warn but then set the window_bits value. This\n    * meant that negative window bits values could be selected that would cause\n    * libpng to write a non-standard PNG file with raw deflate or gzip\n    * compressed IDAT or ancillary chunks.  Such files can be read and there is\n    * no warning on read, so this seems like a very bad idea.\n    */\n   if (window_bits > 15)\n   {\n      png_warning(png_ptr, \"Only compression windows <= 32k supported by PNG\");\n      window_bits = 15;\n   }\n\n   else if (window_bits < 8)\n   {\n      png_warning(png_ptr, \"Only compression windows >= 256 supported by PNG\");\n      window_bits = 8;\n   }\n\n   png_ptr->zlib_window_bits = window_bits;\n}\n\nvoid PNGAPI\npng_set_compression_method(png_structrp png_ptr, int method)\n{\n   png_debug(1, \"in png_set_compression_method\");\n\n   if (png_ptr == NULL)\n      return;\n\n   /* This would produce an invalid PNG file if it worked, but it doesn't and\n    * deflate will fault it, so it is harmless to just warn here.\n    */\n   if (method != 8)\n      png_warning(png_ptr, \"Only compression method 8 is supported by PNG\");\n\n   png_ptr->zlib_method = method;\n}\n#endif /* WRITE_CUSTOMIZE_COMPRESSION */\n\n/* The following were added to libpng-1.5.4 */\n#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED\nvoid PNGAPI\npng_set_text_compression_level(png_structrp png_ptr, int level)\n{\n   png_debug(1, \"in png_set_text_compression_level\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->zlib_text_level = level;\n}\n\nvoid PNGAPI\npng_set_text_compression_mem_level(png_structrp png_ptr, int mem_level)\n{\n   png_debug(1, \"in png_set_text_compression_mem_level\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->zlib_text_mem_level = mem_level;\n}\n\nvoid PNGAPI\npng_set_text_compression_strategy(png_structrp png_ptr, int strategy)\n{\n   png_debug(1, \"in png_set_text_compression_strategy\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->zlib_text_strategy = strategy;\n}\n\n/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a\n * smaller value of window_bits if it can do so safely.\n */\nvoid PNGAPI\npng_set_text_compression_window_bits(png_structrp png_ptr, int window_bits)\n{\n   if (png_ptr == NULL)\n      return;\n\n   if (window_bits > 15)\n   {\n      png_warning(png_ptr, \"Only compression windows <= 32k supported by PNG\");\n      window_bits = 15;\n   }\n\n   else if (window_bits < 8)\n   {\n      png_warning(png_ptr, \"Only compression windows >= 256 supported by PNG\");\n      window_bits = 8;\n   }\n\n   png_ptr->zlib_text_window_bits = window_bits;\n}\n\nvoid PNGAPI\npng_set_text_compression_method(png_structrp png_ptr, int method)\n{\n   png_debug(1, \"in png_set_text_compression_method\");\n\n   if (png_ptr == NULL)\n      return;\n\n   if (method != 8)\n      png_warning(png_ptr, \"Only compression method 8 is supported by PNG\");\n\n   png_ptr->zlib_text_method = method;\n}\n#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */\n/* end of API added to libpng-1.5.4 */\n\nvoid PNGAPI\npng_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn)\n{\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->write_row_fn = write_row_fn;\n}\n\n#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED\nvoid PNGAPI\npng_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr\n    write_user_transform_fn)\n{\n   png_debug(1, \"in png_set_write_user_transform_fn\");\n\n   if (png_ptr == NULL)\n      return;\n\n   png_ptr->transformations |= PNG_USER_TRANSFORM;\n   png_ptr->write_user_transform_fn = write_user_transform_fn;\n}\n#endif\n\n\n#ifdef PNG_INFO_IMAGE_SUPPORTED\nvoid PNGAPI\npng_write_png(png_structrp png_ptr, png_inforp info_ptr,\n    int transforms, voidp params)\n{\n   if (png_ptr == NULL || info_ptr == NULL)\n      return;\n\n   if ((info_ptr->valid & PNG_INFO_IDAT) == 0)\n   {\n      png_app_error(png_ptr, \"no rows for png_write_image to write\");\n      return;\n   }\n\n   /* Write the file header information. */\n   png_write_info(png_ptr, info_ptr);\n\n   /* ------ these transformations don't touch the info structure ------- */\n\n   /* Invert monochrome pixels */\n   if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0)\n#ifdef PNG_WRITE_INVERT_SUPPORTED\n      png_set_invert_mono(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_INVERT_MONO not supported\");\n#endif\n\n   /* Shift the pixels up to a legal bit depth and fill in\n    * as appropriate to correctly scale the image.\n    */\n   if ((transforms & PNG_TRANSFORM_SHIFT) != 0)\n#ifdef PNG_WRITE_SHIFT_SUPPORTED\n      if ((info_ptr->valid & PNG_INFO_sBIT) != 0)\n         png_set_shift(png_ptr, &info_ptr->sig_bit);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_SHIFT not supported\");\n#endif\n\n   /* Pack pixels into bytes */\n   if ((transforms & PNG_TRANSFORM_PACKING) != 0)\n#ifdef PNG_WRITE_PACK_SUPPORTED\n      png_set_packing(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_PACKING not supported\");\n#endif\n\n   /* Swap location of alpha bytes from ARGB to RGBA */\n   if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0)\n#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED\n      png_set_swap_alpha(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_SWAP_ALPHA not supported\");\n#endif\n\n   /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into\n    * RGB, note that the code expects the input color type to be G or RGB; no\n    * alpha channel.\n    */\n   if ((transforms & (PNG_TRANSFORM_STRIP_FILLER_AFTER|\n       PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0)\n   {\n#ifdef PNG_WRITE_FILLER_SUPPORTED\n      if ((transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) != 0)\n      {\n         if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0)\n            png_app_error(png_ptr,\n                \"PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported\");\n\n         /* Continue if ignored - this is the pre-1.6.10 behavior */\n         png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);\n      }\n\n      else if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0)\n         png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_STRIP_FILLER not supported\");\n#endif\n   }\n\n   /* Flip BGR pixels to RGB */\n   if ((transforms & PNG_TRANSFORM_BGR) != 0)\n#ifdef PNG_WRITE_BGR_SUPPORTED\n      png_set_bgr(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_BGR not supported\");\n#endif\n\n   /* Swap bytes of 16-bit files to most significant byte first */\n   if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0)\n#ifdef PNG_WRITE_SWAP_SUPPORTED\n      png_set_swap(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_SWAP_ENDIAN not supported\");\n#endif\n\n   /* Swap bits of 1-bit, 2-bit, 4-bit packed pixel formats */\n   if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0)\n#ifdef PNG_WRITE_PACKSWAP_SUPPORTED\n      png_set_packswap(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_PACKSWAP not supported\");\n#endif\n\n   /* Invert the alpha channel from opacity to transparency */\n   if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0)\n#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED\n      png_set_invert_alpha(png_ptr);\n#else\n      png_app_error(png_ptr, \"PNG_TRANSFORM_INVERT_ALPHA not supported\");\n#endif\n\n   /* ----------------------- end of transformations ------------------- */\n\n   /* Write the bits */\n   png_write_image(png_ptr, info_ptr->row_pointers);\n\n   /* It is REQUIRED to call this to finish writing the rest of the file */\n   png_write_end(png_ptr, info_ptr);\n\n   PNG_UNUSED(params)\n}\n#endif\n\n\n#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED\n/* Initialize the write structure - general purpose utility. */\nstatic int\npng_image_write_init(png_imagep image)\n{\n   png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image,\n       png_safe_error, png_safe_warning);\n\n   if (png_ptr != NULL)\n   {\n      png_infop info_ptr = png_create_info_struct(png_ptr);\n\n      if (info_ptr != NULL)\n      {\n         png_controlp control = png_voidcast(png_controlp,\n             png_malloc_warn(png_ptr, (sizeof *control)));\n\n         if (control != NULL)\n         {\n            memset(control, 0, (sizeof *control));\n\n            control->png_ptr = png_ptr;\n            control->info_ptr = info_ptr;\n            control->for_write = 1;\n\n            image->opaque = control;\n            return 1;\n         }\n\n         /* Error clean up */\n         png_destroy_info_struct(png_ptr, &info_ptr);\n      }\n\n      png_destroy_write_struct(&png_ptr, NULL);\n   }\n\n   return png_image_error(image, \"png_image_write_: out of memory\");\n}\n\n/* Arguments to png_image_write_main: */\ntypedef struct\n{\n   /* Arguments: */\n   png_imagep      image;\n   png_const_voidp buffer;\n   png_int_32      row_stride;\n   png_const_voidp colormap;\n   int             convert_to_8bit;\n   /* Local variables: */\n   png_const_voidp first_row;\n   ptrdiff_t       row_bytes;\n   png_voidp       local_row;\n   /* Byte count for memory writing */\n   png_bytep        memory;\n   png_alloc_size_t memory_bytes; /* not used for STDIO */\n   png_alloc_size_t output_bytes; /* running total */\n} png_image_write_control;\n\n/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to\n * do any necessary byte swapping.  The component order is defined by the\n * png_image format value.\n */\nstatic int\npng_write_image_16bit(png_voidp argument)\n{\n   png_image_write_control *display = png_voidcast(png_image_write_control*,\n       argument);\n   png_imagep image = display->image;\n   png_structrp png_ptr = image->opaque->png_ptr;\n\n   png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,\n       display->first_row);\n   png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);\n   png_uint_16p row_end;\n   const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;\n   int aindex = 0;\n   png_uint_32 y = image->height;\n\n   if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)\n   {\n#   ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED\n      if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0)\n      {\n         aindex = -1;\n         ++input_row; /* To point to the first component */\n         ++output_row;\n      }\n         else\n            aindex = channels;\n#     else\n         aindex = channels;\n#     endif\n   }\n\n   else\n      png_error(png_ptr, \"png_write_image: internal call error\");\n\n   /* Work out the output row end and count over this, note that the increment\n    * above to 'row' means that row_end can actually be beyond the end of the\n    * row; this is correct.\n    */\n   row_end = output_row + image->width * (channels+1);\n\n   while (y-- > 0)\n   {\n      png_const_uint_16p in_ptr = input_row;\n      png_uint_16p out_ptr = output_row;\n\n      while (out_ptr < row_end)\n      {\n         const png_uint_16 alpha = in_ptr[aindex];\n         png_uint_32 reciprocal = 0;\n         int c;\n\n         out_ptr[aindex] = alpha;\n\n         /* Calculate a reciprocal.  The correct calculation is simply\n          * component/alpha*65535 << 15. (I.e. 15 bits of precision); this\n          * allows correct rounding by adding .5 before the shift.  'reciprocal'\n          * is only initialized when required.\n          */\n         if (alpha > 0 && alpha < 65535)\n            reciprocal = ((0xffff<<15)+(alpha>>1))/alpha;\n\n         c = channels;\n         do /* always at least one channel */\n         {\n            png_uint_16 component = *in_ptr++;\n\n            /* The following gives 65535 for an alpha of 0, which is fine,\n             * otherwise if 0/0 is represented as some other value there is more\n             * likely to be a discontinuity which will probably damage\n             * compression when moving from a fully transparent area to a\n             * nearly transparent one.  (The assumption here is that opaque\n             * areas tend not to be 0 intensity.)\n             */\n            if (component >= alpha)\n               component = 65535;\n\n            /* component<alpha, so component/alpha is less than one and\n             * component*reciprocal is less than 2^31.\n             */\n            else if (component > 0 && alpha < 65535)\n            {\n               png_uint_32 calc = component * reciprocal;\n               calc += 16384; /* round to nearest */\n               component = (png_uint_16)(calc >> 15);\n            }\n\n            *out_ptr++ = component;\n         }\n         while (--c > 0);\n\n         /* Skip to next component (skip the intervening alpha channel) */\n         ++in_ptr;\n         ++out_ptr;\n      }\n\n      png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row));\n      input_row += display->row_bytes/(sizeof (png_uint_16));\n   }\n\n   return 1;\n}\n\n/* Given 16-bit input (1 to 4 channels) write 8-bit output.  If an alpha channel\n * is present it must be removed from the components, the components are then\n * written in sRGB encoding.  No components are added or removed.\n *\n * Calculate an alpha reciprocal to reverse pre-multiplication.  As above the\n * calculation can be done to 15 bits of accuracy; however, the output needs to\n * be scaled in the range 0..255*65535, so include that scaling here.\n */\n#   define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha)\n\nstatic png_byte\npng_unpremultiply(png_uint_32 component, png_uint_32 alpha,\n   png_uint_32 reciprocal/*from the above macro*/)\n{\n   /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0\n    * is represented as some other value there is more likely to be a\n    * discontinuity which will probably damage compression when moving from a\n    * fully transparent area to a nearly transparent one.  (The assumption here\n    * is that opaque areas tend not to be 0 intensity.)\n    *\n    * There is a rounding problem here; if alpha is less than 128 it will end up\n    * as 0 when scaled to 8 bits.  To avoid introducing spurious colors into the\n    * output change for this too.\n    */\n   if (component >= alpha || alpha < 128)\n      return 255;\n\n   /* component<alpha, so component/alpha is less than one and\n    * component*reciprocal is less than 2^31.\n    */\n   else if (component > 0)\n   {\n      /* The test is that alpha/257 (rounded) is less than 255, the first value\n       * that becomes 255 is 65407.\n       * NOTE: this must agree with the PNG_DIV257 macro (which must, therefore,\n       * be exact!)  [Could also test reciprocal != 0]\n       */\n      if (alpha < 65407)\n      {\n         component *= reciprocal;\n         component += 64; /* round to nearest */\n         component >>= 7;\n      }\n\n      else\n         component *= 255;\n\n      /* Convert the component to sRGB. */\n      return (png_byte)PNG_sRGB_FROM_LINEAR(component);\n   }\n\n   else\n      return 0;\n}\n\nstatic int\npng_write_image_8bit(png_voidp argument)\n{\n   png_image_write_control *display = png_voidcast(png_image_write_control*,\n       argument);\n   png_imagep image = display->image;\n   png_structrp png_ptr = image->opaque->png_ptr;\n\n   png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,\n       display->first_row);\n   png_bytep output_row = png_voidcast(png_bytep, display->local_row);\n   png_uint_32 y = image->height;\n   const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;\n\n   if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)\n   {\n      png_bytep row_end;\n      int aindex;\n\n#   ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED\n      if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0)\n      {\n         aindex = -1;\n         ++input_row; /* To point to the first component */\n         ++output_row;\n      }\n\n      else\n#   endif\n      aindex = channels;\n\n      /* Use row_end in place of a loop counter: */\n      row_end = output_row + image->width * (channels+1);\n\n      while (y-- > 0)\n      {\n         png_const_uint_16p in_ptr = input_row;\n         png_bytep out_ptr = output_row;\n\n         while (out_ptr < row_end)\n         {\n            png_uint_16 alpha = in_ptr[aindex];\n            png_byte alphabyte = (png_byte)PNG_DIV257(alpha);\n            png_uint_32 reciprocal = 0;\n            int c;\n\n            /* Scale and write the alpha channel. */\n            out_ptr[aindex] = alphabyte;\n\n            if (alphabyte > 0 && alphabyte < 255)\n               reciprocal = UNP_RECIPROCAL(alpha);\n\n            c = channels;\n            do /* always at least one channel */\n               *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal);\n            while (--c > 0);\n\n            /* Skip to next component (skip the intervening alpha channel) */\n            ++in_ptr;\n            ++out_ptr;\n         } /* while out_ptr < row_end */\n\n         png_write_row(png_ptr, png_voidcast(png_const_bytep,\n             display->local_row));\n         input_row += display->row_bytes/(sizeof (png_uint_16));\n      } /* while y */\n   }\n\n   else\n   {\n      /* No alpha channel, so the row_end really is the end of the row and it\n       * is sufficient to loop over the components one by one.\n       */\n      png_bytep row_end = output_row + image->width * channels;\n\n      while (y-- > 0)\n      {\n         png_const_uint_16p in_ptr = input_row;\n         png_bytep out_ptr = output_row;\n\n         while (out_ptr < row_end)\n         {\n            png_uint_32 component = *in_ptr++;\n\n            component *= 255;\n            *out_ptr++ = (png_byte)PNG_sRGB_FROM_LINEAR(component);\n         }\n\n         png_write_row(png_ptr, output_row);\n         input_row += display->row_bytes/(sizeof (png_uint_16));\n      }\n   }\n\n   return 1;\n}\n\nstatic void\npng_image_set_PLTE(png_image_write_control *display)\n{\n   const png_imagep image = display->image;\n   const void *cmap = display->colormap;\n   const int entries = image->colormap_entries > 256 ? 256 :\n       (int)image->colormap_entries;\n\n   /* NOTE: the caller must check for cmap != NULL and entries != 0 */\n   const png_uint_32 format = image->format;\n   const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);\n\n#   if defined(PNG_FORMAT_BGR_SUPPORTED) &&\\\n      defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED)\n      const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 &&\n          (format & PNG_FORMAT_FLAG_ALPHA) != 0;\n#   else\n#     define afirst 0\n#   endif\n\n#   ifdef PNG_FORMAT_BGR_SUPPORTED\n      const int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;\n#   else\n#     define bgr 0\n#   endif\n\n   int i, num_trans;\n   png_color palette[256];\n   png_byte tRNS[256];\n\n   memset(tRNS, 255, (sizeof tRNS));\n   memset(palette, 0, (sizeof palette));\n\n   for (i=num_trans=0; i<entries; ++i)\n   {\n      /* This gets automatically converted to sRGB with reversal of the\n       * pre-multiplication if the color-map has an alpha channel.\n       */\n      if ((format & PNG_FORMAT_FLAG_LINEAR) != 0)\n      {\n         png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap);\n\n         entry += i * channels;\n\n         if ((channels & 1) != 0) /* no alpha */\n         {\n            if (channels >= 3) /* RGB */\n            {\n               palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 *\n                   entry[(2 ^ bgr)]);\n               palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 *\n                   entry[1]);\n               palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 *\n                   entry[bgr]);\n            }\n\n            else /* Gray */\n               palette[i].blue = palette[i].red = palette[i].green =\n                  (png_byte)PNG_sRGB_FROM_LINEAR(255 * *entry);\n         }\n\n         else /* alpha */\n         {\n            png_uint_16 alpha = entry[afirst ? 0 : channels-1];\n            png_byte alphabyte = (png_byte)PNG_DIV257(alpha);\n            png_uint_32 reciprocal = 0;\n\n            /* Calculate a reciprocal, as in the png_write_image_8bit code above\n             * this is designed to produce a value scaled to 255*65535 when\n             * divided by 128 (i.e. asr 7).\n             */\n            if (alphabyte > 0 && alphabyte < 255)\n               reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha;\n\n            tRNS[i] = alphabyte;\n            if (alphabyte < 255)\n               num_trans = i+1;\n\n            if (channels >= 3) /* RGB */\n            {\n               palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)],\n                  alpha, reciprocal);\n               palette[i].green = png_unpremultiply(entry[afirst + 1], alpha,\n                  reciprocal);\n               palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha,\n                  reciprocal);\n            }\n\n            else /* gray */\n               palette[i].blue = palette[i].red = palette[i].green =\n                  png_unpremultiply(entry[afirst], alpha, reciprocal);\n         }\n      }\n\n      else /* Color-map has sRGB values */\n      {\n         png_const_bytep entry = png_voidcast(png_const_bytep, cmap);\n\n         entry += i * channels;\n\n         switch (channels)\n         {\n            case 4:\n               tRNS[i] = entry[afirst ? 0 : 3];\n               if (tRNS[i] < 255)\n                  num_trans = i+1;\n               /* FALL THROUGH */\n            case 3:\n               palette[i].blue = entry[afirst + (2 ^ bgr)];\n               palette[i].green = entry[afirst + 1];\n               palette[i].red = entry[afirst + bgr];\n               break;\n\n            case 2:\n               tRNS[i] = entry[1 ^ afirst];\n               if (tRNS[i] < 255)\n                  num_trans = i+1;\n               /* FALL THROUGH */\n            case 1:\n               palette[i].blue = palette[i].red = palette[i].green =\n                  entry[afirst];\n               break;\n\n            default:\n               break;\n         }\n      }\n   }\n\n#   ifdef afirst\n#     undef afirst\n#   endif\n#   ifdef bgr\n#     undef bgr\n#   endif\n\n   png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette,\n      entries);\n\n   if (num_trans > 0)\n      png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS,\n         num_trans, NULL);\n\n   image->colormap_entries = entries;\n}\n\nstatic int\npng_image_write_main(png_voidp argument)\n{\n   png_image_write_control *display = png_voidcast(png_image_write_control*,\n      argument);\n   png_imagep image = display->image;\n   png_structrp png_ptr = image->opaque->png_ptr;\n   png_inforp info_ptr = image->opaque->info_ptr;\n   png_uint_32 format = image->format;\n\n   /* The following four ints are actually booleans */\n   int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);\n   int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */\n   int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA);\n   int write_16bit = linear && !colormap && (display->convert_to_8bit == 0);\n\n#   ifdef PNG_BENIGN_ERRORS_SUPPORTED\n      /* Make sure we error out on any bad situation */\n      png_set_benign_errors(png_ptr, 0/*error*/);\n#   endif\n\n   /* Default the 'row_stride' parameter if required, also check the row stride\n    * and total image size to ensure that they are within the system limits.\n    */\n   {\n      const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);\n\n      if (image->width <= 0x7FFFFFFFU/channels) /* no overflow */\n      {\n         png_uint_32 check;\n         const png_uint_32 png_row_stride = image->width * channels;\n\n         if (display->row_stride == 0)\n            display->row_stride = (png_int_32)/*SAFE*/png_row_stride;\n\n         if (display->row_stride < 0)\n            check = -display->row_stride;\n\n         else\n            check = display->row_stride;\n\n         if (check >= png_row_stride)\n         {\n            /* Now check for overflow of the image buffer calculation; this\n             * limits the whole image size to 32 bits for API compatibility with\n             * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.\n             */\n            if (image->height > 0xFFFFFFFF/png_row_stride)\n               png_error(image->opaque->png_ptr, \"memory image too large\");\n         }\n\n         else\n            png_error(image->opaque->png_ptr, \"supplied row stride too small\");\n      }\n\n      else\n         png_error(image->opaque->png_ptr, \"image row stride too large\");\n   }\n\n   /* Set the required transforms then write the rows in the correct order. */\n   if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0)\n   {\n      if (display->colormap != NULL && image->colormap_entries > 0)\n      {\n         png_uint_32 entries = image->colormap_entries;\n\n         png_set_IHDR(png_ptr, info_ptr, image->width, image->height,\n            entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),\n            PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,\n            PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);\n\n         png_image_set_PLTE(display);\n      }\n\n      else\n         png_error(image->opaque->png_ptr,\n            \"no color-map for color-mapped image\");\n   }\n\n   else\n      png_set_IHDR(png_ptr, info_ptr, image->width, image->height,\n         write_16bit ? 16 : 8,\n         ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +\n         ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),\n         PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);\n\n   /* Counter-intuitively the data transformations must be called *after*\n    * png_write_info, not before as in the read code, but the 'set' functions\n    * must still be called before.  Just set the color space information, never\n    * write an interlaced image.\n    */\n\n   if (write_16bit != 0)\n   {\n      /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */\n      png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR);\n\n      if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)\n         png_set_cHRM_fixed(png_ptr, info_ptr,\n            /* color      x       y */\n            /* white */ 31270, 32900,\n            /* red   */ 64000, 33000,\n            /* green */ 30000, 60000,\n            /* blue  */ 15000,  6000\n         );\n   }\n\n   else if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)\n      png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL);\n\n   /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit\n    * space must still be gamma encoded.\n    */\n   else\n      png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE);\n\n   /* Write the file header. */\n   png_write_info(png_ptr, info_ptr);\n\n   /* Now set up the data transformations (*after* the header is written),\n    * remove the handled transformations from the 'format' flags for checking.\n    *\n    * First check for a little endian system if writing 16-bit files.\n    */\n   if (write_16bit != 0)\n   {\n      PNG_CONST png_uint_16 le = 0x0001;\n\n      if ((*(png_const_bytep) & le) != 0)\n         png_set_swap(png_ptr);\n   }\n\n#   ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED\n      if ((format & PNG_FORMAT_FLAG_BGR) != 0)\n      {\n         if (colormap == 0 && (format & PNG_FORMAT_FLAG_COLOR) != 0)\n            png_set_bgr(png_ptr);\n         format &= ~PNG_FORMAT_FLAG_BGR;\n      }\n#   endif\n\n#   ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED\n      if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)\n      {\n         if (colormap == 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0)\n            png_set_swap_alpha(png_ptr);\n         format &= ~PNG_FORMAT_FLAG_AFIRST;\n      }\n#   endif\n\n   /* If there are 16 or fewer color-map entries we wrote a lower bit depth\n    * above, but the application data is still byte packed.\n    */\n   if (colormap != 0 && image->colormap_entries <= 16)\n      png_set_packing(png_ptr);\n\n   /* That should have handled all (both) the transforms. */\n   if ((format & ~(png_uint_32)(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR |\n         PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0)\n      png_error(png_ptr, \"png_write_image: unsupported transformation\");\n\n   {\n      png_const_bytep row = png_voidcast(png_const_bytep, display->buffer);\n      ptrdiff_t row_bytes = display->row_stride;\n\n      if (linear != 0)\n         row_bytes *= (sizeof (png_uint_16));\n\n      if (row_bytes < 0)\n         row += (image->height-1) * (-row_bytes);\n\n      display->first_row = row;\n      display->row_bytes = row_bytes;\n   }\n\n   /* Apply 'fast' options if the flag is set. */\n   if ((image->flags & PNG_IMAGE_FLAG_FAST) != 0)\n   {\n      png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_NO_FILTERS);\n      /* NOTE: determined by experiment using pngstest, this reflects some\n       * balance between the time to write the image once and the time to read\n       * it about 50 times.  The speed-up in pngstest was about 10-20% of the\n       * total (user) time on a heavily loaded system.\n       */\n#   ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED\n      png_set_compression_level(png_ptr, 3);\n#   endif\n   }\n\n   /* Check for the cases that currently require a pre-transform on the row\n    * before it is written.  This only applies when the input is 16-bit and\n    * either there is an alpha channel or it is converted to 8-bit.\n    */\n   if ((linear != 0 && alpha != 0 ) ||\n       (colormap == 0 && display->convert_to_8bit != 0))\n   {\n      png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,\n         png_get_rowbytes(png_ptr, info_ptr)));\n      int result;\n\n      display->local_row = row;\n      if (write_16bit != 0)\n         result = png_safe_execute(image, png_write_image_16bit, display);\n      else\n         result = png_safe_execute(image, png_write_image_8bit, display);\n      display->local_row = NULL;\n\n      png_free(png_ptr, row);\n\n      /* Skip the 'write_end' on error: */\n      if (result == 0)\n         return 0;\n   }\n\n   /* Otherwise this is the case where the input is in a format currently\n    * supported by the rest of the libpng write code; call it directly.\n    */\n   else\n   {\n      png_const_bytep row = png_voidcast(png_const_bytep, display->first_row);\n      ptrdiff_t row_bytes = display->row_bytes;\n      png_uint_32 y = image->height;\n\n      while (y-- > 0)\n      {\n         png_write_row(png_ptr, row);\n         row += row_bytes;\n      }\n   }\n\n   png_write_end(png_ptr, info_ptr);\n   return 1;\n}\n\n\nstatic void (PNGCBAPI\nimage_memory_write)(png_structp png_ptr, png_bytep/*const*/ data,\n   png_size_t size)\n{\n   png_image_write_control *display = png_voidcast(png_image_write_control*,\n      png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/);\n   const png_alloc_size_t ob = display->output_bytes;\n\n   /* Check for overflow; this should never happen: */\n   if (size <= ((png_alloc_size_t)-1) - ob)\n   {\n      /* I don't think libpng ever does this, but just in case: */\n      if (size > 0)\n      {\n         if (display->memory_bytes >= ob+size) /* writing */\n            memcpy(display->memory+ob, data, size);\n\n         /* Always update the size: */\n         display->output_bytes = ob+size;\n      }\n   }\n\n   else\n      png_error(png_ptr, \"png_image_write_to_memory: PNG too big\");\n}\n\nstatic void (PNGCBAPI\nimage_memory_flush)(png_structp png_ptr)\n{\n   PNG_UNUSED(png_ptr)\n}\n\nstatic int\npng_image_write_memory(png_voidp argument)\n{\n   png_image_write_control *display = png_voidcast(png_image_write_control*,\n      argument);\n\n   /* The rest of the memory-specific init and write_main in an error protected\n    * environment.  This case needs to use callbacks for the write operations\n    * since libpng has no built in support for writing to memory.\n    */\n   png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/,\n         image_memory_write, image_memory_flush);\n\n   return png_image_write_main(display);\n}\n\nint PNGAPI\npng_image_write_to_memory(png_imagep image, void *memory,\n   png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit,\n   const void *buffer, png_int_32 row_stride, const void *colormap)\n{\n   /* Write the image to the given buffer, or count the bytes if it is NULL */\n   if (image != NULL && image->version == PNG_IMAGE_VERSION)\n   {\n      if (memory_bytes != NULL && buffer != NULL)\n      {\n         /* This is to give the caller an easier error detection in the NULL\n          * case and guard against uninitialized variable problems:\n          */\n         if (memory == NULL)\n            *memory_bytes = 0;\n\n         if (png_image_write_init(image) != 0)\n         {\n            png_image_write_control display;\n            int result;\n\n            memset(&display, 0, (sizeof display));\n            display.image = image;\n            display.buffer = buffer;\n            display.row_stride = row_stride;\n            display.colormap = colormap;\n            display.convert_to_8bit = convert_to_8bit;\n            display.memory = png_voidcast(png_bytep, memory);\n            display.memory_bytes = *memory_bytes;\n            display.output_bytes = 0;\n\n            result = png_safe_execute(image, png_image_write_memory, &display);\n            png_image_free(image);\n\n            /* write_memory returns true even if we ran out of buffer. */\n            if (result)\n            {\n               /* On out-of-buffer this function returns '0' but still updates\n                * memory_bytes:\n                */\n               if (memory != NULL && display.output_bytes > *memory_bytes)\n                  result = 0;\n\n               *memory_bytes = display.output_bytes;\n            }\n\n            return result;\n         }\n\n         else\n            return 0;\n      }\n\n      else\n         return png_image_error(image,\n            \"png_image_write_to_memory: invalid argument\");\n   }\n\n   else if (image != NULL)\n      return png_image_error(image,\n         \"png_image_write_to_memory: incorrect PNG_IMAGE_VERSION\");\n\n   else\n      return 0;\n}\n\n#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED\nint PNGAPI\npng_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,\n   const void *buffer, png_int_32 row_stride, const void *colormap)\n{\n   /* Write the image to the given (FILE*). */\n   if (image != NULL && image->version == PNG_IMAGE_VERSION)\n   {\n      if (file != NULL && buffer != NULL)\n      {\n         if (png_image_write_init(image) != 0)\n         {\n            png_image_write_control display;\n            int result;\n\n            /* This is slightly evil, but png_init_io doesn't do anything other\n             * than this and we haven't changed the standard IO functions so\n             * this saves a 'safe' function.\n             */\n            image->opaque->png_ptr->io_ptr = file;\n\n            memset(&display, 0, (sizeof display));\n            display.image = image;\n            display.buffer = buffer;\n            display.row_stride = row_stride;\n            display.colormap = colormap;\n            display.convert_to_8bit = convert_to_8bit;\n\n            result = png_safe_execute(image, png_image_write_main, &display);\n            png_image_free(image);\n            return result;\n         }\n\n         else\n            return 0;\n      }\n\n      else\n         return png_image_error(image,\n            \"png_image_write_to_stdio: invalid argument\");\n   }\n\n   else if (image != NULL)\n      return png_image_error(image,\n         \"png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION\");\n\n   else\n      return 0;\n}\n\nint PNGAPI\npng_image_write_to_file(png_imagep image, const char *file_name,\n   int convert_to_8bit, const void *buffer, png_int_32 row_stride,\n   const void *colormap)\n{\n   /* Write the image to the named file. */\n   if (image != NULL && image->version == PNG_IMAGE_VERSION)\n   {\n      if (file_name != NULL && buffer != NULL)\n      {\n         FILE *fp = fopen(file_name, \"wb\");\n\n         if (fp != NULL)\n         {\n            if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,\n               row_stride, colormap) != 0)\n            {\n               int error; /* from fflush/fclose */\n\n               /* Make sure the file is flushed correctly. */\n               if (fflush(fp) == 0 && ferror(fp) == 0)\n               {\n                  if (fclose(fp) == 0)\n                     return 1;\n\n                  error = errno; /* from fclose */\n               }\n\n               else\n               {\n                  error = errno; /* from fflush or ferror */\n                  (void)fclose(fp);\n               }\n\n               (void)remove(file_name);\n               /* The image has already been cleaned up; this is just used to\n                * set the error (because the original write succeeded).\n                */\n               return png_image_error(image, strerror(error));\n            }\n\n            else\n            {\n               /* Clean up: just the opened file. */\n               (void)fclose(fp);\n               (void)remove(file_name);\n               return 0;\n            }\n         }\n\n         else\n            return png_image_error(image, strerror(errno));\n      }\n\n      else\n         return png_image_error(image,\n            \"png_image_write_to_file: invalid argument\");\n   }\n\n   else if (image != NULL)\n      return png_image_error(image,\n         \"png_image_write_to_file: incorrect PNG_IMAGE_VERSION\");\n\n   else\n      return 0;\n}\n#endif /* SIMPLIFIED_WRITE_STDIO */\n#endif /* SIMPLIFIED_WRITE */\n#endif /* WRITE */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngwtran.c",
    "content": "\n/* pngwtran.c - transforms the data in a row for PNG writers\n *\n * Last changed in libpng 1.6.18 [July 23, 2015]\n * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n#include \"pngpriv.h\"\n\n#ifdef PNG_WRITE_SUPPORTED\n#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED\n\n#ifdef PNG_WRITE_PACK_SUPPORTED\n/* Pack pixels into bytes.  Pass the true bit depth in bit_depth.  The\n * row_info bit depth should be 8 (one pixel per byte).  The channels\n * should be 1 (this only happens on grayscale and paletted images).\n */\nstatic void\npng_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)\n{\n   png_debug(1, \"in png_do_pack\");\n\n   if (row_info->bit_depth == 8 &&\n      row_info->channels == 1)\n   {\n      switch ((int)bit_depth)\n      {\n         case 1:\n         {\n            png_bytep sp, dp;\n            int mask, v;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n\n            sp = row;\n            dp = row;\n            mask = 0x80;\n            v = 0;\n\n            for (i = 0; i < row_width; i++)\n            {\n               if (*sp != 0)\n                  v |= mask;\n\n               sp++;\n\n               if (mask > 1)\n                  mask >>= 1;\n\n               else\n               {\n                  mask = 0x80;\n                  *dp = (png_byte)v;\n                  dp++;\n                  v = 0;\n               }\n            }\n\n            if (mask != 0x80)\n               *dp = (png_byte)v;\n\n            break;\n         }\n\n         case 2:\n         {\n            png_bytep sp, dp;\n            unsigned int shift;\n            int v;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n\n            sp = row;\n            dp = row;\n            shift = 6;\n            v = 0;\n\n            for (i = 0; i < row_width; i++)\n            {\n               png_byte value;\n\n               value = (png_byte)(*sp & 0x03);\n               v |= (value << shift);\n\n               if (shift == 0)\n               {\n                  shift = 6;\n                  *dp = (png_byte)v;\n                  dp++;\n                  v = 0;\n               }\n\n               else\n                  shift -= 2;\n\n               sp++;\n            }\n\n            if (shift != 6)\n               *dp = (png_byte)v;\n\n            break;\n         }\n\n         case 4:\n         {\n            png_bytep sp, dp;\n            unsigned int shift;\n            int v;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n\n            sp = row;\n            dp = row;\n            shift = 4;\n            v = 0;\n\n            for (i = 0; i < row_width; i++)\n            {\n               png_byte value;\n\n               value = (png_byte)(*sp & 0x0f);\n               v |= (value << shift);\n\n               if (shift == 0)\n               {\n                  shift = 4;\n                  *dp = (png_byte)v;\n                  dp++;\n                  v = 0;\n               }\n\n               else\n                  shift -= 4;\n\n               sp++;\n            }\n\n            if (shift != 4)\n               *dp = (png_byte)v;\n\n            break;\n         }\n\n         default:\n            break;\n      }\n\n      row_info->bit_depth = (png_byte)bit_depth;\n      row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);\n      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,\n          row_info->width);\n   }\n}\n#endif\n\n#ifdef PNG_WRITE_SHIFT_SUPPORTED\n/* Shift pixel values to take advantage of whole range.  Pass the\n * true number of bits in bit_depth.  The row should be packed\n * according to row_info->bit_depth.  Thus, if you had a row of\n * bit depth 4, but the pixels only had values from 0 to 7, you\n * would pass 3 as bit_depth, and this routine would translate the\n * data to 0 to 15.\n */\nstatic void\npng_do_shift(png_row_infop row_info, png_bytep row,\n    png_const_color_8p bit_depth)\n{\n   png_debug(1, \"in png_do_shift\");\n\n   if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)\n   {\n      int shift_start[4], shift_dec[4];\n      int channels = 0;\n\n      if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)\n      {\n         shift_start[channels] = row_info->bit_depth - bit_depth->red;\n         shift_dec[channels] = bit_depth->red;\n         channels++;\n\n         shift_start[channels] = row_info->bit_depth - bit_depth->green;\n         shift_dec[channels] = bit_depth->green;\n         channels++;\n\n         shift_start[channels] = row_info->bit_depth - bit_depth->blue;\n         shift_dec[channels] = bit_depth->blue;\n         channels++;\n      }\n\n      else\n      {\n         shift_start[channels] = row_info->bit_depth - bit_depth->gray;\n         shift_dec[channels] = bit_depth->gray;\n         channels++;\n      }\n\n      if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)\n      {\n         shift_start[channels] = row_info->bit_depth - bit_depth->alpha;\n         shift_dec[channels] = bit_depth->alpha;\n         channels++;\n      }\n\n      /* With low row depths, could only be grayscale, so one channel */\n      if (row_info->bit_depth < 8)\n      {\n         png_bytep bp = row;\n         png_size_t i;\n         unsigned int mask;\n         png_size_t row_bytes = row_info->rowbytes;\n\n         if (bit_depth->gray == 1 && row_info->bit_depth == 2)\n            mask = 0x55;\n\n         else if (row_info->bit_depth == 4 && bit_depth->gray == 3)\n            mask = 0x11;\n\n         else\n            mask = 0xff;\n\n         for (i = 0; i < row_bytes; i++, bp++)\n         {\n            int j;\n            unsigned int v, out;\n\n            v = *bp;\n            out = 0;\n\n            for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])\n            {\n               if (j > 0)\n                  out |= v << j;\n\n               else\n                  out |= (v >> (-j)) & mask;\n            }\n\n            *bp = (png_byte)(out & 0xff);\n         }\n      }\n\n      else if (row_info->bit_depth == 8)\n      {\n         png_bytep bp = row;\n         png_uint_32 i;\n         png_uint_32 istop = channels * row_info->width;\n\n         for (i = 0; i < istop; i++, bp++)\n         {\n\n            const unsigned int c = i%channels;\n            int j;\n            unsigned int v, out;\n\n            v = *bp;\n            out = 0;\n\n            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])\n            {\n               if (j > 0)\n                  out |= v << j;\n\n               else\n                  out |= v >> (-j);\n            }\n\n            *bp = (png_byte)(out & 0xff);\n         }\n      }\n\n      else\n      {\n         png_bytep bp;\n         png_uint_32 i;\n         png_uint_32 istop = channels * row_info->width;\n\n         for (bp = row, i = 0; i < istop; i++)\n         {\n            const unsigned int c = i%channels;\n            int j;\n            unsigned int value, v;\n\n            v = png_get_uint_16(bp);\n            value = 0;\n\n            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])\n            {\n               if (j > 0)\n                  value |= v << j;\n\n               else\n                  value |= v >> (-j);\n            }\n            *bp++ = (png_byte)((value >> 8) & 0xff);\n            *bp++ = (png_byte)(value & 0xff);\n         }\n      }\n   }\n}\n#endif\n\n#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED\nstatic void\npng_do_write_swap_alpha(png_row_infop row_info, png_bytep row)\n{\n   png_debug(1, \"in png_do_write_swap_alpha\");\n\n   {\n      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n      {\n         if (row_info->bit_depth == 8)\n         {\n            /* This converts from ARGB to RGBA */\n            png_bytep sp, dp;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n\n            for (i = 0, sp = dp = row; i < row_width; i++)\n            {\n               png_byte save = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = save;\n            }\n         }\n\n#ifdef PNG_WRITE_16BIT_SUPPORTED\n         else\n         {\n            /* This converts from AARRGGBB to RRGGBBAA */\n            png_bytep sp, dp;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n\n            for (i = 0, sp = dp = row; i < row_width; i++)\n            {\n               png_byte save[2];\n               save[0] = *(sp++);\n               save[1] = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = save[0];\n               *(dp++) = save[1];\n            }\n         }\n#endif /* WRITE_16BIT */\n      }\n\n      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n      {\n         if (row_info->bit_depth == 8)\n         {\n            /* This converts from AG to GA */\n            png_bytep sp, dp;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n\n            for (i = 0, sp = dp = row; i < row_width; i++)\n            {\n               png_byte save = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = save;\n            }\n         }\n\n#ifdef PNG_WRITE_16BIT_SUPPORTED\n         else\n         {\n            /* This converts from AAGG to GGAA */\n            png_bytep sp, dp;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n\n            for (i = 0, sp = dp = row; i < row_width; i++)\n            {\n               png_byte save[2];\n               save[0] = *(sp++);\n               save[1] = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = save[0];\n               *(dp++) = save[1];\n            }\n         }\n#endif /* WRITE_16BIT */\n      }\n   }\n}\n#endif\n\n#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED\nstatic void\npng_do_write_invert_alpha(png_row_infop row_info, png_bytep row)\n{\n   png_debug(1, \"in png_do_write_invert_alpha\");\n\n   {\n      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\n      {\n         if (row_info->bit_depth == 8)\n         {\n            /* This inverts the alpha channel in RGBA */\n            png_bytep sp, dp;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n\n            for (i = 0, sp = dp = row; i < row_width; i++)\n            {\n               /* Does nothing\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               */\n               sp+=3; dp = sp;\n               *dp = (png_byte)(255 - *(sp++));\n            }\n         }\n\n#ifdef PNG_WRITE_16BIT_SUPPORTED\n         else\n         {\n            /* This inverts the alpha channel in RRGGBBAA */\n            png_bytep sp, dp;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n\n            for (i = 0, sp = dp = row; i < row_width; i++)\n            {\n               /* Does nothing\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               */\n               sp+=6; dp = sp;\n               *(dp++) = (png_byte)(255 - *(sp++));\n               *dp     = (png_byte)(255 - *(sp++));\n            }\n         }\n#endif /* WRITE_16BIT */\n      }\n\n      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n      {\n         if (row_info->bit_depth == 8)\n         {\n            /* This inverts the alpha channel in GA */\n            png_bytep sp, dp;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n\n            for (i = 0, sp = dp = row; i < row_width; i++)\n            {\n               *(dp++) = *(sp++);\n               *(dp++) = (png_byte)(255 - *(sp++));\n            }\n         }\n\n#ifdef PNG_WRITE_16BIT_SUPPORTED\n         else\n         {\n            /* This inverts the alpha channel in GGAA */\n            png_bytep sp, dp;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n\n            for (i = 0, sp = dp = row; i < row_width; i++)\n            {\n               /* Does nothing\n               *(dp++) = *(sp++);\n               *(dp++) = *(sp++);\n               */\n               sp+=2; dp = sp;\n               *(dp++) = (png_byte)(255 - *(sp++));\n               *dp     = (png_byte)(255 - *(sp++));\n            }\n         }\n#endif /* WRITE_16BIT */\n      }\n   }\n}\n#endif\n\n/* Transform the data according to the user's wishes.  The order of\n * transformations is significant.\n */\nvoid /* PRIVATE */\npng_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)\n{\n   png_debug(1, \"in png_do_write_transformations\");\n\n   if (png_ptr == NULL)\n      return;\n\n#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED\n   if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)\n      if (png_ptr->write_user_transform_fn != NULL)\n         (*(png_ptr->write_user_transform_fn)) /* User write transform\n                                                 function */\n             (png_ptr,  /* png_ptr */\n             row_info,  /* row_info: */\n                /*  png_uint_32 width;       width of row */\n                /*  png_size_t rowbytes;     number of bytes in row */\n                /*  png_byte color_type;     color type of pixels */\n                /*  png_byte bit_depth;      bit depth of samples */\n                /*  png_byte channels;       number of channels (1-4) */\n                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */\n             png_ptr->row_buf + 1);      /* start of pixel data for row */\n#endif\n\n#ifdef PNG_WRITE_FILLER_SUPPORTED\n   if ((png_ptr->transformations & PNG_FILLER) != 0)\n      png_do_strip_channel(row_info, png_ptr->row_buf + 1,\n         !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));\n#endif\n\n#ifdef PNG_WRITE_PACKSWAP_SUPPORTED\n   if ((png_ptr->transformations & PNG_PACKSWAP) != 0)\n      png_do_packswap(row_info, png_ptr->row_buf + 1);\n#endif\n\n#ifdef PNG_WRITE_PACK_SUPPORTED\n   if ((png_ptr->transformations & PNG_PACK) != 0)\n      png_do_pack(row_info, png_ptr->row_buf + 1,\n          (png_uint_32)png_ptr->bit_depth);\n#endif\n\n#ifdef PNG_WRITE_SWAP_SUPPORTED\n#  ifdef PNG_16BIT_SUPPORTED\n   if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)\n      png_do_swap(row_info, png_ptr->row_buf + 1);\n#  endif\n#endif\n\n#ifdef PNG_WRITE_SHIFT_SUPPORTED\n   if ((png_ptr->transformations & PNG_SHIFT) != 0)\n      png_do_shift(row_info, png_ptr->row_buf + 1,\n          &(png_ptr->shift));\n#endif\n\n#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED\n   if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)\n      png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);\n#endif\n\n#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED\n   if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)\n      png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);\n#endif\n\n#ifdef PNG_WRITE_BGR_SUPPORTED\n   if ((png_ptr->transformations & PNG_BGR) != 0)\n      png_do_bgr(row_info, png_ptr->row_buf + 1);\n#endif\n\n#ifdef PNG_WRITE_INVERT_SUPPORTED\n   if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)\n      png_do_invert(row_info, png_ptr->row_buf + 1);\n#endif\n}\n#endif /* WRITE_TRANSFORMS */\n#endif /* WRITE */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/pngwutil.c",
    "content": "\n/* pngwutil.c - utilities to write a PNG file\n *\n * Last changed in libpng 1.6.21 [(PENDING RELEASE)]\n * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson\n * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\n * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n#include \"pngpriv.h\"\n\n#ifdef PNG_WRITE_SUPPORTED\n\n#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED\n/* Place a 32-bit number into a buffer in PNG byte order.  We work\n * with unsigned numbers for convenience, although one supported\n * ancillary chunk uses signed (two's complement) numbers.\n */\nvoid PNGAPI\npng_save_uint_32(png_bytep buf, png_uint_32 i)\n{\n   buf[0] = (png_byte)((i >> 24) & 0xffU);\n   buf[1] = (png_byte)((i >> 16) & 0xffU);\n   buf[2] = (png_byte)((i >>  8) & 0xffU);\n   buf[3] = (png_byte)( i        & 0xffU);\n}\n\n/* Place a 16-bit number into a buffer in PNG byte order.\n * The parameter is declared unsigned int, not png_uint_16,\n * just to avoid potential problems on pre-ANSI C compilers.\n */\nvoid PNGAPI\npng_save_uint_16(png_bytep buf, unsigned int i)\n{\n   buf[0] = (png_byte)((i >> 8) & 0xffU);\n   buf[1] = (png_byte)( i       & 0xffU);\n}\n#endif\n\n/* Simple function to write the signature.  If we have already written\n * the magic bytes of the signature, or more likely, the PNG stream is\n * being embedded into another stream and doesn't need its own signature,\n * we should call png_set_sig_bytes() to tell libpng how many of the\n * bytes have already been written.\n */\nvoid PNGAPI\npng_write_sig(png_structrp png_ptr)\n{\n   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};\n\n#ifdef PNG_IO_STATE_SUPPORTED\n   /* Inform the I/O callback that the signature is being written */\n   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE;\n#endif\n\n   /* Write the rest of the 8 byte signature */\n   png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],\n      (png_size_t)(8 - png_ptr->sig_bytes));\n\n   if (png_ptr->sig_bytes < 3)\n      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;\n}\n\n/* Write the start of a PNG chunk.  The type is the chunk type.\n * The total_length is the sum of the lengths of all the data you will be\n * passing in png_write_chunk_data().\n */\nstatic void\npng_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name,\n    png_uint_32 length)\n{\n   png_byte buf[8];\n\n#if defined(PNG_DEBUG) && (PNG_DEBUG > 0)\n   PNG_CSTRING_FROM_CHUNK(buf, chunk_name);\n   png_debug2(0, \"Writing %s chunk, length = %lu\", buf, (unsigned long)length);\n#endif\n\n   if (png_ptr == NULL)\n      return;\n\n#ifdef PNG_IO_STATE_SUPPORTED\n   /* Inform the I/O callback that the chunk header is being written.\n    * PNG_IO_CHUNK_HDR requires a single I/O call.\n    */\n   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR;\n#endif\n\n   /* Write the length and the chunk name */\n   png_save_uint_32(buf, length);\n   png_save_uint_32(buf + 4, chunk_name);\n   png_write_data(png_ptr, buf, 8);\n\n   /* Put the chunk name into png_ptr->chunk_name */\n   png_ptr->chunk_name = chunk_name;\n\n   /* Reset the crc and run it over the chunk name */\n   png_reset_crc(png_ptr);\n\n   png_calculate_crc(png_ptr, buf + 4, 4);\n\n#ifdef PNG_IO_STATE_SUPPORTED\n   /* Inform the I/O callback that chunk data will (possibly) be written.\n    * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.\n    */\n   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA;\n#endif\n}\n\nvoid PNGAPI\npng_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string,\n    png_uint_32 length)\n{\n   png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length);\n}\n\n/* Write the data of a PNG chunk started with png_write_chunk_header().\n * Note that multiple calls to this function are allowed, and that the\n * sum of the lengths from these calls *must* add up to the total_length\n * given to png_write_chunk_header().\n */\nvoid PNGAPI\npng_write_chunk_data(png_structrp png_ptr, png_const_bytep data,\n    png_size_t length)\n{\n   /* Write the data, and run the CRC over it */\n   if (png_ptr == NULL)\n      return;\n\n   if (data != NULL && length > 0)\n   {\n      png_write_data(png_ptr, data, length);\n\n      /* Update the CRC after writing the data,\n       * in case the user I/O routine alters it.\n       */\n      png_calculate_crc(png_ptr, data, length);\n   }\n}\n\n/* Finish a chunk started with png_write_chunk_header(). */\nvoid PNGAPI\npng_write_chunk_end(png_structrp png_ptr)\n{\n   png_byte buf[4];\n\n   if (png_ptr == NULL) return;\n\n#ifdef PNG_IO_STATE_SUPPORTED\n   /* Inform the I/O callback that the chunk CRC is being written.\n    * PNG_IO_CHUNK_CRC requires a single I/O function call.\n    */\n   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC;\n#endif\n\n   /* Write the crc in a single operation */\n   png_save_uint_32(buf, png_ptr->crc);\n\n   png_write_data(png_ptr, buf, (png_size_t)4);\n}\n\n/* Write a PNG chunk all at once.  The type is an array of ASCII characters\n * representing the chunk name.  The array must be at least 4 bytes in\n * length, and does not need to be null terminated.  To be safe, pass the\n * pre-defined chunk names here, and if you need a new one, define it\n * where the others are defined.  The length is the length of the data.\n * All the data must be present.  If that is not possible, use the\n * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()\n * functions instead.\n */\nstatic void\npng_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,\n   png_const_bytep data, png_size_t length)\n{\n   if (png_ptr == NULL)\n      return;\n\n   /* On 64-bit architectures 'length' may not fit in a png_uint_32. */\n   if (length > PNG_UINT_31_MAX)\n      png_error(png_ptr, \"length exceeds PNG maximum\");\n\n   png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length);\n   png_write_chunk_data(png_ptr, data, length);\n   png_write_chunk_end(png_ptr);\n}\n\n/* This is the API that calls the internal function above. */\nvoid PNGAPI\npng_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string,\n   png_const_bytep data, png_size_t length)\n{\n   png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,\n      length);\n}\n\n/* This is used below to find the size of an image to pass to png_deflate_claim,\n * so it only needs to be accurate if the size is less than 16384 bytes (the\n * point at which a lower LZ window size can be used.)\n */\nstatic png_alloc_size_t\npng_image_size(png_structrp png_ptr)\n{\n   /* Only return sizes up to the maximum of a png_uint_32; do this by limiting\n    * the width and height used to 15 bits.\n    */\n   png_uint_32 h = png_ptr->height;\n\n   if (png_ptr->rowbytes < 32768 && h < 32768)\n   {\n      if (png_ptr->interlaced != 0)\n      {\n         /* Interlacing makes the image larger because of the replication of\n          * both the filter byte and the padding to a byte boundary.\n          */\n         png_uint_32 w = png_ptr->width;\n         unsigned int pd = png_ptr->pixel_depth;\n         png_alloc_size_t cb_base;\n         int pass;\n\n         for (cb_base=0, pass=0; pass<=6; ++pass)\n         {\n            png_uint_32 pw = PNG_PASS_COLS(w, pass);\n\n            if (pw > 0)\n               cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass);\n         }\n\n         return cb_base;\n      }\n\n      else\n         return (png_ptr->rowbytes+1) * h;\n   }\n\n   else\n      return 0xffffffffU;\n}\n\n#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED\n   /* This is the code to hack the first two bytes of the deflate stream (the\n    * deflate header) to correct the windowBits value to match the actual data\n    * size.  Note that the second argument is the *uncompressed* size but the\n    * first argument is the *compressed* data (and it must be deflate\n    * compressed.)\n    */\nstatic void\noptimize_cmf(png_bytep data, png_alloc_size_t data_size)\n{\n   /* Optimize the CMF field in the zlib stream.  The resultant zlib stream is\n    * still compliant to the stream specification.\n    */\n   if (data_size <= 16384) /* else windowBits must be 15 */\n   {\n      unsigned int z_cmf = data[0];  /* zlib compression method and flags */\n\n      if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)\n      {\n         unsigned int z_cinfo;\n         unsigned int half_z_window_size;\n\n         z_cinfo = z_cmf >> 4;\n         half_z_window_size = 1U << (z_cinfo + 7);\n\n         if (data_size <= half_z_window_size) /* else no change */\n         {\n            unsigned int tmp;\n\n            do\n            {\n               half_z_window_size >>= 1;\n               --z_cinfo;\n            }\n            while (z_cinfo > 0 && data_size <= half_z_window_size);\n\n            z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);\n\n            data[0] = (png_byte)z_cmf;\n            tmp = data[1] & 0xe0;\n            tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;\n            data[1] = (png_byte)tmp;\n         }\n      }\n   }\n}\n#endif /* WRITE_OPTIMIZE_CMF */\n\n/* Initialize the compressor for the appropriate type of compression. */\nstatic int\npng_deflate_claim(png_structrp png_ptr, png_uint_32 owner,\n   png_alloc_size_t data_size)\n{\n   if (png_ptr->zowner != 0)\n   {\n#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)\n      char msg[64];\n\n      PNG_STRING_FROM_CHUNK(msg, owner);\n      msg[4] = ':';\n      msg[5] = ' ';\n      PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner);\n      /* So the message that results is \"<chunk> using zstream\"; this is an\n       * internal error, but is very useful for debugging.  i18n requirements\n       * are minimal.\n       */\n      (void)png_safecat(msg, (sizeof msg), 10, \" using zstream\");\n#endif\n#if PNG_RELEASE_BUILD\n         png_warning(png_ptr, msg);\n\n         /* Attempt sane error recovery */\n         if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */\n         {\n            png_ptr->zstream.msg = PNGZ_MSG_CAST(\"in use by IDAT\");\n            return Z_STREAM_ERROR;\n         }\n\n         png_ptr->zowner = 0;\n#else\n         png_error(png_ptr, msg);\n#endif\n   }\n\n   {\n      int level = png_ptr->zlib_level;\n      int method = png_ptr->zlib_method;\n      int windowBits = png_ptr->zlib_window_bits;\n      int memLevel = png_ptr->zlib_mem_level;\n      int strategy; /* set below */\n      int ret; /* zlib return code */\n\n      if (owner == png_IDAT)\n      {\n         if ((png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) != 0)\n            strategy = png_ptr->zlib_strategy;\n\n         else if (png_ptr->do_filter != PNG_FILTER_NONE)\n            strategy = PNG_Z_DEFAULT_STRATEGY;\n\n         else\n            strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY;\n      }\n\n      else\n      {\n#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED\n            level = png_ptr->zlib_text_level;\n            method = png_ptr->zlib_text_method;\n            windowBits = png_ptr->zlib_text_window_bits;\n            memLevel = png_ptr->zlib_text_mem_level;\n            strategy = png_ptr->zlib_text_strategy;\n#else\n            /* If customization is not supported the values all come from the\n             * IDAT values except for the strategy, which is fixed to the\n             * default.  (This is the pre-1.6.0 behavior too, although it was\n             * implemented in a very different way.)\n             */\n            strategy = Z_DEFAULT_STRATEGY;\n#endif\n      }\n\n      /* Adjust 'windowBits' down if larger than 'data_size'; to stop this\n       * happening just pass 32768 as the data_size parameter.  Notice that zlib\n       * requires an extra 262 bytes in the window in addition to the data to be\n       * able to see the whole of the data, so if data_size+262 takes us to the\n       * next windowBits size we need to fix up the value later.  (Because even\n       * though deflate needs the extra window, inflate does not!)\n       */\n      if (data_size <= 16384)\n      {\n         /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to\n          * work round a Microsoft Visual C misbehavior which, contrary to C-90,\n          * widens the result of the following shift to 64-bits if (and,\n          * apparently, only if) it is used in a test.\n          */\n         unsigned int half_window_size = 1U << (windowBits-1);\n\n         while (data_size + 262 <= half_window_size)\n         {\n            half_window_size >>= 1;\n            --windowBits;\n         }\n      }\n\n      /* Check against the previous initialized values, if any. */\n      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0 &&\n         (png_ptr->zlib_set_level != level ||\n         png_ptr->zlib_set_method != method ||\n         png_ptr->zlib_set_window_bits != windowBits ||\n         png_ptr->zlib_set_mem_level != memLevel ||\n         png_ptr->zlib_set_strategy != strategy))\n      {\n         if (deflateEnd(&png_ptr->zstream) != Z_OK)\n            png_warning(png_ptr, \"deflateEnd failed (ignored)\");\n\n         png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED;\n      }\n\n      /* For safety clear out the input and output pointers (currently zlib\n       * doesn't use them on Init, but it might in the future).\n       */\n      png_ptr->zstream.next_in = NULL;\n      png_ptr->zstream.avail_in = 0;\n      png_ptr->zstream.next_out = NULL;\n      png_ptr->zstream.avail_out = 0;\n\n      /* Now initialize if required, setting the new parameters, otherwise just\n       * to a simple reset to the previous parameters.\n       */\n      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)\n         ret = deflateReset(&png_ptr->zstream);\n\n      else\n      {\n         ret = deflateInit2(&png_ptr->zstream, level, method, windowBits,\n            memLevel, strategy);\n\n         if (ret == Z_OK)\n            png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;\n      }\n\n      /* The return code is from either deflateReset or deflateInit2; they have\n       * pretty much the same set of error codes.\n       */\n      if (ret == Z_OK)\n         png_ptr->zowner = owner;\n\n      else\n         png_zstream_error(png_ptr, ret);\n\n      return ret;\n   }\n}\n\n/* Clean up (or trim) a linked list of compression buffers. */\nvoid /* PRIVATE */\npng_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp)\n{\n   png_compression_bufferp list = *listp;\n\n   if (list != NULL)\n   {\n      *listp = NULL;\n\n      do\n      {\n         png_compression_bufferp next = list->next;\n\n         png_free(png_ptr, list);\n         list = next;\n      }\n      while (list != NULL);\n   }\n}\n\n#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED\n/* This pair of functions encapsulates the operation of (a) compressing a\n * text string, and (b) issuing it later as a series of chunk data writes.\n * The compression_state structure is shared context for these functions\n * set up by the caller to allow access to the relevant local variables.\n *\n * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size\n * temporary buffers.  From 1.6.0 it is retained in png_struct so that it will\n * be correctly freed in the event of a write error (previous implementations\n * just leaked memory.)\n */\ntypedef struct\n{\n   png_const_bytep      input;        /* The uncompressed input data */\n   png_alloc_size_t     input_len;    /* Its length */\n   png_uint_32          output_len;   /* Final compressed length */\n   png_byte             output[1024]; /* First block of output */\n} compression_state;\n\nstatic void\npng_text_compress_init(compression_state *comp, png_const_bytep input,\n   png_alloc_size_t input_len)\n{\n   comp->input = input;\n   comp->input_len = input_len;\n   comp->output_len = 0;\n}\n\n/* Compress the data in the compression state input */\nstatic int\npng_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,\n   compression_state *comp, png_uint_32 prefix_len)\n{\n   int ret;\n\n   /* To find the length of the output it is necessary to first compress the\n    * input. The result is buffered rather than using the two-pass algorithm\n    * that is used on the inflate side; deflate is assumed to be slower and a\n    * PNG writer is assumed to have more memory available than a PNG reader.\n    *\n    * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an\n    * upper limit on the output size, but it is always bigger than the input\n    * size so it is likely to be more efficient to use this linked-list\n    * approach.\n    */\n   ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len);\n\n   if (ret != Z_OK)\n      return ret;\n\n   /* Set up the compression buffers, we need a loop here to avoid overflowing a\n    * uInt.  Use ZLIB_IO_MAX to limit the input.  The output is always limited\n    * by the output buffer size, so there is no need to check that.  Since this\n    * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits\n    * in size.\n    */\n   {\n      png_compression_bufferp *end = &png_ptr->zbuffer_list;\n      png_alloc_size_t input_len = comp->input_len; /* may be zero! */\n      png_uint_32 output_len;\n\n      /* zlib updates these for us: */\n      png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input);\n      png_ptr->zstream.avail_in = 0; /* Set below */\n      png_ptr->zstream.next_out = comp->output;\n      png_ptr->zstream.avail_out = (sizeof comp->output);\n\n      output_len = png_ptr->zstream.avail_out;\n\n      do\n      {\n         uInt avail_in = ZLIB_IO_MAX;\n\n         if (avail_in > input_len)\n            avail_in = (uInt)input_len;\n\n         input_len -= avail_in;\n\n         png_ptr->zstream.avail_in = avail_in;\n\n         if (png_ptr->zstream.avail_out == 0)\n         {\n            png_compression_buffer *next;\n\n            /* Chunk data is limited to 2^31 bytes in length, so the prefix\n             * length must be counted here.\n             */\n            if (output_len + prefix_len > PNG_UINT_31_MAX)\n            {\n               ret = Z_MEM_ERROR;\n               break;\n            }\n\n            /* Need a new (malloc'ed) buffer, but there may be one present\n             * already.\n             */\n            next = *end;\n            if (next == NULL)\n            {\n               next = png_voidcast(png_compression_bufferp, png_malloc_base\n                  (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));\n\n               if (next == NULL)\n               {\n                  ret = Z_MEM_ERROR;\n                  break;\n               }\n\n               /* Link in this buffer (so that it will be freed later) */\n               next->next = NULL;\n               *end = next;\n            }\n\n            png_ptr->zstream.next_out = next->output;\n            png_ptr->zstream.avail_out = png_ptr->zbuffer_size;\n            output_len += png_ptr->zstream.avail_out;\n\n            /* Move 'end' to the next buffer pointer. */\n            end = &next->next;\n         }\n\n         /* Compress the data */\n         ret = deflate(&png_ptr->zstream,\n            input_len > 0 ? Z_NO_FLUSH : Z_FINISH);\n\n         /* Claw back input data that was not consumed (because avail_in is\n          * reset above every time round the loop).\n          */\n         input_len += png_ptr->zstream.avail_in;\n         png_ptr->zstream.avail_in = 0; /* safety */\n      }\n      while (ret == Z_OK);\n\n      /* There may be some space left in the last output buffer. This needs to\n       * be subtracted from output_len.\n       */\n      output_len -= png_ptr->zstream.avail_out;\n      png_ptr->zstream.avail_out = 0; /* safety */\n      comp->output_len = output_len;\n\n      /* Now double check the output length, put in a custom message if it is\n       * too long.  Otherwise ensure the z_stream::msg pointer is set to\n       * something.\n       */\n      if (output_len + prefix_len >= PNG_UINT_31_MAX)\n      {\n         png_ptr->zstream.msg = PNGZ_MSG_CAST(\"compressed data too long\");\n         ret = Z_MEM_ERROR;\n      }\n\n      else\n         png_zstream_error(png_ptr, ret);\n\n      /* Reset zlib for another zTXt/iTXt or image data */\n      png_ptr->zowner = 0;\n\n      /* The only success case is Z_STREAM_END, input_len must be 0; if not this\n       * is an internal error.\n       */\n      if (ret == Z_STREAM_END && input_len == 0)\n      {\n#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED\n         /* Fix up the deflate header, if required */\n         optimize_cmf(comp->output, comp->input_len);\n#endif\n         /* But Z_OK is returned, not Z_STREAM_END; this allows the claim\n          * function above to return Z_STREAM_END on an error (though it never\n          * does in the current versions of zlib.)\n          */\n         return Z_OK;\n      }\n\n      else\n         return ret;\n   }\n}\n\n/* Ship the compressed text out via chunk writes */\nstatic void\npng_write_compressed_data_out(png_structrp png_ptr, compression_state *comp)\n{\n   png_uint_32 output_len = comp->output_len;\n   png_const_bytep output = comp->output;\n   png_uint_32 avail = (sizeof comp->output);\n   png_compression_buffer *next = png_ptr->zbuffer_list;\n\n   for (;;)\n   {\n      if (avail > output_len)\n         avail = output_len;\n\n      png_write_chunk_data(png_ptr, output, avail);\n\n      output_len -= avail;\n\n      if (output_len == 0 || next == NULL)\n         break;\n\n      avail = png_ptr->zbuffer_size;\n      output = next->output;\n      next = next->next;\n   }\n\n   /* This is an internal error; 'next' must have been NULL! */\n   if (output_len > 0)\n      png_error(png_ptr, \"error writing ancillary chunked compressed data\");\n}\n#endif /* WRITE_COMPRESSED_TEXT */\n\n/* Write the IHDR chunk, and update the png_struct with the necessary\n * information.  Note that the rest of this code depends upon this\n * information being correct.\n */\nvoid /* PRIVATE */\npng_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,\n    int bit_depth, int color_type, int compression_type, int filter_type,\n    int interlace_type)\n{\n   png_byte buf[13]; /* Buffer to store the IHDR info */\n\n   png_debug(1, \"in png_write_IHDR\");\n\n   /* Check that we have valid input data from the application info */\n   switch (color_type)\n   {\n      case PNG_COLOR_TYPE_GRAY:\n         switch (bit_depth)\n         {\n            case 1:\n            case 2:\n            case 4:\n            case 8:\n#ifdef PNG_WRITE_16BIT_SUPPORTED\n            case 16:\n#endif\n               png_ptr->channels = 1; break;\n\n            default:\n               png_error(png_ptr,\n                   \"Invalid bit depth for grayscale image\");\n         }\n         break;\n\n      case PNG_COLOR_TYPE_RGB:\n#ifdef PNG_WRITE_16BIT_SUPPORTED\n         if (bit_depth != 8 && bit_depth != 16)\n#else\n         if (bit_depth != 8)\n#endif\n            png_error(png_ptr, \"Invalid bit depth for RGB image\");\n\n         png_ptr->channels = 3;\n         break;\n\n      case PNG_COLOR_TYPE_PALETTE:\n         switch (bit_depth)\n         {\n            case 1:\n            case 2:\n            case 4:\n            case 8:\n               png_ptr->channels = 1;\n               break;\n\n            default:\n               png_error(png_ptr, \"Invalid bit depth for paletted image\");\n         }\n         break;\n\n      case PNG_COLOR_TYPE_GRAY_ALPHA:\n         if (bit_depth != 8 && bit_depth != 16)\n            png_error(png_ptr, \"Invalid bit depth for grayscale+alpha image\");\n\n         png_ptr->channels = 2;\n         break;\n\n      case PNG_COLOR_TYPE_RGB_ALPHA:\n#ifdef PNG_WRITE_16BIT_SUPPORTED\n         if (bit_depth != 8 && bit_depth != 16)\n#else\n         if (bit_depth != 8)\n#endif\n            png_error(png_ptr, \"Invalid bit depth for RGBA image\");\n\n         png_ptr->channels = 4;\n         break;\n\n      default:\n         png_error(png_ptr, \"Invalid image color type specified\");\n   }\n\n   if (compression_type != PNG_COMPRESSION_TYPE_BASE)\n   {\n      png_warning(png_ptr, \"Invalid compression type specified\");\n      compression_type = PNG_COMPRESSION_TYPE_BASE;\n   }\n\n   /* Write filter_method 64 (intrapixel differencing) only if\n    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and\n    * 2. Libpng did not write a PNG signature (this filter_method is only\n    *    used in PNG datastreams that are embedded in MNG datastreams) and\n    * 3. The application called png_permit_mng_features with a mask that\n    *    included PNG_FLAG_MNG_FILTER_64 and\n    * 4. The filter_method is 64 and\n    * 5. The color_type is RGB or RGBA\n    */\n   if (\n#ifdef PNG_MNG_FEATURES_SUPPORTED\n       !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&\n       ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&\n       (color_type == PNG_COLOR_TYPE_RGB ||\n        color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&\n       (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&\n#endif\n       filter_type != PNG_FILTER_TYPE_BASE)\n   {\n      png_warning(png_ptr, \"Invalid filter type specified\");\n      filter_type = PNG_FILTER_TYPE_BASE;\n   }\n\n#ifdef PNG_WRITE_INTERLACING_SUPPORTED\n   if (interlace_type != PNG_INTERLACE_NONE &&\n       interlace_type != PNG_INTERLACE_ADAM7)\n   {\n      png_warning(png_ptr, \"Invalid interlace type specified\");\n      interlace_type = PNG_INTERLACE_ADAM7;\n   }\n#else\n   interlace_type=PNG_INTERLACE_NONE;\n#endif\n\n   /* Save the relevant information */\n   png_ptr->bit_depth = (png_byte)bit_depth;\n   png_ptr->color_type = (png_byte)color_type;\n   png_ptr->interlaced = (png_byte)interlace_type;\n#ifdef PNG_MNG_FEATURES_SUPPORTED\n   png_ptr->filter_type = (png_byte)filter_type;\n#endif\n   png_ptr->compression_type = (png_byte)compression_type;\n   png_ptr->width = width;\n   png_ptr->height = height;\n\n   png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);\n   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);\n   /* Set the usr info, so any transformations can modify it */\n   png_ptr->usr_width = png_ptr->width;\n   png_ptr->usr_bit_depth = png_ptr->bit_depth;\n   png_ptr->usr_channels = png_ptr->channels;\n\n   /* Pack the header information into the buffer */\n   png_save_uint_32(buf, width);\n   png_save_uint_32(buf + 4, height);\n   buf[8] = (png_byte)bit_depth;\n   buf[9] = (png_byte)color_type;\n   buf[10] = (png_byte)compression_type;\n   buf[11] = (png_byte)filter_type;\n   buf[12] = (png_byte)interlace_type;\n\n   /* Write the chunk */\n   png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);\n\n   if ((png_ptr->do_filter) == PNG_NO_FILTERS)\n   {\n      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||\n          png_ptr->bit_depth < 8)\n         png_ptr->do_filter = PNG_FILTER_NONE;\n\n      else\n         png_ptr->do_filter = PNG_ALL_FILTERS;\n   }\n\n   png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */\n}\n\n/* Write the palette.  We are careful not to trust png_color to be in the\n * correct order for PNG, so people can redefine it to any convenient\n * structure.\n */\nvoid /* PRIVATE */\npng_write_PLTE(png_structrp png_ptr, png_const_colorp palette,\n    png_uint_32 num_pal)\n{\n   png_uint_32 max_palette_length, i;\n   png_const_colorp pal_ptr;\n   png_byte buf[3];\n\n   png_debug(1, \"in png_write_PLTE\");\n\n   max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?\n      (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;\n\n   if ((\n#ifdef PNG_MNG_FEATURES_SUPPORTED\n       (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 &&\n#endif\n       num_pal == 0) || num_pal > max_palette_length)\n   {\n      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\n      {\n         png_error(png_ptr, \"Invalid number of colors in palette\");\n      }\n\n      else\n      {\n         png_warning(png_ptr, \"Invalid number of colors in palette\");\n         return;\n      }\n   }\n\n   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)\n   {\n      png_warning(png_ptr,\n          \"Ignoring request to write a PLTE chunk in grayscale PNG\");\n\n      return;\n   }\n\n   png_ptr->num_palette = (png_uint_16)num_pal;\n   png_debug1(3, \"num_palette = %d\", png_ptr->num_palette);\n\n   png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3));\n#ifdef PNG_POINTER_INDEXING_SUPPORTED\n\n   for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)\n   {\n      buf[0] = pal_ptr->red;\n      buf[1] = pal_ptr->green;\n      buf[2] = pal_ptr->blue;\n      png_write_chunk_data(png_ptr, buf, (png_size_t)3);\n   }\n\n#else\n   /* This is a little slower but some buggy compilers need to do this\n    * instead\n    */\n   pal_ptr=palette;\n\n   for (i = 0; i < num_pal; i++)\n   {\n      buf[0] = pal_ptr[i].red;\n      buf[1] = pal_ptr[i].green;\n      buf[2] = pal_ptr[i].blue;\n      png_write_chunk_data(png_ptr, buf, (png_size_t)3);\n   }\n\n#endif\n   png_write_chunk_end(png_ptr);\n   png_ptr->mode |= PNG_HAVE_PLTE;\n}\n\n/* This is similar to png_text_compress, above, except that it does not require\n * all of the data at once and, instead of buffering the compressed result,\n * writes it as IDAT chunks.  Unlike png_text_compress it *can* png_error out\n * because it calls the write interface.  As a result it does its own error\n * reporting and does not return an error code.  In the event of error it will\n * just call png_error.  The input data length may exceed 32-bits.  The 'flush'\n * parameter is exactly the same as that to deflate, with the following\n * meanings:\n *\n * Z_NO_FLUSH: normal incremental output of compressed data\n * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush\n * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up\n *\n * The routine manages the acquire and release of the png_ptr->zstream by\n * checking and (at the end) clearing png_ptr->zowner; it does some sanity\n * checks on the 'mode' flags while doing this.\n */\nvoid /* PRIVATE */\npng_compress_IDAT(png_structrp png_ptr, png_const_bytep input,\n   png_alloc_size_t input_len, int flush)\n{\n   if (png_ptr->zowner != png_IDAT)\n   {\n      /* First time.   Ensure we have a temporary buffer for compression and\n       * trim the buffer list if it has more than one entry to free memory.\n       * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been\n       * created at this point, but the check here is quick and safe.\n       */\n      if (png_ptr->zbuffer_list == NULL)\n      {\n         png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp,\n            png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));\n         png_ptr->zbuffer_list->next = NULL;\n      }\n\n      else\n         png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next);\n\n      /* It is a terminal error if we can't claim the zstream. */\n      if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK)\n         png_error(png_ptr, png_ptr->zstream.msg);\n\n      /* The output state is maintained in png_ptr->zstream, so it must be\n       * initialized here after the claim.\n       */\n      png_ptr->zstream.next_out = png_ptr->zbuffer_list->output;\n      png_ptr->zstream.avail_out = png_ptr->zbuffer_size;\n   }\n\n   /* Now loop reading and writing until all the input is consumed or an error\n    * terminates the operation.  The _out values are maintained across calls to\n    * this function, but the input must be reset each time.\n    */\n   png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input);\n   png_ptr->zstream.avail_in = 0; /* set below */\n   for (;;)\n   {\n      int ret;\n\n      /* INPUT: from the row data */\n      uInt avail = ZLIB_IO_MAX;\n\n      if (avail > input_len)\n         avail = (uInt)input_len; /* safe because of the check */\n\n      png_ptr->zstream.avail_in = avail;\n      input_len -= avail;\n\n      ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush);\n\n      /* Include as-yet unconsumed input */\n      input_len += png_ptr->zstream.avail_in;\n      png_ptr->zstream.avail_in = 0;\n\n      /* OUTPUT: write complete IDAT chunks when avail_out drops to zero. Note\n       * that these two zstream fields are preserved across the calls, therefore\n       * there is no need to set these up on entry to the loop.\n       */\n      if (png_ptr->zstream.avail_out == 0)\n      {\n         png_bytep data = png_ptr->zbuffer_list->output;\n         uInt size = png_ptr->zbuffer_size;\n\n         /* Write an IDAT containing the data then reset the buffer.  The\n          * first IDAT may need deflate header optimization.\n          */\n#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED\n            if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 &&\n                png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)\n               optimize_cmf(data, png_image_size(png_ptr));\n#endif\n\n         png_write_complete_chunk(png_ptr, png_IDAT, data, size);\n         png_ptr->mode |= PNG_HAVE_IDAT;\n\n         png_ptr->zstream.next_out = data;\n         png_ptr->zstream.avail_out = size;\n\n         /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with\n          * the same flush parameter until it has finished output, for NO_FLUSH\n          * it doesn't matter.\n          */\n         if (ret == Z_OK && flush != Z_NO_FLUSH)\n            continue;\n      }\n\n      /* The order of these checks doesn't matter much; it just affects which\n       * possible error might be detected if multiple things go wrong at once.\n       */\n      if (ret == Z_OK) /* most likely return code! */\n      {\n         /* If all the input has been consumed then just return.  If Z_FINISH\n          * was used as the flush parameter something has gone wrong if we get\n          * here.\n          */\n         if (input_len == 0)\n         {\n            if (flush == Z_FINISH)\n               png_error(png_ptr, \"Z_OK on Z_FINISH with output space\");\n\n            return;\n         }\n      }\n\n      else if (ret == Z_STREAM_END && flush == Z_FINISH)\n      {\n         /* This is the end of the IDAT data; any pending output must be\n          * flushed.  For small PNG files we may still be at the beginning.\n          */\n         png_bytep data = png_ptr->zbuffer_list->output;\n         uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out;\n\n#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED\n         if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 &&\n             png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)\n            optimize_cmf(data, png_image_size(png_ptr));\n#endif\n\n         png_write_complete_chunk(png_ptr, png_IDAT, data, size);\n         png_ptr->zstream.avail_out = 0;\n         png_ptr->zstream.next_out = NULL;\n         png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;\n\n         png_ptr->zowner = 0; /* Release the stream */\n         return;\n      }\n\n      else\n      {\n         /* This is an error condition. */\n         png_zstream_error(png_ptr, ret);\n         png_error(png_ptr, png_ptr->zstream.msg);\n      }\n   }\n}\n\n/* Write an IEND chunk */\nvoid /* PRIVATE */\npng_write_IEND(png_structrp png_ptr)\n{\n   png_debug(1, \"in png_write_IEND\");\n\n   png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);\n   png_ptr->mode |= PNG_HAVE_IEND;\n}\n\n#ifdef PNG_WRITE_gAMA_SUPPORTED\n/* Write a gAMA chunk */\nvoid /* PRIVATE */\npng_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma)\n{\n   png_byte buf[4];\n\n   png_debug(1, \"in png_write_gAMA\");\n\n   /* file_gamma is saved in 1/100,000ths */\n   png_save_uint_32(buf, (png_uint_32)file_gamma);\n   png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);\n}\n#endif\n\n#ifdef PNG_WRITE_sRGB_SUPPORTED\n/* Write a sRGB chunk */\nvoid /* PRIVATE */\npng_write_sRGB(png_structrp png_ptr, int srgb_intent)\n{\n   png_byte buf[1];\n\n   png_debug(1, \"in png_write_sRGB\");\n\n   if (srgb_intent >= PNG_sRGB_INTENT_LAST)\n      png_warning(png_ptr,\n          \"Invalid sRGB rendering intent specified\");\n\n   buf[0]=(png_byte)srgb_intent;\n   png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);\n}\n#endif\n\n#ifdef PNG_WRITE_iCCP_SUPPORTED\n/* Write an iCCP chunk */\nvoid /* PRIVATE */\npng_write_iCCP(png_structrp png_ptr, png_const_charp name,\n    png_const_bytep profile)\n{\n   png_uint_32 name_len;\n   png_uint_32 profile_len;\n   png_byte new_name[81]; /* 1 byte for the compression byte */\n   compression_state comp;\n   png_uint_32 temp;\n\n   png_debug(1, \"in png_write_iCCP\");\n\n   /* These are all internal problems: the profile should have been checked\n    * before when it was stored.\n    */\n   if (profile == NULL)\n      png_error(png_ptr, \"No profile for iCCP chunk\"); /* internal error */\n\n   profile_len = png_get_uint_32(profile);\n\n   if (profile_len < 132)\n      png_error(png_ptr, \"ICC profile too short\");\n\n   temp = (png_uint_32) (*(profile+8));\n   if (temp > 3 && (profile_len & 0x03))\n      png_error(png_ptr, \"ICC profile length invalid (not a multiple of 4)\");\n\n   {\n      png_uint_32 embedded_profile_len = png_get_uint_32(profile);\n\n      if (profile_len != embedded_profile_len)\n         png_error(png_ptr, \"Profile length does not match profile\");\n   }\n\n   name_len = png_check_keyword(png_ptr, name, new_name);\n\n   if (name_len == 0)\n      png_error(png_ptr, \"iCCP: invalid keyword\");\n\n   new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE;\n\n   /* Make sure we include the NULL after the name and the compression type */\n   ++name_len;\n\n   png_text_compress_init(&comp, profile, profile_len);\n\n   /* Allow for keyword terminator and compression byte */\n   if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK)\n      png_error(png_ptr, png_ptr->zstream.msg);\n\n   png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len);\n\n   png_write_chunk_data(png_ptr, new_name, name_len);\n\n   png_write_compressed_data_out(png_ptr, &comp);\n\n   png_write_chunk_end(png_ptr);\n}\n#endif\n\n#ifdef PNG_WRITE_sPLT_SUPPORTED\n/* Write a sPLT chunk */\nvoid /* PRIVATE */\npng_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)\n{\n   png_uint_32 name_len;\n   png_byte new_name[80];\n   png_byte entrybuf[10];\n   png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);\n   png_size_t palette_size = entry_size * spalette->nentries;\n   png_sPLT_entryp ep;\n#ifndef PNG_POINTER_INDEXING_SUPPORTED\n   int i;\n#endif\n\n   png_debug(1, \"in png_write_sPLT\");\n\n   name_len = png_check_keyword(png_ptr, spalette->name, new_name);\n\n   if (name_len == 0)\n      png_error(png_ptr, \"sPLT: invalid keyword\");\n\n   /* Make sure we include the NULL after the name */\n   png_write_chunk_header(png_ptr, png_sPLT,\n       (png_uint_32)(name_len + 2 + palette_size));\n\n   png_write_chunk_data(png_ptr, (png_bytep)new_name,\n       (png_size_t)(name_len + 1));\n\n   png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);\n\n   /* Loop through each palette entry, writing appropriately */\n#ifdef PNG_POINTER_INDEXING_SUPPORTED\n   for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++)\n   {\n      if (spalette->depth == 8)\n      {\n         entrybuf[0] = (png_byte)ep->red;\n         entrybuf[1] = (png_byte)ep->green;\n         entrybuf[2] = (png_byte)ep->blue;\n         entrybuf[3] = (png_byte)ep->alpha;\n         png_save_uint_16(entrybuf + 4, ep->frequency);\n      }\n\n      else\n      {\n         png_save_uint_16(entrybuf + 0, ep->red);\n         png_save_uint_16(entrybuf + 2, ep->green);\n         png_save_uint_16(entrybuf + 4, ep->blue);\n         png_save_uint_16(entrybuf + 6, ep->alpha);\n         png_save_uint_16(entrybuf + 8, ep->frequency);\n      }\n\n      png_write_chunk_data(png_ptr, entrybuf, entry_size);\n   }\n#else\n   ep=spalette->entries;\n   for (i = 0; i>spalette->nentries; i++)\n   {\n      if (spalette->depth == 8)\n      {\n         entrybuf[0] = (png_byte)ep[i].red;\n         entrybuf[1] = (png_byte)ep[i].green;\n         entrybuf[2] = (png_byte)ep[i].blue;\n         entrybuf[3] = (png_byte)ep[i].alpha;\n         png_save_uint_16(entrybuf + 4, ep[i].frequency);\n      }\n\n      else\n      {\n         png_save_uint_16(entrybuf + 0, ep[i].red);\n         png_save_uint_16(entrybuf + 2, ep[i].green);\n         png_save_uint_16(entrybuf + 4, ep[i].blue);\n         png_save_uint_16(entrybuf + 6, ep[i].alpha);\n         png_save_uint_16(entrybuf + 8, ep[i].frequency);\n      }\n\n      png_write_chunk_data(png_ptr, entrybuf, entry_size);\n   }\n#endif\n\n   png_write_chunk_end(png_ptr);\n}\n#endif\n\n#ifdef PNG_WRITE_sBIT_SUPPORTED\n/* Write the sBIT chunk */\nvoid /* PRIVATE */\npng_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)\n{\n   png_byte buf[4];\n   png_size_t size;\n\n   png_debug(1, \"in png_write_sBIT\");\n\n   /* Make sure we don't depend upon the order of PNG_COLOR_8 */\n   if ((color_type & PNG_COLOR_MASK_COLOR) != 0)\n   {\n      png_byte maxbits;\n\n      maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :\n          png_ptr->usr_bit_depth);\n\n      if (sbit->red == 0 || sbit->red > maxbits ||\n          sbit->green == 0 || sbit->green > maxbits ||\n          sbit->blue == 0 || sbit->blue > maxbits)\n      {\n         png_warning(png_ptr, \"Invalid sBIT depth specified\");\n         return;\n      }\n\n      buf[0] = sbit->red;\n      buf[1] = sbit->green;\n      buf[2] = sbit->blue;\n      size = 3;\n   }\n\n   else\n   {\n      if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)\n      {\n         png_warning(png_ptr, \"Invalid sBIT depth specified\");\n         return;\n      }\n\n      buf[0] = sbit->gray;\n      size = 1;\n   }\n\n   if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)\n   {\n      if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)\n      {\n         png_warning(png_ptr, \"Invalid sBIT depth specified\");\n         return;\n      }\n\n      buf[size++] = sbit->alpha;\n   }\n\n   png_write_complete_chunk(png_ptr, png_sBIT, buf, size);\n}\n#endif\n\n#ifdef PNG_WRITE_cHRM_SUPPORTED\n/* Write the cHRM chunk */\nvoid /* PRIVATE */\npng_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy)\n{\n   png_byte buf[32];\n\n   png_debug(1, \"in png_write_cHRM\");\n\n   /* Each value is saved in 1/100,000ths */\n   png_save_int_32(buf,      xy->whitex);\n   png_save_int_32(buf +  4, xy->whitey);\n\n   png_save_int_32(buf +  8, xy->redx);\n   png_save_int_32(buf + 12, xy->redy);\n\n   png_save_int_32(buf + 16, xy->greenx);\n   png_save_int_32(buf + 20, xy->greeny);\n\n   png_save_int_32(buf + 24, xy->bluex);\n   png_save_int_32(buf + 28, xy->bluey);\n\n   png_write_complete_chunk(png_ptr, png_cHRM, buf, 32);\n}\n#endif\n\n#ifdef PNG_WRITE_tRNS_SUPPORTED\n/* Write the tRNS chunk */\nvoid /* PRIVATE */\npng_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,\n    png_const_color_16p tran, int num_trans, int color_type)\n{\n   png_byte buf[6];\n\n   png_debug(1, \"in png_write_tRNS\");\n\n   if (color_type == PNG_COLOR_TYPE_PALETTE)\n   {\n      if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)\n      {\n         png_app_warning(png_ptr,\n             \"Invalid number of transparent colors specified\");\n         return;\n      }\n\n      /* Write the chunk out as it is */\n      png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,\n         (png_size_t)num_trans);\n   }\n\n   else if (color_type == PNG_COLOR_TYPE_GRAY)\n   {\n      /* One 16-bit value */\n      if (tran->gray >= (1 << png_ptr->bit_depth))\n      {\n         png_app_warning(png_ptr,\n             \"Ignoring attempt to write tRNS chunk out-of-range for bit_depth\");\n\n         return;\n      }\n\n      png_save_uint_16(buf, tran->gray);\n      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);\n   }\n\n   else if (color_type == PNG_COLOR_TYPE_RGB)\n   {\n      /* Three 16-bit values */\n      png_save_uint_16(buf, tran->red);\n      png_save_uint_16(buf + 2, tran->green);\n      png_save_uint_16(buf + 4, tran->blue);\n#ifdef PNG_WRITE_16BIT_SUPPORTED\n      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0)\n#else\n      if ((buf[0] | buf[2] | buf[4]) != 0)\n#endif\n      {\n         png_app_warning(png_ptr,\n           \"Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8\");\n         return;\n      }\n\n      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);\n   }\n\n   else\n   {\n      png_app_warning(png_ptr, \"Can't write tRNS with an alpha channel\");\n   }\n}\n#endif\n\n#ifdef PNG_WRITE_bKGD_SUPPORTED\n/* Write the background chunk */\nvoid /* PRIVATE */\npng_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)\n{\n   png_byte buf[6];\n\n   png_debug(1, \"in png_write_bKGD\");\n\n   if (color_type == PNG_COLOR_TYPE_PALETTE)\n   {\n      if (\n#ifdef PNG_MNG_FEATURES_SUPPORTED\n          (png_ptr->num_palette != 0 ||\n          (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0) &&\n#endif\n         back->index >= png_ptr->num_palette)\n      {\n         png_warning(png_ptr, \"Invalid background palette index\");\n         return;\n      }\n\n      buf[0] = back->index;\n      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);\n   }\n\n   else if ((color_type & PNG_COLOR_MASK_COLOR) != 0)\n   {\n      png_save_uint_16(buf, back->red);\n      png_save_uint_16(buf + 2, back->green);\n      png_save_uint_16(buf + 4, back->blue);\n#ifdef PNG_WRITE_16BIT_SUPPORTED\n      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0)\n#else\n      if ((buf[0] | buf[2] | buf[4]) != 0)\n#endif\n      {\n         png_warning(png_ptr,\n             \"Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8\");\n\n         return;\n      }\n\n      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);\n   }\n\n   else\n   {\n      if (back->gray >= (1 << png_ptr->bit_depth))\n      {\n         png_warning(png_ptr,\n             \"Ignoring attempt to write bKGD chunk out-of-range for bit_depth\");\n\n         return;\n      }\n\n      png_save_uint_16(buf, back->gray);\n      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);\n   }\n}\n#endif\n\n#ifdef PNG_WRITE_hIST_SUPPORTED\n/* Write the histogram */\nvoid /* PRIVATE */\npng_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)\n{\n   int i;\n   png_byte buf[3];\n\n   png_debug(1, \"in png_write_hIST\");\n\n   if (num_hist > (int)png_ptr->num_palette)\n   {\n      png_debug2(3, \"num_hist = %d, num_palette = %d\", num_hist,\n          png_ptr->num_palette);\n\n      png_warning(png_ptr, \"Invalid number of histogram entries specified\");\n      return;\n   }\n\n   png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));\n\n   for (i = 0; i < num_hist; i++)\n   {\n      png_save_uint_16(buf, hist[i]);\n      png_write_chunk_data(png_ptr, buf, (png_size_t)2);\n   }\n\n   png_write_chunk_end(png_ptr);\n}\n#endif\n\n#ifdef PNG_WRITE_tEXt_SUPPORTED\n/* Write a tEXt chunk */\nvoid /* PRIVATE */\npng_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,\n    png_size_t text_len)\n{\n   png_uint_32 key_len;\n   png_byte new_key[80];\n\n   png_debug(1, \"in png_write_tEXt\");\n\n   key_len = png_check_keyword(png_ptr, key, new_key);\n\n   if (key_len == 0)\n      png_error(png_ptr, \"tEXt: invalid keyword\");\n\n   if (text == NULL || *text == '\\0')\n      text_len = 0;\n\n   else\n      text_len = strlen(text);\n\n   if (text_len > PNG_UINT_31_MAX - (key_len+1))\n      png_error(png_ptr, \"tEXt: text too long\");\n\n   /* Make sure we include the 0 after the key */\n   png_write_chunk_header(png_ptr, png_tEXt,\n       (png_uint_32)/*checked above*/(key_len + text_len + 1));\n   /*\n    * We leave it to the application to meet PNG-1.0 requirements on the\n    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of\n    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.\n    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.\n    */\n   png_write_chunk_data(png_ptr, new_key, key_len + 1);\n\n   if (text_len != 0)\n      png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len);\n\n   png_write_chunk_end(png_ptr);\n}\n#endif\n\n#ifdef PNG_WRITE_zTXt_SUPPORTED\n/* Write a compressed text chunk */\nvoid /* PRIVATE */\npng_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,\n    int compression)\n{\n   png_uint_32 key_len;\n   png_byte new_key[81];\n   compression_state comp;\n\n   png_debug(1, \"in png_write_zTXt\");\n\n   if (compression == PNG_TEXT_COMPRESSION_NONE)\n   {\n      png_write_tEXt(png_ptr, key, text, 0);\n      return;\n   }\n\n   if (compression != PNG_TEXT_COMPRESSION_zTXt)\n      png_error(png_ptr, \"zTXt: invalid compression type\");\n\n   key_len = png_check_keyword(png_ptr, key, new_key);\n\n   if (key_len == 0)\n      png_error(png_ptr, \"zTXt: invalid keyword\");\n\n   /* Add the compression method and 1 for the keyword separator. */\n   new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;\n   ++key_len;\n\n   /* Compute the compressed data; do it now for the length */\n   png_text_compress_init(&comp, (png_const_bytep)text,\n      text == NULL ? 0 : strlen(text));\n\n   if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK)\n      png_error(png_ptr, png_ptr->zstream.msg);\n\n   /* Write start of chunk */\n   png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len);\n\n   /* Write key */\n   png_write_chunk_data(png_ptr, new_key, key_len);\n\n   /* Write the compressed data */\n   png_write_compressed_data_out(png_ptr, &comp);\n\n   /* Close the chunk */\n   png_write_chunk_end(png_ptr);\n}\n#endif\n\n#ifdef PNG_WRITE_iTXt_SUPPORTED\n/* Write an iTXt chunk */\nvoid /* PRIVATE */\npng_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key,\n    png_const_charp lang, png_const_charp lang_key, png_const_charp text)\n{\n   png_uint_32 key_len, prefix_len;\n   png_size_t lang_len, lang_key_len;\n   png_byte new_key[82];\n   compression_state comp;\n\n   png_debug(1, \"in png_write_iTXt\");\n\n   key_len = png_check_keyword(png_ptr, key, new_key);\n\n   if (key_len == 0)\n      png_error(png_ptr, \"iTXt: invalid keyword\");\n\n   /* Set the compression flag */\n   switch (compression)\n   {\n      case PNG_ITXT_COMPRESSION_NONE:\n      case PNG_TEXT_COMPRESSION_NONE:\n         compression = new_key[++key_len] = 0; /* no compression */\n         break;\n\n      case PNG_TEXT_COMPRESSION_zTXt:\n      case PNG_ITXT_COMPRESSION_zTXt:\n         compression = new_key[++key_len] = 1; /* compressed */\n         break;\n\n      default:\n         png_error(png_ptr, \"iTXt: invalid compression\");\n   }\n\n   new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;\n   ++key_len; /* for the keywod separator */\n\n   /* We leave it to the application to meet PNG-1.0 requirements on the\n    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of\n    * any non-Latin-1 characters except for NEWLINE.  ISO PNG, however,\n    * specifies that the text is UTF-8 and this really doesn't require any\n    * checking.\n    *\n    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.\n    *\n    * TODO: validate the language tag correctly (see the spec.)\n    */\n   if (lang == NULL) lang = \"\"; /* empty language is valid */\n   lang_len = strlen(lang)+1;\n   if (lang_key == NULL) lang_key = \"\"; /* may be empty */\n   lang_key_len = strlen(lang_key)+1;\n   if (text == NULL) text = \"\"; /* may be empty */\n\n   prefix_len = key_len;\n   if (lang_len > PNG_UINT_31_MAX-prefix_len)\n      prefix_len = PNG_UINT_31_MAX;\n   else\n      prefix_len = (png_uint_32)(prefix_len + lang_len);\n\n   if (lang_key_len > PNG_UINT_31_MAX-prefix_len)\n      prefix_len = PNG_UINT_31_MAX;\n   else\n      prefix_len = (png_uint_32)(prefix_len + lang_key_len);\n\n   png_text_compress_init(&comp, (png_const_bytep)text, strlen(text));\n\n   if (compression != 0)\n   {\n      if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK)\n         png_error(png_ptr, png_ptr->zstream.msg);\n   }\n\n   else\n   {\n      if (comp.input_len > PNG_UINT_31_MAX-prefix_len)\n         png_error(png_ptr, \"iTXt: uncompressed text too long\");\n\n      /* So the string will fit in a chunk: */\n      comp.output_len = (png_uint_32)/*SAFE*/comp.input_len;\n   }\n\n   png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len);\n\n   png_write_chunk_data(png_ptr, new_key, key_len);\n\n   png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len);\n\n   png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len);\n\n   if (compression != 0)\n      png_write_compressed_data_out(png_ptr, &comp);\n\n   else\n      png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.output_len);\n\n   png_write_chunk_end(png_ptr);\n}\n#endif\n\n#ifdef PNG_WRITE_oFFs_SUPPORTED\n/* Write the oFFs chunk */\nvoid /* PRIVATE */\npng_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset,\n    int unit_type)\n{\n   png_byte buf[9];\n\n   png_debug(1, \"in png_write_oFFs\");\n\n   if (unit_type >= PNG_OFFSET_LAST)\n      png_warning(png_ptr, \"Unrecognized unit type for oFFs chunk\");\n\n   png_save_int_32(buf, x_offset);\n   png_save_int_32(buf + 4, y_offset);\n   buf[8] = (png_byte)unit_type;\n\n   png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);\n}\n#endif\n#ifdef PNG_WRITE_pCAL_SUPPORTED\n/* Write the pCAL chunk (described in the PNG extensions document) */\nvoid /* PRIVATE */\npng_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,\n    png_int_32 X1, int type, int nparams, png_const_charp units,\n    png_charpp params)\n{\n   png_uint_32 purpose_len;\n   png_size_t units_len, total_len;\n   png_size_tp params_len;\n   png_byte buf[10];\n   png_byte new_purpose[80];\n   int i;\n\n   png_debug1(1, \"in png_write_pCAL (%d parameters)\", nparams);\n\n   if (type >= PNG_EQUATION_LAST)\n      png_error(png_ptr, \"Unrecognized equation type for pCAL chunk\");\n\n   purpose_len = png_check_keyword(png_ptr, purpose, new_purpose);\n\n   if (purpose_len == 0)\n      png_error(png_ptr, \"pCAL: invalid keyword\");\n\n   ++purpose_len; /* terminator */\n\n   png_debug1(3, \"pCAL purpose length = %d\", (int)purpose_len);\n   units_len = strlen(units) + (nparams == 0 ? 0 : 1);\n   png_debug1(3, \"pCAL units length = %d\", (int)units_len);\n   total_len = purpose_len + units_len + 10;\n\n   params_len = (png_size_tp)png_malloc(png_ptr,\n       (png_alloc_size_t)(nparams * (sizeof (png_size_t))));\n\n   /* Find the length of each parameter, making sure we don't count the\n    * null terminator for the last parameter.\n    */\n   for (i = 0; i < nparams; i++)\n   {\n      params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1);\n      png_debug2(3, \"pCAL parameter %d length = %lu\", i,\n          (unsigned long)params_len[i]);\n      total_len += params_len[i];\n   }\n\n   png_debug1(3, \"pCAL total length = %d\", (int)total_len);\n   png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len);\n   png_write_chunk_data(png_ptr, new_purpose, purpose_len);\n   png_save_int_32(buf, X0);\n   png_save_int_32(buf + 4, X1);\n   buf[8] = (png_byte)type;\n   buf[9] = (png_byte)nparams;\n   png_write_chunk_data(png_ptr, buf, (png_size_t)10);\n   png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);\n\n   for (i = 0; i < nparams; i++)\n   {\n      png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]);\n   }\n\n   png_free(png_ptr, params_len);\n   png_write_chunk_end(png_ptr);\n}\n#endif\n\n#ifdef PNG_WRITE_sCAL_SUPPORTED\n/* Write the sCAL chunk */\nvoid /* PRIVATE */\npng_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width,\n    png_const_charp height)\n{\n   png_byte buf[64];\n   png_size_t wlen, hlen, total_len;\n\n   png_debug(1, \"in png_write_sCAL_s\");\n\n   wlen = strlen(width);\n   hlen = strlen(height);\n   total_len = wlen + hlen + 2;\n\n   if (total_len > 64)\n   {\n      png_warning(png_ptr, \"Can't write sCAL (buffer too small)\");\n      return;\n   }\n\n   buf[0] = (png_byte)unit;\n   memcpy(buf + 1, width, wlen + 1);      /* Append the '\\0' here */\n   memcpy(buf + wlen + 2, height, hlen);  /* Do NOT append the '\\0' here */\n\n   png_debug1(3, \"sCAL total length = %u\", (unsigned int)total_len);\n   png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len);\n}\n#endif\n\n#ifdef PNG_WRITE_pHYs_SUPPORTED\n/* Write the pHYs chunk */\nvoid /* PRIVATE */\npng_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit,\n    png_uint_32 y_pixels_per_unit,\n    int unit_type)\n{\n   png_byte buf[9];\n\n   png_debug(1, \"in png_write_pHYs\");\n\n   if (unit_type >= PNG_RESOLUTION_LAST)\n      png_warning(png_ptr, \"Unrecognized unit type for pHYs chunk\");\n\n   png_save_uint_32(buf, x_pixels_per_unit);\n   png_save_uint_32(buf + 4, y_pixels_per_unit);\n   buf[8] = (png_byte)unit_type;\n\n   png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);\n}\n#endif\n\n#ifdef PNG_WRITE_tIME_SUPPORTED\n/* Write the tIME chunk.  Use either png_convert_from_struct_tm()\n * or png_convert_from_time_t(), or fill in the structure yourself.\n */\nvoid /* PRIVATE */\npng_write_tIME(png_structrp png_ptr, png_const_timep mod_time)\n{\n   png_byte buf[7];\n\n   png_debug(1, \"in png_write_tIME\");\n\n   if (mod_time->month  > 12 || mod_time->month  < 1 ||\n       mod_time->day    > 31 || mod_time->day    < 1 ||\n       mod_time->hour   > 23 || mod_time->second > 60)\n   {\n      png_warning(png_ptr, \"Invalid time specified for tIME chunk\");\n      return;\n   }\n\n   png_save_uint_16(buf, mod_time->year);\n   buf[2] = mod_time->month;\n   buf[3] = mod_time->day;\n   buf[4] = mod_time->hour;\n   buf[5] = mod_time->minute;\n   buf[6] = mod_time->second;\n\n   png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7);\n}\n#endif\n\n/* Initializes the row writing capability of libpng */\nvoid /* PRIVATE */\npng_write_start_row(png_structrp png_ptr)\n{\n#ifdef PNG_WRITE_INTERLACING_SUPPORTED\n   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */\n\n   /* Start of interlace block */\n   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};\n\n   /* Offset to next interlace block */\n   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};\n\n   /* Start of interlace block in the y direction */\n   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};\n\n   /* Offset to next interlace block in the y direction */\n   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};\n#endif\n\n   png_alloc_size_t buf_size;\n   int usr_pixel_depth;\n\n#ifdef PNG_WRITE_FILTER_SUPPORTED\n   png_byte filters;\n#endif\n\n   png_debug(1, \"in png_write_start_row\");\n\n   usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth;\n   buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1;\n\n   /* 1.5.6: added to allow checking in the row write code. */\n   png_ptr->transformed_pixel_depth = png_ptr->pixel_depth;\n   png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth;\n\n   /* Set up row buffer */\n   png_ptr->row_buf = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));\n\n   png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;\n\n#ifdef PNG_WRITE_FILTER_SUPPORTED\n   filters = png_ptr->do_filter;\n\n   if (png_ptr->height == 1)\n      filters &= 0xff & ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);\n\n   if (png_ptr->width == 1)\n      filters &= 0xff & ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH);\n\n   if (filters == 0)\n      filters = PNG_FILTER_NONE;\n\n   png_ptr->do_filter = filters;\n\n   if (((filters & (PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG |\n       PNG_FILTER_PAETH)) != 0) && png_ptr->try_row == NULL)\n   {\n      int num_filters = 0;\n\n      png_ptr->try_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));\n\n      if (filters & PNG_FILTER_SUB)\n         num_filters++;\n\n      if (filters & PNG_FILTER_UP)\n         num_filters++;\n\n      if (filters & PNG_FILTER_AVG)\n         num_filters++;\n\n      if (filters & PNG_FILTER_PAETH)\n         num_filters++;\n\n      if (num_filters > 1)\n         png_ptr->tst_row = png_voidcast(png_bytep, png_malloc(png_ptr,\n             buf_size));\n   }\n\n   /* We only need to keep the previous row if we are using one of the following\n    * filters.\n    */\n   if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0)\n      png_ptr->prev_row = png_voidcast(png_bytep,\n         png_calloc(png_ptr, buf_size));\n#endif /* WRITE_FILTER */\n\n#ifdef PNG_WRITE_INTERLACING_SUPPORTED\n   /* If interlaced, we need to set up width and height of pass */\n   if (png_ptr->interlaced != 0)\n   {\n      if ((png_ptr->transformations & PNG_INTERLACE) == 0)\n      {\n         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -\n             png_pass_ystart[0]) / png_pass_yinc[0];\n\n         png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -\n             png_pass_start[0]) / png_pass_inc[0];\n      }\n\n      else\n      {\n         png_ptr->num_rows = png_ptr->height;\n         png_ptr->usr_width = png_ptr->width;\n      }\n   }\n\n   else\n#endif\n   {\n      png_ptr->num_rows = png_ptr->height;\n      png_ptr->usr_width = png_ptr->width;\n   }\n}\n\n/* Internal use only.  Called when finished processing a row of data. */\nvoid /* PRIVATE */\npng_write_finish_row(png_structrp png_ptr)\n{\n#ifdef PNG_WRITE_INTERLACING_SUPPORTED\n   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */\n\n   /* Start of interlace block */\n   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};\n\n   /* Offset to next interlace block */\n   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};\n\n   /* Start of interlace block in the y direction */\n   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};\n\n   /* Offset to next interlace block in the y direction */\n   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};\n#endif\n\n   png_debug(1, \"in png_write_finish_row\");\n\n   /* Next row */\n   png_ptr->row_number++;\n\n   /* See if we are done */\n   if (png_ptr->row_number < png_ptr->num_rows)\n      return;\n\n#ifdef PNG_WRITE_INTERLACING_SUPPORTED\n   /* If interlaced, go to next pass */\n   if (png_ptr->interlaced != 0)\n   {\n      png_ptr->row_number = 0;\n      if ((png_ptr->transformations & PNG_INTERLACE) != 0)\n      {\n         png_ptr->pass++;\n      }\n\n      else\n      {\n         /* Loop until we find a non-zero width or height pass */\n         do\n         {\n            png_ptr->pass++;\n\n            if (png_ptr->pass >= 7)\n               break;\n\n            png_ptr->usr_width = (png_ptr->width +\n                png_pass_inc[png_ptr->pass] - 1 -\n                png_pass_start[png_ptr->pass]) /\n                png_pass_inc[png_ptr->pass];\n\n            png_ptr->num_rows = (png_ptr->height +\n                png_pass_yinc[png_ptr->pass] - 1 -\n                png_pass_ystart[png_ptr->pass]) /\n                png_pass_yinc[png_ptr->pass];\n\n            if ((png_ptr->transformations & PNG_INTERLACE) != 0)\n               break;\n\n         } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);\n\n      }\n\n      /* Reset the row above the image for the next pass */\n      if (png_ptr->pass < 7)\n      {\n         if (png_ptr->prev_row != NULL)\n            memset(png_ptr->prev_row, 0,\n                (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*\n                png_ptr->usr_bit_depth, png_ptr->width)) + 1);\n\n         return;\n      }\n   }\n#endif\n\n   /* If we get here, we've just written the last row, so we need\n      to flush the compressor */\n   png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH);\n}\n\n#ifdef PNG_WRITE_INTERLACING_SUPPORTED\n/* Pick out the correct pixels for the interlace pass.\n * The basic idea here is to go through the row with a source\n * pointer and a destination pointer (sp and dp), and copy the\n * correct pixels for the pass.  As the row gets compacted,\n * sp will always be >= dp, so we should never overwrite anything.\n * See the default: case for the easiest code to understand.\n */\nvoid /* PRIVATE */\npng_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)\n{\n   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */\n\n   /* Start of interlace block */\n   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};\n\n   /* Offset to next interlace block */\n   static PNG_CONST png_byte  png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};\n\n   png_debug(1, \"in png_do_write_interlace\");\n\n   /* We don't have to do anything on the last pass (6) */\n   if (pass < 6)\n   {\n      /* Each pixel depth is handled separately */\n      switch (row_info->pixel_depth)\n      {\n         case 1:\n         {\n            png_bytep sp;\n            png_bytep dp;\n            unsigned int shift;\n            int d;\n            int value;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n\n            dp = row;\n            d = 0;\n            shift = 7;\n\n            for (i = png_pass_start[pass]; i < row_width;\n               i += png_pass_inc[pass])\n            {\n               sp = row + (png_size_t)(i >> 3);\n               value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;\n               d |= (value << shift);\n\n               if (shift == 0)\n               {\n                  shift = 7;\n                  *dp++ = (png_byte)d;\n                  d = 0;\n               }\n\n               else\n                  shift--;\n\n            }\n            if (shift != 7)\n               *dp = (png_byte)d;\n\n            break;\n         }\n\n         case 2:\n         {\n            png_bytep sp;\n            png_bytep dp;\n            unsigned int shift;\n            int d;\n            int value;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n\n            dp = row;\n            shift = 6;\n            d = 0;\n\n            for (i = png_pass_start[pass]; i < row_width;\n               i += png_pass_inc[pass])\n            {\n               sp = row + (png_size_t)(i >> 2);\n               value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;\n               d |= (value << shift);\n\n               if (shift == 0)\n               {\n                  shift = 6;\n                  *dp++ = (png_byte)d;\n                  d = 0;\n               }\n\n               else\n                  shift -= 2;\n            }\n            if (shift != 6)\n               *dp = (png_byte)d;\n\n            break;\n         }\n\n         case 4:\n         {\n            png_bytep sp;\n            png_bytep dp;\n            unsigned int shift;\n            int d;\n            int value;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n\n            dp = row;\n            shift = 4;\n            d = 0;\n            for (i = png_pass_start[pass]; i < row_width;\n                i += png_pass_inc[pass])\n            {\n               sp = row + (png_size_t)(i >> 1);\n               value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;\n               d |= (value << shift);\n\n               if (shift == 0)\n               {\n                  shift = 4;\n                  *dp++ = (png_byte)d;\n                  d = 0;\n               }\n\n               else\n                  shift -= 4;\n            }\n            if (shift != 4)\n               *dp = (png_byte)d;\n\n            break;\n         }\n\n         default:\n         {\n            png_bytep sp;\n            png_bytep dp;\n            png_uint_32 i;\n            png_uint_32 row_width = row_info->width;\n            png_size_t pixel_bytes;\n\n            /* Start at the beginning */\n            dp = row;\n\n            /* Find out how many bytes each pixel takes up */\n            pixel_bytes = (row_info->pixel_depth >> 3);\n\n            /* Loop through the row, only looking at the pixels that matter */\n            for (i = png_pass_start[pass]; i < row_width;\n               i += png_pass_inc[pass])\n            {\n               /* Find out where the original pixel is */\n               sp = row + (png_size_t)i * pixel_bytes;\n\n               /* Move the pixel */\n               if (dp != sp)\n                  memcpy(dp, sp, pixel_bytes);\n\n               /* Next pixel */\n               dp += pixel_bytes;\n            }\n            break;\n         }\n      }\n      /* Set new row width */\n      row_info->width = (row_info->width +\n          png_pass_inc[pass] - 1 -\n          png_pass_start[pass]) /\n          png_pass_inc[pass];\n\n      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,\n          row_info->width);\n   }\n}\n#endif\n\n\n/* This filters the row, chooses which filter to use, if it has not already\n * been specified by the application, and then writes the row out with the\n * chosen filter.\n */\nstatic void /* PRIVATE */\npng_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,\n   png_size_t row_bytes);\n\n#ifdef PNG_WRITE_FILTER_SUPPORTED\nstatic png_size_t /* PRIVATE */\npng_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp,\n    const png_size_t row_bytes, const png_size_t lmins)\n{\n   png_bytep rp, dp, lp;\n   png_size_t i;\n   png_size_t sum = 0;\n   int v;\n\n   png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;\n\n   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp;\n        i++, rp++, dp++)\n   {\n      v = *dp = *rp;\n      sum += (v < 128) ? v : 256 - v;\n   }\n\n   for (lp = png_ptr->row_buf + 1; i < row_bytes;\n      i++, rp++, lp++, dp++)\n   {\n      v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);\n      sum += (v < 128) ? v : 256 - v;\n\n      if (sum > lmins)  /* We are already worse, don't continue. */\n        break;\n   }\n\n   return (sum);\n}\n\nstatic png_size_t /* PRIVATE */\npng_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,\n    const png_size_t lmins)\n{\n   png_bytep rp, dp, pp;\n   png_size_t i;\n   png_size_t sum = 0;\n   int v;\n\n   png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;\n\n   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,\n       pp = png_ptr->prev_row + 1; i < row_bytes;\n       i++, rp++, pp++, dp++)\n   {\n      v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);\n      sum += (v < 128) ? v : 256 - v;\n\n      if (sum > lmins)  /* We are already worse, don't continue. */\n        break;\n   }\n\n   return (sum);\n}\n\nstatic png_size_t /* PRIVATE */\npng_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,\n      const png_size_t row_bytes, const png_size_t lmins)\n{\n   png_bytep rp, dp, pp, lp;\n   png_uint_32 i;\n   png_size_t sum = 0;\n   int v;\n\n   png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;\n\n   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,\n        pp = png_ptr->prev_row + 1; i < bpp; i++)\n   {\n      v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);\n\n      sum += (v < 128) ? v : 256 - v;\n   }\n\n   for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)\n   {\n      v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))\n          & 0xff);\n\n      sum += (v < 128) ? v : 256 - v;\n\n      if (sum > lmins)  /* We are already worse, don't continue. */\n        break;\n   }\n\n   return (sum);\n}\n\nstatic png_size_t /* PRIVATE */\npng_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,\n    const png_size_t row_bytes, const png_size_t lmins)\n{\n   png_bytep rp, dp, pp, cp, lp;\n   png_size_t i;\n   png_size_t sum = 0;\n   int v;\n\n   png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;\n\n   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,\n       pp = png_ptr->prev_row + 1; i < bpp; i++)\n   {\n      v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);\n\n      sum += (v < 128) ? v : 256 - v;\n   }\n\n   for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;\n        i++)\n   {\n      int a, b, c, pa, pb, pc, p;\n\n      b = *pp++;\n      c = *cp++;\n      a = *lp++;\n\n      p = b - c;\n      pc = a - c;\n\n#ifdef PNG_USE_ABS\n      pa = abs(p);\n      pb = abs(pc);\n      pc = abs(p + pc);\n#else\n      pa = p < 0 ? -p : p;\n      pb = pc < 0 ? -pc : pc;\n      pc = (p + pc) < 0 ? -(p + pc) : p + pc;\n#endif\n\n      p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;\n\n      v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);\n\n      sum += (v < 128) ? v : 256 - v;\n\n      if (sum > lmins)  /* We are already worse, don't continue. */\n        break;\n   }\n\n   return (sum);\n}\n#endif /* WRITE_FILTER */\n\nvoid /* PRIVATE */\npng_write_find_filter(png_structrp png_ptr, png_row_infop row_info)\n{\n#ifndef PNG_WRITE_FILTER_SUPPORTED\n   png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1);\n#else\n   png_byte filter_to_do = png_ptr->do_filter;\n   png_bytep row_buf;\n   png_bytep best_row;\n   png_uint_32 bpp;\n   png_size_t mins;\n   png_size_t row_bytes = row_info->rowbytes;\n\n   png_debug(1, \"in png_write_find_filter\");\n\n   /* Find out how many bytes offset each pixel is */\n   bpp = (row_info->pixel_depth + 7) >> 3;\n\n   row_buf = png_ptr->row_buf;\n   mins = PNG_SIZE_MAX - 256/* so we can detect potential overflow of the\n                               running sum */;\n\n   /* The prediction method we use is to find which method provides the\n    * smallest value when summing the absolute values of the distances\n    * from zero, using anything >= 128 as negative numbers.  This is known\n    * as the \"minimum sum of absolute differences\" heuristic.  Other\n    * heuristics are the \"weighted minimum sum of absolute differences\"\n    * (experimental and can in theory improve compression), and the \"zlib\n    * predictive\" method (not implemented yet), which does test compressions\n    * of lines using different filter methods, and then chooses the\n    * (series of) filter(s) that give minimum compressed data size (VERY\n    * computationally expensive).\n    *\n    * GRR 980525:  consider also\n    *\n    *   (1) minimum sum of absolute differences from running average (i.e.,\n    *       keep running sum of non-absolute differences & count of bytes)\n    *       [track dispersion, too?  restart average if dispersion too large?]\n    *\n    *  (1b) minimum sum of absolute differences from sliding average, probably\n    *       with window size <= deflate window (usually 32K)\n    *\n    *   (2) minimum sum of squared differences from zero or running average\n    *       (i.e., ~ root-mean-square approach)\n    */\n\n\n   /* We don't need to test the 'no filter' case if this is the only filter\n    * that has been chosen, as it doesn't actually do anything to the data.\n    */\n   best_row = png_ptr->row_buf;\n\n\n   if ((filter_to_do & PNG_FILTER_NONE) != 0 && filter_to_do != PNG_FILTER_NONE)\n   {\n      png_bytep rp;\n      png_size_t sum = 0;\n      png_size_t i;\n      int v;\n\n      if (PNG_SIZE_MAX/128 <= row_bytes)\n      {\n         for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)\n         {\n            /* Check for overflow */\n            if (sum > PNG_SIZE_MAX/128 - 256)\n               break;\n\n            v = *rp;\n            sum += (v < 128) ? v : 256 - v;\n         }\n      }\n      else /* Overflow is not possible */\n      {\n         for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)\n         {\n            v = *rp;\n            sum += (v < 128) ? v : 256 - v;\n         }\n      }\n\n      mins = sum;\n   }\n\n   /* Sub filter */\n   if (filter_to_do == PNG_FILTER_SUB)\n   /* It's the only filter so no testing is needed */\n   {\n      (void) png_setup_sub_row(png_ptr, bpp, row_bytes, mins);\n      best_row = png_ptr->try_row;\n   }\n\n   else if ((filter_to_do & PNG_FILTER_SUB) != 0)\n   {\n      png_size_t sum;\n      png_size_t lmins = mins;\n\n      sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);\n\n      if (sum < mins)\n      {\n         mins = sum;\n         best_row = png_ptr->try_row;\n         if (png_ptr->tst_row != NULL)\n         {\n            png_ptr->try_row = png_ptr->tst_row;\n            png_ptr->tst_row = best_row;\n         }\n      }\n   }\n\n   /* Up filter */\n   if (filter_to_do == PNG_FILTER_UP)\n   {\n      (void) png_setup_up_row(png_ptr, row_bytes, mins);\n      best_row = png_ptr->try_row;\n   }\n\n   else if ((filter_to_do & PNG_FILTER_UP) != 0)\n   {\n      png_size_t sum;\n      png_size_t lmins = mins;\n\n      sum = png_setup_up_row(png_ptr, row_bytes, lmins);\n\n      if (sum < mins)\n      {\n         mins = sum;\n         best_row = png_ptr->try_row;\n         if (png_ptr->tst_row != NULL)\n         {\n            png_ptr->try_row = png_ptr->tst_row;\n            png_ptr->tst_row = best_row;\n         }\n      }\n   }\n\n   /* Avg filter */\n   if (filter_to_do == PNG_FILTER_AVG)\n   {\n      (void) png_setup_avg_row(png_ptr, bpp, row_bytes, mins);\n      best_row = png_ptr->try_row;\n   }\n\n   else if ((filter_to_do & PNG_FILTER_AVG) != 0)\n   {\n      png_size_t sum;\n      png_size_t lmins = mins;\n\n      sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins);\n\n      if (sum < mins)\n      {\n         mins = sum;\n         best_row = png_ptr->try_row;\n         if (png_ptr->tst_row != NULL)\n         {\n            png_ptr->try_row = png_ptr->tst_row;\n            png_ptr->tst_row = best_row;\n         }\n      }\n   }\n\n   /* Paeth filter */\n   if ((filter_to_do == PNG_FILTER_PAETH) != 0)\n   {\n      (void) png_setup_paeth_row(png_ptr, bpp, row_bytes, mins);\n      best_row = png_ptr->try_row;\n   }\n\n   else if ((filter_to_do & PNG_FILTER_PAETH) != 0)\n   {\n      png_size_t sum;\n      png_size_t lmins = mins;\n\n      sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins);\n\n      if (sum < mins)\n      {\n         best_row = png_ptr->try_row;\n         if (png_ptr->tst_row != NULL)\n         {\n            png_ptr->try_row = png_ptr->tst_row;\n            png_ptr->tst_row = best_row;\n         }\n      }\n   }\n\n   /* Do the actual writing of the filtered row data from the chosen filter. */\n   png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1);\n\n#endif /* WRITE_FILTER */\n}\n\n\n/* Do the actual writing of a previously filtered row. */\nstatic void\npng_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,\n   png_size_t full_row_length/*includes filter byte*/)\n{\n   png_debug(1, \"in png_write_filtered_row\");\n\n   png_debug1(2, \"filter = %d\", filtered_row[0]);\n\n   png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH);\n\n#ifdef PNG_WRITE_FILTER_SUPPORTED\n   /* Swap the current and previous rows */\n   if (png_ptr->prev_row != NULL)\n   {\n      png_bytep tptr;\n\n      tptr = png_ptr->prev_row;\n      png_ptr->prev_row = png_ptr->row_buf;\n      png_ptr->row_buf = tptr;\n   }\n#endif /* WRITE_FILTER */\n\n   /* Finish row - updates counters and flushes zlib if last row */\n   png_write_finish_row(png_ptr);\n\n#ifdef PNG_WRITE_FLUSH_SUPPORTED\n   png_ptr->flush_rows++;\n\n   if (png_ptr->flush_dist > 0 &&\n       png_ptr->flush_rows >= png_ptr->flush_dist)\n   {\n      png_write_flush(png_ptr);\n   }\n#endif /* WRITE_FLUSH */\n}\n#endif /* WRITE */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/owatcom/libpng.tgt",
    "content": "40\ntargetIdent\n0\nMProject\n1\nMComponent\n0\n2\nWString\n3\nLIB\n3\nWString\n5\nn_2sn\n1\n0\n0\n4\nMCommand\n0\n5\nMCommand\n0\n6\nMItem\n10\nlibpng.lib\n7\nWString\n3\nLIB\n8\nWVList\n0\n9\nWVList\n1\n10\nActionStates\n11\nWString\n5\n&Make\n12\nWVList\n0\n-1\n1\n1\n0\n13\nWPickList\n16\n14\nMItem\n3\n*.c\n15\nWString\n4\nCOBJ\n16\nWVList\n2\n17\nMVState\n18\nWString\n3\nWCC\n19\nWString\n25\nn????Include directories:\n1\n20\nWString\n39\n\"$(%zlib);$(%watcom)/h;$(%watcom)/h/nt\"\n0\n21\nMVState\n22\nWString\n3\nWCC\n23\nWString\n25\nn????Include directories:\n0\n24\nWString\n39\n\"$(%zlib);$(%watcom)/h;$(%watcom)/h/nt\"\n0\n25\nWVList\n1\n26\nActionStates\n27\nWString\n5\n&Make\n28\nWVList\n0\n-1\n1\n1\n0\n29\nMItem\n11\n..\\..\\png.c\n30\nWString\n4\nCOBJ\n31\nWVList\n0\n32\nWVList\n0\n14\n1\n1\n0\n33\nMItem\n16\n..\\..\\pngerror.c\n34\nWString\n4\nCOBJ\n35\nWVList\n0\n36\nWVList\n0\n14\n1\n1\n0\n37\nMItem\n14\n..\\..\\pngget.c\n38\nWString\n4\nCOBJ\n39\nWVList\n0\n40\nWVList\n0\n14\n1\n1\n0\n41\nMItem\n14\n..\\..\\pngmem.c\n42\nWString\n4\nCOBJ\n43\nWVList\n0\n44\nWVList\n0\n14\n1\n1\n0\n45\nMItem\n16\n..\\..\\pngpread.c\n46\nWString\n4\nCOBJ\n47\nWVList\n0\n48\nWVList\n0\n14\n1\n1\n0\n49\nMItem\n15\n..\\..\\pngread.c\n50\nWString\n4\nCOBJ\n51\nWVList\n0\n52\nWVList\n0\n14\n1\n1\n0\n53\nMItem\n14\n..\\..\\pngrio.c\n54\nWString\n4\nCOBJ\n55\nWVList\n0\n56\nWVList\n0\n14\n1\n1\n0\n57\nMItem\n16\n..\\..\\pngrtran.c\n58\nWString\n4\nCOBJ\n59\nWVList\n0\n60\nWVList\n0\n14\n1\n1\n0\n61\nMItem\n16\n..\\..\\pngrutil.c\n62\nWString\n4\nCOBJ\n63\nWVList\n0\n64\nWVList\n0\n14\n1\n1\n0\n65\nMItem\n14\n..\\..\\pngset.c\n66\nWString\n4\nCOBJ\n67\nWVList\n0\n68\nWVList\n0\n14\n1\n1\n0\n69\nMItem\n16\n..\\..\\pngtrans.c\n70\nWString\n4\nCOBJ\n71\nWVList\n0\n72\nWVList\n0\n14\n1\n1\n0\n73\nMItem\n14\n..\\..\\pngwio.c\n74\nWString\n4\nCOBJ\n75\nWVList\n0\n76\nWVList\n0\n14\n1\n1\n0\n77\nMItem\n16\n..\\..\\pngwrite.c\n78\nWString\n4\nCOBJ\n79\nWVList\n0\n80\nWVList\n0\n14\n1\n1\n0\n81\nMItem\n16\n..\\..\\pngwtran.c\n82\nWString\n4\nCOBJ\n83\nWVList\n0\n84\nWVList\n0\n14\n1\n1\n0\n85\nMItem\n16\n..\\..\\pngwutil.c\n86\nWString\n4\nCOBJ\n87\nWVList\n0\n88\nWVList\n0\n14\n1\n1\n0\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/owatcom/libpng.wpj",
    "content": "40\nprojectIdent\n0\nVpeMain\n1\nWRect\n256\n0\n8960\n9294\n2\nMProject\n3\nMCommand\n322\n# Locations of zlib and (if required) awk (change as required:)\nset zlib=..\\..\\..\\zlib\nset awk=\n#\n@if not exist pngconfig.dfa $(MAKE) $(__MAKEOPTS__) -f pngconfig.mak defaults\n@if exist config.inf type config.inf\n@echo Checking for the libpng configuration file pnglibconf.h\n$(MAKE) $(__MAKEOPTS__) -f pngconfig.mak\n4\nMCommand\n19\n@type pngconfig.inf\n4\n5\nWFileName\n10\nlibpng.tgt\n6\nWFileName\n11\npngtest.tgt\n7\nWFileName\n12\npngvalid.tgt\n8\nWFileName\n12\npngstest.tgt\n9\nWVList\n4\n10\nVComponent\n11\nWRect\n0\n0\n5638\n4174\n0\n0\n12\nWFileName\n10\nlibpng.tgt\n0\n0\n13\nVComponent\n14\nWRect\n1280\n1550\n5638\n4174\n0\n0\n15\nWFileName\n11\npngtest.tgt\n0\n1\n16\nVComponent\n17\nWRect\n524\n497\n5638\n4174\n0\n0\n18\nWFileName\n12\npngvalid.tgt\n0\n1\n19\nVComponent\n20\nWRect\n2054\n2701\n5674\n4232\n0\n0\n21\nWFileName\n12\npngstest.tgt\n0\n1\n19\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/owatcom/pngconfig.mak",
    "content": "# This is an OpenWatcom make file which builds pnglibconf.h - the libpng\n# configuration header.  You can ignore this file if you don't need to\n# configure libpng; a default configuration will be built.\n#\n# For more information build libpng.wpj under the IDE and then read the\n# generated files:\n#\n#    config.inf: Basic configuration information for a standard build.\n#    pngconfig.dfa: Advanced configuration for non-standard libpng builds.\n#\nDELETE=rm -f\nECHO=echo\nCOPY=copy\n#\n# If your configuration needs to test compiler flags when building\n# pnglibconf.h you may need to override the following on the wmake command\n# line:\nCFLAGS=\nCC=wcl386\nCPP=$(CC) -pw0\n#\n# Read awk from the environment if set, else it can be set on the command\n# line (the default approach is to set the %awk% environment variable in the\n# IDE libpng.wpj 'before' rule - this setting is local.)\n!ifdef %awk\nAWK=$(%awk)\n!endif\n#\n# pnglibconf.h must exist in the source directory, this is the final rule\n# which copies the local built version (and this is the default target for\n# this makefile.)\n..\\..\\pnglibconf.h: pnglibconf.h\n $(COPY) pnglibconf.h $@\n\n!ifdef AWK\n# CPPFLAGS should contain the options to control the result,\n# but DEFS and CFLAGS are also supported here, override\n# as appropriate\nDFNFLAGS = $(DEFS) $(CPPFLAGS) $(CFLAGS)\n\npnglibconf.h: pnglibconf.dfn\n $(DELETE) $@ dfn.c dfn1.out dfn2.out\n $(ECHO) $#include \"pnglibconf.dfn\" >dfn.c\n $(CPP) $(DFNFLAGS) dfn.c >dfn1.out\n $(AWK) -f << dfn1.out >dfn2.out\n/^.*PNG_DEFN_MAGIC-.*-PNG_DEFN_END.*$$/{\n sub(/^.*PNG_DEFN_MAGIC-/, \"\")\n sub(/ *-PNG_DEFN_END.*$$/, \"\")\n gsub(/ *@@@ */, \"\")\n print\n}\n<<\n $(COPY) dfn2.out $@\n @type << >pngconfig.inf\nThis is a locally configurable build of libpng.lib; for configuration\ninstructions consult and edit projects/openwatcom/pngconfig.dfa\n<<\n $(DELETE) dfn.c dfn1.out dfn2.out\n\npnglibconf.dfn: ..\\..\\scripts\\pnglibconf.dfa ..\\..\\scripts\\options.awk pngconfig.dfa ..\\..\\pngconf.h\n $(DELETE) $@ dfn1.out dfn2.out\n $(AWK) -f ..\\..\\scripts\\options.awk out=dfn1.out version=search ..\\..\\pngconf.h ..\\..\\scripts\\pnglibconf.dfa pngconfig.dfa $(DFA_XTRA) 1>&2\n $(AWK) -f ..\\..\\scripts\\options.awk out=dfn2.out dfn1.out 1>&2\n $(COPY) dfn2.out $@\n $(DELETE) dfn1.out dfn2.out\n\n!else\n# The following lines are used to copy scripts\\pnglibconf.h.prebuilt and make\n# the required change to the calling convention.\n#\n# By default libpng is built to use the __cdecl calling convention on\n# Windows.  This gives compatibility with MSVC and GCC.  Unfortunately it\n# does not work with OpenWatcom because OpenWatcom implements longjmp using\n# the __watcall convention (compared with both MSVC and GCC which use __cdecl\n# for library functions.)\n#\n# Thus the default must be changed to build on OpenWatcom and, once changed,\n# the result will not be compatible with applications built using other\n# compilers (in fact attempts to build will fail at compile time.)\n#\npnglibconf.h: ..\\..\\scripts\\pnglibconf.h.prebuilt .existsonly\n @$(ECHO) .\n @$(ECHO) .\n @$(ECHO) $$(AWK) NOT AVAILABLE: COPYING scripts\\pnglibconf.h.prebuilt\n @$(ECHO) .\n @$(ECHO) .\n vi -q -k \":1,$$s/PNG_API_RULE 0$$/PNG_API_RULE 2/\\n:w! $@\\n:q!\\n\" ..\\..\\scripts\\pnglibconf.h.prebuilt\n @$(ECHO) .\n @$(ECHO) .\n @$(ECHO) YOU HAVE A DEFAULT CONFIGURATION BECAUSE YOU DO NOT HAVE AWK!\n @$(ECHO) .\n @$(ECHO) .\n @type << >pngconfig.inf\nThis is the default configuration of libpng.lib, if you wish to\nchange the configuration please consult the instructions in\nprojects/owatcom/pngconfig.dfa.\n<<\n\n!endif\n\n# Make the default files\ndefaults: .symbolic\n @$(COPY) << config.inf\n$# The libpng project is incompletely configured.  To complete configuration\n$# please complete the following steps:\n$#\n$#   1) Edit the 'before' rule of libpng.wpj (from the IDE) to define the\n$#      locations of the zlib include file zlib.h and the built zlib library,\n$#      zlib.lib.\n$#\n$#   2) If you want to change libpng to a non-standard configuration also\n$#      change the definition of 'awk' in the before rule to the name of your\n$#      awk command.  For more instructions on configuration read\n$#      pngconfig.dfa.\n$#\n$#   3) Delete this file (config.inf).\n<<\n @$(COPY) << pngconfig.dfa\n$# pngconfig.dfa: this file contains configuration options for libpng.\n$# If emtpy the standard configuration will be built.  For this file to be\n$# used a working version of the program 'awk' is required and the program\n$# must be identified in the 'before' rule of the project.\n$#\n$# If you don't already have 'awk', or the version of awk you have seems not\n$# to work, download Brian Kernighan's awk (Brian Kernighan is the author of\n$# awk.)  You can find source code and a built executable (called awk95.exe)\n$# here:\n$#\n$#     http://www.cs.princeton.edu/~bwk/btl.mirror/\n$#\n$# The executable works just fine.\n$#\n$# If build issues errors after a change to pngconfig.dfa you have entered\n$# inconsistent feature requests, or even malformed requests, in\n$# pngconfig.dfa.  The error messages from awk should be comprehensible, but\n$# if not simply go back to the start (nothing but comments in this file) and\n$# enter configuration lines one by one until one produces an error.  (Or, of\n$# course, do the standard binary chop.)\n$#\n$# You need to rebuild everything after a change to pnglibconf.dfa - i.e. you\n$# must do Actions/Mark All Targets for Remake.  This is because the compiler\n$# generated dependency information (as of OpenWatcom 1.9) does not record the\n$# dependency on pnglibconf.h correctly.\n$#\n$# If awk isn't set then this file is bypassed.  If you just want the standard\n$# configuration it is automatically produced from the distributed version\n$# (scripts\\pnglibconf.h.prebuilt) by editting PNG_API_RULE to 2 (to force use\n$# of the OpenWatcom library calling convention.)\n$#\n<<\n\nclean:: .symbolic\n $(DELETE) ..\\..\\pnglibconf.h pnglibconf.* dfn.c *.out pngconfig.inf\n $(DELETE) *.obj *.mbr *.sym *.err *.pch libpng.mk\n $(DELETE) libpng.lib libpng.lbr libpng.lb1 libpng.cbr libpng.mk1\n $(DELETE) pngtest.exe pngtest.map pngtest.lk1 pngtest.mk1\n $(DELETE) pngvalid.exe pngvalid.map pngvalid.lk1 pngvalid.mk1\n\ndistclean:: clean .symbolic\n $(DELETE) zlib.inf awk.inf config.inf pngconfig.dfa\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/owatcom/pngstest.tgt",
    "content": "40\ntargetIdent\n0\nMProject\n1\nMComponent\n0\n2\nWString\n4\nNEXE\n3\nWString\n5\nnc2en\n1\n0\n0\n4\nMCommand\n0\n5\nMCommand\n1118\npngstest --strict --log ../../contrib/pngsuite/basn0g01.png ../../contrib/pngsuite/basn0g02.png ../../contrib/pngsuite/basn0g04.png ../../contrib/pngsuite/basn0g08.png ../../contrib/pngsuite/basn0g16.png ../../contrib/pngsuite/basn2c08.png ../../contrib/pngsuite/basn2c16.png ../../contrib/pngsuite/basn3p01.png ../../contrib/pngsuite/basn3p02.png ../../contrib/pngsuite/basn3p04.png ../../contrib/pngsuite/basn3p08.png ../../contrib/pngsuite/basn4a08.png ../../contrib/pngsuite/basn4a16.png ../../contrib/pngsuite/basn6a08.png ../../contrib/pngsuite/basn6a16.png ../../contrib/pngsuite/ftbbn0g04.png ../../contrib/pngsuite/ftbbn0g01.png ../../contrib/pngsuite/ftbbn0g02.png ../../contrib/pngsuite/ftbbn2c16.png ../../contrib/pngsuite/ftbbn3p08.png ../../contrib/pngsuite/ftbgn2c16.png ../../contrib/pngsuite/ftbgn3p08.png ../../contrib/pngsuite/ftbrn2c08.png ../../contrib/pngsuite/ftbwn0g16.png ../../contrib/pngsuite/ftbwn3p08.png ../../contrib/pngsuite/ftbyn3p08.png ../../contrib/pngsuite/ftp0n0g08.png ../../contrib/pngsuite/ftp0n2c08.png ../../contrib/pngsuite/ftp0n3p08.png ../../contrib/pngsuite/ftp1n3p08.png\n6\nMItem\n12\npngstest.exe\n7\nWString\n4\nNEXE\n8\nWVList\n6\n9\nMVState\n10\nWString\n7\nWINLINK\n11\nWString\n11\n?????Stack:\n1\n12\nWString\n4\n768k\n0\n13\nMVState\n14\nWString\n7\nWINLINK\n15\nWString\n28\n?????Library directories(;):\n1\n16\nWString\n8\n$(%zlib)\n0\n17\nMVState\n18\nWString\n7\nWINLINK\n19\nWString\n18\n?????Libraries(,):\n1\n20\nWString\n19\nlibpng.lib zlib.lib\n0\n21\nMVState\n22\nWString\n7\nWINLINK\n23\nWString\n11\n?????Stack:\n0\n24\nWString\n4\n768k\n0\n25\nMVState\n26\nWString\n7\nWINLINK\n27\nWString\n28\n?????Library directories(;):\n0\n28\nWString\n8\n$(%zlib)\n0\n29\nMVState\n30\nWString\n7\nWINLINK\n31\nWString\n18\n?????Libraries(,):\n0\n32\nWString\n19\nlibpng.lib zlib.lib\n0\n33\nWVList\n1\n34\nActionStates\n35\nWString\n4\n&Run\n36\nWVList\n0\n-1\n1\n1\n0\n37\nWPickList\n2\n38\nMItem\n3\n*.c\n39\nWString\n4\nCOBJ\n40\nWVList\n2\n41\nMVState\n42\nWString\n3\nWCC\n43\nWString\n25\nn????Include directories:\n1\n44\nWString\n39\n\"$(%zlib);$(%watcom)/h;$(%watcom)/h/nt\"\n0\n45\nMVState\n46\nWString\n3\nWCC\n47\nWString\n25\nn????Include directories:\n0\n48\nWString\n39\n\"$(%zlib);$(%watcom)/h;$(%watcom)/h/nt\"\n0\n49\nWVList\n0\n-1\n1\n1\n0\n50\nMItem\n33\n..\\..\\contrib\\libtests\\pngstest.c\n51\nWString\n4\nCOBJ\n52\nWVList\n0\n53\nWVList\n0\n38\n1\n1\n0\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/owatcom/pngtest.tgt",
    "content": "40\ntargetIdent\n0\nMProject\n1\nMComponent\n0\n2\nWString\n4\nNEXE\n3\nWString\n5\nnc2en\n1\n0\n0\n4\nMCommand\n0\n5\nMCommand\n34\ncd ..\\..\nprojects\\owatcom\\pngtest\n6\nMItem\n11\npngtest.exe\n7\nWString\n4\nNEXE\n8\nWVList\n4\n9\nMVState\n10\nWString\n7\nWINLINK\n11\nWString\n28\n?????Library directories(;):\n1\n12\nWString\n8\n$(%zlib)\n0\n13\nMVState\n14\nWString\n7\nWINLINK\n15\nWString\n18\n?????Libraries(,):\n1\n16\nWString\n19\nlibpng.lib zlib.lib\n0\n17\nMVState\n18\nWString\n7\nWINLINK\n19\nWString\n28\n?????Library directories(;):\n0\n20\nWString\n8\n$(%zlib)\n0\n21\nMVState\n22\nWString\n7\nWINLINK\n23\nWString\n18\n?????Libraries(,):\n0\n24\nWString\n19\nlibpng.lib zlib.lib\n0\n25\nWVList\n0\n-1\n1\n1\n0\n26\nWPickList\n2\n27\nMItem\n3\n*.c\n28\nWString\n4\nCOBJ\n29\nWVList\n2\n30\nMVState\n31\nWString\n3\nWCC\n32\nWString\n25\nn????Include directories:\n1\n33\nWString\n39\n\"$(%zlib);$(%watcom)/h;$(%watcom)/h/nt\"\n0\n34\nMVState\n35\nWString\n3\nWCC\n36\nWString\n25\nn????Include directories:\n0\n37\nWString\n39\n\"$(%zlib);$(%watcom)/h;$(%watcom)/h/nt\"\n0\n38\nWVList\n0\n-1\n1\n1\n0\n39\nMItem\n15\n..\\..\\pngtest.c\n40\nWString\n4\nCOBJ\n41\nWVList\n0\n42\nWVList\n0\n27\n1\n1\n0\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/owatcom/pngvalid.tgt",
    "content": "40\ntargetIdent\n0\nMProject\n1\nMComponent\n0\n2\nWString\n4\nNEXE\n3\nWString\n5\nnc2en\n1\n0\n0\n4\nMCommand\n0\n5\nMCommand\n8\npngvalid\n6\nMItem\n12\npngvalid.exe\n7\nWString\n4\nNEXE\n8\nWVList\n6\n9\nMVState\n10\nWString\n7\nWINLINK\n11\nWString\n11\n?????Stack:\n1\n12\nWString\n4\n768k\n0\n13\nMVState\n14\nWString\n7\nWINLINK\n15\nWString\n28\n?????Library directories(;):\n1\n16\nWString\n8\n$(%zlib)\n0\n17\nMVState\n18\nWString\n7\nWINLINK\n19\nWString\n18\n?????Libraries(,):\n1\n20\nWString\n19\nlibpng.lib zlib.lib\n0\n21\nMVState\n22\nWString\n7\nWINLINK\n23\nWString\n11\n?????Stack:\n0\n24\nWString\n4\n768k\n0\n25\nMVState\n26\nWString\n7\nWINLINK\n27\nWString\n28\n?????Library directories(;):\n0\n28\nWString\n8\n$(%zlib)\n0\n29\nMVState\n30\nWString\n7\nWINLINK\n31\nWString\n18\n?????Libraries(,):\n0\n32\nWString\n19\nlibpng.lib zlib.lib\n0\n33\nWVList\n0\n-1\n1\n1\n0\n34\nWPickList\n2\n35\nMItem\n3\n*.c\n36\nWString\n4\nCOBJ\n37\nWVList\n2\n38\nMVState\n39\nWString\n3\nWCC\n40\nWString\n25\nn????Include directories:\n1\n41\nWString\n39\n\"$(%zlib);$(%watcom)/h;$(%watcom)/h/nt\"\n0\n42\nMVState\n43\nWString\n3\nWCC\n44\nWString\n25\nn????Include directories:\n0\n45\nWString\n39\n\"$(%zlib);$(%watcom)/h;$(%watcom)/h/nt\"\n0\n46\nWVList\n0\n-1\n1\n1\n0\n47\nMItem\n33\n..\\..\\contrib\\libtests\\pngvalid.c\n48\nWString\n4\nCOBJ\n49\nWVList\n0\n50\nWVList\n0\n35\n1\n1\n0\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/visualc71/PRJ0041.mak",
    "content": "# Prevent \"Cannot find missing dependency...\" warnings while compiling\n# pngwin.rc (PRJ0041).\n\nall: $(IntDir)\\alloc.h \\\n\t $(IntDir)\\fp.h \\\n\t $(IntDir)\\m68881.h \\\n\t $(IntDir)\\mem.h \\\n\t $(IntDir)\\pngusr.h \\\n\t $(IntDir)\\strings.h \\\n\t $(IntDir)\\unistd.h \\\n\t $(IntDir)\\unixio.h\n\n$(IntDir)\\alloc.h \\\n$(IntDir)\\fp.h \\\n$(IntDir)\\m68881.h \\\n$(IntDir)\\mem.h \\\n$(IntDir)\\pngusr.h \\\n$(IntDir)\\strings.h \\\n$(IntDir)\\unistd.h \\\n$(IntDir)\\unixio.h:\n\t@!echo.>$@\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/visualc71/README.txt",
    "content": "Microsoft Developer Studio Project File, Format Version 7.10 for libpng.\n\nCopyright (C) 2004 Simon-Pierre Cadieux.\n\nThis code is released under the libpng license.\nFor conditions of distribution and use, see copyright notice in png.h\n\nNOTE: This project will be removed from libpng-1.5.0.  It has\nbeen replaced with the \"vstudio\" project.\n\nAssumptions:\n* The libpng source files are in ..\\..\n* The zlib source files are in ..\\..\\..\\zlib\n* The zlib project file is in . /* Warning: This is until the zlib project\n  files get intergrated into the next zlib release. The final zlib project\n  directory will then be ..\\..\\..\\zlib\\projects\\visualc71. */\n\nTo use:\n\n1) On the main menu, select \"File | Open Solution\".\n   Open \"libpng.sln\".\n\n2) Display the Solution Explorer view (Ctrl+Alt+L)\n\n3) Set one of the project as the StartUp project. If you just want to build the\n   binaries set \"libpng\" as the startup project (Select \"libpng\" tree view\n   item + Project | Set as StartUp project). If you want to build and test the\n   binaries set it to \"pngtest\" (Select \"pngtest\" tree view item +\n   Project | Set as StartUp project)\n\n4) Select \"Build | Configuration Manager...\".\n   Choose the configuration you wish to build.\n\n5) Select \"Build | Clean Solution\".\n\n6) Select \"Build | Build Solution (Ctrl-Shift-B)\"\n\nThis project builds the libpng binaries as follows:\n\n* Win32_DLL_Release\\libpng16.dll      DLL build\n* Win32_DLL_Debug\\libpng16d.dll       DLL build (debug version)\n* Win32_DLL_VB\\libpng16vb.dll         DLL build for Visual Basic, using stdcall\n* Win32_LIB_Release\\libpng.lib        static build\n* Win32_LIB_Debug\\libpngd.lib         static build (debug version)\n\nNotes:\n\nIf you change anything in the source files, or select different compiler\nsettings, please change the DLL name to something different than any of\nthe above names. Also, make sure that in your \"pngusr.h\" you define\nPNG_USER_PRIVATEBUILD and PNG_USER_DLLFNAME_POSTFIX according to the\ninstructions provided in \"pngconf.h\".\n\nAll DLLs built by this project use the Microsoft dynamic C runtime library\nMSVCR71.DLL (MSVCR71D.DLL for debug versions).  If you distribute any of the\nabove mentioned libraries you may have to include this DLL in your package.\nFor a list of files that are redistributable in Visual Studio see\n$(VCINSTALLDIR)\\redist.txt.\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/visualc71/README_zlib.txt",
    "content": "/* WARNING: This file was put in the LibPNG distribution for convenience only.\n            It is expected to be part of the next zlib release under\n            \"projects\\visualc71\\README.txt.\" */\n\nMicrosoft Developer Studio Project File, Format Version 7.10 for zlib.\n\nCopyright (C) 2004 Simon-Pierre Cadieux.\nCopyright (C) 2004 Cosmin Truta.\n\nThis code is released under the libpng license.\nFor conditions of distribution and use, see copyright notice in zlib.h.\n\nNOTE: This project will be removed from libpng-1.5.0.  It has\nbeen replaced with the \"vstudio\" project.\n\nTo use:\n\n1) On the main menu, select \"File | Open Solution\".\n   Open \"zlib.sln\".\n\n2) Display the Solution Explorer view (Ctrl+Alt+L)\n\n3) Set one of the project as the StartUp project. If you just want to build the\n   binaries set \"zlib\" as the startup project (Select \"zlib\" tree view item +\n   Project | Set as StartUp project). If you want to build and test the\n   binaries set it to \"example\" (Select \"example\" tree view item + Project |\n   Set as StartUp project), If you want to build the minigzip utility set it to\n   \"minigzip\" (Select \"minigzip\" tree view item + Project | Set as StartUp\n   project\n\n4) Select \"Build | Configuration Manager...\".\n   Choose the configuration you wish to build.\n\n5) Select \"Build | Clean Solution\".\n\n6) Select \"Build | Build Solution (Ctrl-Shift-B)\"\n\nThis project builds the zlib binaries as follows:\n\n* Win32_DLL_Release\\zlib1.dll       DLL build\n* Win32_DLL_Debug\\zlib1d.dll        DLL build (debug version)\n* Win32_LIB_Release\\zlib.lib        static build\n* Win32_LIB_Debug\\zlibd.lib         static build (debug version)\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/visualc71/libpng.sln",
    "content": "Microsoft Visual Studio Solution File, Format Version 8.00\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"libpng\", \"libpng.vcproj\", \"{0008960E-E0DD-41A6-8265-00B31DDB4C21}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{2D4F8105-7D21-454C-9932-B47CAB71A5C0} = {2D4F8105-7D21-454C-9932-B47CAB71A5C0}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"pngtest\", \"pngtest.vcproj\", \"{FD1C2F86-9EEF-47BD-95A4-530917E17FDA}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{0008960E-E0DD-41A6-8265-00B31DDB4C21} = {0008960E-E0DD-41A6-8265-00B31DDB4C21}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"zlib\", \"zlib.vcproj\", \"{2D4F8105-7D21-454C-9932-B47CAB71A5C0}\"\n\tProjectSection(ProjectDependencies) = postProject\n\tEndProjectSection\nEndProject\nGlobal\n\tGlobalSection(SolutionConfiguration) = preSolution\n\t\tDLL Debug = DLL Debug\n\t\tDLL Release = DLL Release\n\t\tDLL VB = DLL VB\n\t\tLIB Debug = LIB Debug\n\t\tLIB Release = LIB Release\n\tEndGlobalSection\n\tGlobalSection(ProjectConfiguration) = postSolution\n\t\t{0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL Debug.ActiveCfg = DLL Debug|Win32\n\t\t{0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL Debug.Build.0 = DLL Debug|Win32\n\t\t{0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL Release.ActiveCfg = DLL Release|Win32\n\t\t{0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL Release.Build.0 = DLL Release|Win32\n\t\t{0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL VB.ActiveCfg = DLL VB|Win32\n\t\t{0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL VB.Build.0 = DLL VB|Win32\n\t\t{0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB Debug.ActiveCfg = LIB Debug|Win32\n\t\t{0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB Debug.Build.0 = LIB Debug|Win32\n\t\t{0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB Release.ActiveCfg = LIB Release|Win32\n\t\t{0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB Release.Build.0 = LIB Release|Win32\n\t\t{FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL Debug.ActiveCfg = DLL Debug|Win32\n\t\t{FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL Debug.Build.0 = DLL Debug|Win32\n\t\t{FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL Release.ActiveCfg = DLL Release|Win32\n\t\t{FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL Release.Build.0 = DLL Release|Win32\n\t\t{FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL VB.ActiveCfg = DLL VB|Win32\n\t\t{FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL VB.Build.0 = DLL VB|Win32\n\t\t{FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.LIB Debug.ActiveCfg = LIB Debug|Win32\n\t\t{FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.LIB Debug.Build.0 = LIB Debug|Win32\n\t\t{FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.LIB Release.ActiveCfg = LIB Release|Win32\n\t\t{FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.LIB Release.Build.0 = LIB Release|Win32\n\t\t{2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL Debug.ActiveCfg = DLL Debug|Win32\n\t\t{2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL Debug.Build.0 = DLL Debug|Win32\n\t\t{2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL Release.ActiveCfg = DLL Release|Win32\n\t\t{2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL Release.Build.0 = DLL Release|Win32\n\t\t{2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL VB.ActiveCfg = DLL Release|Win32\n\t\t{2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL VB.Build.0 = DLL Release|Win32\n\t\t{2D4F8105-7D21-454C-9932-B47CAB71A5C0}.LIB Debug.ActiveCfg = LIB Debug|Win32\n\t\t{2D4F8105-7D21-454C-9932-B47CAB71A5C0}.LIB Debug.Build.0 = LIB Debug|Win32\n\t\t{2D4F8105-7D21-454C-9932-B47CAB71A5C0}.LIB Release.ActiveCfg = LIB Release|Win32\n\t\t{2D4F8105-7D21-454C-9932-B47CAB71A5C0}.LIB Release.Build.0 = LIB Release|Win32\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityAddIns) = postSolution\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/visualc71/libpng.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n<VisualStudioProject\n\tProjectType=\"Visual C++\"\n\tVersion=\"7.10\"\n\tName=\"libpng\"\n\tRootNamespace=\"libpng\">\n\t<Platforms>\n\t\t<Platform\n\t\t\tName=\"Win32\"/>\n\t</Platforms>\n\t<Configurations>\n\t\t<Configuration\n\t\t\tName=\"DLL Release|Win32\"\n\t\t\tOutputDirectory=\".\\Win32_DLL_Release\"\n\t\t\tIntermediateDirectory=\".\\Win32_DLL_Release\"\n\t\t\tConfigurationType=\"2\">\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..;..\\..\\..\\zlib\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;PNG_BUILD_DLL;ZLIB_DLL;_CRT_SECURE_NO_WARNINGS\"\n\t\t\t\tStringPooling=\"TRUE\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tEnableFunctionLevelLinking=\"TRUE\"\n\t\t\t\tUsePrecompiledHeader=\"3\"\n\t\t\t\tPrecompiledHeaderThrough=\"pngpriv.h\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tCompileAs=\"0\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)/libpng16.dll\"\n\t\t\t\tLinkIncremental=\"1\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t\tCommandLine=\"copy ..\\..\\scripts\\pnglibconf.h.prebuilt ..\\..\\pnglibconf.h\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tCulture=\"1033\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..;..\\..\\..\\zlib;$(IntDir)\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"DLL Debug|Win32\"\n\t\t\tOutputDirectory=\".\\Win32_DLL_Debug\"\n\t\t\tIntermediateDirectory=\".\\Win32_DLL_Debug\"\n\t\t\tConfigurationType=\"2\">\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..;..\\..\\..\\zlib\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;DEBUG;PNG_DEBUG=1;PNG_BUILD_DLL;ZLIB_DLL;_CRT_SECURE_NO_WARNINGS\"\n\t\t\t\tBasicRuntimeChecks=\"3\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tUsePrecompiledHeader=\"3\"\n\t\t\t\tPrecompiledHeaderThrough=\"pngpriv.h\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDebugInformationFormat=\"4\"\n\t\t\t\tCompileAs=\"0\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)/libpng16d.dll\"\n\t\t\t\tGenerateDebugInformation=\"TRUE\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t\tCommandLine=\"copy ..\\..\\scripts\\pnglibconf.h.prebuilt ..\\..\\pnglibconf.h\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tPreprocessorDefinitions=\"_DEBUG,PNG_DEBUG=1\"\n\t\t\t\tCulture=\"1033\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..;..\\..\\..\\zlib;$(IntDir)\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"DLL VB|Win32\"\n\t\t\tOutputDirectory=\".\\Win32_DLL_VB\"\n\t\t\tIntermediateDirectory=\".\\Win32_DLL_VB\"\n\t\t\tConfigurationType=\"2\">\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..;..\\..\\..\\zlib\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;PNG_BUILD_DLL;ZLIB_DLL;PNGAPI=__stdcall;PNG_NO_MODULEDEF;PNG_LIBPNG_SPECIALBUILD;PNG_USER_PRIVATEBUILD;_CRT_SECURE_NO_WARNINGS\"\n\t\t\t\tStringPooling=\"TRUE\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tEnableFunctionLevelLinking=\"TRUE\"\n\t\t\t\tUsePrecompiledHeader=\"3\"\n\t\t\t\tPrecompiledHeaderThrough=\"pngpriv.h\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tCompileAs=\"0\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)/libpng16vb.dll\"\n\t\t\t\tLinkIncremental=\"1\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t\tCommandLine=\"copy ..\\..\\scripts\\pnglibconf.h.prebuilt ..\\..\\pnglibconf.h\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tAdditionalOptions=\"/d PNG_NO_PEDANTIC_WARNINGS /d PNG_LIBPNG_DLLFNAME_POSTFIX=&quot;&quot;&quot;&quot;VB&quot;&quot;&quot;&quot; /d PNG_LIBPNG_SPECIALBUILD=&quot;&quot;&quot;&quot;__stdcall calling convention used for exported functions&quot;&quot;&quot;&quot;\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tCulture=\"1033\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..;..\\..\\..\\zlib;$(IntDir)\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"LIB Release|Win32\"\n\t\t\tOutputDirectory=\".\\Win32_LIB_Release\"\n\t\t\tIntermediateDirectory=\".\\Win32_LIB_Release\"\n\t\t\tConfigurationType=\"4\">\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..;..\\..\\..\\zlib\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS\"\n\t\t\t\tStringPooling=\"TRUE\"\n\t\t\t\tRuntimeLibrary=\"0\"\n\t\t\t\tEnableFunctionLevelLinking=\"TRUE\"\n\t\t\t\tUsePrecompiledHeader=\"3\"\n\t\t\t\tPrecompiledHeaderThrough=\"pngpriv.h\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tCompileAs=\"0\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLibrarianTool\"\n\t\t\t\tOutputFile=\"$(OutDir)/libpng.lib\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t\tCommandLine=\"copy ..\\..\\scripts\\pnglibconf.h.prebuilt ..\\..\\pnglibconf.h\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"LIB Debug|Win32\"\n\t\t\tOutputDirectory=\".\\Win32_LIB_Debug\"\n\t\t\tIntermediateDirectory=\".\\Win32_LIB_Debug\"\n\t\t\tConfigurationType=\"4\">\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..;..\\..\\..\\zlib\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;DEBUG;PNG_DEBUG=1;_CRT_SECURE_NO_WARNINGS\"\n\t\t\t\tBasicRuntimeChecks=\"3\"\n\t\t\t\tRuntimeLibrary=\"1\"\n\t\t\t\tUsePrecompiledHeader=\"3\"\n\t\t\t\tPrecompiledHeaderThrough=\"pngpriv.h\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDebugInformationFormat=\"4\"\n\t\t\t\tCompileAs=\"0\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLibrarianTool\"\n\t\t\t\tOutputFile=\"$(OutDir)/libpngd.lib\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t\tCommandLine=\"copy ..\\..\\scripts\\pnglibconf.h.prebuilt ..\\..\\pnglibconf.h\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\n\t\t</Configuration>\n\t</Configurations>\n\t<References>\n\t</References>\n\t<Files>\n\t\t<Filter\n\t\t\tName=\"Source Files\"\n\t\t\tFilter=\"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat\">\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\png.c\">\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"DLL Release|Win32\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tUsePrecompiledHeader=\"0\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"DLL Debug|Win32\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tUsePrecompiledHeader=\"0\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"DLL VB|Win32\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tUsePrecompiledHeader=\"0\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Release|Win32\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tUsePrecompiledHeader=\"0\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Debug|Win32\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tUsePrecompiledHeader=\"0\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngerror.c\">\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"DLL Release|Win32\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tUsePrecompiledHeader=\"1\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"DLL Debug|Win32\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tUsePrecompiledHeader=\"1\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"DLL VB|Win32\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tUsePrecompiledHeader=\"1\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Release|Win32\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tUsePrecompiledHeader=\"1\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Debug|Win32\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tUsePrecompiledHeader=\"1\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngget.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngmem.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngpread.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngread.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngrio.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngrtran.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngrutil.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngset.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngtrans.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngwio.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngwrite.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngwtran.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngwutil.c\">\n\t\t\t</File>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Header Files\"\n\t\t\tFilter=\"h;hpp;hxx;hm;inl\">\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\png.h\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngconf.h\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngpriv.h\">\n\t\t\t</File>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Resource Files\"\n\t\t\tFilter=\"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\">\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\scripts\\pngwin.rc\">\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Release|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCResourceCompilerTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Debug|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCResourceCompilerTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t</File>\n\t\t</Filter>\n\t\t<File\n\t\t\tRelativePath=\".\\PRJ0041.mak\">\n\t\t\t<FileConfiguration\n\t\t\t\tName=\"DLL Release|Win32\">\n\t\t\t\t<Tool\n\t\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t\t\tDescription=\"Create dummy include files to prevent &quot;Cannot find missing dependency...&quot; warnings.\"\n\t\t\t\t\tCommandLine=\"nmake -f PRJ0041.mak IntDir=$(IntDir)\"\n\t\t\t\t\tOutputs=\"$(IntDir)\\alloc.h;$(IntDir)\\fp.h;$(IntDir)\\m68881.h;$(IntDir)\\mem.h;$(IntDir)\\pngusr.h;$(IntDir)\\strings.h;$(IntDir)\\unistd.h;$(IntDir)\\unixio.h\"/>\n\t\t\t</FileConfiguration>\n\t\t\t<FileConfiguration\n\t\t\t\tName=\"DLL Debug|Win32\">\n\t\t\t\t<Tool\n\t\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t\t\tDescription=\"Create dummy include files to prevent &quot;Cannot find missing dependency...&quot; warnings.\"\n\t\t\t\t\tCommandLine=\"nmake -f PRJ0041.mak IntDir=$(IntDir)\"\n\t\t\t\t\tOutputs=\"$(IntDir)\\alloc.h;$(IntDir)\\fp.h;$(IntDir)\\m68881.h;$(IntDir)\\mem.h;$(IntDir)\\pngusr.h;$(IntDir)\\strings.h;$(IntDir)\\unistd.h;$(IntDir)\\unixio.h\"/>\n\t\t\t</FileConfiguration>\n\t\t\t<FileConfiguration\n\t\t\t\tName=\"DLL VB|Win32\">\n\t\t\t\t<Tool\n\t\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t\t\tDescription=\"Create dummy include files to prevent &quot;Cannot find missing dependency...&quot; warnings.\"\n\t\t\t\t\tCommandLine=\"nmake -f PRJ0041.mak IntDir=$(IntDir)\"\n\t\t\t\t\tOutputs=\"$(IntDir)\\alloc.h;$(IntDir)\\fp.h;$(IntDir)\\m68881.h;$(IntDir)\\mem.h;$(IntDir)\\pngusr.h;$(IntDir)\\strings.h;$(IntDir)\\unistd.h;$(IntDir)\\unixio.h\"/>\n\t\t\t</FileConfiguration>\n\t\t</File>\n\t\t<File\n\t\t\tRelativePath=\"README.txt\">\n\t\t</File>\n\t</Files>\n\t<Globals>\n\t</Globals>\n</VisualStudioProject>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/visualc71/pngtest.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n<VisualStudioProject\n\tProjectType=\"Visual C++\"\n\tVersion=\"7.10\"\n\tName=\"pngtest\"\n\tRootNamespace=\"pngtest\">\n\t<Platforms>\n\t\t<Platform\n\t\t\tName=\"Win32\"/>\n\t</Platforms>\n\t<Configurations>\n\t\t<Configuration\n\t\t\tName=\"DLL Release|Win32\"\n\t\t\tOutputDirectory=\".\\Win32_DLL_Release\\Test\"\n\t\t\tIntermediateDirectory=\".\\Win32_DLL_Release\\Test\"\n\t\t\tConfigurationType=\"1\">\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\scripts;..\\..\\..\\zlib\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;PNG_DLL;PNG_NO_STDIO;_CRT_SECURE_NO_WARNINGS\"\n\t\t\t\tStringPooling=\"TRUE\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tEnableFunctionLevelLinking=\"TRUE\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tCompileAs=\"0\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t\tDescription=\"Testing...\"\n\t\t\t\tCommandLine=\"set path=$(OutDir)\\..;$(OutDir)\\..\\ZLib\n$(TargetPath) ..\\..\\pngtest.png $(IntDir)\\pngout.png\"\n\t\t\t\tOutputs=\"$(IntDir)\\pngout.png\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)/pngtest.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tSubSystem=\"1\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"DLL Debug|Win32\"\n\t\t\tOutputDirectory=\".\\Win32_DLL_Debug\\Test\"\n\t\t\tIntermediateDirectory=\".\\Win32_DLL_Debug\\Test\"\n\t\t\tConfigurationType=\"1\">\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\scripts;..\\..\\..\\zlib\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;PNG_DLL;PNG_NO_STDIO;_CRT_SECURE_NO_WARNINGS\"\n\t\t\t\tBasicRuntimeChecks=\"3\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDebugInformationFormat=\"4\"\n\t\t\t\tCompileAs=\"0\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t\tDescription=\"Testing...\"\n\t\t\t\tCommandLine=\"set path=$(OutDir)\\..;$(OutDir)\\..\\ZLib\n$(TargetPath) ..\\..\\pngtest.png $(IntDir)\\pngout.png\"\n\t\t\t\tOutputs=\"$(IntDir)\\pngout.png\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)/pngtest.exe\"\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tTargetMachine=\"1\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"DLL VB|Win32\"\n\t\t\tOutputDirectory=\".\\Win32_DLL_VB\\Test\"\n\t\t\tIntermediateDirectory=\".\\Win32_DLL_VB\\Test\"\n\t\t\tConfigurationType=\"1\">\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\scripts;..\\..\\..\\zlib\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;PNG_DLL;PNG_NO_STDIO;PNGAPI=__stdcall;PNG_USER_PRIVATEBUILD;_CRT_SECURE_NO_WARNINGS\"\n\t\t\t\tStringPooling=\"TRUE\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tEnableFunctionLevelLinking=\"TRUE\"\n\t\t\t\tWarningLevel=\"2\"\n\t\t\t\tCallingConvention=\"2\"\n\t\t\t\tCompileAs=\"0\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t\tDescription=\"Testing...\"\n\t\t\t\tCommandLine=\"set path=$(OutDir)\\..;$(OutDir)\\..\\..\\Win32_DLL_Release\\ZLib\n$(TargetPath) ..\\..\\pngtest.png $(IntDir)\\pngout.png\"\n\t\t\t\tOutputs=\"$(IntDir)\\pngout.png\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)/pngtest.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tIgnoreDefaultLibraryNames=\"$(IntDir)\\libpng16b.lib\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tTargetMachine=\"1\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"LIB Release|Win32\"\n\t\t\tOutputDirectory=\".\\Win32_LIB_Release\\Test\"\n\t\t\tIntermediateDirectory=\".\\Win32_LIB_Release\\Test\"\n\t\t\tConfigurationType=\"1\">\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\scripts;..\\..\\..\\zlib\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS\"\n\t\t\t\tStringPooling=\"TRUE\"\n\t\t\t\tRuntimeLibrary=\"0\"\n\t\t\t\tEnableFunctionLevelLinking=\"TRUE\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tCompileAs=\"0\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t\tDescription=\"Testing...\"\n\t\t\t\tCommandLine=\"set path=$(OutDir)\\..;$(OutDir)\\..\\ZLib\n$(TargetPath) ..\\..\\pngtest.png $(IntDir)\\pngout.png\"\n\t\t\t\tOutputs=\"$(IntDir)\\pngout.png\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)/pngtest.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tTargetMachine=\"1\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"LIB Debug|Win32\"\n\t\t\tOutputDirectory=\".\\Win32_LIB_Debug\\Test\"\n\t\t\tIntermediateDirectory=\".\\Win32_LIB_Debug\\Test\"\n\t\t\tConfigurationType=\"1\">\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\scripts;..\\..\\..\\zlib\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS\"\n\t\t\t\tBasicRuntimeChecks=\"3\"\n\t\t\t\tRuntimeLibrary=\"1\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDebugInformationFormat=\"4\"\n\t\t\t\tCompileAs=\"0\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t\tDescription=\"Testing...\"\n\t\t\t\tCommandLine=\"set path=$(OutDir)\\..;$(OutDir)\\..\\ZLib\n$(TargetPath) ..\\..\\pngtest.png $(IntDir)\\pngout.png\"\n\t\t\t\tOutputs=\"$(IntDir)\\pngout.png\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)/pngtest.exe\"\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tTargetMachine=\"1\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\n\t\t</Configuration>\n\t</Configurations>\n\t<References>\n\t</References>\n\t<Files>\n\t\t<Filter\n\t\t\tName=\"Source Files\"\n\t\t\tFilter=\"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat\">\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\pngtest.c\">\n\t\t\t</File>\n\t\t</Filter>\n\t</Files>\n\t<Globals>\n\t</Globals>\n</VisualStudioProject>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/visualc71/zlib.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n<VisualStudioProject\n\tProjectType=\"Visual C++\"\n\tVersion=\"7.10\"\n\tName=\"zlib\">\n\t<Platforms>\n\t\t<Platform\n\t\t\tName=\"Win32\"/>\n\t</Platforms>\n\t<Configurations>\n\t\t<Configuration\n\t\t\tName=\"DLL Release|Win32\"\n\t\t\tOutputDirectory=\".\\Win32_DLL_Release\\ZLib\"\n\t\t\tIntermediateDirectory=\".\\Win32_DLL_Release\\ZLib\"\n\t\t\tConfigurationType=\"2\">\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..\\zlib\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS\"\n\t\t\t\tStringPooling=\"TRUE\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tEnableFunctionLevelLinking=\"TRUE\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tCompileAs=\"1\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlib1.dll\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tModuleDefinitionFile=\"..\\..\\..\\zlib\\win32\\zlib.def\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tCulture=\"1033\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"DLL Debug|Win32\"\n\t\t\tOutputDirectory=\".\\Win32_DLL_Debug\\ZLib\"\n\t\t\tIntermediateDirectory=\".\\Win32_DLL_Debug\\ZLib\"\n\t\t\tConfigurationType=\"2\">\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..\\zlib\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS\"\n\t\t\t\tBasicRuntimeChecks=\"3\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDebugInformationFormat=\"4\"\n\t\t\t\tCompileAs=\"1\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlib1d.dll\"\n\t\t\t\tModuleDefinitionFile=\"..\\..\\..\\zlib\\win32\\zlib.def\"\n\t\t\t\tGenerateDebugInformation=\"TRUE\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tPreprocessorDefinitions=\"_DEBUG\"\n\t\t\t\tCulture=\"1033\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"LIB Release|Win32\"\n\t\t\tOutputDirectory=\".\\Win32_LIB_Release\\ZLib\"\n\t\t\tIntermediateDirectory=\".\\Win32_LIB_Release\\ZLib\"\n\t\t\tConfigurationType=\"4\">\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..\\zlib\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS\"\n\t\t\t\tStringPooling=\"TRUE\"\n\t\t\t\tRuntimeLibrary=\"0\"\n\t\t\t\tEnableFunctionLevelLinking=\"TRUE\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tCompileAs=\"1\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLibrarianTool\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlib.lib\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"LIB Debug|Win32\"\n\t\t\tOutputDirectory=\".\\Win32_LIB_Debug\\ZLib\"\n\t\t\tIntermediateDirectory=\".\\Win32_LIB_Debug\\ZLib\"\n\t\t\tConfigurationType=\"4\">\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..\\zlib\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS\"\n\t\t\t\tBasicRuntimeChecks=\"3\"\n\t\t\t\tRuntimeLibrary=\"1\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDebugInformationFormat=\"4\"\n\t\t\t\tCompileAs=\"1\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLibrarianTool\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibd.lib\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\n\t\t</Configuration>\n\t</Configurations>\n\t<References>\n\t</References>\n\t<Files>\n\t\t<Filter\n\t\t\tName=\"Source Files\"\n\t\t\tFilter=\"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat\">\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\adler32.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\compress.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\crc32.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\deflate.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\gzlib.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\gzclose.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\gzread.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\gzwrite.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\infback.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\inffast.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\inflate.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\inftrees.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\trees.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\uncompr.c\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\win32\\zlib.def\">\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Release|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Debug|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\zutil.c\">\n\t\t\t</File>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Header Files\"\n\t\t\tFilter=\"h;hpp;hxx;hm;inl\">\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\crc32.h\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\deflate.h\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\inffast.h\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\inffixed.h\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\inflate.h\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\inftrees.h\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\trees.h\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\zconf.h\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\zlib.h\">\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\zutil.h\">\n\t\t\t</File>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Resource Files\"\n\t\t\tFilter=\"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\">\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\win32\\zlib1.rc\">\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Release|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCResourceCompilerTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Debug|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCResourceCompilerTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t</File>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Assembler Files (Unsupported)\"\n\t\t\tFilter=\"asm;obj;c;cpp;cxx;h;hpp;hxx\">\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\contrib\\masmx86\\gvmat32.asm\">\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"DLL Release|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"DLL Debug|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Release|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Debug|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\contrib\\masmx86\\gvmat32c.c\">\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"DLL Release|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"DLL Debug|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Release|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Debug|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib\\contrib\\masmx86\\inffas32.asm\">\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"DLL Release|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"DLL Debug|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Release|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"LIB Debug|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"TRUE\">\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCustomBuildTool\"/>\n\t\t\t\t</FileConfiguration>\n\t\t\t</File>\n\t\t</Filter>\n\t\t<File\n\t\t\tRelativePath=\"README.txt\">\n\t\t</File>\n\t</Files>\n\t<Globals>\n\t</Globals>\n</VisualStudioProject>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/vstudio/README.txt",
    "content": "\nVisualStudio instructions\n\nlibpng version 1.6.22beta03 - February 8, 2016\n\nCopyright (c) 2010,2013,2015 Glenn Randers-Pehrson\n\nThis code is released under the libpng license.\nFor conditions of distribution and use, see the disclaimer\nand license in png.h\n\nThis directory  contains support for building libpng under MicroSoft\nVisualStudio 2010.  It may also work under later versions of VisualStudio.\nYou should be familiar with VisualStudio before using this directory.\n\nInitial preparations\n====================\nYou must enter some information in zlib.props before attempting to build\nwith this 'solution'.  Please read and edit zlib.props first.  You will\nprobably not be familiar with the contents of zlib.props - do not worry,\nit is mostly harmless.\n\nThis is all you need to do to build the 'release' and 'release library'\nconfigurations.\n\nDebugging\n=========\nThe release configurations default to /Ox optimization.  Full debugging\ninformation is produced (in the .pdb), but if you encounter a problem the\noptimization may make it difficult to debug.  Simply rebuild with a lower\noptimization level (e.g. /Od.)\n\nLinking your application\n========================\nNormally you should link against the 'release' configuration.  This builds a\nDLL for libpng with the default runtime options used by Visual Studio 2010.\nIn particular the runtime library is the \"MultiThreaded DLL\" version.\nIf you use Visual Studio defaults to build your application you will have no\nproblems.\n\nIf you don't use the Visual Studio defaults your application must still be\nbuilt with the default runtime option (/MD).  If, for some reason, it is not\nthen your application will crash inside libpng16.dll as soon as libpng\ntries to read from a file handle you pass in.\n\nIf you do not want to use the DLL, for example for a very small application,\nthe 'release library' configuration may be more appropriate.  This is built\nwith a non-standard runtime library - the \"MultiThreaded\" version.  When you\nbuild your application it must be compiled with this option (/MT), otherwise\nit will not build (if you are lucky) or crash (if you are not.) See the\nWARNING file that is distributed along with this readme.txt.\n\nStop reading here\n=================\nYou have enough information to build a working application.\n\nDebug versions have limited support\n===================================\nThis solution includes limited support for debug versions of libpng.  You\ndo not need these unless your own solution itself uses debug builds (it is\nfar more effective to debug on the release builds, there is no point building\na special debug build unless you have heap corruption problems that you can't\ntrack down.)\n\nThe debug build of libpng is minimally supported.  Support for debug builds of\nzlib is also minimal.  You really don't want to do this.\n\nWARNING\n=======\nLibpng 1.6.x does not use the default run-time library when building static\nlibrary builds of libpng; instead of the shared DLL runtime it uses a static\nruntime.  If you need to change this make sure to change the setting on all the\nrelevant projects:\n\n    libpng\n    zlib\n    all the test programs\n\nThe runtime library settings for each build are as follows:\n\n               Release        Debug\n    DLL         /MD            /MDd\n    Library     /MT            /MTd\n\nNOTICE that libpng 1.5.x erroneously used /MD for Debug DLL builds; if you used\nthe debug builds in your app and you changed your app to use /MD you will need\nto change it back to /MDd for libpng 1.6.0 and later.\n\nThe Visual Studio 2010 defaults for a Win32 DLL or Static Library project are\nas follows:\n\n                     Release     Debug\n    DLL               /MD         /MDd\n    Static Library    /MD         /MDd\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/vstudio/libpng/libpng.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug Library|Win32\">\n      <Configuration>Debug Library</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release Library|Win32\">\n      <Configuration>Release Library</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{D6973076-9317-4EF2-A0B8-B7A18AC0713E}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>libpng</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(SolutionDir)\\zlib.props\" />\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildBeforeTargets>\n    </CustomBuildBeforeTargets>\n    <TargetName>$(ProjectName)16</TargetName>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildBeforeTargets />\n    <TargetName>$(ProjectName)16</TargetName>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildBeforeTargets>\n    </CustomBuildBeforeTargets>\n    <TargetName>$(ProjectName)16</TargetName>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildBeforeTargets />\n    <TargetName>$(ProjectName)16</TargetName>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <MinimalRebuild>false</MinimalRebuild>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n      <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>\n      <PrecompiledHeaderFile>pngpriv.h</PrecompiledHeaderFile>\n      <BrowseInformation>true</BrowseInformation>\n      <CompileAs>CompileAsC</CompileAs>\n      <StringPooling>true</StringPooling>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <Optimization>Disabled</Optimization>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>zlib.lib</AdditionalDependencies>\n      <Version>16</Version>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <MinimalRebuild>false</MinimalRebuild>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Disabled</Optimization>\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n      <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>\n      <PrecompiledHeaderFile>pngpriv.h</PrecompiledHeaderFile>\n      <BrowseInformation>true</BrowseInformation>\n      <CompileAs>CompileAsC</CompileAs>\n      <StringPooling>true</StringPooling>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n      <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>\n      <PrecompiledHeaderFile>pngpriv.h</PrecompiledHeaderFile>\n      <BrowseInformation>true</BrowseInformation>\n      <CompileAs>CompileAsC</CompileAs>\n      <StringPooling>true</StringPooling>\n      <MinimalRebuild>false</MinimalRebuild>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <Optimization>Full</Optimization>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>zlib.lib</AdditionalDependencies>\n      <Version>16</Version>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n      <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>\n      <PrecompiledHeaderFile>pngpriv.h</PrecompiledHeaderFile>\n      <BrowseInformation>true</BrowseInformation>\n      <CompileAs>CompileAsC</CompileAs>\n      <StringPooling>true</StringPooling>\n      <MinimalRebuild>false</MinimalRebuild>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <Optimization>Full</Optimization>\n      <WholeProgramOptimization>true</WholeProgramOptimization>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\png.c\">\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\">Create</PrecompiledHeader>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\pngerror.c\" />\n    <ClCompile Include=\"..\\..\\..\\pngget.c\" />\n    <ClCompile Include=\"..\\..\\..\\pngmem.c\" />\n    <ClCompile Include=\"..\\..\\..\\pngpread.c\" />\n    <ClCompile Include=\"..\\..\\..\\pngread.c\" />\n    <ClCompile Include=\"..\\..\\..\\pngrio.c\" />\n    <ClCompile Include=\"..\\..\\..\\pngrtran.c\" />\n    <ClCompile Include=\"..\\..\\..\\pngrutil.c\" />\n    <ClCompile Include=\"..\\..\\..\\pngset.c\" />\n    <ClCompile Include=\"..\\..\\..\\pngtrans.c\" />\n    <ClCompile Include=\"..\\..\\..\\pngwio.c\" />\n    <ClCompile Include=\"..\\..\\..\\pngwrite.c\" />\n    <ClCompile Include=\"..\\..\\..\\pngwtran.c\" />\n    <ClCompile Include=\"..\\..\\..\\pngwutil.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"..\\..\\..\\scripts\\pngwin.rc\">\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\">true</ExcludedFromBuild>\n    </ResourceCompile>\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/vstudio/pnglibconf/pnglibconf.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{EB33566E-DA7F-4D28-9077-88C0B7C77E35}</ProjectGuid>\n    <RootNamespace>pnglibconf</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(SolutionDir)\\zlib.props\" />\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <CustomBuildBeforeTargets>Build</CustomBuildBeforeTargets>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <CustomBuildStep>\n      <Command>copy ..\\..\\..\\scripts\\pnglibconf.h.prebuilt ..\\..\\..\\pnglibconf.h</Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Message>Generating pnglibconf.h</Message>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>..\\..\\..\\pnglibconf.h</Outputs>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Inputs>..\\..\\..\\scripts\\pnglibconf.h.prebuilt</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/vstudio/pngstest/pngstest.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug Library|Win32\">\n      <Configuration>Debug Library</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release Library|Win32\">\n      <Configuration>Release Library</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{277AC57F-313B-4D06-B119-A3CDB672D2FF}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>pngstest</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(SolutionDir)\\zlib.props\" />\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <MinimalRebuild>false</MinimalRebuild>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Disabled</Optimization>\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <StringPooling>true</StringPooling>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <BrowseInformation>true</BrowseInformation>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>libpng16.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing libpng simplified API test program</Message>\n      <Command>\"$(OutDir)pngstest.exe\" --strict --log --touch \"$(IntDir)pngstest.out\" ../../../contrib/pngsuite/basn0g01.png ../../../contrib/pngsuite/basn0g02.png ../../../contrib/pngsuite/basn0g04.png ../../../contrib/pngsuite/basn0g08.png ../../../contrib/pngsuite/basn0g16.png ../../../contrib/pngsuite/basn2c08.png ../../../contrib/pngsuite/basn2c16.png ../../../contrib/pngsuite/basn3p01.png ../../../contrib/pngsuite/basn3p02.png ../../../contrib/pngsuite/basn3p04.png ../../../contrib/pngsuite/basn3p08.png ../../../contrib/pngsuite/basn4a08.png ../../../contrib/pngsuite/basn4a16.png ../../../contrib/pngsuite/basn6a08.png ../../../contrib/pngsuite/basn6a16.png ../../../contrib/pngsuite/ftbbn0g01.png ../../../contrib/pngsuite/ftbbn0g02.png ../../../contrib/pngsuite/ftbbn0g04.png ../../../contrib/pngsuite/ftbbn2c16.png ../../../contrib/pngsuite/ftbbn3p08.png ../../../contrib/pngsuite/ftbgn2c16.png ../../../contrib/pngsuite/ftbgn3p08.png ../../../contrib/pngsuite/ftbrn2c08.png ../../../contrib/pngsuite/ftbwn0g16.png ../../../contrib/pngsuite/ftbwn3p08.png ../../../contrib/pngsuite/ftbyn3p08.png ../../../contrib/pngsuite/ftp0n0g08.png ../../../contrib/pngsuite/ftp0n2c08.png ../../../contrib/pngsuite/ftp0n3p08.png ../../../contrib/pngsuite/ftp1n3p08.png</Command>\n      <Outputs>$(IntDir)pngstest.out</Outputs>\n      <Inputs>$(OutDir)pngstest.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <MinimalRebuild>false</MinimalRebuild>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Disabled</Optimization>\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <StringPooling>true</StringPooling>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <BrowseInformation>true</BrowseInformation>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>libpng16.lib;zlib.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing libpng simplified API test program</Message>\n      <Command>\"$(OutDir)pngstest.exe\" --strict --log --touch \"$(IntDir)pngstest.out\" ../../../contrib/pngsuite/basn0g01.png ../../../contrib/pngsuite/basn0g02.png ../../../contrib/pngsuite/basn0g04.png ../../../contrib/pngsuite/basn0g08.png ../../../contrib/pngsuite/basn0g16.png ../../../contrib/pngsuite/basn2c08.png ../../../contrib/pngsuite/basn2c16.png ../../../contrib/pngsuite/basn3p01.png ../../../contrib/pngsuite/basn3p02.png ../../../contrib/pngsuite/basn3p04.png ../../../contrib/pngsuite/basn3p08.png ../../../contrib/pngsuite/basn4a08.png ../../../contrib/pngsuite/basn4a16.png ../../../contrib/pngsuite/basn6a08.png ../../../contrib/pngsuite/basn6a16.png ../../../contrib/pngsuite/ftbbn0g01.png ../../../contrib/pngsuite/ftbbn0g02.png ../../../contrib/pngsuite/ftbbn0g04.png ../../../contrib/pngsuite/ftbbn2c16.png ../../../contrib/pngsuite/ftbbn3p08.png ../../../contrib/pngsuite/ftbgn2c16.png ../../../contrib/pngsuite/ftbgn3p08.png ../../../contrib/pngsuite/ftbrn2c08.png ../../../contrib/pngsuite/ftbwn0g16.png ../../../contrib/pngsuite/ftbwn3p08.png ../../../contrib/pngsuite/ftbyn3p08.png ../../../contrib/pngsuite/ftp0n0g08.png ../../../contrib/pngsuite/ftp0n2c08.png ../../../contrib/pngsuite/ftp0n3p08.png ../../../contrib/pngsuite/ftp1n3p08.png</Command>\n      <Outputs>$(IntDir)pngstest.out</Outputs>\n      <Inputs>$(OutDir)pngstest.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Full</Optimization>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <StringPooling>true</StringPooling>\n      <MinimalRebuild>false</MinimalRebuild>\n      <BrowseInformation>true</BrowseInformation>\n      <WholeProgramOptimization>true</WholeProgramOptimization>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>libpng16.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing libpng simplified API test program</Message>\n      <Command>\"$(OutDir)pngstest.exe\" --strict --log --touch \"$(IntDir)pngstest.out\" ../../../contrib/pngsuite/basn0g01.png ../../../contrib/pngsuite/basn0g02.png ../../../contrib/pngsuite/basn0g04.png ../../../contrib/pngsuite/basn0g08.png ../../../contrib/pngsuite/basn0g16.png ../../../contrib/pngsuite/basn2c08.png ../../../contrib/pngsuite/basn2c16.png ../../../contrib/pngsuite/basn3p01.png ../../../contrib/pngsuite/basn3p02.png ../../../contrib/pngsuite/basn3p04.png ../../../contrib/pngsuite/basn3p08.png ../../../contrib/pngsuite/basn4a08.png ../../../contrib/pngsuite/basn4a16.png ../../../contrib/pngsuite/basn6a08.png ../../../contrib/pngsuite/basn6a16.png ../../../contrib/pngsuite/ftbbn0g01.png ../../../contrib/pngsuite/ftbbn0g02.png ../../../contrib/pngsuite/ftbbn0g04.png ../../../contrib/pngsuite/ftbbn2c16.png ../../../contrib/pngsuite/ftbbn3p08.png ../../../contrib/pngsuite/ftbgn2c16.png ../../../contrib/pngsuite/ftbgn3p08.png ../../../contrib/pngsuite/ftbrn2c08.png ../../../contrib/pngsuite/ftbwn0g16.png ../../../contrib/pngsuite/ftbwn3p08.png ../../../contrib/pngsuite/ftbyn3p08.png ../../../contrib/pngsuite/ftp0n0g08.png ../../../contrib/pngsuite/ftp0n2c08.png ../../../contrib/pngsuite/ftp0n3p08.png ../../../contrib/pngsuite/ftp1n3p08.png</Command>\n      <Outputs>$(IntDir)pngstest.out</Outputs>\n      <Inputs>$(OutDir)pngstest.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Full</Optimization>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <StringPooling>true</StringPooling>\n      <MinimalRebuild>false</MinimalRebuild>\n      <BrowseInformation>true</BrowseInformation>\n      <WholeProgramOptimization>true</WholeProgramOptimization>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>libpng16.lib;zlib.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing libpng simplified API test program</Message>\n      <Command>\"$(OutDir)pngstest.exe\" --strict --log --touch \"$(IntDir)pngstest.out\" ../../../contrib/pngsuite/basn0g01.png ../../../contrib/pngsuite/basn0g02.png ../../../contrib/pngsuite/basn0g04.png ../../../contrib/pngsuite/basn0g08.png ../../../contrib/pngsuite/basn0g16.png ../../../contrib/pngsuite/basn2c08.png ../../../contrib/pngsuite/basn2c16.png ../../../contrib/pngsuite/basn3p01.png ../../../contrib/pngsuite/basn3p02.png ../../../contrib/pngsuite/basn3p04.png ../../../contrib/pngsuite/basn3p08.png ../../../contrib/pngsuite/basn4a08.png ../../../contrib/pngsuite/basn4a16.png ../../../contrib/pngsuite/basn6a08.png ../../../contrib/pngsuite/basn6a16.png ../../../contrib/pngsuite/ftbbn0g01.png ../../../contrib/pngsuite/ftbbn0g02.png ../../../contrib/pngsuite/ftbbn0g04.png ../../../contrib/pngsuite/ftbbn2c16.png ../../../contrib/pngsuite/ftbbn3p08.png ../../../contrib/pngsuite/ftbgn2c16.png ../../../contrib/pngsuite/ftbgn3p08.png ../../../contrib/pngsuite/ftbrn2c08.png ../../../contrib/pngsuite/ftbwn0g16.png ../../../contrib/pngsuite/ftbwn3p08.png ../../../contrib/pngsuite/ftbyn3p08.png ../../../contrib/pngsuite/ftp0n0g08.png ../../../contrib/pngsuite/ftp0n2c08.png ../../../contrib/pngsuite/ftp0n3p08.png ../../../contrib/pngsuite/ftp1n3p08.png</Command>\n      <Outputs>$(IntDir)pngstest.out</Outputs>\n      <Inputs>$(OutDir)pngstest.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\contrib\\libtests\\pngstest.c\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/vstudio/pngtest/pngtest.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug Library|Win32\">\n      <Configuration>Debug Library</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release Library|Win32\">\n      <Configuration>Release Library</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{228BA965-50D5-42B2-8BCF-AFCC227E3C1D}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>pngtest</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(SolutionDir)\\zlib.props\" />\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <MinimalRebuild>false</MinimalRebuild>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Disabled</Optimization>\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <StringPooling>true</StringPooling>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <BrowseInformation>true</BrowseInformation>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>libpng16.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing PNG test program</Message>\n      <Command>\"$(OutDir)pngtest.exe\" ..\\..\\..\\pngtest.png \"$(IntDir)pngout.png\"</Command>\n      <Outputs>$(IntDir)pngout.png</Outputs>\n      <Inputs>..\\..\\..\\pngtest.png;$(OutDir)pngtest.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <MinimalRebuild>false</MinimalRebuild>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Disabled</Optimization>\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <StringPooling>true</StringPooling>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <BrowseInformation>true</BrowseInformation>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>libpng16.lib;zlib.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing PNG test program</Message>\n      <Command>\"$(OutDir)pngtest.exe\" ..\\..\\..\\pngtest.png \"$(IntDir)pngout.png\"</Command>\n      <Outputs>$(IntDir)pngout.png</Outputs>\n      <Inputs>..\\..\\..\\pngtest.png;$(OutDir)pngtest.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Full</Optimization>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <StringPooling>true</StringPooling>\n      <MinimalRebuild>false</MinimalRebuild>\n      <BrowseInformation>true</BrowseInformation>\n      <WholeProgramOptimization>true</WholeProgramOptimization>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>\n      <AdditionalDependencies>libpng16.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing PNG test program</Message>\n      <Command>\"$(OutDir)pngtest.exe\" ..\\..\\..\\pngtest.png \"$(IntDir)pngout.png\"</Command>\n      <Outputs>$(IntDir)pngout.png</Outputs>\n      <Inputs>..\\..\\..\\pngtest.png;$(OutDir)pngtest.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Full</Optimization>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <StringPooling>true</StringPooling>\n      <MinimalRebuild>false</MinimalRebuild>\n      <BrowseInformation>true</BrowseInformation>\n      <WholeProgramOptimization>true</WholeProgramOptimization>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>libpng16.lib;zlib.lib</AdditionalDependencies>\n      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing PNG test program</Message>\n      <Command>$(OutDir)pngtest.exe ..\\..\\..\\pngtest.png $(IntDir)pngout.png</Command>\n      <Command>\"$(OutDir)pngtest.exe\" ..\\..\\..\\pngtest.png \"$(IntDir)pngout.png\"</Command>\n      <Outputs>$(IntDir)pngout.png</Outputs>\n      <Inputs>..\\..\\..\\pngtest.png;$(OutDir)pngtest.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\pngtest.c\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/vstudio/pngunknown/pngunknown.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug Library|Win32\">\n      <Configuration>Debug Library</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release Library|Win32\">\n      <Configuration>Release Library</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{C5D3156C-8C8C-4936-B35F-2B829BA36FEC}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>pngunknown</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(SolutionDir)\\zlib.props\" />\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <MinimalRebuild>false</MinimalRebuild>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Disabled</Optimization>\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <StringPooling>true</StringPooling>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <BrowseInformation>true</BrowseInformation>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>libpng16.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing PNG validation program</Message>\n      <Command>\"$(OutDir)pngunknown.exe\" --strict --default --touch \"$(IntDir)pngunknown.out\" ../../../pngtest.png</Command>\n      <Outputs>$(IntDir)pngunknown.out</Outputs>\n      <Inputs>$(OutDir)pngunknown.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <MinimalRebuild>false</MinimalRebuild>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Disabled</Optimization>\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <StringPooling>true</StringPooling>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <BrowseInformation>true</BrowseInformation>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>libpng16.lib;zlib.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing PNG validation program</Message>\n      <Command>\"$(OutDir)pngunknown.exe\" --strict --default --touch \"$(IntDir)pngunknown.out\" ../../../pngtest.png</Command>\n      <Outputs>$(IntDir)pngunknown.out</Outputs>\n      <Inputs>$(OutDir)pngunknown.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Full</Optimization>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <StringPooling>true</StringPooling>\n      <MinimalRebuild>false</MinimalRebuild>\n      <BrowseInformation>true</BrowseInformation>\n      <WholeProgramOptimization>true</WholeProgramOptimization>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>libpng16.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing PNG validation program</Message>\n      <Command>\"$(OutDir)pngunknown.exe\" --strict --default --touch \"$(IntDir)pngunknown.out\" ../../../pngtest.png</Command>\n      <Outputs>$(IntDir)pngunknown.out</Outputs>\n      <Inputs>$(OutDir)pngunknown.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Full</Optimization>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <StringPooling>true</StringPooling>\n      <MinimalRebuild>false</MinimalRebuild>\n      <BrowseInformation>true</BrowseInformation>\n      <WholeProgramOptimization>true</WholeProgramOptimization>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>libpng16.lib;zlib.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing PNG validation program</Message>\n      <Command>\"$(OutDir)pngunknown.exe\" --strict --default --touch \"$(IntDir)pngunknown.out\" ../../../pngtest.png</Command>\n      <Outputs>$(IntDir)pngunknown.out</Outputs>\n      <Inputs>$(OutDir)pngunknown.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\contrib\\libtests\\pngunknown.c\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/vstudio/pngvalid/pngvalid.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug Library|Win32\">\n      <Configuration>Debug Library</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release Library|Win32\">\n      <Configuration>Release Library</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{9B36B6FE-7FC0-434F-A71F-BBEF8099F1D8}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>pngvalid</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(SolutionDir)\\zlib.props\" />\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildAfterTargets />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <MinimalRebuild>false</MinimalRebuild>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Disabled</Optimization>\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <StringPooling>true</StringPooling>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <BrowseInformation>true</BrowseInformation>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>libpng16.lib;zlib.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing PNG validation program</Message>\n      <Command>\"$(OutDir)pngvalid.exe\" --touch \"$(IntDir)pngvalid.out\"</Command>\n      <Outputs>$(IntDir)pngvalid.out</Outputs>\n      <Inputs>$(OutDir)pngvalid.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level4</WarningLevel>\n      <MinimalRebuild>false</MinimalRebuild>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Disabled</Optimization>\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <StringPooling>true</StringPooling>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <BrowseInformation>true</BrowseInformation>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>libpng16.lib;zlib.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing PNG validation program</Message>\n      <Command>\"$(OutDir)pngvalid.exe\" --touch \"$(IntDir)pngvalid.out\"</Command>\n      <Outputs>$(IntDir)pngvalid.out</Outputs>\n      <Inputs>$(OutDir)pngvalid.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Full</Optimization>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <StringPooling>true</StringPooling>\n      <MinimalRebuild>false</MinimalRebuild>\n      <BrowseInformation>true</BrowseInformation>\n      <WholeProgramOptimization>true</WholeProgramOptimization>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>libpng16.lib;zlib.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing PNG validation program</Message>\n      <Command>\"$(OutDir)pngvalid.exe\" --touch \"$(IntDir)pngvalid.out\"</Command>\n      <Outputs>$(IntDir)pngvalid.out</Outputs>\n      <Inputs>$(OutDir)pngvalid.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level4</WarningLevel>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Full</Optimization>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <FunctionLevelLinking>false</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories>$(ZLibSrcDir);..\\..\\..\\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>\n      <CompileAsManaged>false</CompileAsManaged>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <StringPooling>true</StringPooling>\n      <MinimalRebuild>false</MinimalRebuild>\n      <BrowseInformation>true</BrowseInformation>\n      <WholeProgramOptimization>true</WholeProgramOptimization>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>libpng16.lib;zlib.lib</AdditionalDependencies>\n      <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>\n      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>\n    </Link>\n    <CustomBuildStep>\n      <Message>Executing PNG validation program</Message>\n      <Command>\"$(OutDir)pngvalid.exe\" --touch \"$(IntDir)pngvalid.out\"</Command>\n      <Outputs>$(IntDir)pngvalid.out</Outputs>\n      <Inputs>$(OutDir)pngvalid.exe</Inputs>\n    </CustomBuildStep>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\contrib\\libtests\\pngvalid.c\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/vstudio/vstudio.sln",
    "content": "Microsoft Visual Studio Solution File, Format Version 11.00\n# Visual Studio 2010\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"zlib\", \"zlib\\zlib.vcxproj\", \"{60F89955-91C6-3A36-8000-13C592FEC2DF}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"pnglibconf\", \"pnglibconf\\pnglibconf.vcxproj\", \"{EB33566E-DA7F-4D28-9077-88C0B7C77E35}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"libpng\", \"libpng\\libpng.vcxproj\", \"{D6973076-9317-4EF2-A0B8-B7A18AC0713E}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{60F89955-91C6-3A36-8000-13C592FEC2DF} = {60F89955-91C6-3A36-8000-13C592FEC2DF}\n\t\t{EB33566E-DA7F-4D28-9077-88C0B7C77E35} = {EB33566E-DA7F-4D28-9077-88C0B7C77E35}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"pngtest\", \"pngtest\\pngtest.vcxproj\", \"{228BA965-50D5-42B2-8BCF-AFCC227E3C1D}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{60F89955-91C6-3A36-8000-13C592FEC2DF} = {60F89955-91C6-3A36-8000-13C592FEC2DF}\n\t\t{EB33566E-DA7F-4D28-9077-88C0B7C77E35} = {EB33566E-DA7F-4D28-9077-88C0B7C77E35}\n\t\t{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {D6973076-9317-4EF2-A0B8-B7A18AC0713E}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"pngvalid\", \"pngvalid\\pngvalid.vcxproj\", \"{9B36B6FE-7FC0-434F-A71F-BBEF8099F1D8}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{60F89955-91C6-3A36-8000-13C592FEC2DF} = {60F89955-91C6-3A36-8000-13C592FEC2DF}\n\t\t{EB33566E-DA7F-4D28-9077-88C0B7C77E35} = {EB33566E-DA7F-4D28-9077-88C0B7C77E35}\n\t\t{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {D6973076-9317-4EF2-A0B8-B7A18AC0713E}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"pngstest\", \"pngstest\\pngstest.vcxproj\", \"{277AC57F-313B-4D06-B119-A3CDB672D2FF}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{60F89955-91C6-3A36-8000-13C592FEC2DF} = {60F89955-91C6-3A36-8000-13C592FEC2DF}\n\t\t{EB33566E-DA7F-4D28-9077-88C0B7C77E35} = {EB33566E-DA7F-4D28-9077-88C0B7C77E35}\n\t\t{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {D6973076-9317-4EF2-A0B8-B7A18AC0713E}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"pngunknown\", \"pngunknown\\pngunknown.vcxproj\", \"{C5D3156C-8C8C-4936-B35F-2B829BA36FEC}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{60F89955-91C6-3A36-8000-13C592FEC2DF} = {60F89955-91C6-3A36-8000-13C592FEC2DF}\n\t\t{EB33566E-DA7F-4D28-9077-88C0B7C77E35} = {EB33566E-DA7F-4D28-9077-88C0B7C77E35}\n\t\t{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {D6973076-9317-4EF2-A0B8-B7A18AC0713E}\n\tEndProjectSection\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug Library|Win32 = Debug Library|Win32\n\t\tDebug|Win32 = Debug|Win32\n\t\tRelease Library|Win32 = Release Library|Win32\n\t\tRelease|Win32 = Release|Win32\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug Library|Win32.ActiveCfg = Debug Library|Win32\n\t\t{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug Library|Win32.Build.0 = Debug Library|Win32\n\t\t{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release Library|Win32.ActiveCfg = Release Library|Win32\n\t\t{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release Library|Win32.Build.0 = Release Library|Win32\n\t\t{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|Win32.Build.0 = Release|Win32\n\t\t{228BA965-50D5-42B2-8BCF-AFCC227E3C1D}.Debug Library|Win32.ActiveCfg = Debug Library|Win32\n\t\t{228BA965-50D5-42B2-8BCF-AFCC227E3C1D}.Debug Library|Win32.Build.0 = Debug Library|Win32\n\t\t{228BA965-50D5-42B2-8BCF-AFCC227E3C1D}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{228BA965-50D5-42B2-8BCF-AFCC227E3C1D}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{228BA965-50D5-42B2-8BCF-AFCC227E3C1D}.Release Library|Win32.ActiveCfg = Release Library|Win32\n\t\t{228BA965-50D5-42B2-8BCF-AFCC227E3C1D}.Release Library|Win32.Build.0 = Release Library|Win32\n\t\t{228BA965-50D5-42B2-8BCF-AFCC227E3C1D}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{228BA965-50D5-42B2-8BCF-AFCC227E3C1D}.Release|Win32.Build.0 = Release|Win32\n\t\t{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug Library|Win32.ActiveCfg = Debug Library|Win32\n\t\t{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug Library|Win32.Build.0 = Debug Library|Win32\n\t\t{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release Library|Win32.ActiveCfg = Release Library|Win32\n\t\t{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release Library|Win32.Build.0 = Release Library|Win32\n\t\t{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release|Win32.Build.0 = Release|Win32\n\t\t{9B36B6FE-7FC0-434F-A71F-BBEF8099F1D8}.Debug Library|Win32.ActiveCfg = Debug Library|Win32\n\t\t{9B36B6FE-7FC0-434F-A71F-BBEF8099F1D8}.Debug Library|Win32.Build.0 = Debug Library|Win32\n\t\t{9B36B6FE-7FC0-434F-A71F-BBEF8099F1D8}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{9B36B6FE-7FC0-434F-A71F-BBEF8099F1D8}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{9B36B6FE-7FC0-434F-A71F-BBEF8099F1D8}.Release Library|Win32.ActiveCfg = Release Library|Win32\n\t\t{9B36B6FE-7FC0-434F-A71F-BBEF8099F1D8}.Release Library|Win32.Build.0 = Release Library|Win32\n\t\t{9B36B6FE-7FC0-434F-A71F-BBEF8099F1D8}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{9B36B6FE-7FC0-434F-A71F-BBEF8099F1D8}.Release|Win32.Build.0 = Release|Win32\n\t\t{EB33566E-DA7F-4D28-9077-88C0B7C77E35}.Debug Library|Win32.ActiveCfg = Release|Win32\n\t\t{EB33566E-DA7F-4D28-9077-88C0B7C77E35}.Debug Library|Win32.Build.0 = Release|Win32\n\t\t{EB33566E-DA7F-4D28-9077-88C0B7C77E35}.Debug|Win32.ActiveCfg = Release|Win32\n\t\t{EB33566E-DA7F-4D28-9077-88C0B7C77E35}.Debug|Win32.Build.0 = Release|Win32\n\t\t{EB33566E-DA7F-4D28-9077-88C0B7C77E35}.Release Library|Win32.ActiveCfg = Release|Win32\n\t\t{EB33566E-DA7F-4D28-9077-88C0B7C77E35}.Release Library|Win32.Build.0 = Release|Win32\n\t\t{EB33566E-DA7F-4D28-9077-88C0B7C77E35}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{EB33566E-DA7F-4D28-9077-88C0B7C77E35}.Release|Win32.Build.0 = Release|Win32\n\t\t{277AC57F-313B-4D06-B119-A3CDB672D2FF}.Debug Library|Win32.ActiveCfg = Debug Library|Win32\n\t\t{277AC57F-313B-4D06-B119-A3CDB672D2FF}.Debug Library|Win32.Build.0 = Debug Library|Win32\n\t\t{277AC57F-313B-4D06-B119-A3CDB672D2FF}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{277AC57F-313B-4D06-B119-A3CDB672D2FF}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{277AC57F-313B-4D06-B119-A3CDB672D2FF}.Release Library|Win32.ActiveCfg = Release Library|Win32\n\t\t{277AC57F-313B-4D06-B119-A3CDB672D2FF}.Release Library|Win32.Build.0 = Release Library|Win32\n\t\t{277AC57F-313B-4D06-B119-A3CDB672D2FF}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{277AC57F-313B-4D06-B119-A3CDB672D2FF}.Release|Win32.Build.0 = Release|Win32\n\t\t{C5D3156C-8C8C-4936-B35F-2B829BA36FEC}.Debug Library|Win32.ActiveCfg = Debug Library|Win32\n\t\t{C5D3156C-8C8C-4936-B35F-2B829BA36FEC}.Debug Library|Win32.Build.0 = Debug Library|Win32\n\t\t{C5D3156C-8C8C-4936-B35F-2B829BA36FEC}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{C5D3156C-8C8C-4936-B35F-2B829BA36FEC}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{C5D3156C-8C8C-4936-B35F-2B829BA36FEC}.Release Library|Win32.ActiveCfg = Release Library|Win32\n\t\t{C5D3156C-8C8C-4936-B35F-2B829BA36FEC}.Release Library|Win32.Build.0 = Release Library|Win32\n\t\t{C5D3156C-8C8C-4936-B35F-2B829BA36FEC}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{C5D3156C-8C8C-4936-B35F-2B829BA36FEC}.Release|Win32.Build.0 = Release|Win32\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/vstudio/zlib/zlib.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug Library|Win32\">\n      <Configuration>Debug Library</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release Library|Win32\">\n      <Configuration>Release Library</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"$(ZLibSrcDir)\\adler32.c\" />\n    <ClCompile Include=\"$(ZLibSrcDir)\\compress.c\" />\n    <ClCompile Include=\"$(ZLibSrcDir)\\crc32.c\" />\n    <ClCompile Include=\"$(ZLibSrcDir)\\deflate.c\" />\n    <ClCompile Include=\"$(ZLibSrcDir)\\infback.c\" />\n    <ClCompile Include=\"$(ZLibSrcDir)\\inffast.c\" />\n    <ClCompile Include=\"$(ZLibSrcDir)\\inflate.c\" />\n    <ClCompile Include=\"$(ZLibSrcDir)\\inftrees.c\" />\n    <ClCompile Include=\"$(ZLibSrcDir)\\trees.c\" />\n    <ClCompile Include=\"$(ZLibSrcDir)\\uncompr.c\" />\n    <ClCompile Include=\"$(ZLibSrcDir)\\zutil.c\" />\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{60F89955-91C6-3A36-8000-13C592FEC2DF}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>zlib</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(SolutionDir)\\zlib.props\" />\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug Library|Win32'\">\n    <ClCompile>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;Z_SOLO;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <WarningLevel>TurnOffAllWarnings</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Disabled</Optimization>\n      <BrowseInformation>true</BrowseInformation>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n    </ClCompile>\n    <Link>\n      <TargetMachine>MachineX86</TargetMachine>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Windows</SubSystem>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;Z_SOLO;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <WarningLevel>TurnOffAllWarnings</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Disabled</Optimization>\n      <BrowseInformation>true</BrowseInformation>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <TargetMachine>MachineX86</TargetMachine>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Windows</SubSystem>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release Library|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Full</Optimization>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <WholeProgramOptimization>true</WholeProgramOptimization>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <BrowseInformation>true</BrowseInformation>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;Z_SOLO;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <TargetMachine>MachineX86</TargetMachine>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Windows</SubSystem>\n    </Link>\n    <Lib>\n      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <Optimization>Full</Optimization>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <WholeProgramOptimization>true</WholeProgramOptimization>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <BrowseInformation>true</BrowseInformation>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <TreatWarningAsError>true</TreatWarningAsError>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;Z_SOLO;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <TargetMachine>MachineX86</TargetMachine>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Windows</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>\n    </Lib>\n  </ItemDefinitionGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/projects/vstudio/zlib.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n * zlib.props - location of zlib source\n *\n * libpng version 1.6.22beta03 - February 8, 2016\n *\n * Copyright (c) 1998-2011 Glenn Randers-Pehrson\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n\n * You must edit this file to record the location of the zlib\n * source code.\n -->\n\n<Project ToolsVersion=\"4.0\"\n   xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup Label=\"Globals\">\n    <!-- Place the name of the directory containing the source of zlib used for\n\t debugging in this property.\n\n         The directory need only contain the '.c' and '.h' files from the\n\t source.\n\n\t If you use a relative directory name (as below) then it must be\n\t relative to the project directories; these are one level deeper than\n\t the directories containing this file.\n\n\t If the version of zlib you use does not match that used when the\n\t distribution was built you will get warnings from pngtest that the zlib\n\t versions do not match.  The zlib version used in this build is recorded\n\t below:\n     -->\n    <ZLibSrcDir>..\\..\\..\\..\\zlib-1.2.8</ZLibSrcDir>\n\n    <!-- The following line allows compilation for an ARM target with Visual\n         Studio 2012.  Notice that this is not supported by the Visual Studio\n         2012 IDE and that the programs that result cannot be run unless they\n         signed by Microsoft.  This is therefore untested; only Microsoft can\n         test it:\n     -->\n    <WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>\n  </PropertyGroup>\n</Project>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/README.txt",
    "content": "\nMakefiles for  libpng version 1.6.22beta03 - February 8, 2016\n\npnglibconf.h.prebuilt       =>  Stores configuration settings\n makefile.linux    =>  Linux/ELF makefile\n                       (gcc, creates libpng16.so.16.1.6.22beta03)\n makefile.gcc      =>  Generic makefile (gcc, creates static libpng.a)\n makefile.knr      =>  Archaic UNIX Makefile that converts files with\n                       ansi2knr (Requires ansi2knr.c from\n                       ftp://ftp.cs.wisc.edu/ghost)\n makefile.acorn    =>  Acorn makefile\n makefile.aix      =>  AIX/gcc makefile\n makefile.amiga    =>  Amiga makefile\n makefile.atari    =>  Atari makefile\n makefile.bc32     =>  32-bit Borland C++ (all modules compiled in C mode)\n makefile.beos     =>  beos makefile\n makefile.bor      =>  Borland makefile (uses bcc)\n makefile.cegcc    =>  minge32ce for Windows CE makefile\n makefile.darwin   =>  Darwin makefile, can use on MacosX\n makefile.dec      =>  DEC Alpha UNIX makefile\n makefile.dj2      =>  DJGPP 2 makefile\n makefile.freebsd  =>  FreeBSD makefile\n makefile.gcc      =>  Generic gcc makefile\n makefile.hpgcc    =>  HPUX makefile using gcc\n makefile.hpux     =>  HPUX (10.20 and 11.00) makefile\n makefile.hp64     =>  HPUX (10.20 and 11.00) makefile, 64-bit\n makefile.ibmc     =>  IBM C/C++ version 3.x for Win32 and OS/2 (static)\n makefile.intel    =>  Intel C/C++ version 4.0 and later\n makefile.mips     =>  MIPS makefile\n makefile.msc      =>  Microsoft C makefile\n makefile.netbsd   =>  NetBSD/cc makefile, makes libpng.so.\n makefile.openbsd  =>  OpenBSD makefile\n makefile.os2      =>  OS/2 Makefile (gcc and emx, requires libpng.def)\n makefile.sco      =>  For SCO OSr5  ELF and Unixware 7 with Native cc\n makefile.sggcc    =>  Silicon Graphics (gcc,\n                       creates libpng16.so.16.1.6.22beta03)\n makefile.sgi      =>  Silicon Graphics IRIX makefile (cc, creates static lib)\n makefile.solaris  =>  Solaris 2.X makefile (gcc,\n                       creates libpng16.so.16.1.6.22beta03)\n makefile.so9      =>  Solaris 9 makefile (gcc,\n                       creates libpng16.so.16.1.6.22beta03)\n makefile.std      =>  Generic UNIX makefile (cc, creates static libpng.a)\n makefile.sunos    =>  Sun makefile\n makefile.32sunu   =>  Sun Ultra 32-bit makefile\n makefile.64sunu   =>  Sun Ultra 64-bit makefile\n makefile.tc3      =>  Turbo C 3.0 makefile\n makefile.vcwin32  =>  makefile for Microsoft Visual C++ 4.0 and later\n makevms.com       =>  VMS build script\n smakefile.ppc     =>  AMIGA smakefile for SAS C V6.58/7.00 PPC compiler\n                       (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)\n\nOther supporting scripts:\n README.txt        =>  This file\n descrip.mms       =>  VMS makefile for MMS or MMK\n libpng-config-body.in => used by several makefiles to create libpng-config\n libpng-config-head.in => used by several makefiles to create libpng-config\n libpng.pc.in      =>  Used by several makefiles to create libpng.pc\n pngwin.rc         =>  Used by the visualc71 project.\n pngwin.def        =>  Used by makefile.os2\n pngwin.dfn        =>  Used to maintain pngwin.def\n SCOPTIONS.ppc     =>  Used with smakefile.ppc\n\n checksym.awk       =>  Used for maintaining pnglibconf.h\n def.dfn            =>  Used for maintaining pnglibconf.h\n options.awk        =>  Used for maintaining pnglibconf.h\n pnglibconf.dfa     =>  Used for maintaining pnglibconf.h\n pnglibconf.mak     =>  Used for maintaining pnglibconf.h\n sym.dfn            =>  Used for symbol versioning\n symbols.def        =>  Used for symbol versioning\n symbols.dfn        =>  Used for symbol versioning\n vers.dfn           =>  Used for symbol versioning\n\n libtool.m4        =>  Used by autoconf tools\n ltoptions.m4      =>  Used by autoconf tools\n ltsugar.m4        =>  Used by autoconf tools\n ltversion.m4      =>  Used by autoconf tools\n lt~obsolete.m4    =>  Used by autoconf tools\n\n intprefix.dfn     =>  Used by autoconf tools\n macro.lst         =>  Used by autoconf tools\n prefix.dfn        =>  Used by autoconf tools\n\n\nFurther information can be found in comments in the individual makefiles.\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/SCOPTIONS.ppc",
    "content": "OPTIMIZE\nOPTPEEP\nOPTTIME\nOPTSCHED\nAUTOREGISTER\nPARMS=REGISTERS\nINCLUDEDIR=hlp:ppc/include\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/checksym.awk",
    "content": "#!/bin/awk -f\n# Check a list of symbols against the master definition\n# (official) list.  Arguments:\n#\n# awk -f checksym.awk official-def list-to-check\n#\n# Output is a file in the current directory called 'symbols.new',\n# the value of the awk variable \"of\" (which can be changed on the\n# command line if required.)  stdout holds error messages.  Error\n# code indicates success or failure.\n#\n# NOTE: this is a pure, old fashioned, awk script.  It will\n# work with any awk\n\nBEGIN{\n   err=0\n   master=\"\"        # master file\n   official[1] = \"\" # defined symbols from master file\n   symbol[1] = \"\"   # defined symbols from png.h\n   removed[1] = \"\"  # removed symbols from png.h\n   lasto = 0        # last ordinal value from png.h\n   mastero = 0      # highest ordinal in master file\n   symbolo = 0      # highest ordinal in png.h\n   missing = \"error\"# log an error on missing symbols\n   of=\"symbols.new\" # default to a fixed name\n}\n\n# Read existing definitions from the master file (the first\n# file on the command line.)  This must be a def file and it\n# has definition lines (others are ignored) of the form:\n#\n#   symbol @ordinal\n#\nmaster == \"\" {\n   master = FILENAME\n}\nFILENAME==master && NF==2 && $2~/^@/ && $1!~/^;/ {\n   o=0+substr($2,2)\n   if (o > 0) {\n      if (official[o] == \"\") {\n         official[o] = $1\n         if (o > mastero) mastero = o\n         next\n      } else\n         print master \": duplicated symbol:\", official[o] \":\", $0\n   } else\n      print master \": bad export line format:\", $0\n   err = 1\n}\nFILENAME==master && $1==\";missing\" && NF==2{\n   # This allows the master file to control how missing symbols\n   # are handled; symbols that aren't in either the master or\n   # the new file.  Valid values are 'ignore', 'warning' and\n   # 'error'\n   missing = $2\n}\nFILENAME==master {\n   next\n}\n\n# Read new definitions, these are free form but the lines must\n# just be symbol definitions.  Lines will be commented out for\n# 'removed' symbols, introduced in png.h using PNG_REMOVED rather\n# than PNG_EXPORT.  Use symbols.dfn or pngwin.dfn to generate the\n# input file.\n#\n#  symbol @ordinal   # two fields, exported symbol\n#  ; symbol @ordinal # three fields, removed symbol\n#  ; @ordinal        # two fields, the last ordinal\nNF==2 && $1 == \";\" && $2 ~ /^@[1-9][0-9]*$/ { # last ordinal\n   o=0+substr($2,2)\n   if (lasto == 0 || lasto == o)\n      lasto=o\n   else {\n      print \"png.h: duplicated last ordinal:\", lasto, o\n      err = 1\n   }\n   next\n}\nNF==3 && $1 == \";\" && $3 ~ /^@[1-9][0-9]*$/ { # removed symbol\n   o=0+substr($3,2)\n   if (removed[o] == \"\" || removed[o] == $2) {\n      removed[o] = $2\n      if (o > symbolo) symbolo = o\n   } else {\n      print \"png.h: duplicated removed symbol\", o \": '\" removed[o] \"' != '\" $2 \"'\"\n      err = 1\n   }\n   next\n}\nNF==2 && $2 ~ /^@[1-9][0-9]*$/ { # exported symbol\n   o=0+substr($2,2)\n   if (symbol[o] == \"\" || symbol[o] == $1) {\n      symbol[o] = $1\n      if (o > symbolo) symbolo = o\n   } else {\n      print \"png.h: duplicated symbol\", o \": '\" symbol[o] \"' != '\" $1 \"'\"\n      err = 1\n   }\n}\n{\n   next # skip all other lines\n}\n\n# At the end check for symbols marked as both duplicated and removed\nEND{\n   if (symbolo > lasto) {\n      print \"highest symbol ordinal in png.h,\", symbolo \", exceeds last ordinal from png.h\", lasto\n      err = 1\n   }\n   if (mastero > lasto) {\n      print \"highest symbol ordinal in\", master \",\", mastero \", exceeds last ordinal from png.h\", lasto\n      err = 1\n   }\n   unexported=0\n   # Add a standard header to symbols.new:\n   print \";Version INSERT-VERSION-HERE\" >of\n   print \";--------------------------------------------------------------\" >of\n   print \"; LIBPNG symbol list as a Win32 DEF file\" >of\n   print \"; Contains all the symbols that can be exported from libpng\" >of\n   print \";--------------------------------------------------------------\" >of\n   print \"LIBRARY\" >of\n   print \"\" >of\n   print \"EXPORTS\" >of\n\n   for (o=1; o<=lasto; ++o) {\n      if (symbol[o] == \"\" && removed[o] == \"\") {\n         if (unexported == 0) unexported = o\n         if (official[o] == \"\") {\n            # missing in export list too, so ok\n            if (o < lasto) continue\n         }\n      }\n      if (unexported != 0) {\n         # Symbols in the .def but not in the new file are errors, but\n         # the 'unexported' symbols aren't in either.  By default this\n         # is an error too (see the setting of 'missing' at the start),\n         # but this can be reset on the command line or by stuff in the\n         # file - see the comments above.\n         if (missing != \"ignore\") {\n            if (o-1 > unexported)\n               print \"png.h:\", missing \": missing symbols:\", unexported \"-\" o-1\n            else\n               print \"png.h:\", missing \": missing symbol:\", unexported\n            if (missing != \"warning\")\n               err = 1\n         }\n         unexported = 0\n      }\n      if (symbol[o] != \"\" && removed[o] != \"\") {\n         print \"png.h: symbol\", o, \"both exported as '\" symbol[o] \"' and removed as '\" removed[o] \"'\"\n         err = 1\n      } else if (symbol[o] != official[o]) {\n         # either the symbol is missing somewhere or it changed\n         err = 1\n         if (symbol[o] == \"\")\n            print \"png.h: symbol\", o, \"is exported as '\" official[o] \"' in\", master\n         else if (official[o] == \"\")\n            print \"png.h: exported symbol\", o, \"'\" symbol[o] \"' not present in\", master\n         else\n            print \"png.h: exported symbol\", o, \"'\" symbol[o] \"' exists as '\" official[o] \"' in\", master\n      }\n\n      # Finally generate symbols.new\n      if (symbol[o] != \"\")\n         print \" \" symbol[o], \"@\" o > of\n   }\n\n   if (err != 0) {\n      print \"*** A new list is in\", of, \"***\"\n      exit 1\n   }\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/def.c",
    "content": "/* def.c - define format of libpng.def\n *\n * Last changed in libpng version 1.6.16 [December 22, 2014]\n * Copyright (c) 2011-2014 Glenn Randers-Pehrson\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n/* Write the export file header: */\nPNG_DFN \";--------------------------------------------------------------\"\nPNG_DFN \"; LIBPNG module definition file for OS/2\"\nPNG_DFN \";--------------------------------------------------------------\"\nPNG_DFN \"\"\nPNG_DFN \"; If you give the library an explicit name one or other files\"\nPNG_DFN \"; may need modifying to support the new name on one or more\"\nPNG_DFN \"; systems.\"\nPNG_DFN \"LIBRARY\"\nPNG_DFN \"OS2 DESCRIPTION \"PNG image compression library\"\"\nPNG_DFN \"OS2 CODE PRELOAD MOVEABLE DISCARDABLE\"\nPNG_DFN \"\"\nPNG_DFN \"EXPORTS\"\nPNG_DFN \";Version 1.6.22beta03\"\n\n#define PNG_EXPORTA(ordinal, type, name, args, attributes)\\\n        PNG_DFN \"@\" SYMBOL_PREFIX \"@@\" name \"@\"\n\n#include \"../png.h\"\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/descrip.mms",
    "content": "\ncc_defs = /inc=$(ZLIBSRC)\nc_deb =\n\n.ifdef __DECC__\npref = /prefix=all\n.endif\n\n\n\nOBJS = png.obj, pngset.obj, pngget.obj, pngrutil.obj, pngtrans.obj,\\\n\tpngwutil.obj, pngread.obj, pngmem.obj, pngwrite.obj, pngrtran.obj,\\\n\tpngwtran.obj, pngrio.obj, pngwio.obj, pngerror.obj, pngpread.obj\n\n\nCFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)\n\nall : pngtest.exe libpng.olb\n\t\t@ write sys$output \" pngtest available\"\n\nlibpng.olb : libpng.olb($(OBJS))\n\t@ write sys$output \" Libpng available\"\n\n\npngtest.exe : pngtest.obj libpng.olb\n              link pngtest,libpng.olb/lib,$(ZLIBSRC)libz.olb/lib\n\ntest : pngtest.exe\n   run pngtest\n\nclean :\n\tdelete *.obj;*,*.exe;\n\n\n# Other dependencies.\npng.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\npngpread.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\npngset.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\npngget.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\npngread.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\npngrtran.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\npngrutil.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\npngerror.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\npngmem.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\npngrio.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\npngwio.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\npngtrans.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\npngwrite.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\npngwtran.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\npngwutil.obj : png.h, pngconf.h, pnglibconf.h, pngpriv.h, pngstruct.h,pnginfo.h, pngdebug.h\n\npngtest.obj : png.h, pngconf.h, pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/dfn.awk",
    "content": "#!/bin/awk -f\n# scripts/dfn.awk - process a .dfn file\n#\n# last changed in libpng version 1.5.19 - August 21, 2014\n#\n# Copyright (c) 2013-2014 Glenn Randers-Pehrson\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# The output of this script is written to the file given by\n# the variable 'out', which should be set on the command line.\n# Error messages are printed to stdout and if any are printed\n# the script will exit with error code 1.\n\nBEGIN{\n   out=\"/dev/null\"       # as a flag\n   out_count=0           # count of output lines\n   err=0                 # set if an error occurred\n   sort=0                # sort the output\n   array[\"\"]=\"\"\n}\n\n# The output file must be specified before any input:\nNR==1 && out == \"/dev/null\" {\n   print \"out=output.file must be given on the command line\"\n   # but continue without setting the error code; this allows the\n   # script to be checked easily\n}\n\n# Output can be sorted; two lines are recognized\n$1 == \"PNG_DFN_START_SORT\"{\n   sort=0+$2\n   next\n}\n\n$1 ~ /^PNG_DFN_END_SORT/{\n   # Do a very simple, slow, sort; notice that blank lines won't be\n   # output by this\n   for (entry in array) {\n      while (array[entry] != \"\") {\n         key = entry\n         value = array[key]\n         array[key] = \"\"\n\n         for (alt in array) {\n            if (array[alt] != \"\" && alt < key) {\n               array[key] = value\n               value = array[alt]\n               key = alt\n               array[alt] = \"\"\n            }\n         }\n\n         print value >out\n      }\n   }\n   sort=0\n   next\n}\n\n/^[^\"]*PNG_DFN *\".*\"[^\"]*$/{\n   # A definition line, apparently correctly formatted; extract the\n   # definition then replace any doubled \"\" that remain with a single\n   # double quote.  Notice that the original doubled double quotes\n   # may have been split by tokenization\n   #\n   # Sometimes GCC splits the PNG_DFN lines; we know this has happened\n   # if the quotes aren't closed and must read another line.  In this\n   # case it is essential to reject lines that start with '#' because those\n   # are introduced #line directives.\n   orig=$0\n   line=$0\n   lineno=FNR\n   if (lineno == \"\") lineno=NR\n\n   if (sub(/^[^\"]*PNG_DFN *\"/,\"\",line) != 1) {\n\tprint \"line\", lineno \": processing failed:\"\n\tprint orig\n\terr=1\n       next\n   } else {\n\t++out_count\n   }\n\n   # Now examine quotes within the value:\n   #\n   #   @\" - delete this and any following spaces\n   #   \"@ - delete this and any preceding spaces\n   #   @' - replace this by a double quote\n   #\n   # This allows macro substitution by the C compiler thus:\n   #\n   #   #define first_name John\n   #   #define last_name Smith\n   #\n   #\tPNG_DFN\"#define name @'@\" first_name \"@ @\" last_name \"@@'\"\n   #\n   # Might get C preprocessed to:\n   #\n   #   PNG_DFN \"#define foo @'@\" John \"@ @\" Smith \"@@'\"\n   #\n   # Which this script reduces to:\n   #\n   #\t#define name \"John Smith\"\n   #\n   while (1) {\n      # While there is an @\" remove it and the next \"@\n      if (line ~ /@\"/) {\n         if (line ~ /@\".*\"@/) {\n            # Do this special case first to avoid swallowing extra spaces\n            # before or after the @ stuff:\n            if (!sub(/@\" *\"@/, \"\", line)) {\n               # Ok, do it in pieces - there has to be a non-space between the\n               # two.  NOTE: really weird things happen if a leading @\" is\n               # lost - the code will error out below (I believe).\n               if (!sub(/@\" */, \"\", line) || !sub(/ *\"@/, \"\", line)) {\n                  print \"line\", lineno, \": internal error:\", orig\n                  exit 1\n               }\n            }\n         }\n\n         # There is no matching \"@.  Assume a split line\n         else while (1) {\n            if (getline nextline) {\n               # If the line starts with '#' it is a preprocesor line directive\n               # from cc -E; skip it:\n               if (nextline !~ /^#/) {\n                  line = line \" \" nextline\n                  break\n               }\n            } else {\n               # This is end-of-input - probably a missing \"@ on the first line:\n               print \"line\", lineno \": unbalanced @\\\" ... \\\"@ pair\"\n               err=1\n               next\n            }\n         }\n\n         # Keep going until all the @\" have gone\n         continue\n      }\n\n      # Attempt to remove a trailing \" (not preceded by '@') - if this can\n      # be done, stop now; if not assume a split line again\n      if (sub(/\"[^\"]*$/, \"\", line))\n         break\n\n      # Read another line\n      while (1) {\n         if (getline nextline) {\n            if (nextline !~ /^#/) {\n               line = line \" \" nextline\n               # Go back to stripping @\" \"@ pairs\n               break\n            }\n         } else {\n            print \"line\", lineno \": unterminated PNG_DFN string\"\n            err=1\n            next\n         }\n      }\n   }\n\n   # Put any needed double quotes in (at the end, because these would otherwise\n   # interfere with the processing above.)\n   gsub(/@'/,\"\\\"\", line)\n\n   # Remove any trailing spaces (not really required, but for\n   # editorial consistency\n   sub(/ *$/, \"\", line)\n\n   # Remove trailing CR\n   sub(/\r$/, \"\", line)\n\n   if (sort) {\n      if (split(line, parts) < sort) {\n         print \"line\", lineno \": missing sort field:\", line\n         err=1\n      } else\n         array[parts[sort]] = line\n   }\n\n   else\n      print line >out\n   next\n}\n\n/PNG_DFN/{\n   print \"line\", NR, \"incorrectly formatted PNG_DFN line:\"\n   print $0\n   err = 1\n}\n\nEND{\n   if (out_count > 0 || err > 0)\n\texit err\n\n   print \"no definition lines found\"\n   exit 1\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/genchk.cmake.in",
    "content": "# genchk.cmake.in\n# Generate .chk from .out with awk (generic), based upon the automake logic.\n\n# Copyright (C) 2016 Glenn Randers-Pehrson\n# Written by Roger Leigh, 2016\n\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Variables substituted from CMakeLists.txt\nset(SRCDIR \"@CMAKE_CURRENT_SOURCE_DIR@\")\n\nset(AWK \"@AWK@\")\n\nget_filename_component(INPUTEXT \"${INPUT}\" EXT)\nget_filename_component(OUTPUTEXT \"${OUTPUT}\" EXT)\nget_filename_component(INPUTBASE \"${INPUT}\" NAME_WE)\nget_filename_component(OUTPUTBASE \"${OUTPUT}\" NAME_WE)\nget_filename_component(INPUTDIR \"${INPUT}\" PATH)\nget_filename_component(OUTPUTDIR \"${OUTPUT}\" PATH)\n\nif(\"${INPUTEXT}\" STREQUAL \".out\" AND \"${OUTPUTEXT}\" STREQUAL \".chk\")\n  # Generate .chk from .out with awk (generic)\n  file(REMOVE \"${OUTPUT}\" \"${OUTPUTDIR}/${OUTPUTBASE}.new\")\n  execute_process(COMMAND \"${AWK}\" -f \"${SRCDIR}/scripts/checksym.awk\"\n                          \"${SRCDIR}/scripts/${INPUTBASE}.def\"\n                          \"of=${OUTPUTDIR}/${OUTPUTBASE}.new\"\n                          \"${INPUT}\"\n                  RESULT_VARIABLE AWK_FAIL)\n  if(AWK_FAIL)\n    message(FATAL_ERROR \"Failed to generate ${OUTPUTDIR}/${OUTPUTBASE}.new\")\n  endif()\n  file(RENAME \"${OUTPUTDIR}/${OUTPUTBASE}.new\" \"${OUTPUT}\")\nelse()\n  message(FATAL_ERROR \"Unsupported conversion: ${INPUTEXT} to ${OUTPUTEXT}\")\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/genout.cmake.in",
    "content": "# genout.cmake.in\n# Generate .out from .c with awk (generic), based upon the automake logic.\n\n# Copyright (C) 2016 Glenn Randers-Pehrson\n# Written by Roger Leigh, 2016\n\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Variables substituted from CMakeLists.txt\nset(SRCDIR \"@CMAKE_CURRENT_SOURCE_DIR@\")\nset(BINDIR \"@CMAKE_CURRENT_BINARY_DIR@\")\n\nset(AWK \"@AWK@\")\nset(CMAKE_C_COMPILER \"@CMAKE_C_COMPILER@\")\nset(CMAKE_C_FLAGS \"@CMAKE_C_FLAGS@\")\nset(INCDIR \"@CMAKE_CURRENT_BINARY_DIR@\")\nset(PNG_PREFIX \"@PNG_PREFIX@\")\nset(PNGLIB_MAJOR \"@PNGLIB_MAJOR@\")\nset(PNGLIB_MINOR \"@PNGLIB_MINOR@\")\nset(PNGLIB_VERSION \"@PNGLIB_VERSION@\")\nset(ZLIBINCDIR \"@ZLIB_INCLUDE_DIR@\")\n\nget_filename_component(INPUTEXT \"${INPUT}\" EXT)\nget_filename_component(OUTPUTEXT \"${OUTPUT}\" EXT)\nget_filename_component(INPUTBASE \"${INPUT}\" NAME_WE)\nget_filename_component(OUTPUTBASE \"${OUTPUT}\" NAME_WE)\nget_filename_component(INPUTDIR \"${INPUT}\" PATH)\nget_filename_component(OUTPUTDIR \"${OUTPUT}\" PATH)\n\nif (\"${INPUTEXT}\" STREQUAL \".c\" AND \"${OUTPUTEXT}\" STREQUAL \".out\")\n  get_filename_component(GENDIR \"${OUTPUT}\" PATH)\n  file(MAKE_DIRECTORY \"${GENDIR}\")\n\n  file(REMOVE \"${OUTPUT}.tf1\" \"${OUTPUT}.tf2\")\n\n  set(INCLUDES \"-I${INCDIR}\")\n  if(ZLIBINCDIR)\n    list(APPEND INCLUDES \"-I${ZLIBINCDIR}\")\n  endif()\n\n  if(PNG_PREFIX)\n    set(PNG_PREFIX_DEF \"-DPNG_PREFIX=${PNG_PREFIX}\")\n  endif()\n\n  execute_process(COMMAND \"${CMAKE_C_COMPILER}\" \"-E\"\n                          ${CMAKE_C_FLAGS}\n                          \"-I${SRCDIR}\"\n                          \"-I${BINDIR}\"\n                          ${INCLUDES}\n                          \"-DPNGLIB_LIBNAME=PNG${PNGLIB_MAJOR}${PNGLIB_MINOR}_0\"\n                          \"-DPNGLIB_VERSION=${PNGLIB_VERSION}\"\n                          \"-DSYMBOL_PREFIX=${SYMBOL_PREFIX}\"\n                          \"-DPNG_NO_USE_READ_MACROS\"\n                          \"-DPNG_BUILDING_SYMBOL_TABLE\"\n                          ${PNG_PREFIX_DEF}\n                          \"${INPUT}\"\n                  OUTPUT_FILE \"${OUTPUT}.tf1\"\n                  WORKING_DIRECTORY \"${BINDIR}\"\n                  RESULT_VARIABLE CPP_FAIL)\n  if(CPP_FAIL)\n    message(FATAL_ERROR \"Failed to generate ${OUTPUT}.tf1\")\n  endif()\n\n  execute_process(COMMAND \"${AWK}\" -f \"${SRCDIR}/scripts/dfn.awk\"\n                          \"out=${OUTPUT}.tf2\" \"${OUTPUT}.tf1\"\n                  WORKING_DIRECTORY \"${BINDIR}\"\n                  RESULT_VARIABLE AWK_FAIL)\n  if(AWK_FAIL)\n    message(FATAL_ERROR \"Failed to generate ${OUTPUT}.tf2\")\n  endif()\n\n  file(REMOVE \"${OUTPUT}.tf1\")\n  file(RENAME \"${OUTPUT}.tf2\" \"${OUTPUT}\")\nelse()\n  message(FATAL_ERROR \"Unsupported conversion: ${INPUTEXT} to ${OUTPUTEXT}\")\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/gensrc.cmake.in",
    "content": "# gensrc.cmake.in\n# Generate source files with awk, based upon the automake logic.\n\n# Copyright (C) 2016 Glenn Randers-Pehrson\n# Written by Roger Leigh, 2016\n\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Variables substituted from CMakeLists.txt\nset(SRCDIR \"@CMAKE_CURRENT_SOURCE_DIR@\")\nset(BINDIR \"@CMAKE_CURRENT_BINARY_DIR@\")\n\nset(AWK \"@AWK@\")\nset(DFA_XTRA \"@DFA_XTRA@\")\nset(PNG_PREFIX \"@PNG_PREFIX@\")\nset(PNGLIB_VERSION \"@PNGLIB_VERSION@\")\n\nif(\"${OUTPUT}\" STREQUAL \"scripts/pnglibconf.c\")\n  # Generate scripts/pnglibconf.c\n\n  file(REMOVE \"${BINDIR}/pnglibconf.tf6\" \"${BINDIR}/pnglibconf.tf7\")\n\n  execute_process(COMMAND \"${CMAKE_COMMAND}\" -E echo \"com ${PNGLIB_VERSION} STANDARD API DEFINITION\"\n                  COMMAND \"${AWK}\" -f \"${SRCDIR}/scripts/options.awk\"\n                          \"out=pnglibconf.tf6\" \"logunsupported=1\" \"version=search\"\n                          \"${SRCDIR}/pngconf.h\" \"-\"\n                          \"${SRCDIR}/scripts/pnglibconf.dfa\"\n                  WORKING_DIRECTORY \"${BINDIR}\"\n                  RESULT_VARIABLE AWK_FAIL)\n  if(AWK_FAIL)\n    message(FATAL_ERROR \"Failed to generate pnglibconf.tf6\")\n  endif()\n\n  execute_process(COMMAND \"${AWK}\" -f \"${SRCDIR}/scripts/options.awk\"\n                  \"out=pnglibconf.tf7\" \"pnglibconf.tf6\"\n                  WORKING_DIRECTORY \"${BINDIR}\"\n                  RESULT_VARIABLE AWK_FAIL)\n  if(AWK_FAIL)\n    message(FATAL_ERROR \"Failed to generate pnglibconf.tf7\")\n  endif()\n\n  file(REMOVE \"pnglibconf.tf6\")\n  file(MAKE_DIRECTORY \"${BINDIR}/scripts\")\n  file(RENAME \"pnglibconf.tf7\" \"${BINDIR}/scripts/pnglibconf.c\")\n\nelseif (\"${OUTPUT}\" STREQUAL \"pnglibconf.c\")\n  # Generate pnglibconf.c\n\n  file(REMOVE \"${BINDIR}/pnglibconf.tf4\" \"${BINDIR}/pnglibconf.tf5\")\n\n  execute_process(COMMAND \"${AWK}\" -f \"${SRCDIR}/scripts/options.awk\"\n                  out=pnglibconf.tf4 version=search\n                  ${SRCDIR}/pngconf.h ${SRCDIR}/scripts/pnglibconf.dfa\n                  ${SRCDIR}/pngusr.dfa ${DFA_XTRA}\n                  WORKING_DIRECTORY \"${BINDIR}\"\n                  RESULT_VARIABLE AWK_FAIL)\n  if(AWK_FAIL)\n    message(FATAL_ERROR \"Failed to generate pnglibconf.tf4\")\n  endif()\n\n  execute_process(COMMAND \"${AWK}\" -f \"${SRCDIR}/scripts/options.awk\"\n                  out=pnglibconf.tf5 pnglibconf.tf4\n                  WORKING_DIRECTORY \"${BINDIR}\"\n                  RESULT_VARIABLE AWK_FAIL)\n  if(AWK_FAIL)\n    message(FATAL_ERROR \"Failed to generate pnglibconf.tf5\")\n  endif()\n\n  file(REMOVE \"pnglibconf.tf4\")\n  file(MAKE_DIRECTORY \"${BINDIR}/scripts\")\n  file(RENAME \"pnglibconf.tf5\" \"${BINDIR}/pnglibconf.c\")\n\nelseif (\"${OUTPUT}\" STREQUAL \"pnglibconf.h\")\n  # Generate pnglibconf.h\n\n  file(REMOVE \"${BINDIR}/${OUTPUT}\")\n  if(PNG_PREFIX)\n    file(REMOVE \"pnglibconf.tf8\")\n\n    execute_process(COMMAND \"${AWK}\" \"s==0 && NR>1{print prev}\n                             s==0{prev=\\$0}\n                             s==1{print \\\"#define\\\", \\$1, \\\"${PNG_PREFIX}\\\" \\$1}\n                             s==2{print \\\"#define ${PNG_PREFIX}png_\\\" \\$1, \\\"PNG_\\\" \\$1}\n                             END{print prev}\" s=0 pnglibconf.out s=1 \"${BINDIR}/scripts/prefix.out\"\n                             s=2 \"${SRCDIR}/scripts/macro.lst\"\n                    OUTPUT_FILE pnglibconf.tf8\n                    RESULT_VARIABLE AWK_FAIL)\n    if(AWK_FAIL)\n      message(FATAL_ERROR \"Failed to generate pnglibconf.tf8\")\n    endif()\n\n    file(RENAME \"pnglibconf.tf8\" \"${BINDIR}/${OUTPUT}\")\n  else()\n    execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${BINDIR}/pnglibconf.out\"\n                                                       \"${BINDIR}/${OUTPUT}\"\n                    RESULT_VARIABLE COPY_FAIL)\n    if(COPY_FAIL)\n      message(FATAL_ERROR \"Failed to create pnglibconf.h\")\n    endif()\n  endif()\n\nelseif (\"${OUTPUT}\" STREQUAL \"pngprefix.h\")\n  # Generate pngprefix.h\n\n  file(REMOVE \"${BINDIR}/${OUTPUT}\")\n\n  if(PNG_PREFIX)\n    file(REMOVE \"pngprefix.tf1\")\n\n    execute_process(COMMAND \"${AWK}\"\n                            \"{print \\\"#define\\\", \\$1, \\\"${PNG_PREFIX}\\\" \\$1}\"\n                            \"${BINDIR}/scripts/intprefix.out\"\n                    OUTPUT_FILE \"pngprefix.tf1\"\n                    RESULT_VARIABLE AWK_FAIL)\n    if(AWK_FAIL)\n      message(FATAL_ERROR \"Failed to generate pngprefix.tf1\")\n    endif()\n\n    file(RENAME \"pngprefix.tf1\" \"${BINDIR}/${OUTPUT}\")\n  else()\n    file(WRITE \"${BINDIR}/${OUTPUT}\" \"/* No libpng symbol prefix configured. */\")\n  endif()\n\nelseif(\"${OUTPUT}\" STREQUAL \"scripts/pnglibconf.h.prebuilt\")\n  # Generate scripts/pnglibconf.h.prebuilt (fails build)\n\n  message(STATUS \"Attempting to build scripts/pnglibconf.h.prebuilt\")\n  message(STATUS \"This is a machine generated file, but if you want to make\")\n  message(STATUS \"a new one simply build the 'genfiles' target, and copy\")\n  message(STATUS \"scripts/pnglibconf.out to scripts/pnglibconf.h.prebuilt\")\n  message(STATUS \"AND set PNG_ZLIB_VERNUM to 0 (you MUST do this)\")\n  message(FATAL_ERROR \"Stopping build\")\n\nelse()\n  message(FATAL_ERROR \"Unsupported output: ${OUTPUT}\")\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/intprefix.c",
    "content": "\n/* intprefix.c - generate an unprefixed internal symbol list\n *\n * Last changed in libpng version 1.6.16 [December 22, 2014]\n * Copyright (c) 2013-2014 Glenn Randers-Pehrson\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n#define PNG_INTERNAL_DATA(type, name, array)\\\n        PNG_DFN \"@\" name \"@\"\n\n#define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\\\n        PNG_DFN \"@\" name \"@\"\n\n#define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\\\n        PNG_DFN \"@\" name \"@\"\n\n#define PNGPREFIX_H /* self generation */\n#include \"../pngpriv.h\"\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/libpng-config-body.in",
    "content": "\nusage()\n{\n    cat <<EOF\nUsage: libpng-config [OPTION] ...\n\nKnown values for OPTION are:\n\n  --prefix        print libpng prefix\n  --libdir        print path to directory containing library\n  --libs          print library linking information\n  --ccopts        print compiler options\n  --cppflags      print pre-processor flags\n  --cflags        print preprocessor flags, I_opts, and compiler options\n  --I_opts        print \"-I\" include options\n  --L_opts        print linker \"-L\" flags for dynamic linking\n  --R_opts        print dynamic linker \"-R\" or \"-rpath\" flags\n  --ldopts        print linker options\n  --ldflags       print linker flags (ldopts, L_opts, R_opts, and libs)\n  --static        revise subsequent outputs for static linking\n  --help          print this help and exit\n  --version       print version information\nEOF\n\n    exit $1\n}\n\nif test $# -eq 0; then\n    usage 1\nfi\n\nwhile test $# -gt 0; do\n    case \"$1\" in\n\n    --prefix)\n        echo ${prefix}\n        ;;\n\n    --version)\n        echo ${version}\n        exit 0\n        ;;\n\n    --help)\n        usage 0\n        ;;\n\n    --ccopts)\n        echo ${ccopts}\n        ;;\n\n    --cppflags)\n        echo ${cppflags}\n        ;;\n\n    --cflags)\n        echo ${I_opts} ${cppflags} ${ccopts}\n        ;;\n\n    --libdir)\n        echo ${libdir}\n        ;;\n\n    --libs)\n        echo ${libs}\n        ;;\n\n    --I_opts)\n        echo ${I_opts}\n        ;;\n\n    --L_opts)\n        echo ${L_opts}\n        ;;\n\n    --R_opts)\n        echo ${R_opts}\n        ;;\n\n    --ldflags)\n        echo ${ldflags} ${L_opts} ${R_opts} ${libs}\n        ;;\n\n    --static)\n        R_opts=\"\"\n        ;;\n\n    *)\n        usage\n        exit 1\n        ;;\n    esac\n    shift\ndone\n\nexit 0\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/libpng-config-head.in",
    "content": "#! /bin/sh\n\n# libpng-config\n# provides configuration info for libpng.\n\n# Copyright (C) 2002 Glenn Randers-Pehrson\n\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Modeled after libxml-config.\n\nversion=1.6.22beta03\nprefix=\"\"\nlibdir=\"\"\nlibs=\"\"\nI_opts=\"\"\nL_opts=\"\"\nR_opts=\"\"\ncppflags=\"\"\nccopts=\"\"\nldopts=\"\"\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/libpng.pc.in",
    "content": "prefix=@prefix@\nexec_prefix=@exec_prefix@\nlibdir=@libdir@\nincludedir=@includedir@/libpng16\n\nName: libpng\nDescription: Loads and saves PNG files\nVersion: 1.6.22beta03\nLibs: -L${libdir} -lpng16\nCflags: -I${includedir}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/macro.lst",
    "content": "get_uint_32(buf)\nget_uint_16(buf)\nget_int_32(buf)\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.32sunu",
    "content": "# makefile for libpng on Solaris 2.x with cc\n# Contributed by William L. Sebok, based on makefile.linux\n# Copyright (C) 2002, 2006, 2010-2014 Glenn Randers-Pehrson\n# Copyright (C) 1998 Greg Roelofs\n# Copyright (C) 1996, 1997 Andreas Dilger\n\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Library name:\nLIBNAME=libpng16\nPNGMAJ = 16\n\n# Shared library names:\nLIBSO=$(LIBNAME).so\nLIBSOMAJ=$(LIBNAME).so.$(PNGMAJ)\nLIBSOREL=$(LIBSOMAJ).$(RELEASE)\nOLDSO=libpng.so\n\n# Utilities:\nCC=cc\nAR_RC=ar rc\nMKDIR_P=mkdir -p\nLN_SF=ln -f -s\nRANLIB=echo\nRM_F=/bin/rm -f\n\nSUN_CC_FLAGS=-fast -xtarget=ultra\nSUN_LD_FLAGS=-fast -xtarget=ultra\n\n# where make install puts libpng.a, libpng16.so and libpng16/png.h\nprefix=/a\nexec_prefix=$(prefix)\n\n# Where the zlib library and include files are located\n# Changing these to ../zlib poses a security risk.  If you want\n# to have zlib in an adjacent directory, specify the full path instead of \"..\".\n#ZLIBLIB=../zlib\n#ZLIBINC=../zlib\n\nZLIBLIB=/usr/lib\nZLIBINC=/usr/include\n\nWARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \\\n\t-Wmissing-declarations -Wtraditional -Wcast-align \\\n\t-Wstrict-prototypes -Wmissing-prototypes #-Wconversion\nCPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5\nCFLAGS=$(SUN_CC_FLAGS) # $(WARNMORE) -g\nLDFLAGS=$(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB) libpng.a -lz -lm\n\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\nOBJSDLL = $(OBJS:.o=.pic.o)\n\n.SUFFIXES:      .c .o .pic.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\n.c.pic.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -KPIC -o $@ $*.c\n\nall: libpng.a $(LIBSO) pngtest libpng.pc libpng-config\n\ninclude scripts/pnglibconf.mak\nDELETE = $(RM_F)\nDFNFLAGS = $(DEFS) $(CPPFLAGS)\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo libdir=\\\"$(LIBPATH)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo L_opts=\\\"-L$(LIBPATH)\\\"; \\\n\techo R_opts=\\\"-R$(LIBPATH)\\\"; \\\n\techo ccopts=\\\"-fast -xtarget=ultra\\\"; \\\n\techo ldopts=\\\"-fast -xtarget=ultra\\\"; \\\n\techo libs=\\\"-lpng16 -lz -lm\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ): $(OBJSDLL)\n\t@case \"`type ld`\" in *ucb*) \\\n\techo; \\\n\techo '## WARNING:'; \\\n\techo '## The commands \"CC\" and \"LD\" must NOT refer to /usr/ucb/cc'; \\\n\techo '## and /usr/ucb/ld.  If they do, you need to adjust your PATH'; \\\n\techo '## environment variable to put /usr/ccs/bin ahead of /usr/ucb.'; \\\n\techo '## The environment variable LD_LIBRARY_PATH should not be set'; \\\n\techo '## at all.  If it is, things are likely to break because of'; \\\n\techo '## the libucb dependency that is created.'; \\\n\techo; \\\n\t;; \\\n\tesac\n\t$(LD) -G -L$(ZLIBLIB) -R$(ZLIBLIB) -h $(LIBSOMAJ) \\\n\t -o $(LIBSOMAJ) $(OBJSDLL)\n\npngtest: pngtest.o $(LIBSO)\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOREL)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)/$(LIBSOREL)\n\tchmod 755 $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) $(SUN_CC_FLAGS) -I$(DI) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -o pngtestd -L$(DL) -R$(DL) `$(BINPATH)/$(LIBNAME)-config --ldflags` \\\n\t   $(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB)\n\t./pngtestd pngtest.png\n\ntest-installed:\n\techo\n\techo Testing installed dynamic shared library.\n\t$(CC) $(SUN_CC_FLAGS) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` \\\n\t   $(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB)\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngtesti pngout.png \\\n\tlibpng-config $(LIBSO) $(LIBSOMAJ)* \\\n\tlibpng.pc\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o png.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o pngerror.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o pngrio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o pngwio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o pngmem.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o pngset.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o pngget.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o pngread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o pngrtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o pngrutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o pngtrans.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o pngwrite.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o pngwtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o pngwutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o pngpread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.64sunu",
    "content": "# makefile for libpng on Solaris 2.x with cc\n# Contributed by William L. Sebok, based on makefile.linux\n# Copyright (C) 2002, 2006, 2010-2014 Glenn Randers-Pehrson\n# Copyright (C) 1998 Greg Roelofs\n# Copyright (C) 1996, 1997 Andreas Dilger\n\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Library name:\nLIBNAME=libpng16\nPNGMAJ = 16\n\n# Shared library names:\nLIBSO=$(LIBNAME).so\nLIBSOMAJ=$(LIBNAME).so.$(PNGMAJ)\nLIBSOREL=$(LIBSOMAJ).$(RELEASE)\nOLDSO=libpng.so\n\n# Utilities:\nCC=cc\nAR_RC=ar rc\nMKDIR_P=mkdir -p\nLN_SF=ln -f -s\nRANLIB=echo\nRM_F=/bin/rm -f\n\nSUN_CC_FLAGS=-fast -xtarget=ultra -xarch=v9\nSUN_LD_FLAGS=-fast -xtarget=ultra -xarch=v9\n\n# where make install puts libpng.a, libpng16.so and libpng16/png.h\nprefix=/a\nexec_prefix=$(prefix)\n\n# Where the zlib library and include files are located\n# Changing these to ../zlib poses a security risk.  If you want\n# to have zlib in an adjacent directory, specify the full path instead of \"..\".\n#ZLIBLIB=../zlib\n#ZLIBINC=../zlib\n\nZLIBLIB=/usr/lib\nZLIBINC=/usr/include\n\nWARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \\\n\t-Wmissing-declarations -Wtraditional -Wcast-align \\\n\t-Wstrict-prototypes -Wmissing-prototypes #-Wconversion\nCPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5\nCFLAGS= $(SUN_CC_FLAGS) # $(WARNMORE) -g\nLDFLAGS=-L. -R. $(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng16 -lz -lm\n\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\nOBJSDLL = $(OBJS:.o=.pic.o)\n\n.SUFFIXES:      .c .o .pic.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\n.c.pic.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -KPIC -o $@ $*.c\n\nall: libpng.a $(LIBSO) pngtest libpng.pc libpng-config\n\ninclude scripts/pnglibconf.mak\nDELETE = $(RM_F)\nDFNFLAGS = $(DEFS) $(CPPFLAGS)\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo libdir=\\\"$(LIBPATH)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo L_opts=\\\"-L$(LIBPATH)\\\"; \\\n\techo R_opts=\\\"-R$(LIBPATH)\\\"; \\\n\techo ccopts=\\\"-fast -xtarget=ultra -xarch=v9\\\"; \\\n\techo ldopts=\\\"-fast -xtarget=ultra -xarch=v9\\\"; \\\n\techo libs=\\\"-lpng16 -lz -lm\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ): $(OBJSDLL)\n\t@case \"`type ld`\" in *ucb*) \\\n\techo; \\\n\techo '## WARNING:'; \\\n\techo '## The commands \"CC\" and \"LD\" must NOT refer to /usr/ucb/cc'; \\\n\techo '## and /usr/ucb/ld.  If they do, you need to adjust your PATH'; \\\n\techo '## environment variable to put /usr/ccs/bin ahead of /usr/ucb.'; \\\n\techo '## The environment variable LD_LIBRARY_PATH should not be set'; \\\n\techo '## at all.  If it is, things are likely to break because of'; \\\n\techo '## the libucb dependency that is created.'; \\\n\techo; \\\n\t;; \\\n\tesac\n\t$(LD) -G -L$(ZLIBLIB) -R$(ZLIBLIB) -h $(LIBSOMAJ) \\\n\t -o $(LIBSOMAJ) $(OBJSDLL)\n\npngtest: pngtest.o $(LIBSO)\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\ninstall-headers: png.h pngconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOREL)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)/$(LIBSOREL)\n\tchmod 755 $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) $(SUN_CC_FLAGS) -I$(DI) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -o pngtestd -L$(DL) -R$(DL) `$(BINPATH)/$(LIBNAME)-config --ldflags` \\\n\t   $(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB)\n\t./pngtestd pngtest.png\n\ntest-installed:\n\techo\n\techo Testing installed dynamic shared library.\n\t$(CC) $(SUN_CC_FLAGS) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` \\\n\t   $(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB)\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngtesti pngout.png \\\n\tlibpng-config $(LIBSO) $(LIBSOMAJ)* \\\n\tlibpng.pc\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o png.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o pngerror.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o pngrio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o pngwio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o pngmem.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o pngset.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o pngget.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o pngread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o pngrtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o pngrutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o pngtrans.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o pngwrite.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o pngwtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o pngwutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o pngpread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.acorn",
    "content": "# Project:   libpng\n\n\n# Toolflags:\nCCflags = -c -depend !Depend -IC:,Zlib: -g -throwback  -DRISCOS  -fnah\nC++flags = -c -depend !Depend -IC: -throwback\nLinkflags = -aif -c++ -o $@\nObjAsmflags = -throwback -NoCache -depend !Depend\nCMHGflags =\nLibFileflags = -c -l -o $@\nSqueezeflags = -o $@\n\n# Final targets:\n@.libpng-lib:   @.o.png @.o.pngerror @.o.pngrio @.o.pngwio @.o.pngmem \\\n\t@.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngrtran \\\n\t@.o.pngrutil @.o.pngtrans @.o.pngwrite @.o.pngwtran @.o.pngwutil\n\tLibFile $(LibFileflags) @.o.png @.o.pngerror @.o.pngrio @.o.pngrtran \\\n\t@.o.pngmem @.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngwio \\\n\t@.o.pngrutil @.o.pngtrans  @.o.pngwrite @.o.pngwtran @.o.pngwutil\n@.mm-libpng-lib:   @.mm.png @.mm.pngerror @.mm.pngrio @.mm.pngwio @.mm.pngmem \\\n\t@.mm.pngpread @.mm.pngset @.mm.pngget @.mm.pngread @.mm.pngrtran \\\n\t@.mm.pngrutil @.mm.pngtrans @.mm.pngwrite @.mm.pngwtran @.mm.pngwutil\n\tLibFile $(LibFileflags) @.mm.png @.mm.pngerror @.mm.pngrio \\\n\t@.mm.pngwio @.mm.pngmem @.mm.pngpread @.mm.pngset @.mm.pngget \\\n\t@.mm.pngread @.mm.pngrtran @.mm.pngrutil @.mm.pngtrans @.mm.pngwrite \\\n\t@.mm.pngwtran @.mm.pngwutil\n\n\n# User-editable dependencies:\n# (C) Copyright 1997 Tom Tanner\nTest: @.pngtest\n\t<Prefix$Dir>.pngtest\n\t@remove <Prefix$Dir>.pngtest\n\n#It would be nice if you could stop \"make\" listing from here on!\n@.pngtest:   @.o.pngtest @.libpng-lib C:o.Stubs Zlib:zlib_lib\n\tLink $(Linkflags) @.o.pngtest @.libpng-lib C:o.Stubs Zlib:zlib_lib\n\n.SUFFIXES: .o .mm .c\n\n.c.mm:\n\tMemCheck.CC cc $(ccflags) -o $@ LibPng:$<\n.c.o:\n\tcc $(ccflags) -o $@ $<\n\n# See scripts.mak.libpngconf for how to generate this:\n@.h.libpngconf: @.scripts.h.libpngconf\n\tcopy @.scripts.h.libpngconf $@\n\n# Static dependencies:\n@.o.png @.o.pngerror @.o.pngrio @.o.pngwio @.o.pngmem \\\n@.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngrtran \\\n@.o.pngrutil @.o.pngtrans @.o.pngwrite @.o.pngwtran @.o.pngwutil \\\n@.o.pngtest: @.h.libpngconf\n\n\n# Dynamic dependencies:\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.aix",
    "content": "# makefile for libpng using gcc (generic, static library)\n# Copyright (C) 2002, 2006-2009, 2014 Glenn Randers-Pehrson\n# Copyright (C) 2000 Cosmin Truta\n# Copyright (C) 2000 Marc O. Gloor (AIX support added, from makefile.gcc)\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Location of the zlib library and include files\nZLIBINC = ../zlib\nZLIBLIB = ../zlib\n\n# Compiler, linker, lib and other tools\nCC = gcc\nLD = $(CC)\nAR_RC = ar rcs\nMKDIR_P = mkdir -p\nRANLIB = ranlib\nRM_F = rm -f\nLN_SF = ln -f -s\n\nLIBNAME = libpng16\nPNGMAJ = 16\n\nprefix=/usr/local\nINCPATH=$(prefix)/include\nLIBPATH=$(prefix)/lib\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\n\nWARNMORE =\nCPPFLAGS = -I$(ZLIBINC) # -DPNG_DEBUG=5\nCFLAGS = -W -Wall -O2 # $(WARNMORE) -g\nLDFLAGS = -L. -L$(ZLIBLIB) -lpng16 -lz -lm\n\n# Variables\nOBJS =  png.o pngerror.o pngget.o pngmem.o pngpread.o \\\n\tpngread.o pngrio.o pngrtran.o pngrutil.o pngset.o \\\n\tpngtrans.o pngwio.o pngwrite.o pngwtran.o pngwutil.o\n\n# Targets\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\nall: $(LIBNAME).a pngtest$(E)\n\ninclude scripts/pnglibconf.mak\nREMOVE = $(RM_F)\nDFNFLAGS = $(DEFS) $(CPPFLAGS)\n\n$(LIBNAME).a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\ntest: pngtest$(E)\n\t./pngtest$(E)\n\npngtest$(E): pngtest.o $(LIBNAME).a\n\t$(LD) -o $@ pngtest.o $(LDFLAGS)\n\ninstall: $(LIBNAME).a\n\t-@if [ ! -d $(DI)  ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME)  ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DI)/$(LIBNAME)/png.h\n\t-@$(RM_F) $(DI)/$(LIBNAME)/pngconf.h\n\t-@$(RM_F) $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h\n\t-@$(RM_F) $(DI)/pngconf.h\n\t-@$(RM_F) $(DI)/pnglibconf.h\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h \\\n\t$(DI)/$(LIBNAME)/pngconf.h \\\n\t$(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) -r $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\t-@$(RM_F) $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\tcp $(LIBNAME).a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\t(cd $(DI); $(LN_SF) libpng/* .;)\n\nclean:\n\t$(RM_F) *.o $(LIBNAME).a pngtest pngout.png pnglibconf.h\n\npng.o:      png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o:  png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o:  png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.amiga",
    "content": "# Commodore Amiga Makefile\n# makefile for libpng and SAS C V6.5x compiler\n# Copyright (C) 1995-2000 Wolf Faust\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n#\n# Location/path of zlib include files\nZLIB=/zlib\n#compiler\nCC=sc\n#compiler flags\n# WARNING: a bug in V6.51 causes bad code with OPTGO\n#          So use V6.55 or set NOOPTGO!!!!!!!!!\nCFLAGS= NOSTKCHK PARMS=REG OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL\\\n\tOPTLOOP OPTRDEP=4 OPTDEP=4 OPTCOMP=4 INCLUDEDIR=$(ZLIB) \\\n\tDEFINE=PNG_INTERNAL\n#linker flags\nLDFLAGS= SD ND BATCH\n#link libs\nLDLIBS= libpng.lib libgz.lib LIB:scm.lib LIB:sc.lib Lib:amiga.lib\n# linker\nLN= slink\n# file deletion command\nRM= delete quiet\n# library (.lib) file creation command\nAR= oml\n# make directory command\nMKDIR= makedir\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\nall: libpng.lib pngtest\n\nlibpng.lib: $(OBJS)\n-$(RM) libpng.lib\n$(AR) libpng.lib r $(OBJS)\n\n$(OBJS): pngpriv.h png.h pngconf.h pnglibconf.h pnginfo.h pngstruct.h pngdebug.h\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\nCOPY $(PNGLIBCONF_H_PREBUILT) TO pnglibconf.h\n\npngtest: pngtest.o libpng.lib\n$(LN) <WITH <\n$(LDFLAGS)\nTO pngtest\nFROM LIB:c.o pngtest.o\nLIB $(LDLIBS)\n<\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.atari",
    "content": "# makefile for libpng\n# Copyright (C) 2002, 2014 Glenn Randers-Pehrson\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n#\n# Modified for LC56/ATARI assumes libz.lib is in same dir and uses default\n# rules for library management\n#\nCPPFLAGS = -I..\\zlib\nCFLAGS = -O\nLBR = png.lib\nLDFLAGS = -L. -L..\\zlib -lpng -lz -lm\n\n# where make install puts libpng.a and png.h\nprefix=/usr/local\nINCPATH=$(prefix)/include\nLIBPATH=$(prefix)/lib\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = $(LBR)(png.o) $(LBR)(pngset.o) $(LBR)(pngget.o) $(LBR)(pngrutil.o)\\\n\t$(LBR)(pngtrans.o) $(LBR)(pngwutil.o)\\\n\t$(LBR)(pngread.o) $(LBR)(pngerror.o) $(LBR)(pngwrite.o)\\\n\t$(LBR)(pngrtran.o) $(LBR)(pngwtran.o)\\\n\t$(LBR)(pngmem.o) $(LBR)(pngrio.o) $(LBR)(pngwio.o) $(LBR)(pngpread.o)\n\nall: $(LBR) pngtest.ttp\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $<\n\n$(LBR): $(OBJS)\n\n$(OBJS): pngpriv.h png.h pngconf.h pnglibconf.h pnginfo.h pngstruct.h pngdebug.h\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\tcp $(PNGLIBCONF_H_PREBUILT) $@\n\npngtest.ttp: pngtest.o $(LBR)\n\t$(CC) $(CFLAGS) $(LDFLAGS) -o$@ pngtest.o\n\ninstall: libpng.a\n\t-@mkdir $(DESTDIR)$(INCPATH)\n\t-@mkdir $(DESTDIR)$(INCPATH)/libpng\n\t-@mkdir $(DESTDIR)$(LIBPATH)\n\t-@rm -f $(DESTDIR)$(INCPATH)/png.h\n\t-@rm -f $(DESTDIR)$(INCPATH)/pngconf.h\n\t-@rm -f $(DESTDIR)$(INCPATH)/pnglibconf.h\n\tcp png.h $(DESTDIR)$(INCPATH)/libpng\n\tcp pngconf.h $(DESTDIR)$(INCPATH)/libpng\n\tcp pnglibconf.h $(DESTDIR)$(INCPATH)/libpng\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/pnglibconf.h\n\t(cd $(DESTDIR)$(INCPATH); ln -f -s $(LIBNAME) libpng; \\\n\tln -f -s $(LIBNAME)/* .)\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.bc32",
    "content": "# Makefile for libpng\n# 32-bit Borland C++ (Note: All modules are compiled in C mode)\n# To build the library, do:\n#       \"make -fmakefile.bc32\"\n#\n# -------------------- 32-bit Borland C++ --------------------\n\n### Absolutely necessary for this makefile to work\n.AUTODEPEND\n\n## Where zlib.h, zconf.h and zlib.lib are\nZLIB_DIR=..\\zlib\n\n## Compiler, linker, librarian and other tools\nCC=bcc32\nLD=bcc32\nLIB=tlib\nCP=copy\n\n# -3 = 386, -4 = 486, -5 = Pentium etc.\n!ifndef TARGET_CPU\n#TARGET_CPU=-6\n!endif\n\n# Use this if you don't want Borland's fancy exception handling\n# (Caution: doesn't work with CBuilderX)\n#NOEHLIB=noeh32.lib\n\n!ifdef DEBUG\nCDEBUG=-v\nLDEBUG=-v\n!else\nCDEBUG=\nLDEBUG=\n!endif\n\n# STACKOFLOW=1\n!ifdef STACKOFLOW\nCDEBUG=$(CDEBUG) -N\nLDEBUG=$(LDEBUG) -N\n!endif\n\n# -O2 optimize for speed\n# -d  merge duplicate strings\n# -k- turn off standard stack frame\n# -w  display all warnings\nCPPFLAGS=-I$(ZLIB_DIR)\nCFLAGS=-O2 -d -k- -w $(TARGET_CPU) $(CDEBUG)\n\n# -M  generate map file\nLDFLAGS=-L$(ZLIB_DIR) -M $(LDEBUG)\n\n# Pre-built configuration\n# See scripts\\pnglibconf.mak for more options\n!ifndef PNGLIBCONF_H_PREBUILT\nPNGLIBCONF_H_PREBUILT = scripts\\pnglibconf.h.prebuilt\n!endif\n\n## Variables\nOBJS = \\\n\tpng.obj \\\n\tpngerror.obj \\\n\tpngget.obj \\\n\tpngmem.obj \\\n\tpngpread.obj \\\n\tpngread.obj \\\n\tpngrio.obj \\\n\tpngrtran.obj \\\n\tpngrutil.obj \\\n\tpngset.obj \\\n\tpngtrans.obj \\\n\tpngwio.obj \\\n\tpngwrite.obj \\\n\tpngwtran.obj \\\n\tpngwutil.obj\n\nLIBOBJS = \\\n\t+png.obj \\\n\t+pngerror.obj \\\n\t+pngget.obj \\\n\t+pngmem.obj \\\n\t+pngpread.obj \\\n\t+pngread.obj \\\n\t+pngrio.obj \\\n\t+pngrtran.obj \\\n\t+pngrutil.obj \\\n\t+pngset.obj \\\n\t+pngtrans.obj \\\n\t+pngwio.obj \\\n\t+pngwrite.obj \\\n\t+pngwtran.obj \\\n\t+pngwutil.obj\n\nLIBNAME=libpng.lib\n\n## Implicit rules\n# Braces let make \"batch\" calls to the compiler,\n# 2 calls instead of 12; space is important.\n.c.obj:\n\t$(CC) $(CPPFLAGS) $(CFLAGS) -c {$*.c }\n\n.c.exe:\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $*.c \\\n\t  $(LIBNAME) zlib.lib $(NOEHLIB)\n\n.obj.exe:\n\t$(LD) $(LDFLAGS) $*.obj $(LIBNAME) zlib.lib $(NOEHLIB)\n\n## Major targets\nall: libpng pngtest\n\nlibpng: $(LIBNAME)\n\npngtest: pngtest.exe\n\ntest: pngtest.exe\n\tpngtest\n\n## Minor Targets\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\npng.obj: png.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.obj: pngerror.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.obj: pngget.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.obj: pngmem.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.obj: pngpread.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.obj: pngread.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.obj: pngrio.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.obj: pngrtran.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.obj: pngrutil.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.obj: pngset.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.obj: pngtrans.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.obj: pngwio.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.obj: pngwrite.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.obj: pngwtran.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.obj: pngwutil.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtest.obj: pngtest.c png.h pngconf.h pnglibconf.h\n\n$(LIBNAME): $(OBJS)\n\t-del $(LIBNAME)\n\t$(LIB) $(LIBNAME) @&&|\n$(LIBOBJS), libpng\n|\n\n# Cleanup\nclean:\n\t-del pnglibconf.h\n\t-del *.obj\n\t-del $(LIBNAME)\n\t-del pngtest.exe\n\t-del *.lst\n\t-del *.map\n\t-del *.tds\n\t-del pngout.png\n\n# End of makefile for libpng\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.beos",
    "content": "# makefile for libpng on BeOS x86 ELF with gcc\n# modified from makefile.linux by Sander Stoks\n# Copyright (C) 2002, 2006, 2008, 2010-2014 Glenn Randers-Pehrson\n# Copyright (C) 1999 Greg Roelofs\n# Copyright (C) 1996, 1997 Andreas Dilger\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Library name:\nLIBNAME=libpng16\nPNGMAJ = 16\n\n# Shared library names:\nLIBSO=$(LIBNAME).so\nLIBSOMAJ=$(LIBNAME).so.$(PNGMAJ)\nLIBSOREL=$(LIBSOMAJ).$(RELEASE)\nOLDSO=libpng.so\n\n# Utilities:\nCC=gcc\nAR_RC=ar rc\nMKDIR_P=mkdir -p\nLN_SF=ln -sf\nRANLIB=ranlib\nCP=cp\nRM_F=/bin/rm -f\n\n# Where the zlib library and include files are located\nZLIBLIB=/usr/local/lib\nZLIBINC=/usr/local/include\n\nALIGN=\n# For i386:\n# ALIGN=-malign-loops=2 -malign-functions=2\n\nWARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \\\n\t-Wmissing-declarations -Wtraditional -Wcast-align \\\n\t-Wstrict-prototypes -Wmissing-prototypes #-Wconversion\n\n# On BeOS, -O1 is actually better than -O3.  This is a known bug but it's\n# still here in R4.5\nCPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5\nCFLAGS=-W -Wall -O1 -funroll-loops $(ALIGN) # $(WARNMORE) -g\n# LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng -lz\nLDFLAGS=-L. -Wl,-soname=$(LIBSOMAJ) -L$(ZLIBLIB) -lz\n\n# where make install puts libpng.a, libpng16.so*, and png.h\nprefix=/usr/local\nexec_prefix=$(prefix)\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\nOBJSDLL = $(OBJS)\n\n.SUFFIXES:      .c .o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\nall: libpng.a $(LIBSO) pngtest libpng.pc libpng-config\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo libs=\\\"-lpng16 -lz \\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\tcp $(LIBSO)* /boot/home/config/lib\n\n$(LIBSOMAJ): $(OBJSDLL)\n\t$(CC) -nostart -Wl,-soname,$(LIBSOMAJ) -o \\\n\t$(LIBSOMAJ) $(OBJSDLL) $(LDFLAGS)\n\npngtest: pngtest.o $(LIBSO)\n\t$(CC) -L$(ZLIBLIB) -L. -lz -lpng16 -o pngtest pngtest.o\n\ntest: pngtest\n\t./pngtest\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOREL)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)/$(LIBSOREL)\n\tchmod 755 $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) -I$(DI) $(CPPFLAGS) $(CFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(DL) -L$(ZLIBLIB) -Wl,-rpath $(ZLIBLIB):$(DL) \\\n\t   -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtestd pngtest.png\n\ntest-installed:\n\t$(CC) $(CPPFLAGS) $(CFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngout.png libpng-config \\\n\t$(LIBSO) $(LIBSOMAJ)* pngtesti \\\n\tpnglibconf.h libpng.pc\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o png.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o pngerror.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o pngrio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o pngwio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o pngmem.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o pngset.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o pngget.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o pngread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o pngrtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o pngrutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o pngtrans.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o pngwrite.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o pngwtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o pngwutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o pngpread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.bor",
    "content": "# Makefile for libpng\n# 16-bit Borland C++ (Note: All modules are compiled in C mode)\n# To build the library, do:\n#       \"make -fmakefile.bor -DMODEL=c\"\n# or:   \"make -fmakefile.bor -DMODEL=l\"\n#\n# ------------ Borland C++ ------------\n\n### Absolutely necessary for this makefile to work\n.AUTODEPEND\n\n## Where zlib.h, zconf.h and zlib_MODEL.lib are\nZLIB_DIR=..\\zlib\n\n## Compiler, linker, librarian and other tools\nCC=bcc\nLD=bcc\nLIB=tlib\nCP=copy\n\n!ifndef MODEL\nMODEL=l\n!endif\n\nMODEL_ARG=-m$(MODEL)\n\n#TARGET_CPU=3\n# 2 = 286, 3 = 386, etc.\n!ifndef TARGET_CPU\nTARGET_CPU=2\n!endif\n\n# Use this if you don't want Borland's fancy exception handling\n# (for Borland C++ 4.0 or later)\n#NOEHLIB=noeh$(MODEL).lib\n\n!ifdef DEBUG\nCDEBUG=-v\nLDEBUG=-v\n!else\nCDEBUG=\nLDEBUG=\n!endif\n\n# STACKOFLOW=1\n!ifdef STACKOFLOW\nCDEBUG=$(CDEBUG) -N\nLDEBUG=$(LDEBUG) -N\n!endif\n\n# -X- turn on dependency generation in the object file\n# -w  set all warnings on\n# -O2 optimize for speed\n# -Z  global optimization\nCPPFLAGS=-I$(ZLIB_DIR)\nCFLAGS=-O2 -Z -X- -w -$(TARGET_CPU) $(MODEL_ARG) $(CDEBUG)\n\n# -M  generate map file\nLDFLAGS=-M -L$(ZLIB_DIR) $(MODEL_ARG) $(LDEBUG)\n\n# Pre-built configuration\n# See scripts\\pnglibconf.mak for more options\n!ifndef PNGLIBCONF_H_PREBUILT\nPNGLIBCONF_H_PREBUILT = scripts\\pnglibconf.h.prebuilt\n!endif\n\n## Variables\n\nOBJS = \\\n\tpng.obj \\\n\tpngerror.obj \\\n\tpngget.obj \\\n\tpngmem.obj \\\n\tpngpread.obj \\\n\tpngread.obj \\\n\tpngrio.obj \\\n\tpngrtran.obj \\\n\tpngrutil.obj \\\n\tpngset.obj \\\n\tpngtrans.obj \\\n\tpngwio.obj \\\n\tpngwrite.obj \\\n\tpngwtran.obj \\\n\tpngwutil.obj\n\nLIBOBJS = \\\n\t+png.obj \\\n\t+pngerror.obj \\\n\t+pngget.obj \\\n\t+pngmem.obj \\\n\t+pngpread.obj \\\n\t+pngread.obj \\\n\t+pngrio.obj \\\n\t+pngrtran.obj \\\n\t+pngrutil.obj \\\n\t+pngset.obj \\\n\t+pngtrans.obj \\\n\t+pngwio.obj \\\n\t+pngwrite.obj \\\n\t+pngwtran.obj \\\n\t+pngwutil.obj\n\nLIBNAME=libpng$(MODEL).lib\n\n## Implicit rules\n\n# Braces let make \"batch\" calls to the compiler,\n# 2 calls instead of 12; space is important.\n.c.obj:\n\t$(CC) $(CPPFLAGS) $(CFLAGS) -c {$*.c }\n\n.c.exe:\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $*.c \\\n\t  $(LIBNAME) zlib_$(MODEL).lib $(NOEHLIB)\n\n## Major targets\n\nall: libpng pngtest\n\n# try !include scripts\\pnglibconf.mak for more options\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng: $(LIBNAME)\n\npngtest: pngtest$(MODEL).exe\n\ntest: pngtest$(MODEL).exe\n\tpngtest$(MODEL)\n\n## Minor Targets\n\npng.obj: png.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.obj: pngerror.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.obj: pngget.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.obj: pngmem.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.obj: pngpread.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.obj: pngread.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.obj: pngrio.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.obj: pngrtran.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.obj: pngrutil.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.obj: pngset.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.obj: pngtrans.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.obj: pngwio.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.obj: pngwrite.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.obj: pngwtran.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.obj: pngwutil.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\n$(LIBNAME): $(OBJS)\n\t-del $(LIBNAME)\n\t$(LIB) $(LIBNAME) @&&|\n$(LIBOBJS), libpng$(MODEL)\n|\n\npngtest$(MODEL).obj: pngtest.c png.h pngconf.h pnglibconf.h\n\t$(CC) $(CFLAGS) -opngtest$(MODEL) -c pngtest.c\n\npngtest$(MODEL).exe: pngtest$(MODEL).obj\n\t$(LD) $(LDFLAGS) pngtest$(MODEL).obj $(LIBNAME) zlib_$(MODEL).lib $(NOEHLIB)\n\n# Clean up anything else you want\nclean:\n\t-del pnglibconf.h\n\t-del *.obj\n\t-del *.exe\n\t-del *.lib\n\t-del *.lst\n\t-del *.map\n\n# End of makefile for libpng\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.cegcc",
    "content": "# Makefile for creating Windows CE release archives, with the\n# mingw32ce compiler.\n\n# Last updated: 22-Jul-2008\n\n# Copyright (C) 2008 Vincent Torri\n\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# To get some help, type\n#\n# make help\n#\n# To create the archives\n#\n# make\n#\n# To remove everything, type:\n#\n# make clean\n\nVERMAJ = 1\nVERMIN = 6\nVERMIC = 22\nVER = $(VERMAJ).$(VERMIN).$(VERMIC)\nNAME = libpng\nPACKAGE = $(NAME)-$(VER)\n\nBIN = libpng16-0.dll\nLIB = libpng16.a libpng16.dll.a libpng.a libpng.dll.a\nINCLUDE = png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\nPC = libpng16.pc libpng.pc\n\nMANIFESTVERBIN = \"Libpng-$(VER): Binary files\"\nMANIFESTVERDEV = \"Libpng-$(VER): Developer files\"\nMANIFESTVERDESC = \"Libpng: the official PNG reference library\"\n\nall: $(NAME)\n\n$(NAME): remove-old copy-src compilation copy manifest archive\n\t@echo \" * Removal of the directories\"\n\t@rm -rf $(PACKAGE)/ $(PACKAGE)-bin/ $(PACKAGE)-dev/\n\nremove-old:\n\t@echo \" * Removal of the old files\"\n\t@rm -rf $(PACKAGE)-bin*\n\t@rm -rf $(PACKAGE)-dev*\n\ncopy-src:\n\t@echo \" * Copy of source files\"\n\t@cp -R ../src/$(PACKAGE) .\n\t@echo \" * Creation of directories and files\"\n\t@mkdir -p $(PACKAGE)-bin/bin\n\t@mkdir -p $(PACKAGE)-bin/manifest\n\t@mkdir -p $(PACKAGE)-dev/lib/pkgconfig\n\t@mkdir -p $(PACKAGE)-dev/include/$(NAME)$(VERMAJ)$(VERMIN)\n\t@mkdir -p $(PACKAGE)-dev/manifest\n\t@touch $(PACKAGE)-bin/manifest/$(PACKAGE)-bin.mft\n\t@touch $(PACKAGE)-bin/manifest/$(PACKAGE)-bin.ver\n\t@touch $(PACKAGE)-dev/manifest/$(PACKAGE)-dev.mft\n\t@touch $(PACKAGE)-dev/manifest/$(PACKAGE)-dev.ver\n\ncompilation:\n\t@echo \" * Compilation of $(PACKAGE)\"\n\tcd $(PACKAGE) && CPPFLAGS=\"$(CPPFLAGS) -DPNG_CONSOLE_IO_SUPPORTED -D_WIN32_WCE=0x0420\" \\\n\t\tCFLAGS=\"$(CFLAGS) -mms-bitfields -O3 -pipe -fomit-frame-pointer\" \\\n\t\tLDFLAGS=\"$(LDFLAGS) -Wl,--enable-auto-import -Wl,-s\" \\\n\t\t./configure --prefix=/opt/wince --host=arm-mingw32ce && make\n\ncopy:\n\t@echo \" * Copy of binary and development files\"\n\t@for i in $(BIN); do \\\n\t  cp $(PACKAGE)/.libs/$$i $(PACKAGE)-bin/bin; \\\n\tdone\n\t@for i in $(LIB); do \\\n\t  cp $(PACKAGE)/.libs/$$i $(PACKAGE)-dev/lib; \\\n\tdone\n\t@for i in $(INCLUDE); do \\\n\t  cp $(PACKAGE)/$$i $(PACKAGE)-dev/include/$(NAME)$(VERMAJ)$(VERMIN); \\\n\tdone\n\t@for i in $(PC); do \\\n\t  cp $(PACKAGE)/$$i $(PACKAGE)-dev/lib/pkgconfig; \\\n\tdone\n\nmanifest:\n\t@echo \" * Creation of the manifest\"\n\t@cd $(PACKAGE)-bin && find * >> manifest/$(PACKAGE)-bin.mft\n\t@cd $(PACKAGE)-bin && \\\n\t  echo $(MANIFESTVERBIN) >> manifest/$(PACKAGE)-bin.ver && \\\n\t  echo $(MANIFESTVERDESC) >> manifest/$(PACKAGE)-bin.ver\n\t@cd $(PACKAGE)-dev && find * >> manifest/$(PACKAGE)-dev.mft\n\t@cd $(PACKAGE)-dev && \\\n\t  echo $(MANIFESTVERDEV) >> manifest/$(PACKAGE)-dev.ver && \\\n\t  echo $(MANIFESTVERDESC) >> manifest/$(PACKAGE)-dev.ver\n\narchive:\n\t@echo \" * Creation of the archives\"\n\t@tar cf $(PACKAGE)-bin.tar $(PACKAGE)-bin\n\t@bzip2 -9 $(PACKAGE)-bin.tar\n\t@tar cf $(PACKAGE)-dev.tar $(PACKAGE)-dev\n\t@bzip2 -9 $(PACKAGE)-dev.tar\n\nclean:\n\t@echo \" * Cleaning\"\n\t@rm -rf $(PACKAGE)*\n\nhelp:\n\t@echo\n\t@echo \"To create the archives, type:\"\n\t@echo \" make\"\n\t@echo\n\t@echo \"To remove everything, type:\"\n\t@echo \" make clean\"\n\t@echo\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.darwin",
    "content": "# makefile for libpng on Darwin / Mac OS X\n# Copyright (C) 2002, 2004, 2006, 2008, 2010-2014 Glenn Randers-Pehrson\n# Copyright (C) 2001 Christoph Pfisterer\n# derived from makefile.linux:\n#  Copyright (C) 1998, 1999 Greg Roelofs\n#  Copyright (C) 1996, 1997 Andreas Dilger\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# where \"make install\" puts libpng.a, libpng16.dylib, png.h, pngconf.h,\n# and pnglibconf.h\nprefix=/usr/local\nexec_prefix=$(prefix)\n\n# Where the zlib library and include files are located\nZLIBLIB=/usr/lib\nZLIBINC=/usr/include\n\n# Library name:\nLIBNAME = libpng16\nPNGMAJ = 16\n\n# Shared library names:\nLIBSO=$(LIBNAME).dylib\nLIBSOMAJ=$(LIBNAME).$(PNGMAJ).dylib\nLIBSOREL=$(LIBNAME).$(PNGMAJ).$(RELEASE).dylib\nOLDSO=libpng.dylib\n\n# Utilities:\nCC=cc\nAR_RC=ar rc\nMKDIR_P=mkdir -p\nLN_SF=ln -sf\nRANLIB=ranlib\nCP=cp\nRM_F=/bin/rm -f\n\nCPPFLAGS=-I$(ZLIBINC)\n# CFLAGS=-W -Wall -O3 -funroll-loops\nCFLAGS=-W -Wall -O -funroll-loops\nLDFLAGS=-L. -L$(ZLIBLIB) -lpng16 -lz\n\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\nOBJSDLL = $(OBJS:.o=.pic.o)\n\n.SUFFIXES:      .c .o .pic.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\n.c.pic.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -fno-common -o $@ $*.c\n\nall: libpng.a $(LIBSO) pngtest libpng.pc libpng-config\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo L_opts=\\\"-L$(LIBPATH)\\\"; \\\n\techo libs=\\\"-lpng16 -lz\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ): $(OBJSDLL)\n\t$(CC) -dynamiclib \\\n\t -install_name $(LIBPATH)/$(LIBSOMAJ) \\\n\t -current_version 16 -compatibility_version 16 \\\n\t -o $(LIBSOMAJ) \\\n\t $(OBJSDLL) -L$(ZLIBLIB) -lz\n\npngtest: pngtest.o $(LIBSO)\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t$(RANLIB) $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOMAJ)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)\n\tchmod 755 $(DL)/$(LIBSOMAJ)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) -I$(DI) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(DL) -L$(ZLIBLIB) \\\n\t   -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtestd pngtest.png\n\ntest-installed:\n\t$(CC) $(CPPFLAGS) $(CFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(ZLIBLIB) \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngout.png libpng-config \\\n\tlibpng.pc $(LIBNAME).*dylib pngtesti pnglibconf.h\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o png.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o pngerror.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o pngrio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o pngwio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o pngmem.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o pngset.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o pngget.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o pngread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o pngrtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o pngrutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o pngtrans.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o pngwrite.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o pngwtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o pngwutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o pngpread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.dec",
    "content": "# makefile for libpng on DEC Alpha Unix\n# Copyright (C) 2000-2002, 2006, 2010-2014 Glenn Randers-Pehrson\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Library name:\nPNGMAJ = 16\nLIBNAME = libpng16\n\n# Shared library names:\nLIBSO=$(LIBNAME).so\nLIBSOMAJ=$(LIBNAME).so.$(PNGMAJ)\nLIBSOREL=$(LIBSOMAJ).$(RELEASE)\nOLDSO=libpng.so\n\n# Utilities:\nAR_RC=ar rc\nCC=cc\nMKDIR_P=mkdir\nLN_SF=ln -f -s\nRANLIB=ranlib\nCP=cp\nRM_F=/bin/rm -f\n\n# where make install puts libpng.a and png.h\nprefix=/usr/local\nexec_prefix=$(prefix)\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\n# Where the zlib library and include files are located\n#ZLIBLIB=/usr/local/lib\n#ZLIBINC=/usr/local/include\nZLIBLIB=../zlib\nZLIBINC=../zlib\n\nCPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5\nCFLAGS=-std -w1 -O # -g\nLDFLAGS=-L$(ZLIBLIB) -rpath $(ZLIBLIB) libpng.a -lz -lm\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\nall: $(LIBSO) libpng.a pngtest libpng.pc libpng-config\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@  $(OBJS)\n\t$(RANLIB) $@\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo ccopts=\\\"-std\\\"; \\\n\techo L_opts=\\\"-L$(LIBPATH)\\\"; \\\n\techo libs=\\\"-lpng16 -lz -lm\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ): $(OBJS)\n\t$(CC) -shared -o $@ $(OBJS) -L$(ZLIBLIB) \\\n\t-soname $(LIBSOMAJ)\n\npngtest: pngtest.o libpng.a\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@/bin/rm -f $(DI)/libpng\n\t(cd $(DI); $(LN_SF)(LIBNAME) libpng; $(LN_SF)(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t-@/bin/rm -f $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF)(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOREL)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)/$(LIBSOREL)\n\tchmod 755 $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@/bin/rm -f $(DM)/man3/libpng.3\n\t-@/bin/rm -f $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@/bin/rm -f $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@/bin/rm -f $(DB)/libpng-config\n\t-@/bin/rm -f $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF)(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) -w1 -I$(DI) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(DL) -L$(ZLIBLIB)  -R$(ZLIBLIB) -R$(DL) \\\n\t   -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtestd pngtest.png\n\ntest-installed:\n\techo\n\techo Testing installed dynamic shared library.\n\t$(CC) -w1 $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(ZLIBLIB) -R$(ZLIBLIB) \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngtesti pngout.png \\\n\tlibpng-config $(LIBSO) $(LIBSOMAJ)* \\\n\tlibpng.pc pnglibconf.h\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.dj2",
    "content": "# DJGPP (DOS gcc) makefile for libpng\n# Copyright (C) 2002, 2006, 2009-2014 Glenn Randers-Pehrson\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# where make install will put libpng.a and png.h\n#prefix=/usr/local\nprefix=.\nINCPATH=$(prefix)/include\nLIBPATH=$(prefix)/lib\n\nCC=gcc\nCPPFLAGS=-I../zlib -DPNG_NO_SNPRINTF\nCFLAGS=-O\nLDFLAGS=-L. -L../zlib/ -lpng -lz -lm\n\nRANLIB=ranlib\n\nCP=cp\nRM_F=rm -f\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o pngwtran.o \\\n\tpngmem.o pngerror.o pngpread.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\nall: libpng.a pngtest\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\tar rc $@  $(OBJS)\n\t$(RANLIB) $@\n\npngtest: pngtest.o libpng.a\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\tcoff2exe pngtest\n\ntest: pngtest\n\t./pngtest\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngout.png pnglibconf.h\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.freebsd",
    "content": "# makefile for libpng under FreeBSD\n# Copyright (C) 2014 Glenn Randers-Pehrson and Andrey A. Chernov\n# Copyright (C) 2002, 2007, 2009 Glenn Randers-Pehrson and Andrey A. Chernov\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\nPREFIX?=        /usr/local\nSHLIB_VER?=     16\n\nLIB=\t\tpng\nSHLIB_MAJOR=\t${SHLIB_VER}\nSHLIB_MINOR=\t0\nNO_PROFILE=\tYES\nNO_OBJ=\t\tYES\n\n# where make install puts libpng.a and png.h\nDESTDIR=\t${PREFIX}\nLIBDIR=\t\t/lib\nINCS=\t\tpng.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\nINCSDIR=\t/include/libpng\nINCDIR=\t\t${INCSDIR}\t\t# for 4.x bsd.lib.mk\nMAN=\t\tlibpng.3 libpngpf.3 png.5\nMANDIR=\t\t/man/man\nSYMLINKS=       libpng/png.h ${INCSDIR}/../png.h \\\n\t\tlibpng/pngconf.h ${INCSDIR}/../pngconf.h \\\n\t\tlibpng/pnglibconf.h ${INCSDIR}/../pnglibconf.h\n\n# where make install finds libz.a and zlib.h\nZLIBLIB=\t/usr/lib\nZLIBINC=\t/usr/include\n\nLDADD+=\t\t-lm -lz\n#LDADD+=\t-lm -lz -lssp_nonshared   # for OSVERSION < 800000 ?\n\nDPADD+=\t\t${LIBM} ${LIBZ}\n\nCPPFLAGS+=\t-I. -I${ZLIBINC}\nCFLAGS+=\t-W -Wall\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT= scripts/pnglibconf.h.prebuilt\n\nSRCS=\tpng.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \\\n\tpngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \\\n\tpngwtran.c pngmem.c pngerror.c pngpread.c\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\npngtest: pngtest.o libpng.a\n\t${CC} ${CFLAGS} -L. -static -o pngtest pngtest.o -L${ZLIBLIB} \\\n\t-lpng ${LDADD}\n\nCLEANFILES= pngtest pngtest.o pngout.png\n\ntest: pngtest\n\t./pngtest\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\tcp $(PNGLIBCONF_H_PREBUILT) $@\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n.include <bsd.lib.mk>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.gcc",
    "content": "# makefile for libpng using gcc (generic, static library)\n# Copyright (C) 2008, 2014 Glenn Randers-Pehrson\n# Copyright (C) 2000 Cosmin Truta\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Location of the zlib library and include files\nZLIBINC = ../zlib\nZLIBLIB = ../zlib\n\n# Compiler, linker, lib and other tools\nCC = gcc\nLD = $(CC)\nAR_RC = ar rcs\nRANLIB = ranlib\nCP = cp\nRM_F = rm -f\n\nWARNMORE = -Wwrite-strings -Wpointer-arith -Wshadow \\\n\t-Wmissing-declarations -Wtraditional -Wcast-align \\\n\t-Wstrict-prototypes -Wmissing-prototypes # -Wconversion\nCPPFLAGS = -I$(ZLIBINC) # -DPNG_DEBUG=5\nCFLAGS = -W -Wall -O2 # $(WARNMORE) -g\nLDFLAGS =\nLIBS = -lz -lm\n\n# File extensions\nEXEEXT =\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\n# Variables\nOBJS =  png.o pngerror.o pngget.o pngmem.o pngpread.o \\\n\tpngread.o pngrio.o pngrtran.o pngrutil.o pngset.o \\\n\tpngtrans.o pngwio.o pngwrite.o pngwtran.o pngwutil.o\n\n# Targets\nall: static\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\nstatic: libpng.a pngtest$(EXEEXT)\n\nshared:\n\t@echo This is a generic makefile that cannot create shared libraries.\n\t@echo Please use a configuration that is specific to your platform.\n\t@false\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\ntest: pngtest$(EXEEXT)\n\t./pngtest$(EXEEXT)\n\npngtest$(EXEEXT): pngtest.o libpng.a\n\t$(LD) $(LDFLAGS) -L$(ZLIBLIB) -o $@ pngtest.o libpng.a $(LIBS)\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest$(EXEEXT) pngout.png pnglibconf.h\n\npng.o:      png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o:  png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o:  png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.hp64",
    "content": "# makefile for libpng, HPUX (10.20 and 11.00) using the ANSI/C product.\n# Copyright (C) 1999-2002, 2006, 2009, 2010-2014 Glenn Randers-Pehrson\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42\n# contributed by Jim Rice and updated by Chris Schleicher, Hewlett Packard\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Where the zlib library and include files are located\nZLIBLIB=/opt/zlib/lib\nZLIBINC=/opt/zlib/include\n\n# Note that if you plan to build a libpng shared library, zlib must also\n# be a shared library, which zlib's configure does not do.  After running\n# zlib's configure, edit the appropriate lines of makefile to read:\n#   CFLAGS=-O1 -DHAVE_UNISTD -DUSE_MAP -fPIC \\\n#   LDSHARED=ld -b\n#   SHAREDLIB=libz.sl\n\n# Library name:\nLIBNAME = libpng16\nPNGMAJ = 16\n\n# Shared library names:\nLIBSO=$(LIBNAME).sl\nLIBSOMAJ=$(LIBNAME).sl.$(PNGMAJ)\nLIBSOREL=$(LIBSOMAJ).$(RELEASE)\nOLDSO=libpng.sl\n\n# Utilities:\nAR_RC=ar rc\nCC=cc\nMKDIR_P=mkdir -p\nLN_SF=ln -sf\nRANLIB=ranlib\nCP=cp\nRM_F=/bin/rm -f\n\nCPPFLAGS=-I$(ZLIBINC) \\\n        -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_UNISTD_H -DUSE_MMAP\nCFLAGS=-O -Ae -Wl,+vnocompatwarnings +DD64 +Z\n# Caution: be sure you have built zlib with the same CFLAGS.\nCCFLAGS=-O -Ae -Wl,+vnocompatwarnings +DD64 +Z\n\nLDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm\n\n# where make install puts libpng.a, libpng16.sl, and png.h\nprefix=/opt/libpng\nexec_prefix=$(prefix)\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\nOBJSDLL = $(OBJS:.o=.pic.o)\n\n.SUFFIXES:\t.c .o .pic.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\n.c.pic.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) +z -o $@ $*.c\n\nall: libpng.a $(LIBSO) pngtest libpng.pc libpng-config\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo ccopts=\\\"-O -Ae -Wl,+vnocompatwarnings +DD64 +Z\\\"; \\\n\techo L_opts=\\\"-L$(LIBPATH)\\\"; \\\n\techo libs=\\\"-lpng16 -lz -lm\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ): $(OBJSDLL)\n\t$(LD) -b +s \\\n\t+h $(LIBSOMAJ) -o $(LIBSOMAJ) $(OBJSDLL)\n\npngtest: pngtest.o libpng.a\n\t$(CC) -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOREL)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)/$(LIBSOREL)\n\tchmod 755 $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) -I$(DI) $(CPPFLAGS) $(CCFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(DL) -L$(ZLIBLIB) \\\n\t   -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtestd pngtest.png\n\ntest-installed:\n\techo\n\techo Testing installed dynamic shared library.\n\t$(CC) $(CPPFLAGS) $(CCFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(ZLIBLIB) \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngtesti pngout.png \\\n\tlibpng-config $(LIBSO) $(LIBSOMAJ)* \\\n\tlibpng.pc pnglibconf.h\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.hpgcc",
    "content": "# makefile for libpng on HP-UX using GCC with the HP ANSI/C linker.\n# Copyright (C) 2002, 2006-2008, 2010-2014 Glenn Randers-Pehrson\n# Copyright (C) 2001, Laurent faillie\n# Copyright (C) 1998, 1999 Greg Roelofs\n# Copyright (C) 1996, 1997 Andreas Dilger\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Library name:\nLIBNAME = libpng16\nPNGMAJ = 16\n\n# Shared library names:\nLIBSO=$(LIBNAME).sl\nLIBSOMAJ=$(LIBNAME).sl.$(PNGMAJ)\nLIBSOREL=$(LIBSOMAJ).$(RELEASE)\nOLDSO=libpng.sl\n\n# Utilities:\nCC=gcc\nLD=ld\nAR_RC=ar rc\nMKDIR_P=mkdir -p\nLN_SF=ln -sf\nRANLIB=ranlib\nCP=cp\nRM_F=/bin/rm -f\n\n# where \"make install\" puts libpng.a, $(OLDSO)*, png.h, pngconf.h\n# and pnglibconf.h\nprefix=/usr/local\nexec_prefix=$(prefix)\n\n# Where the zlib library and include files are located\nZLIBLIB=/opt/zlib/lib\nZLIBINC=/opt/zlib/include\n\n# Note that if you plan to build a libpng shared library, zlib must also\n# be a shared library, which zlib's configure does not do.  After running\n# zlib's configure, edit the appropriate lines of makefile to read:\n#   CFLAGS=-O1 -DHAVE_UNISTD -DUSE_MAP -fPIC \\\n#   LDSHARED=ld -b\n#   SHAREDLIB=libz.sl\n\nALIGN=\n# for i386:\n#ALIGN=-malign-loops=2 -malign-functions=2\n\nWARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \\\n\t-Wmissing-declarations -Wtraditional -Wcast-align \\\n\t-Wstrict-prototypes -Wmissing-prototypes #-Wconversion\n\n# for pgcc version 2.95.1, -O3 is buggy; don't use it.\n\nCPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5\nCFLAGS=-W -Wall -O3 -funroll-loops $(ALIGN) # $(WARNMORE) -g\n#LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng16 -lz -lm\nLDFLAGS=-L. -L$(ZLIBLIB) -lpng16 -lz -lm\n\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\nOBJSDLL = $(OBJS:.o=.pic.o)\n\n.SUFFIXES:      .c .o .pic.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\n.c.pic.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ $*.c\n\nall: libpng.a $(LIBSO) pngtest libpng.pc libpng-config\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo libs=\\\"-lpng16 -lz -lm\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ): $(OBJSDLL)\n\t$(LD) -b +s \\\n\t+h $(LIBSOMAJ) -o $(LIBSOMAJ) $(OBJSDLL)\n\npngtest: pngtest.o $(LIBSO)\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOREL)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)/$(LIBSOREL)\n\tchmod 755 $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) -I$(DI) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(DL) -L$(ZLIBLIB) -Wl,-rpath,$(DL) -Wl,-rpath,$(ZLIBLIB) \\\n\t   -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtestd pngtest.png\n\ntest-installed:\n\techo\n\techo Testing installed dynamic shared library.\n\t$(CC) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngtesti pngout.png \\\n\tlibpng-config $(LIBSO) $(LIBSOMAJ)* \\\n\tlibpng.pc pnglibconf.h\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o png.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o pngerror.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o pngrio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o pngwio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o pngmem.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o pngset.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o pngget.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o pngread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o pngrtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o pngrutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o pngtrans.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o pngwrite.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o pngwtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o pngwutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o pngpread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.hpux",
    "content": "# makefile for libpng, HPUX (10.20 and 11.00) using the ANSI/C product.\n# Copyright (C) 1999-2002, 2006, 2010-2014 Glenn Randers-Pehrson\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42\n# contributed by Jim Rice and updated by Chris Schleicher, Hewlett Packard\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Where the zlib library and include files are located\nZLIBLIB=/opt/zlib/lib\nZLIBINC=/opt/zlib/include\n\n# Note that if you plan to build a libpng shared library, zlib must also\n# be a shared library, which zlib's configure does not do.  After running\n# zlib's configure, edit the appropriate lines of makefile to read:\n#   CPPFLAGS=-DHAVE_UNISTD -DUSE_MAP\n#   CFLAGS=-O1 -fPIC\n#   LDSHARED=ld -b\n#   SHAREDLIB=libz.sl\n\n# Library name:\nLIBNAME = libpng16\nPNGMAJ = 16\n\n# Shared library names:\nLIBSO=$(LIBNAME).sl\nLIBSOMAJ=$(LIBNAME).sl.$(PNGMAJ)\nLIBSOREL=$(LIBSOMAJ).$(RELEASE)\nOLDSO=libpng.sl\n\n# Utilities:\nAR_RC=ar rc\nCC=cc\nMKDIR_P=mkdir -p\nLN_SF=ln -sf\nRANLIB=ranlib\nRM_F=/bin/rm -f\n\n# where make install puts libpng.a, libpng16.sl, and png.h\nprefix=/opt/libpng\nexec_prefix=$(prefix)\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\nCPPFLAGS=-I$(ZLIBINC)\nCFLAGS=-O -Ae +DA1.1 +DS2.0\n# Caution: be sure you have built zlib with the same CFLAGS.\nCCFLAGS=-O -Ae +DA1.1 +DS2.0\nLDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\nOBJSDLL = $(OBJS:.o=.pic.o)\n\n.SUFFIXES:\t.c .o .pic.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\n.c.pic.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) +z -o $@ $*.c\n\nall: libpng.a $(LIBSO) pngtest libpng.pc libpng-config\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo ccopts=\\\"-O -Ae +DA1.1 +DS2.0\\\"; \\\n\techo L_opts=\\\"-L$(LIBPATH)\\\"; \\\n\techo libs=\\\"-lpng16 -lz -lm\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ): $(OBJSDLL)\n\t$(LD) -b +s \\\n\t+h $(LIBSOMAJ) -o $(LIBSOMAJ) $(OBJSDLL)\n\npngtest: pngtest.o libpng.a\n\t$(CC) -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOREL)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)/$(LIBSOREL)\n\tchmod 755 $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) -I$(DI) $(CPPFLAGS) $(CCFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(DL) -L$(ZLIBLIB) \\\n\t   -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtestd pngtest.png\n\ntest-installed:\n\techo\n\techo Testing installed dynamic shared library.\n\t$(CC) $(CPPFLAGS) $(CCFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(ZLIBLIB) \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngtesti pngout.png \\\n\tlibpng-config $(LIBSO) $(LIBSOMAJ)* \\\n\tlibpng.pc pnglibconf.h\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.ibmc",
    "content": "# Makefile for libpng (static)\n# IBM C version 3.x for Win32 and OS/2\n# Copyright (C) 2006, 2014 Glenn Randers-Pehrson\n# Copyright (C) 2000 Cosmin Truta\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n#\n# Notes:\n#   Derived from makefile.std\n#   All modules are compiled in C mode\n#   Tested under Win32, expected to work under OS/2\n#   Can be easily adapted for IBM VisualAge/C++ for AIX\n\n# Location of the zlib library and include files\nZLIBINC = ../zlib\nZLIBLIB = ../zlib\n\n# Compiler, linker, lib and other tools\nCC = icc\nLD = ilink\nAR = ilib\nCP = copy\nRM = del\n\nCPPFLAGS = -I$(ZLIBINC)\nCFLAGS = -Mc -O2 -W3\nLDFLAGS =\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\n# File extensions\nO=.obj\nA=.lib\nE=.exe\n\n# Variables\nOBJS = png$(O) pngerror$(O) pngget$(O) pngmem$(O) pngpread$(O) \\\n\tpngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) pngset$(O) \\\n\tpngtrans$(O) pngwio$(O) pngwrite$(O) pngwtran$(O) pngwutil$(O)\n\nLIBS = libpng$(A) $(ZLIBLIB)/zlib$(A)\n\n# Targets\n.c$(O):\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $<\n\nall: libpng$(A) pngtest$(E)\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng$(A): $(OBJS)\n\t$(AR) -out:$@ $(OBJS)\n\ntest: pngtest$(E)\n\tpngtest$(E)\n\npngtest: pngtest$(E)\n\npngtest$(E): pngtest$(O) libpng$(A)\n\t$(LD) $(LDFLAGS) pngtest$(O) $(LIBS)\n\nclean:\n\t$(RM) *$(O)\n\t$(RM) libpng$(A)\n\t$(RM) pnglibconf.h\n\t$(RM) pngtest$(E)\n\t$(RM) pngout.png\n\npng$(O):      png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget$(O):   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem$(O):   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread$(O):  png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio$(O):   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset$(O):   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio$(O):   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest$(O):  png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.intel",
    "content": "# Makefile for libpng\n# Microsoft Visual C++ with Intel C/C++ Compiler 4.0 and later\n\n# Copyright (C) 2006, 2014 Glenn Randers-Pehrson\n# Copyright (C) 2000, Pawel Mrochen, based on makefile.msc which is\n# copyright 1995 Guy Eric Schalnat, Group 42, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n#\n# To use, do \"nmake /f scripts\\makefile.intel\"\n#\n# ------------------- Intel C/C++ Compiler 4.0 and later -------------------\n\n# Where the zlib library and include files are located\nZLIBLIB=..\\zlib\nZLIBINC=..\\zlib\n\n# Target CPU\nCPU=6\t\t# Pentium II\n#CPU=5\t\t# Pentium\n\n# Calling convention\nCALLING=r\t# __fastcall\n#CALLING=z\t# __stdcall\n#CALLING=d\t# __cdecl\n\n# Uncomment next to put error messages in a file\n#ERRFILE=>>pngerrs\n\n# --------------------------------------------------------------------------\n\nCC=icl -c\nCPPFLAGS=-I$(ZLIBINC)\nCFLAGS=-O2 -G$(CPU)$(CALLING) -Qip -Qunroll4 -nologo\nLD=link\nLDFLAGS=/SUBSYSTEM:CONSOLE /NOLOGO\nCP=cp\n\n# Pre-built configuration\n# See scripts\\pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts\\pnglibconf.h.prebuilt\n\nO=.obj\n\nOBJS=png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O) \\\npngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O) \\\npngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)\n\nall: test\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\npng$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngset$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngget$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngread$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngpread$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngrtran$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngrutil$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngerror$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngmem$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngrio$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngwio$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngtrans$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngwrite$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngwtran$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngwutil$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\nlibpng.lib: $(OBJS)\n\tif exist libpng.lib del libpng.lib\n\tlib /NOLOGO /OUT:libpng.lib $(OBJS)\n\npngtest.exe: pngtest.obj libpng.lib\n\t$(LD) $(LDFLAGS) /OUT:pngtest.exe pngtest.obj libpng.lib $(ZLIBLIB)\\zlib.lib\n\npngtest$(O): png.h pngconf.h pnglibconf.h\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\ntest: pngtest.exe\n\tpngtest.exe\n\n\n# End of makefile for libpng\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.knr",
    "content": "# makefile for libpng\n# Copyright (C) 2002, 2006, 2009, 2014 Glenn Randers-Pehrson\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n#\n# This makefile requires the file ansi2knr.c, which you can get\n# from the Ghostscript ftp site at ftp://ftp.cs.wisc.edu/ghost/\n# If you have libjpeg, you probably already have ansi2knr.c in the jpeg\n# source distribution.\n\n# where make install puts libpng.a and png.h\nprefix=/usr/local\nINCPATH=$(prefix)/include\nLIBPATH=$(prefix)/lib\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nCC = cc\nCPPFLAGS = -I../zlib\nCFLAGS = -O\nLDFLAGS = -L. -L../zlib/ -lpng -lz -lm\n# flags for ansi2knr\nANSI2KNRFLAGS=\n\nRANLIB = ranlib\n#RANLIB = echo\n\nCP = cp\nRM_F = rm -f\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\nall: ansi2knr libpng.a pngtest\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\n# general rule to allow ansi2knr to work\n.c.o:\n\t./ansi2knr $*.c T$*.c\n\t$(CC) $(CPPFLAGS) $(CFLAGS) -c T$*.c\n\trm -f T$*.c $*.o\n\tmv T$*.o $*.o\n\nansi2knr: ansi2knr.c\n\t$(CC) $(CPPFLAGS) $(CFLAGS) $(ANSI2KNRFLAGS) -o ansi2knr ansi2knr.c\n\nlibpng.a: ansi2knr $(OBJS)\n\tar rc $@  $(OBJS)\n\t$(RANLIB) $@\n\npngtest: pngtest.o libpng.a\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\ninstall: libpng.a png.h pngconf.h pnglibconf.h\n\t-@mkdir $(DESTDIR)$(INCPATH)\n\t-@mkdir $(DESTDIR)$(INCPATH)/libpng\n\t-@mkdir $(DESTDIR)$(LIBPATH)\n\t-@rm -f $(DESTDIR)$(INCPATH)/png.h\n\t-@rm -f $(DESTDIR)$(INCPATH)/pngconf.h\n\tcp png.h $(DESTDIR)$(INCPATH)/libpng\n\tcp pngconf.h $(DESTDIR)$(INCPATH)/libpng\n\tcp pnglibconf.h $(DESTDIR)$(INCPATH)/libpng\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/pnglibconf.h\n\t(cd $(DESTDIR)$(INCPATH); ln -f -s libpng/* .)\n\tcp libpng.a $(DESTDIR)$(LIBPATH)\n\tchmod 644 $(DESTDIR)$(LIBPATH)/libpng.a\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngout.png ansi2knr pnglibconf.h\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.linux",
    "content": "# makefile for libpng.a and libpng16.so on Linux ELF with gcc\n# Copyright (C) 1998, 1999, 2002, 2006, 2008, 2010-2014 Greg Roelofs and\n# Glenn Randers-Pehrson\n# Copyright (C) 1996, 1997 Andreas Dilger\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Library name:\nLIBNAME = libpng16\nPNGMAJ = 16\nRELEASE = 22\n\n# Shared library names:\nLIBSO=$(LIBNAME).so\nLIBSOMAJ=$(LIBNAME).so.$(PNGMAJ)\nLIBSOREL=$(LIBSOMAJ).$(RELEASE)\nOLDSO=libpng.so\n\n# Utilities:\nAR_RC=ar rc\nCC=gcc\nMKDIR_P=mkdir -p\nLN_SF=ln -sf\nRANLIB=ranlib\nCP=cp\nRM_F=/bin/rm -f\n\n# where \"make install\" puts libpng16.a, libpng16.so*,\n# libpng16/png.h, libpng16/pngconf.h, and libpng16/pnglibconf.h\n# Prefix must be a full pathname.\nprefix=/usr/local\nexec_prefix=$(prefix)\n\n# Where the zlib library and include files are located.\n#ZLIBLIB=/usr/local/lib\n#ZLIBINC=/usr/local/include\nZLIBLIB=../zlib\nZLIBINC=../zlib\n\nALIGN=\n# for i386:\n#ALIGN=-malign-loops=2 -malign-functions=2\n\nWARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \\\n\t-Wmissing-declarations -Wtraditional -Wcast-align \\\n\t-Wstrict-prototypes -Wmissing-prototypes #-Wconversion\n\n# for pgcc version 2.95.1, -O3 is buggy; don't use it.\n\nCPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5\nCFLAGS= -W -Wall -O3 -funroll-loops \\\n\t$(ALIGN) # $(WARNMORE) -g -DPNG_DEBUG=5\n\nLDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng16 -lz -lm\nLDFLAGS_A=-L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) libpng.a -lz -lm\n\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS =  png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\nOBJSDLL = $(OBJS:.o=.pic.o)\n\n.SUFFIXES:      .c .o .pic.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\n.c.pic.o:\n\t$(CC) -c $(CFLAGS) -fPIC -o $@ $*.c\n\nall: libpng.a $(LIBSO) pngtest pngtest-static libpng.pc libpng-config\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo L_opts=\\\"-L$(LIBPATH)\\\"; \\\n\techo R_opts=\\\"-Wl,-rpath,$(LIBPATH)\\\"; \\\n\techo libs=\\\"-lpng16 -lz -lm\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ): $(OBJSDLL)\n\t$(CC) -shared -Wl,-soname,$(LIBSOMAJ) -o $(LIBSOMAJ) $(OBJSDLL)\n\npngtest: pngtest.o $(LIBSO)\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\npngtest-static: pngtest.o libpng.a\n\t$(CC) -o pngtest-static $(CFLAGS) pngtest.o $(LDFLAGS_A)\n\ntest: pngtest pngtest-static\n\t@echo \"\"\n\t@echo \"   Running pngtest dynamically linked with $(LIBSO):\"\n\t@echo \"\"\n\t./pngtest\n\t@echo \"\"\n\t@echo \"   Running pngtest statically linked with libpng.a:\"\n\t@echo \"\"\n\t./pngtest-static\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOREL)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)/$(LIBSOREL)\n\tchmod 755 $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) -I$(DI) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(DL) -L$(ZLIBLIB) -Wl, -rpath,$(DL) -Wl,-rpath,$(ZLIBLIB) \\\n\t   -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtestd pngtest.png\n\ntest-installed:\n\t$(CC) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngout.png libpng-config \\\n\t$(LIBSO) $(LIBSOMAJ)* pngtest-static pngtesti \\\n\tlibpng.pc pnglibconf.h\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o png.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o pngerror.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o pngrio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o pngwio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o pngmem.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o pngset.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o pngget.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o pngread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o pngrtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o pngrutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o pngtrans.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o pngwrite.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o pngwtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o pngwutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o pngpread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.mips",
    "content": "# makefile for libpng\n# Copyright (C) 1998-2014 Glenn Randers-Pehrson\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# where make install puts libpng.a and png.h\nprefix=/usr/local\nINCPATH=$(prefix)/include\nLIBPATH=$(prefix)/lib\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nCC=cc\nCPPFLAGS=-I../zlib -DSYSV -Dmips\nCFLAGS=-O -systype sysv -w\n#CFLAGS=-O\nLDFLAGS=-L. -L../zlib/ -lpng -lz -lm\n\n#RANLIB=ranlib\nRANLIB=echo\n\nCP=cp\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\nall: libpng.a pngtest\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\tar rc $@  $(OBJS)\n\t$(RANLIB) $@\n\npngtest: pngtest.o libpng.a\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\ninstall: libpng.a\n\t-@mkdir $(DESTDIR)$(INCPATH)\n\t-@mkdir $(DESTDIR)$(INCPATH)/libpng\n\t-@mkdir $(DESTDIR)$(LIBPATH)\n\t-@rm -f $(DESTDIR)$(INCPATH)/png.h\n\t-@rm -f $(DESTDIR)$(INCPATH)/pngconf.h\n\t-@rm -f $(DESTDIR)$(INCPATH)/pnglibconf.h\n\tcp png.h $(DESTDIR)$(INCPATH)/libpng\n\tcp pngconf.h $(DESTDIR)$(INCPATH)/libpng\n\tcp pnglibconf.h $(DESTDIR)$(INCPATH)/libpng\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/pnglibconf.h\n\t(cd $(DESTDIR)$(INCPATH); ln -f -s libpng/* .)\n\tcp libpng.a $(DESTDIR)$(LIBPATH)\n\tchmod 644 $(DESTDIR)$(LIBPATH)/libpng.a\n\nclean:\n\trm -f *.o libpng.a pngtest pngout.png pnglibconf.h\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.msc",
    "content": "# makefile for libpng\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.\n# Copyright (C) 2006, 2009, 2014 Glenn Randers-Pehrson\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n#\n# Assumes that zlib.lib, zconf.h, and zlib.h have been copied to ..\\zlib\n\n# -------- Microsoft C 5.1 and later, does not use assembler code --------\nMODEL=L\nCPPFLAGS=-I..\\zlib\nCFLAGS=-Oait -Gs -nologo -W3 -A$(MODEL)\n#-Ox generates bad code with MSC 5.1\nCC=cl\nLD=link\nLDFLAGS=/e/st:0x1500/noe\nCP=copy\nO=.obj\n\n# Pre-built configuration\n# See scripts\\pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts\\pnglibconf.h.prebuilt\n\n#uncomment next to put error messages in a file\nERRFILE= >> pngerrs\n\n# variables\nOBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)\nOBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)\nOBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)\n\nall: libpng.lib\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\npng$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngset$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngget$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngread$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngpread$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngrtran$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngrutil$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngerror$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngmem$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngrio$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngwio$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngtrans$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngwrite$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngwtran$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngwutil$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\nlibpng.lib: $(OBJS1) $(OBJS2) $(OBJS3)\n\tdel libpng.lib\n\tlib libpng $(OBJS1);\n\tlib libpng $(OBJS2);\n\tlib libpng $(OBJS3);\n\npngtest$(O): png.h pngconf.h pnglibconf.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngtest.exe: pngtest.obj libpng.lib\n\t$(LD) $(LDFLAGS) pngtest.obj,,,libpng.lib ..\\zlib\\zlib.lib ;\n\ntest: pngtest.exe\n\tpngtest\n\n# End of makefile for libpng\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.msys",
    "content": "# makefile for libpng using MSYS/gcc (shared, static library)\n# Copyright (C) 2012 Glenn Randers-Pehrson and Christopher M. Wheeler\n#\n# Portions taken from makefile.linux:\n# Copyright (C) 1998, 1999, 2002, 2006, 2008, 2010-2014 Greg Roelofs and\n# Glenn Randers-Pehrson\n# Copyright (C) 2000 Cosmin Truta\n# Copyright (C) 1996, 1997 Andreas Dilger\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n# # # # # # # # # # # # # # # # #\nprefix=/usr/local\nexec_prefix=$(prefix)\n\n# Library name:\nLIBNAME = libpng16\nPNGMAJ = 16\nRELEASE = 22\n\n# Shared library names:\nLIBSO=$(LIBNAME).dll\nLIBSOMAJ=$(LIBNAME).dll.$(PNGMAJ)\nLIBSOREL=$(PNGMAJ).$(RELEASE)\nOLDSO=libpng.dll\n\n# Where the zlib library and include files are located.\n#ZLIBLIB=../zlib\n#ZLIBINC=../zlib\nZLIBLIB=/usr/local/lib\nZLIBINC=/usr/local/include\n\n# Compiler, linker, lib and other tools\nCC = gcc\nLD = $(CC)\nAR_RC = ar rcs\nRANLIB = ranlib\nCP = cp\nRM_F = rm -rf\nMKDIR_P=mkdir -p\nLN_SF=ln -sf\n\n#ARCH = -march=pentium3\n#ARCH = -march=i686\nARCH =\nCPPFLAGS = # -DPNG_DEBUG=5\nCFLAGS = -W -Wall -O2 $(ARCH) # -g\nLDFLAGS =\nLIBS = -lz -lm\n\n# File extensions\nEXEEXT=.exe\n\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\n\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\n# Variables\nOBJS =  png.o pngerror.o pngget.o pngmem.o pngpread.o \\\n\tpngread.o pngrio.o pngrtran.o pngrutil.o pngset.o \\\n\tpngtrans.o pngwio.o pngwrite.o pngwtran.o pngwutil.o\n\n# Targets\nall: static shared\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $<\n\nstatic: libpng.a pngtest$(EXEEXT)\n\nshared: $(LIBSOMAJ)\n\t$(CC) -shared -Wl,-soname,$(LIBSOMAJ) -o $(LIBSO)\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ):\n\t$(CC) -shared -Wl,-soname,$(LIBSOMAJ) -o $(LIBSOMAJ)\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo L_opts=\\\"-L$(LIBPATH)\\\"; \\\n\techo R_opts=\\\"-Wl,-rpath,$(LIBPATH)\\\"; \\\n\techo libs=\\\"-lpng16 -lz -lm\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSO) $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\ntest: pngtest$(EXEEXT)\n\t./pngtest$(EXEEXT)\n\npngtest$(EXEEXT): pngtest.o libpng.a\n\t$(LD) $(LDFLAGS) -L$(ZLIBLIB) -o $@ pngtest.o libpng.a $(LIBS)\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest$(EXEEXT) pngout.png pnglibconf.h $(LIBSO) \\\n\t$(LIBSOMAJ) libpng-config\n\npng.o:      png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o:  png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o:   png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o:  png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.ne12bsd",
    "content": "# makefile for libpng for NetBSD for the standard\n# make obj && make depend && make && make test\n# make includes && make install\n# Copyright (C) 2002 Patrick R.L. Welche\n# Copyright (C) 2007, 2009, 2014 Glenn Randers-Pehrson\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# You should also run makefile.netbsd\n\nLOCALBASE?=/usr/local\nLIBDIR=\t${LOCALBASE}/lib\nMANDIR= ${LOCALBASE}/man\nINCSDIR=${LOCALBASE}/include/libpng16\n\nLIB=\tpng16\nSHLIB_MAJOR=\t0\nSHLIB_MINOR=\t1.6.22beta03\nSRCS=\tpng.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \\\n\tpngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \\\n\tpngwtran.c pngmem.c pngerror.c pngpread.c\nINCS=\tpng.h pngconf.h pnglibconf.h\nMAN=\tlibpng.3 libpngpf.3 png.5\n\nCPPFLAGS+=-I${.CURDIR}\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT= scripts/pnglibconf.h.prebuilt\n\n# We should be able to do something like this instead of the manual\n# uncommenting, but it core dumps for me at the moment:\n# .if ${MACHINE_ARCH} == \"i386\"\n#   MKLINT= no\n# .endif\n\nCLEANFILES+=pngtest.o pngtest pnglibconf.h\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\tcp $(PNGLIBCONF_H_PREBUILT) $@\n\npngtest.o:\tpngtest.c\n\t${CC} -c ${CPPFLAGS} ${CFLAGS} ${.ALLSRC} -o ${.TARGET}\n\npngtest:\tpngtest.o libpng.a\n\t${CC} ${LDFLAGS} ${.ALLSRC} -o${.TARGET} -lz -lm\n\ntest:\tpngtest\n\tcd ${.CURDIR} && ${.OBJDIR}/pngtest\n\n.include <bsd.lib.mk>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.netbsd",
    "content": "# makefile for libpng for NetBSD for the standard\n# make obj && make depend && make && make test\n# make includes && make install\n# Copyright (C) 2002 Patrick R.L. Welche\n# Copyright (C) 2007-2009, 2014 Glenn Randers-Pehrson\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# You should also run makefile.ne16bsd\n\nLOCALBASE?=/usr/local\nLIBDIR=\t${LOCALBASE}/lib\nMANDIR= ${LOCALBASE}/man\nINCSDIR=${LOCALBASE}/include\n\nLIB=\tpng\nSHLIB_MAJOR=\t16\nSHLIB_MINOR=\t1.6.22beta03\nSRCS=\tpng.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \\\n\tpngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \\\n\tpngwtran.c pngmem.c pngerror.c pngpread.c\nINCS=\tpng.h pngconf.h pnglibconf.h\nMAN=\tlibpng.3 libpngpf.3 png.5\n\nCPPFLAGS+=-I${.CURDIR}\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT= scripts/pnglibconf.h.prebuilt\n\n# We should be able to do something like this instead of the manual\n# uncommenting, but it core dumps for me at the moment:\n# .if ${MACHINE_ARCH} == \"i386\"\n#   MKLINT= no\n# .endif\n\nCLEANFILES+=pngtest.o pngtest pnglibconf.h\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\tcp $(PNGLIBCONF_H_PREBUILT) $@\n\npngtest.o:\tpngtest.c\n\t${CC} -c ${CPPFLAGS} ${CFLAGS} ${.ALLSRC} -o ${.TARGET}\n\npngtest:\tpngtest.o libpng.a\n\t${CC} ${LDFLAGS} ${.ALLSRC} -o${.TARGET} -lz -lm\n\ntest:\tpngtest\n\tcd ${.CURDIR} && ${.OBJDIR}/pngtest\n\n.include <bsd.lib.mk>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.openbsd",
    "content": "# makefile for libpng\n# Copyright (C) 2007-2009, 2014 Glenn Randers-Pehrson\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\nPREFIX?= /usr/local\nLIBDIR=\t${PREFIX}/lib\nMANDIR= ${PREFIX}/man/cat\n\nSHLIB_MAJOR=\t16\nSHLIB_MINOR=\t1.6.22beta03\n\nLIB=\tpng\nSRCS=\tpng.c pngerror.c pngget.c pngmem.c pngpread.c \\\n\tpngread.c pngrio.c pngrtran.c pngrutil.c pngset.c pngtrans.c \\\n\tpngwio.c pngwrite.c pngwtran.c pngwutil.c\n\nHDRS=\tpng.h pngconf.h pnglibconf.h\n\nCFLAGS+= -W -Wall\nCPPFLAGS+= -I${.CURDIR}\n\nNOPROFILE= Yes\n\nCLEANFILES+= pngtest.o pngtest pnglibconf.h\n\nMAN=\tlibpng.3 libpngpf.3 png.5\nDOCS=\tANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO \\\n\tlibpng-manual.txt\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT= scripts/pnglibconf.h.prebuilt\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\tcp $(PNGLIBCONF_H_PREBUILT) $@\n\npngtest.o:\tpngtest.c\n\t${CC} ${CPPFLAGS} ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET}\n\npngtest:\tpngtest.o\n\t${CC} ${LDFLAGS} ${.ALLSRC} -o ${.TARGET} -L${.OBJDIR} -lpng -lz -lm\n\ntest:\tpngtest\n\tcd ${.OBJDIR} && env \\\n\t\tLD_LIBRARY_PATH=\"${.OBJDIR}\" ${.OBJDIR}/pngtest\n\nbeforeinstall:\n\tif [ ! -d ${DESTDIR}${PREFIX}/include/libpng ]; then \\\n\t  ${INSTALL} -d -o root -g wheel ${DESTDIR}${PREFIX}/include; \\\n\tfi\n\tif [ ! -d ${DESTDIR}${LIBDIR} ]; then \\\n\t  ${INSTALL} -d -o root -g wheel ${DESTDIR}${LIBDIR}; \\\n\tfi\n\tif [ ! -d ${DESTDIR}${LIBDIR}/debug ]; then \\\n\t  ${INSTALL} -d -o root -g wheel ${DESTDIR}${LIBDIR}/debug; \\\n\tfi\n\tif [ ! -d ${DESTDIR}${MANDIR}3 ]; then \\\n\t  ${INSTALL} -d -o root -g wheel ${DESTDIR}${MANDIR}3; \\\n\tfi\n\tif [ ! -d ${DESTDIR}${MANDIR}5 ]; then \\\n\t  ${INSTALL} -d -o root -g wheel ${DESTDIR}${MANDIR}5; \\\n\tfi\n\tif [ ! -d ${DESTDIR}${PREFIX}/share/doc/png ]; then \\\n\t  ${INSTALL} -d -o root -g wheel ${DESTDIR}${PREFIX}/share/doc/png; \\\n\tfi\n\nafterinstall:\n\t@rm -f ${DESTDIR}${LIBDIR}/libpng_pic.a\n\t@rm -f ${DESTDIR}${LIBDIR}/debug/libpng.a\n\t@rm -f ${DESTDIR}${PREFIX}/include/png.h\n\t@rm -f ${DESTDIR}${PREFIX}/include/pngconf.h\n\t@rm -f ${DESTDIR}${PREFIX}/include/pnglibconf.h\n\t@rmdir ${DESTDIR}${LIBDIR}/debug 2>/dev/null || true\n\t${INSTALL} ${INSTALL_COPY} -o ${SHAREOWN} -g ${SHAREGRP} \\\n\t\t-m ${NONBINMODE} ${HDRS} ${DESTDIR}${PREFIX}/include\n\t${INSTALL} ${INSTALL_COPY} -o ${SHAREOWN} -g ${SHAREGRP} \\\n\t\t-m ${NONBINMODE} ${HDRS} ${DESTDIR}${PREFIX}/include\n\t${INSTALL} ${INSTALL_COPY} -o ${SHAREOWN} -g ${SHAREGRP} \\\n\t\t-m ${NONBINMODE} ${DOCS} ${DESTDIR}${PREFIX}/share/doc/png\n\n.include <bsd.lib.mk>\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.sco",
    "content": "# makefile for SCO OSr5  ELF and Unixware 7 with Native cc\n# Contributed by Mike Hopkirk (hops@sco.com) modified from Makefile.lnx\n#   force ELF build dynamic linking, SONAME setting in lib and RPATH in app\n# Copyright (C) 2002, 2006, 2010-2014 Glenn Randers-Pehrson\n# Copyright (C) 1998 Greg Roelofs\n# Copyright (C) 1996, 1997 Andreas Dilger\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Library name:\nLIBNAME = libpng16\nPNGMAJ = 16\n\n# Shared library names:\nLIBSO=$(LIBNAME).so\nLIBSOMAJ=$(LIBNAME).so.$(PNGMAJ)\nLIBSOREL=$(LIBSOMAJ).$(RELEASE)\nOLDSO=libpng.so\n\n# Utilities:\nCC=cc\nAR_RC=ar rc\nMKDIR_P=mkdir\nLN_SF=ln -f -s\nRANLIB=echo\nCP=cp\nRM_F=/bin/rm -f\n\n# where make install puts libpng.a, $(OLDSO)*, and png.h\nprefix=/usr/local\nexec_prefix=$(prefix)\n\n# Where the zlib library and include files are located\n#ZLIBLIB=/usr/local/lib\n#ZLIBINC=/usr/local/include\nZLIBLIB=../zlib\nZLIBINC=../zlib\n\nCPPFLAGS=-I$(ZLIBINC)\nCFLAGS= -dy -belf -O3\nLDFLAGS=-L. -L$(ZLIBLIB) -lpng16 -lz -lm\n\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\nOBJSDLL = $(OBJS:.o=.pic.o)\n\n.SUFFIXES:      .c .o .pic.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\n.c.pic.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -KPIC -o $@ $*.c\n\nall: libpng.a $(LIBSO) pngtest libpng.pc libpng-config\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo ccopts=\\\"-belf\\\"; \\\n\techo L_opts=\\\"-L$(LIBPATH)\\\"; \\\n\techo libs=\\\"-lpng16 -lz -lm\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ): $(OBJSDLL)\n\t$(CC) -G  -Wl,-h,$(LIBSOMAJ) -o $(LIBSOMAJ) \\\n\t $(OBJSDLL)\n\npngtest: pngtest.o $(LIBSO)\n\tLD_RUN_PATH=.:$(ZLIBLIB) $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\t-@$(RM_F) $(DI)/png.h\n\t-@$(RM_F) $(DI)/pngconf.h\n\t-@$(RM_F) $(DI)/pnglibconf.h\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOREL)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)/$(LIBSOREL)\n\tchmod 755 $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) -I$(DI) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(DL) -L$(ZLIBLIB) \\\n\t   -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtestd pngtest.png\n\ntest-installed:\n\t$(CC) $(CPPFLAGS) $(CFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(ZLIBLIB) \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngout.png libpng-config \\\n\t$(LIBSO) $(LIBSOMAJ)* pngtest-static pngtesti \\\n\tpnglibconf.h libpng.pc\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o png.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o pngerror.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o pngrio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o pngwio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o pngmem.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o pngset.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o pngget.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o pngread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o pngrtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o pngrutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o pngtrans.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o pngwrite.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o pngwtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o pngwutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o pngpread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.sggcc",
    "content": "# makefile for libpng.a and libpng16.so, SGI IRIX with 'cc'\n# Copyright (C) 2001-2002, 2006, 2010-2014 Glenn Randers-Pehrson\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Library name:\nLIBNAME=libpng16\nPNGMAJ = 16\n\n# Shared library names:\nLIBSO=$(LIBNAME).so\nLIBSOMAJ=$(LIBNAME).so.$(PNGMAJ)\nLIBSOREL=$(LIBSOMAJ).$(RELEASE)\nOLDSO=libpng.so\n\n# Utilities:\nAR_RC=ar rc\nCC=gcc\nMKDIR_P=mkdir -p\nLN_SF=ln -sf\nRANLIB=echo\nCP=cp\nRM_F=/bin/rm -f\n\n# Where make install puts libpng.a, libpng16.so, and libpng16/png.h\n# Prefix must be a full pathname.\n\nprefix=/usr/local\nexec_prefix=$(prefix)\n\n# Where the zlib library and include files are located\n#ZLIBLIB=/usr/local/lib32\n#ZLIBINC=/usr/local/include\n#ZLIBLIB=/usr/local/lib\n#ZLIBINC=/usr/local/include\nZLIBLIB=../zlib\nZLIBINC=../zlib\n\n# ABI can be blank to use default for your system, -32, -o32, -n32, or -64\n# See \"man abi\".  zlib must be built with the same ABI.\nABI=\n\nWARNMORE=\nCPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5\nCFLAGS=$(ABI) -O $(WARNMORE) -fPIC -mabi=n32 # -g\nLDFLAGS=$(ABI) -L. -L$(ZLIBLIB) -lpng -lz -lm\nLDSHARED=cc $(ABI) -shared -soname $(LIBSOMAJ) \\\n\t-set_version sgi$(PNGMAJ).0\n# See \"man dso\" for info about shared objects\n\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\n#LIBPATH=$(exec_prefix)/lib32\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS =  png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\nall: libpng.a pngtest shared libpng.pc libpng-config\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\nshared: $(LIBSOMAJ)\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo ccopts=\\\"$(ABI)\\\"; \\\n\techo cppflags=\\\"\\\"; \\\n\techo ldopts=\\\"$(ABI)\\\"; \\\n\techo L_opts=\\\"-L$(LIBPATH)\\\"; \\\n\techo libdir=\\\"$(LIBPATH)\\\"; \\\n\techo libs=\\\"-lpng16 -lz -lm\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ): $(OBJS)\n\t$(LDSHARED) -o $@ $(OBJS)\n\t$(RM_F) $(LIBSO) $(LIBSOMAJ)\n\npngtest: pngtest.o libpng.a\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\techo\n\techo Testing local static library.\n\t./pngtest\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOREL)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)/$(LIBSOREL)\n\tchmod 755 $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) -I$(DI) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(DL) -L$(ZLIBLIB) \\\n\t   -rpath $(ZLIBLIB):$(DL) \\\n\t   -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtestd pngtest.png\n\ntest-installed:\n\techo\n\techo Testing installed dynamic shared library.\n\t$(CC) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(ZLIBLIB) \\\n\t   -rpath $(ZLIBLIB):`$(BINPATH)/$(LIBNAME)-config --libdir` \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) libpng.a pngtest pngtesti pngout.png libpng.pc \\\n\tso_locations libpng-config $(LIBSO) $(LIBSOMAJ)* pnglibconf.h\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.sgi",
    "content": "# makefile for libpng.a and libpng16.so, SGI IRIX with 'cc'\n# Copyright (C) 2001-2002, 2006, 2007, 2010-2014 Glenn Randers-Pehrson\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Library name:\nLIBNAME=libpng16\nPNGMAJ = 16\n\n# Shared library names:\nLIBSO=$(LIBNAME).so\nLIBSOMAJ=$(LIBNAME).so.$(PNGMAJ)\nLIBSOREL=$(LIBSOMAJ).$(RELEASE)\nOLDSO=libpng.so\n\n# Utilities:\nAR_RC=ar rc\nCC=cc\nMKDIR_P=mkdir -p\nLN_SF=ln -sf\nRANLIB=echo\nCP=cp\nRM_F=/bin/rm -f\n\n# Where make install puts libpng.a, libpng16.so, and libpng16/png.h\n# Prefix must be a full pathname.\n\nprefix=/usr/local\nexec_prefix=$(prefix)\n\n# Where the zlib library and include files are located\n#ZLIBLIB=/usr/local/lib32\n#ZLIBINC=/usr/local/include\n#ZLIBLIB=/usr/local/lib\n#ZLIBINC=/usr/local/include\nZLIBLIB=../zlib\nZLIBINC=../zlib\n\n# ABI can be blank to use default for your system, -32, -o32, -n32, or -64\n# See \"man abi\".  zlib must be built with the same ABI.\nABI=\n\nWARNMORE=-fullwarn\n# Note: -KPIC is the default anyhow\nCPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5\n#CFLAGS= $(ABI) -O $(WARNMORE) -KPIC # -g\nCFLAGS=$(ABI) -O $(WARNMORE)\nLDFLAGS_A=$(ABI) -L. -L$(ZLIBLIB) -lpng16 -lz -lm\nLDFLAGS=$(ABI) -L. -L$(ZLIBLIB) -lpng -lz -lm\nLDSHARED=cc $(ABI) -shared -soname $(LIBSOMAJ) \\\n\t-set_version sgi$(PNGMAJ).0\n# See \"man dso\" for info about shared objects\n\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\n#LIBPATH=$(exec_prefix)/lib32\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS =  png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\nall: libpng.a pngtest shared libpng.pc libpng-config\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo ccopts=\\\"$(ABI)\\\"; \\\n\techo ldopts=\\\"$(ABI)\\\"; \\\n\techo L_opts=\\\"-L$(LIBPATH)\\\"; \\\n\techo libdir=\\\"$(LIBPATH)\\\"; \\\n\techo libs=\\\"-lpng16 -lz -lm\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ): $(OBJS)\n\t$(LDSHARED) -o $@ $(OBJS)\n\t$(RM_F) $(LIBSO) $(LIBSOMAJ)\n\npngtest: pngtest.o libpng.a\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\techo\n\techo Testing local static library.\n\t./pngtest\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOREL)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)/$(LIBSOREL)\n\tchmod 755 $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) -I$(DI) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(DL) -L$(ZLIBLIB) \\\n\t   -rpath $(ZLIBLIB):$(DL) \\\n\t   -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtestd pngtest.png\n\ntest-installed:\n\techo\n\techo Testing installed dynamic shared library.\n\t$(CC) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -L$(ZLIBLIB) \\\n\t   -rpath $(ZLIBLIB):`$(BINPATH)/$(LIBNAME)-config --libdir` \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags`\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngtesti pngout.png libpng.pc libpng-config \\\n\t$(LIBSO) $(LIBSOMAJ)* \\\n\tso_locations pnglibconf.h\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.so9",
    "content": "# makefile for libpng on Solaris 9 (beta) with Forte cc\n# Updated by Chad Schrock for Solaris 9\n# Contributed by William L. Sebok, based on makefile.linux\n# Copyright (C) 2002, 2006, 2008, 2010-2014 Glenn Randers-Pehrson\n# Copyright (C) 1998-2001 Greg Roelofs\n# Copyright (C) 1996-1997 Andreas Dilger\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Library name:\nPNGMAJ = 16\nLIBNAME = libpng16\n\n# Shared library names:\nLIBSO=$(LIBNAME).so\nLIBSOMAJ=$(LIBNAME).so.$(PNGMAJ)\nLIBSOREL=$(LIBSOMAJ).$(RELEASE)\nOLDSO=libpng.so\n\n# Utilities:\n# gcc 2.95 doesn't work.\nCC=cc\nAR_RC=ar rc\nMKDIR_P=mkdir -p\nLN_SF=ln -f -s\nRANLIB=echo\nCP=cp\nRM_F=/bin/rm -f\n\n# Where make install puts libpng.a, $(OLDSO)*, and png.h\nprefix=/usr/local\nexec_prefix=$(prefix)\n\n# Where the zlib library and include files are located\n# Changing these to ../zlib poses a security risk.  If you want\n# to have zlib in an adjacent directory, specify the full path instead of \"..\".\n#ZLIBLIB=../zlib\n#ZLIBINC=../zlib\n#ZLIBLIB=/usr/local/lib\n#ZLIBINC=/usr/local/include\n#Use the preinstalled zlib that comes with Solaris 9:\nZLIBLIB=/usr/lib\nZLIBINC=/usr/include\n\n#WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \\\n\t-Wmissing-declarations -Wtraditional -Wcast-align \\\n\t-Wstrict-prototypes -Wmissing-prototypes #-Wconversion\nCPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5\n#CFLAGS=-W -Wall -O3 $(WARNMORE) -g\nCFLAGS=-O3\nLDFLAGS=-L. -R. -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng16 -lz -lm\n\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\nOBJSDLL = $(OBJS:.o=.pic.o)\n\n.SUFFIXES:      .c .o .pic.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\n.c.pic.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -KPIC -o $@ $*.c\n\nall: libpng.a $(LIBSO) pngtest libpng.pc libpng-config\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo L_opts=\\\"-L$(LIBPATH)\\\"; \\\n\techo R_opts=\\\"-R$(LIBPATH)\\\"; \\\n\techo libs=\\\"-lpng16 -lz -lm\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ): $(OBJSDLL)\n\t@case \"`type ld`\" in *ucb*) \\\n\techo; \\\n\techo '## WARNING:'; \\\n\techo '## The commands \"CC\" and \"LD\" must NOT refer to /usr/ucb/cc'; \\\n\techo '## and /usr/ucb/ld.  If they do, you need to adjust your PATH'; \\\n\techo '## environment variable to put /usr/ccs/bin ahead of /usr/ucb.'; \\\n\techo '## The environment variable LD_LIBRARY_PATH should not be set'; \\\n\techo '## at all.  If it is, things are likely to break because of'; \\\n\techo '## the libucb dependency that is created.'; \\\n\techo; \\\n\t;; \\\n\tesac\n\t$(LD) -G -h $(LIBSOMAJ) \\\n\t -o $(LIBSOMAJ) $(OBJSDLL)\n\npngtest: pngtest.o $(LIBSO)\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOREL)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)/$(LIBSOREL)\n\tchmod 755 $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) -I$(DI) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` \\\n\t   -L$(DL) -L$(ZLIBLIB)  -R$(ZLIBLIB) -R$(DL)\n\t./pngtestd pngtest.png\n\ntest-installed:\n\techo\n\techo Testing installed dynamic shared library.\n\t$(CC) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` \\\n\t   -L$(ZLIBLIB) -R$(ZLIBLIB)\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngtesti pngout.png \\\n\tlibpng-config $(LIBSO) $(LIBSOMAJ)* \\\n\tlibpng.pc pnglibconf.h\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o png.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o pngerror.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o pngrio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o pngwio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o pngmem.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o pngset.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o pngget.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o pngread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o pngrtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o pngrutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o pngtrans.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o pngwrite.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o pngwtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o pngwutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o pngpread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.solaris",
    "content": "# makefile for libpng on Solaris 2.x with gcc\n# Copyright (C) 2004, 2006-2008, 2010-2014 Glenn Randers-Pehrson\n# Contributed by William L. Sebok, based on makefile.linux\n# Copyright (C) 1998 Greg Roelofs\n# Copyright (C) 1996, 1997 Andreas Dilger\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Library name:\nLIBNAME = libpng16\nPNGMAJ = 16\n\n# Shared library names:\nLIBSO=$(LIBNAME).so\nLIBSOMAJ=$(LIBNAME).so.$(PNGMAJ)\nLIBSOREL=$(LIBSOMAJ).$(RELEASE)\nOLDSO=libpng.so\n\n# Utilities:\nAR_RC=ar rc\nCC=gcc\nMKDIR_P=mkdir -p\nLN_SF=ln -f -s\nRANLIB=echo\nCP=cp\nRM_F=/bin/rm -f\n\n# Where make install puts libpng.a, libpng16.so*, and png.h\nprefix=/usr/local\nexec_prefix=$(prefix)\n\n# Where the zlib library and include files are located\n# Changing these to ../zlib poses a security risk.  If you want\n# to have zlib in an adjacent directory, specify the full path instead of \"..\".\n#ZLIBLIB=../zlib\n#ZLIBINC=../zlib\n\nZLIBLIB=/usr/local/lib\nZLIBINC=/usr/local/include\n\nWARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \\\n\t-Wmissing-declarations -Wtraditional -Wcast-align \\\n\t-Wstrict-prototypes -Wmissing-prototypes #-Wconversion\nCPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5\nCFLAGS= -W -Wall -O \\\n\t# $(WARNMORE) -g -DPNG_DEBUG=5\nLDFLAGS=-L. -R. -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng16 -lz -lm\n\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\nOBJSDLL = $(OBJS:.o=.pic.o)\n\n.SUFFIXES:      .c .o .pic.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\n.c.pic.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ $*.c\n\nall: libpng.a $(LIBSO) pngtest libpng.pc libpng-config\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo cppflags=\\\"\\\"; \\\n\techo L_opts=\\\"-L$(LIBPATH)\\\"; \\\n\techo R_opts=\\\"-R$(LIBPATH)\\\"; \\\n\techo libs=\\\"-lpng16 -lz -lm\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ): $(OBJSDLL)\n\t@case \"`type ld`\" in *ucb*) \\\n\techo; \\\n\techo '## WARNING:'; \\\n\techo '## The commands \"CC\" and \"LD\" must NOT refer to /usr/ucb/cc'; \\\n\techo '## and /usr/ucb/ld.  If they do, you need to adjust your PATH'; \\\n\techo '## environment variable to put /usr/ccs/bin ahead of /usr/ucb.'; \\\n\techo '## The environment variable LD_LIBRARY_PATH should not be set'; \\\n\techo '## at all.  If it is, things are likely to break because of'; \\\n\techo '## the libucb dependency that is created.'; \\\n\techo; \\\n\t;; \\\n\tesac\n\t$(LD) -G -h $(LIBSOMAJ) \\\n\t -o $(LIBSOMAJ) $(OBJSDLL)\n\npngtest: pngtest.o $(LIBSO)\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOREL)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)/$(LIBSOREL)\n\tchmod 755 $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) -I$(DI) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` \\\n\t   -L$(DL) -L$(ZLIBLIB) -R$(ZLIBLIB) -R$(DL)\n\t./pngtestd pngtest.png\n\ntest-installed:\n\techo\n\techo Testing installed dynamic shared library.\n\t$(CC) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` \\\n\t   -L$(ZLIBLIB) -R$(ZLIBLIB)\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngtesti pngout.png \\\n\tlibpng-config $(LIBSO) $(LIBSOMAJ)* \\\n\tlibpng.pc pnglibconf.h\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o png.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o pngerror.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o pngrio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o pngwio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o pngmem.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o pngset.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o pngget.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o pngread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o pngrtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o pngrutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o pngtrans.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o pngwrite.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o pngwtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o pngwutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o pngpread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.solaris-x86",
    "content": "# makefile for libpng on Solaris 2.x with gcc\n# Copyright (C) 2004, 2006-2008, 2010-2014 Glenn Randers-Pehrson\n# Contributed by William L. Sebok, based on makefile.linux\n# Copyright (C) 1998 Greg Roelofs\n# Copyright (C) 1996, 1997 Andreas Dilger\n\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# Library name:\nLIBNAME = libpng16\nPNGMAJ = 16\n\n# Shared library names:\nLIBSO=$(LIBNAME).so\nLIBSOMAJ=$(LIBNAME).so.$(PNGMAJ)\nLIBSOREL=$(LIBSOMAJ).$(RELEASE)\nOLDSO=libpng.so\n\n# Utilities:\nAR_RC=ar rc\nCC=gcc\nMKDIR_P=mkdir -p\nLN_SF=ln -f -s\nRANLIB=echo\nCP=cp\nRM_F=/bin/rm -f\n\n# Where make install puts libpng.a, libpng16.so*, and png.h\nprefix=/usr/local\nexec_prefix=$(prefix)\n\n# Where the zlib library and include files are located\n# Changing these to ../zlib poses a security risk.  If you want\n# to have zlib in an adjacent directory, specify the full path instead of \"..\".\n#ZLIBLIB=../zlib\n#ZLIBINC=../zlib\n\nZLIBLIB=/usr/local/lib\nZLIBINC=/usr/local/include\n\nWARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \\\n\t-Wmissing-declarations -Wtraditional -Wcast-align \\\n\t-Wstrict-prototypes -Wmissing-prototypes #-Wconversion\nCPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5\nCFLAGS=-W -Wall -O # $(WARNMORE) -g\nLDFLAGS=-L. -R. -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng16 -lz -lm\n\nINCPATH=$(prefix)/include\nLIBPATH=$(exec_prefix)/lib\nMANPATH=$(prefix)/man\nBINPATH=$(exec_prefix)/bin\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\nDB=$(DESTDIR)$(BINPATH)\nDI=$(DESTDIR)$(INCPATH)\nDL=$(DESTDIR)$(LIBPATH)\nDM=$(DESTDIR)$(MANPATH)\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\nOBJSDLL = $(OBJS:.o=.pic.o)\n\n.SUFFIXES:      .c .o .pic.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\n.c.pic.o:\n\t$(CC) -c $(CFLAGS) -fPIC -o $@ $*.c\n\nall: libpng.a $(LIBSO) pngtest libpng.pc libpng-config\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@ $(OBJS)\n\t$(RANLIB) $@\n\nlibpng.pc:\n\tcat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \\\n\t-e s!@exec_prefix@!$(exec_prefix)! \\\n\t-e s!@libdir@!$(LIBPATH)! \\\n\t-e s!@includedir@!$(INCPATH)! \\\n\t-e s!-lpng16!-lpng16\\ -lz\\ -lm! > libpng.pc\n\nlibpng-config:\n\t( cat scripts/libpng-config-head.in; \\\n\techo prefix=\\\"$(prefix)\\\"; \\\n\techo I_opts=\\\"-I$(INCPATH)/$(LIBNAME)\\\"; \\\n\techo cppflags=\\\"\"; \\\n\techo L_opts=\\\"-L$(LIBPATH)\\\"; \\\n\techo R_opts=\\\"-R$(LIBPATH)\\\"; \\\n\techo libs=\\\"-lpng16 -lz -lm\\\"; \\\n\tcat scripts/libpng-config-body.in ) > libpng-config\n\tchmod +x libpng-config\n\n$(LIBSO): $(LIBSOMAJ)\n\t$(LN_SF) $(LIBSOMAJ) $(LIBSO)\n\n$(LIBSOMAJ): $(OBJSDLL)\n\t@case \"`type ld`\" in *ucb*) \\\n\techo; \\\n\techo '## WARNING:'; \\\n\techo '## The commands \"CC\" and \"LD\" must NOT refer to /usr/ucb/cc'; \\\n\techo '## and /usr/ucb/ld.  If they do, you need to adjust your PATH'; \\\n\techo '## environment variable to put /usr/ccs/bin ahead of /usr/ucb.'; \\\n\techo '## The environment variable LD_LIBRARY_PATH should not be set'; \\\n\techo '## at all.  If it is, things are likely to break because of'; \\\n\techo '## the libucb dependency that is created.'; \\\n\techo; \\\n\t;; \\\n\tesac\n\t$(LD) -G -h $(LIBSOMAJ) \\\n\t -o $(LIBSOMAJ) $(OBJSDLL)\n\npngtest: pngtest.o $(LIBSO)\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\ninstall-headers: png.h pngconf.h pnglibconf.h\n\t-@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi\n\t-@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi\n\tcp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME)\n\tchmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h\n\t-@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h\n\t-@$(RM_F) $(DI)/libpng\n\t(cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .)\n\ninstall-static: install-headers libpng.a\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\tcp libpng.a $(DL)/$(LIBNAME).a\n\tchmod 644 $(DL)/$(LIBNAME).a\n\t-@$(RM_F) $(DL)/libpng.a\n\t(cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a)\n\ninstall-shared: install-headers $(LIBSOMAJ) libpng.pc\n\t-@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi\n\t-@$(RM_F) $(DL)/$(LIBSO)\n\t-@$(RM_F) $(DL)/$(LIBSOREL)\n\t-@$(RM_F) $(DL)/$(OLDSO)\n\tcp $(LIBSOMAJ) $(DL)/$(LIBSOREL)\n\tchmod 755 $(DL)/$(LIBSOREL)\n\t(cd $(DL); \\\n\t$(LN_SF) $(LIBSOREL) $(LIBSO); \\\n\t$(LN_SF) $(LIBSO) $(OLDSO))\n\t-@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi\n\t-@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc\n\t-@$(RM_F) $(DL)/pkgconfig/libpng.pc\n\tcp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc\n\tchmod 644 $(DL)/pkgconfig/$(LIBNAME).pc\n\t(cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc)\n\ninstall-man: libpng.3 libpngpf.3 png.5\n\t-@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi\n\t-@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi\n\t-@$(RM_F) $(DM)/man3/libpng.3\n\t-@$(RM_F) $(DM)/man3/libpngpf.3\n\tcp libpng.3 $(DM)/man3\n\tcp libpngpf.3 $(DM)/man3\n\t-@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi\n\t-@$(RM_F) $(DM)/man5/png.5\n\tcp png.5 $(DM)/man5\n\ninstall-config: libpng-config\n\t-@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi\n\t-@$(RM_F) $(DB)/libpng-config\n\t-@$(RM_F) $(DB)/$(LIBNAME)-config\n\tcp libpng-config $(DB)/$(LIBNAME)-config\n\tchmod 755 $(DB)/$(LIBNAME)-config\n\t(cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config)\n\ninstall: install-static install-shared install-man install-config\n\n# If you installed in $(DESTDIR), test-installed won't work until you\n# move the library to its final location.  Use test-dd to test it\n# before then.\n\ntest-dd:\n\techo\n\techo Testing installed dynamic shared library in $(DL).\n\t$(CC) -I$(DI) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` \\\n\t   -L$(DL) -L$(ZLIBLIB) -R$(ZLIBLIB) -R$(DL)\n\t./pngtestd pngtest.png\n\ntest-installed:\n\techo\n\techo Testing installed dynamic shared library.\n\t$(CC) $(CPPFLAGS) \\\n\t   `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \\\n\t   -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` \\\n\t   -L$(ZLIBLIB) -R$(ZLIBLIB)\n\t./pngtesti pngtest.png\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngtesti pngout.png \\\n\tlibpng-config $(LIBSO) $(LIBSOMAJ)* \\\n\tlibpng.pc pnglibconf.h\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o png.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o pngerror.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o pngrio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o pngwio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o pngmem.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o pngset.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o pngget.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o pngread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o pngrtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o pngrutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o pngtrans.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o pngwrite.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o pngwtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o pngwutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o pngpread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.std",
    "content": "# makefile for libpng\n# Copyright (C) 2002, 2006, 2014 Glenn Randers-Pehrson\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# where make install puts libpng.a and png.h\nprefix=/usr/local\nINCPATH=$(prefix)/include\nLIBPATH=$(prefix)/lib\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\n# Where the zlib library and include files are located\n#ZLIBLIB=/usr/local/lib\n#ZLIBINC=/usr/local/include\nZLIBLIB=../zlib\nZLIBINC=../zlib\n\nCC = cc\nAR_RC = ar rc\nMKDIR_P = mkdir\nLN_SF = ln -sf\nRANLIB = ranlib\nCP = cp\nRM_F = rm -f\nAWK = awk\nSED = sed\nCPP = $(CC) -E\nECHO = echo\n\nDFNFLAGS = # DFNFLAGS contains -D options to use in the libpng build\nDFA_EXTRA = # extra files that can be used to control configuration\nCPPFLAGS = -I$(ZLIBINC) # -DPNG_DEBUG=5\nCFLAGS = -O # -g\nLDFLAGS = -L. -L$(ZLIBLIB) -lpng -lz -lm\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\nall: libpng.a pngtest\n\n# The standard pnglibconf.h exists as scripts/pnglibconf.h.prebuilt,\n# copy this if the following doesn't work.\npnglibconf.h: pnglibconf.dfn\n\t$(RM_F) $@ pnglibconf.c pnglibconf.out pnglibconf.tmp\n\t$(ECHO) '#include \"pnglibconf.dfn\"' >pnglibconf.c\n\t$(ECHO) \"If '$(CC) -E' crashes try /lib/cpp (e.g. CPP='/lib/cpp')\" >&2\n\t$(CPP) $(DFNFLAGS) pnglibconf.c >pnglibconf.out\n\t$(AWK) -f \"scripts/dfn.awk\" out=\"pnglibconf.tmp\" pnglibconf.out 1>&2\n\tmv pnglibconf.tmp $@\n\npnglibconf.dfn: scripts/pnglibconf.dfa scripts/options.awk pngconf.h pngusr.dfa $(DFA_XTRA)\n\t$(RM_F) $@ pnglibconf.pre pnglibconf.tmp\n\t$(ECHO) \"Calling $(AWK) from scripts/pnglibconf.mak\" >&2\n\t$(ECHO) \"If 'awk' crashes try a better awk (e.g. AWK='nawk')\" >&2\n\t$(AWK) -f scripts/options.awk out=\"pnglibconf.pre\"\\\n\t    version=search pngconf.h scripts/pnglibconf.dfa\\\n\t    pngusr.dfa $(DFA_XTRA) 1>&2\n\t$(AWK) -f scripts/options.awk out=\"pnglibconf.tmp\" pnglibconf.pre 1>&2\n\tmv pnglibconf.tmp $@\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@  $(OBJS)\n\t$(RANLIB) $@\n\npngtest: pngtest.o libpng.a\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\ninstall: libpng.a pnglibconf.h\n\t-@$(MKDIR_P) $(DESTDIR)$(INCPATH)\n\t-@$(MKDIR_P) $(DESTDIR)$(INCPATH)/libpng\n\t-@$(MKDIR_P) $(DESTDIR)$(LIBPATH)\n\t-@$(RM_F) $(DESTDIR)$(INCPATH)/png.h\n\t-@$(RM_F) $(DESTDIR)$(INCPATH)/pngconf.h\n\t-@$(RM_F) $(DESTDIR)$(INCPATH)/pnglibconf.h\n\tcp png.h $(DESTDIR)$(INCPATH)/libpng\n\tcp pngconf.h $(DESTDIR)$(INCPATH)/libpng\n\tcp pnglibconf.h $(DESTDIR)$(INCPATH)/libpng\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/pnglibconf.h\n\t(cd $(DESTDIR)$(INCPATH); ln -f -s libpng/* .)\n\tcp libpng.a $(DESTDIR)$(LIBPATH)\n\tchmod 644 $(DESTDIR)$(LIBPATH)/libpng.a\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngout.png pnglibconf.h pnglibconf.c \\\n\tpnglibconf.out\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.sunos",
    "content": "# makefile for libpng\n# Copyright (C) 2002, 2006, 2014 Glenn Randers-Pehrson\n# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# where make install puts libpng.a and png.h\nprefix=/usr/local\nINCPATH=$(prefix)/include\nLIBPATH=$(prefix)/lib\n\n# override DESTDIR= on the make install command line to easily support\n# installing into a temporary location.  Example:\n#\n#    make install DESTDIR=/tmp/build/libpng\n#\n# If you're going to install into a temporary location\n# via DESTDIR, $(DESTDIR)$(prefix) must already exist before\n# you execute make install.\nDESTDIR=\n\n# Where the zlib library and include files are located\n#ZLIBLIB=/usr/local/lib\n#ZLIBINC=/usr/local/include\nZLIBLIB=../zlib\nZLIBINC=../zlib\n\n\nWARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow -Wconversion \\\n\t-Wmissing-declarations -Wtraditional -Wcast-align \\\n\t-Wstrict-prototypes -Wmissing-prototypes\n\nCC=gcc\nAR_RC=ar rc\nMKDIR_P=mkdir -p\nLN_SF=ln -f -s\nRANLIB=ranlib\nCP=cp\nRM_F=/bin/rm -f\n\nCPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5\nCFLAGS=-O # $(WARNMORE)\nLDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm\n\n# Pre-built configuration\n# See scripts/pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \\\n\tpngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \\\n\tpngwtran.o pngmem.o pngerror.o pngpread.o\n\n.c.o:\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<\n\nall: libpng.a pngtest\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\nlibpng.a: $(OBJS)\n\t$(AR_RC) $@  $(OBJS)\n\t$(RANLIB) $@\n\npngtest: pngtest.o libpng.a\n\t$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)\n\ntest: pngtest\n\t./pngtest\n\ninstall: libpng.a\n\t-@$(MKDIR_P) $(DESTDIR)$(INCPATH)\n\t-@$(MKDIR_P) $(DESTDIR)$(INCPATH)/libpng\n\t-@$(MKDIR_P) $(DESTDIR)$(LIBPATH)\n\t-@$(RM_F) $(DESTDIR)$(INCPATH)/png.h\n\t-@$(RM_F) $(DESTDIR)$(INCPATH)/pngconf.h\n\t-@$(RM_F) $(DESTDIR)$(INCPATH)/pnglibconf.h\n\tcp png.h $(DESTDIR)$(INCPATH)/libpng\n\tcp pngconf.h $(DESTDIR)$(INCPATH)/libpng\n\tcp pnglibconf.h $(DESTDIR)$(INCPATH)/libpng\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h\n\tchmod 644 $(DESTDIR)$(INCPATH)/libpng/pnglibconf.h\n\t(cd $(DESTDIR)$(INCPATH); $(LN_SF) libpng/* .)\n\tcp libpng.a $(DESTDIR)$(LIBPATH)\n\tchmod 644 $(DESTDIR)$(LIBPATH)/libpng.a\n\nclean:\n\t$(RM_F) *.o libpng.a pngtest pngout.png pnglibconf.h\n\nDOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO\nwritelock:\n\tchmod a-w *.[ch35] $(DOCS) scripts/*\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\npng.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngerror.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngmem.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngset.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngget.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\npngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\npngtest.o: png.h pngconf.h pnglibconf.h\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.tc3",
    "content": "# Makefile for libpng\n# TurboC/C++ (Note: All modules are compiled in C mode)\n\n# To use, do \"make -fmakefile.tc3\"\n\n# ----- Turbo C++ 3.0 -----\n\nMODEL=l\nCPPFLAGS=-I..\\zlib\nCFLAGS=-O2 -Z -m$(MODEL)\nCC=tcc\nLD=tcc\nLIB=tlib\nLDFLAGS=-m$(MODEL) -L..\\zlib\nCP=copy\n\n# Pre-built configuration\n# See scripts\\pnglibconf.mak for more options\n!ifndef PNGLIBCONF_H_PREBUILT\nPNGLIBCONF_H_PREBUILT = scripts\\pnglibconf.h.prebuilt\n!endif\n\nO=.obj\nE=.exe\n\n# variables\nOBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)\nOBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)\nOBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)\nOBJSL1 = +png$(O) +pngset$(O) +pngget$(O) +pngrutil$(O) +pngtrans$(O)\nOBJSL2 = +pngwutil$(O) +pngmem$(O) +pngpread$(O) +pngread$(O) +pngerror$(O)\nOBJSL3 = +pngwrite$(O) +pngrtran$(O) +pngwtran$(O) +pngrio$(O) +pngwio$(O)\n\nall: libpng$(MODEL).lib pngtest$(E)\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\npngtest: pngtest$(E)\n\ntest: pngtest$(E)\n\tpngtest$(E)\n\npng$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t\t  $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngset$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t\t  $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngget$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t\t  $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngread$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t\t  $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngpread$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t\t  $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngrtran$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t\t  $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngrutil$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t\t  $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngerror$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngmem$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngrio$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngwio$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngtest$(O): png.h pngconf.h pnglibconf.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngtrans$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngwrite$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngwtran$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\npngwutil$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c\n\nlibpng$(MODEL).lib: $(OBJS1) $(OBJS2) $(OBJS3)\n\t$(LIB) libpng$(MODEL) +$(OBJSL1)\n\t$(LIB) libpng$(MODEL) +$(OBJSL2)\n\t$(LIB) libpng$(MODEL) +$(OBJSL3)\n\npngtest$(E): pngtest$(O) libpng$(MODEL).lib\n\t$(LD) $(LDFLAGS) pngtest.obj libpng$(MODEL).lib zlib_$(MODEL).lib\n\n# End of makefile for libpng\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makefile.vcwin32",
    "content": "# makefile for libpng\n# Copyright (C) 1998 Tim Wegner\n# Copyright (C) 2006,2009,2011,2014 Glenn Randers-Pehrson\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n#\n# Assumes that zlib.lib, zconf.h, and zlib.h have been copied to ..\\zlib\n# To use, do \"nmake /f scripts\\makefile.vcwin32\"\n\n# -------- Microsoft Visual C++ 2.0 and later --------\n\n# Compiler, linker, librarian and other tools\nCC = cl\nLD = link\nAR = lib\nCPPFLAGS = -I..\\zlib\nCFLAGS  = -nologo -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -MD -O2 -W3\nLDFLAGS = -nologo\nARFLAGS = -nologo\nCP = copy\nRM = del\n\n# Pre-built configuration\n# See scripts\\pnglibconf.mak for more options\nPNGLIBCONF_H_PREBUILT = scripts\\pnglibconf.h.prebuilt\n\n# File extensions\nO=.obj\n\n#uncomment next to put error messages in a file\n#ERRFILE= >> pngerrs.log\n\n# Variables\nOBJS1 = png$(O) pngerror$(O) pngget$(O) pngmem$(O) pngpread$(O)\nOBJS2 = pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) pngset$(O)\nOBJS3 = pngtrans$(O) pngwio$(O) pngwrite$(O) pngwtran$(O) pngwutil$(O)\nOBJS  = $(OBJS1) $(OBJS2) $(OBJS3)\n\n# Targets\nall: libpng.lib\n\npnglibconf.h: $(PNGLIBCONF_H_PREBUILT)\n\t$(CP) $(PNGLIBCONF_H_PREBUILT) $@\n\npng$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngset$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngget$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngread$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngpread$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngrtran$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngrutil$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngerror$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngmem$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngrio$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngwio$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngtrans$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngwrite$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngwtran$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngwutil$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\nlibpng.lib: $(OBJS)\n\t-$(RM) $@\n\t$(AR) $(ARFLAGS) -out:$@ $(OBJS) $(ERRFILE)\n\npngtest$(O): png.h pngconf.h pnglibconf.h\n\t$(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)\n\npngtest.exe: pngtest$(O) libpng.lib\n\t$(LD) $(LDFLAGS) -out:$@ pngtest$(O) libpng.lib ..\\zlib\\zlib.lib $(ERRFILE)\n\ntest: pngtest.exe\n\tpngtest\n\nclean:\n\t-$(RM) *$(O)\n\t-$(RM) libpng.lib\n\t-$(RM) pnglibconf.h\n\t-$(RM) pngtest.exe\n\t-$(RM) pngout.png\n\n# End of makefile for libpng\n\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/makevms.com",
    "content": "$! make libpng under VMS\n$!\n$!\n$! Check for MMK/MMS\n$!\n$! This procedure accepts one parameter (contrib), which causes it to build\n$! the programs from the contrib directory instead of libpng.\n$!\n$ p1 = f$edit(p1,\"UPCASE\")\n$ if p1 .eqs. \"CONTRIB\"\n$ then\n$   set def [.contrib.gregbook]\n$   @makevms\n$   set def [-.pngminus]\n$   @makevms\n$   set def [--]\n$   exit\n$ endif\n$ Make = \"\"\n$ If F$Search (\"Sys$System:MMS.EXE\") .nes. \"\" Then Make = \"MMS\"\n$ If F$Type (MMK) .eqs. \"STRING\" Then Make = \"MMK\"\n$!\n$! Look for the compiler used\n$!\n$ zlibsrc = \"[-.zlib]\"\n$ ccopt=\"/include=''zlibsrc'\"\n$ if f$getsyi(\"HW_MODEL\").ge.1024\n$ then\n$  ccopt = \"/prefix=all\"+ccopt\n$  comp  = \"__decc__=1\"\n$  if f$trnlnm(\"SYS\").eqs.\"\" then define sys sys$library:\n$ else\n$  if f$search(\"SYS$SYSTEM:DECC$COMPILER.EXE\").eqs.\"\"\n$   then\n$    if f$trnlnm(\"SYS\").eqs.\"\" then define sys sys$library:\n$    if f$search(\"SYS$SYSTEM:VAXC.EXE\").eqs.\"\"\n$     then\n$      comp  = \"__gcc__=1\"\n$      CC :== GCC\n$     else\n$      comp = \"__vaxc__=1\"\n$     endif\n$   else\n$    if f$trnlnm(\"SYS\").eqs.\"\" then define sys decc$library_include:\n$    ccopt = \"/decc/prefix=all\"+ccopt\n$    comp  = \"__decc__=1\"\n$  endif\n$ endif\n$!\n$! Build the thing plain or with mms/mmk\n$!\n$ write sys$output \"Compiling Libpng sources ...\"\n$ if make.eqs.\"\"\n$  then\n$   dele pngtest.obj;*\n$   CALL MAKE png.OBJ \"cc ''CCOPT' png\" -\n\tpng.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   CALL MAKE pngset.OBJ \"cc ''CCOPT' pngset\" -\n\tpngset.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   CALL MAKE pngget.OBJ \"cc ''CCOPT' pngget\" -\n\tpngget.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   CALL MAKE pngread.OBJ \"cc ''CCOPT' pngread\" -\n\tpngread.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   CALL MAKE pngpread.OBJ \"cc ''CCOPT' pngpread\" -\n\tpngpread.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   CALL MAKE pngrtran.OBJ \"cc ''CCOPT' pngrtran\" -\n\tpngrtran.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   CALL MAKE pngrutil.OBJ \"cc ''CCOPT' pngrutil\" -\n\tpngrutil.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   CALL MAKE pngerror.OBJ \"cc ''CCOPT' pngerror\" -\n\tpngerror.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   CALL MAKE pngmem.OBJ \"cc ''CCOPT' pngmem\" -\n\tpngmem.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   CALL MAKE pngrio.OBJ \"cc ''CCOPT' pngrio\" -\n\tpngrio.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   CALL MAKE pngwio.OBJ \"cc ''CCOPT' pngwio\" -\n\tpngwio.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   CALL MAKE pngtrans.OBJ \"cc ''CCOPT' pngtrans\" -\n\tpngtrans.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   CALL MAKE pngwrite.OBJ \"cc ''CCOPT' pngwrite\" -\n\tpngwrite.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   CALL MAKE pngwtran.OBJ \"cc ''CCOPT' pngwtran\" -\n\tpngwtran.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   CALL MAKE pngwutil.OBJ \"cc ''CCOPT' pngwutil\" -\n\tpngwutil.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h\n$   write sys$output \"Building Libpng ...\"\n$   CALL MAKE libpng.OLB \"lib/crea libpng.olb *.obj\" *.OBJ\n$   write sys$output \"Building pngtest...\"\n$   CALL MAKE pngtest.OBJ \"cc ''CCOPT' pngtest\" -\n\tpngtest.c png.h pngconf.h pnglibconf.h\n$   call make pngtest.exe -\n\t\"LINK pngtest,libpng.olb/lib,''zlibsrc'libz.olb/lib\" -\n\tpngtest.obj libpng.olb\n$   write sys$output \"Testing Libpng...\"\n$   run pngtest\n$  else\n$   if f$search(\"DESCRIP.MMS\") .eqs. \"\" then copy/nolog [.SCRIPTS]DESCRIP.MMS []\n$   'make'/macro=('comp',zlibsrc='zlibsrc')\n$  endif\n$ write sys$output \"Libpng build completed\"\n$ exit\n$!\n$!\n$MAKE: SUBROUTINE   !SUBROUTINE TO CHECK DEPENDENCIES\n$ V = 'F$Verify(0)\n$! P1 = What we are trying to make\n$! P2 = Command to make it\n$! P3 - P8  What it depends on\n$\n$ If F$Search(P1) .Eqs. \"\" Then Goto Makeit\n$ Time = F$CvTime(F$File(P1,\"RDT\"))\n$arg=3\n$Loop:\n$       Argument = P'arg\n$       If Argument .Eqs. \"\" Then Goto Exit\n$       El=0\n$Loop2:\n$       File = F$Element(El,\" \",Argument)\n$       If File .Eqs. \" \" Then Goto Endl\n$       AFile = \"\"\n$Loop3:\n$       OFile = AFile\n$       AFile = F$Search(File)\n$       If AFile .Eqs. \"\" .Or. AFile .Eqs. OFile Then Goto NextEl\n$       If F$CvTime(F$File(AFile,\"RDT\")) .Ges. Time Then Goto Makeit\n$       Goto Loop3\n$NextEL:\n$       El = El + 1\n$       Goto Loop2\n$EndL:\n$ arg=arg+1\n$ If arg .Le. 8 Then Goto Loop\n$ Goto Exit\n$\n$Makeit:\n$ VV=F$VERIFY(0)\n$ write sys$output P2\n$ 'P2\n$ VV='F$Verify(VV)\n$Exit:\n$ If V Then Set Verify\n$ENDSUBROUTINE\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/options.awk",
    "content": "#!/bin/awk -f\n# scripts/options.awk - library build configuration control\n#\n# last changed in libpng version 1.6.11 - June 5, 2014\n#\n# Copyright (c) 1998-2014 Glenn Randers-Pehrson\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\n# The output of this script is written to the file given by\n# the variable 'out'.  The script is run twice, once with\n# an intermediate output file, 'options.tmp' then again on\n# that file to produce the final output:\n#\n#  awk -f scripts/options.awk out=options.tmp scripts/options.dfa 1>&2\n#  awk -f scripts/options.awk out=options.dfn options.tmp 1>&2\n#\n# Some options may be specified on the command line:\n#\n#  deb=1            Causes debugging to be output\n#  logunsupported=1 Causes all options to be recorded in the output\n#  everything=off   Causes all options to be disabled by default\n#  everything=on    Causes all options to be enabled by default\n#\n# If awk fails on your platform, try nawk instead.\n#\n# These options may also be specified in the original input file (and\n# are copied to the preprocessed file).\n\nBEGIN{\n   out=\"\"                       # intermediate, preprocessed, file\n   pre=-1                       # preprocess (first line)\n   version=\"libpng version unknown\" # version information\n   version_file=\"\"              # where to find the version\n   err=0                        # in-line exit sets this\n   # The following definitions prevent the C preprocessor noticing the lines\n   # that will be in the final output file.  Some C preprocessors tokenise\n   # the lines, for example by inserting spaces around operators, and all\n   # C preprocessors notice lines that start with '#', most remove comments.\n   # The technique adopted here is to make the final output lines into\n   # C strings (enclosed in double quotes), preceeded by PNG_DFN.  As a\n   # consequence the output cannot contain a 'raw' double quote - instead put\n   # @' in, this will be replaced by a single \" afterward.  See the parser\n   # script dfn.awk for more capabilities (not required here).  Note that if\n   # you need a \" in a 'setting' in pnglibconf.dfa it must also be @'!\n   dq=\"@'\"                      # For a single double quote\n   start=\" PNG_DFN \\\"\"          # Start stuff to output (can't contain a \"!)\n   end=\"\\\" \"                    # End stuff to output\n   subs=\"@\\\" \"                  # Substitute start (substitute a C macro)\n   sube=\" \\\"@\"                  # Substitute end\n   comment=start \"/*\"           # Comment start\n   cend=\"*/\" end                # Comment end\n   def=start \"#define PNG_\"     # Arbitrary define\n   sup=\"_SUPPORTED\" end         # end supported option\n   und=comment \"#undef PNG_\"    # Unsupported option\n   une=\"_SUPPORTED\" cend        # end unsupported option\n   error=start \"ERROR:\"         # error message, terminate with 'end'\n\n   # Variables\n   deb=0                        # debug - set on command line\n   everything=\"\"                # do not override defaults\n   logunsupported=0             # write unsupported options too\n\n   # Precreate arrays\n   # for each option:\n   option[\"\"] = \"\"    # list of all options: default enabled/disabled\n   done[\"\"] = 1       # marks option as having been output\n   requires[\"\"] = \"\"  # requires by option\n   iffs[\"\"] = \"\"      # if by option\n   enabledby[\"\"] = \"\" # options that enable it by option\n   sets[\"\"] = \"\"      # settings set by each option\n   setval[\"\"] = \"\"    # value to set (indexed: 'option sets[option]')\n   # for each setting:\n   setting[\"\"] = \"\"   # requires by setting\n   defaults[\"\"] = \"\"  # used for a defaulted value\n   doneset[\"\"] = 1    # marks setting as having been output\n   r[\"\"] = \"\"         # Temporary array\n\n   # For decorating the output file\n   protect = \"\"\n}\n\n# The output file must be specified before any input:\nout == \"\" {\n   print \"out=output.file must be given on the command line\"\n   err = 1\n   exit 1\n}\n\n# The very first line indicates whether we are reading pre-processed\n# input or not, this must come *first* because 'PREPROCESSED' needs\n# to be the very first line in the temporary file.\npre == -1{\n   if ($0 == \"PREPROCESSED\") {\n      pre = 0\n      next\n   } else {\n      pre = 1\n      print \"PREPROCESSED\" >out\n      # And fall through to continue processing\n   }\n}\n\n# While pre-processing if version is set to \"search\" look for a version string\n# in the following file.\npre && version == \"search\" && version_file == \"\"{\n   version_file = FILENAME\n}\n\npre && version == \"search\" && version_file != FILENAME{\n   print \"version string not found in\", version_file\n   err = 1\n   exit 1\n}\n\npre && version == \"search\" && $0 ~ /^ \\* libpng version/{\n   version = substr($0, 4)\n   print \"version =\", version >out\n   next\n}\n\npre && FILENAME == version_file{\n   next\n}\n\n# variable=value\n#   Sets the given variable to the given value (the syntax is fairly\n#   free form, except for deb (you are expected to understand how to\n#   set the debug variable...)\n#\n#   This happens before the check on 'pre' below skips most of the\n#   rest of the actions, so the variable settings happen during\n#   preprocessing but are recorded in the END action too.  This\n#   allows them to be set on the command line too.\n$0 ~ /^[ \t]*version[ \t]*=/{\n   sub(/^[  ]*version[  ]*=[  ]*/, \"\")\n   version = $0\n   next\n}\n$0 ~ /^[ \t]*everything[ \t=]*off[ \t]*$/{\n   everything = \"off\"\n   next\n}\n$0 ~ /^[ \t]*everything[ \t=]*on[ \t]*$/{\n   everything = \"on\"\n   next\n}\n$0 ~ /^[ \t]*logunsupported[ \t=]*0[ \t]*$/{\n   logunsupported = 0\n   next\n}\n$0 ~ /^[ \t]*logunsupported[ \t=]*1[ \t]*$/{\n   logunsupported = 1\n   next\n}\n$1 == \"deb\" && $2 == \"=\" && NF == 3{\n   deb = $3\n   next\n}\n\n# Preprocessing - this just copies the input file with lines\n# that need preprocessing (just chunk at present) expanded\n# The bare \"pre\" instead of \"pre != 0\" crashes under Sunos awk\npre && $1 != \"chunk\"{\n   print >out\n   next\n}\n\n# The first characters of the line determine how it is processed,\n# leading spaces are ignored.  In general tokens that are not\n# keywords are the names of options.  An option 'name' is\n# controlled by the definition of the corresponding macros:\n#\n#   PNG_name_SUPPORTED    The option is turned on\n#   PNG_NO_name\n#   PNG_NO_name_SUPPORTED If the first macro is not defined\n#                         either of these will turn the option off\n#\n# If none of these macros are defined the option is turned on, unless\n# the keyword 'off' is given in a line relating to the option.  The\n# keyword 'on' can also be given, but it will be ignored (since it is\n# the default.)\n#\n# In the syntax below a 'name' is indicated by \"NAME\", other macro\n# values are indicated by \"MACRO\", as with \"NAME\" the leading \"PNG_\"\n# is omitted, but in this case the \"NO_\" prefix and the \"_SUPPORTED\"\n# suffix are never used.\n#\n# Each line is introduced by a keyword - the first non-space characters\n# on the line.  A line starting with a '#' is a comment - it is totally\n# ignored.  Keywords are as follows, a NAME, is simply a macro name\n# without the leading PNG_, PNG_NO_ or the trailing _SUPPORTED.\n\n$1 ~ /^#/ || $0 ~ /^[ \t]*$/{\n   next\n}\n\n# com <comment>\n#   The whole line is placed in the output file as a comment with\n#   the preceding 'com' removed\n$1 == \"com\"{\n   if (NF > 1) {\n      # sub(/^[ \t]*com[ \t]*/, \"\")\n      $1 = \"\"\n      print comment $0, cend >out\n   } else\n      print start end >out\n   next\n}\n\n# version\n#   Inserts a version comment\n$1 == \"version\" && NF == 1{\n   if (version == \"\") {\n      print \"ERROR: no version string set\"\n      err = 1 # prevent END{} running\n      exit 1\n   }\n\n   print comment, version, cend >out\n   next\n}\n\n# file output input protect\n#   Informational: the official name of the input file (without\n#   make generated local directories), the official name of the\n#   output file and, if required, a name to use in a protection\n#   macro for the contents.\n$1 == \"file\" && NF >= 2{\n   print comment, $2, cend >out\n   print comment, \"Machine generated file: DO NOT EDIT\", cend >out\n   if (NF >= 3)\n      print comment, \"Derived from:\", $3, cend >out\n   protect = $4\n   if (protect != \"\") {\n      print start \"#ifndef\", protect end >out\n      print start \"#define\", protect end >out\n   }\n   next\n}\n\n# option NAME ( (requires|enables|if) NAME* | on | off | disabled |\n#                sets SETTING VALUE+ )*\n#     \n#   Declares an option 'NAME' and describes its default setting (disabled)\n#   and its relationship to other options.  The option is disabled\n#   unless *all* the options listed after 'requires' are set and at\n#   least one of the options listed after 'if' is set.  If the\n#   option is set then it turns on all the options listed after 'enables'.\n#\n#   Note that \"enables\" takes priority over the required/if/disabled/off\n#   setting of the target option.\n#\n#   The definition file may list an option as 'disabled': off by default,\n#   otherwise the option is enabled: on by default.  A later (and it must\n#   be later) entry may turn an option on or off explicitly.\n\n$1 == \"option\" && NF >= 2{\n   opt = $2\n   sub(/,$/,\"\",opt)\n   onoff = option[opt]  # records current (and the default is \"\", enabled)\n   key = \"\"\n   istart = 3\n   do {\n      if (istart == 1) {     # continuation line\n         val = getline\n\n         if (val != 1) { # error reading it\n            if (val == 0)\n               print \"option\", opt \": ERROR: missing continuation line\"\n            else\n               print \"option\", opt \": ERROR: error reading continuation line\"\n\n            # This is a hard error\n            err = 1 # prevent END{} running\n            exit 1\n         }\n      }\n\n      for (i=istart; i<=NF; ++i) {\n         val=$(i)\n         sub(/,$/,\"\",val)\n         if (val == \"on\" || val == \"off\" || val == \"disabled\" || val ==\"enabled\") {\n            key = \"\"\n            if (onoff != val) {\n               # on or off can zap disabled or enabled:\n               if (onoff == \"\" || (onoff == \"disabled\" || onoff == \"enabled\") &&\n                   (val == \"on\" || val == \"off\")) {\n                  # It's easy to mis-spell the option when turning it\n                  # on or off, so warn about it here:\n                  if (onoff == \"\" && (val == \"on\" || val == \"off\")) {\n                     print \"option\", opt \": ERROR: turning unrecognized option\", val\n                     # For the moment error out - it is safer\n                     err = 1 # prevent END{} running\n                     exit 1\n                  }\n                  onoff = val\n               } else {\n                  # Print a message, otherwise the error\n                  # below is incomprehensible\n                  print \"option\", opt \": currently\", onoff \": attempt to turn\", val\n                  break\n               }\n            }\n         } else if (val == \"requires\" || val == \"if\" || val == \"enables\" || val ==\"sets\") {\n            key = val\n         } else if (key == \"requires\") {\n            requires[opt] = requires[opt] \" \" val\n         } else if (key == \"if\") {\n            iffs[opt] = iffs[opt] \" \" val\n         } else if (key == \"enables\") {\n            enabledby[val] = enabledby[val] \" \" opt\n         } else if (key == \"sets\") {\n            sets[opt] = sets[opt] \" \" val\n            key = \"setval\"\n            set = val\n         } else if (key == \"setval\") {\n            setval[opt \" \" set] = setval[opt \" \" set] \" \" val\n         } else\n            break # bad line format\n      }\n\n      istart = 1\n   } while (i > NF && $0 ~ /,$/)\n\n   if (i > NF) {\n      # Set the option, defaulting to 'enabled'\n      if (onoff == \"\") onoff = \"enabled\"\n      option[opt] = onoff\n      next\n   }\n   # Else fall through to the error handler\n}\n\n# chunk NAME [requires OPT] [enables LIST] [on|off|disabled]\n#   Expands to the 'option' settings appropriate to the reading and\n#   writing of an ancilliary PNG chunk 'NAME':\n#\n#   option READ_NAME requires READ_ANCILLARY_CHUNKS [READ_OPT]\n#   option READ_NAME enables NAME LIST\n#   [option READ_NAME off]\n#   option WRITE_NAME requires WRITE_ANCILLARY_CHUNKS [WRITE_OPT]\n#   option WRITE_NAME enables NAME LIST\n#   [option WRITE_NAME off]\n\npre != 0 && $1 == \"chunk\" && NF >= 2{\n   # 'chunk' is handled on the first pass by writing appropriate\n   # 'option' lines into the intermediate file.\n   opt = $2\n   sub(/,$/,\"\",opt)\n   onoff = \"\"\n   reqread = \"\"\n   reqwrite = \"\"\n   enables = \"\"\n   req = 0\n   istart = 3\n   do {\n      if (istart == 1) {     # continuation line\n         val = getline\n\n         if (val != 1) { # error reading it\n            if (val == 0)\n               print \"chunk\", opt \": ERROR: missing continuation line\"\n            else\n               print \"chunk\", opt \": ERROR: error reading continuation line\"\n\n            # This is a hard error\n            err = 1 # prevent END{} running\n            exit 1\n         }\n      }\n\n      # read the keywords/additional OPTS\n      for (i=istart; i<=NF; ++i) {\n         val = $(i)\n         sub(/,$/,\"\",val)\n         if (val == \"on\" || val == \"off\" || val == \"disabled\") {\n            if (onoff != val) {\n               if (onoff == \"\")\n                  onoff = val\n               else\n                  break # on/off conflict\n            }\n            req = 0\n         } else if (val == \"requires\")\n            req = 1\n         else if (val == \"enables\")\n            req = 2\n         else if (req == 1){\n            reqread = reqread \" READ_\" val\n            reqwrite = reqwrite \" WRITE_\" val\n         } else if (req == 2)\n            enables = enables \" \" val\n         else\n            break # bad line: handled below\n      }\n\n      istart = 1\n   } while (i > NF && $0 ~ /,$/)\n\n   if (i > NF) {\n      # Output new 'option' lines to the intermediate file (out)\n      print \"option READ_\" opt, \"requires READ_ANCILLARY_CHUNKS\" reqread, \"enables\", opt enables , onoff >out\n      print \"option WRITE_\" opt, \"requires WRITE_ANCILLARY_CHUNKS\" reqwrite, \"enables\", opt enables, onoff >out\n      next\n   }\n   # Else hit the error handler below - bad line format!\n}\n\n# setting MACRO ( requires MACRO* )* [ default VALUE ]\n#   Behaves in a similar way to 'option' without looking for NO_ or\n#   _SUPPORTED; the macro is enabled if it is defined so long as all\n#   the 'requires' macros are also defined.  The definitions may be\n#   empty, an error will be issued if the 'requires' macros are\n#   *not* defined.  If given the 'default' value is used if the\n#   macro is not defined.  The default value will be re-tokenised.\n#   (BTW: this is somewhat restrictive, it mainly exists for the\n#   support of non-standard configurations and numeric parameters,\n#   see the uses in scripts/options.dat\n\n$1 == \"setting\" && (NF == 2 || NF >= 3 && ($3 == \"requires\" || $3 == \"default\")){\n   reqs = \"\"\n   deflt = \"\"\n   isdef = 0\n   key = \"\"\n   for (i=3; i<=NF; ++i)\n      if ($(i) == \"requires\" || $(i) == \"default\") {\n         key = $(i)\n         if (key == \"default\") isdef = 1\n      } else if (key == \"requires\")\n         reqs = reqs \" \" $(i)\n      else if (key == \"default\")\n         deflt = deflt \" \" $(i)\n      else\n         break # Format error, handled below\n\n   setting[$2] = reqs\n   # NOTE: this overwrites a previous value silently\n   if (isdef && deflt == \"\")\n      deflt = \" \" # as a flag to force output\n   defaults[$2] = deflt\n   next\n}\n\n# The order of the dependency lines (option, chunk, setting) is irrelevant\n# - the 'enables', 'requires' and 'if' settings will be used to determine\n# the correct order in the output and the final values in pnglibconf.h are\n# not order dependent.  'requires' and 'if' entries take precedence over\n# 'enables' from other options; if an option requires another option it\n# won't be set regardless of any options that enable it unless the other\n# option is also enabled.\n#\n# Similarly 'enables' trumps a NO_ definition in CFLAGS or pngusr.h\n#\n# For simplicity cycles in the definitions are regarded as errors,\n# even if they are not ambiguous.\n# A given NAME can be specified in as many 'option' lines as required, the\n# definitions are additive.\n\n# For backwards compatibility equivalent macros may be listed thus:\n#\n# = [NO_]NAME MACRO\n#   Makes -DMACRO equivalent to -DPNG_NO_NAME or -DPNG_NAME_SUPPORTED\n#   as appropriate.\n#\n# The definition is injected into the C compiler input when encountered\n# in the second pass (so all these definitions appear *after* the @\n# lines!)\n#\n# 'NAME' is as above, but 'MACRO' is the full text of the equivalent\n# old, deprecated, macro.\n\n$1 == \"=\" && NF == 3{\n   print \"#ifdef PNG_\" $3 >out\n   if ($2 ~ /^NO_/)\n      print \"#   define PNG_\" $2 >out\n   else\n      print \"#   define PNG_\" $2 \"_SUPPORTED\" >out\n   print \"#endif\" >out\n   next\n}\n\n# Lines may be injected into the C compiler input by preceding them\n# with an \"@\" character.  The line is copied with just the leading\n# @ removed.\n\n$1 ~ /^@/{\n   # sub(/^[ \t]*@/, \"\")\n   $1 = substr($1, 2)\n   print >out\n   next\n}\n\n# Check for unrecognized lines, because of the preprocessing chunk\n# format errors will be detected on the first pass independent of\n# any other format errors.\n{\n   print \"options.awk: bad line (\" NR \"):\", $0\n   err = 1 # prevent END{} running\n   exit 1\n}\n\n# For checking purposes names that start with \"ok_\" or \"fail_\" are\n# not output to pnglibconf.h and must be either enabled or disabled\n# respectively for the build to succeed.  This allows interdependencies\n# between options of the form \"at least one of\" or \"at most one of\"\n# to be checked.  For example:\n#\n# option FLOATING_POINT enables ok_math\n# option FIXED_POINT enables ok_math\n#   This ensures that at least one of FLOATING_POINT and FIXED_POINT\n#   must be set for the build to succeed.\n#\n# option fail_math requires FLOATING_POINT FIXED_POINT\n#   This means the build will fail if *both* FLOATING_POINT and\n#   FIXED_POINT are set (this is an example; in fact both are allowed.)\n#\n# If all these options were given the build would require exactly one\n# of the names to be enabled.\n\nEND{\n   # END{} gets run on an exit (a traditional awk feature)\n   if (err) exit 1\n\n   if (pre) {\n      # Record the final value of the variables\n      print \"deb =\", deb >out\n      if (everything != \"\") {\n         print \"everything =\", everything >out\n      }\n      print \"logunsupported =\", logunsupported >out\n      exit 0\n   }\n\n   # Do the options first (allowing options to set settings).  The dependency\n   # tree is thus:\n   #\n   #   name     >     name\n   #   name requires  name\n   #   name if        name\n   #   name enabledby name\n   #\n   # First build a list 'tree' by option of all the things on which\n   # it depends.\n   print \"\" >out\n   print \"/* OPTIONS */\" >out\n   print comment, \"options\", cend >out\n   for (opt in enabledby) tree[opt] = 1  # may not be explicit options\n   for (opt in option) if (opt != \"\") {\n      o = option[opt]\n      # option should always be one of the following values\n      if (o != \"on\" && o != \"off\" && o != \"disabled\" && o != \"enabled\") {\n         print \"internal option error (\" o \")\"\n         exit 1\n      }\n      tree[opt] = \"\"   # so unlisted options marked\n   }\n   for (opt in tree) if (opt != \"\") {\n      if (tree[opt] == 1) {\n         tree[opt] = \"\"\n         if (option[opt] != \"\") {\n            print \"internal error (1)\"\n            exit 1\n         }\n         # Macros only listed in 'enables' remain off unless\n         # one of the enabling macros is on.\n         option[opt] = \"disabled\"\n      }\n\n      split(\"\", list) # clear 'list'\n      # Now add every requires, iffs or enabledby entry to 'list'\n      # so that we can add a unique list of requirements to tree[i]\n      split(requires[opt] iffs[opt] enabledby[opt], r)\n      for (i in r) list[r[i]] = 1\n      for (i in list) tree[opt] = tree[opt] \" \" i\n   }\n\n   # print the tree for extreme debugging\n   if (deb > 2) for (i in tree) if (i != \"\") print i, \"depends-on\" tree[i]\n\n   # Ok, now check all options marked explicitly 'on' or 'off':\n   #\n   # If an option[opt] is 'on' then turn on all requires[opt]\n   # If an option[opt] is 'off' then turn off all enabledby[opt]\n   #\n   # Error out if we have to turn 'on' to an 'off' option or vice versa.\n   npending = 0\n   for (opt in option) if (opt != \"\") {\n      if (option[opt] == \"on\" || option[opt] == \"off\") {\n         pending[++npending] = opt\n      }\n   }\n\n   err = 0 # set on error\n   while (npending > 0) {\n      opt = pending[npending--]\n      if (option[opt] == \"on\") {\n         nreqs = split(requires[opt], r)\n         for (j=1; j<=nreqs; ++j) {\n            if (option[r[j]] == \"off\") {\n               print \"option\", opt, \"turned on, but requirement\", r[j], \"is turned off\"\n               err = 1\n            } else if (option[r[j]] != \"on\") {\n               option[r[j]] = \"on\"\n               pending[++npending] = r[j]\n            }\n         }\n      } else {\n         if (option[opt] != \"off\") {\n            print \"internal error (2)\"\n            exit 1\n         }\n         nreqs = split(enabledby[opt], r)\n         for (j=1; j<=nreqs; ++j) {\n            if (option[r[j]] == \"on\") {\n               print \"option\", opt, \"turned off, but enabled by\", r[j], \"which is turned on\"\n               err = 1\n            } else if (option[r[j]] != \"off\") {\n               option[r[j]] = \"off\"\n               pending[++npending] = r[j]\n            }\n         }\n      }\n   }\n   if (err) exit 1\n\n   # Sort options:\n   print \"PNG_DFN_START_SORT 2\" >out\n\n   # option[i] is now the complete list of all the tokens we may\n   # need to output, go through it as above, depth first.\n   finished = 0\n   while (!finished) {\n      finished = 1\n      movement = 0 # done nothing\n      for (i in option) if (!done[i]) {\n         nreqs = split(tree[i], r)\n         if (nreqs > 0) {\n            for (j=1; j<=nreqs; ++j) if (!done[r[j]]) {\n               break\n            }\n            if (j<=nreqs) {\n               finished = 0\n               continue  # next option\n            }\n         }\n\n         # All the requirements have been processed, output\n         # this option.  An option is _SUPPORTED if:\n         #\n         # all 'requires' are _SUPPORTED AND\n         # at least one of the 'if' options are _SUPPORTED AND\n         # EITHER:\n         #   The name is _SUPPORTED (on the command line)\n         # OR:\n         #   an 'enabledby' is _SUPPORTED\n         # OR:\n         #   NO_name is not defined AND\n         #   the option is not disabled; an option is disabled if:\n         #    option == off\n         #    option == disabled && everything != on\n         #    option == \"\" && everything == off\n         if (deb) print \"option\", i\n         print \"\" >out\n         print \"/* option:\", i, option[i] >out\n         print \" *   requires:  \" requires[i] >out\n         print \" *   if:        \" iffs[i] >out\n         print \" *   enabled-by:\" enabledby[i] >out\n         print \" *   sets:      \" sets[i], \"*/\" >out\n         print \"#undef PNG_on\" >out\n         print \"#define PNG_on 1\" >out\n\n         # requires\n         nreqs = split(requires[i], r)\n         for (j=1; j<=nreqs; ++j) {\n            print \"#ifndef PNG_\" r[j] \"_SUPPORTED\" >out\n            print \"#   undef PNG_on /*!\" r[j] \"*/\" >out\n            # This error appears in the final output if something\n            # was switched 'on' but the processing above to force\n            # the requires did not work\n            if (option[i] == \"on\") {\n               print error, i, \"requires\", r[j] end >out\n            }\n            print \"#endif\" >out\n         }\n\n         # if\n         have_ifs = 0\n         nreqs = split(iffs[i], r)\n         print \"#undef PNG_no_if\" >out\n         if (nreqs > 0) {\n            have_ifs = 1\n            print \"/* if\" iffs[i], \"*/\" >out\n            print \"#define PNG_no_if 1\" >out\n            for (j=1; j<=nreqs; ++j) {\n               print \"#ifdef PNG_\" r[j] \"_SUPPORTED\" >out\n               print \"#   undef PNG_no_if /*\" r[j] \"*/\" >out\n               print \"#endif\" >out\n            }\n            print \"#ifdef PNG_no_if /*missing if*/\" >out\n            print \"#   undef PNG_on\" >out\n            # There is no checking above for this, because we\n            # don't know which 'if' to choose, so whine about\n            # it here:\n            if (option[i] == \"on\") {\n               print error, i, \"needs one of:\", iffs[i] end >out\n            }\n            print \"#endif\" >out\n         }\n\n         print \"#ifdef PNG_on /*requires, if*/\" >out\n         # enables\n         print \"#   undef PNG_not_enabled\" >out\n         print \"#   define PNG_not_enabled 1\" >out\n         print \"   /* enabled by\" enabledby[i], \"*/\" >out\n         nreqs = split(enabledby[i], r)\n         for (j=1; j<=nreqs; ++j) {\n            print \"#ifdef PNG_\" r[j] \"_SUPPORTED\" >out\n            print \"#   undef PNG_not_enabled /*\" r[j] \"*/\" >out\n            # Oops, probably not intended (should be factored\n            # out by the checks above).\n            if (option[i] == \"off\") {\n               print error, i, \"enabled by:\", r[j] end >out\n            }\n            print \"#endif\" >out\n         }\n\n         print \"#   ifndef PNG_\" i \"_SUPPORTED /*!command line*/\" >out\n         print \"#    ifdef PNG_not_enabled /*!enabled*/\" >out\n         # 'have_ifs' here means that everything = \"off\" still allows an 'if' on\n         # an otherwise enabled option to turn it on; otherwise the 'if'\n         # handling is effectively disabled by 'everything = off'\n         if (option[i] == \"off\" || option[i] == \"disabled\" && everything != \"on\" || option[i] == \"enabled\" && everything == \"off\" && !have_ifs) {\n            print \"#      undef PNG_on /*default off*/\" >out\n         } else {\n            print \"#      ifdef PNG_NO_\" i >out\n            print \"#       undef PNG_on /*turned off*/\" >out\n            print \"#      endif\" >out\n            print \"#      ifdef PNG_NO_\" i \"_SUPPORTED\" >out\n            print \"#       undef PNG_on /*turned off*/\" >out\n            print \"#      endif\" >out\n         }\n         print \"#    endif /*!enabled*/\" >out\n         print \"#    ifdef PNG_on\" >out\n         # The _SUPPORTED macro must be defined so that dependent\n         # options output later work.\n         print \"#      define PNG_\" i \"_SUPPORTED\" >out\n         print \"#    endif\" >out\n         print \"#   endif /*!command line*/\" >out\n         # If PNG_on is still set the option should be defined in\n         # pnglibconf.h\n         print \"#   ifdef PNG_on\" >out\n         if (i ~ /^fail_/) {\n            print error, i, \"is on: enabled by:\" iffs[i] enabledby[i] \", requires\" requires[i] end >out\n         } else if (i !~ /^ok_/) {\n            print def i sup >out\n            # Supported option, set required settings\n            nreqs = split(sets[i], r)\n            for (j=1; j<=nreqs; ++j) {\n               print \"#    ifdef PNG_set_\" r[j] >out\n               # Some other option has already set a value:\n               print error, i, \"sets\", r[j] \": duplicate setting\" end >out\n               print error, \"   previous value: \" end \"PNG_set_\" r[j] >out\n               print \"#    else\" >out\n               # Else set the default: note that this won't accept arbitrary\n               # values, the setval string must be acceptable to all the C\n               # compilers we use.  That means it must be VERY simple; a number,\n               # a name or a string.\n               print \"#     define PNG_set_\" r[j], setval[i \" \" r[j]] >out\n               print \"#    endif\" >out\n            }\n         }\n         print \"#   endif /* definition */\" >out\n         print \"#endif /*requires, if*/\" >out\n         if (logunsupported || i ~ /^ok_/) {\n            print \"#ifndef  PNG_on\" >out\n            if (logunsupported) {\n               print und i une >out\n            }\n            if (i ~ /^ok_/) {\n               print error, i, \"not enabled: requires:\" requires[i] \", enabled by:\" iffs[i] enabledby[i] end >out\n            }\n            print \"#endif\" >out\n         }\n\n         done[i] = 1\n         ++movement\n      }\n\n      if (!finished && !movement) {\n         print \"option: loop or missing option in dependency tree, cannot process:\"\n         for (i in option) if (!done[i]) {\n            print \"  option\", i, \"depends on\" tree[i], \"needs:\"\n            nreqs = split(tree[i], r)\n            if (nreqs > 0) for (j=1; j<=nreqs; ++j) if (!done[r[j]]) {\n               print \"   \" r[j]\n            }\n         }\n         exit 1\n      }\n   }\n   print \"PNG_DFN_END_SORT\" >out\n   print comment, \"end of options\", cend >out\n\n   # Do the 'setting' values second, the algorithm the standard\n   # tree walk (O(1)) done in an O(2) while/for loop; interations\n   # settings x depth, outputing the deepest required macros\n   # first.\n   print \"\" >out\n   print \"/* SETTINGS */\" >out\n   print comment, \"settings\", cend >out\n   # Sort (in dfn.awk) on field 2, the setting name\n   print \"PNG_DFN_START_SORT 2\" >out\n   finished = 0\n   while (!finished) {\n      finished = 1\n      movement = 0 # done nothing\n      for (i in setting) if (!doneset[i]) {\n         nreqs = split(setting[i], r)\n         if (nreqs > 0) {\n            # By default assume the requires values are options, but if there\n            # is no option with that name check for a setting\n            for (j=1; j<=nreqs; ++j) if (option[r[j]] == \"\" && !doneset[r[j]]) {\n               break\n            }\n            if (j<=nreqs) {\n               finished = 0\n               continue # try a different setting\n            }\n         }\n\n         # All the requirements have been processed, output\n         # this setting.\n         if (deb) print \"setting\", i\n         deflt = defaults[i]\n         # Remove any spurious trailing spaces\n         sub(/ *$/,\"\",deflt)\n         # A leading @ means leave it unquoted so the preprocessor\n         # can substitute the build time value\n         if (deflt ~ /^ @/)\n            deflt = \" \" subs substr(deflt, 3) sube\n         print \"\" >out\n         print \"/* setting: \", i >out\n         print \" *   requires:\" setting[i] >out\n         print \" *   default: \", defaults[i] deflt, \"*/\" >out\n         for (j=1; j<=nreqs; ++j) {\n            if (option[r[j]] != \"\")\n               print \"#ifndef PNG_\" r[j] \"_SUPPORTED\" >out\n            else\n               print \"#ifndef PNG_\" r[j] >out\n            print error, i, \"requires\", r[j] end >out\n            print \"# endif\" >out\n         }\n         # The precedence is:\n         #\n         #  1) External definition; trumps:\n         #  2) Option 'sets' value; trumps:\n         #  3) Setting 'default'\n         #\n         print \"#ifdef PNG_\" i >out\n         # PNG_<i> is defined, so substitute the value:\n         print def i, subs \"PNG_\" i sube end >out\n         print \"#else /* use default */\" >out\n         print \"# ifdef PNG_set_\" i >out\n         # Value from an option 'sets' argument\n         print def i, subs \"PNG_set_\" i sube end >out\n         # This is so that subsequent tests on the setting work:\n         print \"#  define PNG_\" i, \"1\" >out\n         if (defaults[i] != \"\") {\n            print \"# else /*default*/\" >out\n            print def i deflt end >out\n            print \"#  define PNG_\" i, \"1\" >out\n         }\n         print \"# endif /* defaults */\" >out\n         print \"#endif /* setting\", i, \"*/\" >out\n\n         doneset[i] = 1\n         ++movement\n      }\n\n      if (!finished && !movement) {\n         print \"setting: loop or missing setting in 'requires', cannot process:\"\n         for (i in setting) if (!doneset[i]) {\n            print \"  setting\", i, \"requires\" setting[i]\n         }\n         exit 1\n      }\n   }\n   print \"PNG_DFN_END_SORT\" >out\n   print comment, \"end of settings\", cend >out\n\n   # Regular end - everything looks ok\n   if (protect != \"\") {\n      print start \"#endif\", \"/*\", protect, \"*/\" end >out\n   }\n}\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/pnglibconf.dfa",
    "content": "# scripts/pnglibconf.dfa - library build configuration control\n#\n@/*- pnglibconf.dfn intermediate file\n@ *  generated from scripts/pnglibconf.dfa\n@ */\n#\ncom pnglibconf.h - library build configuration\ncom\nversion\ncom\ncom Copyright (c) 1998-2016 Glenn Randers-Pehrson\ncom\ncom This code is released under the libpng license.\ncom For conditions of distribution and use, see the disclaimer\ncom and license in png.h\ncom\n\nfile pnglibconf.h scripts/pnglibconf.dfa PNGLCONF_H\n\n# This file is preprocessed by scripts/options.awk and the\n# C compiler to generate 'pnglibconf.h' - a list of all the\n# configuration options.  The file lists the various options\n# that can *only* be specified during the libpng build;\n# pnglibconf.h freezes the definitions selected for the specific\n# build.\n#\n# The syntax is detailed in scripts/options.awk; this is a summary\n# only:\n#\n# setting <name> [requires ...] [default]\n#    #define PNG_<name> <value>  /* value comes from current setting */\n# option <name> [requires ...] [if ...] [enables ...] [disabled]\n#    #define PNG_<name>_SUPPORTED if the requirements are met and\n#    enable the other options listed\n# chunk <name> [requires ...] [enables ...] [disabled]\n#    Enable chunk processing for the given ancillary chunk; any\n#    'requires something' expands to READ_something for read and\n#    WRITE_something for write, but the enables list members are\n#    used as given (e.g. enables GAMMA just expands to that on the\n#    correspond READ_name and WRITE_name lines.)\n#\n# \",\" may be used to separate options on an 'option' line and is ignored; it\n# doesn't change the meaning of the line.  (NOT setting, where \",\" becomes\n# part of the setting!)  A comma at the end of an option line causes a\n# continuation (the next line is included in the option too.)\n#\n# Note that the 'on' and 'off' keywords, while valid on both option\n# and chunk, should not be used in this file because they force the\n# relevant options on or off.\n\n#----------------------------------------------------------------------\n\n# The following setting, option and chunk values can all be changed\n# while building libpng:\n#\n# setting: change 'setting' lines to fine tune library performance;\n#   changes to the settings don't affect the libpng API functionally\n#\n# option: change 'option' lines to remove or add capabilities from\n#   or to the library; options change the library API\n#\n# chunk: change 'chunk' lines to remove capabilities to process\n#   optional ('ancillary') chunks.  This does not prevent PNG\n#   decoding but does change the libpng API because some chunks\n#   will be ignored.\n#\n# There are three ways of disabling features, in no particular order:\n#\n# 1) Create 'pngusr.h', enter the required private build information\n# detailed below and #define PNG_NO_<option> for each option you\n# don't want in that file in that file.  You can also turn on options\n# using PNG_<option>_SUPPORTED.  When you have finished rerun\n# configure and rebuild pnglibconf.h file with -DPNG_USER_CONFIG:\n#\n#  make clean\n#  CPPFLAGS='-DPNG_USER_CONFIG' ./configure\n#  make pnglibconf.h\n#\n# pngusr.h is only used during the creation of pnglibconf.h, but it\n# is safer to ensure that -DPNG_USER_CONFIG is specified throughout\n# the build by changing the CPPFLAGS passed to the initial ./configure\n#\n# 2) Add definitions of the settings you want to change to\n# CPPFLAGS; for example:\n#\n#   -DPNG_DEFAULT_READ_MACROS=0\n#\n# (This would change the default to *not* use read macros.)  Be\n# very careful to change only settings that don't alter the API\n# because this approach bypasses the private build checking.  You\n# can also change settings from pngpriv.h (read pngpriv.h) safely\n# without API changes.  Do that in the same way.\n#\n# 3) Write a new '.dfa' file (say 'pngusr.dfa') and in this file\n# provide override values for setting entries and turn option or\n# chunk values explicitly 'on' or 'off':\n#\n#    setting FOO default VALUE\n#    option BAR [on|off]\n#\n# Then add this file to the options.awk command line (the *first*\n# one) after this file.  The make macro DFA_XTRA is provided to make\n# this easier (set it like CPPFLAGS prior to running ./configure).\n# Look at the builds below contrib/pngminim for some extreme examples\n# of how this can be used.\n#\n# Don't edit this file unless you are contributing a patch to\n# libpng and need new or modified options/settings.\n#----------------------------------------------------------------------\n\n# The following causes commented out #undef lines to be written to\n# pnglibconf.h; this can be stopped by logunsupported=0 in a later\n# file or on the command line (after pnglibconf.dfa)\n\nlogunsupported = 1\n\n# The following allows the output from configure to modify the contents of\n# pnglibconf.h\n\n@#ifdef HAVE_CONFIG_H\n@#  include \"config.h\"\n@#endif\n\n# PNG_USER_CONFIG has to be defined on the compiler command line\n# to cause pngusr.h to be read while constructing pnglibconf.h\n#\n# If you create a private DLL you need to define the following\n# macros in the file 'pngusr.h' and set -DPNG_USER_CONFIG for\n# compilation (i.e. in CPPFLAGS.)\n# #define PNG_USER_PRIVATEBUILD \\\n#     <Describes by whom and why this version of the DLL was built>\n#  e.g. #define PNG_USER_PRIVATEBUILD \"Build by MyCompany for xyz reasons.\"\n# #define PNG_USER_DLLFNAME_POSTFIX <two-letter postfix that serve to\n#        distinguish your DLL from those of the official release. These\n#        correspond to the trailing letters that come after the version\n#        number and must match your private DLL name>\n#  e.g. // private DLL \"libpng13gx.dll\"\n#       #define PNG_USER_DLLFNAME_POSTFIX \"gx\"\n#\n# The following macros are also at your disposal if you want to complete the\n# DLL VERSIONINFO structure.\n# - PNG_USER_VERSIONINFO_COMMENTS\n# - PNG_USER_VERSIONINFO_COMPANYNAME\n# - PNG_USER_VERSIONINFO_LEGALTRADEMARKS\n\n# It is necessary to include configures definitions here so that AC_DEFINE\n# in configure.ac works in a comprehensible way\n@#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)\n@#  include \"config.h\"\n@#endif\n\n@#ifdef PNG_USER_CONFIG\n@#  include \"pngusr.h\"\n@#endif\n\n# This is a special fixup for the Watcom C compiler on Windows, which has\n# multiple procedure call standards.  Unless PNG_API_RULE is set explicitly\n# (i.e. if it is not defined at this point) it will be forced to '2' here when\n# using Watcom.  This indicates to the other header files that Watcom behaviour\n# is required where appropriate.\n\n@#ifdef __WATCOMC__\n@#  ifndef PNG_API_RULE\n@#     define PNG_API_RULE 2 /* Use Watcom calling conventions */\n@#  endif\n@#endif\n\n# IN DEVELOPMENT\n# These are currently experimental features; define them if you want (NOTE:\n# experimental options must be disabled before they are defined in this file!)\n\n# NONE\n\n# Note that PNG_USER_CONFIG only has an effect when building\n# pnglibconf.h\n\nsetting USER_CONFIG\nsetting USER_PRIVATEBUILD\nsetting USER_DLLFNAME_POSTFIX\nsetting USER_VERSIONINFO_COMMENTS\nsetting USER_VERSIONINFO_COMPANYNAME\nsetting USER_VERSIONINFO_LEGALTRADEMARKS\n\n# Record the 'API rule' used to select calling conventions on\n# those systems that support such things (see all the comments in\n# pngconf.h)\n# Changing this setting has a fundamental affect on the PNG ABI,\n# do not release shared libraries with this changed.\n\nsetting API_RULE default 0\n\n# This allows a prefix to be added to the front of every API functon name (and\n# therefore every symbol) by redefining all the function names with the prefix\n# at the end of pnglibconf.h.  It also turns on similar internal symbol renaming\n# by causing a similar build-time only file, pngprefix.h, to be generated.\n\nsetting PREFIX\n\n# Implementation specific control of the optimizations, enabled by those\n# hardware or software options that need it (typically when run-time choices\n# must be made by the user)\noption SET_OPTION disabled\n\n# These options are specific to the ARM NEON hardware optimizations.  At present\n# these optimizations depend on GCC specific pre-processing of an assembler (.S)\n# file so they probably won't work with other compilers.\n#\n# ARM_NEON_OPT: unset: check at compile time (__ARM_NEON__ must be defined by\n#                      the compiler, typically as a result of specifying\n#                      CC=\"gcc -mfpu=neon\".)\n#                   0: disable (even if the CPU has a NEON FPU.)\n#                   1: check at run time (via ARM_NEON_{API,CHECK})\n#                   2: switch on unconditionally (inadvisable - instead pass\n#                      -mfpu=neon to GCC in CC)\n#           When building libpng avoid using any setting other than '0'; '1' is\n#           set automatically when either 'API' or 'CHECK' are configured in,\n#           '2' should not be necessary as -mfpu=neon will achieve the same\n#           effect as well as applying NEON optimizations to the rest of the\n#           libpng code.\n#           NOTE: any setting other than '0' requires ALIGNED_MEMORY\n# ARM_NEON_API:   (PNG_ARM_NEON == 1) allow the optimization to be switched on\n#                 with png_set_option\n# ARM_NEON_CHECK: (PNG_ARM_NEON == 1) compile a run-time check to see if Neon\n#                 extensions are supported. This is poorly supported and\n#                 deprecated - use the png_set_option API.\nsetting ARM_NEON_OPT\noption ARM_NEON_API disabled requires ALIGNED_MEMORY enables SET_OPTION,\n   sets ARM_NEON_OPT 1\noption ARM_NEON_CHECK disabled requires ALIGNED_MEMORY,\n   sets ARM_NEON_OPT 1\n\n# These settings configure the default compression level (0-9) and 'strategy';\n# strategy is as defined by the implementors of zlib. It describes the input\n# data and modifies the zlib parameters in an attempt to optimize the balance\n# between search and huffman encoding in the zlib algorithms.  The defaults are\n# the zlib.h defaults - the apparently recursive definition does not arise\n# because the name of the setting is prefixed by PNG_\n#\n# The TEXT values are the defaults when writing compressed text (all forms)\n\n# Include the zlib header so that the defaults below are known\n@#  include <zlib.h>\n\n# The '@' here means to substitute the value when pnglibconf.h is built\nsetting Z_DEFAULT_COMPRESSION default @Z_DEFAULT_COMPRESSION\n# TODO: why aren't these Z_RLE; zlib.h says that Z_RLE, specifically, is\n# appropriate for PNG images, maybe it doesn't exist in all versions?\nsetting Z_DEFAULT_STRATEGY default @Z_FILTERED\nsetting Z_DEFAULT_NOFILTER_STRATEGY default @Z_DEFAULT_STRATEGY\nsetting ZLIB_VERNUM default @ZLIB_VERNUM\n\n# Linkage of:\n#\n#  API:      libpng API functions\n#  CALLBACK: internal non-file-local callbacks\n#  FUNCTION: internal non-file-local functions\n#  DATA:     internal non-file-local (const) data\nsetting LINKAGE_API default extern\nsetting LINKAGE_CALLBACK default extern\nsetting LINKAGE_FUNCTION default extern\nsetting LINKAGE_DATA default extern\n\nsetting TEXT_Z_DEFAULT_COMPRESSION default @Z_DEFAULT_COMPRESSION\nsetting TEXT_Z_DEFAULT_STRATEGY default @Z_DEFAULT_STRATEGY\n\n# Default to using the read macros\n\nsetting DEFAULT_READ_MACROS default 1\n\n# The alternative is to call functions to read PNG values, if\n# the functions are turned *off* the read macros must always\n# be enabled, so turning this off will actually force the\n# USE_READ_MACROS option on (see pngconf.h)\n\noption READ_INT_FUNCTIONS requires READ\n\n# The same for write  but these can only be switched off if no writing\n# is required at all - hence the use of a 'disabled', not a 'requires'.\n# If these are needed, they are enabled in the 'WRITE options' section\n# below.\n\noption WRITE_INT_FUNCTIONS disabled\n\n# Error controls\n#\n# WARNINGS: normally on, if off no warnings are generated\n# ERROR_TEXT: normally on, if off errors happen but there is no message\n# ERROR_NUMBERS: unimplemented feature, therefore disabled\n# BENIGN_ERRORS: support for just issuing warnings for recoverable errors\n#\n# BENIGN_READ_ERRORS:\n#     By default recoverable errors on read should just generate warnings,\n#     generally safe but PNG files that don't conform to the specification will\n#     be accepted if a meaningful result can be produced.\n#\n# BENIGN_WRITE_ERRORS:\n#     By default recoverable errors on write should just generate warnings,\n#     not generally safe because this allows the application to write invalid\n#     PNG files.  Applications should enable this themselves; it's useful\n#     because it means that a failure to write an ancilliary chunk can often be\n#     ignored.\n\noption WARNINGS\noption ERROR_TEXT\noption ERROR_NUMBERS disabled\n\noption BENIGN_ERRORS\noption BENIGN_WRITE_ERRORS requires BENIGN_ERRORS disabled\noption BENIGN_READ_ERRORS requires BENIGN_ERRORS\n\n\n# Generic options - affect both read and write.\n\noption MNG_FEATURES\n\n# Arithmetic options, the first is the big switch that chooses between internal\n# floating and fixed point arithmetic implementations - it does not affect any\n# APIs.  The second two (the _POINT settings) switch off individual APIs.\n#\n# Prior to libpng 1.6.8 one of the API (_POINT) variants had to be selected.  At\n# 1.6.8 this restriction has been removed; the simplified API can be used\n# without enabling any of the low level fixed/floating APIs.\n\noption FLOATING_ARITHMETIC\noption FLOATING_POINT\noption FIXED_POINT\n\n# This protects us against compilers that run on a windowing system\n# and thus don't have or would rather us not use the stdio types:\n# stdin, stdout, and stderr.  The only one currently used is stderr\n# in png_error() and png_warning().  #defining PNG_NO_CONSOLE_IO will\n# prevent these from being compiled and used. #defining PNG_NO_STDIO\n# will also prevent these, plus will prevent the entire set of stdio\n# macros and functions (FILE *, printf, etc.) from being compiled and used,\n# unless (PNG_DEBUG > 0) has been #defined.\n\noption STDIO\noption CONSOLE_IO requires STDIO\n\n# Note: prior to 1.5.0 this option could not be disabled if STDIO\n# was enabled.  Prior to 1.5.3 this option required STDIO\n\noption TIME_RFC1123\n\n# PNG_SETJMP_NOT_SUPPORTED is an old equivalent for NO_SETJMP\n\noption SETJMP\n= NO_SETJMP SETJMP_NOT_SUPPORTED\n\n# If this is disabled it is not possible for apps to get the\n# values from the 'info' structure, this effectively removes\n# quite a lot of the READ API.\n\noption EASY_ACCESS\n\n# Added at libpng-1.2.0\n\noption USER_MEM\n\n# Added at libpng-1.4.0\n\noption IO_STATE\n\n# Libpng limits: limit the size of images and data on read.\n#\n# If this option is disabled all the limit checking code will be disabled:\n\noption USER_LIMITS requires READ\n\n# The default settings given below for the limits mean that libpng will\n# limit the size of images or the size of data in ancilliary chunks to less\n# than the specification or implementation limits. Settings have the\n# following interpretations:\n#\n# USER_WIDTH_MAX: maximum width of an image that will be read\n# USER_HEIGHT_MAX: maximum height\n# USER_CHUNK_MALLOC_MAX: maximum in-memory (decompressed) size of a single chunk\n# USER_CHUNK_CACHE_MAX: maximum number of chunks to be cached\n#\n# Only chunks that are variable in number are counted towards the\n\n# Use 0x7fffffff for unlimited\nsetting USER_WIDTH_MAX default        1000000\nsetting USER_HEIGHT_MAX default       1000000\n\n# Use 0 for unlimited\nsetting USER_CHUNK_CACHE_MAX default     1000\nsetting USER_CHUNK_MALLOC_MAX default 8000000\n\n# If this option is enabled APIs to set the above limits at run time are added;\n# without this the hardwired (compile time) limits will be used.\noption SET_USER_LIMITS requires USER_LIMITS\n\n# All of the following options relate to code capabilities for\n# processing image data before creating a PNG or after reading one.\n# You can remove these capabilities safely and still be PNG\n# conformant, however the library that results is still non-standard.\n# See the comments above about how to change options and settings.\n\n# READ options\n#\n# WARNING: in libpng 1.5 maintained configuration compatibility with earlier\n# versions.  In some cases turning off an option turned off other options, in\n# others it was ineffective unless dependent options were also turned off.\n# Libpng 1.6 changes this: in general if you turn off an option that affects\n# APIs it stays off and simply disables APIs that depend on it.\n#\n# As a result if you simply port the libpng 1.5 configuration to libpng 1.6 you\n# will probably see build failures due to missing APIs.  Fixing these failures\n# requires some, perhaps considerable, knowledge of what your libpng using\n# applications are doing, fortunately there is no great reason for you to move\n# to libpng 1.6; the new interfaces in 1.6 will take several years to become\n# popular.\n\noption READ enables READ_INTERLACING SET_OPTION\n\n# Disabling READ_16BIT does not disable reading 16-bit PNG files, but it\n# forces them to be chopped down to 8-bit, and disables any 16-bit\n# processing after that has happened.  You need to be sure to enable\n# READ_SCALE_16_TO_8 or READ_STRIP_16_TO_8 when you disable READ_16BIT for\n# this to work properly.  You should disable the other option if you need to\n# ensure a particular conversion (otherwise the app can chose.)\n\noption READ_16BIT requires READ enables 16BIT\n\noption READ_QUANTIZE requires READ\n\noption READ_TRANSFORMS requires READ\n= NO_READ_TRANSFORMS READ_TRANSFORMS_NOT_SUPPORTED\n\n# Read gamma handling.  Gamma processing is a core part of libpng and many of\n# the capabilities are dependent on libpng performing gamma correction.\n#\n# In libpng 1.6 disabling gamma processing (setting PNG_NO_READ_GAMMA)\n# consistently disables those parts of the API that depend on it.  Prior to\n# 1.6.0 this was not true; the results were unpredictable and varied between\n# releases.\n#\n# If you disable gamma processing and your program no longer compiles you need\n# to ask whether you really need the APIs that are missing.  If you do then you\n# almost certainly need the gamma processing.\n#\n# If you handle gamma issues outside libpng then you do not need the libpng\n# gamma processing; and it is an enormous waste of space.  You just need to\n# remove the use of libpng APIs that depend on it.\noption READ_GAMMA requires READ_TRANSFORMS, READ_gAMA, READ_sRGB\n\noption READ_ALPHA_MODE requires READ_TRANSFORMS, READ_GAMMA\noption READ_BACKGROUND requires READ_TRANSFORMS, READ_STRIP_ALPHA, READ_GAMMA\noption READ_BGR requires READ_TRANSFORMS\noption READ_EXPAND_16 requires READ_TRANSFORMS, READ_16BIT, READ_EXPAND\noption READ_EXPAND requires READ_TRANSFORMS\noption READ_FILLER requires READ_TRANSFORMS\noption READ_GRAY_TO_RGB requires READ_TRANSFORMS\noption READ_INVERT_ALPHA requires READ_TRANSFORMS\noption READ_INVERT requires READ_TRANSFORMS\noption READ_PACK requires READ_TRANSFORMS\noption READ_PACKSWAP requires READ_TRANSFORMS\noption READ_RGB_TO_GRAY requires READ_TRANSFORMS, READ_GAMMA enables COLORSPACE\noption READ_SCALE_16_TO_8 requires READ_TRANSFORMS\noption READ_SHIFT requires READ_TRANSFORMS\noption READ_STRIP_16_TO_8 requires READ_TRANSFORMS\noption READ_STRIP_ALPHA requires READ_TRANSFORMS\noption READ_SWAP_ALPHA requires READ_TRANSFORMS\noption READ_SWAP requires READ_TRANSFORMS, READ_16BIT\noption READ_USER_TRANSFORM requires READ_TRANSFORMS\n\noption PROGRESSIVE_READ requires READ\noption SEQUENTIAL_READ requires READ\n\n# You can define PNG_NO_PROGRESSIVE_READ if you don't do progressive reading.\n# This is not talking about interlacing capability!  You'll still have\n# interlacing unless you turn off the following which is required\n# for PNG-compliant decoders.  (In other words, do not do this - in\n# fact it can't be disabled from the command line!)\n#option READ_INTERLACING requires READ\n\noption READ_COMPOSITE_NODIV requires READ\n= NO_READ_COMPOSITE_NODIV NO_READ_COMPOSITED_NODIV\n\n# Inch conversions\n\noption INCH_CONVERSIONS\n= INCH_CONVERSIONS INCH_CONVERSIONS\n\n# API to build a grayscale palette\n# NOTE: this is not used internally by libpng at present.\n\noption BUILD_GRAYSCALE_PALETTE\n\n# WRITE options\n\noption WRITE enables WRITE_INT_FUNCTIONS\n\n# Disabling WRITE_16BIT prevents 16-bit PNG files from being\n# generated.\noption WRITE_16BIT requires WRITE enables 16BIT\n\noption WRITE_TRANSFORMS requires WRITE\n= NO_WRITE_TRANSFORMS WRITE_TRANSFORMS_NOT_SUPPORTED\n\noption WRITE_SHIFT requires WRITE_TRANSFORMS\noption WRITE_PACK requires WRITE_TRANSFORMS\noption WRITE_BGR requires WRITE_TRANSFORMS\noption WRITE_SWAP requires WRITE_TRANSFORMS, WRITE_16BIT\noption WRITE_PACKSWAP requires WRITE_TRANSFORMS\noption WRITE_INVERT requires WRITE_TRANSFORMS\noption WRITE_FILLER requires WRITE_TRANSFORMS\noption WRITE_SWAP_ALPHA requires WRITE_TRANSFORMS\noption WRITE_INVERT_ALPHA requires WRITE_TRANSFORMS\noption WRITE_USER_TRANSFORM requires WRITE_TRANSFORMS\n\n# This is not required for PNG-compliant encoders, but can cause\n# trouble if left undefined\n\noption WRITE_INTERLACING requires WRITE\n\n# Deprecated, will be removed.\noption WRITE_WEIGHTED_FILTER requires WRITE\n\noption WRITE_FLUSH requires WRITE\n\n# Note: these can be turned off explicitly if not required by the\n# apps implementing the user transforms\noption USER_TRANSFORM_PTR if READ_USER_TRANSFORM, WRITE_USER_TRANSFORM\noption USER_TRANSFORM_INFO if READ_USER_TRANSFORM, WRITE_USER_TRANSFORM\n\n# This enables API to set compression parameters for compressing\n# non-IDAT chunks (zTXt, iTXt, iCCP, and unknown chunks).  This feature\n# was added at libpng-1.5.3.\noption WRITE_CUSTOMIZE_ZTXT_COMPRESSION requires WRITE\noption WRITE_CUSTOMIZE_COMPRESSION requires WRITE\n\n# Any chunks you are not interested in, you can undef here.  The\n# ones that allocate memory may be expecially important (hIST,\n# tEXt, zTXt, tRNS, pCAL).  Others will just save time and make png_info\n# a bit smaller.\n\n# The size of the png_text structure changed in libpng-1.0.6 when\n# iTXt support was added.  iTXt support was turned off by default through\n# libpng-1.2.x, to support old apps that malloc the png_text structure\n# instead of calling png_set_text() and letting libpng malloc it.  It\n# was turned on by default in libpng-1.4.0.\n\noption READ_ANCILLARY_CHUNKS requires READ\n# PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED is deprecated.\n= NO_READ_ANCILLARY_CHUNKS READ_ANCILLARY_CHUNKS_NOT_SUPPORTED\n\noption WRITE_ANCILLARY_CHUNKS requires WRITE\n# PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED is deprecated.\n= NO_WRITE_ANCILLARY_CHUNKS WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED\n\n# These options disable *all* the text chunks if turned off\n\noption READ_TEXT requires READ_ANCILLARY_CHUNKS enables TEXT\noption WRITE_TEXT requires WRITE_ANCILLARY_CHUNKS enables TEXT\n\n# Moved to pnglibconf.h at libpng-1.5.0\n# Feature support: in 1.4 this was in pngconf.h, but the following\n# features have no affect on the libpng API.  Add library\n# only features to the end of this list.  Add features that\n# affect the API above.  (Note: the list of chunks follows\n# the library-only settings.)\n#\n# BUILD TIME ONLY OPTIONS\n#   These options do not affect the API but rather alter how the\n#   API is implemented, they get recorded in pnglibconf.h, but\n#   can't be changed by the application.\n\n# Colorspace support (enabled as required); just the support for colorant\n# information.  Gamma support, likewise, is just support for the gamma\n# information, READ_GAMMA is required for gamma transformations (so it\n# is possible to read PNG gamma without enabling all the libpng transform\n# code - do this for applications that do their own gamma processing)\n#\n# As of 1.6.0 COLORSPACE is only useful if the application processes the\n# information; this is because the library does not do any colorspace\n# processing, it just validates the data in the PNG file.\n\noption GAMMA disabled\noption COLORSPACE enables GAMMA disabled\n\n# When an ICC profile is read, or png_set, it will be checked for a match\n# against known sRGB profiles if the sRGB handling is enabled.  The\n# PNG_sRGB_PROFILE_CHECKS setting controls how much work is done during the\n# check:\n#\n# -1: Don't do any sRGB profile checking.\n#\n#  0: Just validate the profile MD5 signature if present, otherwise use\n#     the checks in option 1.\n#\n#  1: Additionally check the length, intent and adler32 checksum of the\n#     actual data.   If enabled this will reject known profiles that have\n#     had the rendering intent in the header changed as well as other edits\n#     done without updating the checksum.  See the discussion below.\n#\n#  2: Additionally checksum all the data using the ethernet CRC32 algorithm.\n#     This makes it more difficult to fake profiles and makes it less likely\n#     to get a false positive on profiles with no signature, but is probably\n#     just a waste of time since all currently approved ICC sRGB profiles have\n#     a secure MD5 signature.\n#\n# The rendering intent.  An ICC profile stores an intended rendering intent,\n# but does not include the value in the signature.  The intent is documented\n# as the intent that should be used when combining two profiles.  The sRGB\n# profile is intended, however, to be used with any of the four defined intents.\n# For this reason the sRGB chunk includes an 'intent' to be used when displaying\n# the image (intent is really a property of the image not the profile.)\n#\n# Unfortunately the iCCP chunk does not.  It may therefore be that some\n# applications modify the intent in profiles (including sRGB profiles) to work\n# round this problem.  Selecting an option other than option '0' will cause such\n# modified profiles to be rejected.\n#\n# Security.  The use of Adler32 and CRC32 checksums does not help significantly\n# with any security issues.  It is relatively easy to produce arbitrary profiles\n# with the required checksums on current computer systems.  Nevertheless\n# security does not seem to be an issue because the only consequence of a false\n# positive is a false assertion that the profile is an sRGB profile.  This might\n# be used to hide data from libpng using applications, but it doesn't seem\n# possible to damage them.\n\nsetting sRGB_PROFILE_CHECKS default 2\n\n# Artificially align memory - the code typically aligns to 8 byte\n# boundaries if this is switched on, it's a small waste of space\n# but can help (in theory) on some architectures.  Only affects\n# internal structures.  Added at libpng 1.4.0\n\noption ALIGNED_MEMORY\n\n# Buggy compilers (e.g., gcc 2.7.2.2) need PNG_NO_POINTER_INDEXING\n# See png[wr]util.c, normally this should always be *on*\n\noption POINTER_INDEXING\n\n# Other defines for things like memory and the like can go here.\n\n# BUILD TIME SETTINGS\n# Like build time options these do not affect the API, but they\n# may be useful to applications because they record details of\n# how the API will behave particularly with regard to overall\n# accuracy.\n\n# This controls how fine the quantizing gets.  As this allocates\n# a largish chunk of memory (32K), those who are not as concerned\n# with quantizing quality can decrease some or all of these.\n\nsetting QUANTIZE_RED_BITS default 5\nsetting QUANTIZE_GREEN_BITS default 5\nsetting QUANTIZE_BLUE_BITS default 5\n\n# This controls how fine the gamma correction becomes when you\n# are only interested in 8 bits anyway.  Increasing this value\n# results in more memory being used, and more pow() functions\n# being called to fill in the gamma tables.  Don't set this value\n# less than 8, and even that may not work (I haven't tested it).\n\nsetting MAX_GAMMA_8 default 11\n\n# This controls how much a difference in gamma we can tolerate before\n# we actually start doing gamma conversion, it's a fixed point value,\n# so the default below is 0.05, meaning libpng ignores corrections in\n# the range 0.95 to 1.05\n\nsetting GAMMA_THRESHOLD_FIXED default 5000\n\n# Precision to use when converting a floating point value to a PNG\n# extension format string in an sCAL chunk (only relevant if the\n# floating point API is enabled)\n\nsetting sCAL_PRECISION default 5\n\n# This is the size of the compression buffer, and thus the size of\n# an IDAT chunk.  Make this whatever size you feel is best for your\n# machine.  One of these will be allocated per png_struct.  When this\n# is full, it writes the data to the disk, and does some other\n# calculations.  Making this an extremely small size may slow\n# the library down, but you may want to experiment to determine\n# where it becomes significant, if you are concerned with memory\n# usage.  Note that zlib allocates at least 32Kb also.  For readers,\n# this describes the size of the buffer available to read the data in.\n# Unless this gets smaller than the size of a row (compressed),\n# it should not make much difference how big this is.\n\nsetting ZBUF_SIZE default 8192\n\n# This is the size of the decompression buffer used when counting or checking\n# the decompressed size of an LZ stream from a compressed ancilliary chunk; the\n# decompressed data is never used so a different size may be optimal.  This size\n# was determined using contrib/libtests/timepng.c with compressed zTXt data\n# around 11MByte in size.  Slight speed improvements (up to about 14% in\n# timepng) can be achieved by very large increases (to 32kbyte) on regular data,\n# but highly compressible data shows only around 2% improvement.   The size is\n# chosen to minimize the effects of DoS attacks based on using very large\n# amounts of highly compressible data.\n\nsetting INFLATE_BUF_SIZE default 1024\n\n# This is the maximum amount of IDAT data that the sequential reader will\n# process at one time.  The setting does not affect the size of IDAT chunks\n# read, just the amount read at once.  Neither does it affect the progressive\n# reader, which processes just the amount of data the application gives it.\n# The sequential reader is currently unable to process more than one IDAT at\n# once - it has to read and process each one in turn.  There is no point setting\n# this to a value larger than the IDAT chunks typically encountered (it would\n# just waste memory) but there may be some point in reducing it below the value\n# of ZBUF_SIZE (the size of IDAT chunks written by libpng.)\n\nsetting IDAT_READ_SIZE default PNG_ZBUF_SIZE\n\n# Ancillary chunks\nchunk bKGD\nchunk cHRM enables COLORSPACE\nchunk gAMA enables GAMMA\nchunk hIST\nchunk iCCP enables COLORSPACE, GAMMA\nchunk iTXt enables TEXT\nchunk oFFs\nchunk pCAL\nchunk pHYs\nchunk sBIT\nchunk sCAL\nchunk sPLT\nchunk sRGB enables COLORSPACE, GAMMA, SET_OPTION\nchunk tEXt requires TEXT\nchunk tIME\nchunk tRNS\nchunk zTXt enables TEXT\n\n# This only affects support of the optional PLTE chunk in RGB and RGBA\n# images.  Notice that READ_ANCILLARY_CHUNKS therefore disables part\n# of the regular chunk reading too.\n\noption READ_OPT_PLTE requires READ_ANCILLARY_CHUNKS\n\n# Unknown chunk handling\n#\n# 'UNKNOWN_CHUNKS' is a global option to disable all unknown chunk handling on\n# read or write; everything else below requires it (directly or indirectly).\noption UNKNOWN_CHUNKS\n\n# There are three main options to control the ability to read and write unknown\n# chunks.  If either read option is turned on then unknown chunks will be read,\n# otherwise they are skipped.  If the write option is turned on unknown chunks\n# set by png_set_unknown_chunks will be written otherwise it is an error to call\n# that API on a write struct.\noption WRITE_UNKNOWN_CHUNKS requires WRITE requires UNKNOWN_CHUNKS\noption WRITE_UNKNOWN_CHUNKS enables STORE_UNKNOWN_CHUNKS\n\n# The first way to read user chunks is to have libpng save them for a later call\n# to png_get_unknown_chunks, the application must call\n# png_set_keep_unknown_chunks to cause this to actually happen (see png.h)\noption SAVE_UNKNOWN_CHUNKS requires READ requires SET_UNKNOWN_CHUNKS\noption SAVE_UNKNOWN_CHUNKS enables READ_UNKNOWN_CHUNKS, STORE_UNKNOWN_CHUNKS\n\n# The second approach is to use an application provided callback to process the\n# chunks, the callback can either handle the chunk entirely itself or request\n# that libpng store the chunk for later retrieval via png_get_unknown_chunks.\n#\n# NOTE: If STORE_UNKNOWN_CHUNKS is not enabled (which is the default if\n# both SAVE_UNKNOWN_CHUNKS and WRITE_UNKNOWN_CHUNKS are disabled) then a\n# 0 result from the callback will be ignored because no support for saving\n# unknown chunks has been compiled in.  The normal symptom is that your app\n# fails to compile because png_get_unknown_chunks is no longer defined in png.h.\n# If you encounter this issue simply enable STORE_UNKNOWN_CHUNKS in your build.\n#\n# Note that there is no 'WRITE_USER_CHUNKS' so the USER_CHUNKS option is always\n# the same as READ_USER_CHUNKS at present\noption READ_USER_CHUNKS requires READ, UNKNOWN_CHUNKS\noption READ_USER_CHUNKS enables READ_UNKNOWN_CHUNKS, USER_CHUNKS\n\n# Two further options are provided to allow detailed control of the handling.\n# The first enables png_set_keep_unknown_chunks; this allows the default to be\n# changed from discarding unknown chunks and allows per-chunk control.  This is\n# required to use the SAVE_UNKNOWN_CHUNKS option.  If enabled this option also\n# applies to write (see png.h), otherwise the write API simply writes all the\n# chunks it is given.\n#\n# The second option extends the unknown handling to allow known chunks to be\n# handled as though they were unknown.  This option doesn't change any APIs, it\n# merely turns on the code to check known as well as unknown chunks.\n#\n# This option no longer affects the write code.  It can be safely disabled and\n# will prevent applications stopping libpng reading known chunks.\noption SET_UNKNOWN_CHUNKS requires UNKNOWN_CHUNKS\noption HANDLE_AS_UNKNOWN requires SET_UNKNOWN_CHUNKS\n\n# The following options are derived from the above and should not be turned on\n# explicitly.\noption READ_UNKNOWN_CHUNKS requires UNKNOWN_CHUNKS disabled\noption STORE_UNKNOWN_CHUNKS requires UNKNOWN_CHUNKS disabled\n\noption CONVERT_tIME requires WRITE_ANCILLARY_CHUNKS\n# The \"tm\" structure is not supported on WindowsCE\n\n@#ifdef _WIN32_WCE\n@#   define PNG_NO_CONVERT_tIME\n@#endif\n\noption WRITE_FILTER requires WRITE\n\noption SAVE_INT_32 disabled\n# png_save_int_32 is required internally for writing the ancillary chunks oFFs\n# and pCAL and for both reading and writing iCCP (for the generation/checking of\n# the corresponding cHRM/gAMA chunks) if full ICC is supported.\n\n# added at libpng-1.5.4\n\noption WRITE_OPTIMIZE_CMF requires WRITE\n\noption READ_COMPRESSED_TEXT disabled\noption READ_iCCP enables READ_COMPRESSED_TEXT\noption READ_iTXt enables READ_COMPRESSED_TEXT\noption READ_zTXt enables READ_COMPRESSED_TEXT\n\noption WRITE_oFFs enables SAVE_INT_32\noption WRITE_pCAL enables SAVE_INT_32\noption WRITE_cHRM enables SAVE_INT_32\n\noption WRITE_COMPRESSED_TEXT disabled\noption WRITE_iCCP enables WRITE_COMPRESSED_TEXT\noption WRITE_iTXt enables WRITE_COMPRESSED_TEXT\noption WRITE_zTXt enables WRITE_COMPRESSED_TEXT\n\n# Turn this off to disable png_read_png() and png_write_png() and\n# leave the row_pointers member out of the info structure.\n\noption INFO_IMAGE\n\n# added at libpng-1.5.10\n# Turn this off to disable warning about invalid palette index and\n# leave the num_palette_max member out of the png structure.\n\noption CHECK_FOR_INVALID_INDEX enables READ_CHECK_FOR_INVALID_INDEX\noption CHECK_FOR_INVALID_INDEX enables WRITE_CHECK_FOR_INVALID_INDEX\noption READ_CHECK_FOR_INVALID_INDEX requires READ, CHECK_FOR_INVALID_INDEX\noption WRITE_CHECK_FOR_INVALID_INDEX requires WRITE, CHECK_FOR_INVALID_INDEX\n\n# added at libpng-1.5.15\noption GET_PALETTE_MAX enables READ_GET_PALETTE_MAX WRITE_GET_PALETTE_MAX\noption READ_GET_PALETTE_MAX requires READ_CHECK_FOR_INVALID_INDEX disabled\noption WRITE_GET_PALETTE_MAX requires WRITE_CHECK_FOR_INVALID_INDEX disabled\n\n# Simplified API options (added at libpng-1.6.0)\n#  In libpng 1.6.8 the handling of these options was changed to used 'requires'\n#  throughout, so that disabling some of the low level support always disables\n#  the base simplified read/write API.  This much simplifies the handling and\n#  makes 'everything = off' work in a more intuitive way.  It eliminates a\n#  previously reported feature that APIs previously enabled by the simplified\n#  API couldn't be turned off without explicitly turning off the simplified\n#  APIs.\n#\n# Read:\noption SIMPLIFIED_READ,\n   requires SEQUENTIAL_READ, READ_TRANSFORMS, SETJMP, BENIGN_ERRORS,\n      READ_EXPAND, READ_16BIT, READ_EXPAND_16, READ_SCALE_16_TO_8,\n      READ_RGB_TO_GRAY, READ_ALPHA_MODE, READ_BACKGROUND, READ_STRIP_ALPHA,\n      READ_FILLER, READ_SWAP, READ_PACK, READ_GRAY_TO_RGB, READ_GAMMA,\n      READ_tRNS, READ_bKGD, READ_gAMA, READ_cHRM, READ_sRGB, READ_sBIT\n\n# AFIRST and BGR read options:\n#  Prior to libpng 1.6.8 these were disabled but switched on if the low level\n#  libpng routines that do the swaps were enabled.  This worked but was\n#  confusing.  In libpng 1.6.8 the options were changed to simple 'requires'\n#  and are enabled by default.  This should work the same way in practice.\noption SIMPLIFIED_READ_AFIRST enables FORMAT_AFIRST,\n   requires SIMPLIFIED_READ READ_SWAP_ALPHA\n\noption SIMPLIFIED_READ_BGR enables FORMAT_BGR,\n   requires SIMPLIFIED_READ READ_BGR\n\n# Write:\noption SIMPLIFIED_WRITE,\n   requires WRITE, SETJMP, WRITE_SWAP, WRITE_PACK,\n      WRITE_tRNS, WRITE_gAMA, WRITE_sRGB, WRITE_cHRM\n\n# 1.6.22: allow simplified write without stdio support:\noption SIMPLIFIED_WRITE_STDIO requires SIMPLIFIED_WRITE STDIO\n\noption SIMPLIFIED_WRITE_AFIRST enables FORMAT_AFIRST,\n   requires SIMPLIFIED_WRITE WRITE_SWAP_ALPHA\n\noption SIMPLIFIED_WRITE_BGR enables FORMAT_BGR,\n   requires SIMPLIFIED_WRITE WRITE_BGR\n\n# Formats:\noption FORMAT_AFIRST disabled\noption FORMAT_BGR disabled\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/pnglibconf.h.prebuilt",
    "content": "/* libpng 1.6.22beta03 STANDARD API DEFINITION */\n\n/* pnglibconf.h - library build configuration */\n\n/* Libpng version 1.6.22beta03 - February 8, 2016 */\n\n/* Copyright (c) 1998-2015 Glenn Randers-Pehrson */\n\n/* This code is released under the libpng license. */\n/* For conditions of distribution and use, see the disclaimer */\n/* and license in png.h */\n\n/* pnglibconf.h */\n/* Machine generated file: DO NOT EDIT */\n/* Derived from: scripts/pnglibconf.dfa */\n#ifndef PNGLCONF_H\n#define PNGLCONF_H\n/* options */\n#define PNG_16BIT_SUPPORTED\n#define PNG_ALIGNED_MEMORY_SUPPORTED\n/*#undef PNG_ARM_NEON_API_SUPPORTED*/\n/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/\n#define PNG_BENIGN_ERRORS_SUPPORTED\n#define PNG_BENIGN_READ_ERRORS_SUPPORTED\n/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/\n#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED\n#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED\n#define PNG_COLORSPACE_SUPPORTED\n#define PNG_CONSOLE_IO_SUPPORTED\n#define PNG_CONVERT_tIME_SUPPORTED\n#define PNG_EASY_ACCESS_SUPPORTED\n/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/\n#define PNG_ERROR_TEXT_SUPPORTED\n#define PNG_FIXED_POINT_SUPPORTED\n#define PNG_FLOATING_ARITHMETIC_SUPPORTED\n#define PNG_FLOATING_POINT_SUPPORTED\n#define PNG_FORMAT_AFIRST_SUPPORTED\n#define PNG_FORMAT_BGR_SUPPORTED\n#define PNG_GAMMA_SUPPORTED\n#define PNG_GET_PALETTE_MAX_SUPPORTED\n#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED\n#define PNG_INCH_CONVERSIONS_SUPPORTED\n#define PNG_INFO_IMAGE_SUPPORTED\n#define PNG_IO_STATE_SUPPORTED\n#define PNG_MNG_FEATURES_SUPPORTED\n#define PNG_POINTER_INDEXING_SUPPORTED\n#define PNG_PROGRESSIVE_READ_SUPPORTED\n#define PNG_READ_16BIT_SUPPORTED\n#define PNG_READ_ALPHA_MODE_SUPPORTED\n#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED\n#define PNG_READ_BACKGROUND_SUPPORTED\n#define PNG_READ_BGR_SUPPORTED\n#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED\n#define PNG_READ_COMPOSITE_NODIV_SUPPORTED\n#define PNG_READ_COMPRESSED_TEXT_SUPPORTED\n#define PNG_READ_EXPAND_16_SUPPORTED\n#define PNG_READ_EXPAND_SUPPORTED\n#define PNG_READ_FILLER_SUPPORTED\n#define PNG_READ_GAMMA_SUPPORTED\n#define PNG_READ_GET_PALETTE_MAX_SUPPORTED\n#define PNG_READ_GRAY_TO_RGB_SUPPORTED\n#define PNG_READ_INTERLACING_SUPPORTED\n#define PNG_READ_INT_FUNCTIONS_SUPPORTED\n#define PNG_READ_INVERT_ALPHA_SUPPORTED\n#define PNG_READ_INVERT_SUPPORTED\n#define PNG_READ_OPT_PLTE_SUPPORTED\n#define PNG_READ_PACKSWAP_SUPPORTED\n#define PNG_READ_PACK_SUPPORTED\n#define PNG_READ_QUANTIZE_SUPPORTED\n#define PNG_READ_RGB_TO_GRAY_SUPPORTED\n#define PNG_READ_SCALE_16_TO_8_SUPPORTED\n#define PNG_READ_SHIFT_SUPPORTED\n#define PNG_READ_STRIP_16_TO_8_SUPPORTED\n#define PNG_READ_STRIP_ALPHA_SUPPORTED\n#define PNG_READ_SUPPORTED\n#define PNG_READ_SWAP_ALPHA_SUPPORTED\n#define PNG_READ_SWAP_SUPPORTED\n#define PNG_READ_TEXT_SUPPORTED\n#define PNG_READ_TRANSFORMS_SUPPORTED\n#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED\n#define PNG_READ_USER_CHUNKS_SUPPORTED\n#define PNG_READ_USER_TRANSFORM_SUPPORTED\n#define PNG_READ_bKGD_SUPPORTED\n#define PNG_READ_cHRM_SUPPORTED\n#define PNG_READ_gAMA_SUPPORTED\n#define PNG_READ_hIST_SUPPORTED\n#define PNG_READ_iCCP_SUPPORTED\n#define PNG_READ_iTXt_SUPPORTED\n#define PNG_READ_oFFs_SUPPORTED\n#define PNG_READ_pCAL_SUPPORTED\n#define PNG_READ_pHYs_SUPPORTED\n#define PNG_READ_sBIT_SUPPORTED\n#define PNG_READ_sCAL_SUPPORTED\n#define PNG_READ_sPLT_SUPPORTED\n#define PNG_READ_sRGB_SUPPORTED\n#define PNG_READ_tEXt_SUPPORTED\n#define PNG_READ_tIME_SUPPORTED\n#define PNG_READ_tRNS_SUPPORTED\n#define PNG_READ_zTXt_SUPPORTED\n#define PNG_SAVE_INT_32_SUPPORTED\n#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED\n#define PNG_SEQUENTIAL_READ_SUPPORTED\n#define PNG_SETJMP_SUPPORTED\n#define PNG_SET_OPTION_SUPPORTED\n#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED\n#define PNG_SET_USER_LIMITS_SUPPORTED\n#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED\n#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED\n#define PNG_SIMPLIFIED_READ_SUPPORTED\n#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED\n#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED\n#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED\n#define PNG_SIMPLIFIED_WRITE_SUPPORTED\n#define PNG_STDIO_SUPPORTED\n#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED\n#define PNG_TEXT_SUPPORTED\n#define PNG_TIME_RFC1123_SUPPORTED\n#define PNG_UNKNOWN_CHUNKS_SUPPORTED\n#define PNG_USER_CHUNKS_SUPPORTED\n#define PNG_USER_LIMITS_SUPPORTED\n#define PNG_USER_MEM_SUPPORTED\n#define PNG_USER_TRANSFORM_INFO_SUPPORTED\n#define PNG_USER_TRANSFORM_PTR_SUPPORTED\n#define PNG_WARNINGS_SUPPORTED\n#define PNG_WRITE_16BIT_SUPPORTED\n#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED\n#define PNG_WRITE_BGR_SUPPORTED\n#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED\n#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED\n#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED\n#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED\n#define PNG_WRITE_FILLER_SUPPORTED\n#define PNG_WRITE_FILTER_SUPPORTED\n#define PNG_WRITE_FLUSH_SUPPORTED\n#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED\n#define PNG_WRITE_INTERLACING_SUPPORTED\n#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED\n#define PNG_WRITE_INVERT_ALPHA_SUPPORTED\n#define PNG_WRITE_INVERT_SUPPORTED\n#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED\n#define PNG_WRITE_PACKSWAP_SUPPORTED\n#define PNG_WRITE_PACK_SUPPORTED\n#define PNG_WRITE_SHIFT_SUPPORTED\n#define PNG_WRITE_SUPPORTED\n#define PNG_WRITE_SWAP_ALPHA_SUPPORTED\n#define PNG_WRITE_SWAP_SUPPORTED\n#define PNG_WRITE_TEXT_SUPPORTED\n#define PNG_WRITE_TRANSFORMS_SUPPORTED\n#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED\n#define PNG_WRITE_USER_TRANSFORM_SUPPORTED\n#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED\n#define PNG_WRITE_bKGD_SUPPORTED\n#define PNG_WRITE_cHRM_SUPPORTED\n#define PNG_WRITE_gAMA_SUPPORTED\n#define PNG_WRITE_hIST_SUPPORTED\n#define PNG_WRITE_iCCP_SUPPORTED\n#define PNG_WRITE_iTXt_SUPPORTED\n#define PNG_WRITE_oFFs_SUPPORTED\n#define PNG_WRITE_pCAL_SUPPORTED\n#define PNG_WRITE_pHYs_SUPPORTED\n#define PNG_WRITE_sBIT_SUPPORTED\n#define PNG_WRITE_sCAL_SUPPORTED\n#define PNG_WRITE_sPLT_SUPPORTED\n#define PNG_WRITE_sRGB_SUPPORTED\n#define PNG_WRITE_tEXt_SUPPORTED\n#define PNG_WRITE_tIME_SUPPORTED\n#define PNG_WRITE_tRNS_SUPPORTED\n#define PNG_WRITE_zTXt_SUPPORTED\n#define PNG_bKGD_SUPPORTED\n#define PNG_cHRM_SUPPORTED\n#define PNG_gAMA_SUPPORTED\n#define PNG_hIST_SUPPORTED\n#define PNG_iCCP_SUPPORTED\n#define PNG_iTXt_SUPPORTED\n#define PNG_oFFs_SUPPORTED\n#define PNG_pCAL_SUPPORTED\n#define PNG_pHYs_SUPPORTED\n#define PNG_sBIT_SUPPORTED\n#define PNG_sCAL_SUPPORTED\n#define PNG_sPLT_SUPPORTED\n#define PNG_sRGB_SUPPORTED\n#define PNG_tEXt_SUPPORTED\n#define PNG_tIME_SUPPORTED\n#define PNG_tRNS_SUPPORTED\n#define PNG_zTXt_SUPPORTED\n/* end of options */\n/* settings */\n#define PNG_API_RULE 0\n#define PNG_DEFAULT_READ_MACROS 1\n#define PNG_GAMMA_THRESHOLD_FIXED 5000\n#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE\n#define PNG_INFLATE_BUF_SIZE 1024\n#define PNG_LINKAGE_API extern\n#define PNG_LINKAGE_CALLBACK extern\n#define PNG_LINKAGE_DATA extern\n#define PNG_LINKAGE_FUNCTION extern\n#define PNG_MAX_GAMMA_8 11\n#define PNG_QUANTIZE_BLUE_BITS 5\n#define PNG_QUANTIZE_GREEN_BITS 5\n#define PNG_QUANTIZE_RED_BITS 5\n#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)\n#define PNG_TEXT_Z_DEFAULT_STRATEGY 0\n#define PNG_USER_CHUNK_CACHE_MAX 1000\n#define PNG_USER_CHUNK_MALLOC_MAX 8000000\n#define PNG_USER_HEIGHT_MAX 1000000\n#define PNG_USER_WIDTH_MAX 1000000\n#define PNG_ZBUF_SIZE 8192\n#define PNG_ZLIB_VERNUM 0 /* unknown */\n#define PNG_Z_DEFAULT_COMPRESSION (-1)\n#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0\n#define PNG_Z_DEFAULT_STRATEGY 1\n#define PNG_sCAL_PRECISION 5\n#define PNG_sRGB_PROFILE_CHECKS 2\n/* end of settings */\n#endif /* PNGLCONF_H */\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/pnglibconf.mak",
    "content": "#!/usr/bin/make -f\n# pnglibconf.mak - standard make lines for pnglibconf.h\n#\n# These lines are copied from Makefile.am, they illustrate\n# how to automate the build of pnglibconf.h from scripts/pnglibconf.dfa\n# given just 'awk', a C preprocessor and standard command line utilities\n\n# Override as appropriate, these definitions can be overridden on\n# the make command line (AWK='nawk' for example).\nAWK = gawk\nAWK = mawk\nAWK = nawk\nAWK = one-true-awk\nAWK = awk  # Crashes on SunOS 5.10 - use 'nawk'\nCPP = $(CC) -E # On SUN OS 5.10 if this causes problems use /lib/cpp\n\nMOVE = mv\nDELETE = rm -f\nECHO = echo\nDFA_XTRA = # Put your configuration file here, see scripts/pnglibconf.dfa.  Eg:\n# DFA_XTRA = pngusr.dfa\n\n# CPPFLAGS should contain the options to control the result,\n# but DEFS and CFLAGS are also supported here, override\n# as appropriate\nDFNFLAGS = $(DEFS) $(CPPFLAGS) $(CFLAGS)\n\n# srcdir is a defacto standard for the location of the source\nsrcdir = .\n\n# The standard pnglibconf.h exists as scripts/pnglibconf.h.prebuilt,\n# copy this if the following doesn't work.\npnglibconf.h: pnglibconf.dfn\n\t$(DELETE) $@ pnglibconf.c pnglibconf.out pnglibconf.tmp\n\t$(ECHO) '#include \"pnglibconf.dfn\"' >pnglibconf.c\n\t$(ECHO) \"If '$(CC) -E' crashes try /lib/cpp (e.g. CPP='/lib/cpp')\" >&2\n\t$(CPP) $(DFNFLAGS) pnglibconf.c >pnglibconf.out\n\t$(AWK) -f \"$(srcdir)/scripts/dfn.awk\" out=\"pnglibconf.tmp\" pnglibconf.out 1>&2\n\t$(MOVE) pnglibconf.tmp $@\n\npnglibconf.dfn: $(srcdir)/scripts/pnglibconf.dfa $(srcdir)/scripts/options.awk $(srcdir)/pngconf.h $(srcdir)/pngusr.dfa $(DFA_XTRA)\n\t$(DELETE) $@ pnglibconf.pre pnglibconf.tmp\n\t$(ECHO) \"Calling $(AWK) from scripts/pnglibconf.mak\" >&2\n\t$(ECHO) \"If 'awk' crashes try a better awk (e.g. AWK='nawk')\" >&2\n\t$(AWK) -f $(srcdir)/scripts/options.awk out=\"pnglibconf.pre\"\\\n\t    version=search $(srcdir)/pngconf.h $(srcdir)/scripts/pnglibconf.dfa\\\n\t    $(srcdir)/pngusr.dfa $(DFA_XTRA) 1>&2\n\t$(AWK) -f $(srcdir)/scripts/options.awk out=\"pnglibconf.tmp\" pnglibconf.pre 1>&2\n\t$(MOVE) pnglibconf.tmp $@\n\nclean-pnglibconf:\n\t$(DELETE) pnglibconf.h pnglibconf.c pnglibconf.out pnglibconf.pre \\\n\tpnglibconf.dfn\n\nclean: clean-pnglibconf\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/pngwin.rc",
    "content": "#define PNG_VERSION_INFO_ONLY\n\n#include <windows.h>\n#include \"../png.h\"\n\n#define _QUOTE(x) # x\n#define QUOTE(x) _QUOTE(x)\n\n#define PNG_LIBPNG_DLLFNAME \"LIBPNG\"\n\n/* Support deprecated PRIVATEBUILD macro */\n#if defined(PRIVATEBUILD) && !defined(PNG_USER_PRIVATEBUILD)\n#  define PNG_USER_PRIVATEBUILD PRIVATEBUILD\n#endif\n\n#if defined(PNG_USER_DLLFNAME_POSTFIX) && !defined(PNG_USER_PRIVATEBUILD)\n#  error \"PNG_USER_PRIVATEBUILD must be defined as a string describing the\\\n custom changes made to the library.\"\n#endif\n\n/* Prioritize PNG_USER_x over PNG_LIBPNG_x */\n#ifdef PNG_USER_DLLFNAME_POSTFIX\n#  undef PNG_LIBPNG_DLLFNAME_POSTFIX\n#  define PNG_LIBPNG_DLLFNAME_POSTFIX PNG_USER_DLLFNAME_POSTFIX\n#endif\n\n#ifdef PNG_USER_VERSIONINFO_COMMENTS\n#  undef PNG_LIBPNG_VERSIONINFO_COMMENTS\n#  define PNG_LIBPNG_VERSIONINFO_COMMENTS PNG_USER_VERSIONINFO_COMMENTS\n#endif\n\n#if defined(PNG_DEBUG) && (PNG_DEBUG > 0)\n#  define VS_DEBUG VS_FF_DEBUG\n#  ifndef PNG_LIBPNG_DLLFNAME_POSTFIX\n#    define PNG_LIBPNG_DLLFNAME_POSTFIX \"D\"\n#  endif /* PNG_LIBPNG_DLLFNAME_POSTFIX */\n#  ifndef PNG_LIBPNG_VERSIONINFO_COMMENTS\n#    define PNG_LIBPNG_VERSIONINFO_COMMENTS \"PNG_DEBUG=\" QUOTE(PNG_DEBUG)\n#  endif /* PNG_LIBPNG_VERSIONINFO_COMMENTS */\n#else\n#  define VS_DEBUG 0\n#  ifndef PNG_LIBPNG_DLLFNAME_POSTFIX\n#     define PNG_LIBPNG_DLLFNAME_POSTFIX\n#  endif /* PNG_LIBPNG_DLLFNAME_POSTFIX */\n#endif /* defined(DEBUG)... */\n\n#ifdef PNG_USER_PRIVATEBUILD\n#  define VS_PRIVATEBUILD VS_FF_PRIVATEBUILD\n#else\n#  define VS_PRIVATEBUILD 0\n#endif /* PNG_USER_PRIVATEBUILD */\n\n#ifdef PNG_LIBPNG_SPECIALBUILD\n#  define VS_SPECIALBUILD VS_FF_SPECIALBUILD\n#else\n#  define VS_SPECIALBUILD 0\n#endif /* PNG_LIBPNG_BUILD_SPECIAL */\n\n#if ((PNG_LIBPNG_BUILD_BASE_TYPE & PNG_LIBPNG_RELEASE_STATUS_MASK) !=\\\n      PNG_LIBPNG_BUILD_STABLE)\n#  define VS_PRERELEASE VS_FF_PRERELEASE\n#  define VS_PATCHED 0\n#else\n#  define VS_PRERELEASE 0\n#  if (PNG_LIBPNG_BUILD_BASE_TYPE & PNG_LIBPNG_BUILD_PATCHED)\n#    define VS_PATCHED VS_FF_PATCHED\n#  else\n#    define VS_PATCHED 0\n#  endif\n#endif\n\nVS_VERSION_INFO VERSIONINFO\nFILEVERSION PNG_LIBPNG_VER_MAJOR, PNG_LIBPNG_VER_MINOR, PNG_LIBPNG_VER_RELEASE, PNG_LIBPNG_VER_BUILD\nPRODUCTVERSION PNG_LIBPNG_VER_MAJOR, PNG_LIBPNG_VER_MINOR, PNG_LIBPNG_VER_RELEASE, PNG_LIBPNG_VER_BUILD\nFILEFLAGSMASK VS_FFI_FILEFLAGSMASK\nFILEFLAGS VS_DEBUG | VS_PRIVATEBUILD | VS_SPECIALBUILD | VS_PRERELEASE | VS_PATCHED\nFILEOS VOS__WINDOWS32\nFILETYPE VFT_DLL\nFILESUBTYPE VFT2_UNKNOWN\nBEGIN\n  BLOCK \"StringFileInfo\"\n  BEGIN BLOCK \"040904E4\" /* Language type = U.S English(0x0409) and Character Set = Windows, Multilingual(0x04E4) */\n    BEGIN\n#ifdef PNG_LIBPNG_VERSIONINFO_COMMENTS\n      VALUE \"Comments\", PNG_LIBPNG_VERSIONINFO_COMMENTS \"\\000\"\n#endif /* PNG_LIBPNG_VERSIONINFO_COMMENTS */\n#ifdef PNG_USER_VERSIONINFO_COMPANYNAME\n      VALUE \"CompanyName\", PNG_USER_VERSIONINFO_COMPANYNAME \"\\000\"\n#endif /* PNG_USER_VERSIONINFO_COMPANYNAME */\n      VALUE \"FileDescription\", \"PNG image compression library\\000\"\n      VALUE \"FileVersion\", PNG_LIBPNG_VER_STRING \"\\000\"\n      VALUE \"InternalName\", PNG_LIBPNG_DLLFNAME QUOTE(PNG_LIBPNG_VER_DLLNUM) PNG_LIBPNG_DLLFNAME_POSTFIX \" (Windows 32 bit)\\000\"\n      VALUE \"LegalCopyright\", \"\\251 1998-2009 Glenn Randers-Pehrson et al.\\000\"\n#ifdef PNG_USER_VERSIONINFO_LEGALTRADEMARKS\n      VALUE \"LegalTrademarks\", PNG_USER_VERSIONINFO_LEGALTRADEMARKS \"\\000\"\n#endif /* PNG_USER_VERSIONINFO_LEGALTRADEMARKS */\n      VALUE \"OriginalFilename\", PNG_LIBPNG_DLLFNAME QUOTE(PNG_LIBPNG_VER_DLLNUM) PNG_LIBPNG_DLLFNAME_POSTFIX \".DLL\\000\"\n#ifdef PNG_USER_PRIVATEBUILD\n      VALUE \"PrivateBuild\", PNG_USER_PRIVATEBUILD \"\\000\"\n#endif /* PNG_USER_PRIVATEBUILD */\n      VALUE \"ProductName\", \"LibPNG\\000\"\n      VALUE \"ProductVersion\", \"1\\000\"\n#ifdef PNG_LIBPNG_SPECIALBUILD\n      VALUE \"SpecialBuild\", PNG_LIBPNG_SPECIALBUILD \"\\000\"\n#endif /* PNG_LIBPNG_SPECIALBUILD */\n    END\n  END\n  BLOCK \"VarFileInfo\"\n  BEGIN\n    VALUE \"Translation\", 0x0409, 0x04E4\n  END\nEND\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/prefix.c",
    "content": "\n/* prefix.c - generate an unprefixed symbol list\n *\n * Last changed in libpng version 1.6.16 [December 22, 2014]\n * Copyright (c) 2013-2014 Glenn Randers-Pehrson\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n#define PNG_EXPORTA(ordinal, type, name, args, attributes)\\\n        PNG_DFN \"@\" name \"@\"\n\n/* The configuration information *before* the additional of symbol renames,\n * the list is the C name list; no symbol prefix.\n */\n#include \"pnglibconf.out\"\n\nPNG_DFN_START_SORT 1\n\n#include \"../png.h\"\n\nPNG_DFN_END_SORT\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/smakefile.ppc",
    "content": "# Amiga powerUP (TM) Makefile\n# makefile for libpng and SAS C V6.58/7.00 PPC compiler\n# Copyright (C) 1998 by Andreas R. Kleinert\n#\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\nCC       = scppc\nCFLAGS   = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL IDIR /zlib \\\n           OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8\nLIBNAME  = libpng.a\nAR       = ppc-amigaos-ar\nAR_FLAGS = cr\nRANLIB   = ppc-amigaos-ranlib\nLDFLAGS  = -r -o\nLDLIBS   =  ../zlib/libzip.a LIB:scppc.a\nLN       = ppc-amigaos-ld\nRM       = delete quiet\nMKDIR    = makedir\n\nOBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o pngread.o \\\n       pngerror.o pngpread.o pngwrite.o pngrtran.o pngwtran.o pngrio.o \\\n       pngwio.o pngmem.o\n\nall: $(LIBNAME) pngtest\n\n$(LIBNAME): $(OBJS)\n            $(AR) $(AR_FLAGS) $@ $(OBJS)\n            $(RANLIB) $@\n\npngtest: pngtest.o $(LIBNAME)\n        $(LN) $(LDFLAGS) pngtest LIB:c_ppc.o pngtest.o $(LIBNAME) $(LDLIBS) \\\nLIB:end.o\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/sym.c",
    "content": "\n/* sym.c - define format of libpng.sym\n *\n * Last changed in libpng version 1.6.16 [December 22, 2014]\n * Copyright (c) 2011-2014 Glenn Randers-Pehrson\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n#define PNG_EXPORTA(ordinal, type, name, args, attributes)\\\n        PNG_DFN \"@\" SYMBOL_PREFIX \"@@\" name \"@\"\n\n#include \"../png.h\"\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/symbols.c",
    "content": "\n/* symbols.c - find all exported symbols\n *\n * Last changed in libpng version 1.6.16 [December 22, 2014]\n * Copyright (c) 2011-2014 Glenn Randers-Pehrson\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n/* NOTE: making 'symbols.chk' checks both that the exported\n * symbols in the library don't change and (implicitly) that\n * scripts/pnglibconf.h.prebuilt is as expected.\n * If scripts/pnglibconf.h.prebuilt is remade using\n * scripts/pnglibconf.dfa then this checks the .dfa file too.\n */\n\n#define PNG_EXPORTA(ordinal, type, name, args, attributes)\\\n        PNG_DFN \"@\" name \"@ @@\" ordinal \"@\"\n#define PNG_REMOVED(ordinal, type, name, args, attributes)\\\n        PNG_DFN \"; @\" name \"@ @@\" ordinal \"@\"\n#define PNG_EXPORT_LAST_ORDINAL(ordinal)\\\n        PNG_DFN \"; @@\" ordinal \"@\"\n\n/* Read the defaults, but use scripts/pnglibconf.h.prebuilt; the 'standard'\n * header file.\n */\n#include \"pnglibconf.h.prebuilt\"\n#include \"../png.h\"\n\n/* Some things are turned off by default.  Turn these things\n * on here (by hand) to get the APIs they expose and validate\n * that no harm is done.  This list is the set of options\n * defaulted to 'off' in scripts/pnglibconf.dfa\n *\n * Maintenance: if scripts/pnglibconf.dfa options are changed\n * from, or to, 'disabled' this needs updating!\n */\n#define PNG_BENIGN_ERRORS_SUPPORTED\n#define PNG_ERROR_NUMBERS_SUPPORTED\n#define PNG_READ_BIG_ENDIAN_SUPPORTED  /* should do nothing! */\n#define PNG_INCH_CONVERSIONS_SUPPORTED\n#define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED\n#define PNG_SET_OPTION_SUPPORTED\n\n#undef PNG_H\n#include \"../png.h\"\n\n/* Finally there are a couple of places where option support\n * actually changes the APIs revealed using a #if/#else/#endif\n * test in png.h, test these here.\n */\n#undef  PNG_FLOATING_POINT_SUPPORTED /* Exposes 'fixed' APIs */\n#undef  PNG_ERROR_TEXT_SUPPORTED     /* Exposes unsupported APIs */\n\n#undef PNG_H\n#include \"../png.h\"\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/symbols.def",
    "content": ";Version 1.6.22beta03\n;--------------------------------------------------------------\n; LIBPNG symbol list as a Win32 DEF file\n; Contains all the symbols that can be exported from libpng\n;--------------------------------------------------------------\nLIBRARY\n\nEXPORTS\n png_access_version_number @1\n png_set_sig_bytes @2\n png_sig_cmp @3\n png_create_read_struct @4\n png_create_write_struct @5\n png_get_compression_buffer_size @6\n png_set_compression_buffer_size @7\n png_set_longjmp_fn @8\n png_longjmp @9\n png_reset_zstream @10\n png_create_read_struct_2 @11\n png_create_write_struct_2 @12\n png_write_sig @13\n png_write_chunk @14\n png_write_chunk_start @15\n png_write_chunk_data @16\n png_write_chunk_end @17\n png_create_info_struct @18\n png_info_init_3 @19\n png_write_info_before_PLTE @20\n png_write_info @21\n png_read_info @22\n png_convert_to_rfc1123 @23\n png_convert_from_struct_tm @24\n png_convert_from_time_t @25\n png_set_expand @26\n png_set_expand_gray_1_2_4_to_8 @27\n png_set_palette_to_rgb @28\n png_set_tRNS_to_alpha @29\n png_set_bgr @30\n png_set_gray_to_rgb @31\n png_set_rgb_to_gray @32\n png_set_rgb_to_gray_fixed @33\n png_get_rgb_to_gray_status @34\n png_build_grayscale_palette @35\n png_set_strip_alpha @36\n png_set_swap_alpha @37\n png_set_invert_alpha @38\n png_set_filler @39\n png_set_add_alpha @40\n png_set_swap @41\n png_set_packing @42\n png_set_packswap @43\n png_set_shift @44\n png_set_interlace_handling @45\n png_set_invert_mono @46\n png_set_background @47\n png_set_strip_16 @48\n png_set_quantize @49\n png_set_gamma @50\n png_set_flush @51\n png_write_flush @52\n png_start_read_image @53\n png_read_update_info @54\n png_read_rows @55\n png_read_row @56\n png_read_image @57\n png_write_row @58\n png_write_rows @59\n png_write_image @60\n png_write_end @61\n png_read_end @62\n png_destroy_info_struct @63\n png_destroy_read_struct @64\n png_destroy_write_struct @65\n png_set_crc_action @66\n png_set_filter @67\n png_set_filter_heuristics @68\n png_set_compression_level @69\n png_set_compression_mem_level @70\n png_set_compression_strategy @71\n png_set_compression_window_bits @72\n png_set_compression_method @73\n png_init_io @74\n png_set_error_fn @75\n png_get_error_ptr @76\n png_set_write_fn @77\n png_set_read_fn @78\n png_get_io_ptr @79\n png_set_read_status_fn @80\n png_set_write_status_fn @81\n png_set_mem_fn @82\n png_get_mem_ptr @83\n png_set_read_user_transform_fn @84\n png_set_write_user_transform_fn @85\n png_set_user_transform_info @86\n png_get_user_transform_ptr @87\n png_set_read_user_chunk_fn @88\n png_get_user_chunk_ptr @89\n png_set_progressive_read_fn @90\n png_get_progressive_ptr @91\n png_process_data @92\n png_progressive_combine_row @93\n png_malloc @94\n png_calloc @95\n png_malloc_warn @96\n png_free @97\n png_free_data @98\n png_data_freer @99\n png_malloc_default @100\n png_free_default @101\n png_error @102\n png_chunk_error @103\n png_err @104\n png_warning @105\n png_chunk_warning @106\n png_benign_error @107\n png_chunk_benign_error @108\n png_set_benign_errors @109\n png_get_valid @110\n png_get_rowbytes @111\n png_get_rows @112\n png_set_rows @113\n png_get_channels @114\n png_get_image_width @115\n png_get_image_height @116\n png_get_bit_depth @117\n png_get_color_type @118\n png_get_filter_type @119\n png_get_interlace_type @120\n png_get_compression_type @121\n png_get_pixels_per_meter @122\n png_get_x_pixels_per_meter @123\n png_get_y_pixels_per_meter @124\n png_get_pixel_aspect_ratio @125\n png_get_x_offset_pixels @126\n png_get_y_offset_pixels @127\n png_get_x_offset_microns @128\n png_get_y_offset_microns @129\n png_get_signature @130\n png_get_bKGD @131\n png_set_bKGD @132\n png_get_cHRM @133\n png_get_cHRM_fixed @134\n png_set_cHRM @135\n png_set_cHRM_fixed @136\n png_get_gAMA @137\n png_get_gAMA_fixed @138\n png_set_gAMA @139\n png_set_gAMA_fixed @140\n png_get_hIST @141\n png_set_hIST @142\n png_get_IHDR @143\n png_set_IHDR @144\n png_get_oFFs @145\n png_set_oFFs @146\n png_get_pCAL @147\n png_set_pCAL @148\n png_get_pHYs @149\n png_set_pHYs @150\n png_get_PLTE @151\n png_set_PLTE @152\n png_get_sBIT @153\n png_set_sBIT @154\n png_get_sRGB @155\n png_set_sRGB @156\n png_set_sRGB_gAMA_and_cHRM @157\n png_get_iCCP @158\n png_set_iCCP @159\n png_get_sPLT @160\n png_set_sPLT @161\n png_get_text @162\n png_set_text @163\n png_get_tIME @164\n png_set_tIME @165\n png_get_tRNS @166\n png_set_tRNS @167\n png_get_sCAL @168\n png_get_sCAL_s @169\n png_set_sCAL @170\n png_set_sCAL_s @171\n png_set_keep_unknown_chunks @172\n png_handle_as_unknown @173\n png_set_unknown_chunks @174\n png_set_unknown_chunk_location @175\n png_get_unknown_chunks @176\n png_set_invalid @177\n png_read_png @178\n png_write_png @179\n png_get_copyright @180\n png_get_header_ver @181\n png_get_header_version @182\n png_get_libpng_ver @183\n png_permit_mng_features @184\n png_set_strip_error_numbers @185\n png_set_user_limits @186\n png_get_user_width_max @187\n png_get_user_height_max @188\n png_set_chunk_cache_max @189\n png_get_chunk_cache_max @190\n png_set_chunk_malloc_max @191\n png_get_chunk_malloc_max @192\n png_get_pixels_per_inch @193\n png_get_x_pixels_per_inch @194\n png_get_y_pixels_per_inch @195\n png_get_x_offset_inches @196\n png_get_y_offset_inches @197\n png_get_pHYs_dpi @198\n png_get_io_state @199\n png_get_uint_32 @201\n png_get_uint_16 @202\n png_get_int_32 @203\n png_get_uint_31 @204\n png_save_uint_32 @205\n png_save_int_32 @206\n png_save_uint_16 @207\n png_set_gamma_fixed @208\n png_set_filter_heuristics_fixed @209\n png_get_pixel_aspect_ratio_fixed @210\n png_get_x_offset_inches_fixed @211\n png_get_y_offset_inches_fixed @212\n png_set_sCAL_fixed @213\n png_get_sCAL_fixed @214\n png_set_background_fixed @215\n png_get_io_chunk_type @216\n png_get_current_row_number @217\n png_get_current_pass_number @218\n png_process_data_pause @219\n png_process_data_skip @220\n png_set_expand_16 @221\n png_set_text_compression_level @222\n png_set_text_compression_mem_level @223\n png_set_text_compression_strategy @224\n png_set_text_compression_window_bits @225\n png_set_text_compression_method @226\n png_set_alpha_mode @227\n png_set_alpha_mode_fixed @228\n png_set_scale_16 @229\n png_get_cHRM_XYZ @230\n png_get_cHRM_XYZ_fixed @231\n png_set_cHRM_XYZ @232\n png_set_cHRM_XYZ_fixed @233\n png_image_begin_read_from_file @234\n png_image_begin_read_from_stdio @235\n png_image_begin_read_from_memory @236\n png_image_finish_read @237\n png_image_free @238\n png_image_write_to_file @239\n png_image_write_to_stdio @240\n png_convert_to_rfc1123_buffer @241\n png_set_check_for_invalid_index @242\n png_get_palette_max @243\n png_set_option @244\n png_image_write_to_memory @245\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/test.cmake.in",
    "content": "# test.cmake.in\n\n# Copyright (C) 2016 Glenn Randers-Pehrson\n# Written by Roger Leigh, 2016\n\n# This code is released under the libpng license.\n# For conditions of distribution and use, see the disclaimer\n# and license in png.h\n\nset(TEST_OPTIONS \"@TEST_OPTIONS@\")\nset(TEST_FILES \"@TEST_FILES@\")\n\nforeach(file ${TEST_FILES})\n  file(TO_NATIVE_PATH \"${file}\" native_file)\n  list(APPEND NATIVE_TEST_FILES \"${native_file}\")\nendforeach()\n\n# Add the directory containing libpng to the PATH (Windows only)\nif(WIN32)\n  get_filename_component(LIBPNG_DIR \"${LIBPNG}\" PATH)\n  file(TO_NATIVE_PATH \"${LIBPNG_DIR}\" LIBPNG_DIR)\n  set(ENV{PATH} \"${LIBPNG_DIR};$ENV{PATH}\")\nendif()\n\nexecute_process(COMMAND \"${CMAKE_COMMAND}\" -E echo \"Running ${TEST_COMMAND}\" ${TEST_OPTIONS} ${NATIVE_TEST_FILES})\n\nexecute_process(COMMAND \"${TEST_COMMAND}\" ${TEST_OPTIONS} ${NATIVE_TEST_FILES}\n                RESULT_VARIABLE TEST_STATUS)\nif(TEST_STATUS)\n  message(FATAL_ERROR \"Returned failed status ${TEST_STATUS}!\")\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/libpng/scripts/vers.c",
    "content": "\n/* vers.c - define format of libpng.vers\n *\n * Last changed in libpng version 1.6.16 [December 22, 2014]\n * Copyright (c) 2011-2014 Glenn Randers-Pehrson\n *\n * This code is released under the libpng license.\n * For conditions of distribution and use, see the disclaimer\n * and license in png.h\n */\n\n#define PNG_EXPORTA(ordinal, type, name, args, attributes)\\\n        PNG_DFN \" @\" SYMBOL_PREFIX \"@@\" name \"@;\"\n\nPNG_DFN \"@\" PNGLIB_LIBNAME \"@ {global:\"\n\n#include \"../png.h\"\n\nPNG_DFN \"local: *; };\"\n"
  },
  {
    "path": "atlas-aapt/external/safe-iop/Android.mk",
    "content": "# Copyright (C) 2008 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\nLOCAL_PATH:= $(call my-dir)\ninclude $(CLEAR_VARS)\n\nLOCAL_C_INCLUDES := \\\n\t$(LOCAL_PATH)/include\n\nLOCAL_SRC_FILES := src/safe_iop.c\n\nLOCAL_MODULE := libsafe_iop\n\ninclude $(BUILD_STATIC_LIBRARY)\n\ninclude $(LOCAL_PATH)/testsuite/Android.mk\n"
  },
  {
    "path": "atlas-aapt/external/safe-iop/CleanSpec.mk",
    "content": "# Copyright (C) 2007 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n# If you don't need to do a full clean build but would like to touch\n# a file or delete some intermediate files, add a clean step to the end\n# of the list.  These steps will only be run once, if they haven't been\n# run before.\n#\n# E.g.:\n#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)\n#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)\n#\n# Always use \"touch -c\" and \"rm -f\" or \"rm -rf\" to gracefully deal with\n# files that are missing or have been moved.\n#\n# Use $(PRODUCT_OUT) to get to the \"out/target/product/blah/\" directory.\n# Use $(OUT_DIR) to refer to the \"out\" directory.\n#\n# If you need to re-do something that's already mentioned, just copy\n# the command and add it to the bottom of the list.  E.g., if a change\n# that you made last week required touching a file and a change you\n# made today requires touching the same file, just copy the old\n# touch step and add it to the end of the list.\n#\n# ************************************************\n# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST\n# ************************************************\n\n# For example:\n#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)\n#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)\n#$(call add-clean-step, find $(OUT_DIR) -type f -name \"IGTalkSession*\" -print0 | xargs -0 rm -f)\n#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)\n\n# ************************************************\n# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST\n# ************************************************\n"
  },
  {
    "path": "atlas-aapt/external/safe-iop/MODULE_LICENSE_BSD_LIKE",
    "content": ""
  },
  {
    "path": "atlas-aapt/external/safe-iop/NOTICE",
    "content": "/*\n * Copyright (c) 2007,2008 Will Drewry <redpig@dataspill.org>\n * Some portions contributed by Google Inc., 2008.\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n"
  },
  {
    "path": "atlas-aapt/external/safe-iop/README.version",
    "content": "URL: https://code.google.com/p/safe-iop/downloads/detail?name=safe-iop-0.3.1.tgz&can=2&q=\nVersion: 0.3.1\nBugComponent: 21001\nAllAdvisories: yes\n"
  },
  {
    "path": "atlas-aapt/external/safe-iop/include/safe_iop.h",
    "content": "/* safe_iop\n * License:: released in to the public domain\n * Author:: Will Drewry <redpig@dataspill.org>\n * Copyright 2007,2008 redpig@dataspill.org\n * Some portions copyright The Android Open Source Project\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS\n * OF ANY KIND, either express or implied.\n * \n * To Do:\n * - Add varargs style interface for safe_<op>()\n * - Add support for safe conversion\n * - Add additional sizes to safe_iopf (currently 32-bit only)\n *   (this will make use of the safe conversion above)\n * - Add left shift support\n * - Add more test cases for interfaces (op_mixed)\n * - Add more tests for edge cases I've missed? and for thoroughness\n *\n * History:\n * = 0.3\n * - solidified code into a smaller number of macros and functions\n * - added typeless functions using gcc magic (typeof)\n * - deprecrated old interfaces (-DSAFE_IOP_COMPAT)\n * - discover size maximums automagically\n * - separated test cases for easier understanding\n * - significantly expanded test cases\n * - derive type maximums and minimums internally (checked in testing)\n * = 0.2\n * - Removed dependence on twos complement arithmetic to allow macro-ized\n *   definitions\n * - Added (s)size_t support\n * - Added (u)int8,16,64 support\n * - Added portable inlining\n * - Added support for NULL result pointers\n * - Added support for header-only use (safe_iop.c only needed for safe_iopf)\n * = 0.1\n * - Initial release\n *\n * Contributors & thanks:\n * - peter@valchev.net for his review, comments, and enthusiasm\n * - thanks to Google for contributing some time\n */\n\n/* This library supplies a set of standard functions for performing and\n * checking safe integer operations. The code is based on examples from\n * https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow\n *\n * Inline functions are available for specific operations.  If the result\n * pointer is NULL, the function will still return 1 or 0 if it would\n * or would not overflow.  If multiple operations need to be performed,\n * safe_iopf provides a format-string driven model, but it does not yet support\n * non-32 bit operations\n *\n * NOTE: This code assumes int32_t to be signed.\n */\n#ifndef _SAFE_IOP_H\n#define _SAFE_IOP_H\n#include <limits.h>  /* for CHAR_BIT */\n#include <assert.h>  /* for type enforcement */\n\ntypedef enum { SAFE_IOP_TYPE_S32 = 1,\n               SAFE_IOP_TYPE_U32,\n               SAFE_IOP_TYPE_DEFAULT = SAFE_IOP_TYPE_S32,\n               } safe_type_t;\n\n#define SAFE_IOP_TYPE_PREFIXES \"us\"\n\n/* use a nice prefix :) */\n#define __sio(x) OPAQUE_SAFE_IOP_PREFIX_ ## x\n#define OPAQUE_SAFE_IOP_PREFIX_var(x) __sio(VARIABLE_ ## x)\n#define OPAQUE_SAFE_IOP_PREFIX_m(x) __sio(MACRO_ ## x)\n\n\n/* A recursive macro which safely multiplies the given type together.\n * _ptr may be NULL.\n * mixed types or mixed sizes will unconditionally return 0;\n */\n#define OPAQUE_SAFE_IOP_PREFIX_MACRO_smax(_a) \\\n  ((typeof(_a))(~((typeof(_a)) 1 << ((sizeof(typeof(_a)) * CHAR_BIT) - 1))))\n#define OPAQUE_SAFE_IOP_PREFIX_MACRO_smin(_a) \\\n  ((typeof(_a))(-__sio(m)(smax)(_a) - 1))\n#define OPAQUE_SAFE_IOP_PREFIX_MACRO_umax(_a) ((typeof(_a))(~((typeof(_a)) 0)))\n\n#define OPAQUE_SAFE_IOP_PREFIX_MACRO_type_enforce(__A, __B) \\\n  ((((__sio(m)(smin)(__A) <= ((typeof(__A))0)) && \\\n     (__sio(m)(smin)(__B) <= ((typeof(__B))0))) || \\\n   (((__sio(m)(smin)(__A) > ((typeof(__A))0))) && \\\n     (__sio(m)(smin)(__B) > ((typeof(__B))0)))) && \\\n   (sizeof(typeof(__A)) == sizeof(typeof(__B)))) \n\n\n/* We use a non-void wrapper for assert(). This allows us to factor it away on\n * -DNDEBUG but still have conditionals test the result (and optionally return\n *  false).\n */\n#if defined(NDEBUG)\n#  define OPAQUE_SAFE_IOP_PREFIX_MACRO_assert(x) (x)\n#else\n#  define OPAQUE_SAFE_IOP_PREFIX_MACRO_assert(x) ({ assert(x); 1; })\n#endif\n\n\n/* Primary interface macros */\n/* type checking is compiled out if NDEBUG supplied. */\n#define safe_add(_ptr, __a, __b) \\\n ({ int __sio(var)(ok) = 0; \\\n    typeof(__a) __sio(var)(_a) = (__a); \\\n    typeof(__b) __sio(var)(_b) = (__b); \\\n    typeof(_ptr) __sio(var)(p) = (_ptr); \\\n    if (__sio(m)(assert)(__sio(m)(type_enforce)(__sio(var)(_a), \\\n                                                __sio(var)(_b)))) { \\\n      if (__sio(m)(smin)(__sio(var)(_a)) <= ((typeof(__sio(var)(_a)))0)) { \\\n        __sio(var)(ok) = safe_sadd(__sio(var)(p), \\\n                                   __sio(var)(_a), \\\n                                   __sio(var)(_b)); \\\n      } else { \\\n        __sio(var)(ok) = safe_uadd(__sio(var)(p), \\\n                                   __sio(var)(_a), \\\n                                   __sio(var)(_b)); \\\n      } \\\n    } \\\n    __sio(var)(ok); })\n\n#define safe_add3(_ptr, _A, _B, _C) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n   (safe_add(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n    safe_add((_ptr), __sio(var)(r), __sio(var)(c))); })\n\n#define safe_add4(_ptr, _A, _B, _C, _D) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C); \\\n   typeof(_D) __sio(var)(d) = (_D); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n  (safe_add(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n   safe_add(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \\\n   safe_add((_ptr), __sio(var)(r), (__sio(var)(d)))); })\n\n#define safe_add5(_ptr, _A, _B, _C, _D, _E) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C); \\\n   typeof(_D) __sio(var)(d) = (_D); \\\n   typeof(_E) __sio(var)(e) = (_E); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n  (safe_add(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n   safe_add(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \\\n   safe_add(&(__sio(var)(r)), __sio(var)(r), __sio(var)(d)) && \\\n   safe_add((_ptr), __sio(var)(r), __sio(var)(e))); })\n\n#define safe_sub(_ptr, __a, __b) \\\n ({ int __sio(var)(ok) = 0; \\\n    typeof(__a) __sio(var)(_a) = (__a); \\\n    typeof(__b) __sio(var)(_b) = (__b); \\\n    typeof(_ptr) __sio(var)(p) = (_ptr); \\\n    if (__sio(m)(assert)(__sio(m)(type_enforce)(__sio(var)(_a), \\\n                                                __sio(var)(_b)))) { \\\n      if (__sio(m)(umax)(__sio(var)(_a)) <= ((typeof(__sio(var)(_a)))0)) { \\\n        __sio(var)(ok) = safe_ssub(__sio(var)(p), \\\n                                   __sio(var)(_a), \\\n                                   __sio(var)(_b)); \\\n      } else { \\\n        __sio(var)(ok) = safe_usub(__sio(var)(p), \\\n                                   __sio(var)(_a), \\\n                                   __sio(var)(_b)); \\\n      } \\\n    } \\\n    __sio(var)(ok); })\n\n/* These are sequentially performed */\n#define safe_sub3(_ptr, _A, _B, _C) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n   (safe_sub(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n    safe_sub((_ptr), __sio(var)(r), __sio(var)(c))); })\n\n#define safe_sub4(_ptr, _A, _B, _C, _D) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C); \\\n   typeof(_D) __sio(var)(d) = (_D); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n  (safe_sub(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n   safe_sub(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \\\n   safe_sub((_ptr), __sio(var)(r), (__sio(var)(d)))); })\n\n#define safe_sub5(_ptr, _A, _B, _C, _D, _E) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C); \\\n   typeof(_D) __sio(var)(d) = (_D); \\\n   typeof(_E) __sio(var)(e) = (_E); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n   (safe_sub(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n    safe_sub(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \\\n    safe_sub(&(__sio(var)(r)), __sio(var)(r), __sio(var)(d)) && \\\n    safe_sub((_ptr), __sio(var)(r), __sio(var)(e))); })\n\n\n \n#define safe_mul(_ptr, __a, __b) \\\n ({ int __sio(var)(ok) = 0; \\\n    typeof(__a) __sio(var)(_a) = (__a); \\\n    typeof(__b) __sio(var)(_b) = (__b); \\\n    typeof(_ptr) __sio(var)(p) = (_ptr); \\\n    if (__sio(m)(assert)(__sio(m)(type_enforce)(__sio(var)(_a), \\\n                                                __sio(var)(_b)))) { \\\n      if (__sio(m)(umax)(__sio(var)(_a)) <= ((typeof(__sio(var)(_a)))0)) { \\\n        __sio(var)(ok) = safe_smul(__sio(var)(p), \\\n                                   __sio(var)(_a), \\\n                                   __sio(var)(_b)); \\\n      } else { \\\n        __sio(var)(ok) = safe_umul(__sio(var)(p), \\\n                                   __sio(var)(_a), \\\n                                   __sio(var)(_b)); \\\n      } \\\n    } \\\n    __sio(var)(ok); })\n\n#define safe_mul3(_ptr, _A, _B, _C) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n   (safe_mul(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n    safe_mul((_ptr), __sio(var)(r), __sio(var)(c))); })\n\n#define safe_mul4(_ptr, _A, _B, _C, _D) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C); \\\n   typeof(_D) __sio(var)(d) = (_D); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n  (safe_mul(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n   safe_mul(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \\\n   safe_mul((_ptr), __sio(var)(r), (__sio(var)(d)))); })\n\n#define safe_mul5(_ptr, _A, _B, _C, _D, _E) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C); \\\n   typeof(_D) __sio(var)(d) = (_D); \\\n   typeof(_E) __sio(var)(e) = (_E); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n  (safe_mul(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n   safe_mul(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \\\n   safe_mul(&(__sio(var)(r)), __sio(var)(r), __sio(var)(d)) && \\\n   safe_mul((_ptr), __sio(var)(r), __sio(var)(e))); })\n\n#define safe_div(_ptr, __a, __b) \\\n ({ int __sio(var)(ok) = 0; \\\n    typeof(__a) __sio(var)(_a) = (__a); \\\n    typeof(__b) __sio(var)(_b) = (__b); \\\n    typeof(_ptr) __sio(var)(p) = (_ptr); \\\n    if (__sio(m)(assert)(__sio(m)(type_enforce)(__sio(var)(_a), \\\n                                                __sio(var)(_b)))) { \\\n      if (__sio(m)(umax)(__sio(var)(_a)) <= ((typeof(__sio(var)(_a)))0)) { \\\n        __sio(var)(ok) = safe_sdiv(__sio(var)(p), \\\n                                   __sio(var)(_a), \\\n                                   __sio(var)(_b)); \\\n      } else { \\\n        __sio(var)(ok) = safe_udiv(__sio(var)(p), \\\n                                   __sio(var)(_a), \\\n                                   __sio(var)(_b)); \\\n      } \\\n    } \\\n    __sio(var)(ok); })\n\n#define safe_div3(_ptr, _A, _B, _C) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n   (safe_div(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n    safe_div((_ptr), __sio(var)(r), __sio(var)(c))); })\n\n#define safe_div4(_ptr, _A, _B, _C, _D) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C); \\\n   typeof(_D) __sio(var)(d) = (_D); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n  (safe_div(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n   safe_div(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \\\n   safe_div((_ptr), __sio(var)(r), (__sio(var)(d)))); })\n\n#define safe_div5(_ptr, _A, _B, _C, _D, _E) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C); \\\n   typeof(_D) __sio(var)(d) = (_D); \\\n   typeof(_E) __sio(var)(e) = (_E); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n  (safe_div(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n   safe_div(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \\\n   safe_div(&(__sio(var)(r)), __sio(var)(r), __sio(var)(d)) && \\\n   safe_div((_ptr), __sio(var)(r), __sio(var)(e))); })\n\n#define safe_mod(_ptr, __a, __b) \\\n ({ int __sio(var)(ok) = 0; \\\n    typeof(__a) __sio(var)(_a) = (__a); \\\n    typeof(__b) __sio(var)(_b) = (__b); \\\n    typeof(_ptr) __sio(var)(p) = (_ptr); \\\n    if (__sio(m)(assert)(__sio(m)(type_enforce)(__sio(var)(_a), \\\n                                                __sio(var)(_b)))) { \\\n      if (__sio(m)(umax)(__sio(var)(_a)) <= ((typeof(__sio(var)(_a)))0)) { \\\n        __sio(var)(ok) = safe_smod(__sio(var)(p), \\\n                                   __sio(var)(_a), \\\n                                   __sio(var)(_b)); \\\n      } else { \\\n        __sio(var)(ok) = safe_umod(__sio(var)(p), \\\n                                   __sio(var)(_a), \\\n                                   __sio(var)(_b)); \\\n      } \\\n    } \\\n    __sio(var)(ok); })\n\n#define safe_mod3(_ptr, _A, _B, _C) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n   (safe_mod(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n    safe_mod((_ptr), __sio(var)(r), __sio(var)(c))); })\n\n#define safe_mod4(_ptr, _A, _B, _C, _D) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C); \\\n   typeof(_D) __sio(var)(d) = (_D); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n   (safe_mod(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n    safe_mod(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \\\n    safe_mod((_ptr), __sio(var)(r), (__sio(var)(d)))); })\n\n#define safe_mod5(_ptr, _A, _B, _C, _D, _E) \\\n({ typeof(_A) __sio(var)(a) = (_A); \\\n   typeof(_B) __sio(var)(b) = (_B); \\\n   typeof(_C) __sio(var)(c) = (_C), \\\n   typeof(_D) __sio(var)(d) = (_D); \\\n   typeof(_E) __sio(var)(e) = (_E); \\\n   typeof(_A) __sio(var)(r) = 0; \\\n   (safe_mod(&(__sio(var)(r)), __sio(var)(a), __sio(var)(b)) && \\\n    safe_mod(&(__sio(var)(r)), __sio(var)(r), __sio(var)(c)) && \\\n    safe_mod(&(__sio(var)(r)), __sio(var)(r), __sio(var)(d)) && \\\n    safe_mod((_ptr), __sio(var)(r), __sio(var)(e))); })\n\n/*** Safe integer operation implementation macros ***/\n\n#define safe_uadd(_ptr, _a, _b) \\\n ({ int __sio(var)(ok) = 0; \\\n    if ((typeof(_a))(_b) <= (typeof(_a))(__sio(m)(umax)(_a) - (_a))) { \\\n      if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) + (_b); } \\\n      __sio(var)(ok) = 1; \\\n    } __sio(var)(ok); })\n\n#define safe_sadd(_ptr, _a, _b) \\\n  ({ int __sio(var)(ok) = 1; \\\n     if (((_b) > (typeof(_a))0) && ((_a) > (typeof(_a))0)) { /*>0*/ \\\n       if ((_a) > (typeof(_a))(__sio(m)(smax)(_a) - (_b))) __sio(var)(ok) = 0; \\\n     } else if (!((_b) > (typeof(_a))0) && !((_a) > (typeof(_a))0)) { /*<0*/ \\\n       if ((_a) < (typeof(_a))(__sio(m)(smin)(_a) - (_b))) __sio(var)(ok) = 0; \\\n     } \\\n     if (__sio(var)(ok) && (_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) + (_b); } \\\n     __sio(var)(ok); })\n\n#define safe_usub(_ptr, _a, _b) \\\n  ({ int __sio(var)(ok) = 0; \\\n     if ((_a) >= (_b)) { \\\n       if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) - (_b); } \\\n       __sio(var)(ok) = 1; \\\n     } \\\n     __sio(var)(ok); }) \n\n#define safe_ssub(_ptr, _a, _b) \\\n  ({ int __sio(var)(ok) = 0; \\\n     if (!((_b) <= 0 && (_a) > (__sio(m)(smax)(_a) + (_b))) && \\\n         !((_b) > 0 && (_a) < (__sio(m)(smin)(_a) + (_b)))) { \\\n         __sio(var)(ok) = 1; \\\n         if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) - (_b); } \\\n     } \\\n     __sio(var)(ok); }) \n\n#define safe_umul(_ptr, _a, _b) \\\n  ({ int __sio(var)(ok) = 0; \\\n     if (!(_b) || (_a) <= (__sio(m)(umax)(_a) / (_b))) { \\\n       __sio(var)(ok) = 1; \\\n       if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) * (_b); } \\\n     } \\\n     __sio(var)(ok); }) \n\n#define safe_smul(_ptr, _a, _b) \\\n  ({ int __sio(var)(ok) = 1; \\\n    if ((_a) > 0) {  /* a is positive */ \\\n      if ((_b) > 0) {  /* b and a are positive */ \\\n        if ((_a) > (__sio(m)(smax)(_a) / (_b))) { \\\n          __sio(var)(ok) = 0; \\\n        } \\\n      } /* end if a and b are positive */ \\\n      else { /* a positive, b non-positive */ \\\n        if ((_b) < (__sio(m)(smin)(_a) / (_a))) { \\\n          __sio(var)(ok) = 0; \\\n        } \\\n      } /* a positive, b non-positive */ \\\n    } /* end if a is positive */ \\\n    else { /* a is non-positive */ \\\n      if ((_b) > 0) { /* a is non-positive, b is positive */ \\\n        if ((_a) < (__sio(m)(smin)(_a) / (_b))) { \\\n        __sio(var)(ok) = 0; \\\n        } \\\n      } /* end if a is non-positive, b is positive */ \\\n      else { /* a and b are non-positive */ \\\n        if( ((_a) != 0) && ((_b) < (__sio(m)(smax)(_a) / (_a)))) { \\\n          __sio(var)(ok) = 0; \\\n        } \\\n      } /* end if a and b are non-positive */ \\\n    } /* end if a is non-positive */ \\\n    if (__sio(var)(ok) && (_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) * (_b); } \\\n    __sio(var)(ok); }) \n\n/* div-by-zero is the only thing addressed */\n#define safe_udiv(_ptr, _a, _b) \\\n ({ int __sio(var)(ok) = 0; \\\n    if ((_b) != 0) { \\\n      if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) / (_b); } \\\n      __sio(var)(ok) = 1; \\\n    } \\\n    __sio(var)(ok); })\n\n/* Addreses div by zero and smin -1 */\n#define safe_sdiv(_ptr, _a, _b) \\\n ({ int __sio(var)(ok) = 0; \\\n    if ((_b) != 0 && \\\n        (((_a) != __sio(m)(smin)(_a)) || ((_b) != (typeof(_b))-1))) { \\\n      if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) / (_b); } \\\n      __sio(var)(ok) = 1; \\\n    } \\\n    __sio(var)(ok); })\n\n#define safe_umod(_ptr, _a, _b) \\\n ({ int __sio(var)(ok) = 0; \\\n    if ((_b) != 0) { \\\n      if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) % (_b); } \\\n      __sio(var)(ok) = 1; \\\n    } \\\n    __sio(var)(ok); })\n\n#define safe_smod(_ptr, _a, _b) \\\n ({ int __sio(var)(ok) = 0; \\\n    if ((_b) != 0 && \\\n        (((_a) != __sio(m)(smin)(_a)) || ((_b) != (typeof(_b))-1))) { \\\n      if ((_ptr)) { *((typeof(_a)*)(_ptr)) = (_a) % (_b); } \\\n      __sio(var)(ok) = 1; \\\n    } \\\n    __sio(var)(ok); })\n\n#if SAFE_IOP_COMPAT\n/* These are used for testing for easy type enforcement */\n#include <sys/types.h>\n#include <limits.h>\n\n#ifndef SAFE_IOP_INLINE\n#  if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 &&  __GNUC_MINOR__ > 0)\n#    define SAFE_IOP_INLINE __attribute__((always_inline)) static inline\n#  else\n#    define SAFE_IOP_INLINE static inline\n#  endif\n#endif\n\n#define MAKE_UADD(_prefix, _bits, _type, _max) \\\n  SAFE_IOP_INLINE \\\n  int safe_add##_prefix##_bits (_type *result, _type value, _type a) { \\\n    return safe_uadd(result, value, a); \\\n  }\n\n#define MAKE_SADD(_prefix, _bits, _type, _max) \\\n  SAFE_IOP_INLINE \\\n  int safe_add##_prefix##_bits(_type *result, _type value, _type a) { \\\n    return safe_sadd(result, value, a); \\\n  }\n\n#define MAKE_USUB(_prefix, _bits, _type) \\\n  SAFE_IOP_INLINE \\\n  int safe_sub##_prefix##_bits(_type *result, _type value, _type a) { \\\n    return safe_usub(result, value, a); \\\n  }\n\n#define MAKE_SSUB(_prefix, _bits, _type, _min, _max) \\\n  SAFE_IOP_INLINE \\\n  int safe_sub##_prefix##_bits(_type *result, _type value, _type a) { \\\n    return safe_ssub(result, value, a); \\\n  }\n\n#define MAKE_UMUL(_prefix, _bits, _type, _max) \\\n  SAFE_IOP_INLINE \\\n  int safe_mul##_prefix##_bits(_type *result, _type value, _type a) { \\\n    return safe_umul(result, value, a); \\\n  }\n\n\n#define MAKE_SMUL(_prefix, _bits, _type, _max, _min) \\\n  SAFE_IOP_INLINE \\\n  int safe_mul##_prefix##_bits(_type *result, _type value, _type a) { \\\n    return safe_smul(result, value, a); \\\n  }\n\n#define MAKE_UDIV(_prefix, _bits, _type) \\\n  SAFE_IOP_INLINE \\\n  int safe_div##_prefix##_bits(_type *result, _type value, _type a) { \\\n    return safe_udiv(result, value, a); \\\n  }\n\n#define MAKE_SDIV(_prefix, _bits, _type, _min) \\\n  SAFE_IOP_INLINE \\\n  int safe_div##_prefix##_bits(_type *result, _type value, _type a) { \\\n    return safe_sdiv(result, value, a); \\\n  }\n\n#define MAKE_UMOD(_prefix, _bits, _type) \\\n  SAFE_IOP_INLINE \\\n  int safe_mod##_prefix##_bits(_type *result, _type value, _type a) { \\\n    return safe_umod(result, value, a); \\\n  }\n\n#define MAKE_SMOD(_prefix, _bits, _type, _min) \\\n  SAFE_IOP_INLINE \\\n  int safe_mod##_prefix##_bits(_type *result, _type value, _type a) { \\\n    return safe_smod(result, value, a); \\\n  }\n\n/* __LP64__ is given by GCC. Without more work, this is bound to GCC. */\n#if __LP64__ == 1 || __SIZEOF_LONG__ > __SIZEOF_INT__\n#  define SAFE_INT64_MAX 0x7fffffffffffffffL\n#  define SAFE_UINT64_MAX 0xffffffffffffffffUL\n#  define SAFE_INT64_MIN (-SAFE_INT64_MAX - 1L)\n#elif __SIZEOF_LONG__ == __SIZEOF_INT__\n#  define SAFE_INT64_MAX 0x7fffffffffffffffLL\n#  define SAFE_UINT64_MAX 0xffffffffffffffffULL\n#  define SAFE_INT64_MIN (-SAFE_INT64_MAX - 1LL)\n#else\n#  warning \"64-bit support disabled\"\n#  define SAFE_IOP_NO_64 1\n#endif\n\n/* Assumes SSIZE_MAX */\n#ifndef SSIZE_MIN\n#  if SSIZE_MAX == LONG_MAX\n#    define SSIZE_MIN LONG_MIN\n#  elif SSIZE_MAX == LONG_LONG_MAX\n#    define SSIZE_MIN LONG_LONG_MIN\n#  else\n#    error \"SSIZE_MIN is not defined and could not be guessed\"\n#  endif\n#endif\n\n\n\n#ifndef SAFE_IOP_NO_64\n  MAKE_UADD(u, 64, u_int64_t, SAFE_UINT64_MAX)\n#endif\nMAKE_UADD(,szt, size_t, SIZE_MAX)\nMAKE_UADD(u, 32, u_int32_t, UINT_MAX)\nMAKE_UADD(u, 16, u_int16_t, USHRT_MAX)\nMAKE_UADD(u,  8, u_int8_t, UCHAR_MAX)\n\n#ifndef SAFE_IOP_NO_64\n  MAKE_SADD(s, 64, int64_t, SAFE_INT64_MAX)\n#endif\nMAKE_SADD(s, szt, ssize_t, SSIZE_MAX)\nMAKE_SADD(s, 32, int32_t, INT_MAX)\nMAKE_SADD(s, 16, int16_t, SHRT_MAX)\nMAKE_SADD(s,  8, int8_t, SCHAR_MAX)\n\n#ifndef SAFE_IOP_NO_64\n  MAKE_USUB(u, 64, u_int64_t)\n#endif\nMAKE_USUB(, szt, size_t)\nMAKE_USUB(u, 32, u_int32_t)\nMAKE_USUB(u, 16, u_int16_t)\nMAKE_USUB(u, 8, u_int8_t)\n\n#ifndef SAFE_IOP_NO_64\n  MAKE_SSUB(s, 64, int64_t, SAFE_INT64_MIN, SAFE_INT64_MAX)\n#endif\nMAKE_SSUB(s, szt, ssize_t, SSIZE_MIN, SSIZE_MAX)\nMAKE_SSUB(s, 32, int32_t, INT_MIN, INT_MAX)\nMAKE_SSUB(s, 16, int16_t, SHRT_MIN, SHRT_MAX)\nMAKE_SSUB(s,  8, int8_t, SCHAR_MIN, SCHAR_MAX)\n\n\n#ifndef SAFE_IOP_NO_64\n  MAKE_UMUL(u, 64, u_int64_t, SAFE_UINT64_MAX)\n#endif\nMAKE_UMUL(, szt, size_t, SIZE_MAX)\nMAKE_UMUL(u, 32, u_int32_t, UINT_MAX)\nMAKE_UMUL(u, 16, u_int16_t, USHRT_MAX)\nMAKE_UMUL(u, 8, u_int8_t,  UCHAR_MAX)\n\n#ifndef SAFE_IOP_NO_64\n  MAKE_SMUL(s, 64, int64_t, SAFE_INT64_MAX, SAFE_INT64_MIN)\n#endif\nMAKE_SMUL(s, szt, ssize_t, SSIZE_MAX, SSIZE_MIN)\nMAKE_SMUL(s, 32, int32_t, INT_MAX, INT_MIN)\nMAKE_SMUL(s, 16, int16_t, SHRT_MAX, SHRT_MIN)\nMAKE_SMUL(s,  8, int8_t,  SCHAR_MAX, SCHAR_MIN)\n\n\n#ifndef SAFE_IOP_NO_64\n  MAKE_UDIV(u, 64, u_int64_t)\n#endif\nMAKE_UDIV(, szt, size_t)\nMAKE_UDIV(u, 32, u_int32_t)\nMAKE_UDIV(u, 16, u_int16_t)\nMAKE_UDIV(u,  8, u_int8_t)\n\n#ifndef SAFE_IOP_NO_64\n  MAKE_SDIV(s, 64, int64_t, SAFE_INT64_MIN)\n#endif\nMAKE_SDIV(s, szt, ssize_t, SSIZE_MIN)\nMAKE_SDIV(s, 32, int32_t, INT_MIN)\nMAKE_SDIV(s, 16, int16_t, SHRT_MIN)\nMAKE_SDIV(s,  8, int8_t,  SCHAR_MIN)\n\n\n#ifndef SAFE_IOP_NO_64\n  MAKE_UMOD(u, 64, u_int64_t)\n#endif\nMAKE_UMOD(, szt, size_t)\nMAKE_UMOD(u, 32, u_int32_t)\nMAKE_UMOD(u, 16, u_int16_t)\nMAKE_UMOD(u,  8, u_int8_t)\n\n#ifndef SAFE_IOP_NO_64\n  MAKE_SMOD(s, 64, int64_t, SAFE_INT64_MIN)\n#endif\nMAKE_SMOD(s, szt, ssize_t, SSIZE_MIN)\nMAKE_SMOD(s, 32, int32_t, INT_MIN)\nMAKE_SMOD(s, 16, int16_t, SHRT_MIN)\nMAKE_SMOD(s, 8, int8_t,  SCHAR_MIN)\n\n/* Cleanup the macro spam */\n#undef MAKE_SMUL\n#undef MAKE_UMUL\n#undef MAKE_SSUB\n#undef MAKE_USUB\n#undef MAKE_SADD\n#undef MAKE_UADD\n#undef MAKE_UDIV\n#undef MAKE_SDIV\n#undef MAKE_UMOD\n#undef MAKE_SMOD\n\n#endif  /* SAFE_IOP_COMPAT */\n\n\n\n/* safe_iopf\n *\n * Takes in a character array which specifies the operations\n * to perform on a given value. The value will be assumed to be\n * of the type specified for each operation.\n *\n * Currently accepted format syntax is:\n *   [type_marker]operation...\n * The type marker may be any of the following:\n * - s32 for signed int32\n * - u32 for unsigned int32\n * If no type_marker is specified, it is assumed to be s32.\n *\n * Currently, this only performs correctly with 32-bit integers.\n *\n * The operation must be one of the following:\n * - * -- multiplication\n * - / -- division\n * - - -- subtraction\n * - + -- addition\n * - % -- modulo (remainder)\n * \n * Whitespace will be ignored.\n *\n * Args:\n * - pointer to the final result  (this must be at least the size of int32)\n * - array of format characters\n * - all remaining arguments are derived from the format\n * Output:\n * - Returns 1 on success leaving the result in value\n * - Returns 0 on failure leaving the contents of value *unknown*\n */\n\nint safe_iopf(void *result, const char *const fmt, ...);\n\n\n#endif  /* _SAFE_IOP_H */\n"
  },
  {
    "path": "atlas-aapt/external/safe-iop/src/safe_iop.c",
    "content": "/* safe_iop\n * License:: released in to the public domain\n * Author:: Will Drewry <redpig@dataspill.org>\n * Copyright 2007,2008 redpig@dataspill.org\n * Some portions copyright The Android Open Source Project\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS\n * OF ANY KIND, either express or implied.\n *\n * See safe_iop.h for more info.\n */\n#include <stdint.h>\n#include <stdarg.h>\n#include <string.h>\n#include <sys/types.h>\n\n#include <safe_iop.h>\n\n/* Read off the type if the first value matches a type prefix\n * and consume characters if successful.\n */\nstatic int _safe_op_read_type(safe_type_t *type, const char **c) {\n  if (type == NULL) {\n    return 0;\n  }\n  if (c == NULL || *c == NULL || **c == '\\0') {\n    return 0;\n  }\n  /* Extract a type for the operation if there is one */\n  if (strchr(SAFE_IOP_TYPE_PREFIXES, **c) != NULL) {\n    switch(**c) {\n      case 'u':\n        if ((*(*c+1) && *(*c+1) == '3') &&\n            (*(*c+2) && *(*c+2) == '2')) {\n          *type = SAFE_IOP_TYPE_U32;\n          *c += 3; /* Advance past type */\n        }\n        break;\n      case 's':\n        if ((*(*c+1) && *(*c+1) == '3') &&\n            (*(*c+2) && *(*c+2) == '2')) {\n          *type = SAFE_IOP_TYPE_S32;\n          *c += 3; /* Advance past type */\n        }\n        break;\n      default:\n        /* Unknown type */\n        return 0;\n    }\n  }\n  return 1;\n}\n\n#define _SAFE_IOP_TYPE_CASE(_type, _func) { \\\n  _type a = va_arg(ap, _type), value = *((_type *) result); \\\n  if (!baseline) { \\\n    value = a; \\\n    a = va_arg(ap, _type); \\\n    baseline = 1; \\\n  } \\\n  if (! _func( (_type *) result, value, a)) \\\n    return 0; \\\n}\n#define _SAFE_IOP_OP_CASE(u32func, s32func) \\\n  switch (type) { \\\n    case SAFE_IOP_TYPE_U32: \\\n      _SAFE_IOP_TYPE_CASE(u_int32_t, u32func); \\\n      break; \\\n    case SAFE_IOP_TYPE_S32: \\\n      _SAFE_IOP_TYPE_CASE(int32_t, s32func); \\\n      break; \\\n    default: \\\n      return 0; \\\n  }\n\nint safe_iopf(void *result, const char *const fmt, ...) {\n  va_list ap;\n  int baseline = 0; /* indicates if the base value is present */\n\n  const char *c = NULL;\n  safe_type_t type = SAFE_IOP_TYPE_DEFAULT;\n  /* Result should not be NULL */\n  if (!result)\n    return 0;\n\n  va_start(ap, fmt);\n  if (fmt == NULL || fmt[0] == '\\0')\n    return 0;\n  for(c=fmt;(*c);c++) {\n    /* Read the type if specified */\n    if (!_safe_op_read_type(&type, &c)) {\n      return 0;\n    }\n\n    /* Process the the operations */\n    switch(*c) { /* operation */\n      case '+': /* add */\n        _SAFE_IOP_OP_CASE(safe_uadd, safe_sadd);\n        break;\n      case '-': /* sub */\n        _SAFE_IOP_OP_CASE(safe_usub, safe_ssub);\n        break;\n      case '*': /* mul */\n        _SAFE_IOP_OP_CASE(safe_umul, safe_smul);\n        break;\n      case '/': /* div */\n        _SAFE_IOP_OP_CASE(safe_udiv, safe_sdiv);\n        break;\n      case '%': /* mod */\n        _SAFE_IOP_OP_CASE(safe_umod, safe_smod);\n        break;\n      default:\n       /* unknown op */\n       return 0;\n    }\n    /* Reset the type */\n   type = SAFE_IOP_TYPE_DEFAULT;\n  }\n  /* Success! */\n  return 1;\n}\n\n#ifdef SAFE_IOP_TEST\n#include <stdio.h>\n#include <stdint.h>\n#include <limits.h>\n\n/* __LP64__ is given by GCC. Without more work, this is bound to GCC. */\n#if __LP64__ == 1 || __SIZEOF_LONG__ > __SIZEOF_INT__\n#  define SAFE_INT64_MAX 0x7fffffffffffffffL\n#  define SAFE_UINT64_MAX 0xffffffffffffffffUL\n#  define SAFE_INT64_MIN (-SAFE_INT64_MAX - 1L)\n#elif __SIZEOF_LONG__ == __SIZEOF_INT__\n#  define SAFE_INT64_MAX 0x7fffffffffffffffLL\n#  define SAFE_UINT64_MAX 0xffffffffffffffffULL\n#  define SAFE_INT64_MIN (-SAFE_INT64_MAX - 1LL)\n#else\n#  warning \"64-bit support disabled\"\n#  define SAFE_IOP_NO_64 1\n#endif\n\n/* Pull these from GNU's limit.h */\n#ifndef LLONG_MAX\n#  define LLONG_MAX 9223372036854775807LL\n#endif\n#ifndef LLONG_MIN\n#  define LLONG_MIN (-LLONG_MAX - 1LL)\n#endif\n#ifndef ULLONG_MAX\n#  define ULLONG_MAX 18446744073709551615ULL\n#endif\n\n/* Assumes SSIZE_MAX */\n#ifndef SSIZE_MIN\n#  if SSIZE_MAX == LONG_MAX\n#    define SSIZE_MIN LONG_MIN\n#  elif SSIZE_MAX == LONG_LONG_MAX\n#    define SSIZE_MIN LONG_LONG_MIN\n#  else\n#    error \"SSIZE_MIN is not defined and could not be guessed\"\n#  endif\n#endif\n\n#define EXPECT_FALSE(cmd) ({ \\\n  printf(\"%s: EXPECT_FALSE(\" #cmd \") => \", __func__); \\\n  if ((cmd) != 0) { printf(\" FAILED\\n\"); expect_fail++; r = 0; } \\\n  else { printf(\" PASSED\\n\"); expect_succ++; } \\\n  expect++; \\\n  })\n#define EXPECT_TRUE(cmd) ({ \\\n  printf(\"%s: EXPECT_TRUE(\" #cmd \") => \", __func__); \\\n  if ((cmd) != 1) { printf(\" FAILED\\n\"); expect_fail++; r = 0; } \\\n  else { printf(\" PASSED\\n\"); expect_succ++; } \\\n  expect++;  \\\n  })\n\nstatic int expect = 0, expect_succ = 0, expect_fail = 0;\n\n/***** ADD *****/\nint T_add_s8() {\n  int r=1;\n  int8_t a, b;\n  a=SCHAR_MIN; b=-1; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=SCHAR_MAX; b=1; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=-10; b=-11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=SCHAR_MIN; b=SCHAR_MAX; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=SCHAR_MIN+1; b=-1; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=SCHAR_MAX/2; b=SCHAR_MAX/2; EXPECT_TRUE(safe_add(NULL, a, b));\n  return r;\n}\n\nint T_add_s16() {\n  int r=1;\n  int16_t a, b;\n  a=SHRT_MIN; b=-1; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=SHRT_MAX; b=1; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=SHRT_MIN; b=SHRT_MAX; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=SHRT_MAX/2; b=SHRT_MAX/2; EXPECT_TRUE(safe_add(NULL, a, b));\n  return r;\n}\n\nint T_add_s32() {\n  int r=1;\n  int32_t a, b;\n  a=INT_MIN; b=-1; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=INT_MAX; b=1; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=INT_MIN; b=INT_MAX; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=INT_MAX/2; b=INT_MAX/2; EXPECT_TRUE(safe_add(NULL, a, b));\n  return r;\n}\n\nint T_add_s64() {\n  int r=1;\n  int64_t a, b;\n  a=SAFE_INT64_MIN; b=-1; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=SAFE_INT64_MAX; b=1; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=SAFE_INT64_MIN; b=SAFE_INT64_MAX; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=SAFE_INT64_MAX/2; b=SAFE_INT64_MAX/2; EXPECT_TRUE(safe_add(NULL, a, b));\n  return r;\n}\n\nint T_add_long() {\n  int r=1;\n  long a, b;\n  a=LONG_MIN; b=-1; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=LONG_MAX; b=1; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=LONG_MIN; b=LONG_MAX; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=LONG_MAX/2; b=LONG_MAX/2; EXPECT_TRUE(safe_add(NULL, a, b));\n  return r;\n}\nint T_add_longlong() {\n  int r=1;\n  long long a, b;\n  a=LLONG_MIN; b=-1; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=LLONG_MAX; b=1; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=LLONG_MIN; b=LLONG_MAX; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=LLONG_MAX/2; b=LLONG_MAX/2; EXPECT_TRUE(safe_add(NULL, a, b));\n  return r;\n}\nint T_add_ssizet() {\n  int r=1;\n  ssize_t a, b;\n  a=SSIZE_MIN; b=-1; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=SSIZE_MAX; b=1; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=SSIZE_MIN; b=SSIZE_MAX; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=SSIZE_MAX/2; b=SSIZE_MAX/2; EXPECT_TRUE(safe_add(NULL, a, b));\n  return r;\n}\n\nint T_add_u8() {\n  int r=1;\n  uint8_t a, b;\n  a=1; b=UCHAR_MAX; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=UCHAR_MAX/2; b=a+2; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=UCHAR_MAX/2; b=a; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=UCHAR_MAX/2; b=a+1; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=0; b=UCHAR_MAX; EXPECT_TRUE(safe_add(NULL, a, b));\n  return r;\n}\n\nint T_add_u16() {\n  int r=1;\n  uint16_t a, b;\n  a=1; b=USHRT_MAX; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=USHRT_MAX/2; b=a+2; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=USHRT_MAX/2; b=a; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=USHRT_MAX/2; b=a+1; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=0; b=USHRT_MAX; EXPECT_TRUE(safe_add(NULL, a, b));\n  return r;\n}\n\nint T_add_u32() {\n  int r=1;\n  uint32_t a, b;\n  a=1; b=UINT_MAX; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=UINT_MAX/2; b=a+2; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=UINT_MAX/2; b=a; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=UINT_MAX/2; b=a+1; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=0; b=UINT_MAX; EXPECT_TRUE(safe_add(NULL, a, b));\n  return r;\n}\n\nint T_add_u64() {\n  int r=1;\n  uint64_t a, b;\n  a=1; b=SAFE_UINT64_MAX; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=SAFE_UINT64_MAX/2; b=a+2; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=SAFE_UINT64_MAX/2; b=a; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=SAFE_UINT64_MAX/2; b=a+1; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=0; b=SAFE_UINT64_MAX; EXPECT_TRUE(safe_add(NULL, a, b));\n  return r;\n}\n\nint T_add_ulong() {\n  int r=1;\n  unsigned long a, b;\n  a=1; b=ULONG_MAX; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=ULONG_MAX/2; b=a+2; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=ULONG_MAX/2; b=a; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=ULONG_MAX/2; b=a+1; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=0; b=ULONG_MAX; EXPECT_TRUE(safe_add(NULL, a, b));\n  return r;\n}\n\nint T_add_ulonglong() {\n  int r=1;\n  unsigned long long a, b;\n  a=1; b=ULLONG_MAX; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=ULLONG_MAX/2; b=a+2; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=ULLONG_MAX/2; b=a; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=ULLONG_MAX/2; b=a+1; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=0; b=ULLONG_MAX; EXPECT_TRUE(safe_add(NULL, a, b));\n  return r;\n}\n\nint T_add_sizet() {\n  int r=1;\n  size_t a, b;\n  a=1; b=SIZE_MAX; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=SIZE_MAX/2; b=a+2; EXPECT_FALSE(safe_add(NULL, a, b));\n  a=SIZE_MAX/2; b=a; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=SIZE_MAX/2; b=a+1; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=10; b=11; EXPECT_TRUE(safe_add(NULL, a, b));\n  a=0; b=SIZE_MAX; EXPECT_TRUE(safe_add(NULL, a, b));\n  return r;\n}\n\nint T_add_mixed() {\n  int r=1;\n  int8_t a = 1;\n  uint8_t b = 2;\n  uint16_t c = 3;\n  EXPECT_FALSE(safe_add(NULL, a, b));\n  EXPECT_FALSE(safe_add(NULL, b, c));\n  EXPECT_FALSE(safe_add(NULL, a, c));\n  EXPECT_FALSE(safe_add3(NULL, a, b, c));\n  return r;\n}\n\nint T_add_increment() {\n  int r=1;\n  uint16_t a = 1, b = 2, c = 0, d[2]= {0};\n  uint16_t *cur = d;\n  EXPECT_TRUE(safe_add(cur++, a++, b));\n  EXPECT_TRUE(cur == &d[1]);\n  EXPECT_TRUE(d[0] == 3);\n  EXPECT_TRUE(a == 2);\n  a = 1; b = 2; c = 1; cur=d;d[0] = 0;\n  EXPECT_TRUE(safe_add3(cur++, a++, b++, c));\n  EXPECT_TRUE(d[0] == 4);\n  EXPECT_TRUE(cur == &d[1]);\n  EXPECT_TRUE(a == 2);\n  EXPECT_TRUE(b == 3);\n  EXPECT_TRUE(c == 1);\n  return r;\n}\n\n\n\n/***** SUB *****/\nint T_sub_s8() {\n  int r=1;\n  int8_t a, b;\n  a=SCHAR_MIN; b=1; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=SCHAR_MIN; b=SCHAR_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=SCHAR_MIN/2; b=SCHAR_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=-2; b=SCHAR_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=SCHAR_MAX; b=SCHAR_MAX; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=2; b=10; EXPECT_TRUE(safe_sub(NULL, a, b));\n  return r;\n}\n\nint T_sub_s16() {\n  int r=1;\n  int16_t a, b;\n  a=SHRT_MIN; b=1; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=SHRT_MIN; b=SHRT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=SHRT_MIN/2; b=SHRT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=-2; b=SHRT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=SHRT_MAX; b=SHRT_MAX; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=2; b=10; EXPECT_TRUE(safe_sub(NULL, a, b));\n  return r;\n}\n\nint T_sub_s32() {\n  int r=1;\n  int32_t a, b;\n  a=INT_MIN; b=1; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=INT_MIN; b=INT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=INT_MIN/2; b=INT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=-2; b=INT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=INT_MAX; b=INT_MAX; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=2; b=10; EXPECT_TRUE(safe_sub(NULL, a, b));\n  return r;\n}\n\nint T_sub_s64() {\n  int r=1;\n  int64_t a, b;\n  a=SAFE_INT64_MIN; b=1; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=SAFE_INT64_MIN; b=SAFE_INT64_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=SAFE_INT64_MIN/2; b=SAFE_INT64_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=-2; b=SAFE_INT64_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=SAFE_INT64_MAX; b=SAFE_INT64_MAX; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=2; b=10; EXPECT_TRUE(safe_sub(NULL, a, b));\n  return r;\n}\n\nint T_sub_long() {\n  int r=1;\n  long a, b;\n  a=LONG_MIN; b=1; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=LONG_MIN; b=LONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=LONG_MIN/2; b=LONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=-2; b=LONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=LONG_MAX; b=LONG_MAX; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=2; b=10; EXPECT_TRUE(safe_sub(NULL, a, b));\n  return r;\n}\n\nint T_sub_longlong() {\n  int r=1;\n  long long a, b;\n  a=LLONG_MIN; b=1; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=LLONG_MIN; b=LLONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=LLONG_MIN/2; b=LLONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=-2; b=LLONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=LLONG_MAX; b=LLONG_MAX; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=2; b=10; EXPECT_TRUE(safe_sub(NULL, a, b));\n  return r;\n}\n\nint T_sub_ssizet() {\n  int r=1;\n  ssize_t a, b;\n  a=SSIZE_MIN; b=1; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=SSIZE_MIN; b=SSIZE_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=SSIZE_MIN/2; b=SSIZE_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=-2; b=SSIZE_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=SSIZE_MAX; b=SSIZE_MAX; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=2; b=10; EXPECT_TRUE(safe_sub(NULL, a, b));\n  return r;\n}\n\nint T_sub_u8() {\n  int r=1;\n  uint8_t a, b;\n  a=0; b=UCHAR_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=UCHAR_MAX-1; b=UCHAR_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=UCHAR_MAX; b=UCHAR_MAX; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=1; b=100; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=100; b=0; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=0; b=0; EXPECT_TRUE(safe_sub(NULL, a, b));\n  return r;\n}\n\nint T_sub_u16() {\n  int r=1;\n  uint16_t a, b;\n  a=0; b=USHRT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=USHRT_MAX-1; b=USHRT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=USHRT_MAX; b=USHRT_MAX; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=1; b=100; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=100; b=0; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=0; b=0; EXPECT_TRUE(safe_sub(NULL, a, b));\n  return r;\n}\n\nint T_sub_u32() {\n  int r=1;\n  uint32_t a, b;\n  a=UINT_MAX-1; b=UINT_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=UINT_MAX; b=UINT_MAX; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=1; b=100; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=100; b=0; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=0; b=0; EXPECT_TRUE(safe_sub(NULL, a, b));\n  return r;\n}\n\nint T_sub_u64() {\n  int r=1;\n  uint64_t a, b;\n  a=SAFE_UINT64_MAX-1; b=SAFE_UINT64_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=SAFE_UINT64_MAX; b=SAFE_UINT64_MAX; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=1; b=100; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=100; b=0; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=0; b=0; EXPECT_TRUE(safe_sub(NULL, a, b));\n  return r;\n}\n\nint T_sub_ulong() {\n  int r=1;\n  unsigned long a, b;\n  a=ULONG_MAX-1; b=ULONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=ULONG_MAX; b=ULONG_MAX; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=1; b=100; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=100; b=0; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=0; b=0; EXPECT_TRUE(safe_sub(NULL, a, b));\n  return r;\n}\n\nint T_sub_ulonglong() {\n  int r=1;\n  unsigned long long a, b;\n  a=ULLONG_MAX-1; b=ULLONG_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=ULLONG_MAX; b=ULLONG_MAX; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=1; b=100; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=100; b=0; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=0; b=0; EXPECT_TRUE(safe_sub(NULL, a, b));\n  return r;\n}\n\nint T_sub_sizet() {\n  int r=1;\n  size_t a, b;\n  a=SIZE_MAX-1; b=SIZE_MAX; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=SIZE_MAX; b=SIZE_MAX; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=1; b=100; EXPECT_FALSE(safe_sub(NULL, a, b));\n  a=100; b=0; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_sub(NULL, a, b));\n  a=0; b=0; EXPECT_TRUE(safe_sub(NULL, a, b));\n  return r;\n}\n\n/***** MUL *****/\nint T_mul_s8() {\n  int r=1;\n  int8_t a, b;\n  a=SCHAR_MIN; b=-1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SCHAR_MIN; b=-2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SCHAR_MAX; b=SCHAR_MAX; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SCHAR_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SCHAR_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=100; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=SCHAR_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=SCHAR_MIN; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=SCHAR_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=SCHAR_MIN; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  return r;\n}\n\nint T_mul_s16() {\n  int r=1;\n  int16_t a, b;\n  a=SHRT_MIN; b=-1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SHRT_MIN; b=-2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SHRT_MAX; b=SHRT_MAX; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SHRT_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SHRT_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=100; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=SHRT_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=SHRT_MIN; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=SHRT_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=SHRT_MIN; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  return r;\n}\n\nint T_mul_s32() {\n  int r=1;\n  int32_t a, b;\n  a=INT_MIN; b=-1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=INT_MIN; b=-2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=INT_MAX; b=INT_MAX; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=INT_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=INT_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=100; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=INT_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=INT_MIN; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=INT_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=INT_MIN; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  return r;\n}\n\nint T_mul_s64() {\n  int r=1;\n  int64_t a, b;\n  a=SAFE_INT64_MIN; b=-1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SAFE_INT64_MIN; b=-2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SAFE_INT64_MAX; b=SAFE_INT64_MAX; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SAFE_INT64_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SAFE_INT64_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=100; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=SAFE_INT64_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=SAFE_INT64_MIN; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=SAFE_INT64_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=SAFE_INT64_MIN; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  return r;\n}\n\nint T_mul_long() {\n  int r=1;\n  long a, b;\n  a=LONG_MIN; b=-1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=LONG_MIN; b=-2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=LONG_MAX; b=LONG_MAX; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=LONG_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=LONG_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=100; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=LONG_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=LONG_MIN; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=LONG_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=LONG_MIN; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  return r;\n}\nint T_mul_longlong() {\n  int r=1;\n  long long a, b;\n  a=LLONG_MIN; b=-1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=LLONG_MIN; b=-2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=LLONG_MAX; b=LLONG_MAX; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=LLONG_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=LLONG_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=100; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=LLONG_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=LLONG_MIN; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=LLONG_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=LLONG_MIN; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  return r;\n}\nint T_mul_ssizet() {\n  int r=1;\n  ssize_t a, b;\n  a=SSIZE_MIN; b=-1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SSIZE_MIN; b=-2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SSIZE_MAX; b=SSIZE_MAX; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SSIZE_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SSIZE_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=100; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=SSIZE_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=SSIZE_MIN; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=SSIZE_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=SSIZE_MIN; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  return r;\n}\n\nint T_mul_u8() {\n  int r=1;\n  uint8_t a, b;\n  a=UCHAR_MAX-1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=UCHAR_MAX-1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=UCHAR_MAX; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=UCHAR_MAX; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=UCHAR_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=UCHAR_MAX/2+1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=UCHAR_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=UCHAR_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=1; b=UCHAR_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=UCHAR_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=UCHAR_MAX; b=1; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  return r;\n}\n\nint T_mul_u16() {\n  int r=1;\n  uint16_t a, b;\n  a=USHRT_MAX-1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=USHRT_MAX-1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=USHRT_MAX; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=USHRT_MAX; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=USHRT_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=USHRT_MAX/2+1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=USHRT_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=USHRT_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=1; b=USHRT_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=USHRT_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=USHRT_MAX; b=1; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  return r;\n}\n\nint T_mul_u32() {\n  int r=1;\n  uint32_t a, b;\n  a=UINT_MAX-1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=UINT_MAX-1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=UINT_MAX; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=UINT_MAX; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=UINT_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=UINT_MAX/2+1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=UINT_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=UINT_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=1; b=UINT_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=UINT_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=UINT_MAX; b=1; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  return r;\n}\n\nint T_mul_u64() {\n  int r=1;\n  uint64_t a, b;\n  a=SAFE_UINT64_MAX-1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=SAFE_UINT64_MAX-1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SAFE_UINT64_MAX; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=SAFE_UINT64_MAX; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SAFE_UINT64_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=SAFE_UINT64_MAX/2+1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SAFE_UINT64_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=SAFE_UINT64_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=1; b=SAFE_UINT64_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=SAFE_UINT64_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=SAFE_UINT64_MAX; b=1; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  return r;\n}\n\nint T_mul_ulong() {\n  int r=1;\n  unsigned long a, b;\n  a=ULONG_MAX-1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=ULONG_MAX-1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=ULONG_MAX; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=ULONG_MAX; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=ULONG_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=ULONG_MAX/2+1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=ULONG_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=ULONG_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=1; b=ULONG_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=ULONG_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=ULONG_MAX; b=1; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  return r;\n}\n\nint T_mul_ulonglong() {\n  int r=1;\n  unsigned long long a, b;\n  a=ULLONG_MAX-1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=ULLONG_MAX-1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=ULLONG_MAX; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=ULLONG_MAX; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=ULLONG_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=ULLONG_MAX/2+1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=ULLONG_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=ULLONG_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=1; b=ULLONG_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=ULLONG_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=ULLONG_MAX; b=1; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  return r;\n}\n\nint T_mul_sizet() {\n  int r=1;\n  size_t a, b;\n  a=SIZE_MAX-1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=SIZE_MAX-1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SIZE_MAX; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=SIZE_MAX; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SIZE_MAX/2+1; b=2; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=2; b=SIZE_MAX/2+1; EXPECT_FALSE(safe_mul(NULL, a, b));\n  a=SIZE_MAX/2; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=0; b=SIZE_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=1; b=SIZE_MAX; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=SIZE_MAX; b=0; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=SIZE_MAX; b=1; EXPECT_TRUE(safe_mul(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mul(NULL, a, b));\n  return r;\n}\n\n/***** MOD *****/\nint T_mod_s8() {\n  int r=1;\n  int8_t a, b;\n  a=SCHAR_MIN; b=-1; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b));\n  return r;\n}\n\nint T_mod_s16() {\n  int r=1;\n  int16_t a, b;\n  a=SHRT_MIN; b=-1; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b));\n  return r;\n}\n\nint T_mod_s32() {\n  int r=1;\n  int32_t a, b;\n  a=INT_MIN; b=-1; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b));\n  return r;\n}\n\nint T_mod_s64() {\n  int r=1;\n  int64_t a, b;\n  a=SAFE_INT64_MIN; b=-1; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b));\n  return r;\n}\n\nint T_mod_long() {\n  int r=1;\n  long a, b;\n  a=LONG_MIN; b=-1; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b));\n  return r;\n}\nint T_mod_longlong() {\n  int r=1;\n  long long a, b;\n  a=LLONG_MIN; b=-1LL; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=100LL; b=0LL; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=10LL; b=2LL; EXPECT_TRUE(safe_mod(NULL, a, b));\n  return r;\n}\nint T_mod_ssizet() {\n  int r=1;\n  ssize_t a, b;\n  a=SSIZE_MIN; b=-1; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b));\n  return r;\n}\n\nint T_mod_u8() {\n  int r=1;\n  uint8_t a, b;\n  a=0; b=UCHAR_MAX; EXPECT_TRUE(safe_mod(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b));\n  return r;\n}\n\nint T_mod_u16() {\n  int r=1;\n  uint16_t a, b;\n  a=0; b=USHRT_MAX; EXPECT_TRUE(safe_mod(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b));\n  return r;\n}\n\nint T_mod_u32() {\n  int r=1;\n  uint32_t a, b;\n  a=0; b=UINT_MAX; EXPECT_TRUE(safe_mod(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b));\n  return r;\n}\n\nint T_mod_u64() {\n  int r=1;\n  uint64_t a, b;\n  a=0; b=SAFE_INT64_MAX; EXPECT_TRUE(safe_mod(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b));\n  return r;\n}\n\nint T_mod_ulong() {\n  int r=1;\n  unsigned long a, b;\n  a=0; b=LONG_MAX; EXPECT_TRUE(safe_mod(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b));\n  return r;\n}\n\nint T_mod_ulonglong() {\n  int r=1;\n  unsigned long long a, b;\n  a=0ULL; b=~0ULL; EXPECT_TRUE(safe_mod(NULL, a, b));\n  a=100ULL; b=0ULL; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=10ULL; b=2ULL; EXPECT_TRUE(safe_mod(NULL, a, b));\n  return r;\n}\n\nint T_mod_sizet() {\n  int r=1;\n  size_t a, b;\n  a=0; b=SIZE_MAX; EXPECT_TRUE(safe_mod(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_mod(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_mod(NULL, a, b));\n  return r;\n}\n\n/***** DIV *****/\nint T_div_s8() {\n  int r=1;\n  int8_t a, b;\n  a=SCHAR_MIN; b=-1; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b));\n  return r;\n}\n\nint T_div_s16() {\n  int r=1;\n  int16_t a, b;\n  a=SHRT_MIN; b=-1; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b));\n  return r;\n}\n\nint T_div_s32() {\n  int r=1;\n  int32_t a, b;\n  a=INT_MIN; b=-1; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b));\n  return r;\n}\n\nint T_div_s64() {\n  int r=1;\n  int64_t a, b;\n  a=SAFE_INT64_MIN; b=-1; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b));\n  return r;\n}\n\nint T_div_long() {\n  int r=1;\n  long a, b;\n  a=LONG_MIN; b=-1; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b));\n  return r;\n}\nint T_div_longlong() {\n  int r=1;\n  long long a, b;\n  a=LLONG_MIN; b=-1LL; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=100LL; b=0LL; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=10LL; b=2LL; EXPECT_TRUE(safe_div(NULL, a, b));\n  return r;\n}\nint T_div_ssizet() {\n  int r=1;\n  ssize_t a, b;\n  a=SSIZE_MIN; b=-1; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b));\n  return r;\n}\n\nint T_div_u8() {\n  int r=1;\n  uint8_t a, b;\n  a=0; b=UCHAR_MAX; EXPECT_TRUE(safe_div(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b));\n  return r;\n}\n\nint T_div_u16() {\n  int r=1;\n  uint16_t a, b;\n  a=0; b=USHRT_MAX; EXPECT_TRUE(safe_div(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b));\n  return r;\n}\n\nint T_div_u32() {\n  int r=1;\n  uint32_t a, b;\n  a=0; b=UINT_MAX; EXPECT_TRUE(safe_div(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b));\n  return r;\n}\n\nint T_div_u64() {\n  int r=1;\n  uint64_t a, b;\n  a=0; b=SAFE_INT64_MAX; EXPECT_TRUE(safe_div(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b));\n  return r;\n}\n\nint T_div_ulong() {\n  int r=1;\n  unsigned long a, b;\n  a=0; b=LONG_MAX; EXPECT_TRUE(safe_div(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b));\n  return r;\n}\n\nint T_div_ulonglong() {\n  int r=1;\n  unsigned long long a, b;\n  a=0ULL; b=~0ULL; EXPECT_TRUE(safe_div(NULL, a, b));\n  a=100ULL; b=0ULL; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=10ULL; b=2ULL; EXPECT_TRUE(safe_div(NULL, a, b));\n  return r;\n}\n\nint T_div_sizet() {\n  int r=1;\n  size_t a, b;\n  a=0; b=SIZE_MAX; EXPECT_TRUE(safe_div(NULL, a, b));\n  a=100; b=0; EXPECT_FALSE(safe_div(NULL, a, b));\n  a=10; b=2; EXPECT_TRUE(safe_div(NULL, a, b));\n  return r;\n}\n\nint T_magic_constants() {\n  int r=1;\n  EXPECT_TRUE(__sio(m)(smin)(((int8_t)0)) == SCHAR_MIN);\n  EXPECT_TRUE(__sio(m)(smax)(((int8_t)0)) == SCHAR_MAX);\n  EXPECT_TRUE(__sio(m)(umax)(((uint8_t)0)) == UCHAR_MAX);\n\n  EXPECT_TRUE(__sio(m)(smin)(((int16_t)0)) == SHRT_MIN);\n  EXPECT_TRUE(__sio(m)(smax)(((int16_t)0)) == SHRT_MAX);\n  EXPECT_TRUE(__sio(m)(umax)(((uint16_t)0)) == USHRT_MAX);\n\n  EXPECT_TRUE(__sio(m)(smin)(((int32_t)0)) == INT_MIN);\n  EXPECT_TRUE(__sio(m)(smax)(((int32_t)0)) == INT_MAX);\n  EXPECT_TRUE(__sio(m)(umax)(((uint32_t)0)) == UINT_MAX);\n\n  EXPECT_TRUE(__sio(m)(smin)(((int64_t)0)) == SAFE_INT64_MIN);\n  EXPECT_TRUE(__sio(m)(smax)(((int64_t)0)) == SAFE_INT64_MAX);\n  EXPECT_TRUE(__sio(m)(umax)(((uint64_t)0)) == SAFE_UINT64_MAX);\n\n  EXPECT_TRUE(__sio(m)(smin)(((ssize_t)0)) == SSIZE_MIN);\n  EXPECT_TRUE(__sio(m)(smax)(((ssize_t)0)) == SSIZE_MAX);\n  EXPECT_TRUE(__sio(m)(umax)(((size_t)0)) == SIZE_MAX);\n\n  EXPECT_TRUE(__sio(m)(smin)(((long)0)) == LONG_MIN);\n  EXPECT_TRUE(__sio(m)(smax)(((long)0)) == LONG_MAX);\n  EXPECT_TRUE(__sio(m)(umax)(((unsigned long)0)) == ULONG_MAX);\n\n  EXPECT_TRUE(__sio(m)(smin)(((long long)0)) == LLONG_MIN);\n  EXPECT_TRUE(__sio(m)(smax)(((long long)0)) == LLONG_MAX);\n  EXPECT_TRUE(__sio(m)(umax)(((unsigned long long)0)) == ULLONG_MAX);\n\n  return r;\n}\n\n\n\n\nint main(int argc, char **argv) {\n  /* test inlines */\n  int tests = 0, succ = 0, fail = 0;\n  tests++; if (T_div_s8())  succ++; else fail++;\n  tests++; if (T_div_s16()) succ++; else fail++;\n  tests++; if (T_div_s32()) succ++; else fail++;\n  tests++; if (T_div_s64()) succ++; else fail++;\n  tests++; if (T_div_long()) succ++; else fail++;\n  tests++; if (T_div_longlong()) succ++; else fail++;\n  tests++; if (T_div_ssizet()) succ++; else fail++;\n  tests++; if (T_div_u8())  succ++; else fail++;\n  tests++; if (T_div_u16()) succ++; else fail++;\n  tests++; if (T_div_u32()) succ++; else fail++;\n  tests++; if (T_div_u64()) succ++; else fail++;\n  tests++; if (T_div_ulong()) succ++; else fail++;\n  tests++; if (T_div_ulonglong()) succ++; else fail++;\n  tests++; if (T_div_sizet()) succ++; else fail++;\n\n  tests++; if (T_mod_s8())  succ++; else fail++;\n  tests++; if (T_mod_s16()) succ++; else fail++;\n  tests++; if (T_mod_s32()) succ++; else fail++;\n  tests++; if (T_mod_s64()) succ++; else fail++;\n  tests++; if (T_mod_long()) succ++; else fail++;\n  tests++; if (T_mod_longlong()) succ++; else fail++;\n  tests++; if (T_mod_ssizet()) succ++; else fail++;\n  tests++; if (T_mod_u8())  succ++; else fail++;\n  tests++; if (T_mod_u16()) succ++; else fail++;\n  tests++; if (T_mod_u32()) succ++; else fail++;\n  tests++; if (T_mod_u64()) succ++; else fail++;\n  tests++; if (T_mod_ulong()) succ++; else fail++;\n  tests++; if (T_mod_ulonglong()) succ++; else fail++;\n  tests++; if (T_mod_sizet()) succ++; else fail++;\n\n  tests++; if (T_mul_s8())  succ++; else fail++;\n  tests++; if (T_mul_s16()) succ++; else fail++;\n  tests++; if (T_mul_s32()) succ++; else fail++;\n  tests++; if (T_mul_s64()) succ++; else fail++;\n  tests++; if (T_mul_long()) succ++; else fail++;\n  tests++; if (T_mul_longlong()) succ++; else fail++;\n  tests++; if (T_mul_ssizet()) succ++; else fail++;\n  tests++; if (T_mul_u8())  succ++; else fail++;\n  tests++; if (T_mul_u16()) succ++; else fail++;\n  tests++; if (T_mul_u32()) succ++; else fail++;\n  tests++; if (T_mul_u64()) succ++; else fail++;\n  tests++; if (T_mul_ulong()) succ++; else fail++;\n  tests++; if (T_mul_ulonglong()) succ++; else fail++;\n  tests++; if (T_mul_sizet()) succ++; else fail++;\n\n  tests++; if (T_sub_s8())  succ++; else fail++;\n  tests++; if (T_sub_s16()) succ++; else fail++;\n  tests++; if (T_sub_s32()) succ++; else fail++;\n  tests++; if (T_sub_s64()) succ++; else fail++;\n  tests++; if (T_sub_long()) succ++; else fail++;\n  tests++; if (T_sub_longlong()) succ++; else fail++;\n  tests++; if (T_sub_ssizet()) succ++; else fail++;\n  tests++; if (T_sub_u8())  succ++; else fail++;\n  tests++; if (T_sub_u16()) succ++; else fail++;\n  tests++; if (T_sub_u32()) succ++; else fail++;\n  tests++; if (T_sub_u64()) succ++; else fail++;\n  tests++; if (T_sub_ulong()) succ++; else fail++;\n  tests++; if (T_sub_ulonglong()) succ++; else fail++;\n  tests++; if (T_sub_sizet()) succ++; else fail++;\n\n  tests++; if (T_add_s8())  succ++; else fail++;\n  tests++; if (T_add_s16()) succ++; else fail++;\n  tests++; if (T_add_s32()) succ++; else fail++;\n  tests++; if (T_add_s64()) succ++; else fail++;\n  tests++; if (T_add_long()) succ++; else fail++;\n  tests++; if (T_add_longlong()) succ++; else fail++;\n  tests++; if (T_add_ssizet()) succ++; else fail++;\n  tests++; if (T_add_u8())  succ++; else fail++;\n  tests++; if (T_add_u16()) succ++; else fail++;\n  tests++; if (T_add_u32()) succ++; else fail++;\n  tests++; if (T_add_u64()) succ++; else fail++;\n  tests++; if (T_add_ulong()) succ++; else fail++;\n  tests++; if (T_add_ulonglong()) succ++; else fail++;\n  tests++; if (T_add_sizet()) succ++; else fail++;\n  tests++; if (T_add_mixed()) succ++; else fail++;\n  tests++; if (T_add_increment()) succ++; else fail++;\n\n  tests++; if (T_magic_constants()) succ++; else fail++;\n\n  printf(\"%d/%d expects succeeded (%d failures)\\n\",\n         expect_succ, expect, expect_fail);\n  printf(\"%d/%d tests succeeded (%d failures)\\n\", succ, tests, fail);\n  /* TODO: Add tests for safe_iopf when upgraded */\n  return fail;\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/safe-iop/testsuite/Android.mk",
    "content": "# Copyright (C) 2008 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nLOCAL_PATH:= $(call my-dir)\ninclude $(CLEAR_VARS)\n\nLOCAL_C_INCLUDES := \\\n\t$(LOCAL_PATH)/../include\n\n# TODO: make the test use the compiled static lib.\nLOCAL_SRC_FILES := ../src/safe_iop.c\nLOCAL_CFLAGS := -DSAFE_IOP_TEST=1 -DNDEBUG=1\n\nLOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)\nLOCAL_MODULE_TAGS := optional\n\nLOCAL_MODULE := safe_iop_test\n\ninclude $(BUILD_EXECUTABLE)\n"
  },
  {
    "path": "atlas-aapt/external/zlib/Android.mk",
    "content": "LOCAL_PATH:= $(call my-dir)\ninclude $(CLEAR_VARS)\n\n# measurements show that the ARM version of ZLib is about x1.17 faster\n# than the thumb one...\nLOCAL_ARM_MODE := arm\n\nzlib_files := \\\n\tsrc/adler32.c \\\n\tsrc/compress.c \\\n\tsrc/crc32.c \\\n\tsrc/deflate.c \\\n\tsrc/gzclose.c \\\n\tsrc/gzlib.c \\\n\tsrc/gzread.c \\\n\tsrc/gzwrite.c \\\n\tsrc/infback.c \\\n\tsrc/inflate.c \\\n\tsrc/inftrees.c \\\n\tsrc/inffast.c \\\n\tsrc/trees.c \\\n\tsrc/uncompr.c \\\n\tsrc/zutil.c\n\nLOCAL_MODULE := libz\nLOCAL_MODULE_TAGS := optional\nLOCAL_CFLAGS += -O3 -DUSE_MMAP\n\n# TODO: This is to work around b/24465209. Remove after root cause is fixed\nLOCAL_LDFLAGS_arm := -Wl,--hash-style=both\n\nLOCAL_SRC_FILES := $(zlib_files)\nifneq ($(TARGET_BUILD_APPS),)\n  LOCAL_SDK_VERSION := 9\nelse\n  LOCAL_CXX_STL := none\nendif\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)\ninclude $(BUILD_SHARED_LIBRARY)\n\ninclude $(CLEAR_VARS)\n\nLOCAL_ARM_MODE := arm\nLOCAL_MODULE := libz\nLOCAL_MODULE_TAGS := optional\nLOCAL_CFLAGS += -O3 -DUSE_MMAP\nLOCAL_SRC_FILES := $(zlib_files)\nifneq ($(TARGET_BUILD_APPS),)\n  LOCAL_SDK_VERSION := 9\nelse\n  LOCAL_CXX_STL := none\nendif\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)\ninclude $(BUILD_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libz\nLOCAL_MODULE_TAGS := optional\nLOCAL_CFLAGS += -O3 -DUSE_MMAP\nLOCAL_SRC_FILES := $(zlib_files)\nLOCAL_MULTILIB := both\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)\nLOCAL_MODULE_HOST_OS := darwin linux windows\nLOCAL_CXX_STL := none\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libz-host\nLOCAL_MODULE_TAGS := optional\nLOCAL_CFLAGS += -O3 -DUSE_MMAP\nLOCAL_SRC_FILES := $(zlib_files)\nLOCAL_MULTILIB := both\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)\nLOCAL_CXX_STL := none\ninclude $(BUILD_HOST_SHARED_LIBRARY)\n\ninclude $(CLEAR_VARS)\n\nLOCAL_SRC_FILES:=        \\\n\tsrc/test/minigzip.c\n\nLOCAL_MODULE:= gzip\n\nLOCAL_SHARED_LIBRARIES := libz\n\nLOCAL_CXX_STL := none\n\ninclude $(BUILD_EXECUTABLE)\n\ninclude $(CLEAR_VARS)\n\nLOCAL_SRC_FILES:=        \\\n\tsrc/test/minigzip.c\n\nLOCAL_MODULE:= minigzip\n\nLOCAL_STATIC_LIBRARIES := libz\n\nLOCAL_CXX_STL := none\n\ninclude $(BUILD_HOST_EXECUTABLE)\n"
  },
  {
    "path": "atlas-aapt/external/zlib/CleanSpec.mk",
    "content": "# Copyright (C) 2007 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n# If you don't need to do a full clean build but would like to touch\n# a file or delete some intermediate files, add a clean step to the end\n# of the list.  These steps will only be run once, if they haven't been\n# run before.\n#\n# E.g.:\n#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)\n#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)\n#\n# Always use \"touch -c\" and \"rm -f\" or \"rm -rf\" to gracefully deal with\n# files that are missing or have been moved.\n#\n# Use $(PRODUCT_OUT) to get to the \"out/target/product/blah/\" directory.\n# Use $(OUT_DIR) to refer to the \"out\" directory.\n#\n# If you need to re-do something that's already mentioned, just copy\n# the command and add it to the bottom of the list.  E.g., if a change\n# that you made last week required touching a file and a change you\n# made today requires touching the same file, just copy the old\n# touch step and add it to the end of the list.\n#\n# ************************************************\n# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST\n# ************************************************\n\n# For example:\n#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)\n#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)\n#$(call add-clean-step, find $(OUT_DIR) -type f -name \"IGTalkSession*\" -print0 | xargs -0 rm -f)\n#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)\n\n# ************************************************\n# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST\n# ************************************************\n"
  },
  {
    "path": "atlas-aapt/external/zlib/MODULE_LICENSE_BSD_LIKE",
    "content": ""
  },
  {
    "path": "atlas-aapt/external/zlib/NOTICE",
    "content": " (C) 1995-2013 Jean-loup Gailly and Mark Adler\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Jean-loup Gailly        Mark Adler\n  jloup@gzip.org          madler@alumni.caltech.edu\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 2.4.4)\nset(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)\n\nproject(zlib C)\n\nset(VERSION \"1.2.8\")\n\noption(ASM686 \"Enable building i686 assembly implementation\")\noption(AMD64 \"Enable building amd64 assembly implementation\")\n\nset(INSTALL_BIN_DIR \"${CMAKE_INSTALL_PREFIX}/bin\" CACHE PATH \"Installation directory for executables\")\nset(INSTALL_LIB_DIR \"${CMAKE_INSTALL_PREFIX}/lib\" CACHE PATH \"Installation directory for libraries\")\nset(INSTALL_INC_DIR \"${CMAKE_INSTALL_PREFIX}/include\" CACHE PATH \"Installation directory for headers\")\nset(INSTALL_MAN_DIR \"${CMAKE_INSTALL_PREFIX}/share/man\" CACHE PATH \"Installation directory for manual pages\")\nset(INSTALL_PKGCONFIG_DIR \"${CMAKE_INSTALL_PREFIX}/share/pkgconfig\" CACHE PATH \"Installation directory for pkgconfig (.pc) files\")\n\ninclude(CheckTypeSize)\ninclude(CheckFunctionExists)\ninclude(CheckIncludeFile)\ninclude(CheckCSourceCompiles)\nenable_testing()\n\ncheck_include_file(sys/types.h HAVE_SYS_TYPES_H)\ncheck_include_file(stdint.h    HAVE_STDINT_H)\ncheck_include_file(stddef.h    HAVE_STDDEF_H)\n\n#\n# Check to see if we have large file support\n#\nset(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1)\n# We add these other definitions here because CheckTypeSize.cmake\n# in CMake 2.4.x does not automatically do so and we want\n# compatibility with CMake 2.4.x.\nif(HAVE_SYS_TYPES_H)\n    list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H)\nendif()\nif(HAVE_STDINT_H)\n    list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H)\nendif()\nif(HAVE_STDDEF_H)\n    list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H)\nendif()\ncheck_type_size(off64_t OFF64_T)\nif(HAVE_OFF64_T)\n   add_definitions(-D_LARGEFILE64_SOURCE=1)\nendif()\nset(CMAKE_REQUIRED_DEFINITIONS) # clear variable\n\n#\n# Check for fseeko\n#\ncheck_function_exists(fseeko HAVE_FSEEKO)\nif(NOT HAVE_FSEEKO)\n    add_definitions(-DNO_FSEEKO)\nendif()\n\n#\n# Check for unistd.h\n#\ncheck_include_file(unistd.h Z_HAVE_UNISTD_H)\n\nif(MSVC)\n    set(CMAKE_DEBUG_POSTFIX \"d\")\n    add_definitions(-D_CRT_SECURE_NO_DEPRECATE)\n    add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)\n    include_directories(${CMAKE_CURRENT_SOURCE_DIR})\nendif()\n\nif(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)\n    # If we're doing an out of source build and the user has a zconf.h\n    # in their source tree...\n    if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h)\n        message(STATUS \"Renaming\")\n        message(STATUS \"    ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h\")\n        message(STATUS \"to 'zconf.h.included' because this file is included with zlib\")\n        message(STATUS \"but CMake generates it automatically in the build directory.\")\n        file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included)\n  endif()\nendif()\n\nset(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc)\nconfigure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein\n\t\t${ZLIB_PC} @ONLY)\nconfigure_file(\t${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein\n\t\t${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY)\ninclude_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})\n\n\n#============================================================================\n# zlib\n#============================================================================\n\nset(ZLIB_PUBLIC_HDRS\n    ${CMAKE_CURRENT_BINARY_DIR}/zconf.h\n    zlib.h\n)\nset(ZLIB_PRIVATE_HDRS\n    crc32.h\n    deflate.h\n    gzguts.h\n    inffast.h\n    inffixed.h\n    inflate.h\n    inftrees.h\n    trees.h\n    zutil.h\n)\nset(ZLIB_SRCS\n    adler32.c\n    compress.c\n    crc32.c\n    deflate.c\n    gzclose.c\n    gzlib.c\n    gzread.c\n    gzwrite.c\n    inflate.c\n    infback.c\n    inftrees.c\n    inffast.c\n    trees.c\n    uncompr.c\n    zutil.c\n)\n\nif(NOT MINGW)\n    set(ZLIB_DLL_SRCS\n        win32/zlib1.rc # If present will override custom build rule below.\n    )\nendif()\n\nif(CMAKE_COMPILER_IS_GNUCC)\n    if(ASM686)\n        set(ZLIB_ASMS contrib/asm686/match.S)\n    elseif (AMD64)\n        set(ZLIB_ASMS contrib/amd64/amd64-match.S)\n    endif ()\n\n\tif(ZLIB_ASMS)\n\t\tadd_definitions(-DASMV)\n\t\tset_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE)\n\tendif()\nendif()\n\nif(MSVC)\n    if(ASM686)\n\t\tENABLE_LANGUAGE(ASM_MASM)\n        set(ZLIB_ASMS\n\t\t\tcontrib/masmx86/inffas32.asm\n\t\t\tcontrib/masmx86/match686.asm\n\t\t)\n    elseif (AMD64)\n\t\tENABLE_LANGUAGE(ASM_MASM)\n        set(ZLIB_ASMS\n\t\t\tcontrib/masmx64/gvmat64.asm\n\t\t\tcontrib/masmx64/inffasx64.asm\n\t\t)\n    endif()\n\n\tif(ZLIB_ASMS)\n\t\tadd_definitions(-DASMV -DASMINF)\n\tendif()\nendif()\n\n# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION\nfile(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents)\nstring(REGEX REPLACE \".*#define[ \\t]+ZLIB_VERSION[ \\t]+\\\"([-0-9A-Za-z.]+)\\\".*\"\n    \"\\\\1\" ZLIB_FULL_VERSION ${_zlib_h_contents})\n\nif(MINGW)\n    # This gets us DLL resource information when compiling on MinGW.\n    if(NOT CMAKE_RC_COMPILER)\n        set(CMAKE_RC_COMPILER windres.exe)\n    endif()\n\n    add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj\n                       COMMAND ${CMAKE_RC_COMPILER}\n                            -D GCC_WINDRES\n                            -I ${CMAKE_CURRENT_SOURCE_DIR}\n                            -I ${CMAKE_CURRENT_BINARY_DIR}\n                            -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj\n                            -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc)\n    set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)\nendif(MINGW)\n\nadd_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})\nadd_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})\nset_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL)\nset_target_properties(zlib PROPERTIES SOVERSION 1)\n\nif(NOT CYGWIN)\n    # This property causes shared libraries on Linux to have the full version\n    # encoded into their final filename.  We disable this on Cygwin because\n    # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll\n    # seems to be the default.\n    #\n    # This has no effect with MSVC, on that platform the version info for\n    # the DLL comes from the resource file win32/zlib1.rc\n    set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION})\nendif()\n\nif(UNIX)\n    # On unix-like platforms the library is almost always called libz\n   set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z)\n   if(NOT APPLE)\n     set_target_properties(zlib PROPERTIES LINK_FLAGS \"-Wl,--version-script,\\\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\\\"\")\n   endif()\nelseif(BUILD_SHARED_LIBS AND WIN32)\n    # Creates zlib1.dll when building shared library version\n    set_target_properties(zlib PROPERTIES SUFFIX \"1.dll\")\nendif()\n\nif(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )\n    install(TARGETS zlib zlibstatic\n        RUNTIME DESTINATION \"${INSTALL_BIN_DIR}\"\n        ARCHIVE DESTINATION \"${INSTALL_LIB_DIR}\"\n        LIBRARY DESTINATION \"${INSTALL_LIB_DIR}\" )\nendif()\nif(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )\n    install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION \"${INSTALL_INC_DIR}\")\nendif()\nif(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )\n    install(FILES zlib.3 DESTINATION \"${INSTALL_MAN_DIR}/man3\")\nendif()\nif(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )\n    install(FILES ${ZLIB_PC} DESTINATION \"${INSTALL_PKGCONFIG_DIR}\")\nendif()\n\n#============================================================================\n# Example binaries\n#============================================================================\n\nadd_executable(example test/example.c)\ntarget_link_libraries(example zlib)\nadd_test(example example)\n\nadd_executable(minigzip test/minigzip.c)\ntarget_link_libraries(minigzip zlib)\n\nif(HAVE_OFF64_T)\n    add_executable(example64 test/example.c)\n    target_link_libraries(example64 zlib)\n    set_target_properties(example64 PROPERTIES COMPILE_FLAGS \"-D_FILE_OFFSET_BITS=64\")\n    add_test(example64 example64)\n\n    add_executable(minigzip64 test/minigzip.c)\n    target_link_libraries(minigzip64 zlib)\n    set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS \"-D_FILE_OFFSET_BITS=64\")\nendif()\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/ChangeLog",
    "content": "\n                ChangeLog file for zlib\n\nChanges in 1.2.8 (28 Apr 2013)\n- Update contrib/minizip/iowin32.c for Windows RT [Vollant]\n- Do not force Z_CONST for C++\n- Clean up contrib/vstudio [Ro]\n- Correct spelling error in zlib.h\n- Fix mixed line endings in contrib/vstudio\n\nChanges in 1.2.7.3 (13 Apr 2013)\n- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc\n\nChanges in 1.2.7.2 (13 Apr 2013)\n- Change check for a four-byte type back to hexadecimal\n- Fix typo in win32/Makefile.msc\n- Add casts in gzwrite.c for pointer differences\n\nChanges in 1.2.7.1 (24 Mar 2013)\n- Replace use of unsafe string functions with snprintf if available\n- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink]\n- Fix gzgetc undefine when Z_PREFIX set [Turk]\n- Eliminate use of mktemp in Makefile (not always available)\n- Fix bug in 'F' mode for gzopen()\n- Add inflateGetDictionary() function\n- Correct comment in deflate.h\n- Use _snprintf for snprintf in Microsoft C\n- On Darwin, only use /usr/bin/libtool if libtool is not Apple\n- Delete \"--version\" file if created by \"ar --version\" [Richard G.]\n- Fix configure check for veracity of compiler error return codes\n- Fix CMake compilation of static lib for MSVC2010 x64\n- Remove unused variable in infback9.c\n- Fix argument checks in gzlog_compress() and gzlog_write()\n- Clean up the usage of z_const and respect const usage within zlib\n- Clean up examples/gzlog.[ch] comparisons of different types\n- Avoid shift equal to bits in type (caused endless loop)\n- Fix unintialized value bug in gzputc() introduced by const patches\n- Fix memory allocation error in examples/zran.c [Nor]\n- Fix bug where gzopen(), gzclose() would write an empty file\n- Fix bug in gzclose() when gzwrite() runs out of memory\n- Check for input buffer malloc failure in examples/gzappend.c\n- Add note to contrib/blast to use binary mode in stdio\n- Fix comparisons of differently signed integers in contrib/blast\n- Check for invalid code length codes in contrib/puff\n- Fix serious but very rare decompression bug in inftrees.c\n- Update inflateBack() comments, since inflate() can be faster\n- Use underscored I/O function names for WINAPI_FAMILY\n- Add _tr_flush_bits to the external symbols prefixed by --zprefix\n- Add contrib/vstudio/vc10 pre-build step for static only\n- Quote --version-script argument in CMakeLists.txt\n- Don't specify --version-script on Apple platforms in CMakeLists.txt\n- Fix casting error in contrib/testzlib/testzlib.c\n- Fix types in contrib/minizip to match result of get_crc_table()\n- Simplify contrib/vstudio/vc10 with 'd' suffix\n- Add TOP support to win32/Makefile.msc\n- Suport i686 and amd64 assembler builds in CMakeLists.txt\n- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h\n- Add vc11 and vc12 build files to contrib/vstudio\n- Add gzvprintf() as an undocumented function in zlib\n- Fix configure for Sun shell\n- Remove runtime check in configure for four-byte integer type\n- Add casts and consts to ease user conversion to C++\n- Add man pages for minizip and miniunzip\n- In Makefile uninstall, don't rm if preceding cd fails\n- Do not return Z_BUF_ERROR if deflateParam() has nothing to write\n\nChanges in 1.2.7 (2 May 2012)\n- Replace use of memmove() with a simple copy for portability\n- Test for existence of strerror\n- Restore gzgetc_ for backward compatibility with 1.2.6\n- Fix build with non-GNU make on Solaris\n- Require gcc 4.0 or later on Mac OS X to use the hidden attribute\n- Include unistd.h for Watcom C\n- Use __WATCOMC__ instead of __WATCOM__\n- Do not use the visibility attribute if NO_VIZ defined\n- Improve the detection of no hidden visibility attribute\n- Avoid using __int64 for gcc or solo compilation\n- Cast to char * in gzprintf to avoid warnings [Zinser]\n- Fix make_vms.com for VAX [Zinser]\n- Don't use library or built-in byte swaps\n- Simplify test and use of gcc hidden attribute\n- Fix bug in gzclose_w() when gzwrite() fails to allocate memory\n- Add \"x\" (O_EXCL) and \"e\" (O_CLOEXEC) modes support to gzopen()\n- Fix bug in test/minigzip.c for configure --solo\n- Fix contrib/vstudio project link errors [Mohanathas]\n- Add ability to choose the builder in make_vms.com [Schweda]\n- Add DESTDIR support to mingw32 win32/Makefile.gcc\n- Fix comments in win32/Makefile.gcc for proper usage\n- Allow overriding the default install locations for cmake\n- Generate and install the pkg-config file with cmake\n- Build both a static and a shared version of zlib with cmake\n- Include version symbols for cmake builds\n- If using cmake with MSVC, add the source directory to the includes\n- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta]\n- Move obsolete emx makefile to old [Truta]\n- Allow the use of -Wundef when compiling or using zlib\n- Avoid the use of the -u option with mktemp\n- Improve inflate() documentation on the use of Z_FINISH\n- Recognize clang as gcc\n- Add gzopen_w() in Windows for wide character path names\n- Rename zconf.h in CMakeLists.txt to move it out of the way\n- Add source directory in CMakeLists.txt for building examples\n- Look in build directory for zlib.pc in CMakeLists.txt\n- Remove gzflags from zlibvc.def in vc9 and vc10\n- Fix contrib/minizip compilation in the MinGW environment\n- Update ./configure for Solaris, support --64 [Mooney]\n- Remove -R. from Solaris shared build (possible security issue)\n- Avoid race condition for parallel make (-j) running example\n- Fix type mismatch between get_crc_table() and crc_table\n- Fix parsing of version with \"-\" in CMakeLists.txt [Snider, Ziegler]\n- Fix the path to zlib.map in CMakeLists.txt\n- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe]\n- Add instructions to win32/Makefile.gcc for shared install [Torri]\n\nChanges in 1.2.6.1 (12 Feb 2012)\n- Avoid the use of the Objective-C reserved name \"id\"\n- Include io.h in gzguts.h for Microsoft compilers\n- Fix problem with ./configure --prefix and gzgetc macro\n- Include gz_header definition when compiling zlib solo\n- Put gzflags() functionality back in zutil.c\n- Avoid library header include in crc32.c for Z_SOLO\n- Use name in GCC_CLASSIC as C compiler for coverage testing, if set\n- Minor cleanup in contrib/minizip/zip.c [Vollant]\n- Update make_vms.com [Zinser]\n- Remove unnecessary gzgetc_ function\n- Use optimized byte swap operations for Microsoft and GNU [Snyder]\n- Fix minor typo in zlib.h comments [Rzesniowiecki]\n\nChanges in 1.2.6 (29 Jan 2012)\n- Update the Pascal interface in contrib/pascal\n- Fix function numbers for gzgetc_ in zlibvc.def files\n- Fix configure.ac for contrib/minizip [Schiffer]\n- Fix large-entry detection in minizip on 64-bit systems [Schiffer]\n- Have ./configure use the compiler return code for error indication\n- Fix CMakeLists.txt for cross compilation [McClure]\n- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes]\n- Fix compilation of contrib/minizip on FreeBSD [Marquez]\n- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath]\n- Include io.h for Turbo C / Borland C on all platforms [Truta]\n- Make version explicit in contrib/minizip/configure.ac [Bosmans]\n- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant]\n- Minor cleanup up contrib/minizip/unzip.c [Vollant]\n- Fix bug when compiling minizip with C++ [Vollant]\n- Protect for long name and extra fields in contrib/minizip [Vollant]\n- Avoid some warnings in contrib/minizip [Vollant]\n- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip\n- Add missing libs to minizip linker command\n- Add support for VPATH builds in contrib/minizip\n- Add an --enable-demos option to contrib/minizip/configure\n- Add the generation of configure.log by ./configure\n- Exit when required parameters not provided to win32/Makefile.gcc\n- Have gzputc return the character written instead of the argument\n- Use the -m option on ldconfig for BSD systems [Tobias]\n- Correct in zlib.map when deflateResetKeep was added\n\nChanges in 1.2.5.3 (15 Jan 2012)\n- Restore gzgetc function for binary compatibility\n- Do not use _lseeki64 under Borland C++ [Truta]\n- Update win32/Makefile.msc to build test/*.c [Truta]\n- Remove old/visualc6 given CMakefile and other alternatives\n- Update AS400 build files and documentation [Monnerat]\n- Update win32/Makefile.gcc to build test/*.c [Truta]\n- Permit stronger flushes after Z_BLOCK flushes\n- Avoid extraneous empty blocks when doing empty flushes\n- Permit Z_NULL arguments to deflatePending\n- Allow deflatePrime() to insert bits in the middle of a stream\n- Remove second empty static block for Z_PARTIAL_FLUSH\n- Write out all of the available bits when using Z_BLOCK\n- Insert the first two strings in the hash table after a flush\n\nChanges in 1.2.5.2 (17 Dec 2011)\n- fix ld error: unable to find version dependency 'ZLIB_1.2.5'\n- use relative symlinks for shared libs\n- Avoid searching past window for Z_RLE strategy\n- Assure that high-water mark initialization is always applied in deflate\n- Add assertions to fill_window() in deflate.c to match comments\n- Update python link in README\n- Correct spelling error in gzread.c\n- Fix bug in gzgets() for a concatenated empty gzip stream\n- Correct error in comment for gz_make()\n- Change gzread() and related to ignore junk after gzip streams\n- Allow gzread() and related to continue after gzclearerr()\n- Allow gzrewind() and gzseek() after a premature end-of-file\n- Simplify gzseek() now that raw after gzip is ignored\n- Change gzgetc() to a macro for speed (~40% speedup in testing)\n- Fix gzclose() to return the actual error last encountered\n- Always add large file support for windows\n- Include zconf.h for windows large file support\n- Include zconf.h.cmakein for windows large file support\n- Update zconf.h.cmakein on make distclean\n- Merge vestigial vsnprintf determination from zutil.h to gzguts.h\n- Clarify how gzopen() appends in zlib.h comments\n- Correct documentation of gzdirect() since junk at end now ignored\n- Add a transparent write mode to gzopen() when 'T' is in the mode\n- Update python link in zlib man page\n- Get inffixed.h and MAKEFIXED result to match\n- Add a ./config --solo option to make zlib subset with no libary use\n- Add undocumented inflateResetKeep() function for CAB file decoding\n- Add --cover option to ./configure for gcc coverage testing\n- Add #define ZLIB_CONST option to use const in the z_stream interface\n- Add comment to gzdopen() in zlib.h to use dup() when using fileno()\n- Note behavior of uncompress() to provide as much data as it can\n- Add files in contrib/minizip to aid in building libminizip\n- Split off AR options in Makefile.in and configure\n- Change ON macro to Z_ARG to avoid application conflicts\n- Facilitate compilation with Borland C++ for pragmas and vsnprintf\n- Include io.h for Turbo C / Borland C++\n- Move example.c and minigzip.c to test/\n- Simplify incomplete code table filling in inflate_table()\n- Remove code from inflate.c and infback.c that is impossible to execute\n- Test the inflate code with full coverage\n- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw)\n- Add deflateResetKeep and fix inflateResetKeep to retain dictionary\n- Fix gzwrite.c to accommodate reduced memory zlib compilation\n- Have inflate() with Z_FINISH avoid the allocation of a window\n- Do not set strm->adler when doing raw inflate\n- Fix gzeof() to behave just like feof() when read is not past end of file\n- Fix bug in gzread.c when end-of-file is reached\n- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF\n- Document gzread() capability to read concurrently written files\n- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo]\n\nChanges in 1.2.5.1 (10 Sep 2011)\n- Update FAQ entry on shared builds (#13)\n- Avoid symbolic argument to chmod in Makefile.in\n- Fix bug and add consts in contrib/puff [Oberhumer]\n- Update contrib/puff/zeros.raw test file to have all block types\n- Add full coverage test for puff in contrib/puff/Makefile\n- Fix static-only-build install in Makefile.in\n- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno]\n- Add libz.a dependency to shared in Makefile.in for parallel builds\n- Spell out \"number\" (instead of \"nb\") in zlib.h for total_in, total_out\n- Replace $(...) with `...` in configure for non-bash sh [Bowler]\n- Add darwin* to Darwin* and solaris* to SunOS\\ 5* in configure [Groffen]\n- Add solaris* to Linux* in configure to allow gcc use [Groffen]\n- Add *bsd* to Linux* case in configure [Bar-Lev]\n- Add inffast.obj to dependencies in win32/Makefile.msc\n- Correct spelling error in deflate.h [Kohler]\n- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc\n- Add test to configure for GNU C looking for gcc in output of $cc -v\n- Add zlib.pc generation to win32/Makefile.gcc [Weigelt]\n- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not\n- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense\n- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser)\n- Make stronger test in zconf.h to include unistd.h for LFS\n- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack]\n- Fix zlib.h LFS support when Z_PREFIX used\n- Add updated as400 support (removed from old) [Monnerat]\n- Avoid deflate sensitivity to volatile input data\n- Avoid division in adler32_combine for NO_DIVIDE\n- Clarify the use of Z_FINISH with deflateBound() amount of space\n- Set binary for output file in puff.c\n- Use u4 type for crc_table to avoid conversion warnings\n- Apply casts in zlib.h to avoid conversion warnings\n- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller]\n- Improve inflateSync() documentation to note indeterminancy\n- Add deflatePending() function to return the amount of pending output\n- Correct the spelling of \"specification\" in FAQ [Randers-Pehrson]\n- Add a check in configure for stdarg.h, use for gzprintf()\n- Check that pointers fit in ints when gzprint() compiled old style\n- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler]\n- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt]\n- Add debug records in assmebler code [Londer]\n- Update RFC references to use http://tools.ietf.org/html/... [Li]\n- Add --archs option, use of libtool to configure for Mac OS X [Borstel]\n\nChanges in 1.2.5 (19 Apr 2010)\n- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev]\n- Default to libdir as sharedlibdir in configure [Nieder]\n- Update copyright dates on modified source files\n- Update trees.c to be able to generate modified trees.h\n- Exit configure for MinGW, suggesting win32/Makefile.gcc\n- Check for NULL path in gz_open [Homurlu]\n\nChanges in 1.2.4.5 (18 Apr 2010)\n- Set sharedlibdir in configure [Torok]\n- Set LDFLAGS in Makefile.in [Bar-Lev]\n- Avoid mkdir objs race condition in Makefile.in [Bowler]\n- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays\n- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C\n- Don't use hidden attribute when it is a warning generator (e.g. Solaris)\n\nChanges in 1.2.4.4 (18 Apr 2010)\n- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok]\n- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty\n- Try to use bash or ksh regardless of functionality of /bin/sh\n- Fix configure incompatibility with NetBSD sh\n- Remove attempt to run under bash or ksh since have better NetBSD fix\n- Fix win32/Makefile.gcc for MinGW [Bar-Lev]\n- Add diagnostic messages when using CROSS_PREFIX in configure\n- Added --sharedlibdir option to configure [Weigelt]\n- Use hidden visibility attribute when available [Frysinger]\n\nChanges in 1.2.4.3 (10 Apr 2010)\n- Only use CROSS_PREFIX in configure for ar and ranlib if they exist\n- Use CROSS_PREFIX for nm [Bar-Lev]\n- Assume _LARGEFILE64_SOURCE defined is equivalent to true\n- Avoid use of undefined symbols in #if with && and ||\n- Make *64 prototypes in gzguts.h consistent with functions\n- Add -shared load option for MinGW in configure [Bowler]\n- Move z_off64_t to public interface, use instead of off64_t\n- Remove ! from shell test in configure (not portable to Solaris)\n- Change +0 macro tests to -0 for possibly increased portability\n\nChanges in 1.2.4.2 (9 Apr 2010)\n- Add consistent carriage returns to readme.txt's in masmx86 and masmx64\n- Really provide prototypes for *64 functions when building without LFS\n- Only define unlink() in minigzip.c if unistd.h not included\n- Update README to point to contrib/vstudio project files\n- Move projects/vc6 to old/ and remove projects/\n- Include stdlib.h in minigzip.c for setmode() definition under WinCE\n- Clean up assembler builds in win32/Makefile.msc [Rowe]\n- Include sys/types.h for Microsoft for off_t definition\n- Fix memory leak on error in gz_open()\n- Symbolize nm as $NM in configure [Weigelt]\n- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt]\n- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined\n- Fix bug in gzeof() to take into account unused input data\n- Avoid initialization of structures with variables in puff.c\n- Updated win32/README-WIN32.txt [Rowe]\n\nChanges in 1.2.4.1 (28 Mar 2010)\n- Remove the use of [a-z] constructs for sed in configure [gentoo 310225]\n- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech]\n- Restore \"for debugging\" comment on sprintf() in gzlib.c\n- Remove fdopen for MVS from gzguts.h\n- Put new README-WIN32.txt in win32 [Rowe]\n- Add check for shell to configure and invoke another shell if needed\n- Fix big fat stinking bug in gzseek() on uncompressed files\n- Remove vestigial F_OPEN64 define in zutil.h\n- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE\n- Avoid errors on non-LFS systems when applications define LFS macros\n- Set EXE to \".exe\" in configure for MINGW [Kahle]\n- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill]\n- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev]\n- Add DLL install in win32/makefile.gcc [Bar-Lev]\n- Allow Linux* or linux* from uname in configure [Bar-Lev]\n- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev]\n- Add cross-compilation prefixes to configure [Bar-Lev]\n- Match type exactly in gz_load() invocation in gzread.c\n- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func\n- Provide prototypes for *64 functions when building zlib without LFS\n- Don't use -lc when linking shared library on MinGW\n- Remove errno.h check in configure and vestigial errno code in zutil.h\n\nChanges in 1.2.4 (14 Mar 2010)\n- Fix VER3 extraction in configure for no fourth subversion\n- Update zlib.3, add docs to Makefile.in to make .pdf out of it\n- Add zlib.3.pdf to distribution\n- Don't set error code in gzerror() if passed pointer is NULL\n- Apply destination directory fixes to CMakeLists.txt [Lowman]\n- Move #cmakedefine's to a new zconf.in.cmakein\n- Restore zconf.h for builds that don't use configure or cmake\n- Add distclean to dummy Makefile for convenience\n- Update and improve INDEX, README, and FAQ\n- Update CMakeLists.txt for the return of zconf.h [Lowman]\n- Update contrib/vstudio/vc9 and vc10 [Vollant]\n- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc\n- Apply license and readme changes to contrib/asm686 [Raiter]\n- Check file name lengths and add -c option in minigzip.c [Li]\n- Update contrib/amd64 and contrib/masmx86/ [Vollant]\n- Avoid use of \"eof\" parameter in trees.c to not shadow library variable\n- Update make_vms.com for removal of zlibdefs.h [Zinser]\n- Update assembler code and vstudio projects in contrib [Vollant]\n- Remove outdated assembler code contrib/masm686 and contrib/asm586\n- Remove old vc7 and vc8 from contrib/vstudio\n- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe]\n- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open()\n- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant]\n- Remove *64 functions from win32/zlib.def (they're not 64-bit yet)\n- Fix bug in void-returning vsprintf() case in gzwrite.c\n- Fix name change from inflate.h in contrib/inflate86/inffas86.c\n- Check if temporary file exists before removing in make_vms.com [Zinser]\n- Fix make install and uninstall for --static option\n- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta]\n- Update readme.txt in contrib/masmx64 and masmx86 to assemble\n\nChanges in 1.2.3.9 (21 Feb 2010)\n- Expunge gzio.c\n- Move as400 build information to old\n- Fix updates in contrib/minizip and contrib/vstudio\n- Add const to vsnprintf test in configure to avoid warnings [Weigelt]\n- Delete zconf.h (made by configure) [Weigelt]\n- Change zconf.in.h to zconf.h.in per convention [Weigelt]\n- Check for NULL buf in gzgets()\n- Return empty string for gzgets() with len == 1 (like fgets())\n- Fix description of gzgets() in zlib.h for end-of-file, NULL return\n- Update minizip to 1.1 [Vollant]\n- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c\n- Note in zlib.h that gzerror() should be used to distinguish from EOF\n- Remove use of snprintf() from gzlib.c\n- Fix bug in gzseek()\n- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant]\n- Fix zconf.h generation in CMakeLists.txt [Lowman]\n- Improve comments in zconf.h where modified by configure\n\nChanges in 1.2.3.8 (13 Feb 2010)\n- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer]\n- Use z_off64_t in gz_zero() and gz_skip() to match state->skip\n- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t)\n- Revert to Makefile.in from 1.2.3.6 (live with the clutter)\n- Fix missing error return in gzflush(), add zlib.h note\n- Add *64 functions to zlib.map [Levin]\n- Fix signed/unsigned comparison in gz_comp()\n- Use SFLAGS when testing shared linking in configure\n- Add --64 option to ./configure to use -m64 with gcc\n- Fix ./configure --help to correctly name options\n- Have make fail if a test fails [Levin]\n- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson]\n- Remove assembler object files from contrib\n\nChanges in 1.2.3.7 (24 Jan 2010)\n- Always gzopen() with O_LARGEFILE if available\n- Fix gzdirect() to work immediately after gzopen() or gzdopen()\n- Make gzdirect() more precise when the state changes while reading\n- Improve zlib.h documentation in many places\n- Catch memory allocation failure in gz_open()\n- Complete close operation if seek forward in gzclose_w() fails\n- Return Z_ERRNO from gzclose_r() if close() fails\n- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL\n- Return zero for gzwrite() errors to match zlib.h description\n- Return -1 on gzputs() error to match zlib.h description\n- Add zconf.in.h to allow recovery from configure modification [Weigelt]\n- Fix static library permissions in Makefile.in [Weigelt]\n- Avoid warnings in configure tests that hide functionality [Weigelt]\n- Add *BSD and DragonFly to Linux case in configure [gentoo 123571]\n- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212]\n- Avoid access of uninitialized data for first inflateReset2 call [Gomes]\n- Keep object files in subdirectories to reduce the clutter somewhat\n- Remove default Makefile and zlibdefs.h, add dummy Makefile\n- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_\n- Remove zlibdefs.h completely -- modify zconf.h instead\n\nChanges in 1.2.3.6 (17 Jan 2010)\n- Avoid void * arithmetic in gzread.c and gzwrite.c\n- Make compilers happier with const char * for gz_error message\n- Avoid unused parameter warning in inflate.c\n- Avoid signed-unsigned comparison warning in inflate.c\n- Indent #pragma's for traditional C\n- Fix usage of strwinerror() in glib.c, change to gz_strwinerror()\n- Correct email address in configure for system options\n- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser]\n- Update zlib.map [Brown]\n- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok]\n- Apply various fixes to CMakeLists.txt [Lowman]\n- Add checks on len in gzread() and gzwrite()\n- Add error message for no more room for gzungetc()\n- Remove zlib version check in gzwrite()\n- Defer compression of gzprintf() result until need to\n- Use snprintf() in gzdopen() if available\n- Remove USE_MMAP configuration determination (only used by minigzip)\n- Remove examples/pigz.c (available separately)\n- Update examples/gun.c to 1.6\n\nChanges in 1.2.3.5 (8 Jan 2010)\n- Add space after #if in zutil.h for some compilers\n- Fix relatively harmless bug in deflate_fast() [Exarevsky]\n- Fix same problem in deflate_slow()\n- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown]\n- Add deflate_rle() for faster Z_RLE strategy run-length encoding\n- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding\n- Change name of \"write\" variable in inffast.c to avoid library collisions\n- Fix premature EOF from gzread() in gzio.c [Brown]\n- Use zlib header window size if windowBits is 0 in inflateInit2()\n- Remove compressBound() call in deflate.c to avoid linking compress.o\n- Replace use of errno in gz* with functions, support WinCE [Alves]\n- Provide alternative to perror() in minigzip.c for WinCE [Alves]\n- Don't use _vsnprintf on later versions of MSVC [Lowman]\n- Add CMake build script and input file [Lowman]\n- Update contrib/minizip to 1.1 [Svensson, Vollant]\n- Moved nintendods directory from contrib to .\n- Replace gzio.c with a new set of routines with the same functionality\n- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above\n- Update contrib/minizip to 1.1b\n- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h\n\nChanges in 1.2.3.4 (21 Dec 2009)\n- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility\n- Update comments in configure and Makefile.in for default --shared\n- Fix test -z's in configure [Marquess]\n- Build examplesh and minigzipsh when not testing\n- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h\n- Import LDFLAGS from the environment in configure\n- Fix configure to populate SFLAGS with discovered CFLAGS options\n- Adapt make_vms.com to the new Makefile.in [Zinser]\n- Add zlib2ansi script for C++ compilation [Marquess]\n- Add _FILE_OFFSET_BITS=64 test to make test (when applicable)\n- Add AMD64 assembler code for longest match to contrib [Teterin]\n- Include options from $SFLAGS when doing $LDSHARED\n- Simplify 64-bit file support by introducing z_off64_t type\n- Make shared object files in objs directory to work around old Sun cc\n- Use only three-part version number for Darwin shared compiles\n- Add rc option to ar in Makefile.in for when ./configure not run\n- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4*\n- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile\n- Protect against _FILE_OFFSET_BITS being defined when compiling zlib\n- Rename Makefile.in targets allstatic to static and allshared to shared\n- Fix static and shared Makefile.in targets to be independent\n- Correct error return bug in gz_open() by setting state [Brown]\n- Put spaces before ;;'s in configure for better sh compatibility\n- Add pigz.c (parallel implementation of gzip) to examples/\n- Correct constant in crc32.c to UL [Leventhal]\n- Reject negative lengths in crc32_combine()\n- Add inflateReset2() function to work like inflateEnd()/inflateInit2()\n- Include sys/types.h for _LARGEFILE64_SOURCE [Brown]\n- Correct typo in doc/algorithm.txt [Janik]\n- Fix bug in adler32_combine() [Zhu]\n- Catch missing-end-of-block-code error in all inflates and in puff\n    Assures that random input to inflate eventually results in an error\n- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/\n- Update ENOUGH and its usage to reflect discovered bounds\n- Fix gzerror() error report on empty input file [Brown]\n- Add ush casts in trees.c to avoid pedantic runtime errors\n- Fix typo in zlib.h uncompress() description [Reiss]\n- Correct inflate() comments with regard to automatic header detection\n- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays)\n- Put new version of gzlog (2.0) in examples with interruption recovery\n- Add puff compile option to permit invalid distance-too-far streams\n- Add puff TEST command options, ability to read piped input\n- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but\n  _LARGEFILE64_SOURCE not defined\n- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart\n- Fix deflateSetDictionary() to use all 32K for output consistency\n- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h)\n- Clear bytes after deflate lookahead to avoid use of uninitialized data\n- Change a limit in inftrees.c to be more transparent to Coverity Prevent\n- Update win32/zlib.def with exported symbols from zlib.h\n- Correct spelling errors in zlib.h [Willem, Sobrado]\n- Allow Z_BLOCK for deflate() to force a new block\n- Allow negative bits in inflatePrime() to delete existing bit buffer\n- Add Z_TREES flush option to inflate() to return at end of trees\n- Add inflateMark() to return current state information for random access\n- Add Makefile for NintendoDS to contrib [Costa]\n- Add -w in configure compile tests to avoid spurious warnings [Beucler]\n- Fix typos in zlib.h comments for deflateSetDictionary()\n- Fix EOF detection in transparent gzread() [Maier]\n\nChanges in 1.2.3.3 (2 October 2006)\n- Make --shared the default for configure, add a --static option\n- Add compile option to permit invalid distance-too-far streams\n- Add inflateUndermine() function which is required to enable above\n- Remove use of \"this\" variable name for C++ compatibility [Marquess]\n- Add testing of shared library in make test, if shared library built\n- Use ftello() and fseeko() if available instead of ftell() and fseek()\n- Provide two versions of all functions that use the z_off_t type for\n  binary compatibility -- a normal version and a 64-bit offset version,\n  per the Large File Support Extension when _LARGEFILE64_SOURCE is\n  defined; use the 64-bit versions by default when _FILE_OFFSET_BITS\n  is defined to be 64\n- Add a --uname= option to configure to perhaps help with cross-compiling\n\nChanges in 1.2.3.2 (3 September 2006)\n- Turn off silly Borland warnings [Hay]\n- Use off64_t and define _LARGEFILE64_SOURCE when present\n- Fix missing dependency on inffixed.h in Makefile.in\n- Rig configure --shared to build both shared and static [Teredesai, Truta]\n- Remove zconf.in.h and instead create a new zlibdefs.h file\n- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant]\n- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt]\n\nChanges in 1.2.3.1 (16 August 2006)\n- Add watcom directory with OpenWatcom make files [Daniel]\n- Remove #undef of FAR in zconf.in.h for MVS [Fedtke]\n- Update make_vms.com [Zinser]\n- Use -fPIC for shared build in configure [Teredesai, Nicholson]\n- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen]\n- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bck]\n- Add some FAQ entries about the contrib directory\n- Update the MVS question in the FAQ\n- Avoid extraneous reads after EOF in gzio.c [Brown]\n- Correct spelling of \"successfully\" in gzio.c [Randers-Pehrson]\n- Add comments to zlib.h about gzerror() usage [Brown]\n- Set extra flags in gzip header in gzopen() like deflate() does\n- Make configure options more compatible with double-dash conventions\n  [Weigelt]\n- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen]\n- Fix uninstall target in Makefile.in [Truta]\n- Add pkgconfig support [Weigelt]\n- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt]\n- Replace set_data_type() with a more accurate detect_data_type() in\n  trees.c, according to the txtvsbin.txt document [Truta]\n- Swap the order of #include <stdio.h> and #include \"zlib.h\" in\n  gzio.c, example.c and minigzip.c [Truta]\n- Shut up annoying VS2005 warnings about standard C deprecation [Rowe,\n  Truta] (where?)\n- Fix target \"clean\" from win32/Makefile.bor [Truta]\n- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe]\n- Update zlib www home address in win32/DLL_FAQ.txt [Truta]\n- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove]\n- Enable browse info in the \"Debug\" and \"ASM Debug\" configurations in\n  the Visual C++ 6 project, and set (non-ASM) \"Debug\" as default [Truta]\n- Add pkgconfig support [Weigelt]\n- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h,\n  for use in win32/zlib1.rc [Polushin, Rowe, Truta]\n- Add a document that explains the new text detection scheme to\n  doc/txtvsbin.txt [Truta]\n- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta]\n- Move algorithm.txt into doc/ [Truta]\n- Synchronize FAQ with website\n- Fix compressBound(), was low for some pathological cases [Fearnley]\n- Take into account wrapper variations in deflateBound()\n- Set examples/zpipe.c input and output to binary mode for Windows\n- Update examples/zlib_how.html with new zpipe.c (also web site)\n- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems\n  that gcc became pickier in 4.0)\n- Add zlib.map for Linux: \"All symbols from zlib-1.1.4 remain\n  un-versioned, the patch adds versioning only for symbols introduced in\n  zlib-1.2.0 or later.  It also declares as local those symbols which are\n  not designed to be exported.\" [Levin]\n- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure\n- Do not initialize global static by default in trees.c, add a response\n  NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess]\n- Don't use strerror() in gzio.c under WinCE [Yakimov]\n- Don't use errno.h in zutil.h under WinCE [Yakimov]\n- Move arguments for AR to its usage to allow replacing ar [Marot]\n- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson]\n- Improve inflateInit() and inflateInit2() documentation\n- Fix structure size comment in inflate.h\n- Change configure help option from --h* to --help [Santos]\n\nChanges in 1.2.3 (18 July 2005)\n- Apply security vulnerability fixes to contrib/infback9 as well\n- Clean up some text files (carriage returns, trailing space)\n- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant]\n\nChanges in 1.2.2.4 (11 July 2005)\n- Add inflatePrime() function for starting inflation at bit boundary\n- Avoid some Visual C warnings in deflate.c\n- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit\n  compile\n- Fix some spelling errors in comments [Betts]\n- Correct inflateInit2() error return documentation in zlib.h\n- Add zran.c example of compressed data random access to examples\n  directory, shows use of inflatePrime()\n- Fix cast for assignments to strm->state in inflate.c and infback.c\n- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]\n- Move declarations of gf2 functions to right place in crc32.c [Oberhumer]\n- Add cast in trees.c t avoid a warning [Oberhumer]\n- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer]\n- Update make_vms.com [Zinser]\n- Initialize state->write in inflateReset() since copied in inflate_fast()\n- Be more strict on incomplete code sets in inflate_table() and increase\n  ENOUGH and MAXD -- this repairs a possible security vulnerability for\n  invalid inflate input.  Thanks to Tavis Ormandy and Markus Oberhumer for\n  discovering the vulnerability and providing test cases.\n- Add ia64 support to configure for HP-UX [Smith]\n- Add error return to gzread() for format or i/o error [Levin]\n- Use malloc.h for OS/2 [Necasek]\n\nChanges in 1.2.2.3 (27 May 2005)\n- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile\n- Typecast fread() return values in gzio.c [Vollant]\n- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)\n- Fix crc check bug in gzread() after gzungetc() [Heiner]\n- Add the deflateTune() function to adjust internal compression parameters\n- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)\n- Remove an incorrect assertion in examples/zpipe.c\n- Add C++ wrapper in infback9.h [Donais]\n- Fix bug in inflateCopy() when decoding fixed codes\n- Note in zlib.h how much deflateSetDictionary() actually uses\n- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)\n- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]\n- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]\n- Add gzdirect() function to indicate transparent reads\n- Update contrib/minizip [Vollant]\n- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]\n- Add casts in crc32.c to avoid warnings [Oberhumer]\n- Add contrib/masmx64 [Vollant]\n- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]\n\nChanges in 1.2.2.2 (30 December 2004)\n- Replace structure assignments in deflate.c and inflate.c with zmemcpy to\n  avoid implicit memcpy calls (portability for no-library compilation)\n- Increase sprintf() buffer size in gzdopen() to allow for large numbers\n- Add INFLATE_STRICT to check distances against zlib header\n- Improve WinCE errno handling and comments [Chang]\n- Remove comment about no gzip header processing in FAQ\n- Add Z_FIXED strategy option to deflateInit2() to force fixed trees\n- Add updated make_vms.com [Coghlan], update README\n- Create a new \"examples\" directory, move gzappend.c there, add zpipe.c,\n  fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.\n- Add FAQ entry and comments in deflate.c on uninitialized memory access\n- Add Solaris 9 make options in configure [Gilbert]\n- Allow strerror() usage in gzio.c for STDC\n- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]\n- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]\n- Use z_off_t for adler32_combine() and crc32_combine() lengths\n- Make adler32() much faster for small len\n- Use OS_CODE in deflate() default gzip header\n\nChanges in 1.2.2.1 (31 October 2004)\n- Allow inflateSetDictionary() call for raw inflate\n- Fix inflate header crc check bug for file names and comments\n- Add deflateSetHeader() and gz_header structure for custom gzip headers\n- Add inflateGetheader() to retrieve gzip headers\n- Add crc32_combine() and adler32_combine() functions\n- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list\n- Use zstreamp consistently in zlib.h (inflate_back functions)\n- Remove GUNZIP condition from definition of inflate_mode in inflate.h\n  and in contrib/inflate86/inffast.S [Truta, Anderson]\n- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]\n- Update projects/README.projects and projects/visualc6 [Truta]\n- Update win32/DLL_FAQ.txt [Truta]\n- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]\n- Deprecate Z_ASCII; use Z_TEXT instead [Truta]\n- Use a new algorithm for setting strm->data_type in trees.c [Truta]\n- Do not define an exit() prototype in zutil.c unless DEBUG defined\n- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]\n- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()\n- Fix Darwin build version identification [Peterson]\n\nChanges in 1.2.2 (3 October 2004)\n- Update zlib.h comments on gzip in-memory processing\n- Set adler to 1 in inflateReset() to support Java test suite [Walles]\n- Add contrib/dotzlib [Ravn]\n- Update win32/DLL_FAQ.txt [Truta]\n- Update contrib/minizip [Vollant]\n- Move contrib/visual-basic.txt to old/ [Truta]\n- Fix assembler builds in projects/visualc6/ [Truta]\n\nChanges in 1.2.1.2 (9 September 2004)\n- Update INDEX file\n- Fix trees.c to update strm->data_type (no one ever noticed!)\n- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]\n- Add \"volatile\" to crc table flag declaration (for DYNAMIC_CRC_TABLE)\n- Add limited multitasking protection to DYNAMIC_CRC_TABLE\n- Add NO_vsnprintf for VMS in zutil.h [Mozilla]\n- Don't declare strerror() under VMS [Mozilla]\n- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize\n- Update contrib/ada [Anisimkov]\n- Update contrib/minizip [Vollant]\n- Fix configure to not hardcode directories for Darwin [Peterson]\n- Fix gzio.c to not return error on empty files [Brown]\n- Fix indentation; update version in contrib/delphi/ZLib.pas and\n  contrib/pascal/zlibpas.pas [Truta]\n- Update mkasm.bat in contrib/masmx86 [Truta]\n- Update contrib/untgz [Truta]\n- Add projects/README.projects [Truta]\n- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]\n- Update win32/DLL_FAQ.txt [Truta]\n- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]\n- Remove an unnecessary assignment to curr in inftrees.c [Truta]\n- Add OS/2 to exe builds in configure [Poltorak]\n- Remove err dummy parameter in zlib.h [Kientzle]\n\nChanges in 1.2.1.1 (9 January 2004)\n- Update email address in README\n- Several FAQ updates\n- Fix a big fat bug in inftrees.c that prevented decoding valid\n  dynamic blocks with only literals and no distance codes --\n  Thanks to \"Hot Emu\" for the bug report and sample file\n- Add a note to puff.c on no distance codes case.\n\nChanges in 1.2.1 (17 November 2003)\n- Remove a tab in contrib/gzappend/gzappend.c\n- Update some interfaces in contrib for new zlib functions\n- Update zlib version number in some contrib entries\n- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]\n- Support shared libraries on Hurd and KFreeBSD [Brown]\n- Fix error in NO_DIVIDE option of adler32.c\n\nChanges in 1.2.0.8 (4 November 2003)\n- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas\n- Add experimental NO_DIVIDE #define in adler32.c\n    - Possibly faster on some processors (let me know if it is)\n- Correct Z_BLOCK to not return on first inflate call if no wrap\n- Fix strm->data_type on inflate() return to correctly indicate EOB\n- Add deflatePrime() function for appending in the middle of a byte\n- Add contrib/gzappend for an example of appending to a stream\n- Update win32/DLL_FAQ.txt [Truta]\n- Delete Turbo C comment in README [Truta]\n- Improve some indentation in zconf.h [Truta]\n- Fix infinite loop on bad input in configure script [Church]\n- Fix gzeof() for concatenated gzip files [Johnson]\n- Add example to contrib/visual-basic.txt [Michael B.]\n- Add -p to mkdir's in Makefile.in [vda]\n- Fix configure to properly detect presence or lack of printf functions\n- Add AS400 support [Monnerat]\n- Add a little Cygwin support [Wilson]\n\nChanges in 1.2.0.7 (21 September 2003)\n- Correct some debug formats in contrib/infback9\n- Cast a type in a debug statement in trees.c\n- Change search and replace delimiter in configure from % to # [Beebe]\n- Update contrib/untgz to 0.2 with various fixes [Truta]\n- Add build support for Amiga [Nikl]\n- Remove some directories in old that have been updated to 1.2\n- Add dylib building for Mac OS X in configure and Makefile.in\n- Remove old distribution stuff from Makefile\n- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X\n- Update links in README\n\nChanges in 1.2.0.6 (13 September 2003)\n- Minor FAQ updates\n- Update contrib/minizip to 1.00 [Vollant]\n- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]\n- Update POSTINC comment for 68060 [Nikl]\n- Add contrib/infback9 with deflate64 decoding (unsupported)\n- For MVS define NO_vsnprintf and undefine FAR [van Burik]\n- Add pragma for fdopen on MVS [van Burik]\n\nChanges in 1.2.0.5 (8 September 2003)\n- Add OF to inflateBackEnd() declaration in zlib.h\n- Remember start when using gzdopen in the middle of a file\n- Use internal off_t counters in gz* functions to properly handle seeks\n- Perform more rigorous check for distance-too-far in inffast.c\n- Add Z_BLOCK flush option to return from inflate at block boundary\n- Set strm->data_type on return from inflate\n    - Indicate bits unused, if at block boundary, and if in last block\n- Replace size_t with ptrdiff_t in crc32.c, and check for correct size\n- Add condition so old NO_DEFLATE define still works for compatibility\n- FAQ update regarding the Windows DLL [Truta]\n- INDEX update: add qnx entry, remove aix entry [Truta]\n- Install zlib.3 into mandir [Wilson]\n- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]\n- Adapt the zlib interface to the new DLL convention guidelines [Truta]\n- Introduce ZLIB_WINAPI macro to allow the export of functions using\n  the WINAPI calling convention, for Visual Basic [Vollant, Truta]\n- Update msdos and win32 scripts and makefiles [Truta]\n- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]\n- Add contrib/ada [Anisimkov]\n- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]\n- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]\n- Add contrib/masm686 [Truta]\n- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm\n  [Truta, Vollant]\n- Update contrib/delphi; rename to contrib/pascal; add example [Truta]\n- Remove contrib/delphi2; add a new contrib/delphi [Truta]\n- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,\n  and fix some method prototypes [Truta]\n- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip\n  [Truta]\n- Avoid the use of backslash (\\) in contrib/minizip [Vollant]\n- Fix file time handling in contrib/untgz; update makefiles [Truta]\n- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines\n  [Vollant]\n- Remove contrib/vstudio/vc15_16 [Vollant]\n- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]\n- Update README.contrib [Truta]\n- Invert the assignment order of match_head and s->prev[...] in\n  INSERT_STRING [Truta]\n- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings\n  [Truta]\n- Compare function pointers with 0, not with NULL or Z_NULL [Truta]\n- Fix prototype of syncsearch in inflate.c [Truta]\n- Introduce ASMINF macro to be enabled when using an ASM implementation\n  of inflate_fast [Truta]\n- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]\n- Modify test_gzio in example.c to take a single file name as a\n  parameter [Truta]\n- Exit the example.c program if gzopen fails [Truta]\n- Add type casts around strlen in example.c [Truta]\n- Remove casting to sizeof in minigzip.c; give a proper type\n  to the variable compared with SUFFIX_LEN [Truta]\n- Update definitions of STDC and STDC99 in zconf.h [Truta]\n- Synchronize zconf.h with the new Windows DLL interface [Truta]\n- Use SYS16BIT instead of __32BIT__ to distinguish between\n  16- and 32-bit platforms [Truta]\n- Use far memory allocators in small 16-bit memory models for\n  Turbo C [Truta]\n- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in\n  zlibCompileFlags [Truta]\n- Cygwin has vsnprintf [Wilson]\n- In Windows16, OS_CODE is 0, as in MSDOS [Truta]\n- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]\n\nChanges in 1.2.0.4 (10 August 2003)\n- Minor FAQ updates\n- Be more strict when checking inflateInit2's windowBits parameter\n- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well\n- Add gzip wrapper option to deflateInit2 using windowBits\n- Add updated QNX rule in configure and qnx directory [Bonnefoy]\n- Make inflate distance-too-far checks more rigorous\n- Clean up FAR usage in inflate\n- Add casting to sizeof() in gzio.c and minigzip.c\n\nChanges in 1.2.0.3 (19 July 2003)\n- Fix silly error in gzungetc() implementation [Vollant]\n- Update contrib/minizip and contrib/vstudio [Vollant]\n- Fix printf format in example.c\n- Correct cdecl support in zconf.in.h [Anisimkov]\n- Minor FAQ updates\n\nChanges in 1.2.0.2 (13 July 2003)\n- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons\n- Attempt to avoid warnings in crc32.c for pointer-int conversion\n- Add AIX to configure, remove aix directory [Bakker]\n- Add some casts to minigzip.c\n- Improve checking after insecure sprintf() or vsprintf() calls\n- Remove #elif's from crc32.c\n- Change leave label to inf_leave in inflate.c and infback.c to avoid\n  library conflicts\n- Remove inflate gzip decoding by default--only enable gzip decoding by\n  special request for stricter backward compatibility\n- Add zlibCompileFlags() function to return compilation information\n- More typecasting in deflate.c to avoid warnings\n- Remove leading underscore from _Capital #defines [Truta]\n- Fix configure to link shared library when testing\n- Add some Windows CE target adjustments [Mai]\n- Remove #define ZLIB_DLL in zconf.h [Vollant]\n- Add zlib.3 [Rodgers]\n- Update RFC URL in deflate.c and algorithm.txt [Mai]\n- Add zlib_dll_FAQ.txt to contrib [Truta]\n- Add UL to some constants [Truta]\n- Update minizip and vstudio [Vollant]\n- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h\n- Expand use of NO_DUMMY_DECL to avoid all dummy structures\n- Added iostream3 to contrib [Schwardt]\n- Replace rewind() with fseek() for WinCE [Truta]\n- Improve setting of zlib format compression level flags\n    - Report 0 for huffman and rle strategies and for level == 0 or 1\n    - Report 2 only for level == 6\n- Only deal with 64K limit when necessary at compile time [Truta]\n- Allow TOO_FAR check to be turned off at compile time [Truta]\n- Add gzclearerr() function [Souza]\n- Add gzungetc() function\n\nChanges in 1.2.0.1 (17 March 2003)\n- Add Z_RLE strategy for run-length encoding [Truta]\n    - When Z_RLE requested, restrict matches to distance one\n    - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE\n- Correct FASTEST compilation to allow level == 0\n- Clean up what gets compiled for FASTEST\n- Incorporate changes to zconf.in.h [Vollant]\n    - Refine detection of Turbo C need for dummy returns\n    - Refine ZLIB_DLL compilation\n    - Include additional header file on VMS for off_t typedef\n- Try to use _vsnprintf where it supplants vsprintf [Vollant]\n- Add some casts in inffast.c\n- Enchance comments in zlib.h on what happens if gzprintf() tries to\n  write more than 4095 bytes before compression\n- Remove unused state from inflateBackEnd()\n- Remove exit(0) from minigzip.c, example.c\n- Get rid of all those darn tabs\n- Add \"check\" target to Makefile.in that does the same thing as \"test\"\n- Add \"mostlyclean\" and \"maintainer-clean\" targets to Makefile.in\n- Update contrib/inflate86 [Anderson]\n- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]\n- Add msdos and win32 directories with makefiles [Truta]\n- More additions and improvements to the FAQ\n\nChanges in 1.2.0 (9 March 2003)\n- New and improved inflate code\n    - About 20% faster\n    - Does not allocate 32K window unless and until needed\n    - Automatically detects and decompresses gzip streams\n    - Raw inflate no longer needs an extra dummy byte at end\n    - Added inflateBack functions using a callback interface--even faster\n      than inflate, useful for file utilities (gzip, zip)\n    - Added inflateCopy() function to record state for random access on\n      externally generated deflate streams (e.g. in gzip files)\n    - More readable code (I hope)\n- New and improved crc32()\n    - About 50% faster, thanks to suggestions from Rodney Brown\n- Add deflateBound() and compressBound() functions\n- Fix memory leak in deflateInit2()\n- Permit setting dictionary for raw deflate (for parallel deflate)\n- Fix const declaration for gzwrite()\n- Check for some malloc() failures in gzio.c\n- Fix bug in gzopen() on single-byte file 0x1f\n- Fix bug in gzread() on concatenated file with 0x1f at end of buffer\n  and next buffer doesn't start with 0x8b\n- Fix uncompress() to return Z_DATA_ERROR on truncated input\n- Free memory at end of example.c\n- Remove MAX #define in trees.c (conflicted with some libraries)\n- Fix static const's in deflate.c, gzio.c, and zutil.[ch]\n- Declare malloc() and free() in gzio.c if STDC not defined\n- Use malloc() instead of calloc() in zutil.c if int big enough\n- Define STDC for AIX\n- Add aix/ with approach for compiling shared library on AIX\n- Add HP-UX support for shared libraries in configure\n- Add OpenUNIX support for shared libraries in configure\n- Use $cc instead of gcc to build shared library\n- Make prefix directory if needed when installing\n- Correct Macintosh avoidance of typedef Byte in zconf.h\n- Correct Turbo C memory allocation when under Linux\n- Use libz.a instead of -lz in Makefile (assure use of compiled library)\n- Update configure to check for snprintf or vsnprintf functions and their\n  return value, warn during make if using an insecure function\n- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that\n  is lost when library is used--resolution is to build new zconf.h\n- Documentation improvements (in zlib.h):\n    - Document raw deflate and inflate\n    - Update RFCs URL\n    - Point out that zlib and gzip formats are different\n    - Note that Z_BUF_ERROR is not fatal\n    - Document string limit for gzprintf() and possible buffer overflow\n    - Note requirement on avail_out when flushing\n    - Note permitted values of flush parameter of inflate()\n- Add some FAQs (and even answers) to the FAQ\n- Add contrib/inflate86/ for x86 faster inflate\n- Add contrib/blast/ for PKWare Data Compression Library decompression\n- Add contrib/puff/ simple inflate for deflate format description\n\nChanges in 1.1.4 (11 March 2002)\n- ZFREE was repeated on same allocation on some error conditions.\n  This creates a security problem described in\n  http://www.zlib.org/advisory-2002-03-11.txt\n- Returned incorrect error (Z_MEM_ERROR) on some invalid data\n- Avoid accesses before window for invalid distances with inflate window\n  less than 32K.\n- force windowBits > 8 to avoid a bug in the encoder for a window size\n  of 256 bytes. (A complete fix will be available in 1.1.5).\n\nChanges in 1.1.3 (9 July 1998)\n- fix \"an inflate input buffer bug that shows up on rare but persistent\n  occasions\" (Mark)\n- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)\n- fix gzseek(..., SEEK_SET) in write mode\n- fix crc check after a gzeek (Frank Faubert)\n- fix miniunzip when the last entry in a zip file is itself a zip file\n  (J Lillge)\n- add contrib/asm586 and contrib/asm686 (Brian Raiter)\n  See http://www.muppetlabs.com/~breadbox/software/assembly.html\n- add support for Delphi 3 in contrib/delphi (Bob Dellaca)\n- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)\n- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)\n- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)\n- added a FAQ file\n\n- Support gzdopen on Mac with Metrowerks (Jason Linhart)\n- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)\n- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)\n- avoid some warnings with Borland C (Tom Tanner)\n- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)\n- emulate utime() for WIN32 in contrib/untgz  (Gilles Vollant)\n- allow several arguments to configure (Tim Mooney, Frodo Looijaard)\n- use libdir and includedir in Makefile.in (Tim Mooney)\n- support shared libraries on OSF1 V4 (Tim Mooney)\n- remove so_locations in \"make clean\"  (Tim Mooney)\n- fix maketree.c compilation error (Glenn, Mark)\n- Python interface to zlib now in Python 1.5 (Jeremy Hylton)\n- new Makefile.riscos (Rich Walker)\n- initialize static descriptors in trees.c for embedded targets (Nick Smith)\n- use \"foo-gz\" in example.c for RISCOS and VMS (Nick Smith)\n- add the OS/2 files in Makefile.in too (Andrew Zabolotny)\n- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)\n- fix maketree.c to allow clean compilation of inffixed.h (Mark)\n- fix parameter check in deflateCopy (Gunther Nikl)\n- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)\n- Many portability patches by Christian Spieler:\n  . zutil.c, zutil.h: added \"const\" for zmem*\n  . Make_vms.com: fixed some typos\n  . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists\n  . msdos/Makefile.msc: remove \"default rtl link library\" info from obj files\n  . msdos/Makefile.*: use model-dependent name for the built zlib library\n  . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:\n     new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)\n- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)\n- replace __far with _far for better portability (Christian Spieler, Tom Lane)\n- fix test for errno.h in configure (Tim Newsham)\n\nChanges in 1.1.2 (19 March 98)\n- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)\n  See http://www.winimage.com/zLibDll/unzip.html\n- preinitialize the inflate tables for fixed codes, to make the code\n  completely thread safe (Mark)\n- some simplifications and slight speed-up to the inflate code (Mark)\n- fix gzeof on non-compressed files (Allan Schrum)\n- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)\n- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)\n- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)\n- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)\n- do not wrap extern \"C\" around system includes (Tom Lane)\n- mention zlib binding for TCL in README (Andreas Kupries)\n- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)\n- allow \"make install prefix=...\" even after configure (Glenn Randers-Pehrson)\n- allow \"configure --prefix $HOME\" (Tim Mooney)\n- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)\n- move Makefile.sas to amiga/Makefile.sas\n\nChanges in 1.1.1 (27 Feb 98)\n- fix macros _tr_tally_* in deflate.h for debug mode  (Glenn Randers-Pehrson)\n- remove block truncation heuristic which had very marginal effect for zlib\n  (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the\n  compression ratio on some files. This also allows inlining _tr_tally for\n  matches in deflate_slow.\n- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)\n\nChanges in 1.1.0 (24 Feb 98)\n- do not return STREAM_END prematurely in inflate (John Bowler)\n- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)\n- compile with -DFASTEST to get compression code optimized for speed only\n- in minigzip, try mmap'ing the input file first (Miguel Albrecht)\n- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain\n  on Sun but significant on HP)\n\n- add a pointer to experimental unzip library in README (Gilles Vollant)\n- initialize variable gcc in configure (Chris Herborth)\n\nChanges in 1.0.9 (17 Feb 1998)\n- added gzputs and gzgets functions\n- do not clear eof flag in gzseek (Mark Diekhans)\n- fix gzseek for files in transparent mode (Mark Diekhans)\n- do not assume that vsprintf returns the number of bytes written (Jens Krinke)\n- replace EXPORT with ZEXPORT to avoid conflict with other programs\n- added compress2 in zconf.h, zlib.def, zlib.dnt\n- new asm code from Gilles Vollant in contrib/asm386\n- simplify the inflate code (Mark):\n . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()\n . ZALLOC the length list in inflate_trees_fixed() instead of using stack\n . ZALLOC the value area for huft_build() instead of using stack\n . Simplify Z_FINISH check in inflate()\n\n- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8\n- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)\n- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with\n  the declaration of FAR (Gilles VOllant)\n- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)\n- read_buf buf parameter of type Bytef* instead of charf*\n- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)\n- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)\n- fix check for presence of directories in \"make install\" (Ian Willis)\n\nChanges in 1.0.8 (27 Jan 1998)\n- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)\n- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)\n- added compress2() to allow setting the compression level\n- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)\n- use constant arrays for the static trees in trees.c instead of computing\n  them at run time (thanks to Ken Raeburn for this suggestion). To create\n  trees.h, compile with GEN_TREES_H and run \"make test\".\n- check return code of example in \"make test\" and display result\n- pass minigzip command line options to file_compress\n- simplifying code of inflateSync to avoid gcc 2.8 bug\n\n- support CC=\"gcc -Wall\" in configure -s (QingLong)\n- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)\n- fix test for shared library support to avoid compiler warnings\n- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)\n- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)\n- do not use fdopen for Metrowerks on Mac (Brad Pettit))\n- add checks for gzputc and gzputc in example.c\n- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)\n- use const for the CRC table (Ken Raeburn)\n- fixed \"make uninstall\" for shared libraries\n- use Tracev instead of Trace in infblock.c\n- in example.c use correct compressed length for test_sync\n- suppress +vnocompatwarnings in configure for HPUX (not always supported)\n\nChanges in 1.0.7 (20 Jan 1998)\n- fix gzseek which was broken in write mode\n- return error for gzseek to negative absolute position\n- fix configure for Linux (Chun-Chung Chen)\n- increase stack space for MSC (Tim Wegner)\n- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)\n- define EXPORTVA for gzprintf (Gilles Vollant)\n- added man page zlib.3 (Rick Rodgers)\n- for contrib/untgz, fix makedir() and improve Makefile\n\n- check gzseek in write mode in example.c\n- allocate extra buffer for seeks only if gzseek is actually called\n- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)\n- add inflateSyncPoint in zconf.h\n- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def\n\nChanges in 1.0.6 (19 Jan 1998)\n- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and\n  gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)\n- Fix a deflate bug occurring only with compression level 0 (thanks to\n  Andy Buckler for finding this one).\n- In minigzip, pass transparently also the first byte for .Z files.\n- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()\n- check Z_FINISH in inflate (thanks to Marc Schluper)\n- Implement deflateCopy (thanks to Adam Costello)\n- make static libraries by default in configure, add --shared option.\n- move MSDOS or Windows specific files to directory msdos\n- suppress the notion of partial flush to simplify the interface\n  (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)\n- suppress history buffer provided by application to simplify the interface\n  (this feature was not implemented anyway in 1.0.4)\n- next_in and avail_in must be initialized before calling inflateInit or\n  inflateInit2\n- add EXPORT in all exported functions (for Windows DLL)\n- added Makefile.nt (thanks to Stephen Williams)\n- added the unsupported \"contrib\" directory:\n   contrib/asm386/ by Gilles Vollant <info@winimage.com>\n        386 asm code replacing longest_match().\n   contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>\n        A C++ I/O streams interface to the zlib gz* functions\n   contrib/iostream2/  by Tyge Lvset <Tyge.Lovset@cmr.no>\n        Another C++ I/O streams interface\n   contrib/untgz/  by \"Pedro A. Aranda Guti\\irrez\" <paag@tid.es>\n        A very simple tar.gz file extractor using zlib\n   contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>\n        How to use compress(), uncompress() and the gz* functions from VB.\n- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression\n  level) in minigzip (thanks to Tom Lane)\n\n- use const for rommable constants in deflate\n- added test for gzseek and gztell in example.c\n- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)\n- add undocumented function zError to convert error code to string\n  (for Tim Smithers)\n- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.\n- Use default memcpy for Symantec MSDOS compiler.\n- Add EXPORT keyword for check_func (needed for Windows DLL)\n- add current directory to LD_LIBRARY_PATH for \"make test\"\n- create also a link for libz.so.1\n- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)\n- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)\n- added -soname for Linux in configure (Chun-Chung Chen,\n- assign numbers to the exported functions in zlib.def (for Windows DLL)\n- add advice in zlib.h for best usage of deflateSetDictionary\n- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)\n- allow compilation with ANSI keywords only enabled for TurboC in large model\n- avoid \"versionString\"[0] (Borland bug)\n- add NEED_DUMMY_RETURN for Borland\n- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).\n- allow compilation with CC\n- defined STDC for OS/2 (David Charlap)\n- limit external names to 8 chars for MVS (Thomas Lund)\n- in minigzip.c, use static buffers only for 16-bit systems\n- fix suffix check for \"minigzip -d foo.gz\"\n- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)\n- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)\n- added makelcc.bat for lcc-win32 (Tom St Denis)\n- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)\n- Avoid expanded $Id$. Use \"rcs -kb\" or \"cvs admin -kb\" to avoid Id expansion.\n- check for unistd.h in configure (for off_t)\n- remove useless check parameter in inflate_blocks_free\n- avoid useless assignment of s->check to itself in inflate_blocks_new\n- do not flush twice in gzclose (thanks to Ken Raeburn)\n- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h\n- use NO_ERRNO_H instead of enumeration of operating systems with errno.h\n- work around buggy fclose on pipes for HP/UX\n- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)\n- fix configure if CC is already equal to gcc\n\nChanges in 1.0.5 (3 Jan 98)\n- Fix inflate to terminate gracefully when fed corrupted or invalid data\n- Use const for rommable constants in inflate\n- Eliminate memory leaks on error conditions in inflate\n- Removed some vestigial code in inflate\n- Update web address in README\n\nChanges in 1.0.4 (24 Jul 96)\n- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF\n  bit, so the decompressor could decompress all the correct data but went\n  on to attempt decompressing extra garbage data. This affected minigzip too.\n- zlibVersion and gzerror return const char* (needed for DLL)\n- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)\n- use z_error only for DEBUG (avoid problem with DLLs)\n\nChanges in 1.0.3 (2 Jul 96)\n- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS\n  small and medium models; this makes the library incompatible with previous\n  versions for these models. (No effect in large model or on other systems.)\n- return OK instead of BUF_ERROR if previous deflate call returned with\n  avail_out as zero but there is nothing to do\n- added memcmp for non STDC compilers\n- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)\n- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)\n- better check for 16-bit mode MSC (avoids problem with Symantec)\n\nChanges in 1.0.2 (23 May 96)\n- added Windows DLL support\n- added a function zlibVersion (for the DLL support)\n- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)\n- Bytef is define's instead of typedef'd only for Borland C\n- avoid reading uninitialized memory in example.c\n- mention in README that the zlib format is now RFC1950\n- updated Makefile.dj2\n- added algorithm.doc\n\nChanges in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]\n- fix array overlay in deflate.c which sometimes caused bad compressed data\n- fix inflate bug with empty stored block\n- fix MSDOS medium model which was broken in 0.99\n- fix deflateParams() which could generated bad compressed data.\n- Bytef is define'd instead of typedef'ed (work around Borland bug)\n- added an INDEX file\n- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),\n  Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)\n- speed up adler32 for modern machines without auto-increment\n- added -ansi for IRIX in configure\n- static_init_done in trees.c is an int\n- define unlink as delete for VMS\n- fix configure for QNX\n- add configure branch for SCO and HPUX\n- avoid many warnings (unused variables, dead assignments, etc...)\n- no fdopen for BeOS\n- fix the Watcom fix for 32 bit mode (define FAR as empty)\n- removed redefinition of Byte for MKWERKS\n- work around an MWKERKS bug (incorrect merge of all .h files)\n\nChanges in 0.99 (27 Jan 96)\n- allow preset dictionary shared between compressor and decompressor\n- allow compression level 0 (no compression)\n- add deflateParams in zlib.h: allow dynamic change of compression level\n  and compression strategy.\n- test large buffers and deflateParams in example.c\n- add optional \"configure\" to build zlib as a shared library\n- suppress Makefile.qnx, use configure instead\n- fixed deflate for 64-bit systems (detected on Cray)\n- fixed inflate_blocks for 64-bit systems (detected on Alpha)\n- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)\n- always return Z_BUF_ERROR when deflate() has nothing to do\n- deflateInit and inflateInit are now macros to allow version checking\n- prefix all global functions and types with z_ with -DZ_PREFIX\n- make falloc completely reentrant (inftrees.c)\n- fixed very unlikely race condition in ct_static_init\n- free in reverse order of allocation to help memory manager\n- use zlib-1.0/* instead of zlib/* inside the tar.gz\n- make zlib warning-free with \"gcc -O3 -Wall -Wwrite-strings -Wpointer-arith\n  -Wconversion -Wstrict-prototypes -Wmissing-prototypes\"\n- allow gzread on concatenated .gz files\n- deflateEnd now returns Z_DATA_ERROR if it was premature\n- deflate is finally (?) fully deterministic (no matches beyond end of input)\n- Document Z_SYNC_FLUSH\n- add uninstall in Makefile\n- Check for __cpluplus in zlib.h\n- Better test in ct_align for partial flush\n- avoid harmless warnings for Borland C++\n- initialize hash_head in deflate.c\n- avoid warning on fdopen (gzio.c) for HP cc -Aa\n- include stdlib.h for STDC compilers\n- include errno.h for Cray\n- ignore error if ranlib doesn't exist\n- call ranlib twice for NeXTSTEP\n- use exec_prefix instead of prefix for libz.a\n- renamed ct_* as _tr_* to avoid conflict with applications\n- clear z->msg in inflateInit2 before any error return\n- initialize opaque in example.c, gzio.c, deflate.c and inflate.c\n- fixed typo in zconf.h (_GNUC__ => __GNUC__)\n- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)\n- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)\n- in fcalloc, normalize pointer if size > 65520 bytes\n- don't use special fcalloc for 32 bit Borland C++\n- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...\n- use Z_BINARY instead of BINARY\n- document that gzclose after gzdopen will close the file\n- allow \"a\" as mode in gzopen.\n- fix error checking in gzread\n- allow skipping .gz extra-field on pipes\n- added reference to Perl interface in README\n- put the crc table in FAR data (I dislike more and more the medium model :)\n- added get_crc_table\n- added a dimension to all arrays (Borland C can't count).\n- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast\n- guard against multiple inclusion of *.h (for precompiled header on Mac)\n- Watcom C pretends to be Microsoft C small model even in 32 bit mode.\n- don't use unsized arrays to avoid silly warnings by Visual C++:\n     warning C4746: 'inflate_mask' : unsized array treated as  '__far'\n     (what's wrong with far data in far model?).\n- define enum out of inflate_blocks_state to allow compilation with C++\n\nChanges in 0.95 (16 Aug 95)\n- fix MSDOS small and medium model (now easier to adapt to any compiler)\n- inlined send_bits\n- fix the final (:-) bug for deflate with flush (output was correct but\n  not completely flushed in rare occasions).\n- default window size is same for compression and decompression\n  (it's now sufficient to set MAX_WBITS in zconf.h).\n- voidp -> voidpf and voidnp -> voidp (for consistency with other\n  typedefs and because voidnp was not near in large model).\n\nChanges in 0.94 (13 Aug 95)\n- support MSDOS medium model\n- fix deflate with flush (could sometimes generate bad output)\n- fix deflateReset (zlib header was incorrectly suppressed)\n- added support for VMS\n- allow a compression level in gzopen()\n- gzflush now calls fflush\n- For deflate with flush, flush even if no more input is provided.\n- rename libgz.a as libz.a\n- avoid complex expression in infcodes.c triggering Turbo C bug\n- work around a problem with gcc on Alpha (in INSERT_STRING)\n- don't use inline functions (problem with some gcc versions)\n- allow renaming of Byte, uInt, etc... with #define.\n- avoid warning about (unused) pointer before start of array in deflate.c\n- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c\n- avoid reserved word 'new' in trees.c\n\nChanges in 0.93 (25 June 95)\n- temporarily disable inline functions\n- make deflate deterministic\n- give enough lookahead for PARTIAL_FLUSH\n- Set binary mode for stdin/stdout in minigzip.c for OS/2\n- don't even use signed char in inflate (not portable enough)\n- fix inflate memory leak for segmented architectures\n\nChanges in 0.92 (3 May 95)\n- don't assume that char is signed (problem on SGI)\n- Clear bit buffer when starting a stored block\n- no memcpy on Pyramid\n- suppressed inftest.c\n- optimized fill_window, put longest_match inline for gcc\n- optimized inflate on stored blocks.\n- untabify all sources to simplify patches\n\nChanges in 0.91 (2 May 95)\n- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h\n- Document the memory requirements in zconf.h\n- added \"make install\"\n- fix sync search logic in inflateSync\n- deflate(Z_FULL_FLUSH) now works even if output buffer too short\n- after inflateSync, don't scare people with just \"lo world\"\n- added support for DJGPP\n\nChanges in 0.9 (1 May 95)\n- don't assume that zalloc clears the allocated memory (the TurboC bug\n  was Mark's bug after all :)\n- let again gzread copy uncompressed data unchanged (was working in 0.71)\n- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented\n- added a test of inflateSync in example.c\n- moved MAX_WBITS to zconf.h because users might want to change that.\n- document explicitly that zalloc(64K) on MSDOS must return a normalized\n  pointer (zero offset)\n- added Makefiles for Microsoft C, Turbo C, Borland C++\n- faster crc32()\n\nChanges in 0.8 (29 April 95)\n- added fast inflate (inffast.c)\n- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this\n  is incompatible with previous versions of zlib which returned Z_OK.\n- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)\n  (actually that was not a compiler bug, see 0.81 above)\n- gzread no longer reads one extra byte in certain cases\n- In gzio destroy(), don't reference a freed structure\n- avoid many warnings for MSDOS\n- avoid the ERROR symbol which is used by MS Windows\n\nChanges in 0.71 (14 April 95)\n- Fixed more MSDOS compilation problems :( There is still a bug with\n  TurboC large model.\n\nChanges in 0.7 (14 April 95)\n- Added full inflate support.\n- Simplified the crc32() interface. The pre- and post-conditioning\n  (one's complement) is now done inside crc32(). WARNING: this is\n  incompatible with previous versions; see zlib.h for the new usage.\n\nChanges in 0.61 (12 April 95)\n- workaround for a bug in TurboC. example and minigzip now work on MSDOS.\n\nChanges in 0.6 (11 April 95)\n- added minigzip.c\n- added gzdopen to reopen a file descriptor as gzFile\n- added transparent reading of non-gziped files in gzread.\n- fixed bug in gzread (don't read crc as data)\n- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).\n- don't allocate big arrays in the stack (for MSDOS)\n- fix some MSDOS compilation problems\n\nChanges in 0.5:\n- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but\n  not yet Z_FULL_FLUSH.\n- support decompression but only in a single step (forced Z_FINISH)\n- added opaque object for zalloc and zfree.\n- added deflateReset and inflateReset\n- added a variable zlib_version for consistency checking.\n- renamed the 'filter' parameter of deflateInit2 as 'strategy'.\n  Added Z_FILTERED and Z_HUFFMAN_ONLY constants.\n\nChanges in 0.4:\n- avoid \"zip\" everywhere, use zlib instead of ziplib.\n- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush\n  if compression method == 8.\n- added adler32 and crc32\n- renamed deflateOptions as deflateInit2, call one or the other but not both\n- added the method parameter for deflateInit2.\n- added inflateInit2\n- simplied considerably deflateInit and inflateInit by not supporting\n  user-provided history buffer. This is supported only in deflateInit2\n  and inflateInit2.\n\nChanges in 0.3:\n- prefix all macro names with Z_\n- use Z_FINISH instead of deflateEnd to finish compression.\n- added Z_HUFFMAN_ONLY\n- added gzerror()\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/FAQ",
    "content": "\n                Frequently Asked Questions about zlib\n\n\nIf your question is not there, please check the zlib home page\nhttp://zlib.net/ which may have more recent information.\nThe lastest zlib FAQ is at http://zlib.net/zlib_faq.html\n\n\n 1. Is zlib Y2K-compliant?\n\n    Yes. zlib doesn't handle dates.\n\n 2. Where can I get a Windows DLL version?\n\n    The zlib sources can be compiled without change to produce a DLL.  See the\n    file win32/DLL_FAQ.txt in the zlib distribution.  Pointers to the\n    precompiled DLL are found in the zlib web site at http://zlib.net/ .\n\n 3. Where can I get a Visual Basic interface to zlib?\n\n    See\n        * http://marknelson.us/1997/01/01/zlib-engine/\n        * win32/DLL_FAQ.txt in the zlib distribution\n\n 4. compress() returns Z_BUF_ERROR.\n\n    Make sure that before the call of compress(), the length of the compressed\n    buffer is equal to the available size of the compressed buffer and not\n    zero.  For Visual Basic, check that this parameter is passed by reference\n    (\"as any\"), not by value (\"as long\").\n\n 5. deflate() or inflate() returns Z_BUF_ERROR.\n\n    Before making the call, make sure that avail_in and avail_out are not zero.\n    When setting the parameter flush equal to Z_FINISH, also make sure that\n    avail_out is big enough to allow processing all pending input.  Note that a\n    Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be\n    made with more input or output space.  A Z_BUF_ERROR may in fact be\n    unavoidable depending on how the functions are used, since it is not\n    possible to tell whether or not there is more output pending when\n    strm.avail_out returns with zero.  See http://zlib.net/zlib_how.html for a\n    heavily annotated example.\n\n 6. Where's the zlib documentation (man pages, etc.)?\n\n    It's in zlib.h .  Examples of zlib usage are in the files test/example.c\n    and test/minigzip.c, with more in examples/ .\n\n 7. Why don't you use GNU autoconf or libtool or ...?\n\n    Because we would like to keep zlib as a very small and simple package.\n    zlib is rather portable and doesn't need much configuration.\n\n 8. I found a bug in zlib.\n\n    Most of the time, such problems are due to an incorrect usage of zlib.\n    Please try to reproduce the problem with a small program and send the\n    corresponding source to us at zlib@gzip.org .  Do not send multi-megabyte\n    data files without prior agreement.\n\n 9. Why do I get \"undefined reference to gzputc\"?\n\n    If \"make test\" produces something like\n\n       example.o(.text+0x154): undefined reference to `gzputc'\n\n    check that you don't have old files libz.* in /usr/lib, /usr/local/lib or\n    /usr/X11R6/lib. Remove any old versions, then do \"make install\".\n\n10. I need a Delphi interface to zlib.\n\n    See the contrib/delphi directory in the zlib distribution.\n\n11. Can zlib handle .zip archives?\n\n    Not by itself, no.  See the directory contrib/minizip in the zlib\n    distribution.\n\n12. Can zlib handle .Z files?\n\n    No, sorry.  You have to spawn an uncompress or gunzip subprocess, or adapt\n    the code of uncompress on your own.\n\n13. How can I make a Unix shared library?\n\n    By default a shared (and a static) library is built for Unix.  So:\n\n    make distclean\n    ./configure\n    make\n\n14. How do I install a shared zlib library on Unix?\n\n    After the above, then:\n\n    make install\n\n    However, many flavors of Unix come with a shared zlib already installed.\n    Before going to the trouble of compiling a shared version of zlib and\n    trying to install it, you may want to check if it's already there!  If you\n    can #include <zlib.h>, it's there.  The -lz option will probably link to\n    it.  You can check the version at the top of zlib.h or with the\n    ZLIB_VERSION symbol defined in zlib.h .\n\n15. I have a question about OttoPDF.\n\n    We are not the authors of OttoPDF. The real author is on the OttoPDF web\n    site: Joel Hainley, jhainley@myndkryme.com.\n\n16. Can zlib decode Flate data in an Adobe PDF file?\n\n    Yes. See http://www.pdflib.com/ . To modify PDF forms, see\n    http://sourceforge.net/projects/acroformtool/ .\n\n17. Why am I getting this \"register_frame_info not found\" error on Solaris?\n\n    After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib\n    generates an error such as:\n\n        ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:\n        symbol __register_frame_info: referenced symbol not found\n\n    The symbol __register_frame_info is not part of zlib, it is generated by\n    the C compiler (cc or gcc).  You must recompile applications using zlib\n    which have this problem.  This problem is specific to Solaris.  See\n    http://www.sunfreeware.com for Solaris versions of zlib and applications\n    using zlib.\n\n18. Why does gzip give an error on a file I make with compress/deflate?\n\n    The compress and deflate functions produce data in the zlib format, which\n    is different and incompatible with the gzip format.  The gz* functions in\n    zlib on the other hand use the gzip format.  Both the zlib and gzip formats\n    use the same compressed data format internally, but have different headers\n    and trailers around the compressed data.\n\n19. Ok, so why are there two different formats?\n\n    The gzip format was designed to retain the directory information about a\n    single file, such as the name and last modification date.  The zlib format\n    on the other hand was designed for in-memory and communication channel\n    applications, and has a much more compact header and trailer and uses a\n    faster integrity check than gzip.\n\n20. Well that's nice, but how do I make a gzip file in memory?\n\n    You can request that deflate write the gzip format instead of the zlib\n    format using deflateInit2().  You can also request that inflate decode the\n    gzip format using inflateInit2().  Read zlib.h for more details.\n\n21. Is zlib thread-safe?\n\n    Yes.  However any library routines that zlib uses and any application-\n    provided memory allocation routines must also be thread-safe.  zlib's gz*\n    functions use stdio library routines, and most of zlib's functions use the\n    library memory allocation routines by default.  zlib's *Init* functions\n    allow for the application to provide custom memory allocation routines.\n\n    Of course, you should only operate on any given zlib or gzip stream from a\n    single thread at a time.\n\n22. Can I use zlib in my commercial application?\n\n    Yes.  Please read the license in zlib.h.\n\n23. Is zlib under the GNU license?\n\n    No.  Please read the license in zlib.h.\n\n24. The license says that altered source versions must be \"plainly marked\". So\n    what exactly do I need to do to meet that requirement?\n\n    You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h.  In\n    particular, the final version number needs to be changed to \"f\", and an\n    identification string should be appended to ZLIB_VERSION.  Version numbers\n    x.x.x.f are reserved for modifications to zlib by others than the zlib\n    maintainers.  For example, if the version of the base zlib you are altering\n    is \"1.2.3.4\", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and\n    ZLIB_VERSION to something like \"1.2.3.f-zachary-mods-v3\".  You can also\n    update the version strings in deflate.c and inftrees.c.\n\n    For altered source distributions, you should also note the origin and\n    nature of the changes in zlib.h, as well as in ChangeLog and README, along\n    with the dates of the alterations.  The origin should include at least your\n    name (or your company's name), and an email address to contact for help or\n    issues with the library.\n\n    Note that distributing a compiled zlib library along with zlib.h and\n    zconf.h is also a source distribution, and so you should change\n    ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes\n    in zlib.h as you would for a full source distribution.\n\n25. Will zlib work on a big-endian or little-endian architecture, and can I\n    exchange compressed data between them?\n\n    Yes and yes.\n\n26. Will zlib work on a 64-bit machine?\n\n    Yes.  It has been tested on 64-bit machines, and has no dependence on any\n    data types being limited to 32-bits in length.  If you have any\n    difficulties, please provide a complete problem report to zlib@gzip.org\n\n27. Will zlib decompress data from the PKWare Data Compression Library?\n\n    No.  The PKWare DCL uses a completely different compressed data format than\n    does PKZIP and zlib.  However, you can look in zlib's contrib/blast\n    directory for a possible solution to your problem.\n\n28. Can I access data randomly in a compressed stream?\n\n    No, not without some preparation.  If when compressing you periodically use\n    Z_FULL_FLUSH, carefully write all the pending data at those points, and\n    keep an index of those locations, then you can start decompression at those\n    points.  You have to be careful to not use Z_FULL_FLUSH too often, since it\n    can significantly degrade compression.  Alternatively, you can scan a\n    deflate stream once to generate an index, and then use that index for\n    random access.  See examples/zran.c .\n\n29. Does zlib work on MVS, OS/390, CICS, etc.?\n\n    It has in the past, but we have not heard of any recent evidence.  There\n    were working ports of zlib 1.1.4 to MVS, but those links no longer work.\n    If you know of recent, successful applications of zlib on these operating\n    systems, please let us know.  Thanks.\n\n30. Is there some simpler, easier to read version of inflate I can look at to\n    understand the deflate format?\n\n    First off, you should read RFC 1951.  Second, yes.  Look in zlib's\n    contrib/puff directory.\n\n31. Does zlib infringe on any patents?\n\n    As far as we know, no.  In fact, that was originally the whole point behind\n    zlib.  Look here for some more information:\n\n    http://www.gzip.org/#faq11\n\n32. Can zlib work with greater than 4 GB of data?\n\n    Yes.  inflate() and deflate() will process any amount of data correctly.\n    Each call of inflate() or deflate() is limited to input and output chunks\n    of the maximum value that can be stored in the compiler's \"unsigned int\"\n    type, but there is no limit to the number of chunks.  Note however that the\n    strm.total_in and strm_total_out counters may be limited to 4 GB.  These\n    counters are provided as a convenience and are not used internally by\n    inflate() or deflate().  The application can easily set up its own counters\n    updated after each call of inflate() or deflate() to count beyond 4 GB.\n    compress() and uncompress() may be limited to 4 GB, since they operate in a\n    single call.  gzseek() and gztell() may be limited to 4 GB depending on how\n    zlib is compiled.  See the zlibCompileFlags() function in zlib.h.\n\n    The word \"may\" appears several times above since there is a 4 GB limit only\n    if the compiler's \"long\" type is 32 bits.  If the compiler's \"long\" type is\n    64 bits, then the limit is 16 exabytes.\n\n33. Does zlib have any security vulnerabilities?\n\n    The only one that we are aware of is potentially in gzprintf().  If zlib is\n    compiled to use sprintf() or vsprintf(), then there is no protection\n    against a buffer overflow of an 8K string space (or other value as set by\n    gzbuffer()), other than the caller of gzprintf() assuring that the output\n    will not exceed 8K.  On the other hand, if zlib is compiled to use\n    snprintf() or vsnprintf(), which should normally be the case, then there is\n    no vulnerability.  The ./configure script will display warnings if an\n    insecure variation of sprintf() will be used by gzprintf().  Also the\n    zlibCompileFlags() function will return information on what variant of\n    sprintf() is used by gzprintf().\n\n    If you don't have snprintf() or vsnprintf() and would like one, you can\n    find a portable implementation here:\n\n        http://www.ijs.si/software/snprintf/\n\n    Note that you should be using the most recent version of zlib.  Versions\n    1.1.3 and before were subject to a double-free vulnerability, and versions\n    1.2.1 and 1.2.2 were subject to an access exception when decompressing\n    invalid compressed data.\n\n34. Is there a Java version of zlib?\n\n    Probably what you want is to use zlib in Java. zlib is already included\n    as part of the Java SDK in the java.util.zip package. If you really want\n    a version of zlib written in the Java language, look on the zlib home\n    page for links: http://zlib.net/ .\n\n35. I get this or that compiler or source-code scanner warning when I crank it\n    up to maximally-pedantic. Can't you guys write proper code?\n\n    Many years ago, we gave up attempting to avoid warnings on every compiler\n    in the universe.  It just got to be a waste of time, and some compilers\n    were downright silly as well as contradicted each other.  So now, we simply\n    make sure that the code always works.\n\n36. Valgrind (or some similar memory access checker) says that deflate is\n    performing a conditional jump that depends on an uninitialized value.\n    Isn't that a bug?\n\n    No.  That is intentional for performance reasons, and the output of deflate\n    is not affected.  This only started showing up recently since zlib 1.2.x\n    uses malloc() by default for allocations, whereas earlier versions used\n    calloc(), which zeros out the allocated memory.  Even though the code was\n    correct, versions 1.2.4 and later was changed to not stimulate these\n    checkers.\n\n37. Will zlib read the (insert any ancient or arcane format here) compressed\n    data format?\n\n    Probably not. Look in the comp.compression FAQ for pointers to various\n    formats and associated software.\n\n38. How can I encrypt/decrypt zip files with zlib?\n\n    zlib doesn't support encryption.  The original PKZIP encryption is very\n    weak and can be broken with freely available programs.  To get strong\n    encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib\n    compression.  For PKZIP compatible \"encryption\", look at\n    http://www.info-zip.org/\n\n39. What's the difference between the \"gzip\" and \"deflate\" HTTP 1.1 encodings?\n\n    \"gzip\" is the gzip format, and \"deflate\" is the zlib format.  They should\n    probably have called the second one \"zlib\" instead to avoid confusion with\n    the raw deflate compressed data format.  While the HTTP 1.1 RFC 2616\n    correctly points to the zlib specification in RFC 1950 for the \"deflate\"\n    transfer encoding, there have been reports of servers and browsers that\n    incorrectly produce or expect raw deflate data per the deflate\n    specification in RFC 1951, most notably Microsoft.  So even though the\n    \"deflate\" transfer encoding using the zlib format would be the more\n    efficient approach (and in fact exactly what the zlib format was designed\n    for), using the \"gzip\" transfer encoding is probably more reliable due to\n    an unfortunate choice of name on the part of the HTTP 1.1 authors.\n\n    Bottom line: use the gzip format for HTTP 1.1 encoding.\n\n40. Does zlib support the new \"Deflate64\" format introduced by PKWare?\n\n    No.  PKWare has apparently decided to keep that format proprietary, since\n    they have not documented it as they have previous compression formats.  In\n    any case, the compression improvements are so modest compared to other more\n    modern approaches, that it's not worth the effort to implement.\n\n41. I'm having a problem with the zip functions in zlib, can you help?\n\n    There are no zip functions in zlib.  You are probably using minizip by\n    Giles Vollant, which is found in the contrib directory of zlib.  It is not\n    part of zlib.  In fact none of the stuff in contrib is part of zlib.  The\n    files in there are not supported by the zlib authors.  You need to contact\n    the authors of the respective contribution for help.\n\n42. The match.asm code in contrib is under the GNU General Public License.\n    Since it's part of zlib, doesn't that mean that all of zlib falls under the\n    GNU GPL?\n\n    No.  The files in contrib are not part of zlib.  They were contributed by\n    other authors and are provided as a convenience to the user within the zlib\n    distribution.  Each item in contrib has its own license.\n\n43. Is zlib subject to export controls?  What is its ECCN?\n\n    zlib is not subject to export controls, and so is classified as EAR99.\n\n44. Can you please sign these lengthy legal documents and fax them back to us\n    so that we can use your software in our product?\n\n    No. Go away. Shoo.\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/INDEX",
    "content": "CMakeLists.txt  cmake build file\nChangeLog       history of changes\nFAQ             Frequently Asked Questions about zlib\nINDEX           this file\nMakefile        dummy Makefile that tells you to ./configure\nMakefile.in     template for Unix Makefile\nREADME          guess what\nconfigure       configure script for Unix\nmake_vms.com    makefile for VMS\ntest/example.c  zlib usages examples for build testing\ntest/minigzip.c minimal gzip-like functionality for build testing\ntest/infcover.c inf*.c code coverage for build coverage testing\ntreebuild.xml   XML description of source file dependencies\nzconf.h.cmakein zconf.h template for cmake\nzconf.h.in      zconf.h template for configure\nzlib.3          Man page for zlib\nzlib.3.pdf      Man page in PDF format\nzlib.map        Linux symbol information\nzlib.pc.in      Template for pkg-config descriptor\nzlib.pc.cmakein zlib.pc template for cmake\nzlib2ansi       perl script to convert source files for C++ compilation\n\namiga/          makefiles for Amiga SAS C\nas400/          makefiles for AS/400\ndoc/            documentation for formats and algorithms\nmsdos/          makefiles for MSDOS\nnintendods/     makefile for Nintendo DS\nold/            makefiles for various architectures and zlib documentation\n                files that have not yet been updated for zlib 1.2.x\nqnx/            makefiles for QNX\nwatcom/         makefiles for OpenWatcom\nwin32/          makefiles for Windows\n\n                zlib public header files (required for library use):\nzconf.h\nzlib.h\n\n                private source files used to build the zlib library:\nadler32.c\ncompress.c\ncrc32.c\ncrc32.h\ndeflate.c\ndeflate.h\ngzclose.c\ngzguts.h\ngzlib.c\ngzread.c\ngzwrite.c\ninfback.c\ninffast.c\ninffast.h\ninffixed.h\ninflate.c\ninflate.h\ninftrees.c\ninftrees.h\ntrees.c\ntrees.h\nuncompr.c\nzutil.c\nzutil.h\n\n                source files for sample programs\nSee examples/README.examples\n\n                unsupported contributions by third parties\nSee contrib/README.contrib\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/Makefile.in",
    "content": "# Makefile for zlib\n# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler\n# For conditions of distribution and use, see copyright notice in zlib.h\n\n# To compile and test, type:\n#    ./configure; make test\n# Normally configure builds both a static and a shared library.\n# If you want to build just a static library, use: ./configure --static\n\n# To use the asm code, type:\n#    cp contrib/asm?86/match.S ./match.S\n#    make LOC=-DASMV OBJA=match.o\n\n# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:\n#    make install\n# To install in $HOME instead of /usr/local, use:\n#    make install prefix=$HOME\n\nCC=cc\n\nCFLAGS=-O\n#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7\n#CFLAGS=-g -DDEBUG\n#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \\\n#           -Wstrict-prototypes -Wmissing-prototypes\n\nSFLAGS=-O\nLDFLAGS=\nTEST_LDFLAGS=-L. libz.a\nLDSHARED=$(CC)\nCPP=$(CC) -E\n\nSTATICLIB=libz.a\nSHAREDLIB=libz.so\nSHAREDLIBV=libz.so.1.2.8\nSHAREDLIBM=libz.so.1\nLIBS=$(STATICLIB) $(SHAREDLIBV)\n\nAR=ar\nARFLAGS=rc\nRANLIB=ranlib\nLDCONFIG=ldconfig\nLDSHAREDLIBC=-lc\nTAR=tar\nSHELL=/bin/sh\nEXE=\n\nprefix = /usr/local\nexec_prefix = ${prefix}\nlibdir = ${exec_prefix}/lib\nsharedlibdir = ${libdir}\nincludedir = ${prefix}/include\nmandir = ${prefix}/share/man\nman3dir = ${mandir}/man3\npkgconfigdir = ${libdir}/pkgconfig\n\nOBJZ = adler32.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o\nOBJG = compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o\nOBJC = $(OBJZ) $(OBJG)\n\nPIC_OBJZ = adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo\nPIC_OBJG = compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo\nPIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG)\n\n# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo\nOBJA =\nPIC_OBJA =\n\nOBJS = $(OBJC) $(OBJA)\n\nPIC_OBJS = $(PIC_OBJC) $(PIC_OBJA)\n\nall: static shared\n\nstatic: example$(EXE) minigzip$(EXE)\n\nshared: examplesh$(EXE) minigzipsh$(EXE)\n\nall64: example64$(EXE) minigzip64$(EXE)\n\ncheck: test\n\ntest: all teststatic testshared\n\nteststatic: static\n\t@TMPST=tmpst_$$; \\\n\tif echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \\\n\t  echo '\t\t*** zlib test OK ***'; \\\n\telse \\\n\t  echo '\t\t*** zlib test FAILED ***'; false; \\\n\tfi; \\\n\trm -f $$TMPST\n\ntestshared: shared\n\t@LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \\\n\tLD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \\\n\tDYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \\\n\tSHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \\\n\tTMPSH=tmpsh_$$; \\\n\tif echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \\\n\t  echo '\t\t*** zlib shared test OK ***'; \\\n\telse \\\n\t  echo '\t\t*** zlib shared test FAILED ***'; false; \\\n\tfi; \\\n\trm -f $$TMPSH\n\ntest64: all64\n\t@TMP64=tmp64_$$; \\\n\tif echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \\\n\t  echo '\t\t*** zlib 64-bit test OK ***'; \\\n\telse \\\n\t  echo '\t\t*** zlib 64-bit test FAILED ***'; false; \\\n\tfi; \\\n\trm -f $$TMP64\n\ninfcover.o: test/infcover.c zlib.h zconf.h\n\t$(CC) $(CFLAGS) -I. -c -o $@ test/infcover.c\n\ninfcover: infcover.o libz.a\n\t$(CC) $(CFLAGS) -o $@ infcover.o libz.a\n\ncover: infcover\n\trm -f *.gcda\n\t./infcover\n\tgcov inf*.c\n\nlibz.a: $(OBJS)\n\t$(AR) $(ARFLAGS) $@ $(OBJS)\n\t-@ ($(RANLIB) $@ || true) >/dev/null 2>&1\n\nmatch.o: match.S\n\t$(CPP) match.S > _match.s\n\t$(CC) -c _match.s\n\tmv _match.o match.o\n\trm -f _match.s\n\nmatch.lo: match.S\n\t$(CPP) match.S > _match.s\n\t$(CC) -c -fPIC _match.s\n\tmv _match.o match.lo\n\trm -f _match.s\n\nexample.o: test/example.c zlib.h zconf.h\n\t$(CC) $(CFLAGS) -I. -c -o $@ test/example.c\n\nminigzip.o: test/minigzip.c zlib.h zconf.h\n\t$(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c\n\nexample64.o: test/example.c zlib.h zconf.h\n\t$(CC) $(CFLAGS) -I. -D_FILE_OFFSET_BITS=64 -c -o $@ test/example.c\n\nminigzip64.o: test/minigzip.c zlib.h zconf.h\n\t$(CC) $(CFLAGS) -I. -D_FILE_OFFSET_BITS=64 -c -o $@ test/minigzip.c\n\n.SUFFIXES: .lo\n\n.c.lo:\n\t-@mkdir objs 2>/dev/null || test -d objs\n\t$(CC) $(SFLAGS) -DPIC -c -o objs/$*.o $<\n\t-@mv objs/$*.o $@\n\nplacebo $(SHAREDLIBV): $(PIC_OBJS) libz.a\n\t$(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS)\n\trm -f $(SHAREDLIB) $(SHAREDLIBM)\n\tln -s $@ $(SHAREDLIB)\n\tln -s $@ $(SHAREDLIBM)\n\t-@rmdir objs\n\nexample$(EXE): example.o $(STATICLIB)\n\t$(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS)\n\nminigzip$(EXE): minigzip.o $(STATICLIB)\n\t$(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS)\n\nexamplesh$(EXE): example.o $(SHAREDLIBV)\n\t$(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV)\n\nminigzipsh$(EXE): minigzip.o $(SHAREDLIBV)\n\t$(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV)\n\nexample64$(EXE): example64.o $(STATICLIB)\n\t$(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS)\n\nminigzip64$(EXE): minigzip64.o $(STATICLIB)\n\t$(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS)\n\ninstall-libs: $(LIBS)\n\t-@if [ ! -d $(DESTDIR)$(exec_prefix)  ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi\n\t-@if [ ! -d $(DESTDIR)$(libdir)       ]; then mkdir -p $(DESTDIR)$(libdir); fi\n\t-@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi\n\t-@if [ ! -d $(DESTDIR)$(man3dir)      ]; then mkdir -p $(DESTDIR)$(man3dir); fi\n\t-@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi\n\tcp $(STATICLIB) $(DESTDIR)$(libdir)\n\tchmod 644 $(DESTDIR)$(libdir)/$(STATICLIB)\n\t-@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1\n\t-@if test -n \"$(SHAREDLIBV)\"; then \\\n\t  cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \\\n\t  echo \"cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)\"; \\\n\t  chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \\\n\t  echo \"chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV)\"; \\\n\t  rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \\\n\t  ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB); \\\n\t  ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \\\n\t  ($(LDCONFIG) || true)  >/dev/null 2>&1; \\\n\tfi\n\tcp zlib.3 $(DESTDIR)$(man3dir)\n\tchmod 644 $(DESTDIR)$(man3dir)/zlib.3\n\tcp zlib.pc $(DESTDIR)$(pkgconfigdir)\n\tchmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc\n# The ranlib in install is needed on NeXTSTEP which checks file times\n# ldconfig is for Linux\n\ninstall: install-libs\n\t-@if [ ! -d $(DESTDIR)$(includedir)   ]; then mkdir -p $(DESTDIR)$(includedir); fi\n\tcp zlib.h zconf.h $(DESTDIR)$(includedir)\n\tchmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h\n\nuninstall:\n\tcd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h\n\tcd $(DESTDIR)$(libdir) && rm -f libz.a; \\\n\tif test -n \"$(SHAREDLIBV)\" -a -f $(SHAREDLIBV); then \\\n\t  rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \\\n\tfi\n\tcd $(DESTDIR)$(man3dir) && rm -f zlib.3\n\tcd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc\n\ndocs: zlib.3.pdf\n\nzlib.3.pdf: zlib.3\n\tgroff -mandoc -f H -T ps zlib.3 | ps2pdf - zlib.3.pdf\n\nzconf.h.cmakein: zconf.h.in\n\t-@ TEMPFILE=zconfh_$$; \\\n\techo \"/#define ZCONF_H/ a\\\\\\\\\\n#cmakedefine Z_PREFIX\\\\\\\\\\n#cmakedefine Z_HAVE_UNISTD_H\\n\" >> $$TEMPFILE &&\\\n\tsed -f $$TEMPFILE zconf.h.in > zconf.h.cmakein &&\\\n\ttouch -r zconf.h.in zconf.h.cmakein &&\\\n\trm $$TEMPFILE\n\nzconf: zconf.h.in\n\tcp -p zconf.h.in zconf.h\n\nmostlyclean: clean\nclean:\n\trm -f *.o *.lo *~ \\\n\t   example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \\\n\t   example64$(EXE) minigzip64$(EXE) \\\n\t   infcover \\\n\t   libz.* foo.gz so_locations \\\n\t   _match.s maketree contrib/infback9/*.o\n\trm -rf objs\n\trm -f *.gcda *.gcno *.gcov\n\trm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov\n\nmaintainer-clean: distclean\ndistclean: clean zconf zconf.h.cmakein docs\n\trm -f Makefile zlib.pc configure.log\n\t-@rm -f .DS_Store\n\t-@printf 'all:\\n\\t-@echo \"Please use ./configure first.  Thank you.\"\\n' > Makefile\n\t-@printf '\\ndistclean:\\n\\tmake -f Makefile.in distclean\\n' >> Makefile\n\t-@touch -r Makefile.in Makefile\n\ntags:\n\tetags *.[ch]\n\ndepend:\n\tmakedepend -- $(CFLAGS) -- *.[ch]\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\nadler32.o zutil.o: zutil.h zlib.h zconf.h\ngzclose.o gzlib.o gzread.o gzwrite.o: zlib.h zconf.h gzguts.h\ncompress.o example.o minigzip.o uncompr.o: zlib.h zconf.h\ncrc32.o: zutil.h zlib.h zconf.h crc32.h\ndeflate.o: deflate.h zutil.h zlib.h zconf.h\ninfback.o inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h\ninffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h\ninftrees.o: zutil.h zlib.h zconf.h inftrees.h\ntrees.o: deflate.h zutil.h zlib.h zconf.h trees.h\n\nadler32.lo zutil.lo: zutil.h zlib.h zconf.h\ngzclose.lo gzlib.lo gzread.lo gzwrite.lo: zlib.h zconf.h gzguts.h\ncompress.lo example.lo minigzip.lo uncompr.lo: zlib.h zconf.h\ncrc32.lo: zutil.h zlib.h zconf.h crc32.h\ndeflate.lo: deflate.h zutil.h zlib.h zconf.h\ninfback.lo inflate.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h\ninffast.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h\ninftrees.lo: zutil.h zlib.h zconf.h inftrees.h\ntrees.lo: deflate.h zutil.h zlib.h zconf.h trees.h\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/README",
    "content": "ZLIB DATA COMPRESSION LIBRARY\n\nzlib 1.2.8 is a general purpose data compression library.  All the code is\nthread safe.  The data format used by the zlib library is described by RFCs\n(Request for Comments) 1950 to 1952 in the files\nhttp://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and\nrfc1952 (gzip format).\n\nAll functions of the compression library are documented in the file zlib.h\n(volunteer to write man pages welcome, contact zlib@gzip.org).  A usage example\nof the library is given in the file test/example.c which also tests that\nthe library is working correctly.  Another example is given in the file\ntest/minigzip.c.  The compression library itself is composed of all source\nfiles in the root directory.\n\nTo compile all files and run the test program, follow the instructions given at\nthe top of Makefile.in.  In short \"./configure; make test\", and if that goes\nwell, \"make install\" should work for most flavors of Unix.  For Windows, use\none of the special makefiles in win32/ or contrib/vstudio/ .  For VMS, use\nmake_vms.com.\n\nQuestions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant\n<info@winimage.com> for the Windows DLL version.  The zlib home page is\nhttp://zlib.net/ .  Before reporting a problem, please check this site to\nverify that you have the latest version of zlib; otherwise get the latest\nversion and check whether the problem still exists or not.\n\nPLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.\n\nMark Nelson <markn@ieee.org> wrote an article about zlib for the Jan.  1997\nissue of Dr.  Dobb's Journal; a copy of the article is available at\nhttp://marknelson.us/1997/01/01/zlib-engine/ .\n\nThe changes made in version 1.2.8 are documented in the file ChangeLog.\n\nUnsupported third party contributions are provided in directory contrib/ .\n\nzlib is available in Java using the java.util.zip package, documented at\nhttp://java.sun.com/developer/technicalArticles/Programming/compression/ .\n\nA Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available\nat CPAN (Comprehensive Perl Archive Network) sites, including\nhttp://search.cpan.org/~pmqs/IO-Compress-Zlib/ .\n\nA Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is\navailable in Python 1.5 and later versions, see\nhttp://docs.python.org/library/zlib.html .\n\nzlib is built into tcl: http://wiki.tcl.tk/4610 .\n\nAn experimental package to read and write files in .zip format, written on top\nof zlib by Gilles Vollant <info@winimage.com>, is available in the\ncontrib/minizip directory of zlib.\n\n\nNotes for some targets:\n\n- For Windows DLL versions, please see win32/DLL_FAQ.txt\n\n- For 64-bit Irix, deflate.c must be compiled without any optimization. With\n  -O, one libpng test fails. The test works in 32 bit mode (with the -n32\n  compiler flag). The compiler bug has been reported to SGI.\n\n- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works\n  when compiled with cc.\n\n- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is\n  necessary to get gzprintf working correctly. This is done by configure.\n\n- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with\n  other compilers. Use \"make test\" to check your compiler.\n\n- gzdopen is not supported on RISCOS or BEOS.\n\n- For PalmOs, see http://palmzlib.sourceforge.net/\n\n\nAcknowledgments:\n\n  The deflate format used by zlib was defined by Phil Katz.  The deflate and\n  zlib specifications were written by L.  Peter Deutsch.  Thanks to all the\n  people who reported problems and suggested various improvements in zlib; they\n  are too numerous to cite here.\n\nCopyright notice:\n\n (C) 1995-2013 Jean-loup Gailly and Mark Adler\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Jean-loup Gailly        Mark Adler\n  jloup@gzip.org          madler@alumni.caltech.edu\n\nIf you use the zlib library in a product, we would appreciate *not* receiving\nlengthy legal documents to sign.  The sources are provided for free but without\nwarranty of any kind.  The library has been entirely written by Jean-loup\nGailly and Mark Adler; it does not include third-party code.\n\nIf you redistribute modified sources, we would appreciate that you include in\nthe file ChangeLog history information documenting your changes.  Please read\nthe FAQ for more information on the distribution of modified source versions.\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/adler32.c",
    "content": "/* adler32.c -- compute the Adler-32 checksum of a data stream\n * Copyright (C) 1995-2011 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* @(#) $Id$ */\n\n#include \"zutil.h\"\n\n#define local static\n\nlocal uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));\n\n#define BASE 65521      /* largest prime smaller than 65536 */\n#define NMAX 5552\n/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */\n\n#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}\n#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);\n#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);\n#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);\n#define DO16(buf)   DO8(buf,0); DO8(buf,8);\n\n/* use NO_DIVIDE if your processor does not do division in hardware --\n   try it both ways to see which is faster */\n#ifdef NO_DIVIDE\n/* note that this assumes BASE is 65521, where 65536 % 65521 == 15\n   (thank you to John Reiser for pointing this out) */\n#  define CHOP(a) \\\n    do { \\\n        unsigned long tmp = a >> 16; \\\n        a &= 0xffffUL; \\\n        a += (tmp << 4) - tmp; \\\n    } while (0)\n#  define MOD28(a) \\\n    do { \\\n        CHOP(a); \\\n        if (a >= BASE) a -= BASE; \\\n    } while (0)\n#  define MOD(a) \\\n    do { \\\n        CHOP(a); \\\n        MOD28(a); \\\n    } while (0)\n#  define MOD63(a) \\\n    do { /* this assumes a is not negative */ \\\n        z_off64_t tmp = a >> 32; \\\n        a &= 0xffffffffL; \\\n        a += (tmp << 8) - (tmp << 5) + tmp; \\\n        tmp = a >> 16; \\\n        a &= 0xffffL; \\\n        a += (tmp << 4) - tmp; \\\n        tmp = a >> 16; \\\n        a &= 0xffffL; \\\n        a += (tmp << 4) - tmp; \\\n        if (a >= BASE) a -= BASE; \\\n    } while (0)\n#else\n#  define MOD(a) a %= BASE\n#  define MOD28(a) a %= BASE\n#  define MOD63(a) a %= BASE\n#endif\n\n/* ========================================================================= */\nuLong ZEXPORT adler32(adler, buf, len)\n    uLong adler;\n    const Bytef *buf;\n    uInt len;\n{\n    unsigned long sum2;\n    unsigned n;\n\n    /* split Adler-32 into component sums */\n    sum2 = (adler >> 16) & 0xffff;\n    adler &= 0xffff;\n\n    /* in case user likes doing a byte at a time, keep it fast */\n    if (len == 1) {\n        adler += buf[0];\n        if (adler >= BASE)\n            adler -= BASE;\n        sum2 += adler;\n        if (sum2 >= BASE)\n            sum2 -= BASE;\n        return adler | (sum2 << 16);\n    }\n\n    /* initial Adler-32 value (deferred check for len == 1 speed) */\n    if (buf == Z_NULL)\n        return 1L;\n\n    /* in case short lengths are provided, keep it somewhat fast */\n    if (len < 16) {\n        while (len--) {\n            adler += *buf++;\n            sum2 += adler;\n        }\n        if (adler >= BASE)\n            adler -= BASE;\n        MOD28(sum2);            /* only added so many BASE's */\n        return adler | (sum2 << 16);\n    }\n\n    /* do length NMAX blocks -- requires just one modulo operation */\n    while (len >= NMAX) {\n        len -= NMAX;\n        n = NMAX / 16;          /* NMAX is divisible by 16 */\n        do {\n            DO16(buf);          /* 16 sums unrolled */\n            buf += 16;\n        } while (--n);\n        MOD(adler);\n        MOD(sum2);\n    }\n\n    /* do remaining bytes (less than NMAX, still just one modulo) */\n    if (len) {                  /* avoid modulos if none remaining */\n        while (len >= 16) {\n            len -= 16;\n            DO16(buf);\n            buf += 16;\n        }\n        while (len--) {\n            adler += *buf++;\n            sum2 += adler;\n        }\n        MOD(adler);\n        MOD(sum2);\n    }\n\n    /* return recombined sums */\n    return adler | (sum2 << 16);\n}\n\n/* ========================================================================= */\nlocal uLong adler32_combine_(adler1, adler2, len2)\n    uLong adler1;\n    uLong adler2;\n    z_off64_t len2;\n{\n    unsigned long sum1;\n    unsigned long sum2;\n    unsigned rem;\n\n    /* for negative len, return invalid adler32 as a clue for debugging */\n    if (len2 < 0)\n        return 0xffffffffUL;\n\n    /* the derivation of this formula is left as an exercise for the reader */\n    MOD63(len2);                /* assumes len2 >= 0 */\n    rem = (unsigned)len2;\n    sum1 = adler1 & 0xffff;\n    sum2 = rem * sum1;\n    MOD(sum2);\n    sum1 += (adler2 & 0xffff) + BASE - 1;\n    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;\n    if (sum1 >= BASE) sum1 -= BASE;\n    if (sum1 >= BASE) sum1 -= BASE;\n    if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);\n    if (sum2 >= BASE) sum2 -= BASE;\n    return sum1 | (sum2 << 16);\n}\n\n/* ========================================================================= */\nuLong ZEXPORT adler32_combine(adler1, adler2, len2)\n    uLong adler1;\n    uLong adler2;\n    z_off_t len2;\n{\n    return adler32_combine_(adler1, adler2, len2);\n}\n\nuLong ZEXPORT adler32_combine64(adler1, adler2, len2)\n    uLong adler1;\n    uLong adler2;\n    z_off64_t len2;\n{\n    return adler32_combine_(adler1, adler2, len2);\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/amiga/Makefile.pup",
    "content": "# Amiga powerUP (TM) Makefile\n# makefile for libpng and SAS C V6.58/7.00 PPC compiler\n# Copyright (C) 1998 by Andreas R. Kleinert\n\nLIBNAME\t= libzip.a\n\nCC\t= scppc\nCFLAGS\t= NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \\\n\t  OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 NOVER\nAR\t= ppc-amigaos-ar cr\nRANLIB\t= ppc-amigaos-ranlib\nLD\t= ppc-amigaos-ld -r\nLDFLAGS\t= -o\nLDLIBS\t= LIB:scppc.a LIB:end.o\nRM\t= delete quiet\n\nOBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \\\n       uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o\n\nTEST_OBJS = example.o minigzip.o\n\nall: example minigzip\n\ncheck: test\ntest: all\n\texample\n\techo hello world | minigzip | minigzip -d\n\n$(LIBNAME): $(OBJS)\n\t$(AR) $@ $(OBJS)\n\t-$(RANLIB) $@\n\nexample: example.o $(LIBNAME)\n\t$(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)\n\nminigzip: minigzip.o $(LIBNAME)\n\t$(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)\n\nmostlyclean: clean\nclean:\n\t$(RM) *.o example minigzip $(LIBNAME) foo.gz\n\nzip:\n\tzip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \\\n\t  descrip.mms *.[ch]\n\ntgz:\n\tcd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \\\n\t  zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch]\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\nadler32.o: zlib.h zconf.h\ncompress.o: zlib.h zconf.h\ncrc32.o: crc32.h zlib.h zconf.h\ndeflate.o: deflate.h zutil.h zlib.h zconf.h\nexample.o: zlib.h zconf.h\ngzclose.o: zlib.h zconf.h gzguts.h\ngzlib.o: zlib.h zconf.h gzguts.h\ngzread.o: zlib.h zconf.h gzguts.h\ngzwrite.o: zlib.h zconf.h gzguts.h\ninffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h\ninflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h\ninfback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h\ninftrees.o: zutil.h zlib.h zconf.h inftrees.h\nminigzip.o: zlib.h zconf.h\ntrees.o: deflate.h zutil.h zlib.h zconf.h trees.h\nuncompr.o: zlib.h zconf.h\nzutil.o: zutil.h zlib.h zconf.h\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/amiga/Makefile.sas",
    "content": "# SMakefile for zlib\n# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly\n# Osma Ahvenlampi <Osma.Ahvenlampi@hut.fi>\n# Amiga, SAS/C 6.56 & Smake\n\nCC=sc\nCFLAGS=OPT\n#CFLAGS=OPT CPU=68030\n#CFLAGS=DEBUG=LINE\nLDFLAGS=LIB z.lib\n\nSCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \\\n       NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX \\\n       DEF=POSTINC\n\nOBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \\\n       uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o\n\nTEST_OBJS = example.o minigzip.o\n\nall: SCOPTIONS example minigzip\n\ncheck: test\ntest: all\n\texample\n\techo hello world | minigzip | minigzip -d\n\ninstall: z.lib\n\tcopy clone zlib.h zconf.h INCLUDE:\n\tcopy clone z.lib LIB:\n\nz.lib: $(OBJS)\n\toml z.lib r $(OBJS)\n\nexample: example.o z.lib\n\t$(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS)\n\nminigzip: minigzip.o z.lib\n\t$(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS)\n\nmostlyclean: clean\nclean:\n\t-delete force quiet example minigzip *.o z.lib foo.gz *.lnk SCOPTIONS\n\nSCOPTIONS: Makefile.sas\n\tcopy to $@ <from <\n$(SCOPTIONS)\n<\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\nadler32.o: zlib.h zconf.h\ncompress.o: zlib.h zconf.h\ncrc32.o: crc32.h zlib.h zconf.h\ndeflate.o: deflate.h zutil.h zlib.h zconf.h\nexample.o: zlib.h zconf.h\ngzclose.o: zlib.h zconf.h gzguts.h\ngzlib.o: zlib.h zconf.h gzguts.h\ngzread.o: zlib.h zconf.h gzguts.h\ngzwrite.o: zlib.h zconf.h gzguts.h\ninffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h\ninflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h\ninfback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h\ninftrees.o: zutil.h zlib.h zconf.h inftrees.h\nminigzip.o: zlib.h zconf.h\ntrees.o: deflate.h zutil.h zlib.h zconf.h trees.h\nuncompr.o: zlib.h zconf.h\nzutil.o: zutil.h zlib.h zconf.h\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/as400/bndsrc",
    "content": "STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB')\n\n/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/\n/*   Version 1.1.3 entry points.                                    */\n/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/\n\n/********************************************************************/\n/*   *MODULE      ADLER32      ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"adler32\")\n\n/********************************************************************/\n/*   *MODULE      COMPRESS     ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"compress\")\n  EXPORT SYMBOL(\"compress2\")\n\n/********************************************************************/\n/*   *MODULE      CRC32        ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"crc32\")\n  EXPORT SYMBOL(\"get_crc_table\")\n\n/********************************************************************/\n/*   *MODULE      DEFLATE      ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"deflate\")\n  EXPORT SYMBOL(\"deflateEnd\")\n  EXPORT SYMBOL(\"deflateSetDictionary\")\n  EXPORT SYMBOL(\"deflateCopy\")\n  EXPORT SYMBOL(\"deflateReset\")\n  EXPORT SYMBOL(\"deflateParams\")\n  EXPORT SYMBOL(\"deflatePrime\")\n  EXPORT SYMBOL(\"deflateInit_\")\n  EXPORT SYMBOL(\"deflateInit2_\")\n\n/********************************************************************/\n/*   *MODULE      GZIO         ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"gzopen\")\n  EXPORT SYMBOL(\"gzdopen\")\n  EXPORT SYMBOL(\"gzsetparams\")\n  EXPORT SYMBOL(\"gzread\")\n  EXPORT SYMBOL(\"gzwrite\")\n  EXPORT SYMBOL(\"gzprintf\")\n  EXPORT SYMBOL(\"gzputs\")\n  EXPORT SYMBOL(\"gzgets\")\n  EXPORT SYMBOL(\"gzputc\")\n  EXPORT SYMBOL(\"gzgetc\")\n  EXPORT SYMBOL(\"gzflush\")\n  EXPORT SYMBOL(\"gzseek\")\n  EXPORT SYMBOL(\"gzrewind\")\n  EXPORT SYMBOL(\"gztell\")\n  EXPORT SYMBOL(\"gzeof\")\n  EXPORT SYMBOL(\"gzclose\")\n  EXPORT SYMBOL(\"gzerror\")\n\n/********************************************************************/\n/*   *MODULE      INFLATE      ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"inflate\")\n  EXPORT SYMBOL(\"inflateEnd\")\n  EXPORT SYMBOL(\"inflateSetDictionary\")\n  EXPORT SYMBOL(\"inflateSync\")\n  EXPORT SYMBOL(\"inflateReset\")\n  EXPORT SYMBOL(\"inflateInit_\")\n  EXPORT SYMBOL(\"inflateInit2_\")\n  EXPORT SYMBOL(\"inflateSyncPoint\")\n\n/********************************************************************/\n/*   *MODULE      UNCOMPR      ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"uncompress\")\n\n/********************************************************************/\n/*   *MODULE      ZUTIL        ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"zlibVersion\")\n  EXPORT SYMBOL(\"zError\")\n\n/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/\n/*   Version 1.2.1 additional entry points.                         */\n/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/\n\n/********************************************************************/\n/*   *MODULE      COMPRESS     ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"compressBound\")\n\n/********************************************************************/\n/*   *MODULE      DEFLATE      ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"deflateBound\")\n\n/********************************************************************/\n/*   *MODULE      GZIO         ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"gzungetc\")\n  EXPORT SYMBOL(\"gzclearerr\")\n\n/********************************************************************/\n/*   *MODULE      INFBACK      ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"inflateBack\")\n  EXPORT SYMBOL(\"inflateBackEnd\")\n  EXPORT SYMBOL(\"inflateBackInit_\")\n\n/********************************************************************/\n/*   *MODULE      INFLATE      ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"inflateCopy\")\n\n/********************************************************************/\n/*   *MODULE      ZUTIL        ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"zlibCompileFlags\")\n\n/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/\n/*   Version 1.2.5 additional entry points.                         */\n/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/\n\n/********************************************************************/\n/*   *MODULE      ADLER32      ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"adler32_combine\")\n  EXPORT SYMBOL(\"adler32_combine64\")\n\n/********************************************************************/\n/*   *MODULE      CRC32        ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"crc32_combine\")\n  EXPORT SYMBOL(\"crc32_combine64\")\n\n/********************************************************************/\n/*   *MODULE      GZLIB        ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"gzbuffer\")\n  EXPORT SYMBOL(\"gzoffset\")\n  EXPORT SYMBOL(\"gzoffset64\")\n  EXPORT SYMBOL(\"gzopen64\")\n  EXPORT SYMBOL(\"gzseek64\")\n  EXPORT SYMBOL(\"gztell64\")\n\n/********************************************************************/\n/*   *MODULE      GZREAD       ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"gzclose_r\")\n\n/********************************************************************/\n/*   *MODULE      GZWRITE      ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"gzclose_w\")\n\n/********************************************************************/\n/*   *MODULE      INFLATE      ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"inflateMark\")\n  EXPORT SYMBOL(\"inflatePrime\")\n  EXPORT SYMBOL(\"inflateReset2\")\n  EXPORT SYMBOL(\"inflateUndermine\")\n\n/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/\n/*   Version 1.2.6 additional entry points.                         */\n/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/\n\n/********************************************************************/\n/*   *MODULE      DEFLATE      ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"deflateResetKeep\")\n  EXPORT SYMBOL(\"deflatePending\")\n\n/********************************************************************/\n/*   *MODULE      GZWRITE      ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"gzgetc_\")\n\n/********************************************************************/\n/*   *MODULE      INFLATE      ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"inflateResetKeep\")\n\n/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/\n/*   Version 1.2.8 additional entry points.                         */\n/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/\n\n/********************************************************************/\n/*   *MODULE      INFLATE      ZLIB         01/02/01  00:15:09      */\n/********************************************************************/\n\n  EXPORT SYMBOL(\"inflateGetDictionary\")\n\nENDPGMEXP\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/as400/compile.clp",
    "content": "/******************************************************************************/\n/*                                                                            */\n/*  ZLIB                                                                      */\n/*                                                                            */\n/*    Compile sources into modules and link them into a service program.      */\n/*                                                                            */\n/******************************************************************************/\n\n             PGM\n\n/*      Configuration adjustable parameters.                                  */\n\n             DCL        VAR(&SRCLIB) TYPE(*CHAR) LEN(10) +\n                          VALUE('ZLIB')                         /* Source library. */\n             DCL        VAR(&SRCFILE) TYPE(*CHAR) LEN(10) +\n                          VALUE('SOURCES')                      /* Source member file. */\n             DCL        VAR(&CTLFILE) TYPE(*CHAR) LEN(10) +\n                          VALUE('TOOLS')                        /* Control member file. */\n\n             DCL        VAR(&MODLIB) TYPE(*CHAR) LEN(10) +\n                          VALUE('ZLIB')                         /* Module library. */\n\n             DCL        VAR(&SRVLIB) TYPE(*CHAR) LEN(10) +\n                          VALUE('LGPL')                         /* Service program library. */\n\n             DCL        VAR(&CFLAGS) TYPE(*CHAR) +\n                          VALUE('OPTIMIZE(40)')                 /* Compile options. */\n\n             DCL        VAR(&TGTRLS) TYPE(*CHAR) +\n                          VALUE('V5R3M0')                       /* Target release. */\n\n\n/*      Working storage.                                                      */\n\n             DCL        VAR(&CMDLEN) TYPE(*DEC) LEN(15 5) VALUE(300)    /* Command length. */\n             DCL        VAR(&CMD) TYPE(*CHAR) LEN(512)\n             DCL        VAR(&FIXDCMD) TYPE(*CHAR) LEN(512)\n\n\n/*      Compile sources into modules.                                         */\n\n             CHGVAR     VAR(&FIXDCMD) VALUE('CRTCMOD' *BCAT &CFLAGS *BCAT      +\n                        'SYSIFCOPT(*IFS64IO)' *BCAT                            +\n                        'DEFINE(''_LARGEFILE64_SOURCE''' *BCAT                 +\n                        '''_LFS64_LARGEFILE=1'') TGTRLS(' *TCAT &TGTRLS *TCAT  +\n                        ') SRCFILE(' *TCAT &SRCLIB *TCAT '/' *TCAT             +\n                        &SRCFILE *TCAT ') MODULE(' *TCAT &MODLIB *TCAT '/')\n\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'ADLER32)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'COMPRESS)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'CRC32)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'DEFLATE)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZCLOSE)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZLIB)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZREAD)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZWRITE)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFBACK)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFFAST)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFLATE)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFTREES)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'TREES)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'UNCOMPR)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'ZUTIL)')\n             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)\n\n\n/*      Link modules into a service program.                                  */\n\n             CRTSRVPGM  SRVPGM(&SRVLIB/ZLIB) +\n                          MODULE(&MODLIB/ADLER32     &MODLIB/COMPRESS    +\n                                 &MODLIB/CRC32       &MODLIB/DEFLATE     +\n                                 &MODLIB/GZCLOSE     &MODLIB/GZLIB       +\n                                 &MODLIB/GZREAD      &MODLIB/GZWRITE     +\n                                 &MODLIB/INFBACK     &MODLIB/INFFAST     +\n                                 &MODLIB/INFLATE     &MODLIB/INFTREES    +\n                                 &MODLIB/TREES       &MODLIB/UNCOMPR     +\n                                 &MODLIB/ZUTIL)                          +\n                          SRCFILE(&SRCLIB/&CTLFILE) SRCMBR(BNDSRC)       +\n                          TEXT('ZLIB 1.2.8') TGTRLS(&TGTRLS)\n\n             ENDPGM\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/as400/readme.txt",
    "content": "        ZLIB version 1.2.8 for AS400 installation instructions\n\nI) From an AS400 *SAVF file:\n\n1)      Unpacking archive to an AS400 save file\n\nOn the AS400:\n\n_       Create the ZLIB AS400 library:\n\n        CRTLIB LIB(ZLIB) TYPE(*PROD) TEXT('ZLIB compression API library')\n\n_       Create a work save file, for example:\n\n                CRTSAVF FILE(ZLIB/ZLIBSAVF)\n\nOn a PC connected to the target AS400:\n\n_       Unpack the save file image to a PC file \"ZLIBSAVF\"\n_       Upload this file into the save file on the AS400, for example\n                using ftp in BINARY mode.\n\n\n2)      Populating the ZLIB AS400 source library\n\nOn the AS400:\n\n_       Extract the saved objects into the ZLIB AS400 library using:\n\nRSTOBJ OBJ(*ALL) SAVLIB(ZLIB) DEV(*SAVF) SAVF(ZLIB/ZLIBSAVF) RSTLIB(ZLIB)\n\n\n3)      Customize installation:\n\n_       Edit CL member ZLIB/TOOLS(COMPILE) and change parameters if needed,\n                according to the comments.\n\n_       Compile this member with:\n\n        CRTCLPGM PGM(ZLIB/COMPILE) SRCFILE(ZLIB/TOOLS) SRCMBR(COMPILE)\n\n\n4)      Compile and generate the service program:\n\n_       This can now be done by executing:\n\n        CALL PGM(ZLIB/COMPILE)\n\n\n\nII) From the original source distribution:\n\n1)      On the AS400, create the source library:\n\n        CRTLIB LIB(ZLIB) TYPE(*PROD) TEXT('ZLIB compression API library')\n\n2)      Create the source files:\n\n        CRTSRCPF FILE(ZLIB/SOURCES) RCDLEN(112) TEXT('ZLIB library modules')\n        CRTSRCPF FILE(ZLIB/H)       RCDLEN(112) TEXT('ZLIB library includes')\n        CRTSRCPF FILE(ZLIB/TOOLS)   RCDLEN(112) TEXT('ZLIB library control utilities')\n\n3)      From the machine hosting the distribution files, upload them (with\n                FTP in text mode, for example) according to the following table:\n\n    Original    AS400   AS400    AS400 AS400\n    file        file    member   type  description\n                SOURCES                Original ZLIB C subprogram sources\n    adler32.c           ADLER32  C     ZLIB - Compute the Adler-32 checksum of a dta strm\n    compress.c          COMPRESS C     ZLIB - Compress a memory buffer\n    crc32.c             CRC32    C     ZLIB - Compute the CRC-32 of a data stream\n    deflate.c           DEFLATE  C     ZLIB - Compress data using the deflation algorithm\n    gzclose.c           GZCLOSE  C     ZLIB - Close .gz files\n    gzlib.c             GZLIB    C     ZLIB - Miscellaneous .gz files IO support\n    gzread.c            GZREAD   C     ZLIB - Read .gz files\n    gzwrite.c           GZWRITE  C     ZLIB - Write .gz files\n    infback.c           INFBACK  C     ZLIB - Inflate using a callback interface\n    inffast.c           INFFAST  C     ZLIB - Fast proc. literals & length/distance pairs\n    inflate.c           INFLATE  C     ZLIB - Interface to inflate modules\n    inftrees.c          INFTREES C     ZLIB - Generate Huffman trees for efficient decode\n    trees.c             TREES    C     ZLIB - Output deflated data using Huffman coding\n    uncompr.c           UNCOMPR  C     ZLIB - Decompress a memory buffer\n    zutil.c             ZUTIL    C     ZLIB - Target dependent utility functions\n                H                      Original ZLIB C and ILE/RPG include files\n    crc32.h             CRC32    C     ZLIB - CRC32 tables\n    deflate.h           DEFLATE  C     ZLIB - Internal compression state\n    gzguts.h            GZGUTS   C     ZLIB - Definitions for the gzclose module\n    inffast.h           INFFAST  C     ZLIB - Header to use inffast.c\n    inffixed.h          INFFIXED C     ZLIB - Table for decoding fixed codes\n    inflate.h           INFLATE  C     ZLIB - Internal inflate state definitions\n    inftrees.h          INFTREES C     ZLIB - Header to use inftrees.c\n    trees.h             TREES    C     ZLIB - Created automatically with -DGEN_TREES_H\n    zconf.h             ZCONF    C     ZLIB - Compression library configuration\n    zlib.h              ZLIB     C     ZLIB - Compression library C user interface\n    as400/zlib.inc      ZLIB.INC RPGLE ZLIB - Compression library ILE RPG user interface\n    zutil.h             ZUTIL    C     ZLIB - Internal interface and configuration\n                TOOLS                  Building source software & AS/400 README\n    as400/bndsrc        BNDSRC         Entry point exportation list\n    as400/compile.clp   COMPILE  CLP   Compile sources & generate service program\n    as400/readme.txt    README   TXT   Installation instructions\n\n4)      Continue as in I)3).\n\n\n\n\nNotes:  For AS400 ILE RPG programmers, a /copy member defining the ZLIB\n                API prototypes for ILE RPG can be found in ZLIB/H(ZLIB.INC).\n                Please read comments in this member for more information.\n\n        Remember that most foreign textual data are ASCII coded: this\n                implementation does not handle conversion from/to ASCII, so\n                text data code conversions must be done explicitely.\n\n        Mainly for the reason above, always open zipped files in binary mode.\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/as400/zlib.inc",
    "content": "      *  ZLIB.INC - Interface to the general purpose compression library\n      *\n      *  ILE RPG400 version by Patrick Monnerat, DATASPHERE.\n      *  Version 1.2.8\n      *\n      *\n      *  WARNING:\n      *     Procedures inflateInit(), inflateInit2(), deflateInit(),\n      *         deflateInit2() and inflateBackInit() need to be called with\n      *         two additional arguments:\n      *         the package version string and the stream control structure.\n      *         size. This is needed because RPG lacks some macro feature.\n      *         Call these procedures as:\n      *             inflateInit(...: ZLIB_VERSION: %size(z_stream))\n      *\n      /if not defined(ZLIB_H_)\n      /define ZLIB_H_\n      *\n      **************************************************************************\n      *                               Constants\n      **************************************************************************\n      *\n      *  Versioning information.\n      *\n     D ZLIB_VERSION    C                   '1.2.8'\n     D ZLIB_VERNUM     C                   X'1280'\n     D ZLIB_VER_MAJOR  C                   1\n     D ZLIB_VER_MINOR  C                   2\n     D ZLIB_VER_REVISION...\n     D                 C                   8\n     D ZLIB_VER_SUBREVISION...\n     D                 C                   0\n      *\n      *  Other equates.\n      *\n     D Z_NO_FLUSH      C                   0\n     D Z_PARTIAL_FLUSH...\n     D                 C                   1\n     D Z_SYNC_FLUSH    C                   2\n     D Z_FULL_FLUSH    C                   3\n     D Z_FINISH        C                   4\n     D Z_BLOCK         C                   5\n     D Z_TREES         C                   6\n      *\n     D Z_OK            C                   0\n     D Z_STREAM_END    C                   1\n     D Z_NEED_DICT     C                   2\n     D Z_ERRNO         C                   -1\n     D Z_STREAM_ERROR  C                   -2\n     D Z_DATA_ERROR    C                   -3\n     D Z_MEM_ERROR     C                   -4\n     D Z_BUF_ERROR     C                   -5\n     DZ_VERSION_ERROR  C                   -6\n      *\n     D Z_NO_COMPRESSION...\n     D                 C                   0\n     D Z_BEST_SPEED    C                   1\n     D Z_BEST_COMPRESSION...\n     D                 C                   9\n     D Z_DEFAULT_COMPRESSION...\n     D                 C                   -1\n      *\n     D Z_FILTERED      C                   1\n     D Z_HUFFMAN_ONLY  C                   2\n     D Z_RLE           C                   3\n     D Z_DEFAULT_STRATEGY...\n     D                 C                   0\n      *\n     D Z_BINARY        C                   0\n     D Z_ASCII         C                   1\n     D Z_UNKNOWN       C                   2\n      *\n     D Z_DEFLATED      C                   8\n      *\n     D Z_NULL          C                   0\n      *\n      **************************************************************************\n      *                                 Types\n      **************************************************************************\n      *\n     D z_streamp       S               *                                        Stream struct ptr\n     D gzFile          S               *                                        File pointer\n     D z_off_t         S             10i 0                                      Stream offsets\n     D z_off64_t       S             20i 0                                      Stream offsets\n      *\n      **************************************************************************\n      *                               Structures\n      **************************************************************************\n      *\n      *  The GZIP encode/decode stream support structure.\n      *\n     D z_stream        DS                  align based(z_streamp)\n     D  zs_next_in                     *                                        Next input byte\n     D  zs_avail_in                  10U 0                                      Byte cnt at next_in\n     D  zs_total_in                  10U 0                                      Total bytes read\n     D  zs_next_out                    *                                        Output buffer ptr\n     D  zs_avail_out                 10U 0                                      Room left @ next_out\n     D  zs_total_out                 10U 0                                      Total bytes written\n     D  zs_msg                         *                                        Last errmsg or null\n     D  zs_state                       *                                        Internal state\n     D  zs_zalloc                      *   procptr                              Int. state allocator\n     D  zs_free                        *   procptr                              Int. state dealloc.\n     D  zs_opaque                      *                                        Private alloc. data\n     D  zs_data_type                 10i 0                                      ASC/BIN best guess\n     D  zs_adler                     10u 0                                      Uncompr. adler32 val\n     D                               10U 0                                      Reserved\n     D                               10U 0                                      Ptr. alignment\n      *\n      **************************************************************************\n      *                     Utility function prototypes\n      **************************************************************************\n      *\n     D compress        PR            10I 0 extproc('compress')\n     D  dest                      65535    options(*varsize)                    Destination buffer\n     D  destLen                      10U 0                                      Destination length\n     D  source                    65535    const options(*varsize)              Source buffer\n     D  sourceLen                    10u 0 value                                Source length\n      *\n     D compress2       PR            10I 0 extproc('compress2')\n     D  dest                      65535    options(*varsize)                    Destination buffer\n     D  destLen                      10U 0                                      Destination length\n     D  source                    65535    const options(*varsize)              Source buffer\n     D  sourceLen                    10U 0 value                                Source length\n     D  level                        10I 0 value                                Compression level\n      *\n     D compressBound   PR            10U 0 extproc('compressBound')\n     D  sourceLen                    10U 0 value\n      *\n     D uncompress      PR            10I 0 extproc('uncompress')\n     D  dest                      65535    options(*varsize)                    Destination buffer\n     D  destLen                      10U 0                                      Destination length\n     D  source                    65535    const options(*varsize)              Source buffer\n     D  sourceLen                    10U 0 value                                Source length\n      *\n      /if not defined(LARGE_FILES)\n     D gzopen          PR                  extproc('gzopen')\n     D                                     like(gzFile)\n     D  path                           *   value options(*string)               File pathname\n     D  mode                           *   value options(*string)               Open mode\n      /else\n     D gzopen          PR                  extproc('gzopen64')\n     D                                     like(gzFile)\n     D  path                           *   value options(*string)               File pathname\n     D  mode                           *   value options(*string)               Open mode\n      *\n     D gzopen64        PR                  extproc('gzopen64')\n     D                                     like(gzFile)\n     D  path                           *   value options(*string)               File pathname\n     D  mode                           *   value options(*string)               Open mode\n      /endif\n      *\n     D gzdopen         PR                  extproc('gzdopen')\n     D                                     like(gzFile)\n     D  fd                           10I 0 value                                File descriptor\n     D  mode                           *   value options(*string)               Open mode\n      *\n     D gzbuffer        PR            10I 0 extproc('gzbuffer')\n     D  file                               value like(gzFile)                   File pointer\n     D  size                         10U 0 value\n      *\n     D gzsetparams     PR            10I 0 extproc('gzsetparams')\n     D  file                               value like(gzFile)                   File pointer\n     D  level                        10I 0 value\n     D  strategy                     10I 0 value\n      *\n     D gzread          PR            10I 0 extproc('gzread')\n     D  file                               value like(gzFile)                   File pointer\n     D  buf                       65535    options(*varsize)                    Buffer\n     D  len                          10u 0 value                                Buffer length\n      *\n     D gzwrite         PR            10I 0 extproc('gzwrite')\n     D  file                               value like(gzFile)                   File pointer\n     D  buf                       65535    const options(*varsize)              Buffer\n     D  len                          10u 0 value                                Buffer length\n      *\n     D gzputs          PR            10I 0 extproc('gzputs')\n     D  file                               value like(gzFile)                   File pointer\n     D  s                              *   value options(*string)               String to output\n      *\n     D gzgets          PR              *   extproc('gzgets')\n     D  file                               value like(gzFile)                   File pointer\n     D  buf                       65535    options(*varsize)                    Read buffer\n     D  len                          10i 0 value                                Buffer length\n      *\n     D gzputc          PR            10i 0 extproc('gzputc')\n     D  file                               value like(gzFile)                   File pointer\n     D  c                            10I 0 value                                Character to write\n      *\n     D gzgetc          PR            10i 0 extproc('gzgetc')\n     D  file                               value like(gzFile)                   File pointer\n      *\n     D gzgetc_         PR            10i 0 extproc('gzgetc_')\n     D  file                               value like(gzFile)                   File pointer\n      *\n     D gzungetc        PR            10i 0 extproc('gzungetc')\n     D  c                            10I 0 value                                Character to push\n     D  file                               value like(gzFile)                   File pointer\n      *\n     D gzflush         PR            10i 0 extproc('gzflush')\n     D  file                               value like(gzFile)                   File pointer\n     D  flush                        10I 0 value                                Type of flush\n      *\n      /if not defined(LARGE_FILES)\n     D gzseek          PR                  extproc('gzseek')\n     D                                     like(z_off_t)\n     D  file                               value like(gzFile)                   File pointer\n     D  offset                             value like(z_off_t)                  Offset\n     D  whence                       10i 0 value                                Origin\n      /else\n     D gzseek          PR                  extproc('gzseek64')\n     D                                     like(z_off_t)\n     D  file                               value like(gzFile)                   File pointer\n     D  offset                             value like(z_off_t)                  Offset\n     D  whence                       10i 0 value                                Origin\n      *\n     D gzseek64        PR                  extproc('gzseek64')\n     D                                     like(z_off64_t)\n     D  file                               value like(gzFile)                   File pointer\n     D  offset                             value like(z_off64_t)                Offset\n     D  whence                       10i 0 value                                Origin\n      /endif\n      *\n     D gzrewind        PR            10i 0 extproc('gzrewind')\n     D  file                               value like(gzFile)                   File pointer\n      *\n      /if not defined(LARGE_FILES)\n     D gztell          PR                  extproc('gztell')\n     D                                     like(z_off_t)\n     D  file                               value like(gzFile)                   File pointer\n      /else\n     D gztell          PR                  extproc('gztell64')\n     D                                     like(z_off_t)\n     D  file                               value like(gzFile)                   File pointer\n      *\n     D gztell64        PR                  extproc('gztell64')\n     D                                     like(z_off64_t)\n     D  file                               value like(gzFile)                   File pointer\n      /endif\n      *\n      /if not defined(LARGE_FILES)\n     D gzoffset        PR                  extproc('gzoffset')\n     D                                     like(z_off_t)\n     D  file                               value like(gzFile)                   File pointer\n      /else\n     D gzoffset        PR                  extproc('gzoffset64')\n     D                                     like(z_off_t)\n     D  file                               value like(gzFile)                   File pointer\n      *\n     D gzoffset64      PR                  extproc('gzoffset64')\n     D                                     like(z_off64_t)\n     D  file                               value like(gzFile)                   File pointer\n      /endif\n      *\n     D gzeof           PR            10i 0 extproc('gzeof')\n     D  file                               value like(gzFile)                   File pointer\n      *\n     D gzclose_r       PR            10i 0 extproc('gzclose_r')\n     D  file                               value like(gzFile)                   File pointer\n      *\n     D gzclose_w       PR            10i 0 extproc('gzclose_w')\n     D  file                               value like(gzFile)                   File pointer\n      *\n     D gzclose         PR            10i 0 extproc('gzclose')\n     D  file                               value like(gzFile)                   File pointer\n      *\n     D gzerror         PR              *   extproc('gzerror')                   Error string\n     D  file                               value like(gzFile)                   File pointer\n     D  errnum                       10I 0                                      Error code\n      *\n     D gzclearerr      PR                  extproc('gzclearerr')\n     D  file                               value like(gzFile)                   File pointer\n      *\n      **************************************************************************\n      *                        Basic function prototypes\n      **************************************************************************\n      *\n     D zlibVersion     PR              *   extproc('zlibVersion')               Version string\n      *\n     D deflateInit     PR            10I 0 extproc('deflateInit_')              Init. compression\n     D  strm                               like(z_stream)                       Compression stream\n     D  level                        10I 0 value                                Compression level\n     D  version                        *   value options(*string)               Version string\n     D  stream_size                  10i 0 value                                Stream struct. size\n      *\n     D deflate         PR            10I 0 extproc('deflate')                   Compress data\n     D  strm                               like(z_stream)                       Compression stream\n     D  flush                        10I 0 value                                Flush type required\n      *\n     D deflateEnd      PR            10I 0 extproc('deflateEnd')                Termin. compression\n     D  strm                               like(z_stream)                       Compression stream\n      *\n     D inflateInit     PR            10I 0 extproc('inflateInit_')              Init. expansion\n     D  strm                               like(z_stream)                       Expansion stream\n     D  version                        *   value options(*string)               Version string\n     D  stream_size                  10i 0 value                                Stream struct. size\n      *\n     D inflate         PR            10I 0 extproc('inflate')                   Expand data\n     D  strm                               like(z_stream)                       Expansion stream\n     D  flush                        10I 0 value                                Flush type required\n      *\n     D inflateEnd      PR            10I 0 extproc('inflateEnd')                Termin. expansion\n     D  strm                               like(z_stream)                       Expansion stream\n      *\n      **************************************************************************\n      *                        Advanced function prototypes\n      **************************************************************************\n      *\n     D deflateInit2    PR            10I 0 extproc('deflateInit2_')             Init. compression\n     D  strm                               like(z_stream)                       Compression stream\n     D  level                        10I 0 value                                Compression level\n     D  method                       10I 0 value                                Compression method\n     D  windowBits                   10I 0 value                                log2(window size)\n     D  memLevel                     10I 0 value                                Mem/cmpress tradeoff\n     D  strategy                     10I 0 value                                Compression stategy\n     D  version                        *   value options(*string)               Version string\n     D  stream_size                  10i 0 value                                Stream struct. size\n      *\n     D deflateSetDictionary...\n     D                 PR            10I 0 extproc('deflateSetDictionary')      Init. dictionary\n     D  strm                               like(z_stream)                       Compression stream\n     D  dictionary                65535    const options(*varsize)              Dictionary bytes\n     D  dictLength                   10U 0 value                                Dictionary length\n      *\n     D deflateCopy     PR            10I 0 extproc('deflateCopy')               Compress strm 2 strm\n     D  dest                               like(z_stream)                       Destination stream\n     D  source                             like(z_stream)                       Source stream\n      *\n     D deflateReset    PR            10I 0 extproc('deflateReset')              End and init. stream\n     D  strm                               like(z_stream)                       Compression stream\n      *\n     D deflateParams   PR            10I 0 extproc('deflateParams')             Change level & strat\n     D  strm                               like(z_stream)                       Compression stream\n     D  level                        10I 0 value                                Compression level\n     D  strategy                     10I 0 value                                Compression stategy\n      *\n     D deflateBound    PR            10U 0 extproc('deflateBound')              Change level & strat\n     D  strm                               like(z_stream)                       Compression stream\n     D  sourcelen                    10U 0 value                                Compression level\n      *\n     D deflatePending  PR            10I 0 extproc('deflatePending')            Change level & strat\n     D  strm                               like(z_stream)                       Compression stream\n     D  pending                      10U 0                                      Pending bytes\n     D  bits                         10I 0                                      Pending bits\n      *\n     D deflatePrime    PR            10I 0 extproc('deflatePrime')              Change level & strat\n     D  strm                               like(z_stream)                       Compression stream\n     D  bits                         10I 0 value                                # of bits to insert\n     D  value                        10I 0 value                                Bits to insert\n      *\n     D inflateInit2    PR            10I 0 extproc('inflateInit2_')             Init. expansion\n     D  strm                               like(z_stream)                       Expansion stream\n     D  windowBits                   10I 0 value                                log2(window size)\n     D  version                        *   value options(*string)               Version string\n     D  stream_size                  10i 0 value                                Stream struct. size\n      *\n     D inflateSetDictionary...\n     D                 PR            10I 0 extproc('inflateSetDictionary')      Init. dictionary\n     D  strm                               like(z_stream)                       Expansion stream\n     D  dictionary                65535    const options(*varsize)              Dictionary bytes\n     D  dictLength                   10U 0 value                                Dictionary length\n      *\n     D inflateGetDictionary...\n     D                 PR            10I 0 extproc('inflateGetDictionary')      Get dictionary\n     D  strm                               like(z_stream)                       Expansion stream\n     D  dictionary                65535    options(*varsize)                    Dictionary bytes\n     D  dictLength                   10U 0                                      Dictionary length\n      *\n     D inflateSync     PR            10I 0 extproc('inflateSync')               Sync. expansion\n     D  strm                               like(z_stream)                       Expansion stream\n      *\n     D inflateCopy     PR            10I 0 extproc('inflateCopy')\n     D  dest                               like(z_stream)                       Destination stream\n     D  source                             like(z_stream)                       Source stream\n      *\n     D inflateReset    PR            10I 0 extproc('inflateReset')              End and init. stream\n     D  strm                               like(z_stream)                       Expansion stream\n      *\n     D inflateReset2   PR            10I 0 extproc('inflateReset2')             End and init. stream\n     D  strm                               like(z_stream)                       Expansion stream\n     D  windowBits                   10I 0 value                                Log2(buffer size)\n      *\n     D inflatePrime    PR            10I 0 extproc('inflatePrime')              Insert bits\n     D  strm                               like(z_stream)                       Expansion stream\n     D  bits                         10I 0 value                                Bit count\n     D  value                        10I 0 value                                Bits to insert\n      *\n     D inflateMark     PR            10I 0 extproc('inflateMark')               Get inflate info\n     D  strm                               like(z_stream)                       Expansion stream\n      *\n     D inflateBackInit...\n     D                 PR            10I 0 extproc('inflateBackInit_')\n     D  strm                               like(z_stream)                       Expansion stream\n     D  windowBits                   10I 0 value                                Log2(buffer size)\n     D  window                    65535    options(*varsize)                    Buffer\n     D  version                        *   value options(*string)               Version string\n     D  stream_size                  10i 0 value                                Stream struct. size\n      *\n     D inflateBack     PR            10I 0 extproc('inflateBack')\n     D  strm                               like(z_stream)                       Expansion stream\n     D  in                             *   value procptr                        Input function\n     D  in_desc                        *   value                                Input descriptor\n     D  out                            *   value procptr                        Output function\n     D  out_desc                       *   value                                Output descriptor\n      *\n     D inflateBackEnd  PR            10I 0 extproc('inflateBackEnd')\n     D  strm                               like(z_stream)                       Expansion stream\n      *\n     D zlibCompileFlags...\n     D                 PR            10U 0 extproc('zlibCompileFlags')\n      *\n      **************************************************************************\n      *                        Checksum function prototypes\n      **************************************************************************\n      *\n     D adler32         PR            10U 0 extproc('adler32')                   New checksum\n     D  adler                        10U 0 value                                Old checksum\n     D  buf                       65535    const options(*varsize)              Bytes to accumulate\n     D  len                          10U 0 value                                Buffer length\n      *\n     D crc32           PR            10U 0 extproc('crc32')                     New checksum\n     D  crc                          10U 0 value                                Old checksum\n     D  buf                       65535    const options(*varsize)              Bytes to accumulate\n     D  len                          10U 0 value                                Buffer length\n      *\n      **************************************************************************\n      *                     Miscellaneous function prototypes\n      **************************************************************************\n      *\n     D zError          PR              *   extproc('zError')                    Error string\n     D  err                          10I 0 value                                Error code\n      *\n     D inflateSyncPoint...\n     D                 PR            10I 0 extproc('inflateSyncPoint')\n     D  strm                               like(z_stream)                       Expansion stream\n      *\n     D get_crc_table   PR              *   extproc('get_crc_table')             Ptr to ulongs\n      *\n     D inflateUndermine...\n     D                 PR            10I 0 extproc('inflateUndermine')\n     D  strm                               like(z_stream)                       Expansion stream\n     D  arg                          10I 0 value                                Error code\n      *\n     D inflateResetKeep...\n     D                 PR            10I 0 extproc('inflateResetKeep')          End and init. stream\n     D  strm                               like(z_stream)                       Expansion stream\n      *\n     D deflateResetKeep...\n     D                 PR            10I 0 extproc('deflateResetKeep')          End and init. stream\n     D  strm                               like(z_stream)                       Expansion stream\n      *\n      /endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/compress.c",
    "content": "/* compress.c -- compress a memory buffer\n * Copyright (C) 1995-2005 Jean-loup Gailly.\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* @(#) $Id$ */\n\n#define ZLIB_INTERNAL\n#include \"zlib.h\"\n\n/* ===========================================================================\n     Compresses the source buffer into the destination buffer. The level\n   parameter has the same meaning as in deflateInit.  sourceLen is the byte\n   length of the source buffer. Upon entry, destLen is the total size of the\n   destination buffer, which must be at least 0.1% larger than sourceLen plus\n   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.\n\n     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_BUF_ERROR if there was not enough room in the output buffer,\n   Z_STREAM_ERROR if the level parameter is invalid.\n*/\nint ZEXPORT compress2 (dest, destLen, source, sourceLen, level)\n    Bytef *dest;\n    uLongf *destLen;\n    const Bytef *source;\n    uLong sourceLen;\n    int level;\n{\n    z_stream stream;\n    int err;\n\n    stream.next_in = (z_const Bytef *)source;\n    stream.avail_in = (uInt)sourceLen;\n#ifdef MAXSEG_64K\n    /* Check for source > 64K on 16-bit machine: */\n    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;\n#endif\n    stream.next_out = dest;\n    stream.avail_out = (uInt)*destLen;\n    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;\n\n    stream.zalloc = (alloc_func)0;\n    stream.zfree = (free_func)0;\n    stream.opaque = (voidpf)0;\n\n    err = deflateInit(&stream, level);\n    if (err != Z_OK) return err;\n\n    err = deflate(&stream, Z_FINISH);\n    if (err != Z_STREAM_END) {\n        deflateEnd(&stream);\n        return err == Z_OK ? Z_BUF_ERROR : err;\n    }\n    *destLen = stream.total_out;\n\n    err = deflateEnd(&stream);\n    return err;\n}\n\n/* ===========================================================================\n */\nint ZEXPORT compress (dest, destLen, source, sourceLen)\n    Bytef *dest;\n    uLongf *destLen;\n    const Bytef *source;\n    uLong sourceLen;\n{\n    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);\n}\n\n/* ===========================================================================\n     If the default memLevel or windowBits for deflateInit() is changed, then\n   this function needs to be updated.\n */\nuLong ZEXPORT compressBound (sourceLen)\n    uLong sourceLen;\n{\n    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +\n           (sourceLen >> 25) + 13;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/configure",
    "content": "#!/bin/sh\n# configure script for zlib.\n#\n# Normally configure builds both a static and a shared library.\n# If you want to build just a static library, use: ./configure --static\n#\n# To impose specific compiler or flags or install directory, use for example:\n#    prefix=$HOME CC=cc CFLAGS=\"-O4\" ./configure\n# or for csh/tcsh users:\n#    (setenv prefix $HOME; setenv CC cc; setenv CFLAGS \"-O4\"; ./configure)\n\n# Incorrect settings of CC or CFLAGS may prevent creating a shared library.\n# If you have problems, try without defining CC and CFLAGS before reporting\n# an error.\n\n# start off configure.log\necho -------------------- >> configure.log\necho $0 $* >> configure.log\ndate >> configure.log\n\n# set command prefix for cross-compilation\nif [ -n \"${CHOST}\" ]; then\n    uname=\"`echo \"${CHOST}\" | sed -e 's/^[^-]*-\\([^-]*\\)$/\\1/' -e 's/^[^-]*-[^-]*-\\([^-]*\\)$/\\1/' -e 's/^[^-]*-[^-]*-\\([^-]*\\)-.*$/\\1/'`\"\n    CROSS_PREFIX=\"${CHOST}-\"\nfi\n\n# destination name for static library\nSTATICLIB=libz.a\n\n# extract zlib version numbers from zlib.h\nVER=`sed -n -e '/VERSION \"/s/.*\"\\(.*\\)\".*/\\1/p' < zlib.h`\nVER3=`sed -n -e '/VERSION \"/s/.*\"\\([0-9]*\\\\.[0-9]*\\\\.[0-9]*\\).*/\\1/p' < zlib.h`\nVER2=`sed -n -e '/VERSION \"/s/.*\"\\([0-9]*\\\\.[0-9]*\\)\\\\..*/\\1/p' < zlib.h`\nVER1=`sed -n -e '/VERSION \"/s/.*\"\\([0-9]*\\)\\\\..*/\\1/p' < zlib.h`\n\n# establish commands for library building\nif \"${CROSS_PREFIX}ar\" --version >/dev/null 2>/dev/null || test $? -lt 126; then\n    AR=${AR-\"${CROSS_PREFIX}ar\"}\n    test -n \"${CROSS_PREFIX}\" && echo Using ${AR} | tee -a configure.log\nelse\n    AR=${AR-\"ar\"}\n    test -n \"${CROSS_PREFIX}\" && echo Using ${AR} | tee -a configure.log\nfi\nARFLAGS=${ARFLAGS-\"rc\"}\nif \"${CROSS_PREFIX}ranlib\" --version >/dev/null 2>/dev/null || test $? -lt 126; then\n    RANLIB=${RANLIB-\"${CROSS_PREFIX}ranlib\"}\n    test -n \"${CROSS_PREFIX}\" && echo Using ${RANLIB} | tee -a configure.log\nelse\n    RANLIB=${RANLIB-\"ranlib\"}\nfi\nif \"${CROSS_PREFIX}nm\" --version >/dev/null 2>/dev/null || test $? -lt 126; then\n    NM=${NM-\"${CROSS_PREFIX}nm\"}\n    test -n \"${CROSS_PREFIX}\" && echo Using ${NM} | tee -a configure.log\nelse\n    NM=${NM-\"nm\"}\nfi\n\n# set defaults before processing command line options\nLDCONFIG=${LDCONFIG-\"ldconfig\"}\nLDSHAREDLIBC=\"${LDSHAREDLIBC--lc}\"\nARCHS=\nprefix=${prefix-/usr/local}\nexec_prefix=${exec_prefix-'${prefix}'}\nlibdir=${libdir-'${exec_prefix}/lib'}\nsharedlibdir=${sharedlibdir-'${libdir}'}\nincludedir=${includedir-'${prefix}/include'}\nmandir=${mandir-'${prefix}/share/man'}\nshared_ext='.so'\nshared=1\nsolo=0\ncover=0\nzprefix=0\nzconst=0\nbuild64=0\ngcc=0\nold_cc=\"$CC\"\nold_cflags=\"$CFLAGS\"\nOBJC='$(OBJZ) $(OBJG)'\nPIC_OBJC='$(PIC_OBJZ) $(PIC_OBJG)'\n\n# leave this script, optionally in a bad way\nleave()\n{\n  if test \"$*\" != \"0\"; then\n    echo \"** $0 aborting.\" | tee -a configure.log\n  fi\n  rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version\n  echo -------------------- >> configure.log\n  echo >> configure.log\n  echo >> configure.log\n  exit $1\n}\n\n# process command line options\nwhile test $# -ge 1\ndo\ncase \"$1\" in\n    -h* | --help)\n      echo 'usage:' | tee -a configure.log\n      echo '  configure [--const] [--zprefix] [--prefix=PREFIX]  [--eprefix=EXPREFIX]' | tee -a configure.log\n      echo '    [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log\n      echo '    [--includedir=INCLUDEDIR] [--archs=\"-arch i386 -arch x86_64\"]' | tee -a configure.log\n        exit 0 ;;\n    -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;;\n    -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;;\n    -l*=* | --libdir=*) libdir=`echo $1 | sed 's/.*=//'`; shift ;;\n    --sharedlibdir=*) sharedlibdir=`echo $1 | sed 's/.*=//'`; shift ;;\n    -i*=* | --includedir=*) includedir=`echo $1 | sed 's/.*=//'`;shift ;;\n    -u*=* | --uname=*) uname=`echo $1 | sed 's/.*=//'`;shift ;;\n    -p* | --prefix) prefix=\"$2\"; shift; shift ;;\n    -e* | --eprefix) exec_prefix=\"$2\"; shift; shift ;;\n    -l* | --libdir) libdir=\"$2\"; shift; shift ;;\n    -i* | --includedir) includedir=\"$2\"; shift; shift ;;\n    -s* | --shared | --enable-shared) shared=1; shift ;;\n    -t | --static) shared=0; shift ;;\n    --solo) solo=1; shift ;;\n    --cover) cover=1; shift ;;\n    -z* | --zprefix) zprefix=1; shift ;;\n    -6* | --64) build64=1; shift ;;\n    -a*=* | --archs=*) ARCHS=`echo $1 | sed 's/.*=//'`; shift ;;\n    --sysconfdir=*) echo \"ignored option: --sysconfdir\" | tee -a configure.log; shift ;;\n    --localstatedir=*) echo \"ignored option: --localstatedir\" | tee -a configure.log; shift ;;\n    -c* | --const) zconst=1; shift ;;\n    *)\n      echo \"unknown option: $1\" | tee -a configure.log\n      echo \"$0 --help for help\" | tee -a configure.log\n      leave 1;;\n    esac\ndone\n\n# temporary file name\ntest=ztest$$\n\n# put arguments in log, also put test file in log if used in arguments\nshow()\n{\n  case \"$*\" in\n    *$test.c*)\n      echo === $test.c === >> configure.log\n      cat $test.c >> configure.log\n      echo === >> configure.log;;\n  esac\n  echo $* >> configure.log\n}\n\n# check for gcc vs. cc and set compile and link flags based on the system identified by uname\ncat > $test.c <<EOF\nextern int getchar();\nint hello() {return getchar();}\nEOF\n\ntest -z \"$CC\" && echo Checking for ${CROSS_PREFIX}gcc... | tee -a configure.log\ncc=${CC-${CROSS_PREFIX}gcc}\ncflags=${CFLAGS-\"-O3\"}\n# to force the asm version use: CFLAGS=\"-O3 -DASMV\" ./configure\ncase \"$cc\" in\n  *gcc*) gcc=1 ;;\n  *clang*) gcc=1 ;;\nesac\ncase `$cc -v 2>&1` in\n  *gcc*) gcc=1 ;;\nesac\n\nshow $cc -c $test.c\nif test \"$gcc\" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then\n  echo ... using gcc >> configure.log\n  CC=\"$cc\"\n  CFLAGS=\"${CFLAGS--O3} ${ARCHS}\"\n  SFLAGS=\"${CFLAGS--O3} -fPIC\"\n  LDFLAGS=\"${LDFLAGS} ${ARCHS}\"\n  if test $build64 -eq 1; then\n    CFLAGS=\"${CFLAGS} -m64\"\n    SFLAGS=\"${SFLAGS} -m64\"\n  fi\n  if test \"${ZLIBGCCWARN}\" = \"YES\"; then\n    if test \"$zconst\" -eq 1; then\n      CFLAGS=\"${CFLAGS} -Wall -Wextra -Wcast-qual -pedantic -DZLIB_CONST\"\n    else\n      CFLAGS=\"${CFLAGS} -Wall -Wextra -pedantic\"\n    fi\n  fi\n  if test -z \"$uname\"; then\n    uname=`(uname -s || echo unknown) 2>/dev/null`\n  fi\n  case \"$uname\" in\n  Linux* | linux* | GNU | GNU/* | solaris*)\n        LDSHARED=${LDSHARED-\"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map\"} ;;\n  *BSD | *bsd* | DragonFly)\n        LDSHARED=${LDSHARED-\"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map\"}\n        LDCONFIG=\"ldconfig -m\" ;;\n  CYGWIN* | Cygwin* | cygwin* | OS/2*)\n        EXE='.exe' ;;\n  MINGW* | mingw*)\n# temporary bypass\n        rm -f $test.[co] $test $test$shared_ext\n        echo \"Please use win32/Makefile.gcc instead.\" | tee -a configure.log\n        leave 1\n        LDSHARED=${LDSHARED-\"$cc -shared\"}\n        LDSHAREDLIBC=\"\"\n        EXE='.exe' ;;\n  QNX*)  # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4\n         # (alain.bonnefoy@icbt.com)\n                 LDSHARED=${LDSHARED-\"$cc -shared -Wl,-hlibz.so.1\"} ;;\n  HP-UX*)\n         LDSHARED=${LDSHARED-\"$cc -shared $SFLAGS\"}\n         case `(uname -m || echo unknown) 2>/dev/null` in\n         ia64)\n                 shared_ext='.so'\n                 SHAREDLIB='libz.so' ;;\n         *)\n                 shared_ext='.sl'\n                 SHAREDLIB='libz.sl' ;;\n         esac ;;\n  Darwin* | darwin*)\n             shared_ext='.dylib'\n             SHAREDLIB=libz$shared_ext\n             SHAREDLIBV=libz.$VER$shared_ext\n             SHAREDLIBM=libz.$VER1$shared_ext\n             LDSHARED=${LDSHARED-\"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3\"}\n             if libtool -V 2>&1 | grep Apple > /dev/null; then\n                 AR=\"libtool\"\n             else\n                 AR=\"/usr/bin/libtool\"\n             fi\n             ARFLAGS=\"-o\" ;;\n  *)             LDSHARED=${LDSHARED-\"$cc -shared\"} ;;\n  esac\nelse\n  # find system name and corresponding cc options\n  CC=${CC-cc}\n  gcc=0\n  echo ... using $CC >> configure.log\n  if test -z \"$uname\"; then\n    uname=`(uname -sr || echo unknown) 2>/dev/null`\n  fi\n  case \"$uname\" in\n  HP-UX*)    SFLAGS=${CFLAGS-\"-O +z\"}\n             CFLAGS=${CFLAGS-\"-O\"}\n#            LDSHARED=${LDSHARED-\"ld -b +vnocompatwarnings\"}\n             LDSHARED=${LDSHARED-\"ld -b\"}\n         case `(uname -m || echo unknown) 2>/dev/null` in\n         ia64)\n             shared_ext='.so'\n             SHAREDLIB='libz.so' ;;\n         *)\n             shared_ext='.sl'\n             SHAREDLIB='libz.sl' ;;\n         esac ;;\n  IRIX*)     SFLAGS=${CFLAGS-\"-ansi -O2 -rpath .\"}\n             CFLAGS=${CFLAGS-\"-ansi -O2\"}\n             LDSHARED=${LDSHARED-\"cc -shared -Wl,-soname,libz.so.1\"} ;;\n  OSF1\\ V4*) SFLAGS=${CFLAGS-\"-O -std1\"}\n             CFLAGS=${CFLAGS-\"-O -std1\"}\n             LDFLAGS=\"${LDFLAGS} -Wl,-rpath,.\"\n             LDSHARED=${LDSHARED-\"cc -shared  -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0\"} ;;\n  OSF1*)     SFLAGS=${CFLAGS-\"-O -std1\"}\n             CFLAGS=${CFLAGS-\"-O -std1\"}\n             LDSHARED=${LDSHARED-\"cc -shared -Wl,-soname,libz.so.1\"} ;;\n  QNX*)      SFLAGS=${CFLAGS-\"-4 -O\"}\n             CFLAGS=${CFLAGS-\"-4 -O\"}\n             LDSHARED=${LDSHARED-\"cc\"}\n             RANLIB=${RANLIB-\"true\"}\n             AR=\"cc\"\n             ARFLAGS=\"-A\" ;;\n  SCO_SV\\ 3.2*) SFLAGS=${CFLAGS-\"-O3 -dy -KPIC \"}\n             CFLAGS=${CFLAGS-\"-O3\"}\n             LDSHARED=${LDSHARED-\"cc -dy -KPIC -G\"} ;;\n  SunOS\\ 5* | solaris*)\n         LDSHARED=${LDSHARED-\"cc -G -h libz$shared_ext.$VER1\"}\n         SFLAGS=${CFLAGS-\"-fast -KPIC\"}\n         CFLAGS=${CFLAGS-\"-fast\"}\n         if test $build64 -eq 1; then\n             # old versions of SunPRO/Workshop/Studio don't support -m64,\n             # but newer ones do.  Check for it.\n             flag64=`$CC -flags | egrep -- '^-m64'`\n             if test x\"$flag64\" != x\"\" ; then\n                 CFLAGS=\"${CFLAGS} -m64\"\n                 SFLAGS=\"${SFLAGS} -m64\"\n             else\n                 case `(uname -m || echo unknown) 2>/dev/null` in\n                   i86*)\n                     SFLAGS=\"$SFLAGS -xarch=amd64\"\n                     CFLAGS=\"$CFLAGS -xarch=amd64\" ;;\n                   *)\n                     SFLAGS=\"$SFLAGS -xarch=v9\"\n                     CFLAGS=\"$CFLAGS -xarch=v9\" ;;\n                 esac\n             fi\n         fi\n         ;;\n  SunOS\\ 4*) SFLAGS=${CFLAGS-\"-O2 -PIC\"}\n             CFLAGS=${CFLAGS-\"-O2\"}\n             LDSHARED=${LDSHARED-\"ld\"} ;;\n  SunStudio\\ 9*) SFLAGS=${CFLAGS-\"-fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b\"}\n             CFLAGS=${CFLAGS-\"-fast -xtarget=ultra3 -xarch=v9b\"}\n             LDSHARED=${LDSHARED-\"cc -xarch=v9b\"} ;;\n  UNIX_System_V\\ 4.2.0)\n             SFLAGS=${CFLAGS-\"-KPIC -O\"}\n             CFLAGS=${CFLAGS-\"-O\"}\n             LDSHARED=${LDSHARED-\"cc -G\"} ;;\n  UNIX_SV\\ 4.2MP)\n             SFLAGS=${CFLAGS-\"-Kconform_pic -O\"}\n             CFLAGS=${CFLAGS-\"-O\"}\n             LDSHARED=${LDSHARED-\"cc -G\"} ;;\n  OpenUNIX\\ 5)\n             SFLAGS=${CFLAGS-\"-KPIC -O\"}\n             CFLAGS=${CFLAGS-\"-O\"}\n             LDSHARED=${LDSHARED-\"cc -G\"} ;;\n  AIX*)  # Courtesy of dbakker@arrayasolutions.com\n             SFLAGS=${CFLAGS-\"-O -qmaxmem=8192\"}\n             CFLAGS=${CFLAGS-\"-O -qmaxmem=8192\"}\n             LDSHARED=${LDSHARED-\"xlc -G\"} ;;\n  # send working options for other systems to zlib@gzip.org\n  *)         SFLAGS=${CFLAGS-\"-O\"}\n             CFLAGS=${CFLAGS-\"-O\"}\n             LDSHARED=${LDSHARED-\"cc -shared\"} ;;\n  esac\nfi\n\n# destination names for shared library if not defined above\nSHAREDLIB=${SHAREDLIB-\"libz$shared_ext\"}\nSHAREDLIBV=${SHAREDLIBV-\"libz$shared_ext.$VER\"}\nSHAREDLIBM=${SHAREDLIBM-\"libz$shared_ext.$VER1\"}\n\necho >> configure.log\n\n# define functions for testing compiler and library characteristics and logging the results\n\ncat > $test.c <<EOF\n#error error\nEOF\nif ($CC -c $CFLAGS $test.c) 2>/dev/null; then\n  try()\n  {\n    show $*\n    test \"`( $* ) 2>&1 | tee -a configure.log`\" = \"\"\n  }\n  echo - using any output from compiler to indicate an error >> configure.log\nelse\ntry()\n{\n  show $*\n  ( $* ) >> configure.log 2>&1\n  ret=$?\n  if test $ret -ne 0; then\n    echo \"(exit code \"$ret\")\" >> configure.log\n  fi\n  return $ret\n}\nfi\n\ntryboth()\n{\n  show $*\n  got=`( $* ) 2>&1`\n  ret=$?\n  printf %s \"$got\" >> configure.log\n  if test $ret -ne 0; then\n    return $ret\n  fi\n  test \"$got\" = \"\"\n}\n\ncat > $test.c << EOF\nint foo() { return 0; }\nEOF\necho \"Checking for obsessive-compulsive compiler options...\" >> configure.log\nif try $CC -c $CFLAGS $test.c; then\n  :\nelse\n  echo \"Compiler error reporting is too harsh for $0 (perhaps remove -Werror).\" | tee -a configure.log\n  leave 1\nfi\n\necho >> configure.log\n\n# see if shared library build supported\ncat > $test.c <<EOF\nextern int getchar();\nint hello() {return getchar();}\nEOF\nif test $shared -eq 1; then\n  echo Checking for shared library support... | tee -a configure.log\n  # we must test in two steps (cc then ld), required at least on SunOS 4.x\n  if try $CC -w -c $SFLAGS $test.c &&\n     try $LDSHARED $SFLAGS -o $test$shared_ext $test.o; then\n    echo Building shared library $SHAREDLIBV with $CC. | tee -a configure.log\n  elif test -z \"$old_cc\" -a -z \"$old_cflags\"; then\n    echo No shared library support. | tee -a configure.log\n    shared=0;\n  else\n    echo 'No shared library support; try without defining CC and CFLAGS' | tee -a configure.log\n    shared=0;\n  fi\nfi\nif test $shared -eq 0; then\n  LDSHARED=\"$CC\"\n  ALL=\"static\"\n  TEST=\"all teststatic\"\n  SHAREDLIB=\"\"\n  SHAREDLIBV=\"\"\n  SHAREDLIBM=\"\"\n  echo Building static library $STATICLIB version $VER with $CC. | tee -a configure.log\nelse\n  ALL=\"static shared\"\n  TEST=\"all teststatic testshared\"\nfi\n\n# check for underscores in external names for use by assembler code\nCPP=${CPP-\"$CC -E\"}\ncase $CFLAGS in\n  *ASMV*)\n    echo >> configure.log\n    show \"$NM $test.o | grep _hello\"\n    if test \"`$NM $test.o | grep _hello | tee -a configure.log`\" = \"\"; then\n      CPP=\"$CPP -DNO_UNDERLINE\"\n      echo Checking for underline in external names... No. | tee -a configure.log\n    else\n      echo Checking for underline in external names... Yes. | tee -a configure.log\n    fi ;;\nesac\n\necho >> configure.log\n\n# check for large file support, and if none, check for fseeko()\ncat > $test.c <<EOF\n#include <sys/types.h>\noff64_t dummy = 0;\nEOF\nif try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then\n  CFLAGS=\"${CFLAGS} -D_LARGEFILE64_SOURCE=1\"\n  SFLAGS=\"${SFLAGS} -D_LARGEFILE64_SOURCE=1\"\n  ALL=\"${ALL} all64\"\n  TEST=\"${TEST} test64\"\n  echo \"Checking for off64_t... Yes.\" | tee -a configure.log\n  echo \"Checking for fseeko... Yes.\" | tee -a configure.log\nelse\n  echo \"Checking for off64_t... No.\" | tee -a configure.log\n  echo >> configure.log\n  cat > $test.c <<EOF\n#include <stdio.h>\nint main(void) {\n  fseeko(NULL, 0, 0);\n  return 0;\n}\nEOF\n  if try $CC $CFLAGS -o $test $test.c; then\n    echo \"Checking for fseeko... Yes.\" | tee -a configure.log\n  else\n    CFLAGS=\"${CFLAGS} -DNO_FSEEKO\"\n    SFLAGS=\"${SFLAGS} -DNO_FSEEKO\"\n    echo \"Checking for fseeko... No.\" | tee -a configure.log\n  fi\nfi\n\necho >> configure.log\n\n# check for strerror() for use by gz* functions\ncat > $test.c <<EOF\n#include <string.h>\n#include <errno.h>\nint main() { return strlen(strerror(errno)); }\nEOF\nif try $CC $CFLAGS -o $test $test.c; then\n  echo \"Checking for strerror... Yes.\" | tee -a configure.log\nelse\n  CFLAGS=\"${CFLAGS} -DNO_STRERROR\"\n  SFLAGS=\"${SFLAGS} -DNO_STRERROR\"\n  echo \"Checking for strerror... No.\" | tee -a configure.log\nfi\n\n# copy clean zconf.h for subsequent edits\ncp -p zconf.h.in zconf.h\n\necho >> configure.log\n\n# check for unistd.h and save result in zconf.h\ncat > $test.c <<EOF\n#include <unistd.h>\nint main() { return 0; }\nEOF\nif try $CC -c $CFLAGS $test.c; then\n  sed < zconf.h \"/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\\(.*\\) may be/ 1\\1 was/\" > zconf.temp.h\n  mv zconf.temp.h zconf.h\n  echo \"Checking for unistd.h... Yes.\" | tee -a configure.log\nelse\n  echo \"Checking for unistd.h... No.\" | tee -a configure.log\nfi\n\necho >> configure.log\n\n# check for stdarg.h and save result in zconf.h\ncat > $test.c <<EOF\n#include <stdarg.h>\nint main() { return 0; }\nEOF\nif try $CC -c $CFLAGS $test.c; then\n  sed < zconf.h \"/^#ifdef HAVE_STDARG_H.* may be/s/def HAVE_STDARG_H\\(.*\\) may be/ 1\\1 was/\" > zconf.temp.h\n  mv zconf.temp.h zconf.h\n  echo \"Checking for stdarg.h... Yes.\" | tee -a configure.log\nelse\n  echo \"Checking for stdarg.h... No.\" | tee -a configure.log\nfi\n\n# if the z_ prefix was requested, save that in zconf.h\nif test $zprefix -eq 1; then\n  sed < zconf.h \"/#ifdef Z_PREFIX.* may be/s/def Z_PREFIX\\(.*\\) may be/ 1\\1 was/\" > zconf.temp.h\n  mv zconf.temp.h zconf.h\n  echo >> configure.log\n  echo \"Using z_ prefix on all symbols.\" | tee -a configure.log\nfi\n\n# if --solo compilation was requested, save that in zconf.h and remove gz stuff from object lists\nif test $solo -eq 1; then\n  sed '/#define ZCONF_H/a\\\n#define Z_SOLO\n\n' < zconf.h > zconf.temp.h\n  mv zconf.temp.h zconf.h\nOBJC='$(OBJZ)'\nPIC_OBJC='$(PIC_OBJZ)'\nfi\n\n# if code coverage testing was requested, use older gcc if defined, e.g. \"gcc-4.2\" on Mac OS X\nif test $cover -eq 1; then\n  CFLAGS=\"${CFLAGS} -fprofile-arcs -ftest-coverage\"\n  if test -n \"$GCC_CLASSIC\"; then\n    CC=$GCC_CLASSIC\n  fi\nfi\n\necho >> configure.log\n\n# conduct a series of tests to resolve eight possible cases of using \"vs\" or \"s\" printf functions\n# (using stdarg or not), with or without \"n\" (proving size of buffer), and with or without a\n# return value.  The most secure result is vsnprintf() with a return value.  snprintf() with a\n# return value is secure as well, but then gzprintf() will be limited to 20 arguments.\ncat > $test.c <<EOF\n#include <stdio.h>\n#include <stdarg.h>\n#include \"zconf.h\"\nint main()\n{\n#ifndef STDC\n  choke me\n#endif\n  return 0;\n}\nEOF\nif try $CC -c $CFLAGS $test.c; then\n  echo \"Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf().\" | tee -a configure.log\n\n  echo >> configure.log\n  cat > $test.c <<EOF\n#include <stdio.h>\n#include <stdarg.h>\nint mytest(const char *fmt, ...)\n{\n  char buf[20];\n  va_list ap;\n  va_start(ap, fmt);\n  vsnprintf(buf, sizeof(buf), fmt, ap);\n  va_end(ap);\n  return 0;\n}\nint main()\n{\n  return (mytest(\"Hello%d\\n\", 1));\n}\nEOF\n  if try $CC $CFLAGS -o $test $test.c; then\n    echo \"Checking for vsnprintf() in stdio.h... Yes.\" | tee -a configure.log\n\n    echo >> configure.log\n    cat >$test.c <<EOF\n#include <stdio.h>\n#include <stdarg.h>\nint mytest(const char *fmt, ...)\n{\n  int n;\n  char buf[20];\n  va_list ap;\n  va_start(ap, fmt);\n  n = vsnprintf(buf, sizeof(buf), fmt, ap);\n  va_end(ap);\n  return n;\n}\nint main()\n{\n  return (mytest(\"Hello%d\\n\", 1));\n}\nEOF\n\n    if try $CC -c $CFLAGS $test.c; then\n      echo \"Checking for return value of vsnprintf()... Yes.\" | tee -a configure.log\n    else\n      CFLAGS=\"$CFLAGS -DHAS_vsnprintf_void\"\n      SFLAGS=\"$SFLAGS -DHAS_vsnprintf_void\"\n      echo \"Checking for return value of vsnprintf()... No.\" | tee -a configure.log\n      echo \"  WARNING: apparently vsnprintf() does not return a value. zlib\" | tee -a configure.log\n      echo \"  can build but will be open to possible string-format security\" | tee -a configure.log\n      echo \"  vulnerabilities.\" | tee -a configure.log\n    fi\n  else\n    CFLAGS=\"$CFLAGS -DNO_vsnprintf\"\n    SFLAGS=\"$SFLAGS -DNO_vsnprintf\"\n    echo \"Checking for vsnprintf() in stdio.h... No.\" | tee -a configure.log\n    echo \"  WARNING: vsnprintf() not found, falling back to vsprintf(). zlib\" | tee -a configure.log\n    echo \"  can build but will be open to possible buffer-overflow security\" | tee -a configure.log\n    echo \"  vulnerabilities.\" | tee -a configure.log\n\n    echo >> configure.log\n    cat >$test.c <<EOF\n#include <stdio.h>\n#include <stdarg.h>\nint mytest(const char *fmt, ...)\n{\n  int n;\n  char buf[20];\n  va_list ap;\n  va_start(ap, fmt);\n  n = vsprintf(buf, fmt, ap);\n  va_end(ap);\n  return n;\n}\nint main()\n{\n  return (mytest(\"Hello%d\\n\", 1));\n}\nEOF\n\n    if try $CC -c $CFLAGS $test.c; then\n      echo \"Checking for return value of vsprintf()... Yes.\" | tee -a configure.log\n    else\n      CFLAGS=\"$CFLAGS -DHAS_vsprintf_void\"\n      SFLAGS=\"$SFLAGS -DHAS_vsprintf_void\"\n      echo \"Checking for return value of vsprintf()... No.\" | tee -a configure.log\n      echo \"  WARNING: apparently vsprintf() does not return a value. zlib\" | tee -a configure.log\n      echo \"  can build but will be open to possible string-format security\" | tee -a configure.log\n      echo \"  vulnerabilities.\" | tee -a configure.log\n    fi\n  fi\nelse\n  echo \"Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf().\" | tee -a configure.log\n\n  echo >> configure.log\n  cat >$test.c <<EOF\n#include <stdio.h>\nint mytest()\n{\n  char buf[20];\n  snprintf(buf, sizeof(buf), \"%s\", \"foo\");\n  return 0;\n}\nint main()\n{\n  return (mytest());\n}\nEOF\n\n  if try $CC $CFLAGS -o $test $test.c; then\n    echo \"Checking for snprintf() in stdio.h... Yes.\" | tee -a configure.log\n\n    echo >> configure.log\n    cat >$test.c <<EOF\n#include <stdio.h>\nint mytest()\n{\n  char buf[20];\n  return snprintf(buf, sizeof(buf), \"%s\", \"foo\");\n}\nint main()\n{\n  return (mytest());\n}\nEOF\n\n    if try $CC -c $CFLAGS $test.c; then\n      echo \"Checking for return value of snprintf()... Yes.\" | tee -a configure.log\n    else\n      CFLAGS=\"$CFLAGS -DHAS_snprintf_void\"\n      SFLAGS=\"$SFLAGS -DHAS_snprintf_void\"\n      echo \"Checking for return value of snprintf()... No.\" | tee -a configure.log\n      echo \"  WARNING: apparently snprintf() does not return a value. zlib\" | tee -a configure.log\n      echo \"  can build but will be open to possible string-format security\" | tee -a configure.log\n      echo \"  vulnerabilities.\" | tee -a configure.log\n    fi\n  else\n    CFLAGS=\"$CFLAGS -DNO_snprintf\"\n    SFLAGS=\"$SFLAGS -DNO_snprintf\"\n    echo \"Checking for snprintf() in stdio.h... No.\" | tee -a configure.log\n    echo \"  WARNING: snprintf() not found, falling back to sprintf(). zlib\" | tee -a configure.log\n    echo \"  can build but will be open to possible buffer-overflow security\" | tee -a configure.log\n    echo \"  vulnerabilities.\" | tee -a configure.log\n\n    echo >> configure.log\n    cat >$test.c <<EOF\n#include <stdio.h>\nint mytest()\n{\n  char buf[20];\n  return sprintf(buf, \"%s\", \"foo\");\n}\nint main()\n{\n  return (mytest());\n}\nEOF\n\n    if try $CC -c $CFLAGS $test.c; then\n      echo \"Checking for return value of sprintf()... Yes.\" | tee -a configure.log\n    else\n      CFLAGS=\"$CFLAGS -DHAS_sprintf_void\"\n      SFLAGS=\"$SFLAGS -DHAS_sprintf_void\"\n      echo \"Checking for return value of sprintf()... No.\" | tee -a configure.log\n      echo \"  WARNING: apparently sprintf() does not return a value. zlib\" | tee -a configure.log\n      echo \"  can build but will be open to possible string-format security\" | tee -a configure.log\n      echo \"  vulnerabilities.\" | tee -a configure.log\n    fi\n  fi\nfi\n\n# see if we can hide zlib internal symbols that are linked between separate source files\nif test \"$gcc\" -eq 1; then\n  echo >> configure.log\n  cat > $test.c <<EOF\n#define ZLIB_INTERNAL __attribute__((visibility (\"hidden\")))\nint ZLIB_INTERNAL foo;\nint main()\n{\n  return 0;\n}\nEOF\n  if tryboth $CC -c $CFLAGS $test.c; then\n    CFLAGS=\"$CFLAGS -DHAVE_HIDDEN\"\n    SFLAGS=\"$SFLAGS -DHAVE_HIDDEN\"\n    echo \"Checking for attribute(visibility) support... Yes.\" | tee -a configure.log\n  else\n    echo \"Checking for attribute(visibility) support... No.\" | tee -a configure.log\n  fi\nfi\n\n# show the results in the log\necho >> configure.log\necho ALL = $ALL >> configure.log\necho AR = $AR >> configure.log\necho ARFLAGS = $ARFLAGS >> configure.log\necho CC = $CC >> configure.log\necho CFLAGS = $CFLAGS >> configure.log\necho CPP = $CPP >> configure.log\necho EXE = $EXE >> configure.log\necho LDCONFIG = $LDCONFIG >> configure.log\necho LDFLAGS = $LDFLAGS >> configure.log\necho LDSHARED = $LDSHARED >> configure.log\necho LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log\necho OBJC = $OBJC >> configure.log\necho PIC_OBJC = $PIC_OBJC >> configure.log\necho RANLIB = $RANLIB >> configure.log\necho SFLAGS = $SFLAGS >> configure.log\necho SHAREDLIB = $SHAREDLIB >> configure.log\necho SHAREDLIBM = $SHAREDLIBM >> configure.log\necho SHAREDLIBV = $SHAREDLIBV >> configure.log\necho STATICLIB = $STATICLIB >> configure.log\necho TEST = $TEST >> configure.log\necho VER = $VER >> configure.log\necho Z_U4 = $Z_U4 >> configure.log\necho exec_prefix = $exec_prefix >> configure.log\necho includedir = $includedir >> configure.log\necho libdir = $libdir >> configure.log\necho mandir = $mandir >> configure.log\necho prefix = $prefix >> configure.log\necho sharedlibdir = $sharedlibdir >> configure.log\necho uname = $uname >> configure.log\n\n# udpate Makefile with the configure results\nsed < Makefile.in \"\n/^CC *=/s#=.*#=$CC#\n/^CFLAGS *=/s#=.*#=$CFLAGS#\n/^SFLAGS *=/s#=.*#=$SFLAGS#\n/^LDFLAGS *=/s#=.*#=$LDFLAGS#\n/^LDSHARED *=/s#=.*#=$LDSHARED#\n/^CPP *=/s#=.*#=$CPP#\n/^STATICLIB *=/s#=.*#=$STATICLIB#\n/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#\n/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#\n/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#\n/^AR *=/s#=.*#=$AR#\n/^ARFLAGS *=/s#=.*#=$ARFLAGS#\n/^RANLIB *=/s#=.*#=$RANLIB#\n/^LDCONFIG *=/s#=.*#=$LDCONFIG#\n/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC#\n/^EXE *=/s#=.*#=$EXE#\n/^prefix *=/s#=.*#=$prefix#\n/^exec_prefix *=/s#=.*#=$exec_prefix#\n/^libdir *=/s#=.*#=$libdir#\n/^sharedlibdir *=/s#=.*#=$sharedlibdir#\n/^includedir *=/s#=.*#=$includedir#\n/^mandir *=/s#=.*#=$mandir#\n/^OBJC *=/s#=.*#= $OBJC#\n/^PIC_OBJC *=/s#=.*#= $PIC_OBJC#\n/^all: */s#:.*#: $ALL#\n/^test: */s#:.*#: $TEST#\n\" > Makefile\n\n# create zlib.pc with the configure results\nsed < zlib.pc.in \"\n/^CC *=/s#=.*#=$CC#\n/^CFLAGS *=/s#=.*#=$CFLAGS#\n/^CPP *=/s#=.*#=$CPP#\n/^LDSHARED *=/s#=.*#=$LDSHARED#\n/^STATICLIB *=/s#=.*#=$STATICLIB#\n/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#\n/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#\n/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#\n/^AR *=/s#=.*#=$AR#\n/^ARFLAGS *=/s#=.*#=$ARFLAGS#\n/^RANLIB *=/s#=.*#=$RANLIB#\n/^EXE *=/s#=.*#=$EXE#\n/^prefix *=/s#=.*#=$prefix#\n/^exec_prefix *=/s#=.*#=$exec_prefix#\n/^libdir *=/s#=.*#=$libdir#\n/^sharedlibdir *=/s#=.*#=$sharedlibdir#\n/^includedir *=/s#=.*#=$includedir#\n/^mandir *=/s#=.*#=$mandir#\n/^LDFLAGS *=/s#=.*#=$LDFLAGS#\n\" | sed -e \"\ns/\\@VERSION\\@/$VER/g;\n\" > zlib.pc\n\n# done\nleave 0\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/README.contrib",
    "content": "All files under this contrib directory are UNSUPPORTED. There were\nprovided by users of zlib and were not tested by the authors of zlib.\nUse at your own risk. Please contact the authors of the contributions\nfor help about these, not the zlib authors. Thanks.\n\n\nada/        by Dmitriy Anisimkov <anisimkov@yahoo.com>\n        Support for Ada\n        See http://zlib-ada.sourceforge.net/\n\namd64/      by Mikhail Teterin <mi@ALDAN.algebra.com>\n        asm code for AMD64\n        See patch at http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/96393\n\nasm686/     by Brian Raiter <breadbox@muppetlabs.com>\n        asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax\n        See http://www.muppetlabs.com/~breadbox/software/assembly.html\n\nblast/      by Mark Adler <madler@alumni.caltech.edu>\n        Decompressor for output of PKWare Data Compression Library (DCL)\n\ndelphi/     by Cosmin Truta <cosmint@cs.ubbcluj.ro>\n        Support for Delphi and C++ Builder\n\ndotzlib/    by Henrik Ravn <henrik@ravn.com>\n        Support for Microsoft .Net and Visual C++ .Net\n\ngcc_gvmat64/by Gilles Vollant <info@winimage.com>\n        GCC Version of x86 64-bit (AMD64 and Intel EM64t) code for x64\n        assembler to replace longest_match() and inflate_fast()\n\ninfback9/   by Mark Adler <madler@alumni.caltech.edu>\n        Unsupported diffs to infback to decode the deflate64 format\n\ninflate86/  by Chris Anderson <christop@charm.net>\n        Tuned x86 gcc asm code to replace inflate_fast()\n\niostream/   by Kevin Ruland <kevin@rodin.wustl.edu>\n        A C++ I/O streams interface to the zlib gz* functions\n\niostream2/  by Tyge Lvset <Tyge.Lovset@cmr.no>\n        Another C++ I/O streams interface\n\niostream3/  by Ludwig Schwardt <schwardt@sun.ac.za>\n            and Kevin Ruland <kevin@rodin.wustl.edu>\n        Yet another C++ I/O streams interface\n\nmasmx64/    by Gilles Vollant <info@winimage.com>\n        x86 64-bit (AMD64 and Intel EM64t) code for x64 assembler to\n        replace longest_match() and inflate_fast(),  also masm x86\n        64-bits translation of Chris Anderson inflate_fast()\n\nmasmx86/    by Gilles Vollant <info@winimage.com>\n        x86 asm code to replace longest_match() and inflate_fast(),\n        for Visual C++ and MASM (32 bits).\n        Based on Brian Raiter (asm686) and Chris Anderson (inflate86)\n\nminizip/    by Gilles Vollant <info@winimage.com>\n        Mini zip and unzip based on zlib\n        Includes Zip64 support by Mathias Svensson <mathias@result42.com>\n        See http://www.winimage.com/zLibDll/unzip.html\n\npascal/     by Bob Dellaca <bobdl@xtra.co.nz> et al.\n        Support for Pascal\n\npuff/       by Mark Adler <madler@alumni.caltech.edu>\n        Small, low memory usage inflate.  Also serves to provide an\n        unambiguous description of the deflate format.\n\ntestzlib/   by Gilles Vollant <info@winimage.com>\n        Example of the use of zlib\n\nuntgz/      by Pedro A. Aranda Gutierrez <paag@tid.es>\n        A very simple tar.gz file extractor using zlib\n\nvstudio/    by Gilles Vollant <info@winimage.com>\n        Building a minizip-enhanced zlib with Microsoft Visual Studio\n        Includes vc11 from kreuzerkrieg and vc12 from davispuh\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/ada/buffer_demo.adb",
    "content": "----------------------------------------------------------------\n--  ZLib for Ada thick binding.                               --\n--                                                            --\n--  Copyright (C) 2002-2004 Dmitriy Anisimkov                 --\n--                                                            --\n--  Open source license information is in the zlib.ads file.  --\n----------------------------------------------------------------\n--\n--  $Id: buffer_demo.adb,v 1.3 2004/09/06 06:55:35 vagul Exp $\n\n--  This demo program provided by Dr Steve Sangwine <sjs@essex.ac.uk>\n--\n--  Demonstration of a problem with Zlib-Ada (already fixed) when a buffer\n--  of exactly the correct size is used for decompressed data, and the last\n--  few bytes passed in to Zlib are checksum bytes.\n\n--  This program compresses a string of text, and then decompresses the\n--  compressed text into a buffer of the same size as the original text.\n\nwith Ada.Streams; use Ada.Streams;\nwith Ada.Text_IO;\n\nwith ZLib; use ZLib;\n\nprocedure Buffer_Demo is\n   EOL  : Character renames ASCII.LF;\n   Text : constant String\n     := \"Four score and seven years ago our fathers brought forth,\" & EOL &\n        \"upon this continent, a new nation, conceived in liberty,\" & EOL &\n        \"and dedicated to the proposition that `all men are created equal'.\";\n\n   Source : Stream_Element_Array (1 .. Text'Length);\n   for Source'Address use Text'Address;\n\nbegin\n   Ada.Text_IO.Put (Text);\n   Ada.Text_IO.New_Line;\n   Ada.Text_IO.Put_Line\n     (\"Uncompressed size : \" & Positive'Image (Text'Length) & \" bytes\");\n\n   declare\n      Compressed_Data : Stream_Element_Array (1 .. Text'Length);\n      L               : Stream_Element_Offset;\n   begin\n      Compress : declare\n         Compressor : Filter_Type;\n         I : Stream_Element_Offset;\n      begin\n         Deflate_Init (Compressor);\n\n         --  Compress the whole of T at once.\n\n         Translate (Compressor, Source, I, Compressed_Data, L, Finish);\n         pragma Assert (I = Source'Last);\n\n         Close (Compressor);\n\n         Ada.Text_IO.Put_Line\n           (\"Compressed size :   \"\n            & Stream_Element_Offset'Image (L) & \" bytes\");\n      end Compress;\n\n      --  Now we decompress the data, passing short blocks of data to Zlib\n      --  (because this demonstrates the problem - the last block passed will\n      --  contain checksum information and there will be no output, only a\n      --  check inside Zlib that the checksum is correct).\n\n      Decompress : declare\n         Decompressor : Filter_Type;\n\n         Uncompressed_Data : Stream_Element_Array (1 .. Text'Length);\n\n         Block_Size : constant := 4;\n         --  This makes sure that the last block contains\n         --  only Adler checksum data.\n\n         P : Stream_Element_Offset := Compressed_Data'First - 1;\n         O : Stream_Element_Offset;\n      begin\n         Inflate_Init (Decompressor);\n\n         loop\n            Translate\n              (Decompressor,\n               Compressed_Data\n                 (P + 1 .. Stream_Element_Offset'Min (P + Block_Size, L)),\n               P,\n               Uncompressed_Data\n                 (Total_Out (Decompressor) + 1 .. Uncompressed_Data'Last),\n               O,\n               No_Flush);\n\n               Ada.Text_IO.Put_Line\n                 (\"Total in : \" & Count'Image (Total_In (Decompressor)) &\n                  \", out : \" & Count'Image (Total_Out (Decompressor)));\n\n               exit when P = L;\n         end loop;\n\n         Ada.Text_IO.New_Line;\n         Ada.Text_IO.Put_Line\n           (\"Decompressed text matches original text : \"\n             & Boolean'Image (Uncompressed_Data = Source));\n      end Decompress;\n   end;\nend Buffer_Demo;\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/ada/mtest.adb",
    "content": "----------------------------------------------------------------\n--  ZLib for Ada thick binding.                               --\n--                                                            --\n--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --\n--                                                            --\n--  Open source license information is in the zlib.ads file.  --\n----------------------------------------------------------------\n--  Continuous test for ZLib multithreading. If the test would fail\n--  we should provide thread safe allocation routines for the Z_Stream.\n--\n--  $Id: mtest.adb,v 1.4 2004/07/23 07:49:54 vagul Exp $\n\nwith ZLib;\nwith Ada.Streams;\nwith Ada.Numerics.Discrete_Random;\nwith Ada.Text_IO;\nwith Ada.Exceptions;\nwith Ada.Task_Identification;\n\nprocedure MTest is\n   use Ada.Streams;\n   use ZLib;\n\n   Stop : Boolean := False;\n\n   pragma Atomic (Stop);\n\n   subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;\n\n   package Random_Elements is\n      new Ada.Numerics.Discrete_Random (Visible_Symbols);\n\n   task type Test_Task;\n\n   task body Test_Task is\n      Buffer : Stream_Element_Array (1 .. 100_000);\n      Gen : Random_Elements.Generator;\n\n      Buffer_First  : Stream_Element_Offset;\n      Compare_First : Stream_Element_Offset;\n\n      Deflate : Filter_Type;\n      Inflate : Filter_Type;\n\n      procedure Further (Item : in Stream_Element_Array);\n\n      procedure Read_Buffer\n        (Item : out Ada.Streams.Stream_Element_Array;\n         Last : out Ada.Streams.Stream_Element_Offset);\n\n      -------------\n      -- Further --\n      -------------\n\n      procedure Further (Item : in Stream_Element_Array) is\n\n         procedure Compare (Item : in Stream_Element_Array);\n\n         -------------\n         -- Compare --\n         -------------\n\n         procedure Compare (Item : in Stream_Element_Array) is\n            Next_First : Stream_Element_Offset := Compare_First + Item'Length;\n         begin\n            if Buffer (Compare_First .. Next_First - 1) /= Item then\n               raise Program_Error;\n            end if;\n\n            Compare_First := Next_First;\n         end Compare;\n\n         procedure Compare_Write is new ZLib.Write (Write => Compare);\n      begin\n         Compare_Write (Inflate, Item, No_Flush);\n      end Further;\n\n      -----------------\n      -- Read_Buffer --\n      -----------------\n\n      procedure Read_Buffer\n        (Item : out Ada.Streams.Stream_Element_Array;\n         Last : out Ada.Streams.Stream_Element_Offset)\n      is\n         Buff_Diff   : Stream_Element_Offset := Buffer'Last - Buffer_First;\n         Next_First : Stream_Element_Offset;\n      begin\n         if Item'Length <= Buff_Diff then\n            Last := Item'Last;\n\n            Next_First := Buffer_First + Item'Length;\n\n            Item := Buffer (Buffer_First .. Next_First - 1);\n\n            Buffer_First := Next_First;\n         else\n            Last := Item'First + Buff_Diff;\n            Item (Item'First .. Last) := Buffer (Buffer_First .. Buffer'Last);\n            Buffer_First := Buffer'Last + 1;\n         end if;\n      end Read_Buffer;\n\n      procedure Translate is new Generic_Translate\n                                   (Data_In  => Read_Buffer,\n                                    Data_Out => Further);\n\n   begin\n      Random_Elements.Reset (Gen);\n\n      Buffer := (others => 20);\n\n      Main : loop\n         for J in Buffer'Range loop\n            Buffer (J) := Random_Elements.Random (Gen);\n\n            Deflate_Init (Deflate);\n            Inflate_Init (Inflate);\n\n            Buffer_First  := Buffer'First;\n            Compare_First := Buffer'First;\n\n            Translate (Deflate);\n\n            if Compare_First /= Buffer'Last + 1 then\n               raise Program_Error;\n            end if;\n\n            Ada.Text_IO.Put_Line\n              (Ada.Task_Identification.Image\n                 (Ada.Task_Identification.Current_Task)\n               & Stream_Element_Offset'Image (J)\n               & ZLib.Count'Image (Total_Out (Deflate)));\n\n            Close (Deflate);\n            Close (Inflate);\n\n            exit Main when Stop;\n         end loop;\n      end loop Main;\n   exception\n      when E : others =>\n         Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Information (E));\n         Stop := True;\n   end Test_Task;\n\n   Test : array (1 .. 4) of Test_Task;\n\n   pragma Unreferenced (Test);\n\n   Dummy : Character;\n\nbegin\n   Ada.Text_IO.Get_Immediate (Dummy);\n   Stop := True;\nend MTest;\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/ada/read.adb",
    "content": "----------------------------------------------------------------\n--  ZLib for Ada thick binding.                               --\n--                                                            --\n--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --\n--                                                            --\n--  Open source license information is in the zlib.ads file.  --\n----------------------------------------------------------------\n\n--  $Id: read.adb,v 1.8 2004/05/31 10:53:40 vagul Exp $\n\n--  Test/demo program for the generic read interface.\n\nwith Ada.Numerics.Discrete_Random;\nwith Ada.Streams;\nwith Ada.Text_IO;\n\nwith ZLib;\n\nprocedure Read is\n\n   use Ada.Streams;\n\n   ------------------------------------\n   --  Test configuration parameters --\n   ------------------------------------\n\n   File_Size   : Stream_Element_Offset := 100_000;\n\n   Continuous  : constant Boolean          := False;\n   --  If this constant is True, the test would be repeated again and again,\n   --  with increment File_Size for every iteration.\n\n   Header      : constant ZLib.Header_Type := ZLib.Default;\n   --  Do not use Header other than Default in ZLib versions 1.1.4 and older.\n\n   Init_Random : constant := 8;\n   --  We are using the same random sequence, in case of we catch bug,\n   --  so we would be able to reproduce it.\n\n   -- End --\n\n   Pack_Size : Stream_Element_Offset;\n   Offset    : Stream_Element_Offset;\n\n   Filter     : ZLib.Filter_Type;\n\n   subtype Visible_Symbols\n      is Stream_Element range 16#20# .. 16#7E#;\n\n   package Random_Elements is new\n      Ada.Numerics.Discrete_Random (Visible_Symbols);\n\n   Gen : Random_Elements.Generator;\n   Period  : constant Stream_Element_Offset := 200;\n   --  Period constant variable for random generator not to be very random.\n   --  Bigger period, harder random.\n\n   Read_Buffer : Stream_Element_Array (1 .. 2048);\n   Read_First  : Stream_Element_Offset;\n   Read_Last   : Stream_Element_Offset;\n\n   procedure Reset;\n\n   procedure Read\n     (Item : out Stream_Element_Array;\n      Last : out Stream_Element_Offset);\n   --  this procedure is for generic instantiation of\n   --  ZLib.Read\n   --  reading data from the File_In.\n\n   procedure Read is new ZLib.Read\n                           (Read,\n                            Read_Buffer,\n                            Rest_First => Read_First,\n                            Rest_Last  => Read_Last);\n\n   ----------\n   -- Read --\n   ----------\n\n   procedure Read\n     (Item : out Stream_Element_Array;\n      Last : out Stream_Element_Offset) is\n   begin\n      Last := Stream_Element_Offset'Min\n               (Item'Last,\n                Item'First + File_Size - Offset);\n\n      for J in Item'First .. Last loop\n         if J < Item'First + Period then\n            Item (J) := Random_Elements.Random (Gen);\n         else\n            Item (J) := Item (J - Period);\n         end if;\n\n         Offset   := Offset + 1;\n      end loop;\n   end Read;\n\n   -----------\n   -- Reset --\n   -----------\n\n   procedure Reset is\n   begin\n      Random_Elements.Reset (Gen, Init_Random);\n      Pack_Size := 0;\n      Offset := 1;\n      Read_First := Read_Buffer'Last + 1;\n      Read_Last  := Read_Buffer'Last;\n   end Reset;\n\nbegin\n   Ada.Text_IO.Put_Line (\"ZLib \" & ZLib.Version);\n\n   loop\n      for Level in ZLib.Compression_Level'Range loop\n\n         Ada.Text_IO.Put (\"Level =\"\n            & ZLib.Compression_Level'Image (Level));\n\n         --  Deflate using generic instantiation.\n\n         ZLib.Deflate_Init\n               (Filter,\n                Level,\n                Header => Header);\n\n         Reset;\n\n         Ada.Text_IO.Put\n           (Stream_Element_Offset'Image (File_Size) & \" ->\");\n\n         loop\n            declare\n               Buffer : Stream_Element_Array (1 .. 1024);\n               Last   : Stream_Element_Offset;\n            begin\n               Read (Filter, Buffer, Last);\n\n               Pack_Size := Pack_Size + Last - Buffer'First + 1;\n\n               exit when Last < Buffer'Last;\n            end;\n         end loop;\n\n         Ada.Text_IO.Put_Line (Stream_Element_Offset'Image (Pack_Size));\n\n         ZLib.Close (Filter);\n      end loop;\n\n      exit when not Continuous;\n\n      File_Size := File_Size + 1;\n   end loop;\nend Read;\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/ada/readme.txt",
    "content": "                        ZLib for Ada thick binding (ZLib.Ada)\n                        Release 1.3\n\nZLib.Ada is a thick binding interface to the popular ZLib data\ncompression library, available at http://www.gzip.org/zlib/.\nIt provides Ada-style access to the ZLib C library.\n\n\n        Here are the main changes since ZLib.Ada 1.2:\n\n- Attension: ZLib.Read generic routine have a initialization requirement\n  for Read_Last parameter now. It is a bit incompartible with previous version,\n  but extends functionality, we could use new parameters Allow_Read_Some and\n  Flush now.\n\n- Added Is_Open routines to ZLib and ZLib.Streams packages.\n\n- Add pragma Assert to check Stream_Element is 8 bit.\n\n- Fix extraction to buffer with exact known decompressed size. Error reported by\n  Steve Sangwine.\n\n- Fix definition of ULong (changed to unsigned_long), fix regression on 64 bits\n  computers. Patch provided by Pascal Obry.\n\n- Add Status_Error exception definition.\n\n- Add pragma Assertion that Ada.Streams.Stream_Element size is 8 bit.\n\n\n        How to build ZLib.Ada under GNAT\n\nYou should have the ZLib library already build on your computer, before\nbuilding ZLib.Ada. Make the directory of ZLib.Ada sources current and\nissue the command:\n\n  gnatmake test -largs -L<directory where libz.a is> -lz\n\nOr use the GNAT project file build for GNAT 3.15 or later:\n\n  gnatmake -Pzlib.gpr -L<directory where libz.a is>\n\n\n        How to build ZLib.Ada under Aonix ObjectAda for Win32 7.2.2\n\n1. Make a project with all *.ads and *.adb files from the distribution.\n2. Build the libz.a library from the ZLib C sources.\n3. Rename libz.a to z.lib.\n4. Add the library z.lib to the project.\n5. Add the libc.lib library from the ObjectAda distribution to the project.\n6. Build the executable using test.adb as a main procedure.\n\n\n        How to use ZLib.Ada\n\nThe source files test.adb and read.adb are small demo programs that show\nthe main functionality of ZLib.Ada.\n\nThe routines from the package specifications are commented.\n\n\nHomepage: http://zlib-ada.sourceforge.net/\nAuthor: Dmitriy Anisimkov <anisimkov@yahoo.com>\n\nContributors: Pascal Obry <pascal@obry.org>, Steve Sangwine <sjs@essex.ac.uk>\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/ada/test.adb",
    "content": "----------------------------------------------------------------\n--  ZLib for Ada thick binding.                               --\n--                                                            --\n--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --\n--                                                            --\n--  Open source license information is in the zlib.ads file.  --\n----------------------------------------------------------------\n\n--  $Id: test.adb,v 1.17 2003/08/12 12:13:30 vagul Exp $\n\n--  The program has a few aims.\n--  1. Test ZLib.Ada95 thick binding functionality.\n--  2. Show the example of use main functionality of the ZLib.Ada95 binding.\n--  3. Build this program automatically compile all ZLib.Ada95 packages under\n--     GNAT Ada95 compiler.\n\nwith ZLib.Streams;\nwith Ada.Streams.Stream_IO;\nwith Ada.Numerics.Discrete_Random;\n\nwith Ada.Text_IO;\n\nwith Ada.Calendar;\n\nprocedure Test is\n\n   use Ada.Streams;\n   use Stream_IO;\n\n   ------------------------------------\n   --  Test configuration parameters --\n   ------------------------------------\n\n   File_Size   : Count   := 100_000;\n   Continuous  : constant Boolean := False;\n\n   Header      : constant ZLib.Header_Type := ZLib.Default;\n                                              --  ZLib.None;\n                                              --  ZLib.Auto;\n                                              --  ZLib.GZip;\n   --  Do not use Header other then Default in ZLib versions 1.1.4\n   --  and older.\n\n   Strategy    : constant ZLib.Strategy_Type := ZLib.Default_Strategy;\n   Init_Random : constant := 10;\n\n   -- End --\n\n   In_File_Name  : constant String := \"testzlib.in\";\n   --  Name of the input file\n\n   Z_File_Name   : constant String := \"testzlib.zlb\";\n   --  Name of the compressed file.\n\n   Out_File_Name : constant String := \"testzlib.out\";\n   --  Name of the decompressed file.\n\n   File_In   : File_Type;\n   File_Out  : File_Type;\n   File_Back : File_Type;\n   File_Z    : ZLib.Streams.Stream_Type;\n\n   Filter : ZLib.Filter_Type;\n\n   Time_Stamp : Ada.Calendar.Time;\n\n   procedure Generate_File;\n   --  Generate file of spetsified size with some random data.\n   --  The random data is repeatable, for the good compression.\n\n   procedure Compare_Streams\n     (Left, Right : in out Root_Stream_Type'Class);\n   --  The procedure compearing data in 2 streams.\n   --  It is for compare data before and after compression/decompression.\n\n   procedure Compare_Files (Left, Right : String);\n   --  Compare files. Based on the Compare_Streams.\n\n   procedure Copy_Streams\n     (Source, Target : in out Root_Stream_Type'Class;\n      Buffer_Size    : in     Stream_Element_Offset := 1024);\n   --  Copying data from one stream to another. It is for test stream\n   --  interface of the library.\n\n   procedure Data_In\n     (Item : out Stream_Element_Array;\n      Last : out Stream_Element_Offset);\n   --  this procedure is for generic instantiation of\n   --  ZLib.Generic_Translate.\n   --  reading data from the File_In.\n\n   procedure Data_Out (Item : in Stream_Element_Array);\n   --  this procedure is for generic instantiation of\n   --  ZLib.Generic_Translate.\n   --  writing data to the File_Out.\n\n   procedure Stamp;\n   --  Store the timestamp to the local variable.\n\n   procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count);\n   --  Print the time statistic with the message.\n\n   procedure Translate is new ZLib.Generic_Translate\n                                (Data_In  => Data_In,\n                                 Data_Out => Data_Out);\n   --  This procedure is moving data from File_In to File_Out\n   --  with compression or decompression, depend on initialization of\n   --  Filter parameter.\n\n   -------------------\n   -- Compare_Files --\n   -------------------\n\n   procedure Compare_Files (Left, Right : String) is\n      Left_File, Right_File : File_Type;\n   begin\n      Open (Left_File, In_File, Left);\n      Open (Right_File, In_File, Right);\n      Compare_Streams (Stream (Left_File).all, Stream (Right_File).all);\n      Close (Left_File);\n      Close (Right_File);\n   end Compare_Files;\n\n   ---------------------\n   -- Compare_Streams --\n   ---------------------\n\n   procedure Compare_Streams\n     (Left, Right : in out Ada.Streams.Root_Stream_Type'Class)\n   is\n      Left_Buffer, Right_Buffer : Stream_Element_Array (0 .. 16#FFF#);\n      Left_Last, Right_Last : Stream_Element_Offset;\n   begin\n      loop\n         Read (Left, Left_Buffer, Left_Last);\n         Read (Right, Right_Buffer, Right_Last);\n\n         if Left_Last /= Right_Last then\n            Ada.Text_IO.Put_Line (\"Compare error :\"\n              & Stream_Element_Offset'Image (Left_Last)\n              & \" /= \"\n              & Stream_Element_Offset'Image (Right_Last));\n\n            raise Constraint_Error;\n\n         elsif Left_Buffer (0 .. Left_Last)\n               /= Right_Buffer (0 .. Right_Last)\n         then\n            Ada.Text_IO.Put_Line (\"ERROR: IN and OUT files is not equal.\");\n            raise Constraint_Error;\n\n         end if;\n\n         exit when Left_Last < Left_Buffer'Last;\n      end loop;\n   end Compare_Streams;\n\n   ------------------\n   -- Copy_Streams --\n   ------------------\n\n   procedure Copy_Streams\n     (Source, Target : in out Ada.Streams.Root_Stream_Type'Class;\n      Buffer_Size    : in     Stream_Element_Offset := 1024)\n   is\n      Buffer : Stream_Element_Array (1 .. Buffer_Size);\n      Last   : Stream_Element_Offset;\n   begin\n      loop\n         Read  (Source, Buffer, Last);\n         Write (Target, Buffer (1 .. Last));\n\n         exit when Last < Buffer'Last;\n      end loop;\n   end Copy_Streams;\n\n   -------------\n   -- Data_In --\n   -------------\n\n   procedure Data_In\n     (Item : out Stream_Element_Array;\n      Last : out Stream_Element_Offset) is\n   begin\n      Read (File_In, Item, Last);\n   end Data_In;\n\n   --------------\n   -- Data_Out --\n   --------------\n\n   procedure Data_Out (Item : in Stream_Element_Array) is\n   begin\n      Write (File_Out, Item);\n   end Data_Out;\n\n   -------------------\n   -- Generate_File --\n   -------------------\n\n   procedure Generate_File is\n      subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;\n\n      package Random_Elements is\n         new Ada.Numerics.Discrete_Random (Visible_Symbols);\n\n      Gen    : Random_Elements.Generator;\n      Buffer : Stream_Element_Array := (1 .. 77 => 16#20#) & 10;\n\n      Buffer_Count : constant Count := File_Size / Buffer'Length;\n      --  Number of same buffers in the packet.\n\n      Density : constant Count := 30; --  from 0 to Buffer'Length - 2;\n\n      procedure Fill_Buffer (J, D : in Count);\n      --  Change the part of the buffer.\n\n      -----------------\n      -- Fill_Buffer --\n      -----------------\n\n      procedure Fill_Buffer (J, D : in Count) is\n      begin\n         for K in 0 .. D loop\n            Buffer\n              (Stream_Element_Offset ((J + K) mod (Buffer'Length - 1) + 1))\n             := Random_Elements.Random (Gen);\n\n         end loop;\n      end Fill_Buffer;\n\n   begin\n      Random_Elements.Reset (Gen, Init_Random);\n\n      Create (File_In, Out_File, In_File_Name);\n\n      Fill_Buffer (1, Buffer'Length - 2);\n\n      for J in 1 .. Buffer_Count loop\n         Write (File_In, Buffer);\n\n         Fill_Buffer (J, Density);\n      end loop;\n\n      --  fill remain size.\n\n      Write\n        (File_In,\n         Buffer\n           (1 .. Stream_Element_Offset\n                   (File_Size - Buffer'Length * Buffer_Count)));\n\n      Flush (File_In);\n      Close (File_In);\n   end Generate_File;\n\n   ---------------------\n   -- Print_Statistic --\n   ---------------------\n\n   procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count) is\n      use Ada.Calendar;\n      use Ada.Text_IO;\n\n      package Count_IO is new Integer_IO (ZLib.Count);\n\n      Curr_Dur : Duration := Clock - Time_Stamp;\n   begin\n      Put (Msg);\n\n      Set_Col (20);\n      Ada.Text_IO.Put (\"size =\");\n\n      Count_IO.Put\n        (Data_Size,\n         Width => Stream_IO.Count'Image (File_Size)'Length);\n\n      Put_Line (\" duration =\" & Duration'Image (Curr_Dur));\n   end Print_Statistic;\n\n   -----------\n   -- Stamp --\n   -----------\n\n   procedure Stamp is\n   begin\n      Time_Stamp := Ada.Calendar.Clock;\n   end Stamp;\n\nbegin\n   Ada.Text_IO.Put_Line (\"ZLib \" & ZLib.Version);\n\n   loop\n      Generate_File;\n\n      for Level in ZLib.Compression_Level'Range loop\n\n         Ada.Text_IO.Put_Line (\"Level =\"\n            & ZLib.Compression_Level'Image (Level));\n\n         --  Test generic interface.\n         Open   (File_In, In_File, In_File_Name);\n         Create (File_Out, Out_File, Z_File_Name);\n\n         Stamp;\n\n         --  Deflate using generic instantiation.\n\n         ZLib.Deflate_Init\n               (Filter   => Filter,\n                Level    => Level,\n                Strategy => Strategy,\n                Header   => Header);\n\n         Translate (Filter);\n         Print_Statistic (\"Generic compress\", ZLib.Total_Out (Filter));\n         ZLib.Close (Filter);\n\n         Close (File_In);\n         Close (File_Out);\n\n         Open   (File_In, In_File, Z_File_Name);\n         Create (File_Out, Out_File, Out_File_Name);\n\n         Stamp;\n\n         --  Inflate using generic instantiation.\n\n         ZLib.Inflate_Init (Filter, Header => Header);\n\n         Translate (Filter);\n         Print_Statistic (\"Generic decompress\", ZLib.Total_Out (Filter));\n\n         ZLib.Close (Filter);\n\n         Close (File_In);\n         Close (File_Out);\n\n         Compare_Files (In_File_Name, Out_File_Name);\n\n         --  Test stream interface.\n\n         --  Compress to the back stream.\n\n         Open   (File_In, In_File, In_File_Name);\n         Create (File_Back, Out_File, Z_File_Name);\n\n         Stamp;\n\n         ZLib.Streams.Create\n           (Stream          => File_Z,\n            Mode            => ZLib.Streams.Out_Stream,\n            Back            => ZLib.Streams.Stream_Access\n                                 (Stream (File_Back)),\n            Back_Compressed => True,\n            Level           => Level,\n            Strategy        => Strategy,\n            Header          => Header);\n\n         Copy_Streams\n           (Source => Stream (File_In).all,\n            Target => File_Z);\n\n         --  Flushing internal buffers to the back stream.\n\n         ZLib.Streams.Flush (File_Z, ZLib.Finish);\n\n         Print_Statistic (\"Write compress\",\n                          ZLib.Streams.Write_Total_Out (File_Z));\n\n         ZLib.Streams.Close (File_Z);\n\n         Close (File_In);\n         Close (File_Back);\n\n         --  Compare reading from original file and from\n         --  decompression stream.\n\n         Open (File_In,   In_File, In_File_Name);\n         Open (File_Back, In_File, Z_File_Name);\n\n         ZLib.Streams.Create\n           (Stream          => File_Z,\n            Mode            => ZLib.Streams.In_Stream,\n            Back            => ZLib.Streams.Stream_Access\n                                 (Stream (File_Back)),\n            Back_Compressed => True,\n            Header          => Header);\n\n         Stamp;\n         Compare_Streams (Stream (File_In).all, File_Z);\n\n         Print_Statistic (\"Read decompress\",\n                          ZLib.Streams.Read_Total_Out (File_Z));\n\n         ZLib.Streams.Close (File_Z);\n         Close (File_In);\n         Close (File_Back);\n\n         --  Compress by reading from compression stream.\n\n         Open (File_Back, In_File, In_File_Name);\n         Create (File_Out, Out_File, Z_File_Name);\n\n         ZLib.Streams.Create\n           (Stream          => File_Z,\n            Mode            => ZLib.Streams.In_Stream,\n            Back            => ZLib.Streams.Stream_Access\n                                 (Stream (File_Back)),\n            Back_Compressed => False,\n            Level           => Level,\n            Strategy        => Strategy,\n            Header          => Header);\n\n         Stamp;\n         Copy_Streams\n           (Source => File_Z,\n            Target => Stream (File_Out).all);\n\n         Print_Statistic (\"Read compress\",\n                          ZLib.Streams.Read_Total_Out (File_Z));\n\n         ZLib.Streams.Close (File_Z);\n\n         Close (File_Out);\n         Close (File_Back);\n\n         --  Decompress to decompression stream.\n\n         Open   (File_In,   In_File, Z_File_Name);\n         Create (File_Back, Out_File, Out_File_Name);\n\n         ZLib.Streams.Create\n           (Stream          => File_Z,\n            Mode            => ZLib.Streams.Out_Stream,\n            Back            => ZLib.Streams.Stream_Access\n                                 (Stream (File_Back)),\n            Back_Compressed => False,\n            Header          => Header);\n\n         Stamp;\n\n         Copy_Streams\n           (Source => Stream (File_In).all,\n            Target => File_Z);\n\n         Print_Statistic (\"Write decompress\",\n                          ZLib.Streams.Write_Total_Out (File_Z));\n\n         ZLib.Streams.Close (File_Z);\n         Close (File_In);\n         Close (File_Back);\n\n         Compare_Files (In_File_Name, Out_File_Name);\n      end loop;\n\n      Ada.Text_IO.Put_Line (Count'Image (File_Size) & \" Ok.\");\n\n      exit when not Continuous;\n\n      File_Size := File_Size + 1;\n   end loop;\nend Test;\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/ada/zlib-streams.adb",
    "content": "----------------------------------------------------------------\n--  ZLib for Ada thick binding.                               --\n--                                                            --\n--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --\n--                                                            --\n--  Open source license information is in the zlib.ads file.  --\n----------------------------------------------------------------\n\n--  $Id: zlib-streams.adb,v 1.10 2004/05/31 10:53:40 vagul Exp $\n\nwith Ada.Unchecked_Deallocation;\n\npackage body ZLib.Streams is\n\n   -----------\n   -- Close --\n   -----------\n\n   procedure Close (Stream : in out Stream_Type) is\n      procedure Free is new Ada.Unchecked_Deallocation\n         (Stream_Element_Array, Buffer_Access);\n   begin\n      if Stream.Mode = Out_Stream or Stream.Mode = Duplex then\n         --  We should flush the data written by the writer.\n\n         Flush (Stream, Finish);\n\n         Close (Stream.Writer);\n      end if;\n\n      if Stream.Mode = In_Stream or Stream.Mode = Duplex then\n         Close (Stream.Reader);\n         Free (Stream.Buffer);\n      end if;\n   end Close;\n\n   ------------\n   -- Create --\n   ------------\n\n   procedure Create\n     (Stream            :    out Stream_Type;\n      Mode              : in     Stream_Mode;\n      Back              : in     Stream_Access;\n      Back_Compressed   : in     Boolean;\n      Level             : in     Compression_Level := Default_Compression;\n      Strategy          : in     Strategy_Type     := Default_Strategy;\n      Header            : in     Header_Type       := Default;\n      Read_Buffer_Size  : in     Ada.Streams.Stream_Element_Offset\n                                    := Default_Buffer_Size;\n      Write_Buffer_Size : in     Ada.Streams.Stream_Element_Offset\n                                    := Default_Buffer_Size)\n   is\n\n      subtype Buffer_Subtype is Stream_Element_Array (1 .. Read_Buffer_Size);\n\n      procedure Init_Filter\n         (Filter   : in out Filter_Type;\n          Compress : in     Boolean);\n\n      -----------------\n      -- Init_Filter --\n      -----------------\n\n      procedure Init_Filter\n         (Filter   : in out Filter_Type;\n          Compress : in     Boolean) is\n      begin\n         if Compress then\n            Deflate_Init\n              (Filter, Level, Strategy, Header => Header);\n         else\n            Inflate_Init (Filter, Header => Header);\n         end if;\n      end Init_Filter;\n\n   begin\n      Stream.Back := Back;\n      Stream.Mode := Mode;\n\n      if Mode = Out_Stream or Mode = Duplex then\n         Init_Filter (Stream.Writer, Back_Compressed);\n         Stream.Buffer_Size := Write_Buffer_Size;\n      else\n         Stream.Buffer_Size := 0;\n      end if;\n\n      if Mode = In_Stream or Mode = Duplex then\n         Init_Filter (Stream.Reader, not Back_Compressed);\n\n         Stream.Buffer     := new Buffer_Subtype;\n         Stream.Rest_First := Stream.Buffer'Last + 1;\n         Stream.Rest_Last  := Stream.Buffer'Last;\n      end if;\n   end Create;\n\n   -----------\n   -- Flush --\n   -----------\n\n   procedure Flush\n     (Stream : in out Stream_Type;\n      Mode   : in     Flush_Mode := Sync_Flush)\n   is\n      Buffer : Stream_Element_Array (1 .. Stream.Buffer_Size);\n      Last   : Stream_Element_Offset;\n   begin\n      loop\n         Flush (Stream.Writer, Buffer, Last, Mode);\n\n         Ada.Streams.Write (Stream.Back.all, Buffer (1 .. Last));\n\n         exit when Last < Buffer'Last;\n      end loop;\n   end Flush;\n\n   -------------\n   -- Is_Open --\n   -------------\n\n   function Is_Open (Stream : Stream_Type) return Boolean is\n   begin\n      return Is_Open (Stream.Reader) or else Is_Open (Stream.Writer);\n   end Is_Open;\n\n   ----------\n   -- Read --\n   ----------\n\n   procedure Read\n     (Stream : in out Stream_Type;\n      Item   :    out Stream_Element_Array;\n      Last   :    out Stream_Element_Offset)\n   is\n\n      procedure Read\n        (Item : out Stream_Element_Array;\n         Last : out Stream_Element_Offset);\n\n      ----------\n      -- Read --\n      ----------\n\n      procedure Read\n        (Item : out Stream_Element_Array;\n         Last : out Stream_Element_Offset) is\n      begin\n         Ada.Streams.Read (Stream.Back.all, Item, Last);\n      end Read;\n\n      procedure Read is new ZLib.Read\n         (Read       => Read,\n          Buffer     => Stream.Buffer.all,\n          Rest_First => Stream.Rest_First,\n          Rest_Last  => Stream.Rest_Last);\n\n   begin\n      Read (Stream.Reader, Item, Last);\n   end Read;\n\n   -------------------\n   -- Read_Total_In --\n   -------------------\n\n   function Read_Total_In (Stream : in Stream_Type) return Count is\n   begin\n      return Total_In (Stream.Reader);\n   end Read_Total_In;\n\n   --------------------\n   -- Read_Total_Out --\n   --------------------\n\n   function Read_Total_Out (Stream : in Stream_Type) return Count is\n   begin\n      return Total_Out (Stream.Reader);\n   end Read_Total_Out;\n\n   -----------\n   -- Write --\n   -----------\n\n   procedure Write\n     (Stream : in out Stream_Type;\n      Item   : in     Stream_Element_Array)\n   is\n\n      procedure Write (Item : in Stream_Element_Array);\n\n      -----------\n      -- Write --\n      -----------\n\n      procedure Write (Item : in Stream_Element_Array) is\n      begin\n         Ada.Streams.Write (Stream.Back.all, Item);\n      end Write;\n\n      procedure Write is new ZLib.Write\n         (Write       => Write,\n          Buffer_Size => Stream.Buffer_Size);\n\n   begin\n      Write (Stream.Writer, Item, No_Flush);\n   end Write;\n\n   --------------------\n   -- Write_Total_In --\n   --------------------\n\n   function Write_Total_In (Stream : in Stream_Type) return Count is\n   begin\n      return Total_In (Stream.Writer);\n   end Write_Total_In;\n\n   ---------------------\n   -- Write_Total_Out --\n   ---------------------\n\n   function Write_Total_Out (Stream : in Stream_Type) return Count is\n   begin\n      return Total_Out (Stream.Writer);\n   end Write_Total_Out;\n\nend ZLib.Streams;\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/ada/zlib-streams.ads",
    "content": "----------------------------------------------------------------\n--  ZLib for Ada thick binding.                               --\n--                                                            --\n--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --\n--                                                            --\n--  Open source license information is in the zlib.ads file.  --\n----------------------------------------------------------------\n\n--  $Id: zlib-streams.ads,v 1.12 2004/05/31 10:53:40 vagul Exp $\n\npackage ZLib.Streams is\n\n   type Stream_Mode is (In_Stream, Out_Stream, Duplex);\n\n   type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;\n\n   type Stream_Type is\n      new Ada.Streams.Root_Stream_Type with private;\n\n   procedure Read\n     (Stream : in out Stream_Type;\n      Item   :    out Ada.Streams.Stream_Element_Array;\n      Last   :    out Ada.Streams.Stream_Element_Offset);\n\n   procedure Write\n     (Stream : in out Stream_Type;\n      Item   : in     Ada.Streams.Stream_Element_Array);\n\n   procedure Flush\n     (Stream : in out Stream_Type;\n      Mode   : in     Flush_Mode := Sync_Flush);\n   --  Flush the written data to the back stream,\n   --  all data placed to the compressor is flushing to the Back stream.\n   --  Should not be used untill necessary, becouse it is decreasing\n   --  compression.\n\n   function Read_Total_In (Stream : in Stream_Type) return Count;\n   pragma Inline (Read_Total_In);\n   --  Return total number of bytes read from back stream so far.\n\n   function Read_Total_Out (Stream : in Stream_Type) return Count;\n   pragma Inline (Read_Total_Out);\n   --  Return total number of bytes read so far.\n\n   function Write_Total_In (Stream : in Stream_Type) return Count;\n   pragma Inline (Write_Total_In);\n   --  Return total number of bytes written so far.\n\n   function Write_Total_Out (Stream : in Stream_Type) return Count;\n   pragma Inline (Write_Total_Out);\n   --  Return total number of bytes written to the back stream.\n\n   procedure Create\n     (Stream            :    out Stream_Type;\n      Mode              : in     Stream_Mode;\n      Back              : in     Stream_Access;\n      Back_Compressed   : in     Boolean;\n      Level             : in     Compression_Level := Default_Compression;\n      Strategy          : in     Strategy_Type     := Default_Strategy;\n      Header            : in     Header_Type       := Default;\n      Read_Buffer_Size  : in     Ada.Streams.Stream_Element_Offset\n                                    := Default_Buffer_Size;\n      Write_Buffer_Size : in     Ada.Streams.Stream_Element_Offset\n                                    := Default_Buffer_Size);\n   --  Create the Comression/Decompression stream.\n   --  If mode is In_Stream then Write operation is disabled.\n   --  If mode is Out_Stream then Read operation is disabled.\n\n   --  If Back_Compressed is true then\n   --  Data written to the Stream is compressing to the Back stream\n   --  and data read from the Stream is decompressed data from the Back stream.\n\n   --  If Back_Compressed is false then\n   --  Data written to the Stream is decompressing to the Back stream\n   --  and data read from the Stream is compressed data from the Back stream.\n\n   --  !!! When the Need_Header is False ZLib-Ada is using undocumented\n   --  ZLib 1.1.4 functionality to do not create/wait for ZLib headers.\n\n   function Is_Open (Stream : Stream_Type) return Boolean;\n\n   procedure Close (Stream : in out Stream_Type);\n\nprivate\n\n   use Ada.Streams;\n\n   type Buffer_Access is access all Stream_Element_Array;\n\n   type Stream_Type\n     is new Root_Stream_Type with\n   record\n      Mode       : Stream_Mode;\n\n      Buffer     : Buffer_Access;\n      Rest_First : Stream_Element_Offset;\n      Rest_Last  : Stream_Element_Offset;\n      --  Buffer for Read operation.\n      --  We need to have this buffer in the record\n      --  becouse not all read data from back stream\n      --  could be processed during the read operation.\n\n      Buffer_Size : Stream_Element_Offset;\n      --  Buffer size for write operation.\n      --  We do not need to have this buffer\n      --  in the record becouse all data could be\n      --  processed in the write operation.\n\n      Back       : Stream_Access;\n      Reader     : Filter_Type;\n      Writer     : Filter_Type;\n   end record;\n\nend ZLib.Streams;\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/ada/zlib-thin.adb",
    "content": "----------------------------------------------------------------\n--  ZLib for Ada thick binding.                               --\n--                                                            --\n--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --\n--                                                            --\n--  Open source license information is in the zlib.ads file.  --\n----------------------------------------------------------------\n\n--  $Id: zlib-thin.adb,v 1.8 2003/12/14 18:27:31 vagul Exp $\n\npackage body ZLib.Thin is\n\n   ZLIB_VERSION  : constant Chars_Ptr := zlibVersion;\n\n   Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit;\n\n   --------------\n   -- Avail_In --\n   --------------\n\n   function Avail_In (Strm : in Z_Stream) return UInt is\n   begin\n      return Strm.Avail_In;\n   end Avail_In;\n\n   ---------------\n   -- Avail_Out --\n   ---------------\n\n   function Avail_Out (Strm : in Z_Stream) return UInt is\n   begin\n      return Strm.Avail_Out;\n   end Avail_Out;\n\n   ------------------\n   -- Deflate_Init --\n   ------------------\n\n   function Deflate_Init\n     (strm       : Z_Streamp;\n      level      : Int;\n      method     : Int;\n      windowBits : Int;\n      memLevel   : Int;\n      strategy   : Int)\n      return       Int is\n   begin\n      return deflateInit2\n               (strm,\n                level,\n                method,\n                windowBits,\n                memLevel,\n                strategy,\n                ZLIB_VERSION,\n                Z_Stream_Size);\n   end Deflate_Init;\n\n   ------------------\n   -- Inflate_Init --\n   ------------------\n\n   function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is\n   begin\n      return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size);\n   end Inflate_Init;\n\n   ------------------------\n   -- Last_Error_Message --\n   ------------------------\n\n   function Last_Error_Message (Strm : in Z_Stream) return String is\n      use Interfaces.C.Strings;\n   begin\n      if Strm.msg = Null_Ptr then\n         return \"\";\n      else\n         return Value (Strm.msg);\n      end if;\n   end Last_Error_Message;\n\n   ------------\n   -- Set_In --\n   ------------\n\n   procedure Set_In\n     (Strm   : in out Z_Stream;\n      Buffer : in     Voidp;\n      Size   : in     UInt) is\n   begin\n      Strm.Next_In  := Buffer;\n      Strm.Avail_In := Size;\n   end Set_In;\n\n   ------------------\n   -- Set_Mem_Func --\n   ------------------\n\n   procedure Set_Mem_Func\n     (Strm   : in out Z_Stream;\n      Opaque : in     Voidp;\n      Alloc  : in     alloc_func;\n      Free   : in     free_func) is\n   begin\n      Strm.opaque := Opaque;\n      Strm.zalloc := Alloc;\n      Strm.zfree  := Free;\n   end Set_Mem_Func;\n\n   -------------\n   -- Set_Out --\n   -------------\n\n   procedure Set_Out\n     (Strm   : in out Z_Stream;\n      Buffer : in     Voidp;\n      Size   : in     UInt) is\n   begin\n      Strm.Next_Out  := Buffer;\n      Strm.Avail_Out := Size;\n   end Set_Out;\n\n   --------------\n   -- Total_In --\n   --------------\n\n   function Total_In (Strm : in Z_Stream) return ULong is\n   begin\n      return Strm.Total_In;\n   end Total_In;\n\n   ---------------\n   -- Total_Out --\n   ---------------\n\n   function Total_Out (Strm : in Z_Stream) return ULong is\n   begin\n      return Strm.Total_Out;\n   end Total_Out;\n\nend ZLib.Thin;\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/ada/zlib-thin.ads",
    "content": "----------------------------------------------------------------\n--  ZLib for Ada thick binding.                               --\n--                                                            --\n--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --\n--                                                            --\n--  Open source license information is in the zlib.ads file.  --\n----------------------------------------------------------------\n\n--  $Id: zlib-thin.ads,v 1.11 2004/07/23 06:33:11 vagul Exp $\n\nwith Interfaces.C.Strings;\n\nwith System;\n\nprivate package ZLib.Thin is\n\n   --  From zconf.h\n\n   MAX_MEM_LEVEL : constant := 9;         --  zconf.h:105\n                                          --  zconf.h:105\n   MAX_WBITS : constant := 15;      --  zconf.h:115\n                                    --  32K LZ77 window\n                                    --  zconf.h:115\n   SEEK_SET : constant := 8#0000#;  --  zconf.h:244\n                                    --  Seek from beginning of file.\n                                    --  zconf.h:244\n   SEEK_CUR : constant := 1;        --  zconf.h:245\n                                    --  Seek from current position.\n                                    --  zconf.h:245\n   SEEK_END : constant := 2;        --  zconf.h:246\n                                    --  Set file pointer to EOF plus \"offset\"\n                                    --  zconf.h:246\n\n   type Byte is new Interfaces.C.unsigned_char; --  8 bits\n                                                --  zconf.h:214\n   type UInt is new Interfaces.C.unsigned;      --  16 bits or more\n                                                --  zconf.h:216\n   type Int is new Interfaces.C.int;\n\n   type ULong is new Interfaces.C.unsigned_long;     --  32 bits or more\n                                                     --  zconf.h:217\n   subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr;\n\n   type ULong_Access is access ULong;\n   type Int_Access is access Int;\n\n   subtype Voidp is System.Address;            --  zconf.h:232\n\n   subtype Byte_Access is Voidp;\n\n   Nul : constant Voidp := System.Null_Address;\n   --  end from zconf\n\n   Z_NO_FLUSH : constant := 8#0000#;   --  zlib.h:125\n                                       --  zlib.h:125\n   Z_PARTIAL_FLUSH : constant := 1;       --  zlib.h:126\n                                          --  will be removed, use\n                                          --  Z_SYNC_FLUSH instead\n                                          --  zlib.h:126\n   Z_SYNC_FLUSH : constant := 2;       --  zlib.h:127\n                                       --  zlib.h:127\n   Z_FULL_FLUSH : constant := 3;       --  zlib.h:128\n                                       --  zlib.h:128\n   Z_FINISH : constant := 4;        --  zlib.h:129\n                                    --  zlib.h:129\n   Z_OK : constant := 8#0000#;   --  zlib.h:132\n                                 --  zlib.h:132\n   Z_STREAM_END : constant := 1;       --  zlib.h:133\n                                       --  zlib.h:133\n   Z_NEED_DICT : constant := 2;        --  zlib.h:134\n                                       --  zlib.h:134\n   Z_ERRNO : constant := -1;        --  zlib.h:135\n                                    --  zlib.h:135\n   Z_STREAM_ERROR : constant := -2;       --  zlib.h:136\n                                          --  zlib.h:136\n   Z_DATA_ERROR : constant := -3;      --  zlib.h:137\n                                       --  zlib.h:137\n   Z_MEM_ERROR : constant := -4;       --  zlib.h:138\n                                       --  zlib.h:138\n   Z_BUF_ERROR : constant := -5;       --  zlib.h:139\n                                       --  zlib.h:139\n   Z_VERSION_ERROR : constant := -6;      --  zlib.h:140\n                                          --  zlib.h:140\n   Z_NO_COMPRESSION : constant := 8#0000#;   --  zlib.h:145\n                                             --  zlib.h:145\n   Z_BEST_SPEED : constant := 1;       --  zlib.h:146\n                                       --  zlib.h:146\n   Z_BEST_COMPRESSION : constant := 9;       --  zlib.h:147\n                                             --  zlib.h:147\n   Z_DEFAULT_COMPRESSION : constant := -1;      --  zlib.h:148\n                                                --  zlib.h:148\n   Z_FILTERED : constant := 1;      --  zlib.h:151\n                                    --  zlib.h:151\n   Z_HUFFMAN_ONLY : constant := 2;        --  zlib.h:152\n                                          --  zlib.h:152\n   Z_DEFAULT_STRATEGY : constant := 8#0000#; --  zlib.h:153\n                                             --  zlib.h:153\n   Z_BINARY : constant := 8#0000#;  --  zlib.h:156\n                                    --  zlib.h:156\n   Z_ASCII : constant := 1;      --  zlib.h:157\n                                 --  zlib.h:157\n   Z_UNKNOWN : constant := 2;       --  zlib.h:158\n                                    --  zlib.h:158\n   Z_DEFLATED : constant := 8;      --  zlib.h:161\n                                    --  zlib.h:161\n   Z_NULL : constant := 8#0000#; --  zlib.h:164\n                                 --  for initializing zalloc, zfree, opaque\n                                 --  zlib.h:164\n   type gzFile is new Voidp;                  --  zlib.h:646\n\n   type Z_Stream is private;\n\n   type Z_Streamp is access all Z_Stream;     --  zlib.h:89\n\n   type alloc_func is access function\n     (Opaque : Voidp;\n      Items  : UInt;\n      Size   : UInt)\n      return Voidp; --  zlib.h:63\n\n   type free_func is access procedure (opaque : Voidp; address : Voidp);\n\n   function zlibVersion return Chars_Ptr;\n\n   function Deflate (strm : Z_Streamp; flush : Int) return Int;\n\n   function DeflateEnd (strm : Z_Streamp) return Int;\n\n   function Inflate (strm : Z_Streamp; flush : Int) return Int;\n\n   function InflateEnd (strm : Z_Streamp) return Int;\n\n   function deflateSetDictionary\n     (strm       : Z_Streamp;\n      dictionary : Byte_Access;\n      dictLength : UInt)\n      return       Int;\n\n   function deflateCopy (dest : Z_Streamp; source : Z_Streamp) return Int;\n   --  zlib.h:478\n\n   function deflateReset (strm : Z_Streamp) return Int; -- zlib.h:495\n\n   function deflateParams\n     (strm     : Z_Streamp;\n      level    : Int;\n      strategy : Int)\n      return     Int;       -- zlib.h:506\n\n   function inflateSetDictionary\n     (strm       : Z_Streamp;\n      dictionary : Byte_Access;\n      dictLength : UInt)\n      return       Int; --  zlib.h:548\n\n   function inflateSync (strm : Z_Streamp) return Int;  --  zlib.h:565\n\n   function inflateReset (strm : Z_Streamp) return Int; --  zlib.h:580\n\n   function compress\n     (dest      : Byte_Access;\n      destLen   : ULong_Access;\n      source    : Byte_Access;\n      sourceLen : ULong)\n      return      Int;           -- zlib.h:601\n\n   function compress2\n     (dest      : Byte_Access;\n      destLen   : ULong_Access;\n      source    : Byte_Access;\n      sourceLen : ULong;\n      level     : Int)\n      return      Int;          -- zlib.h:615\n\n   function uncompress\n     (dest      : Byte_Access;\n      destLen   : ULong_Access;\n      source    : Byte_Access;\n      sourceLen : ULong)\n      return      Int;\n\n   function gzopen (path : Chars_Ptr; mode : Chars_Ptr) return gzFile;\n\n   function gzdopen (fd : Int; mode : Chars_Ptr) return gzFile;\n\n   function gzsetparams\n     (file     : gzFile;\n      level    : Int;\n      strategy : Int)\n      return     Int;\n\n   function gzread\n     (file : gzFile;\n      buf  : Voidp;\n      len  : UInt)\n      return Int;\n\n   function gzwrite\n     (file : in gzFile;\n      buf  : in Voidp;\n      len  : in UInt)\n      return Int;\n\n   function gzprintf (file : in gzFile; format : in Chars_Ptr) return Int;\n\n   function gzputs (file : in gzFile; s : in Chars_Ptr) return Int;\n\n   function gzgets\n     (file : gzFile;\n      buf  : Chars_Ptr;\n      len  : Int)\n      return Chars_Ptr;\n\n   function gzputc (file : gzFile; char : Int) return Int;\n\n   function gzgetc (file : gzFile) return Int;\n\n   function gzflush (file : gzFile; flush : Int) return Int;\n\n   function gzseek\n     (file   : gzFile;\n      offset : Int;\n      whence : Int)\n      return   Int;\n\n   function gzrewind (file : gzFile) return Int;\n\n   function gztell (file : gzFile) return Int;\n\n   function gzeof (file : gzFile) return Int;\n\n   function gzclose (file : gzFile) return Int;\n\n   function gzerror (file : gzFile; errnum : Int_Access) return Chars_Ptr;\n\n   function adler32\n     (adler : ULong;\n      buf   : Byte_Access;\n      len   : UInt)\n      return  ULong;\n\n   function crc32\n     (crc  : ULong;\n      buf  : Byte_Access;\n      len  : UInt)\n      return ULong;\n\n   function deflateInit\n     (strm        : Z_Streamp;\n      level       : Int;\n      version     : Chars_Ptr;\n      stream_size : Int)\n      return        Int;\n\n   function deflateInit2\n     (strm        : Z_Streamp;\n      level       : Int;\n      method      : Int;\n      windowBits  : Int;\n      memLevel    : Int;\n      strategy    : Int;\n      version     : Chars_Ptr;\n      stream_size : Int)\n      return        Int;\n\n   function Deflate_Init\n     (strm       : Z_Streamp;\n      level      : Int;\n      method     : Int;\n      windowBits : Int;\n      memLevel   : Int;\n      strategy   : Int)\n      return       Int;\n   pragma Inline (Deflate_Init);\n\n   function inflateInit\n     (strm        : Z_Streamp;\n      version     : Chars_Ptr;\n      stream_size : Int)\n      return        Int;\n\n   function inflateInit2\n     (strm        : in Z_Streamp;\n      windowBits  : in Int;\n      version     : in Chars_Ptr;\n      stream_size : in Int)\n      return      Int;\n\n   function inflateBackInit\n     (strm        : in Z_Streamp;\n      windowBits  : in Int;\n      window      : in Byte_Access;\n      version     : in Chars_Ptr;\n      stream_size : in Int)\n      return      Int;\n   --  Size of window have to be 2**windowBits.\n\n   function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int;\n   pragma Inline (Inflate_Init);\n\n   function zError (err : Int) return Chars_Ptr;\n\n   function inflateSyncPoint (z : Z_Streamp) return Int;\n\n   function get_crc_table return ULong_Access;\n\n   --  Interface to the available fields of the z_stream structure.\n   --  The application must update next_in and avail_in when avail_in has\n   --  dropped to zero. It must update next_out and avail_out when avail_out\n   --  has dropped to zero. The application must initialize zalloc, zfree and\n   --  opaque before calling the init function.\n\n   procedure Set_In\n     (Strm   : in out Z_Stream;\n      Buffer : in Voidp;\n      Size   : in UInt);\n   pragma Inline (Set_In);\n\n   procedure Set_Out\n     (Strm   : in out Z_Stream;\n      Buffer : in Voidp;\n      Size   : in UInt);\n   pragma Inline (Set_Out);\n\n   procedure Set_Mem_Func\n     (Strm   : in out Z_Stream;\n      Opaque : in Voidp;\n      Alloc  : in alloc_func;\n      Free   : in free_func);\n   pragma Inline (Set_Mem_Func);\n\n   function Last_Error_Message (Strm : in Z_Stream) return String;\n   pragma Inline (Last_Error_Message);\n\n   function Avail_Out (Strm : in Z_Stream) return UInt;\n   pragma Inline (Avail_Out);\n\n   function Avail_In (Strm : in Z_Stream) return UInt;\n   pragma Inline (Avail_In);\n\n   function Total_In (Strm : in Z_Stream) return ULong;\n   pragma Inline (Total_In);\n\n   function Total_Out (Strm : in Z_Stream) return ULong;\n   pragma Inline (Total_Out);\n\n   function inflateCopy\n     (dest   : in Z_Streamp;\n      Source : in Z_Streamp)\n      return Int;\n\n   function compressBound (Source_Len : in ULong) return ULong;\n\n   function deflateBound\n     (Strm       : in Z_Streamp;\n      Source_Len : in ULong)\n      return     ULong;\n\n   function gzungetc (C : in Int; File : in  gzFile) return Int;\n\n   function zlibCompileFlags return ULong;\n\nprivate\n\n   type Z_Stream is record            -- zlib.h:68\n      Next_In   : Voidp      := Nul;  -- next input byte\n      Avail_In  : UInt       := 0;    -- number of bytes available at next_in\n      Total_In  : ULong      := 0;    -- total nb of input bytes read so far\n      Next_Out  : Voidp      := Nul;  -- next output byte should be put there\n      Avail_Out : UInt       := 0;    -- remaining free space at next_out\n      Total_Out : ULong      := 0;    -- total nb of bytes output so far\n      msg       : Chars_Ptr;          -- last error message, NULL if no error\n      state     : Voidp;              -- not visible by applications\n      zalloc    : alloc_func := null; -- used to allocate the internal state\n      zfree     : free_func  := null; -- used to free the internal state\n      opaque    : Voidp;              -- private data object passed to\n                                      --  zalloc and zfree\n      data_type : Int;                -- best guess about the data type:\n                                      --  ascii or binary\n      adler     : ULong;              -- adler32 value of the uncompressed\n                                      --  data\n      reserved  : ULong;              -- reserved for future use\n   end record;\n\n   pragma Convention (C, Z_Stream);\n\n   pragma Import (C, zlibVersion, \"zlibVersion\");\n   pragma Import (C, Deflate, \"deflate\");\n   pragma Import (C, DeflateEnd, \"deflateEnd\");\n   pragma Import (C, Inflate, \"inflate\");\n   pragma Import (C, InflateEnd, \"inflateEnd\");\n   pragma Import (C, deflateSetDictionary, \"deflateSetDictionary\");\n   pragma Import (C, deflateCopy, \"deflateCopy\");\n   pragma Import (C, deflateReset, \"deflateReset\");\n   pragma Import (C, deflateParams, \"deflateParams\");\n   pragma Import (C, inflateSetDictionary, \"inflateSetDictionary\");\n   pragma Import (C, inflateSync, \"inflateSync\");\n   pragma Import (C, inflateReset, \"inflateReset\");\n   pragma Import (C, compress, \"compress\");\n   pragma Import (C, compress2, \"compress2\");\n   pragma Import (C, uncompress, \"uncompress\");\n   pragma Import (C, gzopen, \"gzopen\");\n   pragma Import (C, gzdopen, \"gzdopen\");\n   pragma Import (C, gzsetparams, \"gzsetparams\");\n   pragma Import (C, gzread, \"gzread\");\n   pragma Import (C, gzwrite, \"gzwrite\");\n   pragma Import (C, gzprintf, \"gzprintf\");\n   pragma Import (C, gzputs, \"gzputs\");\n   pragma Import (C, gzgets, \"gzgets\");\n   pragma Import (C, gzputc, \"gzputc\");\n   pragma Import (C, gzgetc, \"gzgetc\");\n   pragma Import (C, gzflush, \"gzflush\");\n   pragma Import (C, gzseek, \"gzseek\");\n   pragma Import (C, gzrewind, \"gzrewind\");\n   pragma Import (C, gztell, \"gztell\");\n   pragma Import (C, gzeof, \"gzeof\");\n   pragma Import (C, gzclose, \"gzclose\");\n   pragma Import (C, gzerror, \"gzerror\");\n   pragma Import (C, adler32, \"adler32\");\n   pragma Import (C, crc32, \"crc32\");\n   pragma Import (C, deflateInit, \"deflateInit_\");\n   pragma Import (C, inflateInit, \"inflateInit_\");\n   pragma Import (C, deflateInit2, \"deflateInit2_\");\n   pragma Import (C, inflateInit2, \"inflateInit2_\");\n   pragma Import (C, zError, \"zError\");\n   pragma Import (C, inflateSyncPoint, \"inflateSyncPoint\");\n   pragma Import (C, get_crc_table, \"get_crc_table\");\n\n   --  since zlib 1.2.0:\n\n   pragma Import (C, inflateCopy, \"inflateCopy\");\n   pragma Import (C, compressBound, \"compressBound\");\n   pragma Import (C, deflateBound, \"deflateBound\");\n   pragma Import (C, gzungetc, \"gzungetc\");\n   pragma Import (C, zlibCompileFlags, \"zlibCompileFlags\");\n\n   pragma Import (C, inflateBackInit, \"inflateBackInit_\");\n\n   --  I stopped binding the inflateBack routines, becouse realize that\n   --  it does not support zlib and gzip headers for now, and have no\n   --  symmetric deflateBack routines.\n   --  ZLib-Ada is symmetric regarding deflate/inflate data transformation\n   --  and has a similar generic callback interface for the\n   --  deflate/inflate transformation based on the regular Deflate/Inflate\n   --  routines.\n\n   --  pragma Import (C, inflateBack, \"inflateBack\");\n   --  pragma Import (C, inflateBackEnd, \"inflateBackEnd\");\n\nend ZLib.Thin;\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/ada/zlib.adb",
    "content": "----------------------------------------------------------------\n--  ZLib for Ada thick binding.                               --\n--                                                            --\n--  Copyright (C) 2002-2004 Dmitriy Anisimkov                 --\n--                                                            --\n--  Open source license information is in the zlib.ads file.  --\n----------------------------------------------------------------\n\n--  $Id: zlib.adb,v 1.31 2004/09/06 06:53:19 vagul Exp $\n\nwith Ada.Exceptions;\nwith Ada.Unchecked_Conversion;\nwith Ada.Unchecked_Deallocation;\n\nwith Interfaces.C.Strings;\n\nwith ZLib.Thin;\n\npackage body ZLib is\n\n   use type Thin.Int;\n\n   type Z_Stream is new Thin.Z_Stream;\n\n   type Return_Code_Enum is\n      (OK,\n       STREAM_END,\n       NEED_DICT,\n       ERRNO,\n       STREAM_ERROR,\n       DATA_ERROR,\n       MEM_ERROR,\n       BUF_ERROR,\n       VERSION_ERROR);\n\n   type Flate_Step_Function is access\n     function (Strm : in Thin.Z_Streamp; Flush : in Thin.Int) return Thin.Int;\n   pragma Convention (C, Flate_Step_Function);\n\n   type Flate_End_Function is access\n      function (Ctrm : in Thin.Z_Streamp) return Thin.Int;\n   pragma Convention (C, Flate_End_Function);\n\n   type Flate_Type is record\n      Step : Flate_Step_Function;\n      Done : Flate_End_Function;\n   end record;\n\n   subtype Footer_Array is Stream_Element_Array (1 .. 8);\n\n   Simple_GZip_Header : constant Stream_Element_Array (1 .. 10)\n     := (16#1f#, 16#8b#,                 --  Magic header\n         16#08#,                         --  Z_DEFLATED\n         16#00#,                         --  Flags\n         16#00#, 16#00#, 16#00#, 16#00#, --  Time\n         16#00#,                         --  XFlags\n         16#03#                          --  OS code\n        );\n   --  The simplest gzip header is not for informational, but just for\n   --  gzip format compatibility.\n   --  Note that some code below is using assumption\n   --  Simple_GZip_Header'Last > Footer_Array'Last, so do not make\n   --  Simple_GZip_Header'Last <= Footer_Array'Last.\n\n   Return_Code : constant array (Thin.Int range <>) of Return_Code_Enum\n     := (0 => OK,\n         1 => STREAM_END,\n         2 => NEED_DICT,\n        -1 => ERRNO,\n        -2 => STREAM_ERROR,\n        -3 => DATA_ERROR,\n        -4 => MEM_ERROR,\n        -5 => BUF_ERROR,\n        -6 => VERSION_ERROR);\n\n   Flate : constant array (Boolean) of Flate_Type\n     := (True  => (Step => Thin.Deflate'Access,\n                   Done => Thin.DeflateEnd'Access),\n         False => (Step => Thin.Inflate'Access,\n                   Done => Thin.InflateEnd'Access));\n\n   Flush_Finish : constant array (Boolean) of Flush_Mode\n     := (True => Finish, False => No_Flush);\n\n   procedure Raise_Error (Stream : in Z_Stream);\n   pragma Inline (Raise_Error);\n\n   procedure Raise_Error (Message : in String);\n   pragma Inline (Raise_Error);\n\n   procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int);\n\n   procedure Free is new Ada.Unchecked_Deallocation\n      (Z_Stream, Z_Stream_Access);\n\n   function To_Thin_Access is new Ada.Unchecked_Conversion\n     (Z_Stream_Access, Thin.Z_Streamp);\n\n   procedure Translate_GZip\n     (Filter    : in out Filter_Type;\n      In_Data   : in     Ada.Streams.Stream_Element_Array;\n      In_Last   :    out Ada.Streams.Stream_Element_Offset;\n      Out_Data  :    out Ada.Streams.Stream_Element_Array;\n      Out_Last  :    out Ada.Streams.Stream_Element_Offset;\n      Flush     : in     Flush_Mode);\n   --  Separate translate routine for make gzip header.\n\n   procedure Translate_Auto\n     (Filter    : in out Filter_Type;\n      In_Data   : in     Ada.Streams.Stream_Element_Array;\n      In_Last   :    out Ada.Streams.Stream_Element_Offset;\n      Out_Data  :    out Ada.Streams.Stream_Element_Array;\n      Out_Last  :    out Ada.Streams.Stream_Element_Offset;\n      Flush     : in     Flush_Mode);\n   --  translate routine without additional headers.\n\n   -----------------\n   -- Check_Error --\n   -----------------\n\n   procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int) is\n      use type Thin.Int;\n   begin\n      if Code /= Thin.Z_OK then\n         Raise_Error\n            (Return_Code_Enum'Image (Return_Code (Code))\n              & \": \" & Last_Error_Message (Stream));\n      end if;\n   end Check_Error;\n\n   -----------\n   -- Close --\n   -----------\n\n   procedure Close\n     (Filter       : in out Filter_Type;\n      Ignore_Error : in     Boolean := False)\n   is\n      Code : Thin.Int;\n   begin\n      if not Ignore_Error and then not Is_Open (Filter) then\n         raise Status_Error;\n      end if;\n\n      Code := Flate (Filter.Compression).Done (To_Thin_Access (Filter.Strm));\n\n      if Ignore_Error or else Code = Thin.Z_OK then\n         Free (Filter.Strm);\n      else\n         declare\n            Error_Message : constant String\n              := Last_Error_Message (Filter.Strm.all);\n         begin\n            Free (Filter.Strm);\n            Ada.Exceptions.Raise_Exception\n               (ZLib_Error'Identity,\n                Return_Code_Enum'Image (Return_Code (Code))\n                  & \": \" & Error_Message);\n         end;\n      end if;\n   end Close;\n\n   -----------\n   -- CRC32 --\n   -----------\n\n   function CRC32\n     (CRC  : in Unsigned_32;\n      Data : in Ada.Streams.Stream_Element_Array)\n      return Unsigned_32\n   is\n      use Thin;\n   begin\n      return Unsigned_32 (crc32 (ULong (CRC),\n                                 Data'Address,\n                                 Data'Length));\n   end CRC32;\n\n   procedure CRC32\n     (CRC  : in out Unsigned_32;\n      Data : in     Ada.Streams.Stream_Element_Array) is\n   begin\n      CRC := CRC32 (CRC, Data);\n   end CRC32;\n\n   ------------------\n   -- Deflate_Init --\n   ------------------\n\n   procedure Deflate_Init\n     (Filter       : in out Filter_Type;\n      Level        : in     Compression_Level  := Default_Compression;\n      Strategy     : in     Strategy_Type      := Default_Strategy;\n      Method       : in     Compression_Method := Deflated;\n      Window_Bits  : in     Window_Bits_Type   := Default_Window_Bits;\n      Memory_Level : in     Memory_Level_Type  := Default_Memory_Level;\n      Header       : in     Header_Type        := Default)\n   is\n      use type Thin.Int;\n      Win_Bits : Thin.Int := Thin.Int (Window_Bits);\n   begin\n      if Is_Open (Filter) then\n         raise Status_Error;\n      end if;\n\n      --  We allow ZLib to make header only in case of default header type.\n      --  Otherwise we would either do header by ourselfs, or do not do\n      --  header at all.\n\n      if Header = None or else Header = GZip then\n         Win_Bits := -Win_Bits;\n      end if;\n\n      --  For the GZip CRC calculation and make headers.\n\n      if Header = GZip then\n         Filter.CRC    := 0;\n         Filter.Offset := Simple_GZip_Header'First;\n      else\n         Filter.Offset := Simple_GZip_Header'Last + 1;\n      end if;\n\n      Filter.Strm        := new Z_Stream;\n      Filter.Compression := True;\n      Filter.Stream_End  := False;\n      Filter.Header      := Header;\n\n      if Thin.Deflate_Init\n           (To_Thin_Access (Filter.Strm),\n            Level      => Thin.Int (Level),\n            method     => Thin.Int (Method),\n            windowBits => Win_Bits,\n            memLevel   => Thin.Int (Memory_Level),\n            strategy   => Thin.Int (Strategy)) /= Thin.Z_OK\n      then\n         Raise_Error (Filter.Strm.all);\n      end if;\n   end Deflate_Init;\n\n   -----------\n   -- Flush --\n   -----------\n\n   procedure Flush\n     (Filter    : in out Filter_Type;\n      Out_Data  :    out Ada.Streams.Stream_Element_Array;\n      Out_Last  :    out Ada.Streams.Stream_Element_Offset;\n      Flush     : in     Flush_Mode)\n   is\n      No_Data : Stream_Element_Array := (1 .. 0 => 0);\n      Last    : Stream_Element_Offset;\n   begin\n      Translate (Filter, No_Data, Last, Out_Data, Out_Last, Flush);\n   end Flush;\n\n   -----------------------\n   -- Generic_Translate --\n   -----------------------\n\n   procedure Generic_Translate\n     (Filter          : in out ZLib.Filter_Type;\n      In_Buffer_Size  : in     Integer := Default_Buffer_Size;\n      Out_Buffer_Size : in     Integer := Default_Buffer_Size)\n   is\n      In_Buffer  : Stream_Element_Array\n                     (1 .. Stream_Element_Offset (In_Buffer_Size));\n      Out_Buffer : Stream_Element_Array\n                     (1 .. Stream_Element_Offset (Out_Buffer_Size));\n      Last       : Stream_Element_Offset;\n      In_Last    : Stream_Element_Offset;\n      In_First   : Stream_Element_Offset;\n      Out_Last   : Stream_Element_Offset;\n   begin\n      Main : loop\n         Data_In (In_Buffer, Last);\n\n         In_First := In_Buffer'First;\n\n         loop\n            Translate\n              (Filter   => Filter,\n               In_Data  => In_Buffer (In_First .. Last),\n               In_Last  => In_Last,\n               Out_Data => Out_Buffer,\n               Out_Last => Out_Last,\n               Flush    => Flush_Finish (Last < In_Buffer'First));\n\n            if Out_Buffer'First <= Out_Last then\n               Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last));\n            end if;\n\n            exit Main when Stream_End (Filter);\n\n            --  The end of in buffer.\n\n            exit when In_Last = Last;\n\n            In_First := In_Last + 1;\n         end loop;\n      end loop Main;\n\n   end Generic_Translate;\n\n   ------------------\n   -- Inflate_Init --\n   ------------------\n\n   procedure Inflate_Init\n     (Filter      : in out Filter_Type;\n      Window_Bits : in     Window_Bits_Type := Default_Window_Bits;\n      Header      : in     Header_Type      := Default)\n   is\n      use type Thin.Int;\n      Win_Bits : Thin.Int := Thin.Int (Window_Bits);\n\n      procedure Check_Version;\n      --  Check the latest header types compatibility.\n\n      procedure Check_Version is\n      begin\n         if Version <= \"1.1.4\" then\n            Raise_Error\n              (\"Inflate header type \" & Header_Type'Image (Header)\n               & \" incompatible with ZLib version \" & Version);\n         end if;\n      end Check_Version;\n\n   begin\n      if Is_Open (Filter) then\n         raise Status_Error;\n      end if;\n\n      case Header is\n         when None =>\n            Check_Version;\n\n            --  Inflate data without headers determined\n            --  by negative Win_Bits.\n\n            Win_Bits := -Win_Bits;\n         when GZip =>\n            Check_Version;\n\n            --  Inflate gzip data defined by flag 16.\n\n            Win_Bits := Win_Bits + 16;\n         when Auto =>\n            Check_Version;\n\n            --  Inflate with automatic detection\n            --  of gzip or native header defined by flag 32.\n\n            Win_Bits := Win_Bits + 32;\n         when Default => null;\n      end case;\n\n      Filter.Strm        := new Z_Stream;\n      Filter.Compression := False;\n      Filter.Stream_End  := False;\n      Filter.Header      := Header;\n\n      if Thin.Inflate_Init\n         (To_Thin_Access (Filter.Strm), Win_Bits) /= Thin.Z_OK\n      then\n         Raise_Error (Filter.Strm.all);\n      end if;\n   end Inflate_Init;\n\n   -------------\n   -- Is_Open --\n   -------------\n\n   function Is_Open (Filter : in Filter_Type) return Boolean is\n   begin\n      return Filter.Strm /= null;\n   end Is_Open;\n\n   -----------------\n   -- Raise_Error --\n   -----------------\n\n   procedure Raise_Error (Message : in String) is\n   begin\n      Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message);\n   end Raise_Error;\n\n   procedure Raise_Error (Stream : in Z_Stream) is\n   begin\n      Raise_Error (Last_Error_Message (Stream));\n   end Raise_Error;\n\n   ----------\n   -- Read --\n   ----------\n\n   procedure Read\n     (Filter : in out Filter_Type;\n      Item   :    out Ada.Streams.Stream_Element_Array;\n      Last   :    out Ada.Streams.Stream_Element_Offset;\n      Flush  : in     Flush_Mode := No_Flush)\n   is\n      In_Last    : Stream_Element_Offset;\n      Item_First : Ada.Streams.Stream_Element_Offset := Item'First;\n      V_Flush    : Flush_Mode := Flush;\n\n   begin\n      pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1);\n      pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last);\n\n      loop\n         if Rest_Last = Buffer'First - 1 then\n            V_Flush := Finish;\n\n         elsif Rest_First > Rest_Last then\n            Read (Buffer, Rest_Last);\n            Rest_First := Buffer'First;\n\n            if Rest_Last < Buffer'First then\n               V_Flush := Finish;\n            end if;\n         end if;\n\n         Translate\n           (Filter   => Filter,\n            In_Data  => Buffer (Rest_First .. Rest_Last),\n            In_Last  => In_Last,\n            Out_Data => Item (Item_First .. Item'Last),\n            Out_Last => Last,\n            Flush    => V_Flush);\n\n         Rest_First := In_Last + 1;\n\n         exit when Stream_End (Filter)\n           or else Last = Item'Last\n           or else (Last >= Item'First and then Allow_Read_Some);\n\n         Item_First := Last + 1;\n      end loop;\n   end Read;\n\n   ----------------\n   -- Stream_End --\n   ----------------\n\n   function Stream_End (Filter : in Filter_Type) return Boolean is\n   begin\n      if Filter.Header = GZip and Filter.Compression then\n         return Filter.Stream_End\n            and then Filter.Offset = Footer_Array'Last + 1;\n      else\n         return Filter.Stream_End;\n      end if;\n   end Stream_End;\n\n   --------------\n   -- Total_In --\n   --------------\n\n   function Total_In (Filter : in Filter_Type) return Count is\n   begin\n      return Count (Thin.Total_In (To_Thin_Access (Filter.Strm).all));\n   end Total_In;\n\n   ---------------\n   -- Total_Out --\n   ---------------\n\n   function Total_Out (Filter : in Filter_Type) return Count is\n   begin\n      return Count (Thin.Total_Out (To_Thin_Access (Filter.Strm).all));\n   end Total_Out;\n\n   ---------------\n   -- Translate --\n   ---------------\n\n   procedure Translate\n     (Filter    : in out Filter_Type;\n      In_Data   : in     Ada.Streams.Stream_Element_Array;\n      In_Last   :    out Ada.Streams.Stream_Element_Offset;\n      Out_Data  :    out Ada.Streams.Stream_Element_Array;\n      Out_Last  :    out Ada.Streams.Stream_Element_Offset;\n      Flush     : in     Flush_Mode) is\n   begin\n      if Filter.Header = GZip and then Filter.Compression then\n         Translate_GZip\n           (Filter   => Filter,\n            In_Data  => In_Data,\n            In_Last  => In_Last,\n            Out_Data => Out_Data,\n            Out_Last => Out_Last,\n            Flush    => Flush);\n      else\n         Translate_Auto\n           (Filter   => Filter,\n            In_Data  => In_Data,\n            In_Last  => In_Last,\n            Out_Data => Out_Data,\n            Out_Last => Out_Last,\n            Flush    => Flush);\n      end if;\n   end Translate;\n\n   --------------------\n   -- Translate_Auto --\n   --------------------\n\n   procedure Translate_Auto\n     (Filter    : in out Filter_Type;\n      In_Data   : in     Ada.Streams.Stream_Element_Array;\n      In_Last   :    out Ada.Streams.Stream_Element_Offset;\n      Out_Data  :    out Ada.Streams.Stream_Element_Array;\n      Out_Last  :    out Ada.Streams.Stream_Element_Offset;\n      Flush     : in     Flush_Mode)\n   is\n      use type Thin.Int;\n      Code : Thin.Int;\n\n   begin\n      if not Is_Open (Filter) then\n         raise Status_Error;\n      end if;\n\n      if Out_Data'Length = 0 and then In_Data'Length = 0 then\n         raise Constraint_Error;\n      end if;\n\n      Set_Out (Filter.Strm.all, Out_Data'Address, Out_Data'Length);\n      Set_In  (Filter.Strm.all, In_Data'Address, In_Data'Length);\n\n      Code := Flate (Filter.Compression).Step\n        (To_Thin_Access (Filter.Strm),\n         Thin.Int (Flush));\n\n      if Code = Thin.Z_STREAM_END then\n         Filter.Stream_End := True;\n      else\n         Check_Error (Filter.Strm.all, Code);\n      end if;\n\n      In_Last  := In_Data'Last\n         - Stream_Element_Offset (Avail_In (Filter.Strm.all));\n      Out_Last := Out_Data'Last\n         - Stream_Element_Offset (Avail_Out (Filter.Strm.all));\n   end Translate_Auto;\n\n   --------------------\n   -- Translate_GZip --\n   --------------------\n\n   procedure Translate_GZip\n     (Filter    : in out Filter_Type;\n      In_Data   : in     Ada.Streams.Stream_Element_Array;\n      In_Last   :    out Ada.Streams.Stream_Element_Offset;\n      Out_Data  :    out Ada.Streams.Stream_Element_Array;\n      Out_Last  :    out Ada.Streams.Stream_Element_Offset;\n      Flush     : in     Flush_Mode)\n   is\n      Out_First : Stream_Element_Offset;\n\n      procedure Add_Data (Data : in Stream_Element_Array);\n      --  Add data to stream from the Filter.Offset till necessary,\n      --  used for add gzip headr/footer.\n\n      procedure Put_32\n        (Item : in out Stream_Element_Array;\n         Data : in     Unsigned_32);\n      pragma Inline (Put_32);\n\n      --------------\n      -- Add_Data --\n      --------------\n\n      procedure Add_Data (Data : in Stream_Element_Array) is\n         Data_First : Stream_Element_Offset renames Filter.Offset;\n         Data_Last  : Stream_Element_Offset;\n         Data_Len   : Stream_Element_Offset; --  -1\n         Out_Len    : Stream_Element_Offset; --  -1\n      begin\n         Out_First := Out_Last + 1;\n\n         if Data_First > Data'Last then\n            return;\n         end if;\n\n         Data_Len  := Data'Last     - Data_First;\n         Out_Len   := Out_Data'Last - Out_First;\n\n         if Data_Len <= Out_Len then\n            Out_Last  := Out_First  + Data_Len;\n            Data_Last := Data'Last;\n         else\n            Out_Last  := Out_Data'Last;\n            Data_Last := Data_First + Out_Len;\n         end if;\n\n         Out_Data (Out_First .. Out_Last) := Data (Data_First .. Data_Last);\n\n         Data_First := Data_Last + 1;\n         Out_First  := Out_Last + 1;\n      end Add_Data;\n\n      ------------\n      -- Put_32 --\n      ------------\n\n      procedure Put_32\n        (Item : in out Stream_Element_Array;\n         Data : in     Unsigned_32)\n      is\n         D : Unsigned_32 := Data;\n      begin\n         for J in Item'First .. Item'First + 3 loop\n            Item (J) := Stream_Element (D and 16#FF#);\n            D := Shift_Right (D, 8);\n         end loop;\n      end Put_32;\n\n   begin\n      Out_Last := Out_Data'First - 1;\n\n      if not Filter.Stream_End then\n         Add_Data (Simple_GZip_Header);\n\n         Translate_Auto\n           (Filter   => Filter,\n            In_Data  => In_Data,\n            In_Last  => In_Last,\n            Out_Data => Out_Data (Out_First .. Out_Data'Last),\n            Out_Last => Out_Last,\n            Flush    => Flush);\n\n         CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last));\n      end if;\n\n      if Filter.Stream_End and then Out_Last <= Out_Data'Last then\n         --  This detection method would work only when\n         --  Simple_GZip_Header'Last > Footer_Array'Last\n\n         if Filter.Offset = Simple_GZip_Header'Last + 1 then\n            Filter.Offset := Footer_Array'First;\n         end if;\n\n         declare\n            Footer : Footer_Array;\n         begin\n            Put_32 (Footer, Filter.CRC);\n            Put_32 (Footer (Footer'First + 4 .. Footer'Last),\n                    Unsigned_32 (Total_In (Filter)));\n            Add_Data (Footer);\n         end;\n      end if;\n   end Translate_GZip;\n\n   -------------\n   -- Version --\n   -------------\n\n   function Version return String is\n   begin\n      return Interfaces.C.Strings.Value (Thin.zlibVersion);\n   end Version;\n\n   -----------\n   -- Write --\n   -----------\n\n   procedure Write\n     (Filter : in out Filter_Type;\n      Item   : in     Ada.Streams.Stream_Element_Array;\n      Flush  : in     Flush_Mode := No_Flush)\n   is\n      Buffer   : Stream_Element_Array (1 .. Buffer_Size);\n      In_Last  : Stream_Element_Offset;\n      Out_Last : Stream_Element_Offset;\n      In_First : Stream_Element_Offset := Item'First;\n   begin\n      if Item'Length = 0 and Flush = No_Flush then\n         return;\n      end if;\n\n      loop\n         Translate\n           (Filter   => Filter,\n            In_Data  => Item (In_First .. Item'Last),\n            In_Last  => In_Last,\n            Out_Data => Buffer,\n            Out_Last => Out_Last,\n            Flush    => Flush);\n\n         if Out_Last >= Buffer'First then\n            Write (Buffer (1 .. Out_Last));\n         end if;\n\n         exit when In_Last = Item'Last or Stream_End (Filter);\n\n         In_First := In_Last + 1;\n      end loop;\n   end Write;\n\nend ZLib;\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/ada/zlib.ads",
    "content": "------------------------------------------------------------------------------\n--                      ZLib for Ada thick binding.                         --\n--                                                                          --\n--              Copyright (C) 2002-2004 Dmitriy Anisimkov                   --\n--                                                                          --\n--  This library is free software; you can redistribute it and/or modify    --\n--  it under the terms of the GNU General Public License as published by    --\n--  the Free Software Foundation; either version 2 of the License, or (at   --\n--  your option) any later version.                                         --\n--                                                                          --\n--  This library is distributed in the hope that it will be useful, but     --\n--  WITHOUT ANY WARRANTY; without even the implied warranty of              --\n--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       --\n--  General Public License for more details.                                --\n--                                                                          --\n--  You should have received a copy of the GNU General Public License       --\n--  along with this library; if not, write to the Free Software Foundation, --\n--  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.          --\n--                                                                          --\n--  As a special exception, if other files instantiate generics from this   --\n--  unit, or you link this unit with other files to produce an executable,  --\n--  this  unit  does not  by itself cause  the resulting executable to be   --\n--  covered by the GNU General Public License. This exception does not      --\n--  however invalidate any other reasons why the executable file  might be  --\n--  covered by the  GNU Public License.                                     --\n------------------------------------------------------------------------------\n\n--  $Id: zlib.ads,v 1.26 2004/09/06 06:53:19 vagul Exp $\n\nwith Ada.Streams;\n\nwith Interfaces;\n\npackage ZLib is\n\n   ZLib_Error   : exception;\n   Status_Error : exception;\n\n   type Compression_Level is new Integer range -1 .. 9;\n\n   type Flush_Mode is private;\n\n   type Compression_Method is private;\n\n   type Window_Bits_Type is new Integer range 8 .. 15;\n\n   type Memory_Level_Type is new Integer range 1 .. 9;\n\n   type Unsigned_32 is new Interfaces.Unsigned_32;\n\n   type Strategy_Type is private;\n\n   type Header_Type is (None, Auto, Default, GZip);\n   --  Header type usage have a some limitation for inflate.\n   --  See comment for Inflate_Init.\n\n   subtype Count is Ada.Streams.Stream_Element_Count;\n\n   Default_Memory_Level : constant Memory_Level_Type := 8;\n   Default_Window_Bits  : constant Window_Bits_Type  := 15;\n\n   ----------------------------------\n   -- Compression method constants --\n   ----------------------------------\n\n   Deflated : constant Compression_Method;\n   --  Only one method allowed in this ZLib version\n\n   ---------------------------------\n   -- Compression level constants --\n   ---------------------------------\n\n   No_Compression      : constant Compression_Level := 0;\n   Best_Speed          : constant Compression_Level := 1;\n   Best_Compression    : constant Compression_Level := 9;\n   Default_Compression : constant Compression_Level := -1;\n\n   --------------------------\n   -- Flush mode constants --\n   --------------------------\n\n   No_Flush      : constant Flush_Mode;\n   --  Regular way for compression, no flush\n\n   Partial_Flush : constant Flush_Mode;\n   --  Will be removed, use Z_SYNC_FLUSH instead\n\n   Sync_Flush    : constant Flush_Mode;\n   --  All pending output is flushed to the output buffer and the output\n   --  is aligned on a byte boundary, so that the decompressor can get all\n   --  input data available so far. (In particular avail_in is zero after the\n   --  call if enough output space has been provided  before the call.)\n   --  Flushing may degrade compression for some compression algorithms and so\n   --  it should be used only when necessary.\n\n   Block_Flush   : constant Flush_Mode;\n   --  Z_BLOCK requests that inflate() stop\n   --  if and when it get to the next deflate block boundary. When decoding the\n   --  zlib or gzip format, this will cause inflate() to return immediately\n   --  after the header and before the first block. When doing a raw inflate,\n   --  inflate() will go ahead and process the first block, and will return\n   --  when it gets to the end of that block, or when it runs out of data.\n\n   Full_Flush    : constant Flush_Mode;\n   --  All output is flushed as with SYNC_FLUSH, and the compression state\n   --  is reset so that decompression can restart from this point if previous\n   --  compressed data has been damaged or if random access is desired. Using\n   --  Full_Flush too often can seriously degrade the compression.\n\n   Finish        : constant Flush_Mode;\n   --  Just for tell the compressor that input data is complete.\n\n   ------------------------------------\n   -- Compression strategy constants --\n   ------------------------------------\n\n   --  RLE stategy could be used only in version 1.2.0 and later.\n\n   Filtered         : constant Strategy_Type;\n   Huffman_Only     : constant Strategy_Type;\n   RLE              : constant Strategy_Type;\n   Default_Strategy : constant Strategy_Type;\n\n   Default_Buffer_Size : constant := 4096;\n\n   type Filter_Type is tagged limited private;\n   --  The filter is for compression and for decompression.\n   --  The usage of the type is depend of its initialization.\n\n   function Version return String;\n   pragma Inline (Version);\n   --  Return string representation of the ZLib version.\n\n   procedure Deflate_Init\n     (Filter       : in out Filter_Type;\n      Level        : in     Compression_Level  := Default_Compression;\n      Strategy     : in     Strategy_Type      := Default_Strategy;\n      Method       : in     Compression_Method := Deflated;\n      Window_Bits  : in     Window_Bits_Type   := Default_Window_Bits;\n      Memory_Level : in     Memory_Level_Type  := Default_Memory_Level;\n      Header       : in     Header_Type        := Default);\n   --  Compressor initialization.\n   --  When Header parameter is Auto or Default, then default zlib header\n   --  would be provided for compressed data.\n   --  When Header is GZip, then gzip header would be set instead of\n   --  default header.\n   --  When Header is None, no header would be set for compressed data.\n\n   procedure Inflate_Init\n     (Filter      : in out Filter_Type;\n      Window_Bits : in     Window_Bits_Type := Default_Window_Bits;\n      Header      : in     Header_Type      := Default);\n   --  Decompressor initialization.\n   --  Default header type mean that ZLib default header is expecting in the\n   --  input compressed stream.\n   --  Header type None mean that no header is expecting in the input stream.\n   --  GZip header type mean that GZip header is expecting in the\n   --  input compressed stream.\n   --  Auto header type mean that header type (GZip or Native) would be\n   --  detected automatically in the input stream.\n   --  Note that header types parameter values None, GZip and Auto are\n   --  supported for inflate routine only in ZLib versions 1.2.0.2 and later.\n   --  Deflate_Init is supporting all header types.\n\n   function Is_Open (Filter : in Filter_Type) return Boolean;\n   pragma Inline (Is_Open);\n   --  Is the filter opened for compression or decompression.\n\n   procedure Close\n     (Filter       : in out Filter_Type;\n      Ignore_Error : in     Boolean := False);\n   --  Closing the compression or decompressor.\n   --  If stream is closing before the complete and Ignore_Error is False,\n   --  The exception would be raised.\n\n   generic\n      with procedure Data_In\n        (Item : out Ada.Streams.Stream_Element_Array;\n         Last : out Ada.Streams.Stream_Element_Offset);\n      with procedure Data_Out\n        (Item : in Ada.Streams.Stream_Element_Array);\n   procedure Generic_Translate\n     (Filter          : in out Filter_Type;\n      In_Buffer_Size  : in     Integer := Default_Buffer_Size;\n      Out_Buffer_Size : in     Integer := Default_Buffer_Size);\n   --  Compress/decompress data fetch from Data_In routine and pass the result\n   --  to the Data_Out routine. User should provide Data_In and Data_Out\n   --  for compression/decompression data flow.\n   --  Compression or decompression depend on Filter initialization.\n\n   function Total_In (Filter : in Filter_Type) return Count;\n   pragma Inline (Total_In);\n   --  Returns total number of input bytes read so far\n\n   function Total_Out (Filter : in Filter_Type) return Count;\n   pragma Inline (Total_Out);\n   --  Returns total number of bytes output so far\n\n   function CRC32\n     (CRC    : in Unsigned_32;\n      Data   : in Ada.Streams.Stream_Element_Array)\n      return Unsigned_32;\n   pragma Inline (CRC32);\n   --  Compute CRC32, it could be necessary for make gzip format\n\n   procedure CRC32\n     (CRC  : in out Unsigned_32;\n      Data : in     Ada.Streams.Stream_Element_Array);\n   pragma Inline (CRC32);\n   --  Compute CRC32, it could be necessary for make gzip format\n\n   -------------------------------------------------\n   --  Below is more complex low level routines.  --\n   -------------------------------------------------\n\n   procedure Translate\n     (Filter    : in out Filter_Type;\n      In_Data   : in     Ada.Streams.Stream_Element_Array;\n      In_Last   :    out Ada.Streams.Stream_Element_Offset;\n      Out_Data  :    out Ada.Streams.Stream_Element_Array;\n      Out_Last  :    out Ada.Streams.Stream_Element_Offset;\n      Flush     : in     Flush_Mode);\n   --  Compress/decompress the In_Data buffer and place the result into\n   --  Out_Data. In_Last is the index of last element from In_Data accepted by\n   --  the Filter. Out_Last is the last element of the received data from\n   --  Filter. To tell the filter that incoming data are complete put the\n   --  Flush parameter to Finish.\n\n   function Stream_End (Filter : in Filter_Type) return Boolean;\n   pragma Inline (Stream_End);\n   --  Return the true when the stream is complete.\n\n   procedure Flush\n     (Filter    : in out Filter_Type;\n      Out_Data  :    out Ada.Streams.Stream_Element_Array;\n      Out_Last  :    out Ada.Streams.Stream_Element_Offset;\n      Flush     : in     Flush_Mode);\n   pragma Inline (Flush);\n   --  Flushing the data from the compressor.\n\n   generic\n      with procedure Write\n        (Item : in Ada.Streams.Stream_Element_Array);\n      --  User should provide this routine for accept\n      --  compressed/decompressed data.\n\n      Buffer_Size : in Ada.Streams.Stream_Element_Offset\n         := Default_Buffer_Size;\n      --  Buffer size for Write user routine.\n\n   procedure Write\n     (Filter  : in out Filter_Type;\n      Item    : in     Ada.Streams.Stream_Element_Array;\n      Flush   : in     Flush_Mode := No_Flush);\n   --  Compress/Decompress data from Item to the generic parameter procedure\n   --  Write. Output buffer size could be set in Buffer_Size generic parameter.\n\n   generic\n      with procedure Read\n        (Item : out Ada.Streams.Stream_Element_Array;\n         Last : out Ada.Streams.Stream_Element_Offset);\n      --  User should provide data for compression/decompression\n      --  thru this routine.\n\n      Buffer : in out Ada.Streams.Stream_Element_Array;\n      --  Buffer for keep remaining data from the previous\n      --  back read.\n\n      Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset;\n      --  Rest_First have to be initialized to Buffer'Last + 1\n      --  Rest_Last have to be initialized to Buffer'Last\n      --  before usage.\n\n      Allow_Read_Some : in Boolean := False;\n      --  Is it allowed to return Last < Item'Last before end of data.\n\n   procedure Read\n     (Filter : in out Filter_Type;\n      Item   :    out Ada.Streams.Stream_Element_Array;\n      Last   :    out Ada.Streams.Stream_Element_Offset;\n      Flush  : in     Flush_Mode := No_Flush);\n   --  Compress/Decompress data from generic parameter procedure Read to the\n   --  Item. User should provide Buffer and initialized Rest_First, Rest_Last\n   --  indicators. If Allow_Read_Some is True, Read routines could return\n   --  Last < Item'Last only at end of stream.\n\nprivate\n\n   use Ada.Streams;\n\n   pragma Assert (Ada.Streams.Stream_Element'Size    =    8);\n   pragma Assert (Ada.Streams.Stream_Element'Modulus = 2**8);\n\n   type Flush_Mode is new Integer range 0 .. 5;\n\n   type Compression_Method is new Integer range 8 .. 8;\n\n   type Strategy_Type is new Integer range 0 .. 3;\n\n   No_Flush      : constant Flush_Mode := 0;\n   Partial_Flush : constant Flush_Mode := 1;\n   Sync_Flush    : constant Flush_Mode := 2;\n   Full_Flush    : constant Flush_Mode := 3;\n   Finish        : constant Flush_Mode := 4;\n   Block_Flush   : constant Flush_Mode := 5;\n\n   Filtered         : constant Strategy_Type := 1;\n   Huffman_Only     : constant Strategy_Type := 2;\n   RLE              : constant Strategy_Type := 3;\n   Default_Strategy : constant Strategy_Type := 0;\n\n   Deflated : constant Compression_Method := 8;\n\n   type Z_Stream;\n\n   type Z_Stream_Access is access all Z_Stream;\n\n   type Filter_Type is tagged limited record\n      Strm        : Z_Stream_Access;\n      Compression : Boolean;\n      Stream_End  : Boolean;\n      Header      : Header_Type;\n      CRC         : Unsigned_32;\n      Offset      : Stream_Element_Offset;\n      --  Offset for gzip header/footer output.\n   end record;\n\nend ZLib;\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/ada/zlib.gpr",
    "content": "project Zlib is\n\n   for Languages use (\"Ada\");\n   for Source_Dirs use (\".\");\n   for Object_Dir use \".\";\n   for Main use (\"test.adb\", \"mtest.adb\", \"read.adb\", \"buffer_demo\");\n\n   package Compiler is\n      for Default_Switches (\"ada\") use (\"-gnatwcfilopru\", \"-gnatVcdfimorst\", \"-gnatyabcefhiklmnoprst\");\n   end Compiler;\n\n   package Linker is\n      for Default_Switches (\"ada\") use (\"-lz\");\n   end Linker;\n\n   package Builder is\n      for Default_Switches (\"ada\") use (\"-s\", \"-gnatQ\");\n   end Builder;\n\nend Zlib;\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/amd64/amd64-match.S",
    "content": "/*\n * match.S -- optimized version of longest_match()\n * based on the similar work by Gilles Vollant, and Brian Raiter, written 1998\n *\n * This is free software; you can redistribute it and/or modify it\n * under the terms of the BSD License. Use by owners of Che Guevarra\n * parafernalia is prohibited, where possible, and highly discouraged\n * elsewhere.\n */\n\n#ifndef NO_UNDERLINE\n#\tdefine\tmatch_init\t_match_init\n#\tdefine\tlongest_match\t_longest_match\n#endif\n\n#define\tscanend\t\tebx\n#define\tscanendw\tbx\n#define\tchainlenwmask\tedx /* high word: current chain len low word: s->wmask */\n#define\tcurmatch\trsi\n#define\tcurmatchd\tesi\n#define\twindowbestlen\tr8\n#define\tscanalign\tr9\n#define\tscanalignd\tr9d\n#define\twindow\t\tr10\n#define\tbestlen\t\tr11\n#define\tbestlend\tr11d\n#define\tscanstart\tr12d\n#define\tscanstartw\tr12w\n#define scan\t\tr13\n#define nicematch\tr14d\n#define\tlimit\t\tr15\n#define\tlimitd\t\tr15d\n#define prev\t\trcx\n\n/*\n * The 258 is a \"magic number, not a parameter -- changing it\n * breaks the hell loose\n */\n#define\tMAX_MATCH\t(258)\n#define\tMIN_MATCH\t(3)\n#define\tMIN_LOOKAHEAD\t(MAX_MATCH + MIN_MATCH + 1)\n#define\tMAX_MATCH_8\t((MAX_MATCH + 7) & ~7)\n\n/* stack frame offsets */\n#define\tLocalVarsSize\t(112)\n#define _chainlenwmask\t( 8-LocalVarsSize)(%rsp)\n#define _windowbestlen\t(16-LocalVarsSize)(%rsp)\n#define save_r14        (24-LocalVarsSize)(%rsp)\n#define save_rsi        (32-LocalVarsSize)(%rsp)\n#define save_rbx        (40-LocalVarsSize)(%rsp)\n#define save_r12        (56-LocalVarsSize)(%rsp)\n#define save_r13        (64-LocalVarsSize)(%rsp)\n#define save_r15        (80-LocalVarsSize)(%rsp)\n\n\n.globl\tmatch_init, longest_match\n\n/*\n * On AMD64 the first argument of a function (in our case -- the pointer to\n * deflate_state structure) is passed in %rdi, hence our offsets below are\n * all off of that.\n */\n\n/* you can check the structure offset by running\n\n#include <stdlib.h>\n#include <stdio.h>\n#include \"deflate.h\"\n\nvoid print_depl()\n{\ndeflate_state ds;\ndeflate_state *s=&ds;\nprintf(\"size pointer=%u\\n\",(int)sizeof(void*));\n\nprintf(\"#define dsWSize         (%3u)(%%rdi)\\n\",(int)(((char*)&(s->w_size))-((char*)s)));\nprintf(\"#define dsWMask         (%3u)(%%rdi)\\n\",(int)(((char*)&(s->w_mask))-((char*)s)));\nprintf(\"#define dsWindow        (%3u)(%%rdi)\\n\",(int)(((char*)&(s->window))-((char*)s)));\nprintf(\"#define dsPrev          (%3u)(%%rdi)\\n\",(int)(((char*)&(s->prev))-((char*)s)));\nprintf(\"#define dsMatchLen      (%3u)(%%rdi)\\n\",(int)(((char*)&(s->match_length))-((char*)s)));\nprintf(\"#define dsPrevMatch     (%3u)(%%rdi)\\n\",(int)(((char*)&(s->prev_match))-((char*)s)));\nprintf(\"#define dsStrStart      (%3u)(%%rdi)\\n\",(int)(((char*)&(s->strstart))-((char*)s)));\nprintf(\"#define dsMatchStart    (%3u)(%%rdi)\\n\",(int)(((char*)&(s->match_start))-((char*)s)));\nprintf(\"#define dsLookahead     (%3u)(%%rdi)\\n\",(int)(((char*)&(s->lookahead))-((char*)s)));\nprintf(\"#define dsPrevLen       (%3u)(%%rdi)\\n\",(int)(((char*)&(s->prev_length))-((char*)s)));\nprintf(\"#define dsMaxChainLen   (%3u)(%%rdi)\\n\",(int)(((char*)&(s->max_chain_length))-((char*)s)));\nprintf(\"#define dsGoodMatch     (%3u)(%%rdi)\\n\",(int)(((char*)&(s->good_match))-((char*)s)));\nprintf(\"#define dsNiceMatch     (%3u)(%%rdi)\\n\",(int)(((char*)&(s->nice_match))-((char*)s)));\n}\n\n*/\n\n\n/*\n  to compile for XCode 3.2 on MacOSX x86_64\n  - run \"gcc -g -c -DXCODE_MAC_X64_STRUCTURE amd64-match.S\"\n */\n\n\n#ifndef CURRENT_LINX_XCODE_MAC_X64_STRUCTURE\n#define dsWSize\t\t( 68)(%rdi)\n#define dsWMask\t\t( 76)(%rdi)\n#define dsWindow\t( 80)(%rdi)\n#define dsPrev\t\t( 96)(%rdi)\n#define dsMatchLen\t(144)(%rdi)\n#define dsPrevMatch\t(148)(%rdi)\n#define dsStrStart\t(156)(%rdi)\n#define dsMatchStart\t(160)(%rdi)\n#define dsLookahead\t(164)(%rdi)\n#define dsPrevLen\t(168)(%rdi)\n#define dsMaxChainLen\t(172)(%rdi)\n#define dsGoodMatch\t(188)(%rdi)\n#define dsNiceMatch\t(192)(%rdi)\n\n#else \n\n#ifndef STRUCT_OFFSET\n#\tdefine STRUCT_OFFSET\t(0)\n#endif\n\n\n#define dsWSize\t\t( 56 + STRUCT_OFFSET)(%rdi)\n#define dsWMask\t\t( 64 + STRUCT_OFFSET)(%rdi)\n#define dsWindow\t( 72 + STRUCT_OFFSET)(%rdi)\n#define dsPrev\t\t( 88 + STRUCT_OFFSET)(%rdi)\n#define dsMatchLen\t(136 + STRUCT_OFFSET)(%rdi)\n#define dsPrevMatch\t(140 + STRUCT_OFFSET)(%rdi)\n#define dsStrStart\t(148 + STRUCT_OFFSET)(%rdi)\n#define dsMatchStart\t(152 + STRUCT_OFFSET)(%rdi)\n#define dsLookahead\t(156 + STRUCT_OFFSET)(%rdi)\n#define dsPrevLen\t(160 + STRUCT_OFFSET)(%rdi)\n#define dsMaxChainLen\t(164 + STRUCT_OFFSET)(%rdi)\n#define dsGoodMatch\t(180 + STRUCT_OFFSET)(%rdi)\n#define dsNiceMatch\t(184 + STRUCT_OFFSET)(%rdi)\n\n#endif\n\n\n\n\n.text\n\n/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */\n\nlongest_match:\n/*\n * Retrieve the function arguments. %curmatch will hold cur_match\n * throughout the entire function (passed via rsi on amd64).\n * rdi will hold the pointer to the deflate_state (first arg on amd64)\n */\n\t\tmov     %rsi, save_rsi\n\t\tmov     %rbx, save_rbx\n\t\tmov\t%r12, save_r12\n\t\tmov     %r13, save_r13\n\t\tmov     %r14, save_r14\n\t\tmov     %r15, save_r15\n\n/* uInt wmask = s->w_mask;\t\t\t\t\t\t*/\n/* unsigned chain_length = s->max_chain_length;\t\t\t\t*/\n/* if (s->prev_length >= s->good_match) {\t\t\t\t*/\n/*     chain_length >>= 2;\t\t\t\t\t\t*/\n/* }\t\t\t\t\t\t\t\t\t*/\n\n\t\tmovl\tdsPrevLen, %eax\n\t\tmovl\tdsGoodMatch, %ebx\n\t\tcmpl\t%ebx, %eax\n\t\tmovl\tdsWMask, %eax\n\t\tmovl\tdsMaxChainLen, %chainlenwmask\n\t\tjl\tLastMatchGood\n\t\tshrl\t$2, %chainlenwmask\nLastMatchGood:\n\n/* chainlen is decremented once beforehand so that the function can\t*/\n/* use the sign flag instead of the zero flag for the exit test.\t*/\n/* It is then shifted into the high word, to make room for the wmask\t*/\n/* value, which it will always accompany.\t\t\t\t*/\n\n\t\tdecl\t%chainlenwmask\n\t\tshll\t$16, %chainlenwmask\n\t\torl\t%eax, %chainlenwmask\n\n/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;\t*/\n\n\t\tmovl\tdsNiceMatch, %eax\n\t\tmovl\tdsLookahead, %ebx\n\t\tcmpl\t%eax, %ebx\n\t\tjl\tLookaheadLess\n\t\tmovl\t%eax, %ebx\nLookaheadLess:\tmovl\t%ebx, %nicematch\n\n/* register Bytef *scan = s->window + s->strstart;\t\t\t*/\n\n\t\tmov\tdsWindow, %window\n\t\tmovl\tdsStrStart, %limitd\n\t\tlea\t(%limit, %window), %scan\n\n/* Determine how many bytes the scan ptr is off from being\t\t*/\n/* dword-aligned.\t\t\t\t\t\t\t*/\n\n\t\tmov\t%scan, %scanalign\n\t\tnegl\t%scanalignd\n\t\tandl\t$3, %scanalignd\n\n/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?\t\t\t*/\n/*     s->strstart - (IPos)MAX_DIST(s) : NIL;\t\t\t\t*/\n\n\t\tmovl\tdsWSize, %eax\n\t\tsubl\t$MIN_LOOKAHEAD, %eax\n\t\txorl\t%ecx, %ecx\n\t\tsubl\t%eax, %limitd\n\t\tcmovng\t%ecx, %limitd\n\n/* int best_len = s->prev_length;\t\t\t\t\t*/\n\n\t\tmovl\tdsPrevLen, %bestlend\n\n/* Store the sum of s->window + best_len in %windowbestlen locally, and in memory.\t*/\n\n\t\tlea\t(%window, %bestlen), %windowbestlen\n\t\tmov\t%windowbestlen, _windowbestlen\n\n/* register ush scan_start = *(ushf*)scan;\t\t\t\t*/\n/* register ush scan_end   = *(ushf*)(scan+best_len-1);\t\t\t*/\n/* Posf *prev = s->prev;\t\t\t\t\t\t*/\n\n\t\tmovzwl\t(%scan), %scanstart\n\t\tmovzwl\t-1(%scan, %bestlen), %scanend\n\t\tmov\tdsPrev, %prev\n\n/* Jump into the main loop.\t\t\t\t\t\t*/\n\n\t\tmovl\t%chainlenwmask, _chainlenwmask\n\t\tjmp\tLoopEntry\n\n.balign 16\n\n/* do {\n *     match = s->window + cur_match;\n *     if (*(ushf*)(match+best_len-1) != scan_end ||\n *         *(ushf*)match != scan_start) continue;\n *     [...]\n * } while ((cur_match = prev[cur_match & wmask]) > limit\n *          && --chain_length != 0);\n *\n * Here is the inner loop of the function. The function will spend the\n * majority of its time in this loop, and majority of that time will\n * be spent in the first ten instructions.\n */\nLookupLoop:\n\t\tandl\t%chainlenwmask, %curmatchd\n\t\tmovzwl\t(%prev, %curmatch, 2), %curmatchd\n\t\tcmpl\t%limitd, %curmatchd\n\t\tjbe\tLeaveNow\n\t\tsubl\t$0x00010000, %chainlenwmask\n\t\tjs\tLeaveNow\nLoopEntry:\tcmpw\t-1(%windowbestlen, %curmatch), %scanendw\n\t\tjne\tLookupLoop\n\t\tcmpw\t%scanstartw, (%window, %curmatch)\n\t\tjne\tLookupLoop\n\n/* Store the current value of chainlen.\t\t\t\t\t*/\n\t\tmovl\t%chainlenwmask, _chainlenwmask\n\n/* %scan is the string under scrutiny, and %prev to the string we\t*/\n/* are hoping to match it up with. In actuality, %esi and %edi are\t*/\n/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is\t*/\n/* initialized to -(MAX_MATCH_8 - scanalign).\t\t\t\t*/\n\n\t\tmov\t$(-MAX_MATCH_8), %rdx\n\t\tlea\t(%curmatch, %window), %windowbestlen\n\t\tlea\tMAX_MATCH_8(%windowbestlen, %scanalign), %windowbestlen\n\t\tlea\tMAX_MATCH_8(%scan, %scanalign), %prev\n\n/* the prefetching below makes very little difference... */\n\t\tprefetcht1\t(%windowbestlen, %rdx)\n\t\tprefetcht1\t(%prev, %rdx)\n\n/*\n * Test the strings for equality, 8 bytes at a time. At the end,\n * adjust %rdx so that it is offset to the exact byte that mismatched.\n *\n * It should be confessed that this loop usually does not represent\n * much of the total running time. Replacing it with a more\n * straightforward \"rep cmpsb\" would not drastically degrade\n * performance -- unrolling it, for example, makes no difference.\n */\n\n#undef USE_SSE\t/* works, but is 6-7% slower, than non-SSE... */\n\nLoopCmps:\n#ifdef USE_SSE\n\t\t/* Preload the SSE registers */\n\t\tmovdqu\t  (%windowbestlen, %rdx), %xmm1\n\t\tmovdqu\t  (%prev, %rdx), %xmm2\n\t\tpcmpeqb\t%xmm2, %xmm1\n\t\tmovdqu\t16(%windowbestlen, %rdx), %xmm3\n\t\tmovdqu\t16(%prev, %rdx), %xmm4\n\t\tpcmpeqb\t%xmm4, %xmm3\n\t\tmovdqu\t32(%windowbestlen, %rdx), %xmm5\n\t\tmovdqu\t32(%prev, %rdx), %xmm6\n\t\tpcmpeqb\t%xmm6, %xmm5\n\t\tmovdqu\t48(%windowbestlen, %rdx), %xmm7\n\t\tmovdqu\t48(%prev, %rdx), %xmm8\n\t\tpcmpeqb\t%xmm8, %xmm7\n\n\t\t/* Check the comparisions' results */\n\t\tpmovmskb %xmm1, %rax\n\t\tnotw\t%ax\n\t\tbsfw\t%ax, %ax\n\t\tjnz\tLeaveLoopCmps\n\t\t\n\t\t/* this is the only iteration of the loop with a possibility of having\n\t\t   incremented rdx by 0x108 (each loop iteration add 16*4 = 0x40 \n\t\t   and (0x40*4)+8=0x108 */\n\t\tadd\t$8, %rdx\n\t\tjz LenMaximum\n\t\tadd\t$8, %rdx\n\n\t\t\n\t\tpmovmskb %xmm3, %rax\n\t\tnotw\t%ax\n\t\tbsfw\t%ax, %ax\n\t\tjnz\tLeaveLoopCmps\n\t\t\n\t\t\n\t\tadd\t$16, %rdx\n\n\n\t\tpmovmskb %xmm5, %rax\n\t\tnotw\t%ax\n\t\tbsfw\t%ax, %ax\n\t\tjnz\tLeaveLoopCmps\n\t\t\n\t\tadd\t$16, %rdx\n\n\n\t\tpmovmskb %xmm7, %rax\n\t\tnotw\t%ax\n\t\tbsfw\t%ax, %ax\n\t\tjnz\tLeaveLoopCmps\n\t\t\n\t\tadd\t$16, %rdx\n\t\t\n\t\tjmp\tLoopCmps\nLeaveLoopCmps:\tadd\t%rax, %rdx\n#else\n\t\tmov\t(%windowbestlen, %rdx), %rax\n\t\txor\t(%prev, %rdx), %rax\n\t\tjnz\tLeaveLoopCmps\n\t\t\n\t\tmov\t8(%windowbestlen, %rdx), %rax\n\t\txor\t8(%prev, %rdx), %rax\n\t\tjnz\tLeaveLoopCmps8\n\n\t\tmov\t16(%windowbestlen, %rdx), %rax\n\t\txor\t16(%prev, %rdx), %rax\n\t\tjnz\tLeaveLoopCmps16\n\t\t\t\t\n\t\tadd\t$24, %rdx\n\t\tjnz\tLoopCmps\n\t\tjmp\tLenMaximum\n#\tif 0\n/*\n * This three-liner is tantalizingly simple, but bsf is a slow instruction,\n * and the complicated alternative down below is quite a bit faster. Sad...\n */\n\nLeaveLoopCmps:\tbsf\t%rax, %rax /* find the first non-zero bit */\n\t\tshrl\t$3, %eax /* divide by 8 to get the byte */\n\t\tadd\t%rax, %rdx\n#\telse\nLeaveLoopCmps16:\n\t\tadd\t$8, %rdx\nLeaveLoopCmps8:\n\t\tadd\t$8, %rdx\nLeaveLoopCmps:\ttestl   $0xFFFFFFFF, %eax /* Check the first 4 bytes */\n\t\tjnz     Check16\n\t\tadd     $4, %rdx\n\t\tshr     $32, %rax\nCheck16:        testw   $0xFFFF, %ax\n\t\tjnz     LenLower\n\t\tadd\t$2, %rdx\n\t\tshrl\t$16, %eax\nLenLower:\tsubb\t$1, %al\n\t\tadc\t$0, %rdx\n#\tendif\n#endif\n\n/* Calculate the length of the match. If it is longer than MAX_MATCH,\t*/\n/* then automatically accept it as the best possible match and leave.\t*/\n\n\t\tlea\t(%prev, %rdx), %rax\n\t\tsub\t%scan, %rax\n\t\tcmpl\t$MAX_MATCH, %eax\n\t\tjge\tLenMaximum\n\n/* If the length of the match is not longer than the best match we\t*/\n/* have so far, then forget it and return to the lookup loop.\t\t*/\n\n\t\tcmpl\t%bestlend, %eax\n\t\tjg\tLongerMatch\n\t\tmov\t_windowbestlen, %windowbestlen\n\t\tmov\tdsPrev, %prev\n\t\tmovl\t_chainlenwmask, %edx\n\t\tjmp\tLookupLoop\n\n/*         s->match_start = cur_match;\t\t\t\t\t*/\n/*         best_len = len;\t\t\t\t\t\t*/\n/*         if (len >= nice_match) break;\t\t\t\t*/\n/*         scan_end = *(ushf*)(scan+best_len-1);\t\t\t*/\n\nLongerMatch:\n\t\tmovl\t%eax, %bestlend\n\t\tmovl\t%curmatchd, dsMatchStart\n\t\tcmpl\t%nicematch, %eax\n\t\tjge\tLeaveNow\n\n\t\tlea\t(%window, %bestlen), %windowbestlen\n\t\tmov\t%windowbestlen, _windowbestlen\n\n\t\tmovzwl\t-1(%scan, %rax), %scanend\n\t\tmov\tdsPrev, %prev\n\t\tmovl\t_chainlenwmask, %chainlenwmask\n\t\tjmp\tLookupLoop\n\n/* Accept the current string, with the maximum possible length.\t\t*/\n\nLenMaximum:\n\t\tmovl\t$MAX_MATCH, %bestlend\n\t\tmovl\t%curmatchd, dsMatchStart\n\n/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;\t\t*/\n/* return s->lookahead;\t\t\t\t\t\t\t*/\n\nLeaveNow:\n\t\tmovl\tdsLookahead, %eax\n\t\tcmpl\t%eax, %bestlend\n\t\tcmovngl\t%bestlend, %eax\nLookaheadRet:\n\n/* Restore the registers and return from whence we came.\t\t\t*/\n\n\tmov\tsave_rsi, %rsi\n\tmov\tsave_rbx, %rbx\n\tmov\tsave_r12, %r12\n\tmov\tsave_r13, %r13\n\tmov\tsave_r14, %r14\n\tmov\tsave_r15, %r15\n\n\tret\n\nmatch_init:\tret\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/asm686/README.686",
    "content": "This is a patched version of zlib, modified to use\nPentium-Pro-optimized assembly code in the deflation algorithm. The\nfiles changed/added by this patch are:\n\nREADME.686\nmatch.S\n\nThe speedup that this patch provides varies, depending on whether the\ncompiler used to build the original version of zlib falls afoul of the\nPPro's speed traps. My own tests show a speedup of around 10-20% at\nthe default compression level, and 20-30% using -9, against a version\ncompiled using gcc 2.7.2.3. Your mileage may vary.\n\nNote that this code has been tailored for the PPro/PII in particular,\nand will not perform particuarly well on a Pentium.\n\nIf you are using an assembler other than GNU as, you will have to\ntranslate match.S to use your assembler's syntax. (Have fun.)\n\nBrian Raiter\nbreadbox@muppetlabs.com\nApril, 1998\n\n\nAdded for zlib 1.1.3:\n\nThe patches come from\nhttp://www.muppetlabs.com/~breadbox/software/assembly.html\n\nTo compile zlib with this asm file, copy match.S to the zlib directory\nthen do:\n\nCFLAGS=\"-O3 -DASMV\" ./configure\nmake OBJA=match.o\n\n\nUpdate:\n\nI've been ignoring these assembly routines for years, believing that\ngcc's generated code had caught up with it sometime around gcc 2.95\nand the major rearchitecting of the Pentium 4. However, I recently\nlearned that, despite what I believed, this code still has some life\nin it. On the Pentium 4 and AMD64 chips, it continues to run about 8%\nfaster than the code produced by gcc 4.1.\n\nIn acknowledgement of its continuing usefulness, I've altered the\nlicense to match that of the rest of zlib. Share and Enjoy!\n\nBrian Raiter\nbreadbox@muppetlabs.com\nApril, 2007\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/asm686/match.S",
    "content": "/* match.S -- x86 assembly version of the zlib longest_match() function.\n * Optimized for the Intel 686 chips (PPro and later).\n *\n * Copyright (C) 1998, 2007 Brian Raiter <breadbox@muppetlabs.com>\n *\n * This software is provided 'as-is', without any express or implied\n * warranty.  In no event will the author be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would be\n *    appreciated but is not required.\n * 2. Altered source versions must be plainly marked as such, and must not be\n *    misrepresented as being the original software.\n * 3. This notice may not be removed or altered from any source distribution.\n */\n\n#ifndef NO_UNDERLINE\n#define\tmatch_init\t_match_init\n#define\tlongest_match\t_longest_match\n#endif\n\n#define\tMAX_MATCH\t(258)\n#define\tMIN_MATCH\t(3)\n#define\tMIN_LOOKAHEAD\t(MAX_MATCH + MIN_MATCH + 1)\n#define\tMAX_MATCH_8\t((MAX_MATCH + 7) & ~7)\n\n/* stack frame offsets */\n\n#define\tchainlenwmask\t\t0\t/* high word: current chain len\t*/\n\t\t\t\t\t/* low word: s->wmask\t\t*/\n#define\twindow\t\t\t4\t/* local copy of s->window\t*/\n#define\twindowbestlen\t\t8\t/* s->window + bestlen\t\t*/\n#define\tscanstart\t\t16\t/* first two bytes of string\t*/\n#define\tscanend\t\t\t12\t/* last two bytes of string\t*/\n#define\tscanalign\t\t20\t/* dword-misalignment of string\t*/\n#define\tnicematch\t\t24\t/* a good enough match size\t*/\n#define\tbestlen\t\t\t28\t/* size of best match so far\t*/\n#define\tscan\t\t\t32\t/* ptr to string wanting match\t*/\n\n#define\tLocalVarsSize\t\t(36)\n/*\tsaved ebx\t\t36 */\n/*\tsaved edi\t\t40 */\n/*\tsaved esi\t\t44 */\n/*\tsaved ebp\t\t48 */\n/*\treturn address\t\t52 */\n#define\tdeflatestate\t\t56\t/* the function arguments\t*/\n#define\tcurmatch\t\t60\n\n/* All the +zlib1222add offsets are due to the addition of fields\n *  in zlib in the deflate_state structure since the asm code was first written\n * (if you compile with zlib 1.0.4 or older, use \"zlib1222add equ (-4)\").\n * (if you compile with zlib between 1.0.5 and 1.2.2.1, use \"zlib1222add equ 0\").\n * if you compile with zlib 1.2.2.2 or later , use \"zlib1222add equ 8\").\n */\n\n#define zlib1222add\t\t(8)\n\n#define\tdsWSize\t\t\t(36+zlib1222add)\n#define\tdsWMask\t\t\t(44+zlib1222add)\n#define\tdsWindow\t\t(48+zlib1222add)\n#define\tdsPrev\t\t\t(56+zlib1222add)\n#define\tdsMatchLen\t\t(88+zlib1222add)\n#define\tdsPrevMatch\t\t(92+zlib1222add)\n#define\tdsStrStart\t\t(100+zlib1222add)\n#define\tdsMatchStart\t\t(104+zlib1222add)\n#define\tdsLookahead\t\t(108+zlib1222add)\n#define\tdsPrevLen\t\t(112+zlib1222add)\n#define\tdsMaxChainLen\t\t(116+zlib1222add)\n#define\tdsGoodMatch\t\t(132+zlib1222add)\n#define\tdsNiceMatch\t\t(136+zlib1222add)\n\n\n.file \"match.S\"\n\n.globl\tmatch_init, longest_match\n\n.text\n\n/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */\n.cfi_sections\t.debug_frame\n\nlongest_match:\n\n.cfi_startproc\n/* Save registers that the compiler may be using, and adjust %esp to\t*/\n/* make room for our stack frame.\t\t\t\t\t*/\n\n\t\tpushl\t%ebp\n\t\t.cfi_def_cfa_offset 8\n\t\t.cfi_offset ebp, -8\n\t\tpushl\t%edi\n\t\t.cfi_def_cfa_offset 12\n\t\tpushl\t%esi\n\t\t.cfi_def_cfa_offset 16\n\t\tpushl\t%ebx\n\t\t.cfi_def_cfa_offset 20\n\t\tsubl\t$LocalVarsSize, %esp\n\t\t.cfi_def_cfa_offset LocalVarsSize+20\n\n/* Retrieve the function arguments. %ecx will hold cur_match\t\t*/\n/* throughout the entire function. %edx will hold the pointer to the\t*/\n/* deflate_state structure during the function's setup (before\t\t*/\n/* entering the main loop).\t\t\t\t\t\t*/\n\n\t\tmovl\tdeflatestate(%esp), %edx\n\t\tmovl\tcurmatch(%esp), %ecx\n\n/* uInt wmask = s->w_mask;\t\t\t\t\t\t*/\n/* unsigned chain_length = s->max_chain_length;\t\t\t\t*/\n/* if (s->prev_length >= s->good_match) {\t\t\t\t*/\n/*     chain_length >>= 2;\t\t\t\t\t\t*/\n/* }\t\t\t\t\t\t\t\t\t*/\n \n\t\tmovl\tdsPrevLen(%edx), %eax\n\t\tmovl\tdsGoodMatch(%edx), %ebx\n\t\tcmpl\t%ebx, %eax\n\t\tmovl\tdsWMask(%edx), %eax\n\t\tmovl\tdsMaxChainLen(%edx), %ebx\n\t\tjl\tLastMatchGood\n\t\tshrl\t$2, %ebx\nLastMatchGood:\n\n/* chainlen is decremented once beforehand so that the function can\t*/\n/* use the sign flag instead of the zero flag for the exit test.\t*/\n/* It is then shifted into the high word, to make room for the wmask\t*/\n/* value, which it will always accompany.\t\t\t\t*/\n\n\t\tdecl\t%ebx\n\t\tshll\t$16, %ebx\n\t\torl\t%eax, %ebx\n\t\tmovl\t%ebx, chainlenwmask(%esp)\n\n/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;\t*/\n\n\t\tmovl\tdsNiceMatch(%edx), %eax\n\t\tmovl\tdsLookahead(%edx), %ebx\n\t\tcmpl\t%eax, %ebx\n\t\tjl\tLookaheadLess\n\t\tmovl\t%eax, %ebx\nLookaheadLess:\tmovl\t%ebx, nicematch(%esp)\n\n/* register Bytef *scan = s->window + s->strstart;\t\t\t*/\n\n\t\tmovl\tdsWindow(%edx), %esi\n\t\tmovl\t%esi, window(%esp)\n\t\tmovl\tdsStrStart(%edx), %ebp\n\t\tlea\t(%esi,%ebp), %edi\n\t\tmovl\t%edi, scan(%esp)\n\n/* Determine how many bytes the scan ptr is off from being\t\t*/\n/* dword-aligned.\t\t\t\t\t\t\t*/\n\n\t\tmovl\t%edi, %eax\n\t\tnegl\t%eax\n\t\tandl\t$3, %eax\n\t\tmovl\t%eax, scanalign(%esp)\n\n/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?\t\t\t*/\n/*     s->strstart - (IPos)MAX_DIST(s) : NIL;\t\t\t\t*/\n\n\t\tmovl\tdsWSize(%edx), %eax\n\t\tsubl\t$MIN_LOOKAHEAD, %eax\n\t\tsubl\t%eax, %ebp\n\t\tjg\tLimitPositive\n\t\txorl\t%ebp, %ebp\nLimitPositive:\n\n/* int best_len = s->prev_length;\t\t\t\t\t*/\n\n\t\tmovl\tdsPrevLen(%edx), %eax\n\t\tmovl\t%eax, bestlen(%esp)\n\n/* Store the sum of s->window + best_len in %esi locally, and in %esi.\t*/\n\n\t\taddl\t%eax, %esi\n\t\tmovl\t%esi, windowbestlen(%esp)\n\n/* register ush scan_start = *(ushf*)scan;\t\t\t\t*/\n/* register ush scan_end   = *(ushf*)(scan+best_len-1);\t\t\t*/\n/* Posf *prev = s->prev;\t\t\t\t\t\t*/\n\n\t\tmovzwl\t(%edi), %ebx\n\t\tmovl\t%ebx, scanstart(%esp)\n\t\tmovzwl\t-1(%edi,%eax), %ebx\n\t\tmovl\t%ebx, scanend(%esp)\n\t\tmovl\tdsPrev(%edx), %edi\n\n/* Jump into the main loop.\t\t\t\t\t\t*/\n\n\t\tmovl\tchainlenwmask(%esp), %edx\n\t\tjmp\tLoopEntry\n\n.balign 16\n\n/* do {\n *     match = s->window + cur_match;\n *     if (*(ushf*)(match+best_len-1) != scan_end ||\n *         *(ushf*)match != scan_start) continue;\n *     [...]\n * } while ((cur_match = prev[cur_match & wmask]) > limit\n *          && --chain_length != 0);\n *\n * Here is the inner loop of the function. The function will spend the\n * majority of its time in this loop, and majority of that time will\n * be spent in the first ten instructions.\n *\n * Within this loop:\n * %ebx = scanend\n * %ecx = curmatch\n * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)\n * %esi = windowbestlen - i.e., (window + bestlen)\n * %edi = prev\n * %ebp = limit\n */\nLookupLoop:\n\t\tandl\t%edx, %ecx\n\t\tmovzwl\t(%edi,%ecx,2), %ecx\n\t\tcmpl\t%ebp, %ecx\n\t\tjbe\tLeaveNow\n\t\tsubl\t$0x00010000, %edx\n\t\tjs\tLeaveNow\nLoopEntry:\tmovzwl\t-1(%esi,%ecx), %eax\n\t\tcmpl\t%ebx, %eax\n\t\tjnz\tLookupLoop\n\t\tmovl\twindow(%esp), %eax\n\t\tmovzwl\t(%eax,%ecx), %eax\n\t\tcmpl\tscanstart(%esp), %eax\n\t\tjnz\tLookupLoop\n\n/* Store the current value of chainlen.\t\t\t\t\t*/\n\n\t\tmovl\t%edx, chainlenwmask(%esp)\n\n/* Point %edi to the string under scrutiny, and %esi to the string we\t*/\n/* are hoping to match it up with. In actuality, %esi and %edi are\t*/\n/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is\t*/\n/* initialized to -(MAX_MATCH_8 - scanalign).\t\t\t\t*/\n\n\t\tmovl\twindow(%esp), %esi\n\t\tmovl\tscan(%esp), %edi\n\t\taddl\t%ecx, %esi\n\t\tmovl\tscanalign(%esp), %eax\n\t\tmovl\t$(-MAX_MATCH_8), %edx\n\t\tlea\tMAX_MATCH_8(%edi,%eax), %edi\n\t\tlea\tMAX_MATCH_8(%esi,%eax), %esi\n\n/* Test the strings for equality, 8 bytes at a time. At the end,\n * adjust %edx so that it is offset to the exact byte that mismatched.\n *\n * We already know at this point that the first three bytes of the\n * strings match each other, and they can be safely passed over before\n * starting the compare loop. So what this code does is skip over 0-3\n * bytes, as much as necessary in order to dword-align the %edi\n * pointer. (%esi will still be misaligned three times out of four.)\n *\n * It should be confessed that this loop usually does not represent\n * much of the total running time. Replacing it with a more\n * straightforward \"rep cmpsb\" would not drastically degrade\n * performance.\n */\nLoopCmps:\n\t\tmovl\t(%esi,%edx), %eax\n\t\txorl\t(%edi,%edx), %eax\n\t\tjnz\tLeaveLoopCmps\n\t\tmovl\t4(%esi,%edx), %eax\n\t\txorl\t4(%edi,%edx), %eax\n\t\tjnz\tLeaveLoopCmps4\n\t\taddl\t$8, %edx\n\t\tjnz\tLoopCmps\n\t\tjmp\tLenMaximum\nLeaveLoopCmps4:\taddl\t$4, %edx\nLeaveLoopCmps:\ttestl\t$0x0000FFFF, %eax\n\t\tjnz\tLenLower\n\t\taddl\t$2, %edx\n\t\tshrl\t$16, %eax\nLenLower:\tsubb\t$1, %al\n\t\tadcl\t$0, %edx\n\n/* Calculate the length of the match. If it is longer than MAX_MATCH,\t*/\n/* then automatically accept it as the best possible match and leave.\t*/\n\n\t\tlea\t(%edi,%edx), %eax\n\t\tmovl\tscan(%esp), %edi\n\t\tsubl\t%edi, %eax\n\t\tcmpl\t$MAX_MATCH, %eax\n\t\tjge\tLenMaximum\n\n/* If the length of the match is not longer than the best match we\t*/\n/* have so far, then forget it and return to the lookup loop.\t\t*/\n\n\t\tmovl\tdeflatestate(%esp), %edx\n\t\tmovl\tbestlen(%esp), %ebx\n\t\tcmpl\t%ebx, %eax\n\t\tjg\tLongerMatch\n\t\tmovl\twindowbestlen(%esp), %esi\n\t\tmovl\tdsPrev(%edx), %edi\n\t\tmovl\tscanend(%esp), %ebx\n\t\tmovl\tchainlenwmask(%esp), %edx\n\t\tjmp\tLookupLoop\n\n/*         s->match_start = cur_match;\t\t\t\t\t*/\n/*         best_len = len;\t\t\t\t\t\t*/\n/*         if (len >= nice_match) break;\t\t\t\t*/\n/*         scan_end = *(ushf*)(scan+best_len-1);\t\t\t*/\n\nLongerMatch:\tmovl\tnicematch(%esp), %ebx\n\t\tmovl\t%eax, bestlen(%esp)\n\t\tmovl\t%ecx, dsMatchStart(%edx)\n\t\tcmpl\t%ebx, %eax\n\t\tjge\tLeaveNow\n\t\tmovl\twindow(%esp), %esi\n\t\taddl\t%eax, %esi\n\t\tmovl\t%esi, windowbestlen(%esp)\n\t\tmovzwl\t-1(%edi,%eax), %ebx\n\t\tmovl\tdsPrev(%edx), %edi\n\t\tmovl\t%ebx, scanend(%esp)\n\t\tmovl\tchainlenwmask(%esp), %edx\n\t\tjmp\tLookupLoop\n\n/* Accept the current string, with the maximum possible length.\t\t*/\n\nLenMaximum:\tmovl\tdeflatestate(%esp), %edx\n\t\tmovl\t$MAX_MATCH, bestlen(%esp)\n\t\tmovl\t%ecx, dsMatchStart(%edx)\n\n/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;\t\t*/\n/* return s->lookahead;\t\t\t\t\t\t\t*/\n\nLeaveNow:\n\t\tmovl\tdeflatestate(%esp), %edx\n\t\tmovl\tbestlen(%esp), %ebx\n\t\tmovl\tdsLookahead(%edx), %eax\n\t\tcmpl\t%eax, %ebx\n\t\tjg\tLookaheadRet\n\t\tmovl\t%ebx, %eax\nLookaheadRet:\n\n/* Restore the stack and return from whence we came.\t\t\t*/\n\n\t\taddl\t$LocalVarsSize, %esp\n\t\t.cfi_def_cfa_offset 20\n\t\tpopl\t%ebx\n\t\t.cfi_def_cfa_offset 16\n\t\tpopl\t%esi\n\t\t.cfi_def_cfa_offset 12\n\t\tpopl\t%edi\n\t\t.cfi_def_cfa_offset 8\n\t\tpopl\t%ebp\n\t\t.cfi_def_cfa_offset 4\n.cfi_endproc\nmatch_init:\tret\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/blast/Makefile",
    "content": "blast: blast.c blast.h\n\tcc -DTEST -o blast blast.c\n\ntest: blast\n\tblast < test.pk | cmp - test.txt\n\nclean:\n\trm -f blast blast.o\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/blast/README",
    "content": "Read blast.h for purpose and usage.\n\nMark Adler\nmadler@alumni.caltech.edu\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/blast/blast.c",
    "content": "/* blast.c\n * Copyright (C) 2003, 2012 Mark Adler\n * For conditions of distribution and use, see copyright notice in blast.h\n * version 1.2, 24 Oct 2012\n *\n * blast.c decompresses data compressed by the PKWare Compression Library.\n * This function provides functionality similar to the explode() function of\n * the PKWare library, hence the name \"blast\".\n *\n * This decompressor is based on the excellent format description provided by\n * Ben Rudiak-Gould in comp.compression on August 13, 2001.  Interestingly, the\n * example Ben provided in the post is incorrect.  The distance 110001 should\n * instead be 111000.  When corrected, the example byte stream becomes:\n *\n *    00 04 82 24 25 8f 80 7f\n *\n * which decompresses to \"AIAIAIAIAIAIA\" (without the quotes).\n */\n\n/*\n * Change history:\n *\n * 1.0  12 Feb 2003     - First version\n * 1.1  16 Feb 2003     - Fixed distance check for > 4 GB uncompressed data\n * 1.2  24 Oct 2012     - Add note about using binary mode in stdio\n *                      - Fix comparisons of differently signed integers\n */\n\n#include <setjmp.h>             /* for setjmp(), longjmp(), and jmp_buf */\n#include \"blast.h\"              /* prototype for blast() */\n\n#define local static            /* for local function definitions */\n#define MAXBITS 13              /* maximum code length */\n#define MAXWIN 4096             /* maximum window size */\n\n/* input and output state */\nstruct state {\n    /* input state */\n    blast_in infun;             /* input function provided by user */\n    void *inhow;                /* opaque information passed to infun() */\n    unsigned char *in;          /* next input location */\n    unsigned left;              /* available input at in */\n    int bitbuf;                 /* bit buffer */\n    int bitcnt;                 /* number of bits in bit buffer */\n\n    /* input limit error return state for bits() and decode() */\n    jmp_buf env;\n\n    /* output state */\n    blast_out outfun;           /* output function provided by user */\n    void *outhow;               /* opaque information passed to outfun() */\n    unsigned next;              /* index of next write location in out[] */\n    int first;                  /* true to check distances (for first 4K) */\n    unsigned char out[MAXWIN];  /* output buffer and sliding window */\n};\n\n/*\n * Return need bits from the input stream.  This always leaves less than\n * eight bits in the buffer.  bits() works properly for need == 0.\n *\n * Format notes:\n *\n * - Bits are stored in bytes from the least significant bit to the most\n *   significant bit.  Therefore bits are dropped from the bottom of the bit\n *   buffer, using shift right, and new bytes are appended to the top of the\n *   bit buffer, using shift left.\n */\nlocal int bits(struct state *s, int need)\n{\n    int val;            /* bit accumulator */\n\n    /* load at least need bits into val */\n    val = s->bitbuf;\n    while (s->bitcnt < need) {\n        if (s->left == 0) {\n            s->left = s->infun(s->inhow, &(s->in));\n            if (s->left == 0) longjmp(s->env, 1);       /* out of input */\n        }\n        val |= (int)(*(s->in)++) << s->bitcnt;          /* load eight bits */\n        s->left--;\n        s->bitcnt += 8;\n    }\n\n    /* drop need bits and update buffer, always zero to seven bits left */\n    s->bitbuf = val >> need;\n    s->bitcnt -= need;\n\n    /* return need bits, zeroing the bits above that */\n    return val & ((1 << need) - 1);\n}\n\n/*\n * Huffman code decoding tables.  count[1..MAXBITS] is the number of symbols of\n * each length, which for a canonical code are stepped through in order.\n * symbol[] are the symbol values in canonical order, where the number of\n * entries is the sum of the counts in count[].  The decoding process can be\n * seen in the function decode() below.\n */\nstruct huffman {\n    short *count;       /* number of symbols of each length */\n    short *symbol;      /* canonically ordered symbols */\n};\n\n/*\n * Decode a code from the stream s using huffman table h.  Return the symbol or\n * a negative value if there is an error.  If all of the lengths are zero, i.e.\n * an empty code, or if the code is incomplete and an invalid code is received,\n * then -9 is returned after reading MAXBITS bits.\n *\n * Format notes:\n *\n * - The codes as stored in the compressed data are bit-reversed relative to\n *   a simple integer ordering of codes of the same lengths.  Hence below the\n *   bits are pulled from the compressed data one at a time and used to\n *   build the code value reversed from what is in the stream in order to\n *   permit simple integer comparisons for decoding.\n *\n * - The first code for the shortest length is all ones.  Subsequent codes of\n *   the same length are simply integer decrements of the previous code.  When\n *   moving up a length, a one bit is appended to the code.  For a complete\n *   code, the last code of the longest length will be all zeros.  To support\n *   this ordering, the bits pulled during decoding are inverted to apply the\n *   more \"natural\" ordering starting with all zeros and incrementing.\n */\nlocal int decode(struct state *s, struct huffman *h)\n{\n    int len;            /* current number of bits in code */\n    int code;           /* len bits being decoded */\n    int first;          /* first code of length len */\n    int count;          /* number of codes of length len */\n    int index;          /* index of first code of length len in symbol table */\n    int bitbuf;         /* bits from stream */\n    int left;           /* bits left in next or left to process */\n    short *next;        /* next number of codes */\n\n    bitbuf = s->bitbuf;\n    left = s->bitcnt;\n    code = first = index = 0;\n    len = 1;\n    next = h->count + 1;\n    while (1) {\n        while (left--) {\n            code |= (bitbuf & 1) ^ 1;   /* invert code */\n            bitbuf >>= 1;\n            count = *next++;\n            if (code < first + count) { /* if length len, return symbol */\n                s->bitbuf = bitbuf;\n                s->bitcnt = (s->bitcnt - len) & 7;\n                return h->symbol[index + (code - first)];\n            }\n            index += count;             /* else update for next length */\n            first += count;\n            first <<= 1;\n            code <<= 1;\n            len++;\n        }\n        left = (MAXBITS+1) - len;\n        if (left == 0) break;\n        if (s->left == 0) {\n            s->left = s->infun(s->inhow, &(s->in));\n            if (s->left == 0) longjmp(s->env, 1);       /* out of input */\n        }\n        bitbuf = *(s->in)++;\n        s->left--;\n        if (left > 8) left = 8;\n    }\n    return -9;                          /* ran out of codes */\n}\n\n/*\n * Given a list of repeated code lengths rep[0..n-1], where each byte is a\n * count (high four bits + 1) and a code length (low four bits), generate the\n * list of code lengths.  This compaction reduces the size of the object code.\n * Then given the list of code lengths length[0..n-1] representing a canonical\n * Huffman code for n symbols, construct the tables required to decode those\n * codes.  Those tables are the number of codes of each length, and the symbols\n * sorted by length, retaining their original order within each length.  The\n * return value is zero for a complete code set, negative for an over-\n * subscribed code set, and positive for an incomplete code set.  The tables\n * can be used if the return value is zero or positive, but they cannot be used\n * if the return value is negative.  If the return value is zero, it is not\n * possible for decode() using that table to return an error--any stream of\n * enough bits will resolve to a symbol.  If the return value is positive, then\n * it is possible for decode() using that table to return an error for received\n * codes past the end of the incomplete lengths.\n */\nlocal int construct(struct huffman *h, const unsigned char *rep, int n)\n{\n    int symbol;         /* current symbol when stepping through length[] */\n    int len;            /* current length when stepping through h->count[] */\n    int left;           /* number of possible codes left of current length */\n    short offs[MAXBITS+1];      /* offsets in symbol table for each length */\n    short length[256];  /* code lengths */\n\n    /* convert compact repeat counts into symbol bit length list */\n    symbol = 0;\n    do {\n        len = *rep++;\n        left = (len >> 4) + 1;\n        len &= 15;\n        do {\n            length[symbol++] = len;\n        } while (--left);\n    } while (--n);\n    n = symbol;\n\n    /* count number of codes of each length */\n    for (len = 0; len <= MAXBITS; len++)\n        h->count[len] = 0;\n    for (symbol = 0; symbol < n; symbol++)\n        (h->count[length[symbol]])++;   /* assumes lengths are within bounds */\n    if (h->count[0] == n)               /* no codes! */\n        return 0;                       /* complete, but decode() will fail */\n\n    /* check for an over-subscribed or incomplete set of lengths */\n    left = 1;                           /* one possible code of zero length */\n    for (len = 1; len <= MAXBITS; len++) {\n        left <<= 1;                     /* one more bit, double codes left */\n        left -= h->count[len];          /* deduct count from possible codes */\n        if (left < 0) return left;      /* over-subscribed--return negative */\n    }                                   /* left > 0 means incomplete */\n\n    /* generate offsets into symbol table for each length for sorting */\n    offs[1] = 0;\n    for (len = 1; len < MAXBITS; len++)\n        offs[len + 1] = offs[len] + h->count[len];\n\n    /*\n     * put symbols in table sorted by length, by symbol order within each\n     * length\n     */\n    for (symbol = 0; symbol < n; symbol++)\n        if (length[symbol] != 0)\n            h->symbol[offs[length[symbol]]++] = symbol;\n\n    /* return zero for complete set, positive for incomplete set */\n    return left;\n}\n\n/*\n * Decode PKWare Compression Library stream.\n *\n * Format notes:\n *\n * - First byte is 0 if literals are uncoded or 1 if they are coded.  Second\n *   byte is 4, 5, or 6 for the number of extra bits in the distance code.\n *   This is the base-2 logarithm of the dictionary size minus six.\n *\n * - Compressed data is a combination of literals and length/distance pairs\n *   terminated by an end code.  Literals are either Huffman coded or\n *   uncoded bytes.  A length/distance pair is a coded length followed by a\n *   coded distance to represent a string that occurs earlier in the\n *   uncompressed data that occurs again at the current location.\n *\n * - A bit preceding a literal or length/distance pair indicates which comes\n *   next, 0 for literals, 1 for length/distance.\n *\n * - If literals are uncoded, then the next eight bits are the literal, in the\n *   normal bit order in th stream, i.e. no bit-reversal is needed. Similarly,\n *   no bit reversal is needed for either the length extra bits or the distance\n *   extra bits.\n *\n * - Literal bytes are simply written to the output.  A length/distance pair is\n *   an instruction to copy previously uncompressed bytes to the output.  The\n *   copy is from distance bytes back in the output stream, copying for length\n *   bytes.\n *\n * - Distances pointing before the beginning of the output data are not\n *   permitted.\n *\n * - Overlapped copies, where the length is greater than the distance, are\n *   allowed and common.  For example, a distance of one and a length of 518\n *   simply copies the last byte 518 times.  A distance of four and a length of\n *   twelve copies the last four bytes three times.  A simple forward copy\n *   ignoring whether the length is greater than the distance or not implements\n *   this correctly.\n */\nlocal int decomp(struct state *s)\n{\n    int lit;            /* true if literals are coded */\n    int dict;           /* log2(dictionary size) - 6 */\n    int symbol;         /* decoded symbol, extra bits for distance */\n    int len;            /* length for copy */\n    unsigned dist;      /* distance for copy */\n    int copy;           /* copy counter */\n    unsigned char *from, *to;   /* copy pointers */\n    static int virgin = 1;                              /* build tables once */\n    static short litcnt[MAXBITS+1], litsym[256];        /* litcode memory */\n    static short lencnt[MAXBITS+1], lensym[16];         /* lencode memory */\n    static short distcnt[MAXBITS+1], distsym[64];       /* distcode memory */\n    static struct huffman litcode = {litcnt, litsym};   /* length code */\n    static struct huffman lencode = {lencnt, lensym};   /* length code */\n    static struct huffman distcode = {distcnt, distsym};/* distance code */\n        /* bit lengths of literal codes */\n    static const unsigned char litlen[] = {\n        11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8,\n        9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5,\n        7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12,\n        8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27,\n        44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45,\n        44, 173};\n        /* bit lengths of length codes 0..15 */\n    static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23};\n        /* bit lengths of distance codes 0..63 */\n    static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248};\n    static const short base[16] = {     /* base for length codes */\n        3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264};\n    static const char extra[16] = {     /* extra bits for length codes */\n        0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8};\n\n    /* set up decoding tables (once--might not be thread-safe) */\n    if (virgin) {\n        construct(&litcode, litlen, sizeof(litlen));\n        construct(&lencode, lenlen, sizeof(lenlen));\n        construct(&distcode, distlen, sizeof(distlen));\n        virgin = 0;\n    }\n\n    /* read header */\n    lit = bits(s, 8);\n    if (lit > 1) return -1;\n    dict = bits(s, 8);\n    if (dict < 4 || dict > 6) return -2;\n\n    /* decode literals and length/distance pairs */\n    do {\n        if (bits(s, 1)) {\n            /* get length */\n            symbol = decode(s, &lencode);\n            len = base[symbol] + bits(s, extra[symbol]);\n            if (len == 519) break;              /* end code */\n\n            /* get distance */\n            symbol = len == 2 ? 2 : dict;\n            dist = decode(s, &distcode) << symbol;\n            dist += bits(s, symbol);\n            dist++;\n            if (s->first && dist > s->next)\n                return -3;              /* distance too far back */\n\n            /* copy length bytes from distance bytes back */\n            do {\n                to = s->out + s->next;\n                from = to - dist;\n                copy = MAXWIN;\n                if (s->next < dist) {\n                    from += copy;\n                    copy = dist;\n                }\n                copy -= s->next;\n                if (copy > len) copy = len;\n                len -= copy;\n                s->next += copy;\n                do {\n                    *to++ = *from++;\n                } while (--copy);\n                if (s->next == MAXWIN) {\n                    if (s->outfun(s->outhow, s->out, s->next)) return 1;\n                    s->next = 0;\n                    s->first = 0;\n                }\n            } while (len != 0);\n        }\n        else {\n            /* get literal and write it */\n            symbol = lit ? decode(s, &litcode) : bits(s, 8);\n            s->out[s->next++] = symbol;\n            if (s->next == MAXWIN) {\n                if (s->outfun(s->outhow, s->out, s->next)) return 1;\n                s->next = 0;\n                s->first = 0;\n            }\n        }\n    } while (1);\n    return 0;\n}\n\n/* See comments in blast.h */\nint blast(blast_in infun, void *inhow, blast_out outfun, void *outhow)\n{\n    struct state s;             /* input/output state */\n    int err;                    /* return value */\n\n    /* initialize input state */\n    s.infun = infun;\n    s.inhow = inhow;\n    s.left = 0;\n    s.bitbuf = 0;\n    s.bitcnt = 0;\n\n    /* initialize output state */\n    s.outfun = outfun;\n    s.outhow = outhow;\n    s.next = 0;\n    s.first = 1;\n\n    /* return if bits() or decode() tries to read past available input */\n    if (setjmp(s.env) != 0)             /* if came back here via longjmp(), */\n        err = 2;                        /*  then skip decomp(), return error */\n    else\n        err = decomp(&s);               /* decompress */\n\n    /* write any leftover output and update the error code if needed */\n    if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0)\n        err = 1;\n    return err;\n}\n\n#ifdef TEST\n/* Example of how to use blast() */\n#include <stdio.h>\n#include <stdlib.h>\n\n#define CHUNK 16384\n\nlocal unsigned inf(void *how, unsigned char **buf)\n{\n    static unsigned char hold[CHUNK];\n\n    *buf = hold;\n    return fread(hold, 1, CHUNK, (FILE *)how);\n}\n\nlocal int outf(void *how, unsigned char *buf, unsigned len)\n{\n    return fwrite(buf, 1, len, (FILE *)how) != len;\n}\n\n/* Decompress a PKWare Compression Library stream from stdin to stdout */\nint main(void)\n{\n    int ret, n;\n\n    /* decompress to stdout */\n    ret = blast(inf, stdin, outf, stdout);\n    if (ret != 0) fprintf(stderr, \"blast error: %d\\n\", ret);\n\n    /* see if there are any leftover bytes */\n    n = 0;\n    while (getchar() != EOF) n++;\n    if (n) fprintf(stderr, \"blast warning: %d unused bytes of input\\n\", n);\n\n    /* return blast() error code */\n    return ret;\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/blast/blast.h",
    "content": "/* blast.h -- interface for blast.c\n  Copyright (C) 2003, 2012 Mark Adler\n  version 1.2, 24 Oct 2012\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the author be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Mark Adler    madler@alumni.caltech.edu\n */\n\n\n/*\n * blast() decompresses the PKWare Data Compression Library (DCL) compressed\n * format.  It provides the same functionality as the explode() function in\n * that library.  (Note: PKWare overused the \"implode\" verb, and the format\n * used by their library implode() function is completely different and\n * incompatible with the implode compression method supported by PKZIP.)\n *\n * The binary mode for stdio functions should be used to assure that the\n * compressed data is not corrupted when read or written.  For example:\n * fopen(..., \"rb\") and fopen(..., \"wb\").\n */\n\n\ntypedef unsigned (*blast_in)(void *how, unsigned char **buf);\ntypedef int (*blast_out)(void *how, unsigned char *buf, unsigned len);\n/* Definitions for input/output functions passed to blast().  See below for\n * what the provided functions need to do.\n */\n\n\nint blast(blast_in infun, void *inhow, blast_out outfun, void *outhow);\n/* Decompress input to output using the provided infun() and outfun() calls.\n * On success, the return value of blast() is zero.  If there is an error in\n * the source data, i.e. it is not in the proper format, then a negative value\n * is returned.  If there is not enough input available or there is not enough\n * output space, then a positive error is returned.\n *\n * The input function is invoked: len = infun(how, &buf), where buf is set by\n * infun() to point to the input buffer, and infun() returns the number of\n * available bytes there.  If infun() returns zero, then blast() returns with\n * an input error.  (blast() only asks for input if it needs it.)  inhow is for\n * use by the application to pass an input descriptor to infun(), if desired.\n *\n * The output function is invoked: err = outfun(how, buf, len), where the bytes\n * to be written are buf[0..len-1].  If err is not zero, then blast() returns\n * with an output error.  outfun() is always called with len <= 4096.  outhow\n * is for use by the application to pass an output descriptor to outfun(), if\n * desired.\n *\n * The return codes are:\n *\n *   2:  ran out of input before completing decompression\n *   1:  output error before completing decompression\n *   0:  successful decompression\n *  -1:  literal flag not zero or one\n *  -2:  dictionary size not in 4..6\n *  -3:  distance is too far back\n *\n * At the bottom of blast.c is an example program that uses blast() that can be\n * compiled to produce a command-line decompression filter by defining TEST.\n */\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/blast/test.txt",
    "content": "AIAIAIAIAIAIA"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/delphi/ZLib.pas",
    "content": "{*******************************************************}\n{                                                       }\n{       Borland Delphi Supplemental Components          }\n{       ZLIB Data Compression Interface Unit            }\n{                                                       }\n{       Copyright (c) 1997,99 Borland Corporation       }\n{                                                       }\n{*******************************************************}\n\n{ Updated for zlib 1.2.x by Cosmin Truta <cosmint@cs.ubbcluj.ro> }\n\nunit ZLib;\n\ninterface\n\nuses SysUtils, Classes;\n\ntype\n  TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer; cdecl;\n  TFree = procedure (AppData, Block: Pointer); cdecl;\n\n  // Internal structure.  Ignore.\n  TZStreamRec = packed record\n    next_in: PChar;       // next input byte\n    avail_in: Integer;    // number of bytes available at next_in\n    total_in: Longint;    // total nb of input bytes read so far\n\n    next_out: PChar;      // next output byte should be put here\n    avail_out: Integer;   // remaining free space at next_out\n    total_out: Longint;   // total nb of bytes output so far\n\n    msg: PChar;           // last error message, NULL if no error\n    internal: Pointer;    // not visible by applications\n\n    zalloc: TAlloc;       // used to allocate the internal state\n    zfree: TFree;         // used to free the internal state\n    AppData: Pointer;     // private data object passed to zalloc and zfree\n\n    data_type: Integer;   // best guess about the data type: ascii or binary\n    adler: Longint;       // adler32 value of the uncompressed data\n    reserved: Longint;    // reserved for future use\n  end;\n\n  // Abstract ancestor class\n  TCustomZlibStream = class(TStream)\n  private\n    FStrm: TStream;\n    FStrmPos: Integer;\n    FOnProgress: TNotifyEvent;\n    FZRec: TZStreamRec;\n    FBuffer: array [Word] of Char;\n  protected\n    procedure Progress(Sender: TObject); dynamic;\n    property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;\n    constructor Create(Strm: TStream);\n  end;\n\n{ TCompressionStream compresses data on the fly as data is written to it, and\n  stores the compressed data to another stream.\n\n  TCompressionStream is write-only and strictly sequential. Reading from the\n  stream will raise an exception. Using Seek to move the stream pointer\n  will raise an exception.\n\n  Output data is cached internally, written to the output stream only when\n  the internal output buffer is full.  All pending output data is flushed\n  when the stream is destroyed.\n\n  The Position property returns the number of uncompressed bytes of\n  data that have been written to the stream so far.\n\n  CompressionRate returns the on-the-fly percentage by which the original\n  data has been compressed:  (1 - (CompressedBytes / UncompressedBytes)) * 100\n  If raw data size = 100 and compressed data size = 25, the CompressionRate\n  is 75%\n\n  The OnProgress event is called each time the output buffer is filled and\n  written to the output stream.  This is useful for updating a progress\n  indicator when you are writing a large chunk of data to the compression\n  stream in a single call.}\n\n\n  TCompressionLevel = (clNone, clFastest, clDefault, clMax);\n\n  TCompressionStream = class(TCustomZlibStream)\n  private\n    function GetCompressionRate: Single;\n  public\n    constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream);\n    destructor Destroy; override;\n    function Read(var Buffer; Count: Longint): Longint; override;\n    function Write(const Buffer; Count: Longint): Longint; override;\n    function Seek(Offset: Longint; Origin: Word): Longint; override;\n    property CompressionRate: Single read GetCompressionRate;\n    property OnProgress;\n  end;\n\n{ TDecompressionStream decompresses data on the fly as data is read from it.\n\n  Compressed data comes from a separate source stream.  TDecompressionStream\n  is read-only and unidirectional; you can seek forward in the stream, but not\n  backwards.  The special case of setting the stream position to zero is\n  allowed.  Seeking forward decompresses data until the requested position in\n  the uncompressed data has been reached.  Seeking backwards, seeking relative\n  to the end of the stream, requesting the size of the stream, and writing to\n  the stream will raise an exception.\n\n  The Position property returns the number of bytes of uncompressed data that\n  have been read from the stream so far.\n\n  The OnProgress event is called each time the internal input buffer of\n  compressed data is exhausted and the next block is read from the input stream.\n  This is useful for updating a progress indicator when you are reading a\n  large chunk of data from the decompression stream in a single call.}\n\n  TDecompressionStream = class(TCustomZlibStream)\n  public\n    constructor Create(Source: TStream);\n    destructor Destroy; override;\n    function Read(var Buffer; Count: Longint): Longint; override;\n    function Write(const Buffer; Count: Longint): Longint; override;\n    function Seek(Offset: Longint; Origin: Word): Longint; override;\n    property OnProgress;\n  end;\n\n\n\n{ CompressBuf compresses data, buffer to buffer, in one call.\n   In: InBuf = ptr to compressed data\n       InBytes = number of bytes in InBuf\n  Out: OutBuf = ptr to newly allocated buffer containing decompressed data\n       OutBytes = number of bytes in OutBuf   }\nprocedure CompressBuf(const InBuf: Pointer; InBytes: Integer;\n                      out OutBuf: Pointer; out OutBytes: Integer);\n\n\n{ DecompressBuf decompresses data, buffer to buffer, in one call.\n   In: InBuf = ptr to compressed data\n       InBytes = number of bytes in InBuf\n       OutEstimate = zero, or est. size of the decompressed data\n  Out: OutBuf = ptr to newly allocated buffer containing decompressed data\n       OutBytes = number of bytes in OutBuf   }\nprocedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;\n OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);\n\n{ DecompressToUserBuf decompresses data, buffer to buffer, in one call.\n   In: InBuf = ptr to compressed data\n       InBytes = number of bytes in InBuf\n  Out: OutBuf = ptr to user-allocated buffer to contain decompressed data\n       BufSize = number of bytes in OutBuf   }\nprocedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;\n  const OutBuf: Pointer; BufSize: Integer);\n\nconst\n  zlib_version = '1.2.8';\n\ntype\n  EZlibError = class(Exception);\n  ECompressionError = class(EZlibError);\n  EDecompressionError = class(EZlibError);\n\nimplementation\n\nuses ZLibConst;\n\nconst\n  Z_NO_FLUSH      = 0;\n  Z_PARTIAL_FLUSH = 1;\n  Z_SYNC_FLUSH    = 2;\n  Z_FULL_FLUSH    = 3;\n  Z_FINISH        = 4;\n\n  Z_OK            = 0;\n  Z_STREAM_END    = 1;\n  Z_NEED_DICT     = 2;\n  Z_ERRNO         = (-1);\n  Z_STREAM_ERROR  = (-2);\n  Z_DATA_ERROR    = (-3);\n  Z_MEM_ERROR     = (-4);\n  Z_BUF_ERROR     = (-5);\n  Z_VERSION_ERROR = (-6);\n\n  Z_NO_COMPRESSION       =   0;\n  Z_BEST_SPEED           =   1;\n  Z_BEST_COMPRESSION     =   9;\n  Z_DEFAULT_COMPRESSION  = (-1);\n\n  Z_FILTERED            = 1;\n  Z_HUFFMAN_ONLY        = 2;\n  Z_RLE                 = 3;\n  Z_DEFAULT_STRATEGY    = 0;\n\n  Z_BINARY   = 0;\n  Z_ASCII    = 1;\n  Z_UNKNOWN  = 2;\n\n  Z_DEFLATED = 8;\n\n\n{$L adler32.obj}\n{$L compress.obj}\n{$L crc32.obj}\n{$L deflate.obj}\n{$L infback.obj}\n{$L inffast.obj}\n{$L inflate.obj}\n{$L inftrees.obj}\n{$L trees.obj}\n{$L uncompr.obj}\n{$L zutil.obj}\n\nprocedure adler32; external;\nprocedure compressBound; external;\nprocedure crc32; external;\nprocedure deflateInit2_; external;\nprocedure deflateParams; external;\n\nfunction _malloc(Size: Integer): Pointer; cdecl;\nbegin\n  Result := AllocMem(Size);\nend;\n\nprocedure _free(Block: Pointer); cdecl;\nbegin\n  FreeMem(Block);\nend;\n\nprocedure _memset(P: Pointer; B: Byte; count: Integer); cdecl;\nbegin\n  FillChar(P^, count, B);\nend;\n\nprocedure _memcpy(dest, source: Pointer; count: Integer); cdecl;\nbegin\n  Move(source^, dest^, count);\nend;\n\n\n\n// deflate compresses data\nfunction deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;\n  recsize: Integer): Integer; external;\nfunction deflate(var strm: TZStreamRec; flush: Integer): Integer; external;\nfunction deflateEnd(var strm: TZStreamRec): Integer; external;\n\n// inflate decompresses data\nfunction inflateInit_(var strm: TZStreamRec; version: PChar;\n  recsize: Integer): Integer; external;\nfunction inflate(var strm: TZStreamRec; flush: Integer): Integer; external;\nfunction inflateEnd(var strm: TZStreamRec): Integer; external;\nfunction inflateReset(var strm: TZStreamRec): Integer; external;\n\n\nfunction zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl;\nbegin\n//  GetMem(Result, Items*Size);\n  Result := AllocMem(Items * Size);\nend;\n\nprocedure zlibFreeMem(AppData, Block: Pointer); cdecl;\nbegin\n  FreeMem(Block);\nend;\n\n{function zlibCheck(code: Integer): Integer;\nbegin\n  Result := code;\n  if code < 0 then\n    raise EZlibError.Create('error');    //!!\nend;}\n\nfunction CCheck(code: Integer): Integer;\nbegin\n  Result := code;\n  if code < 0 then\n    raise ECompressionError.Create('error'); //!!\nend;\n\nfunction DCheck(code: Integer): Integer;\nbegin\n  Result := code;\n  if code < 0 then\n    raise EDecompressionError.Create('error');  //!!\nend;\n\nprocedure CompressBuf(const InBuf: Pointer; InBytes: Integer;\n                      out OutBuf: Pointer; out OutBytes: Integer);\nvar\n  strm: TZStreamRec;\n  P: Pointer;\nbegin\n  FillChar(strm, sizeof(strm), 0);\n  strm.zalloc := zlibAllocMem;\n  strm.zfree := zlibFreeMem;\n  OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;\n  GetMem(OutBuf, OutBytes);\n  try\n    strm.next_in := InBuf;\n    strm.avail_in := InBytes;\n    strm.next_out := OutBuf;\n    strm.avail_out := OutBytes;\n    CCheck(deflateInit_(strm, Z_BEST_COMPRESSION, zlib_version, sizeof(strm)));\n    try\n      while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do\n      begin\n        P := OutBuf;\n        Inc(OutBytes, 256);\n        ReallocMem(OutBuf, OutBytes);\n        strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));\n        strm.avail_out := 256;\n      end;\n    finally\n      CCheck(deflateEnd(strm));\n    end;\n    ReallocMem(OutBuf, strm.total_out);\n    OutBytes := strm.total_out;\n  except\n    FreeMem(OutBuf);\n    raise\n  end;\nend;\n\n\nprocedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;\n  OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);\nvar\n  strm: TZStreamRec;\n  P: Pointer;\n  BufInc: Integer;\nbegin\n  FillChar(strm, sizeof(strm), 0);\n  strm.zalloc := zlibAllocMem;\n  strm.zfree := zlibFreeMem;\n  BufInc := (InBytes + 255) and not 255;\n  if OutEstimate = 0 then\n    OutBytes := BufInc\n  else\n    OutBytes := OutEstimate;\n  GetMem(OutBuf, OutBytes);\n  try\n    strm.next_in := InBuf;\n    strm.avail_in := InBytes;\n    strm.next_out := OutBuf;\n    strm.avail_out := OutBytes;\n    DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));\n    try\n      while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do\n      begin\n        P := OutBuf;\n        Inc(OutBytes, BufInc);\n        ReallocMem(OutBuf, OutBytes);\n        strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));\n        strm.avail_out := BufInc;\n      end;\n    finally\n      DCheck(inflateEnd(strm));\n    end;\n    ReallocMem(OutBuf, strm.total_out);\n    OutBytes := strm.total_out;\n  except\n    FreeMem(OutBuf);\n    raise\n  end;\nend;\n\nprocedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;\n  const OutBuf: Pointer; BufSize: Integer);\nvar\n  strm: TZStreamRec;\nbegin\n  FillChar(strm, sizeof(strm), 0);\n  strm.zalloc := zlibAllocMem;\n  strm.zfree := zlibFreeMem;\n  strm.next_in := InBuf;\n  strm.avail_in := InBytes;\n  strm.next_out := OutBuf;\n  strm.avail_out := BufSize;\n  DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));\n  try\n    if DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END then\n      raise EZlibError.CreateRes(@sTargetBufferTooSmall);\n  finally\n    DCheck(inflateEnd(strm));\n  end;\nend;\n\n// TCustomZlibStream\n\nconstructor TCustomZLibStream.Create(Strm: TStream);\nbegin\n  inherited Create;\n  FStrm := Strm;\n  FStrmPos := Strm.Position;\n  FZRec.zalloc := zlibAllocMem;\n  FZRec.zfree := zlibFreeMem;\nend;\n\nprocedure TCustomZLibStream.Progress(Sender: TObject);\nbegin\n  if Assigned(FOnProgress) then FOnProgress(Sender);\nend;\n\n\n// TCompressionStream\n\nconstructor TCompressionStream.Create(CompressionLevel: TCompressionLevel;\n  Dest: TStream);\nconst\n  Levels: array [TCompressionLevel] of ShortInt =\n    (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);\nbegin\n  inherited Create(Dest);\n  FZRec.next_out := FBuffer;\n  FZRec.avail_out := sizeof(FBuffer);\n  CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec)));\nend;\n\ndestructor TCompressionStream.Destroy;\nbegin\n  FZRec.next_in := nil;\n  FZRec.avail_in := 0;\n  try\n    if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;\n    while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END)\n      and (FZRec.avail_out = 0) do\n    begin\n      FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));\n      FZRec.next_out := FBuffer;\n      FZRec.avail_out := sizeof(FBuffer);\n    end;\n    if FZRec.avail_out < sizeof(FBuffer) then\n      FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out);\n  finally\n    deflateEnd(FZRec);\n  end;\n  inherited Destroy;\nend;\n\nfunction TCompressionStream.Read(var Buffer; Count: Longint): Longint;\nbegin\n  raise ECompressionError.CreateRes(@sInvalidStreamOp);\nend;\n\nfunction TCompressionStream.Write(const Buffer; Count: Longint): Longint;\nbegin\n  FZRec.next_in := @Buffer;\n  FZRec.avail_in := Count;\n  if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;\n  while (FZRec.avail_in > 0) do\n  begin\n    CCheck(deflate(FZRec, 0));\n    if FZRec.avail_out = 0 then\n    begin\n      FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));\n      FZRec.next_out := FBuffer;\n      FZRec.avail_out := sizeof(FBuffer);\n      FStrmPos := FStrm.Position;\n      Progress(Self);\n    end;\n  end;\n  Result := Count;\nend;\n\nfunction TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint;\nbegin\n  if (Offset = 0) and (Origin = soFromCurrent) then\n    Result := FZRec.total_in\n  else\n    raise ECompressionError.CreateRes(@sInvalidStreamOp);\nend;\n\nfunction TCompressionStream.GetCompressionRate: Single;\nbegin\n  if FZRec.total_in = 0 then\n    Result := 0\n  else\n    Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0;\nend;\n\n\n// TDecompressionStream\n\nconstructor TDecompressionStream.Create(Source: TStream);\nbegin\n  inherited Create(Source);\n  FZRec.next_in := FBuffer;\n  FZRec.avail_in := 0;\n  DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec)));\nend;\n\ndestructor TDecompressionStream.Destroy;\nbegin\n  FStrm.Seek(-FZRec.avail_in, 1);\n  inflateEnd(FZRec);\n  inherited Destroy;\nend;\n\nfunction TDecompressionStream.Read(var Buffer; Count: Longint): Longint;\nbegin\n  FZRec.next_out := @Buffer;\n  FZRec.avail_out := Count;\n  if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;\n  while (FZRec.avail_out > 0) do\n  begin\n    if FZRec.avail_in = 0 then\n    begin\n      FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer));\n      if FZRec.avail_in = 0 then\n      begin\n        Result := Count - FZRec.avail_out;\n        Exit;\n      end;\n      FZRec.next_in := FBuffer;\n      FStrmPos := FStrm.Position;\n      Progress(Self);\n    end;\n    CCheck(inflate(FZRec, 0));\n  end;\n  Result := Count;\nend;\n\nfunction TDecompressionStream.Write(const Buffer; Count: Longint): Longint;\nbegin\n  raise EDecompressionError.CreateRes(@sInvalidStreamOp);\nend;\n\nfunction TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;\nvar\n  I: Integer;\n  Buf: array [0..4095] of Char;\nbegin\n  if (Offset = 0) and (Origin = soFromBeginning) then\n  begin\n    DCheck(inflateReset(FZRec));\n    FZRec.next_in := FBuffer;\n    FZRec.avail_in := 0;\n    FStrm.Position := 0;\n    FStrmPos := 0;\n  end\n  else if ( (Offset >= 0) and (Origin = soFromCurrent)) or\n          ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then\n  begin\n    if Origin = soFromBeginning then Dec(Offset, FZRec.total_out);\n    if Offset > 0 then\n    begin\n      for I := 1 to Offset div sizeof(Buf) do\n        ReadBuffer(Buf, sizeof(Buf));\n      ReadBuffer(Buf, Offset mod sizeof(Buf));\n    end;\n  end\n  else\n    raise EDecompressionError.CreateRes(@sInvalidStreamOp);\n  Result := FZRec.total_out;\nend;\n\n\nend.\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/delphi/ZLibConst.pas",
    "content": "unit ZLibConst;\n\ninterface\n\nresourcestring\n  sTargetBufferTooSmall = 'ZLib error: target buffer may be too small';\n  sInvalidStreamOp = 'Invalid stream operation';\n\nimplementation\n\nend.\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/delphi/readme.txt",
    "content": "\nOverview\n========\n\nThis directory contains an update to the ZLib interface unit,\ndistributed by Borland as a Delphi supplemental component.\n\nThe original ZLib unit is Copyright (c) 1997,99 Borland Corp.,\nand is based on zlib version 1.0.4.  There are a series of bugs\nand security problems associated with that old zlib version, and\nwe recommend the users to update their ZLib unit.\n\n\nSummary of modifications\n========================\n\n- Improved makefile, adapted to zlib version 1.2.1.\n\n- Some field types from TZStreamRec are changed from Integer to\n  Longint, for consistency with the zlib.h header, and for 64-bit\n  readiness.\n\n- The zlib_version constant is updated.\n\n- The new Z_RLE strategy has its corresponding symbolic constant.\n\n- The allocation and deallocation functions and function types\n  (TAlloc, TFree, zlibAllocMem and zlibFreeMem) are now cdecl,\n  and _malloc and _free are added as C RTL stubs.  As a result,\n  the original C sources of zlib can be compiled out of the box,\n  and linked to the ZLib unit.\n\n\nSuggestions for improvements\n============================\n\nCurrently, the ZLib unit provides only a limited wrapper around\nthe zlib library, and much of the original zlib functionality is\nmissing.  Handling compressed file formats like ZIP/GZIP or PNG\ncannot be implemented without having this functionality.\nApplications that handle these formats are either using their own,\nduplicated code, or not using the ZLib unit at all.\n\nHere are a few suggestions:\n\n- Checksum class wrappers around adler32() and crc32(), similar\n  to the Java classes that implement the java.util.zip.Checksum\n  interface.\n\n- The ability to read and write raw deflate streams, without the\n  zlib stream header and trailer.  Raw deflate streams are used\n  in the ZIP file format.\n\n- The ability to read and write gzip streams, used in the GZIP\n  file format, and normally produced by the gzip program.\n\n- The ability to select a different compression strategy, useful\n  to PNG and MNG image compression, and to multimedia compression\n  in general.  Besides the compression level\n\n    TCompressionLevel = (clNone, clFastest, clDefault, clMax);\n\n  which, in fact, could have used the 'z' prefix and avoided\n  TColor-like symbols\n\n    TCompressionLevel = (zcNone, zcFastest, zcDefault, zcMax);\n\n  there could be a compression strategy\n\n    TCompressionStrategy = (zsDefault, zsFiltered, zsHuffmanOnly, zsRle);\n\n- ZIP and GZIP stream handling via TStreams.\n\n\n--\nCosmin Truta <cosmint@cs.ubbcluj.ro>\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/delphi/zlibd32.mak",
    "content": "# Makefile for zlib\n# For use with Delphi and C++ Builder under Win32\n# Updated for zlib 1.2.x by Cosmin Truta\n\n# ------------ Borland C++ ------------\n\n# This project uses the Delphi (fastcall/register) calling convention:\nLOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl\n\nCC = bcc32\nLD = bcc32\nAR = tlib\n# do not use \"-pr\" in CFLAGS\nCFLAGS = -a -d -k- -O2 $(LOC)\nLDFLAGS =\n\n\n# variables\nZLIB_LIB = zlib.lib\n\nOBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj\nOBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj\nOBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj\nOBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj\n\n\n# targets\nall: $(ZLIB_LIB) example.exe minigzip.exe\n\n.c.obj:\n\t$(CC) -c $(CFLAGS) $*.c\n\nadler32.obj: adler32.c zlib.h zconf.h\n\ncompress.obj: compress.c zlib.h zconf.h\n\ncrc32.obj: crc32.c zlib.h zconf.h crc32.h\n\ndeflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h\n\ngzclose.obj: gzclose.c zlib.h zconf.h gzguts.h\n\ngzlib.obj: gzlib.c zlib.h zconf.h gzguts.h\n\ngzread.obj: gzread.c zlib.h zconf.h gzguts.h\n\ngzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h\n\ninfback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h inffixed.h\n\ninffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h\n\ninflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h inffixed.h\n\ninftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h\n\ntrees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h\n\nuncompr.obj: uncompr.c zlib.h zconf.h\n\nzutil.obj: zutil.c zutil.h zlib.h zconf.h\n\nexample.obj: test/example.c zlib.h zconf.h\n\nminigzip.obj: test/minigzip.c zlib.h zconf.h\n\n\n# For the sake of the old Borland make,\n# the command line is cut to fit in the MS-DOS 128 byte limit:\n$(ZLIB_LIB): $(OBJ1) $(OBJ2)\n\t-del $(ZLIB_LIB)\n\t$(AR) $(ZLIB_LIB) $(OBJP1)\n\t$(AR) $(ZLIB_LIB) $(OBJP2)\n\n\n# testing\ntest: example.exe minigzip.exe\n\texample\n\techo hello world | minigzip | minigzip -d\n\nexample.exe: example.obj $(ZLIB_LIB)\n\t$(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)\n\nminigzip.exe: minigzip.obj $(ZLIB_LIB)\n\t$(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)\n\n\n# cleanup\nclean:\n\t-del *.obj\n\t-del *.exe\n\t-del *.lib\n\t-del *.tds\n\t-del zlib.bak\n\t-del foo.gz\n\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/dotzlib/DotZLib/AssemblyInfo.cs",
    "content": "using System.Reflection;\nusing System.Runtime.CompilerServices;\n\n//\n// General Information about an assembly is controlled through the following\n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n//\n[assembly: AssemblyTitle(\"DotZLib\")]\n[assembly: AssemblyDescription(\".Net bindings for ZLib compression dll 1.2.x\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"Henrik Ravn\")]\n[assembly: AssemblyProduct(\"\")]\n[assembly: AssemblyCopyright(\"(c) 2004 by Henrik Ravn\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n//\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version\n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Revision and Build Numbers\n// by using the '*' as shown below:\n\n[assembly: AssemblyVersion(\"1.0.*\")]\n\n//\n// In order to sign your assembly you must specify a key to use. Refer to the\n// Microsoft .NET Framework documentation for more information on assembly signing.\n//\n// Use the attributes below to control which key is used for signing.\n//\n// Notes:\n//   (*) If no key is specified, the assembly is not signed.\n//   (*) KeyName refers to a key that has been installed in the Crypto Service\n//       Provider (CSP) on your machine. KeyFile refers to a file which contains\n//       a key.\n//   (*) If the KeyFile and the KeyName values are both specified, the\n//       following processing occurs:\n//       (1) If the KeyName can be found in the CSP, that key is used.\n//       (2) If the KeyName does not exist and the KeyFile does exist, the key\n//           in the KeyFile is installed into the CSP and used.\n//   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.\n//       When specifying the KeyFile, the location of the KeyFile should be\n//       relative to the project output directory which is\n//       %Project Directory%\\obj\\<configuration>. For example, if your KeyFile is\n//       located in the project directory, you would specify the AssemblyKeyFile\n//       attribute as [assembly: AssemblyKeyFile(\"..\\\\..\\\\mykey.snk\")]\n//   (*) Delay Signing is an advanced option - see the Microsoft .NET Framework\n//       documentation for more information on this.\n//\n[assembly: AssemblyDelaySign(false)]\n[assembly: AssemblyKeyFile(\"\")]\n[assembly: AssemblyKeyName(\"\")]\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/dotzlib/DotZLib/ChecksumImpl.cs",
    "content": "//\n//  Copyright Henrik Ravn 2004\n//\n// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\n// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n\nusing System;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\n\nnamespace DotZLib\n{\n    #region ChecksumGeneratorBase\n    /// <summary>\n    /// Implements the common functionality needed for all <see cref=\"ChecksumGenerator\"/>s\n    /// </summary>\n    /// <example></example>\n    public abstract class ChecksumGeneratorBase : ChecksumGenerator\n    {\n        /// <summary>\n        /// The value of the current checksum\n        /// </summary>\n        protected uint _current;\n\n        /// <summary>\n        /// Initializes a new instance of the checksum generator base - the current checksum is\n        /// set to zero\n        /// </summary>\n        public ChecksumGeneratorBase()\n        {\n            _current = 0;\n        }\n\n        /// <summary>\n        /// Initializes a new instance of the checksum generator basewith a specified value\n        /// </summary>\n        /// <param name=\"initialValue\">The value to set the current checksum to</param>\n        public ChecksumGeneratorBase(uint initialValue)\n        {\n            _current = initialValue;\n        }\n\n        /// <summary>\n        /// Resets the current checksum to zero\n        /// </summary>\n        public void Reset() { _current = 0; }\n\n        /// <summary>\n        /// Gets the current checksum value\n        /// </summary>\n        public uint Value { get { return _current; } }\n\n        /// <summary>\n        /// Updates the current checksum with part of an array of bytes\n        /// </summary>\n        /// <param name=\"data\">The data to update the checksum with</param>\n        /// <param name=\"offset\">Where in <c>data</c> to start updating</param>\n        /// <param name=\"count\">The number of bytes from <c>data</c> to use</param>\n        /// <exception cref=\"ArgumentException\">The sum of offset and count is larger than the length of <c>data</c></exception>\n        /// <exception cref=\"NullReferenceException\"><c>data</c> is a null reference</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\">Offset or count is negative.</exception>\n        /// <remarks>All the other <c>Update</c> methods are implmeneted in terms of this one.\n        /// This is therefore the only method a derived class has to implement</remarks>\n        public abstract void Update(byte[] data, int offset, int count);\n\n        /// <summary>\n        /// Updates the current checksum with an array of bytes.\n        /// </summary>\n        /// <param name=\"data\">The data to update the checksum with</param>\n        public void Update(byte[] data)\n        {\n            Update(data, 0, data.Length);\n        }\n\n        /// <summary>\n        /// Updates the current checksum with the data from a string\n        /// </summary>\n        /// <param name=\"data\">The string to update the checksum with</param>\n        /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>\n        public void Update(string data)\n        {\n\t\t\tUpdate(Encoding.UTF8.GetBytes(data));\n        }\n\n        /// <summary>\n        /// Updates the current checksum with the data from a string, using a specific encoding\n        /// </summary>\n        /// <param name=\"data\">The string to update the checksum with</param>\n        /// <param name=\"encoding\">The encoding to use</param>\n        public void Update(string data, Encoding encoding)\n        {\n            Update(encoding.GetBytes(data));\n        }\n\n    }\n    #endregion\n\n    #region CRC32\n    /// <summary>\n    /// Implements a CRC32 checksum generator\n    /// </summary>\n    public sealed class CRC32Checksum : ChecksumGeneratorBase\n    {\n        #region DLL imports\n\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern uint crc32(uint crc, int data, uint length);\n\n        #endregion\n\n        /// <summary>\n        /// Initializes a new instance of the CRC32 checksum generator\n        /// </summary>\n        public CRC32Checksum() : base() {}\n\n        /// <summary>\n        /// Initializes a new instance of the CRC32 checksum generator with a specified value\n        /// </summary>\n        /// <param name=\"initialValue\">The value to set the current checksum to</param>\n        public CRC32Checksum(uint initialValue) : base(initialValue) {}\n\n        /// <summary>\n        /// Updates the current checksum with part of an array of bytes\n        /// </summary>\n        /// <param name=\"data\">The data to update the checksum with</param>\n        /// <param name=\"offset\">Where in <c>data</c> to start updating</param>\n        /// <param name=\"count\">The number of bytes from <c>data</c> to use</param>\n        /// <exception cref=\"ArgumentException\">The sum of offset and count is larger than the length of <c>data</c></exception>\n        /// <exception cref=\"NullReferenceException\"><c>data</c> is a null reference</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\">Offset or count is negative.</exception>\n        public override void Update(byte[] data, int offset, int count)\n        {\n            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();\n            if ((offset+count) > data.Length) throw new ArgumentException();\n            GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);\n            try\n            {\n                _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);\n            }\n            finally\n            {\n                hData.Free();\n            }\n        }\n\n    }\n    #endregion\n\n    #region Adler\n    /// <summary>\n    /// Implements a checksum generator that computes the Adler checksum on data\n    /// </summary>\n    public sealed class AdlerChecksum : ChecksumGeneratorBase\n    {\n        #region DLL imports\n\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern uint adler32(uint adler, int data, uint length);\n\n        #endregion\n\n        /// <summary>\n        /// Initializes a new instance of the Adler checksum generator\n        /// </summary>\n        public AdlerChecksum() : base() {}\n\n        /// <summary>\n        /// Initializes a new instance of the Adler checksum generator with a specified value\n        /// </summary>\n        /// <param name=\"initialValue\">The value to set the current checksum to</param>\n        public AdlerChecksum(uint initialValue) : base(initialValue) {}\n\n        /// <summary>\n        /// Updates the current checksum with part of an array of bytes\n        /// </summary>\n        /// <param name=\"data\">The data to update the checksum with</param>\n        /// <param name=\"offset\">Where in <c>data</c> to start updating</param>\n        /// <param name=\"count\">The number of bytes from <c>data</c> to use</param>\n        /// <exception cref=\"ArgumentException\">The sum of offset and count is larger than the length of <c>data</c></exception>\n        /// <exception cref=\"NullReferenceException\"><c>data</c> is a null reference</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\">Offset or count is negative.</exception>\n        public override void Update(byte[] data, int offset, int count)\n        {\n            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();\n            if ((offset+count) > data.Length) throw new ArgumentException();\n            GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);\n            try\n            {\n                _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);\n            }\n            finally\n            {\n                hData.Free();\n            }\n        }\n\n    }\n    #endregion\n\n}"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/dotzlib/DotZLib/CircularBuffer.cs",
    "content": "//\n//  Copyright Henrik Ravn 2004\n//\n// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\n// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n\nusing System;\nusing System.Diagnostics;\n\nnamespace DotZLib\n{\n\n\t/// <summary>\n\t/// This class implements a circular buffer\n\t/// </summary>\n\tinternal class CircularBuffer\n\t{\n        #region Private data\n        private int _capacity;\n        private int _head;\n        private int _tail;\n        private int _size;\n        private byte[] _buffer;\n        #endregion\n\n        public CircularBuffer(int capacity)\n        {\n            Debug.Assert( capacity > 0 );\n            _buffer = new byte[capacity];\n            _capacity = capacity;\n            _head = 0;\n            _tail = 0;\n            _size = 0;\n        }\n\n        public int Size { get { return _size; } }\n\n        public int Put(byte[] source, int offset, int count)\n        {\n            Debug.Assert( count > 0 );\n            int trueCount = Math.Min(count, _capacity - Size);\n            for (int i = 0; i < trueCount; ++i)\n                _buffer[(_tail+i) % _capacity] = source[offset+i];\n            _tail += trueCount;\n            _tail %= _capacity;\n            _size += trueCount;\n            return trueCount;\n        }\n\n        public bool Put(byte b)\n        {\n            if (Size == _capacity) // no room\n                return false;\n            _buffer[_tail++] = b;\n            _tail %= _capacity;\n            ++_size;\n            return true;\n        }\n\n        public int Get(byte[] destination, int offset, int count)\n        {\n            int trueCount = Math.Min(count,Size);\n            for (int i = 0; i < trueCount; ++i)\n                destination[offset + i] = _buffer[(_head+i) % _capacity];\n            _head += trueCount;\n            _head %= _capacity;\n            _size -= trueCount;\n            return trueCount;\n        }\n\n        public int Get()\n        {\n            if (Size == 0)\n                return -1;\n\n            int result = (int)_buffer[_head++ % _capacity];\n            --_size;\n            return result;\n        }\n\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/dotzlib/DotZLib/CodecBase.cs",
    "content": "//\n//  Copyright Henrik Ravn 2004\n//\n// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\n// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace DotZLib\n{\n\t/// <summary>\n\t/// Implements the common functionality needed for all <see cref=\"Codec\"/>s\n\t/// </summary>\n\tpublic abstract class CodecBase : Codec, IDisposable\n\t{\n\n        #region Data members\n\n        /// <summary>\n        /// Instance of the internal zlib buffer structure that is\n        /// passed to all functions in the zlib dll\n        /// </summary>\n        internal ZStream _ztream = new ZStream();\n\n        /// <summary>\n        /// True if the object instance has been disposed, false otherwise\n        /// </summary>\n        protected bool _isDisposed = false;\n\n        /// <summary>\n        /// The size of the internal buffers\n        /// </summary>\n        protected const int kBufferSize = 16384;\n\n        private byte[] _outBuffer = new byte[kBufferSize];\n        private byte[] _inBuffer = new byte[kBufferSize];\n\n        private GCHandle _hInput;\n        private GCHandle _hOutput;\n\n        private uint _checksum = 0;\n\n        #endregion\n\n        /// <summary>\n        /// Initializes a new instance of the <c>CodeBase</c> class.\n        /// </summary>\n\t\tpublic CodecBase()\n\t\t{\n            try\n            {\n                _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned);\n                _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned);\n            }\n            catch (Exception)\n            {\n                CleanUp(false);\n                throw;\n            }\n        }\n\n\n        #region Codec Members\n\n        /// <summary>\n        /// Occurs when more processed data are available.\n        /// </summary>\n        public event DataAvailableHandler DataAvailable;\n\n        /// <summary>\n        /// Fires the <see cref=\"DataAvailable\"/> event\n        /// </summary>\n        protected void OnDataAvailable()\n        {\n            if (_ztream.total_out > 0)\n            {\n                if (DataAvailable != null)\n                    DataAvailable( _outBuffer, 0, (int)_ztream.total_out);\n                resetOutput();\n            }\n        }\n\n        /// <summary>\n        /// Adds more data to the codec to be processed.\n        /// </summary>\n        /// <param name=\"data\">Byte array containing the data to be added to the codec</param>\n        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>\n        public void Add(byte[] data)\n        {\n            Add(data,0,data.Length);\n        }\n\n        /// <summary>\n        /// Adds more data to the codec to be processed.\n        /// </summary>\n        /// <param name=\"data\">Byte array containing the data to be added to the codec</param>\n        /// <param name=\"offset\">The index of the first byte to add from <c>data</c></param>\n        /// <param name=\"count\">The number of bytes to add</param>\n        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>\n        /// <remarks>This must be implemented by a derived class</remarks>\n        public abstract void Add(byte[] data, int offset, int count);\n\n        /// <summary>\n        /// Finishes up any pending data that needs to be processed and handled.\n        /// </summary>\n        /// <remarks>This must be implemented by a derived class</remarks>\n        public abstract void Finish();\n\n        /// <summary>\n        /// Gets the checksum of the data that has been added so far\n        /// </summary>\n        public uint Checksum { get { return _checksum; } }\n\n        #endregion\n\n        #region Destructor & IDisposable stuff\n\n        /// <summary>\n        /// Destroys this instance\n        /// </summary>\n        ~CodecBase()\n        {\n            CleanUp(false);\n        }\n\n        /// <summary>\n        /// Releases any unmanaged resources and calls the <see cref=\"CleanUp()\"/> method of the derived class\n        /// </summary>\n        public void Dispose()\n        {\n            CleanUp(true);\n        }\n\n        /// <summary>\n        /// Performs any codec specific cleanup\n        /// </summary>\n        /// <remarks>This must be implemented by a derived class</remarks>\n        protected abstract void CleanUp();\n\n        // performs the release of the handles and calls the dereived CleanUp()\n        private void CleanUp(bool isDisposing)\n        {\n            if (!_isDisposed)\n            {\n                CleanUp();\n                if (_hInput.IsAllocated)\n                    _hInput.Free();\n                if (_hOutput.IsAllocated)\n                    _hOutput.Free();\n\n                _isDisposed = true;\n            }\n        }\n\n\n        #endregion\n\n        #region Helper methods\n\n        /// <summary>\n        /// Copies a number of bytes to the internal codec buffer - ready for proccesing\n        /// </summary>\n        /// <param name=\"data\">The byte array that contains the data to copy</param>\n        /// <param name=\"startIndex\">The index of the first byte to copy</param>\n        /// <param name=\"count\">The number of bytes to copy from <c>data</c></param>\n        protected void copyInput(byte[] data, int startIndex, int count)\n        {\n            Array.Copy(data, startIndex, _inBuffer,0, count);\n            _ztream.next_in = _hInput.AddrOfPinnedObject();\n            _ztream.total_in = 0;\n            _ztream.avail_in = (uint)count;\n\n        }\n\n        /// <summary>\n        /// Resets the internal output buffers to a known state - ready for processing\n        /// </summary>\n        protected void resetOutput()\n        {\n            _ztream.total_out = 0;\n            _ztream.avail_out = kBufferSize;\n            _ztream.next_out = _hOutput.AddrOfPinnedObject();\n        }\n\n        /// <summary>\n        /// Updates the running checksum property\n        /// </summary>\n        /// <param name=\"newSum\">The new checksum value</param>\n        protected void setChecksum(uint newSum)\n        {\n            _checksum = newSum;\n        }\n        #endregion\n\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/dotzlib/DotZLib/Deflater.cs",
    "content": "//\n//  Copyright Henrik Ravn 2004\n//\n// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\n// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n\nusing System;\nusing System.Diagnostics;\nusing System.Runtime.InteropServices;\n\nnamespace DotZLib\n{\n\n    /// <summary>\n    /// Implements a data compressor, using the deflate algorithm in the ZLib dll\n    /// </summary>\n\tpublic sealed class Deflater : CodecBase\n\t{\n        #region Dll imports\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]\n        private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size);\n\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern int deflate(ref ZStream sz, int flush);\n\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern int deflateReset(ref ZStream sz);\n\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern int deflateEnd(ref ZStream sz);\n        #endregion\n\n        /// <summary>\n        /// Constructs an new instance of the <c>Deflater</c>\n        /// </summary>\n        /// <param name=\"level\">The compression level to use for this <c>Deflater</c></param>\n\t\tpublic Deflater(CompressLevel level) : base()\n\t\t{\n            int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream));\n            if (retval != 0)\n                throw new ZLibException(retval, \"Could not initialize deflater\");\n\n            resetOutput();\n\t\t}\n\n        /// <summary>\n        /// Adds more data to the codec to be processed.\n        /// </summary>\n        /// <param name=\"data\">Byte array containing the data to be added to the codec</param>\n        /// <param name=\"offset\">The index of the first byte to add from <c>data</c></param>\n        /// <param name=\"count\">The number of bytes to add</param>\n        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>\n        public override void Add(byte[] data, int offset, int count)\n        {\n            if (data == null) throw new ArgumentNullException();\n            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();\n            if ((offset+count) > data.Length) throw new ArgumentException();\n\n            int total = count;\n            int inputIndex = offset;\n            int err = 0;\n\n            while (err >= 0 && inputIndex < total)\n            {\n                copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));\n                while (err >= 0 && _ztream.avail_in > 0)\n                {\n                    err = deflate(ref _ztream, (int)FlushTypes.None);\n                    if (err == 0)\n                        while (_ztream.avail_out == 0)\n                        {\n                            OnDataAvailable();\n                            err = deflate(ref _ztream, (int)FlushTypes.None);\n                        }\n                    inputIndex += (int)_ztream.total_in;\n                }\n            }\n            setChecksum( _ztream.adler );\n        }\n\n\n        /// <summary>\n        /// Finishes up any pending data that needs to be processed and handled.\n        /// </summary>\n        public override void Finish()\n        {\n            int err;\n            do\n            {\n                err = deflate(ref _ztream, (int)FlushTypes.Finish);\n                OnDataAvailable();\n            }\n            while (err == 0);\n            setChecksum( _ztream.adler );\n            deflateReset(ref _ztream);\n            resetOutput();\n        }\n\n        /// <summary>\n        /// Closes the internal zlib deflate stream\n        /// </summary>\n        protected override void CleanUp() { deflateEnd(ref _ztream); }\n\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/dotzlib/DotZLib/DotZLib.cs",
    "content": "//\n//  Copyright Henrik Ravn 2004\n//\n// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\n// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n\nusing System;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\n\nnamespace DotZLib\n{\n\n    #region Internal types\n\n    /// <summary>\n    /// Defines constants for the various flush types used with zlib\n    /// </summary>\n    internal enum FlushTypes\n    {\n        None,  Partial,  Sync,  Full,  Finish,  Block\n    }\n\n    #region ZStream structure\n    // internal mapping of the zlib zstream structure for marshalling\n    [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)]\n    internal struct ZStream\n    {\n        public IntPtr next_in;\n        public uint avail_in;\n        public uint total_in;\n\n        public IntPtr next_out;\n        public uint avail_out;\n        public uint total_out;\n\n        [MarshalAs(UnmanagedType.LPStr)]\n        string msg;\n        uint state;\n\n        uint zalloc;\n        uint zfree;\n        uint opaque;\n\n        int data_type;\n        public uint adler;\n        uint reserved;\n    }\n\n    #endregion\n\n    #endregion\n\n    #region Public enums\n    /// <summary>\n    /// Defines constants for the available compression levels in zlib\n    /// </summary>\n    public enum CompressLevel : int\n    {\n        /// <summary>\n        /// The default compression level with a reasonable compromise between compression and speed\n        /// </summary>\n        Default = -1,\n        /// <summary>\n        /// No compression at all. The data are passed straight through.\n        /// </summary>\n        None = 0,\n        /// <summary>\n        /// The maximum compression rate available.\n        /// </summary>\n        Best = 9,\n        /// <summary>\n        /// The fastest available compression level.\n        /// </summary>\n        Fastest = 1\n    }\n    #endregion\n\n    #region Exception classes\n    /// <summary>\n    /// The exception that is thrown when an error occurs on the zlib dll\n    /// </summary>\n    public class ZLibException : ApplicationException\n    {\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"ZLibException\"/> class with a specified\n        /// error message and error code\n        /// </summary>\n        /// <param name=\"errorCode\">The zlib error code that caused the exception</param>\n        /// <param name=\"msg\">A message that (hopefully) describes the error</param>\n        public ZLibException(int errorCode, string msg) : base(String.Format(\"ZLib error {0} {1}\", errorCode, msg))\n        {\n        }\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"ZLibException\"/> class with a specified\n        /// error code\n        /// </summary>\n        /// <param name=\"errorCode\">The zlib error code that caused the exception</param>\n        public ZLibException(int errorCode) : base(String.Format(\"ZLib error {0}\", errorCode))\n        {\n        }\n    }\n    #endregion\n\n    #region Interfaces\n\n    /// <summary>\n    /// Declares methods and properties that enables a running checksum to be calculated\n    /// </summary>\n    public interface ChecksumGenerator\n    {\n        /// <summary>\n        /// Gets the current value of the checksum\n        /// </summary>\n        uint Value { get; }\n\n        /// <summary>\n        /// Clears the current checksum to 0\n        /// </summary>\n        void Reset();\n\n        /// <summary>\n        /// Updates the current checksum with an array of bytes\n        /// </summary>\n        /// <param name=\"data\">The data to update the checksum with</param>\n        void Update(byte[] data);\n\n        /// <summary>\n        /// Updates the current checksum with part of an array of bytes\n        /// </summary>\n        /// <param name=\"data\">The data to update the checksum with</param>\n        /// <param name=\"offset\">Where in <c>data</c> to start updating</param>\n        /// <param name=\"count\">The number of bytes from <c>data</c> to use</param>\n        /// <exception cref=\"ArgumentException\">The sum of offset and count is larger than the length of <c>data</c></exception>\n        /// <exception cref=\"ArgumentNullException\"><c>data</c> is a null reference</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\">Offset or count is negative.</exception>\n        void Update(byte[] data, int offset, int count);\n\n        /// <summary>\n        /// Updates the current checksum with the data from a string\n        /// </summary>\n        /// <param name=\"data\">The string to update the checksum with</param>\n        /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>\n        void Update(string data);\n\n        /// <summary>\n        /// Updates the current checksum with the data from a string, using a specific encoding\n        /// </summary>\n        /// <param name=\"data\">The string to update the checksum with</param>\n        /// <param name=\"encoding\">The encoding to use</param>\n        void Update(string data, Encoding encoding);\n    }\n\n\n    /// <summary>\n    /// Represents the method that will be called from a codec when new data\n    /// are available.\n    /// </summary>\n    /// <paramref name=\"data\">The byte array containing the processed data</paramref>\n    /// <paramref name=\"startIndex\">The index of the first processed byte in <c>data</c></paramref>\n    /// <paramref name=\"count\">The number of processed bytes available</paramref>\n    /// <remarks>On return from this method, the data may be overwritten, so grab it while you can.\n    /// You cannot assume that startIndex will be zero.\n    /// </remarks>\n    public delegate void DataAvailableHandler(byte[] data, int startIndex, int count);\n\n    /// <summary>\n    /// Declares methods and events for implementing compressors/decompressors\n    /// </summary>\n    public interface Codec\n    {\n        /// <summary>\n        /// Occurs when more processed data are available.\n        /// </summary>\n        event DataAvailableHandler DataAvailable;\n\n        /// <summary>\n        /// Adds more data to the codec to be processed.\n        /// </summary>\n        /// <param name=\"data\">Byte array containing the data to be added to the codec</param>\n        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>\n        void Add(byte[] data);\n\n        /// <summary>\n        /// Adds more data to the codec to be processed.\n        /// </summary>\n        /// <param name=\"data\">Byte array containing the data to be added to the codec</param>\n        /// <param name=\"offset\">The index of the first byte to add from <c>data</c></param>\n        /// <param name=\"count\">The number of bytes to add</param>\n        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>\n        void Add(byte[] data, int offset, int count);\n\n        /// <summary>\n        /// Finishes up any pending data that needs to be processed and handled.\n        /// </summary>\n        void Finish();\n\n        /// <summary>\n        /// Gets the checksum of the data that has been added so far\n        /// </summary>\n        uint Checksum { get; }\n\n\n    }\n\n    #endregion\n\n    #region Classes\n    /// <summary>\n    /// Encapsulates general information about the ZLib library\n    /// </summary>\n    public class Info\n    {\n        #region DLL imports\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern uint zlibCompileFlags();\n\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern string zlibVersion();\n        #endregion\n\n        #region Private stuff\n        private uint _flags;\n\n        // helper function that unpacks a bitsize mask\n        private static int bitSize(uint bits)\n        {\n            switch (bits)\n            {\n                case 0: return 16;\n                case 1: return 32;\n                case 2: return 64;\n            }\n            return -1;\n        }\n        #endregion\n\n        /// <summary>\n        /// Constructs an instance of the <c>Info</c> class.\n        /// </summary>\n        public Info()\n        {\n            _flags = zlibCompileFlags();\n        }\n\n        /// <summary>\n        /// True if the library is compiled with debug info\n        /// </summary>\n        public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } }\n\n        /// <summary>\n        /// True if the library is compiled with assembly optimizations\n        /// </summary>\n        public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } }\n\n        /// <summary>\n        /// Gets the size of the unsigned int that was compiled into Zlib\n        /// </summary>\n        public int SizeOfUInt { get { return bitSize(_flags & 3); } }\n\n        /// <summary>\n        /// Gets the size of the unsigned long that was compiled into Zlib\n        /// </summary>\n        public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } }\n\n        /// <summary>\n        /// Gets the size of the pointers that were compiled into Zlib\n        /// </summary>\n        public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } }\n\n        /// <summary>\n        /// Gets the size of the z_off_t type that was compiled into Zlib\n        /// </summary>\n        public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } }\n\n        /// <summary>\n        /// Gets the version of ZLib as a string, e.g. \"1.2.1\"\n        /// </summary>\n        public static string Version { get { return zlibVersion(); } }\n    }\n\n    #endregion\n\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/dotzlib/DotZLib/DotZLib.csproj",
    "content": "<VisualStudioProject>\n    <CSHARP\n        ProjectType = \"Local\"\n        ProductVersion = \"7.10.3077\"\n        SchemaVersion = \"2.0\"\n        ProjectGuid = \"{BB1EE0B1-1808-46CB-B786-949D91117FC5}\"\n    >\n        <Build>\n            <Settings\n                ApplicationIcon = \"\"\n                AssemblyKeyContainerName = \"\"\n                AssemblyName = \"DotZLib\"\n                AssemblyOriginatorKeyFile = \"\"\n                DefaultClientScript = \"JScript\"\n                DefaultHTMLPageLayout = \"Grid\"\n                DefaultTargetSchema = \"IE50\"\n                DelaySign = \"false\"\n                OutputType = \"Library\"\n                PreBuildEvent = \"\"\n                PostBuildEvent = \"\"\n                RootNamespace = \"DotZLib\"\n                RunPostBuildEvent = \"OnBuildSuccess\"\n                StartupObject = \"\"\n            >\n                <Config\n                    Name = \"Debug\"\n                    AllowUnsafeBlocks = \"false\"\n                    BaseAddress = \"285212672\"\n                    CheckForOverflowUnderflow = \"false\"\n                    ConfigurationOverrideFile = \"\"\n                    DefineConstants = \"DEBUG;TRACE\"\n                    DocumentationFile = \"docs\\DotZLib.xml\"\n                    DebugSymbols = \"true\"\n                    FileAlignment = \"4096\"\n                    IncrementalBuild = \"false\"\n                    NoStdLib = \"false\"\n                    NoWarn = \"1591\"\n                    Optimize = \"false\"\n                    OutputPath = \"bin\\Debug\\\"\n                    RegisterForComInterop = \"false\"\n                    RemoveIntegerChecks = \"false\"\n                    TreatWarningsAsErrors = \"false\"\n                    WarningLevel = \"4\"\n                />\n                <Config\n                    Name = \"Release\"\n                    AllowUnsafeBlocks = \"false\"\n                    BaseAddress = \"285212672\"\n                    CheckForOverflowUnderflow = \"false\"\n                    ConfigurationOverrideFile = \"\"\n                    DefineConstants = \"TRACE\"\n                    DocumentationFile = \"docs\\DotZLib.xml\"\n                    DebugSymbols = \"false\"\n                    FileAlignment = \"4096\"\n                    IncrementalBuild = \"false\"\n                    NoStdLib = \"false\"\n                    NoWarn = \"\"\n                    Optimize = \"true\"\n                    OutputPath = \"bin\\Release\\\"\n                    RegisterForComInterop = \"false\"\n                    RemoveIntegerChecks = \"false\"\n                    TreatWarningsAsErrors = \"false\"\n                    WarningLevel = \"4\"\n                />\n            </Settings>\n            <References>\n                <Reference\n                    Name = \"System\"\n                    AssemblyName = \"System\"\n                    HintPath = \"C:\\WINNT\\Microsoft.NET\\Framework\\v1.1.4322\\System.dll\"\n                />\n                <Reference\n                    Name = \"System.Data\"\n                    AssemblyName = \"System.Data\"\n                    HintPath = \"C:\\WINNT\\Microsoft.NET\\Framework\\v1.1.4322\\System.Data.dll\"\n                />\n                <Reference\n                    Name = \"System.XML\"\n                    AssemblyName = \"System.Xml\"\n                    HintPath = \"C:\\WINNT\\Microsoft.NET\\Framework\\v1.1.4322\\System.XML.dll\"\n                />\n                <Reference\n                    Name = \"nunit.framework\"\n                    AssemblyName = \"nunit.framework\"\n                    HintPath = \"E:\\apps\\NUnit V2.1\\\\bin\\nunit.framework.dll\"\n                    AssemblyFolderKey = \"hklm\\dn\\nunit.framework\"\n                />\n            </References>\n        </Build>\n        <Files>\n            <Include>\n                <File\n                    RelPath = \"AssemblyInfo.cs\"\n                    SubType = \"Code\"\n                    BuildAction = \"Compile\"\n                />\n                <File\n                    RelPath = \"ChecksumImpl.cs\"\n                    SubType = \"Code\"\n                    BuildAction = \"Compile\"\n                />\n                <File\n                    RelPath = \"CircularBuffer.cs\"\n                    SubType = \"Code\"\n                    BuildAction = \"Compile\"\n                />\n                <File\n                    RelPath = \"CodecBase.cs\"\n                    SubType = \"Code\"\n                    BuildAction = \"Compile\"\n                />\n                <File\n                    RelPath = \"Deflater.cs\"\n                    SubType = \"Code\"\n                    BuildAction = \"Compile\"\n                />\n                <File\n                    RelPath = \"DotZLib.cs\"\n                    SubType = \"Code\"\n                    BuildAction = \"Compile\"\n                />\n                <File\n                    RelPath = \"GZipStream.cs\"\n                    SubType = \"Code\"\n                    BuildAction = \"Compile\"\n                />\n                <File\n                    RelPath = \"Inflater.cs\"\n                    SubType = \"Code\"\n                    BuildAction = \"Compile\"\n                />\n                <File\n                    RelPath = \"UnitTests.cs\"\n                    SubType = \"Code\"\n                    BuildAction = \"Compile\"\n                />\n            </Include>\n        </Files>\n    </CSHARP>\n</VisualStudioProject>\n\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/dotzlib/DotZLib/GZipStream.cs",
    "content": "//\n//  Copyright Henrik Ravn 2004\n//\n// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\n// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n\nusing System;\nusing System.IO;\nusing System.Runtime.InteropServices;\n\nnamespace DotZLib\n{\n\t/// <summary>\n\t/// Implements a compressed <see cref=\"Stream\"/>, in GZip (.gz) format.\n\t/// </summary>\n\tpublic class GZipStream : Stream, IDisposable\n\t{\n        #region Dll Imports\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]\n        private static extern IntPtr gzopen(string name, string mode);\n\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern int gzclose(IntPtr gzFile);\n\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern int gzwrite(IntPtr gzFile, int data, int length);\n\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern int gzread(IntPtr gzFile, int data, int length);\n\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern int gzgetc(IntPtr gzFile);\n\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern int gzputc(IntPtr gzFile, int c);\n\n        #endregion\n\n        #region Private data\n        private IntPtr _gzFile;\n        private bool _isDisposed = false;\n        private bool _isWriting;\n        #endregion\n\n        #region Constructors\n        /// <summary>\n        /// Creates a new file as a writeable GZipStream\n        /// </summary>\n        /// <param name=\"fileName\">The name of the compressed file to create</param>\n        /// <param name=\"level\">The compression level to use when adding data</param>\n        /// <exception cref=\"ZLibException\">If an error occurred in the internal zlib function</exception>\n\t\tpublic GZipStream(string fileName, CompressLevel level)\n\t\t{\n            _isWriting = true;\n            _gzFile = gzopen(fileName, String.Format(\"wb{0}\", (int)level));\n            if (_gzFile == IntPtr.Zero)\n                throw new ZLibException(-1, \"Could not open \" + fileName);\n\t\t}\n\n        /// <summary>\n        /// Opens an existing file as a readable GZipStream\n        /// </summary>\n        /// <param name=\"fileName\">The name of the file to open</param>\n        /// <exception cref=\"ZLibException\">If an error occurred in the internal zlib function</exception>\n        public GZipStream(string fileName)\n        {\n            _isWriting = false;\n            _gzFile = gzopen(fileName, \"rb\");\n            if (_gzFile == IntPtr.Zero)\n                throw new ZLibException(-1, \"Could not open \" + fileName);\n\n        }\n        #endregion\n\n        #region Access properties\n        /// <summary>\n        /// Returns true of this stream can be read from, false otherwise\n        /// </summary>\n        public override bool CanRead\n        {\n            get\n            {\n                return !_isWriting;\n            }\n        }\n\n\n        /// <summary>\n        /// Returns false.\n        /// </summary>\n        public override bool CanSeek\n        {\n            get\n            {\n                return false;\n            }\n        }\n\n        /// <summary>\n        /// Returns true if this tsream is writeable, false otherwise\n        /// </summary>\n        public override bool CanWrite\n        {\n            get\n            {\n                return _isWriting;\n            }\n        }\n        #endregion\n\n        #region Destructor & IDispose stuff\n\n        /// <summary>\n        /// Destroys this instance\n        /// </summary>\n        ~GZipStream()\n        {\n            cleanUp(false);\n        }\n\n        /// <summary>\n        /// Closes the external file handle\n        /// </summary>\n        public void Dispose()\n        {\n            cleanUp(true);\n        }\n\n        // Does the actual closing of the file handle.\n        private void cleanUp(bool isDisposing)\n        {\n            if (!_isDisposed)\n            {\n                gzclose(_gzFile);\n                _isDisposed = true;\n            }\n        }\n        #endregion\n\n        #region Basic reading and writing\n        /// <summary>\n        /// Attempts to read a number of bytes from the stream.\n        /// </summary>\n        /// <param name=\"buffer\">The destination data buffer</param>\n        /// <param name=\"offset\">The index of the first destination byte in <c>buffer</c></param>\n        /// <param name=\"count\">The number of bytes requested</param>\n        /// <returns>The number of bytes read</returns>\n        /// <exception cref=\"ArgumentNullException\">If <c>buffer</c> is null</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\">If <c>count</c> or <c>offset</c> are negative</exception>\n        /// <exception cref=\"ArgumentException\">If <c>offset</c>  + <c>count</c> is &gt; buffer.Length</exception>\n        /// <exception cref=\"NotSupportedException\">If this stream is not readable.</exception>\n        /// <exception cref=\"ObjectDisposedException\">If this stream has been disposed.</exception>\n        public override int Read(byte[] buffer, int offset, int count)\n        {\n            if (!CanRead) throw new NotSupportedException();\n            if (buffer == null) throw new ArgumentNullException();\n            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();\n            if ((offset+count) > buffer.Length) throw new ArgumentException();\n            if (_isDisposed) throw new ObjectDisposedException(\"GZipStream\");\n\n            GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);\n            int result;\n            try\n            {\n                result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);\n                if (result < 0)\n                    throw new IOException();\n            }\n            finally\n            {\n                h.Free();\n            }\n            return result;\n        }\n\n        /// <summary>\n        /// Attempts to read a single byte from the stream.\n        /// </summary>\n        /// <returns>The byte that was read, or -1 in case of error or End-Of-File</returns>\n        public override int ReadByte()\n        {\n            if (!CanRead) throw new NotSupportedException();\n            if (_isDisposed) throw new ObjectDisposedException(\"GZipStream\");\n            return gzgetc(_gzFile);\n        }\n\n        /// <summary>\n        /// Writes a number of bytes to the stream\n        /// </summary>\n        /// <param name=\"buffer\"></param>\n        /// <param name=\"offset\"></param>\n        /// <param name=\"count\"></param>\n        /// <exception cref=\"ArgumentNullException\">If <c>buffer</c> is null</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\">If <c>count</c> or <c>offset</c> are negative</exception>\n        /// <exception cref=\"ArgumentException\">If <c>offset</c>  + <c>count</c> is &gt; buffer.Length</exception>\n        /// <exception cref=\"NotSupportedException\">If this stream is not writeable.</exception>\n        /// <exception cref=\"ObjectDisposedException\">If this stream has been disposed.</exception>\n        public override void Write(byte[] buffer, int offset, int count)\n        {\n            if (!CanWrite) throw new NotSupportedException();\n            if (buffer == null) throw new ArgumentNullException();\n            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();\n            if ((offset+count) > buffer.Length) throw new ArgumentException();\n            if (_isDisposed) throw new ObjectDisposedException(\"GZipStream\");\n\n            GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);\n            try\n            {\n                int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);\n                if (result < 0)\n                    throw new IOException();\n            }\n            finally\n            {\n                h.Free();\n            }\n        }\n\n        /// <summary>\n        /// Writes a single byte to the stream\n        /// </summary>\n        /// <param name=\"value\">The byte to add to the stream.</param>\n        /// <exception cref=\"NotSupportedException\">If this stream is not writeable.</exception>\n        /// <exception cref=\"ObjectDisposedException\">If this stream has been disposed.</exception>\n        public override void WriteByte(byte value)\n        {\n            if (!CanWrite) throw new NotSupportedException();\n            if (_isDisposed) throw new ObjectDisposedException(\"GZipStream\");\n\n            int result = gzputc(_gzFile, (int)value);\n            if (result < 0)\n                throw new IOException();\n        }\n        #endregion\n\n        #region Position & length stuff\n        /// <summary>\n        /// Not supported.\n        /// </summary>\n        /// <param name=\"value\"></param>\n        /// <exception cref=\"NotSupportedException\">Always thrown</exception>\n        public override void SetLength(long value)\n        {\n            throw new NotSupportedException();\n        }\n\n        /// <summary>\n        ///  Not suppported.\n        /// </summary>\n        /// <param name=\"offset\"></param>\n        /// <param name=\"origin\"></param>\n        /// <returns></returns>\n        /// <exception cref=\"NotSupportedException\">Always thrown</exception>\n        public override long Seek(long offset, SeekOrigin origin)\n        {\n            throw new NotSupportedException();\n        }\n\n        /// <summary>\n        /// Flushes the <c>GZipStream</c>.\n        /// </summary>\n        /// <remarks>In this implementation, this method does nothing. This is because excessive\n        /// flushing may degrade the achievable compression rates.</remarks>\n        public override void Flush()\n        {\n            // left empty on purpose\n        }\n\n        /// <summary>\n        /// Gets/sets the current position in the <c>GZipStream</c>. Not suppported.\n        /// </summary>\n        /// <remarks>In this implementation this property is not supported</remarks>\n        /// <exception cref=\"NotSupportedException\">Always thrown</exception>\n        public override long Position\n        {\n            get\n            {\n                throw new NotSupportedException();\n            }\n            set\n            {\n                throw new NotSupportedException();\n            }\n        }\n\n        /// <summary>\n        /// Gets the size of the stream. Not suppported.\n        /// </summary>\n        /// <remarks>In this implementation this property is not supported</remarks>\n        /// <exception cref=\"NotSupportedException\">Always thrown</exception>\n        public override long Length\n        {\n            get\n            {\n                throw new NotSupportedException();\n            }\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/dotzlib/DotZLib/Inflater.cs",
    "content": "//\n//  Copyright Henrik Ravn 2004\n//\n// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\n// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n\nusing System;\nusing System.Diagnostics;\nusing System.Runtime.InteropServices;\n\nnamespace DotZLib\n{\n\n    /// <summary>\n    /// Implements a data decompressor, using the inflate algorithm in the ZLib dll\n    /// </summary>\n    public class Inflater : CodecBase\n\t{\n        #region Dll imports\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]\n        private static extern int inflateInit_(ref ZStream sz, string vs, int size);\n\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern int inflate(ref ZStream sz, int flush);\n\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern int inflateReset(ref ZStream sz);\n\n        [DllImport(\"ZLIB1.dll\", CallingConvention=CallingConvention.Cdecl)]\n        private static extern int inflateEnd(ref ZStream sz);\n        #endregion\n\n        /// <summary>\n        /// Constructs an new instance of the <c>Inflater</c>\n        /// </summary>\n        public Inflater() : base()\n\t\t{\n            int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream));\n            if (retval != 0)\n                throw new ZLibException(retval, \"Could not initialize inflater\");\n\n            resetOutput();\n        }\n\n\n        /// <summary>\n        /// Adds more data to the codec to be processed.\n        /// </summary>\n        /// <param name=\"data\">Byte array containing the data to be added to the codec</param>\n        /// <param name=\"offset\">The index of the first byte to add from <c>data</c></param>\n        /// <param name=\"count\">The number of bytes to add</param>\n        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>\n        public override void Add(byte[] data, int offset, int count)\n        {\n            if (data == null) throw new ArgumentNullException();\n            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();\n            if ((offset+count) > data.Length) throw new ArgumentException();\n\n            int total = count;\n            int inputIndex = offset;\n            int err = 0;\n\n            while (err >= 0 && inputIndex < total)\n            {\n                copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));\n                err = inflate(ref _ztream, (int)FlushTypes.None);\n                if (err == 0)\n                    while (_ztream.avail_out == 0)\n                    {\n                        OnDataAvailable();\n                        err = inflate(ref _ztream, (int)FlushTypes.None);\n                    }\n\n                inputIndex += (int)_ztream.total_in;\n            }\n            setChecksum( _ztream.adler );\n        }\n\n\n        /// <summary>\n        /// Finishes up any pending data that needs to be processed and handled.\n        /// </summary>\n        public override void Finish()\n        {\n            int err;\n            do\n            {\n                err = inflate(ref _ztream, (int)FlushTypes.Finish);\n                OnDataAvailable();\n            }\n            while (err == 0);\n            setChecksum( _ztream.adler );\n            inflateReset(ref _ztream);\n            resetOutput();\n        }\n\n        /// <summary>\n        /// Closes the internal zlib inflate stream\n        /// </summary>\n        protected override void CleanUp() { inflateEnd(ref _ztream); }\n\n\n\t}\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/dotzlib/DotZLib/UnitTests.cs",
    "content": "//\n// © Copyright Henrik Ravn 2004\n//\n// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\n// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n\nusing System;\nusing System.Collections;\nusing System.IO;\n\n// uncomment the define below to include unit tests\n//#define nunit\n#if nunit\nusing NUnit.Framework;\n\n// Unit tests for the DotZLib class library\n// ----------------------------------------\n//\n// Use this with NUnit 2 from http://www.nunit.org\n//\n\nnamespace DotZLibTests\n{\n    using DotZLib;\n\n    // helper methods\n    internal class Utils\n    {\n        public static bool byteArrEqual( byte[] lhs, byte[] rhs )\n        {\n            if (lhs.Length != rhs.Length)\n                return false;\n            for (int i = lhs.Length-1; i >= 0; --i)\n                if (lhs[i] != rhs[i])\n                    return false;\n            return true;\n        }\n\n    }\n\n\n    [TestFixture]\n    public class CircBufferTests\n    {\n        #region Circular buffer tests\n        [Test]\n        public void SinglePutGet()\n        {\n            CircularBuffer buf = new CircularBuffer(10);\n            Assert.AreEqual( 0, buf.Size );\n            Assert.AreEqual( -1, buf.Get() );\n\n            Assert.IsTrue(buf.Put( 1 ));\n            Assert.AreEqual( 1, buf.Size );\n            Assert.AreEqual( 1, buf.Get() );\n            Assert.AreEqual( 0, buf.Size );\n            Assert.AreEqual( -1, buf.Get() );\n        }\n\n        [Test]\n        public void BlockPutGet()\n        {\n            CircularBuffer buf = new CircularBuffer(10);\n            byte[] arr = {1,2,3,4,5,6,7,8,9,10};\n            Assert.AreEqual( 10, buf.Put(arr,0,10) );\n            Assert.AreEqual( 10, buf.Size );\n            Assert.IsFalse( buf.Put(11) );\n            Assert.AreEqual( 1, buf.Get() );\n            Assert.IsTrue( buf.Put(11) );\n\n            byte[] arr2 = (byte[])arr.Clone();\n            Assert.AreEqual( 9, buf.Get(arr2,1,9) );\n            Assert.IsTrue( Utils.byteArrEqual(arr,arr2) );\n        }\n\n        #endregion\n    }\n\n    [TestFixture]\n    public class ChecksumTests\n    {\n        #region CRC32 Tests\n        [Test]\n        public void CRC32_Null()\n        {\n            CRC32Checksum crc32 = new CRC32Checksum();\n            Assert.AreEqual( 0, crc32.Value );\n\n            crc32 = new CRC32Checksum(1);\n            Assert.AreEqual( 1, crc32.Value );\n\n            crc32 = new CRC32Checksum(556);\n            Assert.AreEqual( 556, crc32.Value );\n        }\n\n        [Test]\n        public void CRC32_Data()\n        {\n            CRC32Checksum crc32 = new CRC32Checksum();\n            byte[] data = { 1,2,3,4,5,6,7 };\n            crc32.Update(data);\n            Assert.AreEqual( 0x70e46888, crc32.Value  );\n\n            crc32 = new CRC32Checksum();\n            crc32.Update(\"penguin\");\n            Assert.AreEqual( 0x0e5c1a120, crc32.Value );\n\n            crc32 = new CRC32Checksum(1);\n            crc32.Update(\"penguin\");\n            Assert.AreEqual(0x43b6aa94, crc32.Value);\n\n        }\n        #endregion\n\n        #region Adler tests\n\n        [Test]\n        public void Adler_Null()\n        {\n            AdlerChecksum adler = new AdlerChecksum();\n            Assert.AreEqual(0, adler.Value);\n\n            adler = new AdlerChecksum(1);\n            Assert.AreEqual( 1, adler.Value );\n\n            adler = new AdlerChecksum(556);\n            Assert.AreEqual( 556, adler.Value );\n        }\n\n        [Test]\n        public void Adler_Data()\n        {\n            AdlerChecksum adler = new AdlerChecksum(1);\n            byte[] data = { 1,2,3,4,5,6,7 };\n            adler.Update(data);\n            Assert.AreEqual( 0x5b001d, adler.Value  );\n\n            adler = new AdlerChecksum();\n            adler.Update(\"penguin\");\n            Assert.AreEqual(0x0bcf02f6, adler.Value );\n\n            adler = new AdlerChecksum(1);\n            adler.Update(\"penguin\");\n            Assert.AreEqual(0x0bd602f7, adler.Value);\n\n        }\n        #endregion\n    }\n\n    [TestFixture]\n    public class InfoTests\n    {\n        #region Info tests\n        [Test]\n        public void Info_Version()\n        {\n            Info info = new Info();\n            Assert.AreEqual(\"1.2.8\", Info.Version);\n            Assert.AreEqual(32, info.SizeOfUInt);\n            Assert.AreEqual(32, info.SizeOfULong);\n            Assert.AreEqual(32, info.SizeOfPointer);\n            Assert.AreEqual(32, info.SizeOfOffset);\n        }\n        #endregion\n    }\n\n    [TestFixture]\n    public class DeflateInflateTests\n    {\n        #region Deflate tests\n        [Test]\n        public void Deflate_Init()\n        {\n            using (Deflater def = new Deflater(CompressLevel.Default))\n            {\n            }\n        }\n\n        private ArrayList compressedData = new ArrayList();\n        private uint adler1;\n\n        private ArrayList uncompressedData = new ArrayList();\n        private uint adler2;\n\n        public void CDataAvail(byte[] data, int startIndex, int count)\n        {\n            for (int i = 0; i < count; ++i)\n                compressedData.Add(data[i+startIndex]);\n        }\n\n        [Test]\n        public void Deflate_Compress()\n        {\n            compressedData.Clear();\n\n            byte[] testData = new byte[35000];\n            for (int i = 0; i < testData.Length; ++i)\n                testData[i] = 5;\n\n            using (Deflater def = new Deflater((CompressLevel)5))\n            {\n                def.DataAvailable += new DataAvailableHandler(CDataAvail);\n                def.Add(testData);\n                def.Finish();\n                adler1 = def.Checksum;\n            }\n        }\n        #endregion\n\n        #region Inflate tests\n        [Test]\n        public void Inflate_Init()\n        {\n            using (Inflater inf = new Inflater())\n            {\n            }\n        }\n\n        private void DDataAvail(byte[] data, int startIndex, int count)\n        {\n            for (int i = 0; i < count; ++i)\n                uncompressedData.Add(data[i+startIndex]);\n        }\n\n        [Test]\n        public void Inflate_Expand()\n        {\n            uncompressedData.Clear();\n\n            using (Inflater inf = new Inflater())\n            {\n                inf.DataAvailable += new DataAvailableHandler(DDataAvail);\n                inf.Add((byte[])compressedData.ToArray(typeof(byte)));\n                inf.Finish();\n                adler2 = inf.Checksum;\n            }\n            Assert.AreEqual( adler1, adler2 );\n        }\n        #endregion\n    }\n\n    [TestFixture]\n    public class GZipStreamTests\n    {\n        #region GZipStream test\n        [Test]\n        public void GZipStream_WriteRead()\n        {\n            using (GZipStream gzOut = new GZipStream(\"gzstream.gz\", CompressLevel.Best))\n            {\n                BinaryWriter writer = new BinaryWriter(gzOut);\n                writer.Write(\"hi there\");\n                writer.Write(Math.PI);\n                writer.Write(42);\n            }\n\n            using (GZipStream gzIn = new GZipStream(\"gzstream.gz\"))\n            {\n                BinaryReader reader = new BinaryReader(gzIn);\n                string s = reader.ReadString();\n                Assert.AreEqual(\"hi there\",s);\n                double d = reader.ReadDouble();\n                Assert.AreEqual(Math.PI, d);\n                int i = reader.ReadInt32();\n                Assert.AreEqual(42,i);\n            }\n\n        }\n        #endregion\n\t}\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/dotzlib/DotZLib.build",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<project name=\"DotZLib\" default=\"build\" basedir=\"./DotZLib\">\n\t<description>A .Net wrapper library around ZLib1.dll</description>\n\n\t<property name=\"nunit.location\" value=\"c:/program files/NUnit V2.1/bin\" />\n\t<property name=\"build.root\" value=\"bin\" />\n\n\t<property name=\"debug\" value=\"true\" />\n\t<property name=\"nunit\" value=\"true\" />\n\n\t<property name=\"build.folder\" value=\"${build.root}/debug/\" if=\"${debug}\" />\n\t<property name=\"build.folder\" value=\"${build.root}/release/\" unless=\"${debug}\" />\n\n\t<target name=\"clean\" description=\"Remove all generated files\">\n\t\t<delete dir=\"${build.root}\" failonerror=\"false\" />\n\t</target>\n\n\t<target name=\"build\" description=\"compiles the source code\">\n\n\t\t<mkdir dir=\"${build.folder}\" />\n\t\t<csc target=\"library\" output=\"${build.folder}DotZLib.dll\" debug=\"${debug}\">\n\t\t\t<references basedir=\"${nunit.location}\">\n\t\t\t\t<includes if=\"${nunit}\" name=\"nunit.framework.dll\" />\n\t\t\t</references>\n\t\t\t<sources>\n\t\t\t\t<includes name=\"*.cs\" />\n\t\t\t\t<excludes name=\"UnitTests.cs\" unless=\"${nunit}\" />\n\t\t\t</sources>\n\t\t\t<arg value=\"/d:nunit\" if=\"${nunit}\" />\n\t\t</csc>\n\t</target>\n\n</project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/dotzlib/DotZLib.sln",
    "content": "Microsoft Visual Studio Solution File, Format Version 8.00\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"DotZLib\", \"DotZLib\\DotZLib.csproj\", \"{BB1EE0B1-1808-46CB-B786-949D91117FC5}\"\n\tProjectSection(ProjectDependencies) = postProject\n\tEndProjectSection\nEndProject\nGlobal\n\tGlobalSection(SolutionConfiguration) = preSolution\n\t\tDebug = Debug\n\t\tRelease = Release\n\tEndGlobalSection\n\tGlobalSection(ProjectConfiguration) = postSolution\n\t\t{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.ActiveCfg = Debug|.NET\n\t\t{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.Build.0 = Debug|.NET\n\t\t{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.ActiveCfg = Release|.NET\n\t\t{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.Build.0 = Release|.NET\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityAddIns) = postSolution\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/dotzlib/LICENSE_1_0.txt",
    "content": "Boost Software License - Version 1.0 - August 17th, 2003\n\nPermission is hereby granted, free of charge, to any person or organization\nobtaining a copy of the software and accompanying documentation covered by\nthis license (the \"Software\") to use, reproduce, display, distribute,\nexecute, and transmit the Software, and to prepare derivative works of the\nSoftware, and to permit third-parties to whom the Software is furnished to\ndo so, all subject to the following:\n\nThe copyright notices in the Software and this entire statement, including\nthe above license grant, this restriction and the following disclaimer,\nmust be included in all copies of the Software, in whole or in part, and\nall derivative works of the Software, unless such copies or derivative\nworks are solely in the form of machine-executable object code generated by\na source language processor.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\nSHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\nFOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE."
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/dotzlib/readme.txt",
    "content": "This directory contains a .Net wrapper class library for the ZLib1.dll\n\nThe wrapper includes support for inflating/deflating memory buffers,\n.Net streaming wrappers for the gz streams part of zlib, and wrappers\nfor the checksum parts of zlib. See DotZLib/UnitTests.cs for examples.\n\nDirectory structure:\n--------------------\n\nLICENSE_1_0.txt       - License file.\nreadme.txt            - This file.\nDotZLib.chm           - Class library documentation\nDotZLib.build         - NAnt build file\nDotZLib.sln           - Microsoft Visual Studio 2003 solution file\n\nDotZLib\\*.cs          - Source files for the class library\n\nUnit tests:\n-----------\nThe file DotZLib/UnitTests.cs contains unit tests for use with NUnit 2.1 or higher.\nTo include unit tests in the build, define nunit before building.\n\n\nBuild instructions:\n-------------------\n\n1. Using Visual Studio.Net 2003:\n   Open DotZLib.sln in VS.Net and build from there. Output file (DotZLib.dll)\n   will be found ./DotZLib/bin/release or ./DotZLib/bin/debug, depending on\n   you are building the release or debug version of the library. Check\n   DotZLib/UnitTests.cs for instructions on how to include unit tests in the\n   build.\n\n2. Using NAnt:\n   Open a command prompt with access to the build environment and run nant\n   in the same directory as the DotZLib.build file.\n   You can define 2 properties on the nant command-line to control the build:\n   debug={true|false} to toggle between release/debug builds (default=true).\n   nunit={true|false} to include or esclude unit tests (default=true).\n   Also the target clean will remove binaries.\n   Output file (DotZLib.dll) will be found in either ./DotZLib/bin/release\n   or ./DotZLib/bin/debug, depending on whether you are building the release\n   or debug version of the library.\n\n   Examples:\n     nant -D:debug=false -D:nunit=false\n       will build a release mode version of the library without unit tests.\n     nant\n       will build a debug version of the library with unit tests\n     nant clean\n       will remove all previously built files.\n\n\n---------------------------------\nCopyright (c) Henrik Ravn 2004\n\nUse, modification and distribution are subject to the Boost Software License, Version 1.0.\n(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/gcc_gvmat64/gvmat64.S",
    "content": "/*\n;uInt longest_match_x64(\n;    deflate_state *s,\n;    IPos cur_match);                             // current match \n\n; gvmat64.S -- Asm portion of the optimized longest_match for 32 bits x86_64\n;  (AMD64 on Athlon 64, Opteron, Phenom\n;     and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7)\n; this file is translation from gvmat64.asm to GCC 4.x (for Linux, Mac XCode)\n; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.\n;\n; File written by Gilles Vollant, by converting to assembly the longest_match\n;  from Jean-loup Gailly in deflate.c of zLib and infoZip zip.\n;  and by taking inspiration on asm686 with masm, optimised assembly code\n;        from Brian Raiter, written 1998\n;\n;  This software is provided 'as-is', without any express or implied\n;  warranty.  In no event will the authors be held liable for any damages\n;  arising from the use of this software.\n;\n;  Permission is granted to anyone to use this software for any purpose,\n;  including commercial applications, and to alter it and redistribute it\n;  freely, subject to the following restrictions:\n;\n;  1. The origin of this software must not be misrepresented; you must not\n;     claim that you wrote the original software. If you use this software\n;     in a product, an acknowledgment in the product documentation would be\n;     appreciated but is not required.\n;  2. Altered source versions must be plainly marked as such, and must not be\n;     misrepresented as being the original software\n;  3. This notice may not be removed or altered from any source distribution.\n;\n;         http://www.zlib.net\n;         http://www.winimage.com/zLibDll\n;         http://www.muppetlabs.com/~breadbox/software/assembly.html\n;\n; to compile this file for zLib, I use option:\n;   gcc -c -arch x86_64 gvmat64.S\n\n\n;uInt longest_match(s, cur_match)\n;    deflate_state *s;\n;    IPos cur_match;                             // current match /\n;\n; with XCode for Mac, I had strange error with some jump on intel syntax\n; this is why BEFORE_JMP and AFTER_JMP are used\n */\n\n\n#define BEFORE_JMP .att_syntax\n#define AFTER_JMP .intel_syntax noprefix\n\n#ifndef NO_UNDERLINE\n#\tdefine\tmatch_init\t_match_init\n#\tdefine\tlongest_match\t_longest_match\n#endif\n\n.intel_syntax noprefix\n\n.globl\tmatch_init, longest_match\n.text\nlongest_match:\n\n\n\n#define LocalVarsSize 96\n/*\n; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12\n; free register :  r14,r15\n; register can be saved : rsp\n*/\n\n#define chainlenwmask     (rsp + 8 - LocalVarsSize)\n#define nicematch         (rsp + 16 - LocalVarsSize)\n\n#define save_rdi        (rsp + 24 - LocalVarsSize)\n#define save_rsi        (rsp + 32 - LocalVarsSize)\n#define save_rbx        (rsp + 40 - LocalVarsSize)\n#define save_rbp        (rsp + 48 - LocalVarsSize)\n#define save_r12        (rsp + 56 - LocalVarsSize)\n#define save_r13        (rsp + 64 - LocalVarsSize)\n#define save_r14        (rsp + 72 - LocalVarsSize)\n#define save_r15        (rsp + 80 - LocalVarsSize)\n\n\n/*\n;  all the +4 offsets are due to the addition of pending_buf_size (in zlib\n;  in the deflate_state structure since the asm code was first written\n;  (if you compile with zlib 1.0.4 or older, remove the +4).\n;  Note : these value are good with a 8 bytes boundary pack structure\n*/\n\n#define    MAX_MATCH              258\n#define    MIN_MATCH              3\n#define    MIN_LOOKAHEAD          (MAX_MATCH+MIN_MATCH+1)\n\n/*\n;;; Offsets for fields in the deflate_state structure. These numbers\n;;; are calculated from the definition of deflate_state, with the\n;;; assumption that the compiler will dword-align the fields. (Thus,\n;;; changing the definition of deflate_state could easily cause this\n;;; program to crash horribly, without so much as a warning at\n;;; compile time. Sigh.)\n\n;  all the +zlib1222add offsets are due to the addition of fields\n;  in zlib in the deflate_state structure since the asm code was first written\n;  (if you compile with zlib 1.0.4 or older, use \"zlib1222add equ (-4)\").\n;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use \"zlib1222add equ 0\").\n;  if you compile with zlib 1.2.2.2 or later , use \"zlib1222add equ 8\").\n*/\n\n\n\n/* you can check the structure offset by running\n\n#include <stdlib.h>\n#include <stdio.h>\n#include \"deflate.h\"\n\nvoid print_depl()\n{\ndeflate_state ds;\ndeflate_state *s=&ds;\nprintf(\"size pointer=%u\\n\",(int)sizeof(void*));\n\nprintf(\"#define dsWSize         %u\\n\",(int)(((char*)&(s->w_size))-((char*)s)));\nprintf(\"#define dsWMask         %u\\n\",(int)(((char*)&(s->w_mask))-((char*)s)));\nprintf(\"#define dsWindow        %u\\n\",(int)(((char*)&(s->window))-((char*)s)));\nprintf(\"#define dsPrev          %u\\n\",(int)(((char*)&(s->prev))-((char*)s)));\nprintf(\"#define dsMatchLen      %u\\n\",(int)(((char*)&(s->match_length))-((char*)s)));\nprintf(\"#define dsPrevMatch     %u\\n\",(int)(((char*)&(s->prev_match))-((char*)s)));\nprintf(\"#define dsStrStart      %u\\n\",(int)(((char*)&(s->strstart))-((char*)s)));\nprintf(\"#define dsMatchStart    %u\\n\",(int)(((char*)&(s->match_start))-((char*)s)));\nprintf(\"#define dsLookahead     %u\\n\",(int)(((char*)&(s->lookahead))-((char*)s)));\nprintf(\"#define dsPrevLen       %u\\n\",(int)(((char*)&(s->prev_length))-((char*)s)));\nprintf(\"#define dsMaxChainLen   %u\\n\",(int)(((char*)&(s->max_chain_length))-((char*)s)));\nprintf(\"#define dsGoodMatch     %u\\n\",(int)(((char*)&(s->good_match))-((char*)s)));\nprintf(\"#define dsNiceMatch     %u\\n\",(int)(((char*)&(s->nice_match))-((char*)s)));\n}\n*/\n\n#define dsWSize          68\n#define dsWMask          76\n#define dsWindow         80\n#define dsPrev           96\n#define dsMatchLen       144\n#define dsPrevMatch      148\n#define dsStrStart       156\n#define dsMatchStart     160\n#define dsLookahead      164\n#define dsPrevLen        168\n#define dsMaxChainLen    172\n#define dsGoodMatch      188\n#define dsNiceMatch      192\n\n#define window_size      [ rcx + dsWSize]\n#define WMask            [ rcx + dsWMask]\n#define window_ad        [ rcx + dsWindow]\n#define prev_ad          [ rcx + dsPrev]\n#define strstart         [ rcx + dsStrStart]\n#define match_start      [ rcx + dsMatchStart]\n#define Lookahead        [ rcx + dsLookahead] //; 0ffffffffh on infozip\n#define prev_length      [ rcx + dsPrevLen]\n#define max_chain_length [ rcx + dsMaxChainLen]\n#define good_match       [ rcx + dsGoodMatch]\n#define nice_match       [ rcx + dsNiceMatch]\n\n/*\n; windows:\n; parameter 1 in rcx(deflate state s), param 2 in rdx (cur match)\n\n; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and\n; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp\n;\n; All registers must be preserved across the call, except for\n;   rax, rcx, rdx, r8, r9, r10, and r11, which are scratch.\n\n;\n; gcc on macosx-linux:\n; see http://www.x86-64.org/documentation/abi-0.99.pdf\n; param 1 in rdi, param 2 in rsi\n; rbx, rsp, rbp, r12 to r15 must be preserved\n\n;;; Save registers that the compiler may be using, and adjust esp to\n;;; make room for our stack frame.\n\n\n;;; Retrieve the function arguments. r8d will hold cur_match\n;;; throughout the entire function. edx will hold the pointer to the\n;;; deflate_state structure during the function's setup (before\n;;; entering the main loop.\n\n; ms: parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)\n; mac: param 1 in rdi, param 2 rsi\n; this clear high 32 bits of r8, which can be garbage in both r8 and rdx\n*/\n        mov [save_rbx],rbx\n        mov [save_rbp],rbp\n\n\n        mov rcx,rdi\n\n        mov r8d,esi\n\n\n        mov [save_r12],r12\n        mov [save_r13],r13\n        mov [save_r14],r14\n        mov [save_r15],r15\n\n\n//;;; uInt wmask = s->w_mask;\n//;;; unsigned chain_length = s->max_chain_length;\n//;;; if (s->prev_length >= s->good_match) {\n//;;;     chain_length >>= 2;\n//;;; }\n\n\n        mov edi, prev_length\n        mov esi, good_match\n        mov eax, WMask\n        mov ebx, max_chain_length\n        cmp edi, esi\n        jl  LastMatchGood\n        shr ebx, 2\nLastMatchGood:\n\n//;;; chainlen is decremented once beforehand so that the function can\n//;;; use the sign flag instead of the zero flag for the exit test.\n//;;; It is then shifted into the high word, to make room for the wmask\n//;;; value, which it will always accompany.\n\n        dec ebx\n        shl ebx, 16\n        or  ebx, eax\n\n//;;; on zlib only\n//;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;\n\n\n\n        mov eax, nice_match\n        mov [chainlenwmask], ebx\n        mov r10d, Lookahead\n        cmp r10d, eax\n        cmovnl r10d, eax\n        mov [nicematch],r10d\n\n\n\n//;;; register Bytef *scan = s->window + s->strstart;\n        mov r10, window_ad\n        mov ebp, strstart\n        lea r13, [r10 + rbp]\n\n//;;; Determine how many bytes the scan ptr is off from being\n//;;; dword-aligned.\n\n         mov r9,r13\n         neg r13\n         and r13,3\n\n//;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?\n//;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;\n\n\n        mov eax, window_size\n        sub eax, MIN_LOOKAHEAD\n\n\n        xor edi,edi\n        sub ebp, eax\n\n        mov r11d, prev_length\n\n        cmovng ebp,edi\n\n//;;; int best_len = s->prev_length;\n\n\n//;;; Store the sum of s->window + best_len in esi locally, and in esi.\n\n       lea  rsi,[r10+r11]\n\n//;;; register ush scan_start = *(ushf*)scan;\n//;;; register ush scan_end   = *(ushf*)(scan+best_len-1);\n//;;; Posf *prev = s->prev;\n\n        movzx r12d,word ptr [r9]\n        movzx ebx, word ptr [r9 + r11 - 1]\n\n        mov rdi, prev_ad\n\n//;;; Jump into the main loop.\n\n        mov edx, [chainlenwmask]\n\n        cmp bx,word ptr [rsi + r8 - 1]\n        jz  LookupLoopIsZero\n\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\nLookupLoop1:\n        and r8d, edx\n\n        movzx   r8d, word ptr [rdi + r8*2]\n        cmp r8d, ebp\n        jbe LeaveNow\n\t\t\n\t\t\n\t\t\n        sub edx, 0x00010000\n\t\tBEFORE_JMP\n        js  LeaveNow\n\t\tAFTER_JMP\n\nLoopEntry1:\n        cmp bx,word ptr [rsi + r8 - 1]\n\t\tBEFORE_JMP\n        jz  LookupLoopIsZero\n\t\tAFTER_JMP\n\nLookupLoop2:\n        and r8d, edx\n\n        movzx   r8d, word ptr [rdi + r8*2]\n        cmp r8d, ebp\n\t\tBEFORE_JMP\n        jbe LeaveNow\n\t\tAFTER_JMP\n        sub edx, 0x00010000\n\t\tBEFORE_JMP\n        js  LeaveNow\n\t\tAFTER_JMP\n\nLoopEntry2:\n        cmp bx,word ptr [rsi + r8 - 1]\n\t\tBEFORE_JMP\n        jz  LookupLoopIsZero\n\t\tAFTER_JMP\n\nLookupLoop4:\n        and r8d, edx\n\n        movzx   r8d, word ptr [rdi + r8*2]\n        cmp r8d, ebp\n\t\tBEFORE_JMP\n        jbe LeaveNow\n\t\tAFTER_JMP\n        sub edx, 0x00010000\n\t\tBEFORE_JMP\n        js  LeaveNow\n\t\tAFTER_JMP\n\nLoopEntry4:\n\n        cmp bx,word ptr [rsi + r8 - 1]\n\t\tBEFORE_JMP\n        jnz LookupLoop1\n        jmp LookupLoopIsZero\n\t\tAFTER_JMP\n/*\n;;; do {\n;;;     match = s->window + cur_match;\n;;;     if (*(ushf*)(match+best_len-1) != scan_end ||\n;;;         *(ushf*)match != scan_start) continue;\n;;;     [...]\n;;; } while ((cur_match = prev[cur_match & wmask]) > limit\n;;;          && --chain_length != 0);\n;;;\n;;; Here is the inner loop of the function. The function will spend the\n;;; majority of its time in this loop, and majority of that time will\n;;; be spent in the first ten instructions.\n;;;\n;;; Within this loop:\n;;; ebx = scanend\n;;; r8d = curmatch\n;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)\n;;; esi = windowbestlen - i.e., (window + bestlen)\n;;; edi = prev\n;;; ebp = limit\n*/\n.balign 16\nLookupLoop:\n        and r8d, edx\n\n        movzx   r8d, word ptr [rdi + r8*2]\n        cmp r8d, ebp\n\t\tBEFORE_JMP\n        jbe LeaveNow\n\t\tAFTER_JMP\n        sub edx, 0x00010000\n\t\tBEFORE_JMP\n        js  LeaveNow\n\t\tAFTER_JMP\n\nLoopEntry:\n\n        cmp bx,word ptr [rsi + r8 - 1]\n\t\tBEFORE_JMP\n        jnz LookupLoop1\n\t\tAFTER_JMP\nLookupLoopIsZero:\n        cmp     r12w, word ptr [r10 + r8]\n\t\tBEFORE_JMP\n        jnz LookupLoop1\n\t\tAFTER_JMP\n\n\n//;;; Store the current value of chainlen.\n        mov [chainlenwmask], edx\n/*\n;;; Point edi to the string under scrutiny, and esi to the string we\n;;; are hoping to match it up with. In actuality, esi and edi are\n;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is\n;;; initialized to -(MAX_MATCH_8 - scanalign).\n*/\n        lea rsi,[r8+r10]\n        mov rdx, 0xfffffffffffffef8 //; -(MAX_MATCH_8)\n        lea rsi, [rsi + r13 + 0x0108] //;MAX_MATCH_8]\n        lea rdi, [r9 + r13 + 0x0108] //;MAX_MATCH_8]\n\n        prefetcht1 [rsi+rdx]\n        prefetcht1 [rdi+rdx]\n\n/*\n;;; Test the strings for equality, 8 bytes at a time. At the end,\n;;; adjust rdx so that it is offset to the exact byte that mismatched.\n;;;\n;;; We already know at this point that the first three bytes of the\n;;; strings match each other, and they can be safely passed over before\n;;; starting the compare loop. So what this code does is skip over 0-3\n;;; bytes, as much as necessary in order to dword-align the edi\n;;; pointer. (rsi will still be misaligned three times out of four.)\n;;;\n;;; It should be confessed that this loop usually does not represent\n;;; much of the total running time. Replacing it with a more\n;;; straightforward \"rep cmpsb\" would not drastically degrade\n;;; performance.\n*/\n\nLoopCmps:\n        mov rax, [rsi + rdx]\n        xor rax, [rdi + rdx]\n        jnz LeaveLoopCmps\n\n        mov rax, [rsi + rdx + 8]\n        xor rax, [rdi + rdx + 8]\n        jnz LeaveLoopCmps8\n\n\n        mov rax, [rsi + rdx + 8+8]\n        xor rax, [rdi + rdx + 8+8]\n        jnz LeaveLoopCmps16\n\n        add rdx,8+8+8\n\n\t\tBEFORE_JMP\n        jnz  LoopCmps\n        jmp  LenMaximum\n\t\tAFTER_JMP\n\t\t\nLeaveLoopCmps16: add rdx,8\nLeaveLoopCmps8: add rdx,8\nLeaveLoopCmps:\n\n        test    eax, 0x0000FFFF\n        jnz LenLower\n\n        test eax,0xffffffff\n\n        jnz LenLower32\n\n        add rdx,4\n        shr rax,32\n        or ax,ax\n\t\tBEFORE_JMP\n        jnz LenLower\n\t\tAFTER_JMP\n\nLenLower32:\n        shr eax,16\n        add rdx,2\n\t\t\nLenLower:\t\t\n        sub al, 1\n        adc rdx, 0\n//;;; Calculate the length of the match. If it is longer than MAX_MATCH,\n//;;; then automatically accept it as the best possible match and leave.\n\n        lea rax, [rdi + rdx]\n        sub rax, r9\n        cmp eax, MAX_MATCH\n\t\tBEFORE_JMP\n        jge LenMaximum\n\t\tAFTER_JMP\n/*\n;;; If the length of the match is not longer than the best match we\n;;; have so far, then forget it and return to the lookup loop.\n;///////////////////////////////////\n*/\n        cmp eax, r11d\n        jg  LongerMatch\n\n        lea rsi,[r10+r11]\n\n        mov rdi, prev_ad\n        mov edx, [chainlenwmask]\n\t\tBEFORE_JMP\n        jmp LookupLoop\n\t\tAFTER_JMP\n/*\n;;;         s->match_start = cur_match;\n;;;         best_len = len;\n;;;         if (len >= nice_match) break;\n;;;         scan_end = *(ushf*)(scan+best_len-1);\n*/\nLongerMatch:\n        mov r11d, eax\n        mov match_start, r8d\n        cmp eax, [nicematch]\n\t\tBEFORE_JMP\n        jge LeaveNow\n\t\tAFTER_JMP\n\n        lea rsi,[r10+rax]\n\n        movzx   ebx, word ptr [r9 + rax - 1]\n        mov rdi, prev_ad\n        mov edx, [chainlenwmask]\n\t\tBEFORE_JMP\n        jmp LookupLoop\n\t\tAFTER_JMP\n\n//;;; Accept the current string, with the maximum possible length.\n\nLenMaximum:\n        mov r11d,MAX_MATCH\n        mov match_start, r8d\n\n//;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;\n//;;; return s->lookahead;\n\nLeaveNow:\n        mov eax, Lookahead\n        cmp r11d, eax\n        cmovng eax, r11d\n\n\n\n//;;; Restore the stack and return from whence we came.\n\n\n//        mov rsi,[save_rsi]\n//        mov rdi,[save_rdi]\n        mov rbx,[save_rbx]\n        mov rbp,[save_rbp]\n        mov r12,[save_r12]\n        mov r13,[save_r13]\n        mov r14,[save_r14]\n        mov r15,[save_r15]\n\n\n        ret 0\n//; please don't remove this string !\n//; Your can freely use gvmat64 in any free or commercial app\n//; but it is far better don't remove the string in the binary!\n //   db     0dh,0ah,\"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005\",0dh,0ah,0\n\n\nmatch_init:\n  ret 0\n\n\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/infback9/README",
    "content": "See infback9.h for what this is and how to use it.\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/infback9/infback9.c",
    "content": "/* infback9.c -- inflate deflate64 data using a call-back interface\n * Copyright (C) 1995-2008 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#include \"zutil.h\"\n#include \"infback9.h\"\n#include \"inftree9.h\"\n#include \"inflate9.h\"\n\n#define WSIZE 65536UL\n\n/*\n   strm provides memory allocation functions in zalloc and zfree, or\n   Z_NULL to use the library memory allocation functions.\n\n   window is a user-supplied window and output buffer that is 64K bytes.\n */\nint ZEXPORT inflateBack9Init_(strm, window, version, stream_size)\nz_stream FAR *strm;\nunsigned char FAR *window;\nconst char *version;\nint stream_size;\n{\n    struct inflate_state FAR *state;\n\n    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||\n        stream_size != (int)(sizeof(z_stream)))\n        return Z_VERSION_ERROR;\n    if (strm == Z_NULL || window == Z_NULL)\n        return Z_STREAM_ERROR;\n    strm->msg = Z_NULL;                 /* in case we return an error */\n    if (strm->zalloc == (alloc_func)0) {\n        strm->zalloc = zcalloc;\n        strm->opaque = (voidpf)0;\n    }\n    if (strm->zfree == (free_func)0) strm->zfree = zcfree;\n    state = (struct inflate_state FAR *)ZALLOC(strm, 1,\n                                               sizeof(struct inflate_state));\n    if (state == Z_NULL) return Z_MEM_ERROR;\n    Tracev((stderr, \"inflate: allocated\\n\"));\n    strm->state = (voidpf)state;\n    state->window = window;\n    return Z_OK;\n}\n\n/*\n   Build and output length and distance decoding tables for fixed code\n   decoding.\n */\n#ifdef MAKEFIXED\n#include <stdio.h>\n\nvoid makefixed9(void)\n{\n    unsigned sym, bits, low, size;\n    code *next, *lenfix, *distfix;\n    struct inflate_state state;\n    code fixed[544];\n\n    /* literal/length table */\n    sym = 0;\n    while (sym < 144) state.lens[sym++] = 8;\n    while (sym < 256) state.lens[sym++] = 9;\n    while (sym < 280) state.lens[sym++] = 7;\n    while (sym < 288) state.lens[sym++] = 8;\n    next = fixed;\n    lenfix = next;\n    bits = 9;\n    inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work);\n\n    /* distance table */\n    sym = 0;\n    while (sym < 32) state.lens[sym++] = 5;\n    distfix = next;\n    bits = 5;\n    inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work);\n\n    /* write tables */\n    puts(\"    /* inffix9.h -- table for decoding deflate64 fixed codes\");\n    puts(\"     * Generated automatically by makefixed9().\");\n    puts(\"     */\");\n    puts(\"\");\n    puts(\"    /* WARNING: this file should *not* be used by applications.\");\n    puts(\"       It is part of the implementation of this library and is\");\n    puts(\"       subject to change. Applications should only use zlib.h.\");\n    puts(\"     */\");\n    puts(\"\");\n    size = 1U << 9;\n    printf(\"    static const code lenfix[%u] = {\", size);\n    low = 0;\n    for (;;) {\n        if ((low % 6) == 0) printf(\"\\n        \");\n        printf(\"{%u,%u,%d}\", lenfix[low].op, lenfix[low].bits,\n               lenfix[low].val);\n        if (++low == size) break;\n        putchar(',');\n    }\n    puts(\"\\n    };\");\n    size = 1U << 5;\n    printf(\"\\n    static const code distfix[%u] = {\", size);\n    low = 0;\n    for (;;) {\n        if ((low % 5) == 0) printf(\"\\n        \");\n        printf(\"{%u,%u,%d}\", distfix[low].op, distfix[low].bits,\n               distfix[low].val);\n        if (++low == size) break;\n        putchar(',');\n    }\n    puts(\"\\n    };\");\n}\n#endif /* MAKEFIXED */\n\n/* Macros for inflateBack(): */\n\n/* Clear the input bit accumulator */\n#define INITBITS() \\\n    do { \\\n        hold = 0; \\\n        bits = 0; \\\n    } while (0)\n\n/* Assure that some input is available.  If input is requested, but denied,\n   then return a Z_BUF_ERROR from inflateBack(). */\n#define PULL() \\\n    do { \\\n        if (have == 0) { \\\n            have = in(in_desc, &next); \\\n            if (have == 0) { \\\n                next = Z_NULL; \\\n                ret = Z_BUF_ERROR; \\\n                goto inf_leave; \\\n            } \\\n        } \\\n    } while (0)\n\n/* Get a byte of input into the bit accumulator, or return from inflateBack()\n   with an error if there is no input available. */\n#define PULLBYTE() \\\n    do { \\\n        PULL(); \\\n        have--; \\\n        hold += (unsigned long)(*next++) << bits; \\\n        bits += 8; \\\n    } while (0)\n\n/* Assure that there are at least n bits in the bit accumulator.  If there is\n   not enough available input to do that, then return from inflateBack() with\n   an error. */\n#define NEEDBITS(n) \\\n    do { \\\n        while (bits < (unsigned)(n)) \\\n            PULLBYTE(); \\\n    } while (0)\n\n/* Return the low n bits of the bit accumulator (n <= 16) */\n#define BITS(n) \\\n    ((unsigned)hold & ((1U << (n)) - 1))\n\n/* Remove n bits from the bit accumulator */\n#define DROPBITS(n) \\\n    do { \\\n        hold >>= (n); \\\n        bits -= (unsigned)(n); \\\n    } while (0)\n\n/* Remove zero to seven bits as needed to go to a byte boundary */\n#define BYTEBITS() \\\n    do { \\\n        hold >>= bits & 7; \\\n        bits -= bits & 7; \\\n    } while (0)\n\n/* Assure that some output space is available, by writing out the window\n   if it's full.  If the write fails, return from inflateBack() with a\n   Z_BUF_ERROR. */\n#define ROOM() \\\n    do { \\\n        if (left == 0) { \\\n            put = window; \\\n            left = WSIZE; \\\n            wrap = 1; \\\n            if (out(out_desc, put, (unsigned)left)) { \\\n                ret = Z_BUF_ERROR; \\\n                goto inf_leave; \\\n            } \\\n        } \\\n    } while (0)\n\n/*\n   strm provides the memory allocation functions and window buffer on input,\n   and provides information on the unused input on return.  For Z_DATA_ERROR\n   returns, strm will also provide an error message.\n\n   in() and out() are the call-back input and output functions.  When\n   inflateBack() needs more input, it calls in().  When inflateBack() has\n   filled the window with output, or when it completes with data in the\n   window, it calls out() to write out the data.  The application must not\n   change the provided input until in() is called again or inflateBack()\n   returns.  The application must not change the window/output buffer until\n   inflateBack() returns.\n\n   in() and out() are called with a descriptor parameter provided in the\n   inflateBack() call.  This parameter can be a structure that provides the\n   information required to do the read or write, as well as accumulated\n   information on the input and output such as totals and check values.\n\n   in() should return zero on failure.  out() should return non-zero on\n   failure.  If either in() or out() fails, than inflateBack() returns a\n   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it\n   was in() or out() that caused in the error.  Otherwise,  inflateBack()\n   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format\n   error, or Z_MEM_ERROR if it could not allocate memory for the state.\n   inflateBack() can also return Z_STREAM_ERROR if the input parameters\n   are not correct, i.e. strm is Z_NULL or the state was not initialized.\n */\nint ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc)\nz_stream FAR *strm;\nin_func in;\nvoid FAR *in_desc;\nout_func out;\nvoid FAR *out_desc;\n{\n    struct inflate_state FAR *state;\n    z_const unsigned char FAR *next;    /* next input */\n    unsigned char FAR *put;     /* next output */\n    unsigned have;              /* available input */\n    unsigned long left;         /* available output */\n    inflate_mode mode;          /* current inflate mode */\n    int lastblock;              /* true if processing last block */\n    int wrap;                   /* true if the window has wrapped */\n    unsigned char FAR *window;  /* allocated sliding window, if needed */\n    unsigned long hold;         /* bit buffer */\n    unsigned bits;              /* bits in bit buffer */\n    unsigned extra;             /* extra bits needed */\n    unsigned long length;       /* literal or length of data to copy */\n    unsigned long offset;       /* distance back to copy string from */\n    unsigned long copy;         /* number of stored or match bytes to copy */\n    unsigned char FAR *from;    /* where to copy match bytes from */\n    code const FAR *lencode;    /* starting table for length/literal codes */\n    code const FAR *distcode;   /* starting table for distance codes */\n    unsigned lenbits;           /* index bits for lencode */\n    unsigned distbits;          /* index bits for distcode */\n    code here;                  /* current decoding table entry */\n    code last;                  /* parent table entry */\n    unsigned len;               /* length to copy for repeats, bits to drop */\n    int ret;                    /* return code */\n    static const unsigned short order[19] = /* permutation of code lengths */\n        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};\n#include \"inffix9.h\"\n\n    /* Check that the strm exists and that the state was initialized */\n    if (strm == Z_NULL || strm->state == Z_NULL)\n        return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n\n    /* Reset the state */\n    strm->msg = Z_NULL;\n    mode = TYPE;\n    lastblock = 0;\n    wrap = 0;\n    window = state->window;\n    next = strm->next_in;\n    have = next != Z_NULL ? strm->avail_in : 0;\n    hold = 0;\n    bits = 0;\n    put = window;\n    left = WSIZE;\n    lencode = Z_NULL;\n    distcode = Z_NULL;\n\n    /* Inflate until end of block marked as last */\n    for (;;)\n        switch (mode) {\n        case TYPE:\n            /* determine and dispatch block type */\n            if (lastblock) {\n                BYTEBITS();\n                mode = DONE;\n                break;\n            }\n            NEEDBITS(3);\n            lastblock = BITS(1);\n            DROPBITS(1);\n            switch (BITS(2)) {\n            case 0:                             /* stored block */\n                Tracev((stderr, \"inflate:     stored block%s\\n\",\n                        lastblock ? \" (last)\" : \"\"));\n                mode = STORED;\n                break;\n            case 1:                             /* fixed block */\n                lencode = lenfix;\n                lenbits = 9;\n                distcode = distfix;\n                distbits = 5;\n                Tracev((stderr, \"inflate:     fixed codes block%s\\n\",\n                        lastblock ? \" (last)\" : \"\"));\n                mode = LEN;                     /* decode codes */\n                break;\n            case 2:                             /* dynamic block */\n                Tracev((stderr, \"inflate:     dynamic codes block%s\\n\",\n                        lastblock ? \" (last)\" : \"\"));\n                mode = TABLE;\n                break;\n            case 3:\n                strm->msg = (char *)\"invalid block type\";\n                mode = BAD;\n            }\n            DROPBITS(2);\n            break;\n\n        case STORED:\n            /* get and verify stored block length */\n            BYTEBITS();                         /* go to byte boundary */\n            NEEDBITS(32);\n            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {\n                strm->msg = (char *)\"invalid stored block lengths\";\n                mode = BAD;\n                break;\n            }\n            length = (unsigned)hold & 0xffff;\n            Tracev((stderr, \"inflate:       stored length %lu\\n\",\n                    length));\n            INITBITS();\n\n            /* copy stored block from input to output */\n            while (length != 0) {\n                copy = length;\n                PULL();\n                ROOM();\n                if (copy > have) copy = have;\n                if (copy > left) copy = left;\n                zmemcpy(put, next, copy);\n                have -= copy;\n                next += copy;\n                left -= copy;\n                put += copy;\n                length -= copy;\n            }\n            Tracev((stderr, \"inflate:       stored end\\n\"));\n            mode = TYPE;\n            break;\n\n        case TABLE:\n            /* get dynamic table entries descriptor */\n            NEEDBITS(14);\n            state->nlen = BITS(5) + 257;\n            DROPBITS(5);\n            state->ndist = BITS(5) + 1;\n            DROPBITS(5);\n            state->ncode = BITS(4) + 4;\n            DROPBITS(4);\n            if (state->nlen > 286) {\n                strm->msg = (char *)\"too many length symbols\";\n                mode = BAD;\n                break;\n            }\n            Tracev((stderr, \"inflate:       table sizes ok\\n\"));\n\n            /* get code length code lengths (not a typo) */\n            state->have = 0;\n            while (state->have < state->ncode) {\n                NEEDBITS(3);\n                state->lens[order[state->have++]] = (unsigned short)BITS(3);\n                DROPBITS(3);\n            }\n            while (state->have < 19)\n                state->lens[order[state->have++]] = 0;\n            state->next = state->codes;\n            lencode = (code const FAR *)(state->next);\n            lenbits = 7;\n            ret = inflate_table9(CODES, state->lens, 19, &(state->next),\n                                &(lenbits), state->work);\n            if (ret) {\n                strm->msg = (char *)\"invalid code lengths set\";\n                mode = BAD;\n                break;\n            }\n            Tracev((stderr, \"inflate:       code lengths ok\\n\"));\n\n            /* get length and distance code code lengths */\n            state->have = 0;\n            while (state->have < state->nlen + state->ndist) {\n                for (;;) {\n                    here = lencode[BITS(lenbits)];\n                    if ((unsigned)(here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                if (here.val < 16) {\n                    NEEDBITS(here.bits);\n                    DROPBITS(here.bits);\n                    state->lens[state->have++] = here.val;\n                }\n                else {\n                    if (here.val == 16) {\n                        NEEDBITS(here.bits + 2);\n                        DROPBITS(here.bits);\n                        if (state->have == 0) {\n                            strm->msg = (char *)\"invalid bit length repeat\";\n                            mode = BAD;\n                            break;\n                        }\n                        len = (unsigned)(state->lens[state->have - 1]);\n                        copy = 3 + BITS(2);\n                        DROPBITS(2);\n                    }\n                    else if (here.val == 17) {\n                        NEEDBITS(here.bits + 3);\n                        DROPBITS(here.bits);\n                        len = 0;\n                        copy = 3 + BITS(3);\n                        DROPBITS(3);\n                    }\n                    else {\n                        NEEDBITS(here.bits + 7);\n                        DROPBITS(here.bits);\n                        len = 0;\n                        copy = 11 + BITS(7);\n                        DROPBITS(7);\n                    }\n                    if (state->have + copy > state->nlen + state->ndist) {\n                        strm->msg = (char *)\"invalid bit length repeat\";\n                        mode = BAD;\n                        break;\n                    }\n                    while (copy--)\n                        state->lens[state->have++] = (unsigned short)len;\n                }\n            }\n\n            /* handle error breaks in while */\n            if (mode == BAD) break;\n\n            /* check for end-of-block code (better have one) */\n            if (state->lens[256] == 0) {\n                strm->msg = (char *)\"invalid code -- missing end-of-block\";\n                mode = BAD;\n                break;\n            }\n\n            /* build code tables -- note: do not change the lenbits or distbits\n               values here (9 and 6) without reading the comments in inftree9.h\n               concerning the ENOUGH constants, which depend on those values */\n            state->next = state->codes;\n            lencode = (code const FAR *)(state->next);\n            lenbits = 9;\n            ret = inflate_table9(LENS, state->lens, state->nlen,\n                            &(state->next), &(lenbits), state->work);\n            if (ret) {\n                strm->msg = (char *)\"invalid literal/lengths set\";\n                mode = BAD;\n                break;\n            }\n            distcode = (code const FAR *)(state->next);\n            distbits = 6;\n            ret = inflate_table9(DISTS, state->lens + state->nlen,\n                            state->ndist, &(state->next), &(distbits),\n                            state->work);\n            if (ret) {\n                strm->msg = (char *)\"invalid distances set\";\n                mode = BAD;\n                break;\n            }\n            Tracev((stderr, \"inflate:       codes ok\\n\"));\n            mode = LEN;\n\n        case LEN:\n            /* get a literal, length, or end-of-block code */\n            for (;;) {\n                here = lencode[BITS(lenbits)];\n                if ((unsigned)(here.bits) <= bits) break;\n                PULLBYTE();\n            }\n            if (here.op && (here.op & 0xf0) == 0) {\n                last = here;\n                for (;;) {\n                    here = lencode[last.val +\n                            (BITS(last.bits + last.op) >> last.bits)];\n                    if ((unsigned)(last.bits + here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                DROPBITS(last.bits);\n            }\n            DROPBITS(here.bits);\n            length = (unsigned)here.val;\n\n            /* process literal */\n            if (here.op == 0) {\n                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?\n                        \"inflate:         literal '%c'\\n\" :\n                        \"inflate:         literal 0x%02x\\n\", here.val));\n                ROOM();\n                *put++ = (unsigned char)(length);\n                left--;\n                mode = LEN;\n                break;\n            }\n\n            /* process end of block */\n            if (here.op & 32) {\n                Tracevv((stderr, \"inflate:         end of block\\n\"));\n                mode = TYPE;\n                break;\n            }\n\n            /* invalid code */\n            if (here.op & 64) {\n                strm->msg = (char *)\"invalid literal/length code\";\n                mode = BAD;\n                break;\n            }\n\n            /* length code -- get extra bits, if any */\n            extra = (unsigned)(here.op) & 31;\n            if (extra != 0) {\n                NEEDBITS(extra);\n                length += BITS(extra);\n                DROPBITS(extra);\n            }\n            Tracevv((stderr, \"inflate:         length %lu\\n\", length));\n\n            /* get distance code */\n            for (;;) {\n                here = distcode[BITS(distbits)];\n                if ((unsigned)(here.bits) <= bits) break;\n                PULLBYTE();\n            }\n            if ((here.op & 0xf0) == 0) {\n                last = here;\n                for (;;) {\n                    here = distcode[last.val +\n                            (BITS(last.bits + last.op) >> last.bits)];\n                    if ((unsigned)(last.bits + here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                DROPBITS(last.bits);\n            }\n            DROPBITS(here.bits);\n            if (here.op & 64) {\n                strm->msg = (char *)\"invalid distance code\";\n                mode = BAD;\n                break;\n            }\n            offset = (unsigned)here.val;\n\n            /* get distance extra bits, if any */\n            extra = (unsigned)(here.op) & 15;\n            if (extra != 0) {\n                NEEDBITS(extra);\n                offset += BITS(extra);\n                DROPBITS(extra);\n            }\n            if (offset > WSIZE - (wrap ? 0: left)) {\n                strm->msg = (char *)\"invalid distance too far back\";\n                mode = BAD;\n                break;\n            }\n            Tracevv((stderr, \"inflate:         distance %lu\\n\", offset));\n\n            /* copy match from window to output */\n            do {\n                ROOM();\n                copy = WSIZE - offset;\n                if (copy < left) {\n                    from = put + copy;\n                    copy = left - copy;\n                }\n                else {\n                    from = put - offset;\n                    copy = left;\n                }\n                if (copy > length) copy = length;\n                length -= copy;\n                left -= copy;\n                do {\n                    *put++ = *from++;\n                } while (--copy);\n            } while (length != 0);\n            break;\n\n        case DONE:\n            /* inflate stream terminated properly -- write leftover output */\n            ret = Z_STREAM_END;\n            if (left < WSIZE) {\n                if (out(out_desc, window, (unsigned)(WSIZE - left)))\n                    ret = Z_BUF_ERROR;\n            }\n            goto inf_leave;\n\n        case BAD:\n            ret = Z_DATA_ERROR;\n            goto inf_leave;\n\n        default:                /* can't happen, but makes compilers happy */\n            ret = Z_STREAM_ERROR;\n            goto inf_leave;\n        }\n\n    /* Return unused input */\n  inf_leave:\n    strm->next_in = next;\n    strm->avail_in = have;\n    return ret;\n}\n\nint ZEXPORT inflateBack9End(strm)\nz_stream FAR *strm;\n{\n    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)\n        return Z_STREAM_ERROR;\n    ZFREE(strm, strm->state);\n    strm->state = Z_NULL;\n    Tracev((stderr, \"inflate: end\\n\"));\n    return Z_OK;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/infback9/infback9.h",
    "content": "/* infback9.h -- header for using inflateBack9 functions\n * Copyright (C) 2003 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/*\n * This header file and associated patches provide a decoder for PKWare's\n * undocumented deflate64 compression method (method 9).  Use with infback9.c,\n * inftree9.h, inftree9.c, and inffix9.h.  These patches are not supported.\n * This should be compiled with zlib, since it uses zutil.h and zutil.o.\n * This code has not yet been tested on 16-bit architectures.  See the\n * comments in zlib.h for inflateBack() usage.  These functions are used\n * identically, except that there is no windowBits parameter, and a 64K\n * window must be provided.  Also if int's are 16 bits, then a zero for\n * the third parameter of the \"out\" function actually means 65536UL.\n * zlib.h must be included before this header file.\n */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm,\n                                    in_func in, void FAR *in_desc,\n                                    out_func out, void FAR *out_desc));\nZEXTERN int ZEXPORT inflateBack9End OF((z_stream FAR *strm));\nZEXTERN int ZEXPORT inflateBack9Init_ OF((z_stream FAR *strm,\n                                         unsigned char FAR *window,\n                                         const char *version,\n                                         int stream_size));\n#define inflateBack9Init(strm, window) \\\n        inflateBack9Init_((strm), (window), \\\n        ZLIB_VERSION, sizeof(z_stream))\n\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/infback9/inffix9.h",
    "content": "    /* inffix9.h -- table for decoding deflate64 fixed codes\n     * Generated automatically by makefixed9().\n     */\n\n    /* WARNING: this file should *not* be used by applications.\n       It is part of the implementation of this library and is\n       subject to change. Applications should only use zlib.h.\n     */\n\n    static const code lenfix[512] = {\n        {96,7,0},{0,8,80},{0,8,16},{132,8,115},{130,7,31},{0,8,112},\n        {0,8,48},{0,9,192},{128,7,10},{0,8,96},{0,8,32},{0,9,160},\n        {0,8,0},{0,8,128},{0,8,64},{0,9,224},{128,7,6},{0,8,88},\n        {0,8,24},{0,9,144},{131,7,59},{0,8,120},{0,8,56},{0,9,208},\n        {129,7,17},{0,8,104},{0,8,40},{0,9,176},{0,8,8},{0,8,136},\n        {0,8,72},{0,9,240},{128,7,4},{0,8,84},{0,8,20},{133,8,227},\n        {131,7,43},{0,8,116},{0,8,52},{0,9,200},{129,7,13},{0,8,100},\n        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},\n        {128,7,8},{0,8,92},{0,8,28},{0,9,152},{132,7,83},{0,8,124},\n        {0,8,60},{0,9,216},{130,7,23},{0,8,108},{0,8,44},{0,9,184},\n        {0,8,12},{0,8,140},{0,8,76},{0,9,248},{128,7,3},{0,8,82},\n        {0,8,18},{133,8,163},{131,7,35},{0,8,114},{0,8,50},{0,9,196},\n        {129,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},{0,8,130},\n        {0,8,66},{0,9,228},{128,7,7},{0,8,90},{0,8,26},{0,9,148},\n        {132,7,67},{0,8,122},{0,8,58},{0,9,212},{130,7,19},{0,8,106},\n        {0,8,42},{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},\n        {128,7,5},{0,8,86},{0,8,22},{65,8,0},{131,7,51},{0,8,118},\n        {0,8,54},{0,9,204},{129,7,15},{0,8,102},{0,8,38},{0,9,172},\n        {0,8,6},{0,8,134},{0,8,70},{0,9,236},{128,7,9},{0,8,94},\n        {0,8,30},{0,9,156},{132,7,99},{0,8,126},{0,8,62},{0,9,220},\n        {130,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},\n        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{133,8,131},\n        {130,7,31},{0,8,113},{0,8,49},{0,9,194},{128,7,10},{0,8,97},\n        {0,8,33},{0,9,162},{0,8,1},{0,8,129},{0,8,65},{0,9,226},\n        {128,7,6},{0,8,89},{0,8,25},{0,9,146},{131,7,59},{0,8,121},\n        {0,8,57},{0,9,210},{129,7,17},{0,8,105},{0,8,41},{0,9,178},\n        {0,8,9},{0,8,137},{0,8,73},{0,9,242},{128,7,4},{0,8,85},\n        {0,8,21},{144,8,3},{131,7,43},{0,8,117},{0,8,53},{0,9,202},\n        {129,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},\n        {0,8,69},{0,9,234},{128,7,8},{0,8,93},{0,8,29},{0,9,154},\n        {132,7,83},{0,8,125},{0,8,61},{0,9,218},{130,7,23},{0,8,109},\n        {0,8,45},{0,9,186},{0,8,13},{0,8,141},{0,8,77},{0,9,250},\n        {128,7,3},{0,8,83},{0,8,19},{133,8,195},{131,7,35},{0,8,115},\n        {0,8,51},{0,9,198},{129,7,11},{0,8,99},{0,8,35},{0,9,166},\n        {0,8,3},{0,8,131},{0,8,67},{0,9,230},{128,7,7},{0,8,91},\n        {0,8,27},{0,9,150},{132,7,67},{0,8,123},{0,8,59},{0,9,214},\n        {130,7,19},{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},\n        {0,8,75},{0,9,246},{128,7,5},{0,8,87},{0,8,23},{77,8,0},\n        {131,7,51},{0,8,119},{0,8,55},{0,9,206},{129,7,15},{0,8,103},\n        {0,8,39},{0,9,174},{0,8,7},{0,8,135},{0,8,71},{0,9,238},\n        {128,7,9},{0,8,95},{0,8,31},{0,9,158},{132,7,99},{0,8,127},\n        {0,8,63},{0,9,222},{130,7,27},{0,8,111},{0,8,47},{0,9,190},\n        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},\n        {0,8,16},{132,8,115},{130,7,31},{0,8,112},{0,8,48},{0,9,193},\n        {128,7,10},{0,8,96},{0,8,32},{0,9,161},{0,8,0},{0,8,128},\n        {0,8,64},{0,9,225},{128,7,6},{0,8,88},{0,8,24},{0,9,145},\n        {131,7,59},{0,8,120},{0,8,56},{0,9,209},{129,7,17},{0,8,104},\n        {0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},{0,9,241},\n        {128,7,4},{0,8,84},{0,8,20},{133,8,227},{131,7,43},{0,8,116},\n        {0,8,52},{0,9,201},{129,7,13},{0,8,100},{0,8,36},{0,9,169},\n        {0,8,4},{0,8,132},{0,8,68},{0,9,233},{128,7,8},{0,8,92},\n        {0,8,28},{0,9,153},{132,7,83},{0,8,124},{0,8,60},{0,9,217},\n        {130,7,23},{0,8,108},{0,8,44},{0,9,185},{0,8,12},{0,8,140},\n        {0,8,76},{0,9,249},{128,7,3},{0,8,82},{0,8,18},{133,8,163},\n        {131,7,35},{0,8,114},{0,8,50},{0,9,197},{129,7,11},{0,8,98},\n        {0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},\n        {128,7,7},{0,8,90},{0,8,26},{0,9,149},{132,7,67},{0,8,122},\n        {0,8,58},{0,9,213},{130,7,19},{0,8,106},{0,8,42},{0,9,181},\n        {0,8,10},{0,8,138},{0,8,74},{0,9,245},{128,7,5},{0,8,86},\n        {0,8,22},{65,8,0},{131,7,51},{0,8,118},{0,8,54},{0,9,205},\n        {129,7,15},{0,8,102},{0,8,38},{0,9,173},{0,8,6},{0,8,134},\n        {0,8,70},{0,9,237},{128,7,9},{0,8,94},{0,8,30},{0,9,157},\n        {132,7,99},{0,8,126},{0,8,62},{0,9,221},{130,7,27},{0,8,110},\n        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},\n        {96,7,0},{0,8,81},{0,8,17},{133,8,131},{130,7,31},{0,8,113},\n        {0,8,49},{0,9,195},{128,7,10},{0,8,97},{0,8,33},{0,9,163},\n        {0,8,1},{0,8,129},{0,8,65},{0,9,227},{128,7,6},{0,8,89},\n        {0,8,25},{0,9,147},{131,7,59},{0,8,121},{0,8,57},{0,9,211},\n        {129,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},{0,8,137},\n        {0,8,73},{0,9,243},{128,7,4},{0,8,85},{0,8,21},{144,8,3},\n        {131,7,43},{0,8,117},{0,8,53},{0,9,203},{129,7,13},{0,8,101},\n        {0,8,37},{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},\n        {128,7,8},{0,8,93},{0,8,29},{0,9,155},{132,7,83},{0,8,125},\n        {0,8,61},{0,9,219},{130,7,23},{0,8,109},{0,8,45},{0,9,187},\n        {0,8,13},{0,8,141},{0,8,77},{0,9,251},{128,7,3},{0,8,83},\n        {0,8,19},{133,8,195},{131,7,35},{0,8,115},{0,8,51},{0,9,199},\n        {129,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},\n        {0,8,67},{0,9,231},{128,7,7},{0,8,91},{0,8,27},{0,9,151},\n        {132,7,67},{0,8,123},{0,8,59},{0,9,215},{130,7,19},{0,8,107},\n        {0,8,43},{0,9,183},{0,8,11},{0,8,139},{0,8,75},{0,9,247},\n        {128,7,5},{0,8,87},{0,8,23},{77,8,0},{131,7,51},{0,8,119},\n        {0,8,55},{0,9,207},{129,7,15},{0,8,103},{0,8,39},{0,9,175},\n        {0,8,7},{0,8,135},{0,8,71},{0,9,239},{128,7,9},{0,8,95},\n        {0,8,31},{0,9,159},{132,7,99},{0,8,127},{0,8,63},{0,9,223},\n        {130,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},\n        {0,8,79},{0,9,255}\n    };\n\n    static const code distfix[32] = {\n        {128,5,1},{135,5,257},{131,5,17},{139,5,4097},{129,5,5},\n        {137,5,1025},{133,5,65},{141,5,16385},{128,5,3},{136,5,513},\n        {132,5,33},{140,5,8193},{130,5,9},{138,5,2049},{134,5,129},\n        {142,5,32769},{128,5,2},{135,5,385},{131,5,25},{139,5,6145},\n        {129,5,7},{137,5,1537},{133,5,97},{141,5,24577},{128,5,4},\n        {136,5,769},{132,5,49},{140,5,12289},{130,5,13},{138,5,3073},\n        {134,5,193},{142,5,49153}\n    };\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/infback9/inflate9.h",
    "content": "/* inflate9.h -- internal inflate state definition\n * Copyright (C) 1995-2003 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* WARNING: this file should *not* be used by applications. It is\n   part of the implementation of the compression library and is\n   subject to change. Applications should only use zlib.h.\n */\n\n/* Possible inflate modes between inflate() calls */\ntypedef enum {\n        TYPE,       /* i: waiting for type bits, including last-flag bit */\n        STORED,     /* i: waiting for stored size (length and complement) */\n        TABLE,      /* i: waiting for dynamic block table lengths */\n            LEN,        /* i: waiting for length/lit code */\n    DONE,       /* finished check, done -- remain here until reset */\n    BAD         /* got a data error -- remain here until reset */\n} inflate_mode;\n\n/*\n    State transitions between above modes -\n\n    (most modes can go to the BAD mode -- not shown for clarity)\n\n    Read deflate blocks:\n            TYPE -> STORED or TABLE or LEN or DONE\n            STORED -> TYPE\n            TABLE -> LENLENS -> CODELENS -> LEN\n    Read deflate codes:\n                LEN -> LEN or TYPE\n */\n\n/* state maintained between inflate() calls.  Approximately 7K bytes. */\nstruct inflate_state {\n        /* sliding window */\n    unsigned char FAR *window;  /* allocated sliding window, if needed */\n        /* dynamic table building */\n    unsigned ncode;             /* number of code length code lengths */\n    unsigned nlen;              /* number of length code lengths */\n    unsigned ndist;             /* number of distance code lengths */\n    unsigned have;              /* number of code lengths in lens[] */\n    code FAR *next;             /* next available space in codes[] */\n    unsigned short lens[320];   /* temporary storage for code lengths */\n    unsigned short work[288];   /* work area for code table building */\n    code codes[ENOUGH];         /* space for code tables */\n};\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/infback9/inftree9.c",
    "content": "/* inftree9.c -- generate Huffman trees for efficient decoding\n * Copyright (C) 1995-2013 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#include \"zutil.h\"\n#include \"inftree9.h\"\n\n#define MAXBITS 15\n\nconst char inflate9_copyright[] =\n   \" inflate9 1.2.8 Copyright 1995-2013 Mark Adler \";\n/*\n  If you use the zlib library in a product, an acknowledgment is welcome\n  in the documentation of your product. If for some reason you cannot\n  include such an acknowledgment, I would appreciate that you keep this\n  copyright string in the executable of your product.\n */\n\n/*\n   Build a set of tables to decode the provided canonical Huffman code.\n   The code lengths are lens[0..codes-1].  The result starts at *table,\n   whose indices are 0..2^bits-1.  work is a writable array of at least\n   lens shorts, which is used as a work area.  type is the type of code\n   to be generated, CODES, LENS, or DISTS.  On return, zero is success,\n   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table\n   on return points to the next available entry's address.  bits is the\n   requested root table index bits, and on return it is the actual root\n   table index bits.  It will differ if the request is greater than the\n   longest code or if it is less than the shortest code.\n */\nint inflate_table9(type, lens, codes, table, bits, work)\ncodetype type;\nunsigned short FAR *lens;\nunsigned codes;\ncode FAR * FAR *table;\nunsigned FAR *bits;\nunsigned short FAR *work;\n{\n    unsigned len;               /* a code's length in bits */\n    unsigned sym;               /* index of code symbols */\n    unsigned min, max;          /* minimum and maximum code lengths */\n    unsigned root;              /* number of index bits for root table */\n    unsigned curr;              /* number of index bits for current table */\n    unsigned drop;              /* code bits to drop for sub-table */\n    int left;                   /* number of prefix codes available */\n    unsigned used;              /* code entries in table used */\n    unsigned huff;              /* Huffman code */\n    unsigned incr;              /* for incrementing code, index */\n    unsigned fill;              /* index for replicating entries */\n    unsigned low;               /* low bits for current root entry */\n    unsigned mask;              /* mask for low root bits */\n    code this;                  /* table entry for duplication */\n    code FAR *next;             /* next available space in table */\n    const unsigned short FAR *base;     /* base value table to use */\n    const unsigned short FAR *extra;    /* extra bits table to use */\n    int end;                    /* use base and extra for symbol > end */\n    unsigned short count[MAXBITS+1];    /* number of codes of each length */\n    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */\n    static const unsigned short lbase[31] = { /* Length codes 257..285 base */\n        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17,\n        19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115,\n        131, 163, 195, 227, 3, 0, 0};\n    static const unsigned short lext[31] = { /* Length codes 257..285 extra */\n        128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,\n        130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,\n        133, 133, 133, 133, 144, 72, 78};\n    static const unsigned short dbase[32] = { /* Distance codes 0..31 base */\n        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,\n        65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,\n        4097, 6145, 8193, 12289, 16385, 24577, 32769, 49153};\n    static const unsigned short dext[32] = { /* Distance codes 0..31 extra */\n        128, 128, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132,\n        133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 138, 138,\n        139, 139, 140, 140, 141, 141, 142, 142};\n\n    /*\n       Process a set of code lengths to create a canonical Huffman code.  The\n       code lengths are lens[0..codes-1].  Each length corresponds to the\n       symbols 0..codes-1.  The Huffman code is generated by first sorting the\n       symbols by length from short to long, and retaining the symbol order\n       for codes with equal lengths.  Then the code starts with all zero bits\n       for the first code of the shortest length, and the codes are integer\n       increments for the same length, and zeros are appended as the length\n       increases.  For the deflate format, these bits are stored backwards\n       from their more natural integer increment ordering, and so when the\n       decoding tables are built in the large loop below, the integer codes\n       are incremented backwards.\n\n       This routine assumes, but does not check, that all of the entries in\n       lens[] are in the range 0..MAXBITS.  The caller must assure this.\n       1..MAXBITS is interpreted as that code length.  zero means that that\n       symbol does not occur in this code.\n\n       The codes are sorted by computing a count of codes for each length,\n       creating from that a table of starting indices for each length in the\n       sorted table, and then entering the symbols in order in the sorted\n       table.  The sorted table is work[], with that space being provided by\n       the caller.\n\n       The length counts are used for other purposes as well, i.e. finding\n       the minimum and maximum length codes, determining if there are any\n       codes at all, checking for a valid set of lengths, and looking ahead\n       at length counts to determine sub-table sizes when building the\n       decoding tables.\n     */\n\n    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */\n    for (len = 0; len <= MAXBITS; len++)\n        count[len] = 0;\n    for (sym = 0; sym < codes; sym++)\n        count[lens[sym]]++;\n\n    /* bound code lengths, force root to be within code lengths */\n    root = *bits;\n    for (max = MAXBITS; max >= 1; max--)\n        if (count[max] != 0) break;\n    if (root > max) root = max;\n    if (max == 0) return -1;            /* no codes! */\n    for (min = 1; min <= MAXBITS; min++)\n        if (count[min] != 0) break;\n    if (root < min) root = min;\n\n    /* check for an over-subscribed or incomplete set of lengths */\n    left = 1;\n    for (len = 1; len <= MAXBITS; len++) {\n        left <<= 1;\n        left -= count[len];\n        if (left < 0) return -1;        /* over-subscribed */\n    }\n    if (left > 0 && (type == CODES || max != 1))\n        return -1;                      /* incomplete set */\n\n    /* generate offsets into symbol table for each length for sorting */\n    offs[1] = 0;\n    for (len = 1; len < MAXBITS; len++)\n        offs[len + 1] = offs[len] + count[len];\n\n    /* sort symbols by length, by symbol order within each length */\n    for (sym = 0; sym < codes; sym++)\n        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;\n\n    /*\n       Create and fill in decoding tables.  In this loop, the table being\n       filled is at next and has curr index bits.  The code being used is huff\n       with length len.  That code is converted to an index by dropping drop\n       bits off of the bottom.  For codes where len is less than drop + curr,\n       those top drop + curr - len bits are incremented through all values to\n       fill the table with replicated entries.\n\n       root is the number of index bits for the root table.  When len exceeds\n       root, sub-tables are created pointed to by the root entry with an index\n       of the low root bits of huff.  This is saved in low to check for when a\n       new sub-table should be started.  drop is zero when the root table is\n       being filled, and drop is root when sub-tables are being filled.\n\n       When a new sub-table is needed, it is necessary to look ahead in the\n       code lengths to determine what size sub-table is needed.  The length\n       counts are used for this, and so count[] is decremented as codes are\n       entered in the tables.\n\n       used keeps track of how many table entries have been allocated from the\n       provided *table space.  It is checked for LENS and DIST tables against\n       the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in\n       the initial root table size constants.  See the comments in inftree9.h\n       for more information.\n\n       sym increments through all symbols, and the loop terminates when\n       all codes of length max, i.e. all codes, have been processed.  This\n       routine permits incomplete codes, so another loop after this one fills\n       in the rest of the decoding tables with invalid code markers.\n     */\n\n    /* set up for code type */\n    switch (type) {\n    case CODES:\n        base = extra = work;    /* dummy value--not used */\n        end = 19;\n        break;\n    case LENS:\n        base = lbase;\n        base -= 257;\n        extra = lext;\n        extra -= 257;\n        end = 256;\n        break;\n    default:            /* DISTS */\n        base = dbase;\n        extra = dext;\n        end = -1;\n    }\n\n    /* initialize state for loop */\n    huff = 0;                   /* starting code */\n    sym = 0;                    /* starting code symbol */\n    len = min;                  /* starting code length */\n    next = *table;              /* current table to fill in */\n    curr = root;                /* current table index bits */\n    drop = 0;                   /* current bits to drop from code for index */\n    low = (unsigned)(-1);       /* trigger new sub-table when len > root */\n    used = 1U << root;          /* use root table entries */\n    mask = used - 1;            /* mask for comparing low */\n\n    /* check available table space */\n    if ((type == LENS && used >= ENOUGH_LENS) ||\n        (type == DISTS && used >= ENOUGH_DISTS))\n        return 1;\n\n    /* process all codes and make table entries */\n    for (;;) {\n        /* create table entry */\n        this.bits = (unsigned char)(len - drop);\n        if ((int)(work[sym]) < end) {\n            this.op = (unsigned char)0;\n            this.val = work[sym];\n        }\n        else if ((int)(work[sym]) > end) {\n            this.op = (unsigned char)(extra[work[sym]]);\n            this.val = base[work[sym]];\n        }\n        else {\n            this.op = (unsigned char)(32 + 64);         /* end of block */\n            this.val = 0;\n        }\n\n        /* replicate for those indices with low len bits equal to huff */\n        incr = 1U << (len - drop);\n        fill = 1U << curr;\n        do {\n            fill -= incr;\n            next[(huff >> drop) + fill] = this;\n        } while (fill != 0);\n\n        /* backwards increment the len-bit code huff */\n        incr = 1U << (len - 1);\n        while (huff & incr)\n            incr >>= 1;\n        if (incr != 0) {\n            huff &= incr - 1;\n            huff += incr;\n        }\n        else\n            huff = 0;\n\n        /* go to next symbol, update count, len */\n        sym++;\n        if (--(count[len]) == 0) {\n            if (len == max) break;\n            len = lens[work[sym]];\n        }\n\n        /* create new sub-table if needed */\n        if (len > root && (huff & mask) != low) {\n            /* if first time, transition to sub-tables */\n            if (drop == 0)\n                drop = root;\n\n            /* increment past last table */\n            next += 1U << curr;\n\n            /* determine length of next table */\n            curr = len - drop;\n            left = (int)(1 << curr);\n            while (curr + drop < max) {\n                left -= count[curr + drop];\n                if (left <= 0) break;\n                curr++;\n                left <<= 1;\n            }\n\n            /* check for enough space */\n            used += 1U << curr;\n            if ((type == LENS && used >= ENOUGH_LENS) ||\n                (type == DISTS && used >= ENOUGH_DISTS))\n                return 1;\n\n            /* point entry in root table to sub-table */\n            low = huff & mask;\n            (*table)[low].op = (unsigned char)curr;\n            (*table)[low].bits = (unsigned char)root;\n            (*table)[low].val = (unsigned short)(next - *table);\n        }\n    }\n\n    /*\n       Fill in rest of table for incomplete codes.  This loop is similar to the\n       loop above in incrementing huff for table indices.  It is assumed that\n       len is equal to curr + drop, so there is no loop needed to increment\n       through high index bits.  When the current sub-table is filled, the loop\n       drops back to the root table to fill in any remaining entries there.\n     */\n    this.op = (unsigned char)64;                /* invalid code marker */\n    this.bits = (unsigned char)(len - drop);\n    this.val = (unsigned short)0;\n    while (huff != 0) {\n        /* when done with sub-table, drop back to root table */\n        if (drop != 0 && (huff & mask) != low) {\n            drop = 0;\n            len = root;\n            next = *table;\n            curr = root;\n            this.bits = (unsigned char)len;\n        }\n\n        /* put invalid code marker in table */\n        next[huff >> drop] = this;\n\n        /* backwards increment the len-bit code huff */\n        incr = 1U << (len - 1);\n        while (huff & incr)\n            incr >>= 1;\n        if (incr != 0) {\n            huff &= incr - 1;\n            huff += incr;\n        }\n        else\n            huff = 0;\n    }\n\n    /* set return parameters */\n    *table += used;\n    *bits = root;\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/infback9/inftree9.h",
    "content": "/* inftree9.h -- header to use inftree9.c\n * Copyright (C) 1995-2008 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* WARNING: this file should *not* be used by applications. It is\n   part of the implementation of the compression library and is\n   subject to change. Applications should only use zlib.h.\n */\n\n/* Structure for decoding tables.  Each entry provides either the\n   information needed to do the operation requested by the code that\n   indexed that table entry, or it provides a pointer to another\n   table that indexes more bits of the code.  op indicates whether\n   the entry is a pointer to another table, a literal, a length or\n   distance, an end-of-block, or an invalid code.  For a table\n   pointer, the low four bits of op is the number of index bits of\n   that table.  For a length or distance, the low four bits of op\n   is the number of extra bits to get after the code.  bits is\n   the number of bits in this code or part of the code to drop off\n   of the bit buffer.  val is the actual byte to output in the case\n   of a literal, the base length or distance, or the offset from\n   the current table to the next table.  Each entry is four bytes. */\ntypedef struct {\n    unsigned char op;           /* operation, extra bits, table bits */\n    unsigned char bits;         /* bits in this part of the code */\n    unsigned short val;         /* offset in table or code value */\n} code;\n\n/* op values as set by inflate_table():\n    00000000 - literal\n    0000tttt - table link, tttt != 0 is the number of table index bits\n    100eeeee - length or distance, eeee is the number of extra bits\n    01100000 - end of block\n    01000000 - invalid code\n */\n\n/* Maximum size of the dynamic table.  The maximum number of code structures is\n   1446, which is the sum of 852 for literal/length codes and 594 for distance\n   codes.  These values were found by exhaustive searches using the program\n   examples/enough.c found in the zlib distribtution.  The arguments to that\n   program are the number of symbols, the initial root table size, and the\n   maximum bit length of a code.  \"enough 286 9 15\" for literal/length codes\n   returns returns 852, and \"enough 32 6 15\" for distance codes returns 594.\n   The initial root table size (9 or 6) is found in the fifth argument of the\n   inflate_table() calls in infback9.c.  If the root table size is changed,\n   then these maximum sizes would be need to be recalculated and updated. */\n#define ENOUGH_LENS 852\n#define ENOUGH_DISTS 594\n#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)\n\n/* Type of code to build for inflate_table9() */\ntypedef enum {\n    CODES,\n    LENS,\n    DISTS\n} codetype;\n\nextern int inflate_table9 OF((codetype type, unsigned short FAR *lens,\n                             unsigned codes, code FAR * FAR *table,\n                             unsigned FAR *bits, unsigned short FAR *work));\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/inflate86/inffas86.c",
    "content": "/* inffas86.c is a hand tuned assembler version of\n *\n * inffast.c -- fast decoding\n * Copyright (C) 1995-2003 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n *\n * Copyright (C) 2003 Chris Anderson <christop@charm.net>\n * Please use the copyright conditions above.\n *\n * Dec-29-2003 -- I added AMD64 inflate asm support.  This version is also\n * slightly quicker on x86 systems because, instead of using rep movsb to copy\n * data, it uses rep movsw, which moves data in 2-byte chunks instead of single\n * bytes.  I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates\n * from http://fedora.linux.duke.edu/fc1_x86_64\n * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with\n * 1GB ram.  The 64-bit version is about 4% faster than the 32-bit version,\n * when decompressing mozilla-source-1.3.tar.gz.\n *\n * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from\n * the gcc -S output of zlib-1.2.0/inffast.c.  Zlib-1.2.0 is in beta release at\n * the moment.  I have successfully compiled and tested this code with gcc2.96,\n * gcc3.2, icc5.0, msvc6.0.  It is very close to the speed of inffast.S\n * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX\n * enabled.  I will attempt to merge the MMX code into this version.  Newer\n * versions of this and inffast.S can be found at\n * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/\n */\n\n#include \"zutil.h\"\n#include \"inftrees.h\"\n#include \"inflate.h\"\n#include \"inffast.h\"\n\n/* Mark Adler's comments from inffast.c: */\n\n/*\n   Decode literal, length, and distance codes and write out the resulting\n   literal and match bytes until either not enough input or output is\n   available, an end-of-block is encountered, or a data error is encountered.\n   When large enough input and output buffers are supplied to inflate(), for\n   example, a 16K input buffer and a 64K output buffer, more than 95% of the\n   inflate execution time is spent in this routine.\n\n   Entry assumptions:\n\n        state->mode == LEN\n        strm->avail_in >= 6\n        strm->avail_out >= 258\n        start >= strm->avail_out\n        state->bits < 8\n\n   On return, state->mode is one of:\n\n        LEN -- ran out of enough output space or enough available input\n        TYPE -- reached end of block code, inflate() to interpret next block\n        BAD -- error in block data\n\n   Notes:\n\n    - The maximum input bits used by a length/distance pair is 15 bits for the\n      length code, 5 bits for the length extra, 15 bits for the distance code,\n      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.\n      Therefore if strm->avail_in >= 6, then there is enough input to avoid\n      checking for available input while decoding.\n\n    - The maximum bytes that a single length/distance pair can output is 258\n      bytes, which is the maximum length that can be coded.  inflate_fast()\n      requires strm->avail_out >= 258 for each loop to avoid checking for\n      output space.\n */\nvoid inflate_fast(strm, start)\nz_streamp strm;\nunsigned start;         /* inflate()'s starting value for strm->avail_out */\n{\n    struct inflate_state FAR *state;\n    struct inffast_ar {\n/* 64   32                               x86  x86_64 */\n/* ar offset                              register */\n/*  0    0 */ void *esp;                /* esp save */\n/*  8    4 */ void *ebp;                /* ebp save */\n/* 16    8 */ unsigned char FAR *in;    /* esi rsi  local strm->next_in */\n/* 24   12 */ unsigned char FAR *last;  /*     r9   while in < last */\n/* 32   16 */ unsigned char FAR *out;   /* edi rdi  local strm->next_out */\n/* 40   20 */ unsigned char FAR *beg;   /*          inflate()'s init next_out */\n/* 48   24 */ unsigned char FAR *end;   /*     r10  while out < end */\n/* 56   28 */ unsigned char FAR *window;/*          size of window, wsize!=0 */\n/* 64   32 */ code const FAR *lcode;    /* ebp rbp  local strm->lencode */\n/* 72   36 */ code const FAR *dcode;    /*     r11  local strm->distcode */\n/* 80   40 */ unsigned long hold;       /* edx rdx  local strm->hold */\n/* 88   44 */ unsigned bits;            /* ebx rbx  local strm->bits */\n/* 92   48 */ unsigned wsize;           /*          window size */\n/* 96   52 */ unsigned write;           /*          window write index */\n/*100   56 */ unsigned lmask;           /*     r12  mask for lcode */\n/*104   60 */ unsigned dmask;           /*     r13  mask for dcode */\n/*108   64 */ unsigned len;             /*     r14  match length */\n/*112   68 */ unsigned dist;            /*     r15  match distance */\n/*116   72 */ unsigned status;          /*          set when state chng*/\n    } ar;\n\n#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )\n#define PAD_AVAIL_IN 6\n#define PAD_AVAIL_OUT 258\n#else\n#define PAD_AVAIL_IN 5\n#define PAD_AVAIL_OUT 257\n#endif\n\n    /* copy state to local variables */\n    state = (struct inflate_state FAR *)strm->state;\n    ar.in = strm->next_in;\n    ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);\n    ar.out = strm->next_out;\n    ar.beg = ar.out - (start - strm->avail_out);\n    ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);\n    ar.wsize = state->wsize;\n    ar.write = state->wnext;\n    ar.window = state->window;\n    ar.hold = state->hold;\n    ar.bits = state->bits;\n    ar.lcode = state->lencode;\n    ar.dcode = state->distcode;\n    ar.lmask = (1U << state->lenbits) - 1;\n    ar.dmask = (1U << state->distbits) - 1;\n\n    /* decode literals and length/distances until end-of-block or not enough\n       input data or output space */\n\n    /* align in on 1/2 hold size boundary */\n    while (((unsigned long)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {\n        ar.hold += (unsigned long)*ar.in++ << ar.bits;\n        ar.bits += 8;\n    }\n\n#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )\n    __asm__ __volatile__ (\n\"        leaq    %0, %%rax\\n\"\n\"        movq    %%rbp, 8(%%rax)\\n\"       /* save regs rbp and rsp */\n\"        movq    %%rsp, (%%rax)\\n\"\n\"        movq    %%rax, %%rsp\\n\"          /* make rsp point to &ar */\n\"        movq    16(%%rsp), %%rsi\\n\"      /* rsi  = in */\n\"        movq    32(%%rsp), %%rdi\\n\"      /* rdi  = out */\n\"        movq    24(%%rsp), %%r9\\n\"       /* r9   = last */\n\"        movq    48(%%rsp), %%r10\\n\"      /* r10  = end */\n\"        movq    64(%%rsp), %%rbp\\n\"      /* rbp  = lcode */\n\"        movq    72(%%rsp), %%r11\\n\"      /* r11  = dcode */\n\"        movq    80(%%rsp), %%rdx\\n\"      /* rdx  = hold */\n\"        movl    88(%%rsp), %%ebx\\n\"      /* ebx  = bits */\n\"        movl    100(%%rsp), %%r12d\\n\"    /* r12d = lmask */\n\"        movl    104(%%rsp), %%r13d\\n\"    /* r13d = dmask */\n                                          /* r14d = len */\n                                          /* r15d = dist */\n\"        cld\\n\"\n\"        cmpq    %%rdi, %%r10\\n\"\n\"        je      .L_one_time\\n\"           /* if only one decode left */\n\"        cmpq    %%rsi, %%r9\\n\"\n\"        je      .L_one_time\\n\"\n\"        jmp     .L_do_loop\\n\"\n\n\".L_one_time:\\n\"\n\"        movq    %%r12, %%r8\\n\"           /* r8 = lmask */\n\"        cmpb    $32, %%bl\\n\"\n\"        ja      .L_get_length_code_one_time\\n\"\n\n\"        lodsl\\n\"                         /* eax = *(uint *)in++ */\n\"        movb    %%bl, %%cl\\n\"            /* cl = bits, needs it for shifting */\n\"        addb    $32, %%bl\\n\"             /* bits += 32 */\n\"        shlq    %%cl, %%rax\\n\"\n\"        orq     %%rax, %%rdx\\n\"          /* hold |= *((uint *)in)++ << bits */\n\"        jmp     .L_get_length_code_one_time\\n\"\n\n\".align 32,0x90\\n\"\n\".L_while_test:\\n\"\n\"        cmpq    %%rdi, %%r10\\n\"\n\"        jbe     .L_break_loop\\n\"\n\"        cmpq    %%rsi, %%r9\\n\"\n\"        jbe     .L_break_loop\\n\"\n\n\".L_do_loop:\\n\"\n\"        movq    %%r12, %%r8\\n\"           /* r8 = lmask */\n\"        cmpb    $32, %%bl\\n\"\n\"        ja      .L_get_length_code\\n\"    /* if (32 < bits) */\n\n\"        lodsl\\n\"                         /* eax = *(uint *)in++ */\n\"        movb    %%bl, %%cl\\n\"            /* cl = bits, needs it for shifting */\n\"        addb    $32, %%bl\\n\"             /* bits += 32 */\n\"        shlq    %%cl, %%rax\\n\"\n\"        orq     %%rax, %%rdx\\n\"          /* hold |= *((uint *)in)++ << bits */\n\n\".L_get_length_code:\\n\"\n\"        andq    %%rdx, %%r8\\n\"            /* r8 &= hold */\n\"        movl    (%%rbp,%%r8,4), %%eax\\n\"  /* eax = lcode[hold & lmask] */\n\n\"        movb    %%ah, %%cl\\n\"            /* cl = this.bits */\n\"        subb    %%ah, %%bl\\n\"            /* bits -= this.bits */\n\"        shrq    %%cl, %%rdx\\n\"           /* hold >>= this.bits */\n\n\"        testb   %%al, %%al\\n\"\n\"        jnz     .L_test_for_length_base\\n\" /* if (op != 0) 45.7% */\n\n\"        movq    %%r12, %%r8\\n\"            /* r8 = lmask */\n\"        shrl    $16, %%eax\\n\"            /* output this.val char */\n\"        stosb\\n\"\n\n\".L_get_length_code_one_time:\\n\"\n\"        andq    %%rdx, %%r8\\n\"            /* r8 &= hold */\n\"        movl    (%%rbp,%%r8,4), %%eax\\n\" /* eax = lcode[hold & lmask] */\n\n\".L_dolen:\\n\"\n\"        movb    %%ah, %%cl\\n\"            /* cl = this.bits */\n\"        subb    %%ah, %%bl\\n\"            /* bits -= this.bits */\n\"        shrq    %%cl, %%rdx\\n\"           /* hold >>= this.bits */\n\n\"        testb   %%al, %%al\\n\"\n\"        jnz     .L_test_for_length_base\\n\" /* if (op != 0) 45.7% */\n\n\"        shrl    $16, %%eax\\n\"            /* output this.val char */\n\"        stosb\\n\"\n\"        jmp     .L_while_test\\n\"\n\n\".align 32,0x90\\n\"\n\".L_test_for_length_base:\\n\"\n\"        movl    %%eax, %%r14d\\n\"         /* len = this */\n\"        shrl    $16, %%r14d\\n\"           /* len = this.val */\n\"        movb    %%al, %%cl\\n\"\n\n\"        testb   $16, %%al\\n\"\n\"        jz      .L_test_for_second_level_length\\n\" /* if ((op & 16) == 0) 8% */\n\"        andb    $15, %%cl\\n\"             /* op &= 15 */\n\"        jz      .L_decode_distance\\n\"    /* if (!op) */\n\n\".L_add_bits_to_len:\\n\"\n\"        subb    %%cl, %%bl\\n\"\n\"        xorl    %%eax, %%eax\\n\"\n\"        incl    %%eax\\n\"\n\"        shll    %%cl, %%eax\\n\"\n\"        decl    %%eax\\n\"\n\"        andl    %%edx, %%eax\\n\"          /* eax &= hold */\n\"        shrq    %%cl, %%rdx\\n\"\n\"        addl    %%eax, %%r14d\\n\"         /* len += hold & mask[op] */\n\n\".L_decode_distance:\\n\"\n\"        movq    %%r13, %%r8\\n\"           /* r8 = dmask */\n\"        cmpb    $32, %%bl\\n\"\n\"        ja      .L_get_distance_code\\n\"  /* if (32 < bits) */\n\n\"        lodsl\\n\"                         /* eax = *(uint *)in++ */\n\"        movb    %%bl, %%cl\\n\"            /* cl = bits, needs it for shifting */\n\"        addb    $32, %%bl\\n\"             /* bits += 32 */\n\"        shlq    %%cl, %%rax\\n\"\n\"        orq     %%rax, %%rdx\\n\"          /* hold |= *((uint *)in)++ << bits */\n\n\".L_get_distance_code:\\n\"\n\"        andq    %%rdx, %%r8\\n\"           /* r8 &= hold */\n\"        movl    (%%r11,%%r8,4), %%eax\\n\" /* eax = dcode[hold & dmask] */\n\n\".L_dodist:\\n\"\n\"        movl    %%eax, %%r15d\\n\"         /* dist = this */\n\"        shrl    $16, %%r15d\\n\"           /* dist = this.val */\n\"        movb    %%ah, %%cl\\n\"\n\"        subb    %%ah, %%bl\\n\"            /* bits -= this.bits */\n\"        shrq    %%cl, %%rdx\\n\"           /* hold >>= this.bits */\n\"        movb    %%al, %%cl\\n\"            /* cl = this.op */\n\n\"        testb   $16, %%al\\n\"             /* if ((op & 16) == 0) */\n\"        jz      .L_test_for_second_level_dist\\n\"\n\"        andb    $15, %%cl\\n\"             /* op &= 15 */\n\"        jz      .L_check_dist_one\\n\"\n\n\".L_add_bits_to_dist:\\n\"\n\"        subb    %%cl, %%bl\\n\"\n\"        xorl    %%eax, %%eax\\n\"\n\"        incl    %%eax\\n\"\n\"        shll    %%cl, %%eax\\n\"\n\"        decl    %%eax\\n\"                 /* (1 << op) - 1 */\n\"        andl    %%edx, %%eax\\n\"          /* eax &= hold */\n\"        shrq    %%cl, %%rdx\\n\"\n\"        addl    %%eax, %%r15d\\n\"         /* dist += hold & ((1 << op) - 1) */\n\n\".L_check_window:\\n\"\n\"        movq    %%rsi, %%r8\\n\"           /* save in so from can use it's reg */\n\"        movq    %%rdi, %%rax\\n\"\n\"        subq    40(%%rsp), %%rax\\n\"      /* nbytes = out - beg */\n\n\"        cmpl    %%r15d, %%eax\\n\"\n\"        jb      .L_clip_window\\n\"        /* if (dist > nbytes) 4.2% */\n\n\"        movl    %%r14d, %%ecx\\n\"         /* ecx = len */\n\"        movq    %%rdi, %%rsi\\n\"\n\"        subq    %%r15, %%rsi\\n\"          /* from = out - dist */\n\n\"        sarl    %%ecx\\n\"\n\"        jnc     .L_copy_two\\n\"           /* if len % 2 == 0 */\n\n\"        rep     movsw\\n\"\n\"        movb    (%%rsi), %%al\\n\"\n\"        movb    %%al, (%%rdi)\\n\"\n\"        incq    %%rdi\\n\"\n\n\"        movq    %%r8, %%rsi\\n\"           /* move in back to %rsi, toss from */\n\"        jmp     .L_while_test\\n\"\n\n\".L_copy_two:\\n\"\n\"        rep     movsw\\n\"\n\"        movq    %%r8, %%rsi\\n\"           /* move in back to %rsi, toss from */\n\"        jmp     .L_while_test\\n\"\n\n\".align 32,0x90\\n\"\n\".L_check_dist_one:\\n\"\n\"        cmpl    $1, %%r15d\\n\"            /* if dist 1, is a memset */\n\"        jne     .L_check_window\\n\"\n\"        cmpq    %%rdi, 40(%%rsp)\\n\"      /* if out == beg, outside window */\n\"        je      .L_check_window\\n\"\n\n\"        movl    %%r14d, %%ecx\\n\"         /* ecx = len */\n\"        movb    -1(%%rdi), %%al\\n\"\n\"        movb    %%al, %%ah\\n\"\n\n\"        sarl    %%ecx\\n\"\n\"        jnc     .L_set_two\\n\"\n\"        movb    %%al, (%%rdi)\\n\"\n\"        incq    %%rdi\\n\"\n\n\".L_set_two:\\n\"\n\"        rep     stosw\\n\"\n\"        jmp     .L_while_test\\n\"\n\n\".align 32,0x90\\n\"\n\".L_test_for_second_level_length:\\n\"\n\"        testb   $64, %%al\\n\"\n\"        jnz     .L_test_for_end_of_block\\n\" /* if ((op & 64) != 0) */\n\n\"        xorl    %%eax, %%eax\\n\"\n\"        incl    %%eax\\n\"\n\"        shll    %%cl, %%eax\\n\"\n\"        decl    %%eax\\n\"\n\"        andl    %%edx, %%eax\\n\"         /* eax &= hold */\n\"        addl    %%r14d, %%eax\\n\"        /* eax += len */\n\"        movl    (%%rbp,%%rax,4), %%eax\\n\" /* eax = lcode[val+(hold&mask[op])]*/\n\"        jmp     .L_dolen\\n\"\n\n\".align 32,0x90\\n\"\n\".L_test_for_second_level_dist:\\n\"\n\"        testb   $64, %%al\\n\"\n\"        jnz     .L_invalid_distance_code\\n\" /* if ((op & 64) != 0) */\n\n\"        xorl    %%eax, %%eax\\n\"\n\"        incl    %%eax\\n\"\n\"        shll    %%cl, %%eax\\n\"\n\"        decl    %%eax\\n\"\n\"        andl    %%edx, %%eax\\n\"         /* eax &= hold */\n\"        addl    %%r15d, %%eax\\n\"        /* eax += dist */\n\"        movl    (%%r11,%%rax,4), %%eax\\n\" /* eax = dcode[val+(hold&mask[op])]*/\n\"        jmp     .L_dodist\\n\"\n\n\".align 32,0x90\\n\"\n\".L_clip_window:\\n\"\n\"        movl    %%eax, %%ecx\\n\"         /* ecx = nbytes */\n\"        movl    92(%%rsp), %%eax\\n\"     /* eax = wsize, prepare for dist cmp */\n\"        negl    %%ecx\\n\"                /* nbytes = -nbytes */\n\n\"        cmpl    %%r15d, %%eax\\n\"\n\"        jb      .L_invalid_distance_too_far\\n\" /* if (dist > wsize) */\n\n\"        addl    %%r15d, %%ecx\\n\"         /* nbytes = dist - nbytes */\n\"        cmpl    $0, 96(%%rsp)\\n\"\n\"        jne     .L_wrap_around_window\\n\" /* if (write != 0) */\n\n\"        movq    56(%%rsp), %%rsi\\n\"     /* from  = window */\n\"        subl    %%ecx, %%eax\\n\"         /* eax  -= nbytes */\n\"        addq    %%rax, %%rsi\\n\"         /* from += wsize - nbytes */\n\n\"        movl    %%r14d, %%eax\\n\"        /* eax = len */\n\"        cmpl    %%ecx, %%r14d\\n\"\n\"        jbe     .L_do_copy\\n\"           /* if (nbytes >= len) */\n\n\"        subl    %%ecx, %%eax\\n\"         /* eax -= nbytes */\n\"        rep     movsb\\n\"\n\"        movq    %%rdi, %%rsi\\n\"\n\"        subq    %%r15, %%rsi\\n\"         /* from = &out[ -dist ] */\n\"        jmp     .L_do_copy\\n\"\n\n\".align 32,0x90\\n\"\n\".L_wrap_around_window:\\n\"\n\"        movl    96(%%rsp), %%eax\\n\"     /* eax = write */\n\"        cmpl    %%eax, %%ecx\\n\"\n\"        jbe     .L_contiguous_in_window\\n\" /* if (write >= nbytes) */\n\n\"        movl    92(%%rsp), %%esi\\n\"     /* from  = wsize */\n\"        addq    56(%%rsp), %%rsi\\n\"     /* from += window */\n\"        addq    %%rax, %%rsi\\n\"         /* from += write */\n\"        subq    %%rcx, %%rsi\\n\"         /* from -= nbytes */\n\"        subl    %%eax, %%ecx\\n\"         /* nbytes -= write */\n\n\"        movl    %%r14d, %%eax\\n\"        /* eax = len */\n\"        cmpl    %%ecx, %%eax\\n\"\n\"        jbe     .L_do_copy\\n\"           /* if (nbytes >= len) */\n\n\"        subl    %%ecx, %%eax\\n\"         /* len -= nbytes */\n\"        rep     movsb\\n\"\n\"        movq    56(%%rsp), %%rsi\\n\"     /* from = window */\n\"        movl    96(%%rsp), %%ecx\\n\"     /* nbytes = write */\n\"        cmpl    %%ecx, %%eax\\n\"\n\"        jbe     .L_do_copy\\n\"           /* if (nbytes >= len) */\n\n\"        subl    %%ecx, %%eax\\n\"         /* len -= nbytes */\n\"        rep     movsb\\n\"\n\"        movq    %%rdi, %%rsi\\n\"\n\"        subq    %%r15, %%rsi\\n\"         /* from = out - dist */\n\"        jmp     .L_do_copy\\n\"\n\n\".align 32,0x90\\n\"\n\".L_contiguous_in_window:\\n\"\n\"        movq    56(%%rsp), %%rsi\\n\"     /* rsi = window */\n\"        addq    %%rax, %%rsi\\n\"\n\"        subq    %%rcx, %%rsi\\n\"         /* from += write - nbytes */\n\n\"        movl    %%r14d, %%eax\\n\"        /* eax = len */\n\"        cmpl    %%ecx, %%eax\\n\"\n\"        jbe     .L_do_copy\\n\"           /* if (nbytes >= len) */\n\n\"        subl    %%ecx, %%eax\\n\"         /* len -= nbytes */\n\"        rep     movsb\\n\"\n\"        movq    %%rdi, %%rsi\\n\"\n\"        subq    %%r15, %%rsi\\n\"         /* from = out - dist */\n\"        jmp     .L_do_copy\\n\"           /* if (nbytes >= len) */\n\n\".align 32,0x90\\n\"\n\".L_do_copy:\\n\"\n\"        movl    %%eax, %%ecx\\n\"         /* ecx = len */\n\"        rep     movsb\\n\"\n\n\"        movq    %%r8, %%rsi\\n\"          /* move in back to %esi, toss from */\n\"        jmp     .L_while_test\\n\"\n\n\".L_test_for_end_of_block:\\n\"\n\"        testb   $32, %%al\\n\"\n\"        jz      .L_invalid_literal_length_code\\n\"\n\"        movl    $1, 116(%%rsp)\\n\"\n\"        jmp     .L_break_loop_with_status\\n\"\n\n\".L_invalid_literal_length_code:\\n\"\n\"        movl    $2, 116(%%rsp)\\n\"\n\"        jmp     .L_break_loop_with_status\\n\"\n\n\".L_invalid_distance_code:\\n\"\n\"        movl    $3, 116(%%rsp)\\n\"\n\"        jmp     .L_break_loop_with_status\\n\"\n\n\".L_invalid_distance_too_far:\\n\"\n\"        movl    $4, 116(%%rsp)\\n\"\n\"        jmp     .L_break_loop_with_status\\n\"\n\n\".L_break_loop:\\n\"\n\"        movl    $0, 116(%%rsp)\\n\"\n\n\".L_break_loop_with_status:\\n\"\n/* put in, out, bits, and hold back into ar and pop esp */\n\"        movq    %%rsi, 16(%%rsp)\\n\"     /* in */\n\"        movq    %%rdi, 32(%%rsp)\\n\"     /* out */\n\"        movl    %%ebx, 88(%%rsp)\\n\"     /* bits */\n\"        movq    %%rdx, 80(%%rsp)\\n\"     /* hold */\n\"        movq    (%%rsp), %%rax\\n\"       /* restore rbp and rsp */\n\"        movq    8(%%rsp), %%rbp\\n\"\n\"        movq    %%rax, %%rsp\\n\"\n          :\n          : \"m\" (ar)\n          : \"memory\", \"%rax\", \"%rbx\", \"%rcx\", \"%rdx\", \"%rsi\", \"%rdi\",\n            \"%r8\", \"%r9\", \"%r10\", \"%r11\", \"%r12\", \"%r13\", \"%r14\", \"%r15\"\n    );\n#elif ( defined( __GNUC__ ) || defined( __ICC ) ) && defined( __i386 )\n    __asm__ __volatile__ (\n\"        leal    %0, %%eax\\n\"\n\"        movl    %%esp, (%%eax)\\n\"        /* save esp, ebp */\n\"        movl    %%ebp, 4(%%eax)\\n\"\n\"        movl    %%eax, %%esp\\n\"\n\"        movl    8(%%esp), %%esi\\n\"       /* esi = in */\n\"        movl    16(%%esp), %%edi\\n\"      /* edi = out */\n\"        movl    40(%%esp), %%edx\\n\"      /* edx = hold */\n\"        movl    44(%%esp), %%ebx\\n\"      /* ebx = bits */\n\"        movl    32(%%esp), %%ebp\\n\"      /* ebp = lcode */\n\n\"        cld\\n\"\n\"        jmp     .L_do_loop\\n\"\n\n\".align 32,0x90\\n\"\n\".L_while_test:\\n\"\n\"        cmpl    %%edi, 24(%%esp)\\n\"      /* out < end */\n\"        jbe     .L_break_loop\\n\"\n\"        cmpl    %%esi, 12(%%esp)\\n\"      /* in < last */\n\"        jbe     .L_break_loop\\n\"\n\n\".L_do_loop:\\n\"\n\"        cmpb    $15, %%bl\\n\"\n\"        ja      .L_get_length_code\\n\"    /* if (15 < bits) */\n\n\"        xorl    %%eax, %%eax\\n\"\n\"        lodsw\\n\"                         /* al = *(ushort *)in++ */\n\"        movb    %%bl, %%cl\\n\"            /* cl = bits, needs it for shifting */\n\"        addb    $16, %%bl\\n\"             /* bits += 16 */\n\"        shll    %%cl, %%eax\\n\"\n\"        orl     %%eax, %%edx\\n\"        /* hold |= *((ushort *)in)++ << bits */\n\n\".L_get_length_code:\\n\"\n\"        movl    56(%%esp), %%eax\\n\"      /* eax = lmask */\n\"        andl    %%edx, %%eax\\n\"          /* eax &= hold */\n\"        movl    (%%ebp,%%eax,4), %%eax\\n\" /* eax = lcode[hold & lmask] */\n\n\".L_dolen:\\n\"\n\"        movb    %%ah, %%cl\\n\"            /* cl = this.bits */\n\"        subb    %%ah, %%bl\\n\"            /* bits -= this.bits */\n\"        shrl    %%cl, %%edx\\n\"           /* hold >>= this.bits */\n\n\"        testb   %%al, %%al\\n\"\n\"        jnz     .L_test_for_length_base\\n\" /* if (op != 0) 45.7% */\n\n\"        shrl    $16, %%eax\\n\"            /* output this.val char */\n\"        stosb\\n\"\n\"        jmp     .L_while_test\\n\"\n\n\".align 32,0x90\\n\"\n\".L_test_for_length_base:\\n\"\n\"        movl    %%eax, %%ecx\\n\"          /* len = this */\n\"        shrl    $16, %%ecx\\n\"            /* len = this.val */\n\"        movl    %%ecx, 64(%%esp)\\n\"      /* save len */\n\"        movb    %%al, %%cl\\n\"\n\n\"        testb   $16, %%al\\n\"\n\"        jz      .L_test_for_second_level_length\\n\" /* if ((op & 16) == 0) 8% */\n\"        andb    $15, %%cl\\n\"             /* op &= 15 */\n\"        jz      .L_decode_distance\\n\"    /* if (!op) */\n\"        cmpb    %%cl, %%bl\\n\"\n\"        jae     .L_add_bits_to_len\\n\"    /* if (op <= bits) */\n\n\"        movb    %%cl, %%ch\\n\"            /* stash op in ch, freeing cl */\n\"        xorl    %%eax, %%eax\\n\"\n\"        lodsw\\n\"                         /* al = *(ushort *)in++ */\n\"        movb    %%bl, %%cl\\n\"            /* cl = bits, needs it for shifting */\n\"        addb    $16, %%bl\\n\"             /* bits += 16 */\n\"        shll    %%cl, %%eax\\n\"\n\"        orl     %%eax, %%edx\\n\"         /* hold |= *((ushort *)in)++ << bits */\n\"        movb    %%ch, %%cl\\n\"            /* move op back to ecx */\n\n\".L_add_bits_to_len:\\n\"\n\"        subb    %%cl, %%bl\\n\"\n\"        xorl    %%eax, %%eax\\n\"\n\"        incl    %%eax\\n\"\n\"        shll    %%cl, %%eax\\n\"\n\"        decl    %%eax\\n\"\n\"        andl    %%edx, %%eax\\n\"          /* eax &= hold */\n\"        shrl    %%cl, %%edx\\n\"\n\"        addl    %%eax, 64(%%esp)\\n\"      /* len += hold & mask[op] */\n\n\".L_decode_distance:\\n\"\n\"        cmpb    $15, %%bl\\n\"\n\"        ja      .L_get_distance_code\\n\"  /* if (15 < bits) */\n\n\"        xorl    %%eax, %%eax\\n\"\n\"        lodsw\\n\"                         /* al = *(ushort *)in++ */\n\"        movb    %%bl, %%cl\\n\"            /* cl = bits, needs it for shifting */\n\"        addb    $16, %%bl\\n\"             /* bits += 16 */\n\"        shll    %%cl, %%eax\\n\"\n\"        orl     %%eax, %%edx\\n\"         /* hold |= *((ushort *)in)++ << bits */\n\n\".L_get_distance_code:\\n\"\n\"        movl    60(%%esp), %%eax\\n\"      /* eax = dmask */\n\"        movl    36(%%esp), %%ecx\\n\"      /* ecx = dcode */\n\"        andl    %%edx, %%eax\\n\"          /* eax &= hold */\n\"        movl    (%%ecx,%%eax,4), %%eax\\n\"/* eax = dcode[hold & dmask] */\n\n\".L_dodist:\\n\"\n\"        movl    %%eax, %%ebp\\n\"          /* dist = this */\n\"        shrl    $16, %%ebp\\n\"            /* dist = this.val */\n\"        movb    %%ah, %%cl\\n\"\n\"        subb    %%ah, %%bl\\n\"            /* bits -= this.bits */\n\"        shrl    %%cl, %%edx\\n\"           /* hold >>= this.bits */\n\"        movb    %%al, %%cl\\n\"            /* cl = this.op */\n\n\"        testb   $16, %%al\\n\"             /* if ((op & 16) == 0) */\n\"        jz      .L_test_for_second_level_dist\\n\"\n\"        andb    $15, %%cl\\n\"             /* op &= 15 */\n\"        jz      .L_check_dist_one\\n\"\n\"        cmpb    %%cl, %%bl\\n\"\n\"        jae     .L_add_bits_to_dist\\n\"   /* if (op <= bits) 97.6% */\n\n\"        movb    %%cl, %%ch\\n\"            /* stash op in ch, freeing cl */\n\"        xorl    %%eax, %%eax\\n\"\n\"        lodsw\\n\"                         /* al = *(ushort *)in++ */\n\"        movb    %%bl, %%cl\\n\"            /* cl = bits, needs it for shifting */\n\"        addb    $16, %%bl\\n\"             /* bits += 16 */\n\"        shll    %%cl, %%eax\\n\"\n\"        orl     %%eax, %%edx\\n\"        /* hold |= *((ushort *)in)++ << bits */\n\"        movb    %%ch, %%cl\\n\"            /* move op back to ecx */\n\n\".L_add_bits_to_dist:\\n\"\n\"        subb    %%cl, %%bl\\n\"\n\"        xorl    %%eax, %%eax\\n\"\n\"        incl    %%eax\\n\"\n\"        shll    %%cl, %%eax\\n\"\n\"        decl    %%eax\\n\"                 /* (1 << op) - 1 */\n\"        andl    %%edx, %%eax\\n\"          /* eax &= hold */\n\"        shrl    %%cl, %%edx\\n\"\n\"        addl    %%eax, %%ebp\\n\"          /* dist += hold & ((1 << op) - 1) */\n\n\".L_check_window:\\n\"\n\"        movl    %%esi, 8(%%esp)\\n\"       /* save in so from can use it's reg */\n\"        movl    %%edi, %%eax\\n\"\n\"        subl    20(%%esp), %%eax\\n\"      /* nbytes = out - beg */\n\n\"        cmpl    %%ebp, %%eax\\n\"\n\"        jb      .L_clip_window\\n\"        /* if (dist > nbytes) 4.2% */\n\n\"        movl    64(%%esp), %%ecx\\n\"      /* ecx = len */\n\"        movl    %%edi, %%esi\\n\"\n\"        subl    %%ebp, %%esi\\n\"          /* from = out - dist */\n\n\"        sarl    %%ecx\\n\"\n\"        jnc     .L_copy_two\\n\"           /* if len % 2 == 0 */\n\n\"        rep     movsw\\n\"\n\"        movb    (%%esi), %%al\\n\"\n\"        movb    %%al, (%%edi)\\n\"\n\"        incl    %%edi\\n\"\n\n\"        movl    8(%%esp), %%esi\\n\"       /* move in back to %esi, toss from */\n\"        movl    32(%%esp), %%ebp\\n\"      /* ebp = lcode */\n\"        jmp     .L_while_test\\n\"\n\n\".L_copy_two:\\n\"\n\"        rep     movsw\\n\"\n\"        movl    8(%%esp), %%esi\\n\"       /* move in back to %esi, toss from */\n\"        movl    32(%%esp), %%ebp\\n\"      /* ebp = lcode */\n\"        jmp     .L_while_test\\n\"\n\n\".align 32,0x90\\n\"\n\".L_check_dist_one:\\n\"\n\"        cmpl    $1, %%ebp\\n\"            /* if dist 1, is a memset */\n\"        jne     .L_check_window\\n\"\n\"        cmpl    %%edi, 20(%%esp)\\n\"\n\"        je      .L_check_window\\n\"      /* out == beg, if outside window */\n\n\"        movl    64(%%esp), %%ecx\\n\"      /* ecx = len */\n\"        movb    -1(%%edi), %%al\\n\"\n\"        movb    %%al, %%ah\\n\"\n\n\"        sarl    %%ecx\\n\"\n\"        jnc     .L_set_two\\n\"\n\"        movb    %%al, (%%edi)\\n\"\n\"        incl    %%edi\\n\"\n\n\".L_set_two:\\n\"\n\"        rep     stosw\\n\"\n\"        movl    32(%%esp), %%ebp\\n\"      /* ebp = lcode */\n\"        jmp     .L_while_test\\n\"\n\n\".align 32,0x90\\n\"\n\".L_test_for_second_level_length:\\n\"\n\"        testb   $64, %%al\\n\"\n\"        jnz     .L_test_for_end_of_block\\n\" /* if ((op & 64) != 0) */\n\n\"        xorl    %%eax, %%eax\\n\"\n\"        incl    %%eax\\n\"\n\"        shll    %%cl, %%eax\\n\"\n\"        decl    %%eax\\n\"\n\"        andl    %%edx, %%eax\\n\"         /* eax &= hold */\n\"        addl    64(%%esp), %%eax\\n\"     /* eax += len */\n\"        movl    (%%ebp,%%eax,4), %%eax\\n\" /* eax = lcode[val+(hold&mask[op])]*/\n\"        jmp     .L_dolen\\n\"\n\n\".align 32,0x90\\n\"\n\".L_test_for_second_level_dist:\\n\"\n\"        testb   $64, %%al\\n\"\n\"        jnz     .L_invalid_distance_code\\n\" /* if ((op & 64) != 0) */\n\n\"        xorl    %%eax, %%eax\\n\"\n\"        incl    %%eax\\n\"\n\"        shll    %%cl, %%eax\\n\"\n\"        decl    %%eax\\n\"\n\"        andl    %%edx, %%eax\\n\"         /* eax &= hold */\n\"        addl    %%ebp, %%eax\\n\"         /* eax += dist */\n\"        movl    36(%%esp), %%ecx\\n\"     /* ecx = dcode */\n\"        movl    (%%ecx,%%eax,4), %%eax\\n\" /* eax = dcode[val+(hold&mask[op])]*/\n\"        jmp     .L_dodist\\n\"\n\n\".align 32,0x90\\n\"\n\".L_clip_window:\\n\"\n\"        movl    %%eax, %%ecx\\n\"\n\"        movl    48(%%esp), %%eax\\n\"     /* eax = wsize */\n\"        negl    %%ecx\\n\"                /* nbytes = -nbytes */\n\"        movl    28(%%esp), %%esi\\n\"     /* from = window */\n\n\"        cmpl    %%ebp, %%eax\\n\"\n\"        jb      .L_invalid_distance_too_far\\n\" /* if (dist > wsize) */\n\n\"        addl    %%ebp, %%ecx\\n\"         /* nbytes = dist - nbytes */\n\"        cmpl    $0, 52(%%esp)\\n\"\n\"        jne     .L_wrap_around_window\\n\" /* if (write != 0) */\n\n\"        subl    %%ecx, %%eax\\n\"\n\"        addl    %%eax, %%esi\\n\"         /* from += wsize - nbytes */\n\n\"        movl    64(%%esp), %%eax\\n\"     /* eax = len */\n\"        cmpl    %%ecx, %%eax\\n\"\n\"        jbe     .L_do_copy\\n\"           /* if (nbytes >= len) */\n\n\"        subl    %%ecx, %%eax\\n\"         /* len -= nbytes */\n\"        rep     movsb\\n\"\n\"        movl    %%edi, %%esi\\n\"\n\"        subl    %%ebp, %%esi\\n\"         /* from = out - dist */\n\"        jmp     .L_do_copy\\n\"\n\n\".align 32,0x90\\n\"\n\".L_wrap_around_window:\\n\"\n\"        movl    52(%%esp), %%eax\\n\"     /* eax = write */\n\"        cmpl    %%eax, %%ecx\\n\"\n\"        jbe     .L_contiguous_in_window\\n\" /* if (write >= nbytes) */\n\n\"        addl    48(%%esp), %%esi\\n\"     /* from += wsize */\n\"        addl    %%eax, %%esi\\n\"         /* from += write */\n\"        subl    %%ecx, %%esi\\n\"         /* from -= nbytes */\n\"        subl    %%eax, %%ecx\\n\"         /* nbytes -= write */\n\n\"        movl    64(%%esp), %%eax\\n\"     /* eax = len */\n\"        cmpl    %%ecx, %%eax\\n\"\n\"        jbe     .L_do_copy\\n\"           /* if (nbytes >= len) */\n\n\"        subl    %%ecx, %%eax\\n\"         /* len -= nbytes */\n\"        rep     movsb\\n\"\n\"        movl    28(%%esp), %%esi\\n\"     /* from = window */\n\"        movl    52(%%esp), %%ecx\\n\"     /* nbytes = write */\n\"        cmpl    %%ecx, %%eax\\n\"\n\"        jbe     .L_do_copy\\n\"           /* if (nbytes >= len) */\n\n\"        subl    %%ecx, %%eax\\n\"         /* len -= nbytes */\n\"        rep     movsb\\n\"\n\"        movl    %%edi, %%esi\\n\"\n\"        subl    %%ebp, %%esi\\n\"         /* from = out - dist */\n\"        jmp     .L_do_copy\\n\"\n\n\".align 32,0x90\\n\"\n\".L_contiguous_in_window:\\n\"\n\"        addl    %%eax, %%esi\\n\"\n\"        subl    %%ecx, %%esi\\n\"         /* from += write - nbytes */\n\n\"        movl    64(%%esp), %%eax\\n\"     /* eax = len */\n\"        cmpl    %%ecx, %%eax\\n\"\n\"        jbe     .L_do_copy\\n\"           /* if (nbytes >= len) */\n\n\"        subl    %%ecx, %%eax\\n\"         /* len -= nbytes */\n\"        rep     movsb\\n\"\n\"        movl    %%edi, %%esi\\n\"\n\"        subl    %%ebp, %%esi\\n\"         /* from = out - dist */\n\"        jmp     .L_do_copy\\n\"           /* if (nbytes >= len) */\n\n\".align 32,0x90\\n\"\n\".L_do_copy:\\n\"\n\"        movl    %%eax, %%ecx\\n\"\n\"        rep     movsb\\n\"\n\n\"        movl    8(%%esp), %%esi\\n\"      /* move in back to %esi, toss from */\n\"        movl    32(%%esp), %%ebp\\n\"     /* ebp = lcode */\n\"        jmp     .L_while_test\\n\"\n\n\".L_test_for_end_of_block:\\n\"\n\"        testb   $32, %%al\\n\"\n\"        jz      .L_invalid_literal_length_code\\n\"\n\"        movl    $1, 72(%%esp)\\n\"\n\"        jmp     .L_break_loop_with_status\\n\"\n\n\".L_invalid_literal_length_code:\\n\"\n\"        movl    $2, 72(%%esp)\\n\"\n\"        jmp     .L_break_loop_with_status\\n\"\n\n\".L_invalid_distance_code:\\n\"\n\"        movl    $3, 72(%%esp)\\n\"\n\"        jmp     .L_break_loop_with_status\\n\"\n\n\".L_invalid_distance_too_far:\\n\"\n\"        movl    8(%%esp), %%esi\\n\"\n\"        movl    $4, 72(%%esp)\\n\"\n\"        jmp     .L_break_loop_with_status\\n\"\n\n\".L_break_loop:\\n\"\n\"        movl    $0, 72(%%esp)\\n\"\n\n\".L_break_loop_with_status:\\n\"\n/* put in, out, bits, and hold back into ar and pop esp */\n\"        movl    %%esi, 8(%%esp)\\n\"      /* save in */\n\"        movl    %%edi, 16(%%esp)\\n\"     /* save out */\n\"        movl    %%ebx, 44(%%esp)\\n\"     /* save bits */\n\"        movl    %%edx, 40(%%esp)\\n\"     /* save hold */\n\"        movl    4(%%esp), %%ebp\\n\"      /* restore esp, ebp */\n\"        movl    (%%esp), %%esp\\n\"\n          :\n          : \"m\" (ar)\n          : \"memory\", \"%eax\", \"%ebx\", \"%ecx\", \"%edx\", \"%esi\", \"%edi\"\n    );\n#elif defined( _MSC_VER ) && ! defined( _M_AMD64 )\n    __asm {\n\tlea\teax, ar\n\tmov\t[eax], esp         /* save esp, ebp */\n\tmov\t[eax+4], ebp\n\tmov\tesp, eax\n\tmov\tesi, [esp+8]       /* esi = in */\n\tmov\tedi, [esp+16]      /* edi = out */\n\tmov\tedx, [esp+40]      /* edx = hold */\n\tmov\tebx, [esp+44]      /* ebx = bits */\n\tmov\tebp, [esp+32]      /* ebp = lcode */\n\n\tcld\n\tjmp\tL_do_loop\n\nALIGN 4\nL_while_test:\n\tcmp\t[esp+24], edi\n\tjbe\tL_break_loop\n\tcmp\t[esp+12], esi\n\tjbe\tL_break_loop\n\nL_do_loop:\n\tcmp\tbl, 15\n\tja\tL_get_length_code    /* if (15 < bits) */\n\n\txor\teax, eax\n\tlodsw                         /* al = *(ushort *)in++ */\n\tmov\tcl, bl            /* cl = bits, needs it for shifting */\n\tadd\tbl, 16             /* bits += 16 */\n\tshl\teax, cl\n\tor\tedx, eax        /* hold |= *((ushort *)in)++ << bits */\n\nL_get_length_code:\n\tmov\teax, [esp+56]      /* eax = lmask */\n\tand\teax, edx          /* eax &= hold */\n\tmov\teax, [ebp+eax*4] /* eax = lcode[hold & lmask] */\n\nL_dolen:\n\tmov\tcl, ah            /* cl = this.bits */\n\tsub\tbl, ah            /* bits -= this.bits */\n\tshr\tedx, cl           /* hold >>= this.bits */\n\n\ttest\tal, al\n\tjnz\tL_test_for_length_base /* if (op != 0) 45.7% */\n\n\tshr\teax, 16            /* output this.val char */\n\tstosb\n\tjmp\tL_while_test\n\nALIGN 4\nL_test_for_length_base:\n\tmov\tecx, eax          /* len = this */\n\tshr\tecx, 16            /* len = this.val */\n\tmov\t[esp+64], ecx      /* save len */\n\tmov\tcl, al\n\n\ttest\tal, 16\n\tjz\tL_test_for_second_level_length /* if ((op & 16) == 0) 8% */\n\tand\tcl, 15             /* op &= 15 */\n\tjz\tL_decode_distance    /* if (!op) */\n\tcmp\tbl, cl\n\tjae\tL_add_bits_to_len    /* if (op <= bits) */\n\n\tmov\tch, cl            /* stash op in ch, freeing cl */\n\txor\teax, eax\n\tlodsw                         /* al = *(ushort *)in++ */\n\tmov\tcl, bl            /* cl = bits, needs it for shifting */\n\tadd\tbl, 16             /* bits += 16 */\n\tshl\teax, cl\n\tor\tedx, eax         /* hold |= *((ushort *)in)++ << bits */\n\tmov\tcl, ch            /* move op back to ecx */\n\nL_add_bits_to_len:\n\tsub\tbl, cl\n\txor\teax, eax\n\tinc\teax\n\tshl\teax, cl\n\tdec\teax\n\tand\teax, edx          /* eax &= hold */\n\tshr\tedx, cl\n\tadd\t[esp+64], eax      /* len += hold & mask[op] */\n\nL_decode_distance:\n\tcmp\tbl, 15\n\tja\tL_get_distance_code  /* if (15 < bits) */\n\n\txor\teax, eax\n\tlodsw                         /* al = *(ushort *)in++ */\n\tmov\tcl, bl            /* cl = bits, needs it for shifting */\n\tadd\tbl, 16             /* bits += 16 */\n\tshl\teax, cl\n\tor\tedx, eax         /* hold |= *((ushort *)in)++ << bits */\n\nL_get_distance_code:\n\tmov\teax, [esp+60]      /* eax = dmask */\n\tmov\tecx, [esp+36]      /* ecx = dcode */\n\tand\teax, edx          /* eax &= hold */\n\tmov\teax, [ecx+eax*4]/* eax = dcode[hold & dmask] */\n\nL_dodist:\n\tmov\tebp, eax          /* dist = this */\n\tshr\tebp, 16            /* dist = this.val */\n\tmov\tcl, ah\n\tsub\tbl, ah            /* bits -= this.bits */\n\tshr\tedx, cl           /* hold >>= this.bits */\n\tmov\tcl, al            /* cl = this.op */\n\n\ttest\tal, 16             /* if ((op & 16) == 0) */\n\tjz\tL_test_for_second_level_dist\n\tand\tcl, 15             /* op &= 15 */\n\tjz\tL_check_dist_one\n\tcmp\tbl, cl\n\tjae\tL_add_bits_to_dist   /* if (op <= bits) 97.6% */\n\n\tmov\tch, cl            /* stash op in ch, freeing cl */\n\txor\teax, eax\n\tlodsw                         /* al = *(ushort *)in++ */\n\tmov\tcl, bl            /* cl = bits, needs it for shifting */\n\tadd\tbl, 16             /* bits += 16 */\n\tshl\teax, cl\n\tor\tedx, eax        /* hold |= *((ushort *)in)++ << bits */\n\tmov\tcl, ch            /* move op back to ecx */\n\nL_add_bits_to_dist:\n\tsub\tbl, cl\n\txor\teax, eax\n\tinc\teax\n\tshl\teax, cl\n\tdec\teax                 /* (1 << op) - 1 */\n\tand\teax, edx          /* eax &= hold */\n\tshr\tedx, cl\n\tadd\tebp, eax          /* dist += hold & ((1 << op) - 1) */\n\nL_check_window:\n\tmov\t[esp+8], esi       /* save in so from can use it's reg */\n\tmov\teax, edi\n\tsub\teax, [esp+20]      /* nbytes = out - beg */\n\n\tcmp\teax, ebp\n\tjb\tL_clip_window        /* if (dist > nbytes) 4.2% */\n\n\tmov\tecx, [esp+64]      /* ecx = len */\n\tmov\tesi, edi\n\tsub\tesi, ebp          /* from = out - dist */\n\n\tsar\tecx, 1\n\tjnc\tL_copy_two\n\n\trep     movsw\n\tmov\tal, [esi]\n\tmov\t[edi], al\n\tinc\tedi\n\n\tmov\tesi, [esp+8]      /* move in back to %esi, toss from */\n\tmov\tebp, [esp+32]     /* ebp = lcode */\n\tjmp\tL_while_test\n\nL_copy_two:\n\trep     movsw\n\tmov\tesi, [esp+8]      /* move in back to %esi, toss from */\n\tmov\tebp, [esp+32]     /* ebp = lcode */\n\tjmp\tL_while_test\n\nALIGN 4\nL_check_dist_one:\n\tcmp\tebp, 1            /* if dist 1, is a memset */\n\tjne\tL_check_window\n\tcmp\t[esp+20], edi\n\tje\tL_check_window    /* out == beg, if outside window */\n\n\tmov\tecx, [esp+64]     /* ecx = len */\n\tmov\tal, [edi-1]\n\tmov\tah, al\n\n\tsar\tecx, 1\n\tjnc\tL_set_two\n\tmov\t[edi], al         /* memset out with from[-1] */\n\tinc\tedi\n\nL_set_two:\n\trep     stosw\n\tmov\tebp, [esp+32]     /* ebp = lcode */\n\tjmp\tL_while_test\n\nALIGN 4\nL_test_for_second_level_length:\n\ttest\tal, 64\n\tjnz\tL_test_for_end_of_block /* if ((op & 64) != 0) */\n\n\txor\teax, eax\n\tinc\teax\n\tshl\teax, cl\n\tdec\teax\n\tand\teax, edx         /* eax &= hold */\n\tadd\teax, [esp+64]     /* eax += len */\n\tmov\teax, [ebp+eax*4] /* eax = lcode[val+(hold&mask[op])]*/\n\tjmp\tL_dolen\n\nALIGN 4\nL_test_for_second_level_dist:\n\ttest\tal, 64\n\tjnz\tL_invalid_distance_code /* if ((op & 64) != 0) */\n\n\txor\teax, eax\n\tinc\teax\n\tshl\teax, cl\n\tdec\teax\n\tand\teax, edx         /* eax &= hold */\n\tadd\teax, ebp         /* eax += dist */\n\tmov\tecx, [esp+36]     /* ecx = dcode */\n\tmov\teax, [ecx+eax*4] /* eax = dcode[val+(hold&mask[op])]*/\n\tjmp\tL_dodist\n\nALIGN 4\nL_clip_window:\n\tmov\tecx, eax\n\tmov\teax, [esp+48]     /* eax = wsize */\n\tneg\tecx                /* nbytes = -nbytes */\n\tmov\tesi, [esp+28]     /* from = window */\n\n\tcmp\teax, ebp\n\tjb\tL_invalid_distance_too_far /* if (dist > wsize) */\n\n\tadd\tecx, ebp         /* nbytes = dist - nbytes */\n\tcmp\tdword ptr [esp+52], 0\n\tjne\tL_wrap_around_window /* if (write != 0) */\n\n\tsub\teax, ecx\n\tadd\tesi, eax         /* from += wsize - nbytes */\n\n\tmov\teax, [esp+64]    /* eax = len */\n\tcmp\teax, ecx\n\tjbe\tL_do_copy          /* if (nbytes >= len) */\n\n\tsub\teax, ecx         /* len -= nbytes */\n\trep     movsb\n\tmov\tesi, edi\n\tsub\tesi, ebp         /* from = out - dist */\n\tjmp\tL_do_copy\n\nALIGN 4\nL_wrap_around_window:\n\tmov\teax, [esp+52]    /* eax = write */\n\tcmp\tecx, eax\n\tjbe\tL_contiguous_in_window /* if (write >= nbytes) */\n\n\tadd\tesi, [esp+48]    /* from += wsize */\n\tadd\tesi, eax         /* from += write */\n\tsub\tesi, ecx         /* from -= nbytes */\n\tsub\tecx, eax         /* nbytes -= write */\n\n\tmov\teax, [esp+64]    /* eax = len */\n\tcmp\teax, ecx\n\tjbe\tL_do_copy          /* if (nbytes >= len) */\n\n\tsub\teax, ecx         /* len -= nbytes */\n\trep     movsb\n\tmov\tesi, [esp+28]     /* from = window */\n\tmov\tecx, [esp+52]     /* nbytes = write */\n\tcmp\teax, ecx\n\tjbe\tL_do_copy          /* if (nbytes >= len) */\n\n\tsub\teax, ecx         /* len -= nbytes */\n\trep     movsb\n\tmov\tesi, edi\n\tsub\tesi, ebp         /* from = out - dist */\n\tjmp\tL_do_copy\n\nALIGN 4\nL_contiguous_in_window:\n\tadd\tesi, eax\n\tsub\tesi, ecx         /* from += write - nbytes */\n\n\tmov\teax, [esp+64]    /* eax = len */\n\tcmp\teax, ecx\n\tjbe\tL_do_copy          /* if (nbytes >= len) */\n\n\tsub\teax, ecx         /* len -= nbytes */\n\trep     movsb\n\tmov\tesi, edi\n\tsub\tesi, ebp         /* from = out - dist */\n\tjmp\tL_do_copy\n\nALIGN 4\nL_do_copy:\n\tmov\tecx, eax\n\trep     movsb\n\n\tmov\tesi, [esp+8]      /* move in back to %esi, toss from */\n\tmov\tebp, [esp+32]     /* ebp = lcode */\n\tjmp\tL_while_test\n\nL_test_for_end_of_block:\n\ttest\tal, 32\n\tjz\tL_invalid_literal_length_code\n\tmov\tdword ptr [esp+72], 1\n\tjmp\tL_break_loop_with_status\n\nL_invalid_literal_length_code:\n\tmov\tdword ptr [esp+72], 2\n\tjmp\tL_break_loop_with_status\n\nL_invalid_distance_code:\n\tmov\tdword ptr [esp+72], 3\n\tjmp\tL_break_loop_with_status\n\nL_invalid_distance_too_far:\n\tmov\tesi, [esp+4]\n\tmov\tdword ptr [esp+72], 4\n\tjmp\tL_break_loop_with_status\n\nL_break_loop:\n\tmov\tdword ptr [esp+72], 0\n\nL_break_loop_with_status:\n/* put in, out, bits, and hold back into ar and pop esp */\n\tmov\t[esp+8], esi     /* save in */\n\tmov\t[esp+16], edi    /* save out */\n\tmov\t[esp+44], ebx    /* save bits */\n\tmov\t[esp+40], edx    /* save hold */\n\tmov\tebp, [esp+4]     /* restore esp, ebp */\n\tmov\tesp, [esp]\n    }\n#else\n#error \"x86 architecture not defined\"\n#endif\n\n    if (ar.status > 1) {\n        if (ar.status == 2)\n            strm->msg = \"invalid literal/length code\";\n        else if (ar.status == 3)\n            strm->msg = \"invalid distance code\";\n        else\n            strm->msg = \"invalid distance too far back\";\n        state->mode = BAD;\n    }\n    else if ( ar.status == 1 ) {\n        state->mode = TYPE;\n    }\n\n    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */\n    ar.len = ar.bits >> 3;\n    ar.in -= ar.len;\n    ar.bits -= ar.len << 3;\n    ar.hold &= (1U << ar.bits) - 1;\n\n    /* update state and return */\n    strm->next_in = ar.in;\n    strm->next_out = ar.out;\n    strm->avail_in = (unsigned)(ar.in < ar.last ?\n                                PAD_AVAIL_IN + (ar.last - ar.in) :\n                                PAD_AVAIL_IN - (ar.in - ar.last));\n    strm->avail_out = (unsigned)(ar.out < ar.end ?\n                                 PAD_AVAIL_OUT + (ar.end - ar.out) :\n                                 PAD_AVAIL_OUT - (ar.out - ar.end));\n    state->hold = ar.hold;\n    state->bits = ar.bits;\n    return;\n}\n\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/inflate86/inffast.S",
    "content": "/*\n * inffast.S is a hand tuned assembler version of:\n *\n * inffast.c -- fast decoding\n * Copyright (C) 1995-2003 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n *\n * Copyright (C) 2003 Chris Anderson <christop@charm.net>\n * Please use the copyright conditions above.\n *\n * This version (Jan-23-2003) of inflate_fast was coded and tested under\n * GNU/Linux on a pentium 3, using the gcc-3.2 compiler distribution.  On that\n * machine, I found that gzip style archives decompressed about 20% faster than\n * the gcc-3.2 -O3 -fomit-frame-pointer compiled version.  Your results will\n * depend on how large of a buffer is used for z_stream.next_in & next_out\n * (8K-32K worked best for my 256K cpu cache) and how much overhead there is in\n * stream processing I/O and crc32/addler32.  In my case, this routine used\n * 70% of the cpu time and crc32 used 20%.\n *\n * I am confident that this version will work in the general case, but I have\n * not tested a wide variety of datasets or a wide variety of platforms.\n *\n * Jan-24-2003 -- Added -DUSE_MMX define for slightly faster inflating.\n * It should be a runtime flag instead of compile time flag...\n *\n * Jan-26-2003 -- Added runtime check for MMX support with cpuid instruction.\n * With -DUSE_MMX, only MMX code is compiled.  With -DNO_MMX, only non-MMX code\n * is compiled.  Without either option, runtime detection is enabled.  Runtime\n * detection should work on all modern cpus and the recomended algorithm (flip\n * ID bit on eflags and then use the cpuid instruction) is used in many\n * multimedia applications.  Tested under win2k with gcc-2.95 and gas-2.12\n * distributed with cygwin3.  Compiling with gcc-2.95 -c inffast.S -o\n * inffast.obj generates a COFF object which can then be linked with MSVC++\n * compiled code.  Tested under FreeBSD 4.7 with gcc-2.95.\n *\n * Jan-28-2003 -- Tested Athlon XP... MMX mode is slower than no MMX (and\n * slower than compiler generated code).  Adjusted cpuid check to use the MMX\n * code only for Pentiums < P4 until I have more data on the P4.  Speed\n * improvment is only about 15% on the Athlon when compared with code generated\n * with MSVC++.  Not sure yet, but I think the P4 will also be slower using the\n * MMX mode because many of it's x86 ALU instructions execute in .5 cycles and\n * have less latency than MMX ops.  Added code to buffer the last 11 bytes of\n * the input stream since the MMX code grabs bits in chunks of 32, which\n * differs from the inffast.c algorithm.  I don't think there would have been\n * read overruns where a page boundary was crossed (a segfault), but there\n * could have been overruns when next_in ends on unaligned memory (unintialized\n * memory read).\n *\n * Mar-13-2003 -- P4 MMX is slightly slower than P4 NO_MMX.  I created a C\n * version of the non-MMX code so that it doesn't depend on zstrm and zstate\n * structure offsets which are hard coded in this file.  This was last tested\n * with zlib-1.2.0 which is currently in beta testing, newer versions of this\n * and inffas86.c can be found at http://www.eetbeetee.com/zlib/ and\n * http://www.charm.net/~christop/zlib/\n */\n\n\n/*\n * if you have underscore linking problems (_inflate_fast undefined), try\n * using -DGAS_COFF\n */\n#if ! defined( GAS_COFF ) && ! defined( GAS_ELF )\n\n#if defined( WIN32 ) || defined( __CYGWIN__ )\n#define GAS_COFF /* windows object format */\n#else\n#define GAS_ELF\n#endif\n\n#endif /* ! GAS_COFF && ! GAS_ELF */\n\n\n#if defined( GAS_COFF )\n\n/* coff externals have underscores */\n#define inflate_fast _inflate_fast\n#define inflate_fast_use_mmx _inflate_fast_use_mmx\n\n#endif /* GAS_COFF */\n\n\n.file \"inffast.S\"\n\n.globl inflate_fast\n\n.text\n.align 4,0\n.L_invalid_literal_length_code_msg:\n.string \"invalid literal/length code\"\n\n.align 4,0\n.L_invalid_distance_code_msg:\n.string \"invalid distance code\"\n\n.align 4,0\n.L_invalid_distance_too_far_msg:\n.string \"invalid distance too far back\"\n\n#if ! defined( NO_MMX )\n.align 4,0\n.L_mask: /* mask[N] = ( 1 << N ) - 1 */\n.long 0\n.long 1\n.long 3\n.long 7\n.long 15\n.long 31\n.long 63\n.long 127\n.long 255\n.long 511\n.long 1023\n.long 2047\n.long 4095\n.long 8191\n.long 16383\n.long 32767\n.long 65535\n.long 131071\n.long 262143\n.long 524287\n.long 1048575\n.long 2097151\n.long 4194303\n.long 8388607\n.long 16777215\n.long 33554431\n.long 67108863\n.long 134217727\n.long 268435455\n.long 536870911\n.long 1073741823\n.long 2147483647\n.long 4294967295\n#endif /* NO_MMX */\n\n.text\n\n/*\n * struct z_stream offsets, in zlib.h\n */\n#define next_in_strm   0   /* strm->next_in */\n#define avail_in_strm  4   /* strm->avail_in */\n#define next_out_strm  12  /* strm->next_out */\n#define avail_out_strm 16  /* strm->avail_out */\n#define msg_strm       24  /* strm->msg */\n#define state_strm     28  /* strm->state */\n\n/*\n * struct inflate_state offsets, in inflate.h\n */\n#define mode_state     0   /* state->mode */\n#define wsize_state    32  /* state->wsize */\n#define write_state    40  /* state->write */\n#define window_state   44  /* state->window */\n#define hold_state     48  /* state->hold */\n#define bits_state     52  /* state->bits */\n#define lencode_state  68  /* state->lencode */\n#define distcode_state 72  /* state->distcode */\n#define lenbits_state  76  /* state->lenbits */\n#define distbits_state 80  /* state->distbits */\n\n/*\n * inflate_fast's activation record\n */\n#define local_var_size 64 /* how much local space for vars */\n#define strm_sp        88 /* first arg: z_stream * (local_var_size + 24) */\n#define start_sp       92 /* second arg: unsigned int (local_var_size + 28) */\n\n/*\n * offsets for local vars on stack\n */\n#define out            60  /* unsigned char* */\n#define window         56  /* unsigned char* */\n#define wsize          52  /* unsigned int */\n#define write          48  /* unsigned int */\n#define in             44  /* unsigned char* */\n#define beg            40  /* unsigned char* */\n#define buf            28  /* char[ 12 ] */\n#define len            24  /* unsigned int */\n#define last           20  /* unsigned char* */\n#define end            16  /* unsigned char* */\n#define dcode          12  /* code* */\n#define lcode           8  /* code* */\n#define dmask           4  /* unsigned int */\n#define lmask           0  /* unsigned int */\n\n/*\n * typedef enum inflate_mode consts, in inflate.h\n */\n#define INFLATE_MODE_TYPE 11  /* state->mode flags enum-ed in inflate.h */\n#define INFLATE_MODE_BAD  26\n\n\n#if ! defined( USE_MMX ) && ! defined( NO_MMX )\n\n#define RUN_TIME_MMX\n\n#define CHECK_MMX    1\n#define DO_USE_MMX   2\n#define DONT_USE_MMX 3\n\n.globl inflate_fast_use_mmx\n\n.data\n\n.align 4,0\ninflate_fast_use_mmx: /* integer flag for run time control 1=check,2=mmx,3=no */\n.long CHECK_MMX\n\n#if defined( GAS_ELF )\n/* elf info */\n.type   inflate_fast_use_mmx,@object\n.size   inflate_fast_use_mmx,4\n#endif\n\n#endif /* RUN_TIME_MMX */\n\n#if defined( GAS_COFF )\n/* coff info: scl 2 = extern, type 32 = function */\n.def inflate_fast; .scl 2; .type 32; .endef\n#endif\n\n.text\n\n.align 32,0x90\ninflate_fast:\n        pushl   %edi\n        pushl   %esi\n        pushl   %ebp\n        pushl   %ebx\n        pushf   /* save eflags (strm_sp, state_sp assumes this is 32 bits) */\n        subl    $local_var_size, %esp\n        cld\n\n#define strm_r  %esi\n#define state_r %edi\n\n        movl    strm_sp(%esp), strm_r\n        movl    state_strm(strm_r), state_r\n\n        /* in = strm->next_in;\n         * out = strm->next_out;\n         * last = in + strm->avail_in - 11;\n         * beg = out - (start - strm->avail_out);\n         * end = out + (strm->avail_out - 257);\n         */\n        movl    avail_in_strm(strm_r), %edx\n        movl    next_in_strm(strm_r), %eax\n\n        addl    %eax, %edx      /* avail_in += next_in */\n        subl    $11, %edx       /* avail_in -= 11 */\n\n        movl    %eax, in(%esp)\n        movl    %edx, last(%esp)\n\n        movl    start_sp(%esp), %ebp\n        movl    avail_out_strm(strm_r), %ecx\n        movl    next_out_strm(strm_r), %ebx\n\n        subl    %ecx, %ebp      /* start -= avail_out */\n        negl    %ebp            /* start = -start */\n        addl    %ebx, %ebp      /* start += next_out */\n\n        subl    $257, %ecx      /* avail_out -= 257 */\n        addl    %ebx, %ecx      /* avail_out += out */\n\n        movl    %ebx, out(%esp)\n        movl    %ebp, beg(%esp)\n        movl    %ecx, end(%esp)\n\n        /* wsize = state->wsize;\n         * write = state->write;\n         * window = state->window;\n         * hold = state->hold;\n         * bits = state->bits;\n         * lcode = state->lencode;\n         * dcode = state->distcode;\n         * lmask = ( 1 << state->lenbits ) - 1;\n         * dmask = ( 1 << state->distbits ) - 1;\n         */\n\n        movl    lencode_state(state_r), %eax\n        movl    distcode_state(state_r), %ecx\n\n        movl    %eax, lcode(%esp)\n        movl    %ecx, dcode(%esp)\n\n        movl    $1, %eax\n        movl    lenbits_state(state_r), %ecx\n        shll    %cl, %eax\n        decl    %eax\n        movl    %eax, lmask(%esp)\n\n        movl    $1, %eax\n        movl    distbits_state(state_r), %ecx\n        shll    %cl, %eax\n        decl    %eax\n        movl    %eax, dmask(%esp)\n\n        movl    wsize_state(state_r), %eax\n        movl    write_state(state_r), %ecx\n        movl    window_state(state_r), %edx\n\n        movl    %eax, wsize(%esp)\n        movl    %ecx, write(%esp)\n        movl    %edx, window(%esp)\n\n        movl    hold_state(state_r), %ebp\n        movl    bits_state(state_r), %ebx\n\n#undef strm_r\n#undef state_r\n\n#define in_r       %esi\n#define from_r     %esi\n#define out_r      %edi\n\n        movl    in(%esp), in_r\n        movl    last(%esp), %ecx\n        cmpl    in_r, %ecx\n        ja      .L_align_long           /* if in < last */\n\n        addl    $11, %ecx               /* ecx = &in[ avail_in ] */\n        subl    in_r, %ecx              /* ecx = avail_in */\n        movl    $12, %eax\n        subl    %ecx, %eax              /* eax = 12 - avail_in */\n        leal    buf(%esp), %edi\n        rep     movsb                   /* memcpy( buf, in, avail_in ) */\n        movl    %eax, %ecx\n        xorl    %eax, %eax\n        rep     stosb         /* memset( &buf[ avail_in ], 0, 12 - avail_in ) */\n        leal    buf(%esp), in_r         /* in = buf */\n        movl    in_r, last(%esp)        /* last = in, do just one iteration */\n        jmp     .L_is_aligned\n\n        /* align in_r on long boundary */\n.L_align_long:\n        testl   $3, in_r\n        jz      .L_is_aligned\n        xorl    %eax, %eax\n        movb    (in_r), %al\n        incl    in_r\n        movl    %ebx, %ecx\n        addl    $8, %ebx\n        shll    %cl, %eax\n        orl     %eax, %ebp\n        jmp     .L_align_long\n\n.L_is_aligned:\n        movl    out(%esp), out_r\n\n#if defined( NO_MMX )\n        jmp     .L_do_loop\n#endif\n\n#if defined( USE_MMX )\n        jmp     .L_init_mmx\n#endif\n\n/*** Runtime MMX check ***/\n\n#if defined( RUN_TIME_MMX )\n.L_check_mmx:\n        cmpl    $DO_USE_MMX, inflate_fast_use_mmx\n        je      .L_init_mmx\n        ja      .L_do_loop /* > 2 */\n\n        pushl   %eax\n        pushl   %ebx\n        pushl   %ecx\n        pushl   %edx\n        pushf\n        movl    (%esp), %eax      /* copy eflags to eax */\n        xorl    $0x200000, (%esp) /* try toggling ID bit of eflags (bit 21)\n                                   * to see if cpu supports cpuid...\n                                   * ID bit method not supported by NexGen but\n                                   * bios may load a cpuid instruction and\n                                   * cpuid may be disabled on Cyrix 5-6x86 */\n        popf\n        pushf\n        popl    %edx              /* copy new eflags to edx */\n        xorl    %eax, %edx        /* test if ID bit is flipped */\n        jz      .L_dont_use_mmx   /* not flipped if zero */\n        xorl    %eax, %eax\n        cpuid\n        cmpl    $0x756e6547, %ebx /* check for GenuineIntel in ebx,ecx,edx */\n        jne     .L_dont_use_mmx\n        cmpl    $0x6c65746e, %ecx\n        jne     .L_dont_use_mmx\n        cmpl    $0x49656e69, %edx\n        jne     .L_dont_use_mmx\n        movl    $1, %eax\n        cpuid                     /* get cpu features */\n        shrl    $8, %eax\n        andl    $15, %eax\n        cmpl    $6, %eax          /* check for Pentium family, is 0xf for P4 */\n        jne     .L_dont_use_mmx\n        testl   $0x800000, %edx   /* test if MMX feature is set (bit 23) */\n        jnz     .L_use_mmx\n        jmp     .L_dont_use_mmx\n.L_use_mmx:\n        movl    $DO_USE_MMX, inflate_fast_use_mmx\n        jmp     .L_check_mmx_pop\n.L_dont_use_mmx:\n        movl    $DONT_USE_MMX, inflate_fast_use_mmx\n.L_check_mmx_pop:\n        popl    %edx\n        popl    %ecx\n        popl    %ebx\n        popl    %eax\n        jmp     .L_check_mmx\n#endif\n\n\n/*** Non-MMX code ***/\n\n#if defined ( NO_MMX ) || defined( RUN_TIME_MMX )\n\n#define hold_r     %ebp\n#define bits_r     %bl\n#define bitslong_r %ebx\n\n.align 32,0x90\n.L_while_test:\n        /* while (in < last && out < end)\n         */\n        cmpl    out_r, end(%esp)\n        jbe     .L_break_loop           /* if (out >= end) */\n\n        cmpl    in_r, last(%esp)\n        jbe     .L_break_loop\n\n.L_do_loop:\n        /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out\n         *\n         * do {\n         *   if (bits < 15) {\n         *     hold |= *((unsigned short *)in)++ << bits;\n         *     bits += 16\n         *   }\n         *   this = lcode[hold & lmask]\n         */\n        cmpb    $15, bits_r\n        ja      .L_get_length_code      /* if (15 < bits) */\n\n        xorl    %eax, %eax\n        lodsw                           /* al = *(ushort *)in++ */\n        movb    bits_r, %cl             /* cl = bits, needs it for shifting */\n        addb    $16, bits_r             /* bits += 16 */\n        shll    %cl, %eax\n        orl     %eax, hold_r            /* hold |= *((ushort *)in)++ << bits */\n\n.L_get_length_code:\n        movl    lmask(%esp), %edx       /* edx = lmask */\n        movl    lcode(%esp), %ecx       /* ecx = lcode */\n        andl    hold_r, %edx            /* edx &= hold */\n        movl    (%ecx,%edx,4), %eax     /* eax = lcode[hold & lmask] */\n\n.L_dolen:\n        /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out\n         *\n         * dolen:\n         *    bits -= this.bits;\n         *    hold >>= this.bits\n         */\n        movb    %ah, %cl                /* cl = this.bits */\n        subb    %ah, bits_r             /* bits -= this.bits */\n        shrl    %cl, hold_r             /* hold >>= this.bits */\n\n        /* check if op is a literal\n         * if (op == 0) {\n         *    PUP(out) = this.val;\n         *  }\n         */\n        testb   %al, %al\n        jnz     .L_test_for_length_base /* if (op != 0) 45.7% */\n\n        shrl    $16, %eax               /* output this.val char */\n        stosb\n        jmp     .L_while_test\n\n.L_test_for_length_base:\n        /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = len\n         *\n         * else if (op & 16) {\n         *   len = this.val\n         *   op &= 15\n         *   if (op) {\n         *     if (op > bits) {\n         *       hold |= *((unsigned short *)in)++ << bits;\n         *       bits += 16\n         *     }\n         *     len += hold & mask[op];\n         *     bits -= op;\n         *     hold >>= op;\n         *   }\n         */\n#define len_r %edx\n        movl    %eax, len_r             /* len = this */\n        shrl    $16, len_r              /* len = this.val */\n        movb    %al, %cl\n\n        testb   $16, %al\n        jz      .L_test_for_second_level_length /* if ((op & 16) == 0) 8% */\n        andb    $15, %cl                /* op &= 15 */\n        jz      .L_save_len             /* if (!op) */\n        cmpb    %cl, bits_r\n        jae     .L_add_bits_to_len      /* if (op <= bits) */\n\n        movb    %cl, %ch                /* stash op in ch, freeing cl */\n        xorl    %eax, %eax\n        lodsw                           /* al = *(ushort *)in++ */\n        movb    bits_r, %cl             /* cl = bits, needs it for shifting */\n        addb    $16, bits_r             /* bits += 16 */\n        shll    %cl, %eax\n        orl     %eax, hold_r            /* hold |= *((ushort *)in)++ << bits */\n        movb    %ch, %cl                /* move op back to ecx */\n\n.L_add_bits_to_len:\n        movl    $1, %eax\n        shll    %cl, %eax\n        decl    %eax\n        subb    %cl, bits_r\n        andl    hold_r, %eax            /* eax &= hold */\n        shrl    %cl, hold_r\n        addl    %eax, len_r             /* len += hold & mask[op] */\n\n.L_save_len:\n        movl    len_r, len(%esp)        /* save len */\n#undef  len_r\n\n.L_decode_distance:\n        /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = dist\n         *\n         *   if (bits < 15) {\n         *     hold |= *((unsigned short *)in)++ << bits;\n         *     bits += 16\n         *   }\n         *   this = dcode[hold & dmask];\n         * dodist:\n         *   bits -= this.bits;\n         *   hold >>= this.bits;\n         *   op = this.op;\n         */\n\n        cmpb    $15, bits_r\n        ja      .L_get_distance_code    /* if (15 < bits) */\n\n        xorl    %eax, %eax\n        lodsw                           /* al = *(ushort *)in++ */\n        movb    bits_r, %cl             /* cl = bits, needs it for shifting */\n        addb    $16, bits_r             /* bits += 16 */\n        shll    %cl, %eax\n        orl     %eax, hold_r            /* hold |= *((ushort *)in)++ << bits */\n\n.L_get_distance_code:\n        movl    dmask(%esp), %edx       /* edx = dmask */\n        movl    dcode(%esp), %ecx       /* ecx = dcode */\n        andl    hold_r, %edx            /* edx &= hold */\n        movl    (%ecx,%edx,4), %eax     /* eax = dcode[hold & dmask] */\n\n#define dist_r %edx\n.L_dodist:\n        movl    %eax, dist_r            /* dist = this */\n        shrl    $16, dist_r             /* dist = this.val */\n        movb    %ah, %cl\n        subb    %ah, bits_r             /* bits -= this.bits */\n        shrl    %cl, hold_r             /* hold >>= this.bits */\n\n        /* if (op & 16) {\n         *   dist = this.val\n         *   op &= 15\n         *   if (op > bits) {\n         *     hold |= *((unsigned short *)in)++ << bits;\n         *     bits += 16\n         *   }\n         *   dist += hold & mask[op];\n         *   bits -= op;\n         *   hold >>= op;\n         */\n        movb    %al, %cl                /* cl = this.op */\n\n        testb   $16, %al                /* if ((op & 16) == 0) */\n        jz      .L_test_for_second_level_dist\n        andb    $15, %cl                /* op &= 15 */\n        jz      .L_check_dist_one\n        cmpb    %cl, bits_r\n        jae     .L_add_bits_to_dist     /* if (op <= bits) 97.6% */\n\n        movb    %cl, %ch                /* stash op in ch, freeing cl */\n        xorl    %eax, %eax\n        lodsw                           /* al = *(ushort *)in++ */\n        movb    bits_r, %cl             /* cl = bits, needs it for shifting */\n        addb    $16, bits_r             /* bits += 16 */\n        shll    %cl, %eax\n        orl     %eax, hold_r            /* hold |= *((ushort *)in)++ << bits */\n        movb    %ch, %cl                /* move op back to ecx */\n\n.L_add_bits_to_dist:\n        movl    $1, %eax\n        shll    %cl, %eax\n        decl    %eax                    /* (1 << op) - 1 */\n        subb    %cl, bits_r\n        andl    hold_r, %eax            /* eax &= hold */\n        shrl    %cl, hold_r\n        addl    %eax, dist_r            /* dist += hold & ((1 << op) - 1) */\n        jmp     .L_check_window\n\n.L_check_window:\n        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist\n         *       %ecx = nbytes\n         *\n         * nbytes = out - beg;\n         * if (dist <= nbytes) {\n         *   from = out - dist;\n         *   do {\n         *     PUP(out) = PUP(from);\n         *   } while (--len > 0) {\n         * }\n         */\n\n        movl    in_r, in(%esp)          /* save in so from can use it's reg */\n        movl    out_r, %eax\n        subl    beg(%esp), %eax         /* nbytes = out - beg */\n\n        cmpl    dist_r, %eax\n        jb      .L_clip_window          /* if (dist > nbytes) 4.2% */\n\n        movl    len(%esp), %ecx\n        movl    out_r, from_r\n        subl    dist_r, from_r          /* from = out - dist */\n\n        subl    $3, %ecx\n        movb    (from_r), %al\n        movb    %al, (out_r)\n        movb    1(from_r), %al\n        movb    2(from_r), %dl\n        addl    $3, from_r\n        movb    %al, 1(out_r)\n        movb    %dl, 2(out_r)\n        addl    $3, out_r\n        rep     movsb\n\n        movl    in(%esp), in_r          /* move in back to %esi, toss from */\n        jmp     .L_while_test\n\n.align 16,0x90\n.L_check_dist_one:\n        cmpl    $1, dist_r\n        jne     .L_check_window\n        cmpl    out_r, beg(%esp)\n        je      .L_check_window\n\n        decl    out_r\n        movl    len(%esp), %ecx\n        movb    (out_r), %al\n        subl    $3, %ecx\n\n        movb    %al, 1(out_r)\n        movb    %al, 2(out_r)\n        movb    %al, 3(out_r)\n        addl    $4, out_r\n        rep     stosb\n\n        jmp     .L_while_test\n\n.align 16,0x90\n.L_test_for_second_level_length:\n        /* else if ((op & 64) == 0) {\n         *   this = lcode[this.val + (hold & mask[op])];\n         * }\n         */\n        testb   $64, %al\n        jnz     .L_test_for_end_of_block  /* if ((op & 64) != 0) */\n\n        movl    $1, %eax\n        shll    %cl, %eax\n        decl    %eax\n        andl    hold_r, %eax            /* eax &= hold */\n        addl    %edx, %eax              /* eax += this.val */\n        movl    lcode(%esp), %edx       /* edx = lcode */\n        movl    (%edx,%eax,4), %eax     /* eax = lcode[val + (hold&mask[op])] */\n        jmp     .L_dolen\n\n.align 16,0x90\n.L_test_for_second_level_dist:\n        /* else if ((op & 64) == 0) {\n         *   this = dcode[this.val + (hold & mask[op])];\n         * }\n         */\n        testb   $64, %al\n        jnz     .L_invalid_distance_code  /* if ((op & 64) != 0) */\n\n        movl    $1, %eax\n        shll    %cl, %eax\n        decl    %eax\n        andl    hold_r, %eax            /* eax &= hold */\n        addl    %edx, %eax              /* eax += this.val */\n        movl    dcode(%esp), %edx       /* edx = dcode */\n        movl    (%edx,%eax,4), %eax     /* eax = dcode[val + (hold&mask[op])] */\n        jmp     .L_dodist\n\n.align 16,0x90\n.L_clip_window:\n        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist\n         *       %ecx = nbytes\n         *\n         * else {\n         *   if (dist > wsize) {\n         *     invalid distance\n         *   }\n         *   from = window;\n         *   nbytes = dist - nbytes;\n         *   if (write == 0) {\n         *     from += wsize - nbytes;\n         */\n#define nbytes_r %ecx\n        movl    %eax, nbytes_r\n        movl    wsize(%esp), %eax       /* prepare for dist compare */\n        negl    nbytes_r                /* nbytes = -nbytes */\n        movl    window(%esp), from_r    /* from = window */\n\n        cmpl    dist_r, %eax\n        jb      .L_invalid_distance_too_far /* if (dist > wsize) */\n\n        addl    dist_r, nbytes_r        /* nbytes = dist - nbytes */\n        cmpl    $0, write(%esp)\n        jne     .L_wrap_around_window   /* if (write != 0) */\n\n        subl    nbytes_r, %eax\n        addl    %eax, from_r            /* from += wsize - nbytes */\n\n        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist\n         *       %ecx = nbytes, %eax = len\n         *\n         *     if (nbytes < len) {\n         *       len -= nbytes;\n         *       do {\n         *         PUP(out) = PUP(from);\n         *       } while (--nbytes);\n         *       from = out - dist;\n         *     }\n         *   }\n         */\n#define len_r %eax\n        movl    len(%esp), len_r\n        cmpl    nbytes_r, len_r\n        jbe     .L_do_copy1             /* if (nbytes >= len) */\n\n        subl    nbytes_r, len_r         /* len -= nbytes */\n        rep     movsb\n        movl    out_r, from_r\n        subl    dist_r, from_r          /* from = out - dist */\n        jmp     .L_do_copy1\n\n        cmpl    nbytes_r, len_r\n        jbe     .L_do_copy1             /* if (nbytes >= len) */\n\n        subl    nbytes_r, len_r         /* len -= nbytes */\n        rep     movsb\n        movl    out_r, from_r\n        subl    dist_r, from_r          /* from = out - dist */\n        jmp     .L_do_copy1\n\n.L_wrap_around_window:\n        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist\n         *       %ecx = nbytes, %eax = write, %eax = len\n         *\n         *   else if (write < nbytes) {\n         *     from += wsize + write - nbytes;\n         *     nbytes -= write;\n         *     if (nbytes < len) {\n         *       len -= nbytes;\n         *       do {\n         *         PUP(out) = PUP(from);\n         *       } while (--nbytes);\n         *       from = window;\n         *       nbytes = write;\n         *       if (nbytes < len) {\n         *         len -= nbytes;\n         *         do {\n         *           PUP(out) = PUP(from);\n         *         } while(--nbytes);\n         *         from = out - dist;\n         *       }\n         *     }\n         *   }\n         */\n#define write_r %eax\n        movl    write(%esp), write_r\n        cmpl    write_r, nbytes_r\n        jbe     .L_contiguous_in_window /* if (write >= nbytes) */\n\n        addl    wsize(%esp), from_r\n        addl    write_r, from_r\n        subl    nbytes_r, from_r        /* from += wsize + write - nbytes */\n        subl    write_r, nbytes_r       /* nbytes -= write */\n#undef write_r\n\n        movl    len(%esp), len_r\n        cmpl    nbytes_r, len_r\n        jbe     .L_do_copy1             /* if (nbytes >= len) */\n\n        subl    nbytes_r, len_r         /* len -= nbytes */\n        rep     movsb\n        movl    window(%esp), from_r    /* from = window */\n        movl    write(%esp), nbytes_r   /* nbytes = write */\n        cmpl    nbytes_r, len_r\n        jbe     .L_do_copy1             /* if (nbytes >= len) */\n\n        subl    nbytes_r, len_r         /* len -= nbytes */\n        rep     movsb\n        movl    out_r, from_r\n        subl    dist_r, from_r          /* from = out - dist */\n        jmp     .L_do_copy1\n\n.L_contiguous_in_window:\n        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist\n         *       %ecx = nbytes, %eax = write, %eax = len\n         *\n         *   else {\n         *     from += write - nbytes;\n         *     if (nbytes < len) {\n         *       len -= nbytes;\n         *       do {\n         *         PUP(out) = PUP(from);\n         *       } while (--nbytes);\n         *       from = out - dist;\n         *     }\n         *   }\n         */\n#define write_r %eax\n        addl    write_r, from_r\n        subl    nbytes_r, from_r        /* from += write - nbytes */\n#undef write_r\n\n        movl    len(%esp), len_r\n        cmpl    nbytes_r, len_r\n        jbe     .L_do_copy1             /* if (nbytes >= len) */\n\n        subl    nbytes_r, len_r         /* len -= nbytes */\n        rep     movsb\n        movl    out_r, from_r\n        subl    dist_r, from_r          /* from = out - dist */\n\n.L_do_copy1:\n        /* regs: %esi = from, %esi = in, %ebp = hold, %bl = bits, %edi = out\n         *       %eax = len\n         *\n         *     while (len > 0) {\n         *       PUP(out) = PUP(from);\n         *       len--;\n         *     }\n         *   }\n         * } while (in < last && out < end);\n         */\n#undef nbytes_r\n#define in_r %esi\n        movl    len_r, %ecx\n        rep     movsb\n\n        movl    in(%esp), in_r          /* move in back to %esi, toss from */\n        jmp     .L_while_test\n\n#undef len_r\n#undef dist_r\n\n#endif /* NO_MMX || RUN_TIME_MMX */\n\n\n/*** MMX code ***/\n\n#if defined( USE_MMX ) || defined( RUN_TIME_MMX )\n\n.align 32,0x90\n.L_init_mmx:\n        emms\n\n#undef  bits_r\n#undef  bitslong_r\n#define bitslong_r %ebp\n#define hold_mm    %mm0\n        movd    %ebp, hold_mm\n        movl    %ebx, bitslong_r\n\n#define used_mm   %mm1\n#define dmask2_mm %mm2\n#define lmask2_mm %mm3\n#define lmask_mm  %mm4\n#define dmask_mm  %mm5\n#define tmp_mm    %mm6\n\n        movd    lmask(%esp), lmask_mm\n        movq    lmask_mm, lmask2_mm\n        movd    dmask(%esp), dmask_mm\n        movq    dmask_mm, dmask2_mm\n        pxor    used_mm, used_mm\n        movl    lcode(%esp), %ebx       /* ebx = lcode */\n        jmp     .L_do_loop_mmx\n\n.align 32,0x90\n.L_while_test_mmx:\n        /* while (in < last && out < end)\n         */\n        cmpl    out_r, end(%esp)\n        jbe     .L_break_loop           /* if (out >= end) */\n\n        cmpl    in_r, last(%esp)\n        jbe     .L_break_loop\n\n.L_do_loop_mmx:\n        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */\n\n        cmpl    $32, bitslong_r\n        ja      .L_get_length_code_mmx  /* if (32 < bits) */\n\n        movd    bitslong_r, tmp_mm\n        movd    (in_r), %mm7\n        addl    $4, in_r\n        psllq   tmp_mm, %mm7\n        addl    $32, bitslong_r\n        por     %mm7, hold_mm           /* hold_mm |= *((uint *)in)++ << bits */\n\n.L_get_length_code_mmx:\n        pand    hold_mm, lmask_mm\n        movd    lmask_mm, %eax\n        movq    lmask2_mm, lmask_mm\n        movl    (%ebx,%eax,4), %eax     /* eax = lcode[hold & lmask] */\n\n.L_dolen_mmx:\n        movzbl  %ah, %ecx               /* ecx = this.bits */\n        movd    %ecx, used_mm\n        subl    %ecx, bitslong_r        /* bits -= this.bits */\n\n        testb   %al, %al\n        jnz     .L_test_for_length_base_mmx /* if (op != 0) 45.7% */\n\n        shrl    $16, %eax               /* output this.val char */\n        stosb\n        jmp     .L_while_test_mmx\n\n.L_test_for_length_base_mmx:\n#define len_r  %edx\n        movl    %eax, len_r             /* len = this */\n        shrl    $16, len_r              /* len = this.val */\n\n        testb   $16, %al\n        jz      .L_test_for_second_level_length_mmx /* if ((op & 16) == 0) 8% */\n        andl    $15, %eax               /* op &= 15 */\n        jz      .L_decode_distance_mmx  /* if (!op) */\n\n        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */\n        movd    %eax, used_mm\n        movd    hold_mm, %ecx\n        subl    %eax, bitslong_r\n        andl    .L_mask(,%eax,4), %ecx\n        addl    %ecx, len_r             /* len += hold & mask[op] */\n\n.L_decode_distance_mmx:\n        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */\n\n        cmpl    $32, bitslong_r\n        ja      .L_get_dist_code_mmx    /* if (32 < bits) */\n\n        movd    bitslong_r, tmp_mm\n        movd    (in_r), %mm7\n        addl    $4, in_r\n        psllq   tmp_mm, %mm7\n        addl    $32, bitslong_r\n        por     %mm7, hold_mm           /* hold_mm |= *((uint *)in)++ << bits */\n\n.L_get_dist_code_mmx:\n        movl    dcode(%esp), %ebx       /* ebx = dcode */\n        pand    hold_mm, dmask_mm\n        movd    dmask_mm, %eax\n        movq    dmask2_mm, dmask_mm\n        movl    (%ebx,%eax,4), %eax     /* eax = dcode[hold & lmask] */\n\n.L_dodist_mmx:\n#define dist_r %ebx\n        movzbl  %ah, %ecx               /* ecx = this.bits */\n        movl    %eax, dist_r\n        shrl    $16, dist_r             /* dist  = this.val */\n        subl    %ecx, bitslong_r        /* bits -= this.bits */\n        movd    %ecx, used_mm\n\n        testb   $16, %al                /* if ((op & 16) == 0) */\n        jz      .L_test_for_second_level_dist_mmx\n        andl    $15, %eax               /* op &= 15 */\n        jz      .L_check_dist_one_mmx\n\n.L_add_bits_to_dist_mmx:\n        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */\n        movd    %eax, used_mm           /* save bit length of current op */\n        movd    hold_mm, %ecx           /* get the next bits on input stream */\n        subl    %eax, bitslong_r        /* bits -= op bits */\n        andl    .L_mask(,%eax,4), %ecx  /* ecx   = hold & mask[op] */\n        addl    %ecx, dist_r            /* dist += hold & mask[op] */\n\n.L_check_window_mmx:\n        movl    in_r, in(%esp)          /* save in so from can use it's reg */\n        movl    out_r, %eax\n        subl    beg(%esp), %eax         /* nbytes = out - beg */\n\n        cmpl    dist_r, %eax\n        jb      .L_clip_window_mmx      /* if (dist > nbytes) 4.2% */\n\n        movl    len_r, %ecx\n        movl    out_r, from_r\n        subl    dist_r, from_r          /* from = out - dist */\n\n        subl    $3, %ecx\n        movb    (from_r), %al\n        movb    %al, (out_r)\n        movb    1(from_r), %al\n        movb    2(from_r), %dl\n        addl    $3, from_r\n        movb    %al, 1(out_r)\n        movb    %dl, 2(out_r)\n        addl    $3, out_r\n        rep     movsb\n\n        movl    in(%esp), in_r          /* move in back to %esi, toss from */\n        movl    lcode(%esp), %ebx       /* move lcode back to %ebx, toss dist */\n        jmp     .L_while_test_mmx\n\n.align 16,0x90\n.L_check_dist_one_mmx:\n        cmpl    $1, dist_r\n        jne     .L_check_window_mmx\n        cmpl    out_r, beg(%esp)\n        je      .L_check_window_mmx\n\n        decl    out_r\n        movl    len_r, %ecx\n        movb    (out_r), %al\n        subl    $3, %ecx\n\n        movb    %al, 1(out_r)\n        movb    %al, 2(out_r)\n        movb    %al, 3(out_r)\n        addl    $4, out_r\n        rep     stosb\n\n        movl    lcode(%esp), %ebx       /* move lcode back to %ebx, toss dist */\n        jmp     .L_while_test_mmx\n\n.align 16,0x90\n.L_test_for_second_level_length_mmx:\n        testb   $64, %al\n        jnz     .L_test_for_end_of_block  /* if ((op & 64) != 0) */\n\n        andl    $15, %eax\n        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */\n        movd    hold_mm, %ecx\n        andl    .L_mask(,%eax,4), %ecx\n        addl    len_r, %ecx\n        movl    (%ebx,%ecx,4), %eax     /* eax = lcode[hold & lmask] */\n        jmp     .L_dolen_mmx\n\n.align 16,0x90\n.L_test_for_second_level_dist_mmx:\n        testb   $64, %al\n        jnz     .L_invalid_distance_code  /* if ((op & 64) != 0) */\n\n        andl    $15, %eax\n        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */\n        movd    hold_mm, %ecx\n        andl    .L_mask(,%eax,4), %ecx\n        movl    dcode(%esp), %eax       /* ecx = dcode */\n        addl    dist_r, %ecx\n        movl    (%eax,%ecx,4), %eax     /* eax = lcode[hold & lmask] */\n        jmp     .L_dodist_mmx\n\n.align 16,0x90\n.L_clip_window_mmx:\n#define nbytes_r %ecx\n        movl    %eax, nbytes_r\n        movl    wsize(%esp), %eax       /* prepare for dist compare */\n        negl    nbytes_r                /* nbytes = -nbytes */\n        movl    window(%esp), from_r    /* from = window */\n\n        cmpl    dist_r, %eax\n        jb      .L_invalid_distance_too_far /* if (dist > wsize) */\n\n        addl    dist_r, nbytes_r        /* nbytes = dist - nbytes */\n        cmpl    $0, write(%esp)\n        jne     .L_wrap_around_window_mmx /* if (write != 0) */\n\n        subl    nbytes_r, %eax\n        addl    %eax, from_r            /* from += wsize - nbytes */\n\n        cmpl    nbytes_r, len_r\n        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */\n\n        subl    nbytes_r, len_r         /* len -= nbytes */\n        rep     movsb\n        movl    out_r, from_r\n        subl    dist_r, from_r          /* from = out - dist */\n        jmp     .L_do_copy1_mmx\n\n        cmpl    nbytes_r, len_r\n        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */\n\n        subl    nbytes_r, len_r         /* len -= nbytes */\n        rep     movsb\n        movl    out_r, from_r\n        subl    dist_r, from_r          /* from = out - dist */\n        jmp     .L_do_copy1_mmx\n\n.L_wrap_around_window_mmx:\n#define write_r %eax\n        movl    write(%esp), write_r\n        cmpl    write_r, nbytes_r\n        jbe     .L_contiguous_in_window_mmx /* if (write >= nbytes) */\n\n        addl    wsize(%esp), from_r\n        addl    write_r, from_r\n        subl    nbytes_r, from_r        /* from += wsize + write - nbytes */\n        subl    write_r, nbytes_r       /* nbytes -= write */\n#undef write_r\n\n        cmpl    nbytes_r, len_r\n        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */\n\n        subl    nbytes_r, len_r         /* len -= nbytes */\n        rep     movsb\n        movl    window(%esp), from_r    /* from = window */\n        movl    write(%esp), nbytes_r   /* nbytes = write */\n        cmpl    nbytes_r, len_r\n        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */\n\n        subl    nbytes_r, len_r         /* len -= nbytes */\n        rep     movsb\n        movl    out_r, from_r\n        subl    dist_r, from_r          /* from = out - dist */\n        jmp     .L_do_copy1_mmx\n\n.L_contiguous_in_window_mmx:\n#define write_r %eax\n        addl    write_r, from_r\n        subl    nbytes_r, from_r        /* from += write - nbytes */\n#undef write_r\n\n        cmpl    nbytes_r, len_r\n        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */\n\n        subl    nbytes_r, len_r         /* len -= nbytes */\n        rep     movsb\n        movl    out_r, from_r\n        subl    dist_r, from_r          /* from = out - dist */\n\n.L_do_copy1_mmx:\n#undef nbytes_r\n#define in_r %esi\n        movl    len_r, %ecx\n        rep     movsb\n\n        movl    in(%esp), in_r          /* move in back to %esi, toss from */\n        movl    lcode(%esp), %ebx       /* move lcode back to %ebx, toss dist */\n        jmp     .L_while_test_mmx\n\n#undef hold_r\n#undef bitslong_r\n\n#endif /* USE_MMX || RUN_TIME_MMX */\n\n\n/*** USE_MMX, NO_MMX, and RUNTIME_MMX from here on ***/\n\n.L_invalid_distance_code:\n        /* else {\n         *   strm->msg = \"invalid distance code\";\n         *   state->mode = BAD;\n         * }\n         */\n        movl    $.L_invalid_distance_code_msg, %ecx\n        movl    $INFLATE_MODE_BAD, %edx\n        jmp     .L_update_stream_state\n\n.L_test_for_end_of_block:\n        /* else if (op & 32) {\n         *   state->mode = TYPE;\n         *   break;\n         * }\n         */\n        testb   $32, %al\n        jz      .L_invalid_literal_length_code  /* if ((op & 32) == 0) */\n\n        movl    $0, %ecx\n        movl    $INFLATE_MODE_TYPE, %edx\n        jmp     .L_update_stream_state\n\n.L_invalid_literal_length_code:\n        /* else {\n         *   strm->msg = \"invalid literal/length code\";\n         *   state->mode = BAD;\n         * }\n         */\n        movl    $.L_invalid_literal_length_code_msg, %ecx\n        movl    $INFLATE_MODE_BAD, %edx\n        jmp     .L_update_stream_state\n\n.L_invalid_distance_too_far:\n        /* strm->msg = \"invalid distance too far back\";\n         * state->mode = BAD;\n         */\n        movl    in(%esp), in_r          /* from_r has in's reg, put in back */\n        movl    $.L_invalid_distance_too_far_msg, %ecx\n        movl    $INFLATE_MODE_BAD, %edx\n        jmp     .L_update_stream_state\n\n.L_update_stream_state:\n        /* set strm->msg = %ecx, strm->state->mode = %edx */\n        movl    strm_sp(%esp), %eax\n        testl   %ecx, %ecx              /* if (msg != NULL) */\n        jz      .L_skip_msg\n        movl    %ecx, msg_strm(%eax)    /* strm->msg = msg */\n.L_skip_msg:\n        movl    state_strm(%eax), %eax  /* state = strm->state */\n        movl    %edx, mode_state(%eax)  /* state->mode = edx (BAD | TYPE) */\n        jmp     .L_break_loop\n\n.align 32,0x90\n.L_break_loop:\n\n/*\n * Regs:\n *\n * bits = %ebp when mmx, and in %ebx when non-mmx\n * hold = %hold_mm when mmx, and in %ebp when non-mmx\n * in   = %esi\n * out  = %edi\n */\n\n#if defined( USE_MMX ) || defined( RUN_TIME_MMX )\n\n#if defined( RUN_TIME_MMX )\n\n        cmpl    $DO_USE_MMX, inflate_fast_use_mmx\n        jne     .L_update_next_in\n\n#endif /* RUN_TIME_MMX */\n\n        movl    %ebp, %ebx\n\n.L_update_next_in:\n\n#endif\n\n#define strm_r  %eax\n#define state_r %edx\n\n        /* len = bits >> 3;\n         * in -= len;\n         * bits -= len << 3;\n         * hold &= (1U << bits) - 1;\n         * state->hold = hold;\n         * state->bits = bits;\n         * strm->next_in = in;\n         * strm->next_out = out;\n         */\n        movl    strm_sp(%esp), strm_r\n        movl    %ebx, %ecx\n        movl    state_strm(strm_r), state_r\n        shrl    $3, %ecx\n        subl    %ecx, in_r\n        shll    $3, %ecx\n        subl    %ecx, %ebx\n        movl    out_r, next_out_strm(strm_r)\n        movl    %ebx, bits_state(state_r)\n        movl    %ebx, %ecx\n\n        leal    buf(%esp), %ebx\n        cmpl    %ebx, last(%esp)\n        jne     .L_buf_not_used         /* if buf != last */\n\n        subl    %ebx, in_r              /* in -= buf */\n        movl    next_in_strm(strm_r), %ebx\n        movl    %ebx, last(%esp)        /* last = strm->next_in */\n        addl    %ebx, in_r              /* in += strm->next_in */\n        movl    avail_in_strm(strm_r), %ebx\n        subl    $11, %ebx\n        addl    %ebx, last(%esp)    /* last = &strm->next_in[ avail_in - 11 ] */\n\n.L_buf_not_used:\n        movl    in_r, next_in_strm(strm_r)\n\n        movl    $1, %ebx\n        shll    %cl, %ebx\n        decl    %ebx\n\n#if defined( USE_MMX ) || defined( RUN_TIME_MMX )\n\n#if defined( RUN_TIME_MMX )\n\n        cmpl    $DO_USE_MMX, inflate_fast_use_mmx\n        jne     .L_update_hold\n\n#endif /* RUN_TIME_MMX */\n\n        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */\n        movd    hold_mm, %ebp\n\n        emms\n\n.L_update_hold:\n\n#endif /* USE_MMX || RUN_TIME_MMX */\n\n        andl    %ebx, %ebp\n        movl    %ebp, hold_state(state_r)\n\n#define last_r %ebx\n\n        /* strm->avail_in = in < last ? 11 + (last - in) : 11 - (in - last) */\n        movl    last(%esp), last_r\n        cmpl    in_r, last_r\n        jbe     .L_last_is_smaller     /* if (in >= last) */\n\n        subl    in_r, last_r           /* last -= in */\n        addl    $11, last_r            /* last += 11 */\n        movl    last_r, avail_in_strm(strm_r)\n        jmp     .L_fixup_out\n.L_last_is_smaller:\n        subl    last_r, in_r           /* in -= last */\n        negl    in_r                   /* in = -in */\n        addl    $11, in_r              /* in += 11 */\n        movl    in_r, avail_in_strm(strm_r)\n\n#undef last_r\n#define end_r %ebx\n\n.L_fixup_out:\n        /* strm->avail_out = out < end ? 257 + (end - out) : 257 - (out - end)*/\n        movl    end(%esp), end_r\n        cmpl    out_r, end_r\n        jbe     .L_end_is_smaller      /* if (out >= end) */\n\n        subl    out_r, end_r           /* end -= out */\n        addl    $257, end_r            /* end += 257 */\n        movl    end_r, avail_out_strm(strm_r)\n        jmp     .L_done\n.L_end_is_smaller:\n        subl    end_r, out_r           /* out -= end */\n        negl    out_r                  /* out = -out */\n        addl    $257, out_r            /* out += 257 */\n        movl    out_r, avail_out_strm(strm_r)\n\n#undef end_r\n#undef strm_r\n#undef state_r\n\n.L_done:\n        addl    $local_var_size, %esp\n        popf\n        popl    %ebx\n        popl    %ebp\n        popl    %esi\n        popl    %edi\n        ret\n\n#if defined( GAS_ELF )\n/* elf info */\n.type inflate_fast,@function\n.size inflate_fast,.-inflate_fast\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/iostream/test.cpp",
    "content": "\n#include \"zfstream.h\"\n\nint main() {\n\n  // Construct a stream object with this filebuffer.  Anything sent\n  // to this stream will go to standard out.\n  gzofstream os( 1, ios::out );\n\n  // This text is getting compressed and sent to stdout.\n  // To prove this, run 'test | zcat'.\n  os << \"Hello, Mommy\" << endl;\n\n  os << setcompressionlevel( Z_NO_COMPRESSION );\n  os << \"hello, hello, hi, ho!\" << endl;\n\n  setcompressionlevel( os, Z_DEFAULT_COMPRESSION )\n    << \"I'm compressing again\" << endl;\n\n  os.close();\n\n  return 0;\n\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/iostream/zfstream.cpp",
    "content": "\n#include \"zfstream.h\"\n\ngzfilebuf::gzfilebuf() :\n  file(NULL),\n  mode(0),\n  own_file_descriptor(0)\n{ }\n\ngzfilebuf::~gzfilebuf() {\n\n  sync();\n  if ( own_file_descriptor )\n    close();\n\n}\n\ngzfilebuf *gzfilebuf::open( const char *name,\n                            int io_mode ) {\n\n  if ( is_open() )\n    return NULL;\n\n  char char_mode[10];\n  char *p = char_mode;\n\n  if ( io_mode & ios::in ) {\n    mode = ios::in;\n    *p++ = 'r';\n  } else if ( io_mode & ios::app ) {\n    mode = ios::app;\n    *p++ = 'a';\n  } else {\n    mode = ios::out;\n    *p++ = 'w';\n  }\n\n  if ( io_mode & ios::binary ) {\n    mode |= ios::binary;\n    *p++ = 'b';\n  }\n\n  // Hard code the compression level\n  if ( io_mode & (ios::out|ios::app )) {\n    *p++ = '9';\n  }\n\n  // Put the end-of-string indicator\n  *p = '\\0';\n\n  if ( (file = gzopen(name, char_mode)) == NULL )\n    return NULL;\n\n  own_file_descriptor = 1;\n\n  return this;\n\n}\n\ngzfilebuf *gzfilebuf::attach( int file_descriptor,\n                              int io_mode ) {\n\n  if ( is_open() )\n    return NULL;\n\n  char char_mode[10];\n  char *p = char_mode;\n\n  if ( io_mode & ios::in ) {\n    mode = ios::in;\n    *p++ = 'r';\n  } else if ( io_mode & ios::app ) {\n    mode = ios::app;\n    *p++ = 'a';\n  } else {\n    mode = ios::out;\n    *p++ = 'w';\n  }\n\n  if ( io_mode & ios::binary ) {\n    mode |= ios::binary;\n    *p++ = 'b';\n  }\n\n  // Hard code the compression level\n  if ( io_mode & (ios::out|ios::app )) {\n    *p++ = '9';\n  }\n\n  // Put the end-of-string indicator\n  *p = '\\0';\n\n  if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )\n    return NULL;\n\n  own_file_descriptor = 0;\n\n  return this;\n\n}\n\ngzfilebuf *gzfilebuf::close() {\n\n  if ( is_open() ) {\n\n    sync();\n    gzclose( file );\n    file = NULL;\n\n  }\n\n  return this;\n\n}\n\nint gzfilebuf::setcompressionlevel( int comp_level ) {\n\n  return gzsetparams(file, comp_level, -2);\n\n}\n\nint gzfilebuf::setcompressionstrategy( int comp_strategy ) {\n\n  return gzsetparams(file, -2, comp_strategy);\n\n}\n\n\nstreampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) {\n\n  return streampos(EOF);\n\n}\n\nint gzfilebuf::underflow() {\n\n  // If the file hasn't been opened for reading, error.\n  if ( !is_open() || !(mode & ios::in) )\n    return EOF;\n\n  // if a buffer doesn't exists, allocate one.\n  if ( !base() ) {\n\n    if ( (allocate()) == EOF )\n      return EOF;\n    setp(0,0);\n\n  } else {\n\n    if ( in_avail() )\n      return (unsigned char) *gptr();\n\n    if ( out_waiting() ) {\n      if ( flushbuf() == EOF )\n        return EOF;\n    }\n\n  }\n\n  // Attempt to fill the buffer.\n\n  int result = fillbuf();\n  if ( result == EOF ) {\n    // disable get area\n    setg(0,0,0);\n    return EOF;\n  }\n\n  return (unsigned char) *gptr();\n\n}\n\nint gzfilebuf::overflow( int c ) {\n\n  if ( !is_open() || !(mode & ios::out) )\n    return EOF;\n\n  if ( !base() ) {\n    if ( allocate() == EOF )\n      return EOF;\n    setg(0,0,0);\n  } else {\n    if (in_avail()) {\n        return EOF;\n    }\n    if (out_waiting()) {\n      if (flushbuf() == EOF)\n        return EOF;\n    }\n  }\n\n  int bl = blen();\n  setp( base(), base() + bl);\n\n  if ( c != EOF ) {\n\n    *pptr() = c;\n    pbump(1);\n\n  }\n\n  return 0;\n\n}\n\nint gzfilebuf::sync() {\n\n  if ( !is_open() )\n    return EOF;\n\n  if ( out_waiting() )\n    return flushbuf();\n\n  return 0;\n\n}\n\nint gzfilebuf::flushbuf() {\n\n  int n;\n  char *q;\n\n  q = pbase();\n  n = pptr() - q;\n\n  if ( gzwrite( file, q, n) < n )\n    return EOF;\n\n  setp(0,0);\n\n  return 0;\n\n}\n\nint gzfilebuf::fillbuf() {\n\n  int required;\n  char *p;\n\n  p = base();\n\n  required = blen();\n\n  int t = gzread( file, p, required );\n\n  if ( t <= 0) return EOF;\n\n  setg( base(), base(), base()+t);\n\n  return t;\n\n}\n\ngzfilestream_common::gzfilestream_common() :\n  ios( gzfilestream_common::rdbuf() )\n{ }\n\ngzfilestream_common::~gzfilestream_common()\n{ }\n\nvoid gzfilestream_common::attach( int fd, int io_mode ) {\n\n  if ( !buffer.attach( fd, io_mode) )\n    clear( ios::failbit | ios::badbit );\n  else\n    clear();\n\n}\n\nvoid gzfilestream_common::open( const char *name, int io_mode ) {\n\n  if ( !buffer.open( name, io_mode ) )\n    clear( ios::failbit | ios::badbit );\n  else\n    clear();\n\n}\n\nvoid gzfilestream_common::close() {\n\n  if ( !buffer.close() )\n    clear( ios::failbit | ios::badbit );\n\n}\n\ngzfilebuf *gzfilestream_common::rdbuf()\n{\n  return &buffer;\n}\n\ngzifstream::gzifstream() :\n  ios( gzfilestream_common::rdbuf() )\n{\n  clear( ios::badbit );\n}\n\ngzifstream::gzifstream( const char *name, int io_mode ) :\n  ios( gzfilestream_common::rdbuf() )\n{\n  gzfilestream_common::open( name, io_mode );\n}\n\ngzifstream::gzifstream( int fd, int io_mode ) :\n  ios( gzfilestream_common::rdbuf() )\n{\n  gzfilestream_common::attach( fd, io_mode );\n}\n\ngzifstream::~gzifstream() { }\n\ngzofstream::gzofstream() :\n  ios( gzfilestream_common::rdbuf() )\n{\n  clear( ios::badbit );\n}\n\ngzofstream::gzofstream( const char *name, int io_mode ) :\n  ios( gzfilestream_common::rdbuf() )\n{\n  gzfilestream_common::open( name, io_mode );\n}\n\ngzofstream::gzofstream( int fd, int io_mode ) :\n  ios( gzfilestream_common::rdbuf() )\n{\n  gzfilestream_common::attach( fd, io_mode );\n}\n\ngzofstream::~gzofstream() { }\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/iostream/zfstream.h",
    "content": "\n#ifndef zfstream_h\n#define zfstream_h\n\n#include <fstream.h>\n#include \"zlib.h\"\n\nclass gzfilebuf : public streambuf {\n\npublic:\n\n  gzfilebuf( );\n  virtual ~gzfilebuf();\n\n  gzfilebuf *open( const char *name, int io_mode );\n  gzfilebuf *attach( int file_descriptor, int io_mode );\n  gzfilebuf *close();\n\n  int setcompressionlevel( int comp_level );\n  int setcompressionstrategy( int comp_strategy );\n\n  inline int is_open() const { return (file !=NULL); }\n\n  virtual streampos seekoff( streamoff, ios::seek_dir, int );\n\n  virtual int sync();\n\nprotected:\n\n  virtual int underflow();\n  virtual int overflow( int = EOF );\n\nprivate:\n\n  gzFile file;\n  short mode;\n  short own_file_descriptor;\n\n  int flushbuf();\n  int fillbuf();\n\n};\n\nclass gzfilestream_common : virtual public ios {\n\n  friend class gzifstream;\n  friend class gzofstream;\n  friend gzofstream &setcompressionlevel( gzofstream &, int );\n  friend gzofstream &setcompressionstrategy( gzofstream &, int );\n\npublic:\n  virtual ~gzfilestream_common();\n\n  void attach( int fd, int io_mode );\n  void open( const char *name, int io_mode );\n  void close();\n\nprotected:\n  gzfilestream_common();\n\nprivate:\n  gzfilebuf *rdbuf();\n\n  gzfilebuf buffer;\n\n};\n\nclass gzifstream : public gzfilestream_common, public istream {\n\npublic:\n\n  gzifstream();\n  gzifstream( const char *name, int io_mode = ios::in );\n  gzifstream( int fd, int io_mode = ios::in );\n\n  virtual ~gzifstream();\n\n};\n\nclass gzofstream : public gzfilestream_common, public ostream {\n\npublic:\n\n  gzofstream();\n  gzofstream( const char *name, int io_mode = ios::out );\n  gzofstream( int fd, int io_mode = ios::out );\n\n  virtual ~gzofstream();\n\n};\n\ntemplate<class T> class gzomanip {\n  friend gzofstream &operator<<(gzofstream &, const gzomanip<T> &);\npublic:\n  gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { }\nprivate:\n  gzofstream &(*func)(gzofstream &, T);\n  T val;\n};\n\ntemplate<class T> gzofstream &operator<<(gzofstream &s, const gzomanip<T> &m)\n{\n  return (*m.func)(s, m.val);\n}\n\ninline gzofstream &setcompressionlevel( gzofstream &s, int l )\n{\n  (s.rdbuf())->setcompressionlevel(l);\n  return s;\n}\n\ninline gzofstream &setcompressionstrategy( gzofstream &s, int l )\n{\n  (s.rdbuf())->setcompressionstrategy(l);\n  return s;\n}\n\ninline gzomanip<int> setcompressionlevel(int l)\n{\n  return gzomanip<int>(&setcompressionlevel,l);\n}\n\ninline gzomanip<int> setcompressionstrategy(int l)\n{\n  return gzomanip<int>(&setcompressionstrategy,l);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/iostream2/zstream.h",
    "content": "/*\n *\n * Copyright (c) 1997\n * Christian Michelsen Research AS\n * Advanced Computing\n * Fantoftvegen 38, 5036 BERGEN, Norway\n * http://www.cmr.no\n *\n * Permission to use, copy, modify, distribute and sell this software\n * and its documentation for any purpose is hereby granted without fee,\n * provided that the above copyright notice appear in all copies and\n * that both that copyright notice and this permission notice appear\n * in supporting documentation.  Christian Michelsen Research AS makes no\n * representations about the suitability of this software for any\n * purpose.  It is provided \"as is\" without express or implied warranty.\n *\n */\n\n#ifndef ZSTREAM__H\n#define ZSTREAM__H\n\n/*\n * zstream.h - C++ interface to the 'zlib' general purpose compression library\n * $Id: zstream.h 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $\n */\n\n#include <strstream.h>\n#include <string.h>\n#include <stdio.h>\n#include \"zlib.h\"\n\n#if defined(_WIN32)\n#   include <fcntl.h>\n#   include <io.h>\n#   define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)\n#else\n#   define SET_BINARY_MODE(file)\n#endif\n\nclass zstringlen {\npublic:\n    zstringlen(class izstream&);\n    zstringlen(class ozstream&, const char*);\n    size_t value() const { return val.word; }\nprivate:\n    struct Val { unsigned char byte; size_t word; } val;\n};\n\n//  ----------------------------- izstream -----------------------------\n\nclass izstream\n{\n    public:\n        izstream() : m_fp(0) {}\n        izstream(FILE* fp) : m_fp(0) { open(fp); }\n        izstream(const char* name) : m_fp(0) { open(name); }\n        ~izstream() { close(); }\n\n        /* Opens a gzip (.gz) file for reading.\n         * open() can be used to read a file which is not in gzip format;\n         * in this case read() will directly read from the file without\n         * decompression. errno can be checked to distinguish two error\n         * cases (if errno is zero, the zlib error is Z_MEM_ERROR).\n         */\n        void open(const char* name) {\n            if (m_fp) close();\n            m_fp = ::gzopen(name, \"rb\");\n        }\n\n        void open(FILE* fp) {\n            SET_BINARY_MODE(fp);\n            if (m_fp) close();\n            m_fp = ::gzdopen(fileno(fp), \"rb\");\n        }\n\n        /* Flushes all pending input if necessary, closes the compressed file\n         * and deallocates all the (de)compression state. The return value is\n         * the zlib error number (see function error() below).\n         */\n        int close() {\n            int r = ::gzclose(m_fp);\n            m_fp = 0; return r;\n        }\n\n        /* Binary read the given number of bytes from the compressed file.\n         */\n        int read(void* buf, size_t len) {\n            return ::gzread(m_fp, buf, len);\n        }\n\n        /* Returns the error message for the last error which occurred on the\n         * given compressed file. errnum is set to zlib error number. If an\n         * error occurred in the file system and not in the compression library,\n         * errnum is set to Z_ERRNO and the application may consult errno\n         * to get the exact error code.\n         */\n        const char* error(int* errnum) {\n            return ::gzerror(m_fp, errnum);\n        }\n\n        gzFile fp() { return m_fp; }\n\n    private:\n        gzFile m_fp;\n};\n\n/*\n * Binary read the given (array of) object(s) from the compressed file.\n * If the input file was not in gzip format, read() copies the objects number\n * of bytes into the buffer.\n * returns the number of uncompressed bytes actually read\n * (0 for end of file, -1 for error).\n */\ntemplate <class T, class Items>\ninline int read(izstream& zs, T* x, Items items) {\n    return ::gzread(zs.fp(), x, items*sizeof(T));\n}\n\n/*\n * Binary input with the '>' operator.\n */\ntemplate <class T>\ninline izstream& operator>(izstream& zs, T& x) {\n    ::gzread(zs.fp(), &x, sizeof(T));\n    return zs;\n}\n\n\ninline zstringlen::zstringlen(izstream& zs) {\n    zs > val.byte;\n    if (val.byte == 255) zs > val.word;\n    else val.word = val.byte;\n}\n\n/*\n * Read length of string + the string with the '>' operator.\n */\ninline izstream& operator>(izstream& zs, char* x) {\n    zstringlen len(zs);\n    ::gzread(zs.fp(), x, len.value());\n    x[len.value()] = '\\0';\n    return zs;\n}\n\ninline char* read_string(izstream& zs) {\n    zstringlen len(zs);\n    char* x = new char[len.value()+1];\n    ::gzread(zs.fp(), x, len.value());\n    x[len.value()] = '\\0';\n    return x;\n}\n\n// ----------------------------- ozstream -----------------------------\n\nclass ozstream\n{\n    public:\n        ozstream() : m_fp(0), m_os(0) {\n        }\n        ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION)\n            : m_fp(0), m_os(0) {\n            open(fp, level);\n        }\n        ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION)\n            : m_fp(0), m_os(0) {\n            open(name, level);\n        }\n        ~ozstream() {\n            close();\n        }\n\n        /* Opens a gzip (.gz) file for writing.\n         * The compression level parameter should be in 0..9\n         * errno can be checked to distinguish two error cases\n         * (if errno is zero, the zlib error is Z_MEM_ERROR).\n         */\n        void open(const char* name, int level = Z_DEFAULT_COMPRESSION) {\n            char mode[4] = \"wb\\0\";\n            if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;\n            if (m_fp) close();\n            m_fp = ::gzopen(name, mode);\n        }\n\n        /* open from a FILE pointer.\n         */\n        void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) {\n            SET_BINARY_MODE(fp);\n            char mode[4] = \"wb\\0\";\n            if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;\n            if (m_fp) close();\n            m_fp = ::gzdopen(fileno(fp), mode);\n        }\n\n        /* Flushes all pending output if necessary, closes the compressed file\n         * and deallocates all the (de)compression state. The return value is\n         * the zlib error number (see function error() below).\n         */\n        int close() {\n            if (m_os) {\n                ::gzwrite(m_fp, m_os->str(), m_os->pcount());\n                delete[] m_os->str(); delete m_os; m_os = 0;\n            }\n            int r = ::gzclose(m_fp); m_fp = 0; return r;\n        }\n\n        /* Binary write the given number of bytes into the compressed file.\n         */\n        int write(const void* buf, size_t len) {\n            return ::gzwrite(m_fp, (voidp) buf, len);\n        }\n\n        /* Flushes all pending output into the compressed file. The parameter\n         * _flush is as in the deflate() function. The return value is the zlib\n         * error number (see function gzerror below). flush() returns Z_OK if\n         * the flush_ parameter is Z_FINISH and all output could be flushed.\n         * flush() should be called only when strictly necessary because it can\n         * degrade compression.\n         */\n        int flush(int _flush) {\n            os_flush();\n            return ::gzflush(m_fp, _flush);\n        }\n\n        /* Returns the error message for the last error which occurred on the\n         * given compressed file. errnum is set to zlib error number. If an\n         * error occurred in the file system and not in the compression library,\n         * errnum is set to Z_ERRNO and the application may consult errno\n         * to get the exact error code.\n         */\n        const char* error(int* errnum) {\n            return ::gzerror(m_fp, errnum);\n        }\n\n        gzFile fp() { return m_fp; }\n\n        ostream& os() {\n            if (m_os == 0) m_os = new ostrstream;\n            return *m_os;\n        }\n\n        void os_flush() {\n            if (m_os && m_os->pcount()>0) {\n                ostrstream* oss = new ostrstream;\n                oss->fill(m_os->fill());\n                oss->flags(m_os->flags());\n                oss->precision(m_os->precision());\n                oss->width(m_os->width());\n                ::gzwrite(m_fp, m_os->str(), m_os->pcount());\n                delete[] m_os->str(); delete m_os; m_os = oss;\n            }\n        }\n\n    private:\n        gzFile m_fp;\n        ostrstream* m_os;\n};\n\n/*\n * Binary write the given (array of) object(s) into the compressed file.\n * returns the number of uncompressed bytes actually written\n * (0 in case of error).\n */\ntemplate <class T, class Items>\ninline int write(ozstream& zs, const T* x, Items items) {\n    return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T));\n}\n\n/*\n * Binary output with the '<' operator.\n */\ntemplate <class T>\ninline ozstream& operator<(ozstream& zs, const T& x) {\n    ::gzwrite(zs.fp(), (voidp) &x, sizeof(T));\n    return zs;\n}\n\ninline zstringlen::zstringlen(ozstream& zs, const char* x) {\n    val.byte = 255;  val.word = ::strlen(x);\n    if (val.word < 255) zs < (val.byte = val.word);\n    else zs < val;\n}\n\n/*\n * Write length of string + the string with the '<' operator.\n */\ninline ozstream& operator<(ozstream& zs, const char* x) {\n    zstringlen len(zs, x);\n    ::gzwrite(zs.fp(), (voidp) x, len.value());\n    return zs;\n}\n\n#ifdef _MSC_VER\ninline ozstream& operator<(ozstream& zs, char* const& x) {\n    return zs < (const char*) x;\n}\n#endif\n\n/*\n * Ascii write with the << operator;\n */\ntemplate <class T>\ninline ostream& operator<<(ozstream& zs, const T& x) {\n    zs.os_flush();\n    return zs.os() << x;\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/iostream2/zstream_test.cpp",
    "content": "#include \"zstream.h\"\n#include <math.h>\n#include <stdlib.h>\n#include <iomanip.h>\n\nvoid main() {\n    char h[256] = \"Hello\";\n    char* g = \"Goodbye\";\n    ozstream out(\"temp.gz\");\n    out < \"This works well\" < h < g;\n    out.close();\n\n    izstream in(\"temp.gz\"); // read it back\n    char *x = read_string(in), *y = new char[256], z[256];\n    in > y > z;\n    in.close();\n    cout << x << endl << y << endl << z << endl;\n\n    out.open(\"temp.gz\"); // try ascii output; zcat temp.gz to see the results\n    out << setw(50) << setfill('#') << setprecision(20) << x << endl << y << endl << z << endl;\n    out << z << endl << y << endl << x << endl;\n    out << 1.1234567890123456789 << endl;\n\n    delete[] x; delete[] y;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/iostream3/README",
    "content": "These classes provide a C++ stream interface to the zlib library. It allows you\nto do things like:\n\n  gzofstream outf(\"blah.gz\");\n  outf << \"These go into the gzip file \" << 123 << endl;\n\nIt does this by deriving a specialized stream buffer for gzipped files, which is\nthe way Stroustrup would have done it. :->\n\nThe gzifstream and gzofstream classes were originally written by Kevin Ruland\nand made available in the zlib contrib/iostream directory. The older version still\ncompiles under gcc 2.xx, but not under gcc 3.xx, which sparked the development of\nthis version.\n\nThe new classes are as standard-compliant as possible, closely following the\napproach of the standard library's fstream classes. It compiles under gcc versions\n3.2 and 3.3, but not under gcc 2.xx. This is mainly due to changes in the standard\nlibrary naming scheme. The new version of gzifstream/gzofstream/gzfilebuf differs\nfrom the previous one in the following respects:\n- added showmanyc\n- added setbuf, with support for unbuffered output via setbuf(0,0)\n- a few bug fixes of stream behavior\n- gzipped output file opened with default compression level instead of maximum level\n- setcompressionlevel()/strategy() members replaced by single setcompression()\n\nThe code is provided \"as is\", with the permission to use, copy, modify, distribute\nand sell it for any purpose without fee.\n\nLudwig Schwardt\n<schwardt@sun.ac.za>\n\nDSP Lab\nElectrical & Electronic Engineering Department\nUniversity of Stellenbosch\nSouth Africa\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/iostream3/TODO",
    "content": "Possible upgrades to gzfilebuf:\n\n- The ability to do putback (e.g. putbackfail)\n\n- The ability to seek (zlib supports this, but could be slow/tricky)\n\n- Simultaneous read/write access (does it make sense?)\n\n- Support for ios_base::ate open mode\n\n- Locale support?\n\n- Check public interface to see which calls give problems\n  (due to dependence on library internals)\n\n- Override operator<<(ostream&, gzfilebuf*) to allow direct copying\n  of stream buffer to stream ( i.e. os << is.rdbuf(); )\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/iostream3/test.cc",
    "content": "/*\n * Test program for gzifstream and gzofstream\n *\n * by Ludwig Schwardt <schwardt@sun.ac.za>\n * original version by Kevin Ruland <kevin@rodin.wustl.edu>\n */\n\n#include \"zfstream.h\"\n#include <iostream>      // for cout\n\nint main() {\n\n  gzofstream outf;\n  gzifstream inf;\n  char buf[80];\n\n  outf.open(\"test1.txt.gz\");\n  outf << \"The quick brown fox sidestepped the lazy canine\\n\"\n       << 1.3 << \"\\nPlan \" << 9 << std::endl;\n  outf.close();\n  std::cout << \"Wrote the following message to 'test1.txt.gz' (check with zcat or zless):\\n\"\n            << \"The quick brown fox sidestepped the lazy canine\\n\"\n            << 1.3 << \"\\nPlan \" << 9 << std::endl;\n\n  std::cout << \"\\nReading 'test1.txt.gz' (buffered) produces:\\n\";\n  inf.open(\"test1.txt.gz\");\n  while (inf.getline(buf,80,'\\n')) {\n    std::cout << buf << \"\\t(\" << inf.rdbuf()->in_avail() << \" chars left in buffer)\\n\";\n  }\n  inf.close();\n\n  outf.rdbuf()->pubsetbuf(0,0);\n  outf.open(\"test2.txt.gz\");\n  outf << setcompression(Z_NO_COMPRESSION)\n       << \"The quick brown fox sidestepped the lazy canine\\n\"\n       << 1.3 << \"\\nPlan \" << 9 << std::endl;\n  outf.close();\n  std::cout << \"\\nWrote the same message to 'test2.txt.gz' in uncompressed form\";\n\n  std::cout << \"\\nReading 'test2.txt.gz' (unbuffered) produces:\\n\";\n  inf.rdbuf()->pubsetbuf(0,0);\n  inf.open(\"test2.txt.gz\");\n  while (inf.getline(buf,80,'\\n')) {\n    std::cout << buf << \"\\t(\" << inf.rdbuf()->in_avail() << \" chars left in buffer)\\n\";\n  }\n  inf.close();\n\n  return 0;\n\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/iostream3/zfstream.cc",
    "content": "/*\n * A C++ I/O streams interface to the zlib gz* functions\n *\n * by Ludwig Schwardt <schwardt@sun.ac.za>\n * original version by Kevin Ruland <kevin@rodin.wustl.edu>\n *\n * This version is standard-compliant and compatible with gcc 3.x.\n */\n\n#include \"zfstream.h\"\n#include <cstring>          // for strcpy, strcat, strlen (mode strings)\n#include <cstdio>           // for BUFSIZ\n\n// Internal buffer sizes (default and \"unbuffered\" versions)\n#define BIGBUFSIZE BUFSIZ\n#define SMALLBUFSIZE 1\n\n/*****************************************************************************/\n\n// Default constructor\ngzfilebuf::gzfilebuf()\n: file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false),\n  buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true)\n{\n  // No buffers to start with\n  this->disable_buffer();\n}\n\n// Destructor\ngzfilebuf::~gzfilebuf()\n{\n  // Sync output buffer and close only if responsible for file\n  // (i.e. attached streams should be left open at this stage)\n  this->sync();\n  if (own_fd)\n    this->close();\n  // Make sure internal buffer is deallocated\n  this->disable_buffer();\n}\n\n// Set compression level and strategy\nint\ngzfilebuf::setcompression(int comp_level,\n                          int comp_strategy)\n{\n  return gzsetparams(file, comp_level, comp_strategy);\n}\n\n// Open gzipped file\ngzfilebuf*\ngzfilebuf::open(const char *name,\n                std::ios_base::openmode mode)\n{\n  // Fail if file already open\n  if (this->is_open())\n    return NULL;\n  // Don't support simultaneous read/write access (yet)\n  if ((mode & std::ios_base::in) && (mode & std::ios_base::out))\n    return NULL;\n\n  // Build mode string for gzopen and check it [27.8.1.3.2]\n  char char_mode[6] = \"\\0\\0\\0\\0\\0\";\n  if (!this->open_mode(mode, char_mode))\n    return NULL;\n\n  // Attempt to open file\n  if ((file = gzopen(name, char_mode)) == NULL)\n    return NULL;\n\n  // On success, allocate internal buffer and set flags\n  this->enable_buffer();\n  io_mode = mode;\n  own_fd = true;\n  return this;\n}\n\n// Attach to gzipped file\ngzfilebuf*\ngzfilebuf::attach(int fd,\n                  std::ios_base::openmode mode)\n{\n  // Fail if file already open\n  if (this->is_open())\n    return NULL;\n  // Don't support simultaneous read/write access (yet)\n  if ((mode & std::ios_base::in) && (mode & std::ios_base::out))\n    return NULL;\n\n  // Build mode string for gzdopen and check it [27.8.1.3.2]\n  char char_mode[6] = \"\\0\\0\\0\\0\\0\";\n  if (!this->open_mode(mode, char_mode))\n    return NULL;\n\n  // Attempt to attach to file\n  if ((file = gzdopen(fd, char_mode)) == NULL)\n    return NULL;\n\n  // On success, allocate internal buffer and set flags\n  this->enable_buffer();\n  io_mode = mode;\n  own_fd = false;\n  return this;\n}\n\n// Close gzipped file\ngzfilebuf*\ngzfilebuf::close()\n{\n  // Fail immediately if no file is open\n  if (!this->is_open())\n    return NULL;\n  // Assume success\n  gzfilebuf* retval = this;\n  // Attempt to sync and close gzipped file\n  if (this->sync() == -1)\n    retval = NULL;\n  if (gzclose(file) < 0)\n    retval = NULL;\n  // File is now gone anyway (postcondition [27.8.1.3.8])\n  file = NULL;\n  own_fd = false;\n  // Destroy internal buffer if it exists\n  this->disable_buffer();\n  return retval;\n}\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n// Convert int open mode to mode string\nbool\ngzfilebuf::open_mode(std::ios_base::openmode mode,\n                     char* c_mode) const\n{\n  bool testb = mode & std::ios_base::binary;\n  bool testi = mode & std::ios_base::in;\n  bool testo = mode & std::ios_base::out;\n  bool testt = mode & std::ios_base::trunc;\n  bool testa = mode & std::ios_base::app;\n\n  // Check for valid flag combinations - see [27.8.1.3.2] (Table 92)\n  // Original zfstream hardcoded the compression level to maximum here...\n  // Double the time for less than 1% size improvement seems\n  // excessive though - keeping it at the default level\n  // To change back, just append \"9\" to the next three mode strings\n  if (!testi && testo && !testt && !testa)\n    strcpy(c_mode, \"w\");\n  if (!testi && testo && !testt && testa)\n    strcpy(c_mode, \"a\");\n  if (!testi && testo && testt && !testa)\n    strcpy(c_mode, \"w\");\n  if (testi && !testo && !testt && !testa)\n    strcpy(c_mode, \"r\");\n  // No read/write mode yet\n//  if (testi && testo && !testt && !testa)\n//    strcpy(c_mode, \"r+\");\n//  if (testi && testo && testt && !testa)\n//    strcpy(c_mode, \"w+\");\n\n  // Mode string should be empty for invalid combination of flags\n  if (strlen(c_mode) == 0)\n    return false;\n  if (testb)\n    strcat(c_mode, \"b\");\n  return true;\n}\n\n// Determine number of characters in internal get buffer\nstd::streamsize\ngzfilebuf::showmanyc()\n{\n  // Calls to underflow will fail if file not opened for reading\n  if (!this->is_open() || !(io_mode & std::ios_base::in))\n    return -1;\n  // Make sure get area is in use\n  if (this->gptr() && (this->gptr() < this->egptr()))\n    return std::streamsize(this->egptr() - this->gptr());\n  else\n    return 0;\n}\n\n// Fill get area from gzipped file\ngzfilebuf::int_type\ngzfilebuf::underflow()\n{\n  // If something is left in the get area by chance, return it\n  // (this shouldn't normally happen, as underflow is only supposed\n  // to be called when gptr >= egptr, but it serves as error check)\n  if (this->gptr() && (this->gptr() < this->egptr()))\n    return traits_type::to_int_type(*(this->gptr()));\n\n  // If the file hasn't been opened for reading, produce error\n  if (!this->is_open() || !(io_mode & std::ios_base::in))\n    return traits_type::eof();\n\n  // Attempt to fill internal buffer from gzipped file\n  // (buffer must be guaranteed to exist...)\n  int bytes_read = gzread(file, buffer, buffer_size);\n  // Indicates error or EOF\n  if (bytes_read <= 0)\n  {\n    // Reset get area\n    this->setg(buffer, buffer, buffer);\n    return traits_type::eof();\n  }\n  // Make all bytes read from file available as get area\n  this->setg(buffer, buffer, buffer + bytes_read);\n\n  // Return next character in get area\n  return traits_type::to_int_type(*(this->gptr()));\n}\n\n// Write put area to gzipped file\ngzfilebuf::int_type\ngzfilebuf::overflow(int_type c)\n{\n  // Determine whether put area is in use\n  if (this->pbase())\n  {\n    // Double-check pointer range\n    if (this->pptr() > this->epptr() || this->pptr() < this->pbase())\n      return traits_type::eof();\n    // Add extra character to buffer if not EOF\n    if (!traits_type::eq_int_type(c, traits_type::eof()))\n    {\n      *(this->pptr()) = traits_type::to_char_type(c);\n      this->pbump(1);\n    }\n    // Number of characters to write to file\n    int bytes_to_write = this->pptr() - this->pbase();\n    // Overflow doesn't fail if nothing is to be written\n    if (bytes_to_write > 0)\n    {\n      // If the file hasn't been opened for writing, produce error\n      if (!this->is_open() || !(io_mode & std::ios_base::out))\n        return traits_type::eof();\n      // If gzipped file won't accept all bytes written to it, fail\n      if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write)\n        return traits_type::eof();\n      // Reset next pointer to point to pbase on success\n      this->pbump(-bytes_to_write);\n    }\n  }\n  // Write extra character to file if not EOF\n  else if (!traits_type::eq_int_type(c, traits_type::eof()))\n  {\n    // If the file hasn't been opened for writing, produce error\n    if (!this->is_open() || !(io_mode & std::ios_base::out))\n      return traits_type::eof();\n    // Impromptu char buffer (allows \"unbuffered\" output)\n    char_type last_char = traits_type::to_char_type(c);\n    // If gzipped file won't accept this character, fail\n    if (gzwrite(file, &last_char, 1) != 1)\n      return traits_type::eof();\n  }\n\n  // If you got here, you have succeeded (even if c was EOF)\n  // The return value should therefore be non-EOF\n  if (traits_type::eq_int_type(c, traits_type::eof()))\n    return traits_type::not_eof(c);\n  else\n    return c;\n}\n\n// Assign new buffer\nstd::streambuf*\ngzfilebuf::setbuf(char_type* p,\n                  std::streamsize n)\n{\n  // First make sure stuff is sync'ed, for safety\n  if (this->sync() == -1)\n    return NULL;\n  // If buffering is turned off on purpose via setbuf(0,0), still allocate one...\n  // \"Unbuffered\" only really refers to put [27.8.1.4.10], while get needs at\n  // least a buffer of size 1 (very inefficient though, therefore make it bigger?)\n  // This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems)\n  if (!p || !n)\n  {\n    // Replace existing buffer (if any) with small internal buffer\n    this->disable_buffer();\n    buffer = NULL;\n    buffer_size = 0;\n    own_buffer = true;\n    this->enable_buffer();\n  }\n  else\n  {\n    // Replace existing buffer (if any) with external buffer\n    this->disable_buffer();\n    buffer = p;\n    buffer_size = n;\n    own_buffer = false;\n    this->enable_buffer();\n  }\n  return this;\n}\n\n// Write put area to gzipped file (i.e. ensures that put area is empty)\nint\ngzfilebuf::sync()\n{\n  return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0;\n}\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n// Allocate internal buffer\nvoid\ngzfilebuf::enable_buffer()\n{\n  // If internal buffer required, allocate one\n  if (own_buffer && !buffer)\n  {\n    // Check for buffered vs. \"unbuffered\"\n    if (buffer_size > 0)\n    {\n      // Allocate internal buffer\n      buffer = new char_type[buffer_size];\n      // Get area starts empty and will be expanded by underflow as need arises\n      this->setg(buffer, buffer, buffer);\n      // Setup entire internal buffer as put area.\n      // The one-past-end pointer actually points to the last element of the buffer,\n      // so that overflow(c) can safely add the extra character c to the sequence.\n      // These pointers remain in place for the duration of the buffer\n      this->setp(buffer, buffer + buffer_size - 1);\n    }\n    else\n    {\n      // Even in \"unbuffered\" case, (small?) get buffer is still required\n      buffer_size = SMALLBUFSIZE;\n      buffer = new char_type[buffer_size];\n      this->setg(buffer, buffer, buffer);\n      // \"Unbuffered\" means no put buffer\n      this->setp(0, 0);\n    }\n  }\n  else\n  {\n    // If buffer already allocated, reset buffer pointers just to make sure no\n    // stale chars are lying around\n    this->setg(buffer, buffer, buffer);\n    this->setp(buffer, buffer + buffer_size - 1);\n  }\n}\n\n// Destroy internal buffer\nvoid\ngzfilebuf::disable_buffer()\n{\n  // If internal buffer exists, deallocate it\n  if (own_buffer && buffer)\n  {\n    // Preserve unbuffered status by zeroing size\n    if (!this->pbase())\n      buffer_size = 0;\n    delete[] buffer;\n    buffer = NULL;\n    this->setg(0, 0, 0);\n    this->setp(0, 0);\n  }\n  else\n  {\n    // Reset buffer pointers to initial state if external buffer exists\n    this->setg(buffer, buffer, buffer);\n    if (buffer)\n      this->setp(buffer, buffer + buffer_size - 1);\n    else\n      this->setp(0, 0);\n  }\n}\n\n/*****************************************************************************/\n\n// Default constructor initializes stream buffer\ngzifstream::gzifstream()\n: std::istream(NULL), sb()\n{ this->init(&sb); }\n\n// Initialize stream buffer and open file\ngzifstream::gzifstream(const char* name,\n                       std::ios_base::openmode mode)\n: std::istream(NULL), sb()\n{\n  this->init(&sb);\n  this->open(name, mode);\n}\n\n// Initialize stream buffer and attach to file\ngzifstream::gzifstream(int fd,\n                       std::ios_base::openmode mode)\n: std::istream(NULL), sb()\n{\n  this->init(&sb);\n  this->attach(fd, mode);\n}\n\n// Open file and go into fail() state if unsuccessful\nvoid\ngzifstream::open(const char* name,\n                 std::ios_base::openmode mode)\n{\n  if (!sb.open(name, mode | std::ios_base::in))\n    this->setstate(std::ios_base::failbit);\n  else\n    this->clear();\n}\n\n// Attach to file and go into fail() state if unsuccessful\nvoid\ngzifstream::attach(int fd,\n                   std::ios_base::openmode mode)\n{\n  if (!sb.attach(fd, mode | std::ios_base::in))\n    this->setstate(std::ios_base::failbit);\n  else\n    this->clear();\n}\n\n// Close file\nvoid\ngzifstream::close()\n{\n  if (!sb.close())\n    this->setstate(std::ios_base::failbit);\n}\n\n/*****************************************************************************/\n\n// Default constructor initializes stream buffer\ngzofstream::gzofstream()\n: std::ostream(NULL), sb()\n{ this->init(&sb); }\n\n// Initialize stream buffer and open file\ngzofstream::gzofstream(const char* name,\n                       std::ios_base::openmode mode)\n: std::ostream(NULL), sb()\n{\n  this->init(&sb);\n  this->open(name, mode);\n}\n\n// Initialize stream buffer and attach to file\ngzofstream::gzofstream(int fd,\n                       std::ios_base::openmode mode)\n: std::ostream(NULL), sb()\n{\n  this->init(&sb);\n  this->attach(fd, mode);\n}\n\n// Open file and go into fail() state if unsuccessful\nvoid\ngzofstream::open(const char* name,\n                 std::ios_base::openmode mode)\n{\n  if (!sb.open(name, mode | std::ios_base::out))\n    this->setstate(std::ios_base::failbit);\n  else\n    this->clear();\n}\n\n// Attach to file and go into fail() state if unsuccessful\nvoid\ngzofstream::attach(int fd,\n                   std::ios_base::openmode mode)\n{\n  if (!sb.attach(fd, mode | std::ios_base::out))\n    this->setstate(std::ios_base::failbit);\n  else\n    this->clear();\n}\n\n// Close file\nvoid\ngzofstream::close()\n{\n  if (!sb.close())\n    this->setstate(std::ios_base::failbit);\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/iostream3/zfstream.h",
    "content": "/*\n * A C++ I/O streams interface to the zlib gz* functions\n *\n * by Ludwig Schwardt <schwardt@sun.ac.za>\n * original version by Kevin Ruland <kevin@rodin.wustl.edu>\n *\n * This version is standard-compliant and compatible with gcc 3.x.\n */\n\n#ifndef ZFSTREAM_H\n#define ZFSTREAM_H\n\n#include <istream>  // not iostream, since we don't need cin/cout\n#include <ostream>\n#include \"zlib.h\"\n\n/*****************************************************************************/\n\n/**\n *  @brief  Gzipped file stream buffer class.\n *\n *  This class implements basic_filebuf for gzipped files. It doesn't yet support\n *  seeking (allowed by zlib but slow/limited), putback and read/write access\n *  (tricky). Otherwise, it attempts to be a drop-in replacement for the standard\n *  file streambuf.\n*/\nclass gzfilebuf : public std::streambuf\n{\npublic:\n  //  Default constructor.\n  gzfilebuf();\n\n  //  Destructor.\n  virtual\n  ~gzfilebuf();\n\n  /**\n   *  @brief  Set compression level and strategy on the fly.\n   *  @param  comp_level  Compression level (see zlib.h for allowed values)\n   *  @param  comp_strategy  Compression strategy (see zlib.h for allowed values)\n   *  @return  Z_OK on success, Z_STREAM_ERROR otherwise.\n   *\n   *  Unfortunately, these parameters cannot be modified separately, as the\n   *  previous zfstream version assumed. Since the strategy is seldom changed,\n   *  it can default and setcompression(level) then becomes like the old\n   *  setcompressionlevel(level).\n  */\n  int\n  setcompression(int comp_level,\n                 int comp_strategy = Z_DEFAULT_STRATEGY);\n\n  /**\n   *  @brief  Check if file is open.\n   *  @return  True if file is open.\n  */\n  bool\n  is_open() const { return (file != NULL); }\n\n  /**\n   *  @brief  Open gzipped file.\n   *  @param  name  File name.\n   *  @param  mode  Open mode flags.\n   *  @return  @c this on success, NULL on failure.\n  */\n  gzfilebuf*\n  open(const char* name,\n       std::ios_base::openmode mode);\n\n  /**\n   *  @brief  Attach to already open gzipped file.\n   *  @param  fd  File descriptor.\n   *  @param  mode  Open mode flags.\n   *  @return  @c this on success, NULL on failure.\n  */\n  gzfilebuf*\n  attach(int fd,\n         std::ios_base::openmode mode);\n\n  /**\n   *  @brief  Close gzipped file.\n   *  @return  @c this on success, NULL on failure.\n  */\n  gzfilebuf*\n  close();\n\nprotected:\n  /**\n   *  @brief  Convert ios open mode int to mode string used by zlib.\n   *  @return  True if valid mode flag combination.\n  */\n  bool\n  open_mode(std::ios_base::openmode mode,\n            char* c_mode) const;\n\n  /**\n   *  @brief  Number of characters available in stream buffer.\n   *  @return  Number of characters.\n   *\n   *  This indicates number of characters in get area of stream buffer.\n   *  These characters can be read without accessing the gzipped file.\n  */\n  virtual std::streamsize\n  showmanyc();\n\n  /**\n   *  @brief  Fill get area from gzipped file.\n   *  @return  First character in get area on success, EOF on error.\n   *\n   *  This actually reads characters from gzipped file to stream\n   *  buffer. Always buffered.\n  */\n  virtual int_type\n  underflow();\n\n  /**\n   *  @brief  Write put area to gzipped file.\n   *  @param  c  Extra character to add to buffer contents.\n   *  @return  Non-EOF on success, EOF on error.\n   *\n   *  This actually writes characters in stream buffer to\n   *  gzipped file. With unbuffered output this is done one\n   *  character at a time.\n  */\n  virtual int_type\n  overflow(int_type c = traits_type::eof());\n\n  /**\n   *  @brief  Installs external stream buffer.\n   *  @param  p  Pointer to char buffer.\n   *  @param  n  Size of external buffer.\n   *  @return  @c this on success, NULL on failure.\n   *\n   *  Call setbuf(0,0) to enable unbuffered output.\n  */\n  virtual std::streambuf*\n  setbuf(char_type* p,\n         std::streamsize n);\n\n  /**\n   *  @brief  Flush stream buffer to file.\n   *  @return  0 on success, -1 on error.\n   *\n   *  This calls underflow(EOF) to do the job.\n  */\n  virtual int\n  sync();\n\n//\n// Some future enhancements\n//\n//  virtual int_type uflow();\n//  virtual int_type pbackfail(int_type c = traits_type::eof());\n//  virtual pos_type\n//  seekoff(off_type off,\n//          std::ios_base::seekdir way,\n//          std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);\n//  virtual pos_type\n//  seekpos(pos_type sp,\n//          std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);\n\nprivate:\n  /**\n   *  @brief  Allocate internal buffer.\n   *\n   *  This function is safe to call multiple times. It will ensure\n   *  that a proper internal buffer exists if it is required. If the\n   *  buffer already exists or is external, the buffer pointers will be\n   *  reset to their original state.\n  */\n  void\n  enable_buffer();\n\n  /**\n   *  @brief  Destroy internal buffer.\n   *\n   *  This function is safe to call multiple times. It will ensure\n   *  that the internal buffer is deallocated if it exists. In any\n   *  case, it will also reset the buffer pointers.\n  */\n  void\n  disable_buffer();\n\n  /**\n   *  Underlying file pointer.\n  */\n  gzFile file;\n\n  /**\n   *  Mode in which file was opened.\n  */\n  std::ios_base::openmode io_mode;\n\n  /**\n   *  @brief  True if this object owns file descriptor.\n   *\n   *  This makes the class responsible for closing the file\n   *  upon destruction.\n  */\n  bool own_fd;\n\n  /**\n   *  @brief  Stream buffer.\n   *\n   *  For simplicity this remains allocated on the free store for the\n   *  entire life span of the gzfilebuf object, unless replaced by setbuf.\n  */\n  char_type* buffer;\n\n  /**\n   *  @brief  Stream buffer size.\n   *\n   *  Defaults to system default buffer size (typically 8192 bytes).\n   *  Modified by setbuf.\n  */\n  std::streamsize buffer_size;\n\n  /**\n   *  @brief  True if this object owns stream buffer.\n   *\n   *  This makes the class responsible for deleting the buffer\n   *  upon destruction.\n  */\n  bool own_buffer;\n};\n\n/*****************************************************************************/\n\n/**\n *  @brief  Gzipped file input stream class.\n *\n *  This class implements ifstream for gzipped files. Seeking and putback\n *  is not supported yet.\n*/\nclass gzifstream : public std::istream\n{\npublic:\n  //  Default constructor\n  gzifstream();\n\n  /**\n   *  @brief  Construct stream on gzipped file to be opened.\n   *  @param  name  File name.\n   *  @param  mode  Open mode flags (forced to contain ios::in).\n  */\n  explicit\n  gzifstream(const char* name,\n             std::ios_base::openmode mode = std::ios_base::in);\n\n  /**\n   *  @brief  Construct stream on already open gzipped file.\n   *  @param  fd    File descriptor.\n   *  @param  mode  Open mode flags (forced to contain ios::in).\n  */\n  explicit\n  gzifstream(int fd,\n             std::ios_base::openmode mode = std::ios_base::in);\n\n  /**\n   *  Obtain underlying stream buffer.\n  */\n  gzfilebuf*\n  rdbuf() const\n  { return const_cast<gzfilebuf*>(&sb); }\n\n  /**\n   *  @brief  Check if file is open.\n   *  @return  True if file is open.\n  */\n  bool\n  is_open() { return sb.is_open(); }\n\n  /**\n   *  @brief  Open gzipped file.\n   *  @param  name  File name.\n   *  @param  mode  Open mode flags (forced to contain ios::in).\n   *\n   *  Stream will be in state good() if file opens successfully;\n   *  otherwise in state fail(). This differs from the behavior of\n   *  ifstream, which never sets the state to good() and therefore\n   *  won't allow you to reuse the stream for a second file unless\n   *  you manually clear() the state. The choice is a matter of\n   *  convenience.\n  */\n  void\n  open(const char* name,\n       std::ios_base::openmode mode = std::ios_base::in);\n\n  /**\n   *  @brief  Attach to already open gzipped file.\n   *  @param  fd  File descriptor.\n   *  @param  mode  Open mode flags (forced to contain ios::in).\n   *\n   *  Stream will be in state good() if attach succeeded; otherwise\n   *  in state fail().\n  */\n  void\n  attach(int fd,\n         std::ios_base::openmode mode = std::ios_base::in);\n\n  /**\n   *  @brief  Close gzipped file.\n   *\n   *  Stream will be in state fail() if close failed.\n  */\n  void\n  close();\n\nprivate:\n  /**\n   *  Underlying stream buffer.\n  */\n  gzfilebuf sb;\n};\n\n/*****************************************************************************/\n\n/**\n *  @brief  Gzipped file output stream class.\n *\n *  This class implements ofstream for gzipped files. Seeking and putback\n *  is not supported yet.\n*/\nclass gzofstream : public std::ostream\n{\npublic:\n  //  Default constructor\n  gzofstream();\n\n  /**\n   *  @brief  Construct stream on gzipped file to be opened.\n   *  @param  name  File name.\n   *  @param  mode  Open mode flags (forced to contain ios::out).\n  */\n  explicit\n  gzofstream(const char* name,\n             std::ios_base::openmode mode = std::ios_base::out);\n\n  /**\n   *  @brief  Construct stream on already open gzipped file.\n   *  @param  fd    File descriptor.\n   *  @param  mode  Open mode flags (forced to contain ios::out).\n  */\n  explicit\n  gzofstream(int fd,\n             std::ios_base::openmode mode = std::ios_base::out);\n\n  /**\n   *  Obtain underlying stream buffer.\n  */\n  gzfilebuf*\n  rdbuf() const\n  { return const_cast<gzfilebuf*>(&sb); }\n\n  /**\n   *  @brief  Check if file is open.\n   *  @return  True if file is open.\n  */\n  bool\n  is_open() { return sb.is_open(); }\n\n  /**\n   *  @brief  Open gzipped file.\n   *  @param  name  File name.\n   *  @param  mode  Open mode flags (forced to contain ios::out).\n   *\n   *  Stream will be in state good() if file opens successfully;\n   *  otherwise in state fail(). This differs from the behavior of\n   *  ofstream, which never sets the state to good() and therefore\n   *  won't allow you to reuse the stream for a second file unless\n   *  you manually clear() the state. The choice is a matter of\n   *  convenience.\n  */\n  void\n  open(const char* name,\n       std::ios_base::openmode mode = std::ios_base::out);\n\n  /**\n   *  @brief  Attach to already open gzipped file.\n   *  @param  fd  File descriptor.\n   *  @param  mode  Open mode flags (forced to contain ios::out).\n   *\n   *  Stream will be in state good() if attach succeeded; otherwise\n   *  in state fail().\n  */\n  void\n  attach(int fd,\n         std::ios_base::openmode mode = std::ios_base::out);\n\n  /**\n   *  @brief  Close gzipped file.\n   *\n   *  Stream will be in state fail() if close failed.\n  */\n  void\n  close();\n\nprivate:\n  /**\n   *  Underlying stream buffer.\n  */\n  gzfilebuf sb;\n};\n\n/*****************************************************************************/\n\n/**\n *  @brief  Gzipped file output stream manipulator class.\n *\n *  This class defines a two-argument manipulator for gzofstream. It is used\n *  as base for the setcompression(int,int) manipulator.\n*/\ntemplate<typename T1, typename T2>\n  class gzomanip2\n  {\n  public:\n    // Allows insertor to peek at internals\n    template <typename Ta, typename Tb>\n      friend gzofstream&\n      operator<<(gzofstream&,\n                 const gzomanip2<Ta,Tb>&);\n\n    // Constructor\n    gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),\n              T1 v1,\n              T2 v2);\n  private:\n    // Underlying manipulator function\n    gzofstream&\n    (*func)(gzofstream&, T1, T2);\n\n    // Arguments for manipulator function\n    T1 val1;\n    T2 val2;\n  };\n\n/*****************************************************************************/\n\n// Manipulator function thunks through to stream buffer\ninline gzofstream&\nsetcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)\n{\n  (gzs.rdbuf())->setcompression(l, s);\n  return gzs;\n}\n\n// Manipulator constructor stores arguments\ntemplate<typename T1, typename T2>\n  inline\n  gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),\n                              T1 v1,\n                              T2 v2)\n  : func(f), val1(v1), val2(v2)\n  { }\n\n// Insertor applies underlying manipulator function to stream\ntemplate<typename T1, typename T2>\n  inline gzofstream&\n  operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)\n  { return (*m.func)(s, m.val1, m.val2); }\n\n// Insert this onto stream to simplify setting of compression level\ninline gzomanip2<int,int>\nsetcompression(int l, int s = Z_DEFAULT_STRATEGY)\n{ return gzomanip2<int,int>(&setcompression, l, s); }\n\n#endif // ZFSTREAM_H\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/masmx64/bld_ml64.bat",
    "content": "ml64.exe /Flinffasx64 /c /Zi inffasx64.asm\nml64.exe /Flgvmat64   /c /Zi gvmat64.asm\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/masmx64/gvmat64.asm",
    "content": ";uInt longest_match_x64(\n;    deflate_state *s,\n;    IPos cur_match);                             /* current match */\n\n; gvmat64.asm -- Asm portion of the optimized longest_match for 32 bits x86_64\n;  (AMD64 on Athlon 64, Opteron, Phenom\n;     and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7)\n; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.\n;\n; File written by Gilles Vollant, by converting to assembly the longest_match\n;  from Jean-loup Gailly in deflate.c of zLib and infoZip zip.\n;\n;  and by taking inspiration on asm686 with masm, optimised assembly code\n;        from Brian Raiter, written 1998\n;\n;  This software is provided 'as-is', without any express or implied\n;  warranty.  In no event will the authors be held liable for any damages\n;  arising from the use of this software.\n;\n;  Permission is granted to anyone to use this software for any purpose,\n;  including commercial applications, and to alter it and redistribute it\n;  freely, subject to the following restrictions:\n;\n;  1. The origin of this software must not be misrepresented; you must not\n;     claim that you wrote the original software. If you use this software\n;     in a product, an acknowledgment in the product documentation would be\n;     appreciated but is not required.\n;  2. Altered source versions must be plainly marked as such, and must not be\n;     misrepresented as being the original software\n;  3. This notice may not be removed or altered from any source distribution.\n;\n;\n;\n;         http://www.zlib.net\n;         http://www.winimage.com/zLibDll\n;         http://www.muppetlabs.com/~breadbox/software/assembly.html\n;\n; to compile this file for infozip Zip, I use option:\n;   ml64.exe /Flgvmat64 /c /Zi /DINFOZIP gvmat64.asm\n;\n; to compile this file for zLib, I use option:\n;   ml64.exe /Flgvmat64 /c /Zi gvmat64.asm\n; Be carrefull to adapt zlib1222add below to your version of zLib\n;   (if you use a version of zLib before 1.0.4 or after 1.2.2.2, change\n;    value of zlib1222add later)\n;\n; This file compile with Microsoft Macro Assembler (x64) for AMD64\n;\n;   ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK\n;\n;   (you can get Windows WDK with ml64 for AMD64 from\n;      http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price)\n;\n\n\n;uInt longest_match(s, cur_match)\n;    deflate_state *s;\n;    IPos cur_match;                             /* current match */\n.code\nlongest_match PROC\n\n\n;LocalVarsSize   equ 88\n LocalVarsSize   equ 72\n\n; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12\n; free register :  r14,r15\n; register can be saved : rsp\n\n chainlenwmask   equ  rsp + 8 - LocalVarsSize    ; high word: current chain len\n                                                 ; low word: s->wmask\n;window          equ  rsp + xx - LocalVarsSize   ; local copy of s->window ; stored in r10\n;windowbestlen   equ  rsp + xx - LocalVarsSize   ; s->window + bestlen , use r10+r11\n;scanstart       equ  rsp + xx - LocalVarsSize   ; first two bytes of string ; stored in r12w\n;scanend         equ  rsp + xx - LocalVarsSize   ; last two bytes of string use ebx\n;scanalign       equ  rsp + xx - LocalVarsSize   ; dword-misalignment of string r13\n;bestlen         equ  rsp + xx - LocalVarsSize   ; size of best match so far -> r11d\n;scan            equ  rsp + xx - LocalVarsSize   ; ptr to string wanting match -> r9\nIFDEF INFOZIP\nELSE\n nicematch       equ  (rsp + 16 - LocalVarsSize) ; a good enough match size\nENDIF\n\nsave_rdi        equ  rsp + 24 - LocalVarsSize\nsave_rsi        equ  rsp + 32 - LocalVarsSize\nsave_rbx        equ  rsp + 40 - LocalVarsSize\nsave_rbp        equ  rsp + 48 - LocalVarsSize\nsave_r12        equ  rsp + 56 - LocalVarsSize\nsave_r13        equ  rsp + 64 - LocalVarsSize\n;save_r14        equ  rsp + 72 - LocalVarsSize\n;save_r15        equ  rsp + 80 - LocalVarsSize\n\n\n; summary of register usage\n; scanend     ebx\n; scanendw    bx\n; chainlenwmask   edx\n; curmatch    rsi\n; curmatchd   esi\n; windowbestlen   r8\n; scanalign   r9\n; scanalignd  r9d\n; window      r10\n; bestlen     r11\n; bestlend    r11d\n; scanstart   r12d\n; scanstartw  r12w\n; scan        r13\n; nicematch   r14d\n; limit       r15\n; limitd      r15d\n; prev        rcx\n\n;  all the +4 offsets are due to the addition of pending_buf_size (in zlib\n;  in the deflate_state structure since the asm code was first written\n;  (if you compile with zlib 1.0.4 or older, remove the +4).\n;  Note : these value are good with a 8 bytes boundary pack structure\n\n\n    MAX_MATCH           equ     258\n    MIN_MATCH           equ     3\n    MIN_LOOKAHEAD       equ     (MAX_MATCH+MIN_MATCH+1)\n\n\n;;; Offsets for fields in the deflate_state structure. These numbers\n;;; are calculated from the definition of deflate_state, with the\n;;; assumption that the compiler will dword-align the fields. (Thus,\n;;; changing the definition of deflate_state could easily cause this\n;;; program to crash horribly, without so much as a warning at\n;;; compile time. Sigh.)\n\n;  all the +zlib1222add offsets are due to the addition of fields\n;  in zlib in the deflate_state structure since the asm code was first written\n;  (if you compile with zlib 1.0.4 or older, use \"zlib1222add equ (-4)\").\n;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use \"zlib1222add equ 0\").\n;  if you compile with zlib 1.2.2.2 or later , use \"zlib1222add equ 8\").\n\n\nIFDEF INFOZIP\n\n_DATA   SEGMENT\nCOMM    window_size:DWORD\n; WMask ; 7fff\nCOMM    window:BYTE:010040H\nCOMM    prev:WORD:08000H\n; MatchLen : unused\n; PrevMatch : unused\nCOMM    strstart:DWORD\nCOMM    match_start:DWORD\n; Lookahead : ignore\nCOMM    prev_length:DWORD ; PrevLen\nCOMM    max_chain_length:DWORD\nCOMM    good_match:DWORD\nCOMM    nice_match:DWORD\nprev_ad equ OFFSET prev\nwindow_ad equ OFFSET window\nnicematch equ nice_match\n_DATA ENDS\nWMask equ 07fffh\n\nELSE\n\n  IFNDEF zlib1222add\n    zlib1222add equ 8\n  ENDIF\ndsWSize         equ 56+zlib1222add+(zlib1222add/2)\ndsWMask         equ 64+zlib1222add+(zlib1222add/2)\ndsWindow        equ 72+zlib1222add\ndsPrev          equ 88+zlib1222add\ndsMatchLen      equ 128+zlib1222add\ndsPrevMatch     equ 132+zlib1222add\ndsStrStart      equ 140+zlib1222add\ndsMatchStart    equ 144+zlib1222add\ndsLookahead     equ 148+zlib1222add\ndsPrevLen       equ 152+zlib1222add\ndsMaxChainLen   equ 156+zlib1222add\ndsGoodMatch     equ 172+zlib1222add\ndsNiceMatch     equ 176+zlib1222add\n\nwindow_size     equ [ rcx + dsWSize]\nWMask           equ [ rcx + dsWMask]\nwindow_ad       equ [ rcx + dsWindow]\nprev_ad         equ [ rcx + dsPrev]\nstrstart        equ [ rcx + dsStrStart]\nmatch_start     equ [ rcx + dsMatchStart]\nLookahead       equ [ rcx + dsLookahead] ; 0ffffffffh on infozip\nprev_length     equ [ rcx + dsPrevLen]\nmax_chain_length equ [ rcx + dsMaxChainLen]\ngood_match      equ [ rcx + dsGoodMatch]\nnice_match      equ [ rcx + dsNiceMatch]\nENDIF\n\n; parameter 1 in r8(deflate state s), param 2 in rdx (cur match)\n\n; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and\n; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp\n;\n; All registers must be preserved across the call, except for\n;   rax, rcx, rdx, r8, r9, r10, and r11, which are scratch.\n\n\n\n;;; Save registers that the compiler may be using, and adjust esp to\n;;; make room for our stack frame.\n\n\n;;; Retrieve the function arguments. r8d will hold cur_match\n;;; throughout the entire function. edx will hold the pointer to the\n;;; deflate_state structure during the function's setup (before\n;;; entering the main loop.\n\n; parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)\n\n; this clear high 32 bits of r8, which can be garbage in both r8 and rdx\n\n        mov [save_rdi],rdi\n        mov [save_rsi],rsi\n        mov [save_rbx],rbx\n        mov [save_rbp],rbp\nIFDEF INFOZIP\n        mov r8d,ecx\nELSE\n        mov r8d,edx\nENDIF\n        mov [save_r12],r12\n        mov [save_r13],r13\n;        mov [save_r14],r14\n;        mov [save_r15],r15\n\n\n;;; uInt wmask = s->w_mask;\n;;; unsigned chain_length = s->max_chain_length;\n;;; if (s->prev_length >= s->good_match) {\n;;;     chain_length >>= 2;\n;;; }\n\n        mov edi, prev_length\n        mov esi, good_match\n        mov eax, WMask\n        mov ebx, max_chain_length\n        cmp edi, esi\n        jl  LastMatchGood\n        shr ebx, 2\nLastMatchGood:\n\n;;; chainlen is decremented once beforehand so that the function can\n;;; use the sign flag instead of the zero flag for the exit test.\n;;; It is then shifted into the high word, to make room for the wmask\n;;; value, which it will always accompany.\n\n        dec ebx\n        shl ebx, 16\n        or  ebx, eax\n\n;;; on zlib only\n;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;\n\nIFDEF INFOZIP\n        mov [chainlenwmask], ebx\n; on infozip nice_match = [nice_match]\nELSE\n        mov eax, nice_match\n        mov [chainlenwmask], ebx\n        mov r10d, Lookahead\n        cmp r10d, eax\n        cmovnl r10d, eax\n        mov [nicematch],r10d\nENDIF\n\n;;; register Bytef *scan = s->window + s->strstart;\n        mov r10, window_ad\n        mov ebp, strstart\n        lea r13, [r10 + rbp]\n\n;;; Determine how many bytes the scan ptr is off from being\n;;; dword-aligned.\n\n         mov r9,r13\n         neg r13\n         and r13,3\n\n;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?\n;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;\nIFDEF INFOZIP\n        mov eax,07efah ; MAX_DIST = (WSIZE-MIN_LOOKAHEAD) (0x8000-(3+8+1))\nELSE\n        mov eax, window_size\n        sub eax, MIN_LOOKAHEAD\nENDIF\n        xor edi,edi\n        sub ebp, eax\n\n        mov r11d, prev_length\n\n        cmovng ebp,edi\n\n;;; int best_len = s->prev_length;\n\n\n;;; Store the sum of s->window + best_len in esi locally, and in esi.\n\n       lea  rsi,[r10+r11]\n\n;;; register ush scan_start = *(ushf*)scan;\n;;; register ush scan_end   = *(ushf*)(scan+best_len-1);\n;;; Posf *prev = s->prev;\n\n        movzx r12d,word ptr [r9]\n        movzx ebx, word ptr [r9 + r11 - 1]\n\n        mov rdi, prev_ad\n\n;;; Jump into the main loop.\n\n        mov edx, [chainlenwmask]\n\n        cmp bx,word ptr [rsi + r8 - 1]\n        jz  LookupLoopIsZero\n\nLookupLoop1:\n        and r8d, edx\n\n        movzx   r8d, word ptr [rdi + r8*2]\n        cmp r8d, ebp\n        jbe LeaveNow\n        sub edx, 00010000h\n        js  LeaveNow\n\nLoopEntry1:\n        cmp bx,word ptr [rsi + r8 - 1]\n        jz  LookupLoopIsZero\n\nLookupLoop2:\n        and r8d, edx\n\n        movzx   r8d, word ptr [rdi + r8*2]\n        cmp r8d, ebp\n        jbe LeaveNow\n        sub edx, 00010000h\n        js  LeaveNow\n\nLoopEntry2:\n        cmp bx,word ptr [rsi + r8 - 1]\n        jz  LookupLoopIsZero\n\nLookupLoop4:\n        and r8d, edx\n\n        movzx   r8d, word ptr [rdi + r8*2]\n        cmp r8d, ebp\n        jbe LeaveNow\n        sub edx, 00010000h\n        js  LeaveNow\n\nLoopEntry4:\n\n        cmp bx,word ptr [rsi + r8 - 1]\n        jnz LookupLoop1\n        jmp LookupLoopIsZero\n\n\n;;; do {\n;;;     match = s->window + cur_match;\n;;;     if (*(ushf*)(match+best_len-1) != scan_end ||\n;;;         *(ushf*)match != scan_start) continue;\n;;;     [...]\n;;; } while ((cur_match = prev[cur_match & wmask]) > limit\n;;;          && --chain_length != 0);\n;;;\n;;; Here is the inner loop of the function. The function will spend the\n;;; majority of its time in this loop, and majority of that time will\n;;; be spent in the first ten instructions.\n;;;\n;;; Within this loop:\n;;; ebx = scanend\n;;; r8d = curmatch\n;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)\n;;; esi = windowbestlen - i.e., (window + bestlen)\n;;; edi = prev\n;;; ebp = limit\n\nLookupLoop:\n        and r8d, edx\n\n        movzx   r8d, word ptr [rdi + r8*2]\n        cmp r8d, ebp\n        jbe LeaveNow\n        sub edx, 00010000h\n        js  LeaveNow\n\nLoopEntry:\n\n        cmp bx,word ptr [rsi + r8 - 1]\n        jnz LookupLoop1\nLookupLoopIsZero:\n        cmp     r12w, word ptr [r10 + r8]\n        jnz LookupLoop1\n\n\n;;; Store the current value of chainlen.\n        mov [chainlenwmask], edx\n\n;;; Point edi to the string under scrutiny, and esi to the string we\n;;; are hoping to match it up with. In actuality, esi and edi are\n;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is\n;;; initialized to -(MAX_MATCH_8 - scanalign).\n\n        lea rsi,[r8+r10]\n        mov rdx, 0fffffffffffffef8h; -(MAX_MATCH_8)\n        lea rsi, [rsi + r13 + 0108h] ;MAX_MATCH_8]\n        lea rdi, [r9 + r13 + 0108h] ;MAX_MATCH_8]\n\n        prefetcht1 [rsi+rdx]\n        prefetcht1 [rdi+rdx]\n\n\n;;; Test the strings for equality, 8 bytes at a time. At the end,\n;;; adjust rdx so that it is offset to the exact byte that mismatched.\n;;;\n;;; We already know at this point that the first three bytes of the\n;;; strings match each other, and they can be safely passed over before\n;;; starting the compare loop. So what this code does is skip over 0-3\n;;; bytes, as much as necessary in order to dword-align the edi\n;;; pointer. (rsi will still be misaligned three times out of four.)\n;;;\n;;; It should be confessed that this loop usually does not represent\n;;; much of the total running time. Replacing it with a more\n;;; straightforward \"rep cmpsb\" would not drastically degrade\n;;; performance.\n\n\nLoopCmps:\n        mov rax, [rsi + rdx]\n        xor rax, [rdi + rdx]\n        jnz LeaveLoopCmps\n\n        mov rax, [rsi + rdx + 8]\n        xor rax, [rdi + rdx + 8]\n        jnz LeaveLoopCmps8\n\n\n        mov rax, [rsi + rdx + 8+8]\n        xor rax, [rdi + rdx + 8+8]\n        jnz LeaveLoopCmps16\n\n        add rdx,8+8+8\n\n        jnz short LoopCmps\n        jmp short LenMaximum\nLeaveLoopCmps16: add rdx,8\nLeaveLoopCmps8: add rdx,8\nLeaveLoopCmps:\n\n        test    eax, 0000FFFFh\n        jnz LenLower\n\n        test eax,0ffffffffh\n\n        jnz LenLower32\n\n        add rdx,4\n        shr rax,32\n        or ax,ax\n        jnz LenLower\n\nLenLower32:\n        shr eax,16\n        add rdx,2\nLenLower:   sub al, 1\n        adc rdx, 0\n;;; Calculate the length of the match. If it is longer than MAX_MATCH,\n;;; then automatically accept it as the best possible match and leave.\n\n        lea rax, [rdi + rdx]\n        sub rax, r9\n        cmp eax, MAX_MATCH\n        jge LenMaximum\n\n;;; If the length of the match is not longer than the best match we\n;;; have so far, then forget it and return to the lookup loop.\n;///////////////////////////////////\n\n        cmp eax, r11d\n        jg  LongerMatch\n\n        lea rsi,[r10+r11]\n\n        mov rdi, prev_ad\n        mov edx, [chainlenwmask]\n        jmp LookupLoop\n\n;;;         s->match_start = cur_match;\n;;;         best_len = len;\n;;;         if (len >= nice_match) break;\n;;;         scan_end = *(ushf*)(scan+best_len-1);\n\nLongerMatch:\n        mov r11d, eax\n        mov match_start, r8d\n        cmp eax, [nicematch]\n        jge LeaveNow\n\n        lea rsi,[r10+rax]\n\n        movzx   ebx, word ptr [r9 + rax - 1]\n        mov rdi, prev_ad\n        mov edx, [chainlenwmask]\n        jmp LookupLoop\n\n;;; Accept the current string, with the maximum possible length.\n\nLenMaximum:\n        mov r11d,MAX_MATCH\n        mov match_start, r8d\n\n;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;\n;;; return s->lookahead;\n\nLeaveNow:\nIFDEF INFOZIP\n        mov eax,r11d\nELSE\n        mov eax, Lookahead\n        cmp r11d, eax\n        cmovng eax, r11d\nENDIF\n\n;;; Restore the stack and return from whence we came.\n\n\n        mov rsi,[save_rsi]\n        mov rdi,[save_rdi]\n        mov rbx,[save_rbx]\n        mov rbp,[save_rbp]\n        mov r12,[save_r12]\n        mov r13,[save_r13]\n;        mov r14,[save_r14]\n;        mov r15,[save_r15]\n\n\n        ret 0\n; please don't remove this string !\n; Your can freely use gvmat64 in any free or commercial app\n; but it is far better don't remove the string in the binary!\n    db     0dh,0ah,\"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005\",0dh,0ah,0\nlongest_match   ENDP\n\nmatch_init PROC\n  ret 0\nmatch_init ENDP\n\n\nEND\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/masmx64/inffas8664.c",
    "content": "/* inffas8664.c is a hand tuned assembler version of inffast.c - fast decoding\n * version for AMD64 on Windows using Microsoft C compiler\n *\n * Copyright (C) 1995-2003 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n *\n * Copyright (C) 2003 Chris Anderson <christop@charm.net>\n * Please use the copyright conditions above.\n *\n * 2005 - Adaptation to Microsoft C Compiler for AMD64 by Gilles Vollant\n *\n * inffas8664.c call function inffas8664fnc in inffasx64.asm\n *  inffasx64.asm is automatically convert from AMD64 portion of inffas86.c\n *\n * Dec-29-2003 -- I added AMD64 inflate asm support.  This version is also\n * slightly quicker on x86 systems because, instead of using rep movsb to copy\n * data, it uses rep movsw, which moves data in 2-byte chunks instead of single\n * bytes.  I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates\n * from http://fedora.linux.duke.edu/fc1_x86_64\n * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with\n * 1GB ram.  The 64-bit version is about 4% faster than the 32-bit version,\n * when decompressing mozilla-source-1.3.tar.gz.\n *\n * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from\n * the gcc -S output of zlib-1.2.0/inffast.c.  Zlib-1.2.0 is in beta release at\n * the moment.  I have successfully compiled and tested this code with gcc2.96,\n * gcc3.2, icc5.0, msvc6.0.  It is very close to the speed of inffast.S\n * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX\n * enabled.  I will attempt to merge the MMX code into this version.  Newer\n * versions of this and inffast.S can be found at\n * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/\n *\n */\n\n#include <stdio.h>\n#include \"zutil.h\"\n#include \"inftrees.h\"\n#include \"inflate.h\"\n#include \"inffast.h\"\n\n/* Mark Adler's comments from inffast.c: */\n\n/*\n   Decode literal, length, and distance codes and write out the resulting\n   literal and match bytes until either not enough input or output is\n   available, an end-of-block is encountered, or a data error is encountered.\n   When large enough input and output buffers are supplied to inflate(), for\n   example, a 16K input buffer and a 64K output buffer, more than 95% of the\n   inflate execution time is spent in this routine.\n\n   Entry assumptions:\n\n        state->mode == LEN\n        strm->avail_in >= 6\n        strm->avail_out >= 258\n        start >= strm->avail_out\n        state->bits < 8\n\n   On return, state->mode is one of:\n\n        LEN -- ran out of enough output space or enough available input\n        TYPE -- reached end of block code, inflate() to interpret next block\n        BAD -- error in block data\n\n   Notes:\n\n    - The maximum input bits used by a length/distance pair is 15 bits for the\n      length code, 5 bits for the length extra, 15 bits for the distance code,\n      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.\n      Therefore if strm->avail_in >= 6, then there is enough input to avoid\n      checking for available input while decoding.\n\n    - The maximum bytes that a single length/distance pair can output is 258\n      bytes, which is the maximum length that can be coded.  inflate_fast()\n      requires strm->avail_out >= 258 for each loop to avoid checking for\n      output space.\n */\n\n\n\n    typedef struct inffast_ar {\n/* 64   32                               x86  x86_64 */\n/* ar offset                              register */\n/*  0    0 */ void *esp;                /* esp save */\n/*  8    4 */ void *ebp;                /* ebp save */\n/* 16    8 */ unsigned char FAR *in;    /* esi rsi  local strm->next_in */\n/* 24   12 */ unsigned char FAR *last;  /*     r9   while in < last */\n/* 32   16 */ unsigned char FAR *out;   /* edi rdi  local strm->next_out */\n/* 40   20 */ unsigned char FAR *beg;   /*          inflate()'s init next_out */\n/* 48   24 */ unsigned char FAR *end;   /*     r10  while out < end */\n/* 56   28 */ unsigned char FAR *window;/*          size of window, wsize!=0 */\n/* 64   32 */ code const FAR *lcode;    /* ebp rbp  local strm->lencode */\n/* 72   36 */ code const FAR *dcode;    /*     r11  local strm->distcode */\n/* 80   40 */ size_t /*unsigned long */hold;       /* edx rdx  local strm->hold */\n/* 88   44 */ unsigned bits;            /* ebx rbx  local strm->bits */\n/* 92   48 */ unsigned wsize;           /*          window size */\n/* 96   52 */ unsigned write;           /*          window write index */\n/*100   56 */ unsigned lmask;           /*     r12  mask for lcode */\n/*104   60 */ unsigned dmask;           /*     r13  mask for dcode */\n/*108   64 */ unsigned len;             /*     r14  match length */\n/*112   68 */ unsigned dist;            /*     r15  match distance */\n/*116   72 */ unsigned status;          /*          set when state chng*/\n    } type_ar;\n#ifdef ASMINF\n\nvoid inflate_fast(strm, start)\nz_streamp strm;\nunsigned start;         /* inflate()'s starting value for strm->avail_out */\n{\n    struct inflate_state FAR *state;\n    type_ar ar;\n    void inffas8664fnc(struct inffast_ar * par);\n\n\n\n#if (defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )) || (defined(_MSC_VER) && defined(_M_AMD64))\n#define PAD_AVAIL_IN 6\n#define PAD_AVAIL_OUT 258\n#else\n#define PAD_AVAIL_IN 5\n#define PAD_AVAIL_OUT 257\n#endif\n\n    /* copy state to local variables */\n    state = (struct inflate_state FAR *)strm->state;\n\n    ar.in = strm->next_in;\n    ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);\n    ar.out = strm->next_out;\n    ar.beg = ar.out - (start - strm->avail_out);\n    ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);\n    ar.wsize = state->wsize;\n    ar.write = state->wnext;\n    ar.window = state->window;\n    ar.hold = state->hold;\n    ar.bits = state->bits;\n    ar.lcode = state->lencode;\n    ar.dcode = state->distcode;\n    ar.lmask = (1U << state->lenbits) - 1;\n    ar.dmask = (1U << state->distbits) - 1;\n\n    /* decode literals and length/distances until end-of-block or not enough\n       input data or output space */\n\n    /* align in on 1/2 hold size boundary */\n    while (((size_t)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {\n        ar.hold += (unsigned long)*ar.in++ << ar.bits;\n        ar.bits += 8;\n    }\n\n    inffas8664fnc(&ar);\n\n    if (ar.status > 1) {\n        if (ar.status == 2)\n            strm->msg = \"invalid literal/length code\";\n        else if (ar.status == 3)\n            strm->msg = \"invalid distance code\";\n        else\n            strm->msg = \"invalid distance too far back\";\n        state->mode = BAD;\n    }\n    else if ( ar.status == 1 ) {\n        state->mode = TYPE;\n    }\n\n    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */\n    ar.len = ar.bits >> 3;\n    ar.in -= ar.len;\n    ar.bits -= ar.len << 3;\n    ar.hold &= (1U << ar.bits) - 1;\n\n    /* update state and return */\n    strm->next_in = ar.in;\n    strm->next_out = ar.out;\n    strm->avail_in = (unsigned)(ar.in < ar.last ?\n                                PAD_AVAIL_IN + (ar.last - ar.in) :\n                                PAD_AVAIL_IN - (ar.in - ar.last));\n    strm->avail_out = (unsigned)(ar.out < ar.end ?\n                                 PAD_AVAIL_OUT + (ar.end - ar.out) :\n                                 PAD_AVAIL_OUT - (ar.out - ar.end));\n    state->hold = (unsigned long)ar.hold;\n    state->bits = ar.bits;\n    return;\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/masmx64/inffasx64.asm",
    "content": "; inffasx64.asm is a hand tuned assembler version of inffast.c - fast decoding\n; version for AMD64 on Windows using Microsoft C compiler\n;\n; inffasx64.asm is automatically convert from AMD64 portion of inffas86.c\n; inffasx64.asm is called by inffas8664.c, which contain more info.\n\n\n; to compile this file, I use option\n;   ml64.exe /Flinffasx64 /c /Zi inffasx64.asm\n;   with Microsoft Macro Assembler (x64) for AMD64\n;\n\n; This file compile with Microsoft Macro Assembler (x64) for AMD64\n;\n;   ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK\n;\n;   (you can get Windows WDK with ml64 for AMD64 from\n;      http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price)\n;\n\n\n.code\ninffas8664fnc PROC\n\n; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and\n; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp\n;\n; All registers must be preserved across the call, except for\n;   rax, rcx, rdx, r8, r-9, r10, and r11, which are scratch.\n\n\n\tmov [rsp-8],rsi\n\tmov [rsp-16],rdi\n\tmov [rsp-24],r12\n\tmov [rsp-32],r13\n\tmov [rsp-40],r14\n\tmov [rsp-48],r15\n\tmov [rsp-56],rbx\n\n\tmov rax,rcx\n\n\tmov\t[rax+8], rbp       ; /* save regs rbp and rsp */\n\tmov\t[rax], rsp\n\n\tmov\trsp, rax          ; /* make rsp point to &ar */\n\n\tmov\trsi, [rsp+16]      ; /* rsi  = in */\n\tmov\trdi, [rsp+32]      ; /* rdi  = out */\n\tmov\tr9, [rsp+24]       ; /* r9   = last */\n\tmov\tr10, [rsp+48]      ; /* r10  = end */\n\tmov\trbp, [rsp+64]      ; /* rbp  = lcode */\n\tmov\tr11, [rsp+72]      ; /* r11  = dcode */\n\tmov\trdx, [rsp+80]      ; /* rdx  = hold */\n\tmov\tebx, [rsp+88]      ; /* ebx  = bits */\n\tmov\tr12d, [rsp+100]    ; /* r12d = lmask */\n\tmov\tr13d, [rsp+104]    ; /* r13d = dmask */\n                                          ; /* r14d = len */\n                                          ; /* r15d = dist */\n\n\n\tcld\n\tcmp\tr10, rdi\n\tje\tL_one_time           ; /* if only one decode left */\n\tcmp\tr9, rsi\n\n    jne L_do_loop\n\n\nL_one_time:\n\tmov\tr8, r12           ; /* r8 = lmask */\n\tcmp\tbl, 32\n\tja\tL_get_length_code_one_time\n\n\tlodsd                         ; /* eax = *(uint *)in++ */\n\tmov\tcl, bl            ; /* cl = bits, needs it for shifting */\n\tadd\tbl, 32             ; /* bits += 32 */\n\tshl\trax, cl\n\tor\trdx, rax          ; /* hold |= *((uint *)in)++ << bits */\n\tjmp\tL_get_length_code_one_time\n\nALIGN 4\nL_while_test:\n\tcmp\tr10, rdi\n\tjbe\tL_break_loop\n\tcmp\tr9, rsi\n\tjbe\tL_break_loop\n\nL_do_loop:\n\tmov\tr8, r12           ; /* r8 = lmask */\n\tcmp\tbl, 32\n\tja\tL_get_length_code    ; /* if (32 < bits) */\n\n\tlodsd                         ; /* eax = *(uint *)in++ */\n\tmov\tcl, bl            ; /* cl = bits, needs it for shifting */\n\tadd\tbl, 32             ; /* bits += 32 */\n\tshl\trax, cl\n\tor\trdx, rax          ; /* hold |= *((uint *)in)++ << bits */\n\nL_get_length_code:\n\tand\tr8, rdx            ; /* r8 &= hold */\n\tmov\teax, [rbp+r8*4]  ; /* eax = lcode[hold & lmask] */\n\n\tmov\tcl, ah            ; /* cl = this.bits */\n\tsub\tbl, ah            ; /* bits -= this.bits */\n\tshr\trdx, cl           ; /* hold >>= this.bits */\n\n\ttest\tal, al\n\tjnz\tL_test_for_length_base ; /* if (op != 0) 45.7% */\n\n\tmov\tr8, r12            ; /* r8 = lmask */\n\tshr\teax, 16            ; /* output this.val char */\n\tstosb\n\nL_get_length_code_one_time:\n\tand\tr8, rdx            ; /* r8 &= hold */\n\tmov\teax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */\n\nL_dolen:\n\tmov\tcl, ah            ; /* cl = this.bits */\n\tsub\tbl, ah            ; /* bits -= this.bits */\n\tshr\trdx, cl           ; /* hold >>= this.bits */\n\n\ttest\tal, al\n\tjnz\tL_test_for_length_base ; /* if (op != 0) 45.7% */\n\n\tshr\teax, 16            ; /* output this.val char */\n\tstosb\n\tjmp\tL_while_test\n\nALIGN 4\nL_test_for_length_base:\n\tmov\tr14d, eax         ; /* len = this */\n\tshr\tr14d, 16           ; /* len = this.val */\n\tmov\tcl, al\n\n\ttest\tal, 16\n\tjz\tL_test_for_second_level_length ; /* if ((op & 16) == 0) 8% */\n\tand\tcl, 15             ; /* op &= 15 */\n\tjz\tL_decode_distance    ; /* if (!op) */\n\nL_add_bits_to_len:\n\tsub\tbl, cl\n\txor\teax, eax\n\tinc\teax\n\tshl\teax, cl\n\tdec\teax\n\tand\teax, edx          ; /* eax &= hold */\n\tshr\trdx, cl\n\tadd\tr14d, eax         ; /* len += hold & mask[op] */\n\nL_decode_distance:\n\tmov\tr8, r13           ; /* r8 = dmask */\n\tcmp\tbl, 32\n\tja\tL_get_distance_code  ; /* if (32 < bits) */\n\n\tlodsd                         ; /* eax = *(uint *)in++ */\n\tmov\tcl, bl            ; /* cl = bits, needs it for shifting */\n\tadd\tbl, 32             ; /* bits += 32 */\n\tshl\trax, cl\n\tor\trdx, rax          ; /* hold |= *((uint *)in)++ << bits */\n\nL_get_distance_code:\n\tand\tr8, rdx           ; /* r8 &= hold */\n\tmov\teax, [r11+r8*4] ; /* eax = dcode[hold & dmask] */\n\nL_dodist:\n\tmov\tr15d, eax         ; /* dist = this */\n\tshr\tr15d, 16           ; /* dist = this.val */\n\tmov\tcl, ah\n\tsub\tbl, ah            ; /* bits -= this.bits */\n\tshr\trdx, cl           ; /* hold >>= this.bits */\n\tmov\tcl, al            ; /* cl = this.op */\n\n\ttest\tal, 16             ; /* if ((op & 16) == 0) */\n\tjz\tL_test_for_second_level_dist\n\tand\tcl, 15             ; /* op &= 15 */\n\tjz\tL_check_dist_one\n\nL_add_bits_to_dist:\n\tsub\tbl, cl\n\txor\teax, eax\n\tinc\teax\n\tshl\teax, cl\n\tdec\teax                 ; /* (1 << op) - 1 */\n\tand\teax, edx          ; /* eax &= hold */\n\tshr\trdx, cl\n\tadd\tr15d, eax         ; /* dist += hold & ((1 << op) - 1) */\n\nL_check_window:\n\tmov\tr8, rsi           ; /* save in so from can use it's reg */\n\tmov\trax, rdi\n\tsub\trax, [rsp+40]      ; /* nbytes = out - beg */\n\n\tcmp\teax, r15d\n\tjb\tL_clip_window        ; /* if (dist > nbytes) 4.2% */\n\n\tmov\tecx, r14d         ; /* ecx = len */\n\tmov\trsi, rdi\n\tsub\trsi, r15          ; /* from = out - dist */\n\n\tsar\tecx, 1\n\tjnc\tL_copy_two           ; /* if len % 2 == 0 */\n\n\trep     movsw\n\tmov\tal, [rsi]\n\tmov\t[rdi], al\n\tinc\trdi\n\n\tmov\trsi, r8           ; /* move in back to %rsi, toss from */\n\tjmp\tL_while_test\n\nL_copy_two:\n\trep     movsw\n\tmov\trsi, r8           ; /* move in back to %rsi, toss from */\n\tjmp\tL_while_test\n\nALIGN 4\nL_check_dist_one:\n\tcmp\tr15d, 1            ; /* if dist 1, is a memset */\n\tjne\tL_check_window\n\tcmp\t[rsp+40], rdi      ; /* if out == beg, outside window */\n\tje\tL_check_window\n\n\tmov\tecx, r14d         ; /* ecx = len */\n\tmov\tal, [rdi-1]\n\tmov\tah, al\n\n\tsar\tecx, 1\n\tjnc\tL_set_two\n\tmov\t[rdi], al\n\tinc\trdi\n\nL_set_two:\n\trep     stosw\n\tjmp\tL_while_test\n\nALIGN 4\nL_test_for_second_level_length:\n\ttest\tal, 64\n\tjnz\tL_test_for_end_of_block ; /* if ((op & 64) != 0) */\n\n\txor\teax, eax\n\tinc\teax\n\tshl\teax, cl\n\tdec\teax\n\tand\teax, edx         ; /* eax &= hold */\n\tadd\teax, r14d        ; /* eax += len */\n\tmov\teax, [rbp+rax*4] ; /* eax = lcode[val+(hold&mask[op])]*/\n\tjmp\tL_dolen\n\nALIGN 4\nL_test_for_second_level_dist:\n\ttest\tal, 64\n\tjnz\tL_invalid_distance_code ; /* if ((op & 64) != 0) */\n\n\txor\teax, eax\n\tinc\teax\n\tshl\teax, cl\n\tdec\teax\n\tand\teax, edx         ; /* eax &= hold */\n\tadd\teax, r15d        ; /* eax += dist */\n\tmov\teax, [r11+rax*4] ; /* eax = dcode[val+(hold&mask[op])]*/\n\tjmp\tL_dodist\n\nALIGN 4\nL_clip_window:\n\tmov\tecx, eax         ; /* ecx = nbytes */\n\tmov\teax, [rsp+92]     ; /* eax = wsize, prepare for dist cmp */\n\tneg\tecx                ; /* nbytes = -nbytes */\n\n\tcmp\teax, r15d\n\tjb\tL_invalid_distance_too_far ; /* if (dist > wsize) */\n\n\tadd\tecx, r15d         ; /* nbytes = dist - nbytes */\n\tcmp\tdword ptr [rsp+96], 0\n\tjne\tL_wrap_around_window ; /* if (write != 0) */\n\n\tmov\trsi, [rsp+56]     ; /* from  = window */\n\tsub\teax, ecx         ; /* eax  -= nbytes */\n\tadd\trsi, rax         ; /* from += wsize - nbytes */\n\n\tmov\teax, r14d        ; /* eax = len */\n\tcmp\tr14d, ecx\n\tjbe\tL_do_copy           ; /* if (nbytes >= len) */\n\n\tsub\teax, ecx         ; /* eax -= nbytes */\n\trep     movsb\n\tmov\trsi, rdi\n\tsub\trsi, r15         ; /* from = &out[ -dist ] */\n\tjmp\tL_do_copy\n\nALIGN 4\nL_wrap_around_window:\n\tmov\teax, [rsp+96]     ; /* eax = write */\n\tcmp\tecx, eax\n\tjbe\tL_contiguous_in_window ; /* if (write >= nbytes) */\n\n\tmov\tesi, [rsp+92]     ; /* from  = wsize */\n\tadd\trsi, [rsp+56]     ; /* from += window */\n\tadd\trsi, rax         ; /* from += write */\n\tsub\trsi, rcx         ; /* from -= nbytes */\n\tsub\tecx, eax         ; /* nbytes -= write */\n\n\tmov\teax, r14d        ; /* eax = len */\n\tcmp\teax, ecx\n\tjbe\tL_do_copy           ; /* if (nbytes >= len) */\n\n\tsub\teax, ecx         ; /* len -= nbytes */\n\trep     movsb\n\tmov\trsi, [rsp+56]     ; /* from = window */\n\tmov\tecx, [rsp+96]     ; /* nbytes = write */\n\tcmp\teax, ecx\n\tjbe\tL_do_copy           ; /* if (nbytes >= len) */\n\n\tsub\teax, ecx         ; /* len -= nbytes */\n\trep     movsb\n\tmov\trsi, rdi\n\tsub\trsi, r15         ; /* from = out - dist */\n\tjmp\tL_do_copy\n\nALIGN 4\nL_contiguous_in_window:\n\tmov\trsi, [rsp+56]     ; /* rsi = window */\n\tadd\trsi, rax\n\tsub\trsi, rcx         ; /* from += write - nbytes */\n\n\tmov\teax, r14d        ; /* eax = len */\n\tcmp\teax, ecx\n\tjbe\tL_do_copy           ; /* if (nbytes >= len) */\n\n\tsub\teax, ecx         ; /* len -= nbytes */\n\trep     movsb\n\tmov\trsi, rdi\n\tsub\trsi, r15         ; /* from = out - dist */\n\tjmp\tL_do_copy           ; /* if (nbytes >= len) */\n\nALIGN 4\nL_do_copy:\n\tmov\tecx, eax         ; /* ecx = len */\n\trep     movsb\n\n\tmov\trsi, r8          ; /* move in back to %esi, toss from */\n\tjmp\tL_while_test\n\nL_test_for_end_of_block:\n\ttest\tal, 32\n\tjz\tL_invalid_literal_length_code\n\tmov\tdword ptr [rsp+116], 1\n\tjmp\tL_break_loop_with_status\n\nL_invalid_literal_length_code:\n\tmov\tdword ptr [rsp+116], 2\n\tjmp\tL_break_loop_with_status\n\nL_invalid_distance_code:\n\tmov\tdword ptr [rsp+116], 3\n\tjmp\tL_break_loop_with_status\n\nL_invalid_distance_too_far:\n\tmov\tdword ptr [rsp+116], 4\n\tjmp\tL_break_loop_with_status\n\nL_break_loop:\n\tmov\tdword ptr [rsp+116], 0\n\nL_break_loop_with_status:\n; /* put in, out, bits, and hold back into ar and pop esp */\n\tmov\t[rsp+16], rsi     ; /* in */\n\tmov\t[rsp+32], rdi     ; /* out */\n\tmov\t[rsp+88], ebx     ; /* bits */\n\tmov\t[rsp+80], rdx     ; /* hold */\n\n\tmov\trax, [rsp]       ; /* restore rbp and rsp */\n\tmov\trbp, [rsp+8]\n\tmov\trsp, rax\n\n\n\n\tmov rsi,[rsp-8]\n\tmov rdi,[rsp-16]\n\tmov r12,[rsp-24]\n\tmov r13,[rsp-32]\n\tmov r14,[rsp-40]\n\tmov r15,[rsp-48]\n\tmov rbx,[rsp-56]\n\n    ret 0\n;          :\n;          : \"m\" (ar)\n;          : \"memory\", \"%rax\", \"%rbx\", \"%rcx\", \"%rdx\", \"%rsi\", \"%rdi\",\n;            \"%r8\", \"%r9\", \"%r10\", \"%r11\", \"%r12\", \"%r13\", \"%r14\", \"%r15\"\n;    );\n\ninffas8664fnc \tENDP\n;_TEXT\tENDS\nEND\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/masmx64/readme.txt",
    "content": "Summary\n-------\nThis directory contains ASM implementations of the functions\nlongest_match() and inflate_fast(), for 64 bits x86 (both AMD64 and Intel EM64t),\nfor use with Microsoft Macro Assembler (x64) for AMD64 and Microsoft C++ 64 bits.\n\ngvmat64.asm is written by Gilles Vollant (2005), by using Brian Raiter 686/32 bits\n   assembly optimized version from Jean-loup Gailly original longest_match function\n\ninffasx64.asm and inffas8664.c were written by Chris Anderson, by optimizing\n   original function from Mark Adler\n\nUse instructions\n----------------\nAssemble the .asm files using MASM and put the object files into the zlib source\ndirectory.  You can also get object files here:\n\n     http://www.winimage.com/zLibDll/zlib124_masm_obj.zip\n\ndefine ASMV and ASMINF in your project. Include inffas8664.c in your source tree,\nand inffasx64.obj and gvmat64.obj as object to link.\n\n\nBuild instructions\n------------------\nrun bld_64.bat with Microsoft Macro Assembler (x64) for AMD64 (ml64.exe)\n\nml64.exe is given with Visual Studio 2005, Windows 2003 server DDK\n\nYou can get Windows 2003 server DDK with ml64 and cl for AMD64 from\n  http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price)\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/masmx86/bld_ml32.bat",
    "content": "ml /coff /Zi /c /Flmatch686.lst match686.asm\nml /coff /Zi /c /Flinffas32.lst inffas32.asm\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/masmx86/inffas32.asm",
    "content": ";/* inffas32.asm is a hand tuned assembler version of inffast.c -- fast decoding\n; *\n; * inffas32.asm is derivated from inffas86.c, with translation of assembly code\n; *\n; * Copyright (C) 1995-2003 Mark Adler\n; * For conditions of distribution and use, see copyright notice in zlib.h\n; *\n; * Copyright (C) 2003 Chris Anderson <christop@charm.net>\n; * Please use the copyright conditions above.\n; *\n; * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from\n; * the gcc -S output of zlib-1.2.0/inffast.c.  Zlib-1.2.0 is in beta release at\n; * the moment.  I have successfully compiled and tested this code with gcc2.96,\n; * gcc3.2, icc5.0, msvc6.0.  It is very close to the speed of inffast.S\n; * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX\n; * enabled.  I will attempt to merge the MMX code into this version.  Newer\n; * versions of this and inffast.S can be found at\n; * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/\n; *\n; * 2005 : modification by Gilles Vollant\n; */\n; For Visual C++ 4.x and higher and ML 6.x and higher\n;   ml.exe is in directory \\MASM611C of Win95 DDK\n;   ml.exe is also distributed in http://www.masm32.com/masmdl.htm\n;    and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/\n;\n;\n;   compile with command line option\n;   ml  /coff /Zi /c /Flinffas32.lst inffas32.asm\n\n;   if you define NO_GZIP (see inflate.h), compile with\n;   ml  /coff /Zi /c /Flinffas32.lst /DNO_GUNZIP inffas32.asm\n\n\n; zlib122sup is 0 fort zlib 1.2.2.1 and lower\n; zlib122sup is 8 fort zlib 1.2.2.2 and more (with addition of dmax and head\n;        in inflate_state in inflate.h)\nzlib1222sup      equ    8\n\n\nIFDEF GUNZIP\n  INFLATE_MODE_TYPE    equ 11\n  INFLATE_MODE_BAD     equ 26\nELSE\n  IFNDEF NO_GUNZIP\n    INFLATE_MODE_TYPE    equ 11\n    INFLATE_MODE_BAD     equ 26\n  ELSE\n    INFLATE_MODE_TYPE    equ 3\n    INFLATE_MODE_BAD     equ 17\n  ENDIF\nENDIF\n\n\n; 75 \"inffast.S\"\n;FILE \"inffast.S\"\n\n;;;GLOBAL _inflate_fast\n\n;;;SECTION .text\n\n\n\n\t.586p\n\t.mmx\n\n\tname\tinflate_fast_x86\n\t.MODEL\tFLAT\n\n_DATA\t\t\tsegment\ninflate_fast_use_mmx:\n\tdd\t1\n\n\n_TEXT\t\t\tsegment\n\n\n\nALIGN 4\n\tdb\t'Fast decoding Code from Chris Anderson'\n\tdb\t0\n\nALIGN 4\ninvalid_literal_length_code_msg:\n\tdb\t'invalid literal/length code'\n\tdb\t0\n\nALIGN 4\ninvalid_distance_code_msg:\n\tdb\t'invalid distance code'\n\tdb\t0\n\nALIGN 4\ninvalid_distance_too_far_msg:\n\tdb\t'invalid distance too far back'\n\tdb\t0\n\n\nALIGN 4\ninflate_fast_mask:\ndd\t0\ndd\t1\ndd\t3\ndd\t7\ndd\t15\ndd\t31\ndd\t63\ndd\t127\ndd\t255\ndd\t511\ndd\t1023\ndd\t2047\ndd\t4095\ndd\t8191\ndd\t16383\ndd\t32767\ndd\t65535\ndd\t131071\ndd\t262143\ndd\t524287\ndd\t1048575\ndd\t2097151\ndd\t4194303\ndd\t8388607\ndd\t16777215\ndd\t33554431\ndd\t67108863\ndd\t134217727\ndd\t268435455\ndd\t536870911\ndd\t1073741823\ndd\t2147483647\ndd\t4294967295\n\n\nmode_state\t equ\t0\t;/* state->mode\t*/\nwsize_state\t equ\t(32+zlib1222sup)\t;/* state->wsize */\nwrite_state\t equ\t(36+4+zlib1222sup)\t;/* state->write */\nwindow_state\t equ\t(40+4+zlib1222sup)\t;/* state->window */\nhold_state\t equ\t(44+4+zlib1222sup)\t;/* state->hold\t*/\nbits_state\t equ\t(48+4+zlib1222sup)\t;/* state->bits\t*/\nlencode_state\t equ\t(64+4+zlib1222sup)\t;/* state->lencode */\ndistcode_state\t equ\t(68+4+zlib1222sup)\t;/* state->distcode */\nlenbits_state\t equ\t(72+4+zlib1222sup)\t;/* state->lenbits */\ndistbits_state\t equ\t(76+4+zlib1222sup)\t;/* state->distbits */\n\n\n;;SECTION .text\n; 205 \"inffast.S\"\n;GLOBAL\tinflate_fast_use_mmx\n\n;SECTION .data\n\n\n; GLOBAL inflate_fast_use_mmx:object\n;.size inflate_fast_use_mmx, 4\n; 226 \"inffast.S\"\n;SECTION .text\n\nALIGN 4\n_inflate_fast proc near\n.FPO (16, 4, 0, 0, 1, 0)\n\tpush  edi\n\tpush  esi\n\tpush  ebp\n\tpush  ebx\n\tpushfd\n\tsub  esp,64\n\tcld\n\n\n\n\n\tmov  esi, [esp+88]\n\tmov  edi, [esi+28]\n\n\n\n\n\n\n\n\tmov  edx, [esi+4]\n\tmov  eax, [esi+0]\n\n\tadd  edx,eax\n\tsub  edx,11\n\n\tmov  [esp+44],eax\n\tmov  [esp+20],edx\n\n\tmov  ebp, [esp+92]\n\tmov  ecx, [esi+16]\n\tmov  ebx, [esi+12]\n\n\tsub  ebp,ecx\n\tneg  ebp\n\tadd  ebp,ebx\n\n\tsub  ecx,257\n\tadd  ecx,ebx\n\n\tmov  [esp+60],ebx\n\tmov  [esp+40],ebp\n\tmov  [esp+16],ecx\n; 285 \"inffast.S\"\n\tmov  eax, [edi+lencode_state]\n\tmov  ecx, [edi+distcode_state]\n\n\tmov  [esp+8],eax\n\tmov  [esp+12],ecx\n\n\tmov  eax,1\n\tmov  ecx, [edi+lenbits_state]\n\tshl  eax,cl\n\tdec  eax\n\tmov  [esp+0],eax\n\n\tmov  eax,1\n\tmov  ecx, [edi+distbits_state]\n\tshl  eax,cl\n\tdec  eax\n\tmov  [esp+4],eax\n\n\tmov  eax, [edi+wsize_state]\n\tmov  ecx, [edi+write_state]\n\tmov  edx, [edi+window_state]\n\n\tmov  [esp+52],eax\n\tmov  [esp+48],ecx\n\tmov  [esp+56],edx\n\n\tmov  ebp, [edi+hold_state]\n\tmov  ebx, [edi+bits_state]\n; 321 \"inffast.S\"\n\tmov  esi, [esp+44]\n\tmov  ecx, [esp+20]\n\tcmp  ecx,esi\n\tja   L_align_long\n\n\tadd  ecx,11\n\tsub  ecx,esi\n\tmov  eax,12\n\tsub  eax,ecx\n\tlea  edi, [esp+28]\n\trep movsb\n\tmov  ecx,eax\n\txor  eax,eax\n\trep stosb\n\tlea  esi, [esp+28]\n\tmov  [esp+20],esi\n\tjmp  L_is_aligned\n\n\nL_align_long:\n\ttest  esi,3\n\tjz   L_is_aligned\n\txor  eax,eax\n\tmov  al, [esi]\n\tinc  esi\n\tmov  ecx,ebx\n\tadd  ebx,8\n\tshl  eax,cl\n\tor  ebp,eax\n\tjmp L_align_long\n\nL_is_aligned:\n\tmov  edi, [esp+60]\n; 366 \"inffast.S\"\nL_check_mmx:\n\tcmp  dword ptr [inflate_fast_use_mmx],2\n\tje   L_init_mmx\n\tja   L_do_loop\n\n\tpush  eax\n\tpush  ebx\n\tpush  ecx\n\tpush  edx\n\tpushfd\n\tmov  eax, [esp]\n\txor  dword ptr [esp],0200000h\n\n\n\n\n\tpopfd\n\tpushfd\n\tpop  edx\n\txor  edx,eax\n\tjz   L_dont_use_mmx\n\txor  eax,eax\n\tcpuid\n\tcmp  ebx,0756e6547h\n\tjne  L_dont_use_mmx\n\tcmp  ecx,06c65746eh\n\tjne  L_dont_use_mmx\n\tcmp  edx,049656e69h\n\tjne  L_dont_use_mmx\n\tmov  eax,1\n\tcpuid\n\tshr  eax,8\n\tand  eax,15\n\tcmp  eax,6\n\tjne  L_dont_use_mmx\n\ttest  edx,0800000h\n\tjnz  L_use_mmx\n\tjmp  L_dont_use_mmx\nL_use_mmx:\n\tmov  dword ptr [inflate_fast_use_mmx],2\n\tjmp  L_check_mmx_pop\nL_dont_use_mmx:\n\tmov  dword ptr [inflate_fast_use_mmx],3\nL_check_mmx_pop:\n\tpop  edx\n\tpop  ecx\n\tpop  ebx\n\tpop  eax\n\tjmp  L_check_mmx\n; 426 \"inffast.S\"\nALIGN 4\nL_do_loop:\n; 437 \"inffast.S\"\n\tcmp  bl,15\n\tja   L_get_length_code\n\n\txor  eax,eax\n\tlodsw\n\tmov  cl,bl\n\tadd  bl,16\n\tshl  eax,cl\n\tor  ebp,eax\n\nL_get_length_code:\n\tmov  edx, [esp+0]\n\tmov  ecx, [esp+8]\n\tand  edx,ebp\n\tmov  eax, [ecx+edx*4]\n\nL_dolen:\n\n\n\n\n\n\n\tmov  cl,ah\n\tsub  bl,ah\n\tshr  ebp,cl\n\n\n\n\n\n\n\ttest  al,al\n\tjnz   L_test_for_length_base\n\n\tshr  eax,16\n\tstosb\n\nL_while_test:\n\n\n\tcmp  [esp+16],edi\n\tjbe  L_break_loop\n\n\tcmp  [esp+20],esi\n\tja   L_do_loop\n\tjmp  L_break_loop\n\nL_test_for_length_base:\n; 502 \"inffast.S\"\n\tmov  edx,eax\n\tshr  edx,16\n\tmov  cl,al\n\n\ttest  al,16\n\tjz   L_test_for_second_level_length\n\tand  cl,15\n\tjz   L_save_len\n\tcmp  bl,cl\n\tjae  L_add_bits_to_len\n\n\tmov  ch,cl\n\txor  eax,eax\n\tlodsw\n\tmov  cl,bl\n\tadd  bl,16\n\tshl  eax,cl\n\tor  ebp,eax\n\tmov  cl,ch\n\nL_add_bits_to_len:\n\tmov  eax,1\n\tshl  eax,cl\n\tdec  eax\n\tsub  bl,cl\n\tand  eax,ebp\n\tshr  ebp,cl\n\tadd  edx,eax\n\nL_save_len:\n\tmov  [esp+24],edx\n\n\nL_decode_distance:\n; 549 \"inffast.S\"\n\tcmp  bl,15\n\tja   L_get_distance_code\n\n\txor  eax,eax\n\tlodsw\n\tmov  cl,bl\n\tadd  bl,16\n\tshl  eax,cl\n\tor  ebp,eax\n\nL_get_distance_code:\n\tmov  edx, [esp+4]\n\tmov  ecx, [esp+12]\n\tand  edx,ebp\n\tmov  eax, [ecx+edx*4]\n\n\nL_dodist:\n\tmov  edx,eax\n\tshr  edx,16\n\tmov  cl,ah\n\tsub  bl,ah\n\tshr  ebp,cl\n; 584 \"inffast.S\"\n\tmov  cl,al\n\n\ttest  al,16\n\tjz  L_test_for_second_level_dist\n\tand  cl,15\n\tjz  L_check_dist_one\n\tcmp  bl,cl\n\tjae  L_add_bits_to_dist\n\n\tmov  ch,cl\n\txor  eax,eax\n\tlodsw\n\tmov  cl,bl\n\tadd  bl,16\n\tshl  eax,cl\n\tor  ebp,eax\n\tmov  cl,ch\n\nL_add_bits_to_dist:\n\tmov  eax,1\n\tshl  eax,cl\n\tdec  eax\n\tsub  bl,cl\n\tand  eax,ebp\n\tshr  ebp,cl\n\tadd  edx,eax\n\tjmp  L_check_window\n\nL_check_window:\n; 625 \"inffast.S\"\n\tmov  [esp+44],esi\n\tmov  eax,edi\n\tsub  eax, [esp+40]\n\n\tcmp  eax,edx\n\tjb   L_clip_window\n\n\tmov  ecx, [esp+24]\n\tmov  esi,edi\n\tsub  esi,edx\n\n\tsub  ecx,3\n\tmov  al, [esi]\n\tmov  [edi],al\n\tmov  al, [esi+1]\n\tmov  dl, [esi+2]\n\tadd  esi,3\n\tmov  [edi+1],al\n\tmov  [edi+2],dl\n\tadd  edi,3\n\trep movsb\n\n\tmov  esi, [esp+44]\n\tjmp  L_while_test\n\nALIGN 4\nL_check_dist_one:\n\tcmp  edx,1\n\tjne  L_check_window\n\tcmp  [esp+40],edi\n\tje  L_check_window\n\n\tdec  edi\n\tmov  ecx, [esp+24]\n\tmov  al, [edi]\n\tsub  ecx,3\n\n\tmov  [edi+1],al\n\tmov  [edi+2],al\n\tmov  [edi+3],al\n\tadd  edi,4\n\trep stosb\n\n\tjmp  L_while_test\n\nALIGN 4\nL_test_for_second_level_length:\n\n\n\n\n\ttest  al,64\n\tjnz   L_test_for_end_of_block\n\n\tmov  eax,1\n\tshl  eax,cl\n\tdec  eax\n\tand  eax,ebp\n\tadd  eax,edx\n\tmov  edx, [esp+8]\n\tmov  eax, [edx+eax*4]\n\tjmp  L_dolen\n\nALIGN 4\nL_test_for_second_level_dist:\n\n\n\n\n\ttest  al,64\n\tjnz   L_invalid_distance_code\n\n\tmov  eax,1\n\tshl  eax,cl\n\tdec  eax\n\tand  eax,ebp\n\tadd  eax,edx\n\tmov  edx, [esp+12]\n\tmov  eax, [edx+eax*4]\n\tjmp  L_dodist\n\nALIGN 4\nL_clip_window:\n; 721 \"inffast.S\"\n\tmov  ecx,eax\n\tmov  eax, [esp+52]\n\tneg  ecx\n\tmov  esi, [esp+56]\n\n\tcmp  eax,edx\n\tjb   L_invalid_distance_too_far\n\n\tadd  ecx,edx\n\tcmp  dword ptr [esp+48],0\n\tjne  L_wrap_around_window\n\n\tsub  eax,ecx\n\tadd  esi,eax\n; 749 \"inffast.S\"\n\tmov  eax, [esp+24]\n\tcmp  eax,ecx\n\tjbe  L_do_copy1\n\n\tsub  eax,ecx\n\trep movsb\n\tmov  esi,edi\n\tsub  esi,edx\n\tjmp  L_do_copy1\n\n\tcmp  eax,ecx\n\tjbe  L_do_copy1\n\n\tsub  eax,ecx\n\trep movsb\n\tmov  esi,edi\n\tsub  esi,edx\n\tjmp  L_do_copy1\n\nL_wrap_around_window:\n; 793 \"inffast.S\"\n\tmov  eax, [esp+48]\n\tcmp  ecx,eax\n\tjbe  L_contiguous_in_window\n\n\tadd  esi, [esp+52]\n\tadd  esi,eax\n\tsub  esi,ecx\n\tsub  ecx,eax\n\n\n\tmov  eax, [esp+24]\n\tcmp  eax,ecx\n\tjbe  L_do_copy1\n\n\tsub  eax,ecx\n\trep movsb\n\tmov  esi, [esp+56]\n\tmov  ecx, [esp+48]\n\tcmp  eax,ecx\n\tjbe  L_do_copy1\n\n\tsub  eax,ecx\n\trep movsb\n\tmov  esi,edi\n\tsub  esi,edx\n\tjmp  L_do_copy1\n\nL_contiguous_in_window:\n; 836 \"inffast.S\"\n\tadd  esi,eax\n\tsub  esi,ecx\n\n\n\tmov  eax, [esp+24]\n\tcmp  eax,ecx\n\tjbe  L_do_copy1\n\n\tsub  eax,ecx\n\trep movsb\n\tmov  esi,edi\n\tsub  esi,edx\n\nL_do_copy1:\n; 862 \"inffast.S\"\n\tmov  ecx,eax\n\trep movsb\n\n\tmov  esi, [esp+44]\n\tjmp  L_while_test\n; 878 \"inffast.S\"\nALIGN 4\nL_init_mmx:\n\temms\n\n\n\n\n\n\tmovd mm0,ebp\n\tmov  ebp,ebx\n; 896 \"inffast.S\"\n\tmovd mm4,dword ptr [esp+0]\n\tmovq mm3,mm4\n\tmovd mm5,dword ptr [esp+4]\n\tmovq mm2,mm5\n\tpxor mm1,mm1\n\tmov  ebx, [esp+8]\n\tjmp  L_do_loop_mmx\n\nALIGN 4\nL_do_loop_mmx:\n\tpsrlq mm0,mm1\n\n\tcmp  ebp,32\n\tja  L_get_length_code_mmx\n\n\tmovd mm6,ebp\n\tmovd mm7,dword ptr [esi]\n\tadd  esi,4\n\tpsllq mm7,mm6\n\tadd  ebp,32\n\tpor mm0,mm7\n\nL_get_length_code_mmx:\n\tpand mm4,mm0\n\tmovd eax,mm4\n\tmovq mm4,mm3\n\tmov  eax, [ebx+eax*4]\n\nL_dolen_mmx:\n\tmovzx  ecx,ah\n\tmovd mm1,ecx\n\tsub  ebp,ecx\n\n\ttest  al,al\n\tjnz L_test_for_length_base_mmx\n\n\tshr  eax,16\n\tstosb\n\nL_while_test_mmx:\n\n\n\tcmp  [esp+16],edi\n\tjbe L_break_loop\n\n\tcmp  [esp+20],esi\n\tja L_do_loop_mmx\n\tjmp L_break_loop\n\nL_test_for_length_base_mmx:\n\n\tmov  edx,eax\n\tshr  edx,16\n\n\ttest  al,16\n\tjz  L_test_for_second_level_length_mmx\n\tand  eax,15\n\tjz L_decode_distance_mmx\n\n\tpsrlq mm0,mm1\n\tmovd mm1,eax\n\tmovd ecx,mm0\n\tsub  ebp,eax\n\tand  ecx, [inflate_fast_mask+eax*4]\n\tadd  edx,ecx\n\nL_decode_distance_mmx:\n\tpsrlq mm0,mm1\n\n\tcmp  ebp,32\n\tja L_get_dist_code_mmx\n\n\tmovd mm6,ebp\n\tmovd mm7,dword ptr [esi]\n\tadd  esi,4\n\tpsllq mm7,mm6\n\tadd  ebp,32\n\tpor mm0,mm7\n\nL_get_dist_code_mmx:\n\tmov  ebx, [esp+12]\n\tpand mm5,mm0\n\tmovd eax,mm5\n\tmovq mm5,mm2\n\tmov  eax, [ebx+eax*4]\n\nL_dodist_mmx:\n\n\tmovzx  ecx,ah\n\tmov  ebx,eax\n\tshr  ebx,16\n\tsub  ebp,ecx\n\tmovd mm1,ecx\n\n\ttest  al,16\n\tjz L_test_for_second_level_dist_mmx\n\tand  eax,15\n\tjz L_check_dist_one_mmx\n\nL_add_bits_to_dist_mmx:\n\tpsrlq mm0,mm1\n\tmovd mm1,eax\n\tmovd ecx,mm0\n\tsub  ebp,eax\n\tand  ecx, [inflate_fast_mask+eax*4]\n\tadd  ebx,ecx\n\nL_check_window_mmx:\n\tmov  [esp+44],esi\n\tmov  eax,edi\n\tsub  eax, [esp+40]\n\n\tcmp  eax,ebx\n\tjb L_clip_window_mmx\n\n\tmov  ecx,edx\n\tmov  esi,edi\n\tsub  esi,ebx\n\n\tsub  ecx,3\n\tmov  al, [esi]\n\tmov  [edi],al\n\tmov  al, [esi+1]\n\tmov  dl, [esi+2]\n\tadd  esi,3\n\tmov  [edi+1],al\n\tmov  [edi+2],dl\n\tadd  edi,3\n\trep movsb\n\n\tmov  esi, [esp+44]\n\tmov  ebx, [esp+8]\n\tjmp  L_while_test_mmx\n\nALIGN 4\nL_check_dist_one_mmx:\n\tcmp  ebx,1\n\tjne  L_check_window_mmx\n\tcmp  [esp+40],edi\n\tje   L_check_window_mmx\n\n\tdec  edi\n\tmov  ecx,edx\n\tmov  al, [edi]\n\tsub  ecx,3\n\n\tmov  [edi+1],al\n\tmov  [edi+2],al\n\tmov  [edi+3],al\n\tadd  edi,4\n\trep stosb\n\n\tmov  ebx, [esp+8]\n\tjmp  L_while_test_mmx\n\nALIGN 4\nL_test_for_second_level_length_mmx:\n\ttest  al,64\n\tjnz L_test_for_end_of_block\n\n\tand  eax,15\n\tpsrlq mm0,mm1\n\tmovd ecx,mm0\n\tand  ecx, [inflate_fast_mask+eax*4]\n\tadd  ecx,edx\n\tmov  eax, [ebx+ecx*4]\n\tjmp L_dolen_mmx\n\nALIGN 4\nL_test_for_second_level_dist_mmx:\n\ttest  al,64\n\tjnz L_invalid_distance_code\n\n\tand  eax,15\n\tpsrlq mm0,mm1\n\tmovd ecx,mm0\n\tand  ecx, [inflate_fast_mask+eax*4]\n\tmov  eax, [esp+12]\n\tadd  ecx,ebx\n\tmov  eax, [eax+ecx*4]\n\tjmp  L_dodist_mmx\n\nALIGN 4\nL_clip_window_mmx:\n\n\tmov  ecx,eax\n\tmov  eax, [esp+52]\n\tneg  ecx\n\tmov  esi, [esp+56]\n\n\tcmp  eax,ebx\n\tjb  L_invalid_distance_too_far\n\n\tadd  ecx,ebx\n\tcmp  dword ptr [esp+48],0\n\tjne  L_wrap_around_window_mmx\n\n\tsub  eax,ecx\n\tadd  esi,eax\n\n\tcmp  edx,ecx\n\tjbe  L_do_copy1_mmx\n\n\tsub  edx,ecx\n\trep movsb\n\tmov  esi,edi\n\tsub  esi,ebx\n\tjmp  L_do_copy1_mmx\n\n\tcmp  edx,ecx\n\tjbe  L_do_copy1_mmx\n\n\tsub  edx,ecx\n\trep movsb\n\tmov  esi,edi\n\tsub  esi,ebx\n\tjmp  L_do_copy1_mmx\n\nL_wrap_around_window_mmx:\n\n\tmov  eax, [esp+48]\n\tcmp  ecx,eax\n\tjbe  L_contiguous_in_window_mmx\n\n\tadd  esi, [esp+52]\n\tadd  esi,eax\n\tsub  esi,ecx\n\tsub  ecx,eax\n\n\n\tcmp  edx,ecx\n\tjbe  L_do_copy1_mmx\n\n\tsub  edx,ecx\n\trep movsb\n\tmov  esi, [esp+56]\n\tmov  ecx, [esp+48]\n\tcmp  edx,ecx\n\tjbe  L_do_copy1_mmx\n\n\tsub  edx,ecx\n\trep movsb\n\tmov  esi,edi\n\tsub  esi,ebx\n\tjmp  L_do_copy1_mmx\n\nL_contiguous_in_window_mmx:\n\n\tadd  esi,eax\n\tsub  esi,ecx\n\n\n\tcmp  edx,ecx\n\tjbe  L_do_copy1_mmx\n\n\tsub  edx,ecx\n\trep movsb\n\tmov  esi,edi\n\tsub  esi,ebx\n\nL_do_copy1_mmx:\n\n\n\tmov  ecx,edx\n\trep movsb\n\n\tmov  esi, [esp+44]\n\tmov  ebx, [esp+8]\n\tjmp  L_while_test_mmx\n; 1174 \"inffast.S\"\nL_invalid_distance_code:\n\n\n\n\n\n\tmov  ecx, invalid_distance_code_msg\n\tmov  edx,INFLATE_MODE_BAD\n\tjmp  L_update_stream_state\n\nL_test_for_end_of_block:\n\n\n\n\n\n\ttest  al,32\n\tjz  L_invalid_literal_length_code\n\n\tmov  ecx,0\n\tmov  edx,INFLATE_MODE_TYPE\n\tjmp  L_update_stream_state\n\nL_invalid_literal_length_code:\n\n\n\n\n\n\tmov  ecx, invalid_literal_length_code_msg\n\tmov  edx,INFLATE_MODE_BAD\n\tjmp  L_update_stream_state\n\nL_invalid_distance_too_far:\n\n\n\n\tmov  esi, [esp+44]\n\tmov  ecx, invalid_distance_too_far_msg\n\tmov  edx,INFLATE_MODE_BAD\n\tjmp  L_update_stream_state\n\nL_update_stream_state:\n\n\tmov  eax, [esp+88]\n\ttest  ecx,ecx\n\tjz  L_skip_msg\n\tmov  [eax+24],ecx\nL_skip_msg:\n\tmov  eax, [eax+28]\n\tmov  [eax+mode_state],edx\n\tjmp  L_break_loop\n\nALIGN 4\nL_break_loop:\n; 1243 \"inffast.S\"\n\tcmp  dword ptr [inflate_fast_use_mmx],2\n\tjne  L_update_next_in\n\n\n\n\tmov  ebx,ebp\n\nL_update_next_in:\n; 1266 \"inffast.S\"\n\tmov  eax, [esp+88]\n\tmov  ecx,ebx\n\tmov  edx, [eax+28]\n\tshr  ecx,3\n\tsub  esi,ecx\n\tshl  ecx,3\n\tsub  ebx,ecx\n\tmov  [eax+12],edi\n\tmov  [edx+bits_state],ebx\n\tmov  ecx,ebx\n\n\tlea  ebx, [esp+28]\n\tcmp  [esp+20],ebx\n\tjne  L_buf_not_used\n\n\tsub  esi,ebx\n\tmov  ebx, [eax+0]\n\tmov  [esp+20],ebx\n\tadd  esi,ebx\n\tmov  ebx, [eax+4]\n\tsub  ebx,11\n\tadd  [esp+20],ebx\n\nL_buf_not_used:\n\tmov  [eax+0],esi\n\n\tmov  ebx,1\n\tshl  ebx,cl\n\tdec  ebx\n\n\n\n\n\n\tcmp  dword ptr [inflate_fast_use_mmx],2\n\tjne  L_update_hold\n\n\n\n\tpsrlq mm0,mm1\n\tmovd ebp,mm0\n\n\temms\n\nL_update_hold:\n\n\n\n\tand  ebp,ebx\n\tmov  [edx+hold_state],ebp\n\n\n\n\n\tmov  ebx, [esp+20]\n\tcmp  ebx,esi\n\tjbe  L_last_is_smaller\n\n\tsub  ebx,esi\n\tadd  ebx,11\n\tmov  [eax+4],ebx\n\tjmp  L_fixup_out\nL_last_is_smaller:\n\tsub  esi,ebx\n\tneg  esi\n\tadd  esi,11\n\tmov  [eax+4],esi\n\n\n\n\nL_fixup_out:\n\n\tmov  ebx, [esp+16]\n\tcmp  ebx,edi\n\tjbe  L_end_is_smaller\n\n\tsub  ebx,edi\n\tadd  ebx,257\n\tmov  [eax+16],ebx\n\tjmp  L_done\nL_end_is_smaller:\n\tsub  edi,ebx\n\tneg  edi\n\tadd  edi,257\n\tmov  [eax+16],edi\n\n\n\n\n\nL_done:\n\tadd  esp,64\n\tpopfd\n\tpop  ebx\n\tpop  ebp\n\tpop  esi\n\tpop  edi\n\tret\n_inflate_fast endp\n\n_TEXT\tends\nend\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/masmx86/match686.asm",
    "content": "; match686.asm -- Asm portion of the optimized longest_match for 32 bits x86\n; Copyright (C) 1995-1996 Jean-loup Gailly, Brian Raiter and Gilles Vollant.\n; File written by Gilles Vollant, by converting match686.S from Brian Raiter\n; for MASM. This is as assembly version of longest_match\n;  from Jean-loup Gailly in deflate.c\n;\n;         http://www.zlib.net\n;         http://www.winimage.com/zLibDll\n;         http://www.muppetlabs.com/~breadbox/software/assembly.html\n;\n; For Visual C++ 4.x and higher and ML 6.x and higher\n;   ml.exe is distributed in\n;  http://www.microsoft.com/downloads/details.aspx?FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64\n;\n; this file contain two implementation of longest_match\n;\n;  this longest_match was written by Brian raiter (1998), optimized for Pentium Pro\n;   (and the faster known version of match_init on modern Core 2 Duo and AMD Phenom)\n;\n;  for using an assembly version of longest_match, you need define ASMV in project\n;\n;    compile the asm file running\n;           ml /coff /Zi /c /Flmatch686.lst match686.asm\n;    and do not include match686.obj in your project\n;\n; note: contrib of zLib 1.2.3 and earlier contained both a deprecated version for\n;  Pentium (prior Pentium Pro) and this version for Pentium Pro and modern processor\n;  with autoselect (with cpu detection code)\n;  if you want support the old pentium optimization, you can still use these version\n;\n; this file is not optimized for old pentium, but it compatible with all x86 32 bits\n; processor (starting 80386)\n;\n;\n; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2\n\n;uInt longest_match(s, cur_match)\n;    deflate_state *s;\n;    IPos cur_match;                             /* current match */\n\n    NbStack         equ     76\n    cur_match       equ     dword ptr[esp+NbStack-0]\n    str_s           equ     dword ptr[esp+NbStack-4]\n; 5 dword on top (ret,ebp,esi,edi,ebx)\n    adrret          equ     dword ptr[esp+NbStack-8]\n    pushebp         equ     dword ptr[esp+NbStack-12]\n    pushedi         equ     dword ptr[esp+NbStack-16]\n    pushesi         equ     dword ptr[esp+NbStack-20]\n    pushebx         equ     dword ptr[esp+NbStack-24]\n\n    chain_length    equ     dword ptr [esp+NbStack-28]\n    limit           equ     dword ptr [esp+NbStack-32]\n    best_len        equ     dword ptr [esp+NbStack-36]\n    window          equ     dword ptr [esp+NbStack-40]\n    prev            equ     dword ptr [esp+NbStack-44]\n    scan_start      equ      word ptr [esp+NbStack-48]\n    wmask           equ     dword ptr [esp+NbStack-52]\n    match_start_ptr equ     dword ptr [esp+NbStack-56]\n    nice_match      equ     dword ptr [esp+NbStack-60]\n    scan            equ     dword ptr [esp+NbStack-64]\n\n    windowlen       equ     dword ptr [esp+NbStack-68]\n    match_start     equ     dword ptr [esp+NbStack-72]\n    strend          equ     dword ptr [esp+NbStack-76]\n    NbStackAdd      equ     (NbStack-24)\n\n    .386p\n\n    name    gvmatch\n    .MODEL  FLAT\n\n\n\n;  all the +zlib1222add offsets are due to the addition of fields\n;  in zlib in the deflate_state structure since the asm code was first written\n;  (if you compile with zlib 1.0.4 or older, use \"zlib1222add equ (-4)\").\n;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use \"zlib1222add equ 0\").\n;  if you compile with zlib 1.2.2.2 or later , use \"zlib1222add equ 8\").\n\n    zlib1222add         equ     8\n\n;  Note : these value are good with a 8 bytes boundary pack structure\n    dep_chain_length    equ     74h+zlib1222add\n    dep_window          equ     30h+zlib1222add\n    dep_strstart        equ     64h+zlib1222add\n    dep_prev_length     equ     70h+zlib1222add\n    dep_nice_match      equ     88h+zlib1222add\n    dep_w_size          equ     24h+zlib1222add\n    dep_prev            equ     38h+zlib1222add\n    dep_w_mask          equ     2ch+zlib1222add\n    dep_good_match      equ     84h+zlib1222add\n    dep_match_start     equ     68h+zlib1222add\n    dep_lookahead       equ     6ch+zlib1222add\n\n\n_TEXT                   segment\n\nIFDEF NOUNDERLINE\n            public  longest_match\n            public  match_init\nELSE\n            public  _longest_match\n            public  _match_init\nENDIF\n\n    MAX_MATCH           equ     258\n    MIN_MATCH           equ     3\n    MIN_LOOKAHEAD       equ     (MAX_MATCH+MIN_MATCH+1)\n\n\n\nMAX_MATCH       equ     258\nMIN_MATCH       equ     3\nMIN_LOOKAHEAD   equ     (MAX_MATCH + MIN_MATCH + 1)\nMAX_MATCH_8_     equ     ((MAX_MATCH + 7) AND 0FFF0h)\n\n\n;;; stack frame offsets\n\nchainlenwmask   equ  esp + 0    ; high word: current chain len\n                    ; low word: s->wmask\nwindow      equ  esp + 4    ; local copy of s->window\nwindowbestlen   equ  esp + 8    ; s->window + bestlen\nscanstart   equ  esp + 16   ; first two bytes of string\nscanend     equ  esp + 12   ; last two bytes of string\nscanalign   equ  esp + 20   ; dword-misalignment of string\nnicematch   equ  esp + 24   ; a good enough match size\nbestlen     equ  esp + 28   ; size of best match so far\nscan        equ  esp + 32   ; ptr to string wanting match\n\nLocalVarsSize   equ 36\n;   saved ebx   byte esp + 36\n;   saved edi   byte esp + 40\n;   saved esi   byte esp + 44\n;   saved ebp   byte esp + 48\n;   return address  byte esp + 52\ndeflatestate    equ  esp + 56   ; the function arguments\ncurmatch    equ  esp + 60\n\n;;; Offsets for fields in the deflate_state structure. These numbers\n;;; are calculated from the definition of deflate_state, with the\n;;; assumption that the compiler will dword-align the fields. (Thus,\n;;; changing the definition of deflate_state could easily cause this\n;;; program to crash horribly, without so much as a warning at\n;;; compile time. Sigh.)\n\ndsWSize     equ 36+zlib1222add\ndsWMask     equ 44+zlib1222add\ndsWindow    equ 48+zlib1222add\ndsPrev      equ 56+zlib1222add\ndsMatchLen  equ 88+zlib1222add\ndsPrevMatch equ 92+zlib1222add\ndsStrStart  equ 100+zlib1222add\ndsMatchStart    equ 104+zlib1222add\ndsLookahead equ 108+zlib1222add\ndsPrevLen   equ 112+zlib1222add\ndsMaxChainLen   equ 116+zlib1222add\ndsGoodMatch equ 132+zlib1222add\ndsNiceMatch equ 136+zlib1222add\n\n\n;;; match686.asm -- Pentium-Pro-optimized version of longest_match()\n;;; Written for zlib 1.1.2\n;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>\n;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html\n;;;\n;;\n;;  This software is provided 'as-is', without any express or implied\n;;  warranty.  In no event will the authors be held liable for any damages\n;;  arising from the use of this software.\n;;\n;;  Permission is granted to anyone to use this software for any purpose,\n;;  including commercial applications, and to alter it and redistribute it\n;;  freely, subject to the following restrictions:\n;;\n;;  1. The origin of this software must not be misrepresented; you must not\n;;     claim that you wrote the original software. If you use this software\n;;     in a product, an acknowledgment in the product documentation would be\n;;     appreciated but is not required.\n;;  2. Altered source versions must be plainly marked as such, and must not be\n;;     misrepresented as being the original software\n;;  3. This notice may not be removed or altered from any source distribution.\n;;\n\n;GLOBAL _longest_match, _match_init\n\n\n;SECTION    .text\n\n;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch)\n\n;_longest_match:\n    IFDEF NOUNDERLINE\n    longest_match       proc near\n    ELSE\n    _longest_match      proc near\n    ENDIF\n.FPO (9, 4, 0, 0, 1, 0)\n\n;;; Save registers that the compiler may be using, and adjust esp to\n;;; make room for our stack frame.\n\n        push    ebp\n        push    edi\n        push    esi\n        push    ebx\n        sub esp, LocalVarsSize\n\n;;; Retrieve the function arguments. ecx will hold cur_match\n;;; throughout the entire function. edx will hold the pointer to the\n;;; deflate_state structure during the function's setup (before\n;;; entering the main loop.\n\n        mov edx, [deflatestate]\n        mov ecx, [curmatch]\n\n;;; uInt wmask = s->w_mask;\n;;; unsigned chain_length = s->max_chain_length;\n;;; if (s->prev_length >= s->good_match) {\n;;;     chain_length >>= 2;\n;;; }\n\n        mov eax, [edx + dsPrevLen]\n        mov ebx, [edx + dsGoodMatch]\n        cmp eax, ebx\n        mov eax, [edx + dsWMask]\n        mov ebx, [edx + dsMaxChainLen]\n        jl  LastMatchGood\n        shr ebx, 2\nLastMatchGood:\n\n;;; chainlen is decremented once beforehand so that the function can\n;;; use the sign flag instead of the zero flag for the exit test.\n;;; It is then shifted into the high word, to make room for the wmask\n;;; value, which it will always accompany.\n\n        dec ebx\n        shl ebx, 16\n        or  ebx, eax\n        mov [chainlenwmask], ebx\n\n;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;\n\n        mov eax, [edx + dsNiceMatch]\n        mov ebx, [edx + dsLookahead]\n        cmp ebx, eax\n        jl  LookaheadLess\n        mov ebx, eax\nLookaheadLess:  mov [nicematch], ebx\n\n;;; register Bytef *scan = s->window + s->strstart;\n\n        mov esi, [edx + dsWindow]\n        mov [window], esi\n        mov ebp, [edx + dsStrStart]\n        lea edi, [esi + ebp]\n        mov [scan], edi\n\n;;; Determine how many bytes the scan ptr is off from being\n;;; dword-aligned.\n\n        mov eax, edi\n        neg eax\n        and eax, 3\n        mov [scanalign], eax\n\n;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?\n;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;\n\n        mov eax, [edx + dsWSize]\n        sub eax, MIN_LOOKAHEAD\n        sub ebp, eax\n        jg  LimitPositive\n        xor ebp, ebp\nLimitPositive:\n\n;;; int best_len = s->prev_length;\n\n        mov eax, [edx + dsPrevLen]\n        mov [bestlen], eax\n\n;;; Store the sum of s->window + best_len in esi locally, and in esi.\n\n        add esi, eax\n        mov [windowbestlen], esi\n\n;;; register ush scan_start = *(ushf*)scan;\n;;; register ush scan_end   = *(ushf*)(scan+best_len-1);\n;;; Posf *prev = s->prev;\n\n        movzx   ebx, word ptr [edi]\n        mov [scanstart], ebx\n        movzx   ebx, word ptr [edi + eax - 1]\n        mov [scanend], ebx\n        mov edi, [edx + dsPrev]\n\n;;; Jump into the main loop.\n\n        mov edx, [chainlenwmask]\n        jmp short LoopEntry\n\nalign 4\n\n;;; do {\n;;;     match = s->window + cur_match;\n;;;     if (*(ushf*)(match+best_len-1) != scan_end ||\n;;;         *(ushf*)match != scan_start) continue;\n;;;     [...]\n;;; } while ((cur_match = prev[cur_match & wmask]) > limit\n;;;          && --chain_length != 0);\n;;;\n;;; Here is the inner loop of the function. The function will spend the\n;;; majority of its time in this loop, and majority of that time will\n;;; be spent in the first ten instructions.\n;;;\n;;; Within this loop:\n;;; ebx = scanend\n;;; ecx = curmatch\n;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)\n;;; esi = windowbestlen - i.e., (window + bestlen)\n;;; edi = prev\n;;; ebp = limit\n\nLookupLoop:\n        and ecx, edx\n        movzx   ecx, word ptr [edi + ecx*2]\n        cmp ecx, ebp\n        jbe LeaveNow\n        sub edx, 00010000h\n        js  LeaveNow\nLoopEntry:  movzx   eax, word ptr [esi + ecx - 1]\n        cmp eax, ebx\n        jnz LookupLoop\n        mov eax, [window]\n        movzx   eax, word ptr [eax + ecx]\n        cmp eax, [scanstart]\n        jnz LookupLoop\n\n;;; Store the current value of chainlen.\n\n        mov [chainlenwmask], edx\n\n;;; Point edi to the string under scrutiny, and esi to the string we\n;;; are hoping to match it up with. In actuality, esi and edi are\n;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is\n;;; initialized to -(MAX_MATCH_8 - scanalign).\n\n        mov esi, [window]\n        mov edi, [scan]\n        add esi, ecx\n        mov eax, [scanalign]\n        mov edx, 0fffffef8h; -(MAX_MATCH_8)\n        lea edi, [edi + eax + 0108h] ;MAX_MATCH_8]\n        lea esi, [esi + eax + 0108h] ;MAX_MATCH_8]\n\n;;; Test the strings for equality, 8 bytes at a time. At the end,\n;;; adjust edx so that it is offset to the exact byte that mismatched.\n;;;\n;;; We already know at this point that the first three bytes of the\n;;; strings match each other, and they can be safely passed over before\n;;; starting the compare loop. So what this code does is skip over 0-3\n;;; bytes, as much as necessary in order to dword-align the edi\n;;; pointer. (esi will still be misaligned three times out of four.)\n;;;\n;;; It should be confessed that this loop usually does not represent\n;;; much of the total running time. Replacing it with a more\n;;; straightforward \"rep cmpsb\" would not drastically degrade\n;;; performance.\n\nLoopCmps:\n        mov eax, [esi + edx]\n        xor eax, [edi + edx]\n        jnz LeaveLoopCmps\n        mov eax, [esi + edx + 4]\n        xor eax, [edi + edx + 4]\n        jnz LeaveLoopCmps4\n        add edx, 8\n        jnz LoopCmps\n        jmp short LenMaximum\nLeaveLoopCmps4: add edx, 4\nLeaveLoopCmps:  test    eax, 0000FFFFh\n        jnz LenLower\n        add edx,  2\n        shr eax, 16\nLenLower:   sub al, 1\n        adc edx, 0\n\n;;; Calculate the length of the match. If it is longer than MAX_MATCH,\n;;; then automatically accept it as the best possible match and leave.\n\n        lea eax, [edi + edx]\n        mov edi, [scan]\n        sub eax, edi\n        cmp eax, MAX_MATCH\n        jge LenMaximum\n\n;;; If the length of the match is not longer than the best match we\n;;; have so far, then forget it and return to the lookup loop.\n\n        mov edx, [deflatestate]\n        mov ebx, [bestlen]\n        cmp eax, ebx\n        jg  LongerMatch\n        mov esi, [windowbestlen]\n        mov edi, [edx + dsPrev]\n        mov ebx, [scanend]\n        mov edx, [chainlenwmask]\n        jmp LookupLoop\n\n;;;         s->match_start = cur_match;\n;;;         best_len = len;\n;;;         if (len >= nice_match) break;\n;;;         scan_end = *(ushf*)(scan+best_len-1);\n\nLongerMatch:    mov ebx, [nicematch]\n        mov [bestlen], eax\n        mov [edx + dsMatchStart], ecx\n        cmp eax, ebx\n        jge LeaveNow\n        mov esi, [window]\n        add esi, eax\n        mov [windowbestlen], esi\n        movzx   ebx, word ptr [edi + eax - 1]\n        mov edi, [edx + dsPrev]\n        mov [scanend], ebx\n        mov edx, [chainlenwmask]\n        jmp LookupLoop\n\n;;; Accept the current string, with the maximum possible length.\n\nLenMaximum: mov edx, [deflatestate]\n        mov dword ptr [bestlen], MAX_MATCH\n        mov [edx + dsMatchStart], ecx\n\n;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;\n;;; return s->lookahead;\n\nLeaveNow:\n        mov edx, [deflatestate]\n        mov ebx, [bestlen]\n        mov eax, [edx + dsLookahead]\n        cmp ebx, eax\n        jg  LookaheadRet\n        mov eax, ebx\nLookaheadRet:\n\n;;; Restore the stack and return from whence we came.\n\n        add esp, LocalVarsSize\n        pop ebx\n        pop esi\n        pop edi\n        pop ebp\n\n        ret\n; please don't remove this string !\n; Your can freely use match686 in any free or commercial app if you don't remove the string in the binary!\n    db     0dh,0ah,\"asm686 with masm, optimised assembly code from Brian Raiter, written 1998\",0dh,0ah\n\n\n    IFDEF NOUNDERLINE\n    longest_match       endp\n    ELSE\n    _longest_match      endp\n    ENDIF\n\n    IFDEF NOUNDERLINE\n    match_init      proc near\n                    ret\n    match_init      endp\n    ELSE\n    _match_init     proc near\n                    ret\n    _match_init     endp\n    ENDIF\n\n\n_TEXT   ends\nend\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/masmx86/readme.txt",
    "content": "\nSummary\n-------\nThis directory contains ASM implementations of the functions\nlongest_match() and inflate_fast().\n\n\nUse instructions\n----------------\nAssemble using MASM, and copy the object files into the zlib source\ndirectory, then run the appropriate makefile, as suggested below.  You can\ndonwload MASM from here:\n\n    http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64\n\nYou can also get objects files here:\n\n    http://www.winimage.com/zLibDll/zlib124_masm_obj.zip\n\nBuild instructions\n------------------\n* With Microsoft C and MASM:\nnmake -f win32/Makefile.msc LOC=\"-DASMV -DASMINF\" OBJA=\"match686.obj inffas32.obj\"\n\n* With Borland C and TASM:\nmake -f win32/Makefile.bor LOCAL_ZLIB=\"-DASMV -DASMINF\" OBJA=\"match686.obj inffas32.obj\" OBJPA=\"+match686c.obj+match686.obj+inffas32.obj\"\n\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/Makefile",
    "content": "CC=cc\nCFLAGS=-O -I../..\n\nUNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a\nZIP_OBJS = minizip.o zip.o   ioapi.o ../../libz.a\n\n.c.o:\n\t$(CC) -c $(CFLAGS) $*.c\n\nall: miniunz minizip\n\nminiunz:  $(UNZ_OBJS)\n\t$(CC) $(CFLAGS) -o $@ $(UNZ_OBJS)\n\nminizip:  $(ZIP_OBJS)\n\t$(CC) $(CFLAGS) -o $@ $(ZIP_OBJS)\n\ntest:\tminiunz minizip\n\t./minizip test readme.txt\n\t./miniunz -l test.zip\n\tmv readme.txt readme.old\n\t./miniunz test.zip\n\nclean:\n\t/bin/rm -f *.o *~ minizip miniunz\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/Makefile.am",
    "content": "lib_LTLIBRARIES = libminizip.la\n\nif COND_DEMOS\nbin_PROGRAMS = miniunzip minizip\nendif\n\nzlib_top_srcdir = $(top_srcdir)/../..\nzlib_top_builddir = $(top_builddir)/../..\n\nAM_CPPFLAGS = -I$(zlib_top_srcdir)\nAM_LDFLAGS = -L$(zlib_top_builddir)\n\nif WIN32\niowin32_src = iowin32.c\niowin32_h = iowin32.h\nendif\n\nlibminizip_la_SOURCES = \\\n\tioapi.c \\\n\tmztools.c \\\n\tunzip.c \\\n\tzip.c \\\n\t${iowin32_src}\n\nlibminizip_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0 -lz\n\nminizip_includedir = $(includedir)/minizip\nminizip_include_HEADERS = \\\n\tcrypt.h \\\n\tioapi.h \\\n\tmztools.h \\\n\tunzip.h \\\n\tzip.h \\\n\t${iowin32_h}\n\npkgconfigdir = $(libdir)/pkgconfig\npkgconfig_DATA = minizip.pc\n\nEXTRA_PROGRAMS = miniunzip minizip\n\nminiunzip_SOURCES = miniunz.c\nminiunzip_LDADD = libminizip.la\n\nminizip_SOURCES = minizip.c\nminizip_LDADD = libminizip.la -lz\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/MiniZip64_Changes.txt",
    "content": "\nMiniZip 1.1 was derrived from MiniZip at version 1.01f\n\nChange in 1.0 (Okt 2009)\n - **TODO - Add history**\n\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/MiniZip64_info.txt",
    "content": "MiniZip - Copyright (c) 1998-2010 - by Gilles Vollant - version 1.1 64 bits from Mathias Svensson\n\nIntroduction\n---------------------\nMiniZip 1.1 is built from MiniZip 1.0 by Gilles Vollant ( http://www.winimage.com/zLibDll/minizip.html )\n\nWhen adding ZIP64 support into minizip it would result into risk of breaking compatibility with minizip 1.0.\nAll possible work was done for compatibility.\n\n\nBackground\n---------------------\nWhen adding ZIP64 support Mathias Svensson found that Even Rouault have added ZIP64 \nsupport for unzip.c into minizip for a open source project called gdal ( http://www.gdal.org/ )\n\nThat was used as a starting point. And after that ZIP64 support was added to zip.c\nsome refactoring and code cleanup was also done.\n\n\nChanged from MiniZip 1.0 to MiniZip 1.1\n---------------------------------------\n* Added ZIP64 support for unzip ( by Even Rouault )\n* Added ZIP64 support for zip ( by Mathias Svensson )\n* Reverted some changed that Even Rouault did.\n* Bunch of patches received from Gulles Vollant that he received for MiniZip from various users.\n* Added unzip patch for BZIP Compression method (patch create by Daniel Borca)\n* Added BZIP Compress method for zip\n* Did some refactoring and code cleanup\n\n\nCredits\n\n Gilles Vollant    - Original MiniZip author\n Even Rouault      - ZIP64 unzip Support\n Daniel Borca      - BZip Compression method support in unzip\n Mathias Svensson  - ZIP64 zip support\n Mathias Svensson  - BZip Compression method support in zip\n\n Resources\n\n ZipLayout   http://result42.com/projects/ZipFileLayout\n             Command line tool for Windows that shows the layout and information of the headers in a zip archive.\n             Used when debugging and validating the creation of zip files using MiniZip64\n\n\n ZIP App Note  http://www.pkware.com/documents/casestudies/APPNOTE.TXT\n               Zip File specification\n\n\nNotes.\n * To be able to use BZip compression method in zip64.c or unzip64.c the BZIP2 lib is needed and HAVE_BZIP2 need to be defined.\n\nLicense\n----------------------------------------------------------\n   Condition of use and distribution are the same than zlib :\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n----------------------------------------------------------\n\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/configure.ac",
    "content": "#                                               -*- Autoconf -*-\n# Process this file with autoconf to produce a configure script.\n\nAC_INIT([minizip], [1.2.8], [bugzilla.redhat.com])\nAC_CONFIG_SRCDIR([minizip.c])\nAM_INIT_AUTOMAKE([foreign])\nLT_INIT\n\nAC_MSG_CHECKING([whether to build example programs])\nAC_ARG_ENABLE([demos], AC_HELP_STRING([--enable-demos], [build example programs]))\nAM_CONDITIONAL([COND_DEMOS], [test \"$enable_demos\" = yes])\nif test \"$enable_demos\" = yes\nthen\n\tAC_MSG_RESULT([yes])\nelse\n\tAC_MSG_RESULT([no])\nfi\n\ncase \"${host}\" in\n\t*-mingw* | mingw*)\n\t\tWIN32=\"yes\"\n\t\t;;\n\t*)\n\t\t;;\nesac\nAM_CONDITIONAL([WIN32], [test \"${WIN32}\" = \"yes\"])\n\n\nAC_SUBST([HAVE_UNISTD_H], [0])\nAC_CHECK_HEADER([unistd.h], [HAVE_UNISTD_H=1], [])\nAC_CONFIG_FILES([Makefile minizip.pc])\nAC_OUTPUT\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/crypt.h",
    "content": "/* crypt.h -- base code for crypt/uncrypt ZIPfile\n\n\n   Version 1.01e, February 12th, 2005\n\n   Copyright (C) 1998-2005 Gilles Vollant\n\n   This code is a modified version of crypting code in Infozip distribution\n\n   The encryption/decryption parts of this source code (as opposed to the\n   non-echoing password parts) were originally written in Europe.  The\n   whole source package can be freely distributed, including from the USA.\n   (Prior to January 2000, re-export from the US was a violation of US law.)\n\n   This encryption code is a direct transcription of the algorithm from\n   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This\n   file (appnote.txt) is distributed with the PKZIP program (even in the\n   version without encryption capabilities).\n\n   If you don't need crypting in your application, just define symbols\n   NOCRYPT and NOUNCRYPT.\n\n   This code support the \"Traditional PKWARE Encryption\".\n\n   The new AES encryption added on Zip format by Winzip (see the page\n   http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong\n   Encryption is not supported.\n*/\n\n#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))\n\n/***********************************************************************\n * Return the next byte in the pseudo-random sequence\n */\nstatic int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)\n{\n    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an\n                     * unpredictable manner on 16-bit systems; not a problem\n                     * with any known compiler so far, though */\n\n    temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;\n    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);\n}\n\n/***********************************************************************\n * Update the encryption keys with the next byte of plain text\n */\nstatic int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)\n{\n    (*(pkeys+0)) = CRC32((*(pkeys+0)), c);\n    (*(pkeys+1)) += (*(pkeys+0)) & 0xff;\n    (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;\n    {\n      register int keyshift = (int)((*(pkeys+1)) >> 24);\n      (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);\n    }\n    return c;\n}\n\n\n/***********************************************************************\n * Initialize the encryption keys and the random header according to\n * the given password.\n */\nstatic void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab)\n{\n    *(pkeys+0) = 305419896L;\n    *(pkeys+1) = 591751049L;\n    *(pkeys+2) = 878082192L;\n    while (*passwd != '\\0') {\n        update_keys(pkeys,pcrc_32_tab,(int)*passwd);\n        passwd++;\n    }\n}\n\n#define zdecode(pkeys,pcrc_32_tab,c) \\\n    (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))\n\n#define zencode(pkeys,pcrc_32_tab,c,t) \\\n    (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))\n\n#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED\n\n#define RAND_HEAD_LEN  12\n   /* \"last resort\" source for second part of crypt seed pattern */\n#  ifndef ZCR_SEED2\n#    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */\n#  endif\n\nstatic int crypthead(const char* passwd,      /* password string */\n                     unsigned char* buf,      /* where to write header */\n                     int bufSize,\n                     unsigned long* pkeys,\n                     const z_crc_t* pcrc_32_tab,\n                     unsigned long crcForCrypting)\n{\n    int n;                       /* index in random header */\n    int t;                       /* temporary */\n    int c;                       /* random byte */\n    unsigned char header[RAND_HEAD_LEN-2]; /* random header */\n    static unsigned calls = 0;   /* ensure different random header each time */\n\n    if (bufSize<RAND_HEAD_LEN)\n      return 0;\n\n    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the\n     * output of rand() to get less predictability, since rand() is\n     * often poorly implemented.\n     */\n    if (++calls == 1)\n    {\n        srand((unsigned)(time(NULL) ^ ZCR_SEED2));\n    }\n    init_keys(passwd, pkeys, pcrc_32_tab);\n    for (n = 0; n < RAND_HEAD_LEN-2; n++)\n    {\n        c = (rand() >> 7) & 0xff;\n        header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);\n    }\n    /* Encrypt random header (last two bytes is high word of crc) */\n    init_keys(passwd, pkeys, pcrc_32_tab);\n    for (n = 0; n < RAND_HEAD_LEN-2; n++)\n    {\n        buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);\n    }\n    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);\n    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);\n    return n;\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/ioapi.c",
    "content": "/* ioapi.h -- IO base function header for compress/uncompress .zip\n   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications for Zip64 support\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n\n         For more info read MiniZip_info.txt\n\n*/\n\n#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS)))\n        #define _CRT_SECURE_NO_WARNINGS\n#endif\n\n#if defined(__APPLE__) || defined(IOAPI_NO_64)\n// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions\n#define FOPEN_FUNC(filename, mode) fopen(filename, mode)\n#define FTELLO_FUNC(stream) ftello(stream)\n#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)\n#else\n#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)\n#define FTELLO_FUNC(stream) ftello64(stream)\n#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)\n#endif\n\n\n#include \"ioapi.h\"\n\nvoidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)\n{\n    if (pfilefunc->zfile_func64.zopen64_file != NULL)\n        return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);\n    else\n    {\n        return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);\n    }\n}\n\nlong call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)\n{\n    if (pfilefunc->zfile_func64.zseek64_file != NULL)\n        return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);\n    else\n    {\n        uLong offsetTruncated = (uLong)offset;\n        if (offsetTruncated != offset)\n            return -1;\n        else\n            return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);\n    }\n}\n\nZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)\n{\n    if (pfilefunc->zfile_func64.zseek64_file != NULL)\n        return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);\n    else\n    {\n        uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);\n        if ((tell_uLong) == MAXU32)\n            return (ZPOS64_T)-1;\n        else\n            return tell_uLong;\n    }\n}\n\nvoid fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)\n{\n    p_filefunc64_32->zfile_func64.zopen64_file = NULL;\n    p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;\n    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;\n    p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;\n    p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;\n    p_filefunc64_32->zfile_func64.ztell64_file = NULL;\n    p_filefunc64_32->zfile_func64.zseek64_file = NULL;\n    p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;\n    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;\n    p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;\n    p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;\n    p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;\n}\n\n\n\nstatic voidpf  ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));\nstatic uLong   ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));\nstatic uLong   ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));\nstatic ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));\nstatic long    ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));\nstatic int     ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));\nstatic int     ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));\n\nstatic voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)\n{\n    FILE* file = NULL;\n    const char* mode_fopen = NULL;\n    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)\n        mode_fopen = \"rb\";\n    else\n    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)\n        mode_fopen = \"r+b\";\n    else\n    if (mode & ZLIB_FILEFUNC_MODE_CREATE)\n        mode_fopen = \"wb\";\n\n    if ((filename!=NULL) && (mode_fopen != NULL))\n        file = fopen(filename, mode_fopen);\n    return file;\n}\n\nstatic voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)\n{\n    FILE* file = NULL;\n    const char* mode_fopen = NULL;\n    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)\n        mode_fopen = \"rb\";\n    else\n    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)\n        mode_fopen = \"r+b\";\n    else\n    if (mode & ZLIB_FILEFUNC_MODE_CREATE)\n        mode_fopen = \"wb\";\n\n    if ((filename!=NULL) && (mode_fopen != NULL))\n        file = FOPEN_FUNC((const char*)filename, mode_fopen);\n    return file;\n}\n\n\nstatic uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)\n{\n    uLong ret;\n    ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);\n    return ret;\n}\n\nstatic uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)\n{\n    uLong ret;\n    ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);\n    return ret;\n}\n\nstatic long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)\n{\n    long ret;\n    ret = ftell((FILE *)stream);\n    return ret;\n}\n\n\nstatic ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)\n{\n    ZPOS64_T ret;\n    ret = FTELLO_FUNC((FILE *)stream);\n    return ret;\n}\n\nstatic long ZCALLBACK fseek_file_func (voidpf  opaque, voidpf stream, uLong offset, int origin)\n{\n    int fseek_origin=0;\n    long ret;\n    switch (origin)\n    {\n    case ZLIB_FILEFUNC_SEEK_CUR :\n        fseek_origin = SEEK_CUR;\n        break;\n    case ZLIB_FILEFUNC_SEEK_END :\n        fseek_origin = SEEK_END;\n        break;\n    case ZLIB_FILEFUNC_SEEK_SET :\n        fseek_origin = SEEK_SET;\n        break;\n    default: return -1;\n    }\n    ret = 0;\n    if (fseek((FILE *)stream, offset, fseek_origin) != 0)\n        ret = -1;\n    return ret;\n}\n\nstatic long ZCALLBACK fseek64_file_func (voidpf  opaque, voidpf stream, ZPOS64_T offset, int origin)\n{\n    int fseek_origin=0;\n    long ret;\n    switch (origin)\n    {\n    case ZLIB_FILEFUNC_SEEK_CUR :\n        fseek_origin = SEEK_CUR;\n        break;\n    case ZLIB_FILEFUNC_SEEK_END :\n        fseek_origin = SEEK_END;\n        break;\n    case ZLIB_FILEFUNC_SEEK_SET :\n        fseek_origin = SEEK_SET;\n        break;\n    default: return -1;\n    }\n    ret = 0;\n\n    if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0)\n                        ret = -1;\n\n    return ret;\n}\n\n\nstatic int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)\n{\n    int ret;\n    ret = fclose((FILE *)stream);\n    return ret;\n}\n\nstatic int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)\n{\n    int ret;\n    ret = ferror((FILE *)stream);\n    return ret;\n}\n\nvoid fill_fopen_filefunc (pzlib_filefunc_def)\n  zlib_filefunc_def* pzlib_filefunc_def;\n{\n    pzlib_filefunc_def->zopen_file = fopen_file_func;\n    pzlib_filefunc_def->zread_file = fread_file_func;\n    pzlib_filefunc_def->zwrite_file = fwrite_file_func;\n    pzlib_filefunc_def->ztell_file = ftell_file_func;\n    pzlib_filefunc_def->zseek_file = fseek_file_func;\n    pzlib_filefunc_def->zclose_file = fclose_file_func;\n    pzlib_filefunc_def->zerror_file = ferror_file_func;\n    pzlib_filefunc_def->opaque = NULL;\n}\n\nvoid fill_fopen64_filefunc (zlib_filefunc64_def*  pzlib_filefunc_def)\n{\n    pzlib_filefunc_def->zopen64_file = fopen64_file_func;\n    pzlib_filefunc_def->zread_file = fread_file_func;\n    pzlib_filefunc_def->zwrite_file = fwrite_file_func;\n    pzlib_filefunc_def->ztell64_file = ftell64_file_func;\n    pzlib_filefunc_def->zseek64_file = fseek64_file_func;\n    pzlib_filefunc_def->zclose_file = fclose_file_func;\n    pzlib_filefunc_def->zerror_file = ferror_file_func;\n    pzlib_filefunc_def->opaque = NULL;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/ioapi.h",
    "content": "/* ioapi.h -- IO base function header for compress/uncompress .zip\n   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications for Zip64 support\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n\n         For more info read MiniZip_info.txt\n\n         Changes\n\n    Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)\n    Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.\n               More if/def section may be needed to support other platforms\n    Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.\n                          (but you should use iowin32.c for windows instead)\n\n*/\n\n#ifndef _ZLIBIOAPI64_H\n#define _ZLIBIOAPI64_H\n\n#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))\n\n  // Linux needs this to support file operation on files larger then 4+GB\n  // But might need better if/def to select just the platforms that needs them.\n\n        #ifndef __USE_FILE_OFFSET64\n                #define __USE_FILE_OFFSET64\n        #endif\n        #ifndef __USE_LARGEFILE64\n                #define __USE_LARGEFILE64\n        #endif\n        #ifndef _LARGEFILE64_SOURCE\n                #define _LARGEFILE64_SOURCE\n        #endif\n        #ifndef _FILE_OFFSET_BIT\n                #define _FILE_OFFSET_BIT 64\n        #endif\n\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include \"zlib.h\"\n\n#if defined(USE_FILE32API)\n#define fopen64 fopen\n#define ftello64 ftell\n#define fseeko64 fseek\n#else\n#ifdef __FreeBSD__\n#define fopen64 fopen\n#define ftello64 ftello\n#define fseeko64 fseeko\n#endif\n#ifdef _MSC_VER\n #define fopen64 fopen\n #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))\n  #define ftello64 _ftelli64\n  #define fseeko64 _fseeki64\n #else // old MSC\n  #define ftello64 ftell\n  #define fseeko64 fseek\n #endif\n#endif\n#endif\n\n/*\n#ifndef ZPOS64_T\n  #ifdef _WIN32\n                #define ZPOS64_T fpos_t\n  #else\n    #include <stdint.h>\n    #define ZPOS64_T uint64_t\n  #endif\n#endif\n*/\n\n#ifdef HAVE_MINIZIP64_CONF_H\n#include \"mz64conf.h\"\n#endif\n\n/* a type choosen by DEFINE */\n#ifdef HAVE_64BIT_INT_CUSTOM\ntypedef  64BIT_INT_CUSTOM_TYPE ZPOS64_T;\n#else\n#ifdef HAS_STDINT_H\n#include \"stdint.h\"\ntypedef uint64_t ZPOS64_T;\n#else\n\n/* Maximum unsigned 32-bit value used as placeholder for zip64 */\n#define MAXU32 0xffffffff\n\n#if defined(_MSC_VER) || defined(__BORLANDC__)\ntypedef unsigned __int64 ZPOS64_T;\n#else\ntypedef unsigned long long int ZPOS64_T;\n#endif\n#endif\n#endif\n\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n#define ZLIB_FILEFUNC_SEEK_CUR (1)\n#define ZLIB_FILEFUNC_SEEK_END (2)\n#define ZLIB_FILEFUNC_SEEK_SET (0)\n\n#define ZLIB_FILEFUNC_MODE_READ      (1)\n#define ZLIB_FILEFUNC_MODE_WRITE     (2)\n#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)\n\n#define ZLIB_FILEFUNC_MODE_EXISTING (4)\n#define ZLIB_FILEFUNC_MODE_CREATE   (8)\n\n\n#ifndef ZCALLBACK\n #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)\n   #define ZCALLBACK CALLBACK\n #else\n   #define ZCALLBACK\n #endif\n#endif\n\n\n\n\ntypedef voidpf   (ZCALLBACK *open_file_func)      OF((voidpf opaque, const char* filename, int mode));\ntypedef uLong    (ZCALLBACK *read_file_func)      OF((voidpf opaque, voidpf stream, void* buf, uLong size));\ntypedef uLong    (ZCALLBACK *write_file_func)     OF((voidpf opaque, voidpf stream, const void* buf, uLong size));\ntypedef int      (ZCALLBACK *close_file_func)     OF((voidpf opaque, voidpf stream));\ntypedef int      (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));\n\ntypedef long     (ZCALLBACK *tell_file_func)      OF((voidpf opaque, voidpf stream));\ntypedef long     (ZCALLBACK *seek_file_func)      OF((voidpf opaque, voidpf stream, uLong offset, int origin));\n\n\n/* here is the \"old\" 32 bits structure structure */\ntypedef struct zlib_filefunc_def_s\n{\n    open_file_func      zopen_file;\n    read_file_func      zread_file;\n    write_file_func     zwrite_file;\n    tell_file_func      ztell_file;\n    seek_file_func      zseek_file;\n    close_file_func     zclose_file;\n    testerror_file_func zerror_file;\n    voidpf              opaque;\n} zlib_filefunc_def;\n\ntypedef ZPOS64_T (ZCALLBACK *tell64_file_func)    OF((voidpf opaque, voidpf stream));\ntypedef long     (ZCALLBACK *seek64_file_func)    OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));\ntypedef voidpf   (ZCALLBACK *open64_file_func)    OF((voidpf opaque, const void* filename, int mode));\n\ntypedef struct zlib_filefunc64_def_s\n{\n    open64_file_func    zopen64_file;\n    read_file_func      zread_file;\n    write_file_func     zwrite_file;\n    tell64_file_func    ztell64_file;\n    seek64_file_func    zseek64_file;\n    close_file_func     zclose_file;\n    testerror_file_func zerror_file;\n    voidpf              opaque;\n} zlib_filefunc64_def;\n\nvoid fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));\nvoid fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));\n\n/* now internal definition, only for zip.c and unzip.h */\ntypedef struct zlib_filefunc64_32_def_s\n{\n    zlib_filefunc64_def zfile_func64;\n    open_file_func      zopen32_file;\n    tell_file_func      ztell32_file;\n    seek_file_func      zseek32_file;\n} zlib_filefunc64_32_def;\n\n\n#define ZREAD64(filefunc,filestream,buf,size)     ((*((filefunc).zfile_func64.zread_file))   ((filefunc).zfile_func64.opaque,filestream,buf,size))\n#define ZWRITE64(filefunc,filestream,buf,size)    ((*((filefunc).zfile_func64.zwrite_file))  ((filefunc).zfile_func64.opaque,filestream,buf,size))\n//#define ZTELL64(filefunc,filestream)            ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))\n//#define ZSEEK64(filefunc,filestream,pos,mode)   ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))\n#define ZCLOSE64(filefunc,filestream)             ((*((filefunc).zfile_func64.zclose_file))  ((filefunc).zfile_func64.opaque,filestream))\n#define ZERROR64(filefunc,filestream)             ((*((filefunc).zfile_func64.zerror_file))  ((filefunc).zfile_func64.opaque,filestream))\n\nvoidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));\nlong    call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));\nZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));\n\nvoid    fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);\n\n#define ZOPEN64(filefunc,filename,mode)         (call_zopen64((&(filefunc)),(filename),(mode)))\n#define ZTELL64(filefunc,filestream)            (call_ztell64((&(filefunc)),(filestream)))\n#define ZSEEK64(filefunc,filestream,pos,mode)   (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/iowin32.c",
    "content": "/* iowin32.c -- IO base function header for compress/uncompress .zip\n     Version 1.1, February 14h, 2010\n     part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications for Zip64 support\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n\n     For more info read MiniZip_info.txt\n\n*/\n\n#include <stdlib.h>\n\n#include \"zlib.h\"\n#include \"ioapi.h\"\n#include \"iowin32.h\"\n\n#ifndef INVALID_HANDLE_VALUE\n#define INVALID_HANDLE_VALUE (0xFFFFFFFF)\n#endif\n\n#ifndef INVALID_SET_FILE_POINTER\n#define INVALID_SET_FILE_POINTER ((DWORD)-1)\n#endif\n\n\n#if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API)))\n#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)\n#define IOWIN32_USING_WINRT_API 1\n#endif\n#endif\n\nvoidpf  ZCALLBACK win32_open_file_func  OF((voidpf opaque, const char* filename, int mode));\nuLong   ZCALLBACK win32_read_file_func  OF((voidpf opaque, voidpf stream, void* buf, uLong size));\nuLong   ZCALLBACK win32_write_file_func OF((voidpf opaque, voidpf stream, const void* buf, uLong size));\nZPOS64_T ZCALLBACK win32_tell64_file_func  OF((voidpf opaque, voidpf stream));\nlong    ZCALLBACK win32_seek64_file_func  OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));\nint     ZCALLBACK win32_close_file_func OF((voidpf opaque, voidpf stream));\nint     ZCALLBACK win32_error_file_func OF((voidpf opaque, voidpf stream));\n\ntypedef struct\n{\n    HANDLE hf;\n    int error;\n} WIN32FILE_IOWIN;\n\n\nstatic void win32_translate_open_mode(int mode,\n                                      DWORD* lpdwDesiredAccess,\n                                      DWORD* lpdwCreationDisposition,\n                                      DWORD* lpdwShareMode,\n                                      DWORD* lpdwFlagsAndAttributes)\n{\n    *lpdwDesiredAccess = *lpdwShareMode = *lpdwFlagsAndAttributes = *lpdwCreationDisposition = 0;\n\n    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)\n    {\n        *lpdwDesiredAccess = GENERIC_READ;\n        *lpdwCreationDisposition = OPEN_EXISTING;\n        *lpdwShareMode = FILE_SHARE_READ;\n    }\n    else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)\n    {\n        *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;\n        *lpdwCreationDisposition = OPEN_EXISTING;\n    }\n    else if (mode & ZLIB_FILEFUNC_MODE_CREATE)\n    {\n        *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;\n        *lpdwCreationDisposition = CREATE_ALWAYS;\n    }\n}\n\nstatic voidpf win32_build_iowin(HANDLE hFile)\n{\n    voidpf ret=NULL;\n\n    if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))\n    {\n        WIN32FILE_IOWIN w32fiow;\n        w32fiow.hf = hFile;\n        w32fiow.error = 0;\n        ret = malloc(sizeof(WIN32FILE_IOWIN));\n\n        if (ret==NULL)\n            CloseHandle(hFile);\n        else\n            *((WIN32FILE_IOWIN*)ret) = w32fiow;\n    }\n    return ret;\n}\n\nvoidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int mode)\n{\n    const char* mode_fopen = NULL;\n    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;\n    HANDLE hFile = NULL;\n\n    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);\n\n#ifdef IOWIN32_USING_WINRT_API\n#ifdef UNICODE\n    if ((filename!=NULL) && (dwDesiredAccess != 0))\n        hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);\n#else\n    if ((filename!=NULL) && (dwDesiredAccess != 0))\n    {\n        WCHAR filenameW[FILENAME_MAX + 0x200 + 1];\n        MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);\n        hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);\n    }\n#endif\n#else\n    if ((filename!=NULL) && (dwDesiredAccess != 0))\n        hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);\n#endif\n\n    return win32_build_iowin(hFile);\n}\n\n\nvoidpf ZCALLBACK win32_open64_file_funcA (voidpf opaque,const void* filename,int mode)\n{\n    const char* mode_fopen = NULL;\n    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;\n    HANDLE hFile = NULL;\n\n    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);\n\n#ifdef IOWIN32_USING_WINRT_API\n    if ((filename!=NULL) && (dwDesiredAccess != 0))\n    {\n        WCHAR filenameW[FILENAME_MAX + 0x200 + 1];\n        MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);\n        hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);\n    }\n#else\n    if ((filename!=NULL) && (dwDesiredAccess != 0))\n        hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);\n#endif\n\n    return win32_build_iowin(hFile);\n}\n\n\nvoidpf ZCALLBACK win32_open64_file_funcW (voidpf opaque,const void* filename,int mode)\n{\n    const char* mode_fopen = NULL;\n    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;\n    HANDLE hFile = NULL;\n\n    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);\n\n#ifdef IOWIN32_USING_WINRT_API\n    if ((filename!=NULL) && (dwDesiredAccess != 0))\n        hFile = CreateFile2((LPCWSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition,NULL);\n#else\n    if ((filename!=NULL) && (dwDesiredAccess != 0))\n        hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);\n#endif\n\n    return win32_build_iowin(hFile);\n}\n\n\nvoidpf ZCALLBACK win32_open_file_func (voidpf opaque,const char* filename,int mode)\n{\n    const char* mode_fopen = NULL;\n    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;\n    HANDLE hFile = NULL;\n\n    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);\n\n#ifdef IOWIN32_USING_WINRT_API\n#ifdef UNICODE\n    if ((filename!=NULL) && (dwDesiredAccess != 0))\n        hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);\n#else\n    if ((filename!=NULL) && (dwDesiredAccess != 0))\n    {\n        WCHAR filenameW[FILENAME_MAX + 0x200 + 1];\n        MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);\n        hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);\n    }\n#endif\n#else\n    if ((filename!=NULL) && (dwDesiredAccess != 0))\n        hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);\n#endif\n\n    return win32_build_iowin(hFile);\n}\n\n\nuLong ZCALLBACK win32_read_file_func (voidpf opaque, voidpf stream, void* buf,uLong size)\n{\n    uLong ret=0;\n    HANDLE hFile = NULL;\n    if (stream!=NULL)\n        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;\n\n    if (hFile != NULL)\n    {\n        if (!ReadFile(hFile, buf, size, &ret, NULL))\n        {\n            DWORD dwErr = GetLastError();\n            if (dwErr == ERROR_HANDLE_EOF)\n                dwErr = 0;\n            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;\n        }\n    }\n\n    return ret;\n}\n\n\nuLong ZCALLBACK win32_write_file_func (voidpf opaque,voidpf stream,const void* buf,uLong size)\n{\n    uLong ret=0;\n    HANDLE hFile = NULL;\n    if (stream!=NULL)\n        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;\n\n    if (hFile != NULL)\n    {\n        if (!WriteFile(hFile, buf, size, &ret, NULL))\n        {\n            DWORD dwErr = GetLastError();\n            if (dwErr == ERROR_HANDLE_EOF)\n                dwErr = 0;\n            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;\n        }\n    }\n\n    return ret;\n}\n\nstatic BOOL MySetFilePointerEx(HANDLE hFile, LARGE_INTEGER pos, LARGE_INTEGER *newPos,  DWORD dwMoveMethod)\n{\n#ifdef IOWIN32_USING_WINRT_API\n    return SetFilePointerEx(hFile, pos, newPos, dwMoveMethod);\n#else\n    LONG lHigh = pos.HighPart;\n    DWORD dwNewPos = SetFilePointer(hFile, pos.LowPart, &lHigh, FILE_CURRENT);\n    BOOL fOk = TRUE;\n    if (dwNewPos == 0xFFFFFFFF)\n        if (GetLastError() != NO_ERROR)\n            fOk = FALSE;\n    if ((newPos != NULL) && (fOk))\n    {\n        newPos->LowPart = dwNewPos;\n        newPos->HighPart = lHigh;\n    }\n    return fOk;\n#endif\n}\n\nlong ZCALLBACK win32_tell_file_func (voidpf opaque,voidpf stream)\n{\n    long ret=-1;\n    HANDLE hFile = NULL;\n    if (stream!=NULL)\n        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;\n    if (hFile != NULL)\n    {\n        LARGE_INTEGER pos;\n        pos.QuadPart = 0;\n\n        if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT))\n        {\n            DWORD dwErr = GetLastError();\n            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;\n            ret = -1;\n        }\n        else\n            ret=(long)pos.LowPart;\n    }\n    return ret;\n}\n\nZPOS64_T ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream)\n{\n    ZPOS64_T ret= (ZPOS64_T)-1;\n    HANDLE hFile = NULL;\n    if (stream!=NULL)\n        hFile = ((WIN32FILE_IOWIN*)stream)->hf;\n\n    if (hFile)\n    {\n        LARGE_INTEGER pos;\n        pos.QuadPart = 0;\n\n        if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT))\n        {\n            DWORD dwErr = GetLastError();\n            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;\n            ret = (ZPOS64_T)-1;\n        }\n        else\n            ret=pos.QuadPart;\n    }\n    return ret;\n}\n\n\nlong ZCALLBACK win32_seek_file_func (voidpf opaque,voidpf stream,uLong offset,int origin)\n{\n    DWORD dwMoveMethod=0xFFFFFFFF;\n    HANDLE hFile = NULL;\n\n    long ret=-1;\n    if (stream!=NULL)\n        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;\n    switch (origin)\n    {\n    case ZLIB_FILEFUNC_SEEK_CUR :\n        dwMoveMethod = FILE_CURRENT;\n        break;\n    case ZLIB_FILEFUNC_SEEK_END :\n        dwMoveMethod = FILE_END;\n        break;\n    case ZLIB_FILEFUNC_SEEK_SET :\n        dwMoveMethod = FILE_BEGIN;\n        break;\n    default: return -1;\n    }\n\n    if (hFile != NULL)\n    {\n        LARGE_INTEGER pos;\n        pos.QuadPart = offset;\n        if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod))\n        {\n            DWORD dwErr = GetLastError();\n            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;\n            ret = -1;\n        }\n        else\n            ret=0;\n    }\n    return ret;\n}\n\nlong ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream,ZPOS64_T offset,int origin)\n{\n    DWORD dwMoveMethod=0xFFFFFFFF;\n    HANDLE hFile = NULL;\n    long ret=-1;\n\n    if (stream!=NULL)\n        hFile = ((WIN32FILE_IOWIN*)stream)->hf;\n\n    switch (origin)\n    {\n        case ZLIB_FILEFUNC_SEEK_CUR :\n            dwMoveMethod = FILE_CURRENT;\n            break;\n        case ZLIB_FILEFUNC_SEEK_END :\n            dwMoveMethod = FILE_END;\n            break;\n        case ZLIB_FILEFUNC_SEEK_SET :\n            dwMoveMethod = FILE_BEGIN;\n            break;\n        default: return -1;\n    }\n\n    if (hFile)\n    {\n        LARGE_INTEGER pos;\n        pos.QuadPart = offset;\n        if (!MySetFilePointerEx(hFile, pos, NULL, FILE_CURRENT))\n        {\n            DWORD dwErr = GetLastError();\n            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;\n            ret = -1;\n        }\n        else\n            ret=0;\n    }\n    return ret;\n}\n\nint ZCALLBACK win32_close_file_func (voidpf opaque, voidpf stream)\n{\n    int ret=-1;\n\n    if (stream!=NULL)\n    {\n        HANDLE hFile;\n        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;\n        if (hFile != NULL)\n        {\n            CloseHandle(hFile);\n            ret=0;\n        }\n        free(stream);\n    }\n    return ret;\n}\n\nint ZCALLBACK win32_error_file_func (voidpf opaque,voidpf stream)\n{\n    int ret=-1;\n    if (stream!=NULL)\n    {\n        ret = ((WIN32FILE_IOWIN*)stream) -> error;\n    }\n    return ret;\n}\n\nvoid fill_win32_filefunc (zlib_filefunc_def* pzlib_filefunc_def)\n{\n    pzlib_filefunc_def->zopen_file = win32_open_file_func;\n    pzlib_filefunc_def->zread_file = win32_read_file_func;\n    pzlib_filefunc_def->zwrite_file = win32_write_file_func;\n    pzlib_filefunc_def->ztell_file = win32_tell_file_func;\n    pzlib_filefunc_def->zseek_file = win32_seek_file_func;\n    pzlib_filefunc_def->zclose_file = win32_close_file_func;\n    pzlib_filefunc_def->zerror_file = win32_error_file_func;\n    pzlib_filefunc_def->opaque = NULL;\n}\n\nvoid fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def)\n{\n    pzlib_filefunc_def->zopen64_file = win32_open64_file_func;\n    pzlib_filefunc_def->zread_file = win32_read_file_func;\n    pzlib_filefunc_def->zwrite_file = win32_write_file_func;\n    pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;\n    pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;\n    pzlib_filefunc_def->zclose_file = win32_close_file_func;\n    pzlib_filefunc_def->zerror_file = win32_error_file_func;\n    pzlib_filefunc_def->opaque = NULL;\n}\n\n\nvoid fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def)\n{\n    pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA;\n    pzlib_filefunc_def->zread_file = win32_read_file_func;\n    pzlib_filefunc_def->zwrite_file = win32_write_file_func;\n    pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;\n    pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;\n    pzlib_filefunc_def->zclose_file = win32_close_file_func;\n    pzlib_filefunc_def->zerror_file = win32_error_file_func;\n    pzlib_filefunc_def->opaque = NULL;\n}\n\n\nvoid fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def)\n{\n    pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW;\n    pzlib_filefunc_def->zread_file = win32_read_file_func;\n    pzlib_filefunc_def->zwrite_file = win32_write_file_func;\n    pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;\n    pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;\n    pzlib_filefunc_def->zclose_file = win32_close_file_func;\n    pzlib_filefunc_def->zerror_file = win32_error_file_func;\n    pzlib_filefunc_def->opaque = NULL;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/iowin32.h",
    "content": "/* iowin32.h -- IO base function header for compress/uncompress .zip\n     Version 1.1, February 14h, 2010\n     part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications for Zip64 support\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n\n         For more info read MiniZip_info.txt\n\n*/\n\n#include <windows.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nvoid fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));\nvoid fill_win32_filefunc64 OF((zlib_filefunc64_def* pzlib_filefunc_def));\nvoid fill_win32_filefunc64A OF((zlib_filefunc64_def* pzlib_filefunc_def));\nvoid fill_win32_filefunc64W OF((zlib_filefunc64_def* pzlib_filefunc_def));\n\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/make_vms.com",
    "content": "$ if f$search(\"ioapi.h_orig\") .eqs. \"\" then copy ioapi.h ioapi.h_orig\n$ open/write zdef vmsdefs.h\n$ copy sys$input: zdef\n$ deck\n#define unix\n#define fill_zlib_filefunc64_32_def_from_filefunc32 fillzffunc64from\n#define Write_Zip64EndOfCentralDirectoryLocator Write_Zip64EoDLocator\n#define Write_Zip64EndOfCentralDirectoryRecord Write_Zip64EoDRecord\n#define Write_EndOfCentralDirectoryRecord Write_EoDRecord\n$ eod\n$ close zdef\n$ copy vmsdefs.h,ioapi.h_orig ioapi.h\n$ cc/include=[--]/prefix=all ioapi.c\n$ cc/include=[--]/prefix=all miniunz.c\n$ cc/include=[--]/prefix=all unzip.c\n$ cc/include=[--]/prefix=all minizip.c\n$ cc/include=[--]/prefix=all zip.c\n$ link miniunz,unzip,ioapi,[--]libz.olb/lib\n$ link minizip,zip,ioapi,[--]libz.olb/lib\n$ mcr []minizip test minizip_info.txt\n$ mcr []miniunz -l test.zip\n$ rename minizip_info.txt; minizip_info.txt_old\n$ mcr []miniunz test.zip\n$ delete test.zip;*\n$exit\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/miniunz.c",
    "content": "/*\n   miniunz.c\n   Version 1.1, February 14h, 2010\n   sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications of Unzip for Zip64\n         Copyright (C) 2007-2008 Even Rouault\n\n         Modifications for Zip64 support on both zip and unzip\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n*/\n\n#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))\n        #ifndef __USE_FILE_OFFSET64\n                #define __USE_FILE_OFFSET64\n        #endif\n        #ifndef __USE_LARGEFILE64\n                #define __USE_LARGEFILE64\n        #endif\n        #ifndef _LARGEFILE64_SOURCE\n                #define _LARGEFILE64_SOURCE\n        #endif\n        #ifndef _FILE_OFFSET_BIT\n                #define _FILE_OFFSET_BIT 64\n        #endif\n#endif\n\n#ifdef __APPLE__\n// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions\n#define FOPEN_FUNC(filename, mode) fopen(filename, mode)\n#define FTELLO_FUNC(stream) ftello(stream)\n#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)\n#else\n#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)\n#define FTELLO_FUNC(stream) ftello64(stream)\n#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)\n#endif\n\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <errno.h>\n#include <fcntl.h>\n\n#ifdef _WIN32\n# include <direct.h>\n# include <io.h>\n#else\n# include <unistd.h>\n# include <utime.h>\n#endif\n\n\n#include \"unzip.h\"\n\n#define CASESENSITIVITY (0)\n#define WRITEBUFFERSIZE (8192)\n#define MAXFILENAME (256)\n\n#ifdef _WIN32\n#define USEWIN32IOAPI\n#include \"iowin32.h\"\n#endif\n/*\n  mini unzip, demo of unzip package\n\n  usage :\n  Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]\n\n  list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT\n    if it exists\n*/\n\n\n/* change_file_date : change the date/time of a file\n    filename : the filename of the file where date/time must be modified\n    dosdate : the new date at the MSDos format (4 bytes)\n    tmu_date : the SAME new date at the tm_unz format */\nvoid change_file_date(filename,dosdate,tmu_date)\n    const char *filename;\n    uLong dosdate;\n    tm_unz tmu_date;\n{\n#ifdef _WIN32\n  HANDLE hFile;\n  FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;\n\n  hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE,\n                      0,NULL,OPEN_EXISTING,0,NULL);\n  GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);\n  DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);\n  LocalFileTimeToFileTime(&ftLocal,&ftm);\n  SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);\n  CloseHandle(hFile);\n#else\n#ifdef unix || __APPLE__\n  struct utimbuf ut;\n  struct tm newdate;\n  newdate.tm_sec = tmu_date.tm_sec;\n  newdate.tm_min=tmu_date.tm_min;\n  newdate.tm_hour=tmu_date.tm_hour;\n  newdate.tm_mday=tmu_date.tm_mday;\n  newdate.tm_mon=tmu_date.tm_mon;\n  if (tmu_date.tm_year > 1900)\n      newdate.tm_year=tmu_date.tm_year - 1900;\n  else\n      newdate.tm_year=tmu_date.tm_year ;\n  newdate.tm_isdst=-1;\n\n  ut.actime=ut.modtime=mktime(&newdate);\n  utime(filename,&ut);\n#endif\n#endif\n}\n\n\n/* mymkdir and change_file_date are not 100 % portable\n   As I don't know well Unix, I wait feedback for the unix portion */\n\nint mymkdir(dirname)\n    const char* dirname;\n{\n    int ret=0;\n#ifdef _WIN32\n    ret = _mkdir(dirname);\n#elif unix\n    ret = mkdir (dirname,0775);\n#elif __APPLE__\n    ret = mkdir (dirname,0775);\n#endif\n    return ret;\n}\n\nint makedir (newdir)\n    char *newdir;\n{\n  char *buffer ;\n  char *p;\n  int  len = (int)strlen(newdir);\n\n  if (len <= 0)\n    return 0;\n\n  buffer = (char*)malloc(len+1);\n        if (buffer==NULL)\n        {\n                printf(\"Error allocating memory\\n\");\n                return UNZ_INTERNALERROR;\n        }\n  strcpy(buffer,newdir);\n\n  if (buffer[len-1] == '/') {\n    buffer[len-1] = '\\0';\n  }\n  if (mymkdir(buffer) == 0)\n    {\n      free(buffer);\n      return 1;\n    }\n\n  p = buffer+1;\n  while (1)\n    {\n      char hold;\n\n      while(*p && *p != '\\\\' && *p != '/')\n        p++;\n      hold = *p;\n      *p = 0;\n      if ((mymkdir(buffer) == -1) && (errno == ENOENT))\n        {\n          printf(\"couldn't create directory %s\\n\",buffer);\n          free(buffer);\n          return 0;\n        }\n      if (hold == 0)\n        break;\n      *p++ = hold;\n    }\n  free(buffer);\n  return 1;\n}\n\nvoid do_banner()\n{\n    printf(\"MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\\n\");\n    printf(\"more info at http://www.winimage.com/zLibDll/unzip.html\\n\\n\");\n}\n\nvoid do_help()\n{\n    printf(\"Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\\n\\n\" \\\n           \"  -e  Extract without pathname (junk paths)\\n\" \\\n           \"  -x  Extract with pathname\\n\" \\\n           \"  -v  list files\\n\" \\\n           \"  -l  list files\\n\" \\\n           \"  -d  directory to extract into\\n\" \\\n           \"  -o  overwrite files without prompting\\n\" \\\n           \"  -p  extract crypted file using password\\n\\n\");\n}\n\nvoid Display64BitsSize(ZPOS64_T n, int size_char)\n{\n  /* to avoid compatibility problem , we do here the conversion */\n  char number[21];\n  int offset=19;\n  int pos_string = 19;\n  number[20]=0;\n  for (;;) {\n      number[offset]=(char)((n%10)+'0');\n      if (number[offset] != '0')\n          pos_string=offset;\n      n/=10;\n      if (offset==0)\n          break;\n      offset--;\n  }\n  {\n      int size_display_string = 19-pos_string;\n      while (size_char > size_display_string)\n      {\n          size_char--;\n          printf(\" \");\n      }\n  }\n\n  printf(\"%s\",&number[pos_string]);\n}\n\nint do_list(uf)\n    unzFile uf;\n{\n    uLong i;\n    unz_global_info64 gi;\n    int err;\n\n    err = unzGetGlobalInfo64(uf,&gi);\n    if (err!=UNZ_OK)\n        printf(\"error %d with zipfile in unzGetGlobalInfo \\n\",err);\n    printf(\"  Length  Method     Size Ratio   Date    Time   CRC-32     Name\\n\");\n    printf(\"  ------  ------     ---- -----   ----    ----   ------     ----\\n\");\n    for (i=0;i<gi.number_entry;i++)\n    {\n        char filename_inzip[256];\n        unz_file_info64 file_info;\n        uLong ratio=0;\n        const char *string_method;\n        char charCrypt=' ';\n        err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);\n        if (err!=UNZ_OK)\n        {\n            printf(\"error %d with zipfile in unzGetCurrentFileInfo\\n\",err);\n            break;\n        }\n        if (file_info.uncompressed_size>0)\n            ratio = (uLong)((file_info.compressed_size*100)/file_info.uncompressed_size);\n\n        /* display a '*' if the file is crypted */\n        if ((file_info.flag & 1) != 0)\n            charCrypt='*';\n\n        if (file_info.compression_method==0)\n            string_method=\"Stored\";\n        else\n        if (file_info.compression_method==Z_DEFLATED)\n        {\n            uInt iLevel=(uInt)((file_info.flag & 0x6)/2);\n            if (iLevel==0)\n              string_method=\"Defl:N\";\n            else if (iLevel==1)\n              string_method=\"Defl:X\";\n            else if ((iLevel==2) || (iLevel==3))\n              string_method=\"Defl:F\"; /* 2:fast , 3 : extra fast*/\n        }\n        else\n        if (file_info.compression_method==Z_BZIP2ED)\n        {\n              string_method=\"BZip2 \";\n        }\n        else\n            string_method=\"Unkn. \";\n\n        Display64BitsSize(file_info.uncompressed_size,7);\n        printf(\"  %6s%c\",string_method,charCrypt);\n        Display64BitsSize(file_info.compressed_size,7);\n        printf(\" %3lu%%  %2.2lu-%2.2lu-%2.2lu  %2.2lu:%2.2lu  %8.8lx   %s\\n\",\n                ratio,\n                (uLong)file_info.tmu_date.tm_mon + 1,\n                (uLong)file_info.tmu_date.tm_mday,\n                (uLong)file_info.tmu_date.tm_year % 100,\n                (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,\n                (uLong)file_info.crc,filename_inzip);\n        if ((i+1)<gi.number_entry)\n        {\n            err = unzGoToNextFile(uf);\n            if (err!=UNZ_OK)\n            {\n                printf(\"error %d with zipfile in unzGoToNextFile\\n\",err);\n                break;\n            }\n        }\n    }\n\n    return 0;\n}\n\n\nint do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)\n    unzFile uf;\n    const int* popt_extract_without_path;\n    int* popt_overwrite;\n    const char* password;\n{\n    char filename_inzip[256];\n    char* filename_withoutpath;\n    char* p;\n    int err=UNZ_OK;\n    FILE *fout=NULL;\n    void* buf;\n    uInt size_buf;\n\n    unz_file_info64 file_info;\n    uLong ratio=0;\n    err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);\n\n    if (err!=UNZ_OK)\n    {\n        printf(\"error %d with zipfile in unzGetCurrentFileInfo\\n\",err);\n        return err;\n    }\n\n    size_buf = WRITEBUFFERSIZE;\n    buf = (void*)malloc(size_buf);\n    if (buf==NULL)\n    {\n        printf(\"Error allocating memory\\n\");\n        return UNZ_INTERNALERROR;\n    }\n\n    p = filename_withoutpath = filename_inzip;\n    while ((*p) != '\\0')\n    {\n        if (((*p)=='/') || ((*p)=='\\\\'))\n            filename_withoutpath = p+1;\n        p++;\n    }\n\n    if ((*filename_withoutpath)=='\\0')\n    {\n        if ((*popt_extract_without_path)==0)\n        {\n            printf(\"creating directory: %s\\n\",filename_inzip);\n            mymkdir(filename_inzip);\n        }\n    }\n    else\n    {\n        const char* write_filename;\n        int skip=0;\n\n        if ((*popt_extract_without_path)==0)\n            write_filename = filename_inzip;\n        else\n            write_filename = filename_withoutpath;\n\n        err = unzOpenCurrentFilePassword(uf,password);\n        if (err!=UNZ_OK)\n        {\n            printf(\"error %d with zipfile in unzOpenCurrentFilePassword\\n\",err);\n        }\n\n        if (((*popt_overwrite)==0) && (err==UNZ_OK))\n        {\n            char rep=0;\n            FILE* ftestexist;\n            ftestexist = FOPEN_FUNC(write_filename,\"rb\");\n            if (ftestexist!=NULL)\n            {\n                fclose(ftestexist);\n                do\n                {\n                    char answer[128];\n                    int ret;\n\n                    printf(\"The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: \",write_filename);\n                    ret = scanf(\"%1s\",answer);\n                    if (ret != 1)\n                    {\n                       exit(EXIT_FAILURE);\n                    }\n                    rep = answer[0] ;\n                    if ((rep>='a') && (rep<='z'))\n                        rep -= 0x20;\n                }\n                while ((rep!='Y') && (rep!='N') && (rep!='A'));\n            }\n\n            if (rep == 'N')\n                skip = 1;\n\n            if (rep == 'A')\n                *popt_overwrite=1;\n        }\n\n        if ((skip==0) && (err==UNZ_OK))\n        {\n            fout=FOPEN_FUNC(write_filename,\"wb\");\n            /* some zipfile don't contain directory alone before file */\n            if ((fout==NULL) && ((*popt_extract_without_path)==0) &&\n                                (filename_withoutpath!=(char*)filename_inzip))\n            {\n                char c=*(filename_withoutpath-1);\n                *(filename_withoutpath-1)='\\0';\n                makedir(write_filename);\n                *(filename_withoutpath-1)=c;\n                fout=FOPEN_FUNC(write_filename,\"wb\");\n            }\n\n            if (fout==NULL)\n            {\n                printf(\"error opening %s\\n\",write_filename);\n            }\n        }\n\n        if (fout!=NULL)\n        {\n            printf(\" extracting: %s\\n\",write_filename);\n\n            do\n            {\n                err = unzReadCurrentFile(uf,buf,size_buf);\n                if (err<0)\n                {\n                    printf(\"error %d with zipfile in unzReadCurrentFile\\n\",err);\n                    break;\n                }\n                if (err>0)\n                    if (fwrite(buf,err,1,fout)!=1)\n                    {\n                        printf(\"error in writing extracted file\\n\");\n                        err=UNZ_ERRNO;\n                        break;\n                    }\n            }\n            while (err>0);\n            if (fout)\n                    fclose(fout);\n\n            if (err==0)\n                change_file_date(write_filename,file_info.dosDate,\n                                 file_info.tmu_date);\n        }\n\n        if (err==UNZ_OK)\n        {\n            err = unzCloseCurrentFile (uf);\n            if (err!=UNZ_OK)\n            {\n                printf(\"error %d with zipfile in unzCloseCurrentFile\\n\",err);\n            }\n        }\n        else\n            unzCloseCurrentFile(uf); /* don't lose the error */\n    }\n\n    free(buf);\n    return err;\n}\n\n\nint do_extract(uf,opt_extract_without_path,opt_overwrite,password)\n    unzFile uf;\n    int opt_extract_without_path;\n    int opt_overwrite;\n    const char* password;\n{\n    uLong i;\n    unz_global_info64 gi;\n    int err;\n    FILE* fout=NULL;\n\n    err = unzGetGlobalInfo64(uf,&gi);\n    if (err!=UNZ_OK)\n        printf(\"error %d with zipfile in unzGetGlobalInfo \\n\",err);\n\n    for (i=0;i<gi.number_entry;i++)\n    {\n        if (do_extract_currentfile(uf,&opt_extract_without_path,\n                                      &opt_overwrite,\n                                      password) != UNZ_OK)\n            break;\n\n        if ((i+1)<gi.number_entry)\n        {\n            err = unzGoToNextFile(uf);\n            if (err!=UNZ_OK)\n            {\n                printf(\"error %d with zipfile in unzGoToNextFile\\n\",err);\n                break;\n            }\n        }\n    }\n\n    return 0;\n}\n\nint do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)\n    unzFile uf;\n    const char* filename;\n    int opt_extract_without_path;\n    int opt_overwrite;\n    const char* password;\n{\n    int err = UNZ_OK;\n    if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)\n    {\n        printf(\"file %s not found in the zipfile\\n\",filename);\n        return 2;\n    }\n\n    if (do_extract_currentfile(uf,&opt_extract_without_path,\n                                      &opt_overwrite,\n                                      password) == UNZ_OK)\n        return 0;\n    else\n        return 1;\n}\n\n\nint main(argc,argv)\n    int argc;\n    char *argv[];\n{\n    const char *zipfilename=NULL;\n    const char *filename_to_extract=NULL;\n    const char *password=NULL;\n    char filename_try[MAXFILENAME+16] = \"\";\n    int i;\n    int ret_value=0;\n    int opt_do_list=0;\n    int opt_do_extract=1;\n    int opt_do_extract_withoutpath=0;\n    int opt_overwrite=0;\n    int opt_extractdir=0;\n    const char *dirname=NULL;\n    unzFile uf=NULL;\n\n    do_banner();\n    if (argc==1)\n    {\n        do_help();\n        return 0;\n    }\n    else\n    {\n        for (i=1;i<argc;i++)\n        {\n            if ((*argv[i])=='-')\n            {\n                const char *p=argv[i]+1;\n\n                while ((*p)!='\\0')\n                {\n                    char c=*(p++);;\n                    if ((c=='l') || (c=='L'))\n                        opt_do_list = 1;\n                    if ((c=='v') || (c=='V'))\n                        opt_do_list = 1;\n                    if ((c=='x') || (c=='X'))\n                        opt_do_extract = 1;\n                    if ((c=='e') || (c=='E'))\n                        opt_do_extract = opt_do_extract_withoutpath = 1;\n                    if ((c=='o') || (c=='O'))\n                        opt_overwrite=1;\n                    if ((c=='d') || (c=='D'))\n                    {\n                        opt_extractdir=1;\n                        dirname=argv[i+1];\n                    }\n\n                    if (((c=='p') || (c=='P')) && (i+1<argc))\n                    {\n                        password=argv[i+1];\n                        i++;\n                    }\n                }\n            }\n            else\n            {\n                if (zipfilename == NULL)\n                    zipfilename = argv[i];\n                else if ((filename_to_extract==NULL) && (!opt_extractdir))\n                        filename_to_extract = argv[i] ;\n            }\n        }\n    }\n\n    if (zipfilename!=NULL)\n    {\n\n#        ifdef USEWIN32IOAPI\n        zlib_filefunc64_def ffunc;\n#        endif\n\n        strncpy(filename_try, zipfilename,MAXFILENAME-1);\n        /* strncpy doesnt append the trailing NULL, of the string is too long. */\n        filename_try[ MAXFILENAME ] = '\\0';\n\n#        ifdef USEWIN32IOAPI\n        fill_win32_filefunc64A(&ffunc);\n        uf = unzOpen2_64(zipfilename,&ffunc);\n#        else\n        uf = unzOpen64(zipfilename);\n#        endif\n        if (uf==NULL)\n        {\n            strcat(filename_try,\".zip\");\n#            ifdef USEWIN32IOAPI\n            uf = unzOpen2_64(filename_try,&ffunc);\n#            else\n            uf = unzOpen64(filename_try);\n#            endif\n        }\n    }\n\n    if (uf==NULL)\n    {\n        printf(\"Cannot open %s or %s.zip\\n\",zipfilename,zipfilename);\n        return 1;\n    }\n    printf(\"%s opened\\n\",filename_try);\n\n    if (opt_do_list==1)\n        ret_value = do_list(uf);\n    else if (opt_do_extract==1)\n    {\n#ifdef _WIN32\n        if (opt_extractdir && _chdir(dirname))\n#else\n        if (opt_extractdir && chdir(dirname))\n#endif\n        {\n          printf(\"Error changing into %s, aborting\\n\", dirname);\n          exit(-1);\n        }\n\n        if (filename_to_extract == NULL)\n            ret_value = do_extract(uf, opt_do_extract_withoutpath, opt_overwrite, password);\n        else\n            ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);\n    }\n\n    unzClose(uf);\n\n    return ret_value;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/miniunzip.1",
    "content": ".\\\"                                      Hey, EMACS: -*- nroff -*-\n.TH miniunzip 1 \"Nov 7, 2001\"\n.\\\" Please adjust this date whenever revising the manpage.\n.\\\"\n.\\\" Some roff macros, for reference:\n.\\\" .nh        disable hyphenation\n.\\\" .hy        enable hyphenation\n.\\\" .ad l      left justify\n.\\\" .ad b      justify to both left and right margins\n.\\\" .nf        disable filling\n.\\\" .fi        enable filling\n.\\\" .br        insert line break\n.\\\" .sp <n>    insert n+1 empty lines\n.\\\" for manpage-specific macros, see man(7)\n.SH NAME\nminiunzip - uncompress and examine ZIP archives\n.SH SYNOPSIS\n.B miniunzip\n.RI [ -exvlo ]\nzipfile [ files_to_extract ] [-d tempdir]\n.SH DESCRIPTION\n.B minizip\nis a simple tool which allows the extraction of compressed file\narchives in the ZIP format used by the MS-DOS utility PKZIP.  It was\nwritten as a demonstration of the\n.IR zlib (3)\nlibrary and therefore lack many of the features of the\n.IR unzip (1)\nprogram.\n.SH OPTIONS\nA number of options are supported.  With the exception of\n.BI \\-d\\  tempdir\nthese must be supplied before any\nother arguments and are:\n.TP\n.BI \\-l\\ ,\\ \\-\\-v\nList the files in the archive without extracting them.\n.TP\n.B \\-o\nOverwrite files without prompting for confirmation.\n.TP\n.B \\-x\nExtract files (default).\n.PP\nThe\n.I zipfile\nargument is the name of the archive to process. The next argument can be used\nto specify a single file to extract from the archive.\n\nLastly, the following option can be specified at the end of the command-line:\n.TP\n.BI \\-d\\  tempdir\nExtract the archive in the directory\n.I tempdir\nrather than the current directory.\n.SH SEE ALSO\n.BR minizip (1),\n.BR zlib (3),\n.BR unzip (1).\n.SH AUTHOR\nThis program was written by Gilles Vollant.  This manual page was\nwritten by Mark Brown <broonie@sirena.org.uk>. The -d tempdir option\nwas added by Dirk Eddelbuettel <edd@debian.org>.\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/minizip.1",
    "content": ".\\\"                                      Hey, EMACS: -*- nroff -*-\n.TH minizip 1 \"May 2, 2001\"\n.\\\" Please adjust this date whenever revising the manpage.\n.\\\"\n.\\\" Some roff macros, for reference:\n.\\\" .nh        disable hyphenation\n.\\\" .hy        enable hyphenation\n.\\\" .ad l      left justify\n.\\\" .ad b      justify to both left and right margins\n.\\\" .nf        disable filling\n.\\\" .fi        enable filling\n.\\\" .br        insert line break\n.\\\" .sp <n>    insert n+1 empty lines\n.\\\" for manpage-specific macros, see man(7)\n.SH NAME\nminizip - create ZIP archives\n.SH SYNOPSIS\n.B minizip\n.RI [ -o ]\nzipfile [ \" files\" ... ]\n.SH DESCRIPTION\n.B minizip\nis a simple tool which allows the creation of compressed file archives\nin the ZIP format used by the MS-DOS utility PKZIP.  It was written as\na demonstration of the\n.IR zlib (3)\nlibrary and therefore lack many of the features of the\n.IR zip (1)\nprogram.\n.SH OPTIONS\nThe first argument supplied is the name of the ZIP archive to create or\n.RI -o\nin which case it is ignored and the second argument treated as the\nname of the ZIP file.  If the ZIP file already exists it will be\noverwritten.\n.PP\nSubsequent arguments specify a list of files to place in the ZIP\narchive.  If none are specified then an empty archive will be created.\n.SH SEE ALSO\n.BR miniunzip (1),\n.BR zlib (3),\n.BR zip (1).\n.SH AUTHOR\nThis program was written by Gilles Vollant.  This manual page was\nwritten by Mark Brown <broonie@sirena.org.uk>.\n\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/minizip.c",
    "content": "/*\n   minizip.c\n   Version 1.1, February 14h, 2010\n   sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications of Unzip for Zip64\n         Copyright (C) 2007-2008 Even Rouault\n\n         Modifications for Zip64 support on both zip and unzip\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n*/\n\n\n#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))\n        #ifndef __USE_FILE_OFFSET64\n                #define __USE_FILE_OFFSET64\n        #endif\n        #ifndef __USE_LARGEFILE64\n                #define __USE_LARGEFILE64\n        #endif\n        #ifndef _LARGEFILE64_SOURCE\n                #define _LARGEFILE64_SOURCE\n        #endif\n        #ifndef _FILE_OFFSET_BIT\n                #define _FILE_OFFSET_BIT 64\n        #endif\n#endif\n\n#ifdef __APPLE__\n// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions\n#define FOPEN_FUNC(filename, mode) fopen(filename, mode)\n#define FTELLO_FUNC(stream) ftello(stream)\n#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)\n#else\n#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)\n#define FTELLO_FUNC(stream) ftello64(stream)\n#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)\n#endif\n\n\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <errno.h>\n#include <fcntl.h>\n\n#ifdef _WIN32\n# include <direct.h>\n# include <io.h>\n#else\n# include <unistd.h>\n# include <utime.h>\n# include <sys/types.h>\n# include <sys/stat.h>\n#endif\n\n#include \"zip.h\"\n\n#ifdef _WIN32\n        #define USEWIN32IOAPI\n        #include \"iowin32.h\"\n#endif\n\n\n\n#define WRITEBUFFERSIZE (16384)\n#define MAXFILENAME (256)\n\n#ifdef _WIN32\nuLong filetime(f, tmzip, dt)\n    char *f;                /* name of file to get info on */\n    tm_zip *tmzip;             /* return value: access, modific. and creation times */\n    uLong *dt;             /* dostime */\n{\n  int ret = 0;\n  {\n      FILETIME ftLocal;\n      HANDLE hFind;\n      WIN32_FIND_DATAA ff32;\n\n      hFind = FindFirstFileA(f,&ff32);\n      if (hFind != INVALID_HANDLE_VALUE)\n      {\n        FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);\n        FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);\n        FindClose(hFind);\n        ret = 1;\n      }\n  }\n  return ret;\n}\n#else\n#ifdef unix || __APPLE__\nuLong filetime(f, tmzip, dt)\n    char *f;               /* name of file to get info on */\n    tm_zip *tmzip;         /* return value: access, modific. and creation times */\n    uLong *dt;             /* dostime */\n{\n  int ret=0;\n  struct stat s;        /* results of stat() */\n  struct tm* filedate;\n  time_t tm_t=0;\n\n  if (strcmp(f,\"-\")!=0)\n  {\n    char name[MAXFILENAME+1];\n    int len = strlen(f);\n    if (len > MAXFILENAME)\n      len = MAXFILENAME;\n\n    strncpy(name, f,MAXFILENAME-1);\n    /* strncpy doesnt append the trailing NULL, of the string is too long. */\n    name[ MAXFILENAME ] = '\\0';\n\n    if (name[len - 1] == '/')\n      name[len - 1] = '\\0';\n    /* not all systems allow stat'ing a file with / appended */\n    if (stat(name,&s)==0)\n    {\n      tm_t = s.st_mtime;\n      ret = 1;\n    }\n  }\n  filedate = localtime(&tm_t);\n\n  tmzip->tm_sec  = filedate->tm_sec;\n  tmzip->tm_min  = filedate->tm_min;\n  tmzip->tm_hour = filedate->tm_hour;\n  tmzip->tm_mday = filedate->tm_mday;\n  tmzip->tm_mon  = filedate->tm_mon ;\n  tmzip->tm_year = filedate->tm_year;\n\n  return ret;\n}\n#else\nuLong filetime(f, tmzip, dt)\n    char *f;                /* name of file to get info on */\n    tm_zip *tmzip;             /* return value: access, modific. and creation times */\n    uLong *dt;             /* dostime */\n{\n    return 0;\n}\n#endif\n#endif\n\n\n\n\nint check_exist_file(filename)\n    const char* filename;\n{\n    FILE* ftestexist;\n    int ret = 1;\n    ftestexist = FOPEN_FUNC(filename,\"rb\");\n    if (ftestexist==NULL)\n        ret = 0;\n    else\n        fclose(ftestexist);\n    return ret;\n}\n\nvoid do_banner()\n{\n    printf(\"MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\\n\");\n    printf(\"more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\\n\\n\");\n}\n\nvoid do_help()\n{\n    printf(\"Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\\n\\n\" \\\n           \"  -o  Overwrite existing file.zip\\n\" \\\n           \"  -a  Append to existing file.zip\\n\" \\\n           \"  -0  Store only\\n\" \\\n           \"  -1  Compress faster\\n\" \\\n           \"  -9  Compress better\\n\\n\" \\\n           \"  -j  exclude path. store only the file name.\\n\\n\");\n}\n\n/* calculate the CRC32 of a file,\n   because to encrypt a file, we need known the CRC32 of the file before */\nint getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)\n{\n   unsigned long calculate_crc=0;\n   int err=ZIP_OK;\n   FILE * fin = FOPEN_FUNC(filenameinzip,\"rb\");\n\n   unsigned long size_read = 0;\n   unsigned long total_read = 0;\n   if (fin==NULL)\n   {\n       err = ZIP_ERRNO;\n   }\n\n    if (err == ZIP_OK)\n        do\n        {\n            err = ZIP_OK;\n            size_read = (int)fread(buf,1,size_buf,fin);\n            if (size_read < size_buf)\n                if (feof(fin)==0)\n            {\n                printf(\"error in reading %s\\n\",filenameinzip);\n                err = ZIP_ERRNO;\n            }\n\n            if (size_read>0)\n                calculate_crc = crc32(calculate_crc,buf,size_read);\n            total_read += size_read;\n\n        } while ((err == ZIP_OK) && (size_read>0));\n\n    if (fin)\n        fclose(fin);\n\n    *result_crc=calculate_crc;\n    printf(\"file %s crc %lx\\n\", filenameinzip, calculate_crc);\n    return err;\n}\n\nint isLargeFile(const char* filename)\n{\n  int largeFile = 0;\n  ZPOS64_T pos = 0;\n  FILE* pFile = FOPEN_FUNC(filename, \"rb\");\n\n  if(pFile != NULL)\n  {\n    int n = FSEEKO_FUNC(pFile, 0, SEEK_END);\n    pos = FTELLO_FUNC(pFile);\n\n                printf(\"File : %s is %lld bytes\\n\", filename, pos);\n\n    if(pos >= 0xffffffff)\n     largeFile = 1;\n\n                fclose(pFile);\n  }\n\n return largeFile;\n}\n\nint main(argc,argv)\n    int argc;\n    char *argv[];\n{\n    int i;\n    int opt_overwrite=0;\n    int opt_compress_level=Z_DEFAULT_COMPRESSION;\n    int opt_exclude_path=0;\n    int zipfilenamearg = 0;\n    char filename_try[MAXFILENAME+16];\n    int zipok;\n    int err=0;\n    int size_buf=0;\n    void* buf=NULL;\n    const char* password=NULL;\n\n\n    do_banner();\n    if (argc==1)\n    {\n        do_help();\n        return 0;\n    }\n    else\n    {\n        for (i=1;i<argc;i++)\n        {\n            if ((*argv[i])=='-')\n            {\n                const char *p=argv[i]+1;\n\n                while ((*p)!='\\0')\n                {\n                    char c=*(p++);;\n                    if ((c=='o') || (c=='O'))\n                        opt_overwrite = 1;\n                    if ((c=='a') || (c=='A'))\n                        opt_overwrite = 2;\n                    if ((c>='0') && (c<='9'))\n                        opt_compress_level = c-'0';\n                    if ((c=='j') || (c=='J'))\n                        opt_exclude_path = 1;\n\n                    if (((c=='p') || (c=='P')) && (i+1<argc))\n                    {\n                        password=argv[i+1];\n                        i++;\n                    }\n                }\n            }\n            else\n            {\n                if (zipfilenamearg == 0)\n                {\n                    zipfilenamearg = i ;\n                }\n            }\n        }\n    }\n\n    size_buf = WRITEBUFFERSIZE;\n    buf = (void*)malloc(size_buf);\n    if (buf==NULL)\n    {\n        printf(\"Error allocating memory\\n\");\n        return ZIP_INTERNALERROR;\n    }\n\n    if (zipfilenamearg==0)\n    {\n        zipok=0;\n    }\n    else\n    {\n        int i,len;\n        int dot_found=0;\n\n        zipok = 1 ;\n        strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);\n        /* strncpy doesnt append the trailing NULL, of the string is too long. */\n        filename_try[ MAXFILENAME ] = '\\0';\n\n        len=(int)strlen(filename_try);\n        for (i=0;i<len;i++)\n            if (filename_try[i]=='.')\n                dot_found=1;\n\n        if (dot_found==0)\n            strcat(filename_try,\".zip\");\n\n        if (opt_overwrite==2)\n        {\n            /* if the file don't exist, we not append file */\n            if (check_exist_file(filename_try)==0)\n                opt_overwrite=1;\n        }\n        else\n        if (opt_overwrite==0)\n            if (check_exist_file(filename_try)!=0)\n            {\n                char rep=0;\n                do\n                {\n                    char answer[128];\n                    int ret;\n                    printf(\"The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : \",filename_try);\n                    ret = scanf(\"%1s\",answer);\n                    if (ret != 1)\n                    {\n                       exit(EXIT_FAILURE);\n                    }\n                    rep = answer[0] ;\n                    if ((rep>='a') && (rep<='z'))\n                        rep -= 0x20;\n                }\n                while ((rep!='Y') && (rep!='N') && (rep!='A'));\n                if (rep=='N')\n                    zipok = 0;\n                if (rep=='A')\n                    opt_overwrite = 2;\n            }\n    }\n\n    if (zipok==1)\n    {\n        zipFile zf;\n        int errclose;\n#        ifdef USEWIN32IOAPI\n        zlib_filefunc64_def ffunc;\n        fill_win32_filefunc64A(&ffunc);\n        zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);\n#        else\n        zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0);\n#        endif\n\n        if (zf == NULL)\n        {\n            printf(\"error opening %s\\n\",filename_try);\n            err= ZIP_ERRNO;\n        }\n        else\n            printf(\"creating %s\\n\",filename_try);\n\n        for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)\n        {\n            if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&\n                  ((argv[i][1]=='o') || (argv[i][1]=='O') ||\n                   (argv[i][1]=='a') || (argv[i][1]=='A') ||\n                   (argv[i][1]=='p') || (argv[i][1]=='P') ||\n                   ((argv[i][1]>='0') || (argv[i][1]<='9'))) &&\n                  (strlen(argv[i]) == 2)))\n            {\n                FILE * fin;\n                int size_read;\n                const char* filenameinzip = argv[i];\n                const char *savefilenameinzip;\n                zip_fileinfo zi;\n                unsigned long crcFile=0;\n                int zip64 = 0;\n\n                zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =\n                zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;\n                zi.dosDate = 0;\n                zi.internal_fa = 0;\n                zi.external_fa = 0;\n                filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);\n\n/*\n                err = zipOpenNewFileInZip(zf,filenameinzip,&zi,\n                                 NULL,0,NULL,0,NULL / * comment * /,\n                                 (opt_compress_level != 0) ? Z_DEFLATED : 0,\n                                 opt_compress_level);\n*/\n                if ((password != NULL) && (err==ZIP_OK))\n                    err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);\n\n                zip64 = isLargeFile(filenameinzip);\n\n                                                         /* The path name saved, should not include a leading slash. */\n               /*if it did, windows/xp and dynazip couldn't read the zip file. */\n                 savefilenameinzip = filenameinzip;\n                 while( savefilenameinzip[0] == '\\\\' || savefilenameinzip[0] == '/' )\n                 {\n                     savefilenameinzip++;\n                 }\n\n                 /*should the zip file contain any path at all?*/\n                 if( opt_exclude_path )\n                 {\n                     const char *tmpptr;\n                     const char *lastslash = 0;\n                     for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++)\n                     {\n                         if( *tmpptr == '\\\\' || *tmpptr == '/')\n                         {\n                             lastslash = tmpptr;\n                         }\n                     }\n                     if( lastslash != NULL )\n                     {\n                         savefilenameinzip = lastslash+1; // base filename follows last slash.\n                     }\n                 }\n\n                 /**/\n                err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi,\n                                 NULL,0,NULL,0,NULL /* comment*/,\n                                 (opt_compress_level != 0) ? Z_DEFLATED : 0,\n                                 opt_compress_level,0,\n                                 /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */\n                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,\n                                 password,crcFile, zip64);\n\n                if (err != ZIP_OK)\n                    printf(\"error in opening %s in zipfile\\n\",filenameinzip);\n                else\n                {\n                    fin = FOPEN_FUNC(filenameinzip,\"rb\");\n                    if (fin==NULL)\n                    {\n                        err=ZIP_ERRNO;\n                        printf(\"error in opening %s for reading\\n\",filenameinzip);\n                    }\n                }\n\n                if (err == ZIP_OK)\n                    do\n                    {\n                        err = ZIP_OK;\n                        size_read = (int)fread(buf,1,size_buf,fin);\n                        if (size_read < size_buf)\n                            if (feof(fin)==0)\n                        {\n                            printf(\"error in reading %s\\n\",filenameinzip);\n                            err = ZIP_ERRNO;\n                        }\n\n                        if (size_read>0)\n                        {\n                            err = zipWriteInFileInZip (zf,buf,size_read);\n                            if (err<0)\n                            {\n                                printf(\"error in writing %s in the zipfile\\n\",\n                                                 filenameinzip);\n                            }\n\n                        }\n                    } while ((err == ZIP_OK) && (size_read>0));\n\n                if (fin)\n                    fclose(fin);\n\n                if (err<0)\n                    err=ZIP_ERRNO;\n                else\n                {\n                    err = zipCloseFileInZip(zf);\n                    if (err!=ZIP_OK)\n                        printf(\"error in closing %s in the zipfile\\n\",\n                                    filenameinzip);\n                }\n            }\n        }\n        errclose = zipClose(zf,NULL);\n        if (errclose != ZIP_OK)\n            printf(\"error in closing %s\\n\",filename_try);\n    }\n    else\n    {\n       do_help();\n    }\n\n    free(buf);\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/minizip.pc.in",
    "content": "prefix=@prefix@\nexec_prefix=@exec_prefix@\nlibdir=@libdir@\nincludedir=@includedir@/minizip\n\nName: minizip\nDescription: Minizip zip file manipulation library\nRequires:\nVersion: @PACKAGE_VERSION@\nLibs: -L${libdir} -lminizip\nLibs.private: -lz\nCflags: -I${includedir}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/mztools.c",
    "content": "/*\n  Additional tools for Minizip\n  Code: Xavier Roche '2004\n  License: Same as ZLIB (www.gzip.org)\n*/\n\n/* Code */\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include \"zlib.h\"\n#include \"unzip.h\"\n\n#define READ_8(adr)  ((unsigned char)*(adr))\n#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )\n#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )\n\n#define WRITE_8(buff, n) do { \\\n  *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \\\n} while(0)\n#define WRITE_16(buff, n) do { \\\n  WRITE_8((unsigned char*)(buff), n); \\\n  WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \\\n} while(0)\n#define WRITE_32(buff, n) do { \\\n  WRITE_16((unsigned char*)(buff), (n) & 0xffff); \\\n  WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \\\n} while(0)\n\nextern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)\nconst char* file;\nconst char* fileOut;\nconst char* fileOutTmp;\nuLong* nRecovered;\nuLong* bytesRecovered;\n{\n  int err = Z_OK;\n  FILE* fpZip = fopen(file, \"rb\");\n  FILE* fpOut = fopen(fileOut, \"wb\");\n  FILE* fpOutCD = fopen(fileOutTmp, \"wb\");\n  if (fpZip != NULL &&  fpOut != NULL) {\n    int entries = 0;\n    uLong totalBytes = 0;\n    char header[30];\n    char filename[1024];\n    char extra[1024];\n    int offset = 0;\n    int offsetCD = 0;\n    while ( fread(header, 1, 30, fpZip) == 30 ) {\n      int currentOffset = offset;\n\n      /* File entry */\n      if (READ_32(header) == 0x04034b50) {\n        unsigned int version = READ_16(header + 4);\n        unsigned int gpflag = READ_16(header + 6);\n        unsigned int method = READ_16(header + 8);\n        unsigned int filetime = READ_16(header + 10);\n        unsigned int filedate = READ_16(header + 12);\n        unsigned int crc = READ_32(header + 14); /* crc */\n        unsigned int cpsize = READ_32(header + 18); /* compressed size */\n        unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */\n        unsigned int fnsize = READ_16(header + 26); /* file name length */\n        unsigned int extsize = READ_16(header + 28); /* extra field length */\n        filename[0] = extra[0] = '\\0';\n\n        /* Header */\n        if (fwrite(header, 1, 30, fpOut) == 30) {\n          offset += 30;\n        } else {\n          err = Z_ERRNO;\n          break;\n        }\n\n        /* Filename */\n        if (fnsize > 0) {\n          if (fnsize < sizeof(filename)) {\n            if (fread(filename, 1, fnsize, fpZip) == fnsize) {\n                if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {\n                offset += fnsize;\n              } else {\n                err = Z_ERRNO;\n                break;\n              }\n            } else {\n              err = Z_ERRNO;\n              break;\n            }\n          } else {\n            err = Z_ERRNO;\n            break;\n          }\n        } else {\n          err = Z_STREAM_ERROR;\n          break;\n        }\n\n        /* Extra field */\n        if (extsize > 0) {\n          if (extsize < sizeof(extra)) {\n            if (fread(extra, 1, extsize, fpZip) == extsize) {\n              if (fwrite(extra, 1, extsize, fpOut) == extsize) {\n                offset += extsize;\n                } else {\n                err = Z_ERRNO;\n                break;\n              }\n            } else {\n              err = Z_ERRNO;\n              break;\n            }\n          } else {\n            err = Z_ERRNO;\n            break;\n          }\n        }\n\n        /* Data */\n        {\n          int dataSize = cpsize;\n          if (dataSize == 0) {\n            dataSize = uncpsize;\n          }\n          if (dataSize > 0) {\n            char* data = malloc(dataSize);\n            if (data != NULL) {\n              if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {\n                if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {\n                  offset += dataSize;\n                  totalBytes += dataSize;\n                } else {\n                  err = Z_ERRNO;\n                }\n              } else {\n                err = Z_ERRNO;\n              }\n              free(data);\n              if (err != Z_OK) {\n                break;\n              }\n            } else {\n              err = Z_MEM_ERROR;\n              break;\n            }\n          }\n        }\n\n        /* Central directory entry */\n        {\n          char header[46];\n          char* comment = \"\";\n          int comsize = (int) strlen(comment);\n          WRITE_32(header, 0x02014b50);\n          WRITE_16(header + 4, version);\n          WRITE_16(header + 6, version);\n          WRITE_16(header + 8, gpflag);\n          WRITE_16(header + 10, method);\n          WRITE_16(header + 12, filetime);\n          WRITE_16(header + 14, filedate);\n          WRITE_32(header + 16, crc);\n          WRITE_32(header + 20, cpsize);\n          WRITE_32(header + 24, uncpsize);\n          WRITE_16(header + 28, fnsize);\n          WRITE_16(header + 30, extsize);\n          WRITE_16(header + 32, comsize);\n          WRITE_16(header + 34, 0);     /* disk # */\n          WRITE_16(header + 36, 0);     /* int attrb */\n          WRITE_32(header + 38, 0);     /* ext attrb */\n          WRITE_32(header + 42, currentOffset);\n          /* Header */\n          if (fwrite(header, 1, 46, fpOutCD) == 46) {\n            offsetCD += 46;\n\n            /* Filename */\n            if (fnsize > 0) {\n              if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {\n                offsetCD += fnsize;\n              } else {\n                err = Z_ERRNO;\n                break;\n              }\n            } else {\n              err = Z_STREAM_ERROR;\n              break;\n            }\n\n            /* Extra field */\n            if (extsize > 0) {\n              if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {\n                offsetCD += extsize;\n              } else {\n                err = Z_ERRNO;\n                break;\n              }\n            }\n\n            /* Comment field */\n            if (comsize > 0) {\n              if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {\n                offsetCD += comsize;\n              } else {\n                err = Z_ERRNO;\n                break;\n              }\n            }\n\n\n          } else {\n            err = Z_ERRNO;\n            break;\n          }\n        }\n\n        /* Success */\n        entries++;\n\n      } else {\n        break;\n      }\n    }\n\n    /* Final central directory  */\n    {\n      int entriesZip = entries;\n      char header[22];\n      char* comment = \"\"; // \"ZIP File recovered by zlib/minizip/mztools\";\n      int comsize = (int) strlen(comment);\n      if (entriesZip > 0xffff) {\n        entriesZip = 0xffff;\n      }\n      WRITE_32(header, 0x06054b50);\n      WRITE_16(header + 4, 0);    /* disk # */\n      WRITE_16(header + 6, 0);    /* disk # */\n      WRITE_16(header + 8, entriesZip);   /* hack */\n      WRITE_16(header + 10, entriesZip);  /* hack */\n      WRITE_32(header + 12, offsetCD);    /* size of CD */\n      WRITE_32(header + 16, offset);      /* offset to CD */\n      WRITE_16(header + 20, comsize);     /* comment */\n\n      /* Header */\n      if (fwrite(header, 1, 22, fpOutCD) == 22) {\n\n        /* Comment field */\n        if (comsize > 0) {\n          if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {\n            err = Z_ERRNO;\n          }\n        }\n\n      } else {\n        err = Z_ERRNO;\n      }\n    }\n\n    /* Final merge (file + central directory) */\n    fclose(fpOutCD);\n    if (err == Z_OK) {\n      fpOutCD = fopen(fileOutTmp, \"rb\");\n      if (fpOutCD != NULL) {\n        int nRead;\n        char buffer[8192];\n        while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {\n          if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {\n            err = Z_ERRNO;\n            break;\n          }\n        }\n        fclose(fpOutCD);\n      }\n    }\n\n    /* Close */\n    fclose(fpZip);\n    fclose(fpOut);\n\n    /* Wipe temporary file */\n    (void)remove(fileOutTmp);\n\n    /* Number of recovered entries */\n    if (err == Z_OK) {\n      if (nRecovered != NULL) {\n        *nRecovered = entries;\n      }\n      if (bytesRecovered != NULL) {\n        *bytesRecovered = totalBytes;\n      }\n    }\n  } else {\n    err = Z_STREAM_ERROR;\n  }\n  return err;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/mztools.h",
    "content": "/*\n  Additional tools for Minizip\n  Code: Xavier Roche '2004\n  License: Same as ZLIB (www.gzip.org)\n*/\n\n#ifndef _zip_tools_H\n#define _zip_tools_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifndef _ZLIB_H\n#include \"zlib.h\"\n#endif\n\n#include \"unzip.h\"\n\n/* Repair a ZIP file (missing central directory)\n   file: file to recover\n   fileOut: output file after recovery\n   fileOutTmp: temporary file name used for recovery\n*/\nextern int ZEXPORT unzRepair(const char* file,\n                             const char* fileOut,\n                             const char* fileOutTmp,\n                             uLong* nRecovered,\n                             uLong* bytesRecovered);\n\n\n#ifdef __cplusplus\n}\n#endif\n\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/unzip.c",
    "content": "/* unzip.c -- IO for uncompress .zip files using zlib\n   Version 1.1, February 14h, 2010\n   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications of Unzip for Zip64\n         Copyright (C) 2007-2008 Even Rouault\n\n         Modifications for Zip64 support on both zip and unzip\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n\n         For more info read MiniZip_info.txt\n\n\n  ------------------------------------------------------------------------------------\n  Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of\n  compatibility with older software. The following is from the original crypt.c.\n  Code woven in by Terry Thorsen 1/2003.\n\n  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.\n\n  See the accompanying file LICENSE, version 2000-Apr-09 or later\n  (the contents of which are also included in zip.h) for terms of use.\n  If, for some reason, all these files are missing, the Info-ZIP license\n  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html\n\n        crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]\n\n  The encryption/decryption parts of this source code (as opposed to the\n  non-echoing password parts) were originally written in Europe.  The\n  whole source package can be freely distributed, including from the USA.\n  (Prior to January 2000, re-export from the US was a violation of US law.)\n\n        This encryption code is a direct transcription of the algorithm from\n  Roger Schlafly, described by Phil Katz in the file appnote.txt.  This\n  file (appnote.txt) is distributed with the PKZIP program (even in the\n  version without encryption capabilities).\n\n        ------------------------------------------------------------------------------------\n\n        Changes in unzip.c\n\n        2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos\n  2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*\n  2007-2008 - Even Rouault - Remove old C style function prototypes\n  2007-2008 - Even Rouault - Add unzip support for ZIP64\n\n        Copyright (C) 2007-2008 Even Rouault\n\n\n        Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).\n  Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G\n                                should only read the compressed/uncompressed size from the Zip64 format if\n                                the size from normal header was 0xFFFFFFFF\n  Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant\n        Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)\n                                Patch created by Daniel Borca\n\n  Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer\n\n  Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson\n\n*/\n\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifndef NOUNCRYPT\n        #define NOUNCRYPT\n#endif\n\n#include \"zlib.h\"\n#include \"unzip.h\"\n\n#ifdef STDC\n#  include <stddef.h>\n#  include <string.h>\n#  include <stdlib.h>\n#endif\n#ifdef NO_ERRNO_H\n    extern int errno;\n#else\n#   include <errno.h>\n#endif\n\n\n#ifndef local\n#  define local static\n#endif\n/* compile with -Dlocal if your debugger can't find static symbols */\n\n\n#ifndef CASESENSITIVITYDEFAULT_NO\n#  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)\n#    define CASESENSITIVITYDEFAULT_NO\n#  endif\n#endif\n\n\n#ifndef UNZ_BUFSIZE\n#define UNZ_BUFSIZE (16384)\n#endif\n\n#ifndef UNZ_MAXFILENAMEINZIP\n#define UNZ_MAXFILENAMEINZIP (256)\n#endif\n\n#ifndef ALLOC\n# define ALLOC(size) (malloc(size))\n#endif\n#ifndef TRYFREE\n# define TRYFREE(p) {if (p) free(p);}\n#endif\n\n#define SIZECENTRALDIRITEM (0x2e)\n#define SIZEZIPLOCALHEADER (0x1e)\n\n\nconst char unz_copyright[] =\n   \" unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll\";\n\n/* unz_file_info_interntal contain internal info about a file in zipfile*/\ntypedef struct unz_file_info64_internal_s\n{\n    ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */\n} unz_file_info64_internal;\n\n\n/* file_in_zip_read_info_s contain internal information about a file in zipfile,\n    when reading and decompress it */\ntypedef struct\n{\n    char  *read_buffer;         /* internal buffer for compressed data */\n    z_stream stream;            /* zLib stream structure for inflate */\n\n#ifdef HAVE_BZIP2\n    bz_stream bstream;          /* bzLib stream structure for bziped */\n#endif\n\n    ZPOS64_T pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/\n    uLong stream_initialised;   /* flag set if stream structure is initialised*/\n\n    ZPOS64_T offset_local_extrafield;/* offset of the local extra field */\n    uInt  size_local_extrafield;/* size of the local extra field */\n    ZPOS64_T pos_local_extrafield;   /* position in the local extra field in read*/\n    ZPOS64_T total_out_64;\n\n    uLong crc32;                /* crc32 of all data uncompressed */\n    uLong crc32_wait;           /* crc32 we must obtain after decompress all */\n    ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */\n    ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/\n    zlib_filefunc64_32_def z_filefunc;\n    voidpf filestream;        /* io structore of the zipfile */\n    uLong compression_method;   /* compression method (0==store) */\n    ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/\n    int   raw;\n} file_in_zip64_read_info_s;\n\n\n/* unz64_s contain internal information about the zipfile\n*/\ntypedef struct\n{\n    zlib_filefunc64_32_def z_filefunc;\n    int is64bitOpenFunction;\n    voidpf filestream;        /* io structore of the zipfile */\n    unz_global_info64 gi;       /* public global information */\n    ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/\n    ZPOS64_T num_file;             /* number of the current file in the zipfile*/\n    ZPOS64_T pos_in_central_dir;   /* pos of the current file in the central dir*/\n    ZPOS64_T current_file_ok;      /* flag about the usability of the current file*/\n    ZPOS64_T central_pos;          /* position of the beginning of the central dir*/\n\n    ZPOS64_T size_central_dir;     /* size of the central directory  */\n    ZPOS64_T offset_central_dir;   /* offset of start of central directory with\n                                   respect to the starting disk number */\n\n    unz_file_info64 cur_file_info; /* public info about the current file in zip*/\n    unz_file_info64_internal cur_file_info_internal; /* private info about it*/\n    file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current\n                                        file if we are decompressing it */\n    int encrypted;\n\n    int isZip64;\n\n#    ifndef NOUNCRYPT\n    unsigned long keys[3];     /* keys defining the pseudo-random sequence */\n    const z_crc_t* pcrc_32_tab;\n#    endif\n} unz64_s;\n\n\n#ifndef NOUNCRYPT\n#include \"crypt.h\"\n#endif\n\n/* ===========================================================================\n     Read a byte from a gz_stream; update next_in and avail_in. Return EOF\n   for end of file.\n   IN assertion: the stream s has been sucessfully opened for reading.\n*/\n\n\nlocal int unz64local_getByte OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream,\n    int *pi));\n\nlocal int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)\n{\n    unsigned char c;\n    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);\n    if (err==1)\n    {\n        *pi = (int)c;\n        return UNZ_OK;\n    }\n    else\n    {\n        if (ZERROR64(*pzlib_filefunc_def,filestream))\n            return UNZ_ERRNO;\n        else\n            return UNZ_EOF;\n    }\n}\n\n\n/* ===========================================================================\n   Reads a long in LSB order from the given gz_stream. Sets\n*/\nlocal int unz64local_getShort OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream,\n    uLong *pX));\n\nlocal int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,\n                             voidpf filestream,\n                             uLong *pX)\n{\n    uLong x ;\n    int i = 0;\n    int err;\n\n    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x = (uLong)i;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((uLong)i)<<8;\n\n    if (err==UNZ_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\nlocal int unz64local_getLong OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream,\n    uLong *pX));\n\nlocal int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,\n                            voidpf filestream,\n                            uLong *pX)\n{\n    uLong x ;\n    int i = 0;\n    int err;\n\n    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x = (uLong)i;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((uLong)i)<<8;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((uLong)i)<<16;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x += ((uLong)i)<<24;\n\n    if (err==UNZ_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\nlocal int unz64local_getLong64 OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream,\n    ZPOS64_T *pX));\n\n\nlocal int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,\n                            voidpf filestream,\n                            ZPOS64_T *pX)\n{\n    ZPOS64_T x ;\n    int i = 0;\n    int err;\n\n    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x = (ZPOS64_T)i;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<8;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<16;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<24;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<32;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<40;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<48;\n\n    if (err==UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x |= ((ZPOS64_T)i)<<56;\n\n    if (err==UNZ_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\n/* My own strcmpi / strcasecmp */\nlocal int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)\n{\n    for (;;)\n    {\n        char c1=*(fileName1++);\n        char c2=*(fileName2++);\n        if ((c1>='a') && (c1<='z'))\n            c1 -= 0x20;\n        if ((c2>='a') && (c2<='z'))\n            c2 -= 0x20;\n        if (c1=='\\0')\n            return ((c2=='\\0') ? 0 : -1);\n        if (c2=='\\0')\n            return 1;\n        if (c1<c2)\n            return -1;\n        if (c1>c2)\n            return 1;\n    }\n}\n\n\n#ifdef  CASESENSITIVITYDEFAULT_NO\n#define CASESENSITIVITYDEFAULTVALUE 2\n#else\n#define CASESENSITIVITYDEFAULTVALUE 1\n#endif\n\n#ifndef STRCMPCASENOSENTIVEFUNCTION\n#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal\n#endif\n\n/*\n   Compare two filename (fileName1,fileName2).\n   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)\n   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi\n                                                                or strcasecmp)\n   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system\n        (like 1 on Unix, 2 on Windows)\n\n*/\nextern int ZEXPORT unzStringFileNameCompare (const char*  fileName1,\n                                                 const char*  fileName2,\n                                                 int iCaseSensitivity)\n\n{\n    if (iCaseSensitivity==0)\n        iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;\n\n    if (iCaseSensitivity==1)\n        return strcmp(fileName1,fileName2);\n\n    return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);\n}\n\n#ifndef BUFREADCOMMENT\n#define BUFREADCOMMENT (0x400)\n#endif\n\n/*\n  Locate the Central directory of a zipfile (at the end, just before\n    the global comment)\n*/\nlocal ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));\nlocal ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)\n{\n    unsigned char* buf;\n    ZPOS64_T uSizeFile;\n    ZPOS64_T uBackRead;\n    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */\n    ZPOS64_T uPosFound=0;\n\n    if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)\n        return 0;\n\n\n    uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);\n\n    if (uMaxBack>uSizeFile)\n        uMaxBack = uSizeFile;\n\n    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);\n    if (buf==NULL)\n        return 0;\n\n    uBackRead = 4;\n    while (uBackRead<uMaxBack)\n    {\n        uLong uReadSize;\n        ZPOS64_T uReadPos ;\n        int i;\n        if (uBackRead+BUFREADCOMMENT>uMaxBack)\n            uBackRead = uMaxBack;\n        else\n            uBackRead+=BUFREADCOMMENT;\n        uReadPos = uSizeFile-uBackRead ;\n\n        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?\n                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);\n        if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n            break;\n\n        if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)\n            break;\n\n        for (i=(int)uReadSize-3; (i--)>0;)\n            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&\n                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))\n            {\n                uPosFound = uReadPos+i;\n                break;\n            }\n\n        if (uPosFound!=0)\n            break;\n    }\n    TRYFREE(buf);\n    return uPosFound;\n}\n\n\n/*\n  Locate the Central directory 64 of a zipfile (at the end, just before\n    the global comment)\n*/\nlocal ZPOS64_T unz64local_SearchCentralDir64 OF((\n    const zlib_filefunc64_32_def* pzlib_filefunc_def,\n    voidpf filestream));\n\nlocal ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,\n                                      voidpf filestream)\n{\n    unsigned char* buf;\n    ZPOS64_T uSizeFile;\n    ZPOS64_T uBackRead;\n    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */\n    ZPOS64_T uPosFound=0;\n    uLong uL;\n                ZPOS64_T relativeOffset;\n\n    if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)\n        return 0;\n\n\n    uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);\n\n    if (uMaxBack>uSizeFile)\n        uMaxBack = uSizeFile;\n\n    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);\n    if (buf==NULL)\n        return 0;\n\n    uBackRead = 4;\n    while (uBackRead<uMaxBack)\n    {\n        uLong uReadSize;\n        ZPOS64_T uReadPos;\n        int i;\n        if (uBackRead+BUFREADCOMMENT>uMaxBack)\n            uBackRead = uMaxBack;\n        else\n            uBackRead+=BUFREADCOMMENT;\n        uReadPos = uSizeFile-uBackRead ;\n\n        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?\n                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);\n        if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n            break;\n\n        if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)\n            break;\n\n        for (i=(int)uReadSize-3; (i--)>0;)\n            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&\n                ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))\n            {\n                uPosFound = uReadPos+i;\n                break;\n            }\n\n        if (uPosFound!=0)\n            break;\n    }\n    TRYFREE(buf);\n    if (uPosFound == 0)\n        return 0;\n\n    /* Zip64 end of central directory locator */\n    if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return 0;\n\n    /* the signature, already checked */\n    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)\n        return 0;\n\n    /* number of the disk with the start of the zip64 end of  central directory */\n    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)\n        return 0;\n    if (uL != 0)\n        return 0;\n\n    /* relative offset of the zip64 end of central directory record */\n    if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)\n        return 0;\n\n    /* total number of disks */\n    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)\n        return 0;\n    if (uL != 1)\n        return 0;\n\n    /* Goto end of central directory record */\n    if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return 0;\n\n     /* the signature */\n    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)\n        return 0;\n\n    if (uL != 0x06064b50)\n        return 0;\n\n    return relativeOffset;\n}\n\n/*\n  Open a Zip file. path contain the full pathname (by example,\n     on a Windows NT computer \"c:\\\\test\\\\zlib114.zip\" or on an Unix computer\n     \"zlib/zlib114.zip\".\n     If the zipfile cannot be opened (file doesn't exist or in not valid), the\n       return value is NULL.\n     Else, the return value is a unzFile Handle, usable with other function\n       of this unzip package.\n*/\nlocal unzFile unzOpenInternal (const void *path,\n                               zlib_filefunc64_32_def* pzlib_filefunc64_32_def,\n                               int is64bitOpenFunction)\n{\n    unz64_s us;\n    unz64_s *s;\n    ZPOS64_T central_pos;\n    uLong   uL;\n\n    uLong number_disk;          /* number of the current dist, used for\n                                   spaning ZIP, unsupported, always 0*/\n    uLong number_disk_with_CD;  /* number the the disk with central dir, used\n                                   for spaning ZIP, unsupported, always 0*/\n    ZPOS64_T number_entry_CD;      /* total number of entries in\n                                   the central dir\n                                   (same than number_entry on nospan) */\n\n    int err=UNZ_OK;\n\n    if (unz_copyright[0]!=' ')\n        return NULL;\n\n    us.z_filefunc.zseek32_file = NULL;\n    us.z_filefunc.ztell32_file = NULL;\n    if (pzlib_filefunc64_32_def==NULL)\n        fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);\n    else\n        us.z_filefunc = *pzlib_filefunc64_32_def;\n    us.is64bitOpenFunction = is64bitOpenFunction;\n\n\n\n    us.filestream = ZOPEN64(us.z_filefunc,\n                                                 path,\n                                                 ZLIB_FILEFUNC_MODE_READ |\n                                                 ZLIB_FILEFUNC_MODE_EXISTING);\n    if (us.filestream==NULL)\n        return NULL;\n\n    central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);\n    if (central_pos)\n    {\n        uLong uS;\n        ZPOS64_T uL64;\n\n        us.isZip64 = 1;\n\n        if (ZSEEK64(us.z_filefunc, us.filestream,\n                                      central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        err=UNZ_ERRNO;\n\n        /* the signature, already checked */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* size of zip64 end of central directory record */\n        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* version made by */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* version needed to extract */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* number of this disk */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* number of the disk with the start of the central directory */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* total number of entries in the central directory on this disk */\n        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* total number of entries in the central directory */\n        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        if ((number_entry_CD!=us.gi.number_entry) ||\n            (number_disk_with_CD!=0) ||\n            (number_disk!=0))\n            err=UNZ_BADZIPFILE;\n\n        /* size of the central directory */\n        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* offset of start of central directory with respect to the\n          starting disk number */\n        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        us.gi.size_comment = 0;\n    }\n    else\n    {\n        central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);\n        if (central_pos==0)\n            err=UNZ_ERRNO;\n\n        us.isZip64 = 0;\n\n        if (ZSEEK64(us.z_filefunc, us.filestream,\n                                        central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n            err=UNZ_ERRNO;\n\n        /* the signature, already checked */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* number of this disk */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* number of the disk with the start of the central directory */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)\n            err=UNZ_ERRNO;\n\n        /* total number of entries in the central dir on this disk */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n        us.gi.number_entry = uL;\n\n        /* total number of entries in the central dir */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n        number_entry_CD = uL;\n\n        if ((number_entry_CD!=us.gi.number_entry) ||\n            (number_disk_with_CD!=0) ||\n            (number_disk!=0))\n            err=UNZ_BADZIPFILE;\n\n        /* size of the central directory */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n        us.size_central_dir = uL;\n\n        /* offset of start of central directory with respect to the\n            starting disk number */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)\n            err=UNZ_ERRNO;\n        us.offset_central_dir = uL;\n\n        /* zipfile comment length */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)\n            err=UNZ_ERRNO;\n    }\n\n    if ((central_pos<us.offset_central_dir+us.size_central_dir) &&\n        (err==UNZ_OK))\n        err=UNZ_BADZIPFILE;\n\n    if (err!=UNZ_OK)\n    {\n        ZCLOSE64(us.z_filefunc, us.filestream);\n        return NULL;\n    }\n\n    us.byte_before_the_zipfile = central_pos -\n                            (us.offset_central_dir+us.size_central_dir);\n    us.central_pos = central_pos;\n    us.pfile_in_zip_read = NULL;\n    us.encrypted = 0;\n\n\n    s=(unz64_s*)ALLOC(sizeof(unz64_s));\n    if( s != NULL)\n    {\n        *s=us;\n        unzGoToFirstFile((unzFile)s);\n    }\n    return (unzFile)s;\n}\n\n\nextern unzFile ZEXPORT unzOpen2 (const char *path,\n                                        zlib_filefunc_def* pzlib_filefunc32_def)\n{\n    if (pzlib_filefunc32_def != NULL)\n    {\n        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;\n        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);\n        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);\n    }\n    else\n        return unzOpenInternal(path, NULL, 0);\n}\n\nextern unzFile ZEXPORT unzOpen2_64 (const void *path,\n                                     zlib_filefunc64_def* pzlib_filefunc_def)\n{\n    if (pzlib_filefunc_def != NULL)\n    {\n        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;\n        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;\n        zlib_filefunc64_32_def_fill.ztell32_file = NULL;\n        zlib_filefunc64_32_def_fill.zseek32_file = NULL;\n        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);\n    }\n    else\n        return unzOpenInternal(path, NULL, 1);\n}\n\nextern unzFile ZEXPORT unzOpen (const char *path)\n{\n    return unzOpenInternal(path, NULL, 0);\n}\n\nextern unzFile ZEXPORT unzOpen64 (const void *path)\n{\n    return unzOpenInternal(path, NULL, 1);\n}\n\n/*\n  Close a ZipFile opened with unzOpen.\n  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),\n    these files MUST be closed with unzCloseCurrentFile before call unzClose.\n  return UNZ_OK if there is no problem. */\nextern int ZEXPORT unzClose (unzFile file)\n{\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\n    if (s->pfile_in_zip_read!=NULL)\n        unzCloseCurrentFile(file);\n\n    ZCLOSE64(s->z_filefunc, s->filestream);\n    TRYFREE(s);\n    return UNZ_OK;\n}\n\n\n/*\n  Write info about the ZipFile in the *pglobal_info structure.\n  No preparation of the structure is needed\n  return UNZ_OK if there is no problem. */\nextern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)\n{\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    *pglobal_info=s->gi;\n    return UNZ_OK;\n}\n\nextern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)\n{\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    /* to do : check if number_entry is not truncated */\n    pglobal_info32->number_entry = (uLong)s->gi.number_entry;\n    pglobal_info32->size_comment = s->gi.size_comment;\n    return UNZ_OK;\n}\n/*\n   Translate date/time from Dos format to tm_unz (readable more easilty)\n*/\nlocal void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)\n{\n    ZPOS64_T uDate;\n    uDate = (ZPOS64_T)(ulDosDate>>16);\n    ptm->tm_mday = (uInt)(uDate&0x1f) ;\n    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;\n    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;\n\n    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);\n    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;\n    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;\n}\n\n/*\n  Get Info about the current file in the zipfile, with internal only info\n*/\nlocal int unz64local_GetCurrentFileInfoInternal OF((unzFile file,\n                                                  unz_file_info64 *pfile_info,\n                                                  unz_file_info64_internal\n                                                  *pfile_info_internal,\n                                                  char *szFileName,\n                                                  uLong fileNameBufferSize,\n                                                  void *extraField,\n                                                  uLong extraFieldBufferSize,\n                                                  char *szComment,\n                                                  uLong commentBufferSize));\n\nlocal int unz64local_GetCurrentFileInfoInternal (unzFile file,\n                                                  unz_file_info64 *pfile_info,\n                                                  unz_file_info64_internal\n                                                  *pfile_info_internal,\n                                                  char *szFileName,\n                                                  uLong fileNameBufferSize,\n                                                  void *extraField,\n                                                  uLong extraFieldBufferSize,\n                                                  char *szComment,\n                                                  uLong commentBufferSize)\n{\n    unz64_s* s;\n    unz_file_info64 file_info;\n    unz_file_info64_internal file_info_internal;\n    int err=UNZ_OK;\n    uLong uMagic;\n    long lSeek=0;\n    uLong uL;\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (ZSEEK64(s->z_filefunc, s->filestream,\n              s->pos_in_central_dir+s->byte_before_the_zipfile,\n              ZLIB_FILEFUNC_SEEK_SET)!=0)\n        err=UNZ_ERRNO;\n\n\n    /* we check the magic */\n    if (err==UNZ_OK)\n    {\n        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)\n            err=UNZ_ERRNO;\n        else if (uMagic!=0x02014b50)\n            err=UNZ_BADZIPFILE;\n    }\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)\n        err=UNZ_ERRNO;\n    file_info.compressed_size = uL;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)\n        err=UNZ_ERRNO;\n    file_info.uncompressed_size = uL;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n                // relative offset of local header\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)\n        err=UNZ_ERRNO;\n    file_info_internal.offset_curfile = uL;\n\n    lSeek+=file_info.size_filename;\n    if ((err==UNZ_OK) && (szFileName!=NULL))\n    {\n        uLong uSizeRead ;\n        if (file_info.size_filename<fileNameBufferSize)\n        {\n            *(szFileName+file_info.size_filename)='\\0';\n            uSizeRead = file_info.size_filename;\n        }\n        else\n            uSizeRead = fileNameBufferSize;\n\n        if ((file_info.size_filename>0) && (fileNameBufferSize>0))\n            if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)\n                err=UNZ_ERRNO;\n        lSeek -= uSizeRead;\n    }\n\n    // Read extrafield\n    if ((err==UNZ_OK) && (extraField!=NULL))\n    {\n        ZPOS64_T uSizeRead ;\n        if (file_info.size_file_extra<extraFieldBufferSize)\n            uSizeRead = file_info.size_file_extra;\n        else\n            uSizeRead = extraFieldBufferSize;\n\n        if (lSeek!=0)\n        {\n            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)\n                lSeek=0;\n            else\n                err=UNZ_ERRNO;\n        }\n\n        if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))\n            if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)\n                err=UNZ_ERRNO;\n\n        lSeek += file_info.size_file_extra - (uLong)uSizeRead;\n    }\n    else\n        lSeek += file_info.size_file_extra;\n\n\n    if ((err==UNZ_OK) && (file_info.size_file_extra != 0))\n    {\n                                uLong acc = 0;\n\n        // since lSeek now points to after the extra field we need to move back\n        lSeek -= file_info.size_file_extra;\n\n        if (lSeek!=0)\n        {\n            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)\n                lSeek=0;\n            else\n                err=UNZ_ERRNO;\n        }\n\n        while(acc < file_info.size_file_extra)\n        {\n            uLong headerId;\n                                                uLong dataSize;\n\n            if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)\n                err=UNZ_ERRNO;\n\n            if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)\n                err=UNZ_ERRNO;\n\n            /* ZIP64 extra fields */\n            if (headerId == 0x0001)\n            {\n                                                        uLong uL;\n\n                                                                if(file_info.uncompressed_size == MAXU32)\n                                                                {\n                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)\n                                                                                        err=UNZ_ERRNO;\n                                                                }\n\n                                                                if(file_info.compressed_size == MAXU32)\n                                                                {\n                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)\n                                                                                  err=UNZ_ERRNO;\n                                                                }\n\n                                                                if(file_info_internal.offset_curfile == MAXU32)\n                                                                {\n                                                                        /* Relative Header offset */\n                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)\n                                                                                err=UNZ_ERRNO;\n                                                                }\n\n                                                                if(file_info.disk_num_start == MAXU32)\n                                                                {\n                                                                        /* Disk Start Number */\n                                                                        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)\n                                                                                err=UNZ_ERRNO;\n                                                                }\n\n            }\n            else\n            {\n                if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)\n                    err=UNZ_ERRNO;\n            }\n\n            acc += 2 + 2 + dataSize;\n        }\n    }\n\n    if ((err==UNZ_OK) && (szComment!=NULL))\n    {\n        uLong uSizeRead ;\n        if (file_info.size_file_comment<commentBufferSize)\n        {\n            *(szComment+file_info.size_file_comment)='\\0';\n            uSizeRead = file_info.size_file_comment;\n        }\n        else\n            uSizeRead = commentBufferSize;\n\n        if (lSeek!=0)\n        {\n            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)\n                lSeek=0;\n            else\n                err=UNZ_ERRNO;\n        }\n\n        if ((file_info.size_file_comment>0) && (commentBufferSize>0))\n            if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)\n                err=UNZ_ERRNO;\n        lSeek+=file_info.size_file_comment - uSizeRead;\n    }\n    else\n        lSeek+=file_info.size_file_comment;\n\n\n    if ((err==UNZ_OK) && (pfile_info!=NULL))\n        *pfile_info=file_info;\n\n    if ((err==UNZ_OK) && (pfile_info_internal!=NULL))\n        *pfile_info_internal=file_info_internal;\n\n    return err;\n}\n\n\n\n/*\n  Write info about the ZipFile in the *pglobal_info structure.\n  No preparation of the structure is needed\n  return UNZ_OK if there is no problem.\n*/\nextern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,\n                                          unz_file_info64 * pfile_info,\n                                          char * szFileName, uLong fileNameBufferSize,\n                                          void *extraField, uLong extraFieldBufferSize,\n                                          char* szComment,  uLong commentBufferSize)\n{\n    return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,\n                                                szFileName,fileNameBufferSize,\n                                                extraField,extraFieldBufferSize,\n                                                szComment,commentBufferSize);\n}\n\nextern int ZEXPORT unzGetCurrentFileInfo (unzFile file,\n                                          unz_file_info * pfile_info,\n                                          char * szFileName, uLong fileNameBufferSize,\n                                          void *extraField, uLong extraFieldBufferSize,\n                                          char* szComment,  uLong commentBufferSize)\n{\n    int err;\n    unz_file_info64 file_info64;\n    err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,\n                                                szFileName,fileNameBufferSize,\n                                                extraField,extraFieldBufferSize,\n                                                szComment,commentBufferSize);\n    if ((err==UNZ_OK) && (pfile_info != NULL))\n    {\n        pfile_info->version = file_info64.version;\n        pfile_info->version_needed = file_info64.version_needed;\n        pfile_info->flag = file_info64.flag;\n        pfile_info->compression_method = file_info64.compression_method;\n        pfile_info->dosDate = file_info64.dosDate;\n        pfile_info->crc = file_info64.crc;\n\n        pfile_info->size_filename = file_info64.size_filename;\n        pfile_info->size_file_extra = file_info64.size_file_extra;\n        pfile_info->size_file_comment = file_info64.size_file_comment;\n\n        pfile_info->disk_num_start = file_info64.disk_num_start;\n        pfile_info->internal_fa = file_info64.internal_fa;\n        pfile_info->external_fa = file_info64.external_fa;\n\n        pfile_info->tmu_date = file_info64.tmu_date,\n\n\n        pfile_info->compressed_size = (uLong)file_info64.compressed_size;\n        pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;\n\n    }\n    return err;\n}\n/*\n  Set the current file of the zipfile to the first file.\n  return UNZ_OK if there is no problem\n*/\nextern int ZEXPORT unzGoToFirstFile (unzFile file)\n{\n    int err=UNZ_OK;\n    unz64_s* s;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    s->pos_in_central_dir=s->offset_central_dir;\n    s->num_file=0;\n    err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,\n                                             &s->cur_file_info_internal,\n                                             NULL,0,NULL,0,NULL,0);\n    s->current_file_ok = (err == UNZ_OK);\n    return err;\n}\n\n/*\n  Set the current file of the zipfile to the next file.\n  return UNZ_OK if there is no problem\n  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.\n*/\nextern int ZEXPORT unzGoToNextFile (unzFile  file)\n{\n    unz64_s* s;\n    int err;\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n        return UNZ_END_OF_LIST_OF_FILE;\n    if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */\n      if (s->num_file+1==s->gi.number_entry)\n        return UNZ_END_OF_LIST_OF_FILE;\n\n    s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +\n            s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;\n    s->num_file++;\n    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,\n                                               &s->cur_file_info_internal,\n                                               NULL,0,NULL,0,NULL,0);\n    s->current_file_ok = (err == UNZ_OK);\n    return err;\n}\n\n\n/*\n  Try locate the file szFileName in the zipfile.\n  For the iCaseSensitivity signification, see unzStringFileNameCompare\n\n  return value :\n  UNZ_OK if the file is found. It becomes the current file.\n  UNZ_END_OF_LIST_OF_FILE if the file is not found\n*/\nextern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)\n{\n    unz64_s* s;\n    int err;\n\n    /* We remember the 'current' position in the file so that we can jump\n     * back there if we fail.\n     */\n    unz_file_info64 cur_file_infoSaved;\n    unz_file_info64_internal cur_file_info_internalSaved;\n    ZPOS64_T num_fileSaved;\n    ZPOS64_T pos_in_central_dirSaved;\n\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n\n    if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)\n        return UNZ_PARAMERROR;\n\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n        return UNZ_END_OF_LIST_OF_FILE;\n\n    /* Save the current state */\n    num_fileSaved = s->num_file;\n    pos_in_central_dirSaved = s->pos_in_central_dir;\n    cur_file_infoSaved = s->cur_file_info;\n    cur_file_info_internalSaved = s->cur_file_info_internal;\n\n    err = unzGoToFirstFile(file);\n\n    while (err == UNZ_OK)\n    {\n        char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];\n        err = unzGetCurrentFileInfo64(file,NULL,\n                                    szCurrentFileName,sizeof(szCurrentFileName)-1,\n                                    NULL,0,NULL,0);\n        if (err == UNZ_OK)\n        {\n            if (unzStringFileNameCompare(szCurrentFileName,\n                                            szFileName,iCaseSensitivity)==0)\n                return UNZ_OK;\n            err = unzGoToNextFile(file);\n        }\n    }\n\n    /* We failed, so restore the state of the 'current file' to where we\n     * were.\n     */\n    s->num_file = num_fileSaved ;\n    s->pos_in_central_dir = pos_in_central_dirSaved ;\n    s->cur_file_info = cur_file_infoSaved;\n    s->cur_file_info_internal = cur_file_info_internalSaved;\n    return err;\n}\n\n\n/*\n///////////////////////////////////////////\n// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)\n// I need random access\n//\n// Further optimization could be realized by adding an ability\n// to cache the directory in memory. The goal being a single\n// comprehensive file read to put the file I need in a memory.\n*/\n\n/*\ntypedef struct unz_file_pos_s\n{\n    ZPOS64_T pos_in_zip_directory;   // offset in file\n    ZPOS64_T num_of_file;            // # of file\n} unz_file_pos;\n*/\n\nextern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos*  file_pos)\n{\n    unz64_s* s;\n\n    if (file==NULL || file_pos==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n        return UNZ_END_OF_LIST_OF_FILE;\n\n    file_pos->pos_in_zip_directory  = s->pos_in_central_dir;\n    file_pos->num_of_file           = s->num_file;\n\n    return UNZ_OK;\n}\n\nextern int ZEXPORT unzGetFilePos(\n    unzFile file,\n    unz_file_pos* file_pos)\n{\n    unz64_file_pos file_pos64;\n    int err = unzGetFilePos64(file,&file_pos64);\n    if (err==UNZ_OK)\n    {\n        file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;\n        file_pos->num_of_file = (uLong)file_pos64.num_of_file;\n    }\n    return err;\n}\n\nextern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)\n{\n    unz64_s* s;\n    int err;\n\n    if (file==NULL || file_pos==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\n    /* jump to the right spot */\n    s->pos_in_central_dir = file_pos->pos_in_zip_directory;\n    s->num_file           = file_pos->num_of_file;\n\n    /* set the current file */\n    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,\n                                               &s->cur_file_info_internal,\n                                               NULL,0,NULL,0,NULL,0);\n    /* return results */\n    s->current_file_ok = (err == UNZ_OK);\n    return err;\n}\n\nextern int ZEXPORT unzGoToFilePos(\n    unzFile file,\n    unz_file_pos* file_pos)\n{\n    unz64_file_pos file_pos64;\n    if (file_pos == NULL)\n        return UNZ_PARAMERROR;\n\n    file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;\n    file_pos64.num_of_file = file_pos->num_of_file;\n    return unzGoToFilePos64(file,&file_pos64);\n}\n\n/*\n// Unzip Helper Functions - should be here?\n///////////////////////////////////////////\n*/\n\n/*\n  Read the local header of the current zipfile\n  Check the coherency of the local header and info in the end of central\n        directory about this file\n  store in *piSizeVar the size of extra info in local header\n        (filename and size of extra field data)\n*/\nlocal int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,\n                                                    ZPOS64_T * poffset_local_extrafield,\n                                                    uInt  * psize_local_extrafield)\n{\n    uLong uMagic,uData,uFlags;\n    uLong size_filename;\n    uLong size_extra_field;\n    int err=UNZ_OK;\n\n    *piSizeVar = 0;\n    *poffset_local_extrafield = 0;\n    *psize_local_extrafield = 0;\n\n    if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +\n                                s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return UNZ_ERRNO;\n\n\n    if (err==UNZ_OK)\n    {\n        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)\n            err=UNZ_ERRNO;\n        else if (uMagic!=0x04034b50)\n            err=UNZ_BADZIPFILE;\n    }\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)\n        err=UNZ_ERRNO;\n/*\n    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))\n        err=UNZ_BADZIPFILE;\n*/\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)\n        err=UNZ_ERRNO;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)\n        err=UNZ_ERRNO;\n    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))\n        err=UNZ_BADZIPFILE;\n\n    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&\n/* #ifdef HAVE_BZIP2 */\n                         (s->cur_file_info.compression_method!=Z_BZIP2ED) &&\n/* #endif */\n                         (s->cur_file_info.compression_method!=Z_DEFLATED))\n        err=UNZ_BADZIPFILE;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */\n        err=UNZ_ERRNO;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */\n        err=UNZ_ERRNO;\n    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))\n        err=UNZ_BADZIPFILE;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */\n        err=UNZ_ERRNO;\n    else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))\n        err=UNZ_BADZIPFILE;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */\n        err=UNZ_ERRNO;\n    else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))\n        err=UNZ_BADZIPFILE;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)\n        err=UNZ_ERRNO;\n    else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))\n        err=UNZ_BADZIPFILE;\n\n    *piSizeVar += (uInt)size_filename;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)\n        err=UNZ_ERRNO;\n    *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +\n                                    SIZEZIPLOCALHEADER + size_filename;\n    *psize_local_extrafield = (uInt)size_extra_field;\n\n    *piSizeVar += (uInt)size_extra_field;\n\n    return err;\n}\n\n/*\n  Open for reading data the current file in the zipfile.\n  If there is no error and the file is opened, the return value is UNZ_OK.\n*/\nextern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,\n                                            int* level, int raw, const char* password)\n{\n    int err=UNZ_OK;\n    uInt iSizeVar;\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    ZPOS64_T offset_local_extrafield;  /* offset of the local extra field */\n    uInt  size_local_extrafield;    /* size of the local extra field */\n#    ifndef NOUNCRYPT\n    char source[12];\n#    else\n    if (password != NULL)\n        return UNZ_PARAMERROR;\n#    endif\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n        return UNZ_PARAMERROR;\n\n    if (s->pfile_in_zip_read != NULL)\n        unzCloseCurrentFile(file);\n\n    if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)\n        return UNZ_BADZIPFILE;\n\n    pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_INTERNALERROR;\n\n    pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);\n    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;\n    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;\n    pfile_in_zip_read_info->pos_local_extrafield=0;\n    pfile_in_zip_read_info->raw=raw;\n\n    if (pfile_in_zip_read_info->read_buffer==NULL)\n    {\n        TRYFREE(pfile_in_zip_read_info);\n        return UNZ_INTERNALERROR;\n    }\n\n    pfile_in_zip_read_info->stream_initialised=0;\n\n    if (method!=NULL)\n        *method = (int)s->cur_file_info.compression_method;\n\n    if (level!=NULL)\n    {\n        *level = 6;\n        switch (s->cur_file_info.flag & 0x06)\n        {\n          case 6 : *level = 1; break;\n          case 4 : *level = 2; break;\n          case 2 : *level = 9; break;\n        }\n    }\n\n    if ((s->cur_file_info.compression_method!=0) &&\n/* #ifdef HAVE_BZIP2 */\n        (s->cur_file_info.compression_method!=Z_BZIP2ED) &&\n/* #endif */\n        (s->cur_file_info.compression_method!=Z_DEFLATED))\n\n        err=UNZ_BADZIPFILE;\n\n    pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;\n    pfile_in_zip_read_info->crc32=0;\n    pfile_in_zip_read_info->total_out_64=0;\n    pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;\n    pfile_in_zip_read_info->filestream=s->filestream;\n    pfile_in_zip_read_info->z_filefunc=s->z_filefunc;\n    pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;\n\n    pfile_in_zip_read_info->stream.total_out = 0;\n\n    if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))\n    {\n#ifdef HAVE_BZIP2\n      pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;\n      pfile_in_zip_read_info->bstream.bzfree = (free_func)0;\n      pfile_in_zip_read_info->bstream.opaque = (voidpf)0;\n      pfile_in_zip_read_info->bstream.state = (voidpf)0;\n\n      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;\n      pfile_in_zip_read_info->stream.zfree = (free_func)0;\n      pfile_in_zip_read_info->stream.opaque = (voidpf)0;\n      pfile_in_zip_read_info->stream.next_in = (voidpf)0;\n      pfile_in_zip_read_info->stream.avail_in = 0;\n\n      err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);\n      if (err == Z_OK)\n        pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;\n      else\n      {\n        TRYFREE(pfile_in_zip_read_info);\n        return err;\n      }\n#else\n      pfile_in_zip_read_info->raw=1;\n#endif\n    }\n    else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))\n    {\n      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;\n      pfile_in_zip_read_info->stream.zfree = (free_func)0;\n      pfile_in_zip_read_info->stream.opaque = (voidpf)0;\n      pfile_in_zip_read_info->stream.next_in = 0;\n      pfile_in_zip_read_info->stream.avail_in = 0;\n\n      err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);\n      if (err == Z_OK)\n        pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;\n      else\n      {\n        TRYFREE(pfile_in_zip_read_info);\n        return err;\n      }\n        /* windowBits is passed < 0 to tell that there is no zlib header.\n         * Note that in this case inflate *requires* an extra \"dummy\" byte\n         * after the compressed stream in order to complete decompression and\n         * return Z_STREAM_END.\n         * In unzip, i don't wait absolutely Z_STREAM_END because I known the\n         * size of both compressed and uncompressed data\n         */\n    }\n    pfile_in_zip_read_info->rest_read_compressed =\n            s->cur_file_info.compressed_size ;\n    pfile_in_zip_read_info->rest_read_uncompressed =\n            s->cur_file_info.uncompressed_size ;\n\n\n    pfile_in_zip_read_info->pos_in_zipfile =\n            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +\n              iSizeVar;\n\n    pfile_in_zip_read_info->stream.avail_in = (uInt)0;\n\n    s->pfile_in_zip_read = pfile_in_zip_read_info;\n                s->encrypted = 0;\n\n#    ifndef NOUNCRYPT\n    if (password != NULL)\n    {\n        int i;\n        s->pcrc_32_tab = get_crc_table();\n        init_keys(password,s->keys,s->pcrc_32_tab);\n        if (ZSEEK64(s->z_filefunc, s->filestream,\n                  s->pfile_in_zip_read->pos_in_zipfile +\n                     s->pfile_in_zip_read->byte_before_the_zipfile,\n                  SEEK_SET)!=0)\n            return UNZ_INTERNALERROR;\n        if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)\n            return UNZ_INTERNALERROR;\n\n        for (i = 0; i<12; i++)\n            zdecode(s->keys,s->pcrc_32_tab,source[i]);\n\n        s->pfile_in_zip_read->pos_in_zipfile+=12;\n        s->encrypted=1;\n    }\n#    endif\n\n\n    return UNZ_OK;\n}\n\nextern int ZEXPORT unzOpenCurrentFile (unzFile file)\n{\n    return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);\n}\n\nextern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char*  password)\n{\n    return unzOpenCurrentFile3(file, NULL, NULL, 0, password);\n}\n\nextern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)\n{\n    return unzOpenCurrentFile3(file, method, level, raw, NULL);\n}\n\n/** Addition for GDAL : START */\n\nextern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)\n{\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    s=(unz64_s*)file;\n    if (file==NULL)\n        return 0; //UNZ_PARAMERROR;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n    if (pfile_in_zip_read_info==NULL)\n        return 0; //UNZ_PARAMERROR;\n    return pfile_in_zip_read_info->pos_in_zipfile +\n                         pfile_in_zip_read_info->byte_before_the_zipfile;\n}\n\n/** Addition for GDAL : END */\n\n/*\n  Read bytes from the current file.\n  buf contain buffer where data must be copied\n  len the size of buf.\n\n  return the number of byte copied if somes bytes are copied\n  return 0 if the end of file was reached\n  return <0 with error code if there is an error\n    (UNZ_ERRNO for IO error, or zLib error for uncompress error)\n*/\nextern int ZEXPORT unzReadCurrentFile  (unzFile file, voidp buf, unsigned len)\n{\n    int err=UNZ_OK;\n    uInt iRead = 0;\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n\n\n    if (pfile_in_zip_read_info->read_buffer == NULL)\n        return UNZ_END_OF_LIST_OF_FILE;\n    if (len==0)\n        return 0;\n\n    pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;\n\n    pfile_in_zip_read_info->stream.avail_out = (uInt)len;\n\n    if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&\n        (!(pfile_in_zip_read_info->raw)))\n        pfile_in_zip_read_info->stream.avail_out =\n            (uInt)pfile_in_zip_read_info->rest_read_uncompressed;\n\n    if ((len>pfile_in_zip_read_info->rest_read_compressed+\n           pfile_in_zip_read_info->stream.avail_in) &&\n         (pfile_in_zip_read_info->raw))\n        pfile_in_zip_read_info->stream.avail_out =\n            (uInt)pfile_in_zip_read_info->rest_read_compressed+\n            pfile_in_zip_read_info->stream.avail_in;\n\n    while (pfile_in_zip_read_info->stream.avail_out>0)\n    {\n        if ((pfile_in_zip_read_info->stream.avail_in==0) &&\n            (pfile_in_zip_read_info->rest_read_compressed>0))\n        {\n            uInt uReadThis = UNZ_BUFSIZE;\n            if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)\n                uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;\n            if (uReadThis == 0)\n                return UNZ_EOF;\n            if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,\n                      pfile_in_zip_read_info->filestream,\n                      pfile_in_zip_read_info->pos_in_zipfile +\n                         pfile_in_zip_read_info->byte_before_the_zipfile,\n                         ZLIB_FILEFUNC_SEEK_SET)!=0)\n                return UNZ_ERRNO;\n            if (ZREAD64(pfile_in_zip_read_info->z_filefunc,\n                      pfile_in_zip_read_info->filestream,\n                      pfile_in_zip_read_info->read_buffer,\n                      uReadThis)!=uReadThis)\n                return UNZ_ERRNO;\n\n\n#            ifndef NOUNCRYPT\n            if(s->encrypted)\n            {\n                uInt i;\n                for(i=0;i<uReadThis;i++)\n                  pfile_in_zip_read_info->read_buffer[i] =\n                      zdecode(s->keys,s->pcrc_32_tab,\n                              pfile_in_zip_read_info->read_buffer[i]);\n            }\n#            endif\n\n\n            pfile_in_zip_read_info->pos_in_zipfile += uReadThis;\n\n            pfile_in_zip_read_info->rest_read_compressed-=uReadThis;\n\n            pfile_in_zip_read_info->stream.next_in =\n                (Bytef*)pfile_in_zip_read_info->read_buffer;\n            pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;\n        }\n\n        if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))\n        {\n            uInt uDoCopy,i ;\n\n            if ((pfile_in_zip_read_info->stream.avail_in == 0) &&\n                (pfile_in_zip_read_info->rest_read_compressed == 0))\n                return (iRead==0) ? UNZ_EOF : iRead;\n\n            if (pfile_in_zip_read_info->stream.avail_out <\n                            pfile_in_zip_read_info->stream.avail_in)\n                uDoCopy = pfile_in_zip_read_info->stream.avail_out ;\n            else\n                uDoCopy = pfile_in_zip_read_info->stream.avail_in ;\n\n            for (i=0;i<uDoCopy;i++)\n                *(pfile_in_zip_read_info->stream.next_out+i) =\n                        *(pfile_in_zip_read_info->stream.next_in+i);\n\n            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;\n\n            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,\n                                pfile_in_zip_read_info->stream.next_out,\n                                uDoCopy);\n            pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;\n            pfile_in_zip_read_info->stream.avail_in -= uDoCopy;\n            pfile_in_zip_read_info->stream.avail_out -= uDoCopy;\n            pfile_in_zip_read_info->stream.next_out += uDoCopy;\n            pfile_in_zip_read_info->stream.next_in += uDoCopy;\n            pfile_in_zip_read_info->stream.total_out += uDoCopy;\n            iRead += uDoCopy;\n        }\n        else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)\n        {\n#ifdef HAVE_BZIP2\n            uLong uTotalOutBefore,uTotalOutAfter;\n            const Bytef *bufBefore;\n            uLong uOutThis;\n\n            pfile_in_zip_read_info->bstream.next_in        = (char*)pfile_in_zip_read_info->stream.next_in;\n            pfile_in_zip_read_info->bstream.avail_in       = pfile_in_zip_read_info->stream.avail_in;\n            pfile_in_zip_read_info->bstream.total_in_lo32  = pfile_in_zip_read_info->stream.total_in;\n            pfile_in_zip_read_info->bstream.total_in_hi32  = 0;\n            pfile_in_zip_read_info->bstream.next_out       = (char*)pfile_in_zip_read_info->stream.next_out;\n            pfile_in_zip_read_info->bstream.avail_out      = pfile_in_zip_read_info->stream.avail_out;\n            pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;\n            pfile_in_zip_read_info->bstream.total_out_hi32 = 0;\n\n            uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;\n            bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;\n\n            err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);\n\n            uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;\n            uOutThis = uTotalOutAfter-uTotalOutBefore;\n\n            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;\n\n            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));\n            pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;\n            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);\n\n            pfile_in_zip_read_info->stream.next_in   = (Bytef*)pfile_in_zip_read_info->bstream.next_in;\n            pfile_in_zip_read_info->stream.avail_in  = pfile_in_zip_read_info->bstream.avail_in;\n            pfile_in_zip_read_info->stream.total_in  = pfile_in_zip_read_info->bstream.total_in_lo32;\n            pfile_in_zip_read_info->stream.next_out  = (Bytef*)pfile_in_zip_read_info->bstream.next_out;\n            pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;\n            pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;\n\n            if (err==BZ_STREAM_END)\n              return (iRead==0) ? UNZ_EOF : iRead;\n            if (err!=BZ_OK)\n              break;\n#endif\n        } // end Z_BZIP2ED\n        else\n        {\n            ZPOS64_T uTotalOutBefore,uTotalOutAfter;\n            const Bytef *bufBefore;\n            ZPOS64_T uOutThis;\n            int flush=Z_SYNC_FLUSH;\n\n            uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;\n            bufBefore = pfile_in_zip_read_info->stream.next_out;\n\n            /*\n            if ((pfile_in_zip_read_info->rest_read_uncompressed ==\n                     pfile_in_zip_read_info->stream.avail_out) &&\n                (pfile_in_zip_read_info->rest_read_compressed == 0))\n                flush = Z_FINISH;\n            */\n            err=inflate(&pfile_in_zip_read_info->stream,flush);\n\n            if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))\n              err = Z_DATA_ERROR;\n\n            uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;\n            uOutThis = uTotalOutAfter-uTotalOutBefore;\n\n            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;\n\n            pfile_in_zip_read_info->crc32 =\n                crc32(pfile_in_zip_read_info->crc32,bufBefore,\n                        (uInt)(uOutThis));\n\n            pfile_in_zip_read_info->rest_read_uncompressed -=\n                uOutThis;\n\n            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);\n\n            if (err==Z_STREAM_END)\n                return (iRead==0) ? UNZ_EOF : iRead;\n            if (err!=Z_OK)\n                break;\n        }\n    }\n\n    if (err==Z_OK)\n        return iRead;\n    return err;\n}\n\n\n/*\n  Give the current position in uncompressed data\n*/\nextern z_off_t ZEXPORT unztell (unzFile file)\n{\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n\n    return (z_off_t)pfile_in_zip_read_info->stream.total_out;\n}\n\nextern ZPOS64_T ZEXPORT unztell64 (unzFile file)\n{\n\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    if (file==NULL)\n        return (ZPOS64_T)-1;\n    s=(unz64_s*)file;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info==NULL)\n        return (ZPOS64_T)-1;\n\n    return pfile_in_zip_read_info->total_out_64;\n}\n\n\n/*\n  return 1 if the end of file was reached, 0 elsewhere\n*/\nextern int ZEXPORT unzeof (unzFile file)\n{\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n\n    if (pfile_in_zip_read_info->rest_read_uncompressed == 0)\n        return 1;\n    else\n        return 0;\n}\n\n\n\n/*\nRead extra field from the current file (opened by unzOpenCurrentFile)\nThis is the local-header version of the extra field (sometimes, there is\nmore info in the local-header version than in the central-header)\n\n  if buf==NULL, it return the size of the local extra field that can be read\n\n  if buf!=NULL, len is the size of the buffer, the extra header is copied in\n    buf.\n  the return value is the number of bytes copied in buf, or (if <0)\n    the error code\n*/\nextern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)\n{\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    uInt read_now;\n    ZPOS64_T size_to_read;\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n\n    size_to_read = (pfile_in_zip_read_info->size_local_extrafield -\n                pfile_in_zip_read_info->pos_local_extrafield);\n\n    if (buf==NULL)\n        return (int)size_to_read;\n\n    if (len>size_to_read)\n        read_now = (uInt)size_to_read;\n    else\n        read_now = (uInt)len ;\n\n    if (read_now==0)\n        return 0;\n\n    if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,\n              pfile_in_zip_read_info->filestream,\n              pfile_in_zip_read_info->offset_local_extrafield +\n              pfile_in_zip_read_info->pos_local_extrafield,\n              ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return UNZ_ERRNO;\n\n    if (ZREAD64(pfile_in_zip_read_info->z_filefunc,\n              pfile_in_zip_read_info->filestream,\n              buf,read_now)!=read_now)\n        return UNZ_ERRNO;\n\n    return (int)read_now;\n}\n\n/*\n  Close the file in zip opened with unzOpenCurrentFile\n  Return UNZ_CRCERROR if all the file was read but the CRC is not good\n*/\nextern int ZEXPORT unzCloseCurrentFile (unzFile file)\n{\n    int err=UNZ_OK;\n\n    unz64_s* s;\n    file_in_zip64_read_info_s* pfile_in_zip_read_info;\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    pfile_in_zip_read_info=s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info==NULL)\n        return UNZ_PARAMERROR;\n\n\n    if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&\n        (!pfile_in_zip_read_info->raw))\n    {\n        if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)\n            err=UNZ_CRCERROR;\n    }\n\n\n    TRYFREE(pfile_in_zip_read_info->read_buffer);\n    pfile_in_zip_read_info->read_buffer = NULL;\n    if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)\n        inflateEnd(&pfile_in_zip_read_info->stream);\n#ifdef HAVE_BZIP2\n    else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)\n        BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);\n#endif\n\n\n    pfile_in_zip_read_info->stream_initialised = 0;\n    TRYFREE(pfile_in_zip_read_info);\n\n    s->pfile_in_zip_read=NULL;\n\n    return err;\n}\n\n\n/*\n  Get the global comment string of the ZipFile, in the szComment buffer.\n  uSizeBuf is the size of the szComment buffer.\n  return the number of byte copied or an error code <0\n*/\nextern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)\n{\n    unz64_s* s;\n    uLong uReadThis ;\n    if (file==NULL)\n        return (int)UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\n    uReadThis = uSizeBuf;\n    if (uReadThis>s->gi.size_comment)\n        uReadThis = s->gi.size_comment;\n\n    if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)\n        return UNZ_ERRNO;\n\n    if (uReadThis>0)\n    {\n      *szComment='\\0';\n      if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)\n        return UNZ_ERRNO;\n    }\n\n    if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))\n        *(szComment+s->gi.size_comment)='\\0';\n    return (int)uReadThis;\n}\n\n/* Additions by RX '2004 */\nextern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)\n{\n    unz64_s* s;\n\n    if (file==NULL)\n          return 0; //UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n    if (!s->current_file_ok)\n      return 0;\n    if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)\n      if (s->num_file==s->gi.number_entry)\n         return 0;\n    return s->pos_in_central_dir;\n}\n\nextern uLong ZEXPORT unzGetOffset (unzFile file)\n{\n    ZPOS64_T offset64;\n\n    if (file==NULL)\n          return 0; //UNZ_PARAMERROR;\n    offset64 = unzGetOffset64(file);\n    return (uLong)offset64;\n}\n\nextern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)\n{\n    unz64_s* s;\n    int err;\n\n    if (file==NULL)\n        return UNZ_PARAMERROR;\n    s=(unz64_s*)file;\n\n    s->pos_in_central_dir = pos;\n    s->num_file = s->gi.number_entry;      /* hack */\n    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,\n                                              &s->cur_file_info_internal,\n                                              NULL,0,NULL,0,NULL,0);\n    s->current_file_ok = (err == UNZ_OK);\n    return err;\n}\n\nextern int ZEXPORT unzSetOffset (unzFile file, uLong pos)\n{\n    return unzSetOffset64(file,pos);\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/unzip.h",
    "content": "/* unzip.h -- IO for uncompress .zip files using zlib\n   Version 1.1, February 14h, 2010\n   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications of Unzip for Zip64\n         Copyright (C) 2007-2008 Even Rouault\n\n         Modifications for Zip64 support on both zip and unzip\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n\n         For more info read MiniZip_info.txt\n\n         ---------------------------------------------------------------------------------\n\n        Condition of use and distribution are the same than zlib :\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  ---------------------------------------------------------------------------------\n\n        Changes\n\n        See header of unzip64.c\n\n*/\n\n#ifndef _unz64_H\n#define _unz64_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifndef _ZLIB_H\n#include \"zlib.h\"\n#endif\n\n#ifndef  _ZLIBIOAPI_H\n#include \"ioapi.h\"\n#endif\n\n#ifdef HAVE_BZIP2\n#include \"bzlib.h\"\n#endif\n\n#define Z_BZIP2ED 12\n\n#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)\n/* like the STRICT of WIN32, we define a pointer that cannot be converted\n    from (void*) without cast */\ntypedef struct TagunzFile__ { int unused; } unzFile__;\ntypedef unzFile__ *unzFile;\n#else\ntypedef voidp unzFile;\n#endif\n\n\n#define UNZ_OK                          (0)\n#define UNZ_END_OF_LIST_OF_FILE         (-100)\n#define UNZ_ERRNO                       (Z_ERRNO)\n#define UNZ_EOF                         (0)\n#define UNZ_PARAMERROR                  (-102)\n#define UNZ_BADZIPFILE                  (-103)\n#define UNZ_INTERNALERROR               (-104)\n#define UNZ_CRCERROR                    (-105)\n\n/* tm_unz contain date/time info */\ntypedef struct tm_unz_s\n{\n    uInt tm_sec;            /* seconds after the minute - [0,59] */\n    uInt tm_min;            /* minutes after the hour - [0,59] */\n    uInt tm_hour;           /* hours since midnight - [0,23] */\n    uInt tm_mday;           /* day of the month - [1,31] */\n    uInt tm_mon;            /* months since January - [0,11] */\n    uInt tm_year;           /* years - [1980..2044] */\n} tm_unz;\n\n/* unz_global_info structure contain global data about the ZIPfile\n   These data comes from the end of central dir */\ntypedef struct unz_global_info64_s\n{\n    ZPOS64_T number_entry;         /* total number of entries in\n                                     the central dir on this disk */\n    uLong size_comment;         /* size of the global comment of the zipfile */\n} unz_global_info64;\n\ntypedef struct unz_global_info_s\n{\n    uLong number_entry;         /* total number of entries in\n                                     the central dir on this disk */\n    uLong size_comment;         /* size of the global comment of the zipfile */\n} unz_global_info;\n\n/* unz_file_info contain information about a file in the zipfile */\ntypedef struct unz_file_info64_s\n{\n    uLong version;              /* version made by                 2 bytes */\n    uLong version_needed;       /* version needed to extract       2 bytes */\n    uLong flag;                 /* general purpose bit flag        2 bytes */\n    uLong compression_method;   /* compression method              2 bytes */\n    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */\n    uLong crc;                  /* crc-32                          4 bytes */\n    ZPOS64_T compressed_size;   /* compressed size                 8 bytes */\n    ZPOS64_T uncompressed_size; /* uncompressed size               8 bytes */\n    uLong size_filename;        /* filename length                 2 bytes */\n    uLong size_file_extra;      /* extra field length              2 bytes */\n    uLong size_file_comment;    /* file comment length             2 bytes */\n\n    uLong disk_num_start;       /* disk number start               2 bytes */\n    uLong internal_fa;          /* internal file attributes        2 bytes */\n    uLong external_fa;          /* external file attributes        4 bytes */\n\n    tm_unz tmu_date;\n} unz_file_info64;\n\ntypedef struct unz_file_info_s\n{\n    uLong version;              /* version made by                 2 bytes */\n    uLong version_needed;       /* version needed to extract       2 bytes */\n    uLong flag;                 /* general purpose bit flag        2 bytes */\n    uLong compression_method;   /* compression method              2 bytes */\n    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */\n    uLong crc;                  /* crc-32                          4 bytes */\n    uLong compressed_size;      /* compressed size                 4 bytes */\n    uLong uncompressed_size;    /* uncompressed size               4 bytes */\n    uLong size_filename;        /* filename length                 2 bytes */\n    uLong size_file_extra;      /* extra field length              2 bytes */\n    uLong size_file_comment;    /* file comment length             2 bytes */\n\n    uLong disk_num_start;       /* disk number start               2 bytes */\n    uLong internal_fa;          /* internal file attributes        2 bytes */\n    uLong external_fa;          /* external file attributes        4 bytes */\n\n    tm_unz tmu_date;\n} unz_file_info;\n\nextern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,\n                                                 const char* fileName2,\n                                                 int iCaseSensitivity));\n/*\n   Compare two filename (fileName1,fileName2).\n   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)\n   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi\n                                or strcasecmp)\n   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system\n    (like 1 on Unix, 2 on Windows)\n*/\n\n\nextern unzFile ZEXPORT unzOpen OF((const char *path));\nextern unzFile ZEXPORT unzOpen64 OF((const void *path));\n/*\n  Open a Zip file. path contain the full pathname (by example,\n     on a Windows XP computer \"c:\\\\zlib\\\\zlib113.zip\" or on an Unix computer\n     \"zlib/zlib113.zip\".\n     If the zipfile cannot be opened (file don't exist or in not valid), the\n       return value is NULL.\n     Else, the return value is a unzFile Handle, usable with other function\n       of this unzip package.\n     the \"64\" function take a const void* pointer, because the path is just the\n       value passed to the open64_file_func callback.\n     Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path\n       is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*\n       does not describe the reality\n*/\n\n\nextern unzFile ZEXPORT unzOpen2 OF((const char *path,\n                                    zlib_filefunc_def* pzlib_filefunc_def));\n/*\n   Open a Zip file, like unzOpen, but provide a set of file low level API\n      for read/write the zip file (see ioapi.h)\n*/\n\nextern unzFile ZEXPORT unzOpen2_64 OF((const void *path,\n                                    zlib_filefunc64_def* pzlib_filefunc_def));\n/*\n   Open a Zip file, like unz64Open, but provide a set of file low level API\n      for read/write the zip file (see ioapi.h)\n*/\n\nextern int ZEXPORT unzClose OF((unzFile file));\n/*\n  Close a ZipFile opened with unzOpen.\n  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),\n    these files MUST be closed with unzCloseCurrentFile before call unzClose.\n  return UNZ_OK if there is no problem. */\n\nextern int ZEXPORT unzGetGlobalInfo OF((unzFile file,\n                                        unz_global_info *pglobal_info));\n\nextern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,\n                                        unz_global_info64 *pglobal_info));\n/*\n  Write info about the ZipFile in the *pglobal_info structure.\n  No preparation of the structure is needed\n  return UNZ_OK if there is no problem. */\n\n\nextern int ZEXPORT unzGetGlobalComment OF((unzFile file,\n                                           char *szComment,\n                                           uLong uSizeBuf));\n/*\n  Get the global comment string of the ZipFile, in the szComment buffer.\n  uSizeBuf is the size of the szComment buffer.\n  return the number of byte copied or an error code <0\n*/\n\n\n/***************************************************************************/\n/* Unzip package allow you browse the directory of the zipfile */\n\nextern int ZEXPORT unzGoToFirstFile OF((unzFile file));\n/*\n  Set the current file of the zipfile to the first file.\n  return UNZ_OK if there is no problem\n*/\n\nextern int ZEXPORT unzGoToNextFile OF((unzFile file));\n/*\n  Set the current file of the zipfile to the next file.\n  return UNZ_OK if there is no problem\n  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.\n*/\n\nextern int ZEXPORT unzLocateFile OF((unzFile file,\n                     const char *szFileName,\n                     int iCaseSensitivity));\n/*\n  Try locate the file szFileName in the zipfile.\n  For the iCaseSensitivity signification, see unzStringFileNameCompare\n\n  return value :\n  UNZ_OK if the file is found. It becomes the current file.\n  UNZ_END_OF_LIST_OF_FILE if the file is not found\n*/\n\n\n/* ****************************************** */\n/* Ryan supplied functions */\n/* unz_file_info contain information about a file in the zipfile */\ntypedef struct unz_file_pos_s\n{\n    uLong pos_in_zip_directory;   /* offset in zip file directory */\n    uLong num_of_file;            /* # of file */\n} unz_file_pos;\n\nextern int ZEXPORT unzGetFilePos(\n    unzFile file,\n    unz_file_pos* file_pos);\n\nextern int ZEXPORT unzGoToFilePos(\n    unzFile file,\n    unz_file_pos* file_pos);\n\ntypedef struct unz64_file_pos_s\n{\n    ZPOS64_T pos_in_zip_directory;   /* offset in zip file directory */\n    ZPOS64_T num_of_file;            /* # of file */\n} unz64_file_pos;\n\nextern int ZEXPORT unzGetFilePos64(\n    unzFile file,\n    unz64_file_pos* file_pos);\n\nextern int ZEXPORT unzGoToFilePos64(\n    unzFile file,\n    const unz64_file_pos* file_pos);\n\n/* ****************************************** */\n\nextern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,\n                         unz_file_info64 *pfile_info,\n                         char *szFileName,\n                         uLong fileNameBufferSize,\n                         void *extraField,\n                         uLong extraFieldBufferSize,\n                         char *szComment,\n                         uLong commentBufferSize));\n\nextern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,\n                         unz_file_info *pfile_info,\n                         char *szFileName,\n                         uLong fileNameBufferSize,\n                         void *extraField,\n                         uLong extraFieldBufferSize,\n                         char *szComment,\n                         uLong commentBufferSize));\n/*\n  Get Info about the current file\n  if pfile_info!=NULL, the *pfile_info structure will contain somes info about\n        the current file\n  if szFileName!=NULL, the filemane string will be copied in szFileName\n            (fileNameBufferSize is the size of the buffer)\n  if extraField!=NULL, the extra field information will be copied in extraField\n            (extraFieldBufferSize is the size of the buffer).\n            This is the Central-header version of the extra field\n  if szComment!=NULL, the comment string of the file will be copied in szComment\n            (commentBufferSize is the size of the buffer)\n*/\n\n\n/** Addition for GDAL : START */\n\nextern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));\n\n/** Addition for GDAL : END */\n\n\n/***************************************************************************/\n/* for reading the content of the current zipfile, you can open it, read data\n   from it, and close it (you can close it before reading all the file)\n   */\n\nextern int ZEXPORT unzOpenCurrentFile OF((unzFile file));\n/*\n  Open for reading data the current file in the zipfile.\n  If there is no error, the return value is UNZ_OK.\n*/\n\nextern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,\n                                                  const char* password));\n/*\n  Open for reading data the current file in the zipfile.\n  password is a crypting password\n  If there is no error, the return value is UNZ_OK.\n*/\n\nextern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,\n                                           int* method,\n                                           int* level,\n                                           int raw));\n/*\n  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)\n    if raw==1\n  *method will receive method of compression, *level will receive level of\n     compression\n  note : you can set level parameter as NULL (if you did not want known level,\n         but you CANNOT set method parameter as NULL\n*/\n\nextern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,\n                                           int* method,\n                                           int* level,\n                                           int raw,\n                                           const char* password));\n/*\n  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)\n    if raw==1\n  *method will receive method of compression, *level will receive level of\n     compression\n  note : you can set level parameter as NULL (if you did not want known level,\n         but you CANNOT set method parameter as NULL\n*/\n\n\nextern int ZEXPORT unzCloseCurrentFile OF((unzFile file));\n/*\n  Close the file in zip opened with unzOpenCurrentFile\n  Return UNZ_CRCERROR if all the file was read but the CRC is not good\n*/\n\nextern int ZEXPORT unzReadCurrentFile OF((unzFile file,\n                      voidp buf,\n                      unsigned len));\n/*\n  Read bytes from the current file (opened by unzOpenCurrentFile)\n  buf contain buffer where data must be copied\n  len the size of buf.\n\n  return the number of byte copied if somes bytes are copied\n  return 0 if the end of file was reached\n  return <0 with error code if there is an error\n    (UNZ_ERRNO for IO error, or zLib error for uncompress error)\n*/\n\nextern z_off_t ZEXPORT unztell OF((unzFile file));\n\nextern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));\n/*\n  Give the current position in uncompressed data\n*/\n\nextern int ZEXPORT unzeof OF((unzFile file));\n/*\n  return 1 if the end of file was reached, 0 elsewhere\n*/\n\nextern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,\n                                             voidp buf,\n                                             unsigned len));\n/*\n  Read extra field from the current file (opened by unzOpenCurrentFile)\n  This is the local-header version of the extra field (sometimes, there is\n    more info in the local-header version than in the central-header)\n\n  if buf==NULL, it return the size of the local extra field\n\n  if buf!=NULL, len is the size of the buffer, the extra header is copied in\n    buf.\n  the return value is the number of bytes copied in buf, or (if <0)\n    the error code\n*/\n\n/***************************************************************************/\n\n/* Get the current file offset */\nextern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);\nextern uLong ZEXPORT unzGetOffset (unzFile file);\n\n/* Set the current file offset */\nextern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);\nextern int ZEXPORT unzSetOffset (unzFile file, uLong pos);\n\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _unz64_H */\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/zip.c",
    "content": "/* zip.c -- IO on .zip files using zlib\n   Version 1.1, February 14h, 2010\n   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications for Zip64 support\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n\n         For more info read MiniZip_info.txt\n\n         Changes\n   Oct-2009 - Mathias Svensson - Remove old C style function prototypes\n   Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives\n   Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.\n   Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data\n                                 It is used when recreting zip archive with RAW when deleting items from a zip.\n                                 ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.\n   Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)\n   Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer\n\n*/\n\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include \"zlib.h\"\n#include \"zip.h\"\n\n#ifdef STDC\n#  include <stddef.h>\n#  include <string.h>\n#  include <stdlib.h>\n#endif\n#ifdef NO_ERRNO_H\n    extern int errno;\n#else\n#   include <errno.h>\n#endif\n\n\n#ifndef local\n#  define local static\n#endif\n/* compile with -Dlocal if your debugger can't find static symbols */\n\n#ifndef VERSIONMADEBY\n# define VERSIONMADEBY   (0x0) /* platform depedent */\n#endif\n\n#ifndef Z_BUFSIZE\n#define Z_BUFSIZE (64*1024) //(16384)\n#endif\n\n#ifndef Z_MAXFILENAMEINZIP\n#define Z_MAXFILENAMEINZIP (256)\n#endif\n\n#ifndef ALLOC\n# define ALLOC(size) (malloc(size))\n#endif\n#ifndef TRYFREE\n# define TRYFREE(p) {if (p) free(p);}\n#endif\n\n/*\n#define SIZECENTRALDIRITEM (0x2e)\n#define SIZEZIPLOCALHEADER (0x1e)\n*/\n\n/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */\n\n\n// NOT sure that this work on ALL platform\n#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))\n\n#ifndef SEEK_CUR\n#define SEEK_CUR    1\n#endif\n\n#ifndef SEEK_END\n#define SEEK_END    2\n#endif\n\n#ifndef SEEK_SET\n#define SEEK_SET    0\n#endif\n\n#ifndef DEF_MEM_LEVEL\n#if MAX_MEM_LEVEL >= 8\n#  define DEF_MEM_LEVEL 8\n#else\n#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL\n#endif\n#endif\nconst char zip_copyright[] =\" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll\";\n\n\n#define SIZEDATA_INDATABLOCK (4096-(4*4))\n\n#define LOCALHEADERMAGIC    (0x04034b50)\n#define CENTRALHEADERMAGIC  (0x02014b50)\n#define ENDHEADERMAGIC      (0x06054b50)\n#define ZIP64ENDHEADERMAGIC      (0x6064b50)\n#define ZIP64ENDLOCHEADERMAGIC   (0x7064b50)\n\n#define FLAG_LOCALHEADER_OFFSET (0x06)\n#define CRC_LOCALHEADER_OFFSET  (0x0e)\n\n#define SIZECENTRALHEADER (0x2e) /* 46 */\n\ntypedef struct linkedlist_datablock_internal_s\n{\n  struct linkedlist_datablock_internal_s* next_datablock;\n  uLong  avail_in_this_block;\n  uLong  filled_in_this_block;\n  uLong  unused; /* for future use and alignement */\n  unsigned char data[SIZEDATA_INDATABLOCK];\n} linkedlist_datablock_internal;\n\ntypedef struct linkedlist_data_s\n{\n    linkedlist_datablock_internal* first_block;\n    linkedlist_datablock_internal* last_block;\n} linkedlist_data;\n\n\ntypedef struct\n{\n    z_stream stream;            /* zLib stream structure for inflate */\n#ifdef HAVE_BZIP2\n    bz_stream bstream;          /* bzLib stream structure for bziped */\n#endif\n\n    int  stream_initialised;    /* 1 is stream is initialised */\n    uInt pos_in_buffered_data;  /* last written byte in buffered_data */\n\n    ZPOS64_T pos_local_header;     /* offset of the local header of the file\n                                     currenty writing */\n    char* central_header;       /* central header data for the current file */\n    uLong size_centralExtra;\n    uLong size_centralheader;   /* size of the central header for cur file */\n    uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */\n    uLong flag;                 /* flag of the file currently writing */\n\n    int  method;                /* compression method of file currenty wr.*/\n    int  raw;                   /* 1 for directly writing raw data */\n    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/\n    uLong dosDate;\n    uLong crc32;\n    int  encrypt;\n    int  zip64;               /* Add ZIP64 extened information in the extra field */\n    ZPOS64_T pos_zip64extrainfo;\n    ZPOS64_T totalCompressedData;\n    ZPOS64_T totalUncompressedData;\n#ifndef NOCRYPT\n    unsigned long keys[3];     /* keys defining the pseudo-random sequence */\n    const z_crc_t* pcrc_32_tab;\n    int crypt_header_size;\n#endif\n} curfile64_info;\n\ntypedef struct\n{\n    zlib_filefunc64_32_def z_filefunc;\n    voidpf filestream;        /* io structore of the zipfile */\n    linkedlist_data central_dir;/* datablock with central dir in construction*/\n    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/\n    curfile64_info ci;            /* info on the file curretly writing */\n\n    ZPOS64_T begin_pos;            /* position of the beginning of the zipfile */\n    ZPOS64_T add_position_when_writting_offset;\n    ZPOS64_T number_entry;\n\n#ifndef NO_ADDFILEINEXISTINGZIP\n    char *globalcomment;\n#endif\n\n} zip64_internal;\n\n\n#ifndef NOCRYPT\n#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED\n#include \"crypt.h\"\n#endif\n\nlocal linkedlist_datablock_internal* allocate_new_datablock()\n{\n    linkedlist_datablock_internal* ldi;\n    ldi = (linkedlist_datablock_internal*)\n                 ALLOC(sizeof(linkedlist_datablock_internal));\n    if (ldi!=NULL)\n    {\n        ldi->next_datablock = NULL ;\n        ldi->filled_in_this_block = 0 ;\n        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;\n    }\n    return ldi;\n}\n\nlocal void free_datablock(linkedlist_datablock_internal* ldi)\n{\n    while (ldi!=NULL)\n    {\n        linkedlist_datablock_internal* ldinext = ldi->next_datablock;\n        TRYFREE(ldi);\n        ldi = ldinext;\n    }\n}\n\nlocal void init_linkedlist(linkedlist_data* ll)\n{\n    ll->first_block = ll->last_block = NULL;\n}\n\nlocal void free_linkedlist(linkedlist_data* ll)\n{\n    free_datablock(ll->first_block);\n    ll->first_block = ll->last_block = NULL;\n}\n\n\nlocal int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)\n{\n    linkedlist_datablock_internal* ldi;\n    const unsigned char* from_copy;\n\n    if (ll==NULL)\n        return ZIP_INTERNALERROR;\n\n    if (ll->last_block == NULL)\n    {\n        ll->first_block = ll->last_block = allocate_new_datablock();\n        if (ll->first_block == NULL)\n            return ZIP_INTERNALERROR;\n    }\n\n    ldi = ll->last_block;\n    from_copy = (unsigned char*)buf;\n\n    while (len>0)\n    {\n        uInt copy_this;\n        uInt i;\n        unsigned char* to_copy;\n\n        if (ldi->avail_in_this_block==0)\n        {\n            ldi->next_datablock = allocate_new_datablock();\n            if (ldi->next_datablock == NULL)\n                return ZIP_INTERNALERROR;\n            ldi = ldi->next_datablock ;\n            ll->last_block = ldi;\n        }\n\n        if (ldi->avail_in_this_block < len)\n            copy_this = (uInt)ldi->avail_in_this_block;\n        else\n            copy_this = (uInt)len;\n\n        to_copy = &(ldi->data[ldi->filled_in_this_block]);\n\n        for (i=0;i<copy_this;i++)\n            *(to_copy+i)=*(from_copy+i);\n\n        ldi->filled_in_this_block += copy_this;\n        ldi->avail_in_this_block -= copy_this;\n        from_copy += copy_this ;\n        len -= copy_this;\n    }\n    return ZIP_OK;\n}\n\n\n\n/****************************************************************************/\n\n#ifndef NO_ADDFILEINEXISTINGZIP\n/* ===========================================================================\n   Inputs a long in LSB order to the given file\n   nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)\n*/\n\nlocal int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));\nlocal int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)\n{\n    unsigned char buf[8];\n    int n;\n    for (n = 0; n < nbByte; n++)\n    {\n        buf[n] = (unsigned char)(x & 0xff);\n        x >>= 8;\n    }\n    if (x != 0)\n      {     /* data overflow - hack for ZIP64 (X Roche) */\n      for (n = 0; n < nbByte; n++)\n        {\n          buf[n] = 0xff;\n        }\n      }\n\n    if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)\n        return ZIP_ERRNO;\n    else\n        return ZIP_OK;\n}\n\nlocal void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));\nlocal void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)\n{\n    unsigned char* buf=(unsigned char*)dest;\n    int n;\n    for (n = 0; n < nbByte; n++) {\n        buf[n] = (unsigned char)(x & 0xff);\n        x >>= 8;\n    }\n\n    if (x != 0)\n    {     /* data overflow - hack for ZIP64 */\n       for (n = 0; n < nbByte; n++)\n       {\n          buf[n] = 0xff;\n       }\n    }\n}\n\n/****************************************************************************/\n\n\nlocal uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)\n{\n    uLong year = (uLong)ptm->tm_year;\n    if (year>=1980)\n        year-=1980;\n    else if (year>=80)\n        year-=80;\n    return\n      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |\n        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));\n}\n\n\n/****************************************************************************/\n\nlocal int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));\n\nlocal int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)\n{\n    unsigned char c;\n    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);\n    if (err==1)\n    {\n        *pi = (int)c;\n        return ZIP_OK;\n    }\n    else\n    {\n        if (ZERROR64(*pzlib_filefunc_def,filestream))\n            return ZIP_ERRNO;\n        else\n            return ZIP_EOF;\n    }\n}\n\n\n/* ===========================================================================\n   Reads a long in LSB order from the given gz_stream. Sets\n*/\nlocal int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));\n\nlocal int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)\n{\n    uLong x ;\n    int i = 0;\n    int err;\n\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x = (uLong)i;\n\n    if (err==ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x += ((uLong)i)<<8;\n\n    if (err==ZIP_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\nlocal int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));\n\nlocal int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)\n{\n    uLong x ;\n    int i = 0;\n    int err;\n\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x = (uLong)i;\n\n    if (err==ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x += ((uLong)i)<<8;\n\n    if (err==ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x += ((uLong)i)<<16;\n\n    if (err==ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n    x += ((uLong)i)<<24;\n\n    if (err==ZIP_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\nlocal int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));\n\n\nlocal int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)\n{\n  ZPOS64_T x;\n  int i = 0;\n  int err;\n\n  err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x = (ZPOS64_T)i;\n\n  if (err==ZIP_OK)\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x += ((ZPOS64_T)i)<<8;\n\n  if (err==ZIP_OK)\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x += ((ZPOS64_T)i)<<16;\n\n  if (err==ZIP_OK)\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x += ((ZPOS64_T)i)<<24;\n\n  if (err==ZIP_OK)\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x += ((ZPOS64_T)i)<<32;\n\n  if (err==ZIP_OK)\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x += ((ZPOS64_T)i)<<40;\n\n  if (err==ZIP_OK)\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x += ((ZPOS64_T)i)<<48;\n\n  if (err==ZIP_OK)\n    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);\n  x += ((ZPOS64_T)i)<<56;\n\n  if (err==ZIP_OK)\n    *pX = x;\n  else\n    *pX = 0;\n\n  return err;\n}\n\n#ifndef BUFREADCOMMENT\n#define BUFREADCOMMENT (0x400)\n#endif\n/*\n  Locate the Central directory of a zipfile (at the end, just before\n    the global comment)\n*/\nlocal ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));\n\nlocal ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)\n{\n  unsigned char* buf;\n  ZPOS64_T uSizeFile;\n  ZPOS64_T uBackRead;\n  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */\n  ZPOS64_T uPosFound=0;\n\n  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)\n    return 0;\n\n\n  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);\n\n  if (uMaxBack>uSizeFile)\n    uMaxBack = uSizeFile;\n\n  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);\n  if (buf==NULL)\n    return 0;\n\n  uBackRead = 4;\n  while (uBackRead<uMaxBack)\n  {\n    uLong uReadSize;\n    ZPOS64_T uReadPos ;\n    int i;\n    if (uBackRead+BUFREADCOMMENT>uMaxBack)\n      uBackRead = uMaxBack;\n    else\n      uBackRead+=BUFREADCOMMENT;\n    uReadPos = uSizeFile-uBackRead ;\n\n    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?\n      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);\n    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n      break;\n\n    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)\n      break;\n\n    for (i=(int)uReadSize-3; (i--)>0;)\n      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&\n        ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))\n      {\n        uPosFound = uReadPos+i;\n        break;\n      }\n\n      if (uPosFound!=0)\n        break;\n  }\n  TRYFREE(buf);\n  return uPosFound;\n}\n\n/*\nLocate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before\nthe global comment)\n*/\nlocal ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));\n\nlocal ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)\n{\n  unsigned char* buf;\n  ZPOS64_T uSizeFile;\n  ZPOS64_T uBackRead;\n  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */\n  ZPOS64_T uPosFound=0;\n  uLong uL;\n  ZPOS64_T relativeOffset;\n\n  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)\n    return 0;\n\n  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);\n\n  if (uMaxBack>uSizeFile)\n    uMaxBack = uSizeFile;\n\n  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);\n  if (buf==NULL)\n    return 0;\n\n  uBackRead = 4;\n  while (uBackRead<uMaxBack)\n  {\n    uLong uReadSize;\n    ZPOS64_T uReadPos;\n    int i;\n    if (uBackRead+BUFREADCOMMENT>uMaxBack)\n      uBackRead = uMaxBack;\n    else\n      uBackRead+=BUFREADCOMMENT;\n    uReadPos = uSizeFile-uBackRead ;\n\n    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?\n      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);\n    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n      break;\n\n    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)\n      break;\n\n    for (i=(int)uReadSize-3; (i--)>0;)\n    {\n      // Signature \"0x07064b50\" Zip64 end of central directory locater\n      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))\n      {\n        uPosFound = uReadPos+i;\n        break;\n      }\n    }\n\n      if (uPosFound!=0)\n        break;\n  }\n\n  TRYFREE(buf);\n  if (uPosFound == 0)\n    return 0;\n\n  /* Zip64 end of central directory locator */\n  if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)\n    return 0;\n\n  /* the signature, already checked */\n  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)\n    return 0;\n\n  /* number of the disk with the start of the zip64 end of  central directory */\n  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)\n    return 0;\n  if (uL != 0)\n    return 0;\n\n  /* relative offset of the zip64 end of central directory record */\n  if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)\n    return 0;\n\n  /* total number of disks */\n  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)\n    return 0;\n  if (uL != 1)\n    return 0;\n\n  /* Goto Zip64 end of central directory record */\n  if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)\n    return 0;\n\n  /* the signature */\n  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)\n    return 0;\n\n  if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'\n    return 0;\n\n  return relativeOffset;\n}\n\nint LoadCentralDirectoryRecord(zip64_internal* pziinit)\n{\n  int err=ZIP_OK;\n  ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/\n\n  ZPOS64_T size_central_dir;     /* size of the central directory  */\n  ZPOS64_T offset_central_dir;   /* offset of start of central directory */\n  ZPOS64_T central_pos;\n  uLong uL;\n\n  uLong number_disk;          /* number of the current dist, used for\n                              spaning ZIP, unsupported, always 0*/\n  uLong number_disk_with_CD;  /* number the the disk with central dir, used\n                              for spaning ZIP, unsupported, always 0*/\n  ZPOS64_T number_entry;\n  ZPOS64_T number_entry_CD;      /* total number of entries in\n                                the central dir\n                                (same than number_entry on nospan) */\n  uLong VersionMadeBy;\n  uLong VersionNeeded;\n  uLong size_comment;\n\n  int hasZIP64Record = 0;\n\n  // check first if we find a ZIP64 record\n  central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);\n  if(central_pos > 0)\n  {\n    hasZIP64Record = 1;\n  }\n  else if(central_pos == 0)\n  {\n    central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);\n  }\n\n/* disable to allow appending to empty ZIP archive\n        if (central_pos==0)\n            err=ZIP_ERRNO;\n*/\n\n  if(hasZIP64Record)\n  {\n    ZPOS64_T sizeEndOfCentralDirectory;\n    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)\n      err=ZIP_ERRNO;\n\n    /* the signature, already checked */\n    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* size of zip64 end of central directory record */\n    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* version made by */\n    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* version needed to extract */\n    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* number of this disk */\n    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* number of the disk with the start of the central directory */\n    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* total number of entries in the central directory on this disk */\n    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* total number of entries in the central directory */\n    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))\n      err=ZIP_BADZIPFILE;\n\n    /* size of the central directory */\n    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* offset of start of central directory with respect to the\n    starting disk number */\n    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    // TODO..\n    // read the comment from the standard central header.\n    size_comment = 0;\n  }\n  else\n  {\n    // Read End of central Directory info\n    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)\n      err=ZIP_ERRNO;\n\n    /* the signature, already checked */\n    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* number of this disk */\n    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* number of the disk with the start of the central directory */\n    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)\n      err=ZIP_ERRNO;\n\n    /* total number of entries in the central dir on this disk */\n    number_entry = 0;\n    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)\n      err=ZIP_ERRNO;\n    else\n      number_entry = uL;\n\n    /* total number of entries in the central dir */\n    number_entry_CD = 0;\n    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)\n      err=ZIP_ERRNO;\n    else\n      number_entry_CD = uL;\n\n    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))\n      err=ZIP_BADZIPFILE;\n\n    /* size of the central directory */\n    size_central_dir = 0;\n    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)\n      err=ZIP_ERRNO;\n    else\n      size_central_dir = uL;\n\n    /* offset of start of central directory with respect to the starting disk number */\n    offset_central_dir = 0;\n    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)\n      err=ZIP_ERRNO;\n    else\n      offset_central_dir = uL;\n\n\n    /* zipfile global comment length */\n    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)\n      err=ZIP_ERRNO;\n  }\n\n  if ((central_pos<offset_central_dir+size_central_dir) &&\n    (err==ZIP_OK))\n    err=ZIP_BADZIPFILE;\n\n  if (err!=ZIP_OK)\n  {\n    ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);\n    return ZIP_ERRNO;\n  }\n\n  if (size_comment>0)\n  {\n    pziinit->globalcomment = (char*)ALLOC(size_comment+1);\n    if (pziinit->globalcomment)\n    {\n      size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);\n      pziinit->globalcomment[size_comment]=0;\n    }\n  }\n\n  byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);\n  pziinit->add_position_when_writting_offset = byte_before_the_zipfile;\n\n  {\n    ZPOS64_T size_central_dir_to_read = size_central_dir;\n    size_t buf_size = SIZEDATA_INDATABLOCK;\n    void* buf_read = (void*)ALLOC(buf_size);\n    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)\n      err=ZIP_ERRNO;\n\n    while ((size_central_dir_to_read>0) && (err==ZIP_OK))\n    {\n      ZPOS64_T read_this = SIZEDATA_INDATABLOCK;\n      if (read_this > size_central_dir_to_read)\n        read_this = size_central_dir_to_read;\n\n      if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)\n        err=ZIP_ERRNO;\n\n      if (err==ZIP_OK)\n        err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);\n\n      size_central_dir_to_read-=read_this;\n    }\n    TRYFREE(buf_read);\n  }\n  pziinit->begin_pos = byte_before_the_zipfile;\n  pziinit->number_entry = number_entry_CD;\n\n  if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)\n    err=ZIP_ERRNO;\n\n  return err;\n}\n\n\n#endif /* !NO_ADDFILEINEXISTINGZIP*/\n\n\n/************************************************************/\nextern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)\n{\n    zip64_internal ziinit;\n    zip64_internal* zi;\n    int err=ZIP_OK;\n\n    ziinit.z_filefunc.zseek32_file = NULL;\n    ziinit.z_filefunc.ztell32_file = NULL;\n    if (pzlib_filefunc64_32_def==NULL)\n        fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);\n    else\n        ziinit.z_filefunc = *pzlib_filefunc64_32_def;\n\n    ziinit.filestream = ZOPEN64(ziinit.z_filefunc,\n                  pathname,\n                  (append == APPEND_STATUS_CREATE) ?\n                  (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :\n                    (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));\n\n    if (ziinit.filestream == NULL)\n        return NULL;\n\n    if (append == APPEND_STATUS_CREATEAFTER)\n        ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);\n\n    ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);\n    ziinit.in_opened_file_inzip = 0;\n    ziinit.ci.stream_initialised = 0;\n    ziinit.number_entry = 0;\n    ziinit.add_position_when_writting_offset = 0;\n    init_linkedlist(&(ziinit.central_dir));\n\n\n\n    zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));\n    if (zi==NULL)\n    {\n        ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);\n        return NULL;\n    }\n\n    /* now we add file in a zipfile */\n#    ifndef NO_ADDFILEINEXISTINGZIP\n    ziinit.globalcomment = NULL;\n    if (append == APPEND_STATUS_ADDINZIP)\n    {\n      // Read and Cache Central Directory Records\n      err = LoadCentralDirectoryRecord(&ziinit);\n    }\n\n    if (globalcomment)\n    {\n      *globalcomment = ziinit.globalcomment;\n    }\n#    endif /* !NO_ADDFILEINEXISTINGZIP*/\n\n    if (err != ZIP_OK)\n    {\n#    ifndef NO_ADDFILEINEXISTINGZIP\n        TRYFREE(ziinit.globalcomment);\n#    endif /* !NO_ADDFILEINEXISTINGZIP*/\n        TRYFREE(zi);\n        return NULL;\n    }\n    else\n    {\n        *zi = ziinit;\n        return (zipFile)zi;\n    }\n}\n\nextern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)\n{\n    if (pzlib_filefunc32_def != NULL)\n    {\n        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;\n        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);\n        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);\n    }\n    else\n        return zipOpen3(pathname, append, globalcomment, NULL);\n}\n\nextern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)\n{\n    if (pzlib_filefunc_def != NULL)\n    {\n        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;\n        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;\n        zlib_filefunc64_32_def_fill.ztell32_file = NULL;\n        zlib_filefunc64_32_def_fill.zseek32_file = NULL;\n        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);\n    }\n    else\n        return zipOpen3(pathname, append, globalcomment, NULL);\n}\n\n\n\nextern zipFile ZEXPORT zipOpen (const char* pathname, int append)\n{\n    return zipOpen3((const void*)pathname,append,NULL,NULL);\n}\n\nextern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)\n{\n    return zipOpen3(pathname,append,NULL,NULL);\n}\n\nint Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)\n{\n  /* write the local header */\n  int err;\n  uInt size_filename = (uInt)strlen(filename);\n  uInt size_extrafield = size_extrafield_local;\n\n  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);\n\n  if (err==ZIP_OK)\n  {\n    if(zi->ci.zip64)\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */\n    else\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */\n  }\n\n  if (err==ZIP_OK)\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);\n\n  if (err==ZIP_OK)\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);\n\n  if (err==ZIP_OK)\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);\n\n  // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later\n  if (err==ZIP_OK)\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */\n  if (err==ZIP_OK)\n  {\n    if(zi->ci.zip64)\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */\n    else\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */\n  }\n  if (err==ZIP_OK)\n  {\n    if(zi->ci.zip64)\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */\n    else\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */\n  }\n\n  if (err==ZIP_OK)\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);\n\n  if(zi->ci.zip64)\n  {\n    size_extrafield += 20;\n  }\n\n  if (err==ZIP_OK)\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);\n\n  if ((err==ZIP_OK) && (size_filename > 0))\n  {\n    if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)\n      err = ZIP_ERRNO;\n  }\n\n  if ((err==ZIP_OK) && (size_extrafield_local > 0))\n  {\n    if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)\n      err = ZIP_ERRNO;\n  }\n\n\n  if ((err==ZIP_OK) && (zi->ci.zip64))\n  {\n      // write the Zip64 extended info\n      short HeaderID = 1;\n      short DataSize = 16;\n      ZPOS64_T CompressedSize = 0;\n      ZPOS64_T UncompressedSize = 0;\n\n      // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)\n      zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);\n\n      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);\n      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);\n\n      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);\n      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);\n  }\n\n  return err;\n}\n\n/*\n NOTE.\n When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped\n before calling this function it can be done with zipRemoveExtraInfoBlock\n\n It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize\n unnecessary allocations.\n */\nextern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                         const void* extrafield_local, uInt size_extrafield_local,\n                                         const void* extrafield_global, uInt size_extrafield_global,\n                                         const char* comment, int method, int level, int raw,\n                                         int windowBits,int memLevel, int strategy,\n                                         const char* password, uLong crcForCrypting,\n                                         uLong versionMadeBy, uLong flagBase, int zip64)\n{\n    zip64_internal* zi;\n    uInt size_filename;\n    uInt size_comment;\n    uInt i;\n    int err = ZIP_OK;\n\n#    ifdef NOCRYPT\n    (crcForCrypting);\n    if (password != NULL)\n        return ZIP_PARAMERROR;\n#    endif\n\n    if (file == NULL)\n        return ZIP_PARAMERROR;\n\n#ifdef HAVE_BZIP2\n    if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))\n      return ZIP_PARAMERROR;\n#else\n    if ((method!=0) && (method!=Z_DEFLATED))\n      return ZIP_PARAMERROR;\n#endif\n\n    zi = (zip64_internal*)file;\n\n    if (zi->in_opened_file_inzip == 1)\n    {\n        err = zipCloseFileInZip (file);\n        if (err != ZIP_OK)\n            return err;\n    }\n\n    if (filename==NULL)\n        filename=\"-\";\n\n    if (comment==NULL)\n        size_comment = 0;\n    else\n        size_comment = (uInt)strlen(comment);\n\n    size_filename = (uInt)strlen(filename);\n\n    if (zipfi == NULL)\n        zi->ci.dosDate = 0;\n    else\n    {\n        if (zipfi->dosDate != 0)\n            zi->ci.dosDate = zipfi->dosDate;\n        else\n          zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);\n    }\n\n    zi->ci.flag = flagBase;\n    if ((level==8) || (level==9))\n      zi->ci.flag |= 2;\n    if (level==2)\n      zi->ci.flag |= 4;\n    if (level==1)\n      zi->ci.flag |= 6;\n    if (password != NULL)\n      zi->ci.flag |= 1;\n\n    zi->ci.crc32 = 0;\n    zi->ci.method = method;\n    zi->ci.encrypt = 0;\n    zi->ci.stream_initialised = 0;\n    zi->ci.pos_in_buffered_data = 0;\n    zi->ci.raw = raw;\n    zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);\n\n    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;\n    zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data\n\n    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);\n\n    zi->ci.size_centralExtra = size_extrafield_global;\n    zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);\n    /* version info */\n    zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);\n    zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);\n    zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);\n    zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);\n    zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);\n    zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/\n    zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/\n    zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/\n    zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);\n    zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);\n    zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);\n    zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/\n\n    if (zipfi==NULL)\n        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);\n    else\n        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);\n\n    if (zipfi==NULL)\n        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);\n    else\n        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);\n\n    if(zi->ci.pos_local_header >= 0xffffffff)\n      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);\n    else\n      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);\n\n    for (i=0;i<size_filename;i++)\n        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);\n\n    for (i=0;i<size_extrafield_global;i++)\n        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =\n              *(((const char*)extrafield_global)+i);\n\n    for (i=0;i<size_comment;i++)\n        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+\n              size_extrafield_global+i) = *(comment+i);\n    if (zi->ci.central_header == NULL)\n        return ZIP_INTERNALERROR;\n\n    zi->ci.zip64 = zip64;\n    zi->ci.totalCompressedData = 0;\n    zi->ci.totalUncompressedData = 0;\n    zi->ci.pos_zip64extrainfo = 0;\n\n    err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);\n\n#ifdef HAVE_BZIP2\n    zi->ci.bstream.avail_in = (uInt)0;\n    zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;\n    zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;\n    zi->ci.bstream.total_in_hi32 = 0;\n    zi->ci.bstream.total_in_lo32 = 0;\n    zi->ci.bstream.total_out_hi32 = 0;\n    zi->ci.bstream.total_out_lo32 = 0;\n#endif\n\n    zi->ci.stream.avail_in = (uInt)0;\n    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;\n    zi->ci.stream.next_out = zi->ci.buffered_data;\n    zi->ci.stream.total_in = 0;\n    zi->ci.stream.total_out = 0;\n    zi->ci.stream.data_type = Z_BINARY;\n\n#ifdef HAVE_BZIP2\n    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))\n#else\n    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))\n#endif\n    {\n        if(zi->ci.method == Z_DEFLATED)\n        {\n          zi->ci.stream.zalloc = (alloc_func)0;\n          zi->ci.stream.zfree = (free_func)0;\n          zi->ci.stream.opaque = (voidpf)0;\n\n          if (windowBits>0)\n              windowBits = -windowBits;\n\n          err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);\n\n          if (err==Z_OK)\n              zi->ci.stream_initialised = Z_DEFLATED;\n        }\n        else if(zi->ci.method == Z_BZIP2ED)\n        {\n#ifdef HAVE_BZIP2\n            // Init BZip stuff here\n          zi->ci.bstream.bzalloc = 0;\n          zi->ci.bstream.bzfree = 0;\n          zi->ci.bstream.opaque = (voidpf)0;\n\n          err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);\n          if(err == BZ_OK)\n            zi->ci.stream_initialised = Z_BZIP2ED;\n#endif\n        }\n\n    }\n\n#    ifndef NOCRYPT\n    zi->ci.crypt_header_size = 0;\n    if ((err==Z_OK) && (password != NULL))\n    {\n        unsigned char bufHead[RAND_HEAD_LEN];\n        unsigned int sizeHead;\n        zi->ci.encrypt = 1;\n        zi->ci.pcrc_32_tab = get_crc_table();\n        /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/\n\n        sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);\n        zi->ci.crypt_header_size = sizeHead;\n\n        if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)\n                err = ZIP_ERRNO;\n    }\n#    endif\n\n    if (err==Z_OK)\n        zi->in_opened_file_inzip = 1;\n    return err;\n}\n\nextern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                         const void* extrafield_local, uInt size_extrafield_local,\n                                         const void* extrafield_global, uInt size_extrafield_global,\n                                         const char* comment, int method, int level, int raw,\n                                         int windowBits,int memLevel, int strategy,\n                                         const char* password, uLong crcForCrypting,\n                                         uLong versionMadeBy, uLong flagBase)\n{\n    return zipOpenNewFileInZip4_64 (file, filename, zipfi,\n                                 extrafield_local, size_extrafield_local,\n                                 extrafield_global, size_extrafield_global,\n                                 comment, method, level, raw,\n                                 windowBits, memLevel, strategy,\n                                 password, crcForCrypting, versionMadeBy, flagBase, 0);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                         const void* extrafield_local, uInt size_extrafield_local,\n                                         const void* extrafield_global, uInt size_extrafield_global,\n                                         const char* comment, int method, int level, int raw,\n                                         int windowBits,int memLevel, int strategy,\n                                         const char* password, uLong crcForCrypting)\n{\n    return zipOpenNewFileInZip4_64 (file, filename, zipfi,\n                                 extrafield_local, size_extrafield_local,\n                                 extrafield_global, size_extrafield_global,\n                                 comment, method, level, raw,\n                                 windowBits, memLevel, strategy,\n                                 password, crcForCrypting, VERSIONMADEBY, 0, 0);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                         const void* extrafield_local, uInt size_extrafield_local,\n                                         const void* extrafield_global, uInt size_extrafield_global,\n                                         const char* comment, int method, int level, int raw,\n                                         int windowBits,int memLevel, int strategy,\n                                         const char* password, uLong crcForCrypting, int zip64)\n{\n    return zipOpenNewFileInZip4_64 (file, filename, zipfi,\n                                 extrafield_local, size_extrafield_local,\n                                 extrafield_global, size_extrafield_global,\n                                 comment, method, level, raw,\n                                 windowBits, memLevel, strategy,\n                                 password, crcForCrypting, VERSIONMADEBY, 0, zip64);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                        const void* extrafield_local, uInt size_extrafield_local,\n                                        const void* extrafield_global, uInt size_extrafield_global,\n                                        const char* comment, int method, int level, int raw)\n{\n    return zipOpenNewFileInZip4_64 (file, filename, zipfi,\n                                 extrafield_local, size_extrafield_local,\n                                 extrafield_global, size_extrafield_global,\n                                 comment, method, level, raw,\n                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,\n                                 NULL, 0, VERSIONMADEBY, 0, 0);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                        const void* extrafield_local, uInt size_extrafield_local,\n                                        const void* extrafield_global, uInt size_extrafield_global,\n                                        const char* comment, int method, int level, int raw, int zip64)\n{\n    return zipOpenNewFileInZip4_64 (file, filename, zipfi,\n                                 extrafield_local, size_extrafield_local,\n                                 extrafield_global, size_extrafield_global,\n                                 comment, method, level, raw,\n                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,\n                                 NULL, 0, VERSIONMADEBY, 0, zip64);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                        const void* extrafield_local, uInt size_extrafield_local,\n                                        const void*extrafield_global, uInt size_extrafield_global,\n                                        const char* comment, int method, int level, int zip64)\n{\n    return zipOpenNewFileInZip4_64 (file, filename, zipfi,\n                                 extrafield_local, size_extrafield_local,\n                                 extrafield_global, size_extrafield_global,\n                                 comment, method, level, 0,\n                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,\n                                 NULL, 0, VERSIONMADEBY, 0, zip64);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,\n                                        const void* extrafield_local, uInt size_extrafield_local,\n                                        const void*extrafield_global, uInt size_extrafield_global,\n                                        const char* comment, int method, int level)\n{\n    return zipOpenNewFileInZip4_64 (file, filename, zipfi,\n                                 extrafield_local, size_extrafield_local,\n                                 extrafield_global, size_extrafield_global,\n                                 comment, method, level, 0,\n                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,\n                                 NULL, 0, VERSIONMADEBY, 0, 0);\n}\n\nlocal int zip64FlushWriteBuffer(zip64_internal* zi)\n{\n    int err=ZIP_OK;\n\n    if (zi->ci.encrypt != 0)\n    {\n#ifndef NOCRYPT\n        uInt i;\n        int t;\n        for (i=0;i<zi->ci.pos_in_buffered_data;i++)\n            zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);\n#endif\n    }\n\n    if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)\n      err = ZIP_ERRNO;\n\n    zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;\n\n#ifdef HAVE_BZIP2\n    if(zi->ci.method == Z_BZIP2ED)\n    {\n      zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;\n      zi->ci.bstream.total_in_lo32 = 0;\n      zi->ci.bstream.total_in_hi32 = 0;\n    }\n    else\n#endif\n    {\n      zi->ci.totalUncompressedData += zi->ci.stream.total_in;\n      zi->ci.stream.total_in = 0;\n    }\n\n\n    zi->ci.pos_in_buffered_data = 0;\n\n    return err;\n}\n\nextern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)\n{\n    zip64_internal* zi;\n    int err=ZIP_OK;\n\n    if (file == NULL)\n        return ZIP_PARAMERROR;\n    zi = (zip64_internal*)file;\n\n    if (zi->in_opened_file_inzip == 0)\n        return ZIP_PARAMERROR;\n\n    zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);\n\n#ifdef HAVE_BZIP2\n    if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))\n    {\n      zi->ci.bstream.next_in = (void*)buf;\n      zi->ci.bstream.avail_in = len;\n      err = BZ_RUN_OK;\n\n      while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))\n      {\n        if (zi->ci.bstream.avail_out == 0)\n        {\n          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)\n            err = ZIP_ERRNO;\n          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;\n          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;\n        }\n\n\n        if(err != BZ_RUN_OK)\n          break;\n\n        if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))\n        {\n          uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;\n//          uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;\n          err=BZ2_bzCompress(&zi->ci.bstream,  BZ_RUN);\n\n          zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;\n        }\n      }\n\n      if(err == BZ_RUN_OK)\n        err = ZIP_OK;\n    }\n    else\n#endif\n    {\n      zi->ci.stream.next_in = (Bytef*)buf;\n      zi->ci.stream.avail_in = len;\n\n      while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))\n      {\n          if (zi->ci.stream.avail_out == 0)\n          {\n              if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)\n                  err = ZIP_ERRNO;\n              zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;\n              zi->ci.stream.next_out = zi->ci.buffered_data;\n          }\n\n\n          if(err != ZIP_OK)\n              break;\n\n          if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))\n          {\n              uLong uTotalOutBefore = zi->ci.stream.total_out;\n              err=deflate(&zi->ci.stream,  Z_NO_FLUSH);\n              if(uTotalOutBefore > zi->ci.stream.total_out)\n              {\n                int bBreak = 0;\n                bBreak++;\n              }\n\n              zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;\n          }\n          else\n          {\n              uInt copy_this,i;\n              if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)\n                  copy_this = zi->ci.stream.avail_in;\n              else\n                  copy_this = zi->ci.stream.avail_out;\n\n              for (i = 0; i < copy_this; i++)\n                  *(((char*)zi->ci.stream.next_out)+i) =\n                      *(((const char*)zi->ci.stream.next_in)+i);\n              {\n                  zi->ci.stream.avail_in -= copy_this;\n                  zi->ci.stream.avail_out-= copy_this;\n                  zi->ci.stream.next_in+= copy_this;\n                  zi->ci.stream.next_out+= copy_this;\n                  zi->ci.stream.total_in+= copy_this;\n                  zi->ci.stream.total_out+= copy_this;\n                  zi->ci.pos_in_buffered_data += copy_this;\n              }\n          }\n      }// while(...)\n    }\n\n    return err;\n}\n\nextern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)\n{\n    return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);\n}\n\nextern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)\n{\n    zip64_internal* zi;\n    ZPOS64_T compressed_size;\n    uLong invalidValue = 0xffffffff;\n    short datasize = 0;\n    int err=ZIP_OK;\n\n    if (file == NULL)\n        return ZIP_PARAMERROR;\n    zi = (zip64_internal*)file;\n\n    if (zi->in_opened_file_inzip == 0)\n        return ZIP_PARAMERROR;\n    zi->ci.stream.avail_in = 0;\n\n    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))\n                {\n                        while (err==ZIP_OK)\n                        {\n                                uLong uTotalOutBefore;\n                                if (zi->ci.stream.avail_out == 0)\n                                {\n                                        if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)\n                                                err = ZIP_ERRNO;\n                                        zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;\n                                        zi->ci.stream.next_out = zi->ci.buffered_data;\n                                }\n                                uTotalOutBefore = zi->ci.stream.total_out;\n                                err=deflate(&zi->ci.stream,  Z_FINISH);\n                                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;\n                        }\n                }\n    else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))\n    {\n#ifdef HAVE_BZIP2\n      err = BZ_FINISH_OK;\n      while (err==BZ_FINISH_OK)\n      {\n        uLong uTotalOutBefore;\n        if (zi->ci.bstream.avail_out == 0)\n        {\n          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)\n            err = ZIP_ERRNO;\n          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;\n          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;\n        }\n        uTotalOutBefore = zi->ci.bstream.total_out_lo32;\n        err=BZ2_bzCompress(&zi->ci.bstream,  BZ_FINISH);\n        if(err == BZ_STREAM_END)\n          err = Z_STREAM_END;\n\n        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);\n      }\n\n      if(err == BZ_FINISH_OK)\n        err = ZIP_OK;\n#endif\n    }\n\n    if (err==Z_STREAM_END)\n        err=ZIP_OK; /* this is normal */\n\n    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))\n                {\n        if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)\n            err = ZIP_ERRNO;\n                }\n\n    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))\n    {\n        int tmp_err = deflateEnd(&zi->ci.stream);\n        if (err == ZIP_OK)\n            err = tmp_err;\n        zi->ci.stream_initialised = 0;\n    }\n#ifdef HAVE_BZIP2\n    else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))\n    {\n      int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);\n                        if (err==ZIP_OK)\n                                err = tmperr;\n                        zi->ci.stream_initialised = 0;\n    }\n#endif\n\n    if (!zi->ci.raw)\n    {\n        crc32 = (uLong)zi->ci.crc32;\n        uncompressed_size = zi->ci.totalUncompressedData;\n    }\n    compressed_size = zi->ci.totalCompressedData;\n\n#    ifndef NOCRYPT\n    compressed_size += zi->ci.crypt_header_size;\n#    endif\n\n    // update Current Item crc and sizes,\n    if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)\n    {\n      /*version Made by*/\n      zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);\n      /*version needed*/\n      zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);\n\n    }\n\n    zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/\n\n\n    if(compressed_size >= 0xffffffff)\n      zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/\n    else\n      zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/\n\n    /// set internal file attributes field\n    if (zi->ci.stream.data_type == Z_ASCII)\n        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);\n\n    if(uncompressed_size >= 0xffffffff)\n      zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/\n    else\n      zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/\n\n    // Add ZIP64 extra info field for uncompressed size\n    if(uncompressed_size >= 0xffffffff)\n      datasize += 8;\n\n    // Add ZIP64 extra info field for compressed size\n    if(compressed_size >= 0xffffffff)\n      datasize += 8;\n\n    // Add ZIP64 extra info field for relative offset to local file header of current file\n    if(zi->ci.pos_local_header >= 0xffffffff)\n      datasize += 8;\n\n    if(datasize > 0)\n    {\n      char* p = NULL;\n\n      if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)\n      {\n        // we can not write more data to the buffer that we have room for.\n        return ZIP_BADZIPFILE;\n      }\n\n      p = zi->ci.central_header + zi->ci.size_centralheader;\n\n      // Add Extra Information Header for 'ZIP64 information'\n      zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID\n      p += 2;\n      zip64local_putValue_inmemory(p, datasize, 2); // DataSize\n      p += 2;\n\n      if(uncompressed_size >= 0xffffffff)\n      {\n        zip64local_putValue_inmemory(p, uncompressed_size, 8);\n        p += 8;\n      }\n\n      if(compressed_size >= 0xffffffff)\n      {\n        zip64local_putValue_inmemory(p, compressed_size, 8);\n        p += 8;\n      }\n\n      if(zi->ci.pos_local_header >= 0xffffffff)\n      {\n        zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);\n        p += 8;\n      }\n\n      // Update how much extra free space we got in the memory buffer\n      // and increase the centralheader size so the new ZIP64 fields are included\n      // ( 4 below is the size of HeaderID and DataSize field )\n      zi->ci.size_centralExtraFree -= datasize + 4;\n      zi->ci.size_centralheader += datasize + 4;\n\n      // Update the extra info size field\n      zi->ci.size_centralExtra += datasize + 4;\n      zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);\n    }\n\n    if (err==ZIP_OK)\n        err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);\n\n    free(zi->ci.central_header);\n\n    if (err==ZIP_OK)\n    {\n        // Update the LocalFileHeader with the new values.\n\n        ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);\n\n        if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)\n            err = ZIP_ERRNO;\n\n        if (err==ZIP_OK)\n            err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */\n\n        if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )\n        {\n          if(zi->ci.pos_zip64extrainfo > 0)\n          {\n            // Update the size in the ZIP64 extended field.\n            if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)\n              err = ZIP_ERRNO;\n\n            if (err==ZIP_OK) /* compressed size, unknown */\n              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);\n\n            if (err==ZIP_OK) /* uncompressed size, unknown */\n              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);\n          }\n          else\n              err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal\n        }\n        else\n        {\n          if (err==ZIP_OK) /* compressed size, unknown */\n              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);\n\n          if (err==ZIP_OK) /* uncompressed size, unknown */\n              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);\n        }\n\n        if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)\n            err = ZIP_ERRNO;\n    }\n\n    zi->number_entry ++;\n    zi->in_opened_file_inzip = 0;\n\n    return err;\n}\n\nextern int ZEXPORT zipCloseFileInZip (zipFile file)\n{\n    return zipCloseFileInZipRaw (file,0,0);\n}\n\nint Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)\n{\n  int err = ZIP_OK;\n  ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;\n\n  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);\n\n  /*num disks*/\n    if (err==ZIP_OK) /* number of the disk with the start of the central directory */\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);\n\n  /*relative offset*/\n    if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);\n\n  /*total disks*/ /* Do not support spawning of disk so always say 1 here*/\n    if (err==ZIP_OK) /* number of the disk with the start of the central directory */\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);\n\n    return err;\n}\n\nint Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)\n{\n  int err = ZIP_OK;\n\n  uLong Zip64DataSize = 44;\n\n  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);\n\n  if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?\n\n  if (err==ZIP_OK) /* version made by */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);\n\n  if (err==ZIP_OK) /* version needed */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);\n\n  if (err==ZIP_OK) /* number of this disk */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);\n\n  if (err==ZIP_OK) /* number of the disk with the start of the central directory */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);\n\n  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */\n    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);\n\n  if (err==ZIP_OK) /* total number of entries in the central dir */\n    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);\n\n  if (err==ZIP_OK) /* size of the central directory */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);\n\n  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */\n  {\n    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);\n  }\n  return err;\n}\nint Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)\n{\n  int err = ZIP_OK;\n\n  /*signature*/\n  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);\n\n  if (err==ZIP_OK) /* number of this disk */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);\n\n  if (err==ZIP_OK) /* number of the disk with the start of the central directory */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);\n\n  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */\n  {\n    {\n      if(zi->number_entry >= 0xFFFF)\n        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record\n      else\n        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);\n    }\n  }\n\n  if (err==ZIP_OK) /* total number of entries in the central dir */\n  {\n    if(zi->number_entry >= 0xFFFF)\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record\n    else\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);\n  }\n\n  if (err==ZIP_OK) /* size of the central directory */\n    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);\n\n  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */\n  {\n    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;\n    if(pos >= 0xffffffff)\n    {\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);\n    }\n    else\n      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);\n  }\n\n   return err;\n}\n\nint Write_GlobalComment(zip64_internal* zi, const char* global_comment)\n{\n  int err = ZIP_OK;\n  uInt size_global_comment = 0;\n\n  if(global_comment != NULL)\n    size_global_comment = (uInt)strlen(global_comment);\n\n  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);\n\n  if (err == ZIP_OK && size_global_comment > 0)\n  {\n    if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)\n      err = ZIP_ERRNO;\n  }\n  return err;\n}\n\nextern int ZEXPORT zipClose (zipFile file, const char* global_comment)\n{\n    zip64_internal* zi;\n    int err = 0;\n    uLong size_centraldir = 0;\n    ZPOS64_T centraldir_pos_inzip;\n    ZPOS64_T pos;\n\n    if (file == NULL)\n        return ZIP_PARAMERROR;\n\n    zi = (zip64_internal*)file;\n\n    if (zi->in_opened_file_inzip == 1)\n    {\n        err = zipCloseFileInZip (file);\n    }\n\n#ifndef NO_ADDFILEINEXISTINGZIP\n    if (global_comment==NULL)\n        global_comment = zi->globalcomment;\n#endif\n\n    centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);\n\n    if (err==ZIP_OK)\n    {\n        linkedlist_datablock_internal* ldi = zi->central_dir.first_block;\n        while (ldi!=NULL)\n        {\n            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))\n            {\n                if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)\n                    err = ZIP_ERRNO;\n            }\n\n            size_centraldir += ldi->filled_in_this_block;\n            ldi = ldi->next_datablock;\n        }\n    }\n    free_linkedlist(&(zi->central_dir));\n\n    pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;\n    if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)\n    {\n      ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);\n      Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);\n\n      Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);\n    }\n\n    if (err==ZIP_OK)\n      err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);\n\n    if(err == ZIP_OK)\n      err = Write_GlobalComment(zi, global_comment);\n\n    if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)\n        if (err == ZIP_OK)\n            err = ZIP_ERRNO;\n\n#ifndef NO_ADDFILEINEXISTINGZIP\n    TRYFREE(zi->globalcomment);\n#endif\n    TRYFREE(zi);\n\n    return err;\n}\n\nextern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)\n{\n  char* p = pData;\n  int size = 0;\n  char* pNewHeader;\n  char* pTmp;\n  short header;\n  short dataSize;\n\n  int retVal = ZIP_OK;\n\n  if(pData == NULL || *dataLen < 4)\n    return ZIP_PARAMERROR;\n\n  pNewHeader = (char*)ALLOC(*dataLen);\n  pTmp = pNewHeader;\n\n  while(p < (pData + *dataLen))\n  {\n    header = *(short*)p;\n    dataSize = *(((short*)p)+1);\n\n    if( header == sHeader ) // Header found.\n    {\n      p += dataSize + 4; // skip it. do not copy to temp buffer\n    }\n    else\n    {\n      // Extra Info block should not be removed, So copy it to the temp buffer.\n      memcpy(pTmp, p, dataSize + 4);\n      p += dataSize + 4;\n      size += dataSize + 4;\n    }\n\n  }\n\n  if(size < *dataLen)\n  {\n    // clean old extra info block.\n    memset(pData,0, *dataLen);\n\n    // copy the new extra info block over the old\n    if(size > 0)\n      memcpy(pData, pNewHeader, size);\n\n    // set the new extra info size\n    *dataLen = size;\n\n    retVal = ZIP_OK;\n  }\n  else\n    retVal = ZIP_ERRNO;\n\n  TRYFREE(pNewHeader);\n\n  return retVal;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/minizip/zip.h",
    "content": "/* zip.h -- IO on .zip files using zlib\n   Version 1.1, February 14h, 2010\n   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )\n\n         Modifications for Zip64 support\n         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )\n\n         For more info read MiniZip_info.txt\n\n         ---------------------------------------------------------------------------\n\n   Condition of use and distribution are the same than zlib :\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n        ---------------------------------------------------------------------------\n\n        Changes\n\n        See header of zip.h\n\n*/\n\n#ifndef _zip12_H\n#define _zip12_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n//#define HAVE_BZIP2\n\n#ifndef _ZLIB_H\n#include \"zlib.h\"\n#endif\n\n#ifndef _ZLIBIOAPI_H\n#include \"ioapi.h\"\n#endif\n\n#ifdef HAVE_BZIP2\n#include \"bzlib.h\"\n#endif\n\n#define Z_BZIP2ED 12\n\n#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)\n/* like the STRICT of WIN32, we define a pointer that cannot be converted\n    from (void*) without cast */\ntypedef struct TagzipFile__ { int unused; } zipFile__;\ntypedef zipFile__ *zipFile;\n#else\ntypedef voidp zipFile;\n#endif\n\n#define ZIP_OK                          (0)\n#define ZIP_EOF                         (0)\n#define ZIP_ERRNO                       (Z_ERRNO)\n#define ZIP_PARAMERROR                  (-102)\n#define ZIP_BADZIPFILE                  (-103)\n#define ZIP_INTERNALERROR               (-104)\n\n#ifndef DEF_MEM_LEVEL\n#  if MAX_MEM_LEVEL >= 8\n#    define DEF_MEM_LEVEL 8\n#  else\n#    define DEF_MEM_LEVEL  MAX_MEM_LEVEL\n#  endif\n#endif\n/* default memLevel */\n\n/* tm_zip contain date/time info */\ntypedef struct tm_zip_s\n{\n    uInt tm_sec;            /* seconds after the minute - [0,59] */\n    uInt tm_min;            /* minutes after the hour - [0,59] */\n    uInt tm_hour;           /* hours since midnight - [0,23] */\n    uInt tm_mday;           /* day of the month - [1,31] */\n    uInt tm_mon;            /* months since January - [0,11] */\n    uInt tm_year;           /* years - [1980..2044] */\n} tm_zip;\n\ntypedef struct\n{\n    tm_zip      tmz_date;       /* date in understandable format           */\n    uLong       dosDate;       /* if dos_date == 0, tmu_date is used      */\n/*    uLong       flag;        */   /* general purpose bit flag        2 bytes */\n\n    uLong       internal_fa;    /* internal file attributes        2 bytes */\n    uLong       external_fa;    /* external file attributes        4 bytes */\n} zip_fileinfo;\n\ntypedef const char* zipcharpc;\n\n\n#define APPEND_STATUS_CREATE        (0)\n#define APPEND_STATUS_CREATEAFTER   (1)\n#define APPEND_STATUS_ADDINZIP      (2)\n\nextern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));\nextern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));\n/*\n  Create a zipfile.\n     pathname contain on Windows XP a filename like \"c:\\\\zlib\\\\zlib113.zip\" or on\n       an Unix computer \"zlib/zlib113.zip\".\n     if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip\n       will be created at the end of the file.\n         (useful if the file contain a self extractor code)\n     if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will\n       add files in existing zip (be sure you don't add file that doesn't exist)\n     If the zipfile cannot be opened, the return value is NULL.\n     Else, the return value is a zipFile Handle, usable with other function\n       of this zip package.\n*/\n\n/* Note : there is no delete function into a zipfile.\n   If you want delete file into a zipfile, you must open a zipfile, and create another\n   Of couse, you can use RAW reading and writing to copy the file you did not want delte\n*/\n\nextern zipFile ZEXPORT zipOpen2 OF((const char *pathname,\n                                   int append,\n                                   zipcharpc* globalcomment,\n                                   zlib_filefunc_def* pzlib_filefunc_def));\n\nextern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,\n                                   int append,\n                                   zipcharpc* globalcomment,\n                                   zlib_filefunc64_def* pzlib_filefunc_def));\n\nextern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,\n                       const char* filename,\n                       const zip_fileinfo* zipfi,\n                       const void* extrafield_local,\n                       uInt size_extrafield_local,\n                       const void* extrafield_global,\n                       uInt size_extrafield_global,\n                       const char* comment,\n                       int method,\n                       int level));\n\nextern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,\n                       const char* filename,\n                       const zip_fileinfo* zipfi,\n                       const void* extrafield_local,\n                       uInt size_extrafield_local,\n                       const void* extrafield_global,\n                       uInt size_extrafield_global,\n                       const char* comment,\n                       int method,\n                       int level,\n                       int zip64));\n\n/*\n  Open a file in the ZIP for writing.\n  filename : the filename in zip (if NULL, '-' without quote will be used\n  *zipfi contain supplemental information\n  if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local\n    contains the extrafield data the the local header\n  if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global\n    contains the extrafield data the the local header\n  if comment != NULL, comment contain the comment string\n  method contain the compression method (0 for store, Z_DEFLATED for deflate)\n  level contain the level of compression (can be Z_DEFAULT_COMPRESSION)\n  zip64 is set to 1 if a zip64 extended information block should be added to the local file header.\n                    this MUST be '1' if the uncompressed size is >= 0xffffffff.\n\n*/\n\n\nextern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,\n                                            const char* filename,\n                                            const zip_fileinfo* zipfi,\n                                            const void* extrafield_local,\n                                            uInt size_extrafield_local,\n                                            const void* extrafield_global,\n                                            uInt size_extrafield_global,\n                                            const char* comment,\n                                            int method,\n                                            int level,\n                                            int raw));\n\n\nextern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,\n                                            const char* filename,\n                                            const zip_fileinfo* zipfi,\n                                            const void* extrafield_local,\n                                            uInt size_extrafield_local,\n                                            const void* extrafield_global,\n                                            uInt size_extrafield_global,\n                                            const char* comment,\n                                            int method,\n                                            int level,\n                                            int raw,\n                                            int zip64));\n/*\n  Same than zipOpenNewFileInZip, except if raw=1, we write raw file\n */\n\nextern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,\n                                            const char* filename,\n                                            const zip_fileinfo* zipfi,\n                                            const void* extrafield_local,\n                                            uInt size_extrafield_local,\n                                            const void* extrafield_global,\n                                            uInt size_extrafield_global,\n                                            const char* comment,\n                                            int method,\n                                            int level,\n                                            int raw,\n                                            int windowBits,\n                                            int memLevel,\n                                            int strategy,\n                                            const char* password,\n                                            uLong crcForCrypting));\n\nextern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,\n                                            const char* filename,\n                                            const zip_fileinfo* zipfi,\n                                            const void* extrafield_local,\n                                            uInt size_extrafield_local,\n                                            const void* extrafield_global,\n                                            uInt size_extrafield_global,\n                                            const char* comment,\n                                            int method,\n                                            int level,\n                                            int raw,\n                                            int windowBits,\n                                            int memLevel,\n                                            int strategy,\n                                            const char* password,\n                                            uLong crcForCrypting,\n                                            int zip64\n                                            ));\n\n/*\n  Same than zipOpenNewFileInZip2, except\n    windowBits,memLevel,,strategy : see parameter strategy in deflateInit2\n    password : crypting password (NULL for no crypting)\n    crcForCrypting : crc of file to compress (needed for crypting)\n */\n\nextern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,\n                                            const char* filename,\n                                            const zip_fileinfo* zipfi,\n                                            const void* extrafield_local,\n                                            uInt size_extrafield_local,\n                                            const void* extrafield_global,\n                                            uInt size_extrafield_global,\n                                            const char* comment,\n                                            int method,\n                                            int level,\n                                            int raw,\n                                            int windowBits,\n                                            int memLevel,\n                                            int strategy,\n                                            const char* password,\n                                            uLong crcForCrypting,\n                                            uLong versionMadeBy,\n                                            uLong flagBase\n                                            ));\n\n\nextern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,\n                                            const char* filename,\n                                            const zip_fileinfo* zipfi,\n                                            const void* extrafield_local,\n                                            uInt size_extrafield_local,\n                                            const void* extrafield_global,\n                                            uInt size_extrafield_global,\n                                            const char* comment,\n                                            int method,\n                                            int level,\n                                            int raw,\n                                            int windowBits,\n                                            int memLevel,\n                                            int strategy,\n                                            const char* password,\n                                            uLong crcForCrypting,\n                                            uLong versionMadeBy,\n                                            uLong flagBase,\n                                            int zip64\n                                            ));\n/*\n  Same than zipOpenNewFileInZip4, except\n    versionMadeBy : value for Version made by field\n    flag : value for flag field (compression level info will be added)\n */\n\n\nextern int ZEXPORT zipWriteInFileInZip OF((zipFile file,\n                       const void* buf,\n                       unsigned len));\n/*\n  Write data in the zipfile\n*/\n\nextern int ZEXPORT zipCloseFileInZip OF((zipFile file));\n/*\n  Close the current file in the zipfile\n*/\n\nextern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,\n                                            uLong uncompressed_size,\n                                            uLong crc32));\n\nextern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,\n                                            ZPOS64_T uncompressed_size,\n                                            uLong crc32));\n\n/*\n  Close the current file in the zipfile, for file opened with\n    parameter raw=1 in zipOpenNewFileInZip2\n  uncompressed_size and crc32 are value for the uncompressed size\n*/\n\nextern int ZEXPORT zipClose OF((zipFile file,\n                const char* global_comment));\n/*\n  Close the zipfile\n*/\n\n\nextern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));\n/*\n  zipRemoveExtraInfoBlock -  Added by Mathias Svensson\n\n  Remove extra information block from a extra information data for the local file header or central directory header\n\n  It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode.\n\n  0x0001 is the signature header for the ZIP64 extra information blocks\n\n  usage.\n                        Remove ZIP64 Extra information from a central director extra field data\n              zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001);\n\n                        Remove ZIP64 Extra information from a Local File Header extra field data\n        zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);\n*/\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _zip64_H */\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/pascal/example.pas",
    "content": "(* example.c -- usage example of the zlib compression library\n * Copyright (C) 1995-2003 Jean-loup Gailly.\n * For conditions of distribution and use, see copyright notice in zlib.h\n *\n * Pascal translation\n * Copyright (C) 1998 by Jacques Nomssi Nzali.\n * For conditions of distribution and use, see copyright notice in readme.txt\n *\n * Adaptation to the zlibpas interface\n * Copyright (C) 2003 by Cosmin Truta.\n * For conditions of distribution and use, see copyright notice in readme.txt\n *)\n\nprogram example;\n\n{$DEFINE TEST_COMPRESS}\n{DO NOT $DEFINE TEST_GZIO}\n{$DEFINE TEST_DEFLATE}\n{$DEFINE TEST_INFLATE}\n{$DEFINE TEST_FLUSH}\n{$DEFINE TEST_SYNC}\n{$DEFINE TEST_DICT}\n\nuses SysUtils, zlibpas;\n\nconst TESTFILE = 'foo.gz';\n\n(* \"hello world\" would be more standard, but the repeated \"hello\"\n * stresses the compression code better, sorry...\n *)\nconst hello: PChar = 'hello, hello!';\n\nconst dictionary: PChar = 'hello';\n\nvar dictId: LongInt; (* Adler32 value of the dictionary *)\n\nprocedure CHECK_ERR(err: Integer; msg: String);\nbegin\n  if err <> Z_OK then\n  begin\n    WriteLn(msg, ' error: ', err);\n    Halt(1);\n  end;\nend;\n\nprocedure EXIT_ERR(const msg: String);\nbegin\n  WriteLn('Error: ', msg);\n  Halt(1);\nend;\n\n(* ===========================================================================\n * Test compress and uncompress\n *)\n{$IFDEF TEST_COMPRESS}\nprocedure test_compress(compr: Pointer; comprLen: LongInt;\n                        uncompr: Pointer; uncomprLen: LongInt);\nvar err: Integer;\n    len: LongInt;\nbegin\n  len := StrLen(hello)+1;\n\n  err := compress(compr, comprLen, hello, len);\n  CHECK_ERR(err, 'compress');\n\n  StrCopy(PChar(uncompr), 'garbage');\n\n  err := uncompress(uncompr, uncomprLen, compr, comprLen);\n  CHECK_ERR(err, 'uncompress');\n\n  if StrComp(PChar(uncompr), hello) <> 0 then\n    EXIT_ERR('bad uncompress')\n  else\n    WriteLn('uncompress(): ', PChar(uncompr));\nend;\n{$ENDIF}\n\n(* ===========================================================================\n * Test read/write of .gz files\n *)\n{$IFDEF TEST_GZIO}\nprocedure test_gzio(const fname: PChar; (* compressed file name *)\n                    uncompr: Pointer;\n                    uncomprLen: LongInt);\nvar err: Integer;\n    len: Integer;\n    zfile: gzFile;\n    pos: LongInt;\nbegin\n  len := StrLen(hello)+1;\n\n  zfile := gzopen(fname, 'wb');\n  if zfile = NIL then\n  begin\n    WriteLn('gzopen error');\n    Halt(1);\n  end;\n  gzputc(zfile, 'h');\n  if gzputs(zfile, 'ello') <> 4 then\n  begin\n    WriteLn('gzputs err: ', gzerror(zfile, err));\n    Halt(1);\n  end;\n  {$IFDEF GZ_FORMAT_STRING}\n  if gzprintf(zfile, ', %s!', 'hello') <> 8 then\n  begin\n    WriteLn('gzprintf err: ', gzerror(zfile, err));\n    Halt(1);\n  end;\n  {$ELSE}\n  if gzputs(zfile, ', hello!') <> 8 then\n  begin\n    WriteLn('gzputs err: ', gzerror(zfile, err));\n    Halt(1);\n  end;\n  {$ENDIF}\n  gzseek(zfile, 1, SEEK_CUR); (* add one zero byte *)\n  gzclose(zfile);\n\n  zfile := gzopen(fname, 'rb');\n  if zfile = NIL then\n  begin\n    WriteLn('gzopen error');\n    Halt(1);\n  end;\n\n  StrCopy(PChar(uncompr), 'garbage');\n\n  if gzread(zfile, uncompr, uncomprLen) <> len then\n  begin\n    WriteLn('gzread err: ', gzerror(zfile, err));\n    Halt(1);\n  end;\n  if StrComp(PChar(uncompr), hello) <> 0 then\n  begin\n    WriteLn('bad gzread: ', PChar(uncompr));\n    Halt(1);\n  end\n  else\n    WriteLn('gzread(): ', PChar(uncompr));\n\n  pos := gzseek(zfile, -8, SEEK_CUR);\n  if (pos <> 6) or (gztell(zfile) <> pos) then\n  begin\n    WriteLn('gzseek error, pos=', pos, ', gztell=', gztell(zfile));\n    Halt(1);\n  end;\n\n  if gzgetc(zfile) <> ' ' then\n  begin\n    WriteLn('gzgetc error');\n    Halt(1);\n  end;\n\n  if gzungetc(' ', zfile) <> ' ' then\n  begin\n    WriteLn('gzungetc error');\n    Halt(1);\n  end;\n\n  gzgets(zfile, PChar(uncompr), uncomprLen);\n  uncomprLen := StrLen(PChar(uncompr));\n  if uncomprLen <> 7 then (* \" hello!\" *)\n  begin\n    WriteLn('gzgets err after gzseek: ', gzerror(zfile, err));\n    Halt(1);\n  end;\n  if StrComp(PChar(uncompr), hello + 6) <> 0 then\n  begin\n    WriteLn('bad gzgets after gzseek');\n    Halt(1);\n  end\n  else\n    WriteLn('gzgets() after gzseek: ', PChar(uncompr));\n\n  gzclose(zfile);\nend;\n{$ENDIF}\n\n(* ===========================================================================\n * Test deflate with small buffers\n *)\n{$IFDEF TEST_DEFLATE}\nprocedure test_deflate(compr: Pointer; comprLen: LongInt);\nvar c_stream: z_stream; (* compression stream *)\n    err: Integer;\n    len: LongInt;\nbegin\n  len := StrLen(hello)+1;\n\n  c_stream.zalloc := NIL;\n  c_stream.zfree := NIL;\n  c_stream.opaque := NIL;\n\n  err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);\n  CHECK_ERR(err, 'deflateInit');\n\n  c_stream.next_in := hello;\n  c_stream.next_out := compr;\n\n  while (c_stream.total_in <> len) and\n        (c_stream.total_out < comprLen) do\n  begin\n    c_stream.avail_out := 1; { force small buffers }\n    c_stream.avail_in := 1;\n    err := deflate(c_stream, Z_NO_FLUSH);\n    CHECK_ERR(err, 'deflate');\n  end;\n\n  (* Finish the stream, still forcing small buffers: *)\n  while TRUE do\n  begin\n    c_stream.avail_out := 1;\n    err := deflate(c_stream, Z_FINISH);\n    if err = Z_STREAM_END then\n      break;\n    CHECK_ERR(err, 'deflate');\n  end;\n\n  err := deflateEnd(c_stream);\n  CHECK_ERR(err, 'deflateEnd');\nend;\n{$ENDIF}\n\n(* ===========================================================================\n * Test inflate with small buffers\n *)\n{$IFDEF TEST_INFLATE}\nprocedure test_inflate(compr: Pointer; comprLen : LongInt;\n                       uncompr: Pointer; uncomprLen : LongInt);\nvar err: Integer;\n    d_stream: z_stream; (* decompression stream *)\nbegin\n  StrCopy(PChar(uncompr), 'garbage');\n\n  d_stream.zalloc := NIL;\n  d_stream.zfree := NIL;\n  d_stream.opaque := NIL;\n\n  d_stream.next_in := compr;\n  d_stream.avail_in := 0;\n  d_stream.next_out := uncompr;\n\n  err := inflateInit(d_stream);\n  CHECK_ERR(err, 'inflateInit');\n\n  while (d_stream.total_out < uncomprLen) and\n        (d_stream.total_in < comprLen) do\n  begin\n    d_stream.avail_out := 1; (* force small buffers *)\n    d_stream.avail_in := 1;\n    err := inflate(d_stream, Z_NO_FLUSH);\n    if err = Z_STREAM_END then\n      break;\n    CHECK_ERR(err, 'inflate');\n  end;\n\n  err := inflateEnd(d_stream);\n  CHECK_ERR(err, 'inflateEnd');\n\n  if StrComp(PChar(uncompr), hello) <> 0 then\n    EXIT_ERR('bad inflate')\n  else\n    WriteLn('inflate(): ', PChar(uncompr));\nend;\n{$ENDIF}\n\n(* ===========================================================================\n * Test deflate with large buffers and dynamic change of compression level\n *)\n{$IFDEF TEST_DEFLATE}\nprocedure test_large_deflate(compr: Pointer; comprLen: LongInt;\n                             uncompr: Pointer; uncomprLen: LongInt);\nvar c_stream: z_stream; (* compression stream *)\n    err: Integer;\nbegin\n  c_stream.zalloc := NIL;\n  c_stream.zfree := NIL;\n  c_stream.opaque := NIL;\n\n  err := deflateInit(c_stream, Z_BEST_SPEED);\n  CHECK_ERR(err, 'deflateInit');\n\n  c_stream.next_out := compr;\n  c_stream.avail_out := Integer(comprLen);\n\n  (* At this point, uncompr is still mostly zeroes, so it should compress\n   * very well:\n   *)\n  c_stream.next_in := uncompr;\n  c_stream.avail_in := Integer(uncomprLen);\n  err := deflate(c_stream, Z_NO_FLUSH);\n  CHECK_ERR(err, 'deflate');\n  if c_stream.avail_in <> 0 then\n    EXIT_ERR('deflate not greedy');\n\n  (* Feed in already compressed data and switch to no compression: *)\n  deflateParams(c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);\n  c_stream.next_in := compr;\n  c_stream.avail_in := Integer(comprLen div 2);\n  err := deflate(c_stream, Z_NO_FLUSH);\n  CHECK_ERR(err, 'deflate');\n\n  (* Switch back to compressing mode: *)\n  deflateParams(c_stream, Z_BEST_COMPRESSION, Z_FILTERED);\n  c_stream.next_in := uncompr;\n  c_stream.avail_in := Integer(uncomprLen);\n  err := deflate(c_stream, Z_NO_FLUSH);\n  CHECK_ERR(err, 'deflate');\n\n  err := deflate(c_stream, Z_FINISH);\n  if err <> Z_STREAM_END then\n    EXIT_ERR('deflate should report Z_STREAM_END');\n\n  err := deflateEnd(c_stream);\n  CHECK_ERR(err, 'deflateEnd');\nend;\n{$ENDIF}\n\n(* ===========================================================================\n * Test inflate with large buffers\n *)\n{$IFDEF TEST_INFLATE}\nprocedure test_large_inflate(compr: Pointer; comprLen: LongInt;\n                             uncompr: Pointer; uncomprLen: LongInt);\nvar err: Integer;\n    d_stream: z_stream; (* decompression stream *)\nbegin\n  StrCopy(PChar(uncompr), 'garbage');\n\n  d_stream.zalloc := NIL;\n  d_stream.zfree := NIL;\n  d_stream.opaque := NIL;\n\n  d_stream.next_in := compr;\n  d_stream.avail_in := Integer(comprLen);\n\n  err := inflateInit(d_stream);\n  CHECK_ERR(err, 'inflateInit');\n\n  while TRUE do\n  begin\n    d_stream.next_out := uncompr;            (* discard the output *)\n    d_stream.avail_out := Integer(uncomprLen);\n    err := inflate(d_stream, Z_NO_FLUSH);\n    if err = Z_STREAM_END then\n      break;\n    CHECK_ERR(err, 'large inflate');\n  end;\n\n  err := inflateEnd(d_stream);\n  CHECK_ERR(err, 'inflateEnd');\n\n  if d_stream.total_out <> 2 * uncomprLen + comprLen div 2 then\n  begin\n    WriteLn('bad large inflate: ', d_stream.total_out);\n    Halt(1);\n  end\n  else\n    WriteLn('large_inflate(): OK');\nend;\n{$ENDIF}\n\n(* ===========================================================================\n * Test deflate with full flush\n *)\n{$IFDEF TEST_FLUSH}\nprocedure test_flush(compr: Pointer; var comprLen : LongInt);\nvar c_stream: z_stream; (* compression stream *)\n    err: Integer;\n    len: Integer;\nbegin\n  len := StrLen(hello)+1;\n\n  c_stream.zalloc := NIL;\n  c_stream.zfree := NIL;\n  c_stream.opaque := NIL;\n\n  err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);\n  CHECK_ERR(err, 'deflateInit');\n\n  c_stream.next_in := hello;\n  c_stream.next_out := compr;\n  c_stream.avail_in := 3;\n  c_stream.avail_out := Integer(comprLen);\n  err := deflate(c_stream, Z_FULL_FLUSH);\n  CHECK_ERR(err, 'deflate');\n\n  Inc(PByteArray(compr)^[3]); (* force an error in first compressed block *)\n  c_stream.avail_in := len - 3;\n\n  err := deflate(c_stream, Z_FINISH);\n  if err <> Z_STREAM_END then\n    CHECK_ERR(err, 'deflate');\n\n  err := deflateEnd(c_stream);\n  CHECK_ERR(err, 'deflateEnd');\n\n  comprLen := c_stream.total_out;\nend;\n{$ENDIF}\n\n(* ===========================================================================\n * Test inflateSync()\n *)\n{$IFDEF TEST_SYNC}\nprocedure test_sync(compr: Pointer; comprLen: LongInt;\n                    uncompr: Pointer; uncomprLen : LongInt);\nvar err: Integer;\n    d_stream: z_stream; (* decompression stream *)\nbegin\n  StrCopy(PChar(uncompr), 'garbage');\n\n  d_stream.zalloc := NIL;\n  d_stream.zfree := NIL;\n  d_stream.opaque := NIL;\n\n  d_stream.next_in := compr;\n  d_stream.avail_in := 2; (* just read the zlib header *)\n\n  err := inflateInit(d_stream);\n  CHECK_ERR(err, 'inflateInit');\n\n  d_stream.next_out := uncompr;\n  d_stream.avail_out := Integer(uncomprLen);\n\n  inflate(d_stream, Z_NO_FLUSH);\n  CHECK_ERR(err, 'inflate');\n\n  d_stream.avail_in := Integer(comprLen-2);   (* read all compressed data *)\n  err := inflateSync(d_stream);               (* but skip the damaged part *)\n  CHECK_ERR(err, 'inflateSync');\n\n  err := inflate(d_stream, Z_FINISH);\n  if err <> Z_DATA_ERROR then\n    EXIT_ERR('inflate should report DATA_ERROR');\n    (* Because of incorrect adler32 *)\n\n  err := inflateEnd(d_stream);\n  CHECK_ERR(err, 'inflateEnd');\n\n  WriteLn('after inflateSync(): hel', PChar(uncompr));\nend;\n{$ENDIF}\n\n(* ===========================================================================\n * Test deflate with preset dictionary\n *)\n{$IFDEF TEST_DICT}\nprocedure test_dict_deflate(compr: Pointer; comprLen: LongInt);\nvar c_stream: z_stream; (* compression stream *)\n    err: Integer;\nbegin\n  c_stream.zalloc := NIL;\n  c_stream.zfree := NIL;\n  c_stream.opaque := NIL;\n\n  err := deflateInit(c_stream, Z_BEST_COMPRESSION);\n  CHECK_ERR(err, 'deflateInit');\n\n  err := deflateSetDictionary(c_stream, dictionary, StrLen(dictionary));\n  CHECK_ERR(err, 'deflateSetDictionary');\n\n  dictId := c_stream.adler;\n  c_stream.next_out := compr;\n  c_stream.avail_out := Integer(comprLen);\n\n  c_stream.next_in := hello;\n  c_stream.avail_in := StrLen(hello)+1;\n\n  err := deflate(c_stream, Z_FINISH);\n  if err <> Z_STREAM_END then\n    EXIT_ERR('deflate should report Z_STREAM_END');\n\n  err := deflateEnd(c_stream);\n  CHECK_ERR(err, 'deflateEnd');\nend;\n{$ENDIF}\n\n(* ===========================================================================\n * Test inflate with a preset dictionary\n *)\n{$IFDEF TEST_DICT}\nprocedure test_dict_inflate(compr: Pointer; comprLen: LongInt;\n                            uncompr: Pointer; uncomprLen: LongInt);\nvar err: Integer;\n    d_stream: z_stream; (* decompression stream *)\nbegin\n  StrCopy(PChar(uncompr), 'garbage');\n\n  d_stream.zalloc := NIL;\n  d_stream.zfree := NIL;\n  d_stream.opaque := NIL;\n\n  d_stream.next_in := compr;\n  d_stream.avail_in := Integer(comprLen);\n\n  err := inflateInit(d_stream);\n  CHECK_ERR(err, 'inflateInit');\n\n  d_stream.next_out := uncompr;\n  d_stream.avail_out := Integer(uncomprLen);\n\n  while TRUE do\n  begin\n    err := inflate(d_stream, Z_NO_FLUSH);\n    if err = Z_STREAM_END then\n      break;\n    if err = Z_NEED_DICT then\n    begin\n      if d_stream.adler <> dictId then\n        EXIT_ERR('unexpected dictionary');\n      err := inflateSetDictionary(d_stream, dictionary, StrLen(dictionary));\n    end;\n    CHECK_ERR(err, 'inflate with dict');\n  end;\n\n  err := inflateEnd(d_stream);\n  CHECK_ERR(err, 'inflateEnd');\n\n  if StrComp(PChar(uncompr), hello) <> 0 then\n    EXIT_ERR('bad inflate with dict')\n  else\n    WriteLn('inflate with dictionary: ', PChar(uncompr));\nend;\n{$ENDIF}\n\nvar compr, uncompr: Pointer;\n    comprLen, uncomprLen: LongInt;\n\nbegin\n  if zlibVersion^ <> ZLIB_VERSION[1] then\n    EXIT_ERR('Incompatible zlib version');\n\n  WriteLn('zlib version: ', zlibVersion);\n  WriteLn('zlib compile flags: ', Format('0x%x', [zlibCompileFlags]));\n\n  comprLen := 10000 * SizeOf(Integer); (* don't overflow on MSDOS *)\n  uncomprLen := comprLen;\n  GetMem(compr, comprLen);\n  GetMem(uncompr, uncomprLen);\n  if (compr = NIL) or (uncompr = NIL) then\n    EXIT_ERR('Out of memory');\n  (* compr and uncompr are cleared to avoid reading uninitialized\n   * data and to ensure that uncompr compresses well.\n   *)\n  FillChar(compr^, comprLen, 0);\n  FillChar(uncompr^, uncomprLen, 0);\n\n  {$IFDEF TEST_COMPRESS}\n  WriteLn('** Testing compress');\n  test_compress(compr, comprLen, uncompr, uncomprLen);\n  {$ENDIF}\n\n  {$IFDEF TEST_GZIO}\n  WriteLn('** Testing gzio');\n  if ParamCount >= 1 then\n    test_gzio(ParamStr(1), uncompr, uncomprLen)\n  else\n    test_gzio(TESTFILE, uncompr, uncomprLen);\n  {$ENDIF}\n\n  {$IFDEF TEST_DEFLATE}\n  WriteLn('** Testing deflate with small buffers');\n  test_deflate(compr, comprLen);\n  {$ENDIF}\n  {$IFDEF TEST_INFLATE}\n  WriteLn('** Testing inflate with small buffers');\n  test_inflate(compr, comprLen, uncompr, uncomprLen);\n  {$ENDIF}\n\n  {$IFDEF TEST_DEFLATE}\n  WriteLn('** Testing deflate with large buffers');\n  test_large_deflate(compr, comprLen, uncompr, uncomprLen);\n  {$ENDIF}\n  {$IFDEF TEST_INFLATE}\n  WriteLn('** Testing inflate with large buffers');\n  test_large_inflate(compr, comprLen, uncompr, uncomprLen);\n  {$ENDIF}\n\n  {$IFDEF TEST_FLUSH}\n  WriteLn('** Testing deflate with full flush');\n  test_flush(compr, comprLen);\n  {$ENDIF}\n  {$IFDEF TEST_SYNC}\n  WriteLn('** Testing inflateSync');\n  test_sync(compr, comprLen, uncompr, uncomprLen);\n  {$ENDIF}\n  comprLen := uncomprLen;\n\n  {$IFDEF TEST_DICT}\n  WriteLn('** Testing deflate and inflate with preset dictionary');\n  test_dict_deflate(compr, comprLen);\n  test_dict_inflate(compr, comprLen, uncompr, uncomprLen);\n  {$ENDIF}\n\n  FreeMem(compr, comprLen);\n  FreeMem(uncompr, uncomprLen);\nend.\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/pascal/readme.txt",
    "content": "\nThis directory contains a Pascal (Delphi, Kylix) interface to the\nzlib data compression library.\n\n\nDirectory listing\n=================\n\nzlibd32.mak     makefile for Borland C++\nexample.pas     usage example of zlib\nzlibpas.pas     the Pascal interface to zlib\nreadme.txt      this file\n\n\nCompatibility notes\n===================\n\n- Although the name \"zlib\" would have been more normal for the\n  zlibpas unit, this name is already taken by Borland's ZLib unit.\n  This is somehow unfortunate, because that unit is not a genuine\n  interface to the full-fledged zlib functionality, but a suite of\n  class wrappers around zlib streams.  Other essential features,\n  such as checksums, are missing.\n  It would have been more appropriate for that unit to have a name\n  like \"ZStreams\", or something similar.\n\n- The C and zlib-supplied types int, uInt, long, uLong, etc. are\n  translated directly into Pascal types of similar sizes (Integer,\n  LongInt, etc.), to avoid namespace pollution.  In particular,\n  there is no conversion of unsigned int into a Pascal unsigned\n  integer.  The Word type is non-portable and has the same size\n  (16 bits) both in a 16-bit and in a 32-bit environment, unlike\n  Integer.  Even if there is a 32-bit Cardinal type, there is no\n  real need for unsigned int in zlib under a 32-bit environment.\n\n- Except for the callbacks, the zlib function interfaces are\n  assuming the calling convention normally used in Pascal\n  (__pascal for DOS and Windows16, __fastcall for Windows32).\n  Since the cdecl keyword is used, the old Turbo Pascal does\n  not work with this interface.\n\n- The gz* function interfaces are not translated, to avoid\n  interfacing problems with the C runtime library.  Besides,\n    gzprintf(gzFile file, const char *format, ...)\n  cannot be translated into Pascal.\n\n\nLegal issues\n============\n\nThe zlibpas interface is:\n  Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler.\n  Copyright (C) 1998 by Bob Dellaca.\n  Copyright (C) 2003 by Cosmin Truta.\n\nThe example program is:\n  Copyright (C) 1995-2003 by Jean-loup Gailly.\n  Copyright (C) 1998,1999,2000 by Jacques Nomssi Nzali.\n  Copyright (C) 2003 by Cosmin Truta.\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the author be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/pascal/zlibd32.mak",
    "content": "# Makefile for zlib\n# For use with Delphi and C++ Builder under Win32\n# Updated for zlib 1.2.x by Cosmin Truta\n\n# ------------ Borland C++ ------------\n\n# This project uses the Delphi (fastcall/register) calling convention:\nLOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl\n\nCC = bcc32\nLD = bcc32\nAR = tlib\n# do not use \"-pr\" in CFLAGS\nCFLAGS = -a -d -k- -O2 $(LOC)\nLDFLAGS =\n\n\n# variables\nZLIB_LIB = zlib.lib\n\nOBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj\nOBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj\nOBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj\nOBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj\n\n\n# targets\nall: $(ZLIB_LIB) example.exe minigzip.exe\n\n.c.obj:\n\t$(CC) -c $(CFLAGS) $*.c\n\nadler32.obj: adler32.c zlib.h zconf.h\n\ncompress.obj: compress.c zlib.h zconf.h\n\ncrc32.obj: crc32.c zlib.h zconf.h crc32.h\n\ndeflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h\n\ngzclose.obj: gzclose.c zlib.h zconf.h gzguts.h\n\ngzlib.obj: gzlib.c zlib.h zconf.h gzguts.h\n\ngzread.obj: gzread.c zlib.h zconf.h gzguts.h\n\ngzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h\n\ninfback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h inffixed.h\n\ninffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h\n\ninflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h inffixed.h\n\ninftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h\n\ntrees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h\n\nuncompr.obj: uncompr.c zlib.h zconf.h\n\nzutil.obj: zutil.c zutil.h zlib.h zconf.h\n\nexample.obj: test/example.c zlib.h zconf.h\n\nminigzip.obj: test/minigzip.c zlib.h zconf.h\n\n\n# For the sake of the old Borland make,\n# the command line is cut to fit in the MS-DOS 128 byte limit:\n$(ZLIB_LIB): $(OBJ1) $(OBJ2)\n\t-del $(ZLIB_LIB)\n\t$(AR) $(ZLIB_LIB) $(OBJP1)\n\t$(AR) $(ZLIB_LIB) $(OBJP2)\n\n\n# testing\ntest: example.exe minigzip.exe\n\texample\n\techo hello world | minigzip | minigzip -d\n\nexample.exe: example.obj $(ZLIB_LIB)\n\t$(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)\n\nminigzip.exe: minigzip.obj $(ZLIB_LIB)\n\t$(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)\n\n\n# cleanup\nclean:\n\t-del *.obj\n\t-del *.exe\n\t-del *.lib\n\t-del *.tds\n\t-del zlib.bak\n\t-del foo.gz\n\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/pascal/zlibpas.pas",
    "content": "(* zlibpas -- Pascal interface to the zlib data compression library\n *\n * Copyright (C) 2003 Cosmin Truta.\n * Derived from original sources by Bob Dellaca.\n * For conditions of distribution and use, see copyright notice in readme.txt\n *)\n\nunit zlibpas;\n\ninterface\n\nconst\n  ZLIB_VERSION = '1.2.8';\n  ZLIB_VERNUM  = $1280;\n\ntype\n  alloc_func = function(opaque: Pointer; items, size: Integer): Pointer;\n                 cdecl;\n  free_func  = procedure(opaque, address: Pointer);\n                 cdecl;\n\n  in_func    = function(opaque: Pointer; var buf: PByte): Integer;\n                 cdecl;\n  out_func   = function(opaque: Pointer; buf: PByte; size: Integer): Integer;\n                 cdecl;\n\n  z_streamp = ^z_stream;\n  z_stream = packed record\n    next_in: PChar;       (* next input byte *)\n    avail_in: Integer;    (* number of bytes available at next_in *)\n    total_in: LongInt;    (* total nb of input bytes read so far *)\n\n    next_out: PChar;      (* next output byte should be put there *)\n    avail_out: Integer;   (* remaining free space at next_out *)\n    total_out: LongInt;   (* total nb of bytes output so far *)\n\n    msg: PChar;           (* last error message, NULL if no error *)\n    state: Pointer;       (* not visible by applications *)\n\n    zalloc: alloc_func;   (* used to allocate the internal state *)\n    zfree: free_func;     (* used to free the internal state *)\n    opaque: Pointer;      (* private data object passed to zalloc and zfree *)\n\n    data_type: Integer;   (* best guess about the data type: ascii or binary *)\n    adler: LongInt;       (* adler32 value of the uncompressed data *)\n    reserved: LongInt;    (* reserved for future use *)\n  end;\n\n  gz_headerp = ^gz_header;\n  gz_header = packed record\n    text: Integer;        (* true if compressed data believed to be text *)\n    time: LongInt;        (* modification time *)\n    xflags: Integer;      (* extra flags (not used when writing a gzip file) *)\n    os: Integer;          (* operating system *)\n    extra: PChar;         (* pointer to extra field or Z_NULL if none *)\n    extra_len: Integer;   (* extra field length (valid if extra != Z_NULL) *)\n    extra_max: Integer;   (* space at extra (only when reading header) *)\n    name: PChar;          (* pointer to zero-terminated file name or Z_NULL *)\n    name_max: Integer;    (* space at name (only when reading header) *)\n    comment: PChar;       (* pointer to zero-terminated comment or Z_NULL *)\n    comm_max: Integer;    (* space at comment (only when reading header) *)\n    hcrc: Integer;        (* true if there was or will be a header crc *)\n    done: Integer;        (* true when done reading gzip header *)\n  end;\n\n(* constants *)\nconst\n  Z_NO_FLUSH      = 0;\n  Z_PARTIAL_FLUSH = 1;\n  Z_SYNC_FLUSH    = 2;\n  Z_FULL_FLUSH    = 3;\n  Z_FINISH        = 4;\n  Z_BLOCK         = 5;\n  Z_TREES         = 6;\n\n  Z_OK            =  0;\n  Z_STREAM_END    =  1;\n  Z_NEED_DICT     =  2;\n  Z_ERRNO         = -1;\n  Z_STREAM_ERROR  = -2;\n  Z_DATA_ERROR    = -3;\n  Z_MEM_ERROR     = -4;\n  Z_BUF_ERROR     = -5;\n  Z_VERSION_ERROR = -6;\n\n  Z_NO_COMPRESSION       =  0;\n  Z_BEST_SPEED           =  1;\n  Z_BEST_COMPRESSION     =  9;\n  Z_DEFAULT_COMPRESSION  = -1;\n\n  Z_FILTERED            = 1;\n  Z_HUFFMAN_ONLY        = 2;\n  Z_RLE                 = 3;\n  Z_FIXED               = 4;\n  Z_DEFAULT_STRATEGY    = 0;\n\n  Z_BINARY   = 0;\n  Z_TEXT     = 1;\n  Z_ASCII    = 1;\n  Z_UNKNOWN  = 2;\n\n  Z_DEFLATED = 8;\n\n(* basic functions *)\nfunction zlibVersion: PChar;\nfunction deflateInit(var strm: z_stream; level: Integer): Integer;\nfunction deflate(var strm: z_stream; flush: Integer): Integer;\nfunction deflateEnd(var strm: z_stream): Integer;\nfunction inflateInit(var strm: z_stream): Integer;\nfunction inflate(var strm: z_stream; flush: Integer): Integer;\nfunction inflateEnd(var strm: z_stream): Integer;\n\n(* advanced functions *)\nfunction deflateInit2(var strm: z_stream; level, method, windowBits,\n                      memLevel, strategy: Integer): Integer;\nfunction deflateSetDictionary(var strm: z_stream; const dictionary: PChar;\n                              dictLength: Integer): Integer;\nfunction deflateCopy(var dest, source: z_stream): Integer;\nfunction deflateReset(var strm: z_stream): Integer;\nfunction deflateParams(var strm: z_stream; level, strategy: Integer): Integer;\nfunction deflateTune(var strm: z_stream; good_length, max_lazy, nice_length, max_chain: Integer): Integer;\nfunction deflateBound(var strm: z_stream; sourceLen: LongInt): LongInt;\nfunction deflatePending(var strm: z_stream; var pending: Integer; var bits: Integer): Integer;\nfunction deflatePrime(var strm: z_stream; bits, value: Integer): Integer;\nfunction deflateSetHeader(var strm: z_stream; head: gz_header): Integer;\nfunction inflateInit2(var strm: z_stream; windowBits: Integer): Integer;\nfunction inflateSetDictionary(var strm: z_stream; const dictionary: PChar;\n                              dictLength: Integer): Integer;\nfunction inflateSync(var strm: z_stream): Integer;\nfunction inflateCopy(var dest, source: z_stream): Integer;\nfunction inflateReset(var strm: z_stream): Integer;\nfunction inflateReset2(var strm: z_stream; windowBits: Integer): Integer;\nfunction inflatePrime(var strm: z_stream; bits, value: Integer): Integer;\nfunction inflateMark(var strm: z_stream): LongInt;\nfunction inflateGetHeader(var strm: z_stream; var head: gz_header): Integer;\nfunction inflateBackInit(var strm: z_stream;\n                         windowBits: Integer; window: PChar): Integer;\nfunction inflateBack(var strm: z_stream; in_fn: in_func; in_desc: Pointer;\n                     out_fn: out_func; out_desc: Pointer): Integer;\nfunction inflateBackEnd(var strm: z_stream): Integer;\nfunction zlibCompileFlags: LongInt;\n\n(* utility functions *)\nfunction compress(dest: PChar; var destLen: LongInt;\n                  const source: PChar; sourceLen: LongInt): Integer;\nfunction compress2(dest: PChar; var destLen: LongInt;\n                  const source: PChar; sourceLen: LongInt;\n                  level: Integer): Integer;\nfunction compressBound(sourceLen: LongInt): LongInt;\nfunction uncompress(dest: PChar; var destLen: LongInt;\n                    const source: PChar; sourceLen: LongInt): Integer;\n\n(* checksum functions *)\nfunction adler32(adler: LongInt; const buf: PChar; len: Integer): LongInt;\nfunction adler32_combine(adler1, adler2, len2: LongInt): LongInt;\nfunction crc32(crc: LongInt; const buf: PChar; len: Integer): LongInt;\nfunction crc32_combine(crc1, crc2, len2: LongInt): LongInt;\n\n(* various hacks, don't look :) *)\nfunction deflateInit_(var strm: z_stream; level: Integer;\n                      const version: PChar; stream_size: Integer): Integer;\nfunction inflateInit_(var strm: z_stream; const version: PChar;\n                      stream_size: Integer): Integer;\nfunction deflateInit2_(var strm: z_stream;\n                       level, method, windowBits, memLevel, strategy: Integer;\n                       const version: PChar; stream_size: Integer): Integer;\nfunction inflateInit2_(var strm: z_stream; windowBits: Integer;\n                       const version: PChar; stream_size: Integer): Integer;\nfunction inflateBackInit_(var strm: z_stream;\n                          windowBits: Integer; window: PChar;\n                          const version: PChar; stream_size: Integer): Integer;\n\n\nimplementation\n\n{$L adler32.obj}\n{$L compress.obj}\n{$L crc32.obj}\n{$L deflate.obj}\n{$L infback.obj}\n{$L inffast.obj}\n{$L inflate.obj}\n{$L inftrees.obj}\n{$L trees.obj}\n{$L uncompr.obj}\n{$L zutil.obj}\n\nfunction adler32; external;\nfunction adler32_combine; external;\nfunction compress; external;\nfunction compress2; external;\nfunction compressBound; external;\nfunction crc32; external;\nfunction crc32_combine; external;\nfunction deflate; external;\nfunction deflateBound; external;\nfunction deflateCopy; external;\nfunction deflateEnd; external;\nfunction deflateInit_; external;\nfunction deflateInit2_; external;\nfunction deflateParams; external;\nfunction deflatePending; external;\nfunction deflatePrime; external;\nfunction deflateReset; external;\nfunction deflateSetDictionary; external;\nfunction deflateSetHeader; external;\nfunction deflateTune; external;\nfunction inflate; external;\nfunction inflateBack; external;\nfunction inflateBackEnd; external;\nfunction inflateBackInit_; external;\nfunction inflateCopy; external;\nfunction inflateEnd; external;\nfunction inflateGetHeader; external;\nfunction inflateInit_; external;\nfunction inflateInit2_; external;\nfunction inflateMark; external;\nfunction inflatePrime; external;\nfunction inflateReset; external;\nfunction inflateReset2; external;\nfunction inflateSetDictionary; external;\nfunction inflateSync; external;\nfunction uncompress; external;\nfunction zlibCompileFlags; external;\nfunction zlibVersion; external;\n\nfunction deflateInit(var strm: z_stream; level: Integer): Integer;\nbegin\n  Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream));\nend;\n\nfunction deflateInit2(var strm: z_stream; level, method, windowBits, memLevel,\n                      strategy: Integer): Integer;\nbegin\n  Result := deflateInit2_(strm, level, method, windowBits, memLevel, strategy,\n                          ZLIB_VERSION, sizeof(z_stream));\nend;\n\nfunction inflateInit(var strm: z_stream): Integer;\nbegin\n  Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream));\nend;\n\nfunction inflateInit2(var strm: z_stream; windowBits: Integer): Integer;\nbegin\n  Result := inflateInit2_(strm, windowBits, ZLIB_VERSION, sizeof(z_stream));\nend;\n\nfunction inflateBackInit(var strm: z_stream;\n                         windowBits: Integer; window: PChar): Integer;\nbegin\n  Result := inflateBackInit_(strm, windowBits, window,\n                             ZLIB_VERSION, sizeof(z_stream));\nend;\n\nfunction _malloc(Size: Integer): Pointer; cdecl;\nbegin\n  GetMem(Result, Size);\nend;\n\nprocedure _free(Block: Pointer); cdecl;\nbegin\n  FreeMem(Block);\nend;\n\nprocedure _memset(P: Pointer; B: Byte; count: Integer); cdecl;\nbegin\n  FillChar(P^, count, B);\nend;\n\nprocedure _memcpy(dest, source: Pointer; count: Integer); cdecl;\nbegin\n  Move(source^, dest^, count);\nend;\n\nend.\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/puff/Makefile",
    "content": "CFLAGS=-O\n\npuff: puff.o pufftest.o\n\npuff.o: puff.h\n\npufftest.o: puff.h\n\ntest: puff\n\tpuff zeros.raw\n\npuft: puff.c puff.h pufftest.o\n\tcc -fprofile-arcs -ftest-coverage -o puft puff.c pufftest.o\n\n# puff full coverage test (should say 100%)\ncov: puft\n\t@rm -f *.gcov *.gcda\n\t@puft -w zeros.raw 2>&1 | cat > /dev/null\n\t@echo '04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2\n\t@echo '00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2\n\t@echo '00 00 00 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 254\n\t@echo '00 01 00 fe ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2\n\t@echo '01 01 00 fe ff 0a' | xxd -r -p | puft -f 2>&1 | cat > /dev/null\n\t@echo '02 7e ff ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246\n\t@echo '02' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2\n\t@echo '04 80 49 92 24 49 92 24 0f b4 ff ff c3 04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2\n\t@echo '04 80 49 92 24 49 92 24 71 ff ff 93 11 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 249\n\t@echo '04 c0 81 08 00 00 00 00 20 7f eb 0b 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246\n\t@echo '0b 00 00' | xxd -r -p | puft -f 2>&1 | cat > /dev/null\n\t@echo '1a 07' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246\n\t@echo '0c c0 81 00 00 00 00 00 90 ff 6b 04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 245\n\t@puft -f zeros.raw 2>&1 | cat > /dev/null\n\t@echo 'fc 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 253\n\t@echo '04 00 fe ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 252\n\t@echo '04 00 24 49' | xxd -r -p | puft 2> /dev/null || test $$? -eq 251\n\t@echo '04 80 49 92 24 49 92 24 0f b4 ff ff c3 84' | xxd -r -p | puft 2> /dev/null || test $$? -eq 248\n\t@echo '04 00 24 e9 ff ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 250\n\t@echo '04 00 24 e9 ff 6d' | xxd -r -p | puft 2> /dev/null || test $$? -eq 247\n\t@gcov -n puff.c\n\nclean:\n\trm -f puff puft *.o *.gc*\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/puff/README",
    "content": "Puff -- A Simple Inflate\n3 Mar 2003\nMark Adler\nmadler@alumni.caltech.edu\n\nWhat this is --\n\npuff.c provides the routine puff() to decompress the deflate data format.  It\ndoes so more slowly than zlib, but the code is about one-fifth the size of the\ninflate code in zlib, and written to be very easy to read.\n\nWhy I wrote this --\n\npuff.c was written to document the deflate format unambiguously, by virtue of\nbeing working C code.  It is meant to supplement RFC 1951, which formally\ndescribes the deflate format.  I have received many questions on details of the\ndeflate format, and I hope that reading this code will answer those questions.\npuff.c is heavily commented with details of the deflate format, especially\nthose little nooks and cranies of the format that might not be obvious from a\nspecification.\n\npuff.c may also be useful in applications where code size or memory usage is a\nvery limited resource, and speed is not as important.\n\nHow to use it --\n\nWell, most likely you should just be reading puff.c and using zlib for actual\napplications, but if you must ...\n\nInclude puff.h in your code, which provides this prototype:\n\nint puff(unsigned char *dest,           /* pointer to destination pointer */\n         unsigned long *destlen,        /* amount of output space */\n         unsigned char *source,         /* pointer to source data pointer */\n         unsigned long *sourcelen);     /* amount of input available */\n\nThen you can call puff() to decompress a deflate stream that is in memory in\nits entirety at source, to a sufficiently sized block of memory for the\ndecompressed data at dest.  puff() is the only external symbol in puff.c  The\nonly C library functions that puff.c needs are setjmp() and longjmp(), which\nare used to simplify error checking in the code to improve readabilty.  puff.c\ndoes no memory allocation, and uses less than 2K bytes off of the stack.\n\nIf destlen is not enough space for the uncompressed data, then inflate will\nreturn an error without writing more than destlen bytes.  Note that this means\nthat in order to decompress the deflate data successfully, you need to know\nthe size of the uncompressed data ahead of time.\n\nIf needed, puff() can determine the size of the uncompressed data with no\noutput space.  This is done by passing dest equal to (unsigned char *)0.  Then\nthe initial value of *destlen is ignored and *destlen is set to the length of\nthe uncompressed data.  So if the size of the uncompressed data is not known,\nthen two passes of puff() can be used--first to determine the size, and second\nto do the actual inflation after allocating the appropriate memory.  Not\npretty, but it works.  (This is one of the reasons you should be using zlib.)\n\nThe deflate format is self-terminating.  If the deflate stream does not end\nin *sourcelen bytes, puff() will return an error without reading at or past\nendsource.\n\nOn return, *sourcelen is updated to the amount of input data consumed, and\n*destlen is updated to the size of the uncompressed data.  See the comments\nin puff.c for the possible return codes for puff().\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/puff/puff.c",
    "content": "/*\n * puff.c\n * Copyright (C) 2002-2013 Mark Adler\n * For conditions of distribution and use, see copyright notice in puff.h\n * version 2.3, 21 Jan 2013\n *\n * puff.c is a simple inflate written to be an unambiguous way to specify the\n * deflate format.  It is not written for speed but rather simplicity.  As a\n * side benefit, this code might actually be useful when small code is more\n * important than speed, such as bootstrap applications.  For typical deflate\n * data, zlib's inflate() is about four times as fast as puff().  zlib's\n * inflate compiles to around 20K on my machine, whereas puff.c compiles to\n * around 4K on my machine (a PowerPC using GNU cc).  If the faster decode()\n * function here is used, then puff() is only twice as slow as zlib's\n * inflate().\n *\n * All dynamically allocated memory comes from the stack.  The stack required\n * is less than 2K bytes.  This code is compatible with 16-bit int's and\n * assumes that long's are at least 32 bits.  puff.c uses the short data type,\n * assumed to be 16 bits, for arrays in order to to conserve memory.  The code\n * works whether integers are stored big endian or little endian.\n *\n * In the comments below are \"Format notes\" that describe the inflate process\n * and document some of the less obvious aspects of the format.  This source\n * code is meant to supplement RFC 1951, which formally describes the deflate\n * format:\n *\n *    http://www.zlib.org/rfc-deflate.html\n */\n\n/*\n * Change history:\n *\n * 1.0  10 Feb 2002     - First version\n * 1.1  17 Feb 2002     - Clarifications of some comments and notes\n *                      - Update puff() dest and source pointers on negative\n *                        errors to facilitate debugging deflators\n *                      - Remove longest from struct huffman -- not needed\n *                      - Simplify offs[] index in construct()\n *                      - Add input size and checking, using longjmp() to\n *                        maintain easy readability\n *                      - Use short data type for large arrays\n *                      - Use pointers instead of long to specify source and\n *                        destination sizes to avoid arbitrary 4 GB limits\n * 1.2  17 Mar 2002     - Add faster version of decode(), doubles speed (!),\n *                        but leave simple version for readabilty\n *                      - Make sure invalid distances detected if pointers\n *                        are 16 bits\n *                      - Fix fixed codes table error\n *                      - Provide a scanning mode for determining size of\n *                        uncompressed data\n * 1.3  20 Mar 2002     - Go back to lengths for puff() parameters [Gailly]\n *                      - Add a puff.h file for the interface\n *                      - Add braces in puff() for else do [Gailly]\n *                      - Use indexes instead of pointers for readability\n * 1.4  31 Mar 2002     - Simplify construct() code set check\n *                      - Fix some comments\n *                      - Add FIXLCODES #define\n * 1.5   6 Apr 2002     - Minor comment fixes\n * 1.6   7 Aug 2002     - Minor format changes\n * 1.7   3 Mar 2003     - Added test code for distribution\n *                      - Added zlib-like license\n * 1.8   9 Jan 2004     - Added some comments on no distance codes case\n * 1.9  21 Feb 2008     - Fix bug on 16-bit integer architectures [Pohland]\n *                      - Catch missing end-of-block symbol error\n * 2.0  25 Jul 2008     - Add #define to permit distance too far back\n *                      - Add option in TEST code for puff to write the data\n *                      - Add option in TEST code to skip input bytes\n *                      - Allow TEST code to read from piped stdin\n * 2.1   4 Apr 2010     - Avoid variable initialization for happier compilers\n *                      - Avoid unsigned comparisons for even happier compilers\n * 2.2  25 Apr 2010     - Fix bug in variable initializations [Oberhumer]\n *                      - Add const where appropriate [Oberhumer]\n *                      - Split if's and ?'s for coverage testing\n *                      - Break out test code to separate file\n *                      - Move NIL to puff.h\n *                      - Allow incomplete code only if single code length is 1\n *                      - Add full code coverage test to Makefile\n * 2.3  21 Jan 2013     - Check for invalid code length codes in dynamic blocks\n */\n\n#include <setjmp.h>             /* for setjmp(), longjmp(), and jmp_buf */\n#include \"puff.h\"               /* prototype for puff() */\n\n#define local static            /* for local function definitions */\n\n/*\n * Maximums for allocations and loops.  It is not useful to change these --\n * they are fixed by the deflate format.\n */\n#define MAXBITS 15              /* maximum bits in a code */\n#define MAXLCODES 286           /* maximum number of literal/length codes */\n#define MAXDCODES 30            /* maximum number of distance codes */\n#define MAXCODES (MAXLCODES+MAXDCODES)  /* maximum codes lengths to read */\n#define FIXLCODES 288           /* number of fixed literal/length codes */\n\n/* input and output state */\nstruct state {\n    /* output state */\n    unsigned char *out;         /* output buffer */\n    unsigned long outlen;       /* available space at out */\n    unsigned long outcnt;       /* bytes written to out so far */\n\n    /* input state */\n    const unsigned char *in;    /* input buffer */\n    unsigned long inlen;        /* available input at in */\n    unsigned long incnt;        /* bytes read so far */\n    int bitbuf;                 /* bit buffer */\n    int bitcnt;                 /* number of bits in bit buffer */\n\n    /* input limit error return state for bits() and decode() */\n    jmp_buf env;\n};\n\n/*\n * Return need bits from the input stream.  This always leaves less than\n * eight bits in the buffer.  bits() works properly for need == 0.\n *\n * Format notes:\n *\n * - Bits are stored in bytes from the least significant bit to the most\n *   significant bit.  Therefore bits are dropped from the bottom of the bit\n *   buffer, using shift right, and new bytes are appended to the top of the\n *   bit buffer, using shift left.\n */\nlocal int bits(struct state *s, int need)\n{\n    long val;           /* bit accumulator (can use up to 20 bits) */\n\n    /* load at least need bits into val */\n    val = s->bitbuf;\n    while (s->bitcnt < need) {\n        if (s->incnt == s->inlen)\n            longjmp(s->env, 1);         /* out of input */\n        val |= (long)(s->in[s->incnt++]) << s->bitcnt;  /* load eight bits */\n        s->bitcnt += 8;\n    }\n\n    /* drop need bits and update buffer, always zero to seven bits left */\n    s->bitbuf = (int)(val >> need);\n    s->bitcnt -= need;\n\n    /* return need bits, zeroing the bits above that */\n    return (int)(val & ((1L << need) - 1));\n}\n\n/*\n * Process a stored block.\n *\n * Format notes:\n *\n * - After the two-bit stored block type (00), the stored block length and\n *   stored bytes are byte-aligned for fast copying.  Therefore any leftover\n *   bits in the byte that has the last bit of the type, as many as seven, are\n *   discarded.  The value of the discarded bits are not defined and should not\n *   be checked against any expectation.\n *\n * - The second inverted copy of the stored block length does not have to be\n *   checked, but it's probably a good idea to do so anyway.\n *\n * - A stored block can have zero length.  This is sometimes used to byte-align\n *   subsets of the compressed data for random access or partial recovery.\n */\nlocal int stored(struct state *s)\n{\n    unsigned len;       /* length of stored block */\n\n    /* discard leftover bits from current byte (assumes s->bitcnt < 8) */\n    s->bitbuf = 0;\n    s->bitcnt = 0;\n\n    /* get length and check against its one's complement */\n    if (s->incnt + 4 > s->inlen)\n        return 2;                               /* not enough input */\n    len = s->in[s->incnt++];\n    len |= s->in[s->incnt++] << 8;\n    if (s->in[s->incnt++] != (~len & 0xff) ||\n        s->in[s->incnt++] != ((~len >> 8) & 0xff))\n        return -2;                              /* didn't match complement! */\n\n    /* copy len bytes from in to out */\n    if (s->incnt + len > s->inlen)\n        return 2;                               /* not enough input */\n    if (s->out != NIL) {\n        if (s->outcnt + len > s->outlen)\n            return 1;                           /* not enough output space */\n        while (len--)\n            s->out[s->outcnt++] = s->in[s->incnt++];\n    }\n    else {                                      /* just scanning */\n        s->outcnt += len;\n        s->incnt += len;\n    }\n\n    /* done with a valid stored block */\n    return 0;\n}\n\n/*\n * Huffman code decoding tables.  count[1..MAXBITS] is the number of symbols of\n * each length, which for a canonical code are stepped through in order.\n * symbol[] are the symbol values in canonical order, where the number of\n * entries is the sum of the counts in count[].  The decoding process can be\n * seen in the function decode() below.\n */\nstruct huffman {\n    short *count;       /* number of symbols of each length */\n    short *symbol;      /* canonically ordered symbols */\n};\n\n/*\n * Decode a code from the stream s using huffman table h.  Return the symbol or\n * a negative value if there is an error.  If all of the lengths are zero, i.e.\n * an empty code, or if the code is incomplete and an invalid code is received,\n * then -10 is returned after reading MAXBITS bits.\n *\n * Format notes:\n *\n * - The codes as stored in the compressed data are bit-reversed relative to\n *   a simple integer ordering of codes of the same lengths.  Hence below the\n *   bits are pulled from the compressed data one at a time and used to\n *   build the code value reversed from what is in the stream in order to\n *   permit simple integer comparisons for decoding.  A table-based decoding\n *   scheme (as used in zlib) does not need to do this reversal.\n *\n * - The first code for the shortest length is all zeros.  Subsequent codes of\n *   the same length are simply integer increments of the previous code.  When\n *   moving up a length, a zero bit is appended to the code.  For a complete\n *   code, the last code of the longest length will be all ones.\n *\n * - Incomplete codes are handled by this decoder, since they are permitted\n *   in the deflate format.  See the format notes for fixed() and dynamic().\n */\n#ifdef SLOW\nlocal int decode(struct state *s, const struct huffman *h)\n{\n    int len;            /* current number of bits in code */\n    int code;           /* len bits being decoded */\n    int first;          /* first code of length len */\n    int count;          /* number of codes of length len */\n    int index;          /* index of first code of length len in symbol table */\n\n    code = first = index = 0;\n    for (len = 1; len <= MAXBITS; len++) {\n        code |= bits(s, 1);             /* get next bit */\n        count = h->count[len];\n        if (code - count < first)       /* if length len, return symbol */\n            return h->symbol[index + (code - first)];\n        index += count;                 /* else update for next length */\n        first += count;\n        first <<= 1;\n        code <<= 1;\n    }\n    return -10;                         /* ran out of codes */\n}\n\n/*\n * A faster version of decode() for real applications of this code.   It's not\n * as readable, but it makes puff() twice as fast.  And it only makes the code\n * a few percent larger.\n */\n#else /* !SLOW */\nlocal int decode(struct state *s, const struct huffman *h)\n{\n    int len;            /* current number of bits in code */\n    int code;           /* len bits being decoded */\n    int first;          /* first code of length len */\n    int count;          /* number of codes of length len */\n    int index;          /* index of first code of length len in symbol table */\n    int bitbuf;         /* bits from stream */\n    int left;           /* bits left in next or left to process */\n    short *next;        /* next number of codes */\n\n    bitbuf = s->bitbuf;\n    left = s->bitcnt;\n    code = first = index = 0;\n    len = 1;\n    next = h->count + 1;\n    while (1) {\n        while (left--) {\n            code |= bitbuf & 1;\n            bitbuf >>= 1;\n            count = *next++;\n            if (code - count < first) { /* if length len, return symbol */\n                s->bitbuf = bitbuf;\n                s->bitcnt = (s->bitcnt - len) & 7;\n                return h->symbol[index + (code - first)];\n            }\n            index += count;             /* else update for next length */\n            first += count;\n            first <<= 1;\n            code <<= 1;\n            len++;\n        }\n        left = (MAXBITS+1) - len;\n        if (left == 0)\n            break;\n        if (s->incnt == s->inlen)\n            longjmp(s->env, 1);         /* out of input */\n        bitbuf = s->in[s->incnt++];\n        if (left > 8)\n            left = 8;\n    }\n    return -10;                         /* ran out of codes */\n}\n#endif /* SLOW */\n\n/*\n * Given the list of code lengths length[0..n-1] representing a canonical\n * Huffman code for n symbols, construct the tables required to decode those\n * codes.  Those tables are the number of codes of each length, and the symbols\n * sorted by length, retaining their original order within each length.  The\n * return value is zero for a complete code set, negative for an over-\n * subscribed code set, and positive for an incomplete code set.  The tables\n * can be used if the return value is zero or positive, but they cannot be used\n * if the return value is negative.  If the return value is zero, it is not\n * possible for decode() using that table to return an error--any stream of\n * enough bits will resolve to a symbol.  If the return value is positive, then\n * it is possible for decode() using that table to return an error for received\n * codes past the end of the incomplete lengths.\n *\n * Not used by decode(), but used for error checking, h->count[0] is the number\n * of the n symbols not in the code.  So n - h->count[0] is the number of\n * codes.  This is useful for checking for incomplete codes that have more than\n * one symbol, which is an error in a dynamic block.\n *\n * Assumption: for all i in 0..n-1, 0 <= length[i] <= MAXBITS\n * This is assured by the construction of the length arrays in dynamic() and\n * fixed() and is not verified by construct().\n *\n * Format notes:\n *\n * - Permitted and expected examples of incomplete codes are one of the fixed\n *   codes and any code with a single symbol which in deflate is coded as one\n *   bit instead of zero bits.  See the format notes for fixed() and dynamic().\n *\n * - Within a given code length, the symbols are kept in ascending order for\n *   the code bits definition.\n */\nlocal int construct(struct huffman *h, const short *length, int n)\n{\n    int symbol;         /* current symbol when stepping through length[] */\n    int len;            /* current length when stepping through h->count[] */\n    int left;           /* number of possible codes left of current length */\n    short offs[MAXBITS+1];      /* offsets in symbol table for each length */\n\n    /* count number of codes of each length */\n    for (len = 0; len <= MAXBITS; len++)\n        h->count[len] = 0;\n    for (symbol = 0; symbol < n; symbol++)\n        (h->count[length[symbol]])++;   /* assumes lengths are within bounds */\n    if (h->count[0] == n)               /* no codes! */\n        return 0;                       /* complete, but decode() will fail */\n\n    /* check for an over-subscribed or incomplete set of lengths */\n    left = 1;                           /* one possible code of zero length */\n    for (len = 1; len <= MAXBITS; len++) {\n        left <<= 1;                     /* one more bit, double codes left */\n        left -= h->count[len];          /* deduct count from possible codes */\n        if (left < 0)\n            return left;                /* over-subscribed--return negative */\n    }                                   /* left > 0 means incomplete */\n\n    /* generate offsets into symbol table for each length for sorting */\n    offs[1] = 0;\n    for (len = 1; len < MAXBITS; len++)\n        offs[len + 1] = offs[len] + h->count[len];\n\n    /*\n     * put symbols in table sorted by length, by symbol order within each\n     * length\n     */\n    for (symbol = 0; symbol < n; symbol++)\n        if (length[symbol] != 0)\n            h->symbol[offs[length[symbol]]++] = symbol;\n\n    /* return zero for complete set, positive for incomplete set */\n    return left;\n}\n\n/*\n * Decode literal/length and distance codes until an end-of-block code.\n *\n * Format notes:\n *\n * - Compressed data that is after the block type if fixed or after the code\n *   description if dynamic is a combination of literals and length/distance\n *   pairs terminated by and end-of-block code.  Literals are simply Huffman\n *   coded bytes.  A length/distance pair is a coded length followed by a\n *   coded distance to represent a string that occurs earlier in the\n *   uncompressed data that occurs again at the current location.\n *\n * - Literals, lengths, and the end-of-block code are combined into a single\n *   code of up to 286 symbols.  They are 256 literals (0..255), 29 length\n *   symbols (257..285), and the end-of-block symbol (256).\n *\n * - There are 256 possible lengths (3..258), and so 29 symbols are not enough\n *   to represent all of those.  Lengths 3..10 and 258 are in fact represented\n *   by just a length symbol.  Lengths 11..257 are represented as a symbol and\n *   some number of extra bits that are added as an integer to the base length\n *   of the length symbol.  The number of extra bits is determined by the base\n *   length symbol.  These are in the static arrays below, lens[] for the base\n *   lengths and lext[] for the corresponding number of extra bits.\n *\n * - The reason that 258 gets its own symbol is that the longest length is used\n *   often in highly redundant files.  Note that 258 can also be coded as the\n *   base value 227 plus the maximum extra value of 31.  While a good deflate\n *   should never do this, it is not an error, and should be decoded properly.\n *\n * - If a length is decoded, including its extra bits if any, then it is\n *   followed a distance code.  There are up to 30 distance symbols.  Again\n *   there are many more possible distances (1..32768), so extra bits are added\n *   to a base value represented by the symbol.  The distances 1..4 get their\n *   own symbol, but the rest require extra bits.  The base distances and\n *   corresponding number of extra bits are below in the static arrays dist[]\n *   and dext[].\n *\n * - Literal bytes are simply written to the output.  A length/distance pair is\n *   an instruction to copy previously uncompressed bytes to the output.  The\n *   copy is from distance bytes back in the output stream, copying for length\n *   bytes.\n *\n * - Distances pointing before the beginning of the output data are not\n *   permitted.\n *\n * - Overlapped copies, where the length is greater than the distance, are\n *   allowed and common.  For example, a distance of one and a length of 258\n *   simply copies the last byte 258 times.  A distance of four and a length of\n *   twelve copies the last four bytes three times.  A simple forward copy\n *   ignoring whether the length is greater than the distance or not implements\n *   this correctly.  You should not use memcpy() since its behavior is not\n *   defined for overlapped arrays.  You should not use memmove() or bcopy()\n *   since though their behavior -is- defined for overlapping arrays, it is\n *   defined to do the wrong thing in this case.\n */\nlocal int codes(struct state *s,\n                const struct huffman *lencode,\n                const struct huffman *distcode)\n{\n    int symbol;         /* decoded symbol */\n    int len;            /* length for copy */\n    unsigned dist;      /* distance for copy */\n    static const short lens[29] = { /* Size base for length codes 257..285 */\n        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,\n        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};\n    static const short lext[29] = { /* Extra bits for length codes 257..285 */\n        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,\n        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};\n    static const short dists[30] = { /* Offset base for distance codes 0..29 */\n        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,\n        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,\n        8193, 12289, 16385, 24577};\n    static const short dext[30] = { /* Extra bits for distance codes 0..29 */\n        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,\n        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,\n        12, 12, 13, 13};\n\n    /* decode literals and length/distance pairs */\n    do {\n        symbol = decode(s, lencode);\n        if (symbol < 0)\n            return symbol;              /* invalid symbol */\n        if (symbol < 256) {             /* literal: symbol is the byte */\n            /* write out the literal */\n            if (s->out != NIL) {\n                if (s->outcnt == s->outlen)\n                    return 1;\n                s->out[s->outcnt] = symbol;\n            }\n            s->outcnt++;\n        }\n        else if (symbol > 256) {        /* length */\n            /* get and compute length */\n            symbol -= 257;\n            if (symbol >= 29)\n                return -10;             /* invalid fixed code */\n            len = lens[symbol] + bits(s, lext[symbol]);\n\n            /* get and check distance */\n            symbol = decode(s, distcode);\n            if (symbol < 0)\n                return symbol;          /* invalid symbol */\n            dist = dists[symbol] + bits(s, dext[symbol]);\n#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR\n            if (dist > s->outcnt)\n                return -11;     /* distance too far back */\n#endif\n\n            /* copy length bytes from distance bytes back */\n            if (s->out != NIL) {\n                if (s->outcnt + len > s->outlen)\n                    return 1;\n                while (len--) {\n                    s->out[s->outcnt] =\n#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR\n                        dist > s->outcnt ?\n                            0 :\n#endif\n                            s->out[s->outcnt - dist];\n                    s->outcnt++;\n                }\n            }\n            else\n                s->outcnt += len;\n        }\n    } while (symbol != 256);            /* end of block symbol */\n\n    /* done with a valid fixed or dynamic block */\n    return 0;\n}\n\n/*\n * Process a fixed codes block.\n *\n * Format notes:\n *\n * - This block type can be useful for compressing small amounts of data for\n *   which the size of the code descriptions in a dynamic block exceeds the\n *   benefit of custom codes for that block.  For fixed codes, no bits are\n *   spent on code descriptions.  Instead the code lengths for literal/length\n *   codes and distance codes are fixed.  The specific lengths for each symbol\n *   can be seen in the \"for\" loops below.\n *\n * - The literal/length code is complete, but has two symbols that are invalid\n *   and should result in an error if received.  This cannot be implemented\n *   simply as an incomplete code since those two symbols are in the \"middle\"\n *   of the code.  They are eight bits long and the longest literal/length\\\n *   code is nine bits.  Therefore the code must be constructed with those\n *   symbols, and the invalid symbols must be detected after decoding.\n *\n * - The fixed distance codes also have two invalid symbols that should result\n *   in an error if received.  Since all of the distance codes are the same\n *   length, this can be implemented as an incomplete code.  Then the invalid\n *   codes are detected while decoding.\n */\nlocal int fixed(struct state *s)\n{\n    static int virgin = 1;\n    static short lencnt[MAXBITS+1], lensym[FIXLCODES];\n    static short distcnt[MAXBITS+1], distsym[MAXDCODES];\n    static struct huffman lencode, distcode;\n\n    /* build fixed huffman tables if first call (may not be thread safe) */\n    if (virgin) {\n        int symbol;\n        short lengths[FIXLCODES];\n\n        /* construct lencode and distcode */\n        lencode.count = lencnt;\n        lencode.symbol = lensym;\n        distcode.count = distcnt;\n        distcode.symbol = distsym;\n\n        /* literal/length table */\n        for (symbol = 0; symbol < 144; symbol++)\n            lengths[symbol] = 8;\n        for (; symbol < 256; symbol++)\n            lengths[symbol] = 9;\n        for (; symbol < 280; symbol++)\n            lengths[symbol] = 7;\n        for (; symbol < FIXLCODES; symbol++)\n            lengths[symbol] = 8;\n        construct(&lencode, lengths, FIXLCODES);\n\n        /* distance table */\n        for (symbol = 0; symbol < MAXDCODES; symbol++)\n            lengths[symbol] = 5;\n        construct(&distcode, lengths, MAXDCODES);\n\n        /* do this just once */\n        virgin = 0;\n    }\n\n    /* decode data until end-of-block code */\n    return codes(s, &lencode, &distcode);\n}\n\n/*\n * Process a dynamic codes block.\n *\n * Format notes:\n *\n * - A dynamic block starts with a description of the literal/length and\n *   distance codes for that block.  New dynamic blocks allow the compressor to\n *   rapidly adapt to changing data with new codes optimized for that data.\n *\n * - The codes used by the deflate format are \"canonical\", which means that\n *   the actual bits of the codes are generated in an unambiguous way simply\n *   from the number of bits in each code.  Therefore the code descriptions\n *   are simply a list of code lengths for each symbol.\n *\n * - The code lengths are stored in order for the symbols, so lengths are\n *   provided for each of the literal/length symbols, and for each of the\n *   distance symbols.\n *\n * - If a symbol is not used in the block, this is represented by a zero as\n *   as the code length.  This does not mean a zero-length code, but rather\n *   that no code should be created for this symbol.  There is no way in the\n *   deflate format to represent a zero-length code.\n *\n * - The maximum number of bits in a code is 15, so the possible lengths for\n *   any code are 1..15.\n *\n * - The fact that a length of zero is not permitted for a code has an\n *   interesting consequence.  Normally if only one symbol is used for a given\n *   code, then in fact that code could be represented with zero bits.  However\n *   in deflate, that code has to be at least one bit.  So for example, if\n *   only a single distance base symbol appears in a block, then it will be\n *   represented by a single code of length one, in particular one 0 bit.  This\n *   is an incomplete code, since if a 1 bit is received, it has no meaning,\n *   and should result in an error.  So incomplete distance codes of one symbol\n *   should be permitted, and the receipt of invalid codes should be handled.\n *\n * - It is also possible to have a single literal/length code, but that code\n *   must be the end-of-block code, since every dynamic block has one.  This\n *   is not the most efficient way to create an empty block (an empty fixed\n *   block is fewer bits), but it is allowed by the format.  So incomplete\n *   literal/length codes of one symbol should also be permitted.\n *\n * - If there are only literal codes and no lengths, then there are no distance\n *   codes.  This is represented by one distance code with zero bits.\n *\n * - The list of up to 286 length/literal lengths and up to 30 distance lengths\n *   are themselves compressed using Huffman codes and run-length encoding.  In\n *   the list of code lengths, a 0 symbol means no code, a 1..15 symbol means\n *   that length, and the symbols 16, 17, and 18 are run-length instructions.\n *   Each of 16, 17, and 18 are follwed by extra bits to define the length of\n *   the run.  16 copies the last length 3 to 6 times.  17 represents 3 to 10\n *   zero lengths, and 18 represents 11 to 138 zero lengths.  Unused symbols\n *   are common, hence the special coding for zero lengths.\n *\n * - The symbols for 0..18 are Huffman coded, and so that code must be\n *   described first.  This is simply a sequence of up to 19 three-bit values\n *   representing no code (0) or the code length for that symbol (1..7).\n *\n * - A dynamic block starts with three fixed-size counts from which is computed\n *   the number of literal/length code lengths, the number of distance code\n *   lengths, and the number of code length code lengths (ok, you come up with\n *   a better name!) in the code descriptions.  For the literal/length and\n *   distance codes, lengths after those provided are considered zero, i.e. no\n *   code.  The code length code lengths are received in a permuted order (see\n *   the order[] array below) to make a short code length code length list more\n *   likely.  As it turns out, very short and very long codes are less likely\n *   to be seen in a dynamic code description, hence what may appear initially\n *   to be a peculiar ordering.\n *\n * - Given the number of literal/length code lengths (nlen) and distance code\n *   lengths (ndist), then they are treated as one long list of nlen + ndist\n *   code lengths.  Therefore run-length coding can and often does cross the\n *   boundary between the two sets of lengths.\n *\n * - So to summarize, the code description at the start of a dynamic block is\n *   three counts for the number of code lengths for the literal/length codes,\n *   the distance codes, and the code length codes.  This is followed by the\n *   code length code lengths, three bits each.  This is used to construct the\n *   code length code which is used to read the remainder of the lengths.  Then\n *   the literal/length code lengths and distance lengths are read as a single\n *   set of lengths using the code length codes.  Codes are constructed from\n *   the resulting two sets of lengths, and then finally you can start\n *   decoding actual compressed data in the block.\n *\n * - For reference, a \"typical\" size for the code description in a dynamic\n *   block is around 80 bytes.\n */\nlocal int dynamic(struct state *s)\n{\n    int nlen, ndist, ncode;             /* number of lengths in descriptor */\n    int index;                          /* index of lengths[] */\n    int err;                            /* construct() return value */\n    short lengths[MAXCODES];            /* descriptor code lengths */\n    short lencnt[MAXBITS+1], lensym[MAXLCODES];         /* lencode memory */\n    short distcnt[MAXBITS+1], distsym[MAXDCODES];       /* distcode memory */\n    struct huffman lencode, distcode;   /* length and distance codes */\n    static const short order[19] =      /* permutation of code length codes */\n        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};\n\n    /* construct lencode and distcode */\n    lencode.count = lencnt;\n    lencode.symbol = lensym;\n    distcode.count = distcnt;\n    distcode.symbol = distsym;\n\n    /* get number of lengths in each table, check lengths */\n    nlen = bits(s, 5) + 257;\n    ndist = bits(s, 5) + 1;\n    ncode = bits(s, 4) + 4;\n    if (nlen > MAXLCODES || ndist > MAXDCODES)\n        return -3;                      /* bad counts */\n\n    /* read code length code lengths (really), missing lengths are zero */\n    for (index = 0; index < ncode; index++)\n        lengths[order[index]] = bits(s, 3);\n    for (; index < 19; index++)\n        lengths[order[index]] = 0;\n\n    /* build huffman table for code lengths codes (use lencode temporarily) */\n    err = construct(&lencode, lengths, 19);\n    if (err != 0)               /* require complete code set here */\n        return -4;\n\n    /* read length/literal and distance code length tables */\n    index = 0;\n    while (index < nlen + ndist) {\n        int symbol;             /* decoded value */\n        int len;                /* last length to repeat */\n\n        symbol = decode(s, &lencode);\n        if (symbol < 0)\n            return symbol;          /* invalid symbol */\n        if (symbol < 16)                /* length in 0..15 */\n            lengths[index++] = symbol;\n        else {                          /* repeat instruction */\n            len = 0;                    /* assume repeating zeros */\n            if (symbol == 16) {         /* repeat last length 3..6 times */\n                if (index == 0)\n                    return -5;          /* no last length! */\n                len = lengths[index - 1];       /* last length */\n                symbol = 3 + bits(s, 2);\n            }\n            else if (symbol == 17)      /* repeat zero 3..10 times */\n                symbol = 3 + bits(s, 3);\n            else                        /* == 18, repeat zero 11..138 times */\n                symbol = 11 + bits(s, 7);\n            if (index + symbol > nlen + ndist)\n                return -6;              /* too many lengths! */\n            while (symbol--)            /* repeat last or zero symbol times */\n                lengths[index++] = len;\n        }\n    }\n\n    /* check for end-of-block code -- there better be one! */\n    if (lengths[256] == 0)\n        return -9;\n\n    /* build huffman table for literal/length codes */\n    err = construct(&lencode, lengths, nlen);\n    if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1]))\n        return -7;      /* incomplete code ok only for single length 1 code */\n\n    /* build huffman table for distance codes */\n    err = construct(&distcode, lengths + nlen, ndist);\n    if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1]))\n        return -8;      /* incomplete code ok only for single length 1 code */\n\n    /* decode data until end-of-block code */\n    return codes(s, &lencode, &distcode);\n}\n\n/*\n * Inflate source to dest.  On return, destlen and sourcelen are updated to the\n * size of the uncompressed data and the size of the deflate data respectively.\n * On success, the return value of puff() is zero.  If there is an error in the\n * source data, i.e. it is not in the deflate format, then a negative value is\n * returned.  If there is not enough input available or there is not enough\n * output space, then a positive error is returned.  In that case, destlen and\n * sourcelen are not updated to facilitate retrying from the beginning with the\n * provision of more input data or more output space.  In the case of invalid\n * inflate data (a negative error), the dest and source pointers are updated to\n * facilitate the debugging of deflators.\n *\n * puff() also has a mode to determine the size of the uncompressed output with\n * no output written.  For this dest must be (unsigned char *)0.  In this case,\n * the input value of *destlen is ignored, and on return *destlen is set to the\n * size of the uncompressed output.\n *\n * The return codes are:\n *\n *   2:  available inflate data did not terminate\n *   1:  output space exhausted before completing inflate\n *   0:  successful inflate\n *  -1:  invalid block type (type == 3)\n *  -2:  stored block length did not match one's complement\n *  -3:  dynamic block code description: too many length or distance codes\n *  -4:  dynamic block code description: code lengths codes incomplete\n *  -5:  dynamic block code description: repeat lengths with no first length\n *  -6:  dynamic block code description: repeat more than specified lengths\n *  -7:  dynamic block code description: invalid literal/length code lengths\n *  -8:  dynamic block code description: invalid distance code lengths\n *  -9:  dynamic block code description: missing end-of-block code\n * -10:  invalid literal/length or distance code in fixed or dynamic block\n * -11:  distance is too far back in fixed or dynamic block\n *\n * Format notes:\n *\n * - Three bits are read for each block to determine the kind of block and\n *   whether or not it is the last block.  Then the block is decoded and the\n *   process repeated if it was not the last block.\n *\n * - The leftover bits in the last byte of the deflate data after the last\n *   block (if it was a fixed or dynamic block) are undefined and have no\n *   expected values to check.\n */\nint puff(unsigned char *dest,           /* pointer to destination pointer */\n         unsigned long *destlen,        /* amount of output space */\n         const unsigned char *source,   /* pointer to source data pointer */\n         unsigned long *sourcelen)      /* amount of input available */\n{\n    struct state s;             /* input/output state */\n    int last, type;             /* block information */\n    int err;                    /* return value */\n\n    /* initialize output state */\n    s.out = dest;\n    s.outlen = *destlen;                /* ignored if dest is NIL */\n    s.outcnt = 0;\n\n    /* initialize input state */\n    s.in = source;\n    s.inlen = *sourcelen;\n    s.incnt = 0;\n    s.bitbuf = 0;\n    s.bitcnt = 0;\n\n    /* return if bits() or decode() tries to read past available input */\n    if (setjmp(s.env) != 0)             /* if came back here via longjmp() */\n        err = 2;                        /* then skip do-loop, return error */\n    else {\n        /* process blocks until last block or error */\n        do {\n            last = bits(&s, 1);         /* one if last block */\n            type = bits(&s, 2);         /* block type 0..3 */\n            err = type == 0 ?\n                    stored(&s) :\n                    (type == 1 ?\n                        fixed(&s) :\n                        (type == 2 ?\n                            dynamic(&s) :\n                            -1));       /* type == 3, invalid */\n            if (err != 0)\n                break;                  /* return with error */\n        } while (!last);\n    }\n\n    /* update the lengths and return */\n    if (err <= 0) {\n        *destlen = s.outcnt;\n        *sourcelen = s.incnt;\n    }\n    return err;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/puff/puff.h",
    "content": "/* puff.h\n  Copyright (C) 2002-2013 Mark Adler, all rights reserved\n  version 2.3, 21 Jan 2013\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the author be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Mark Adler    madler@alumni.caltech.edu\n */\n\n\n/*\n * See puff.c for purpose and usage.\n */\n#ifndef NIL\n#  define NIL ((unsigned char *)0)      /* for no output option */\n#endif\n\nint puff(unsigned char *dest,           /* pointer to destination pointer */\n         unsigned long *destlen,        /* amount of output space */\n         const unsigned char *source,   /* pointer to source data pointer */\n         unsigned long *sourcelen);     /* amount of input available */\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/puff/pufftest.c",
    "content": "/*\n * pufftest.c\n * Copyright (C) 2002-2013 Mark Adler\n * For conditions of distribution and use, see copyright notice in puff.h\n * version 2.3, 21 Jan 2013\n */\n\n/* Example of how to use puff().\n\n   Usage: puff [-w] [-f] [-nnn] file\n          ... | puff [-w] [-f] [-nnn]\n\n   where file is the input file with deflate data, nnn is the number of bytes\n   of input to skip before inflating (e.g. to skip a zlib or gzip header), and\n   -w is used to write the decompressed data to stdout.  -f is for coverage\n   testing, and causes pufftest to fail with not enough output space (-f does\n   a write like -w, so -w is not required). */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include \"puff.h\"\n\n#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)\n#  include <fcntl.h>\n#  include <io.h>\n#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)\n#else\n#  define SET_BINARY_MODE(file)\n#endif\n\n#define local static\n\n/* Return size times approximately the cube root of 2, keeping the result as 1,\n   3, or 5 times a power of 2 -- the result is always > size, until the result\n   is the maximum value of an unsigned long, where it remains.  This is useful\n   to keep reallocations less than ~33% over the actual data. */\nlocal size_t bythirds(size_t size)\n{\n    int n;\n    size_t m;\n\n    m = size;\n    for (n = 0; m; n++)\n        m >>= 1;\n    if (n < 3)\n        return size + 1;\n    n -= 3;\n    m = size >> n;\n    m += m == 6 ? 2 : 1;\n    m <<= n;\n    return m > size ? m : (size_t)(-1);\n}\n\n/* Read the input file *name, or stdin if name is NULL, into allocated memory.\n   Reallocate to larger buffers until the entire file is read in.  Return a\n   pointer to the allocated data, or NULL if there was a memory allocation\n   failure.  *len is the number of bytes of data read from the input file (even\n   if load() returns NULL).  If the input file was empty or could not be opened\n   or read, *len is zero. */\nlocal void *load(const char *name, size_t *len)\n{\n    size_t size;\n    void *buf, *swap;\n    FILE *in;\n\n    *len = 0;\n    buf = malloc(size = 4096);\n    if (buf == NULL)\n        return NULL;\n    in = name == NULL ? stdin : fopen(name, \"rb\");\n    if (in != NULL) {\n        for (;;) {\n            *len += fread((char *)buf + *len, 1, size - *len, in);\n            if (*len < size) break;\n            size = bythirds(size);\n            if (size == *len || (swap = realloc(buf, size)) == NULL) {\n                free(buf);\n                buf = NULL;\n                break;\n            }\n            buf = swap;\n        }\n        fclose(in);\n    }\n    return buf;\n}\n\nint main(int argc, char **argv)\n{\n    int ret, put = 0, fail = 0;\n    unsigned skip = 0;\n    char *arg, *name = NULL;\n    unsigned char *source = NULL, *dest;\n    size_t len = 0;\n    unsigned long sourcelen, destlen;\n\n    /* process arguments */\n    while (arg = *++argv, --argc)\n        if (arg[0] == '-') {\n            if (arg[1] == 'w' && arg[2] == 0)\n                put = 1;\n            else if (arg[1] == 'f' && arg[2] == 0)\n                fail = 1, put = 1;\n            else if (arg[1] >= '0' && arg[1] <= '9')\n                skip = (unsigned)atoi(arg + 1);\n            else {\n                fprintf(stderr, \"invalid option %s\\n\", arg);\n                return 3;\n            }\n        }\n        else if (name != NULL) {\n            fprintf(stderr, \"only one file name allowed\\n\");\n            return 3;\n        }\n        else\n            name = arg;\n    source = load(name, &len);\n    if (source == NULL) {\n        fprintf(stderr, \"memory allocation failure\\n\");\n        return 4;\n    }\n    if (len == 0) {\n        fprintf(stderr, \"could not read %s, or it was empty\\n\",\n                name == NULL ? \"<stdin>\" : name);\n        free(source);\n        return 3;\n    }\n    if (skip >= len) {\n        fprintf(stderr, \"skip request of %d leaves no input\\n\", skip);\n        free(source);\n        return 3;\n    }\n\n    /* test inflate data with offset skip */\n    len -= skip;\n    sourcelen = (unsigned long)len;\n    ret = puff(NIL, &destlen, source + skip, &sourcelen);\n    if (ret)\n        fprintf(stderr, \"puff() failed with return code %d\\n\", ret);\n    else {\n        fprintf(stderr, \"puff() succeeded uncompressing %lu bytes\\n\", destlen);\n        if (sourcelen < len) fprintf(stderr, \"%lu compressed bytes unused\\n\",\n                                     len - sourcelen);\n    }\n\n    /* if requested, inflate again and write decompressd data to stdout */\n    if (put && ret == 0) {\n        if (fail)\n            destlen >>= 1;\n        dest = malloc(destlen);\n        if (dest == NULL) {\n            fprintf(stderr, \"memory allocation failure\\n\");\n            free(source);\n            return 4;\n        }\n        puff(dest, &destlen, source + skip, &sourcelen);\n        SET_BINARY_MODE(stdout);\n        fwrite(dest, 1, destlen, stdout);\n        free(dest);\n    }\n\n    /* clean up */\n    free(source);\n    return ret;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/testzlib/testzlib.c",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n#include <windows.h>\n\n#include \"zlib.h\"\n\n\nvoid MyDoMinus64(LARGE_INTEGER *R,LARGE_INTEGER A,LARGE_INTEGER B)\n{\n    R->HighPart = A.HighPart - B.HighPart;\n    if (A.LowPart >= B.LowPart)\n        R->LowPart = A.LowPart - B.LowPart;\n    else\n    {\n        R->LowPart = A.LowPart - B.LowPart;\n        R->HighPart --;\n    }\n}\n\n#ifdef _M_X64\n// see http://msdn2.microsoft.com/library/twchhe95(en-us,vs.80).aspx for __rdtsc\nunsigned __int64 __rdtsc(void);\nvoid BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)\n{\n //   printf(\"rdtsc = %I64x\\n\",__rdtsc());\n   pbeginTime64->QuadPart=__rdtsc();\n}\n\nLARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)\n{\n    LARGE_INTEGER LIres;\n    unsigned _int64 res=__rdtsc()-((unsigned _int64)(beginTime64.QuadPart));\n    LIres.QuadPart=res;\n   // printf(\"rdtsc = %I64x\\n\",__rdtsc());\n    return LIres;\n}\n#else\n#ifdef _M_IX86\nvoid myGetRDTSC32(LARGE_INTEGER * pbeginTime64)\n{\n    DWORD dwEdx,dwEax;\n    _asm\n    {\n        rdtsc\n        mov dwEax,eax\n        mov dwEdx,edx\n    }\n    pbeginTime64->LowPart=dwEax;\n    pbeginTime64->HighPart=dwEdx;\n}\n\nvoid BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)\n{\n    myGetRDTSC32(pbeginTime64);\n}\n\nLARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)\n{\n    LARGE_INTEGER LIres,endTime64;\n    myGetRDTSC32(&endTime64);\n\n    LIres.LowPart=LIres.HighPart=0;\n    MyDoMinus64(&LIres,endTime64,beginTime64);\n    return LIres;\n}\n#else\nvoid myGetRDTSC32(LARGE_INTEGER * pbeginTime64)\n{\n}\n\nvoid BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)\n{\n}\n\nLARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)\n{\n    LARGE_INTEGER lr;\n    lr.QuadPart=0;\n    return lr;\n}\n#endif\n#endif\n\nvoid BeginCountPerfCounter(LARGE_INTEGER * pbeginTime64,BOOL fComputeTimeQueryPerf)\n{\n    if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(pbeginTime64)))\n    {\n        pbeginTime64->LowPart = GetTickCount();\n        pbeginTime64->HighPart = 0;\n    }\n}\n\nDWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)\n{\n    LARGE_INTEGER endTime64,ticksPerSecond,ticks;\n    DWORDLONG ticksShifted,tickSecShifted;\n    DWORD dwLog=16+0;\n    DWORD dwRet;\n    if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(&endTime64)))\n        dwRet = (GetTickCount() - beginTime64.LowPart)*1;\n    else\n    {\n        MyDoMinus64(&ticks,endTime64,beginTime64);\n        QueryPerformanceFrequency(&ticksPerSecond);\n\n\n        {\n            ticksShifted = Int64ShrlMod32(*(DWORDLONG*)&ticks,dwLog);\n            tickSecShifted = Int64ShrlMod32(*(DWORDLONG*)&ticksPerSecond,dwLog);\n\n        }\n\n        dwRet = (DWORD)((((DWORD)ticksShifted)*1000)/(DWORD)(tickSecShifted));\n        dwRet *=1;\n    }\n    return dwRet;\n}\n\nint ReadFileMemory(const char* filename,long* plFileSize,unsigned char** pFilePtr)\n{\n    FILE* stream;\n    unsigned char* ptr;\n    int retVal=1;\n    stream=fopen(filename, \"rb\");\n    if (stream==NULL)\n        return 0;\n\n    fseek(stream,0,SEEK_END);\n\n    *plFileSize=ftell(stream);\n    fseek(stream,0,SEEK_SET);\n    ptr=malloc((*plFileSize)+1);\n    if (ptr==NULL)\n        retVal=0;\n    else\n    {\n        if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize))\n            retVal=0;\n    }\n    fclose(stream);\n    *pFilePtr=ptr;\n    return retVal;\n}\n\nint main(int argc, char *argv[])\n{\n    int BlockSizeCompress=0x8000;\n    int BlockSizeUncompress=0x8000;\n    int cprLevel=Z_DEFAULT_COMPRESSION ;\n    long lFileSize;\n    unsigned char* FilePtr;\n    long lBufferSizeCpr;\n    long lBufferSizeUncpr;\n    long lCompressedSize=0;\n    unsigned char* CprPtr;\n    unsigned char* UncprPtr;\n    long lSizeCpr,lSizeUncpr;\n    DWORD dwGetTick,dwMsecQP;\n    LARGE_INTEGER li_qp,li_rdtsc,dwResRdtsc;\n\n    if (argc<=1)\n    {\n        printf(\"run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\\n\");\n        return 0;\n    }\n\n    if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0)\n    {\n        printf(\"error reading %s\\n\",argv[1]);\n        return 1;\n    }\n    else printf(\"file %s read, %u bytes\\n\",argv[1],lFileSize);\n\n    if (argc>=3)\n        BlockSizeCompress=atol(argv[2]);\n\n    if (argc>=4)\n        BlockSizeUncompress=atol(argv[3]);\n\n    if (argc>=5)\n        cprLevel=(int)atol(argv[4]);\n\n    lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200;\n    lBufferSizeUncpr = lBufferSizeCpr;\n\n    CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress);\n\n    BeginCountPerfCounter(&li_qp,TRUE);\n    dwGetTick=GetTickCount();\n    BeginCountRdtsc(&li_rdtsc);\n    {\n        z_stream zcpr;\n        int ret=Z_OK;\n        long lOrigToDo = lFileSize;\n        long lOrigDone = 0;\n        int step=0;\n        memset(&zcpr,0,sizeof(z_stream));\n        deflateInit(&zcpr,cprLevel);\n\n        zcpr.next_in = FilePtr;\n        zcpr.next_out = CprPtr;\n\n\n        do\n        {\n            long all_read_before = zcpr.total_in;\n            zcpr.avail_in = min(lOrigToDo,BlockSizeCompress);\n            zcpr.avail_out = BlockSizeCompress;\n            ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH);\n            lOrigDone += (zcpr.total_in-all_read_before);\n            lOrigToDo -= (zcpr.total_in-all_read_before);\n            step++;\n        } while (ret==Z_OK);\n\n        lSizeCpr=zcpr.total_out;\n        deflateEnd(&zcpr);\n        dwGetTick=GetTickCount()-dwGetTick;\n        dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);\n        dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);\n        printf(\"total compress size = %u, in %u step\\n\",lSizeCpr,step);\n        printf(\"time = %u msec = %f sec\\n\",dwGetTick,dwGetTick/(double)1000.);\n        printf(\"defcpr time QP = %u msec = %f sec\\n\",dwMsecQP,dwMsecQP/(double)1000.);\n        printf(\"defcpr result rdtsc = %I64x\\n\\n\",dwResRdtsc.QuadPart);\n    }\n\n    CprPtr=(unsigned char*)realloc(CprPtr,lSizeCpr);\n    UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress);\n\n    BeginCountPerfCounter(&li_qp,TRUE);\n    dwGetTick=GetTickCount();\n    BeginCountRdtsc(&li_rdtsc);\n    {\n        z_stream zcpr;\n        int ret=Z_OK;\n        long lOrigToDo = lSizeCpr;\n        long lOrigDone = 0;\n        int step=0;\n        memset(&zcpr,0,sizeof(z_stream));\n        inflateInit(&zcpr);\n\n        zcpr.next_in = CprPtr;\n        zcpr.next_out = UncprPtr;\n\n\n        do\n        {\n            long all_read_before = zcpr.total_in;\n            zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress);\n            zcpr.avail_out = BlockSizeUncompress;\n            ret=inflate(&zcpr,Z_SYNC_FLUSH);\n            lOrigDone += (zcpr.total_in-all_read_before);\n            lOrigToDo -= (zcpr.total_in-all_read_before);\n            step++;\n        } while (ret==Z_OK);\n\n        lSizeUncpr=zcpr.total_out;\n        inflateEnd(&zcpr);\n        dwGetTick=GetTickCount()-dwGetTick;\n        dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);\n        dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);\n        printf(\"total uncompress size = %u, in %u step\\n\",lSizeUncpr,step);\n        printf(\"time = %u msec = %f sec\\n\",dwGetTick,dwGetTick/(double)1000.);\n        printf(\"uncpr  time QP = %u msec = %f sec\\n\",dwMsecQP,dwMsecQP/(double)1000.);\n        printf(\"uncpr  result rdtsc = %I64x\\n\\n\",dwResRdtsc.QuadPart);\n    }\n\n    if (lSizeUncpr==lFileSize)\n    {\n        if (memcmp(FilePtr,UncprPtr,lFileSize)==0)\n            printf(\"compare ok\\n\");\n\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/testzlib/testzlib.txt",
    "content": "To build testzLib with Visual Studio 2005:\n\ncopy to a directory file from :\n- root of zLib tree\n- contrib/testzlib\n- contrib/masmx86\n- contrib/masmx64\n- contrib/vstudio/vc7\n\nand open testzlib8.sln"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/untgz/Makefile",
    "content": "CC=cc\nCFLAGS=-g\n\nuntgz: untgz.o ../../libz.a\n\t$(CC) $(CFLAGS) -o untgz untgz.o -L../.. -lz\n\nuntgz.o: untgz.c ../../zlib.h\n\t$(CC) $(CFLAGS) -c -I../.. untgz.c\n\n../../libz.a:\n\tcd ../..; ./configure; make\n\nclean:\n\trm -f untgz untgz.o *~\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/untgz/Makefile.msc",
    "content": "CC=cl\nCFLAGS=-MD\n\nuntgz.exe: untgz.obj ..\\..\\zlib.lib\n\t$(CC) $(CFLAGS) untgz.obj ..\\..\\zlib.lib\n\nuntgz.obj: untgz.c ..\\..\\zlib.h\n\t$(CC) $(CFLAGS) -c -I..\\.. untgz.c\n\n..\\..\\zlib.lib:\n\tcd ..\\..\n\t$(MAKE) -f win32\\makefile.msc\n\tcd contrib\\untgz\n\nclean:\n\t-del untgz.obj\n\t-del untgz.exe\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/untgz/untgz.c",
    "content": "/*\n * untgz.c -- Display contents and extract files from a gzip'd TAR file\n *\n * written by Pedro A. Aranda Gutierrez <paag@tid.es>\n * adaptation to Unix by Jean-loup Gailly <jloup@gzip.org>\n * various fixes by Cosmin Truta <cosmint@cs.ubbcluj.ro>\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <errno.h>\n\n#include \"zlib.h\"\n\n#ifdef unix\n#  include <unistd.h>\n#else\n#  include <direct.h>\n#  include <io.h>\n#endif\n\n#ifdef WIN32\n#include <windows.h>\n#  ifndef F_OK\n#    define F_OK  0\n#  endif\n#  define mkdir(dirname,mode)   _mkdir(dirname)\n#  ifdef _MSC_VER\n#    define access(path,mode)   _access(path,mode)\n#    define chmod(path,mode)    _chmod(path,mode)\n#    define strdup(str)         _strdup(str)\n#  endif\n#else\n#  include <utime.h>\n#endif\n\n\n/* values used in typeflag field */\n\n#define REGTYPE  '0'            /* regular file */\n#define AREGTYPE '\\0'           /* regular file */\n#define LNKTYPE  '1'            /* link */\n#define SYMTYPE  '2'            /* reserved */\n#define CHRTYPE  '3'            /* character special */\n#define BLKTYPE  '4'            /* block special */\n#define DIRTYPE  '5'            /* directory */\n#define FIFOTYPE '6'            /* FIFO special */\n#define CONTTYPE '7'            /* reserved */\n\n/* GNU tar extensions */\n\n#define GNUTYPE_DUMPDIR  'D'    /* file names from dumped directory */\n#define GNUTYPE_LONGLINK 'K'    /* long link name */\n#define GNUTYPE_LONGNAME 'L'    /* long file name */\n#define GNUTYPE_MULTIVOL 'M'    /* continuation of file from another volume */\n#define GNUTYPE_NAMES    'N'    /* file name that does not fit into main hdr */\n#define GNUTYPE_SPARSE   'S'    /* sparse file */\n#define GNUTYPE_VOLHDR   'V'    /* tape/volume header */\n\n\n/* tar header */\n\n#define BLOCKSIZE     512\n#define SHORTNAMESIZE 100\n\nstruct tar_header\n{                               /* byte offset */\n  char name[100];               /*   0 */\n  char mode[8];                 /* 100 */\n  char uid[8];                  /* 108 */\n  char gid[8];                  /* 116 */\n  char size[12];                /* 124 */\n  char mtime[12];               /* 136 */\n  char chksum[8];               /* 148 */\n  char typeflag;                /* 156 */\n  char linkname[100];           /* 157 */\n  char magic[6];                /* 257 */\n  char version[2];              /* 263 */\n  char uname[32];               /* 265 */\n  char gname[32];               /* 297 */\n  char devmajor[8];             /* 329 */\n  char devminor[8];             /* 337 */\n  char prefix[155];             /* 345 */\n                                /* 500 */\n};\n\nunion tar_buffer\n{\n  char               buffer[BLOCKSIZE];\n  struct tar_header  header;\n};\n\nstruct attr_item\n{\n  struct attr_item  *next;\n  char              *fname;\n  int                mode;\n  time_t             time;\n};\n\nenum { TGZ_EXTRACT, TGZ_LIST, TGZ_INVALID };\n\nchar *TGZfname          OF((const char *));\nvoid TGZnotfound        OF((const char *));\n\nint getoct              OF((char *, int));\nchar *strtime           OF((time_t *));\nint setfiletime         OF((char *, time_t));\nvoid push_attr          OF((struct attr_item **, char *, int, time_t));\nvoid restore_attr       OF((struct attr_item **));\n\nint ExprMatch           OF((char *, char *));\n\nint makedir             OF((char *));\nint matchname           OF((int, int, char **, char *));\n\nvoid error              OF((const char *));\nint tar                 OF((gzFile, int, int, int, char **));\n\nvoid help               OF((int));\nint main                OF((int, char **));\n\nchar *prog;\n\nconst char *TGZsuffix[] = { \"\\0\", \".tar\", \".tar.gz\", \".taz\", \".tgz\", NULL };\n\n/* return the file name of the TGZ archive */\n/* or NULL if it does not exist */\n\nchar *TGZfname (const char *arcname)\n{\n  static char buffer[1024];\n  int origlen,i;\n\n  strcpy(buffer,arcname);\n  origlen = strlen(buffer);\n\n  for (i=0; TGZsuffix[i]; i++)\n    {\n       strcpy(buffer+origlen,TGZsuffix[i]);\n       if (access(buffer,F_OK) == 0)\n         return buffer;\n    }\n  return NULL;\n}\n\n\n/* error message for the filename */\n\nvoid TGZnotfound (const char *arcname)\n{\n  int i;\n\n  fprintf(stderr,\"%s: Couldn't find \",prog);\n  for (i=0;TGZsuffix[i];i++)\n    fprintf(stderr,(TGZsuffix[i+1]) ? \"%s%s, \" : \"or %s%s\\n\",\n            arcname,\n            TGZsuffix[i]);\n  exit(1);\n}\n\n\n/* convert octal digits to int */\n/* on error return -1 */\n\nint getoct (char *p,int width)\n{\n  int result = 0;\n  char c;\n\n  while (width--)\n    {\n      c = *p++;\n      if (c == 0)\n        break;\n      if (c == ' ')\n        continue;\n      if (c < '0' || c > '7')\n        return -1;\n      result = result * 8 + (c - '0');\n    }\n  return result;\n}\n\n\n/* convert time_t to string */\n/* use the \"YYYY/MM/DD hh:mm:ss\" format */\n\nchar *strtime (time_t *t)\n{\n  struct tm   *local;\n  static char result[32];\n\n  local = localtime(t);\n  sprintf(result,\"%4d/%02d/%02d %02d:%02d:%02d\",\n          local->tm_year+1900, local->tm_mon+1, local->tm_mday,\n          local->tm_hour, local->tm_min, local->tm_sec);\n  return result;\n}\n\n\n/* set file time */\n\nint setfiletime (char *fname,time_t ftime)\n{\n#ifdef WIN32\n  static int isWinNT = -1;\n  SYSTEMTIME st;\n  FILETIME locft, modft;\n  struct tm *loctm;\n  HANDLE hFile;\n  int result;\n\n  loctm = localtime(&ftime);\n  if (loctm == NULL)\n    return -1;\n\n  st.wYear         = (WORD)loctm->tm_year + 1900;\n  st.wMonth        = (WORD)loctm->tm_mon + 1;\n  st.wDayOfWeek    = (WORD)loctm->tm_wday;\n  st.wDay          = (WORD)loctm->tm_mday;\n  st.wHour         = (WORD)loctm->tm_hour;\n  st.wMinute       = (WORD)loctm->tm_min;\n  st.wSecond       = (WORD)loctm->tm_sec;\n  st.wMilliseconds = 0;\n  if (!SystemTimeToFileTime(&st, &locft) ||\n      !LocalFileTimeToFileTime(&locft, &modft))\n    return -1;\n\n  if (isWinNT < 0)\n    isWinNT = (GetVersion() < 0x80000000) ? 1 : 0;\n  hFile = CreateFile(fname, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,\n                     (isWinNT ? FILE_FLAG_BACKUP_SEMANTICS : 0),\n                     NULL);\n  if (hFile == INVALID_HANDLE_VALUE)\n    return -1;\n  result = SetFileTime(hFile, NULL, NULL, &modft) ? 0 : -1;\n  CloseHandle(hFile);\n  return result;\n#else\n  struct utimbuf settime;\n\n  settime.actime = settime.modtime = ftime;\n  return utime(fname,&settime);\n#endif\n}\n\n\n/* push file attributes */\n\nvoid push_attr(struct attr_item **list,char *fname,int mode,time_t time)\n{\n  struct attr_item *item;\n\n  item = (struct attr_item *)malloc(sizeof(struct attr_item));\n  if (item == NULL)\n    error(\"Out of memory\");\n  item->fname = strdup(fname);\n  item->mode  = mode;\n  item->time  = time;\n  item->next  = *list;\n  *list       = item;\n}\n\n\n/* restore file attributes */\n\nvoid restore_attr(struct attr_item **list)\n{\n  struct attr_item *item, *prev;\n\n  for (item = *list; item != NULL; )\n    {\n      setfiletime(item->fname,item->time);\n      chmod(item->fname,item->mode);\n      prev = item;\n      item = item->next;\n      free(prev);\n    }\n  *list = NULL;\n}\n\n\n/* match regular expression */\n\n#define ISSPECIAL(c) (((c) == '*') || ((c) == '/'))\n\nint ExprMatch (char *string,char *expr)\n{\n  while (1)\n    {\n      if (ISSPECIAL(*expr))\n        {\n          if (*expr == '/')\n            {\n              if (*string != '\\\\' && *string != '/')\n                return 0;\n              string ++; expr++;\n            }\n          else if (*expr == '*')\n            {\n              if (*expr ++ == 0)\n                return 1;\n              while (*++string != *expr)\n                if (*string == 0)\n                  return 0;\n            }\n        }\n      else\n        {\n          if (*string != *expr)\n            return 0;\n          if (*expr++ == 0)\n            return 1;\n          string++;\n        }\n    }\n}\n\n\n/* recursive mkdir */\n/* abort on ENOENT; ignore other errors like \"directory already exists\" */\n/* return 1 if OK */\n/*        0 on error */\n\nint makedir (char *newdir)\n{\n  char *buffer = strdup(newdir);\n  char *p;\n  int  len = strlen(buffer);\n\n  if (len <= 0) {\n    free(buffer);\n    return 0;\n  }\n  if (buffer[len-1] == '/') {\n    buffer[len-1] = '\\0';\n  }\n  if (mkdir(buffer, 0755) == 0)\n    {\n      free(buffer);\n      return 1;\n    }\n\n  p = buffer+1;\n  while (1)\n    {\n      char hold;\n\n      while(*p && *p != '\\\\' && *p != '/')\n        p++;\n      hold = *p;\n      *p = 0;\n      if ((mkdir(buffer, 0755) == -1) && (errno == ENOENT))\n        {\n          fprintf(stderr,\"%s: Couldn't create directory %s\\n\",prog,buffer);\n          free(buffer);\n          return 0;\n        }\n      if (hold == 0)\n        break;\n      *p++ = hold;\n    }\n  free(buffer);\n  return 1;\n}\n\n\nint matchname (int arg,int argc,char **argv,char *fname)\n{\n  if (arg == argc)      /* no arguments given (untgz tgzarchive) */\n    return 1;\n\n  while (arg < argc)\n    if (ExprMatch(fname,argv[arg++]))\n      return 1;\n\n  return 0; /* ignore this for the moment being */\n}\n\n\n/* tar file list or extract */\n\nint tar (gzFile in,int action,int arg,int argc,char **argv)\n{\n  union  tar_buffer buffer;\n  int    len;\n  int    err;\n  int    getheader = 1;\n  int    remaining = 0;\n  FILE   *outfile = NULL;\n  char   fname[BLOCKSIZE];\n  int    tarmode;\n  time_t tartime;\n  struct attr_item *attributes = NULL;\n\n  if (action == TGZ_LIST)\n    printf(\"    date      time     size                       file\\n\"\n           \" ---------- -------- --------- -------------------------------------\\n\");\n  while (1)\n    {\n      len = gzread(in, &buffer, BLOCKSIZE);\n      if (len < 0)\n        error(gzerror(in, &err));\n      /*\n       * Always expect complete blocks to process\n       * the tar information.\n       */\n      if (len != BLOCKSIZE)\n        {\n          action = TGZ_INVALID; /* force error exit */\n          remaining = 0;        /* force I/O cleanup */\n        }\n\n      /*\n       * If we have to get a tar header\n       */\n      if (getheader >= 1)\n        {\n          /*\n           * if we met the end of the tar\n           * or the end-of-tar block,\n           * we are done\n           */\n          if (len == 0 || buffer.header.name[0] == 0)\n            break;\n\n          tarmode = getoct(buffer.header.mode,8);\n          tartime = (time_t)getoct(buffer.header.mtime,12);\n          if (tarmode == -1 || tartime == (time_t)-1)\n            {\n              buffer.header.name[0] = 0;\n              action = TGZ_INVALID;\n            }\n\n          if (getheader == 1)\n            {\n              strncpy(fname,buffer.header.name,SHORTNAMESIZE);\n              if (fname[SHORTNAMESIZE-1] != 0)\n                  fname[SHORTNAMESIZE] = 0;\n            }\n          else\n            {\n              /*\n               * The file name is longer than SHORTNAMESIZE\n               */\n              if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0)\n                  error(\"bad long name\");\n              getheader = 1;\n            }\n\n          /*\n           * Act according to the type flag\n           */\n          switch (buffer.header.typeflag)\n            {\n            case DIRTYPE:\n              if (action == TGZ_LIST)\n                printf(\" %s     <dir> %s\\n\",strtime(&tartime),fname);\n              if (action == TGZ_EXTRACT)\n                {\n                  makedir(fname);\n                  push_attr(&attributes,fname,tarmode,tartime);\n                }\n              break;\n            case REGTYPE:\n            case AREGTYPE:\n              remaining = getoct(buffer.header.size,12);\n              if (remaining == -1)\n                {\n                  action = TGZ_INVALID;\n                  break;\n                }\n              if (action == TGZ_LIST)\n                printf(\" %s %9d %s\\n\",strtime(&tartime),remaining,fname);\n              else if (action == TGZ_EXTRACT)\n                {\n                  if (matchname(arg,argc,argv,fname))\n                    {\n                      outfile = fopen(fname,\"wb\");\n                      if (outfile == NULL) {\n                        /* try creating directory */\n                        char *p = strrchr(fname, '/');\n                        if (p != NULL) {\n                          *p = '\\0';\n                          makedir(fname);\n                          *p = '/';\n                          outfile = fopen(fname,\"wb\");\n                        }\n                      }\n                      if (outfile != NULL)\n                        printf(\"Extracting %s\\n\",fname);\n                      else\n                        fprintf(stderr, \"%s: Couldn't create %s\",prog,fname);\n                    }\n                  else\n                    outfile = NULL;\n                }\n              getheader = 0;\n              break;\n            case GNUTYPE_LONGLINK:\n            case GNUTYPE_LONGNAME:\n              remaining = getoct(buffer.header.size,12);\n              if (remaining < 0 || remaining >= BLOCKSIZE)\n                {\n                  action = TGZ_INVALID;\n                  break;\n                }\n              len = gzread(in, fname, BLOCKSIZE);\n              if (len < 0)\n                error(gzerror(in, &err));\n              if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining)\n                {\n                  action = TGZ_INVALID;\n                  break;\n                }\n              getheader = 2;\n              break;\n            default:\n              if (action == TGZ_LIST)\n                printf(\" %s     <---> %s\\n\",strtime(&tartime),fname);\n              break;\n            }\n        }\n      else\n        {\n          unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining;\n\n          if (outfile != NULL)\n            {\n              if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes)\n                {\n                  fprintf(stderr,\n                    \"%s: Error writing %s -- skipping\\n\",prog,fname);\n                  fclose(outfile);\n                  outfile = NULL;\n                  remove(fname);\n                }\n            }\n          remaining -= bytes;\n        }\n\n      if (remaining == 0)\n        {\n          getheader = 1;\n          if (outfile != NULL)\n            {\n              fclose(outfile);\n              outfile = NULL;\n              if (action != TGZ_INVALID)\n                push_attr(&attributes,fname,tarmode,tartime);\n            }\n        }\n\n      /*\n       * Abandon if errors are found\n       */\n      if (action == TGZ_INVALID)\n        {\n          error(\"broken archive\");\n          break;\n        }\n    }\n\n  /*\n   * Restore file modes and time stamps\n   */\n  restore_attr(&attributes);\n\n  if (gzclose(in) != Z_OK)\n    error(\"failed gzclose\");\n\n  return 0;\n}\n\n\n/* ============================================================ */\n\nvoid help(int exitval)\n{\n  printf(\"untgz version 0.2.1\\n\"\n         \"  using zlib version %s\\n\\n\",\n         zlibVersion());\n  printf(\"Usage: untgz file.tgz            extract all files\\n\"\n         \"       untgz file.tgz fname ...  extract selected files\\n\"\n         \"       untgz -l file.tgz         list archive contents\\n\"\n         \"       untgz -h                  display this help\\n\");\n  exit(exitval);\n}\n\nvoid error(const char *msg)\n{\n  fprintf(stderr, \"%s: %s\\n\", prog, msg);\n  exit(1);\n}\n\n\n/* ============================================================ */\n\n#if defined(WIN32) && defined(__GNUC__)\nint _CRT_glob = 0;      /* disable argument globbing in MinGW */\n#endif\n\nint main(int argc,char **argv)\n{\n    int         action = TGZ_EXTRACT;\n    int         arg = 1;\n    char        *TGZfile;\n    gzFile      *f;\n\n    prog = strrchr(argv[0],'\\\\');\n    if (prog == NULL)\n      {\n        prog = strrchr(argv[0],'/');\n        if (prog == NULL)\n          {\n            prog = strrchr(argv[0],':');\n            if (prog == NULL)\n              prog = argv[0];\n            else\n              prog++;\n          }\n        else\n          prog++;\n      }\n    else\n      prog++;\n\n    if (argc == 1)\n      help(0);\n\n    if (strcmp(argv[arg],\"-l\") == 0)\n      {\n        action = TGZ_LIST;\n        if (argc == ++arg)\n          help(0);\n      }\n    else if (strcmp(argv[arg],\"-h\") == 0)\n      {\n        help(0);\n      }\n\n    if ((TGZfile = TGZfname(argv[arg])) == NULL)\n      TGZnotfound(argv[arg]);\n\n    ++arg;\n    if ((action == TGZ_LIST) && (arg != argc))\n      help(1);\n\n/*\n *  Process the TGZ file\n */\n    switch(action)\n      {\n      case TGZ_LIST:\n      case TGZ_EXTRACT:\n        f = gzopen(TGZfile,\"rb\");\n        if (f == NULL)\n          {\n            fprintf(stderr,\"%s: Couldn't gzopen %s\\n\",prog,TGZfile);\n            return 1;\n          }\n        exit(tar(f, action, arg, argc, argv));\n      break;\n\n      default:\n        error(\"Unknown option\");\n        exit(1);\n      }\n\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/readme.txt",
    "content": "Building instructions for the DLL versions of Zlib 1.2.8\n========================================================\n\nThis directory contains projects that build zlib and minizip using\nMicrosoft Visual C++ 9.0/10.0.\n\nYou don't need to build these projects yourself. You can download the\nbinaries from:\n  http://www.winimage.com/zLibDll\n\nMore information can be found at this site.\n\n\n\n\n\nBuild instructions for Visual Studio 2008 (32 bits or 64 bits)\n--------------------------------------------------------------\n- Uncompress current zlib, including all contrib/* files\n- Compile assembly code (with Visual Studio Command Prompt) by running:\n   bld_ml64.bat (in contrib\\masmx64)\n   bld_ml32.bat (in contrib\\masmx86)\n- Open contrib\\vstudio\\vc9\\zlibvc.sln with Microsoft Visual C++ 2008\n- Or run: vcbuild /rebuild contrib\\vstudio\\vc9\\zlibvc.sln \"Release|Win32\"\n\nBuild instructions for Visual Studio 2010 (32 bits or 64 bits)\n--------------------------------------------------------------\n- Uncompress current zlib, including all contrib/* files\n- Open contrib\\vstudio\\vc10\\zlibvc.sln with Microsoft Visual C++ 2010\n\nBuild instructions for Visual Studio 2012 (32 bits or 64 bits)\n--------------------------------------------------------------\n- Uncompress current zlib, including all contrib/* files\n- Open contrib\\vstudio\\vc11\\zlibvc.sln with Microsoft Visual C++ 2012\n\n\nImportant\n---------\n- To use zlibwapi.dll in your application, you must define the\n  macro ZLIB_WINAPI when compiling your application's source files.\n\n\nAdditional notes\n----------------\n- This DLL, named zlibwapi.dll, is compatible to the old zlib.dll built\n  by Gilles Vollant from the zlib 1.1.x sources, and distributed at\n    http://www.winimage.com/zLibDll\n  It uses the WINAPI calling convention for the exported functions, and\n  includes the minizip functionality. If your application needs that\n  particular build of zlib.dll, you can rename zlibwapi.dll to zlib.dll.\n\n- The new DLL was renamed because there exist several incompatible\n  versions of zlib.dll on the Internet.\n\n- There is also an official DLL build of zlib, named zlib1.dll. This one\n  is exporting the functions using the CDECL convention. See the file\n  win32\\DLL_FAQ.txt found in this zlib distribution.\n\n- There used to be a ZLIB_DLL macro in zlib 1.1.x, but now this symbol\n  has a slightly different effect. To avoid compatibility problems, do\n  not define it here.\n\n\nGilles Vollant\ninfo@winimage.com\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/miniunz.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Itanium\">\n      <Configuration>Debug</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Itanium\">\n      <Configuration>Release</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694382A}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\MiniUnzip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\MiniUnzip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\MiniUnzip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\MiniUnzip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\MiniUnzip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\MiniUnzip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\MiniUnzip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\MiniUnzip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\MiniUnzip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\MiniUnzip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\MiniUnzip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\MiniUnzip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</GenerateManifest>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x86\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x86\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x64\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>ia64\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x64\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>ia64\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\minizip\\miniunz.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"zlibvc.vcxproj\">\n      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/miniunz.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{048af943-022b-4db6-beeb-a54c34774ee2}</UniqueIdentifier>\n      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{c1d600d2-888f-4aea-b73e-8b0dd9befa0c}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{0844199a-966b-4f19-81db-1e0125e141b9}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\minizip\\miniunz.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/minizip.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Itanium\">\n      <Configuration>Debug</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Itanium\">\n      <Configuration>Release</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\MiniZip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\MiniZip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\MiniZip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\MiniZip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</LinkIncremental>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\$(Configuration)\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\$(Configuration)\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\$(Configuration)\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</LinkIncremental>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\$(Configuration)\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</LinkIncremental>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x86\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)minizip.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x86\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)minizip.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x64\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)minizip.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>ia64\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)minizip.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x64\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)minizip.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>ia64\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)minizip.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\minizip\\minizip.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"zlibvc.vcxproj\">\n      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/minizip.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{c0419b40-bf50-40da-b153-ff74215b79de}</UniqueIdentifier>\n      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{bb87b070-735b-478e-92ce-7383abb2f36c}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{f46ab6a6-548f-43cb-ae96-681abb5bd5db}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\minizip\\minizip.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/testzlib.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Itanium\">\n      <Configuration>Debug</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|Itanium\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|Win32\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|x64\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Itanium\">\n      <Configuration>Release</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>\n    <RootNamespace>testzlib</RootNamespace>\n    <Keyword>Win32Proj</Keyword>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">x86\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">x86\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">x64\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">x64\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">ia64\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">ia64\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</GenerateManifest>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>..\\..\\masmx86\\match686.obj;..\\..\\masmx86\\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>..\\..\\masmx86\\match686.obj;..\\..\\masmx86\\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>..\\..\\masmx64\\gvmat64.obj;..\\..\\masmx64\\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">\n    <ClCompile>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>..\\..\\masmx64\\gvmat64.obj;..\\..\\masmx64\\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\adler32.c\" />\n    <ClCompile Include=\"..\\..\\..\\compress.c\" />\n    <ClCompile Include=\"..\\..\\..\\crc32.c\" />\n    <ClCompile Include=\"..\\..\\..\\deflate.c\" />\n    <ClCompile Include=\"..\\..\\..\\infback.c\" />\n    <ClCompile Include=\"..\\..\\masmx64\\inffas8664.c\">\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</ExcludedFromBuild>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inffast.c\" />\n    <ClCompile Include=\"..\\..\\..\\inflate.c\" />\n    <ClCompile Include=\"..\\..\\..\\inftrees.c\" />\n    <ClCompile Include=\"..\\..\\testzlib\\testzlib.c\" />\n    <ClCompile Include=\"..\\..\\..\\trees.c\" />\n    <ClCompile Include=\"..\\..\\..\\uncompr.c\" />\n    <ClCompile Include=\"..\\..\\..\\zutil.c\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/testzlib.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{c1f6a2e3-5da5-4955-8653-310d3efe05a9}</UniqueIdentifier>\n      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{c2aaffdc-2c95-4d6f-8466-4bec5890af2c}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{c274fe07-05f2-461c-964b-f6341e4e7eb5}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\adler32.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\compress.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\crc32.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\deflate.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\infback.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\masmx64\\inffas8664.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inffast.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inflate.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inftrees.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\testzlib\\testzlib.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\trees.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\uncompr.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\zutil.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/testzlibdll.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Itanium\">\n      <Configuration>Debug</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Itanium\">\n      <Configuration>Release</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694366A}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\TestZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\TestZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\TestZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\TestZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\TestZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\TestZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\TestZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\TestZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\TestZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\TestZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\TestZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\TestZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</GenerateManifest>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x86\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x86\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x64\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>ia64\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x64\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>ia64\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\testzlib\\testzlib.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"zlibvc.vcxproj\">\n      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/testzlibdll.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{fa61a89f-93fc-4c89-b29e-36224b7592f4}</UniqueIdentifier>\n      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{d4b85da0-2ba2-4934-b57f-e2584e3848ee}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{e573e075-00bd-4a7d-bd67-a8cc9bfc5aca}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\testzlib\\testzlib.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/zlib.rc",
    "content": "#include <windows.h>\n\n#define IDR_VERSION1  1\nIDR_VERSION1\tVERSIONINFO\tMOVEABLE IMPURE LOADONCALL DISCARDABLE\n  FILEVERSION\t 1,2,8,0\n  PRODUCTVERSION 1,2,8,0\n  FILEFLAGSMASK\tVS_FFI_FILEFLAGSMASK\n  FILEFLAGS\t0\n  FILEOS\tVOS_DOS_WINDOWS32\n  FILETYPE\tVFT_DLL\n  FILESUBTYPE\t0\t// not used\nBEGIN\n  BLOCK \"StringFileInfo\"\n  BEGIN\n    BLOCK \"040904E4\"\n    //language ID = U.S. English, char set = Windows, Multilingual\n\n    BEGIN\n      VALUE \"FileDescription\", \"zlib data compression and ZIP file I/O library\\0\"\n      VALUE \"FileVersion\",\t\"1.2.8\\0\"\n      VALUE \"InternalName\",\t\"zlib\\0\"\n      VALUE \"OriginalFilename\",\t\"zlibwapi.dll\\0\"\n      VALUE \"ProductName\",\t\"ZLib.DLL\\0\"\n      VALUE \"Comments\",\"DLL support by Alessandro Iacopetti & Gilles Vollant\\0\"\n      VALUE \"LegalCopyright\", \"(C) 1995-2013 Jean-loup Gailly & Mark Adler\\0\"\n    END\n  END\n  BLOCK \"VarFileInfo\"\n  BEGIN\n    VALUE \"Translation\", 0x0409, 1252\n  END\nEND\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/zlibstat.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Itanium\">\n      <Configuration>Debug</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|Itanium\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|Win32\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|x64\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Itanium\">\n      <Configuration>Release</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">x86\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">x86\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">x64\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">x64\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">ia64\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">ia64\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <DebugInformationFormat>OldStyle</DebugInformationFormat>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n    <PreBuildEvent>\n      <Command>cd ..\\..\\masmx86\nbld_ml32.bat</Command>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>..\\..\\masmx86\\match686.obj;..\\..\\masmx86\\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n    <PreBuildEvent>\n      <Command>cd ..\\..\\masmx86\nbld_ml32.bat</Command>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <DebugInformationFormat>OldStyle</DebugInformationFormat>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n    <PreBuildEvent>\n      <Command>cd ..\\..\\masmx64\nbld_ml64.bat</Command>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <DebugInformationFormat>OldStyle</DebugInformationFormat>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>..\\..\\masmx64\\gvmat64.obj;..\\..\\masmx64\\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n    <PreBuildEvent>\n      <Command>cd ..\\..\\masmx64\nbld_ml64.bat</Command>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\adler32.c\" />\n    <ClCompile Include=\"..\\..\\..\\compress.c\" />\n    <ClCompile Include=\"..\\..\\..\\crc32.c\" />\n    <ClCompile Include=\"..\\..\\..\\deflate.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzclose.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzlib.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzread.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzwrite.c\" />\n    <ClCompile Include=\"..\\..\\..\\infback.c\" />\n    <ClCompile Include=\"..\\..\\masmx64\\inffas8664.c\">\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</ExcludedFromBuild>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inffast.c\" />\n    <ClCompile Include=\"..\\..\\..\\inflate.c\" />\n    <ClCompile Include=\"..\\..\\..\\inftrees.c\" />\n    <ClCompile Include=\"..\\..\\minizip\\ioapi.c\" />\n    <ClCompile Include=\"..\\..\\..\\trees.c\" />\n    <ClCompile Include=\"..\\..\\..\\uncompr.c\" />\n    <ClCompile Include=\"..\\..\\minizip\\unzip.c\" />\n    <ClCompile Include=\"..\\..\\minizip\\zip.c\" />\n    <ClCompile Include=\"..\\..\\..\\zutil.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"zlib.rc\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"zlibvc.def\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/zlibstat.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{174213f6-7f66-4ae8-a3a8-a1e0a1e6ffdd}</UniqueIdentifier>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\adler32.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\compress.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\crc32.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\deflate.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\gzclose.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\gzlib.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\gzread.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\gzwrite.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\infback.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\masmx64\\inffas8664.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inffast.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inflate.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inftrees.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\minizip\\ioapi.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\trees.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\uncompr.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\minizip\\unzip.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\minizip\\zip.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\zutil.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"zlib.rc\">\n      <Filter>Source Files</Filter>\n    </ResourceCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"zlibvc.def\">\n      <Filter>Source Files</Filter>\n    </None>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/zlibvc.def",
    "content": "LIBRARY\n; zlib data compression and ZIP file I/O library\n\nVERSION\t\t1.2.8\n\nEXPORTS\n        adler32                                  @1\n        compress                                 @2\n        crc32                                    @3\n        deflate                                  @4\n        deflateCopy                              @5\n        deflateEnd                               @6\n        deflateInit2_                            @7\n        deflateInit_                             @8\n        deflateParams                            @9\n        deflateReset                             @10\n        deflateSetDictionary                     @11\n        gzclose                                  @12\n        gzdopen                                  @13\n        gzerror                                  @14\n        gzflush                                  @15\n        gzopen                                   @16\n        gzread                                   @17\n        gzwrite                                  @18\n        inflate                                  @19\n        inflateEnd                               @20\n        inflateInit2_                            @21\n        inflateInit_                             @22\n        inflateReset                             @23\n        inflateSetDictionary                     @24\n        inflateSync                              @25\n        uncompress                               @26\n        zlibVersion                              @27\n        gzprintf                                 @28\n        gzputc                                   @29\n        gzgetc                                   @30\n        gzseek                                   @31\n        gzrewind                                 @32\n        gztell                                   @33\n        gzeof                                    @34\n        gzsetparams                              @35\n        zError                                   @36\n        inflateSyncPoint                         @37\n        get_crc_table                            @38\n        compress2                                @39\n        gzputs                                   @40\n        gzgets                                   @41\n        inflateCopy                              @42\n        inflateBackInit_                         @43\n        inflateBack                              @44\n        inflateBackEnd                           @45\n        compressBound                            @46\n        deflateBound                             @47\n        gzclearerr                               @48\n        gzungetc                                 @49\n        zlibCompileFlags                         @50\n        deflatePrime                             @51\n        deflatePending                           @52\n\n        unzOpen                                  @61\n        unzClose                                 @62\n        unzGetGlobalInfo                         @63\n        unzGetCurrentFileInfo                    @64\n        unzGoToFirstFile                         @65\n        unzGoToNextFile                          @66\n        unzOpenCurrentFile                       @67\n        unzReadCurrentFile                       @68\n        unzOpenCurrentFile3                      @69\n        unztell                                  @70\n        unzeof                                   @71\n        unzCloseCurrentFile                      @72\n        unzGetGlobalComment                      @73\n        unzStringFileNameCompare                 @74\n        unzLocateFile                            @75\n        unzGetLocalExtrafield                    @76\n        unzOpen2                                 @77\n        unzOpenCurrentFile2                      @78\n        unzOpenCurrentFilePassword               @79\n\n        zipOpen                                  @80\n        zipOpenNewFileInZip                      @81\n        zipWriteInFileInZip                      @82\n        zipCloseFileInZip                        @83\n        zipClose                                 @84\n        zipOpenNewFileInZip2                     @86\n        zipCloseFileInZipRaw                     @87\n        zipOpen2                                 @88\n        zipOpenNewFileInZip3                     @89\n\n        unzGetFilePos                            @100\n        unzGoToFilePos                           @101\n\n        fill_win32_filefunc                      @110\n\n; zlibwapi v1.2.4 added:\n        fill_win32_filefunc64                   @111\n        fill_win32_filefunc64A                  @112\n        fill_win32_filefunc64W                  @113\n\n        unzOpen64                               @120\n        unzOpen2_64                             @121\n        unzGetGlobalInfo64                      @122\n        unzGetCurrentFileInfo64                 @124\n        unzGetCurrentFileZStreamPos64           @125\n        unztell64                               @126\n        unzGetFilePos64                         @127\n        unzGoToFilePos64                        @128\n\n        zipOpen64                               @130\n        zipOpen2_64                             @131\n        zipOpenNewFileInZip64                   @132\n        zipOpenNewFileInZip2_64                 @133\n        zipOpenNewFileInZip3_64                 @134\n        zipOpenNewFileInZip4_64                 @135\n        zipCloseFileInZipRaw64                  @136\n\n; zlib1 v1.2.4 added:\n        adler32_combine                         @140\n        crc32_combine                           @142\n        deflateSetHeader                        @144\n        deflateTune                             @145\n        gzbuffer                                @146\n        gzclose_r                               @147\n        gzclose_w                               @148\n        gzdirect                                @149\n        gzoffset                                @150\n        inflateGetHeader                        @156\n        inflateMark                             @157\n        inflatePrime                            @158\n        inflateReset2                           @159\n        inflateUndermine                        @160\n\n; zlib1 v1.2.6 added:\n        gzgetc_                                 @161\n        inflateResetKeep                        @163\n        deflateResetKeep                        @164\n\n; zlib1 v1.2.7 added:\n        gzopen_w                                @165\n\n; zlib1 v1.2.8 added:\n        inflateGetDictionary                    @166\n        gzvprintf                               @167\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/zlibvc.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 11.00\n# Visual Studio 2010\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"zlibvc\", \"zlibvc.vcxproj\", \"{8FD826F8-3739-44E6-8CC8-997122E53B8D}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"zlibstat\", \"zlibstat.vcxproj\", \"{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"testzlib\", \"testzlib.vcxproj\", \"{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"testzlibdll\", \"testzlibdll.vcxproj\", \"{C52F9E7B-498A-42BE-8DB4-85A15694366A}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"minizip\", \"minizip.vcxproj\", \"{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"miniunz\", \"miniunz.vcxproj\", \"{C52F9E7B-498A-42BE-8DB4-85A15694382A}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Itanium = Debug|Itanium\n\t\tDebug|Win32 = Debug|Win32\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|Itanium = Release|Itanium\n\t\tRelease|Win32 = Release|Win32\n\t\tRelease|x64 = Release|x64\n\t\tReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium\n\t\tReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32\n\t\tReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/zlibvc.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Itanium\">\n      <Configuration>Debug</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|Itanium\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|Win32\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|x64\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Itanium\">\n      <Configuration>Release</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{8FD826F8-3739-44E6-8CC8-997122E53B8D}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">x86\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">x86\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">x64\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">x64\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">ia64\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">ia64\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</GenerateManifest>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">zlibwapid</TargetName>\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">zlibwapi</TargetName>\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">zlibwapi</TargetName>\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">zlibwapid</TargetName>\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">zlibwapi</TargetName>\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">zlibwapi</TargetName>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Midl>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>Win32</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>..\\..\\masmx86\\match686.obj;..\\..\\masmx86\\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <GenerateMapFile>true</GenerateMapFile>\n      <SubSystem>Windows</SubSystem>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n    </Link>\n    <PreBuildEvent>\n      <Command>cd ..\\..\\masmx86\nbld_ml32.bat</Command>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">\n    <Midl>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>Win32</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerOutput>All</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <SubSystem>Windows</SubSystem>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Midl>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>Win32</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerOutput>All</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>..\\..\\masmx86\\match686.obj;..\\..\\masmx86\\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <SubSystem>Windows</SubSystem>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n    </Link>\n    <PreBuildEvent>\n      <Command>cd ..\\..\\masmx86\nbld_ml32.bat</Command>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Midl>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>X64</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <AdditionalDependencies>..\\..\\masmx64\\gvmat64.obj;..\\..\\masmx64\\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <GenerateMapFile>true</GenerateMapFile>\n      <SubSystem>Windows</SubSystem>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n    <PreBuildEvent>\n      <Command>cd ..\\..\\masmx64\nbld_ml64.bat</Command>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">\n    <Midl>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\n      <SubSystem>Windows</SubSystem>\n      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">\n    <Midl>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>X64</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerOutput>All</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <SubSystem>Windows</SubSystem>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">\n    <Midl>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerOutput>All</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\n      <SubSystem>Windows</SubSystem>\n      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Midl>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>X64</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerOutput>All</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <AdditionalDependencies>..\\..\\masmx64\\gvmat64.obj;..\\..\\masmx64\\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <SubSystem>Windows</SubSystem>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n    <PreBuildEvent>\n      <Command>cd ..\\..\\masmx64\nbld_ml64.bat</Command>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">\n    <Midl>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerOutput>All</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\n      <SubSystem>Windows</SubSystem>\n      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\adler32.c\" />\n    <ClCompile Include=\"..\\..\\..\\compress.c\" />\n    <ClCompile Include=\"..\\..\\..\\crc32.c\" />\n    <ClCompile Include=\"..\\..\\..\\deflate.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzclose.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzlib.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzread.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzwrite.c\" />\n    <ClCompile Include=\"..\\..\\..\\infback.c\" />\n    <ClCompile Include=\"..\\..\\masmx64\\inffas8664.c\">\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</ExcludedFromBuild>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inffast.c\" />\n    <ClCompile Include=\"..\\..\\..\\inflate.c\" />\n    <ClCompile Include=\"..\\..\\..\\inftrees.c\" />\n    <ClCompile Include=\"..\\..\\minizip\\ioapi.c\" />\n    <ClCompile Include=\"..\\..\\minizip\\iowin32.c\" />\n    <ClCompile Include=\"..\\..\\..\\trees.c\" />\n    <ClCompile Include=\"..\\..\\..\\uncompr.c\" />\n    <ClCompile Include=\"..\\..\\minizip\\unzip.c\">\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\minizip\\zip.c\">\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\zutil.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"zlib.rc\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"zlibvc.def\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\..\\deflate.h\" />\n    <ClInclude Include=\"..\\..\\..\\infblock.h\" />\n    <ClInclude Include=\"..\\..\\..\\infcodes.h\" />\n    <ClInclude Include=\"..\\..\\..\\inffast.h\" />\n    <ClInclude Include=\"..\\..\\..\\inftrees.h\" />\n    <ClInclude Include=\"..\\..\\..\\infutil.h\" />\n    <ClInclude Include=\"..\\..\\..\\zconf.h\" />\n    <ClInclude Include=\"..\\..\\..\\zlib.h\" />\n    <ClInclude Include=\"..\\..\\..\\zutil.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc10/zlibvc.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{07934a85-8b61-443d-a0ee-b2eedb74f3cd}</UniqueIdentifier>\n      <Extensions>cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{1d99675b-433d-4a21-9e50-ed4ab8b19762}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;fi;fd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{431c0958-fa71-44d0-9084-2d19d100c0cc}</UniqueIdentifier>\n      <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\adler32.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\compress.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\crc32.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\deflate.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\gzclose.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\gzlib.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\gzread.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\gzwrite.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\infback.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\masmx64\\inffas8664.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inffast.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inflate.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inftrees.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\minizip\\ioapi.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\minizip\\iowin32.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\trees.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\uncompr.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\minizip\\unzip.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\minizip\\zip.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\zutil.c\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"zlib.rc\">\n      <Filter>Source Files</Filter>\n    </ResourceCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"zlibvc.def\">\n      <Filter>Source Files</Filter>\n    </None>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\..\\deflate.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\infblock.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\infcodes.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\inffast.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\inftrees.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\infutil.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\zconf.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\zlib.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\..\\..\\zutil.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc11/miniunz.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Itanium\">\n      <Configuration>Debug</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Itanium\">\n      <Configuration>Release</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694382A}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\MiniUnzip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\MiniUnzip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\MiniUnzip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\MiniUnzip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\MiniUnzip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\MiniUnzip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\MiniUnzip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\MiniUnzip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\MiniUnzip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\MiniUnzip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\MiniUnzip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\MiniUnzip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</GenerateManifest>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x86\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x86\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x64\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>ia64\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x64\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>ia64\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\minizip\\miniunz.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"zlibvc.vcxproj\">\n      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc11/minizip.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Itanium\">\n      <Configuration>Debug</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Itanium\">\n      <Configuration>Release</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\MiniZip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\MiniZip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\MiniZip$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\MiniZip$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</LinkIncremental>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\$(Configuration)\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\$(Configuration)\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\$(Configuration)\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</LinkIncremental>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\$(Configuration)\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</LinkIncremental>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x86\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)minizip.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x86\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)minizip.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x64\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)minizip.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>ia64\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)minizip.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x64\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)minizip.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>ia64\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)minizip.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\minizip\\minizip.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"zlibvc.vcxproj\">\n      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc11/testzlib.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Itanium\">\n      <Configuration>Debug</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|Itanium\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|Win32\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|x64\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Itanium\">\n      <Configuration>Release</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>\n    <RootNamespace>testzlib</RootNamespace>\n    <Keyword>Win32Proj</Keyword>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">x86\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">x86\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">x64\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">x64\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">ia64\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">ia64\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\TestZlib$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\TestZlib$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</GenerateManifest>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>..\\..\\masmx86\\match686.obj;..\\..\\masmx86\\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>..\\..\\masmx86\\match686.obj;..\\..\\masmx86\\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>..\\..\\masmx64\\gvmat64.obj;..\\..\\masmx64\\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">\n    <ClCompile>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>..\\..\\masmx64\\gvmat64.obj;..\\..\\masmx64\\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\adler32.c\" />\n    <ClCompile Include=\"..\\..\\..\\compress.c\" />\n    <ClCompile Include=\"..\\..\\..\\crc32.c\" />\n    <ClCompile Include=\"..\\..\\..\\deflate.c\" />\n    <ClCompile Include=\"..\\..\\..\\infback.c\" />\n    <ClCompile Include=\"..\\..\\masmx64\\inffas8664.c\">\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</ExcludedFromBuild>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inffast.c\" />\n    <ClCompile Include=\"..\\..\\..\\inflate.c\" />\n    <ClCompile Include=\"..\\..\\..\\inftrees.c\" />\n    <ClCompile Include=\"..\\..\\testzlib\\testzlib.c\" />\n    <ClCompile Include=\"..\\..\\..\\trees.c\" />\n    <ClCompile Include=\"..\\..\\..\\uncompr.c\" />\n    <ClCompile Include=\"..\\..\\..\\zutil.c\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc11/testzlibdll.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Itanium\">\n      <Configuration>Debug</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Itanium\">\n      <Configuration>Release</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694366A}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>MultiByte</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\TestZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\TestZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\TestZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\TestZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\TestZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\TestZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\TestZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\TestZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\TestZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\TestZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\TestZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\TestZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</GenerateManifest>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x86\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x86\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x64\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>ia64\\ZlibDllDebug\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>x64\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <OmitFramePointers>true</OmitFramePointers>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>ia64\\ZlibDllRelease\\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\testzlib\\testzlib.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"zlibvc.vcxproj\">\n      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc11/zlib.rc",
    "content": "#include <windows.h>\n\n#define IDR_VERSION1  1\nIDR_VERSION1\tVERSIONINFO\tMOVEABLE IMPURE LOADONCALL DISCARDABLE\n  FILEVERSION\t 1,2,8,0\n  PRODUCTVERSION 1,2,8,0\n  FILEFLAGSMASK\tVS_FFI_FILEFLAGSMASK\n  FILEFLAGS\t0\n  FILEOS\tVOS_DOS_WINDOWS32\n  FILETYPE\tVFT_DLL\n  FILESUBTYPE\t0\t// not used\nBEGIN\n  BLOCK \"StringFileInfo\"\n  BEGIN\n    BLOCK \"040904E4\"\n    //language ID = U.S. English, char set = Windows, Multilingual\n\n    BEGIN\n      VALUE \"FileDescription\", \"zlib data compression and ZIP file I/O library\\0\"\n      VALUE \"FileVersion\",\t\"1.2.8\\0\"\n      VALUE \"InternalName\",\t\"zlib\\0\"\n      VALUE \"OriginalFilename\",\t\"zlibwapi.dll\\0\"\n      VALUE \"ProductName\",\t\"ZLib.DLL\\0\"\n      VALUE \"Comments\",\"DLL support by Alessandro Iacopetti & Gilles Vollant\\0\"\n      VALUE \"LegalCopyright\", \"(C) 1995-2013 Jean-loup Gailly & Mark Adler\\0\"\n    END\n  END\n  BLOCK \"VarFileInfo\"\n  BEGIN\n    VALUE \"Translation\", 0x0409, 1252\n  END\nEND\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc11/zlibstat.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Itanium\">\n      <Configuration>Debug</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|Itanium\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|Win32\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|x64\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Itanium\">\n      <Configuration>Release</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <PlatformToolset>v110</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">x86\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">x86\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">x64\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">x64\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">ia64\\ZlibStat$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">ia64\\ZlibStat$(Configuration)\\Tmp\\</IntDir>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <DebugInformationFormat>OldStyle</DebugInformationFormat>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>..\\..\\masmx86\\match686.obj;..\\..\\masmx86\\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <DebugInformationFormat>OldStyle</DebugInformationFormat>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <DebugInformationFormat>OldStyle</DebugInformationFormat>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>..\\..\\masmx64\\gvmat64.obj;..\\..\\masmx64\\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">\n    <Midl>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Lib>\n      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\adler32.c\" />\n    <ClCompile Include=\"..\\..\\..\\compress.c\" />\n    <ClCompile Include=\"..\\..\\..\\crc32.c\" />\n    <ClCompile Include=\"..\\..\\..\\deflate.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzclose.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzlib.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzread.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzwrite.c\" />\n    <ClCompile Include=\"..\\..\\..\\infback.c\" />\n    <ClCompile Include=\"..\\..\\masmx64\\inffas8664.c\">\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</ExcludedFromBuild>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inffast.c\" />\n    <ClCompile Include=\"..\\..\\..\\inflate.c\" />\n    <ClCompile Include=\"..\\..\\..\\inftrees.c\" />\n    <ClCompile Include=\"..\\..\\minizip\\ioapi.c\" />\n    <ClCompile Include=\"..\\..\\..\\trees.c\" />\n    <ClCompile Include=\"..\\..\\..\\uncompr.c\" />\n    <ClCompile Include=\"..\\..\\minizip\\unzip.c\" />\n    <ClCompile Include=\"..\\..\\minizip\\zip.c\" />\n    <ClCompile Include=\"..\\..\\..\\zutil.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"zlib.rc\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"zlibvc.def\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc11/zlibvc.def",
    "content": "LIBRARY\n; zlib data compression and ZIP file I/O library\n\nVERSION\t\t1.2.8\n\nEXPORTS\n        adler32                                  @1\n        compress                                 @2\n        crc32                                    @3\n        deflate                                  @4\n        deflateCopy                              @5\n        deflateEnd                               @6\n        deflateInit2_                            @7\n        deflateInit_                             @8\n        deflateParams                            @9\n        deflateReset                             @10\n        deflateSetDictionary                     @11\n        gzclose                                  @12\n        gzdopen                                  @13\n        gzerror                                  @14\n        gzflush                                  @15\n        gzopen                                   @16\n        gzread                                   @17\n        gzwrite                                  @18\n        inflate                                  @19\n        inflateEnd                               @20\n        inflateInit2_                            @21\n        inflateInit_                             @22\n        inflateReset                             @23\n        inflateSetDictionary                     @24\n        inflateSync                              @25\n        uncompress                               @26\n        zlibVersion                              @27\n        gzprintf                                 @28\n        gzputc                                   @29\n        gzgetc                                   @30\n        gzseek                                   @31\n        gzrewind                                 @32\n        gztell                                   @33\n        gzeof                                    @34\n        gzsetparams                              @35\n        zError                                   @36\n        inflateSyncPoint                         @37\n        get_crc_table                            @38\n        compress2                                @39\n        gzputs                                   @40\n        gzgets                                   @41\n        inflateCopy                              @42\n        inflateBackInit_                         @43\n        inflateBack                              @44\n        inflateBackEnd                           @45\n        compressBound                            @46\n        deflateBound                             @47\n        gzclearerr                               @48\n        gzungetc                                 @49\n        zlibCompileFlags                         @50\n        deflatePrime                             @51\n        deflatePending                           @52\n\n        unzOpen                                  @61\n        unzClose                                 @62\n        unzGetGlobalInfo                         @63\n        unzGetCurrentFileInfo                    @64\n        unzGoToFirstFile                         @65\n        unzGoToNextFile                          @66\n        unzOpenCurrentFile                       @67\n        unzReadCurrentFile                       @68\n        unzOpenCurrentFile3                      @69\n        unztell                                  @70\n        unzeof                                   @71\n        unzCloseCurrentFile                      @72\n        unzGetGlobalComment                      @73\n        unzStringFileNameCompare                 @74\n        unzLocateFile                            @75\n        unzGetLocalExtrafield                    @76\n        unzOpen2                                 @77\n        unzOpenCurrentFile2                      @78\n        unzOpenCurrentFilePassword               @79\n\n        zipOpen                                  @80\n        zipOpenNewFileInZip                      @81\n        zipWriteInFileInZip                      @82\n        zipCloseFileInZip                        @83\n        zipClose                                 @84\n        zipOpenNewFileInZip2                     @86\n        zipCloseFileInZipRaw                     @87\n        zipOpen2                                 @88\n        zipOpenNewFileInZip3                     @89\n\n        unzGetFilePos                            @100\n        unzGoToFilePos                           @101\n\n        fill_win32_filefunc                      @110\n\n; zlibwapi v1.2.4 added:\n        fill_win32_filefunc64                   @111\n        fill_win32_filefunc64A                  @112\n        fill_win32_filefunc64W                  @113\n\n        unzOpen64                               @120\n        unzOpen2_64                             @121\n        unzGetGlobalInfo64                      @122\n        unzGetCurrentFileInfo64                 @124\n        unzGetCurrentFileZStreamPos64           @125\n        unztell64                               @126\n        unzGetFilePos64                         @127\n        unzGoToFilePos64                        @128\n\n        zipOpen64                               @130\n        zipOpen2_64                             @131\n        zipOpenNewFileInZip64                   @132\n        zipOpenNewFileInZip2_64                 @133\n        zipOpenNewFileInZip3_64                 @134\n        zipOpenNewFileInZip4_64                 @135\n        zipCloseFileInZipRaw64                  @136\n\n; zlib1 v1.2.4 added:\n        adler32_combine                         @140\n        crc32_combine                           @142\n        deflateSetHeader                        @144\n        deflateTune                             @145\n        gzbuffer                                @146\n        gzclose_r                               @147\n        gzclose_w                               @148\n        gzdirect                                @149\n        gzoffset                                @150\n        inflateGetHeader                        @156\n        inflateMark                             @157\n        inflatePrime                            @158\n        inflateReset2                           @159\n        inflateUndermine                        @160\n\n; zlib1 v1.2.6 added:\n        gzgetc_                                 @161\n        inflateResetKeep                        @163\n        deflateResetKeep                        @164\n\n; zlib1 v1.2.7 added:\n        gzopen_w                                @165\n\n; zlib1 v1.2.8 added:\n        inflateGetDictionary                    @166\n        gzvprintf                               @167\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc11/zlibvc.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"zlibvc\", \"zlibvc.vcxproj\", \"{8FD826F8-3739-44E6-8CC8-997122E53B8D}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"zlibstat\", \"zlibstat.vcxproj\", \"{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"testzlib\", \"testzlib.vcxproj\", \"{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"testzlibdll\", \"testzlibdll.vcxproj\", \"{C52F9E7B-498A-42BE-8DB4-85A15694366A}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"minizip\", \"minizip.vcxproj\", \"{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"miniunz\", \"miniunz.vcxproj\", \"{C52F9E7B-498A-42BE-8DB4-85A15694382A}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Itanium = Debug|Itanium\n\t\tDebug|Win32 = Debug|Win32\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|Itanium = Release|Itanium\n\t\tRelease|Win32 = Release|Win32\n\t\tRelease|x64 = Release|x64\n\t\tReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium\n\t\tReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32\n\t\tReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc11/zlibvc.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Itanium\">\n      <Configuration>Debug</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|Itanium\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|Win32\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"ReleaseWithoutAsm|x64\">\n      <Configuration>ReleaseWithoutAsm</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Itanium\">\n      <Configuration>Release</Configuration>\n      <Platform>Itanium</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{8FD826F8-3739-44E6-8CC8-997122E53B8D}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <PlatformToolset>v110</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseOfMfc>false</UseOfMfc>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">x86\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">x86\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">x86\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">x86\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">x64\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">ia64\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">x64\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">x64\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">ia64\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">ia64\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">x64\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</GenerateManifest>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\ZlibDll$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ia64\\ZlibDll$(Configuration)\\Tmp\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</LinkIncremental>\n    <GenerateManifest Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">false</GenerateManifest>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">zlibwapi</TargetName>\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">zlibwapi</TargetName>\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">zlibwapi</TargetName>\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">zlibwapi</TargetName>\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">zlibwapi</TargetName>\n    <TargetName Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">zlibwapi</TargetName>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Midl>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>Win32</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>..\\..\\masmx86\\match686.obj;..\\..\\masmx86\\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\n      <SubSystem>Windows</SubSystem>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\n    </Link>\n    <PreBuildEvent>\n      <Command>cd ..\\..\\masmx86\nbld_ml32.bat</Command>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">\n    <Midl>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>Win32</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerOutput>All</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>\n      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\n      <SubSystem>Windows</SubSystem>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Midl>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>Win32</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerOutput>All</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>..\\..\\masmx86\\match686.obj;..\\..\\masmx86\\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\n      <SubSystem>Windows</SubSystem>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\n    </Link>\n    <PreBuildEvent>\n      <Command>cd ..\\..\\masmx86\nbld_ml32.bat</Command>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Midl>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>X64</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <AdditionalDependencies>..\\..\\masmx64\\gvmat64.obj;..\\..\\masmx64\\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\n      <SubSystem>Windows</SubSystem>\n      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n    <PreBuildEvent>\n      <Command>cd ..\\..\\contrib\\masmx64\nbld_ml64.bat</Command>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">\n    <Midl>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\n      <SubSystem>Windows</SubSystem>\n      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'\">\n    <Midl>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>X64</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerOutput>All</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\n      <SubSystem>Windows</SubSystem>\n      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">\n    <Midl>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerOutput>All</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\n      <SubSystem>Windows</SubSystem>\n      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Midl>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>X64</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerOutput>All</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <AdditionalDependencies>..\\..\\masmx64\\gvmat64.obj;..\\..\\masmx64\\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\n      <SubSystem>Windows</SubSystem>\n      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n    <PreBuildEvent>\n      <Command>cd ..\\..\\masmx64\nbld_ml64.bat</Command>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">\n    <Midl>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MkTypLibCompatible>true</MkTypLibCompatible>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <TargetEnvironment>Itanium</TargetEnvironment>\n      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\n    </Midl>\n    <ClCompile>\n      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\n      <AdditionalIncludeDirectories>..\\..\\..;..\\..\\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <StringPooling>true</StringPooling>\n      <ExceptionHandling>\n      </ExceptionHandling>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\n      <AssemblerOutput>All</AssemblerOutput>\n      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\n      <ObjectFileName>$(IntDir)</ObjectFileName>\n      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\n      <BrowseInformation>\n      </BrowseInformation>\n      <WarningLevel>Level3</WarningLevel>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n    </ClCompile>\n    <ResourceCompile>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <Culture>0x040c</Culture>\n    </ResourceCompile>\n    <Link>\n      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\n      <SuppressStartupBanner>true</SuppressStartupBanner>\n      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\n      <ModuleDefinitionFile>.\\zlibvc.def</ModuleDefinitionFile>\n      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\n      <GenerateMapFile>true</GenerateMapFile>\n      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\n      <SubSystem>Windows</SubSystem>\n      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\n      <TargetMachine>MachineIA64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\..\\..\\adler32.c\" />\n    <ClCompile Include=\"..\\..\\..\\compress.c\" />\n    <ClCompile Include=\"..\\..\\..\\crc32.c\" />\n    <ClCompile Include=\"..\\..\\..\\deflate.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzclose.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzlib.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzread.c\" />\n    <ClCompile Include=\"..\\..\\..\\gzwrite.c\" />\n    <ClCompile Include=\"..\\..\\..\\infback.c\" />\n    <ClCompile Include=\"..\\..\\masmx64\\inffas8664.c\">\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">true</ExcludedFromBuild>\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</ExcludedFromBuild>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\inffast.c\" />\n    <ClCompile Include=\"..\\..\\..\\inflate.c\" />\n    <ClCompile Include=\"..\\..\\..\\inftrees.c\" />\n    <ClCompile Include=\"..\\..\\minizip\\ioapi.c\" />\n    <ClCompile Include=\"..\\..\\minizip\\iowin32.c\" />\n    <ClCompile Include=\"..\\..\\..\\trees.c\" />\n    <ClCompile Include=\"..\\..\\..\\uncompr.c\" />\n    <ClCompile Include=\"..\\..\\minizip\\unzip.c\">\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\minizip\\zip.c\">\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|Itanium'\">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <ClCompile Include=\"..\\..\\..\\zutil.c\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"zlib.rc\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"zlibvc.def\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\..\\..\\deflate.h\" />\n    <ClInclude Include=\"..\\..\\..\\infblock.h\" />\n    <ClInclude Include=\"..\\..\\..\\infcodes.h\" />\n    <ClInclude Include=\"..\\..\\..\\inffast.h\" />\n    <ClInclude Include=\"..\\..\\..\\inftrees.h\" />\n    <ClInclude Include=\"..\\..\\..\\infutil.h\" />\n    <ClInclude Include=\"..\\..\\..\\zconf.h\" />\n    <ClInclude Include=\"..\\..\\..\\zlib.h\" />\n    <ClInclude Include=\"..\\..\\..\\zutil.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc9/miniunz.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n<VisualStudioProject\n\tProjectType=\"Visual C++\"\n\tVersion=\"9.00\"\n\tName=\"miniunz\"\n\tProjectGUID=\"{C52F9E7B-498A-42BE-8DB4-85A15694382A}\"\n\tKeyword=\"Win32Proj\"\n\tTargetFrameworkVersion=\"131072\"\n\t>\n\t<Platforms>\n\t\t<Platform\n\t\t\tName=\"Win32\"\n\t\t/>\n\t\t<Platform\n\t\t\tName=\"x64\"\n\t\t/>\n\t\t<Platform\n\t\t\tName=\"Itanium\"\n\t\t/>\n\t</Platforms>\n\t<ToolFiles>\n\t</ToolFiles>\n\t<Configurations>\n\t\t<Configuration\n\t\t\tName=\"Debug|Win32\"\n\t\t\tOutputDirectory=\"x86\\MiniUnzip$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\MiniUnzip$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE\"\n\t\t\t\tMinimalRebuild=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"1\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"4\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"x86\\ZlibDllDebug\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/miniunz.exe\"\n\t\t\t\tLinkIncremental=\"2\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/miniunz.pdb\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tRandomizedBaseAddress=\"1\"\n\t\t\t\tDataExecutionPrevention=\"0\"\n\t\t\t\tTargetMachine=\"1\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|Win32\"\n\t\t\tOutputDirectory=\"x86\\MiniUnzip$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\MiniUnzip$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"2\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tOmitFramePointers=\"true\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"0\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"x86\\ZlibDllRelease\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/miniunz.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tOptimizeReferences=\"2\"\n\t\t\t\tEnableCOMDATFolding=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tRandomizedBaseAddress=\"1\"\n\t\t\t\tDataExecutionPrevention=\"0\"\n\t\t\t\tTargetMachine=\"1\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Debug|x64\"\n\t\t\tOutputDirectory=\"x64\\MiniUnzip$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\MiniUnzip$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64\"\n\t\t\t\tMinimalRebuild=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"x64\\ZlibDllDebug\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/miniunz.exe\"\n\t\t\t\tLinkIncremental=\"2\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/miniunz.pdb\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tTargetMachine=\"17\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Debug|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\MiniUnzip$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\MiniUnzip$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64\"\n\t\t\t\tMinimalRebuild=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"ia64\\ZlibDllDebug\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/miniunz.exe\"\n\t\t\t\tLinkIncremental=\"2\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/miniunz.pdb\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tTargetMachine=\"5\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|x64\"\n\t\t\tOutputDirectory=\"x64\\MiniUnzip$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\MiniUnzip$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"2\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tOmitFramePointers=\"true\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"x64\\ZlibDllRelease\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/miniunz.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tOptimizeReferences=\"2\"\n\t\t\t\tEnableCOMDATFolding=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tTargetMachine=\"17\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\MiniUnzip$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\MiniUnzip$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"2\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tOmitFramePointers=\"true\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"ia64\\ZlibDllRelease\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/miniunz.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tOptimizeReferences=\"2\"\n\t\t\t\tEnableCOMDATFolding=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tTargetMachine=\"5\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t</Configurations>\n\t<References>\n\t</References>\n\t<Files>\n\t\t<Filter\n\t\t\tName=\"Source Files\"\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm\"\n\t\t\t>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\minizip\\miniunz.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Header Files\"\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc\"\n\t\t\t>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Resource Files\"\n\t\t\tFilter=\"rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\"\n\t\t\t>\n\t\t</Filter>\n\t</Files>\n\t<Globals>\n\t</Globals>\n</VisualStudioProject>\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc9/minizip.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n<VisualStudioProject\n\tProjectType=\"Visual C++\"\n\tVersion=\"9.00\"\n\tName=\"minizip\"\n\tProjectGUID=\"{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}\"\n\tKeyword=\"Win32Proj\"\n\tTargetFrameworkVersion=\"131072\"\n\t>\n\t<Platforms>\n\t\t<Platform\n\t\t\tName=\"Win32\"\n\t\t/>\n\t\t<Platform\n\t\t\tName=\"x64\"\n\t\t/>\n\t\t<Platform\n\t\t\tName=\"Itanium\"\n\t\t/>\n\t</Platforms>\n\t<ToolFiles>\n\t</ToolFiles>\n\t<Configurations>\n\t\t<Configuration\n\t\t\tName=\"Debug|Win32\"\n\t\t\tOutputDirectory=\"x86\\MiniZip$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\MiniZip$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE\"\n\t\t\t\tMinimalRebuild=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"1\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"4\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"x86\\ZlibDllDebug\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/minizip.exe\"\n\t\t\t\tLinkIncremental=\"2\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/minizip.pdb\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tRandomizedBaseAddress=\"1\"\n\t\t\t\tDataExecutionPrevention=\"0\"\n\t\t\t\tTargetMachine=\"1\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|Win32\"\n\t\t\tOutputDirectory=\"x86\\MiniZip$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\MiniZip$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"2\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tOmitFramePointers=\"true\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"0\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"x86\\ZlibDllRelease\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/minizip.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tOptimizeReferences=\"2\"\n\t\t\t\tEnableCOMDATFolding=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tRandomizedBaseAddress=\"1\"\n\t\t\t\tDataExecutionPrevention=\"0\"\n\t\t\t\tTargetMachine=\"1\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Debug|x64\"\n\t\t\tOutputDirectory=\"x64\\$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\$(ConfigurationName)\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64\"\n\t\t\t\tMinimalRebuild=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"x64\\ZlibDllDebug\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/minizip.exe\"\n\t\t\t\tLinkIncremental=\"2\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/minizip.pdb\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tTargetMachine=\"17\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Debug|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\$(ConfigurationName)\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64\"\n\t\t\t\tMinimalRebuild=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"ia64\\ZlibDllDebug\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/minizip.exe\"\n\t\t\t\tLinkIncremental=\"2\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/minizip.pdb\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tTargetMachine=\"5\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|x64\"\n\t\t\tOutputDirectory=\"x64\\$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\$(ConfigurationName)\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"2\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tOmitFramePointers=\"true\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"x64\\ZlibDllRelease\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/minizip.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tOptimizeReferences=\"2\"\n\t\t\t\tEnableCOMDATFolding=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tTargetMachine=\"17\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\$(ConfigurationName)\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"2\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tOmitFramePointers=\"true\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"ia64\\ZlibDllRelease\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/minizip.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tOptimizeReferences=\"2\"\n\t\t\t\tEnableCOMDATFolding=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tTargetMachine=\"5\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t</Configurations>\n\t<References>\n\t</References>\n\t<Files>\n\t\t<Filter\n\t\t\tName=\"Source Files\"\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm\"\n\t\t\t>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\minizip\\minizip.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Header Files\"\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc\"\n\t\t\t>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Resource Files\"\n\t\t\tFilter=\"rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\"\n\t\t\t>\n\t\t</Filter>\n\t</Files>\n\t<Globals>\n\t</Globals>\n</VisualStudioProject>\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc9/testzlib.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n<VisualStudioProject\n\tProjectType=\"Visual C++\"\n\tVersion=\"9,00\"\n\tName=\"testzlib\"\n\tProjectGUID=\"{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}\"\n\tRootNamespace=\"testzlib\"\n\tKeyword=\"Win32Proj\"\n\tTargetFrameworkVersion=\"131072\"\n\t>\n\t<Platforms>\n\t\t<Platform\n\t\t\tName=\"Win32\"\n\t\t/>\n\t\t<Platform\n\t\t\tName=\"x64\"\n\t\t/>\n\t\t<Platform\n\t\t\tName=\"Itanium\"\n\t\t/>\n\t</Platforms>\n\t<ToolFiles>\n\t</ToolFiles>\n\t<Configurations>\n\t\t<Configuration\n\t\t\tName=\"Debug|Win32\"\n\t\t\tOutputDirectory=\"x86\\TestZlib$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\TestZlib$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..\"\n\t\t\t\tPreprocessorDefinitions=\"ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS\"\n\t\t\t\tMinimalRebuild=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"1\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerOutput=\"4\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"4\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"..\\..\\masmx86\\match686.obj ..\\..\\masmx86\\inffas32.obj\"\n\t\t\t\tOutputFile=\"$(OutDir)/testzlib.exe\"\n\t\t\t\tLinkIncremental=\"2\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/testzlib.pdb\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tRandomizedBaseAddress=\"1\"\n\t\t\t\tDataExecutionPrevention=\"0\"\n\t\t\t\tTargetMachine=\"1\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Debug|x64\"\n\t\t\tOutputDirectory=\"x64\\TestZlib$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\TestZlib$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..\"\n\t\t\t\tPreprocessorDefinitions=\"ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"..\\..\\masmx64\\gvmat64.obj ..\\..\\masmx64\\inffasx64.obj\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Debug|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\TestZlib$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\TestZlib$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..\"\n\t\t\t\tPreprocessorDefinitions=\"ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64\"\n\t\t\t\tMinimalRebuild=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerOutput=\"4\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)/testzlib.exe\"\n\t\t\t\tLinkIncremental=\"2\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/testzlib.pdb\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tTargetMachine=\"5\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"ReleaseWithoutAsm|Win32\"\n\t\t\tOutputDirectory=\"x86\\TestZlib$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\TestZlib$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tCharacterSet=\"2\"\n\t\t\tWholeProgramOptimization=\"1\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"2\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tOmitFramePointers=\"true\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"0\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)/testzlib.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tOptimizeReferences=\"2\"\n\t\t\t\tEnableCOMDATFolding=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tRandomizedBaseAddress=\"1\"\n\t\t\t\tDataExecutionPrevention=\"0\"\n\t\t\t\tTargetMachine=\"1\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"ReleaseWithoutAsm|x64\"\n\t\t\tOutputDirectory=\"x64\\TestZlib$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\TestZlib$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tWholeProgramOptimization=\"1\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"ReleaseWithoutAsm|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\TestZlib$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\TestZlib$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tCharacterSet=\"2\"\n\t\t\tWholeProgramOptimization=\"1\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"2\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tOmitFramePointers=\"true\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..\"\n\t\t\t\tPreprocessorDefinitions=\"ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)/testzlib.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tOptimizeReferences=\"2\"\n\t\t\t\tEnableCOMDATFolding=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tTargetMachine=\"5\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|Win32\"\n\t\t\tOutputDirectory=\"x86\\TestZlib$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\TestZlib$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tCharacterSet=\"2\"\n\t\t\tWholeProgramOptimization=\"1\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"2\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tOmitFramePointers=\"true\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..\"\n\t\t\t\tPreprocessorDefinitions=\"ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"0\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"..\\..\\masmx86\\match686.obj ..\\..\\masmx86\\inffas32.obj\"\n\t\t\t\tOutputFile=\"$(OutDir)/testzlib.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tOptimizeReferences=\"2\"\n\t\t\t\tEnableCOMDATFolding=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tRandomizedBaseAddress=\"1\"\n\t\t\t\tDataExecutionPrevention=\"0\"\n\t\t\t\tTargetMachine=\"1\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|x64\"\n\t\t\tOutputDirectory=\"x64\\TestZlib$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\TestZlib$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tWholeProgramOptimization=\"1\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..\"\n\t\t\t\tPreprocessorDefinitions=\"ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"0\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"..\\..\\masmx64\\gvmat64.obj ..\\..\\masmx64\\inffasx64.obj\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\TestZlib$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\TestZlib$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tCharacterSet=\"2\"\n\t\t\tWholeProgramOptimization=\"1\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"2\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tOmitFramePointers=\"true\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..\"\n\t\t\t\tPreprocessorDefinitions=\"ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)/testzlib.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tOptimizeReferences=\"2\"\n\t\t\t\tEnableCOMDATFolding=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tTargetMachine=\"5\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t</Configurations>\n\t<References>\n\t</References>\n\t<Files>\n\t\t<Filter\n\t\t\tName=\"Source Files\"\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm\"\n\t\t\t>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\adler32.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\compress.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\crc32.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\deflate.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\infback.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\masmx64\\inffas8664.c\"\n\t\t\t\t>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Debug|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Debug|Itanium\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"ReleaseWithoutAsm|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"ReleaseWithoutAsm|Itanium\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Release|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Release|Itanium\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\inffast.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\inflate.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\inftrees.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\testzlib\\testzlib.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\trees.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\uncompr.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zutil.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Header Files\"\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc\"\n\t\t\t>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Resource Files\"\n\t\t\tFilter=\"rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\"\n\t\t\t>\n\t\t</Filter>\n\t</Files>\n\t<Globals>\n\t</Globals>\n</VisualStudioProject>\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc9/testzlibdll.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n<VisualStudioProject\n\tProjectType=\"Visual C++\"\n\tVersion=\"9.00\"\n\tName=\"TestZlibDll\"\n\tProjectGUID=\"{C52F9E7B-498A-42BE-8DB4-85A15694366A}\"\n\tKeyword=\"Win32Proj\"\n\tTargetFrameworkVersion=\"131072\"\n\t>\n\t<Platforms>\n\t\t<Platform\n\t\t\tName=\"Win32\"\n\t\t/>\n\t\t<Platform\n\t\t\tName=\"x64\"\n\t\t/>\n\t\t<Platform\n\t\t\tName=\"Itanium\"\n\t\t/>\n\t</Platforms>\n\t<ToolFiles>\n\t</ToolFiles>\n\t<Configurations>\n\t\t<Configuration\n\t\t\tName=\"Debug|Win32\"\n\t\t\tOutputDirectory=\"x86\\TestZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\TestZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE\"\n\t\t\t\tMinimalRebuild=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"1\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"4\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"x86\\ZlibDllDebug\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/testzlib.exe\"\n\t\t\t\tLinkIncremental=\"2\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/testzlib.pdb\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tRandomizedBaseAddress=\"1\"\n\t\t\t\tDataExecutionPrevention=\"0\"\n\t\t\t\tTargetMachine=\"1\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|Win32\"\n\t\t\tOutputDirectory=\"x86\\TestZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\TestZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"2\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tOmitFramePointers=\"true\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"0\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"x86\\ZlibDllRelease\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/testzlib.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tOptimizeReferences=\"2\"\n\t\t\t\tEnableCOMDATFolding=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tRandomizedBaseAddress=\"1\"\n\t\t\t\tDataExecutionPrevention=\"0\"\n\t\t\t\tTargetMachine=\"1\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Debug|x64\"\n\t\t\tOutputDirectory=\"x64\\TestZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\TestZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64\"\n\t\t\t\tMinimalRebuild=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"x64\\ZlibDllDebug\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/testzlib.exe\"\n\t\t\t\tLinkIncremental=\"2\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/testzlib.pdb\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tTargetMachine=\"17\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Debug|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\TestZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\TestZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64\"\n\t\t\t\tMinimalRebuild=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"ia64\\ZlibDllDebug\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/testzlib.exe\"\n\t\t\t\tLinkIncremental=\"2\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/testzlib.pdb\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tTargetMachine=\"5\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|x64\"\n\t\t\tOutputDirectory=\"x64\\TestZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\TestZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"2\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tOmitFramePointers=\"true\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"x64\\ZlibDllRelease\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/testzlib.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tOptimizeReferences=\"2\"\n\t\t\t\tEnableCOMDATFolding=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tTargetMachine=\"17\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\TestZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\TestZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"1\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tCharacterSet=\"2\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"2\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tOmitFramePointers=\"true\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\minizip\"\n\t\t\t\tPreprocessorDefinitions=\"_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tBasicRuntimeChecks=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tUsePrecompiledHeader=\"0\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"ia64\\ZlibDllRelease\\zlibwapi.lib\"\n\t\t\t\tOutputFile=\"$(OutDir)/testzlib.exe\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tSubSystem=\"1\"\n\t\t\t\tOptimizeReferences=\"2\"\n\t\t\t\tEnableCOMDATFolding=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tTargetMachine=\"5\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebDeploymentTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t</Configurations>\n\t<References>\n\t</References>\n\t<Files>\n\t\t<Filter\n\t\t\tName=\"Source Files\"\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm\"\n\t\t\t>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\testzlib\\testzlib.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Header Files\"\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc\"\n\t\t\t>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Resource Files\"\n\t\t\tFilter=\"rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\"\n\t\t\t>\n\t\t</Filter>\n\t</Files>\n\t<Globals>\n\t</Globals>\n</VisualStudioProject>\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc9/zlib.rc",
    "content": "#include <windows.h>\n\n#define IDR_VERSION1  1\nIDR_VERSION1\tVERSIONINFO\tMOVEABLE IMPURE LOADONCALL DISCARDABLE\n  FILEVERSION\t 1,2,8,0\n  PRODUCTVERSION 1,2,8,0\n  FILEFLAGSMASK\tVS_FFI_FILEFLAGSMASK\n  FILEFLAGS\t0\n  FILEOS\tVOS_DOS_WINDOWS32\n  FILETYPE\tVFT_DLL\n  FILESUBTYPE\t0\t// not used\nBEGIN\n  BLOCK \"StringFileInfo\"\n  BEGIN\n    BLOCK \"040904E4\"\n    //language ID = U.S. English, char set = Windows, Multilingual\n\n    BEGIN\n      VALUE \"FileDescription\", \"zlib data compression and ZIP file I/O library\\0\"\n      VALUE \"FileVersion\",\t\"1.2.8\\0\"\n      VALUE \"InternalName\",\t\"zlib\\0\"\n      VALUE \"OriginalFilename\",\t\"zlibwapi.dll\\0\"\n      VALUE \"ProductName\",\t\"ZLib.DLL\\0\"\n      VALUE \"Comments\",\"DLL support by Alessandro Iacopetti & Gilles Vollant\\0\"\n      VALUE \"LegalCopyright\", \"(C) 1995-2013 Jean-loup Gailly & Mark Adler\\0\"\n    END\n  END\n  BLOCK \"VarFileInfo\"\n  BEGIN\n    VALUE \"Translation\", 0x0409, 1252\n  END\nEND\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc9/zlibstat.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n<VisualStudioProject\n\tProjectType=\"Visual C++\"\n\tVersion=\"9,00\"\n\tName=\"zlibstat\"\n\tProjectGUID=\"{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}\"\n\tTargetFrameworkVersion=\"131072\"\n\t>\n\t<Platforms>\n\t\t<Platform\n\t\t\tName=\"Win32\"\n\t\t/>\n\t\t<Platform\n\t\t\tName=\"x64\"\n\t\t/>\n\t\t<Platform\n\t\t\tName=\"Itanium\"\n\t\t/>\n\t</Platforms>\n\t<ToolFiles>\n\t</ToolFiles>\n\t<Configurations>\n\t\t<Configuration\n\t\t\tName=\"Debug|Win32\"\n\t\t\tOutputDirectory=\"x86\\ZlibStat$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\ZlibStat$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"4\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"1\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibstat.pch\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"1\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLibrarianTool\"\n\t\t\t\tAdditionalOptions=\"/MACHINE:X86 /NODEFAULTLIB\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibstat.lib\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Debug|x64\"\n\t\t\tOutputDirectory=\"x64\\ZlibStat$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\ZlibStat$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"4\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibstat.pch\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"1\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLibrarianTool\"\n\t\t\t\tAdditionalOptions=\"/MACHINE:AMD64 /NODEFAULTLIB\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibstat.lib\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Debug|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\ZlibStat$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\ZlibStat$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"4\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibstat.pch\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n\t\t\t\tDebugInformationFormat=\"1\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLibrarianTool\"\n\t\t\t\tAdditionalOptions=\"/MACHINE:IA64 /NODEFAULTLIB\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibstat.lib\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|Win32\"\n\t\t\tOutputDirectory=\"x86\\ZlibStat$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\ZlibStat$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"4\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"0\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibstat.pch\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLibrarianTool\"\n\t\t\t\tAdditionalOptions=\"/MACHINE:X86 /NODEFAULTLIB\"\n\t\t\t\tAdditionalDependencies=\"..\\..\\masmx86\\match686.obj ..\\..\\masmx86\\inffas32.obj \"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibstat.lib\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|x64\"\n\t\t\tOutputDirectory=\"x64\\ZlibStat$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\ZlibStat$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"4\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibstat.pch\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLibrarianTool\"\n\t\t\t\tAdditionalOptions=\"/MACHINE:AMD64 /NODEFAULTLIB\"\n\t\t\t\tAdditionalDependencies=\"..\\..\\masmx64\\gvmat64.obj ..\\..\\masmx64\\inffasx64.obj \"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibstat.lib\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\ZlibStat$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\ZlibStat$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"4\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibstat.pch\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLibrarianTool\"\n\t\t\t\tAdditionalOptions=\"/MACHINE:IA64 /NODEFAULTLIB\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibstat.lib\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"ReleaseWithoutAsm|Win32\"\n\t\t\tOutputDirectory=\"x86\\ZlibStat$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\ZlibStat$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"4\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"0\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibstat.pch\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLibrarianTool\"\n\t\t\t\tAdditionalOptions=\"/MACHINE:X86 /NODEFAULTLIB\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibstat.lib\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"ReleaseWithoutAsm|x64\"\n\t\t\tOutputDirectory=\"x64\\ZlibStat$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\ZlibStat$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"4\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibstat.pch\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLibrarianTool\"\n\t\t\t\tAdditionalOptions=\"/MACHINE:AMD64 /NODEFAULTLIB\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibstat.lib\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"ReleaseWithoutAsm|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\ZlibStat$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\ZlibStat$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"4\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibstat.pch\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLibrarianTool\"\n\t\t\t\tAdditionalOptions=\"/MACHINE:IA64 /NODEFAULTLIB\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibstat.lib\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t</Configurations>\n\t<References>\n\t</References>\n\t<Files>\n\t\t<Filter\n\t\t\tName=\"Source Files\"\n\t\t\t>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\adler32.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\compress.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\crc32.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\deflate.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\gzclose.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\gzguts.h\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\gzlib.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\gzread.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\gzwrite.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\infback.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\masmx64\\inffas8664.c\"\n\t\t\t\t>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Debug|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Debug|Itanium\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Release|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Release|Itanium\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"ReleaseWithoutAsm|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"ReleaseWithoutAsm|Itanium\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\inffast.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\inflate.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\inftrees.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\minizip\\ioapi.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\trees.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\uncompr.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\minizip\\unzip.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\minizip\\zip.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\".\\zlib.rc\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\".\\zlibvc.def\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zutil.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t</Filter>\n\t</Files>\n\t<Globals>\n\t</Globals>\n</VisualStudioProject>\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc9/zlibvc.def",
    "content": "LIBRARY\n; zlib data compression and ZIP file I/O library\n\nVERSION\t\t1.2.8\n\nEXPORTS\n        adler32                                  @1\n        compress                                 @2\n        crc32                                    @3\n        deflate                                  @4\n        deflateCopy                              @5\n        deflateEnd                               @6\n        deflateInit2_                            @7\n        deflateInit_                             @8\n        deflateParams                            @9\n        deflateReset                             @10\n        deflateSetDictionary                     @11\n        gzclose                                  @12\n        gzdopen                                  @13\n        gzerror                                  @14\n        gzflush                                  @15\n        gzopen                                   @16\n        gzread                                   @17\n        gzwrite                                  @18\n        inflate                                  @19\n        inflateEnd                               @20\n        inflateInit2_                            @21\n        inflateInit_                             @22\n        inflateReset                             @23\n        inflateSetDictionary                     @24\n        inflateSync                              @25\n        uncompress                               @26\n        zlibVersion                              @27\n        gzprintf                                 @28\n        gzputc                                   @29\n        gzgetc                                   @30\n        gzseek                                   @31\n        gzrewind                                 @32\n        gztell                                   @33\n        gzeof                                    @34\n        gzsetparams                              @35\n        zError                                   @36\n        inflateSyncPoint                         @37\n        get_crc_table                            @38\n        compress2                                @39\n        gzputs                                   @40\n        gzgets                                   @41\n        inflateCopy                              @42\n        inflateBackInit_                         @43\n        inflateBack                              @44\n        inflateBackEnd                           @45\n        compressBound                            @46\n        deflateBound                             @47\n        gzclearerr                               @48\n        gzungetc                                 @49\n        zlibCompileFlags                         @50\n        deflatePrime                             @51\n        deflatePending                           @52\n\n        unzOpen                                  @61\n        unzClose                                 @62\n        unzGetGlobalInfo                         @63\n        unzGetCurrentFileInfo                    @64\n        unzGoToFirstFile                         @65\n        unzGoToNextFile                          @66\n        unzOpenCurrentFile                       @67\n        unzReadCurrentFile                       @68\n        unzOpenCurrentFile3                      @69\n        unztell                                  @70\n        unzeof                                   @71\n        unzCloseCurrentFile                      @72\n        unzGetGlobalComment                      @73\n        unzStringFileNameCompare                 @74\n        unzLocateFile                            @75\n        unzGetLocalExtrafield                    @76\n        unzOpen2                                 @77\n        unzOpenCurrentFile2                      @78\n        unzOpenCurrentFilePassword               @79\n\n        zipOpen                                  @80\n        zipOpenNewFileInZip                      @81\n        zipWriteInFileInZip                      @82\n        zipCloseFileInZip                        @83\n        zipClose                                 @84\n        zipOpenNewFileInZip2                     @86\n        zipCloseFileInZipRaw                     @87\n        zipOpen2                                 @88\n        zipOpenNewFileInZip3                     @89\n\n        unzGetFilePos                            @100\n        unzGoToFilePos                           @101\n\n        fill_win32_filefunc                      @110\n\n; zlibwapi v1.2.4 added:\n        fill_win32_filefunc64                   @111\n        fill_win32_filefunc64A                  @112\n        fill_win32_filefunc64W                  @113\n\n        unzOpen64                               @120\n        unzOpen2_64                             @121\n        unzGetGlobalInfo64                      @122\n        unzGetCurrentFileInfo64                 @124\n        unzGetCurrentFileZStreamPos64           @125\n        unztell64                               @126\n        unzGetFilePos64                         @127\n        unzGoToFilePos64                        @128\n\n        zipOpen64                               @130\n        zipOpen2_64                             @131\n        zipOpenNewFileInZip64                   @132\n        zipOpenNewFileInZip2_64                 @133\n        zipOpenNewFileInZip3_64                 @134\n        zipOpenNewFileInZip4_64                 @135\n        zipCloseFileInZipRaw64                  @136\n\n; zlib1 v1.2.4 added:\n        adler32_combine                         @140\n        crc32_combine                           @142\n        deflateSetHeader                        @144\n        deflateTune                             @145\n        gzbuffer                                @146\n        gzclose_r                               @147\n        gzclose_w                               @148\n        gzdirect                                @149\n        gzoffset                                @150\n        inflateGetHeader                        @156\n        inflateMark                             @157\n        inflatePrime                            @158\n        inflateReset2                           @159\n        inflateUndermine                        @160\n\n; zlib1 v1.2.6 added:\n        gzgetc_                                 @161\n        inflateResetKeep                        @163\n        deflateResetKeep                        @164\n\n; zlib1 v1.2.7 added:\n        gzopen_w                                @165\n\n; zlib1 v1.2.8 added:\n        inflateGetDictionary                    @166\n        gzvprintf                               @167\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc9/zlibvc.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 10.00\n# Visual Studio 2008\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"zlibvc\", \"zlibvc.vcproj\", \"{8FD826F8-3739-44E6-8CC8-997122E53B8D}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"zlibstat\", \"zlibstat.vcproj\", \"{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"testzlib\", \"testzlib.vcproj\", \"{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"TestZlibDll\", \"testzlibdll.vcproj\", \"{C52F9E7B-498A-42BE-8DB4-85A15694366A}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"minizip\", \"minizip.vcproj\", \"{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"miniunz\", \"miniunz.vcproj\", \"{C52F9E7B-498A-42BE-8DB4-85A15694382A}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}\n\tEndProjectSection\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Itanium = Debug|Itanium\n\t\tDebug|Win32 = Debug|Win32\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|Itanium = Release|Itanium\n\t\tRelease|Win32 = Release|Win32\n\t\tRelease|x64 = Release|x64\n\t\tReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium\n\t\tReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32\n\t\tReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\n\t\t{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\n\t\t{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\n\t\t{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\n\t\t{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\n\t\t{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/contrib/vstudio/vc9/zlibvc.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n<VisualStudioProject\n\tProjectType=\"Visual C++\"\n\tVersion=\"9,00\"\n\tName=\"zlibvc\"\n\tProjectGUID=\"{8FD826F8-3739-44E6-8CC8-997122E53B8D}\"\n\tRootNamespace=\"zlibvc\"\n\tTargetFrameworkVersion=\"131072\"\n\t>\n\t<Platforms>\n\t\t<Platform\n\t\t\tName=\"Win32\"\n\t\t/>\n\t\t<Platform\n\t\t\tName=\"x64\"\n\t\t/>\n\t\t<Platform\n\t\t\tName=\"Itanium\"\n\t\t/>\n\t</Platforms>\n\t<ToolFiles>\n\t</ToolFiles>\n\t<Configurations>\n\t\t<Configuration\n\t\t\tName=\"Debug|Win32\"\n\t\t\tOutputDirectory=\"x86\\ZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\ZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"2\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tPreprocessorDefinitions=\"_DEBUG\"\n\t\t\t\tMkTypLibCompatible=\"true\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tTargetEnvironment=\"1\"\n\t\t\t\tTypeLibraryName=\"$(OutDir)/zlibvc.tlb\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"1\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibvc.pch\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tBrowseInformation=\"0\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tDebugInformationFormat=\"4\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tPreprocessorDefinitions=\"_DEBUG\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalOptions=\"/MACHINE:I386\"\n\t\t\t\tAdditionalDependencies=\"..\\..\\masmx86\\match686.obj ..\\..\\masmx86\\inffas32.obj\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibwapi.dll\"\n\t\t\t\tLinkIncremental=\"2\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tModuleDefinitionFile=\".\\zlibvc.def\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/zlibwapi.pdb\"\n\t\t\t\tGenerateMapFile=\"true\"\n\t\t\t\tMapFileName=\"$(OutDir)/zlibwapi.map\"\n\t\t\t\tSubSystem=\"2\"\n\t\t\t\tRandomizedBaseAddress=\"1\"\n\t\t\t\tDataExecutionPrevention=\"0\"\n\t\t\t\tImportLibrary=\"$(OutDir)/zlibwapi.lib\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Debug|x64\"\n\t\t\tOutputDirectory=\"x64\\ZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\ZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"2\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tPreprocessorDefinitions=\"_DEBUG\"\n\t\t\t\tMkTypLibCompatible=\"true\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tTargetEnvironment=\"3\"\n\t\t\t\tTypeLibraryName=\"$(OutDir)/zlibvc.tlb\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibvc.pch\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tBrowseInformation=\"0\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tPreprocessorDefinitions=\"_DEBUG\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"..\\..\\masmx64\\gvmat64.obj ..\\..\\masmx64\\inffasx64.obj \"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibwapi.dll\"\n\t\t\t\tLinkIncremental=\"2\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tModuleDefinitionFile=\".\\zlibvc.def\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/zlibwapi.pdb\"\n\t\t\t\tGenerateMapFile=\"true\"\n\t\t\t\tMapFileName=\"$(OutDir)/zlibwapi.map\"\n\t\t\t\tSubSystem=\"2\"\n\t\t\t\tImportLibrary=\"$(OutDir)/zlibwapi.lib\"\n\t\t\t\tTargetMachine=\"17\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Debug|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\ZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\ZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"2\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tPreprocessorDefinitions=\"_DEBUG\"\n\t\t\t\tMkTypLibCompatible=\"true\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t\tTypeLibraryName=\"$(OutDir)/zlibvc.tlb\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tOptimization=\"0\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"3\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibvc.pch\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tBrowseInformation=\"0\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tDebugInformationFormat=\"3\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tPreprocessorDefinitions=\"_DEBUG\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibwapi.dll\"\n\t\t\t\tLinkIncremental=\"2\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tModuleDefinitionFile=\".\\zlibvc.def\"\n\t\t\t\tGenerateDebugInformation=\"true\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/zlibwapi.pdb\"\n\t\t\t\tGenerateMapFile=\"true\"\n\t\t\t\tMapFileName=\"$(OutDir)/zlibwapi.map\"\n\t\t\t\tSubSystem=\"2\"\n\t\t\t\tImportLibrary=\"$(OutDir)/zlibwapi.lib\"\n\t\t\t\tTargetMachine=\"5\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"ReleaseWithoutAsm|Win32\"\n\t\t\tOutputDirectory=\"x86\\ZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\ZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"2\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\tWholeProgramOptimization=\"1\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tMkTypLibCompatible=\"true\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tTargetEnvironment=\"1\"\n\t\t\t\tTypeLibraryName=\"$(OutDir)/zlibvc.tlb\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibvc.pch\"\n\t\t\t\tAssemblerOutput=\"2\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tBrowseInformation=\"0\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalOptions=\"/MACHINE:I386\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibwapi.dll\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tIgnoreAllDefaultLibraries=\"false\"\n\t\t\t\tModuleDefinitionFile=\".\\zlibvc.def\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/zlibwapi.pdb\"\n\t\t\t\tGenerateMapFile=\"true\"\n\t\t\t\tMapFileName=\"$(OutDir)/zlibwapi.map\"\n\t\t\t\tSubSystem=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tRandomizedBaseAddress=\"1\"\n\t\t\t\tDataExecutionPrevention=\"0\"\n\t\t\t\tImportLibrary=\"$(OutDir)/zlibwapi.lib\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"ReleaseWithoutAsm|x64\"\n\t\t\tOutputDirectory=\"x64\\ZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\ZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"2\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\tWholeProgramOptimization=\"1\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tMkTypLibCompatible=\"true\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tTargetEnvironment=\"3\"\n\t\t\t\tTypeLibraryName=\"$(OutDir)/zlibvc.tlb\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibvc.pch\"\n\t\t\t\tAssemblerOutput=\"2\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tBrowseInformation=\"0\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibwapi.dll\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tIgnoreAllDefaultLibraries=\"false\"\n\t\t\t\tModuleDefinitionFile=\".\\zlibvc.def\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/zlibwapi.pdb\"\n\t\t\t\tGenerateMapFile=\"true\"\n\t\t\t\tMapFileName=\"$(OutDir)/zlibwapi.map\"\n\t\t\t\tSubSystem=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tImportLibrary=\"$(OutDir)/zlibwapi.lib\"\n\t\t\t\tTargetMachine=\"17\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"ReleaseWithoutAsm|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\ZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\ZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"2\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\tWholeProgramOptimization=\"1\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tMkTypLibCompatible=\"true\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t\tTypeLibraryName=\"$(OutDir)/zlibvc.tlb\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibvc.pch\"\n\t\t\t\tAssemblerOutput=\"2\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tBrowseInformation=\"0\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibwapi.dll\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tIgnoreAllDefaultLibraries=\"false\"\n\t\t\t\tModuleDefinitionFile=\".\\zlibvc.def\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/zlibwapi.pdb\"\n\t\t\t\tGenerateMapFile=\"true\"\n\t\t\t\tMapFileName=\"$(OutDir)/zlibwapi.map\"\n\t\t\t\tSubSystem=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tImportLibrary=\"$(OutDir)/zlibwapi.lib\"\n\t\t\t\tTargetMachine=\"5\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|Win32\"\n\t\t\tOutputDirectory=\"x86\\ZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x86\\ZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"2\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\tWholeProgramOptimization=\"1\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tMkTypLibCompatible=\"true\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tTargetEnvironment=\"1\"\n\t\t\t\tTypeLibraryName=\"$(OutDir)/zlibvc.tlb\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"0\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibvc.pch\"\n\t\t\t\tAssemblerOutput=\"2\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tBrowseInformation=\"0\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalOptions=\"/MACHINE:I386\"\n\t\t\t\tAdditionalDependencies=\"..\\..\\masmx86\\match686.obj ..\\..\\masmx86\\inffas32.obj \"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibwapi.dll\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tIgnoreAllDefaultLibraries=\"false\"\n\t\t\t\tModuleDefinitionFile=\".\\zlibvc.def\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/zlibwapi.pdb\"\n\t\t\t\tGenerateMapFile=\"true\"\n\t\t\t\tMapFileName=\"$(OutDir)/zlibwapi.map\"\n\t\t\t\tSubSystem=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tRandomizedBaseAddress=\"1\"\n\t\t\t\tDataExecutionPrevention=\"0\"\n\t\t\t\tImportLibrary=\"$(OutDir)/zlibwapi.lib\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|x64\"\n\t\t\tOutputDirectory=\"x64\\ZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"x64\\ZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"2\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\tWholeProgramOptimization=\"1\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tMkTypLibCompatible=\"true\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tTargetEnvironment=\"3\"\n\t\t\t\tTypeLibraryName=\"$(OutDir)/zlibvc.tlb\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibvc.pch\"\n\t\t\t\tAssemblerOutput=\"2\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tBrowseInformation=\"0\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tAdditionalDependencies=\"..\\..\\masmx64\\gvmat64.obj ..\\..\\masmx64\\inffasx64.obj \"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibwapi.dll\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tIgnoreAllDefaultLibraries=\"false\"\n\t\t\t\tModuleDefinitionFile=\".\\zlibvc.def\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/zlibwapi.pdb\"\n\t\t\t\tGenerateMapFile=\"true\"\n\t\t\t\tMapFileName=\"$(OutDir)/zlibwapi.map\"\n\t\t\t\tSubSystem=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tImportLibrary=\"$(OutDir)/zlibwapi.lib\"\n\t\t\t\tTargetMachine=\"17\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t\t<Configuration\n\t\t\tName=\"Release|Itanium\"\n\t\t\tOutputDirectory=\"ia64\\ZlibDll$(ConfigurationName)\"\n\t\t\tIntermediateDirectory=\"ia64\\ZlibDll$(ConfigurationName)\\Tmp\"\n\t\t\tConfigurationType=\"2\"\n\t\t\tInheritedPropertySheets=\"UpgradeFromVC70.vsprops\"\n\t\t\tUseOfMFC=\"0\"\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n\t\t\tWholeProgramOptimization=\"1\"\n\t\t\t>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tMkTypLibCompatible=\"true\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tTargetEnvironment=\"2\"\n\t\t\t\tTypeLibraryName=\"$(OutDir)/zlibvc.tlb\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\tInlineFunctionExpansion=\"1\"\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\..;..\\..\\masmx86\"\n\t\t\t\tPreprocessorDefinitions=\"_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64\"\n\t\t\t\tStringPooling=\"true\"\n\t\t\t\tExceptionHandling=\"0\"\n\t\t\t\tRuntimeLibrary=\"2\"\n\t\t\t\tBufferSecurityCheck=\"false\"\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\n\t\t\t\tPrecompiledHeaderFile=\"$(IntDir)/zlibvc.pch\"\n\t\t\t\tAssemblerOutput=\"2\"\n\t\t\t\tAssemblerListingLocation=\"$(IntDir)\\\"\n\t\t\t\tObjectFile=\"$(IntDir)\\\"\n\t\t\t\tProgramDataBaseFileName=\"$(OutDir)\\\"\n\t\t\t\tBrowseInformation=\"0\"\n\t\t\t\tWarningLevel=\"3\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCResourceCompilerTool\"\n\t\t\t\tPreprocessorDefinitions=\"NDEBUG\"\n\t\t\t\tCulture=\"1036\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPreLinkEventTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCLinkerTool\"\n\t\t\t\tOutputFile=\"$(OutDir)\\zlibwapi.dll\"\n\t\t\t\tLinkIncremental=\"1\"\n\t\t\t\tSuppressStartupBanner=\"true\"\n\t\t\t\tGenerateManifest=\"false\"\n\t\t\t\tIgnoreAllDefaultLibraries=\"false\"\n\t\t\t\tModuleDefinitionFile=\".\\zlibvc.def\"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/zlibwapi.pdb\"\n\t\t\t\tGenerateMapFile=\"true\"\n\t\t\t\tMapFileName=\"$(OutDir)/zlibwapi.map\"\n\t\t\t\tSubSystem=\"2\"\n\t\t\t\tOptimizeForWindows98=\"1\"\n\t\t\t\tImportLibrary=\"$(OutDir)/zlibwapi.lib\"\n\t\t\t\tTargetMachine=\"5\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCALinkTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCXDCMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCBscMakeTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCFxCopTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCAppVerifierTool\"\n\t\t\t/>\n\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"\n\t\t\t/>\n\t\t</Configuration>\n\t</Configurations>\n\t<References>\n\t</References>\n\t<Files>\n\t\t<Filter\n\t\t\tName=\"Source Files\"\n\t\t\tFilter=\"cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90\"\n\t\t\t>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\adler32.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\compress.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\crc32.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\deflate.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\gzclose.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\gzguts.h\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\gzlib.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\gzread.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\gzwrite.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\infback.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\masmx64\\inffas8664.c\"\n\t\t\t\t>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Debug|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Debug|Itanium\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"ReleaseWithoutAsm|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"ReleaseWithoutAsm|Itanium\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Release|Win32\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Release|Itanium\"\n\t\t\t\t\tExcludedFromBuild=\"true\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\inffast.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\inflate.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\inftrees.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\minizip\\ioapi.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\minizip\\iowin32.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\trees.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\uncompr.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\minizip\\unzip.c\"\n\t\t\t\t>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Release|Win32\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"\"\n\t\t\t\t\t\tPreprocessorDefinitions=\"ZLIB_INTERNAL\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Release|x64\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"\"\n\t\t\t\t\t\tPreprocessorDefinitions=\"ZLIB_INTERNAL\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Release|Itanium\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"\"\n\t\t\t\t\t\tPreprocessorDefinitions=\"ZLIB_INTERNAL\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\minizip\\zip.c\"\n\t\t\t\t>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Release|Win32\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"\"\n\t\t\t\t\t\tPreprocessorDefinitions=\"ZLIB_INTERNAL\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Release|x64\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"\"\n\t\t\t\t\t\tPreprocessorDefinitions=\"ZLIB_INTERNAL\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t\t<FileConfiguration\n\t\t\t\t\tName=\"Release|Itanium\"\n\t\t\t\t\t>\n\t\t\t\t\t<Tool\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"\"\n\t\t\t\t\t\tPreprocessorDefinitions=\"ZLIB_INTERNAL\"\n\t\t\t\t\t/>\n\t\t\t\t</FileConfiguration>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\".\\zlib.rc\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\".\\zlibvc.def\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zutil.c\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Header Files\"\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;fi;fd\"\n\t\t\t>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\deflate.h\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\infblock.h\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\infcodes.h\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\inffast.h\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\inftrees.h\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\infutil.h\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zconf.h\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zlib.h\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t\t<File\n\t\t\t\tRelativePath=\"..\\..\\..\\zutil.h\"\n\t\t\t\t>\n\t\t\t</File>\n\t\t</Filter>\n\t\t<Filter\n\t\t\tName=\"Resource Files\"\n\t\t\tFilter=\"ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe\"\n\t\t\t>\n\t\t</Filter>\n\t</Files>\n\t<Globals>\n\t</Globals>\n</VisualStudioProject>\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/crc32.c",
    "content": "/* crc32.c -- compute the CRC-32 of a data stream\n * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n *\n * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster\n * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing\n * tables for updating the shift register in one step with three exclusive-ors\n * instead of four steps with four exclusive-ors.  This results in about a\n * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.\n */\n\n/* @(#) $Id$ */\n\n/*\n  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore\n  protection on the static variables used to control the first-use generation\n  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should\n  first call get_crc_table() to initialize the tables before allowing more than\n  one thread to use crc32().\n\n  DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.\n */\n\n#ifdef MAKECRCH\n#  include <stdio.h>\n#  ifndef DYNAMIC_CRC_TABLE\n#    define DYNAMIC_CRC_TABLE\n#  endif /* !DYNAMIC_CRC_TABLE */\n#endif /* MAKECRCH */\n\n#include \"zutil.h\"      /* for STDC and FAR definitions */\n\n#define local static\n\n/* Definitions for doing the crc four data bytes at a time. */\n#if !defined(NOBYFOUR) && defined(Z_U4)\n#  define BYFOUR\n#endif\n#ifdef BYFOUR\n   local unsigned long crc32_little OF((unsigned long,\n                        const unsigned char FAR *, unsigned));\n   local unsigned long crc32_big OF((unsigned long,\n                        const unsigned char FAR *, unsigned));\n#  define TBLS 8\n#else\n#  define TBLS 1\n#endif /* BYFOUR */\n\n/* Local functions for crc concatenation */\nlocal unsigned long gf2_matrix_times OF((unsigned long *mat,\n                                         unsigned long vec));\nlocal void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));\nlocal uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));\n\n\n#ifdef DYNAMIC_CRC_TABLE\n\nlocal volatile int crc_table_empty = 1;\nlocal z_crc_t FAR crc_table[TBLS][256];\nlocal void make_crc_table OF((void));\n#ifdef MAKECRCH\n   local void write_table OF((FILE *, const z_crc_t FAR *));\n#endif /* MAKECRCH */\n/*\n  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:\n  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.\n\n  Polynomials over GF(2) are represented in binary, one bit per coefficient,\n  with the lowest powers in the most significant bit.  Then adding polynomials\n  is just exclusive-or, and multiplying a polynomial by x is a right shift by\n  one.  If we call the above polynomial p, and represent a byte as the\n  polynomial q, also with the lowest power in the most significant bit (so the\n  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,\n  where a mod b means the remainder after dividing a by b.\n\n  This calculation is done using the shift-register method of multiplying and\n  taking the remainder.  The register is initialized to zero, and for each\n  incoming bit, x^32 is added mod p to the register if the bit is a one (where\n  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by\n  x (which is shifting right by one and adding x^32 mod p if the bit shifted\n  out is a one).  We start with the highest power (least significant bit) of\n  q and repeat for all eight bits of q.\n\n  The first table is simply the CRC of all possible eight bit values.  This is\n  all the information needed to generate CRCs on data a byte at a time for all\n  combinations of CRC register values and incoming bytes.  The remaining tables\n  allow for word-at-a-time CRC calculation for both big-endian and little-\n  endian machines, where a word is four bytes.\n*/\nlocal void make_crc_table()\n{\n    z_crc_t c;\n    int n, k;\n    z_crc_t poly;                       /* polynomial exclusive-or pattern */\n    /* terms of polynomial defining this crc (except x^32): */\n    static volatile int first = 1;      /* flag to limit concurrent making */\n    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};\n\n    /* See if another task is already doing this (not thread-safe, but better\n       than nothing -- significantly reduces duration of vulnerability in\n       case the advice about DYNAMIC_CRC_TABLE is ignored) */\n    if (first) {\n        first = 0;\n\n        /* make exclusive-or pattern from polynomial (0xedb88320UL) */\n        poly = 0;\n        for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)\n            poly |= (z_crc_t)1 << (31 - p[n]);\n\n        /* generate a crc for every 8-bit value */\n        for (n = 0; n < 256; n++) {\n            c = (z_crc_t)n;\n            for (k = 0; k < 8; k++)\n                c = c & 1 ? poly ^ (c >> 1) : c >> 1;\n            crc_table[0][n] = c;\n        }\n\n#ifdef BYFOUR\n        /* generate crc for each value followed by one, two, and three zeros,\n           and then the byte reversal of those as well as the first table */\n        for (n = 0; n < 256; n++) {\n            c = crc_table[0][n];\n            crc_table[4][n] = ZSWAP32(c);\n            for (k = 1; k < 4; k++) {\n                c = crc_table[0][c & 0xff] ^ (c >> 8);\n                crc_table[k][n] = c;\n                crc_table[k + 4][n] = ZSWAP32(c);\n            }\n        }\n#endif /* BYFOUR */\n\n        crc_table_empty = 0;\n    }\n    else {      /* not first */\n        /* wait for the other guy to finish (not efficient, but rare) */\n        while (crc_table_empty)\n            ;\n    }\n\n#ifdef MAKECRCH\n    /* write out CRC tables to crc32.h */\n    {\n        FILE *out;\n\n        out = fopen(\"crc32.h\", \"w\");\n        if (out == NULL) return;\n        fprintf(out, \"/* crc32.h -- tables for rapid CRC calculation\\n\");\n        fprintf(out, \" * Generated automatically by crc32.c\\n */\\n\\n\");\n        fprintf(out, \"local const z_crc_t FAR \");\n        fprintf(out, \"crc_table[TBLS][256] =\\n{\\n  {\\n\");\n        write_table(out, crc_table[0]);\n#  ifdef BYFOUR\n        fprintf(out, \"#ifdef BYFOUR\\n\");\n        for (k = 1; k < 8; k++) {\n            fprintf(out, \"  },\\n  {\\n\");\n            write_table(out, crc_table[k]);\n        }\n        fprintf(out, \"#endif\\n\");\n#  endif /* BYFOUR */\n        fprintf(out, \"  }\\n};\\n\");\n        fclose(out);\n    }\n#endif /* MAKECRCH */\n}\n\n#ifdef MAKECRCH\nlocal void write_table(out, table)\n    FILE *out;\n    const z_crc_t FAR *table;\n{\n    int n;\n\n    for (n = 0; n < 256; n++)\n        fprintf(out, \"%s0x%08lxUL%s\", n % 5 ? \"\" : \"    \",\n                (unsigned long)(table[n]),\n                n == 255 ? \"\\n\" : (n % 5 == 4 ? \",\\n\" : \", \"));\n}\n#endif /* MAKECRCH */\n\n#else /* !DYNAMIC_CRC_TABLE */\n/* ========================================================================\n * Tables of CRC-32s of all single-byte values, made by make_crc_table().\n */\n#include \"crc32.h\"\n#endif /* DYNAMIC_CRC_TABLE */\n\n/* =========================================================================\n * This function can be used by asm versions of crc32()\n */\nconst z_crc_t FAR * ZEXPORT get_crc_table()\n{\n#ifdef DYNAMIC_CRC_TABLE\n    if (crc_table_empty)\n        make_crc_table();\n#endif /* DYNAMIC_CRC_TABLE */\n    return (const z_crc_t FAR *)crc_table;\n}\n\n/* ========================================================================= */\n#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)\n#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1\n\n/* ========================================================================= */\nunsigned long ZEXPORT crc32(crc, buf, len)\n    unsigned long crc;\n    const unsigned char FAR *buf;\n    uInt len;\n{\n    if (buf == Z_NULL) return 0UL;\n\n#ifdef DYNAMIC_CRC_TABLE\n    if (crc_table_empty)\n        make_crc_table();\n#endif /* DYNAMIC_CRC_TABLE */\n\n#ifdef BYFOUR\n    if (sizeof(void *) == sizeof(ptrdiff_t)) {\n        z_crc_t endian;\n\n        endian = 1;\n        if (*((unsigned char *)(&endian)))\n            return crc32_little(crc, buf, len);\n        else\n            return crc32_big(crc, buf, len);\n    }\n#endif /* BYFOUR */\n    crc = crc ^ 0xffffffffUL;\n    while (len >= 8) {\n        DO8;\n        len -= 8;\n    }\n    if (len) do {\n        DO1;\n    } while (--len);\n    return crc ^ 0xffffffffUL;\n}\n\n#ifdef BYFOUR\n\n/* ========================================================================= */\n#define DOLIT4 c ^= *buf4++; \\\n        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \\\n            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]\n#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4\n\n/* ========================================================================= */\nlocal unsigned long crc32_little(crc, buf, len)\n    unsigned long crc;\n    const unsigned char FAR *buf;\n    unsigned len;\n{\n    register z_crc_t c;\n    register const z_crc_t FAR *buf4;\n\n    c = (z_crc_t)crc;\n    c = ~c;\n    while (len && ((ptrdiff_t)buf & 3)) {\n        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);\n        len--;\n    }\n\n    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;\n    while (len >= 32) {\n        DOLIT32;\n        len -= 32;\n    }\n    while (len >= 4) {\n        DOLIT4;\n        len -= 4;\n    }\n    buf = (const unsigned char FAR *)buf4;\n\n    if (len) do {\n        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);\n    } while (--len);\n    c = ~c;\n    return (unsigned long)c;\n}\n\n/* ========================================================================= */\n#define DOBIG4 c ^= *++buf4; \\\n        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \\\n            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]\n#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4\n\n/* ========================================================================= */\nlocal unsigned long crc32_big(crc, buf, len)\n    unsigned long crc;\n    const unsigned char FAR *buf;\n    unsigned len;\n{\n    register z_crc_t c;\n    register const z_crc_t FAR *buf4;\n\n    c = ZSWAP32((z_crc_t)crc);\n    c = ~c;\n    while (len && ((ptrdiff_t)buf & 3)) {\n        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);\n        len--;\n    }\n\n    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;\n    buf4--;\n    while (len >= 32) {\n        DOBIG32;\n        len -= 32;\n    }\n    while (len >= 4) {\n        DOBIG4;\n        len -= 4;\n    }\n    buf4++;\n    buf = (const unsigned char FAR *)buf4;\n\n    if (len) do {\n        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);\n    } while (--len);\n    c = ~c;\n    return (unsigned long)(ZSWAP32(c));\n}\n\n#endif /* BYFOUR */\n\n#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */\n\n/* ========================================================================= */\nlocal unsigned long gf2_matrix_times(mat, vec)\n    unsigned long *mat;\n    unsigned long vec;\n{\n    unsigned long sum;\n\n    sum = 0;\n    while (vec) {\n        if (vec & 1)\n            sum ^= *mat;\n        vec >>= 1;\n        mat++;\n    }\n    return sum;\n}\n\n/* ========================================================================= */\nlocal void gf2_matrix_square(square, mat)\n    unsigned long *square;\n    unsigned long *mat;\n{\n    int n;\n\n    for (n = 0; n < GF2_DIM; n++)\n        square[n] = gf2_matrix_times(mat, mat[n]);\n}\n\n/* ========================================================================= */\nlocal uLong crc32_combine_(crc1, crc2, len2)\n    uLong crc1;\n    uLong crc2;\n    z_off64_t len2;\n{\n    int n;\n    unsigned long row;\n    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */\n    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */\n\n    /* degenerate case (also disallow negative lengths) */\n    if (len2 <= 0)\n        return crc1;\n\n    /* put operator for one zero bit in odd */\n    odd[0] = 0xedb88320UL;          /* CRC-32 polynomial */\n    row = 1;\n    for (n = 1; n < GF2_DIM; n++) {\n        odd[n] = row;\n        row <<= 1;\n    }\n\n    /* put operator for two zero bits in even */\n    gf2_matrix_square(even, odd);\n\n    /* put operator for four zero bits in odd */\n    gf2_matrix_square(odd, even);\n\n    /* apply len2 zeros to crc1 (first square will put the operator for one\n       zero byte, eight zero bits, in even) */\n    do {\n        /* apply zeros operator for this bit of len2 */\n        gf2_matrix_square(even, odd);\n        if (len2 & 1)\n            crc1 = gf2_matrix_times(even, crc1);\n        len2 >>= 1;\n\n        /* if no more bits set, then done */\n        if (len2 == 0)\n            break;\n\n        /* another iteration of the loop with odd and even swapped */\n        gf2_matrix_square(odd, even);\n        if (len2 & 1)\n            crc1 = gf2_matrix_times(odd, crc1);\n        len2 >>= 1;\n\n        /* if no more bits set, then done */\n    } while (len2 != 0);\n\n    /* return combined crc */\n    crc1 ^= crc2;\n    return crc1;\n}\n\n/* ========================================================================= */\nuLong ZEXPORT crc32_combine(crc1, crc2, len2)\n    uLong crc1;\n    uLong crc2;\n    z_off_t len2;\n{\n    return crc32_combine_(crc1, crc2, len2);\n}\n\nuLong ZEXPORT crc32_combine64(crc1, crc2, len2)\n    uLong crc1;\n    uLong crc2;\n    z_off64_t len2;\n{\n    return crc32_combine_(crc1, crc2, len2);\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/crc32.h",
    "content": "/* crc32.h -- tables for rapid CRC calculation\n * Generated automatically by crc32.c\n */\n\nlocal const z_crc_t FAR crc_table[TBLS][256] =\n{\n  {\n    0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,\n    0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,\n    0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,\n    0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,\n    0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,\n    0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,\n    0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,\n    0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,\n    0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,\n    0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,\n    0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,\n    0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,\n    0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,\n    0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,\n    0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,\n    0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,\n    0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,\n    0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,\n    0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,\n    0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,\n    0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,\n    0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,\n    0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,\n    0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,\n    0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,\n    0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,\n    0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,\n    0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,\n    0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,\n    0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,\n    0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,\n    0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,\n    0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,\n    0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,\n    0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,\n    0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,\n    0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,\n    0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,\n    0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,\n    0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,\n    0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,\n    0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,\n    0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,\n    0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,\n    0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,\n    0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,\n    0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,\n    0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,\n    0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,\n    0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,\n    0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,\n    0x2d02ef8dUL\n#ifdef BYFOUR\n  },\n  {\n    0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,\n    0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,\n    0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,\n    0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,\n    0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,\n    0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,\n    0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,\n    0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,\n    0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,\n    0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,\n    0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,\n    0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,\n    0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,\n    0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,\n    0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,\n    0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,\n    0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,\n    0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,\n    0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,\n    0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,\n    0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,\n    0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,\n    0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,\n    0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,\n    0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,\n    0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,\n    0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,\n    0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,\n    0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,\n    0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,\n    0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,\n    0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,\n    0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,\n    0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,\n    0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,\n    0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,\n    0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,\n    0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,\n    0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,\n    0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,\n    0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,\n    0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,\n    0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,\n    0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,\n    0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,\n    0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,\n    0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,\n    0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,\n    0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,\n    0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,\n    0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,\n    0x9324fd72UL\n  },\n  {\n    0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,\n    0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,\n    0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,\n    0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,\n    0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,\n    0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,\n    0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,\n    0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,\n    0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,\n    0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,\n    0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,\n    0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,\n    0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,\n    0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,\n    0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,\n    0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,\n    0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,\n    0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,\n    0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,\n    0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,\n    0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,\n    0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,\n    0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,\n    0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,\n    0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,\n    0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,\n    0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,\n    0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,\n    0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,\n    0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,\n    0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,\n    0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,\n    0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,\n    0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,\n    0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,\n    0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,\n    0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,\n    0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,\n    0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,\n    0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,\n    0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,\n    0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,\n    0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,\n    0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,\n    0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,\n    0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,\n    0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,\n    0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,\n    0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,\n    0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,\n    0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,\n    0xbe9834edUL\n  },\n  {\n    0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,\n    0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,\n    0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,\n    0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,\n    0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,\n    0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,\n    0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,\n    0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,\n    0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,\n    0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,\n    0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,\n    0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,\n    0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,\n    0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,\n    0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,\n    0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,\n    0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,\n    0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,\n    0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,\n    0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,\n    0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,\n    0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,\n    0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,\n    0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,\n    0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,\n    0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,\n    0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,\n    0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,\n    0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,\n    0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,\n    0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,\n    0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,\n    0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,\n    0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,\n    0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,\n    0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,\n    0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,\n    0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,\n    0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,\n    0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,\n    0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,\n    0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,\n    0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,\n    0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,\n    0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,\n    0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,\n    0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,\n    0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,\n    0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,\n    0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,\n    0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,\n    0xde0506f1UL\n  },\n  {\n    0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,\n    0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,\n    0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,\n    0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,\n    0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,\n    0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,\n    0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,\n    0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,\n    0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,\n    0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,\n    0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,\n    0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,\n    0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,\n    0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,\n    0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,\n    0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,\n    0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,\n    0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,\n    0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,\n    0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,\n    0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,\n    0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,\n    0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,\n    0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,\n    0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,\n    0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,\n    0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,\n    0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,\n    0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,\n    0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,\n    0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,\n    0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,\n    0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,\n    0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,\n    0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,\n    0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,\n    0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,\n    0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,\n    0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,\n    0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,\n    0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,\n    0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,\n    0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,\n    0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,\n    0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,\n    0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,\n    0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,\n    0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,\n    0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,\n    0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,\n    0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,\n    0x8def022dUL\n  },\n  {\n    0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,\n    0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,\n    0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,\n    0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,\n    0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,\n    0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,\n    0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,\n    0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,\n    0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,\n    0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,\n    0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,\n    0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,\n    0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,\n    0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,\n    0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,\n    0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,\n    0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,\n    0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,\n    0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,\n    0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,\n    0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,\n    0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,\n    0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,\n    0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,\n    0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,\n    0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,\n    0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,\n    0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,\n    0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,\n    0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,\n    0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,\n    0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,\n    0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,\n    0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,\n    0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,\n    0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,\n    0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,\n    0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,\n    0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,\n    0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,\n    0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,\n    0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,\n    0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,\n    0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,\n    0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,\n    0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,\n    0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,\n    0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,\n    0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,\n    0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,\n    0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,\n    0x72fd2493UL\n  },\n  {\n    0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,\n    0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,\n    0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,\n    0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,\n    0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,\n    0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,\n    0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,\n    0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,\n    0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,\n    0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,\n    0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,\n    0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,\n    0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,\n    0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,\n    0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,\n    0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,\n    0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,\n    0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,\n    0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,\n    0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,\n    0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,\n    0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,\n    0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,\n    0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,\n    0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,\n    0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,\n    0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,\n    0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,\n    0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,\n    0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,\n    0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,\n    0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,\n    0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,\n    0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,\n    0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,\n    0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,\n    0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,\n    0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,\n    0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,\n    0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,\n    0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,\n    0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,\n    0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,\n    0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,\n    0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,\n    0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,\n    0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,\n    0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,\n    0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,\n    0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,\n    0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,\n    0xed3498beUL\n  },\n  {\n    0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,\n    0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,\n    0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,\n    0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,\n    0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,\n    0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,\n    0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,\n    0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,\n    0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,\n    0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,\n    0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,\n    0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,\n    0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,\n    0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,\n    0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,\n    0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,\n    0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,\n    0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,\n    0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,\n    0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,\n    0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,\n    0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,\n    0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,\n    0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,\n    0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,\n    0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,\n    0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,\n    0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,\n    0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,\n    0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,\n    0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,\n    0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,\n    0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,\n    0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,\n    0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,\n    0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,\n    0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,\n    0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,\n    0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,\n    0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,\n    0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,\n    0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,\n    0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,\n    0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,\n    0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,\n    0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,\n    0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,\n    0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,\n    0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,\n    0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,\n    0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,\n    0xf10605deUL\n#endif\n  }\n};\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/deflate.c",
    "content": "/* deflate.c -- compress data using the deflation algorithm\n * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/*\n *  ALGORITHM\n *\n *      The \"deflation\" process depends on being able to identify portions\n *      of the input text which are identical to earlier input (within a\n *      sliding window trailing behind the input currently being processed).\n *\n *      The most straightforward technique turns out to be the fastest for\n *      most input files: try all possible matches and select the longest.\n *      The key feature of this algorithm is that insertions into the string\n *      dictionary are very simple and thus fast, and deletions are avoided\n *      completely. Insertions are performed at each input character, whereas\n *      string matches are performed only when the previous match ends. So it\n *      is preferable to spend more time in matches to allow very fast string\n *      insertions and avoid deletions. The matching algorithm for small\n *      strings is inspired from that of Rabin & Karp. A brute force approach\n *      is used to find longer strings when a small match has been found.\n *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze\n *      (by Leonid Broukhis).\n *         A previous version of this file used a more sophisticated algorithm\n *      (by Fiala and Greene) which is guaranteed to run in linear amortized\n *      time, but has a larger average cost, uses more memory and is patented.\n *      However the F&G algorithm may be faster for some highly redundant\n *      files if the parameter max_chain_length (described below) is too large.\n *\n *  ACKNOWLEDGEMENTS\n *\n *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and\n *      I found it in 'freeze' written by Leonid Broukhis.\n *      Thanks to many people for bug reports and testing.\n *\n *  REFERENCES\n *\n *      Deutsch, L.P.,\"DEFLATE Compressed Data Format Specification\".\n *      Available in http://tools.ietf.org/html/rfc1951\n *\n *      A description of the Rabin and Karp algorithm is given in the book\n *         \"Algorithms\" by R. Sedgewick, Addison-Wesley, p252.\n *\n *      Fiala,E.R., and Greene,D.H.\n *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595\n *\n */\n\n/* @(#) $Id$ */\n\n#include \"deflate.h\"\n\nconst char deflate_copyright[] =\n   \" deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler \";\n/*\n  If you use the zlib library in a product, an acknowledgment is welcome\n  in the documentation of your product. If for some reason you cannot\n  include such an acknowledgment, I would appreciate that you keep this\n  copyright string in the executable of your product.\n */\n\n/* ===========================================================================\n *  Function prototypes.\n */\ntypedef enum {\n    need_more,      /* block not completed, need more input or more output */\n    block_done,     /* block flush performed */\n    finish_started, /* finish started, need only more output at next deflate */\n    finish_done     /* finish done, accept no more input or output */\n} block_state;\n\ntypedef block_state (*compress_func) OF((deflate_state *s, int flush));\n/* Compression function. Returns the block state after the call. */\n\nlocal void fill_window    OF((deflate_state *s));\nlocal block_state deflate_stored OF((deflate_state *s, int flush));\nlocal block_state deflate_fast   OF((deflate_state *s, int flush));\n#ifndef FASTEST\nlocal block_state deflate_slow   OF((deflate_state *s, int flush));\n#endif\nlocal block_state deflate_rle    OF((deflate_state *s, int flush));\nlocal block_state deflate_huff   OF((deflate_state *s, int flush));\nlocal void lm_init        OF((deflate_state *s));\nlocal void putShortMSB    OF((deflate_state *s, uInt b));\nlocal void flush_pending  OF((z_streamp strm));\nlocal int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));\n#ifdef ASMV\n      void match_init OF((void)); /* asm code initialization */\n      uInt longest_match  OF((deflate_state *s, IPos cur_match));\n#else\nlocal uInt longest_match  OF((deflate_state *s, IPos cur_match));\n#endif\n\n#ifdef DEBUG\nlocal  void check_match OF((deflate_state *s, IPos start, IPos match,\n                            int length));\n#endif\n\n/* ===========================================================================\n * Local data\n */\n\n#define NIL 0\n/* Tail of hash chains */\n\n#ifndef TOO_FAR\n#  define TOO_FAR 4096\n#endif\n/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */\n\n/* Values for max_lazy_match, good_match and max_chain_length, depending on\n * the desired pack level (0..9). The values given below have been tuned to\n * exclude worst case performance for pathological files. Better values may be\n * found for specific files.\n */\ntypedef struct config_s {\n   ush good_length; /* reduce lazy search above this match length */\n   ush max_lazy;    /* do not perform lazy search above this match length */\n   ush nice_length; /* quit search above this match length */\n   ush max_chain;\n   compress_func func;\n} config;\n\n#ifdef FASTEST\nlocal const config configuration_table[2] = {\n/*      good lazy nice chain */\n/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */\n/* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */\n#else\nlocal const config configuration_table[10] = {\n/*      good lazy nice chain */\n/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */\n/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */\n/* 2 */ {4,    5, 16,    8, deflate_fast},\n/* 3 */ {4,    6, 32,   32, deflate_fast},\n\n/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */\n/* 5 */ {8,   16, 32,   32, deflate_slow},\n/* 6 */ {8,   16, 128, 128, deflate_slow},\n/* 7 */ {8,   32, 128, 256, deflate_slow},\n/* 8 */ {32, 128, 258, 1024, deflate_slow},\n/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */\n#endif\n\n/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4\n * For deflate_fast() (levels <= 3) good is ignored and lazy has a different\n * meaning.\n */\n\n#define EQUAL 0\n/* result of memcmp for equal strings */\n\n#ifndef NO_DUMMY_DECL\nstruct static_tree_desc_s {int dummy;}; /* for buggy compilers */\n#endif\n\n/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */\n#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0))\n\n/* ===========================================================================\n * Update a hash value with the given input byte\n * IN  assertion: all calls to to UPDATE_HASH are made with consecutive\n *    input characters, so that a running hash key can be computed from the\n *    previous key instead of complete recalculation each time.\n */\n#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)\n\n\n/* ===========================================================================\n * Insert string str in the dictionary and set match_head to the previous head\n * of the hash chain (the most recent string with same hash key). Return\n * the previous length of the hash chain.\n * If this file is compiled with -DFASTEST, the compression level is forced\n * to 1, and no hash chains are maintained.\n * IN  assertion: all calls to to INSERT_STRING are made with consecutive\n *    input characters and the first MIN_MATCH bytes of str are valid\n *    (except for the last MIN_MATCH-1 bytes of the input file).\n */\n#ifdef FASTEST\n#define INSERT_STRING(s, str, match_head) \\\n   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \\\n    match_head = s->head[s->ins_h], \\\n    s->head[s->ins_h] = (Pos)(str))\n#else\n#define INSERT_STRING(s, str, match_head) \\\n   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \\\n    match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \\\n    s->head[s->ins_h] = (Pos)(str))\n#endif\n\n/* ===========================================================================\n * Initialize the hash table (avoiding 64K overflow for 16 bit systems).\n * prev[] will be initialized on the fly.\n */\n#define CLEAR_HASH(s) \\\n    s->head[s->hash_size-1] = NIL; \\\n    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));\n\n/* ========================================================================= */\nint ZEXPORT deflateInit_(strm, level, version, stream_size)\n    z_streamp strm;\n    int level;\n    const char *version;\n    int stream_size;\n{\n    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,\n                         Z_DEFAULT_STRATEGY, version, stream_size);\n    /* To do: ignore strm->next_in if we use it as window */\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,\n                  version, stream_size)\n    z_streamp strm;\n    int  level;\n    int  method;\n    int  windowBits;\n    int  memLevel;\n    int  strategy;\n    const char *version;\n    int stream_size;\n{\n    deflate_state *s;\n    int wrap = 1;\n    static const char my_version[] = ZLIB_VERSION;\n\n    ushf *overlay;\n    /* We overlay pending_buf and d_buf+l_buf. This works since the average\n     * output size for (length,distance) codes is <= 24 bits.\n     */\n\n    if (version == Z_NULL || version[0] != my_version[0] ||\n        stream_size != sizeof(z_stream)) {\n        return Z_VERSION_ERROR;\n    }\n    if (strm == Z_NULL) return Z_STREAM_ERROR;\n\n    strm->msg = Z_NULL;\n    if (strm->zalloc == (alloc_func)0) {\n#ifdef Z_SOLO\n        return Z_STREAM_ERROR;\n#else\n        strm->zalloc = zcalloc;\n        strm->opaque = (voidpf)0;\n#endif\n    }\n    if (strm->zfree == (free_func)0)\n#ifdef Z_SOLO\n        return Z_STREAM_ERROR;\n#else\n        strm->zfree = zcfree;\n#endif\n\n#ifdef FASTEST\n    if (level != 0) level = 1;\n#else\n    if (level == Z_DEFAULT_COMPRESSION) level = 6;\n#endif\n\n    if (windowBits < 0) { /* suppress zlib wrapper */\n        wrap = 0;\n        windowBits = -windowBits;\n    }\n#ifdef GZIP\n    else if (windowBits > 15) {\n        wrap = 2;       /* write gzip wrapper instead */\n        windowBits -= 16;\n    }\n#endif\n    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||\n        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||\n        strategy < 0 || strategy > Z_FIXED) {\n        return Z_STREAM_ERROR;\n    }\n    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */\n    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));\n    if (s == Z_NULL) return Z_MEM_ERROR;\n    strm->state = (struct internal_state FAR *)s;\n    s->strm = strm;\n\n    s->wrap = wrap;\n    s->gzhead = Z_NULL;\n    s->w_bits = windowBits;\n    s->w_size = 1 << s->w_bits;\n    s->w_mask = s->w_size - 1;\n\n    s->hash_bits = memLevel + 7;\n    s->hash_size = 1 << s->hash_bits;\n    s->hash_mask = s->hash_size - 1;\n    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);\n\n    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));\n    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));\n    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));\n\n    s->high_water = 0;      /* nothing written to s->window yet */\n\n    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */\n\n    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);\n    s->pending_buf = (uchf *) overlay;\n    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);\n\n    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||\n        s->pending_buf == Z_NULL) {\n        s->status = FINISH_STATE;\n        strm->msg = ERR_MSG(Z_MEM_ERROR);\n        deflateEnd (strm);\n        return Z_MEM_ERROR;\n    }\n    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);\n    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;\n\n    s->level = level;\n    s->strategy = strategy;\n    s->method = (Byte)method;\n\n    return deflateReset(strm);\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)\n    z_streamp strm;\n    const Bytef *dictionary;\n    uInt  dictLength;\n{\n    deflate_state *s;\n    uInt str, n;\n    int wrap;\n    unsigned avail;\n    z_const unsigned char *next;\n\n    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)\n        return Z_STREAM_ERROR;\n    s = strm->state;\n    wrap = s->wrap;\n    if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)\n        return Z_STREAM_ERROR;\n\n    /* when using zlib wrappers, compute Adler-32 for provided dictionary */\n    if (wrap == 1)\n        strm->adler = adler32(strm->adler, dictionary, dictLength);\n    s->wrap = 0;                    /* avoid computing Adler-32 in read_buf */\n\n    /* if dictionary would fill window, just replace the history */\n    if (dictLength >= s->w_size) {\n        if (wrap == 0) {            /* already empty otherwise */\n            CLEAR_HASH(s);\n            s->strstart = 0;\n            s->block_start = 0L;\n            s->insert = 0;\n        }\n        dictionary += dictLength - s->w_size;  /* use the tail */\n        dictLength = s->w_size;\n    }\n\n    /* insert dictionary into window and hash */\n    avail = strm->avail_in;\n    next = strm->next_in;\n    strm->avail_in = dictLength;\n    strm->next_in = (z_const Bytef *)dictionary;\n    fill_window(s);\n    while (s->lookahead >= MIN_MATCH) {\n        str = s->strstart;\n        n = s->lookahead - (MIN_MATCH-1);\n        do {\n            UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);\n#ifndef FASTEST\n            s->prev[str & s->w_mask] = s->head[s->ins_h];\n#endif\n            s->head[s->ins_h] = (Pos)str;\n            str++;\n        } while (--n);\n        s->strstart = str;\n        s->lookahead = MIN_MATCH-1;\n        fill_window(s);\n    }\n    s->strstart += s->lookahead;\n    s->block_start = (long)s->strstart;\n    s->insert = s->lookahead;\n    s->lookahead = 0;\n    s->match_length = s->prev_length = MIN_MATCH-1;\n    s->match_available = 0;\n    strm->next_in = next;\n    strm->avail_in = avail;\n    s->wrap = wrap;\n    return Z_OK;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateResetKeep (strm)\n    z_streamp strm;\n{\n    deflate_state *s;\n\n    if (strm == Z_NULL || strm->state == Z_NULL ||\n        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {\n        return Z_STREAM_ERROR;\n    }\n\n    strm->total_in = strm->total_out = 0;\n    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */\n    strm->data_type = Z_UNKNOWN;\n\n    s = (deflate_state *)strm->state;\n    s->pending = 0;\n    s->pending_out = s->pending_buf;\n\n    if (s->wrap < 0) {\n        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */\n    }\n    s->status = s->wrap ? INIT_STATE : BUSY_STATE;\n    strm->adler =\n#ifdef GZIP\n        s->wrap == 2 ? crc32(0L, Z_NULL, 0) :\n#endif\n        adler32(0L, Z_NULL, 0);\n    s->last_flush = Z_NO_FLUSH;\n\n    _tr_init(s);\n\n    return Z_OK;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateReset (strm)\n    z_streamp strm;\n{\n    int ret;\n\n    ret = deflateResetKeep(strm);\n    if (ret == Z_OK)\n        lm_init(strm->state);\n    return ret;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateSetHeader (strm, head)\n    z_streamp strm;\n    gz_headerp head;\n{\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    if (strm->state->wrap != 2) return Z_STREAM_ERROR;\n    strm->state->gzhead = head;\n    return Z_OK;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflatePending (strm, pending, bits)\n    unsigned *pending;\n    int *bits;\n    z_streamp strm;\n{\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    if (pending != Z_NULL)\n        *pending = strm->state->pending;\n    if (bits != Z_NULL)\n        *bits = strm->state->bi_valid;\n    return Z_OK;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflatePrime (strm, bits, value)\n    z_streamp strm;\n    int bits;\n    int value;\n{\n    deflate_state *s;\n    int put;\n\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    s = strm->state;\n    if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))\n        return Z_BUF_ERROR;\n    do {\n        put = Buf_size - s->bi_valid;\n        if (put > bits)\n            put = bits;\n        s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);\n        s->bi_valid += put;\n        _tr_flush_bits(s);\n        value >>= put;\n        bits -= put;\n    } while (bits);\n    return Z_OK;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateParams(strm, level, strategy)\n    z_streamp strm;\n    int level;\n    int strategy;\n{\n    deflate_state *s;\n    compress_func func;\n    int err = Z_OK;\n\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    s = strm->state;\n\n#ifdef FASTEST\n    if (level != 0) level = 1;\n#else\n    if (level == Z_DEFAULT_COMPRESSION) level = 6;\n#endif\n    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {\n        return Z_STREAM_ERROR;\n    }\n    func = configuration_table[s->level].func;\n\n    if ((strategy != s->strategy || func != configuration_table[level].func) &&\n        strm->total_in != 0) {\n        /* Flush the last buffer: */\n        err = deflate(strm, Z_BLOCK);\n        if (err == Z_BUF_ERROR && s->pending == 0)\n            err = Z_OK;\n    }\n    if (s->level != level) {\n        s->level = level;\n        s->max_lazy_match   = configuration_table[level].max_lazy;\n        s->good_match       = configuration_table[level].good_length;\n        s->nice_match       = configuration_table[level].nice_length;\n        s->max_chain_length = configuration_table[level].max_chain;\n    }\n    s->strategy = strategy;\n    return err;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)\n    z_streamp strm;\n    int good_length;\n    int max_lazy;\n    int nice_length;\n    int max_chain;\n{\n    deflate_state *s;\n\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    s = strm->state;\n    s->good_match = good_length;\n    s->max_lazy_match = max_lazy;\n    s->nice_match = nice_length;\n    s->max_chain_length = max_chain;\n    return Z_OK;\n}\n\n/* =========================================================================\n * For the default windowBits of 15 and memLevel of 8, this function returns\n * a close to exact, as well as small, upper bound on the compressed size.\n * They are coded as constants here for a reason--if the #define's are\n * changed, then this function needs to be changed as well.  The return\n * value for 15 and 8 only works for those exact settings.\n *\n * For any setting other than those defaults for windowBits and memLevel,\n * the value returned is a conservative worst case for the maximum expansion\n * resulting from using fixed blocks instead of stored blocks, which deflate\n * can emit on compressed data for some combinations of the parameters.\n *\n * This function could be more sophisticated to provide closer upper bounds for\n * every combination of windowBits and memLevel.  But even the conservative\n * upper bound of about 14% expansion does not seem onerous for output buffer\n * allocation.\n */\nuLong ZEXPORT deflateBound(strm, sourceLen)\n    z_streamp strm;\n    uLong sourceLen;\n{\n    deflate_state *s;\n    uLong complen, wraplen;\n    Bytef *str;\n\n    /* conservative upper bound for compressed data */\n    complen = sourceLen +\n              ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;\n\n    /* if can't get parameters, return conservative bound plus zlib wrapper */\n    if (strm == Z_NULL || strm->state == Z_NULL)\n        return complen + 6;\n\n    /* compute wrapper length */\n    s = strm->state;\n    switch (s->wrap) {\n    case 0:                                 /* raw deflate */\n        wraplen = 0;\n        break;\n    case 1:                                 /* zlib wrapper */\n        wraplen = 6 + (s->strstart ? 4 : 0);\n        break;\n    case 2:                                 /* gzip wrapper */\n        wraplen = 18;\n        if (s->gzhead != Z_NULL) {          /* user-supplied gzip header */\n            if (s->gzhead->extra != Z_NULL)\n                wraplen += 2 + s->gzhead->extra_len;\n            str = s->gzhead->name;\n            if (str != Z_NULL)\n                do {\n                    wraplen++;\n                } while (*str++);\n            str = s->gzhead->comment;\n            if (str != Z_NULL)\n                do {\n                    wraplen++;\n                } while (*str++);\n            if (s->gzhead->hcrc)\n                wraplen += 2;\n        }\n        break;\n    default:                                /* for compiler happiness */\n        wraplen = 6;\n    }\n\n    /* if not default parameters, return conservative bound */\n    if (s->w_bits != 15 || s->hash_bits != 8 + 7)\n        return complen + wraplen;\n\n    /* default settings: return tight bound for that case */\n    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +\n           (sourceLen >> 25) + 13 - 6 + wraplen;\n}\n\n/* =========================================================================\n * Put a short in the pending buffer. The 16-bit value is put in MSB order.\n * IN assertion: the stream state is correct and there is enough room in\n * pending_buf.\n */\nlocal void putShortMSB (s, b)\n    deflate_state *s;\n    uInt b;\n{\n    put_byte(s, (Byte)(b >> 8));\n    put_byte(s, (Byte)(b & 0xff));\n}\n\n/* =========================================================================\n * Flush as much pending output as possible. All deflate() output goes\n * through this function so some applications may wish to modify it\n * to avoid allocating a large strm->next_out buffer and copying into it.\n * (See also read_buf()).\n */\nlocal void flush_pending(strm)\n    z_streamp strm;\n{\n    unsigned len;\n    deflate_state *s = strm->state;\n\n    _tr_flush_bits(s);\n    len = s->pending;\n    if (len > strm->avail_out) len = strm->avail_out;\n    if (len == 0) return;\n\n    zmemcpy(strm->next_out, s->pending_out, len);\n    strm->next_out  += len;\n    s->pending_out  += len;\n    strm->total_out += len;\n    strm->avail_out  -= len;\n    s->pending -= len;\n    if (s->pending == 0) {\n        s->pending_out = s->pending_buf;\n    }\n}\n\n/* ========================================================================= */\nint ZEXPORT deflate (strm, flush)\n    z_streamp strm;\n    int flush;\n{\n    int old_flush; /* value of flush param for previous deflate call */\n    deflate_state *s;\n\n    if (strm == Z_NULL || strm->state == Z_NULL ||\n        flush > Z_BLOCK || flush < 0) {\n        return Z_STREAM_ERROR;\n    }\n    s = strm->state;\n\n    if (strm->next_out == Z_NULL ||\n        (strm->next_in == Z_NULL && strm->avail_in != 0) ||\n        (s->status == FINISH_STATE && flush != Z_FINISH)) {\n        ERR_RETURN(strm, Z_STREAM_ERROR);\n    }\n    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);\n\n    s->strm = strm; /* just in case */\n    old_flush = s->last_flush;\n    s->last_flush = flush;\n\n    /* Write the header */\n    if (s->status == INIT_STATE) {\n#ifdef GZIP\n        if (s->wrap == 2) {\n            strm->adler = crc32(0L, Z_NULL, 0);\n            put_byte(s, 31);\n            put_byte(s, 139);\n            put_byte(s, 8);\n            if (s->gzhead == Z_NULL) {\n                put_byte(s, 0);\n                put_byte(s, 0);\n                put_byte(s, 0);\n                put_byte(s, 0);\n                put_byte(s, 0);\n                put_byte(s, s->level == 9 ? 2 :\n                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?\n                             4 : 0));\n                put_byte(s, OS_CODE);\n                s->status = BUSY_STATE;\n            }\n            else {\n                put_byte(s, (s->gzhead->text ? 1 : 0) +\n                            (s->gzhead->hcrc ? 2 : 0) +\n                            (s->gzhead->extra == Z_NULL ? 0 : 4) +\n                            (s->gzhead->name == Z_NULL ? 0 : 8) +\n                            (s->gzhead->comment == Z_NULL ? 0 : 16)\n                        );\n                put_byte(s, (Byte)(s->gzhead->time & 0xff));\n                put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));\n                put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));\n                put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));\n                put_byte(s, s->level == 9 ? 2 :\n                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?\n                             4 : 0));\n                put_byte(s, s->gzhead->os & 0xff);\n                if (s->gzhead->extra != Z_NULL) {\n                    put_byte(s, s->gzhead->extra_len & 0xff);\n                    put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);\n                }\n                if (s->gzhead->hcrc)\n                    strm->adler = crc32(strm->adler, s->pending_buf,\n                                        s->pending);\n                s->gzindex = 0;\n                s->status = EXTRA_STATE;\n            }\n        }\n        else\n#endif\n        {\n            uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;\n            uInt level_flags;\n\n            if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)\n                level_flags = 0;\n            else if (s->level < 6)\n                level_flags = 1;\n            else if (s->level == 6)\n                level_flags = 2;\n            else\n                level_flags = 3;\n            header |= (level_flags << 6);\n            if (s->strstart != 0) header |= PRESET_DICT;\n            header += 31 - (header % 31);\n\n            s->status = BUSY_STATE;\n            putShortMSB(s, header);\n\n            /* Save the adler32 of the preset dictionary: */\n            if (s->strstart != 0) {\n                putShortMSB(s, (uInt)(strm->adler >> 16));\n                putShortMSB(s, (uInt)(strm->adler & 0xffff));\n            }\n            strm->adler = adler32(0L, Z_NULL, 0);\n        }\n    }\n#ifdef GZIP\n    if (s->status == EXTRA_STATE) {\n        if (s->gzhead->extra != Z_NULL) {\n            uInt beg = s->pending;  /* start of bytes to update crc */\n\n            while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {\n                if (s->pending == s->pending_buf_size) {\n                    if (s->gzhead->hcrc && s->pending > beg)\n                        strm->adler = crc32(strm->adler, s->pending_buf + beg,\n                                            s->pending - beg);\n                    flush_pending(strm);\n                    beg = s->pending;\n                    if (s->pending == s->pending_buf_size)\n                        break;\n                }\n                put_byte(s, s->gzhead->extra[s->gzindex]);\n                s->gzindex++;\n            }\n            if (s->gzhead->hcrc && s->pending > beg)\n                strm->adler = crc32(strm->adler, s->pending_buf + beg,\n                                    s->pending - beg);\n            if (s->gzindex == s->gzhead->extra_len) {\n                s->gzindex = 0;\n                s->status = NAME_STATE;\n            }\n        }\n        else\n            s->status = NAME_STATE;\n    }\n    if (s->status == NAME_STATE) {\n        if (s->gzhead->name != Z_NULL) {\n            uInt beg = s->pending;  /* start of bytes to update crc */\n            int val;\n\n            do {\n                if (s->pending == s->pending_buf_size) {\n                    if (s->gzhead->hcrc && s->pending > beg)\n                        strm->adler = crc32(strm->adler, s->pending_buf + beg,\n                                            s->pending - beg);\n                    flush_pending(strm);\n                    beg = s->pending;\n                    if (s->pending == s->pending_buf_size) {\n                        val = 1;\n                        break;\n                    }\n                }\n                val = s->gzhead->name[s->gzindex++];\n                put_byte(s, val);\n            } while (val != 0);\n            if (s->gzhead->hcrc && s->pending > beg)\n                strm->adler = crc32(strm->adler, s->pending_buf + beg,\n                                    s->pending - beg);\n            if (val == 0) {\n                s->gzindex = 0;\n                s->status = COMMENT_STATE;\n            }\n        }\n        else\n            s->status = COMMENT_STATE;\n    }\n    if (s->status == COMMENT_STATE) {\n        if (s->gzhead->comment != Z_NULL) {\n            uInt beg = s->pending;  /* start of bytes to update crc */\n            int val;\n\n            do {\n                if (s->pending == s->pending_buf_size) {\n                    if (s->gzhead->hcrc && s->pending > beg)\n                        strm->adler = crc32(strm->adler, s->pending_buf + beg,\n                                            s->pending - beg);\n                    flush_pending(strm);\n                    beg = s->pending;\n                    if (s->pending == s->pending_buf_size) {\n                        val = 1;\n                        break;\n                    }\n                }\n                val = s->gzhead->comment[s->gzindex++];\n                put_byte(s, val);\n            } while (val != 0);\n            if (s->gzhead->hcrc && s->pending > beg)\n                strm->adler = crc32(strm->adler, s->pending_buf + beg,\n                                    s->pending - beg);\n            if (val == 0)\n                s->status = HCRC_STATE;\n        }\n        else\n            s->status = HCRC_STATE;\n    }\n    if (s->status == HCRC_STATE) {\n        if (s->gzhead->hcrc) {\n            if (s->pending + 2 > s->pending_buf_size)\n                flush_pending(strm);\n            if (s->pending + 2 <= s->pending_buf_size) {\n                put_byte(s, (Byte)(strm->adler & 0xff));\n                put_byte(s, (Byte)((strm->adler >> 8) & 0xff));\n                strm->adler = crc32(0L, Z_NULL, 0);\n                s->status = BUSY_STATE;\n            }\n        }\n        else\n            s->status = BUSY_STATE;\n    }\n#endif\n\n    /* Flush as much pending output as possible */\n    if (s->pending != 0) {\n        flush_pending(strm);\n        if (strm->avail_out == 0) {\n            /* Since avail_out is 0, deflate will be called again with\n             * more output space, but possibly with both pending and\n             * avail_in equal to zero. There won't be anything to do,\n             * but this is not an error situation so make sure we\n             * return OK instead of BUF_ERROR at next call of deflate:\n             */\n            s->last_flush = -1;\n            return Z_OK;\n        }\n\n    /* Make sure there is something to do and avoid duplicate consecutive\n     * flushes. For repeated and useless calls with Z_FINISH, we keep\n     * returning Z_STREAM_END instead of Z_BUF_ERROR.\n     */\n    } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&\n               flush != Z_FINISH) {\n        ERR_RETURN(strm, Z_BUF_ERROR);\n    }\n\n    /* User must not provide more input after the first FINISH: */\n    if (s->status == FINISH_STATE && strm->avail_in != 0) {\n        ERR_RETURN(strm, Z_BUF_ERROR);\n    }\n\n    /* Start a new block or continue the current one.\n     */\n    if (strm->avail_in != 0 || s->lookahead != 0 ||\n        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {\n        block_state bstate;\n\n        bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :\n                    (s->strategy == Z_RLE ? deflate_rle(s, flush) :\n                        (*(configuration_table[s->level].func))(s, flush));\n\n        if (bstate == finish_started || bstate == finish_done) {\n            s->status = FINISH_STATE;\n        }\n        if (bstate == need_more || bstate == finish_started) {\n            if (strm->avail_out == 0) {\n                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */\n            }\n            return Z_OK;\n            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call\n             * of deflate should use the same flush parameter to make sure\n             * that the flush is complete. So we don't have to output an\n             * empty block here, this will be done at next call. This also\n             * ensures that for a very small output buffer, we emit at most\n             * one empty block.\n             */\n        }\n        if (bstate == block_done) {\n            if (flush == Z_PARTIAL_FLUSH) {\n                _tr_align(s);\n            } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */\n                _tr_stored_block(s, (char*)0, 0L, 0);\n                /* For a full flush, this empty block will be recognized\n                 * as a special marker by inflate_sync().\n                 */\n                if (flush == Z_FULL_FLUSH) {\n                    CLEAR_HASH(s);             /* forget history */\n                    if (s->lookahead == 0) {\n                        s->strstart = 0;\n                        s->block_start = 0L;\n                        s->insert = 0;\n                    }\n                }\n            }\n            flush_pending(strm);\n            if (strm->avail_out == 0) {\n              s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */\n              return Z_OK;\n            }\n        }\n    }\n    Assert(strm->avail_out > 0, \"bug2\");\n\n    if (flush != Z_FINISH) return Z_OK;\n    if (s->wrap <= 0) return Z_STREAM_END;\n\n    /* Write the trailer */\n#ifdef GZIP\n    if (s->wrap == 2) {\n        put_byte(s, (Byte)(strm->adler & 0xff));\n        put_byte(s, (Byte)((strm->adler >> 8) & 0xff));\n        put_byte(s, (Byte)((strm->adler >> 16) & 0xff));\n        put_byte(s, (Byte)((strm->adler >> 24) & 0xff));\n        put_byte(s, (Byte)(strm->total_in & 0xff));\n        put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));\n        put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));\n        put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));\n    }\n    else\n#endif\n    {\n        putShortMSB(s, (uInt)(strm->adler >> 16));\n        putShortMSB(s, (uInt)(strm->adler & 0xffff));\n    }\n    flush_pending(strm);\n    /* If avail_out is zero, the application will call deflate again\n     * to flush the rest.\n     */\n    if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */\n    return s->pending != 0 ? Z_OK : Z_STREAM_END;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateEnd (strm)\n    z_streamp strm;\n{\n    int status;\n\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n\n    status = strm->state->status;\n    if (status != INIT_STATE &&\n        status != EXTRA_STATE &&\n        status != NAME_STATE &&\n        status != COMMENT_STATE &&\n        status != HCRC_STATE &&\n        status != BUSY_STATE &&\n        status != FINISH_STATE) {\n      return Z_STREAM_ERROR;\n    }\n\n    /* Deallocate in reverse order of allocations: */\n    TRY_FREE(strm, strm->state->pending_buf);\n    TRY_FREE(strm, strm->state->head);\n    TRY_FREE(strm, strm->state->prev);\n    TRY_FREE(strm, strm->state->window);\n\n    ZFREE(strm, strm->state);\n    strm->state = Z_NULL;\n\n    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;\n}\n\n/* =========================================================================\n * Copy the source state to the destination state.\n * To simplify the source, this is not supported for 16-bit MSDOS (which\n * doesn't have enough memory anyway to duplicate compression states).\n */\nint ZEXPORT deflateCopy (dest, source)\n    z_streamp dest;\n    z_streamp source;\n{\n#ifdef MAXSEG_64K\n    return Z_STREAM_ERROR;\n#else\n    deflate_state *ds;\n    deflate_state *ss;\n    ushf *overlay;\n\n\n    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {\n        return Z_STREAM_ERROR;\n    }\n\n    ss = source->state;\n\n    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));\n\n    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));\n    if (ds == Z_NULL) return Z_MEM_ERROR;\n    dest->state = (struct internal_state FAR *) ds;\n    zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));\n    ds->strm = dest;\n\n    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));\n    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));\n    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));\n    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);\n    ds->pending_buf = (uchf *) overlay;\n\n    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||\n        ds->pending_buf == Z_NULL) {\n        deflateEnd (dest);\n        return Z_MEM_ERROR;\n    }\n    /* following zmemcpy do not work for 16-bit MSDOS */\n    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));\n    zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));\n    zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));\n    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);\n\n    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);\n    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);\n    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;\n\n    ds->l_desc.dyn_tree = ds->dyn_ltree;\n    ds->d_desc.dyn_tree = ds->dyn_dtree;\n    ds->bl_desc.dyn_tree = ds->bl_tree;\n\n    return Z_OK;\n#endif /* MAXSEG_64K */\n}\n\n/* ===========================================================================\n * Read a new buffer from the current input stream, update the adler32\n * and total number of bytes read.  All deflate() input goes through\n * this function so some applications may wish to modify it to avoid\n * allocating a large strm->next_in buffer and copying from it.\n * (See also flush_pending()).\n */\nlocal int read_buf(strm, buf, size)\n    z_streamp strm;\n    Bytef *buf;\n    unsigned size;\n{\n    unsigned len = strm->avail_in;\n\n    if (len > size) len = size;\n    if (len == 0) return 0;\n\n    strm->avail_in  -= len;\n\n    zmemcpy(buf, strm->next_in, len);\n    if (strm->state->wrap == 1) {\n        strm->adler = adler32(strm->adler, buf, len);\n    }\n#ifdef GZIP\n    else if (strm->state->wrap == 2) {\n        strm->adler = crc32(strm->adler, buf, len);\n    }\n#endif\n    strm->next_in  += len;\n    strm->total_in += len;\n\n    return (int)len;\n}\n\n/* ===========================================================================\n * Initialize the \"longest match\" routines for a new zlib stream\n */\nlocal void lm_init (s)\n    deflate_state *s;\n{\n    s->window_size = (ulg)2L*s->w_size;\n\n    CLEAR_HASH(s);\n\n    /* Set the default configuration parameters:\n     */\n    s->max_lazy_match   = configuration_table[s->level].max_lazy;\n    s->good_match       = configuration_table[s->level].good_length;\n    s->nice_match       = configuration_table[s->level].nice_length;\n    s->max_chain_length = configuration_table[s->level].max_chain;\n\n    s->strstart = 0;\n    s->block_start = 0L;\n    s->lookahead = 0;\n    s->insert = 0;\n    s->match_length = s->prev_length = MIN_MATCH-1;\n    s->match_available = 0;\n    s->ins_h = 0;\n#ifndef FASTEST\n#ifdef ASMV\n    match_init(); /* initialize the asm code */\n#endif\n#endif\n}\n\n#ifndef FASTEST\n/* ===========================================================================\n * Set match_start to the longest match starting at the given string and\n * return its length. Matches shorter or equal to prev_length are discarded,\n * in which case the result is equal to prev_length and match_start is\n * garbage.\n * IN assertions: cur_match is the head of the hash chain for the current\n *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1\n * OUT assertion: the match length is not greater than s->lookahead.\n */\n#ifndef ASMV\n/* For 80x86 and 680x0, an optimized version will be provided in match.asm or\n * match.S. The code will be functionally equivalent.\n */\nlocal uInt longest_match(s, cur_match)\n    deflate_state *s;\n    IPos cur_match;                             /* current match */\n{\n    unsigned chain_length = s->max_chain_length;/* max hash chain length */\n    register Bytef *scan = s->window + s->strstart; /* current string */\n    register Bytef *match;                       /* matched string */\n    register int len;                           /* length of current match */\n    int best_len = s->prev_length;              /* best match length so far */\n    int nice_match = s->nice_match;             /* stop if match long enough */\n    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?\n        s->strstart - (IPos)MAX_DIST(s) : NIL;\n    /* Stop when cur_match becomes <= limit. To simplify the code,\n     * we prevent matches with the string of window index 0.\n     */\n    Posf *prev = s->prev;\n    uInt wmask = s->w_mask;\n\n#ifdef UNALIGNED_OK\n    /* Compare two bytes at a time. Note: this is not always beneficial.\n     * Try with and without -DUNALIGNED_OK to check.\n     */\n    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;\n    register ush scan_start = *(ushf*)scan;\n    register ush scan_end   = *(ushf*)(scan+best_len-1);\n#else\n    register Bytef *strend = s->window + s->strstart + MAX_MATCH;\n    register Byte scan_end1  = scan[best_len-1];\n    register Byte scan_end   = scan[best_len];\n#endif\n\n    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.\n     * It is easy to get rid of this optimization if necessary.\n     */\n    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, \"Code too clever\");\n\n    /* Do not waste too much time if we already have a good match: */\n    if (s->prev_length >= s->good_match) {\n        chain_length >>= 2;\n    }\n    /* Do not look for matches beyond the end of the input. This is necessary\n     * to make deflate deterministic.\n     */\n    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;\n\n    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, \"need lookahead\");\n\n    do {\n        Assert(cur_match < s->strstart, \"no future\");\n        match = s->window + cur_match;\n\n        /* Skip to next match if the match length cannot increase\n         * or if the match length is less than 2.  Note that the checks below\n         * for insufficient lookahead only occur occasionally for performance\n         * reasons.  Therefore uninitialized memory will be accessed, and\n         * conditional jumps will be made that depend on those values.\n         * However the length of the match is limited to the lookahead, so\n         * the output of deflate is not affected by the uninitialized values.\n         */\n#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)\n        /* This code assumes sizeof(unsigned short) == 2. Do not use\n         * UNALIGNED_OK if your compiler uses a different size.\n         */\n        if (*(ushf*)(match+best_len-1) != scan_end ||\n            *(ushf*)match != scan_start) continue;\n\n        /* It is not necessary to compare scan[2] and match[2] since they are\n         * always equal when the other bytes match, given that the hash keys\n         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at\n         * strstart+3, +5, ... up to strstart+257. We check for insufficient\n         * lookahead only every 4th comparison; the 128th check will be made\n         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is\n         * necessary to put more guard bytes at the end of the window, or\n         * to check more often for insufficient lookahead.\n         */\n        Assert(scan[2] == match[2], \"scan[2]?\");\n        scan++, match++;\n        do {\n        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&\n                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&\n                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&\n                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&\n                 scan < strend);\n        /* The funny \"do {}\" generates better code on most compilers */\n\n        /* Here, scan <= window+strstart+257 */\n        Assert(scan <= s->window+(unsigned)(s->window_size-1), \"wild scan\");\n        if (*scan == *match) scan++;\n\n        len = (MAX_MATCH - 1) - (int)(strend-scan);\n        scan = strend - (MAX_MATCH-1);\n\n#else /* UNALIGNED_OK */\n\n        if (match[best_len]   != scan_end  ||\n            match[best_len-1] != scan_end1 ||\n            *match            != *scan     ||\n            *++match          != scan[1])      continue;\n\n        /* The check at best_len-1 can be removed because it will be made\n         * again later. (This heuristic is not always a win.)\n         * It is not necessary to compare scan[2] and match[2] since they\n         * are always equal when the other bytes match, given that\n         * the hash keys are equal and that HASH_BITS >= 8.\n         */\n        scan += 2, match++;\n        Assert(*scan == *match, \"match[2]?\");\n\n        /* We check for insufficient lookahead only every 8th comparison;\n         * the 256th check will be made at strstart+258.\n         */\n        do {\n        } while (*++scan == *++match && *++scan == *++match &&\n                 *++scan == *++match && *++scan == *++match &&\n                 *++scan == *++match && *++scan == *++match &&\n                 *++scan == *++match && *++scan == *++match &&\n                 scan < strend);\n\n        Assert(scan <= s->window+(unsigned)(s->window_size-1), \"wild scan\");\n\n        len = MAX_MATCH - (int)(strend - scan);\n        scan = strend - MAX_MATCH;\n\n#endif /* UNALIGNED_OK */\n\n        if (len > best_len) {\n            s->match_start = cur_match;\n            best_len = len;\n            if (len >= nice_match) break;\n#ifdef UNALIGNED_OK\n            scan_end = *(ushf*)(scan+best_len-1);\n#else\n            scan_end1  = scan[best_len-1];\n            scan_end   = scan[best_len];\n#endif\n        }\n    } while ((cur_match = prev[cur_match & wmask]) > limit\n             && --chain_length != 0);\n\n    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;\n    return s->lookahead;\n}\n#endif /* ASMV */\n\n#else /* FASTEST */\n\n/* ---------------------------------------------------------------------------\n * Optimized version for FASTEST only\n */\nlocal uInt longest_match(s, cur_match)\n    deflate_state *s;\n    IPos cur_match;                             /* current match */\n{\n    register Bytef *scan = s->window + s->strstart; /* current string */\n    register Bytef *match;                       /* matched string */\n    register int len;                           /* length of current match */\n    register Bytef *strend = s->window + s->strstart + MAX_MATCH;\n\n    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.\n     * It is easy to get rid of this optimization if necessary.\n     */\n    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, \"Code too clever\");\n\n    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, \"need lookahead\");\n\n    Assert(cur_match < s->strstart, \"no future\");\n\n    match = s->window + cur_match;\n\n    /* Return failure if the match length is less than 2:\n     */\n    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;\n\n    /* The check at best_len-1 can be removed because it will be made\n     * again later. (This heuristic is not always a win.)\n     * It is not necessary to compare scan[2] and match[2] since they\n     * are always equal when the other bytes match, given that\n     * the hash keys are equal and that HASH_BITS >= 8.\n     */\n    scan += 2, match += 2;\n    Assert(*scan == *match, \"match[2]?\");\n\n    /* We check for insufficient lookahead only every 8th comparison;\n     * the 256th check will be made at strstart+258.\n     */\n    do {\n    } while (*++scan == *++match && *++scan == *++match &&\n             *++scan == *++match && *++scan == *++match &&\n             *++scan == *++match && *++scan == *++match &&\n             *++scan == *++match && *++scan == *++match &&\n             scan < strend);\n\n    Assert(scan <= s->window+(unsigned)(s->window_size-1), \"wild scan\");\n\n    len = MAX_MATCH - (int)(strend - scan);\n\n    if (len < MIN_MATCH) return MIN_MATCH - 1;\n\n    s->match_start = cur_match;\n    return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;\n}\n\n#endif /* FASTEST */\n\n#ifdef DEBUG\n/* ===========================================================================\n * Check that the match at match_start is indeed a match.\n */\nlocal void check_match(s, start, match, length)\n    deflate_state *s;\n    IPos start, match;\n    int length;\n{\n    /* check that the match is indeed a match */\n    if (zmemcmp(s->window + match,\n                s->window + start, length) != EQUAL) {\n        fprintf(stderr, \" start %u, match %u, length %d\\n\",\n                start, match, length);\n        do {\n            fprintf(stderr, \"%c%c\", s->window[match++], s->window[start++]);\n        } while (--length != 0);\n        z_error(\"invalid match\");\n    }\n    if (z_verbose > 1) {\n        fprintf(stderr,\"\\\\[%d,%d]\", start-match, length);\n        do { putc(s->window[start++], stderr); } while (--length != 0);\n    }\n}\n#else\n#  define check_match(s, start, match, length)\n#endif /* DEBUG */\n\n/* ===========================================================================\n * Fill the window when the lookahead becomes insufficient.\n * Updates strstart and lookahead.\n *\n * IN assertion: lookahead < MIN_LOOKAHEAD\n * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD\n *    At least one byte has been read, or avail_in == 0; reads are\n *    performed for at least two bytes (required for the zip translate_eol\n *    option -- not supported here).\n */\nlocal void fill_window(s)\n    deflate_state *s;\n{\n    register unsigned n, m;\n    register Posf *p;\n    unsigned more;    /* Amount of free space at the end of the window. */\n    uInt wsize = s->w_size;\n\n    Assert(s->lookahead < MIN_LOOKAHEAD, \"already enough lookahead\");\n\n    do {\n        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);\n\n        /* Deal with !@#$% 64K limit: */\n        if (sizeof(int) <= 2) {\n            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {\n                more = wsize;\n\n            } else if (more == (unsigned)(-1)) {\n                /* Very unlikely, but possible on 16 bit machine if\n                 * strstart == 0 && lookahead == 1 (input done a byte at time)\n                 */\n                more--;\n            }\n        }\n\n        /* If the window is almost full and there is insufficient lookahead,\n         * move the upper half to the lower one to make room in the upper half.\n         */\n        if (s->strstart >= wsize+MAX_DIST(s)) {\n\n            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);\n            s->match_start -= wsize;\n            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */\n            s->block_start -= (long) wsize;\n\n            /* Slide the hash table (could be avoided with 32 bit values\n               at the expense of memory usage). We slide even when level == 0\n               to keep the hash table consistent if we switch back to level > 0\n               later. (Using level 0 permanently is not an optimal usage of\n               zlib, so we don't care about this pathological case.)\n             */\n            n = s->hash_size;\n            p = &s->head[n];\n            do {\n                m = *--p;\n                *p = (Pos)(m >= wsize ? m-wsize : NIL);\n            } while (--n);\n\n            n = wsize;\n#ifndef FASTEST\n            p = &s->prev[n];\n            do {\n                m = *--p;\n                *p = (Pos)(m >= wsize ? m-wsize : NIL);\n                /* If n is not on any hash chain, prev[n] is garbage but\n                 * its value will never be used.\n                 */\n            } while (--n);\n#endif\n            more += wsize;\n        }\n        if (s->strm->avail_in == 0) break;\n\n        /* If there was no sliding:\n         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&\n         *    more == window_size - lookahead - strstart\n         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)\n         * => more >= window_size - 2*WSIZE + 2\n         * In the BIG_MEM or MMAP case (not yet supported),\n         *   window_size == input_size + MIN_LOOKAHEAD  &&\n         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.\n         * Otherwise, window_size == 2*WSIZE so more >= 2.\n         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.\n         */\n        Assert(more >= 2, \"more < 2\");\n\n        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);\n        s->lookahead += n;\n\n        /* Initialize the hash value now that we have some input: */\n        if (s->lookahead + s->insert >= MIN_MATCH) {\n            uInt str = s->strstart - s->insert;\n            s->ins_h = s->window[str];\n            UPDATE_HASH(s, s->ins_h, s->window[str + 1]);\n#if MIN_MATCH != 3\n            Call UPDATE_HASH() MIN_MATCH-3 more times\n#endif\n            while (s->insert) {\n                UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);\n#ifndef FASTEST\n                s->prev[str & s->w_mask] = s->head[s->ins_h];\n#endif\n                s->head[s->ins_h] = (Pos)str;\n                str++;\n                s->insert--;\n                if (s->lookahead + s->insert < MIN_MATCH)\n                    break;\n            }\n        }\n        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,\n         * but this is not important since only literal bytes will be emitted.\n         */\n\n    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);\n\n    /* If the WIN_INIT bytes after the end of the current data have never been\n     * written, then zero those bytes in order to avoid memory check reports of\n     * the use of uninitialized (or uninitialised as Julian writes) bytes by\n     * the longest match routines.  Update the high water mark for the next\n     * time through here.  WIN_INIT is set to MAX_MATCH since the longest match\n     * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.\n     */\n    if (s->high_water < s->window_size) {\n        ulg curr = s->strstart + (ulg)(s->lookahead);\n        ulg init;\n\n        if (s->high_water < curr) {\n            /* Previous high water mark below current data -- zero WIN_INIT\n             * bytes or up to end of window, whichever is less.\n             */\n            init = s->window_size - curr;\n            if (init > WIN_INIT)\n                init = WIN_INIT;\n            zmemzero(s->window + curr, (unsigned)init);\n            s->high_water = curr + init;\n        }\n        else if (s->high_water < (ulg)curr + WIN_INIT) {\n            /* High water mark at or above current data, but below current data\n             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up\n             * to end of window, whichever is less.\n             */\n            init = (ulg)curr + WIN_INIT - s->high_water;\n            if (init > s->window_size - s->high_water)\n                init = s->window_size - s->high_water;\n            zmemzero(s->window + s->high_water, (unsigned)init);\n            s->high_water += init;\n        }\n    }\n\n    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,\n           \"not enough room for search\");\n}\n\n/* ===========================================================================\n * Flush the current block, with given end-of-file flag.\n * IN assertion: strstart is set to the end of the current match.\n */\n#define FLUSH_BLOCK_ONLY(s, last) { \\\n   _tr_flush_block(s, (s->block_start >= 0L ? \\\n                   (charf *)&s->window[(unsigned)s->block_start] : \\\n                   (charf *)Z_NULL), \\\n                (ulg)((long)s->strstart - s->block_start), \\\n                (last)); \\\n   s->block_start = s->strstart; \\\n   flush_pending(s->strm); \\\n   Tracev((stderr,\"[FLUSH]\")); \\\n}\n\n/* Same but force premature exit if necessary. */\n#define FLUSH_BLOCK(s, last) { \\\n   FLUSH_BLOCK_ONLY(s, last); \\\n   if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \\\n}\n\n/* ===========================================================================\n * Copy without compression as much as possible from the input stream, return\n * the current block state.\n * This function does not insert new strings in the dictionary since\n * uncompressible data is probably not useful. This function is used\n * only for the level=0 compression option.\n * NOTE: this function should be optimized to avoid extra copying from\n * window to pending_buf.\n */\nlocal block_state deflate_stored(s, flush)\n    deflate_state *s;\n    int flush;\n{\n    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited\n     * to pending_buf_size, and each stored block has a 5 byte header:\n     */\n    ulg max_block_size = 0xffff;\n    ulg max_start;\n\n    if (max_block_size > s->pending_buf_size - 5) {\n        max_block_size = s->pending_buf_size - 5;\n    }\n\n    /* Copy as much as possible from input to output: */\n    for (;;) {\n        /* Fill the window as much as possible: */\n        if (s->lookahead <= 1) {\n\n            Assert(s->strstart < s->w_size+MAX_DIST(s) ||\n                   s->block_start >= (long)s->w_size, \"slide too late\");\n\n            fill_window(s);\n            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;\n\n            if (s->lookahead == 0) break; /* flush the current block */\n        }\n        Assert(s->block_start >= 0L, \"block gone\");\n\n        s->strstart += s->lookahead;\n        s->lookahead = 0;\n\n        /* Emit a stored block if pending_buf will be full: */\n        max_start = s->block_start + max_block_size;\n        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {\n            /* strstart == 0 is possible when wraparound on 16-bit machine */\n            s->lookahead = (uInt)(s->strstart - max_start);\n            s->strstart = (uInt)max_start;\n            FLUSH_BLOCK(s, 0);\n        }\n        /* Flush if we may have to slide, otherwise block_start may become\n         * negative and the data will be gone:\n         */\n        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {\n            FLUSH_BLOCK(s, 0);\n        }\n    }\n    s->insert = 0;\n    if (flush == Z_FINISH) {\n        FLUSH_BLOCK(s, 1);\n        return finish_done;\n    }\n    if ((long)s->strstart > s->block_start)\n        FLUSH_BLOCK(s, 0);\n    return block_done;\n}\n\n/* ===========================================================================\n * Compress as much as possible from the input stream, return the current\n * block state.\n * This function does not perform lazy evaluation of matches and inserts\n * new strings in the dictionary only for unmatched strings or for short\n * matches. It is used only for the fast compression options.\n */\nlocal block_state deflate_fast(s, flush)\n    deflate_state *s;\n    int flush;\n{\n    IPos hash_head;       /* head of the hash chain */\n    int bflush;           /* set if current block must be flushed */\n\n    for (;;) {\n        /* Make sure that we always have enough lookahead, except\n         * at the end of the input file. We need MAX_MATCH bytes\n         * for the next match, plus MIN_MATCH bytes to insert the\n         * string following the next match.\n         */\n        if (s->lookahead < MIN_LOOKAHEAD) {\n            fill_window(s);\n            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {\n                return need_more;\n            }\n            if (s->lookahead == 0) break; /* flush the current block */\n        }\n\n        /* Insert the string window[strstart .. strstart+2] in the\n         * dictionary, and set hash_head to the head of the hash chain:\n         */\n        hash_head = NIL;\n        if (s->lookahead >= MIN_MATCH) {\n            INSERT_STRING(s, s->strstart, hash_head);\n        }\n\n        /* Find the longest match, discarding those <= prev_length.\n         * At this point we have always match_length < MIN_MATCH\n         */\n        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {\n            /* To simplify the code, we prevent matches with the string\n             * of window index 0 (in particular we have to avoid a match\n             * of the string with itself at the start of the input file).\n             */\n            s->match_length = longest_match (s, hash_head);\n            /* longest_match() sets match_start */\n        }\n        if (s->match_length >= MIN_MATCH) {\n            check_match(s, s->strstart, s->match_start, s->match_length);\n\n            _tr_tally_dist(s, s->strstart - s->match_start,\n                           s->match_length - MIN_MATCH, bflush);\n\n            s->lookahead -= s->match_length;\n\n            /* Insert new strings in the hash table only if the match length\n             * is not too large. This saves time but degrades compression.\n             */\n#ifndef FASTEST\n            if (s->match_length <= s->max_insert_length &&\n                s->lookahead >= MIN_MATCH) {\n                s->match_length--; /* string at strstart already in table */\n                do {\n                    s->strstart++;\n                    INSERT_STRING(s, s->strstart, hash_head);\n                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are\n                     * always MIN_MATCH bytes ahead.\n                     */\n                } while (--s->match_length != 0);\n                s->strstart++;\n            } else\n#endif\n            {\n                s->strstart += s->match_length;\n                s->match_length = 0;\n                s->ins_h = s->window[s->strstart];\n                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);\n#if MIN_MATCH != 3\n                Call UPDATE_HASH() MIN_MATCH-3 more times\n#endif\n                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not\n                 * matter since it will be recomputed at next deflate call.\n                 */\n            }\n        } else {\n            /* No match, output a literal byte */\n            Tracevv((stderr,\"%c\", s->window[s->strstart]));\n            _tr_tally_lit (s, s->window[s->strstart], bflush);\n            s->lookahead--;\n            s->strstart++;\n        }\n        if (bflush) FLUSH_BLOCK(s, 0);\n    }\n    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;\n    if (flush == Z_FINISH) {\n        FLUSH_BLOCK(s, 1);\n        return finish_done;\n    }\n    if (s->last_lit)\n        FLUSH_BLOCK(s, 0);\n    return block_done;\n}\n\n#ifndef FASTEST\n/* ===========================================================================\n * Same as above, but achieves better compression. We use a lazy\n * evaluation for matches: a match is finally adopted only if there is\n * no better match at the next window position.\n */\nlocal block_state deflate_slow(s, flush)\n    deflate_state *s;\n    int flush;\n{\n    IPos hash_head;          /* head of hash chain */\n    int bflush;              /* set if current block must be flushed */\n\n    /* Process the input block. */\n    for (;;) {\n        /* Make sure that we always have enough lookahead, except\n         * at the end of the input file. We need MAX_MATCH bytes\n         * for the next match, plus MIN_MATCH bytes to insert the\n         * string following the next match.\n         */\n        if (s->lookahead < MIN_LOOKAHEAD) {\n            fill_window(s);\n            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {\n                return need_more;\n            }\n            if (s->lookahead == 0) break; /* flush the current block */\n        }\n\n        /* Insert the string window[strstart .. strstart+2] in the\n         * dictionary, and set hash_head to the head of the hash chain:\n         */\n        hash_head = NIL;\n        if (s->lookahead >= MIN_MATCH) {\n            INSERT_STRING(s, s->strstart, hash_head);\n        }\n\n        /* Find the longest match, discarding those <= prev_length.\n         */\n        s->prev_length = s->match_length, s->prev_match = s->match_start;\n        s->match_length = MIN_MATCH-1;\n\n        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&\n            s->strstart - hash_head <= MAX_DIST(s)) {\n            /* To simplify the code, we prevent matches with the string\n             * of window index 0 (in particular we have to avoid a match\n             * of the string with itself at the start of the input file).\n             */\n            s->match_length = longest_match (s, hash_head);\n            /* longest_match() sets match_start */\n\n            if (s->match_length <= 5 && (s->strategy == Z_FILTERED\n#if TOO_FAR <= 32767\n                || (s->match_length == MIN_MATCH &&\n                    s->strstart - s->match_start > TOO_FAR)\n#endif\n                )) {\n\n                /* If prev_match is also MIN_MATCH, match_start is garbage\n                 * but we will ignore the current match anyway.\n                 */\n                s->match_length = MIN_MATCH-1;\n            }\n        }\n        /* If there was a match at the previous step and the current\n         * match is not better, output the previous match:\n         */\n        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {\n            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;\n            /* Do not insert strings in hash table beyond this. */\n\n            check_match(s, s->strstart-1, s->prev_match, s->prev_length);\n\n            _tr_tally_dist(s, s->strstart -1 - s->prev_match,\n                           s->prev_length - MIN_MATCH, bflush);\n\n            /* Insert in hash table all strings up to the end of the match.\n             * strstart-1 and strstart are already inserted. If there is not\n             * enough lookahead, the last two strings are not inserted in\n             * the hash table.\n             */\n            s->lookahead -= s->prev_length-1;\n            s->prev_length -= 2;\n            do {\n                if (++s->strstart <= max_insert) {\n                    INSERT_STRING(s, s->strstart, hash_head);\n                }\n            } while (--s->prev_length != 0);\n            s->match_available = 0;\n            s->match_length = MIN_MATCH-1;\n            s->strstart++;\n\n            if (bflush) FLUSH_BLOCK(s, 0);\n\n        } else if (s->match_available) {\n            /* If there was no match at the previous position, output a\n             * single literal. If there was a match but the current match\n             * is longer, truncate the previous match to a single literal.\n             */\n            Tracevv((stderr,\"%c\", s->window[s->strstart-1]));\n            _tr_tally_lit(s, s->window[s->strstart-1], bflush);\n            if (bflush) {\n                FLUSH_BLOCK_ONLY(s, 0);\n            }\n            s->strstart++;\n            s->lookahead--;\n            if (s->strm->avail_out == 0) return need_more;\n        } else {\n            /* There is no previous match to compare with, wait for\n             * the next step to decide.\n             */\n            s->match_available = 1;\n            s->strstart++;\n            s->lookahead--;\n        }\n    }\n    Assert (flush != Z_NO_FLUSH, \"no flush?\");\n    if (s->match_available) {\n        Tracevv((stderr,\"%c\", s->window[s->strstart-1]));\n        _tr_tally_lit(s, s->window[s->strstart-1], bflush);\n        s->match_available = 0;\n    }\n    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;\n    if (flush == Z_FINISH) {\n        FLUSH_BLOCK(s, 1);\n        return finish_done;\n    }\n    if (s->last_lit)\n        FLUSH_BLOCK(s, 0);\n    return block_done;\n}\n#endif /* FASTEST */\n\n/* ===========================================================================\n * For Z_RLE, simply look for runs of bytes, generate matches only of distance\n * one.  Do not maintain a hash table.  (It will be regenerated if this run of\n * deflate switches away from Z_RLE.)\n */\nlocal block_state deflate_rle(s, flush)\n    deflate_state *s;\n    int flush;\n{\n    int bflush;             /* set if current block must be flushed */\n    uInt prev;              /* byte at distance one to match */\n    Bytef *scan, *strend;   /* scan goes up to strend for length of run */\n\n    for (;;) {\n        /* Make sure that we always have enough lookahead, except\n         * at the end of the input file. We need MAX_MATCH bytes\n         * for the longest run, plus one for the unrolled loop.\n         */\n        if (s->lookahead <= MAX_MATCH) {\n            fill_window(s);\n            if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {\n                return need_more;\n            }\n            if (s->lookahead == 0) break; /* flush the current block */\n        }\n\n        /* See how many times the previous byte repeats */\n        s->match_length = 0;\n        if (s->lookahead >= MIN_MATCH && s->strstart > 0) {\n            scan = s->window + s->strstart - 1;\n            prev = *scan;\n            if (prev == *++scan && prev == *++scan && prev == *++scan) {\n                strend = s->window + s->strstart + MAX_MATCH;\n                do {\n                } while (prev == *++scan && prev == *++scan &&\n                         prev == *++scan && prev == *++scan &&\n                         prev == *++scan && prev == *++scan &&\n                         prev == *++scan && prev == *++scan &&\n                         scan < strend);\n                s->match_length = MAX_MATCH - (int)(strend - scan);\n                if (s->match_length > s->lookahead)\n                    s->match_length = s->lookahead;\n            }\n            Assert(scan <= s->window+(uInt)(s->window_size-1), \"wild scan\");\n        }\n\n        /* Emit match if have run of MIN_MATCH or longer, else emit literal */\n        if (s->match_length >= MIN_MATCH) {\n            check_match(s, s->strstart, s->strstart - 1, s->match_length);\n\n            _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);\n\n            s->lookahead -= s->match_length;\n            s->strstart += s->match_length;\n            s->match_length = 0;\n        } else {\n            /* No match, output a literal byte */\n            Tracevv((stderr,\"%c\", s->window[s->strstart]));\n            _tr_tally_lit (s, s->window[s->strstart], bflush);\n            s->lookahead--;\n            s->strstart++;\n        }\n        if (bflush) FLUSH_BLOCK(s, 0);\n    }\n    s->insert = 0;\n    if (flush == Z_FINISH) {\n        FLUSH_BLOCK(s, 1);\n        return finish_done;\n    }\n    if (s->last_lit)\n        FLUSH_BLOCK(s, 0);\n    return block_done;\n}\n\n/* ===========================================================================\n * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.\n * (It will be regenerated if this run of deflate switches away from Huffman.)\n */\nlocal block_state deflate_huff(s, flush)\n    deflate_state *s;\n    int flush;\n{\n    int bflush;             /* set if current block must be flushed */\n\n    for (;;) {\n        /* Make sure that we have a literal to write. */\n        if (s->lookahead == 0) {\n            fill_window(s);\n            if (s->lookahead == 0) {\n                if (flush == Z_NO_FLUSH)\n                    return need_more;\n                break;      /* flush the current block */\n            }\n        }\n\n        /* Output a literal byte */\n        s->match_length = 0;\n        Tracevv((stderr,\"%c\", s->window[s->strstart]));\n        _tr_tally_lit (s, s->window[s->strstart], bflush);\n        s->lookahead--;\n        s->strstart++;\n        if (bflush) FLUSH_BLOCK(s, 0);\n    }\n    s->insert = 0;\n    if (flush == Z_FINISH) {\n        FLUSH_BLOCK(s, 1);\n        return finish_done;\n    }\n    if (s->last_lit)\n        FLUSH_BLOCK(s, 0);\n    return block_done;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/deflate.h",
    "content": "/* deflate.h -- internal compression state\n * Copyright (C) 1995-2012 Jean-loup Gailly\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* WARNING: this file should *not* be used by applications. It is\n   part of the implementation of the compression library and is\n   subject to change. Applications should only use zlib.h.\n */\n\n/* @(#) $Id$ */\n\n#ifndef DEFLATE_H\n#define DEFLATE_H\n\n#include \"zutil.h\"\n\n/* define NO_GZIP when compiling if you want to disable gzip header and\n   trailer creation by deflate().  NO_GZIP would be used to avoid linking in\n   the crc code when it is not needed.  For shared libraries, gzip encoding\n   should be left enabled. */\n#ifndef NO_GZIP\n#  define GZIP\n#endif\n\n/* ===========================================================================\n * Internal compression state.\n */\n\n#define LENGTH_CODES 29\n/* number of length codes, not counting the special END_BLOCK code */\n\n#define LITERALS  256\n/* number of literal bytes 0..255 */\n\n#define L_CODES (LITERALS+1+LENGTH_CODES)\n/* number of Literal or Length codes, including the END_BLOCK code */\n\n#define D_CODES   30\n/* number of distance codes */\n\n#define BL_CODES  19\n/* number of codes used to transfer the bit lengths */\n\n#define HEAP_SIZE (2*L_CODES+1)\n/* maximum heap size */\n\n#define MAX_BITS 15\n/* All codes must not exceed MAX_BITS bits */\n\n#define Buf_size 16\n/* size of bit buffer in bi_buf */\n\n#define INIT_STATE    42\n#define EXTRA_STATE   69\n#define NAME_STATE    73\n#define COMMENT_STATE 91\n#define HCRC_STATE   103\n#define BUSY_STATE   113\n#define FINISH_STATE 666\n/* Stream status */\n\n\n/* Data structure describing a single value and its code string. */\ntypedef struct ct_data_s {\n    union {\n        ush  freq;       /* frequency count */\n        ush  code;       /* bit string */\n    } fc;\n    union {\n        ush  dad;        /* father node in Huffman tree */\n        ush  len;        /* length of bit string */\n    } dl;\n} FAR ct_data;\n\n#define Freq fc.freq\n#define Code fc.code\n#define Dad  dl.dad\n#define Len  dl.len\n\ntypedef struct static_tree_desc_s  static_tree_desc;\n\ntypedef struct tree_desc_s {\n    ct_data *dyn_tree;           /* the dynamic tree */\n    int     max_code;            /* largest code with non zero frequency */\n    static_tree_desc *stat_desc; /* the corresponding static tree */\n} FAR tree_desc;\n\ntypedef ush Pos;\ntypedef Pos FAR Posf;\ntypedef unsigned IPos;\n\n/* A Pos is an index in the character window. We use short instead of int to\n * save space in the various tables. IPos is used only for parameter passing.\n */\n\ntypedef struct internal_state {\n    z_streamp strm;      /* pointer back to this zlib stream */\n    int   status;        /* as the name implies */\n    Bytef *pending_buf;  /* output still pending */\n    ulg   pending_buf_size; /* size of pending_buf */\n    Bytef *pending_out;  /* next pending byte to output to the stream */\n    uInt   pending;      /* nb of bytes in the pending buffer */\n    int   wrap;          /* bit 0 true for zlib, bit 1 true for gzip */\n    gz_headerp  gzhead;  /* gzip header information to write */\n    uInt   gzindex;      /* where in extra, name, or comment */\n    Byte  method;        /* can only be DEFLATED */\n    int   last_flush;    /* value of flush param for previous deflate call */\n\n                /* used by deflate.c: */\n\n    uInt  w_size;        /* LZ77 window size (32K by default) */\n    uInt  w_bits;        /* log2(w_size)  (8..16) */\n    uInt  w_mask;        /* w_size - 1 */\n\n    Bytef *window;\n    /* Sliding window. Input bytes are read into the second half of the window,\n     * and move to the first half later to keep a dictionary of at least wSize\n     * bytes. With this organization, matches are limited to a distance of\n     * wSize-MAX_MATCH bytes, but this ensures that IO is always\n     * performed with a length multiple of the block size. Also, it limits\n     * the window size to 64K, which is quite useful on MSDOS.\n     * To do: use the user input buffer as sliding window.\n     */\n\n    ulg window_size;\n    /* Actual size of window: 2*wSize, except when the user input buffer\n     * is directly used as sliding window.\n     */\n\n    Posf *prev;\n    /* Link to older string with same hash index. To limit the size of this\n     * array to 64K, this link is maintained only for the last 32K strings.\n     * An index in this array is thus a window index modulo 32K.\n     */\n\n    Posf *head; /* Heads of the hash chains or NIL. */\n\n    uInt  ins_h;          /* hash index of string to be inserted */\n    uInt  hash_size;      /* number of elements in hash table */\n    uInt  hash_bits;      /* log2(hash_size) */\n    uInt  hash_mask;      /* hash_size-1 */\n\n    uInt  hash_shift;\n    /* Number of bits by which ins_h must be shifted at each input\n     * step. It must be such that after MIN_MATCH steps, the oldest\n     * byte no longer takes part in the hash key, that is:\n     *   hash_shift * MIN_MATCH >= hash_bits\n     */\n\n    long block_start;\n    /* Window position at the beginning of the current output block. Gets\n     * negative when the window is moved backwards.\n     */\n\n    uInt match_length;           /* length of best match */\n    IPos prev_match;             /* previous match */\n    int match_available;         /* set if previous match exists */\n    uInt strstart;               /* start of string to insert */\n    uInt match_start;            /* start of matching string */\n    uInt lookahead;              /* number of valid bytes ahead in window */\n\n    uInt prev_length;\n    /* Length of the best match at previous step. Matches not greater than this\n     * are discarded. This is used in the lazy match evaluation.\n     */\n\n    uInt max_chain_length;\n    /* To speed up deflation, hash chains are never searched beyond this\n     * length.  A higher limit improves compression ratio but degrades the\n     * speed.\n     */\n\n    uInt max_lazy_match;\n    /* Attempt to find a better match only when the current match is strictly\n     * smaller than this value. This mechanism is used only for compression\n     * levels >= 4.\n     */\n#   define max_insert_length  max_lazy_match\n    /* Insert new strings in the hash table only if the match length is not\n     * greater than this length. This saves time but degrades compression.\n     * max_insert_length is used only for compression levels <= 3.\n     */\n\n    int level;    /* compression level (1..9) */\n    int strategy; /* favor or force Huffman coding*/\n\n    uInt good_match;\n    /* Use a faster search when the previous match is longer than this */\n\n    int nice_match; /* Stop searching when current match exceeds this */\n\n                /* used by trees.c: */\n    /* Didn't use ct_data typedef below to suppress compiler warning */\n    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */\n    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */\n    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */\n\n    struct tree_desc_s l_desc;               /* desc. for literal tree */\n    struct tree_desc_s d_desc;               /* desc. for distance tree */\n    struct tree_desc_s bl_desc;              /* desc. for bit length tree */\n\n    ush bl_count[MAX_BITS+1];\n    /* number of codes at each bit length for an optimal tree */\n\n    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */\n    int heap_len;               /* number of elements in the heap */\n    int heap_max;               /* element of largest frequency */\n    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.\n     * The same heap array is used to build all trees.\n     */\n\n    uch depth[2*L_CODES+1];\n    /* Depth of each subtree used as tie breaker for trees of equal frequency\n     */\n\n    uchf *l_buf;          /* buffer for literals or lengths */\n\n    uInt  lit_bufsize;\n    /* Size of match buffer for literals/lengths.  There are 4 reasons for\n     * limiting lit_bufsize to 64K:\n     *   - frequencies can be kept in 16 bit counters\n     *   - if compression is not successful for the first block, all input\n     *     data is still in the window so we can still emit a stored block even\n     *     when input comes from standard input.  (This can also be done for\n     *     all blocks if lit_bufsize is not greater than 32K.)\n     *   - if compression is not successful for a file smaller than 64K, we can\n     *     even emit a stored file instead of a stored block (saving 5 bytes).\n     *     This is applicable only for zip (not gzip or zlib).\n     *   - creating new Huffman trees less frequently may not provide fast\n     *     adaptation to changes in the input data statistics. (Take for\n     *     example a binary file with poorly compressible code followed by\n     *     a highly compressible string table.) Smaller buffer sizes give\n     *     fast adaptation but have of course the overhead of transmitting\n     *     trees more frequently.\n     *   - I can't count above 4\n     */\n\n    uInt last_lit;      /* running index in l_buf */\n\n    ushf *d_buf;\n    /* Buffer for distances. To simplify the code, d_buf and l_buf have\n     * the same number of elements. To use different lengths, an extra flag\n     * array would be necessary.\n     */\n\n    ulg opt_len;        /* bit length of current block with optimal trees */\n    ulg static_len;     /* bit length of current block with static trees */\n    uInt matches;       /* number of string matches in current block */\n    uInt insert;        /* bytes at end of window left to insert */\n\n#ifdef DEBUG\n    ulg compressed_len; /* total bit length of compressed file mod 2^32 */\n    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */\n#endif\n\n    ush bi_buf;\n    /* Output buffer. bits are inserted starting at the bottom (least\n     * significant bits).\n     */\n    int bi_valid;\n    /* Number of valid bits in bi_buf.  All bits above the last valid bit\n     * are always zero.\n     */\n\n    ulg high_water;\n    /* High water mark offset in window for initialized bytes -- bytes above\n     * this are set to zero in order to avoid memory check warnings when\n     * longest match routines access bytes past the input.  This is then\n     * updated to the new high water mark.\n     */\n\n} FAR deflate_state;\n\n/* Output a byte on the stream.\n * IN assertion: there is enough room in pending_buf.\n */\n#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}\n\n\n#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)\n/* Minimum amount of lookahead, except at the end of the input file.\n * See deflate.c for comments about the MIN_MATCH+1.\n */\n\n#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)\n/* In order to simplify the code, particularly on 16 bit machines, match\n * distances are limited to MAX_DIST instead of WSIZE.\n */\n\n#define WIN_INIT MAX_MATCH\n/* Number of bytes after end of data in window to initialize in order to avoid\n   memory checker errors from longest match routines */\n\n        /* in trees.c */\nvoid ZLIB_INTERNAL _tr_init OF((deflate_state *s));\nint ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));\nvoid ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,\n                        ulg stored_len, int last));\nvoid ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));\nvoid ZLIB_INTERNAL _tr_align OF((deflate_state *s));\nvoid ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,\n                        ulg stored_len, int last));\n\n#define d_code(dist) \\\n   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])\n/* Mapping from a distance to a distance code. dist is the distance - 1 and\n * must not have side effects. _dist_code[256] and _dist_code[257] are never\n * used.\n */\n\n#ifndef DEBUG\n/* Inline versions of _tr_tally for speed: */\n\n#if defined(GEN_TREES_H) || !defined(STDC)\n  extern uch ZLIB_INTERNAL _length_code[];\n  extern uch ZLIB_INTERNAL _dist_code[];\n#else\n  extern const uch ZLIB_INTERNAL _length_code[];\n  extern const uch ZLIB_INTERNAL _dist_code[];\n#endif\n\n# define _tr_tally_lit(s, c, flush) \\\n  { uch cc = (c); \\\n    s->d_buf[s->last_lit] = 0; \\\n    s->l_buf[s->last_lit++] = cc; \\\n    s->dyn_ltree[cc].Freq++; \\\n    flush = (s->last_lit == s->lit_bufsize-1); \\\n   }\n# define _tr_tally_dist(s, distance, length, flush) \\\n  { uch len = (length); \\\n    ush dist = (distance); \\\n    s->d_buf[s->last_lit] = dist; \\\n    s->l_buf[s->last_lit++] = len; \\\n    dist--; \\\n    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \\\n    s->dyn_dtree[d_code(dist)].Freq++; \\\n    flush = (s->last_lit == s->lit_bufsize-1); \\\n  }\n#else\n# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)\n# define _tr_tally_dist(s, distance, length, flush) \\\n              flush = _tr_tally(s, distance, length)\n#endif\n\n#endif /* DEFLATE_H */\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/doc/algorithm.txt",
    "content": "1. Compression algorithm (deflate)\n\nThe deflation algorithm used by gzip (also zip and zlib) is a variation of\nLZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in\nthe input data.  The second occurrence of a string is replaced by a\npointer to the previous string, in the form of a pair (distance,\nlength).  Distances are limited to 32K bytes, and lengths are limited\nto 258 bytes. When a string does not occur anywhere in the previous\n32K bytes, it is emitted as a sequence of literal bytes.  (In this\ndescription, `string' must be taken as an arbitrary sequence of bytes,\nand is not restricted to printable characters.)\n\nLiterals or match lengths are compressed with one Huffman tree, and\nmatch distances are compressed with another tree. The trees are stored\nin a compact form at the start of each block. The blocks can have any\nsize (except that the compressed data for one block must fit in\navailable memory). A block is terminated when deflate() determines that\nit would be useful to start another block with fresh trees. (This is\nsomewhat similar to the behavior of LZW-based _compress_.)\n\nDuplicated strings are found using a hash table. All input strings of\nlength 3 are inserted in the hash table. A hash index is computed for\nthe next 3 bytes. If the hash chain for this index is not empty, all\nstrings in the chain are compared with the current input string, and\nthe longest match is selected.\n\nThe hash chains are searched starting with the most recent strings, to\nfavor small distances and thus take advantage of the Huffman encoding.\nThe hash chains are singly linked. There are no deletions from the\nhash chains, the algorithm simply discards matches that are too old.\n\nTo avoid a worst-case situation, very long hash chains are arbitrarily\ntruncated at a certain length, determined by a runtime option (level\nparameter of deflateInit). So deflate() does not always find the longest\npossible match but generally finds a match which is long enough.\n\ndeflate() also defers the selection of matches with a lazy evaluation\nmechanism. After a match of length N has been found, deflate() searches for\na longer match at the next input byte. If a longer match is found, the\nprevious match is truncated to a length of one (thus producing a single\nliteral byte) and the process of lazy evaluation begins again. Otherwise,\nthe original match is kept, and the next match search is attempted only N\nsteps later.\n\nThe lazy match evaluation is also subject to a runtime parameter. If\nthe current match is long enough, deflate() reduces the search for a longer\nmatch, thus speeding up the whole process. If compression ratio is more\nimportant than speed, deflate() attempts a complete second search even if\nthe first match is already long enough.\n\nThe lazy match evaluation is not performed for the fastest compression\nmodes (level parameter 1 to 3). For these fast modes, new strings\nare inserted in the hash table only when no match was found, or\nwhen the match is not too long. This degrades the compression ratio\nbut saves time since there are both fewer insertions and fewer searches.\n\n\n2. Decompression algorithm (inflate)\n\n2.1 Introduction\n\nThe key question is how to represent a Huffman code (or any prefix code) so\nthat you can decode fast.  The most important characteristic is that shorter\ncodes are much more common than longer codes, so pay attention to decoding the\nshort codes fast, and let the long codes take longer to decode.\n\ninflate() sets up a first level table that covers some number of bits of\ninput less than the length of longest code.  It gets that many bits from the\nstream, and looks it up in the table.  The table will tell if the next\ncode is that many bits or less and how many, and if it is, it will tell\nthe value, else it will point to the next level table for which inflate()\ngrabs more bits and tries to decode a longer code.\n\nHow many bits to make the first lookup is a tradeoff between the time it\ntakes to decode and the time it takes to build the table.  If building the\ntable took no time (and if you had infinite memory), then there would only\nbe a first level table to cover all the way to the longest code.  However,\nbuilding the table ends up taking a lot longer for more bits since short\ncodes are replicated many times in such a table.  What inflate() does is\nsimply to make the number of bits in the first table a variable, and  then\nto set that variable for the maximum speed.\n\nFor inflate, which has 286 possible codes for the literal/length tree, the size\nof the first table is nine bits.  Also the distance trees have 30 possible\nvalues, and the size of the first table is six bits.  Note that for each of\nthose cases, the table ended up one bit longer than the ``average'' code\nlength, i.e. the code length of an approximately flat code which would be a\nlittle more than eight bits for 286 symbols and a little less than five bits\nfor 30 symbols.\n\n\n2.2 More details on the inflate table lookup\n\nOk, you want to know what this cleverly obfuscated inflate tree actually\nlooks like.  You are correct that it's not a Huffman tree.  It is simply a\nlookup table for the first, let's say, nine bits of a Huffman symbol.  The\nsymbol could be as short as one bit or as long as 15 bits.  If a particular\nsymbol is shorter than nine bits, then that symbol's translation is duplicated\nin all those entries that start with that symbol's bits.  For example, if the\nsymbol is four bits, then it's duplicated 32 times in a nine-bit table.  If a\nsymbol is nine bits long, it appears in the table once.\n\nIf the symbol is longer than nine bits, then that entry in the table points\nto another similar table for the remaining bits.  Again, there are duplicated\nentries as needed.  The idea is that most of the time the symbol will be short\nand there will only be one table look up.  (That's whole idea behind data\ncompression in the first place.)  For the less frequent long symbols, there\nwill be two lookups.  If you had a compression method with really long\nsymbols, you could have as many levels of lookups as is efficient.  For\ninflate, two is enough.\n\nSo a table entry either points to another table (in which case nine bits in\nthe above example are gobbled), or it contains the translation for the symbol\nand the number of bits to gobble.  Then you start again with the next\nungobbled bit.\n\nYou may wonder: why not just have one lookup table for how ever many bits the\nlongest symbol is?  The reason is that if you do that, you end up spending\nmore time filling in duplicate symbol entries than you do actually decoding.\nAt least for deflate's output that generates new trees every several 10's of\nkbytes.  You can imagine that filling in a 2^15 entry table for a 15-bit code\nwould take too long if you're only decoding several thousand symbols.  At the\nother extreme, you could make a new table for every bit in the code.  In fact,\nthat's essentially a Huffman tree.  But then you spend too much time\ntraversing the tree while decoding, even for short symbols.\n\nSo the number of bits for the first lookup table is a trade of the time to\nfill out the table vs. the time spent looking at the second level and above of\nthe table.\n\nHere is an example, scaled down:\n\nThe code being decoded, with 10 symbols, from 1 to 6 bits long:\n\nA: 0\nB: 10\nC: 1100\nD: 11010\nE: 11011\nF: 11100\nG: 11101\nH: 11110\nI: 111110\nJ: 111111\n\nLet's make the first table three bits long (eight entries):\n\n000: A,1\n001: A,1\n010: A,1\n011: A,1\n100: B,2\n101: B,2\n110: -> table X (gobble 3 bits)\n111: -> table Y (gobble 3 bits)\n\nEach entry is what the bits decode as and how many bits that is, i.e. how\nmany bits to gobble.  Or the entry points to another table, with the number of\nbits to gobble implicit in the size of the table.\n\nTable X is two bits long since the longest code starting with 110 is five bits\nlong:\n\n00: C,1\n01: C,1\n10: D,2\n11: E,2\n\nTable Y is three bits long since the longest code starting with 111 is six\nbits long:\n\n000: F,2\n001: F,2\n010: G,2\n011: G,2\n100: H,2\n101: H,2\n110: I,3\n111: J,3\n\nSo what we have here are three tables with a total of 20 entries that had to\nbe constructed.  That's compared to 64 entries for a single table.  Or\ncompared to 16 entries for a Huffman tree (six two entry tables and one four\nentry table).  Assuming that the code ideally represents the probability of\nthe symbols, it takes on the average 1.25 lookups per symbol.  That's compared\nto one lookup for the single table, or 1.66 lookups per symbol for the\nHuffman tree.\n\nThere, I think that gives you a picture of what's going on.  For inflate, the\nmeaning of a particular symbol is often more than just a letter.  It can be a\nbyte (a \"literal\"), or it can be either a length or a distance which\nindicates a base value and a number of bits to fetch after the code that is\nadded to the base value.  Or it might be the special end-of-block code.  The\ndata structures created in inftrees.c try to encode all that information\ncompactly in the tables.\n\n\nJean-loup Gailly        Mark Adler\njloup@gzip.org          madler@alumni.caltech.edu\n\n\nReferences:\n\n[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data\nCompression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,\npp. 337-343.\n\n``DEFLATE Compressed Data Format Specification'' available in\nhttp://tools.ietf.org/html/rfc1951\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/doc/rfc1950.txt",
    "content": "\n\n\n\n\n\nNetwork Working Group                                         P. Deutsch\nRequest for Comments: 1950                           Aladdin Enterprises\nCategory: Informational                                      J-L. Gailly\n                                                                Info-ZIP\n                                                                May 1996\n\n\n         ZLIB Compressed Data Format Specification version 3.3\n\nStatus of This Memo\n\n   This memo provides information for the Internet community.  This memo\n   does not specify an Internet standard of any kind.  Distribution of\n   this memo is unlimited.\n\nIESG Note:\n\n   The IESG takes no position on the validity of any Intellectual\n   Property Rights statements contained in this document.\n\nNotices\n\n   Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly\n\n   Permission is granted to copy and distribute this document for any\n   purpose and without charge, including translations into other\n   languages and incorporation into compilations, provided that the\n   copyright notice and this notice are preserved, and that any\n   substantive changes or deletions from the original are clearly\n   marked.\n\n   A pointer to the latest version of this and related documentation in\n   HTML format can be found at the URL\n   <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.\n\nAbstract\n\n   This specification defines a lossless compressed data format.  The\n   data can be produced or consumed, even for an arbitrarily long\n   sequentially presented input data stream, using only an a priori\n   bounded amount of intermediate storage.  The format presently uses\n   the DEFLATE compression method but can be easily extended to use\n   other compression methods.  It can be implemented readily in a manner\n   not covered by patents.  This specification also defines the ADLER-32\n   checksum (an extension and improvement of the Fletcher checksum),\n   used for detection of data corruption, and provides an algorithm for\n   computing it.\n\n\n\n\nDeutsch & Gailly             Informational                      [Page 1]\n\f\nRFC 1950       ZLIB Compressed Data Format Specification        May 1996\n\n\nTable of Contents\n\n   1. Introduction ................................................... 2\n      1.1. Purpose ................................................... 2\n      1.2. Intended audience ......................................... 3\n      1.3. Scope ..................................................... 3\n      1.4. Compliance ................................................ 3\n      1.5.  Definitions of terms and conventions used ................ 3\n      1.6. Changes from previous versions ............................ 3\n   2. Detailed specification ......................................... 3\n      2.1. Overall conventions ....................................... 3\n      2.2. Data format ............................................... 4\n      2.3. Compliance ................................................ 7\n   3. References ..................................................... 7\n   4. Source code .................................................... 8\n   5. Security Considerations ........................................ 8\n   6. Acknowledgements ............................................... 8\n   7. Authors' Addresses ............................................. 8\n   8. Appendix: Rationale ............................................ 9\n   9. Appendix: Sample code ..........................................10\n\n1. Introduction\n\n   1.1. Purpose\n\n      The purpose of this specification is to define a lossless\n      compressed data format that:\n\n          * Is independent of CPU type, operating system, file system,\n            and character set, and hence can be used for interchange;\n\n          * Can be produced or consumed, even for an arbitrarily long\n            sequentially presented input data stream, using only an a\n            priori bounded amount of intermediate storage, and hence can\n            be used in data communications or similar structures such as\n            Unix filters;\n\n          * Can use a number of different compression methods;\n\n          * Can be implemented readily in a manner not covered by\n            patents, and hence can be practiced freely.\n\n      The data format defined by this specification does not attempt to\n      allow random access to compressed data.\n\n\n\n\n\n\n\nDeutsch & Gailly             Informational                      [Page 2]\n\f\nRFC 1950       ZLIB Compressed Data Format Specification        May 1996\n\n\n   1.2. Intended audience\n\n      This specification is intended for use by implementors of software\n      to compress data into zlib format and/or decompress data from zlib\n      format.\n\n      The text of the specification assumes a basic background in\n      programming at the level of bits and other primitive data\n      representations.\n\n   1.3. Scope\n\n      The specification specifies a compressed data format that can be\n      used for in-memory compression of a sequence of arbitrary bytes.\n\n   1.4. Compliance\n\n      Unless otherwise indicated below, a compliant decompressor must be\n      able to accept and decompress any data set that conforms to all\n      the specifications presented here; a compliant compressor must\n      produce data sets that conform to all the specifications presented\n      here.\n\n   1.5.  Definitions of terms and conventions used\n\n      byte: 8 bits stored or transmitted as a unit (same as an octet).\n      (For this specification, a byte is exactly 8 bits, even on\n      machines which store a character on a number of bits different\n      from 8.) See below, for the numbering of bits within a byte.\n\n   1.6. Changes from previous versions\n\n      Version 3.1 was the first public release of this specification.\n      In version 3.2, some terminology was changed and the Adler-32\n      sample code was rewritten for clarity.  In version 3.3, the\n      support for a preset dictionary was introduced, and the\n      specification was converted to RFC style.\n\n2. Detailed specification\n\n   2.1. Overall conventions\n\n      In the diagrams below, a box like this:\n\n         +---+\n         |   | <-- the vertical bars might be missing\n         +---+\n\n\n\n\nDeutsch & Gailly             Informational                      [Page 3]\n\f\nRFC 1950       ZLIB Compressed Data Format Specification        May 1996\n\n\n      represents one byte; a box like this:\n\n         +==============+\n         |              |\n         +==============+\n\n      represents a variable number of bytes.\n\n      Bytes stored within a computer do not have a \"bit order\", since\n      they are always treated as a unit.  However, a byte considered as\n      an integer between 0 and 255 does have a most- and least-\n      significant bit, and since we write numbers with the most-\n      significant digit on the left, we also write bytes with the most-\n      significant bit on the left.  In the diagrams below, we number the\n      bits of a byte so that bit 0 is the least-significant bit, i.e.,\n      the bits are numbered:\n\n         +--------+\n         |76543210|\n         +--------+\n\n      Within a computer, a number may occupy multiple bytes.  All\n      multi-byte numbers in the format described here are stored with\n      the MOST-significant byte first (at the lower memory address).\n      For example, the decimal number 520 is stored as:\n\n             0     1\n         +--------+--------+\n         |00000010|00001000|\n         +--------+--------+\n          ^        ^\n          |        |\n          |        + less significant byte = 8\n          + more significant byte = 2 x 256\n\n   2.2. Data format\n\n      A zlib stream has the following structure:\n\n           0   1\n         +---+---+\n         |CMF|FLG|   (more-->)\n         +---+---+\n\n\n\n\n\n\n\n\nDeutsch & Gailly             Informational                      [Page 4]\n\f\nRFC 1950       ZLIB Compressed Data Format Specification        May 1996\n\n\n      (if FLG.FDICT set)\n\n           0   1   2   3\n         +---+---+---+---+\n         |     DICTID    |   (more-->)\n         +---+---+---+---+\n\n         +=====================+---+---+---+---+\n         |...compressed data...|    ADLER32    |\n         +=====================+---+---+---+---+\n\n      Any data which may appear after ADLER32 are not part of the zlib\n      stream.\n\n      CMF (Compression Method and flags)\n         This byte is divided into a 4-bit compression method and a 4-\n         bit information field depending on the compression method.\n\n            bits 0 to 3  CM     Compression method\n            bits 4 to 7  CINFO  Compression info\n\n      CM (Compression method)\n         This identifies the compression method used in the file. CM = 8\n         denotes the \"deflate\" compression method with a window size up\n         to 32K.  This is the method used by gzip and PNG (see\n         references [1] and [2] in Chapter 3, below, for the reference\n         documents).  CM = 15 is reserved.  It might be used in a future\n         version of this specification to indicate the presence of an\n         extra field before the compressed data.\n\n      CINFO (Compression info)\n         For CM = 8, CINFO is the base-2 logarithm of the LZ77 window\n         size, minus eight (CINFO=7 indicates a 32K window size). Values\n         of CINFO above 7 are not allowed in this version of the\n         specification.  CINFO is not defined in this specification for\n         CM not equal to 8.\n\n      FLG (FLaGs)\n         This flag byte is divided as follows:\n\n            bits 0 to 4  FCHECK  (check bits for CMF and FLG)\n            bit  5       FDICT   (preset dictionary)\n            bits 6 to 7  FLEVEL  (compression level)\n\n         The FCHECK value must be such that CMF and FLG, when viewed as\n         a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG),\n         is a multiple of 31.\n\n\n\n\nDeutsch & Gailly             Informational                      [Page 5]\n\f\nRFC 1950       ZLIB Compressed Data Format Specification        May 1996\n\n\n      FDICT (Preset dictionary)\n         If FDICT is set, a DICT dictionary identifier is present\n         immediately after the FLG byte. The dictionary is a sequence of\n         bytes which are initially fed to the compressor without\n         producing any compressed output. DICT is the Adler-32 checksum\n         of this sequence of bytes (see the definition of ADLER32\n         below).  The decompressor can use this identifier to determine\n         which dictionary has been used by the compressor.\n\n      FLEVEL (Compression level)\n         These flags are available for use by specific compression\n         methods.  The \"deflate\" method (CM = 8) sets these flags as\n         follows:\n\n            0 - compressor used fastest algorithm\n            1 - compressor used fast algorithm\n            2 - compressor used default algorithm\n            3 - compressor used maximum compression, slowest algorithm\n\n         The information in FLEVEL is not needed for decompression; it\n         is there to indicate if recompression might be worthwhile.\n\n      compressed data\n         For compression method 8, the compressed data is stored in the\n         deflate compressed data format as described in the document\n         \"DEFLATE Compressed Data Format Specification\" by L. Peter\n         Deutsch. (See reference [3] in Chapter 3, below)\n\n         Other compressed data formats are not specified in this version\n         of the zlib specification.\n\n      ADLER32 (Adler-32 checksum)\n         This contains a checksum value of the uncompressed data\n         (excluding any dictionary data) computed according to Adler-32\n         algorithm. This algorithm is a 32-bit extension and improvement\n         of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073\n         standard. See references [4] and [5] in Chapter 3, below)\n\n         Adler-32 is composed of two sums accumulated per byte: s1 is\n         the sum of all bytes, s2 is the sum of all s1 values. Both sums\n         are done modulo 65521. s1 is initialized to 1, s2 to zero.  The\n         Adler-32 checksum is stored as s2*65536 + s1 in most-\n         significant-byte first (network) order.\n\n\n\n\n\n\n\n\nDeutsch & Gailly             Informational                      [Page 6]\n\f\nRFC 1950       ZLIB Compressed Data Format Specification        May 1996\n\n\n   2.3. Compliance\n\n      A compliant compressor must produce streams with correct CMF, FLG\n      and ADLER32, but need not support preset dictionaries.  When the\n      zlib data format is used as part of another standard data format,\n      the compressor may use only preset dictionaries that are specified\n      by this other data format.  If this other format does not use the\n      preset dictionary feature, the compressor must not set the FDICT\n      flag.\n\n      A compliant decompressor must check CMF, FLG, and ADLER32, and\n      provide an error indication if any of these have incorrect values.\n      A compliant decompressor must give an error indication if CM is\n      not one of the values defined in this specification (only the\n      value 8 is permitted in this version), since another value could\n      indicate the presence of new features that would cause subsequent\n      data to be interpreted incorrectly.  A compliant decompressor must\n      give an error indication if FDICT is set and DICTID is not the\n      identifier of a known preset dictionary.  A decompressor may\n      ignore FLEVEL and still be compliant.  When the zlib data format\n      is being used as a part of another standard format, a compliant\n      decompressor must support all the preset dictionaries specified by\n      the other format. When the other format does not use the preset\n      dictionary feature, a compliant decompressor must reject any\n      stream in which the FDICT flag is set.\n\n3. References\n\n   [1] Deutsch, L.P.,\"GZIP Compressed Data Format Specification\",\n       available in ftp://ftp.uu.net/pub/archiving/zip/doc/\n\n   [2] Thomas Boutell, \"PNG (Portable Network Graphics) specification\",\n       available in ftp://ftp.uu.net/graphics/png/documents/\n\n   [3] Deutsch, L.P.,\"DEFLATE Compressed Data Format Specification\",\n       available in ftp://ftp.uu.net/pub/archiving/zip/doc/\n\n   [4] Fletcher, J. G., \"An Arithmetic Checksum for Serial\n       Transmissions,\" IEEE Transactions on Communications, Vol. COM-30,\n       No. 1, January 1982, pp. 247-252.\n\n   [5] ITU-T Recommendation X.224, Annex D, \"Checksum Algorithms,\"\n       November, 1993, pp. 144, 145. (Available from\n       gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073.\n\n\n\n\n\n\n\nDeutsch & Gailly             Informational                      [Page 7]\n\f\nRFC 1950       ZLIB Compressed Data Format Specification        May 1996\n\n\n4. Source code\n\n   Source code for a C language implementation of a \"zlib\" compliant\n   library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/.\n\n5. Security Considerations\n\n   A decoder that fails to check the ADLER32 checksum value may be\n   subject to undetected data corruption.\n\n6. Acknowledgements\n\n   Trademarks cited in this document are the property of their\n   respective owners.\n\n   Jean-Loup Gailly and Mark Adler designed the zlib format and wrote\n   the related software described in this specification.  Glenn\n   Randers-Pehrson converted this document to RFC and HTML format.\n\n7. Authors' Addresses\n\n   L. Peter Deutsch\n   Aladdin Enterprises\n   203 Santa Margarita Ave.\n   Menlo Park, CA 94025\n\n   Phone: (415) 322-0103 (AM only)\n   FAX:   (415) 322-1734\n   EMail: <ghost@aladdin.com>\n\n\n   Jean-Loup Gailly\n\n   EMail: <gzip@prep.ai.mit.edu>\n\n   Questions about the technical content of this specification can be\n   sent by email to\n\n   Jean-Loup Gailly <gzip@prep.ai.mit.edu> and\n   Mark Adler <madler@alumni.caltech.edu>\n\n   Editorial comments on this specification can be sent by email to\n\n   L. Peter Deutsch <ghost@aladdin.com> and\n   Glenn Randers-Pehrson <randeg@alumni.rpi.edu>\n\n\n\n\n\n\nDeutsch & Gailly             Informational                      [Page 8]\n\f\nRFC 1950       ZLIB Compressed Data Format Specification        May 1996\n\n\n8. Appendix: Rationale\n\n   8.1. Preset dictionaries\n\n      A preset dictionary is specially useful to compress short input\n      sequences. The compressor can take advantage of the dictionary\n      context to encode the input in a more compact manner. The\n      decompressor can be initialized with the appropriate context by\n      virtually decompressing a compressed version of the dictionary\n      without producing any output. However for certain compression\n      algorithms such as the deflate algorithm this operation can be\n      achieved without actually performing any decompression.\n\n      The compressor and the decompressor must use exactly the same\n      dictionary. The dictionary may be fixed or may be chosen among a\n      certain number of predefined dictionaries, according to the kind\n      of input data. The decompressor can determine which dictionary has\n      been chosen by the compressor by checking the dictionary\n      identifier. This document does not specify the contents of\n      predefined dictionaries, since the optimal dictionaries are\n      application specific. Standard data formats using this feature of\n      the zlib specification must precisely define the allowed\n      dictionaries.\n\n   8.2. The Adler-32 algorithm\n\n      The Adler-32 algorithm is much faster than the CRC32 algorithm yet\n      still provides an extremely low probability of undetected errors.\n\n      The modulo on unsigned long accumulators can be delayed for 5552\n      bytes, so the modulo operation time is negligible.  If the bytes\n      are a, b, c, the second sum is 3a + 2b + c + 3, and so is position\n      and order sensitive, unlike the first sum, which is just a\n      checksum.  That 65521 is prime is important to avoid a possible\n      large class of two-byte errors that leave the check unchanged.\n      (The Fletcher checksum uses 255, which is not prime and which also\n      makes the Fletcher check insensitive to single byte changes 0 <->\n      255.)\n\n      The sum s1 is initialized to 1 instead of zero to make the length\n      of the sequence part of s2, so that the length does not have to be\n      checked separately. (Any sequence of zeroes has a Fletcher\n      checksum of zero.)\n\n\n\n\n\n\n\n\nDeutsch & Gailly             Informational                      [Page 9]\n\f\nRFC 1950       ZLIB Compressed Data Format Specification        May 1996\n\n\n9. Appendix: Sample code\n\n   The following C code computes the Adler-32 checksum of a data buffer.\n   It is written for clarity, not for speed.  The sample code is in the\n   ANSI C programming language. Non C users may find it easier to read\n   with these hints:\n\n      &      Bitwise AND operator.\n      >>     Bitwise right shift operator. When applied to an\n             unsigned quantity, as here, right shift inserts zero bit(s)\n             at the left.\n      <<     Bitwise left shift operator. Left shift inserts zero\n             bit(s) at the right.\n      ++     \"n++\" increments the variable n.\n      %      modulo operator: a % b is the remainder of a divided by b.\n\n      #define BASE 65521 /* largest prime smaller than 65536 */\n\n      /*\n         Update a running Adler-32 checksum with the bytes buf[0..len-1]\n       and return the updated checksum. The Adler-32 checksum should be\n       initialized to 1.\n\n       Usage example:\n\n         unsigned long adler = 1L;\n\n         while (read_buffer(buffer, length) != EOF) {\n           adler = update_adler32(adler, buffer, length);\n         }\n         if (adler != original_adler) error();\n      */\n      unsigned long update_adler32(unsigned long adler,\n         unsigned char *buf, int len)\n      {\n        unsigned long s1 = adler & 0xffff;\n        unsigned long s2 = (adler >> 16) & 0xffff;\n        int n;\n\n        for (n = 0; n < len; n++) {\n          s1 = (s1 + buf[n]) % BASE;\n          s2 = (s2 + s1)     % BASE;\n        }\n        return (s2 << 16) + s1;\n      }\n\n      /* Return the adler32 of the bytes buf[0..len-1] */\n\n\n\n\nDeutsch & Gailly             Informational                     [Page 10]\n\f\nRFC 1950       ZLIB Compressed Data Format Specification        May 1996\n\n\n      unsigned long adler32(unsigned char *buf, int len)\n      {\n        return update_adler32(1L, buf, len);\n      }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nDeutsch & Gailly             Informational                     [Page 11]\n\f\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/doc/rfc1951.txt",
    "content": "\n\n\n\n\n\nNetwork Working Group                                         P. Deutsch\nRequest for Comments: 1951                           Aladdin Enterprises\nCategory: Informational                                         May 1996\n\n\n        DEFLATE Compressed Data Format Specification version 1.3\n\nStatus of This Memo\n\n   This memo provides information for the Internet community.  This memo\n   does not specify an Internet standard of any kind.  Distribution of\n   this memo is unlimited.\n\nIESG Note:\n\n   The IESG takes no position on the validity of any Intellectual\n   Property Rights statements contained in this document.\n\nNotices\n\n   Copyright (c) 1996 L. Peter Deutsch\n\n   Permission is granted to copy and distribute this document for any\n   purpose and without charge, including translations into other\n   languages and incorporation into compilations, provided that the\n   copyright notice and this notice are preserved, and that any\n   substantive changes or deletions from the original are clearly\n   marked.\n\n   A pointer to the latest version of this and related documentation in\n   HTML format can be found at the URL\n   <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.\n\nAbstract\n\n   This specification defines a lossless compressed data format that\n   compresses data using a combination of the LZ77 algorithm and Huffman\n   coding, with efficiency comparable to the best currently available\n   general-purpose compression methods.  The data can be produced or\n   consumed, even for an arbitrarily long sequentially presented input\n   data stream, using only an a priori bounded amount of intermediate\n   storage.  The format can be implemented readily in a manner not\n   covered by patents.\n\n\n\n\n\n\n\n\nDeutsch                      Informational                      [Page 1]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\nTable of Contents\n\n   1. Introduction ................................................... 2\n      1.1. Purpose ................................................... 2\n      1.2. Intended audience ......................................... 3\n      1.3. Scope ..................................................... 3\n      1.4. Compliance ................................................ 3\n      1.5.  Definitions of terms and conventions used ................ 3\n      1.6. Changes from previous versions ............................ 4\n   2. Compressed representation overview ............................. 4\n   3. Detailed specification ......................................... 5\n      3.1. Overall conventions ....................................... 5\n          3.1.1. Packing into bytes .................................. 5\n      3.2. Compressed block format ................................... 6\n          3.2.1. Synopsis of prefix and Huffman coding ............... 6\n          3.2.2. Use of Huffman coding in the \"deflate\" format ....... 7\n          3.2.3. Details of block format ............................. 9\n          3.2.4. Non-compressed blocks (BTYPE=00) ................... 11\n          3.2.5. Compressed blocks (length and distance codes) ...... 11\n          3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12\n          3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13\n      3.3. Compliance ............................................... 14\n   4. Compression algorithm details ................................. 14\n   5. References .................................................... 16\n   6. Security Considerations ....................................... 16\n   7. Source code ................................................... 16\n   8. Acknowledgements .............................................. 16\n   9. Author's Address .............................................. 17\n\n1. Introduction\n\n   1.1. Purpose\n\n      The purpose of this specification is to define a lossless\n      compressed data format that:\n          * Is independent of CPU type, operating system, file system,\n            and character set, and hence can be used for interchange;\n          * Can be produced or consumed, even for an arbitrarily long\n            sequentially presented input data stream, using only an a\n            priori bounded amount of intermediate storage, and hence\n            can be used in data communications or similar structures\n            such as Unix filters;\n          * Compresses data with efficiency comparable to the best\n            currently available general-purpose compression methods,\n            and in particular considerably better than the \"compress\"\n            program;\n          * Can be implemented readily in a manner not covered by\n            patents, and hence can be practiced freely;\n\n\n\nDeutsch                      Informational                      [Page 2]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n          * Is compatible with the file format produced by the current\n            widely used gzip utility, in that conforming decompressors\n            will be able to read data produced by the existing gzip\n            compressor.\n\n      The data format defined by this specification does not attempt to:\n\n          * Allow random access to compressed data;\n          * Compress specialized data (e.g., raster graphics) as well\n            as the best currently available specialized algorithms.\n\n      A simple counting argument shows that no lossless compression\n      algorithm can compress every possible input data set.  For the\n      format defined here, the worst case expansion is 5 bytes per 32K-\n      byte block, i.e., a size increase of 0.015% for large data sets.\n      English text usually compresses by a factor of 2.5 to 3;\n      executable files usually compress somewhat less; graphical data\n      such as raster images may compress much more.\n\n   1.2. Intended audience\n\n      This specification is intended for use by implementors of software\n      to compress data into \"deflate\" format and/or decompress data from\n      \"deflate\" format.\n\n      The text of the specification assumes a basic background in\n      programming at the level of bits and other primitive data\n      representations.  Familiarity with the technique of Huffman coding\n      is helpful but not required.\n\n   1.3. Scope\n\n      The specification specifies a method for representing a sequence\n      of bytes as a (usually shorter) sequence of bits, and a method for\n      packing the latter bit sequence into bytes.\n\n   1.4. Compliance\n\n      Unless otherwise indicated below, a compliant decompressor must be\n      able to accept and decompress any data set that conforms to all\n      the specifications presented here; a compliant compressor must\n      produce data sets that conform to all the specifications presented\n      here.\n\n   1.5.  Definitions of terms and conventions used\n\n      Byte: 8 bits stored or transmitted as a unit (same as an octet).\n      For this specification, a byte is exactly 8 bits, even on machines\n\n\n\nDeutsch                      Informational                      [Page 3]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n      which store a character on a number of bits different from eight.\n      See below, for the numbering of bits within a byte.\n\n      String: a sequence of arbitrary bytes.\n\n   1.6. Changes from previous versions\n\n      There have been no technical changes to the deflate format since\n      version 1.1 of this specification.  In version 1.2, some\n      terminology was changed.  Version 1.3 is a conversion of the\n      specification to RFC style.\n\n2. Compressed representation overview\n\n   A compressed data set consists of a series of blocks, corresponding\n   to successive blocks of input data.  The block sizes are arbitrary,\n   except that non-compressible blocks are limited to 65,535 bytes.\n\n   Each block is compressed using a combination of the LZ77 algorithm\n   and Huffman coding. The Huffman trees for each block are independent\n   of those for previous or subsequent blocks; the LZ77 algorithm may\n   use a reference to a duplicated string occurring in a previous block,\n   up to 32K input bytes before.\n\n   Each block consists of two parts: a pair of Huffman code trees that\n   describe the representation of the compressed data part, and a\n   compressed data part.  (The Huffman trees themselves are compressed\n   using Huffman encoding.)  The compressed data consists of a series of\n   elements of two types: literal bytes (of strings that have not been\n   detected as duplicated within the previous 32K input bytes), and\n   pointers to duplicated strings, where a pointer is represented as a\n   pair <length, backward distance>.  The representation used in the\n   \"deflate\" format limits distances to 32K bytes and lengths to 258\n   bytes, but does not limit the size of a block, except for\n   uncompressible blocks, which are limited as noted above.\n\n   Each type of value (literals, distances, and lengths) in the\n   compressed data is represented using a Huffman code, using one code\n   tree for literals and lengths and a separate code tree for distances.\n   The code trees for each block appear in a compact form just before\n   the compressed data for that block.\n\n\n\n\n\n\n\n\n\n\nDeutsch                      Informational                      [Page 4]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n3. Detailed specification\n\n   3.1. Overall conventions In the diagrams below, a box like this:\n\n         +---+\n         |   | <-- the vertical bars might be missing\n         +---+\n\n      represents one byte; a box like this:\n\n         +==============+\n         |              |\n         +==============+\n\n      represents a variable number of bytes.\n\n      Bytes stored within a computer do not have a \"bit order\", since\n      they are always treated as a unit.  However, a byte considered as\n      an integer between 0 and 255 does have a most- and least-\n      significant bit, and since we write numbers with the most-\n      significant digit on the left, we also write bytes with the most-\n      significant bit on the left.  In the diagrams below, we number the\n      bits of a byte so that bit 0 is the least-significant bit, i.e.,\n      the bits are numbered:\n\n         +--------+\n         |76543210|\n         +--------+\n\n      Within a computer, a number may occupy multiple bytes.  All\n      multi-byte numbers in the format described here are stored with\n      the least-significant byte first (at the lower memory address).\n      For example, the decimal number 520 is stored as:\n\n             0        1\n         +--------+--------+\n         |00001000|00000010|\n         +--------+--------+\n          ^        ^\n          |        |\n          |        + more significant byte = 2 x 256\n          + less significant byte = 8\n\n      3.1.1. Packing into bytes\n\n         This document does not address the issue of the order in which\n         bits of a byte are transmitted on a bit-sequential medium,\n         since the final data format described here is byte- rather than\n\n\n\nDeutsch                      Informational                      [Page 5]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n         bit-oriented.  However, we describe the compressed block format\n         in below, as a sequence of data elements of various bit\n         lengths, not a sequence of bytes.  We must therefore specify\n         how to pack these data elements into bytes to form the final\n         compressed byte sequence:\n\n             * Data elements are packed into bytes in order of\n               increasing bit number within the byte, i.e., starting\n               with the least-significant bit of the byte.\n             * Data elements other than Huffman codes are packed\n               starting with the least-significant bit of the data\n               element.\n             * Huffman codes are packed starting with the most-\n               significant bit of the code.\n\n         In other words, if one were to print out the compressed data as\n         a sequence of bytes, starting with the first byte at the\n         *right* margin and proceeding to the *left*, with the most-\n         significant bit of each byte on the left as usual, one would be\n         able to parse the result from right to left, with fixed-width\n         elements in the correct MSB-to-LSB order and Huffman codes in\n         bit-reversed order (i.e., with the first bit of the code in the\n         relative LSB position).\n\n   3.2. Compressed block format\n\n      3.2.1. Synopsis of prefix and Huffman coding\n\n         Prefix coding represents symbols from an a priori known\n         alphabet by bit sequences (codes), one code for each symbol, in\n         a manner such that different symbols may be represented by bit\n         sequences of different lengths, but a parser can always parse\n         an encoded string unambiguously symbol-by-symbol.\n\n         We define a prefix code in terms of a binary tree in which the\n         two edges descending from each non-leaf node are labeled 0 and\n         1 and in which the leaf nodes correspond one-for-one with (are\n         labeled with) the symbols of the alphabet; then the code for a\n         symbol is the sequence of 0's and 1's on the edges leading from\n         the root to the leaf labeled with that symbol.  For example:\n\n\n\n\n\n\n\n\n\n\n\nDeutsch                      Informational                      [Page 6]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n                          /\\              Symbol    Code\n                         0  1             ------    ----\n                        /    \\                A      00\n                       /\\     B               B       1\n                      0  1                    C     011\n                     /    \\                   D     010\n                    A     /\\\n                         0  1\n                        /    \\\n                       D      C\n\n         A parser can decode the next symbol from an encoded input\n         stream by walking down the tree from the root, at each step\n         choosing the edge corresponding to the next input bit.\n\n         Given an alphabet with known symbol frequencies, the Huffman\n         algorithm allows the construction of an optimal prefix code\n         (one which represents strings with those symbol frequencies\n         using the fewest bits of any possible prefix codes for that\n         alphabet).  Such a code is called a Huffman code.  (See\n         reference [1] in Chapter 5, references for additional\n         information on Huffman codes.)\n\n         Note that in the \"deflate\" format, the Huffman codes for the\n         various alphabets must not exceed certain maximum code lengths.\n         This constraint complicates the algorithm for computing code\n         lengths from symbol frequencies.  Again, see Chapter 5,\n         references for details.\n\n      3.2.2. Use of Huffman coding in the \"deflate\" format\n\n         The Huffman codes used for each alphabet in the \"deflate\"\n         format have two additional rules:\n\n             * All codes of a given bit length have lexicographically\n               consecutive values, in the same order as the symbols\n               they represent;\n\n             * Shorter codes lexicographically precede longer codes.\n\n\n\n\n\n\n\n\n\n\n\n\nDeutsch                      Informational                      [Page 7]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n         We could recode the example above to follow this rule as\n         follows, assuming that the order of the alphabet is ABCD:\n\n            Symbol  Code\n            ------  ----\n            A       10\n            B       0\n            C       110\n            D       111\n\n         I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are\n         lexicographically consecutive.\n\n         Given this rule, we can define the Huffman code for an alphabet\n         just by giving the bit lengths of the codes for each symbol of\n         the alphabet in order; this is sufficient to determine the\n         actual codes.  In our example, the code is completely defined\n         by the sequence of bit lengths (2, 1, 3, 3).  The following\n         algorithm generates the codes as integers, intended to be read\n         from most- to least-significant bit.  The code lengths are\n         initially in tree[I].Len; the codes are produced in\n         tree[I].Code.\n\n         1)  Count the number of codes for each code length.  Let\n             bl_count[N] be the number of codes of length N, N >= 1.\n\n         2)  Find the numerical value of the smallest code for each\n             code length:\n\n                code = 0;\n                bl_count[0] = 0;\n                for (bits = 1; bits <= MAX_BITS; bits++) {\n                    code = (code + bl_count[bits-1]) << 1;\n                    next_code[bits] = code;\n                }\n\n         3)  Assign numerical values to all codes, using consecutive\n             values for all codes of the same length with the base\n             values determined at step 2. Codes that are never used\n             (which have a bit length of zero) must not be assigned a\n             value.\n\n                for (n = 0;  n <= max_code; n++) {\n                    len = tree[n].Len;\n                    if (len != 0) {\n                        tree[n].Code = next_code[len];\n                        next_code[len]++;\n                    }\n\n\n\nDeutsch                      Informational                      [Page 8]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n                }\n\n         Example:\n\n         Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3,\n         3, 2, 4, 4).  After step 1, we have:\n\n            N      bl_count[N]\n            -      -----------\n            2      1\n            3      5\n            4      2\n\n         Step 2 computes the following next_code values:\n\n            N      next_code[N]\n            -      ------------\n            1      0\n            2      0\n            3      2\n            4      14\n\n         Step 3 produces the following code values:\n\n            Symbol Length   Code\n            ------ ------   ----\n            A       3        010\n            B       3        011\n            C       3        100\n            D       3        101\n            E       3        110\n            F       2         00\n            G       4       1110\n            H       4       1111\n\n      3.2.3. Details of block format\n\n         Each block of compressed data begins with 3 header bits\n         containing the following data:\n\n            first bit       BFINAL\n            next 2 bits     BTYPE\n\n         Note that the header bits do not necessarily begin on a byte\n         boundary, since a block does not necessarily occupy an integral\n         number of bytes.\n\n\n\n\n\nDeutsch                      Informational                      [Page 9]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n         BFINAL is set if and only if this is the last block of the data\n         set.\n\n         BTYPE specifies how the data are compressed, as follows:\n\n            00 - no compression\n            01 - compressed with fixed Huffman codes\n            10 - compressed with dynamic Huffman codes\n            11 - reserved (error)\n\n         The only difference between the two compressed cases is how the\n         Huffman codes for the literal/length and distance alphabets are\n         defined.\n\n         In all cases, the decoding algorithm for the actual data is as\n         follows:\n\n            do\n               read block header from input stream.\n               if stored with no compression\n                  skip any remaining bits in current partially\n                     processed byte\n                  read LEN and NLEN (see next section)\n                  copy LEN bytes of data to output\n               otherwise\n                  if compressed with dynamic Huffman codes\n                     read representation of code trees (see\n                        subsection below)\n                  loop (until end of block code recognized)\n                     decode literal/length value from input stream\n                     if value < 256\n                        copy value (literal byte) to output stream\n                     otherwise\n                        if value = end of block (256)\n                           break from loop\n                        otherwise (value = 257..285)\n                           decode distance from input stream\n\n                           move backwards distance bytes in the output\n                           stream, and copy length bytes from this\n                           position to the output stream.\n                  end loop\n            while not last block\n\n         Note that a duplicated string reference may refer to a string\n         in a previous block; i.e., the backward distance may cross one\n         or more block boundaries.  However a distance cannot refer past\n         the beginning of the output stream.  (An application using a\n\n\n\nDeutsch                      Informational                     [Page 10]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n         preset dictionary might discard part of the output stream; a\n         distance can refer to that part of the output stream anyway)\n         Note also that the referenced string may overlap the current\n         position; for example, if the last 2 bytes decoded have values\n         X and Y, a string reference with <length = 5, distance = 2>\n         adds X,Y,X,Y,X to the output stream.\n\n         We now specify each compression method in turn.\n\n      3.2.4. Non-compressed blocks (BTYPE=00)\n\n         Any bits of input up to the next byte boundary are ignored.\n         The rest of the block consists of the following information:\n\n              0   1   2   3   4...\n            +---+---+---+---+================================+\n            |  LEN  | NLEN  |... LEN bytes of literal data...|\n            +---+---+---+---+================================+\n\n         LEN is the number of data bytes in the block.  NLEN is the\n         one's complement of LEN.\n\n      3.2.5. Compressed blocks (length and distance codes)\n\n         As noted above, encoded data blocks in the \"deflate\" format\n         consist of sequences of symbols drawn from three conceptually\n         distinct alphabets: either literal bytes, from the alphabet of\n         byte values (0..255), or <length, backward distance> pairs,\n         where the length is drawn from (3..258) and the distance is\n         drawn from (1..32,768).  In fact, the literal and length\n         alphabets are merged into a single alphabet (0..285), where\n         values 0..255 represent literal bytes, the value 256 indicates\n         end-of-block, and values 257..285 represent length codes\n         (possibly in conjunction with extra bits following the symbol\n         code) as follows:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nDeutsch                      Informational                     [Page 11]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n                 Extra               Extra               Extra\n            Code Bits Length(s) Code Bits Lengths   Code Bits Length(s)\n            ---- ---- ------     ---- ---- -------   ---- ---- -------\n             257   0     3       267   1   15,16     277   4   67-82\n             258   0     4       268   1   17,18     278   4   83-98\n             259   0     5       269   2   19-22     279   4   99-114\n             260   0     6       270   2   23-26     280   4  115-130\n             261   0     7       271   2   27-30     281   5  131-162\n             262   0     8       272   2   31-34     282   5  163-194\n             263   0     9       273   3   35-42     283   5  195-226\n             264   0    10       274   3   43-50     284   5  227-257\n             265   1  11,12      275   3   51-58     285   0    258\n             266   1  13,14      276   3   59-66\n\n         The extra bits should be interpreted as a machine integer\n         stored with the most-significant bit first, e.g., bits 1110\n         represent the value 14.\n\n                  Extra           Extra               Extra\n             Code Bits Dist  Code Bits   Dist     Code Bits Distance\n             ---- ---- ----  ---- ----  ------    ---- ---- --------\n               0   0    1     10   4     33-48    20    9   1025-1536\n               1   0    2     11   4     49-64    21    9   1537-2048\n               2   0    3     12   5     65-96    22   10   2049-3072\n               3   0    4     13   5     97-128   23   10   3073-4096\n               4   1   5,6    14   6    129-192   24   11   4097-6144\n               5   1   7,8    15   6    193-256   25   11   6145-8192\n               6   2   9-12   16   7    257-384   26   12  8193-12288\n               7   2  13-16   17   7    385-512   27   12 12289-16384\n               8   3  17-24   18   8    513-768   28   13 16385-24576\n               9   3  25-32   19   8   769-1024   29   13 24577-32768\n\n      3.2.6. Compression with fixed Huffman codes (BTYPE=01)\n\n         The Huffman codes for the two alphabets are fixed, and are not\n         represented explicitly in the data.  The Huffman code lengths\n         for the literal/length alphabet are:\n\n                   Lit Value    Bits        Codes\n                   ---------    ----        -----\n                     0 - 143     8          00110000 through\n                                            10111111\n                   144 - 255     9          110010000 through\n                                            111111111\n                   256 - 279     7          0000000 through\n                                            0010111\n                   280 - 287     8          11000000 through\n                                            11000111\n\n\n\nDeutsch                      Informational                     [Page 12]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n         The code lengths are sufficient to generate the actual codes,\n         as described above; we show the codes in the table for added\n         clarity.  Literal/length values 286-287 will never actually\n         occur in the compressed data, but participate in the code\n         construction.\n\n         Distance codes 0-31 are represented by (fixed-length) 5-bit\n         codes, with possible additional bits as shown in the table\n         shown in Paragraph 3.2.5, above.  Note that distance codes 30-\n         31 will never actually occur in the compressed data.\n\n      3.2.7. Compression with dynamic Huffman codes (BTYPE=10)\n\n         The Huffman codes for the two alphabets appear in the block\n         immediately after the header bits and before the actual\n         compressed data, first the literal/length code and then the\n         distance code.  Each code is defined by a sequence of code\n         lengths, as discussed in Paragraph 3.2.2, above.  For even\n         greater compactness, the code length sequences themselves are\n         compressed using a Huffman code.  The alphabet for code lengths\n         is as follows:\n\n               0 - 15: Represent code lengths of 0 - 15\n                   16: Copy the previous code length 3 - 6 times.\n                       The next 2 bits indicate repeat length\n                             (0 = 3, ... , 3 = 6)\n                          Example:  Codes 8, 16 (+2 bits 11),\n                                    16 (+2 bits 10) will expand to\n                                    12 code lengths of 8 (1 + 6 + 5)\n                   17: Repeat a code length of 0 for 3 - 10 times.\n                       (3 bits of length)\n                   18: Repeat a code length of 0 for 11 - 138 times\n                       (7 bits of length)\n\n         A code length of 0 indicates that the corresponding symbol in\n         the literal/length or distance alphabet will not occur in the\n         block, and should not participate in the Huffman code\n         construction algorithm given earlier.  If only one distance\n         code is used, it is encoded using one bit, not zero bits; in\n         this case there is a single code length of one, with one unused\n         code.  One distance code of zero bits means that there are no\n         distance codes used at all (the data is all literals).\n\n         We can now define the format of the block:\n\n               5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286)\n               5 Bits: HDIST, # of Distance codes - 1        (1 - 32)\n               4 Bits: HCLEN, # of Code Length codes - 4     (4 - 19)\n\n\n\nDeutsch                      Informational                     [Page 13]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n               (HCLEN + 4) x 3 bits: code lengths for the code length\n                  alphabet given just above, in the order: 16, 17, 18,\n                  0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15\n\n                  These code lengths are interpreted as 3-bit integers\n                  (0-7); as above, a code length of 0 means the\n                  corresponding symbol (literal/length or distance code\n                  length) is not used.\n\n               HLIT + 257 code lengths for the literal/length alphabet,\n                  encoded using the code length Huffman code\n\n               HDIST + 1 code lengths for the distance alphabet,\n                  encoded using the code length Huffman code\n\n               The actual compressed data of the block,\n                  encoded using the literal/length and distance Huffman\n                  codes\n\n               The literal/length symbol 256 (end of data),\n                  encoded using the literal/length Huffman code\n\n         The code length repeat codes can cross from HLIT + 257 to the\n         HDIST + 1 code lengths.  In other words, all code lengths form\n         a single sequence of HLIT + HDIST + 258 values.\n\n   3.3. Compliance\n\n      A compressor may limit further the ranges of values specified in\n      the previous section and still be compliant; for example, it may\n      limit the range of backward pointers to some value smaller than\n      32K.  Similarly, a compressor may limit the size of blocks so that\n      a compressible block fits in memory.\n\n      A compliant decompressor must accept the full range of possible\n      values defined in the previous section, and must accept blocks of\n      arbitrary size.\n\n4. Compression algorithm details\n\n   While it is the intent of this document to define the \"deflate\"\n   compressed data format without reference to any particular\n   compression algorithm, the format is related to the compressed\n   formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below);\n   since many variations of LZ77 are patented, it is strongly\n   recommended that the implementor of a compressor follow the general\n   algorithm presented here, which is known not to be patented per se.\n   The material in this section is not part of the definition of the\n\n\n\nDeutsch                      Informational                     [Page 14]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n   specification per se, and a compressor need not follow it in order to\n   be compliant.\n\n   The compressor terminates a block when it determines that starting a\n   new block with fresh trees would be useful, or when the block size\n   fills up the compressor's block buffer.\n\n   The compressor uses a chained hash table to find duplicated strings,\n   using a hash function that operates on 3-byte sequences.  At any\n   given point during compression, let XYZ be the next 3 input bytes to\n   be examined (not necessarily all different, of course).  First, the\n   compressor examines the hash chain for XYZ.  If the chain is empty,\n   the compressor simply writes out X as a literal byte and advances one\n   byte in the input.  If the hash chain is not empty, indicating that\n   the sequence XYZ (or, if we are unlucky, some other 3 bytes with the\n   same hash function value) has occurred recently, the compressor\n   compares all strings on the XYZ hash chain with the actual input data\n   sequence starting at the current point, and selects the longest\n   match.\n\n   The compressor searches the hash chains starting with the most recent\n   strings, to favor small distances and thus take advantage of the\n   Huffman encoding.  The hash chains are singly linked. There are no\n   deletions from the hash chains; the algorithm simply discards matches\n   that are too old.  To avoid a worst-case situation, very long hash\n   chains are arbitrarily truncated at a certain length, determined by a\n   run-time parameter.\n\n   To improve overall compression, the compressor optionally defers the\n   selection of matches (\"lazy matching\"): after a match of length N has\n   been found, the compressor searches for a longer match starting at\n   the next input byte.  If it finds a longer match, it truncates the\n   previous match to a length of one (thus producing a single literal\n   byte) and then emits the longer match.  Otherwise, it emits the\n   original match, and, as described above, advances N bytes before\n   continuing.\n\n   Run-time parameters also control this \"lazy match\" procedure.  If\n   compression ratio is most important, the compressor attempts a\n   complete second search regardless of the length of the first match.\n   In the normal case, if the current match is \"long enough\", the\n   compressor reduces the search for a longer match, thus speeding up\n   the process.  If speed is most important, the compressor inserts new\n   strings in the hash table only when no match was found, or when the\n   match is not \"too long\".  This degrades the compression ratio but\n   saves time since there are both fewer insertions and fewer searches.\n\n\n\n\n\nDeutsch                      Informational                     [Page 15]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n5. References\n\n   [1] Huffman, D. A., \"A Method for the Construction of Minimum\n       Redundancy Codes\", Proceedings of the Institute of Radio\n       Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101.\n\n   [2] Ziv J., Lempel A., \"A Universal Algorithm for Sequential Data\n       Compression\", IEEE Transactions on Information Theory, Vol. 23,\n       No. 3, pp. 337-343.\n\n   [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources,\n       available in ftp://ftp.uu.net/pub/archiving/zip/doc/\n\n   [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources,\n       available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/\n\n   [5] Schwartz, E. S., and Kallick, B. \"Generating a canonical prefix\n       encoding.\" Comm. ACM, 7,3 (Mar. 1964), pp. 166-169.\n\n   [6] Hirschberg and Lelewer, \"Efficient decoding of prefix codes,\"\n       Comm. ACM, 33,4, April 1990, pp. 449-459.\n\n6. Security Considerations\n\n   Any data compression method involves the reduction of redundancy in\n   the data.  Consequently, any corruption of the data is likely to have\n   severe effects and be difficult to correct.  Uncompressed text, on\n   the other hand, will probably still be readable despite the presence\n   of some corrupted bytes.\n\n   It is recommended that systems using this data format provide some\n   means of validating the integrity of the compressed data.  See\n   reference [3], for example.\n\n7. Source code\n\n   Source code for a C language implementation of a \"deflate\" compliant\n   compressor and decompressor is available within the zlib package at\n   ftp://ftp.uu.net/pub/archiving/zip/zlib/.\n\n8. Acknowledgements\n\n   Trademarks cited in this document are the property of their\n   respective owners.\n\n   Phil Katz designed the deflate format.  Jean-Loup Gailly and Mark\n   Adler wrote the related software described in this specification.\n   Glenn Randers-Pehrson converted this document to RFC and HTML format.\n\n\n\nDeutsch                      Informational                     [Page 16]\n\f\nRFC 1951      DEFLATE Compressed Data Format Specification      May 1996\n\n\n9. Author's Address\n\n   L. Peter Deutsch\n   Aladdin Enterprises\n   203 Santa Margarita Ave.\n   Menlo Park, CA 94025\n\n   Phone: (415) 322-0103 (AM only)\n   FAX:   (415) 322-1734\n   EMail: <ghost@aladdin.com>\n\n   Questions about the technical content of this specification can be\n   sent by email to:\n\n   Jean-Loup Gailly <gzip@prep.ai.mit.edu> and\n   Mark Adler <madler@alumni.caltech.edu>\n\n   Editorial comments on this specification can be sent by email to:\n\n   L. Peter Deutsch <ghost@aladdin.com> and\n   Glenn Randers-Pehrson <randeg@alumni.rpi.edu>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nDeutsch                      Informational                     [Page 17]\n\f\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/doc/rfc1952.txt",
    "content": "\n\n\n\n\n\nNetwork Working Group                                         P. Deutsch\nRequest for Comments: 1952                           Aladdin Enterprises\nCategory: Informational                                         May 1996\n\n\n               GZIP file format specification version 4.3\n\nStatus of This Memo\n\n   This memo provides information for the Internet community.  This memo\n   does not specify an Internet standard of any kind.  Distribution of\n   this memo is unlimited.\n\nIESG Note:\n\n   The IESG takes no position on the validity of any Intellectual\n   Property Rights statements contained in this document.\n\nNotices\n\n   Copyright (c) 1996 L. Peter Deutsch\n\n   Permission is granted to copy and distribute this document for any\n   purpose and without charge, including translations into other\n   languages and incorporation into compilations, provided that the\n   copyright notice and this notice are preserved, and that any\n   substantive changes or deletions from the original are clearly\n   marked.\n\n   A pointer to the latest version of this and related documentation in\n   HTML format can be found at the URL\n   <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.\n\nAbstract\n\n   This specification defines a lossless compressed data format that is\n   compatible with the widely used GZIP utility.  The format includes a\n   cyclic redundancy check value for detecting data corruption.  The\n   format presently uses the DEFLATE method of compression but can be\n   easily extended to use other compression methods.  The format can be\n   implemented readily in a manner not covered by patents.\n\n\n\n\n\n\n\n\n\n\nDeutsch                      Informational                      [Page 1]\n\f\nRFC 1952             GZIP File Format Specification             May 1996\n\n\nTable of Contents\n\n   1. Introduction ................................................... 2\n      1.1. Purpose ................................................... 2\n      1.2. Intended audience ......................................... 3\n      1.3. Scope ..................................................... 3\n      1.4. Compliance ................................................ 3\n      1.5. Definitions of terms and conventions used ................. 3\n      1.6. Changes from previous versions ............................ 3\n   2. Detailed specification ......................................... 4\n      2.1. Overall conventions ....................................... 4\n      2.2. File format ............................................... 5\n      2.3. Member format ............................................. 5\n          2.3.1. Member header and trailer ........................... 6\n              2.3.1.1. Extra field ................................... 8\n              2.3.1.2. Compliance .................................... 9\n      3. References .................................................. 9\n      4. Security Considerations .................................... 10\n      5. Acknowledgements ........................................... 10\n      6. Author's Address ........................................... 10\n      7. Appendix: Jean-Loup Gailly's gzip utility .................. 11\n      8. Appendix: Sample CRC Code .................................. 11\n\n1. Introduction\n\n   1.1. Purpose\n\n      The purpose of this specification is to define a lossless\n      compressed data format that:\n\n          * Is independent of CPU type, operating system, file system,\n            and character set, and hence can be used for interchange;\n          * Can compress or decompress a data stream (as opposed to a\n            randomly accessible file) to produce another data stream,\n            using only an a priori bounded amount of intermediate\n            storage, and hence can be used in data communications or\n            similar structures such as Unix filters;\n          * Compresses data with efficiency comparable to the best\n            currently available general-purpose compression methods,\n            and in particular considerably better than the \"compress\"\n            program;\n          * Can be implemented readily in a manner not covered by\n            patents, and hence can be practiced freely;\n          * Is compatible with the file format produced by the current\n            widely used gzip utility, in that conforming decompressors\n            will be able to read data produced by the existing gzip\n            compressor.\n\n\n\n\nDeutsch                      Informational                      [Page 2]\n\f\nRFC 1952             GZIP File Format Specification             May 1996\n\n\n      The data format defined by this specification does not attempt to:\n\n          * Provide random access to compressed data;\n          * Compress specialized data (e.g., raster graphics) as well as\n            the best currently available specialized algorithms.\n\n   1.2. Intended audience\n\n      This specification is intended for use by implementors of software\n      to compress data into gzip format and/or decompress data from gzip\n      format.\n\n      The text of the specification assumes a basic background in\n      programming at the level of bits and other primitive data\n      representations.\n\n   1.3. Scope\n\n      The specification specifies a compression method and a file format\n      (the latter assuming only that a file can store a sequence of\n      arbitrary bytes).  It does not specify any particular interface to\n      a file system or anything about character sets or encodings\n      (except for file names and comments, which are optional).\n\n   1.4. Compliance\n\n      Unless otherwise indicated below, a compliant decompressor must be\n      able to accept and decompress any file that conforms to all the\n      specifications presented here; a compliant compressor must produce\n      files that conform to all the specifications presented here.  The\n      material in the appendices is not part of the specification per se\n      and is not relevant to compliance.\n\n   1.5. Definitions of terms and conventions used\n\n      byte: 8 bits stored or transmitted as a unit (same as an octet).\n      (For this specification, a byte is exactly 8 bits, even on\n      machines which store a character on a number of bits different\n      from 8.)  See below for the numbering of bits within a byte.\n\n   1.6. Changes from previous versions\n\n      There have been no technical changes to the gzip format since\n      version 4.1 of this specification.  In version 4.2, some\n      terminology was changed, and the sample CRC code was rewritten for\n      clarity and to eliminate the requirement for the caller to do pre-\n      and post-conditioning.  Version 4.3 is a conversion of the\n      specification to RFC style.\n\n\n\nDeutsch                      Informational                      [Page 3]\n\f\nRFC 1952             GZIP File Format Specification             May 1996\n\n\n2. Detailed specification\n\n   2.1. Overall conventions\n\n      In the diagrams below, a box like this:\n\n         +---+\n         |   | <-- the vertical bars might be missing\n         +---+\n\n      represents one byte; a box like this:\n\n         +==============+\n         |              |\n         +==============+\n\n      represents a variable number of bytes.\n\n      Bytes stored within a computer do not have a \"bit order\", since\n      they are always treated as a unit.  However, a byte considered as\n      an integer between 0 and 255 does have a most- and least-\n      significant bit, and since we write numbers with the most-\n      significant digit on the left, we also write bytes with the most-\n      significant bit on the left.  In the diagrams below, we number the\n      bits of a byte so that bit 0 is the least-significant bit, i.e.,\n      the bits are numbered:\n\n         +--------+\n         |76543210|\n         +--------+\n\n      This document does not address the issue of the order in which\n      bits of a byte are transmitted on a bit-sequential medium, since\n      the data format described here is byte- rather than bit-oriented.\n\n      Within a computer, a number may occupy multiple bytes.  All\n      multi-byte numbers in the format described here are stored with\n      the least-significant byte first (at the lower memory address).\n      For example, the decimal number 520 is stored as:\n\n             0        1\n         +--------+--------+\n         |00001000|00000010|\n         +--------+--------+\n          ^        ^\n          |        |\n          |        + more significant byte = 2 x 256\n          + less significant byte = 8\n\n\n\nDeutsch                      Informational                      [Page 4]\n\f\nRFC 1952             GZIP File Format Specification             May 1996\n\n\n   2.2. File format\n\n      A gzip file consists of a series of \"members\" (compressed data\n      sets).  The format of each member is specified in the following\n      section.  The members simply appear one after another in the file,\n      with no additional information before, between, or after them.\n\n   2.3. Member format\n\n      Each member has the following structure:\n\n         +---+---+---+---+---+---+---+---+---+---+\n         |ID1|ID2|CM |FLG|     MTIME     |XFL|OS | (more-->)\n         +---+---+---+---+---+---+---+---+---+---+\n\n      (if FLG.FEXTRA set)\n\n         +---+---+=================================+\n         | XLEN  |...XLEN bytes of \"extra field\"...| (more-->)\n         +---+---+=================================+\n\n      (if FLG.FNAME set)\n\n         +=========================================+\n         |...original file name, zero-terminated...| (more-->)\n         +=========================================+\n\n      (if FLG.FCOMMENT set)\n\n         +===================================+\n         |...file comment, zero-terminated...| (more-->)\n         +===================================+\n\n      (if FLG.FHCRC set)\n\n         +---+---+\n         | CRC16 |\n         +---+---+\n\n         +=======================+\n         |...compressed blocks...| (more-->)\n         +=======================+\n\n           0   1   2   3   4   5   6   7\n         +---+---+---+---+---+---+---+---+\n         |     CRC32     |     ISIZE     |\n         +---+---+---+---+---+---+---+---+\n\n\n\n\nDeutsch                      Informational                      [Page 5]\n\f\nRFC 1952             GZIP File Format Specification             May 1996\n\n\n      2.3.1. Member header and trailer\n\n         ID1 (IDentification 1)\n         ID2 (IDentification 2)\n            These have the fixed values ID1 = 31 (0x1f, \\037), ID2 = 139\n            (0x8b, \\213), to identify the file as being in gzip format.\n\n         CM (Compression Method)\n            This identifies the compression method used in the file.  CM\n            = 0-7 are reserved.  CM = 8 denotes the \"deflate\"\n            compression method, which is the one customarily used by\n            gzip and which is documented elsewhere.\n\n         FLG (FLaGs)\n            This flag byte is divided into individual bits as follows:\n\n               bit 0   FTEXT\n               bit 1   FHCRC\n               bit 2   FEXTRA\n               bit 3   FNAME\n               bit 4   FCOMMENT\n               bit 5   reserved\n               bit 6   reserved\n               bit 7   reserved\n\n            If FTEXT is set, the file is probably ASCII text.  This is\n            an optional indication, which the compressor may set by\n            checking a small amount of the input data to see whether any\n            non-ASCII characters are present.  In case of doubt, FTEXT\n            is cleared, indicating binary data. For systems which have\n            different file formats for ascii text and binary data, the\n            decompressor can use FTEXT to choose the appropriate format.\n            We deliberately do not specify the algorithm used to set\n            this bit, since a compressor always has the option of\n            leaving it cleared and a decompressor always has the option\n            of ignoring it and letting some other program handle issues\n            of data conversion.\n\n            If FHCRC is set, a CRC16 for the gzip header is present,\n            immediately before the compressed data. The CRC16 consists\n            of the two least significant bytes of the CRC32 for all\n            bytes of the gzip header up to and not including the CRC16.\n            [The FHCRC bit was never set by versions of gzip up to\n            1.2.4, even though it was documented with a different\n            meaning in gzip 1.2.4.]\n\n            If FEXTRA is set, optional extra fields are present, as\n            described in a following section.\n\n\n\nDeutsch                      Informational                      [Page 6]\n\f\nRFC 1952             GZIP File Format Specification             May 1996\n\n\n            If FNAME is set, an original file name is present,\n            terminated by a zero byte.  The name must consist of ISO\n            8859-1 (LATIN-1) characters; on operating systems using\n            EBCDIC or any other character set for file names, the name\n            must be translated to the ISO LATIN-1 character set.  This\n            is the original name of the file being compressed, with any\n            directory components removed, and, if the file being\n            compressed is on a file system with case insensitive names,\n            forced to lower case. There is no original file name if the\n            data was compressed from a source other than a named file;\n            for example, if the source was stdin on a Unix system, there\n            is no file name.\n\n            If FCOMMENT is set, a zero-terminated file comment is\n            present.  This comment is not interpreted; it is only\n            intended for human consumption.  The comment must consist of\n            ISO 8859-1 (LATIN-1) characters.  Line breaks should be\n            denoted by a single line feed character (10 decimal).\n\n            Reserved FLG bits must be zero.\n\n         MTIME (Modification TIME)\n            This gives the most recent modification time of the original\n            file being compressed.  The time is in Unix format, i.e.,\n            seconds since 00:00:00 GMT, Jan.  1, 1970.  (Note that this\n            may cause problems for MS-DOS and other systems that use\n            local rather than Universal time.)  If the compressed data\n            did not come from a file, MTIME is set to the time at which\n            compression started.  MTIME = 0 means no time stamp is\n            available.\n\n         XFL (eXtra FLags)\n            These flags are available for use by specific compression\n            methods.  The \"deflate\" method (CM = 8) sets these flags as\n            follows:\n\n               XFL = 2 - compressor used maximum compression,\n                         slowest algorithm\n               XFL = 4 - compressor used fastest algorithm\n\n         OS (Operating System)\n            This identifies the type of file system on which compression\n            took place.  This may be useful in determining end-of-line\n            convention for text files.  The currently defined values are\n            as follows:\n\n\n\n\n\n\nDeutsch                      Informational                      [Page 7]\n\f\nRFC 1952             GZIP File Format Specification             May 1996\n\n\n                 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32)\n                 1 - Amiga\n                 2 - VMS (or OpenVMS)\n                 3 - Unix\n                 4 - VM/CMS\n                 5 - Atari TOS\n                 6 - HPFS filesystem (OS/2, NT)\n                 7 - Macintosh\n                 8 - Z-System\n                 9 - CP/M\n                10 - TOPS-20\n                11 - NTFS filesystem (NT)\n                12 - QDOS\n                13 - Acorn RISCOS\n               255 - unknown\n\n         XLEN (eXtra LENgth)\n            If FLG.FEXTRA is set, this gives the length of the optional\n            extra field.  See below for details.\n\n         CRC32 (CRC-32)\n            This contains a Cyclic Redundancy Check value of the\n            uncompressed data computed according to CRC-32 algorithm\n            used in the ISO 3309 standard and in section 8.1.1.6.2 of\n            ITU-T recommendation V.42.  (See http://www.iso.ch for\n            ordering ISO documents. See gopher://info.itu.ch for an\n            online version of ITU-T V.42.)\n\n         ISIZE (Input SIZE)\n            This contains the size of the original (uncompressed) input\n            data modulo 2^32.\n\n      2.3.1.1. Extra field\n\n         If the FLG.FEXTRA bit is set, an \"extra field\" is present in\n         the header, with total length XLEN bytes.  It consists of a\n         series of subfields, each of the form:\n\n            +---+---+---+---+==================================+\n            |SI1|SI2|  LEN  |... LEN bytes of subfield data ...|\n            +---+---+---+---+==================================+\n\n         SI1 and SI2 provide a subfield ID, typically two ASCII letters\n         with some mnemonic value.  Jean-Loup Gailly\n         <gzip@prep.ai.mit.edu> is maintaining a registry of subfield\n         IDs; please send him any subfield ID you wish to use.  Subfield\n         IDs with SI2 = 0 are reserved for future use.  The following\n         IDs are currently defined:\n\n\n\nDeutsch                      Informational                      [Page 8]\n\f\nRFC 1952             GZIP File Format Specification             May 1996\n\n\n            SI1         SI2         Data\n            ----------  ----------  ----\n            0x41 ('A')  0x70 ('P')  Apollo file type information\n\n         LEN gives the length of the subfield data, excluding the 4\n         initial bytes.\n\n      2.3.1.2. Compliance\n\n         A compliant compressor must produce files with correct ID1,\n         ID2, CM, CRC32, and ISIZE, but may set all the other fields in\n         the fixed-length part of the header to default values (255 for\n         OS, 0 for all others).  The compressor must set all reserved\n         bits to zero.\n\n         A compliant decompressor must check ID1, ID2, and CM, and\n         provide an error indication if any of these have incorrect\n         values.  It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC\n         at least so it can skip over the optional fields if they are\n         present.  It need not examine any other part of the header or\n         trailer; in particular, a decompressor may ignore FTEXT and OS\n         and always produce binary output, and still be compliant.  A\n         compliant decompressor must give an error indication if any\n         reserved bit is non-zero, since such a bit could indicate the\n         presence of a new field that would cause subsequent data to be\n         interpreted incorrectly.\n\n3. References\n\n   [1] \"Information Processing - 8-bit single-byte coded graphic\n       character sets - Part 1: Latin alphabet No.1\" (ISO 8859-1:1987).\n       The ISO 8859-1 (Latin-1) character set is a superset of 7-bit\n       ASCII. Files defining this character set are available as\n       iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/\n\n   [2] ISO 3309\n\n   [3] ITU-T recommendation V.42\n\n   [4] Deutsch, L.P.,\"DEFLATE Compressed Data Format Specification\",\n       available in ftp://ftp.uu.net/pub/archiving/zip/doc/\n\n   [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in\n       ftp://prep.ai.mit.edu/pub/gnu/\n\n   [6] Sarwate, D.V., \"Computation of Cyclic Redundancy Checks via Table\n       Look-Up\", Communications of the ACM, 31(8), pp.1008-1013.\n\n\n\n\nDeutsch                      Informational                      [Page 9]\n\f\nRFC 1952             GZIP File Format Specification             May 1996\n\n\n   [7] Schwaderer, W.D., \"CRC Calculation\", April 85 PC Tech Journal,\n       pp.118-133.\n\n   [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt,\n       describing the CRC concept.\n\n4. Security Considerations\n\n   Any data compression method involves the reduction of redundancy in\n   the data.  Consequently, any corruption of the data is likely to have\n   severe effects and be difficult to correct.  Uncompressed text, on\n   the other hand, will probably still be readable despite the presence\n   of some corrupted bytes.\n\n   It is recommended that systems using this data format provide some\n   means of validating the integrity of the compressed data, such as by\n   setting and checking the CRC-32 check value.\n\n5. Acknowledgements\n\n   Trademarks cited in this document are the property of their\n   respective owners.\n\n   Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler,\n   the related software described in this specification.  Glenn\n   Randers-Pehrson converted this document to RFC and HTML format.\n\n6. Author's Address\n\n   L. Peter Deutsch\n   Aladdin Enterprises\n   203 Santa Margarita Ave.\n   Menlo Park, CA 94025\n\n   Phone: (415) 322-0103 (AM only)\n   FAX:   (415) 322-1734\n   EMail: <ghost@aladdin.com>\n\n   Questions about the technical content of this specification can be\n   sent by email to:\n\n   Jean-Loup Gailly <gzip@prep.ai.mit.edu> and\n   Mark Adler <madler@alumni.caltech.edu>\n\n   Editorial comments on this specification can be sent by email to:\n\n   L. Peter Deutsch <ghost@aladdin.com> and\n   Glenn Randers-Pehrson <randeg@alumni.rpi.edu>\n\n\n\nDeutsch                      Informational                     [Page 10]\n\f\nRFC 1952             GZIP File Format Specification             May 1996\n\n\n7. Appendix: Jean-Loup Gailly's gzip utility\n\n   The most widely used implementation of gzip compression, and the\n   original documentation on which this specification is based, were\n   created by Jean-Loup Gailly <gzip@prep.ai.mit.edu>.  Since this\n   implementation is a de facto standard, we mention some more of its\n   features here.  Again, the material in this section is not part of\n   the specification per se, and implementations need not follow it to\n   be compliant.\n\n   When compressing or decompressing a file, gzip preserves the\n   protection, ownership, and modification time attributes on the local\n   file system, since there is no provision for representing protection\n   attributes in the gzip file format itself.  Since the file format\n   includes a modification time, the gzip decompressor provides a\n   command line switch that assigns the modification time from the file,\n   rather than the local modification time of the compressed input, to\n   the decompressed output.\n\n8. Appendix: Sample CRC Code\n\n   The following sample code represents a practical implementation of\n   the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42\n   for a formal specification.)\n\n   The sample code is in the ANSI C programming language. Non C users\n   may find it easier to read with these hints:\n\n      &      Bitwise AND operator.\n      ^      Bitwise exclusive-OR operator.\n      >>     Bitwise right shift operator. When applied to an\n             unsigned quantity, as here, right shift inserts zero\n             bit(s) at the left.\n      !      Logical NOT operator.\n      ++     \"n++\" increments the variable n.\n      0xNNN  0x introduces a hexadecimal (base 16) constant.\n             Suffix L indicates a long value (at least 32 bits).\n\n      /* Table of CRCs of all 8-bit messages. */\n      unsigned long crc_table[256];\n\n      /* Flag: has the table been computed? Initially false. */\n      int crc_table_computed = 0;\n\n      /* Make the table for a fast CRC. */\n      void make_crc_table(void)\n      {\n        unsigned long c;\n\n\n\nDeutsch                      Informational                     [Page 11]\n\f\nRFC 1952             GZIP File Format Specification             May 1996\n\n\n        int n, k;\n        for (n = 0; n < 256; n++) {\n          c = (unsigned long) n;\n          for (k = 0; k < 8; k++) {\n            if (c & 1) {\n              c = 0xedb88320L ^ (c >> 1);\n            } else {\n              c = c >> 1;\n            }\n          }\n          crc_table[n] = c;\n        }\n        crc_table_computed = 1;\n      }\n\n      /*\n         Update a running crc with the bytes buf[0..len-1] and return\n       the updated crc. The crc should be initialized to zero. Pre- and\n       post-conditioning (one's complement) is performed within this\n       function so it shouldn't be done by the caller. Usage example:\n\n         unsigned long crc = 0L;\n\n         while (read_buffer(buffer, length) != EOF) {\n           crc = update_crc(crc, buffer, length);\n         }\n         if (crc != original_crc) error();\n      */\n      unsigned long update_crc(unsigned long crc,\n                      unsigned char *buf, int len)\n      {\n        unsigned long c = crc ^ 0xffffffffL;\n        int n;\n\n        if (!crc_table_computed)\n          make_crc_table();\n        for (n = 0; n < len; n++) {\n          c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);\n        }\n        return c ^ 0xffffffffL;\n      }\n\n      /* Return the CRC of the bytes buf[0..len-1]. */\n      unsigned long crc(unsigned char *buf, int len)\n      {\n        return update_crc(0L, buf, len);\n      }\n\n\n\n\nDeutsch                      Informational                     [Page 12]\n\f\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/doc/txtvsbin.txt",
    "content": "A Fast Method for Identifying Plain Text Files\n==============================================\n\n\nIntroduction\n------------\n\nGiven a file coming from an unknown source, it is sometimes desirable\nto find out whether the format of that file is plain text.  Although\nthis may appear like a simple task, a fully accurate detection of the\nfile type requires heavy-duty semantic analysis on the file contents.\nIt is, however, possible to obtain satisfactory results by employing\nvarious heuristics.\n\nPrevious versions of PKZip and other zip-compatible compression tools\nwere using a crude detection scheme: if more than 80% (4/5) of the bytes\nfound in a certain buffer are within the range [7..127], the file is\nlabeled as plain text, otherwise it is labeled as binary.  A prominent\nlimitation of this scheme is the restriction to Latin-based alphabets.\nOther alphabets, like Greek, Cyrillic or Asian, make extensive use of\nthe bytes within the range [128..255], and texts using these alphabets\nare most often misidentified by this scheme; in other words, the rate\nof false negatives is sometimes too high, which means that the recall\nis low.  Another weakness of this scheme is a reduced precision, due to\nthe false positives that may occur when binary files containing large\namounts of textual characters are misidentified as plain text.\n\nIn this article we propose a new, simple detection scheme that features\na much increased precision and a near-100% recall.  This scheme is\ndesigned to work on ASCII, Unicode and other ASCII-derived alphabets,\nand it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.)\nand variable-sized encodings (ISO-2022, UTF-8, etc.).  Wider encodings\n(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however.\n\n\nThe Algorithm\n-------------\n\nThe algorithm works by dividing the set of bytecodes [0..255] into three\ncategories:\n- The white list of textual bytecodes:\n  9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255.\n- The gray list of tolerated bytecodes:\n  7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC).\n- The black list of undesired, non-textual bytecodes:\n  0 (NUL) to 6, 14 to 31.\n\nIf a file contains at least one byte that belongs to the white list and\nno byte that belongs to the black list, then the file is categorized as\nplain text; otherwise, it is categorized as binary.  (The boundary case,\nwhen the file is empty, automatically falls into the latter category.)\n\n\nRationale\n---------\n\nThe idea behind this algorithm relies on two observations.\n\nThe first observation is that, although the full range of 7-bit codes\n[0..127] is properly specified by the ASCII standard, most control\ncharacters in the range [0..31] are not used in practice.  The only\nwidely-used, almost universally-portable control codes are 9 (TAB),\n10 (LF) and 13 (CR).  There are a few more control codes that are\nrecognized on a reduced range of platforms and text viewers/editors:\n7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these\ncodes are rarely (if ever) used alone, without being accompanied by\nsome printable text.  Even the newer, portable text formats such as\nXML avoid using control characters outside the list mentioned here.\n\nThe second observation is that most of the binary files tend to contain\ncontrol characters, especially 0 (NUL).  Even though the older text\ndetection schemes observe the presence of non-ASCII codes from the range\n[128..255], the precision rarely has to suffer if this upper range is\nlabeled as textual, because the files that are genuinely binary tend to\ncontain both control characters and codes from the upper range.  On the\nother hand, the upper range needs to be labeled as textual, because it\nis used by virtually all ASCII extensions.  In particular, this range is\nused for encoding non-Latin scripts.\n\nSince there is no counting involved, other than simply observing the\npresence or the absence of some byte values, the algorithm produces\nconsistent results, regardless what alphabet encoding is being used.\n(If counting were involved, it could be possible to obtain different\nresults on a text encoded, say, using ISO-8859-16 versus UTF-8.)\n\nThere is an extra category of plain text files that are \"polluted\" with\none or more black-listed codes, either by mistake or by peculiar design\nconsiderations.  In such cases, a scheme that tolerates a small fraction\nof black-listed codes would provide an increased recall (i.e. more true\npositives).  This, however, incurs a reduced precision overall, since\nfalse positives are more likely to appear in binary files that contain\nlarge chunks of textual data.  Furthermore, \"polluted\" plain text should\nbe regarded as binary by general-purpose text detection schemes, because\ngeneral-purpose text processing algorithms might not be applicable.\nUnder this premise, it is safe to say that our detection method provides\na near-100% recall.\n\nExperiments have been run on many files coming from various platforms\nand applications.  We tried plain text files, system logs, source code,\nformatted office documents, compiled object code, etc.  The results\nconfirm the optimistic assumptions about the capabilities of this\nalgorithm.\n\n\n--\nCosmin Truta\nLast updated: 2006-May-28\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/examples/README.examples",
    "content": "This directory contains examples of the use of zlib and other relevant\nprograms and documentation.\n\nenough.c\n    calculation and justification of ENOUGH parameter in inftrees.h\n    - calculates the maximum table space used in inflate tree\n      construction over all possible Huffman codes\n\nfitblk.c\n    compress just enough input to nearly fill a requested output size\n    - zlib isn't designed to do this, but fitblk does it anyway\n\ngun.c\n    uncompress a gzip file\n    - illustrates the use of inflateBack() for high speed file-to-file\n      decompression using call-back functions\n    - is approximately twice as fast as gzip -d\n    - also provides Unix uncompress functionality, again twice as fast\n\ngzappend.c\n    append to a gzip file\n    - illustrates the use of the Z_BLOCK flush parameter for inflate()\n    - illustrates the use of deflatePrime() to start at any bit\n\ngzjoin.c\n    join gzip files without recalculating the crc or recompressing\n    - illustrates the use of the Z_BLOCK flush parameter for inflate()\n    - illustrates the use of crc32_combine()\n\ngzlog.c\ngzlog.h\n    efficiently and robustly maintain a message log file in gzip format\n    - illustrates use of raw deflate, Z_PARTIAL_FLUSH, deflatePrime(),\n      and deflateSetDictionary()\n    - illustrates use of a gzip header extra field\n\nzlib_how.html\n    painfully comprehensive description of zpipe.c (see below)\n    - describes in excruciating detail the use of deflate() and inflate()\n\nzpipe.c\n    reads and writes zlib streams from stdin to stdout\n    - illustrates the proper use of deflate() and inflate()\n    - deeply commented in zlib_how.html (see above)\n\nzran.c\n    index a zlib or gzip stream and randomly access it\n    - illustrates the use of Z_BLOCK, inflatePrime(), and\n      inflateSetDictionary() to provide random access\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/examples/enough.c",
    "content": "/* enough.c -- determine the maximum size of inflate's Huffman code tables over\n * all possible valid and complete Huffman codes, subject to a length limit.\n * Copyright (C) 2007, 2008, 2012 Mark Adler\n * Version 1.4  18 August 2012  Mark Adler\n */\n\n/* Version history:\n   1.0   3 Jan 2007  First version (derived from codecount.c version 1.4)\n   1.1   4 Jan 2007  Use faster incremental table usage computation\n                     Prune examine() search on previously visited states\n   1.2   5 Jan 2007  Comments clean up\n                     As inflate does, decrease root for short codes\n                     Refuse cases where inflate would increase root\n   1.3  17 Feb 2008  Add argument for initial root table size\n                     Fix bug for initial root table size == max - 1\n                     Use a macro to compute the history index\n   1.4  18 Aug 2012  Avoid shifts more than bits in type (caused endless loop!)\n                     Clean up comparisons of different types\n                     Clean up code indentation\n */\n\n/*\n   Examine all possible Huffman codes for a given number of symbols and a\n   maximum code length in bits to determine the maximum table size for zilb's\n   inflate.  Only complete Huffman codes are counted.\n\n   Two codes are considered distinct if the vectors of the number of codes per\n   length are not identical.  So permutations of the symbol assignments result\n   in the same code for the counting, as do permutations of the assignments of\n   the bit values to the codes (i.e. only canonical codes are counted).\n\n   We build a code from shorter to longer lengths, determining how many symbols\n   are coded at each length.  At each step, we have how many symbols remain to\n   be coded, what the last code length used was, and how many bit patterns of\n   that length remain unused. Then we add one to the code length and double the\n   number of unused patterns to graduate to the next code length.  We then\n   assign all portions of the remaining symbols to that code length that\n   preserve the properties of a correct and eventually complete code.  Those\n   properties are: we cannot use more bit patterns than are available; and when\n   all the symbols are used, there are exactly zero possible bit patterns\n   remaining.\n\n   The inflate Huffman decoding algorithm uses two-level lookup tables for\n   speed.  There is a single first-level table to decode codes up to root bits\n   in length (root == 9 in the current inflate implementation).  The table\n   has 1 << root entries and is indexed by the next root bits of input.  Codes\n   shorter than root bits have replicated table entries, so that the correct\n   entry is pointed to regardless of the bits that follow the short code.  If\n   the code is longer than root bits, then the table entry points to a second-\n   level table.  The size of that table is determined by the longest code with\n   that root-bit prefix.  If that longest code has length len, then the table\n   has size 1 << (len - root), to index the remaining bits in that set of\n   codes.  Each subsequent root-bit prefix then has its own sub-table.  The\n   total number of table entries required by the code is calculated\n   incrementally as the number of codes at each bit length is populated.  When\n   all of the codes are shorter than root bits, then root is reduced to the\n   longest code length, resulting in a single, smaller, one-level table.\n\n   The inflate algorithm also provides for small values of root (relative to\n   the log2 of the number of symbols), where the shortest code has more bits\n   than root.  In that case, root is increased to the length of the shortest\n   code.  This program, by design, does not handle that case, so it is verified\n   that the number of symbols is less than 2^(root + 1).\n\n   In order to speed up the examination (by about ten orders of magnitude for\n   the default arguments), the intermediate states in the build-up of a code\n   are remembered and previously visited branches are pruned.  The memory\n   required for this will increase rapidly with the total number of symbols and\n   the maximum code length in bits.  However this is a very small price to pay\n   for the vast speedup.\n\n   First, all of the possible Huffman codes are counted, and reachable\n   intermediate states are noted by a non-zero count in a saved-results array.\n   Second, the intermediate states that lead to (root + 1) bit or longer codes\n   are used to look at all sub-codes from those junctures for their inflate\n   memory usage.  (The amount of memory used is not affected by the number of\n   codes of root bits or less in length.)  Third, the visited states in the\n   construction of those sub-codes and the associated calculation of the table\n   size is recalled in order to avoid recalculating from the same juncture.\n   Beginning the code examination at (root + 1) bit codes, which is enabled by\n   identifying the reachable nodes, accounts for about six of the orders of\n   magnitude of improvement for the default arguments.  About another four\n   orders of magnitude come from not revisiting previous states.  Out of\n   approximately 2x10^16 possible Huffman codes, only about 2x10^6 sub-codes\n   need to be examined to cover all of the possible table memory usage cases\n   for the default arguments of 286 symbols limited to 15-bit codes.\n\n   Note that an unsigned long long type is used for counting.  It is quite easy\n   to exceed the capacity of an eight-byte integer with a large number of\n   symbols and a large maximum code length, so multiple-precision arithmetic\n   would need to replace the unsigned long long arithmetic in that case.  This\n   program will abort if an overflow occurs.  The big_t type identifies where\n   the counting takes place.\n\n   An unsigned long long type is also used for calculating the number of\n   possible codes remaining at the maximum length.  This limits the maximum\n   code length to the number of bits in a long long minus the number of bits\n   needed to represent the symbols in a flat code.  The code_t type identifies\n   where the bit pattern counting takes place.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n\n#define local static\n\n/* special data types */\ntypedef unsigned long long big_t;   /* type for code counting */\ntypedef unsigned long long code_t;  /* type for bit pattern counting */\nstruct tab {                        /* type for been here check */\n    size_t len;         /* length of bit vector in char's */\n    char *vec;          /* allocated bit vector */\n};\n\n/* The array for saving results, num[], is indexed with this triplet:\n\n      syms: number of symbols remaining to code\n      left: number of available bit patterns at length len\n      len: number of bits in the codes currently being assigned\n\n   Those indices are constrained thusly when saving results:\n\n      syms: 3..totsym (totsym == total symbols to code)\n      left: 2..syms - 1, but only the evens (so syms == 8 -> 2, 4, 6)\n      len: 1..max - 1 (max == maximum code length in bits)\n\n   syms == 2 is not saved since that immediately leads to a single code.  left\n   must be even, since it represents the number of available bit patterns at\n   the current length, which is double the number at the previous length.\n   left ends at syms-1 since left == syms immediately results in a single code.\n   (left > sym is not allowed since that would result in an incomplete code.)\n   len is less than max, since the code completes immediately when len == max.\n\n   The offset into the array is calculated for the three indices with the\n   first one (syms) being outermost, and the last one (len) being innermost.\n   We build the array with length max-1 lists for the len index, with syms-3\n   of those for each symbol.  There are totsym-2 of those, with each one\n   varying in length as a function of sym.  See the calculation of index in\n   count() for the index, and the calculation of size in main() for the size\n   of the array.\n\n   For the deflate example of 286 symbols limited to 15-bit codes, the array\n   has 284,284 entries, taking up 2.17 MB for an 8-byte big_t.  More than\n   half of the space allocated for saved results is actually used -- not all\n   possible triplets are reached in the generation of valid Huffman codes.\n */\n\n/* The array for tracking visited states, done[], is itself indexed identically\n   to the num[] array as described above for the (syms, left, len) triplet.\n   Each element in the array is further indexed by the (mem, rem) doublet,\n   where mem is the amount of inflate table space used so far, and rem is the\n   remaining unused entries in the current inflate sub-table.  Each indexed\n   element is simply one bit indicating whether the state has been visited or\n   not.  Since the ranges for mem and rem are not known a priori, each bit\n   vector is of a variable size, and grows as needed to accommodate the visited\n   states.  mem and rem are used to calculate a single index in a triangular\n   array.  Since the range of mem is expected in the default case to be about\n   ten times larger than the range of rem, the array is skewed to reduce the\n   memory usage, with eight times the range for mem than for rem.  See the\n   calculations for offset and bit in beenhere() for the details.\n\n   For the deflate example of 286 symbols limited to 15-bit codes, the bit\n   vectors grow to total approximately 21 MB, in addition to the 4.3 MB done[]\n   array itself.\n */\n\n/* Globals to avoid propagating constants or constant pointers recursively */\nlocal int max;          /* maximum allowed bit length for the codes */\nlocal int root;         /* size of base code table in bits */\nlocal int large;        /* largest code table so far */\nlocal size_t size;      /* number of elements in num and done */\nlocal int *code;        /* number of symbols assigned to each bit length */\nlocal big_t *num;       /* saved results array for code counting */\nlocal struct tab *done; /* states already evaluated array */\n\n/* Index function for num[] and done[] */\n#define INDEX(i,j,k) (((size_t)((i-1)>>1)*((i-2)>>1)+(j>>1)-1)*(max-1)+k-1)\n\n/* Free allocated space.  Uses globals code, num, and done. */\nlocal void cleanup(void)\n{\n    size_t n;\n\n    if (done != NULL) {\n        for (n = 0; n < size; n++)\n            if (done[n].len)\n                free(done[n].vec);\n        free(done);\n    }\n    if (num != NULL)\n        free(num);\n    if (code != NULL)\n        free(code);\n}\n\n/* Return the number of possible Huffman codes using bit patterns of lengths\n   len through max inclusive, coding syms symbols, with left bit patterns of\n   length len unused -- return -1 if there is an overflow in the counting.\n   Keep a record of previous results in num to prevent repeating the same\n   calculation.  Uses the globals max and num. */\nlocal big_t count(int syms, int len, int left)\n{\n    big_t sum;          /* number of possible codes from this juncture */\n    big_t got;          /* value returned from count() */\n    int least;          /* least number of syms to use at this juncture */\n    int most;           /* most number of syms to use at this juncture */\n    int use;            /* number of bit patterns to use in next call */\n    size_t index;       /* index of this case in *num */\n\n    /* see if only one possible code */\n    if (syms == left)\n        return 1;\n\n    /* note and verify the expected state */\n    assert(syms > left && left > 0 && len < max);\n\n    /* see if we've done this one already */\n    index = INDEX(syms, left, len);\n    got = num[index];\n    if (got)\n        return got;         /* we have -- return the saved result */\n\n    /* we need to use at least this many bit patterns so that the code won't be\n       incomplete at the next length (more bit patterns than symbols) */\n    least = (left << 1) - syms;\n    if (least < 0)\n        least = 0;\n\n    /* we can use at most this many bit patterns, lest there not be enough\n       available for the remaining symbols at the maximum length (if there were\n       no limit to the code length, this would become: most = left - 1) */\n    most = (((code_t)left << (max - len)) - syms) /\n            (((code_t)1 << (max - len)) - 1);\n\n    /* count all possible codes from this juncture and add them up */\n    sum = 0;\n    for (use = least; use <= most; use++) {\n        got = count(syms - use, len + 1, (left - use) << 1);\n        sum += got;\n        if (got == (big_t)0 - 1 || sum < got)   /* overflow */\n            return (big_t)0 - 1;\n    }\n\n    /* verify that all recursive calls are productive */\n    assert(sum != 0);\n\n    /* save the result and return it */\n    num[index] = sum;\n    return sum;\n}\n\n/* Return true if we've been here before, set to true if not.  Set a bit in a\n   bit vector to indicate visiting this state.  Each (syms,len,left) state\n   has a variable size bit vector indexed by (mem,rem).  The bit vector is\n   lengthened if needed to allow setting the (mem,rem) bit. */\nlocal int beenhere(int syms, int len, int left, int mem, int rem)\n{\n    size_t index;       /* index for this state's bit vector */\n    size_t offset;      /* offset in this state's bit vector */\n    int bit;            /* mask for this state's bit */\n    size_t length;      /* length of the bit vector in bytes */\n    char *vector;       /* new or enlarged bit vector */\n\n    /* point to vector for (syms,left,len), bit in vector for (mem,rem) */\n    index = INDEX(syms, left, len);\n    mem -= 1 << root;\n    offset = (mem >> 3) + rem;\n    offset = ((offset * (offset + 1)) >> 1) + rem;\n    bit = 1 << (mem & 7);\n\n    /* see if we've been here */\n    length = done[index].len;\n    if (offset < length && (done[index].vec[offset] & bit) != 0)\n        return 1;       /* done this! */\n\n    /* we haven't been here before -- set the bit to show we have now */\n\n    /* see if we need to lengthen the vector in order to set the bit */\n    if (length <= offset) {\n        /* if we have one already, enlarge it, zero out the appended space */\n        if (length) {\n            do {\n                length <<= 1;\n            } while (length <= offset);\n            vector = realloc(done[index].vec, length);\n            if (vector != NULL)\n                memset(vector + done[index].len, 0, length - done[index].len);\n        }\n\n        /* otherwise we need to make a new vector and zero it out */\n        else {\n            length = 1 << (len - root);\n            while (length <= offset)\n                length <<= 1;\n            vector = calloc(length, sizeof(char));\n        }\n\n        /* in either case, bail if we can't get the memory */\n        if (vector == NULL) {\n            fputs(\"abort: unable to allocate enough memory\\n\", stderr);\n            cleanup();\n            exit(1);\n        }\n\n        /* install the new vector */\n        done[index].len = length;\n        done[index].vec = vector;\n    }\n\n    /* set the bit */\n    done[index].vec[offset] |= bit;\n    return 0;\n}\n\n/* Examine all possible codes from the given node (syms, len, left).  Compute\n   the amount of memory required to build inflate's decoding tables, where the\n   number of code structures used so far is mem, and the number remaining in\n   the current sub-table is rem.  Uses the globals max, code, root, large, and\n   done. */\nlocal void examine(int syms, int len, int left, int mem, int rem)\n{\n    int least;          /* least number of syms to use at this juncture */\n    int most;           /* most number of syms to use at this juncture */\n    int use;            /* number of bit patterns to use in next call */\n\n    /* see if we have a complete code */\n    if (syms == left) {\n        /* set the last code entry */\n        code[len] = left;\n\n        /* complete computation of memory used by this code */\n        while (rem < left) {\n            left -= rem;\n            rem = 1 << (len - root);\n            mem += rem;\n        }\n        assert(rem == left);\n\n        /* if this is a new maximum, show the entries used and the sub-code */\n        if (mem > large) {\n            large = mem;\n            printf(\"max %d: \", mem);\n            for (use = root + 1; use <= max; use++)\n                if (code[use])\n                    printf(\"%d[%d] \", code[use], use);\n            putchar('\\n');\n            fflush(stdout);\n        }\n\n        /* remove entries as we drop back down in the recursion */\n        code[len] = 0;\n        return;\n    }\n\n    /* prune the tree if we can */\n    if (beenhere(syms, len, left, mem, rem))\n        return;\n\n    /* we need to use at least this many bit patterns so that the code won't be\n       incomplete at the next length (more bit patterns than symbols) */\n    least = (left << 1) - syms;\n    if (least < 0)\n        least = 0;\n\n    /* we can use at most this many bit patterns, lest there not be enough\n       available for the remaining symbols at the maximum length (if there were\n       no limit to the code length, this would become: most = left - 1) */\n    most = (((code_t)left << (max - len)) - syms) /\n            (((code_t)1 << (max - len)) - 1);\n\n    /* occupy least table spaces, creating new sub-tables as needed */\n    use = least;\n    while (rem < use) {\n        use -= rem;\n        rem = 1 << (len - root);\n        mem += rem;\n    }\n    rem -= use;\n\n    /* examine codes from here, updating table space as we go */\n    for (use = least; use <= most; use++) {\n        code[len] = use;\n        examine(syms - use, len + 1, (left - use) << 1,\n                mem + (rem ? 1 << (len - root) : 0), rem << 1);\n        if (rem == 0) {\n            rem = 1 << (len - root);\n            mem += rem;\n        }\n        rem--;\n    }\n\n    /* remove entries as we drop back down in the recursion */\n    code[len] = 0;\n}\n\n/* Look at all sub-codes starting with root + 1 bits.  Look at only the valid\n   intermediate code states (syms, left, len).  For each completed code,\n   calculate the amount of memory required by inflate to build the decoding\n   tables. Find the maximum amount of memory required and show the code that\n   requires that maximum.  Uses the globals max, root, and num. */\nlocal void enough(int syms)\n{\n    int n;              /* number of remaing symbols for this node */\n    int left;           /* number of unused bit patterns at this length */\n    size_t index;       /* index of this case in *num */\n\n    /* clear code */\n    for (n = 0; n <= max; n++)\n        code[n] = 0;\n\n    /* look at all (root + 1) bit and longer codes */\n    large = 1 << root;              /* base table */\n    if (root < max)                 /* otherwise, there's only a base table */\n        for (n = 3; n <= syms; n++)\n            for (left = 2; left < n; left += 2)\n            {\n                /* look at all reachable (root + 1) bit nodes, and the\n                   resulting codes (complete at root + 2 or more) */\n                index = INDEX(n, left, root + 1);\n                if (root + 1 < max && num[index])       /* reachable node */\n                    examine(n, root + 1, left, 1 << root, 0);\n\n                /* also look at root bit codes with completions at root + 1\n                   bits (not saved in num, since complete), just in case */\n                if (num[index - 1] && n <= left << 1)\n                    examine((n - left) << 1, root + 1, (n - left) << 1,\n                            1 << root, 0);\n            }\n\n    /* done */\n    printf(\"done: maximum of %d table entries\\n\", large);\n}\n\n/*\n   Examine and show the total number of possible Huffman codes for a given\n   maximum number of symbols, initial root table size, and maximum code length\n   in bits -- those are the command arguments in that order.  The default\n   values are 286, 9, and 15 respectively, for the deflate literal/length code.\n   The possible codes are counted for each number of coded symbols from two to\n   the maximum.  The counts for each of those and the total number of codes are\n   shown.  The maximum number of inflate table entires is then calculated\n   across all possible codes.  Each new maximum number of table entries and the\n   associated sub-code (starting at root + 1 == 10 bits) is shown.\n\n   To count and examine Huffman codes that are not length-limited, provide a\n   maximum length equal to the number of symbols minus one.\n\n   For the deflate literal/length code, use \"enough\".  For the deflate distance\n   code, use \"enough 30 6\".\n\n   This uses the %llu printf format to print big_t numbers, which assumes that\n   big_t is an unsigned long long.  If the big_t type is changed (for example\n   to a multiple precision type), the method of printing will also need to be\n   updated.\n */\nint main(int argc, char **argv)\n{\n    int syms;           /* total number of symbols to code */\n    int n;              /* number of symbols to code for this run */\n    big_t got;          /* return value of count() */\n    big_t sum;          /* accumulated number of codes over n */\n    code_t word;        /* for counting bits in code_t */\n\n    /* set up globals for cleanup() */\n    code = NULL;\n    num = NULL;\n    done = NULL;\n\n    /* get arguments -- default to the deflate literal/length code */\n    syms = 286;\n    root = 9;\n    max = 15;\n    if (argc > 1) {\n        syms = atoi(argv[1]);\n        if (argc > 2) {\n            root = atoi(argv[2]);\n            if (argc > 3)\n                max = atoi(argv[3]);\n        }\n    }\n    if (argc > 4 || syms < 2 || root < 1 || max < 1) {\n        fputs(\"invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\\n\",\n              stderr);\n        return 1;\n    }\n\n    /* if not restricting the code length, the longest is syms - 1 */\n    if (max > syms - 1)\n        max = syms - 1;\n\n    /* determine the number of bits in a code_t */\n    for (n = 0, word = 1; word; n++, word <<= 1)\n        ;\n\n    /* make sure that the calculation of most will not overflow */\n    if (max > n || (code_t)(syms - 2) >= (((code_t)0 - 1) >> (max - 1))) {\n        fputs(\"abort: code length too long for internal types\\n\", stderr);\n        return 1;\n    }\n\n    /* reject impossible code requests */\n    if ((code_t)(syms - 1) > ((code_t)1 << max) - 1) {\n        fprintf(stderr, \"%d symbols cannot be coded in %d bits\\n\",\n                syms, max);\n        return 1;\n    }\n\n    /* allocate code vector */\n    code = calloc(max + 1, sizeof(int));\n    if (code == NULL) {\n        fputs(\"abort: unable to allocate enough memory\\n\", stderr);\n        return 1;\n    }\n\n    /* determine size of saved results array, checking for overflows,\n       allocate and clear the array (set all to zero with calloc()) */\n    if (syms == 2)              /* iff max == 1 */\n        num = NULL;             /* won't be saving any results */\n    else {\n        size = syms >> 1;\n        if (size > ((size_t)0 - 1) / (n = (syms - 1) >> 1) ||\n                (size *= n, size > ((size_t)0 - 1) / (n = max - 1)) ||\n                (size *= n, size > ((size_t)0 - 1) / sizeof(big_t)) ||\n                (num = calloc(size, sizeof(big_t))) == NULL) {\n            fputs(\"abort: unable to allocate enough memory\\n\", stderr);\n            cleanup();\n            return 1;\n        }\n    }\n\n    /* count possible codes for all numbers of symbols, add up counts */\n    sum = 0;\n    for (n = 2; n <= syms; n++) {\n        got = count(n, 1, 2);\n        sum += got;\n        if (got == (big_t)0 - 1 || sum < got) {     /* overflow */\n            fputs(\"abort: can't count that high!\\n\", stderr);\n            cleanup();\n            return 1;\n        }\n        printf(\"%llu %d-codes\\n\", got, n);\n    }\n    printf(\"%llu total codes for 2 to %d symbols\", sum, syms);\n    if (max < syms - 1)\n        printf(\" (%d-bit length limit)\\n\", max);\n    else\n        puts(\" (no length limit)\");\n\n    /* allocate and clear done array for beenhere() */\n    if (syms == 2)\n        done = NULL;\n    else if (size > ((size_t)0 - 1) / sizeof(struct tab) ||\n             (done = calloc(size, sizeof(struct tab))) == NULL) {\n        fputs(\"abort: unable to allocate enough memory\\n\", stderr);\n        cleanup();\n        return 1;\n    }\n\n    /* find and show maximum inflate table usage */\n    if (root > max)                 /* reduce root to max length */\n        root = max;\n    if ((code_t)syms < ((code_t)1 << (root + 1)))\n        enough(syms);\n    else\n        puts(\"cannot handle minimum code lengths > root\");\n\n    /* done */\n    cleanup();\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/examples/fitblk.c",
    "content": "/* fitblk.c: example of fitting compressed output to a specified size\n   Not copyrighted -- provided to the public domain\n   Version 1.1  25 November 2004  Mark Adler */\n\n/* Version history:\n   1.0  24 Nov 2004  First version\n   1.1  25 Nov 2004  Change deflateInit2() to deflateInit()\n                     Use fixed-size, stack-allocated raw buffers\n                     Simplify code moving compression to subroutines\n                     Use assert() for internal errors\n                     Add detailed description of approach\n */\n\n/* Approach to just fitting a requested compressed size:\n\n   fitblk performs three compression passes on a portion of the input\n   data in order to determine how much of that input will compress to\n   nearly the requested output block size.  The first pass generates\n   enough deflate blocks to produce output to fill the requested\n   output size plus a specfied excess amount (see the EXCESS define\n   below).  The last deflate block may go quite a bit past that, but\n   is discarded.  The second pass decompresses and recompresses just\n   the compressed data that fit in the requested plus excess sized\n   buffer.  The deflate process is terminated after that amount of\n   input, which is less than the amount consumed on the first pass.\n   The last deflate block of the result will be of a comparable size\n   to the final product, so that the header for that deflate block and\n   the compression ratio for that block will be about the same as in\n   the final product.  The third compression pass decompresses the\n   result of the second step, but only the compressed data up to the\n   requested size minus an amount to allow the compressed stream to\n   complete (see the MARGIN define below).  That will result in a\n   final compressed stream whose length is less than or equal to the\n   requested size.  Assuming sufficient input and a requested size\n   greater than a few hundred bytes, the shortfall will typically be\n   less than ten bytes.\n\n   If the input is short enough that the first compression completes\n   before filling the requested output size, then that compressed\n   stream is return with no recompression.\n\n   EXCESS is chosen to be just greater than the shortfall seen in a\n   two pass approach similar to the above.  That shortfall is due to\n   the last deflate block compressing more efficiently with a smaller\n   header on the second pass.  EXCESS is set to be large enough so\n   that there is enough uncompressed data for the second pass to fill\n   out the requested size, and small enough so that the final deflate\n   block of the second pass will be close in size to the final deflate\n   block of the third and final pass.  MARGIN is chosen to be just\n   large enough to assure that the final compression has enough room\n   to complete in all cases.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <assert.h>\n#include \"zlib.h\"\n\n#define local static\n\n/* print nastygram and leave */\nlocal void quit(char *why)\n{\n    fprintf(stderr, \"fitblk abort: %s\\n\", why);\n    exit(1);\n}\n\n#define RAWLEN 4096    /* intermediate uncompressed buffer size */\n\n/* compress from file to def until provided buffer is full or end of\n   input reached; return last deflate() return value, or Z_ERRNO if\n   there was read error on the file */\nlocal int partcompress(FILE *in, z_streamp def)\n{\n    int ret, flush;\n    unsigned char raw[RAWLEN];\n\n    flush = Z_NO_FLUSH;\n    do {\n        def->avail_in = fread(raw, 1, RAWLEN, in);\n        if (ferror(in))\n            return Z_ERRNO;\n        def->next_in = raw;\n        if (feof(in))\n            flush = Z_FINISH;\n        ret = deflate(def, flush);\n        assert(ret != Z_STREAM_ERROR);\n    } while (def->avail_out != 0 && flush == Z_NO_FLUSH);\n    return ret;\n}\n\n/* recompress from inf's input to def's output; the input for inf and\n   the output for def are set in those structures before calling;\n   return last deflate() return value, or Z_MEM_ERROR if inflate()\n   was not able to allocate enough memory when it needed to */\nlocal int recompress(z_streamp inf, z_streamp def)\n{\n    int ret, flush;\n    unsigned char raw[RAWLEN];\n\n    flush = Z_NO_FLUSH;\n    do {\n        /* decompress */\n        inf->avail_out = RAWLEN;\n        inf->next_out = raw;\n        ret = inflate(inf, Z_NO_FLUSH);\n        assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR &&\n               ret != Z_NEED_DICT);\n        if (ret == Z_MEM_ERROR)\n            return ret;\n\n        /* compress what was decompresed until done or no room */\n        def->avail_in = RAWLEN - inf->avail_out;\n        def->next_in = raw;\n        if (inf->avail_out != 0)\n            flush = Z_FINISH;\n        ret = deflate(def, flush);\n        assert(ret != Z_STREAM_ERROR);\n    } while (ret != Z_STREAM_END && def->avail_out != 0);\n    return ret;\n}\n\n#define EXCESS 256      /* empirically determined stream overage */\n#define MARGIN 8        /* amount to back off for completion */\n\n/* compress from stdin to fixed-size block on stdout */\nint main(int argc, char **argv)\n{\n    int ret;                /* return code */\n    unsigned size;          /* requested fixed output block size */\n    unsigned have;          /* bytes written by deflate() call */\n    unsigned char *blk;     /* intermediate and final stream */\n    unsigned char *tmp;     /* close to desired size stream */\n    z_stream def, inf;      /* zlib deflate and inflate states */\n\n    /* get requested output size */\n    if (argc != 2)\n        quit(\"need one argument: size of output block\");\n    ret = strtol(argv[1], argv + 1, 10);\n    if (argv[1][0] != 0)\n        quit(\"argument must be a number\");\n    if (ret < 8)            /* 8 is minimum zlib stream size */\n        quit(\"need positive size of 8 or greater\");\n    size = (unsigned)ret;\n\n    /* allocate memory for buffers and compression engine */\n    blk = malloc(size + EXCESS);\n    def.zalloc = Z_NULL;\n    def.zfree = Z_NULL;\n    def.opaque = Z_NULL;\n    ret = deflateInit(&def, Z_DEFAULT_COMPRESSION);\n    if (ret != Z_OK || blk == NULL)\n        quit(\"out of memory\");\n\n    /* compress from stdin until output full, or no more input */\n    def.avail_out = size + EXCESS;\n    def.next_out = blk;\n    ret = partcompress(stdin, &def);\n    if (ret == Z_ERRNO)\n        quit(\"error reading input\");\n\n    /* if it all fit, then size was undersubscribed -- done! */\n    if (ret == Z_STREAM_END && def.avail_out >= EXCESS) {\n        /* write block to stdout */\n        have = size + EXCESS - def.avail_out;\n        if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))\n            quit(\"error writing output\");\n\n        /* clean up and print results to stderr */\n        ret = deflateEnd(&def);\n        assert(ret != Z_STREAM_ERROR);\n        free(blk);\n        fprintf(stderr,\n                \"%u bytes unused out of %u requested (all input)\\n\",\n                size - have, size);\n        return 0;\n    }\n\n    /* it didn't all fit -- set up for recompression */\n    inf.zalloc = Z_NULL;\n    inf.zfree = Z_NULL;\n    inf.opaque = Z_NULL;\n    inf.avail_in = 0;\n    inf.next_in = Z_NULL;\n    ret = inflateInit(&inf);\n    tmp = malloc(size + EXCESS);\n    if (ret != Z_OK || tmp == NULL)\n        quit(\"out of memory\");\n    ret = deflateReset(&def);\n    assert(ret != Z_STREAM_ERROR);\n\n    /* do first recompression close to the right amount */\n    inf.avail_in = size + EXCESS;\n    inf.next_in = blk;\n    def.avail_out = size + EXCESS;\n    def.next_out = tmp;\n    ret = recompress(&inf, &def);\n    if (ret == Z_MEM_ERROR)\n        quit(\"out of memory\");\n\n    /* set up for next reocmpression */\n    ret = inflateReset(&inf);\n    assert(ret != Z_STREAM_ERROR);\n    ret = deflateReset(&def);\n    assert(ret != Z_STREAM_ERROR);\n\n    /* do second and final recompression (third compression) */\n    inf.avail_in = size - MARGIN;   /* assure stream will complete */\n    inf.next_in = tmp;\n    def.avail_out = size;\n    def.next_out = blk;\n    ret = recompress(&inf, &def);\n    if (ret == Z_MEM_ERROR)\n        quit(\"out of memory\");\n    assert(ret == Z_STREAM_END);    /* otherwise MARGIN too small */\n\n    /* done -- write block to stdout */\n    have = size - def.avail_out;\n    if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))\n        quit(\"error writing output\");\n\n    /* clean up and print results to stderr */\n    free(tmp);\n    ret = inflateEnd(&inf);\n    assert(ret != Z_STREAM_ERROR);\n    ret = deflateEnd(&def);\n    assert(ret != Z_STREAM_ERROR);\n    free(blk);\n    fprintf(stderr,\n            \"%u bytes unused out of %u requested (%lu input)\\n\",\n            size - have, size, def.total_in);\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/examples/gun.c",
    "content": "/* gun.c -- simple gunzip to give an example of the use of inflateBack()\n * Copyright (C) 2003, 2005, 2008, 2010, 2012 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n   Version 1.7  12 August 2012  Mark Adler */\n\n/* Version history:\n   1.0  16 Feb 2003  First version for testing of inflateBack()\n   1.1  21 Feb 2005  Decompress concatenated gzip streams\n                     Remove use of \"this\" variable (C++ keyword)\n                     Fix return value for in()\n                     Improve allocation failure checking\n                     Add typecasting for void * structures\n                     Add -h option for command version and usage\n                     Add a bunch of comments\n   1.2  20 Mar 2005  Add Unix compress (LZW) decompression\n                     Copy file attributes from input file to output file\n   1.3  12 Jun 2005  Add casts for error messages [Oberhumer]\n   1.4   8 Dec 2006  LZW decompression speed improvements\n   1.5   9 Feb 2008  Avoid warning in latest version of gcc\n   1.6  17 Jan 2010  Avoid signed/unsigned comparison warnings\n   1.7  12 Aug 2012  Update for z_const usage in zlib 1.2.8\n */\n\n/*\n   gun [ -t ] [ name ... ]\n\n   decompresses the data in the named gzip files.  If no arguments are given,\n   gun will decompress from stdin to stdout.  The names must end in .gz, -gz,\n   .z, -z, _z, or .Z.  The uncompressed data will be written to a file name\n   with the suffix stripped.  On success, the original file is deleted.  On\n   failure, the output file is deleted.  For most failures, the command will\n   continue to process the remaining names on the command line.  A memory\n   allocation failure will abort the command.  If -t is specified, then the\n   listed files or stdin will be tested as gzip files for integrity (without\n   checking for a proper suffix), no output will be written, and no files\n   will be deleted.\n\n   Like gzip, gun allows concatenated gzip streams and will decompress them,\n   writing all of the uncompressed data to the output.  Unlike gzip, gun allows\n   an empty file on input, and will produce no error writing an empty output\n   file.\n\n   gun will also decompress files made by Unix compress, which uses LZW\n   compression.  These files are automatically detected by virtue of their\n   magic header bytes.  Since the end of Unix compress stream is marked by the\n   end-of-file, they cannot be concantenated.  If a Unix compress stream is\n   encountered in an input file, it is the last stream in that file.\n\n   Like gunzip and uncompress, the file attributes of the orignal compressed\n   file are maintained in the final uncompressed file, to the extent that the\n   user permissions allow it.\n\n   On my Mac OS X PowerPC G4, gun is almost twice as fast as gunzip (version\n   1.2.4) is on the same file, when gun is linked with zlib 1.2.2.  Also the\n   LZW decompression provided by gun is about twice as fast as the standard\n   Unix uncompress command.\n */\n\n/* external functions and related types and constants */\n#include <stdio.h>          /* fprintf() */\n#include <stdlib.h>         /* malloc(), free() */\n#include <string.h>         /* strerror(), strcmp(), strlen(), memcpy() */\n#include <errno.h>          /* errno */\n#include <fcntl.h>          /* open() */\n#include <unistd.h>         /* read(), write(), close(), chown(), unlink() */\n#include <sys/types.h>\n#include <sys/stat.h>       /* stat(), chmod() */\n#include <utime.h>          /* utime() */\n#include \"zlib.h\"           /* inflateBackInit(), inflateBack(), */\n                            /* inflateBackEnd(), crc32() */\n\n/* function declaration */\n#define local static\n\n/* buffer constants */\n#define SIZE 32768U         /* input and output buffer sizes */\n#define PIECE 16384         /* limits i/o chunks for 16-bit int case */\n\n/* structure for infback() to pass to input function in() -- it maintains the\n   input file and a buffer of size SIZE */\nstruct ind {\n    int infile;\n    unsigned char *inbuf;\n};\n\n/* Load input buffer, assumed to be empty, and return bytes loaded and a\n   pointer to them.  read() is called until the buffer is full, or until it\n   returns end-of-file or error.  Return 0 on error. */\nlocal unsigned in(void *in_desc, z_const unsigned char **buf)\n{\n    int ret;\n    unsigned len;\n    unsigned char *next;\n    struct ind *me = (struct ind *)in_desc;\n\n    next = me->inbuf;\n    *buf = next;\n    len = 0;\n    do {\n        ret = PIECE;\n        if ((unsigned)ret > SIZE - len)\n            ret = (int)(SIZE - len);\n        ret = (int)read(me->infile, next, ret);\n        if (ret == -1) {\n            len = 0;\n            break;\n        }\n        next += ret;\n        len += ret;\n    } while (ret != 0 && len < SIZE);\n    return len;\n}\n\n/* structure for infback() to pass to output function out() -- it maintains the\n   output file, a running CRC-32 check on the output and the total number of\n   bytes output, both for checking against the gzip trailer.  (The length in\n   the gzip trailer is stored modulo 2^32, so it's ok if a long is 32 bits and\n   the output is greater than 4 GB.) */\nstruct outd {\n    int outfile;\n    int check;                  /* true if checking crc and total */\n    unsigned long crc;\n    unsigned long total;\n};\n\n/* Write output buffer and update the CRC-32 and total bytes written.  write()\n   is called until all of the output is written or an error is encountered.\n   On success out() returns 0.  For a write failure, out() returns 1.  If the\n   output file descriptor is -1, then nothing is written.\n */\nlocal int out(void *out_desc, unsigned char *buf, unsigned len)\n{\n    int ret;\n    struct outd *me = (struct outd *)out_desc;\n\n    if (me->check) {\n        me->crc = crc32(me->crc, buf, len);\n        me->total += len;\n    }\n    if (me->outfile != -1)\n        do {\n            ret = PIECE;\n            if ((unsigned)ret > len)\n                ret = (int)len;\n            ret = (int)write(me->outfile, buf, ret);\n            if (ret == -1)\n                return 1;\n            buf += ret;\n            len -= ret;\n        } while (len != 0);\n    return 0;\n}\n\n/* next input byte macro for use inside lunpipe() and gunpipe() */\n#define NEXT() (have ? 0 : (have = in(indp, &next)), \\\n                last = have ? (have--, (int)(*next++)) : -1)\n\n/* memory for gunpipe() and lunpipe() --\n   the first 256 entries of prefix[] and suffix[] are never used, could\n   have offset the index, but it's faster to waste the memory */\nunsigned char inbuf[SIZE];              /* input buffer */\nunsigned char outbuf[SIZE];             /* output buffer */\nunsigned short prefix[65536];           /* index to LZW prefix string */\nunsigned char suffix[65536];            /* one-character LZW suffix */\nunsigned char match[65280 + 2];         /* buffer for reversed match or gzip\n                                           32K sliding window */\n\n/* throw out what's left in the current bits byte buffer (this is a vestigial\n   aspect of the compressed data format derived from an implementation that\n   made use of a special VAX machine instruction!) */\n#define FLUSHCODE() \\\n    do { \\\n        left = 0; \\\n        rem = 0; \\\n        if (chunk > have) { \\\n            chunk -= have; \\\n            have = 0; \\\n            if (NEXT() == -1) \\\n                break; \\\n            chunk--; \\\n            if (chunk > have) { \\\n                chunk = have = 0; \\\n                break; \\\n            } \\\n        } \\\n        have -= chunk; \\\n        next += chunk; \\\n        chunk = 0; \\\n    } while (0)\n\n/* Decompress a compress (LZW) file from indp to outfile.  The compress magic\n   header (two bytes) has already been read and verified.  There are have bytes\n   of buffered input at next.  strm is used for passing error information back\n   to gunpipe().\n\n   lunpipe() will return Z_OK on success, Z_BUF_ERROR for an unexpected end of\n   file, read error, or write error (a write error indicated by strm->next_in\n   not equal to Z_NULL), or Z_DATA_ERROR for invalid input.\n */\nlocal int lunpipe(unsigned have, z_const unsigned char *next, struct ind *indp,\n                  int outfile, z_stream *strm)\n{\n    int last;                   /* last byte read by NEXT(), or -1 if EOF */\n    unsigned chunk;             /* bytes left in current chunk */\n    int left;                   /* bits left in rem */\n    unsigned rem;               /* unused bits from input */\n    int bits;                   /* current bits per code */\n    unsigned code;              /* code, table traversal index */\n    unsigned mask;              /* mask for current bits codes */\n    int max;                    /* maximum bits per code for this stream */\n    unsigned flags;             /* compress flags, then block compress flag */\n    unsigned end;               /* last valid entry in prefix/suffix tables */\n    unsigned temp;              /* current code */\n    unsigned prev;              /* previous code */\n    unsigned final;             /* last character written for previous code */\n    unsigned stack;             /* next position for reversed string */\n    unsigned outcnt;            /* bytes in output buffer */\n    struct outd outd;           /* output structure */\n    unsigned char *p;\n\n    /* set up output */\n    outd.outfile = outfile;\n    outd.check = 0;\n\n    /* process remainder of compress header -- a flags byte */\n    flags = NEXT();\n    if (last == -1)\n        return Z_BUF_ERROR;\n    if (flags & 0x60) {\n        strm->msg = (char *)\"unknown lzw flags set\";\n        return Z_DATA_ERROR;\n    }\n    max = flags & 0x1f;\n    if (max < 9 || max > 16) {\n        strm->msg = (char *)\"lzw bits out of range\";\n        return Z_DATA_ERROR;\n    }\n    if (max == 9)                           /* 9 doesn't really mean 9 */\n        max = 10;\n    flags &= 0x80;                          /* true if block compress */\n\n    /* clear table */\n    bits = 9;\n    mask = 0x1ff;\n    end = flags ? 256 : 255;\n\n    /* set up: get first 9-bit code, which is the first decompressed byte, but\n       don't create a table entry until the next code */\n    if (NEXT() == -1)                       /* no compressed data is ok */\n        return Z_OK;\n    final = prev = (unsigned)last;          /* low 8 bits of code */\n    if (NEXT() == -1)                       /* missing a bit */\n        return Z_BUF_ERROR;\n    if (last & 1) {                         /* code must be < 256 */\n        strm->msg = (char *)\"invalid lzw code\";\n        return Z_DATA_ERROR;\n    }\n    rem = (unsigned)last >> 1;              /* remaining 7 bits */\n    left = 7;\n    chunk = bits - 2;                       /* 7 bytes left in this chunk */\n    outbuf[0] = (unsigned char)final;       /* write first decompressed byte */\n    outcnt = 1;\n\n    /* decode codes */\n    stack = 0;\n    for (;;) {\n        /* if the table will be full after this, increment the code size */\n        if (end >= mask && bits < max) {\n            FLUSHCODE();\n            bits++;\n            mask <<= 1;\n            mask++;\n        }\n\n        /* get a code of length bits */\n        if (chunk == 0)                     /* decrement chunk modulo bits */\n            chunk = bits;\n        code = rem;                         /* low bits of code */\n        if (NEXT() == -1) {                 /* EOF is end of compressed data */\n            /* write remaining buffered output */\n            if (outcnt && out(&outd, outbuf, outcnt)) {\n                strm->next_in = outbuf;     /* signal write error */\n                return Z_BUF_ERROR;\n            }\n            return Z_OK;\n        }\n        code += (unsigned)last << left;     /* middle (or high) bits of code */\n        left += 8;\n        chunk--;\n        if (bits > left) {                  /* need more bits */\n            if (NEXT() == -1)               /* can't end in middle of code */\n                return Z_BUF_ERROR;\n            code += (unsigned)last << left; /* high bits of code */\n            left += 8;\n            chunk--;\n        }\n        code &= mask;                       /* mask to current code length */\n        left -= bits;                       /* number of unused bits */\n        rem = (unsigned)last >> (8 - left); /* unused bits from last byte */\n\n        /* process clear code (256) */\n        if (code == 256 && flags) {\n            FLUSHCODE();\n            bits = 9;                       /* initialize bits and mask */\n            mask = 0x1ff;\n            end = 255;                      /* empty table */\n            continue;                       /* get next code */\n        }\n\n        /* special code to reuse last match */\n        temp = code;                        /* save the current code */\n        if (code > end) {\n            /* Be picky on the allowed code here, and make sure that the code\n               we drop through (prev) will be a valid index so that random\n               input does not cause an exception.  The code != end + 1 check is\n               empirically derived, and not checked in the original uncompress\n               code.  If this ever causes a problem, that check could be safely\n               removed.  Leaving this check in greatly improves gun's ability\n               to detect random or corrupted input after a compress header.\n               In any case, the prev > end check must be retained. */\n            if (code != end + 1 || prev > end) {\n                strm->msg = (char *)\"invalid lzw code\";\n                return Z_DATA_ERROR;\n            }\n            match[stack++] = (unsigned char)final;\n            code = prev;\n        }\n\n        /* walk through linked list to generate output in reverse order */\n        p = match + stack;\n        while (code >= 256) {\n            *p++ = suffix[code];\n            code = prefix[code];\n        }\n        stack = p - match;\n        match[stack++] = (unsigned char)code;\n        final = code;\n\n        /* link new table entry */\n        if (end < mask) {\n            end++;\n            prefix[end] = (unsigned short)prev;\n            suffix[end] = (unsigned char)final;\n        }\n\n        /* set previous code for next iteration */\n        prev = temp;\n\n        /* write output in forward order */\n        while (stack > SIZE - outcnt) {\n            while (outcnt < SIZE)\n                outbuf[outcnt++] = match[--stack];\n            if (out(&outd, outbuf, outcnt)) {\n                strm->next_in = outbuf; /* signal write error */\n                return Z_BUF_ERROR;\n            }\n            outcnt = 0;\n        }\n        p = match + stack;\n        do {\n            outbuf[outcnt++] = *--p;\n        } while (p > match);\n        stack = 0;\n\n        /* loop for next code with final and prev as the last match, rem and\n           left provide the first 0..7 bits of the next code, end is the last\n           valid table entry */\n    }\n}\n\n/* Decompress a gzip file from infile to outfile.  strm is assumed to have been\n   successfully initialized with inflateBackInit().  The input file may consist\n   of a series of gzip streams, in which case all of them will be decompressed\n   to the output file.  If outfile is -1, then the gzip stream(s) integrity is\n   checked and nothing is written.\n\n   The return value is a zlib error code: Z_MEM_ERROR if out of memory,\n   Z_DATA_ERROR if the header or the compressed data is invalid, or if the\n   trailer CRC-32 check or length doesn't match, Z_BUF_ERROR if the input ends\n   prematurely or a write error occurs, or Z_ERRNO if junk (not a another gzip\n   stream) follows a valid gzip stream.\n */\nlocal int gunpipe(z_stream *strm, int infile, int outfile)\n{\n    int ret, first, last;\n    unsigned have, flags, len;\n    z_const unsigned char *next = NULL;\n    struct ind ind, *indp;\n    struct outd outd;\n\n    /* setup input buffer */\n    ind.infile = infile;\n    ind.inbuf = inbuf;\n    indp = &ind;\n\n    /* decompress concatenated gzip streams */\n    have = 0;                               /* no input data read in yet */\n    first = 1;                              /* looking for first gzip header */\n    strm->next_in = Z_NULL;                 /* so Z_BUF_ERROR means EOF */\n    for (;;) {\n        /* look for the two magic header bytes for a gzip stream */\n        if (NEXT() == -1) {\n            ret = Z_OK;\n            break;                          /* empty gzip stream is ok */\n        }\n        if (last != 31 || (NEXT() != 139 && last != 157)) {\n            strm->msg = (char *)\"incorrect header check\";\n            ret = first ? Z_DATA_ERROR : Z_ERRNO;\n            break;                          /* not a gzip or compress header */\n        }\n        first = 0;                          /* next non-header is junk */\n\n        /* process a compress (LZW) file -- can't be concatenated after this */\n        if (last == 157) {\n            ret = lunpipe(have, next, indp, outfile, strm);\n            break;\n        }\n\n        /* process remainder of gzip header */\n        ret = Z_BUF_ERROR;\n        if (NEXT() != 8) {                  /* only deflate method allowed */\n            if (last == -1) break;\n            strm->msg = (char *)\"unknown compression method\";\n            ret = Z_DATA_ERROR;\n            break;\n        }\n        flags = NEXT();                     /* header flags */\n        NEXT();                             /* discard mod time, xflgs, os */\n        NEXT();\n        NEXT();\n        NEXT();\n        NEXT();\n        NEXT();\n        if (last == -1) break;\n        if (flags & 0xe0) {\n            strm->msg = (char *)\"unknown header flags set\";\n            ret = Z_DATA_ERROR;\n            break;\n        }\n        if (flags & 4) {                    /* extra field */\n            len = NEXT();\n            len += (unsigned)(NEXT()) << 8;\n            if (last == -1) break;\n            while (len > have) {\n                len -= have;\n                have = 0;\n                if (NEXT() == -1) break;\n                len--;\n            }\n            if (last == -1) break;\n            have -= len;\n            next += len;\n        }\n        if (flags & 8)                      /* file name */\n            while (NEXT() != 0 && last != -1)\n                ;\n        if (flags & 16)                     /* comment */\n            while (NEXT() != 0 && last != -1)\n                ;\n        if (flags & 2) {                    /* header crc */\n            NEXT();\n            NEXT();\n        }\n        if (last == -1) break;\n\n        /* set up output */\n        outd.outfile = outfile;\n        outd.check = 1;\n        outd.crc = crc32(0L, Z_NULL, 0);\n        outd.total = 0;\n\n        /* decompress data to output */\n        strm->next_in = next;\n        strm->avail_in = have;\n        ret = inflateBack(strm, in, indp, out, &outd);\n        if (ret != Z_STREAM_END) break;\n        next = strm->next_in;\n        have = strm->avail_in;\n        strm->next_in = Z_NULL;             /* so Z_BUF_ERROR means EOF */\n\n        /* check trailer */\n        ret = Z_BUF_ERROR;\n        if (NEXT() != (int)(outd.crc & 0xff) ||\n            NEXT() != (int)((outd.crc >> 8) & 0xff) ||\n            NEXT() != (int)((outd.crc >> 16) & 0xff) ||\n            NEXT() != (int)((outd.crc >> 24) & 0xff)) {\n            /* crc error */\n            if (last != -1) {\n                strm->msg = (char *)\"incorrect data check\";\n                ret = Z_DATA_ERROR;\n            }\n            break;\n        }\n        if (NEXT() != (int)(outd.total & 0xff) ||\n            NEXT() != (int)((outd.total >> 8) & 0xff) ||\n            NEXT() != (int)((outd.total >> 16) & 0xff) ||\n            NEXT() != (int)((outd.total >> 24) & 0xff)) {\n            /* length error */\n            if (last != -1) {\n                strm->msg = (char *)\"incorrect length check\";\n                ret = Z_DATA_ERROR;\n            }\n            break;\n        }\n\n        /* go back and look for another gzip stream */\n    }\n\n    /* clean up and return */\n    return ret;\n}\n\n/* Copy file attributes, from -> to, as best we can.  This is best effort, so\n   no errors are reported.  The mode bits, including suid, sgid, and the sticky\n   bit are copied (if allowed), the owner's user id and group id are copied\n   (again if allowed), and the access and modify times are copied. */\nlocal void copymeta(char *from, char *to)\n{\n    struct stat was;\n    struct utimbuf when;\n\n    /* get all of from's Unix meta data, return if not a regular file */\n    if (stat(from, &was) != 0 || (was.st_mode & S_IFMT) != S_IFREG)\n        return;\n\n    /* set to's mode bits, ignore errors */\n    (void)chmod(to, was.st_mode & 07777);\n\n    /* copy owner's user and group, ignore errors */\n    (void)chown(to, was.st_uid, was.st_gid);\n\n    /* copy access and modify times, ignore errors */\n    when.actime = was.st_atime;\n    when.modtime = was.st_mtime;\n    (void)utime(to, &when);\n}\n\n/* Decompress the file inname to the file outnname, of if test is true, just\n   decompress without writing and check the gzip trailer for integrity.  If\n   inname is NULL or an empty string, read from stdin.  If outname is NULL or\n   an empty string, write to stdout.  strm is a pre-initialized inflateBack\n   structure.  When appropriate, copy the file attributes from inname to\n   outname.\n\n   gunzip() returns 1 if there is an out-of-memory error or an unexpected\n   return code from gunpipe().  Otherwise it returns 0.\n */\nlocal int gunzip(z_stream *strm, char *inname, char *outname, int test)\n{\n    int ret;\n    int infile, outfile;\n\n    /* open files */\n    if (inname == NULL || *inname == 0) {\n        inname = \"-\";\n        infile = 0;     /* stdin */\n    }\n    else {\n        infile = open(inname, O_RDONLY, 0);\n        if (infile == -1) {\n            fprintf(stderr, \"gun cannot open %s\\n\", inname);\n            return 0;\n        }\n    }\n    if (test)\n        outfile = -1;\n    else if (outname == NULL || *outname == 0) {\n        outname = \"-\";\n        outfile = 1;    /* stdout */\n    }\n    else {\n        outfile = open(outname, O_CREAT | O_TRUNC | O_WRONLY, 0666);\n        if (outfile == -1) {\n            close(infile);\n            fprintf(stderr, \"gun cannot create %s\\n\", outname);\n            return 0;\n        }\n    }\n    errno = 0;\n\n    /* decompress */\n    ret = gunpipe(strm, infile, outfile);\n    if (outfile > 2) close(outfile);\n    if (infile > 2) close(infile);\n\n    /* interpret result */\n    switch (ret) {\n    case Z_OK:\n    case Z_ERRNO:\n        if (infile > 2 && outfile > 2) {\n            copymeta(inname, outname);          /* copy attributes */\n            unlink(inname);\n        }\n        if (ret == Z_ERRNO)\n            fprintf(stderr, \"gun warning: trailing garbage ignored in %s\\n\",\n                    inname);\n        break;\n    case Z_DATA_ERROR:\n        if (outfile > 2) unlink(outname);\n        fprintf(stderr, \"gun data error on %s: %s\\n\", inname, strm->msg);\n        break;\n    case Z_MEM_ERROR:\n        if (outfile > 2) unlink(outname);\n        fprintf(stderr, \"gun out of memory error--aborting\\n\");\n        return 1;\n    case Z_BUF_ERROR:\n        if (outfile > 2) unlink(outname);\n        if (strm->next_in != Z_NULL) {\n            fprintf(stderr, \"gun write error on %s: %s\\n\",\n                    outname, strerror(errno));\n        }\n        else if (errno) {\n            fprintf(stderr, \"gun read error on %s: %s\\n\",\n                    inname, strerror(errno));\n        }\n        else {\n            fprintf(stderr, \"gun unexpected end of file on %s\\n\",\n                    inname);\n        }\n        break;\n    default:\n        if (outfile > 2) unlink(outname);\n        fprintf(stderr, \"gun internal error--aborting\\n\");\n        return 1;\n    }\n    return 0;\n}\n\n/* Process the gun command line arguments.  See the command syntax near the\n   beginning of this source file. */\nint main(int argc, char **argv)\n{\n    int ret, len, test;\n    char *outname;\n    unsigned char *window;\n    z_stream strm;\n\n    /* initialize inflateBack state for repeated use */\n    window = match;                         /* reuse LZW match buffer */\n    strm.zalloc = Z_NULL;\n    strm.zfree = Z_NULL;\n    strm.opaque = Z_NULL;\n    ret = inflateBackInit(&strm, 15, window);\n    if (ret != Z_OK) {\n        fprintf(stderr, \"gun out of memory error--aborting\\n\");\n        return 1;\n    }\n\n    /* decompress each file to the same name with the suffix removed */\n    argc--;\n    argv++;\n    test = 0;\n    if (argc && strcmp(*argv, \"-h\") == 0) {\n        fprintf(stderr, \"gun 1.6 (17 Jan 2010)\\n\");\n        fprintf(stderr, \"Copyright (C) 2003-2010 Mark Adler\\n\");\n        fprintf(stderr, \"usage: gun [-t] [file1.gz [file2.Z ...]]\\n\");\n        return 0;\n    }\n    if (argc && strcmp(*argv, \"-t\") == 0) {\n        test = 1;\n        argc--;\n        argv++;\n    }\n    if (argc)\n        do {\n            if (test)\n                outname = NULL;\n            else {\n                len = (int)strlen(*argv);\n                if (strcmp(*argv + len - 3, \".gz\") == 0 ||\n                    strcmp(*argv + len - 3, \"-gz\") == 0)\n                    len -= 3;\n                else if (strcmp(*argv + len - 2, \".z\") == 0 ||\n                    strcmp(*argv + len - 2, \"-z\") == 0 ||\n                    strcmp(*argv + len - 2, \"_z\") == 0 ||\n                    strcmp(*argv + len - 2, \".Z\") == 0)\n                    len -= 2;\n                else {\n                    fprintf(stderr, \"gun error: no gz type on %s--skipping\\n\",\n                            *argv);\n                    continue;\n                }\n                outname = malloc(len + 1);\n                if (outname == NULL) {\n                    fprintf(stderr, \"gun out of memory error--aborting\\n\");\n                    ret = 1;\n                    break;\n                }\n                memcpy(outname, *argv, len);\n                outname[len] = 0;\n            }\n            ret = gunzip(&strm, *argv, outname, test);\n            if (outname != NULL) free(outname);\n            if (ret) break;\n        } while (argv++, --argc);\n    else\n        ret = gunzip(&strm, NULL, NULL, test);\n\n    /* clean up */\n    inflateBackEnd(&strm);\n    return ret;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/examples/gzappend.c",
    "content": "/* gzappend -- command to append to a gzip file\n\n  Copyright (C) 2003, 2012 Mark Adler, all rights reserved\n  version 1.2, 11 Oct 2012\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the author be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Mark Adler    madler@alumni.caltech.edu\n */\n\n/*\n * Change history:\n *\n * 1.0  19 Oct 2003     - First version\n * 1.1   4 Nov 2003     - Expand and clarify some comments and notes\n *                      - Add version and copyright to help\n *                      - Send help to stdout instead of stderr\n *                      - Add some preemptive typecasts\n *                      - Add L to constants in lseek() calls\n *                      - Remove some debugging information in error messages\n *                      - Use new data_type definition for zlib 1.2.1\n *                      - Simplfy and unify file operations\n *                      - Finish off gzip file in gztack()\n *                      - Use deflatePrime() instead of adding empty blocks\n *                      - Keep gzip file clean on appended file read errors\n *                      - Use in-place rotate instead of auxiliary buffer\n *                        (Why you ask?  Because it was fun to write!)\n * 1.2  11 Oct 2012     - Fix for proper z_const usage\n *                      - Check for input buffer malloc failure\n */\n\n/*\n   gzappend takes a gzip file and appends to it, compressing files from the\n   command line or data from stdin.  The gzip file is written to directly, to\n   avoid copying that file, in case it's large.  Note that this results in the\n   unfriendly behavior that if gzappend fails, the gzip file is corrupted.\n\n   This program was written to illustrate the use of the new Z_BLOCK option of\n   zlib 1.2.x's inflate() function.  This option returns from inflate() at each\n   block boundary to facilitate locating and modifying the last block bit at\n   the start of the final deflate block.  Also whether using Z_BLOCK or not,\n   another required feature of zlib 1.2.x is that inflate() now provides the\n   number of unusued bits in the last input byte used.  gzappend will not work\n   with versions of zlib earlier than 1.2.1.\n\n   gzappend first decompresses the gzip file internally, discarding all but\n   the last 32K of uncompressed data, and noting the location of the last block\n   bit and the number of unused bits in the last byte of the compressed data.\n   The gzip trailer containing the CRC-32 and length of the uncompressed data\n   is verified.  This trailer will be later overwritten.\n\n   Then the last block bit is cleared by seeking back in the file and rewriting\n   the byte that contains it.  Seeking forward, the last byte of the compressed\n   data is saved along with the number of unused bits to initialize deflate.\n\n   A deflate process is initialized, using the last 32K of the uncompressed\n   data from the gzip file to initialize the dictionary.  If the total\n   uncompressed data was less than 32K, then all of it is used to initialize\n   the dictionary.  The deflate output bit buffer is also initialized with the\n   last bits from the original deflate stream.  From here on, the data to\n   append is simply compressed using deflate, and written to the gzip file.\n   When that is complete, the new CRC-32 and uncompressed length are written\n   as the trailer of the gzip file.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include \"zlib.h\"\n\n#define local static\n#define LGCHUNK 14\n#define CHUNK (1U << LGCHUNK)\n#define DSIZE 32768U\n\n/* print an error message and terminate with extreme prejudice */\nlocal void bye(char *msg1, char *msg2)\n{\n    fprintf(stderr, \"gzappend error: %s%s\\n\", msg1, msg2);\n    exit(1);\n}\n\n/* return the greatest common divisor of a and b using Euclid's algorithm,\n   modified to be fast when one argument much greater than the other, and\n   coded to avoid unnecessary swapping */\nlocal unsigned gcd(unsigned a, unsigned b)\n{\n    unsigned c;\n\n    while (a && b)\n        if (a > b) {\n            c = b;\n            while (a - c >= c)\n                c <<= 1;\n            a -= c;\n        }\n        else {\n            c = a;\n            while (b - c >= c)\n                c <<= 1;\n            b -= c;\n        }\n    return a + b;\n}\n\n/* rotate list[0..len-1] left by rot positions, in place */\nlocal void rotate(unsigned char *list, unsigned len, unsigned rot)\n{\n    unsigned char tmp;\n    unsigned cycles;\n    unsigned char *start, *last, *to, *from;\n\n    /* normalize rot and handle degenerate cases */\n    if (len < 2) return;\n    if (rot >= len) rot %= len;\n    if (rot == 0) return;\n\n    /* pointer to last entry in list */\n    last = list + (len - 1);\n\n    /* do simple left shift by one */\n    if (rot == 1) {\n        tmp = *list;\n        memcpy(list, list + 1, len - 1);\n        *last = tmp;\n        return;\n    }\n\n    /* do simple right shift by one */\n    if (rot == len - 1) {\n        tmp = *last;\n        memmove(list + 1, list, len - 1);\n        *list = tmp;\n        return;\n    }\n\n    /* otherwise do rotate as a set of cycles in place */\n    cycles = gcd(len, rot);             /* number of cycles */\n    do {\n        start = from = list + cycles;   /* start index is arbitrary */\n        tmp = *from;                    /* save entry to be overwritten */\n        for (;;) {\n            to = from;                  /* next step in cycle */\n            from += rot;                /* go right rot positions */\n            if (from > last) from -= len;   /* (pointer better not wrap) */\n            if (from == start) break;   /* all but one shifted */\n            *to = *from;                /* shift left */\n        }\n        *to = tmp;                      /* complete the circle */\n    } while (--cycles);\n}\n\n/* structure for gzip file read operations */\ntypedef struct {\n    int fd;                     /* file descriptor */\n    int size;                   /* 1 << size is bytes in buf */\n    unsigned left;              /* bytes available at next */\n    unsigned char *buf;         /* buffer */\n    z_const unsigned char *next;    /* next byte in buffer */\n    char *name;                 /* file name for error messages */\n} file;\n\n/* reload buffer */\nlocal int readin(file *in)\n{\n    int len;\n\n    len = read(in->fd, in->buf, 1 << in->size);\n    if (len == -1) bye(\"error reading \", in->name);\n    in->left = (unsigned)len;\n    in->next = in->buf;\n    return len;\n}\n\n/* read from file in, exit if end-of-file */\nlocal int readmore(file *in)\n{\n    if (readin(in) == 0) bye(\"unexpected end of \", in->name);\n    return 0;\n}\n\n#define read1(in) (in->left == 0 ? readmore(in) : 0, \\\n                   in->left--, *(in->next)++)\n\n/* skip over n bytes of in */\nlocal void skip(file *in, unsigned n)\n{\n    unsigned bypass;\n\n    if (n > in->left) {\n        n -= in->left;\n        bypass = n & ~((1U << in->size) - 1);\n        if (bypass) {\n            if (lseek(in->fd, (off_t)bypass, SEEK_CUR) == -1)\n                bye(\"seeking \", in->name);\n            n -= bypass;\n        }\n        readmore(in);\n        if (n > in->left)\n            bye(\"unexpected end of \", in->name);\n    }\n    in->left -= n;\n    in->next += n;\n}\n\n/* read a four-byte unsigned integer, little-endian, from in */\nunsigned long read4(file *in)\n{\n    unsigned long val;\n\n    val = read1(in);\n    val += (unsigned)read1(in) << 8;\n    val += (unsigned long)read1(in) << 16;\n    val += (unsigned long)read1(in) << 24;\n    return val;\n}\n\n/* skip over gzip header */\nlocal void gzheader(file *in)\n{\n    int flags;\n    unsigned n;\n\n    if (read1(in) != 31 || read1(in) != 139) bye(in->name, \" not a gzip file\");\n    if (read1(in) != 8) bye(\"unknown compression method in\", in->name);\n    flags = read1(in);\n    if (flags & 0xe0) bye(\"unknown header flags set in\", in->name);\n    skip(in, 6);\n    if (flags & 4) {\n        n = read1(in);\n        n += (unsigned)(read1(in)) << 8;\n        skip(in, n);\n    }\n    if (flags & 8) while (read1(in) != 0) ;\n    if (flags & 16) while (read1(in) != 0) ;\n    if (flags & 2) skip(in, 2);\n}\n\n/* decompress gzip file \"name\", return strm with a deflate stream ready to\n   continue compression of the data in the gzip file, and return a file\n   descriptor pointing to where to write the compressed data -- the deflate\n   stream is initialized to compress using level \"level\" */\nlocal int gzscan(char *name, z_stream *strm, int level)\n{\n    int ret, lastbit, left, full;\n    unsigned have;\n    unsigned long crc, tot;\n    unsigned char *window;\n    off_t lastoff, end;\n    file gz;\n\n    /* open gzip file */\n    gz.name = name;\n    gz.fd = open(name, O_RDWR, 0);\n    if (gz.fd == -1) bye(\"cannot open \", name);\n    gz.buf = malloc(CHUNK);\n    if (gz.buf == NULL) bye(\"out of memory\", \"\");\n    gz.size = LGCHUNK;\n    gz.left = 0;\n\n    /* skip gzip header */\n    gzheader(&gz);\n\n    /* prepare to decompress */\n    window = malloc(DSIZE);\n    if (window == NULL) bye(\"out of memory\", \"\");\n    strm->zalloc = Z_NULL;\n    strm->zfree = Z_NULL;\n    strm->opaque = Z_NULL;\n    ret = inflateInit2(strm, -15);\n    if (ret != Z_OK) bye(\"out of memory\", \" or library mismatch\");\n\n    /* decompress the deflate stream, saving append information */\n    lastbit = 0;\n    lastoff = lseek(gz.fd, 0L, SEEK_CUR) - gz.left;\n    left = 0;\n    strm->avail_in = gz.left;\n    strm->next_in = gz.next;\n    crc = crc32(0L, Z_NULL, 0);\n    have = full = 0;\n    do {\n        /* if needed, get more input */\n        if (strm->avail_in == 0) {\n            readmore(&gz);\n            strm->avail_in = gz.left;\n            strm->next_in = gz.next;\n        }\n\n        /* set up output to next available section of sliding window */\n        strm->avail_out = DSIZE - have;\n        strm->next_out = window + have;\n\n        /* inflate and check for errors */\n        ret = inflate(strm, Z_BLOCK);\n        if (ret == Z_STREAM_ERROR) bye(\"internal stream error!\", \"\");\n        if (ret == Z_MEM_ERROR) bye(\"out of memory\", \"\");\n        if (ret == Z_DATA_ERROR)\n            bye(\"invalid compressed data--format violated in\", name);\n\n        /* update crc and sliding window pointer */\n        crc = crc32(crc, window + have, DSIZE - have - strm->avail_out);\n        if (strm->avail_out)\n            have = DSIZE - strm->avail_out;\n        else {\n            have = 0;\n            full = 1;\n        }\n\n        /* process end of block */\n        if (strm->data_type & 128) {\n            if (strm->data_type & 64)\n                left = strm->data_type & 0x1f;\n            else {\n                lastbit = strm->data_type & 0x1f;\n                lastoff = lseek(gz.fd, 0L, SEEK_CUR) - strm->avail_in;\n            }\n        }\n    } while (ret != Z_STREAM_END);\n    inflateEnd(strm);\n    gz.left = strm->avail_in;\n    gz.next = strm->next_in;\n\n    /* save the location of the end of the compressed data */\n    end = lseek(gz.fd, 0L, SEEK_CUR) - gz.left;\n\n    /* check gzip trailer and save total for deflate */\n    if (crc != read4(&gz))\n        bye(\"invalid compressed data--crc mismatch in \", name);\n    tot = strm->total_out;\n    if ((tot & 0xffffffffUL) != read4(&gz))\n        bye(\"invalid compressed data--length mismatch in\", name);\n\n    /* if not at end of file, warn */\n    if (gz.left || readin(&gz))\n        fprintf(stderr,\n            \"gzappend warning: junk at end of gzip file overwritten\\n\");\n\n    /* clear last block bit */\n    lseek(gz.fd, lastoff - (lastbit != 0), SEEK_SET);\n    if (read(gz.fd, gz.buf, 1) != 1) bye(\"reading after seek on \", name);\n    *gz.buf = (unsigned char)(*gz.buf ^ (1 << ((8 - lastbit) & 7)));\n    lseek(gz.fd, -1L, SEEK_CUR);\n    if (write(gz.fd, gz.buf, 1) != 1) bye(\"writing after seek to \", name);\n\n    /* if window wrapped, build dictionary from window by rotating */\n    if (full) {\n        rotate(window, DSIZE, have);\n        have = DSIZE;\n    }\n\n    /* set up deflate stream with window, crc, total_in, and leftover bits */\n    ret = deflateInit2(strm, level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);\n    if (ret != Z_OK) bye(\"out of memory\", \"\");\n    deflateSetDictionary(strm, window, have);\n    strm->adler = crc;\n    strm->total_in = tot;\n    if (left) {\n        lseek(gz.fd, --end, SEEK_SET);\n        if (read(gz.fd, gz.buf, 1) != 1) bye(\"reading after seek on \", name);\n        deflatePrime(strm, 8 - left, *gz.buf);\n    }\n    lseek(gz.fd, end, SEEK_SET);\n\n    /* clean up and return */\n    free(window);\n    free(gz.buf);\n    return gz.fd;\n}\n\n/* append file \"name\" to gzip file gd using deflate stream strm -- if last\n   is true, then finish off the deflate stream at the end */\nlocal void gztack(char *name, int gd, z_stream *strm, int last)\n{\n    int fd, len, ret;\n    unsigned left;\n    unsigned char *in, *out;\n\n    /* open file to compress and append */\n    fd = 0;\n    if (name != NULL) {\n        fd = open(name, O_RDONLY, 0);\n        if (fd == -1)\n            fprintf(stderr, \"gzappend warning: %s not found, skipping ...\\n\",\n                    name);\n    }\n\n    /* allocate buffers */\n    in = malloc(CHUNK);\n    out = malloc(CHUNK);\n    if (in == NULL || out == NULL) bye(\"out of memory\", \"\");\n\n    /* compress input file and append to gzip file */\n    do {\n        /* get more input */\n        len = read(fd, in, CHUNK);\n        if (len == -1) {\n            fprintf(stderr,\n                    \"gzappend warning: error reading %s, skipping rest ...\\n\",\n                    name);\n            len = 0;\n        }\n        strm->avail_in = (unsigned)len;\n        strm->next_in = in;\n        if (len) strm->adler = crc32(strm->adler, in, (unsigned)len);\n\n        /* compress and write all available output */\n        do {\n            strm->avail_out = CHUNK;\n            strm->next_out = out;\n            ret = deflate(strm, last && len == 0 ? Z_FINISH : Z_NO_FLUSH);\n            left = CHUNK - strm->avail_out;\n            while (left) {\n                len = write(gd, out + CHUNK - strm->avail_out - left, left);\n                if (len == -1) bye(\"writing gzip file\", \"\");\n                left -= (unsigned)len;\n            }\n        } while (strm->avail_out == 0 && ret != Z_STREAM_END);\n    } while (len != 0);\n\n    /* write trailer after last entry */\n    if (last) {\n        deflateEnd(strm);\n        out[0] = (unsigned char)(strm->adler);\n        out[1] = (unsigned char)(strm->adler >> 8);\n        out[2] = (unsigned char)(strm->adler >> 16);\n        out[3] = (unsigned char)(strm->adler >> 24);\n        out[4] = (unsigned char)(strm->total_in);\n        out[5] = (unsigned char)(strm->total_in >> 8);\n        out[6] = (unsigned char)(strm->total_in >> 16);\n        out[7] = (unsigned char)(strm->total_in >> 24);\n        len = 8;\n        do {\n            ret = write(gd, out + 8 - len, len);\n            if (ret == -1) bye(\"writing gzip file\", \"\");\n            len -= ret;\n        } while (len);\n        close(gd);\n    }\n\n    /* clean up and return */\n    free(out);\n    free(in);\n    if (fd > 0) close(fd);\n}\n\n/* process the compression level option if present, scan the gzip file, and\n   append the specified files, or append the data from stdin if no other file\n   names are provided on the command line -- the gzip file must be writable\n   and seekable */\nint main(int argc, char **argv)\n{\n    int gd, level;\n    z_stream strm;\n\n    /* ignore command name */\n    argc--; argv++;\n\n    /* provide usage if no arguments */\n    if (*argv == NULL) {\n        printf(\n            \"gzappend 1.2 (11 Oct 2012) Copyright (C) 2003, 2012 Mark Adler\\n\"\n               );\n        printf(\n            \"usage: gzappend [-level] file.gz [ addthis [ andthis ... ]]\\n\");\n        return 0;\n    }\n\n    /* set compression level */\n    level = Z_DEFAULT_COMPRESSION;\n    if (argv[0][0] == '-') {\n        if (argv[0][1] < '0' || argv[0][1] > '9' || argv[0][2] != 0)\n            bye(\"invalid compression level\", \"\");\n        level = argv[0][1] - '0';\n        if (*++argv == NULL) bye(\"no gzip file name after options\", \"\");\n    }\n\n    /* prepare to append to gzip file */\n    gd = gzscan(*argv++, &strm, level);\n\n    /* append files on command line, or from stdin if none */\n    if (*argv == NULL)\n        gztack(NULL, gd, &strm, 1);\n    else\n        do {\n            gztack(*argv, gd, &strm, argv[1] == NULL);\n        } while (*++argv != NULL);\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/examples/gzjoin.c",
    "content": "/* gzjoin -- command to join gzip files into one gzip file\n\n  Copyright (C) 2004, 2005, 2012 Mark Adler, all rights reserved\n  version 1.2, 14 Aug 2012\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the author be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Mark Adler    madler@alumni.caltech.edu\n */\n\n/*\n * Change history:\n *\n * 1.0  11 Dec 2004     - First version\n * 1.1  12 Jun 2005     - Changed ssize_t to long for portability\n * 1.2  14 Aug 2012     - Clean up for z_const usage\n */\n\n/*\n   gzjoin takes one or more gzip files on the command line and writes out a\n   single gzip file that will uncompress to the concatenation of the\n   uncompressed data from the individual gzip files.  gzjoin does this without\n   having to recompress any of the data and without having to calculate a new\n   crc32 for the concatenated uncompressed data.  gzjoin does however have to\n   decompress all of the input data in order to find the bits in the compressed\n   data that need to be modified to concatenate the streams.\n\n   gzjoin does not do an integrity check on the input gzip files other than\n   checking the gzip header and decompressing the compressed data.  They are\n   otherwise assumed to be complete and correct.\n\n   Each joint between gzip files removes at least 18 bytes of previous trailer\n   and subsequent header, and inserts an average of about three bytes to the\n   compressed data in order to connect the streams.  The output gzip file\n   has a minimal ten-byte gzip header with no file name or modification time.\n\n   This program was written to illustrate the use of the Z_BLOCK option of\n   inflate() and the crc32_combine() function.  gzjoin will not compile with\n   versions of zlib earlier than 1.2.3.\n */\n\n#include <stdio.h>      /* fputs(), fprintf(), fwrite(), putc() */\n#include <stdlib.h>     /* exit(), malloc(), free() */\n#include <fcntl.h>      /* open() */\n#include <unistd.h>     /* close(), read(), lseek() */\n#include \"zlib.h\"\n    /* crc32(), crc32_combine(), inflateInit2(), inflate(), inflateEnd() */\n\n#define local static\n\n/* exit with an error (return a value to allow use in an expression) */\nlocal int bail(char *why1, char *why2)\n{\n    fprintf(stderr, \"gzjoin error: %s%s, output incomplete\\n\", why1, why2);\n    exit(1);\n    return 0;\n}\n\n/* -- simple buffered file input with access to the buffer -- */\n\n#define CHUNK 32768         /* must be a power of two and fit in unsigned */\n\n/* bin buffered input file type */\ntypedef struct {\n    char *name;             /* name of file for error messages */\n    int fd;                 /* file descriptor */\n    unsigned left;          /* bytes remaining at next */\n    unsigned char *next;    /* next byte to read */\n    unsigned char *buf;     /* allocated buffer of length CHUNK */\n} bin;\n\n/* close a buffered file and free allocated memory */\nlocal void bclose(bin *in)\n{\n    if (in != NULL) {\n        if (in->fd != -1)\n            close(in->fd);\n        if (in->buf != NULL)\n            free(in->buf);\n        free(in);\n    }\n}\n\n/* open a buffered file for input, return a pointer to type bin, or NULL on\n   failure */\nlocal bin *bopen(char *name)\n{\n    bin *in;\n\n    in = malloc(sizeof(bin));\n    if (in == NULL)\n        return NULL;\n    in->buf = malloc(CHUNK);\n    in->fd = open(name, O_RDONLY, 0);\n    if (in->buf == NULL || in->fd == -1) {\n        bclose(in);\n        return NULL;\n    }\n    in->left = 0;\n    in->next = in->buf;\n    in->name = name;\n    return in;\n}\n\n/* load buffer from file, return -1 on read error, 0 or 1 on success, with\n   1 indicating that end-of-file was reached */\nlocal int bload(bin *in)\n{\n    long len;\n\n    if (in == NULL)\n        return -1;\n    if (in->left != 0)\n        return 0;\n    in->next = in->buf;\n    do {\n        len = (long)read(in->fd, in->buf + in->left, CHUNK - in->left);\n        if (len < 0)\n            return -1;\n        in->left += (unsigned)len;\n    } while (len != 0 && in->left < CHUNK);\n    return len == 0 ? 1 : 0;\n}\n\n/* get a byte from the file, bail if end of file */\n#define bget(in) (in->left ? 0 : bload(in), \\\n                  in->left ? (in->left--, *(in->next)++) : \\\n                    bail(\"unexpected end of file on \", in->name))\n\n/* get a four-byte little-endian unsigned integer from file */\nlocal unsigned long bget4(bin *in)\n{\n    unsigned long val;\n\n    val = bget(in);\n    val += (unsigned long)(bget(in)) << 8;\n    val += (unsigned long)(bget(in)) << 16;\n    val += (unsigned long)(bget(in)) << 24;\n    return val;\n}\n\n/* skip bytes in file */\nlocal void bskip(bin *in, unsigned skip)\n{\n    /* check pointer */\n    if (in == NULL)\n        return;\n\n    /* easy case -- skip bytes in buffer */\n    if (skip <= in->left) {\n        in->left -= skip;\n        in->next += skip;\n        return;\n    }\n\n    /* skip what's in buffer, discard buffer contents */\n    skip -= in->left;\n    in->left = 0;\n\n    /* seek past multiples of CHUNK bytes */\n    if (skip > CHUNK) {\n        unsigned left;\n\n        left = skip & (CHUNK - 1);\n        if (left == 0) {\n            /* exact number of chunks: seek all the way minus one byte to check\n               for end-of-file with a read */\n            lseek(in->fd, skip - 1, SEEK_CUR);\n            if (read(in->fd, in->buf, 1) != 1)\n                bail(\"unexpected end of file on \", in->name);\n            return;\n        }\n\n        /* skip the integral chunks, update skip with remainder */\n        lseek(in->fd, skip - left, SEEK_CUR);\n        skip = left;\n    }\n\n    /* read more input and skip remainder */\n    bload(in);\n    if (skip > in->left)\n        bail(\"unexpected end of file on \", in->name);\n    in->left -= skip;\n    in->next += skip;\n}\n\n/* -- end of buffered input functions -- */\n\n/* skip the gzip header from file in */\nlocal void gzhead(bin *in)\n{\n    int flags;\n\n    /* verify gzip magic header and compression method */\n    if (bget(in) != 0x1f || bget(in) != 0x8b || bget(in) != 8)\n        bail(in->name, \" is not a valid gzip file\");\n\n    /* get and verify flags */\n    flags = bget(in);\n    if ((flags & 0xe0) != 0)\n        bail(\"unknown reserved bits set in \", in->name);\n\n    /* skip modification time, extra flags, and os */\n    bskip(in, 6);\n\n    /* skip extra field if present */\n    if (flags & 4) {\n        unsigned len;\n\n        len = bget(in);\n        len += (unsigned)(bget(in)) << 8;\n        bskip(in, len);\n    }\n\n    /* skip file name if present */\n    if (flags & 8)\n        while (bget(in) != 0)\n            ;\n\n    /* skip comment if present */\n    if (flags & 16)\n        while (bget(in) != 0)\n            ;\n\n    /* skip header crc if present */\n    if (flags & 2)\n        bskip(in, 2);\n}\n\n/* write a four-byte little-endian unsigned integer to out */\nlocal void put4(unsigned long val, FILE *out)\n{\n    putc(val & 0xff, out);\n    putc((val >> 8) & 0xff, out);\n    putc((val >> 16) & 0xff, out);\n    putc((val >> 24) & 0xff, out);\n}\n\n/* Load up zlib stream from buffered input, bail if end of file */\nlocal void zpull(z_streamp strm, bin *in)\n{\n    if (in->left == 0)\n        bload(in);\n    if (in->left == 0)\n        bail(\"unexpected end of file on \", in->name);\n    strm->avail_in = in->left;\n    strm->next_in = in->next;\n}\n\n/* Write header for gzip file to out and initialize trailer. */\nlocal void gzinit(unsigned long *crc, unsigned long *tot, FILE *out)\n{\n    fwrite(\"\\x1f\\x8b\\x08\\0\\0\\0\\0\\0\\0\\xff\", 1, 10, out);\n    *crc = crc32(0L, Z_NULL, 0);\n    *tot = 0;\n}\n\n/* Copy the compressed data from name, zeroing the last block bit of the last\n   block if clr is true, and adding empty blocks as needed to get to a byte\n   boundary.  If clr is false, then the last block becomes the last block of\n   the output, and the gzip trailer is written.  crc and tot maintains the\n   crc and length (modulo 2^32) of the output for the trailer.  The resulting\n   gzip file is written to out.  gzinit() must be called before the first call\n   of gzcopy() to write the gzip header and to initialize crc and tot. */\nlocal void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot,\n                  FILE *out)\n{\n    int ret;                /* return value from zlib functions */\n    int pos;                /* where the \"last block\" bit is in byte */\n    int last;               /* true if processing the last block */\n    bin *in;                /* buffered input file */\n    unsigned char *start;   /* start of compressed data in buffer */\n    unsigned char *junk;    /* buffer for uncompressed data -- discarded */\n    z_off_t len;            /* length of uncompressed data (support > 4 GB) */\n    z_stream strm;          /* zlib inflate stream */\n\n    /* open gzip file and skip header */\n    in = bopen(name);\n    if (in == NULL)\n        bail(\"could not open \", name);\n    gzhead(in);\n\n    /* allocate buffer for uncompressed data and initialize raw inflate\n       stream */\n    junk = malloc(CHUNK);\n    strm.zalloc = Z_NULL;\n    strm.zfree = Z_NULL;\n    strm.opaque = Z_NULL;\n    strm.avail_in = 0;\n    strm.next_in = Z_NULL;\n    ret = inflateInit2(&strm, -15);\n    if (junk == NULL || ret != Z_OK)\n        bail(\"out of memory\", \"\");\n\n    /* inflate and copy compressed data, clear last-block bit if requested */\n    len = 0;\n    zpull(&strm, in);\n    start = in->next;\n    last = start[0] & 1;\n    if (last && clr)\n        start[0] &= ~1;\n    strm.avail_out = 0;\n    for (;;) {\n        /* if input used and output done, write used input and get more */\n        if (strm.avail_in == 0 && strm.avail_out != 0) {\n            fwrite(start, 1, strm.next_in - start, out);\n            start = in->buf;\n            in->left = 0;\n            zpull(&strm, in);\n        }\n\n        /* decompress -- return early when end-of-block reached */\n        strm.avail_out = CHUNK;\n        strm.next_out = junk;\n        ret = inflate(&strm, Z_BLOCK);\n        switch (ret) {\n        case Z_MEM_ERROR:\n            bail(\"out of memory\", \"\");\n        case Z_DATA_ERROR:\n            bail(\"invalid compressed data in \", in->name);\n        }\n\n        /* update length of uncompressed data */\n        len += CHUNK - strm.avail_out;\n\n        /* check for block boundary (only get this when block copied out) */\n        if (strm.data_type & 128) {\n            /* if that was the last block, then done */\n            if (last)\n                break;\n\n            /* number of unused bits in last byte */\n            pos = strm.data_type & 7;\n\n            /* find the next last-block bit */\n            if (pos != 0) {\n                /* next last-block bit is in last used byte */\n                pos = 0x100 >> pos;\n                last = strm.next_in[-1] & pos;\n                if (last && clr)\n                    in->buf[strm.next_in - in->buf - 1] &= ~pos;\n            }\n            else {\n                /* next last-block bit is in next unused byte */\n                if (strm.avail_in == 0) {\n                    /* don't have that byte yet -- get it */\n                    fwrite(start, 1, strm.next_in - start, out);\n                    start = in->buf;\n                    in->left = 0;\n                    zpull(&strm, in);\n                }\n                last = strm.next_in[0] & 1;\n                if (last && clr)\n                    in->buf[strm.next_in - in->buf] &= ~1;\n            }\n        }\n    }\n\n    /* update buffer with unused input */\n    in->left = strm.avail_in;\n    in->next = in->buf + (strm.next_in - in->buf);\n\n    /* copy used input, write empty blocks to get to byte boundary */\n    pos = strm.data_type & 7;\n    fwrite(start, 1, in->next - start - 1, out);\n    last = in->next[-1];\n    if (pos == 0 || !clr)\n        /* already at byte boundary, or last file: write last byte */\n        putc(last, out);\n    else {\n        /* append empty blocks to last byte */\n        last &= ((0x100 >> pos) - 1);       /* assure unused bits are zero */\n        if (pos & 1) {\n            /* odd -- append an empty stored block */\n            putc(last, out);\n            if (pos == 1)\n                putc(0, out);               /* two more bits in block header */\n            fwrite(\"\\0\\0\\xff\\xff\", 1, 4, out);\n        }\n        else {\n            /* even -- append 1, 2, or 3 empty fixed blocks */\n            switch (pos) {\n            case 6:\n                putc(last | 8, out);\n                last = 0;\n            case 4:\n                putc(last | 0x20, out);\n                last = 0;\n            case 2:\n                putc(last | 0x80, out);\n                putc(0, out);\n            }\n        }\n    }\n\n    /* update crc and tot */\n    *crc = crc32_combine(*crc, bget4(in), len);\n    *tot += (unsigned long)len;\n\n    /* clean up */\n    inflateEnd(&strm);\n    free(junk);\n    bclose(in);\n\n    /* write trailer if this is the last gzip file */\n    if (!clr) {\n        put4(*crc, out);\n        put4(*tot, out);\n    }\n}\n\n/* join the gzip files on the command line, write result to stdout */\nint main(int argc, char **argv)\n{\n    unsigned long crc, tot;     /* running crc and total uncompressed length */\n\n    /* skip command name */\n    argc--;\n    argv++;\n\n    /* show usage if no arguments */\n    if (argc == 0) {\n        fputs(\"gzjoin usage: gzjoin f1.gz [f2.gz [f3.gz ...]] > fjoin.gz\\n\",\n              stderr);\n        return 0;\n    }\n\n    /* join gzip files on command line and write to stdout */\n    gzinit(&crc, &tot, stdout);\n    while (argc--)\n        gzcopy(*argv++, argc, &crc, &tot, stdout);\n\n    /* done */\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/examples/gzlog.c",
    "content": "/*\n * gzlog.c\n * Copyright (C) 2004, 2008, 2012 Mark Adler, all rights reserved\n * For conditions of distribution and use, see copyright notice in gzlog.h\n * version 2.2, 14 Aug 2012\n */\n\n/*\n   gzlog provides a mechanism for frequently appending short strings to a gzip\n   file that is efficient both in execution time and compression ratio.  The\n   strategy is to write the short strings in an uncompressed form to the end of\n   the gzip file, only compressing when the amount of uncompressed data has\n   reached a given threshold.\n\n   gzlog also provides protection against interruptions in the process due to\n   system crashes.  The status of the operation is recorded in an extra field\n   in the gzip file, and is only updated once the gzip file is brought to a\n   valid state.  The last data to be appended or compressed is saved in an\n   auxiliary file, so that if the operation is interrupted, it can be completed\n   the next time an append operation is attempted.\n\n   gzlog maintains another auxiliary file with the last 32K of data from the\n   compressed portion, which is preloaded for the compression of the subsequent\n   data.  This minimizes the impact to the compression ratio of appending.\n */\n\n/*\n   Operations Concept:\n\n   Files (log name \"foo\"):\n   foo.gz -- gzip file with the complete log\n   foo.add -- last message to append or last data to compress\n   foo.dict -- dictionary of the last 32K of data for next compression\n   foo.temp -- temporary dictionary file for compression after this one\n   foo.lock -- lock file for reading and writing the other files\n   foo.repairs -- log file for log file recovery operations (not compressed)\n\n   gzip file structure:\n   - fixed-length (no file name) header with extra field (see below)\n   - compressed data ending initially with empty stored block\n   - uncompressed data filling out originally empty stored block and\n     subsequent stored blocks as needed (16K max each)\n   - gzip trailer\n   - no junk at end (no other gzip streams)\n\n   When appending data, the information in the first three items above plus the\n   foo.add file are sufficient to recover an interrupted append operation.  The\n   extra field has the necessary information to restore the start of the last\n   stored block and determine where to append the data in the foo.add file, as\n   well as the crc and length of the gzip data before the append operation.\n\n   The foo.add file is created before the gzip file is marked for append, and\n   deleted after the gzip file is marked as complete.  So if the append\n   operation is interrupted, the data to add will still be there.  If due to\n   some external force, the foo.add file gets deleted between when the append\n   operation was interrupted and when recovery is attempted, the gzip file will\n   still be restored, but without the appended data.\n\n   When compressing data, the information in the first two items above plus the\n   foo.add file are sufficient to recover an interrupted compress operation.\n   The extra field has the necessary information to find the end of the\n   compressed data, and contains both the crc and length of just the compressed\n   data and of the complete set of data including the contents of the foo.add\n   file.\n\n   Again, the foo.add file is maintained during the compress operation in case\n   of an interruption.  If in the unlikely event the foo.add file with the data\n   to be compressed is missing due to some external force, a gzip file with\n   just the previous compressed data will be reconstructed.  In this case, all\n   of the data that was to be compressed is lost (approximately one megabyte).\n   This will not occur if all that happened was an interruption of the compress\n   operation.\n\n   The third state that is marked is the replacement of the old dictionary with\n   the new dictionary after a compress operation.  Once compression is\n   complete, the gzip file is marked as being in the replace state.  This\n   completes the gzip file, so an interrupt after being so marked does not\n   result in recompression.  Then the dictionary file is replaced, and the gzip\n   file is marked as completed.  This state prevents the possibility of\n   restarting compression with the wrong dictionary file.\n\n   All three operations are wrapped by a lock/unlock procedure.  In order to\n   gain exclusive access to the log files, first a foo.lock file must be\n   exclusively created.  When all operations are complete, the lock is\n   released by deleting the foo.lock file.  If when attempting to create the\n   lock file, it already exists and the modify time of the lock file is more\n   than five minutes old (set by the PATIENCE define below), then the old\n   lock file is considered stale and deleted, and the exclusive creation of\n   the lock file is retried.  To assure that there are no false assessments\n   of the staleness of the lock file, the operations periodically touch the\n   lock file to update the modified date.\n\n   Following is the definition of the extra field with all of the information\n   required to enable the above append and compress operations and their\n   recovery if interrupted.  Multi-byte values are stored little endian\n   (consistent with the gzip format).  File pointers are eight bytes long.\n   The crc's and lengths for the gzip trailer are four bytes long.  (Note that\n   the length at the end of a gzip file is used for error checking only, and\n   for large files is actually the length modulo 2^32.)  The stored block\n   length is two bytes long.  The gzip extra field two-byte identification is\n   \"ap\" for append.  It is assumed that writing the extra field to the file is\n   an \"atomic\" operation.  That is, either all of the extra field is written\n   to the file, or none of it is, if the operation is interrupted right at the\n   point of updating the extra field.  This is a reasonable assumption, since\n   the extra field is within the first 52 bytes of the file, which is smaller\n   than any expected block size for a mass storage device (usually 512 bytes or\n   larger).\n\n   Extra field (35 bytes):\n   - Pointer to first stored block length -- this points to the two-byte length\n     of the first stored block, which is followed by the two-byte, one's\n     complement of that length.  The stored block length is preceded by the\n     three-bit header of the stored block, which is the actual start of the\n     stored block in the deflate format.  See the bit offset field below.\n   - Pointer to the last stored block length.  This is the same as above, but\n     for the last stored block of the uncompressed data in the gzip file.\n     Initially this is the same as the first stored block length pointer.\n     When the stored block gets to 16K (see the MAX_STORE define), then a new\n     stored block as added, at which point the last stored block length pointer\n     is different from the first stored block length pointer.  When they are\n     different, the first bit of the last stored block header is eight bits, or\n     one byte back from the block length.\n   - Compressed data crc and length.  This is the crc and length of the data\n     that is in the compressed portion of the deflate stream.  These are used\n     only in the event that the foo.add file containing the data to compress is\n     lost after a compress operation is interrupted.\n   - Total data crc and length.  This is the crc and length of all of the data\n     stored in the gzip file, compressed and uncompressed.  It is used to\n     reconstruct the gzip trailer when compressing, as well as when recovering\n     interrupted operations.\n   - Final stored block length.  This is used to quickly find where to append,\n     and allows the restoration of the original final stored block state when\n     an append operation is interrupted.\n   - First stored block start as the number of bits back from the final stored\n     block first length byte.  This value is in the range of 3..10, and is\n     stored as the low three bits of the final byte of the extra field after\n     subtracting three (0..7).  This allows the last-block bit of the stored\n     block header to be updated when a new stored block is added, for the case\n     when the first stored block and the last stored block are the same.  (When\n     they are different, the numbers of bits back is known to be eight.)  This\n     also allows for new compressed data to be appended to the old compressed\n     data in the compress operation, overwriting the previous first stored\n     block, or for the compressed data to be terminated and a valid gzip file\n     reconstructed on the off chance that a compression operation was\n     interrupted and the data to compress in the foo.add file was deleted.\n   - The operation in process.  This is the next two bits in the last byte (the\n     bits under the mask 0x18).  The are interpreted as 0: nothing in process,\n     1: append in process, 2: compress in process, 3: replace in process.\n   - The top three bits of the last byte in the extra field are reserved and\n     are currently set to zero.\n\n   Main procedure:\n   - Exclusively create the foo.lock file using the O_CREAT and O_EXCL modes of\n     the system open() call.  If the modify time of an existing lock file is\n     more than PATIENCE seconds old, then the lock file is deleted and the\n     exclusive create is retried.\n   - Load the extra field from the foo.gz file, and see if an operation was in\n     progress but not completed.  If so, apply the recovery procedure below.\n   - Perform the append procedure with the provided data.\n   - If the uncompressed data in the foo.gz file is 1MB or more, apply the\n     compress procedure.\n   - Delete the foo.lock file.\n\n   Append procedure:\n   - Put what to append in the foo.add file so that the operation can be\n     restarted if this procedure is interrupted.\n   - Mark the foo.gz extra field with the append operation in progress.\n   + Restore the original last-block bit and stored block length of the last\n     stored block from the information in the extra field, in case a previous\n     append operation was interrupted.\n   - Append the provided data to the last stored block, creating new stored\n     blocks as needed and updating the stored blocks last-block bits and\n     lengths.\n   - Update the crc and length with the new data, and write the gzip trailer.\n   - Write over the extra field (with a single write operation) with the new\n     pointers, lengths, and crc's, and mark the gzip file as not in process.\n     Though there is still a foo.add file, it will be ignored since nothing\n     is in process.  If a foo.add file is leftover from a previously\n     completed operation, it is truncated when writing new data to it.\n   - Delete the foo.add file.\n\n   Compress and replace procedures:\n   - Read all of the uncompressed data in the stored blocks in foo.gz and write\n     it to foo.add.  Also write foo.temp with the last 32K of that data to\n     provide a dictionary for the next invocation of this procedure.\n   - Rewrite the extra field marking foo.gz with a compression in process.\n   * If there is no data provided to compress (due to a missing foo.add file\n     when recovering), reconstruct and truncate the foo.gz file to contain\n     only the previous compressed data and proceed to the step after the next\n     one.  Otherwise ...\n   - Compress the data with the dictionary in foo.dict, and write to the\n     foo.gz file starting at the bit immediately following the last previously\n     compressed block.  If there is no foo.dict, proceed anyway with the\n     compression at slightly reduced efficiency.  (For the foo.dict file to be\n     missing requires some external failure beyond simply the interruption of\n     a compress operation.)  During this process, the foo.lock file is\n     periodically touched to assure that that file is not considered stale by\n     another process before we're done.  The deflation is terminated with a\n     non-last empty static block (10 bits long), that is then located and\n     written over by a last-bit-set empty stored block.\n   - Append the crc and length of the data in the gzip file (previously\n     calculated during the append operations).\n   - Write over the extra field with the updated stored block offsets, bits\n     back, crc's, and lengths, and mark foo.gz as in process for a replacement\n     of the dictionary.\n   @ Delete the foo.add file.\n   - Replace foo.dict with foo.temp.\n   - Write over the extra field, marking foo.gz as complete.\n\n   Recovery procedure:\n   - If not a replace recovery, read in the foo.add file, and provide that data\n     to the appropriate recovery below.  If there is no foo.add file, provide\n     a zero data length to the recovery.  In that case, the append recovery\n     restores the foo.gz to the previous compressed + uncompressed data state.\n     For the the compress recovery, a missing foo.add file results in foo.gz\n     being restored to the previous compressed-only data state.\n   - Append recovery:\n     - Pick up append at + step above\n   - Compress recovery:\n     - Pick up compress at * step above\n   - Replace recovery:\n     - Pick up compress at @ step above\n   - Log the repair with a date stamp in foo.repairs\n */\n\n#include <sys/types.h>\n#include <stdio.h>      /* rename, fopen, fprintf, fclose */\n#include <stdlib.h>     /* malloc, free */\n#include <string.h>     /* strlen, strrchr, strcpy, strncpy, strcmp */\n#include <fcntl.h>      /* open */\n#include <unistd.h>     /* lseek, read, write, close, unlink, sleep, */\n                        /* ftruncate, fsync */\n#include <errno.h>      /* errno */\n#include <time.h>       /* time, ctime */\n#include <sys/stat.h>   /* stat */\n#include <sys/time.h>   /* utimes */\n#include \"zlib.h\"       /* crc32 */\n\n#include \"gzlog.h\"      /* header for external access */\n\n#define local static\ntypedef unsigned int uint;\ntypedef unsigned long ulong;\n\n/* Macro for debugging to deterministically force recovery operations */\n#ifdef DEBUG\n    #include <setjmp.h>         /* longjmp */\n    jmp_buf gzlog_jump;         /* where to go back to */\n    int gzlog_bail = 0;         /* which point to bail at (1..8) */\n    int gzlog_count = -1;       /* number of times through to wait */\n#   define BAIL(n) do { if (n == gzlog_bail && gzlog_count-- == 0) \\\n                            longjmp(gzlog_jump, gzlog_bail); } while (0)\n#else\n#   define BAIL(n)\n#endif\n\n/* how old the lock file can be in seconds before considering it stale */\n#define PATIENCE 300\n\n/* maximum stored block size in Kbytes -- must be in 1..63 */\n#define MAX_STORE 16\n\n/* number of stored Kbytes to trigger compression (must be >= 32 to allow\n   dictionary construction, and <= 204 * MAX_STORE, in order for >> 10 to\n   discard the stored block headers contribution of five bytes each) */\n#define TRIGGER 1024\n\n/* size of a deflate dictionary (this cannot be changed) */\n#define DICT 32768U\n\n/* values for the operation (2 bits) */\n#define NO_OP 0\n#define APPEND_OP 1\n#define COMPRESS_OP 2\n#define REPLACE_OP 3\n\n/* macros to extract little-endian integers from an unsigned byte buffer */\n#define PULL2(p) ((p)[0]+((uint)((p)[1])<<8))\n#define PULL4(p) (PULL2(p)+((ulong)PULL2(p+2)<<16))\n#define PULL8(p) (PULL4(p)+((off_t)PULL4(p+4)<<32))\n\n/* macros to store integers into a byte buffer in little-endian order */\n#define PUT2(p,a) do {(p)[0]=a;(p)[1]=(a)>>8;} while(0)\n#define PUT4(p,a) do {PUT2(p,a);PUT2(p+2,a>>16);} while(0)\n#define PUT8(p,a) do {PUT4(p,a);PUT4(p+4,a>>32);} while(0)\n\n/* internal structure for log information */\n#define LOGID \"\\106\\035\\172\"    /* should be three non-zero characters */\nstruct log {\n    char id[4];     /* contains LOGID to detect inadvertent overwrites */\n    int fd;         /* file descriptor for .gz file, opened read/write */\n    char *path;     /* allocated path, e.g. \"/var/log/foo\" or \"foo\" */\n    char *end;      /* end of path, for appending suffices such as \".gz\" */\n    off_t first;    /* offset of first stored block first length byte */\n    int back;       /* location of first block id in bits back from first */\n    uint stored;    /* bytes currently in last stored block */\n    off_t last;     /* offset of last stored block first length byte */\n    ulong ccrc;     /* crc of compressed data */\n    ulong clen;     /* length (modulo 2^32) of compressed data */\n    ulong tcrc;     /* crc of total data */\n    ulong tlen;     /* length (modulo 2^32) of total data */\n    time_t lock;    /* last modify time of our lock file */\n};\n\n/* gzip header for gzlog */\nlocal unsigned char log_gzhead[] = {\n    0x1f, 0x8b,                 /* magic gzip id */\n    8,                          /* compression method is deflate */\n    4,                          /* there is an extra field (no file name) */\n    0, 0, 0, 0,                 /* no modification time provided */\n    0, 0xff,                    /* no extra flags, no OS specified */\n    39, 0, 'a', 'p', 35, 0      /* extra field with \"ap\" subfield */\n                                /* 35 is EXTRA, 39 is EXTRA + 4 */\n};\n\n#define HEAD sizeof(log_gzhead)     /* should be 16 */\n\n/* initial gzip extra field content (52 == HEAD + EXTRA + 1) */\nlocal unsigned char log_gzext[] = {\n    52, 0, 0, 0, 0, 0, 0, 0,    /* offset of first stored block length */\n    52, 0, 0, 0, 0, 0, 0, 0,    /* offset of last stored block length */\n    0, 0, 0, 0, 0, 0, 0, 0,     /* compressed data crc and length */\n    0, 0, 0, 0, 0, 0, 0, 0,     /* total data crc and length */\n    0, 0,                       /* final stored block data length */\n    5                           /* op is NO_OP, last bit 8 bits back */\n};\n\n#define EXTRA sizeof(log_gzext)     /* should be 35 */\n\n/* initial gzip data and trailer */\nlocal unsigned char log_gzbody[] = {\n    1, 0, 0, 0xff, 0xff,        /* empty stored block (last) */\n    0, 0, 0, 0,                 /* crc */\n    0, 0, 0, 0                  /* uncompressed length */\n};\n\n#define BODY sizeof(log_gzbody)\n\n/* Exclusively create foo.lock in order to negotiate exclusive access to the\n   foo.* files.  If the modify time of an existing lock file is greater than\n   PATIENCE seconds in the past, then consider the lock file to have been\n   abandoned, delete it, and try the exclusive create again.  Save the lock\n   file modify time for verification of ownership.  Return 0 on success, or -1\n   on failure, usually due to an access restriction or invalid path.  Note that\n   if stat() or unlink() fails, it may be due to another process noticing the\n   abandoned lock file a smidge sooner and deleting it, so those are not\n   flagged as an error. */\nlocal int log_lock(struct log *log)\n{\n    int fd;\n    struct stat st;\n\n    strcpy(log->end, \".lock\");\n    while ((fd = open(log->path, O_CREAT | O_EXCL, 0644)) < 0) {\n        if (errno != EEXIST)\n            return -1;\n        if (stat(log->path, &st) == 0 && time(NULL) - st.st_mtime > PATIENCE) {\n            unlink(log->path);\n            continue;\n        }\n        sleep(2);       /* relinquish the CPU for two seconds while waiting */\n    }\n    close(fd);\n    if (stat(log->path, &st) == 0)\n        log->lock = st.st_mtime;\n    return 0;\n}\n\n/* Update the modify time of the lock file to now, in order to prevent another\n   task from thinking that the lock is stale.  Save the lock file modify time\n   for verification of ownership. */\nlocal void log_touch(struct log *log)\n{\n    struct stat st;\n\n    strcpy(log->end, \".lock\");\n    utimes(log->path, NULL);\n    if (stat(log->path, &st) == 0)\n        log->lock = st.st_mtime;\n}\n\n/* Check the log file modify time against what is expected.  Return true if\n   this is not our lock.  If it is our lock, touch it to keep it. */\nlocal int log_check(struct log *log)\n{\n    struct stat st;\n\n    strcpy(log->end, \".lock\");\n    if (stat(log->path, &st) || st.st_mtime != log->lock)\n        return 1;\n    log_touch(log);\n    return 0;\n}\n\n/* Unlock a previously acquired lock, but only if it's ours. */\nlocal void log_unlock(struct log *log)\n{\n    if (log_check(log))\n        return;\n    strcpy(log->end, \".lock\");\n    unlink(log->path);\n    log->lock = 0;\n}\n\n/* Check the gzip header and read in the extra field, filling in the values in\n   the log structure.  Return op on success or -1 if the gzip header was not as\n   expected.  op is the current operation in progress last written to the extra\n   field.  This assumes that the gzip file has already been opened, with the\n   file descriptor log->fd. */\nlocal int log_head(struct log *log)\n{\n    int op;\n    unsigned char buf[HEAD + EXTRA];\n\n    if (lseek(log->fd, 0, SEEK_SET) < 0 ||\n        read(log->fd, buf, HEAD + EXTRA) != HEAD + EXTRA ||\n        memcmp(buf, log_gzhead, HEAD)) {\n        return -1;\n    }\n    log->first = PULL8(buf + HEAD);\n    log->last = PULL8(buf + HEAD + 8);\n    log->ccrc = PULL4(buf + HEAD + 16);\n    log->clen = PULL4(buf + HEAD + 20);\n    log->tcrc = PULL4(buf + HEAD + 24);\n    log->tlen = PULL4(buf + HEAD + 28);\n    log->stored = PULL2(buf + HEAD + 32);\n    log->back = 3 + (buf[HEAD + 34] & 7);\n    op = (buf[HEAD + 34] >> 3) & 3;\n    return op;\n}\n\n/* Write over the extra field contents, marking the operation as op.  Use fsync\n   to assure that the device is written to, and in the requested order.  This\n   operation, and only this operation, is assumed to be atomic in order to\n   assure that the log is recoverable in the event of an interruption at any\n   point in the process.  Return -1 if the write to foo.gz failed. */\nlocal int log_mark(struct log *log, int op)\n{\n    int ret;\n    unsigned char ext[EXTRA];\n\n    PUT8(ext, log->first);\n    PUT8(ext + 8, log->last);\n    PUT4(ext + 16, log->ccrc);\n    PUT4(ext + 20, log->clen);\n    PUT4(ext + 24, log->tcrc);\n    PUT4(ext + 28, log->tlen);\n    PUT2(ext + 32, log->stored);\n    ext[34] = log->back - 3 + (op << 3);\n    fsync(log->fd);\n    ret = lseek(log->fd, HEAD, SEEK_SET) < 0 ||\n          write(log->fd, ext, EXTRA) != EXTRA ? -1 : 0;\n    fsync(log->fd);\n    return ret;\n}\n\n/* Rewrite the last block header bits and subsequent zero bits to get to a byte\n   boundary, setting the last block bit if last is true, and then write the\n   remainder of the stored block header (length and one's complement).  Leave\n   the file pointer after the end of the last stored block data.  Return -1 if\n   there is a read or write failure on the foo.gz file */\nlocal int log_last(struct log *log, int last)\n{\n    int back, len, mask;\n    unsigned char buf[6];\n\n    /* determine the locations of the bytes and bits to modify */\n    back = log->last == log->first ? log->back : 8;\n    len = back > 8 ? 2 : 1;                 /* bytes back from log->last */\n    mask = 0x80 >> ((back - 1) & 7);        /* mask for block last-bit */\n\n    /* get the byte to modify (one or two back) into buf[0] -- don't need to\n       read the byte if the last-bit is eight bits back, since in that case\n       the entire byte will be modified */\n    buf[0] = 0;\n    if (back != 8 && (lseek(log->fd, log->last - len, SEEK_SET) < 0 ||\n                      read(log->fd, buf, 1) != 1))\n        return -1;\n\n    /* change the last-bit of the last stored block as requested -- note\n       that all bits above the last-bit are set to zero, per the type bits\n       of a stored block being 00 and per the convention that the bits to\n       bring the stream to a byte boundary are also zeros */\n    buf[1] = 0;\n    buf[2 - len] = (*buf & (mask - 1)) + (last ? mask : 0);\n\n    /* write the modified stored block header and lengths, move the file\n       pointer to after the last stored block data */\n    PUT2(buf + 2, log->stored);\n    PUT2(buf + 4, log->stored ^ 0xffff);\n    return lseek(log->fd, log->last - len, SEEK_SET) < 0 ||\n           write(log->fd, buf + 2 - len, len + 4) != len + 4 ||\n           lseek(log->fd, log->stored, SEEK_CUR) < 0 ? -1 : 0;\n}\n\n/* Append len bytes from data to the locked and open log file.  len may be zero\n   if recovering and no .add file was found.  In that case, the previous state\n   of the foo.gz file is restored.  The data is appended uncompressed in\n   deflate stored blocks.  Return -1 if there was an error reading or writing\n   the foo.gz file. */\nlocal int log_append(struct log *log, unsigned char *data, size_t len)\n{\n    uint put;\n    off_t end;\n    unsigned char buf[8];\n\n    /* set the last block last-bit and length, in case recovering an\n       interrupted append, then position the file pointer to append to the\n       block */\n    if (log_last(log, 1))\n        return -1;\n\n    /* append, adding stored blocks and updating the offset of the last stored\n       block as needed, and update the total crc and length */\n    while (len) {\n        /* append as much as we can to the last block */\n        put = (MAX_STORE << 10) - log->stored;\n        if (put > len)\n            put = (uint)len;\n        if (put) {\n            if (write(log->fd, data, put) != put)\n                return -1;\n            BAIL(1);\n            log->tcrc = crc32(log->tcrc, data, put);\n            log->tlen += put;\n            log->stored += put;\n            data += put;\n            len -= put;\n        }\n\n        /* if we need to, add a new empty stored block */\n        if (len) {\n            /* mark current block as not last */\n            if (log_last(log, 0))\n                return -1;\n\n            /* point to new, empty stored block */\n            log->last += 4 + log->stored + 1;\n            log->stored = 0;\n        }\n\n        /* mark last block as last, update its length */\n        if (log_last(log, 1))\n            return -1;\n        BAIL(2);\n    }\n\n    /* write the new crc and length trailer, and truncate just in case (could\n       be recovering from partial append with a missing foo.add file) */\n    PUT4(buf, log->tcrc);\n    PUT4(buf + 4, log->tlen);\n    if (write(log->fd, buf, 8) != 8 ||\n        (end = lseek(log->fd, 0, SEEK_CUR)) < 0 || ftruncate(log->fd, end))\n        return -1;\n\n    /* write the extra field, marking the log file as done, delete .add file */\n    if (log_mark(log, NO_OP))\n        return -1;\n    strcpy(log->end, \".add\");\n    unlink(log->path);          /* ignore error, since may not exist */\n    return 0;\n}\n\n/* Replace the foo.dict file with the foo.temp file.  Also delete the foo.add\n   file, since the compress operation may have been interrupted before that was\n   done.  Returns 1 if memory could not be allocated, or -1 if reading or\n   writing foo.gz fails, or if the rename fails for some reason other than\n   foo.temp not existing.  foo.temp not existing is a permitted error, since\n   the replace operation may have been interrupted after the rename is done,\n   but before foo.gz is marked as complete. */\nlocal int log_replace(struct log *log)\n{\n    int ret;\n    char *dest;\n\n    /* delete foo.add file */\n    strcpy(log->end, \".add\");\n    unlink(log->path);         /* ignore error, since may not exist */\n    BAIL(3);\n\n    /* rename foo.name to foo.dict, replacing foo.dict if it exists */\n    strcpy(log->end, \".dict\");\n    dest = malloc(strlen(log->path) + 1);\n    if (dest == NULL)\n        return -2;\n    strcpy(dest, log->path);\n    strcpy(log->end, \".temp\");\n    ret = rename(log->path, dest);\n    free(dest);\n    if (ret && errno != ENOENT)\n        return -1;\n    BAIL(4);\n\n    /* mark the foo.gz file as done */\n    return log_mark(log, NO_OP);\n}\n\n/* Compress the len bytes at data and append the compressed data to the\n   foo.gz deflate data immediately after the previous compressed data.  This\n   overwrites the previous uncompressed data, which was stored in foo.add\n   and is the data provided in data[0..len-1].  If this operation is\n   interrupted, it picks up at the start of this routine, with the foo.add\n   file read in again.  If there is no data to compress (len == 0), then we\n   simply terminate the foo.gz file after the previously compressed data,\n   appending a final empty stored block and the gzip trailer.  Return -1 if\n   reading or writing the log.gz file failed, or -2 if there was a memory\n   allocation failure. */\nlocal int log_compress(struct log *log, unsigned char *data, size_t len)\n{\n    int fd;\n    uint got, max;\n    ssize_t dict;\n    off_t end;\n    z_stream strm;\n    unsigned char buf[DICT];\n\n    /* compress and append compressed data */\n    if (len) {\n        /* set up for deflate, allocating memory */\n        strm.zalloc = Z_NULL;\n        strm.zfree = Z_NULL;\n        strm.opaque = Z_NULL;\n        if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8,\n                         Z_DEFAULT_STRATEGY) != Z_OK)\n            return -2;\n\n        /* read in dictionary (last 32K of data that was compressed) */\n        strcpy(log->end, \".dict\");\n        fd = open(log->path, O_RDONLY, 0);\n        if (fd >= 0) {\n            dict = read(fd, buf, DICT);\n            close(fd);\n            if (dict < 0) {\n                deflateEnd(&strm);\n                return -1;\n            }\n            if (dict)\n                deflateSetDictionary(&strm, buf, (uint)dict);\n        }\n        log_touch(log);\n\n        /* prime deflate with last bits of previous block, position write\n           pointer to write those bits and overwrite what follows */\n        if (lseek(log->fd, log->first - (log->back > 8 ? 2 : 1),\n                SEEK_SET) < 0 ||\n            read(log->fd, buf, 1) != 1 || lseek(log->fd, -1, SEEK_CUR) < 0) {\n            deflateEnd(&strm);\n            return -1;\n        }\n        deflatePrime(&strm, (8 - log->back) & 7, *buf);\n\n        /* compress, finishing with a partial non-last empty static block */\n        strm.next_in = data;\n        max = (((uint)0 - 1) >> 1) + 1; /* in case int smaller than size_t */\n        do {\n            strm.avail_in = len > max ? max : (uint)len;\n            len -= strm.avail_in;\n            do {\n                strm.avail_out = DICT;\n                strm.next_out = buf;\n                deflate(&strm, len ? Z_NO_FLUSH : Z_PARTIAL_FLUSH);\n                got = DICT - strm.avail_out;\n                if (got && write(log->fd, buf, got) != got) {\n                    deflateEnd(&strm);\n                    return -1;\n                }\n                log_touch(log);\n            } while (strm.avail_out == 0);\n        } while (len);\n        deflateEnd(&strm);\n        BAIL(5);\n\n        /* find start of empty static block -- scanning backwards the first one\n           bit is the second bit of the block, if the last byte is zero, then\n           we know the byte before that has a one in the top bit, since an\n           empty static block is ten bits long */\n        if ((log->first = lseek(log->fd, -1, SEEK_CUR)) < 0 ||\n            read(log->fd, buf, 1) != 1)\n            return -1;\n        log->first++;\n        if (*buf) {\n            log->back = 1;\n            while ((*buf & ((uint)1 << (8 - log->back++))) == 0)\n                ;       /* guaranteed to terminate, since *buf != 0 */\n        }\n        else\n            log->back = 10;\n\n        /* update compressed crc and length */\n        log->ccrc = log->tcrc;\n        log->clen = log->tlen;\n    }\n    else {\n        /* no data to compress -- fix up existing gzip stream */\n        log->tcrc = log->ccrc;\n        log->tlen = log->clen;\n    }\n\n    /* complete and truncate gzip stream */\n    log->last = log->first;\n    log->stored = 0;\n    PUT4(buf, log->tcrc);\n    PUT4(buf + 4, log->tlen);\n    if (log_last(log, 1) || write(log->fd, buf, 8) != 8 ||\n        (end = lseek(log->fd, 0, SEEK_CUR)) < 0 || ftruncate(log->fd, end))\n        return -1;\n    BAIL(6);\n\n    /* mark as being in the replace operation */\n    if (log_mark(log, REPLACE_OP))\n        return -1;\n\n    /* execute the replace operation and mark the file as done */\n    return log_replace(log);\n}\n\n/* log a repair record to the .repairs file */\nlocal void log_log(struct log *log, int op, char *record)\n{\n    time_t now;\n    FILE *rec;\n\n    now = time(NULL);\n    strcpy(log->end, \".repairs\");\n    rec = fopen(log->path, \"a\");\n    if (rec == NULL)\n        return;\n    fprintf(rec, \"%.24s %s recovery: %s\\n\", ctime(&now), op == APPEND_OP ?\n            \"append\" : (op == COMPRESS_OP ? \"compress\" : \"replace\"), record);\n    fclose(rec);\n    return;\n}\n\n/* Recover the interrupted operation op.  First read foo.add for recovering an\n   append or compress operation.  Return -1 if there was an error reading or\n   writing foo.gz or reading an existing foo.add, or -2 if there was a memory\n   allocation failure. */\nlocal int log_recover(struct log *log, int op)\n{\n    int fd, ret = 0;\n    unsigned char *data = NULL;\n    size_t len = 0;\n    struct stat st;\n\n    /* log recovery */\n    log_log(log, op, \"start\");\n\n    /* load foo.add file if expected and present */\n    if (op == APPEND_OP || op == COMPRESS_OP) {\n        strcpy(log->end, \".add\");\n        if (stat(log->path, &st) == 0 && st.st_size) {\n            len = (size_t)(st.st_size);\n            if ((off_t)len != st.st_size ||\n                    (data = malloc(st.st_size)) == NULL) {\n                log_log(log, op, \"allocation failure\");\n                return -2;\n            }\n            if ((fd = open(log->path, O_RDONLY, 0)) < 0) {\n                log_log(log, op, \".add file read failure\");\n                return -1;\n            }\n            ret = (size_t)read(fd, data, len) != len;\n            close(fd);\n            if (ret) {\n                log_log(log, op, \".add file read failure\");\n                return -1;\n            }\n            log_log(log, op, \"loaded .add file\");\n        }\n        else\n            log_log(log, op, \"missing .add file!\");\n    }\n\n    /* recover the interrupted operation */\n    switch (op) {\n    case APPEND_OP:\n        ret = log_append(log, data, len);\n        break;\n    case COMPRESS_OP:\n        ret = log_compress(log, data, len);\n        break;\n    case REPLACE_OP:\n        ret = log_replace(log);\n    }\n\n    /* log status */\n    log_log(log, op, ret ? \"failure\" : \"complete\");\n\n    /* clean up */\n    if (data != NULL)\n        free(data);\n    return ret;\n}\n\n/* Close the foo.gz file (if open) and release the lock. */\nlocal void log_close(struct log *log)\n{\n    if (log->fd >= 0)\n        close(log->fd);\n    log->fd = -1;\n    log_unlock(log);\n}\n\n/* Open foo.gz, verify the header, and load the extra field contents, after\n   first creating the foo.lock file to gain exclusive access to the foo.*\n   files.  If foo.gz does not exist or is empty, then write the initial header,\n   extra, and body content of an empty foo.gz log file.  If there is an error\n   creating the lock file due to access restrictions, or an error reading or\n   writing the foo.gz file, or if the foo.gz file is not a proper log file for\n   this object (e.g. not a gzip file or does not contain the expected extra\n   field), then return true.  If there is an error, the lock is released.\n   Otherwise, the lock is left in place. */\nlocal int log_open(struct log *log)\n{\n    int op;\n\n    /* release open file resource if left over -- can occur if lock lost\n       between gzlog_open() and gzlog_write() */\n    if (log->fd >= 0)\n        close(log->fd);\n    log->fd = -1;\n\n    /* negotiate exclusive access */\n    if (log_lock(log) < 0)\n        return -1;\n\n    /* open the log file, foo.gz */\n    strcpy(log->end, \".gz\");\n    log->fd = open(log->path, O_RDWR | O_CREAT, 0644);\n    if (log->fd < 0) {\n        log_close(log);\n        return -1;\n    }\n\n    /* if new, initialize foo.gz with an empty log, delete old dictionary */\n    if (lseek(log->fd, 0, SEEK_END) == 0) {\n        if (write(log->fd, log_gzhead, HEAD) != HEAD ||\n            write(log->fd, log_gzext, EXTRA) != EXTRA ||\n            write(log->fd, log_gzbody, BODY) != BODY) {\n            log_close(log);\n            return -1;\n        }\n        strcpy(log->end, \".dict\");\n        unlink(log->path);\n    }\n\n    /* verify log file and load extra field information */\n    if ((op = log_head(log)) < 0) {\n        log_close(log);\n        return -1;\n    }\n\n    /* check for interrupted process and if so, recover */\n    if (op != NO_OP && log_recover(log, op)) {\n        log_close(log);\n        return -1;\n    }\n\n    /* touch the lock file to prevent another process from grabbing it */\n    log_touch(log);\n    return 0;\n}\n\n/* See gzlog.h for the description of the external methods below */\ngzlog *gzlog_open(char *path)\n{\n    size_t n;\n    struct log *log;\n\n    /* check arguments */\n    if (path == NULL || *path == 0)\n        return NULL;\n\n    /* allocate and initialize log structure */\n    log = malloc(sizeof(struct log));\n    if (log == NULL)\n        return NULL;\n    strcpy(log->id, LOGID);\n    log->fd = -1;\n\n    /* save path and end of path for name construction */\n    n = strlen(path);\n    log->path = malloc(n + 9);              /* allow for \".repairs\" */\n    if (log->path == NULL) {\n        free(log);\n        return NULL;\n    }\n    strcpy(log->path, path);\n    log->end = log->path + n;\n\n    /* gain exclusive access and verify log file -- may perform a\n       recovery operation if needed */\n    if (log_open(log)) {\n        free(log->path);\n        free(log);\n        return NULL;\n    }\n\n    /* return pointer to log structure */\n    return log;\n}\n\n/* gzlog_compress() return values:\n    0: all good\n   -1: file i/o error (usually access issue)\n   -2: memory allocation failure\n   -3: invalid log pointer argument */\nint gzlog_compress(gzlog *logd)\n{\n    int fd, ret;\n    uint block;\n    size_t len, next;\n    unsigned char *data, buf[5];\n    struct log *log = logd;\n\n    /* check arguments */\n    if (log == NULL || strcmp(log->id, LOGID))\n        return -3;\n\n    /* see if we lost the lock -- if so get it again and reload the extra\n       field information (it probably changed), recover last operation if\n       necessary */\n    if (log_check(log) && log_open(log))\n        return -1;\n\n    /* create space for uncompressed data */\n    len = ((size_t)(log->last - log->first) & ~(((size_t)1 << 10) - 1)) +\n          log->stored;\n    if ((data = malloc(len)) == NULL)\n        return -2;\n\n    /* do statement here is just a cheap trick for error handling */\n    do {\n        /* read in the uncompressed data */\n        if (lseek(log->fd, log->first - 1, SEEK_SET) < 0)\n            break;\n        next = 0;\n        while (next < len) {\n            if (read(log->fd, buf, 5) != 5)\n                break;\n            block = PULL2(buf + 1);\n            if (next + block > len ||\n                read(log->fd, (char *)data + next, block) != block)\n                break;\n            next += block;\n        }\n        if (lseek(log->fd, 0, SEEK_CUR) != log->last + 4 + log->stored)\n            break;\n        log_touch(log);\n\n        /* write the uncompressed data to the .add file */\n        strcpy(log->end, \".add\");\n        fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);\n        if (fd < 0)\n            break;\n        ret = (size_t)write(fd, data, len) != len;\n        if (ret | close(fd))\n            break;\n        log_touch(log);\n\n        /* write the dictionary for the next compress to the .temp file */\n        strcpy(log->end, \".temp\");\n        fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);\n        if (fd < 0)\n            break;\n        next = DICT > len ? len : DICT;\n        ret = (size_t)write(fd, (char *)data + len - next, next) != next;\n        if (ret | close(fd))\n            break;\n        log_touch(log);\n\n        /* roll back to compressed data, mark the compress in progress */\n        log->last = log->first;\n        log->stored = 0;\n        if (log_mark(log, COMPRESS_OP))\n            break;\n        BAIL(7);\n\n        /* compress and append the data (clears mark) */\n        ret = log_compress(log, data, len);\n        free(data);\n        return ret;\n    } while (0);\n\n    /* broke out of do above on i/o error */\n    free(data);\n    return -1;\n}\n\n/* gzlog_write() return values:\n    0: all good\n   -1: file i/o error (usually access issue)\n   -2: memory allocation failure\n   -3: invalid log pointer argument */\nint gzlog_write(gzlog *logd, void *data, size_t len)\n{\n    int fd, ret;\n    struct log *log = logd;\n\n    /* check arguments */\n    if (log == NULL || strcmp(log->id, LOGID))\n        return -3;\n    if (data == NULL || len <= 0)\n        return 0;\n\n    /* see if we lost the lock -- if so get it again and reload the extra\n       field information (it probably changed), recover last operation if\n       necessary */\n    if (log_check(log) && log_open(log))\n        return -1;\n\n    /* create and write .add file */\n    strcpy(log->end, \".add\");\n    fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);\n    if (fd < 0)\n        return -1;\n    ret = (size_t)write(fd, data, len) != len;\n    if (ret | close(fd))\n        return -1;\n    log_touch(log);\n\n    /* mark log file with append in progress */\n    if (log_mark(log, APPEND_OP))\n        return -1;\n    BAIL(8);\n\n    /* append data (clears mark) */\n    if (log_append(log, data, len))\n        return -1;\n\n    /* check to see if it's time to compress -- if not, then done */\n    if (((log->last - log->first) >> 10) + (log->stored >> 10) < TRIGGER)\n        return 0;\n\n    /* time to compress */\n    return gzlog_compress(log);\n}\n\n/* gzlog_close() return values:\n    0: ok\n   -3: invalid log pointer argument */\nint gzlog_close(gzlog *logd)\n{\n    struct log *log = logd;\n\n    /* check arguments */\n    if (log == NULL || strcmp(log->id, LOGID))\n        return -3;\n\n    /* close the log file and release the lock */\n    log_close(log);\n\n    /* free structure and return */\n    if (log->path != NULL)\n        free(log->path);\n    strcpy(log->id, \"bad\");\n    free(log);\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/examples/gzlog.h",
    "content": "/* gzlog.h\n  Copyright (C) 2004, 2008, 2012 Mark Adler, all rights reserved\n  version 2.2, 14 Aug 2012\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the author be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Mark Adler    madler@alumni.caltech.edu\n */\n\n/* Version History:\n   1.0  26 Nov 2004  First version\n   2.0  25 Apr 2008  Complete redesign for recovery of interrupted operations\n                     Interface changed slightly in that now path is a prefix\n                     Compression now occurs as needed during gzlog_write()\n                     gzlog_write() now always leaves the log file as valid gzip\n   2.1   8 Jul 2012  Fix argument checks in gzlog_compress() and gzlog_write()\n   2.2  14 Aug 2012  Clean up signed comparisons\n */\n\n/*\n   The gzlog object allows writing short messages to a gzipped log file,\n   opening the log file locked for small bursts, and then closing it.  The log\n   object works by appending stored (uncompressed) data to the gzip file until\n   1 MB has been accumulated.  At that time, the stored data is compressed, and\n   replaces the uncompressed data in the file.  The log file is truncated to\n   its new size at that time.  After each write operation, the log file is a\n   valid gzip file that can decompressed to recover what was written.\n\n   The gzlog operations can be interupted at any point due to an application or\n   system crash, and the log file will be recovered the next time the log is\n   opened with gzlog_open().\n */\n\n#ifndef GZLOG_H\n#define GZLOG_H\n\n/* gzlog object type */\ntypedef void gzlog;\n\n/* Open a gzlog object, creating the log file if it does not exist.  Return\n   NULL on error.  Note that gzlog_open() could take a while to complete if it\n   has to wait to verify that a lock is stale (possibly for five minutes), or\n   if there is significant contention with other instantiations of this object\n   when locking the resource.  path is the prefix of the file names created by\n   this object.  If path is \"foo\", then the log file will be \"foo.gz\", and\n   other auxiliary files will be created and destroyed during the process:\n   \"foo.dict\" for a compression dictionary, \"foo.temp\" for a temporary (next)\n   dictionary, \"foo.add\" for data being added or compressed, \"foo.lock\" for the\n   lock file, and \"foo.repairs\" to log recovery operations performed due to\n   interrupted gzlog operations.  A gzlog_open() followed by a gzlog_close()\n   will recover a previously interrupted operation, if any. */\ngzlog *gzlog_open(char *path);\n\n/* Write to a gzlog object.  Return zero on success, -1 if there is a file i/o\n   error on any of the gzlog files (this should not happen if gzlog_open()\n   succeeded, unless the device has run out of space or leftover auxiliary\n   files have permissions or ownership that prevent their use), -2 if there is\n   a memory allocation failure, or -3 if the log argument is invalid (e.g. if\n   it was not created by gzlog_open()).  This function will write data to the\n   file uncompressed, until 1 MB has been accumulated, at which time that data\n   will be compressed.  The log file will be a valid gzip file upon successful\n   return. */\nint gzlog_write(gzlog *log, void *data, size_t len);\n\n/* Force compression of any uncompressed data in the log.  This should be used\n   sparingly, if at all.  The main application would be when a log file will\n   not be appended to again.  If this is used to compress frequently while\n   appending, it will both significantly increase the execution time and\n   reduce the compression ratio.  The return codes are the same as for\n   gzlog_write(). */\nint gzlog_compress(gzlog *log);\n\n/* Close a gzlog object.  Return zero on success, -3 if the log argument is\n   invalid.  The log object is freed, and so cannot be referenced again. */\nint gzlog_close(gzlog *log);\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/examples/zlib_how.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n  \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\n<title>zlib Usage Example</title>\n<!--  Copyright (c) 2004, 2005 Mark Adler.  -->\n</head>\n<body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#0000FF\" vlink=\"#00A000\">\n<h2 align=\"center\"> zlib Usage Example </h2>\nWe often get questions about how the <tt>deflate()</tt> and <tt>inflate()</tt> functions should be used.\nUsers wonder when they should provide more input, when they should use more output,\nwhat to do with a <tt>Z_BUF_ERROR</tt>, how to make sure the process terminates properly, and\nso on.  So for those who have read <tt>zlib.h</tt> (a few times), and\nwould like further edification, below is an annotated example in C of simple routines to compress and decompress\nfrom an input file to an output file using <tt>deflate()</tt> and <tt>inflate()</tt> respectively.  The\nannotations are interspersed between lines of the code.  So please read between the lines.\nWe hope this helps explain some of the intricacies of <em>zlib</em>.\n<p>\nWithout further adieu, here is the program <a href=\"zpipe.c\"><tt>zpipe.c</tt></a>:\n<pre><b>\n/* zpipe.c: example of proper use of zlib's inflate() and deflate()\n   Not copyrighted -- provided to the public domain\n   Version 1.4  11 December 2005  Mark Adler */\n\n/* Version history:\n   1.0  30 Oct 2004  First version\n   1.1   8 Nov 2004  Add void casting for unused return values\n                     Use switch statement for inflate() return values\n   1.2   9 Nov 2004  Add assertions to document zlib guarantees\n   1.3   6 Apr 2005  Remove incorrect assertion in inf()\n   1.4  11 Dec 2005  Add hack to avoid MSDOS end-of-line conversions\n                     Avoid some compiler warnings for input and output buffers\n */\n</b></pre><!-- -->\nWe now include the header files for the required definitions.  From\n<tt>stdio.h</tt> we use <tt>fopen()</tt>, <tt>fread()</tt>, <tt>fwrite()</tt>,\n<tt>feof()</tt>, <tt>ferror()</tt>, and <tt>fclose()</tt> for file i/o, and\n<tt>fputs()</tt> for error messages.  From <tt>string.h</tt> we use\n<tt>strcmp()</tt> for command line argument processing.\nFrom <tt>assert.h</tt> we use the <tt>assert()</tt> macro.\nFrom <tt>zlib.h</tt>\nwe use the basic compression functions <tt>deflateInit()</tt>,\n<tt>deflate()</tt>, and <tt>deflateEnd()</tt>, and the basic decompression\nfunctions <tt>inflateInit()</tt>, <tt>inflate()</tt>, and\n<tt>inflateEnd()</tt>.\n<pre><b>\n#include &lt;stdio.h&gt;\n#include &lt;string.h&gt;\n#include &lt;assert.h&gt;\n#include \"zlib.h\"\n</b></pre><!-- -->\nThis is an ugly hack required to avoid corruption of the input and output data on\nWindows/MS-DOS systems.  Without this, those systems would assume that the input and output\nfiles are text, and try to convert the end-of-line characters from one standard to\nanother.  That would corrupt binary data, and in particular would render the compressed data unusable.\nThis sets the input and output to binary which suppresses the end-of-line conversions.\n<tt>SET_BINARY_MODE()</tt> will be used later on <tt>stdin</tt> and <tt>stdout</tt>, at the beginning of <tt>main()</tt>.\n<pre><b>\n#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)\n#  include &lt;fcntl.h&gt;\n#  include &lt;io.h&gt;\n#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)\n#else\n#  define SET_BINARY_MODE(file)\n#endif\n</b></pre><!-- -->\n<tt>CHUNK</tt> is simply the buffer size for feeding data to and pulling data\nfrom the <em>zlib</em> routines.  Larger buffer sizes would be more efficient,\nespecially for <tt>inflate()</tt>.  If the memory is available, buffers sizes\non the order of 128K or 256K bytes should be used.\n<pre><b>\n#define CHUNK 16384\n</b></pre><!-- -->\nThe <tt>def()</tt> routine compresses data from an input file to an output file.  The output data\nwill be in the <em>zlib</em> format, which is different from the <em>gzip</em> or <em>zip</em>\nformats.  The <em>zlib</em> format has a very small header of only two bytes to identify it as\na <em>zlib</em> stream and to provide decoding information, and a four-byte trailer with a fast\ncheck value to verify the integrity of the uncompressed data after decoding.\n<pre><b>\n/* Compress from file source to file dest until EOF on source.\n   def() returns Z_OK on success, Z_MEM_ERROR if memory could not be\n   allocated for processing, Z_STREAM_ERROR if an invalid compression\n   level is supplied, Z_VERSION_ERROR if the version of zlib.h and the\n   version of the library linked do not match, or Z_ERRNO if there is\n   an error reading or writing the files. */\nint def(FILE *source, FILE *dest, int level)\n{\n</b></pre>\nHere are the local variables for <tt>def()</tt>.  <tt>ret</tt> will be used for <em>zlib</em>\nreturn codes.  <tt>flush</tt> will keep track of the current flushing state for <tt>deflate()</tt>,\nwhich is either no flushing, or flush to completion after the end of the input file is reached.\n<tt>have</tt> is the amount of data returned from <tt>deflate()</tt>.  The <tt>strm</tt> structure\nis used to pass information to and from the <em>zlib</em> routines, and to maintain the\n<tt>deflate()</tt> state.  <tt>in</tt> and <tt>out</tt> are the input and output buffers for\n<tt>deflate()</tt>.\n<pre><b>\n    int ret, flush;\n    unsigned have;\n    z_stream strm;\n    unsigned char in[CHUNK];\n    unsigned char out[CHUNK];\n</b></pre><!-- -->\nThe first thing we do is to initialize the <em>zlib</em> state for compression using\n<tt>deflateInit()</tt>.  This must be done before the first use of <tt>deflate()</tt>.\nThe <tt>zalloc</tt>, <tt>zfree</tt>, and <tt>opaque</tt> fields in the <tt>strm</tt>\nstructure must be initialized before calling <tt>deflateInit()</tt>.  Here they are\nset to the <em>zlib</em> constant <tt>Z_NULL</tt> to request that <em>zlib</em> use\nthe default memory allocation routines.  An application may also choose to provide\ncustom memory allocation routines here.  <tt>deflateInit()</tt> will allocate on the\norder of 256K bytes for the internal state.\n(See <a href=\"zlib_tech.html\"><em>zlib Technical Details</em></a>.)\n<p>\n<tt>deflateInit()</tt> is called with a pointer to the structure to be initialized and\nthe compression level, which is an integer in the range of -1 to 9.  Lower compression\nlevels result in faster execution, but less compression.  Higher levels result in\ngreater compression, but slower execution.  The <em>zlib</em> constant Z_DEFAULT_COMPRESSION,\nequal to -1,\nprovides a good compromise between compression and speed and is equivalent to level 6.\nLevel 0 actually does no compression at all, and in fact expands the data slightly to produce\nthe <em>zlib</em> format (it is not a byte-for-byte copy of the input).\nMore advanced applications of <em>zlib</em>\nmay use <tt>deflateInit2()</tt> here instead.  Such an application may want to reduce how\nmuch memory will be used, at some price in compression.  Or it may need to request a\n<em>gzip</em> header and trailer instead of a <em>zlib</em> header and trailer, or raw\nencoding with no header or trailer at all.\n<p>\nWe must check the return value of <tt>deflateInit()</tt> against the <em>zlib</em> constant\n<tt>Z_OK</tt> to make sure that it was able to\nallocate memory for the internal state, and that the provided arguments were valid.\n<tt>deflateInit()</tt> will also check that the version of <em>zlib</em> that the <tt>zlib.h</tt>\nfile came from matches the version of <em>zlib</em> actually linked with the program.  This\nis especially important for environments in which <em>zlib</em> is a shared library.\n<p>\nNote that an application can initialize multiple, independent <em>zlib</em> streams, which can\noperate in parallel.  The state information maintained in the structure allows the <em>zlib</em>\nroutines to be reentrant.\n<pre><b>\n    /* allocate deflate state */\n    strm.zalloc = Z_NULL;\n    strm.zfree = Z_NULL;\n    strm.opaque = Z_NULL;\n    ret = deflateInit(&amp;strm, level);\n    if (ret != Z_OK)\n        return ret;\n</b></pre><!-- -->\nWith the pleasantries out of the way, now we can get down to business.  The outer <tt>do</tt>-loop\nreads all of the input file and exits at the bottom of the loop once end-of-file is reached.\nThis loop contains the only call of <tt>deflate()</tt>.  So we must make sure that all of the\ninput data has been processed and that all of the output data has been generated and consumed\nbefore we fall out of the loop at the bottom.\n<pre><b>\n    /* compress until end of file */\n    do {\n</b></pre>\nWe start off by reading data from the input file.  The number of bytes read is put directly\ninto <tt>avail_in</tt>, and a pointer to those bytes is put into <tt>next_in</tt>.  We also\ncheck to see if end-of-file on the input has been reached.  If we are at the end of file, then <tt>flush</tt> is set to the\n<em>zlib</em> constant <tt>Z_FINISH</tt>, which is later passed to <tt>deflate()</tt> to\nindicate that this is the last chunk of input data to compress.  We need to use <tt>feof()</tt>\nto check for end-of-file as opposed to seeing if fewer than <tt>CHUNK</tt> bytes have been read.  The\nreason is that if the input file length is an exact multiple of <tt>CHUNK</tt>, we will miss\nthe fact that we got to the end-of-file, and not know to tell <tt>deflate()</tt> to finish\nup the compressed stream.  If we are not yet at the end of the input, then the <em>zlib</em>\nconstant <tt>Z_NO_FLUSH</tt> will be passed to <tt>deflate</tt> to indicate that we are still\nin the middle of the uncompressed data.\n<p>\nIf there is an error in reading from the input file, the process is aborted with\n<tt>deflateEnd()</tt> being called to free the allocated <em>zlib</em> state before returning\nthe error.  We wouldn't want a memory leak, now would we?  <tt>deflateEnd()</tt> can be called\nat any time after the state has been initialized.  Once that's done, <tt>deflateInit()</tt> (or\n<tt>deflateInit2()</tt>) would have to be called to start a new compression process.  There is\nno point here in checking the <tt>deflateEnd()</tt> return code.  The deallocation can't fail.\n<pre><b>\n        strm.avail_in = fread(in, 1, CHUNK, source);\n        if (ferror(source)) {\n            (void)deflateEnd(&amp;strm);\n            return Z_ERRNO;\n        }\n        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;\n        strm.next_in = in;\n</b></pre><!-- -->\nThe inner <tt>do</tt>-loop passes our chunk of input data to <tt>deflate()</tt>, and then\nkeeps calling <tt>deflate()</tt> until it is done producing output.  Once there is no more\nnew output, <tt>deflate()</tt> is guaranteed to have consumed all of the input, i.e.,\n<tt>avail_in</tt> will be zero.\n<pre><b>\n        /* run deflate() on input until output buffer not full, finish\n           compression if all of source has been read in */\n        do {\n</b></pre>\nOutput space is provided to <tt>deflate()</tt> by setting <tt>avail_out</tt> to the number\nof available output bytes and <tt>next_out</tt> to a pointer to that space.\n<pre><b>\n            strm.avail_out = CHUNK;\n            strm.next_out = out;\n</b></pre>\nNow we call the compression engine itself, <tt>deflate()</tt>.  It takes as many of the\n<tt>avail_in</tt> bytes at <tt>next_in</tt> as it can process, and writes as many as\n<tt>avail_out</tt> bytes to <tt>next_out</tt>.  Those counters and pointers are then\nupdated past the input data consumed and the output data written.  It is the amount of\noutput space available that may limit how much input is consumed.\nHence the inner loop to make sure that\nall of the input is consumed by providing more output space each time.  Since <tt>avail_in</tt>\nand <tt>next_in</tt> are updated by <tt>deflate()</tt>, we don't have to mess with those\nbetween <tt>deflate()</tt> calls until it's all used up.\n<p>\nThe parameters to <tt>deflate()</tt> are a pointer to the <tt>strm</tt> structure containing\nthe input and output information and the internal compression engine state, and a parameter\nindicating whether and how to flush data to the output.  Normally <tt>deflate</tt> will consume\nseveral K bytes of input data before producing any output (except for the header), in order\nto accumulate statistics on the data for optimum compression.  It will then put out a burst of\ncompressed data, and proceed to consume more input before the next burst.  Eventually,\n<tt>deflate()</tt>\nmust be told to terminate the stream, complete the compression with provided input data, and\nwrite out the trailer check value.  <tt>deflate()</tt> will continue to compress normally as long\nas the flush parameter is <tt>Z_NO_FLUSH</tt>.  Once the <tt>Z_FINISH</tt> parameter is provided,\n<tt>deflate()</tt> will begin to complete the compressed output stream.  However depending on how\nmuch output space is provided, <tt>deflate()</tt> may have to be called several times until it\nhas provided the complete compressed stream, even after it has consumed all of the input.  The flush\nparameter must continue to be <tt>Z_FINISH</tt> for those subsequent calls.\n<p>\nThere are other values of the flush parameter that are used in more advanced applications.  You can\nforce <tt>deflate()</tt> to produce a burst of output that encodes all of the input data provided\nso far, even if it wouldn't have otherwise, for example to control data latency on a link with\ncompressed data.  You can also ask that <tt>deflate()</tt> do that as well as erase any history up to\nthat point so that what follows can be decompressed independently, for example for random access\napplications.  Both requests will degrade compression by an amount depending on how often such\nrequests are made.\n<p>\n<tt>deflate()</tt> has a return value that can indicate errors, yet we do not check it here.  Why\nnot?  Well, it turns out that <tt>deflate()</tt> can do no wrong here.  Let's go through\n<tt>deflate()</tt>'s return values and dispense with them one by one.  The possible values are\n<tt>Z_OK</tt>, <tt>Z_STREAM_END</tt>, <tt>Z_STREAM_ERROR</tt>, or <tt>Z_BUF_ERROR</tt>.  <tt>Z_OK</tt>\nis, well, ok.  <tt>Z_STREAM_END</tt> is also ok and will be returned for the last call of\n<tt>deflate()</tt>.  This is already guaranteed by calling <tt>deflate()</tt> with <tt>Z_FINISH</tt>\nuntil it has no more output.  <tt>Z_STREAM_ERROR</tt> is only possible if the stream is not\ninitialized properly, but we did initialize it properly.  There is no harm in checking for\n<tt>Z_STREAM_ERROR</tt> here, for example to check for the possibility that some\nother part of the application inadvertently clobbered the memory containing the <em>zlib</em> state.\n<tt>Z_BUF_ERROR</tt> will be explained further below, but\nsuffice it to say that this is simply an indication that <tt>deflate()</tt> could not consume\nmore input or produce more output.  <tt>deflate()</tt> can be called again with more output space\nor more available input, which it will be in this code.\n<pre><b>\n            ret = deflate(&amp;strm, flush);    /* no bad return value */\n            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */\n</b></pre>\nNow we compute how much output <tt>deflate()</tt> provided on the last call, which is the\ndifference between how much space was provided before the call, and how much output space\nis still available after the call.  Then that data, if any, is written to the output file.\nWe can then reuse the output buffer for the next call of <tt>deflate()</tt>.  Again if there\nis a file i/o error, we call <tt>deflateEnd()</tt> before returning to avoid a memory leak.\n<pre><b>\n            have = CHUNK - strm.avail_out;\n            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {\n                (void)deflateEnd(&amp;strm);\n                return Z_ERRNO;\n            }\n</b></pre>\nThe inner <tt>do</tt>-loop is repeated until the last <tt>deflate()</tt> call fails to fill the\nprovided output buffer.  Then we know that <tt>deflate()</tt> has done as much as it can with\nthe provided input, and that all of that input has been consumed.  We can then fall out of this\nloop and reuse the input buffer.\n<p>\nThe way we tell that <tt>deflate()</tt> has no more output is by seeing that it did not fill\nthe output buffer, leaving <tt>avail_out</tt> greater than zero.  However suppose that\n<tt>deflate()</tt> has no more output, but just so happened to exactly fill the output buffer!\n<tt>avail_out</tt> is zero, and we can't tell that <tt>deflate()</tt> has done all it can.\nAs far as we know, <tt>deflate()</tt>\nhas more output for us.  So we call it again.  But now <tt>deflate()</tt> produces no output\nat all, and <tt>avail_out</tt> remains unchanged as <tt>CHUNK</tt>.  That <tt>deflate()</tt> call\nwasn't able to do anything, either consume input or produce output, and so it returns\n<tt>Z_BUF_ERROR</tt>.  (See, I told you I'd cover this later.)  However this is not a problem at\nall.  Now we finally have the desired indication that <tt>deflate()</tt> is really done,\nand so we drop out of the inner loop to provide more input to <tt>deflate()</tt>.\n<p>\nWith <tt>flush</tt> set to <tt>Z_FINISH</tt>, this final set of <tt>deflate()</tt> calls will\ncomplete the output stream.  Once that is done, subsequent calls of <tt>deflate()</tt> would return\n<tt>Z_STREAM_ERROR</tt> if the flush parameter is not <tt>Z_FINISH</tt>, and do no more processing\nuntil the state is reinitialized.\n<p>\nSome applications of <em>zlib</em> have two loops that call <tt>deflate()</tt>\ninstead of the single inner loop we have here.  The first loop would call\nwithout flushing and feed all of the data to <tt>deflate()</tt>.  The second loop would call\n<tt>deflate()</tt> with no more\ndata and the <tt>Z_FINISH</tt> parameter to complete the process.  As you can see from this\nexample, that can be avoided by simply keeping track of the current flush state.\n<pre><b>\n        } while (strm.avail_out == 0);\n        assert(strm.avail_in == 0);     /* all input will be used */\n</b></pre><!-- -->\nNow we check to see if we have already processed all of the input file.  That information was\nsaved in the <tt>flush</tt> variable, so we see if that was set to <tt>Z_FINISH</tt>.  If so,\nthen we're done and we fall out of the outer loop.  We're guaranteed to get <tt>Z_STREAM_END</tt>\nfrom the last <tt>deflate()</tt> call, since we ran it until the last chunk of input was\nconsumed and all of the output was generated.\n<pre><b>\n        /* done when last data in file processed */\n    } while (flush != Z_FINISH);\n    assert(ret == Z_STREAM_END);        /* stream will be complete */\n</b></pre><!-- -->\nThe process is complete, but we still need to deallocate the state to avoid a memory leak\n(or rather more like a memory hemorrhage if you didn't do this).  Then\nfinally we can return with a happy return value.\n<pre><b>\n    /* clean up and return */\n    (void)deflateEnd(&amp;strm);\n    return Z_OK;\n}\n</b></pre><!-- -->\nNow we do the same thing for decompression in the <tt>inf()</tt> routine. <tt>inf()</tt>\ndecompresses what is hopefully a valid <em>zlib</em> stream from the input file and writes the\nuncompressed data to the output file.  Much of the discussion above for <tt>def()</tt>\napplies to <tt>inf()</tt> as well, so the discussion here will focus on the differences between\nthe two.\n<pre><b>\n/* Decompress from file source to file dest until stream ends or EOF.\n   inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be\n   allocated for processing, Z_DATA_ERROR if the deflate data is\n   invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and\n   the version of the library linked do not match, or Z_ERRNO if there\n   is an error reading or writing the files. */\nint inf(FILE *source, FILE *dest)\n{\n</b></pre>\nThe local variables have the same functionality as they do for <tt>def()</tt>.  The\nonly difference is that there is no <tt>flush</tt> variable, since <tt>inflate()</tt>\ncan tell from the <em>zlib</em> stream itself when the stream is complete.\n<pre><b>\n    int ret;\n    unsigned have;\n    z_stream strm;\n    unsigned char in[CHUNK];\n    unsigned char out[CHUNK];\n</b></pre><!-- -->\nThe initialization of the state is the same, except that there is no compression level,\nof course, and two more elements of the structure are initialized.  <tt>avail_in</tt>\nand <tt>next_in</tt> must be initialized before calling <tt>inflateInit()</tt>.  This\nis because the application has the option to provide the start of the zlib stream in\norder for <tt>inflateInit()</tt> to have access to information about the compression\nmethod to aid in memory allocation.  In the current implementation of <em>zlib</em>\n(up through versions 1.2.x), the method-dependent memory allocations are deferred to the first call of\n<tt>inflate()</tt> anyway.  However those fields must be initialized since later versions\nof <em>zlib</em> that provide more compression methods may take advantage of this interface.\nIn any case, no decompression is performed by <tt>inflateInit()</tt>, so the\n<tt>avail_out</tt> and <tt>next_out</tt> fields do not need to be initialized before calling.\n<p>\nHere <tt>avail_in</tt> is set to zero and <tt>next_in</tt> is set to <tt>Z_NULL</tt> to\nindicate that no input data is being provided.\n<pre><b>\n    /* allocate inflate state */\n    strm.zalloc = Z_NULL;\n    strm.zfree = Z_NULL;\n    strm.opaque = Z_NULL;\n    strm.avail_in = 0;\n    strm.next_in = Z_NULL;\n    ret = inflateInit(&amp;strm);\n    if (ret != Z_OK)\n        return ret;\n</b></pre><!-- -->\nThe outer <tt>do</tt>-loop decompresses input until <tt>inflate()</tt> indicates\nthat it has reached the end of the compressed data and has produced all of the uncompressed\noutput.  This is in contrast to <tt>def()</tt> which processes all of the input file.\nIf end-of-file is reached before the compressed data self-terminates, then the compressed\ndata is incomplete and an error is returned.\n<pre><b>\n    /* decompress until deflate stream ends or end of file */\n    do {\n</b></pre>\nWe read input data and set the <tt>strm</tt> structure accordingly.  If we've reached the\nend of the input file, then we leave the outer loop and report an error, since the\ncompressed data is incomplete.  Note that we may read more data than is eventually consumed\nby <tt>inflate()</tt>, if the input file continues past the <em>zlib</em> stream.\nFor applications where <em>zlib</em> streams are embedded in other data, this routine would\nneed to be modified to return the unused data, or at least indicate how much of the input\ndata was not used, so the application would know where to pick up after the <em>zlib</em> stream.\n<pre><b>\n        strm.avail_in = fread(in, 1, CHUNK, source);\n        if (ferror(source)) {\n            (void)inflateEnd(&amp;strm);\n            return Z_ERRNO;\n        }\n        if (strm.avail_in == 0)\n            break;\n        strm.next_in = in;\n</b></pre><!-- -->\nThe inner <tt>do</tt>-loop has the same function it did in <tt>def()</tt>, which is to\nkeep calling <tt>inflate()</tt> until has generated all of the output it can with the\nprovided input.\n<pre><b>\n        /* run inflate() on input until output buffer not full */\n        do {\n</b></pre>\nJust like in <tt>def()</tt>, the same output space is provided for each call of <tt>inflate()</tt>.\n<pre><b>\n            strm.avail_out = CHUNK;\n            strm.next_out = out;\n</b></pre>\nNow we run the decompression engine itself.  There is no need to adjust the flush parameter, since\nthe <em>zlib</em> format is self-terminating. The main difference here is that there are\nreturn values that we need to pay attention to.  <tt>Z_DATA_ERROR</tt>\nindicates that <tt>inflate()</tt> detected an error in the <em>zlib</em> compressed data format,\nwhich means that either the data is not a <em>zlib</em> stream to begin with, or that the data was\ncorrupted somewhere along the way since it was compressed.  The other error to be processed is\n<tt>Z_MEM_ERROR</tt>, which can occur since memory allocation is deferred until <tt>inflate()</tt>\nneeds it, unlike <tt>deflate()</tt>, whose memory is allocated at the start by <tt>deflateInit()</tt>.\n<p>\nAdvanced applications may use\n<tt>deflateSetDictionary()</tt> to prime <tt>deflate()</tt> with a set of likely data to improve the\nfirst 32K or so of compression.  This is noted in the <em>zlib</em> header, so <tt>inflate()</tt>\nrequests that that dictionary be provided before it can start to decompress.  Without the dictionary,\ncorrect decompression is not possible.  For this routine, we have no idea what the dictionary is,\nso the <tt>Z_NEED_DICT</tt> indication is converted to a <tt>Z_DATA_ERROR</tt>.\n<p>\n<tt>inflate()</tt> can also return <tt>Z_STREAM_ERROR</tt>, which should not be possible here,\nbut could be checked for as noted above for <tt>def()</tt>.  <tt>Z_BUF_ERROR</tt> does not need to be\nchecked for here, for the same reasons noted for <tt>def()</tt>.  <tt>Z_STREAM_END</tt> will be\nchecked for later.\n<pre><b>\n            ret = inflate(&amp;strm, Z_NO_FLUSH);\n            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */\n            switch (ret) {\n            case Z_NEED_DICT:\n                ret = Z_DATA_ERROR;     /* and fall through */\n            case Z_DATA_ERROR:\n            case Z_MEM_ERROR:\n                (void)inflateEnd(&amp;strm);\n                return ret;\n            }\n</b></pre>\nThe output of <tt>inflate()</tt> is handled identically to that of <tt>deflate()</tt>.\n<pre><b>\n            have = CHUNK - strm.avail_out;\n            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {\n                (void)inflateEnd(&amp;strm);\n                return Z_ERRNO;\n            }\n</b></pre>\nThe inner <tt>do</tt>-loop ends when <tt>inflate()</tt> has no more output as indicated\nby not filling the output buffer, just as for <tt>deflate()</tt>.  In this case, we cannot\nassert that <tt>strm.avail_in</tt> will be zero, since the deflate stream may end before the file\ndoes.\n<pre><b>\n        } while (strm.avail_out == 0);\n</b></pre><!-- -->\nThe outer <tt>do</tt>-loop ends when <tt>inflate()</tt> reports that it has reached the\nend of the input <em>zlib</em> stream, has completed the decompression and integrity\ncheck, and has provided all of the output.  This is indicated by the <tt>inflate()</tt>\nreturn value <tt>Z_STREAM_END</tt>.  The inner loop is guaranteed to leave <tt>ret</tt>\nequal to <tt>Z_STREAM_END</tt> if the last chunk of the input file read contained the end\nof the <em>zlib</em> stream.  So if the return value is not <tt>Z_STREAM_END</tt>, the\nloop continues to read more input.\n<pre><b>\n        /* done when inflate() says it's done */\n    } while (ret != Z_STREAM_END);\n</b></pre><!-- -->\nAt this point, decompression successfully completed, or we broke out of the loop due to no\nmore data being available from the input file.  If the last <tt>inflate()</tt> return value\nis not <tt>Z_STREAM_END</tt>, then the <em>zlib</em> stream was incomplete and a data error\nis returned.  Otherwise, we return with a happy return value.  Of course, <tt>inflateEnd()</tt>\nis called first to avoid a memory leak.\n<pre><b>\n    /* clean up and return */\n    (void)inflateEnd(&amp;strm);\n    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;\n}\n</b></pre><!-- -->\nThat ends the routines that directly use <em>zlib</em>.  The following routines make this\na command-line program by running data through the above routines from <tt>stdin</tt> to\n<tt>stdout</tt>, and handling any errors reported by <tt>def()</tt> or <tt>inf()</tt>.\n<p>\n<tt>zerr()</tt> is used to interpret the possible error codes from <tt>def()</tt>\nand <tt>inf()</tt>, as detailed in their comments above, and print out an error message.\nNote that these are only a subset of the possible return values from <tt>deflate()</tt>\nand <tt>inflate()</tt>.\n<pre><b>\n/* report a zlib or i/o error */\nvoid zerr(int ret)\n{\n    fputs(\"zpipe: \", stderr);\n    switch (ret) {\n    case Z_ERRNO:\n        if (ferror(stdin))\n            fputs(\"error reading stdin\\n\", stderr);\n        if (ferror(stdout))\n            fputs(\"error writing stdout\\n\", stderr);\n        break;\n    case Z_STREAM_ERROR:\n        fputs(\"invalid compression level\\n\", stderr);\n        break;\n    case Z_DATA_ERROR:\n        fputs(\"invalid or incomplete deflate data\\n\", stderr);\n        break;\n    case Z_MEM_ERROR:\n        fputs(\"out of memory\\n\", stderr);\n        break;\n    case Z_VERSION_ERROR:\n        fputs(\"zlib version mismatch!\\n\", stderr);\n    }\n}\n</b></pre><!-- -->\nHere is the <tt>main()</tt> routine used to test <tt>def()</tt> and <tt>inf()</tt>.  The\n<tt>zpipe</tt> command is simply a compression pipe from <tt>stdin</tt> to <tt>stdout</tt>, if\nno arguments are given, or it is a decompression pipe if <tt>zpipe -d</tt> is used.  If any other\narguments are provided, no compression or decompression is performed.  Instead a usage\nmessage is displayed.  Examples are <tt>zpipe < foo.txt > foo.txt.z</tt> to compress, and\n<tt>zpipe -d < foo.txt.z > foo.txt</tt> to decompress.\n<pre><b>\n/* compress or decompress from stdin to stdout */\nint main(int argc, char **argv)\n{\n    int ret;\n\n    /* avoid end-of-line conversions */\n    SET_BINARY_MODE(stdin);\n    SET_BINARY_MODE(stdout);\n\n    /* do compression if no arguments */\n    if (argc == 1) {\n        ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);\n        if (ret != Z_OK)\n            zerr(ret);\n        return ret;\n    }\n\n    /* do decompression if -d specified */\n    else if (argc == 2 &amp;&amp; strcmp(argv[1], \"-d\") == 0) {\n        ret = inf(stdin, stdout);\n        if (ret != Z_OK)\n            zerr(ret);\n        return ret;\n    }\n\n    /* otherwise, report usage */\n    else {\n        fputs(\"zpipe usage: zpipe [-d] &lt; source &gt; dest\\n\", stderr);\n        return 1;\n    }\n}\n</b></pre>\n<hr>\n<i>Copyright (c) 2004, 2005 by Mark Adler<br>Last modified 11 December 2005</i>\n</body>\n</html>\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/examples/zpipe.c",
    "content": "/* zpipe.c: example of proper use of zlib's inflate() and deflate()\n   Not copyrighted -- provided to the public domain\n   Version 1.4  11 December 2005  Mark Adler */\n\n/* Version history:\n   1.0  30 Oct 2004  First version\n   1.1   8 Nov 2004  Add void casting for unused return values\n                     Use switch statement for inflate() return values\n   1.2   9 Nov 2004  Add assertions to document zlib guarantees\n   1.3   6 Apr 2005  Remove incorrect assertion in inf()\n   1.4  11 Dec 2005  Add hack to avoid MSDOS end-of-line conversions\n                     Avoid some compiler warnings for input and output buffers\n */\n\n#include <stdio.h>\n#include <string.h>\n#include <assert.h>\n#include \"zlib.h\"\n\n#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)\n#  include <fcntl.h>\n#  include <io.h>\n#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)\n#else\n#  define SET_BINARY_MODE(file)\n#endif\n\n#define CHUNK 16384\n\n/* Compress from file source to file dest until EOF on source.\n   def() returns Z_OK on success, Z_MEM_ERROR if memory could not be\n   allocated for processing, Z_STREAM_ERROR if an invalid compression\n   level is supplied, Z_VERSION_ERROR if the version of zlib.h and the\n   version of the library linked do not match, or Z_ERRNO if there is\n   an error reading or writing the files. */\nint def(FILE *source, FILE *dest, int level)\n{\n    int ret, flush;\n    unsigned have;\n    z_stream strm;\n    unsigned char in[CHUNK];\n    unsigned char out[CHUNK];\n\n    /* allocate deflate state */\n    strm.zalloc = Z_NULL;\n    strm.zfree = Z_NULL;\n    strm.opaque = Z_NULL;\n    ret = deflateInit(&strm, level);\n    if (ret != Z_OK)\n        return ret;\n\n    /* compress until end of file */\n    do {\n        strm.avail_in = fread(in, 1, CHUNK, source);\n        if (ferror(source)) {\n            (void)deflateEnd(&strm);\n            return Z_ERRNO;\n        }\n        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;\n        strm.next_in = in;\n\n        /* run deflate() on input until output buffer not full, finish\n           compression if all of source has been read in */\n        do {\n            strm.avail_out = CHUNK;\n            strm.next_out = out;\n            ret = deflate(&strm, flush);    /* no bad return value */\n            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */\n            have = CHUNK - strm.avail_out;\n            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {\n                (void)deflateEnd(&strm);\n                return Z_ERRNO;\n            }\n        } while (strm.avail_out == 0);\n        assert(strm.avail_in == 0);     /* all input will be used */\n\n        /* done when last data in file processed */\n    } while (flush != Z_FINISH);\n    assert(ret == Z_STREAM_END);        /* stream will be complete */\n\n    /* clean up and return */\n    (void)deflateEnd(&strm);\n    return Z_OK;\n}\n\n/* Decompress from file source to file dest until stream ends or EOF.\n   inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be\n   allocated for processing, Z_DATA_ERROR if the deflate data is\n   invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and\n   the version of the library linked do not match, or Z_ERRNO if there\n   is an error reading or writing the files. */\nint inf(FILE *source, FILE *dest)\n{\n    int ret;\n    unsigned have;\n    z_stream strm;\n    unsigned char in[CHUNK];\n    unsigned char out[CHUNK];\n\n    /* allocate inflate state */\n    strm.zalloc = Z_NULL;\n    strm.zfree = Z_NULL;\n    strm.opaque = Z_NULL;\n    strm.avail_in = 0;\n    strm.next_in = Z_NULL;\n    ret = inflateInit(&strm);\n    if (ret != Z_OK)\n        return ret;\n\n    /* decompress until deflate stream ends or end of file */\n    do {\n        strm.avail_in = fread(in, 1, CHUNK, source);\n        if (ferror(source)) {\n            (void)inflateEnd(&strm);\n            return Z_ERRNO;\n        }\n        if (strm.avail_in == 0)\n            break;\n        strm.next_in = in;\n\n        /* run inflate() on input until output buffer not full */\n        do {\n            strm.avail_out = CHUNK;\n            strm.next_out = out;\n            ret = inflate(&strm, Z_NO_FLUSH);\n            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */\n            switch (ret) {\n            case Z_NEED_DICT:\n                ret = Z_DATA_ERROR;     /* and fall through */\n            case Z_DATA_ERROR:\n            case Z_MEM_ERROR:\n                (void)inflateEnd(&strm);\n                return ret;\n            }\n            have = CHUNK - strm.avail_out;\n            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {\n                (void)inflateEnd(&strm);\n                return Z_ERRNO;\n            }\n        } while (strm.avail_out == 0);\n\n        /* done when inflate() says it's done */\n    } while (ret != Z_STREAM_END);\n\n    /* clean up and return */\n    (void)inflateEnd(&strm);\n    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;\n}\n\n/* report a zlib or i/o error */\nvoid zerr(int ret)\n{\n    fputs(\"zpipe: \", stderr);\n    switch (ret) {\n    case Z_ERRNO:\n        if (ferror(stdin))\n            fputs(\"error reading stdin\\n\", stderr);\n        if (ferror(stdout))\n            fputs(\"error writing stdout\\n\", stderr);\n        break;\n    case Z_STREAM_ERROR:\n        fputs(\"invalid compression level\\n\", stderr);\n        break;\n    case Z_DATA_ERROR:\n        fputs(\"invalid or incomplete deflate data\\n\", stderr);\n        break;\n    case Z_MEM_ERROR:\n        fputs(\"out of memory\\n\", stderr);\n        break;\n    case Z_VERSION_ERROR:\n        fputs(\"zlib version mismatch!\\n\", stderr);\n    }\n}\n\n/* compress or decompress from stdin to stdout */\nint main(int argc, char **argv)\n{\n    int ret;\n\n    /* avoid end-of-line conversions */\n    SET_BINARY_MODE(stdin);\n    SET_BINARY_MODE(stdout);\n\n    /* do compression if no arguments */\n    if (argc == 1) {\n        ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);\n        if (ret != Z_OK)\n            zerr(ret);\n        return ret;\n    }\n\n    /* do decompression if -d specified */\n    else if (argc == 2 && strcmp(argv[1], \"-d\") == 0) {\n        ret = inf(stdin, stdout);\n        if (ret != Z_OK)\n            zerr(ret);\n        return ret;\n    }\n\n    /* otherwise, report usage */\n    else {\n        fputs(\"zpipe usage: zpipe [-d] < source > dest\\n\", stderr);\n        return 1;\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/examples/zran.c",
    "content": "/* zran.c -- example of zlib/gzip stream indexing and random access\n * Copyright (C) 2005, 2012 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n   Version 1.1  29 Sep 2012  Mark Adler */\n\n/* Version History:\n 1.0  29 May 2005  First version\n 1.1  29 Sep 2012  Fix memory reallocation error\n */\n\n/* Illustrate the use of Z_BLOCK, inflatePrime(), and inflateSetDictionary()\n   for random access of a compressed file.  A file containing a zlib or gzip\n   stream is provided on the command line.  The compressed stream is decoded in\n   its entirety, and an index built with access points about every SPAN bytes\n   in the uncompressed output.  The compressed file is left open, and can then\n   be read randomly, having to decompress on the average SPAN/2 uncompressed\n   bytes before getting to the desired block of data.\n\n   An access point can be created at the start of any deflate block, by saving\n   the starting file offset and bit of that block, and the 32K bytes of\n   uncompressed data that precede that block.  Also the uncompressed offset of\n   that block is saved to provide a referece for locating a desired starting\n   point in the uncompressed stream.  build_index() works by decompressing the\n   input zlib or gzip stream a block at a time, and at the end of each block\n   deciding if enough uncompressed data has gone by to justify the creation of\n   a new access point.  If so, that point is saved in a data structure that\n   grows as needed to accommodate the points.\n\n   To use the index, an offset in the uncompressed data is provided, for which\n   the latest accees point at or preceding that offset is located in the index.\n   The input file is positioned to the specified location in the index, and if\n   necessary the first few bits of the compressed data is read from the file.\n   inflate is initialized with those bits and the 32K of uncompressed data, and\n   the decompression then proceeds until the desired offset in the file is\n   reached.  Then the decompression continues to read the desired uncompressed\n   data from the file.\n\n   Another approach would be to generate the index on demand.  In that case,\n   requests for random access reads from the compressed data would try to use\n   the index, but if a read far enough past the end of the index is required,\n   then further index entries would be generated and added.\n\n   There is some fair bit of overhead to starting inflation for the random\n   access, mainly copying the 32K byte dictionary.  So if small pieces of the\n   file are being accessed, it would make sense to implement a cache to hold\n   some lookahead and avoid many calls to extract() for small lengths.\n\n   Another way to build an index would be to use inflateCopy().  That would\n   not be constrained to have access points at block boundaries, but requires\n   more memory per access point, and also cannot be saved to file due to the\n   use of pointers in the state.  The approach here allows for storage of the\n   index in a file.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include \"zlib.h\"\n\n#define local static\n\n#define SPAN 1048576L       /* desired distance between access points */\n#define WINSIZE 32768U      /* sliding window size */\n#define CHUNK 16384         /* file input buffer size */\n\n/* access point entry */\nstruct point {\n    off_t out;          /* corresponding offset in uncompressed data */\n    off_t in;           /* offset in input file of first full byte */\n    int bits;           /* number of bits (1-7) from byte at in - 1, or 0 */\n    unsigned char window[WINSIZE];  /* preceding 32K of uncompressed data */\n};\n\n/* access point list */\nstruct access {\n    int have;           /* number of list entries filled in */\n    int size;           /* number of list entries allocated */\n    struct point *list; /* allocated list */\n};\n\n/* Deallocate an index built by build_index() */\nlocal void free_index(struct access *index)\n{\n    if (index != NULL) {\n        free(index->list);\n        free(index);\n    }\n}\n\n/* Add an entry to the access point list.  If out of memory, deallocate the\n   existing list and return NULL. */\nlocal struct access *addpoint(struct access *index, int bits,\n    off_t in, off_t out, unsigned left, unsigned char *window)\n{\n    struct point *next;\n\n    /* if list is empty, create it (start with eight points) */\n    if (index == NULL) {\n        index = malloc(sizeof(struct access));\n        if (index == NULL) return NULL;\n        index->list = malloc(sizeof(struct point) << 3);\n        if (index->list == NULL) {\n            free(index);\n            return NULL;\n        }\n        index->size = 8;\n        index->have = 0;\n    }\n\n    /* if list is full, make it bigger */\n    else if (index->have == index->size) {\n        index->size <<= 1;\n        next = realloc(index->list, sizeof(struct point) * index->size);\n        if (next == NULL) {\n            free_index(index);\n            return NULL;\n        }\n        index->list = next;\n    }\n\n    /* fill in entry and increment how many we have */\n    next = index->list + index->have;\n    next->bits = bits;\n    next->in = in;\n    next->out = out;\n    if (left)\n        memcpy(next->window, window + WINSIZE - left, left);\n    if (left < WINSIZE)\n        memcpy(next->window + left, window, WINSIZE - left);\n    index->have++;\n\n    /* return list, possibly reallocated */\n    return index;\n}\n\n/* Make one entire pass through the compressed stream and build an index, with\n   access points about every span bytes of uncompressed output -- span is\n   chosen to balance the speed of random access against the memory requirements\n   of the list, about 32K bytes per access point.  Note that data after the end\n   of the first zlib or gzip stream in the file is ignored.  build_index()\n   returns the number of access points on success (>= 1), Z_MEM_ERROR for out\n   of memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a\n   file read error.  On success, *built points to the resulting index. */\nlocal int build_index(FILE *in, off_t span, struct access **built)\n{\n    int ret;\n    off_t totin, totout;        /* our own total counters to avoid 4GB limit */\n    off_t last;                 /* totout value of last access point */\n    struct access *index;       /* access points being generated */\n    z_stream strm;\n    unsigned char input[CHUNK];\n    unsigned char window[WINSIZE];\n\n    /* initialize inflate */\n    strm.zalloc = Z_NULL;\n    strm.zfree = Z_NULL;\n    strm.opaque = Z_NULL;\n    strm.avail_in = 0;\n    strm.next_in = Z_NULL;\n    ret = inflateInit2(&strm, 47);      /* automatic zlib or gzip decoding */\n    if (ret != Z_OK)\n        return ret;\n\n    /* inflate the input, maintain a sliding window, and build an index -- this\n       also validates the integrity of the compressed data using the check\n       information at the end of the gzip or zlib stream */\n    totin = totout = last = 0;\n    index = NULL;               /* will be allocated by first addpoint() */\n    strm.avail_out = 0;\n    do {\n        /* get some compressed data from input file */\n        strm.avail_in = fread(input, 1, CHUNK, in);\n        if (ferror(in)) {\n            ret = Z_ERRNO;\n            goto build_index_error;\n        }\n        if (strm.avail_in == 0) {\n            ret = Z_DATA_ERROR;\n            goto build_index_error;\n        }\n        strm.next_in = input;\n\n        /* process all of that, or until end of stream */\n        do {\n            /* reset sliding window if necessary */\n            if (strm.avail_out == 0) {\n                strm.avail_out = WINSIZE;\n                strm.next_out = window;\n            }\n\n            /* inflate until out of input, output, or at end of block --\n               update the total input and output counters */\n            totin += strm.avail_in;\n            totout += strm.avail_out;\n            ret = inflate(&strm, Z_BLOCK);      /* return at end of block */\n            totin -= strm.avail_in;\n            totout -= strm.avail_out;\n            if (ret == Z_NEED_DICT)\n                ret = Z_DATA_ERROR;\n            if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)\n                goto build_index_error;\n            if (ret == Z_STREAM_END)\n                break;\n\n            /* if at end of block, consider adding an index entry (note that if\n               data_type indicates an end-of-block, then all of the\n               uncompressed data from that block has been delivered, and none\n               of the compressed data after that block has been consumed,\n               except for up to seven bits) -- the totout == 0 provides an\n               entry point after the zlib or gzip header, and assures that the\n               index always has at least one access point; we avoid creating an\n               access point after the last block by checking bit 6 of data_type\n             */\n            if ((strm.data_type & 128) && !(strm.data_type & 64) &&\n                (totout == 0 || totout - last > span)) {\n                index = addpoint(index, strm.data_type & 7, totin,\n                                 totout, strm.avail_out, window);\n                if (index == NULL) {\n                    ret = Z_MEM_ERROR;\n                    goto build_index_error;\n                }\n                last = totout;\n            }\n        } while (strm.avail_in != 0);\n    } while (ret != Z_STREAM_END);\n\n    /* clean up and return index (release unused entries in list) */\n    (void)inflateEnd(&strm);\n    index->list = realloc(index->list, sizeof(struct point) * index->have);\n    index->size = index->have;\n    *built = index;\n    return index->size;\n\n    /* return error */\n  build_index_error:\n    (void)inflateEnd(&strm);\n    if (index != NULL)\n        free_index(index);\n    return ret;\n}\n\n/* Use the index to read len bytes from offset into buf, return bytes read or\n   negative for error (Z_DATA_ERROR or Z_MEM_ERROR).  If data is requested past\n   the end of the uncompressed data, then extract() will return a value less\n   than len, indicating how much as actually read into buf.  This function\n   should not return a data error unless the file was modified since the index\n   was generated.  extract() may also return Z_ERRNO if there is an error on\n   reading or seeking the input file. */\nlocal int extract(FILE *in, struct access *index, off_t offset,\n                  unsigned char *buf, int len)\n{\n    int ret, skip;\n    z_stream strm;\n    struct point *here;\n    unsigned char input[CHUNK];\n    unsigned char discard[WINSIZE];\n\n    /* proceed only if something reasonable to do */\n    if (len < 0)\n        return 0;\n\n    /* find where in stream to start */\n    here = index->list;\n    ret = index->have;\n    while (--ret && here[1].out <= offset)\n        here++;\n\n    /* initialize file and inflate state to start there */\n    strm.zalloc = Z_NULL;\n    strm.zfree = Z_NULL;\n    strm.opaque = Z_NULL;\n    strm.avail_in = 0;\n    strm.next_in = Z_NULL;\n    ret = inflateInit2(&strm, -15);         /* raw inflate */\n    if (ret != Z_OK)\n        return ret;\n    ret = fseeko(in, here->in - (here->bits ? 1 : 0), SEEK_SET);\n    if (ret == -1)\n        goto extract_ret;\n    if (here->bits) {\n        ret = getc(in);\n        if (ret == -1) {\n            ret = ferror(in) ? Z_ERRNO : Z_DATA_ERROR;\n            goto extract_ret;\n        }\n        (void)inflatePrime(&strm, here->bits, ret >> (8 - here->bits));\n    }\n    (void)inflateSetDictionary(&strm, here->window, WINSIZE);\n\n    /* skip uncompressed bytes until offset reached, then satisfy request */\n    offset -= here->out;\n    strm.avail_in = 0;\n    skip = 1;                               /* while skipping to offset */\n    do {\n        /* define where to put uncompressed data, and how much */\n        if (offset == 0 && skip) {          /* at offset now */\n            strm.avail_out = len;\n            strm.next_out = buf;\n            skip = 0;                       /* only do this once */\n        }\n        if (offset > WINSIZE) {             /* skip WINSIZE bytes */\n            strm.avail_out = WINSIZE;\n            strm.next_out = discard;\n            offset -= WINSIZE;\n        }\n        else if (offset != 0) {             /* last skip */\n            strm.avail_out = (unsigned)offset;\n            strm.next_out = discard;\n            offset = 0;\n        }\n\n        /* uncompress until avail_out filled, or end of stream */\n        do {\n            if (strm.avail_in == 0) {\n                strm.avail_in = fread(input, 1, CHUNK, in);\n                if (ferror(in)) {\n                    ret = Z_ERRNO;\n                    goto extract_ret;\n                }\n                if (strm.avail_in == 0) {\n                    ret = Z_DATA_ERROR;\n                    goto extract_ret;\n                }\n                strm.next_in = input;\n            }\n            ret = inflate(&strm, Z_NO_FLUSH);       /* normal inflate */\n            if (ret == Z_NEED_DICT)\n                ret = Z_DATA_ERROR;\n            if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)\n                goto extract_ret;\n            if (ret == Z_STREAM_END)\n                break;\n        } while (strm.avail_out != 0);\n\n        /* if reach end of stream, then don't keep trying to get more */\n        if (ret == Z_STREAM_END)\n            break;\n\n        /* do until offset reached and requested data read, or stream ends */\n    } while (skip);\n\n    /* compute number of uncompressed bytes read after offset */\n    ret = skip ? 0 : len - strm.avail_out;\n\n    /* clean up and return bytes read or error */\n  extract_ret:\n    (void)inflateEnd(&strm);\n    return ret;\n}\n\n/* Demonstrate the use of build_index() and extract() by processing the file\n   provided on the command line, and the extracting 16K from about 2/3rds of\n   the way through the uncompressed output, and writing that to stdout. */\nint main(int argc, char **argv)\n{\n    int len;\n    off_t offset;\n    FILE *in;\n    struct access *index = NULL;\n    unsigned char buf[CHUNK];\n\n    /* open input file */\n    if (argc != 2) {\n        fprintf(stderr, \"usage: zran file.gz\\n\");\n        return 1;\n    }\n    in = fopen(argv[1], \"rb\");\n    if (in == NULL) {\n        fprintf(stderr, \"zran: could not open %s for reading\\n\", argv[1]);\n        return 1;\n    }\n\n    /* build index */\n    len = build_index(in, SPAN, &index);\n    if (len < 0) {\n        fclose(in);\n        switch (len) {\n        case Z_MEM_ERROR:\n            fprintf(stderr, \"zran: out of memory\\n\");\n            break;\n        case Z_DATA_ERROR:\n            fprintf(stderr, \"zran: compressed data error in %s\\n\", argv[1]);\n            break;\n        case Z_ERRNO:\n            fprintf(stderr, \"zran: read error on %s\\n\", argv[1]);\n            break;\n        default:\n            fprintf(stderr, \"zran: error %d while building index\\n\", len);\n        }\n        return 1;\n    }\n    fprintf(stderr, \"zran: built index with %d access points\\n\", len);\n\n    /* use index by reading some bytes from an arbitrary offset */\n    offset = (index->list[index->have - 1].out << 1) / 3;\n    len = extract(in, index, offset, buf, CHUNK);\n    if (len < 0)\n        fprintf(stderr, \"zran: extraction failed: %s error\\n\",\n                len == Z_MEM_ERROR ? \"out of memory\" : \"input corrupted\");\n    else {\n        fwrite(buf, 1, len, stdout);\n        fprintf(stderr, \"zran: extracted %d bytes at %llu\\n\", len, offset);\n    }\n\n    /* clean up and exit */\n    free_index(index);\n    fclose(in);\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/gzclose.c",
    "content": "/* gzclose.c -- zlib gzclose() function\n * Copyright (C) 2004, 2010 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#include \"gzguts.h\"\n\n/* gzclose() is in a separate file so that it is linked in only if it is used.\n   That way the other gzclose functions can be used instead to avoid linking in\n   unneeded compression or decompression routines. */\nint ZEXPORT gzclose(file)\n    gzFile file;\n{\n#ifndef NO_GZCOMPRESS\n    gz_statep state;\n\n    if (file == NULL)\n        return Z_STREAM_ERROR;\n    state = (gz_statep)file;\n\n    return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);\n#else\n    return gzclose_r(file);\n#endif\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/gzguts.h",
    "content": "/* gzguts.h -- zlib internal header definitions for gz* operations\n * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#ifdef _LARGEFILE64_SOURCE\n#  ifndef _LARGEFILE_SOURCE\n#    define _LARGEFILE_SOURCE 1\n#  endif\n#  ifdef _FILE_OFFSET_BITS\n#    undef _FILE_OFFSET_BITS\n#  endif\n#endif\n\n#ifdef HAVE_HIDDEN\n#  define ZLIB_INTERNAL __attribute__((visibility (\"hidden\")))\n#else\n#  define ZLIB_INTERNAL\n#endif\n\n#include <stdio.h>\n#include \"zlib.h\"\n#ifdef STDC\n#  include <string.h>\n#  include <stdlib.h>\n#  include <limits.h>\n#endif\n#include <fcntl.h>\n\n#ifdef _WIN32\n#  include <stddef.h>\n#endif\n\n#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)\n#  include <io.h>\n#endif\n\n#ifdef WINAPI_FAMILY\n#  define open _open\n#  define read _read\n#  define write _write\n#  define close _close\n#endif\n\n#ifdef NO_DEFLATE       /* for compatibility with old definition */\n#  define NO_GZCOMPRESS\n#endif\n\n#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)\n#  ifndef HAVE_VSNPRINTF\n#    define HAVE_VSNPRINTF\n#  endif\n#endif\n\n#if defined(__CYGWIN__)\n#  ifndef HAVE_VSNPRINTF\n#    define HAVE_VSNPRINTF\n#  endif\n#endif\n\n#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)\n#  ifndef HAVE_VSNPRINTF\n#    define HAVE_VSNPRINTF\n#  endif\n#endif\n\n#ifndef HAVE_VSNPRINTF\n#  ifdef MSDOS\n/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),\n   but for now we just assume it doesn't. */\n#    define NO_vsnprintf\n#  endif\n#  ifdef __TURBOC__\n#    define NO_vsnprintf\n#  endif\n#  ifdef WIN32\n/* In Win32, vsnprintf is available as the \"non-ANSI\" _vsnprintf. */\n#    if !defined(vsnprintf) && !defined(NO_vsnprintf)\n#      if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )\n#         define vsnprintf _vsnprintf\n#      endif\n#    endif\n#  endif\n#  ifdef __SASC\n#    define NO_vsnprintf\n#  endif\n#  ifdef VMS\n#    define NO_vsnprintf\n#  endif\n#  ifdef __OS400__\n#    define NO_vsnprintf\n#  endif\n#  ifdef __MVS__\n#    define NO_vsnprintf\n#  endif\n#endif\n\n/* unlike snprintf (which is required in C99, yet still not supported by\n   Microsoft more than a decade later!), _snprintf does not guarantee null\n   termination of the result -- however this is only used in gzlib.c where\n   the result is assured to fit in the space provided */\n#ifdef _MSC_VER\n#  define snprintf _snprintf\n#endif\n\n#ifndef local\n#  define local static\n#endif\n/* compile with -Dlocal if your debugger can't find static symbols */\n\n/* gz* functions always use library allocation functions */\n#ifndef STDC\n  extern voidp  malloc OF((uInt size));\n  extern void   free   OF((voidpf ptr));\n#endif\n\n/* get errno and strerror definition */\n#if defined UNDER_CE\n#  include <windows.h>\n#  define zstrerror() gz_strwinerror((DWORD)GetLastError())\n#else\n#  ifndef NO_STRERROR\n#    include <errno.h>\n#    define zstrerror() strerror(errno)\n#  else\n#    define zstrerror() \"stdio error (consult errno)\"\n#  endif\n#endif\n\n/* provide prototypes for these when building zlib without LFS */\n#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0\n    ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));\n    ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));\n    ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));\n    ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));\n#endif\n\n/* default memLevel */\n#if MAX_MEM_LEVEL >= 8\n#  define DEF_MEM_LEVEL 8\n#else\n#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL\n#endif\n\n/* default i/o buffer size -- double this for output when reading (this and\n   twice this must be able to fit in an unsigned type) */\n#define GZBUFSIZE 8192\n\n/* gzip modes, also provide a little integrity check on the passed structure */\n#define GZ_NONE 0\n#define GZ_READ 7247\n#define GZ_WRITE 31153\n#define GZ_APPEND 1     /* mode set to GZ_WRITE after the file is opened */\n\n/* values for gz_state how */\n#define LOOK 0      /* look for a gzip header */\n#define COPY 1      /* copy input directly */\n#define GZIP 2      /* decompress a gzip stream */\n\n/* internal gzip file state data structure */\ntypedef struct {\n        /* exposed contents for gzgetc() macro */\n    struct gzFile_s x;      /* \"x\" for exposed */\n                            /* x.have: number of bytes available at x.next */\n                            /* x.next: next output data to deliver or write */\n                            /* x.pos: current position in uncompressed data */\n        /* used for both reading and writing */\n    int mode;               /* see gzip modes above */\n    int fd;                 /* file descriptor */\n    char *path;             /* path or fd for error messages */\n    unsigned size;          /* buffer size, zero if not allocated yet */\n    unsigned want;          /* requested buffer size, default is GZBUFSIZE */\n    unsigned char *in;      /* input buffer */\n    unsigned char *out;     /* output buffer (double-sized when reading) */\n    int direct;             /* 0 if processing gzip, 1 if transparent */\n        /* just for reading */\n    int how;                /* 0: get header, 1: copy, 2: decompress */\n    z_off64_t start;        /* where the gzip data started, for rewinding */\n    int eof;                /* true if end of input file reached */\n    int past;               /* true if read requested past end */\n        /* just for writing */\n    int level;              /* compression level */\n    int strategy;           /* compression strategy */\n        /* seek request */\n    z_off64_t skip;         /* amount to skip (already rewound if backwards) */\n    int seek;               /* true if seek request pending */\n        /* error information */\n    int err;                /* error code */\n    char *msg;              /* error message */\n        /* zlib inflate or deflate stream */\n    z_stream strm;          /* stream structure in-place (not a pointer) */\n} gz_state;\ntypedef gz_state FAR *gz_statep;\n\n/* shared functions */\nvoid ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));\n#if defined UNDER_CE\nchar ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));\n#endif\n\n/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t\n   value -- needed when comparing unsigned to z_off64_t, which is signed\n   (possible z_off64_t types off_t, off64_t, and long are all signed) */\n#ifdef INT_MAX\n#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)\n#else\nunsigned ZLIB_INTERNAL gz_intmax OF((void));\n#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/gzlib.c",
    "content": "/* gzlib.c -- zlib functions common to reading and writing gzip files\n * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#include \"gzguts.h\"\n\n#if defined(_WIN32) && !defined(__BORLANDC__)\n#  define LSEEK _lseeki64\n#else\n#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0\n#  define LSEEK lseek64\n#else\n#  define LSEEK lseek\n#endif\n#endif\n\n/* Local functions */\nlocal void gz_reset OF((gz_statep));\nlocal gzFile gz_open OF((const void *, int, const char *));\n\n#if defined UNDER_CE\n\n/* Map the Windows error number in ERROR to a locale-dependent error message\n   string and return a pointer to it.  Typically, the values for ERROR come\n   from GetLastError.\n\n   The string pointed to shall not be modified by the application, but may be\n   overwritten by a subsequent call to gz_strwinerror\n\n   The gz_strwinerror function does not change the current setting of\n   GetLastError. */\nchar ZLIB_INTERNAL *gz_strwinerror (error)\n     DWORD error;\n{\n    static char buf[1024];\n\n    wchar_t *msgbuf;\n    DWORD lasterr = GetLastError();\n    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM\n        | FORMAT_MESSAGE_ALLOCATE_BUFFER,\n        NULL,\n        error,\n        0, /* Default language */\n        (LPVOID)&msgbuf,\n        0,\n        NULL);\n    if (chars != 0) {\n        /* If there is an \\r\\n appended, zap it.  */\n        if (chars >= 2\n            && msgbuf[chars - 2] == '\\r' && msgbuf[chars - 1] == '\\n') {\n            chars -= 2;\n            msgbuf[chars] = 0;\n        }\n\n        if (chars > sizeof (buf) - 1) {\n            chars = sizeof (buf) - 1;\n            msgbuf[chars] = 0;\n        }\n\n        wcstombs(buf, msgbuf, chars + 1);\n        LocalFree(msgbuf);\n    }\n    else {\n        sprintf(buf, \"unknown win32 error (%ld)\", error);\n    }\n\n    SetLastError(lasterr);\n    return buf;\n}\n\n#endif /* UNDER_CE */\n\n/* Reset gzip file state */\nlocal void gz_reset(state)\n    gz_statep state;\n{\n    state->x.have = 0;              /* no output data available */\n    if (state->mode == GZ_READ) {   /* for reading ... */\n        state->eof = 0;             /* not at end of file */\n        state->past = 0;            /* have not read past end yet */\n        state->how = LOOK;          /* look for gzip header */\n    }\n    state->seek = 0;                /* no seek request pending */\n    gz_error(state, Z_OK, NULL);    /* clear error */\n    state->x.pos = 0;               /* no uncompressed data yet */\n    state->strm.avail_in = 0;       /* no input data yet */\n}\n\n/* Open a gzip file either by name or file descriptor. */\nlocal gzFile gz_open(path, fd, mode)\n    const void *path;\n    int fd;\n    const char *mode;\n{\n    gz_statep state;\n    size_t len;\n    int oflag;\n#ifdef O_CLOEXEC\n    int cloexec = 0;\n#endif\n#ifdef O_EXCL\n    int exclusive = 0;\n#endif\n\n    /* check input */\n    if (path == NULL)\n        return NULL;\n\n    /* allocate gzFile structure to return */\n    state = (gz_statep)malloc(sizeof(gz_state));\n    if (state == NULL)\n        return NULL;\n    state->size = 0;            /* no buffers allocated yet */\n    state->want = GZBUFSIZE;    /* requested buffer size */\n    state->msg = NULL;          /* no error message yet */\n\n    /* interpret mode */\n    state->mode = GZ_NONE;\n    state->level = Z_DEFAULT_COMPRESSION;\n    state->strategy = Z_DEFAULT_STRATEGY;\n    state->direct = 0;\n    while (*mode) {\n        if (*mode >= '0' && *mode <= '9')\n            state->level = *mode - '0';\n        else\n            switch (*mode) {\n            case 'r':\n                state->mode = GZ_READ;\n                break;\n#ifndef NO_GZCOMPRESS\n            case 'w':\n                state->mode = GZ_WRITE;\n                break;\n            case 'a':\n                state->mode = GZ_APPEND;\n                break;\n#endif\n            case '+':       /* can't read and write at the same time */\n                free(state);\n                return NULL;\n            case 'b':       /* ignore -- will request binary anyway */\n                break;\n#ifdef O_CLOEXEC\n            case 'e':\n                cloexec = 1;\n                break;\n#endif\n#ifdef O_EXCL\n            case 'x':\n                exclusive = 1;\n                break;\n#endif\n            case 'f':\n                state->strategy = Z_FILTERED;\n                break;\n            case 'h':\n                state->strategy = Z_HUFFMAN_ONLY;\n                break;\n            case 'R':\n                state->strategy = Z_RLE;\n                break;\n            case 'F':\n                state->strategy = Z_FIXED;\n                break;\n            case 'T':\n                state->direct = 1;\n                break;\n            default:        /* could consider as an error, but just ignore */\n                ;\n            }\n        mode++;\n    }\n\n    /* must provide an \"r\", \"w\", or \"a\" */\n    if (state->mode == GZ_NONE) {\n        free(state);\n        return NULL;\n    }\n\n    /* can't force transparent read */\n    if (state->mode == GZ_READ) {\n        if (state->direct) {\n            free(state);\n            return NULL;\n        }\n        state->direct = 1;      /* for empty file */\n    }\n\n    /* save the path name for error messages */\n#ifdef _WIN32\n    if (fd == -2) {\n        len = wcstombs(NULL, path, 0);\n        if (len == (size_t)-1)\n            len = 0;\n    }\n    else\n#endif\n        len = strlen((const char *)path);\n    state->path = (char *)malloc(len + 1);\n    if (state->path == NULL) {\n        free(state);\n        return NULL;\n    }\n#ifdef _WIN32\n    if (fd == -2)\n        if (len)\n            wcstombs(state->path, path, len + 1);\n        else\n            *(state->path) = 0;\n    else\n#endif\n#if !defined(NO_snprintf) && !defined(NO_vsnprintf)\n        snprintf(state->path, len + 1, \"%s\", (const char *)path);\n#else\n        strcpy(state->path, path);\n#endif\n\n    /* compute the flags for open() */\n    oflag =\n#ifdef O_LARGEFILE\n        O_LARGEFILE |\n#endif\n#ifdef O_BINARY\n        O_BINARY |\n#endif\n#ifdef O_CLOEXEC\n        (cloexec ? O_CLOEXEC : 0) |\n#endif\n        (state->mode == GZ_READ ?\n         O_RDONLY :\n         (O_WRONLY | O_CREAT |\n#ifdef O_EXCL\n          (exclusive ? O_EXCL : 0) |\n#endif\n          (state->mode == GZ_WRITE ?\n           O_TRUNC :\n           O_APPEND)));\n\n    /* open the file with the appropriate flags (or just use fd) */\n    state->fd = fd > -1 ? fd : (\n#ifdef _WIN32\n        fd == -2 ? _wopen(path, oflag, 0666) :\n#endif\n        open((const char *)path, oflag, 0666));\n    if (state->fd == -1) {\n        free(state->path);\n        free(state);\n        return NULL;\n    }\n    if (state->mode == GZ_APPEND)\n        state->mode = GZ_WRITE;         /* simplify later checks */\n\n    /* save the current position for rewinding (only if reading) */\n    if (state->mode == GZ_READ) {\n        state->start = LSEEK(state->fd, 0, SEEK_CUR);\n        if (state->start == -1) state->start = 0;\n    }\n\n    /* initialize stream */\n    gz_reset(state);\n\n    /* return stream */\n    return (gzFile)state;\n}\n\n/* -- see zlib.h -- */\ngzFile ZEXPORT gzopen(path, mode)\n    const char *path;\n    const char *mode;\n{\n    return gz_open(path, -1, mode);\n}\n\n/* -- see zlib.h -- */\ngzFile ZEXPORT gzopen64(path, mode)\n    const char *path;\n    const char *mode;\n{\n    return gz_open(path, -1, mode);\n}\n\n/* -- see zlib.h -- */\ngzFile ZEXPORT gzdopen(fd, mode)\n    int fd;\n    const char *mode;\n{\n    char *path;         /* identifier for error messages */\n    gzFile gz;\n\n    if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)\n        return NULL;\n#if !defined(NO_snprintf) && !defined(NO_vsnprintf)\n    snprintf(path, 7 + 3 * sizeof(int), \"<fd:%d>\", fd); /* for debugging */\n#else\n    sprintf(path, \"<fd:%d>\", fd);   /* for debugging */\n#endif\n    gz = gz_open(path, fd, mode);\n    free(path);\n    return gz;\n}\n\n/* -- see zlib.h -- */\n#ifdef _WIN32\ngzFile ZEXPORT gzopen_w(path, mode)\n    const wchar_t *path;\n    const char *mode;\n{\n    return gz_open(path, -2, mode);\n}\n#endif\n\n/* -- see zlib.h -- */\nint ZEXPORT gzbuffer(file, size)\n    gzFile file;\n    unsigned size;\n{\n    gz_statep state;\n\n    /* get internal structure and check integrity */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ && state->mode != GZ_WRITE)\n        return -1;\n\n    /* make sure we haven't already allocated memory */\n    if (state->size != 0)\n        return -1;\n\n    /* check and set requested size */\n    if (size < 2)\n        size = 2;               /* need two bytes to check magic header */\n    state->want = size;\n    return 0;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzrewind(file)\n    gzFile file;\n{\n    gz_statep state;\n\n    /* get internal structure */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n\n    /* check that we're reading and that there's no error */\n    if (state->mode != GZ_READ ||\n            (state->err != Z_OK && state->err != Z_BUF_ERROR))\n        return -1;\n\n    /* back up and start over */\n    if (LSEEK(state->fd, state->start, SEEK_SET) == -1)\n        return -1;\n    gz_reset(state);\n    return 0;\n}\n\n/* -- see zlib.h -- */\nz_off64_t ZEXPORT gzseek64(file, offset, whence)\n    gzFile file;\n    z_off64_t offset;\n    int whence;\n{\n    unsigned n;\n    z_off64_t ret;\n    gz_statep state;\n\n    /* get internal structure and check integrity */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ && state->mode != GZ_WRITE)\n        return -1;\n\n    /* check that there's no error */\n    if (state->err != Z_OK && state->err != Z_BUF_ERROR)\n        return -1;\n\n    /* can only seek from start or relative to current position */\n    if (whence != SEEK_SET && whence != SEEK_CUR)\n        return -1;\n\n    /* normalize offset to a SEEK_CUR specification */\n    if (whence == SEEK_SET)\n        offset -= state->x.pos;\n    else if (state->seek)\n        offset += state->skip;\n    state->seek = 0;\n\n    /* if within raw area while reading, just go there */\n    if (state->mode == GZ_READ && state->how == COPY &&\n            state->x.pos + offset >= 0) {\n        ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);\n        if (ret == -1)\n            return -1;\n        state->x.have = 0;\n        state->eof = 0;\n        state->past = 0;\n        state->seek = 0;\n        gz_error(state, Z_OK, NULL);\n        state->strm.avail_in = 0;\n        state->x.pos += offset;\n        return state->x.pos;\n    }\n\n    /* calculate skip amount, rewinding if needed for back seek when reading */\n    if (offset < 0) {\n        if (state->mode != GZ_READ)         /* writing -- can't go backwards */\n            return -1;\n        offset += state->x.pos;\n        if (offset < 0)                     /* before start of file! */\n            return -1;\n        if (gzrewind(file) == -1)           /* rewind, then skip to offset */\n            return -1;\n    }\n\n    /* if reading, skip what's in output buffer (one less gzgetc() check) */\n    if (state->mode == GZ_READ) {\n        n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?\n            (unsigned)offset : state->x.have;\n        state->x.have -= n;\n        state->x.next += n;\n        state->x.pos += n;\n        offset -= n;\n    }\n\n    /* request skip (if not zero) */\n    if (offset) {\n        state->seek = 1;\n        state->skip = offset;\n    }\n    return state->x.pos + offset;\n}\n\n/* -- see zlib.h -- */\nz_off_t ZEXPORT gzseek(file, offset, whence)\n    gzFile file;\n    z_off_t offset;\n    int whence;\n{\n    z_off64_t ret;\n\n    ret = gzseek64(file, (z_off64_t)offset, whence);\n    return ret == (z_off_t)ret ? (z_off_t)ret : -1;\n}\n\n/* -- see zlib.h -- */\nz_off64_t ZEXPORT gztell64(file)\n    gzFile file;\n{\n    gz_statep state;\n\n    /* get internal structure and check integrity */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ && state->mode != GZ_WRITE)\n        return -1;\n\n    /* return position */\n    return state->x.pos + (state->seek ? state->skip : 0);\n}\n\n/* -- see zlib.h -- */\nz_off_t ZEXPORT gztell(file)\n    gzFile file;\n{\n    z_off64_t ret;\n\n    ret = gztell64(file);\n    return ret == (z_off_t)ret ? (z_off_t)ret : -1;\n}\n\n/* -- see zlib.h -- */\nz_off64_t ZEXPORT gzoffset64(file)\n    gzFile file;\n{\n    z_off64_t offset;\n    gz_statep state;\n\n    /* get internal structure and check integrity */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ && state->mode != GZ_WRITE)\n        return -1;\n\n    /* compute and return effective offset in file */\n    offset = LSEEK(state->fd, 0, SEEK_CUR);\n    if (offset == -1)\n        return -1;\n    if (state->mode == GZ_READ)             /* reading */\n        offset -= state->strm.avail_in;     /* don't count buffered input */\n    return offset;\n}\n\n/* -- see zlib.h -- */\nz_off_t ZEXPORT gzoffset(file)\n    gzFile file;\n{\n    z_off64_t ret;\n\n    ret = gzoffset64(file);\n    return ret == (z_off_t)ret ? (z_off_t)ret : -1;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzeof(file)\n    gzFile file;\n{\n    gz_statep state;\n\n    /* get internal structure and check integrity */\n    if (file == NULL)\n        return 0;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ && state->mode != GZ_WRITE)\n        return 0;\n\n    /* return end-of-file state */\n    return state->mode == GZ_READ ? state->past : 0;\n}\n\n/* -- see zlib.h -- */\nconst char * ZEXPORT gzerror(file, errnum)\n    gzFile file;\n    int *errnum;\n{\n    gz_statep state;\n\n    /* get internal structure and check integrity */\n    if (file == NULL)\n        return NULL;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ && state->mode != GZ_WRITE)\n        return NULL;\n\n    /* return error information */\n    if (errnum != NULL)\n        *errnum = state->err;\n    return state->err == Z_MEM_ERROR ? \"out of memory\" :\n                                       (state->msg == NULL ? \"\" : state->msg);\n}\n\n/* -- see zlib.h -- */\nvoid ZEXPORT gzclearerr(file)\n    gzFile file;\n{\n    gz_statep state;\n\n    /* get internal structure and check integrity */\n    if (file == NULL)\n        return;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ && state->mode != GZ_WRITE)\n        return;\n\n    /* clear error and end-of-file */\n    if (state->mode == GZ_READ) {\n        state->eof = 0;\n        state->past = 0;\n    }\n    gz_error(state, Z_OK, NULL);\n}\n\n/* Create an error message in allocated memory and set state->err and\n   state->msg accordingly.  Free any previous error message already there.  Do\n   not try to free or allocate space if the error is Z_MEM_ERROR (out of\n   memory).  Simply save the error message as a static string.  If there is an\n   allocation failure constructing the error message, then convert the error to\n   out of memory. */\nvoid ZLIB_INTERNAL gz_error(state, err, msg)\n    gz_statep state;\n    int err;\n    const char *msg;\n{\n    /* free previously allocated message and clear */\n    if (state->msg != NULL) {\n        if (state->err != Z_MEM_ERROR)\n            free(state->msg);\n        state->msg = NULL;\n    }\n\n    /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */\n    if (err != Z_OK && err != Z_BUF_ERROR)\n        state->x.have = 0;\n\n    /* set error code, and if no message, then done */\n    state->err = err;\n    if (msg == NULL)\n        return;\n\n    /* for an out of memory error, return literal string when requested */\n    if (err == Z_MEM_ERROR)\n        return;\n\n    /* construct error message with path */\n    if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==\n            NULL) {\n        state->err = Z_MEM_ERROR;\n        return;\n    }\n#if !defined(NO_snprintf) && !defined(NO_vsnprintf)\n    snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,\n             \"%s%s%s\", state->path, \": \", msg);\n#else\n    strcpy(state->msg, state->path);\n    strcat(state->msg, \": \");\n    strcat(state->msg, msg);\n#endif\n    return;\n}\n\n#ifndef INT_MAX\n/* portably return maximum value for an int (when limits.h presumed not\n   available) -- we need to do this to cover cases where 2's complement not\n   used, since C standard permits 1's complement and sign-bit representations,\n   otherwise we could just use ((unsigned)-1) >> 1 */\nunsigned ZLIB_INTERNAL gz_intmax()\n{\n    unsigned p, q;\n\n    p = 1;\n    do {\n        q = p;\n        p <<= 1;\n        p++;\n    } while (p > q);\n    return q >> 1;\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/gzread.c",
    "content": "/* gzread.c -- zlib functions for reading gzip files\n * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#include \"gzguts.h\"\n\n/* Local functions */\nlocal int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));\nlocal int gz_avail OF((gz_statep));\nlocal int gz_look OF((gz_statep));\nlocal int gz_decomp OF((gz_statep));\nlocal int gz_fetch OF((gz_statep));\nlocal int gz_skip OF((gz_statep, z_off64_t));\n\n/* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from\n   state->fd, and update state->eof, state->err, and state->msg as appropriate.\n   This function needs to loop on read(), since read() is not guaranteed to\n   read the number of bytes requested, depending on the type of descriptor. */\nlocal int gz_load(state, buf, len, have)\n    gz_statep state;\n    unsigned char *buf;\n    unsigned len;\n    unsigned *have;\n{\n    int ret;\n\n    *have = 0;\n    do {\n        ret = read(state->fd, buf + *have, len - *have);\n        if (ret <= 0)\n            break;\n        *have += ret;\n    } while (*have < len);\n    if (ret < 0) {\n        gz_error(state, Z_ERRNO, zstrerror());\n        return -1;\n    }\n    if (ret == 0)\n        state->eof = 1;\n    return 0;\n}\n\n/* Load up input buffer and set eof flag if last data loaded -- return -1 on\n   error, 0 otherwise.  Note that the eof flag is set when the end of the input\n   file is reached, even though there may be unused data in the buffer.  Once\n   that data has been used, no more attempts will be made to read the file.\n   If strm->avail_in != 0, then the current data is moved to the beginning of\n   the input buffer, and then the remainder of the buffer is loaded with the\n   available data from the input file. */\nlocal int gz_avail(state)\n    gz_statep state;\n{\n    unsigned got;\n    z_streamp strm = &(state->strm);\n\n    if (state->err != Z_OK && state->err != Z_BUF_ERROR)\n        return -1;\n    if (state->eof == 0) {\n        if (strm->avail_in) {       /* copy what's there to the start */\n            unsigned char *p = state->in;\n            unsigned const char *q = strm->next_in;\n            unsigned n = strm->avail_in;\n            do {\n                *p++ = *q++;\n            } while (--n);\n        }\n        if (gz_load(state, state->in + strm->avail_in,\n                    state->size - strm->avail_in, &got) == -1)\n            return -1;\n        strm->avail_in += got;\n        strm->next_in = state->in;\n    }\n    return 0;\n}\n\n/* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.\n   If this is the first time in, allocate required memory.  state->how will be\n   left unchanged if there is no more input data available, will be set to COPY\n   if there is no gzip header and direct copying will be performed, or it will\n   be set to GZIP for decompression.  If direct copying, then leftover input\n   data from the input buffer will be copied to the output buffer.  In that\n   case, all further file reads will be directly to either the output buffer or\n   a user buffer.  If decompressing, the inflate state will be initialized.\n   gz_look() will return 0 on success or -1 on failure. */\nlocal int gz_look(state)\n    gz_statep state;\n{\n    z_streamp strm = &(state->strm);\n\n    /* allocate read buffers and inflate memory */\n    if (state->size == 0) {\n        /* allocate buffers */\n        state->in = (unsigned char *)malloc(state->want);\n        state->out = (unsigned char *)malloc(state->want << 1);\n        if (state->in == NULL || state->out == NULL) {\n            if (state->out != NULL)\n                free(state->out);\n            if (state->in != NULL)\n                free(state->in);\n            gz_error(state, Z_MEM_ERROR, \"out of memory\");\n            return -1;\n        }\n        state->size = state->want;\n\n        /* allocate inflate memory */\n        state->strm.zalloc = Z_NULL;\n        state->strm.zfree = Z_NULL;\n        state->strm.opaque = Z_NULL;\n        state->strm.avail_in = 0;\n        state->strm.next_in = Z_NULL;\n        if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) {    /* gunzip */\n            free(state->out);\n            free(state->in);\n            state->size = 0;\n            gz_error(state, Z_MEM_ERROR, \"out of memory\");\n            return -1;\n        }\n    }\n\n    /* get at least the magic bytes in the input buffer */\n    if (strm->avail_in < 2) {\n        if (gz_avail(state) == -1)\n            return -1;\n        if (strm->avail_in == 0)\n            return 0;\n    }\n\n    /* look for gzip magic bytes -- if there, do gzip decoding (note: there is\n       a logical dilemma here when considering the case of a partially written\n       gzip file, to wit, if a single 31 byte is written, then we cannot tell\n       whether this is a single-byte file, or just a partially written gzip\n       file -- for here we assume that if a gzip file is being written, then\n       the header will be written in a single operation, so that reading a\n       single byte is sufficient indication that it is not a gzip file) */\n    if (strm->avail_in > 1 &&\n            strm->next_in[0] == 31 && strm->next_in[1] == 139) {\n        inflateReset(strm);\n        state->how = GZIP;\n        state->direct = 0;\n        return 0;\n    }\n\n    /* no gzip header -- if we were decoding gzip before, then this is trailing\n       garbage.  Ignore the trailing garbage and finish. */\n    if (state->direct == 0) {\n        strm->avail_in = 0;\n        state->eof = 1;\n        state->x.have = 0;\n        return 0;\n    }\n\n    /* doing raw i/o, copy any leftover input to output -- this assumes that\n       the output buffer is larger than the input buffer, which also assures\n       space for gzungetc() */\n    state->x.next = state->out;\n    if (strm->avail_in) {\n        memcpy(state->x.next, strm->next_in, strm->avail_in);\n        state->x.have = strm->avail_in;\n        strm->avail_in = 0;\n    }\n    state->how = COPY;\n    state->direct = 1;\n    return 0;\n}\n\n/* Decompress from input to the provided next_out and avail_out in the state.\n   On return, state->x.have and state->x.next point to the just decompressed\n   data.  If the gzip stream completes, state->how is reset to LOOK to look for\n   the next gzip stream or raw data, once state->x.have is depleted.  Returns 0\n   on success, -1 on failure. */\nlocal int gz_decomp(state)\n    gz_statep state;\n{\n    int ret = Z_OK;\n    unsigned had;\n    z_streamp strm = &(state->strm);\n\n    /* fill output buffer up to end of deflate stream */\n    had = strm->avail_out;\n    do {\n        /* get more input for inflate() */\n        if (strm->avail_in == 0 && gz_avail(state) == -1)\n            return -1;\n        if (strm->avail_in == 0) {\n            gz_error(state, Z_BUF_ERROR, \"unexpected end of file\");\n            break;\n        }\n\n        /* decompress and handle errors */\n        ret = inflate(strm, Z_NO_FLUSH);\n        if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {\n            gz_error(state, Z_STREAM_ERROR,\n                     \"internal error: inflate stream corrupt\");\n            return -1;\n        }\n        if (ret == Z_MEM_ERROR) {\n            gz_error(state, Z_MEM_ERROR, \"out of memory\");\n            return -1;\n        }\n        if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */\n            gz_error(state, Z_DATA_ERROR,\n                     strm->msg == NULL ? \"compressed data error\" : strm->msg);\n            return -1;\n        }\n    } while (strm->avail_out && ret != Z_STREAM_END);\n\n    /* update available output */\n    state->x.have = had - strm->avail_out;\n    state->x.next = strm->next_out - state->x.have;\n\n    /* if the gzip stream completed successfully, look for another */\n    if (ret == Z_STREAM_END)\n        state->how = LOOK;\n\n    /* good decompression */\n    return 0;\n}\n\n/* Fetch data and put it in the output buffer.  Assumes state->x.have is 0.\n   Data is either copied from the input file or decompressed from the input\n   file depending on state->how.  If state->how is LOOK, then a gzip header is\n   looked for to determine whether to copy or decompress.  Returns -1 on error,\n   otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the\n   end of the input file has been reached and all data has been processed.  */\nlocal int gz_fetch(state)\n    gz_statep state;\n{\n    z_streamp strm = &(state->strm);\n\n    do {\n        switch(state->how) {\n        case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */\n            if (gz_look(state) == -1)\n                return -1;\n            if (state->how == LOOK)\n                return 0;\n            break;\n        case COPY:      /* -> COPY */\n            if (gz_load(state, state->out, state->size << 1, &(state->x.have))\n                    == -1)\n                return -1;\n            state->x.next = state->out;\n            return 0;\n        case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */\n            strm->avail_out = state->size << 1;\n            strm->next_out = state->out;\n            if (gz_decomp(state) == -1)\n                return -1;\n        }\n    } while (state->x.have == 0 && (!state->eof || strm->avail_in));\n    return 0;\n}\n\n/* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */\nlocal int gz_skip(state, len)\n    gz_statep state;\n    z_off64_t len;\n{\n    unsigned n;\n\n    /* skip over len bytes or reach end-of-file, whichever comes first */\n    while (len)\n        /* skip over whatever is in output buffer */\n        if (state->x.have) {\n            n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?\n                (unsigned)len : state->x.have;\n            state->x.have -= n;\n            state->x.next += n;\n            state->x.pos += n;\n            len -= n;\n        }\n\n        /* output buffer empty -- return if we're at the end of the input */\n        else if (state->eof && state->strm.avail_in == 0)\n            break;\n\n        /* need more data to skip -- load up output buffer */\n        else {\n            /* get more output, looking for header if required */\n            if (gz_fetch(state) == -1)\n                return -1;\n        }\n    return 0;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzread(file, buf, len)\n    gzFile file;\n    voidp buf;\n    unsigned len;\n{\n    unsigned got, n;\n    gz_statep state;\n    z_streamp strm;\n\n    /* get internal structure */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    strm = &(state->strm);\n\n    /* check that we're reading and that there's no (serious) error */\n    if (state->mode != GZ_READ ||\n            (state->err != Z_OK && state->err != Z_BUF_ERROR))\n        return -1;\n\n    /* since an int is returned, make sure len fits in one, otherwise return\n       with an error (this avoids the flaw in the interface) */\n    if ((int)len < 0) {\n        gz_error(state, Z_DATA_ERROR, \"requested length does not fit in int\");\n        return -1;\n    }\n\n    /* if len is zero, avoid unnecessary operations */\n    if (len == 0)\n        return 0;\n\n    /* process a skip request */\n    if (state->seek) {\n        state->seek = 0;\n        if (gz_skip(state, state->skip) == -1)\n            return -1;\n    }\n\n    /* get len bytes to buf, or less than len if at the end */\n    got = 0;\n    do {\n        /* first just try copying data from the output buffer */\n        if (state->x.have) {\n            n = state->x.have > len ? len : state->x.have;\n            memcpy(buf, state->x.next, n);\n            state->x.next += n;\n            state->x.have -= n;\n        }\n\n        /* output buffer empty -- return if we're at the end of the input */\n        else if (state->eof && strm->avail_in == 0) {\n            state->past = 1;        /* tried to read past end */\n            break;\n        }\n\n        /* need output data -- for small len or new stream load up our output\n           buffer */\n        else if (state->how == LOOK || len < (state->size << 1)) {\n            /* get more output, looking for header if required */\n            if (gz_fetch(state) == -1)\n                return -1;\n            continue;       /* no progress yet -- go back to copy above */\n            /* the copy above assures that we will leave with space in the\n               output buffer, allowing at least one gzungetc() to succeed */\n        }\n\n        /* large len -- read directly into user buffer */\n        else if (state->how == COPY) {      /* read directly */\n            if (gz_load(state, (unsigned char *)buf, len, &n) == -1)\n                return -1;\n        }\n\n        /* large len -- decompress directly into user buffer */\n        else {  /* state->how == GZIP */\n            strm->avail_out = len;\n            strm->next_out = (unsigned char *)buf;\n            if (gz_decomp(state) == -1)\n                return -1;\n            n = state->x.have;\n            state->x.have = 0;\n        }\n\n        /* update progress */\n        len -= n;\n        buf = (char *)buf + n;\n        got += n;\n        state->x.pos += n;\n    } while (len);\n\n    /* return number of bytes read into user buffer (will fit in int) */\n    return (int)got;\n}\n\n/* -- see zlib.h -- */\n#ifdef Z_PREFIX_SET\n#  undef z_gzgetc\n#else\n#  undef gzgetc\n#endif\nint ZEXPORT gzgetc(file)\n    gzFile file;\n{\n    int ret;\n    unsigned char buf[1];\n    gz_statep state;\n\n    /* get internal structure */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n\n    /* check that we're reading and that there's no (serious) error */\n    if (state->mode != GZ_READ ||\n        (state->err != Z_OK && state->err != Z_BUF_ERROR))\n        return -1;\n\n    /* try output buffer (no need to check for skip request) */\n    if (state->x.have) {\n        state->x.have--;\n        state->x.pos++;\n        return *(state->x.next)++;\n    }\n\n    /* nothing there -- try gzread() */\n    ret = gzread(file, buf, 1);\n    return ret < 1 ? -1 : buf[0];\n}\n\nint ZEXPORT gzgetc_(file)\ngzFile file;\n{\n    return gzgetc(file);\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzungetc(c, file)\n    int c;\n    gzFile file;\n{\n    gz_statep state;\n\n    /* get internal structure */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n\n    /* check that we're reading and that there's no (serious) error */\n    if (state->mode != GZ_READ ||\n        (state->err != Z_OK && state->err != Z_BUF_ERROR))\n        return -1;\n\n    /* process a skip request */\n    if (state->seek) {\n        state->seek = 0;\n        if (gz_skip(state, state->skip) == -1)\n            return -1;\n    }\n\n    /* can't push EOF */\n    if (c < 0)\n        return -1;\n\n    /* if output buffer empty, put byte at end (allows more pushing) */\n    if (state->x.have == 0) {\n        state->x.have = 1;\n        state->x.next = state->out + (state->size << 1) - 1;\n        state->x.next[0] = c;\n        state->x.pos--;\n        state->past = 0;\n        return c;\n    }\n\n    /* if no room, give up (must have already done a gzungetc()) */\n    if (state->x.have == (state->size << 1)) {\n        gz_error(state, Z_DATA_ERROR, \"out of room to push characters\");\n        return -1;\n    }\n\n    /* slide output data if needed and insert byte before existing data */\n    if (state->x.next == state->out) {\n        unsigned char *src = state->out + state->x.have;\n        unsigned char *dest = state->out + (state->size << 1);\n        while (src > state->out)\n            *--dest = *--src;\n        state->x.next = dest;\n    }\n    state->x.have++;\n    state->x.next--;\n    state->x.next[0] = c;\n    state->x.pos--;\n    state->past = 0;\n    return c;\n}\n\n/* -- see zlib.h -- */\nchar * ZEXPORT gzgets(file, buf, len)\n    gzFile file;\n    char *buf;\n    int len;\n{\n    unsigned left, n;\n    char *str;\n    unsigned char *eol;\n    gz_statep state;\n\n    /* check parameters and get internal structure */\n    if (file == NULL || buf == NULL || len < 1)\n        return NULL;\n    state = (gz_statep)file;\n\n    /* check that we're reading and that there's no (serious) error */\n    if (state->mode != GZ_READ ||\n        (state->err != Z_OK && state->err != Z_BUF_ERROR))\n        return NULL;\n\n    /* process a skip request */\n    if (state->seek) {\n        state->seek = 0;\n        if (gz_skip(state, state->skip) == -1)\n            return NULL;\n    }\n\n    /* copy output bytes up to new line or len - 1, whichever comes first --\n       append a terminating zero to the string (we don't check for a zero in\n       the contents, let the user worry about that) */\n    str = buf;\n    left = (unsigned)len - 1;\n    if (left) do {\n        /* assure that something is in the output buffer */\n        if (state->x.have == 0 && gz_fetch(state) == -1)\n            return NULL;                /* error */\n        if (state->x.have == 0) {       /* end of file */\n            state->past = 1;            /* read past end */\n            break;                      /* return what we have */\n        }\n\n        /* look for end-of-line in current output buffer */\n        n = state->x.have > left ? left : state->x.have;\n        eol = (unsigned char *)memchr(state->x.next, '\\n', n);\n        if (eol != NULL)\n            n = (unsigned)(eol - state->x.next) + 1;\n\n        /* copy through end-of-line, or remainder if not found */\n        memcpy(buf, state->x.next, n);\n        state->x.have -= n;\n        state->x.next += n;\n        state->x.pos += n;\n        left -= n;\n        buf += n;\n    } while (left && eol == NULL);\n\n    /* return terminated string, or if nothing, end of file */\n    if (buf == str)\n        return NULL;\n    buf[0] = 0;\n    return str;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzdirect(file)\n    gzFile file;\n{\n    gz_statep state;\n\n    /* get internal structure */\n    if (file == NULL)\n        return 0;\n    state = (gz_statep)file;\n\n    /* if the state is not known, but we can find out, then do so (this is\n       mainly for right after a gzopen() or gzdopen()) */\n    if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)\n        (void)gz_look(state);\n\n    /* return 1 if transparent, 0 if processing a gzip stream */\n    return state->direct;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzclose_r(file)\n    gzFile file;\n{\n    int ret, err;\n    gz_statep state;\n\n    /* get internal structure */\n    if (file == NULL)\n        return Z_STREAM_ERROR;\n    state = (gz_statep)file;\n\n    /* check that we're reading */\n    if (state->mode != GZ_READ)\n        return Z_STREAM_ERROR;\n\n    /* free memory and close file */\n    if (state->size) {\n        inflateEnd(&(state->strm));\n        free(state->out);\n        free(state->in);\n    }\n    err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;\n    gz_error(state, Z_OK, NULL);\n    free(state->path);\n    ret = close(state->fd);\n    free(state);\n    return ret ? Z_ERRNO : err;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/gzwrite.c",
    "content": "/* gzwrite.c -- zlib functions for writing gzip files\n * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#include \"gzguts.h\"\n\n/* Local functions */\nlocal int gz_init OF((gz_statep));\nlocal int gz_comp OF((gz_statep, int));\nlocal int gz_zero OF((gz_statep, z_off64_t));\n\n/* Initialize state for writing a gzip file.  Mark initialization by setting\n   state->size to non-zero.  Return -1 on failure or 0 on success. */\nlocal int gz_init(state)\n    gz_statep state;\n{\n    int ret;\n    z_streamp strm = &(state->strm);\n\n    /* allocate input buffer */\n    state->in = (unsigned char *)malloc(state->want);\n    if (state->in == NULL) {\n        gz_error(state, Z_MEM_ERROR, \"out of memory\");\n        return -1;\n    }\n\n    /* only need output buffer and deflate state if compressing */\n    if (!state->direct) {\n        /* allocate output buffer */\n        state->out = (unsigned char *)malloc(state->want);\n        if (state->out == NULL) {\n            free(state->in);\n            gz_error(state, Z_MEM_ERROR, \"out of memory\");\n            return -1;\n        }\n\n        /* allocate deflate memory, set up for gzip compression */\n        strm->zalloc = Z_NULL;\n        strm->zfree = Z_NULL;\n        strm->opaque = Z_NULL;\n        ret = deflateInit2(strm, state->level, Z_DEFLATED,\n                           MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);\n        if (ret != Z_OK) {\n            free(state->out);\n            free(state->in);\n            gz_error(state, Z_MEM_ERROR, \"out of memory\");\n            return -1;\n        }\n    }\n\n    /* mark state as initialized */\n    state->size = state->want;\n\n    /* initialize write buffer if compressing */\n    if (!state->direct) {\n        strm->avail_out = state->size;\n        strm->next_out = state->out;\n        state->x.next = strm->next_out;\n    }\n    return 0;\n}\n\n/* Compress whatever is at avail_in and next_in and write to the output file.\n   Return -1 if there is an error writing to the output file, otherwise 0.\n   flush is assumed to be a valid deflate() flush value.  If flush is Z_FINISH,\n   then the deflate() state is reset to start a new gzip stream.  If gz->direct\n   is true, then simply write to the output file without compressing, and\n   ignore flush. */\nlocal int gz_comp(state, flush)\n    gz_statep state;\n    int flush;\n{\n    int ret, got;\n    unsigned have;\n    z_streamp strm = &(state->strm);\n\n    /* allocate memory if this is the first time through */\n    if (state->size == 0 && gz_init(state) == -1)\n        return -1;\n\n    /* write directly if requested */\n    if (state->direct) {\n        got = write(state->fd, strm->next_in, strm->avail_in);\n        if (got < 0 || (unsigned)got != strm->avail_in) {\n            gz_error(state, Z_ERRNO, zstrerror());\n            return -1;\n        }\n        strm->avail_in = 0;\n        return 0;\n    }\n\n    /* run deflate() on provided input until it produces no more output */\n    ret = Z_OK;\n    do {\n        /* write out current buffer contents if full, or if flushing, but if\n           doing Z_FINISH then don't write until we get to Z_STREAM_END */\n        if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&\n            (flush != Z_FINISH || ret == Z_STREAM_END))) {\n            have = (unsigned)(strm->next_out - state->x.next);\n            if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||\n                         (unsigned)got != have)) {\n                gz_error(state, Z_ERRNO, zstrerror());\n                return -1;\n            }\n            if (strm->avail_out == 0) {\n                strm->avail_out = state->size;\n                strm->next_out = state->out;\n            }\n            state->x.next = strm->next_out;\n        }\n\n        /* compress */\n        have = strm->avail_out;\n        ret = deflate(strm, flush);\n        if (ret == Z_STREAM_ERROR) {\n            gz_error(state, Z_STREAM_ERROR,\n                      \"internal error: deflate stream corrupt\");\n            return -1;\n        }\n        have -= strm->avail_out;\n    } while (have);\n\n    /* if that completed a deflate stream, allow another to start */\n    if (flush == Z_FINISH)\n        deflateReset(strm);\n\n    /* all done, no errors */\n    return 0;\n}\n\n/* Compress len zeros to output.  Return -1 on error, 0 on success. */\nlocal int gz_zero(state, len)\n    gz_statep state;\n    z_off64_t len;\n{\n    int first;\n    unsigned n;\n    z_streamp strm = &(state->strm);\n\n    /* consume whatever's left in the input buffer */\n    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)\n        return -1;\n\n    /* compress len zeros (len guaranteed > 0) */\n    first = 1;\n    while (len) {\n        n = GT_OFF(state->size) || (z_off64_t)state->size > len ?\n            (unsigned)len : state->size;\n        if (first) {\n            memset(state->in, 0, n);\n            first = 0;\n        }\n        strm->avail_in = n;\n        strm->next_in = state->in;\n        state->x.pos += n;\n        if (gz_comp(state, Z_NO_FLUSH) == -1)\n            return -1;\n        len -= n;\n    }\n    return 0;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzwrite(file, buf, len)\n    gzFile file;\n    voidpc buf;\n    unsigned len;\n{\n    unsigned put = len;\n    gz_statep state;\n    z_streamp strm;\n\n    /* get internal structure */\n    if (file == NULL)\n        return 0;\n    state = (gz_statep)file;\n    strm = &(state->strm);\n\n    /* check that we're writing and that there's no error */\n    if (state->mode != GZ_WRITE || state->err != Z_OK)\n        return 0;\n\n    /* since an int is returned, make sure len fits in one, otherwise return\n       with an error (this avoids the flaw in the interface) */\n    if ((int)len < 0) {\n        gz_error(state, Z_DATA_ERROR, \"requested length does not fit in int\");\n        return 0;\n    }\n\n    /* if len is zero, avoid unnecessary operations */\n    if (len == 0)\n        return 0;\n\n    /* allocate memory if this is the first time through */\n    if (state->size == 0 && gz_init(state) == -1)\n        return 0;\n\n    /* check for seek request */\n    if (state->seek) {\n        state->seek = 0;\n        if (gz_zero(state, state->skip) == -1)\n            return 0;\n    }\n\n    /* for small len, copy to input buffer, otherwise compress directly */\n    if (len < state->size) {\n        /* copy to input buffer, compress when full */\n        do {\n            unsigned have, copy;\n\n            if (strm->avail_in == 0)\n                strm->next_in = state->in;\n            have = (unsigned)((strm->next_in + strm->avail_in) - state->in);\n            copy = state->size - have;\n            if (copy > len)\n                copy = len;\n            memcpy(state->in + have, buf, copy);\n            strm->avail_in += copy;\n            state->x.pos += copy;\n            buf = (const char *)buf + copy;\n            len -= copy;\n            if (len && gz_comp(state, Z_NO_FLUSH) == -1)\n                return 0;\n        } while (len);\n    }\n    else {\n        /* consume whatever's left in the input buffer */\n        if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)\n            return 0;\n\n        /* directly compress user buffer to file */\n        strm->avail_in = len;\n        strm->next_in = (z_const Bytef *)buf;\n        state->x.pos += len;\n        if (gz_comp(state, Z_NO_FLUSH) == -1)\n            return 0;\n    }\n\n    /* input was all buffered or compressed (put will fit in int) */\n    return (int)put;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzputc(file, c)\n    gzFile file;\n    int c;\n{\n    unsigned have;\n    unsigned char buf[1];\n    gz_statep state;\n    z_streamp strm;\n\n    /* get internal structure */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    strm = &(state->strm);\n\n    /* check that we're writing and that there's no error */\n    if (state->mode != GZ_WRITE || state->err != Z_OK)\n        return -1;\n\n    /* check for seek request */\n    if (state->seek) {\n        state->seek = 0;\n        if (gz_zero(state, state->skip) == -1)\n            return -1;\n    }\n\n    /* try writing to input buffer for speed (state->size == 0 if buffer not\n       initialized) */\n    if (state->size) {\n        if (strm->avail_in == 0)\n            strm->next_in = state->in;\n        have = (unsigned)((strm->next_in + strm->avail_in) - state->in);\n        if (have < state->size) {\n            state->in[have] = c;\n            strm->avail_in++;\n            state->x.pos++;\n            return c & 0xff;\n        }\n    }\n\n    /* no room in buffer or not initialized, use gz_write() */\n    buf[0] = c;\n    if (gzwrite(file, buf, 1) != 1)\n        return -1;\n    return c & 0xff;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzputs(file, str)\n    gzFile file;\n    const char *str;\n{\n    int ret;\n    unsigned len;\n\n    /* write string */\n    len = (unsigned)strlen(str);\n    ret = gzwrite(file, str, len);\n    return ret == 0 && len != 0 ? -1 : ret;\n}\n\n#if defined(STDC) || defined(Z_HAVE_STDARG_H)\n#include <stdarg.h>\n\n/* -- see zlib.h -- */\nint ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)\n{\n    int size, len;\n    gz_statep state;\n    z_streamp strm;\n\n    /* get internal structure */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    strm = &(state->strm);\n\n    /* check that we're writing and that there's no error */\n    if (state->mode != GZ_WRITE || state->err != Z_OK)\n        return 0;\n\n    /* make sure we have some buffer space */\n    if (state->size == 0 && gz_init(state) == -1)\n        return 0;\n\n    /* check for seek request */\n    if (state->seek) {\n        state->seek = 0;\n        if (gz_zero(state, state->skip) == -1)\n            return 0;\n    }\n\n    /* consume whatever's left in the input buffer */\n    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)\n        return 0;\n\n    /* do the printf() into the input buffer, put length in len */\n    size = (int)(state->size);\n    state->in[size - 1] = 0;\n#ifdef NO_vsnprintf\n#  ifdef HAS_vsprintf_void\n    (void)vsprintf((char *)(state->in), format, va);\n    for (len = 0; len < size; len++)\n        if (state->in[len] == 0) break;\n#  else\n    len = vsprintf((char *)(state->in), format, va);\n#  endif\n#else\n#  ifdef HAS_vsnprintf_void\n    (void)vsnprintf((char *)(state->in), size, format, va);\n    len = strlen((char *)(state->in));\n#  else\n    len = vsnprintf((char *)(state->in), size, format, va);\n#  endif\n#endif\n\n    /* check that printf() results fit in buffer */\n    if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)\n        return 0;\n\n    /* update buffer and position, defer compression until needed */\n    strm->avail_in = (unsigned)len;\n    strm->next_in = state->in;\n    state->x.pos += len;\n    return len;\n}\n\nint ZEXPORTVA gzprintf(gzFile file, const char *format, ...)\n{\n    va_list va;\n    int ret;\n\n    va_start(va, format);\n    ret = gzvprintf(file, format, va);\n    va_end(va);\n    return ret;\n}\n\n#else /* !STDC && !Z_HAVE_STDARG_H */\n\n/* -- see zlib.h -- */\nint ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,\n                       a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)\n    gzFile file;\n    const char *format;\n    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,\n        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;\n{\n    int size, len;\n    gz_statep state;\n    z_streamp strm;\n\n    /* get internal structure */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    strm = &(state->strm);\n\n    /* check that can really pass pointer in ints */\n    if (sizeof(int) != sizeof(void *))\n        return 0;\n\n    /* check that we're writing and that there's no error */\n    if (state->mode != GZ_WRITE || state->err != Z_OK)\n        return 0;\n\n    /* make sure we have some buffer space */\n    if (state->size == 0 && gz_init(state) == -1)\n        return 0;\n\n    /* check for seek request */\n    if (state->seek) {\n        state->seek = 0;\n        if (gz_zero(state, state->skip) == -1)\n            return 0;\n    }\n\n    /* consume whatever's left in the input buffer */\n    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)\n        return 0;\n\n    /* do the printf() into the input buffer, put length in len */\n    size = (int)(state->size);\n    state->in[size - 1] = 0;\n#ifdef NO_snprintf\n#  ifdef HAS_sprintf_void\n    sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,\n            a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);\n    for (len = 0; len < size; len++)\n        if (state->in[len] == 0) break;\n#  else\n    len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,\n                  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);\n#  endif\n#else\n#  ifdef HAS_snprintf_void\n    snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,\n             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);\n    len = strlen((char *)(state->in));\n#  else\n    len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,\n                   a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,\n                   a19, a20);\n#  endif\n#endif\n\n    /* check that printf() results fit in buffer */\n    if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)\n        return 0;\n\n    /* update buffer and position, defer compression until needed */\n    strm->avail_in = (unsigned)len;\n    strm->next_in = state->in;\n    state->x.pos += len;\n    return len;\n}\n\n#endif\n\n/* -- see zlib.h -- */\nint ZEXPORT gzflush(file, flush)\n    gzFile file;\n    int flush;\n{\n    gz_statep state;\n\n    /* get internal structure */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n\n    /* check that we're writing and that there's no error */\n    if (state->mode != GZ_WRITE || state->err != Z_OK)\n        return Z_STREAM_ERROR;\n\n    /* check flush parameter */\n    if (flush < 0 || flush > Z_FINISH)\n        return Z_STREAM_ERROR;\n\n    /* check for seek request */\n    if (state->seek) {\n        state->seek = 0;\n        if (gz_zero(state, state->skip) == -1)\n            return -1;\n    }\n\n    /* compress remaining data with requested flush */\n    gz_comp(state, flush);\n    return state->err;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzsetparams(file, level, strategy)\n    gzFile file;\n    int level;\n    int strategy;\n{\n    gz_statep state;\n    z_streamp strm;\n\n    /* get internal structure */\n    if (file == NULL)\n        return Z_STREAM_ERROR;\n    state = (gz_statep)file;\n    strm = &(state->strm);\n\n    /* check that we're writing and that there's no error */\n    if (state->mode != GZ_WRITE || state->err != Z_OK)\n        return Z_STREAM_ERROR;\n\n    /* if no change is requested, then do nothing */\n    if (level == state->level && strategy == state->strategy)\n        return Z_OK;\n\n    /* check for seek request */\n    if (state->seek) {\n        state->seek = 0;\n        if (gz_zero(state, state->skip) == -1)\n            return -1;\n    }\n\n    /* change compression parameters for subsequent input */\n    if (state->size) {\n        /* flush previous input with previous parameters before changing */\n        if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)\n            return state->err;\n        deflateParams(strm, level, strategy);\n    }\n    state->level = level;\n    state->strategy = strategy;\n    return Z_OK;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzclose_w(file)\n    gzFile file;\n{\n    int ret = Z_OK;\n    gz_statep state;\n\n    /* get internal structure */\n    if (file == NULL)\n        return Z_STREAM_ERROR;\n    state = (gz_statep)file;\n\n    /* check that we're writing */\n    if (state->mode != GZ_WRITE)\n        return Z_STREAM_ERROR;\n\n    /* check for seek request */\n    if (state->seek) {\n        state->seek = 0;\n        if (gz_zero(state, state->skip) == -1)\n            ret = state->err;\n    }\n\n    /* flush, free memory, and close file */\n    if (gz_comp(state, Z_FINISH) == -1)\n        ret = state->err;\n    if (state->size) {\n        if (!state->direct) {\n            (void)deflateEnd(&(state->strm));\n            free(state->out);\n        }\n        free(state->in);\n    }\n    gz_error(state, Z_OK, NULL);\n    free(state->path);\n    if (close(state->fd) == -1)\n        ret = Z_ERRNO;\n    free(state);\n    return ret;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/infback.c",
    "content": "/* infback.c -- inflate using a call-back interface\n * Copyright (C) 1995-2011 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/*\n   This code is largely copied from inflate.c.  Normally either infback.o or\n   inflate.o would be linked into an application--not both.  The interface\n   with inffast.c is retained so that optimized assembler-coded versions of\n   inflate_fast() can be used with either inflate.c or infback.c.\n */\n\n#include \"zutil.h\"\n#include \"inftrees.h\"\n#include \"inflate.h\"\n#include \"inffast.h\"\n\n/* function prototypes */\nlocal void fixedtables OF((struct inflate_state FAR *state));\n\n/*\n   strm provides memory allocation functions in zalloc and zfree, or\n   Z_NULL to use the library memory allocation functions.\n\n   windowBits is in the range 8..15, and window is a user-supplied\n   window and output buffer that is 2**windowBits bytes.\n */\nint ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)\nz_streamp strm;\nint windowBits;\nunsigned char FAR *window;\nconst char *version;\nint stream_size;\n{\n    struct inflate_state FAR *state;\n\n    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||\n        stream_size != (int)(sizeof(z_stream)))\n        return Z_VERSION_ERROR;\n    if (strm == Z_NULL || window == Z_NULL ||\n        windowBits < 8 || windowBits > 15)\n        return Z_STREAM_ERROR;\n    strm->msg = Z_NULL;                 /* in case we return an error */\n    if (strm->zalloc == (alloc_func)0) {\n#ifdef Z_SOLO\n        return Z_STREAM_ERROR;\n#else\n        strm->zalloc = zcalloc;\n        strm->opaque = (voidpf)0;\n#endif\n    }\n    if (strm->zfree == (free_func)0)\n#ifdef Z_SOLO\n        return Z_STREAM_ERROR;\n#else\n    strm->zfree = zcfree;\n#endif\n    state = (struct inflate_state FAR *)ZALLOC(strm, 1,\n                                               sizeof(struct inflate_state));\n    if (state == Z_NULL) return Z_MEM_ERROR;\n    Tracev((stderr, \"inflate: allocated\\n\"));\n    strm->state = (struct internal_state FAR *)state;\n    state->dmax = 32768U;\n    state->wbits = windowBits;\n    state->wsize = 1U << windowBits;\n    state->window = window;\n    state->wnext = 0;\n    state->whave = 0;\n    return Z_OK;\n}\n\n/*\n   Return state with length and distance decoding tables and index sizes set to\n   fixed code decoding.  Normally this returns fixed tables from inffixed.h.\n   If BUILDFIXED is defined, then instead this routine builds the tables the\n   first time it's called, and returns those tables the first time and\n   thereafter.  This reduces the size of the code by about 2K bytes, in\n   exchange for a little execution time.  However, BUILDFIXED should not be\n   used for threaded applications, since the rewriting of the tables and virgin\n   may not be thread-safe.\n */\nlocal void fixedtables(state)\nstruct inflate_state FAR *state;\n{\n#ifdef BUILDFIXED\n    static int virgin = 1;\n    static code *lenfix, *distfix;\n    static code fixed[544];\n\n    /* build fixed huffman tables if first call (may not be thread safe) */\n    if (virgin) {\n        unsigned sym, bits;\n        static code *next;\n\n        /* literal/length table */\n        sym = 0;\n        while (sym < 144) state->lens[sym++] = 8;\n        while (sym < 256) state->lens[sym++] = 9;\n        while (sym < 280) state->lens[sym++] = 7;\n        while (sym < 288) state->lens[sym++] = 8;\n        next = fixed;\n        lenfix = next;\n        bits = 9;\n        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);\n\n        /* distance table */\n        sym = 0;\n        while (sym < 32) state->lens[sym++] = 5;\n        distfix = next;\n        bits = 5;\n        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);\n\n        /* do this just once */\n        virgin = 0;\n    }\n#else /* !BUILDFIXED */\n#   include \"inffixed.h\"\n#endif /* BUILDFIXED */\n    state->lencode = lenfix;\n    state->lenbits = 9;\n    state->distcode = distfix;\n    state->distbits = 5;\n}\n\n/* Macros for inflateBack(): */\n\n/* Load returned state from inflate_fast() */\n#define LOAD() \\\n    do { \\\n        put = strm->next_out; \\\n        left = strm->avail_out; \\\n        next = strm->next_in; \\\n        have = strm->avail_in; \\\n        hold = state->hold; \\\n        bits = state->bits; \\\n    } while (0)\n\n/* Set state from registers for inflate_fast() */\n#define RESTORE() \\\n    do { \\\n        strm->next_out = put; \\\n        strm->avail_out = left; \\\n        strm->next_in = next; \\\n        strm->avail_in = have; \\\n        state->hold = hold; \\\n        state->bits = bits; \\\n    } while (0)\n\n/* Clear the input bit accumulator */\n#define INITBITS() \\\n    do { \\\n        hold = 0; \\\n        bits = 0; \\\n    } while (0)\n\n/* Assure that some input is available.  If input is requested, but denied,\n   then return a Z_BUF_ERROR from inflateBack(). */\n#define PULL() \\\n    do { \\\n        if (have == 0) { \\\n            have = in(in_desc, &next); \\\n            if (have == 0) { \\\n                next = Z_NULL; \\\n                ret = Z_BUF_ERROR; \\\n                goto inf_leave; \\\n            } \\\n        } \\\n    } while (0)\n\n/* Get a byte of input into the bit accumulator, or return from inflateBack()\n   with an error if there is no input available. */\n#define PULLBYTE() \\\n    do { \\\n        PULL(); \\\n        have--; \\\n        hold += (unsigned long)(*next++) << bits; \\\n        bits += 8; \\\n    } while (0)\n\n/* Assure that there are at least n bits in the bit accumulator.  If there is\n   not enough available input to do that, then return from inflateBack() with\n   an error. */\n#define NEEDBITS(n) \\\n    do { \\\n        while (bits < (unsigned)(n)) \\\n            PULLBYTE(); \\\n    } while (0)\n\n/* Return the low n bits of the bit accumulator (n < 16) */\n#define BITS(n) \\\n    ((unsigned)hold & ((1U << (n)) - 1))\n\n/* Remove n bits from the bit accumulator */\n#define DROPBITS(n) \\\n    do { \\\n        hold >>= (n); \\\n        bits -= (unsigned)(n); \\\n    } while (0)\n\n/* Remove zero to seven bits as needed to go to a byte boundary */\n#define BYTEBITS() \\\n    do { \\\n        hold >>= bits & 7; \\\n        bits -= bits & 7; \\\n    } while (0)\n\n/* Assure that some output space is available, by writing out the window\n   if it's full.  If the write fails, return from inflateBack() with a\n   Z_BUF_ERROR. */\n#define ROOM() \\\n    do { \\\n        if (left == 0) { \\\n            put = state->window; \\\n            left = state->wsize; \\\n            state->whave = left; \\\n            if (out(out_desc, put, left)) { \\\n                ret = Z_BUF_ERROR; \\\n                goto inf_leave; \\\n            } \\\n        } \\\n    } while (0)\n\n/*\n   strm provides the memory allocation functions and window buffer on input,\n   and provides information on the unused input on return.  For Z_DATA_ERROR\n   returns, strm will also provide an error message.\n\n   in() and out() are the call-back input and output functions.  When\n   inflateBack() needs more input, it calls in().  When inflateBack() has\n   filled the window with output, or when it completes with data in the\n   window, it calls out() to write out the data.  The application must not\n   change the provided input until in() is called again or inflateBack()\n   returns.  The application must not change the window/output buffer until\n   inflateBack() returns.\n\n   in() and out() are called with a descriptor parameter provided in the\n   inflateBack() call.  This parameter can be a structure that provides the\n   information required to do the read or write, as well as accumulated\n   information on the input and output such as totals and check values.\n\n   in() should return zero on failure.  out() should return non-zero on\n   failure.  If either in() or out() fails, than inflateBack() returns a\n   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it\n   was in() or out() that caused in the error.  Otherwise,  inflateBack()\n   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format\n   error, or Z_MEM_ERROR if it could not allocate memory for the state.\n   inflateBack() can also return Z_STREAM_ERROR if the input parameters\n   are not correct, i.e. strm is Z_NULL or the state was not initialized.\n */\nint ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)\nz_streamp strm;\nin_func in;\nvoid FAR *in_desc;\nout_func out;\nvoid FAR *out_desc;\n{\n    struct inflate_state FAR *state;\n    z_const unsigned char FAR *next;    /* next input */\n    unsigned char FAR *put;     /* next output */\n    unsigned have, left;        /* available input and output */\n    unsigned long hold;         /* bit buffer */\n    unsigned bits;              /* bits in bit buffer */\n    unsigned copy;              /* number of stored or match bytes to copy */\n    unsigned char FAR *from;    /* where to copy match bytes from */\n    code here;                  /* current decoding table entry */\n    code last;                  /* parent table entry */\n    unsigned len;               /* length to copy for repeats, bits to drop */\n    int ret;                    /* return code */\n    static const unsigned short order[19] = /* permutation of code lengths */\n        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};\n\n    /* Check that the strm exists and that the state was initialized */\n    if (strm == Z_NULL || strm->state == Z_NULL)\n        return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n\n    /* Reset the state */\n    strm->msg = Z_NULL;\n    state->mode = TYPE;\n    state->last = 0;\n    state->whave = 0;\n    next = strm->next_in;\n    have = next != Z_NULL ? strm->avail_in : 0;\n    hold = 0;\n    bits = 0;\n    put = state->window;\n    left = state->wsize;\n\n    /* Inflate until end of block marked as last */\n    for (;;)\n        switch (state->mode) {\n        case TYPE:\n            /* determine and dispatch block type */\n            if (state->last) {\n                BYTEBITS();\n                state->mode = DONE;\n                break;\n            }\n            NEEDBITS(3);\n            state->last = BITS(1);\n            DROPBITS(1);\n            switch (BITS(2)) {\n            case 0:                             /* stored block */\n                Tracev((stderr, \"inflate:     stored block%s\\n\",\n                        state->last ? \" (last)\" : \"\"));\n                state->mode = STORED;\n                break;\n            case 1:                             /* fixed block */\n                fixedtables(state);\n                Tracev((stderr, \"inflate:     fixed codes block%s\\n\",\n                        state->last ? \" (last)\" : \"\"));\n                state->mode = LEN;              /* decode codes */\n                break;\n            case 2:                             /* dynamic block */\n                Tracev((stderr, \"inflate:     dynamic codes block%s\\n\",\n                        state->last ? \" (last)\" : \"\"));\n                state->mode = TABLE;\n                break;\n            case 3:\n                strm->msg = (char *)\"invalid block type\";\n                state->mode = BAD;\n            }\n            DROPBITS(2);\n            break;\n\n        case STORED:\n            /* get and verify stored block length */\n            BYTEBITS();                         /* go to byte boundary */\n            NEEDBITS(32);\n            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {\n                strm->msg = (char *)\"invalid stored block lengths\";\n                state->mode = BAD;\n                break;\n            }\n            state->length = (unsigned)hold & 0xffff;\n            Tracev((stderr, \"inflate:       stored length %u\\n\",\n                    state->length));\n            INITBITS();\n\n            /* copy stored block from input to output */\n            while (state->length != 0) {\n                copy = state->length;\n                PULL();\n                ROOM();\n                if (copy > have) copy = have;\n                if (copy > left) copy = left;\n                zmemcpy(put, next, copy);\n                have -= copy;\n                next += copy;\n                left -= copy;\n                put += copy;\n                state->length -= copy;\n            }\n            Tracev((stderr, \"inflate:       stored end\\n\"));\n            state->mode = TYPE;\n            break;\n\n        case TABLE:\n            /* get dynamic table entries descriptor */\n            NEEDBITS(14);\n            state->nlen = BITS(5) + 257;\n            DROPBITS(5);\n            state->ndist = BITS(5) + 1;\n            DROPBITS(5);\n            state->ncode = BITS(4) + 4;\n            DROPBITS(4);\n#ifndef PKZIP_BUG_WORKAROUND\n            if (state->nlen > 286 || state->ndist > 30) {\n                strm->msg = (char *)\"too many length or distance symbols\";\n                state->mode = BAD;\n                break;\n            }\n#endif\n            Tracev((stderr, \"inflate:       table sizes ok\\n\"));\n\n            /* get code length code lengths (not a typo) */\n            state->have = 0;\n            while (state->have < state->ncode) {\n                NEEDBITS(3);\n                state->lens[order[state->have++]] = (unsigned short)BITS(3);\n                DROPBITS(3);\n            }\n            while (state->have < 19)\n                state->lens[order[state->have++]] = 0;\n            state->next = state->codes;\n            state->lencode = (code const FAR *)(state->next);\n            state->lenbits = 7;\n            ret = inflate_table(CODES, state->lens, 19, &(state->next),\n                                &(state->lenbits), state->work);\n            if (ret) {\n                strm->msg = (char *)\"invalid code lengths set\";\n                state->mode = BAD;\n                break;\n            }\n            Tracev((stderr, \"inflate:       code lengths ok\\n\"));\n\n            /* get length and distance code code lengths */\n            state->have = 0;\n            while (state->have < state->nlen + state->ndist) {\n                for (;;) {\n                    here = state->lencode[BITS(state->lenbits)];\n                    if ((unsigned)(here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                if (here.val < 16) {\n                    DROPBITS(here.bits);\n                    state->lens[state->have++] = here.val;\n                }\n                else {\n                    if (here.val == 16) {\n                        NEEDBITS(here.bits + 2);\n                        DROPBITS(here.bits);\n                        if (state->have == 0) {\n                            strm->msg = (char *)\"invalid bit length repeat\";\n                            state->mode = BAD;\n                            break;\n                        }\n                        len = (unsigned)(state->lens[state->have - 1]);\n                        copy = 3 + BITS(2);\n                        DROPBITS(2);\n                    }\n                    else if (here.val == 17) {\n                        NEEDBITS(here.bits + 3);\n                        DROPBITS(here.bits);\n                        len = 0;\n                        copy = 3 + BITS(3);\n                        DROPBITS(3);\n                    }\n                    else {\n                        NEEDBITS(here.bits + 7);\n                        DROPBITS(here.bits);\n                        len = 0;\n                        copy = 11 + BITS(7);\n                        DROPBITS(7);\n                    }\n                    if (state->have + copy > state->nlen + state->ndist) {\n                        strm->msg = (char *)\"invalid bit length repeat\";\n                        state->mode = BAD;\n                        break;\n                    }\n                    while (copy--)\n                        state->lens[state->have++] = (unsigned short)len;\n                }\n            }\n\n            /* handle error breaks in while */\n            if (state->mode == BAD) break;\n\n            /* check for end-of-block code (better have one) */\n            if (state->lens[256] == 0) {\n                strm->msg = (char *)\"invalid code -- missing end-of-block\";\n                state->mode = BAD;\n                break;\n            }\n\n            /* build code tables -- note: do not change the lenbits or distbits\n               values here (9 and 6) without reading the comments in inftrees.h\n               concerning the ENOUGH constants, which depend on those values */\n            state->next = state->codes;\n            state->lencode = (code const FAR *)(state->next);\n            state->lenbits = 9;\n            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),\n                                &(state->lenbits), state->work);\n            if (ret) {\n                strm->msg = (char *)\"invalid literal/lengths set\";\n                state->mode = BAD;\n                break;\n            }\n            state->distcode = (code const FAR *)(state->next);\n            state->distbits = 6;\n            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,\n                            &(state->next), &(state->distbits), state->work);\n            if (ret) {\n                strm->msg = (char *)\"invalid distances set\";\n                state->mode = BAD;\n                break;\n            }\n            Tracev((stderr, \"inflate:       codes ok\\n\"));\n            state->mode = LEN;\n\n        case LEN:\n            /* use inflate_fast() if we have enough input and output */\n            if (have >= 6 && left >= 258) {\n                RESTORE();\n                if (state->whave < state->wsize)\n                    state->whave = state->wsize - left;\n                inflate_fast(strm, state->wsize);\n                LOAD();\n                break;\n            }\n\n            /* get a literal, length, or end-of-block code */\n            for (;;) {\n                here = state->lencode[BITS(state->lenbits)];\n                if ((unsigned)(here.bits) <= bits) break;\n                PULLBYTE();\n            }\n            if (here.op && (here.op & 0xf0) == 0) {\n                last = here;\n                for (;;) {\n                    here = state->lencode[last.val +\n                            (BITS(last.bits + last.op) >> last.bits)];\n                    if ((unsigned)(last.bits + here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                DROPBITS(last.bits);\n            }\n            DROPBITS(here.bits);\n            state->length = (unsigned)here.val;\n\n            /* process literal */\n            if (here.op == 0) {\n                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?\n                        \"inflate:         literal '%c'\\n\" :\n                        \"inflate:         literal 0x%02x\\n\", here.val));\n                ROOM();\n                *put++ = (unsigned char)(state->length);\n                left--;\n                state->mode = LEN;\n                break;\n            }\n\n            /* process end of block */\n            if (here.op & 32) {\n                Tracevv((stderr, \"inflate:         end of block\\n\"));\n                state->mode = TYPE;\n                break;\n            }\n\n            /* invalid code */\n            if (here.op & 64) {\n                strm->msg = (char *)\"invalid literal/length code\";\n                state->mode = BAD;\n                break;\n            }\n\n            /* length code -- get extra bits, if any */\n            state->extra = (unsigned)(here.op) & 15;\n            if (state->extra != 0) {\n                NEEDBITS(state->extra);\n                state->length += BITS(state->extra);\n                DROPBITS(state->extra);\n            }\n            Tracevv((stderr, \"inflate:         length %u\\n\", state->length));\n\n            /* get distance code */\n            for (;;) {\n                here = state->distcode[BITS(state->distbits)];\n                if ((unsigned)(here.bits) <= bits) break;\n                PULLBYTE();\n            }\n            if ((here.op & 0xf0) == 0) {\n                last = here;\n                for (;;) {\n                    here = state->distcode[last.val +\n                            (BITS(last.bits + last.op) >> last.bits)];\n                    if ((unsigned)(last.bits + here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                DROPBITS(last.bits);\n            }\n            DROPBITS(here.bits);\n            if (here.op & 64) {\n                strm->msg = (char *)\"invalid distance code\";\n                state->mode = BAD;\n                break;\n            }\n            state->offset = (unsigned)here.val;\n\n            /* get distance extra bits, if any */\n            state->extra = (unsigned)(here.op) & 15;\n            if (state->extra != 0) {\n                NEEDBITS(state->extra);\n                state->offset += BITS(state->extra);\n                DROPBITS(state->extra);\n            }\n            if (state->offset > state->wsize - (state->whave < state->wsize ?\n                                                left : 0)) {\n                strm->msg = (char *)\"invalid distance too far back\";\n                state->mode = BAD;\n                break;\n            }\n            Tracevv((stderr, \"inflate:         distance %u\\n\", state->offset));\n\n            /* copy match from window to output */\n            do {\n                ROOM();\n                copy = state->wsize - state->offset;\n                if (copy < left) {\n                    from = put + copy;\n                    copy = left - copy;\n                }\n                else {\n                    from = put - state->offset;\n                    copy = left;\n                }\n                if (copy > state->length) copy = state->length;\n                state->length -= copy;\n                left -= copy;\n                do {\n                    *put++ = *from++;\n                } while (--copy);\n            } while (state->length != 0);\n            break;\n\n        case DONE:\n            /* inflate stream terminated properly -- write leftover output */\n            ret = Z_STREAM_END;\n            if (left < state->wsize) {\n                if (out(out_desc, state->window, state->wsize - left))\n                    ret = Z_BUF_ERROR;\n            }\n            goto inf_leave;\n\n        case BAD:\n            ret = Z_DATA_ERROR;\n            goto inf_leave;\n\n        default:                /* can't happen, but makes compilers happy */\n            ret = Z_STREAM_ERROR;\n            goto inf_leave;\n        }\n\n    /* Return unused input */\n  inf_leave:\n    strm->next_in = next;\n    strm->avail_in = have;\n    return ret;\n}\n\nint ZEXPORT inflateBackEnd(strm)\nz_streamp strm;\n{\n    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)\n        return Z_STREAM_ERROR;\n    ZFREE(strm, strm->state);\n    strm->state = Z_NULL;\n    Tracev((stderr, \"inflate: end\\n\"));\n    return Z_OK;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/inffast.c",
    "content": "/* inffast.c -- fast decoding\n * Copyright (C) 1995-2008, 2010, 2013 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#include \"zutil.h\"\n#include \"inftrees.h\"\n#include \"inflate.h\"\n#include \"inffast.h\"\n\n#ifndef ASMINF\n\n/* Allow machine dependent optimization for post-increment or pre-increment.\n   Based on testing to date,\n   Pre-increment preferred for:\n   - PowerPC G3 (Adler)\n   - MIPS R5000 (Randers-Pehrson)\n   Post-increment preferred for:\n   - none\n   No measurable difference:\n   - Pentium III (Anderson)\n   - M68060 (Nikl)\n */\n#ifdef POSTINC\n#  define OFF 0\n#  define PUP(a) *(a)++\n#else\n#  define OFF 1\n#  define PUP(a) *++(a)\n#endif\n\n/*\n   Decode literal, length, and distance codes and write out the resulting\n   literal and match bytes until either not enough input or output is\n   available, an end-of-block is encountered, or a data error is encountered.\n   When large enough input and output buffers are supplied to inflate(), for\n   example, a 16K input buffer and a 64K output buffer, more than 95% of the\n   inflate execution time is spent in this routine.\n\n   Entry assumptions:\n\n        state->mode == LEN\n        strm->avail_in >= 6\n        strm->avail_out >= 258\n        start >= strm->avail_out\n        state->bits < 8\n\n   On return, state->mode is one of:\n\n        LEN -- ran out of enough output space or enough available input\n        TYPE -- reached end of block code, inflate() to interpret next block\n        BAD -- error in block data\n\n   Notes:\n\n    - The maximum input bits used by a length/distance pair is 15 bits for the\n      length code, 5 bits for the length extra, 15 bits for the distance code,\n      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.\n      Therefore if strm->avail_in >= 6, then there is enough input to avoid\n      checking for available input while decoding.\n\n    - The maximum bytes that a single length/distance pair can output is 258\n      bytes, which is the maximum length that can be coded.  inflate_fast()\n      requires strm->avail_out >= 258 for each loop to avoid checking for\n      output space.\n */\nvoid ZLIB_INTERNAL inflate_fast(strm, start)\nz_streamp strm;\nunsigned start;         /* inflate()'s starting value for strm->avail_out */\n{\n    struct inflate_state FAR *state;\n    z_const unsigned char FAR *in;      /* local strm->next_in */\n    z_const unsigned char FAR *last;    /* have enough input while in < last */\n    unsigned char FAR *out;     /* local strm->next_out */\n    unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */\n    unsigned char FAR *end;     /* while out < end, enough space available */\n#ifdef INFLATE_STRICT\n    unsigned dmax;              /* maximum distance from zlib header */\n#endif\n    unsigned wsize;             /* window size or zero if not using window */\n    unsigned whave;             /* valid bytes in the window */\n    unsigned wnext;             /* window write index */\n    unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */\n    unsigned long hold;         /* local strm->hold */\n    unsigned bits;              /* local strm->bits */\n    code const FAR *lcode;      /* local strm->lencode */\n    code const FAR *dcode;      /* local strm->distcode */\n    unsigned lmask;             /* mask for first level of length codes */\n    unsigned dmask;             /* mask for first level of distance codes */\n    code here;                  /* retrieved table entry */\n    unsigned op;                /* code bits, operation, extra bits, or */\n                                /*  window position, window bytes to copy */\n    unsigned len;               /* match length, unused bytes */\n    unsigned dist;              /* match distance */\n    unsigned char FAR *from;    /* where to copy match from */\n\n    /* copy state to local variables */\n    state = (struct inflate_state FAR *)strm->state;\n    in = strm->next_in - OFF;\n    last = in + (strm->avail_in - 5);\n    out = strm->next_out - OFF;\n    beg = out - (start - strm->avail_out);\n    end = out + (strm->avail_out - 257);\n#ifdef INFLATE_STRICT\n    dmax = state->dmax;\n#endif\n    wsize = state->wsize;\n    whave = state->whave;\n    wnext = state->wnext;\n    window = state->window;\n    hold = state->hold;\n    bits = state->bits;\n    lcode = state->lencode;\n    dcode = state->distcode;\n    lmask = (1U << state->lenbits) - 1;\n    dmask = (1U << state->distbits) - 1;\n\n    /* decode literals and length/distances until end-of-block or not enough\n       input data or output space */\n    do {\n        if (bits < 15) {\n            hold += (unsigned long)(PUP(in)) << bits;\n            bits += 8;\n            hold += (unsigned long)(PUP(in)) << bits;\n            bits += 8;\n        }\n        here = lcode[hold & lmask];\n      dolen:\n        op = (unsigned)(here.bits);\n        hold >>= op;\n        bits -= op;\n        op = (unsigned)(here.op);\n        if (op == 0) {                          /* literal */\n            Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?\n                    \"inflate:         literal '%c'\\n\" :\n                    \"inflate:         literal 0x%02x\\n\", here.val));\n            PUP(out) = (unsigned char)(here.val);\n        }\n        else if (op & 16) {                     /* length base */\n            len = (unsigned)(here.val);\n            op &= 15;                           /* number of extra bits */\n            if (op) {\n                if (bits < op) {\n                    hold += (unsigned long)(PUP(in)) << bits;\n                    bits += 8;\n                }\n                len += (unsigned)hold & ((1U << op) - 1);\n                hold >>= op;\n                bits -= op;\n            }\n            Tracevv((stderr, \"inflate:         length %u\\n\", len));\n            if (bits < 15) {\n                hold += (unsigned long)(PUP(in)) << bits;\n                bits += 8;\n                hold += (unsigned long)(PUP(in)) << bits;\n                bits += 8;\n            }\n            here = dcode[hold & dmask];\n          dodist:\n            op = (unsigned)(here.bits);\n            hold >>= op;\n            bits -= op;\n            op = (unsigned)(here.op);\n            if (op & 16) {                      /* distance base */\n                dist = (unsigned)(here.val);\n                op &= 15;                       /* number of extra bits */\n                if (bits < op) {\n                    hold += (unsigned long)(PUP(in)) << bits;\n                    bits += 8;\n                    if (bits < op) {\n                        hold += (unsigned long)(PUP(in)) << bits;\n                        bits += 8;\n                    }\n                }\n                dist += (unsigned)hold & ((1U << op) - 1);\n#ifdef INFLATE_STRICT\n                if (dist > dmax) {\n                    strm->msg = (char *)\"invalid distance too far back\";\n                    state->mode = BAD;\n                    break;\n                }\n#endif\n                hold >>= op;\n                bits -= op;\n                Tracevv((stderr, \"inflate:         distance %u\\n\", dist));\n                op = (unsigned)(out - beg);     /* max distance in output */\n                if (dist > op) {                /* see if copy from window */\n                    op = dist - op;             /* distance back in window */\n                    if (op > whave) {\n                        if (state->sane) {\n                            strm->msg =\n                                (char *)\"invalid distance too far back\";\n                            state->mode = BAD;\n                            break;\n                        }\n#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR\n                        if (len <= op - whave) {\n                            do {\n                                PUP(out) = 0;\n                            } while (--len);\n                            continue;\n                        }\n                        len -= op - whave;\n                        do {\n                            PUP(out) = 0;\n                        } while (--op > whave);\n                        if (op == 0) {\n                            from = out - dist;\n                            do {\n                                PUP(out) = PUP(from);\n                            } while (--len);\n                            continue;\n                        }\n#endif\n                    }\n                    from = window - OFF;\n                    if (wnext == 0) {           /* very common case */\n                        from += wsize - op;\n                        if (op < len) {         /* some from window */\n                            len -= op;\n                            do {\n                                PUP(out) = PUP(from);\n                            } while (--op);\n                            from = out - dist;  /* rest from output */\n                        }\n                    }\n                    else if (wnext < op) {      /* wrap around window */\n                        from += wsize + wnext - op;\n                        op -= wnext;\n                        if (op < len) {         /* some from end of window */\n                            len -= op;\n                            do {\n                                PUP(out) = PUP(from);\n                            } while (--op);\n                            from = window - OFF;\n                            if (wnext < len) {  /* some from start of window */\n                                op = wnext;\n                                len -= op;\n                                do {\n                                    PUP(out) = PUP(from);\n                                } while (--op);\n                                from = out - dist;      /* rest from output */\n                            }\n                        }\n                    }\n                    else {                      /* contiguous in window */\n                        from += wnext - op;\n                        if (op < len) {         /* some from window */\n                            len -= op;\n                            do {\n                                PUP(out) = PUP(from);\n                            } while (--op);\n                            from = out - dist;  /* rest from output */\n                        }\n                    }\n                    while (len > 2) {\n                        PUP(out) = PUP(from);\n                        PUP(out) = PUP(from);\n                        PUP(out) = PUP(from);\n                        len -= 3;\n                    }\n                    if (len) {\n                        PUP(out) = PUP(from);\n                        if (len > 1)\n                            PUP(out) = PUP(from);\n                    }\n                }\n                else {\n                    from = out - dist;          /* copy direct from output */\n                    do {                        /* minimum length is three */\n                        PUP(out) = PUP(from);\n                        PUP(out) = PUP(from);\n                        PUP(out) = PUP(from);\n                        len -= 3;\n                    } while (len > 2);\n                    if (len) {\n                        PUP(out) = PUP(from);\n                        if (len > 1)\n                            PUP(out) = PUP(from);\n                    }\n                }\n            }\n            else if ((op & 64) == 0) {          /* 2nd level distance code */\n                here = dcode[here.val + (hold & ((1U << op) - 1))];\n                goto dodist;\n            }\n            else {\n                strm->msg = (char *)\"invalid distance code\";\n                state->mode = BAD;\n                break;\n            }\n        }\n        else if ((op & 64) == 0) {              /* 2nd level length code */\n            here = lcode[here.val + (hold & ((1U << op) - 1))];\n            goto dolen;\n        }\n        else if (op & 32) {                     /* end-of-block */\n            Tracevv((stderr, \"inflate:         end of block\\n\"));\n            state->mode = TYPE;\n            break;\n        }\n        else {\n            strm->msg = (char *)\"invalid literal/length code\";\n            state->mode = BAD;\n            break;\n        }\n    } while (in < last && out < end);\n\n    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */\n    len = bits >> 3;\n    in -= len;\n    bits -= len << 3;\n    hold &= (1U << bits) - 1;\n\n    /* update state and return */\n    strm->next_in = in + OFF;\n    strm->next_out = out + OFF;\n    strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));\n    strm->avail_out = (unsigned)(out < end ?\n                                 257 + (end - out) : 257 - (out - end));\n    state->hold = hold;\n    state->bits = bits;\n    return;\n}\n\n/*\n   inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):\n   - Using bit fields for code structure\n   - Different op definition to avoid & for extra bits (do & for table bits)\n   - Three separate decoding do-loops for direct, window, and wnext == 0\n   - Special case for distance > 1 copies to do overlapped load and store copy\n   - Explicit branch predictions (based on measured branch probabilities)\n   - Deferring match copy and interspersed it with decoding subsequent codes\n   - Swapping literal/length else\n   - Swapping window/direct else\n   - Larger unrolled copy loops (three is about right)\n   - Moving len -= 3 statement into middle of loop\n */\n\n#endif /* !ASMINF */\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/inffast.h",
    "content": "/* inffast.h -- header to use inffast.c\n * Copyright (C) 1995-2003, 2010 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* WARNING: this file should *not* be used by applications. It is\n   part of the implementation of the compression library and is\n   subject to change. Applications should only use zlib.h.\n */\n\nvoid ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/inffixed.h",
    "content": "    /* inffixed.h -- table for decoding fixed codes\n     * Generated automatically by makefixed().\n     */\n\n    /* WARNING: this file should *not* be used by applications.\n       It is part of the implementation of this library and is\n       subject to change. Applications should only use zlib.h.\n     */\n\n    static const code lenfix[512] = {\n        {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},\n        {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},\n        {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},\n        {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},\n        {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},\n        {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},\n        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},\n        {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},\n        {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},\n        {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},\n        {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},\n        {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},\n        {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},\n        {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},\n        {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},\n        {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},\n        {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},\n        {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},\n        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},\n        {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},\n        {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},\n        {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},\n        {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},\n        {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},\n        {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},\n        {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},\n        {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},\n        {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},\n        {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},\n        {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},\n        {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},\n        {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},\n        {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},\n        {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},\n        {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},\n        {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},\n        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},\n        {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},\n        {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},\n        {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},\n        {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},\n        {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},\n        {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},\n        {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},\n        {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},\n        {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},\n        {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},\n        {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},\n        {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},\n        {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},\n        {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},\n        {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},\n        {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},\n        {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},\n        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},\n        {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},\n        {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},\n        {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},\n        {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},\n        {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},\n        {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},\n        {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},\n        {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},\n        {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},\n        {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},\n        {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},\n        {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},\n        {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},\n        {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},\n        {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},\n        {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},\n        {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},\n        {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},\n        {0,9,255}\n    };\n\n    static const code distfix[32] = {\n        {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},\n        {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},\n        {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},\n        {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},\n        {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},\n        {22,5,193},{64,5,0}\n    };\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/inflate.c",
    "content": "/* inflate.c -- zlib decompression\n * Copyright (C) 1995-2012 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/*\n * Change history:\n *\n * 1.2.beta0    24 Nov 2002\n * - First version -- complete rewrite of inflate to simplify code, avoid\n *   creation of window when not needed, minimize use of window when it is\n *   needed, make inffast.c even faster, implement gzip decoding, and to\n *   improve code readability and style over the previous zlib inflate code\n *\n * 1.2.beta1    25 Nov 2002\n * - Use pointers for available input and output checking in inffast.c\n * - Remove input and output counters in inffast.c\n * - Change inffast.c entry and loop from avail_in >= 7 to >= 6\n * - Remove unnecessary second byte pull from length extra in inffast.c\n * - Unroll direct copy to three copies per loop in inffast.c\n *\n * 1.2.beta2    4 Dec 2002\n * - Change external routine names to reduce potential conflicts\n * - Correct filename to inffixed.h for fixed tables in inflate.c\n * - Make hbuf[] unsigned char to match parameter type in inflate.c\n * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)\n *   to avoid negation problem on Alphas (64 bit) in inflate.c\n *\n * 1.2.beta3    22 Dec 2002\n * - Add comments on state->bits assertion in inffast.c\n * - Add comments on op field in inftrees.h\n * - Fix bug in reuse of allocated window after inflateReset()\n * - Remove bit fields--back to byte structure for speed\n * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths\n * - Change post-increments to pre-increments in inflate_fast(), PPC biased?\n * - Add compile time option, POSTINC, to use post-increments instead (Intel?)\n * - Make MATCH copy in inflate() much faster for when inflate_fast() not used\n * - Use local copies of stream next and avail values, as well as local bit\n *   buffer and bit count in inflate()--for speed when inflate_fast() not used\n *\n * 1.2.beta4    1 Jan 2003\n * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings\n * - Move a comment on output buffer sizes from inffast.c to inflate.c\n * - Add comments in inffast.c to introduce the inflate_fast() routine\n * - Rearrange window copies in inflate_fast() for speed and simplification\n * - Unroll last copy for window match in inflate_fast()\n * - Use local copies of window variables in inflate_fast() for speed\n * - Pull out common wnext == 0 case for speed in inflate_fast()\n * - Make op and len in inflate_fast() unsigned for consistency\n * - Add FAR to lcode and dcode declarations in inflate_fast()\n * - Simplified bad distance check in inflate_fast()\n * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new\n *   source file infback.c to provide a call-back interface to inflate for\n *   programs like gzip and unzip -- uses window as output buffer to avoid\n *   window copying\n *\n * 1.2.beta5    1 Jan 2003\n * - Improved inflateBack() interface to allow the caller to provide initial\n *   input in strm.\n * - Fixed stored blocks bug in inflateBack()\n *\n * 1.2.beta6    4 Jan 2003\n * - Added comments in inffast.c on effectiveness of POSTINC\n * - Typecasting all around to reduce compiler warnings\n * - Changed loops from while (1) or do {} while (1) to for (;;), again to\n *   make compilers happy\n * - Changed type of window in inflateBackInit() to unsigned char *\n *\n * 1.2.beta7    27 Jan 2003\n * - Changed many types to unsigned or unsigned short to avoid warnings\n * - Added inflateCopy() function\n *\n * 1.2.0        9 Mar 2003\n * - Changed inflateBack() interface to provide separate opaque descriptors\n *   for the in() and out() functions\n * - Changed inflateBack() argument and in_func typedef to swap the length\n *   and buffer address return values for the input function\n * - Check next_in and next_out for Z_NULL on entry to inflate()\n *\n * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.\n */\n\n#include \"zutil.h\"\n#include \"inftrees.h\"\n#include \"inflate.h\"\n#include \"inffast.h\"\n\n#ifdef MAKEFIXED\n#  ifndef BUILDFIXED\n#    define BUILDFIXED\n#  endif\n#endif\n\n/* function prototypes */\nlocal void fixedtables OF((struct inflate_state FAR *state));\nlocal int updatewindow OF((z_streamp strm, const unsigned char FAR *end,\n                           unsigned copy));\n#ifdef BUILDFIXED\n   void makefixed OF((void));\n#endif\nlocal unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,\n                              unsigned len));\n\nint ZEXPORT inflateResetKeep(strm)\nz_streamp strm;\n{\n    struct inflate_state FAR *state;\n\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    strm->total_in = strm->total_out = state->total = 0;\n    strm->msg = Z_NULL;\n    if (state->wrap)        /* to support ill-conceived Java test suite */\n        strm->adler = state->wrap & 1;\n    state->mode = HEAD;\n    state->last = 0;\n    state->havedict = 0;\n    state->dmax = 32768U;\n    state->head = Z_NULL;\n    state->hold = 0;\n    state->bits = 0;\n    state->lencode = state->distcode = state->next = state->codes;\n    state->sane = 1;\n    state->back = -1;\n    Tracev((stderr, \"inflate: reset\\n\"));\n    return Z_OK;\n}\n\nint ZEXPORT inflateReset(strm)\nz_streamp strm;\n{\n    struct inflate_state FAR *state;\n\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    state->wsize = 0;\n    state->whave = 0;\n    state->wnext = 0;\n    return inflateResetKeep(strm);\n}\n\nint ZEXPORT inflateReset2(strm, windowBits)\nz_streamp strm;\nint windowBits;\n{\n    int wrap;\n    struct inflate_state FAR *state;\n\n    /* get the state */\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n\n    /* extract wrap request from windowBits parameter */\n    if (windowBits < 0) {\n        wrap = 0;\n        windowBits = -windowBits;\n    }\n    else {\n        wrap = (windowBits >> 4) + 1;\n#ifdef GUNZIP\n        if (windowBits < 48)\n            windowBits &= 15;\n#endif\n    }\n\n    /* set number of window bits, free window if different */\n    if (windowBits && (windowBits < 8 || windowBits > 15))\n        return Z_STREAM_ERROR;\n    if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {\n        ZFREE(strm, state->window);\n        state->window = Z_NULL;\n    }\n\n    /* update state and reset the rest of it */\n    state->wrap = wrap;\n    state->wbits = (unsigned)windowBits;\n    return inflateReset(strm);\n}\n\nint ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)\nz_streamp strm;\nint windowBits;\nconst char *version;\nint stream_size;\n{\n    int ret;\n    struct inflate_state FAR *state;\n\n    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||\n        stream_size != (int)(sizeof(z_stream)))\n        return Z_VERSION_ERROR;\n    if (strm == Z_NULL) return Z_STREAM_ERROR;\n    strm->msg = Z_NULL;                 /* in case we return an error */\n    if (strm->zalloc == (alloc_func)0) {\n#ifdef Z_SOLO\n        return Z_STREAM_ERROR;\n#else\n        strm->zalloc = zcalloc;\n        strm->opaque = (voidpf)0;\n#endif\n    }\n    if (strm->zfree == (free_func)0)\n#ifdef Z_SOLO\n        return Z_STREAM_ERROR;\n#else\n        strm->zfree = zcfree;\n#endif\n    state = (struct inflate_state FAR *)\n            ZALLOC(strm, 1, sizeof(struct inflate_state));\n    if (state == Z_NULL) return Z_MEM_ERROR;\n    Tracev((stderr, \"inflate: allocated\\n\"));\n    strm->state = (struct internal_state FAR *)state;\n    state->window = Z_NULL;\n    ret = inflateReset2(strm, windowBits);\n    if (ret != Z_OK) {\n        ZFREE(strm, state);\n        strm->state = Z_NULL;\n    }\n    return ret;\n}\n\nint ZEXPORT inflateInit_(strm, version, stream_size)\nz_streamp strm;\nconst char *version;\nint stream_size;\n{\n    return inflateInit2_(strm, DEF_WBITS, version, stream_size);\n}\n\nint ZEXPORT inflatePrime(strm, bits, value)\nz_streamp strm;\nint bits;\nint value;\n{\n    struct inflate_state FAR *state;\n\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    if (bits < 0) {\n        state->hold = 0;\n        state->bits = 0;\n        return Z_OK;\n    }\n    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;\n    value &= (1L << bits) - 1;\n    state->hold += value << state->bits;\n    state->bits += bits;\n    return Z_OK;\n}\n\n/*\n   Return state with length and distance decoding tables and index sizes set to\n   fixed code decoding.  Normally this returns fixed tables from inffixed.h.\n   If BUILDFIXED is defined, then instead this routine builds the tables the\n   first time it's called, and returns those tables the first time and\n   thereafter.  This reduces the size of the code by about 2K bytes, in\n   exchange for a little execution time.  However, BUILDFIXED should not be\n   used for threaded applications, since the rewriting of the tables and virgin\n   may not be thread-safe.\n */\nlocal void fixedtables(state)\nstruct inflate_state FAR *state;\n{\n#ifdef BUILDFIXED\n    static int virgin = 1;\n    static code *lenfix, *distfix;\n    static code fixed[544];\n\n    /* build fixed huffman tables if first call (may not be thread safe) */\n    if (virgin) {\n        unsigned sym, bits;\n        static code *next;\n\n        /* literal/length table */\n        sym = 0;\n        while (sym < 144) state->lens[sym++] = 8;\n        while (sym < 256) state->lens[sym++] = 9;\n        while (sym < 280) state->lens[sym++] = 7;\n        while (sym < 288) state->lens[sym++] = 8;\n        next = fixed;\n        lenfix = next;\n        bits = 9;\n        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);\n\n        /* distance table */\n        sym = 0;\n        while (sym < 32) state->lens[sym++] = 5;\n        distfix = next;\n        bits = 5;\n        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);\n\n        /* do this just once */\n        virgin = 0;\n    }\n#else /* !BUILDFIXED */\n#   include \"inffixed.h\"\n#endif /* BUILDFIXED */\n    state->lencode = lenfix;\n    state->lenbits = 9;\n    state->distcode = distfix;\n    state->distbits = 5;\n}\n\n#ifdef MAKEFIXED\n#include <stdio.h>\n\n/*\n   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also\n   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes\n   those tables to stdout, which would be piped to inffixed.h.  A small program\n   can simply call makefixed to do this:\n\n    void makefixed(void);\n\n    int main(void)\n    {\n        makefixed();\n        return 0;\n    }\n\n   Then that can be linked with zlib built with MAKEFIXED defined and run:\n\n    a.out > inffixed.h\n */\nvoid makefixed()\n{\n    unsigned low, size;\n    struct inflate_state state;\n\n    fixedtables(&state);\n    puts(\"    /* inffixed.h -- table for decoding fixed codes\");\n    puts(\"     * Generated automatically by makefixed().\");\n    puts(\"     */\");\n    puts(\"\");\n    puts(\"    /* WARNING: this file should *not* be used by applications.\");\n    puts(\"       It is part of the implementation of this library and is\");\n    puts(\"       subject to change. Applications should only use zlib.h.\");\n    puts(\"     */\");\n    puts(\"\");\n    size = 1U << 9;\n    printf(\"    static const code lenfix[%u] = {\", size);\n    low = 0;\n    for (;;) {\n        if ((low % 7) == 0) printf(\"\\n        \");\n        printf(\"{%u,%u,%d}\", (low & 127) == 99 ? 64 : state.lencode[low].op,\n               state.lencode[low].bits, state.lencode[low].val);\n        if (++low == size) break;\n        putchar(',');\n    }\n    puts(\"\\n    };\");\n    size = 1U << 5;\n    printf(\"\\n    static const code distfix[%u] = {\", size);\n    low = 0;\n    for (;;) {\n        if ((low % 6) == 0) printf(\"\\n        \");\n        printf(\"{%u,%u,%d}\", state.distcode[low].op, state.distcode[low].bits,\n               state.distcode[low].val);\n        if (++low == size) break;\n        putchar(',');\n    }\n    puts(\"\\n    };\");\n}\n#endif /* MAKEFIXED */\n\n/*\n   Update the window with the last wsize (normally 32K) bytes written before\n   returning.  If window does not exist yet, create it.  This is only called\n   when a window is already in use, or when output has been written during this\n   inflate call, but the end of the deflate stream has not been reached yet.\n   It is also called to create a window for dictionary data when a dictionary\n   is loaded.\n\n   Providing output buffers larger than 32K to inflate() should provide a speed\n   advantage, since only the last 32K of output is copied to the sliding window\n   upon return from inflate(), and since all distances after the first 32K of\n   output will fall in the output data, making match copies simpler and faster.\n   The advantage may be dependent on the size of the processor's data caches.\n */\nlocal int updatewindow(strm, end, copy)\nz_streamp strm;\nconst Bytef *end;\nunsigned copy;\n{\n    struct inflate_state FAR *state;\n    unsigned dist;\n\n    state = (struct inflate_state FAR *)strm->state;\n\n    /* if it hasn't been done already, allocate space for the window */\n    if (state->window == Z_NULL) {\n        state->window = (unsigned char FAR *)\n                        ZALLOC(strm, 1U << state->wbits,\n                               sizeof(unsigned char));\n        if (state->window == Z_NULL) return 1;\n    }\n\n    /* if window not in use yet, initialize */\n    if (state->wsize == 0) {\n        state->wsize = 1U << state->wbits;\n        state->wnext = 0;\n        state->whave = 0;\n    }\n\n    /* copy state->wsize or less output bytes into the circular window */\n    if (copy >= state->wsize) {\n        zmemcpy(state->window, end - state->wsize, state->wsize);\n        state->wnext = 0;\n        state->whave = state->wsize;\n    }\n    else {\n        dist = state->wsize - state->wnext;\n        if (dist > copy) dist = copy;\n        zmemcpy(state->window + state->wnext, end - copy, dist);\n        copy -= dist;\n        if (copy) {\n            zmemcpy(state->window, end - copy, copy);\n            state->wnext = copy;\n            state->whave = state->wsize;\n        }\n        else {\n            state->wnext += dist;\n            if (state->wnext == state->wsize) state->wnext = 0;\n            if (state->whave < state->wsize) state->whave += dist;\n        }\n    }\n    return 0;\n}\n\n/* Macros for inflate(): */\n\n/* check function to use adler32() for zlib or crc32() for gzip */\n#ifdef GUNZIP\n#  define UPDATE(check, buf, len) \\\n    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))\n#else\n#  define UPDATE(check, buf, len) adler32(check, buf, len)\n#endif\n\n/* check macros for header crc */\n#ifdef GUNZIP\n#  define CRC2(check, word) \\\n    do { \\\n        hbuf[0] = (unsigned char)(word); \\\n        hbuf[1] = (unsigned char)((word) >> 8); \\\n        check = crc32(check, hbuf, 2); \\\n    } while (0)\n\n#  define CRC4(check, word) \\\n    do { \\\n        hbuf[0] = (unsigned char)(word); \\\n        hbuf[1] = (unsigned char)((word) >> 8); \\\n        hbuf[2] = (unsigned char)((word) >> 16); \\\n        hbuf[3] = (unsigned char)((word) >> 24); \\\n        check = crc32(check, hbuf, 4); \\\n    } while (0)\n#endif\n\n/* Load registers with state in inflate() for speed */\n#define LOAD() \\\n    do { \\\n        put = strm->next_out; \\\n        left = strm->avail_out; \\\n        next = strm->next_in; \\\n        have = strm->avail_in; \\\n        hold = state->hold; \\\n        bits = state->bits; \\\n    } while (0)\n\n/* Restore state from registers in inflate() */\n#define RESTORE() \\\n    do { \\\n        strm->next_out = put; \\\n        strm->avail_out = left; \\\n        strm->next_in = next; \\\n        strm->avail_in = have; \\\n        state->hold = hold; \\\n        state->bits = bits; \\\n    } while (0)\n\n/* Clear the input bit accumulator */\n#define INITBITS() \\\n    do { \\\n        hold = 0; \\\n        bits = 0; \\\n    } while (0)\n\n/* Get a byte of input into the bit accumulator, or return from inflate()\n   if there is no input available. */\n#define PULLBYTE() \\\n    do { \\\n        if (have == 0) goto inf_leave; \\\n        have--; \\\n        hold += (unsigned long)(*next++) << bits; \\\n        bits += 8; \\\n    } while (0)\n\n/* Assure that there are at least n bits in the bit accumulator.  If there is\n   not enough available input to do that, then return from inflate(). */\n#define NEEDBITS(n) \\\n    do { \\\n        while (bits < (unsigned)(n)) \\\n            PULLBYTE(); \\\n    } while (0)\n\n/* Return the low n bits of the bit accumulator (n < 16) */\n#define BITS(n) \\\n    ((unsigned)hold & ((1U << (n)) - 1))\n\n/* Remove n bits from the bit accumulator */\n#define DROPBITS(n) \\\n    do { \\\n        hold >>= (n); \\\n        bits -= (unsigned)(n); \\\n    } while (0)\n\n/* Remove zero to seven bits as needed to go to a byte boundary */\n#define BYTEBITS() \\\n    do { \\\n        hold >>= bits & 7; \\\n        bits -= bits & 7; \\\n    } while (0)\n\n/*\n   inflate() uses a state machine to process as much input data and generate as\n   much output data as possible before returning.  The state machine is\n   structured roughly as follows:\n\n    for (;;) switch (state) {\n    ...\n    case STATEn:\n        if (not enough input data or output space to make progress)\n            return;\n        ... make progress ...\n        state = STATEm;\n        break;\n    ...\n    }\n\n   so when inflate() is called again, the same case is attempted again, and\n   if the appropriate resources are provided, the machine proceeds to the\n   next state.  The NEEDBITS() macro is usually the way the state evaluates\n   whether it can proceed or should return.  NEEDBITS() does the return if\n   the requested bits are not available.  The typical use of the BITS macros\n   is:\n\n        NEEDBITS(n);\n        ... do something with BITS(n) ...\n        DROPBITS(n);\n\n   where NEEDBITS(n) either returns from inflate() if there isn't enough\n   input left to load n bits into the accumulator, or it continues.  BITS(n)\n   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops\n   the low n bits off the accumulator.  INITBITS() clears the accumulator\n   and sets the number of available bits to zero.  BYTEBITS() discards just\n   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()\n   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.\n\n   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return\n   if there is no input available.  The decoding of variable length codes uses\n   PULLBYTE() directly in order to pull just enough bytes to decode the next\n   code, and no more.\n\n   Some states loop until they get enough input, making sure that enough\n   state information is maintained to continue the loop where it left off\n   if NEEDBITS() returns in the loop.  For example, want, need, and keep\n   would all have to actually be part of the saved state in case NEEDBITS()\n   returns:\n\n    case STATEw:\n        while (want < need) {\n            NEEDBITS(n);\n            keep[want++] = BITS(n);\n            DROPBITS(n);\n        }\n        state = STATEx;\n    case STATEx:\n\n   As shown above, if the next state is also the next case, then the break\n   is omitted.\n\n   A state may also return if there is not enough output space available to\n   complete that state.  Those states are copying stored data, writing a\n   literal byte, and copying a matching string.\n\n   When returning, a \"goto inf_leave\" is used to update the total counters,\n   update the check value, and determine whether any progress has been made\n   during that inflate() call in order to return the proper return code.\n   Progress is defined as a change in either strm->avail_in or strm->avail_out.\n   When there is a window, goto inf_leave will update the window with the last\n   output written.  If a goto inf_leave occurs in the middle of decompression\n   and there is no window currently, goto inf_leave will create one and copy\n   output to the window for the next call of inflate().\n\n   In this implementation, the flush parameter of inflate() only affects the\n   return code (per zlib.h).  inflate() always writes as much as possible to\n   strm->next_out, given the space available and the provided input--the effect\n   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers\n   the allocation of and copying into a sliding window until necessary, which\n   provides the effect documented in zlib.h for Z_FINISH when the entire input\n   stream available.  So the only thing the flush parameter actually does is:\n   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it\n   will return Z_BUF_ERROR if it has not reached the end of the stream.\n */\n\nint ZEXPORT inflate(strm, flush)\nz_streamp strm;\nint flush;\n{\n    struct inflate_state FAR *state;\n    z_const unsigned char FAR *next;    /* next input */\n    unsigned char FAR *put;     /* next output */\n    unsigned have, left;        /* available input and output */\n    unsigned long hold;         /* bit buffer */\n    unsigned bits;              /* bits in bit buffer */\n    unsigned in, out;           /* save starting available input and output */\n    unsigned copy;              /* number of stored or match bytes to copy */\n    unsigned char FAR *from;    /* where to copy match bytes from */\n    code here;                  /* current decoding table entry */\n    code last;                  /* parent table entry */\n    unsigned len;               /* length to copy for repeats, bits to drop */\n    int ret;                    /* return code */\n#ifdef GUNZIP\n    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */\n#endif\n    static const unsigned short order[19] = /* permutation of code lengths */\n        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};\n\n    if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||\n        (strm->next_in == Z_NULL && strm->avail_in != 0))\n        return Z_STREAM_ERROR;\n\n    state = (struct inflate_state FAR *)strm->state;\n    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */\n    LOAD();\n    in = have;\n    out = left;\n    ret = Z_OK;\n    for (;;)\n        switch (state->mode) {\n        case HEAD:\n            if (state->wrap == 0) {\n                state->mode = TYPEDO;\n                break;\n            }\n            NEEDBITS(16);\n#ifdef GUNZIP\n            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */\n                state->check = crc32(0L, Z_NULL, 0);\n                CRC2(state->check, hold);\n                INITBITS();\n                state->mode = FLAGS;\n                break;\n            }\n            state->flags = 0;           /* expect zlib header */\n            if (state->head != Z_NULL)\n                state->head->done = -1;\n            if (!(state->wrap & 1) ||   /* check if zlib header allowed */\n#else\n            if (\n#endif\n                ((BITS(8) << 8) + (hold >> 8)) % 31) {\n                strm->msg = (char *)\"incorrect header check\";\n                state->mode = BAD;\n                break;\n            }\n            if (BITS(4) != Z_DEFLATED) {\n                strm->msg = (char *)\"unknown compression method\";\n                state->mode = BAD;\n                break;\n            }\n            DROPBITS(4);\n            len = BITS(4) + 8;\n            if (state->wbits == 0)\n                state->wbits = len;\n            else if (len > state->wbits) {\n                strm->msg = (char *)\"invalid window size\";\n                state->mode = BAD;\n                break;\n            }\n            state->dmax = 1U << len;\n            Tracev((stderr, \"inflate:   zlib header ok\\n\"));\n            strm->adler = state->check = adler32(0L, Z_NULL, 0);\n            state->mode = hold & 0x200 ? DICTID : TYPE;\n            INITBITS();\n            break;\n#ifdef GUNZIP\n        case FLAGS:\n            NEEDBITS(16);\n            state->flags = (int)(hold);\n            if ((state->flags & 0xff) != Z_DEFLATED) {\n                strm->msg = (char *)\"unknown compression method\";\n                state->mode = BAD;\n                break;\n            }\n            if (state->flags & 0xe000) {\n                strm->msg = (char *)\"unknown header flags set\";\n                state->mode = BAD;\n                break;\n            }\n            if (state->head != Z_NULL)\n                state->head->text = (int)((hold >> 8) & 1);\n            if (state->flags & 0x0200) CRC2(state->check, hold);\n            INITBITS();\n            state->mode = TIME;\n        case TIME:\n            NEEDBITS(32);\n            if (state->head != Z_NULL)\n                state->head->time = hold;\n            if (state->flags & 0x0200) CRC4(state->check, hold);\n            INITBITS();\n            state->mode = OS;\n        case OS:\n            NEEDBITS(16);\n            if (state->head != Z_NULL) {\n                state->head->xflags = (int)(hold & 0xff);\n                state->head->os = (int)(hold >> 8);\n            }\n            if (state->flags & 0x0200) CRC2(state->check, hold);\n            INITBITS();\n            state->mode = EXLEN;\n        case EXLEN:\n            if (state->flags & 0x0400) {\n                NEEDBITS(16);\n                state->length = (unsigned)(hold);\n                if (state->head != Z_NULL)\n                    state->head->extra_len = (unsigned)hold;\n                if (state->flags & 0x0200) CRC2(state->check, hold);\n                INITBITS();\n            }\n            else if (state->head != Z_NULL)\n                state->head->extra = Z_NULL;\n            state->mode = EXTRA;\n        case EXTRA:\n            if (state->flags & 0x0400) {\n                copy = state->length;\n                if (copy > have) copy = have;\n                if (copy) {\n                    if (state->head != Z_NULL &&\n                        state->head->extra != Z_NULL) {\n                        len = state->head->extra_len - state->length;\n                        zmemcpy(state->head->extra + len, next,\n                                len + copy > state->head->extra_max ?\n                                state->head->extra_max - len : copy);\n                    }\n                    if (state->flags & 0x0200)\n                        state->check = crc32(state->check, next, copy);\n                    have -= copy;\n                    next += copy;\n                    state->length -= copy;\n                }\n                if (state->length) goto inf_leave;\n            }\n            state->length = 0;\n            state->mode = NAME;\n        case NAME:\n            if (state->flags & 0x0800) {\n                if (have == 0) goto inf_leave;\n                copy = 0;\n                do {\n                    len = (unsigned)(next[copy++]);\n                    if (state->head != Z_NULL &&\n                            state->head->name != Z_NULL &&\n                            state->length < state->head->name_max)\n                        state->head->name[state->length++] = len;\n                } while (len && copy < have);\n                if (state->flags & 0x0200)\n                    state->check = crc32(state->check, next, copy);\n                have -= copy;\n                next += copy;\n                if (len) goto inf_leave;\n            }\n            else if (state->head != Z_NULL)\n                state->head->name = Z_NULL;\n            state->length = 0;\n            state->mode = COMMENT;\n        case COMMENT:\n            if (state->flags & 0x1000) {\n                if (have == 0) goto inf_leave;\n                copy = 0;\n                do {\n                    len = (unsigned)(next[copy++]);\n                    if (state->head != Z_NULL &&\n                            state->head->comment != Z_NULL &&\n                            state->length < state->head->comm_max)\n                        state->head->comment[state->length++] = len;\n                } while (len && copy < have);\n                if (state->flags & 0x0200)\n                    state->check = crc32(state->check, next, copy);\n                have -= copy;\n                next += copy;\n                if (len) goto inf_leave;\n            }\n            else if (state->head != Z_NULL)\n                state->head->comment = Z_NULL;\n            state->mode = HCRC;\n        case HCRC:\n            if (state->flags & 0x0200) {\n                NEEDBITS(16);\n                if (hold != (state->check & 0xffff)) {\n                    strm->msg = (char *)\"header crc mismatch\";\n                    state->mode = BAD;\n                    break;\n                }\n                INITBITS();\n            }\n            if (state->head != Z_NULL) {\n                state->head->hcrc = (int)((state->flags >> 9) & 1);\n                state->head->done = 1;\n            }\n            strm->adler = state->check = crc32(0L, Z_NULL, 0);\n            state->mode = TYPE;\n            break;\n#endif\n        case DICTID:\n            NEEDBITS(32);\n            strm->adler = state->check = ZSWAP32(hold);\n            INITBITS();\n            state->mode = DICT;\n        case DICT:\n            if (state->havedict == 0) {\n                RESTORE();\n                return Z_NEED_DICT;\n            }\n            strm->adler = state->check = adler32(0L, Z_NULL, 0);\n            state->mode = TYPE;\n        case TYPE:\n            if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;\n        case TYPEDO:\n            if (state->last) {\n                BYTEBITS();\n                state->mode = CHECK;\n                break;\n            }\n            NEEDBITS(3);\n            state->last = BITS(1);\n            DROPBITS(1);\n            switch (BITS(2)) {\n            case 0:                             /* stored block */\n                Tracev((stderr, \"inflate:     stored block%s\\n\",\n                        state->last ? \" (last)\" : \"\"));\n                state->mode = STORED;\n                break;\n            case 1:                             /* fixed block */\n                fixedtables(state);\n                Tracev((stderr, \"inflate:     fixed codes block%s\\n\",\n                        state->last ? \" (last)\" : \"\"));\n                state->mode = LEN_;             /* decode codes */\n                if (flush == Z_TREES) {\n                    DROPBITS(2);\n                    goto inf_leave;\n                }\n                break;\n            case 2:                             /* dynamic block */\n                Tracev((stderr, \"inflate:     dynamic codes block%s\\n\",\n                        state->last ? \" (last)\" : \"\"));\n                state->mode = TABLE;\n                break;\n            case 3:\n                strm->msg = (char *)\"invalid block type\";\n                state->mode = BAD;\n            }\n            DROPBITS(2);\n            break;\n        case STORED:\n            BYTEBITS();                         /* go to byte boundary */\n            NEEDBITS(32);\n            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {\n                strm->msg = (char *)\"invalid stored block lengths\";\n                state->mode = BAD;\n                break;\n            }\n            state->length = (unsigned)hold & 0xffff;\n            Tracev((stderr, \"inflate:       stored length %u\\n\",\n                    state->length));\n            INITBITS();\n            state->mode = COPY_;\n            if (flush == Z_TREES) goto inf_leave;\n        case COPY_:\n            state->mode = COPY;\n        case COPY:\n            copy = state->length;\n            if (copy) {\n                if (copy > have) copy = have;\n                if (copy > left) copy = left;\n                if (copy == 0) goto inf_leave;\n                zmemcpy(put, next, copy);\n                have -= copy;\n                next += copy;\n                left -= copy;\n                put += copy;\n                state->length -= copy;\n                break;\n            }\n            Tracev((stderr, \"inflate:       stored end\\n\"));\n            state->mode = TYPE;\n            break;\n        case TABLE:\n            NEEDBITS(14);\n            state->nlen = BITS(5) + 257;\n            DROPBITS(5);\n            state->ndist = BITS(5) + 1;\n            DROPBITS(5);\n            state->ncode = BITS(4) + 4;\n            DROPBITS(4);\n#ifndef PKZIP_BUG_WORKAROUND\n            if (state->nlen > 286 || state->ndist > 30) {\n                strm->msg = (char *)\"too many length or distance symbols\";\n                state->mode = BAD;\n                break;\n            }\n#endif\n            Tracev((stderr, \"inflate:       table sizes ok\\n\"));\n            state->have = 0;\n            state->mode = LENLENS;\n        case LENLENS:\n            while (state->have < state->ncode) {\n                NEEDBITS(3);\n                state->lens[order[state->have++]] = (unsigned short)BITS(3);\n                DROPBITS(3);\n            }\n            while (state->have < 19)\n                state->lens[order[state->have++]] = 0;\n            state->next = state->codes;\n            state->lencode = (const code FAR *)(state->next);\n            state->lenbits = 7;\n            ret = inflate_table(CODES, state->lens, 19, &(state->next),\n                                &(state->lenbits), state->work);\n            if (ret) {\n                strm->msg = (char *)\"invalid code lengths set\";\n                state->mode = BAD;\n                break;\n            }\n            Tracev((stderr, \"inflate:       code lengths ok\\n\"));\n            state->have = 0;\n            state->mode = CODELENS;\n        case CODELENS:\n            while (state->have < state->nlen + state->ndist) {\n                for (;;) {\n                    here = state->lencode[BITS(state->lenbits)];\n                    if ((unsigned)(here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                if (here.val < 16) {\n                    DROPBITS(here.bits);\n                    state->lens[state->have++] = here.val;\n                }\n                else {\n                    if (here.val == 16) {\n                        NEEDBITS(here.bits + 2);\n                        DROPBITS(here.bits);\n                        if (state->have == 0) {\n                            strm->msg = (char *)\"invalid bit length repeat\";\n                            state->mode = BAD;\n                            break;\n                        }\n                        len = state->lens[state->have - 1];\n                        copy = 3 + BITS(2);\n                        DROPBITS(2);\n                    }\n                    else if (here.val == 17) {\n                        NEEDBITS(here.bits + 3);\n                        DROPBITS(here.bits);\n                        len = 0;\n                        copy = 3 + BITS(3);\n                        DROPBITS(3);\n                    }\n                    else {\n                        NEEDBITS(here.bits + 7);\n                        DROPBITS(here.bits);\n                        len = 0;\n                        copy = 11 + BITS(7);\n                        DROPBITS(7);\n                    }\n                    if (state->have + copy > state->nlen + state->ndist) {\n                        strm->msg = (char *)\"invalid bit length repeat\";\n                        state->mode = BAD;\n                        break;\n                    }\n                    while (copy--)\n                        state->lens[state->have++] = (unsigned short)len;\n                }\n            }\n\n            /* handle error breaks in while */\n            if (state->mode == BAD) break;\n\n            /* check for end-of-block code (better have one) */\n            if (state->lens[256] == 0) {\n                strm->msg = (char *)\"invalid code -- missing end-of-block\";\n                state->mode = BAD;\n                break;\n            }\n\n            /* build code tables -- note: do not change the lenbits or distbits\n               values here (9 and 6) without reading the comments in inftrees.h\n               concerning the ENOUGH constants, which depend on those values */\n            state->next = state->codes;\n            state->lencode = (const code FAR *)(state->next);\n            state->lenbits = 9;\n            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),\n                                &(state->lenbits), state->work);\n            if (ret) {\n                strm->msg = (char *)\"invalid literal/lengths set\";\n                state->mode = BAD;\n                break;\n            }\n            state->distcode = (const code FAR *)(state->next);\n            state->distbits = 6;\n            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,\n                            &(state->next), &(state->distbits), state->work);\n            if (ret) {\n                strm->msg = (char *)\"invalid distances set\";\n                state->mode = BAD;\n                break;\n            }\n            Tracev((stderr, \"inflate:       codes ok\\n\"));\n            state->mode = LEN_;\n            if (flush == Z_TREES) goto inf_leave;\n        case LEN_:\n            state->mode = LEN;\n        case LEN:\n            if (have >= 6 && left >= 258) {\n                RESTORE();\n                inflate_fast(strm, out);\n                LOAD();\n                if (state->mode == TYPE)\n                    state->back = -1;\n                break;\n            }\n            state->back = 0;\n            for (;;) {\n                here = state->lencode[BITS(state->lenbits)];\n                if ((unsigned)(here.bits) <= bits) break;\n                PULLBYTE();\n            }\n            if (here.op && (here.op & 0xf0) == 0) {\n                last = here;\n                for (;;) {\n                    here = state->lencode[last.val +\n                            (BITS(last.bits + last.op) >> last.bits)];\n                    if ((unsigned)(last.bits + here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                DROPBITS(last.bits);\n                state->back += last.bits;\n            }\n            DROPBITS(here.bits);\n            state->back += here.bits;\n            state->length = (unsigned)here.val;\n            if ((int)(here.op) == 0) {\n                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?\n                        \"inflate:         literal '%c'\\n\" :\n                        \"inflate:         literal 0x%02x\\n\", here.val));\n                state->mode = LIT;\n                break;\n            }\n            if (here.op & 32) {\n                Tracevv((stderr, \"inflate:         end of block\\n\"));\n                state->back = -1;\n                state->mode = TYPE;\n                break;\n            }\n            if (here.op & 64) {\n                strm->msg = (char *)\"invalid literal/length code\";\n                state->mode = BAD;\n                break;\n            }\n            state->extra = (unsigned)(here.op) & 15;\n            state->mode = LENEXT;\n        case LENEXT:\n            if (state->extra) {\n                NEEDBITS(state->extra);\n                state->length += BITS(state->extra);\n                DROPBITS(state->extra);\n                state->back += state->extra;\n            }\n            Tracevv((stderr, \"inflate:         length %u\\n\", state->length));\n            state->was = state->length;\n            state->mode = DIST;\n        case DIST:\n            for (;;) {\n                here = state->distcode[BITS(state->distbits)];\n                if ((unsigned)(here.bits) <= bits) break;\n                PULLBYTE();\n            }\n            if ((here.op & 0xf0) == 0) {\n                last = here;\n                for (;;) {\n                    here = state->distcode[last.val +\n                            (BITS(last.bits + last.op) >> last.bits)];\n                    if ((unsigned)(last.bits + here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                DROPBITS(last.bits);\n                state->back += last.bits;\n            }\n            DROPBITS(here.bits);\n            state->back += here.bits;\n            if (here.op & 64) {\n                strm->msg = (char *)\"invalid distance code\";\n                state->mode = BAD;\n                break;\n            }\n            state->offset = (unsigned)here.val;\n            state->extra = (unsigned)(here.op) & 15;\n            state->mode = DISTEXT;\n        case DISTEXT:\n            if (state->extra) {\n                NEEDBITS(state->extra);\n                state->offset += BITS(state->extra);\n                DROPBITS(state->extra);\n                state->back += state->extra;\n            }\n#ifdef INFLATE_STRICT\n            if (state->offset > state->dmax) {\n                strm->msg = (char *)\"invalid distance too far back\";\n                state->mode = BAD;\n                break;\n            }\n#endif\n            Tracevv((stderr, \"inflate:         distance %u\\n\", state->offset));\n            state->mode = MATCH;\n        case MATCH:\n            if (left == 0) goto inf_leave;\n            copy = out - left;\n            if (state->offset > copy) {         /* copy from window */\n                copy = state->offset - copy;\n                if (copy > state->whave) {\n                    if (state->sane) {\n                        strm->msg = (char *)\"invalid distance too far back\";\n                        state->mode = BAD;\n                        break;\n                    }\n#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR\n                    Trace((stderr, \"inflate.c too far\\n\"));\n                    copy -= state->whave;\n                    if (copy > state->length) copy = state->length;\n                    if (copy > left) copy = left;\n                    left -= copy;\n                    state->length -= copy;\n                    do {\n                        *put++ = 0;\n                    } while (--copy);\n                    if (state->length == 0) state->mode = LEN;\n                    break;\n#endif\n                }\n                if (copy > state->wnext) {\n                    copy -= state->wnext;\n                    from = state->window + (state->wsize - copy);\n                }\n                else\n                    from = state->window + (state->wnext - copy);\n                if (copy > state->length) copy = state->length;\n            }\n            else {                              /* copy from output */\n                from = put - state->offset;\n                copy = state->length;\n            }\n            if (copy > left) copy = left;\n            left -= copy;\n            state->length -= copy;\n            do {\n                *put++ = *from++;\n            } while (--copy);\n            if (state->length == 0) state->mode = LEN;\n            break;\n        case LIT:\n            if (left == 0) goto inf_leave;\n            *put++ = (unsigned char)(state->length);\n            left--;\n            state->mode = LEN;\n            break;\n        case CHECK:\n            if (state->wrap) {\n                NEEDBITS(32);\n                out -= left;\n                strm->total_out += out;\n                state->total += out;\n                if (out)\n                    strm->adler = state->check =\n                        UPDATE(state->check, put - out, out);\n                out = left;\n                if ((\n#ifdef GUNZIP\n                     state->flags ? hold :\n#endif\n                     ZSWAP32(hold)) != state->check) {\n                    strm->msg = (char *)\"incorrect data check\";\n                    state->mode = BAD;\n                    break;\n                }\n                INITBITS();\n                Tracev((stderr, \"inflate:   check matches trailer\\n\"));\n            }\n#ifdef GUNZIP\n            state->mode = LENGTH;\n        case LENGTH:\n            if (state->wrap && state->flags) {\n                NEEDBITS(32);\n                if (hold != (state->total & 0xffffffffUL)) {\n                    strm->msg = (char *)\"incorrect length check\";\n                    state->mode = BAD;\n                    break;\n                }\n                INITBITS();\n                Tracev((stderr, \"inflate:   length matches trailer\\n\"));\n            }\n#endif\n            state->mode = DONE;\n        case DONE:\n            ret = Z_STREAM_END;\n            goto inf_leave;\n        case BAD:\n            ret = Z_DATA_ERROR;\n            goto inf_leave;\n        case MEM:\n            return Z_MEM_ERROR;\n        case SYNC:\n        default:\n            return Z_STREAM_ERROR;\n        }\n\n    /*\n       Return from inflate(), updating the total counts and the check value.\n       If there was no progress during the inflate() call, return a buffer\n       error.  Call updatewindow() to create and/or update the window state.\n       Note: a memory error from inflate() is non-recoverable.\n     */\n  inf_leave:\n    RESTORE();\n    if (state->wsize || (out != strm->avail_out && state->mode < BAD &&\n            (state->mode < CHECK || flush != Z_FINISH)))\n        if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {\n            state->mode = MEM;\n            return Z_MEM_ERROR;\n        }\n    in -= strm->avail_in;\n    out -= strm->avail_out;\n    strm->total_in += in;\n    strm->total_out += out;\n    state->total += out;\n    if (state->wrap && out)\n        strm->adler = state->check =\n            UPDATE(state->check, strm->next_out - out, out);\n    strm->data_type = state->bits + (state->last ? 64 : 0) +\n                      (state->mode == TYPE ? 128 : 0) +\n                      (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);\n    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)\n        ret = Z_BUF_ERROR;\n    return ret;\n}\n\nint ZEXPORT inflateEnd(strm)\nz_streamp strm;\n{\n    struct inflate_state FAR *state;\n    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)\n        return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    if (state->window != Z_NULL) ZFREE(strm, state->window);\n    ZFREE(strm, strm->state);\n    strm->state = Z_NULL;\n    Tracev((stderr, \"inflate: end\\n\"));\n    return Z_OK;\n}\n\nint ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)\nz_streamp strm;\nBytef *dictionary;\nuInt *dictLength;\n{\n    struct inflate_state FAR *state;\n\n    /* check state */\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n\n    /* copy dictionary */\n    if (state->whave && dictionary != Z_NULL) {\n        zmemcpy(dictionary, state->window + state->wnext,\n                state->whave - state->wnext);\n        zmemcpy(dictionary + state->whave - state->wnext,\n                state->window, state->wnext);\n    }\n    if (dictLength != Z_NULL)\n        *dictLength = state->whave;\n    return Z_OK;\n}\n\nint ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)\nz_streamp strm;\nconst Bytef *dictionary;\nuInt dictLength;\n{\n    struct inflate_state FAR *state;\n    unsigned long dictid;\n    int ret;\n\n    /* check state */\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    if (state->wrap != 0 && state->mode != DICT)\n        return Z_STREAM_ERROR;\n\n    /* check for correct dictionary identifier */\n    if (state->mode == DICT) {\n        dictid = adler32(0L, Z_NULL, 0);\n        dictid = adler32(dictid, dictionary, dictLength);\n        if (dictid != state->check)\n            return Z_DATA_ERROR;\n    }\n\n    /* copy dictionary to window using updatewindow(), which will amend the\n       existing dictionary if appropriate */\n    ret = updatewindow(strm, dictionary + dictLength, dictLength);\n    if (ret) {\n        state->mode = MEM;\n        return Z_MEM_ERROR;\n    }\n    state->havedict = 1;\n    Tracev((stderr, \"inflate:   dictionary set\\n\"));\n    return Z_OK;\n}\n\nint ZEXPORT inflateGetHeader(strm, head)\nz_streamp strm;\ngz_headerp head;\n{\n    struct inflate_state FAR *state;\n\n    /* check state */\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;\n\n    /* save header structure */\n    state->head = head;\n    head->done = 0;\n    return Z_OK;\n}\n\n/*\n   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found\n   or when out of input.  When called, *have is the number of pattern bytes\n   found in order so far, in 0..3.  On return *have is updated to the new\n   state.  If on return *have equals four, then the pattern was found and the\n   return value is how many bytes were read including the last byte of the\n   pattern.  If *have is less than four, then the pattern has not been found\n   yet and the return value is len.  In the latter case, syncsearch() can be\n   called again with more data and the *have state.  *have is initialized to\n   zero for the first call.\n */\nlocal unsigned syncsearch(have, buf, len)\nunsigned FAR *have;\nconst unsigned char FAR *buf;\nunsigned len;\n{\n    unsigned got;\n    unsigned next;\n\n    got = *have;\n    next = 0;\n    while (next < len && got < 4) {\n        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))\n            got++;\n        else if (buf[next])\n            got = 0;\n        else\n            got = 4 - got;\n        next++;\n    }\n    *have = got;\n    return next;\n}\n\nint ZEXPORT inflateSync(strm)\nz_streamp strm;\n{\n    unsigned len;               /* number of bytes to look at or looked at */\n    unsigned long in, out;      /* temporary to save total_in and total_out */\n    unsigned char buf[4];       /* to restore bit buffer to byte string */\n    struct inflate_state FAR *state;\n\n    /* check parameters */\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;\n\n    /* if first time, start search in bit buffer */\n    if (state->mode != SYNC) {\n        state->mode = SYNC;\n        state->hold <<= state->bits & 7;\n        state->bits -= state->bits & 7;\n        len = 0;\n        while (state->bits >= 8) {\n            buf[len++] = (unsigned char)(state->hold);\n            state->hold >>= 8;\n            state->bits -= 8;\n        }\n        state->have = 0;\n        syncsearch(&(state->have), buf, len);\n    }\n\n    /* search available input */\n    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);\n    strm->avail_in -= len;\n    strm->next_in += len;\n    strm->total_in += len;\n\n    /* return no joy or set up to restart inflate() on a new block */\n    if (state->have != 4) return Z_DATA_ERROR;\n    in = strm->total_in;  out = strm->total_out;\n    inflateReset(strm);\n    strm->total_in = in;  strm->total_out = out;\n    state->mode = TYPE;\n    return Z_OK;\n}\n\n/*\n   Returns true if inflate is currently at the end of a block generated by\n   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP\n   implementation to provide an additional safety check. PPP uses\n   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored\n   block. When decompressing, PPP checks that at the end of input packet,\n   inflate is waiting for these length bytes.\n */\nint ZEXPORT inflateSyncPoint(strm)\nz_streamp strm;\n{\n    struct inflate_state FAR *state;\n\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    return state->mode == STORED && state->bits == 0;\n}\n\nint ZEXPORT inflateCopy(dest, source)\nz_streamp dest;\nz_streamp source;\n{\n    struct inflate_state FAR *state;\n    struct inflate_state FAR *copy;\n    unsigned char FAR *window;\n    unsigned wsize;\n\n    /* check input */\n    if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||\n        source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)\n        return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)source->state;\n\n    /* allocate space */\n    copy = (struct inflate_state FAR *)\n           ZALLOC(source, 1, sizeof(struct inflate_state));\n    if (copy == Z_NULL) return Z_MEM_ERROR;\n    window = Z_NULL;\n    if (state->window != Z_NULL) {\n        window = (unsigned char FAR *)\n                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));\n        if (window == Z_NULL) {\n            ZFREE(source, copy);\n            return Z_MEM_ERROR;\n        }\n    }\n\n    /* copy state */\n    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));\n    zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));\n    if (state->lencode >= state->codes &&\n        state->lencode <= state->codes + ENOUGH - 1) {\n        copy->lencode = copy->codes + (state->lencode - state->codes);\n        copy->distcode = copy->codes + (state->distcode - state->codes);\n    }\n    copy->next = copy->codes + (state->next - state->codes);\n    if (window != Z_NULL) {\n        wsize = 1U << state->wbits;\n        zmemcpy(window, state->window, wsize);\n    }\n    copy->window = window;\n    dest->state = (struct internal_state FAR *)copy;\n    return Z_OK;\n}\n\nint ZEXPORT inflateUndermine(strm, subvert)\nz_streamp strm;\nint subvert;\n{\n    struct inflate_state FAR *state;\n\n    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    state->sane = !subvert;\n#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR\n    return Z_OK;\n#else\n    state->sane = 1;\n    return Z_DATA_ERROR;\n#endif\n}\n\nlong ZEXPORT inflateMark(strm)\nz_streamp strm;\n{\n    struct inflate_state FAR *state;\n\n    if (strm == Z_NULL || strm->state == Z_NULL)\n        return (long)(((unsigned long)0 - 1) << 16);\n    state = (struct inflate_state FAR *)strm->state;\n    return (long)(((unsigned long)((long)state->back)) << 16) +\n        (state->mode == COPY ? state->length :\n            (state->mode == MATCH ? state->was - state->length : 0));\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/inflate.h",
    "content": "/* inflate.h -- internal inflate state definition\n * Copyright (C) 1995-2009 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* WARNING: this file should *not* be used by applications. It is\n   part of the implementation of the compression library and is\n   subject to change. Applications should only use zlib.h.\n */\n\n/* define NO_GZIP when compiling if you want to disable gzip header and\n   trailer decoding by inflate().  NO_GZIP would be used to avoid linking in\n   the crc code when it is not needed.  For shared libraries, gzip decoding\n   should be left enabled. */\n#ifndef NO_GZIP\n#  define GUNZIP\n#endif\n\n/* Possible inflate modes between inflate() calls */\ntypedef enum {\n    HEAD,       /* i: waiting for magic header */\n    FLAGS,      /* i: waiting for method and flags (gzip) */\n    TIME,       /* i: waiting for modification time (gzip) */\n    OS,         /* i: waiting for extra flags and operating system (gzip) */\n    EXLEN,      /* i: waiting for extra length (gzip) */\n    EXTRA,      /* i: waiting for extra bytes (gzip) */\n    NAME,       /* i: waiting for end of file name (gzip) */\n    COMMENT,    /* i: waiting for end of comment (gzip) */\n    HCRC,       /* i: waiting for header crc (gzip) */\n    DICTID,     /* i: waiting for dictionary check value */\n    DICT,       /* waiting for inflateSetDictionary() call */\n        TYPE,       /* i: waiting for type bits, including last-flag bit */\n        TYPEDO,     /* i: same, but skip check to exit inflate on new block */\n        STORED,     /* i: waiting for stored size (length and complement) */\n        COPY_,      /* i/o: same as COPY below, but only first time in */\n        COPY,       /* i/o: waiting for input or output to copy stored block */\n        TABLE,      /* i: waiting for dynamic block table lengths */\n        LENLENS,    /* i: waiting for code length code lengths */\n        CODELENS,   /* i: waiting for length/lit and distance code lengths */\n            LEN_,       /* i: same as LEN below, but only first time in */\n            LEN,        /* i: waiting for length/lit/eob code */\n            LENEXT,     /* i: waiting for length extra bits */\n            DIST,       /* i: waiting for distance code */\n            DISTEXT,    /* i: waiting for distance extra bits */\n            MATCH,      /* o: waiting for output space to copy string */\n            LIT,        /* o: waiting for output space to write literal */\n    CHECK,      /* i: waiting for 32-bit check value */\n    LENGTH,     /* i: waiting for 32-bit length (gzip) */\n    DONE,       /* finished check, done -- remain here until reset */\n    BAD,        /* got a data error -- remain here until reset */\n    MEM,        /* got an inflate() memory error -- remain here until reset */\n    SYNC        /* looking for synchronization bytes to restart inflate() */\n} inflate_mode;\n\n/*\n    State transitions between above modes -\n\n    (most modes can go to BAD or MEM on error -- not shown for clarity)\n\n    Process header:\n        HEAD -> (gzip) or (zlib) or (raw)\n        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->\n                  HCRC -> TYPE\n        (zlib) -> DICTID or TYPE\n        DICTID -> DICT -> TYPE\n        (raw) -> TYPEDO\n    Read deflate blocks:\n            TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK\n            STORED -> COPY_ -> COPY -> TYPE\n            TABLE -> LENLENS -> CODELENS -> LEN_\n            LEN_ -> LEN\n    Read deflate codes in fixed or dynamic block:\n                LEN -> LENEXT or LIT or TYPE\n                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN\n                LIT -> LEN\n    Process trailer:\n        CHECK -> LENGTH -> DONE\n */\n\n/* state maintained between inflate() calls.  Approximately 10K bytes. */\nstruct inflate_state {\n    inflate_mode mode;          /* current inflate mode */\n    int last;                   /* true if processing last block */\n    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip */\n    int havedict;               /* true if dictionary provided */\n    int flags;                  /* gzip header method and flags (0 if zlib) */\n    unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */\n    unsigned long check;        /* protected copy of check value */\n    unsigned long total;        /* protected copy of output count */\n    gz_headerp head;            /* where to save gzip header information */\n        /* sliding window */\n    unsigned wbits;             /* log base 2 of requested window size */\n    unsigned wsize;             /* window size or zero if not using window */\n    unsigned whave;             /* valid bytes in the window */\n    unsigned wnext;             /* window write index */\n    unsigned char FAR *window;  /* allocated sliding window, if needed */\n        /* bit accumulator */\n    unsigned long hold;         /* input bit accumulator */\n    unsigned bits;              /* number of bits in \"in\" */\n        /* for string and stored block copying */\n    unsigned length;            /* literal or length of data to copy */\n    unsigned offset;            /* distance back to copy string from */\n        /* for table and code decoding */\n    unsigned extra;             /* extra bits needed */\n        /* fixed and dynamic code tables */\n    code const FAR *lencode;    /* starting table for length/literal codes */\n    code const FAR *distcode;   /* starting table for distance codes */\n    unsigned lenbits;           /* index bits for lencode */\n    unsigned distbits;          /* index bits for distcode */\n        /* dynamic table building */\n    unsigned ncode;             /* number of code length code lengths */\n    unsigned nlen;              /* number of length code lengths */\n    unsigned ndist;             /* number of distance code lengths */\n    unsigned have;              /* number of code lengths in lens[] */\n    code FAR *next;             /* next available space in codes[] */\n    unsigned short lens[320];   /* temporary storage for code lengths */\n    unsigned short work[288];   /* work area for code table building */\n    code codes[ENOUGH];         /* space for code tables */\n    int sane;                   /* if false, allow invalid distance too far */\n    int back;                   /* bits back of last unprocessed length/lit */\n    unsigned was;               /* initial length of match */\n};\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/inftrees.c",
    "content": "/* inftrees.c -- generate Huffman trees for efficient decoding\n * Copyright (C) 1995-2013 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#include \"zutil.h\"\n#include \"inftrees.h\"\n\n#define MAXBITS 15\n\nconst char inflate_copyright[] =\n   \" inflate 1.2.8 Copyright 1995-2013 Mark Adler \";\n/*\n  If you use the zlib library in a product, an acknowledgment is welcome\n  in the documentation of your product. If for some reason you cannot\n  include such an acknowledgment, I would appreciate that you keep this\n  copyright string in the executable of your product.\n */\n\n/*\n   Build a set of tables to decode the provided canonical Huffman code.\n   The code lengths are lens[0..codes-1].  The result starts at *table,\n   whose indices are 0..2^bits-1.  work is a writable array of at least\n   lens shorts, which is used as a work area.  type is the type of code\n   to be generated, CODES, LENS, or DISTS.  On return, zero is success,\n   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table\n   on return points to the next available entry's address.  bits is the\n   requested root table index bits, and on return it is the actual root\n   table index bits.  It will differ if the request is greater than the\n   longest code or if it is less than the shortest code.\n */\nint ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)\ncodetype type;\nunsigned short FAR *lens;\nunsigned codes;\ncode FAR * FAR *table;\nunsigned FAR *bits;\nunsigned short FAR *work;\n{\n    unsigned len;               /* a code's length in bits */\n    unsigned sym;               /* index of code symbols */\n    unsigned min, max;          /* minimum and maximum code lengths */\n    unsigned root;              /* number of index bits for root table */\n    unsigned curr;              /* number of index bits for current table */\n    unsigned drop;              /* code bits to drop for sub-table */\n    int left;                   /* number of prefix codes available */\n    unsigned used;              /* code entries in table used */\n    unsigned huff;              /* Huffman code */\n    unsigned incr;              /* for incrementing code, index */\n    unsigned fill;              /* index for replicating entries */\n    unsigned low;               /* low bits for current root entry */\n    unsigned mask;              /* mask for low root bits */\n    code here;                  /* table entry for duplication */\n    code FAR *next;             /* next available space in table */\n    const unsigned short FAR *base;     /* base value table to use */\n    const unsigned short FAR *extra;    /* extra bits table to use */\n    int end;                    /* use base and extra for symbol > end */\n    unsigned short count[MAXBITS+1];    /* number of codes of each length */\n    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */\n    static const unsigned short lbase[31] = { /* Length codes 257..285 base */\n        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,\n        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};\n    static const unsigned short lext[31] = { /* Length codes 257..285 extra */\n        16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,\n        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78};\n    static const unsigned short dbase[32] = { /* Distance codes 0..29 base */\n        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,\n        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,\n        8193, 12289, 16385, 24577, 0, 0};\n    static const unsigned short dext[32] = { /* Distance codes 0..29 extra */\n        16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,\n        23, 23, 24, 24, 25, 25, 26, 26, 27, 27,\n        28, 28, 29, 29, 64, 64};\n\n    /*\n       Process a set of code lengths to create a canonical Huffman code.  The\n       code lengths are lens[0..codes-1].  Each length corresponds to the\n       symbols 0..codes-1.  The Huffman code is generated by first sorting the\n       symbols by length from short to long, and retaining the symbol order\n       for codes with equal lengths.  Then the code starts with all zero bits\n       for the first code of the shortest length, and the codes are integer\n       increments for the same length, and zeros are appended as the length\n       increases.  For the deflate format, these bits are stored backwards\n       from their more natural integer increment ordering, and so when the\n       decoding tables are built in the large loop below, the integer codes\n       are incremented backwards.\n\n       This routine assumes, but does not check, that all of the entries in\n       lens[] are in the range 0..MAXBITS.  The caller must assure this.\n       1..MAXBITS is interpreted as that code length.  zero means that that\n       symbol does not occur in this code.\n\n       The codes are sorted by computing a count of codes for each length,\n       creating from that a table of starting indices for each length in the\n       sorted table, and then entering the symbols in order in the sorted\n       table.  The sorted table is work[], with that space being provided by\n       the caller.\n\n       The length counts are used for other purposes as well, i.e. finding\n       the minimum and maximum length codes, determining if there are any\n       codes at all, checking for a valid set of lengths, and looking ahead\n       at length counts to determine sub-table sizes when building the\n       decoding tables.\n     */\n\n    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */\n    for (len = 0; len <= MAXBITS; len++)\n        count[len] = 0;\n    for (sym = 0; sym < codes; sym++)\n        count[lens[sym]]++;\n\n    /* bound code lengths, force root to be within code lengths */\n    root = *bits;\n    for (max = MAXBITS; max >= 1; max--)\n        if (count[max] != 0) break;\n    if (root > max) root = max;\n    if (max == 0) {                     /* no symbols to code at all */\n        here.op = (unsigned char)64;    /* invalid code marker */\n        here.bits = (unsigned char)1;\n        here.val = (unsigned short)0;\n        *(*table)++ = here;             /* make a table to force an error */\n        *(*table)++ = here;\n        *bits = 1;\n        return 0;     /* no symbols, but wait for decoding to report error */\n    }\n    for (min = 1; min < max; min++)\n        if (count[min] != 0) break;\n    if (root < min) root = min;\n\n    /* check for an over-subscribed or incomplete set of lengths */\n    left = 1;\n    for (len = 1; len <= MAXBITS; len++) {\n        left <<= 1;\n        left -= count[len];\n        if (left < 0) return -1;        /* over-subscribed */\n    }\n    if (left > 0 && (type == CODES || max != 1))\n        return -1;                      /* incomplete set */\n\n    /* generate offsets into symbol table for each length for sorting */\n    offs[1] = 0;\n    for (len = 1; len < MAXBITS; len++)\n        offs[len + 1] = offs[len] + count[len];\n\n    /* sort symbols by length, by symbol order within each length */\n    for (sym = 0; sym < codes; sym++)\n        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;\n\n    /*\n       Create and fill in decoding tables.  In this loop, the table being\n       filled is at next and has curr index bits.  The code being used is huff\n       with length len.  That code is converted to an index by dropping drop\n       bits off of the bottom.  For codes where len is less than drop + curr,\n       those top drop + curr - len bits are incremented through all values to\n       fill the table with replicated entries.\n\n       root is the number of index bits for the root table.  When len exceeds\n       root, sub-tables are created pointed to by the root entry with an index\n       of the low root bits of huff.  This is saved in low to check for when a\n       new sub-table should be started.  drop is zero when the root table is\n       being filled, and drop is root when sub-tables are being filled.\n\n       When a new sub-table is needed, it is necessary to look ahead in the\n       code lengths to determine what size sub-table is needed.  The length\n       counts are used for this, and so count[] is decremented as codes are\n       entered in the tables.\n\n       used keeps track of how many table entries have been allocated from the\n       provided *table space.  It is checked for LENS and DIST tables against\n       the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in\n       the initial root table size constants.  See the comments in inftrees.h\n       for more information.\n\n       sym increments through all symbols, and the loop terminates when\n       all codes of length max, i.e. all codes, have been processed.  This\n       routine permits incomplete codes, so another loop after this one fills\n       in the rest of the decoding tables with invalid code markers.\n     */\n\n    /* set up for code type */\n    switch (type) {\n    case CODES:\n        base = extra = work;    /* dummy value--not used */\n        end = 19;\n        break;\n    case LENS:\n        base = lbase;\n        base -= 257;\n        extra = lext;\n        extra -= 257;\n        end = 256;\n        break;\n    default:            /* DISTS */\n        base = dbase;\n        extra = dext;\n        end = -1;\n    }\n\n    /* initialize state for loop */\n    huff = 0;                   /* starting code */\n    sym = 0;                    /* starting code symbol */\n    len = min;                  /* starting code length */\n    next = *table;              /* current table to fill in */\n    curr = root;                /* current table index bits */\n    drop = 0;                   /* current bits to drop from code for index */\n    low = (unsigned)(-1);       /* trigger new sub-table when len > root */\n    used = 1U << root;          /* use root table entries */\n    mask = used - 1;            /* mask for comparing low */\n\n    /* check available table space */\n    if ((type == LENS && used > ENOUGH_LENS) ||\n        (type == DISTS && used > ENOUGH_DISTS))\n        return 1;\n\n    /* process all codes and make table entries */\n    for (;;) {\n        /* create table entry */\n        here.bits = (unsigned char)(len - drop);\n        if ((int)(work[sym]) < end) {\n            here.op = (unsigned char)0;\n            here.val = work[sym];\n        }\n        else if ((int)(work[sym]) > end) {\n            here.op = (unsigned char)(extra[work[sym]]);\n            here.val = base[work[sym]];\n        }\n        else {\n            here.op = (unsigned char)(32 + 64);         /* end of block */\n            here.val = 0;\n        }\n\n        /* replicate for those indices with low len bits equal to huff */\n        incr = 1U << (len - drop);\n        fill = 1U << curr;\n        min = fill;                 /* save offset to next table */\n        do {\n            fill -= incr;\n            next[(huff >> drop) + fill] = here;\n        } while (fill != 0);\n\n        /* backwards increment the len-bit code huff */\n        incr = 1U << (len - 1);\n        while (huff & incr)\n            incr >>= 1;\n        if (incr != 0) {\n            huff &= incr - 1;\n            huff += incr;\n        }\n        else\n            huff = 0;\n\n        /* go to next symbol, update count, len */\n        sym++;\n        if (--(count[len]) == 0) {\n            if (len == max) break;\n            len = lens[work[sym]];\n        }\n\n        /* create new sub-table if needed */\n        if (len > root && (huff & mask) != low) {\n            /* if first time, transition to sub-tables */\n            if (drop == 0)\n                drop = root;\n\n            /* increment past last table */\n            next += min;            /* here min is 1 << curr */\n\n            /* determine length of next table */\n            curr = len - drop;\n            left = (int)(1 << curr);\n            while (curr + drop < max) {\n                left -= count[curr + drop];\n                if (left <= 0) break;\n                curr++;\n                left <<= 1;\n            }\n\n            /* check for enough space */\n            used += 1U << curr;\n            if ((type == LENS && used > ENOUGH_LENS) ||\n                (type == DISTS && used > ENOUGH_DISTS))\n                return 1;\n\n            /* point entry in root table to sub-table */\n            low = huff & mask;\n            (*table)[low].op = (unsigned char)curr;\n            (*table)[low].bits = (unsigned char)root;\n            (*table)[low].val = (unsigned short)(next - *table);\n        }\n    }\n\n    /* fill in remaining table entry if code is incomplete (guaranteed to have\n       at most one remaining entry, since if the code is incomplete, the\n       maximum code length that was allowed to get this far is one bit) */\n    if (huff != 0) {\n        here.op = (unsigned char)64;            /* invalid code marker */\n        here.bits = (unsigned char)(len - drop);\n        here.val = (unsigned short)0;\n        next[huff] = here;\n    }\n\n    /* set return parameters */\n    *table += used;\n    *bits = root;\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/inftrees.h",
    "content": "/* inftrees.h -- header to use inftrees.c\n * Copyright (C) 1995-2005, 2010 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* WARNING: this file should *not* be used by applications. It is\n   part of the implementation of the compression library and is\n   subject to change. Applications should only use zlib.h.\n */\n\n/* Structure for decoding tables.  Each entry provides either the\n   information needed to do the operation requested by the code that\n   indexed that table entry, or it provides a pointer to another\n   table that indexes more bits of the code.  op indicates whether\n   the entry is a pointer to another table, a literal, a length or\n   distance, an end-of-block, or an invalid code.  For a table\n   pointer, the low four bits of op is the number of index bits of\n   that table.  For a length or distance, the low four bits of op\n   is the number of extra bits to get after the code.  bits is\n   the number of bits in this code or part of the code to drop off\n   of the bit buffer.  val is the actual byte to output in the case\n   of a literal, the base length or distance, or the offset from\n   the current table to the next table.  Each entry is four bytes. */\ntypedef struct {\n    unsigned char op;           /* operation, extra bits, table bits */\n    unsigned char bits;         /* bits in this part of the code */\n    unsigned short val;         /* offset in table or code value */\n} code;\n\n/* op values as set by inflate_table():\n    00000000 - literal\n    0000tttt - table link, tttt != 0 is the number of table index bits\n    0001eeee - length or distance, eeee is the number of extra bits\n    01100000 - end of block\n    01000000 - invalid code\n */\n\n/* Maximum size of the dynamic table.  The maximum number of code structures is\n   1444, which is the sum of 852 for literal/length codes and 592 for distance\n   codes.  These values were found by exhaustive searches using the program\n   examples/enough.c found in the zlib distribtution.  The arguments to that\n   program are the number of symbols, the initial root table size, and the\n   maximum bit length of a code.  \"enough 286 9 15\" for literal/length codes\n   returns returns 852, and \"enough 30 6 15\" for distance codes returns 592.\n   The initial root table size (9 or 6) is found in the fifth argument of the\n   inflate_table() calls in inflate.c and infback.c.  If the root table size is\n   changed, then these maximum sizes would be need to be recalculated and\n   updated. */\n#define ENOUGH_LENS 852\n#define ENOUGH_DISTS 592\n#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)\n\n/* Type of code to build for inflate_table() */\ntypedef enum {\n    CODES,\n    LENS,\n    DISTS\n} codetype;\n\nint ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,\n                             unsigned codes, code FAR * FAR *table,\n                             unsigned FAR *bits, unsigned short FAR *work));\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/make_vms.com",
    "content": "$! make libz under VMS written by\n$! Martin P.J. Zinser\n$!\n$! In case of problems with the install you might contact me at\n$! zinser@zinser.no-ip.info(preferred) or\n$! martin.zinser@eurexchange.com (work)\n$!\n$! Make procedure history for Zlib\n$!\n$!------------------------------------------------------------------------------\n$! Version history\n$! 0.01 20060120 First version to receive a number\n$! 0.02 20061008 Adapt to new Makefile.in\n$! 0.03 20091224 Add support for large file check\n$! 0.04 20100110 Add new gzclose, gzlib, gzread, gzwrite\n$! 0.05 20100221 Exchange zlibdefs.h by zconf.h.in\n$! 0.06 20120111 Fix missing amiss_err, update zconf_h.in, fix new exmples\n$!               subdir path, update module search in makefile.in\n$! 0.07 20120115 Triggered by work done by Alexey Chupahin completly redesigned\n$!               shared image creation\n$! 0.08 20120219 Make it work on VAX again, pre-load missing symbols to shared\n$!               image\n$! 0.09 20120305 SMS.  P1 sets builder (\"MMK\", \"MMS\", \" \" (built-in)).\n$!               \"\" -> automatic, preference: MMK, MMS, built-in.\n$!\n$ on error then goto err_exit\n$!\n$ true  = 1\n$ false = 0\n$ tmpnam = \"temp_\" + f$getjpi(\"\",\"pid\")\n$ tt = tmpnam + \".txt\"\n$ tc = tmpnam + \".c\"\n$ th = tmpnam + \".h\"\n$ define/nolog tconfig 'th'\n$ its_decc = false\n$ its_vaxc = false\n$ its_gnuc = false\n$ s_case   = False\n$!\n$! Setup variables holding \"config\" information\n$!\n$ Make    = \"''p1'\"\n$ name     = \"Zlib\"\n$ version  = \"?.?.?\"\n$ v_string = \"ZLIB_VERSION\"\n$ v_file   = \"zlib.h\"\n$ ccopt   = \"/include = []\"\n$ lopts   = \"\"\n$ dnsrl   = \"\"\n$ aconf_in_file = \"zconf.h.in#zconf.h_in#zconf_h.in\"\n$ conf_check_string = \"\"\n$ linkonly = false\n$ optfile  = name + \".opt\"\n$ mapfile  = name + \".map\"\n$ libdefs  = \"\"\n$ vax      = f$getsyi(\"HW_MODEL\").lt.1024\n$ axp      = f$getsyi(\"HW_MODEL\").ge.1024 .and. f$getsyi(\"HW_MODEL\").lt.4096\n$ ia64     = f$getsyi(\"HW_MODEL\").ge.4096\n$!\n$! 2012-03-05 SMS.\n$! Why is this needed?  And if it is needed, why not simply \".not. vax\"?\n$!\n$!!! if axp .or. ia64 then  set proc/parse=extended\n$!\n$ whoami = f$parse(f$environment(\"Procedure\"),,,,\"NO_CONCEAL\")\n$ mydef  = F$parse(whoami,,,\"DEVICE\")\n$ mydir  = f$parse(whoami,,,\"DIRECTORY\") - \"][\"\n$ myproc = f$parse(whoami,,,\"Name\") + f$parse(whoami,,,\"type\")\n$!\n$! Check for MMK/MMS\n$!\n$ if (Make .eqs. \"\")\n$ then\n$   If F$Search (\"Sys$System:MMS.EXE\") .nes. \"\" Then Make = \"MMS\"\n$   If F$Type (MMK) .eqs. \"STRING\" Then Make = \"MMK\"\n$ else\n$   Make = f$edit( Make, \"trim\")\n$ endif\n$!\n$ gosub find_version\n$!\n$  open/write topt tmp.opt\n$  open/write optf 'optfile'\n$!\n$ gosub check_opts\n$!\n$! Look for the compiler used\n$!\n$ gosub check_compiler\n$ close topt\n$ close optf\n$!\n$ if its_decc\n$ then\n$   ccopt = \"/prefix=all\" + ccopt\n$   if f$trnlnm(\"SYS\") .eqs. \"\"\n$   then\n$     if axp\n$     then\n$       define sys sys$library:\n$     else\n$       ccopt = \"/decc\" + ccopt\n$       define sys decc$library_include:\n$     endif\n$   endif\n$!\n$! 2012-03-05 SMS.\n$! Why /NAMES = AS_IS?  Why not simply \".not. vax\"?  And why not on VAX?\n$!\n$   if axp .or. ia64\n$   then\n$       ccopt = ccopt + \"/name=as_is/opt=(inline=speed)\"\n$       s_case = true\n$   endif\n$ endif\n$ if its_vaxc .or. its_gnuc\n$ then\n$    if f$trnlnm(\"SYS\").eqs.\"\" then define sys sys$library:\n$ endif\n$!\n$! Build a fake configure input header\n$!\n$ open/write conf_hin config.hin\n$ write conf_hin \"#undef _LARGEFILE64_SOURCE\"\n$ close conf_hin\n$!\n$!\n$ i = 0\n$FIND_ACONF:\n$ fname = f$element(i,\"#\",aconf_in_file)\n$ if fname .eqs. \"#\" then goto AMISS_ERR\n$ if f$search(fname) .eqs. \"\"\n$ then\n$   i = i + 1\n$   goto find_aconf\n$ endif\n$ open/read/err=aconf_err aconf_in 'fname'\n$ open/write aconf zconf.h\n$ACONF_LOOP:\n$ read/end_of_file=aconf_exit aconf_in line\n$ work = f$edit(line, \"compress,trim\")\n$ if f$extract(0,6,work) .nes. \"#undef\"\n$ then\n$   if f$extract(0,12,work) .nes. \"#cmakedefine\"\n$   then\n$       write aconf line\n$   endif\n$ else\n$   cdef = f$element(1,\" \",work)\n$   gosub check_config\n$ endif\n$ goto aconf_loop\n$ACONF_EXIT:\n$ write aconf \"\"\n$ write aconf \"/* VMS specifics added by make_vms.com: */\"\n$ write aconf \"#define VMS 1\"\n$ write aconf \"#include <unistd.h>\"\n$ write aconf \"#include <unixio.h>\"\n$ write aconf \"#ifdef _LARGEFILE\"\n$ write aconf \"# define off64_t __off64_t\"\n$ write aconf \"# define fopen64 fopen\"\n$ write aconf \"# define fseeko64 fseeko\"\n$ write aconf \"# define lseek64 lseek\"\n$ write aconf \"# define ftello64 ftell\"\n$ write aconf \"#endif\"\n$ write aconf \"#if !defined( __VAX) && (__CRTL_VER >= 70312000)\"\n$ write aconf \"# define HAVE_VSNPRINTF\"\n$ write aconf \"#endif\"\n$ close aconf_in\n$ close aconf\n$ if f$search(\"''th'\") .nes. \"\" then delete 'th';*\n$! Build the thing plain or with mms\n$!\n$ write sys$output \"Compiling Zlib sources ...\"\n$ if make.eqs.\"\"\n$ then\n$   if (f$search( \"example.obj;*\") .nes. \"\") then delete example.obj;*\n$   if (f$search( \"minigzip.obj;*\") .nes. \"\") then delete minigzip.obj;*\n$   CALL MAKE adler32.OBJ \"CC ''CCOPT' adler32\" -\n                adler32.c zlib.h zconf.h\n$   CALL MAKE compress.OBJ \"CC ''CCOPT' compress\" -\n                compress.c zlib.h zconf.h\n$   CALL MAKE crc32.OBJ \"CC ''CCOPT' crc32\" -\n                crc32.c zlib.h zconf.h\n$   CALL MAKE deflate.OBJ \"CC ''CCOPT' deflate\" -\n                deflate.c deflate.h zutil.h zlib.h zconf.h\n$   CALL MAKE gzclose.OBJ \"CC ''CCOPT' gzclose\" -\n                gzclose.c zutil.h zlib.h zconf.h\n$   CALL MAKE gzlib.OBJ \"CC ''CCOPT' gzlib\" -\n                gzlib.c zutil.h zlib.h zconf.h\n$   CALL MAKE gzread.OBJ \"CC ''CCOPT' gzread\" -\n                gzread.c zutil.h zlib.h zconf.h\n$   CALL MAKE gzwrite.OBJ \"CC ''CCOPT' gzwrite\" -\n                gzwrite.c zutil.h zlib.h zconf.h\n$   CALL MAKE infback.OBJ \"CC ''CCOPT' infback\" -\n                infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h\n$   CALL MAKE inffast.OBJ \"CC ''CCOPT' inffast\" -\n                inffast.c zutil.h zlib.h zconf.h inffast.h\n$   CALL MAKE inflate.OBJ \"CC ''CCOPT' inflate\" -\n                inflate.c zutil.h zlib.h zconf.h infblock.h\n$   CALL MAKE inftrees.OBJ \"CC ''CCOPT' inftrees\" -\n                inftrees.c zutil.h zlib.h zconf.h inftrees.h\n$   CALL MAKE trees.OBJ \"CC ''CCOPT' trees\" -\n                trees.c deflate.h zutil.h zlib.h zconf.h\n$   CALL MAKE uncompr.OBJ \"CC ''CCOPT' uncompr\" -\n                uncompr.c zlib.h zconf.h\n$   CALL MAKE zutil.OBJ \"CC ''CCOPT' zutil\" -\n                zutil.c zutil.h zlib.h zconf.h\n$   write sys$output \"Building Zlib ...\"\n$   CALL MAKE libz.OLB \"lib/crea libz.olb *.obj\" *.OBJ\n$   write sys$output \"Building example...\"\n$   CALL MAKE example.OBJ \"CC ''CCOPT' [.test]example\" -\n                [.test]example.c zlib.h zconf.h\n$   call make example.exe \"LINK example,libz.olb/lib\" example.obj libz.olb\n$   write sys$output \"Building minigzip...\"\n$   CALL MAKE minigzip.OBJ \"CC ''CCOPT' [.test]minigzip\" -\n              [.test]minigzip.c zlib.h zconf.h\n$   call make minigzip.exe -\n              \"LINK minigzip,libz.olb/lib\" -\n              minigzip.obj libz.olb\n$ else\n$   gosub crea_mms\n$   write sys$output \"Make ''name' ''version' with ''Make' \"\n$   'make'\n$ endif\n$!\n$! Create shareable image\n$!\n$ gosub crea_olist\n$ write sys$output \"Creating libzshr.exe\"\n$ call map_2_shopt 'mapfile' 'optfile'\n$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,'optfile'/opt\n$ write sys$output \"Zlib build completed\"\n$ delete/nolog tmp.opt;*\n$ exit\n$AMISS_ERR:\n$ write sys$output \"No source for config.hin found.\"\n$ write sys$output \"Tried any of ''aconf_in_file'\"\n$ goto err_exit\n$CC_ERR:\n$ write sys$output \"C compiler required to build ''name'\"\n$ goto err_exit\n$ERR_EXIT:\n$ set message/facil/ident/sever/text\n$ close/nolog optf\n$ close/nolog topt\n$ close/nolog aconf_in\n$ close/nolog aconf\n$ close/nolog out\n$ close/nolog min\n$ close/nolog mod\n$ close/nolog h_in\n$ write sys$output \"Exiting...\"\n$ exit 2\n$!\n$!\n$MAKE: SUBROUTINE   !SUBROUTINE TO CHECK DEPENDENCIES\n$ V = 'F$Verify(0)\n$! P1 = What we are trying to make\n$! P2 = Command to make it\n$! P3 - P8  What it depends on\n$\n$ If F$Search(P1) .Eqs. \"\" Then Goto Makeit\n$ Time = F$CvTime(F$File(P1,\"RDT\"))\n$arg=3\n$Loop:\n$       Argument = P'arg\n$       If Argument .Eqs. \"\" Then Goto Exit\n$       El=0\n$Loop2:\n$       File = F$Element(El,\" \",Argument)\n$       If File .Eqs. \" \" Then Goto Endl\n$       AFile = \"\"\n$Loop3:\n$       OFile = AFile\n$       AFile = F$Search(File)\n$       If AFile .Eqs. \"\" .Or. AFile .Eqs. OFile Then Goto NextEl\n$       If F$CvTime(F$File(AFile,\"RDT\")) .Ges. Time Then Goto Makeit\n$       Goto Loop3\n$NextEL:\n$       El = El + 1\n$       Goto Loop2\n$EndL:\n$ arg=arg+1\n$ If arg .Le. 8 Then Goto Loop\n$ Goto Exit\n$\n$Makeit:\n$ VV=F$VERIFY(0)\n$ write sys$output P2\n$ 'P2\n$ VV='F$Verify(VV)\n$Exit:\n$ If V Then Set Verify\n$ENDSUBROUTINE\n$!------------------------------------------------------------------------------\n$!\n$! Check command line options and set symbols accordingly\n$!\n$!------------------------------------------------------------------------------\n$! Version history\n$! 0.01 20041206 First version to receive a number\n$! 0.02 20060126 Add new \"HELP\" target\n$ CHECK_OPTS:\n$ i = 1\n$ OPT_LOOP:\n$ if i .lt. 9\n$ then\n$   cparm = f$edit(p'i',\"upcase\")\n$!\n$! Check if parameter actually contains something\n$!\n$   if f$edit(cparm,\"trim\") .nes. \"\"\n$   then\n$     if cparm .eqs. \"DEBUG\"\n$     then\n$       ccopt = ccopt + \"/noopt/deb\"\n$       lopts = lopts + \"/deb\"\n$     endif\n$     if f$locate(\"CCOPT=\",cparm) .lt. f$length(cparm)\n$     then\n$       start = f$locate(\"=\",cparm) + 1\n$       len   = f$length(cparm) - start\n$       ccopt = ccopt + f$extract(start,len,cparm)\n$       if f$locate(\"AS_IS\",f$edit(ccopt,\"UPCASE\")) .lt. f$length(ccopt) -\n          then s_case = true\n$     endif\n$     if cparm .eqs. \"LINK\" then linkonly = true\n$     if f$locate(\"LOPTS=\",cparm) .lt. f$length(cparm)\n$     then\n$       start = f$locate(\"=\",cparm) + 1\n$       len   = f$length(cparm) - start\n$       lopts = lopts + f$extract(start,len,cparm)\n$     endif\n$     if f$locate(\"CC=\",cparm) .lt. f$length(cparm)\n$     then\n$       start  = f$locate(\"=\",cparm) + 1\n$       len    = f$length(cparm) - start\n$       cc_com = f$extract(start,len,cparm)\n        if (cc_com .nes. \"DECC\") .and. -\n           (cc_com .nes. \"VAXC\") .and. -\n           (cc_com .nes. \"GNUC\")\n$       then\n$         write sys$output \"Unsupported compiler choice ''cc_com' ignored\"\n$         write sys$output \"Use DECC, VAXC, or GNUC instead\"\n$       else\n$         if cc_com .eqs. \"DECC\" then its_decc = true\n$         if cc_com .eqs. \"VAXC\" then its_vaxc = true\n$         if cc_com .eqs. \"GNUC\" then its_gnuc = true\n$       endif\n$     endif\n$     if f$locate(\"MAKE=\",cparm) .lt. f$length(cparm)\n$     then\n$       start  = f$locate(\"=\",cparm) + 1\n$       len    = f$length(cparm) - start\n$       mmks = f$extract(start,len,cparm)\n$       if (mmks .eqs. \"MMK\") .or. (mmks .eqs. \"MMS\")\n$       then\n$         make = mmks\n$       else\n$         write sys$output \"Unsupported make choice ''mmks' ignored\"\n$         write sys$output \"Use MMK or MMS instead\"\n$       endif\n$     endif\n$     if cparm .eqs. \"HELP\" then gosub bhelp\n$   endif\n$   i = i + 1\n$   goto opt_loop\n$ endif\n$ return\n$!------------------------------------------------------------------------------\n$!\n$! Look for the compiler used\n$!\n$! Version history\n$! 0.01 20040223 First version to receive a number\n$! 0.02 20040229 Save/set value of decc$no_rooted_search_lists\n$! 0.03 20060202 Extend handling of GNU C\n$! 0.04 20090402 Compaq -> hp\n$CHECK_COMPILER:\n$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))\n$ then\n$   its_decc = (f$search(\"SYS$SYSTEM:DECC$COMPILER.EXE\") .nes. \"\")\n$   its_vaxc = .not. its_decc .and. (F$Search(\"SYS$System:VAXC.Exe\") .nes. \"\")\n$   its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm(\"gnu_cc\") .nes. \"\")\n$ endif\n$!\n$! Exit if no compiler available\n$!\n$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))\n$ then goto CC_ERR\n$ else\n$   if its_decc\n$   then\n$     write sys$output \"CC compiler check ... hp C\"\n$     if f$trnlnm(\"decc$no_rooted_search_lists\") .nes. \"\"\n$     then\n$       dnrsl = f$trnlnm(\"decc$no_rooted_search_lists\")\n$     endif\n$     define/nolog decc$no_rooted_search_lists 1\n$   else\n$     if its_vaxc then write sys$output \"CC compiler check ... VAX C\"\n$     if its_gnuc\n$     then\n$         write sys$output \"CC compiler check ... GNU C\"\n$         if f$trnlnm(topt) then write topt \"gnu_cc:[000000]gcclib.olb/lib\"\n$         if f$trnlnm(optf) then write optf \"gnu_cc:[000000]gcclib.olb/lib\"\n$         cc = \"gcc\"\n$     endif\n$     if f$trnlnm(topt) then write topt \"sys$share:vaxcrtl.exe/share\"\n$     if f$trnlnm(optf) then write optf \"sys$share:vaxcrtl.exe/share\"\n$   endif\n$ endif\n$ return\n$!------------------------------------------------------------------------------\n$!\n$! If MMS/MMK are available dump out the descrip.mms if required\n$!\n$CREA_MMS:\n$ write sys$output \"Creating descrip.mms...\"\n$ create descrip.mms\n$ open/append out descrip.mms\n$ copy sys$input: out\n$ deck\n# descrip.mms: MMS description file for building zlib on VMS\n# written by Martin P.J. Zinser\n# <zinser@zinser.no-ip.info or martin.zinser@eurexchange.com>\n\nOBJS = adler32.obj, compress.obj, crc32.obj, gzclose.obj, gzlib.obj\\\n       gzread.obj, gzwrite.obj, uncompr.obj, infback.obj\\\n       deflate.obj, trees.obj, zutil.obj, inflate.obj, \\\n       inftrees.obj, inffast.obj\n\n$ eod\n$ write out \"CFLAGS=\", ccopt\n$ write out \"LOPTS=\", lopts\n$ write out \"all : example.exe minigzip.exe libz.olb\"\n$ copy sys$input: out\n$ deck\n        @ write sys$output \" Example applications available\"\n\nlibz.olb : libz.olb($(OBJS))\n\t@ write sys$output \" libz available\"\n\nexample.exe : example.obj libz.olb\n              link $(LOPTS) example,libz.olb/lib\n\nminigzip.exe : minigzip.obj libz.olb\n              link $(LOPTS) minigzip,libz.olb/lib\n\nclean :\n\tdelete *.obj;*,libz.olb;*,*.opt;*,*.exe;*\n\n\n# Other dependencies.\nadler32.obj  : adler32.c zutil.h zlib.h zconf.h\ncompress.obj : compress.c zlib.h zconf.h\ncrc32.obj    : crc32.c zutil.h zlib.h zconf.h\ndeflate.obj  : deflate.c deflate.h zutil.h zlib.h zconf.h\nexample.obj  : [.test]example.c zlib.h zconf.h\ngzclose.obj  : gzclose.c zutil.h zlib.h zconf.h\ngzlib.obj    : gzlib.c zutil.h zlib.h zconf.h\ngzread.obj   : gzread.c zutil.h zlib.h zconf.h\ngzwrite.obj  : gzwrite.c zutil.h zlib.h zconf.h\ninffast.obj  : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h\ninflate.obj  : inflate.c zutil.h zlib.h zconf.h\ninftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h\nminigzip.obj : [.test]minigzip.c zlib.h zconf.h\ntrees.obj    : trees.c deflate.h zutil.h zlib.h zconf.h\nuncompr.obj  : uncompr.c zlib.h zconf.h\nzutil.obj    : zutil.c zutil.h zlib.h zconf.h\ninfback.obj  : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h\n$ eod\n$ close out\n$ return\n$!------------------------------------------------------------------------------\n$!\n$! Read list of core library sources from makefile.in and create options\n$! needed to build shareable image\n$!\n$CREA_OLIST:\n$ open/read min makefile.in\n$ open/write mod modules.opt\n$ src_check_list = \"OBJZ =#OBJG =\"\n$MRLOOP:\n$ read/end=mrdone min rec\n$ i = 0\n$SRC_CHECK_LOOP:\n$ src_check = f$element(i, \"#\", src_check_list)\n$ i = i+1\n$ if src_check .eqs. \"#\" then goto mrloop\n$ if (f$extract(0,6,rec) .nes. src_check) then goto src_check_loop\n$ rec = rec - src_check\n$ gosub extra_filnam\n$ if (f$element(1,\"\\\",rec) .eqs. \"\\\") then goto mrloop\n$MRSLOOP:\n$ read/end=mrdone min rec\n$ gosub extra_filnam\n$ if (f$element(1,\"\\\",rec) .nes. \"\\\") then goto mrsloop\n$MRDONE:\n$ close min\n$ close mod\n$ return\n$!------------------------------------------------------------------------------\n$!\n$! Take record extracted in crea_olist and split it into single filenames\n$!\n$EXTRA_FILNAM:\n$ myrec = f$edit(rec - \"\\\", \"trim,compress\")\n$ i = 0\n$FELOOP:\n$ srcfil = f$element(i,\" \", myrec)\n$ if (srcfil .nes. \" \")\n$ then\n$   write mod f$parse(srcfil,,,\"NAME\"), \".obj\"\n$   i = i + 1\n$   goto feloop\n$ endif\n$ return\n$!------------------------------------------------------------------------------\n$!\n$! Find current Zlib version number\n$!\n$FIND_VERSION:\n$ open/read h_in 'v_file'\n$hloop:\n$ read/end=hdone h_in rec\n$ rec = f$edit(rec,\"TRIM\")\n$ if (f$extract(0,1,rec) .nes. \"#\") then goto hloop\n$ rec = f$edit(rec - \"#\", \"TRIM\")\n$ if f$element(0,\" \",rec) .nes. \"define\" then goto hloop\n$ if f$element(1,\" \",rec) .eqs. v_string\n$ then\n$   version = 'f$element(2,\" \",rec)'\n$   goto hdone\n$ endif\n$ goto hloop\n$hdone:\n$ close h_in\n$ return\n$!------------------------------------------------------------------------------\n$!\n$CHECK_CONFIG:\n$!\n$ in_ldef = f$locate(cdef,libdefs)\n$ if (in_ldef .lt. f$length(libdefs))\n$ then\n$   write aconf \"#define ''cdef' 1\"\n$   libdefs = f$extract(0,in_ldef,libdefs) + -\n              f$extract(in_ldef + f$length(cdef) + 1, -\n                        f$length(libdefs) - in_ldef - f$length(cdef) - 1, -\n                        libdefs)\n$ else\n$   if (f$type('cdef') .eqs. \"INTEGER\")\n$   then\n$     write aconf \"#define ''cdef' \", 'cdef'\n$   else\n$     if (f$type('cdef') .eqs. \"STRING\")\n$     then\n$       write aconf \"#define ''cdef' \", \"\"\"\", '''cdef'', \"\"\"\"\n$     else\n$       gosub check_cc_def\n$     endif\n$   endif\n$ endif\n$ return\n$!------------------------------------------------------------------------------\n$!\n$! Check if this is a define relating to the properties of the C/C++\n$! compiler\n$!\n$ CHECK_CC_DEF:\n$ if (cdef .eqs. \"_LARGEFILE64_SOURCE\")\n$ then\n$   copy sys$input: 'tc'\n$   deck\n#include \"tconfig\"\n#define _LARGEFILE\n#include <stdio.h>\n\nint main(){\nFILE *fp;\n  fp = fopen(\"temp.txt\",\"r\");\n  fseeko(fp,1,SEEK_SET);\n  fclose(fp);\n}\n\n$   eod\n$   test_inv = false\n$   comm_h = false\n$   gosub cc_prop_check\n$   return\n$ endif\n$ write aconf \"/* \", line, \" */\"\n$ return\n$!------------------------------------------------------------------------------\n$!\n$! Check for properties of C/C++ compiler\n$!\n$! Version history\n$! 0.01 20031020 First version to receive a number\n$! 0.02 20031022 Added logic for defines with value\n$! 0.03 20040309 Make sure local config file gets not deleted\n$! 0.04 20041230 Also write include for configure run\n$! 0.05 20050103 Add processing of \"comment defines\"\n$CC_PROP_CHECK:\n$ cc_prop = true\n$ is_need = false\n$ is_need = (f$extract(0,4,cdef) .eqs. \"NEED\") .or. (test_inv .eq. true)\n$ if f$search(th) .eqs. \"\" then create 'th'\n$ set message/nofac/noident/nosever/notext\n$ on error then continue\n$ cc 'tmpnam'\n$ if .not. ($status)  then cc_prop = false\n$ on error then continue\n$! The headers might lie about the capabilities of the RTL\n$ link 'tmpnam',tmp.opt/opt\n$ if .not. ($status)  then cc_prop = false\n$ set message/fac/ident/sever/text\n$ on error then goto err_exit\n$ delete/nolog 'tmpnam'.*;*/exclude='th'\n$ if (cc_prop .and. .not. is_need) .or. -\n     (.not. cc_prop .and. is_need)\n$ then\n$   write sys$output \"Checking for ''cdef'... yes\"\n$   if f$type('cdef_val'_yes) .nes. \"\"\n$   then\n$     if f$type('cdef_val'_yes) .eqs. \"INTEGER\" -\n         then call write_config f$fao(\"#define !AS !UL\",cdef,'cdef_val'_yes)\n$     if f$type('cdef_val'_yes) .eqs. \"STRING\" -\n         then call write_config f$fao(\"#define !AS !AS\",cdef,'cdef_val'_yes)\n$   else\n$     call write_config f$fao(\"#define !AS 1\",cdef)\n$   endif\n$   if (cdef .eqs. \"HAVE_FSEEKO\") .or. (cdef .eqs. \"_LARGE_FILES\") .or. -\n       (cdef .eqs. \"_LARGEFILE64_SOURCE\") then -\n      call write_config f$string(\"#define _LARGEFILE 1\")\n$ else\n$   write sys$output \"Checking for ''cdef'... no\"\n$   if (comm_h)\n$   then\n      call write_config f$fao(\"/* !AS */\",line)\n$   else\n$     if f$type('cdef_val'_no) .nes. \"\"\n$     then\n$       if f$type('cdef_val'_no) .eqs. \"INTEGER\" -\n           then call write_config f$fao(\"#define !AS !UL\",cdef,'cdef_val'_no)\n$       if f$type('cdef_val'_no) .eqs. \"STRING\" -\n           then call write_config f$fao(\"#define !AS !AS\",cdef,'cdef_val'_no)\n$     else\n$       call write_config f$fao(\"#undef !AS\",cdef)\n$     endif\n$   endif\n$ endif\n$ return\n$!------------------------------------------------------------------------------\n$!\n$! Check for properties of C/C++ compiler with multiple result values\n$!\n$! Version history\n$! 0.01 20040127 First version\n$! 0.02 20050103 Reconcile changes from cc_prop up to version 0.05\n$CC_MPROP_CHECK:\n$ cc_prop = true\n$ i    = 1\n$ idel = 1\n$ MT_LOOP:\n$ if f$type(result_'i') .eqs. \"STRING\"\n$ then\n$   set message/nofac/noident/nosever/notext\n$   on error then continue\n$   cc 'tmpnam'_'i'\n$   if .not. ($status)  then cc_prop = false\n$   on error then continue\n$! The headers might lie about the capabilities of the RTL\n$   link 'tmpnam'_'i',tmp.opt/opt\n$   if .not. ($status)  then cc_prop = false\n$   set message/fac/ident/sever/text\n$   on error then goto err_exit\n$   delete/nolog 'tmpnam'_'i'.*;*\n$   if (cc_prop)\n$   then\n$     write sys$output \"Checking for ''cdef'... \", mdef_'i'\n$     if f$type(mdef_'i') .eqs. \"INTEGER\" -\n         then call write_config f$fao(\"#define !AS !UL\",cdef,mdef_'i')\n$     if f$type('cdef_val'_yes) .eqs. \"STRING\" -\n         then call write_config f$fao(\"#define !AS !AS\",cdef,mdef_'i')\n$     goto msym_clean\n$   else\n$     i = i + 1\n$     goto mt_loop\n$   endif\n$ endif\n$ write sys$output \"Checking for ''cdef'... no\"\n$ call write_config f$fao(\"#undef !AS\",cdef)\n$ MSYM_CLEAN:\n$ if (idel .le. msym_max)\n$ then\n$   delete/sym mdef_'idel'\n$   idel = idel + 1\n$   goto msym_clean\n$ endif\n$ return\n$!------------------------------------------------------------------------------\n$!\n$! Write configuration to both permanent and temporary config file\n$!\n$! Version history\n$! 0.01 20031029 First version to receive a number\n$!\n$WRITE_CONFIG: SUBROUTINE\n$  write aconf 'p1'\n$  open/append confh 'th'\n$  write confh 'p1'\n$  close confh\n$ENDSUBROUTINE\n$!------------------------------------------------------------------------------\n$!\n$! Analyze the project map file and create the symbol vector for a shareable\n$! image from it\n$!\n$! Version history\n$! 0.01 20120128 First version\n$! 0.02 20120226 Add pre-load logic\n$!\n$ MAP_2_SHOPT: Subroutine\n$!\n$ SAY := \"WRITE_ SYS$OUTPUT\"\n$!\n$ IF F$SEARCH(\"''P1'\") .EQS. \"\"\n$ THEN\n$    SAY \"MAP_2_SHOPT-E-NOSUCHFILE:  Error, inputfile ''p1' not available\"\n$    goto exit_m2s\n$ ENDIF\n$ IF \"''P2'\" .EQS. \"\"\n$ THEN\n$    SAY \"MAP_2_SHOPT:  Error, no output file provided\"\n$    goto exit_m2s\n$ ENDIF\n$!\n$ module1 = \"deflate#deflateEnd#deflateInit_#deflateParams#deflateSetDictionary\"\n$ module2 = \"gzclose#gzerror#gzgetc#gzgets#gzopen#gzprintf#gzputc#gzputs#gzread\"\n$ module3 = \"gzseek#gztell#inflate#inflateEnd#inflateInit_#inflateSetDictionary\"\n$ module4 = \"inflateSync#uncompress#zlibVersion#compress\"\n$ open/read map 'p1\n$ if axp .or. ia64\n$ then\n$     open/write aopt a.opt\n$     open/write bopt b.opt\n$     write aopt \" CASE_SENSITIVE=YES\"\n$     write bopt \"SYMBOL_VECTOR= (-\"\n$     mod_sym_num = 1\n$ MOD_SYM_LOOP:\n$     if f$type(module'mod_sym_num') .nes. \"\"\n$     then\n$         mod_in = 0\n$ MOD_SYM_IN:\n$         shared_proc = f$element(mod_in, \"#\", module'mod_sym_num')\n$         if shared_proc .nes. \"#\"\n$         then\n$             write aopt f$fao(\" symbol_vector=(!AS/!AS=PROCEDURE)\",-\n        \t\t       f$edit(shared_proc,\"upcase\"),shared_proc)\n$             write bopt f$fao(\"!AS=PROCEDURE,-\",shared_proc)\n$             mod_in = mod_in + 1\n$             goto mod_sym_in\n$         endif\n$         mod_sym_num = mod_sym_num + 1\n$         goto mod_sym_loop\n$     endif\n$MAP_LOOP:\n$     read/end=map_end map line\n$     if (f$locate(\"{\",line).lt. f$length(line)) .or. -\n         (f$locate(\"global:\", line) .lt. f$length(line))\n$     then\n$         proc = true\n$         goto map_loop\n$     endif\n$     if f$locate(\"}\",line).lt. f$length(line) then proc = false\n$     if f$locate(\"local:\", line) .lt. f$length(line) then proc = false\n$     if proc\n$     then\n$         shared_proc = f$edit(line,\"collapse\")\n$         chop_semi = f$locate(\";\", shared_proc)\n$         if chop_semi .lt. f$length(shared_proc) then -\n              shared_proc = f$extract(0, chop_semi, shared_proc)\n$         write aopt f$fao(\" symbol_vector=(!AS/!AS=PROCEDURE)\",-\n        \t\t\t f$edit(shared_proc,\"upcase\"),shared_proc)\n$         write bopt f$fao(\"!AS=PROCEDURE,-\",shared_proc)\n$     endif\n$     goto map_loop\n$MAP_END:\n$     close/nolog aopt\n$     close/nolog bopt\n$     open/append libopt 'p2'\n$     open/read aopt a.opt\n$     open/read bopt b.opt\n$ALOOP:\n$     read/end=aloop_end aopt line\n$     write libopt line\n$     goto aloop\n$ALOOP_END:\n$     close/nolog aopt\n$     sv = \"\"\n$BLOOP:\n$     read/end=bloop_end bopt svn\n$     if (svn.nes.\"\")\n$     then\n$        if (sv.nes.\"\") then write libopt sv\n$        sv = svn\n$     endif\n$     goto bloop\n$BLOOP_END:\n$     write libopt f$extract(0,f$length(sv)-2,sv), \"-\"\n$     write libopt \")\"\n$     close/nolog bopt\n$     delete/nolog/noconf a.opt;*,b.opt;*\n$ else\n$     if vax\n$     then\n$     open/append libopt 'p2'\n$     mod_sym_num = 1\n$ VMOD_SYM_LOOP:\n$     if f$type(module'mod_sym_num') .nes. \"\"\n$     then\n$         mod_in = 0\n$ VMOD_SYM_IN:\n$         shared_proc = f$element(mod_in, \"#\", module'mod_sym_num')\n$         if shared_proc .nes. \"#\"\n$         then\n$     \t      write libopt f$fao(\"UNIVERSAL=!AS\",-\n      \t  \t\t\t     f$edit(shared_proc,\"upcase\"))\n$             mod_in = mod_in + 1\n$             goto vmod_sym_in\n$         endif\n$         mod_sym_num = mod_sym_num + 1\n$         goto vmod_sym_loop\n$     endif\n$VMAP_LOOP:\n$     \t  read/end=vmap_end map line\n$     \t  if (f$locate(\"{\",line).lt. f$length(line)) .or. -\n   \t      (f$locate(\"global:\", line) .lt. f$length(line))\n$     \t  then\n$     \t      proc = true\n$     \t      goto vmap_loop\n$     \t  endif\n$     \t  if f$locate(\"}\",line).lt. f$length(line) then proc = false\n$     \t  if f$locate(\"local:\", line) .lt. f$length(line) then proc = false\n$     \t  if proc\n$     \t  then\n$     \t      shared_proc = f$edit(line,\"collapse\")\n$     \t      chop_semi = f$locate(\";\", shared_proc)\n$     \t      if chop_semi .lt. f$length(shared_proc) then -\n      \t  \t  shared_proc = f$extract(0, chop_semi, shared_proc)\n$     \t      write libopt f$fao(\"UNIVERSAL=!AS\",-\n      \t  \t\t\t     f$edit(shared_proc,\"upcase\"))\n$     \t  endif\n$     \t  goto vmap_loop\n$VMAP_END:\n$     else\n$         write sys$output \"Unknown Architecture (Not VAX, AXP, or IA64)\"\n$         write sys$output \"No options file created\"\n$     endif\n$ endif\n$ EXIT_M2S:\n$ close/nolog map\n$ close/nolog libopt\n$ endsubroutine\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/msdos/Makefile.bor",
    "content": "# Makefile for zlib\n# Borland C++\n# Last updated: 15-Mar-2003\n\n# To use, do \"make -fmakefile.bor\"\n# To compile in small model, set below: MODEL=s\n\n# WARNING: the small model is supported but only for small values of\n# MAX_WBITS and MAX_MEM_LEVEL. For example:\n#    -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3\n# If you wish to reduce the memory requirements (default 256K for big\n# objects plus a few K), you can add to the LOC macro below:\n#   -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14\n# See zconf.h for details about the memory requirements.\n\n# ------------ Turbo C++, Borland C++ ------------\n\n#    Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)\n#    should be added to the environment via \"set LOCAL_ZLIB=-DFOO\" or added\n#    to the declaration of LOC here:\nLOC = $(LOCAL_ZLIB)\n\n# type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.\nCPU_TYP = 0\n\n# memory model: one of s, m, c, l (small, medium, compact, large)\nMODEL=l\n\n# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version\nCC=bcc\nLD=bcc\nAR=tlib\n\n# compiler flags\n# replace \"-O2\" by \"-O -G -a -d\" for Turbo C++ 1.0\nCFLAGS=-O2 -Z -m$(MODEL) $(LOC)\n\nLDFLAGS=-m$(MODEL) -f-\n\n\n# variables\nZLIB_LIB = zlib_$(MODEL).lib\n\nOBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj\nOBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj\nOBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj\nOBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj\n\n\n# targets\nall: $(ZLIB_LIB) example.exe minigzip.exe\n\n.c.obj:\n\t$(CC) -c $(CFLAGS) $*.c\n\nadler32.obj: adler32.c zlib.h zconf.h\n\ncompress.obj: compress.c zlib.h zconf.h\n\ncrc32.obj: crc32.c zlib.h zconf.h crc32.h\n\ndeflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h\n\ngzclose.obj: gzclose.c zlib.h zconf.h gzguts.h\n\ngzlib.obj: gzlib.c zlib.h zconf.h gzguts.h\n\ngzread.obj: gzread.c zlib.h zconf.h gzguts.h\n\ngzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h\n\ninfback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h inffixed.h\n\ninffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h\n\ninflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h inffixed.h\n\ninftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h\n\ntrees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h\n\nuncompr.obj: uncompr.c zlib.h zconf.h\n\nzutil.obj: zutil.c zutil.h zlib.h zconf.h\n\nexample.obj: test/example.c zlib.h zconf.h\n\nminigzip.obj: test/minigzip.c zlib.h zconf.h\n\n\n# the command line is cut to fit in the MS-DOS 128 byte limit:\n$(ZLIB_LIB): $(OBJ1) $(OBJ2)\n\t-del $(ZLIB_LIB)\n\t$(AR) $(ZLIB_LIB) $(OBJP1)\n\t$(AR) $(ZLIB_LIB) $(OBJP2)\n\nexample.exe: example.obj $(ZLIB_LIB)\n\t$(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)\n\nminigzip.exe: minigzip.obj $(ZLIB_LIB)\n\t$(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)\n\ntest: example.exe minigzip.exe\n\texample\n\techo hello world | minigzip | minigzip -d\n\nclean:\n\t-del *.obj\n\t-del *.lib\n\t-del *.exe\n\t-del zlib_*.bak\n\t-del foo.gz\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/msdos/Makefile.dj2",
    "content": "# Makefile for zlib.  Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96.\n# Copyright (C) 1995-1998 Jean-loup Gailly.\n# For conditions of distribution and use, see copyright notice in zlib.h\n\n# To compile, or to compile and test, type:\n#\n#   make -fmakefile.dj2;  make test -fmakefile.dj2\n#\n# To install libz.a, zconf.h and zlib.h in the djgpp directories, type:\n#\n#    make install -fmakefile.dj2\n#\n# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as\n# in the sample below if the pattern of the DJGPP distribution is to\n# be followed.  Remember that, while <sp>'es around <=> are ignored in\n# makefiles, they are *not* in batch files or in djgpp.env.\n# - - - - -\n# [make]\n# INCLUDE_PATH=%\\>;INCLUDE_PATH%%\\DJDIR%\\include\n# LIBRARY_PATH=%\\>;LIBRARY_PATH%%\\DJDIR%\\lib\n# BUTT=-m486\n# - - - - -\n# Alternately, these variables may be defined below, overriding the values\n# in djgpp.env, as\n# INCLUDE_PATH=c:\\usr\\include\n# LIBRARY_PATH=c:\\usr\\lib\n\nCC=gcc\n\n#CFLAGS=-MMD -O\n#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7\n#CFLAGS=-MMD -g -DDEBUG\nCFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \\\n             -Wstrict-prototypes -Wmissing-prototypes\n\n# If cp.exe is available, replace \"copy /Y\" with \"cp -fp\" .\nCP=copy /Y\n# If gnu install.exe is available, replace $(CP) with ginstall.\nINSTALL=$(CP)\n# The default value of RM is \"rm -f.\"  If \"rm.exe\" is found, comment out:\nRM=del\nLDLIBS=-L. -lz\nLD=$(CC) -s -o\nLDSHARED=$(CC)\n\nINCL=zlib.h zconf.h\nLIBS=libz.a\n\nAR=ar rcs\n\nprefix=/usr/local\nexec_prefix = $(prefix)\n\nOBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \\\n       uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o\n\nOBJA =\n# to use the asm code: make OBJA=match.o\n\nTEST_OBJS = example.o minigzip.o\n\nall: example.exe minigzip.exe\n\ncheck: test\ntest: all\n\t./example\n\techo hello world | .\\minigzip | .\\minigzip -d\n\n%.o : %.c\n\t$(CC) $(CFLAGS) -c $< -o $@\n\nlibz.a: $(OBJS) $(OBJA)\n\t$(AR) $@ $(OBJS) $(OBJA)\n\n%.exe : %.o $(LIBS)\n\t$(LD) $@ $< $(LDLIBS)\n\n# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env .\n\n.PHONY : uninstall clean\n\ninstall: $(INCL) $(LIBS)\n\t-@if not exist $(INCLUDE_PATH)\\nul mkdir $(INCLUDE_PATH)\n\t-@if not exist $(LIBRARY_PATH)\\nul mkdir $(LIBRARY_PATH)\n\t$(INSTALL) zlib.h $(INCLUDE_PATH)\n\t$(INSTALL) zconf.h $(INCLUDE_PATH)\n\t$(INSTALL) libz.a $(LIBRARY_PATH)\n\nuninstall:\n\t$(RM) $(INCLUDE_PATH)\\zlib.h\n\t$(RM) $(INCLUDE_PATH)\\zconf.h\n\t$(RM) $(LIBRARY_PATH)\\libz.a\n\nclean:\n\t$(RM) *.d\n\t$(RM) *.o\n\t$(RM) *.exe\n\t$(RM) libz.a\n\t$(RM) foo.gz\n\nDEPS := $(wildcard *.d)\nifneq ($(DEPS),)\ninclude $(DEPS)\nendif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/msdos/Makefile.emx",
    "content": "# Makefile for zlib.  Modified for emx 0.9c by Chr. Spieler, 6/17/98.\n# Copyright (C) 1995-1998 Jean-loup Gailly.\n# For conditions of distribution and use, see copyright notice in zlib.h\n\n# To compile, or to compile and test, type:\n#\n#   make -fmakefile.emx;  make test -fmakefile.emx\n#\n\nCC=gcc\n\n#CFLAGS=-MMD -O\n#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7\n#CFLAGS=-MMD -g -DDEBUG\nCFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \\\n             -Wstrict-prototypes -Wmissing-prototypes\n\n# If cp.exe is available, replace \"copy /Y\" with \"cp -fp\" .\nCP=copy /Y\n# If gnu install.exe is available, replace $(CP) with ginstall.\nINSTALL=$(CP)\n# The default value of RM is \"rm -f.\"  If \"rm.exe\" is found, comment out:\nRM=del\nLDLIBS=-L. -lzlib\nLD=$(CC) -s -o\nLDSHARED=$(CC)\n\nINCL=zlib.h zconf.h\nLIBS=zlib.a\n\nAR=ar rcs\n\nprefix=/usr/local\nexec_prefix = $(prefix)\n\nOBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \\\n       uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o\n\nTEST_OBJS = example.o minigzip.o\n\nall: example.exe minigzip.exe\n\ntest: all\n\t./example\n\techo hello world | .\\minigzip | .\\minigzip -d\n\n%.o : %.c\n\t$(CC) $(CFLAGS) -c $< -o $@\n\nzlib.a: $(OBJS)\n\t$(AR) $@ $(OBJS)\n\n%.exe : %.o $(LIBS)\n\t$(LD) $@ $< $(LDLIBS)\n\n\n.PHONY : clean\n\nclean:\n\t$(RM) *.d\n\t$(RM) *.o\n\t$(RM) *.exe\n\t$(RM) zlib.a\n\t$(RM) foo.gz\n\nDEPS := $(wildcard *.d)\nifneq ($(DEPS),)\ninclude $(DEPS)\nendif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/msdos/Makefile.msc",
    "content": "# Makefile for zlib\n# Microsoft C 5.1 or later\n# Last updated: 19-Mar-2003\n\n# To use, do \"make makefile.msc\"\n# To compile in small model, set below: MODEL=S\n\n# If you wish to reduce the memory requirements (default 256K for big\n# objects plus a few K), you can add to the LOC macro below:\n#   -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14\n# See zconf.h for details about the memory requirements.\n\n# ------------- Microsoft C 5.1 and later -------------\n\n#    Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)\n#    should be added to the environment via \"set LOCAL_ZLIB=-DFOO\" or added\n#    to the declaration of LOC here:\nLOC = $(LOCAL_ZLIB)\n\n# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.\nCPU_TYP = 0\n\n# Memory model: one of S, M, C, L (small, medium, compact, large)\nMODEL=L\n\nCC=cl\nCFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC)\n#-Ox generates bad code with MSC 5.1\nLIB_CFLAGS=-Zl $(CFLAGS)\n\nLD=link\nLDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode\n# \"/farcall/packcode\" are only useful for `large code' memory models\n# but should be a \"no-op\" for small code models.\n\n\n# variables\nZLIB_LIB = zlib_$(MODEL).lib\n\nOBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj\nOBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj\n\n\n# targets\nall:  $(ZLIB_LIB) example.exe minigzip.exe\n\n.c.obj:\n\t$(CC) -c $(LIB_CFLAGS) $*.c\n\nadler32.obj: adler32.c zlib.h zconf.h\n\ncompress.obj: compress.c zlib.h zconf.h\n\ncrc32.obj: crc32.c zlib.h zconf.h crc32.h\n\ndeflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h\n\ngzclose.obj: gzclose.c zlib.h zconf.h gzguts.h\n\ngzlib.obj: gzlib.c zlib.h zconf.h gzguts.h\n\ngzread.obj: gzread.c zlib.h zconf.h gzguts.h\n\ngzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h\n\ninfback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h inffixed.h\n\ninffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h\n\ninflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h inffixed.h\n\ninftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h\n\ntrees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h\n\nuncompr.obj: uncompr.c zlib.h zconf.h\n\nzutil.obj: zutil.c zutil.h zlib.h zconf.h\n\nexample.obj: test/example.c zlib.h zconf.h\n\t$(CC) -c $(CFLAGS) $*.c\n\nminigzip.obj: test/minigzip.c zlib.h zconf.h\n\t$(CC) -c $(CFLAGS) $*.c\n\n\n# the command line is cut to fit in the MS-DOS 128 byte limit:\n$(ZLIB_LIB): $(OBJ1) $(OBJ2)\n\tif exist $(ZLIB_LIB) del $(ZLIB_LIB)\n\tlib $(ZLIB_LIB) $(OBJ1);\n\tlib $(ZLIB_LIB) $(OBJ2);\n\nexample.exe: example.obj $(ZLIB_LIB)\n\t$(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB);\n\nminigzip.exe: minigzip.obj $(ZLIB_LIB)\n\t$(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB);\n\ntest: example.exe minigzip.exe\n\texample\n\techo hello world | minigzip | minigzip -d\n\nclean:\n\t-del *.obj\n\t-del *.lib\n\t-del *.exe\n\t-del *.map\n\t-del zlib_*.bak\n\t-del foo.gz\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/msdos/Makefile.tc",
    "content": "# Makefile for zlib\n# Turbo C 2.01, Turbo C++ 1.01\n# Last updated: 15-Mar-2003\n\n# To use, do \"make -fmakefile.tc\"\n# To compile in small model, set below: MODEL=s\n\n# WARNING: the small model is supported but only for small values of\n# MAX_WBITS and MAX_MEM_LEVEL. For example:\n#    -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3\n# If you wish to reduce the memory requirements (default 256K for big\n# objects plus a few K), you can add to CFLAGS below:\n#   -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14\n# See zconf.h for details about the memory requirements.\n\n# ------------ Turbo C 2.01, Turbo C++ 1.01 ------------\nMODEL=l\nCC=tcc\nLD=tcc\nAR=tlib\n# CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3\nCFLAGS=-O2 -G -Z -m$(MODEL)\nLDFLAGS=-m$(MODEL) -f-\n\n\n# variables\nZLIB_LIB = zlib_$(MODEL).lib\n\nOBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj\nOBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj\nOBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj\nOBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj\n\n\n# targets\nall: $(ZLIB_LIB) example.exe minigzip.exe\n\n.c.obj:\n\t$(CC) -c $(CFLAGS) $*.c\n\nadler32.obj: adler32.c zlib.h zconf.h\n\ncompress.obj: compress.c zlib.h zconf.h\n\ncrc32.obj: crc32.c zlib.h zconf.h crc32.h\n\ndeflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h\n\ngzclose.obj: gzclose.c zlib.h zconf.h gzguts.h\n\ngzlib.obj: gzlib.c zlib.h zconf.h gzguts.h\n\ngzread.obj: gzread.c zlib.h zconf.h gzguts.h\n\ngzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h\n\ninfback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h inffixed.h\n\ninffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h\n\ninflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h inffixed.h\n\ninftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h\n\ntrees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h\n\nuncompr.obj: uncompr.c zlib.h zconf.h\n\nzutil.obj: zutil.c zutil.h zlib.h zconf.h\n\nexample.obj: test/example.c zlib.h zconf.h\n\nminigzip.obj: test/minigzip.c zlib.h zconf.h\n\n\n# the command line is cut to fit in the MS-DOS 128 byte limit:\n$(ZLIB_LIB): $(OBJ1) $(OBJ2)\n\t-del $(ZLIB_LIB)\n\t$(AR) $(ZLIB_LIB) $(OBJP1)\n\t$(AR) $(ZLIB_LIB) $(OBJP2)\n\nexample.exe: example.obj $(ZLIB_LIB)\n\t$(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)\n\nminigzip.exe: minigzip.obj $(ZLIB_LIB)\n\t$(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)\n\ntest: example.exe minigzip.exe\n\texample\n\techo hello world | minigzip | minigzip -d\n\nclean:\n\t-del *.obj\n\t-del *.lib\n\t-del *.exe\n\t-del zlib_*.bak\n\t-del foo.gz\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/nintendods/Makefile",
    "content": "#---------------------------------------------------------------------------------\n.SUFFIXES:\n#---------------------------------------------------------------------------------\n\nifeq ($(strip $(DEVKITARM)),)\n$(error \"Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM\")\nendif\n\ninclude $(DEVKITARM)/ds_rules\n\n#---------------------------------------------------------------------------------\n# TARGET is the name of the output\n# BUILD is the directory where object files & intermediate files will be placed\n# SOURCES is a list of directories containing source code\n# DATA is a list of directories containing data files\n# INCLUDES is a list of directories containing header files\n#---------------------------------------------------------------------------------\nTARGET\t\t:=\t$(shell basename $(CURDIR))\nBUILD\t\t:=\tbuild\nSOURCES\t\t:=\t../../\nDATA\t\t:=\tdata\nINCLUDES\t:=\tinclude\n\n#---------------------------------------------------------------------------------\n# options for code generation\n#---------------------------------------------------------------------------------\nARCH\t:=\t-mthumb -mthumb-interwork\n\nCFLAGS\t:=\t-Wall -O2\\\n\t\t-march=armv5te -mtune=arm946e-s \\\n\t\t-fomit-frame-pointer -ffast-math \\\n\t\t$(ARCH)\n\nCFLAGS\t+=\t$(INCLUDE) -DARM9\nCXXFLAGS\t:= $(CFLAGS) -fno-rtti -fno-exceptions\n\nASFLAGS\t:=\t$(ARCH) -march=armv5te -mtune=arm946e-s\nLDFLAGS\t=\t-specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)\n\n#---------------------------------------------------------------------------------\n# list of directories containing libraries, this must be the top level containing\n# include and lib\n#---------------------------------------------------------------------------------\nLIBDIRS\t:=\t$(LIBNDS)\n\n#---------------------------------------------------------------------------------\n# no real need to edit anything past this point unless you need to add additional\n# rules for different file extensions\n#---------------------------------------------------------------------------------\nifneq ($(BUILD),$(notdir $(CURDIR)))\n#---------------------------------------------------------------------------------\n\nexport OUTPUT\t:=\t$(CURDIR)/lib/libz.a\n\nexport VPATH\t:=\t$(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \\\n\t\t\t$(foreach dir,$(DATA),$(CURDIR)/$(dir))\n\nexport DEPSDIR\t:=\t$(CURDIR)/$(BUILD)\n\nCFILES\t\t:=\t$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))\nCPPFILES\t:=\t$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))\nSFILES\t\t:=\t$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))\nBINFILES\t:=\t$(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))\n\n#---------------------------------------------------------------------------------\n# use CXX for linking C++ projects, CC for standard C\n#---------------------------------------------------------------------------------\nifeq ($(strip $(CPPFILES)),)\n#---------------------------------------------------------------------------------\n\texport LD\t:=\t$(CC)\n#---------------------------------------------------------------------------------\nelse\n#---------------------------------------------------------------------------------\n\texport LD\t:=\t$(CXX)\n#---------------------------------------------------------------------------------\nendif\n#---------------------------------------------------------------------------------\n\nexport OFILES\t:=\t$(addsuffix .o,$(BINFILES)) \\\n\t\t\t$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)\n\nexport INCLUDE\t:=\t$(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \\\n\t\t\t$(foreach dir,$(LIBDIRS),-I$(dir)/include) \\\n\t\t\t-I$(CURDIR)/$(BUILD)\n\n.PHONY: $(BUILD) clean all\n\n#---------------------------------------------------------------------------------\nall: $(BUILD)\n\t@[ -d $@ ] || mkdir -p include\n\t@cp ../../*.h include\n\nlib:\n\t@[ -d $@ ] || mkdir -p $@\n\t\n$(BUILD): lib\n\t@[ -d $@ ] || mkdir -p $@\n\t@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile\n\n#---------------------------------------------------------------------------------\nclean:\n\t@echo clean ...\n\t@rm -fr $(BUILD) lib\n\n#---------------------------------------------------------------------------------\nelse\n\nDEPENDS\t:=\t$(OFILES:.o=.d)\n\n#---------------------------------------------------------------------------------\n# main targets\n#---------------------------------------------------------------------------------\n$(OUTPUT)\t:\t$(OFILES)\n\n#---------------------------------------------------------------------------------\n%.bin.o\t:\t%.bin\n#---------------------------------------------------------------------------------\n\t@echo $(notdir $<)\n\t@$(bin2o)\n\n\n-include $(DEPENDS)\n\n#---------------------------------------------------------------------------------------\nendif\n#---------------------------------------------------------------------------------------\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/nintendods/README",
    "content": "This Makefile requires devkitARM (http://www.devkitpro.org/category/devkitarm/) and works inside \"contrib/nds\". It is based on a devkitARM template.\n\nEduardo Costa <eduardo.m.costa@gmail.com>\nJanuary 3, 2009\n\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/old/Makefile.emx",
    "content": "# Makefile for zlib.  Modified for emx/rsxnt by Chr. Spieler, 6/16/98.\n# Copyright (C) 1995-1998 Jean-loup Gailly.\n# For conditions of distribution and use, see copyright notice in zlib.h\n\n# To compile, or to compile and test, type:\n#\n#   make -fmakefile.emx;  make test -fmakefile.emx\n#\n\nCC=gcc -Zwin32\n\n#CFLAGS=-MMD -O\n#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7\n#CFLAGS=-MMD -g -DDEBUG\nCFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \\\n             -Wstrict-prototypes -Wmissing-prototypes\n\n# If cp.exe is available, replace \"copy /Y\" with \"cp -fp\" .\nCP=copy /Y\n# If gnu install.exe is available, replace $(CP) with ginstall.\nINSTALL=$(CP)\n# The default value of RM is \"rm -f.\"  If \"rm.exe\" is found, comment out:\nRM=del\nLDLIBS=-L. -lzlib\nLD=$(CC) -s -o\nLDSHARED=$(CC)\n\nINCL=zlib.h zconf.h\nLIBS=zlib.a\n\nAR=ar rcs\n\nprefix=/usr/local\nexec_prefix = $(prefix)\n\nOBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \\\n       gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o\n\nTEST_OBJS = example.o minigzip.o\n\nall: example.exe minigzip.exe\n\ntest: all\n\t./example\n\techo hello world | .\\minigzip | .\\minigzip -d\n\n%.o : %.c\n\t$(CC) $(CFLAGS) -c $< -o $@\n\nzlib.a: $(OBJS)\n\t$(AR) $@ $(OBJS)\n\n%.exe : %.o $(LIBS)\n\t$(LD) $@ $< $(LDLIBS)\n\n\n.PHONY : clean\n\nclean:\n\t$(RM) *.d\n\t$(RM) *.o\n\t$(RM) *.exe\n\t$(RM) zlib.a\n\t$(RM) foo.gz\n\nDEPS := $(wildcard *.d)\nifneq ($(DEPS),)\ninclude $(DEPS)\nendif\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/old/Makefile.riscos",
    "content": "# Project:   zlib_1_03\n# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430\n# test works out-of-the-box, installs `somewhere' on demand\n\n# Toolflags:\nCCflags = -c -depend !Depend -IC: -g -throwback  -DRISCOS  -fah\nC++flags = -c -depend !Depend -IC: -throwback\nLinkflags = -aif -c++ -o $@\nObjAsmflags = -throwback -NoCache -depend !Depend\nCMHGflags =\nLibFileflags = -c -l -o $@\nSqueezeflags = -o $@\n\n# change the line below to where _you_ want the library installed.\nlibdest = lib:zlib\n\n# Final targets:\n@.lib:   @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \\\n        @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \\\n        @.o.uncompr @.o.zutil\n        LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \\\n        @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \\\n        @.o.trees @.o.uncompr @.o.zutil\ntest:   @.minigzip @.example @.lib\n\t@copy @.lib @.libc  A~C~DF~L~N~P~Q~RS~TV\n\t@echo running tests: hang on.\n\t@/@.minigzip -f -9 libc\n\t@/@.minigzip -d libc-gz\n\t@/@.minigzip -f -1 libc\n\t@/@.minigzip -d libc-gz\n\t@/@.minigzip -h -9 libc\n\t@/@.minigzip -d libc-gz\n\t@/@.minigzip -h -1 libc\n\t@/@.minigzip -d libc-gz\n\t@/@.minigzip -9 libc\n\t@/@.minigzip -d libc-gz\n\t@/@.minigzip -1 libc\n\t@/@.minigzip -d libc-gz\n\t@diff @.lib @.libc\n\t@echo that should have reported '@.lib and @.libc identical' if you have diff.\n\t@/@.example @.fred @.fred\n\t@echo that will have given lots of hello!'s.\n\n@.minigzip:   @.o.minigzip @.lib C:o.Stubs\n        Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs\n@.example:   @.o.example @.lib C:o.Stubs\n        Link $(Linkflags) @.o.example @.lib C:o.Stubs\n\ninstall: @.lib\n\tcdir $(libdest)\n\tcdir $(libdest).h\n\t@copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV\n\t@copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV\n\t@copy @.lib $(libdest).lib  A~C~DF~L~N~P~Q~RS~TV\n\t@echo okay, installed zlib in $(libdest)\n\nclean:; remove @.minigzip\n\tremove @.example\n\tremove @.libc\n\t-wipe @.o.* F~r~cV\n\tremove @.fred\n\n# User-editable dependencies:\n.c.o:\n        cc $(ccflags) -o $@ $<\n\n# Static dependencies:\n\n# Dynamic dependencies:\no.example:\tc.example\no.example:\th.zlib\no.example:\th.zconf\no.minigzip:\tc.minigzip\no.minigzip:\th.zlib\no.minigzip:\th.zconf\no.adler32:\tc.adler32\no.adler32:\th.zlib\no.adler32:\th.zconf\no.compress:\tc.compress\no.compress:\th.zlib\no.compress:\th.zconf\no.crc32:\tc.crc32\no.crc32:\th.zlib\no.crc32:\th.zconf\no.deflate:\tc.deflate\no.deflate:\th.deflate\no.deflate:\th.zutil\no.deflate:\th.zlib\no.deflate:\th.zconf\no.gzio:\tc.gzio\no.gzio:\th.zutil\no.gzio:\th.zlib\no.gzio:\th.zconf\no.infblock:\tc.infblock\no.infblock:\th.zutil\no.infblock:\th.zlib\no.infblock:\th.zconf\no.infblock:\th.infblock\no.infblock:\th.inftrees\no.infblock:\th.infcodes\no.infblock:\th.infutil\no.infcodes:\tc.infcodes\no.infcodes:\th.zutil\no.infcodes:\th.zlib\no.infcodes:\th.zconf\no.infcodes:\th.inftrees\no.infcodes:\th.infblock\no.infcodes:\th.infcodes\no.infcodes:\th.infutil\no.infcodes:\th.inffast\no.inffast:\tc.inffast\no.inffast:\th.zutil\no.inffast:\th.zlib\no.inffast:\th.zconf\no.inffast:\th.inftrees\no.inffast:\th.infblock\no.inffast:\th.infcodes\no.inffast:\th.infutil\no.inffast:\th.inffast\no.inflate:\tc.inflate\no.inflate:\th.zutil\no.inflate:\th.zlib\no.inflate:\th.zconf\no.inflate:\th.infblock\no.inftrees:\tc.inftrees\no.inftrees:\th.zutil\no.inftrees:\th.zlib\no.inftrees:\th.zconf\no.inftrees:\th.inftrees\no.inftrees:\th.inffixed\no.infutil:\tc.infutil\no.infutil:\th.zutil\no.infutil:\th.zlib\no.infutil:\th.zconf\no.infutil:\th.infblock\no.infutil:\th.inftrees\no.infutil:\th.infcodes\no.infutil:\th.infutil\no.trees:\tc.trees\no.trees:\th.deflate\no.trees:\th.zutil\no.trees:\th.zlib\no.trees:\th.zconf\no.trees:\th.trees\no.uncompr:\tc.uncompr\no.uncompr:\th.zlib\no.uncompr:\th.zconf\no.zutil:\tc.zutil\no.zutil:\th.zutil\no.zutil:\th.zlib\no.zutil:\th.zconf\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/old/README",
    "content": "This directory contains files that have not been updated for zlib 1.2.x\n\n(Volunteers are encouraged to help clean this up.  Thanks.)\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/old/descrip.mms",
    "content": "# descrip.mms: MMS description file for building zlib on VMS\n# written by Martin P.J. Zinser <m.zinser@gsi.de>\n\ncc_defs =\nc_deb =\n\n.ifdef __DECC__\npref = /prefix=all\n.endif\n\nOBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\\\n       deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\\\n       inftrees.obj, infcodes.obj, infutil.obj, inffast.obj\n\nCFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)\n\nall : example.exe minigzip.exe\n        @ write sys$output \" Example applications available\"\nlibz.olb : libz.olb($(OBJS))\n\t@ write sys$output \" libz available\"\n\nexample.exe : example.obj libz.olb\n              link example,libz.olb/lib\n\nminigzip.exe : minigzip.obj libz.olb\n              link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib\n\nclean :\n\tdelete *.obj;*,libz.olb;*\n\n\n# Other dependencies.\nadler32.obj : zutil.h zlib.h zconf.h\ncompress.obj : zlib.h zconf.h\ncrc32.obj : zutil.h zlib.h zconf.h\ndeflate.obj : deflate.h zutil.h zlib.h zconf.h\nexample.obj : zlib.h zconf.h\ngzio.obj : zutil.h zlib.h zconf.h\ninfblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h\ninfcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h\ninffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h\ninflate.obj : zutil.h zlib.h zconf.h infblock.h\ninftrees.obj : zutil.h zlib.h zconf.h inftrees.h\ninfutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h\nminigzip.obj : zlib.h zconf.h\ntrees.obj : deflate.h zutil.h zlib.h zconf.h\nuncompr.obj : zlib.h zconf.h\nzutil.obj : zutil.h zlib.h zconf.h\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/old/os2/Makefile.os2",
    "content": "# Makefile for zlib under OS/2 using GCC (PGCC)\n# For conditions of distribution and use, see copyright notice in zlib.h\n\n# To compile and test, type:\n#   cp Makefile.os2 ..\n#   cd ..\n#   make -f Makefile.os2 test\n\n# This makefile will build a static library z.lib, a shared library\n# z.dll and a import library zdll.lib. You can use either z.lib or\n# zdll.lib by specifying either -lz or -lzdll on gcc's command line\n\nCC=gcc -Zomf -s\n\nCFLAGS=-O6 -Wall\n#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7\n#CFLAGS=-g -DDEBUG\n#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \\\n#           -Wstrict-prototypes -Wmissing-prototypes\n\n#################### BUG WARNING: #####################\n## infcodes.c hits a bug in pgcc-1.0, so you have to use either\n## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem)\n## This bug is reportedly fixed in pgcc >1.0, but this was not tested\nCFLAGS+=-fno-force-mem\n\nLDFLAGS=-s -L. -lzdll -Zcrtdll\nLDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll\n\nVER=1.1.0\nZLIB=z.lib\nSHAREDLIB=z.dll\nSHAREDLIBIMP=zdll.lib\nLIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP)\n\nAR=emxomfar cr\nIMPLIB=emximp\nRANLIB=echo\nTAR=tar\nSHELL=bash\n\nprefix=/usr/local\nexec_prefix = $(prefix)\n\nOBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \\\n       zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o\n\nTEST_OBJS = example.o minigzip.o\n\nDISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \\\n  algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \\\n  nt/Makefile.nt nt/zlib.dnt  contrib/README.contrib contrib/*.txt \\\n  contrib/asm386/*.asm contrib/asm386/*.c \\\n  contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \\\n  contrib/iostream/*.h  contrib/iostream2/*.h contrib/iostream2/*.cpp \\\n  contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32\n\nall: example.exe minigzip.exe\n\ntest: all\n\t@LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \\\n\techo hello world | ./minigzip | ./minigzip -d || \\\n\t  echo '\t\t*** minigzip test FAILED ***' ; \\\n\tif ./example; then \\\n\t  echo '\t\t*** zlib test OK ***'; \\\n\telse \\\n\t  echo '\t\t*** zlib test FAILED ***'; \\\n\tfi\n\n$(ZLIB): $(OBJS)\n\t$(AR) $@ $(OBJS)\n\t-@ ($(RANLIB) $@ || true) >/dev/null 2>&1\n\n$(SHAREDLIB): $(OBJS) os2/z.def\n\t$(LDSHARED) -o $@ $^\n\n$(SHAREDLIBIMP): os2/z.def\n\t$(IMPLIB) -o $@ $^\n\nexample.exe: example.o $(LIBS)\n\t$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)\n\nminigzip.exe: minigzip.o $(LIBS)\n\t$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)\n\nclean:\n\trm -f *.o *~ example minigzip libz.a libz.so* foo.gz\n\ndistclean:\tclean\n\nzip:\n\tmv Makefile Makefile~; cp -p Makefile.in Makefile\n\trm -f test.c ztest*.c\n\tv=`sed -n -e 's/\\.//g' -e '/VERSION \"/s/.*\"\\(.*\\)\".*/\\1/p' < zlib.h`;\\\n\tzip -ul9 zlib$$v $(DISTFILES)\n\tmv Makefile~ Makefile\n\ndist:\n\tmv Makefile Makefile~; cp -p Makefile.in Makefile\n\trm -f test.c ztest*.c\n\td=zlib-`sed -n '/VERSION \"/s/.*\"\\(.*\\)\".*/\\1/p' < zlib.h`;\\\n\trm -f $$d.tar.gz; \\\n\tif test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \\\n\tfiles=\"\"; \\\n\tfor f in $(DISTFILES); do files=\"$$files $$d/$$f\"; done; \\\n\tcd ..; \\\n\tGZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \\\n\tif test ! -d $$d; then rm -f $$d; fi\n\tmv Makefile~ Makefile\n\ntags:\n\tetags *.[ch]\n\ndepend:\n\tmakedepend -- $(CFLAGS) -- *.[ch]\n\n# DO NOT DELETE THIS LINE -- make depend depends on it.\n\nadler32.o: zlib.h zconf.h\ncompress.o: zlib.h zconf.h\ncrc32.o: zlib.h zconf.h\ndeflate.o: deflate.h zutil.h zlib.h zconf.h\nexample.o: zlib.h zconf.h\ngzio.o: zutil.h zlib.h zconf.h\ninfblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h\ninfcodes.o: zutil.h zlib.h zconf.h\ninfcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h\ninffast.o: zutil.h zlib.h zconf.h inftrees.h\ninffast.o: infblock.h infcodes.h infutil.h inffast.h\ninflate.o: zutil.h zlib.h zconf.h infblock.h\ninftrees.o: zutil.h zlib.h zconf.h inftrees.h\ninfutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h\nminigzip.o: zlib.h zconf.h\ntrees.o: deflate.h zutil.h zlib.h zconf.h trees.h\nuncompr.o: zlib.h zconf.h\nzutil.o: zutil.h zlib.h zconf.h\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/old/os2/zlib.def",
    "content": ";\n; Slightly modified version of ../nt/zlib.dnt :-)\n;\n\nLIBRARY\t\tZ\nDESCRIPTION\t\"Zlib compression library for OS/2\"\nCODE\t\tPRELOAD MOVEABLE DISCARDABLE\nDATA\t\tPRELOAD MOVEABLE MULTIPLE\n\nEXPORTS\n    adler32\n    compress\n    crc32\n    deflate\n    deflateCopy\n    deflateEnd\n    deflateInit2_\n    deflateInit_\n    deflateParams\n    deflateReset\n    deflateSetDictionary\n    gzclose\n    gzdopen\n    gzerror\n    gzflush\n    gzopen\n    gzread\n    gzwrite\n    inflate\n    inflateEnd\n    inflateInit2_\n    inflateInit_\n    inflateReset\n    inflateSetDictionary\n    inflateSync\n    uncompress\n    zlibVersion\n    gzprintf\n    gzputc\n    gzgetc\n    gzseek\n    gzrewind\n    gztell\n    gzeof\n    gzsetparams\n    zError\n    inflateSyncPoint\n    get_crc_table\n    compress2\n    gzputs\n    gzgets\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/old/visual-basic.txt",
    "content": "See below some functions declarations for Visual Basic.\n\nFrequently Asked Question:\n\nQ: Each time I use the compress function I get the -5 error (not enough\n   room in the output buffer).\n\nA: Make sure that the length of the compressed buffer is passed by\n   reference (\"as any\"), not by value (\"as long\"). Also check that\n   before the call of compress this length is equal to the total size of\n   the compressed buffer and not zero.\n\n\nFrom: \"Jon Caruana\" <jon-net@usa.net>\nSubject: Re: How to port zlib declares to vb?\nDate: Mon, 28 Oct 1996 18:33:03 -0600\n\nGot the answer! (I haven't had time to check this but it's what I got, and\nlooks correct):\n\nHe has the following routines working:\n        compress\n        uncompress\n        gzopen\n        gzwrite\n        gzread\n        gzclose\n\nDeclares follow: (Quoted from Carlos Rios <c_rios@sonda.cl>, in Vb4 form)\n\n#If Win16 Then   'Use Win16 calls.\nDeclare Function compress Lib \"ZLIB.DLL\" (ByVal compr As\n        String, comprLen As Any, ByVal buf As String, ByVal buflen\n        As Long) As Integer\nDeclare Function uncompress Lib \"ZLIB.DLL\" (ByVal uncompr\n        As String, uncomprLen As Any, ByVal compr As String, ByVal\n        lcompr As Long) As Integer\nDeclare Function gzopen Lib \"ZLIB.DLL\" (ByVal filePath As\n        String, ByVal mode As String) As Long\nDeclare Function gzread Lib \"ZLIB.DLL\" (ByVal file As\n        Long, ByVal uncompr As String, ByVal uncomprLen As Integer)\n        As Integer\nDeclare Function gzwrite Lib \"ZLIB.DLL\" (ByVal file As\n        Long, ByVal uncompr As String, ByVal uncomprLen As Integer)\n        As Integer\nDeclare Function gzclose Lib \"ZLIB.DLL\" (ByVal file As\n        Long) As Integer\n#Else\nDeclare Function compress Lib \"ZLIB32.DLL\"\n        (ByVal compr As String, comprLen As Any, ByVal buf As\n        String, ByVal buflen As Long) As Integer\nDeclare Function uncompress Lib \"ZLIB32.DLL\"\n        (ByVal uncompr As String, uncomprLen As Any, ByVal compr As\n        String, ByVal lcompr As Long) As Long\nDeclare Function gzopen Lib \"ZLIB32.DLL\"\n        (ByVal file As String, ByVal mode As String) As Long\nDeclare Function gzread Lib \"ZLIB32.DLL\"\n        (ByVal file As Long, ByVal uncompr As String, ByVal\n        uncomprLen As Long) As Long\nDeclare Function gzwrite Lib \"ZLIB32.DLL\"\n        (ByVal file As Long, ByVal uncompr As String, ByVal\n        uncomprLen As Long) As Long\nDeclare Function gzclose Lib \"ZLIB32.DLL\"\n        (ByVal file As Long) As Long\n#End If\n\n-Jon Caruana\njon-net@usa.net\nMicrosoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member\n\n\nHere is another example from Michael <michael_borgsys@hotmail.com> that he\nsays conforms to the VB guidelines, and that solves the problem of not\nknowing the uncompressed size by storing it at the end of the file:\n\n'Calling the functions:\n'bracket meaning: <parameter> [optional] {Range of possible values}\n'Call subCompressFile(<path with filename to compress> [, <path with\nfilename to write to>, [level of compression {1..9}]])\n'Call subUncompressFile(<path with filename to compress>)\n\nOption Explicit\nPrivate lngpvtPcnSml As Long 'Stores value for 'lngPercentSmaller'\nPrivate Const SUCCESS As Long = 0\nPrivate Const strFilExt As String = \".cpr\"\nPrivate Declare Function lngfncCpr Lib \"zlib.dll\" Alias \"compress2\" (ByRef\ndest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long,\nByVal level As Integer) As Long\nPrivate Declare Function lngfncUcp Lib \"zlib.dll\" Alias \"uncompress\" (ByRef\ndest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long)\nAs Long\n\nPublic Sub subCompressFile(ByVal strargOriFilPth As String, Optional ByVal\nstrargCprFilPth As String, Optional ByVal intLvl As Integer = 9)\n    Dim strCprPth As String\n    Dim lngOriSiz As Long\n    Dim lngCprSiz As Long\n    Dim bytaryOri() As Byte\n    Dim bytaryCpr() As Byte\n    lngOriSiz = FileLen(strargOriFilPth)\n    ReDim bytaryOri(lngOriSiz - 1)\n    Open strargOriFilPth For Binary Access Read As #1\n        Get #1, , bytaryOri()\n    Close #1\n    strCprPth = IIf(strargCprFilPth = \"\", strargOriFilPth, strargCprFilPth)\n'Select file path and name\n    strCprPth = strCprPth & IIf(Right(strCprPth, Len(strFilExt)) =\nstrFilExt, \"\", strFilExt) 'Add file extension if not exists\n    lngCprSiz = (lngOriSiz * 1.01) + 12 'Compression needs temporary a bit\nmore space then original file size\n    ReDim bytaryCpr(lngCprSiz - 1)\n    If lngfncCpr(bytaryCpr(0), lngCprSiz, bytaryOri(0), lngOriSiz, intLvl) =\nSUCCESS Then\n        lngpvtPcnSml = (1# - (lngCprSiz / lngOriSiz)) * 100\n        ReDim Preserve bytaryCpr(lngCprSiz - 1)\n        Open strCprPth For Binary Access Write As #1\n            Put #1, , bytaryCpr()\n            Put #1, , lngOriSiz 'Add the the original size value to the end\n(last 4 bytes)\n        Close #1\n    Else\n        MsgBox \"Compression error\"\n    End If\n    Erase bytaryCpr\n    Erase bytaryOri\nEnd Sub\n\nPublic Sub subUncompressFile(ByVal strargFilPth As String)\n    Dim bytaryCpr() As Byte\n    Dim bytaryOri() As Byte\n    Dim lngOriSiz As Long\n    Dim lngCprSiz As Long\n    Dim strOriPth As String\n    lngCprSiz = FileLen(strargFilPth)\n    ReDim bytaryCpr(lngCprSiz - 1)\n    Open strargFilPth For Binary Access Read As #1\n        Get #1, , bytaryCpr()\n    Close #1\n    'Read the original file size value:\n    lngOriSiz = bytaryCpr(lngCprSiz - 1) * (2 ^ 24) _\n              + bytaryCpr(lngCprSiz - 2) * (2 ^ 16) _\n              + bytaryCpr(lngCprSiz - 3) * (2 ^ 8) _\n              + bytaryCpr(lngCprSiz - 4)\n    ReDim Preserve bytaryCpr(lngCprSiz - 5) 'Cut of the original size value\n    ReDim bytaryOri(lngOriSiz - 1)\n    If lngfncUcp(bytaryOri(0), lngOriSiz, bytaryCpr(0), lngCprSiz) = SUCCESS\nThen\n        strOriPth = Left(strargFilPth, Len(strargFilPth) - Len(strFilExt))\n        Open strOriPth For Binary Access Write As #1\n            Put #1, , bytaryOri()\n        Close #1\n    Else\n        MsgBox \"Uncompression error\"\n    End If\n    Erase bytaryCpr\n    Erase bytaryOri\nEnd Sub\nPublic Property Get lngPercentSmaller() As Long\n    lngPercentSmaller = lngpvtPcnSml\nEnd Property\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/qnx/package.qpg",
    "content": "<QPG:Generation>\n   <QPG:Options>\n      <QPG:User unattended=\"no\" verbosity=\"2\" listfiles=\"yes\"/>\n      <QPG:Defaults type=\"qnx_package\"/>\n      <QPG:Source></QPG:Source>\n      <QPG:Release number=\"+\"/>\n      <QPG:Build></QPG:Build>\n      <QPG:FileSorting strip=\"yes\"/>\n      <QPG:Package targets=\"combine\"/>\n      <QPG:Repository generate=\"yes\"/>\n      <QPG:FinalDir></QPG:FinalDir>\n      <QPG:Cleanup></QPG:Cleanup>\n   </QPG:Options>\n\n   <QPG:Responsible>\n      <QPG:Company></QPG:Company>\n      <QPG:Department></QPG:Department>\n      <QPG:Group></QPG:Group>\n      <QPG:Team></QPG:Team>\n      <QPG:Employee></QPG:Employee>\n      <QPG:EmailAddress></QPG:EmailAddress>\n   </QPG:Responsible>\n\n   <QPG:Values>\n      <QPG:Files>\n         <QPG:Add file=\"../zconf.h\" install=\"/opt/include/\" user=\"root:sys\" permission=\"644\"/>\n         <QPG:Add file=\"../zlib.h\" install=\"/opt/include/\" user=\"root:sys\" permission=\"644\"/>\n         <QPG:Add file=\"../libz.so.1.2.8\" install=\"/opt/lib/\" user=\"root:bin\" permission=\"644\"/>\n         <QPG:Add file=\"libz.so\" install=\"/opt/lib/\" component=\"dev\" filetype=\"symlink\" linkto=\"libz.so.1.2.8\"/>\n         <QPG:Add file=\"libz.so.1\" install=\"/opt/lib/\" filetype=\"symlink\" linkto=\"libz.so.1.2.8\"/>\n         <QPG:Add file=\"../libz.so.1.2.8\" install=\"/opt/lib/\" component=\"slib\"/>\n      </QPG:Files>\n\n      <QPG:PackageFilter>\n         <QPM:PackageManifest>\n            <QPM:PackageDescription>\n               <QPM:PackageType>Library</QPM:PackageType>\n               <QPM:PackageReleaseNotes></QPM:PackageReleaseNotes>\n               <QPM:PackageReleaseUrgency>Medium</QPM:PackageReleaseUrgency>\n               <QPM:PackageRepository></QPM:PackageRepository>\n               <QPM:FileVersion>2.0</QPM:FileVersion>\n            </QPM:PackageDescription>\n\n            <QPM:ProductDescription>\n               <QPM:ProductName>zlib</QPM:ProductName>\n               <QPM:ProductIdentifier>zlib</QPM:ProductIdentifier>\n               <QPM:ProductEmail>alain.bonnefoy@icbt.com</QPM:ProductEmail>\n               <QPM:VendorName>Public</QPM:VendorName>\n               <QPM:VendorInstallName>public</QPM:VendorInstallName>\n               <QPM:VendorURL>www.gzip.org/zlib</QPM:VendorURL>\n               <QPM:VendorEmbedURL></QPM:VendorEmbedURL>\n               <QPM:VendorEmail></QPM:VendorEmail>\n               <QPM:AuthorName>Jean-Loup Gailly,Mark Adler</QPM:AuthorName>\n               <QPM:AuthorURL>www.gzip.org/zlib</QPM:AuthorURL>\n               <QPM:AuthorEmbedURL></QPM:AuthorEmbedURL>\n               <QPM:AuthorEmail>zlib@gzip.org</QPM:AuthorEmail>\n               <QPM:ProductIconSmall></QPM:ProductIconSmall>\n               <QPM:ProductIconLarge></QPM:ProductIconLarge>\n               <QPM:ProductDescriptionShort>A massively spiffy yet delicately unobtrusive compression library.</QPM:ProductDescriptionShort>\n               <QPM:ProductDescriptionLong>zlib is designed to be a free, general-purpose, legally unencumbered, lossless data compression library for use on virtually any computer hardware and operating system.</QPM:ProductDescriptionLong>\n               <QPM:ProductDescriptionURL>http://www.gzip.org/zlib</QPM:ProductDescriptionURL>\n               <QPM:ProductDescriptionEmbedURL></QPM:ProductDescriptionEmbedURL>\n            </QPM:ProductDescription>\n\n            <QPM:ReleaseDescription>\n               <QPM:ReleaseVersion>1.2.8</QPM:ReleaseVersion>\n               <QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>\n               <QPM:ReleaseStability>Stable</QPM:ReleaseStability>\n               <QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>\n               <QPM:ReleaseNoteMajor></QPM:ReleaseNoteMajor>\n               <QPM:ExcludeCountries>\n                  <QPM:Country></QPM:Country>\n               </QPM:ExcludeCountries>\n\n               <QPM:ReleaseCopyright>No License</QPM:ReleaseCopyright>\n            </QPM:ReleaseDescription>\n\n            <QPM:ContentDescription>\n               <QPM:ContentTopic xmlmultiple=\"true\">Software Development/Libraries and Extensions/C Libraries</QPM:ContentTopic>\n               <QPM:ContentKeyword>zlib,compression</QPM:ContentKeyword>\n               <QPM:TargetOS>qnx6</QPM:TargetOS>\n               <QPM:HostOS>qnx6</QPM:HostOS>\n               <QPM:DisplayEnvironment xmlmultiple=\"true\">None</QPM:DisplayEnvironment>\n               <QPM:TargetAudience xmlmultiple=\"true\">Developer</QPM:TargetAudience>\n            </QPM:ContentDescription>\n         </QPM:PackageManifest>\n      </QPG:PackageFilter>\n\n      <QPG:PackageFilter proc=\"none\" target=\"none\">\n         <QPM:PackageManifest>\n            <QPM:ProductInstallationDependencies>\n               <QPM:ProductRequirements></QPM:ProductRequirements>\n            </QPM:ProductInstallationDependencies>\n\n            <QPM:ProductInstallationProcedure>\n               <QPM:Script xmlmultiple=\"true\">\n                  <QPM:ScriptName></QPM:ScriptName>\n                  <QPM:ScriptType>Install</QPM:ScriptType>\n                  <QPM:ScriptTiming>Post</QPM:ScriptTiming>\n                  <QPM:ScriptBlocking>No</QPM:ScriptBlocking>\n                  <QPM:ScriptResult>Ignore</QPM:ScriptResult>\n                  <QPM:ShortDescription></QPM:ShortDescription>\n                  <QPM:UseBinaries>No</QPM:UseBinaries>\n                  <QPM:Priority>Optional</QPM:Priority>\n               </QPM:Script>\n            </QPM:ProductInstallationProcedure>\n         </QPM:PackageManifest>\n\n         <QPM:Launch>\n         </QPM:Launch>\n      </QPG:PackageFilter>\n\n      <QPG:PackageFilter type=\"core\" component=\"none\">\n         <QPM:PackageManifest>\n            <QPM:ProductInstallationProcedure>\n\t       <QPM:OrderDependency xmlmultiple=\"true\">\n\t          <QPM:Order>InstallOver</QPM:Order>\n\t          <QPM:Product>zlib</QPM:Product>\n\t       </QPM:OrderDependency>\n            </QPM:ProductInstallationProcedure>\n         </QPM:PackageManifest>\n\n         <QPM:Launch>\n         </QPM:Launch>\n      </QPG:PackageFilter>\n\n      <QPG:PackageFilter type=\"core\" component=\"dev\">\n         <QPM:PackageManifest>\n            <QPM:ProductInstallationProcedure>\n\t       <QPM:OrderDependency xmlmultiple=\"true\">\n\t          <QPM:Order>InstallOver</QPM:Order>\n\t          <QPM:Product>zlib-dev</QPM:Product>\n\t       </QPM:OrderDependency>\n            </QPM:ProductInstallationProcedure>\n         </QPM:PackageManifest>\n\n         <QPM:Launch>\n         </QPM:Launch>\n      </QPG:PackageFilter>\n   </QPG:Values>\n</QPG:Generation>\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/test/example.c",
    "content": "/* example.c -- usage example of the zlib compression library\n * Copyright (C) 1995-2006, 2011 Jean-loup Gailly.\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* @(#) $Id$ */\n\n#include \"zlib.h\"\n#include <stdio.h>\n\n#ifdef STDC\n#  include <string.h>\n#  include <stdlib.h>\n#endif\n\n#if defined(VMS) || defined(RISCOS)\n#  define TESTFILE \"foo-gz\"\n#else\n#  define TESTFILE \"foo.gz\"\n#endif\n\n#define CHECK_ERR(err, msg) { \\\n    if (err != Z_OK) { \\\n        fprintf(stderr, \"%s error: %d\\n\", msg, err); \\\n        exit(1); \\\n    } \\\n}\n\nz_const char hello[] = \"hello, hello!\";\n/* \"hello world\" would be more standard, but the repeated \"hello\"\n * stresses the compression code better, sorry...\n */\n\nconst char dictionary[] = \"hello\";\nuLong dictId; /* Adler32 value of the dictionary */\n\nvoid test_deflate       OF((Byte *compr, uLong comprLen));\nvoid test_inflate       OF((Byte *compr, uLong comprLen,\n                            Byte *uncompr, uLong uncomprLen));\nvoid test_large_deflate OF((Byte *compr, uLong comprLen,\n                            Byte *uncompr, uLong uncomprLen));\nvoid test_large_inflate OF((Byte *compr, uLong comprLen,\n                            Byte *uncompr, uLong uncomprLen));\nvoid test_flush         OF((Byte *compr, uLong *comprLen));\nvoid test_sync          OF((Byte *compr, uLong comprLen,\n                            Byte *uncompr, uLong uncomprLen));\nvoid test_dict_deflate  OF((Byte *compr, uLong comprLen));\nvoid test_dict_inflate  OF((Byte *compr, uLong comprLen,\n                            Byte *uncompr, uLong uncomprLen));\nint  main               OF((int argc, char *argv[]));\n\n\n#ifdef Z_SOLO\n\nvoid *myalloc OF((void *, unsigned, unsigned));\nvoid myfree OF((void *, void *));\n\nvoid *myalloc(q, n, m)\n    void *q;\n    unsigned n, m;\n{\n    q = Z_NULL;\n    return calloc(n, m);\n}\n\nvoid myfree(void *q, void *p)\n{\n    q = Z_NULL;\n    free(p);\n}\n\nstatic alloc_func zalloc = myalloc;\nstatic free_func zfree = myfree;\n\n#else /* !Z_SOLO */\n\nstatic alloc_func zalloc = (alloc_func)0;\nstatic free_func zfree = (free_func)0;\n\nvoid test_compress      OF((Byte *compr, uLong comprLen,\n                            Byte *uncompr, uLong uncomprLen));\nvoid test_gzio          OF((const char *fname,\n                            Byte *uncompr, uLong uncomprLen));\n\n/* ===========================================================================\n * Test compress() and uncompress()\n */\nvoid test_compress(compr, comprLen, uncompr, uncomprLen)\n    Byte *compr, *uncompr;\n    uLong comprLen, uncomprLen;\n{\n    int err;\n    uLong len = (uLong)strlen(hello)+1;\n\n    err = compress(compr, &comprLen, (const Bytef*)hello, len);\n    CHECK_ERR(err, \"compress\");\n\n    strcpy((char*)uncompr, \"garbage\");\n\n    err = uncompress(uncompr, &uncomprLen, compr, comprLen);\n    CHECK_ERR(err, \"uncompress\");\n\n    if (strcmp((char*)uncompr, hello)) {\n        fprintf(stderr, \"bad uncompress\\n\");\n        exit(1);\n    } else {\n        printf(\"uncompress(): %s\\n\", (char *)uncompr);\n    }\n}\n\n/* ===========================================================================\n * Test read/write of .gz files\n */\nvoid test_gzio(fname, uncompr, uncomprLen)\n    const char *fname; /* compressed file name */\n    Byte *uncompr;\n    uLong uncomprLen;\n{\n#ifdef NO_GZCOMPRESS\n    fprintf(stderr, \"NO_GZCOMPRESS -- gz* functions cannot compress\\n\");\n#else\n    int err;\n    int len = (int)strlen(hello)+1;\n    gzFile file;\n    z_off_t pos;\n\n    file = gzopen(fname, \"wb\");\n    if (file == NULL) {\n        fprintf(stderr, \"gzopen error\\n\");\n        exit(1);\n    }\n    gzputc(file, 'h');\n    if (gzputs(file, \"ello\") != 4) {\n        fprintf(stderr, \"gzputs err: %s\\n\", gzerror(file, &err));\n        exit(1);\n    }\n    if (gzprintf(file, \", %s!\", \"hello\") != 8) {\n        fprintf(stderr, \"gzprintf err: %s\\n\", gzerror(file, &err));\n        exit(1);\n    }\n    gzseek(file, 1L, SEEK_CUR); /* add one zero byte */\n    gzclose(file);\n\n    file = gzopen(fname, \"rb\");\n    if (file == NULL) {\n        fprintf(stderr, \"gzopen error\\n\");\n        exit(1);\n    }\n    strcpy((char*)uncompr, \"garbage\");\n\n    if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {\n        fprintf(stderr, \"gzread err: %s\\n\", gzerror(file, &err));\n        exit(1);\n    }\n    if (strcmp((char*)uncompr, hello)) {\n        fprintf(stderr, \"bad gzread: %s\\n\", (char*)uncompr);\n        exit(1);\n    } else {\n        printf(\"gzread(): %s\\n\", (char*)uncompr);\n    }\n\n    pos = gzseek(file, -8L, SEEK_CUR);\n    if (pos != 6 || gztell(file) != pos) {\n        fprintf(stderr, \"gzseek error, pos=%ld, gztell=%ld\\n\",\n                (long)pos, (long)gztell(file));\n        exit(1);\n    }\n\n    if (gzgetc(file) != ' ') {\n        fprintf(stderr, \"gzgetc error\\n\");\n        exit(1);\n    }\n\n    if (gzungetc(' ', file) != ' ') {\n        fprintf(stderr, \"gzungetc error\\n\");\n        exit(1);\n    }\n\n    gzgets(file, (char*)uncompr, (int)uncomprLen);\n    if (strlen((char*)uncompr) != 7) { /* \" hello!\" */\n        fprintf(stderr, \"gzgets err after gzseek: %s\\n\", gzerror(file, &err));\n        exit(1);\n    }\n    if (strcmp((char*)uncompr, hello + 6)) {\n        fprintf(stderr, \"bad gzgets after gzseek\\n\");\n        exit(1);\n    } else {\n        printf(\"gzgets() after gzseek: %s\\n\", (char*)uncompr);\n    }\n\n    gzclose(file);\n#endif\n}\n\n#endif /* Z_SOLO */\n\n/* ===========================================================================\n * Test deflate() with small buffers\n */\nvoid test_deflate(compr, comprLen)\n    Byte *compr;\n    uLong comprLen;\n{\n    z_stream c_stream; /* compression stream */\n    int err;\n    uLong len = (uLong)strlen(hello)+1;\n\n    c_stream.zalloc = zalloc;\n    c_stream.zfree = zfree;\n    c_stream.opaque = (voidpf)0;\n\n    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);\n    CHECK_ERR(err, \"deflateInit\");\n\n    c_stream.next_in  = (z_const unsigned char *)hello;\n    c_stream.next_out = compr;\n\n    while (c_stream.total_in != len && c_stream.total_out < comprLen) {\n        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */\n        err = deflate(&c_stream, Z_NO_FLUSH);\n        CHECK_ERR(err, \"deflate\");\n    }\n    /* Finish the stream, still forcing small buffers: */\n    for (;;) {\n        c_stream.avail_out = 1;\n        err = deflate(&c_stream, Z_FINISH);\n        if (err == Z_STREAM_END) break;\n        CHECK_ERR(err, \"deflate\");\n    }\n\n    err = deflateEnd(&c_stream);\n    CHECK_ERR(err, \"deflateEnd\");\n}\n\n/* ===========================================================================\n * Test inflate() with small buffers\n */\nvoid test_inflate(compr, comprLen, uncompr, uncomprLen)\n    Byte *compr, *uncompr;\n    uLong comprLen, uncomprLen;\n{\n    int err;\n    z_stream d_stream; /* decompression stream */\n\n    strcpy((char*)uncompr, \"garbage\");\n\n    d_stream.zalloc = zalloc;\n    d_stream.zfree = zfree;\n    d_stream.opaque = (voidpf)0;\n\n    d_stream.next_in  = compr;\n    d_stream.avail_in = 0;\n    d_stream.next_out = uncompr;\n\n    err = inflateInit(&d_stream);\n    CHECK_ERR(err, \"inflateInit\");\n\n    while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {\n        d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */\n        err = inflate(&d_stream, Z_NO_FLUSH);\n        if (err == Z_STREAM_END) break;\n        CHECK_ERR(err, \"inflate\");\n    }\n\n    err = inflateEnd(&d_stream);\n    CHECK_ERR(err, \"inflateEnd\");\n\n    if (strcmp((char*)uncompr, hello)) {\n        fprintf(stderr, \"bad inflate\\n\");\n        exit(1);\n    } else {\n        printf(\"inflate(): %s\\n\", (char *)uncompr);\n    }\n}\n\n/* ===========================================================================\n * Test deflate() with large buffers and dynamic change of compression level\n */\nvoid test_large_deflate(compr, comprLen, uncompr, uncomprLen)\n    Byte *compr, *uncompr;\n    uLong comprLen, uncomprLen;\n{\n    z_stream c_stream; /* compression stream */\n    int err;\n\n    c_stream.zalloc = zalloc;\n    c_stream.zfree = zfree;\n    c_stream.opaque = (voidpf)0;\n\n    err = deflateInit(&c_stream, Z_BEST_SPEED);\n    CHECK_ERR(err, \"deflateInit\");\n\n    c_stream.next_out = compr;\n    c_stream.avail_out = (uInt)comprLen;\n\n    /* At this point, uncompr is still mostly zeroes, so it should compress\n     * very well:\n     */\n    c_stream.next_in = uncompr;\n    c_stream.avail_in = (uInt)uncomprLen;\n    err = deflate(&c_stream, Z_NO_FLUSH);\n    CHECK_ERR(err, \"deflate\");\n    if (c_stream.avail_in != 0) {\n        fprintf(stderr, \"deflate not greedy\\n\");\n        exit(1);\n    }\n\n    /* Feed in already compressed data and switch to no compression: */\n    deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);\n    c_stream.next_in = compr;\n    c_stream.avail_in = (uInt)comprLen/2;\n    err = deflate(&c_stream, Z_NO_FLUSH);\n    CHECK_ERR(err, \"deflate\");\n\n    /* Switch back to compressing mode: */\n    deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);\n    c_stream.next_in = uncompr;\n    c_stream.avail_in = (uInt)uncomprLen;\n    err = deflate(&c_stream, Z_NO_FLUSH);\n    CHECK_ERR(err, \"deflate\");\n\n    err = deflate(&c_stream, Z_FINISH);\n    if (err != Z_STREAM_END) {\n        fprintf(stderr, \"deflate should report Z_STREAM_END\\n\");\n        exit(1);\n    }\n    err = deflateEnd(&c_stream);\n    CHECK_ERR(err, \"deflateEnd\");\n}\n\n/* ===========================================================================\n * Test inflate() with large buffers\n */\nvoid test_large_inflate(compr, comprLen, uncompr, uncomprLen)\n    Byte *compr, *uncompr;\n    uLong comprLen, uncomprLen;\n{\n    int err;\n    z_stream d_stream; /* decompression stream */\n\n    strcpy((char*)uncompr, \"garbage\");\n\n    d_stream.zalloc = zalloc;\n    d_stream.zfree = zfree;\n    d_stream.opaque = (voidpf)0;\n\n    d_stream.next_in  = compr;\n    d_stream.avail_in = (uInt)comprLen;\n\n    err = inflateInit(&d_stream);\n    CHECK_ERR(err, \"inflateInit\");\n\n    for (;;) {\n        d_stream.next_out = uncompr;            /* discard the output */\n        d_stream.avail_out = (uInt)uncomprLen;\n        err = inflate(&d_stream, Z_NO_FLUSH);\n        if (err == Z_STREAM_END) break;\n        CHECK_ERR(err, \"large inflate\");\n    }\n\n    err = inflateEnd(&d_stream);\n    CHECK_ERR(err, \"inflateEnd\");\n\n    if (d_stream.total_out != 2*uncomprLen + comprLen/2) {\n        fprintf(stderr, \"bad large inflate: %ld\\n\", d_stream.total_out);\n        exit(1);\n    } else {\n        printf(\"large_inflate(): OK\\n\");\n    }\n}\n\n/* ===========================================================================\n * Test deflate() with full flush\n */\nvoid test_flush(compr, comprLen)\n    Byte *compr;\n    uLong *comprLen;\n{\n    z_stream c_stream; /* compression stream */\n    int err;\n    uInt len = (uInt)strlen(hello)+1;\n\n    c_stream.zalloc = zalloc;\n    c_stream.zfree = zfree;\n    c_stream.opaque = (voidpf)0;\n\n    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);\n    CHECK_ERR(err, \"deflateInit\");\n\n    c_stream.next_in  = (z_const unsigned char *)hello;\n    c_stream.next_out = compr;\n    c_stream.avail_in = 3;\n    c_stream.avail_out = (uInt)*comprLen;\n    err = deflate(&c_stream, Z_FULL_FLUSH);\n    CHECK_ERR(err, \"deflate\");\n\n    compr[3]++; /* force an error in first compressed block */\n    c_stream.avail_in = len - 3;\n\n    err = deflate(&c_stream, Z_FINISH);\n    if (err != Z_STREAM_END) {\n        CHECK_ERR(err, \"deflate\");\n    }\n    err = deflateEnd(&c_stream);\n    CHECK_ERR(err, \"deflateEnd\");\n\n    *comprLen = c_stream.total_out;\n}\n\n/* ===========================================================================\n * Test inflateSync()\n */\nvoid test_sync(compr, comprLen, uncompr, uncomprLen)\n    Byte *compr, *uncompr;\n    uLong comprLen, uncomprLen;\n{\n    int err;\n    z_stream d_stream; /* decompression stream */\n\n    strcpy((char*)uncompr, \"garbage\");\n\n    d_stream.zalloc = zalloc;\n    d_stream.zfree = zfree;\n    d_stream.opaque = (voidpf)0;\n\n    d_stream.next_in  = compr;\n    d_stream.avail_in = 2; /* just read the zlib header */\n\n    err = inflateInit(&d_stream);\n    CHECK_ERR(err, \"inflateInit\");\n\n    d_stream.next_out = uncompr;\n    d_stream.avail_out = (uInt)uncomprLen;\n\n    inflate(&d_stream, Z_NO_FLUSH);\n    CHECK_ERR(err, \"inflate\");\n\n    d_stream.avail_in = (uInt)comprLen-2;   /* read all compressed data */\n    err = inflateSync(&d_stream);           /* but skip the damaged part */\n    CHECK_ERR(err, \"inflateSync\");\n\n    err = inflate(&d_stream, Z_FINISH);\n    if (err != Z_DATA_ERROR) {\n        fprintf(stderr, \"inflate should report DATA_ERROR\\n\");\n        /* Because of incorrect adler32 */\n        exit(1);\n    }\n    err = inflateEnd(&d_stream);\n    CHECK_ERR(err, \"inflateEnd\");\n\n    printf(\"after inflateSync(): hel%s\\n\", (char *)uncompr);\n}\n\n/* ===========================================================================\n * Test deflate() with preset dictionary\n */\nvoid test_dict_deflate(compr, comprLen)\n    Byte *compr;\n    uLong comprLen;\n{\n    z_stream c_stream; /* compression stream */\n    int err;\n\n    c_stream.zalloc = zalloc;\n    c_stream.zfree = zfree;\n    c_stream.opaque = (voidpf)0;\n\n    err = deflateInit(&c_stream, Z_BEST_COMPRESSION);\n    CHECK_ERR(err, \"deflateInit\");\n\n    err = deflateSetDictionary(&c_stream,\n                (const Bytef*)dictionary, (int)sizeof(dictionary));\n    CHECK_ERR(err, \"deflateSetDictionary\");\n\n    dictId = c_stream.adler;\n    c_stream.next_out = compr;\n    c_stream.avail_out = (uInt)comprLen;\n\n    c_stream.next_in = (z_const unsigned char *)hello;\n    c_stream.avail_in = (uInt)strlen(hello)+1;\n\n    err = deflate(&c_stream, Z_FINISH);\n    if (err != Z_STREAM_END) {\n        fprintf(stderr, \"deflate should report Z_STREAM_END\\n\");\n        exit(1);\n    }\n    err = deflateEnd(&c_stream);\n    CHECK_ERR(err, \"deflateEnd\");\n}\n\n/* ===========================================================================\n * Test inflate() with a preset dictionary\n */\nvoid test_dict_inflate(compr, comprLen, uncompr, uncomprLen)\n    Byte *compr, *uncompr;\n    uLong comprLen, uncomprLen;\n{\n    int err;\n    z_stream d_stream; /* decompression stream */\n\n    strcpy((char*)uncompr, \"garbage\");\n\n    d_stream.zalloc = zalloc;\n    d_stream.zfree = zfree;\n    d_stream.opaque = (voidpf)0;\n\n    d_stream.next_in  = compr;\n    d_stream.avail_in = (uInt)comprLen;\n\n    err = inflateInit(&d_stream);\n    CHECK_ERR(err, \"inflateInit\");\n\n    d_stream.next_out = uncompr;\n    d_stream.avail_out = (uInt)uncomprLen;\n\n    for (;;) {\n        err = inflate(&d_stream, Z_NO_FLUSH);\n        if (err == Z_STREAM_END) break;\n        if (err == Z_NEED_DICT) {\n            if (d_stream.adler != dictId) {\n                fprintf(stderr, \"unexpected dictionary\");\n                exit(1);\n            }\n            err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,\n                                       (int)sizeof(dictionary));\n        }\n        CHECK_ERR(err, \"inflate with dict\");\n    }\n\n    err = inflateEnd(&d_stream);\n    CHECK_ERR(err, \"inflateEnd\");\n\n    if (strcmp((char*)uncompr, hello)) {\n        fprintf(stderr, \"bad inflate with dict\\n\");\n        exit(1);\n    } else {\n        printf(\"inflate with dictionary: %s\\n\", (char *)uncompr);\n    }\n}\n\n/* ===========================================================================\n * Usage:  example [output.gz  [input.gz]]\n */\n\nint main(argc, argv)\n    int argc;\n    char *argv[];\n{\n    Byte *compr, *uncompr;\n    uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */\n    uLong uncomprLen = comprLen;\n    static const char* myVersion = ZLIB_VERSION;\n\n    if (zlibVersion()[0] != myVersion[0]) {\n        fprintf(stderr, \"incompatible zlib version\\n\");\n        exit(1);\n\n    } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {\n        fprintf(stderr, \"warning: different zlib version\\n\");\n    }\n\n    printf(\"zlib version %s = 0x%04x, compile flags = 0x%lx\\n\",\n            ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());\n\n    compr    = (Byte*)calloc((uInt)comprLen, 1);\n    uncompr  = (Byte*)calloc((uInt)uncomprLen, 1);\n    /* compr and uncompr are cleared to avoid reading uninitialized\n     * data and to ensure that uncompr compresses well.\n     */\n    if (compr == Z_NULL || uncompr == Z_NULL) {\n        printf(\"out of memory\\n\");\n        exit(1);\n    }\n\n#ifdef Z_SOLO\n    argc = strlen(argv[0]);\n#else\n    test_compress(compr, comprLen, uncompr, uncomprLen);\n\n    test_gzio((argc > 1 ? argv[1] : TESTFILE),\n              uncompr, uncomprLen);\n#endif\n\n    test_deflate(compr, comprLen);\n    test_inflate(compr, comprLen, uncompr, uncomprLen);\n\n    test_large_deflate(compr, comprLen, uncompr, uncomprLen);\n    test_large_inflate(compr, comprLen, uncompr, uncomprLen);\n\n    test_flush(compr, &comprLen);\n    test_sync(compr, comprLen, uncompr, uncomprLen);\n    comprLen = uncomprLen;\n\n    test_dict_deflate(compr, comprLen);\n    test_dict_inflate(compr, comprLen, uncompr, uncomprLen);\n\n    free(compr);\n    free(uncompr);\n\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/test/infcover.c",
    "content": "/* infcover.c -- test zlib's inflate routines with full code coverage\n * Copyright (C) 2011 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* to use, do: ./configure --cover && make cover */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#include \"zlib.h\"\n\n/* get definition of internal structure so we can mess with it (see pull()),\n   and so we can call inflate_trees() (see cover5()) */\n#define ZLIB_INTERNAL\n#include \"inftrees.h\"\n#include \"inflate.h\"\n\n#define local static\n\n/* -- memory tracking routines -- */\n\n/*\n   These memory tracking routines are provided to zlib and track all of zlib's\n   allocations and deallocations, check for LIFO operations, keep a current\n   and high water mark of total bytes requested, optionally set a limit on the\n   total memory that can be allocated, and when done check for memory leaks.\n\n   They are used as follows:\n\n   z_stream strm;\n   mem_setup(&strm)         initializes the memory tracking and sets the\n                            zalloc, zfree, and opaque members of strm to use\n                            memory tracking for all zlib operations on strm\n   mem_limit(&strm, limit)  sets a limit on the total bytes requested -- a\n                            request that exceeds this limit will result in an\n                            allocation failure (returns NULL) -- setting the\n                            limit to zero means no limit, which is the default\n                            after mem_setup()\n   mem_used(&strm, \"msg\")   prints to stderr \"msg\" and the total bytes used\n   mem_high(&strm, \"msg\")   prints to stderr \"msg\" and the high water mark\n   mem_done(&strm, \"msg\")   ends memory tracking, releases all allocations\n                            for the tracking as well as leaked zlib blocks, if\n                            any.  If there was anything unusual, such as leaked\n                            blocks, non-FIFO frees, or frees of addresses not\n                            allocated, then \"msg\" and information about the\n                            problem is printed to stderr.  If everything is\n                            normal, nothing is printed. mem_done resets the\n                            strm members to Z_NULL to use the default memory\n                            allocation routines on the next zlib initialization\n                            using strm.\n */\n\n/* these items are strung together in a linked list, one for each allocation */\nstruct mem_item {\n    void *ptr;                  /* pointer to allocated memory */\n    size_t size;                /* requested size of allocation */\n    struct mem_item *next;      /* pointer to next item in list, or NULL */\n};\n\n/* this structure is at the root of the linked list, and tracks statistics */\nstruct mem_zone {\n    struct mem_item *first;     /* pointer to first item in list, or NULL */\n    size_t total, highwater;    /* total allocations, and largest total */\n    size_t limit;               /* memory allocation limit, or 0 if no limit */\n    int notlifo, rogue;         /* counts of non-LIFO frees and rogue frees */\n};\n\n/* memory allocation routine to pass to zlib */\nlocal void *mem_alloc(void *mem, unsigned count, unsigned size)\n{\n    void *ptr;\n    struct mem_item *item;\n    struct mem_zone *zone = mem;\n    size_t len = count * (size_t)size;\n\n    /* induced allocation failure */\n    if (zone == NULL || (zone->limit && zone->total + len > zone->limit))\n        return NULL;\n\n    /* perform allocation using the standard library, fill memory with a\n       non-zero value to make sure that the code isn't depending on zeros */\n    ptr = malloc(len);\n    if (ptr == NULL)\n        return NULL;\n    memset(ptr, 0xa5, len);\n\n    /* create a new item for the list */\n    item = malloc(sizeof(struct mem_item));\n    if (item == NULL) {\n        free(ptr);\n        return NULL;\n    }\n    item->ptr = ptr;\n    item->size = len;\n\n    /* insert item at the beginning of the list */\n    item->next = zone->first;\n    zone->first = item;\n\n    /* update the statistics */\n    zone->total += item->size;\n    if (zone->total > zone->highwater)\n        zone->highwater = zone->total;\n\n    /* return the allocated memory */\n    return ptr;\n}\n\n/* memory free routine to pass to zlib */\nlocal void mem_free(void *mem, void *ptr)\n{\n    struct mem_item *item, *next;\n    struct mem_zone *zone = mem;\n\n    /* if no zone, just do a free */\n    if (zone == NULL) {\n        free(ptr);\n        return;\n    }\n\n    /* point next to the item that matches ptr, or NULL if not found -- remove\n       the item from the linked list if found */\n    next = zone->first;\n    if (next) {\n        if (next->ptr == ptr)\n            zone->first = next->next;   /* first one is it, remove from list */\n        else {\n            do {                        /* search the linked list */\n                item = next;\n                next = item->next;\n            } while (next != NULL && next->ptr != ptr);\n            if (next) {                 /* if found, remove from linked list */\n                item->next = next->next;\n                zone->notlifo++;        /* not a LIFO free */\n            }\n\n        }\n    }\n\n    /* if found, update the statistics and free the item */\n    if (next) {\n        zone->total -= next->size;\n        free(next);\n    }\n\n    /* if not found, update the rogue count */\n    else\n        zone->rogue++;\n\n    /* in any case, do the requested free with the standard library function */\n    free(ptr);\n}\n\n/* set up a controlled memory allocation space for monitoring, set the stream\n   parameters to the controlled routines, with opaque pointing to the space */\nlocal void mem_setup(z_stream *strm)\n{\n    struct mem_zone *zone;\n\n    zone = malloc(sizeof(struct mem_zone));\n    assert(zone != NULL);\n    zone->first = NULL;\n    zone->total = 0;\n    zone->highwater = 0;\n    zone->limit = 0;\n    zone->notlifo = 0;\n    zone->rogue = 0;\n    strm->opaque = zone;\n    strm->zalloc = mem_alloc;\n    strm->zfree = mem_free;\n}\n\n/* set a limit on the total memory allocation, or 0 to remove the limit */\nlocal void mem_limit(z_stream *strm, size_t limit)\n{\n    struct mem_zone *zone = strm->opaque;\n\n    zone->limit = limit;\n}\n\n/* show the current total requested allocations in bytes */\nlocal void mem_used(z_stream *strm, char *prefix)\n{\n    struct mem_zone *zone = strm->opaque;\n\n    fprintf(stderr, \"%s: %lu allocated\\n\", prefix, zone->total);\n}\n\n/* show the high water allocation in bytes */\nlocal void mem_high(z_stream *strm, char *prefix)\n{\n    struct mem_zone *zone = strm->opaque;\n\n    fprintf(stderr, \"%s: %lu high water mark\\n\", prefix, zone->highwater);\n}\n\n/* release the memory allocation zone -- if there are any surprises, notify */\nlocal void mem_done(z_stream *strm, char *prefix)\n{\n    int count = 0;\n    struct mem_item *item, *next;\n    struct mem_zone *zone = strm->opaque;\n\n    /* show high water mark */\n    mem_high(strm, prefix);\n\n    /* free leftover allocations and item structures, if any */\n    item = zone->first;\n    while (item != NULL) {\n        free(item->ptr);\n        next = item->next;\n        free(item);\n        item = next;\n        count++;\n    }\n\n    /* issue alerts about anything unexpected */\n    if (count || zone->total)\n        fprintf(stderr, \"** %s: %lu bytes in %d blocks not freed\\n\",\n                prefix, zone->total, count);\n    if (zone->notlifo)\n        fprintf(stderr, \"** %s: %d frees not LIFO\\n\", prefix, zone->notlifo);\n    if (zone->rogue)\n        fprintf(stderr, \"** %s: %d frees not recognized\\n\",\n                prefix, zone->rogue);\n\n    /* free the zone and delete from the stream */\n    free(zone);\n    strm->opaque = Z_NULL;\n    strm->zalloc = Z_NULL;\n    strm->zfree = Z_NULL;\n}\n\n/* -- inflate test routines -- */\n\n/* Decode a hexadecimal string, set *len to length, in[] to the bytes.  This\n   decodes liberally, in that hex digits can be adjacent, in which case two in\n   a row writes a byte.  Or they can delimited by any non-hex character, where\n   the delimiters are ignored except when a single hex digit is followed by a\n   delimiter in which case that single digit writes a byte.  The returned\n   data is allocated and must eventually be freed.  NULL is returned if out of\n   memory.  If the length is not needed, then len can be NULL. */\nlocal unsigned char *h2b(const char *hex, unsigned *len)\n{\n    unsigned char *in;\n    unsigned next, val;\n\n    in = malloc((strlen(hex) + 1) >> 1);\n    if (in == NULL)\n        return NULL;\n    next = 0;\n    val = 1;\n    do {\n        if (*hex >= '0' && *hex <= '9')\n            val = (val << 4) + *hex - '0';\n        else if (*hex >= 'A' && *hex <= 'F')\n            val = (val << 4) + *hex - 'A' + 10;\n        else if (*hex >= 'a' && *hex <= 'f')\n            val = (val << 4) + *hex - 'a' + 10;\n        else if (val != 1 && val < 32)  /* one digit followed by delimiter */\n            val += 240;                 /* make it look like two digits */\n        if (val > 255) {                /* have two digits */\n            in[next++] = val & 0xff;    /* save the decoded byte */\n            val = 1;                    /* start over */\n        }\n    } while (*hex++);       /* go through the loop with the terminating null */\n    if (len != NULL)\n        *len = next;\n    in = reallocf(in, next);\n    return in;\n}\n\n/* generic inflate() run, where hex is the hexadecimal input data, what is the\n   text to include in an error message, step is how much input data to feed\n   inflate() on each call, or zero to feed it all, win is the window bits\n   parameter to inflateInit2(), len is the size of the output buffer, and err\n   is the error code expected from the first inflate() call (the second\n   inflate() call is expected to return Z_STREAM_END).  If win is 47, then\n   header information is collected with inflateGetHeader().  If a zlib stream\n   is looking for a dictionary, then an empty dictionary is provided.\n   inflate() is run until all of the input data is consumed. */\nlocal void inf(char *hex, char *what, unsigned step, int win, unsigned len,\n               int err)\n{\n    int ret;\n    unsigned have;\n    unsigned char *in, *out;\n    z_stream strm, copy;\n    gz_header head;\n\n    mem_setup(&strm);\n    strm.avail_in = 0;\n    strm.next_in = Z_NULL;\n    ret = inflateInit2(&strm, win);\n    if (ret != Z_OK) {\n        mem_done(&strm, what);\n        return;\n    }\n    out = malloc(len);                          assert(out != NULL);\n    if (win == 47) {\n        head.extra = out;\n        head.extra_max = len;\n        head.name = out;\n        head.name_max = len;\n        head.comment = out;\n        head.comm_max = len;\n        ret = inflateGetHeader(&strm, &head);   assert(ret == Z_OK);\n    }\n    in = h2b(hex, &have);                       assert(in != NULL);\n    if (step == 0 || step > have)\n        step = have;\n    strm.avail_in = step;\n    have -= step;\n    strm.next_in = in;\n    do {\n        strm.avail_out = len;\n        strm.next_out = out;\n        ret = inflate(&strm, Z_NO_FLUSH);       assert(err == 9 || ret == err);\n        if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT)\n            break;\n        if (ret == Z_NEED_DICT) {\n            ret = inflateSetDictionary(&strm, in, 1);\n                                                assert(ret == Z_DATA_ERROR);\n            mem_limit(&strm, 1);\n            ret = inflateSetDictionary(&strm, out, 0);\n                                                assert(ret == Z_MEM_ERROR);\n            mem_limit(&strm, 0);\n            ((struct inflate_state *)strm.state)->mode = DICT;\n            ret = inflateSetDictionary(&strm, out, 0);\n                                                assert(ret == Z_OK);\n            ret = inflate(&strm, Z_NO_FLUSH);   assert(ret == Z_BUF_ERROR);\n        }\n        ret = inflateCopy(&copy, &strm);        assert(ret == Z_OK);\n        ret = inflateEnd(&copy);                assert(ret == Z_OK);\n        err = 9;                        /* don't care next time around */\n        have += strm.avail_in;\n        strm.avail_in = step > have ? have : step;\n        have -= strm.avail_in;\n    } while (strm.avail_in);\n    free(in);\n    free(out);\n    ret = inflateReset2(&strm, -8);             assert(ret == Z_OK);\n    ret = inflateEnd(&strm);                    assert(ret == Z_OK);\n    mem_done(&strm, what);\n}\n\n/* cover all of the lines in inflate.c up to inflate() */\nlocal void cover_support(void)\n{\n    int ret;\n    z_stream strm;\n\n    mem_setup(&strm);\n    strm.avail_in = 0;\n    strm.next_in = Z_NULL;\n    ret = inflateInit(&strm);                   assert(ret == Z_OK);\n    mem_used(&strm, \"inflate init\");\n    ret = inflatePrime(&strm, 5, 31);           assert(ret == Z_OK);\n    ret = inflatePrime(&strm, -1, 0);           assert(ret == Z_OK);\n    ret = inflateSetDictionary(&strm, Z_NULL, 0);\n                                                assert(ret == Z_STREAM_ERROR);\n    ret = inflateEnd(&strm);                    assert(ret == Z_OK);\n    mem_done(&strm, \"prime\");\n\n    inf(\"63 0\", \"force window allocation\", 0, -15, 1, Z_OK);\n    inf(\"63 18 5\", \"force window replacement\", 0, -8, 259, Z_OK);\n    inf(\"63 18 68 30 d0 0 0\", \"force split window update\", 4, -8, 259, Z_OK);\n    inf(\"3 0\", \"use fixed blocks\", 0, -15, 1, Z_STREAM_END);\n    inf(\"\", \"bad window size\", 0, 1, 0, Z_STREAM_ERROR);\n\n    mem_setup(&strm);\n    strm.avail_in = 0;\n    strm.next_in = Z_NULL;\n    ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream));\n                                                assert(ret == Z_VERSION_ERROR);\n    mem_done(&strm, \"wrong version\");\n\n    strm.avail_in = 0;\n    strm.next_in = Z_NULL;\n    ret = inflateInit(&strm);                   assert(ret == Z_OK);\n    ret = inflateEnd(&strm);                    assert(ret == Z_OK);\n    fputs(\"inflate built-in memory routines\\n\", stderr);\n}\n\n/* cover all inflate() header and trailer cases and code after inflate() */\nlocal void cover_wrap(void)\n{\n    int ret;\n    z_stream strm, copy;\n    unsigned char dict[257];\n\n    ret = inflate(Z_NULL, 0);                   assert(ret == Z_STREAM_ERROR);\n    ret = inflateEnd(Z_NULL);                   assert(ret == Z_STREAM_ERROR);\n    ret = inflateCopy(Z_NULL, Z_NULL);          assert(ret == Z_STREAM_ERROR);\n    fputs(\"inflate bad parameters\\n\", stderr);\n\n    inf(\"1f 8b 0 0\", \"bad gzip method\", 0, 31, 0, Z_DATA_ERROR);\n    inf(\"1f 8b 8 80\", \"bad gzip flags\", 0, 31, 0, Z_DATA_ERROR);\n    inf(\"77 85\", \"bad zlib method\", 0, 15, 0, Z_DATA_ERROR);\n    inf(\"8 99\", \"set window size from header\", 0, 0, 0, Z_OK);\n    inf(\"78 9c\", \"bad zlib window size\", 0, 8, 0, Z_DATA_ERROR);\n    inf(\"78 9c 63 0 0 0 1 0 1\", \"check adler32\", 0, 15, 1, Z_STREAM_END);\n    inf(\"1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0\", \"bad header crc\", 0, 47, 1,\n        Z_DATA_ERROR);\n    inf(\"1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0\", \"check gzip length\",\n        0, 47, 0, Z_STREAM_END);\n    inf(\"78 90\", \"bad zlib header check\", 0, 47, 0, Z_DATA_ERROR);\n    inf(\"8 b8 0 0 0 1\", \"need dictionary\", 0, 8, 0, Z_NEED_DICT);\n    inf(\"78 9c 63 0\", \"compute adler32\", 0, 15, 1, Z_OK);\n\n    mem_setup(&strm);\n    strm.avail_in = 0;\n    strm.next_in = Z_NULL;\n    ret = inflateInit2(&strm, -8);\n    strm.avail_in = 2;\n    strm.next_in = (void *)\"\\x63\";\n    strm.avail_out = 1;\n    strm.next_out = (void *)&ret;\n    mem_limit(&strm, 1);\n    ret = inflate(&strm, Z_NO_FLUSH);           assert(ret == Z_MEM_ERROR);\n    ret = inflate(&strm, Z_NO_FLUSH);           assert(ret == Z_MEM_ERROR);\n    mem_limit(&strm, 0);\n    memset(dict, 0, 257);\n    ret = inflateSetDictionary(&strm, dict, 257);\n                                                assert(ret == Z_OK);\n    mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256);\n    ret = inflatePrime(&strm, 16, 0);           assert(ret == Z_OK);\n    strm.avail_in = 2;\n    strm.next_in = (void *)\"\\x80\";\n    ret = inflateSync(&strm);                   assert(ret == Z_DATA_ERROR);\n    ret = inflate(&strm, Z_NO_FLUSH);           assert(ret == Z_STREAM_ERROR);\n    strm.avail_in = 4;\n    strm.next_in = (void *)\"\\0\\0\\xff\\xff\";\n    ret = inflateSync(&strm);                   assert(ret == Z_OK);\n    (void)inflateSyncPoint(&strm);\n    ret = inflateCopy(&copy, &strm);            assert(ret == Z_MEM_ERROR);\n    mem_limit(&strm, 0);\n    ret = inflateUndermine(&strm, 1);           assert(ret == Z_DATA_ERROR);\n    (void)inflateMark(&strm);\n    ret = inflateEnd(&strm);                    assert(ret == Z_OK);\n    mem_done(&strm, \"miscellaneous, force memory errors\");\n}\n\n/* input and output functions for inflateBack() */\nlocal unsigned pull(void *desc, unsigned char **buf)\n{\n    static unsigned int next = 0;\n    static unsigned char dat[] = {0x63, 0, 2, 0};\n    struct inflate_state *state;\n\n    if (desc == Z_NULL) {\n        next = 0;\n        return 0;   /* no input (already provided at next_in) */\n    }\n    state = (void *)((z_stream *)desc)->state;\n    if (state != Z_NULL)\n        state->mode = SYNC;     /* force an otherwise impossible situation */\n    return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0;\n}\n\nlocal int push(void *desc, unsigned char *buf, unsigned len)\n{\n    buf += len;\n    return desc != Z_NULL;      /* force error if desc not null */\n}\n\n/* cover inflateBack() up to common deflate data cases and after those */\nlocal void cover_back(void)\n{\n    int ret;\n    z_stream strm;\n    unsigned char win[32768];\n\n    ret = inflateBackInit_(Z_NULL, 0, win, 0, 0);\n                                                assert(ret == Z_VERSION_ERROR);\n    ret = inflateBackInit(Z_NULL, 0, win);      assert(ret == Z_STREAM_ERROR);\n    ret = inflateBack(Z_NULL, Z_NULL, Z_NULL, Z_NULL, Z_NULL);\n                                                assert(ret == Z_STREAM_ERROR);\n    ret = inflateBackEnd(Z_NULL);               assert(ret == Z_STREAM_ERROR);\n    fputs(\"inflateBack bad parameters\\n\", stderr);\n\n    mem_setup(&strm);\n    ret = inflateBackInit(&strm, 15, win);      assert(ret == Z_OK);\n    strm.avail_in = 2;\n    strm.next_in = (void *)\"\\x03\";\n    ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);\n                                                assert(ret == Z_STREAM_END);\n        /* force output error */\n    strm.avail_in = 3;\n    strm.next_in = (void *)\"\\x63\\x00\";\n    ret = inflateBack(&strm, pull, Z_NULL, push, &strm);\n                                                assert(ret == Z_BUF_ERROR);\n        /* force mode error by mucking with state */\n    ret = inflateBack(&strm, pull, &strm, push, Z_NULL);\n                                                assert(ret == Z_STREAM_ERROR);\n    ret = inflateBackEnd(&strm);                assert(ret == Z_OK);\n    mem_done(&strm, \"inflateBack bad state\");\n\n    ret = inflateBackInit(&strm, 15, win);      assert(ret == Z_OK);\n    ret = inflateBackEnd(&strm);                assert(ret == Z_OK);\n    fputs(\"inflateBack built-in memory routines\\n\", stderr);\n}\n\n/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */\nlocal int try(char *hex, char *id, int err)\n{\n    int ret;\n    unsigned len, size;\n    unsigned char *in, *out, *win;\n    char *prefix;\n    z_stream strm;\n\n    /* convert to hex */\n    in = h2b(hex, &len);\n    assert(in != NULL);\n\n    /* allocate work areas */\n    size = len << 3;\n    out = malloc(size);\n    assert(out != NULL);\n    win = malloc(32768);\n    assert(win != NULL);\n    prefix = malloc(strlen(id) + 6);\n    assert(prefix != NULL);\n\n    /* first with inflate */\n    strcpy(prefix, id);\n    strcat(prefix, \"-late\");\n    mem_setup(&strm);\n    strm.avail_in = 0;\n    strm.next_in = Z_NULL;\n    ret = inflateInit2(&strm, err < 0 ? 47 : -15);\n    assert(ret == Z_OK);\n    strm.avail_in = len;\n    strm.next_in = in;\n    do {\n        strm.avail_out = size;\n        strm.next_out = out;\n        ret = inflate(&strm, Z_TREES);\n        assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR);\n        if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT)\n            break;\n    } while (strm.avail_in || strm.avail_out == 0);\n    if (err) {\n        assert(ret == Z_DATA_ERROR);\n        assert(strcmp(id, strm.msg) == 0);\n    }\n    inflateEnd(&strm);\n    mem_done(&strm, prefix);\n\n    /* then with inflateBack */\n    if (err >= 0) {\n        strcpy(prefix, id);\n        strcat(prefix, \"-back\");\n        mem_setup(&strm);\n        ret = inflateBackInit(&strm, 15, win);\n        assert(ret == Z_OK);\n        strm.avail_in = len;\n        strm.next_in = in;\n        ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);\n        assert(ret != Z_STREAM_ERROR);\n        if (err) {\n            assert(ret == Z_DATA_ERROR);\n            assert(strcmp(id, strm.msg) == 0);\n        }\n        inflateBackEnd(&strm);\n        mem_done(&strm, prefix);\n    }\n\n    /* clean up */\n    free(prefix);\n    free(win);\n    free(out);\n    free(in);\n    return ret;\n}\n\n/* cover deflate data cases in both inflate() and inflateBack() */\nlocal void cover_inflate(void)\n{\n    try(\"0 0 0 0 0\", \"invalid stored block lengths\", 1);\n    try(\"3 0\", \"fixed\", 0);\n    try(\"6\", \"invalid block type\", 1);\n    try(\"1 1 0 fe ff 0\", \"stored\", 0);\n    try(\"fc 0 0\", \"too many length or distance symbols\", 1);\n    try(\"4 0 fe ff\", \"invalid code lengths set\", 1);\n    try(\"4 0 24 49 0\", \"invalid bit length repeat\", 1);\n    try(\"4 0 24 e9 ff ff\", \"invalid bit length repeat\", 1);\n    try(\"4 0 24 e9 ff 6d\", \"invalid code -- missing end-of-block\", 1);\n    try(\"4 80 49 92 24 49 92 24 71 ff ff 93 11 0\",\n        \"invalid literal/lengths set\", 1);\n    try(\"4 80 49 92 24 49 92 24 f b4 ff ff c3 84\", \"invalid distances set\", 1);\n    try(\"4 c0 81 8 0 0 0 0 20 7f eb b 0 0\", \"invalid literal/length code\", 1);\n    try(\"2 7e ff ff\", \"invalid distance code\", 1);\n    try(\"c c0 81 0 0 0 0 0 90 ff 6b 4 0\", \"invalid distance too far back\", 1);\n\n    /* also trailer mismatch just in inflate() */\n    try(\"1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1\", \"incorrect data check\", -1);\n    try(\"1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1\",\n        \"incorrect length check\", -1);\n    try(\"5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c\", \"pull 17\", 0);\n    try(\"5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f\",\n        \"long code\", 0);\n    try(\"ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f\", \"length extra\", 0);\n    try(\"ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c\",\n        \"long distance and extra\", 0);\n    try(\"ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \"\n        \"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6\", \"window end\", 0);\n    inf(\"2 8 20 80 0 3 0\", \"inflate_fast TYPE return\", 0, -15, 258,\n        Z_STREAM_END);\n    inf(\"63 18 5 40 c 0\", \"window wrap\", 3, -8, 300, Z_OK);\n}\n\n/* cover remaining lines in inftrees.c */\nlocal void cover_trees(void)\n{\n    int ret;\n    unsigned bits;\n    unsigned short lens[16], work[16];\n    code *next, table[ENOUGH_DISTS];\n\n    /* we need to call inflate_table() directly in order to manifest not-\n       enough errors, since zlib insures that enough is always enough */\n    for (bits = 0; bits < 15; bits++)\n        lens[bits] = (unsigned short)(bits + 1);\n    lens[15] = 15;\n    next = table;\n    bits = 15;\n    ret = inflate_table(DISTS, lens, 16, &next, &bits, work);\n                                                assert(ret == 1);\n    next = table;\n    bits = 1;\n    ret = inflate_table(DISTS, lens, 16, &next, &bits, work);\n                                                assert(ret == 1);\n    fputs(\"inflate_table not enough errors\\n\", stderr);\n}\n\n/* cover remaining inffast.c decoding and window copying */\nlocal void cover_fast(void)\n{\n    inf(\"e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68\"\n        \" ff 7f 0f 0 0 0\", \"fast length extra bits\", 0, -8, 258, Z_DATA_ERROR);\n    inf(\"25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49\"\n        \" 50 fe ff ff 3f 0 0\", \"fast distance extra bits\", 0, -8, 258,\n        Z_DATA_ERROR);\n    inf(\"3 7e 0 0 0 0 0\", \"fast invalid distance code\", 0, -8, 258,\n        Z_DATA_ERROR);\n    inf(\"1b 7 0 0 0 0 0\", \"fast invalid literal/length code\", 0, -8, 258,\n        Z_DATA_ERROR);\n    inf(\"d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0\",\n        \"fast 2nd level codes and too far back\", 0, -8, 258, Z_DATA_ERROR);\n    inf(\"63 18 5 8c 10 8 0 0 0 0\", \"very common case\", 0, -8, 259, Z_OK);\n    inf(\"63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0\",\n        \"contiguous and wrap around window\", 6, -8, 259, Z_OK);\n    inf(\"63 0 3 0 0 0 0 0\", \"copy direct from output\", 0, -8, 259,\n        Z_STREAM_END);\n}\n\nint main(void)\n{\n    fprintf(stderr, \"%s\\n\", zlibVersion());\n    cover_support();\n    cover_wrap();\n    cover_back();\n    cover_inflate();\n    cover_trees();\n    cover_fast();\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/test/minigzip.c",
    "content": "/* minigzip.c -- simulate gzip using the zlib compression library\n * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly.\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/*\n * minigzip is a minimal implementation of the gzip utility. This is\n * only an example of using zlib and isn't meant to replace the\n * full-featured gzip. No attempt is made to deal with file systems\n * limiting names to 14 or 8+3 characters, etc... Error checking is\n * very limited. So use minigzip only for testing; use gzip for the\n * real thing. On MSDOS, use only on file names without extension\n * or in pipe mode.\n */\n\n/* @(#) $Id$ */\n\n#include \"zlib.h\"\n#include <stdio.h>\n\n#ifdef STDC\n#  include <string.h>\n#  include <stdlib.h>\n#endif\n\n#ifdef USE_MMAP\n#  include <sys/types.h>\n#  include <sys/mman.h>\n#  include <sys/stat.h>\n#endif\n\n#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)\n#  include <fcntl.h>\n#  include <io.h>\n#  ifdef UNDER_CE\n#    include <stdlib.h>\n#  endif\n#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)\n#else\n#  define SET_BINARY_MODE(file)\n#endif\n\n#ifdef _MSC_VER\n#  define snprintf _snprintf\n#endif\n\n#ifdef VMS\n#  define unlink delete\n#  define GZ_SUFFIX \"-gz\"\n#endif\n#ifdef RISCOS\n#  define unlink remove\n#  define GZ_SUFFIX \"-gz\"\n#  define fileno(file) file->__file\n#endif\n#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os\n#  include <unix.h> /* for fileno */\n#endif\n\n#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)\n#ifndef WIN32 /* unlink already in stdio.h for WIN32 */\n  extern int unlink OF((const char *));\n#endif\n#endif\n\n#if defined(UNDER_CE)\n#  include <windows.h>\n#  define perror(s) pwinerror(s)\n\n/* Map the Windows error number in ERROR to a locale-dependent error\n   message string and return a pointer to it.  Typically, the values\n   for ERROR come from GetLastError.\n\n   The string pointed to shall not be modified by the application,\n   but may be overwritten by a subsequent call to strwinerror\n\n   The strwinerror function does not change the current setting\n   of GetLastError.  */\n\nstatic char *strwinerror (error)\n     DWORD error;\n{\n    static char buf[1024];\n\n    wchar_t *msgbuf;\n    DWORD lasterr = GetLastError();\n    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM\n        | FORMAT_MESSAGE_ALLOCATE_BUFFER,\n        NULL,\n        error,\n        0, /* Default language */\n        (LPVOID)&msgbuf,\n        0,\n        NULL);\n    if (chars != 0) {\n        /* If there is an \\r\\n appended, zap it.  */\n        if (chars >= 2\n            && msgbuf[chars - 2] == '\\r' && msgbuf[chars - 1] == '\\n') {\n            chars -= 2;\n            msgbuf[chars] = 0;\n        }\n\n        if (chars > sizeof (buf) - 1) {\n            chars = sizeof (buf) - 1;\n            msgbuf[chars] = 0;\n        }\n\n        wcstombs(buf, msgbuf, chars + 1);\n        LocalFree(msgbuf);\n    }\n    else {\n        sprintf(buf, \"unknown win32 error (%ld)\", error);\n    }\n\n    SetLastError(lasterr);\n    return buf;\n}\n\nstatic void pwinerror (s)\n    const char *s;\n{\n    if (s && *s)\n        fprintf(stderr, \"%s: %s\\n\", s, strwinerror(GetLastError ()));\n    else\n        fprintf(stderr, \"%s\\n\", strwinerror(GetLastError ()));\n}\n\n#endif /* UNDER_CE */\n\n#ifndef GZ_SUFFIX\n#  define GZ_SUFFIX \".gz\"\n#endif\n#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)\n\n#define BUFLEN      16384\n#define MAX_NAME_LEN 1024\n\n#ifdef MAXSEG_64K\n#  define local static\n   /* Needed for systems with limitation on stack size. */\n#else\n#  define local\n#endif\n\n#ifdef Z_SOLO\n/* for Z_SOLO, create simplified gz* functions using deflate and inflate */\n\n#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)\n#  include <unistd.h>       /* for unlink() */\n#endif\n\nvoid *myalloc OF((void *, unsigned, unsigned));\nvoid myfree OF((void *, void *));\n\nvoid *myalloc(q, n, m)\n    void *q;\n    unsigned n, m;\n{\n    q = Z_NULL;\n    return calloc(n, m);\n}\n\nvoid myfree(q, p)\n    void *q, *p;\n{\n    q = Z_NULL;\n    free(p);\n}\n\ntypedef struct gzFile_s {\n    FILE *file;\n    int write;\n    int err;\n    char *msg;\n    z_stream strm;\n} *gzFile;\n\ngzFile gzopen OF((const char *, const char *));\ngzFile gzdopen OF((int, const char *));\ngzFile gz_open OF((const char *, int, const char *));\n\ngzFile gzopen(path, mode)\nconst char *path;\nconst char *mode;\n{\n    return gz_open(path, -1, mode);\n}\n\ngzFile gzdopen(fd, mode)\nint fd;\nconst char *mode;\n{\n    return gz_open(NULL, fd, mode);\n}\n\ngzFile gz_open(path, fd, mode)\n    const char *path;\n    int fd;\n    const char *mode;\n{\n    gzFile gz;\n    int ret;\n\n    gz = malloc(sizeof(struct gzFile_s));\n    if (gz == NULL)\n        return NULL;\n    gz->write = strchr(mode, 'w') != NULL;\n    gz->strm.zalloc = myalloc;\n    gz->strm.zfree = myfree;\n    gz->strm.opaque = Z_NULL;\n    if (gz->write)\n        ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);\n    else {\n        gz->strm.next_in = 0;\n        gz->strm.avail_in = Z_NULL;\n        ret = inflateInit2(&(gz->strm), 15 + 16);\n    }\n    if (ret != Z_OK) {\n        free(gz);\n        return NULL;\n    }\n    gz->file = path == NULL ? fdopen(fd, gz->write ? \"wb\" : \"rb\") :\n                              fopen(path, gz->write ? \"wb\" : \"rb\");\n    if (gz->file == NULL) {\n        gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));\n        free(gz);\n        return NULL;\n    }\n    gz->err = 0;\n    gz->msg = \"\";\n    return gz;\n}\n\nint gzwrite OF((gzFile, const void *, unsigned));\n\nint gzwrite(gz, buf, len)\n    gzFile gz;\n    const void *buf;\n    unsigned len;\n{\n    z_stream *strm;\n    unsigned char out[BUFLEN];\n\n    if (gz == NULL || !gz->write)\n        return 0;\n    strm = &(gz->strm);\n    strm->next_in = (void *)buf;\n    strm->avail_in = len;\n    do {\n        strm->next_out = out;\n        strm->avail_out = BUFLEN;\n        (void)deflate(strm, Z_NO_FLUSH);\n        fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);\n    } while (strm->avail_out == 0);\n    return len;\n}\n\nint gzread OF((gzFile, void *, unsigned));\n\nint gzread(gz, buf, len)\n    gzFile gz;\n    void *buf;\n    unsigned len;\n{\n    int ret;\n    unsigned got;\n    unsigned char in[1];\n    z_stream *strm;\n\n    if (gz == NULL || gz->write)\n        return 0;\n    if (gz->err)\n        return 0;\n    strm = &(gz->strm);\n    strm->next_out = (void *)buf;\n    strm->avail_out = len;\n    do {\n        got = fread(in, 1, 1, gz->file);\n        if (got == 0)\n            break;\n        strm->next_in = in;\n        strm->avail_in = 1;\n        ret = inflate(strm, Z_NO_FLUSH);\n        if (ret == Z_DATA_ERROR) {\n            gz->err = Z_DATA_ERROR;\n            gz->msg = strm->msg;\n            return 0;\n        }\n        if (ret == Z_STREAM_END)\n            inflateReset(strm);\n    } while (strm->avail_out);\n    return len - strm->avail_out;\n}\n\nint gzclose OF((gzFile));\n\nint gzclose(gz)\n    gzFile gz;\n{\n    z_stream *strm;\n    unsigned char out[BUFLEN];\n\n    if (gz == NULL)\n        return Z_STREAM_ERROR;\n    strm = &(gz->strm);\n    if (gz->write) {\n        strm->next_in = Z_NULL;\n        strm->avail_in = 0;\n        do {\n            strm->next_out = out;\n            strm->avail_out = BUFLEN;\n            (void)deflate(strm, Z_FINISH);\n            fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);\n        } while (strm->avail_out == 0);\n        deflateEnd(strm);\n    }\n    else\n        inflateEnd(strm);\n    fclose(gz->file);\n    free(gz);\n    return Z_OK;\n}\n\nconst char *gzerror OF((gzFile, int *));\n\nconst char *gzerror(gz, err)\n    gzFile gz;\n    int *err;\n{\n    *err = gz->err;\n    return gz->msg;\n}\n\n#endif\n\nchar *prog;\n\nvoid error            OF((const char *msg));\nvoid gz_compress      OF((FILE   *in, gzFile out));\n#ifdef USE_MMAP\nint  gz_compress_mmap OF((FILE   *in, gzFile out));\n#endif\nvoid gz_uncompress    OF((gzFile in, FILE   *out));\nvoid file_compress    OF((char  *file, char *mode));\nvoid file_uncompress  OF((char  *file));\nint  main             OF((int argc, char *argv[]));\n\n/* ===========================================================================\n * Display error message and exit\n */\nvoid error(msg)\n    const char *msg;\n{\n    fprintf(stderr, \"%s: %s\\n\", prog, msg);\n    exit(1);\n}\n\n/* ===========================================================================\n * Compress input to output then close both files.\n */\n\nvoid gz_compress(in, out)\n    FILE   *in;\n    gzFile out;\n{\n    local char buf[BUFLEN];\n    int len;\n    int err;\n\n#ifdef USE_MMAP\n    /* Try first compressing with mmap. If mmap fails (minigzip used in a\n     * pipe), use the normal fread loop.\n     */\n    if (gz_compress_mmap(in, out) == Z_OK) return;\n#endif\n    for (;;) {\n        len = (int)fread(buf, 1, sizeof(buf), in);\n        if (ferror(in)) {\n            perror(\"fread\");\n            exit(1);\n        }\n        if (len == 0) break;\n\n        if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));\n    }\n    fclose(in);\n    if (gzclose(out) != Z_OK) error(\"failed gzclose\");\n}\n\n#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */\n\n/* Try compressing the input file at once using mmap. Return Z_OK if\n * if success, Z_ERRNO otherwise.\n */\nint gz_compress_mmap(in, out)\n    FILE   *in;\n    gzFile out;\n{\n    int len;\n    int err;\n    int ifd = fileno(in);\n    caddr_t buf;    /* mmap'ed buffer for the entire input file */\n    off_t buf_len;  /* length of the input file */\n    struct stat sb;\n\n    /* Determine the size of the file, needed for mmap: */\n    if (fstat(ifd, &sb) < 0) return Z_ERRNO;\n    buf_len = sb.st_size;\n    if (buf_len <= 0) return Z_ERRNO;\n\n    /* Now do the actual mmap: */\n    buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);\n    if (buf == (caddr_t)(-1)) return Z_ERRNO;\n\n    /* Compress the whole file at once: */\n    len = gzwrite(out, (char *)buf, (unsigned)buf_len);\n\n    if (len != (int)buf_len) error(gzerror(out, &err));\n\n    munmap(buf, buf_len);\n    fclose(in);\n    if (gzclose(out) != Z_OK) error(\"failed gzclose\");\n    return Z_OK;\n}\n#endif /* USE_MMAP */\n\n/* ===========================================================================\n * Uncompress input to output then close both files.\n */\nvoid gz_uncompress(in, out)\n    gzFile in;\n    FILE   *out;\n{\n    local char buf[BUFLEN];\n    int len;\n    int err;\n\n    for (;;) {\n        len = gzread(in, buf, sizeof(buf));\n        if (len < 0) error (gzerror(in, &err));\n        if (len == 0) break;\n\n        if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {\n            error(\"failed fwrite\");\n        }\n    }\n    if (fclose(out)) error(\"failed fclose\");\n\n    if (gzclose(in) != Z_OK) error(\"failed gzclose\");\n}\n\n\n/* ===========================================================================\n * Compress the given file: create a corresponding .gz file and remove the\n * original.\n */\nvoid file_compress(file, mode)\n    char  *file;\n    char  *mode;\n{\n    local char outfile[MAX_NAME_LEN];\n    FILE  *in;\n    gzFile out;\n\n    if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {\n        fprintf(stderr, \"%s: filename too long\\n\", prog);\n        exit(1);\n    }\n\n#if !defined(NO_snprintf) && !defined(NO_vsnprintf)\n    snprintf(outfile, sizeof(outfile), \"%s%s\", file, GZ_SUFFIX);\n#else\n    strcpy(outfile, file);\n    strcat(outfile, GZ_SUFFIX);\n#endif\n\n    in = fopen(file, \"rb\");\n    if (in == NULL) {\n        perror(file);\n        exit(1);\n    }\n    out = gzopen(outfile, mode);\n    if (out == NULL) {\n        fprintf(stderr, \"%s: can't gzopen %s\\n\", prog, outfile);\n        exit(1);\n    }\n    gz_compress(in, out);\n\n    unlink(file);\n}\n\n\n/* ===========================================================================\n * Uncompress the given file and remove the original.\n */\nvoid file_uncompress(file)\n    char  *file;\n{\n    local char buf[MAX_NAME_LEN];\n    char *infile, *outfile;\n    FILE  *out;\n    gzFile in;\n    size_t len = strlen(file);\n\n    if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {\n        fprintf(stderr, \"%s: filename too long\\n\", prog);\n        exit(1);\n    }\n\n#if !defined(NO_snprintf) && !defined(NO_vsnprintf)\n    snprintf(buf, sizeof(buf), \"%s\", file);\n#else\n    strcpy(buf, file);\n#endif\n\n    if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {\n        infile = file;\n        outfile = buf;\n        outfile[len-3] = '\\0';\n    } else {\n        outfile = file;\n        infile = buf;\n#if !defined(NO_snprintf) && !defined(NO_vsnprintf)\n        snprintf(buf + len, sizeof(buf) - len, \"%s\", GZ_SUFFIX);\n#else\n        strcat(infile, GZ_SUFFIX);\n#endif\n    }\n    in = gzopen(infile, \"rb\");\n    if (in == NULL) {\n        fprintf(stderr, \"%s: can't gzopen %s\\n\", prog, infile);\n        exit(1);\n    }\n    out = fopen(outfile, \"wb\");\n    if (out == NULL) {\n        perror(file);\n        exit(1);\n    }\n\n    gz_uncompress(in, out);\n\n    unlink(infile);\n}\n\n\n/* ===========================================================================\n * Usage:  minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]\n *   -c : write to standard output\n *   -d : decompress\n *   -f : compress with Z_FILTERED\n *   -h : compress with Z_HUFFMAN_ONLY\n *   -r : compress with Z_RLE\n *   -1 to -9 : compression level\n */\n\nint main(argc, argv)\n    int argc;\n    char *argv[];\n{\n    int copyout = 0;\n    int uncompr = 0;\n    gzFile file;\n    char *bname, outmode[20];\n\n#if !defined(NO_snprintf) && !defined(NO_vsnprintf)\n    snprintf(outmode, sizeof(outmode), \"%s\", \"wb6 \");\n#else\n    strcpy(outmode, \"wb6 \");\n#endif\n\n    prog = argv[0];\n    bname = strrchr(argv[0], '/');\n    if (bname)\n      bname++;\n    else\n      bname = argv[0];\n    argc--, argv++;\n\n    if (!strcmp(bname, \"gunzip\"))\n      uncompr = 1;\n    else if (!strcmp(bname, \"zcat\"))\n      copyout = uncompr = 1;\n\n    while (argc > 0) {\n      if (strcmp(*argv, \"-c\") == 0)\n        copyout = 1;\n      else if (strcmp(*argv, \"-d\") == 0)\n        uncompr = 1;\n      else if (strcmp(*argv, \"-f\") == 0)\n        outmode[3] = 'f';\n      else if (strcmp(*argv, \"-h\") == 0)\n        outmode[3] = 'h';\n      else if (strcmp(*argv, \"-r\") == 0)\n        outmode[3] = 'R';\n      else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&\n               (*argv)[2] == 0)\n        outmode[2] = (*argv)[1];\n      else\n        break;\n      argc--, argv++;\n    }\n    if (outmode[3] == ' ')\n        outmode[3] = 0;\n    if (argc == 0) {\n        SET_BINARY_MODE(stdin);\n        SET_BINARY_MODE(stdout);\n        if (uncompr) {\n            file = gzdopen(fileno(stdin), \"rb\");\n            if (file == NULL) error(\"can't gzdopen stdin\");\n            gz_uncompress(file, stdout);\n        } else {\n            file = gzdopen(fileno(stdout), outmode);\n            if (file == NULL) error(\"can't gzdopen stdout\");\n            gz_compress(stdin, file);\n        }\n    } else {\n        if (copyout) {\n            SET_BINARY_MODE(stdout);\n        }\n        do {\n            if (uncompr) {\n                if (copyout) {\n                    file = gzopen(*argv, \"rb\");\n                    if (file == NULL)\n                        fprintf(stderr, \"%s: can't gzopen %s\\n\", prog, *argv);\n                    else\n                        gz_uncompress(file, stdout);\n                } else {\n                    file_uncompress(*argv);\n                }\n            } else {\n                if (copyout) {\n                    FILE * in = fopen(*argv, \"rb\");\n\n                    if (in == NULL) {\n                        perror(*argv);\n                    } else {\n                        file = gzdopen(fileno(stdout), outmode);\n                        if (file == NULL) error(\"can't gzdopen stdout\");\n\n                        gz_compress(in, file);\n                    }\n\n                } else {\n                    file_compress(*argv, outmode);\n                }\n            }\n        } while (argv++, --argc);\n    }\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/treebuild.xml",
    "content": "<?xml version=\"1.0\" ?>\n<package name=\"zlib\" version=\"1.2.8\">\n    <library name=\"zlib\" dlversion=\"1.2.8\" dlname=\"z\">\n\t<property name=\"description\"> zip compression library </property>\n\t<property name=\"include-target-dir\" value=\"$(@PACKAGE/install-includedir)\" />\n\n\t<!-- fixme: not implemented yet -->\n\t<property name=\"compiler/c/inline\" value=\"yes\" />\n\n\t<include-file name=\"zlib.h\" scope=\"public\" mode=\"644\" />\n\t<include-file name=\"zconf.h\" scope=\"public\" mode=\"644\" />\n\n\t<source name=\"adler32.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t</source>\n\t<source name=\"compress.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t</source>\n\t<source name=\"crc32.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t    <depend name=\"crc32.h\" />\n\t</source>\n\t<source name=\"gzclose.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t    <depend name=\"gzguts.h\" />\n\t</source>\n\t<source name=\"gzlib.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t    <depend name=\"gzguts.h\" />\n\t</source>\n\t<source name=\"gzread.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t    <depend name=\"gzguts.h\" />\n\t</source>\n\t<source name=\"gzwrite.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t    <depend name=\"gzguts.h\" />\n\t</source>\n\t<source name=\"uncompr.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t</source>\n\t<source name=\"deflate.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t    <depend name=\"zutil.h\" />\n\t    <depend name=\"deflate.h\" />\n\t</source>\n\t<source name=\"trees.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t    <depend name=\"zutil.h\" />\n\t    <depend name=\"deflate.h\" />\n\t    <depend name=\"trees.h\" />\n\t</source>\n\t<source name=\"zutil.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t    <depend name=\"zutil.h\" />\n\t</source>\n\t<source name=\"inflate.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t    <depend name=\"zutil.h\" />\n\t    <depend name=\"inftrees.h\" />\n\t    <depend name=\"inflate.h\" />\n\t    <depend name=\"inffast.h\" />\n\t</source>\n\t<source name=\"infback.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t    <depend name=\"zutil.h\" />\n\t    <depend name=\"inftrees.h\" />\n\t    <depend name=\"inflate.h\" />\n\t    <depend name=\"inffast.h\" />\n\t</source>\n\t<source name=\"inftrees.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t    <depend name=\"zutil.h\" />\n\t    <depend name=\"inftrees.h\" />\n\t</source>\n\t<source name=\"inffast.c\">\n\t    <depend name=\"zlib.h\" />\n\t    <depend name=\"zconf.h\" />\n\t    <depend name=\"zutil.h\" />\n\t    <depend name=\"inftrees.h\" />\n\t    <depend name=\"inflate.h\" />\n\t    <depend name=\"inffast.h\" />\n\t</source>\n    </library>\n</package>\n\n<!--\nCFLAGS=-O\n#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7\n#CFLAGS=-g -DDEBUG\n#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \\\n#           -Wstrict-prototypes -Wmissing-prototypes\n\n# OBJA =\n# to use the asm code: make OBJA=match.o\n#\nmatch.o: match.S\n\t$(CPP) match.S > _match.s\n\t$(CC) -c _match.s\n\tmv _match.o match.o\n\trm -f _match.s\n-->\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/trees.c",
    "content": "/* trees.c -- output deflated data using Huffman coding\n * Copyright (C) 1995-2012 Jean-loup Gailly\n * detect_data_type() function provided freely by Cosmin Truta, 2006\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/*\n *  ALGORITHM\n *\n *      The \"deflation\" process uses several Huffman trees. The more\n *      common source values are represented by shorter bit sequences.\n *\n *      Each code tree is stored in a compressed form which is itself\n * a Huffman encoding of the lengths of all the code strings (in\n * ascending order by source values).  The actual code strings are\n * reconstructed from the lengths in the inflate process, as described\n * in the deflate specification.\n *\n *  REFERENCES\n *\n *      Deutsch, L.P.,\"'Deflate' Compressed Data Format Specification\".\n *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc\n *\n *      Storer, James A.\n *          Data Compression:  Methods and Theory, pp. 49-50.\n *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.\n *\n *      Sedgewick, R.\n *          Algorithms, p290.\n *          Addison-Wesley, 1983. ISBN 0-201-06672-6.\n */\n\n/* @(#) $Id$ */\n\n/* #define GEN_TREES_H */\n\n#include \"deflate.h\"\n\n#ifdef DEBUG\n#  include <ctype.h>\n#endif\n\n/* ===========================================================================\n * Constants\n */\n\n#define MAX_BL_BITS 7\n/* Bit length codes must not exceed MAX_BL_BITS bits */\n\n#define END_BLOCK 256\n/* end of block literal code */\n\n#define REP_3_6      16\n/* repeat previous bit length 3-6 times (2 bits of repeat count) */\n\n#define REPZ_3_10    17\n/* repeat a zero length 3-10 times  (3 bits of repeat count) */\n\n#define REPZ_11_138  18\n/* repeat a zero length 11-138 times  (7 bits of repeat count) */\n\nlocal const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */\n   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};\n\nlocal const int extra_dbits[D_CODES] /* extra bits for each distance code */\n   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};\n\nlocal const int extra_blbits[BL_CODES]/* extra bits for each bit length code */\n   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};\n\nlocal const uch bl_order[BL_CODES]\n   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};\n/* The lengths of the bit length codes are sent in order of decreasing\n * probability, to avoid transmitting the lengths for unused bit length codes.\n */\n\n/* ===========================================================================\n * Local data. These are initialized only once.\n */\n\n#define DIST_CODE_LEN  512 /* see definition of array dist_code below */\n\n#if defined(GEN_TREES_H) || !defined(STDC)\n/* non ANSI compilers may not accept trees.h */\n\nlocal ct_data static_ltree[L_CODES+2];\n/* The static literal tree. Since the bit lengths are imposed, there is no\n * need for the L_CODES extra codes used during heap construction. However\n * The codes 286 and 287 are needed to build a canonical tree (see _tr_init\n * below).\n */\n\nlocal ct_data static_dtree[D_CODES];\n/* The static distance tree. (Actually a trivial tree since all codes use\n * 5 bits.)\n */\n\nuch _dist_code[DIST_CODE_LEN];\n/* Distance codes. The first 256 values correspond to the distances\n * 3 .. 258, the last 256 values correspond to the top 8 bits of\n * the 15 bit distances.\n */\n\nuch _length_code[MAX_MATCH-MIN_MATCH+1];\n/* length code for each normalized match length (0 == MIN_MATCH) */\n\nlocal int base_length[LENGTH_CODES];\n/* First normalized length for each code (0 = MIN_MATCH) */\n\nlocal int base_dist[D_CODES];\n/* First normalized distance for each code (0 = distance of 1) */\n\n#else\n#  include \"trees.h\"\n#endif /* GEN_TREES_H */\n\nstruct static_tree_desc_s {\n    const ct_data *static_tree;  /* static tree or NULL */\n    const intf *extra_bits;      /* extra bits for each code or NULL */\n    int     extra_base;          /* base index for extra_bits */\n    int     elems;               /* max number of elements in the tree */\n    int     max_length;          /* max bit length for the codes */\n};\n\nlocal static_tree_desc  static_l_desc =\n{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};\n\nlocal static_tree_desc  static_d_desc =\n{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};\n\nlocal static_tree_desc  static_bl_desc =\n{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};\n\n/* ===========================================================================\n * Local (static) routines in this file.\n */\n\nlocal void tr_static_init OF((void));\nlocal void init_block     OF((deflate_state *s));\nlocal void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));\nlocal void gen_bitlen     OF((deflate_state *s, tree_desc *desc));\nlocal void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));\nlocal void build_tree     OF((deflate_state *s, tree_desc *desc));\nlocal void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));\nlocal void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));\nlocal int  build_bl_tree  OF((deflate_state *s));\nlocal void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,\n                              int blcodes));\nlocal void compress_block OF((deflate_state *s, const ct_data *ltree,\n                              const ct_data *dtree));\nlocal int  detect_data_type OF((deflate_state *s));\nlocal unsigned bi_reverse OF((unsigned value, int length));\nlocal void bi_windup      OF((deflate_state *s));\nlocal void bi_flush       OF((deflate_state *s));\nlocal void copy_block     OF((deflate_state *s, charf *buf, unsigned len,\n                              int header));\n\n#ifdef GEN_TREES_H\nlocal void gen_trees_header OF((void));\n#endif\n\n#ifndef DEBUG\n#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)\n   /* Send a code of the given tree. c and tree must not have side effects */\n\n#else /* DEBUG */\n#  define send_code(s, c, tree) \\\n     { if (z_verbose>2) fprintf(stderr,\"\\ncd %3d \",(c)); \\\n       send_bits(s, tree[c].Code, tree[c].Len); }\n#endif\n\n/* ===========================================================================\n * Output a short LSB first on the stream.\n * IN assertion: there is enough room in pendingBuf.\n */\n#define put_short(s, w) { \\\n    put_byte(s, (uch)((w) & 0xff)); \\\n    put_byte(s, (uch)((ush)(w) >> 8)); \\\n}\n\n/* ===========================================================================\n * Send a value on a given number of bits.\n * IN assertion: length <= 16 and value fits in length bits.\n */\n#ifdef DEBUG\nlocal void send_bits      OF((deflate_state *s, int value, int length));\n\nlocal void send_bits(s, value, length)\n    deflate_state *s;\n    int value;  /* value to send */\n    int length; /* number of bits */\n{\n    Tracevv((stderr,\" l %2d v %4x \", length, value));\n    Assert(length > 0 && length <= 15, \"invalid length\");\n    s->bits_sent += (ulg)length;\n\n    /* If not enough room in bi_buf, use (valid) bits from bi_buf and\n     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))\n     * unused bits in value.\n     */\n    if (s->bi_valid > (int)Buf_size - length) {\n        s->bi_buf |= (ush)value << s->bi_valid;\n        put_short(s, s->bi_buf);\n        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);\n        s->bi_valid += length - Buf_size;\n    } else {\n        s->bi_buf |= (ush)value << s->bi_valid;\n        s->bi_valid += length;\n    }\n}\n#else /* !DEBUG */\n\n#define send_bits(s, value, length) \\\n{ int len = length;\\\n  if (s->bi_valid > (int)Buf_size - len) {\\\n    int val = value;\\\n    s->bi_buf |= (ush)val << s->bi_valid;\\\n    put_short(s, s->bi_buf);\\\n    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\\\n    s->bi_valid += len - Buf_size;\\\n  } else {\\\n    s->bi_buf |= (ush)(value) << s->bi_valid;\\\n    s->bi_valid += len;\\\n  }\\\n}\n#endif /* DEBUG */\n\n\n/* the arguments must not have side effects */\n\n/* ===========================================================================\n * Initialize the various 'constant' tables.\n */\nlocal void tr_static_init()\n{\n#if defined(GEN_TREES_H) || !defined(STDC)\n    static int static_init_done = 0;\n    int n;        /* iterates over tree elements */\n    int bits;     /* bit counter */\n    int length;   /* length value */\n    int code;     /* code value */\n    int dist;     /* distance index */\n    ush bl_count[MAX_BITS+1];\n    /* number of codes at each bit length for an optimal tree */\n\n    if (static_init_done) return;\n\n    /* For some embedded targets, global variables are not initialized: */\n#ifdef NO_INIT_GLOBAL_POINTERS\n    static_l_desc.static_tree = static_ltree;\n    static_l_desc.extra_bits = extra_lbits;\n    static_d_desc.static_tree = static_dtree;\n    static_d_desc.extra_bits = extra_dbits;\n    static_bl_desc.extra_bits = extra_blbits;\n#endif\n\n    /* Initialize the mapping length (0..255) -> length code (0..28) */\n    length = 0;\n    for (code = 0; code < LENGTH_CODES-1; code++) {\n        base_length[code] = length;\n        for (n = 0; n < (1<<extra_lbits[code]); n++) {\n            _length_code[length++] = (uch)code;\n        }\n    }\n    Assert (length == 256, \"tr_static_init: length != 256\");\n    /* Note that the length 255 (match length 258) can be represented\n     * in two different ways: code 284 + 5 bits or code 285, so we\n     * overwrite length_code[255] to use the best encoding:\n     */\n    _length_code[length-1] = (uch)code;\n\n    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */\n    dist = 0;\n    for (code = 0 ; code < 16; code++) {\n        base_dist[code] = dist;\n        for (n = 0; n < (1<<extra_dbits[code]); n++) {\n            _dist_code[dist++] = (uch)code;\n        }\n    }\n    Assert (dist == 256, \"tr_static_init: dist != 256\");\n    dist >>= 7; /* from now on, all distances are divided by 128 */\n    for ( ; code < D_CODES; code++) {\n        base_dist[code] = dist << 7;\n        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {\n            _dist_code[256 + dist++] = (uch)code;\n        }\n    }\n    Assert (dist == 256, \"tr_static_init: 256+dist != 512\");\n\n    /* Construct the codes of the static literal tree */\n    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;\n    n = 0;\n    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;\n    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;\n    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;\n    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;\n    /* Codes 286 and 287 do not exist, but we must include them in the\n     * tree construction to get a canonical Huffman tree (longest code\n     * all ones)\n     */\n    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);\n\n    /* The static distance tree is trivial: */\n    for (n = 0; n < D_CODES; n++) {\n        static_dtree[n].Len = 5;\n        static_dtree[n].Code = bi_reverse((unsigned)n, 5);\n    }\n    static_init_done = 1;\n\n#  ifdef GEN_TREES_H\n    gen_trees_header();\n#  endif\n#endif /* defined(GEN_TREES_H) || !defined(STDC) */\n}\n\n/* ===========================================================================\n * Genererate the file trees.h describing the static trees.\n */\n#ifdef GEN_TREES_H\n#  ifndef DEBUG\n#    include <stdio.h>\n#  endif\n\n#  define SEPARATOR(i, last, width) \\\n      ((i) == (last)? \"\\n};\\n\\n\" :    \\\n       ((i) % (width) == (width)-1 ? \",\\n\" : \", \"))\n\nvoid gen_trees_header()\n{\n    FILE *header = fopen(\"trees.h\", \"w\");\n    int i;\n\n    Assert (header != NULL, \"Can't open trees.h\");\n    fprintf(header,\n            \"/* header created automatically with -DGEN_TREES_H */\\n\\n\");\n\n    fprintf(header, \"local const ct_data static_ltree[L_CODES+2] = {\\n\");\n    for (i = 0; i < L_CODES+2; i++) {\n        fprintf(header, \"{{%3u},{%3u}}%s\", static_ltree[i].Code,\n                static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));\n    }\n\n    fprintf(header, \"local const ct_data static_dtree[D_CODES] = {\\n\");\n    for (i = 0; i < D_CODES; i++) {\n        fprintf(header, \"{{%2u},{%2u}}%s\", static_dtree[i].Code,\n                static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));\n    }\n\n    fprintf(header, \"const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\\n\");\n    for (i = 0; i < DIST_CODE_LEN; i++) {\n        fprintf(header, \"%2u%s\", _dist_code[i],\n                SEPARATOR(i, DIST_CODE_LEN-1, 20));\n    }\n\n    fprintf(header,\n        \"const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\\n\");\n    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {\n        fprintf(header, \"%2u%s\", _length_code[i],\n                SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));\n    }\n\n    fprintf(header, \"local const int base_length[LENGTH_CODES] = {\\n\");\n    for (i = 0; i < LENGTH_CODES; i++) {\n        fprintf(header, \"%1u%s\", base_length[i],\n                SEPARATOR(i, LENGTH_CODES-1, 20));\n    }\n\n    fprintf(header, \"local const int base_dist[D_CODES] = {\\n\");\n    for (i = 0; i < D_CODES; i++) {\n        fprintf(header, \"%5u%s\", base_dist[i],\n                SEPARATOR(i, D_CODES-1, 10));\n    }\n\n    fclose(header);\n}\n#endif /* GEN_TREES_H */\n\n/* ===========================================================================\n * Initialize the tree data structures for a new zlib stream.\n */\nvoid ZLIB_INTERNAL _tr_init(s)\n    deflate_state *s;\n{\n    tr_static_init();\n\n    s->l_desc.dyn_tree = s->dyn_ltree;\n    s->l_desc.stat_desc = &static_l_desc;\n\n    s->d_desc.dyn_tree = s->dyn_dtree;\n    s->d_desc.stat_desc = &static_d_desc;\n\n    s->bl_desc.dyn_tree = s->bl_tree;\n    s->bl_desc.stat_desc = &static_bl_desc;\n\n    s->bi_buf = 0;\n    s->bi_valid = 0;\n#ifdef DEBUG\n    s->compressed_len = 0L;\n    s->bits_sent = 0L;\n#endif\n\n    /* Initialize the first block of the first file: */\n    init_block(s);\n}\n\n/* ===========================================================================\n * Initialize a new block.\n */\nlocal void init_block(s)\n    deflate_state *s;\n{\n    int n; /* iterates over tree elements */\n\n    /* Initialize the trees. */\n    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;\n    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;\n    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;\n\n    s->dyn_ltree[END_BLOCK].Freq = 1;\n    s->opt_len = s->static_len = 0L;\n    s->last_lit = s->matches = 0;\n}\n\n#define SMALLEST 1\n/* Index within the heap array of least frequent node in the Huffman tree */\n\n\n/* ===========================================================================\n * Remove the smallest element from the heap and recreate the heap with\n * one less element. Updates heap and heap_len.\n */\n#define pqremove(s, tree, top) \\\n{\\\n    top = s->heap[SMALLEST]; \\\n    s->heap[SMALLEST] = s->heap[s->heap_len--]; \\\n    pqdownheap(s, tree, SMALLEST); \\\n}\n\n/* ===========================================================================\n * Compares to subtrees, using the tree depth as tie breaker when\n * the subtrees have equal frequency. This minimizes the worst case length.\n */\n#define smaller(tree, n, m, depth) \\\n   (tree[n].Freq < tree[m].Freq || \\\n   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))\n\n/* ===========================================================================\n * Restore the heap property by moving down the tree starting at node k,\n * exchanging a node with the smallest of its two sons if necessary, stopping\n * when the heap property is re-established (each father smaller than its\n * two sons).\n */\nlocal void pqdownheap(s, tree, k)\n    deflate_state *s;\n    ct_data *tree;  /* the tree to restore */\n    int k;               /* node to move down */\n{\n    int v = s->heap[k];\n    int j = k << 1;  /* left son of k */\n    while (j <= s->heap_len) {\n        /* Set j to the smallest of the two sons: */\n        if (j < s->heap_len &&\n            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {\n            j++;\n        }\n        /* Exit if v is smaller than both sons */\n        if (smaller(tree, v, s->heap[j], s->depth)) break;\n\n        /* Exchange v with the smallest son */\n        s->heap[k] = s->heap[j];  k = j;\n\n        /* And continue down the tree, setting j to the left son of k */\n        j <<= 1;\n    }\n    s->heap[k] = v;\n}\n\n/* ===========================================================================\n * Compute the optimal bit lengths for a tree and update the total bit length\n * for the current block.\n * IN assertion: the fields freq and dad are set, heap[heap_max] and\n *    above are the tree nodes sorted by increasing frequency.\n * OUT assertions: the field len is set to the optimal bit length, the\n *     array bl_count contains the frequencies for each bit length.\n *     The length opt_len is updated; static_len is also updated if stree is\n *     not null.\n */\nlocal void gen_bitlen(s, desc)\n    deflate_state *s;\n    tree_desc *desc;    /* the tree descriptor */\n{\n    ct_data *tree        = desc->dyn_tree;\n    int max_code         = desc->max_code;\n    const ct_data *stree = desc->stat_desc->static_tree;\n    const intf *extra    = desc->stat_desc->extra_bits;\n    int base             = desc->stat_desc->extra_base;\n    int max_length       = desc->stat_desc->max_length;\n    int h;              /* heap index */\n    int n, m;           /* iterate over the tree elements */\n    int bits;           /* bit length */\n    int xbits;          /* extra bits */\n    ush f;              /* frequency */\n    int overflow = 0;   /* number of elements with bit length too large */\n\n    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;\n\n    /* In a first pass, compute the optimal bit lengths (which may\n     * overflow in the case of the bit length tree).\n     */\n    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */\n\n    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {\n        n = s->heap[h];\n        bits = tree[tree[n].Dad].Len + 1;\n        if (bits > max_length) bits = max_length, overflow++;\n        tree[n].Len = (ush)bits;\n        /* We overwrite tree[n].Dad which is no longer needed */\n\n        if (n > max_code) continue; /* not a leaf node */\n\n        s->bl_count[bits]++;\n        xbits = 0;\n        if (n >= base) xbits = extra[n-base];\n        f = tree[n].Freq;\n        s->opt_len += (ulg)f * (bits + xbits);\n        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);\n    }\n    if (overflow == 0) return;\n\n    Trace((stderr,\"\\nbit length overflow\\n\"));\n    /* This happens for example on obj2 and pic of the Calgary corpus */\n\n    /* Find the first bit length which could increase: */\n    do {\n        bits = max_length-1;\n        while (s->bl_count[bits] == 0) bits--;\n        s->bl_count[bits]--;      /* move one leaf down the tree */\n        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */\n        s->bl_count[max_length]--;\n        /* The brother of the overflow item also moves one step up,\n         * but this does not affect bl_count[max_length]\n         */\n        overflow -= 2;\n    } while (overflow > 0);\n\n    /* Now recompute all bit lengths, scanning in increasing frequency.\n     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all\n     * lengths instead of fixing only the wrong ones. This idea is taken\n     * from 'ar' written by Haruhiko Okumura.)\n     */\n    for (bits = max_length; bits != 0; bits--) {\n        n = s->bl_count[bits];\n        while (n != 0) {\n            m = s->heap[--h];\n            if (m > max_code) continue;\n            if ((unsigned) tree[m].Len != (unsigned) bits) {\n                Trace((stderr,\"code %d bits %d->%d\\n\", m, tree[m].Len, bits));\n                s->opt_len += ((long)bits - (long)tree[m].Len)\n                              *(long)tree[m].Freq;\n                tree[m].Len = (ush)bits;\n            }\n            n--;\n        }\n    }\n}\n\n/* ===========================================================================\n * Generate the codes for a given tree and bit counts (which need not be\n * optimal).\n * IN assertion: the array bl_count contains the bit length statistics for\n * the given tree and the field len is set for all tree elements.\n * OUT assertion: the field code is set for all tree elements of non\n *     zero code length.\n */\nlocal void gen_codes (tree, max_code, bl_count)\n    ct_data *tree;             /* the tree to decorate */\n    int max_code;              /* largest code with non zero frequency */\n    ushf *bl_count;            /* number of codes at each bit length */\n{\n    ush next_code[MAX_BITS+1]; /* next code value for each bit length */\n    ush code = 0;              /* running code value */\n    int bits;                  /* bit index */\n    int n;                     /* code index */\n\n    /* The distribution counts are first used to generate the code values\n     * without bit reversal.\n     */\n    for (bits = 1; bits <= MAX_BITS; bits++) {\n        next_code[bits] = code = (code + bl_count[bits-1]) << 1;\n    }\n    /* Check that the bit counts in bl_count are consistent. The last code\n     * must be all ones.\n     */\n    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,\n            \"inconsistent bit counts\");\n    Tracev((stderr,\"\\ngen_codes: max_code %d \", max_code));\n\n    for (n = 0;  n <= max_code; n++) {\n        int len = tree[n].Len;\n        if (len == 0) continue;\n        /* Now reverse the bits */\n        tree[n].Code = bi_reverse(next_code[len]++, len);\n\n        Tracecv(tree != static_ltree, (stderr,\"\\nn %3d %c l %2d c %4x (%x) \",\n             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));\n    }\n}\n\n/* ===========================================================================\n * Construct one Huffman tree and assigns the code bit strings and lengths.\n * Update the total bit length for the current block.\n * IN assertion: the field freq is set for all tree elements.\n * OUT assertions: the fields len and code are set to the optimal bit length\n *     and corresponding code. The length opt_len is updated; static_len is\n *     also updated if stree is not null. The field max_code is set.\n */\nlocal void build_tree(s, desc)\n    deflate_state *s;\n    tree_desc *desc; /* the tree descriptor */\n{\n    ct_data *tree         = desc->dyn_tree;\n    const ct_data *stree  = desc->stat_desc->static_tree;\n    int elems             = desc->stat_desc->elems;\n    int n, m;          /* iterate over heap elements */\n    int max_code = -1; /* largest code with non zero frequency */\n    int node;          /* new node being created */\n\n    /* Construct the initial heap, with least frequent element in\n     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].\n     * heap[0] is not used.\n     */\n    s->heap_len = 0, s->heap_max = HEAP_SIZE;\n\n    for (n = 0; n < elems; n++) {\n        if (tree[n].Freq != 0) {\n            s->heap[++(s->heap_len)] = max_code = n;\n            s->depth[n] = 0;\n        } else {\n            tree[n].Len = 0;\n        }\n    }\n\n    /* The pkzip format requires that at least one distance code exists,\n     * and that at least one bit should be sent even if there is only one\n     * possible code. So to avoid special checks later on we force at least\n     * two codes of non zero frequency.\n     */\n    while (s->heap_len < 2) {\n        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);\n        tree[node].Freq = 1;\n        s->depth[node] = 0;\n        s->opt_len--; if (stree) s->static_len -= stree[node].Len;\n        /* node is 0 or 1 so it does not have extra bits */\n    }\n    desc->max_code = max_code;\n\n    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,\n     * establish sub-heaps of increasing lengths:\n     */\n    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);\n\n    /* Construct the Huffman tree by repeatedly combining the least two\n     * frequent nodes.\n     */\n    node = elems;              /* next internal node of the tree */\n    do {\n        pqremove(s, tree, n);  /* n = node of least frequency */\n        m = s->heap[SMALLEST]; /* m = node of next least frequency */\n\n        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */\n        s->heap[--(s->heap_max)] = m;\n\n        /* Create a new node father of n and m */\n        tree[node].Freq = tree[n].Freq + tree[m].Freq;\n        s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?\n                                s->depth[n] : s->depth[m]) + 1);\n        tree[n].Dad = tree[m].Dad = (ush)node;\n#ifdef DUMP_BL_TREE\n        if (tree == s->bl_tree) {\n            fprintf(stderr,\"\\nnode %d(%d), sons %d(%d) %d(%d)\",\n                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);\n        }\n#endif\n        /* and insert the new node in the heap */\n        s->heap[SMALLEST] = node++;\n        pqdownheap(s, tree, SMALLEST);\n\n    } while (s->heap_len >= 2);\n\n    s->heap[--(s->heap_max)] = s->heap[SMALLEST];\n\n    /* At this point, the fields freq and dad are set. We can now\n     * generate the bit lengths.\n     */\n    gen_bitlen(s, (tree_desc *)desc);\n\n    /* The field len is now set, we can generate the bit codes */\n    gen_codes ((ct_data *)tree, max_code, s->bl_count);\n}\n\n/* ===========================================================================\n * Scan a literal or distance tree to determine the frequencies of the codes\n * in the bit length tree.\n */\nlocal void scan_tree (s, tree, max_code)\n    deflate_state *s;\n    ct_data *tree;   /* the tree to be scanned */\n    int max_code;    /* and its largest code of non zero frequency */\n{\n    int n;                     /* iterates over all tree elements */\n    int prevlen = -1;          /* last emitted length */\n    int curlen;                /* length of current code */\n    int nextlen = tree[0].Len; /* length of next code */\n    int count = 0;             /* repeat count of the current code */\n    int max_count = 7;         /* max repeat count */\n    int min_count = 4;         /* min repeat count */\n\n    if (nextlen == 0) max_count = 138, min_count = 3;\n    tree[max_code+1].Len = (ush)0xffff; /* guard */\n\n    for (n = 0; n <= max_code; n++) {\n        curlen = nextlen; nextlen = tree[n+1].Len;\n        if (++count < max_count && curlen == nextlen) {\n            continue;\n        } else if (count < min_count) {\n            s->bl_tree[curlen].Freq += count;\n        } else if (curlen != 0) {\n            if (curlen != prevlen) s->bl_tree[curlen].Freq++;\n            s->bl_tree[REP_3_6].Freq++;\n        } else if (count <= 10) {\n            s->bl_tree[REPZ_3_10].Freq++;\n        } else {\n            s->bl_tree[REPZ_11_138].Freq++;\n        }\n        count = 0; prevlen = curlen;\n        if (nextlen == 0) {\n            max_count = 138, min_count = 3;\n        } else if (curlen == nextlen) {\n            max_count = 6, min_count = 3;\n        } else {\n            max_count = 7, min_count = 4;\n        }\n    }\n}\n\n/* ===========================================================================\n * Send a literal or distance tree in compressed form, using the codes in\n * bl_tree.\n */\nlocal void send_tree (s, tree, max_code)\n    deflate_state *s;\n    ct_data *tree; /* the tree to be scanned */\n    int max_code;       /* and its largest code of non zero frequency */\n{\n    int n;                     /* iterates over all tree elements */\n    int prevlen = -1;          /* last emitted length */\n    int curlen;                /* length of current code */\n    int nextlen = tree[0].Len; /* length of next code */\n    int count = 0;             /* repeat count of the current code */\n    int max_count = 7;         /* max repeat count */\n    int min_count = 4;         /* min repeat count */\n\n    /* tree[max_code+1].Len = -1; */  /* guard already set */\n    if (nextlen == 0) max_count = 138, min_count = 3;\n\n    for (n = 0; n <= max_code; n++) {\n        curlen = nextlen; nextlen = tree[n+1].Len;\n        if (++count < max_count && curlen == nextlen) {\n            continue;\n        } else if (count < min_count) {\n            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);\n\n        } else if (curlen != 0) {\n            if (curlen != prevlen) {\n                send_code(s, curlen, s->bl_tree); count--;\n            }\n            Assert(count >= 3 && count <= 6, \" 3_6?\");\n            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);\n\n        } else if (count <= 10) {\n            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);\n\n        } else {\n            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);\n        }\n        count = 0; prevlen = curlen;\n        if (nextlen == 0) {\n            max_count = 138, min_count = 3;\n        } else if (curlen == nextlen) {\n            max_count = 6, min_count = 3;\n        } else {\n            max_count = 7, min_count = 4;\n        }\n    }\n}\n\n/* ===========================================================================\n * Construct the Huffman tree for the bit lengths and return the index in\n * bl_order of the last bit length code to send.\n */\nlocal int build_bl_tree(s)\n    deflate_state *s;\n{\n    int max_blindex;  /* index of last bit length code of non zero freq */\n\n    /* Determine the bit length frequencies for literal and distance trees */\n    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);\n    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);\n\n    /* Build the bit length tree: */\n    build_tree(s, (tree_desc *)(&(s->bl_desc)));\n    /* opt_len now includes the length of the tree representations, except\n     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.\n     */\n\n    /* Determine the number of bit length codes to send. The pkzip format\n     * requires that at least 4 bit length codes be sent. (appnote.txt says\n     * 3 but the actual value used is 4.)\n     */\n    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {\n        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;\n    }\n    /* Update opt_len to include the bit length tree and counts */\n    s->opt_len += 3*(max_blindex+1) + 5+5+4;\n    Tracev((stderr, \"\\ndyn trees: dyn %ld, stat %ld\",\n            s->opt_len, s->static_len));\n\n    return max_blindex;\n}\n\n/* ===========================================================================\n * Send the header for a block using dynamic Huffman trees: the counts, the\n * lengths of the bit length codes, the literal tree and the distance tree.\n * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.\n */\nlocal void send_all_trees(s, lcodes, dcodes, blcodes)\n    deflate_state *s;\n    int lcodes, dcodes, blcodes; /* number of codes for each tree */\n{\n    int rank;                    /* index in bl_order */\n\n    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, \"not enough codes\");\n    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,\n            \"too many codes\");\n    Tracev((stderr, \"\\nbl counts: \"));\n    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */\n    send_bits(s, dcodes-1,   5);\n    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */\n    for (rank = 0; rank < blcodes; rank++) {\n        Tracev((stderr, \"\\nbl code %2d \", bl_order[rank]));\n        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);\n    }\n    Tracev((stderr, \"\\nbl tree: sent %ld\", s->bits_sent));\n\n    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */\n    Tracev((stderr, \"\\nlit tree: sent %ld\", s->bits_sent));\n\n    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */\n    Tracev((stderr, \"\\ndist tree: sent %ld\", s->bits_sent));\n}\n\n/* ===========================================================================\n * Send a stored block\n */\nvoid ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)\n    deflate_state *s;\n    charf *buf;       /* input block */\n    ulg stored_len;   /* length of input block */\n    int last;         /* one if this is the last block for a file */\n{\n    send_bits(s, (STORED_BLOCK<<1)+last, 3);    /* send block type */\n#ifdef DEBUG\n    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;\n    s->compressed_len += (stored_len + 4) << 3;\n#endif\n    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */\n}\n\n/* ===========================================================================\n * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)\n */\nvoid ZLIB_INTERNAL _tr_flush_bits(s)\n    deflate_state *s;\n{\n    bi_flush(s);\n}\n\n/* ===========================================================================\n * Send one empty static block to give enough lookahead for inflate.\n * This takes 10 bits, of which 7 may remain in the bit buffer.\n */\nvoid ZLIB_INTERNAL _tr_align(s)\n    deflate_state *s;\n{\n    send_bits(s, STATIC_TREES<<1, 3);\n    send_code(s, END_BLOCK, static_ltree);\n#ifdef DEBUG\n    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */\n#endif\n    bi_flush(s);\n}\n\n/* ===========================================================================\n * Determine the best encoding for the current block: dynamic trees, static\n * trees or store, and output the encoded block to the zip file.\n */\nvoid ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)\n    deflate_state *s;\n    charf *buf;       /* input block, or NULL if too old */\n    ulg stored_len;   /* length of input block */\n    int last;         /* one if this is the last block for a file */\n{\n    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */\n    int max_blindex = 0;  /* index of last bit length code of non zero freq */\n\n    /* Build the Huffman trees unless a stored block is forced */\n    if (s->level > 0) {\n\n        /* Check if the file is binary or text */\n        if (s->strm->data_type == Z_UNKNOWN)\n            s->strm->data_type = detect_data_type(s);\n\n        /* Construct the literal and distance trees */\n        build_tree(s, (tree_desc *)(&(s->l_desc)));\n        Tracev((stderr, \"\\nlit data: dyn %ld, stat %ld\", s->opt_len,\n                s->static_len));\n\n        build_tree(s, (tree_desc *)(&(s->d_desc)));\n        Tracev((stderr, \"\\ndist data: dyn %ld, stat %ld\", s->opt_len,\n                s->static_len));\n        /* At this point, opt_len and static_len are the total bit lengths of\n         * the compressed block data, excluding the tree representations.\n         */\n\n        /* Build the bit length tree for the above two trees, and get the index\n         * in bl_order of the last bit length code to send.\n         */\n        max_blindex = build_bl_tree(s);\n\n        /* Determine the best encoding. Compute the block lengths in bytes. */\n        opt_lenb = (s->opt_len+3+7)>>3;\n        static_lenb = (s->static_len+3+7)>>3;\n\n        Tracev((stderr, \"\\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u \",\n                opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,\n                s->last_lit));\n\n        if (static_lenb <= opt_lenb) opt_lenb = static_lenb;\n\n    } else {\n        Assert(buf != (char*)0, \"lost buf\");\n        opt_lenb = static_lenb = stored_len + 5; /* force a stored block */\n    }\n\n#ifdef FORCE_STORED\n    if (buf != (char*)0) { /* force stored block */\n#else\n    if (stored_len+4 <= opt_lenb && buf != (char*)0) {\n                       /* 4: two words for the lengths */\n#endif\n        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.\n         * Otherwise we can't have processed more than WSIZE input bytes since\n         * the last block flush, because compression would have been\n         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to\n         * transform a block into a stored block.\n         */\n        _tr_stored_block(s, buf, stored_len, last);\n\n#ifdef FORCE_STATIC\n    } else if (static_lenb >= 0) { /* force static trees */\n#else\n    } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {\n#endif\n        send_bits(s, (STATIC_TREES<<1)+last, 3);\n        compress_block(s, (const ct_data *)static_ltree,\n                       (const ct_data *)static_dtree);\n#ifdef DEBUG\n        s->compressed_len += 3 + s->static_len;\n#endif\n    } else {\n        send_bits(s, (DYN_TREES<<1)+last, 3);\n        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,\n                       max_blindex+1);\n        compress_block(s, (const ct_data *)s->dyn_ltree,\n                       (const ct_data *)s->dyn_dtree);\n#ifdef DEBUG\n        s->compressed_len += 3 + s->opt_len;\n#endif\n    }\n    Assert (s->compressed_len == s->bits_sent, \"bad compressed size\");\n    /* The above check is made mod 2^32, for files larger than 512 MB\n     * and uLong implemented on 32 bits.\n     */\n    init_block(s);\n\n    if (last) {\n        bi_windup(s);\n#ifdef DEBUG\n        s->compressed_len += 7;  /* align on byte boundary */\n#endif\n    }\n    Tracev((stderr,\"\\ncomprlen %lu(%lu) \", s->compressed_len>>3,\n           s->compressed_len-7*last));\n}\n\n/* ===========================================================================\n * Save the match info and tally the frequency counts. Return true if\n * the current block must be flushed.\n */\nint ZLIB_INTERNAL _tr_tally (s, dist, lc)\n    deflate_state *s;\n    unsigned dist;  /* distance of matched string */\n    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */\n{\n    s->d_buf[s->last_lit] = (ush)dist;\n    s->l_buf[s->last_lit++] = (uch)lc;\n    if (dist == 0) {\n        /* lc is the unmatched char */\n        s->dyn_ltree[lc].Freq++;\n    } else {\n        s->matches++;\n        /* Here, lc is the match length - MIN_MATCH */\n        dist--;             /* dist = match distance - 1 */\n        Assert((ush)dist < (ush)MAX_DIST(s) &&\n               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&\n               (ush)d_code(dist) < (ush)D_CODES,  \"_tr_tally: bad match\");\n\n        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;\n        s->dyn_dtree[d_code(dist)].Freq++;\n    }\n\n#ifdef TRUNCATE_BLOCK\n    /* Try to guess if it is profitable to stop the current block here */\n    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {\n        /* Compute an upper bound for the compressed length */\n        ulg out_length = (ulg)s->last_lit*8L;\n        ulg in_length = (ulg)((long)s->strstart - s->block_start);\n        int dcode;\n        for (dcode = 0; dcode < D_CODES; dcode++) {\n            out_length += (ulg)s->dyn_dtree[dcode].Freq *\n                (5L+extra_dbits[dcode]);\n        }\n        out_length >>= 3;\n        Tracev((stderr,\"\\nlast_lit %u, in %ld, out ~%ld(%ld%%) \",\n               s->last_lit, in_length, out_length,\n               100L - out_length*100L/in_length));\n        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;\n    }\n#endif\n    return (s->last_lit == s->lit_bufsize-1);\n    /* We avoid equality with lit_bufsize because of wraparound at 64K\n     * on 16 bit machines and because stored blocks are restricted to\n     * 64K-1 bytes.\n     */\n}\n\n/* ===========================================================================\n * Send the block data compressed using the given Huffman trees\n */\nlocal void compress_block(s, ltree, dtree)\n    deflate_state *s;\n    const ct_data *ltree; /* literal tree */\n    const ct_data *dtree; /* distance tree */\n{\n    unsigned dist;      /* distance of matched string */\n    int lc;             /* match length or unmatched char (if dist == 0) */\n    unsigned lx = 0;    /* running index in l_buf */\n    unsigned code;      /* the code to send */\n    int extra;          /* number of extra bits to send */\n\n    if (s->last_lit != 0) do {\n        dist = s->d_buf[lx];\n        lc = s->l_buf[lx++];\n        if (dist == 0) {\n            send_code(s, lc, ltree); /* send a literal byte */\n            Tracecv(isgraph(lc), (stderr,\" '%c' \", lc));\n        } else {\n            /* Here, lc is the match length - MIN_MATCH */\n            code = _length_code[lc];\n            send_code(s, code+LITERALS+1, ltree); /* send the length code */\n            extra = extra_lbits[code];\n            if (extra != 0) {\n                lc -= base_length[code];\n                send_bits(s, lc, extra);       /* send the extra length bits */\n            }\n            dist--; /* dist is now the match distance - 1 */\n            code = d_code(dist);\n            Assert (code < D_CODES, \"bad d_code\");\n\n            send_code(s, code, dtree);       /* send the distance code */\n            extra = extra_dbits[code];\n            if (extra != 0) {\n                dist -= base_dist[code];\n                send_bits(s, dist, extra);   /* send the extra distance bits */\n            }\n        } /* literal or match pair ? */\n\n        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */\n        Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,\n               \"pendingBuf overflow\");\n\n    } while (lx < s->last_lit);\n\n    send_code(s, END_BLOCK, ltree);\n}\n\n/* ===========================================================================\n * Check if the data type is TEXT or BINARY, using the following algorithm:\n * - TEXT if the two conditions below are satisfied:\n *    a) There are no non-portable control characters belonging to the\n *       \"black list\" (0..6, 14..25, 28..31).\n *    b) There is at least one printable character belonging to the\n *       \"white list\" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).\n * - BINARY otherwise.\n * - The following partially-portable control characters form a\n *   \"gray list\" that is ignored in this detection algorithm:\n *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).\n * IN assertion: the fields Freq of dyn_ltree are set.\n */\nlocal int detect_data_type(s)\n    deflate_state *s;\n{\n    /* black_mask is the bit mask of black-listed bytes\n     * set bits 0..6, 14..25, and 28..31\n     * 0xf3ffc07f = binary 11110011111111111100000001111111\n     */\n    unsigned long black_mask = 0xf3ffc07fUL;\n    int n;\n\n    /* Check for non-textual (\"black-listed\") bytes. */\n    for (n = 0; n <= 31; n++, black_mask >>= 1)\n        if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))\n            return Z_BINARY;\n\n    /* Check for textual (\"white-listed\") bytes. */\n    if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0\n            || s->dyn_ltree[13].Freq != 0)\n        return Z_TEXT;\n    for (n = 32; n < LITERALS; n++)\n        if (s->dyn_ltree[n].Freq != 0)\n            return Z_TEXT;\n\n    /* There are no \"black-listed\" or \"white-listed\" bytes:\n     * this stream either is empty or has tolerated (\"gray-listed\") bytes only.\n     */\n    return Z_BINARY;\n}\n\n/* ===========================================================================\n * Reverse the first len bits of a code, using straightforward code (a faster\n * method would use a table)\n * IN assertion: 1 <= len <= 15\n */\nlocal unsigned bi_reverse(code, len)\n    unsigned code; /* the value to invert */\n    int len;       /* its bit length */\n{\n    register unsigned res = 0;\n    do {\n        res |= code & 1;\n        code >>= 1, res <<= 1;\n    } while (--len > 0);\n    return res >> 1;\n}\n\n/* ===========================================================================\n * Flush the bit buffer, keeping at most 7 bits in it.\n */\nlocal void bi_flush(s)\n    deflate_state *s;\n{\n    if (s->bi_valid == 16) {\n        put_short(s, s->bi_buf);\n        s->bi_buf = 0;\n        s->bi_valid = 0;\n    } else if (s->bi_valid >= 8) {\n        put_byte(s, (Byte)s->bi_buf);\n        s->bi_buf >>= 8;\n        s->bi_valid -= 8;\n    }\n}\n\n/* ===========================================================================\n * Flush the bit buffer and align the output on a byte boundary\n */\nlocal void bi_windup(s)\n    deflate_state *s;\n{\n    if (s->bi_valid > 8) {\n        put_short(s, s->bi_buf);\n    } else if (s->bi_valid > 0) {\n        put_byte(s, (Byte)s->bi_buf);\n    }\n    s->bi_buf = 0;\n    s->bi_valid = 0;\n#ifdef DEBUG\n    s->bits_sent = (s->bits_sent+7) & ~7;\n#endif\n}\n\n/* ===========================================================================\n * Copy a stored block, storing first the length and its\n * one's complement if requested.\n */\nlocal void copy_block(s, buf, len, header)\n    deflate_state *s;\n    charf    *buf;    /* the input data */\n    unsigned len;     /* its length */\n    int      header;  /* true if block header must be written */\n{\n    bi_windup(s);        /* align on byte boundary */\n\n    if (header) {\n        put_short(s, (ush)len);\n        put_short(s, (ush)~len);\n#ifdef DEBUG\n        s->bits_sent += 2*16;\n#endif\n    }\n#ifdef DEBUG\n    s->bits_sent += (ulg)len<<3;\n#endif\n    while (len--) {\n        put_byte(s, *buf++);\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/trees.h",
    "content": "/* header created automatically with -DGEN_TREES_H */\n\nlocal const ct_data static_ltree[L_CODES+2] = {\n{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},\n{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},\n{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},\n{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},\n{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},\n{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},\n{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},\n{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},\n{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},\n{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},\n{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},\n{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},\n{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},\n{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},\n{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},\n{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},\n{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},\n{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},\n{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},\n{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},\n{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},\n{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},\n{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},\n{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},\n{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},\n{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},\n{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},\n{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},\n{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},\n{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},\n{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},\n{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},\n{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},\n{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},\n{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},\n{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},\n{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},\n{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},\n{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},\n{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},\n{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},\n{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},\n{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},\n{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},\n{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},\n{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},\n{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},\n{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},\n{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},\n{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},\n{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},\n{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},\n{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},\n{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},\n{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},\n{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},\n{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},\n{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}\n};\n\nlocal const ct_data static_dtree[D_CODES] = {\n{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},\n{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},\n{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},\n{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},\n{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},\n{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}\n};\n\nconst uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,\n 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,\n10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,\n13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,\n15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,\n18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,\n23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,\n27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29\n};\n\nconst uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,\n13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,\n17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,\n19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,\n21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,\n22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,\n23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,\n26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28\n};\n\nlocal const int base_length[LENGTH_CODES] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,\n64, 80, 96, 112, 128, 160, 192, 224, 0\n};\n\nlocal const int base_dist[D_CODES] = {\n    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,\n   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,\n 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576\n};\n\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/uncompr.c",
    "content": "/* uncompr.c -- decompress a memory buffer\n * Copyright (C) 1995-2003, 2010 Jean-loup Gailly.\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* @(#) $Id$ */\n\n#define ZLIB_INTERNAL\n#include \"zlib.h\"\n\n/* ===========================================================================\n     Decompresses the source buffer into the destination buffer.  sourceLen is\n   the byte length of the source buffer. Upon entry, destLen is the total\n   size of the destination buffer, which must be large enough to hold the\n   entire uncompressed data. (The size of the uncompressed data must have\n   been saved previously by the compressor and transmitted to the decompressor\n   by some mechanism outside the scope of this compression library.)\n   Upon exit, destLen is the actual size of the compressed buffer.\n\n     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_BUF_ERROR if there was not enough room in the output\n   buffer, or Z_DATA_ERROR if the input data was corrupted.\n*/\nint ZEXPORT uncompress (dest, destLen, source, sourceLen)\n    Bytef *dest;\n    uLongf *destLen;\n    const Bytef *source;\n    uLong sourceLen;\n{\n    z_stream stream;\n    int err;\n\n    stream.next_in = (z_const Bytef *)source;\n    stream.avail_in = (uInt)sourceLen;\n    /* Check for source > 64K on 16-bit machine: */\n    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;\n\n    stream.next_out = dest;\n    stream.avail_out = (uInt)*destLen;\n    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;\n\n    stream.zalloc = (alloc_func)0;\n    stream.zfree = (free_func)0;\n\n    err = inflateInit(&stream);\n    if (err != Z_OK) return err;\n\n    err = inflate(&stream, Z_FINISH);\n    if (err != Z_STREAM_END) {\n        inflateEnd(&stream);\n        if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))\n            return Z_DATA_ERROR;\n        return err;\n    }\n    *destLen = stream.total_out;\n\n    err = inflateEnd(&stream);\n    return err;\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/watcom/watcom_f.mak",
    "content": "# Makefile for zlib\n# OpenWatcom flat model\n# Last updated: 28-Dec-2005\n\n# To use, do \"wmake -f watcom_f.mak\"\n\nC_SOURCE =  adler32.c  compress.c crc32.c   deflate.c    &\n\t    gzclose.c  gzlib.c    gzread.c  gzwrite.c    &\n            infback.c  inffast.c  inflate.c inftrees.c   &\n            trees.c    uncompr.c  zutil.c\n\nOBJS =      adler32.obj  compress.obj crc32.obj   deflate.obj    &\n\t    gzclose.obj  gzlib.obj    gzread.obj  gzwrite.obj    &\n            infback.obj  inffast.obj  inflate.obj inftrees.obj   &\n            trees.obj    uncompr.obj  zutil.obj\n\nCC       = wcc386\nLINKER   = wcl386\nCFLAGS   = -zq -mf -3r -fp3 -s -bt=dos -oilrtfm -fr=nul -wx\nZLIB_LIB = zlib_f.lib\n\n.C.OBJ:\n        $(CC) $(CFLAGS) $[@\n\nall: $(ZLIB_LIB) example.exe minigzip.exe\n\n$(ZLIB_LIB): $(OBJS)\n\twlib -b -c $(ZLIB_LIB) -+adler32.obj  -+compress.obj -+crc32.obj\n\twlib -b -c $(ZLIB_LIB) -+gzclose.obj  -+gzlib.obj    -+gzread.obj   -+gzwrite.obj\n        wlib -b -c $(ZLIB_LIB) -+deflate.obj  -+infback.obj\n        wlib -b -c $(ZLIB_LIB) -+inffast.obj  -+inflate.obj  -+inftrees.obj\n        wlib -b -c $(ZLIB_LIB) -+trees.obj    -+uncompr.obj  -+zutil.obj\n\nexample.exe: $(ZLIB_LIB) example.obj\n\t$(LINKER) -ldos32a -fe=example.exe example.obj $(ZLIB_LIB)\n\nminigzip.exe: $(ZLIB_LIB) minigzip.obj\n\t$(LINKER) -ldos32a -fe=minigzip.exe minigzip.obj $(ZLIB_LIB)\n\nclean: .SYMBOLIC\n          del *.obj\n          del $(ZLIB_LIB)\n          @echo Cleaning done\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/watcom/watcom_l.mak",
    "content": "# Makefile for zlib\n# OpenWatcom large model\n# Last updated: 28-Dec-2005\n\n# To use, do \"wmake -f watcom_l.mak\"\n\nC_SOURCE =  adler32.c  compress.c crc32.c   deflate.c    &\n\t    gzclose.c  gzlib.c    gzread.c  gzwrite.c    &\n            infback.c  inffast.c  inflate.c inftrees.c   &\n            trees.c    uncompr.c  zutil.c\n\nOBJS =      adler32.obj  compress.obj crc32.obj   deflate.obj    &\n\t    gzclose.obj  gzlib.obj    gzread.obj  gzwrite.obj    &\n            infback.obj  inffast.obj  inflate.obj inftrees.obj   &\n            trees.obj    uncompr.obj  zutil.obj\n\nCC       = wcc\nLINKER   = wcl\nCFLAGS   = -zq -ml -s -bt=dos -oilrtfm -fr=nul -wx\nZLIB_LIB = zlib_l.lib\n\n.C.OBJ:\n        $(CC) $(CFLAGS) $[@\n\nall: $(ZLIB_LIB) example.exe minigzip.exe\n\n$(ZLIB_LIB): $(OBJS)\n\twlib -b -c $(ZLIB_LIB) -+adler32.obj  -+compress.obj -+crc32.obj\n\twlib -b -c $(ZLIB_LIB) -+gzclose.obj  -+gzlib.obj    -+gzread.obj   -+gzwrite.obj\n        wlib -b -c $(ZLIB_LIB) -+deflate.obj  -+infback.obj\n        wlib -b -c $(ZLIB_LIB) -+inffast.obj  -+inflate.obj  -+inftrees.obj\n        wlib -b -c $(ZLIB_LIB) -+trees.obj    -+uncompr.obj  -+zutil.obj\n\nexample.exe: $(ZLIB_LIB) example.obj\n\t$(LINKER) -fe=example.exe example.obj $(ZLIB_LIB)\n\nminigzip.exe: $(ZLIB_LIB) minigzip.obj\n\t$(LINKER) -fe=minigzip.exe minigzip.obj $(ZLIB_LIB)\n\nclean: .SYMBOLIC\n          del *.obj\n          del $(ZLIB_LIB)\n          @echo Cleaning done\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/win32/DLL_FAQ.txt",
    "content": "\n            Frequently Asked Questions about ZLIB1.DLL\n\n\nThis document describes the design, the rationale, and the usage\nof the official DLL build of zlib, named ZLIB1.DLL.  If you have\ngeneral questions about zlib, you should see the file \"FAQ\" found\nin the zlib distribution, or at the following location:\n  http://www.gzip.org/zlib/zlib_faq.html\n\n\n 1. What is ZLIB1.DLL, and how can I get it?\n\n  - ZLIB1.DLL is the official build of zlib as a DLL.\n    (Please remark the character '1' in the name.)\n\n    Pointers to a precompiled ZLIB1.DLL can be found in the zlib\n    web site at:\n      http://www.zlib.net/\n\n    Applications that link to ZLIB1.DLL can rely on the following\n    specification:\n\n    * The exported symbols are exclusively defined in the source\n      files \"zlib.h\" and \"zlib.def\", found in an official zlib\n      source distribution.\n    * The symbols are exported by name, not by ordinal.\n    * The exported names are undecorated.\n    * The calling convention of functions is \"C\" (CDECL).\n    * The ZLIB1.DLL binary is linked to MSVCRT.DLL.\n\n    The archive in which ZLIB1.DLL is bundled contains compiled\n    test programs that must run with a valid build of ZLIB1.DLL.\n    It is recommended to download the prebuilt DLL from the zlib\n    web site, instead of building it yourself, to avoid potential\n    incompatibilities that could be introduced by your compiler\n    and build settings.  If you do build the DLL yourself, please\n    make sure that it complies with all the above requirements,\n    and it runs with the precompiled test programs, bundled with\n    the original ZLIB1.DLL distribution.\n\n    If, for any reason, you need to build an incompatible DLL,\n    please use a different file name.\n\n\n 2. Why did you change the name of the DLL to ZLIB1.DLL?\n    What happened to the old ZLIB.DLL?\n\n  - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required\n    compilation settings that were incompatible to those used by\n    a static build.  The DLL settings were supposed to be enabled\n    by defining the macro ZLIB_DLL, before including \"zlib.h\".\n    Incorrect handling of this macro was silently accepted at\n    build time, resulting in two major problems:\n\n    * ZLIB_DLL was missing from the old makefile.  When building\n      the DLL, not all people added it to the build options.  In\n      consequence, incompatible incarnations of ZLIB.DLL started\n      to circulate around the net.\n\n    * When switching from using the static library to using the\n      DLL, applications had to define the ZLIB_DLL macro and\n      to recompile all the sources that contained calls to zlib\n      functions.  Failure to do so resulted in creating binaries\n      that were unable to run with the official ZLIB.DLL build.\n\n    The only possible solution that we could foresee was to make\n    a binary-incompatible change in the DLL interface, in order to\n    remove the dependency on the ZLIB_DLL macro, and to release\n    the new DLL under a different name.\n\n    We chose the name ZLIB1.DLL, where '1' indicates the major\n    zlib version number.  We hope that we will not have to break\n    the binary compatibility again, at least not as long as the\n    zlib-1.x series will last.\n\n    There is still a ZLIB_DLL macro, that can trigger a more\n    efficient build and use of the DLL, but compatibility no\n    longer dependents on it.\n\n\n 3. Can I build ZLIB.DLL from the new zlib sources, and replace\n    an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier?\n\n  - In principle, you can do it by assigning calling convention\n    keywords to the macros ZEXPORT and ZEXPORTVA.  In practice,\n    it depends on what you mean by \"an old ZLIB.DLL\", because the\n    old DLL exists in several mutually-incompatible versions.\n    You have to find out first what kind of calling convention is\n    being used in your particular ZLIB.DLL build, and to use the\n    same one in the new build.  If you don't know what this is all\n    about, you might be better off if you would just leave the old\n    DLL intact.\n\n\n 4. Can I compile my application using the new zlib interface, and\n    link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or\n    earlier?\n\n  - The official answer is \"no\"; the real answer depends again on\n    what kind of ZLIB.DLL you have.  Even if you are lucky, this\n    course of action is unreliable.\n\n    If you rebuild your application and you intend to use a newer\n    version of zlib (post- 1.1.4), it is strongly recommended to\n    link it to the new ZLIB1.DLL.\n\n\n 5. Why are the zlib symbols exported by name, and not by ordinal?\n\n  - Although exporting symbols by ordinal is a little faster, it\n    is risky.  Any single glitch in the maintenance or use of the\n    DEF file that contains the ordinals can result in incompatible\n    builds and frustrating crashes.  Simply put, the benefits of\n    exporting symbols by ordinal do not justify the risks.\n\n    Technically, it should be possible to maintain ordinals in\n    the DEF file, and still export the symbols by name.  Ordinals\n    exist in every DLL, and even if the dynamic linking performed\n    at the DLL startup is searching for names, ordinals serve as\n    hints, for a faster name lookup.  However, if the DEF file\n    contains ordinals, the Microsoft linker automatically builds\n    an implib that will cause the executables linked to it to use\n    those ordinals, and not the names.  It is interesting to\n    notice that the GNU linker for Win32 does not suffer from this\n    problem.\n\n    It is possible to avoid the DEF file if the exported symbols\n    are accompanied by a \"__declspec(dllexport)\" attribute in the\n    source files.  You can do this in zlib by predefining the\n    ZLIB_DLL macro.\n\n\n 6. I see that the ZLIB1.DLL functions use the \"C\" (CDECL) calling\n    convention.  Why not use the STDCALL convention?\n    STDCALL is the standard convention in Win32, and I need it in\n    my Visual Basic project!\n\n    (For readability, we use CDECL to refer to the convention\n     triggered by the \"__cdecl\" keyword, STDCALL to refer to\n     the convention triggered by \"__stdcall\", and FASTCALL to\n     refer to the convention triggered by \"__fastcall\".)\n\n  - Most of the native Windows API functions (without varargs) use\n    indeed the WINAPI convention (which translates to STDCALL in\n    Win32), but the standard C functions use CDECL.  If a user\n    application is intrinsically tied to the Windows API (e.g.\n    it calls native Windows API functions such as CreateFile()),\n    sometimes it makes sense to decorate its own functions with\n    WINAPI.  But if ANSI C or POSIX portability is a goal (e.g.\n    it calls standard C functions such as fopen()), it is not a\n    sound decision to request the inclusion of <windows.h>, or to\n    use non-ANSI constructs, for the sole purpose to make the user\n    functions STDCALL-able.\n\n    The functionality offered by zlib is not in the category of\n    \"Windows functionality\", but is more like \"C functionality\".\n\n    Technically, STDCALL is not bad; in fact, it is slightly\n    faster than CDECL, and it works with variable-argument\n    functions, just like CDECL.  It is unfortunate that, in spite\n    of using STDCALL in the Windows API, it is not the default\n    convention used by the C compilers that run under Windows.\n    The roots of the problem reside deep inside the unsafety of\n    the K&R-style function prototypes, where the argument types\n    are not specified; but that is another story for another day.\n\n    The remaining fact is that CDECL is the default convention.\n    Even if an explicit convention is hard-coded into the function\n    prototypes inside C headers, problems may appear.  The\n    necessity to expose the convention in users' callbacks is one\n    of these problems.\n\n    The calling convention issues are also important when using\n    zlib in other programming languages.  Some of them, like Ada\n    (GNAT) and Fortran (GNU G77), have C bindings implemented\n    initially on Unix, and relying on the C calling convention.\n    On the other hand, the pre- .NET versions of Microsoft Visual\n    Basic require STDCALL, while Borland Delphi prefers, although\n    it does not require, FASTCALL.\n\n    In fairness to all possible uses of zlib outside the C\n    programming language, we choose the default \"C\" convention.\n    Anyone interested in different bindings or conventions is\n    encouraged to maintain specialized projects.  The \"contrib/\"\n    directory from the zlib distribution already holds a couple\n    of foreign bindings, such as Ada, C++, and Delphi.\n\n\n 7. I need a DLL for my Visual Basic project.  What can I do?\n\n  - Define the ZLIB_WINAPI macro before including \"zlib.h\", when\n    building both the DLL and the user application (except that\n    you don't need to define anything when using the DLL in Visual\n    Basic).  The ZLIB_WINAPI macro will switch on the WINAPI\n    (STDCALL) convention.  The name of this DLL must be different\n    than the official ZLIB1.DLL.\n\n    Gilles Vollant has contributed a build named ZLIBWAPI.DLL,\n    with the ZLIB_WINAPI macro turned on, and with the minizip\n    functionality built in.  For more information, please read\n    the notes inside \"contrib/vstudio/readme.txt\", found in the\n    zlib distribution.\n\n\n 8. I need to use zlib in my Microsoft .NET project.  What can I\n    do?\n\n  - Henrik Ravn has contributed a .NET wrapper around zlib.  Look\n    into contrib/dotzlib/, inside the zlib distribution.\n\n\n 9. If my application uses ZLIB1.DLL, should I link it to\n    MSVCRT.DLL?  Why?\n\n  - It is not required, but it is recommended to link your\n    application to MSVCRT.DLL, if it uses ZLIB1.DLL.\n\n    The executables (.EXE, .DLL, etc.) that are involved in the\n    same process and are using the C run-time library (i.e. they\n    are calling standard C functions), must link to the same\n    library.  There are several libraries in the Win32 system:\n    CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc.\n    Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that\n    depend on it should also be linked to MSVCRT.DLL.\n\n\n10. Why are you saying that ZLIB1.DLL and my application should\n    be linked to the same C run-time (CRT) library?  I linked my\n    application and my DLLs to different C libraries (e.g. my\n    application to a static library, and my DLLs to MSVCRT.DLL),\n    and everything works fine.\n\n  - If a user library invokes only pure Win32 API (accessible via\n    <windows.h> and the related headers), its DLL build will work\n    in any context.  But if this library invokes standard C API,\n    things get more complicated.\n\n    There is a single Win32 library in a Win32 system.  Every\n    function in this library resides in a single DLL module, that\n    is safe to call from anywhere.  On the other hand, there are\n    multiple versions of the C library, and each of them has its\n    own separate internal state.  Standalone executables and user\n    DLLs that call standard C functions must link to a C run-time\n    (CRT) library, be it static or shared (DLL).  Intermixing\n    occurs when an executable (not necessarily standalone) and a\n    DLL are linked to different CRTs, and both are running in the\n    same process.\n\n    Intermixing multiple CRTs is possible, as long as their\n    internal states are kept intact.  The Microsoft Knowledge Base\n    articles KB94248 \"HOWTO: Use the C Run-Time\" and KB140584\n    \"HOWTO: Link with the Correct C Run-Time (CRT) Library\"\n    mention the potential problems raised by intermixing.\n\n    If intermixing works for you, it's because your application\n    and DLLs are avoiding the corruption of each of the CRTs'\n    internal states, maybe by careful design, or maybe by fortune.\n\n    Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such\n    as those provided by Borland, raises similar problems.\n\n\n11. Why are you linking ZLIB1.DLL to MSVCRT.DLL?\n\n  - MSVCRT.DLL exists on every Windows 95 with a new service pack\n    installed, or with Microsoft Internet Explorer 4 or later, and\n    on all other Windows 4.x or later (Windows 98, Windows NT 4,\n    or later).  It is freely distributable; if not present in the\n    system, it can be downloaded from Microsoft or from other\n    software provider for free.\n\n    The fact that MSVCRT.DLL does not exist on a virgin Windows 95\n    is not so problematic.  Windows 95 is scarcely found nowadays,\n    Microsoft ended its support a long time ago, and many recent\n    applications from various vendors, including Microsoft, do not\n    even run on it.  Furthermore, no serious user should run\n    Windows 95 without a proper update installed.\n\n\n12. Why are you not linking ZLIB1.DLL to\n    <<my favorite C run-time library>> ?\n\n  - We considered and abandoned the following alternatives:\n\n    * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or\n      LIBCMT.LIB) is not a good option.  People are using the DLL\n      mainly to save disk space.  If you are linking your program\n      to a static C library, you may as well consider linking zlib\n      in statically, too.\n\n    * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because\n      CRTDLL.DLL is present on every Win32 installation.\n      Unfortunately, it has a series of problems: it does not\n      work properly with Microsoft's C++ libraries, it does not\n      provide support for 64-bit file offsets, (and so on...),\n      and Microsoft discontinued its support a long time ago.\n\n    * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied\n      with the Microsoft .NET platform, and Visual C++ 7.0/7.1,\n      raises problems related to the status of ZLIB1.DLL as a\n      system component.  According to the Microsoft Knowledge Base\n      article KB326922 \"INFO: Redistribution of the Shared C\n      Runtime Component in Visual C++ .NET\", MSVCR70.DLL and\n      MSVCR71.DLL are not supposed to function as system DLLs,\n      because they may clash with MSVCRT.DLL.  Instead, the\n      application's installer is supposed to put these DLLs\n      (if needed) in the application's private directory.\n      If ZLIB1.DLL depends on a non-system runtime, it cannot\n      function as a redistributable system component.\n\n    * Linking ZLIB1.DLL to non-Microsoft runtimes, such as\n      Borland's, or Cygwin's, raises problems related to the\n      reliable presence of these runtimes on Win32 systems.\n      It's easier to let the DLL build of zlib up to the people\n      who distribute these runtimes, and who may proceed as\n      explained in the answer to Question 14.\n\n\n13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL,\n    how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0\n    (Visual Studio .NET) or newer?\n\n  - Due to the problems explained in the Microsoft Knowledge Base\n    article KB326922 (see the previous answer), the C runtime that\n    comes with the VC7 environment is no longer considered a\n    system component.  That is, it should not be assumed that this\n    runtime exists, or may be installed in a system directory.\n    Since ZLIB1.DLL is supposed to be a system component, it may\n    not depend on a non-system component.\n\n    In order to link ZLIB1.DLL and your application to MSVCRT.DLL\n    in VC7, you need the library of Visual C++ 6.0 or older.  If\n    you don't have this library at hand, it's probably best not to\n    use ZLIB1.DLL.\n\n    We are hoping that, in the future, Microsoft will provide a\n    way to build applications linked to a proper system runtime,\n    from the Visual C++ environment.  Until then, you have a\n    couple of alternatives, such as linking zlib in statically.\n    If your application requires dynamic linking, you may proceed\n    as explained in the answer to Question 14.\n\n\n14. I need to link my own DLL build to a CRT different than\n    MSVCRT.DLL.  What can I do?\n\n  - Feel free to rebuild the DLL from the zlib sources, and link\n    it the way you want.  You should, however, clearly state that\n    your build is unofficial.  You should give it a different file\n    name, and/or install it in a private directory that can be\n    accessed by your application only, and is not visible to the\n    others (i.e. it's neither in the PATH, nor in the SYSTEM or\n    SYSTEM32 directories).  Otherwise, your build may clash with\n    applications that link to the official build.\n\n    For example, in Cygwin, zlib is linked to the Cygwin runtime\n    CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL.\n\n\n15. May I include additional pieces of code that I find useful,\n    link them in ZLIB1.DLL, and export them?\n\n  - No.  A legitimate build of ZLIB1.DLL must not include code\n    that does not originate from the official zlib source code.\n    But you can make your own private DLL build, under a different\n    file name, as suggested in the previous answer.\n\n    For example, zlib is a part of the VCL library, distributed\n    with Borland Delphi and C++ Builder.  The DLL build of VCL\n    is a redistributable file, named VCLxx.DLL.\n\n\n16. May I remove some functionality out of ZLIB1.DLL, by enabling\n    macros like NO_GZCOMPRESS or NO_GZIP at compile time?\n\n  - No.  A legitimate build of ZLIB1.DLL must provide the complete\n    zlib functionality, as implemented in the official zlib source\n    code.  But you can make your own private DLL build, under a\n    different file name, as suggested in the previous answer.\n\n\n17. I made my own ZLIB1.DLL build.  Can I test it for compliance?\n\n  - We prefer that you download the official DLL from the zlib\n    web site.  If you need something peculiar from this DLL, you\n    can send your suggestion to the zlib mailing list.\n\n    However, in case you do rebuild the DLL yourself, you can run\n    it with the test programs found in the DLL distribution.\n    Running these test programs is not a guarantee of compliance,\n    but a failure can imply a detected problem.\n\n**\n\nThis document is written and maintained by\nCosmin Truta <cosmint@cs.ubbcluj.ro>\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/win32/Makefile.bor",
    "content": "# Makefile for zlib\n# Borland C++ for Win32\n#\n# Usage:\n#  make -f win32/Makefile.bor\n#  make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj\n\n# ------------ Borland C++ ------------\n\n# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)\n# should be added to the environment via \"set LOCAL_ZLIB=-DFOO\" or\n# added to the declaration of LOC here:\nLOC = $(LOCAL_ZLIB)\n\nCC = bcc32\nAS = bcc32\nLD = bcc32\nAR = tlib\nCFLAGS  = -a -d -k- -O2 $(LOC)\nASFLAGS = $(LOC)\nLDFLAGS = $(LOC)\n\n\n# variables\nZLIB_LIB = zlib.lib\n\nOBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj\nOBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj\n#OBJA =\nOBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj\nOBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj\n#OBJPA=\n\n\n# targets\nall: $(ZLIB_LIB) example.exe minigzip.exe\n\n.c.obj:\n\t$(CC) -c $(CFLAGS) $<\n\n.asm.obj:\n\t$(AS) -c $(ASFLAGS) $<\n\nadler32.obj: adler32.c zlib.h zconf.h\n\ncompress.obj: compress.c zlib.h zconf.h\n\ncrc32.obj: crc32.c zlib.h zconf.h crc32.h\n\ndeflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h\n\ngzclose.obj: gzclose.c zlib.h zconf.h gzguts.h\n\ngzlib.obj: gzlib.c zlib.h zconf.h gzguts.h\n\ngzread.obj: gzread.c zlib.h zconf.h gzguts.h\n\ngzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h\n\ninfback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h inffixed.h\n\ninffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h\n\ninflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \\\n inffast.h inffixed.h\n\ninftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h\n\ntrees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h\n\nuncompr.obj: uncompr.c zlib.h zconf.h\n\nzutil.obj: zutil.c zutil.h zlib.h zconf.h\n\nexample.obj: test/example.c zlib.h zconf.h\n\nminigzip.obj: test/minigzip.c zlib.h zconf.h\n\n\n# For the sake of the old Borland make,\n# the command line is cut to fit in the MS-DOS 128 byte limit:\n$(ZLIB_LIB): $(OBJ1) $(OBJ2) $(OBJA)\n\t-del $(ZLIB_LIB)\n\t$(AR) $(ZLIB_LIB) $(OBJP1)\n\t$(AR) $(ZLIB_LIB) $(OBJP2)\n\t$(AR) $(ZLIB_LIB) $(OBJPA)\n\n\n# testing\ntest: example.exe minigzip.exe\n\texample\n\techo hello world | minigzip | minigzip -d\n\nexample.exe: example.obj $(ZLIB_LIB)\n\t$(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)\n\nminigzip.exe: minigzip.obj $(ZLIB_LIB)\n\t$(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)\n\n\n# cleanup\nclean:\n\t-del $(ZLIB_LIB)\n\t-del *.obj\n\t-del *.exe\n\t-del *.tds\n\t-del zlib.bak\n\t-del foo.gz\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/win32/Makefile.gcc",
    "content": "# Makefile for zlib, derived from Makefile.dj2.\n# Modified for mingw32 by C. Spieler, 6/16/98.\n# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003.\n# Last updated: Mar 2012.\n# Tested under Cygwin and MinGW.\n\n# Copyright (C) 1995-2003 Jean-loup Gailly.\n# For conditions of distribution and use, see copyright notice in zlib.h\n\n# To compile, or to compile and test, type from the top level zlib directory:\n#\n#   make -fwin32/Makefile.gcc;  make test testdll -fwin32/Makefile.gcc\n#\n# To use the asm code, type:\n#   cp contrib/asm?86/match.S ./match.S\n#   make LOC=-DASMV OBJA=match.o -fwin32/Makefile.gcc\n#\n# To install libz.a, zconf.h and zlib.h in the system directories, type:\n#\n#   make install -fwin32/Makefile.gcc\n#\n# BINARY_PATH, INCLUDE_PATH and LIBRARY_PATH must be set.\n#\n# To install the shared lib, append SHARED_MODE=1 to the make command :\n#\n#   make install -fwin32/Makefile.gcc SHARED_MODE=1\n\n# Note:\n# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN),\n# the DLL name should be changed from \"zlib1.dll\".\n\nSTATICLIB = libz.a\nSHAREDLIB = zlib1.dll\nIMPLIB    = libz.dll.a\n\n#\n# Set to 1 if shared object needs to be installed\n#\nSHARED_MODE=0\n\n#LOC = -DASMV\n#LOC = -DDEBUG -g\n\nPREFIX =\nCC = $(PREFIX)gcc\nCFLAGS = $(LOC) -O3 -Wall\n\nAS = $(CC)\nASFLAGS = $(LOC) -Wall\n\nLD = $(CC)\nLDFLAGS = $(LOC)\n\nAR = $(PREFIX)ar\nARFLAGS = rcs\n\nRC = $(PREFIX)windres\nRCFLAGS = --define GCC_WINDRES\n\nSTRIP = $(PREFIX)strip\n\nCP = cp -fp\n# If GNU install is available, replace $(CP) with install.\nINSTALL = $(CP)\nRM = rm -f\n\nprefix ?= /usr/local\nexec_prefix = $(prefix)\n\nOBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \\\n       gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o\nOBJA =\n\nall: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) example.exe minigzip.exe example_d.exe minigzip_d.exe\n\ntest: example.exe minigzip.exe\n\t./example\n\techo hello world | ./minigzip | ./minigzip -d\n\ntestdll: example_d.exe minigzip_d.exe\n\t./example_d\n\techo hello world | ./minigzip_d | ./minigzip_d -d\n\n.c.o:\n\t$(CC) $(CFLAGS) -c -o $@ $<\n\n.S.o:\n\t$(AS) $(ASFLAGS) -c -o $@ $<\n\n$(STATICLIB): $(OBJS) $(OBJA)\n\t$(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA)\n\n$(IMPLIB): $(SHAREDLIB)\n\n$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlibrc.o\n\t$(CC) -shared -Wl,--out-implib,$(IMPLIB) $(LDFLAGS) \\\n\t-o $@ win32/zlib.def $(OBJS) $(OBJA) zlibrc.o\n\t$(STRIP) $@\n\nexample.exe: example.o $(STATICLIB)\n\t$(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB)\n\t$(STRIP) $@\n\nminigzip.exe: minigzip.o $(STATICLIB)\n\t$(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB)\n\t$(STRIP) $@\n\nexample_d.exe: example.o $(IMPLIB)\n\t$(LD) $(LDFLAGS) -o $@ example.o $(IMPLIB)\n\t$(STRIP) $@\n\nminigzip_d.exe: minigzip.o $(IMPLIB)\n\t$(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB)\n\t$(STRIP) $@\n\nexample.o: test/example.c zlib.h zconf.h\n\t$(CC) $(CFLAGS) -I. -c -o $@ test/example.c\n\nminigzip.o: test/minigzip.c zlib.h zconf.h\n\t$(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c\n\nzlibrc.o: win32/zlib1.rc\n\t$(RC) $(RCFLAGS) -o $@ win32/zlib1.rc\n\n.PHONY: install uninstall clean\n\ninstall: zlib.h zconf.h $(STATICLIB) $(IMPLIB)\n\t@if test -z \"$(DESTDIR)$(INCLUDE_PATH)\" -o -z \"$(DESTDIR)$(LIBRARY_PATH)\" -o -z \"$(DESTDIR)$(BINARY_PATH)\"; then \\\n\t\techo INCLUDE_PATH, LIBRARY_PATH, and BINARY_PATH must be specified; \\\n\t\texit 1; \\\n\tfi\n\t-@mkdir -p '$(DESTDIR)$(INCLUDE_PATH)'\n\t-@mkdir -p '$(DESTDIR)$(LIBRARY_PATH)' '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig\n\t-if [ \"$(SHARED_MODE)\" = \"1\" ]; then \\\n\t\tmkdir -p '$(DESTDIR)$(BINARY_PATH)'; \\\n\t\t$(INSTALL) $(SHAREDLIB) '$(DESTDIR)$(BINARY_PATH)'; \\\n\t\t$(INSTALL) $(IMPLIB) '$(DESTDIR)$(LIBRARY_PATH)'; \\\n\tfi\n\t-$(INSTALL) zlib.h '$(DESTDIR)$(INCLUDE_PATH)'\n\t-$(INSTALL) zconf.h '$(DESTDIR)$(INCLUDE_PATH)'\n\t-$(INSTALL) $(STATICLIB) '$(DESTDIR)$(LIBRARY_PATH)'\n\tsed \\\n\t\t-e 's|@prefix@|${prefix}|g' \\\n\t\t-e 's|@exec_prefix@|${exec_prefix}|g' \\\n\t\t-e 's|@libdir@|$(LIBRARY_PATH)|g' \\\n\t\t-e 's|@sharedlibdir@|$(LIBRARY_PATH)|g' \\\n\t\t-e 's|@includedir@|$(INCLUDE_PATH)|g' \\\n\t\t-e 's|@VERSION@|'`sed -n -e '/VERSION \"/s/.*\"\\(.*\\)\".*/\\1/p' zlib.h`'|g' \\\n\t\tzlib.pc.in > '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig/zlib.pc\n\nuninstall:\n\t-if [ \"$(SHARED_MODE)\" = \"1\" ]; then \\\n\t\t$(RM) '$(DESTDIR)$(BINARY_PATH)'/$(SHAREDLIB); \\\n\t\t$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(IMPLIB); \\\n\tfi\n\t-$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zlib.h\n\t-$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zconf.h\n\t-$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(STATICLIB)\n\nclean:\n\t-$(RM) $(STATICLIB)\n\t-$(RM) $(SHAREDLIB)\n\t-$(RM) $(IMPLIB)\n\t-$(RM) *.o\n\t-$(RM) *.exe\n\t-$(RM) foo.gz\n\nadler32.o: zlib.h zconf.h\ncompress.o: zlib.h zconf.h\ncrc32.o: crc32.h zlib.h zconf.h\ndeflate.o: deflate.h zutil.h zlib.h zconf.h\ngzclose.o: zlib.h zconf.h gzguts.h\ngzlib.o: zlib.h zconf.h gzguts.h\ngzread.o: zlib.h zconf.h gzguts.h\ngzwrite.o: zlib.h zconf.h gzguts.h\ninffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h\ninflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h\ninfback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h\ninftrees.o: zutil.h zlib.h zconf.h inftrees.h\ntrees.o: deflate.h zutil.h zlib.h zconf.h trees.h\nuncompr.o: zlib.h zconf.h\nzutil.o: zutil.h zlib.h zconf.h\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/win32/Makefile.msc",
    "content": "# Makefile for zlib using Microsoft (Visual) C\n# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler\n#\n# Usage:\n#   nmake -f win32/Makefile.msc                          (standard build)\n#   nmake -f win32/Makefile.msc LOC=-DFOO                (nonstandard build)\n#   nmake -f win32/Makefile.msc LOC=\"-DASMV -DASMINF\" \\\n#         OBJA=\"inffas32.obj match686.obj\"               (use ASM code, x86)\n#   nmake -f win32/Makefile.msc AS=ml64 LOC=\"-DASMV -DASMINF -I.\" \\\n#         OBJA=\"inffasx64.obj gvmat64.obj inffas8664.obj\"  (use ASM code, x64)\n\n# The toplevel directory of the source tree.\n#\nTOP = .\n\n# optional build flags\nLOC =\n\n# variables\nSTATICLIB = zlib.lib\nSHAREDLIB = zlib1.dll\nIMPLIB    = zdll.lib\n\nCC = cl\nAS = ml\nLD = link\nAR = lib\nRC = rc\nCFLAGS  = -nologo -MD -W3 -O2 -Oy- -Zi -Fd\"zlib\" $(LOC)\nWFLAGS  = -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE\nASFLAGS = -coff -Zi $(LOC)\nLDFLAGS = -nologo -debug -incremental:no -opt:ref\nARFLAGS = -nologo\nRCFLAGS = /dWIN32 /r\n\nOBJS = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj \\\n       gzwrite.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj\nOBJA =\n\n\n# targets\nall: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \\\n     example.exe minigzip.exe example_d.exe minigzip_d.exe\n\n$(STATICLIB): $(OBJS) $(OBJA)\n\t$(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA)\n\n$(IMPLIB): $(SHAREDLIB)\n\n$(SHAREDLIB): $(TOP)/win32/zlib.def $(OBJS) $(OBJA) zlib1.res\n\t$(LD) $(LDFLAGS) -def:$(TOP)/win32/zlib.def -dll -implib:$(IMPLIB) \\\n\t  -out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res\n\tif exist $@.manifest \\\n\t  mt -nologo -manifest $@.manifest -outputresource:$@;2\n\nexample.exe: example.obj $(STATICLIB)\n\t$(LD) $(LDFLAGS) example.obj $(STATICLIB)\n\tif exist $@.manifest \\\n\t  mt -nologo -manifest $@.manifest -outputresource:$@;1\n\nminigzip.exe: minigzip.obj $(STATICLIB)\n\t$(LD) $(LDFLAGS) minigzip.obj $(STATICLIB)\n\tif exist $@.manifest \\\n\t  mt -nologo -manifest $@.manifest -outputresource:$@;1\n\nexample_d.exe: example.obj $(IMPLIB)\n\t$(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB)\n\tif exist $@.manifest \\\n\t  mt -nologo -manifest $@.manifest -outputresource:$@;1\n\nminigzip_d.exe: minigzip.obj $(IMPLIB)\n\t$(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB)\n\tif exist $@.manifest \\\n\t  mt -nologo -manifest $@.manifest -outputresource:$@;1\n\n{$(TOP)}.c.obj:\n\t$(CC) -c $(WFLAGS) $(CFLAGS) $<\n\n{$(TOP)/test}.c.obj:\n\t$(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $<\n\n{$(TOP)/contrib/masmx64}.c.obj:\n\t$(CC) -c $(WFLAGS) $(CFLAGS) $<\n\n{$(TOP)/contrib/masmx64}.asm.obj:\n\t$(AS) -c $(ASFLAGS) $<\n\n{$(TOP)/contrib/masmx86}.asm.obj:\n\t$(AS) -c $(ASFLAGS) $<\n\nadler32.obj: $(TOP)/adler32.c $(TOP)/zlib.h $(TOP)/zconf.h\n\ncompress.obj: $(TOP)/compress.c $(TOP)/zlib.h $(TOP)/zconf.h\n\ncrc32.obj: $(TOP)/crc32.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/crc32.h\n\ndeflate.obj: $(TOP)/deflate.c $(TOP)/deflate.h $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h\n\ngzclose.obj: $(TOP)/gzclose.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h\n\ngzlib.obj: $(TOP)/gzlib.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h\n\ngzread.obj: $(TOP)/gzread.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h\n\ngzwrite.obj: $(TOP)/gzwrite.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h\n\ninfback.obj: $(TOP)/infback.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \\\n             $(TOP)/inffast.h $(TOP)/inffixed.h\n\ninffast.obj: $(TOP)/inffast.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \\\n             $(TOP)/inffast.h\n\ninflate.obj: $(TOP)/inflate.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \\\n             $(TOP)/inffast.h $(TOP)/inffixed.h\n\ninftrees.obj: $(TOP)/inftrees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h\n\ntrees.obj: $(TOP)/trees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/deflate.h $(TOP)/trees.h\n\nuncompr.obj: $(TOP)/uncompr.c $(TOP)/zlib.h $(TOP)/zconf.h\n\nzutil.obj: $(TOP)/zutil.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h\n\ngvmat64.obj: $(TOP)/contrib\\masmx64\\gvmat64.asm\n\ninffasx64.obj: $(TOP)/contrib\\masmx64\\inffasx64.asm\n\ninffas8664.obj: $(TOP)/contrib\\masmx64\\inffas8664.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h \\\n\t\t$(TOP)/inftrees.h $(TOP)/inflate.h $(TOP)/inffast.h\n\ninffas32.obj: $(TOP)/contrib\\masmx86\\inffas32.asm\n\nmatch686.obj: $(TOP)/contrib\\masmx86\\match686.asm\n\nexample.obj: $(TOP)/test/example.c $(TOP)/zlib.h $(TOP)/zconf.h\n\nminigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zlib.h $(TOP)/zconf.h\n\nzlib1.res: $(TOP)/win32/zlib1.rc\n\t$(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/zlib1.rc\n\n# testing\ntest: example.exe minigzip.exe\n\texample\n\techo hello world | minigzip | minigzip -d\n\ntestdll: example_d.exe minigzip_d.exe\n\texample_d\n\techo hello world | minigzip_d | minigzip_d -d\n\n\n# cleanup\nclean:\n\t-del $(STATICLIB)\n\t-del $(SHAREDLIB)\n\t-del $(IMPLIB)\n\t-del *.obj\n\t-del *.res\n\t-del *.exp\n\t-del *.exe\n\t-del *.pdb\n\t-del *.manifest\n\t-del foo.gz\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/win32/README-WIN32.txt",
    "content": "ZLIB DATA COMPRESSION LIBRARY\n\nzlib 1.2.8 is a general purpose data compression library.  All the code is\nthread safe.  The data format used by the zlib library is described by RFCs\n(Request for Comments) 1950 to 1952 in the files\nhttp://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)\nand rfc1952.txt (gzip format).\n\nAll functions of the compression library are documented in the file zlib.h\n(volunteer to write man pages welcome, contact zlib@gzip.org).  Two compiled\nexamples are distributed in this package, example and minigzip.  The example_d\nand minigzip_d flavors validate that the zlib1.dll file is working correctly.\n\nQuestions about zlib should be sent to <zlib@gzip.org>.  The zlib home page\nis http://zlib.net/ .  Before reporting a problem, please check this site to\nverify that you have the latest version of zlib; otherwise get the latest\nversion and check whether the problem still exists or not.\n\nPLEASE read DLL_FAQ.txt, and the the zlib FAQ http://zlib.net/zlib_faq.html\nbefore asking for help.\n\n\nManifest:\n\nThe package zlib-1.2.8-win32-x86.zip will contain the following files:\n\n  README-WIN32.txt This document\n  ChangeLog        Changes since previous zlib packages\n  DLL_FAQ.txt      Frequently asked questions about zlib1.dll\n  zlib.3.pdf       Documentation of this library in Adobe Acrobat format\n\n  example.exe      A statically-bound example (using zlib.lib, not the dll)\n  example.pdb      Symbolic information for debugging example.exe\n\n  example_d.exe    A zlib1.dll bound example (using zdll.lib)\n  example_d.pdb    Symbolic information for debugging example_d.exe\n\n  minigzip.exe     A statically-bound test program (using zlib.lib, not the dll)\n  minigzip.pdb     Symbolic information for debugging minigzip.exe\n\n  minigzip_d.exe   A zlib1.dll bound test program (using zdll.lib)\n  minigzip_d.pdb   Symbolic information for debugging minigzip_d.exe\n\n  zlib.h           Install these files into the compilers' INCLUDE path to\n  zconf.h          compile programs which use zlib.lib or zdll.lib\n\n  zdll.lib         Install these files into the compilers' LIB path if linking\n  zdll.exp         a compiled program to the zlib1.dll binary\n\n  zlib.lib         Install these files into the compilers' LIB path to link zlib\n  zlib.pdb         into compiled programs, without zlib1.dll runtime dependency\n                   (zlib.pdb provides debugging info to the compile time linker)\n\n  zlib1.dll        Install this binary shared library into the system PATH, or\n                   the program's runtime directory (where the .exe resides)\n  zlib1.pdb        Install in the same directory as zlib1.dll, in order to debug\n                   an application crash using WinDbg or similar tools.\n\nAll .pdb files above are entirely optional, but are very useful to a developer\nattempting to diagnose program misbehavior or a crash.  Many additional\nimportant files for developers can be found in the zlib127.zip source package\navailable from http://zlib.net/ - review that package's README file for details.\n\n\nAcknowledgments:\n\nThe deflate format used by zlib was defined by Phil Katz.  The deflate and\nzlib specifications were written by L.  Peter Deutsch.  Thanks to all the\npeople who reported problems and suggested various improvements in zlib; they\nare too numerous to cite here.\n\n\nCopyright notice:\n\n  (C) 1995-2012 Jean-loup Gailly and Mark Adler\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Jean-loup Gailly        Mark Adler\n  jloup@gzip.org          madler@alumni.caltech.edu\n\nIf you use the zlib library in a product, we would appreciate *not* receiving\nlengthy legal documents to sign.  The sources are provided for free but without\nwarranty of any kind.  The library has been entirely written by Jean-loup\nGailly and Mark Adler; it does not include third-party code.\n\nIf you redistribute modified sources, we would appreciate that you include in\nthe file ChangeLog history information documenting your changes.  Please read\nthe FAQ for more information on the distribution of modified source versions.\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/win32/VisualC.txt",
    "content": "\nTo build zlib using the Microsoft Visual C++ environment,\nuse the appropriate project from the projects/ directory.\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/win32/zlib.def",
    "content": "; zlib data compression library\nEXPORTS\n; basic functions\n    zlibVersion\n    deflate\n    deflateEnd\n    inflate\n    inflateEnd\n; advanced functions\n    deflateSetDictionary\n    deflateCopy\n    deflateReset\n    deflateParams\n    deflateTune\n    deflateBound\n    deflatePending\n    deflatePrime\n    deflateSetHeader\n    inflateSetDictionary\n    inflateGetDictionary\n    inflateSync\n    inflateCopy\n    inflateReset\n    inflateReset2\n    inflatePrime\n    inflateMark\n    inflateGetHeader\n    inflateBack\n    inflateBackEnd\n    zlibCompileFlags\n; utility functions\n    compress\n    compress2\n    compressBound\n    uncompress\n    gzopen\n    gzdopen\n    gzbuffer\n    gzsetparams\n    gzread\n    gzwrite\n    gzprintf\n    gzvprintf\n    gzputs\n    gzgets\n    gzputc\n    gzgetc\n    gzungetc\n    gzflush\n    gzseek\n    gzrewind\n    gztell\n    gzoffset\n    gzeof\n    gzdirect\n    gzclose\n    gzclose_r\n    gzclose_w\n    gzerror\n    gzclearerr\n; large file functions\n    gzopen64\n    gzseek64\n    gztell64\n    gzoffset64\n    adler32_combine64\n    crc32_combine64\n; checksum functions\n    adler32\n    crc32\n    adler32_combine\n    crc32_combine\n; various hacks, don't look :)\n    deflateInit_\n    deflateInit2_\n    inflateInit_\n    inflateInit2_\n    inflateBackInit_\n    gzgetc_\n    zError\n    inflateSyncPoint\n    get_crc_table\n    inflateUndermine\n    inflateResetKeep\n    deflateResetKeep\n    gzopen_w\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/win32/zlib1.rc",
    "content": "#include <winver.h>\n#include \"../zlib.h\"\n\n#ifdef GCC_WINDRES\nVS_VERSION_INFO\t\tVERSIONINFO\n#else\nVS_VERSION_INFO\t\tVERSIONINFO\tMOVEABLE IMPURE LOADONCALL DISCARDABLE\n#endif\n  FILEVERSION\t\tZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0\n  PRODUCTVERSION\tZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0\n  FILEFLAGSMASK\t\tVS_FFI_FILEFLAGSMASK\n#ifdef _DEBUG\n  FILEFLAGS\t\t1\n#else\n  FILEFLAGS\t\t0\n#endif\n  FILEOS\t\tVOS__WINDOWS32\n  FILETYPE\t\tVFT_DLL\n  FILESUBTYPE\t\t0\t// not used\nBEGIN\n  BLOCK \"StringFileInfo\"\n  BEGIN\n    BLOCK \"040904E4\"\n    //language ID = U.S. English, char set = Windows, Multilingual\n    BEGIN\n      VALUE \"FileDescription\",\t\"zlib data compression library\\0\"\n      VALUE \"FileVersion\",\tZLIB_VERSION \"\\0\"\n      VALUE \"InternalName\",\t\"zlib1.dll\\0\"\n      VALUE \"LegalCopyright\",\t\"(C) 1995-2013 Jean-loup Gailly & Mark Adler\\0\"\n      VALUE \"OriginalFilename\",\t\"zlib1.dll\\0\"\n      VALUE \"ProductName\",\t\"zlib\\0\"\n      VALUE \"ProductVersion\",\tZLIB_VERSION \"\\0\"\n      VALUE \"Comments\",\t\t\"For more information visit http://www.zlib.net/\\0\"\n    END\n  END\n  BLOCK \"VarFileInfo\"\n  BEGIN\n    VALUE \"Translation\", 0x0409, 1252\n  END\nEND\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/zconf.h",
    "content": "/* zconf.h -- configuration of the zlib compression library\n * Copyright (C) 1995-2013 Jean-loup Gailly.\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* @(#) $Id$ */\n\n#ifndef ZCONF_H\n#define ZCONF_H\n\n/*\n * If you *really* need a unique prefix for all types and library functions,\n * compile with -DZ_PREFIX. The \"standard\" zlib should be compiled without it.\n * Even better than compiling with -DZ_PREFIX would be to use configure to set\n * this permanently in zconf.h using \"./configure --zprefix\".\n */\n#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */\n#  define Z_PREFIX_SET\n\n/* all linked symbols */\n#  define _dist_code            z__dist_code\n#  define _length_code          z__length_code\n#  define _tr_align             z__tr_align\n#  define _tr_flush_bits        z__tr_flush_bits\n#  define _tr_flush_block       z__tr_flush_block\n#  define _tr_init              z__tr_init\n#  define _tr_stored_block      z__tr_stored_block\n#  define _tr_tally             z__tr_tally\n#  define adler32               z_adler32\n#  define adler32_combine       z_adler32_combine\n#  define adler32_combine64     z_adler32_combine64\n#  ifndef Z_SOLO\n#    define compress              z_compress\n#    define compress2             z_compress2\n#    define compressBound         z_compressBound\n#  endif\n#  define crc32                 z_crc32\n#  define crc32_combine         z_crc32_combine\n#  define crc32_combine64       z_crc32_combine64\n#  define deflate               z_deflate\n#  define deflateBound          z_deflateBound\n#  define deflateCopy           z_deflateCopy\n#  define deflateEnd            z_deflateEnd\n#  define deflateInit2_         z_deflateInit2_\n#  define deflateInit_          z_deflateInit_\n#  define deflateParams         z_deflateParams\n#  define deflatePending        z_deflatePending\n#  define deflatePrime          z_deflatePrime\n#  define deflateReset          z_deflateReset\n#  define deflateResetKeep      z_deflateResetKeep\n#  define deflateSetDictionary  z_deflateSetDictionary\n#  define deflateSetHeader      z_deflateSetHeader\n#  define deflateTune           z_deflateTune\n#  define deflate_copyright     z_deflate_copyright\n#  define get_crc_table         z_get_crc_table\n#  ifndef Z_SOLO\n#    define gz_error              z_gz_error\n#    define gz_intmax             z_gz_intmax\n#    define gz_strwinerror        z_gz_strwinerror\n#    define gzbuffer              z_gzbuffer\n#    define gzclearerr            z_gzclearerr\n#    define gzclose               z_gzclose\n#    define gzclose_r             z_gzclose_r\n#    define gzclose_w             z_gzclose_w\n#    define gzdirect              z_gzdirect\n#    define gzdopen               z_gzdopen\n#    define gzeof                 z_gzeof\n#    define gzerror               z_gzerror\n#    define gzflush               z_gzflush\n#    define gzgetc                z_gzgetc\n#    define gzgetc_               z_gzgetc_\n#    define gzgets                z_gzgets\n#    define gzoffset              z_gzoffset\n#    define gzoffset64            z_gzoffset64\n#    define gzopen                z_gzopen\n#    define gzopen64              z_gzopen64\n#    ifdef _WIN32\n#      define gzopen_w              z_gzopen_w\n#    endif\n#    define gzprintf              z_gzprintf\n#    define gzvprintf             z_gzvprintf\n#    define gzputc                z_gzputc\n#    define gzputs                z_gzputs\n#    define gzread                z_gzread\n#    define gzrewind              z_gzrewind\n#    define gzseek                z_gzseek\n#    define gzseek64              z_gzseek64\n#    define gzsetparams           z_gzsetparams\n#    define gztell                z_gztell\n#    define gztell64              z_gztell64\n#    define gzungetc              z_gzungetc\n#    define gzwrite               z_gzwrite\n#  endif\n#  define inflate               z_inflate\n#  define inflateBack           z_inflateBack\n#  define inflateBackEnd        z_inflateBackEnd\n#  define inflateBackInit_      z_inflateBackInit_\n#  define inflateCopy           z_inflateCopy\n#  define inflateEnd            z_inflateEnd\n#  define inflateGetHeader      z_inflateGetHeader\n#  define inflateInit2_         z_inflateInit2_\n#  define inflateInit_          z_inflateInit_\n#  define inflateMark           z_inflateMark\n#  define inflatePrime          z_inflatePrime\n#  define inflateReset          z_inflateReset\n#  define inflateReset2         z_inflateReset2\n#  define inflateSetDictionary  z_inflateSetDictionary\n#  define inflateGetDictionary  z_inflateGetDictionary\n#  define inflateSync           z_inflateSync\n#  define inflateSyncPoint      z_inflateSyncPoint\n#  define inflateUndermine      z_inflateUndermine\n#  define inflateResetKeep      z_inflateResetKeep\n#  define inflate_copyright     z_inflate_copyright\n#  define inflate_fast          z_inflate_fast\n#  define inflate_table         z_inflate_table\n#  ifndef Z_SOLO\n#    define uncompress            z_uncompress\n#  endif\n#  define zError                z_zError\n#  ifndef Z_SOLO\n#    define zcalloc               z_zcalloc\n#    define zcfree                z_zcfree\n#  endif\n#  define zlibCompileFlags      z_zlibCompileFlags\n#  define zlibVersion           z_zlibVersion\n\n/* all zlib typedefs in zlib.h and zconf.h */\n#  define Byte                  z_Byte\n#  define Bytef                 z_Bytef\n#  define alloc_func            z_alloc_func\n#  define charf                 z_charf\n#  define free_func             z_free_func\n#  ifndef Z_SOLO\n#    define gzFile                z_gzFile\n#  endif\n#  define gz_header             z_gz_header\n#  define gz_headerp            z_gz_headerp\n#  define in_func               z_in_func\n#  define intf                  z_intf\n#  define out_func              z_out_func\n#  define uInt                  z_uInt\n#  define uIntf                 z_uIntf\n#  define uLong                 z_uLong\n#  define uLongf                z_uLongf\n#  define voidp                 z_voidp\n#  define voidpc                z_voidpc\n#  define voidpf                z_voidpf\n\n/* all zlib structs in zlib.h and zconf.h */\n#  define gz_header_s           z_gz_header_s\n#  define internal_state        z_internal_state\n\n#endif\n\n#if defined(__MSDOS__) && !defined(MSDOS)\n#  define MSDOS\n#endif\n#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)\n#  define OS2\n#endif\n#if defined(_WINDOWS) && !defined(WINDOWS)\n#  define WINDOWS\n#endif\n#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)\n#  ifndef WIN32\n#    define WIN32\n#  endif\n#endif\n#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)\n#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)\n#    ifndef SYS16BIT\n#      define SYS16BIT\n#    endif\n#  endif\n#endif\n\n/*\n * Compile with -DMAXSEG_64K if the alloc function cannot allocate more\n * than 64k bytes at a time (needed on systems with 16-bit int).\n */\n#ifdef SYS16BIT\n#  define MAXSEG_64K\n#endif\n#ifdef MSDOS\n#  define UNALIGNED_OK\n#endif\n\n#ifdef __STDC_VERSION__\n#  ifndef STDC\n#    define STDC\n#  endif\n#  if __STDC_VERSION__ >= 199901L\n#    ifndef STDC99\n#      define STDC99\n#    endif\n#  endif\n#endif\n#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))\n#  define STDC\n#endif\n#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))\n#  define STDC\n#endif\n#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))\n#  define STDC\n#endif\n#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))\n#  define STDC\n#endif\n\n#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */\n#  define STDC\n#endif\n\n#ifndef STDC\n#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */\n#    define const       /* note: need a more gentle solution here */\n#  endif\n#endif\n\n#if defined(ZLIB_CONST) && !defined(z_const)\n#  define z_const const\n#else\n#  define z_const\n#endif\n\n/* Some Mac compilers merge all .h files incorrectly: */\n#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)\n#  define NO_DUMMY_DECL\n#endif\n\n/* Maximum value for memLevel in deflateInit2 */\n#ifndef MAX_MEM_LEVEL\n#  ifdef MAXSEG_64K\n#    define MAX_MEM_LEVEL 8\n#  else\n#    define MAX_MEM_LEVEL 9\n#  endif\n#endif\n\n/* Maximum value for windowBits in deflateInit2 and inflateInit2.\n * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files\n * created by gzip. (Files created by minigzip can still be extracted by\n * gzip.)\n */\n#ifndef MAX_WBITS\n#  define MAX_WBITS   15 /* 32K LZ77 window */\n#endif\n\n/* The memory requirements for deflate are (in bytes):\n            (1 << (windowBits+2)) +  (1 << (memLevel+9))\n that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)\n plus a few kilobytes for small objects. For example, if you want to reduce\n the default memory requirements from 256K to 128K, compile with\n     make CFLAGS=\"-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7\"\n Of course this will generally degrade compression (there's no free lunch).\n\n   The memory requirements for inflate are (in bytes) 1 << windowBits\n that is, 32K for windowBits=15 (default value) plus a few kilobytes\n for small objects.\n*/\n\n                        /* Type declarations */\n\n#ifndef OF /* function prototypes */\n#  ifdef STDC\n#    define OF(args)  args\n#  else\n#    define OF(args)  ()\n#  endif\n#endif\n\n#ifndef Z_ARG /* function prototypes for stdarg */\n#  if defined(STDC) || defined(Z_HAVE_STDARG_H)\n#    define Z_ARG(args)  args\n#  else\n#    define Z_ARG(args)  ()\n#  endif\n#endif\n\n/* The following definitions for FAR are needed only for MSDOS mixed\n * model programming (small or medium model with some far allocations).\n * This was tested only with MSC; for other MSDOS compilers you may have\n * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,\n * just define FAR to be empty.\n */\n#ifdef SYS16BIT\n#  if defined(M_I86SM) || defined(M_I86MM)\n     /* MSC small or medium model */\n#    define SMALL_MEDIUM\n#    ifdef _MSC_VER\n#      define FAR _far\n#    else\n#      define FAR far\n#    endif\n#  endif\n#  if (defined(__SMALL__) || defined(__MEDIUM__))\n     /* Turbo C small or medium model */\n#    define SMALL_MEDIUM\n#    ifdef __BORLANDC__\n#      define FAR _far\n#    else\n#      define FAR far\n#    endif\n#  endif\n#endif\n\n#if defined(WINDOWS) || defined(WIN32)\n   /* If building or using zlib as a DLL, define ZLIB_DLL.\n    * This is not mandatory, but it offers a little performance increase.\n    */\n#  ifdef ZLIB_DLL\n#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))\n#      ifdef ZLIB_INTERNAL\n#        define ZEXTERN extern __declspec(dllexport)\n#      else\n#        define ZEXTERN extern __declspec(dllimport)\n#      endif\n#    endif\n#  endif  /* ZLIB_DLL */\n   /* If building or using zlib with the WINAPI/WINAPIV calling convention,\n    * define ZLIB_WINAPI.\n    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.\n    */\n#  ifdef ZLIB_WINAPI\n#    ifdef FAR\n#      undef FAR\n#    endif\n#    include <windows.h>\n     /* No need for _export, use ZLIB.DEF instead. */\n     /* For complete Windows compatibility, use WINAPI, not __stdcall. */\n#    define ZEXPORT WINAPI\n#    ifdef WIN32\n#      define ZEXPORTVA WINAPIV\n#    else\n#      define ZEXPORTVA FAR CDECL\n#    endif\n#  endif\n#endif\n\n#if defined (__BEOS__)\n#  ifdef ZLIB_DLL\n#    ifdef ZLIB_INTERNAL\n#      define ZEXPORT   __declspec(dllexport)\n#      define ZEXPORTVA __declspec(dllexport)\n#    else\n#      define ZEXPORT   __declspec(dllimport)\n#      define ZEXPORTVA __declspec(dllimport)\n#    endif\n#  endif\n#endif\n\n#ifndef ZEXTERN\n#  define ZEXTERN extern\n#endif\n#ifndef ZEXPORT\n#  define ZEXPORT\n#endif\n#ifndef ZEXPORTVA\n#  define ZEXPORTVA\n#endif\n\n#ifndef FAR\n#  define FAR\n#endif\n\n#if !defined(__MACTYPES__)\ntypedef unsigned char  Byte;  /* 8 bits */\n#endif\ntypedef unsigned int   uInt;  /* 16 bits or more */\ntypedef unsigned long  uLong; /* 32 bits or more */\n\n#ifdef SMALL_MEDIUM\n   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */\n#  define Bytef Byte FAR\n#else\n   typedef Byte  FAR Bytef;\n#endif\ntypedef char  FAR charf;\ntypedef int   FAR intf;\ntypedef uInt  FAR uIntf;\ntypedef uLong FAR uLongf;\n\n#ifdef STDC\n   typedef void const *voidpc;\n   typedef void FAR   *voidpf;\n   typedef void       *voidp;\n#else\n   typedef Byte const *voidpc;\n   typedef Byte FAR   *voidpf;\n   typedef Byte       *voidp;\n#endif\n\n#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)\n#  include <limits.h>\n#  if (UINT_MAX == 0xffffffffUL)\n#    define Z_U4 unsigned\n#  elif (ULONG_MAX == 0xffffffffUL)\n#    define Z_U4 unsigned long\n#  elif (USHRT_MAX == 0xffffffffUL)\n#    define Z_U4 unsigned short\n#  endif\n#endif\n\n#ifdef Z_U4\n   typedef Z_U4 z_crc_t;\n#else\n   typedef unsigned long z_crc_t;\n#endif\n\n#if 1    /* was set to #if 1 by ./configure */\n#  define Z_HAVE_UNISTD_H\n#endif\n\n#if 1    /* was set to #if 1 by ./configure */\n#  define Z_HAVE_STDARG_H\n#endif\n\n#ifdef STDC\n#  ifndef Z_SOLO\n#    include <sys/types.h>      /* for off_t */\n#  endif\n#endif\n\n#if defined(STDC) || defined(Z_HAVE_STDARG_H)\n#  ifndef Z_SOLO\n#    include <stdarg.h>         /* for va_list */\n#  endif\n#endif\n\n#ifdef _WIN32\n#  ifndef Z_SOLO\n#    include <stddef.h>         /* for wchar_t */\n#  endif\n#endif\n\n/* a little trick to accommodate both \"#define _LARGEFILE64_SOURCE\" and\n * \"#define _LARGEFILE64_SOURCE 1\" as requesting 64-bit operations, (even\n * though the former does not conform to the LFS document), but considering\n * both \"#undef _LARGEFILE64_SOURCE\" and \"#define _LARGEFILE64_SOURCE 0\" as\n * equivalently requesting no 64-bit operations\n */\n#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1\n#  undef _LARGEFILE64_SOURCE\n#endif\n\n#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)\n#  define Z_HAVE_UNISTD_H\n#endif\n#ifndef Z_SOLO\n#  if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)\n#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */\n#    ifdef VMS\n#      include <unixio.h>       /* for off_t */\n#    endif\n#    ifndef z_off_t\n#      define z_off_t off_t\n#    endif\n#  endif\n#endif\n\n#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0\n#  define Z_LFS64\n#endif\n\n#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)\n#  define Z_LARGE64\n#endif\n\n#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)\n#  define Z_WANT64\n#endif\n\n#if !defined(SEEK_SET) && !defined(Z_SOLO)\n#  define SEEK_SET        0       /* Seek from beginning of file.  */\n#  define SEEK_CUR        1       /* Seek from current position.  */\n#  define SEEK_END        2       /* Set file pointer to EOF plus \"offset\" */\n#endif\n\n#ifndef z_off_t\n#  define z_off_t long\n#endif\n\n#if !defined(_WIN32) && defined(Z_LARGE64)\n#  define z_off64_t off64_t\n#else\n#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)\n#    define z_off64_t __int64\n#  else\n#    define z_off64_t z_off_t\n#  endif\n#endif\n\n/* MVS linker does not support external names larger than 8 bytes */\n#if defined(__MVS__)\n  #pragma map(deflateInit_,\"DEIN\")\n  #pragma map(deflateInit2_,\"DEIN2\")\n  #pragma map(deflateEnd,\"DEEND\")\n  #pragma map(deflateBound,\"DEBND\")\n  #pragma map(inflateInit_,\"ININ\")\n  #pragma map(inflateInit2_,\"ININ2\")\n  #pragma map(inflateEnd,\"INEND\")\n  #pragma map(inflateSync,\"INSY\")\n  #pragma map(inflateSetDictionary,\"INSEDI\")\n  #pragma map(compressBound,\"CMBND\")\n  #pragma map(inflate_table,\"INTABL\")\n  #pragma map(inflate_fast,\"INFA\")\n  #pragma map(inflate_copyright,\"INCOPY\")\n#endif\n\n#endif /* ZCONF_H */\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/zconf.h.cmakein",
    "content": "/* zconf.h -- configuration of the zlib compression library\n * Copyright (C) 1995-2013 Jean-loup Gailly.\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* @(#) $Id$ */\n\n#ifndef ZCONF_H\n#define ZCONF_H\n#cmakedefine Z_PREFIX\n#cmakedefine Z_HAVE_UNISTD_H\n\n/*\n * If you *really* need a unique prefix for all types and library functions,\n * compile with -DZ_PREFIX. The \"standard\" zlib should be compiled without it.\n * Even better than compiling with -DZ_PREFIX would be to use configure to set\n * this permanently in zconf.h using \"./configure --zprefix\".\n */\n#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */\n#  define Z_PREFIX_SET\n\n/* all linked symbols */\n#  define _dist_code            z__dist_code\n#  define _length_code          z__length_code\n#  define _tr_align             z__tr_align\n#  define _tr_flush_bits        z__tr_flush_bits\n#  define _tr_flush_block       z__tr_flush_block\n#  define _tr_init              z__tr_init\n#  define _tr_stored_block      z__tr_stored_block\n#  define _tr_tally             z__tr_tally\n#  define adler32               z_adler32\n#  define adler32_combine       z_adler32_combine\n#  define adler32_combine64     z_adler32_combine64\n#  ifndef Z_SOLO\n#    define compress              z_compress\n#    define compress2             z_compress2\n#    define compressBound         z_compressBound\n#  endif\n#  define crc32                 z_crc32\n#  define crc32_combine         z_crc32_combine\n#  define crc32_combine64       z_crc32_combine64\n#  define deflate               z_deflate\n#  define deflateBound          z_deflateBound\n#  define deflateCopy           z_deflateCopy\n#  define deflateEnd            z_deflateEnd\n#  define deflateInit2_         z_deflateInit2_\n#  define deflateInit_          z_deflateInit_\n#  define deflateParams         z_deflateParams\n#  define deflatePending        z_deflatePending\n#  define deflatePrime          z_deflatePrime\n#  define deflateReset          z_deflateReset\n#  define deflateResetKeep      z_deflateResetKeep\n#  define deflateSetDictionary  z_deflateSetDictionary\n#  define deflateSetHeader      z_deflateSetHeader\n#  define deflateTune           z_deflateTune\n#  define deflate_copyright     z_deflate_copyright\n#  define get_crc_table         z_get_crc_table\n#  ifndef Z_SOLO\n#    define gz_error              z_gz_error\n#    define gz_intmax             z_gz_intmax\n#    define gz_strwinerror        z_gz_strwinerror\n#    define gzbuffer              z_gzbuffer\n#    define gzclearerr            z_gzclearerr\n#    define gzclose               z_gzclose\n#    define gzclose_r             z_gzclose_r\n#    define gzclose_w             z_gzclose_w\n#    define gzdirect              z_gzdirect\n#    define gzdopen               z_gzdopen\n#    define gzeof                 z_gzeof\n#    define gzerror               z_gzerror\n#    define gzflush               z_gzflush\n#    define gzgetc                z_gzgetc\n#    define gzgetc_               z_gzgetc_\n#    define gzgets                z_gzgets\n#    define gzoffset              z_gzoffset\n#    define gzoffset64            z_gzoffset64\n#    define gzopen                z_gzopen\n#    define gzopen64              z_gzopen64\n#    ifdef _WIN32\n#      define gzopen_w              z_gzopen_w\n#    endif\n#    define gzprintf              z_gzprintf\n#    define gzvprintf             z_gzvprintf\n#    define gzputc                z_gzputc\n#    define gzputs                z_gzputs\n#    define gzread                z_gzread\n#    define gzrewind              z_gzrewind\n#    define gzseek                z_gzseek\n#    define gzseek64              z_gzseek64\n#    define gzsetparams           z_gzsetparams\n#    define gztell                z_gztell\n#    define gztell64              z_gztell64\n#    define gzungetc              z_gzungetc\n#    define gzwrite               z_gzwrite\n#  endif\n#  define inflate               z_inflate\n#  define inflateBack           z_inflateBack\n#  define inflateBackEnd        z_inflateBackEnd\n#  define inflateBackInit_      z_inflateBackInit_\n#  define inflateCopy           z_inflateCopy\n#  define inflateEnd            z_inflateEnd\n#  define inflateGetHeader      z_inflateGetHeader\n#  define inflateInit2_         z_inflateInit2_\n#  define inflateInit_          z_inflateInit_\n#  define inflateMark           z_inflateMark\n#  define inflatePrime          z_inflatePrime\n#  define inflateReset          z_inflateReset\n#  define inflateReset2         z_inflateReset2\n#  define inflateSetDictionary  z_inflateSetDictionary\n#  define inflateGetDictionary  z_inflateGetDictionary\n#  define inflateSync           z_inflateSync\n#  define inflateSyncPoint      z_inflateSyncPoint\n#  define inflateUndermine      z_inflateUndermine\n#  define inflateResetKeep      z_inflateResetKeep\n#  define inflate_copyright     z_inflate_copyright\n#  define inflate_fast          z_inflate_fast\n#  define inflate_table         z_inflate_table\n#  ifndef Z_SOLO\n#    define uncompress            z_uncompress\n#  endif\n#  define zError                z_zError\n#  ifndef Z_SOLO\n#    define zcalloc               z_zcalloc\n#    define zcfree                z_zcfree\n#  endif\n#  define zlibCompileFlags      z_zlibCompileFlags\n#  define zlibVersion           z_zlibVersion\n\n/* all zlib typedefs in zlib.h and zconf.h */\n#  define Byte                  z_Byte\n#  define Bytef                 z_Bytef\n#  define alloc_func            z_alloc_func\n#  define charf                 z_charf\n#  define free_func             z_free_func\n#  ifndef Z_SOLO\n#    define gzFile                z_gzFile\n#  endif\n#  define gz_header             z_gz_header\n#  define gz_headerp            z_gz_headerp\n#  define in_func               z_in_func\n#  define intf                  z_intf\n#  define out_func              z_out_func\n#  define uInt                  z_uInt\n#  define uIntf                 z_uIntf\n#  define uLong                 z_uLong\n#  define uLongf                z_uLongf\n#  define voidp                 z_voidp\n#  define voidpc                z_voidpc\n#  define voidpf                z_voidpf\n\n/* all zlib structs in zlib.h and zconf.h */\n#  define gz_header_s           z_gz_header_s\n#  define internal_state        z_internal_state\n\n#endif\n\n#if defined(__MSDOS__) && !defined(MSDOS)\n#  define MSDOS\n#endif\n#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)\n#  define OS2\n#endif\n#if defined(_WINDOWS) && !defined(WINDOWS)\n#  define WINDOWS\n#endif\n#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)\n#  ifndef WIN32\n#    define WIN32\n#  endif\n#endif\n#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)\n#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)\n#    ifndef SYS16BIT\n#      define SYS16BIT\n#    endif\n#  endif\n#endif\n\n/*\n * Compile with -DMAXSEG_64K if the alloc function cannot allocate more\n * than 64k bytes at a time (needed on systems with 16-bit int).\n */\n#ifdef SYS16BIT\n#  define MAXSEG_64K\n#endif\n#ifdef MSDOS\n#  define UNALIGNED_OK\n#endif\n\n#ifdef __STDC_VERSION__\n#  ifndef STDC\n#    define STDC\n#  endif\n#  if __STDC_VERSION__ >= 199901L\n#    ifndef STDC99\n#      define STDC99\n#    endif\n#  endif\n#endif\n#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))\n#  define STDC\n#endif\n#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))\n#  define STDC\n#endif\n#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))\n#  define STDC\n#endif\n#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))\n#  define STDC\n#endif\n\n#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */\n#  define STDC\n#endif\n\n#ifndef STDC\n#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */\n#    define const       /* note: need a more gentle solution here */\n#  endif\n#endif\n\n#if defined(ZLIB_CONST) && !defined(z_const)\n#  define z_const const\n#else\n#  define z_const\n#endif\n\n/* Some Mac compilers merge all .h files incorrectly: */\n#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)\n#  define NO_DUMMY_DECL\n#endif\n\n/* Maximum value for memLevel in deflateInit2 */\n#ifndef MAX_MEM_LEVEL\n#  ifdef MAXSEG_64K\n#    define MAX_MEM_LEVEL 8\n#  else\n#    define MAX_MEM_LEVEL 9\n#  endif\n#endif\n\n/* Maximum value for windowBits in deflateInit2 and inflateInit2.\n * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files\n * created by gzip. (Files created by minigzip can still be extracted by\n * gzip.)\n */\n#ifndef MAX_WBITS\n#  define MAX_WBITS   15 /* 32K LZ77 window */\n#endif\n\n/* The memory requirements for deflate are (in bytes):\n            (1 << (windowBits+2)) +  (1 << (memLevel+9))\n that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)\n plus a few kilobytes for small objects. For example, if you want to reduce\n the default memory requirements from 256K to 128K, compile with\n     make CFLAGS=\"-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7\"\n Of course this will generally degrade compression (there's no free lunch).\n\n   The memory requirements for inflate are (in bytes) 1 << windowBits\n that is, 32K for windowBits=15 (default value) plus a few kilobytes\n for small objects.\n*/\n\n                        /* Type declarations */\n\n#ifndef OF /* function prototypes */\n#  ifdef STDC\n#    define OF(args)  args\n#  else\n#    define OF(args)  ()\n#  endif\n#endif\n\n#ifndef Z_ARG /* function prototypes for stdarg */\n#  if defined(STDC) || defined(Z_HAVE_STDARG_H)\n#    define Z_ARG(args)  args\n#  else\n#    define Z_ARG(args)  ()\n#  endif\n#endif\n\n/* The following definitions for FAR are needed only for MSDOS mixed\n * model programming (small or medium model with some far allocations).\n * This was tested only with MSC; for other MSDOS compilers you may have\n * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,\n * just define FAR to be empty.\n */\n#ifdef SYS16BIT\n#  if defined(M_I86SM) || defined(M_I86MM)\n     /* MSC small or medium model */\n#    define SMALL_MEDIUM\n#    ifdef _MSC_VER\n#      define FAR _far\n#    else\n#      define FAR far\n#    endif\n#  endif\n#  if (defined(__SMALL__) || defined(__MEDIUM__))\n     /* Turbo C small or medium model */\n#    define SMALL_MEDIUM\n#    ifdef __BORLANDC__\n#      define FAR _far\n#    else\n#      define FAR far\n#    endif\n#  endif\n#endif\n\n#if defined(WINDOWS) || defined(WIN32)\n   /* If building or using zlib as a DLL, define ZLIB_DLL.\n    * This is not mandatory, but it offers a little performance increase.\n    */\n#  ifdef ZLIB_DLL\n#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))\n#      ifdef ZLIB_INTERNAL\n#        define ZEXTERN extern __declspec(dllexport)\n#      else\n#        define ZEXTERN extern __declspec(dllimport)\n#      endif\n#    endif\n#  endif  /* ZLIB_DLL */\n   /* If building or using zlib with the WINAPI/WINAPIV calling convention,\n    * define ZLIB_WINAPI.\n    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.\n    */\n#  ifdef ZLIB_WINAPI\n#    ifdef FAR\n#      undef FAR\n#    endif\n#    include <windows.h>\n     /* No need for _export, use ZLIB.DEF instead. */\n     /* For complete Windows compatibility, use WINAPI, not __stdcall. */\n#    define ZEXPORT WINAPI\n#    ifdef WIN32\n#      define ZEXPORTVA WINAPIV\n#    else\n#      define ZEXPORTVA FAR CDECL\n#    endif\n#  endif\n#endif\n\n#if defined (__BEOS__)\n#  ifdef ZLIB_DLL\n#    ifdef ZLIB_INTERNAL\n#      define ZEXPORT   __declspec(dllexport)\n#      define ZEXPORTVA __declspec(dllexport)\n#    else\n#      define ZEXPORT   __declspec(dllimport)\n#      define ZEXPORTVA __declspec(dllimport)\n#    endif\n#  endif\n#endif\n\n#ifndef ZEXTERN\n#  define ZEXTERN extern\n#endif\n#ifndef ZEXPORT\n#  define ZEXPORT\n#endif\n#ifndef ZEXPORTVA\n#  define ZEXPORTVA\n#endif\n\n#ifndef FAR\n#  define FAR\n#endif\n\n#if !defined(__MACTYPES__)\ntypedef unsigned char  Byte;  /* 8 bits */\n#endif\ntypedef unsigned int   uInt;  /* 16 bits or more */\ntypedef unsigned long  uLong; /* 32 bits or more */\n\n#ifdef SMALL_MEDIUM\n   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */\n#  define Bytef Byte FAR\n#else\n   typedef Byte  FAR Bytef;\n#endif\ntypedef char  FAR charf;\ntypedef int   FAR intf;\ntypedef uInt  FAR uIntf;\ntypedef uLong FAR uLongf;\n\n#ifdef STDC\n   typedef void const *voidpc;\n   typedef void FAR   *voidpf;\n   typedef void       *voidp;\n#else\n   typedef Byte const *voidpc;\n   typedef Byte FAR   *voidpf;\n   typedef Byte       *voidp;\n#endif\n\n#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)\n#  include <limits.h>\n#  if (UINT_MAX == 0xffffffffUL)\n#    define Z_U4 unsigned\n#  elif (ULONG_MAX == 0xffffffffUL)\n#    define Z_U4 unsigned long\n#  elif (USHRT_MAX == 0xffffffffUL)\n#    define Z_U4 unsigned short\n#  endif\n#endif\n\n#ifdef Z_U4\n   typedef Z_U4 z_crc_t;\n#else\n   typedef unsigned long z_crc_t;\n#endif\n\n#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */\n#  define Z_HAVE_UNISTD_H\n#endif\n\n#ifdef HAVE_STDARG_H    /* may be set to #if 1 by ./configure */\n#  define Z_HAVE_STDARG_H\n#endif\n\n#ifdef STDC\n#  ifndef Z_SOLO\n#    include <sys/types.h>      /* for off_t */\n#  endif\n#endif\n\n#if defined(STDC) || defined(Z_HAVE_STDARG_H)\n#  ifndef Z_SOLO\n#    include <stdarg.h>         /* for va_list */\n#  endif\n#endif\n\n#ifdef _WIN32\n#  ifndef Z_SOLO\n#    include <stddef.h>         /* for wchar_t */\n#  endif\n#endif\n\n/* a little trick to accommodate both \"#define _LARGEFILE64_SOURCE\" and\n * \"#define _LARGEFILE64_SOURCE 1\" as requesting 64-bit operations, (even\n * though the former does not conform to the LFS document), but considering\n * both \"#undef _LARGEFILE64_SOURCE\" and \"#define _LARGEFILE64_SOURCE 0\" as\n * equivalently requesting no 64-bit operations\n */\n#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1\n#  undef _LARGEFILE64_SOURCE\n#endif\n\n#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)\n#  define Z_HAVE_UNISTD_H\n#endif\n#ifndef Z_SOLO\n#  if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)\n#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */\n#    ifdef VMS\n#      include <unixio.h>       /* for off_t */\n#    endif\n#    ifndef z_off_t\n#      define z_off_t off_t\n#    endif\n#  endif\n#endif\n\n#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0\n#  define Z_LFS64\n#endif\n\n#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)\n#  define Z_LARGE64\n#endif\n\n#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)\n#  define Z_WANT64\n#endif\n\n#if !defined(SEEK_SET) && !defined(Z_SOLO)\n#  define SEEK_SET        0       /* Seek from beginning of file.  */\n#  define SEEK_CUR        1       /* Seek from current position.  */\n#  define SEEK_END        2       /* Set file pointer to EOF plus \"offset\" */\n#endif\n\n#ifndef z_off_t\n#  define z_off_t long\n#endif\n\n#if !defined(_WIN32) && defined(Z_LARGE64)\n#  define z_off64_t off64_t\n#else\n#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)\n#    define z_off64_t __int64\n#  else\n#    define z_off64_t z_off_t\n#  endif\n#endif\n\n/* MVS linker does not support external names larger than 8 bytes */\n#if defined(__MVS__)\n  #pragma map(deflateInit_,\"DEIN\")\n  #pragma map(deflateInit2_,\"DEIN2\")\n  #pragma map(deflateEnd,\"DEEND\")\n  #pragma map(deflateBound,\"DEBND\")\n  #pragma map(inflateInit_,\"ININ\")\n  #pragma map(inflateInit2_,\"ININ2\")\n  #pragma map(inflateEnd,\"INEND\")\n  #pragma map(inflateSync,\"INSY\")\n  #pragma map(inflateSetDictionary,\"INSEDI\")\n  #pragma map(compressBound,\"CMBND\")\n  #pragma map(inflate_table,\"INTABL\")\n  #pragma map(inflate_fast,\"INFA\")\n  #pragma map(inflate_copyright,\"INCOPY\")\n#endif\n\n#endif /* ZCONF_H */\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/zconf.h.in",
    "content": "/* zconf.h -- configuration of the zlib compression library\n * Copyright (C) 1995-2013 Jean-loup Gailly.\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* @(#) $Id$ */\n\n#ifndef ZCONF_H\n#define ZCONF_H\n\n/*\n * If you *really* need a unique prefix for all types and library functions,\n * compile with -DZ_PREFIX. The \"standard\" zlib should be compiled without it.\n * Even better than compiling with -DZ_PREFIX would be to use configure to set\n * this permanently in zconf.h using \"./configure --zprefix\".\n */\n#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */\n#  define Z_PREFIX_SET\n\n/* all linked symbols */\n#  define _dist_code            z__dist_code\n#  define _length_code          z__length_code\n#  define _tr_align             z__tr_align\n#  define _tr_flush_bits        z__tr_flush_bits\n#  define _tr_flush_block       z__tr_flush_block\n#  define _tr_init              z__tr_init\n#  define _tr_stored_block      z__tr_stored_block\n#  define _tr_tally             z__tr_tally\n#  define adler32               z_adler32\n#  define adler32_combine       z_adler32_combine\n#  define adler32_combine64     z_adler32_combine64\n#  ifndef Z_SOLO\n#    define compress              z_compress\n#    define compress2             z_compress2\n#    define compressBound         z_compressBound\n#  endif\n#  define crc32                 z_crc32\n#  define crc32_combine         z_crc32_combine\n#  define crc32_combine64       z_crc32_combine64\n#  define deflate               z_deflate\n#  define deflateBound          z_deflateBound\n#  define deflateCopy           z_deflateCopy\n#  define deflateEnd            z_deflateEnd\n#  define deflateInit2_         z_deflateInit2_\n#  define deflateInit_          z_deflateInit_\n#  define deflateParams         z_deflateParams\n#  define deflatePending        z_deflatePending\n#  define deflatePrime          z_deflatePrime\n#  define deflateReset          z_deflateReset\n#  define deflateResetKeep      z_deflateResetKeep\n#  define deflateSetDictionary  z_deflateSetDictionary\n#  define deflateSetHeader      z_deflateSetHeader\n#  define deflateTune           z_deflateTune\n#  define deflate_copyright     z_deflate_copyright\n#  define get_crc_table         z_get_crc_table\n#  ifndef Z_SOLO\n#    define gz_error              z_gz_error\n#    define gz_intmax             z_gz_intmax\n#    define gz_strwinerror        z_gz_strwinerror\n#    define gzbuffer              z_gzbuffer\n#    define gzclearerr            z_gzclearerr\n#    define gzclose               z_gzclose\n#    define gzclose_r             z_gzclose_r\n#    define gzclose_w             z_gzclose_w\n#    define gzdirect              z_gzdirect\n#    define gzdopen               z_gzdopen\n#    define gzeof                 z_gzeof\n#    define gzerror               z_gzerror\n#    define gzflush               z_gzflush\n#    define gzgetc                z_gzgetc\n#    define gzgetc_               z_gzgetc_\n#    define gzgets                z_gzgets\n#    define gzoffset              z_gzoffset\n#    define gzoffset64            z_gzoffset64\n#    define gzopen                z_gzopen\n#    define gzopen64              z_gzopen64\n#    ifdef _WIN32\n#      define gzopen_w              z_gzopen_w\n#    endif\n#    define gzprintf              z_gzprintf\n#    define gzvprintf             z_gzvprintf\n#    define gzputc                z_gzputc\n#    define gzputs                z_gzputs\n#    define gzread                z_gzread\n#    define gzrewind              z_gzrewind\n#    define gzseek                z_gzseek\n#    define gzseek64              z_gzseek64\n#    define gzsetparams           z_gzsetparams\n#    define gztell                z_gztell\n#    define gztell64              z_gztell64\n#    define gzungetc              z_gzungetc\n#    define gzwrite               z_gzwrite\n#  endif\n#  define inflate               z_inflate\n#  define inflateBack           z_inflateBack\n#  define inflateBackEnd        z_inflateBackEnd\n#  define inflateBackInit_      z_inflateBackInit_\n#  define inflateCopy           z_inflateCopy\n#  define inflateEnd            z_inflateEnd\n#  define inflateGetHeader      z_inflateGetHeader\n#  define inflateInit2_         z_inflateInit2_\n#  define inflateInit_          z_inflateInit_\n#  define inflateMark           z_inflateMark\n#  define inflatePrime          z_inflatePrime\n#  define inflateReset          z_inflateReset\n#  define inflateReset2         z_inflateReset2\n#  define inflateSetDictionary  z_inflateSetDictionary\n#  define inflateGetDictionary  z_inflateGetDictionary\n#  define inflateSync           z_inflateSync\n#  define inflateSyncPoint      z_inflateSyncPoint\n#  define inflateUndermine      z_inflateUndermine\n#  define inflateResetKeep      z_inflateResetKeep\n#  define inflate_copyright     z_inflate_copyright\n#  define inflate_fast          z_inflate_fast\n#  define inflate_table         z_inflate_table\n#  ifndef Z_SOLO\n#    define uncompress            z_uncompress\n#  endif\n#  define zError                z_zError\n#  ifndef Z_SOLO\n#    define zcalloc               z_zcalloc\n#    define zcfree                z_zcfree\n#  endif\n#  define zlibCompileFlags      z_zlibCompileFlags\n#  define zlibVersion           z_zlibVersion\n\n/* all zlib typedefs in zlib.h and zconf.h */\n#  define Byte                  z_Byte\n#  define Bytef                 z_Bytef\n#  define alloc_func            z_alloc_func\n#  define charf                 z_charf\n#  define free_func             z_free_func\n#  ifndef Z_SOLO\n#    define gzFile                z_gzFile\n#  endif\n#  define gz_header             z_gz_header\n#  define gz_headerp            z_gz_headerp\n#  define in_func               z_in_func\n#  define intf                  z_intf\n#  define out_func              z_out_func\n#  define uInt                  z_uInt\n#  define uIntf                 z_uIntf\n#  define uLong                 z_uLong\n#  define uLongf                z_uLongf\n#  define voidp                 z_voidp\n#  define voidpc                z_voidpc\n#  define voidpf                z_voidpf\n\n/* all zlib structs in zlib.h and zconf.h */\n#  define gz_header_s           z_gz_header_s\n#  define internal_state        z_internal_state\n\n#endif\n\n#if defined(__MSDOS__) && !defined(MSDOS)\n#  define MSDOS\n#endif\n#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)\n#  define OS2\n#endif\n#if defined(_WINDOWS) && !defined(WINDOWS)\n#  define WINDOWS\n#endif\n#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)\n#  ifndef WIN32\n#    define WIN32\n#  endif\n#endif\n#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)\n#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)\n#    ifndef SYS16BIT\n#      define SYS16BIT\n#    endif\n#  endif\n#endif\n\n/*\n * Compile with -DMAXSEG_64K if the alloc function cannot allocate more\n * than 64k bytes at a time (needed on systems with 16-bit int).\n */\n#ifdef SYS16BIT\n#  define MAXSEG_64K\n#endif\n#ifdef MSDOS\n#  define UNALIGNED_OK\n#endif\n\n#ifdef __STDC_VERSION__\n#  ifndef STDC\n#    define STDC\n#  endif\n#  if __STDC_VERSION__ >= 199901L\n#    ifndef STDC99\n#      define STDC99\n#    endif\n#  endif\n#endif\n#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))\n#  define STDC\n#endif\n#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))\n#  define STDC\n#endif\n#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))\n#  define STDC\n#endif\n#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))\n#  define STDC\n#endif\n\n#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */\n#  define STDC\n#endif\n\n#ifndef STDC\n#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */\n#    define const       /* note: need a more gentle solution here */\n#  endif\n#endif\n\n#if defined(ZLIB_CONST) && !defined(z_const)\n#  define z_const const\n#else\n#  define z_const\n#endif\n\n/* Some Mac compilers merge all .h files incorrectly: */\n#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)\n#  define NO_DUMMY_DECL\n#endif\n\n/* Maximum value for memLevel in deflateInit2 */\n#ifndef MAX_MEM_LEVEL\n#  ifdef MAXSEG_64K\n#    define MAX_MEM_LEVEL 8\n#  else\n#    define MAX_MEM_LEVEL 9\n#  endif\n#endif\n\n/* Maximum value for windowBits in deflateInit2 and inflateInit2.\n * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files\n * created by gzip. (Files created by minigzip can still be extracted by\n * gzip.)\n */\n#ifndef MAX_WBITS\n#  define MAX_WBITS   15 /* 32K LZ77 window */\n#endif\n\n/* The memory requirements for deflate are (in bytes):\n            (1 << (windowBits+2)) +  (1 << (memLevel+9))\n that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)\n plus a few kilobytes for small objects. For example, if you want to reduce\n the default memory requirements from 256K to 128K, compile with\n     make CFLAGS=\"-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7\"\n Of course this will generally degrade compression (there's no free lunch).\n\n   The memory requirements for inflate are (in bytes) 1 << windowBits\n that is, 32K for windowBits=15 (default value) plus a few kilobytes\n for small objects.\n*/\n\n                        /* Type declarations */\n\n#ifndef OF /* function prototypes */\n#  ifdef STDC\n#    define OF(args)  args\n#  else\n#    define OF(args)  ()\n#  endif\n#endif\n\n#ifndef Z_ARG /* function prototypes for stdarg */\n#  if defined(STDC) || defined(Z_HAVE_STDARG_H)\n#    define Z_ARG(args)  args\n#  else\n#    define Z_ARG(args)  ()\n#  endif\n#endif\n\n/* The following definitions for FAR are needed only for MSDOS mixed\n * model programming (small or medium model with some far allocations).\n * This was tested only with MSC; for other MSDOS compilers you may have\n * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,\n * just define FAR to be empty.\n */\n#ifdef SYS16BIT\n#  if defined(M_I86SM) || defined(M_I86MM)\n     /* MSC small or medium model */\n#    define SMALL_MEDIUM\n#    ifdef _MSC_VER\n#      define FAR _far\n#    else\n#      define FAR far\n#    endif\n#  endif\n#  if (defined(__SMALL__) || defined(__MEDIUM__))\n     /* Turbo C small or medium model */\n#    define SMALL_MEDIUM\n#    ifdef __BORLANDC__\n#      define FAR _far\n#    else\n#      define FAR far\n#    endif\n#  endif\n#endif\n\n#if defined(WINDOWS) || defined(WIN32)\n   /* If building or using zlib as a DLL, define ZLIB_DLL.\n    * This is not mandatory, but it offers a little performance increase.\n    */\n#  ifdef ZLIB_DLL\n#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))\n#      ifdef ZLIB_INTERNAL\n#        define ZEXTERN extern __declspec(dllexport)\n#      else\n#        define ZEXTERN extern __declspec(dllimport)\n#      endif\n#    endif\n#  endif  /* ZLIB_DLL */\n   /* If building or using zlib with the WINAPI/WINAPIV calling convention,\n    * define ZLIB_WINAPI.\n    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.\n    */\n#  ifdef ZLIB_WINAPI\n#    ifdef FAR\n#      undef FAR\n#    endif\n#    include <windows.h>\n     /* No need for _export, use ZLIB.DEF instead. */\n     /* For complete Windows compatibility, use WINAPI, not __stdcall. */\n#    define ZEXPORT WINAPI\n#    ifdef WIN32\n#      define ZEXPORTVA WINAPIV\n#    else\n#      define ZEXPORTVA FAR CDECL\n#    endif\n#  endif\n#endif\n\n#if defined (__BEOS__)\n#  ifdef ZLIB_DLL\n#    ifdef ZLIB_INTERNAL\n#      define ZEXPORT   __declspec(dllexport)\n#      define ZEXPORTVA __declspec(dllexport)\n#    else\n#      define ZEXPORT   __declspec(dllimport)\n#      define ZEXPORTVA __declspec(dllimport)\n#    endif\n#  endif\n#endif\n\n#ifndef ZEXTERN\n#  define ZEXTERN extern\n#endif\n#ifndef ZEXPORT\n#  define ZEXPORT\n#endif\n#ifndef ZEXPORTVA\n#  define ZEXPORTVA\n#endif\n\n#ifndef FAR\n#  define FAR\n#endif\n\n#if !defined(__MACTYPES__)\ntypedef unsigned char  Byte;  /* 8 bits */\n#endif\ntypedef unsigned int   uInt;  /* 16 bits or more */\ntypedef unsigned long  uLong; /* 32 bits or more */\n\n#ifdef SMALL_MEDIUM\n   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */\n#  define Bytef Byte FAR\n#else\n   typedef Byte  FAR Bytef;\n#endif\ntypedef char  FAR charf;\ntypedef int   FAR intf;\ntypedef uInt  FAR uIntf;\ntypedef uLong FAR uLongf;\n\n#ifdef STDC\n   typedef void const *voidpc;\n   typedef void FAR   *voidpf;\n   typedef void       *voidp;\n#else\n   typedef Byte const *voidpc;\n   typedef Byte FAR   *voidpf;\n   typedef Byte       *voidp;\n#endif\n\n#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)\n#  include <limits.h>\n#  if (UINT_MAX == 0xffffffffUL)\n#    define Z_U4 unsigned\n#  elif (ULONG_MAX == 0xffffffffUL)\n#    define Z_U4 unsigned long\n#  elif (USHRT_MAX == 0xffffffffUL)\n#    define Z_U4 unsigned short\n#  endif\n#endif\n\n#ifdef Z_U4\n   typedef Z_U4 z_crc_t;\n#else\n   typedef unsigned long z_crc_t;\n#endif\n\n#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */\n#  define Z_HAVE_UNISTD_H\n#endif\n\n#ifdef HAVE_STDARG_H    /* may be set to #if 1 by ./configure */\n#  define Z_HAVE_STDARG_H\n#endif\n\n#ifdef STDC\n#  ifndef Z_SOLO\n#    include <sys/types.h>      /* for off_t */\n#  endif\n#endif\n\n#if defined(STDC) || defined(Z_HAVE_STDARG_H)\n#  ifndef Z_SOLO\n#    include <stdarg.h>         /* for va_list */\n#  endif\n#endif\n\n#ifdef _WIN32\n#  ifndef Z_SOLO\n#    include <stddef.h>         /* for wchar_t */\n#  endif\n#endif\n\n/* a little trick to accommodate both \"#define _LARGEFILE64_SOURCE\" and\n * \"#define _LARGEFILE64_SOURCE 1\" as requesting 64-bit operations, (even\n * though the former does not conform to the LFS document), but considering\n * both \"#undef _LARGEFILE64_SOURCE\" and \"#define _LARGEFILE64_SOURCE 0\" as\n * equivalently requesting no 64-bit operations\n */\n#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1\n#  undef _LARGEFILE64_SOURCE\n#endif\n\n#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)\n#  define Z_HAVE_UNISTD_H\n#endif\n#ifndef Z_SOLO\n#  if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)\n#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */\n#    ifdef VMS\n#      include <unixio.h>       /* for off_t */\n#    endif\n#    ifndef z_off_t\n#      define z_off_t off_t\n#    endif\n#  endif\n#endif\n\n#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0\n#  define Z_LFS64\n#endif\n\n#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)\n#  define Z_LARGE64\n#endif\n\n#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)\n#  define Z_WANT64\n#endif\n\n#if !defined(SEEK_SET) && !defined(Z_SOLO)\n#  define SEEK_SET        0       /* Seek from beginning of file.  */\n#  define SEEK_CUR        1       /* Seek from current position.  */\n#  define SEEK_END        2       /* Set file pointer to EOF plus \"offset\" */\n#endif\n\n#ifndef z_off_t\n#  define z_off_t long\n#endif\n\n#if !defined(_WIN32) && defined(Z_LARGE64)\n#  define z_off64_t off64_t\n#else\n#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)\n#    define z_off64_t __int64\n#  else\n#    define z_off64_t z_off_t\n#  endif\n#endif\n\n/* MVS linker does not support external names larger than 8 bytes */\n#if defined(__MVS__)\n  #pragma map(deflateInit_,\"DEIN\")\n  #pragma map(deflateInit2_,\"DEIN2\")\n  #pragma map(deflateEnd,\"DEEND\")\n  #pragma map(deflateBound,\"DEBND\")\n  #pragma map(inflateInit_,\"ININ\")\n  #pragma map(inflateInit2_,\"ININ2\")\n  #pragma map(inflateEnd,\"INEND\")\n  #pragma map(inflateSync,\"INSY\")\n  #pragma map(inflateSetDictionary,\"INSEDI\")\n  #pragma map(compressBound,\"CMBND\")\n  #pragma map(inflate_table,\"INTABL\")\n  #pragma map(inflate_fast,\"INFA\")\n  #pragma map(inflate_copyright,\"INCOPY\")\n#endif\n\n#endif /* ZCONF_H */\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/zlib.3",
    "content": ".TH ZLIB 3 \"28 Apr 2013\"\n.SH NAME\nzlib \\- compression/decompression library\n.SH SYNOPSIS\n[see\n.I zlib.h\nfor full description]\n.SH DESCRIPTION\nThe\n.I zlib\nlibrary is a general purpose data compression library.\nThe code is thread safe, assuming that the standard library functions\nused are thread safe, such as memory allocation routines.\nIt provides in-memory compression and decompression functions,\nincluding integrity checks of the uncompressed data.\nThis version of the library supports only one compression method (deflation)\nbut other algorithms may be added later\nwith the same stream interface.\n.LP\nCompression can be done in a single step if the buffers are large enough\nor can be done by repeated calls of the compression function.\nIn the latter case,\nthe application must provide more input and/or consume the output\n(providing more output space) before each call.\n.LP\nThe library also supports reading and writing files in\n.IR gzip (1)\n(.gz) format\nwith an interface similar to that of stdio.\n.LP\nThe library does not install any signal handler.\nThe decoder checks the consistency of the compressed data,\nso the library should never crash even in the case of corrupted input.\n.LP\nAll functions of the compression library are documented in the file\n.IR zlib.h .\nThe distribution source includes examples of use of the library\nin the files\n.I test/example.c\nand\n.IR test/minigzip.c,\nas well as other examples in the\n.IR examples/\ndirectory.\n.LP\nChanges to this version are documented in the file\n.I ChangeLog\nthat accompanies the source.\n.LP\n.I zlib\nis available in Java using the java.util.zip package:\n.IP\nhttp://java.sun.com/developer/technicalArticles/Programming/compression/\n.LP\nA Perl interface to\n.IR zlib ,\nwritten by Paul Marquess (pmqs@cpan.org),\nis available at CPAN (Comprehensive Perl Archive Network) sites,\nincluding:\n.IP\nhttp://search.cpan.org/~pmqs/IO-Compress-Zlib/\n.LP\nA Python interface to\n.IR zlib ,\nwritten by A.M. Kuchling (amk@magnet.com),\nis available in Python 1.5 and later versions:\n.IP\nhttp://docs.python.org/library/zlib.html\n.LP\n.I zlib\nis built into\n.IR tcl:\n.IP\nhttp://wiki.tcl.tk/4610\n.LP\nAn experimental package to read and write files in .zip format,\nwritten on top of\n.I zlib\nby Gilles Vollant (info@winimage.com),\nis available at:\n.IP\nhttp://www.winimage.com/zLibDll/minizip.html\nand also in the\n.I contrib/minizip\ndirectory of the main\n.I zlib\nsource distribution.\n.SH \"SEE ALSO\"\nThe\n.I zlib\nweb site can be found at:\n.IP\nhttp://zlib.net/\n.LP\nThe data format used by the zlib library is described by RFC\n(Request for Comments) 1950 to 1952 in the files:\n.IP\nhttp://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format)\n.br\nhttp://tools.ietf.org/html/rfc1951 (for the deflate compressed data format)\n.br\nhttp://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format)\n.LP\nMark Nelson wrote an article about\n.I zlib\nfor the Jan. 1997 issue of  Dr. Dobb's Journal;\na copy of the article is available at:\n.IP\nhttp://marknelson.us/1997/01/01/zlib-engine/\n.SH \"REPORTING PROBLEMS\"\nBefore reporting a problem,\nplease check the\n.I zlib\nweb site to verify that you have the latest version of\n.IR zlib ;\notherwise,\nobtain the latest version and see if the problem still exists.\nPlease read the\n.I zlib\nFAQ at:\n.IP\nhttp://zlib.net/zlib_faq.html\n.LP\nbefore asking for help.\nSend questions and/or comments to zlib@gzip.org,\nor (for the Windows DLL version) to Gilles Vollant (info@winimage.com).\n.SH AUTHORS\nVersion 1.2.8\nCopyright (C) 1995-2013 Jean-loup Gailly (jloup@gzip.org)\nand Mark Adler (madler@alumni.caltech.edu).\n.LP\nThis software is provided \"as-is,\"\nwithout any express or implied warranty.\nIn no event will the authors be held liable for any damages\narising from the use of this software.\nSee the distribution directory with respect to requirements\ngoverning redistribution.\nThe deflate format used by\n.I zlib\nwas defined by Phil Katz.\nThe deflate and\n.I zlib\nspecifications were written by L. Peter Deutsch.\nThanks to all the people who reported problems and suggested various\nimprovements in\n.IR zlib ;\nwho are too numerous to cite here.\n.LP\nUNIX manual page by R. P. C. Rodgers,\nU.S. National Library of Medicine (rodgers@nlm.nih.gov).\n.\\\" end of man page\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/zlib.h",
    "content": "/* zlib.h -- interface of the 'zlib' general purpose compression library\n  version 1.2.8, April 28th, 2013\n\n  Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Jean-loup Gailly        Mark Adler\n  jloup@gzip.org          madler@alumni.caltech.edu\n\n\n  The data format used by the zlib library is described by RFCs (Request for\n  Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950\n  (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).\n*/\n\n#ifndef ZLIB_H\n#define ZLIB_H\n\n#include \"zconf.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define ZLIB_VERSION \"1.2.8\"\n#define ZLIB_VERNUM 0x1280\n#define ZLIB_VER_MAJOR 1\n#define ZLIB_VER_MINOR 2\n#define ZLIB_VER_REVISION 8\n#define ZLIB_VER_SUBREVISION 0\n\n/*\n    The 'zlib' compression library provides in-memory compression and\n  decompression functions, including integrity checks of the uncompressed data.\n  This version of the library supports only one compression method (deflation)\n  but other algorithms will be added later and will have the same stream\n  interface.\n\n    Compression can be done in a single step if the buffers are large enough,\n  or can be done by repeated calls of the compression function.  In the latter\n  case, the application must provide more input and/or consume the output\n  (providing more output space) before each call.\n\n    The compressed data format used by default by the in-memory functions is\n  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped\n  around a deflate stream, which is itself documented in RFC 1951.\n\n    The library also supports reading and writing files in gzip (.gz) format\n  with an interface similar to that of stdio using the functions that start\n  with \"gz\".  The gzip format is different from the zlib format.  gzip is a\n  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.\n\n    This library can optionally read and write gzip streams in memory as well.\n\n    The zlib format was designed to be compact and fast for use in memory\n  and on communications channels.  The gzip format was designed for single-\n  file compression on file systems, has a larger header than zlib to maintain\n  directory information, and uses a different, slower check method than zlib.\n\n    The library does not install any signal handler.  The decoder checks\n  the consistency of the compressed data, so the library should never crash\n  even in case of corrupted input.\n*/\n\ntypedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));\ntypedef void   (*free_func)  OF((voidpf opaque, voidpf address));\n\nstruct internal_state;\n\ntypedef struct z_stream_s {\n    z_const Bytef *next_in;     /* next input byte */\n    uInt     avail_in;  /* number of bytes available at next_in */\n    uLong    total_in;  /* total number of input bytes read so far */\n\n    Bytef    *next_out; /* next output byte should be put there */\n    uInt     avail_out; /* remaining free space at next_out */\n    uLong    total_out; /* total number of bytes output so far */\n\n    z_const char *msg;  /* last error message, NULL if no error */\n    struct internal_state FAR *state; /* not visible by applications */\n\n    alloc_func zalloc;  /* used to allocate the internal state */\n    free_func  zfree;   /* used to free the internal state */\n    voidpf     opaque;  /* private data object passed to zalloc and zfree */\n\n    int     data_type;  /* best guess about the data type: binary or text */\n    uLong   adler;      /* adler32 value of the uncompressed data */\n    uLong   reserved;   /* reserved for future use */\n} z_stream;\n\ntypedef z_stream FAR *z_streamp;\n\n/*\n     gzip header information passed to and from zlib routines.  See RFC 1952\n  for more details on the meanings of these fields.\n*/\ntypedef struct gz_header_s {\n    int     text;       /* true if compressed data believed to be text */\n    uLong   time;       /* modification time */\n    int     xflags;     /* extra flags (not used when writing a gzip file) */\n    int     os;         /* operating system */\n    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */\n    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */\n    uInt    extra_max;  /* space at extra (only when reading header) */\n    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */\n    uInt    name_max;   /* space at name (only when reading header) */\n    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */\n    uInt    comm_max;   /* space at comment (only when reading header) */\n    int     hcrc;       /* true if there was or will be a header crc */\n    int     done;       /* true when done reading gzip header (not used\n                           when writing a gzip file) */\n} gz_header;\n\ntypedef gz_header FAR *gz_headerp;\n\n/*\n     The application must update next_in and avail_in when avail_in has dropped\n   to zero.  It must update next_out and avail_out when avail_out has dropped\n   to zero.  The application must initialize zalloc, zfree and opaque before\n   calling the init function.  All other fields are set by the compression\n   library and must not be updated by the application.\n\n     The opaque value provided by the application will be passed as the first\n   parameter for calls of zalloc and zfree.  This can be useful for custom\n   memory management.  The compression library attaches no meaning to the\n   opaque value.\n\n     zalloc must return Z_NULL if there is not enough memory for the object.\n   If zlib is used in a multi-threaded application, zalloc and zfree must be\n   thread safe.\n\n     On 16-bit systems, the functions zalloc and zfree must be able to allocate\n   exactly 65536 bytes, but will not be required to allocate more than this if\n   the symbol MAXSEG_64K is defined (see zconf.h).  WARNING: On MSDOS, pointers\n   returned by zalloc for objects of exactly 65536 bytes *must* have their\n   offset normalized to zero.  The default allocation function provided by this\n   library ensures this (see zutil.c).  To reduce memory requirements and avoid\n   any allocation of 64K objects, at the expense of compression ratio, compile\n   the library with -DMAX_WBITS=14 (see zconf.h).\n\n     The fields total_in and total_out can be used for statistics or progress\n   reports.  After compression, total_in holds the total size of the\n   uncompressed data and may be saved for use in the decompressor (particularly\n   if the decompressor wants to decompress everything in a single step).\n*/\n\n                        /* constants */\n\n#define Z_NO_FLUSH      0\n#define Z_PARTIAL_FLUSH 1\n#define Z_SYNC_FLUSH    2\n#define Z_FULL_FLUSH    3\n#define Z_FINISH        4\n#define Z_BLOCK         5\n#define Z_TREES         6\n/* Allowed flush values; see deflate() and inflate() below for details */\n\n#define Z_OK            0\n#define Z_STREAM_END    1\n#define Z_NEED_DICT     2\n#define Z_ERRNO        (-1)\n#define Z_STREAM_ERROR (-2)\n#define Z_DATA_ERROR   (-3)\n#define Z_MEM_ERROR    (-4)\n#define Z_BUF_ERROR    (-5)\n#define Z_VERSION_ERROR (-6)\n/* Return codes for the compression/decompression functions. Negative values\n * are errors, positive values are used for special but normal events.\n */\n\n#define Z_NO_COMPRESSION         0\n#define Z_BEST_SPEED             1\n#define Z_BEST_COMPRESSION       9\n#define Z_DEFAULT_COMPRESSION  (-1)\n/* compression levels */\n\n#define Z_FILTERED            1\n#define Z_HUFFMAN_ONLY        2\n#define Z_RLE                 3\n#define Z_FIXED               4\n#define Z_DEFAULT_STRATEGY    0\n/* compression strategy; see deflateInit2() below for details */\n\n#define Z_BINARY   0\n#define Z_TEXT     1\n#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */\n#define Z_UNKNOWN  2\n/* Possible values of the data_type field (though see inflate()) */\n\n#define Z_DEFLATED   8\n/* The deflate compression method (the only one supported in this version) */\n\n#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */\n\n#define zlib_version zlibVersion()\n/* for compatibility with versions < 1.0.2 */\n\n\n                        /* basic functions */\n\nZEXTERN const char * ZEXPORT zlibVersion OF((void));\n/* The application can compare zlibVersion and ZLIB_VERSION for consistency.\n   If the first character differs, the library code actually used is not\n   compatible with the zlib.h header file used by the application.  This check\n   is automatically made by deflateInit and inflateInit.\n */\n\n/*\nZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));\n\n     Initializes the internal stream state for compression.  The fields\n   zalloc, zfree and opaque must be initialized before by the caller.  If\n   zalloc and zfree are set to Z_NULL, deflateInit updates them to use default\n   allocation functions.\n\n     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:\n   1 gives best speed, 9 gives best compression, 0 gives no compression at all\n   (the input data is simply copied a block at a time).  Z_DEFAULT_COMPRESSION\n   requests a default compromise between speed and compression (currently\n   equivalent to level 6).\n\n     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_STREAM_ERROR if level is not a valid compression level, or\n   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible\n   with the version assumed by the caller (ZLIB_VERSION).  msg is set to null\n   if there is no error message.  deflateInit does not perform any compression:\n   this will be done by deflate().\n*/\n\n\nZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));\n/*\n    deflate compresses as much data as possible, and stops when the input\n  buffer becomes empty or the output buffer becomes full.  It may introduce\n  some output latency (reading input without producing any output) except when\n  forced to flush.\n\n    The detailed semantics are as follows.  deflate performs one or both of the\n  following actions:\n\n  - Compress more input starting at next_in and update next_in and avail_in\n    accordingly.  If not all input can be processed (because there is not\n    enough room in the output buffer), next_in and avail_in are updated and\n    processing will resume at this point for the next call of deflate().\n\n  - Provide more output starting at next_out and update next_out and avail_out\n    accordingly.  This action is forced if the parameter flush is non zero.\n    Forcing flush frequently degrades the compression ratio, so this parameter\n    should be set only when necessary (in interactive applications).  Some\n    output may be provided even if flush is not set.\n\n    Before the call of deflate(), the application should ensure that at least\n  one of the actions is possible, by providing more input and/or consuming more\n  output, and updating avail_in or avail_out accordingly; avail_out should\n  never be zero before the call.  The application can consume the compressed\n  output when it wants, for example when the output buffer is full (avail_out\n  == 0), or after each call of deflate().  If deflate returns Z_OK and with\n  zero avail_out, it must be called again after making room in the output\n  buffer because there might be more output pending.\n\n    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to\n  decide how much data to accumulate before producing output, in order to\n  maximize compression.\n\n    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is\n  flushed to the output buffer and the output is aligned on a byte boundary, so\n  that the decompressor can get all input data available so far.  (In\n  particular avail_in is zero after the call if enough output space has been\n  provided before the call.) Flushing may degrade compression for some\n  compression algorithms and so it should be used only when necessary.  This\n  completes the current deflate block and follows it with an empty stored block\n  that is three bits plus filler bits to the next byte, followed by four bytes\n  (00 00 ff ff).\n\n    If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the\n  output buffer, but the output is not aligned to a byte boundary.  All of the\n  input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.\n  This completes the current deflate block and follows it with an empty fixed\n  codes block that is 10 bits long.  This assures that enough bytes are output\n  in order for the decompressor to finish the block before the empty fixed code\n  block.\n\n    If flush is set to Z_BLOCK, a deflate block is completed and emitted, as\n  for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to\n  seven bits of the current block are held to be written as the next byte after\n  the next deflate block is completed.  In this case, the decompressor may not\n  be provided enough bits at this point in order to complete decompression of\n  the data provided so far to the compressor.  It may need to wait for the next\n  block to be emitted.  This is for advanced applications that need to control\n  the emission of deflate blocks.\n\n    If flush is set to Z_FULL_FLUSH, all output is flushed as with\n  Z_SYNC_FLUSH, and the compression state is reset so that decompression can\n  restart from this point if previous compressed data has been damaged or if\n  random access is desired.  Using Z_FULL_FLUSH too often can seriously degrade\n  compression.\n\n    If deflate returns with avail_out == 0, this function must be called again\n  with the same value of the flush parameter and more output space (updated\n  avail_out), until the flush is complete (deflate returns with non-zero\n  avail_out).  In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that\n  avail_out is greater than six to avoid repeated flush markers due to\n  avail_out == 0 on return.\n\n    If the parameter flush is set to Z_FINISH, pending input is processed,\n  pending output is flushed and deflate returns with Z_STREAM_END if there was\n  enough output space; if deflate returns with Z_OK, this function must be\n  called again with Z_FINISH and more output space (updated avail_out) but no\n  more input data, until it returns with Z_STREAM_END or an error.  After\n  deflate has returned Z_STREAM_END, the only possible operations on the stream\n  are deflateReset or deflateEnd.\n\n    Z_FINISH can be used immediately after deflateInit if all the compression\n  is to be done in a single step.  In this case, avail_out must be at least the\n  value returned by deflateBound (see below).  Then deflate is guaranteed to\n  return Z_STREAM_END.  If not enough output space is provided, deflate will\n  not return Z_STREAM_END, and it must be called again as described above.\n\n    deflate() sets strm->adler to the adler32 checksum of all input read\n  so far (that is, total_in bytes).\n\n    deflate() may update strm->data_type if it can make a good guess about\n  the input data type (Z_BINARY or Z_TEXT).  In doubt, the data is considered\n  binary.  This field is only for information purposes and does not affect the\n  compression algorithm in any manner.\n\n    deflate() returns Z_OK if some progress has been made (more input\n  processed or more output produced), Z_STREAM_END if all input has been\n  consumed and all output has been produced (only when flush is set to\n  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example\n  if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible\n  (for example avail_in or avail_out was zero).  Note that Z_BUF_ERROR is not\n  fatal, and deflate() can be called again with more input and more output\n  space to continue compressing.\n*/\n\n\nZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));\n/*\n     All dynamically allocated data structures for this stream are freed.\n   This function discards any unprocessed input and does not flush any pending\n   output.\n\n     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the\n   stream state was inconsistent, Z_DATA_ERROR if the stream was freed\n   prematurely (some input or output was discarded).  In the error case, msg\n   may be set but then points to a static string (which must not be\n   deallocated).\n*/\n\n\n/*\nZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));\n\n     Initializes the internal stream state for decompression.  The fields\n   next_in, avail_in, zalloc, zfree and opaque must be initialized before by\n   the caller.  If next_in is not Z_NULL and avail_in is large enough (the\n   exact value depends on the compression method), inflateInit determines the\n   compression method from the zlib header and allocates all data structures\n   accordingly; otherwise the allocation will be deferred to the first call of\n   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to\n   use default allocation functions.\n\n     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the\n   version assumed by the caller, or Z_STREAM_ERROR if the parameters are\n   invalid, such as a null pointer to the structure.  msg is set to null if\n   there is no error message.  inflateInit does not perform any decompression\n   apart from possibly reading the zlib header if present: actual decompression\n   will be done by inflate().  (So next_in and avail_in may be modified, but\n   next_out and avail_out are unused and unchanged.) The current implementation\n   of inflateInit() does not process any header information -- that is deferred\n   until inflate() is called.\n*/\n\n\nZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));\n/*\n    inflate decompresses as much data as possible, and stops when the input\n  buffer becomes empty or the output buffer becomes full.  It may introduce\n  some output latency (reading input without producing any output) except when\n  forced to flush.\n\n  The detailed semantics are as follows.  inflate performs one or both of the\n  following actions:\n\n  - Decompress more input starting at next_in and update next_in and avail_in\n    accordingly.  If not all input can be processed (because there is not\n    enough room in the output buffer), next_in is updated and processing will\n    resume at this point for the next call of inflate().\n\n  - Provide more output starting at next_out and update next_out and avail_out\n    accordingly.  inflate() provides as much output as possible, until there is\n    no more input data or no more space in the output buffer (see below about\n    the flush parameter).\n\n    Before the call of inflate(), the application should ensure that at least\n  one of the actions is possible, by providing more input and/or consuming more\n  output, and updating the next_* and avail_* values accordingly.  The\n  application can consume the uncompressed output when it wants, for example\n  when the output buffer is full (avail_out == 0), or after each call of\n  inflate().  If inflate returns Z_OK and with zero avail_out, it must be\n  called again after making room in the output buffer because there might be\n  more output pending.\n\n    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,\n  Z_BLOCK, or Z_TREES.  Z_SYNC_FLUSH requests that inflate() flush as much\n  output as possible to the output buffer.  Z_BLOCK requests that inflate()\n  stop if and when it gets to the next deflate block boundary.  When decoding\n  the zlib or gzip format, this will cause inflate() to return immediately\n  after the header and before the first block.  When doing a raw inflate,\n  inflate() will go ahead and process the first block, and will return when it\n  gets to the end of that block, or when it runs out of data.\n\n    The Z_BLOCK option assists in appending to or combining deflate streams.\n  Also to assist in this, on return inflate() will set strm->data_type to the\n  number of unused bits in the last byte taken from strm->next_in, plus 64 if\n  inflate() is currently decoding the last block in the deflate stream, plus\n  128 if inflate() returned immediately after decoding an end-of-block code or\n  decoding the complete header up to just before the first byte of the deflate\n  stream.  The end-of-block will not be indicated until all of the uncompressed\n  data from that block has been written to strm->next_out.  The number of\n  unused bits may in general be greater than seven, except when bit 7 of\n  data_type is set, in which case the number of unused bits will be less than\n  eight.  data_type is set as noted here every time inflate() returns for all\n  flush options, and so can be used to determine the amount of currently\n  consumed input in bits.\n\n    The Z_TREES option behaves as Z_BLOCK does, but it also returns when the\n  end of each deflate block header is reached, before any actual data in that\n  block is decoded.  This allows the caller to determine the length of the\n  deflate block header for later use in random access within a deflate block.\n  256 is added to the value of strm->data_type when inflate() returns\n  immediately after reaching the end of the deflate block header.\n\n    inflate() should normally be called until it returns Z_STREAM_END or an\n  error.  However if all decompression is to be performed in a single step (a\n  single call of inflate), the parameter flush should be set to Z_FINISH.  In\n  this case all pending input is processed and all pending output is flushed;\n  avail_out must be large enough to hold all of the uncompressed data for the\n  operation to complete.  (The size of the uncompressed data may have been\n  saved by the compressor for this purpose.) The use of Z_FINISH is not\n  required to perform an inflation in one step.  However it may be used to\n  inform inflate that a faster approach can be used for the single inflate()\n  call.  Z_FINISH also informs inflate to not maintain a sliding window if the\n  stream completes, which reduces inflate's memory footprint.  If the stream\n  does not complete, either because not all of the stream is provided or not\n  enough output space is provided, then a sliding window will be allocated and\n  inflate() can be called again to continue the operation as if Z_NO_FLUSH had\n  been used.\n\n     In this implementation, inflate() always flushes as much output as\n  possible to the output buffer, and always uses the faster approach on the\n  first call.  So the effects of the flush parameter in this implementation are\n  on the return value of inflate() as noted below, when inflate() returns early\n  when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of\n  memory for a sliding window when Z_FINISH is used.\n\n     If a preset dictionary is needed after this call (see inflateSetDictionary\n  below), inflate sets strm->adler to the Adler-32 checksum of the dictionary\n  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets\n  strm->adler to the Adler-32 checksum of all output produced so far (that is,\n  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described\n  below.  At the end of the stream, inflate() checks that its computed adler32\n  checksum is equal to that saved by the compressor and returns Z_STREAM_END\n  only if the checksum is correct.\n\n    inflate() can decompress and check either zlib-wrapped or gzip-wrapped\n  deflate data.  The header type is detected automatically, if requested when\n  initializing with inflateInit2().  Any information contained in the gzip\n  header is not retained, so applications that need that information should\n  instead use raw inflate, see inflateInit2() below, or inflateBack() and\n  perform their own processing of the gzip header and trailer.  When processing\n  gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output\n  producted so far.  The CRC-32 is checked against the gzip trailer.\n\n    inflate() returns Z_OK if some progress has been made (more input processed\n  or more output produced), Z_STREAM_END if the end of the compressed data has\n  been reached and all uncompressed output has been produced, Z_NEED_DICT if a\n  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was\n  corrupted (input stream not conforming to the zlib format or incorrect check\n  value), Z_STREAM_ERROR if the stream structure was inconsistent (for example\n  next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,\n  Z_BUF_ERROR if no progress is possible or if there was not enough room in the\n  output buffer when Z_FINISH is used.  Note that Z_BUF_ERROR is not fatal, and\n  inflate() can be called again with more input and more output space to\n  continue decompressing.  If Z_DATA_ERROR is returned, the application may\n  then call inflateSync() to look for a good compression block if a partial\n  recovery of the data is desired.\n*/\n\n\nZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));\n/*\n     All dynamically allocated data structures for this stream are freed.\n   This function discards any unprocessed input and does not flush any pending\n   output.\n\n     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state\n   was inconsistent.  In the error case, msg may be set but then points to a\n   static string (which must not be deallocated).\n*/\n\n\n                        /* Advanced functions */\n\n/*\n    The following functions are needed only in some special applications.\n*/\n\n/*\nZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,\n                                     int  level,\n                                     int  method,\n                                     int  windowBits,\n                                     int  memLevel,\n                                     int  strategy));\n\n     This is another version of deflateInit with more compression options.  The\n   fields next_in, zalloc, zfree and opaque must be initialized before by the\n   caller.\n\n     The method parameter is the compression method.  It must be Z_DEFLATED in\n   this version of the library.\n\n     The windowBits parameter is the base two logarithm of the window size\n   (the size of the history buffer).  It should be in the range 8..15 for this\n   version of the library.  Larger values of this parameter result in better\n   compression at the expense of memory usage.  The default value is 15 if\n   deflateInit is used instead.\n\n     windowBits can also be -8..-15 for raw deflate.  In this case, -windowBits\n   determines the window size.  deflate() will then generate raw deflate data\n   with no zlib header or trailer, and will not compute an adler32 check value.\n\n     windowBits can also be greater than 15 for optional gzip encoding.  Add\n   16 to windowBits to write a simple gzip header and trailer around the\n   compressed data instead of a zlib wrapper.  The gzip header will have no\n   file name, no extra data, no comment, no modification time (set to zero), no\n   header crc, and the operating system will be set to 255 (unknown).  If a\n   gzip stream is being written, strm->adler is a crc32 instead of an adler32.\n\n     The memLevel parameter specifies how much memory should be allocated\n   for the internal compression state.  memLevel=1 uses minimum memory but is\n   slow and reduces compression ratio; memLevel=9 uses maximum memory for\n   optimal speed.  The default value is 8.  See zconf.h for total memory usage\n   as a function of windowBits and memLevel.\n\n     The strategy parameter is used to tune the compression algorithm.  Use the\n   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a\n   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no\n   string match), or Z_RLE to limit match distances to one (run-length\n   encoding).  Filtered data consists mostly of small values with a somewhat\n   random distribution.  In this case, the compression algorithm is tuned to\n   compress them better.  The effect of Z_FILTERED is to force more Huffman\n   coding and less string matching; it is somewhat intermediate between\n   Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY.  Z_RLE is designed to be almost as\n   fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data.  The\n   strategy parameter only affects the compression ratio but not the\n   correctness of the compressed output even if it is not set appropriately.\n   Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler\n   decoder for special applications.\n\n     deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid\n   method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is\n   incompatible with the version assumed by the caller (ZLIB_VERSION).  msg is\n   set to null if there is no error message.  deflateInit2 does not perform any\n   compression: this will be done by deflate().\n*/\n\nZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,\n                                             const Bytef *dictionary,\n                                             uInt  dictLength));\n/*\n     Initializes the compression dictionary from the given byte sequence\n   without producing any compressed output.  When using the zlib format, this\n   function must be called immediately after deflateInit, deflateInit2 or\n   deflateReset, and before any call of deflate.  When doing raw deflate, this\n   function must be called either before any call of deflate, or immediately\n   after the completion of a deflate block, i.e. after all input has been\n   consumed and all output has been delivered when using any of the flush\n   options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH.  The\n   compressor and decompressor must use exactly the same dictionary (see\n   inflateSetDictionary).\n\n     The dictionary should consist of strings (byte sequences) that are likely\n   to be encountered later in the data to be compressed, with the most commonly\n   used strings preferably put towards the end of the dictionary.  Using a\n   dictionary is most useful when the data to be compressed is short and can be\n   predicted with good accuracy; the data can then be compressed better than\n   with the default empty dictionary.\n\n     Depending on the size of the compression data structures selected by\n   deflateInit or deflateInit2, a part of the dictionary may in effect be\n   discarded, for example if the dictionary is larger than the window size\n   provided in deflateInit or deflateInit2.  Thus the strings most likely to be\n   useful should be put at the end of the dictionary, not at the front.  In\n   addition, the current implementation of deflate will use at most the window\n   size minus 262 bytes of the provided dictionary.\n\n     Upon return of this function, strm->adler is set to the adler32 value\n   of the dictionary; the decompressor may later use this value to determine\n   which dictionary has been used by the compressor.  (The adler32 value\n   applies to the whole dictionary even if only a subset of the dictionary is\n   actually used by the compressor.) If a raw deflate was requested, then the\n   adler32 value is not computed and strm->adler is not set.\n\n     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a\n   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is\n   inconsistent (for example if deflate has already been called for this stream\n   or if not at a block boundary for raw deflate).  deflateSetDictionary does\n   not perform any compression: this will be done by deflate().\n*/\n\nZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,\n                                    z_streamp source));\n/*\n     Sets the destination stream as a complete copy of the source stream.\n\n     This function can be useful when several compression strategies will be\n   tried, for example when there are several ways of pre-processing the input\n   data with a filter.  The streams that will be discarded should then be freed\n   by calling deflateEnd.  Note that deflateCopy duplicates the internal\n   compression state which can be quite large, so this strategy is slow and can\n   consume lots of memory.\n\n     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent\n   (such as zalloc being Z_NULL).  msg is left unchanged in both source and\n   destination.\n*/\n\nZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));\n/*\n     This function is equivalent to deflateEnd followed by deflateInit,\n   but does not free and reallocate all the internal compression state.  The\n   stream will keep the same compression level and any other attributes that\n   may have been set by deflateInit2.\n\n     deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent (such as zalloc or state being Z_NULL).\n*/\n\nZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,\n                                      int level,\n                                      int strategy));\n/*\n     Dynamically update the compression level and compression strategy.  The\n   interpretation of level and strategy is as in deflateInit2.  This can be\n   used to switch between compression and straight copy of the input data, or\n   to switch to a different kind of input data requiring a different strategy.\n   If the compression level is changed, the input available so far is\n   compressed with the old level (and may be flushed); the new level will take\n   effect only at the next call of deflate().\n\n     Before the call of deflateParams, the stream state must be set as for\n   a call of deflate(), since the currently available input may have to be\n   compressed and flushed.  In particular, strm->avail_out must be non-zero.\n\n     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source\n   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if\n   strm->avail_out was zero.\n*/\n\nZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,\n                                    int good_length,\n                                    int max_lazy,\n                                    int nice_length,\n                                    int max_chain));\n/*\n     Fine tune deflate's internal compression parameters.  This should only be\n   used by someone who understands the algorithm used by zlib's deflate for\n   searching for the best matching string, and even then only by the most\n   fanatic optimizer trying to squeeze out the last compressed bit for their\n   specific input data.  Read the deflate.c source code for the meaning of the\n   max_lazy, good_length, nice_length, and max_chain parameters.\n\n     deflateTune() can be called after deflateInit() or deflateInit2(), and\n   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.\n */\n\nZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,\n                                       uLong sourceLen));\n/*\n     deflateBound() returns an upper bound on the compressed size after\n   deflation of sourceLen bytes.  It must be called after deflateInit() or\n   deflateInit2(), and after deflateSetHeader(), if used.  This would be used\n   to allocate an output buffer for deflation in a single pass, and so would be\n   called before deflate().  If that first deflate() call is provided the\n   sourceLen input bytes, an output buffer allocated to the size returned by\n   deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed\n   to return Z_STREAM_END.  Note that it is possible for the compressed size to\n   be larger than the value returned by deflateBound() if flush options other\n   than Z_FINISH or Z_NO_FLUSH are used.\n*/\n\nZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,\n                                       unsigned *pending,\n                                       int *bits));\n/*\n     deflatePending() returns the number of bytes and bits of output that have\n   been generated, but not yet provided in the available output.  The bytes not\n   provided would be due to the available output space having being consumed.\n   The number of bits of output not provided are between 0 and 7, where they\n   await more bits to join them in order to fill out a full byte.  If pending\n   or bits are Z_NULL, then those values are not set.\n\n     deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent.\n */\n\nZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,\n                                     int bits,\n                                     int value));\n/*\n     deflatePrime() inserts bits in the deflate output stream.  The intent\n   is that this function is used to start off the deflate output with the bits\n   leftover from a previous deflate stream when appending to it.  As such, this\n   function can only be used for raw deflate, and must be used before the first\n   deflate() call after a deflateInit2() or deflateReset().  bits must be less\n   than or equal to 16, and that many of the least significant bits of value\n   will be inserted in the output.\n\n     deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough\n   room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the\n   source stream state was inconsistent.\n*/\n\nZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,\n                                         gz_headerp head));\n/*\n     deflateSetHeader() provides gzip header information for when a gzip\n   stream is requested by deflateInit2().  deflateSetHeader() may be called\n   after deflateInit2() or deflateReset() and before the first call of\n   deflate().  The text, time, os, extra field, name, and comment information\n   in the provided gz_header structure are written to the gzip header (xflag is\n   ignored -- the extra flags are set according to the compression level).  The\n   caller must assure that, if not Z_NULL, name and comment are terminated with\n   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are\n   available there.  If hcrc is true, a gzip header crc is included.  Note that\n   the current versions of the command-line version of gzip (up through version\n   1.3.x) do not support header crc's, and will report that it is a \"multi-part\n   gzip file\" and give up.\n\n     If deflateSetHeader is not used, the default gzip header has text false,\n   the time set to zero, and os set to 255, with no extra, name, or comment\n   fields.  The gzip header is returned to the default state by deflateReset().\n\n     deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent.\n*/\n\n/*\nZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,\n                                     int  windowBits));\n\n     This is another version of inflateInit with an extra parameter.  The\n   fields next_in, avail_in, zalloc, zfree and opaque must be initialized\n   before by the caller.\n\n     The windowBits parameter is the base two logarithm of the maximum window\n   size (the size of the history buffer).  It should be in the range 8..15 for\n   this version of the library.  The default value is 15 if inflateInit is used\n   instead.  windowBits must be greater than or equal to the windowBits value\n   provided to deflateInit2() while compressing, or it must be equal to 15 if\n   deflateInit2() was not used.  If a compressed stream with a larger window\n   size is given as input, inflate() will return with the error code\n   Z_DATA_ERROR instead of trying to allocate a larger window.\n\n     windowBits can also be zero to request that inflate use the window size in\n   the zlib header of the compressed stream.\n\n     windowBits can also be -8..-15 for raw inflate.  In this case, -windowBits\n   determines the window size.  inflate() will then process raw deflate data,\n   not looking for a zlib or gzip header, not generating a check value, and not\n   looking for any check values for comparison at the end of the stream.  This\n   is for use with other formats that use the deflate compressed data format\n   such as zip.  Those formats provide their own check values.  If a custom\n   format is developed using the raw deflate format for compressed data, it is\n   recommended that a check value such as an adler32 or a crc32 be applied to\n   the uncompressed data as is done in the zlib, gzip, and zip formats.  For\n   most applications, the zlib format should be used as is.  Note that comments\n   above on the use in deflateInit2() applies to the magnitude of windowBits.\n\n     windowBits can also be greater than 15 for optional gzip decoding.  Add\n   32 to windowBits to enable zlib and gzip decoding with automatic header\n   detection, or add 16 to decode only the gzip format (the zlib format will\n   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is a\n   crc32 instead of an adler32.\n\n     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the\n   version assumed by the caller, or Z_STREAM_ERROR if the parameters are\n   invalid, such as a null pointer to the structure.  msg is set to null if\n   there is no error message.  inflateInit2 does not perform any decompression\n   apart from possibly reading the zlib header if present: actual decompression\n   will be done by inflate().  (So next_in and avail_in may be modified, but\n   next_out and avail_out are unused and unchanged.) The current implementation\n   of inflateInit2() does not process any header information -- that is\n   deferred until inflate() is called.\n*/\n\nZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,\n                                             const Bytef *dictionary,\n                                             uInt  dictLength));\n/*\n     Initializes the decompression dictionary from the given uncompressed byte\n   sequence.  This function must be called immediately after a call of inflate,\n   if that call returned Z_NEED_DICT.  The dictionary chosen by the compressor\n   can be determined from the adler32 value returned by that call of inflate.\n   The compressor and decompressor must use exactly the same dictionary (see\n   deflateSetDictionary).  For raw inflate, this function can be called at any\n   time to set the dictionary.  If the provided dictionary is smaller than the\n   window and there is already data in the window, then the provided dictionary\n   will amend what's there.  The application must insure that the dictionary\n   that was used for compression is provided.\n\n     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a\n   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is\n   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the\n   expected one (incorrect adler32 value).  inflateSetDictionary does not\n   perform any decompression: this will be done by subsequent calls of\n   inflate().\n*/\n\nZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,\n                                             Bytef *dictionary,\n                                             uInt  *dictLength));\n/*\n     Returns the sliding dictionary being maintained by inflate.  dictLength is\n   set to the number of bytes in the dictionary, and that many bytes are copied\n   to dictionary.  dictionary must have enough space, where 32768 bytes is\n   always enough.  If inflateGetDictionary() is called with dictionary equal to\n   Z_NULL, then only the dictionary length is returned, and nothing is copied.\n   Similary, if dictLength is Z_NULL, then it is not set.\n\n     inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the\n   stream state is inconsistent.\n*/\n\nZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));\n/*\n     Skips invalid compressed data until a possible full flush point (see above\n   for the description of deflate with Z_FULL_FLUSH) can be found, or until all\n   available input is skipped.  No output is provided.\n\n     inflateSync searches for a 00 00 FF FF pattern in the compressed data.\n   All full flush points have this pattern, but not all occurrences of this\n   pattern are full flush points.\n\n     inflateSync returns Z_OK if a possible full flush point has been found,\n   Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point\n   has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.\n   In the success case, the application may save the current current value of\n   total_in which indicates where valid compressed data was found.  In the\n   error case, the application may repeatedly call inflateSync, providing more\n   input each time, until success or end of the input data.\n*/\n\nZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,\n                                    z_streamp source));\n/*\n     Sets the destination stream as a complete copy of the source stream.\n\n     This function can be useful when randomly accessing a large stream.  The\n   first pass through the stream can periodically record the inflate state,\n   allowing restarting inflate at those points when randomly accessing the\n   stream.\n\n     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent\n   (such as zalloc being Z_NULL).  msg is left unchanged in both source and\n   destination.\n*/\n\nZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));\n/*\n     This function is equivalent to inflateEnd followed by inflateInit,\n   but does not free and reallocate all the internal decompression state.  The\n   stream will keep attributes that may have been set by inflateInit2.\n\n     inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent (such as zalloc or state being Z_NULL).\n*/\n\nZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,\n                                      int windowBits));\n/*\n     This function is the same as inflateReset, but it also permits changing\n   the wrap and window size requests.  The windowBits parameter is interpreted\n   the same as it is for inflateInit2.\n\n     inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent (such as zalloc or state being Z_NULL), or if\n   the windowBits parameter is invalid.\n*/\n\nZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,\n                                     int bits,\n                                     int value));\n/*\n     This function inserts bits in the inflate input stream.  The intent is\n   that this function is used to start inflating at a bit position in the\n   middle of a byte.  The provided bits will be used before any bytes are used\n   from next_in.  This function should only be used with raw inflate, and\n   should be used before the first inflate() call after inflateInit2() or\n   inflateReset().  bits must be less than or equal to 16, and that many of the\n   least significant bits of value will be inserted in the input.\n\n     If bits is negative, then the input stream bit buffer is emptied.  Then\n   inflatePrime() can be called again to put bits in the buffer.  This is used\n   to clear out bits leftover after feeding inflate a block description prior\n   to feeding inflate codes.\n\n     inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent.\n*/\n\nZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));\n/*\n     This function returns two values, one in the lower 16 bits of the return\n   value, and the other in the remaining upper bits, obtained by shifting the\n   return value down 16 bits.  If the upper value is -1 and the lower value is\n   zero, then inflate() is currently decoding information outside of a block.\n   If the upper value is -1 and the lower value is non-zero, then inflate is in\n   the middle of a stored block, with the lower value equaling the number of\n   bytes from the input remaining to copy.  If the upper value is not -1, then\n   it is the number of bits back from the current bit position in the input of\n   the code (literal or length/distance pair) currently being processed.  In\n   that case the lower value is the number of bytes already emitted for that\n   code.\n\n     A code is being processed if inflate is waiting for more input to complete\n   decoding of the code, or if it has completed decoding but is waiting for\n   more output space to write the literal or match data.\n\n     inflateMark() is used to mark locations in the input data for random\n   access, which may be at bit positions, and to note those cases where the\n   output of a code may span boundaries of random access blocks.  The current\n   location in the input stream can be determined from avail_in and data_type\n   as noted in the description for the Z_BLOCK flush parameter for inflate.\n\n     inflateMark returns the value noted above or -1 << 16 if the provided\n   source stream state was inconsistent.\n*/\n\nZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,\n                                         gz_headerp head));\n/*\n     inflateGetHeader() requests that gzip header information be stored in the\n   provided gz_header structure.  inflateGetHeader() may be called after\n   inflateInit2() or inflateReset(), and before the first call of inflate().\n   As inflate() processes the gzip stream, head->done is zero until the header\n   is completed, at which time head->done is set to one.  If a zlib stream is\n   being decoded, then head->done is set to -1 to indicate that there will be\n   no gzip header information forthcoming.  Note that Z_BLOCK or Z_TREES can be\n   used to force inflate() to return immediately after header processing is\n   complete and before any actual data is decompressed.\n\n     The text, time, xflags, and os fields are filled in with the gzip header\n   contents.  hcrc is set to true if there is a header CRC.  (The header CRC\n   was valid if done is set to one.) If extra is not Z_NULL, then extra_max\n   contains the maximum number of bytes to write to extra.  Once done is true,\n   extra_len contains the actual extra field length, and extra contains the\n   extra field, or that field truncated if extra_max is less than extra_len.\n   If name is not Z_NULL, then up to name_max characters are written there,\n   terminated with a zero unless the length is greater than name_max.  If\n   comment is not Z_NULL, then up to comm_max characters are written there,\n   terminated with a zero unless the length is greater than comm_max.  When any\n   of extra, name, or comment are not Z_NULL and the respective field is not\n   present in the header, then that field is set to Z_NULL to signal its\n   absence.  This allows the use of deflateSetHeader() with the returned\n   structure to duplicate the header.  However if those fields are set to\n   allocated memory, then the application will need to save those pointers\n   elsewhere so that they can be eventually freed.\n\n     If inflateGetHeader is not used, then the header information is simply\n   discarded.  The header is always checked for validity, including the header\n   CRC if present.  inflateReset() will reset the process to discard the header\n   information.  The application would need to call inflateGetHeader() again to\n   retrieve the header from the next gzip stream.\n\n     inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent.\n*/\n\n/*\nZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,\n                                        unsigned char FAR *window));\n\n     Initialize the internal stream state for decompression using inflateBack()\n   calls.  The fields zalloc, zfree and opaque in strm must be initialized\n   before the call.  If zalloc and zfree are Z_NULL, then the default library-\n   derived memory allocation routines are used.  windowBits is the base two\n   logarithm of the window size, in the range 8..15.  window is a caller\n   supplied buffer of that size.  Except for special applications where it is\n   assured that deflate was used with small window sizes, windowBits must be 15\n   and a 32K byte window must be supplied to be able to decompress general\n   deflate streams.\n\n     See inflateBack() for the usage of these routines.\n\n     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of\n   the parameters are invalid, Z_MEM_ERROR if the internal state could not be\n   allocated, or Z_VERSION_ERROR if the version of the library does not match\n   the version of the header file.\n*/\n\ntypedef unsigned (*in_func) OF((void FAR *,\n                                z_const unsigned char FAR * FAR *));\ntypedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));\n\nZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,\n                                    in_func in, void FAR *in_desc,\n                                    out_func out, void FAR *out_desc));\n/*\n     inflateBack() does a raw inflate with a single call using a call-back\n   interface for input and output.  This is potentially more efficient than\n   inflate() for file i/o applications, in that it avoids copying between the\n   output and the sliding window by simply making the window itself the output\n   buffer.  inflate() can be faster on modern CPUs when used with large\n   buffers.  inflateBack() trusts the application to not change the output\n   buffer passed by the output function, at least until inflateBack() returns.\n\n     inflateBackInit() must be called first to allocate the internal state\n   and to initialize the state with the user-provided window buffer.\n   inflateBack() may then be used multiple times to inflate a complete, raw\n   deflate stream with each call.  inflateBackEnd() is then called to free the\n   allocated state.\n\n     A raw deflate stream is one with no zlib or gzip header or trailer.\n   This routine would normally be used in a utility that reads zip or gzip\n   files and writes out uncompressed files.  The utility would decode the\n   header and process the trailer on its own, hence this routine expects only\n   the raw deflate stream to decompress.  This is different from the normal\n   behavior of inflate(), which expects either a zlib or gzip header and\n   trailer around the deflate stream.\n\n     inflateBack() uses two subroutines supplied by the caller that are then\n   called by inflateBack() for input and output.  inflateBack() calls those\n   routines until it reads a complete deflate stream and writes out all of the\n   uncompressed data, or until it encounters an error.  The function's\n   parameters and return types are defined above in the in_func and out_func\n   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the\n   number of bytes of provided input, and a pointer to that input in buf.  If\n   there is no input available, in() must return zero--buf is ignored in that\n   case--and inflateBack() will return a buffer error.  inflateBack() will call\n   out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].  out()\n   should return zero on success, or non-zero on failure.  If out() returns\n   non-zero, inflateBack() will return with an error.  Neither in() nor out()\n   are permitted to change the contents of the window provided to\n   inflateBackInit(), which is also the buffer that out() uses to write from.\n   The length written by out() will be at most the window size.  Any non-zero\n   amount of input may be provided by in().\n\n     For convenience, inflateBack() can be provided input on the first call by\n   setting strm->next_in and strm->avail_in.  If that input is exhausted, then\n   in() will be called.  Therefore strm->next_in must be initialized before\n   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called\n   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in\n   must also be initialized, and then if strm->avail_in is not zero, input will\n   initially be taken from strm->next_in[0 ..  strm->avail_in - 1].\n\n     The in_desc and out_desc parameters of inflateBack() is passed as the\n   first parameter of in() and out() respectively when they are called.  These\n   descriptors can be optionally used to pass any information that the caller-\n   supplied in() and out() functions need to do their job.\n\n     On return, inflateBack() will set strm->next_in and strm->avail_in to\n   pass back any unused input that was provided by the last in() call.  The\n   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR\n   if in() or out() returned an error, Z_DATA_ERROR if there was a format error\n   in the deflate stream (in which case strm->msg is set to indicate the nature\n   of the error), or Z_STREAM_ERROR if the stream was not properly initialized.\n   In the case of Z_BUF_ERROR, an input or output error can be distinguished\n   using strm->next_in which will be Z_NULL only if in() returned an error.  If\n   strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning\n   non-zero.  (in() will always be called before out(), so strm->next_in is\n   assured to be defined if out() returns non-zero.) Note that inflateBack()\n   cannot return Z_OK.\n*/\n\nZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));\n/*\n     All memory allocated by inflateBackInit() is freed.\n\n     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream\n   state was inconsistent.\n*/\n\nZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));\n/* Return flags indicating compile-time options.\n\n    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:\n     1.0: size of uInt\n     3.2: size of uLong\n     5.4: size of voidpf (pointer)\n     7.6: size of z_off_t\n\n    Compiler, assembler, and debug options:\n     8: DEBUG\n     9: ASMV or ASMINF -- use ASM code\n     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention\n     11: 0 (reserved)\n\n    One-time table building (smaller code, but not thread-safe if true):\n     12: BUILDFIXED -- build static block decoding tables when needed\n     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed\n     14,15: 0 (reserved)\n\n    Library content (indicates missing functionality):\n     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking\n                          deflate code when not needed)\n     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect\n                    and decode gzip streams (to avoid linking crc code)\n     18-19: 0 (reserved)\n\n    Operation variations (changes in library functionality):\n     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate\n     21: FASTEST -- deflate algorithm with only one, lowest compression level\n     22,23: 0 (reserved)\n\n    The sprintf variant used by gzprintf (zero is best):\n     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format\n     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!\n     26: 0 = returns value, 1 = void -- 1 means inferred string length returned\n\n    Remainder:\n     27-31: 0 (reserved)\n */\n\n#ifndef Z_SOLO\n\n                        /* utility functions */\n\n/*\n     The following utility functions are implemented on top of the basic\n   stream-oriented functions.  To simplify the interface, some default options\n   are assumed (compression level and memory usage, standard memory allocation\n   functions).  The source code of these utility functions can be modified if\n   you need special options.\n*/\n\nZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,\n                                 const Bytef *source, uLong sourceLen));\n/*\n     Compresses the source buffer into the destination buffer.  sourceLen is\n   the byte length of the source buffer.  Upon entry, destLen is the total size\n   of the destination buffer, which must be at least the value returned by\n   compressBound(sourceLen).  Upon exit, destLen is the actual size of the\n   compressed buffer.\n\n     compress returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_BUF_ERROR if there was not enough room in the output\n   buffer.\n*/\n\nZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,\n                                  const Bytef *source, uLong sourceLen,\n                                  int level));\n/*\n     Compresses the source buffer into the destination buffer.  The level\n   parameter has the same meaning as in deflateInit.  sourceLen is the byte\n   length of the source buffer.  Upon entry, destLen is the total size of the\n   destination buffer, which must be at least the value returned by\n   compressBound(sourceLen).  Upon exit, destLen is the actual size of the\n   compressed buffer.\n\n     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_BUF_ERROR if there was not enough room in the output buffer,\n   Z_STREAM_ERROR if the level parameter is invalid.\n*/\n\nZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));\n/*\n     compressBound() returns an upper bound on the compressed size after\n   compress() or compress2() on sourceLen bytes.  It would be used before a\n   compress() or compress2() call to allocate the destination buffer.\n*/\n\nZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,\n                                   const Bytef *source, uLong sourceLen));\n/*\n     Decompresses the source buffer into the destination buffer.  sourceLen is\n   the byte length of the source buffer.  Upon entry, destLen is the total size\n   of the destination buffer, which must be large enough to hold the entire\n   uncompressed data.  (The size of the uncompressed data must have been saved\n   previously by the compressor and transmitted to the decompressor by some\n   mechanism outside the scope of this compression library.) Upon exit, destLen\n   is the actual size of the uncompressed buffer.\n\n     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_BUF_ERROR if there was not enough room in the output\n   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.  In\n   the case where there is not enough room, uncompress() will fill the output\n   buffer with the uncompressed data up to that point.\n*/\n\n                        /* gzip file access functions */\n\n/*\n     This library supports reading and writing files in gzip (.gz) format with\n   an interface similar to that of stdio, using the functions that start with\n   \"gz\".  The gzip format is different from the zlib format.  gzip is a gzip\n   wrapper, documented in RFC 1952, wrapped around a deflate stream.\n*/\n\ntypedef struct gzFile_s *gzFile;    /* semi-opaque gzip file descriptor */\n\n/*\nZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));\n\n     Opens a gzip (.gz) file for reading or writing.  The mode parameter is as\n   in fopen (\"rb\" or \"wb\") but can also include a compression level (\"wb9\") or\n   a strategy: 'f' for filtered data as in \"wb6f\", 'h' for Huffman-only\n   compression as in \"wb1h\", 'R' for run-length encoding as in \"wb1R\", or 'F'\n   for fixed code compression as in \"wb9F\".  (See the description of\n   deflateInit2 for more information about the strategy parameter.)  'T' will\n   request transparent writing or appending with no compression and not using\n   the gzip format.\n\n     \"a\" can be used instead of \"w\" to request that the gzip stream that will\n   be written be appended to the file.  \"+\" will result in an error, since\n   reading and writing to the same gzip file is not supported.  The addition of\n   \"x\" when writing will create the file exclusively, which fails if the file\n   already exists.  On systems that support it, the addition of \"e\" when\n   reading or writing will set the flag to close the file on an execve() call.\n\n     These functions, as well as gzip, will read and decode a sequence of gzip\n   streams in a file.  The append function of gzopen() can be used to create\n   such a file.  (Also see gzflush() for another way to do this.)  When\n   appending, gzopen does not test whether the file begins with a gzip stream,\n   nor does it look for the end of the gzip streams to begin appending.  gzopen\n   will simply append a gzip stream to the existing file.\n\n     gzopen can be used to read a file which is not in gzip format; in this\n   case gzread will directly read from the file without decompression.  When\n   reading, this will be detected automatically by looking for the magic two-\n   byte gzip header.\n\n     gzopen returns NULL if the file could not be opened, if there was\n   insufficient memory to allocate the gzFile state, or if an invalid mode was\n   specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).\n   errno can be checked to determine if the reason gzopen failed was that the\n   file could not be opened.\n*/\n\nZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));\n/*\n     gzdopen associates a gzFile with the file descriptor fd.  File descriptors\n   are obtained from calls like open, dup, creat, pipe or fileno (if the file\n   has been previously opened with fopen).  The mode parameter is as in gzopen.\n\n     The next call of gzclose on the returned gzFile will also close the file\n   descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor\n   fd.  If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,\n   mode);.  The duplicated descriptor should be saved to avoid a leak, since\n   gzdopen does not close fd if it fails.  If you are using fileno() to get the\n   file descriptor from a FILE *, then you will have to use dup() to avoid\n   double-close()ing the file descriptor.  Both gzclose() and fclose() will\n   close the associated file descriptor, so they need to have different file\n   descriptors.\n\n     gzdopen returns NULL if there was insufficient memory to allocate the\n   gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not\n   provided, or '+' was provided), or if fd is -1.  The file descriptor is not\n   used until the next gz* read, write, seek, or close operation, so gzdopen\n   will not detect if fd is invalid (unless fd is -1).\n*/\n\nZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));\n/*\n     Set the internal buffer size used by this library's functions.  The\n   default buffer size is 8192 bytes.  This function must be called after\n   gzopen() or gzdopen(), and before any other calls that read or write the\n   file.  The buffer memory allocation is always deferred to the first read or\n   write.  Two buffers are allocated, either both of the specified size when\n   writing, or one of the specified size and the other twice that size when\n   reading.  A larger buffer size of, for example, 64K or 128K bytes will\n   noticeably increase the speed of decompression (reading).\n\n     The new buffer size also affects the maximum length for gzprintf().\n\n     gzbuffer() returns 0 on success, or -1 on failure, such as being called\n   too late.\n*/\n\nZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));\n/*\n     Dynamically update the compression level or strategy.  See the description\n   of deflateInit2 for the meaning of these parameters.\n\n     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not\n   opened for writing.\n*/\n\nZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));\n/*\n     Reads the given number of uncompressed bytes from the compressed file.  If\n   the input file is not in gzip format, gzread copies the given number of\n   bytes into the buffer directly from the file.\n\n     After reaching the end of a gzip stream in the input, gzread will continue\n   to read, looking for another gzip stream.  Any number of gzip streams may be\n   concatenated in the input file, and will all be decompressed by gzread().\n   If something other than a gzip stream is encountered after a gzip stream,\n   that remaining trailing garbage is ignored (and no error is returned).\n\n     gzread can be used to read a gzip file that is being concurrently written.\n   Upon reaching the end of the input, gzread will return with the available\n   data.  If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then\n   gzclearerr can be used to clear the end of file indicator in order to permit\n   gzread to be tried again.  Z_OK indicates that a gzip stream was completed\n   on the last gzread.  Z_BUF_ERROR indicates that the input file ended in the\n   middle of a gzip stream.  Note that gzread does not return -1 in the event\n   of an incomplete gzip stream.  This error is deferred until gzclose(), which\n   will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip\n   stream.  Alternatively, gzerror can be used before gzclose to detect this\n   case.\n\n     gzread returns the number of uncompressed bytes actually read, less than\n   len for end of file, or -1 for error.\n*/\n\nZEXTERN int ZEXPORT gzwrite OF((gzFile file,\n                                voidpc buf, unsigned len));\n/*\n     Writes the given number of uncompressed bytes into the compressed file.\n   gzwrite returns the number of uncompressed bytes written or 0 in case of\n   error.\n*/\n\nZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));\n/*\n     Converts, formats, and writes the arguments to the compressed file under\n   control of the format string, as in fprintf.  gzprintf returns the number of\n   uncompressed bytes actually written, or 0 in case of error.  The number of\n   uncompressed bytes written is limited to 8191, or one less than the buffer\n   size given to gzbuffer().  The caller should assure that this limit is not\n   exceeded.  If it is exceeded, then gzprintf() will return an error (0) with\n   nothing written.  In this case, there may also be a buffer overflow with\n   unpredictable consequences, which is possible only if zlib was compiled with\n   the insecure functions sprintf() or vsprintf() because the secure snprintf()\n   or vsnprintf() functions were not available.  This can be determined using\n   zlibCompileFlags().\n*/\n\nZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));\n/*\n     Writes the given null-terminated string to the compressed file, excluding\n   the terminating null character.\n\n     gzputs returns the number of characters written, or -1 in case of error.\n*/\n\nZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));\n/*\n     Reads bytes from the compressed file until len-1 characters are read, or a\n   newline character is read and transferred to buf, or an end-of-file\n   condition is encountered.  If any characters are read or if len == 1, the\n   string is terminated with a null character.  If no characters are read due\n   to an end-of-file or len < 1, then the buffer is left untouched.\n\n     gzgets returns buf which is a null-terminated string, or it returns NULL\n   for end-of-file or in case of error.  If there was an error, the contents at\n   buf are indeterminate.\n*/\n\nZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));\n/*\n     Writes c, converted to an unsigned char, into the compressed file.  gzputc\n   returns the value that was written, or -1 in case of error.\n*/\n\nZEXTERN int ZEXPORT gzgetc OF((gzFile file));\n/*\n     Reads one byte from the compressed file.  gzgetc returns this byte or -1\n   in case of end of file or error.  This is implemented as a macro for speed.\n   As such, it does not do all of the checking the other functions do.  I.e.\n   it does not check to see if file is NULL, nor whether the structure file\n   points to has been clobbered or not.\n*/\n\nZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));\n/*\n     Push one character back onto the stream to be read as the first character\n   on the next read.  At least one character of push-back is allowed.\n   gzungetc() returns the character pushed, or -1 on failure.  gzungetc() will\n   fail if c is -1, and may fail if a character has been pushed but not read\n   yet.  If gzungetc is used immediately after gzopen or gzdopen, at least the\n   output buffer size of pushed characters is allowed.  (See gzbuffer above.)\n   The pushed character will be discarded if the stream is repositioned with\n   gzseek() or gzrewind().\n*/\n\nZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));\n/*\n     Flushes all pending output into the compressed file.  The parameter flush\n   is as in the deflate() function.  The return value is the zlib error number\n   (see function gzerror below).  gzflush is only permitted when writing.\n\n     If the flush parameter is Z_FINISH, the remaining data is written and the\n   gzip stream is completed in the output.  If gzwrite() is called again, a new\n   gzip stream will be started in the output.  gzread() is able to read such\n   concatented gzip streams.\n\n     gzflush should be called only when strictly necessary because it will\n   degrade compression if called too often.\n*/\n\n/*\nZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,\n                                   z_off_t offset, int whence));\n\n     Sets the starting position for the next gzread or gzwrite on the given\n   compressed file.  The offset represents a number of bytes in the\n   uncompressed data stream.  The whence parameter is defined as in lseek(2);\n   the value SEEK_END is not supported.\n\n     If the file is opened for reading, this function is emulated but can be\n   extremely slow.  If the file is opened for writing, only forward seeks are\n   supported; gzseek then compresses a sequence of zeroes up to the new\n   starting position.\n\n     gzseek returns the resulting offset location as measured in bytes from\n   the beginning of the uncompressed stream, or -1 in case of error, in\n   particular if the file is opened for writing and the new starting position\n   would be before the current position.\n*/\n\nZEXTERN int ZEXPORT    gzrewind OF((gzFile file));\n/*\n     Rewinds the given file. This function is supported only for reading.\n\n     gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)\n*/\n\n/*\nZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));\n\n     Returns the starting position for the next gzread or gzwrite on the given\n   compressed file.  This position represents a number of bytes in the\n   uncompressed data stream, and is zero when starting, even if appending or\n   reading a gzip stream from the middle of a file using gzdopen().\n\n     gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)\n*/\n\n/*\nZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));\n\n     Returns the current offset in the file being read or written.  This offset\n   includes the count of bytes that precede the gzip stream, for example when\n   appending or when using gzdopen() for reading.  When reading, the offset\n   does not include as yet unused buffered input.  This information can be used\n   for a progress indicator.  On error, gzoffset() returns -1.\n*/\n\nZEXTERN int ZEXPORT gzeof OF((gzFile file));\n/*\n     Returns true (1) if the end-of-file indicator has been set while reading,\n   false (0) otherwise.  Note that the end-of-file indicator is set only if the\n   read tried to go past the end of the input, but came up short.  Therefore,\n   just like feof(), gzeof() may return false even if there is no more data to\n   read, in the event that the last read request was for the exact number of\n   bytes remaining in the input file.  This will happen if the input file size\n   is an exact multiple of the buffer size.\n\n     If gzeof() returns true, then the read functions will return no more data,\n   unless the end-of-file indicator is reset by gzclearerr() and the input file\n   has grown since the previous end of file was detected.\n*/\n\nZEXTERN int ZEXPORT gzdirect OF((gzFile file));\n/*\n     Returns true (1) if file is being copied directly while reading, or false\n   (0) if file is a gzip stream being decompressed.\n\n     If the input file is empty, gzdirect() will return true, since the input\n   does not contain a gzip stream.\n\n     If gzdirect() is used immediately after gzopen() or gzdopen() it will\n   cause buffers to be allocated to allow reading the file to determine if it\n   is a gzip file.  Therefore if gzbuffer() is used, it should be called before\n   gzdirect().\n\n     When writing, gzdirect() returns true (1) if transparent writing was\n   requested (\"wT\" for the gzopen() mode), or false (0) otherwise.  (Note:\n   gzdirect() is not needed when writing.  Transparent writing must be\n   explicitly requested, so the application already knows the answer.  When\n   linking statically, using gzdirect() will include all of the zlib code for\n   gzip file reading and decompression, which may not be desired.)\n*/\n\nZEXTERN int ZEXPORT    gzclose OF((gzFile file));\n/*\n     Flushes all pending output if necessary, closes the compressed file and\n   deallocates the (de)compression state.  Note that once file is closed, you\n   cannot call gzerror with file, since its structures have been deallocated.\n   gzclose must not be called more than once on the same file, just as free\n   must not be called more than once on the same allocation.\n\n     gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a\n   file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the\n   last read ended in the middle of a gzip stream, or Z_OK on success.\n*/\n\nZEXTERN int ZEXPORT gzclose_r OF((gzFile file));\nZEXTERN int ZEXPORT gzclose_w OF((gzFile file));\n/*\n     Same as gzclose(), but gzclose_r() is only for use when reading, and\n   gzclose_w() is only for use when writing or appending.  The advantage to\n   using these instead of gzclose() is that they avoid linking in zlib\n   compression or decompression code that is not used when only reading or only\n   writing respectively.  If gzclose() is used, then both compression and\n   decompression code will be included the application when linking to a static\n   zlib library.\n*/\n\nZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));\n/*\n     Returns the error message for the last error which occurred on the given\n   compressed file.  errnum is set to zlib error number.  If an error occurred\n   in the file system and not in the compression library, errnum is set to\n   Z_ERRNO and the application may consult errno to get the exact error code.\n\n     The application must not modify the returned string.  Future calls to\n   this function may invalidate the previously returned string.  If file is\n   closed, then the string previously returned by gzerror will no longer be\n   available.\n\n     gzerror() should be used to distinguish errors from end-of-file for those\n   functions above that do not distinguish those cases in their return values.\n*/\n\nZEXTERN void ZEXPORT gzclearerr OF((gzFile file));\n/*\n     Clears the error and end-of-file flags for file.  This is analogous to the\n   clearerr() function in stdio.  This is useful for continuing to read a gzip\n   file that is being written concurrently.\n*/\n\n#endif /* !Z_SOLO */\n\n                        /* checksum functions */\n\n/*\n     These functions are not related to compression but are exported\n   anyway because they might be useful in applications using the compression\n   library.\n*/\n\nZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));\n/*\n     Update a running Adler-32 checksum with the bytes buf[0..len-1] and\n   return the updated checksum.  If buf is Z_NULL, this function returns the\n   required initial value for the checksum.\n\n     An Adler-32 checksum is almost as reliable as a CRC32 but can be computed\n   much faster.\n\n   Usage example:\n\n     uLong adler = adler32(0L, Z_NULL, 0);\n\n     while (read_buffer(buffer, length) != EOF) {\n       adler = adler32(adler, buffer, length);\n     }\n     if (adler != original_adler) error();\n*/\n\n/*\nZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,\n                                          z_off_t len2));\n\n     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1\n   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for\n   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of\n   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.  Note\n   that the z_off_t type (like off_t) is a signed integer.  If len2 is\n   negative, the result has no meaning or utility.\n*/\n\nZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));\n/*\n     Update a running CRC-32 with the bytes buf[0..len-1] and return the\n   updated CRC-32.  If buf is Z_NULL, this function returns the required\n   initial value for the crc.  Pre- and post-conditioning (one's complement) is\n   performed within this function so it shouldn't be done by the application.\n\n   Usage example:\n\n     uLong crc = crc32(0L, Z_NULL, 0);\n\n     while (read_buffer(buffer, length) != EOF) {\n       crc = crc32(crc, buffer, length);\n     }\n     if (crc != original_crc) error();\n*/\n\n/*\nZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));\n\n     Combine two CRC-32 check values into one.  For two sequences of bytes,\n   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were\n   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32\n   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and\n   len2.\n*/\n\n\n                        /* various hacks, don't look :) */\n\n/* deflateInit and inflateInit are macros to allow checking the zlib version\n * and the compiler's view of z_stream:\n */\nZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,\n                                     const char *version, int stream_size));\nZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,\n                                     const char *version, int stream_size));\nZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,\n                                      int windowBits, int memLevel,\n                                      int strategy, const char *version,\n                                      int stream_size));\nZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,\n                                      const char *version, int stream_size));\nZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,\n                                         unsigned char FAR *window,\n                                         const char *version,\n                                         int stream_size));\n#define deflateInit(strm, level) \\\n        deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))\n#define inflateInit(strm) \\\n        inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))\n#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \\\n        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\\\n                      (strategy), ZLIB_VERSION, (int)sizeof(z_stream))\n#define inflateInit2(strm, windowBits) \\\n        inflateInit2_((strm), (windowBits), ZLIB_VERSION, \\\n                      (int)sizeof(z_stream))\n#define inflateBackInit(strm, windowBits, window) \\\n        inflateBackInit_((strm), (windowBits), (window), \\\n                      ZLIB_VERSION, (int)sizeof(z_stream))\n\n#ifndef Z_SOLO\n\n/* gzgetc() macro and its supporting function and exposed data structure.  Note\n * that the real internal state is much larger than the exposed structure.\n * This abbreviated structure exposes just enough for the gzgetc() macro.  The\n * user should not mess with these exposed elements, since their names or\n * behavior could change in the future, perhaps even capriciously.  They can\n * only be used by the gzgetc() macro.  You have been warned.\n */\nstruct gzFile_s {\n    unsigned have;\n    unsigned char *next;\n    z_off64_t pos;\n};\nZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));  /* backward compatibility */\n#ifdef Z_PREFIX_SET\n#  undef z_gzgetc\n#  define z_gzgetc(g) \\\n          ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))\n#else\n#  define gzgetc(g) \\\n          ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))\n#endif\n\n/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or\n * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if\n * both are true, the application gets the *64 functions, and the regular\n * functions are changed to 64 bits) -- in case these are set on systems\n * without large file support, _LFS64_LARGEFILE must also be true\n */\n#ifdef Z_LARGE64\n   ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));\n   ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));\n   ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));\n   ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));\n   ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));\n   ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));\n#endif\n\n#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)\n#  ifdef Z_PREFIX_SET\n#    define z_gzopen z_gzopen64\n#    define z_gzseek z_gzseek64\n#    define z_gztell z_gztell64\n#    define z_gzoffset z_gzoffset64\n#    define z_adler32_combine z_adler32_combine64\n#    define z_crc32_combine z_crc32_combine64\n#  else\n#    define gzopen gzopen64\n#    define gzseek gzseek64\n#    define gztell gztell64\n#    define gzoffset gzoffset64\n#    define adler32_combine adler32_combine64\n#    define crc32_combine crc32_combine64\n#  endif\n#  ifndef Z_LARGE64\n     ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));\n     ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));\n     ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));\n     ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));\n     ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));\n     ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));\n#  endif\n#else\n   ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));\n   ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));\n   ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));\n   ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));\n   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));\n   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));\n#endif\n\n#else /* Z_SOLO */\n\n   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));\n   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));\n\n#endif /* !Z_SOLO */\n\n/* hack for buggy compilers */\n#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)\n    struct internal_state {int dummy;};\n#endif\n\n/* undocumented functions */\nZEXTERN const char   * ZEXPORT zError           OF((int));\nZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp));\nZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table    OF((void));\nZEXTERN int            ZEXPORT inflateUndermine OF((z_streamp, int));\nZEXTERN int            ZEXPORT inflateResetKeep OF((z_streamp));\nZEXTERN int            ZEXPORT deflateResetKeep OF((z_streamp));\n#if defined(_WIN32) && !defined(Z_SOLO)\nZEXTERN gzFile         ZEXPORT gzopen_w OF((const wchar_t *path,\n                                            const char *mode));\n#endif\n#if defined(STDC) || defined(Z_HAVE_STDARG_H)\n#  ifndef Z_SOLO\nZEXTERN int            ZEXPORTVA gzvprintf Z_ARG((gzFile file,\n                                                  const char *format,\n                                                  va_list va));\n#  endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* ZLIB_H */\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/zlib.pc",
    "content": "prefix=/usr/local\nexec_prefix=${prefix}\nlibdir=${exec_prefix}/lib\nsharedlibdir=${libdir}\nincludedir=${prefix}/include\n\nName: zlib\nDescription: zlib compression library\nVersion: 1.2.8\n\nRequires:\nLibs: -L${libdir} -L${sharedlibdir} -lz\nCflags: -I${includedir}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/zlib.pc.cmakein",
    "content": "prefix=@CMAKE_INSTALL_PREFIX@\nexec_prefix=@CMAKE_INSTALL_PREFIX@\nlibdir=@INSTALL_LIB_DIR@\nsharedlibdir=@INSTALL_LIB_DIR@\nincludedir=@INSTALL_INC_DIR@\n\nName: zlib\nDescription: zlib compression library\nVersion: @VERSION@\n\nRequires:\nLibs: -L${libdir} -L${sharedlibdir} -lz\nCflags: -I${includedir}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/zlib.pc.in",
    "content": "prefix=@prefix@\nexec_prefix=@exec_prefix@\nlibdir=@libdir@\nsharedlibdir=@sharedlibdir@\nincludedir=@includedir@\n\nName: zlib\nDescription: zlib compression library\nVersion: @VERSION@\n\nRequires:\nLibs: -L${libdir} -L${sharedlibdir} -lz\nCflags: -I${includedir}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/zlib2ansi",
    "content": "#!/usr/bin/perl\n\n# Transform K&R C function definitions into ANSI equivalent.\n#\n# Author: Paul Marquess\n# Version: 1.0\n# Date: 3 October 2006\n\n# TODO\n#\n# Asumes no function pointer parameters. unless they are typedefed.\n# Assumes no literal strings that look like function definitions\n# Assumes functions start at the beginning of a line\n\nuse strict;\nuse warnings;\n\nlocal $/;\n$_ = <>;\n\nmy $sp = qr{ \\s* (?: /\\* .*? \\*/ )? \\s* }x; # assume no nested comments\n\nmy $d1    = qr{ $sp (?: [\\w\\*\\s]+ $sp)* $sp \\w+ $sp [\\[\\]\\s]* $sp }x ;\nmy $decl  = qr{ $sp (?: \\w+ $sp )+ $d1 }xo ;\nmy $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ;\n\n\nwhile (s/^\n            (                  # Start $1\n                (              #   Start $2\n                    .*?        #     Minimal eat content\n                    ( ^ \\w [\\w\\s\\*]+ )    #     $3 -- function name\n                    \\s*        #     optional whitespace\n                )              # $2 - Matched up to before parameter list\n\n                \\( \\s*         # Literal \"(\" + optional whitespace\n                ( [^\\)]+ )     # $4 - one or more anythings except \")\"\n                \\s* \\)         # optional whitespace surrounding a Literal \")\"\n\n                ( (?: $dList )+ ) # $5\n\n                $sp ^ {        # literal \"{\" at start of line\n            )                  # Remember to $1\n        //xsom\n      )\n{\n    my $all = $1 ;\n    my $prefix = $2;\n    my $param_list = $4 ;\n    my $params = $5;\n\n    StripComments($params);\n    StripComments($param_list);\n    $param_list =~ s/^\\s+//;\n    $param_list =~ s/\\s+$//;\n\n    my $i = 0 ;\n    my %pList = map { $_ => $i++ }\n                split /\\s*,\\s*/, $param_list;\n    my $pMatch = '(\\b' . join('|', keys %pList) . '\\b)\\W*$' ;\n\n    my @params = split /\\s*;\\s*/, $params;\n    my @outParams = ();\n    foreach my $p (@params)\n    {\n        if ($p =~ /,/)\n        {\n            my @bits = split /\\s*,\\s*/, $p;\n            my $first = shift @bits;\n            $first =~ s/^\\s*//;\n            push @outParams, $first;\n            $first =~ /^(\\w+\\s*)/;\n            my $type = $1 ;\n            push @outParams, map { $type . $_ } @bits;\n        }\n        else\n        {\n            $p =~ s/^\\s+//;\n            push @outParams, $p;\n        }\n    }\n\n\n    my %tmp = map { /$pMatch/;  $_ => $pList{$1}  }\n              @outParams ;\n\n    @outParams = map  { \"    $_\" }\n                 sort { $tmp{$a} <=> $tmp{$b} }\n                 @outParams ;\n\n    print $prefix ;\n    print \"(\\n\" . join(\",\\n\", @outParams) . \")\\n\";\n    print \"{\" ;\n\n}\n\n# Output any trailing code.\nprint ;\nexit 0;\n\n\nsub StripComments\n{\n\n  no warnings;\n\n  # Strip C & C++ coments\n  # From the perlfaq\n  $_[0] =~\n\n    s{\n       /\\*         ##  Start of /* ... */ comment\n       [^*]*\\*+    ##  Non-* followed by 1-or-more *'s\n       (\n         [^/*][^*]*\\*+\n       )*          ##  0-or-more things which don't start with /\n                   ##    but do end with '*'\n       /           ##  End of /* ... */ comment\n\n     |         ##     OR  C++ Comment\n       //          ## Start of C++ comment //\n       [^\\n]*      ## followed by 0-or-more non end of line characters\n\n     |         ##     OR  various things which aren't comments:\n\n       (\n         \"           ##  Start of \" ... \" string\n         (\n           \\\\.           ##  Escaped char\n         |               ##    OR\n           [^\"\\\\]        ##  Non \"\\\n         )*\n         \"           ##  End of \" ... \" string\n\n       |         ##     OR\n\n         '           ##  Start of ' ... ' string\n         (\n           \\\\.           ##  Escaped char\n         |               ##    OR\n           [^'\\\\]        ##  Non '\\\n         )*\n         '           ##  End of ' ... ' string\n\n       |         ##     OR\n\n         .           ##  Anything other char\n         [^/\"'\\\\]*   ##  Chars which doesn't start a comment, string or escape\n       )\n     }{$2}gxs;\n\n}\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/zutil.c",
    "content": "/* zutil.c -- target dependent utility functions for the compression library\n * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly.\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* @(#) $Id$ */\n\n#include \"zutil.h\"\n#ifndef Z_SOLO\n#  include \"gzguts.h\"\n#endif\n\n#ifndef NO_DUMMY_DECL\nstruct internal_state      {int dummy;}; /* for buggy compilers */\n#endif\n\nz_const char * const z_errmsg[10] = {\n\"need dictionary\",     /* Z_NEED_DICT       2  */\n\"stream end\",          /* Z_STREAM_END      1  */\n\"\",                    /* Z_OK              0  */\n\"file error\",          /* Z_ERRNO         (-1) */\n\"stream error\",        /* Z_STREAM_ERROR  (-2) */\n\"data error\",          /* Z_DATA_ERROR    (-3) */\n\"insufficient memory\", /* Z_MEM_ERROR     (-4) */\n\"buffer error\",        /* Z_BUF_ERROR     (-5) */\n\"incompatible version\",/* Z_VERSION_ERROR (-6) */\n\"\"};\n\n\nconst char * ZEXPORT zlibVersion()\n{\n    return ZLIB_VERSION;\n}\n\nuLong ZEXPORT zlibCompileFlags()\n{\n    uLong flags;\n\n    flags = 0;\n    switch ((int)(sizeof(uInt))) {\n    case 2:     break;\n    case 4:     flags += 1;     break;\n    case 8:     flags += 2;     break;\n    default:    flags += 3;\n    }\n    switch ((int)(sizeof(uLong))) {\n    case 2:     break;\n    case 4:     flags += 1 << 2;        break;\n    case 8:     flags += 2 << 2;        break;\n    default:    flags += 3 << 2;\n    }\n    switch ((int)(sizeof(voidpf))) {\n    case 2:     break;\n    case 4:     flags += 1 << 4;        break;\n    case 8:     flags += 2 << 4;        break;\n    default:    flags += 3 << 4;\n    }\n    switch ((int)(sizeof(z_off_t))) {\n    case 2:     break;\n    case 4:     flags += 1 << 6;        break;\n    case 8:     flags += 2 << 6;        break;\n    default:    flags += 3 << 6;\n    }\n#ifdef DEBUG\n    flags += 1 << 8;\n#endif\n#if defined(ASMV) || defined(ASMINF)\n    flags += 1 << 9;\n#endif\n#ifdef ZLIB_WINAPI\n    flags += 1 << 10;\n#endif\n#ifdef BUILDFIXED\n    flags += 1 << 12;\n#endif\n#ifdef DYNAMIC_CRC_TABLE\n    flags += 1 << 13;\n#endif\n#ifdef NO_GZCOMPRESS\n    flags += 1L << 16;\n#endif\n#ifdef NO_GZIP\n    flags += 1L << 17;\n#endif\n#ifdef PKZIP_BUG_WORKAROUND\n    flags += 1L << 20;\n#endif\n#ifdef FASTEST\n    flags += 1L << 21;\n#endif\n#if defined(STDC) || defined(Z_HAVE_STDARG_H)\n#  ifdef NO_vsnprintf\n    flags += 1L << 25;\n#    ifdef HAS_vsprintf_void\n    flags += 1L << 26;\n#    endif\n#  else\n#    ifdef HAS_vsnprintf_void\n    flags += 1L << 26;\n#    endif\n#  endif\n#else\n    flags += 1L << 24;\n#  ifdef NO_snprintf\n    flags += 1L << 25;\n#    ifdef HAS_sprintf_void\n    flags += 1L << 26;\n#    endif\n#  else\n#    ifdef HAS_snprintf_void\n    flags += 1L << 26;\n#    endif\n#  endif\n#endif\n    return flags;\n}\n\n#ifdef DEBUG\n\n#  ifndef verbose\n#    define verbose 0\n#  endif\nint ZLIB_INTERNAL z_verbose = verbose;\n\nvoid ZLIB_INTERNAL z_error (m)\n    char *m;\n{\n    fprintf(stderr, \"%s\\n\", m);\n    exit(1);\n}\n#endif\n\n/* exported to allow conversion of error code to string for compress() and\n * uncompress()\n */\nconst char * ZEXPORT zError(err)\n    int err;\n{\n    return ERR_MSG(err);\n}\n\n#if defined(_WIN32_WCE)\n    /* The Microsoft C Run-Time Library for Windows CE doesn't have\n     * errno.  We define it as a global variable to simplify porting.\n     * Its value is always 0 and should not be used.\n     */\n    int errno = 0;\n#endif\n\n#ifndef HAVE_MEMCPY\n\nvoid ZLIB_INTERNAL zmemcpy(dest, source, len)\n    Bytef* dest;\n    const Bytef* source;\n    uInt  len;\n{\n    if (len == 0) return;\n    do {\n        *dest++ = *source++; /* ??? to be unrolled */\n    } while (--len != 0);\n}\n\nint ZLIB_INTERNAL zmemcmp(s1, s2, len)\n    const Bytef* s1;\n    const Bytef* s2;\n    uInt  len;\n{\n    uInt j;\n\n    for (j = 0; j < len; j++) {\n        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;\n    }\n    return 0;\n}\n\nvoid ZLIB_INTERNAL zmemzero(dest, len)\n    Bytef* dest;\n    uInt  len;\n{\n    if (len == 0) return;\n    do {\n        *dest++ = 0;  /* ??? to be unrolled */\n    } while (--len != 0);\n}\n#endif\n\n#ifndef Z_SOLO\n\n#ifdef SYS16BIT\n\n#ifdef __TURBOC__\n/* Turbo C in 16-bit mode */\n\n#  define MY_ZCALLOC\n\n/* Turbo C malloc() does not allow dynamic allocation of 64K bytes\n * and farmalloc(64K) returns a pointer with an offset of 8, so we\n * must fix the pointer. Warning: the pointer must be put back to its\n * original form in order to free it, use zcfree().\n */\n\n#define MAX_PTR 10\n/* 10*64K = 640K */\n\nlocal int next_ptr = 0;\n\ntypedef struct ptr_table_s {\n    voidpf org_ptr;\n    voidpf new_ptr;\n} ptr_table;\n\nlocal ptr_table table[MAX_PTR];\n/* This table is used to remember the original form of pointers\n * to large buffers (64K). Such pointers are normalized with a zero offset.\n * Since MSDOS is not a preemptive multitasking OS, this table is not\n * protected from concurrent access. This hack doesn't work anyway on\n * a protected system like OS/2. Use Microsoft C instead.\n */\n\nvoidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)\n{\n    voidpf buf = opaque; /* just to make some compilers happy */\n    ulg bsize = (ulg)items*size;\n\n    /* If we allocate less than 65520 bytes, we assume that farmalloc\n     * will return a usable pointer which doesn't have to be normalized.\n     */\n    if (bsize < 65520L) {\n        buf = farmalloc(bsize);\n        if (*(ush*)&buf != 0) return buf;\n    } else {\n        buf = farmalloc(bsize + 16L);\n    }\n    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;\n    table[next_ptr].org_ptr = buf;\n\n    /* Normalize the pointer to seg:0 */\n    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;\n    *(ush*)&buf = 0;\n    table[next_ptr++].new_ptr = buf;\n    return buf;\n}\n\nvoid ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)\n{\n    int n;\n    if (*(ush*)&ptr != 0) { /* object < 64K */\n        farfree(ptr);\n        return;\n    }\n    /* Find the original pointer */\n    for (n = 0; n < next_ptr; n++) {\n        if (ptr != table[n].new_ptr) continue;\n\n        farfree(table[n].org_ptr);\n        while (++n < next_ptr) {\n            table[n-1] = table[n];\n        }\n        next_ptr--;\n        return;\n    }\n    ptr = opaque; /* just to make some compilers happy */\n    Assert(0, \"zcfree: ptr not found\");\n}\n\n#endif /* __TURBOC__ */\n\n\n#ifdef M_I86\n/* Microsoft C in 16-bit mode */\n\n#  define MY_ZCALLOC\n\n#if (!defined(_MSC_VER) || (_MSC_VER <= 600))\n#  define _halloc  halloc\n#  define _hfree   hfree\n#endif\n\nvoidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)\n{\n    if (opaque) opaque = 0; /* to make compiler happy */\n    return _halloc((long)items, size);\n}\n\nvoid ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)\n{\n    if (opaque) opaque = 0; /* to make compiler happy */\n    _hfree(ptr);\n}\n\n#endif /* M_I86 */\n\n#endif /* SYS16BIT */\n\n\n#ifndef MY_ZCALLOC /* Any system without a special alloc function */\n\n#ifndef STDC\nextern voidp  malloc OF((uInt size));\nextern voidp  calloc OF((uInt items, uInt size));\nextern void   free   OF((voidpf ptr));\n#endif\n\nvoidpf ZLIB_INTERNAL zcalloc (opaque, items, size)\n    voidpf opaque;\n    unsigned items;\n    unsigned size;\n{\n    if (opaque) items += size - size; /* make compiler happy */\n    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :\n                              (voidpf)calloc(items, size);\n}\n\nvoid ZLIB_INTERNAL zcfree (opaque, ptr)\n    voidpf opaque;\n    voidpf ptr;\n{\n    free(ptr);\n    if (opaque) return; /* make compiler happy */\n}\n\n#endif /* MY_ZCALLOC */\n\n#endif /* !Z_SOLO */\n"
  },
  {
    "path": "atlas-aapt/external/zlib/src/zutil.h",
    "content": "/* zutil.h -- internal interface and configuration of the compression library\n * Copyright (C) 1995-2013 Jean-loup Gailly.\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* WARNING: this file should *not* be used by applications. It is\n   part of the implementation of the compression library and is\n   subject to change. Applications should only use zlib.h.\n */\n\n/* @(#) $Id$ */\n\n#ifndef ZUTIL_H\n#define ZUTIL_H\n\n#ifdef HAVE_HIDDEN\n#  define ZLIB_INTERNAL __attribute__((visibility (\"hidden\")))\n#else\n#  define ZLIB_INTERNAL\n#endif\n\n#include \"zlib.h\"\n\n#if defined(STDC) && !defined(Z_SOLO)\n#  if !(defined(_WIN32_WCE) && defined(_MSC_VER))\n#    include <stddef.h>\n#  endif\n#  include <string.h>\n#  include <stdlib.h>\n#endif\n\n#ifdef Z_SOLO\n   typedef long ptrdiff_t;  /* guess -- will be caught if guess is wrong */\n#endif\n\n#ifndef local\n#  define local static\n#endif\n/* compile with -Dlocal if your debugger can't find static symbols */\n\ntypedef unsigned char  uch;\ntypedef uch FAR uchf;\ntypedef unsigned short ush;\ntypedef ush FAR ushf;\ntypedef unsigned long  ulg;\n\nextern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */\n/* (size given to avoid silly warnings with Visual C++) */\n\n#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]\n\n#define ERR_RETURN(strm,err) \\\n  return (strm->msg = ERR_MSG(err), (err))\n/* To be used only when the state is known to be valid */\n\n        /* common constants */\n\n#ifndef DEF_WBITS\n#  define DEF_WBITS MAX_WBITS\n#endif\n/* default windowBits for decompression. MAX_WBITS is for compression only */\n\n#if MAX_MEM_LEVEL >= 8\n#  define DEF_MEM_LEVEL 8\n#else\n#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL\n#endif\n/* default memLevel */\n\n#define STORED_BLOCK 0\n#define STATIC_TREES 1\n#define DYN_TREES    2\n/* The three kinds of block type */\n\n#define MIN_MATCH  3\n#define MAX_MATCH  258\n/* The minimum and maximum match lengths */\n\n#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */\n\n        /* target dependencies */\n\n#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))\n#  define OS_CODE  0x00\n#  ifndef Z_SOLO\n#    if defined(__TURBOC__) || defined(__BORLANDC__)\n#      if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))\n         /* Allow compilation with ANSI keywords only enabled */\n         void _Cdecl farfree( void *block );\n         void *_Cdecl farmalloc( unsigned long nbytes );\n#      else\n#        include <alloc.h>\n#      endif\n#    else /* MSC or DJGPP */\n#      include <malloc.h>\n#    endif\n#  endif\n#endif\n\n#ifdef AMIGA\n#  define OS_CODE  0x01\n#endif\n\n#if defined(VAXC) || defined(VMS)\n#  define OS_CODE  0x02\n#  define F_OPEN(name, mode) \\\n     fopen((name), (mode), \"mbc=60\", \"ctx=stm\", \"rfm=fix\", \"mrs=512\")\n#endif\n\n#if defined(ATARI) || defined(atarist)\n#  define OS_CODE  0x05\n#endif\n\n#ifdef OS2\n#  define OS_CODE  0x06\n#  if defined(M_I86) && !defined(Z_SOLO)\n#    include <malloc.h>\n#  endif\n#endif\n\n#if defined(MACOS) || defined(TARGET_OS_MAC)\n#  define OS_CODE  0x07\n#  ifndef Z_SOLO\n#    if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os\n#      include <unix.h> /* for fdopen */\n#    else\n#      ifndef fdopen\n#        define fdopen(fd,mode) NULL /* No fdopen() */\n#      endif\n#    endif\n#  endif\n#endif\n\n#ifdef TOPS20\n#  define OS_CODE  0x0a\n#endif\n\n#ifdef WIN32\n#  ifndef __CYGWIN__  /* Cygwin is Unix, not Win32 */\n#    define OS_CODE  0x0b\n#  endif\n#endif\n\n#ifdef __50SERIES /* Prime/PRIMOS */\n#  define OS_CODE  0x0f\n#endif\n\n#if defined(_BEOS_) || defined(RISCOS)\n#  define fdopen(fd,mode) NULL /* No fdopen() */\n#endif\n\n#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX\n#  if defined(_WIN32_WCE)\n#    define fdopen(fd,mode) NULL /* No fdopen() */\n#    ifndef _PTRDIFF_T_DEFINED\n       typedef int ptrdiff_t;\n#      define _PTRDIFF_T_DEFINED\n#    endif\n#  else\n#    define fdopen(fd,type)  _fdopen(fd,type)\n#  endif\n#endif\n\n#if defined(__BORLANDC__) && !defined(MSDOS)\n  #pragma warn -8004\n  #pragma warn -8008\n  #pragma warn -8066\n#endif\n\n/* provide prototypes for these when building zlib without LFS */\n#if !defined(_WIN32) && \\\n    (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)\n    ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));\n    ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));\n#endif\n\n        /* common defaults */\n\n#ifndef OS_CODE\n#  define OS_CODE  0x03  /* assume Unix */\n#endif\n\n#ifndef F_OPEN\n#  define F_OPEN(name, mode) fopen((name), (mode))\n#endif\n\n         /* functions */\n\n#if defined(pyr) || defined(Z_SOLO)\n#  define NO_MEMCPY\n#endif\n#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)\n /* Use our own functions for small and medium model with MSC <= 5.0.\n  * You may have to use the same strategy for Borland C (untested).\n  * The __SC__ check is for Symantec.\n  */\n#  define NO_MEMCPY\n#endif\n#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)\n#  define HAVE_MEMCPY\n#endif\n#ifdef HAVE_MEMCPY\n#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */\n#    define zmemcpy _fmemcpy\n#    define zmemcmp _fmemcmp\n#    define zmemzero(dest, len) _fmemset(dest, 0, len)\n#  else\n#    define zmemcpy memcpy\n#    define zmemcmp memcmp\n#    define zmemzero(dest, len) memset(dest, 0, len)\n#  endif\n#else\n   void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));\n   int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));\n   void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));\n#endif\n\n/* Diagnostic functions */\n#ifdef DEBUG\n#  include <stdio.h>\n   extern int ZLIB_INTERNAL z_verbose;\n   extern void ZLIB_INTERNAL z_error OF((char *m));\n#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}\n#  define Trace(x) {if (z_verbose>=0) fprintf x ;}\n#  define Tracev(x) {if (z_verbose>0) fprintf x ;}\n#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}\n#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}\n#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}\n#else\n#  define Assert(cond,msg)\n#  define Trace(x)\n#  define Tracev(x)\n#  define Tracevv(x)\n#  define Tracec(c,x)\n#  define Tracecv(c,x)\n#endif\n\n#ifndef Z_SOLO\n   voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,\n                                    unsigned size));\n   void ZLIB_INTERNAL zcfree  OF((voidpf opaque, voidpf ptr));\n#endif\n\n#define ZALLOC(strm, items, size) \\\n           (*((strm)->zalloc))((strm)->opaque, (items), (size))\n#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))\n#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}\n\n/* Reverse the bytes in a 32-bit value */\n#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \\\n                    (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))\n\n#endif /* ZUTIL_H */\n"
  },
  {
    "path": "atlas-aapt/external/zlib/update_zlib.sh",
    "content": "#!/bin/bash\n# Run with no arguments from any directory, with no special setup required.\n\n# Abort if any command returns an error exit status, or if an undefined\n# variable is used.\nset -e\nset -u\n\nbase_dir=$(realpath $(dirname $0))\n\n# Extract the latest version from the web page.\nnew_version=$(wget -O - --no-verbose -q http://zlib.net/ | \\\n              grep 'http://zlib.net/zlib-[0-9].*.tar.gz' | \\\n              sed 's/.*zlib-\\(.*\\)\\.tar\\.gz.*/\\1/')\ntgz_file=\"zlib-$new_version.tar.gz\"\n\necho \"Upgrading zlib to version $new_version...\"\necho \"-------------------------------------------------------------------\"\n\necho \"Downloading $tgz_file...\"\nwget -O /tmp/$tgz_file --no-verbose \"http://zlib.net/$tgz_file\"\n\necho \"Cleaning out old version...\"\nsrc_dir=$base_dir/src\nrm -rf $src_dir\n\necho \"Unpacking new version...\"\ncd $base_dir\ntar zxf /tmp/$tgz_file\nmv zlib-$new_version src\n\necho \"Configuring new version...\"\ncd src\n./configure\nrm Makefile configure.log\ncd ..\n\necho \"Fixing NOTICE file...\"\ngrep -A21 'Copyright notice:' src/README | tail -20 > NOTICE\n\nmd5_sum=$(md5sum /tmp/$tgz_file)\necho \"MD5: $md5_sum\"\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/android_runtime/AndroidRuntime.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n\n#ifndef _RUNTIME_ANDROID_RUNTIME_H\n#define _RUNTIME_ANDROID_RUNTIME_H\n\n#include <utils/Errors.h>\n#include <binder/IBinder.h>\n#include <utils/String8.h>\n#include <utils/String16.h>\n#include <utils/Vector.h>\n#include <utils/threads.h>\n#include <pthread.h>\n#include <nativehelper/jni.h>\n\n\nnamespace android {\n\nclass AndroidRuntime\n{\npublic:\n    AndroidRuntime(char* argBlockStart, size_t argBlockSize);\n    virtual ~AndroidRuntime();\n\n    enum StartMode {\n        Zygote,\n        SystemServer,\n        Application,\n        Tool,\n    };\n\n    void setArgv0(const char* argv0);\n    void addOption(const char* optionString, void* extra_info = NULL);\n\n    /**\n     * Register a set of methods in the specified class.\n     */\n    static int registerNativeMethods(JNIEnv* env,\n        const char* className, const JNINativeMethod* gMethods, int numMethods);\n\n    /**\n     * Call a class's static main method with the given arguments,\n     */\n    status_t callMain(const String8& className, jclass clazz, const Vector<String8>& args);\n\n    /**\n     * Find a class, with the input either of the form\n     * \"package/class\" or \"package.class\".\n     */\n    static jclass findClass(JNIEnv* env, const char* className);\n\n    void start(const char *classname, const Vector<String8>& options, bool zygote);\n\n    void exit(int code);\n\n    void setExitWithoutCleanup(bool exitWithoutCleanup) {\n        mExitWithoutCleanup = exitWithoutCleanup;\n    }\n\n    static AndroidRuntime* getRuntime();\n\n    /**\n     * This gets called after the VM has been created, but before we\n     * run any code. Override it to make any FindClass calls that need\n     * to use CLASSPATH.\n     */\n    virtual void onVmCreated(JNIEnv* env);\n\n    /**\n     * This gets called after the JavaVM has initialized.  Override it\n     * with the system's native entry point.\n     */\n    virtual void onStarted() = 0;\n\n    /**\n     * This gets called after the JavaVM has initialized after a Zygote\n     * fork. Override it to initialize threads, etc. Upon return, the\n     * correct static main will be invoked.\n     */\n    virtual void onZygoteInit() { }\n\n    /**\n     * Called when the Java application exits to perform additional cleanup actions\n     * before the process is terminated.\n     */\n    virtual void onExit(int code) { }\n\n    /** create a new thread that is visible from Java */\n    static android_thread_id_t createJavaThread(const char* name, void (*start)(void *),\n        void* arg);\n\n    /** return a pointer to the VM running in this process */\n    static JavaVM* getJavaVM() { return mJavaVM; }\n\n    /** return a pointer to the JNIEnv pointer for this thread */\n    static JNIEnv* getJNIEnv();\n\n    /** return a new string corresponding to 'className' with all '.'s replaced by '/'s. */\n    static char* toSlashClassName(const char* className);\n\n    /** Create a Java string from an ASCII or Latin-1 string */\n    static jstring NewStringLatin1(JNIEnv* env, const char* bytes);\n\nprivate:\n    static int startReg(JNIEnv* env);\n    bool parseRuntimeOption(const char* property,\n                            char* buffer,\n                            const char* runtimeArg,\n                            const char* defaultArg = \"\");\n    bool parseCompilerOption(const char* property,\n                             char* buffer,\n                             const char* compilerArg,\n                             const char* quotingArg);\n    bool parseCompilerRuntimeOption(const char* property,\n                                    char* buffer,\n                                    const char* runtimeArg,\n                                    const char* quotingArg);\n    void parseExtraOpts(char* extraOptsBuf, const char* quotingArg);\n    int startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote);\n\n    Vector<JavaVMOption> mOptions;\n    bool mExitWithoutCleanup;\n    char* const mArgBlockStart;\n    const size_t mArgBlockLength;\n\n    /* JNI JavaVM pointer */\n    static JavaVM* mJavaVM;\n\n    /*\n     * Thread creation helpers.\n     */\n    static int javaCreateThreadEtc(\n                                android_thread_func_t entryFunction,\n                                void* userData,\n                                const char* threadName,\n                                int32_t threadPriority,\n                                size_t threadStackSize,\n                                android_thread_id_t* threadId);\n    static int javaThreadShell(void* args);\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/android_runtime/Log.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _RUNTIME_ANDROID_LOG_H\n#define _RUNTIME_ANDROID_LOG_H\n\n// This relies on JNIHelp.h\n\n/* Logging macros.\n *\n * Logs an exception.  If the exception is omitted or NULL, logs the current exception\n * from the JNI environment, if any.\n */\n#define LOG_EX(env, priority, tag, ...) \\\n    jniLogException(env, ANDROID_##priority, tag, ##__VA_ARGS__)\n#define LOGV_EX(env, ...) LOG_EX(env, LOG_VERBOSE, LOG_TAG, ##__VA_ARGS__)\n#define LOGD_EX(env, ...) LOG_EX(env, LOG_DEBUG, LOG_TAG, ##__VA_ARGS__)\n#define LOGI_EX(env, ...) LOG_EX(env, LOG_INFO, LOG_TAG, ##__VA_ARGS__)\n#define LOGW_EX(env, ...) LOG_EX(env, LOG_WARN, LOG_TAG, ##__VA_ARGS__)\n#define LOGE_EX(env, ...) LOG_EX(env, LOG_ERROR, LOG_TAG, ##__VA_ARGS__)\n\n#endif // _RUNTIME_ANDROID_LOG_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/android_runtime/android_app_NativeActivity.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _ANDROID_APP_NATIVEACTIVITY_H\n#define _ANDROID_APP_NATIVEACTIVITY_H\n\n#include <utils/Looper.h>\n\n#include <android/native_activity.h>\n\n#include \"jni.h\"\n\nnamespace android {\n\nextern void android_NativeActivity_finish(\n        ANativeActivity* activity);\n\nextern void android_NativeActivity_setWindowFormat(\n        ANativeActivity* activity, int32_t format);\n\nextern void android_NativeActivity_setWindowFlags(\n        ANativeActivity* activity, int32_t values, int32_t mask);\n\nextern void android_NativeActivity_showSoftInput(\n        ANativeActivity* activity, int32_t flags);\n\nextern void android_NativeActivity_hideSoftInput(\n        ANativeActivity* activity, int32_t flags);\n\n} // namespace android\n\n#endif // _ANDROID_APP_NATIVEACTIVITY_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/android_runtime/android_content_res_Configuration.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _ANDROID_CONTENT_RES_CONFIGURATION_H\n#define _ANDROID_CONTENT_RES_CONFIGURATION_H\n\n#include <androidfw/ResourceTypes.h>\n#include <android/configuration.h>\n\n#include \"jni.h\"\n\nstruct AConfiguration : android::ResTable_config {\n};\n\nnamespace android {\n\nextern void android_Configuration_getFromJava(\n        JNIEnv* env, jobject clazz, struct AConfiguration* out);\n\n} // namespace android\n\n\n#endif // _ANDROID_CONTENT_RES_CONFIGURATION_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/android_runtime/android_graphics_SurfaceTexture.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _ANDROID_GRAPHICS_SURFACETEXTURE_H\n#define _ANDROID_GRAPHICS_SURFACETEXTURE_H\n\n#include <android/native_window.h>\n\n#include \"jni.h\"\n\nnamespace android {\n\nclass GLConsumer;\nclass IGraphicBufferProducer;\n\nextern sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(JNIEnv* env, jobject thiz);\nextern bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz);\n\n/* Gets the underlying GLConsumer from a SurfaceTexture Java object. */\nextern sp<GLConsumer> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz);\n\n/* gets the producer end of the SurfaceTexture */\nextern sp<IGraphicBufferProducer> SurfaceTexture_getProducer(JNIEnv* env, jobject thiz);\n\n} // namespace android\n\n#endif // _ANDROID_GRAPHICS_SURFACETEXTURE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/android_runtime/android_hardware_camera2_CameraMetadata.h",
    "content": "/*\n * Copyright 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_HARDWARE_CAMERA2_CAMERAMETADATA_JNI_H\n#define ANDROID_HARDWARE_CAMERA2_CAMERAMETADATA_JNI_H\n\n#include <camera/CameraMetadata.h>\n\n#include \"jni.h\"\n\nnamespace android {\n\n/**\n * Copies the native metadata for this java object into the given output CameraMetadata object.\n */\nstatus_t CameraMetadata_getNativeMetadata(JNIEnv* env, jobject thiz,\n               /*out*/CameraMetadata* metadata);\n\n} /*namespace android*/\n\n#endif /*ANDROID_HARDWARE_CAMERA2_CAMERAMETADATA_JNI_H*/\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/android_runtime/android_util_AssetManager.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef android_util_AssetManager_H\n#define android_util_AssetManager_H\n\n#include <androidfw/AssetManager.h>\n\n#include \"jni.h\"\n\nnamespace android {\n\nextern AssetManager* assetManagerForJavaObject(JNIEnv* env, jobject assetMgr);\n\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/android_runtime/android_view_InputQueue.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _ANDROID_VIEW_INPUTQUEUE_H\n#define _ANDROID_VIEW_INPUTQUEUE_H\n\n#include <input/Input.h>\n#include <utils/Looper.h>\n#include <utils/TypeHelpers.h>\n#include <utils/Vector.h>\n\n#include \"JNIHelp.h\"\n\n/*\n * Declare a concrete type for the NDK's AInputQueue forward declaration\n */\nstruct AInputQueue{\n};\n\nnamespace android {\n\nclass InputQueue : public AInputQueue, public MessageHandler {\npublic:\n    virtual ~InputQueue();\n\n    void attachLooper(Looper* looper, int ident, ALooper_callbackFunc callback, void* data);\n\n    void detachLooper();\n\n    bool hasEvents();\n\n    status_t getEvent(InputEvent** outEvent);\n\n    bool preDispatchEvent(InputEvent* event);\n\n    void finishEvent(InputEvent* event, bool handled);\n\n    KeyEvent* createKeyEvent();\n\n    MotionEvent* createMotionEvent();\n\n    void recycleInputEvent(InputEvent* event);\n\n    void enqueueEvent(InputEvent* event);\n\n    static InputQueue* createQueue(jobject inputQueueObj, const sp<Looper>& looper);\n\nprotected:\n    virtual void handleMessage(const Message& message);\n\nprivate:\n    InputQueue(jobject inputQueueObj, const sp<Looper>& looper,\n            int readDispatchFd, int writeDispatchFd);\n\n    void detachLooperLocked();\n\n    jobject mInputQueueWeakGlobal;\n    int mDispatchReadFd;\n    int mDispatchWriteFd;\n    Vector<Looper*> mAppLoopers;\n    sp<Looper> mDispatchLooper;\n    sp<WeakMessageHandler> mHandler;\n    PooledInputEventFactory mPooledInputEventFactory;\n    // Guards the pending and finished event vectors\n    mutable Mutex mLock;\n    Vector<InputEvent*> mPendingEvents;\n    Vector<key_value_pair_t<InputEvent*, bool> > mFinishedEvents;\n};\n\n} // namespace android\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/android_runtime/android_view_Surface.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _ANDROID_VIEW_SURFACE_H\n#define _ANDROID_VIEW_SURFACE_H\n\n#include <android/native_window.h>\n\n#include \"jni.h\"\n\nnamespace android {\n\nclass Surface;\nclass IGraphicBufferProducer;\n\n/**\n * Enum mirroring the public API definitions for image and pixel formats.\n * Some of these are hidden in the public API\n *\n * Keep up to date with android.graphics.ImageFormat and\n * android.graphics.PixelFormat\n */\nenum class PublicFormat {\n    UNKNOWN           = 0x0,\n    RGBA_8888         = 0x1,\n    RGBX_8888         = 0x2,\n    RGB_888           = 0x3,\n    RGB_565           = 0x4,\n    NV16              = 0x10,\n    NV21              = 0x11,\n    YUY2              = 0x14,\n    RAW_SENSOR        = 0x20,\n    PRIVATE           = 0x22,\n    YUV_420_888       = 0x23,\n    RAW_PRIVATE       = 0x24,\n    RAW10             = 0x25,\n    RAW12             = 0x26,\n    JPEG              = 0x100,\n    DEPTH_POINT_CLOUD = 0x101,\n    YV12              = 0x32315659,\n    Y8                = 0x20203859, // @hide\n    Y16               = 0x20363159, // @hide\n    DEPTH16           = 0x44363159\n};\n\n/* Gets the underlying ANativeWindow for a Surface. */\nextern sp<ANativeWindow> android_view_Surface_getNativeWindow(\n        JNIEnv* env, jobject surfaceObj);\n\n/* Returns true if the object is an instance of Surface. */\nextern bool android_view_Surface_isInstanceOf(JNIEnv* env, jobject obj);\n\n/* Gets the underlying Surface from a Surface Java object. */\nextern sp<Surface> android_view_Surface_getSurface(JNIEnv* env, jobject surfaceObj);\n\n/* Creates a Surface from an IGraphicBufferProducer. */\nextern jobject android_view_Surface_createFromIGraphicBufferProducer(JNIEnv* env,\n        const sp<IGraphicBufferProducer>& bufferProducer);\n\n/* Convert from android.graphics.ImageFormat/PixelFormat enums to graphics.h HAL\n * format */\nextern int android_view_Surface_mapPublicFormatToHalFormat(PublicFormat f);\n\n/* Convert from android.graphics.ImageFormat/PixelFormat enums to graphics.h HAL\n * dataspace */\nextern android_dataspace android_view_Surface_mapPublicFormatToHalDataspace(\n        PublicFormat f);\n\n/* Convert from HAL format, dataspace pair to\n * android.graphics.ImageFormat/PixelFormat.\n * For unknown/unspecified pairs, returns PublicFormat::UNKNOWN */\nextern PublicFormat android_view_Surface_mapHalFormatDataspaceToPublicFormat(\n        int format, android_dataspace dataSpace);\n\n} // namespace android\n\n#endif // _ANDROID_VIEW_SURFACE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/android_runtime/android_view_SurfaceSession.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _ANDROID_VIEW_SURFACE_SESSION_H\n#define _ANDROID_VIEW_SURFACE_SESSION_H\n\n#include \"jni.h\"\n\nnamespace android {\n\nclass SurfaceComposerClient;\n\n/* Gets the underlying SurfaceComposerClient for a SurfaceSession. */\nextern sp<SurfaceComposerClient> android_view_SurfaceSession_getClient(\n        JNIEnv* env, jobject surfaceSessionObj);\n\n} // namespace android\n\n#endif // _ANDROID_VIEW_SURFACE_SESSION_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/Asset.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Class providing access to a read-only asset.  Asset objects are NOT\n// thread-safe, and should not be shared across threads.\n//\n#ifndef __LIBS_ASSET_H\n#define __LIBS_ASSET_H\n\n#include <stdio.h>\n#include <sys/types.h>\n\n#include <utils/Compat.h>\n#include <utils/Errors.h>\n#include <utils/FileMap.h>\n#include <utils/String8.h>\n\nnamespace android {\n\n/*\n * Instances of this class provide read-only operations on a byte stream.\n *\n * Access may be optimized for streaming, random, or whole buffer modes.  All\n * operations are supported regardless of how the file was opened, but some\n * things will be less efficient.  [pass that in??]\n *\n * \"Asset\" is the base class for all types of assets.  The classes below\n * provide most of the implementation.  The AssetManager uses one of the\n * static \"create\" functions defined here to create a new instance.\n */\nclass Asset {\npublic:\n    virtual ~Asset(void);\n\n    static int32_t getGlobalCount();\n    static String8 getAssetAllocations();\n    \n    /* used when opening an asset */\n    typedef enum AccessMode {\n        ACCESS_UNKNOWN = 0,\n\n        /* read chunks, and seek forward and backward */\n        ACCESS_RANDOM,\n\n        /* read sequentially, with an occasional forward seek */\n        ACCESS_STREAMING,\n\n        /* caller plans to ask for a read-only buffer with all data */\n        ACCESS_BUFFER,\n    } AccessMode;\n\n    /*\n     * Read data from the current offset.  Returns the actual number of\n     * bytes read, 0 on EOF, or -1 on error.\n     */\n    virtual ssize_t read(void* buf, size_t count) = 0;\n\n    /*\n     * Seek to the specified offset.  \"whence\" uses the same values as\n     * lseek/fseek.  Returns the new position on success, or (off64_t) -1\n     * on failure.\n     */\n    virtual off64_t seek(off64_t offset, int whence) = 0;\n\n    /*\n     * Close the asset, freeing all associated resources.\n     */\n    virtual void close(void) = 0;\n\n    /*\n     * Get a pointer to a buffer with the entire contents of the file.\n     */\n    virtual const void* getBuffer(bool wordAligned) = 0;\n\n    /*\n     * Get the total amount of data that can be read.\n     */\n    virtual off64_t getLength(void) const = 0;\n\n    /*\n     * Get the total amount of data that can be read from the current position.\n     */\n    virtual off64_t getRemainingLength(void) const = 0;\n\n    /*\n     * Open a new file descriptor that can be used to read this asset.\n     * Returns -1 if you can not use the file descriptor (for example if the\n     * asset is compressed).\n     */\n    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const = 0;\n\n    /*\n     * Return whether this asset's buffer is allocated in RAM (not mmapped).\n     * Note: not virtual so it is safe to call even when being destroyed.\n     */\n    virtual bool isAllocated(void) const { return false; }\n\n    /*\n     * Get a string identifying the asset's source.  This might be a full\n     * path, it might be a colon-separated list of identifiers.\n     *\n     * This is NOT intended to be used for anything except debug output.\n     * DO NOT try to parse this or use it to open a file.\n     */\n    const char* getAssetSource(void) const { return mAssetSource.string(); }\n\nprotected:\n    Asset(void);        // constructor; only invoked indirectly\n\n    /* handle common seek() housekeeping */\n    off64_t handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn);\n\n    /* set the asset source string */\n    void setAssetSource(const String8& path) { mAssetSource = path; }\n\n    AccessMode getAccessMode(void) const { return mAccessMode; }\n\nprivate:\n    /* these operations are not implemented */\n    Asset(const Asset& src);\n    Asset& operator=(const Asset& src);\n\n    /* AssetManager needs access to our \"create\" functions */\n    friend class AssetManager;\n\n    /*\n     * Create the asset from a named file on disk.\n     */\n    static Asset* createFromFile(const char* fileName, AccessMode mode);\n\n    /*\n     * Create the asset from a named, compressed file on disk (e.g. \".gz\").\n     */\n    static Asset* createFromCompressedFile(const char* fileName,\n        AccessMode mode);\n\n#if 0\n    /*\n     * Create the asset from a segment of an open file.  This will fail\n     * if \"offset\" and \"length\" don't fit within the bounds of the file.\n     *\n     * The asset takes ownership of the file descriptor.\n     */\n    static Asset* createFromFileSegment(int fd, off64_t offset, size_t length,\n        AccessMode mode);\n\n    /*\n     * Create from compressed data.  \"fd\" should be seeked to the start of\n     * the compressed data.  This could be inside a gzip file or part of a\n     * Zip archive.\n     *\n     * The asset takes ownership of the file descriptor.\n     *\n     * This may not verify the validity of the compressed data until first\n     * use.\n     */\n    static Asset* createFromCompressedData(int fd, off64_t offset,\n        int compressionMethod, size_t compressedLength,\n        size_t uncompressedLength, AccessMode mode);\n#endif\n\n    /*\n     * Create the asset from a memory-mapped file segment.\n     *\n     * The asset takes ownership of the FileMap.\n     */\n    static Asset* createFromUncompressedMap(FileMap* dataMap, AccessMode mode);\n\n    /*\n     * Create the asset from a memory-mapped file segment with compressed\n     * data.\n     *\n     * The asset takes ownership of the FileMap.\n     */\n    static Asset* createFromCompressedMap(FileMap* dataMap,\n        size_t uncompressedLen, AccessMode mode);\n\n\n    /*\n     * Create from a reference-counted chunk of shared memory.\n     */\n    // TODO\n\n    AccessMode  mAccessMode;        // how the asset was opened\n    String8    mAssetSource;       // debug string\n    \n    Asset*\t\tmNext;\t\t\t\t// linked list.\n    Asset*\t\tmPrev;\n};\n\n\n/*\n * ===========================================================================\n *\n * Innards follow.  Do not use these classes directly.\n */\n\n/*\n * An asset based on an uncompressed file on disk.  It may encompass the\n * entire file or just a piece of it.  Access is through fread/fseek.\n */\nclass _FileAsset : public Asset {\npublic:\n    _FileAsset(void);\n    virtual ~_FileAsset(void);\n\n    /*\n     * Use a piece of an already-open file.\n     *\n     * On success, the object takes ownership of \"fd\".\n     */\n    status_t openChunk(const char* fileName, int fd, off64_t offset, size_t length);\n\n    /*\n     * Use a memory-mapped region.\n     *\n     * On success, the object takes ownership of \"dataMap\".\n     */\n    status_t openChunk(FileMap* dataMap);\n\n    /*\n     * Standard Asset interfaces.\n     */\n    virtual ssize_t read(void* buf, size_t count);\n    virtual off64_t seek(off64_t offset, int whence);\n    virtual void close(void);\n    virtual const void* getBuffer(bool wordAligned);\n    virtual off64_t getLength(void) const { return mLength; }\n    virtual off64_t getRemainingLength(void) const { return mLength-mOffset; }\n    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const;\n    virtual bool isAllocated(void) const { return mBuf != NULL; }\n\nprivate:\n    off64_t     mStart;         // absolute file offset of start of chunk\n    off64_t     mLength;        // length of the chunk\n    off64_t     mOffset;        // current local offset, 0 == mStart\n    FILE*       mFp;            // for read/seek\n    char*       mFileName;      // for opening\n\n    /*\n     * To support getBuffer() we either need to read the entire thing into\n     * a buffer or memory-map it.  For small files it's probably best to\n     * just read them in.\n     */\n    enum { kReadVsMapThreshold = 4096 };\n\n    FileMap*    mMap;           // for memory map\n    unsigned char* mBuf;        // for read\n    \n    const void* ensureAlignment(FileMap* map);\n};\n\n\n/*\n * An asset based on compressed data in a file.\n */\nclass _CompressedAsset : public Asset {\npublic:\n    _CompressedAsset(void);\n    virtual ~_CompressedAsset(void);\n\n    /*\n     * Use a piece of an already-open file.\n     *\n     * On success, the object takes ownership of \"fd\".\n     */\n    status_t openChunk(int fd, off64_t offset, int compressionMethod,\n        size_t uncompressedLen, size_t compressedLen);\n\n    /*\n     * Use a memory-mapped region.\n     *\n     * On success, the object takes ownership of \"fd\".\n     */\n    status_t openChunk(FileMap* dataMap, size_t uncompressedLen);\n\n    /*\n     * Standard Asset interfaces.\n     */\n    virtual ssize_t read(void* buf, size_t count);\n    virtual off64_t seek(off64_t offset, int whence);\n    virtual void close(void);\n    virtual const void* getBuffer(bool wordAligned);\n    virtual off64_t getLength(void) const { return mUncompressedLen; }\n    virtual off64_t getRemainingLength(void) const { return mUncompressedLen-mOffset; }\n    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const { return -1; }\n    virtual bool isAllocated(void) const { return mBuf != NULL; }\n\nprivate:\n    off64_t     mStart;         // offset to start of compressed data\n    off64_t     mCompressedLen; // length of the compressed data\n    off64_t     mUncompressedLen; // length of the uncompressed data\n    off64_t     mOffset;        // current offset, 0 == start of uncomp data\n\n    FileMap*    mMap;           // for memory-mapped input\n    int         mFd;            // for file input\n\n    class StreamingZipInflater* mZipInflater;  // for streaming large compressed assets\n\n    unsigned char*  mBuf;       // for getBuffer()\n};\n\n// need: shared mmap version?\n\n}; // namespace android\n\n#endif // __LIBS_ASSET_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/AssetDir.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Access a chunk of the asset hierarchy as if it were a single directory.\n//\n#ifndef __LIBS_ASSETDIR_H\n#define __LIBS_ASSETDIR_H\n\n#include <androidfw/misc.h>\n#include <utils/String8.h>\n#include <utils/Vector.h>\n#include <utils/SortedVector.h>\n#include <sys/types.h>\n\nnamespace android {\n\n/*\n * This provides vector-style access to a directory.  We do this rather\n * than modeling opendir/readdir access because it's simpler and the\n * nature of the operation requires us to have all data on hand anyway.\n *\n * The list of files will be sorted in ascending order by ASCII value.\n *\n * The contents are populated by our friend, the AssetManager.\n */\nclass AssetDir {\npublic:\n    AssetDir(void)\n        : mFileInfo(NULL)\n        {}\n    virtual ~AssetDir(void) {\n        delete mFileInfo;\n    }\n\n    /*\n     * Vector-style access.\n     */\n    size_t getFileCount(void) { return mFileInfo->size(); }\n    const String8& getFileName(int idx) {\n        return mFileInfo->itemAt(idx).getFileName();\n    }\n    const String8& getSourceName(int idx) {\n        return mFileInfo->itemAt(idx).getSourceName();\n    }\n\n    /*\n     * Get the type of a file (usually regular or directory).\n     */\n    FileType getFileType(int idx) {\n        return mFileInfo->itemAt(idx).getFileType();\n    }\n\nprivate:\n    /* these operations are not implemented */\n    AssetDir(const AssetDir& src);\n    const AssetDir& operator=(const AssetDir& src);\n\n    friend class AssetManager;\n\n    /*\n     * This holds information about files in the asset hierarchy.\n     */\n    class FileInfo {\n    public:\n        FileInfo(void) {}\n        FileInfo(const String8& path)      // useful for e.g. svect.indexOf\n            : mFileName(path), mFileType(kFileTypeUnknown)\n            {}\n        ~FileInfo(void) {}\n        FileInfo(const FileInfo& src) {\n            copyMembers(src);\n        }\n        const FileInfo& operator= (const FileInfo& src) {\n            if (this != &src)\n                copyMembers(src);\n            return *this;\n        }\n\n        void copyMembers(const FileInfo& src) {\n            mFileName = src.mFileName;\n            mFileType = src.mFileType;\n            mSourceName = src.mSourceName;\n        }\n\n        /* need this for SortedVector; must compare only on file name */\n        bool operator< (const FileInfo& rhs) const {\n            return mFileName < rhs.mFileName;\n        }\n\n        /* used by AssetManager */\n        bool operator== (const FileInfo& rhs) const {\n            return mFileName == rhs.mFileName;\n        }\n\n        void set(const String8& path, FileType type) {\n            mFileName = path;\n            mFileType = type;\n        }\n\n        const String8& getFileName(void) const { return mFileName; }\n        void setFileName(const String8& path) { mFileName = path; }\n\n        FileType getFileType(void) const { return mFileType; }\n        void setFileType(FileType type) { mFileType = type; }\n\n        const String8& getSourceName(void) const { return mSourceName; }\n        void setSourceName(const String8& path) { mSourceName = path; }\n\n        /*\n         * Handy utility for finding an entry in a sorted vector of FileInfo.\n         * Returns the index of the matching entry, or -1 if none found.\n         */\n        static int findEntry(const SortedVector<FileInfo>* pVector,\n            const String8& fileName);\n\n    private:\n        String8    mFileName;      // filename only\n        FileType    mFileType;      // regular, directory, etc\n\n        String8    mSourceName;    // currently debug-only\n    };\n\n    /* AssetManager uses this to initialize us */\n    void setFileList(SortedVector<FileInfo>* list) { mFileInfo = list; }\n\n    SortedVector<FileInfo>* mFileInfo;\n};\n\n}; // namespace android\n\n#endif // __LIBS_ASSETDIR_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/AssetManager.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Asset management class.  AssetManager objects are thread-safe.\n//\n#ifndef __LIBS_ASSETMANAGER_H\n#define __LIBS_ASSETMANAGER_H\n\n#include <androidfw/Asset.h>\n#include <androidfw/AssetDir.h>\n#include <androidfw/ZipFileRO.h>\n#include <utils/KeyedVector.h>\n#include <utils/SortedVector.h>\n#include <utils/String16.h>\n#include <utils/String8.h>\n#include <utils/threads.h>\n#include <utils/Vector.h>\n\n/*\n * Native-app access is via the opaque typedef struct AAssetManager in the C namespace.\n */\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct AAssetManager { };\n\n#ifdef __cplusplus\n};\n#endif\n\n\n/*\n * Now the proper C++ android-namespace definitions\n */\n\nnamespace android {\n\nclass Asset;        // fwd decl for things that include Asset.h first\nclass ResTable;\nstruct ResTable_config;\n\n/*\n * Every application that uses assets needs one instance of this.  A\n * single instance may be shared across multiple threads, and a single\n * thread may have more than one instance (the latter is discouraged).\n *\n * The purpose of the AssetManager is to create Asset objects.  To do\n * this efficiently it may cache information about the locations of\n * files it has seen.  This can be controlled with the \"cacheMode\"\n * argument.\n *\n * The asset hierarchy may be examined like a filesystem, using\n * AssetDir objects to peruse a single directory.\n */\nclass AssetManager : public AAssetManager {\npublic:\n    static const char* RESOURCES_FILENAME;\n    static const char* IDMAP_BIN;\n    static const char* OVERLAY_DIR;\n    static const char* TARGET_PACKAGE_NAME;\n    static const char* TARGET_APK_PATH;\n    static const char* IDMAP_DIR;\n\n    typedef enum CacheMode {\n        CACHE_UNKNOWN = 0,\n        CACHE_OFF,          // don't try to cache file locations\n        CACHE_DEFER,        // construct cache as pieces are needed\n        //CACHE_SCAN,         // scan full(!) asset hierarchy at init() time\n    } CacheMode;\n\n    AssetManager(CacheMode cacheMode = CACHE_OFF);\n    virtual ~AssetManager(void);\n\n    static int32_t getGlobalCount();\n    \n    /*                                                                       \n     * Add a new source for assets.  This can be called multiple times to\n     * look in multiple places for assets.  It can be either a directory (for\n     * finding assets as raw files on the disk) or a ZIP file.  This newly\n     * added asset path will be examined first when searching for assets,\n     * before any that were previously added, the assets are added as shared\n     * library if appAsLib is true.\n     *\n     * Returns \"true\" on success, \"false\" on failure.  If 'cookie' is non-NULL,\n     * then on success, *cookie is set to the value corresponding to the\n     * newly-added asset source.\n     */\n    bool addAssetPath(const String8& path, int32_t* cookie,\n        bool appAsLib=false, bool isSystemAsset=false);\n    bool addOverlayPath(const String8& path, int32_t* cookie);\n\n    /*\n     * Convenience for adding the standard system assets.  Uses the\n     * ANDROID_ROOT environment variable to find them.\n     */\n    bool addDefaultAssets();\n\n    /*\n     * Iterate over the asset paths in this manager.  (Previously\n     * added via addAssetPath() and addDefaultAssets().)  On first call,\n     * 'cookie' must be 0, resulting in the first cookie being returned.\n     * Each next cookie will be returned there-after, until -1 indicating\n     * the end has been reached.\n     */\n    int32_t nextAssetPath(const int32_t cookie) const;\n\n    /*\n     * Return an asset path in the manager.  'which' must be between 0 and\n     * countAssetPaths().\n     */\n    String8 getAssetPath(const int32_t cookie) const;\n\n    /*\n     * Set the current locale and vendor.  The locale can change during\n     * the lifetime of an AssetManager if the user updates the device's\n     * language setting.  The vendor is less likely to change.\n     *\n     * Pass in NULL to indicate no preference.\n     */\n    void setLocale(const char* locale);\n    void setVendor(const char* vendor);\n\n    /*\n     * Choose screen orientation for resources values returned.\n     */\n    void setConfiguration(const ResTable_config& config, const char* locale = NULL);\n\n    void getConfiguration(ResTable_config* outConfig) const;\n\n    typedef Asset::AccessMode AccessMode;       // typing shortcut\n\n    /*\n     * Open an asset.\n     *\n     * This will search through locale-specific and vendor-specific\n     * directories and packages to find the file.\n     *\n     * The object returned does not depend on the AssetManager.  It should\n     * be freed by calling Asset::close().\n     */\n    Asset* open(const char* fileName, AccessMode mode);\n\n    /*\n     * Open a non-asset file as an asset.\n     *\n     * This is for opening files that are included in an asset package\n     * but aren't assets.  These sit outside the usual \"locale/vendor\"\n     * path hierarchy, and will not be seen by \"AssetDir\" or included\n     * in our filename cache.\n     */\n    Asset* openNonAsset(const char* fileName, AccessMode mode, int32_t* outCookie = NULL);\n\n    /*\n     * Explicit non-asset file.  The file explicitly named by the cookie (the\n     * resource set to look in) and fileName will be opened and returned.\n     */\n    Asset* openNonAsset(const int32_t cookie, const char* fileName, AccessMode mode);\n\n    /*\n     * Open a directory within the asset hierarchy.\n     *\n     * The contents of the directory are an amalgam of vendor-specific,\n     * locale-specific, and generic assets stored loosely or in asset\n     * packages.  Depending on the cache setting and previous accesses,\n     * this call may incur significant disk overhead.\n     *\n     * To open the top-level directory, pass in \"\".\n     */\n    AssetDir* openDir(const char* dirName);\n\n    /*\n     * Open a directory within a particular path of the asset manager.\n     *\n     * The contents of the directory are an amalgam of vendor-specific,\n     * locale-specific, and generic assets stored loosely or in asset\n     * packages.  Depending on the cache setting and previous accesses,\n     * this call may incur significant disk overhead.\n     *\n     * To open the top-level directory, pass in \"\".\n     */\n    AssetDir* openNonAssetDir(const int32_t cookie, const char* dirName);\n\n    /*\n     * Get the type of a file in the asset hierarchy.  They will either\n     * be \"regular\" or \"directory\".  [Currently only works for \"regular\".]\n     *\n     * Can also be used as a quick test for existence of a file.\n     */\n    FileType getFileType(const char* fileName);\n\n    /*                                                                       \n     * Return the complete resource table to find things in the package.\n     */\n    const ResTable& getResources(bool required = true) const;\n\n    /*\n     * Discard cached filename information.  This only needs to be called\n     * if somebody has updated the set of \"loose\" files, and we want to\n     * discard our cached notion of what's where.\n     */\n    void purge(void) { purgeFileNameCacheLocked(); }\n\n    /*\n     * Return true if the files this AssetManager references are all\n     * up-to-date (have not been changed since it was created).  If false\n     * is returned, you will need to create a new AssetManager to get\n     * the current data.\n     */\n    bool isUpToDate();\n\n    /**\n     * Get the known locales for this asset manager object.\n     */\n    void getLocales(Vector<String8>* locales, bool includeSystemLocales=true) const;\n\n    /**\n     * Generate idmap data to translate resources IDs between a package and a\n     * corresponding overlay package.\n     */\n    bool createIdmap(const char* targetApkPath, const char* overlayApkPath,\n        uint32_t targetCrc, uint32_t overlayCrc, uint32_t** outData, size_t* outSize);\n\nprivate:\n    struct asset_path\n    {\n        asset_path() : path(\"\"), type(kFileTypeRegular), idmap(\"\"),\n                       isSystemOverlay(false), isSystemAsset(false) {}\n        String8 path;\n        FileType type;\n        String8 idmap;\n        bool isSystemOverlay;\n        bool isSystemAsset;\n    };\n\n    Asset* openInPathLocked(const char* fileName, AccessMode mode,\n        const asset_path& path);\n    Asset* openNonAssetInPathLocked(const char* fileName, AccessMode mode,\n        const asset_path& path);\n    Asset* openInLocaleVendorLocked(const char* fileName, AccessMode mode,\n        const asset_path& path, const char* locale, const char* vendor);\n    String8 createPathNameLocked(const asset_path& path, const char* locale,\n        const char* vendor);\n    String8 createPathNameLocked(const asset_path& path, const char* rootDir);\n    String8 createZipSourceNameLocked(const String8& zipFileName,\n        const String8& dirName, const String8& fileName);\n\n    ZipFileRO* getZipFileLocked(const asset_path& path);\n    Asset* openAssetFromFileLocked(const String8& fileName, AccessMode mode);\n    Asset* openAssetFromZipLocked(const ZipFileRO* pZipFile,\n        const ZipEntryRO entry, AccessMode mode, const String8& entryName);\n\n    bool scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n        const asset_path& path, const char* rootDir, const char* dirName);\n    SortedVector<AssetDir::FileInfo>* scanDirLocked(const String8& path);\n    bool scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n        const asset_path& path, const char* rootDir, const char* dirName);\n    void mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n        const SortedVector<AssetDir::FileInfo>* pContents);\n\n    void loadFileNameCacheLocked(void);\n    void fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n        const char* dirName);\n    bool fncScanAndMergeDirLocked(\n        SortedVector<AssetDir::FileInfo>* pMergedInfo,\n        const asset_path& path, const char* locale, const char* vendor,\n        const char* dirName);\n    void purgeFileNameCacheLocked(void);\n\n    const ResTable* getResTable(bool required = true) const;\n    void setLocaleLocked(const char* locale);\n    void updateResourceParamsLocked() const;\n    bool appendPathToResTable(const asset_path& ap, bool appAsLib=false) const;\n\n    Asset* openIdmapLocked(const struct asset_path& ap) const;\n\n    void addSystemOverlays(const char* pathOverlaysList, const String8& targetPackagePath,\n            ResTable* sharedRes, size_t offset) const;\n\n    class SharedZip : public RefBase {\n    public:\n        static sp<SharedZip> get(const String8& path, bool createIfNotPresent = true);\n\n        ZipFileRO* getZip();\n\n        Asset* getResourceTableAsset();\n        Asset* setResourceTableAsset(Asset* asset);\n\n        ResTable* getResourceTable();\n        ResTable* setResourceTable(ResTable* res);\n        \n        bool isUpToDate();\n\n        void addOverlay(const asset_path& ap);\n        bool getOverlay(size_t idx, asset_path* out) const;\n        \n    protected:\n        ~SharedZip();\n\n    private:\n        SharedZip(const String8& path, time_t modWhen);\n        SharedZip(); // <-- not implemented\n\n        String8 mPath;\n        ZipFileRO* mZipFile;\n        time_t mModWhen;\n\n        Asset* mResourceTableAsset;\n        ResTable* mResourceTable;\n\n        Vector<asset_path> mOverlays;\n\n        static Mutex gLock;\n        static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;\n    };\n\n    /*\n     * Manage a set of Zip files.  For each file we need a pointer to the\n     * ZipFile and a time_t with the file's modification date.\n     *\n     * We currently only have two zip files (current app, \"common\" app).\n     * (This was originally written for 8, based on app/locale/vendor.)\n     */\n    class ZipSet {\n    public:\n        ZipSet(void);\n        ~ZipSet(void);\n\n        /*\n         * Return a ZipFileRO structure for a ZipFileRO with the specified\n         * parameters.\n         */\n        ZipFileRO* getZip(const String8& path);\n\n        Asset* getZipResourceTableAsset(const String8& path);\n        Asset* setZipResourceTableAsset(const String8& path, Asset* asset);\n\n        ResTable* getZipResourceTable(const String8& path);\n        ResTable* setZipResourceTable(const String8& path, ResTable* res);\n\n        // generate path, e.g. \"common/en-US-noogle.zip\"\n        static String8 getPathName(const char* path);\n\n        bool isUpToDate();\n\n        void addOverlay(const String8& path, const asset_path& overlay);\n        bool getOverlay(const String8& path, size_t idx, asset_path* out) const;\n        \n    private:\n        void closeZip(int idx);\n\n        int getIndex(const String8& zip) const;\n        mutable Vector<String8> mZipPath;\n        mutable Vector<sp<SharedZip> > mZipFile;\n    };\n\n    // Protect all internal state.\n    mutable Mutex   mLock;\n\n    ZipSet          mZipSet;\n\n    Vector<asset_path> mAssetPaths;\n    char*           mLocale;\n    char*           mVendor;\n\n    mutable ResTable* mResources;\n    ResTable_config* mConfig;\n\n    /*\n     * Cached data for \"loose\" files.  This lets us avoid poking at the\n     * filesystem when searching for loose assets.  Each entry is the\n     * \"extended partial\" path, e.g. \"default/default/foo/bar.txt\".  The\n     * full set of files is present, including \".EXCLUDE\" entries.\n     *\n     * We do not cache directory names.  We don't retain the \".gz\",\n     * because to our clients \"foo\" and \"foo.gz\" both look like \"foo\".\n     */\n    CacheMode       mCacheMode;         // is the cache enabled?\n    bool            mCacheValid;        // clear when locale or vendor changes\n    SortedVector<AssetDir::FileInfo> mCache;\n};\n\n}; // namespace android\n\n#endif // __LIBS_ASSETMANAGER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/AttributeFinder.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef H_ATTRIBUTE_FINDER\n#define H_ATTRIBUTE_FINDER\n\n#include <stdint.h>\n#include <utils/KeyedVector.h>\n\nnamespace android {\n\nstatic inline uint32_t getPackage(uint32_t attr) {\n    return attr >> 24;\n}\n\n/**\n * A helper class to search linearly for the requested\n * attribute, maintaining it's position and optimizing for\n * the case that subsequent searches will involve an attribute with\n * a higher attribute ID.\n *\n * In the case that a subsequent attribute has a different package ID,\n * its resource ID may not be larger than the preceding search, so\n * back tracking is supported for this case. This\n * back tracking requirement is mainly for shared library\n * resources, whose package IDs get assigned at runtime\n * and thus attributes from a shared library may\n * be out of order.\n *\n * We make two assumptions about the order of attributes:\n * 1) The input has the same sorting rules applied to it as\n *    the attribute data contained by this class.\n * 2) Attributes are grouped by package ID.\n * 3) Among attributes with the same package ID, the attributes are\n *    sorted by increasing resource ID.\n *\n * Ex: 02010000, 02010001, 010100f4, 010100f5, 0x7f010001, 07f010003\n *\n * The total order of attributes (including package ID) can not be linear\n * as shared libraries get assigned dynamic package IDs at runtime, which\n * may break the sort order established at build time.\n */\ntemplate <typename Derived, typename Iterator>\nclass BackTrackingAttributeFinder {\npublic:\n    BackTrackingAttributeFinder(const Iterator& begin, const Iterator& end);\n\n    Iterator find(uint32_t attr);\n\nprivate:\n    void jumpToClosestAttribute(uint32_t packageId);\n    void markCurrentPackageId(uint32_t packageId);\n\n    bool mFirstTime;\n    Iterator mBegin;\n    Iterator mEnd;\n    Iterator mCurrent;\n    Iterator mLargest;\n    uint32_t mLastPackageId;\n    uint32_t mCurrentAttr;\n\n    // Package Offsets (best-case, fast look-up).\n    Iterator mFrameworkStart;\n    Iterator mAppStart;\n\n    // Worst case, we have shared-library resources.\n    KeyedVector<uint32_t, Iterator> mPackageOffsets;\n};\n\ntemplate <typename Derived, typename Iterator> inline\nBackTrackingAttributeFinder<Derived, Iterator>::BackTrackingAttributeFinder(const Iterator& begin, const Iterator& end)\n    : mFirstTime(true)\n    , mBegin(begin)\n    , mEnd(end)\n    , mCurrent(begin)\n    , mLargest(begin)\n    , mLastPackageId(0)\n    , mCurrentAttr(0)\n    , mFrameworkStart(end)\n    , mAppStart(end) {\n}\n\ntemplate <typename Derived, typename Iterator>\nvoid BackTrackingAttributeFinder<Derived, Iterator>::jumpToClosestAttribute(const uint32_t packageId) {\n    switch (packageId) {\n        case 0x01:\n            mCurrent = mFrameworkStart;\n            break;\n        case 0x7f:\n            mCurrent = mAppStart;\n            break;\n        default: {\n            ssize_t idx = mPackageOffsets.indexOfKey(packageId);\n            if (idx >= 0) {\n                // We have seen this package ID before, so jump to the first\n                // attribute with this package ID.\n                mCurrent = mPackageOffsets[idx];\n            } else {\n                mCurrent = mEnd;\n            }\n            break;\n        }\n    }\n\n    // We have never seen this package ID yet, so jump to the\n    // latest/largest index we have processed so far.\n    if (mCurrent == mEnd) {\n        mCurrent = mLargest;\n    }\n\n    if (mCurrent != mEnd) {\n        mCurrentAttr = static_cast<const Derived*>(this)->getAttribute(mCurrent);\n    }\n}\n\ntemplate <typename Derived, typename Iterator>\nvoid BackTrackingAttributeFinder<Derived, Iterator>::markCurrentPackageId(const uint32_t packageId) {\n    switch (packageId) {\n        case 0x01:\n            mFrameworkStart = mCurrent;\n            break;\n        case 0x7f:\n            mAppStart = mCurrent;\n            break;\n        default:\n            mPackageOffsets.add(packageId, mCurrent);\n            break;\n    }\n}\n\ntemplate <typename Derived, typename Iterator>\nIterator BackTrackingAttributeFinder<Derived, Iterator>::find(uint32_t attr) {\n    if (!(mBegin < mEnd)) {\n        return mEnd;\n    }\n\n    if (mFirstTime) {\n        // One-time initialization. We do this here instead of the constructor\n        // because the derived class we access in getAttribute() may not be\n        // fully constructed.\n        mFirstTime = false;\n        mCurrentAttr = static_cast<const Derived*>(this)->getAttribute(mBegin);\n        mLastPackageId = getPackage(mCurrentAttr);\n        markCurrentPackageId(mLastPackageId);\n    }\n\n    // Looking for the needle (attribute we're looking for)\n    // in the haystack (the attributes we're searching through)\n    const uint32_t needlePackageId = getPackage(attr);\n    if (mLastPackageId != needlePackageId) {\n        jumpToClosestAttribute(needlePackageId);\n        mLastPackageId = needlePackageId;\n    }\n\n    // Walk through the xml attributes looking for the requested attribute.\n    while (mCurrent != mEnd) {\n        const uint32_t haystackPackageId = getPackage(mCurrentAttr);\n        if (needlePackageId == haystackPackageId && attr < mCurrentAttr) {\n            // The attribute we are looking was not found.\n            break;\n        }\n        const uint32_t prevAttr = mCurrentAttr;\n\n        // Move to the next attribute in the XML.\n        ++mCurrent;\n        if (mCurrent != mEnd) {\n            mCurrentAttr = static_cast<const Derived*>(this)->getAttribute(mCurrent);\n            const uint32_t newHaystackPackageId = getPackage(mCurrentAttr);\n            if (haystackPackageId != newHaystackPackageId) {\n                // We've moved to the next group of attributes\n                // with a new package ID, so we should record\n                // the offset of this new package ID.\n                markCurrentPackageId(newHaystackPackageId);\n            }\n        }\n\n        if (mCurrent > mLargest) {\n            // We've moved past the latest attribute we've\n            // seen.\n            mLargest = mCurrent;\n        }\n\n        if (attr == prevAttr) {\n            // We found the attribute we were looking for.\n            return mCurrent - 1;\n        }\n    }\n    return mEnd;\n}\n\n} // namespace android\n\n#endif // H_ATTRIBUTE_FINDER\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/BackupHelpers.h",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _UTILS_BACKUP_HELPERS_H\n#define _UTILS_BACKUP_HELPERS_H\n\n#include <sys/stat.h>\n\n#include <utils/Errors.h>\n#include <utils/String8.h>\n#include <utils/KeyedVector.h>\n\nnamespace android {\n\nenum {\n    BACKUP_HEADER_ENTITY_V1 = 0x61746144, // Data (little endian)\n};\n\ntypedef struct {\n    int type; // BACKUP_HEADER_ENTITY_V1\n    int keyLen; // length of the key name, not including the null terminator\n    int dataSize; // size of the data, not including the padding, -1 means delete\n} entity_header_v1;\n\nstruct SnapshotHeader {\n    int magic0;\n    int fileCount;\n    int magic1;\n    int totalSize;\n};\n\nstruct FileState {\n    int modTime_sec;\n    int modTime_nsec;\n    int mode;\n    int size;\n    int crc32;\n    int nameLen;\n};\n\nstruct FileRec {\n    String8 file;\n    bool deleted;\n    FileState s;\n};\n\n\n/**\n * Writes the data.\n *\n * If an error occurs, it poisons this object and all write calls will fail\n * with the error that occurred.\n */\nclass BackupDataWriter\n{\npublic:\n    BackupDataWriter(int fd);\n    // does not close fd\n    ~BackupDataWriter();\n\n    status_t WriteEntityHeader(const String8& key, size_t dataSize);\n\n    /* Note: WriteEntityData will write arbitrary data into the file without\n     * validation or a previously-supplied header.  The full backup implementation\n     * uses it this way to generate a controlled binary stream that is not\n     * entity-structured.  If the implementation here is changed, either this\n     * use case must remain valid, or the full backup implementation should be\n     * adjusted to use some other appropriate mechanism.\n     */\n    status_t WriteEntityData(const void* data, size_t size);\n\n    void SetKeyPrefix(const String8& keyPrefix);\n\nprivate:\n    explicit BackupDataWriter();\n    status_t write_padding_for(int n);\n    \n    int m_fd;\n    status_t m_status;\n    ssize_t m_pos;\n    int m_entityCount;\n    String8 m_keyPrefix;\n};\n\n/**\n * Reads the data.\n *\n * If an error occurs, it poisons this object and all write calls will fail\n * with the error that occurred.\n */\nclass BackupDataReader\n{\npublic:\n    BackupDataReader(int fd);\n    // does not close fd\n    ~BackupDataReader();\n\n    status_t Status();\n    status_t ReadNextHeader(bool* done, int* type);\n\n    bool HasEntities();\n    status_t ReadEntityHeader(String8* key, size_t* dataSize);\n    status_t SkipEntityData(); // must be called with the pointer at the beginning of the data.\n    ssize_t ReadEntityData(void* data, size_t size);\n\nprivate:\n    explicit BackupDataReader();\n    status_t skip_padding();\n    \n    int m_fd;\n    bool m_done;\n    status_t m_status;\n    ssize_t m_pos;\n    ssize_t m_dataEndPos;\n    int m_entityCount;\n    union {\n        int type;\n        entity_header_v1 entity;\n    } m_header;\n    String8 m_key;\n};\n\nint back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,\n        char const* const* files, char const* const *keys, int fileCount);\n\nint write_tarfile(const String8& packageName, const String8& domain,\n        const String8& rootPath, const String8& filePath, off_t* outSize,\n        BackupDataWriter* outputStream);\n\nclass RestoreHelperBase\n{\npublic:\n    RestoreHelperBase();\n    ~RestoreHelperBase();\n\n    status_t WriteFile(const String8& filename, BackupDataReader* in);\n    status_t WriteSnapshot(int fd);\n\nprivate:\n    void* m_buf;\n    bool m_loggedUnknownMetadata;\n    KeyedVector<String8,FileRec> m_files;\n};\n\n//#define TEST_BACKUP_HELPERS 1\n\n#if TEST_BACKUP_HELPERS\nint backup_helper_test_empty();\nint backup_helper_test_four();\nint backup_helper_test_files();\nint backup_helper_test_null_base();\nint backup_helper_test_missing_file();\nint backup_helper_test_data_writer();\nint backup_helper_test_data_reader();\n#endif\n\n} // namespace android\n\n#endif // _UTILS_BACKUP_HELPERS_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/ByteBucketArray.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __BYTE_BUCKET_ARRAY_H\n#define __BYTE_BUCKET_ARRAY_H\n\n#include <utils/Log.h>\n#include <stdint.h>\n#include <string.h>\n\nnamespace android {\n\n/**\n * Stores a sparsely populated array. Has a fixed size of 256\n * (number of entries that a byte can represent).\n */\ntemplate<typename T>\nclass ByteBucketArray {\npublic:\n    ByteBucketArray() : mDefault() {\n        memset(mBuckets, 0, sizeof(mBuckets));\n    }\n\n    ~ByteBucketArray() {\n        for (size_t i = 0; i < NUM_BUCKETS; i++) {\n            if (mBuckets[i] != NULL) {\n                delete [] mBuckets[i];\n            }\n        }\n        memset(mBuckets, 0, sizeof(mBuckets));\n    }\n\n    inline size_t size() const {\n        return NUM_BUCKETS * BUCKET_SIZE;\n    }\n\n    inline const T& get(size_t index) const {\n        return (*this)[index];\n    }\n\n    const T& operator[](size_t index) const {\n        if (index >= size()) {\n            return mDefault;\n        }\n\n        uint8_t bucketIndex = static_cast<uint8_t>(index) >> 4;\n        T* bucket = mBuckets[bucketIndex];\n        if (bucket == NULL) {\n            return mDefault;\n        }\n        return bucket[0x0f & static_cast<uint8_t>(index)];\n    }\n\n    T& editItemAt(size_t index) {\n        ALOG_ASSERT(index < size(), \"ByteBucketArray.getOrCreate(index=%u) with size=%u\",\n                (uint32_t) index, (uint32_t) size());\n\n        uint8_t bucketIndex = static_cast<uint8_t>(index) >> 4;\n        T* bucket = mBuckets[bucketIndex];\n        if (bucket == NULL) {\n            bucket = mBuckets[bucketIndex] = new T[BUCKET_SIZE]();\n        }\n        return bucket[0x0f & static_cast<uint8_t>(index)];\n    }\n\n    bool set(size_t index, const T& value) {\n        if (index >= size()) {\n            return false;\n        }\n\n        editItemAt(index) = value;\n        return true;\n    }\n\nprivate:\n    enum { NUM_BUCKETS = 16, BUCKET_SIZE = 16 };\n\n    T*  mBuckets[NUM_BUCKETS];\n    T   mDefault;\n};\n\n} // namespace android\n\n#endif // __BYTE_BUCKET_ARRAY_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/CursorWindow.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _ANDROID__DATABASE_WINDOW_H\n#define _ANDROID__DATABASE_WINDOW_H\n\n#include <cutils/log.h>\n#include <stddef.h>\n#include <stdint.h>\n\n#include <binder/Parcel.h>\n#include <utils/String8.h>\n\n#if LOG_NDEBUG\n\n#define IF_LOG_WINDOW() if (false)\n#define LOG_WINDOW(...)\n\n#else\n\n#define IF_LOG_WINDOW() IF_ALOG(LOG_DEBUG, \"CursorWindow\")\n#define LOG_WINDOW(...) ALOG(LOG_DEBUG, \"CursorWindow\", __VA_ARGS__)\n\n#endif\n\nnamespace android {\n\n/**\n * This class stores a set of rows from a database in a buffer. The begining of the\n * window has first chunk of RowSlots, which are offsets to the row directory, followed by\n * an offset to the next chunk in a linked-list of additional chunk of RowSlots in case\n * the pre-allocated chunk isn't big enough to refer to all rows. Each row directory has a\n * FieldSlot per column, which has the size, offset, and type of the data for that field.\n * Note that the data types come from sqlite3.h.\n *\n * Strings are stored in UTF-8.\n */\nclass CursorWindow {\n    CursorWindow(const String8& name, int ashmemFd,\n            void* data, size_t size, bool readOnly);\n\npublic:\n    /* Field types. */\n    enum {\n        FIELD_TYPE_NULL = 0,\n        FIELD_TYPE_INTEGER = 1,\n        FIELD_TYPE_FLOAT = 2,\n        FIELD_TYPE_STRING = 3,\n        FIELD_TYPE_BLOB = 4,\n    };\n\n    /* Opaque type that describes a field slot. */\n    struct FieldSlot {\n    private:\n        int32_t type;\n        union {\n            double d;\n            int64_t l;\n            struct {\n                uint32_t offset;\n                uint32_t size;\n            } buffer;\n        } data;\n\n        friend class CursorWindow;\n    } __attribute((packed));\n\n    ~CursorWindow();\n\n    static status_t create(const String8& name, size_t size, CursorWindow** outCursorWindow);\n    static status_t createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow);\n\n    status_t writeToParcel(Parcel* parcel);\n\n    inline String8 name() { return mName; }\n    inline size_t size() { return mSize; }\n    inline size_t freeSpace() { return mSize - mHeader->freeOffset; }\n    inline uint32_t getNumRows() { return mHeader->numRows; }\n    inline uint32_t getNumColumns() { return mHeader->numColumns; }\n\n    status_t clear();\n    status_t setNumColumns(uint32_t numColumns);\n\n    /**\n     * Allocate a row slot and its directory.\n     * The row is initialized will null entries for each field.\n     */\n    status_t allocRow();\n    status_t freeLastRow();\n\n    status_t putBlob(uint32_t row, uint32_t column, const void* value, size_t size);\n    status_t putString(uint32_t row, uint32_t column, const char* value, size_t sizeIncludingNull);\n    status_t putLong(uint32_t row, uint32_t column, int64_t value);\n    status_t putDouble(uint32_t row, uint32_t column, double value);\n    status_t putNull(uint32_t row, uint32_t column);\n\n    /**\n     * Gets the field slot at the specified row and column.\n     * Returns null if the requested row or column is not in the window.\n     */\n    FieldSlot* getFieldSlot(uint32_t row, uint32_t column);\n\n    inline int32_t getFieldSlotType(FieldSlot* fieldSlot) {\n        return fieldSlot->type;\n    }\n\n    inline int64_t getFieldSlotValueLong(FieldSlot* fieldSlot) {\n        return fieldSlot->data.l;\n    }\n\n    inline double getFieldSlotValueDouble(FieldSlot* fieldSlot) {\n        return fieldSlot->data.d;\n    }\n\n    inline const char* getFieldSlotValueString(FieldSlot* fieldSlot,\n            size_t* outSizeIncludingNull) {\n        *outSizeIncludingNull = fieldSlot->data.buffer.size;\n        return static_cast<char*>(offsetToPtr(fieldSlot->data.buffer.offset));\n    }\n\n    inline const void* getFieldSlotValueBlob(FieldSlot* fieldSlot, size_t* outSize) {\n        *outSize = fieldSlot->data.buffer.size;\n        return offsetToPtr(fieldSlot->data.buffer.offset);\n    }\n\nprivate:\n    static const size_t ROW_SLOT_CHUNK_NUM_ROWS = 100;\n\n    struct Header {\n        // Offset of the lowest unused byte in the window.\n        uint32_t freeOffset;\n\n        // Offset of the first row slot chunk.\n        uint32_t firstChunkOffset;\n\n        uint32_t numRows;\n        uint32_t numColumns;\n    };\n\n    struct RowSlot {\n        uint32_t offset;\n    };\n\n    struct RowSlotChunk {\n        RowSlot slots[ROW_SLOT_CHUNK_NUM_ROWS];\n        uint32_t nextChunkOffset;\n    };\n\n    String8 mName;\n    int mAshmemFd;\n    void* mData;\n    size_t mSize;\n    bool mReadOnly;\n    Header* mHeader;\n\n    inline void* offsetToPtr(uint32_t offset) {\n        return static_cast<uint8_t*>(mData) + offset;\n    }\n\n    inline uint32_t offsetFromPtr(void* ptr) {\n        return static_cast<uint8_t*>(ptr) - static_cast<uint8_t*>(mData);\n    }\n\n    /**\n     * Allocate a portion of the window. Returns the offset\n     * of the allocation, or 0 if there isn't enough space.\n     * If aligned is true, the allocation gets 4 byte alignment.\n     */\n    uint32_t alloc(size_t size, bool aligned = false);\n\n    RowSlot* getRowSlot(uint32_t row);\n    RowSlot* allocRowSlot();\n\n    status_t putBlobOrString(uint32_t row, uint32_t column,\n            const void* value, size_t size, int32_t type);\n};\n\n}; // namespace android\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/DisplayEventDispatcher.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <gui/DisplayEventReceiver.h>\n#include <utils/Log.h>\n#include <utils/Looper.h>\n\nnamespace android {\n\nclass DisplayEventDispatcher : public LooperCallback {\npublic:\n    DisplayEventDispatcher(const sp<Looper>& looper);\n\n    status_t initialize();\n    void dispose();\n    status_t scheduleVsync();\n\nprotected:\n    virtual ~DisplayEventDispatcher() = default;\n\nprivate:\n    sp<Looper> mLooper;\n    DisplayEventReceiver mReceiver;\n    bool mWaitingForVsync;\n\n    virtual void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) = 0;\n    virtual void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected) = 0;\n\n    virtual int handleEvent(int receiveFd, int events, void* data);\n    bool processPendingEvents(nsecs_t* outTimestamp, int32_t* id, uint32_t* outCount);\n};\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/LocaleData.h",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBS_UTILS_LOCALE_DATA_H\n#define _LIBS_UTILS_LOCALE_DATA_H\n\n#include <stddef.h>\n#include <stdint.h>\n\nnamespace android {\n\nint localeDataCompareRegions(\n        const char* left_region, const char* right_region,\n        const char* requested_language, const char* requested_script,\n        const char* requested_region);\n\nvoid localeDataComputeScript(char out[4], const char* language, const char* region);\n\nbool localeDataIsCloseToUsEnglish(const char* region);\n\n} // namespace android\n\n#endif // _LIBS_UTILS_LOCALE_DATA_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/ObbFile.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef OBBFILE_H_\n#define OBBFILE_H_\n\n#include <stdint.h>\n#include <strings.h>\n\n#include <utils/RefBase.h>\n#include <utils/String8.h>\n\nnamespace android {\n\n// OBB flags (bit 0)\n#define OBB_OVERLAY         (1 << 0)\n#define OBB_SALTED          (1 << 1)\n\nclass ObbFile : public RefBase {\nprotected:\n    virtual ~ObbFile();\n\npublic:\n    ObbFile();\n\n    bool readFrom(const char* filename);\n    bool readFrom(int fd);\n    bool writeTo(const char* filename);\n    bool writeTo(int fd);\n    bool removeFrom(const char* filename);\n    bool removeFrom(int fd);\n\n    const char* getFileName() const {\n        return mFileName;\n    }\n\n    const String8 getPackageName() const {\n        return mPackageName;\n    }\n\n    void setPackageName(String8 packageName) {\n        mPackageName = packageName;\n    }\n\n    int32_t getVersion() const {\n        return mVersion;\n    }\n\n    void setVersion(int32_t version) {\n        mVersion = version;\n    }\n\n    int32_t getFlags() const {\n        return mFlags;\n    }\n\n    void setFlags(int32_t flags) {\n        mFlags = flags;\n    }\n\n    const unsigned char* getSalt(size_t* length) const {\n        if ((mFlags & OBB_SALTED) == 0) {\n            *length = 0;\n            return NULL;\n        }\n\n        *length = sizeof(mSalt);\n        return mSalt;\n    }\n\n    bool setSalt(const unsigned char* salt, size_t length) {\n        if (length != sizeof(mSalt)) {\n            return false;\n        }\n\n        memcpy(mSalt, salt, sizeof(mSalt));\n        mFlags |= OBB_SALTED;\n        return true;\n    }\n\n    bool isOverlay() {\n        return (mFlags & OBB_OVERLAY) == OBB_OVERLAY;\n    }\n\n    void setOverlay(bool overlay) {\n        if (overlay) {\n            mFlags |= OBB_OVERLAY;\n        } else {\n            mFlags &= ~OBB_OVERLAY;\n        }\n    }\n\n    static inline uint32_t get4LE(const unsigned char* buf) {\n        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);\n    }\n\n    static inline void put4LE(unsigned char* buf, uint32_t val) {\n        buf[0] = val & 0xFF;\n        buf[1] = (val >> 8) & 0xFF;\n        buf[2] = (val >> 16) & 0xFF;\n        buf[3] = (val >> 24) & 0xFF;\n    }\n\nprivate:\n    /* Package name this ObbFile is associated with */\n    String8 mPackageName;\n\n    /* Package version this ObbFile is associated with */\n    int32_t mVersion;\n\n    /* Flags for this OBB type. */\n    int32_t mFlags;\n\n    /* Whether the file is salted. */\n    bool mSalted;\n\n    /* The encryption salt. */\n    unsigned char mSalt[8];\n\n    const char* mFileName;\n\n    size_t mFileSize;\n\n    size_t mFooterStart;\n\n    unsigned char* mReadBuf;\n\n    bool parseObbFile(int fd);\n};\n\n}\n#endif /* OBBFILE_H_ */\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/ResourcePackageId.h",
    "content": "#ifndef __ResourcePackageId__\n#define __ResourcePackageId__\nextern size_t customePackageId;\nextern char* sktPackageName;\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/ResourceTypes.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Definitions of resource data structures.\n//\n#ifndef _LIBS_UTILS_RESOURCE_TYPES_H\n#define _LIBS_UTILS_RESOURCE_TYPES_H\n\n#include <androidfw/Asset.h>\n#include <androidfw/LocaleData.h>\n#include <utils/ByteOrder.h>\n#include <utils/Errors.h>\n#include <utils/String16.h>\n#include <utils/Vector.h>\n#include <utils/KeyedVector.h>\n\n#include <utils/threads.h>\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <android/configuration.h>\n\n#include <memory>\n\nnamespace android {\n\n/**\n * In C++11, char16_t is defined as *at least* 16 bits. We do a lot of\n * casting on raw data and expect char16_t to be exactly 16 bits.\n */\n#if __cplusplus >= 201103L\nstruct __assertChar16Size {\n    static_assert(sizeof(char16_t) == sizeof(uint16_t), \"char16_t is not 16 bits\");\n    static_assert(alignof(char16_t) == alignof(uint16_t), \"char16_t is not 16-bit aligned\");\n};\n#endif\n\n/** ********************************************************************\n *  PNG Extensions\n *\n *  New private chunks that may be placed in PNG images.\n *\n *********************************************************************** */\n\n/**\n * This chunk specifies how to split an image into segments for\n * scaling.\n *\n * There are J horizontal and K vertical segments.  These segments divide\n * the image into J*K regions as follows (where J=4 and K=3):\n *\n *      F0   S0    F1     S1\n *   +-----+----+------+-------+\n * S2|  0  |  1 |  2   |   3   |\n *   +-----+----+------+-------+\n *   |     |    |      |       |\n *   |     |    |      |       |\n * F2|  4  |  5 |  6   |   7   |\n *   |     |    |      |       |\n *   |     |    |      |       |\n *   +-----+----+------+-------+\n * S3|  8  |  9 |  10  |   11  |\n *   +-----+----+------+-------+\n *\n * Each horizontal and vertical segment is considered to by either\n * stretchable (marked by the Sx labels) or fixed (marked by the Fy\n * labels), in the horizontal or vertical axis, respectively. In the\n * above example, the first is horizontal segment (F0) is fixed, the\n * next is stretchable and then they continue to alternate. Note that\n * the segment list for each axis can begin or end with a stretchable\n * or fixed segment.\n *\n * The relative sizes of the stretchy segments indicates the relative\n * amount of stretchiness of the regions bordered by the segments.  For\n * example, regions 3, 7 and 11 above will take up more horizontal space\n * than regions 1, 5 and 9 since the horizontal segment associated with\n * the first set of regions is larger than the other set of regions.  The\n * ratios of the amount of horizontal (or vertical) space taken by any\n * two stretchable slices is exactly the ratio of their corresponding\n * segment lengths.\n *\n * xDivs and yDivs are arrays of horizontal and vertical pixel\n * indices.  The first pair of Divs (in either array) indicate the\n * starting and ending points of the first stretchable segment in that\n * axis. The next pair specifies the next stretchable segment, etc. So\n * in the above example xDiv[0] and xDiv[1] specify the horizontal\n * coordinates for the regions labeled 1, 5 and 9.  xDiv[2] and\n * xDiv[3] specify the coordinates for regions 3, 7 and 11. Note that\n * the leftmost slices always start at x=0 and the rightmost slices\n * always end at the end of the image. So, for example, the regions 0,\n * 4 and 8 (which are fixed along the X axis) start at x value 0 and\n * go to xDiv[0] and slices 2, 6 and 10 start at xDiv[1] and end at\n * xDiv[2].\n *\n * The colors array contains hints for each of the regions. They are\n * ordered according left-to-right and top-to-bottom as indicated above.\n * For each segment that is a solid color the array entry will contain\n * that color value; otherwise it will contain NO_COLOR. Segments that\n * are completely transparent will always have the value TRANSPARENT_COLOR.\n *\n * The PNG chunk type is \"npTc\".\n */\nstruct alignas(uintptr_t) Res_png_9patch\n{\n    Res_png_9patch() : wasDeserialized(false), xDivsOffset(0),\n                       yDivsOffset(0), colorsOffset(0) { }\n\n    int8_t wasDeserialized;\n    uint8_t numXDivs;\n    uint8_t numYDivs;\n    uint8_t numColors;\n\n    // The offset (from the start of this structure) to the xDivs & yDivs\n    // array for this 9patch. To get a pointer to this array, call\n    // getXDivs or getYDivs. Note that the serialized form for 9patches places\n    // the xDivs, yDivs and colors arrays immediately after the location\n    // of the Res_png_9patch struct.\n    uint32_t xDivsOffset;\n    uint32_t yDivsOffset;\n\n    int32_t paddingLeft, paddingRight;\n    int32_t paddingTop, paddingBottom;\n\n    enum {\n        // The 9 patch segment is not a solid color.\n        NO_COLOR = 0x00000001,\n\n        // The 9 patch segment is completely transparent.\n        TRANSPARENT_COLOR = 0x00000000\n    };\n\n    // The offset (from the start of this structure) to the colors array\n    // for this 9patch.\n    uint32_t colorsOffset;\n\n    // Convert data from device representation to PNG file representation.\n    void deviceToFile();\n    // Convert data from PNG file representation to device representation.\n    void fileToDevice();\n\n    // Serialize/Marshall the patch data into a newly malloc-ed block.\n    static void* serialize(const Res_png_9patch& patchHeader, const int32_t* xDivs,\n                           const int32_t* yDivs, const uint32_t* colors);\n    // Serialize/Marshall the patch data into |outData|.\n    static void serialize(const Res_png_9patch& patchHeader, const int32_t* xDivs,\n                           const int32_t* yDivs, const uint32_t* colors, void* outData);\n    // Deserialize/Unmarshall the patch data\n    static Res_png_9patch* deserialize(void* data);\n    // Compute the size of the serialized data structure\n    size_t serializedSize() const;\n\n    // These tell where the next section of a patch starts.\n    // For example, the first patch includes the pixels from\n    // 0 to xDivs[0]-1 and the second patch includes the pixels\n    // from xDivs[0] to xDivs[1]-1.\n    inline int32_t* getXDivs() const {\n        return reinterpret_cast<int32_t*>(reinterpret_cast<uintptr_t>(this) + xDivsOffset);\n    }\n    inline int32_t* getYDivs() const {\n        return reinterpret_cast<int32_t*>(reinterpret_cast<uintptr_t>(this) + yDivsOffset);\n    }\n    inline uint32_t* getColors() const {\n        return reinterpret_cast<uint32_t*>(reinterpret_cast<uintptr_t>(this) + colorsOffset);\n    }\n\n} __attribute__((packed));\n\n/** ********************************************************************\n *  Base Types\n *\n *  These are standard types that are shared between multiple specific\n *  resource types.\n *\n *********************************************************************** */\n\n/**\n * Header that appears at the front of every data chunk in a resource.\n */\nstruct ResChunk_header\n{\n    // Type identifier for this chunk.  The meaning of this value depends\n    // on the containing chunk.\n    uint16_t type;\n\n    // Size of the chunk header (in bytes).  Adding this value to\n    // the address of the chunk allows you to find its associated data\n    // (if any).\n    uint16_t headerSize;\n\n    // Total size of this chunk (in bytes).  This is the chunkSize plus\n    // the size of any data associated with the chunk.  Adding this value\n    // to the chunk allows you to completely skip its contents (including\n    // any child chunks).  If this value is the same as chunkSize, there is\n    // no data associated with the chunk.\n    uint32_t size;\n};\n\nenum {\n    RES_NULL_TYPE               = 0x0000,\n    RES_STRING_POOL_TYPE        = 0x0001,\n    RES_TABLE_TYPE              = 0x0002,\n    RES_XML_TYPE                = 0x0003,\n\n    // Chunk types in RES_XML_TYPE\n    RES_XML_FIRST_CHUNK_TYPE    = 0x0100,\n    RES_XML_START_NAMESPACE_TYPE= 0x0100,\n    RES_XML_END_NAMESPACE_TYPE  = 0x0101,\n    RES_XML_START_ELEMENT_TYPE  = 0x0102,\n    RES_XML_END_ELEMENT_TYPE    = 0x0103,\n    RES_XML_CDATA_TYPE          = 0x0104,\n    RES_XML_LAST_CHUNK_TYPE     = 0x017f,\n    // This contains a uint32_t array mapping strings in the string\n    // pool back to resource identifiers.  It is optional.\n    RES_XML_RESOURCE_MAP_TYPE   = 0x0180,\n\n    // Chunk types in RES_TABLE_TYPE\n    RES_TABLE_PACKAGE_TYPE      = 0x0200,\n    RES_TABLE_TYPE_TYPE         = 0x0201,\n    RES_TABLE_TYPE_SPEC_TYPE    = 0x0202,\n    RES_TABLE_LIBRARY_TYPE      = 0x0203\n};\n\n/**\n * Macros for building/splitting resource identifiers.\n */\n#define Res_VALIDID(resid) (resid != 0)\n#define Res_CHECKID(resid) ((resid&0xFFFF0000) != 0)\n#define Res_MAKEID(package, type, entry) \\\n    (((package+1)<<24) | (((type+1)&0xFF)<<16) | (entry&0xFFFF))\n#define Res_GETPACKAGE(id) ((id>>24)-1)\n#define Res_GETTYPE(id) (((id>>16)&0xFF)-1)\n#define Res_GETENTRY(id) (id&0xFFFF)\n\n#define Res_INTERNALID(resid) ((resid&0xFFFF0000) != 0 && (resid&0xFF0000) == 0)\n#define Res_MAKEINTERNAL(entry) (0x01000000 | (entry&0xFFFF))\n#define Res_MAKEARRAY(entry) (0x02000000 | (entry&0xFFFF))\n\nstatic const size_t Res_MAXPACKAGE = 255;\nstatic const size_t Res_MAXTYPE = 255;\n\n/**\n * Representation of a value in a resource, supplying type\n * information.\n */\nstruct Res_value\n{\n    // Number of bytes in this structure.\n    uint16_t size;\n\n    // Always set to 0.\n    uint8_t res0;\n        \n    // Type of the data value.\n    enum {\n        // The 'data' is either 0 or 1, specifying this resource is either\n        // undefined or empty, respectively.\n        TYPE_NULL = 0x00,\n        // The 'data' holds a ResTable_ref, a reference to another resource\n        // table entry.\n        TYPE_REFERENCE = 0x01,\n        // The 'data' holds an attribute resource identifier.\n        TYPE_ATTRIBUTE = 0x02,\n        // The 'data' holds an index into the containing resource table's\n        // global value string pool.\n        TYPE_STRING = 0x03,\n        // The 'data' holds a single-precision floating point number.\n        TYPE_FLOAT = 0x04,\n        // The 'data' holds a complex number encoding a dimension value,\n        // such as \"100in\".\n        TYPE_DIMENSION = 0x05,\n        // The 'data' holds a complex number encoding a fraction of a\n        // container.\n        TYPE_FRACTION = 0x06,\n        // The 'data' holds a dynamic ResTable_ref, which needs to be\n        // resolved before it can be used like a TYPE_REFERENCE.\n        TYPE_DYNAMIC_REFERENCE = 0x07,\n        // The 'data' holds an attribute resource identifier, which needs to be resolved\n        // before it can be used like a TYPE_ATTRIBUTE.\n        TYPE_DYNAMIC_ATTRIBUTE = 0x08,\n\n        // Beginning of integer flavors...\n        TYPE_FIRST_INT = 0x10,\n\n        // The 'data' is a raw integer value of the form n..n.\n        TYPE_INT_DEC = 0x10,\n        // The 'data' is a raw integer value of the form 0xn..n.\n        TYPE_INT_HEX = 0x11,\n        // The 'data' is either 0 or 1, for input \"false\" or \"true\" respectively.\n        TYPE_INT_BOOLEAN = 0x12,\n\n        // Beginning of color integer flavors...\n        TYPE_FIRST_COLOR_INT = 0x1c,\n\n        // The 'data' is a raw integer value of the form #aarrggbb.\n        TYPE_INT_COLOR_ARGB8 = 0x1c,\n        // The 'data' is a raw integer value of the form #rrggbb.\n        TYPE_INT_COLOR_RGB8 = 0x1d,\n        // The 'data' is a raw integer value of the form #argb.\n        TYPE_INT_COLOR_ARGB4 = 0x1e,\n        // The 'data' is a raw integer value of the form #rgb.\n        TYPE_INT_COLOR_RGB4 = 0x1f,\n\n        // ...end of integer flavors.\n        TYPE_LAST_COLOR_INT = 0x1f,\n\n        // ...end of integer flavors.\n        TYPE_LAST_INT = 0x1f\n    };\n    uint8_t dataType;\n\n    // Structure of complex data values (TYPE_UNIT and TYPE_FRACTION)\n    enum {\n        // Where the unit type information is.  This gives us 16 possible\n        // types, as defined below.\n        COMPLEX_UNIT_SHIFT = 0,\n        COMPLEX_UNIT_MASK = 0xf,\n\n        // TYPE_DIMENSION: Value is raw pixels.\n        COMPLEX_UNIT_PX = 0,\n        // TYPE_DIMENSION: Value is Device Independent Pixels.\n        COMPLEX_UNIT_DIP = 1,\n        // TYPE_DIMENSION: Value is a Scaled device independent Pixels.\n        COMPLEX_UNIT_SP = 2,\n        // TYPE_DIMENSION: Value is in points.\n        COMPLEX_UNIT_PT = 3,\n        // TYPE_DIMENSION: Value is in inches.\n        COMPLEX_UNIT_IN = 4,\n        // TYPE_DIMENSION: Value is in millimeters.\n        COMPLEX_UNIT_MM = 5,\n\n        // TYPE_FRACTION: A basic fraction of the overall size.\n        COMPLEX_UNIT_FRACTION = 0,\n        // TYPE_FRACTION: A fraction of the parent size.\n        COMPLEX_UNIT_FRACTION_PARENT = 1,\n\n        // Where the radix information is, telling where the decimal place\n        // appears in the mantissa.  This give us 4 possible fixed point\n        // representations as defined below.\n        COMPLEX_RADIX_SHIFT = 4,\n        COMPLEX_RADIX_MASK = 0x3,\n\n        // The mantissa is an integral number -- i.e., 0xnnnnnn.0\n        COMPLEX_RADIX_23p0 = 0,\n        // The mantissa magnitude is 16 bits -- i.e, 0xnnnn.nn\n        COMPLEX_RADIX_16p7 = 1,\n        // The mantissa magnitude is 8 bits -- i.e, 0xnn.nnnn\n        COMPLEX_RADIX_8p15 = 2,\n        // The mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn\n        COMPLEX_RADIX_0p23 = 3,\n\n        // Where the actual value is.  This gives us 23 bits of\n        // precision.  The top bit is the sign.\n        COMPLEX_MANTISSA_SHIFT = 8,\n        COMPLEX_MANTISSA_MASK = 0xffffff\n    };\n\n    // Possible data values for TYPE_NULL.\n    enum {\n        // The value is not defined.\n        DATA_NULL_UNDEFINED = 0,\n        // The value is explicitly defined as empty.\n        DATA_NULL_EMPTY = 1\n    };\n\n    // The data for this item, as interpreted according to dataType.\n    typedef uint32_t data_type;\n    data_type data;\n\n    void copyFrom_dtoh(const Res_value& src);\n};\n\n/**\n *  This is a reference to a unique entry (a ResTable_entry structure)\n *  in a resource table.  The value is structured as: 0xpptteeee,\n *  where pp is the package index, tt is the type index in that\n *  package, and eeee is the entry index in that type.  The package\n *  and type values start at 1 for the first item, to help catch cases\n *  where they have not been supplied.\n */\nstruct ResTable_ref\n{\n    uint32_t ident;\n};\n\n/**\n * Reference to a string in a string pool.\n */\nstruct ResStringPool_ref\n{\n    // Index into the string pool table (uint32_t-offset from the indices\n    // immediately after ResStringPool_header) at which to find the location\n    // of the string data in the pool.\n    uint32_t index;\n};\n\n/** ********************************************************************\n *  String Pool\n *\n *  A set of strings that can be references by others through a\n *  ResStringPool_ref.\n *\n *********************************************************************** */\n\n/**\n * Definition for a pool of strings.  The data of this chunk is an\n * array of uint32_t providing indices into the pool, relative to\n * stringsStart.  At stringsStart are all of the UTF-16 strings\n * concatenated together; each starts with a uint16_t of the string's\n * length and each ends with a 0x0000 terminator.  If a string is >\n * 32767 characters, the high bit of the length is set meaning to take\n * those 15 bits as a high word and it will be followed by another\n * uint16_t containing the low word.\n *\n * If styleCount is not zero, then immediately following the array of\n * uint32_t indices into the string table is another array of indices\n * into a style table starting at stylesStart.  Each entry in the\n * style table is an array of ResStringPool_span structures.\n */\nstruct ResStringPool_header\n{\n    struct ResChunk_header header;\n\n    // Number of strings in this pool (number of uint32_t indices that follow\n    // in the data).\n    uint32_t stringCount;\n\n    // Number of style span arrays in the pool (number of uint32_t indices\n    // follow the string indices).\n    uint32_t styleCount;\n\n    // Flags.\n    enum {\n        // If set, the string index is sorted by the string values (based\n        // on strcmp16()).\n        SORTED_FLAG = 1<<0,\n\n        // String pool is encoded in UTF-8\n        UTF8_FLAG = 1<<8\n    };\n    uint32_t flags;\n\n    // Index from header of the string data.\n    uint32_t stringsStart;\n\n    // Index from header of the style data.\n    uint32_t stylesStart;\n};\n\n/**\n * This structure defines a span of style information associated with\n * a string in the pool.\n */\nstruct ResStringPool_span\n{\n    enum {\n        END = 0xFFFFFFFF\n    };\n\n    // This is the name of the span -- that is, the name of the XML\n    // tag that defined it.  The special value END (0xFFFFFFFF) indicates\n    // the end of an array of spans.\n    ResStringPool_ref name;\n\n    // The range of characters in the string that this span applies to.\n    uint32_t firstChar, lastChar;\n};\n\n/**\n * Convenience class for accessing data in a ResStringPool resource.\n */\nclass ResStringPool\n{\npublic:\n    ResStringPool();\n    ResStringPool(const void* data, size_t size, bool copyData=false);\n    ~ResStringPool();\n\n    void setToEmpty();\n    status_t setTo(const void* data, size_t size, bool copyData=false);\n\n    status_t getError() const;\n\n    void uninit();\n\n    // Return string entry as UTF16; if the pool is UTF8, the string will\n    // be converted before returning.\n    inline const char16_t* stringAt(const ResStringPool_ref& ref, size_t* outLen) const {\n        return stringAt(ref.index, outLen);\n    }\n    const char16_t* stringAt(size_t idx, size_t* outLen) const;\n\n    // Note: returns null if the string pool is not UTF8.\n    const char* string8At(size_t idx, size_t* outLen) const;\n\n    // Return string whether the pool is UTF8 or UTF16.  Does not allow you\n    // to distinguish null.\n    const String8 string8ObjectAt(size_t idx) const;\n\n    const ResStringPool_span* styleAt(const ResStringPool_ref& ref) const;\n    const ResStringPool_span* styleAt(size_t idx) const;\n\n    ssize_t indexOfString(const char16_t* str, size_t strLen) const;\n\n    size_t size() const;\n    size_t styleCount() const;\n    size_t bytes() const;\n\n    bool isSorted() const;\n    bool isUTF8() const;\n\nprivate:\n    status_t                    mError;\n    void*                       mOwnedData;\n    const ResStringPool_header* mHeader;\n    size_t                      mSize;\n    mutable Mutex               mDecodeLock;\n    const uint32_t*             mEntries;\n    const uint32_t*             mEntryStyles;\n    const void*                 mStrings;\n    char16_t mutable**          mCache;\n    uint32_t                    mStringPoolSize;    // number of uint16_t\n    const uint32_t*             mStyles;\n    uint32_t                    mStylePoolSize;    // number of uint32_t\n};\n\n/**\n * Wrapper class that allows the caller to retrieve a string from\n * a string pool without knowing which string pool to look.\n */\nclass StringPoolRef {\npublic:\n    StringPoolRef();\n    StringPoolRef(const ResStringPool* pool, uint32_t index);\n\n    const char* string8(size_t* outLen) const;\n    const char16_t* string16(size_t* outLen) const;\n\nprivate:\n    const ResStringPool*        mPool;\n    uint32_t                    mIndex;\n};\n\n/** ********************************************************************\n *  XML Tree\n *\n *  Binary representation of an XML document.  This is designed to\n *  express everything in an XML document, in a form that is much\n *  easier to parse on the device.\n *\n *********************************************************************** */\n\n/**\n * XML tree header.  This appears at the front of an XML tree,\n * describing its content.  It is followed by a flat array of\n * ResXMLTree_node structures; the hierarchy of the XML document\n * is described by the occurrance of RES_XML_START_ELEMENT_TYPE\n * and corresponding RES_XML_END_ELEMENT_TYPE nodes in the array.\n */\nstruct ResXMLTree_header\n{\n    struct ResChunk_header header;\n};\n\n/**\n * Basic XML tree node.  A single item in the XML document.  Extended info\n * about the node can be found after header.headerSize.\n */\nstruct ResXMLTree_node\n{\n    struct ResChunk_header header;\n\n    // Line number in original source file at which this element appeared.\n    uint32_t lineNumber;\n\n    // Optional XML comment that was associated with this element; -1 if none.\n    struct ResStringPool_ref comment;\n};\n\n/**\n * Extended XML tree node for CDATA tags -- includes the CDATA string.\n * Appears header.headerSize bytes after a ResXMLTree_node.\n */\nstruct ResXMLTree_cdataExt\n{\n    // The raw CDATA character data.\n    struct ResStringPool_ref data;\n    \n    // The typed value of the character data if this is a CDATA node.\n    struct Res_value typedData;\n};\n\n/**\n * Extended XML tree node for namespace start/end nodes.\n * Appears header.headerSize bytes after a ResXMLTree_node.\n */\nstruct ResXMLTree_namespaceExt\n{\n    // The prefix of the namespace.\n    struct ResStringPool_ref prefix;\n    \n    // The URI of the namespace.\n    struct ResStringPool_ref uri;\n};\n\n/**\n * Extended XML tree node for element start/end nodes.\n * Appears header.headerSize bytes after a ResXMLTree_node.\n */\nstruct ResXMLTree_endElementExt\n{\n    // String of the full namespace of this element.\n    struct ResStringPool_ref ns;\n    \n    // String name of this node if it is an ELEMENT; the raw\n    // character data if this is a CDATA node.\n    struct ResStringPool_ref name;\n};\n\n/**\n * Extended XML tree node for start tags -- includes attribute\n * information.\n * Appears header.headerSize bytes after a ResXMLTree_node.\n */\nstruct ResXMLTree_attrExt\n{\n    // String of the full namespace of this element.\n    struct ResStringPool_ref ns;\n    \n    // String name of this node if it is an ELEMENT; the raw\n    // character data if this is a CDATA node.\n    struct ResStringPool_ref name;\n    \n    // Byte offset from the start of this structure where the attributes start.\n    uint16_t attributeStart;\n    \n    // Size of the ResXMLTree_attribute structures that follow.\n    uint16_t attributeSize;\n    \n    // Number of attributes associated with an ELEMENT.  These are\n    // available as an array of ResXMLTree_attribute structures\n    // immediately following this node.\n    uint16_t attributeCount;\n    \n    // Index (1-based) of the \"id\" attribute. 0 if none.\n    uint16_t idIndex;\n    \n    // Index (1-based) of the \"class\" attribute. 0 if none.\n    uint16_t classIndex;\n    \n    // Index (1-based) of the \"style\" attribute. 0 if none.\n    uint16_t styleIndex;\n};\n\nstruct ResXMLTree_attribute\n{\n    // Namespace of this attribute.\n    struct ResStringPool_ref ns;\n    \n    // Name of this attribute.\n    struct ResStringPool_ref name;\n\n    // The original raw string value of this attribute.\n    struct ResStringPool_ref rawValue;\n    \n    // Processesd typed value of this attribute.\n    struct Res_value typedValue;\n};\n\nclass ResXMLTree;\n\nclass ResXMLParser\n{\npublic:\n    ResXMLParser(const ResXMLTree& tree);\n\n    enum event_code_t {\n        BAD_DOCUMENT = -1,\n        START_DOCUMENT = 0,\n        END_DOCUMENT = 1,\n        \n        FIRST_CHUNK_CODE = RES_XML_FIRST_CHUNK_TYPE, \n        \n        START_NAMESPACE = RES_XML_START_NAMESPACE_TYPE,\n        END_NAMESPACE = RES_XML_END_NAMESPACE_TYPE,\n        START_TAG = RES_XML_START_ELEMENT_TYPE,\n        END_TAG = RES_XML_END_ELEMENT_TYPE,\n        TEXT = RES_XML_CDATA_TYPE\n    };\n\n    struct ResXMLPosition\n    {\n        event_code_t                eventCode;\n        const ResXMLTree_node*      curNode;\n        const void*                 curExt;\n    };\n\n    void restart();\n\n    const ResStringPool& getStrings() const;\n\n    event_code_t getEventType() const;\n    // Note, unlike XmlPullParser, the first call to next() will return\n    // START_TAG of the first element.\n    event_code_t next();\n\n    // These are available for all nodes:\n    int32_t getCommentID() const;\n    const char16_t* getComment(size_t* outLen) const;\n    uint32_t getLineNumber() const;\n    \n    // This is available for TEXT:\n    int32_t getTextID() const;\n    const char16_t* getText(size_t* outLen) const;\n    ssize_t getTextValue(Res_value* outValue) const;\n    \n    // These are available for START_NAMESPACE and END_NAMESPACE:\n    int32_t getNamespacePrefixID() const;\n    const char16_t* getNamespacePrefix(size_t* outLen) const;\n    int32_t getNamespaceUriID() const;\n    const char16_t* getNamespaceUri(size_t* outLen) const;\n    \n    // These are available for START_TAG and END_TAG:\n    int32_t getElementNamespaceID() const;\n    const char16_t* getElementNamespace(size_t* outLen) const;\n    int32_t getElementNameID() const;\n    const char16_t* getElementName(size_t* outLen) const;\n    \n    // Remaining methods are for retrieving information about attributes\n    // associated with a START_TAG:\n    \n    size_t getAttributeCount() const;\n    \n    // Returns -1 if no namespace, -2 if idx out of range.\n    int32_t getAttributeNamespaceID(size_t idx) const;\n    const char16_t* getAttributeNamespace(size_t idx, size_t* outLen) const;\n\n    int32_t getAttributeNameID(size_t idx) const;\n    const char16_t* getAttributeName(size_t idx, size_t* outLen) const;\n    uint32_t getAttributeNameResID(size_t idx) const;\n\n    // These will work only if the underlying string pool is UTF-8.\n    const char* getAttributeNamespace8(size_t idx, size_t* outLen) const;\n    const char* getAttributeName8(size_t idx, size_t* outLen) const;\n\n    int32_t getAttributeValueStringID(size_t idx) const;\n    const char16_t* getAttributeStringValue(size_t idx, size_t* outLen) const;\n    \n    int32_t getAttributeDataType(size_t idx) const;\n    int32_t getAttributeData(size_t idx) const;\n    ssize_t getAttributeValue(size_t idx, Res_value* outValue) const;\n\n    ssize_t indexOfAttribute(const char* ns, const char* attr) const;\n    ssize_t indexOfAttribute(const char16_t* ns, size_t nsLen,\n                             const char16_t* attr, size_t attrLen) const;\n\n    ssize_t indexOfID() const;\n    ssize_t indexOfClass() const;\n    ssize_t indexOfStyle() const;\n\n    void getPosition(ResXMLPosition* pos) const;\n    void setPosition(const ResXMLPosition& pos);\n\nprivate:\n    friend class ResXMLTree;\n    \n    event_code_t nextNode();\n\n    const ResXMLTree&           mTree;\n    event_code_t                mEventCode;\n    const ResXMLTree_node*      mCurNode;\n    const void*                 mCurExt;\n};\n\nclass DynamicRefTable;\n\n/**\n * Convenience class for accessing data in a ResXMLTree resource.\n */\nclass ResXMLTree : public ResXMLParser\n{\npublic:\n    ResXMLTree(const DynamicRefTable* dynamicRefTable);\n    ResXMLTree();\n    ~ResXMLTree();\n\n    status_t setTo(const void* data, size_t size, bool copyData=false);\n\n    status_t getError() const;\n\n    void uninit();\n\nprivate:\n    friend class ResXMLParser;\n\n    status_t validateNode(const ResXMLTree_node* node) const;\n\n    const DynamicRefTable* const mDynamicRefTable;\n\n    status_t                    mError;\n    void*                       mOwnedData;\n    const ResXMLTree_header*    mHeader;\n    size_t                      mSize;\n    const uint8_t*              mDataEnd;\n    ResStringPool               mStrings;\n    const uint32_t*             mResIds;\n    size_t                      mNumResIds;\n    const ResXMLTree_node*      mRootNode;\n    const void*                 mRootExt;\n    event_code_t                mRootCode;\n};\n\n/** ********************************************************************\n *  RESOURCE TABLE\n *\n *********************************************************************** */\n\n/**\n * Header for a resource table.  Its data contains a series of\n * additional chunks:\n *   * A ResStringPool_header containing all table values.  This string pool\n *     contains all of the string values in the entire resource table (not\n *     the names of entries or type identifiers however).\n *   * One or more ResTable_package chunks.\n *\n * Specific entries within a resource table can be uniquely identified\n * with a single integer as defined by the ResTable_ref structure.\n */\nstruct ResTable_header\n{\n    struct ResChunk_header header;\n\n    // The number of ResTable_package structures.\n    uint32_t packageCount;\n};\n\n/**\n * A collection of resource data types within a package.  Followed by\n * one or more ResTable_type and ResTable_typeSpec structures containing the\n * entry values for each resource type.\n */\nstruct ResTable_package\n{\n    struct ResChunk_header header;\n\n    // If this is a base package, its ID.  Package IDs start\n    // at 1 (corresponding to the value of the package bits in a\n    // resource identifier).  0 means this is not a base package.\n    uint32_t id;\n\n    // Actual name of this package, \\0-terminated.\n    uint16_t name[128];\n\n    // Offset to a ResStringPool_header defining the resource\n    // type symbol table.  If zero, this package is inheriting from\n    // another base package (overriding specific values in it).\n    uint32_t typeStrings;\n\n    // Last index into typeStrings that is for public use by others.\n    uint32_t lastPublicType;\n\n    // Offset to a ResStringPool_header defining the resource\n    // key symbol table.  If zero, this package is inheriting from\n    // another base package (overriding specific values in it).\n    uint32_t keyStrings;\n\n    // Last index into keyStrings that is for public use by others.\n    uint32_t lastPublicKey;\n\n    uint32_t typeIdOffset;\n};\n\n// The most specific locale can consist of:\n//\n// - a 3 char language code\n// - a 3 char region code prefixed by a 'r'\n// - a 4 char script code prefixed by a 's'\n// - a 8 char variant code prefixed by a 'v'\n//\n// each separated by a single char separator, which sums up to a total of 24\n// chars, (25 include the string terminator) rounded up to 28 to be 4 byte\n// aligned.\n#define RESTABLE_MAX_LOCALE_LEN 28\n\n\n/**\n * Describes a particular resource configuration.\n */\nstruct ResTable_config\n{\n    // Number of bytes in this structure.\n    uint32_t size;\n    \n    union {\n        struct {\n            // Mobile country code (from SIM).  0 means \"any\".\n            uint16_t mcc;\n            // Mobile network code (from SIM).  0 means \"any\".\n            uint16_t mnc;\n        };\n        uint32_t imsi;\n    };\n    \n    union {\n        struct {\n            // This field can take three different forms:\n            // - \\0\\0 means \"any\".\n            //\n            // - Two 7 bit ascii values interpreted as ISO-639-1 language\n            //   codes ('fr', 'en' etc. etc.). The high bit for both bytes is\n            //   zero.\n            //\n            // - A single 16 bit little endian packed value representing an\n            //   ISO-639-2 3 letter language code. This will be of the form:\n            //\n            //   {1, t, t, t, t, t, s, s, s, s, s, f, f, f, f, f}\n            //\n            //   bit[0, 4] = first letter of the language code\n            //   bit[5, 9] = second letter of the language code\n            //   bit[10, 14] = third letter of the language code.\n            //   bit[15] = 1 always\n            //\n            // For backwards compatibility, languages that have unambiguous\n            // two letter codes are represented in that format.\n            //\n            // The layout is always bigendian irrespective of the runtime\n            // architecture.\n            char language[2];\n            \n            // This field can take three different forms:\n            // - \\0\\0 means \"any\".\n            //\n            // - Two 7 bit ascii values interpreted as 2 letter region\n            //   codes ('US', 'GB' etc.). The high bit for both bytes is zero.\n            //\n            // - An UN M.49 3 digit region code. For simplicity, these are packed\n            //   in the same manner as the language codes, though we should need\n            //   only 10 bits to represent them, instead of the 15.\n            //\n            // The layout is always bigendian irrespective of the runtime\n            // architecture.\n            char country[2];\n        };\n        uint32_t locale;\n    };\n    \n    enum {\n        ORIENTATION_ANY  = ACONFIGURATION_ORIENTATION_ANY,\n        ORIENTATION_PORT = ACONFIGURATION_ORIENTATION_PORT,\n        ORIENTATION_LAND = ACONFIGURATION_ORIENTATION_LAND,\n        ORIENTATION_SQUARE = ACONFIGURATION_ORIENTATION_SQUARE,\n    };\n    \n    enum {\n        TOUCHSCREEN_ANY  = ACONFIGURATION_TOUCHSCREEN_ANY,\n        TOUCHSCREEN_NOTOUCH  = ACONFIGURATION_TOUCHSCREEN_NOTOUCH,\n        TOUCHSCREEN_STYLUS  = ACONFIGURATION_TOUCHSCREEN_STYLUS,\n        TOUCHSCREEN_FINGER  = ACONFIGURATION_TOUCHSCREEN_FINGER,\n    };\n    \n    enum {\n        DENSITY_DEFAULT = ACONFIGURATION_DENSITY_DEFAULT,\n        DENSITY_LOW = ACONFIGURATION_DENSITY_LOW,\n        DENSITY_MEDIUM = ACONFIGURATION_DENSITY_MEDIUM,\n        DENSITY_TV = ACONFIGURATION_DENSITY_TV,\n        DENSITY_HIGH = ACONFIGURATION_DENSITY_HIGH,\n        DENSITY_XHIGH = ACONFIGURATION_DENSITY_XHIGH,\n        DENSITY_XXHIGH = ACONFIGURATION_DENSITY_XXHIGH,\n        DENSITY_XXXHIGH = ACONFIGURATION_DENSITY_XXXHIGH,\n        DENSITY_ANY = ACONFIGURATION_DENSITY_ANY,\n        DENSITY_NONE = ACONFIGURATION_DENSITY_NONE\n    };\n    \n    union {\n        struct {\n            uint8_t orientation;\n            uint8_t touchscreen;\n            uint16_t density;\n        };\n        uint32_t screenType;\n    };\n    \n    enum {\n        KEYBOARD_ANY  = ACONFIGURATION_KEYBOARD_ANY,\n        KEYBOARD_NOKEYS  = ACONFIGURATION_KEYBOARD_NOKEYS,\n        KEYBOARD_QWERTY  = ACONFIGURATION_KEYBOARD_QWERTY,\n        KEYBOARD_12KEY  = ACONFIGURATION_KEYBOARD_12KEY,\n    };\n    \n    enum {\n        NAVIGATION_ANY  = ACONFIGURATION_NAVIGATION_ANY,\n        NAVIGATION_NONAV  = ACONFIGURATION_NAVIGATION_NONAV,\n        NAVIGATION_DPAD  = ACONFIGURATION_NAVIGATION_DPAD,\n        NAVIGATION_TRACKBALL  = ACONFIGURATION_NAVIGATION_TRACKBALL,\n        NAVIGATION_WHEEL  = ACONFIGURATION_NAVIGATION_WHEEL,\n    };\n    \n    enum {\n        MASK_KEYSHIDDEN = 0x0003,\n        KEYSHIDDEN_ANY = ACONFIGURATION_KEYSHIDDEN_ANY,\n        KEYSHIDDEN_NO = ACONFIGURATION_KEYSHIDDEN_NO,\n        KEYSHIDDEN_YES = ACONFIGURATION_KEYSHIDDEN_YES,\n        KEYSHIDDEN_SOFT = ACONFIGURATION_KEYSHIDDEN_SOFT,\n    };\n    \n    enum {\n        MASK_NAVHIDDEN = 0x000c,\n        SHIFT_NAVHIDDEN = 2,\n        NAVHIDDEN_ANY = ACONFIGURATION_NAVHIDDEN_ANY << SHIFT_NAVHIDDEN,\n        NAVHIDDEN_NO = ACONFIGURATION_NAVHIDDEN_NO << SHIFT_NAVHIDDEN,\n        NAVHIDDEN_YES = ACONFIGURATION_NAVHIDDEN_YES << SHIFT_NAVHIDDEN,\n    };\n    \n    union {\n        struct {\n            uint8_t keyboard;\n            uint8_t navigation;\n            uint8_t inputFlags;\n            uint8_t inputPad0;\n        };\n        uint32_t input;\n    };\n    \n    enum {\n        SCREENWIDTH_ANY = 0\n    };\n    \n    enum {\n        SCREENHEIGHT_ANY = 0\n    };\n    \n    union {\n        struct {\n            uint16_t screenWidth;\n            uint16_t screenHeight;\n        };\n        uint32_t screenSize;\n    };\n    \n    enum {\n        SDKVERSION_ANY = 0\n    };\n    \n  enum {\n        MINORVERSION_ANY = 0\n    };\n    \n    union {\n        struct {\n            uint16_t sdkVersion;\n            // For now minorVersion must always be 0!!!  Its meaning\n            // is currently undefined.\n            uint16_t minorVersion;\n        };\n        uint32_t version;\n    };\n    \n    enum {\n        // screenLayout bits for screen size class.\n        MASK_SCREENSIZE = 0x0f,\n        SCREENSIZE_ANY = ACONFIGURATION_SCREENSIZE_ANY,\n        SCREENSIZE_SMALL = ACONFIGURATION_SCREENSIZE_SMALL,\n        SCREENSIZE_NORMAL = ACONFIGURATION_SCREENSIZE_NORMAL,\n        SCREENSIZE_LARGE = ACONFIGURATION_SCREENSIZE_LARGE,\n        SCREENSIZE_XLARGE = ACONFIGURATION_SCREENSIZE_XLARGE,\n        \n        // screenLayout bits for wide/long screen variation.\n        MASK_SCREENLONG = 0x30,\n        SHIFT_SCREENLONG = 4,\n        SCREENLONG_ANY = ACONFIGURATION_SCREENLONG_ANY << SHIFT_SCREENLONG,\n        SCREENLONG_NO = ACONFIGURATION_SCREENLONG_NO << SHIFT_SCREENLONG,\n        SCREENLONG_YES = ACONFIGURATION_SCREENLONG_YES << SHIFT_SCREENLONG,\n\n        // screenLayout bits for layout direction.\n        MASK_LAYOUTDIR = 0xC0,\n        SHIFT_LAYOUTDIR = 6,\n        LAYOUTDIR_ANY = ACONFIGURATION_LAYOUTDIR_ANY << SHIFT_LAYOUTDIR,\n        LAYOUTDIR_LTR = ACONFIGURATION_LAYOUTDIR_LTR << SHIFT_LAYOUTDIR,\n        LAYOUTDIR_RTL = ACONFIGURATION_LAYOUTDIR_RTL << SHIFT_LAYOUTDIR,\n    };\n    \n    enum {\n        // uiMode bits for the mode type.\n        MASK_UI_MODE_TYPE = 0x0f,\n        UI_MODE_TYPE_ANY = ACONFIGURATION_UI_MODE_TYPE_ANY,\n        UI_MODE_TYPE_NORMAL = ACONFIGURATION_UI_MODE_TYPE_NORMAL,\n        UI_MODE_TYPE_DESK = ACONFIGURATION_UI_MODE_TYPE_DESK,\n        UI_MODE_TYPE_CAR = ACONFIGURATION_UI_MODE_TYPE_CAR,\n        UI_MODE_TYPE_TELEVISION = ACONFIGURATION_UI_MODE_TYPE_TELEVISION,\n        UI_MODE_TYPE_APPLIANCE = ACONFIGURATION_UI_MODE_TYPE_APPLIANCE,\n        UI_MODE_TYPE_WATCH = ACONFIGURATION_UI_MODE_TYPE_WATCH,\n\n        // uiMode bits for the night switch.\n        MASK_UI_MODE_NIGHT = 0x30,\n        SHIFT_UI_MODE_NIGHT = 4,\n        UI_MODE_NIGHT_ANY = ACONFIGURATION_UI_MODE_NIGHT_ANY << SHIFT_UI_MODE_NIGHT,\n        UI_MODE_NIGHT_NO = ACONFIGURATION_UI_MODE_NIGHT_NO << SHIFT_UI_MODE_NIGHT,\n        UI_MODE_NIGHT_YES = ACONFIGURATION_UI_MODE_NIGHT_YES << SHIFT_UI_MODE_NIGHT,\n    };\n\n    union {\n        struct {\n            uint8_t screenLayout;\n            uint8_t uiMode;\n            uint16_t smallestScreenWidthDp;\n        };\n        uint32_t screenConfig;\n    };\n    \n    union {\n        struct {\n            uint16_t screenWidthDp;\n            uint16_t screenHeightDp;\n        };\n        uint32_t screenSizeDp;\n    };\n\n    // The ISO-15924 short name for the script corresponding to this\n    // configuration. (eg. Hant, Latn, etc.). Interpreted in conjunction with\n    // the locale field.\n    char localeScript[4];\n\n    // A single BCP-47 variant subtag. Will vary in length between 4 and 8\n    // chars. Interpreted in conjunction with the locale field.\n    char localeVariant[8];\n\n    enum {\n        // screenLayout2 bits for round/notround.\n        MASK_SCREENROUND = 0x03,\n        SCREENROUND_ANY = ACONFIGURATION_SCREENROUND_ANY,\n        SCREENROUND_NO = ACONFIGURATION_SCREENROUND_NO,\n        SCREENROUND_YES = ACONFIGURATION_SCREENROUND_YES,\n    };\n\n    // An extension of screenConfig.\n    union {\n        struct {\n            uint8_t screenLayout2;      // Contains round/notround qualifier.\n            uint8_t screenConfigPad1;   // Reserved padding.\n            uint16_t screenConfigPad2;  // Reserved padding.\n        };\n        uint32_t screenConfig2;\n    };\n\n    // If false and localeScript is set, it means that the script of the locale\n    // was explicitly provided.\n    //\n    // If true, it means that localeScript was automatically computed.\n    // localeScript may still not be set in this case, which means that we\n    // tried but could not compute a script.\n    bool localeScriptWasComputed;\n\n    void copyFromDeviceNoSwap(const ResTable_config& o);\n    \n    void copyFromDtoH(const ResTable_config& o);\n    \n    void swapHtoD();\n\n    int compare(const ResTable_config& o) const;\n    int compareLogical(const ResTable_config& o) const;\n\n    // Flags indicating a set of config values.  These flag constants must\n    // match the corresponding ones in android.content.pm.ActivityInfo and\n    // attrs_manifest.xml.\n    enum {\n        CONFIG_MCC = ACONFIGURATION_MCC,\n        CONFIG_MNC = ACONFIGURATION_MNC,\n        CONFIG_LOCALE = ACONFIGURATION_LOCALE,\n        CONFIG_TOUCHSCREEN = ACONFIGURATION_TOUCHSCREEN,\n        CONFIG_KEYBOARD = ACONFIGURATION_KEYBOARD,\n        CONFIG_KEYBOARD_HIDDEN = ACONFIGURATION_KEYBOARD_HIDDEN,\n        CONFIG_NAVIGATION = ACONFIGURATION_NAVIGATION,\n        CONFIG_ORIENTATION = ACONFIGURATION_ORIENTATION,\n        CONFIG_DENSITY = ACONFIGURATION_DENSITY,\n        CONFIG_SCREEN_SIZE = ACONFIGURATION_SCREEN_SIZE,\n        CONFIG_SMALLEST_SCREEN_SIZE = ACONFIGURATION_SMALLEST_SCREEN_SIZE,\n        CONFIG_VERSION = ACONFIGURATION_VERSION,\n        CONFIG_SCREEN_LAYOUT = ACONFIGURATION_SCREEN_LAYOUT,\n        CONFIG_UI_MODE = ACONFIGURATION_UI_MODE,\n        CONFIG_LAYOUTDIR = ACONFIGURATION_LAYOUTDIR,\n        CONFIG_SCREEN_ROUND = ACONFIGURATION_SCREEN_ROUND,\n    };\n    \n    // Compare two configuration, returning CONFIG_* flags set for each value\n    // that is different.\n    int diff(const ResTable_config& o) const;\n    \n    // Return true if 'this' is more specific than 'o'.\n    bool isMoreSpecificThan(const ResTable_config& o) const;\n\n    // Return true if 'this' is a better match than 'o' for the 'requested'\n    // configuration.  This assumes that match() has already been used to\n    // remove any configurations that don't match the requested configuration\n    // at all; if they are not first filtered, non-matching results can be\n    // considered better than matching ones.\n    // The general rule per attribute: if the request cares about an attribute\n    // (it normally does), if the two (this and o) are equal it's a tie.  If\n    // they are not equal then one must be generic because only generic and\n    // '==requested' will pass the match() call.  So if this is not generic,\n    // it wins.  If this IS generic, o wins (return false).\n    bool isBetterThan(const ResTable_config& o, const ResTable_config* requested) const;\n\n    // Return true if 'this' can be considered a match for the parameters in \n    // 'settings'.\n    // Note this is asymetric.  A default piece of data will match every request\n    // but a request for the default should not match odd specifics\n    // (ie, request with no mcc should not match a particular mcc's data)\n    // settings is the requested settings\n    bool match(const ResTable_config& settings) const;\n\n    // Get the string representation of the locale component of this\n    // Config. The maximum size of this representation will be\n    // |RESTABLE_MAX_LOCALE_LEN| (including a terminating '\\0').\n    //\n    // Example: en-US, en-Latn-US, en-POSIX.\n    void getBcp47Locale(char* out) const;\n\n    // Append to str the resource-qualifer string representation of the\n    // locale component of this Config. If the locale is only country\n    // and language, it will look like en-rUS. If it has scripts and\n    // variants, it will be a modified bcp47 tag: b+en+Latn+US.\n    void appendDirLocale(String8& str) const;\n\n    // Sets the values of language, region, script and variant to the\n    // well formed BCP-47 locale contained in |in|. The input locale is\n    // assumed to be valid and no validation is performed.\n    void setBcp47Locale(const char* in);\n\n    inline void clearLocale() {\n        locale = 0;\n        localeScriptWasComputed = false;\n        memset(localeScript, 0, sizeof(localeScript));\n        memset(localeVariant, 0, sizeof(localeVariant));\n    }\n\n    inline void computeScript() {\n        localeDataComputeScript(localeScript, language, country);\n    }\n\n    // Get the 2 or 3 letter language code of this configuration. Trailing\n    // bytes are set to '\\0'.\n    size_t unpackLanguage(char language[4]) const;\n    // Get the 2 or 3 letter language code of this configuration. Trailing\n    // bytes are set to '\\0'.\n    size_t unpackRegion(char region[4]) const;\n\n    // Sets the language code of this configuration to the first three\n    // chars at |language|.\n    //\n    // If |language| is a 2 letter code, the trailing byte must be '\\0' or\n    // the BCP-47 separator '-'.\n    void packLanguage(const char* language);\n    // Sets the region code of this configuration to the first three bytes\n    // at |region|. If |region| is a 2 letter code, the trailing byte must be '\\0'\n    // or the BCP-47 separator '-'.\n    void packRegion(const char* region);\n\n    // Returns a positive integer if this config is more specific than |o|\n    // with respect to their locales, a negative integer if |o| is more specific\n    // and 0 if they're equally specific.\n    int isLocaleMoreSpecificThan(const ResTable_config &o) const;\n\n    // Return true if 'this' is a better locale match than 'o' for the\n    // 'requested' configuration. Similar to isBetterThan(), this assumes that\n    // match() has already been used to remove any configurations that don't\n    // match the requested configuration at all.\n    bool isLocaleBetterThan(const ResTable_config& o, const ResTable_config* requested) const;\n\n    String8 toString() const;\n};\n\n/**\n * A specification of the resources defined by a particular type.\n *\n * There should be one of these chunks for each resource type.\n *\n * This structure is followed by an array of integers providing the set of\n * configuration change flags (ResTable_config::CONFIG_*) that have multiple\n * resources for that configuration.  In addition, the high bit is set if that\n * resource has been made public.\n */\nstruct ResTable_typeSpec\n{\n    struct ResChunk_header header;\n\n    // The type identifier this chunk is holding.  Type IDs start\n    // at 1 (corresponding to the value of the type bits in a\n    // resource identifier).  0 is invalid.\n    uint8_t id;\n    \n    // Must be 0.\n    uint8_t res0;\n    // Must be 0.\n    uint16_t res1;\n    \n    // Number of uint32_t entry configuration masks that follow.\n    uint32_t entryCount;\n\n    enum {\n        // Additional flag indicating an entry is public.\n        SPEC_PUBLIC = 0x40000000\n    };\n};\n\n/**\n * A collection of resource entries for a particular resource data\n * type. Followed by an array of uint32_t defining the resource\n * values, corresponding to the array of type strings in the\n * ResTable_package::typeStrings string block. Each of these hold an\n * index from entriesStart; a value of NO_ENTRY means that entry is\n * not defined.\n *\n * There may be multiple of these chunks for a particular resource type,\n * supply different configuration variations for the resource values of\n * that type.\n *\n * It would be nice to have an additional ordered index of entries, so\n * we can do a binary search if trying to find a resource by string name.\n */\nstruct ResTable_type\n{\n    struct ResChunk_header header;\n\n    enum {\n        NO_ENTRY = 0xFFFFFFFF\n    };\n    \n    // The type identifier this chunk is holding.  Type IDs start\n    // at 1 (corresponding to the value of the type bits in a\n    // resource identifier).  0 is invalid.\n    uint8_t id;\n    \n    // Must be 0.\n    uint8_t res0;\n    // Must be 0.\n    uint16_t res1;\n    \n    // Number of uint32_t entry indices that follow.\n    uint32_t entryCount;\n\n    // Offset from header where ResTable_entry data starts.\n    uint32_t entriesStart;\n    \n    // Configuration this collection of entries is designed for.\n    ResTable_config config;\n};\n\n/**\n * This is the beginning of information about an entry in the resource\n * table.  It holds the reference to the name of this entry, and is\n * immediately followed by one of:\n *   * A Res_value structure, if FLAG_COMPLEX is -not- set.\n *   * An array of ResTable_map structures, if FLAG_COMPLEX is set.\n *     These supply a set of name/value mappings of data.\n */\nstruct ResTable_entry\n{\n    // Number of bytes in this structure.\n    uint16_t size;\n\n    enum {\n        // If set, this is a complex entry, holding a set of name/value\n        // mappings.  It is followed by an array of ResTable_map structures.\n        FLAG_COMPLEX = 0x0001,\n        // If set, this resource has been declared public, so libraries\n        // are allowed to reference it.\n        FLAG_PUBLIC = 0x0002,\n        // If set, this is a weak resource and may be overriden by strong\n        // resources of the same name/type. This is only useful during\n        // linking with other resource tables.\n        FLAG_WEAK = 0x0004\n    };\n    uint16_t flags;\n    \n    // Reference into ResTable_package::keyStrings identifying this entry.\n    struct ResStringPool_ref key;\n};\n\n/**\n * Extended form of a ResTable_entry for map entries, defining a parent map\n * resource from which to inherit values.\n */\nstruct ResTable_map_entry : public ResTable_entry\n{\n    // Resource identifier of the parent mapping, or 0 if there is none.\n    // This is always treated as a TYPE_DYNAMIC_REFERENCE.\n    ResTable_ref parent;\n    // Number of name/value pairs that follow for FLAG_COMPLEX.\n    uint32_t count;\n};\n\n/**\n * A single name/value mapping that is part of a complex resource\n * entry.\n */\nstruct ResTable_map\n{\n    // The resource identifier defining this mapping's name.  For attribute\n    // resources, 'name' can be one of the following special resource types\n    // to supply meta-data about the attribute; for all other resource types\n    // it must be an attribute resource.\n    ResTable_ref name;\n\n    // Special values for 'name' when defining attribute resources.\n    enum {\n        // This entry holds the attribute's type code.\n        ATTR_TYPE = Res_MAKEINTERNAL(0),\n\n        // For integral attributes, this is the minimum value it can hold.\n        ATTR_MIN = Res_MAKEINTERNAL(1),\n\n        // For integral attributes, this is the maximum value it can hold.\n        ATTR_MAX = Res_MAKEINTERNAL(2),\n\n        // Localization of this resource is can be encouraged or required with\n        // an aapt flag if this is set\n        ATTR_L10N = Res_MAKEINTERNAL(3),\n\n        // for plural support, see android.content.res.PluralRules#attrForQuantity(int)\n        ATTR_OTHER = Res_MAKEINTERNAL(4),\n        ATTR_ZERO = Res_MAKEINTERNAL(5),\n        ATTR_ONE = Res_MAKEINTERNAL(6),\n        ATTR_TWO = Res_MAKEINTERNAL(7),\n        ATTR_FEW = Res_MAKEINTERNAL(8),\n        ATTR_MANY = Res_MAKEINTERNAL(9)\n        \n    };\n\n    // Bit mask of allowed types, for use with ATTR_TYPE.\n    enum {\n        // No type has been defined for this attribute, use generic\n        // type handling.  The low 16 bits are for types that can be\n        // handled generically; the upper 16 require additional information\n        // in the bag so can not be handled generically for TYPE_ANY.\n        TYPE_ANY = 0x0000FFFF,\n\n        // Attribute holds a references to another resource.\n        TYPE_REFERENCE = 1<<0,\n\n        // Attribute holds a generic string.\n        TYPE_STRING = 1<<1,\n\n        // Attribute holds an integer value.  ATTR_MIN and ATTR_MIN can\n        // optionally specify a constrained range of possible integer values.\n        TYPE_INTEGER = 1<<2,\n\n        // Attribute holds a boolean integer.\n        TYPE_BOOLEAN = 1<<3,\n\n        // Attribute holds a color value.\n        TYPE_COLOR = 1<<4,\n\n        // Attribute holds a floating point value.\n        TYPE_FLOAT = 1<<5,\n\n        // Attribute holds a dimension value, such as \"20px\".\n        TYPE_DIMENSION = 1<<6,\n\n        // Attribute holds a fraction value, such as \"20%\".\n        TYPE_FRACTION = 1<<7,\n\n        // Attribute holds an enumeration.  The enumeration values are\n        // supplied as additional entries in the map.\n        TYPE_ENUM = 1<<16,\n\n        // Attribute holds a bitmaks of flags.  The flag bit values are\n        // supplied as additional entries in the map.\n        TYPE_FLAGS = 1<<17\n    };\n\n    // Enum of localization modes, for use with ATTR_L10N.\n    enum {\n        L10N_NOT_REQUIRED = 0,\n        L10N_SUGGESTED    = 1\n    };\n    \n    // This mapping's value.\n    Res_value value;\n};\n\n/**\n * A package-id to package name mapping for any shared libraries used\n * in this resource table. The package-id's encoded in this resource\n * table may be different than the id's assigned at runtime. We must\n * be able to translate the package-id's based on the package name.\n */\nstruct ResTable_lib_header\n{\n    struct ResChunk_header header;\n\n    // The number of shared libraries linked in this resource table.\n    uint32_t count;\n};\n\n/**\n * A shared library package-id to package name entry.\n */\nstruct ResTable_lib_entry\n{\n    // The package-id this shared library was assigned at build time.\n    // We use a uint32 to keep the structure aligned on a uint32 boundary.\n    uint32_t packageId;\n\n    // The package name of the shared library. \\0 terminated.\n    uint16_t packageName[128];\n};\n\n/**\n * Holds the shared library ID table. Shared libraries are assigned package IDs at\n * build time, but they may be loaded in a different order, so we need to maintain\n * a mapping of build-time package ID to run-time assigned package ID.\n *\n * Dynamic references are not currently supported in overlays. Only the base package\n * may have dynamic references.\n */\nclass DynamicRefTable\n{\npublic:\n    DynamicRefTable(uint8_t packageId, bool appAsLib);\n\n    // Loads an unmapped reference table from the package.\n    status_t load(const ResTable_lib_header* const header);\n\n    // Adds mappings from the other DynamicRefTable\n    status_t addMappings(const DynamicRefTable& other);\n\n    // Creates a mapping from build-time package ID to run-time package ID for\n    // the given package.\n    status_t addMapping(const String16& packageName, uint8_t packageId);\n\n    // Performs the actual conversion of build-time resource ID to run-time\n    // resource ID.\n    inline status_t lookupResourceId(uint32_t* resId) const;\n    inline status_t lookupResourceValue(Res_value* value) const;\n\n    inline const KeyedVector<String16, uint8_t>& entries() const {\n        return mEntries;\n    }\n\nprivate:\n    const uint8_t                   mAssignedPackageId;\n    uint8_t                         mLookupTable[256];\n    KeyedVector<String16, uint8_t>  mEntries;\n    bool                            mAppAsLib;\n};\n\nbool U16StringToInt(const char16_t* s, size_t len, Res_value* outValue);\n\n/**\n * Convenience class for accessing data in a ResTable resource.\n */\nclass ResTable\n{\npublic:\n    ResTable();\n    ResTable(const void* data, size_t size, const int32_t cookie,\n             bool copyData=false);\n    ~ResTable();\n\n    status_t add(const void* data, size_t size, const int32_t cookie=-1, bool copyData=false);\n    status_t add(const void* data, size_t size, const void* idmapData, size_t idmapDataSize,\n            const int32_t cookie=-1, bool copyData=false, bool appAsLib=false);\n\n    status_t add(Asset* asset, const int32_t cookie=-1, bool copyData=false);\n    status_t add(Asset* asset, Asset* idmapAsset, const int32_t cookie=-1, bool copyData=false,\n            bool appAsLib=false, bool isSystemAsset=false);\n\n    status_t add(ResTable* src, bool isSystemAsset=false);\n    status_t addEmpty(const int32_t cookie);\n\n    status_t getError() const;\n\n    void uninit();\n\n    struct resource_name\n    {\n        const char16_t* package;\n        size_t packageLen;\n        const char16_t* type;\n        const char* type8;\n        size_t typeLen;\n        const char16_t* name;\n        const char* name8;\n        size_t nameLen;\n    };\n\n    bool getResourceName(uint32_t resID, bool allowUtf8, resource_name* outName) const;\n\n    bool getResourceFlags(uint32_t resID, uint32_t* outFlags) const;\n\n    /**\n     * Retrieve the value of a resource.  If the resource is found, returns a\n     * value >= 0 indicating the table it is in (for use with\n     * getTableStringBlock() and getTableCookie()) and fills in 'outValue'.  If\n     * not found, returns a negative error code.\n     *\n     * Note that this function does not do reference traversal.  If you want\n     * to follow references to other resources to get the \"real\" value to\n     * use, you need to call resolveReference() after this function.\n     *\n     * @param resID The desired resoruce identifier.\n     * @param outValue Filled in with the resource data that was found.\n     *\n     * @return ssize_t Either a >= 0 table index or a negative error code.\n     */\n    ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag = false,\n                    uint16_t density = 0,\n                    uint32_t* outSpecFlags = NULL,\n                    ResTable_config* outConfig = NULL) const;\n\n    inline ssize_t getResource(const ResTable_ref& res, Res_value* outValue,\n            uint32_t* outSpecFlags=NULL) const {\n        return getResource(res.ident, outValue, false, 0, outSpecFlags, NULL);\n    }\n\n    ssize_t resolveReference(Res_value* inOutValue,\n                             ssize_t blockIndex,\n                             uint32_t* outLastRef = NULL,\n                             uint32_t* inoutTypeSpecFlags = NULL,\n                             ResTable_config* outConfig = NULL) const;\n\n    enum {\n        TMP_BUFFER_SIZE = 16\n    };\n    const char16_t* valueToString(const Res_value* value, size_t stringBlock,\n                                  char16_t tmpBuffer[TMP_BUFFER_SIZE],\n                                  size_t* outLen) const;\n\n    struct bag_entry {\n        ssize_t stringBlock;\n        ResTable_map map;\n    };\n\n    /**\n     * Retrieve the bag of a resource.  If the resoruce is found, returns the\n     * number of bags it contains and 'outBag' points to an array of their\n     * values.  If not found, a negative error code is returned.\n     *\n     * Note that this function -does- do reference traversal of the bag data.\n     *\n     * @param resID The desired resource identifier.\n     * @param outBag Filled inm with a pointer to the bag mappings.\n     *\n     * @return ssize_t Either a >= 0 bag count of negative error code.\n     */\n    ssize_t lockBag(uint32_t resID, const bag_entry** outBag) const;\n\n    void unlockBag(const bag_entry* bag) const;\n\n    void lock() const;\n\n    ssize_t getBagLocked(uint32_t resID, const bag_entry** outBag,\n            uint32_t* outTypeSpecFlags=NULL) const;\n\n    void unlock() const;\n\n    class Theme {\n    public:\n        Theme(const ResTable& table);\n        ~Theme();\n\n        inline const ResTable& getResTable() const { return mTable; }\n\n        status_t applyStyle(uint32_t resID, bool force=false);\n        status_t setTo(const Theme& other);\n        status_t clear();\n\n        /**\n         * Retrieve a value in the theme.  If the theme defines this\n         * value, returns a value >= 0 indicating the table it is in\n         * (for use with getTableStringBlock() and getTableCookie) and\n         * fills in 'outValue'.  If not found, returns a negative error\n         * code.\n         *\n         * Note that this function does not do reference traversal.  If you want\n         * to follow references to other resources to get the \"real\" value to\n         * use, you need to call resolveReference() after this function.\n         *\n         * @param resID A resource identifier naming the desired theme\n         *              attribute.\n         * @param outValue Filled in with the theme value that was\n         *                 found.\n         *\n         * @return ssize_t Either a >= 0 table index or a negative error code.\n         */\n        ssize_t getAttribute(uint32_t resID, Res_value* outValue,\n                uint32_t* outTypeSpecFlags = NULL) const;\n\n        /**\n         * This is like ResTable::resolveReference(), but also takes\n         * care of resolving attribute references to the theme.\n         */\n        ssize_t resolveAttributeReference(Res_value* inOutValue,\n                ssize_t blockIndex, uint32_t* outLastRef = NULL,\n                uint32_t* inoutTypeSpecFlags = NULL,\n                ResTable_config* inoutConfig = NULL) const;\n\n        /**\n         * Returns a bit mask of configuration changes that will impact this\n         * theme (and thus require completely reloading it).\n         */\n        uint32_t getChangingConfigurations() const;\n\n        void dumpToLog() const;\n        \n    private:\n        Theme(const Theme&);\n        Theme& operator=(const Theme&);\n\n        struct theme_entry {\n            ssize_t stringBlock;\n            uint32_t typeSpecFlags;\n            Res_value value;\n        };\n\n        struct type_info {\n            size_t numEntries;\n            theme_entry* entries;\n        };\n\n        struct package_info {\n            type_info types[Res_MAXTYPE + 1];\n        };\n\n        void free_package(package_info* pi);\n        package_info* copy_package(package_info* pi);\n\n        const ResTable& mTable;\n        package_info*   mPackages[Res_MAXPACKAGE];\n        uint32_t        mTypeSpecFlags;\n    };\n\n    void setParameters(const ResTable_config* params);\n    void getParameters(ResTable_config* params) const;\n\n    // Retrieve an identifier (which can be passed to getResource)\n    // for a given resource name.  The 'name' can be fully qualified\n    // (<package>:<type>.<basename>) or the package or type components\n    // can be dropped if default values are supplied here.\n    //\n    // Returns 0 if no such resource was found, else a valid resource ID.\n    uint32_t identifierForName(const char16_t* name, size_t nameLen,\n                               const char16_t* type = 0, size_t typeLen = 0,\n                               const char16_t* defPackage = 0,\n                               size_t defPackageLen = 0,\n                               uint32_t* outTypeSpecFlags = NULL) const;\n\n    static bool expandResourceRef(const char16_t* refStr, size_t refLen,\n                                  String16* outPackage,\n                                  String16* outType,\n                                  String16* outName,\n                                  const String16* defType = NULL,\n                                  const String16* defPackage = NULL,\n                                  const char** outErrorMsg = NULL,\n                                  bool* outPublicOnly = NULL);\n\n    static bool stringToInt(const char16_t* s, size_t len, Res_value* outValue);\n    static bool stringToFloat(const char16_t* s, size_t len, Res_value* outValue);\n\n    // Used with stringToValue.\n    class Accessor\n    {\n    public:\n        inline virtual ~Accessor() { }\n\n        virtual const String16& getAssetsPackage() const = 0;\n\n        virtual uint32_t getCustomResource(const String16& package,\n                                           const String16& type,\n                                           const String16& name) const = 0;\n        virtual uint32_t getCustomResourceWithCreation(const String16& package,\n                                                       const String16& type,\n                                                       const String16& name,\n                                                       const bool createIfNeeded = false) = 0;\n        virtual uint32_t getRemappedPackage(uint32_t origPackage) const = 0;\n        virtual bool getAttributeType(uint32_t attrID, uint32_t* outType) = 0;\n        virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin) = 0;\n        virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax) = 0;\n        virtual bool getAttributeEnum(uint32_t attrID,\n                                      const char16_t* name, size_t nameLen,\n                                      Res_value* outValue) = 0;\n        virtual bool getAttributeFlags(uint32_t attrID,\n                                       const char16_t* name, size_t nameLen,\n                                       Res_value* outValue) = 0;\n        virtual uint32_t getAttributeL10N(uint32_t attrID) = 0;\n        virtual bool getLocalizationSetting() = 0;\n        virtual void reportError(void* accessorCookie, const char* fmt, ...) = 0;\n    };\n\n    // Convert a string to a resource value.  Handles standard \"@res\",\n    // \"#color\", \"123\", and \"0x1bd\" types; performs escaping of strings.\n    // The resulting value is placed in 'outValue'; if it is a string type,\n    // 'outString' receives the string.  If 'attrID' is supplied, the value is\n    // type checked against this attribute and it is used to perform enum\n    // evaluation.  If 'acccessor' is supplied, it will be used to attempt to\n    // resolve resources that do not exist in this ResTable.  If 'attrType' is\n    // supplied, the value will be type checked for this format if 'attrID'\n    // is not supplied or found.\n    bool stringToValue(Res_value* outValue, String16* outString,\n                       const char16_t* s, size_t len,\n                       bool preserveSpaces, bool coerceType,\n                       uint32_t attrID = 0,\n                       const String16* defType = NULL,\n                       const String16* defPackage = NULL,\n                       Accessor* accessor = NULL,\n                       void* accessorCookie = NULL,\n                       uint32_t attrType = ResTable_map::TYPE_ANY,\n                       bool enforcePrivate = true,\n                       bool printError = true) const;\n\n    // Perform processing of escapes and quotes in a string.\n    static bool collectString(String16* outString,\n                              const char16_t* s, size_t len,\n                              bool preserveSpaces,\n                              const char** outErrorMsg = NULL,\n                              bool append = false);\n\n    size_t getBasePackageCount() const;\n    const String16 getBasePackageName(size_t idx) const;\n    uint32_t getBasePackageId(size_t idx) const;\n    uint32_t getLastTypeIdForPackage(size_t idx) const;\n\n    // Return the number of resource tables that the object contains.\n    size_t getTableCount() const;\n    // Return the values string pool for the resource table at the given\n    // index.  This string pool contains all of the strings for values\n    // contained in the resource table -- that is the item values themselves,\n    // but not the names their entries or types.\n    const ResStringPool* getTableStringBlock(size_t index) const;\n    // Return unique cookie identifier for the given resource table.\n    int32_t getTableCookie(size_t index) const;\n\n    const DynamicRefTable* getDynamicRefTableForCookie(int32_t cookie) const;\n\n    // Return the configurations (ResTable_config) that we know about\n    void getConfigurations(Vector<ResTable_config>* configs, bool ignoreMipmap=false,\n            bool ignoreAndroidPackage=false, bool includeSystemConfigs=true) const;\n\n    void getLocales(Vector<String8>* locales, bool includeSystemLocales=true) const;\n\n    // Generate an idmap.\n    //\n    // Return value: on success: NO_ERROR; caller is responsible for free-ing\n    // outData (using free(3)). On failure, any status_t value other than\n    // NO_ERROR; the caller should not free outData.\n    status_t createIdmap(const ResTable& overlay,\n            uint32_t targetCrc, uint32_t overlayCrc,\n            const char* targetPath, const char* overlayPath,\n            void** outData, size_t* outSize) const;\n\n    static const size_t IDMAP_HEADER_SIZE_BYTES = 4 * sizeof(uint32_t) + 2 * 256;\n\n    // Retrieve idmap meta-data.\n    //\n    // This function only requires the idmap header (the first\n    // IDMAP_HEADER_SIZE_BYTES) bytes of an idmap file.\n    static bool getIdmapInfo(const void* idmap, size_t size,\n            uint32_t* pVersion,\n            uint32_t* pTargetCrc, uint32_t* pOverlayCrc,\n            String8* pTargetPath, String8* pOverlayPath);\n\n    void print(bool inclValues) const;\n    static String8 normalizeForOutput(const char* input);\n    KeyedVector<uint32_t, ResTable::resource_name> getResourceEntries() const;\n\nprivate:\n    struct Header;\n    struct Type;\n    struct Entry;\n    struct Package;\n    struct PackageGroup;\n    typedef Vector<Type*> TypeList;\n\n    struct bag_set {\n        size_t numAttrs;    // number in array\n        size_t availAttrs;  // total space in array\n        uint32_t typeSpecFlags;\n        // Followed by 'numAttr' bag_entry structures.\n    };\n\n    /**\n     * Configuration dependent cached data. This must be cleared when the configuration is\n     * changed (setParameters).\n     */\n    struct TypeCacheEntry {\n        TypeCacheEntry() : cachedBags(NULL) {}\n\n        // Computed attribute bags for this type.\n        bag_set** cachedBags;\n\n        // Pre-filtered list of configurations (per asset path) that match the parameters set on this\n        // ResTable.\n        Vector<std::shared_ptr<Vector<const ResTable_type*>>> filteredConfigs;\n    };\n\n    status_t addInternal(const void* data, size_t size, const void* idmapData, size_t idmapDataSize,\n            bool appAsLib, const int32_t cookie, bool copyData, bool isSystemAsset=false);\n\n    ssize_t getResourcePackageIndex(uint32_t resID) const;\n\n    status_t getEntry(\n        const PackageGroup* packageGroup, int typeIndex, int entryIndex,\n        const ResTable_config* config,\n        Entry* outEntry) const;\n\n    uint32_t findEntry(const PackageGroup* group, ssize_t typeIndex, const char16_t* name,\n            size_t nameLen, uint32_t* outTypeSpecFlags) const;\n\n    status_t parsePackage(\n        const ResTable_package* const pkg, const Header* const header,\n        bool appAsLib, bool isSystemAsset);\n\n    void print_value(const Package* pkg, const Res_value& value) const;\n\n    template <typename Func>\n    void forEachConfiguration(bool ignoreMipmap, bool ignoreAndroidPackage,\n                              bool includeSystemConfigs, const Func& f) const;\n\n    mutable Mutex               mLock;\n\n    // Mutex that controls access to the list of pre-filtered configurations\n    // to check when looking up entries.\n    // When iterating over a bag, the mLock mutex is locked. While mLock is locked,\n    // we do resource lookups.\n    // Mutex is not reentrant, so we must use a different lock than mLock.\n    mutable Mutex               mFilteredConfigLock;\n\n    status_t                    mError;\n\n    ResTable_config             mParams;\n\n    // Array of all resource tables.\n    Vector<Header*>             mHeaders;\n\n    // Array of packages in all resource tables.\n    Vector<PackageGroup*>       mPackageGroups;\n\n    // Mapping from resource package IDs to indices into the internal\n    // package array.\n    uint8_t                     mPackageMap[256];\n\n    uint8_t                     mNextPackageId;\n};\n\n}   // namespace android\n\n#endif // _LIBS_UTILS_RESOURCE_TYPES_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/StreamingZipInflater.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __LIBS_STREAMINGZIPINFLATER_H\n#define __LIBS_STREAMINGZIPINFLATER_H\n\n#include <unistd.h>\n#include <inttypes.h>\n#include <zlib.h>\n\n#include <utils/Compat.h>\n\nnamespace android {\n\nclass StreamingZipInflater {\npublic:\n    static const size_t INPUT_CHUNK_SIZE = 64 * 1024;\n    static const size_t OUTPUT_CHUNK_SIZE = 64 * 1024;\n\n    // Flavor that pages in the compressed data from a fd\n    StreamingZipInflater(int fd, off64_t compDataStart, size_t uncompSize, size_t compSize);\n\n    // Flavor that gets the compressed data from an in-memory buffer\n    StreamingZipInflater(class FileMap* dataMap, size_t uncompSize);\n\n    ~StreamingZipInflater();\n\n    // read 'count' bytes of uncompressed data from the current position.  outBuf may\n    // be NULL, in which case the data is consumed and discarded.\n    ssize_t read(void* outBuf, size_t count);\n\n    // seeking backwards requires uncompressing fom the beginning, so is very\n    // expensive.  seeking forwards only requires uncompressing from the current\n    // position to the destination.\n    off64_t seekAbsolute(off64_t absoluteInputPosition);\n\nprivate:\n    void initInflateState();\n    int readNextChunk();\n\n    // where to find the uncompressed data\n    int mFd;\n    off64_t mInFileStart;         // where the compressed data lives in the file\n    class FileMap* mDataMap;\n\n    z_stream mInflateState;\n    bool mStreamNeedsInit;\n\n    // output invariants for this asset\n    uint8_t* mOutBuf;           // output buf for decompressed bytes\n    size_t mOutBufSize;         // allocated size of mOutBuf\n    size_t mOutTotalSize;       // total uncompressed size of the blob\n\n    // current output state bookkeeping\n    off64_t mOutCurPosition;      // current position in total offset\n    size_t mOutLastDecoded;     // last decoded byte + 1 in mOutbuf\n    size_t mOutDeliverable;     // next undelivered byte of decoded output in mOutBuf\n\n    // input invariants\n    uint8_t* mInBuf;\n    size_t mInBufSize;          // allocated size of mInBuf;\n    size_t mInTotalSize;        // total size of compressed data for this blob\n\n    // input state bookkeeping\n    size_t mInNextChunkOffset;  // offset from start of blob at which the next input chunk lies\n    // the z_stream contains state about input block consumption\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/TypeWrappers.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __TYPE_WRAPPERS_H\n#define __TYPE_WRAPPERS_H\n\n#include <androidfw/ResourceTypes.h>\n\nnamespace android {\n\nstruct TypeVariant {\n    TypeVariant(const ResTable_type* data)\n        : data(data) {}\n\n    class iterator {\n    public:\n        iterator& operator=(const iterator& rhs) {\n            mTypeVariant = rhs.mTypeVariant;\n            mIndex = rhs.mIndex;\n        }\n\n        bool operator==(const iterator& rhs) const {\n            return mTypeVariant == rhs.mTypeVariant && mIndex == rhs.mIndex;\n        }\n\n        bool operator!=(const iterator& rhs) const {\n            return mTypeVariant != rhs.mTypeVariant || mIndex != rhs.mIndex;\n        }\n\n        iterator operator++(int) {\n            uint32_t prevIndex = mIndex;\n            operator++();\n            return iterator(mTypeVariant, prevIndex);\n        }\n\n        const ResTable_entry* operator->() const {\n            return operator*();\n        }\n\n        uint32_t index() const {\n            return mIndex;\n        }\n\n        iterator& operator++();\n        const ResTable_entry* operator*() const;\n\n    private:\n        friend struct TypeVariant;\n        iterator(const TypeVariant* tv, uint32_t index)\n            : mTypeVariant(tv), mIndex(index) {}\n        const TypeVariant* mTypeVariant;\n        uint32_t mIndex;\n    };\n\n    iterator beginEntries() const {\n        return iterator(this, 0);\n    }\n\n    iterator endEntries() const {\n        return iterator(this, dtohl(data->entryCount));\n    }\n\n    const ResTable_type* data;\n};\n\n} // namespace android\n\n#endif // __TYPE_WRAPPERS_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/ZipFileRO.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * Read-only access to Zip archives, with minimal heap allocation.\n *\n * This is similar to the more-complete ZipFile class, but no attempt\n * has been made to make them interchangeable.  This class operates under\n * a very different set of assumptions and constraints.\n *\n * One such assumption is that if you're getting file descriptors for\n * use with this class as a child of a fork() operation, you must be on\n * a pread() to guarantee correct operation. This is because pread() can\n * atomically read at a file offset without worrying about a lock around an\n * lseek() + read() pair.\n */\n#ifndef __LIBS_ZIPFILERO_H\n#define __LIBS_ZIPFILERO_H\n\n#include <utils/Compat.h>\n#include <utils/Errors.h>\n#include <utils/FileMap.h>\n#include <utils/threads.h>\n\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <time.h>\n\ntypedef void* ZipArchiveHandle;\n\nnamespace android {\n\n/*\n * Trivial typedef to ensure that ZipEntryRO is not treated as a simple\n * integer.  We use NULL to indicate an invalid value.\n */\ntypedef void* ZipEntryRO;\n\n/*\n * Open a Zip archive for reading.\n *\n * Implemented as a thin wrapper over system/core/libziparchive.\n *\n * \"open\" and \"find entry by name\" are fast operations and use as little\n * memory as possible.\n *\n * We also support fast iteration over all entries in the file (with a\n * stable, but unspecified iteration order).\n *\n * NOTE: If this is used on file descriptors inherited from a fork() operation,\n * you must be on a platform that implements pread() to guarantee correctness\n * on the shared file descriptors.\n */\nclass ZipFileRO {\npublic:\n    /* Zip compression methods we support */\n    enum : uint16_t {\n        kCompressStored = 0,\n        kCompressDeflated = 8\n    };\n\n    /*\n     * Open an archive.\n     */\n    static ZipFileRO* open(const char* zipFileName);\n\n    /*\n     * Find an entry, by name.  Returns the entry identifier, or NULL if\n     * not found.\n     */\n    ZipEntryRO findEntryByName(const char* entryName) const;\n\n\n    /*\n     * Start iterating over the list of entries in the zip file. Requires\n     * a matching call to endIteration with the same cookie.\n     */\n    bool startIteration(void** cookie);\n    bool startIteration(void** cookie, const char* prefix, const char* suffix);\n\n    /**\n     * Return the next entry in iteration order, or NULL if there are no more\n     * entries in this archive.\n     */\n    ZipEntryRO nextEntry(void* cookie);\n\n    void endIteration(void* cookie);\n\n    void releaseEntry(ZipEntryRO entry) const;\n\n    /*\n     * Return the #of entries in the Zip archive.\n     */\n    int getNumEntries();\n\n    /*\n     * Copy the filename into the supplied buffer.  Returns 0 on success,\n     * -1 if \"entry\" is invalid, or the filename length if it didn't fit. The\n     * length, and the returned string, include the null-termination.\n     */\n    int getEntryFileName(ZipEntryRO entry, char* buffer, size_t bufLen) const;\n\n    /*\n     * Get the vital stats for an entry.  Pass in NULL pointers for anything\n     * you don't need.\n     *\n     * \"*pOffset\" holds the Zip file offset of the entry's data.\n     *\n     * Returns \"false\" if \"entry\" is bogus or if the data in the Zip file\n     * appears to be bad.\n     */\n    bool getEntryInfo(ZipEntryRO entry, uint16_t* pMethod, uint32_t* pUncompLen,\n        uint32_t* pCompLen, off64_t* pOffset, uint32_t* pModWhen,\n        uint32_t* pCrc32) const;\n\n    /*\n     * Create a new FileMap object that maps a subset of the archive.  For\n     * an uncompressed entry this effectively provides a pointer to the\n     * actual data, for a compressed entry this provides the input buffer\n     * for inflate().\n     */\n    FileMap* createEntryFileMap(ZipEntryRO entry) const;\n\n    /*\n     * Uncompress the data into a buffer.  Depending on the compression\n     * format, this is either an \"inflate\" operation or a memcpy.\n     *\n     * Use \"uncompLen\" from getEntryInfo() to determine the required\n     * buffer size.\n     *\n     * Returns \"true\" on success.\n     */\n    bool uncompressEntry(ZipEntryRO entry, void* buffer, size_t size) const;\n\n    /*\n     * Uncompress the data to an open file descriptor.\n     */\n    bool uncompressEntry(ZipEntryRO entry, int fd) const;\n\n    ~ZipFileRO();\n\nprivate:\n    /* these are private and not defined */\n    ZipFileRO(const ZipFileRO& src);\n    ZipFileRO& operator=(const ZipFileRO& src);\n\n    ZipFileRO(ZipArchiveHandle handle, char* fileName) : mHandle(handle),\n        mFileName(fileName)\n    {\n    }\n\n    const ZipArchiveHandle mHandle;\n    char* mFileName;\n};\n\n}; // namespace android\n\n#endif /*__LIBS_ZIPFILERO_H*/\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/ZipUtils.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Miscellaneous zip/gzip utility functions.\n//\n#ifndef __LIBS_ZIPUTILS_H\n#define __LIBS_ZIPUTILS_H\n\n#include <stdint.h>\n#include <string.h>\n#include <stdio.h>\n#include <time.h>\n\nnamespace android {\n\n/*\n * Container class for utility functions, primarily for namespace reasons.\n */\nclass ZipUtils {\npublic:\n    /*\n     * General utility function for uncompressing \"deflate\" data from a file\n     * to a buffer.\n     */\n    static bool inflateToBuffer(FILE* fp, void* buf, long uncompressedLen,\n        long compressedLen);\n    static bool inflateToBuffer(int fd, void* buf, long uncompressedLen,\n        long compressedLen);\n    static bool inflateToBuffer(void *in, void* buf, long uncompressedLen,\n        long compressedLen);\n\n    /*\n     * Someday we might want to make this generic and handle bzip2 \".bz2\"\n     * files too.\n     *\n     * We could declare gzip to be a sub-class of zip that has exactly\n     * one always-compressed entry, but we currently want to treat Zip\n     * and gzip as distinct, so there's no value.\n     *\n     * The zlib library has some gzip utilities, but it has no interface\n     * for extracting the uncompressed length of the file (you do *not*\n     * want to gzseek to the end).\n     *\n     * Pass in a seeked file pointer for the gzip file.  If this is a gzip\n     * file, we set our return values appropriately and return \"true\" with\n     * the file seeked to the start of the compressed data.\n     */\n    static bool examineGzip(FILE* fp, int* pCompressionMethod,\n        long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32);\n\n    /*\n     * Utility function to convert ZIP's time format to a timespec struct.\n     *\n     * NOTE: this method will clear all existing state from |timespec|.\n     */\n    static inline void zipTimeToTimespec(uint32_t when, struct tm* timespec) {\n        const uint32_t date = when >> 16;\n\n        memset(timespec, 0, sizeof(struct tm));\n        timespec->tm_year = ((date >> 9) & 0x7F) + 80; // Zip is years since 1980\n        timespec->tm_mon = ((date >> 5) & 0x0F) - 1;\n        timespec->tm_mday = date & 0x1F;\n\n        timespec->tm_hour = (when >> 11) & 0x1F;\n        timespec->tm_min = (when >> 5) & 0x3F;\n        timespec->tm_sec = (when & 0x1F) << 1;\n        timespec->tm_isdst = -1;\n    }\nprivate:\n    ZipUtils() {}\n    ~ZipUtils() {}\n};\n\n}; // namespace android\n\n#endif /*__LIBS_ZIPUTILS_H*/\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/androidfw/misc.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <sys/types.h>\n\n//\n// Handy utility functions and portability code.\n//\n#ifndef _LIBS_ANDROID_FW_MISC_H\n#define _LIBS_ANDROID_FW_MISC_H\n\nnamespace android {\n\n/*\n * Some utility functions for working with files.  These could be made\n * part of a \"File\" class.\n */\ntypedef enum FileType {\n    kFileTypeUnknown = 0,\n    kFileTypeNonexistent,       // i.e. ENOENT\n    kFileTypeRegular,\n    kFileTypeDirectory,\n    kFileTypeCharDev,\n    kFileTypeBlockDev,\n    kFileTypeFifo,\n    kFileTypeSymlink,\n    kFileTypeSocket,\n} FileType;\n/* get the file's type; follows symlinks */\nFileType getFileType(const char* fileName);\n/* get the file's modification date; returns -1 w/errno set on failure */\ntime_t getFileModDate(const char* fileName);\n\n}; // namespace android\n\n#endif // _LIBS_ANDROID_FW_MISC_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/private/README",
    "content": "This folder contains private include files.\n\nThese include files are part of the private implementation details of\nvarious framework components.  Use at your peril.\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/private/hwui/DrawGlInfo.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_HWUI_DRAW_GL_INFO_H\n#define ANDROID_HWUI_DRAW_GL_INFO_H\n\nnamespace android {\nnamespace uirenderer {\n\n/**\n * Structure used by OpenGLRenderer::callDrawGLFunction() to pass and\n * receive data from OpenGL functors.\n */\nstruct DrawGlInfo {\n    // Input: current clip rect\n    int clipLeft;\n    int clipTop;\n    int clipRight;\n    int clipBottom;\n\n    // Input: current width/height of destination surface\n    int width;\n    int height;\n\n    // Input: is the render target an FBO\n    bool isLayer;\n\n    // Input: current transform matrix, in OpenGL format\n    float transform[16];\n\n    // Output: dirty region to redraw\n    float dirtyLeft;\n    float dirtyTop;\n    float dirtyRight;\n    float dirtyBottom;\n\n    /**\n     * Values used as the \"what\" parameter of the functor.\n     */\n    enum Mode {\n        // Indicates that the functor is called to perform a draw\n        kModeDraw,\n        // Indicates the the functor is called only to perform\n        // processing and that no draw should be attempted\n        kModeProcess,\n        // Same as kModeProcess, however there is no GL context because it was\n        // lost or destroyed\n        kModeProcessNoContext,\n        // Invoked every time the UI thread pushes over a frame to the render thread\n        // *and the owning view has a dirty display list*. This is a signal to sync\n        // any data that needs to be shared between the UI thread and the render thread.\n        // During this time the UI thread is blocked.\n        kModeSync\n    };\n\n    /**\n     * Values used by OpenGL functors to tell the framework\n     * what to do next.\n     */\n    enum Status {\n        // The functor is done\n        kStatusDone = 0x0,\n        // DisplayList actually issued GL drawing commands.\n        // This is used to signal the HardwareRenderer that the\n        // buffers should be flipped - otherwise, there were no\n        // changes to the buffer, so no need to flip. Some hardware\n        // has issues with stale buffer contents when no GL\n        // commands are issued.\n        kStatusDrew = 0x4\n    };\n}; // struct DrawGlInfo\n\n}; // namespace uirenderer\n}; // namespace android\n\n#endif // ANDROID_HWUI_DRAW_GL_INFO_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/storage/IMountService.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_IMOUNTSERVICE_H\n#define ANDROID_IMOUNTSERVICE_H\n\n#include <storage/IMountServiceListener.h>\n#include <storage/IMountShutdownObserver.h>\n#include <storage/IObbActionListener.h>\n\n#include <utils/String8.h>\n\n#include <binder/IInterface.h>\n#include <binder/Parcel.h>\n\nnamespace android {\n\nclass IMountService: public IInterface {\npublic:\n    DECLARE_META_INTERFACE(MountService);\n\n    virtual void registerListener(const sp<IMountServiceListener>& listener) = 0;\n    virtual void\n            unregisterListener(const sp<IMountServiceListener>& listener) = 0;\n    virtual bool isUsbMassStorageConnected() = 0;\n    virtual void setUsbMassStorageEnabled(const bool enable) = 0;\n    virtual bool isUsbMassStorageEnabled() = 0;\n    virtual int32_t mountVolume(const String16& mountPoint) = 0;\n    virtual int32_t unmountVolume(\n            const String16& mountPoint, const bool force, const bool removeEncryption) = 0;\n    virtual int32_t formatVolume(const String16& mountPoint) = 0;\n    virtual int32_t\n            getStorageUsers(const String16& mountPoint, int32_t** users) = 0;\n    virtual int32_t getVolumeState(const String16& mountPoint) = 0;\n    virtual int32_t createSecureContainer(const String16& id,\n            const int32_t sizeMb, const String16& fstype, const String16& key,\n            const int32_t ownerUid) = 0;\n    virtual int32_t finalizeSecureContainer(const String16& id) = 0;\n    virtual int32_t destroySecureContainer(const String16& id) = 0;\n    virtual int32_t mountSecureContainer(const String16& id,\n            const String16& key, const int32_t ownerUid) = 0;\n    virtual int32_t\n            unmountSecureContainer(const String16& id, const bool force) = 0;\n    virtual bool isSecureContainerMounted(const String16& id) = 0;\n    virtual int32_t renameSecureContainer(const String16& oldId,\n            const String16& newId) = 0;\n    virtual bool getSecureContainerPath(const String16& id, String16& path) = 0;\n    virtual int32_t getSecureContainerList(const String16& id,\n            String16*& containers) = 0;\n    virtual void shutdown(const sp<IMountShutdownObserver>& observer) = 0;\n    virtual void finishMediaUpdate() = 0;\n    virtual void mountObb(const String16& rawPath, const String16& canonicalPath,\n            const String16& key, const sp<IObbActionListener>& token,\n            const int32_t nonce) = 0;\n    virtual void unmountObb(const String16& filename, const bool force,\n            const sp<IObbActionListener>& token, const int32_t nonce) = 0;\n    virtual bool isObbMounted(const String16& filename) = 0;\n    virtual bool getMountedObbPath(const String16& filename, String16& path) = 0;\n    virtual int32_t decryptStorage(const String16& password) = 0;\n    virtual int32_t encryptStorage(const String16& password) = 0;\n};\n\n// ----------------------------------------------------------------------------\n\nclass BnMountService: public BnInterface<IMountService> {\npublic:\n    virtual status_t onTransact(uint32_t code, const Parcel& data,\n            Parcel* reply, uint32_t flags = 0);\n};\n\n}\n; // namespace android\n\n#endif // ANDROID_IMOUNTSERVICE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/storage/IMountServiceListener.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_IMOUNTSERVICELISTENER_H\n#define ANDROID_IMOUNTSERVICELISTENER_H\n\n#include <binder/IInterface.h>\n#include <binder/Parcel.h>\n\nnamespace android {\n\nclass IMountServiceListener: public IInterface {\npublic:\n    DECLARE_META_INTERFACE(MountServiceListener);\n\n    virtual void onUsbMassStorageConnectionChanged(const bool connected) = 0;\n    virtual void onStorageStateChanged(const String16& path,\n            const String16& oldState, const String16& newState) = 0;\n};\n\n// ----------------------------------------------------------------------------\n\nclass BnMountServiceListener: public BnInterface<IMountServiceListener> {\npublic:\n    virtual status_t onTransact(uint32_t code, const Parcel& data,\n            Parcel* reply, uint32_t flags = 0);\n};\n\n}\n; // namespace android\n\n#endif // ANDROID_IMOUNTSERVICELISTENER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/storage/IMountShutdownObserver.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_IMOUNTSHUTDOWNOBSERVER_H\n#define ANDROID_IMOUNTSHUTDOWNOBSERVER_H\n\n#include <binder/IInterface.h>\n#include <binder/Parcel.h>\n\nnamespace android {\n\nclass IMountShutdownObserver: public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(MountShutdownObserver);\n\n    virtual void onShutDownComplete(const int32_t statusCode) = 0;\n};\n\n// ----------------------------------------------------------------------------\n\nclass BnMountShutdownObserver: public BnInterface<IMountShutdownObserver>\n{\npublic:\n    virtual status_t    onTransact( uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n};\n\n}; // namespace android\n\n#endif // ANDROID_IMOUNTSHUTDOWNOBSERVER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/include/storage/IObbActionListener.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_IOBBACTIONLISTENER_H\n#define ANDROID_IOBBACTIONLISTENER_H\n\n#include <binder/IInterface.h>\n#include <binder/Parcel.h>\n\n#include <utils/String16.h>\n\nnamespace android {\n\nclass IObbActionListener: public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(ObbActionListener);\n\n    virtual void onObbResult(const String16& filename, const int32_t nonce, const int32_t state) = 0;\n};\n\n// ----------------------------------------------------------------------------\n\nclass BnObbActionListener: public BnInterface<IObbActionListener>\n{\npublic:\n    virtual status_t    onTransact( uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n};\n\n}; // namespace android\n\n#endif // ANDROID_IOBBACTIONLISTENER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/Android.mk",
    "content": "# Copyright (C) 2010 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nLOCAL_PATH:= $(call my-dir)\n\n# libandroidfw is partially built for the host (used by obbtool, aapt, and others)\n# These files are common to host and target builds.\n\ncommonSources := \\\n    Asset.cpp \\\n    AssetDir.cpp \\\n    AssetManager.cpp \\\n    LocaleData.cpp \\\n    misc.cpp \\\n    ObbFile.cpp \\\n    ResourceTypes.cpp \\\n    StreamingZipInflater.cpp \\\n    TypeWrappers.cpp \\\n    ZipFileRO.cpp \\\n    ZipUtils.cpp\n\ndeviceSources := \\\n    $(commonSources) \\\n    BackupData.cpp \\\n    BackupHelpers.cpp \\\n    CursorWindow.cpp \\\n    DisplayEventDispatcher.cpp\n\nhostSources := $(commonSources)\n\n# For the host\n# =====================================================\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE:= libandroidfw\nLOCAL_MODULE_HOST_OS := darwin linux windows\nLOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS\nLOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code\nLOCAL_SRC_FILES:= $(hostSources)\nLOCAL_C_INCLUDES := external/zlib\n\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\n\n# For the device\n# =====================================================\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE:= libandroidfw\nLOCAL_SRC_FILES:= $(deviceSources)\nLOCAL_C_INCLUDES := \\\n    system/core/include\nLOCAL_STATIC_LIBRARIES := libziparchive libbase\nLOCAL_SHARED_LIBRARIES := \\\n    libbinder \\\n    liblog \\\n    libcutils \\\n    libgui \\\n    libutils \\\n    libz\n\nLOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code\n\ninclude $(BUILD_SHARED_LIBRARY)\n\n\n# Include subdirectory makefiles\n# ============================================================\n\n# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework\n# team really wants is to build the stuff defined by this makefile.\nifeq (,$(ONE_SHOT_MAKEFILE))\ninclude $(call first-makefiles-under,$(LOCAL_PATH))\nendif\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/Asset.cpp",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Provide access to a read-only asset.\n//\n\n#define LOG_TAG \"asset\"\n//#define NDEBUG 0\n\n#include <androidfw/Asset.h>\n#include <androidfw/StreamingZipInflater.h>\n#include <androidfw/ZipFileRO.h>\n#include <androidfw/ZipUtils.h>\n#include <utils/Atomic.h>\n#include <utils/FileMap.h>\n#include <utils/Log.h>\n#include <utils/threads.h>\n\n#include <assert.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <memory.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <unistd.h>\n\nusing namespace android;\n\n#ifndef O_BINARY\n# define O_BINARY 0\n#endif\n\nstatic const bool kIsDebug = false;\n\nstatic Mutex gAssetLock;\nstatic int32_t gCount = 0;\nstatic Asset* gHead = NULL;\nstatic Asset* gTail = NULL;\n\nint32_t Asset::getGlobalCount()\n{\n    AutoMutex _l(gAssetLock);\n    return gCount;\n}\n\nString8 Asset::getAssetAllocations()\n{\n    AutoMutex _l(gAssetLock);\n    String8 res;\n    Asset* cur = gHead;\n    while (cur != NULL) {\n        if (cur->isAllocated()) {\n            res.append(\"    \");\n            res.append(cur->getAssetSource());\n            off64_t size = (cur->getLength()+512)/1024;\n            char buf[64];\n            sprintf(buf, \": %dK\\n\", (int)size);\n            res.append(buf);\n        }\n        cur = cur->mNext;\n    }\n\n    return res;\n}\n\nAsset::Asset(void)\n    : mAccessMode(ACCESS_UNKNOWN)\n{\n    AutoMutex _l(gAssetLock);\n    gCount++;\n    mNext = mPrev = NULL;\n    if (gTail == NULL) {\n        gHead = gTail = this;\n    } else {\n        mPrev = gTail;\n        gTail->mNext = this;\n        gTail = this;\n    }\n    if (kIsDebug) {\n        ALOGI(\"Creating Asset %p #%d\\n\", this, gCount);\n    }\n}\n\nAsset::~Asset(void)\n{\n    AutoMutex _l(gAssetLock);\n    gCount--;\n    if (gHead == this) {\n        gHead = mNext;\n    }\n    if (gTail == this) {\n        gTail = mPrev;\n    }\n    if (mNext != NULL) {\n        mNext->mPrev = mPrev;\n    }\n    if (mPrev != NULL) {\n        mPrev->mNext = mNext;\n    }\n    mNext = mPrev = NULL;\n    if (kIsDebug) {\n        ALOGI(\"Destroying Asset in %p #%d\\n\", this, gCount);\n    }\n}\n\n/*\n * Create a new Asset from a file on disk.  There is a fair chance that\n * the file doesn't actually exist.\n *\n * We can use \"mode\" to decide how we want to go about it.\n */\n/*static*/ Asset* Asset::createFromFile(const char* fileName, AccessMode mode)\n{\n    _FileAsset* pAsset;\n    status_t result;\n    off64_t length;\n    int fd;\n\n    fd = open(fileName, O_RDONLY | O_BINARY);\n    if (fd < 0)\n        return NULL;\n\n    /*\n     * Under Linux, the lseek fails if we actually opened a directory.  To\n     * be correct we should test the file type explicitly, but since we\n     * always open things read-only it doesn't really matter, so there's\n     * no value in incurring the extra overhead of an fstat() call.\n     */\n    // TODO(kroot): replace this with fstat despite the plea above.\n#if 1\n    length = lseek64(fd, 0, SEEK_END);\n    if (length < 0) {\n        ::close(fd);\n        return NULL;\n    }\n    (void) lseek64(fd, 0, SEEK_SET);\n#else\n    struct stat st;\n    if (fstat(fd, &st) < 0) {\n        ::close(fd);\n        return NULL;\n    }\n\n    if (!S_ISREG(st.st_mode)) {\n        ::close(fd);\n        return NULL;\n    }\n#endif\n\n    pAsset = new _FileAsset;\n    result = pAsset->openChunk(fileName, fd, 0, length);\n    if (result != NO_ERROR) {\n        delete pAsset;\n        return NULL;\n    }\n\n    pAsset->mAccessMode = mode;\n    return pAsset;\n}\n\n\n/*\n * Create a new Asset from a compressed file on disk.  There is a fair chance\n * that the file doesn't actually exist.\n *\n * We currently support gzip files.  We might want to handle .bz2 someday.\n */\n/*static*/ Asset* Asset::createFromCompressedFile(const char* fileName,\n    AccessMode mode)\n{\n    _CompressedAsset* pAsset;\n    status_t result;\n    off64_t fileLen;\n    bool scanResult;\n    long offset;\n    int method;\n    long uncompressedLen, compressedLen;\n    int fd;\n\n    fd = open(fileName, O_RDONLY | O_BINARY);\n    if (fd < 0)\n        return NULL;\n\n    fileLen = lseek(fd, 0, SEEK_END);\n    if (fileLen < 0) {\n        ::close(fd);\n        return NULL;\n    }\n    (void) lseek(fd, 0, SEEK_SET);\n\n    /* want buffered I/O for the file scan; must dup so fclose() is safe */\n    FILE* fp = fdopen(dup(fd), \"rb\");\n    if (fp == NULL) {\n        ::close(fd);\n        return NULL;\n    }\n\n    unsigned long crc32;\n    scanResult = ZipUtils::examineGzip(fp, &method, &uncompressedLen,\n                    &compressedLen, &crc32);\n    offset = ftell(fp);\n    fclose(fp);\n    if (!scanResult) {\n        ALOGD(\"File '%s' is not in gzip format\\n\", fileName);\n        ::close(fd);\n        return NULL;\n    }\n\n    pAsset = new _CompressedAsset;\n    result = pAsset->openChunk(fd, offset, method, uncompressedLen,\n                compressedLen);\n    if (result != NO_ERROR) {\n        delete pAsset;\n        return NULL;\n    }\n\n    pAsset->mAccessMode = mode;\n    return pAsset;\n}\n\n\n#if 0\n/*\n * Create a new Asset from part of an open file.\n */\n/*static*/ Asset* Asset::createFromFileSegment(int fd, off64_t offset,\n    size_t length, AccessMode mode)\n{\n    _FileAsset* pAsset;\n    status_t result;\n\n    pAsset = new _FileAsset;\n    result = pAsset->openChunk(NULL, fd, offset, length);\n    if (result != NO_ERROR)\n        return NULL;\n\n    pAsset->mAccessMode = mode;\n    return pAsset;\n}\n\n/*\n * Create a new Asset from compressed data in an open file.\n */\n/*static*/ Asset* Asset::createFromCompressedData(int fd, off64_t offset,\n    int compressionMethod, size_t uncompressedLen, size_t compressedLen,\n    AccessMode mode)\n{\n    _CompressedAsset* pAsset;\n    status_t result;\n\n    pAsset = new _CompressedAsset;\n    result = pAsset->openChunk(fd, offset, compressionMethod,\n                uncompressedLen, compressedLen);\n    if (result != NO_ERROR)\n        return NULL;\n\n    pAsset->mAccessMode = mode;\n    return pAsset;\n}\n#endif\n\n/*\n * Create a new Asset from a memory mapping.\n */\n/*static*/ Asset* Asset::createFromUncompressedMap(FileMap* dataMap,\n    AccessMode mode)\n{\n    _FileAsset* pAsset;\n    status_t result;\n\n    pAsset = new _FileAsset;\n    result = pAsset->openChunk(dataMap);\n    if (result != NO_ERROR)\n        return NULL;\n\n    pAsset->mAccessMode = mode;\n    return pAsset;\n}\n\n/*\n * Create a new Asset from compressed data in a memory mapping.\n */\n/*static*/ Asset* Asset::createFromCompressedMap(FileMap* dataMap,\n    size_t uncompressedLen, AccessMode mode)\n{\n    _CompressedAsset* pAsset;\n    status_t result;\n\n    pAsset = new _CompressedAsset;\n    result = pAsset->openChunk(dataMap, uncompressedLen);\n    if (result != NO_ERROR)\n        return NULL;\n\n    pAsset->mAccessMode = mode;\n    return pAsset;\n}\n\n\n/*\n * Do generic seek() housekeeping.  Pass in the offset/whence values from\n * the seek request, along with the current chunk offset and the chunk\n * length.\n *\n * Returns the new chunk offset, or -1 if the seek is illegal.\n */\noff64_t Asset::handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn)\n{\n    off64_t newOffset;\n\n    switch (whence) {\n    case SEEK_SET:\n        newOffset = offset;\n        break;\n    case SEEK_CUR:\n        newOffset = curPosn + offset;\n        break;\n    case SEEK_END:\n        newOffset = maxPosn + offset;\n        break;\n    default:\n        ALOGW(\"unexpected whence %d\\n\", whence);\n        // this was happening due to an off64_t size mismatch\n        assert(false);\n        return (off64_t) -1;\n    }\n\n    if (newOffset < 0 || newOffset > maxPosn) {\n        ALOGW(\"seek out of range: want %ld, end=%ld\\n\",\n            (long) newOffset, (long) maxPosn);\n        return (off64_t) -1;\n    }\n\n    return newOffset;\n}\n\n\n/*\n * ===========================================================================\n *      _FileAsset\n * ===========================================================================\n */\n\n/*\n * Constructor.\n */\n_FileAsset::_FileAsset(void)\n    : mStart(0), mLength(0), mOffset(0), mFp(NULL), mFileName(NULL), mMap(NULL), mBuf(NULL)\n{\n}\n\n/*\n * Destructor.  Release resources.\n */\n_FileAsset::~_FileAsset(void)\n{\n    close();\n}\n\n/*\n * Operate on a chunk of an uncompressed file.\n *\n * Zero-length chunks are allowed.\n */\nstatus_t _FileAsset::openChunk(const char* fileName, int fd, off64_t offset, size_t length)\n{\n    assert(mFp == NULL);    // no reopen\n    assert(mMap == NULL);\n    assert(fd >= 0);\n    assert(offset >= 0);\n\n    /*\n     * Seek to end to get file length.\n     */\n    off64_t fileLength;\n    fileLength = lseek64(fd, 0, SEEK_END);\n    if (fileLength == (off64_t) -1) {\n        // probably a bad file descriptor\n        ALOGD(\"failed lseek (errno=%d)\\n\", errno);\n        return UNKNOWN_ERROR;\n    }\n\n    if ((off64_t) (offset + length) > fileLength) {\n        ALOGD(\"start (%ld) + len (%ld) > end (%ld)\\n\",\n            (long) offset, (long) length, (long) fileLength);\n        return BAD_INDEX;\n    }\n\n    /* after fdopen, the fd will be closed on fclose() */\n    mFp = fdopen(fd, \"rb\");\n    if (mFp == NULL)\n        return UNKNOWN_ERROR;\n\n    mStart = offset;\n    mLength = length;\n    assert(mOffset == 0);\n\n    /* seek the FILE* to the start of chunk */\n    if (fseek(mFp, mStart, SEEK_SET) != 0) {\n        assert(false);\n    }\n\n    mFileName = fileName != NULL ? strdup(fileName) : NULL;\n\n    return NO_ERROR;\n}\n\n/*\n * Create the chunk from the map.\n */\nstatus_t _FileAsset::openChunk(FileMap* dataMap)\n{\n    assert(mFp == NULL);    // no reopen\n    assert(mMap == NULL);\n    assert(dataMap != NULL);\n\n    mMap = dataMap;\n    mStart = -1;            // not used\n    mLength = dataMap->getDataLength();\n    assert(mOffset == 0);\n\n    return NO_ERROR;\n}\n\n/*\n * Read a chunk of data.\n */\nssize_t _FileAsset::read(void* buf, size_t count)\n{\n    size_t maxLen;\n    size_t actual;\n\n    assert(mOffset >= 0 && mOffset <= mLength);\n\n    if (getAccessMode() == ACCESS_BUFFER) {\n        /*\n         * On first access, read or map the entire file.  The caller has\n         * requested buffer access, either because they're going to be\n         * using the buffer or because what they're doing has appropriate\n         * performance needs and access patterns.\n         */\n        if (mBuf == NULL)\n            getBuffer(false);\n    }\n\n    /* adjust count if we're near EOF */\n    maxLen = mLength - mOffset;\n    if (count > maxLen)\n        count = maxLen;\n\n    if (!count)\n        return 0;\n\n    if (mMap != NULL) {\n        /* copy from mapped area */\n        //printf(\"map read\\n\");\n        memcpy(buf, (char*)mMap->getDataPtr() + mOffset, count);\n        actual = count;\n    } else if (mBuf != NULL) {\n        /* copy from buffer */\n        //printf(\"buf read\\n\");\n        memcpy(buf, (char*)mBuf + mOffset, count);\n        actual = count;\n    } else {\n        /* read from the file */\n        //printf(\"file read\\n\");\n        if (ftell(mFp) != mStart + mOffset) {\n            ALOGE(\"Hosed: %ld != %ld+%ld\\n\",\n                ftell(mFp), (long) mStart, (long) mOffset);\n            assert(false);\n        }\n\n        /*\n         * This returns 0 on error or eof.  We need to use ferror() or feof()\n         * to tell the difference, but we don't currently have those on the\n         * device.  However, we know how much data is *supposed* to be in the\n         * file, so if we don't read the full amount we know something is\n         * hosed.\n         */\n        actual = fread(buf, 1, count, mFp);\n        if (actual == 0)        // something failed -- I/O error?\n            return -1;\n\n        assert(actual == count);\n    }\n\n    mOffset += actual;\n    return actual;\n}\n\n/*\n * Seek to a new position.\n */\noff64_t _FileAsset::seek(off64_t offset, int whence)\n{\n    off64_t newPosn;\n    off64_t actualOffset;\n\n    // compute new position within chunk\n    newPosn = handleSeek(offset, whence, mOffset, mLength);\n    if (newPosn == (off64_t) -1)\n        return newPosn;\n\n    actualOffset = mStart + newPosn;\n\n    if (mFp != NULL) {\n        if (fseek(mFp, (long) actualOffset, SEEK_SET) != 0)\n            return (off64_t) -1;\n    }\n\n    mOffset = actualOffset - mStart;\n    return mOffset;\n}\n\n/*\n * Close the asset.\n */\nvoid _FileAsset::close(void)\n{\n    if (mMap != NULL) {\n        delete mMap;\n        mMap = NULL;\n    }\n    if (mBuf != NULL) {\n        delete[] mBuf;\n        mBuf = NULL;\n    }\n\n    if (mFileName != NULL) {\n        free(mFileName);\n        mFileName = NULL;\n    }\n\n    if (mFp != NULL) {\n        // can only be NULL when called from destructor\n        // (otherwise we would never return this object)\n        fclose(mFp);\n        mFp = NULL;\n    }\n}\n\n/*\n * Return a read-only pointer to a buffer.\n *\n * We can either read the whole thing in or map the relevant piece of\n * the source file.  Ideally a map would be established at a higher\n * level and we'd be using a different object, but we didn't, so we\n * deal with it here.\n */\nconst void* _FileAsset::getBuffer(bool wordAligned)\n{\n    /* subsequent requests just use what we did previously */\n    if (mBuf != NULL)\n        return mBuf;\n    if (mMap != NULL) {\n        if (!wordAligned) {\n            return  mMap->getDataPtr();\n        }\n        return ensureAlignment(mMap);\n    }\n\n    assert(mFp != NULL);\n\n    if (mLength < kReadVsMapThreshold) {\n        unsigned char* buf;\n        long allocLen;\n\n        /* zero-length files are allowed; not sure about zero-len allocs */\n        /* (works fine with gcc + x86linux) */\n        allocLen = mLength;\n        if (mLength == 0)\n            allocLen = 1;\n\n        buf = new unsigned char[allocLen];\n        if (buf == NULL) {\n            ALOGE(\"alloc of %ld bytes failed\\n\", (long) allocLen);\n            return NULL;\n        }\n\n        ALOGV(\"Asset %p allocating buffer size %d (smaller than threshold)\", this, (int)allocLen);\n        if (mLength > 0) {\n            long oldPosn = ftell(mFp);\n            fseek(mFp, mStart, SEEK_SET);\n            if (fread(buf, 1, mLength, mFp) != (size_t) mLength) {\n                ALOGE(\"failed reading %ld bytes\\n\", (long) mLength);\n                delete[] buf;\n                return NULL;\n            }\n            fseek(mFp, oldPosn, SEEK_SET);\n        }\n\n        ALOGV(\" getBuffer: loaded into buffer\\n\");\n\n        mBuf = buf;\n        return mBuf;\n    } else {\n        FileMap* map;\n\n        map = new FileMap;\n        if (!map->create(NULL, fileno(mFp), mStart, mLength, true)) {\n            delete map;\n            return NULL;\n        }\n\n        ALOGV(\" getBuffer: mapped\\n\");\n\n        mMap = map;\n        if (!wordAligned) {\n            return  mMap->getDataPtr();\n        }\n        return ensureAlignment(mMap);\n    }\n}\n\nint _FileAsset::openFileDescriptor(off64_t* outStart, off64_t* outLength) const\n{\n    if (mMap != NULL) {\n        const char* fname = mMap->getFileName();\n        if (fname == NULL) {\n            fname = mFileName;\n        }\n        if (fname == NULL) {\n            return -1;\n        }\n        *outStart = mMap->getDataOffset();\n        *outLength = mMap->getDataLength();\n        return open(fname, O_RDONLY | O_BINARY);\n    }\n    if (mFileName == NULL) {\n        return -1;\n    }\n    *outStart = mStart;\n    *outLength = mLength;\n    return open(mFileName, O_RDONLY | O_BINARY);\n}\n\nconst void* _FileAsset::ensureAlignment(FileMap* map)\n{\n    void* data = map->getDataPtr();\n    if ((((size_t)data)&0x3) == 0) {\n        // We can return this directly if it is aligned on a word\n        // boundary.\n        ALOGV(\"Returning aligned FileAsset %p (%s).\", this,\n                getAssetSource());\n        return data;\n    }\n    // If not aligned on a word boundary, then we need to copy it into\n    // our own buffer.\n    ALOGV(\"Copying FileAsset %p (%s) to buffer size %d to make it aligned.\", this,\n            getAssetSource(), (int)mLength);\n    unsigned char* buf = new unsigned char[mLength];\n    if (buf == NULL) {\n        ALOGE(\"alloc of %ld bytes failed\\n\", (long) mLength);\n        return NULL;\n    }\n    memcpy(buf, data, mLength);\n    mBuf = buf;\n    return buf;\n}\n\n/*\n * ===========================================================================\n *      _CompressedAsset\n * ===========================================================================\n */\n\n/*\n * Constructor.\n */\n_CompressedAsset::_CompressedAsset(void)\n    : mStart(0), mCompressedLen(0), mUncompressedLen(0), mOffset(0),\n      mMap(NULL), mFd(-1), mZipInflater(NULL), mBuf(NULL)\n{\n}\n\n/*\n * Destructor.  Release resources.\n */\n_CompressedAsset::~_CompressedAsset(void)\n{\n    close();\n}\n\n/*\n * Open a chunk of compressed data inside a file.\n *\n * This currently just sets up some values and returns.  On the first\n * read, we expand the entire file into a buffer and return data from it.\n */\nstatus_t _CompressedAsset::openChunk(int fd, off64_t offset,\n    int compressionMethod, size_t uncompressedLen, size_t compressedLen)\n{\n    assert(mFd < 0);        // no re-open\n    assert(mMap == NULL);\n    assert(fd >= 0);\n    assert(offset >= 0);\n    assert(compressedLen > 0);\n\n    if (compressionMethod != ZipFileRO::kCompressDeflated) {\n        assert(false);\n        return UNKNOWN_ERROR;\n    }\n\n    mStart = offset;\n    mCompressedLen = compressedLen;\n    mUncompressedLen = uncompressedLen;\n    assert(mOffset == 0);\n    mFd = fd;\n    assert(mBuf == NULL);\n\n    if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) {\n        mZipInflater = new StreamingZipInflater(mFd, offset, uncompressedLen, compressedLen);\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Open a chunk of compressed data in a mapped region.\n *\n * Nothing is expanded until the first read call.\n */\nstatus_t _CompressedAsset::openChunk(FileMap* dataMap, size_t uncompressedLen)\n{\n    assert(mFd < 0);        // no re-open\n    assert(mMap == NULL);\n    assert(dataMap != NULL);\n\n    mMap = dataMap;\n    mStart = -1;        // not used\n    mCompressedLen = dataMap->getDataLength();\n    mUncompressedLen = uncompressedLen;\n    assert(mOffset == 0);\n\n    if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) {\n        mZipInflater = new StreamingZipInflater(dataMap, uncompressedLen);\n    }\n    return NO_ERROR;\n}\n\n/*\n * Read data from a chunk of compressed data.\n *\n * [For now, that's just copying data out of a buffer.]\n */\nssize_t _CompressedAsset::read(void* buf, size_t count)\n{\n    size_t maxLen;\n    size_t actual;\n\n    assert(mOffset >= 0 && mOffset <= mUncompressedLen);\n\n    /* If we're relying on a streaming inflater, go through that */\n    if (mZipInflater) {\n        actual = mZipInflater->read(buf, count);\n    } else {\n        if (mBuf == NULL) {\n            if (getBuffer(false) == NULL)\n                return -1;\n        }\n        assert(mBuf != NULL);\n\n        /* adjust count if we're near EOF */\n        maxLen = mUncompressedLen - mOffset;\n        if (count > maxLen)\n            count = maxLen;\n\n        if (!count)\n            return 0;\n\n        /* copy from buffer */\n        //printf(\"comp buf read\\n\");\n        memcpy(buf, (char*)mBuf + mOffset, count);\n        actual = count;\n    }\n\n    mOffset += actual;\n    return actual;\n}\n\n/*\n * Handle a seek request.\n *\n * If we're working in a streaming mode, this is going to be fairly\n * expensive, because it requires plowing through a bunch of compressed\n * data.\n */\noff64_t _CompressedAsset::seek(off64_t offset, int whence)\n{\n    off64_t newPosn;\n\n    // compute new position within chunk\n    newPosn = handleSeek(offset, whence, mOffset, mUncompressedLen);\n    if (newPosn == (off64_t) -1)\n        return newPosn;\n\n    if (mZipInflater) {\n        mZipInflater->seekAbsolute(newPosn);\n    }\n    mOffset = newPosn;\n    return mOffset;\n}\n\n/*\n * Close the asset.\n */\nvoid _CompressedAsset::close(void)\n{\n    if (mMap != NULL) {\n        delete mMap;\n        mMap = NULL;\n    }\n\n    delete[] mBuf;\n    mBuf = NULL;\n\n    delete mZipInflater;\n    mZipInflater = NULL;\n\n    if (mFd > 0) {\n        ::close(mFd);\n        mFd = -1;\n    }\n}\n\n/*\n * Get a pointer to a read-only buffer of data.\n *\n * The first time this is called, we expand the compressed data into a\n * buffer.\n */\nconst void* _CompressedAsset::getBuffer(bool)\n{\n    unsigned char* buf = NULL;\n\n    if (mBuf != NULL)\n        return mBuf;\n\n    /*\n     * Allocate a buffer and read the file into it.\n     */\n    buf = new unsigned char[mUncompressedLen];\n    if (buf == NULL) {\n        ALOGW(\"alloc %ld bytes failed\\n\", (long) mUncompressedLen);\n        goto bail;\n    }\n\n    if (mMap != NULL) {\n        if (!ZipUtils::inflateToBuffer(mMap->getDataPtr(), buf,\n                mUncompressedLen, mCompressedLen))\n            goto bail;\n    } else {\n        assert(mFd >= 0);\n\n        /*\n         * Seek to the start of the compressed data.\n         */\n        if (lseek(mFd, mStart, SEEK_SET) != mStart)\n            goto bail;\n\n        /*\n         * Expand the data into it.\n         */\n        if (!ZipUtils::inflateToBuffer(mFd, buf, mUncompressedLen,\n                mCompressedLen))\n            goto bail;\n    }\n\n    /*\n     * Success - now that we have the full asset in RAM we\n     * no longer need the streaming inflater\n     */\n    delete mZipInflater;\n    mZipInflater = NULL;\n\n    mBuf = buf;\n    buf = NULL;\n\nbail:\n    delete[] buf;\n    return mBuf;\n}\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/AssetDir.cpp",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Provide access to a virtual directory in \"asset space\".  Most of the\n// implementation is in the header file or in friend functions in\n// AssetManager.\n//\n#include <androidfw/AssetDir.h>\n\nusing namespace android;\n\n\n/*\n * Find a matching entry in a vector of FileInfo.  Because it's sorted, we\n * can use a binary search.\n *\n * Assumes the vector is sorted in ascending order.\n */\n/*static*/ int AssetDir::FileInfo::findEntry(const SortedVector<FileInfo>* pVector,\n    const String8& fileName)\n{\n    FileInfo tmpInfo;\n\n    tmpInfo.setFileName(fileName);\n    return pVector->indexOf(tmpInfo);\n\n#if 0  // don't need this after all (uses 1/2 compares of SortedVector though)\n    int lo, hi, cur;\n\n    lo = 0;\n    hi = pVector->size() -1;\n    while (lo <= hi) {\n        int cmp;\n\n        cur = (hi + lo) / 2;\n        cmp = strcmp(pVector->itemAt(cur).getFileName(), fileName);\n        if (cmp == 0) {\n            /* match, bail */\n            return cur;\n        } else if (cmp < 0) {\n            /* too low */\n            lo = cur + 1;\n        } else {\n            /* too high */\n            hi = cur -1;\n        }\n    }\n\n    return -1;\n#endif\n}\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/AssetManager.cpp",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Provide access to read-only assets.\n//\n\n#define LOG_TAG \"asset\"\n#define ATRACE_TAG ATRACE_TAG_RESOURCES\n//#define LOG_NDEBUG 0\n\n#include <androidfw/Asset.h>\n#include <androidfw/AssetDir.h>\n#include <androidfw/AssetManager.h>\n#include <androidfw/misc.h>\n#include <androidfw/ResourceTypes.h>\n#include <androidfw/ZipFileRO.h>\n#include <utils/Atomic.h>\n#include <utils/Log.h>\n#include <utils/String8.h>\n#include <utils/String8.h>\n#include <utils/threads.h>\n#include <utils/Timers.h>\n#include <utils/Trace.h>\n\n#include <assert.h>\n#include <dirent.h>\n#include <errno.h>\n#include <string.h> // strerror\n#include <strings.h>\n\n#ifndef TEMP_FAILURE_RETRY\n/* Used to retry syscalls that can return EINTR. */\n#define TEMP_FAILURE_RETRY(exp) ({         \\\n    typeof (exp) _rc;                      \\\n    do {                                   \\\n        _rc = (exp);                       \\\n    } while (_rc == -1 && errno == EINTR); \\\n    _rc; })\n#endif\n\nusing namespace android;\n\nstatic const bool kIsDebug = false;\n\n/*\n * Names for default app, locale, and vendor.  We might want to change\n * these to be an actual locale, e.g. always use en-US as the default.\n */\nstatic const char* kDefaultLocale = \"default\";\nstatic const char* kDefaultVendor = \"default\";\nstatic const char* kAssetsRoot = \"assets\";\nstatic const char* kAppZipName = NULL; //\"classes.jar\";\nstatic const char* kSystemAssets = \"framework/framework-res.apk\";\nstatic const char* kResourceCache = \"resource-cache\";\n\nstatic const char* kExcludeExtension = \".EXCLUDE\";\n\nstatic Asset* const kExcludedAsset = (Asset*) 0xd000000d;\n\nstatic volatile int32_t gCount = 0;\n\nconst char* AssetManager::RESOURCES_FILENAME = \"resources.arsc\";\nconst char* AssetManager::IDMAP_BIN = \"/system/bin/idmap\";\nconst char* AssetManager::OVERLAY_DIR = \"/vendor/overlay\";\nconst char* AssetManager::TARGET_PACKAGE_NAME = \"android\";\nconst char* AssetManager::TARGET_APK_PATH = \"/system/framework/framework-res.apk\";\nconst char* AssetManager::IDMAP_DIR = \"/data/resource-cache\";\n\nnamespace {\n    String8 idmapPathForPackagePath(const String8& pkgPath)\n    {\n        const char* root = getenv(\"ANDROID_DATA\");\n        LOG_ALWAYS_FATAL_IF(root == NULL, \"ANDROID_DATA not set\");\n        String8 path(root);\n        path.appendPath(kResourceCache);\n\n        char buf[256]; // 256 chars should be enough for anyone...\n        strncpy(buf, pkgPath.string(), 255);\n        buf[255] = '\\0';\n        char* filename = buf;\n        while (*filename && *filename == '/') {\n            ++filename;\n        }\n        char* p = filename;\n        while (*p) {\n            if (*p == '/') {\n                *p = '@';\n            }\n            ++p;\n        }\n        path.appendPath(filename);\n        path.append(\"@idmap\");\n\n        return path;\n    }\n\n    /*\n     * Like strdup(), but uses C++ \"new\" operator instead of malloc.\n     */\n    static char* strdupNew(const char* str)\n    {\n        char* newStr;\n        int len;\n\n        if (str == NULL)\n            return NULL;\n\n        len = strlen(str);\n        newStr = new char[len+1];\n        memcpy(newStr, str, len+1);\n\n        return newStr;\n    }\n}\n\n/*\n * ===========================================================================\n *      AssetManager\n * ===========================================================================\n */\n\nint32_t AssetManager::getGlobalCount()\n{\n    return gCount;\n}\n\nAssetManager::AssetManager(CacheMode cacheMode)\n    : mLocale(NULL), mVendor(NULL),\n      mResources(NULL), mConfig(new ResTable_config),\n      mCacheMode(cacheMode), mCacheValid(false)\n{\n    int count = android_atomic_inc(&gCount) + 1;\n    if (kIsDebug) {\n        ALOGI(\"Creating AssetManager %p #%d\\n\", this, count);\n    }\n    memset(mConfig, 0, sizeof(ResTable_config));\n}\n\nAssetManager::~AssetManager(void)\n{\n    int count = android_atomic_dec(&gCount);\n    if (kIsDebug) {\n        ALOGI(\"Destroying AssetManager in %p #%d\\n\", this, count);\n    }\n\n    delete mConfig;\n    delete mResources;\n\n    // don't have a String class yet, so make sure we clean up\n    delete[] mLocale;\n    delete[] mVendor;\n}\n\nbool AssetManager::addAssetPath(\n        const String8& path, int32_t* cookie, bool appAsLib, bool isSystemAsset)\n{\n    AutoMutex _l(mLock);\n\n    asset_path ap;\n\n    String8 realPath(path);\n    if (kAppZipName) {\n        realPath.appendPath(kAppZipName);\n    }\n    ap.type = ::getFileType(realPath.string());\n    if (ap.type == kFileTypeRegular) {\n        ap.path = realPath;\n    } else {\n        ap.path = path;\n        ap.type = ::getFileType(path.string());\n        if (ap.type != kFileTypeDirectory && ap.type != kFileTypeRegular) {\n            ALOGW(\"Asset path %s is neither a directory nor file (type=%d).\",\n                 path.string(), (int)ap.type);\n            return false;\n        }\n    }\n\n    // Skip if we have it already.\n    for (size_t i=0; i<mAssetPaths.size(); i++) {\n        if (mAssetPaths[i].path == ap.path) {\n            if (cookie) {\n                *cookie = static_cast<int32_t>(i+1);\n            }\n            return true;\n        }\n    }\n\n    ALOGV(\"In %p Asset %s path: %s\", this,\n         ap.type == kFileTypeDirectory ? \"dir\" : \"zip\", ap.path.string());\n\n    ap.isSystemAsset = isSystemAsset;\n    mAssetPaths.add(ap);\n\n    // new paths are always added at the end\n    if (cookie) {\n        *cookie = static_cast<int32_t>(mAssetPaths.size());\n    }\n\n#ifdef __ANDROID__\n    // Load overlays, if any\n    asset_path oap;\n    for (size_t idx = 0; mZipSet.getOverlay(ap.path, idx, &oap); idx++) {\n        oap.isSystemAsset = isSystemAsset;\n        mAssetPaths.add(oap);\n    }\n#endif\n\n    if (mResources != NULL) {\n        appendPathToResTable(ap, appAsLib);\n    }\n\n    return true;\n}\n\nbool AssetManager::addOverlayPath(const String8& packagePath, int32_t* cookie)\n{\n    const String8 idmapPath = idmapPathForPackagePath(packagePath);\n\n    AutoMutex _l(mLock);\n\n    for (size_t i = 0; i < mAssetPaths.size(); ++i) {\n        if (mAssetPaths[i].idmap == idmapPath) {\n           *cookie = static_cast<int32_t>(i + 1);\n            return true;\n         }\n     }\n\n    Asset* idmap = NULL;\n    if ((idmap = openAssetFromFileLocked(idmapPath, Asset::ACCESS_BUFFER)) == NULL) {\n        ALOGW(\"failed to open idmap file %s\\n\", idmapPath.string());\n        return false;\n    }\n\n    String8 targetPath;\n    String8 overlayPath;\n    if (!ResTable::getIdmapInfo(idmap->getBuffer(false), idmap->getLength(),\n                NULL, NULL, NULL, &targetPath, &overlayPath)) {\n        ALOGW(\"failed to read idmap file %s\\n\", idmapPath.string());\n        delete idmap;\n        return false;\n    }\n    delete idmap;\n\n    if (overlayPath != packagePath) {\n        ALOGW(\"idmap file %s inconcistent: expected path %s does not match actual path %s\\n\",\n                idmapPath.string(), packagePath.string(), overlayPath.string());\n        return false;\n    }\n    if (access(targetPath.string(), R_OK) != 0) {\n        ALOGW(\"failed to access file %s: %s\\n\", targetPath.string(), strerror(errno));\n        return false;\n    }\n    if (access(idmapPath.string(), R_OK) != 0) {\n        ALOGW(\"failed to access file %s: %s\\n\", idmapPath.string(), strerror(errno));\n        return false;\n    }\n    if (access(overlayPath.string(), R_OK) != 0) {\n        ALOGW(\"failed to access file %s: %s\\n\", overlayPath.string(), strerror(errno));\n        return false;\n    }\n\n    asset_path oap;\n    oap.path = overlayPath;\n    oap.type = ::getFileType(overlayPath.string());\n    oap.idmap = idmapPath;\n#if 0\n    ALOGD(\"Overlay added: targetPath=%s overlayPath=%s idmapPath=%s\\n\",\n            targetPath.string(), overlayPath.string(), idmapPath.string());\n#endif\n    mAssetPaths.add(oap);\n    *cookie = static_cast<int32_t>(mAssetPaths.size());\n\n    if (mResources != NULL) {\n        appendPathToResTable(oap);\n    }\n\n    return true;\n }\n\nbool AssetManager::createIdmap(const char* targetApkPath, const char* overlayApkPath,\n        uint32_t targetCrc, uint32_t overlayCrc, uint32_t** outData, size_t* outSize)\n{\n    AutoMutex _l(mLock);\n    const String8 paths[2] = { String8(targetApkPath), String8(overlayApkPath) };\n    ResTable tables[2];\n\n    for (int i = 0; i < 2; ++i) {\n        asset_path ap;\n        ap.type = kFileTypeRegular;\n        ap.path = paths[i];\n        Asset* ass = openNonAssetInPathLocked(\"resources.arsc\", Asset::ACCESS_BUFFER, ap);\n        if (ass == NULL) {\n            ALOGW(\"failed to find resources.arsc in %s\\n\", ap.path.string());\n            return false;\n        }\n        tables[i].add(ass);\n    }\n\n    return tables[0].createIdmap(tables[1], targetCrc, overlayCrc,\n            targetApkPath, overlayApkPath, (void**)outData, outSize) == NO_ERROR;\n}\n\nbool AssetManager::addDefaultAssets()\n{\n    const char* root = getenv(\"ANDROID_ROOT\");\n    LOG_ALWAYS_FATAL_IF(root == NULL, \"ANDROID_ROOT not set\");\n\n    String8 path(root);\n    path.appendPath(kSystemAssets);\n\n    return addAssetPath(path, NULL, false /* appAsLib */, true /* isSystemAsset */);\n}\n\nint32_t AssetManager::nextAssetPath(const int32_t cookie) const\n{\n    AutoMutex _l(mLock);\n    const size_t next = static_cast<size_t>(cookie) + 1;\n    return next > mAssetPaths.size() ? -1 : next;\n}\n\nString8 AssetManager::getAssetPath(const int32_t cookie) const\n{\n    AutoMutex _l(mLock);\n    const size_t which = static_cast<size_t>(cookie) - 1;\n    if (which < mAssetPaths.size()) {\n        return mAssetPaths[which].path;\n    }\n    return String8();\n}\n\n/*\n * Set the current locale.  Use NULL to indicate no locale.\n *\n * Close and reopen Zip archives as appropriate, and reset cached\n * information in the locale-specific sections of the tree.\n */\nvoid AssetManager::setLocale(const char* locale)\n{\n    AutoMutex _l(mLock);\n    setLocaleLocked(locale);\n}\n\n\nstatic const char kFilPrefix[] = \"fil\";\nstatic const char kTlPrefix[] = \"tl\";\n\n// The sizes of the prefixes, excluding the 0 suffix.\n// char.\nstatic const int kFilPrefixLen = sizeof(kFilPrefix) - 1;\nstatic const int kTlPrefixLen = sizeof(kTlPrefix) - 1;\n\nvoid AssetManager::setLocaleLocked(const char* locale)\n{\n    if (mLocale != NULL) {\n        /* previously set, purge cached data */\n        purgeFileNameCacheLocked();\n        //mZipSet.purgeLocale();\n        delete[] mLocale;\n    }\n\n    // If we're attempting to set a locale that starts with \"fil\",\n    // we should convert it to \"tl\" for backwards compatibility since\n    // we've been using \"tl\" instead of \"fil\" prior to L.\n    //\n    // If the resource table already has entries for \"fil\", we use that\n    // instead of attempting a fallback.\n    if (strncmp(locale, kFilPrefix, kFilPrefixLen) == 0) {\n        Vector<String8> locales;\n        ResTable* res = mResources;\n        if (res != NULL) {\n            res->getLocales(&locales);\n        }\n        const size_t localesSize = locales.size();\n        bool hasFil = false;\n        for (size_t i = 0; i < localesSize; ++i) {\n            if (locales[i].find(kFilPrefix) == 0) {\n                hasFil = true;\n                break;\n            }\n        }\n\n\n        if (!hasFil) {\n            const size_t newLocaleLen = strlen(locale);\n            // This isn't a bug. We really do want mLocale to be 1 byte\n            // shorter than locale, because we're replacing \"fil-\" with\n            // \"tl-\".\n            mLocale = new char[newLocaleLen];\n            // Copy over \"tl\".\n            memcpy(mLocale, kTlPrefix, kTlPrefixLen);\n            // Copy the rest of |locale|, including the terminating '\\0'.\n            memcpy(mLocale + kTlPrefixLen, locale + kFilPrefixLen,\n                   newLocaleLen - kFilPrefixLen + 1);\n            updateResourceParamsLocked();\n            return;\n        }\n    }\n\n    mLocale = strdupNew(locale);\n    updateResourceParamsLocked();\n}\n\n/*\n * Set the current vendor.  Use NULL to indicate no vendor.\n *\n * Close and reopen Zip archives as appropriate, and reset cached\n * information in the vendor-specific sections of the tree.\n */\nvoid AssetManager::setVendor(const char* vendor)\n{\n    AutoMutex _l(mLock);\n\n    if (mVendor != NULL) {\n        /* previously set, purge cached data */\n        purgeFileNameCacheLocked();\n        //mZipSet.purgeVendor();\n        delete[] mVendor;\n    }\n    mVendor = strdupNew(vendor);\n}\n\nvoid AssetManager::setConfiguration(const ResTable_config& config, const char* locale)\n{\n    AutoMutex _l(mLock);\n    *mConfig = config;\n    if (locale) {\n        setLocaleLocked(locale);\n    } else if (config.language[0] != 0) {\n        char spec[RESTABLE_MAX_LOCALE_LEN];\n        config.getBcp47Locale(spec);\n        setLocaleLocked(spec);\n    } else {\n        updateResourceParamsLocked();\n    }\n}\n\nvoid AssetManager::getConfiguration(ResTable_config* outConfig) const\n{\n    AutoMutex _l(mLock);\n    *outConfig = *mConfig;\n}\n\n/*\n * Open an asset.\n *\n * The data could be;\n *  - In a file on disk (assetBase + fileName).\n *  - In a compressed file on disk (assetBase + fileName.gz).\n *  - In a Zip archive, uncompressed or compressed.\n *\n * It can be in a number of different directories and Zip archives.\n * The search order is:\n *  - [appname]\n *    - locale + vendor\n *    - \"default\" + vendor\n *    - locale + \"default\"\n *    - \"default + \"default\"\n *  - \"common\"\n *    - (same as above)\n *\n * To find a particular file, we have to try up to eight paths with\n * all three forms of data.\n *\n * We should probably reject requests for \"illegal\" filenames, e.g. those\n * with illegal characters or \"../\" backward relative paths.\n */\nAsset* AssetManager::open(const char* fileName, AccessMode mode)\n{\n    AutoMutex _l(mLock);\n\n    LOG_FATAL_IF(mAssetPaths.size() == 0, \"No assets added to AssetManager\");\n\n\n    if (mCacheMode != CACHE_OFF && !mCacheValid)\n        loadFileNameCacheLocked();\n\n    String8 assetName(kAssetsRoot);\n    assetName.appendPath(fileName);\n\n    /*\n     * For each top-level asset path, search for the asset.\n     */\n\n    size_t i = mAssetPaths.size();\n    while (i > 0) {\n        i--;\n        ALOGV(\"Looking for asset '%s' in '%s'\\n\",\n                assetName.string(), mAssetPaths.itemAt(i).path.string());\n        Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, mAssetPaths.itemAt(i));\n        if (pAsset != NULL) {\n            return pAsset != kExcludedAsset ? pAsset : NULL;\n        }\n    }\n\n    return NULL;\n}\n\n/*\n * Open a non-asset file as if it were an asset.\n *\n * The \"fileName\" is the partial path starting from the application\n * name.\n */\nAsset* AssetManager::openNonAsset(const char* fileName, AccessMode mode, int32_t* outCookie)\n{\n    AutoMutex _l(mLock);\n\n    LOG_FATAL_IF(mAssetPaths.size() == 0, \"No assets added to AssetManager\");\n\n\n    if (mCacheMode != CACHE_OFF && !mCacheValid)\n        loadFileNameCacheLocked();\n\n    /*\n     * For each top-level asset path, search for the asset.\n     */\n\n    size_t i = mAssetPaths.size();\n    while (i > 0) {\n        i--;\n        ALOGV(\"Looking for non-asset '%s' in '%s'\\n\", fileName, mAssetPaths.itemAt(i).path.string());\n        Asset* pAsset = openNonAssetInPathLocked(\n            fileName, mode, mAssetPaths.itemAt(i));\n        if (pAsset != NULL) {\n            if (outCookie != NULL) *outCookie = static_cast<int32_t>(i + 1);\n            return pAsset != kExcludedAsset ? pAsset : NULL;\n        }\n    }\n\n    return NULL;\n}\n\nAsset* AssetManager::openNonAsset(const int32_t cookie, const char* fileName, AccessMode mode)\n{\n    const size_t which = static_cast<size_t>(cookie) - 1;\n\n    AutoMutex _l(mLock);\n\n    LOG_FATAL_IF(mAssetPaths.size() == 0, \"No assets added to AssetManager\");\n\n    if (mCacheMode != CACHE_OFF && !mCacheValid)\n        loadFileNameCacheLocked();\n\n    if (which < mAssetPaths.size()) {\n        ALOGV(\"Looking for non-asset '%s' in '%s'\\n\", fileName,\n                mAssetPaths.itemAt(which).path.string());\n        Asset* pAsset = openNonAssetInPathLocked(\n            fileName, mode, mAssetPaths.itemAt(which));\n        if (pAsset != NULL) {\n            return pAsset != kExcludedAsset ? pAsset : NULL;\n        }\n    }\n\n    return NULL;\n}\n\n/*\n * Get the type of a file in the asset namespace.\n *\n * This currently only works for regular files.  All others (including\n * directories) will return kFileTypeNonexistent.\n */\nFileType AssetManager::getFileType(const char* fileName)\n{\n    Asset* pAsset = NULL;\n\n    /*\n     * Open the asset.  This is less efficient than simply finding the\n     * file, but it's not too bad (we don't uncompress or mmap data until\n     * the first read() call).\n     */\n    pAsset = open(fileName, Asset::ACCESS_STREAMING);\n    delete pAsset;\n\n    if (pAsset == NULL)\n        return kFileTypeNonexistent;\n    else\n        return kFileTypeRegular;\n}\n\nbool AssetManager::appendPathToResTable(const asset_path& ap, bool appAsLib) const {\n    // skip those ap's that correspond to system overlays\n    if (ap.isSystemOverlay) {\n        return true;\n    }\n\n    Asset* ass = NULL;\n    ResTable* sharedRes = NULL;\n    bool shared = true;\n    bool onlyEmptyResources = true;\n    ATRACE_NAME(ap.path.string());\n    Asset* idmap = openIdmapLocked(ap);\n    size_t nextEntryIdx = mResources->getTableCount();\n    ALOGV(\"Looking for resource asset in '%s'\\n\", ap.path.string());\n    if (ap.type != kFileTypeDirectory) {\n        if (nextEntryIdx == 0) {\n            // The first item is typically the framework resources,\n            // which we want to avoid parsing every time.\n            sharedRes = const_cast<AssetManager*>(this)->\n                mZipSet.getZipResourceTable(ap.path);\n            if (sharedRes != NULL) {\n                // skip ahead the number of system overlay packages preloaded\n                nextEntryIdx = sharedRes->getTableCount();\n            }\n        }\n        if (sharedRes == NULL) {\n            ass = const_cast<AssetManager*>(this)->\n                mZipSet.getZipResourceTableAsset(ap.path);\n            if (ass == NULL) {\n                ALOGV(\"loading resource table %s\\n\", ap.path.string());\n                ass = const_cast<AssetManager*>(this)->\n                    openNonAssetInPathLocked(\"resources.arsc\",\n                                             Asset::ACCESS_BUFFER,\n                                             ap);\n                if (ass != NULL && ass != kExcludedAsset) {\n                    ass = const_cast<AssetManager*>(this)->\n                        mZipSet.setZipResourceTableAsset(ap.path, ass);\n                }\n            }\n            \n            if (nextEntryIdx == 0 && ass != NULL) {\n                // If this is the first resource table in the asset\n                // manager, then we are going to cache it so that we\n                // can quickly copy it out for others.\n                ALOGV(\"Creating shared resources for %s\", ap.path.string());\n                sharedRes = new ResTable();\n                sharedRes->add(ass, idmap, nextEntryIdx + 1, false);\n#ifdef __ANDROID__\n                const char* data = getenv(\"ANDROID_DATA\");\n                LOG_ALWAYS_FATAL_IF(data == NULL, \"ANDROID_DATA not set\");\n                String8 overlaysListPath(data);\n                overlaysListPath.appendPath(kResourceCache);\n                overlaysListPath.appendPath(\"overlays.list\");\n                addSystemOverlays(overlaysListPath.string(), ap.path, sharedRes, nextEntryIdx);\n#endif\n                sharedRes = const_cast<AssetManager*>(this)->\n                    mZipSet.setZipResourceTable(ap.path, sharedRes);\n            }\n        }\n    } else {\n        ALOGV(\"loading resource table %s\\n\", ap.path.string());\n        ass = const_cast<AssetManager*>(this)->\n            openNonAssetInPathLocked(\"resources.arsc\",\n                                     Asset::ACCESS_BUFFER,\n                                     ap);\n        shared = false;\n    }\n\n    if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) {\n        ALOGV(\"Installing resource asset %p in to table %p\\n\", ass, mResources);\n        if (sharedRes != NULL) {\n            ALOGV(\"Copying existing resources for %s\", ap.path.string());\n            mResources->add(sharedRes, ap.isSystemAsset);\n        } else {\n            ALOGV(\"Parsing resources for %s\", ap.path.string());\n            mResources->add(ass, idmap, nextEntryIdx + 1, !shared, appAsLib, ap.isSystemAsset);\n        }\n        onlyEmptyResources = false;\n\n        if (!shared) {\n            delete ass;\n        }\n    } else {\n        ALOGV(\"Installing empty resources in to table %p\\n\", mResources);\n        mResources->addEmpty(nextEntryIdx + 1);\n    }\n\n    if (idmap != NULL) {\n        delete idmap;\n    }\n    return onlyEmptyResources;\n}\n\nconst ResTable* AssetManager::getResTable(bool required) const\n{\n    ResTable* rt = mResources;\n    if (rt) {\n        return rt;\n    }\n\n    // Iterate through all asset packages, collecting resources from each.\n\n    AutoMutex _l(mLock);\n\n    if (mResources != NULL) {\n        return mResources;\n    }\n\n    if (required) {\n        LOG_FATAL_IF(mAssetPaths.size() == 0, \"No assets added to AssetManager\");\n    }\n\n    if (mCacheMode != CACHE_OFF && !mCacheValid) {\n        const_cast<AssetManager*>(this)->loadFileNameCacheLocked();\n    }\n\n    mResources = new ResTable();\n    updateResourceParamsLocked();\n\n    bool onlyEmptyResources = true;\n    const size_t N = mAssetPaths.size();\n    for (size_t i=0; i<N; i++) {\n        bool empty = appendPathToResTable(mAssetPaths.itemAt(i));\n        onlyEmptyResources = onlyEmptyResources && empty;\n    }\n\n    if (required && onlyEmptyResources) {\n        ALOGW(\"Unable to find resources file resources.arsc\");\n        delete mResources;\n        mResources = NULL;\n    }\n\n    return mResources;\n}\n\nvoid AssetManager::updateResourceParamsLocked() const\n{\n    ATRACE_CALL();\n    ResTable* res = mResources;\n    if (!res) {\n        return;\n    }\n\n    if (mLocale) {\n        mConfig->setBcp47Locale(mLocale);\n    } else {\n        mConfig->clearLocale();\n    }\n\n    res->setParameters(mConfig);\n}\n\nAsset* AssetManager::openIdmapLocked(const struct asset_path& ap) const\n{\n    Asset* ass = NULL;\n    if (ap.idmap.size() != 0) {\n        ass = const_cast<AssetManager*>(this)->\n            openAssetFromFileLocked(ap.idmap, Asset::ACCESS_BUFFER);\n        if (ass) {\n            ALOGV(\"loading idmap %s\\n\", ap.idmap.string());\n        } else {\n            ALOGW(\"failed to load idmap %s\\n\", ap.idmap.string());\n        }\n    }\n    return ass;\n}\n\nvoid AssetManager::addSystemOverlays(const char* pathOverlaysList,\n        const String8& targetPackagePath, ResTable* sharedRes, size_t offset) const\n{\n    FILE* fin = fopen(pathOverlaysList, \"r\");\n    if (fin == NULL) {\n        return;\n    }\n\n    char buf[1024];\n    while (fgets(buf, sizeof(buf), fin)) {\n        // format of each line:\n        //   <path to apk><space><path to idmap><newline>\n        char* space = strchr(buf, ' ');\n        char* newline = strchr(buf, '\\n');\n        asset_path oap;\n\n        if (space == NULL || newline == NULL || newline < space) {\n            continue;\n        }\n\n        oap.path = String8(buf, space - buf);\n        oap.type = kFileTypeRegular;\n        oap.idmap = String8(space + 1, newline - space - 1);\n        oap.isSystemOverlay = true;\n\n        Asset* oass = const_cast<AssetManager*>(this)->\n            openNonAssetInPathLocked(\"resources.arsc\",\n                    Asset::ACCESS_BUFFER,\n                    oap);\n\n        if (oass != NULL) {\n            Asset* oidmap = openIdmapLocked(oap);\n            offset++;\n            sharedRes->add(oass, oidmap, offset + 1, false);\n            const_cast<AssetManager*>(this)->mAssetPaths.add(oap);\n            const_cast<AssetManager*>(this)->mZipSet.addOverlay(targetPackagePath, oap);\n        }\n    }\n    fclose(fin);\n}\n\nconst ResTable& AssetManager::getResources(bool required) const\n{\n    const ResTable* rt = getResTable(required);\n    return *rt;\n}\n\nbool AssetManager::isUpToDate()\n{\n    AutoMutex _l(mLock);\n    return mZipSet.isUpToDate();\n}\n\nvoid AssetManager::getLocales(Vector<String8>* locales, bool includeSystemLocales) const\n{\n    ResTable* res = mResources;\n    if (res != NULL) {\n        res->getLocales(locales, includeSystemLocales);\n    }\n\n    const size_t numLocales = locales->size();\n    for (size_t i = 0; i < numLocales; ++i) {\n        const String8& localeStr = locales->itemAt(i);\n        if (localeStr.find(kTlPrefix) == 0) {\n            String8 replaced(\"fil\");\n            replaced += (localeStr.string() + kTlPrefixLen);\n            locales->editItemAt(i) = replaced;\n        }\n    }\n}\n\n/*\n * Open a non-asset file as if it were an asset, searching for it in the\n * specified app.\n *\n * Pass in a NULL values for \"appName\" if the common app directory should\n * be used.\n */\nAsset* AssetManager::openNonAssetInPathLocked(const char* fileName, AccessMode mode,\n    const asset_path& ap)\n{\n    Asset* pAsset = NULL;\n\n    /* look at the filesystem on disk */\n    if (ap.type == kFileTypeDirectory) {\n        String8 path(ap.path);\n        path.appendPath(fileName);\n\n        pAsset = openAssetFromFileLocked(path, mode);\n\n        if (pAsset == NULL) {\n            /* try again, this time with \".gz\" */\n            path.append(\".gz\");\n            pAsset = openAssetFromFileLocked(path, mode);\n        }\n\n        if (pAsset != NULL) {\n            //printf(\"FOUND NA '%s' on disk\\n\", fileName);\n            pAsset->setAssetSource(path);\n        }\n\n    /* look inside the zip file */\n    } else {\n        String8 path(fileName);\n\n        /* check the appropriate Zip file */\n        ZipFileRO* pZip = getZipFileLocked(ap);\n        if (pZip != NULL) {\n            //printf(\"GOT zip, checking NA '%s'\\n\", (const char*) path);\n            ZipEntryRO entry = pZip->findEntryByName(path.string());\n            if (entry != NULL) {\n                //printf(\"FOUND NA in Zip file for %s\\n\", appName ? appName : kAppCommon);\n                pAsset = openAssetFromZipLocked(pZip, entry, mode, path);\n                pZip->releaseEntry(entry);\n            }\n        }\n\n        if (pAsset != NULL) {\n            /* create a \"source\" name, for debug/display */\n            pAsset->setAssetSource(\n                    createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()), String8(\"\"),\n                                                String8(fileName)));\n        }\n    }\n\n    return pAsset;\n}\n\n/*\n * Open an asset, searching for it in the directory hierarchy for the\n * specified app.\n *\n * Pass in a NULL values for \"appName\" if the common app directory should\n * be used.\n */\nAsset* AssetManager::openInPathLocked(const char* fileName, AccessMode mode,\n    const asset_path& ap)\n{\n    Asset* pAsset = NULL;\n\n    /*\n     * Try various combinations of locale and vendor.\n     */\n    if (mLocale != NULL && mVendor != NULL)\n        pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, mVendor);\n    if (pAsset == NULL && mVendor != NULL)\n        pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, mVendor);\n    if (pAsset == NULL && mLocale != NULL)\n        pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, NULL);\n    if (pAsset == NULL)\n        pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, NULL);\n\n    return pAsset;\n}\n\n/*\n * Open an asset, searching for it in the directory hierarchy for the\n * specified locale and vendor.\n *\n * We also search in \"app.jar\".\n *\n * Pass in NULL values for \"appName\", \"locale\", and \"vendor\" if the\n * defaults should be used.\n */\nAsset* AssetManager::openInLocaleVendorLocked(const char* fileName, AccessMode mode,\n    const asset_path& ap, const char* locale, const char* vendor)\n{\n    Asset* pAsset = NULL;\n\n    if (ap.type == kFileTypeDirectory) {\n        if (mCacheMode == CACHE_OFF) {\n            /* look at the filesystem on disk */\n            String8 path(createPathNameLocked(ap, locale, vendor));\n            path.appendPath(fileName);\n    \n            String8 excludeName(path);\n            excludeName.append(kExcludeExtension);\n            if (::getFileType(excludeName.string()) != kFileTypeNonexistent) {\n                /* say no more */\n                //printf(\"+++ excluding '%s'\\n\", (const char*) excludeName);\n                return kExcludedAsset;\n            }\n    \n            pAsset = openAssetFromFileLocked(path, mode);\n    \n            if (pAsset == NULL) {\n                /* try again, this time with \".gz\" */\n                path.append(\".gz\");\n                pAsset = openAssetFromFileLocked(path, mode);\n            }\n    \n            if (pAsset != NULL)\n                pAsset->setAssetSource(path);\n        } else {\n            /* find in cache */\n            String8 path(createPathNameLocked(ap, locale, vendor));\n            path.appendPath(fileName);\n    \n            AssetDir::FileInfo tmpInfo;\n            bool found = false;\n    \n            String8 excludeName(path);\n            excludeName.append(kExcludeExtension);\n    \n            if (mCache.indexOf(excludeName) != NAME_NOT_FOUND) {\n                /* go no farther */\n                //printf(\"+++ Excluding '%s'\\n\", (const char*) excludeName);\n                return kExcludedAsset;\n            }\n\n            /*\n             * File compression extensions (\".gz\") don't get stored in the\n             * name cache, so we have to try both here.\n             */\n            if (mCache.indexOf(path) != NAME_NOT_FOUND) {\n                found = true;\n                pAsset = openAssetFromFileLocked(path, mode);\n                if (pAsset == NULL) {\n                    /* try again, this time with \".gz\" */\n                    path.append(\".gz\");\n                    pAsset = openAssetFromFileLocked(path, mode);\n                }\n            }\n\n            if (pAsset != NULL)\n                pAsset->setAssetSource(path);\n\n            /*\n             * Don't continue the search into the Zip files.  Our cached info\n             * said it was a file on disk; to be consistent with openDir()\n             * we want to return the loose asset.  If the cached file gets\n             * removed, we fail.\n             *\n             * The alternative is to update our cache when files get deleted,\n             * or make some sort of \"best effort\" promise, but for now I'm\n             * taking the hard line.\n             */\n            if (found) {\n                if (pAsset == NULL)\n                    ALOGD(\"Expected file not found: '%s'\\n\", path.string());\n                return pAsset;\n            }\n        }\n    }\n\n    /*\n     * Either it wasn't found on disk or on the cached view of the disk.\n     * Dig through the currently-opened set of Zip files.  If caching\n     * is disabled, the Zip file may get reopened.\n     */\n    if (pAsset == NULL && ap.type == kFileTypeRegular) {\n        String8 path;\n\n        path.appendPath((locale != NULL) ? locale : kDefaultLocale);\n        path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);\n        path.appendPath(fileName);\n\n        /* check the appropriate Zip file */\n        ZipFileRO* pZip = getZipFileLocked(ap);\n        if (pZip != NULL) {\n            //printf(\"GOT zip, checking '%s'\\n\", (const char*) path);\n            ZipEntryRO entry = pZip->findEntryByName(path.string());\n            if (entry != NULL) {\n                //printf(\"FOUND in Zip file for %s/%s-%s\\n\",\n                //    appName, locale, vendor);\n                pAsset = openAssetFromZipLocked(pZip, entry, mode, path);\n                pZip->releaseEntry(entry);\n            }\n        }\n\n        if (pAsset != NULL) {\n            /* create a \"source\" name, for debug/display */\n            pAsset->setAssetSource(createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()),\n                                                             String8(\"\"), String8(fileName)));\n        }\n    }\n\n    return pAsset;\n}\n\n/*\n * Create a \"source name\" for a file from a Zip archive.\n */\nString8 AssetManager::createZipSourceNameLocked(const String8& zipFileName,\n    const String8& dirName, const String8& fileName)\n{\n    String8 sourceName(\"zip:\");\n    sourceName.append(zipFileName);\n    sourceName.append(\":\");\n    if (dirName.length() > 0) {\n        sourceName.appendPath(dirName);\n    }\n    sourceName.appendPath(fileName);\n    return sourceName;\n}\n\n/*\n * Create a path to a loose asset (asset-base/app/locale/vendor).\n */\nString8 AssetManager::createPathNameLocked(const asset_path& ap, const char* locale,\n    const char* vendor)\n{\n    String8 path(ap.path);\n    path.appendPath((locale != NULL) ? locale : kDefaultLocale);\n    path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);\n    return path;\n}\n\n/*\n * Create a path to a loose asset (asset-base/app/rootDir).\n */\nString8 AssetManager::createPathNameLocked(const asset_path& ap, const char* rootDir)\n{\n    String8 path(ap.path);\n    if (rootDir != NULL) path.appendPath(rootDir);\n    return path;\n}\n\n/*\n * Return a pointer to one of our open Zip archives.  Returns NULL if no\n * matching Zip file exists.\n *\n * Right now we have 2 possible Zip files (1 each in app/\"common\").\n *\n * If caching is set to CACHE_OFF, to get the expected behavior we\n * need to reopen the Zip file on every request.  That would be silly\n * and expensive, so instead we just check the file modification date.\n *\n * Pass in NULL values for \"appName\", \"locale\", and \"vendor\" if the\n * generics should be used.\n */\nZipFileRO* AssetManager::getZipFileLocked(const asset_path& ap)\n{\n    ALOGV(\"getZipFileLocked() in %p\\n\", this);\n\n    return mZipSet.getZip(ap.path);\n}\n\n/*\n * Try to open an asset from a file on disk.\n *\n * If the file is compressed with gzip, we seek to the start of the\n * deflated data and pass that in (just like we would for a Zip archive).\n *\n * For uncompressed data, we may already have an mmap()ed version sitting\n * around.  If so, we want to hand that to the Asset instead.\n *\n * This returns NULL if the file doesn't exist, couldn't be opened, or\n * claims to be a \".gz\" but isn't.\n */\nAsset* AssetManager::openAssetFromFileLocked(const String8& pathName,\n    AccessMode mode)\n{\n    Asset* pAsset = NULL;\n\n    if (strcasecmp(pathName.getPathExtension().string(), \".gz\") == 0) {\n        //printf(\"TRYING '%s'\\n\", (const char*) pathName);\n        pAsset = Asset::createFromCompressedFile(pathName.string(), mode);\n    } else {\n        //printf(\"TRYING '%s'\\n\", (const char*) pathName);\n        pAsset = Asset::createFromFile(pathName.string(), mode);\n    }\n\n    return pAsset;\n}\n\n/*\n * Given an entry in a Zip archive, create a new Asset object.\n *\n * If the entry is uncompressed, we may want to create or share a\n * slice of shared memory.\n */\nAsset* AssetManager::openAssetFromZipLocked(const ZipFileRO* pZipFile,\n    const ZipEntryRO entry, AccessMode mode, const String8& entryName)\n{\n    Asset* pAsset = NULL;\n\n    // TODO: look for previously-created shared memory slice?\n    uint16_t method;\n    uint32_t uncompressedLen;\n\n    //printf(\"USING Zip '%s'\\n\", pEntry->getFileName());\n\n    if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, NULL, NULL,\n            NULL, NULL))\n    {\n        ALOGW(\"getEntryInfo failed\\n\");\n        return NULL;\n    }\n\n    FileMap* dataMap = pZipFile->createEntryFileMap(entry);\n    if (dataMap == NULL) {\n        ALOGW(\"create map from entry failed\\n\");\n        return NULL;\n    }\n\n    if (method == ZipFileRO::kCompressStored) {\n        pAsset = Asset::createFromUncompressedMap(dataMap, mode);\n        ALOGV(\"Opened uncompressed entry %s in zip %s mode %d: %p\", entryName.string(),\n                dataMap->getFileName(), mode, pAsset);\n    } else {\n        pAsset = Asset::createFromCompressedMap(dataMap,\n            static_cast<size_t>(uncompressedLen), mode);\n        ALOGV(\"Opened compressed entry %s in zip %s mode %d: %p\", entryName.string(),\n                dataMap->getFileName(), mode, pAsset);\n    }\n    if (pAsset == NULL) {\n        /* unexpected */\n        ALOGW(\"create from segment failed\\n\");\n    }\n\n    return pAsset;\n}\n\n\n\n/*\n * Open a directory in the asset namespace.\n *\n * An \"asset directory\" is simply the combination of all files in all\n * locations, with \".gz\" stripped for loose files.  With app, locale, and\n * vendor defined, we have 8 directories and 2 Zip archives to scan.\n *\n * Pass in \"\" for the root dir.\n */\nAssetDir* AssetManager::openDir(const char* dirName)\n{\n    AutoMutex _l(mLock);\n\n    AssetDir* pDir = NULL;\n    SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL;\n\n    LOG_FATAL_IF(mAssetPaths.size() == 0, \"No assets added to AssetManager\");\n    assert(dirName != NULL);\n\n    //printf(\"+++ openDir(%s) in '%s'\\n\", dirName, (const char*) mAssetBase);\n\n    if (mCacheMode != CACHE_OFF && !mCacheValid)\n        loadFileNameCacheLocked();\n\n    pDir = new AssetDir;\n\n    /*\n     * Scan the various directories, merging what we find into a single\n     * vector.  We want to scan them in reverse priority order so that\n     * the \".EXCLUDE\" processing works correctly.  Also, if we decide we\n     * want to remember where the file is coming from, we'll get the right\n     * version.\n     *\n     * We start with Zip archives, then do loose files.\n     */\n    pMergedInfo = new SortedVector<AssetDir::FileInfo>;\n\n    size_t i = mAssetPaths.size();\n    while (i > 0) {\n        i--;\n        const asset_path& ap = mAssetPaths.itemAt(i);\n        if (ap.type == kFileTypeRegular) {\n            ALOGV(\"Adding directory %s from zip %s\", dirName, ap.path.string());\n            scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName);\n        } else {\n            ALOGV(\"Adding directory %s from dir %s\", dirName, ap.path.string());\n            scanAndMergeDirLocked(pMergedInfo, ap, kAssetsRoot, dirName);\n        }\n    }\n\n#if 0\n    printf(\"FILE LIST:\\n\");\n    for (i = 0; i < (size_t) pMergedInfo->size(); i++) {\n        printf(\" %d: (%d) '%s'\\n\", i,\n            pMergedInfo->itemAt(i).getFileType(),\n            (const char*) pMergedInfo->itemAt(i).getFileName());\n    }\n#endif\n\n    pDir->setFileList(pMergedInfo);\n    return pDir;\n}\n\n/*\n * Open a directory in the non-asset namespace.\n *\n * An \"asset directory\" is simply the combination of all files in all\n * locations, with \".gz\" stripped for loose files.  With app, locale, and\n * vendor defined, we have 8 directories and 2 Zip archives to scan.\n *\n * Pass in \"\" for the root dir.\n */\nAssetDir* AssetManager::openNonAssetDir(const int32_t cookie, const char* dirName)\n{\n    AutoMutex _l(mLock);\n\n    AssetDir* pDir = NULL;\n    SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL;\n\n    LOG_FATAL_IF(mAssetPaths.size() == 0, \"No assets added to AssetManager\");\n    assert(dirName != NULL);\n\n    //printf(\"+++ openDir(%s) in '%s'\\n\", dirName, (const char*) mAssetBase);\n\n    if (mCacheMode != CACHE_OFF && !mCacheValid)\n        loadFileNameCacheLocked();\n\n    pDir = new AssetDir;\n\n    pMergedInfo = new SortedVector<AssetDir::FileInfo>;\n\n    const size_t which = static_cast<size_t>(cookie) - 1;\n\n    if (which < mAssetPaths.size()) {\n        const asset_path& ap = mAssetPaths.itemAt(which);\n        if (ap.type == kFileTypeRegular) {\n            ALOGV(\"Adding directory %s from zip %s\", dirName, ap.path.string());\n            scanAndMergeZipLocked(pMergedInfo, ap, NULL, dirName);\n        } else {\n            ALOGV(\"Adding directory %s from dir %s\", dirName, ap.path.string());\n            scanAndMergeDirLocked(pMergedInfo, ap, NULL, dirName);\n        }\n    }\n\n#if 0\n    printf(\"FILE LIST:\\n\");\n    for (i = 0; i < (size_t) pMergedInfo->size(); i++) {\n        printf(\" %d: (%d) '%s'\\n\", i,\n            pMergedInfo->itemAt(i).getFileType(),\n            (const char*) pMergedInfo->itemAt(i).getFileName());\n    }\n#endif\n\n    pDir->setFileList(pMergedInfo);\n    return pDir;\n}\n\n/*\n * Scan the contents of the specified directory and merge them into the\n * \"pMergedInfo\" vector, removing previous entries if we find \"exclude\"\n * directives.\n *\n * Returns \"false\" if we found nothing to contribute.\n */\nbool AssetManager::scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n    const asset_path& ap, const char* rootDir, const char* dirName)\n{\n    SortedVector<AssetDir::FileInfo>* pContents;\n    String8 path;\n\n    assert(pMergedInfo != NULL);\n\n    //printf(\"scanAndMergeDir: %s %s %s %s\\n\", appName, locale, vendor,dirName);\n\n    if (mCacheValid) {\n        int i, start, count;\n\n        pContents = new SortedVector<AssetDir::FileInfo>;\n\n        /*\n         * Get the basic partial path and find it in the cache.  That's\n         * the start point for the search.\n         */\n        path = createPathNameLocked(ap, rootDir);\n        if (dirName[0] != '\\0')\n            path.appendPath(dirName);\n\n        start = mCache.indexOf(path);\n        if (start == NAME_NOT_FOUND) {\n            //printf(\"+++ not found in cache: dir '%s'\\n\", (const char*) path);\n            delete pContents;\n            return false;\n        }\n\n        /*\n         * The match string looks like \"common/default/default/foo/bar/\".\n         * The '/' on the end ensures that we don't match on the directory\n         * itself or on \".../foo/barfy/\".\n         */\n        path.append(\"/\");\n\n        count = mCache.size();\n\n        /*\n         * Pick out the stuff in the current dir by examining the pathname.\n         * It needs to match the partial pathname prefix, and not have a '/'\n         * (fssep) anywhere after the prefix.\n         */\n        for (i = start+1; i < count; i++) {\n            if (mCache[i].getFileName().length() > path.length() &&\n                strncmp(mCache[i].getFileName().string(), path.string(), path.length()) == 0)\n            {\n                const char* name = mCache[i].getFileName().string();\n                // XXX THIS IS BROKEN!  Looks like we need to store the full\n                // path prefix separately from the file path.\n                if (strchr(name + path.length(), '/') == NULL) {\n                    /* grab it, reducing path to just the filename component */\n                    AssetDir::FileInfo tmp = mCache[i];\n                    tmp.setFileName(tmp.getFileName().getPathLeaf());\n                    pContents->add(tmp);\n                }\n            } else {\n                /* no longer in the dir or its subdirs */\n                break;\n            }\n\n        }\n    } else {\n        path = createPathNameLocked(ap, rootDir);\n        if (dirName[0] != '\\0')\n            path.appendPath(dirName);\n        pContents = scanDirLocked(path);\n        if (pContents == NULL)\n            return false;\n    }\n\n    // if we wanted to do an incremental cache fill, we would do it here\n\n    /*\n     * Process \"exclude\" directives.  If we find a filename that ends with\n     * \".EXCLUDE\", we look for a matching entry in the \"merged\" set, and\n     * remove it if we find it.  We also delete the \"exclude\" entry.\n     */\n    int i, count, exclExtLen;\n\n    count = pContents->size();\n    exclExtLen = strlen(kExcludeExtension);\n    for (i = 0; i < count; i++) {\n        const char* name;\n        int nameLen;\n\n        name = pContents->itemAt(i).getFileName().string();\n        nameLen = strlen(name);\n        if (nameLen > exclExtLen &&\n            strcmp(name + (nameLen - exclExtLen), kExcludeExtension) == 0)\n        {\n            String8 match(name, nameLen - exclExtLen);\n            int matchIdx;\n\n            matchIdx = AssetDir::FileInfo::findEntry(pMergedInfo, match);\n            if (matchIdx > 0) {\n                ALOGV(\"Excluding '%s' [%s]\\n\",\n                    pMergedInfo->itemAt(matchIdx).getFileName().string(),\n                    pMergedInfo->itemAt(matchIdx).getSourceName().string());\n                pMergedInfo->removeAt(matchIdx);\n            } else {\n                //printf(\"+++ no match on '%s'\\n\", (const char*) match);\n            }\n\n            ALOGD(\"HEY: size=%d removing %d\\n\", (int)pContents->size(), i);\n            pContents->removeAt(i);\n            i--;        // adjust \"for\" loop\n            count--;    //  and loop limit\n        }\n    }\n\n    mergeInfoLocked(pMergedInfo, pContents);\n\n    delete pContents;\n\n    return true;\n}\n\n/*\n * Scan the contents of the specified directory, and stuff what we find\n * into a newly-allocated vector.\n *\n * Files ending in \".gz\" will have their extensions removed.\n *\n * We should probably think about skipping files with \"illegal\" names,\n * e.g. illegal characters (/\\:) or excessive length.\n *\n * Returns NULL if the specified directory doesn't exist.\n */\nSortedVector<AssetDir::FileInfo>* AssetManager::scanDirLocked(const String8& path)\n{\n    SortedVector<AssetDir::FileInfo>* pContents = NULL;\n    DIR* dir;\n    struct dirent* entry;\n    FileType fileType;\n\n    ALOGV(\"Scanning dir '%s'\\n\", path.string());\n\n    dir = opendir(path.string());\n    if (dir == NULL)\n        return NULL;\n\n    pContents = new SortedVector<AssetDir::FileInfo>;\n\n    while (1) {\n        entry = readdir(dir);\n        if (entry == NULL)\n            break;\n\n        if (strcmp(entry->d_name, \".\") == 0 ||\n            strcmp(entry->d_name, \"..\") == 0)\n            continue;\n\n#ifdef _DIRENT_HAVE_D_TYPE\n        if (entry->d_type == DT_REG)\n            fileType = kFileTypeRegular;\n        else if (entry->d_type == DT_DIR)\n            fileType = kFileTypeDirectory;\n        else\n            fileType = kFileTypeUnknown;\n#else\n        // stat the file\n        fileType = ::getFileType(path.appendPathCopy(entry->d_name).string());\n#endif\n\n        if (fileType != kFileTypeRegular && fileType != kFileTypeDirectory)\n            continue;\n\n        AssetDir::FileInfo info;\n        info.set(String8(entry->d_name), fileType);\n        if (strcasecmp(info.getFileName().getPathExtension().string(), \".gz\") == 0)\n            info.setFileName(info.getFileName().getBasePath());\n        info.setSourceName(path.appendPathCopy(info.getFileName()));\n        pContents->add(info);\n    }\n\n    closedir(dir);\n    return pContents;\n}\n\n/*\n * Scan the contents out of the specified Zip archive, and merge what we\n * find into \"pMergedInfo\".  If the Zip archive in question doesn't exist,\n * we return immediately.\n *\n * Returns \"false\" if we found nothing to contribute.\n */\nbool AssetManager::scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n    const asset_path& ap, const char* rootDir, const char* baseDirName)\n{\n    ZipFileRO* pZip;\n    Vector<String8> dirs;\n    AssetDir::FileInfo info;\n    SortedVector<AssetDir::FileInfo> contents;\n    String8 sourceName, zipName, dirName;\n\n    pZip = mZipSet.getZip(ap.path);\n    if (pZip == NULL) {\n        ALOGW(\"Failure opening zip %s\\n\", ap.path.string());\n        return false;\n    }\n\n    zipName = ZipSet::getPathName(ap.path.string());\n\n    /* convert \"sounds\" to \"rootDir/sounds\" */\n    if (rootDir != NULL) dirName = rootDir;\n    dirName.appendPath(baseDirName);\n\n    /*\n     * Scan through the list of files, looking for a match.  The files in\n     * the Zip table of contents are not in sorted order, so we have to\n     * process the entire list.  We're looking for a string that begins\n     * with the characters in \"dirName\", is followed by a '/', and has no\n     * subsequent '/' in the stuff that follows.\n     *\n     * What makes this especially fun is that directories are not stored\n     * explicitly in Zip archives, so we have to infer them from context.\n     * When we see \"sounds/foo.wav\" we have to leave a note to ourselves\n     * to insert a directory called \"sounds\" into the list.  We store\n     * these in temporary vector so that we only return each one once.\n     *\n     * Name comparisons are case-sensitive to match UNIX filesystem\n     * semantics.\n     */\n    int dirNameLen = dirName.length();\n    void *iterationCookie;\n    if (!pZip->startIteration(&iterationCookie, dirName.string(), NULL)) {\n        ALOGW(\"ZipFileRO::startIteration returned false\");\n        return false;\n    }\n\n    ZipEntryRO entry;\n    while ((entry = pZip->nextEntry(iterationCookie)) != NULL) {\n        char nameBuf[256];\n\n        if (pZip->getEntryFileName(entry, nameBuf, sizeof(nameBuf)) != 0) {\n            // TODO: fix this if we expect to have long names\n            ALOGE(\"ARGH: name too long?\\n\");\n            continue;\n        }\n        //printf(\"Comparing %s in %s?\\n\", nameBuf, dirName.string());\n        if (dirNameLen == 0 || nameBuf[dirNameLen] == '/')\n        {\n            const char* cp;\n            const char* nextSlash;\n\n            cp = nameBuf + dirNameLen;\n            if (dirNameLen != 0)\n                cp++;       // advance past the '/'\n\n            nextSlash = strchr(cp, '/');\n//xxx this may break if there are bare directory entries\n            if (nextSlash == NULL) {\n                /* this is a file in the requested directory */\n\n                info.set(String8(nameBuf).getPathLeaf(), kFileTypeRegular);\n\n                info.setSourceName(\n                    createZipSourceNameLocked(zipName, dirName, info.getFileName()));\n\n                contents.add(info);\n                //printf(\"FOUND: file '%s'\\n\", info.getFileName().string());\n            } else {\n                /* this is a subdir; add it if we don't already have it*/\n                String8 subdirName(cp, nextSlash - cp);\n                size_t j;\n                size_t N = dirs.size();\n\n                for (j = 0; j < N; j++) {\n                    if (subdirName == dirs[j]) {\n                        break;\n                    }\n                }\n                if (j == N) {\n                    dirs.add(subdirName);\n                }\n\n                //printf(\"FOUND: dir '%s'\\n\", subdirName.string());\n            }\n        }\n    }\n\n    pZip->endIteration(iterationCookie);\n\n    /*\n     * Add the set of unique directories.\n     */\n    for (int i = 0; i < (int) dirs.size(); i++) {\n        info.set(dirs[i], kFileTypeDirectory);\n        info.setSourceName(\n            createZipSourceNameLocked(zipName, dirName, info.getFileName()));\n        contents.add(info);\n    }\n\n    mergeInfoLocked(pMergedInfo, &contents);\n\n    return true;\n}\n\n\n/*\n * Merge two vectors of FileInfo.\n *\n * The merged contents will be stuffed into *pMergedInfo.\n *\n * If an entry for a file exists in both \"pMergedInfo\" and \"pContents\",\n * we use the newer \"pContents\" entry.\n */\nvoid AssetManager::mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n    const SortedVector<AssetDir::FileInfo>* pContents)\n{\n    /*\n     * Merge what we found in this directory with what we found in\n     * other places.\n     *\n     * Two basic approaches:\n     * (1) Create a new array that holds the unique values of the two\n     *     arrays.\n     * (2) Take the elements from pContents and shove them into pMergedInfo.\n     *\n     * Because these are vectors of complex objects, moving elements around\n     * inside the vector requires constructing new objects and allocating\n     * storage for members.  With approach #1, we're always adding to the\n     * end, whereas with #2 we could be inserting multiple elements at the\n     * front of the vector.  Approach #1 requires a full copy of the\n     * contents of pMergedInfo, but approach #2 requires the same copy for\n     * every insertion at the front of pMergedInfo.\n     *\n     * (We should probably use a SortedVector interface that allows us to\n     * just stuff items in, trusting us to maintain the sort order.)\n     */\n    SortedVector<AssetDir::FileInfo>* pNewSorted;\n    int mergeMax, contMax;\n    int mergeIdx, contIdx;\n\n    pNewSorted = new SortedVector<AssetDir::FileInfo>;\n    mergeMax = pMergedInfo->size();\n    contMax = pContents->size();\n    mergeIdx = contIdx = 0;\n\n    while (mergeIdx < mergeMax || contIdx < contMax) {\n        if (mergeIdx == mergeMax) {\n            /* hit end of \"merge\" list, copy rest of \"contents\" */\n            pNewSorted->add(pContents->itemAt(contIdx));\n            contIdx++;\n        } else if (contIdx == contMax) {\n            /* hit end of \"cont\" list, copy rest of \"merge\" */\n            pNewSorted->add(pMergedInfo->itemAt(mergeIdx));\n            mergeIdx++;\n        } else if (pMergedInfo->itemAt(mergeIdx) == pContents->itemAt(contIdx))\n        {\n            /* items are identical, add newer and advance both indices */\n            pNewSorted->add(pContents->itemAt(contIdx));\n            mergeIdx++;\n            contIdx++;\n        } else if (pMergedInfo->itemAt(mergeIdx) < pContents->itemAt(contIdx))\n        {\n            /* \"merge\" is lower, add that one */\n            pNewSorted->add(pMergedInfo->itemAt(mergeIdx));\n            mergeIdx++;\n        } else {\n            /* \"cont\" is lower, add that one */\n            assert(pContents->itemAt(contIdx) < pMergedInfo->itemAt(mergeIdx));\n            pNewSorted->add(pContents->itemAt(contIdx));\n            contIdx++;\n        }\n    }\n\n    /*\n     * Overwrite the \"merged\" list with the new stuff.\n     */\n    *pMergedInfo = *pNewSorted;\n    delete pNewSorted;\n\n#if 0       // for Vector, rather than SortedVector\n    int i, j;\n    for (i = pContents->size() -1; i >= 0; i--) {\n        bool add = true;\n\n        for (j = pMergedInfo->size() -1; j >= 0; j--) {\n            /* case-sensitive comparisons, to behave like UNIX fs */\n            if (strcmp(pContents->itemAt(i).mFileName,\n                       pMergedInfo->itemAt(j).mFileName) == 0)\n            {\n                /* match, don't add this entry */\n                add = false;\n                break;\n            }\n        }\n\n        if (add)\n            pMergedInfo->add(pContents->itemAt(i));\n    }\n#endif\n}\n\n\n/*\n * Load all files into the file name cache.  We want to do this across\n * all combinations of { appname, locale, vendor }, performing a recursive\n * directory traversal.\n *\n * This is not the most efficient data structure.  Also, gathering the\n * information as we needed it (file-by-file or directory-by-directory)\n * would be faster.  However, on the actual device, 99% of the files will\n * live in Zip archives, so this list will be very small.  The trouble\n * is that we have to check the \"loose\" files first, so it's important\n * that we don't beat the filesystem silly looking for files that aren't\n * there.\n *\n * Note on thread safety: this is the only function that causes updates\n * to mCache, and anybody who tries to use it will call here if !mCacheValid,\n * so we need to employ a mutex here.\n */\nvoid AssetManager::loadFileNameCacheLocked(void)\n{\n    assert(!mCacheValid);\n    assert(mCache.size() == 0);\n\n#ifdef DO_TIMINGS   // need to link against -lrt for this now\n    DurationTimer timer;\n    timer.start();\n#endif\n\n    fncScanLocked(&mCache, \"\");\n\n#ifdef DO_TIMINGS\n    timer.stop();\n    ALOGD(\"Cache scan took %.3fms\\n\",\n        timer.durationUsecs() / 1000.0);\n#endif\n\n#if 0\n    int i;\n    printf(\"CACHED FILE LIST (%d entries):\\n\", mCache.size());\n    for (i = 0; i < (int) mCache.size(); i++) {\n        printf(\" %d: (%d) '%s'\\n\", i,\n            mCache.itemAt(i).getFileType(),\n            (const char*) mCache.itemAt(i).getFileName());\n    }\n#endif\n\n    mCacheValid = true;\n}\n\n/*\n * Scan up to 8 versions of the specified directory.\n */\nvoid AssetManager::fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n    const char* dirName)\n{\n    size_t i = mAssetPaths.size();\n    while (i > 0) {\n        i--;\n        const asset_path& ap = mAssetPaths.itemAt(i);\n        fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, NULL, dirName);\n        if (mLocale != NULL)\n            fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, NULL, dirName);\n        if (mVendor != NULL)\n            fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, mVendor, dirName);\n        if (mLocale != NULL && mVendor != NULL)\n            fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, mVendor, dirName);\n    }\n}\n\n/*\n * Recursively scan this directory and all subdirs.\n *\n * This is similar to scanAndMergeDir, but we don't remove the .EXCLUDE\n * files, and we prepend the extended partial path to the filenames.\n */\nbool AssetManager::fncScanAndMergeDirLocked(\n    SortedVector<AssetDir::FileInfo>* pMergedInfo,\n    const asset_path& ap, const char* locale, const char* vendor,\n    const char* dirName)\n{\n    SortedVector<AssetDir::FileInfo>* pContents;\n    String8 partialPath;\n    String8 fullPath;\n\n    // XXX This is broken -- the filename cache needs to hold the base\n    // asset path separately from its filename.\n    \n    partialPath = createPathNameLocked(ap, locale, vendor);\n    if (dirName[0] != '\\0') {\n        partialPath.appendPath(dirName);\n    }\n\n    fullPath = partialPath;\n    pContents = scanDirLocked(fullPath);\n    if (pContents == NULL) {\n        return false;       // directory did not exist\n    }\n\n    /*\n     * Scan all subdirectories of the current dir, merging what we find\n     * into \"pMergedInfo\".\n     */\n    for (int i = 0; i < (int) pContents->size(); i++) {\n        if (pContents->itemAt(i).getFileType() == kFileTypeDirectory) {\n            String8 subdir(dirName);\n            subdir.appendPath(pContents->itemAt(i).getFileName());\n\n            fncScanAndMergeDirLocked(pMergedInfo, ap, locale, vendor, subdir.string());\n        }\n    }\n\n    /*\n     * To be consistent, we want entries for the root directory.  If\n     * we're the root, add one now.\n     */\n    if (dirName[0] == '\\0') {\n        AssetDir::FileInfo tmpInfo;\n\n        tmpInfo.set(String8(\"\"), kFileTypeDirectory);\n        tmpInfo.setSourceName(createPathNameLocked(ap, locale, vendor));\n        pContents->add(tmpInfo);\n    }\n\n    /*\n     * We want to prepend the extended partial path to every entry in\n     * \"pContents\".  It's the same value for each entry, so this will\n     * not change the sorting order of the vector contents.\n     */\n    for (int i = 0; i < (int) pContents->size(); i++) {\n        const AssetDir::FileInfo& info = pContents->itemAt(i);\n        pContents->editItemAt(i).setFileName(partialPath.appendPathCopy(info.getFileName()));\n    }\n\n    mergeInfoLocked(pMergedInfo, pContents);\n    delete pContents;\n    return true;\n}\n\n/*\n * Trash the cache.\n */\nvoid AssetManager::purgeFileNameCacheLocked(void)\n{\n    mCacheValid = false;\n    mCache.clear();\n}\n\n/*\n * ===========================================================================\n *      AssetManager::SharedZip\n * ===========================================================================\n */\n\n\nMutex AssetManager::SharedZip::gLock;\nDefaultKeyedVector<String8, wp<AssetManager::SharedZip> > AssetManager::SharedZip::gOpen;\n\nAssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen)\n    : mPath(path), mZipFile(NULL), mModWhen(modWhen),\n      mResourceTableAsset(NULL), mResourceTable(NULL)\n{\n    if (kIsDebug) {\n        ALOGI(\"Creating SharedZip %p %s\\n\", this, (const char*)mPath);\n    }\n    ALOGV(\"+++ opening zip '%s'\\n\", mPath.string());\n    mZipFile = ZipFileRO::open(mPath.string());\n    if (mZipFile == NULL) {\n        ALOGD(\"failed to open Zip archive '%s'\\n\", mPath.string());\n    }\n}\n\nsp<AssetManager::SharedZip> AssetManager::SharedZip::get(const String8& path,\n        bool createIfNotPresent)\n{\n    AutoMutex _l(gLock);\n    time_t modWhen = getFileModDate(path);\n    sp<SharedZip> zip = gOpen.valueFor(path).promote();\n    if (zip != NULL && zip->mModWhen == modWhen) {\n        return zip;\n    }\n    if (zip == NULL && !createIfNotPresent) {\n        return NULL;\n    }\n    zip = new SharedZip(path, modWhen);\n    gOpen.add(path, zip);\n    return zip;\n\n}\n\nZipFileRO* AssetManager::SharedZip::getZip()\n{\n    return mZipFile;\n}\n\nAsset* AssetManager::SharedZip::getResourceTableAsset()\n{\n    ALOGV(\"Getting from SharedZip %p resource asset %p\\n\", this, mResourceTableAsset);\n    return mResourceTableAsset;\n}\n\nAsset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset)\n{\n    {\n        AutoMutex _l(gLock);\n        if (mResourceTableAsset == NULL) {\n            mResourceTableAsset = asset;\n            // This is not thread safe the first time it is called, so\n            // do it here with the global lock held.\n            asset->getBuffer(true);\n            return asset;\n        }\n    }\n    delete asset;\n    return mResourceTableAsset;\n}\n\nResTable* AssetManager::SharedZip::getResourceTable()\n{\n    ALOGV(\"Getting from SharedZip %p resource table %p\\n\", this, mResourceTable);\n    return mResourceTable;\n}\n\nResTable* AssetManager::SharedZip::setResourceTable(ResTable* res)\n{\n    {\n        AutoMutex _l(gLock);\n        if (mResourceTable == NULL) {\n            mResourceTable = res;\n            return res;\n        }\n    }\n    delete res;\n    return mResourceTable;\n}\n\nbool AssetManager::SharedZip::isUpToDate()\n{\n    time_t modWhen = getFileModDate(mPath.string());\n    return mModWhen == modWhen;\n}\n\nvoid AssetManager::SharedZip::addOverlay(const asset_path& ap)\n{\n    mOverlays.add(ap);\n}\n\nbool AssetManager::SharedZip::getOverlay(size_t idx, asset_path* out) const\n{\n    if (idx >= mOverlays.size()) {\n        return false;\n    }\n    *out = mOverlays[idx];\n    return true;\n}\n\nAssetManager::SharedZip::~SharedZip()\n{\n    if (kIsDebug) {\n        ALOGI(\"Destroying SharedZip %p %s\\n\", this, (const char*)mPath);\n    }\n    if (mResourceTable != NULL) {\n        delete mResourceTable;\n    }\n    if (mResourceTableAsset != NULL) {\n        delete mResourceTableAsset;\n    }\n    if (mZipFile != NULL) {\n        delete mZipFile;\n        ALOGV(\"Closed '%s'\\n\", mPath.string());\n    }\n}\n\n/*\n * ===========================================================================\n *      AssetManager::ZipSet\n * ===========================================================================\n */\n\n/*\n * Constructor.\n */\nAssetManager::ZipSet::ZipSet(void)\n{\n}\n\n/*\n * Destructor.  Close any open archives.\n */\nAssetManager::ZipSet::~ZipSet(void)\n{\n    size_t N = mZipFile.size();\n    for (size_t i = 0; i < N; i++)\n        closeZip(i);\n}\n\n/*\n * Close a Zip file and reset the entry.\n */\nvoid AssetManager::ZipSet::closeZip(int idx)\n{\n    mZipFile.editItemAt(idx) = NULL;\n}\n\n\n/*\n * Retrieve the appropriate Zip file from the set.\n */\nZipFileRO* AssetManager::ZipSet::getZip(const String8& path)\n{\n    int idx = getIndex(path);\n    sp<SharedZip> zip = mZipFile[idx];\n    if (zip == NULL) {\n        zip = SharedZip::get(path);\n        mZipFile.editItemAt(idx) = zip;\n    }\n    return zip->getZip();\n}\n\nAsset* AssetManager::ZipSet::getZipResourceTableAsset(const String8& path)\n{\n    int idx = getIndex(path);\n    sp<SharedZip> zip = mZipFile[idx];\n    if (zip == NULL) {\n        zip = SharedZip::get(path);\n        mZipFile.editItemAt(idx) = zip;\n    }\n    return zip->getResourceTableAsset();\n}\n\nAsset* AssetManager::ZipSet::setZipResourceTableAsset(const String8& path,\n                                                 Asset* asset)\n{\n    int idx = getIndex(path);\n    sp<SharedZip> zip = mZipFile[idx];\n    // doesn't make sense to call before previously accessing.\n    return zip->setResourceTableAsset(asset);\n}\n\nResTable* AssetManager::ZipSet::getZipResourceTable(const String8& path)\n{\n    int idx = getIndex(path);\n    sp<SharedZip> zip = mZipFile[idx];\n    if (zip == NULL) {\n        zip = SharedZip::get(path);\n        mZipFile.editItemAt(idx) = zip;\n    }\n    return zip->getResourceTable();\n}\n\nResTable* AssetManager::ZipSet::setZipResourceTable(const String8& path,\n                                                    ResTable* res)\n{\n    int idx = getIndex(path);\n    sp<SharedZip> zip = mZipFile[idx];\n    // doesn't make sense to call before previously accessing.\n    return zip->setResourceTable(res);\n}\n\n/*\n * Generate the partial pathname for the specified archive.  The caller\n * gets to prepend the asset root directory.\n *\n * Returns something like \"common/en-US-noogle.jar\".\n */\n/*static*/ String8 AssetManager::ZipSet::getPathName(const char* zipPath)\n{\n    return String8(zipPath);\n}\n\nbool AssetManager::ZipSet::isUpToDate()\n{\n    const size_t N = mZipFile.size();\n    for (size_t i=0; i<N; i++) {\n        if (mZipFile[i] != NULL && !mZipFile[i]->isUpToDate()) {\n            return false;\n        }\n    }\n    return true;\n}\n\nvoid AssetManager::ZipSet::addOverlay(const String8& path, const asset_path& overlay)\n{\n    int idx = getIndex(path);\n    sp<SharedZip> zip = mZipFile[idx];\n    zip->addOverlay(overlay);\n}\n\nbool AssetManager::ZipSet::getOverlay(const String8& path, size_t idx, asset_path* out) const\n{\n    sp<SharedZip> zip = SharedZip::get(path, false);\n    if (zip == NULL) {\n        return false;\n    }\n    return zip->getOverlay(idx, out);\n}\n\n/*\n * Compute the zip file's index.\n *\n * \"appName\", \"locale\", and \"vendor\" should be set to NULL to indicate the\n * default directory.\n */\nint AssetManager::ZipSet::getIndex(const String8& zip) const\n{\n    const size_t N = mZipPath.size();\n    for (size_t i=0; i<N; i++) {\n        if (mZipPath[i] == zip) {\n            return i;\n        }\n    }\n\n    mZipPath.add(zip);\n    mZipFile.add(NULL);\n\n    return mZipPath.size()-1;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/BackupData.cpp",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"backup_data\"\n\n#include <androidfw/BackupHelpers.h>\n#include <utils/ByteOrder.h>\n\n#include <stdio.h>\n#include <string.h>\n#include <unistd.h>\n\n#include <cutils/log.h>\n\nnamespace android {\n\nstatic const bool kIsDebug = false;\n\n/*\n * File Format (v1):\n *\n * All ints are stored little-endian.\n *\n *  - An app_header_v1 struct.\n *  - The name of the package, utf-8, null terminated, padded to 4-byte boundary.\n *  - A sequence of zero or more key/value paires (entities), each with\n *      - A entity_header_v1 struct\n *      - The key, utf-8, null terminated, padded to 4-byte boundary.\n *      - The value, padded to 4 byte boundary\n */\n\nconst static int ROUND_UP[4] = { 0, 3, 2, 1 };\n\nstatic inline size_t\npadding_extra(size_t n)\n{\n    return ROUND_UP[n % 4];\n}\n\nBackupDataWriter::BackupDataWriter(int fd)\n    :m_fd(fd),\n     m_status(NO_ERROR),\n     m_entityCount(0)\n{\n    m_pos = (ssize_t) lseek(fd, 0, SEEK_CUR);\n    if (kIsDebug) ALOGI(\"BackupDataWriter(%d) @ %ld\", fd, (long)m_pos);\n}\n\nBackupDataWriter::~BackupDataWriter()\n{\n}\n\n// Pad out anything they've previously written to the next 4 byte boundary.\nstatus_t\nBackupDataWriter::write_padding_for(int n)\n{\n    ssize_t amt;\n    ssize_t paddingSize;\n\n    paddingSize = padding_extra(n);\n    if (paddingSize > 0) {\n        uint32_t padding = 0xbcbcbcbc;\n        if (kIsDebug) ALOGI(\"writing %zd padding bytes for %d\", paddingSize, n);\n        amt = write(m_fd, &padding, paddingSize);\n        if (amt != paddingSize) {\n            m_status = errno;\n            return m_status;\n        }\n        m_pos += amt;\n    }\n    return NO_ERROR;\n}\n\nstatus_t\nBackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize)\n{\n    if (m_status != NO_ERROR) {\n        return m_status;\n    }\n\n    ssize_t amt;\n\n    amt = write_padding_for(m_pos);\n    if (amt != 0) {\n        return amt;\n    }\n\n    String8 k;\n    if (m_keyPrefix.length() > 0) {\n        k = m_keyPrefix;\n        k += \":\";\n        k += key;\n    } else {\n        k = key;\n    }\n    if (kIsDebug) {\n        ALOGD(\"Writing header: prefix='%s' key='%s' dataSize=%zu\", m_keyPrefix.string(),\n                key.string(), dataSize);\n    }\n\n    entity_header_v1 header;\n    ssize_t keyLen;\n\n    keyLen = k.length();\n\n    header.type = tolel(BACKUP_HEADER_ENTITY_V1);\n    header.keyLen = tolel(keyLen);\n    header.dataSize = tolel(dataSize);\n\n    if (kIsDebug) ALOGI(\"writing entity header, %zu bytes\", sizeof(entity_header_v1));\n    amt = write(m_fd, &header, sizeof(entity_header_v1));\n    if (amt != sizeof(entity_header_v1)) {\n        m_status = errno;\n        return m_status;\n    }\n    m_pos += amt;\n\n    if (kIsDebug) ALOGI(\"writing entity header key, %zd bytes\", keyLen+1);\n    amt = write(m_fd, k.string(), keyLen+1);\n    if (amt != keyLen+1) {\n        m_status = errno;\n        return m_status;\n    }\n    m_pos += amt;\n\n    amt = write_padding_for(keyLen+1);\n\n    m_entityCount++;\n\n    return amt;\n}\n\nstatus_t\nBackupDataWriter::WriteEntityData(const void* data, size_t size)\n{\n    if (kIsDebug) ALOGD(\"Writing data: size=%lu\", (unsigned long) size);\n\n    if (m_status != NO_ERROR) {\n        if (kIsDebug) {\n            ALOGD(\"Not writing data - stream in error state %d (%s)\", m_status, strerror(m_status));\n        }\n        return m_status;\n    }\n\n    // We don't write padding here, because they're allowed to call this several\n    // times with smaller buffers.  We write it at the end of WriteEntityHeader\n    // instead.\n    ssize_t amt = write(m_fd, data, size);\n    if (amt != (ssize_t)size) {\n        m_status = errno;\n        if (kIsDebug) ALOGD(\"write returned error %d (%s)\", m_status, strerror(m_status));\n        return m_status;\n    }\n    m_pos += amt;\n    return NO_ERROR;\n}\n\nvoid\nBackupDataWriter::SetKeyPrefix(const String8& keyPrefix)\n{\n    m_keyPrefix = keyPrefix;\n}\n\n\nBackupDataReader::BackupDataReader(int fd)\n    :m_fd(fd),\n     m_done(false),\n     m_status(NO_ERROR),\n     m_entityCount(0)\n{\n    memset(&m_header, 0, sizeof(m_header));\n    m_pos = (ssize_t) lseek(fd, 0, SEEK_CUR);\n    if (kIsDebug) ALOGI(\"BackupDataReader(%d) @ %ld\", fd, (long)m_pos);\n}\n\nBackupDataReader::~BackupDataReader()\n{\n}\n\nstatus_t\nBackupDataReader::Status()\n{\n    return m_status;\n}\n\n#define CHECK_SIZE(actual, expected) \\\n    do { \\\n        if ((actual) != (expected)) { \\\n            if ((actual) == 0) { \\\n                m_status = EIO; \\\n                m_done = true; \\\n            } else { \\\n                m_status = errno; \\\n                ALOGD(\"CHECK_SIZE(a=%ld e=%ld) failed at line %d m_status='%s'\", \\\n                    long(actual), long(expected), __LINE__, strerror(m_status)); \\\n            } \\\n            return m_status; \\\n        } \\\n    } while(0)\n#define SKIP_PADDING() \\\n    do { \\\n        status_t err = skip_padding(); \\\n        if (err != NO_ERROR) { \\\n            ALOGD(\"SKIP_PADDING FAILED at line %d\", __LINE__); \\\n            m_status = err; \\\n            return err; \\\n        } \\\n    } while(0)\n\nstatus_t\nBackupDataReader::ReadNextHeader(bool* done, int* type)\n{\n    *done = m_done;\n    if (m_status != NO_ERROR) {\n        return m_status;\n    }\n\n    int amt;\n\n    amt = skip_padding();\n    if (amt == EIO) {\n        *done = m_done = true;\n        return NO_ERROR;\n    }\n    else if (amt != NO_ERROR) {\n        return amt;\n    }\n    amt = read(m_fd, &m_header, sizeof(m_header));\n    *done = m_done = (amt == 0);\n    if (*done) {\n        return NO_ERROR;\n    }\n    CHECK_SIZE(amt, sizeof(m_header));\n    m_pos += sizeof(m_header);\n    if (type) {\n        *type = m_header.type;\n    }\n\n    // validate and fix up the fields.\n    m_header.type = fromlel(m_header.type);\n    switch (m_header.type)\n    {\n        case BACKUP_HEADER_ENTITY_V1:\n        {\n            m_header.entity.keyLen = fromlel(m_header.entity.keyLen);\n            if (m_header.entity.keyLen <= 0) {\n                ALOGD(\"Entity header at %d has keyLen<=0: 0x%08x\\n\", (int)m_pos,\n                        (int)m_header.entity.keyLen);\n                m_status = EINVAL;\n            }\n            m_header.entity.dataSize = fromlel(m_header.entity.dataSize);\n            m_entityCount++;\n\n            // read the rest of the header (filename)\n            size_t size = m_header.entity.keyLen;\n            char* buf = m_key.lockBuffer(size);\n            if (buf == NULL) {\n                m_status = ENOMEM;\n                return m_status;\n            }\n            int amt = read(m_fd, buf, size+1);\n            CHECK_SIZE(amt, (int)size+1);\n            m_key.unlockBuffer(size);\n            m_pos += size+1;\n            SKIP_PADDING();\n            m_dataEndPos = m_pos + m_header.entity.dataSize;\n\n            break;\n        }\n        default:\n            ALOGD(\"Chunk header at %d has invalid type: 0x%08x\",\n                    (int)(m_pos - sizeof(m_header)), (int)m_header.type);\n            m_status = EINVAL;\n    }\n\n    return m_status;\n}\n\nbool\nBackupDataReader::HasEntities()\n{\n    return m_status == NO_ERROR && m_header.type == BACKUP_HEADER_ENTITY_V1;\n}\n\nstatus_t\nBackupDataReader::ReadEntityHeader(String8* key, size_t* dataSize)\n{\n    if (m_status != NO_ERROR) {\n        return m_status;\n    }\n    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {\n        return EINVAL;\n    }\n    *key = m_key;\n    *dataSize = m_header.entity.dataSize;\n    return NO_ERROR;\n}\n\nstatus_t\nBackupDataReader::SkipEntityData()\n{\n    if (m_status != NO_ERROR) {\n        return m_status;\n    }\n    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {\n        return EINVAL;\n    }\n    if (m_header.entity.dataSize > 0) {\n        int pos = lseek(m_fd, m_dataEndPos, SEEK_SET);\n        if (pos == -1) {\n            return errno;\n        }\n        m_pos = pos;\n    }\n    SKIP_PADDING();\n    return NO_ERROR;\n}\n\nssize_t\nBackupDataReader::ReadEntityData(void* data, size_t size)\n{\n    if (m_status != NO_ERROR) {\n        return -1;\n    }\n    int remaining = m_dataEndPos - m_pos;\n    if (kIsDebug) {\n        ALOGD(\"ReadEntityData size=%zu m_pos=0x%zx m_dataEndPos=0x%zx remaining=%d\\n\",\n                size, m_pos, m_dataEndPos, remaining);\n    }\n    if (remaining <= 0) {\n        return 0;\n    }\n    if (((int)size) > remaining) {\n        size = remaining;\n    }\n    if (kIsDebug) {\n        ALOGD(\"   reading %zu bytes\", size);\n    }\n    int amt = read(m_fd, data, size);\n    if (amt < 0) {\n        m_status = errno;\n        return -1;\n    }\n    if (amt == 0) {\n        m_status = EIO;\n        m_done = true;\n    }\n    m_pos += amt;\n    return amt;\n}\n\nstatus_t\nBackupDataReader::skip_padding()\n{\n    ssize_t amt;\n    ssize_t paddingSize;\n\n    paddingSize = padding_extra(m_pos);\n    if (paddingSize > 0) {\n        uint32_t padding;\n        amt = read(m_fd, &padding, paddingSize);\n        CHECK_SIZE(amt, paddingSize);\n        m_pos += amt;\n    }\n    return NO_ERROR;\n}\n\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/BackupHelpers.cpp",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"file_backup_helper\"\n\n#include <androidfw/BackupHelpers.h>\n\n#include <utils/KeyedVector.h>\n#include <utils/ByteOrder.h>\n#include <utils/String8.h>\n\n#include <errno.h>\n#include <sys/types.h>\n#include <sys/uio.h>\n#include <sys/stat.h>\n#include <sys/time.h>  // for utimes\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <utime.h>\n#include <fcntl.h>\n#include <zlib.h>\n\n#include <cutils/log.h>\n\nnamespace android {\n\n#define MAGIC0 0x70616e53 // Snap\n#define MAGIC1 0x656c6946 // File\n\n/*\n * File entity data format (v1):\n *\n *   - 4-byte version number of the metadata, little endian (0x00000001 for v1)\n *   - 12 bytes of metadata\n *   - the file data itself\n *\n * i.e. a 16-byte metadata header followed by the raw file data.  If the\n * restore code does not recognize the metadata version, it can still\n * interpret the file data itself correctly.\n *\n * file_metadata_v1:\n *\n *   - 4 byte version number === 0x00000001 (little endian)\n *   - 4-byte access mode (little-endian)\n *   - undefined (8 bytes)\n */\n\nstruct file_metadata_v1 {\n    int version;\n    int mode;\n    int undefined_1;\n    int undefined_2;\n};\n\nconst static int CURRENT_METADATA_VERSION = 1;\n\nstatic const bool kIsDebug = false;\n#if TEST_BACKUP_HELPERS\n#define LOGP(f, x...) if (kIsDebug) printf(f \"\\n\", x)\n#else\n#define LOGP(x...) if (kIsDebug) ALOGD(x)\n#endif\n\nconst static int ROUND_UP[4] = { 0, 3, 2, 1 };\n\nstatic inline int\nround_up(int n)\n{\n    return n + ROUND_UP[n % 4];\n}\n\nstatic int\nread_snapshot_file(int fd, KeyedVector<String8,FileState>* snapshot)\n{\n    int bytesRead = 0;\n    int amt;\n    SnapshotHeader header;\n\n    amt = read(fd, &header, sizeof(header));\n    if (amt != sizeof(header)) {\n        return errno;\n    }\n    bytesRead += amt;\n\n    if (header.magic0 != MAGIC0 || header.magic1 != MAGIC1) {\n        ALOGW(\"read_snapshot_file header.magic0=0x%08x magic1=0x%08x\", header.magic0, header.magic1);\n        return 1;\n    }\n\n    for (int i=0; i<header.fileCount; i++) {\n        FileState file;\n        char filenameBuf[128];\n\n        amt = read(fd, &file, sizeof(FileState));\n        if (amt != sizeof(FileState)) {\n            ALOGW(\"read_snapshot_file FileState truncated/error with read at %d bytes\\n\", bytesRead);\n            return 1;\n        }\n        bytesRead += amt;\n\n        // filename is not NULL terminated, but it is padded\n        int nameBufSize = round_up(file.nameLen);\n        char* filename = nameBufSize <= (int)sizeof(filenameBuf)\n                ? filenameBuf\n                : (char*)malloc(nameBufSize);\n        amt = read(fd, filename, nameBufSize);\n        if (amt == nameBufSize) {\n            snapshot->add(String8(filename, file.nameLen), file);\n        }\n        bytesRead += amt;\n        if (filename != filenameBuf) {\n            free(filename);\n        }\n        if (amt != nameBufSize) {\n            ALOGW(\"read_snapshot_file filename truncated/error with read at %d bytes\\n\", bytesRead);\n            return 1;\n        }\n    }\n\n    if (header.totalSize != bytesRead) {\n        ALOGW(\"read_snapshot_file length mismatch: header.totalSize=%d bytesRead=%d\\n\",\n                header.totalSize, bytesRead);\n        return 1;\n    }\n\n    return 0;\n}\n\nstatic int\nwrite_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot)\n{\n    int fileCount = 0;\n    int bytesWritten = sizeof(SnapshotHeader);\n    // preflight size\n    const int N = snapshot.size();\n    for (int i=0; i<N; i++) {\n        const FileRec& g = snapshot.valueAt(i);\n        if (!g.deleted) {\n            const String8& name = snapshot.keyAt(i);\n            bytesWritten += sizeof(FileState) + round_up(name.length());\n            fileCount++;\n        }\n    }\n\n    LOGP(\"write_snapshot_file fd=%d\\n\", fd);\n\n    int amt;\n    SnapshotHeader header = { MAGIC0, fileCount, MAGIC1, bytesWritten };\n\n    amt = write(fd, &header, sizeof(header));\n    if (amt != sizeof(header)) {\n        ALOGW(\"write_snapshot_file error writing header %s\", strerror(errno));\n        return errno;\n    }\n\n    for (int i=0; i<N; i++) {\n        FileRec r = snapshot.valueAt(i);\n        if (!r.deleted) {\n            const String8& name = snapshot.keyAt(i);\n            int nameLen = r.s.nameLen = name.length();\n\n            amt = write(fd, &r.s, sizeof(FileState));\n            if (amt != sizeof(FileState)) {\n                ALOGW(\"write_snapshot_file error writing header %s\", strerror(errno));\n                return 1;\n            }\n\n            // filename is not NULL terminated, but it is padded\n            amt = write(fd, name.string(), nameLen);\n            if (amt != nameLen) {\n                ALOGW(\"write_snapshot_file error writing filename %s\", strerror(errno));\n                return 1;\n            }\n            int paddingLen = ROUND_UP[nameLen % 4];\n            if (paddingLen != 0) {\n                int padding = 0xabababab;\n                amt = write(fd, &padding, paddingLen);\n                if (amt != paddingLen) {\n                    ALOGW(\"write_snapshot_file error writing %d bytes of filename padding %s\",\n                            paddingLen, strerror(errno));\n                    return 1;\n                }\n            }\n        }\n    }\n\n    return 0;\n}\n\nstatic int\nwrite_delete_file(BackupDataWriter* dataStream, const String8& key)\n{\n    LOGP(\"write_delete_file %s\\n\", key.string());\n    return dataStream->WriteEntityHeader(key, -1);\n}\n\nstatic int\nwrite_update_file(BackupDataWriter* dataStream, int fd, int mode, const String8& key,\n        char const* realFilename)\n{\n    LOGP(\"write_update_file %s (%s) : mode 0%o\\n\", realFilename, key.string(), mode);\n\n    const int bufsize = 4*1024;\n    int err;\n    int amt;\n    int fileSize;\n    int bytesLeft;\n    file_metadata_v1 metadata;\n\n    char* buf = (char*)malloc(bufsize);\n\n    fileSize = lseek(fd, 0, SEEK_END);\n    lseek(fd, 0, SEEK_SET);\n\n    if (sizeof(metadata) != 16) {\n        ALOGE(\"ERROR: metadata block is the wrong size!\");\n    }\n\n    bytesLeft = fileSize + sizeof(metadata);\n    err = dataStream->WriteEntityHeader(key, bytesLeft);\n    if (err != 0) {\n        free(buf);\n        return err;\n    }\n\n    // store the file metadata first\n    metadata.version = tolel(CURRENT_METADATA_VERSION);\n    metadata.mode = tolel(mode);\n    metadata.undefined_1 = metadata.undefined_2 = 0;\n    err = dataStream->WriteEntityData(&metadata, sizeof(metadata));\n    if (err != 0) {\n        free(buf);\n        return err;\n    }\n    bytesLeft -= sizeof(metadata); // bytesLeft should == fileSize now\n\n    // now store the file content\n    while ((amt = read(fd, buf, bufsize)) != 0 && bytesLeft > 0) {\n        bytesLeft -= amt;\n        if (bytesLeft < 0) {\n            amt += bytesLeft; // Plus a negative is minus.  Don't write more than we promised.\n        }\n        err = dataStream->WriteEntityData(buf, amt);\n        if (err != 0) {\n            free(buf);\n            return err;\n        }\n    }\n    if (bytesLeft != 0) {\n        if (bytesLeft > 0) {\n            // Pad out the space we promised in the buffer.  We can't corrupt the buffer,\n            // even though the data we're sending is probably bad.\n            memset(buf, 0, bufsize);\n            while (bytesLeft > 0) {\n                amt = bytesLeft < bufsize ? bytesLeft : bufsize;\n                bytesLeft -= amt;\n                err = dataStream->WriteEntityData(buf, amt);\n                if (err != 0) {\n                    free(buf);\n                    return err;\n                }\n            }\n        }\n        ALOGE(\"write_update_file size mismatch for %s. expected=%d actual=%d.\"\n                \" You aren't doing proper locking!\", realFilename, fileSize, fileSize-bytesLeft);\n    }\n\n    free(buf);\n    return NO_ERROR;\n}\n\nstatic int\nwrite_update_file(BackupDataWriter* dataStream, const String8& key, char const* realFilename)\n{\n    int err;\n    struct stat st;\n\n    err = stat(realFilename, &st);\n    if (err < 0) {\n        return errno;\n    }\n\n    int fd = open(realFilename, O_RDONLY);\n    if (fd == -1) {\n        return errno;\n    }\n\n    err = write_update_file(dataStream, fd, st.st_mode, key, realFilename);\n    close(fd);\n    return err;\n}\n\nstatic int\ncompute_crc32(const char* file, FileRec* out) {\n    int fd = open(file, O_RDONLY);\n    if (fd < 0) {\n        return -1;\n    }\n\n    const int bufsize = 4*1024;\n    int amt;\n\n    char* buf = (char*)malloc(bufsize);\n    int crc = crc32(0L, Z_NULL, 0);\n\n    lseek(fd, 0, SEEK_SET);\n\n    while ((amt = read(fd, buf, bufsize)) != 0) {\n        crc = crc32(crc, (Bytef*)buf, amt);\n    }\n\n    close(fd);\n    free(buf);\n\n    out->s.crc32 = crc;\n    return NO_ERROR;\n}\n\nint\nback_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,\n        char const* const* files, char const* const* keys, int fileCount)\n{\n    int err;\n    KeyedVector<String8,FileState> oldSnapshot;\n    KeyedVector<String8,FileRec> newSnapshot;\n\n    if (oldSnapshotFD != -1) {\n        err = read_snapshot_file(oldSnapshotFD, &oldSnapshot);\n        if (err != 0) {\n            // On an error, treat this as a full backup.\n            oldSnapshot.clear();\n        }\n    }\n\n    for (int i=0; i<fileCount; i++) {\n        String8 key(keys[i]);\n        FileRec r;\n        char const* file = files[i];\n        r.file = file;\n        struct stat st;\n\n        err = stat(file, &st);\n        if (err != 0) {\n            // not found => treat as deleted\n            continue;\n        } else {\n            r.deleted = false;\n            r.s.modTime_sec = st.st_mtime;\n            r.s.modTime_nsec = 0; // workaround sim breakage\n            //r.s.modTime_nsec = st.st_mtime_nsec;\n            r.s.mode = st.st_mode;\n            r.s.size = st.st_size;\n\n            if (newSnapshot.indexOfKey(key) >= 0) {\n                LOGP(\"back_up_files key already in use '%s'\", key.string());\n                return -1;\n            }\n\n            // compute the CRC\n            if (compute_crc32(file, &r) != NO_ERROR) {\n                ALOGW(\"Unable to open file %s\", file);\n                continue;\n            }\n        }\n        newSnapshot.add(key, r);\n    }\n\n    int n = 0;\n    int N = oldSnapshot.size();\n    int m = 0;\n    int M = newSnapshot.size();\n\n    while (n<N && m<M) {\n        const String8& p = oldSnapshot.keyAt(n);\n        const String8& q = newSnapshot.keyAt(m);\n        FileRec& g = newSnapshot.editValueAt(m);\n        int cmp = p.compare(q);\n        if (cmp < 0) {\n            // file present in oldSnapshot, but not present in newSnapshot\n            LOGP(\"file removed: %s\", p.string());\n            write_delete_file(dataStream, p);\n            n++;\n        } else if (cmp > 0) {\n            // file added\n            LOGP(\"file added: %s crc=0x%08x\", g.file.string(), g.s.crc32);\n            write_update_file(dataStream, q, g.file.string());\n            m++;\n        } else {\n            // same file exists in both old and new; check whether to update\n            const FileState& f = oldSnapshot.valueAt(n);\n\n            LOGP(\"%s\", q.string());\n            LOGP(\"  old: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x\",\n                    f.modTime_sec, f.modTime_nsec, f.mode, f.size, f.crc32);\n            LOGP(\"  new: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x\",\n                    g.s.modTime_sec, g.s.modTime_nsec, g.s.mode, g.s.size, g.s.crc32);\n            if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec\n                    || f.mode != g.s.mode || f.size != g.s.size || f.crc32 != g.s.crc32) {\n                int fd = open(g.file.string(), O_RDONLY);\n                if (fd < 0) {\n                    ALOGE(\"Unable to read file for backup: %s\", g.file.string());\n                } else {\n                    write_update_file(dataStream, fd, g.s.mode, p, g.file.string());\n                    close(fd);\n                }\n            }\n            n++;\n            m++;\n        }\n    }\n\n    // these were deleted\n    while (n<N) {\n        write_delete_file(dataStream, oldSnapshot.keyAt(n));\n        n++;\n    }\n\n    // these were added\n    while (m<M) {\n        const String8& q = newSnapshot.keyAt(m);\n        FileRec& g = newSnapshot.editValueAt(m);\n        write_update_file(dataStream, q, g.file.string());\n        m++;\n    }\n\n    err = write_snapshot_file(newSnapshotFD, newSnapshot);\n\n    return 0;\n}\n\nstatic void calc_tar_checksum(char* buf) {\n    // [ 148 :   8 ] checksum -- to be calculated with this field as space chars\n    memset(buf + 148, ' ', 8);\n\n    uint16_t sum = 0;\n    for (uint8_t* p = (uint8_t*) buf; p < ((uint8_t*)buf) + 512; p++) {\n        sum += *p;\n    }\n\n    // Now write the real checksum value:\n    // [ 148 :   8 ]  checksum: 6 octal digits [leading zeroes], NUL, SPC\n    sprintf(buf + 148, \"%06o\", sum); // the trailing space is already in place\n}\n\n// Returns number of bytes written\nstatic int write_pax_header_entry(char* buf, const char* key, const char* value) {\n    // start with the size of \"1 key=value\\n\"\n    int len = strlen(key) + strlen(value) + 4;\n    if (len > 9) len++;\n    if (len > 99) len++;\n    if (len > 999) len++;\n    // since PATH_MAX is 4096 we don't expect to have to generate any single\n    // header entry longer than 9999 characters\n\n    return sprintf(buf, \"%d %s=%s\\n\", len, key, value);\n}\n\n// Wire format to the backup manager service is chunked:  each chunk is prefixed by\n// a 4-byte count of its size.  A chunk size of zero (four zero bytes) indicates EOD.\nvoid send_tarfile_chunk(BackupDataWriter* writer, const char* buffer, size_t size) {\n    uint32_t chunk_size_no = htonl(size);\n    writer->WriteEntityData(&chunk_size_no, 4);\n    if (size != 0) writer->WriteEntityData(buffer, size);\n}\n\nint write_tarfile(const String8& packageName, const String8& domain,\n        const String8& rootpath, const String8& filepath, off_t* outSize,\n        BackupDataWriter* writer)\n{\n    // In the output stream everything is stored relative to the root\n    const char* relstart = filepath.string() + rootpath.length();\n    if (*relstart == '/') relstart++;     // won't be true when path == rootpath\n    String8 relpath(relstart);\n\n    // If relpath is empty, it means this is the top of one of the standard named\n    // domain directories, so we should just skip it\n    if (relpath.length() == 0) {\n        *outSize = 0;\n        return 0;\n    }\n\n    // Too long a name for the ustar format?\n    //    \"apps/\" + packagename + '/' + domainpath < 155 chars\n    //    relpath < 100 chars\n    bool needExtended = false;\n    if ((5 + packageName.length() + 1 + domain.length() >= 155) || (relpath.length() >= 100)) {\n        needExtended = true;\n    }\n\n    // Non-7bit-clean path also means needing pax extended format\n    if (!needExtended) {\n        for (size_t i = 0; i < filepath.length(); i++) {\n            if ((filepath[i] & 0x80) != 0) {\n                needExtended = true;\n                break;\n            }\n        }\n    }\n\n    int err = 0;\n    struct stat64 s;\n    if (lstat64(filepath.string(), &s) != 0) {\n        err = errno;\n        ALOGE(\"Error %d (%s) from lstat64(%s)\", err, strerror(err), filepath.string());\n        return err;\n    }\n\n    // very large files need a pax extended size header\n    if (s.st_size > 077777777777LL) {\n        needExtended = true;\n    }\n\n    String8 fullname;   // for pax later on\n    String8 prefix;\n\n    const int isdir = S_ISDIR(s.st_mode);\n    if (isdir) s.st_size = 0;   // directories get no actual data in the tar stream\n\n    // Report the size, including a rough tar overhead estimation: 512 bytes for the\n    // overall tar file-block header, plus 2 blocks if using the pax extended format,\n    // plus the raw content size rounded up to a multiple of 512.\n    *outSize = 512 + (needExtended ? 1024 : 0) + 512*((s.st_size + 511)/512);\n\n    // Measure case: we've returned the size; now return without moving data\n    if (!writer) return 0;\n\n    // !!! TODO: use mmap when possible to avoid churning the buffer cache\n    // !!! TODO: this will break with symlinks; need to use readlink(2)\n    int fd = open(filepath.string(), O_RDONLY);\n    if (fd < 0) {\n        err = errno;\n        ALOGE(\"Error %d (%s) from open(%s)\", err, strerror(err), filepath.string());\n        return err;\n    }\n\n    // read/write up to this much at a time.\n    const size_t BUFSIZE = 32 * 1024;\n    char* buf = (char *)calloc(1,BUFSIZE);\n    char* paxHeader = buf + 512;    // use a different chunk of it as separate scratch\n    char* paxData = buf + 1024;\n\n    if (buf == NULL) {\n        ALOGE(\"Out of mem allocating transfer buffer\");\n        err = ENOMEM;\n        goto done;\n    }\n\n    // Magic fields for the ustar file format\n    strcat(buf + 257, \"ustar\");\n    strcat(buf + 263, \"00\");\n\n    // [ 265 : 32 ] user name, ignored on restore\n    // [ 297 : 32 ] group name, ignored on restore\n\n    // [ 100 :   8 ] file mode\n    snprintf(buf + 100, 8, \"%06o \", s.st_mode & ~S_IFMT);\n\n    // [ 108 :   8 ] uid -- ignored in Android format; uids are remapped at restore time\n    // [ 116 :   8 ] gid -- ignored in Android format\n    snprintf(buf + 108, 8, \"0%lo\", (unsigned long)s.st_uid);\n    snprintf(buf + 116, 8, \"0%lo\", (unsigned long)s.st_gid);\n\n    // [ 124 :  12 ] file size in bytes\n    snprintf(buf + 124, 12, \"%011llo\", (isdir) ? 0LL : s.st_size);\n\n    // [ 136 :  12 ] last mod time as a UTC time_t\n    snprintf(buf + 136, 12, \"%0lo\", (unsigned long)s.st_mtime);\n\n    // [ 156 :   1 ] link/file type\n    uint8_t type;\n    if (isdir) {\n        type = '5';     // tar magic: '5' == directory\n    } else if (S_ISREG(s.st_mode)) {\n        type = '0';     // tar magic: '0' == normal file\n    } else {\n        ALOGW(\"Error: unknown file mode 0%o [%s]\", s.st_mode, filepath.string());\n        goto cleanup;\n    }\n    buf[156] = type;\n\n    // [ 157 : 100 ] name of linked file [not implemented]\n\n    {\n        // Prefix and main relative path.  Path lengths have been preflighted.\n        if (packageName.length() > 0) {\n            prefix = \"apps/\";\n            prefix += packageName;\n        }\n        if (domain.length() > 0) {\n            prefix.appendPath(domain);\n        }\n\n        // pax extended means we don't put in a prefix field, and put a different\n        // string in the basic name field.  We can also construct the full path name\n        // out of the substrings we've now built.\n        fullname = prefix;\n        fullname.appendPath(relpath);\n\n        // ustar:\n        //    [   0 : 100 ]; file name/path\n        //    [ 345 : 155 ] filename path prefix\n        // We only use the prefix area if fullname won't fit in the path\n        if (fullname.length() > 100) {\n            strncpy(buf, relpath.string(), 100);\n            strncpy(buf + 345, prefix.string(), 155);\n        } else {\n            strncpy(buf, fullname.string(), 100);\n        }\n    }\n\n    // [ 329 : 8 ] and [ 337 : 8 ] devmajor/devminor, not used\n\n    ALOGI(\"   Name: %s\", fullname.string());\n\n    // If we're using a pax extended header, build & write that here; lengths are\n    // already preflighted\n    if (needExtended) {\n        char sizeStr[32];   // big enough for a 64-bit unsigned value in decimal\n        char* p = paxData;\n\n        // construct the pax extended header data block\n        memset(paxData, 0, BUFSIZE - (paxData - buf));\n\n        // size header -- calc len in digits by actually rendering the number\n        // to a string - brute force but simple\n        snprintf(sizeStr, sizeof(sizeStr), \"%lld\", (long long)s.st_size);\n        p += write_pax_header_entry(p, \"size\", sizeStr);\n\n        // fullname was generated above with the ustar paths\n        p += write_pax_header_entry(p, \"path\", fullname.string());\n\n        // Now we know how big the pax data is\n        int paxLen = p - paxData;\n\n        // Now build the pax *header* templated on the ustar header\n        memcpy(paxHeader, buf, 512);\n\n        String8 leaf = fullname.getPathLeaf();\n        memset(paxHeader, 0, 100);                  // rewrite the name area\n        snprintf(paxHeader, 100, \"PaxHeader/%s\", leaf.string());\n        memset(paxHeader + 345, 0, 155);            // rewrite the prefix area\n        strncpy(paxHeader + 345, prefix.string(), 155);\n\n        paxHeader[156] = 'x';                       // mark it as a pax extended header\n\n        // [ 124 :  12 ] size of pax extended header data\n        memset(paxHeader + 124, 0, 12);\n        snprintf(paxHeader + 124, 12, \"%011o\", (unsigned int)(p - paxData));\n\n        // Checksum and write the pax block header\n        calc_tar_checksum(paxHeader);\n        send_tarfile_chunk(writer, paxHeader, 512);\n\n        // Now write the pax data itself\n        int paxblocks = (paxLen + 511) / 512;\n        send_tarfile_chunk(writer, paxData, 512 * paxblocks);\n    }\n\n    // Checksum and write the 512-byte ustar file header block to the output\n    calc_tar_checksum(buf);\n    send_tarfile_chunk(writer, buf, 512);\n\n    // Now write the file data itself, for real files.  We honor tar's convention that\n    // only full 512-byte blocks are sent to write().\n    if (!isdir) {\n        off64_t toWrite = s.st_size;\n        while (toWrite > 0) {\n            size_t toRead = toWrite;\n            if (toRead > BUFSIZE) {\n                toRead = BUFSIZE;\n            }\n            ssize_t nRead = read(fd, buf, toRead);\n            if (nRead < 0) {\n                err = errno;\n                ALOGE(\"Unable to read file [%s], err=%d (%s)\", filepath.string(),\n                        err, strerror(err));\n                break;\n            } else if (nRead == 0) {\n                ALOGE(\"EOF but expect %lld more bytes in [%s]\", (long long) toWrite,\n                        filepath.string());\n                err = EIO;\n                break;\n            }\n\n            // At EOF we might have a short block; NUL-pad that to a 512-byte multiple.  This\n            // depends on the OS guarantee that for ordinary files, read() will never return\n            // less than the number of bytes requested.\n            ssize_t partial = (nRead+512) % 512;\n            if (partial > 0) {\n                ssize_t remainder = 512 - partial;\n                memset(buf + nRead, 0, remainder);\n                nRead += remainder;\n            }\n            send_tarfile_chunk(writer, buf, nRead);\n            toWrite -= nRead;\n        }\n    }\n\ncleanup:\n    free(buf);\ndone:\n    close(fd);\n    return err;\n}\n// end tarfile\n\n\n\n#define RESTORE_BUF_SIZE (8*1024)\n\nRestoreHelperBase::RestoreHelperBase()\n{\n    m_buf = malloc(RESTORE_BUF_SIZE);\n    m_loggedUnknownMetadata = false;\n}\n\nRestoreHelperBase::~RestoreHelperBase()\n{\n    free(m_buf);\n}\n\nstatus_t\nRestoreHelperBase::WriteFile(const String8& filename, BackupDataReader* in)\n{\n    ssize_t err;\n    size_t dataSize;\n    String8 key;\n    int fd;\n    void* buf = m_buf;\n    ssize_t amt;\n    int mode;\n    int crc;\n    struct stat st;\n    FileRec r;\n\n    err = in->ReadEntityHeader(&key, &dataSize);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    // Get the metadata block off the head of the file entity and use that to\n    // set up the output file\n    file_metadata_v1 metadata;\n    amt = in->ReadEntityData(&metadata, sizeof(metadata));\n    if (amt != sizeof(metadata)) {\n        ALOGW(\"Could not read metadata for %s -- %ld / %s\", filename.string(),\n                (long)amt, strerror(errno));\n        return EIO;\n    }\n    metadata.version = fromlel(metadata.version);\n    metadata.mode = fromlel(metadata.mode);\n    if (metadata.version > CURRENT_METADATA_VERSION) {\n        if (!m_loggedUnknownMetadata) {\n            m_loggedUnknownMetadata = true;\n            ALOGW(\"Restoring file with unsupported metadata version %d (currently %d)\",\n                    metadata.version, CURRENT_METADATA_VERSION);\n        }\n    }\n    mode = metadata.mode;\n\n    // Write the file and compute the crc\n    crc = crc32(0L, Z_NULL, 0);\n    fd = open(filename.string(), O_CREAT|O_RDWR|O_TRUNC, mode);\n    if (fd == -1) {\n        ALOGW(\"Could not open file %s -- %s\", filename.string(), strerror(errno));\n        return errno;\n    }\n\n    while ((amt = in->ReadEntityData(buf, RESTORE_BUF_SIZE)) > 0) {\n        err = write(fd, buf, amt);\n        if (err != amt) {\n            close(fd);\n            ALOGW(\"Error '%s' writing '%s'\", strerror(errno), filename.string());\n            return errno;\n        }\n        crc = crc32(crc, (Bytef*)buf, amt);\n    }\n\n    close(fd);\n\n    // Record for the snapshot\n    err = stat(filename.string(), &st);\n    if (err != 0) {\n        ALOGW(\"Error stating file that we just created %s\", filename.string());\n        return errno;\n    }\n\n    r.file = filename;\n    r.deleted = false;\n    r.s.modTime_sec = st.st_mtime;\n    r.s.modTime_nsec = 0; // workaround sim breakage\n    //r.s.modTime_nsec = st.st_mtime_nsec;\n    r.s.mode = st.st_mode;\n    r.s.size = st.st_size;\n    r.s.crc32 = crc;\n\n    m_files.add(key, r);\n\n    return NO_ERROR;\n}\n\nstatus_t\nRestoreHelperBase::WriteSnapshot(int fd)\n{\n    return write_snapshot_file(fd, m_files);;\n}\n\n#if TEST_BACKUP_HELPERS\n\n#define SCRATCH_DIR \"/data/backup_helper_test/\"\n\nstatic int\nwrite_text_file(const char* path, const char* data)\n{\n    int amt;\n    int fd;\n    int len;\n\n    fd = creat(path, 0666);\n    if (fd == -1) {\n        fprintf(stderr, \"creat %s failed\\n\", path);\n        return errno;\n    }\n\n    len = strlen(data);\n    amt = write(fd, data, len);\n    if (amt != len) {\n        fprintf(stderr, \"error (%s) writing to file %s\\n\", strerror(errno), path);\n        return errno;\n    }\n\n    close(fd);\n\n    return 0;\n}\n\nstatic int\ncompare_file(const char* path, const unsigned char* data, int len)\n{\n    int fd;\n    int amt;\n\n    fd = open(path, O_RDONLY);\n    if (fd == -1) {\n        fprintf(stderr, \"compare_file error (%s) opening %s\\n\", strerror(errno), path);\n        return errno;\n    }\n\n    unsigned char* contents = (unsigned char*)malloc(len);\n    if (contents == NULL) {\n        fprintf(stderr, \"malloc(%d) failed\\n\", len);\n        return ENOMEM;\n    }\n\n    bool sizesMatch = true;\n    amt = lseek(fd, 0, SEEK_END);\n    if (amt != len) {\n        fprintf(stderr, \"compare_file file length should be %d, was %d\\n\", len, amt);\n        sizesMatch = false;\n    }\n    lseek(fd, 0, SEEK_SET);\n\n    int readLen = amt < len ? amt : len;\n    amt = read(fd, contents, readLen);\n    if (amt != readLen) {\n        fprintf(stderr, \"compare_file read expected %d bytes but got %d\\n\", len, amt);\n    }\n\n    bool contentsMatch = true;\n    for (int i=0; i<readLen; i++) {\n        if (data[i] != contents[i]) {\n            if (contentsMatch) {\n                fprintf(stderr, \"compare_file contents are different: (index, expected, actual)\\n\");\n                contentsMatch = false;\n            }\n            fprintf(stderr, \"  [%-2d] %02x %02x\\n\", i, data[i], contents[i]);\n        }\n    }\n\n    free(contents);\n    return contentsMatch && sizesMatch ? 0 : 1;\n}\n\nint\nbackup_helper_test_empty()\n{\n    int err;\n    int fd;\n    KeyedVector<String8,FileRec> snapshot;\n    const char* filename = SCRATCH_DIR \"backup_helper_test_empty.snap\";\n\n    system(\"rm -r \" SCRATCH_DIR);\n    mkdir(SCRATCH_DIR, 0777);\n\n    // write\n    fd = creat(filename, 0666);\n    if (fd == -1) {\n        fprintf(stderr, \"error creating %s\\n\", filename);\n        return 1;\n    }\n\n    err = write_snapshot_file(fd, snapshot);\n\n    close(fd);\n\n    if (err != 0) {\n        fprintf(stderr, \"write_snapshot_file reported error %d (%s)\\n\", err, strerror(err));\n        return err;\n    }\n\n    static const unsigned char correct_data[] = {\n        0x53, 0x6e, 0x61, 0x70,  0x00, 0x00, 0x00, 0x00,\n        0x46, 0x69, 0x6c, 0x65,  0x10, 0x00, 0x00, 0x00\n    };\n\n    err = compare_file(filename, correct_data, sizeof(correct_data));\n    if (err != 0) {\n        return err;\n    }\n\n    // read\n    fd = open(filename, O_RDONLY);\n    if (fd == -1) {\n        fprintf(stderr, \"error opening for read %s\\n\", filename);\n        return 1;\n    }\n\n    KeyedVector<String8,FileState> readSnapshot;\n    err = read_snapshot_file(fd, &readSnapshot);\n    if (err != 0) {\n        fprintf(stderr, \"read_snapshot_file failed %d\\n\", err);\n        return err;\n    }\n\n    if (readSnapshot.size() != 0) {\n        fprintf(stderr, \"readSnapshot should be length 0\\n\");\n        return 1;\n    }\n\n    return 0;\n}\n\nint\nbackup_helper_test_four()\n{\n    int err;\n    int fd;\n    KeyedVector<String8,FileRec> snapshot;\n    const char* filename = SCRATCH_DIR \"backup_helper_test_four.snap\";\n\n    system(\"rm -r \" SCRATCH_DIR);\n    mkdir(SCRATCH_DIR, 0777);\n\n    // write\n    fd = creat(filename, 0666);\n    if (fd == -1) {\n        fprintf(stderr, \"error opening %s\\n\", filename);\n        return 1;\n    }\n\n    String8 filenames[4];\n    FileState states[4];\n    FileRec r;\n    r.deleted = false;\n\n    states[0].modTime_sec = 0xfedcba98;\n    states[0].modTime_nsec = 0xdeadbeef;\n    states[0].mode = 0777; // decimal 511, hex 0x000001ff\n    states[0].size = 0xababbcbc;\n    states[0].crc32 = 0x12345678;\n    states[0].nameLen = -12;\n    r.s = states[0];\n    filenames[0] = String8(\"bytes_of_padding\");\n    snapshot.add(filenames[0], r);\n\n    states[1].modTime_sec = 0x93400031;\n    states[1].modTime_nsec = 0xdeadbeef;\n    states[1].mode = 0666; // decimal 438, hex 0x000001b6\n    states[1].size = 0x88557766;\n    states[1].crc32 = 0x22334422;\n    states[1].nameLen = -1;\n    r.s = states[1];\n    filenames[1] = String8(\"bytes_of_padding3\");\n    snapshot.add(filenames[1], r);\n\n    states[2].modTime_sec = 0x33221144;\n    states[2].modTime_nsec = 0xdeadbeef;\n    states[2].mode = 0744; // decimal 484, hex 0x000001e4\n    states[2].size = 0x11223344;\n    states[2].crc32 = 0x01122334;\n    states[2].nameLen = 0;\n    r.s = states[2];\n    filenames[2] = String8(\"bytes_of_padding_2\");\n    snapshot.add(filenames[2], r);\n\n    states[3].modTime_sec = 0x33221144;\n    states[3].modTime_nsec = 0xdeadbeef;\n    states[3].mode = 0755; // decimal 493, hex 0x000001ed\n    states[3].size = 0x11223344;\n    states[3].crc32 = 0x01122334;\n    states[3].nameLen = 0;\n    r.s = states[3];\n    filenames[3] = String8(\"bytes_of_padding__1\");\n    snapshot.add(filenames[3], r);\n\n    err = write_snapshot_file(fd, snapshot);\n\n    close(fd);\n\n    if (err != 0) {\n        fprintf(stderr, \"write_snapshot_file reported error %d (%s)\\n\", err, strerror(err));\n        return err;\n    }\n\n    static const unsigned char correct_data[] = {\n        // header\n        0x53, 0x6e, 0x61, 0x70,  0x04, 0x00, 0x00, 0x00,\n        0x46, 0x69, 0x6c, 0x65,  0xbc, 0x00, 0x00, 0x00,\n\n        // bytes_of_padding\n        0x98, 0xba, 0xdc, 0xfe,  0xef, 0xbe, 0xad, 0xde,\n        0xff, 0x01, 0x00, 0x00,  0xbc, 0xbc, 0xab, 0xab,\n        0x78, 0x56, 0x34, 0x12,  0x10, 0x00, 0x00, 0x00,\n        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,\n        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,\n\n        // bytes_of_padding3\n        0x31, 0x00, 0x40, 0x93,  0xef, 0xbe, 0xad, 0xde,\n        0xb6, 0x01, 0x00, 0x00,  0x66, 0x77, 0x55, 0x88,\n        0x22, 0x44, 0x33, 0x22,  0x11, 0x00, 0x00, 0x00,\n        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,\n        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,\n        0x33, 0xab, 0xab, 0xab,\n\n        // bytes of padding2\n        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,\n        0xe4, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,\n        0x34, 0x23, 0x12, 0x01,  0x12, 0x00, 0x00, 0x00,\n        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,\n        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,\n        0x5f, 0x32, 0xab, 0xab,\n\n        // bytes of padding3\n        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,\n        0xed, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,\n        0x34, 0x23, 0x12, 0x01,  0x13, 0x00, 0x00, 0x00,\n        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,\n        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,\n        0x5f, 0x5f, 0x31, 0xab\n    };\n\n    err = compare_file(filename, correct_data, sizeof(correct_data));\n    if (err != 0) {\n        return err;\n    }\n\n    // read\n    fd = open(filename, O_RDONLY);\n    if (fd == -1) {\n        fprintf(stderr, \"error opening for read %s\\n\", filename);\n        return 1;\n    }\n\n\n    KeyedVector<String8,FileState> readSnapshot;\n    err = read_snapshot_file(fd, &readSnapshot);\n    if (err != 0) {\n        fprintf(stderr, \"read_snapshot_file failed %d\\n\", err);\n        return err;\n    }\n\n    if (readSnapshot.size() != 4) {\n        fprintf(stderr, \"readSnapshot should be length 4 is %zu\\n\", readSnapshot.size());\n        return 1;\n    }\n\n    bool matched = true;\n    for (size_t i=0; i<readSnapshot.size(); i++) {\n        const String8& name = readSnapshot.keyAt(i);\n        const FileState state = readSnapshot.valueAt(i);\n\n        if (name != filenames[i] || states[i].modTime_sec != state.modTime_sec\n                || states[i].modTime_nsec != state.modTime_nsec || states[i].mode != state.mode\n                || states[i].size != state.size || states[i].crc32 != states[i].crc32) {\n            fprintf(stderr, \"state %zu expected={%d/%d, %04o, 0x%08x, 0x%08x, %3zu} '%s'\\n\"\n                            \"          actual={%d/%d, %04o, 0x%08x, 0x%08x, %3d} '%s'\\n\", i,\n                    states[i].modTime_sec, states[i].modTime_nsec, states[i].mode, states[i].size,\n                    states[i].crc32, name.length(), filenames[i].string(),\n                    state.modTime_sec, state.modTime_nsec, state.mode, state.size, state.crc32,\n                    state.nameLen, name.string());\n            matched = false;\n        }\n    }\n\n    return matched ? 0 : 1;\n}\n\n// hexdump -v -e '\"    \" 8/1 \" 0x%02x,\" \"\\n\"' data_writer.data\nconst unsigned char DATA_GOLDEN_FILE[] = {\n     0x44, 0x61, 0x74, 0x61, 0x0b, 0x00, 0x00, 0x00,\n     0x0c, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x5f, 0x70,\n     0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,\n     0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,\n     0x6e, 0x67, 0x5f, 0x00, 0x44, 0x61, 0x74, 0x61,\n     0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,\n     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,\n     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,\n     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,\n     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,\n     0x44, 0x61, 0x74, 0x61, 0x0d, 0x00, 0x00, 0x00,\n     0x0e, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,\n     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,\n     0x5f, 0x00, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,\n     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,\n     0x5f, 0x00, 0xbc, 0xbc, 0x44, 0x61, 0x74, 0x61,\n     0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,\n     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,\n     0x6f, 0x31, 0x00, 0xbc, 0x70, 0x61, 0x64, 0x64,\n     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00\n\n};\nconst int DATA_GOLDEN_FILE_SIZE = sizeof(DATA_GOLDEN_FILE);\n\nstatic int\ntest_write_header_and_entity(BackupDataWriter& writer, const char* str)\n{\n    int err;\n    String8 text(str);\n\n    err = writer.WriteEntityHeader(text, text.length()+1);\n    if (err != 0) {\n        fprintf(stderr, \"WriteEntityHeader failed with %s\\n\", strerror(err));\n        return err;\n    }\n\n    err = writer.WriteEntityData(text.string(), text.length()+1);\n    if (err != 0) {\n        fprintf(stderr, \"write failed for data '%s'\\n\", text.string());\n        return errno;\n    }\n\n    return err;\n}\n\nint\nbackup_helper_test_data_writer()\n{\n    int err;\n    int fd;\n    const char* filename = SCRATCH_DIR \"data_writer.data\";\n\n    system(\"rm -r \" SCRATCH_DIR);\n    mkdir(SCRATCH_DIR, 0777);\n    mkdir(SCRATCH_DIR \"data\", 0777);\n\n    fd = creat(filename, 0666);\n    if (fd == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    BackupDataWriter writer(fd);\n\n    err = 0;\n    err |= test_write_header_and_entity(writer, \"no_padding_\");\n    err |= test_write_header_and_entity(writer, \"padded_to__3\");\n    err |= test_write_header_and_entity(writer, \"padded_to_2__\");\n    err |= test_write_header_and_entity(writer, \"padded_to1\");\n\n    close(fd);\n\n    err = compare_file(filename, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);\n    if (err != 0) {\n        return err;\n    }\n\n    return err;\n}\n\nint\ntest_read_header_and_entity(BackupDataReader& reader, const char* str)\n{\n    int err;\n    size_t bufSize = strlen(str)+1;\n    char* buf = (char*)malloc(bufSize);\n    String8 string;\n    size_t actualSize;\n    bool done;\n    int type;\n    ssize_t nRead;\n\n    // printf(\"\\n\\n---------- test_read_header_and_entity -- %s\\n\\n\", str);\n\n    err = reader.ReadNextHeader(&done, &type);\n    if (done) {\n        fprintf(stderr, \"should not be done yet\\n\");\n        goto finished;\n    }\n    if (err != 0) {\n        fprintf(stderr, \"ReadNextHeader (for app header) failed with %s\\n\", strerror(err));\n        goto finished;\n    }\n    if (type != BACKUP_HEADER_ENTITY_V1) {\n        err = EINVAL;\n        fprintf(stderr, \"type=0x%08x expected 0x%08x\\n\", type, BACKUP_HEADER_ENTITY_V1);\n    }\n\n    err = reader.ReadEntityHeader(&string, &actualSize);\n    if (err != 0) {\n        fprintf(stderr, \"ReadEntityHeader failed with %s\\n\", strerror(err));\n        goto finished;\n    }\n    if (string != str) {\n        fprintf(stderr, \"ReadEntityHeader expected key '%s' got '%s'\\n\", str, string.string());\n        err = EINVAL;\n        goto finished;\n    }\n    if (actualSize != bufSize) {\n        fprintf(stderr, \"ReadEntityHeader expected dataSize %zu got %zu\\n\",\n                bufSize, actualSize);\n        err = EINVAL;\n        goto finished;\n    }\n\n    nRead = reader.ReadEntityData(buf, bufSize);\n    if (nRead < 0) {\n        err = reader.Status();\n        fprintf(stderr, \"ReadEntityData failed with %s\\n\", strerror(err));\n        goto finished;\n    }\n\n    if (0 != memcmp(buf, str, bufSize)) {\n        fprintf(stderr, \"ReadEntityData expected '%s' but got something starting with \"\n                \"%02x %02x %02x %02x  '%c%c%c%c'\\n\", str, buf[0], buf[1], buf[2], buf[3],\n                buf[0], buf[1], buf[2], buf[3]);\n        err = EINVAL;\n        goto finished;\n    }\n\n    // The next read will confirm whether it got the right amount of data.\n\nfinished:\n    if (err != NO_ERROR) {\n        fprintf(stderr, \"test_read_header_and_entity failed with %s\\n\", strerror(err));\n    }\n    free(buf);\n    return err;\n}\n\nint\nbackup_helper_test_data_reader()\n{\n    int err;\n    int fd;\n    const char* filename = SCRATCH_DIR \"data_reader.data\";\n\n    system(\"rm -r \" SCRATCH_DIR);\n    mkdir(SCRATCH_DIR, 0777);\n    mkdir(SCRATCH_DIR \"data\", 0777);\n\n    fd = creat(filename, 0666);\n    if (fd == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    err = write(fd, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);\n    if (err != DATA_GOLDEN_FILE_SIZE) {\n        fprintf(stderr, \"Error \\\"%s\\\" writing golden file %s\\n\", strerror(errno), filename);\n        return errno;\n    }\n\n    close(fd);\n\n    fd = open(filename, O_RDONLY);\n    if (fd == -1) {\n        fprintf(stderr, \"Error \\\"%s\\\" opening golden file %s for read\\n\", strerror(errno),\n                filename);\n        return errno;\n    }\n\n    {\n        BackupDataReader reader(fd);\n\n        err = 0;\n\n        if (err == NO_ERROR) {\n            err = test_read_header_and_entity(reader, \"no_padding_\");\n        }\n\n        if (err == NO_ERROR) {\n            err = test_read_header_and_entity(reader, \"padded_to__3\");\n        }\n\n        if (err == NO_ERROR) {\n            err = test_read_header_and_entity(reader, \"padded_to_2__\");\n        }\n\n        if (err == NO_ERROR) {\n            err = test_read_header_and_entity(reader, \"padded_to1\");\n        }\n    }\n\n    close(fd);\n\n    return err;\n}\n\nstatic int\nget_mod_time(const char* filename, struct timeval times[2])\n{\n    int err;\n    struct stat64 st;\n    err = stat64(filename, &st);\n    if (err != 0) {\n        fprintf(stderr, \"stat '%s' failed: %s\\n\", filename, strerror(errno));\n        return errno;\n    }\n\n    times[0].tv_sec = st.st_atim.tv_sec;\n    times[0].tv_usec = st.st_atim.tv_nsec / 1000;\n\n    times[1].tv_sec = st.st_mtim.tv_sec;\n    times[1].tv_usec = st.st_mtim.tv_nsec / 1000;\n\n    return 0;\n}\n\nint\nbackup_helper_test_files()\n{\n    int err;\n    int oldSnapshotFD;\n    int dataStreamFD;\n    int newSnapshotFD;\n\n    system(\"rm -r \" SCRATCH_DIR);\n    mkdir(SCRATCH_DIR, 0777);\n    mkdir(SCRATCH_DIR \"data\", 0777);\n\n    write_text_file(SCRATCH_DIR \"data/b\", \"b\\nbb\\n\");\n    write_text_file(SCRATCH_DIR \"data/c\", \"c\\ncc\\n\");\n    write_text_file(SCRATCH_DIR \"data/d\", \"d\\ndd\\n\");\n    write_text_file(SCRATCH_DIR \"data/e\", \"e\\nee\\n\");\n    write_text_file(SCRATCH_DIR \"data/f\", \"f\\nff\\n\");\n    write_text_file(SCRATCH_DIR \"data/h\", \"h\\nhh\\n\");\n\n    char const* files_before[] = {\n        SCRATCH_DIR \"data/b\",\n        SCRATCH_DIR \"data/c\",\n        SCRATCH_DIR \"data/d\",\n        SCRATCH_DIR \"data/e\",\n        SCRATCH_DIR \"data/f\"\n    };\n\n    char const* keys_before[] = {\n        \"data/b\",\n        \"data/c\",\n        \"data/d\",\n        \"data/e\",\n        \"data/f\"\n    };\n\n    dataStreamFD = creat(SCRATCH_DIR \"1.data\", 0666);\n    if (dataStreamFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    newSnapshotFD = creat(SCRATCH_DIR \"before.snap\", 0666);\n    if (newSnapshotFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    {\n        BackupDataWriter dataStream(dataStreamFD);\n\n        err = back_up_files(-1, &dataStream, newSnapshotFD, files_before, keys_before, 5);\n        if (err != 0) {\n            return err;\n        }\n    }\n\n    close(dataStreamFD);\n    close(newSnapshotFD);\n\n    sleep(3);\n\n    struct timeval d_times[2];\n    struct timeval e_times[2];\n\n    err = get_mod_time(SCRATCH_DIR \"data/d\", d_times);\n    err |= get_mod_time(SCRATCH_DIR \"data/e\", e_times);\n    if (err != 0) {\n        return err;\n    }\n\n    write_text_file(SCRATCH_DIR \"data/a\", \"a\\naa\\n\");\n    unlink(SCRATCH_DIR \"data/c\");\n    write_text_file(SCRATCH_DIR \"data/c\", \"c\\ncc\\n\");\n    write_text_file(SCRATCH_DIR \"data/d\", \"dd\\ndd\\n\");\n    utimes(SCRATCH_DIR \"data/d\", d_times);\n    write_text_file(SCRATCH_DIR \"data/e\", \"z\\nzz\\n\");\n    utimes(SCRATCH_DIR \"data/e\", e_times);\n    write_text_file(SCRATCH_DIR \"data/g\", \"g\\ngg\\n\");\n    unlink(SCRATCH_DIR \"data/f\");\n\n    char const* files_after[] = {\n        SCRATCH_DIR \"data/a\", // added\n        SCRATCH_DIR \"data/b\", // same\n        SCRATCH_DIR \"data/c\", // different mod time\n        SCRATCH_DIR \"data/d\", // different size (same mod time)\n        SCRATCH_DIR \"data/e\", // different contents (same mod time, same size)\n        SCRATCH_DIR \"data/g\"  // added\n    };\n\n    char const* keys_after[] = {\n        \"data/a\", // added\n        \"data/b\", // same\n        \"data/c\", // different mod time\n        \"data/d\", // different size (same mod time)\n        \"data/e\", // different contents (same mod time, same size)\n        \"data/g\"  // added\n    };\n\n    oldSnapshotFD = open(SCRATCH_DIR \"before.snap\", O_RDONLY);\n    if (oldSnapshotFD == -1) {\n        fprintf(stderr, \"error opening: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    dataStreamFD = creat(SCRATCH_DIR \"2.data\", 0666);\n    if (dataStreamFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    newSnapshotFD = creat(SCRATCH_DIR \"after.snap\", 0666);\n    if (newSnapshotFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    {\n        BackupDataWriter dataStream(dataStreamFD);\n\n        err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, files_after, keys_after, 6);\n        if (err != 0) {\n            return err;\n        }\n}\n\n    close(oldSnapshotFD);\n    close(dataStreamFD);\n    close(newSnapshotFD);\n\n    return 0;\n}\n\nint\nbackup_helper_test_null_base()\n{\n    int err;\n    int dataStreamFD;\n    int newSnapshotFD;\n\n    system(\"rm -r \" SCRATCH_DIR);\n    mkdir(SCRATCH_DIR, 0777);\n    mkdir(SCRATCH_DIR \"data\", 0777);\n\n    write_text_file(SCRATCH_DIR \"data/a\", \"a\\naa\\n\");\n\n    char const* files[] = {\n        SCRATCH_DIR \"data/a\",\n    };\n\n    char const* keys[] = {\n        \"a\",\n    };\n\n    dataStreamFD = creat(SCRATCH_DIR \"null_base.data\", 0666);\n    if (dataStreamFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    newSnapshotFD = creat(SCRATCH_DIR \"null_base.snap\", 0666);\n    if (newSnapshotFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    {\n        BackupDataWriter dataStream(dataStreamFD);\n\n        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);\n        if (err != 0) {\n            return err;\n        }\n    }\n\n    close(dataStreamFD);\n    close(newSnapshotFD);\n\n    return 0;\n}\n\nint\nbackup_helper_test_missing_file()\n{\n    int err;\n    int dataStreamFD;\n    int newSnapshotFD;\n\n    system(\"rm -r \" SCRATCH_DIR);\n    mkdir(SCRATCH_DIR, 0777);\n    mkdir(SCRATCH_DIR \"data\", 0777);\n\n    write_text_file(SCRATCH_DIR \"data/b\", \"b\\nbb\\n\");\n\n    char const* files[] = {\n        SCRATCH_DIR \"data/a\",\n        SCRATCH_DIR \"data/b\",\n        SCRATCH_DIR \"data/c\",\n    };\n\n    char const* keys[] = {\n        \"a\",\n        \"b\",\n        \"c\",\n    };\n\n    dataStreamFD = creat(SCRATCH_DIR \"null_base.data\", 0666);\n    if (dataStreamFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    newSnapshotFD = creat(SCRATCH_DIR \"null_base.snap\", 0666);\n    if (newSnapshotFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    {\n        BackupDataWriter dataStream(dataStreamFD);\n\n        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);\n        if (err != 0) {\n            return err;\n        }\n    }\n\n    close(dataStreamFD);\n    close(newSnapshotFD);\n\n    return 0;\n}\n\n\n#endif // TEST_BACKUP_HELPERS\n\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/CursorWindow.cpp",
    "content": "/*\n * Copyright (C) 2006-2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#undef LOG_TAG\n#define LOG_TAG \"CursorWindow\"\n\n#include <androidfw/CursorWindow.h>\n#include <binder/Parcel.h>\n#include <utils/Log.h>\n\n#include <cutils/ashmem.h>\n#include <sys/mman.h>\n\n#include <assert.h>\n#include <string.h>\n#include <stdlib.h>\n\nnamespace android {\n\nCursorWindow::CursorWindow(const String8& name, int ashmemFd,\n        void* data, size_t size, bool readOnly) :\n        mName(name), mAshmemFd(ashmemFd), mData(data), mSize(size), mReadOnly(readOnly) {\n    mHeader = static_cast<Header*>(mData);\n}\n\nCursorWindow::~CursorWindow() {\n    ::munmap(mData, mSize);\n    ::close(mAshmemFd);\n}\n\nstatus_t CursorWindow::create(const String8& name, size_t size, CursorWindow** outCursorWindow) {\n    String8 ashmemName(\"CursorWindow: \");\n    ashmemName.append(name);\n\n    status_t result;\n    int ashmemFd = ashmem_create_region(ashmemName.string(), size);\n    if (ashmemFd < 0) {\n        result = -errno;\n    } else {\n        result = ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);\n        if (result >= 0) {\n            void* data = ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);\n            if (data == MAP_FAILED) {\n                result = -errno;\n            } else {\n                result = ashmem_set_prot_region(ashmemFd, PROT_READ);\n                if (result >= 0) {\n                    CursorWindow* window = new CursorWindow(name, ashmemFd,\n                            data, size, false /*readOnly*/);\n                    result = window->clear();\n                    if (!result) {\n                        LOG_WINDOW(\"Created new CursorWindow: freeOffset=%d, \"\n                                \"numRows=%d, numColumns=%d, mSize=%d, mData=%p\",\n                                window->mHeader->freeOffset,\n                                window->mHeader->numRows,\n                                window->mHeader->numColumns,\n                                window->mSize, window->mData);\n                        *outCursorWindow = window;\n                        return OK;\n                    }\n                    delete window;\n                }\n            }\n            ::munmap(data, size);\n        }\n        ::close(ashmemFd);\n    }\n    *outCursorWindow = NULL;\n    return result;\n}\n\nstatus_t CursorWindow::createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow) {\n    String8 name = parcel->readString8();\n\n    status_t result;\n    int ashmemFd = parcel->readFileDescriptor();\n    if (ashmemFd == int(BAD_TYPE)) {\n        result = BAD_TYPE;\n    } else {\n        ssize_t size = ashmem_get_size_region(ashmemFd);\n        if (size < 0) {\n            result = UNKNOWN_ERROR;\n        } else {\n            int dupAshmemFd = ::dup(ashmemFd);\n            if (dupAshmemFd < 0) {\n                result = -errno;\n            } else {\n                void* data = ::mmap(NULL, size, PROT_READ, MAP_SHARED, dupAshmemFd, 0);\n                if (data == MAP_FAILED) {\n                    result = -errno;\n                } else {\n                    CursorWindow* window = new CursorWindow(name, dupAshmemFd,\n                            data, size, true /*readOnly*/);\n                    LOG_WINDOW(\"Created CursorWindow from parcel: freeOffset=%d, \"\n                            \"numRows=%d, numColumns=%d, mSize=%d, mData=%p\",\n                            window->mHeader->freeOffset,\n                            window->mHeader->numRows,\n                            window->mHeader->numColumns,\n                            window->mSize, window->mData);\n                    *outCursorWindow = window;\n                    return OK;\n                }\n                ::close(dupAshmemFd);\n            }\n        }\n    }\n    *outCursorWindow = NULL;\n    return result;\n}\n\nstatus_t CursorWindow::writeToParcel(Parcel* parcel) {\n    status_t status = parcel->writeString8(mName);\n    if (!status) {\n        status = parcel->writeDupFileDescriptor(mAshmemFd);\n    }\n    return status;\n}\n\nstatus_t CursorWindow::clear() {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    mHeader->freeOffset = sizeof(Header) + sizeof(RowSlotChunk);\n    mHeader->firstChunkOffset = sizeof(Header);\n    mHeader->numRows = 0;\n    mHeader->numColumns = 0;\n\n    RowSlotChunk* firstChunk = static_cast<RowSlotChunk*>(offsetToPtr(mHeader->firstChunkOffset));\n    firstChunk->nextChunkOffset = 0;\n    return OK;\n}\n\nstatus_t CursorWindow::setNumColumns(uint32_t numColumns) {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    uint32_t cur = mHeader->numColumns;\n    if ((cur > 0 || mHeader->numRows > 0) && cur != numColumns) {\n        ALOGE(\"Trying to go from %d columns to %d\", cur, numColumns);\n        return INVALID_OPERATION;\n    }\n    mHeader->numColumns = numColumns;\n    return OK;\n}\n\nstatus_t CursorWindow::allocRow() {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    // Fill in the row slot\n    RowSlot* rowSlot = allocRowSlot();\n    if (rowSlot == NULL) {\n        return NO_MEMORY;\n    }\n\n    // Allocate the slots for the field directory\n    size_t fieldDirSize = mHeader->numColumns * sizeof(FieldSlot);\n    uint32_t fieldDirOffset = alloc(fieldDirSize, true /*aligned*/);\n    if (!fieldDirOffset) {\n        mHeader->numRows--;\n        LOG_WINDOW(\"The row failed, so back out the new row accounting \"\n                \"from allocRowSlot %d\", mHeader->numRows);\n        return NO_MEMORY;\n    }\n    FieldSlot* fieldDir = static_cast<FieldSlot*>(offsetToPtr(fieldDirOffset));\n    memset(fieldDir, 0, fieldDirSize);\n\n    LOG_WINDOW(\"Allocated row %u, rowSlot is at offset %u, fieldDir is %d bytes at offset %u\\n\",\n            mHeader->numRows - 1, offsetFromPtr(rowSlot), fieldDirSize, fieldDirOffset);\n    rowSlot->offset = fieldDirOffset;\n    return OK;\n}\n\nstatus_t CursorWindow::freeLastRow() {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    if (mHeader->numRows > 0) {\n        mHeader->numRows--;\n    }\n    return OK;\n}\n\nuint32_t CursorWindow::alloc(size_t size, bool aligned) {\n    uint32_t padding;\n    if (aligned) {\n        // 4 byte alignment\n        padding = (~mHeader->freeOffset + 1) & 3;\n    } else {\n        padding = 0;\n    }\n\n    uint32_t offset = mHeader->freeOffset + padding;\n    uint32_t nextFreeOffset = offset + size;\n    if (nextFreeOffset > mSize) {\n        ALOGW(\"Window is full: requested allocation %zu bytes, \"\n                \"free space %zu bytes, window size %zu bytes\",\n                size, freeSpace(), mSize);\n        return 0;\n    }\n\n    mHeader->freeOffset = nextFreeOffset;\n    return offset;\n}\n\nCursorWindow::RowSlot* CursorWindow::getRowSlot(uint32_t row) {\n    uint32_t chunkPos = row;\n    RowSlotChunk* chunk = static_cast<RowSlotChunk*>(\n            offsetToPtr(mHeader->firstChunkOffset));\n    while (chunkPos >= ROW_SLOT_CHUNK_NUM_ROWS) {\n        chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));\n        chunkPos -= ROW_SLOT_CHUNK_NUM_ROWS;\n    }\n    return &chunk->slots[chunkPos];\n}\n\nCursorWindow::RowSlot* CursorWindow::allocRowSlot() {\n    uint32_t chunkPos = mHeader->numRows;\n    RowSlotChunk* chunk = static_cast<RowSlotChunk*>(\n            offsetToPtr(mHeader->firstChunkOffset));\n    while (chunkPos > ROW_SLOT_CHUNK_NUM_ROWS) {\n        chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));\n        chunkPos -= ROW_SLOT_CHUNK_NUM_ROWS;\n    }\n    if (chunkPos == ROW_SLOT_CHUNK_NUM_ROWS) {\n        if (!chunk->nextChunkOffset) {\n            chunk->nextChunkOffset = alloc(sizeof(RowSlotChunk), true /*aligned*/);\n            if (!chunk->nextChunkOffset) {\n                return NULL;\n            }\n        }\n        chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));\n        chunk->nextChunkOffset = 0;\n        chunkPos = 0;\n    }\n    mHeader->numRows += 1;\n    return &chunk->slots[chunkPos];\n}\n\nCursorWindow::FieldSlot* CursorWindow::getFieldSlot(uint32_t row, uint32_t column) {\n    if (row >= mHeader->numRows || column >= mHeader->numColumns) {\n        ALOGE(\"Failed to read row %d, column %d from a CursorWindow which \"\n                \"has %d rows, %d columns.\",\n                row, column, mHeader->numRows, mHeader->numColumns);\n        return NULL;\n    }\n    RowSlot* rowSlot = getRowSlot(row);\n    if (!rowSlot) {\n        ALOGE(\"Failed to find rowSlot for row %d.\", row);\n        return NULL;\n    }\n    FieldSlot* fieldDir = static_cast<FieldSlot*>(offsetToPtr(rowSlot->offset));\n    return &fieldDir[column];\n}\n\nstatus_t CursorWindow::putBlob(uint32_t row, uint32_t column, const void* value, size_t size) {\n    return putBlobOrString(row, column, value, size, FIELD_TYPE_BLOB);\n}\n\nstatus_t CursorWindow::putString(uint32_t row, uint32_t column, const char* value,\n        size_t sizeIncludingNull) {\n    return putBlobOrString(row, column, value, sizeIncludingNull, FIELD_TYPE_STRING);\n}\n\nstatus_t CursorWindow::putBlobOrString(uint32_t row, uint32_t column,\n        const void* value, size_t size, int32_t type) {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    FieldSlot* fieldSlot = getFieldSlot(row, column);\n    if (!fieldSlot) {\n        return BAD_VALUE;\n    }\n\n    uint32_t offset = alloc(size);\n    if (!offset) {\n        return NO_MEMORY;\n    }\n\n    memcpy(offsetToPtr(offset), value, size);\n\n    fieldSlot->type = type;\n    fieldSlot->data.buffer.offset = offset;\n    fieldSlot->data.buffer.size = size;\n    return OK;\n}\n\nstatus_t CursorWindow::putLong(uint32_t row, uint32_t column, int64_t value) {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    FieldSlot* fieldSlot = getFieldSlot(row, column);\n    if (!fieldSlot) {\n        return BAD_VALUE;\n    }\n\n    fieldSlot->type = FIELD_TYPE_INTEGER;\n    fieldSlot->data.l = value;\n    return OK;\n}\n\nstatus_t CursorWindow::putDouble(uint32_t row, uint32_t column, double value) {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    FieldSlot* fieldSlot = getFieldSlot(row, column);\n    if (!fieldSlot) {\n        return BAD_VALUE;\n    }\n\n    fieldSlot->type = FIELD_TYPE_FLOAT;\n    fieldSlot->data.d = value;\n    return OK;\n}\n\nstatus_t CursorWindow::putNull(uint32_t row, uint32_t column) {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    FieldSlot* fieldSlot = getFieldSlot(row, column);\n    if (!fieldSlot) {\n        return BAD_VALUE;\n    }\n\n    fieldSlot->type = FIELD_TYPE_NULL;\n    fieldSlot->data.buffer.offset = 0;\n    fieldSlot->data.buffer.size = 0;\n    return OK;\n}\n\n}; // namespace android\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/DisplayEventDispatcher.cpp",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"DisplayEventDispatcher\"\n\n#include <cinttypes>\n#include <cstdint>\n\n#include <androidfw/DisplayEventDispatcher.h>\n#include <gui/DisplayEventReceiver.h>\n#include <utils/Log.h>\n#include <utils/Looper.h>\n\n#include <utils/Timers.h>\n\nnamespace android {\n\n// Number of events to read at a time from the DisplayEventDispatcher pipe.\n// The value should be large enough that we can quickly drain the pipe\n// using just a few large reads.\nstatic const size_t EVENT_BUFFER_SIZE = 100;\n\nDisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper) :\n        mLooper(looper), mWaitingForVsync(false) {\n    ALOGV(\"dispatcher %p ~ Initializing display event dispatcher.\", this);\n}\n\nstatus_t DisplayEventDispatcher::initialize() {\n    status_t result = mReceiver.initCheck();\n    if (result) {\n        ALOGW(\"Failed to initialize display event receiver, status=%d\", result);\n        return result;\n    }\n\n    int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT,\n            this, NULL);\n    if (rc < 0) {\n        return UNKNOWN_ERROR;\n    }\n    return OK;\n}\n\nvoid DisplayEventDispatcher::dispose() {\n    ALOGV(\"dispatcher %p ~ Disposing display event dispatcher.\", this);\n\n    if (!mReceiver.initCheck()) {\n        mLooper->removeFd(mReceiver.getFd());\n    }\n}\n\nstatus_t DisplayEventDispatcher::scheduleVsync() {\n    if (!mWaitingForVsync) {\n        ALOGV(\"dispatcher %p ~ Scheduling vsync.\", this);\n\n        // Drain all pending events.\n        nsecs_t vsyncTimestamp;\n        int32_t vsyncDisplayId;\n        uint32_t vsyncCount;\n        if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {\n            ALOGE(\"dispatcher %p ~ last event processed while scheduling was for %\" PRId64 \"\",\n                    this, ns2ms(static_cast<nsecs_t>(vsyncTimestamp)));\n        }\n\n        status_t status = mReceiver.requestNextVsync();\n        if (status) {\n            ALOGW(\"Failed to request next vsync, status=%d\", status);\n            return status;\n        }\n\n        mWaitingForVsync = true;\n    }\n    return OK;\n}\n\nint DisplayEventDispatcher::handleEvent(int, int events, void*) {\n    if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {\n        ALOGE(\"Display event receiver pipe was closed or an error occurred.  \"\n                \"events=0x%x\", events);\n        return 0; // remove the callback\n    }\n\n    if (!(events & Looper::EVENT_INPUT)) {\n        ALOGW(\"Received spurious callback for unhandled poll event.  \"\n                \"events=0x%x\", events);\n        return 1; // keep the callback\n    }\n\n    // Drain all pending events, keep the last vsync.\n    nsecs_t vsyncTimestamp;\n    int32_t vsyncDisplayId;\n    uint32_t vsyncCount;\n    if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {\n        ALOGV(\"dispatcher %p ~ Vsync pulse: timestamp=%\" PRId64 \", id=%d, count=%d\",\n                this, ns2ms(vsyncTimestamp), vsyncDisplayId, vsyncCount);\n        mWaitingForVsync = false;\n        dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);\n    }\n\n    return 1; // keep the callback\n}\n\nbool DisplayEventDispatcher::processPendingEvents(\n        nsecs_t* outTimestamp, int32_t* outId, uint32_t* outCount) {\n    bool gotVsync = false;\n    DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];\n    ssize_t n;\n    while ((n = mReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {\n        ALOGV(\"dispatcher %p ~ Read %d events.\", this, int(n));\n        for (ssize_t i = 0; i < n; i++) {\n            const DisplayEventReceiver::Event& ev = buf[i];\n            switch (ev.header.type) {\n            case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:\n                // Later vsync events will just overwrite the info from earlier\n                // ones. That's fine, we only care about the most recent.\n                gotVsync = true;\n                *outTimestamp = ev.header.timestamp;\n                *outId = ev.header.id;\n                *outCount = ev.vsync.count;\n                break;\n            case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:\n                dispatchHotplug(ev.header.timestamp, ev.header.id, ev.hotplug.connected);\n                break;\n            default:\n                ALOGW(\"dispatcher %p ~ ignoring unknown event type %#x\", this, ev.header.type);\n                break;\n            }\n        }\n    }\n    if (n < 0) {\n        ALOGW(\"Failed to get events from display event dispatcher, status=%d\", status_t(n));\n    }\n    return gotVsync;\n}\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/LocaleData.cpp",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <cstdint>\n#include <cstdlib>\n#include <cstring>\n#include <string>\n#include <unordered_map>\n#include <unordered_set>\n\n#include <androidfw/LocaleData.h>\n\nnamespace android {\n\n#include \"LocaleDataTables.cpp\"\n\ninline uint32_t packLocale(const char* language, const char* region) {\n    return (((uint8_t) language[0]) << 24u) | (((uint8_t) language[1]) << 16u) |\n           (((uint8_t) region[0]) << 8u) | ((uint8_t) region[1]);\n}\n\ninline uint32_t dropRegion(uint32_t packed_locale) {\n    return packed_locale & 0xFFFF0000lu;\n}\n\ninline bool hasRegion(uint32_t packed_locale) {\n    return (packed_locale & 0x0000FFFFlu) != 0;\n}\n\nconst size_t SCRIPT_LENGTH = 4;\nconst size_t SCRIPT_PARENTS_COUNT = sizeof(SCRIPT_PARENTS)/sizeof(SCRIPT_PARENTS[0]);\nconst uint32_t PACKED_ROOT = 0; // to represent the root locale\n\nuint32_t findParent(uint32_t packed_locale, const char* script) {\n    if (hasRegion(packed_locale)) {\n        for (size_t i = 0; i < SCRIPT_PARENTS_COUNT; i++) {\n            if (memcmp(script, SCRIPT_PARENTS[i].script, SCRIPT_LENGTH) == 0) {\n                auto map = SCRIPT_PARENTS[i].map;\n                auto lookup_result = map->find(packed_locale);\n                if (lookup_result != map->end()) {\n                    return lookup_result->second;\n                }\n                break;\n            }\n        }\n        return dropRegion(packed_locale);\n    }\n    return PACKED_ROOT;\n}\n\n// Find the ancestors of a locale, and fill 'out' with it (assumes out has enough\n// space). If any of the members of stop_list was seen, write it in the\n// output but stop afterwards.\n//\n// This also outputs the index of the last written ancestor in the stop_list\n// to stop_list_index, which will be -1 if it is not found in the stop_list.\n//\n// Returns the number of ancestors written in the output, which is always\n// at least one.\n//\n// (If 'out' is nullptr, we do everything the same way but we simply don't write\n// any results in 'out'.)\nsize_t findAncestors(uint32_t* out, ssize_t* stop_list_index,\n                     uint32_t packed_locale, const char* script,\n                     const uint32_t* stop_list, size_t stop_set_length) {\n    uint32_t ancestor = packed_locale;\n    size_t count = 0;\n    do {\n        if (out != nullptr) out[count] = ancestor;\n        count++;\n        for (size_t i = 0; i < stop_set_length; i++) {\n            if (stop_list[i] == ancestor) {\n                *stop_list_index = (ssize_t) i;\n                return count;\n            }\n        }\n        ancestor = findParent(ancestor, script);\n    } while (ancestor != PACKED_ROOT);\n    *stop_list_index = (ssize_t) -1;\n    return count;\n}\n\nsize_t findDistance(uint32_t supported,\n                    const char* script,\n                    const uint32_t* request_ancestors,\n                    size_t request_ancestors_count) {\n    ssize_t request_ancestors_index;\n    const size_t supported_ancestor_count = findAncestors(\n            nullptr, &request_ancestors_index,\n            supported, script,\n            request_ancestors, request_ancestors_count);\n    // Since both locales share the same root, there will always be a shared\n    // ancestor, so the distance in the parent tree is the sum of the distance\n    // of 'supported' to the lowest common ancestor (number of ancestors\n    // written for 'supported' minus 1) plus the distance of 'request' to the\n    // lowest common ancestor (the index of the ancestor in request_ancestors).\n    return supported_ancestor_count + request_ancestors_index - 1;\n}\n\ninline bool isRepresentative(uint32_t language_and_region, const char* script) {\n    const uint64_t packed_locale = (\n            (((uint64_t) language_and_region) << 32u) |\n            (((uint64_t) script[0]) << 24u) |\n            (((uint64_t) script[1]) << 16u) |\n            (((uint64_t) script[2]) <<  8u) |\n            ((uint64_t) script[3]));\n\n    return (REPRESENTATIVE_LOCALES.count(packed_locale) != 0);\n}\n\nint localeDataCompareRegions(\n        const char* left_region, const char* right_region,\n        const char* requested_language, const char* requested_script,\n        const char* requested_region) {\n\n    if (left_region[0] == right_region[0] && left_region[1] == right_region[1]) {\n        return 0;\n    }\n    const uint32_t left = packLocale(requested_language, left_region);\n    const uint32_t right = packLocale(requested_language, right_region);\n    const uint32_t request = packLocale(requested_language, requested_region);\n\n    uint32_t request_ancestors[MAX_PARENT_DEPTH+1];\n    ssize_t left_right_index;\n    // Find the parents of the request, but stop as soon as we saw left or right\n    const uint32_t left_and_right[] = {left, right};\n    const size_t ancestor_count = findAncestors(\n            request_ancestors, &left_right_index,\n            request, requested_script,\n            left_and_right, sizeof(left_and_right)/sizeof(left_and_right[0]));\n    if (left_right_index == 0) { // We saw left earlier\n        return 1;\n    }\n    if (left_right_index == 1) { // We saw right earlier\n        return -1;\n    }\n\n    // If we are here, neither left nor right are an ancestor of the\n    // request. This means that all the ancestors have been computed and\n    // the last ancestor is just the language by itself. We will use the\n    // distance in the parent tree for determining the better match.\n    const size_t left_distance = findDistance(\n            left, requested_script, request_ancestors, ancestor_count);\n    const size_t right_distance = findDistance(\n            right, requested_script, request_ancestors, ancestor_count);\n    if (left_distance != right_distance) {\n        return (int) right_distance - (int) left_distance; // smaller distance is better\n    }\n\n    // If we are here, left and right are equidistant from the request. We will\n    // try and see if any of them is a representative locale.\n    const bool left_is_representative = isRepresentative(left, requested_script);\n    const bool right_is_representative = isRepresentative(right, requested_script);\n    if (left_is_representative != right_is_representative) {\n        return (int) left_is_representative - (int) right_is_representative;\n    }\n\n    // We have no way of figuring out which locale is a better match. For\n    // the sake of stability, we consider the locale with the lower region\n    // code (in dictionary order) better, with two-letter codes before\n    // three-digit codes (since two-letter codes are more specific).\n    return (int64_t) right - (int64_t) left;\n}\n\nvoid localeDataComputeScript(char out[4], const char* language, const char* region) {\n    if (language[0] == '\\0') {\n        memset(out, '\\0', SCRIPT_LENGTH);\n        return;\n    }\n    uint32_t lookup_key = packLocale(language, region);\n    auto lookup_result = LIKELY_SCRIPTS.find(lookup_key);\n    if (lookup_result == LIKELY_SCRIPTS.end()) {\n        // We couldn't find the locale. Let's try without the region\n        if (region[0] != '\\0') {\n            lookup_key = dropRegion(lookup_key);\n            lookup_result = LIKELY_SCRIPTS.find(lookup_key);\n            if (lookup_result != LIKELY_SCRIPTS.end()) {\n                memcpy(out, SCRIPT_CODES[lookup_result->second], SCRIPT_LENGTH);\n                return;\n            }\n        }\n        // We don't know anything about the locale\n        memset(out, '\\0', SCRIPT_LENGTH);\n        return;\n    } else {\n        // We found the locale.\n        memcpy(out, SCRIPT_CODES[lookup_result->second], SCRIPT_LENGTH);\n    }\n}\n\nconst uint32_t ENGLISH_STOP_LIST[2] = {\n    0x656E0000lu, // en\n    0x656E8400lu, // en-001\n};\nconst char ENGLISH_CHARS[2] = {'e', 'n'};\nconst char LATIN_CHARS[4] = {'L', 'a', 't', 'n'};\n\nbool localeDataIsCloseToUsEnglish(const char* region) {\n    const uint32_t locale = packLocale(ENGLISH_CHARS, region);\n    ssize_t stop_list_index;\n    findAncestors(nullptr, &stop_list_index, locale, LATIN_CHARS, ENGLISH_STOP_LIST, 2);\n    // A locale is like US English if we see \"en\" before \"en-001\" in its ancestor list.\n    return stop_list_index == 0; // 'en' is first in ENGLISH_STOP_LIST\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/LocaleDataTables.cpp",
    "content": "// Auto-generated by frameworks/base/tools/localedata/extract_icu_data.py\n\nconst char SCRIPT_CODES[][4] = {\n    /* 0  */ {'A', 'h', 'o', 'm'},\n    /* 1  */ {'A', 'r', 'a', 'b'},\n    /* 2  */ {'A', 'r', 'm', 'i'},\n    /* 3  */ {'A', 'r', 'm', 'n'},\n    /* 4  */ {'A', 'v', 's', 't'},\n    /* 5  */ {'B', 'a', 'm', 'u'},\n    /* 6  */ {'B', 'a', 's', 's'},\n    /* 7  */ {'B', 'e', 'n', 'g'},\n    /* 8  */ {'B', 'r', 'a', 'h'},\n    /* 9  */ {'C', 'a', 'n', 's'},\n    /* 10 */ {'C', 'a', 'r', 'i'},\n    /* 11 */ {'C', 'h', 'a', 'm'},\n    /* 12 */ {'C', 'h', 'e', 'r'},\n    /* 13 */ {'C', 'o', 'p', 't'},\n    /* 14 */ {'C', 'p', 'r', 't'},\n    /* 15 */ {'C', 'y', 'r', 'l'},\n    /* 16 */ {'D', 'e', 'v', 'a'},\n    /* 17 */ {'E', 'g', 'y', 'p'},\n    /* 18 */ {'E', 't', 'h', 'i'},\n    /* 19 */ {'G', 'e', 'o', 'r'},\n    /* 20 */ {'G', 'o', 't', 'h'},\n    /* 21 */ {'G', 'r', 'e', 'k'},\n    /* 22 */ {'G', 'u', 'j', 'r'},\n    /* 23 */ {'G', 'u', 'r', 'u'},\n    /* 24 */ {'H', 'a', 'n', 's'},\n    /* 25 */ {'H', 'a', 'n', 't'},\n    /* 26 */ {'H', 'a', 't', 'r'},\n    /* 27 */ {'H', 'e', 'b', 'r'},\n    /* 28 */ {'H', 'l', 'u', 'w'},\n    /* 29 */ {'H', 'm', 'n', 'g'},\n    /* 30 */ {'I', 't', 'a', 'l'},\n    /* 31 */ {'J', 'p', 'a', 'n'},\n    /* 32 */ {'K', 'a', 'l', 'i'},\n    /* 33 */ {'K', 'a', 'n', 'a'},\n    /* 34 */ {'K', 'h', 'a', 'r'},\n    /* 35 */ {'K', 'h', 'm', 'r'},\n    /* 36 */ {'K', 'n', 'd', 'a'},\n    /* 37 */ {'K', 'o', 'r', 'e'},\n    /* 38 */ {'K', 't', 'h', 'i'},\n    /* 39 */ {'L', 'a', 'n', 'a'},\n    /* 40 */ {'L', 'a', 'o', 'o'},\n    /* 41 */ {'L', 'a', 't', 'n'},\n    /* 42 */ {'L', 'e', 'p', 'c'},\n    /* 43 */ {'L', 'i', 'n', 'a'},\n    /* 44 */ {'L', 'i', 's', 'u'},\n    /* 45 */ {'L', 'y', 'c', 'i'},\n    /* 46 */ {'L', 'y', 'd', 'i'},\n    /* 47 */ {'M', 'a', 'n', 'd'},\n    /* 48 */ {'M', 'a', 'n', 'i'},\n    /* 49 */ {'M', 'e', 'r', 'c'},\n    /* 50 */ {'M', 'l', 'y', 'm'},\n    /* 51 */ {'M', 'o', 'n', 'g'},\n    /* 52 */ {'M', 'r', 'o', 'o'},\n    /* 53 */ {'M', 'y', 'm', 'r'},\n    /* 54 */ {'N', 'a', 'r', 'b'},\n    /* 55 */ {'N', 'k', 'o', 'o'},\n    /* 56 */ {'O', 'g', 'a', 'm'},\n    /* 57 */ {'O', 'r', 'k', 'h'},\n    /* 58 */ {'O', 'r', 'y', 'a'},\n    /* 59 */ {'P', 'a', 'u', 'c'},\n    /* 60 */ {'P', 'h', 'l', 'i'},\n    /* 61 */ {'P', 'h', 'n', 'x'},\n    /* 62 */ {'P', 'l', 'r', 'd'},\n    /* 63 */ {'P', 'r', 't', 'i'},\n    /* 64 */ {'R', 'u', 'n', 'r'},\n    /* 65 */ {'S', 'a', 'm', 'r'},\n    /* 66 */ {'S', 'a', 'r', 'b'},\n    /* 67 */ {'S', 'a', 'u', 'r'},\n    /* 68 */ {'S', 'g', 'n', 'w'},\n    /* 69 */ {'S', 'i', 'n', 'h'},\n    /* 70 */ {'S', 'o', 'r', 'a'},\n    /* 71 */ {'S', 'y', 'r', 'c'},\n    /* 72 */ {'T', 'a', 'l', 'e'},\n    /* 73 */ {'T', 'a', 'l', 'u'},\n    /* 74 */ {'T', 'a', 'm', 'l'},\n    /* 75 */ {'T', 'a', 'v', 't'},\n    /* 76 */ {'T', 'e', 'l', 'u'},\n    /* 77 */ {'T', 'f', 'n', 'g'},\n    /* 78 */ {'T', 'h', 'a', 'a'},\n    /* 79 */ {'T', 'h', 'a', 'i'},\n    /* 80 */ {'T', 'i', 'b', 't'},\n    /* 81 */ {'U', 'g', 'a', 'r'},\n    /* 82 */ {'V', 'a', 'i', 'i'},\n    /* 83 */ {'X', 'p', 'e', 'o'},\n    /* 84 */ {'X', 's', 'u', 'x'},\n    /* 85 */ {'Y', 'i', 'i', 'i'},\n    /* 86 */ {'~', '~', '~', 'A'},\n    /* 87 */ {'~', '~', '~', 'B'},\n};\n\n\nconst std::unordered_map<uint32_t, uint8_t> LIKELY_SCRIPTS({\n    {0x61610000u, 41u}, // aa -> Latn\n    {0x61620000u, 15u}, // ab -> Cyrl\n    {0xC4200000u, 41u}, // abr -> Latn\n    {0x90400000u, 41u}, // ace -> Latn\n    {0x9C400000u, 41u}, // ach -> Latn\n    {0x80600000u, 41u}, // ada -> Latn\n    {0xE0600000u, 15u}, // ady -> Cyrl\n    {0x61650000u,  4u}, // ae -> Avst\n    {0x84800000u,  1u}, // aeb -> Arab\n    {0x61660000u, 41u}, // af -> Latn\n    {0xC0C00000u, 41u}, // agq -> Latn\n    {0xB8E00000u,  0u}, // aho -> Ahom\n    {0x616B0000u, 41u}, // ak -> Latn\n    {0xA9400000u, 84u}, // akk -> Xsux\n    {0xB5600000u, 41u}, // aln -> Latn\n    {0xCD600000u, 15u}, // alt -> Cyrl\n    {0x616D0000u, 18u}, // am -> Ethi\n    {0xB9800000u, 41u}, // amo -> Latn\n    {0xE5C00000u, 41u}, // aoz -> Latn\n    {0x61720000u,  1u}, // ar -> Arab\n    {0x61725842u, 87u}, // ar-XB -> ~~~B\n    {0x8A200000u,  2u}, // arc -> Armi\n    {0xB6200000u, 41u}, // arn -> Latn\n    {0xBA200000u, 41u}, // aro -> Latn\n    {0xC2200000u,  1u}, // arq -> Arab\n    {0xE2200000u,  1u}, // ary -> Arab\n    {0xE6200000u,  1u}, // arz -> Arab\n    {0x61730000u,  7u}, // as -> Beng\n    {0x82400000u, 41u}, // asa -> Latn\n    {0x92400000u, 68u}, // ase -> Sgnw\n    {0xCE400000u, 41u}, // ast -> Latn\n    {0xA6600000u, 41u}, // atj -> Latn\n    {0x61760000u, 15u}, // av -> Cyrl\n    {0x82C00000u, 16u}, // awa -> Deva\n    {0x61790000u, 41u}, // ay -> Latn\n    {0x617A0000u, 41u}, // az -> Latn\n    {0x617A4951u,  1u}, // az-IQ -> Arab\n    {0x617A4952u,  1u}, // az-IR -> Arab\n    {0x617A5255u, 15u}, // az-RU -> Cyrl\n    {0x62610000u, 15u}, // ba -> Cyrl\n    {0xAC010000u,  1u}, // bal -> Arab\n    {0xB4010000u, 41u}, // ban -> Latn\n    {0xBC010000u, 16u}, // bap -> Deva\n    {0xC4010000u, 41u}, // bar -> Latn\n    {0xC8010000u, 41u}, // bas -> Latn\n    {0xDC010000u,  5u}, // bax -> Bamu\n    {0x88210000u, 41u}, // bbc -> Latn\n    {0xA4210000u, 41u}, // bbj -> Latn\n    {0xA0410000u, 41u}, // bci -> Latn\n    {0x62650000u, 15u}, // be -> Cyrl\n    {0xA4810000u,  1u}, // bej -> Arab\n    {0xB0810000u, 41u}, // bem -> Latn\n    {0xD8810000u, 41u}, // bew -> Latn\n    {0xE4810000u, 41u}, // bez -> Latn\n    {0x8CA10000u, 41u}, // bfd -> Latn\n    {0xC0A10000u, 74u}, // bfq -> Taml\n    {0xCCA10000u,  1u}, // bft -> Arab\n    {0xE0A10000u, 16u}, // bfy -> Deva\n    {0x62670000u, 15u}, // bg -> Cyrl\n    {0x88C10000u, 16u}, // bgc -> Deva\n    {0xB4C10000u,  1u}, // bgn -> Arab\n    {0xDCC10000u, 21u}, // bgx -> Grek\n    {0x62680000u, 38u}, // bh -> Kthi\n    {0x84E10000u, 16u}, // bhb -> Deva\n    {0xA0E10000u, 16u}, // bhi -> Deva\n    {0xA8E10000u, 41u}, // bhk -> Latn\n    {0xB8E10000u, 16u}, // bho -> Deva\n    {0x62690000u, 41u}, // bi -> Latn\n    {0xA9010000u, 41u}, // bik -> Latn\n    {0xB5010000u, 41u}, // bin -> Latn\n    {0xA5210000u, 16u}, // bjj -> Deva\n    {0xB5210000u, 41u}, // bjn -> Latn\n    {0xB1410000u, 41u}, // bkm -> Latn\n    {0xD1410000u, 41u}, // bku -> Latn\n    {0xCD610000u, 75u}, // blt -> Tavt\n    {0x626D0000u, 41u}, // bm -> Latn\n    {0xC1810000u, 41u}, // bmq -> Latn\n    {0x626E0000u,  7u}, // bn -> Beng\n    {0x626F0000u, 80u}, // bo -> Tibt\n    {0xE1E10000u,  7u}, // bpy -> Beng\n    {0xA2010000u,  1u}, // bqi -> Arab\n    {0xD6010000u, 41u}, // bqv -> Latn\n    {0x62720000u, 41u}, // br -> Latn\n    {0x82210000u, 16u}, // bra -> Deva\n    {0x9E210000u,  1u}, // brh -> Arab\n    {0xDE210000u, 16u}, // brx -> Deva\n    {0x62730000u, 41u}, // bs -> Latn\n    {0xC2410000u,  6u}, // bsq -> Bass\n    {0xCA410000u, 41u}, // bss -> Latn\n    {0xBA610000u, 41u}, // bto -> Latn\n    {0xD6610000u, 16u}, // btv -> Deva\n    {0x82810000u, 15u}, // bua -> Cyrl\n    {0x8A810000u, 41u}, // buc -> Latn\n    {0x9A810000u, 41u}, // bug -> Latn\n    {0xB2810000u, 41u}, // bum -> Latn\n    {0x86A10000u, 41u}, // bvb -> Latn\n    {0xB7010000u, 18u}, // byn -> Ethi\n    {0xD7010000u, 41u}, // byv -> Latn\n    {0x93210000u, 41u}, // bze -> Latn\n    {0x63610000u, 41u}, // ca -> Latn\n    {0x9C420000u, 41u}, // cch -> Latn\n    {0xBC420000u,  7u}, // ccp -> Beng\n    {0x63650000u, 15u}, // ce -> Cyrl\n    {0x84820000u, 41u}, // ceb -> Latn\n    {0x98C20000u, 41u}, // cgg -> Latn\n    {0x63680000u, 41u}, // ch -> Latn\n    {0xA8E20000u, 41u}, // chk -> Latn\n    {0xB0E20000u, 15u}, // chm -> Cyrl\n    {0xB8E20000u, 41u}, // cho -> Latn\n    {0xBCE20000u, 41u}, // chp -> Latn\n    {0xC4E20000u, 12u}, // chr -> Cher\n    {0x81220000u,  1u}, // cja -> Arab\n    {0xB1220000u, 11u}, // cjm -> Cham\n    {0x85420000u,  1u}, // ckb -> Arab\n    {0x636F0000u, 41u}, // co -> Latn\n    {0xBDC20000u, 13u}, // cop -> Copt\n    {0xC9E20000u, 41u}, // cps -> Latn\n    {0x63720000u,  9u}, // cr -> Cans\n    {0xA6220000u,  9u}, // crj -> Cans\n    {0xAA220000u,  9u}, // crk -> Cans\n    {0xAE220000u,  9u}, // crl -> Cans\n    {0xB2220000u,  9u}, // crm -> Cans\n    {0xCA220000u, 41u}, // crs -> Latn\n    {0x63730000u, 41u}, // cs -> Latn\n    {0x86420000u, 41u}, // csb -> Latn\n    {0xDA420000u,  9u}, // csw -> Cans\n    {0x8E620000u, 59u}, // ctd -> Pauc\n    {0x63750000u, 15u}, // cu -> Cyrl\n    {0x63760000u, 15u}, // cv -> Cyrl\n    {0x63790000u, 41u}, // cy -> Latn\n    {0x64610000u, 41u}, // da -> Latn\n    {0xA8030000u, 41u}, // dak -> Latn\n    {0xC4030000u, 15u}, // dar -> Cyrl\n    {0xD4030000u, 41u}, // dav -> Latn\n    {0x88430000u,  1u}, // dcc -> Arab\n    {0x64650000u, 41u}, // de -> Latn\n    {0xB4830000u, 41u}, // den -> Latn\n    {0xC4C30000u, 41u}, // dgr -> Latn\n    {0x91230000u, 41u}, // dje -> Latn\n    {0xA5A30000u, 41u}, // dnj -> Latn\n    {0xA1C30000u,  1u}, // doi -> Arab\n    {0x86430000u, 41u}, // dsb -> Latn\n    {0xB2630000u, 41u}, // dtm -> Latn\n    {0xBE630000u, 41u}, // dtp -> Latn\n    {0x82830000u, 41u}, // dua -> Latn\n    {0x64760000u, 78u}, // dv -> Thaa\n    {0xBB030000u, 41u}, // dyo -> Latn\n    {0xD3030000u, 41u}, // dyu -> Latn\n    {0x647A0000u, 80u}, // dz -> Tibt\n    {0xD0240000u, 41u}, // ebu -> Latn\n    {0x65650000u, 41u}, // ee -> Latn\n    {0xA0A40000u, 41u}, // efi -> Latn\n    {0xACC40000u, 41u}, // egl -> Latn\n    {0xE0C40000u, 17u}, // egy -> Egyp\n    {0xE1440000u, 32u}, // eky -> Kali\n    {0x656C0000u, 21u}, // el -> Grek\n    {0x656E0000u, 41u}, // en -> Latn\n    {0x656E5841u, 86u}, // en-XA -> ~~~A\n    {0x656F0000u, 41u}, // eo -> Latn\n    {0x65730000u, 41u}, // es -> Latn\n    {0xD2440000u, 41u}, // esu -> Latn\n    {0x65740000u, 41u}, // et -> Latn\n    {0xCE640000u, 30u}, // ett -> Ital\n    {0x65750000u, 41u}, // eu -> Latn\n    {0xBAC40000u, 41u}, // ewo -> Latn\n    {0xCEE40000u, 41u}, // ext -> Latn\n    {0x66610000u,  1u}, // fa -> Arab\n    {0xB4050000u, 41u}, // fan -> Latn\n    {0x66660000u, 41u}, // ff -> Latn\n    {0xB0A50000u, 41u}, // ffm -> Latn\n    {0x66690000u, 41u}, // fi -> Latn\n    {0x81050000u,  1u}, // fia -> Arab\n    {0xAD050000u, 41u}, // fil -> Latn\n    {0xCD050000u, 41u}, // fit -> Latn\n    {0x666A0000u, 41u}, // fj -> Latn\n    {0x666F0000u, 41u}, // fo -> Latn\n    {0xB5C50000u, 41u}, // fon -> Latn\n    {0x66720000u, 41u}, // fr -> Latn\n    {0x8A250000u, 41u}, // frc -> Latn\n    {0xBE250000u, 41u}, // frp -> Latn\n    {0xC6250000u, 41u}, // frr -> Latn\n    {0xCA250000u, 41u}, // frs -> Latn\n    {0x8E850000u, 41u}, // fud -> Latn\n    {0xC2850000u, 41u}, // fuq -> Latn\n    {0xC6850000u, 41u}, // fur -> Latn\n    {0xD6850000u, 41u}, // fuv -> Latn\n    {0xC6A50000u, 41u}, // fvr -> Latn\n    {0x66790000u, 41u}, // fy -> Latn\n    {0x67610000u, 41u}, // ga -> Latn\n    {0x80060000u, 41u}, // gaa -> Latn\n    {0x98060000u, 41u}, // gag -> Latn\n    {0xB4060000u, 24u}, // gan -> Hans\n    {0xE0060000u, 41u}, // gay -> Latn\n    {0xB0260000u, 16u}, // gbm -> Deva\n    {0xE4260000u,  1u}, // gbz -> Arab\n    {0xC4460000u, 41u}, // gcr -> Latn\n    {0x67640000u, 41u}, // gd -> Latn\n    {0xE4860000u, 18u}, // gez -> Ethi\n    {0xB4C60000u, 16u}, // ggn -> Deva\n    {0xAD060000u, 41u}, // gil -> Latn\n    {0xA9260000u,  1u}, // gjk -> Arab\n    {0xD1260000u,  1u}, // gju -> Arab\n    {0x676C0000u, 41u}, // gl -> Latn\n    {0xA9660000u,  1u}, // glk -> Arab\n    {0x676E0000u, 41u}, // gn -> Latn\n    {0xB1C60000u, 16u}, // gom -> Deva\n    {0xB5C60000u, 76u}, // gon -> Telu\n    {0xC5C60000u, 41u}, // gor -> Latn\n    {0xC9C60000u, 41u}, // gos -> Latn\n    {0xCDC60000u, 20u}, // got -> Goth\n    {0x8A260000u, 14u}, // grc -> Cprt\n    {0xCE260000u,  7u}, // grt -> Beng\n    {0xDA460000u, 41u}, // gsw -> Latn\n    {0x67750000u, 22u}, // gu -> Gujr\n    {0x86860000u, 41u}, // gub -> Latn\n    {0x8A860000u, 41u}, // guc -> Latn\n    {0xC6860000u, 41u}, // gur -> Latn\n    {0xE6860000u, 41u}, // guz -> Latn\n    {0x67760000u, 41u}, // gv -> Latn\n    {0xC6A60000u, 16u}, // gvr -> Deva\n    {0xA2C60000u, 41u}, // gwi -> Latn\n    {0x68610000u, 41u}, // ha -> Latn\n    {0x6861434Du,  1u}, // ha-CM -> Arab\n    {0x68615344u,  1u}, // ha-SD -> Arab\n    {0xA8070000u, 24u}, // hak -> Hans\n    {0xD8070000u, 41u}, // haw -> Latn\n    {0xE4070000u,  1u}, // haz -> Arab\n    {0x68650000u, 27u}, // he -> Hebr\n    {0x68690000u, 16u}, // hi -> Deva\n    {0x95070000u, 41u}, // hif -> Latn\n    {0xAD070000u, 41u}, // hil -> Latn\n    {0xD1670000u, 28u}, // hlu -> Hluw\n    {0x8D870000u, 62u}, // hmd -> Plrd\n    {0x8DA70000u,  1u}, // hnd -> Arab\n    {0x91A70000u, 16u}, // hne -> Deva\n    {0xA5A70000u, 29u}, // hnj -> Hmng\n    {0xB5A70000u, 41u}, // hnn -> Latn\n    {0xB9A70000u,  1u}, // hno -> Arab\n    {0x686F0000u, 41u}, // ho -> Latn\n    {0x89C70000u, 16u}, // hoc -> Deva\n    {0xA5C70000u, 16u}, // hoj -> Deva\n    {0x68720000u, 41u}, // hr -> Latn\n    {0x86470000u, 41u}, // hsb -> Latn\n    {0xB6470000u, 24u}, // hsn -> Hans\n    {0x68740000u, 41u}, // ht -> Latn\n    {0x68750000u, 41u}, // hu -> Latn\n    {0x68790000u,  3u}, // hy -> Armn\n    {0x687A0000u, 41u}, // hz -> Latn\n    {0x69610000u, 41u}, // ia -> Latn\n    {0x80280000u, 41u}, // iba -> Latn\n    {0x84280000u, 41u}, // ibb -> Latn\n    {0x69640000u, 41u}, // id -> Latn\n    {0x69670000u, 41u}, // ig -> Latn\n    {0x69690000u, 85u}, // ii -> Yiii\n    {0x696B0000u, 41u}, // ik -> Latn\n    {0xCD480000u, 41u}, // ikt -> Latn\n    {0xB9680000u, 41u}, // ilo -> Latn\n    {0x696E0000u, 41u}, // in -> Latn\n    {0x9DA80000u, 15u}, // inh -> Cyrl\n    {0x69730000u, 41u}, // is -> Latn\n    {0x69740000u, 41u}, // it -> Latn\n    {0x69750000u,  9u}, // iu -> Cans\n    {0x69770000u, 27u}, // iw -> Hebr\n    {0x9F280000u, 41u}, // izh -> Latn\n    {0x6A610000u, 31u}, // ja -> Jpan\n    {0xB0090000u, 41u}, // jam -> Latn\n    {0xB8C90000u, 41u}, // jgo -> Latn\n    {0x6A690000u, 27u}, // ji -> Hebr\n    {0x89890000u, 41u}, // jmc -> Latn\n    {0xAD890000u, 16u}, // jml -> Deva\n    {0xCE890000u, 41u}, // jut -> Latn\n    {0x6A760000u, 41u}, // jv -> Latn\n    {0x6A770000u, 41u}, // jw -> Latn\n    {0x6B610000u, 19u}, // ka -> Geor\n    {0x800A0000u, 15u}, // kaa -> Cyrl\n    {0x840A0000u, 41u}, // kab -> Latn\n    {0x880A0000u, 41u}, // kac -> Latn\n    {0xA40A0000u, 41u}, // kaj -> Latn\n    {0xB00A0000u, 41u}, // kam -> Latn\n    {0xB80A0000u, 41u}, // kao -> Latn\n    {0x8C2A0000u, 15u}, // kbd -> Cyrl\n    {0x984A0000u, 41u}, // kcg -> Latn\n    {0xA84A0000u, 41u}, // kck -> Latn\n    {0x906A0000u, 41u}, // kde -> Latn\n    {0xCC6A0000u, 79u}, // kdt -> Thai\n    {0x808A0000u, 41u}, // kea -> Latn\n    {0xB48A0000u, 41u}, // ken -> Latn\n    {0xB8AA0000u, 41u}, // kfo -> Latn\n    {0xC4AA0000u, 16u}, // kfr -> Deva\n    {0xE0AA0000u, 16u}, // kfy -> Deva\n    {0x6B670000u, 41u}, // kg -> Latn\n    {0x90CA0000u, 41u}, // kge -> Latn\n    {0xBCCA0000u, 41u}, // kgp -> Latn\n    {0x80EA0000u, 41u}, // kha -> Latn\n    {0x84EA0000u, 73u}, // khb -> Talu\n    {0xB4EA0000u, 16u}, // khn -> Deva\n    {0xC0EA0000u, 41u}, // khq -> Latn\n    {0xCCEA0000u, 53u}, // kht -> Mymr\n    {0xD8EA0000u,  1u}, // khw -> Arab\n    {0x6B690000u, 41u}, // ki -> Latn\n    {0xD10A0000u, 41u}, // kiu -> Latn\n    {0x6B6A0000u, 41u}, // kj -> Latn\n    {0x992A0000u, 40u}, // kjg -> Laoo\n    {0x6B6B0000u, 15u}, // kk -> Cyrl\n    {0x6B6B4146u,  1u}, // kk-AF -> Arab\n    {0x6B6B434Eu,  1u}, // kk-CN -> Arab\n    {0x6B6B4952u,  1u}, // kk-IR -> Arab\n    {0x6B6B4D4Eu,  1u}, // kk-MN -> Arab\n    {0xA54A0000u, 41u}, // kkj -> Latn\n    {0x6B6C0000u, 41u}, // kl -> Latn\n    {0xB56A0000u, 41u}, // kln -> Latn\n    {0x6B6D0000u, 35u}, // km -> Khmr\n    {0x858A0000u, 41u}, // kmb -> Latn\n    {0x6B6E0000u, 36u}, // kn -> Knda\n    {0x6B6F0000u, 37u}, // ko -> Kore\n    {0xA1CA0000u, 15u}, // koi -> Cyrl\n    {0xA9CA0000u, 16u}, // kok -> Deva\n    {0xC9CA0000u, 41u}, // kos -> Latn\n    {0x91EA0000u, 41u}, // kpe -> Latn\n    {0x8A2A0000u, 15u}, // krc -> Cyrl\n    {0xA22A0000u, 41u}, // kri -> Latn\n    {0xA62A0000u, 41u}, // krj -> Latn\n    {0xAE2A0000u, 41u}, // krl -> Latn\n    {0xD22A0000u, 16u}, // kru -> Deva\n    {0x6B730000u,  1u}, // ks -> Arab\n    {0x864A0000u, 41u}, // ksb -> Latn\n    {0x964A0000u, 41u}, // ksf -> Latn\n    {0x9E4A0000u, 41u}, // ksh -> Latn\n    {0x6B750000u, 41u}, // ku -> Latn\n    {0x6B754952u,  1u}, // ku-IR -> Arab\n    {0x6B754C42u,  1u}, // ku-LB -> Arab\n    {0xB28A0000u, 15u}, // kum -> Cyrl\n    {0x6B760000u, 15u}, // kv -> Cyrl\n    {0xC6AA0000u, 41u}, // kvr -> Latn\n    {0xDEAA0000u,  1u}, // kvx -> Arab\n    {0x6B770000u, 41u}, // kw -> Latn\n    {0xB2EA0000u, 79u}, // kxm -> Thai\n    {0xBEEA0000u,  1u}, // kxp -> Arab\n    {0x6B790000u, 15u}, // ky -> Cyrl\n    {0x6B79434Eu,  1u}, // ky-CN -> Arab\n    {0x6B795452u, 41u}, // ky-TR -> Latn\n    {0x6C610000u, 41u}, // la -> Latn\n    {0x840B0000u, 43u}, // lab -> Lina\n    {0x8C0B0000u, 27u}, // lad -> Hebr\n    {0x980B0000u, 41u}, // lag -> Latn\n    {0x9C0B0000u,  1u}, // lah -> Arab\n    {0xA40B0000u, 41u}, // laj -> Latn\n    {0x6C620000u, 41u}, // lb -> Latn\n    {0x902B0000u, 15u}, // lbe -> Cyrl\n    {0xD82B0000u, 41u}, // lbw -> Latn\n    {0xBC4B0000u, 79u}, // lcp -> Thai\n    {0xBC8B0000u, 42u}, // lep -> Lepc\n    {0xE48B0000u, 15u}, // lez -> Cyrl\n    {0x6C670000u, 41u}, // lg -> Latn\n    {0x6C690000u, 41u}, // li -> Latn\n    {0x950B0000u, 16u}, // lif -> Deva\n    {0xA50B0000u, 41u}, // lij -> Latn\n    {0xC90B0000u, 44u}, // lis -> Lisu\n    {0xBD2B0000u, 41u}, // ljp -> Latn\n    {0xA14B0000u,  1u}, // lki -> Arab\n    {0xCD4B0000u, 41u}, // lkt -> Latn\n    {0xB58B0000u, 76u}, // lmn -> Telu\n    {0xB98B0000u, 41u}, // lmo -> Latn\n    {0x6C6E0000u, 41u}, // ln -> Latn\n    {0x6C6F0000u, 40u}, // lo -> Laoo\n    {0xADCB0000u, 41u}, // lol -> Latn\n    {0xE5CB0000u, 41u}, // loz -> Latn\n    {0x8A2B0000u,  1u}, // lrc -> Arab\n    {0x6C740000u, 41u}, // lt -> Latn\n    {0x9A6B0000u, 41u}, // ltg -> Latn\n    {0x6C750000u, 41u}, // lu -> Latn\n    {0x828B0000u, 41u}, // lua -> Latn\n    {0xBA8B0000u, 41u}, // luo -> Latn\n    {0xE28B0000u, 41u}, // luy -> Latn\n    {0xE68B0000u,  1u}, // luz -> Arab\n    {0x6C760000u, 41u}, // lv -> Latn\n    {0xAECB0000u, 79u}, // lwl -> Thai\n    {0x9F2B0000u, 24u}, // lzh -> Hans\n    {0xE72B0000u, 41u}, // lzz -> Latn\n    {0x8C0C0000u, 41u}, // mad -> Latn\n    {0x940C0000u, 41u}, // maf -> Latn\n    {0x980C0000u, 16u}, // mag -> Deva\n    {0xA00C0000u, 16u}, // mai -> Deva\n    {0xA80C0000u, 41u}, // mak -> Latn\n    {0xB40C0000u, 41u}, // man -> Latn\n    {0xB40C474Eu, 55u}, // man-GN -> Nkoo\n    {0xC80C0000u, 41u}, // mas -> Latn\n    {0xE40C0000u, 41u}, // maz -> Latn\n    {0x946C0000u, 15u}, // mdf -> Cyrl\n    {0x9C6C0000u, 41u}, // mdh -> Latn\n    {0xC46C0000u, 41u}, // mdr -> Latn\n    {0xB48C0000u, 41u}, // men -> Latn\n    {0xC48C0000u, 41u}, // mer -> Latn\n    {0x80AC0000u,  1u}, // mfa -> Arab\n    {0x90AC0000u, 41u}, // mfe -> Latn\n    {0x6D670000u, 41u}, // mg -> Latn\n    {0x9CCC0000u, 41u}, // mgh -> Latn\n    {0xB8CC0000u, 41u}, // mgo -> Latn\n    {0xBCCC0000u, 16u}, // mgp -> Deva\n    {0xE0CC0000u, 41u}, // mgy -> Latn\n    {0x6D680000u, 41u}, // mh -> Latn\n    {0x6D690000u, 41u}, // mi -> Latn\n    {0xB50C0000u, 41u}, // min -> Latn\n    {0xC90C0000u, 26u}, // mis -> Hatr\n    {0x6D6B0000u, 15u}, // mk -> Cyrl\n    {0x6D6C0000u, 50u}, // ml -> Mlym\n    {0xC96C0000u, 41u}, // mls -> Latn\n    {0x6D6E0000u, 15u}, // mn -> Cyrl\n    {0x6D6E434Eu, 51u}, // mn-CN -> Mong\n    {0xA1AC0000u,  7u}, // mni -> Beng\n    {0xD9AC0000u, 53u}, // mnw -> Mymr\n    {0x91CC0000u, 41u}, // moe -> Latn\n    {0x9DCC0000u, 41u}, // moh -> Latn\n    {0xC9CC0000u, 41u}, // mos -> Latn\n    {0x6D720000u, 16u}, // mr -> Deva\n    {0x8E2C0000u, 16u}, // mrd -> Deva\n    {0xA62C0000u, 15u}, // mrj -> Cyrl\n    {0xD22C0000u, 52u}, // mru -> Mroo\n    {0x6D730000u, 41u}, // ms -> Latn\n    {0x6D734343u,  1u}, // ms-CC -> Arab\n    {0x6D734944u,  1u}, // ms-ID -> Arab\n    {0x6D740000u, 41u}, // mt -> Latn\n    {0xC66C0000u, 16u}, // mtr -> Deva\n    {0x828C0000u, 41u}, // mua -> Latn\n    {0xCA8C0000u, 41u}, // mus -> Latn\n    {0xE2AC0000u,  1u}, // mvy -> Arab\n    {0xAACC0000u, 41u}, // mwk -> Latn\n    {0xC6CC0000u, 16u}, // mwr -> Deva\n    {0xD6CC0000u, 41u}, // mwv -> Latn\n    {0x8AEC0000u, 41u}, // mxc -> Latn\n    {0x6D790000u, 53u}, // my -> Mymr\n    {0xD70C0000u, 15u}, // myv -> Cyrl\n    {0xDF0C0000u, 41u}, // myx -> Latn\n    {0xE70C0000u, 47u}, // myz -> Mand\n    {0xB72C0000u,  1u}, // mzn -> Arab\n    {0x6E610000u, 41u}, // na -> Latn\n    {0xB40D0000u, 24u}, // nan -> Hans\n    {0xBC0D0000u, 41u}, // nap -> Latn\n    {0xC00D0000u, 41u}, // naq -> Latn\n    {0x6E620000u, 41u}, // nb -> Latn\n    {0x9C4D0000u, 41u}, // nch -> Latn\n    {0x6E640000u, 41u}, // nd -> Latn\n    {0x886D0000u, 41u}, // ndc -> Latn\n    {0xC86D0000u, 41u}, // nds -> Latn\n    {0x6E650000u, 16u}, // ne -> Deva\n    {0xD88D0000u, 16u}, // new -> Deva\n    {0x6E670000u, 41u}, // ng -> Latn\n    {0xACCD0000u, 41u}, // ngl -> Latn\n    {0x90ED0000u, 41u}, // nhe -> Latn\n    {0xD8ED0000u, 41u}, // nhw -> Latn\n    {0xA50D0000u, 41u}, // nij -> Latn\n    {0xD10D0000u, 41u}, // niu -> Latn\n    {0xB92D0000u, 41u}, // njo -> Latn\n    {0x6E6C0000u, 41u}, // nl -> Latn\n    {0x998D0000u, 41u}, // nmg -> Latn\n    {0x6E6E0000u, 41u}, // nn -> Latn\n    {0x9DAD0000u, 41u}, // nnh -> Latn\n    {0x6E6F0000u, 41u}, // no -> Latn\n    {0x8DCD0000u, 39u}, // nod -> Lana\n    {0x91CD0000u, 16u}, // noe -> Deva\n    {0xB5CD0000u, 64u}, // non -> Runr\n    {0xBA0D0000u, 55u}, // nqo -> Nkoo\n    {0x6E720000u, 41u}, // nr -> Latn\n    {0xAA4D0000u,  9u}, // nsk -> Cans\n    {0xBA4D0000u, 41u}, // nso -> Latn\n    {0xCA8D0000u, 41u}, // nus -> Latn\n    {0x6E760000u, 41u}, // nv -> Latn\n    {0xC2ED0000u, 41u}, // nxq -> Latn\n    {0x6E790000u, 41u}, // ny -> Latn\n    {0xB30D0000u, 41u}, // nym -> Latn\n    {0xB70D0000u, 41u}, // nyn -> Latn\n    {0xA32D0000u, 41u}, // nzi -> Latn\n    {0x6F630000u, 41u}, // oc -> Latn\n    {0x6F6D0000u, 41u}, // om -> Latn\n    {0x6F720000u, 58u}, // or -> Orya\n    {0x6F730000u, 15u}, // os -> Cyrl\n    {0xAA6E0000u, 57u}, // otk -> Orkh\n    {0x70610000u, 23u}, // pa -> Guru\n    {0x7061504Bu,  1u}, // pa-PK -> Arab\n    {0x980F0000u, 41u}, // pag -> Latn\n    {0xAC0F0000u, 60u}, // pal -> Phli\n    {0xB00F0000u, 41u}, // pam -> Latn\n    {0xBC0F0000u, 41u}, // pap -> Latn\n    {0xD00F0000u, 41u}, // pau -> Latn\n    {0x8C4F0000u, 41u}, // pcd -> Latn\n    {0xB04F0000u, 41u}, // pcm -> Latn\n    {0x886F0000u, 41u}, // pdc -> Latn\n    {0xCC6F0000u, 41u}, // pdt -> Latn\n    {0xB88F0000u, 83u}, // peo -> Xpeo\n    {0xACAF0000u, 41u}, // pfl -> Latn\n    {0xB4EF0000u, 61u}, // phn -> Phnx\n    {0x814F0000u,  8u}, // pka -> Brah\n    {0xB94F0000u, 41u}, // pko -> Latn\n    {0x706C0000u, 41u}, // pl -> Latn\n    {0xC98F0000u, 41u}, // pms -> Latn\n    {0xCDAF0000u, 21u}, // pnt -> Grek\n    {0xB5CF0000u, 41u}, // pon -> Latn\n    {0x822F0000u, 34u}, // pra -> Khar\n    {0x8E2F0000u,  1u}, // prd -> Arab\n    {0x9A2F0000u, 41u}, // prg -> Latn\n    {0x70730000u,  1u}, // ps -> Arab\n    {0x70740000u, 41u}, // pt -> Latn\n    {0xD28F0000u, 41u}, // puu -> Latn\n    {0x71750000u, 41u}, // qu -> Latn\n    {0x8A900000u, 41u}, // quc -> Latn\n    {0x9A900000u, 41u}, // qug -> Latn\n    {0xA4110000u, 16u}, // raj -> Deva\n    {0x94510000u, 41u}, // rcf -> Latn\n    {0xA4910000u, 41u}, // rej -> Latn\n    {0xB4D10000u, 41u}, // rgn -> Latn\n    {0x81110000u, 41u}, // ria -> Latn\n    {0x95110000u, 77u}, // rif -> Tfng\n    {0x95114E4Cu, 41u}, // rif-NL -> Latn\n    {0xC9310000u, 16u}, // rjs -> Deva\n    {0xCD510000u,  7u}, // rkt -> Beng\n    {0x726D0000u, 41u}, // rm -> Latn\n    {0x95910000u, 41u}, // rmf -> Latn\n    {0xB9910000u, 41u}, // rmo -> Latn\n    {0xCD910000u,  1u}, // rmt -> Arab\n    {0xD1910000u, 41u}, // rmu -> Latn\n    {0x726E0000u, 41u}, // rn -> Latn\n    {0x99B10000u, 41u}, // rng -> Latn\n    {0x726F0000u, 41u}, // ro -> Latn\n    {0x85D10000u, 41u}, // rob -> Latn\n    {0x95D10000u, 41u}, // rof -> Latn\n    {0xB2710000u, 41u}, // rtm -> Latn\n    {0x72750000u, 15u}, // ru -> Cyrl\n    {0x92910000u, 15u}, // rue -> Cyrl\n    {0x9A910000u, 41u}, // rug -> Latn\n    {0x72770000u, 41u}, // rw -> Latn\n    {0xAAD10000u, 41u}, // rwk -> Latn\n    {0xD3110000u, 33u}, // ryu -> Kana\n    {0x73610000u, 16u}, // sa -> Deva\n    {0x94120000u, 41u}, // saf -> Latn\n    {0x9C120000u, 15u}, // sah -> Cyrl\n    {0xC0120000u, 41u}, // saq -> Latn\n    {0xC8120000u, 41u}, // sas -> Latn\n    {0xCC120000u, 41u}, // sat -> Latn\n    {0xE4120000u, 67u}, // saz -> Saur\n    {0xBC320000u, 41u}, // sbp -> Latn\n    {0x73630000u, 41u}, // sc -> Latn\n    {0xA8520000u, 16u}, // sck -> Deva\n    {0xB4520000u, 41u}, // scn -> Latn\n    {0xB8520000u, 41u}, // sco -> Latn\n    {0xC8520000u, 41u}, // scs -> Latn\n    {0x73640000u,  1u}, // sd -> Arab\n    {0x88720000u, 41u}, // sdc -> Latn\n    {0x9C720000u,  1u}, // sdh -> Arab\n    {0x73650000u, 41u}, // se -> Latn\n    {0x94920000u, 41u}, // sef -> Latn\n    {0x9C920000u, 41u}, // seh -> Latn\n    {0xA0920000u, 41u}, // sei -> Latn\n    {0xC8920000u, 41u}, // ses -> Latn\n    {0x73670000u, 41u}, // sg -> Latn\n    {0x80D20000u, 56u}, // sga -> Ogam\n    {0xC8D20000u, 41u}, // sgs -> Latn\n    {0x73680000u, 41u}, // sh -> Latn\n    {0xA0F20000u, 77u}, // shi -> Tfng\n    {0xB4F20000u, 53u}, // shn -> Mymr\n    {0x73690000u, 69u}, // si -> Sinh\n    {0x8D120000u, 41u}, // sid -> Latn\n    {0x736B0000u, 41u}, // sk -> Latn\n    {0xC5520000u,  1u}, // skr -> Arab\n    {0x736C0000u, 41u}, // sl -> Latn\n    {0xA1720000u, 41u}, // sli -> Latn\n    {0xE1720000u, 41u}, // sly -> Latn\n    {0x736D0000u, 41u}, // sm -> Latn\n    {0x81920000u, 41u}, // sma -> Latn\n    {0xA5920000u, 41u}, // smj -> Latn\n    {0xB5920000u, 41u}, // smn -> Latn\n    {0xBD920000u, 65u}, // smp -> Samr\n    {0xC9920000u, 41u}, // sms -> Latn\n    {0x736E0000u, 41u}, // sn -> Latn\n    {0xA9B20000u, 41u}, // snk -> Latn\n    {0x736F0000u, 41u}, // so -> Latn\n    {0xD1D20000u, 79u}, // sou -> Thai\n    {0x73710000u, 41u}, // sq -> Latn\n    {0x73720000u, 15u}, // sr -> Cyrl\n    {0x73724D45u, 41u}, // sr-ME -> Latn\n    {0x7372524Fu, 41u}, // sr-RO -> Latn\n    {0x73725255u, 41u}, // sr-RU -> Latn\n    {0x73725452u, 41u}, // sr-TR -> Latn\n    {0x86320000u, 70u}, // srb -> Sora\n    {0xB6320000u, 41u}, // srn -> Latn\n    {0xC6320000u, 41u}, // srr -> Latn\n    {0xDE320000u, 16u}, // srx -> Deva\n    {0x73730000u, 41u}, // ss -> Latn\n    {0xE2520000u, 41u}, // ssy -> Latn\n    {0x73740000u, 41u}, // st -> Latn\n    {0xC2720000u, 41u}, // stq -> Latn\n    {0x73750000u, 41u}, // su -> Latn\n    {0xAA920000u, 41u}, // suk -> Latn\n    {0xCA920000u, 41u}, // sus -> Latn\n    {0x73760000u, 41u}, // sv -> Latn\n    {0x73770000u, 41u}, // sw -> Latn\n    {0x86D20000u,  1u}, // swb -> Arab\n    {0x8AD20000u, 41u}, // swc -> Latn\n    {0x9AD20000u, 41u}, // swg -> Latn\n    {0xD6D20000u, 16u}, // swv -> Deva\n    {0xB6F20000u, 41u}, // sxn -> Latn\n    {0xAF120000u,  7u}, // syl -> Beng\n    {0xC7120000u, 71u}, // syr -> Syrc\n    {0xAF320000u, 41u}, // szl -> Latn\n    {0x74610000u, 74u}, // ta -> Taml\n    {0xA4130000u, 16u}, // taj -> Deva\n    {0xD8330000u, 41u}, // tbw -> Latn\n    {0xE0530000u, 36u}, // tcy -> Knda\n    {0x8C730000u, 72u}, // tdd -> Tale\n    {0x98730000u, 16u}, // tdg -> Deva\n    {0x9C730000u, 16u}, // tdh -> Deva\n    {0x74650000u, 76u}, // te -> Telu\n    {0xB0930000u, 41u}, // tem -> Latn\n    {0xB8930000u, 41u}, // teo -> Latn\n    {0xCC930000u, 41u}, // tet -> Latn\n    {0x74670000u, 15u}, // tg -> Cyrl\n    {0x7467504Bu,  1u}, // tg-PK -> Arab\n    {0x74680000u, 79u}, // th -> Thai\n    {0xACF30000u, 16u}, // thl -> Deva\n    {0xC0F30000u, 16u}, // thq -> Deva\n    {0xC4F30000u, 16u}, // thr -> Deva\n    {0x74690000u, 18u}, // ti -> Ethi\n    {0x99130000u, 18u}, // tig -> Ethi\n    {0xD5130000u, 41u}, // tiv -> Latn\n    {0x746B0000u, 41u}, // tk -> Latn\n    {0xAD530000u, 41u}, // tkl -> Latn\n    {0xC5530000u, 41u}, // tkr -> Latn\n    {0xCD530000u, 16u}, // tkt -> Deva\n    {0x746C0000u, 41u}, // tl -> Latn\n    {0xE1730000u, 41u}, // tly -> Latn\n    {0x9D930000u, 41u}, // tmh -> Latn\n    {0x746E0000u, 41u}, // tn -> Latn\n    {0x746F0000u, 41u}, // to -> Latn\n    {0x99D30000u, 41u}, // tog -> Latn\n    {0xA1F30000u, 41u}, // tpi -> Latn\n    {0x74720000u, 41u}, // tr -> Latn\n    {0xD2330000u, 41u}, // tru -> Latn\n    {0xD6330000u, 41u}, // trv -> Latn\n    {0x74730000u, 41u}, // ts -> Latn\n    {0x8E530000u, 21u}, // tsd -> Grek\n    {0x96530000u, 16u}, // tsf -> Deva\n    {0x9A530000u, 41u}, // tsg -> Latn\n    {0xA6530000u, 80u}, // tsj -> Tibt\n    {0x74740000u, 15u}, // tt -> Cyrl\n    {0xA6730000u, 41u}, // ttj -> Latn\n    {0xCA730000u, 79u}, // tts -> Thai\n    {0xCE730000u, 41u}, // ttt -> Latn\n    {0xB2930000u, 41u}, // tum -> Latn\n    {0xAEB30000u, 41u}, // tvl -> Latn\n    {0xC2D30000u, 41u}, // twq -> Latn\n    {0x74790000u, 41u}, // ty -> Latn\n    {0xD7130000u, 15u}, // tyv -> Cyrl\n    {0xB3330000u, 41u}, // tzm -> Latn\n    {0xB0740000u, 15u}, // udm -> Cyrl\n    {0x75670000u,  1u}, // ug -> Arab\n    {0x75674B5Au, 15u}, // ug-KZ -> Cyrl\n    {0x75674D4Eu, 15u}, // ug-MN -> Cyrl\n    {0x80D40000u, 81u}, // uga -> Ugar\n    {0x756B0000u, 15u}, // uk -> Cyrl\n    {0xA1740000u, 41u}, // uli -> Latn\n    {0x85940000u, 41u}, // umb -> Latn\n    {0xC5B40000u,  7u}, // unr -> Beng\n    {0xC5B44E50u, 16u}, // unr-NP -> Deva\n    {0xDDB40000u,  7u}, // unx -> Beng\n    {0x75720000u,  1u}, // ur -> Arab\n    {0x757A0000u, 41u}, // uz -> Latn\n    {0x757A4146u,  1u}, // uz-AF -> Arab\n    {0x757A434Eu, 15u}, // uz-CN -> Cyrl\n    {0xA0150000u, 82u}, // vai -> Vaii\n    {0x76650000u, 41u}, // ve -> Latn\n    {0x88950000u, 41u}, // vec -> Latn\n    {0xBC950000u, 41u}, // vep -> Latn\n    {0x76690000u, 41u}, // vi -> Latn\n    {0x89150000u, 41u}, // vic -> Latn\n    {0xC9750000u, 41u}, // vls -> Latn\n    {0x95950000u, 41u}, // vmf -> Latn\n    {0xD9950000u, 41u}, // vmw -> Latn\n    {0x766F0000u, 41u}, // vo -> Latn\n    {0xCDD50000u, 41u}, // vot -> Latn\n    {0xBA350000u, 41u}, // vro -> Latn\n    {0xB6950000u, 41u}, // vun -> Latn\n    {0x77610000u, 41u}, // wa -> Latn\n    {0x90160000u, 41u}, // wae -> Latn\n    {0xAC160000u, 18u}, // wal -> Ethi\n    {0xC4160000u, 41u}, // war -> Latn\n    {0xBC360000u, 41u}, // wbp -> Latn\n    {0xC0360000u, 76u}, // wbq -> Telu\n    {0xC4360000u, 16u}, // wbr -> Deva\n    {0xC9760000u, 41u}, // wls -> Latn\n    {0xA1B60000u,  1u}, // wni -> Arab\n    {0x776F0000u, 41u}, // wo -> Latn\n    {0xB2760000u, 16u}, // wtm -> Deva\n    {0xD2960000u, 24u}, // wuu -> Hans\n    {0xD4170000u, 41u}, // xav -> Latn\n    {0xC4570000u, 10u}, // xcr -> Cari\n    {0x78680000u, 41u}, // xh -> Latn\n    {0x89770000u, 45u}, // xlc -> Lyci\n    {0x8D770000u, 46u}, // xld -> Lydi\n    {0x95970000u, 19u}, // xmf -> Geor\n    {0xB5970000u, 48u}, // xmn -> Mani\n    {0xC5970000u, 49u}, // xmr -> Merc\n    {0x81B70000u, 54u}, // xna -> Narb\n    {0xC5B70000u, 16u}, // xnr -> Deva\n    {0x99D70000u, 41u}, // xog -> Latn\n    {0xC5F70000u, 63u}, // xpr -> Prti\n    {0x82570000u, 66u}, // xsa -> Sarb\n    {0xC6570000u, 16u}, // xsr -> Deva\n    {0xB8180000u, 41u}, // yao -> Latn\n    {0xBC180000u, 41u}, // yap -> Latn\n    {0xD4180000u, 41u}, // yav -> Latn\n    {0x84380000u, 41u}, // ybb -> Latn\n    {0x79690000u, 27u}, // yi -> Hebr\n    {0x796F0000u, 41u}, // yo -> Latn\n    {0xAE380000u, 41u}, // yrl -> Latn\n    {0x82980000u, 41u}, // yua -> Latn\n    {0x7A610000u, 41u}, // za -> Latn\n    {0x98190000u, 41u}, // zag -> Latn\n    {0xA4790000u,  1u}, // zdj -> Arab\n    {0x80990000u, 41u}, // zea -> Latn\n    {0x9CD90000u, 77u}, // zgh -> Tfng\n    {0x7A680000u, 24u}, // zh -> Hans\n    {0x7A684155u, 25u}, // zh-AU -> Hant\n    {0x7A68424Eu, 25u}, // zh-BN -> Hant\n    {0x7A684742u, 25u}, // zh-GB -> Hant\n    {0x7A684746u, 25u}, // zh-GF -> Hant\n    {0x7A68484Bu, 25u}, // zh-HK -> Hant\n    {0x7A684944u, 25u}, // zh-ID -> Hant\n    {0x7A684D4Fu, 25u}, // zh-MO -> Hant\n    {0x7A684D59u, 25u}, // zh-MY -> Hant\n    {0x7A685041u, 25u}, // zh-PA -> Hant\n    {0x7A685046u, 25u}, // zh-PF -> Hant\n    {0x7A685048u, 25u}, // zh-PH -> Hant\n    {0x7A685352u, 25u}, // zh-SR -> Hant\n    {0x7A685448u, 25u}, // zh-TH -> Hant\n    {0x7A685457u, 25u}, // zh-TW -> Hant\n    {0x7A685553u, 25u}, // zh-US -> Hant\n    {0x7A68564Eu, 25u}, // zh-VN -> Hant\n    {0xA1990000u, 41u}, // zmi -> Latn\n    {0x7A750000u, 41u}, // zu -> Latn\n    {0x83390000u, 41u}, // zza -> Latn\n});\n\nstd::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({\n    0x616145544C61746Ellu, // aa_Latn_ET\n    0x616247454379726Cllu, // ab_Cyrl_GE\n    0xC42047484C61746Ellu, // abr_Latn_GH\n    0x904049444C61746Ellu, // ace_Latn_ID\n    0x9C4055474C61746Ellu, // ach_Latn_UG\n    0x806047484C61746Ellu, // ada_Latn_GH\n    0xE06052554379726Cllu, // ady_Cyrl_RU\n    0x6165495241767374llu, // ae_Avst_IR\n    0x8480544E41726162llu, // aeb_Arab_TN\n    0x61665A414C61746Ellu, // af_Latn_ZA\n    0xC0C0434D4C61746Ellu, // agq_Latn_CM\n    0xB8E0494E41686F6Dllu, // aho_Ahom_IN\n    0x616B47484C61746Ellu, // ak_Latn_GH\n    0xA940495158737578llu, // akk_Xsux_IQ\n    0xB560584B4C61746Ellu, // aln_Latn_XK\n    0xCD6052554379726Cllu, // alt_Cyrl_RU\n    0x616D455445746869llu, // am_Ethi_ET\n    0xB9804E474C61746Ellu, // amo_Latn_NG\n    0xE5C049444C61746Ellu, // aoz_Latn_ID\n    0x6172454741726162llu, // ar_Arab_EG\n    0x8A20495241726D69llu, // arc_Armi_IR\n    0x8A204A4F4E626174llu, // arc_Nbat_JO\n    0x8A20535950616C6Dllu, // arc_Palm_SY\n    0xB620434C4C61746Ellu, // arn_Latn_CL\n    0xBA20424F4C61746Ellu, // aro_Latn_BO\n    0xC220445A41726162llu, // arq_Arab_DZ\n    0xE2204D4141726162llu, // ary_Arab_MA\n    0xE620454741726162llu, // arz_Arab_EG\n    0x6173494E42656E67llu, // as_Beng_IN\n    0x8240545A4C61746Ellu, // asa_Latn_TZ\n    0x9240555353676E77llu, // ase_Sgnw_US\n    0xCE4045534C61746Ellu, // ast_Latn_ES\n    0xA66043414C61746Ellu, // atj_Latn_CA\n    0x617652554379726Cllu, // av_Cyrl_RU\n    0x82C0494E44657661llu, // awa_Deva_IN\n    0x6179424F4C61746Ellu, // ay_Latn_BO\n    0x617A495241726162llu, // az_Arab_IR\n    0x617A415A4C61746Ellu, // az_Latn_AZ\n    0x626152554379726Cllu, // ba_Cyrl_RU\n    0xAC01504B41726162llu, // bal_Arab_PK\n    0xB40149444C61746Ellu, // ban_Latn_ID\n    0xBC014E5044657661llu, // bap_Deva_NP\n    0xC40141544C61746Ellu, // bar_Latn_AT\n    0xC801434D4C61746Ellu, // bas_Latn_CM\n    0xDC01434D42616D75llu, // bax_Bamu_CM\n    0x882149444C61746Ellu, // bbc_Latn_ID\n    0xA421434D4C61746Ellu, // bbj_Latn_CM\n    0xA04143494C61746Ellu, // bci_Latn_CI\n    0x626542594379726Cllu, // be_Cyrl_BY\n    0xA481534441726162llu, // bej_Arab_SD\n    0xB0815A4D4C61746Ellu, // bem_Latn_ZM\n    0xD88149444C61746Ellu, // bew_Latn_ID\n    0xE481545A4C61746Ellu, // bez_Latn_TZ\n    0x8CA1434D4C61746Ellu, // bfd_Latn_CM\n    0xC0A1494E54616D6Cllu, // bfq_Taml_IN\n    0xCCA1504B41726162llu, // bft_Arab_PK\n    0xE0A1494E44657661llu, // bfy_Deva_IN\n    0x626742474379726Cllu, // bg_Cyrl_BG\n    0x88C1494E44657661llu, // bgc_Deva_IN\n    0xB4C1504B41726162llu, // bgn_Arab_PK\n    0xDCC154524772656Bllu, // bgx_Grek_TR\n    0x6268494E4B746869llu, // bh_Kthi_IN\n    0x84E1494E44657661llu, // bhb_Deva_IN\n    0xA0E1494E44657661llu, // bhi_Deva_IN\n    0xA8E150484C61746Ellu, // bhk_Latn_PH\n    0xB8E1494E44657661llu, // bho_Deva_IN\n    0x626956554C61746Ellu, // bi_Latn_VU\n    0xA90150484C61746Ellu, // bik_Latn_PH\n    0xB5014E474C61746Ellu, // bin_Latn_NG\n    0xA521494E44657661llu, // bjj_Deva_IN\n    0xB52149444C61746Ellu, // bjn_Latn_ID\n    0xB141434D4C61746Ellu, // bkm_Latn_CM\n    0xD14150484C61746Ellu, // bku_Latn_PH\n    0xCD61564E54617674llu, // blt_Tavt_VN\n    0x626D4D4C4C61746Ellu, // bm_Latn_ML\n    0xC1814D4C4C61746Ellu, // bmq_Latn_ML\n    0x626E424442656E67llu, // bn_Beng_BD\n    0x626F434E54696274llu, // bo_Tibt_CN\n    0xE1E1494E42656E67llu, // bpy_Beng_IN\n    0xA201495241726162llu, // bqi_Arab_IR\n    0xD60143494C61746Ellu, // bqv_Latn_CI\n    0x627246524C61746Ellu, // br_Latn_FR\n    0x8221494E44657661llu, // bra_Deva_IN\n    0x9E21504B41726162llu, // brh_Arab_PK\n    0xDE21494E44657661llu, // brx_Deva_IN\n    0x627342414C61746Ellu, // bs_Latn_BA\n    0xC2414C5242617373llu, // bsq_Bass_LR\n    0xCA41434D4C61746Ellu, // bss_Latn_CM\n    0xBA6150484C61746Ellu, // bto_Latn_PH\n    0xD661504B44657661llu, // btv_Deva_PK\n    0x828152554379726Cllu, // bua_Cyrl_RU\n    0x8A8159544C61746Ellu, // buc_Latn_YT\n    0x9A8149444C61746Ellu, // bug_Latn_ID\n    0xB281434D4C61746Ellu, // bum_Latn_CM\n    0x86A147514C61746Ellu, // bvb_Latn_GQ\n    0xB701455245746869llu, // byn_Ethi_ER\n    0xD701434D4C61746Ellu, // byv_Latn_CM\n    0x93214D4C4C61746Ellu, // bze_Latn_ML\n    0x636145534C61746Ellu, // ca_Latn_ES\n    0x9C424E474C61746Ellu, // cch_Latn_NG\n    0xBC42494E42656E67llu, // ccp_Beng_IN\n    0xBC42424443616B6Dllu, // ccp_Cakm_BD\n    0x636552554379726Cllu, // ce_Cyrl_RU\n    0x848250484C61746Ellu, // ceb_Latn_PH\n    0x98C255474C61746Ellu, // cgg_Latn_UG\n    0x636847554C61746Ellu, // ch_Latn_GU\n    0xA8E2464D4C61746Ellu, // chk_Latn_FM\n    0xB0E252554379726Cllu, // chm_Cyrl_RU\n    0xB8E255534C61746Ellu, // cho_Latn_US\n    0xBCE243414C61746Ellu, // chp_Latn_CA\n    0xC4E2555343686572llu, // chr_Cher_US\n    0x81224B4841726162llu, // cja_Arab_KH\n    0xB122564E4368616Dllu, // cjm_Cham_VN\n    0x8542495141726162llu, // ckb_Arab_IQ\n    0x636F46524C61746Ellu, // co_Latn_FR\n    0xBDC24547436F7074llu, // cop_Copt_EG\n    0xC9E250484C61746Ellu, // cps_Latn_PH\n    0x6372434143616E73llu, // cr_Cans_CA\n    0xA622434143616E73llu, // crj_Cans_CA\n    0xAA22434143616E73llu, // crk_Cans_CA\n    0xAE22434143616E73llu, // crl_Cans_CA\n    0xB222434143616E73llu, // crm_Cans_CA\n    0xCA2253434C61746Ellu, // crs_Latn_SC\n    0x6373435A4C61746Ellu, // cs_Latn_CZ\n    0x8642504C4C61746Ellu, // csb_Latn_PL\n    0xDA42434143616E73llu, // csw_Cans_CA\n    0x8E624D4D50617563llu, // ctd_Pauc_MM\n    0x637552554379726Cllu, // cu_Cyrl_RU\n    0x63754247476C6167llu, // cu_Glag_BG\n    0x637652554379726Cllu, // cv_Cyrl_RU\n    0x637947424C61746Ellu, // cy_Latn_GB\n    0x6461444B4C61746Ellu, // da_Latn_DK\n    0xA80355534C61746Ellu, // dak_Latn_US\n    0xC40352554379726Cllu, // dar_Cyrl_RU\n    0xD4034B454C61746Ellu, // dav_Latn_KE\n    0x8843494E41726162llu, // dcc_Arab_IN\n    0x646544454C61746Ellu, // de_Latn_DE\n    0xB48343414C61746Ellu, // den_Latn_CA\n    0xC4C343414C61746Ellu, // dgr_Latn_CA\n    0x91234E454C61746Ellu, // dje_Latn_NE\n    0xA5A343494C61746Ellu, // dnj_Latn_CI\n    0xA1C3494E41726162llu, // doi_Arab_IN\n    0x864344454C61746Ellu, // dsb_Latn_DE\n    0xB2634D4C4C61746Ellu, // dtm_Latn_ML\n    0xBE634D594C61746Ellu, // dtp_Latn_MY\n    0x8283434D4C61746Ellu, // dua_Latn_CM\n    0x64764D5654686161llu, // dv_Thaa_MV\n    0xBB03534E4C61746Ellu, // dyo_Latn_SN\n    0xD30342464C61746Ellu, // dyu_Latn_BF\n    0x647A425454696274llu, // dz_Tibt_BT\n    0xD0244B454C61746Ellu, // ebu_Latn_KE\n    0x656547484C61746Ellu, // ee_Latn_GH\n    0xA0A44E474C61746Ellu, // efi_Latn_NG\n    0xACC449544C61746Ellu, // egl_Latn_IT\n    0xE0C4454745677970llu, // egy_Egyp_EG\n    0xE1444D4D4B616C69llu, // eky_Kali_MM\n    0x656C47524772656Bllu, // el_Grek_GR\n    0x656E47424C61746Ellu, // en_Latn_GB\n    0x656E55534C61746Ellu, // en_Latn_US\n    0x656E474253686177llu, // en_Shaw_GB\n    0x657345534C61746Ellu, // es_Latn_ES\n    0x65734D584C61746Ellu, // es_Latn_MX\n    0x657355534C61746Ellu, // es_Latn_US\n    0xD24455534C61746Ellu, // esu_Latn_US\n    0x657445454C61746Ellu, // et_Latn_EE\n    0xCE6449544974616Cllu, // ett_Ital_IT\n    0x657545534C61746Ellu, // eu_Latn_ES\n    0xBAC4434D4C61746Ellu, // ewo_Latn_CM\n    0xCEE445534C61746Ellu, // ext_Latn_ES\n    0x6661495241726162llu, // fa_Arab_IR\n    0xB40547514C61746Ellu, // fan_Latn_GQ\n    0x6666534E4C61746Ellu, // ff_Latn_SN\n    0xB0A54D4C4C61746Ellu, // ffm_Latn_ML\n    0x666946494C61746Ellu, // fi_Latn_FI\n    0x8105534441726162llu, // fia_Arab_SD\n    0xAD0550484C61746Ellu, // fil_Latn_PH\n    0xCD0553454C61746Ellu, // fit_Latn_SE\n    0x666A464A4C61746Ellu, // fj_Latn_FJ\n    0x666F464F4C61746Ellu, // fo_Latn_FO\n    0xB5C5424A4C61746Ellu, // fon_Latn_BJ\n    0x667246524C61746Ellu, // fr_Latn_FR\n    0x8A2555534C61746Ellu, // frc_Latn_US\n    0xBE2546524C61746Ellu, // frp_Latn_FR\n    0xC62544454C61746Ellu, // frr_Latn_DE\n    0xCA2544454C61746Ellu, // frs_Latn_DE\n    0x8E8557464C61746Ellu, // fud_Latn_WF\n    0xC2854E454C61746Ellu, // fuq_Latn_NE\n    0xC68549544C61746Ellu, // fur_Latn_IT\n    0xD6854E474C61746Ellu, // fuv_Latn_NG\n    0xC6A553444C61746Ellu, // fvr_Latn_SD\n    0x66794E4C4C61746Ellu, // fy_Latn_NL\n    0x676149454C61746Ellu, // ga_Latn_IE\n    0x800647484C61746Ellu, // gaa_Latn_GH\n    0x98064D444C61746Ellu, // gag_Latn_MD\n    0xB406434E48616E73llu, // gan_Hans_CN\n    0xE00649444C61746Ellu, // gay_Latn_ID\n    0xB026494E44657661llu, // gbm_Deva_IN\n    0xE426495241726162llu, // gbz_Arab_IR\n    0xC44647464C61746Ellu, // gcr_Latn_GF\n    0x676447424C61746Ellu, // gd_Latn_GB\n    0xE486455445746869llu, // gez_Ethi_ET\n    0xB4C64E5044657661llu, // ggn_Deva_NP\n    0xAD064B494C61746Ellu, // gil_Latn_KI\n    0xA926504B41726162llu, // gjk_Arab_PK\n    0xD126504B41726162llu, // gju_Arab_PK\n    0x676C45534C61746Ellu, // gl_Latn_ES\n    0xA966495241726162llu, // glk_Arab_IR\n    0x676E50594C61746Ellu, // gn_Latn_PY\n    0xB1C6494E44657661llu, // gom_Deva_IN\n    0xB5C6494E54656C75llu, // gon_Telu_IN\n    0xC5C649444C61746Ellu, // gor_Latn_ID\n    0xC9C64E4C4C61746Ellu, // gos_Latn_NL\n    0xCDC65541476F7468llu, // got_Goth_UA\n    0x8A26435943707274llu, // grc_Cprt_CY\n    0x8A2647524C696E62llu, // grc_Linb_GR\n    0xCE26494E42656E67llu, // grt_Beng_IN\n    0xDA4643484C61746Ellu, // gsw_Latn_CH\n    0x6775494E47756A72llu, // gu_Gujr_IN\n    0x868642524C61746Ellu, // gub_Latn_BR\n    0x8A86434F4C61746Ellu, // guc_Latn_CO\n    0xC68647484C61746Ellu, // gur_Latn_GH\n    0xE6864B454C61746Ellu, // guz_Latn_KE\n    0x6776494D4C61746Ellu, // gv_Latn_IM\n    0xC6A64E5044657661llu, // gvr_Deva_NP\n    0xA2C643414C61746Ellu, // gwi_Latn_CA\n    0x68614E474C61746Ellu, // ha_Latn_NG\n    0xA807434E48616E73llu, // hak_Hans_CN\n    0xD80755534C61746Ellu, // haw_Latn_US\n    0xE407414641726162llu, // haz_Arab_AF\n    0x6865494C48656272llu, // he_Hebr_IL\n    0x6869494E44657661llu, // hi_Deva_IN\n    0x9507464A4C61746Ellu, // hif_Latn_FJ\n    0xAD0750484C61746Ellu, // hil_Latn_PH\n    0xD1675452486C7577llu, // hlu_Hluw_TR\n    0x8D87434E506C7264llu, // hmd_Plrd_CN\n    0x8DA7504B41726162llu, // hnd_Arab_PK\n    0x91A7494E44657661llu, // hne_Deva_IN\n    0xA5A74C41486D6E67llu, // hnj_Hmng_LA\n    0xB5A750484C61746Ellu, // hnn_Latn_PH\n    0xB9A7504B41726162llu, // hno_Arab_PK\n    0x686F50474C61746Ellu, // ho_Latn_PG\n    0x89C7494E44657661llu, // hoc_Deva_IN\n    0xA5C7494E44657661llu, // hoj_Deva_IN\n    0x687248524C61746Ellu, // hr_Latn_HR\n    0x864744454C61746Ellu, // hsb_Latn_DE\n    0xB647434E48616E73llu, // hsn_Hans_CN\n    0x687448544C61746Ellu, // ht_Latn_HT\n    0x687548554C61746Ellu, // hu_Latn_HU\n    0x6879414D41726D6Ellu, // hy_Armn_AM\n    0x687A4E414C61746Ellu, // hz_Latn_NA\n    0x696146524C61746Ellu, // ia_Latn_FR\n    0x80284D594C61746Ellu, // iba_Latn_MY\n    0x84284E474C61746Ellu, // ibb_Latn_NG\n    0x696449444C61746Ellu, // id_Latn_ID\n    0x69674E474C61746Ellu, // ig_Latn_NG\n    0x6969434E59696969llu, // ii_Yiii_CN\n    0x696B55534C61746Ellu, // ik_Latn_US\n    0xCD4843414C61746Ellu, // ikt_Latn_CA\n    0xB96850484C61746Ellu, // ilo_Latn_PH\n    0x696E49444C61746Ellu, // in_Latn_ID\n    0x9DA852554379726Cllu, // inh_Cyrl_RU\n    0x697349534C61746Ellu, // is_Latn_IS\n    0x697449544C61746Ellu, // it_Latn_IT\n    0x6975434143616E73llu, // iu_Cans_CA\n    0x6977494C48656272llu, // iw_Hebr_IL\n    0x9F2852554C61746Ellu, // izh_Latn_RU\n    0x6A614A504A70616Ellu, // ja_Jpan_JP\n    0xB0094A4D4C61746Ellu, // jam_Latn_JM\n    0xB8C9434D4C61746Ellu, // jgo_Latn_CM\n    0x6A69554148656272llu, // ji_Hebr_UA\n    0x8989545A4C61746Ellu, // jmc_Latn_TZ\n    0xAD894E5044657661llu, // jml_Deva_NP\n    0xCE89444B4C61746Ellu, // jut_Latn_DK\n    0x6A7649444C61746Ellu, // jv_Latn_ID\n    0x6A7749444C61746Ellu, // jw_Latn_ID\n    0x6B61474547656F72llu, // ka_Geor_GE\n    0x800A555A4379726Cllu, // kaa_Cyrl_UZ\n    0x840A445A4C61746Ellu, // kab_Latn_DZ\n    0x880A4D4D4C61746Ellu, // kac_Latn_MM\n    0xA40A4E474C61746Ellu, // kaj_Latn_NG\n    0xB00A4B454C61746Ellu, // kam_Latn_KE\n    0xB80A4D4C4C61746Ellu, // kao_Latn_ML\n    0x8C2A52554379726Cllu, // kbd_Cyrl_RU\n    0x984A4E474C61746Ellu, // kcg_Latn_NG\n    0xA84A5A574C61746Ellu, // kck_Latn_ZW\n    0x906A545A4C61746Ellu, // kde_Latn_TZ\n    0xCC6A544854686169llu, // kdt_Thai_TH\n    0x808A43564C61746Ellu, // kea_Latn_CV\n    0xB48A434D4C61746Ellu, // ken_Latn_CM\n    0xB8AA43494C61746Ellu, // kfo_Latn_CI\n    0xC4AA494E44657661llu, // kfr_Deva_IN\n    0xE0AA494E44657661llu, // kfy_Deva_IN\n    0x6B6743444C61746Ellu, // kg_Latn_CD\n    0x90CA49444C61746Ellu, // kge_Latn_ID\n    0xBCCA42524C61746Ellu, // kgp_Latn_BR\n    0x80EA494E4C61746Ellu, // kha_Latn_IN\n    0x84EA434E54616C75llu, // khb_Talu_CN\n    0xB4EA494E44657661llu, // khn_Deva_IN\n    0xC0EA4D4C4C61746Ellu, // khq_Latn_ML\n    0xCCEA494E4D796D72llu, // kht_Mymr_IN\n    0xD8EA504B41726162llu, // khw_Arab_PK\n    0x6B694B454C61746Ellu, // ki_Latn_KE\n    0xD10A54524C61746Ellu, // kiu_Latn_TR\n    0x6B6A4E414C61746Ellu, // kj_Latn_NA\n    0x992A4C414C616F6Fllu, // kjg_Laoo_LA\n    0x6B6B434E41726162llu, // kk_Arab_CN\n    0x6B6B4B5A4379726Cllu, // kk_Cyrl_KZ\n    0xA54A434D4C61746Ellu, // kkj_Latn_CM\n    0x6B6C474C4C61746Ellu, // kl_Latn_GL\n    0xB56A4B454C61746Ellu, // kln_Latn_KE\n    0x6B6D4B484B686D72llu, // km_Khmr_KH\n    0x858A414F4C61746Ellu, // kmb_Latn_AO\n    0x6B6E494E4B6E6461llu, // kn_Knda_IN\n    0x6B6F4B524B6F7265llu, // ko_Kore_KR\n    0xA1CA52554379726Cllu, // koi_Cyrl_RU\n    0xA9CA494E44657661llu, // kok_Deva_IN\n    0xC9CA464D4C61746Ellu, // kos_Latn_FM\n    0x91EA4C524C61746Ellu, // kpe_Latn_LR\n    0x8A2A52554379726Cllu, // krc_Cyrl_RU\n    0xA22A534C4C61746Ellu, // kri_Latn_SL\n    0xA62A50484C61746Ellu, // krj_Latn_PH\n    0xAE2A52554C61746Ellu, // krl_Latn_RU\n    0xD22A494E44657661llu, // kru_Deva_IN\n    0x6B73494E41726162llu, // ks_Arab_IN\n    0x864A545A4C61746Ellu, // ksb_Latn_TZ\n    0x964A434D4C61746Ellu, // ksf_Latn_CM\n    0x9E4A44454C61746Ellu, // ksh_Latn_DE\n    0x6B75495141726162llu, // ku_Arab_IQ\n    0x6B7554524C61746Ellu, // ku_Latn_TR\n    0xB28A52554379726Cllu, // kum_Cyrl_RU\n    0x6B7652554379726Cllu, // kv_Cyrl_RU\n    0xC6AA49444C61746Ellu, // kvr_Latn_ID\n    0xDEAA504B41726162llu, // kvx_Arab_PK\n    0x6B7747424C61746Ellu, // kw_Latn_GB\n    0xB2EA544854686169llu, // kxm_Thai_TH\n    0xBEEA504B41726162llu, // kxp_Arab_PK\n    0x6B79434E41726162llu, // ky_Arab_CN\n    0x6B794B474379726Cllu, // ky_Cyrl_KG\n    0x6B7954524C61746Ellu, // ky_Latn_TR\n    0x6C6156414C61746Ellu, // la_Latn_VA\n    0x840B47524C696E61llu, // lab_Lina_GR\n    0x8C0B494C48656272llu, // lad_Hebr_IL\n    0x980B545A4C61746Ellu, // lag_Latn_TZ\n    0x9C0B504B41726162llu, // lah_Arab_PK\n    0xA40B55474C61746Ellu, // laj_Latn_UG\n    0x6C624C554C61746Ellu, // lb_Latn_LU\n    0x902B52554379726Cllu, // lbe_Cyrl_RU\n    0xD82B49444C61746Ellu, // lbw_Latn_ID\n    0xBC4B434E54686169llu, // lcp_Thai_CN\n    0xBC8B494E4C657063llu, // lep_Lepc_IN\n    0xE48B52554379726Cllu, // lez_Cyrl_RU\n    0x6C6755474C61746Ellu, // lg_Latn_UG\n    0x6C694E4C4C61746Ellu, // li_Latn_NL\n    0x950B4E5044657661llu, // lif_Deva_NP\n    0x950B494E4C696D62llu, // lif_Limb_IN\n    0xA50B49544C61746Ellu, // lij_Latn_IT\n    0xC90B434E4C697375llu, // lis_Lisu_CN\n    0xBD2B49444C61746Ellu, // ljp_Latn_ID\n    0xA14B495241726162llu, // lki_Arab_IR\n    0xCD4B55534C61746Ellu, // lkt_Latn_US\n    0xB58B494E54656C75llu, // lmn_Telu_IN\n    0xB98B49544C61746Ellu, // lmo_Latn_IT\n    0x6C6E43444C61746Ellu, // ln_Latn_CD\n    0x6C6F4C414C616F6Fllu, // lo_Laoo_LA\n    0xADCB43444C61746Ellu, // lol_Latn_CD\n    0xE5CB5A4D4C61746Ellu, // loz_Latn_ZM\n    0x8A2B495241726162llu, // lrc_Arab_IR\n    0x6C744C544C61746Ellu, // lt_Latn_LT\n    0x9A6B4C564C61746Ellu, // ltg_Latn_LV\n    0x6C7543444C61746Ellu, // lu_Latn_CD\n    0x828B43444C61746Ellu, // lua_Latn_CD\n    0xBA8B4B454C61746Ellu, // luo_Latn_KE\n    0xE28B4B454C61746Ellu, // luy_Latn_KE\n    0xE68B495241726162llu, // luz_Arab_IR\n    0x6C764C564C61746Ellu, // lv_Latn_LV\n    0xAECB544854686169llu, // lwl_Thai_TH\n    0x9F2B434E48616E73llu, // lzh_Hans_CN\n    0xE72B54524C61746Ellu, // lzz_Latn_TR\n    0x8C0C49444C61746Ellu, // mad_Latn_ID\n    0x940C434D4C61746Ellu, // maf_Latn_CM\n    0x980C494E44657661llu, // mag_Deva_IN\n    0xA00C494E44657661llu, // mai_Deva_IN\n    0xA80C49444C61746Ellu, // mak_Latn_ID\n    0xB40C474D4C61746Ellu, // man_Latn_GM\n    0xB40C474E4E6B6F6Fllu, // man_Nkoo_GN\n    0xC80C4B454C61746Ellu, // mas_Latn_KE\n    0xE40C4D584C61746Ellu, // maz_Latn_MX\n    0x946C52554379726Cllu, // mdf_Cyrl_RU\n    0x9C6C50484C61746Ellu, // mdh_Latn_PH\n    0xC46C49444C61746Ellu, // mdr_Latn_ID\n    0xB48C534C4C61746Ellu, // men_Latn_SL\n    0xC48C4B454C61746Ellu, // mer_Latn_KE\n    0x80AC544841726162llu, // mfa_Arab_TH\n    0x90AC4D554C61746Ellu, // mfe_Latn_MU\n    0x6D674D474C61746Ellu, // mg_Latn_MG\n    0x9CCC4D5A4C61746Ellu, // mgh_Latn_MZ\n    0xB8CC434D4C61746Ellu, // mgo_Latn_CM\n    0xBCCC4E5044657661llu, // mgp_Deva_NP\n    0xE0CC545A4C61746Ellu, // mgy_Latn_TZ\n    0x6D684D484C61746Ellu, // mh_Latn_MH\n    0x6D694E5A4C61746Ellu, // mi_Latn_NZ\n    0xB50C49444C61746Ellu, // min_Latn_ID\n    0xC90C495148617472llu, // mis_Hatr_IQ\n    0x6D6B4D4B4379726Cllu, // mk_Cyrl_MK\n    0x6D6C494E4D6C796Dllu, // ml_Mlym_IN\n    0xC96C53444C61746Ellu, // mls_Latn_SD\n    0x6D6E4D4E4379726Cllu, // mn_Cyrl_MN\n    0x6D6E434E4D6F6E67llu, // mn_Mong_CN\n    0xA1AC494E42656E67llu, // mni_Beng_IN\n    0xD9AC4D4D4D796D72llu, // mnw_Mymr_MM\n    0x91CC43414C61746Ellu, // moe_Latn_CA\n    0x9DCC43414C61746Ellu, // moh_Latn_CA\n    0xC9CC42464C61746Ellu, // mos_Latn_BF\n    0x6D72494E44657661llu, // mr_Deva_IN\n    0x8E2C4E5044657661llu, // mrd_Deva_NP\n    0xA62C52554379726Cllu, // mrj_Cyrl_RU\n    0xD22C42444D726F6Fllu, // mru_Mroo_BD\n    0x6D734D594C61746Ellu, // ms_Latn_MY\n    0x6D744D544C61746Ellu, // mt_Latn_MT\n    0xC66C494E44657661llu, // mtr_Deva_IN\n    0x828C434D4C61746Ellu, // mua_Latn_CM\n    0xCA8C55534C61746Ellu, // mus_Latn_US\n    0xE2AC504B41726162llu, // mvy_Arab_PK\n    0xAACC4D4C4C61746Ellu, // mwk_Latn_ML\n    0xC6CC494E44657661llu, // mwr_Deva_IN\n    0xD6CC49444C61746Ellu, // mwv_Latn_ID\n    0x8AEC5A574C61746Ellu, // mxc_Latn_ZW\n    0x6D794D4D4D796D72llu, // my_Mymr_MM\n    0xD70C52554379726Cllu, // myv_Cyrl_RU\n    0xDF0C55474C61746Ellu, // myx_Latn_UG\n    0xE70C49524D616E64llu, // myz_Mand_IR\n    0xB72C495241726162llu, // mzn_Arab_IR\n    0x6E614E524C61746Ellu, // na_Latn_NR\n    0xB40D434E48616E73llu, // nan_Hans_CN\n    0xBC0D49544C61746Ellu, // nap_Latn_IT\n    0xC00D4E414C61746Ellu, // naq_Latn_NA\n    0x6E624E4F4C61746Ellu, // nb_Latn_NO\n    0x9C4D4D584C61746Ellu, // nch_Latn_MX\n    0x6E645A574C61746Ellu, // nd_Latn_ZW\n    0x886D4D5A4C61746Ellu, // ndc_Latn_MZ\n    0xC86D44454C61746Ellu, // nds_Latn_DE\n    0x6E654E5044657661llu, // ne_Deva_NP\n    0xD88D4E5044657661llu, // new_Deva_NP\n    0x6E674E414C61746Ellu, // ng_Latn_NA\n    0xACCD4D5A4C61746Ellu, // ngl_Latn_MZ\n    0x90ED4D584C61746Ellu, // nhe_Latn_MX\n    0xD8ED4D584C61746Ellu, // nhw_Latn_MX\n    0xA50D49444C61746Ellu, // nij_Latn_ID\n    0xD10D4E554C61746Ellu, // niu_Latn_NU\n    0xB92D494E4C61746Ellu, // njo_Latn_IN\n    0x6E6C4E4C4C61746Ellu, // nl_Latn_NL\n    0x998D434D4C61746Ellu, // nmg_Latn_CM\n    0x6E6E4E4F4C61746Ellu, // nn_Latn_NO\n    0x9DAD434D4C61746Ellu, // nnh_Latn_CM\n    0x6E6F4E4F4C61746Ellu, // no_Latn_NO\n    0x8DCD54484C616E61llu, // nod_Lana_TH\n    0x91CD494E44657661llu, // noe_Deva_IN\n    0xB5CD534552756E72llu, // non_Runr_SE\n    0xBA0D474E4E6B6F6Fllu, // nqo_Nkoo_GN\n    0x6E725A414C61746Ellu, // nr_Latn_ZA\n    0xAA4D434143616E73llu, // nsk_Cans_CA\n    0xBA4D5A414C61746Ellu, // nso_Latn_ZA\n    0xCA8D53534C61746Ellu, // nus_Latn_SS\n    0x6E7655534C61746Ellu, // nv_Latn_US\n    0xC2ED434E4C61746Ellu, // nxq_Latn_CN\n    0x6E794D574C61746Ellu, // ny_Latn_MW\n    0xB30D545A4C61746Ellu, // nym_Latn_TZ\n    0xB70D55474C61746Ellu, // nyn_Latn_UG\n    0xA32D47484C61746Ellu, // nzi_Latn_GH\n    0x6F6346524C61746Ellu, // oc_Latn_FR\n    0x6F6D45544C61746Ellu, // om_Latn_ET\n    0x6F72494E4F727961llu, // or_Orya_IN\n    0x6F7347454379726Cllu, // os_Cyrl_GE\n    0xAA6E4D4E4F726B68llu, // otk_Orkh_MN\n    0x7061504B41726162llu, // pa_Arab_PK\n    0x7061494E47757275llu, // pa_Guru_IN\n    0x980F50484C61746Ellu, // pag_Latn_PH\n    0xAC0F495250686C69llu, // pal_Phli_IR\n    0xAC0F434E50686C70llu, // pal_Phlp_CN\n    0xB00F50484C61746Ellu, // pam_Latn_PH\n    0xBC0F41574C61746Ellu, // pap_Latn_AW\n    0xD00F50574C61746Ellu, // pau_Latn_PW\n    0x8C4F46524C61746Ellu, // pcd_Latn_FR\n    0xB04F4E474C61746Ellu, // pcm_Latn_NG\n    0x886F55534C61746Ellu, // pdc_Latn_US\n    0xCC6F43414C61746Ellu, // pdt_Latn_CA\n    0xB88F49525870656Fllu, // peo_Xpeo_IR\n    0xACAF44454C61746Ellu, // pfl_Latn_DE\n    0xB4EF4C4250686E78llu, // phn_Phnx_LB\n    0x814F494E42726168llu, // pka_Brah_IN\n    0xB94F4B454C61746Ellu, // pko_Latn_KE\n    0x706C504C4C61746Ellu, // pl_Latn_PL\n    0xC98F49544C61746Ellu, // pms_Latn_IT\n    0xCDAF47524772656Bllu, // pnt_Grek_GR\n    0xB5CF464D4C61746Ellu, // pon_Latn_FM\n    0x822F504B4B686172llu, // pra_Khar_PK\n    0x8E2F495241726162llu, // prd_Arab_IR\n    0x7073414641726162llu, // ps_Arab_AF\n    0x707442524C61746Ellu, // pt_Latn_BR\n    0xD28F47414C61746Ellu, // puu_Latn_GA\n    0x717550454C61746Ellu, // qu_Latn_PE\n    0x8A9047544C61746Ellu, // quc_Latn_GT\n    0x9A9045434C61746Ellu, // qug_Latn_EC\n    0xA411494E44657661llu, // raj_Deva_IN\n    0x945152454C61746Ellu, // rcf_Latn_RE\n    0xA49149444C61746Ellu, // rej_Latn_ID\n    0xB4D149544C61746Ellu, // rgn_Latn_IT\n    0x8111494E4C61746Ellu, // ria_Latn_IN\n    0x95114D4154666E67llu, // rif_Tfng_MA\n    0xC9314E5044657661llu, // rjs_Deva_NP\n    0xCD51424442656E67llu, // rkt_Beng_BD\n    0x726D43484C61746Ellu, // rm_Latn_CH\n    0x959146494C61746Ellu, // rmf_Latn_FI\n    0xB99143484C61746Ellu, // rmo_Latn_CH\n    0xCD91495241726162llu, // rmt_Arab_IR\n    0xD19153454C61746Ellu, // rmu_Latn_SE\n    0x726E42494C61746Ellu, // rn_Latn_BI\n    0x99B14D5A4C61746Ellu, // rng_Latn_MZ\n    0x726F524F4C61746Ellu, // ro_Latn_RO\n    0x85D149444C61746Ellu, // rob_Latn_ID\n    0x95D1545A4C61746Ellu, // rof_Latn_TZ\n    0xB271464A4C61746Ellu, // rtm_Latn_FJ\n    0x727552554379726Cllu, // ru_Cyrl_RU\n    0x929155414379726Cllu, // rue_Cyrl_UA\n    0x9A9153424C61746Ellu, // rug_Latn_SB\n    0x727752574C61746Ellu, // rw_Latn_RW\n    0xAAD1545A4C61746Ellu, // rwk_Latn_TZ\n    0xD3114A504B616E61llu, // ryu_Kana_JP\n    0x7361494E44657661llu, // sa_Deva_IN\n    0x941247484C61746Ellu, // saf_Latn_GH\n    0x9C1252554379726Cllu, // sah_Cyrl_RU\n    0xC0124B454C61746Ellu, // saq_Latn_KE\n    0xC81249444C61746Ellu, // sas_Latn_ID\n    0xCC12494E4C61746Ellu, // sat_Latn_IN\n    0xE412494E53617572llu, // saz_Saur_IN\n    0xBC32545A4C61746Ellu, // sbp_Latn_TZ\n    0x736349544C61746Ellu, // sc_Latn_IT\n    0xA852494E44657661llu, // sck_Deva_IN\n    0xB45249544C61746Ellu, // scn_Latn_IT\n    0xB85247424C61746Ellu, // sco_Latn_GB\n    0xC85243414C61746Ellu, // scs_Latn_CA\n    0x7364504B41726162llu, // sd_Arab_PK\n    0x7364494E44657661llu, // sd_Deva_IN\n    0x7364494E4B686F6Allu, // sd_Khoj_IN\n    0x7364494E53696E64llu, // sd_Sind_IN\n    0x887249544C61746Ellu, // sdc_Latn_IT\n    0x9C72495241726162llu, // sdh_Arab_IR\n    0x73654E4F4C61746Ellu, // se_Latn_NO\n    0x949243494C61746Ellu, // sef_Latn_CI\n    0x9C924D5A4C61746Ellu, // seh_Latn_MZ\n    0xA0924D584C61746Ellu, // sei_Latn_MX\n    0xC8924D4C4C61746Ellu, // ses_Latn_ML\n    0x736743464C61746Ellu, // sg_Latn_CF\n    0x80D249454F67616Dllu, // sga_Ogam_IE\n    0xC8D24C544C61746Ellu, // sgs_Latn_LT\n    0xA0F24D4154666E67llu, // shi_Tfng_MA\n    0xB4F24D4D4D796D72llu, // shn_Mymr_MM\n    0x73694C4B53696E68llu, // si_Sinh_LK\n    0x8D1245544C61746Ellu, // sid_Latn_ET\n    0x736B534B4C61746Ellu, // sk_Latn_SK\n    0xC552504B41726162llu, // skr_Arab_PK\n    0x736C53494C61746Ellu, // sl_Latn_SI\n    0xA172504C4C61746Ellu, // sli_Latn_PL\n    0xE17249444C61746Ellu, // sly_Latn_ID\n    0x736D57534C61746Ellu, // sm_Latn_WS\n    0x819253454C61746Ellu, // sma_Latn_SE\n    0xA59253454C61746Ellu, // smj_Latn_SE\n    0xB59246494C61746Ellu, // smn_Latn_FI\n    0xBD92494C53616D72llu, // smp_Samr_IL\n    0xC99246494C61746Ellu, // sms_Latn_FI\n    0x736E5A574C61746Ellu, // sn_Latn_ZW\n    0xA9B24D4C4C61746Ellu, // snk_Latn_ML\n    0x736F534F4C61746Ellu, // so_Latn_SO\n    0xD1D2544854686169llu, // sou_Thai_TH\n    0x7371414C4C61746Ellu, // sq_Latn_AL\n    0x737252534379726Cllu, // sr_Cyrl_RS\n    0x737252534C61746Ellu, // sr_Latn_RS\n    0x8632494E536F7261llu, // srb_Sora_IN\n    0xB63253524C61746Ellu, // srn_Latn_SR\n    0xC632534E4C61746Ellu, // srr_Latn_SN\n    0xDE32494E44657661llu, // srx_Deva_IN\n    0x73735A414C61746Ellu, // ss_Latn_ZA\n    0xE25245524C61746Ellu, // ssy_Latn_ER\n    0x73745A414C61746Ellu, // st_Latn_ZA\n    0xC27244454C61746Ellu, // stq_Latn_DE\n    0x737549444C61746Ellu, // su_Latn_ID\n    0xAA92545A4C61746Ellu, // suk_Latn_TZ\n    0xCA92474E4C61746Ellu, // sus_Latn_GN\n    0x737653454C61746Ellu, // sv_Latn_SE\n    0x7377545A4C61746Ellu, // sw_Latn_TZ\n    0x86D2595441726162llu, // swb_Arab_YT\n    0x8AD243444C61746Ellu, // swc_Latn_CD\n    0x9AD244454C61746Ellu, // swg_Latn_DE\n    0xD6D2494E44657661llu, // swv_Deva_IN\n    0xB6F249444C61746Ellu, // sxn_Latn_ID\n    0xAF12424442656E67llu, // syl_Beng_BD\n    0xC712495153797263llu, // syr_Syrc_IQ\n    0xAF32504C4C61746Ellu, // szl_Latn_PL\n    0x7461494E54616D6Cllu, // ta_Taml_IN\n    0xA4134E5044657661llu, // taj_Deva_NP\n    0xD83350484C61746Ellu, // tbw_Latn_PH\n    0xE053494E4B6E6461llu, // tcy_Knda_IN\n    0x8C73434E54616C65llu, // tdd_Tale_CN\n    0x98734E5044657661llu, // tdg_Deva_NP\n    0x9C734E5044657661llu, // tdh_Deva_NP\n    0x7465494E54656C75llu, // te_Telu_IN\n    0xB093534C4C61746Ellu, // tem_Latn_SL\n    0xB89355474C61746Ellu, // teo_Latn_UG\n    0xCC93544C4C61746Ellu, // tet_Latn_TL\n    0x7467504B41726162llu, // tg_Arab_PK\n    0x7467544A4379726Cllu, // tg_Cyrl_TJ\n    0x7468544854686169llu, // th_Thai_TH\n    0xACF34E5044657661llu, // thl_Deva_NP\n    0xC0F34E5044657661llu, // thq_Deva_NP\n    0xC4F34E5044657661llu, // thr_Deva_NP\n    0x7469455445746869llu, // ti_Ethi_ET\n    0x9913455245746869llu, // tig_Ethi_ER\n    0xD5134E474C61746Ellu, // tiv_Latn_NG\n    0x746B544D4C61746Ellu, // tk_Latn_TM\n    0xAD53544B4C61746Ellu, // tkl_Latn_TK\n    0xC553415A4C61746Ellu, // tkr_Latn_AZ\n    0xCD534E5044657661llu, // tkt_Deva_NP\n    0x746C50484C61746Ellu, // tl_Latn_PH\n    0xE173415A4C61746Ellu, // tly_Latn_AZ\n    0x9D934E454C61746Ellu, // tmh_Latn_NE\n    0x746E5A414C61746Ellu, // tn_Latn_ZA\n    0x746F544F4C61746Ellu, // to_Latn_TO\n    0x99D34D574C61746Ellu, // tog_Latn_MW\n    0xA1F350474C61746Ellu, // tpi_Latn_PG\n    0x747254524C61746Ellu, // tr_Latn_TR\n    0xD23354524C61746Ellu, // tru_Latn_TR\n    0xD63354574C61746Ellu, // trv_Latn_TW\n    0x74735A414C61746Ellu, // ts_Latn_ZA\n    0x8E5347524772656Bllu, // tsd_Grek_GR\n    0x96534E5044657661llu, // tsf_Deva_NP\n    0x9A5350484C61746Ellu, // tsg_Latn_PH\n    0xA653425454696274llu, // tsj_Tibt_BT\n    0x747452554379726Cllu, // tt_Cyrl_RU\n    0xA67355474C61746Ellu, // ttj_Latn_UG\n    0xCA73544854686169llu, // tts_Thai_TH\n    0xCE73415A4C61746Ellu, // ttt_Latn_AZ\n    0xB2934D574C61746Ellu, // tum_Latn_MW\n    0xAEB354564C61746Ellu, // tvl_Latn_TV\n    0xC2D34E454C61746Ellu, // twq_Latn_NE\n    0x747950464C61746Ellu, // ty_Latn_PF\n    0xD71352554379726Cllu, // tyv_Cyrl_RU\n    0xB3334D414C61746Ellu, // tzm_Latn_MA\n    0xB07452554379726Cllu, // udm_Cyrl_RU\n    0x7567434E41726162llu, // ug_Arab_CN\n    0x75674B5A4379726Cllu, // ug_Cyrl_KZ\n    0x80D4535955676172llu, // uga_Ugar_SY\n    0x756B55414379726Cllu, // uk_Cyrl_UA\n    0xA174464D4C61746Ellu, // uli_Latn_FM\n    0x8594414F4C61746Ellu, // umb_Latn_AO\n    0xC5B4494E42656E67llu, // unr_Beng_IN\n    0xC5B44E5044657661llu, // unr_Deva_NP\n    0xDDB4494E42656E67llu, // unx_Beng_IN\n    0x7572504B41726162llu, // ur_Arab_PK\n    0x757A414641726162llu, // uz_Arab_AF\n    0x757A555A4C61746Ellu, // uz_Latn_UZ\n    0xA0154C5256616969llu, // vai_Vaii_LR\n    0x76655A414C61746Ellu, // ve_Latn_ZA\n    0x889549544C61746Ellu, // vec_Latn_IT\n    0xBC9552554C61746Ellu, // vep_Latn_RU\n    0x7669564E4C61746Ellu, // vi_Latn_VN\n    0x891553584C61746Ellu, // vic_Latn_SX\n    0xC97542454C61746Ellu, // vls_Latn_BE\n    0x959544454C61746Ellu, // vmf_Latn_DE\n    0xD9954D5A4C61746Ellu, // vmw_Latn_MZ\n    0xCDD552554C61746Ellu, // vot_Latn_RU\n    0xBA3545454C61746Ellu, // vro_Latn_EE\n    0xB695545A4C61746Ellu, // vun_Latn_TZ\n    0x776142454C61746Ellu, // wa_Latn_BE\n    0x901643484C61746Ellu, // wae_Latn_CH\n    0xAC16455445746869llu, // wal_Ethi_ET\n    0xC41650484C61746Ellu, // war_Latn_PH\n    0xBC3641554C61746Ellu, // wbp_Latn_AU\n    0xC036494E54656C75llu, // wbq_Telu_IN\n    0xC436494E44657661llu, // wbr_Deva_IN\n    0xC97657464C61746Ellu, // wls_Latn_WF\n    0xA1B64B4D41726162llu, // wni_Arab_KM\n    0x776F534E4C61746Ellu, // wo_Latn_SN\n    0xB276494E44657661llu, // wtm_Deva_IN\n    0xD296434E48616E73llu, // wuu_Hans_CN\n    0xD41742524C61746Ellu, // xav_Latn_BR\n    0xC457545243617269llu, // xcr_Cari_TR\n    0x78685A414C61746Ellu, // xh_Latn_ZA\n    0x897754524C796369llu, // xlc_Lyci_TR\n    0x8D7754524C796469llu, // xld_Lydi_TR\n    0x9597474547656F72llu, // xmf_Geor_GE\n    0xB597434E4D616E69llu, // xmn_Mani_CN\n    0xC59753444D657263llu, // xmr_Merc_SD\n    0x81B753414E617262llu, // xna_Narb_SA\n    0xC5B7494E44657661llu, // xnr_Deva_IN\n    0x99D755474C61746Ellu, // xog_Latn_UG\n    0xC5F7495250727469llu, // xpr_Prti_IR\n    0x8257594553617262llu, // xsa_Sarb_YE\n    0xC6574E5044657661llu, // xsr_Deva_NP\n    0xB8184D5A4C61746Ellu, // yao_Latn_MZ\n    0xBC18464D4C61746Ellu, // yap_Latn_FM\n    0xD418434D4C61746Ellu, // yav_Latn_CM\n    0x8438434D4C61746Ellu, // ybb_Latn_CM\n    0x796F4E474C61746Ellu, // yo_Latn_NG\n    0xAE3842524C61746Ellu, // yrl_Latn_BR\n    0x82984D584C61746Ellu, // yua_Latn_MX\n    0x7A61434E4C61746Ellu, // za_Latn_CN\n    0x981953444C61746Ellu, // zag_Latn_SD\n    0xA4794B4D41726162llu, // zdj_Arab_KM\n    0x80994E4C4C61746Ellu, // zea_Latn_NL\n    0x9CD94D4154666E67llu, // zgh_Tfng_MA\n    0x7A685457426F706Fllu, // zh_Bopo_TW\n    0x7A68434E48616E73llu, // zh_Hans_CN\n    0x7A68545748616E74llu, // zh_Hant_TW\n    0xA1994D594C61746Ellu, // zmi_Latn_MY\n    0x7A755A414C61746Ellu, // zu_Latn_ZA\n    0x833954524C61746Ellu, // zza_Latn_TR\n});\n\nconst std::unordered_map<uint32_t, uint32_t> ARAB_PARENTS({\n    {0x6172445Au, 0x61729420u}, // ar-DZ -> ar-015\n    {0x61724548u, 0x61729420u}, // ar-EH -> ar-015\n    {0x61724C59u, 0x61729420u}, // ar-LY -> ar-015\n    {0x61724D41u, 0x61729420u}, // ar-MA -> ar-015\n    {0x6172544Eu, 0x61729420u}, // ar-TN -> ar-015\n});\n\nconst std::unordered_map<uint32_t, uint32_t> HANT_PARENTS({\n    {0x7A684D4Fu, 0x7A68484Bu}, // zh-Hant-MO -> zh-Hant-HK\n});\n\nconst std::unordered_map<uint32_t, uint32_t> LATN_PARENTS({\n    {0x656E80A1u, 0x656E8400u}, // en-150 -> en-001\n    {0x656E4147u, 0x656E8400u}, // en-AG -> en-001\n    {0x656E4149u, 0x656E8400u}, // en-AI -> en-001\n    {0x656E4154u, 0x656E80A1u}, // en-AT -> en-150\n    {0x656E4155u, 0x656E8400u}, // en-AU -> en-001\n    {0x656E4242u, 0x656E8400u}, // en-BB -> en-001\n    {0x656E4245u, 0x656E8400u}, // en-BE -> en-001\n    {0x656E424Du, 0x656E8400u}, // en-BM -> en-001\n    {0x656E4253u, 0x656E8400u}, // en-BS -> en-001\n    {0x656E4257u, 0x656E8400u}, // en-BW -> en-001\n    {0x656E425Au, 0x656E8400u}, // en-BZ -> en-001\n    {0x656E4341u, 0x656E8400u}, // en-CA -> en-001\n    {0x656E4343u, 0x656E8400u}, // en-CC -> en-001\n    {0x656E4348u, 0x656E80A1u}, // en-CH -> en-150\n    {0x656E434Bu, 0x656E8400u}, // en-CK -> en-001\n    {0x656E434Du, 0x656E8400u}, // en-CM -> en-001\n    {0x656E4358u, 0x656E8400u}, // en-CX -> en-001\n    {0x656E4359u, 0x656E8400u}, // en-CY -> en-001\n    {0x656E4445u, 0x656E80A1u}, // en-DE -> en-150\n    {0x656E4447u, 0x656E8400u}, // en-DG -> en-001\n    {0x656E444Bu, 0x656E80A1u}, // en-DK -> en-150\n    {0x656E444Du, 0x656E8400u}, // en-DM -> en-001\n    {0x656E4552u, 0x656E8400u}, // en-ER -> en-001\n    {0x656E4649u, 0x656E80A1u}, // en-FI -> en-150\n    {0x656E464Au, 0x656E8400u}, // en-FJ -> en-001\n    {0x656E464Bu, 0x656E8400u}, // en-FK -> en-001\n    {0x656E464Du, 0x656E8400u}, // en-FM -> en-001\n    {0x656E4742u, 0x656E8400u}, // en-GB -> en-001\n    {0x656E4744u, 0x656E8400u}, // en-GD -> en-001\n    {0x656E4747u, 0x656E8400u}, // en-GG -> en-001\n    {0x656E4748u, 0x656E8400u}, // en-GH -> en-001\n    {0x656E4749u, 0x656E8400u}, // en-GI -> en-001\n    {0x656E474Du, 0x656E8400u}, // en-GM -> en-001\n    {0x656E4759u, 0x656E8400u}, // en-GY -> en-001\n    {0x656E484Bu, 0x656E8400u}, // en-HK -> en-001\n    {0x656E4945u, 0x656E8400u}, // en-IE -> en-001\n    {0x656E494Cu, 0x656E8400u}, // en-IL -> en-001\n    {0x656E494Du, 0x656E8400u}, // en-IM -> en-001\n    {0x656E494Eu, 0x656E8400u}, // en-IN -> en-001\n    {0x656E494Fu, 0x656E8400u}, // en-IO -> en-001\n    {0x656E4A45u, 0x656E8400u}, // en-JE -> en-001\n    {0x656E4A4Du, 0x656E8400u}, // en-JM -> en-001\n    {0x656E4B45u, 0x656E8400u}, // en-KE -> en-001\n    {0x656E4B49u, 0x656E8400u}, // en-KI -> en-001\n    {0x656E4B4Eu, 0x656E8400u}, // en-KN -> en-001\n    {0x656E4B59u, 0x656E8400u}, // en-KY -> en-001\n    {0x656E4C43u, 0x656E8400u}, // en-LC -> en-001\n    {0x656E4C52u, 0x656E8400u}, // en-LR -> en-001\n    {0x656E4C53u, 0x656E8400u}, // en-LS -> en-001\n    {0x656E4D47u, 0x656E8400u}, // en-MG -> en-001\n    {0x656E4D4Fu, 0x656E8400u}, // en-MO -> en-001\n    {0x656E4D53u, 0x656E8400u}, // en-MS -> en-001\n    {0x656E4D54u, 0x656E8400u}, // en-MT -> en-001\n    {0x656E4D55u, 0x656E8400u}, // en-MU -> en-001\n    {0x656E4D57u, 0x656E8400u}, // en-MW -> en-001\n    {0x656E4D59u, 0x656E8400u}, // en-MY -> en-001\n    {0x656E4E41u, 0x656E8400u}, // en-NA -> en-001\n    {0x656E4E46u, 0x656E8400u}, // en-NF -> en-001\n    {0x656E4E47u, 0x656E8400u}, // en-NG -> en-001\n    {0x656E4E4Cu, 0x656E80A1u}, // en-NL -> en-150\n    {0x656E4E52u, 0x656E8400u}, // en-NR -> en-001\n    {0x656E4E55u, 0x656E8400u}, // en-NU -> en-001\n    {0x656E4E5Au, 0x656E8400u}, // en-NZ -> en-001\n    {0x656E5047u, 0x656E8400u}, // en-PG -> en-001\n    {0x656E5048u, 0x656E8400u}, // en-PH -> en-001\n    {0x656E504Bu, 0x656E8400u}, // en-PK -> en-001\n    {0x656E504Eu, 0x656E8400u}, // en-PN -> en-001\n    {0x656E5057u, 0x656E8400u}, // en-PW -> en-001\n    {0x656E5257u, 0x656E8400u}, // en-RW -> en-001\n    {0x656E5342u, 0x656E8400u}, // en-SB -> en-001\n    {0x656E5343u, 0x656E8400u}, // en-SC -> en-001\n    {0x656E5344u, 0x656E8400u}, // en-SD -> en-001\n    {0x656E5345u, 0x656E80A1u}, // en-SE -> en-150\n    {0x656E5347u, 0x656E8400u}, // en-SG -> en-001\n    {0x656E5348u, 0x656E8400u}, // en-SH -> en-001\n    {0x656E5349u, 0x656E80A1u}, // en-SI -> en-150\n    {0x656E534Cu, 0x656E8400u}, // en-SL -> en-001\n    {0x656E5353u, 0x656E8400u}, // en-SS -> en-001\n    {0x656E5358u, 0x656E8400u}, // en-SX -> en-001\n    {0x656E535Au, 0x656E8400u}, // en-SZ -> en-001\n    {0x656E5443u, 0x656E8400u}, // en-TC -> en-001\n    {0x656E544Bu, 0x656E8400u}, // en-TK -> en-001\n    {0x656E544Fu, 0x656E8400u}, // en-TO -> en-001\n    {0x656E5454u, 0x656E8400u}, // en-TT -> en-001\n    {0x656E5456u, 0x656E8400u}, // en-TV -> en-001\n    {0x656E545Au, 0x656E8400u}, // en-TZ -> en-001\n    {0x656E5547u, 0x656E8400u}, // en-UG -> en-001\n    {0x656E5643u, 0x656E8400u}, // en-VC -> en-001\n    {0x656E5647u, 0x656E8400u}, // en-VG -> en-001\n    {0x656E5655u, 0x656E8400u}, // en-VU -> en-001\n    {0x656E5753u, 0x656E8400u}, // en-WS -> en-001\n    {0x656E5A41u, 0x656E8400u}, // en-ZA -> en-001\n    {0x656E5A4Du, 0x656E8400u}, // en-ZM -> en-001\n    {0x656E5A57u, 0x656E8400u}, // en-ZW -> en-001\n    {0x65734152u, 0x6573A424u}, // es-AR -> es-419\n    {0x6573424Fu, 0x6573A424u}, // es-BO -> es-419\n    {0x6573434Cu, 0x6573A424u}, // es-CL -> es-419\n    {0x6573434Fu, 0x6573A424u}, // es-CO -> es-419\n    {0x65734352u, 0x6573A424u}, // es-CR -> es-419\n    {0x65734355u, 0x6573A424u}, // es-CU -> es-419\n    {0x6573444Fu, 0x6573A424u}, // es-DO -> es-419\n    {0x65734543u, 0x6573A424u}, // es-EC -> es-419\n    {0x65734754u, 0x6573A424u}, // es-GT -> es-419\n    {0x6573484Eu, 0x6573A424u}, // es-HN -> es-419\n    {0x65734D58u, 0x6573A424u}, // es-MX -> es-419\n    {0x65734E49u, 0x6573A424u}, // es-NI -> es-419\n    {0x65735041u, 0x6573A424u}, // es-PA -> es-419\n    {0x65735045u, 0x6573A424u}, // es-PE -> es-419\n    {0x65735052u, 0x6573A424u}, // es-PR -> es-419\n    {0x65735059u, 0x6573A424u}, // es-PY -> es-419\n    {0x65735356u, 0x6573A424u}, // es-SV -> es-419\n    {0x65735553u, 0x6573A424u}, // es-US -> es-419\n    {0x65735559u, 0x6573A424u}, // es-UY -> es-419\n    {0x65735645u, 0x6573A424u}, // es-VE -> es-419\n    {0x7074414Fu, 0x70745054u}, // pt-AO -> pt-PT\n    {0x70744356u, 0x70745054u}, // pt-CV -> pt-PT\n    {0x70744757u, 0x70745054u}, // pt-GW -> pt-PT\n    {0x70744D4Fu, 0x70745054u}, // pt-MO -> pt-PT\n    {0x70744D5Au, 0x70745054u}, // pt-MZ -> pt-PT\n    {0x70745354u, 0x70745054u}, // pt-ST -> pt-PT\n    {0x7074544Cu, 0x70745054u}, // pt-TL -> pt-PT\n});\n\nconst struct {\n    const char script[4];\n    const std::unordered_map<uint32_t, uint32_t>* map;\n} SCRIPT_PARENTS[] = {\n    {{'A', 'r', 'a', 'b'}, &ARAB_PARENTS},\n    {{'H', 'a', 'n', 't'}, &HANT_PARENTS},\n    {{'L', 'a', 't', 'n'}, &LATN_PARENTS},\n};\n\nconst size_t MAX_PARENT_DEPTH = 3;\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/MODULE_LICENSE_APACHE2",
    "content": ""
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/NOTICE",
    "content": "\n   Copyright (c) 2005-2008, The Android Open Source Project\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/ObbFile.cpp",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <errno.h>\n#include <fcntl.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#define LOG_TAG \"ObbFile\"\n\n#include <androidfw/ObbFile.h>\n#include <utils/Compat.h>\n#include <utils/Log.h>\n\n//#define DEBUG 1\n\n#define kFooterTagSize 8  /* last two 32-bit integers */\n\n#define kFooterMinSize 33 /* 32-bit signature version (4 bytes)\n                           * 32-bit package version (4 bytes)\n                           * 32-bit flags (4 bytes)\n                           * 64-bit salt (8 bytes)\n                           * 32-bit package name size (4 bytes)\n                           * >=1-character package name (1 byte)\n                           * 32-bit footer size (4 bytes)\n                           * 32-bit footer marker (4 bytes)\n                           */\n\n#define kMaxBufSize    32768 /* Maximum file read buffer */\n\n#define kSignature     0x01059983U /* ObbFile signature */\n\n#define kSigVersion    1 /* We only know about signature version 1 */\n\n/* offsets in version 1 of the header */\n#define kPackageVersionOffset 4\n#define kFlagsOffset          8\n#define kSaltOffset           12\n#define kPackageNameLenOffset 20\n#define kPackageNameOffset    24\n\n/*\n * TEMP_FAILURE_RETRY is defined by some, but not all, versions of\n * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's\n * not already defined, then define it here.\n */\n#ifndef TEMP_FAILURE_RETRY\n/* Used to retry syscalls that can return EINTR. */\n#define TEMP_FAILURE_RETRY(exp) ({         \\\n    typeof (exp) _rc;                      \\\n    do {                                   \\\n        _rc = (exp);                       \\\n    } while (_rc == -1 && errno == EINTR); \\\n    _rc; })\n#endif\n\n\nnamespace android {\n\nObbFile::ObbFile()\n        : mPackageName(\"\")\n        , mVersion(-1)\n        , mFlags(0)\n{\n    memset(mSalt, 0, sizeof(mSalt));\n}\n\nObbFile::~ObbFile() {\n}\n\nbool ObbFile::readFrom(const char* filename)\n{\n    int fd;\n    bool success = false;\n\n    fd = ::open(filename, O_RDONLY);\n    if (fd < 0) {\n        ALOGW(\"couldn't open file %s: %s\", filename, strerror(errno));\n        goto out;\n    }\n    success = readFrom(fd);\n    close(fd);\n\n    if (!success) {\n        ALOGW(\"failed to read from %s (fd=%d)\\n\", filename, fd);\n    }\n\nout:\n    return success;\n}\n\nbool ObbFile::readFrom(int fd)\n{\n    if (fd < 0) {\n        ALOGW(\"attempt to read from invalid fd\\n\");\n        return false;\n    }\n\n    return parseObbFile(fd);\n}\n\nbool ObbFile::parseObbFile(int fd)\n{\n    off64_t fileLength = lseek64(fd, 0, SEEK_END);\n\n    if (fileLength < kFooterMinSize) {\n        if (fileLength < 0) {\n            ALOGW(\"error seeking in ObbFile: %s\\n\", strerror(errno));\n        } else {\n            ALOGW(\"file is only %lld (less than %d minimum)\\n\", (long long int)fileLength, kFooterMinSize);\n        }\n        return false;\n    }\n\n    ssize_t actual;\n    size_t footerSize;\n\n    {\n        lseek64(fd, fileLength - kFooterTagSize, SEEK_SET);\n\n        char footer[kFooterTagSize];\n        actual = TEMP_FAILURE_RETRY(read(fd, footer, kFooterTagSize));\n        if (actual != kFooterTagSize) {\n            ALOGW(\"couldn't read footer signature: %s\\n\", strerror(errno));\n            return false;\n        }\n\n        unsigned int fileSig = get4LE((unsigned char*)footer + sizeof(int32_t));\n        if (fileSig != kSignature) {\n            ALOGW(\"footer didn't match magic string (expected 0x%08x; got 0x%08x)\\n\",\n                    kSignature, fileSig);\n            return false;\n        }\n\n        footerSize = get4LE((unsigned char*)footer);\n        if (footerSize > (size_t)fileLength - kFooterTagSize\n                || footerSize > kMaxBufSize) {\n            ALOGW(\"claimed footer size is too large (0x%08zx; file size is 0x%08lld)\\n\",\n                    footerSize, (long long int)fileLength);\n            return false;\n        }\n\n        if (footerSize < (kFooterMinSize - kFooterTagSize)) {\n            ALOGW(\"claimed footer size is too small (0x%zx; minimum size is 0x%x)\\n\",\n                    footerSize, kFooterMinSize - kFooterTagSize);\n            return false;\n        }\n    }\n\n    off64_t fileOffset = fileLength - footerSize - kFooterTagSize;\n    if (lseek64(fd, fileOffset, SEEK_SET) != fileOffset) {\n        ALOGW(\"seek %lld failed: %s\\n\", (long long int)fileOffset, strerror(errno));\n        return false;\n    }\n\n    mFooterStart = fileOffset;\n\n    char* scanBuf = (char*)malloc(footerSize);\n    if (scanBuf == NULL) {\n        ALOGW(\"couldn't allocate scanBuf: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    actual = TEMP_FAILURE_RETRY(read(fd, scanBuf, footerSize));\n    // readAmount is guaranteed to be less than kMaxBufSize\n    if (actual != (ssize_t)footerSize) {\n        ALOGI(\"couldn't read ObbFile footer: %s\\n\", strerror(errno));\n        free(scanBuf);\n        return false;\n    }\n\n#ifdef DEBUG\n    for (int i = 0; i < footerSize; ++i) {\n        ALOGI(\"char: 0x%02x\\n\", scanBuf[i]);\n    }\n#endif\n\n    uint32_t sigVersion = get4LE((unsigned char*)scanBuf);\n    if (sigVersion != kSigVersion) {\n        ALOGW(\"Unsupported ObbFile version %d\\n\", sigVersion);\n        free(scanBuf);\n        return false;\n    }\n\n    mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset);\n    mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset);\n\n    memcpy(&mSalt, (unsigned char*)scanBuf + kSaltOffset, sizeof(mSalt));\n\n    size_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);\n    if (packageNameLen == 0\n            || packageNameLen > (footerSize - kPackageNameOffset)) {\n        ALOGW(\"bad ObbFile package name length (0x%04zx; 0x%04zx possible)\\n\",\n                packageNameLen, footerSize - kPackageNameOffset);\n        free(scanBuf);\n        return false;\n    }\n\n    char* packageName = reinterpret_cast<char*>(scanBuf + kPackageNameOffset);\n    mPackageName = String8(const_cast<char*>(packageName), packageNameLen);\n\n    free(scanBuf);\n\n#ifdef DEBUG\n    ALOGI(\"Obb scan succeeded: packageName=%s, version=%d\\n\", mPackageName.string(), mVersion);\n#endif\n\n    return true;\n}\n\nbool ObbFile::writeTo(const char* filename)\n{\n    int fd;\n    bool success = false;\n\n    fd = ::open(filename, O_WRONLY);\n    if (fd < 0) {\n        goto out;\n    }\n    success = writeTo(fd);\n    close(fd);\n\nout:\n    if (!success) {\n        ALOGW(\"failed to write to %s: %s\\n\", filename, strerror(errno));\n    }\n    return success;\n}\n\nbool ObbFile::writeTo(int fd)\n{\n    if (fd < 0) {\n        return false;\n    }\n\n    lseek64(fd, 0, SEEK_END);\n\n    if (mPackageName.size() == 0 || mVersion == -1) {\n        ALOGW(\"tried to write uninitialized ObbFile data\\n\");\n        return false;\n    }\n\n    unsigned char intBuf[sizeof(uint32_t)+1];\n    memset(&intBuf, 0, sizeof(intBuf));\n\n    put4LE(intBuf, kSigVersion);\n    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {\n        ALOGW(\"couldn't write signature version: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    put4LE(intBuf, mVersion);\n    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {\n        ALOGW(\"couldn't write package version\\n\");\n        return false;\n    }\n\n    put4LE(intBuf, mFlags);\n    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {\n        ALOGW(\"couldn't write package version\\n\");\n        return false;\n    }\n\n    if (write(fd, mSalt, sizeof(mSalt)) != (ssize_t)sizeof(mSalt)) {\n        ALOGW(\"couldn't write salt: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    size_t packageNameLen = mPackageName.size();\n    put4LE(intBuf, packageNameLen);\n    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {\n        ALOGW(\"couldn't write package name length: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) {\n        ALOGW(\"couldn't write package name: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    put4LE(intBuf, kPackageNameOffset + packageNameLen);\n    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {\n        ALOGW(\"couldn't write footer size: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    put4LE(intBuf, kSignature);\n    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {\n        ALOGW(\"couldn't write footer magic signature: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    return true;\n}\n\nbool ObbFile::removeFrom(const char* filename)\n{\n    int fd;\n    bool success = false;\n\n    fd = ::open(filename, O_RDWR);\n    if (fd < 0) {\n        goto out;\n    }\n    success = removeFrom(fd);\n    close(fd);\n\nout:\n    if (!success) {\n        ALOGW(\"failed to remove signature from %s: %s\\n\", filename, strerror(errno));\n    }\n    return success;\n}\n\nbool ObbFile::removeFrom(int fd)\n{\n    if (fd < 0) {\n        return false;\n    }\n\n    if (!readFrom(fd)) {\n        return false;\n    }\n\n    if (ftruncate(fd, mFooterStart) == -1) {\n        return false;\n    }\n\n    return true;\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/ResourceTypes.cpp",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"ResourceType\"\n//#define LOG_NDEBUG 0\n\n#include <ctype.h>\n#include <memory.h>\n#include <stddef.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <algorithm>\n#include <limits>\n#include <memory>\n#include <type_traits>\n\n#include <androidfw/ByteBucketArray.h>\n#include <androidfw/ResourceTypes.h>\n#include <androidfw/TypeWrappers.h>\n#include <utils/Atomic.h>\n#include <utils/ByteOrder.h>\n#include <utils/Debug.h>\n#include <utils/Log.h>\n#include <utils/String16.h>\n#include <utils/String8.h>\n#include <androidfw/ResourcePackageId.h>\n\n#ifdef __ANDROID__\n#include <binder/TextOutput.h>\n#endif\n\n#ifndef INT32_MAX\n#define INT32_MAX ((int32_t)(2147483647))\n#endif\n\n#define APP_PACKAGE_ID      0x7f\n#define SYS_PACKAGE_ID      0x01\n\nsize_t customePackageId = APP_PACKAGE_ID;\nchar* sktPackageName;\n\n\nnamespace android {\n\n#if defined(_WIN32)\n#undef  nhtol\n#undef  htonl\n#define ntohl(x)    ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )\n#define htonl(x)    ntohl(x)\n#define ntohs(x)    ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )\n#define htons(x)    ntohs(x)\n#endif\n\n#define IDMAP_MAGIC             0x504D4449\n#define IDMAP_CURRENT_VERSION   0x00000001\n\nstatic const bool kDebugStringPoolNoisy = false;\nstatic const bool kDebugXMLNoisy = false;\nstatic const bool kDebugTableNoisy = false;\nstatic const bool kDebugTableGetEntry = false;\nstatic const bool kDebugTableSuperNoisy = false;\nstatic const bool kDebugLoadTableNoisy = false;\nstatic const bool kDebugLoadTableSuperNoisy = false;\nstatic const bool kDebugTableTheme = false;\nstatic const bool kDebugResXMLTree = false;\nstatic const bool kDebugLibNoisy = false;\n\n// TODO: This code uses 0xFFFFFFFF converted to bag_set* as a sentinel value. This is bad practice.\n\n// Standard C isspace() is only required to look at the low byte of its input, so\n// produces incorrect results for UTF-16 characters.  For safety's sake, assume that\n// any high-byte UTF-16 code point is not whitespace.\ninline int isspace16(char16_t c) {\n    return (c < 0x0080 && isspace(c));\n}\n\ntemplate<typename T>\ninline static T max(T a, T b) {\n    return a > b ? a : b;\n}\n\n// range checked; guaranteed to NUL-terminate within the stated number of available slots\n// NOTE: if this truncates the dst string due to running out of space, no attempt is\n// made to avoid splitting surrogate pairs.\nstatic void strcpy16_dtoh(char16_t* dst, const uint16_t* src, size_t avail)\n{\n    char16_t* last = dst + avail - 1;\n    while (*src && (dst < last)) {\n        char16_t s = dtohs(static_cast<char16_t>(*src));\n        *dst++ = s;\n        src++;\n    }\n    *dst = 0;\n}\n\nstatic status_t validate_chunk(const ResChunk_header* chunk,\n                               size_t minSize,\n                               const uint8_t* dataEnd,\n                               const char* name)\n{\n    const uint16_t headerSize = dtohs(chunk->headerSize);\n    const uint32_t size = dtohl(chunk->size);\n\n    if (headerSize >= minSize) {\n        if (headerSize <= size) {\n            if (((headerSize|size)&0x3) == 0) {\n                if ((size_t)size <= (size_t)(dataEnd-((const uint8_t*)chunk))) {\n                    return NO_ERROR;\n                }\n                ALOGW(\"%s data size 0x%x extends beyond resource end %p.\",\n                     name, size, (void*)(dataEnd-((const uint8_t*)chunk)));\n                return BAD_TYPE;\n            }\n            ALOGW(\"%s size 0x%x or headerSize 0x%x is not on an integer boundary.\",\n                 name, (int)size, (int)headerSize);\n            return BAD_TYPE;\n        }\n        ALOGW(\"%s size 0x%x is smaller than header size 0x%x.\",\n             name, size, headerSize);\n        return BAD_TYPE;\n    }\n    ALOGW(\"%s header size 0x%04x is too small.\",\n         name, headerSize);\n    return BAD_TYPE;\n}\n\nstatic void fill9patchOffsets(Res_png_9patch* patch) {\n    patch->xDivsOffset = sizeof(Res_png_9patch);\n    patch->yDivsOffset = patch->xDivsOffset + (patch->numXDivs * sizeof(int32_t));\n    patch->colorsOffset = patch->yDivsOffset + (patch->numYDivs * sizeof(int32_t));\n}\n\ninline void Res_value::copyFrom_dtoh(const Res_value& src)\n{\n    size = dtohs(src.size);\n    res0 = src.res0;\n    dataType = src.dataType;\n    data = dtohl(src.data);\n}\n\nvoid Res_png_9patch::deviceToFile()\n{\n    int32_t* xDivs = getXDivs();\n    for (int i = 0; i < numXDivs; i++) {\n        xDivs[i] = htonl(xDivs[i]);\n    }\n    int32_t* yDivs = getYDivs();\n    for (int i = 0; i < numYDivs; i++) {\n        yDivs[i] = htonl(yDivs[i]);\n    }\n    paddingLeft = htonl(paddingLeft);\n    paddingRight = htonl(paddingRight);\n    paddingTop = htonl(paddingTop);\n    paddingBottom = htonl(paddingBottom);\n    uint32_t* colors = getColors();\n    for (int i=0; i<numColors; i++) {\n        colors[i] = htonl(colors[i]);\n    }\n}\n\nvoid Res_png_9patch::fileToDevice()\n{\n    int32_t* xDivs = getXDivs();\n    for (int i = 0; i < numXDivs; i++) {\n        xDivs[i] = ntohl(xDivs[i]);\n    }\n    int32_t* yDivs = getYDivs();\n    for (int i = 0; i < numYDivs; i++) {\n        yDivs[i] = ntohl(yDivs[i]);\n    }\n    paddingLeft = ntohl(paddingLeft);\n    paddingRight = ntohl(paddingRight);\n    paddingTop = ntohl(paddingTop);\n    paddingBottom = ntohl(paddingBottom);\n    uint32_t* colors = getColors();\n    for (int i=0; i<numColors; i++) {\n        colors[i] = ntohl(colors[i]);\n    }\n}\n\nsize_t Res_png_9patch::serializedSize() const\n{\n    // The size of this struct is 32 bytes on the 32-bit target system\n    // 4 * int8_t\n    // 4 * int32_t\n    // 3 * uint32_t\n    return 32\n            + numXDivs * sizeof(int32_t)\n            + numYDivs * sizeof(int32_t)\n            + numColors * sizeof(uint32_t);\n}\n\nvoid* Res_png_9patch::serialize(const Res_png_9patch& patch, const int32_t* xDivs,\n                                const int32_t* yDivs, const uint32_t* colors)\n{\n    // Use calloc since we're going to leave a few holes in the data\n    // and want this to run cleanly under valgrind\n    void* newData = calloc(1, patch.serializedSize());\n    serialize(patch, xDivs, yDivs, colors, newData);\n    return newData;\n}\n\nvoid Res_png_9patch::serialize(const Res_png_9patch& patch, const int32_t* xDivs,\n                               const int32_t* yDivs, const uint32_t* colors, void* outData)\n{\n    uint8_t* data = (uint8_t*) outData;\n    memcpy(data, &patch.wasDeserialized, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors\n    memcpy(data + 12, &patch.paddingLeft, 16);   // copy paddingXXXX\n    data += 32;\n\n    memcpy(data, xDivs, patch.numXDivs * sizeof(int32_t));\n    data +=  patch.numXDivs * sizeof(int32_t);\n    memcpy(data, yDivs, patch.numYDivs * sizeof(int32_t));\n    data +=  patch.numYDivs * sizeof(int32_t);\n    memcpy(data, colors, patch.numColors * sizeof(uint32_t));\n\n    fill9patchOffsets(reinterpret_cast<Res_png_9patch*>(outData));\n}\n\nstatic bool assertIdmapHeader(const void* idmap, size_t size) {\n    if (reinterpret_cast<uintptr_t>(idmap) & 0x03) {\n        ALOGE(\"idmap: header is not word aligned\");\n        return false;\n    }\n\n    if (size < ResTable::IDMAP_HEADER_SIZE_BYTES) {\n        ALOGW(\"idmap: header too small (%d bytes)\", (uint32_t) size);\n        return false;\n    }\n\n    const uint32_t magic = htodl(*reinterpret_cast<const uint32_t*>(idmap));\n    if (magic != IDMAP_MAGIC) {\n        ALOGW(\"idmap: no magic found in header (is 0x%08x, expected 0x%08x)\",\n             magic, IDMAP_MAGIC);\n        return false;\n    }\n\n    const uint32_t version = htodl(*(reinterpret_cast<const uint32_t*>(idmap) + 1));\n    if (version != IDMAP_CURRENT_VERSION) {\n        // We are strict about versions because files with this format are\n        // auto-generated and don't need backwards compatibility.\n        ALOGW(\"idmap: version mismatch in header (is 0x%08x, expected 0x%08x)\",\n                version, IDMAP_CURRENT_VERSION);\n        return false;\n    }\n    return true;\n}\n\nclass IdmapEntries {\npublic:\n    IdmapEntries() : mData(NULL) {}\n\n    bool hasEntries() const {\n        if (mData == NULL) {\n            return false;\n        }\n\n        return (dtohs(*mData) > 0);\n    }\n\n    size_t byteSize() const {\n        if (mData == NULL) {\n            return 0;\n        }\n        uint16_t entryCount = dtohs(mData[2]);\n        return (sizeof(uint16_t) * 4) + (sizeof(uint32_t) * static_cast<size_t>(entryCount));\n    }\n\n    uint8_t targetTypeId() const {\n        if (mData == NULL) {\n            return 0;\n        }\n        return dtohs(mData[0]);\n    }\n\n    uint8_t overlayTypeId() const {\n        if (mData == NULL) {\n            return 0;\n        }\n        return dtohs(mData[1]);\n    }\n\n    status_t setTo(const void* entryHeader, size_t size) {\n        if (reinterpret_cast<uintptr_t>(entryHeader) & 0x03) {\n            ALOGE(\"idmap: entry header is not word aligned\");\n            return UNKNOWN_ERROR;\n        }\n\n        if (size < sizeof(uint16_t) * 4) {\n            ALOGE(\"idmap: entry header is too small (%u bytes)\", (uint32_t) size);\n            return UNKNOWN_ERROR;\n        }\n\n        const uint16_t* header = reinterpret_cast<const uint16_t*>(entryHeader);\n        const uint16_t targetTypeId = dtohs(header[0]);\n        const uint16_t overlayTypeId = dtohs(header[1]);\n        if (targetTypeId == 0 || overlayTypeId == 0 || targetTypeId > 255 || overlayTypeId > 255) {\n            ALOGE(\"idmap: invalid type map (%u -> %u)\", targetTypeId, overlayTypeId);\n            return UNKNOWN_ERROR;\n        }\n\n        uint16_t entryCount = dtohs(header[2]);\n        if (size < sizeof(uint32_t) * (entryCount + 2)) {\n            ALOGE(\"idmap: too small (%u bytes) for the number of entries (%u)\",\n                    (uint32_t) size, (uint32_t) entryCount);\n            return UNKNOWN_ERROR;\n        }\n        mData = header;\n        return NO_ERROR;\n    }\n\n    status_t lookup(uint16_t entryId, uint16_t* outEntryId) const {\n        uint16_t entryCount = dtohs(mData[2]);\n        uint16_t offset = dtohs(mData[3]);\n\n        if (entryId < offset) {\n            // The entry is not present in this idmap\n            return BAD_INDEX;\n        }\n\n        entryId -= offset;\n\n        if (entryId >= entryCount) {\n            // The entry is not present in this idmap\n            return BAD_INDEX;\n        }\n\n        // It is safe to access the type here without checking the size because\n        // we have checked this when it was first loaded.\n        const uint32_t* entries = reinterpret_cast<const uint32_t*>(mData) + 2;\n        uint32_t mappedEntry = dtohl(entries[entryId]);\n        if (mappedEntry == 0xffffffff) {\n            // This entry is not present in this idmap\n            return BAD_INDEX;\n        }\n        *outEntryId = static_cast<uint16_t>(mappedEntry);\n        return NO_ERROR;\n    }\n\nprivate:\n    const uint16_t* mData;\n};\n\nstatus_t parseIdmap(const void* idmap, size_t size, uint8_t* outPackageId, KeyedVector<uint8_t, IdmapEntries>* outMap) {\n    if (!assertIdmapHeader(idmap, size)) {\n        return UNKNOWN_ERROR;\n    }\n\n    size -= ResTable::IDMAP_HEADER_SIZE_BYTES;\n    if (size < sizeof(uint16_t) * 2) {\n        ALOGE(\"idmap: too small to contain any mapping\");\n        return UNKNOWN_ERROR;\n    }\n\n    const uint16_t* data = reinterpret_cast<const uint16_t*>(\n            reinterpret_cast<const uint8_t*>(idmap) + ResTable::IDMAP_HEADER_SIZE_BYTES);\n\n    uint16_t targetPackageId = dtohs(*(data++));\n    if (targetPackageId == 0 || targetPackageId > 255) {\n        ALOGE(\"idmap: target package ID is invalid (%02x)\", targetPackageId);\n        return UNKNOWN_ERROR;\n    }\n\n    uint16_t mapCount = dtohs(*(data++));\n    if (mapCount == 0) {\n        ALOGE(\"idmap: no mappings\");\n        return UNKNOWN_ERROR;\n    }\n\n    if (mapCount > 255) {\n        ALOGW(\"idmap: too many mappings. Only 255 are possible but %u are present\", (uint32_t) mapCount);\n    }\n\n    while (size > sizeof(uint16_t) * 4) {\n        IdmapEntries entries;\n        status_t err = entries.setTo(data, size);\n        if (err != NO_ERROR) {\n            return err;\n        }\n\n        ssize_t index = outMap->add(entries.overlayTypeId(), entries);\n        if (index < 0) {\n            return NO_MEMORY;\n        }\n\n        data += entries.byteSize() / sizeof(uint16_t);\n        size -= entries.byteSize();\n    }\n\n    if (outPackageId != NULL) {\n        *outPackageId = static_cast<uint8_t>(targetPackageId);\n    }\n    return NO_ERROR;\n}\n\nRes_png_9patch* Res_png_9patch::deserialize(void* inData)\n{\n\n    Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(inData);\n    patch->wasDeserialized = true;\n    fill9patchOffsets(patch);\n\n    return patch;\n}\n\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n\nResStringPool::ResStringPool()\n    : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL)\n{\n}\n\nResStringPool::ResStringPool(const void* data, size_t size, bool copyData)\n    : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL)\n{\n    setTo(data, size, copyData);\n}\n\nResStringPool::~ResStringPool()\n{\n    uninit();\n}\n\nvoid ResStringPool::setToEmpty()\n{\n    uninit();\n\n    mOwnedData = calloc(1, sizeof(ResStringPool_header));\n    ResStringPool_header* header = (ResStringPool_header*) mOwnedData;\n    mSize = 0;\n    mEntries = NULL;\n    mStrings = NULL;\n    mStringPoolSize = 0;\n    mEntryStyles = NULL;\n    mStyles = NULL;\n    mStylePoolSize = 0;\n    mHeader = (const ResStringPool_header*) header;\n}\n\nstatus_t ResStringPool::setTo(const void* data, size_t size, bool copyData)\n{\n    if (!data || !size) {\n        return (mError=BAD_TYPE);\n    }\n\n    uninit();\n\n    const bool notDeviceEndian = htods(0xf0) != 0xf0;\n\n    if (copyData || notDeviceEndian) {\n        mOwnedData = malloc(size);\n        if (mOwnedData == NULL) {\n            return (mError=NO_MEMORY);\n        }\n        memcpy(mOwnedData, data, size);\n        data = mOwnedData;\n    }\n\n    mHeader = (const ResStringPool_header*)data;\n\n    if (notDeviceEndian) {\n        ResStringPool_header* h = const_cast<ResStringPool_header*>(mHeader);\n        h->header.headerSize = dtohs(mHeader->header.headerSize);\n        h->header.type = dtohs(mHeader->header.type);\n        h->header.size = dtohl(mHeader->header.size);\n        h->stringCount = dtohl(mHeader->stringCount);\n        h->styleCount = dtohl(mHeader->styleCount);\n        h->flags = dtohl(mHeader->flags);\n        h->stringsStart = dtohl(mHeader->stringsStart);\n        h->stylesStart = dtohl(mHeader->stylesStart);\n    }\n\n    if (mHeader->header.headerSize > mHeader->header.size\n            || mHeader->header.size > size) {\n        ALOGW(\"Bad string block: header size %d or total size %d is larger than data size %d\\n\",\n                (int)mHeader->header.headerSize, (int)mHeader->header.size, (int)size);\n        return (mError=BAD_TYPE);\n    }\n    mSize = mHeader->header.size;\n    mEntries = (const uint32_t*)\n        (((const uint8_t*)data)+mHeader->header.headerSize);\n\n    if (mHeader->stringCount > 0) {\n        if ((mHeader->stringCount*sizeof(uint32_t) < mHeader->stringCount)  // uint32 overflow?\n            || (mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t)))\n                > size) {\n            ALOGW(\"Bad string block: entry of %d items extends past data size %d\\n\",\n                    (int)(mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t))),\n                    (int)size);\n            return (mError=BAD_TYPE);\n        }\n\n        size_t charSize;\n        if (mHeader->flags&ResStringPool_header::UTF8_FLAG) {\n            charSize = sizeof(uint8_t);\n        } else {\n            charSize = sizeof(uint16_t);\n        }\n\n        // There should be at least space for the smallest string\n        // (2 bytes length, null terminator).\n        if (mHeader->stringsStart >= (mSize - sizeof(uint16_t))) {\n            ALOGW(\"Bad string block: string pool starts at %d, after total size %d\\n\",\n                    (int)mHeader->stringsStart, (int)mHeader->header.size);\n            return (mError=BAD_TYPE);\n        }\n\n        mStrings = (const void*)\n            (((const uint8_t*)data) + mHeader->stringsStart);\n\n        if (mHeader->styleCount == 0) {\n            mStringPoolSize = (mSize - mHeader->stringsStart) / charSize;\n        } else {\n            // check invariant: styles starts before end of data\n            if (mHeader->stylesStart >= (mSize - sizeof(uint16_t))) {\n                ALOGW(\"Bad style block: style block starts at %d past data size of %d\\n\",\n                    (int)mHeader->stylesStart, (int)mHeader->header.size);\n                return (mError=BAD_TYPE);\n            }\n            // check invariant: styles follow the strings\n            if (mHeader->stylesStart <= mHeader->stringsStart) {\n                ALOGW(\"Bad style block: style block starts at %d, before strings at %d\\n\",\n                    (int)mHeader->stylesStart, (int)mHeader->stringsStart);\n                return (mError=BAD_TYPE);\n            }\n            mStringPoolSize =\n                (mHeader->stylesStart-mHeader->stringsStart)/charSize;\n        }\n\n        // check invariant: stringCount > 0 requires a string pool to exist\n        if (mStringPoolSize == 0) {\n            ALOGW(\"Bad string block: stringCount is %d but pool size is 0\\n\", (int)mHeader->stringCount);\n            return (mError=BAD_TYPE);\n        }\n\n        if (notDeviceEndian) {\n            size_t i;\n            uint32_t* e = const_cast<uint32_t*>(mEntries);\n            for (i=0; i<mHeader->stringCount; i++) {\n                e[i] = dtohl(mEntries[i]);\n            }\n            if (!(mHeader->flags&ResStringPool_header::UTF8_FLAG)) {\n                const uint16_t* strings = (const uint16_t*)mStrings;\n                uint16_t* s = const_cast<uint16_t*>(strings);\n                for (i=0; i<mStringPoolSize; i++) {\n                    s[i] = dtohs(strings[i]);\n                }\n            }\n        }\n\n        if ((mHeader->flags&ResStringPool_header::UTF8_FLAG &&\n                ((uint8_t*)mStrings)[mStringPoolSize-1] != 0) ||\n                (!(mHeader->flags&ResStringPool_header::UTF8_FLAG) &&\n                ((uint16_t*)mStrings)[mStringPoolSize-1] != 0)) {\n            ALOGW(\"Bad string block: last string is not 0-terminated\\n\");\n            return (mError=BAD_TYPE);\n        }\n    } else {\n        mStrings = NULL;\n        mStringPoolSize = 0;\n    }\n\n    if (mHeader->styleCount > 0) {\n        mEntryStyles = mEntries + mHeader->stringCount;\n        // invariant: integer overflow in calculating mEntryStyles\n        if (mEntryStyles < mEntries) {\n            ALOGW(\"Bad string block: integer overflow finding styles\\n\");\n            return (mError=BAD_TYPE);\n        }\n\n        if (((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader) > (int)size) {\n            ALOGW(\"Bad string block: entry of %d styles extends past data size %d\\n\",\n                    (int)((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader),\n                    (int)size);\n            return (mError=BAD_TYPE);\n        }\n        mStyles = (const uint32_t*)\n            (((const uint8_t*)data)+mHeader->stylesStart);\n        if (mHeader->stylesStart >= mHeader->header.size) {\n            ALOGW(\"Bad string block: style pool starts %d, after total size %d\\n\",\n                    (int)mHeader->stylesStart, (int)mHeader->header.size);\n            return (mError=BAD_TYPE);\n        }\n        mStylePoolSize =\n            (mHeader->header.size-mHeader->stylesStart)/sizeof(uint32_t);\n\n        if (notDeviceEndian) {\n            size_t i;\n            uint32_t* e = const_cast<uint32_t*>(mEntryStyles);\n            for (i=0; i<mHeader->styleCount; i++) {\n                e[i] = dtohl(mEntryStyles[i]);\n            }\n            uint32_t* s = const_cast<uint32_t*>(mStyles);\n            for (i=0; i<mStylePoolSize; i++) {\n                s[i] = dtohl(mStyles[i]);\n            }\n        }\n\n        const ResStringPool_span endSpan = {\n            { htodl(ResStringPool_span::END) },\n            htodl(ResStringPool_span::END), htodl(ResStringPool_span::END)\n        };\n        if (memcmp(&mStyles[mStylePoolSize-(sizeof(endSpan)/sizeof(uint32_t))],\n                   &endSpan, sizeof(endSpan)) != 0) {\n            ALOGW(\"Bad string block: last style is not 0xFFFFFFFF-terminated\\n\");\n            return (mError=BAD_TYPE);\n        }\n    } else {\n        mEntryStyles = NULL;\n        mStyles = NULL;\n        mStylePoolSize = 0;\n    }\n\n    return (mError=NO_ERROR);\n}\n\nstatus_t ResStringPool::getError() const\n{\n    return mError;\n}\n\nvoid ResStringPool::uninit()\n{\n    mError = NO_INIT;\n    if (mHeader != NULL && mCache != NULL) {\n        for (size_t x = 0; x < mHeader->stringCount; x++) {\n            if (mCache[x] != NULL) {\n                free(mCache[x]);\n                mCache[x] = NULL;\n            }\n        }\n        free(mCache);\n        mCache = NULL;\n    }\n    if (mOwnedData) {\n        free(mOwnedData);\n        mOwnedData = NULL;\n    }\n}\n\n/**\n * Strings in UTF-16 format have length indicated by a length encoded in the\n * stored data. It is either 1 or 2 characters of length data. This allows a\n * maximum length of 0x7FFFFFF (2147483647 bytes), but if you're storing that\n * much data in a string, you're abusing them.\n *\n * If the high bit is set, then there are two characters or 4 bytes of length\n * data encoded. In that case, drop the high bit of the first character and\n * add it together with the next character.\n */\nstatic inline size_t\ndecodeLength(const uint16_t** str)\n{\n    size_t len = **str;\n    if ((len & 0x8000) != 0) {\n        (*str)++;\n        len = ((len & 0x7FFF) << 16) | **str;\n    }\n    (*str)++;\n    return len;\n}\n\n/**\n * Strings in UTF-8 format have length indicated by a length encoded in the\n * stored data. It is either 1 or 2 characters of length data. This allows a\n * maximum length of 0x7FFF (32767 bytes), but you should consider storing\n * text in another way if you're using that much data in a single string.\n *\n * If the high bit is set, then there are two characters or 2 bytes of length\n * data encoded. In that case, drop the high bit of the first character and\n * add it together with the next character.\n */\nstatic inline size_t\ndecodeLength(const uint8_t** str)\n{\n    size_t len = **str;\n    if ((len & 0x80) != 0) {\n        (*str)++;\n        len = ((len & 0x7F) << 8) | **str;\n    }\n    (*str)++;\n    return len;\n}\n\nconst char16_t* ResStringPool::stringAt(size_t idx, size_t* u16len) const\n{\n    if (mError == NO_ERROR && idx < mHeader->stringCount) {\n        const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0;\n        const uint32_t off = mEntries[idx]/(isUTF8?sizeof(uint8_t):sizeof(uint16_t));\n        if (off < (mStringPoolSize-1)) {\n            if (!isUTF8) {\n                const uint16_t* strings = (uint16_t*)mStrings;\n                const uint16_t* str = strings+off;\n\n                *u16len = decodeLength(&str);\n                if ((uint32_t)(str+*u16len-strings) < mStringPoolSize) {\n                    // Reject malformed (non null-terminated) strings\n                    if (str[*u16len] != 0x0000) {\n                        ALOGW(\"Bad string block: string #%d is not null-terminated\",\n                              (int)idx);\n                        return NULL;\n                    }\n                    return reinterpret_cast<const char16_t*>(str);\n                } else {\n                    ALOGW(\"Bad string block: string #%d extends to %d, past end at %d\\n\",\n                            (int)idx, (int)(str+*u16len-strings), (int)mStringPoolSize);\n                }\n            } else {\n                const uint8_t* strings = (uint8_t*)mStrings;\n                const uint8_t* u8str = strings+off;\n\n                *u16len = decodeLength(&u8str);\n                size_t u8len = decodeLength(&u8str);\n\n                // encLen must be less than 0x7FFF due to encoding.\n                if ((uint32_t)(u8str+u8len-strings) < mStringPoolSize) {\n                    AutoMutex lock(mDecodeLock);\n\n                    if (mCache == NULL) {\n#ifndef __ANDROID__\n                        if (kDebugStringPoolNoisy) {\n                            ALOGI(\"CREATING STRING CACHE OF %zu bytes\",\n                                    mHeader->stringCount*sizeof(char16_t**));\n                        }\n#else\n                        // We do not want to be in this case when actually running Android.\n                        ALOGW(\"CREATING STRING CACHE OF %zu bytes\",\n                                static_cast<size_t>(mHeader->stringCount*sizeof(char16_t**)));\n#endif\n                        mCache = (char16_t**)calloc(mHeader->stringCount, sizeof(char16_t**));\n                        if (mCache == NULL) {\n                            ALOGW(\"No memory trying to allocate decode cache table of %d bytes\\n\",\n                                    (int)(mHeader->stringCount*sizeof(char16_t**)));\n                            return NULL;\n                        }\n                    }\n\n                    if (mCache[idx] != NULL) {\n                        return mCache[idx];\n                    }\n\n                    ssize_t actualLen = utf8_to_utf16_length(u8str, u8len);\n                    if (actualLen < 0 || (size_t)actualLen != *u16len) {\n                        ALOGW(\"Bad string block: string #%lld decoded length is not correct \"\n                                \"%lld vs %llu\\n\",\n                                (long long)idx, (long long)actualLen, (long long)*u16len);\n                        return NULL;\n                    }\n\n                    // Reject malformed (non null-terminated) strings\n                    if (u8str[u8len] != 0x00) {\n                        ALOGW(\"Bad string block: string #%d is not null-terminated\",\n                              (int)idx);\n                        return NULL;\n                    }\n\n                    char16_t *u16str = (char16_t *)calloc(*u16len+1, sizeof(char16_t));\n                    if (!u16str) {\n                        ALOGW(\"No memory when trying to allocate decode cache for string #%d\\n\",\n                                (int)idx);\n                        return NULL;\n                    }\n\n                    if (kDebugStringPoolNoisy) {\n                        ALOGI(\"Caching UTF8 string: %s\", u8str);\n                    }\n                    utf8_to_utf16(u8str, u8len, u16str);\n                    mCache[idx] = u16str;\n                    return u16str;\n                } else {\n                    ALOGW(\"Bad string block: string #%lld extends to %lld, past end at %lld\\n\",\n                            (long long)idx, (long long)(u8str+u8len-strings),\n                            (long long)mStringPoolSize);\n                }\n            }\n        } else {\n            ALOGW(\"Bad string block: string #%d entry is at %d, past end at %d\\n\",\n                    (int)idx, (int)(off*sizeof(uint16_t)),\n                    (int)(mStringPoolSize*sizeof(uint16_t)));\n        }\n    }\n    return NULL;\n}\n\nconst char* ResStringPool::string8At(size_t idx, size_t* outLen) const\n{\n    if (mError == NO_ERROR && idx < mHeader->stringCount) {\n        if ((mHeader->flags&ResStringPool_header::UTF8_FLAG) == 0) {\n            return NULL;\n        }\n        const uint32_t off = mEntries[idx]/sizeof(char);\n        if (off < (mStringPoolSize-1)) {\n            const uint8_t* strings = (uint8_t*)mStrings;\n            const uint8_t* str = strings+off;\n            *outLen = decodeLength(&str);\n            size_t encLen = decodeLength(&str);\n            if ((uint32_t)(str+encLen-strings) < mStringPoolSize) {\n                return (const char*)str;\n            } else {\n                ALOGW(\"Bad string block: string #%d extends to %d, past end at %d\\n\",\n                        (int)idx, (int)(str+encLen-strings), (int)mStringPoolSize);\n            }\n        } else {\n            ALOGW(\"Bad string block: string #%d entry is at %d, past end at %d\\n\",\n                    (int)idx, (int)(off*sizeof(uint16_t)),\n                    (int)(mStringPoolSize*sizeof(uint16_t)));\n        }\n    }\n    return NULL;\n}\n\nconst String8 ResStringPool::string8ObjectAt(size_t idx) const\n{\n    size_t len;\n    const char *str = string8At(idx, &len);\n    if (str != NULL) {\n        return String8(str, len);\n    }\n\n    const char16_t *str16 = stringAt(idx, &len);\n    if (str16 != NULL) {\n        return String8(str16, len);\n    }\n    return String8();\n}\n\nconst ResStringPool_span* ResStringPool::styleAt(const ResStringPool_ref& ref) const\n{\n    return styleAt(ref.index);\n}\n\nconst ResStringPool_span* ResStringPool::styleAt(size_t idx) const\n{\n    if (mError == NO_ERROR && idx < mHeader->styleCount) {\n        const uint32_t off = (mEntryStyles[idx]/sizeof(uint32_t));\n        if (off < mStylePoolSize) {\n            return (const ResStringPool_span*)(mStyles+off);\n        } else {\n            ALOGW(\"Bad string block: style #%d entry is at %d, past end at %d\\n\",\n                    (int)idx, (int)(off*sizeof(uint32_t)),\n                    (int)(mStylePoolSize*sizeof(uint32_t)));\n        }\n    }\n    return NULL;\n}\n\nssize_t ResStringPool::indexOfString(const char16_t* str, size_t strLen) const\n{\n    if (mError != NO_ERROR) {\n        return mError;\n    }\n\n    size_t len;\n\n    if ((mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0) {\n        if (kDebugStringPoolNoisy) {\n            ALOGI(\"indexOfString UTF-8: %s\", String8(str, strLen).string());\n        }\n\n        // The string pool contains UTF 8 strings; we don't want to cause\n        // temporary UTF-16 strings to be created as we search.\n        if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {\n            // Do a binary search for the string...  this is a little tricky,\n            // because the strings are sorted with strzcmp16().  So to match\n            // the ordering, we need to convert strings in the pool to UTF-16.\n            // But we don't want to hit the cache, so instead we will have a\n            // local temporary allocation for the conversions.\n            char16_t* convBuffer = (char16_t*)malloc(strLen+4);\n            ssize_t l = 0;\n            ssize_t h = mHeader->stringCount-1;\n\n            ssize_t mid;\n            while (l <= h) {\n                mid = l + (h - l)/2;\n                const uint8_t* s = (const uint8_t*)string8At(mid, &len);\n                int c;\n                if (s != NULL) {\n                    char16_t* end = utf8_to_utf16_n(s, len, convBuffer, strLen+3);\n                    *end = 0;\n                    c = strzcmp16(convBuffer, end-convBuffer, str, strLen);\n                } else {\n                    c = -1;\n                }\n                if (kDebugStringPoolNoisy) {\n                    ALOGI(\"Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\\n\",\n                            (const char*)s, c, (int)l, (int)mid, (int)h);\n                }\n                if (c == 0) {\n                    if (kDebugStringPoolNoisy) {\n                        ALOGI(\"MATCH!\");\n                    }\n                    free(convBuffer);\n                    return mid;\n                } else if (c < 0) {\n                    l = mid + 1;\n                } else {\n                    h = mid - 1;\n                }\n            }\n            free(convBuffer);\n        } else {\n            // It is unusual to get the ID from an unsorted string block...\n            // most often this happens because we want to get IDs for style\n            // span tags; since those always appear at the end of the string\n            // block, start searching at the back.\n            String8 str8(str, strLen);\n            const size_t str8Len = str8.size();\n            for (int i=mHeader->stringCount-1; i>=0; i--) {\n                const char* s = string8At(i, &len);\n                if (kDebugStringPoolNoisy) {\n                    ALOGI(\"Looking at %s, i=%d\\n\", String8(s).string(), i);\n                }\n                if (s && str8Len == len && memcmp(s, str8.string(), str8Len) == 0) {\n                    if (kDebugStringPoolNoisy) {\n                        ALOGI(\"MATCH!\");\n                    }\n                    return i;\n                }\n            }\n        }\n\n    } else {\n        if (kDebugStringPoolNoisy) {\n            ALOGI(\"indexOfString UTF-16: %s\", String8(str, strLen).string());\n        }\n\n        if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {\n            // Do a binary search for the string...\n            ssize_t l = 0;\n            ssize_t h = mHeader->stringCount-1;\n\n            ssize_t mid;\n            while (l <= h) {\n                mid = l + (h - l)/2;\n                const char16_t* s = stringAt(mid, &len);\n                int c = s ? strzcmp16(s, len, str, strLen) : -1;\n                if (kDebugStringPoolNoisy) {\n                    ALOGI(\"Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\\n\",\n                            String8(s).string(), c, (int)l, (int)mid, (int)h);\n                }\n                if (c == 0) {\n                    if (kDebugStringPoolNoisy) {\n                        ALOGI(\"MATCH!\");\n                    }\n                    return mid;\n                } else if (c < 0) {\n                    l = mid + 1;\n                } else {\n                    h = mid - 1;\n                }\n            }\n        } else {\n            // It is unusual to get the ID from an unsorted string block...\n            // most often this happens because we want to get IDs for style\n            // span tags; since those always appear at the end of the string\n            // block, start searching at the back.\n            for (int i=mHeader->stringCount-1; i>=0; i--) {\n                const char16_t* s = stringAt(i, &len);\n                if (kDebugStringPoolNoisy) {\n                    ALOGI(\"Looking at %s, i=%d\\n\", String8(s).string(), i);\n                }\n                if (s && strLen == len && strzcmp16(s, len, str, strLen) == 0) {\n                    if (kDebugStringPoolNoisy) {\n                        ALOGI(\"MATCH!\");\n                    }\n                    return i;\n                }\n            }\n        }\n    }\n\n    return NAME_NOT_FOUND;\n}\n\nsize_t ResStringPool::size() const\n{\n    return (mError == NO_ERROR) ? mHeader->stringCount : 0;\n}\n\nsize_t ResStringPool::styleCount() const\n{\n    return (mError == NO_ERROR) ? mHeader->styleCount : 0;\n}\n\nsize_t ResStringPool::bytes() const\n{\n    return (mError == NO_ERROR) ? mHeader->header.size : 0;\n}\n\nbool ResStringPool::isSorted() const\n{\n    return (mHeader->flags&ResStringPool_header::SORTED_FLAG)!=0;\n}\n\nbool ResStringPool::isUTF8() const\n{\n    return (mHeader->flags&ResStringPool_header::UTF8_FLAG)!=0;\n}\n\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n\nResXMLParser::ResXMLParser(const ResXMLTree& tree)\n    : mTree(tree), mEventCode(BAD_DOCUMENT)\n{\n}\n\nvoid ResXMLParser::restart()\n{\n    mCurNode = NULL;\n    mEventCode = mTree.mError == NO_ERROR ? START_DOCUMENT : BAD_DOCUMENT;\n}\nconst ResStringPool& ResXMLParser::getStrings() const\n{\n    return mTree.mStrings;\n}\n\nResXMLParser::event_code_t ResXMLParser::getEventType() const\n{\n    return mEventCode;\n}\n\nResXMLParser::event_code_t ResXMLParser::next()\n{\n    if (mEventCode == START_DOCUMENT) {\n        mCurNode = mTree.mRootNode;\n        mCurExt = mTree.mRootExt;\n        return (mEventCode=mTree.mRootCode);\n    } else if (mEventCode >= FIRST_CHUNK_CODE) {\n        return nextNode();\n    }\n    return mEventCode;\n}\n\nint32_t ResXMLParser::getCommentID() const\n{\n    return mCurNode != NULL ? dtohl(mCurNode->comment.index) : -1;\n}\n\nconst char16_t* ResXMLParser::getComment(size_t* outLen) const\n{\n    int32_t id = getCommentID();\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nuint32_t ResXMLParser::getLineNumber() const\n{\n    return mCurNode != NULL ? dtohl(mCurNode->lineNumber) : -1;\n}\n\nint32_t ResXMLParser::getTextID() const\n{\n    if (mEventCode == TEXT) {\n        return dtohl(((const ResXMLTree_cdataExt*)mCurExt)->data.index);\n    }\n    return -1;\n}\n\nconst char16_t* ResXMLParser::getText(size_t* outLen) const\n{\n    int32_t id = getTextID();\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nssize_t ResXMLParser::getTextValue(Res_value* outValue) const\n{\n    if (mEventCode == TEXT) {\n        outValue->copyFrom_dtoh(((const ResXMLTree_cdataExt*)mCurExt)->typedData);\n        return sizeof(Res_value);\n    }\n    return BAD_TYPE;\n}\n\nint32_t ResXMLParser::getNamespacePrefixID() const\n{\n    if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {\n        return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->prefix.index);\n    }\n    return -1;\n}\n\nconst char16_t* ResXMLParser::getNamespacePrefix(size_t* outLen) const\n{\n    int32_t id = getNamespacePrefixID();\n    //printf(\"prefix=%d  event=%p\\n\", id, mEventCode);\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nint32_t ResXMLParser::getNamespaceUriID() const\n{\n    if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {\n        return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->uri.index);\n    }\n    return -1;\n}\n\nconst char16_t* ResXMLParser::getNamespaceUri(size_t* outLen) const\n{\n    int32_t id = getNamespaceUriID();\n    //printf(\"uri=%d  event=%p\\n\", id, mEventCode);\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nint32_t ResXMLParser::getElementNamespaceID() const\n{\n    if (mEventCode == START_TAG) {\n        return dtohl(((const ResXMLTree_attrExt*)mCurExt)->ns.index);\n    }\n    if (mEventCode == END_TAG) {\n        return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->ns.index);\n    }\n    return -1;\n}\n\nconst char16_t* ResXMLParser::getElementNamespace(size_t* outLen) const\n{\n    int32_t id = getElementNamespaceID();\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nint32_t ResXMLParser::getElementNameID() const\n{\n    if (mEventCode == START_TAG) {\n        return dtohl(((const ResXMLTree_attrExt*)mCurExt)->name.index);\n    }\n    if (mEventCode == END_TAG) {\n        return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->name.index);\n    }\n    return -1;\n}\n\nconst char16_t* ResXMLParser::getElementName(size_t* outLen) const\n{\n    int32_t id = getElementNameID();\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nsize_t ResXMLParser::getAttributeCount() const\n{\n    if (mEventCode == START_TAG) {\n        return dtohs(((const ResXMLTree_attrExt*)mCurExt)->attributeCount);\n    }\n    return 0;\n}\n\nint32_t ResXMLParser::getAttributeNamespaceID(size_t idx) const\n{\n    if (mEventCode == START_TAG) {\n        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;\n        if (idx < dtohs(tag->attributeCount)) {\n            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)\n                (((const uint8_t*)tag)\n                 + dtohs(tag->attributeStart)\n                 + (dtohs(tag->attributeSize)*idx));\n            return dtohl(attr->ns.index);\n        }\n    }\n    return -2;\n}\n\nconst char16_t* ResXMLParser::getAttributeNamespace(size_t idx, size_t* outLen) const\n{\n    int32_t id = getAttributeNamespaceID(idx);\n    //printf(\"attribute namespace=%d  idx=%d  event=%p\\n\", id, idx, mEventCode);\n    if (kDebugXMLNoisy) {\n        printf(\"getAttributeNamespace 0x%zx=0x%x\\n\", idx, id);\n    }\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nconst char* ResXMLParser::getAttributeNamespace8(size_t idx, size_t* outLen) const\n{\n    int32_t id = getAttributeNamespaceID(idx);\n    //printf(\"attribute namespace=%d  idx=%d  event=%p\\n\", id, idx, mEventCode);\n    if (kDebugXMLNoisy) {\n        printf(\"getAttributeNamespace 0x%zx=0x%x\\n\", idx, id);\n    }\n    return id >= 0 ? mTree.mStrings.string8At(id, outLen) : NULL;\n}\n\nint32_t ResXMLParser::getAttributeNameID(size_t idx) const\n{\n    if (mEventCode == START_TAG) {\n        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;\n        if (idx < dtohs(tag->attributeCount)) {\n            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)\n                (((const uint8_t*)tag)\n                 + dtohs(tag->attributeStart)\n                 + (dtohs(tag->attributeSize)*idx));\n            return dtohl(attr->name.index);\n        }\n    }\n    return -1;\n}\n\nconst char16_t* ResXMLParser::getAttributeName(size_t idx, size_t* outLen) const\n{\n    int32_t id = getAttributeNameID(idx);\n    //printf(\"attribute name=%d  idx=%d  event=%p\\n\", id, idx, mEventCode);\n    if (kDebugXMLNoisy) {\n        printf(\"getAttributeName 0x%zx=0x%x\\n\", idx, id);\n    }\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nconst char* ResXMLParser::getAttributeName8(size_t idx, size_t* outLen) const\n{\n    int32_t id = getAttributeNameID(idx);\n    //printf(\"attribute name=%d  idx=%d  event=%p\\n\", id, idx, mEventCode);\n    if (kDebugXMLNoisy) {\n        printf(\"getAttributeName 0x%zx=0x%x\\n\", idx, id);\n    }\n    return id >= 0 ? mTree.mStrings.string8At(id, outLen) : NULL;\n}\n\nuint32_t ResXMLParser::getAttributeNameResID(size_t idx) const\n{\n    int32_t id = getAttributeNameID(idx);\n    if (id >= 0 && (size_t)id < mTree.mNumResIds) {\n        uint32_t resId = dtohl(mTree.mResIds[id]);\n        if (mTree.mDynamicRefTable != NULL) {\n            mTree.mDynamicRefTable->lookupResourceId(&resId);\n        }\n        return resId;\n    }\n    return 0;\n}\n\nint32_t ResXMLParser::getAttributeValueStringID(size_t idx) const\n{\n    if (mEventCode == START_TAG) {\n        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;\n        if (idx < dtohs(tag->attributeCount)) {\n            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)\n                (((const uint8_t*)tag)\n                 + dtohs(tag->attributeStart)\n                 + (dtohs(tag->attributeSize)*idx));\n            return dtohl(attr->rawValue.index);\n        }\n    }\n    return -1;\n}\n\nconst char16_t* ResXMLParser::getAttributeStringValue(size_t idx, size_t* outLen) const\n{\n    int32_t id = getAttributeValueStringID(idx);\n    if (kDebugXMLNoisy) {\n        printf(\"getAttributeValue 0x%zx=0x%x\\n\", idx, id);\n    }\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nint32_t ResXMLParser::getAttributeDataType(size_t idx) const\n{\n    if (mEventCode == START_TAG) {\n        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;\n        if (idx < dtohs(tag->attributeCount)) {\n            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)\n                (((const uint8_t*)tag)\n                 + dtohs(tag->attributeStart)\n                 + (dtohs(tag->attributeSize)*idx));\n            uint8_t type = attr->typedValue.dataType;\n            if (type != Res_value::TYPE_DYNAMIC_REFERENCE) {\n                return type;\n            }\n\n            // This is a dynamic reference. We adjust those references\n            // to regular references at this level, so lie to the caller.\n            return Res_value::TYPE_REFERENCE;\n        }\n    }\n    return Res_value::TYPE_NULL;\n}\n\nint32_t ResXMLParser::getAttributeData(size_t idx) const\n{\n    if (mEventCode == START_TAG) {\n        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;\n        if (idx < dtohs(tag->attributeCount)) {\n            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)\n                (((const uint8_t*)tag)\n                 + dtohs(tag->attributeStart)\n                 + (dtohs(tag->attributeSize)*idx));\n            if (attr->typedValue.dataType != Res_value::TYPE_DYNAMIC_REFERENCE ||\n                    mTree.mDynamicRefTable == NULL) {\n                return dtohl(attr->typedValue.data);\n            }\n\n            uint32_t data = dtohl(attr->typedValue.data);\n            if (mTree.mDynamicRefTable->lookupResourceId(&data) == NO_ERROR) {\n                return data;\n            }\n        }\n    }\n    return 0;\n}\n\nssize_t ResXMLParser::getAttributeValue(size_t idx, Res_value* outValue) const\n{\n    if (mEventCode == START_TAG) {\n        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;\n        if (idx < dtohs(tag->attributeCount)) {\n            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)\n                (((const uint8_t*)tag)\n                 + dtohs(tag->attributeStart)\n                 + (dtohs(tag->attributeSize)*idx));\n            outValue->copyFrom_dtoh(attr->typedValue);\n            if (mTree.mDynamicRefTable != NULL &&\n                    mTree.mDynamicRefTable->lookupResourceValue(outValue) != NO_ERROR) {\n                return BAD_TYPE;\n            }\n            return sizeof(Res_value);\n        }\n    }\n    return BAD_TYPE;\n}\n\nssize_t ResXMLParser::indexOfAttribute(const char* ns, const char* attr) const\n{\n    String16 nsStr(ns != NULL ? ns : \"\");\n    String16 attrStr(attr);\n    return indexOfAttribute(ns ? nsStr.string() : NULL, ns ? nsStr.size() : 0,\n                            attrStr.string(), attrStr.size());\n}\n\nssize_t ResXMLParser::indexOfAttribute(const char16_t* ns, size_t nsLen,\n                                       const char16_t* attr, size_t attrLen) const\n{\n    if (mEventCode == START_TAG) {\n        if (attr == NULL) {\n            return NAME_NOT_FOUND;\n        }\n        const size_t N = getAttributeCount();\n        if (mTree.mStrings.isUTF8()) {\n            String8 ns8, attr8;\n            if (ns != NULL) {\n                ns8 = String8(ns, nsLen);\n            }\n            attr8 = String8(attr, attrLen);\n            if (kDebugStringPoolNoisy) {\n                ALOGI(\"indexOfAttribute UTF8 %s (%zu) / %s (%zu)\", ns8.string(), nsLen,\n                        attr8.string(), attrLen);\n            }\n            for (size_t i=0; i<N; i++) {\n                size_t curNsLen = 0, curAttrLen = 0;\n                const char* curNs = getAttributeNamespace8(i, &curNsLen);\n                const char* curAttr = getAttributeName8(i, &curAttrLen);\n                if (kDebugStringPoolNoisy) {\n                    ALOGI(\"  curNs=%s (%zu), curAttr=%s (%zu)\", curNs, curNsLen, curAttr, curAttrLen);\n                }\n                if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen\n                        && memcmp(attr8.string(), curAttr, attrLen) == 0) {\n                    if (ns == NULL) {\n                        if (curNs == NULL) {\n                            if (kDebugStringPoolNoisy) {\n                                ALOGI(\"  FOUND!\");\n                            }\n                            return i;\n                        }\n                    } else if (curNs != NULL) {\n                        //printf(\" --> ns=%s, curNs=%s\\n\",\n                        //       String8(ns).string(), String8(curNs).string());\n                        if (memcmp(ns8.string(), curNs, nsLen) == 0) {\n                            if (kDebugStringPoolNoisy) {\n                                ALOGI(\"  FOUND!\");\n                            }\n                            return i;\n                        }\n                    }\n                }\n            }\n        } else {\n            if (kDebugStringPoolNoisy) {\n                ALOGI(\"indexOfAttribute UTF16 %s (%zu) / %s (%zu)\",\n                        String8(ns, nsLen).string(), nsLen,\n                        String8(attr, attrLen).string(), attrLen);\n            }\n            for (size_t i=0; i<N; i++) {\n                size_t curNsLen = 0, curAttrLen = 0;\n                const char16_t* curNs = getAttributeNamespace(i, &curNsLen);\n                const char16_t* curAttr = getAttributeName(i, &curAttrLen);\n                if (kDebugStringPoolNoisy) {\n                    ALOGI(\"  curNs=%s (%zu), curAttr=%s (%zu)\",\n                            String8(curNs, curNsLen).string(), curNsLen,\n                            String8(curAttr, curAttrLen).string(), curAttrLen);\n                }\n                if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen\n                        && (memcmp(attr, curAttr, attrLen*sizeof(char16_t)) == 0)) {\n                    if (ns == NULL) {\n                        if (curNs == NULL) {\n                            if (kDebugStringPoolNoisy) {\n                                ALOGI(\"  FOUND!\");\n                            }\n                            return i;\n                        }\n                    } else if (curNs != NULL) {\n                        //printf(\" --> ns=%s, curNs=%s\\n\",\n                        //       String8(ns).string(), String8(curNs).string());\n                        if (memcmp(ns, curNs, nsLen*sizeof(char16_t)) == 0) {\n                            if (kDebugStringPoolNoisy) {\n                                ALOGI(\"  FOUND!\");\n                            }\n                            return i;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    return NAME_NOT_FOUND;\n}\n\nssize_t ResXMLParser::indexOfID() const\n{\n    if (mEventCode == START_TAG) {\n        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->idIndex);\n        if (idx > 0) return (idx-1);\n    }\n    return NAME_NOT_FOUND;\n}\n\nssize_t ResXMLParser::indexOfClass() const\n{\n    if (mEventCode == START_TAG) {\n        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->classIndex);\n        if (idx > 0) return (idx-1);\n    }\n    return NAME_NOT_FOUND;\n}\n\nssize_t ResXMLParser::indexOfStyle() const\n{\n    if (mEventCode == START_TAG) {\n        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->styleIndex);\n        if (idx > 0) return (idx-1);\n    }\n    return NAME_NOT_FOUND;\n}\n\nResXMLParser::event_code_t ResXMLParser::nextNode()\n{\n    if (mEventCode < 0) {\n        return mEventCode;\n    }\n\n    do {\n        const ResXMLTree_node* next = (const ResXMLTree_node*)\n            (((const uint8_t*)mCurNode) + dtohl(mCurNode->header.size));\n        if (kDebugXMLNoisy) {\n            ALOGI(\"Next node: prev=%p, next=%p\\n\", mCurNode, next);\n        }\n\n        if (((const uint8_t*)next) >= mTree.mDataEnd) {\n            mCurNode = NULL;\n            return (mEventCode=END_DOCUMENT);\n        }\n\n        if (mTree.validateNode(next) != NO_ERROR) {\n            mCurNode = NULL;\n            return (mEventCode=BAD_DOCUMENT);\n        }\n\n        mCurNode = next;\n        const uint16_t headerSize = dtohs(next->header.headerSize);\n        const uint32_t totalSize = dtohl(next->header.size);\n        mCurExt = ((const uint8_t*)next) + headerSize;\n        size_t minExtSize = 0;\n        event_code_t eventCode = (event_code_t)dtohs(next->header.type);\n        switch ((mEventCode=eventCode)) {\n            case RES_XML_START_NAMESPACE_TYPE:\n            case RES_XML_END_NAMESPACE_TYPE:\n                minExtSize = sizeof(ResXMLTree_namespaceExt);\n                break;\n            case RES_XML_START_ELEMENT_TYPE:\n                minExtSize = sizeof(ResXMLTree_attrExt);\n                break;\n            case RES_XML_END_ELEMENT_TYPE:\n                minExtSize = sizeof(ResXMLTree_endElementExt);\n                break;\n            case RES_XML_CDATA_TYPE:\n                minExtSize = sizeof(ResXMLTree_cdataExt);\n                break;\n            default:\n                ALOGW(\"Unknown XML block: header type %d in node at %d\\n\",\n                     (int)dtohs(next->header.type),\n                     (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)));\n                continue;\n        }\n\n        if ((totalSize-headerSize) < minExtSize) {\n            ALOGW(\"Bad XML block: header type 0x%x in node at 0x%x has size %d, need %d\\n\",\n                 (int)dtohs(next->header.type),\n                 (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)),\n                 (int)(totalSize-headerSize), (int)minExtSize);\n            return (mEventCode=BAD_DOCUMENT);\n        }\n\n        //printf(\"CurNode=%p, CurExt=%p, headerSize=%d, minExtSize=%d\\n\",\n        //       mCurNode, mCurExt, headerSize, minExtSize);\n\n        return eventCode;\n    } while (true);\n}\n\nvoid ResXMLParser::getPosition(ResXMLParser::ResXMLPosition* pos) const\n{\n    pos->eventCode = mEventCode;\n    pos->curNode = mCurNode;\n    pos->curExt = mCurExt;\n}\n\nvoid ResXMLParser::setPosition(const ResXMLParser::ResXMLPosition& pos)\n{\n    mEventCode = pos.eventCode;\n    mCurNode = pos.curNode;\n    mCurExt = pos.curExt;\n}\n\n// --------------------------------------------------------------------\n\nstatic volatile int32_t gCount = 0;\n\nResXMLTree::ResXMLTree(const DynamicRefTable* dynamicRefTable)\n    : ResXMLParser(*this)\n    , mDynamicRefTable(dynamicRefTable)\n    , mError(NO_INIT), mOwnedData(NULL)\n{\n    if (kDebugResXMLTree) {\n        ALOGI(\"Creating ResXMLTree %p #%d\\n\", this, android_atomic_inc(&gCount)+1);\n    }\n    restart();\n}\n\nResXMLTree::ResXMLTree()\n    : ResXMLParser(*this)\n    , mDynamicRefTable(NULL)\n    , mError(NO_INIT), mOwnedData(NULL)\n{\n    if (kDebugResXMLTree) {\n        ALOGI(\"Creating ResXMLTree %p #%d\\n\", this, android_atomic_inc(&gCount)+1);\n    }\n    restart();\n}\n\nResXMLTree::~ResXMLTree()\n{\n    if (kDebugResXMLTree) {\n        ALOGI(\"Destroying ResXMLTree in %p #%d\\n\", this, android_atomic_dec(&gCount)-1);\n    }\n    uninit();\n}\n\nstatus_t ResXMLTree::setTo(const void* data, size_t size, bool copyData)\n{\n    uninit();\n    mEventCode = START_DOCUMENT;\n\n    if (!data || !size) {\n        return (mError=BAD_TYPE);\n    }\n\n    if (copyData) {\n        mOwnedData = malloc(size);\n        if (mOwnedData == NULL) {\n            return (mError=NO_MEMORY);\n        }\n        memcpy(mOwnedData, data, size);\n        data = mOwnedData;\n    }\n\n    mHeader = (const ResXMLTree_header*)data;\n    mSize = dtohl(mHeader->header.size);\n    if (dtohs(mHeader->header.headerSize) > mSize || mSize > size) {\n        ALOGW(\"Bad XML block: header size %d or total size %d is larger than data size %d\\n\",\n             (int)dtohs(mHeader->header.headerSize),\n             (int)dtohl(mHeader->header.size), (int)size);\n        mError = BAD_TYPE;\n        restart();\n        return mError;\n    }\n    mDataEnd = ((const uint8_t*)mHeader) + mSize;\n\n    mStrings.uninit();\n    mRootNode = NULL;\n    mResIds = NULL;\n    mNumResIds = 0;\n\n    // First look for a couple interesting chunks: the string block\n    // and first XML node.\n    const ResChunk_header* chunk =\n        (const ResChunk_header*)(((const uint8_t*)mHeader) + dtohs(mHeader->header.headerSize));\n    const ResChunk_header* lastChunk = chunk;\n    while (((const uint8_t*)chunk) < (mDataEnd-sizeof(ResChunk_header)) &&\n           ((const uint8_t*)chunk) < (mDataEnd-dtohl(chunk->size))) {\n        status_t err = validate_chunk(chunk, sizeof(ResChunk_header), mDataEnd, \"XML\");\n        if (err != NO_ERROR) {\n            mError = err;\n            goto done;\n        }\n        const uint16_t type = dtohs(chunk->type);\n        const size_t size = dtohl(chunk->size);\n        if (kDebugXMLNoisy) {\n            printf(\"Scanning @ %p: type=0x%x, size=0x%zx\\n\",\n                    (void*)(((uintptr_t)chunk)-((uintptr_t)mHeader)), type, size);\n        }\n        if (type == RES_STRING_POOL_TYPE) {\n            mStrings.setTo(chunk, size);\n        } else if (type == RES_XML_RESOURCE_MAP_TYPE) {\n            mResIds = (const uint32_t*)\n                (((const uint8_t*)chunk)+dtohs(chunk->headerSize));\n            mNumResIds = (dtohl(chunk->size)-dtohs(chunk->headerSize))/sizeof(uint32_t);\n        } else if (type >= RES_XML_FIRST_CHUNK_TYPE\n                   && type <= RES_XML_LAST_CHUNK_TYPE) {\n            if (validateNode((const ResXMLTree_node*)chunk) != NO_ERROR) {\n                mError = BAD_TYPE;\n                goto done;\n            }\n            mCurNode = (const ResXMLTree_node*)lastChunk;\n            if (nextNode() == BAD_DOCUMENT) {\n                mError = BAD_TYPE;\n                goto done;\n            }\n            mRootNode = mCurNode;\n            mRootExt = mCurExt;\n            mRootCode = mEventCode;\n            break;\n        } else {\n            if (kDebugXMLNoisy) {\n                printf(\"Skipping unknown chunk!\\n\");\n            }\n        }\n        lastChunk = chunk;\n        chunk = (const ResChunk_header*)\n            (((const uint8_t*)chunk) + size);\n    }\n\n    if (mRootNode == NULL) {\n        ALOGW(\"Bad XML block: no root element node found\\n\");\n        mError = BAD_TYPE;\n        goto done;\n    }\n\n    mError = mStrings.getError();\n\ndone:\n    restart();\n    return mError;\n}\n\nstatus_t ResXMLTree::getError() const\n{\n    return mError;\n}\n\nvoid ResXMLTree::uninit()\n{\n    mError = NO_INIT;\n    mStrings.uninit();\n    if (mOwnedData) {\n        free(mOwnedData);\n        mOwnedData = NULL;\n    }\n    restart();\n}\n\nstatus_t ResXMLTree::validateNode(const ResXMLTree_node* node) const\n{\n    const uint16_t eventCode = dtohs(node->header.type);\n\n    status_t err = validate_chunk(\n        &node->header, sizeof(ResXMLTree_node),\n        mDataEnd, \"ResXMLTree_node\");\n\n    if (err >= NO_ERROR) {\n        // Only perform additional validation on START nodes\n        if (eventCode != RES_XML_START_ELEMENT_TYPE) {\n            return NO_ERROR;\n        }\n\n        const uint16_t headerSize = dtohs(node->header.headerSize);\n        const uint32_t size = dtohl(node->header.size);\n        const ResXMLTree_attrExt* attrExt = (const ResXMLTree_attrExt*)\n            (((const uint8_t*)node) + headerSize);\n        // check for sensical values pulled out of the stream so far...\n        if ((size >= headerSize + sizeof(ResXMLTree_attrExt))\n                && ((void*)attrExt > (void*)node)) {\n            const size_t attrSize = ((size_t)dtohs(attrExt->attributeSize))\n                * dtohs(attrExt->attributeCount);\n            if ((dtohs(attrExt->attributeStart)+attrSize) <= (size-headerSize)) {\n                return NO_ERROR;\n            }\n            ALOGW(\"Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\\n\",\n                    (unsigned int)(dtohs(attrExt->attributeStart)+attrSize),\n                    (unsigned int)(size-headerSize));\n        }\n        else {\n            ALOGW(\"Bad XML start block: node header size 0x%x, size 0x%x\\n\",\n                (unsigned int)headerSize, (unsigned int)size);\n        }\n        return BAD_TYPE;\n    }\n\n    return err;\n\n#if 0\n    const bool isStart = dtohs(node->header.type) == RES_XML_START_ELEMENT_TYPE;\n\n    const uint16_t headerSize = dtohs(node->header.headerSize);\n    const uint32_t size = dtohl(node->header.size);\n\n    if (headerSize >= (isStart ? sizeof(ResXMLTree_attrNode) : sizeof(ResXMLTree_node))) {\n        if (size >= headerSize) {\n            if (((const uint8_t*)node) <= (mDataEnd-size)) {\n                if (!isStart) {\n                    return NO_ERROR;\n                }\n                if ((((size_t)dtohs(node->attributeSize))*dtohs(node->attributeCount))\n                        <= (size-headerSize)) {\n                    return NO_ERROR;\n                }\n                ALOGW(\"Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\\n\",\n                        ((int)dtohs(node->attributeSize))*dtohs(node->attributeCount),\n                        (int)(size-headerSize));\n                return BAD_TYPE;\n            }\n            ALOGW(\"Bad XML block: node at 0x%x extends beyond data end 0x%x\\n\",\n                    (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)), (int)mSize);\n            return BAD_TYPE;\n        }\n        ALOGW(\"Bad XML block: node at 0x%x header size 0x%x smaller than total size 0x%x\\n\",\n                (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),\n                (int)headerSize, (int)size);\n        return BAD_TYPE;\n    }\n    ALOGW(\"Bad XML block: node at 0x%x header size 0x%x too small\\n\",\n            (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),\n            (int)headerSize);\n    return BAD_TYPE;\n#endif\n}\n\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n\nvoid ResTable_config::copyFromDeviceNoSwap(const ResTable_config& o) {\n    const size_t size = dtohl(o.size);\n    if (size >= sizeof(ResTable_config)) {\n        *this = o;\n    } else {\n        memcpy(this, &o, size);\n        memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size);\n    }\n}\n\n/* static */ size_t unpackLanguageOrRegion(const char in[2], const char base,\n        char out[4]) {\n  if (in[0] & 0x80) {\n      // The high bit is \"1\", which means this is a packed three letter\n      // language code.\n\n      // The smallest 5 bits of the second char are the first alphabet.\n      const uint8_t first = in[1] & 0x1f;\n      // The last three bits of the second char and the first two bits\n      // of the first char are the second alphabet.\n      const uint8_t second = ((in[1] & 0xe0) >> 5) + ((in[0] & 0x03) << 3);\n      // Bits 3 to 7 (inclusive) of the first char are the third alphabet.\n      const uint8_t third = (in[0] & 0x7c) >> 2;\n\n      out[0] = first + base;\n      out[1] = second + base;\n      out[2] = third + base;\n      out[3] = 0;\n\n      return 3;\n  }\n\n  if (in[0]) {\n      memcpy(out, in, 2);\n      memset(out + 2, 0, 2);\n      return 2;\n  }\n\n  memset(out, 0, 4);\n  return 0;\n}\n\n/* static */ void packLanguageOrRegion(const char* in, const char base,\n        char out[2]) {\n  if (in[2] == 0 || in[2] == '-') {\n      out[0] = in[0];\n      out[1] = in[1];\n  } else {\n      uint8_t first = (in[0] - base) & 0x007f;\n      uint8_t second = (in[1] - base) & 0x007f;\n      uint8_t third = (in[2] - base) & 0x007f;\n\n      out[0] = (0x80 | (third << 2) | (second >> 3));\n      out[1] = ((second << 5) | first);\n  }\n}\n\n\nvoid ResTable_config::packLanguage(const char* language) {\n    packLanguageOrRegion(language, 'a', this->language);\n}\n\nvoid ResTable_config::packRegion(const char* region) {\n    packLanguageOrRegion(region, '0', this->country);\n}\n\nsize_t ResTable_config::unpackLanguage(char language[4]) const {\n    return unpackLanguageOrRegion(this->language, 'a', language);\n}\n\nsize_t ResTable_config::unpackRegion(char region[4]) const {\n    return unpackLanguageOrRegion(this->country, '0', region);\n}\n\n\nvoid ResTable_config::copyFromDtoH(const ResTable_config& o) {\n    copyFromDeviceNoSwap(o);\n    size = sizeof(ResTable_config);\n    mcc = dtohs(mcc);\n    mnc = dtohs(mnc);\n    density = dtohs(density);\n    screenWidth = dtohs(screenWidth);\n    screenHeight = dtohs(screenHeight);\n    sdkVersion = dtohs(sdkVersion);\n    minorVersion = dtohs(minorVersion);\n    smallestScreenWidthDp = dtohs(smallestScreenWidthDp);\n    screenWidthDp = dtohs(screenWidthDp);\n    screenHeightDp = dtohs(screenHeightDp);\n}\n\nvoid ResTable_config::swapHtoD() {\n    size = htodl(size);\n    mcc = htods(mcc);\n    mnc = htods(mnc);\n    density = htods(density);\n    screenWidth = htods(screenWidth);\n    screenHeight = htods(screenHeight);\n    sdkVersion = htods(sdkVersion);\n    minorVersion = htods(minorVersion);\n    smallestScreenWidthDp = htods(smallestScreenWidthDp);\n    screenWidthDp = htods(screenWidthDp);\n    screenHeightDp = htods(screenHeightDp);\n}\n\n/* static */ inline int compareLocales(const ResTable_config &l, const ResTable_config &r) {\n    if (l.locale != r.locale) {\n        // NOTE: This is the old behaviour with respect to comparison orders.\n        // The diff value here doesn't make much sense (given our bit packing scheme)\n        // but it's stable, and that's all we need.\n        return l.locale - r.locale;\n    }\n\n    // The language & region are equal, so compare the scripts and variants.\n    const char emptyScript[sizeof(l.localeScript)] = {'\\0', '\\0', '\\0', '\\0'};\n    const char *lScript = l.localeScriptWasComputed ? emptyScript : l.localeScript;\n    const char *rScript = r.localeScriptWasComputed ? emptyScript : r.localeScript;\n    int script = memcmp(lScript, rScript, sizeof(l.localeScript));\n    if (script) {\n        return script;\n    }\n\n    // The language, region and script are equal, so compare variants.\n    //\n    // This should happen very infrequently (if at all.)\n    return memcmp(l.localeVariant, r.localeVariant, sizeof(l.localeVariant));\n}\n\nint ResTable_config::compare(const ResTable_config& o) const {\n    int32_t diff = (int32_t)(imsi - o.imsi);\n    if (diff != 0) return diff;\n    diff = compareLocales(*this, o);\n    if (diff != 0) return diff;\n    diff = (int32_t)(screenType - o.screenType);\n    if (diff != 0) return diff;\n    diff = (int32_t)(input - o.input);\n    if (diff != 0) return diff;\n    diff = (int32_t)(screenSize - o.screenSize);\n    if (diff != 0) return diff;\n    diff = (int32_t)(version - o.version);\n    if (diff != 0) return diff;\n    diff = (int32_t)(screenLayout - o.screenLayout);\n    if (diff != 0) return diff;\n    diff = (int32_t)(screenLayout2 - o.screenLayout2);\n    if (diff != 0) return diff;\n    diff = (int32_t)(uiMode - o.uiMode);\n    if (diff != 0) return diff;\n    diff = (int32_t)(smallestScreenWidthDp - o.smallestScreenWidthDp);\n    if (diff != 0) return diff;\n    diff = (int32_t)(screenSizeDp - o.screenSizeDp);\n    return (int)diff;\n}\n\nint ResTable_config::compareLogical(const ResTable_config& o) const {\n    if (mcc != o.mcc) {\n        return mcc < o.mcc ? -1 : 1;\n    }\n    if (mnc != o.mnc) {\n        return mnc < o.mnc ? -1 : 1;\n    }\n\n    int diff = compareLocales(*this, o);\n    if (diff < 0) {\n        return -1;\n    }\n    if (diff > 0) {\n        return 1;\n    }\n\n    if ((screenLayout & MASK_LAYOUTDIR) != (o.screenLayout & MASK_LAYOUTDIR)) {\n        return (screenLayout & MASK_LAYOUTDIR) < (o.screenLayout & MASK_LAYOUTDIR) ? -1 : 1;\n    }\n    if (smallestScreenWidthDp != o.smallestScreenWidthDp) {\n        return smallestScreenWidthDp < o.smallestScreenWidthDp ? -1 : 1;\n    }\n    if (screenWidthDp != o.screenWidthDp) {\n        return screenWidthDp < o.screenWidthDp ? -1 : 1;\n    }\n    if (screenHeightDp != o.screenHeightDp) {\n        return screenHeightDp < o.screenHeightDp ? -1 : 1;\n    }\n    if (screenWidth != o.screenWidth) {\n        return screenWidth < o.screenWidth ? -1 : 1;\n    }\n    if (screenHeight != o.screenHeight) {\n        return screenHeight < o.screenHeight ? -1 : 1;\n    }\n    if (density != o.density) {\n        return density < o.density ? -1 : 1;\n    }\n    if (orientation != o.orientation) {\n        return orientation < o.orientation ? -1 : 1;\n    }\n    if (touchscreen != o.touchscreen) {\n        return touchscreen < o.touchscreen ? -1 : 1;\n    }\n    if (input != o.input) {\n        return input < o.input ? -1 : 1;\n    }\n    if (screenLayout != o.screenLayout) {\n        return screenLayout < o.screenLayout ? -1 : 1;\n    }\n    if (screenLayout2 != o.screenLayout2) {\n        return screenLayout2 < o.screenLayout2 ? -1 : 1;\n    }\n    if (uiMode != o.uiMode) {\n        return uiMode < o.uiMode ? -1 : 1;\n    }\n    if (version != o.version) {\n        return version < o.version ? -1 : 1;\n    }\n    return 0;\n}\n\nint ResTable_config::diff(const ResTable_config& o) const {\n    int diffs = 0;\n    if (mcc != o.mcc) diffs |= CONFIG_MCC;\n    if (mnc != o.mnc) diffs |= CONFIG_MNC;\n    if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION;\n    if (density != o.density) diffs |= CONFIG_DENSITY;\n    if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN;\n    if (((inputFlags^o.inputFlags)&(MASK_KEYSHIDDEN|MASK_NAVHIDDEN)) != 0)\n            diffs |= CONFIG_KEYBOARD_HIDDEN;\n    if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD;\n    if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;\n    if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;\n    if (version != o.version) diffs |= CONFIG_VERSION;\n    if ((screenLayout & MASK_LAYOUTDIR) != (o.screenLayout & MASK_LAYOUTDIR)) diffs |= CONFIG_LAYOUTDIR;\n    if ((screenLayout & ~MASK_LAYOUTDIR) != (o.screenLayout & ~MASK_LAYOUTDIR)) diffs |= CONFIG_SCREEN_LAYOUT;\n    if ((screenLayout2 & MASK_SCREENROUND) != (o.screenLayout2 & MASK_SCREENROUND)) diffs |= CONFIG_SCREEN_ROUND;\n    if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE;\n    if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE;\n    if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE;\n\n    const int diff = compareLocales(*this, o);\n    if (diff) diffs |= CONFIG_LOCALE;\n\n    return diffs;\n}\n\nint ResTable_config::isLocaleMoreSpecificThan(const ResTable_config& o) const {\n    if (locale || o.locale) {\n        if (language[0] != o.language[0]) {\n            if (!language[0]) return -1;\n            if (!o.language[0]) return 1;\n        }\n\n        if (country[0] != o.country[0]) {\n            if (!country[0]) return -1;\n            if (!o.country[0]) return 1;\n        }\n    }\n\n    // There isn't a well specified \"importance\" order between variants and\n    // scripts. We can't easily tell whether, say \"en-Latn-US\" is more or less\n    // specific than \"en-US-POSIX\".\n    //\n    // We therefore arbitrarily decide to give priority to variants over\n    // scripts since it seems more useful to do so. We will consider\n    // \"en-US-POSIX\" to be more specific than \"en-Latn-US\".\n\n    const int score = ((localeScript[0] != '\\0' && !localeScriptWasComputed) ? 1 : 0) +\n        ((localeVariant[0] != '\\0') ? 2 : 0);\n\n    const int oScore = (o.localeScript[0] != '\\0' && !o.localeScriptWasComputed ? 1 : 0) +\n        ((o.localeVariant[0] != '\\0') ? 2 : 0);\n\n    return score - oScore;\n\n}\n\nbool ResTable_config::isMoreSpecificThan(const ResTable_config& o) const {\n    // The order of the following tests defines the importance of one\n    // configuration parameter over another.  Those tests first are more\n    // important, trumping any values in those following them.\n    if (imsi || o.imsi) {\n        if (mcc != o.mcc) {\n            if (!mcc) return false;\n            if (!o.mcc) return true;\n        }\n\n        if (mnc != o.mnc) {\n            if (!mnc) return false;\n            if (!o.mnc) return true;\n        }\n    }\n\n    if (locale || o.locale) {\n        const int diff = isLocaleMoreSpecificThan(o);\n        if (diff < 0) {\n            return false;\n        }\n\n        if (diff > 0) {\n            return true;\n        }\n    }\n\n    if (screenLayout || o.screenLayout) {\n        if (((screenLayout^o.screenLayout) & MASK_LAYOUTDIR) != 0) {\n            if (!(screenLayout & MASK_LAYOUTDIR)) return false;\n            if (!(o.screenLayout & MASK_LAYOUTDIR)) return true;\n        }\n    }\n\n    if (smallestScreenWidthDp || o.smallestScreenWidthDp) {\n        if (smallestScreenWidthDp != o.smallestScreenWidthDp) {\n            if (!smallestScreenWidthDp) return false;\n            if (!o.smallestScreenWidthDp) return true;\n        }\n    }\n\n    if (screenSizeDp || o.screenSizeDp) {\n        if (screenWidthDp != o.screenWidthDp) {\n            if (!screenWidthDp) return false;\n            if (!o.screenWidthDp) return true;\n        }\n\n        if (screenHeightDp != o.screenHeightDp) {\n            if (!screenHeightDp) return false;\n            if (!o.screenHeightDp) return true;\n        }\n    }\n\n    if (screenLayout || o.screenLayout) {\n        if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) {\n            if (!(screenLayout & MASK_SCREENSIZE)) return false;\n            if (!(o.screenLayout & MASK_SCREENSIZE)) return true;\n        }\n        if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) {\n            if (!(screenLayout & MASK_SCREENLONG)) return false;\n            if (!(o.screenLayout & MASK_SCREENLONG)) return true;\n        }\n    }\n\n    if (screenLayout2 || o.screenLayout2) {\n        if (((screenLayout2^o.screenLayout2) & MASK_SCREENROUND) != 0) {\n            if (!(screenLayout2 & MASK_SCREENROUND)) return false;\n            if (!(o.screenLayout2 & MASK_SCREENROUND)) return true;\n        }\n    }\n\n    if (orientation != o.orientation) {\n        if (!orientation) return false;\n        if (!o.orientation) return true;\n    }\n\n    if (uiMode || o.uiMode) {\n        if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0) {\n            if (!(uiMode & MASK_UI_MODE_TYPE)) return false;\n            if (!(o.uiMode & MASK_UI_MODE_TYPE)) return true;\n        }\n        if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0) {\n            if (!(uiMode & MASK_UI_MODE_NIGHT)) return false;\n            if (!(o.uiMode & MASK_UI_MODE_NIGHT)) return true;\n        }\n    }\n\n    // density is never 'more specific'\n    // as the default just equals 160\n\n    if (touchscreen != o.touchscreen) {\n        if (!touchscreen) return false;\n        if (!o.touchscreen) return true;\n    }\n\n    if (input || o.input) {\n        if (((inputFlags^o.inputFlags) & MASK_KEYSHIDDEN) != 0) {\n            if (!(inputFlags & MASK_KEYSHIDDEN)) return false;\n            if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true;\n        }\n\n        if (((inputFlags^o.inputFlags) & MASK_NAVHIDDEN) != 0) {\n            if (!(inputFlags & MASK_NAVHIDDEN)) return false;\n            if (!(o.inputFlags & MASK_NAVHIDDEN)) return true;\n        }\n\n        if (keyboard != o.keyboard) {\n            if (!keyboard) return false;\n            if (!o.keyboard) return true;\n        }\n\n        if (navigation != o.navigation) {\n            if (!navigation) return false;\n            if (!o.navigation) return true;\n        }\n    }\n\n    if (screenSize || o.screenSize) {\n        if (screenWidth != o.screenWidth) {\n            if (!screenWidth) return false;\n            if (!o.screenWidth) return true;\n        }\n\n        if (screenHeight != o.screenHeight) {\n            if (!screenHeight) return false;\n            if (!o.screenHeight) return true;\n        }\n    }\n\n    if (version || o.version) {\n        if (sdkVersion != o.sdkVersion) {\n            if (!sdkVersion) return false;\n            if (!o.sdkVersion) return true;\n        }\n\n        if (minorVersion != o.minorVersion) {\n            if (!minorVersion) return false;\n            if (!o.minorVersion) return true;\n        }\n    }\n    return false;\n}\n\nbool ResTable_config::isLocaleBetterThan(const ResTable_config& o,\n        const ResTable_config* requested) const {\n    if (requested->locale == 0) {\n        // The request doesn't have a locale, so no resource is better\n        // than the other.\n        return false;\n    }\n\n    if (locale == 0 && o.locale == 0) {\n        // The locales parts of both resources are empty, so no one is better\n        // than the other.\n        return false;\n    }\n\n    // Non-matching locales have been filtered out, so both resources\n    // match the requested locale.\n    //\n    // Because of the locale-related checks in match() and the checks, we know\n    // that:\n    // 1) The resource languages are either empty or match the request;\n    // and\n    // 2) If the request's script is known, the resource scripts are either\n    //    unknown or match the request.\n\n    if (language[0] != o.language[0]) {\n        // The languages of the two resources are not the same. We can only\n        // assume that one of the two resources matched the request because one\n        // doesn't have a language and the other has a matching language.\n        //\n        // We consider the one that has the language specified a better match.\n        //\n        // The exception is that we consider no-language resources a better match\n        // for US English and similar locales than locales that are a descendant\n        // of Internatinal English (en-001), since no-language resources are\n        // where the US English resource have traditionally lived for most apps.\n        if (requested->language[0] == 'e' && requested->language[1] == 'n') {\n            if (requested->country[0] == 'U' && requested->country[1] == 'S') {\n                // For US English itself, we consider a no-locale resource a\n                // better match if the other resource has a country other than\n                // US specified.\n                if (language[0] != '\\0') {\n                    return country[0] == '\\0' || (country[0] == 'U' && country[1] == 'S');\n                } else {\n                    return !(o.country[0] == '\\0' || (o.country[0] == 'U' && o.country[1] == 'S'));\n                }\n            } else if (localeDataIsCloseToUsEnglish(requested->country)) {\n                if (language[0] != '\\0') {\n                    return localeDataIsCloseToUsEnglish(country);\n                } else {\n                    return !localeDataIsCloseToUsEnglish(o.country);\n                }\n            }\n        }\n        return (language[0] != '\\0');\n    }\n\n    // If we are here, both the resources have the same non-empty language as\n    // the request.\n    //\n    // Because the languages are the same, computeScript() always\n    // returns a non-empty script for languages it knows about, and we have passed\n    // the script checks in match(), the scripts are either all unknown or are\n    // all the same. So we can't gain anything by checking the scripts. We need\n    // to check the region and variant.\n\n    // See if any of the regions is better than the other\n    const int region_comparison = localeDataCompareRegions(\n            country, o.country,\n            language, requested->localeScript, requested->country);\n    if (region_comparison != 0) {\n        return (region_comparison > 0);\n    }\n\n    // The regions are the same. Try the variant.\n    if (requested->localeVariant[0] != '\\0'\n            && strncmp(localeVariant, requested->localeVariant, sizeof(localeVariant)) == 0) {\n        return (strncmp(o.localeVariant, requested->localeVariant, sizeof(localeVariant)) != 0);\n    }\n\n    return false;\n}\n\nbool ResTable_config::isBetterThan(const ResTable_config& o,\n        const ResTable_config* requested) const {\n    if (requested) {\n        if (imsi || o.imsi) {\n            if ((mcc != o.mcc) && requested->mcc) {\n                return (mcc);\n            }\n\n            if ((mnc != o.mnc) && requested->mnc) {\n                return (mnc);\n            }\n        }\n\n        if (isLocaleBetterThan(o, requested)) {\n            return true;\n        }\n\n        if (screenLayout || o.screenLayout) {\n            if (((screenLayout^o.screenLayout) & MASK_LAYOUTDIR) != 0\n                    && (requested->screenLayout & MASK_LAYOUTDIR)) {\n                int myLayoutDir = screenLayout & MASK_LAYOUTDIR;\n                int oLayoutDir = o.screenLayout & MASK_LAYOUTDIR;\n                return (myLayoutDir > oLayoutDir);\n            }\n        }\n\n        if (smallestScreenWidthDp || o.smallestScreenWidthDp) {\n            // The configuration closest to the actual size is best.\n            // We assume that larger configs have already been filtered\n            // out at this point.  That means we just want the largest one.\n            if (smallestScreenWidthDp != o.smallestScreenWidthDp) {\n                return smallestScreenWidthDp > o.smallestScreenWidthDp;\n            }\n        }\n\n        if (screenSizeDp || o.screenSizeDp) {\n            // \"Better\" is based on the sum of the difference between both\n            // width and height from the requested dimensions.  We are\n            // assuming the invalid configs (with smaller dimens) have\n            // already been filtered.  Note that if a particular dimension\n            // is unspecified, we will end up with a large value (the\n            // difference between 0 and the requested dimension), which is\n            // good since we will prefer a config that has specified a\n            // dimension value.\n            int myDelta = 0, otherDelta = 0;\n            if (requested->screenWidthDp) {\n                myDelta += requested->screenWidthDp - screenWidthDp;\n                otherDelta += requested->screenWidthDp - o.screenWidthDp;\n            }\n            if (requested->screenHeightDp) {\n                myDelta += requested->screenHeightDp - screenHeightDp;\n                otherDelta += requested->screenHeightDp - o.screenHeightDp;\n            }\n            if (kDebugTableSuperNoisy) {\n                ALOGI(\"Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d\",\n                        screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,\n                        requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);\n            }\n            if (myDelta != otherDelta) {\n                return myDelta < otherDelta;\n            }\n        }\n\n        if (screenLayout || o.screenLayout) {\n            if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0\n                    && (requested->screenLayout & MASK_SCREENSIZE)) {\n                // A little backwards compatibility here: undefined is\n                // considered equivalent to normal.  But only if the\n                // requested size is at least normal; otherwise, small\n                // is better than the default.\n                int mySL = (screenLayout & MASK_SCREENSIZE);\n                int oSL = (o.screenLayout & MASK_SCREENSIZE);\n                int fixedMySL = mySL;\n                int fixedOSL = oSL;\n                if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) {\n                    if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL;\n                    if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL;\n                }\n                // For screen size, the best match is the one that is\n                // closest to the requested screen size, but not over\n                // (the not over part is dealt with in match() below).\n                if (fixedMySL == fixedOSL) {\n                    // If the two are the same, but 'this' is actually\n                    // undefined, then the other is really a better match.\n                    if (mySL == 0) return false;\n                    return true;\n                }\n                if (fixedMySL != fixedOSL) {\n                    return fixedMySL > fixedOSL;\n                }\n            }\n            if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0\n                    && (requested->screenLayout & MASK_SCREENLONG)) {\n                return (screenLayout & MASK_SCREENLONG);\n            }\n        }\n\n        if (screenLayout2 || o.screenLayout2) {\n            if (((screenLayout2^o.screenLayout2) & MASK_SCREENROUND) != 0 &&\n                    (requested->screenLayout2 & MASK_SCREENROUND)) {\n                return screenLayout2 & MASK_SCREENROUND;\n            }\n        }\n\n        if ((orientation != o.orientation) && requested->orientation) {\n            return (orientation);\n        }\n\n        if (uiMode || o.uiMode) {\n            if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0\n                    && (requested->uiMode & MASK_UI_MODE_TYPE)) {\n                return (uiMode & MASK_UI_MODE_TYPE);\n            }\n            if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0\n                    && (requested->uiMode & MASK_UI_MODE_NIGHT)) {\n                return (uiMode & MASK_UI_MODE_NIGHT);\n            }\n        }\n\n        if (screenType || o.screenType) {\n            if (density != o.density) {\n                // Use the system default density (DENSITY_MEDIUM, 160dpi) if none specified.\n                const int thisDensity = density ? density : int(ResTable_config::DENSITY_MEDIUM);\n                const int otherDensity = o.density ? o.density : int(ResTable_config::DENSITY_MEDIUM);\n\n                // We always prefer DENSITY_ANY over scaling a density bucket.\n                if (thisDensity == ResTable_config::DENSITY_ANY) {\n                    return true;\n                } else if (otherDensity == ResTable_config::DENSITY_ANY) {\n                    return false;\n                }\n\n                int requestedDensity = requested->density;\n                if (requested->density == 0 ||\n                        requested->density == ResTable_config::DENSITY_ANY) {\n                    requestedDensity = ResTable_config::DENSITY_MEDIUM;\n                }\n\n                // DENSITY_ANY is now dealt with. We should look to\n                // pick a density bucket and potentially scale it.\n                // Any density is potentially useful\n                // because the system will scale it.  Scaling down\n                // is generally better than scaling up.\n                int h = thisDensity;\n                int l = otherDensity;\n                bool bImBigger = true;\n                if (l > h) {\n                    int t = h;\n                    h = l;\n                    l = t;\n                    bImBigger = false;\n                }\n\n                if (requestedDensity >= h) {\n                    // requested value higher than both l and h, give h\n                    return bImBigger;\n                }\n                if (l >= requestedDensity) {\n                    // requested value lower than both l and h, give l\n                    return !bImBigger;\n                }\n                // saying that scaling down is 2x better than up\n                if (((2 * l) - requestedDensity) * h > requestedDensity * requestedDensity) {\n                    return !bImBigger;\n                } else {\n                    return bImBigger;\n                }\n            }\n\n            if ((touchscreen != o.touchscreen) && requested->touchscreen) {\n                return (touchscreen);\n            }\n        }\n\n        if (input || o.input) {\n            const int keysHidden = inputFlags & MASK_KEYSHIDDEN;\n            const int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN;\n            if (keysHidden != oKeysHidden) {\n                const int reqKeysHidden =\n                        requested->inputFlags & MASK_KEYSHIDDEN;\n                if (reqKeysHidden) {\n\n                    if (!keysHidden) return false;\n                    if (!oKeysHidden) return true;\n                    // For compatibility, we count KEYSHIDDEN_NO as being\n                    // the same as KEYSHIDDEN_SOFT.  Here we disambiguate\n                    // these by making an exact match more specific.\n                    if (reqKeysHidden == keysHidden) return true;\n                    if (reqKeysHidden == oKeysHidden) return false;\n                }\n            }\n\n            const int navHidden = inputFlags & MASK_NAVHIDDEN;\n            const int oNavHidden = o.inputFlags & MASK_NAVHIDDEN;\n            if (navHidden != oNavHidden) {\n                const int reqNavHidden =\n                        requested->inputFlags & MASK_NAVHIDDEN;\n                if (reqNavHidden) {\n\n                    if (!navHidden) return false;\n                    if (!oNavHidden) return true;\n                }\n            }\n\n            if ((keyboard != o.keyboard) && requested->keyboard) {\n                return (keyboard);\n            }\n\n            if ((navigation != o.navigation) && requested->navigation) {\n                return (navigation);\n            }\n        }\n\n        if (screenSize || o.screenSize) {\n            // \"Better\" is based on the sum of the difference between both\n            // width and height from the requested dimensions.  We are\n            // assuming the invalid configs (with smaller sizes) have\n            // already been filtered.  Note that if a particular dimension\n            // is unspecified, we will end up with a large value (the\n            // difference between 0 and the requested dimension), which is\n            // good since we will prefer a config that has specified a\n            // size value.\n            int myDelta = 0, otherDelta = 0;\n            if (requested->screenWidth) {\n                myDelta += requested->screenWidth - screenWidth;\n                otherDelta += requested->screenWidth - o.screenWidth;\n            }\n            if (requested->screenHeight) {\n                myDelta += requested->screenHeight - screenHeight;\n                otherDelta += requested->screenHeight - o.screenHeight;\n            }\n            if (myDelta != otherDelta) {\n                return myDelta < otherDelta;\n            }\n        }\n\n        if (version || o.version) {\n            if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {\n                return (sdkVersion > o.sdkVersion);\n            }\n\n            if ((minorVersion != o.minorVersion) &&\n                    requested->minorVersion) {\n                return (minorVersion);\n            }\n        }\n\n        return false;\n    }\n    return isMoreSpecificThan(o);\n}\n\nbool ResTable_config::match(const ResTable_config& settings) const {\n    if (imsi != 0) {\n        if (mcc != 0 && mcc != settings.mcc) {\n            return false;\n        }\n        if (mnc != 0 && mnc != settings.mnc) {\n            return false;\n        }\n    }\n    if (locale != 0) {\n        // Don't consider country and variants when deciding matches.\n        // (Theoretically, the variant can also affect the script. For\n        // example, \"ar-alalc97\" probably implies the Latin script, but since\n        // CLDR doesn't support getting likely scripts for that, we'll assume\n        // the variant doesn't change the script.)\n        //\n        // If two configs differ only in their country and variant,\n        // they can be weeded out in the isMoreSpecificThan test.\n        if (language[0] != settings.language[0] || language[1] != settings.language[1]) {\n            return false;\n        }\n\n        // For backward compatibility and supporting private-use locales, we\n        // fall back to old behavior if we couldn't determine the script for\n        // either of the desired locale or the provided locale. But if we could determine\n        // the scripts, they should be the same for the locales to match.\n        bool countriesMustMatch = false;\n        char computed_script[4];\n        const char* script;\n        if (settings.localeScript[0] == '\\0') { // could not determine the request's script\n            countriesMustMatch = true;\n        } else {\n            if (localeScript[0] == '\\0' && !localeScriptWasComputed) {\n                // script was not provided or computed, so we try to compute it\n                localeDataComputeScript(computed_script, language, country);\n                if (computed_script[0] == '\\0') { // we could not compute the script\n                    countriesMustMatch = true;\n                } else {\n                    script = computed_script;\n                }\n            } else { // script was provided, so just use it\n                script = localeScript;\n            }\n        }\n\n        if (countriesMustMatch) {\n            if (country[0] != '\\0'\n                && (country[0] != settings.country[0]\n                    || country[1] != settings.country[1])) {\n                return false;\n            }\n        } else {\n            if (memcmp(script, settings.localeScript, sizeof(settings.localeScript)) != 0) {\n                return false;\n            }\n        }\n    }\n\n    if (screenConfig != 0) {\n        const int layoutDir = screenLayout&MASK_LAYOUTDIR;\n        const int setLayoutDir = settings.screenLayout&MASK_LAYOUTDIR;\n        if (layoutDir != 0 && layoutDir != setLayoutDir) {\n            return false;\n        }\n\n        const int screenSize = screenLayout&MASK_SCREENSIZE;\n        const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;\n        // Any screen sizes for larger screens than the setting do not\n        // match.\n        if (screenSize != 0 && screenSize > setScreenSize) {\n            return false;\n        }\n\n        const int screenLong = screenLayout&MASK_SCREENLONG;\n        const int setScreenLong = settings.screenLayout&MASK_SCREENLONG;\n        if (screenLong != 0 && screenLong != setScreenLong) {\n            return false;\n        }\n\n        const int uiModeType = uiMode&MASK_UI_MODE_TYPE;\n        const int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE;\n        if (uiModeType != 0 && uiModeType != setUiModeType) {\n            return false;\n        }\n\n        const int uiModeNight = uiMode&MASK_UI_MODE_NIGHT;\n        const int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT;\n        if (uiModeNight != 0 && uiModeNight != setUiModeNight) {\n            return false;\n        }\n\n        if (smallestScreenWidthDp != 0\n                && smallestScreenWidthDp > settings.smallestScreenWidthDp) {\n            return false;\n        }\n    }\n\n    if (screenConfig2 != 0) {\n        const int screenRound = screenLayout2 & MASK_SCREENROUND;\n        const int setScreenRound = settings.screenLayout2 & MASK_SCREENROUND;\n        if (screenRound != 0 && screenRound != setScreenRound) {\n            return false;\n        }\n    }\n\n    if (screenSizeDp != 0) {\n        if (screenWidthDp != 0 && screenWidthDp > settings.screenWidthDp) {\n            if (kDebugTableSuperNoisy) {\n                ALOGI(\"Filtering out width %d in requested %d\", screenWidthDp,\n                        settings.screenWidthDp);\n            }\n            return false;\n        }\n        if (screenHeightDp != 0 && screenHeightDp > settings.screenHeightDp) {\n            if (kDebugTableSuperNoisy) {\n                ALOGI(\"Filtering out height %d in requested %d\", screenHeightDp,\n                        settings.screenHeightDp);\n            }\n            return false;\n        }\n    }\n    if (screenType != 0) {\n        if (orientation != 0 && orientation != settings.orientation) {\n            return false;\n        }\n        // density always matches - we can scale it.  See isBetterThan\n        if (touchscreen != 0 && touchscreen != settings.touchscreen) {\n            return false;\n        }\n    }\n    if (input != 0) {\n        const int keysHidden = inputFlags&MASK_KEYSHIDDEN;\n        const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;\n        if (keysHidden != 0 && keysHidden != setKeysHidden) {\n            // For compatibility, we count a request for KEYSHIDDEN_NO as also\n            // matching the more recent KEYSHIDDEN_SOFT.  Basically\n            // KEYSHIDDEN_NO means there is some kind of keyboard available.\n            if (kDebugTableSuperNoisy) {\n                ALOGI(\"Matching keysHidden: have=%d, config=%d\\n\", keysHidden, setKeysHidden);\n            }\n            if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) {\n                if (kDebugTableSuperNoisy) {\n                    ALOGI(\"No match!\");\n                }\n                return false;\n            }\n        }\n        const int navHidden = inputFlags&MASK_NAVHIDDEN;\n        const int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN;\n        if (navHidden != 0 && navHidden != setNavHidden) {\n            return false;\n        }\n        if (keyboard != 0 && keyboard != settings.keyboard) {\n            return false;\n        }\n        if (navigation != 0 && navigation != settings.navigation) {\n            return false;\n        }\n    }\n    if (screenSize != 0) {\n        if (screenWidth != 0 && screenWidth > settings.screenWidth) {\n            return false;\n        }\n        if (screenHeight != 0 && screenHeight > settings.screenHeight) {\n            return false;\n        }\n    }\n    if (version != 0) {\n        if (sdkVersion != 0 && sdkVersion > settings.sdkVersion) {\n            return false;\n        }\n        if (minorVersion != 0 && minorVersion != settings.minorVersion) {\n            return false;\n        }\n    }\n    return true;\n}\n\nvoid ResTable_config::appendDirLocale(String8& out) const {\n    if (!language[0]) {\n        return;\n    }\n    const bool scriptWasProvided = localeScript[0] != '\\0' && !localeScriptWasComputed;\n    if (!scriptWasProvided && !localeVariant[0]) {\n        // Legacy format.\n        if (out.size() > 0) {\n            out.append(\"-\");\n        }\n\n        char buf[4];\n        size_t len = unpackLanguage(buf);\n        out.append(buf, len);\n\n        if (country[0]) {\n            out.append(\"-r\");\n            len = unpackRegion(buf);\n            out.append(buf, len);\n        }\n        return;\n    }\n\n    // We are writing the modified BCP 47 tag.\n    // It starts with 'b+' and uses '+' as a separator.\n\n    if (out.size() > 0) {\n        out.append(\"-\");\n    }\n    out.append(\"b+\");\n\n    char buf[4];\n    size_t len = unpackLanguage(buf);\n    out.append(buf, len);\n\n    if (scriptWasProvided) {\n        out.append(\"+\");\n        out.append(localeScript, sizeof(localeScript));\n    }\n\n    if (country[0]) {\n        out.append(\"+\");\n        len = unpackRegion(buf);\n        out.append(buf, len);\n    }\n\n    if (localeVariant[0]) {\n        out.append(\"+\");\n        out.append(localeVariant, strnlen(localeVariant, sizeof(localeVariant)));\n    }\n}\n\nvoid ResTable_config::getBcp47Locale(char str[RESTABLE_MAX_LOCALE_LEN]) const {\n    memset(str, 0, RESTABLE_MAX_LOCALE_LEN);\n\n    // This represents the \"any\" locale value, which has traditionally been\n    // represented by the empty string.\n    if (!language[0] && !country[0]) {\n        return;\n    }\n\n    size_t charsWritten = 0;\n    if (language[0]) {\n        charsWritten += unpackLanguage(str);\n    }\n\n    if (localeScript[0] && !localeScriptWasComputed) {\n        if (charsWritten) {\n            str[charsWritten++] = '-';\n        }\n        memcpy(str + charsWritten, localeScript, sizeof(localeScript));\n        charsWritten += sizeof(localeScript);\n    }\n\n    if (country[0]) {\n        if (charsWritten) {\n            str[charsWritten++] = '-';\n        }\n        charsWritten += unpackRegion(str + charsWritten);\n    }\n\n    if (localeVariant[0]) {\n        if (charsWritten) {\n            str[charsWritten++] = '-';\n        }\n        memcpy(str + charsWritten, localeVariant, sizeof(localeVariant));\n    }\n}\n\n/* static */ inline bool assignLocaleComponent(ResTable_config* config,\n        const char* start, size_t size) {\n\n  switch (size) {\n       case 0:\n           return false;\n       case 2:\n       case 3:\n           config->language[0] ? config->packRegion(start) : config->packLanguage(start);\n           break;\n       case 4:\n           if ('0' <= start[0] && start[0] <= '9') {\n               // this is a variant, so fall through\n           } else {\n               config->localeScript[0] = toupper(start[0]);\n               for (size_t i = 1; i < 4; ++i) {\n                   config->localeScript[i] = tolower(start[i]);\n               }\n               break;\n           }\n       case 5:\n       case 6:\n       case 7:\n       case 8:\n           for (size_t i = 0; i < size; ++i) {\n               config->localeVariant[i] = tolower(start[i]);\n           }\n           break;\n       default:\n           return false;\n  }\n\n  return true;\n}\n\nvoid ResTable_config::setBcp47Locale(const char* in) {\n    locale = 0;\n    memset(localeScript, 0, sizeof(localeScript));\n    memset(localeVariant, 0, sizeof(localeVariant));\n\n    const char* separator = in;\n    const char* start = in;\n    while ((separator = strchr(start, '-')) != NULL) {\n        const size_t size = separator - start;\n        if (!assignLocaleComponent(this, start, size)) {\n            fprintf(stderr, \"Invalid BCP-47 locale string: %s\", in);\n        }\n\n        start = (separator + 1);\n    }\n\n    const size_t size = in + strlen(in) - start;\n    assignLocaleComponent(this, start, size);\n    localeScriptWasComputed = (localeScript[0] == '\\0');\n    if (localeScriptWasComputed) {\n        computeScript();\n    }\n}\n\nString8 ResTable_config::toString() const {\n    String8 res;\n\n    if (mcc != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.appendFormat(\"mcc%d\", dtohs(mcc));\n    }\n    if (mnc != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.appendFormat(\"mnc%d\", dtohs(mnc));\n    }\n\n    appendDirLocale(res);\n\n    if ((screenLayout&MASK_LAYOUTDIR) != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (screenLayout&ResTable_config::MASK_LAYOUTDIR) {\n            case ResTable_config::LAYOUTDIR_LTR:\n                res.append(\"ldltr\");\n                break;\n            case ResTable_config::LAYOUTDIR_RTL:\n                res.append(\"ldrtl\");\n                break;\n            default:\n                res.appendFormat(\"layoutDir=%d\",\n                        dtohs(screenLayout&ResTable_config::MASK_LAYOUTDIR));\n                break;\n        }\n    }\n    if (smallestScreenWidthDp != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.appendFormat(\"sw%ddp\", dtohs(smallestScreenWidthDp));\n    }\n    if (screenWidthDp != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.appendFormat(\"w%ddp\", dtohs(screenWidthDp));\n    }\n    if (screenHeightDp != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.appendFormat(\"h%ddp\", dtohs(screenHeightDp));\n    }\n    if ((screenLayout&MASK_SCREENSIZE) != SCREENSIZE_ANY) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (screenLayout&ResTable_config::MASK_SCREENSIZE) {\n            case ResTable_config::SCREENSIZE_SMALL:\n                res.append(\"small\");\n                break;\n            case ResTable_config::SCREENSIZE_NORMAL:\n                res.append(\"normal\");\n                break;\n            case ResTable_config::SCREENSIZE_LARGE:\n                res.append(\"large\");\n                break;\n            case ResTable_config::SCREENSIZE_XLARGE:\n                res.append(\"xlarge\");\n                break;\n            default:\n                res.appendFormat(\"screenLayoutSize=%d\",\n                        dtohs(screenLayout&ResTable_config::MASK_SCREENSIZE));\n                break;\n        }\n    }\n    if ((screenLayout&MASK_SCREENLONG) != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (screenLayout&ResTable_config::MASK_SCREENLONG) {\n            case ResTable_config::SCREENLONG_NO:\n                res.append(\"notlong\");\n                break;\n            case ResTable_config::SCREENLONG_YES:\n                res.append(\"long\");\n                break;\n            default:\n                res.appendFormat(\"screenLayoutLong=%d\",\n                        dtohs(screenLayout&ResTable_config::MASK_SCREENLONG));\n                break;\n        }\n    }\n    if ((screenLayout2&MASK_SCREENROUND) != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (screenLayout2&MASK_SCREENROUND) {\n            case SCREENROUND_NO:\n                res.append(\"notround\");\n                break;\n            case SCREENROUND_YES:\n                res.append(\"round\");\n                break;\n            default:\n                res.appendFormat(\"screenRound=%d\", dtohs(screenLayout2&MASK_SCREENROUND));\n                break;\n        }\n    }\n    if (orientation != ORIENTATION_ANY) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (orientation) {\n            case ResTable_config::ORIENTATION_PORT:\n                res.append(\"port\");\n                break;\n            case ResTable_config::ORIENTATION_LAND:\n                res.append(\"land\");\n                break;\n            case ResTable_config::ORIENTATION_SQUARE:\n                res.append(\"square\");\n                break;\n            default:\n                res.appendFormat(\"orientation=%d\", dtohs(orientation));\n                break;\n        }\n    }\n    if ((uiMode&MASK_UI_MODE_TYPE) != UI_MODE_TYPE_ANY) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (uiMode&ResTable_config::MASK_UI_MODE_TYPE) {\n            case ResTable_config::UI_MODE_TYPE_DESK:\n                res.append(\"desk\");\n                break;\n            case ResTable_config::UI_MODE_TYPE_CAR:\n                res.append(\"car\");\n                break;\n            case ResTable_config::UI_MODE_TYPE_TELEVISION:\n                res.append(\"television\");\n                break;\n            case ResTable_config::UI_MODE_TYPE_APPLIANCE:\n                res.append(\"appliance\");\n                break;\n            case ResTable_config::UI_MODE_TYPE_WATCH:\n                res.append(\"watch\");\n                break;\n            default:\n                res.appendFormat(\"uiModeType=%d\",\n                        dtohs(screenLayout&ResTable_config::MASK_UI_MODE_TYPE));\n                break;\n        }\n    }\n    if ((uiMode&MASK_UI_MODE_NIGHT) != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (uiMode&ResTable_config::MASK_UI_MODE_NIGHT) {\n            case ResTable_config::UI_MODE_NIGHT_NO:\n                res.append(\"notnight\");\n                break;\n            case ResTable_config::UI_MODE_NIGHT_YES:\n                res.append(\"night\");\n                break;\n            default:\n                res.appendFormat(\"uiModeNight=%d\",\n                        dtohs(uiMode&MASK_UI_MODE_NIGHT));\n                break;\n        }\n    }\n    if (density != DENSITY_DEFAULT) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (density) {\n            case ResTable_config::DENSITY_LOW:\n                res.append(\"ldpi\");\n                break;\n            case ResTable_config::DENSITY_MEDIUM:\n                res.append(\"mdpi\");\n                break;\n            case ResTable_config::DENSITY_TV:\n                res.append(\"tvdpi\");\n                break;\n            case ResTable_config::DENSITY_HIGH:\n                res.append(\"hdpi\");\n                break;\n            case ResTable_config::DENSITY_XHIGH:\n                res.append(\"xhdpi\");\n                break;\n            case ResTable_config::DENSITY_XXHIGH:\n                res.append(\"xxhdpi\");\n                break;\n            case ResTable_config::DENSITY_XXXHIGH:\n                res.append(\"xxxhdpi\");\n                break;\n            case ResTable_config::DENSITY_NONE:\n                res.append(\"nodpi\");\n                break;\n            case ResTable_config::DENSITY_ANY:\n                res.append(\"anydpi\");\n                break;\n            default:\n                res.appendFormat(\"%ddpi\", dtohs(density));\n                break;\n        }\n    }\n    if (touchscreen != TOUCHSCREEN_ANY) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (touchscreen) {\n            case ResTable_config::TOUCHSCREEN_NOTOUCH:\n                res.append(\"notouch\");\n                break;\n            case ResTable_config::TOUCHSCREEN_FINGER:\n                res.append(\"finger\");\n                break;\n            case ResTable_config::TOUCHSCREEN_STYLUS:\n                res.append(\"stylus\");\n                break;\n            default:\n                res.appendFormat(\"touchscreen=%d\", dtohs(touchscreen));\n                break;\n        }\n    }\n    if ((inputFlags&MASK_KEYSHIDDEN) != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (inputFlags&MASK_KEYSHIDDEN) {\n            case ResTable_config::KEYSHIDDEN_NO:\n                res.append(\"keysexposed\");\n                break;\n            case ResTable_config::KEYSHIDDEN_YES:\n                res.append(\"keyshidden\");\n                break;\n            case ResTable_config::KEYSHIDDEN_SOFT:\n                res.append(\"keyssoft\");\n                break;\n        }\n    }\n    if (keyboard != KEYBOARD_ANY) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (keyboard) {\n            case ResTable_config::KEYBOARD_NOKEYS:\n                res.append(\"nokeys\");\n                break;\n            case ResTable_config::KEYBOARD_QWERTY:\n                res.append(\"qwerty\");\n                break;\n            case ResTable_config::KEYBOARD_12KEY:\n                res.append(\"12key\");\n                break;\n            default:\n                res.appendFormat(\"keyboard=%d\", dtohs(keyboard));\n                break;\n        }\n    }\n    if ((inputFlags&MASK_NAVHIDDEN) != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (inputFlags&MASK_NAVHIDDEN) {\n            case ResTable_config::NAVHIDDEN_NO:\n                res.append(\"navexposed\");\n                break;\n            case ResTable_config::NAVHIDDEN_YES:\n                res.append(\"navhidden\");\n                break;\n            default:\n                res.appendFormat(\"inputFlagsNavHidden=%d\",\n                        dtohs(inputFlags&MASK_NAVHIDDEN));\n                break;\n        }\n    }\n    if (navigation != NAVIGATION_ANY) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (navigation) {\n            case ResTable_config::NAVIGATION_NONAV:\n                res.append(\"nonav\");\n                break;\n            case ResTable_config::NAVIGATION_DPAD:\n                res.append(\"dpad\");\n                break;\n            case ResTable_config::NAVIGATION_TRACKBALL:\n                res.append(\"trackball\");\n                break;\n            case ResTable_config::NAVIGATION_WHEEL:\n                res.append(\"wheel\");\n                break;\n            default:\n                res.appendFormat(\"navigation=%d\", dtohs(navigation));\n                break;\n        }\n    }\n    if (screenSize != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.appendFormat(\"%dx%d\", dtohs(screenWidth), dtohs(screenHeight));\n    }\n    if (version != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.appendFormat(\"v%d\", dtohs(sdkVersion));\n        if (minorVersion != 0) {\n            res.appendFormat(\".%d\", dtohs(minorVersion));\n        }\n    }\n\n    return res;\n}\n\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n\nstruct ResTable::Header\n{\n    Header(ResTable* _owner) : owner(_owner), ownedData(NULL), header(NULL),\n        resourceIDMap(NULL), resourceIDMapSize(0) { }\n\n    ~Header()\n    {\n        free(resourceIDMap);\n    }\n\n    const ResTable* const           owner;\n    void*                           ownedData;\n    const ResTable_header*          header;\n    size_t                          size;\n    const uint8_t*                  dataEnd;\n    size_t                          index;\n    int32_t                         cookie;\n\n    ResStringPool                   values;\n    uint32_t*                       resourceIDMap;\n    size_t                          resourceIDMapSize;\n};\n\nstruct ResTable::Entry {\n    ResTable_config config;\n    const ResTable_entry* entry;\n    const ResTable_type* type;\n    uint32_t specFlags;\n    const Package* package;\n\n    StringPoolRef typeStr;\n    StringPoolRef keyStr;\n};\n\nstruct ResTable::Type\n{\n    Type(const Header* _header, const Package* _package, size_t count)\n        : header(_header), package(_package), entryCount(count),\n          typeSpec(NULL), typeSpecFlags(NULL) { }\n    const Header* const             header;\n    const Package* const            package;\n    const size_t                    entryCount;\n    const ResTable_typeSpec*        typeSpec;\n    const uint32_t*                 typeSpecFlags;\n    IdmapEntries                    idmapEntries;\n    Vector<const ResTable_type*>    configs;\n};\n\nstruct ResTable::Package\n{\n    Package(ResTable* _owner, const Header* _header, const ResTable_package* _package)\n        : owner(_owner), header(_header), package(_package), typeIdOffset(0) {\n        if (dtohs(package->header.headerSize) == sizeof(package)) {\n            // The package structure is the same size as the definition.\n            // This means it contains the typeIdOffset field.\n            typeIdOffset = package->typeIdOffset;\n        }\n    }\n\n    const ResTable* const           owner;\n    const Header* const             header;\n    const ResTable_package* const   package;\n\n    ResStringPool                   typeStrings;\n    ResStringPool                   keyStrings;\n\n    size_t                          typeIdOffset;\n};\n\n// A group of objects describing a particular resource package.\n// The first in 'package' is always the root object (from the resource\n// table that defined the package); the ones after are skins on top of it.\nstruct ResTable::PackageGroup\n{\n    PackageGroup(\n            ResTable* _owner, const String16& _name, uint32_t _id,\n            bool appAsLib, bool _isSystemAsset)\n        : owner(_owner)\n        , name(_name)\n        , id(_id)\n        , largestTypeId(0)\n        , dynamicRefTable(static_cast<uint8_t>(_id), appAsLib)\n        , isSystemAsset(_isSystemAsset)\n    { }\n\n    ~PackageGroup() {\n        clearBagCache();\n        const size_t numTypes = types.size();\n        for (size_t i = 0; i < numTypes; i++) {\n            const TypeList& typeList = types[i];\n            const size_t numInnerTypes = typeList.size();\n            for (size_t j = 0; j < numInnerTypes; j++) {\n                if (typeList[j]->package->owner == owner) {\n                    delete typeList[j];\n                }\n            }\n        }\n\n        const size_t N = packages.size();\n        for (size_t i=0; i<N; i++) {\n            Package* pkg = packages[i];\n            if (pkg->owner == owner) {\n                delete pkg;\n            }\n        }\n    }\n\n    /**\n     * Clear all cache related data that depends on parameters/configuration.\n     * This includes the bag caches and filtered types.\n     */\n    void clearBagCache() {\n        for (size_t i = 0; i < typeCacheEntries.size(); i++) {\n            if (kDebugTableNoisy) {\n                printf(\"type=%zu\\n\", i);\n            }\n            const TypeList& typeList = types[i];\n            if (!typeList.isEmpty()) {\n                TypeCacheEntry& cacheEntry = typeCacheEntries.editItemAt(i);\n\n                // Reset the filtered configurations.\n                cacheEntry.filteredConfigs.clear();\n\n                bag_set** typeBags = cacheEntry.cachedBags;\n                if (kDebugTableNoisy) {\n                    printf(\"typeBags=%p\\n\", typeBags);\n                }\n\n                if (typeBags) {\n                    const size_t N = typeList[0]->entryCount;\n                    if (kDebugTableNoisy) {\n                        printf(\"type->entryCount=%zu\\n\", N);\n                    }\n                    for (size_t j = 0; j < N; j++) {\n                        if (typeBags[j] && typeBags[j] != (bag_set*)0xFFFFFFFF) {\n                            free(typeBags[j]);\n                        }\n                    }\n                    free(typeBags);\n                    cacheEntry.cachedBags = NULL;\n                }\n            }\n        }\n    }\n\n    ssize_t findType16(const char16_t* type, size_t len) const {\n        const size_t N = packages.size();\n        for (size_t i = 0; i < N; i++) {\n            ssize_t index = packages[i]->typeStrings.indexOfString(type, len);\n            if (index >= 0) {\n                return index + packages[i]->typeIdOffset;\n            }\n        }\n        return -1;\n    }\n\n    const ResTable* const           owner;\n    String16 const                  name;\n    uint32_t const                  id;\n\n    // This is mainly used to keep track of the loaded packages\n    // and to clean them up properly. Accessing resources happens from\n    // the 'types' array.\n    Vector<Package*>                packages;\n\n    ByteBucketArray<TypeList>       types;\n\n    uint8_t                         largestTypeId;\n\n    // Cached objects dependent on the parameters/configuration of this ResTable.\n    // Gets cleared whenever the parameters/configuration changes.\n    // These are stored here in a parallel structure because the data in `types` may\n    // be shared by other ResTable's (framework resources are shared this way).\n    ByteBucketArray<TypeCacheEntry> typeCacheEntries;\n\n    // The table mapping dynamic references to resolved references for\n    // this package group.\n    // TODO: We may be able to support dynamic references in overlays\n    // by having these tables in a per-package scope rather than\n    // per-package-group.\n    DynamicRefTable                 dynamicRefTable;\n\n    // If the package group comes from a system asset. Used in\n    // determining non-system locales.\n    const bool                      isSystemAsset;\n};\n\nResTable::Theme::Theme(const ResTable& table)\n    : mTable(table)\n    , mTypeSpecFlags(0)\n{\n    memset(mPackages, 0, sizeof(mPackages));\n}\n\nResTable::Theme::~Theme()\n{\n    for (size_t i=0; i<Res_MAXPACKAGE; i++) {\n        package_info* pi = mPackages[i];\n        if (pi != NULL) {\n            free_package(pi);\n        }\n    }\n}\n\nvoid ResTable::Theme::free_package(package_info* pi)\n{\n    for (size_t j = 0; j <= Res_MAXTYPE; j++) {\n        theme_entry* te = pi->types[j].entries;\n        if (te != NULL) {\n            free(te);\n        }\n    }\n    free(pi);\n}\n\nResTable::Theme::package_info* ResTable::Theme::copy_package(package_info* pi)\n{\n    package_info* newpi = (package_info*)malloc(sizeof(package_info));\n    for (size_t j = 0; j <= Res_MAXTYPE; j++) {\n        size_t cnt = pi->types[j].numEntries;\n        newpi->types[j].numEntries = cnt;\n        theme_entry* te = pi->types[j].entries;\n        size_t cnt_max = SIZE_MAX / sizeof(theme_entry);\n        if (te != NULL && (cnt < 0xFFFFFFFF-1) && (cnt < cnt_max)) {\n            theme_entry* newte = (theme_entry*)malloc(cnt*sizeof(theme_entry));\n            newpi->types[j].entries = newte;\n            memcpy(newte, te, cnt*sizeof(theme_entry));\n        } else {\n            newpi->types[j].entries = NULL;\n        }\n    }\n    return newpi;\n}\n\nstatus_t ResTable::Theme::applyStyle(uint32_t resID, bool force)\n{\n    const bag_entry* bag;\n    uint32_t bagTypeSpecFlags = 0;\n    mTable.lock();\n    const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags);\n    if (kDebugTableNoisy) {\n        ALOGV(\"Applying style 0x%08x to theme %p, count=%zu\", resID, this, N);\n    }\n    if (N < 0) {\n        mTable.unlock();\n        return N;\n    }\n\n    mTypeSpecFlags |= bagTypeSpecFlags;\n\n    uint32_t curPackage = 0xffffffff;\n    ssize_t curPackageIndex = 0;\n    package_info* curPI = NULL;\n    uint32_t curType = 0xffffffff;\n    size_t numEntries = 0;\n    theme_entry* curEntries = NULL;\n\n    const bag_entry* end = bag + N;\n    while (bag < end) {\n        const uint32_t attrRes = bag->map.name.ident;\n        const uint32_t p = Res_GETPACKAGE(attrRes);\n        const uint32_t t = Res_GETTYPE(attrRes);\n        const uint32_t e = Res_GETENTRY(attrRes);\n\n        if (curPackage != p) {\n            const ssize_t pidx = mTable.getResourcePackageIndex(attrRes);\n            if (pidx < 0) {\n                ALOGE(\"Style contains key with bad package: 0x%08x\\n\", attrRes);\n                bag++;\n                continue;\n            }\n            curPackage = p;\n            curPackageIndex = pidx;\n            curPI = mPackages[pidx];\n            if (curPI == NULL) {\n                curPI = (package_info*)malloc(sizeof(package_info));\n                memset(curPI, 0, sizeof(*curPI));\n                mPackages[pidx] = curPI;\n            }\n            curType = 0xffffffff;\n        }\n        if (curType != t) {\n            if (t > Res_MAXTYPE) {\n                ALOGE(\"Style contains key with bad type: 0x%08x\\n\", attrRes);\n                bag++;\n                continue;\n            }\n            curType = t;\n            curEntries = curPI->types[t].entries;\n            if (curEntries == NULL) {\n                PackageGroup* const grp = mTable.mPackageGroups[curPackageIndex];\n                const TypeList& typeList = grp->types[t];\n                size_t cnt = typeList.isEmpty() ? 0 : typeList[0]->entryCount;\n                size_t cnt_max = SIZE_MAX / sizeof(theme_entry);\n                size_t buff_size = (cnt < cnt_max && cnt < 0xFFFFFFFF-1) ?\n                                          cnt*sizeof(theme_entry) : 0;\n                curEntries = (theme_entry*)malloc(buff_size);\n                memset(curEntries, Res_value::TYPE_NULL, buff_size);\n                curPI->types[t].numEntries = cnt;\n                curPI->types[t].entries = curEntries;\n            }\n            numEntries = curPI->types[t].numEntries;\n        }\n        if (e >= numEntries) {\n            ALOGE(\"Style contains key with bad entry: 0x%08x\\n\", attrRes);\n            bag++;\n            continue;\n        }\n        theme_entry* curEntry = curEntries + e;\n        if (kDebugTableNoisy) {\n            ALOGV(\"Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x\",\n                    attrRes, bag->map.value.dataType, bag->map.value.data,\n                    curEntry->value.dataType);\n        }\n        if (force || curEntry->value.dataType == Res_value::TYPE_NULL) {\n            curEntry->stringBlock = bag->stringBlock;\n            curEntry->typeSpecFlags |= bagTypeSpecFlags;\n            curEntry->value = bag->map.value;\n        }\n\n        bag++;\n    }\n\n    mTable.unlock();\n\n    if (kDebugTableTheme) {\n        ALOGI(\"Applying style 0x%08x (force=%d)  theme %p...\\n\", resID, force, this);\n        dumpToLog();\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t ResTable::Theme::setTo(const Theme& other)\n{\n    if (kDebugTableTheme) {\n        ALOGI(\"Setting theme %p from theme %p...\\n\", this, &other);\n        dumpToLog();\n        other.dumpToLog();\n    }\n\n    if (&mTable == &other.mTable) {\n        for (size_t i=0; i<Res_MAXPACKAGE; i++) {\n            if (mPackages[i] != NULL) {\n                free_package(mPackages[i]);\n            }\n            if (other.mPackages[i] != NULL) {\n                mPackages[i] = copy_package(other.mPackages[i]);\n            } else {\n                mPackages[i] = NULL;\n            }\n        }\n    } else {\n        // @todo: need to really implement this, not just copy\n        // the system package (which is still wrong because it isn't\n        // fixing up resource references).\n        for (size_t i=0; i<Res_MAXPACKAGE; i++) {\n            if (mPackages[i] != NULL) {\n                free_package(mPackages[i]);\n            }\n            if (i == 0 && other.mPackages[i] != NULL) {\n                mPackages[i] = copy_package(other.mPackages[i]);\n            } else {\n                mPackages[i] = NULL;\n            }\n        }\n    }\n\n    mTypeSpecFlags = other.mTypeSpecFlags;\n\n    if (kDebugTableTheme) {\n        ALOGI(\"Final theme:\");\n        dumpToLog();\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t ResTable::Theme::clear()\n{\n    if (kDebugTableTheme) {\n        ALOGI(\"Clearing theme %p...\\n\", this);\n        dumpToLog();\n    }\n\n    for (size_t i = 0; i < Res_MAXPACKAGE; i++) {\n        if (mPackages[i] != NULL) {\n            free_package(mPackages[i]);\n            mPackages[i] = NULL;\n        }\n    }\n\n    mTypeSpecFlags = 0;\n\n    if (kDebugTableTheme) {\n        ALOGI(\"Final theme:\");\n        dumpToLog();\n    }\n\n    return NO_ERROR;\n}\n\nssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue,\n        uint32_t* outTypeSpecFlags) const\n{\n    int cnt = 20;\n\n    if (outTypeSpecFlags != NULL) *outTypeSpecFlags = 0;\n\n    do {\n        const ssize_t p = mTable.getResourcePackageIndex(resID);\n        const uint32_t t = Res_GETTYPE(resID);\n        const uint32_t e = Res_GETENTRY(resID);\n\n        if (kDebugTableTheme) {\n            ALOGI(\"Looking up attr 0x%08x in theme %p\", resID, this);\n        }\n\n        if (p >= 0) {\n            const package_info* const pi = mPackages[p];\n            if (kDebugTableTheme) {\n                ALOGI(\"Found package: %p\", pi);\n            }\n            if (pi != NULL) {\n                if (kDebugTableTheme) {\n                    ALOGI(\"Desired type index is %zd in avail %zu\", t, Res_MAXTYPE + 1);\n                }\n                if (t <= Res_MAXTYPE) {\n                    const type_info& ti = pi->types[t];\n                    if (kDebugTableTheme) {\n                        ALOGI(\"Desired entry index is %u in avail %zu\", e, ti.numEntries);\n                    }\n                    if (e < ti.numEntries) {\n                        const theme_entry& te = ti.entries[e];\n                        if (outTypeSpecFlags != NULL) {\n                            *outTypeSpecFlags |= te.typeSpecFlags;\n                        }\n                        if (kDebugTableTheme) {\n                            ALOGI(\"Theme value: type=0x%x, data=0x%08x\",\n                                    te.value.dataType, te.value.data);\n                        }\n                        const uint8_t type = te.value.dataType;\n                        if (type == Res_value::TYPE_ATTRIBUTE) {\n                            if (cnt > 0) {\n                                cnt--;\n                                resID = te.value.data;\n                                continue;\n                            }\n                            ALOGW(\"Too many attribute references, stopped at: 0x%08x\\n\", resID);\n                            return BAD_INDEX;\n                        } else if (type != Res_value::TYPE_NULL) {\n                            *outValue = te.value;\n                            return te.stringBlock;\n                        }\n                        return BAD_INDEX;\n                    }\n                }\n            }\n        }\n        break;\n\n    } while (true);\n\n    return BAD_INDEX;\n}\n\nssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue,\n        ssize_t blockIndex, uint32_t* outLastRef,\n        uint32_t* inoutTypeSpecFlags, ResTable_config* inoutConfig) const\n{\n    //printf(\"Resolving type=0x%x\\n\", inOutValue->dataType);\n    if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {\n        uint32_t newTypeSpecFlags;\n        blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags);\n        if (kDebugTableTheme) {\n            ALOGI(\"Resolving attr reference: blockIndex=%d, type=0x%x, data=0x%x\\n\",\n                    (int)blockIndex, (int)inOutValue->dataType, inOutValue->data);\n        }\n        if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags;\n        //printf(\"Retrieved attribute new type=0x%x\\n\", inOutValue->dataType);\n        if (blockIndex < 0) {\n            return blockIndex;\n        }\n    }\n    return mTable.resolveReference(inOutValue, blockIndex, outLastRef,\n            inoutTypeSpecFlags, inoutConfig);\n}\n\nuint32_t ResTable::Theme::getChangingConfigurations() const\n{\n    return mTypeSpecFlags;\n}\n\nvoid ResTable::Theme::dumpToLog() const\n{\n    ALOGI(\"Theme %p:\\n\", this);\n    for (size_t i=0; i<Res_MAXPACKAGE; i++) {\n        package_info* pi = mPackages[i];\n        if (pi == NULL) continue;\n\n        ALOGI(\"  Package #0x%02x:\\n\", (int)(i + 1));\n        for (size_t j = 0; j <= Res_MAXTYPE; j++) {\n            type_info& ti = pi->types[j];\n            if (ti.numEntries == 0) continue;\n            ALOGI(\"    Type #0x%02x:\\n\", (int)(j + 1));\n            for (size_t k = 0; k < ti.numEntries; k++) {\n                const theme_entry& te = ti.entries[k];\n                if (te.value.dataType == Res_value::TYPE_NULL) continue;\n                ALOGI(\"      0x%08x: t=0x%x, d=0x%08x (block=%d)\\n\",\n                     (int)Res_MAKEID(i, j, k),\n                     te.value.dataType, (int)te.value.data, (int)te.stringBlock);\n            }\n        }\n    }\n}\n\nResTable::ResTable()\n    : mError(NO_INIT), mNextPackageId(2)\n{\n    memset(&mParams, 0, sizeof(mParams));\n    memset(mPackageMap, 0, sizeof(mPackageMap));\n    if (kDebugTableSuperNoisy) {\n        ALOGI(\"Creating ResTable %p\\n\", this);\n    }\n}\n\nResTable::ResTable(const void* data, size_t size, const int32_t cookie, bool copyData)\n    : mError(NO_INIT), mNextPackageId(2)\n{\n    memset(&mParams, 0, sizeof(mParams));\n    memset(mPackageMap, 0, sizeof(mPackageMap));\n    addInternal(data, size, NULL, 0, false, cookie, copyData);\n    LOG_FATAL_IF(mError != NO_ERROR, \"Error parsing resource table\");\n    if (kDebugTableSuperNoisy) {\n        ALOGI(\"Creating ResTable %p\\n\", this);\n    }\n}\n\nResTable::~ResTable()\n{\n    if (kDebugTableSuperNoisy) {\n        ALOGI(\"Destroying ResTable in %p\\n\", this);\n    }\n    uninit();\n}\n\ninline ssize_t ResTable::getResourcePackageIndex(uint32_t resID) const\n{\n    return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1;\n}\n\nstatus_t ResTable::add(const void* data, size_t size, const int32_t cookie, bool copyData) {\n    return addInternal(data, size, NULL, 0, false, cookie, copyData);\n}\n\nstatus_t ResTable::add(const void* data, size_t size, const void* idmapData, size_t idmapDataSize,\n        const int32_t cookie, bool copyData, bool appAsLib) {\n    return addInternal(data, size, idmapData, idmapDataSize, appAsLib, cookie, copyData);\n}\n\nstatus_t ResTable::add(Asset* asset, const int32_t cookie, bool copyData) {\n    const void* data = asset->getBuffer(true);\n    if (data == NULL) {\n        ALOGW(\"Unable to get buffer of resource asset file\");\n        return UNKNOWN_ERROR;\n    }\n\n    return addInternal(data, static_cast<size_t>(asset->getLength()), NULL, false, 0, cookie,\n            copyData);\n}\n\nstatus_t ResTable::add(\n        Asset* asset, Asset* idmapAsset, const int32_t cookie, bool copyData,\n        bool appAsLib, bool isSystemAsset) {\n    const void* data = asset->getBuffer(true);\n    if (data == NULL) {\n        ALOGW(\"Unable to get buffer of resource asset file\");\n        return UNKNOWN_ERROR;\n    }\n\n    size_t idmapSize = 0;\n    const void* idmapData = NULL;\n    if (idmapAsset != NULL) {\n        idmapData = idmapAsset->getBuffer(true);\n        if (idmapData == NULL) {\n            ALOGW(\"Unable to get buffer of idmap asset file\");\n            return UNKNOWN_ERROR;\n        }\n        idmapSize = static_cast<size_t>(idmapAsset->getLength());\n    }\n\n    return addInternal(data, static_cast<size_t>(asset->getLength()),\n            idmapData, idmapSize, appAsLib, cookie, copyData, isSystemAsset);\n}\n\nstatus_t ResTable::add(ResTable* src, bool isSystemAsset)\n{\n    mError = src->mError;\n\n    for (size_t i=0; i < src->mHeaders.size(); i++) {\n        mHeaders.add(src->mHeaders[i]);\n    }\n\n    for (size_t i=0; i < src->mPackageGroups.size(); i++) {\n        PackageGroup* srcPg = src->mPackageGroups[i];\n        PackageGroup* pg = new PackageGroup(this, srcPg->name, srcPg->id,\n                false /* appAsLib */, isSystemAsset || srcPg->isSystemAsset);\n        for (size_t j=0; j<srcPg->packages.size(); j++) {\n            pg->packages.add(srcPg->packages[j]);\n        }\n\n        for (size_t j = 0; j < srcPg->types.size(); j++) {\n            if (srcPg->types[j].isEmpty()) {\n                continue;\n            }\n\n            TypeList& typeList = pg->types.editItemAt(j);\n            typeList.appendVector(srcPg->types[j]);\n        }\n        pg->dynamicRefTable.addMappings(srcPg->dynamicRefTable);\n        pg->largestTypeId = max(pg->largestTypeId, srcPg->largestTypeId);\n        mPackageGroups.add(pg);\n    }\n\n    memcpy(mPackageMap, src->mPackageMap, sizeof(mPackageMap));\n\n    return mError;\n}\n\nstatus_t ResTable::addEmpty(const int32_t cookie) {\n    Header* header = new Header(this);\n    header->index = mHeaders.size();\n    header->cookie = cookie;\n    header->values.setToEmpty();\n    header->ownedData = calloc(1, sizeof(ResTable_header));\n\n    ResTable_header* resHeader = (ResTable_header*) header->ownedData;\n    resHeader->header.type = RES_TABLE_TYPE;\n    resHeader->header.headerSize = sizeof(ResTable_header);\n    resHeader->header.size = sizeof(ResTable_header);\n\n    header->header = (const ResTable_header*) resHeader;\n    mHeaders.add(header);\n    return (mError=NO_ERROR);\n}\n\nstatus_t ResTable::addInternal(const void* data, size_t dataSize, const void* idmapData, size_t idmapDataSize,\n        bool appAsLib, const int32_t cookie, bool copyData, bool isSystemAsset)\n{\n    if (!data) {\n        return NO_ERROR;\n    }\n\n    if (dataSize < sizeof(ResTable_header)) {\n        ALOGE(\"Invalid data. Size(%d) is smaller than a ResTable_header(%d).\",\n                (int) dataSize, (int) sizeof(ResTable_header));\n        return UNKNOWN_ERROR;\n    }\n\n    Header* header = new Header(this);\n    header->index = mHeaders.size();\n    header->cookie = cookie;\n    if (idmapData != NULL) {\n        header->resourceIDMap = (uint32_t*) malloc(idmapDataSize);\n        if (header->resourceIDMap == NULL) {\n            delete header;\n            return (mError = NO_MEMORY);\n        }\n        memcpy(header->resourceIDMap, idmapData, idmapDataSize);\n        header->resourceIDMapSize = idmapDataSize;\n    }\n    mHeaders.add(header);\n\n    const bool notDeviceEndian = htods(0xf0) != 0xf0;\n\n    if (kDebugLoadTableNoisy) {\n        ALOGV(\"Adding resources to ResTable: data=%p, size=%zu, cookie=%d, copy=%d \"\n                \"idmap=%p\\n\", data, dataSize, cookie, copyData, idmapData);\n    }\n\n    if (copyData || notDeviceEndian) {\n        header->ownedData = malloc(dataSize);\n        if (header->ownedData == NULL) {\n            return (mError=NO_MEMORY);\n        }\n        memcpy(header->ownedData, data, dataSize);\n        data = header->ownedData;\n    }\n\n    header->header = (const ResTable_header*)data;\n    header->size = dtohl(header->header->header.size);\n    if (kDebugLoadTableSuperNoisy) {\n        ALOGI(\"Got size %zu, again size 0x%x, raw size 0x%x\\n\", header->size,\n                dtohl(header->header->header.size), header->header->header.size);\n    }\n    if (kDebugLoadTableNoisy) {\n        ALOGV(\"Loading ResTable @%p:\\n\", header->header);\n    }\n    if (dtohs(header->header->header.headerSize) > header->size\n            || header->size > dataSize) {\n        ALOGW(\"Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\\n\",\n             (int)dtohs(header->header->header.headerSize),\n             (int)header->size, (int)dataSize);\n        return (mError=BAD_TYPE);\n    }\n    if (((dtohs(header->header->header.headerSize)|header->size)&0x3) != 0) {\n        ALOGW(\"Bad resource table: header size 0x%x or total size 0x%x is not on an integer boundary\\n\",\n             (int)dtohs(header->header->header.headerSize),\n             (int)header->size);\n        return (mError=BAD_TYPE);\n    }\n    header->dataEnd = ((const uint8_t*)header->header) + header->size;\n\n    // Iterate through all chunks.\n    size_t curPackage = 0;\n\n    const ResChunk_header* chunk =\n        (const ResChunk_header*)(((const uint8_t*)header->header)\n                                 + dtohs(header->header->header.headerSize));\n    while (((const uint8_t*)chunk) <= (header->dataEnd-sizeof(ResChunk_header)) &&\n           ((const uint8_t*)chunk) <= (header->dataEnd-dtohl(chunk->size))) {\n        status_t err = validate_chunk(chunk, sizeof(ResChunk_header), header->dataEnd, \"ResTable\");\n        if (err != NO_ERROR) {\n            return (mError=err);\n        }\n        if (kDebugTableNoisy) {\n            ALOGV(\"Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\\n\",\n                    dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),\n                    (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)));\n        }\n        const size_t csize = dtohl(chunk->size);\n        const uint16_t ctype = dtohs(chunk->type);\n        if (ctype == RES_STRING_POOL_TYPE) {\n            if (header->values.getError() != NO_ERROR) {\n                // Only use the first string chunk; ignore any others that\n                // may appear.\n                status_t err = header->values.setTo(chunk, csize);\n                if (err != NO_ERROR) {\n                    return (mError=err);\n                }\n            } else {\n                ALOGW(\"Multiple string chunks found in resource table.\");\n            }\n        } else if (ctype == RES_TABLE_PACKAGE_TYPE) {\n            if (curPackage >= dtohl(header->header->packageCount)) {\n                ALOGW(\"More package chunks were found than the %d declared in the header.\",\n                     dtohl(header->header->packageCount));\n                return (mError=BAD_TYPE);\n            }\n\n            if (parsePackage(\n                    (ResTable_package*)chunk, header, appAsLib, isSystemAsset) != NO_ERROR) {\n                return mError;\n            }\n            curPackage++;\n        } else {\n            ALOGW(\"Unknown chunk type 0x%x in table at %p.\\n\",\n                 ctype,\n                 (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)));\n        }\n        chunk = (const ResChunk_header*)\n            (((const uint8_t*)chunk) + csize);\n    }\n\n    if (curPackage < dtohl(header->header->packageCount)) {\n        ALOGW(\"Fewer package chunks (%d) were found than the %d declared in the header.\",\n             (int)curPackage, dtohl(header->header->packageCount));\n        return (mError=BAD_TYPE);\n    }\n    mError = header->values.getError();\n    if (mError != NO_ERROR) {\n        ALOGW(\"No string values found in resource table!\");\n    }\n\n    if (kDebugTableNoisy) {\n        ALOGV(\"Returning from add with mError=%d\\n\", mError);\n    }\n    return mError;\n}\n\nstatus_t ResTable::getError() const\n{\n    return mError;\n}\n\nvoid ResTable::uninit()\n{\n    mError = NO_INIT;\n    size_t N = mPackageGroups.size();\n    for (size_t i=0; i<N; i++) {\n        PackageGroup* g = mPackageGroups[i];\n        delete g;\n    }\n    N = mHeaders.size();\n    for (size_t i=0; i<N; i++) {\n        Header* header = mHeaders[i];\n        if (header->owner == this) {\n            if (header->ownedData) {\n                free(header->ownedData);\n            }\n            delete header;\n        }\n    }\n\n    mPackageGroups.clear();\n    mHeaders.clear();\n}\n\nbool ResTable::getResourceName(uint32_t resID, bool allowUtf8, resource_name* outName) const\n{\n    if (mError != NO_ERROR) {\n        return false;\n    }\n\n    const ssize_t p = getResourcePackageIndex(resID);\n    const int t = Res_GETTYPE(resID);\n    const int e = Res_GETENTRY(resID);\n\n    if (p < 0) {\n        if (Res_GETPACKAGE(resID)+1 == 0) {\n            ALOGW(\"No package identifier when getting name for resource number 0x%08x\", resID);\n        } else {\n#ifndef STATIC_ANDROIDFW_FOR_TOOLS\n            ALOGW(\"No known package when getting name for resource number 0x%08x\", resID);\n#endif\n        }\n        return false;\n    }\n    if (t < 0) {\n        ALOGW(\"No type identifier when getting name for resource number 0x%08x\", resID);\n        return false;\n    }\n\n    const PackageGroup* const grp = mPackageGroups[p];\n    if (grp == NULL) {\n        ALOGW(\"Bad identifier when getting name for resource number 0x%08x\", resID);\n        return false;\n    }\n\n    Entry entry;\n    status_t err = getEntry(grp, t, e, NULL, &entry);\n    if (err != NO_ERROR) {\n        return false;\n    }\n\n    outName->package = grp->name.string();\n    outName->packageLen = grp->name.size();\n    if (allowUtf8) {\n        outName->type8 = entry.typeStr.string8(&outName->typeLen);\n        outName->name8 = entry.keyStr.string8(&outName->nameLen);\n    } else {\n        outName->type8 = NULL;\n        outName->name8 = NULL;\n    }\n    if (outName->type8 == NULL) {\n        outName->type = entry.typeStr.string16(&outName->typeLen);\n        // If we have a bad index for some reason, we should abort.\n        if (outName->type == NULL) {\n            return false;\n        }\n    }\n    if (outName->name8 == NULL) {\n        outName->name = entry.keyStr.string16(&outName->nameLen);\n        // If we have a bad index for some reason, we should abort.\n        if (outName->name == NULL) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\nssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag, uint16_t density,\n        uint32_t* outSpecFlags, ResTable_config* outConfig) const\n{\n    if (mError != NO_ERROR) {\n        return mError;\n    }\n\n    const ssize_t p = getResourcePackageIndex(resID);\n    const int t = Res_GETTYPE(resID);\n    const int e = Res_GETENTRY(resID);\n\n    if (p < 0) {\n        if (Res_GETPACKAGE(resID)+1 == 0) {\n            ALOGW(\"No package identifier when getting value for resource number 0x%08x\", resID);\n        } else {\n            ALOGW(\"No known package when getting value for resource number 0x%08x\", resID);\n        }\n        return BAD_INDEX;\n    }\n    if (t < 0) {\n        ALOGW(\"No type identifier when getting value for resource number 0x%08x\", resID);\n        return BAD_INDEX;\n    }\n\n    const PackageGroup* const grp = mPackageGroups[p];\n    if (grp == NULL) {\n        ALOGW(\"Bad identifier when getting value for resource number 0x%08x\", resID);\n        return BAD_INDEX;\n    }\n\n    // Allow overriding density\n    ResTable_config desiredConfig = mParams;\n    if (density > 0) {\n        desiredConfig.density = density;\n    }\n\n    Entry entry;\n    status_t err = getEntry(grp, t, e, &desiredConfig, &entry);\n    if (err != NO_ERROR) {\n        // Only log the failure when we're not running on the host as\n        // part of a tool. The caller will do its own logging.\n#ifndef STATIC_ANDROIDFW_FOR_TOOLS\n        ALOGW(\"Failure getting entry for 0x%08x (t=%d e=%d) (error %d)\\n\",\n                resID, t, e, err);\n#endif\n        return err;\n    }\n\n    if ((dtohs(entry.entry->flags) & ResTable_entry::FLAG_COMPLEX) != 0) {\n        if (!mayBeBag) {\n            ALOGW(\"Requesting resource 0x%08x failed because it is complex\\n\", resID);\n        }\n        return BAD_VALUE;\n    }\n\n    const Res_value* value = reinterpret_cast<const Res_value*>(\n            reinterpret_cast<const uint8_t*>(entry.entry) + entry.entry->size);\n\n    outValue->size = dtohs(value->size);\n    outValue->res0 = value->res0;\n    outValue->dataType = value->dataType;\n    outValue->data = dtohl(value->data);\n\n    // The reference may be pointing to a resource in a shared library. These\n    // references have build-time generated package IDs. These ids may not match\n    // the actual package IDs of the corresponding packages in this ResTable.\n    // We need to fix the package ID based on a mapping.\n    if (grp->dynamicRefTable.lookupResourceValue(outValue) != NO_ERROR) {\n        ALOGW(\"Failed to resolve referenced package: 0x%08x\", outValue->data);\n        return BAD_VALUE;\n    }\n\n    if (kDebugTableNoisy) {\n        size_t len;\n        printf(\"Found value: pkg=%zu, type=%d, str=%s, int=%d\\n\",\n                entry.package->header->index,\n                outValue->dataType,\n                outValue->dataType == Res_value::TYPE_STRING ?\n                    String8(entry.package->header->values.stringAt(outValue->data, &len)).string() :\n                    \"\",\n                outValue->data);\n    }\n\n    if (outSpecFlags != NULL) {\n        *outSpecFlags = entry.specFlags;\n    }\n\n    if (outConfig != NULL) {\n        *outConfig = entry.config;\n    }\n\n    return entry.package->header->index;\n}\n\nssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,\n        uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags,\n        ResTable_config* outConfig) const\n{\n    int count=0;\n    while (blockIndex >= 0 && value->dataType == Res_value::TYPE_REFERENCE\n            && value->data != 0 && count < 20) {\n        if (outLastRef) *outLastRef = value->data;\n        uint32_t newFlags = 0;\n        const ssize_t newIndex = getResource(value->data, value, true, 0, &newFlags,\n                outConfig);\n        if (newIndex == BAD_INDEX) {\n            return BAD_INDEX;\n        }\n        if (kDebugTableTheme) {\n            ALOGI(\"Resolving reference 0x%x: newIndex=%d, type=0x%x, data=0x%x\\n\",\n                    value->data, (int)newIndex, (int)value->dataType, value->data);\n        }\n        //printf(\"Getting reference 0x%08x: newIndex=%d\\n\", value->data, newIndex);\n        if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags;\n        if (newIndex < 0) {\n            // This can fail if the resource being referenced is a style...\n            // in this case, just return the reference, and expect the\n            // caller to deal with.\n            return blockIndex;\n        }\n        blockIndex = newIndex;\n        count++;\n    }\n    return blockIndex;\n}\n\nconst char16_t* ResTable::valueToString(\n    const Res_value* value, size_t stringBlock,\n    char16_t /*tmpBuffer*/ [TMP_BUFFER_SIZE], size_t* outLen) const\n{\n    if (!value) {\n        return NULL;\n    }\n    if (value->dataType == value->TYPE_STRING) {\n        return getTableStringBlock(stringBlock)->stringAt(value->data, outLen);\n    }\n    // XXX do int to string conversions.\n    return NULL;\n}\n\nssize_t ResTable::lockBag(uint32_t resID, const bag_entry** outBag) const\n{\n    mLock.lock();\n    ssize_t err = getBagLocked(resID, outBag);\n    if (err < NO_ERROR) {\n        //printf(\"*** get failed!  unlocking\\n\");\n        mLock.unlock();\n    }\n    return err;\n}\n\nvoid ResTable::unlockBag(const bag_entry* /*bag*/) const\n{\n    //printf(\"<<< unlockBag %p\\n\", this);\n    mLock.unlock();\n}\n\nvoid ResTable::lock() const\n{\n    mLock.lock();\n}\n\nvoid ResTable::unlock() const\n{\n    mLock.unlock();\n}\n\nssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,\n        uint32_t* outTypeSpecFlags) const\n{\n    if (mError != NO_ERROR) {\n        return mError;\n    }\n\n    const ssize_t p = getResourcePackageIndex(resID);\n    const int t = Res_GETTYPE(resID);\n    const int e = Res_GETENTRY(resID);\n\n    if (p < 0) {\n        ALOGW(\"Invalid package identifier when getting bag for resource number 0x%08x\", resID);\n        return BAD_INDEX;\n    }\n    if (t < 0) {\n        ALOGW(\"No type identifier when getting bag for resource number 0x%08x\", resID);\n        return BAD_INDEX;\n    }\n\n    //printf(\"Get bag: id=0x%08x, p=%d, t=%d\\n\", resID, p, t);\n    PackageGroup* const grp = mPackageGroups[p];\n    if (grp == NULL) {\n        ALOGW(\"Bad identifier when getting bag for resource number 0x%08x\", resID);\n        return BAD_INDEX;\n    }\n\n    const TypeList& typeConfigs = grp->types[t];\n    if (typeConfigs.isEmpty()) {\n        ALOGW(\"Type identifier 0x%x does not exist.\", t+1);\n        return BAD_INDEX;\n    }\n\n    const size_t NENTRY = typeConfigs[0]->entryCount;\n    if (e >= (int)NENTRY) {\n        ALOGW(\"Entry identifier 0x%x is larger than entry count 0x%x\",\n             e, (int)typeConfigs[0]->entryCount);\n        return BAD_INDEX;\n    }\n\n    // First see if we've already computed this bag...\n    TypeCacheEntry& cacheEntry = grp->typeCacheEntries.editItemAt(t);\n    bag_set** typeSet = cacheEntry.cachedBags;\n    if (typeSet) {\n        bag_set* set = typeSet[e];\n        if (set) {\n            if (set != (bag_set*)0xFFFFFFFF) {\n                if (outTypeSpecFlags != NULL) {\n                    *outTypeSpecFlags = set->typeSpecFlags;\n                }\n                *outBag = (bag_entry*)(set+1);\n                if (kDebugTableSuperNoisy) {\n                    ALOGI(\"Found existing bag for: 0x%x\\n\", resID);\n                }\n                return set->numAttrs;\n            }\n            ALOGW(\"Attempt to retrieve bag 0x%08x which is invalid or in a cycle.\",\n                 resID);\n            return BAD_INDEX;\n        }\n    }\n\n    // Bag not found, we need to compute it!\n    if (!typeSet) {\n        typeSet = (bag_set**)calloc(NENTRY, sizeof(bag_set*));\n        if (!typeSet) return NO_MEMORY;\n        cacheEntry.cachedBags = typeSet;\n    }\n\n    // Mark that we are currently working on this one.\n    typeSet[e] = (bag_set*)0xFFFFFFFF;\n\n    if (kDebugTableNoisy) {\n        ALOGI(\"Building bag: %x\\n\", resID);\n    }\n\n    // Now collect all bag attributes\n    Entry entry;\n    status_t err = getEntry(grp, t, e, &mParams, &entry);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    const uint16_t entrySize = dtohs(entry.entry->size);\n    const uint32_t parent = entrySize >= sizeof(ResTable_map_entry)\n        ? dtohl(((const ResTable_map_entry*)entry.entry)->parent.ident) : 0;\n    const uint32_t count = entrySize >= sizeof(ResTable_map_entry)\n        ? dtohl(((const ResTable_map_entry*)entry.entry)->count) : 0;\n\n    size_t N = count;\n\n    if (kDebugTableNoisy) {\n        ALOGI(\"Found map: size=%x parent=%x count=%d\\n\", entrySize, parent, count);\n\n    // If this map inherits from another, we need to start\n    // with its parent's values.  Otherwise start out empty.\n        ALOGI(\"Creating new bag, entrySize=0x%08x, parent=0x%08x\\n\", entrySize, parent);\n    }\n\n    // This is what we are building.\n    bag_set* set = NULL;\n\n    if (parent) {\n        uint32_t resolvedParent = parent;\n\n        // Bags encode a parent reference without using the standard\n        // Res_value structure. That means we must always try to\n        // resolve a parent reference in case it is actually a\n        // TYPE_DYNAMIC_REFERENCE.\n        status_t err = grp->dynamicRefTable.lookupResourceId(&resolvedParent);\n        if (err != NO_ERROR) {\n            ALOGE(\"Failed resolving bag parent id 0x%08x\", parent);\n            return UNKNOWN_ERROR;\n        }\n\n        const bag_entry* parentBag;\n        uint32_t parentTypeSpecFlags = 0;\n        const ssize_t NP = getBagLocked(resolvedParent, &parentBag, &parentTypeSpecFlags);\n        const size_t NT = ((NP >= 0) ? NP : 0) + N;\n        set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*NT);\n        if (set == NULL) {\n            return NO_MEMORY;\n        }\n        if (NP > 0) {\n            memcpy(set+1, parentBag, NP*sizeof(bag_entry));\n            set->numAttrs = NP;\n            if (kDebugTableNoisy) {\n                ALOGI(\"Initialized new bag with %zd inherited attributes.\\n\", NP);\n            }\n        } else {\n            if (kDebugTableNoisy) {\n                ALOGI(\"Initialized new bag with no inherited attributes.\\n\");\n            }\n            set->numAttrs = 0;\n        }\n        set->availAttrs = NT;\n        set->typeSpecFlags = parentTypeSpecFlags;\n    } else {\n        set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*N);\n        if (set == NULL) {\n            return NO_MEMORY;\n        }\n        set->numAttrs = 0;\n        set->availAttrs = N;\n        set->typeSpecFlags = 0;\n    }\n\n    set->typeSpecFlags |= entry.specFlags;\n\n    // Now merge in the new attributes...\n    size_t curOff = (reinterpret_cast<uintptr_t>(entry.entry) - reinterpret_cast<uintptr_t>(entry.type))\n        + dtohs(entry.entry->size);\n    const ResTable_map* map;\n    bag_entry* entries = (bag_entry*)(set+1);\n    size_t curEntry = 0;\n    uint32_t pos = 0;\n    if (kDebugTableNoisy) {\n        ALOGI(\"Starting with set %p, entries=%p, avail=%zu\\n\", set, entries, set->availAttrs);\n    }\n    while (pos < count) {\n        if (kDebugTableNoisy) {\n            ALOGI(\"Now at %p\\n\", (void*)curOff);\n        }\n\n        if (curOff > (dtohl(entry.type->header.size)-sizeof(ResTable_map))) {\n            ALOGW(\"ResTable_map at %d is beyond type chunk data %d\",\n                 (int)curOff, dtohl(entry.type->header.size));\n            return BAD_TYPE;\n        }\n        map = (const ResTable_map*)(((const uint8_t*)entry.type) + curOff);\n        N++;\n\n        uint32_t newName = htodl(map->name.ident);\n        if (!Res_INTERNALID(newName)) {\n            // Attributes don't have a resource id as the name. They specify\n            // other data, which would be wrong to change via a lookup.\n            if (grp->dynamicRefTable.lookupResourceId(&newName) != NO_ERROR) {\n                ALOGE(\"Failed resolving ResTable_map name at %d with ident 0x%08x\",\n                        (int) curOff, (int) newName);\n                return UNKNOWN_ERROR;\n            }\n        }\n\n        bool isInside;\n        uint32_t oldName = 0;\n        while ((isInside=(curEntry < set->numAttrs))\n                && (oldName=entries[curEntry].map.name.ident) < newName) {\n            if (kDebugTableNoisy) {\n                ALOGI(\"#%zu: Keeping existing attribute: 0x%08x\\n\",\n                        curEntry, entries[curEntry].map.name.ident);\n            }\n            curEntry++;\n        }\n\n        if ((!isInside) || oldName != newName) {\n            // This is a new attribute...  figure out what to do with it.\n            if (set->numAttrs >= set->availAttrs) {\n                // Need to alloc more memory...\n                const size_t newAvail = set->availAttrs+N;\n                set = (bag_set*)realloc(set,\n                                        sizeof(bag_set)\n                                        + sizeof(bag_entry)*newAvail);\n                if (set == NULL) {\n                    return NO_MEMORY;\n                }\n                set->availAttrs = newAvail;\n                entries = (bag_entry*)(set+1);\n                if (kDebugTableNoisy) {\n                    ALOGI(\"Reallocated set %p, entries=%p, avail=%zu\\n\",\n                            set, entries, set->availAttrs);\n                }\n            }\n            if (isInside) {\n                // Going in the middle, need to make space.\n                memmove(entries+curEntry+1, entries+curEntry,\n                        sizeof(bag_entry)*(set->numAttrs-curEntry));\n                set->numAttrs++;\n            }\n            if (kDebugTableNoisy) {\n                ALOGI(\"#%zu: Inserting new attribute: 0x%08x\\n\", curEntry, newName);\n            }\n        } else {\n            if (kDebugTableNoisy) {\n                ALOGI(\"#%zu: Replacing existing attribute: 0x%08x\\n\", curEntry, oldName);\n            }\n        }\n\n        bag_entry* cur = entries+curEntry;\n\n        cur->stringBlock = entry.package->header->index;\n        cur->map.name.ident = newName;\n        cur->map.value.copyFrom_dtoh(map->value);\n        status_t err = grp->dynamicRefTable.lookupResourceValue(&cur->map.value);\n        if (err != NO_ERROR) {\n            ALOGE(\"Reference item(0x%08x) in bag could not be resolved.\", cur->map.value.data);\n            return UNKNOWN_ERROR;\n        }\n\n        if (kDebugTableNoisy) {\n            ALOGI(\"Setting entry #%zu %p: block=%zd, name=0x%08d, type=%d, data=0x%08x\\n\",\n                    curEntry, cur, cur->stringBlock, cur->map.name.ident,\n                    cur->map.value.dataType, cur->map.value.data);\n        }\n\n        // On to the next!\n        curEntry++;\n        pos++;\n        const size_t size = dtohs(map->value.size);\n        curOff += size + sizeof(*map)-sizeof(map->value);\n    };\n\n    if (curEntry > set->numAttrs) {\n        set->numAttrs = curEntry;\n    }\n\n    // And this is it...\n    typeSet[e] = set;\n    if (set) {\n        if (outTypeSpecFlags != NULL) {\n            *outTypeSpecFlags = set->typeSpecFlags;\n        }\n        *outBag = (bag_entry*)(set+1);\n        if (kDebugTableNoisy) {\n            ALOGI(\"Returning %zu attrs\\n\", set->numAttrs);\n        }\n        return set->numAttrs;\n    }\n    return BAD_INDEX;\n}\n\nvoid ResTable::setParameters(const ResTable_config* params)\n{\n    AutoMutex _lock(mLock);\n    AutoMutex _lock2(mFilteredConfigLock);\n\n    if (kDebugTableGetEntry) {\n        ALOGI(\"Setting parameters: %s\\n\", params->toString().string());\n    }\n    mParams = *params;\n    for (size_t p = 0; p < mPackageGroups.size(); p++) {\n        PackageGroup* packageGroup = mPackageGroups.editItemAt(p);\n        if (kDebugTableNoisy) {\n            ALOGI(\"CLEARING BAGS FOR GROUP %zu!\", p);\n        }\n        packageGroup->clearBagCache();\n\n        // Find which configurations match the set of parameters. This allows for a much\n        // faster lookup in getEntry() if the set of values is narrowed down.\n        for (size_t t = 0; t < packageGroup->types.size(); t++) {\n            if (packageGroup->types[t].isEmpty()) {\n                continue;\n            }\n\n            TypeList& typeList = packageGroup->types.editItemAt(t);\n\n            // Retrieve the cache entry for this type.\n            TypeCacheEntry& cacheEntry = packageGroup->typeCacheEntries.editItemAt(t);\n\n            for (size_t ts = 0; ts < typeList.size(); ts++) {\n                Type* type = typeList.editItemAt(ts);\n\n                std::shared_ptr<Vector<const ResTable_type*>> newFilteredConfigs =\n                        std::make_shared<Vector<const ResTable_type*>>();\n\n                for (size_t ti = 0; ti < type->configs.size(); ti++) {\n                    ResTable_config config;\n                    config.copyFromDtoH(type->configs[ti]->config);\n\n                    if (config.match(mParams)) {\n                        newFilteredConfigs->add(type->configs[ti]);\n                    }\n                }\n\n                if (kDebugTableNoisy) {\n                    ALOGD(\"Updating pkg=%zu type=%zu with %zu filtered configs\",\n                          p, t, newFilteredConfigs->size());\n                }\n\n                cacheEntry.filteredConfigs.add(newFilteredConfigs);\n            }\n        }\n    }\n}\n\nvoid ResTable::getParameters(ResTable_config* params) const\n{\n    mLock.lock();\n    *params = mParams;\n    mLock.unlock();\n}\n\nstruct id_name_map {\n    uint32_t id;\n    size_t len;\n    char16_t name[6];\n};\n\nconst static id_name_map ID_NAMES[] = {\n    { ResTable_map::ATTR_TYPE,  5, { '^', 't', 'y', 'p', 'e' } },\n    { ResTable_map::ATTR_L10N,  5, { '^', 'l', '1', '0', 'n' } },\n    { ResTable_map::ATTR_MIN,   4, { '^', 'm', 'i', 'n' } },\n    { ResTable_map::ATTR_MAX,   4, { '^', 'm', 'a', 'x' } },\n    { ResTable_map::ATTR_OTHER, 6, { '^', 'o', 't', 'h', 'e', 'r' } },\n    { ResTable_map::ATTR_ZERO,  5, { '^', 'z', 'e', 'r', 'o' } },\n    { ResTable_map::ATTR_ONE,   4, { '^', 'o', 'n', 'e' } },\n    { ResTable_map::ATTR_TWO,   4, { '^', 't', 'w', 'o' } },\n    { ResTable_map::ATTR_FEW,   4, { '^', 'f', 'e', 'w' } },\n    { ResTable_map::ATTR_MANY,  5, { '^', 'm', 'a', 'n', 'y' } },\n};\n\nuint32_t ResTable::identifierForName(const char16_t* name, size_t nameLen,\n                                     const char16_t* type, size_t typeLen,\n                                     const char16_t* package,\n                                     size_t packageLen,\n                                     uint32_t* outTypeSpecFlags) const\n{\n    if (kDebugTableSuperNoisy) {\n        printf(\"Identifier for name: error=%d\\n\", mError);\n    }\n\n    // Check for internal resource identifier as the very first thing, so\n    // that we will always find them even when there are no resources.\n    if (name[0] == '^') {\n        const int N = (sizeof(ID_NAMES)/sizeof(ID_NAMES[0]));\n        size_t len;\n        for (int i=0; i<N; i++) {\n            const id_name_map* m = ID_NAMES + i;\n            len = m->len;\n            if (len != nameLen) {\n                continue;\n            }\n            for (size_t j=1; j<len; j++) {\n                if (m->name[j] != name[j]) {\n                    goto nope;\n                }\n            }\n            if (outTypeSpecFlags) {\n                *outTypeSpecFlags = ResTable_typeSpec::SPEC_PUBLIC;\n            }\n            return m->id;\nnope:\n            ;\n        }\n        if (nameLen > 7) {\n            if (name[1] == 'i' && name[2] == 'n'\n                && name[3] == 'd' && name[4] == 'e' && name[5] == 'x'\n                && name[6] == '_') {\n                int index = atoi(String8(name + 7, nameLen - 7).string());\n                if (Res_CHECKID(index)) {\n                    ALOGW(\"Array resource index: %d is too large.\",\n                         index);\n                    return 0;\n                }\n                if (outTypeSpecFlags) {\n                    *outTypeSpecFlags = ResTable_typeSpec::SPEC_PUBLIC;\n                }\n                return  Res_MAKEARRAY(index);\n            }\n        }\n        return 0;\n    }\n\n    if (mError != NO_ERROR) {\n        return 0;\n    }\n\n    bool fakePublic = false;\n\n    // Figure out the package and type we are looking in...\n\n    const char16_t* packageEnd = NULL;\n    const char16_t* typeEnd = NULL;\n    const char16_t* const nameEnd = name+nameLen;\n    const char16_t* p = name;\n    while (p < nameEnd) {\n        if (*p == ':') packageEnd = p;\n        else if (*p == '/') typeEnd = p;\n        p++;\n    }\n    if (*name == '@') {\n        name++;\n        if (*name == '*') {\n            fakePublic = true;\n            name++;\n        }\n    }\n    if (name >= nameEnd) {\n        return 0;\n    }\n\n    if (packageEnd) {\n        package = name;\n        packageLen = packageEnd-name;\n        name = packageEnd+1;\n    } else if (!package) {\n        return 0;\n    }\n\n    if (typeEnd) {\n        type = name;\n        typeLen = typeEnd-name;\n        name = typeEnd+1;\n    } else if (!type) {\n        return 0;\n    }\n\n    if (name >= nameEnd) {\n        return 0;\n    }\n    nameLen = nameEnd-name;\n\n    if (kDebugTableNoisy) {\n        printf(\"Looking for identifier: type=%s, name=%s, package=%s\\n\",\n                String8(type, typeLen).string(),\n                String8(name, nameLen).string(),\n                String8(package, packageLen).string());\n    }\n\n    const String16 attr(\"attr\");\n    const String16 attrPrivate(\"^attr-private\");\n\n    const size_t NG = mPackageGroups.size();\n    for (size_t ig=0; ig<NG; ig++) {\n        const PackageGroup* group = mPackageGroups[ig];\n\n        if (strzcmp16(package, packageLen,\n                      group->name.string(), group->name.size())) {\n            if (kDebugTableNoisy) {\n                printf(\"Skipping package group: %s\\n\", String8(group->name).string());\n            }\n            continue;\n        }\n\n        const size_t packageCount = group->packages.size();\n        for (size_t pi = 0; pi < packageCount; pi++) {\n            const char16_t* targetType = type;\n            size_t targetTypeLen = typeLen;\n\n            do {\n                ssize_t ti = group->packages[pi]->typeStrings.indexOfString(\n                        targetType, targetTypeLen);\n                if (ti < 0) {\n                    continue;\n                }\n\n                ti += group->packages[pi]->typeIdOffset;\n\n                const uint32_t identifier = findEntry(group, ti, name, nameLen,\n                        outTypeSpecFlags);\n                if (identifier != 0) {\n                    if (fakePublic && outTypeSpecFlags) {\n                        *outTypeSpecFlags |= ResTable_typeSpec::SPEC_PUBLIC;\n                    }\n                    return identifier;\n                }\n            } while (strzcmp16(attr.string(), attr.size(), targetType, targetTypeLen) == 0\n                    && (targetType = attrPrivate.string())\n                    && (targetTypeLen = attrPrivate.size())\n            );\n        }\n        // break;\n    }\n    return 0;\n}\n\nuint32_t ResTable::findEntry(const PackageGroup* group, ssize_t typeIndex, const char16_t* name,\n        size_t nameLen, uint32_t* outTypeSpecFlags) const {\n    const TypeList& typeList = group->types[typeIndex];\n    const size_t typeCount = typeList.size();\n    for (size_t i = 0; i < typeCount; i++) {\n        const Type* t = typeList[i];\n        const ssize_t ei = t->package->keyStrings.indexOfString(name, nameLen);\n        if (ei < 0) {\n            continue;\n        }\n\n        const size_t configCount = t->configs.size();\n        for (size_t j = 0; j < configCount; j++) {\n            const TypeVariant tv(t->configs[j]);\n            for (TypeVariant::iterator iter = tv.beginEntries();\n                 iter != tv.endEntries();\n                 iter++) {\n                const ResTable_entry* entry = *iter;\n                if (entry == NULL) {\n                    continue;\n                }\n\n                if (dtohl(entry->key.index) == (size_t) ei) {\n                    uint32_t resId = Res_MAKEID(group->id - 1, typeIndex, iter.index());\n                    if (outTypeSpecFlags) {\n                        Entry result;\n                        if (getEntry(group, typeIndex, iter.index(), NULL, &result) != NO_ERROR) {\n                            ALOGW(\"Failed to find spec flags for 0x%08x\", resId);\n                            return 0;\n                        }\n                        *outTypeSpecFlags = result.specFlags;\n                    }\n                    return resId;\n                }\n            }\n        }\n    }\n    return 0;\n}\n\nbool ResTable::expandResourceRef(const char16_t* refStr, size_t refLen,\n                                 String16* outPackage,\n                                 String16* outType,\n                                 String16* outName,\n                                 const String16* defType,\n                                 const String16* defPackage,\n                                 const char** outErrorMsg,\n                                 bool* outPublicOnly)\n{\n    const char16_t* packageEnd = NULL;\n    const char16_t* typeEnd = NULL;\n    const char16_t* p = refStr;\n    const char16_t* const end = p + refLen;\n    while (p < end) {\n        if (*p == ':') packageEnd = p;\n        else if (*p == '/') {\n            typeEnd = p;\n            break;\n        }\n        p++;\n    }\n    p = refStr;\n    if (*p == '@') p++;\n\n    if (outPublicOnly != NULL) {\n        *outPublicOnly = true;\n    }\n    if (*p == '*') {\n        p++;\n        if (outPublicOnly != NULL) {\n            *outPublicOnly = false;\n        }\n    }\n\n    if (packageEnd) {\n        *outPackage = String16(p, packageEnd-p);\n        p = packageEnd+1;\n    } else {\n        if (!defPackage) {\n            if (outErrorMsg) {\n                *outErrorMsg = \"No resource package specified\";\n            }\n            return false;\n        }\n        *outPackage = *defPackage;\n    }\n    if (typeEnd) {\n        *outType = String16(p, typeEnd-p);\n        p = typeEnd+1;\n    } else {\n        if (!defType) {\n            if (outErrorMsg) {\n                *outErrorMsg = \"No resource type specified\";\n            }\n            return false;\n        }\n        *outType = *defType;\n    }\n    *outName = String16(p, end-p);\n    if(**outPackage == 0) {\n        if(outErrorMsg) {\n            *outErrorMsg = \"Resource package cannot be an empty string\";\n        }\n        return false;\n    }\n    if(**outType == 0) {\n        if(outErrorMsg) {\n            *outErrorMsg = \"Resource type cannot be an empty string\";\n        }\n        return false;\n    }\n    if(**outName == 0) {\n        if(outErrorMsg) {\n            *outErrorMsg = \"Resource id cannot be an empty string\";\n        }\n        return false;\n    }\n    return true;\n}\n\nstatic uint32_t get_hex(char c, bool* outError)\n{\n    if (c >= '0' && c <= '9') {\n        return c - '0';\n    } else if (c >= 'a' && c <= 'f') {\n        return c - 'a' + 0xa;\n    } else if (c >= 'A' && c <= 'F') {\n        return c - 'A' + 0xa;\n    }\n    *outError = true;\n    return 0;\n}\n\nstruct unit_entry\n{\n    const char* name;\n    size_t len;\n    uint8_t type;\n    uint32_t unit;\n    float scale;\n};\n\nstatic const unit_entry unitNames[] = {\n    { \"px\", strlen(\"px\"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PX, 1.0f },\n    { \"dip\", strlen(\"dip\"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },\n    { \"dp\", strlen(\"dp\"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },\n    { \"sp\", strlen(\"sp\"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_SP, 1.0f },\n    { \"pt\", strlen(\"pt\"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PT, 1.0f },\n    { \"in\", strlen(\"in\"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_IN, 1.0f },\n    { \"mm\", strlen(\"mm\"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_MM, 1.0f },\n    { \"%\", strlen(\"%\"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION, 1.0f/100 },\n    { \"%p\", strlen(\"%p\"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100 },\n    { NULL, 0, 0, 0, 0 }\n};\n\nstatic bool parse_unit(const char* str, Res_value* outValue,\n                       float* outScale, const char** outEnd)\n{\n    const char* end = str;\n    while (*end != 0 && !isspace((unsigned char)*end)) {\n        end++;\n    }\n    const size_t len = end-str;\n\n    const char* realEnd = end;\n    while (*realEnd != 0 && isspace((unsigned char)*realEnd)) {\n        realEnd++;\n    }\n    if (*realEnd != 0) {\n        return false;\n    }\n\n    const unit_entry* cur = unitNames;\n    while (cur->name) {\n        if (len == cur->len && strncmp(cur->name, str, len) == 0) {\n            outValue->dataType = cur->type;\n            outValue->data = cur->unit << Res_value::COMPLEX_UNIT_SHIFT;\n            *outScale = cur->scale;\n            *outEnd = end;\n            //printf(\"Found unit %s for %s\\n\", cur->name, str);\n            return true;\n        }\n        cur++;\n    }\n\n    return false;\n}\n\nbool U16StringToInt(const char16_t* s, size_t len, Res_value* outValue)\n{\n    while (len > 0 && isspace16(*s)) {\n        s++;\n        len--;\n    }\n\n    if (len <= 0) {\n        return false;\n    }\n\n    size_t i = 0;\n    int64_t val = 0;\n    bool neg = false;\n\n    if (*s == '-') {\n        neg = true;\n        i++;\n    }\n\n    if (s[i] < '0' || s[i] > '9') {\n        return false;\n    }\n\n    static_assert(std::is_same<uint32_t, Res_value::data_type>::value,\n                  \"Res_value::data_type has changed. The range checks in this \"\n                  \"function are no longer correct.\");\n\n    // Decimal or hex?\n    bool isHex;\n    if (len > 1 && s[i] == '0' && s[i+1] == 'x') {\n        isHex = true;\n        i += 2;\n\n        if (neg) {\n            return false;\n        }\n\n        if (i == len) {\n            // Just u\"0x\"\n            return false;\n        }\n\n        bool error = false;\n        while (i < len && !error) {\n            val = (val*16) + get_hex(s[i], &error);\n            i++;\n\n            if (val > std::numeric_limits<uint32_t>::max()) {\n                return false;\n            }\n        }\n        if (error) {\n            return false;\n        }\n    } else {\n        isHex = false;\n        while (i < len) {\n            if (s[i] < '0' || s[i] > '9') {\n                return false;\n            }\n            val = (val*10) + s[i]-'0';\n            i++;\n\n            if ((neg && -val < std::numeric_limits<int32_t>::min()) ||\n                (!neg && val > std::numeric_limits<int32_t>::max())) {\n                return false;\n            }\n        }\n    }\n\n    if (neg) val = -val;\n\n    while (i < len && isspace16(s[i])) {\n        i++;\n    }\n\n    if (i != len) {\n        return false;\n    }\n\n    if (outValue) {\n        outValue->dataType =\n            isHex ? outValue->TYPE_INT_HEX : outValue->TYPE_INT_DEC;\n        outValue->data = static_cast<Res_value::data_type>(val);\n    }\n    return true;\n}\n\nbool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue)\n{\n    return U16StringToInt(s, len, outValue);\n}\n\nbool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue)\n{\n    while (len > 0 && isspace16(*s)) {\n        s++;\n        len--;\n    }\n\n    if (len <= 0) {\n        return false;\n    }\n\n    char buf[128];\n    int i=0;\n    while (len > 0 && *s != 0 && i < 126) {\n        if (*s > 255) {\n            return false;\n        }\n        buf[i++] = *s++;\n        len--;\n    }\n\n    if (len > 0) {\n        return false;\n    }\n    if ((buf[0] < '0' || buf[0] > '9') && buf[0] != '.' && buf[0] != '-' && buf[0] != '+') {\n        return false;\n    }\n\n    buf[i] = 0;\n    const char* end;\n    float f = strtof(buf, (char**)&end);\n\n    if (*end != 0 && !isspace((unsigned char)*end)) {\n        // Might be a unit...\n        float scale;\n        if (parse_unit(end, outValue, &scale, &end)) {\n            f *= scale;\n            const bool neg = f < 0;\n            if (neg) f = -f;\n            uint64_t bits = (uint64_t)(f*(1<<23)+.5f);\n            uint32_t radix;\n            uint32_t shift;\n            if ((bits&0x7fffff) == 0) {\n                // Always use 23p0 if there is no fraction, just to make\n                // things easier to read.\n                radix = Res_value::COMPLEX_RADIX_23p0;\n                shift = 23;\n            } else if ((bits&0xffffffffff800000LL) == 0) {\n                // Magnitude is zero -- can fit in 0 bits of precision.\n                radix = Res_value::COMPLEX_RADIX_0p23;\n                shift = 0;\n            } else if ((bits&0xffffffff80000000LL) == 0) {\n                // Magnitude can fit in 8 bits of precision.\n                radix = Res_value::COMPLEX_RADIX_8p15;\n                shift = 8;\n            } else if ((bits&0xffffff8000000000LL) == 0) {\n                // Magnitude can fit in 16 bits of precision.\n                radix = Res_value::COMPLEX_RADIX_16p7;\n                shift = 16;\n            } else {\n                // Magnitude needs entire range, so no fractional part.\n                radix = Res_value::COMPLEX_RADIX_23p0;\n                shift = 23;\n            }\n            int32_t mantissa = (int32_t)(\n                (bits>>shift) & Res_value::COMPLEX_MANTISSA_MASK);\n            if (neg) {\n                mantissa = (-mantissa) & Res_value::COMPLEX_MANTISSA_MASK;\n            }\n            outValue->data |=\n                (radix<<Res_value::COMPLEX_RADIX_SHIFT)\n                | (mantissa<<Res_value::COMPLEX_MANTISSA_SHIFT);\n            //printf(\"Input value: %f 0x%016Lx, mult: %f, radix: %d, shift: %d, final: 0x%08x\\n\",\n            //       f * (neg ? -1 : 1), bits, f*(1<<23),\n            //       radix, shift, outValue->data);\n            return true;\n        }\n        return false;\n    }\n\n    while (*end != 0 && isspace((unsigned char)*end)) {\n        end++;\n    }\n\n    if (*end == 0) {\n        if (outValue) {\n            outValue->dataType = outValue->TYPE_FLOAT;\n            *(float*)(&outValue->data) = f;\n            return true;\n        }\n    }\n\n    return false;\n}\n\nbool ResTable::stringToValue(Res_value* outValue, String16* outString,\n                             const char16_t* s, size_t len,\n                             bool preserveSpaces, bool coerceType,\n                             uint32_t attrID,\n                             const String16* defType,\n                             const String16* defPackage,\n                             Accessor* accessor,\n                             void* accessorCookie,\n                             uint32_t attrType,\n                             bool enforcePrivate,\n                             bool printError) const\n{\n    bool localizationSetting = accessor != NULL && accessor->getLocalizationSetting();\n    const char* errorMsg = NULL;\n\n    outValue->size = sizeof(Res_value);\n    outValue->res0 = 0;\n\n    // First strip leading/trailing whitespace.  Do this before handling\n    // escapes, so they can be used to force whitespace into the string.\n    if (!preserveSpaces) {\n        while (len > 0 && isspace16(*s)) {\n            s++;\n            len--;\n        }\n        while (len > 0 && isspace16(s[len-1])) {\n            len--;\n        }\n        // If the string ends with '\\', then we keep the space after it.\n        if (len > 0 && s[len-1] == '\\\\' && s[len] != 0) {\n            len++;\n        }\n    }\n\n    //printf(\"Value for: %s\\n\", String8(s, len).string());\n\n    uint32_t l10nReq = ResTable_map::L10N_NOT_REQUIRED;\n    uint32_t attrMin = 0x80000000, attrMax = 0x7fffffff;\n    bool fromAccessor = false;\n    if (attrID != 0 && !Res_INTERNALID(attrID)) {\n        const ssize_t p = getResourcePackageIndex(attrID);\n        const bag_entry* bag;\n        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;\n        //printf(\"For attr 0x%08x got bag of %d\\n\", attrID, cnt);\n        if (cnt >= 0) {\n            while (cnt > 0) {\n                //printf(\"Entry 0x%08x = 0x%08x\\n\", bag->map.name.ident, bag->map.value.data);\n                switch (bag->map.name.ident) {\n                case ResTable_map::ATTR_TYPE:\n                    attrType = bag->map.value.data;\n                    break;\n                case ResTable_map::ATTR_MIN:\n                    attrMin = bag->map.value.data;\n                    break;\n                case ResTable_map::ATTR_MAX:\n                    attrMax = bag->map.value.data;\n                    break;\n                case ResTable_map::ATTR_L10N:\n                    l10nReq = bag->map.value.data;\n                    break;\n                }\n                bag++;\n                cnt--;\n            }\n            unlockBag(bag);\n        } else if (accessor && accessor->getAttributeType(attrID, &attrType)) {\n            fromAccessor = true;\n            if (attrType == ResTable_map::TYPE_ENUM\n                    || attrType == ResTable_map::TYPE_FLAGS\n                    || attrType == ResTable_map::TYPE_INTEGER) {\n                accessor->getAttributeMin(attrID, &attrMin);\n                accessor->getAttributeMax(attrID, &attrMax);\n            }\n            if (localizationSetting) {\n                l10nReq = accessor->getAttributeL10N(attrID);\n            }\n        }\n    }\n\n    const bool canStringCoerce =\n        coerceType && (attrType&ResTable_map::TYPE_STRING) != 0;\n\n    if (*s == '@') {\n        outValue->dataType = outValue->TYPE_REFERENCE;\n\n        // Note: we don't check attrType here because the reference can\n        // be to any other type; we just need to count on the client making\n        // sure the referenced type is correct.\n\n        //printf(\"Looking up ref: %s\\n\", String8(s, len).string());\n\n        // It's a reference!\n        if (len == 5 && s[1]=='n' && s[2]=='u' && s[3]=='l' && s[4]=='l') {\n            // Special case @null as undefined. This will be converted by\n            // AssetManager to TYPE_NULL with data DATA_NULL_UNDEFINED.\n            outValue->data = 0;\n            return true;\n        } else if (len == 6 && s[1]=='e' && s[2]=='m' && s[3]=='p' && s[4]=='t' && s[5]=='y') {\n            // Special case @empty as explicitly defined empty value.\n            outValue->dataType = Res_value::TYPE_NULL;\n            outValue->data = Res_value::DATA_NULL_EMPTY;\n            return true;\n        } else {\n            bool createIfNotFound = false;\n            const char16_t* resourceRefName;\n            int resourceNameLen;\n            if (len > 2 && s[1] == '+') {\n                createIfNotFound = true;\n                resourceRefName = s + 2;\n                resourceNameLen = len - 2;\n            } else if (len > 2 && s[1] == '*') {\n                enforcePrivate = false;\n                resourceRefName = s + 2;\n                resourceNameLen = len - 2;\n            } else {\n                createIfNotFound = false;\n                resourceRefName = s + 1;\n                resourceNameLen = len - 1;\n            }\n            String16 package, type, name;\n            if (!expandResourceRef(resourceRefName,resourceNameLen, &package, &type, &name,\n                                   defType, defPackage, &errorMsg)) {\n                if (accessor != NULL&& printError) {\n                    accessor->reportError(accessorCookie, errorMsg);\n                }\n                return false;\n            }\n\n            uint32_t specFlags = 0;\n            uint32_t rid = identifierForName(name.string(), name.size(), type.string(),\n                    type.size(), package.string(), package.size(), &specFlags);\n            if (rid != 0) {\n                if (enforcePrivate) {\n                    if (accessor == NULL) {\n                        if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {\n                            if (accessor != NULL&& printError) {\n                                accessor->reportError(accessorCookie, \"Resource is not public.\");\n                            }\n                            return false;\n                        }\n                    }\n                }\n\n                if (accessor) {\n                    rid = Res_MAKEID(\n                        accessor->getRemappedPackage(Res_GETPACKAGE(rid)),\n                        Res_GETTYPE(rid), Res_GETENTRY(rid));\n                    if (kDebugTableNoisy) {\n                        ALOGI(\"Incl %s:%s/%s: 0x%08x\\n\",\n                                String8(package).string(), String8(type).string(),\n                                String8(name).string(), rid);\n                    }\n                }\n\n                uint32_t packageId = Res_GETPACKAGE(rid) + 1;\n                if (packageId != customePackageId && packageId != SYS_PACKAGE_ID &&packageId != APP_PACKAGE_ID) {\n                    outValue->dataType = Res_value::TYPE_DYNAMIC_REFERENCE;\n                }\n                outValue->data = rid;\n                return true;\n            }\n\n            if (accessor) {\n                uint32_t rid = accessor->getCustomResourceWithCreation(package, type, name,\n                                                                       createIfNotFound);\n                if (rid != 0) {\n                    if (kDebugTableNoisy) {\n                        ALOGI(\"Pckg %s:%s/%s: 0x%08x\\n\",\n                                String8(package).string(), String8(type).string(),\n                                String8(name).string(), rid);\n                    }\n                    uint32_t packageId = Res_GETPACKAGE(rid) + 1;\n                    if (packageId == 0x00) {\n                        outValue->data = rid;\n                        outValue->dataType = Res_value::TYPE_DYNAMIC_REFERENCE;\n                        return true;\n                    } else if (packageId == customePackageId || packageId == SYS_PACKAGE_ID || packageId == APP_PACKAGE_ID) {\n                        // We accept packageId's generated as 0x01 in order to support\n                        // building the android system resources\n                        outValue->data = rid;\n                        return true;\n                    }\n                }\n            }\n        }\n\n        if (accessor != NULL && printError) {\n            accessor->reportError(accessorCookie, \"No resource found that matches the given name\");\n        }\n        return false;\n    }\n\n    // if we got to here, and localization is required and it's not a reference,\n    // complain and bail.\n    if (l10nReq == ResTable_map::L10N_SUGGESTED) {\n        if (localizationSetting) {\n            if (accessor != NULL && printError) {\n                accessor->reportError(accessorCookie, \"This attribute must be localized.\");\n            }\n        }\n    }\n\n    if (*s == '#') {\n        // It's a color!  Convert to an integer of the form 0xaarrggbb.\n        uint32_t color = 0;\n        bool error = false;\n        if (len == 4) {\n            outValue->dataType = outValue->TYPE_INT_COLOR_RGB4;\n            color |= 0xFF000000;\n            color |= get_hex(s[1], &error) << 20;\n            color |= get_hex(s[1], &error) << 16;\n            color |= get_hex(s[2], &error) << 12;\n            color |= get_hex(s[2], &error) << 8;\n            color |= get_hex(s[3], &error) << 4;\n            color |= get_hex(s[3], &error);\n        } else if (len == 5) {\n            outValue->dataType = outValue->TYPE_INT_COLOR_ARGB4;\n            color |= get_hex(s[1], &error) << 28;\n            color |= get_hex(s[1], &error) << 24;\n            color |= get_hex(s[2], &error) << 20;\n            color |= get_hex(s[2], &error) << 16;\n            color |= get_hex(s[3], &error) << 12;\n            color |= get_hex(s[3], &error) << 8;\n            color |= get_hex(s[4], &error) << 4;\n            color |= get_hex(s[4], &error);\n        } else if (len == 7) {\n            outValue->dataType = outValue->TYPE_INT_COLOR_RGB8;\n            color |= 0xFF000000;\n            color |= get_hex(s[1], &error) << 20;\n            color |= get_hex(s[2], &error) << 16;\n            color |= get_hex(s[3], &error) << 12;\n            color |= get_hex(s[4], &error) << 8;\n            color |= get_hex(s[5], &error) << 4;\n            color |= get_hex(s[6], &error);\n        } else if (len == 9) {\n            outValue->dataType = outValue->TYPE_INT_COLOR_ARGB8;\n            color |= get_hex(s[1], &error) << 28;\n            color |= get_hex(s[2], &error) << 24;\n            color |= get_hex(s[3], &error) << 20;\n            color |= get_hex(s[4], &error) << 16;\n            color |= get_hex(s[5], &error) << 12;\n            color |= get_hex(s[6], &error) << 8;\n            color |= get_hex(s[7], &error) << 4;\n            color |= get_hex(s[8], &error);\n        } else {\n            error = true;\n        }\n        if (!error) {\n            if ((attrType&ResTable_map::TYPE_COLOR) == 0) {\n                if (!canStringCoerce) {\n                    if (accessor != NULL) {\n                        accessor->reportError(accessorCookie,\n                                \"Color types not allowed\");\n                    }\n                    return false;\n                }\n            } else {\n                outValue->data = color;\n                //printf(\"Color input=%s, output=0x%x\\n\", String8(s, len).string(), color);\n                return true;\n            }\n        } else {\n            if ((attrType&ResTable_map::TYPE_COLOR) != 0) {\n                if (accessor != NULL) {\n                    accessor->reportError(accessorCookie, \"Color value not valid --\"\n                            \" must be #rgb, #argb, #rrggbb, or #aarrggbb\");\n                }\n                #if 0\n                fprintf(stderr, \"%s: Color ID %s value %s is not valid\\n\",\n                        \"Resource File\", //(const char*)in->getPrintableSource(),\n                        String8(*curTag).string(),\n                        String8(s, len).string());\n                #endif\n                return false;\n            }\n        }\n    }\n\n    if (*s == '?') {\n        outValue->dataType = outValue->TYPE_ATTRIBUTE;\n\n        // Note: we don't check attrType here because the reference can\n        // be to any other type; we just need to count on the client making\n        // sure the referenced type is correct.\n\n        //printf(\"Looking up attr: %s\\n\", String8(s, len).string());\n\n        static const String16 attr16(\"attr\");\n        String16 package, type, name;\n        if (!expandResourceRef(s+1, len-1, &package, &type, &name,\n                               &attr16, defPackage, &errorMsg)) {\n            if (accessor != NULL) {\n                accessor->reportError(accessorCookie, errorMsg);\n            }\n            return false;\n        }\n\n        //printf(\"Pkg: %s, Type: %s, Name: %s\\n\",\n        //       String8(package).string(), String8(type).string(),\n        //       String8(name).string());\n        uint32_t specFlags = 0;\n        uint32_t rid =\n            identifierForName(name.string(), name.size(),\n                              type.string(), type.size(),\n                              package.string(), package.size(), &specFlags);\n        if (rid != 0) {\n            if (enforcePrivate) {\n                if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {\n                    if (accessor != NULL) {\n                        accessor->reportError(accessorCookie, \"Attribute is not public.\");\n                    }\n                    return false;\n                }\n            }\n\n            if (accessor) {\n                rid = Res_MAKEID(\n                    accessor->getRemappedPackage(Res_GETPACKAGE(rid)),\n                    Res_GETTYPE(rid), Res_GETENTRY(rid));\n            }\n\n            uint32_t packageId = Res_GETPACKAGE(rid) + 1;\n            if (packageId != customePackageId && packageId != APP_PACKAGE_ID && packageId != SYS_PACKAGE_ID) {\n                outValue->dataType = Res_value::TYPE_DYNAMIC_ATTRIBUTE;\n            }\n            outValue->data = rid;\n            return true;\n        }\n\n        if (accessor) {\n            uint32_t rid = accessor->getCustomResource(package, type, name);\n            if (rid != 0) {\n                uint32_t packageId = Res_GETPACKAGE(rid) + 1;\n                if (packageId == 0x00) {\n                    outValue->data = rid;\n                    outValue->dataType = Res_value::TYPE_DYNAMIC_ATTRIBUTE;\n                    return true;\n                } else if (packageId != customePackageId || packageId == APP_PACKAGE_ID || packageId == SYS_PACKAGE_ID) {\n                    // We accept packageId's generated as 0x01 in order to support\n                    // building the android system resources\n                    outValue->data = rid;\n                    return true;\n                }\n            }\n        }\n\n        if (accessor != NULL && printError) {\n            accessor->reportError(accessorCookie, \"No resource found that matches the given name\");\n        }\n        return false;\n    }\n\n    if (stringToInt(s, len, outValue)) {\n        if ((attrType&ResTable_map::TYPE_INTEGER) == 0) {\n            // If this type does not allow integers, but does allow floats,\n            // fall through on this error case because the float type should\n            // be able to accept any integer value.\n            if (!canStringCoerce && (attrType&ResTable_map::TYPE_FLOAT) == 0) {\n                if (accessor != NULL) {\n                    accessor->reportError(accessorCookie, \"Integer types not allowed\");\n                }\n                return false;\n            }\n        } else {\n            if (((int32_t)outValue->data) < ((int32_t)attrMin)\n                    || ((int32_t)outValue->data) > ((int32_t)attrMax)) {\n                if (accessor != NULL) {\n                    accessor->reportError(accessorCookie, \"Integer value out of range\");\n                }\n                return false;\n            }\n            return true;\n        }\n    }\n\n    if (stringToFloat(s, len, outValue)) {\n        if (outValue->dataType == Res_value::TYPE_DIMENSION) {\n            if ((attrType&ResTable_map::TYPE_DIMENSION) != 0) {\n                return true;\n            }\n            if (!canStringCoerce) {\n                if (accessor != NULL) {\n                    accessor->reportError(accessorCookie, \"Dimension types not allowed\");\n                }\n                return false;\n            }\n        } else if (outValue->dataType == Res_value::TYPE_FRACTION) {\n            if ((attrType&ResTable_map::TYPE_FRACTION) != 0) {\n                return true;\n            }\n            if (!canStringCoerce) {\n                if (accessor != NULL) {\n                    accessor->reportError(accessorCookie, \"Fraction types not allowed\");\n                }\n                return false;\n            }\n        } else if ((attrType&ResTable_map::TYPE_FLOAT) == 0) {\n            if (!canStringCoerce) {\n                if (accessor != NULL) {\n                    accessor->reportError(accessorCookie, \"Float types not allowed\");\n                }\n                return false;\n            }\n        } else {\n            return true;\n        }\n    }\n\n    if (len == 4) {\n        if ((s[0] == 't' || s[0] == 'T') &&\n            (s[1] == 'r' || s[1] == 'R') &&\n            (s[2] == 'u' || s[2] == 'U') &&\n            (s[3] == 'e' || s[3] == 'E')) {\n            if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {\n                if (!canStringCoerce) {\n                    if (accessor != NULL) {\n                        accessor->reportError(accessorCookie, \"Boolean types not allowed\");\n                    }\n                    return false;\n                }\n            } else {\n                outValue->dataType = outValue->TYPE_INT_BOOLEAN;\n                outValue->data = (uint32_t)-1;\n                return true;\n            }\n        }\n    }\n\n    if (len == 5) {\n        if ((s[0] == 'f' || s[0] == 'F') &&\n            (s[1] == 'a' || s[1] == 'A') &&\n            (s[2] == 'l' || s[2] == 'L') &&\n            (s[3] == 's' || s[3] == 'S') &&\n            (s[4] == 'e' || s[4] == 'E')) {\n            if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {\n                if (!canStringCoerce) {\n                    if (accessor != NULL) {\n                        accessor->reportError(accessorCookie, \"Boolean types not allowed\");\n                    }\n                    return false;\n                }\n            } else {\n                outValue->dataType = outValue->TYPE_INT_BOOLEAN;\n                outValue->data = 0;\n                return true;\n            }\n        }\n    }\n\n    if ((attrType&ResTable_map::TYPE_ENUM) != 0) {\n        const ssize_t p = getResourcePackageIndex(attrID);\n        const bag_entry* bag;\n        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;\n        //printf(\"Got %d for enum\\n\", cnt);\n        if (cnt >= 0) {\n            resource_name rname;\n            while (cnt > 0) {\n                if (!Res_INTERNALID(bag->map.name.ident)) {\n                    //printf(\"Trying attr #%08x\\n\", bag->map.name.ident);\n                    if (getResourceName(bag->map.name.ident, false, &rname)) {\n                        #if 0\n                        printf(\"Matching %s against %s (0x%08x)\\n\",\n                               String8(s, len).string(),\n                               String8(rname.name, rname.nameLen).string(),\n                               bag->map.name.ident);\n                        #endif\n                        if (strzcmp16(s, len, rname.name, rname.nameLen) == 0) {\n                            outValue->dataType = bag->map.value.dataType;\n                            outValue->data = bag->map.value.data;\n                            unlockBag(bag);\n                            return true;\n                        }\n                    }\n\n                }\n                bag++;\n                cnt--;\n            }\n            unlockBag(bag);\n        }\n\n        if (fromAccessor) {\n            if (accessor->getAttributeEnum(attrID, s, len, outValue)) {\n                return true;\n            }\n        }\n    }\n\n    if ((attrType&ResTable_map::TYPE_FLAGS) != 0) {\n        const ssize_t p = getResourcePackageIndex(attrID);\n        const bag_entry* bag;\n        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;\n        //printf(\"Got %d for flags\\n\", cnt);\n        if (cnt >= 0) {\n            bool failed = false;\n            resource_name rname;\n            outValue->dataType = Res_value::TYPE_INT_HEX;\n            outValue->data = 0;\n            const char16_t* end = s + len;\n            const char16_t* pos = s;\n            while (pos < end && !failed) {\n                const char16_t* start = pos;\n                pos++;\n                while (pos < end && *pos != '|') {\n                    pos++;\n                }\n                //printf(\"Looking for: %s\\n\", String8(start, pos-start).string());\n                const bag_entry* bagi = bag;\n                ssize_t i;\n                for (i=0; i<cnt; i++, bagi++) {\n                    if (!Res_INTERNALID(bagi->map.name.ident)) {\n                        //printf(\"Trying attr #%08x\\n\", bagi->map.name.ident);\n                        if (getResourceName(bagi->map.name.ident, false, &rname)) {\n                            #if 0\n                            printf(\"Matching %s against %s (0x%08x)\\n\",\n                                   String8(start,pos-start).string(),\n                                   String8(rname.name, rname.nameLen).string(),\n                                   bagi->map.name.ident);\n                            #endif\n                            if (strzcmp16(start, pos-start, rname.name, rname.nameLen) == 0) {\n                                outValue->data |= bagi->map.value.data;\n                                break;\n                            }\n                        }\n                    }\n                }\n                if (i >= cnt) {\n                    // Didn't find this flag identifier.\n                    failed = true;\n                }\n                if (pos < end) {\n                    pos++;\n                }\n            }\n            unlockBag(bag);\n            if (!failed) {\n                //printf(\"Final flag value: 0x%lx\\n\", outValue->data);\n                return true;\n            }\n        }\n\n\n        if (fromAccessor) {\n            if (accessor->getAttributeFlags(attrID, s, len, outValue)) {\n                //printf(\"Final flag value: 0x%lx\\n\", outValue->data);\n                return true;\n            }\n        }\n    }\n\n    if ((attrType&ResTable_map::TYPE_STRING) == 0) {\n        if (accessor != NULL) {\n            accessor->reportError(accessorCookie, \"String types not allowed\");\n        }\n        return false;\n    }\n\n    // Generic string handling...\n    outValue->dataType = outValue->TYPE_STRING;\n    if (outString) {\n        bool failed = collectString(outString, s, len, preserveSpaces, &errorMsg);\n        if (accessor != NULL) {\n            accessor->reportError(accessorCookie, errorMsg);\n        }\n        return failed;\n    }\n\n    return true;\n}\n\nbool ResTable::collectString(String16* outString,\n                             const char16_t* s, size_t len,\n                             bool preserveSpaces,\n                             const char** outErrorMsg,\n                             bool append)\n{\n    String16 tmp;\n\n    char quoted = 0;\n    const char16_t* p = s;\n    while (p < (s+len)) {\n        while (p < (s+len)) {\n            const char16_t c = *p;\n            if (c == '\\\\') {\n                break;\n            }\n            if (!preserveSpaces) {\n                if (quoted == 0 && isspace16(c)\n                    && (c != ' ' || isspace16(*(p+1)))) {\n                    break;\n                }\n                if (c == '\"' && (quoted == 0 || quoted == '\"')) {\n                    break;\n                }\n                if (c == '\\'' && (quoted == 0 || quoted == '\\'')) {\n                    /*\n                     * In practice, when people write ' instead of \\'\n                     * in a string, they are doing it by accident\n                     * instead of really meaning to use ' as a quoting\n                     * character.  Warn them so they don't lose it.\n                     */\n                    if (outErrorMsg) {\n                        *outErrorMsg = \"Apostrophe not preceded by \\\\\";\n                    }\n                    return false;\n                }\n            }\n            p++;\n        }\n        if (p < (s+len)) {\n            if (p > s) {\n                tmp.append(String16(s, p-s));\n            }\n            if (!preserveSpaces && (*p == '\"' || *p == '\\'')) {\n                if (quoted == 0) {\n                    quoted = *p;\n                } else {\n                    quoted = 0;\n                }\n                p++;\n            } else if (!preserveSpaces && isspace16(*p)) {\n                // Space outside of a quote -- consume all spaces and\n                // leave a single plain space char.\n                tmp.append(String16(\" \"));\n                p++;\n                while (p < (s+len) && isspace16(*p)) {\n                    p++;\n                }\n            } else if (*p == '\\\\') {\n                p++;\n                if (p < (s+len)) {\n                    switch (*p) {\n                    case 't':\n                        tmp.append(String16(\"\\t\"));\n                        break;\n                    case 'n':\n                        tmp.append(String16(\"\\n\"));\n                        break;\n                    case '#':\n                        tmp.append(String16(\"#\"));\n                        break;\n                    case '@':\n                        tmp.append(String16(\"@\"));\n                        break;\n                    case '?':\n                        tmp.append(String16(\"?\"));\n                        break;\n                    case '\"':\n                        tmp.append(String16(\"\\\"\"));\n                        break;\n                    case '\\'':\n                        tmp.append(String16(\"'\"));\n                        break;\n                    case '\\\\':\n                        tmp.append(String16(\"\\\\\"));\n                        break;\n                    case 'u':\n                    {\n                        char16_t chr = 0;\n                        int i = 0;\n                        while (i < 4 && p[1] != 0) {\n                            p++;\n                            i++;\n                            int c;\n                            if (*p >= '0' && *p <= '9') {\n                                c = *p - '0';\n                            } else if (*p >= 'a' && *p <= 'f') {\n                                c = *p - 'a' + 10;\n                            } else if (*p >= 'A' && *p <= 'F') {\n                                c = *p - 'A' + 10;\n                            } else {\n                                if (outErrorMsg) {\n                                    *outErrorMsg = \"Bad character in \\\\u unicode escape sequence\";\n                                }\n                                return false;\n                            }\n                            chr = (chr<<4) | c;\n                        }\n                        tmp.append(String16(&chr, 1));\n                    } break;\n                    default:\n                        // ignore unknown escape chars.\n                        break;\n                    }\n                    p++;\n                }\n            }\n            len -= (p-s);\n            s = p;\n        }\n    }\n\n    if (tmp.size() != 0) {\n        if (len > 0) {\n            tmp.append(String16(s, len));\n        }\n        if (append) {\n            outString->append(tmp);\n        } else {\n            outString->setTo(tmp);\n        }\n    } else {\n        if (append) {\n            outString->append(String16(s, len));\n        } else {\n            outString->setTo(s, len);\n        }\n    }\n\n    return true;\n}\n\nsize_t ResTable::getBasePackageCount() const\n{\n    if (mError != NO_ERROR) {\n        return 0;\n    }\n    return mPackageGroups.size();\n}\n\nconst String16 ResTable::getBasePackageName(size_t idx) const\n{\n    if (mError != NO_ERROR) {\n        return String16();\n    }\n    LOG_FATAL_IF(idx >= mPackageGroups.size(),\n                 \"Requested package index %d past package count %d\",\n                 (int)idx, (int)mPackageGroups.size());\n    return mPackageGroups[idx]->name;\n}\n\nuint32_t ResTable::getBasePackageId(size_t idx) const\n{\n    if (mError != NO_ERROR) {\n        return 0;\n    }\n    LOG_FATAL_IF(idx >= mPackageGroups.size(),\n                 \"Requested package index %d past package count %d\",\n                 (int)idx, (int)mPackageGroups.size());\n    return mPackageGroups[idx]->id;\n}\n\nuint32_t ResTable::getLastTypeIdForPackage(size_t idx) const\n{\n    if (mError != NO_ERROR) {\n        return 0;\n    }\n    LOG_FATAL_IF(idx >= mPackageGroups.size(),\n            \"Requested package index %d past package count %d\",\n            (int)idx, (int)mPackageGroups.size());\n    const PackageGroup* const group = mPackageGroups[idx];\n    return group->largestTypeId;\n}\n\nsize_t ResTable::getTableCount() const\n{\n    return mHeaders.size();\n}\n\nconst ResStringPool* ResTable::getTableStringBlock(size_t index) const\n{\n    return &mHeaders[index]->values;\n}\n\nint32_t ResTable::getTableCookie(size_t index) const\n{\n    return mHeaders[index]->cookie;\n}\n\nconst DynamicRefTable* ResTable::getDynamicRefTableForCookie(int32_t cookie) const\n{\n    const size_t N = mPackageGroups.size();\n    for (size_t i = 0; i < N; i++) {\n        const PackageGroup* pg = mPackageGroups[i];\n        size_t M = pg->packages.size();\n        for (size_t j = 0; j < M; j++) {\n            if (pg->packages[j]->header->cookie == cookie) {\n                return &pg->dynamicRefTable;\n            }\n        }\n    }\n    return NULL;\n}\n\nstatic bool compareResTableConfig(const ResTable_config& a, const ResTable_config& b) {\n    return a.compare(b) < 0;\n}\n\ntemplate <typename Func>\nvoid ResTable::forEachConfiguration(bool ignoreMipmap, bool ignoreAndroidPackage,\n                                    bool includeSystemConfigs, const Func& f) const {\n    const size_t packageCount = mPackageGroups.size();\n    const String16 android(\"android\");\n    for (size_t i = 0; i < packageCount; i++) {\n        const PackageGroup* packageGroup = mPackageGroups[i];\n        if (ignoreAndroidPackage && android == packageGroup->name) {\n            continue;\n        }\n        if (!includeSystemConfigs && packageGroup->isSystemAsset) {\n            continue;\n        }\n        const size_t typeCount = packageGroup->types.size();\n        for (size_t j = 0; j < typeCount; j++) {\n            const TypeList& typeList = packageGroup->types[j];\n            const size_t numTypes = typeList.size();\n            for (size_t k = 0; k < numTypes; k++) {\n                const Type* type = typeList[k];\n                const ResStringPool& typeStrings = type->package->typeStrings;\n                if (ignoreMipmap && typeStrings.string8ObjectAt(\n                            type->typeSpec->id - 1) == \"mipmap\") {\n                    continue;\n                }\n\n                const size_t numConfigs = type->configs.size();\n                for (size_t m = 0; m < numConfigs; m++) {\n                    const ResTable_type* config = type->configs[m];\n                    ResTable_config cfg;\n                    memset(&cfg, 0, sizeof(ResTable_config));\n                    cfg.copyFromDtoH(config->config);\n\n                    f(cfg);\n                }\n            }\n        }\n    }\n}\n\nvoid ResTable::getConfigurations(Vector<ResTable_config>* configs, bool ignoreMipmap,\n                                 bool ignoreAndroidPackage, bool includeSystemConfigs) const {\n    auto func = [&](const ResTable_config& cfg) {\n        const auto beginIter = configs->begin();\n        const auto endIter = configs->end();\n\n        auto iter = std::lower_bound(beginIter, endIter, cfg, compareResTableConfig);\n        if (iter == endIter || iter->compare(cfg) != 0) {\n            configs->insertAt(cfg, std::distance(beginIter, iter));\n        }\n    };\n    forEachConfiguration(ignoreMipmap, ignoreAndroidPackage, includeSystemConfigs, func);\n}\n\nstatic bool compareString8AndCString(const String8& str, const char* cStr) {\n    return strcmp(str.string(), cStr) < 0;\n}\n\nvoid ResTable::getLocales(Vector<String8>* locales, bool includeSystemLocales) const {\n    char locale[RESTABLE_MAX_LOCALE_LEN];\n\n    forEachConfiguration(false, false, includeSystemLocales, [&](const ResTable_config& cfg) {\n        if (cfg.locale != 0) {\n            cfg.getBcp47Locale(locale);\n\n            const auto beginIter = locales->begin();\n            const auto endIter = locales->end();\n\n            auto iter = std::lower_bound(beginIter, endIter, locale, compareString8AndCString);\n            if (iter == endIter || strcmp(iter->string(), locale) != 0) {\n                locales->insertAt(String8(locale), std::distance(beginIter, iter));\n            }\n        }\n    });\n}\n\nStringPoolRef::StringPoolRef(const ResStringPool* pool, uint32_t index)\n    : mPool(pool), mIndex(index) {}\n\nStringPoolRef::StringPoolRef()\n    : mPool(NULL), mIndex(0) {}\n\nconst char* StringPoolRef::string8(size_t* outLen) const {\n    if (mPool != NULL) {\n        return mPool->string8At(mIndex, outLen);\n    }\n    if (outLen != NULL) {\n        *outLen = 0;\n    }\n    return NULL;\n}\n\nconst char16_t* StringPoolRef::string16(size_t* outLen) const {\n    if (mPool != NULL) {\n        return mPool->stringAt(mIndex, outLen);\n    }\n    if (outLen != NULL) {\n        *outLen = 0;\n    }\n    return NULL;\n}\n\nbool ResTable::getResourceFlags(uint32_t resID, uint32_t* outFlags) const {\n    if (mError != NO_ERROR) {\n        return false;\n    }\n\n    const ssize_t p = getResourcePackageIndex(resID);\n    const int t = Res_GETTYPE(resID);\n    const int e = Res_GETENTRY(resID);\n\n    if (p < 0) {\n        if (Res_GETPACKAGE(resID)+1 == 0) {\n            ALOGW(\"No package identifier when getting flags for resource number 0x%08x\", resID);\n        } else {\n            ALOGW(\"No known package when getting flags for resource number 0x%08x\", resID);\n        }\n        return false;\n    }\n    if (t < 0) {\n        ALOGW(\"No type identifier when getting flags for resource number 0x%08x\", resID);\n        return false;\n    }\n\n    const PackageGroup* const grp = mPackageGroups[p];\n    if (grp == NULL) {\n        ALOGW(\"Bad identifier when getting flags for resource number 0x%08x\", resID);\n        return false;\n    }\n\n    Entry entry;\n    status_t err = getEntry(grp, t, e, NULL, &entry);\n    if (err != NO_ERROR) {\n        return false;\n    }\n\n    *outFlags = entry.specFlags;\n    return true;\n}\n\nstatus_t ResTable::getEntry(\n        const PackageGroup* packageGroup, int typeIndex, int entryIndex,\n        const ResTable_config* config,\n        Entry* outEntry) const\n{\n    const TypeList& typeList = packageGroup->types[typeIndex];\n    if (typeList.isEmpty()) {\n        ALOGV(\"Skipping entry type index 0x%02x because type is NULL!\\n\", typeIndex);\n        return BAD_TYPE;\n    }\n\n    const ResTable_type* bestType = NULL;\n    uint32_t bestOffset = ResTable_type::NO_ENTRY;\n    const Package* bestPackage = NULL;\n    uint32_t specFlags = 0;\n    uint8_t actualTypeIndex = typeIndex;\n    ResTable_config bestConfig;\n    memset(&bestConfig, 0, sizeof(bestConfig));\n\n    // Iterate over the Types of each package.\n    const size_t typeCount = typeList.size();\n    for (size_t i = 0; i < typeCount; i++) {\n        const Type* const typeSpec = typeList[i];\n\n        int realEntryIndex = entryIndex;\n        int realTypeIndex = typeIndex;\n        bool currentTypeIsOverlay = false;\n\n        // Runtime overlay packages provide a mapping of app resource\n        // ID to package resource ID.\n        if (typeSpec->idmapEntries.hasEntries()) {\n            uint16_t overlayEntryIndex;\n            if (typeSpec->idmapEntries.lookup(entryIndex, &overlayEntryIndex) != NO_ERROR) {\n                // No such mapping exists\n                continue;\n            }\n            realEntryIndex = overlayEntryIndex;\n            realTypeIndex = typeSpec->idmapEntries.overlayTypeId() - 1;\n            currentTypeIsOverlay = true;\n        }\n\n        if (static_cast<size_t>(realEntryIndex) >= typeSpec->entryCount) {\n            ALOGW(\"For resource 0x%08x, entry index(%d) is beyond type entryCount(%d)\",\n                    Res_MAKEID(packageGroup->id - 1, typeIndex, entryIndex),\n                    entryIndex, static_cast<int>(typeSpec->entryCount));\n            // We should normally abort here, but some legacy apps declare\n            // resources in the 'android' package (old bug in AAPT).\n            continue;\n        }\n\n        // Aggregate all the flags for each package that defines this entry.\n        if (typeSpec->typeSpecFlags != NULL) {\n            specFlags |= dtohl(typeSpec->typeSpecFlags[realEntryIndex]);\n        } else {\n            specFlags = -1;\n        }\n\n        const Vector<const ResTable_type*>* candidateConfigs = &typeSpec->configs;\n\n        std::shared_ptr<Vector<const ResTable_type*>> filteredConfigs;\n        if (config && memcmp(&mParams, config, sizeof(mParams)) == 0) {\n            // Grab the lock first so we can safely get the current filtered list.\n            AutoMutex _lock(mFilteredConfigLock);\n\n            // This configuration is equal to the one we have previously cached for,\n            // so use the filtered configs.\n\n            const TypeCacheEntry& cacheEntry = packageGroup->typeCacheEntries[typeIndex];\n            if (i < cacheEntry.filteredConfigs.size()) {\n                if (cacheEntry.filteredConfigs[i]) {\n                    // Grab a reference to the shared_ptr so it doesn't get destroyed while\n                    // going through this list.\n                    filteredConfigs = cacheEntry.filteredConfigs[i];\n\n                    // Use this filtered list.\n                    candidateConfigs = filteredConfigs.get();\n                }\n            }\n        }\n\n        const size_t numConfigs = candidateConfigs->size();\n        for (size_t c = 0; c < numConfigs; c++) {\n            const ResTable_type* const thisType = candidateConfigs->itemAt(c);\n            if (thisType == NULL) {\n                continue;\n            }\n\n            ResTable_config thisConfig;\n            thisConfig.copyFromDtoH(thisType->config);\n\n            // Check to make sure this one is valid for the current parameters.\n            if (config != NULL && !thisConfig.match(*config)) {\n                continue;\n            }\n\n            // Check if there is the desired entry in this type.\n            const uint32_t* const eindex = reinterpret_cast<const uint32_t*>(\n                    reinterpret_cast<const uint8_t*>(thisType) + dtohs(thisType->header.headerSize));\n\n            uint32_t thisOffset = dtohl(eindex[realEntryIndex]);\n            if (thisOffset == ResTable_type::NO_ENTRY) {\n                // There is no entry for this index and configuration.\n                continue;\n            }\n\n            if (bestType != NULL) {\n                // Check if this one is less specific than the last found.  If so,\n                // we will skip it.  We check starting with things we most care\n                // about to those we least care about.\n                if (!thisConfig.isBetterThan(bestConfig, config)) {\n                    if (!currentTypeIsOverlay || thisConfig.compare(bestConfig) != 0) {\n                        continue;\n                    }\n                }\n            }\n\n            bestType = thisType;\n            bestOffset = thisOffset;\n            bestConfig = thisConfig;\n            bestPackage = typeSpec->package;\n            actualTypeIndex = realTypeIndex;\n\n            // If no config was specified, any type will do, so skip\n            if (config == NULL) {\n                break;\n            }\n        }\n    }\n\n    if (bestType == NULL) {\n        return BAD_INDEX;\n    }\n\n    bestOffset += dtohl(bestType->entriesStart);\n\n    if (bestOffset > (dtohl(bestType->header.size)-sizeof(ResTable_entry))) {\n        ALOGW(\"ResTable_entry at 0x%x is beyond type chunk data 0x%x\",\n                bestOffset, dtohl(bestType->header.size));\n        return BAD_TYPE;\n    }\n    if ((bestOffset & 0x3) != 0) {\n        ALOGW(\"ResTable_entry at 0x%x is not on an integer boundary\", bestOffset);\n        return BAD_TYPE;\n    }\n\n    const ResTable_entry* const entry = reinterpret_cast<const ResTable_entry*>(\n            reinterpret_cast<const uint8_t*>(bestType) + bestOffset);\n    if (dtohs(entry->size) < sizeof(*entry)) {\n        ALOGW(\"ResTable_entry size 0x%x is too small\", dtohs(entry->size));\n        return BAD_TYPE;\n    }\n\n    if (outEntry != NULL) {\n        outEntry->entry = entry;\n        outEntry->config = bestConfig;\n        outEntry->type = bestType;\n        outEntry->specFlags = specFlags;\n        outEntry->package = bestPackage;\n        outEntry->typeStr = StringPoolRef(&bestPackage->typeStrings, actualTypeIndex - bestPackage->typeIdOffset);\n        outEntry->keyStr = StringPoolRef(&bestPackage->keyStrings, dtohl(entry->key.index));\n    }\n    return NO_ERROR;\n}\n\nstatus_t ResTable::parsePackage(const ResTable_package* const pkg,\n                                const Header* const header, bool appAsLib, bool isSystemAsset)\n{\n    const uint8_t* base = (const uint8_t*)pkg;\n    status_t err = validate_chunk(&pkg->header, sizeof(*pkg) - sizeof(pkg->typeIdOffset),\n                                  header->dataEnd, \"ResTable_package\");\n    if (err != NO_ERROR) {\n        return (mError=err);\n    }\n\n    const uint32_t pkgSize = dtohl(pkg->header.size);\n\n    if (dtohl(pkg->typeStrings) >= pkgSize) {\n        ALOGW(\"ResTable_package type strings at 0x%x are past chunk size 0x%x.\",\n             dtohl(pkg->typeStrings), pkgSize);\n        return (mError=BAD_TYPE);\n    }\n    if ((dtohl(pkg->typeStrings)&0x3) != 0) {\n        ALOGW(\"ResTable_package type strings at 0x%x is not on an integer boundary.\",\n             dtohl(pkg->typeStrings));\n        return (mError=BAD_TYPE);\n    }\n    if (dtohl(pkg->keyStrings) >= pkgSize) {\n        ALOGW(\"ResTable_package key strings at 0x%x are past chunk size 0x%x.\",\n             dtohl(pkg->keyStrings), pkgSize);\n        return (mError=BAD_TYPE);\n    }\n    if ((dtohl(pkg->keyStrings)&0x3) != 0) {\n        ALOGW(\"ResTable_package key strings at 0x%x is not on an integer boundary.\",\n             dtohl(pkg->keyStrings));\n        return (mError=BAD_TYPE);\n    }\n\n    uint32_t id = dtohl(pkg->id);\n    KeyedVector<uint8_t, IdmapEntries> idmapEntries;\n\n    if (header->resourceIDMap != NULL) {\n        uint8_t targetPackageId = 0;\n        status_t err = parseIdmap(header->resourceIDMap, header->resourceIDMapSize, &targetPackageId, &idmapEntries);\n        if (err != NO_ERROR) {\n            ALOGW(\"Overlay is broken\");\n            return (mError=err);\n        }\n        id = targetPackageId;\n    }\n\n    if (id >= 256) {\n        LOG_ALWAYS_FATAL(\"Package id out of range\");\n        return NO_ERROR;\n    } else if (id == 0 || (id == 0x7f && appAsLib) || isSystemAsset) {\n        // This is a library or a system asset, so assign an ID\n        id = mNextPackageId++;\n    }\n\n    PackageGroup* group = NULL;\n    Package* package = new Package(this, header, pkg);\n    if (package == NULL) {\n        return (mError=NO_MEMORY);\n    }\n\n    err = package->typeStrings.setTo(base+dtohl(pkg->typeStrings),\n                                   header->dataEnd-(base+dtohl(pkg->typeStrings)));\n    if (err != NO_ERROR) {\n        delete group;\n        delete package;\n        return (mError=err);\n    }\n\n    err = package->keyStrings.setTo(base+dtohl(pkg->keyStrings),\n                                  header->dataEnd-(base+dtohl(pkg->keyStrings)));\n    if (err != NO_ERROR) {\n        delete group;\n        delete package;\n        return (mError=err);\n    }\n\n    size_t idx = mPackageMap[id];\n    if (idx == 0) {\n        idx = mPackageGroups.size() + 1;\n\n        char16_t tmpName[sizeof(pkg->name)/sizeof(pkg->name[0])];\n        strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(pkg->name[0]));\n        group = new PackageGroup(this, String16(tmpName), id, appAsLib, isSystemAsset);\n        if (group == NULL) {\n            delete package;\n            return (mError=NO_MEMORY);\n        }\n\n        err = mPackageGroups.add(group);\n        if (err < NO_ERROR) {\n            return (mError=err);\n        }\n\n        mPackageMap[id] = static_cast<uint8_t>(idx);\n\n        // Find all packages that reference this package\n        size_t N = mPackageGroups.size();\n        for (size_t i = 0; i < N; i++) {\n            mPackageGroups[i]->dynamicRefTable.addMapping(\n                    group->name, static_cast<uint8_t>(group->id));\n        }\n    } else {\n        group = mPackageGroups.itemAt(idx - 1);\n        if (group == NULL) {\n            return (mError=UNKNOWN_ERROR);\n        }\n    }\n\n    err = group->packages.add(package);\n    if (err < NO_ERROR) {\n        return (mError=err);\n    }\n\n    // Iterate through all chunks.\n    const ResChunk_header* chunk =\n        (const ResChunk_header*)(((const uint8_t*)pkg)\n                                 + dtohs(pkg->header.headerSize));\n    const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size);\n    while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) &&\n           ((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) {\n        if (kDebugTableNoisy) {\n            ALOGV(\"PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\\n\",\n                    dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),\n                    (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)));\n        }\n        const size_t csize = dtohl(chunk->size);\n        const uint16_t ctype = dtohs(chunk->type);\n        if (ctype == RES_TABLE_TYPE_SPEC_TYPE) {\n            const ResTable_typeSpec* typeSpec = (const ResTable_typeSpec*)(chunk);\n            err = validate_chunk(&typeSpec->header, sizeof(*typeSpec),\n                                 endPos, \"ResTable_typeSpec\");\n            if (err != NO_ERROR) {\n                return (mError=err);\n            }\n\n            const size_t typeSpecSize = dtohl(typeSpec->header.size);\n            const size_t newEntryCount = dtohl(typeSpec->entryCount);\n\n            if (kDebugLoadTableNoisy) {\n                ALOGI(\"TypeSpec off %p: type=0x%x, headerSize=0x%x, size=%p\\n\",\n                        (void*)(base-(const uint8_t*)chunk),\n                        dtohs(typeSpec->header.type),\n                        dtohs(typeSpec->header.headerSize),\n                        (void*)typeSpecSize);\n            }\n            // look for block overrun or int overflow when multiplying by 4\n            if ((dtohl(typeSpec->entryCount) > (INT32_MAX/sizeof(uint32_t))\n                    || dtohs(typeSpec->header.headerSize)+(sizeof(uint32_t)*newEntryCount)\n                    > typeSpecSize)) {\n                ALOGW(\"ResTable_typeSpec entry index to %p extends beyond chunk end %p.\",\n                        (void*)(dtohs(typeSpec->header.headerSize) + (sizeof(uint32_t)*newEntryCount)),\n                        (void*)typeSpecSize);\n                return (mError=BAD_TYPE);\n            }\n\n            if (typeSpec->id == 0) {\n                ALOGW(\"ResTable_type has an id of 0.\");\n                return (mError=BAD_TYPE);\n            }\n\n            if (newEntryCount > 0) {\n                uint8_t typeIndex = typeSpec->id - 1;\n                ssize_t idmapIndex = idmapEntries.indexOfKey(typeSpec->id);\n                if (idmapIndex >= 0) {\n                    typeIndex = idmapEntries[idmapIndex].targetTypeId() - 1;\n                }\n\n                TypeList& typeList = group->types.editItemAt(typeIndex);\n                if (!typeList.isEmpty()) {\n                    const Type* existingType = typeList[0];\n                    if (existingType->entryCount != newEntryCount && idmapIndex < 0) {\n                        ALOGW(\"ResTable_typeSpec entry count inconsistent: given %d, previously %d\",\n                                (int) newEntryCount, (int) existingType->entryCount);\n                        // We should normally abort here, but some legacy apps declare\n                        // resources in the 'android' package (old bug in AAPT).\n                    }\n                }\n\n                Type* t = new Type(header, package, newEntryCount);\n                t->typeSpec = typeSpec;\n                t->typeSpecFlags = (const uint32_t*)(\n                        ((const uint8_t*)typeSpec) + dtohs(typeSpec->header.headerSize));\n                if (idmapIndex >= 0) {\n                    t->idmapEntries = idmapEntries[idmapIndex];\n                }\n                typeList.add(t);\n                group->largestTypeId = max(group->largestTypeId, typeSpec->id);\n            } else {\n                ALOGV(\"Skipping empty ResTable_typeSpec for type %d\", typeSpec->id);\n            }\n\n        } else if (ctype == RES_TABLE_TYPE_TYPE) {\n            const ResTable_type* type = (const ResTable_type*)(chunk);\n            err = validate_chunk(&type->header, sizeof(*type)-sizeof(ResTable_config)+4,\n                                 endPos, \"ResTable_type\");\n            if (err != NO_ERROR) {\n                return (mError=err);\n            }\n\n            const uint32_t typeSize = dtohl(type->header.size);\n            const size_t newEntryCount = dtohl(type->entryCount);\n\n            if (kDebugLoadTableNoisy) {\n                printf(\"Type off %p: type=0x%x, headerSize=0x%x, size=%u\\n\",\n                        (void*)(base-(const uint8_t*)chunk),\n                        dtohs(type->header.type),\n                        dtohs(type->header.headerSize),\n                        typeSize);\n            }\n            if (dtohs(type->header.headerSize)+(sizeof(uint32_t)*newEntryCount) > typeSize) {\n                ALOGW(\"ResTable_type entry index to %p extends beyond chunk end 0x%x.\",\n                        (void*)(dtohs(type->header.headerSize) + (sizeof(uint32_t)*newEntryCount)),\n                        typeSize);\n                return (mError=BAD_TYPE);\n            }\n\n            if (newEntryCount != 0\n                && dtohl(type->entriesStart) > (typeSize-sizeof(ResTable_entry))) {\n                ALOGW(\"ResTable_type entriesStart at 0x%x extends beyond chunk end 0x%x.\",\n                     dtohl(type->entriesStart), typeSize);\n                return (mError=BAD_TYPE);\n            }\n\n            if (type->id == 0) {\n                ALOGW(\"ResTable_type has an id of 0.\");\n                return (mError=BAD_TYPE);\n            }\n\n            if (newEntryCount > 0) {\n                uint8_t typeIndex = type->id - 1;\n                ssize_t idmapIndex = idmapEntries.indexOfKey(type->id);\n                if (idmapIndex >= 0) {\n                    typeIndex = idmapEntries[idmapIndex].targetTypeId() - 1;\n                }\n\n                TypeList& typeList = group->types.editItemAt(typeIndex);\n                if (typeList.isEmpty()) {\n                    ALOGE(\"No TypeSpec for type %d\", type->id);\n                    return (mError=BAD_TYPE);\n                }\n\n                Type* t = typeList.editItemAt(typeList.size() - 1);\n                if (newEntryCount != t->entryCount) {\n                    ALOGE(\"ResTable_type entry count inconsistent: given %d, previously %d\",\n                        (int)newEntryCount, (int)t->entryCount);\n                    return (mError=BAD_TYPE);\n                }\n\n                if (t->package != package) {\n                    ALOGE(\"No TypeSpec for type %d\", type->id);\n                    return (mError=BAD_TYPE);\n                }\n\n                t->configs.add(type);\n\n                if (kDebugTableGetEntry) {\n                    ResTable_config thisConfig;\n                    thisConfig.copyFromDtoH(type->config);\n                    ALOGI(\"Adding config to type %d: %s\\n\", type->id,\n                            thisConfig.toString().string());\n                }\n            } else {\n                ALOGV(\"Skipping empty ResTable_type for type %d\", type->id);\n            }\n\n        } else if (ctype == RES_TABLE_LIBRARY_TYPE) {\n            if (group->dynamicRefTable.entries().size() == 0) {\n                status_t err = group->dynamicRefTable.load((const ResTable_lib_header*) chunk);\n                if (err != NO_ERROR) {\n                    return (mError=err);\n                }\n\n                // Fill in the reference table with the entries we already know about.\n                size_t N = mPackageGroups.size();\n                for (size_t i = 0; i < N; i++) {\n                    group->dynamicRefTable.addMapping(mPackageGroups[i]->name, mPackageGroups[i]->id);\n                }\n            } else {\n                ALOGW(\"Found multiple library tables, ignoring...\");\n            }\n        } else {\n            status_t err = validate_chunk(chunk, sizeof(ResChunk_header),\n                                          endPos, \"ResTable_package:unknown\");\n            if (err != NO_ERROR) {\n                return (mError=err);\n            }\n        }\n        chunk = (const ResChunk_header*)\n            (((const uint8_t*)chunk) + csize);\n    }\n\n    return NO_ERROR;\n}\n\nDynamicRefTable::DynamicRefTable(uint8_t packageId, bool appAsLib)\n    : mAssignedPackageId(packageId)\n    , mAppAsLib(appAsLib)\n{\n    memset(mLookupTable, 0, sizeof(mLookupTable));\n\n    // Reserved package ids\n    mLookupTable[customePackageId] = customePackageId;\n    mLookupTable[APP_PACKAGE_ID] = APP_PACKAGE_ID;\n    mLookupTable[SYS_PACKAGE_ID] = SYS_PACKAGE_ID;\n}\n\nstatus_t DynamicRefTable::load(const ResTable_lib_header* const header)\n{\n    const uint32_t entryCount = dtohl(header->count);\n    const uint32_t sizeOfEntries = sizeof(ResTable_lib_entry) * entryCount;\n    const uint32_t expectedSize = dtohl(header->header.size) - dtohl(header->header.headerSize);\n    if (sizeOfEntries > expectedSize) {\n        ALOGE(\"ResTable_lib_header size %u is too small to fit %u entries (x %u).\",\n                expectedSize, entryCount, (uint32_t)sizeof(ResTable_lib_entry));\n        return UNKNOWN_ERROR;\n    }\n\n    const ResTable_lib_entry* entry = (const ResTable_lib_entry*)(((uint8_t*) header) +\n            dtohl(header->header.headerSize));\n    for (uint32_t entryIndex = 0; entryIndex < entryCount; entryIndex++) {\n        uint32_t packageId = dtohl(entry->packageId);\n        char16_t tmpName[sizeof(entry->packageName) / sizeof(char16_t)];\n        strcpy16_dtoh(tmpName, entry->packageName, sizeof(entry->packageName) / sizeof(char16_t));\n        if (kDebugLibNoisy) {\n            ALOGV(\"Found lib entry %s with id %d\\n\", String8(tmpName).string(),\n                    dtohl(entry->packageId));\n        }\n        if (packageId >= 256) {\n            ALOGE(\"Bad package id 0x%08x\", packageId);\n            return UNKNOWN_ERROR;\n        }\n        mEntries.replaceValueFor(String16(tmpName), (uint8_t) packageId);\n        entry = entry + 1;\n    }\n    return NO_ERROR;\n}\n\nstatus_t DynamicRefTable::addMappings(const DynamicRefTable& other) {\n    if (mAssignedPackageId != other.mAssignedPackageId) {\n        return UNKNOWN_ERROR;\n    }\n\n    const size_t entryCount = other.mEntries.size();\n    for (size_t i = 0; i < entryCount; i++) {\n        ssize_t index = mEntries.indexOfKey(other.mEntries.keyAt(i));\n        if (index < 0) {\n            mEntries.add(other.mEntries.keyAt(i), other.mEntries[i]);\n        } else {\n            if (other.mEntries[i] != mEntries[index]) {\n                return UNKNOWN_ERROR;\n            }\n        }\n    }\n\n    // Merge the lookup table. No entry can conflict\n    // (value of 0 means not set).\n    for (size_t i = 0; i < 256; i++) {\n        if (mLookupTable[i] != other.mLookupTable[i]) {\n            if (mLookupTable[i] == 0) {\n                mLookupTable[i] = other.mLookupTable[i];\n            } else if (other.mLookupTable[i] != 0) {\n                return UNKNOWN_ERROR;\n            }\n        }\n    }\n    return NO_ERROR;\n}\n\nstatus_t DynamicRefTable::addMapping(const String16& packageName, uint8_t packageId)\n{\n    ssize_t index = mEntries.indexOfKey(packageName);\n    if (index < 0) {\n        return UNKNOWN_ERROR;\n    }\n    mLookupTable[mEntries.valueAt(index)] = packageId;\n    return NO_ERROR;\n}\n\nstatus_t DynamicRefTable::lookupResourceId(uint32_t* resId) const {\n    uint32_t res = *resId;\n    size_t packageId = Res_GETPACKAGE(res) + 1;\n\n    if ((packageId == customePackageId || packageId == APP_PACKAGE_ID) && !mAppAsLib) {\n        // No lookup needs to be done, app package IDs are absolute.\n        return NO_ERROR;\n    }\n\n    if (packageId == 0 || ((packageId == customePackageId || packageId == APP_PACKAGE_ID) && mAppAsLib)) {\n        // The package ID is 0x00. That means that a shared library is accessing\n        // its own local resource.\n        // Or if app resource is loaded as shared library, the resource which has\n        // app package Id is local resources.\n        // so we fix up those resources with the calling package ID.\n        *resId = (0xFFFFFF & (*resId)) | (((uint32_t) mAssignedPackageId) << 24);\n        return NO_ERROR;\n    }\n\n    // Do a proper lookup.\n    uint8_t translatedId = mLookupTable[packageId];\n    if (translatedId == 0) {\n        ALOGV(\"DynamicRefTable(0x%02x): No mapping for build-time package ID 0x%02x.\",\n                (uint8_t)mAssignedPackageId, (uint8_t)packageId);\n        for (size_t i = 0; i < 256; i++) {\n            if (mLookupTable[i] != 0) {\n                ALOGV(\"e[0x%02x] -> 0x%02x\", (uint8_t)i, mLookupTable[i]);\n            }\n        }\n        return UNKNOWN_ERROR;\n    }\n\n    *resId = (res & 0x00ffffff) | (((uint32_t) translatedId) << 24);\n    return NO_ERROR;\n}\n\nstatus_t DynamicRefTable::lookupResourceValue(Res_value* value) const {\n    uint8_t resolvedType = Res_value::TYPE_REFERENCE;\n    switch (value->dataType) {\n    case Res_value::TYPE_ATTRIBUTE:\n        resolvedType = Res_value::TYPE_ATTRIBUTE;\n        // fallthrough\n    case Res_value::TYPE_REFERENCE:\n        if (!mAppAsLib) {\n            return NO_ERROR;\n        }\n\n        // If the package is loaded as shared library, the resource reference\n        // also need to be fixed.\n        break;\n    case Res_value::TYPE_DYNAMIC_ATTRIBUTE:\n        resolvedType = Res_value::TYPE_ATTRIBUTE;\n        // fallthrough\n    case Res_value::TYPE_DYNAMIC_REFERENCE:\n        break;\n    default:\n        return NO_ERROR;\n    }\n\n    status_t err = lookupResourceId(&value->data);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    value->dataType = resolvedType;\n    return NO_ERROR;\n}\n\nstruct IdmapTypeMap {\n    ssize_t overlayTypeId;\n    size_t entryOffset;\n    Vector<uint32_t> entryMap;\n};\n\nstatus_t ResTable::createIdmap(const ResTable& overlay,\n        uint32_t targetCrc, uint32_t overlayCrc,\n        const char* targetPath, const char* overlayPath,\n        void** outData, size_t* outSize) const\n{\n    // see README for details on the format of map\n    if (mPackageGroups.size() == 0) {\n        ALOGW(\"idmap: target package has no package groups, cannot create idmap\\n\");\n        return UNKNOWN_ERROR;\n    }\n\n    if (mPackageGroups[0]->packages.size() == 0) {\n        ALOGW(\"idmap: target package has no packages in its first package group, \"\n                \"cannot create idmap\\n\");\n        return UNKNOWN_ERROR;\n    }\n\n    KeyedVector<uint8_t, IdmapTypeMap> map;\n\n    // overlaid packages are assumed to contain only one package group\n    const PackageGroup* pg = mPackageGroups[0];\n\n    // starting size is header\n    *outSize = ResTable::IDMAP_HEADER_SIZE_BYTES;\n\n    // target package id and number of types in map\n    *outSize += 2 * sizeof(uint16_t);\n\n    // overlay packages are assumed to contain only one package group\n    const ResTable_package* overlayPackageStruct = overlay.mPackageGroups[0]->packages[0]->package;\n    char16_t tmpName[sizeof(overlayPackageStruct->name)/sizeof(overlayPackageStruct->name[0])];\n    strcpy16_dtoh(tmpName, overlayPackageStruct->name, sizeof(overlayPackageStruct->name)/sizeof(overlayPackageStruct->name[0]));\n    const String16 overlayPackage(tmpName);\n\n    for (size_t typeIndex = 0; typeIndex < pg->types.size(); ++typeIndex) {\n        const TypeList& typeList = pg->types[typeIndex];\n        if (typeList.isEmpty()) {\n            continue;\n        }\n\n        const Type* typeConfigs = typeList[0];\n\n        IdmapTypeMap typeMap;\n        typeMap.overlayTypeId = -1;\n        typeMap.entryOffset = 0;\n\n        for (size_t entryIndex = 0; entryIndex < typeConfigs->entryCount; ++entryIndex) {\n            uint32_t resID = Res_MAKEID(pg->id - 1, typeIndex, entryIndex);\n            resource_name resName;\n            if (!this->getResourceName(resID, false, &resName)) {\n                if (typeMap.entryMap.isEmpty()) {\n                    typeMap.entryOffset++;\n                }\n                continue;\n            }\n\n            const String16 overlayType(resName.type, resName.typeLen);\n            const String16 overlayName(resName.name, resName.nameLen);\n            uint32_t overlayResID = overlay.identifierForName(overlayName.string(),\n                                                              overlayName.size(),\n                                                              overlayType.string(),\n                                                              overlayType.size(),\n                                                              overlayPackage.string(),\n                                                              overlayPackage.size());\n            if (overlayResID == 0) {\n                if (typeMap.entryMap.isEmpty()) {\n                    typeMap.entryOffset++;\n                }\n                continue;\n            }\n\n            if (typeMap.overlayTypeId == -1) {\n                typeMap.overlayTypeId = Res_GETTYPE(overlayResID) + 1;\n            }\n\n            if (Res_GETTYPE(overlayResID) + 1 != static_cast<size_t>(typeMap.overlayTypeId)) {\n                ALOGE(\"idmap: can't mix type ids in entry map. Resource 0x%08x maps to 0x%08x\"\n                        \" but entries should map to resources of type %02zx\",\n                        resID, overlayResID, typeMap.overlayTypeId);\n                return BAD_TYPE;\n            }\n\n            if (typeMap.entryOffset + typeMap.entryMap.size() < entryIndex) {\n                // pad with 0xffffffff's (indicating non-existing entries) before adding this entry\n                size_t index = typeMap.entryMap.size();\n                size_t numItems = entryIndex - (typeMap.entryOffset + index);\n                if (typeMap.entryMap.insertAt(0xffffffff, index, numItems) < 0) {\n                    return NO_MEMORY;\n                }\n            }\n            typeMap.entryMap.add(Res_GETENTRY(overlayResID));\n        }\n\n        if (!typeMap.entryMap.isEmpty()) {\n            if (map.add(static_cast<uint8_t>(typeIndex), typeMap) < 0) {\n                return NO_MEMORY;\n            }\n            *outSize += (4 * sizeof(uint16_t)) + (typeMap.entryMap.size() * sizeof(uint32_t));\n        }\n    }\n\n    if (map.isEmpty()) {\n        ALOGW(\"idmap: no resources in overlay package present in base package\");\n        return UNKNOWN_ERROR;\n    }\n\n    if ((*outData = malloc(*outSize)) == NULL) {\n        return NO_MEMORY;\n    }\n\n    uint32_t* data = (uint32_t*)*outData;\n    *data++ = htodl(IDMAP_MAGIC);\n    *data++ = htodl(IDMAP_CURRENT_VERSION);\n    *data++ = htodl(targetCrc);\n    *data++ = htodl(overlayCrc);\n    const char* paths[] = { targetPath, overlayPath };\n    for (int j = 0; j < 2; ++j) {\n        char* p = (char*)data;\n        const char* path = paths[j];\n        const size_t I = strlen(path);\n        if (I > 255) {\n            ALOGV(\"path exceeds expected 255 characters: %s\\n\", path);\n            return UNKNOWN_ERROR;\n        }\n        for (size_t i = 0; i < 256; ++i) {\n            *p++ = i < I ? path[i] : '\\0';\n        }\n        data += 256 / sizeof(uint32_t);\n    }\n    const size_t mapSize = map.size();\n    uint16_t* typeData = reinterpret_cast<uint16_t*>(data);\n    *typeData++ = htods(pg->id);\n    *typeData++ = htods(mapSize);\n    for (size_t i = 0; i < mapSize; ++i) {\n        uint8_t targetTypeId = map.keyAt(i);\n        const IdmapTypeMap& typeMap = map[i];\n        *typeData++ = htods(targetTypeId + 1);\n        *typeData++ = htods(typeMap.overlayTypeId);\n        *typeData++ = htods(typeMap.entryMap.size());\n        *typeData++ = htods(typeMap.entryOffset);\n\n        const size_t entryCount = typeMap.entryMap.size();\n        uint32_t* entries = reinterpret_cast<uint32_t*>(typeData);\n        for (size_t j = 0; j < entryCount; j++) {\n            entries[j] = htodl(typeMap.entryMap[j]);\n        }\n        typeData += entryCount * 2;\n    }\n\n    return NO_ERROR;\n}\n\nbool ResTable::getIdmapInfo(const void* idmap, size_t sizeBytes,\n                            uint32_t* pVersion,\n                            uint32_t* pTargetCrc, uint32_t* pOverlayCrc,\n                            String8* pTargetPath, String8* pOverlayPath)\n{\n    const uint32_t* map = (const uint32_t*)idmap;\n    if (!assertIdmapHeader(map, sizeBytes)) {\n        return false;\n    }\n    if (pVersion) {\n        *pVersion = dtohl(map[1]);\n    }\n    if (pTargetCrc) {\n        *pTargetCrc = dtohl(map[2]);\n    }\n    if (pOverlayCrc) {\n        *pOverlayCrc = dtohl(map[3]);\n    }\n    if (pTargetPath) {\n        pTargetPath->setTo(reinterpret_cast<const char*>(map + 4));\n    }\n    if (pOverlayPath) {\n        pOverlayPath->setTo(reinterpret_cast<const char*>(map + 4 + 256 / sizeof(uint32_t)));\n    }\n    return true;\n}\n\n\n#define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string())\n\n#define CHAR16_ARRAY_EQ(constant, var, len) \\\n        ((len == (sizeof(constant)/sizeof(constant[0]))) && (0 == memcmp((var), (constant), (len))))\n\nstatic void print_complex(uint32_t complex, bool isFraction)\n{\n    const float MANTISSA_MULT =\n        1.0f / (1<<Res_value::COMPLEX_MANTISSA_SHIFT);\n    const float RADIX_MULTS[] = {\n        1.0f*MANTISSA_MULT, 1.0f/(1<<7)*MANTISSA_MULT,\n        1.0f/(1<<15)*MANTISSA_MULT, 1.0f/(1<<23)*MANTISSA_MULT\n    };\n\n    float value = (complex&(Res_value::COMPLEX_MANTISSA_MASK\n                   <<Res_value::COMPLEX_MANTISSA_SHIFT))\n            * RADIX_MULTS[(complex>>Res_value::COMPLEX_RADIX_SHIFT)\n                            & Res_value::COMPLEX_RADIX_MASK];\n    printf(\"%f\", value);\n\n    if (!isFraction) {\n        switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) {\n            case Res_value::COMPLEX_UNIT_PX: printf(\"px\"); break;\n            case Res_value::COMPLEX_UNIT_DIP: printf(\"dp\"); break;\n            case Res_value::COMPLEX_UNIT_SP: printf(\"sp\"); break;\n            case Res_value::COMPLEX_UNIT_PT: printf(\"pt\"); break;\n            case Res_value::COMPLEX_UNIT_IN: printf(\"in\"); break;\n            case Res_value::COMPLEX_UNIT_MM: printf(\"mm\"); break;\n            default: printf(\" (unknown unit)\"); break;\n        }\n    } else {\n        switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) {\n            case Res_value::COMPLEX_UNIT_FRACTION: printf(\"%%\"); break;\n            case Res_value::COMPLEX_UNIT_FRACTION_PARENT: printf(\"%%p\"); break;\n            default: printf(\" (unknown unit)\"); break;\n        }\n    }\n}\n\n// Normalize a string for output\nString8 ResTable::normalizeForOutput( const char *input )\n{\n    String8 ret;\n    char buff[2];\n    buff[1] = '\\0';\n\n    while (*input != '\\0') {\n        switch (*input) {\n            // All interesting characters are in the ASCII zone, so we are making our own lives\n            // easier by scanning the string one byte at a time.\n        case '\\\\':\n            ret += \"\\\\\\\\\";\n            break;\n        case '\\n':\n            ret += \"\\\\n\";\n            break;\n        case '\"':\n            ret += \"\\\\\\\"\";\n            break;\n        default:\n            buff[0] = *input;\n            ret += buff;\n            break;\n        }\n\n        input++;\n    }\n\n    return ret;\n}\n\nvoid ResTable::print_value(const Package* pkg, const Res_value& value) const\n{\n    if (value.dataType == Res_value::TYPE_NULL) {\n        if (value.data == Res_value::DATA_NULL_UNDEFINED) {\n            printf(\"(null)\\n\");\n        } else if (value.data == Res_value::DATA_NULL_EMPTY) {\n            printf(\"(null empty)\\n\");\n        } else {\n            // This should never happen.\n            printf(\"(null) 0x%08x\\n\", value.data);\n        }\n    } else if (value.dataType == Res_value::TYPE_REFERENCE) {\n        printf(\"(reference) 0x%08x\\n\", value.data);\n    } else if (value.dataType == Res_value::TYPE_DYNAMIC_REFERENCE) {\n        printf(\"(dynamic reference) 0x%08x\\n\", value.data);\n    } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) {\n        printf(\"(attribute) 0x%08x\\n\", value.data);\n    } else if (value.dataType == Res_value::TYPE_DYNAMIC_ATTRIBUTE) {\n        printf(\"(dynamic attribute) 0x%08x\\n\", value.data);\n    } else if (value.dataType == Res_value::TYPE_STRING) {\n        size_t len;\n        const char* str8 = pkg->header->values.string8At(\n                value.data, &len);\n        if (str8 != NULL) {\n            printf(\"(string8) \\\"%s\\\"\\n\", normalizeForOutput(str8).string());\n        } else {\n            const char16_t* str16 = pkg->header->values.stringAt(\n                    value.data, &len);\n            if (str16 != NULL) {\n                printf(\"(string16) \\\"%s\\\"\\n\",\n                    normalizeForOutput(String8(str16, len).string()).string());\n            } else {\n                printf(\"(string) null\\n\");\n            }\n        }\n    } else if (value.dataType == Res_value::TYPE_FLOAT) {\n        printf(\"(float) %g\\n\", *(const float*)&value.data);\n    } else if (value.dataType == Res_value::TYPE_DIMENSION) {\n        printf(\"(dimension) \");\n        print_complex(value.data, false);\n        printf(\"\\n\");\n    } else if (value.dataType == Res_value::TYPE_FRACTION) {\n        printf(\"(fraction) \");\n        print_complex(value.data, true);\n        printf(\"\\n\");\n    } else if (value.dataType >= Res_value::TYPE_FIRST_COLOR_INT\n            || value.dataType <= Res_value::TYPE_LAST_COLOR_INT) {\n        printf(\"(color) #%08x\\n\", value.data);\n    } else if (value.dataType == Res_value::TYPE_INT_BOOLEAN) {\n        printf(\"(boolean) %s\\n\", value.data ? \"true\" : \"false\");\n    } else if (value.dataType >= Res_value::TYPE_FIRST_INT\n            || value.dataType <= Res_value::TYPE_LAST_INT) {\n        printf(\"(int) 0x%08x or %d\\n\", value.data, value.data);\n    } else {\n        printf(\"(unknown type) t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)\\n\",\n               (int)value.dataType, (int)value.data,\n               (int)value.size, (int)value.res0);\n    }\n}\n\nvoid ResTable::print(bool inclValues) const\n{\n    if (mError != 0) {\n        printf(\"mError=0x%x (%s)\\n\", mError, strerror(mError));\n    }\n    size_t pgCount = mPackageGroups.size();\n    printf(\"Package Groups (%d)\\n\", (int)pgCount);\n    for (size_t pgIndex=0; pgIndex<pgCount; pgIndex++) {\n        const PackageGroup* pg = mPackageGroups[pgIndex];\n        printf(\"Package Group %d id=0x%02x packageCount=%d name=%s\\n\",\n                (int)pgIndex, pg->id, (int)pg->packages.size(),\n                String8(pg->name).string());\n\n        const KeyedVector<String16, uint8_t>& refEntries = pg->dynamicRefTable.entries();\n        const size_t refEntryCount = refEntries.size();\n        if (refEntryCount > 0) {\n            printf(\"  DynamicRefTable entryCount=%d:\\n\", (int) refEntryCount);\n            for (size_t refIndex = 0; refIndex < refEntryCount; refIndex++) {\n                printf(\"    0x%02x -> %s\\n\",\n                        refEntries.valueAt(refIndex),\n                        String8(refEntries.keyAt(refIndex)).string());\n            }\n            printf(\"\\n\");\n        }\n\n        int packageId = pg->id;\n        size_t pkgCount = pg->packages.size();\n        for (size_t pkgIndex=0; pkgIndex<pkgCount; pkgIndex++) {\n            const Package* pkg = pg->packages[pkgIndex];\n            // Use a package's real ID, since the ID may have been assigned\n            // if this package is a shared library.\n            packageId = pkg->package->id;\n            char16_t tmpName[sizeof(pkg->package->name)/sizeof(pkg->package->name[0])];\n            strcpy16_dtoh(tmpName, pkg->package->name, sizeof(pkg->package->name)/sizeof(pkg->package->name[0]));\n            printf(\"  Package %d id=0x%02x name=%s\\n\", (int)pkgIndex,\n                    pkg->package->id, String8(tmpName).string());\n        }\n\n        for (size_t typeIndex=0; typeIndex < pg->types.size(); typeIndex++) {\n            const TypeList& typeList = pg->types[typeIndex];\n            if (typeList.isEmpty()) {\n                continue;\n            }\n            const Type* typeConfigs = typeList[0];\n            const size_t NTC = typeConfigs->configs.size();\n            printf(\"    type %d configCount=%d entryCount=%d\\n\",\n                   (int)typeIndex, (int)NTC, (int)typeConfigs->entryCount);\n            if (typeConfigs->typeSpecFlags != NULL) {\n                for (size_t entryIndex=0; entryIndex<typeConfigs->entryCount; entryIndex++) {\n                    uint32_t resID = (0xff000000 & ((packageId)<<24))\n                                | (0x00ff0000 & ((typeIndex+1)<<16))\n                                | (0x0000ffff & (entryIndex));\n                    // Since we are creating resID without actually\n                    // iterating over them, we have no idea which is a\n                    // dynamic reference. We must check.\n                    if (packageId == 0) {\n                        pg->dynamicRefTable.lookupResourceId(&resID);\n                    }\n\n                    resource_name resName;\n                    if (this->getResourceName(resID, true, &resName)) {\n                        String8 type8;\n                        String8 name8;\n                        if (resName.type8 != NULL) {\n                            type8 = String8(resName.type8, resName.typeLen);\n                        } else {\n                            type8 = String8(resName.type, resName.typeLen);\n                        }\n                        if (resName.name8 != NULL) {\n                            name8 = String8(resName.name8, resName.nameLen);\n                        } else {\n                            name8 = String8(resName.name, resName.nameLen);\n                        }\n                        printf(\"      spec resource 0x%08x %s:%s/%s: flags=0x%08x\\n\",\n                            resID,\n                            CHAR16_TO_CSTR(resName.package, resName.packageLen),\n                            type8.string(), name8.string(),\n                            dtohl(typeConfigs->typeSpecFlags[entryIndex]));\n                    } else {\n                        printf(\"      INVALID TYPE CONFIG FOR RESOURCE 0x%08x\\n\", resID);\n                    }\n                }\n            }\n            for (size_t configIndex=0; configIndex<NTC; configIndex++) {\n                const ResTable_type* type = typeConfigs->configs[configIndex];\n                if ((((uint64_t)type)&0x3) != 0) {\n                    printf(\"      NON-INTEGER ResTable_type ADDRESS: %p\\n\", type);\n                    continue;\n                }\n\n                // Always copy the config, as fields get added and we need to\n                // set the defaults.\n                ResTable_config thisConfig;\n                thisConfig.copyFromDtoH(type->config);\n\n                String8 configStr = thisConfig.toString();\n                printf(\"      config %s:\\n\", configStr.size() > 0\n                        ? configStr.string() : \"(default)\");\n                size_t entryCount = dtohl(type->entryCount);\n                uint32_t entriesStart = dtohl(type->entriesStart);\n                if ((entriesStart&0x3) != 0) {\n                    printf(\"      NON-INTEGER ResTable_type entriesStart OFFSET: 0x%x\\n\", entriesStart);\n                    continue;\n                }\n                uint32_t typeSize = dtohl(type->header.size);\n                if ((typeSize&0x3) != 0) {\n                    printf(\"      NON-INTEGER ResTable_type header.size: 0x%x\\n\", typeSize);\n                    continue;\n                }\n                for (size_t entryIndex=0; entryIndex<entryCount; entryIndex++) {\n                    const uint32_t* const eindex = (const uint32_t*)\n                        (((const uint8_t*)type) + dtohs(type->header.headerSize));\n\n                    uint32_t thisOffset = dtohl(eindex[entryIndex]);\n                    if (thisOffset == ResTable_type::NO_ENTRY) {\n                        continue;\n                    }\n\n                    uint32_t resID = (0xff000000 & ((packageId)<<24))\n                                | (0x00ff0000 & ((typeIndex+1)<<16))\n                                | (0x0000ffff & (entryIndex));\n                    if (packageId == 0) {\n                        pg->dynamicRefTable.lookupResourceId(&resID);\n                    }\n                    resource_name resName;\n                    if (this->getResourceName(resID, true, &resName)) {\n                        String8 type8;\n                        String8 name8;\n                        if (resName.type8 != NULL) {\n                            type8 = String8(resName.type8, resName.typeLen);\n                        } else {\n                            type8 = String8(resName.type, resName.typeLen);\n                        }\n                        if (resName.name8 != NULL) {\n                            name8 = String8(resName.name8, resName.nameLen);\n                        } else {\n                            name8 = String8(resName.name, resName.nameLen);\n                        }\n                        printf(\"        resource 0x%08x %s:%s/%s: \", resID,\n                                CHAR16_TO_CSTR(resName.package, resName.packageLen),\n                                type8.string(), name8.string());\n                    } else {\n                        printf(\"        INVALID RESOURCE 0x%08x: \", resID);\n                    }\n                    if ((thisOffset&0x3) != 0) {\n                        printf(\"NON-INTEGER OFFSET: 0x%x\\n\", thisOffset);\n                        continue;\n                    }\n                    if ((thisOffset+sizeof(ResTable_entry)) > typeSize) {\n                        printf(\"OFFSET OUT OF BOUNDS: 0x%x+0x%x (size is 0x%x)\\n\",\n                               entriesStart, thisOffset, typeSize);\n                        continue;\n                    }\n\n                    const ResTable_entry* ent = (const ResTable_entry*)\n                        (((const uint8_t*)type) + entriesStart + thisOffset);\n                    if (((entriesStart + thisOffset)&0x3) != 0) {\n                        printf(\"NON-INTEGER ResTable_entry OFFSET: 0x%x\\n\",\n                             (entriesStart + thisOffset));\n                        continue;\n                    }\n\n                    uintptr_t esize = dtohs(ent->size);\n                    if ((esize&0x3) != 0) {\n                        printf(\"NON-INTEGER ResTable_entry SIZE: %p\\n\", (void *)esize);\n                        continue;\n                    }\n                    if ((thisOffset+esize) > typeSize) {\n                        printf(\"ResTable_entry OUT OF BOUNDS: 0x%x+0x%x+%p (size is 0x%x)\\n\",\n                               entriesStart, thisOffset, (void *)esize, typeSize);\n                        continue;\n                    }\n\n                    const Res_value* valuePtr = NULL;\n                    const ResTable_map_entry* bagPtr = NULL;\n                    Res_value value;\n                    if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) {\n                        printf(\"<bag>\");\n                        bagPtr = (const ResTable_map_entry*)ent;\n                    } else {\n                        valuePtr = (const Res_value*)\n                            (((const uint8_t*)ent) + esize);\n                        value.copyFrom_dtoh(*valuePtr);\n                        printf(\"t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)\",\n                               (int)value.dataType, (int)value.data,\n                               (int)value.size, (int)value.res0);\n                    }\n\n                    if ((dtohs(ent->flags)&ResTable_entry::FLAG_PUBLIC) != 0) {\n                        printf(\" (PUBLIC)\");\n                    }\n                    printf(\"\\n\");\n\n                    if (inclValues) {\n                        if (valuePtr != NULL) {\n                            printf(\"          \");\n                            print_value(typeConfigs->package, value);\n                        } else if (bagPtr != NULL) {\n                            const int N = dtohl(bagPtr->count);\n                            const uint8_t* baseMapPtr = (const uint8_t*)ent;\n                            size_t mapOffset = esize;\n                            const ResTable_map* mapPtr = (ResTable_map*)(baseMapPtr+mapOffset);\n                            const uint32_t parent = dtohl(bagPtr->parent.ident);\n                            uint32_t resolvedParent = parent;\n                            if (Res_GETPACKAGE(resolvedParent) + 1 == 0) {\n                                status_t err = pg->dynamicRefTable.lookupResourceId(&resolvedParent);\n                                if (err != NO_ERROR) {\n                                    resolvedParent = 0;\n                                }\n                            }\n                            printf(\"          Parent=0x%08x(Resolved=0x%08x), Count=%d\\n\",\n                                    parent, resolvedParent, N);\n                            for (int i=0; i<N && mapOffset < (typeSize-sizeof(ResTable_map)); i++) {\n                                printf(\"          #%i (Key=0x%08x): \",\n                                    i, dtohl(mapPtr->name.ident));\n                                value.copyFrom_dtoh(mapPtr->value);\n                                print_value(typeConfigs->package, value);\n                                const size_t size = dtohs(mapPtr->value.size);\n                                mapOffset += size + sizeof(*mapPtr)-sizeof(mapPtr->value);\n                                mapPtr = (ResTable_map*)(baseMapPtr+mapOffset);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nKeyedVector<uint32_t, ResTable::resource_name> ResTable::getResourceEntries() const\n{\n    KeyedVector<uint32_t, resource_name> resourceEntries;\n    size_t pgCount = mPackageGroups.size();\n    for (size_t pgIndex=0; pgIndex<pgCount; pgIndex++) {\n        const PackageGroup* pg = mPackageGroups[pgIndex];\n\n        int packageId = pg->id;\n        size_t pkgCount = pg->packages.size();\n        for (size_t pkgIndex=0; pkgIndex<pkgCount; pkgIndex++) {\n            const Package* pkg = pg->packages[pkgIndex];\n            // Use a package's real ID, since the ID may have been assigned\n            // if this package is a shared library.\n            packageId = pkg->package->id;\n        }\n\n        for (size_t typeIndex=0; typeIndex < pg->types.size(); typeIndex++) {\n            const TypeList& typeList = pg->types[typeIndex];\n            if (typeList.isEmpty()) {\n                continue;\n            }\n            const Type* typeConfigs = typeList[0];\n            if (typeConfigs->typeSpecFlags != NULL) {\n                for (size_t entryIndex=0; entryIndex<typeConfigs->entryCount; entryIndex++) {\n                    uint32_t resID = (0xff000000 & ((packageId)<<24))\n                                | (0x00ff0000 & ((typeIndex+1)<<16))\n                                | (0x0000ffff & (entryIndex));\n                    // Since we are creating resID without actually\n                    // iterating over them, we have no idea which is a\n                    // dynamic reference. We must check.\n                    if (packageId == 0) {\n                        pg->dynamicRefTable.lookupResourceId(&resID);\n                    }\n\n                    resource_name resName;\n                    if (this->getResourceName(resID, true, &resName)) {\n                        resourceEntries.add(resID, resName);\n                    } else {\n                        printf(\"      INVALID TYPE CONFIG FOR RESOURCE 0x%08x\\n\", resID);\n                    }\n                }\n            }\n        }\n    }\n    return resourceEntries;\n}\n\n}   // namespace android\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/StreamingZipInflater.cpp",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//#define LOG_NDEBUG 0\n#define LOG_TAG \"szipinf\"\n#include <utils/Log.h>\n\n#include <androidfw/StreamingZipInflater.h>\n#include <utils/FileMap.h>\n#include <string.h>\n#include <stddef.h>\n#include <assert.h>\n#include <unistd.h>\n#include <errno.h>\n\n/*\n * TEMP_FAILURE_RETRY is defined by some, but not all, versions of\n * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's\n * not already defined, then define it here.\n */\n#ifndef TEMP_FAILURE_RETRY\n/* Used to retry syscalls that can return EINTR. */\n#define TEMP_FAILURE_RETRY(exp) ({         \\\n    typeof (exp) _rc;                      \\\n    do {                                   \\\n        _rc = (exp);                       \\\n    } while (_rc == -1 && errno == EINTR); \\\n    _rc; })\n#endif\n\nstatic const bool kIsDebug = false;\n\nstatic inline size_t min_of(size_t a, size_t b) { return (a < b) ? a : b; }\n\nusing namespace android;\n\n/*\n * Streaming access to compressed asset data in an open fd\n */\nStreamingZipInflater::StreamingZipInflater(int fd, off64_t compDataStart,\n        size_t uncompSize, size_t compSize) {\n    mFd = fd;\n    mDataMap = NULL;\n    mInFileStart = compDataStart;\n    mOutTotalSize = uncompSize;\n    mInTotalSize = compSize;\n\n    mInBufSize = StreamingZipInflater::INPUT_CHUNK_SIZE;\n    mInBuf = new uint8_t[mInBufSize];\n\n    mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;\n    mOutBuf = new uint8_t[mOutBufSize];\n\n    initInflateState();\n}\n\n/*\n * Streaming access to compressed data held in an mmapped region of memory\n */\nStreamingZipInflater::StreamingZipInflater(FileMap* dataMap, size_t uncompSize) {\n    mFd = -1;\n    mDataMap = dataMap;\n    mOutTotalSize = uncompSize;\n    mInTotalSize = dataMap->getDataLength();\n\n    mInBuf = (uint8_t*) dataMap->getDataPtr();\n    mInBufSize = mInTotalSize;\n\n    mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;\n    mOutBuf = new uint8_t[mOutBufSize];\n\n    initInflateState();\n}\n\nStreamingZipInflater::~StreamingZipInflater() {\n    // tear down the in-flight zip state just in case\n    ::inflateEnd(&mInflateState);\n\n    if (mDataMap == NULL) {\n        delete [] mInBuf;\n    }\n    delete [] mOutBuf;\n}\n\nvoid StreamingZipInflater::initInflateState() {\n    ALOGV(\"Initializing inflate state\");\n\n    memset(&mInflateState, 0, sizeof(mInflateState));\n    mInflateState.zalloc = Z_NULL;\n    mInflateState.zfree = Z_NULL;\n    mInflateState.opaque = Z_NULL;\n    mInflateState.next_in = (Bytef*)mInBuf;\n    mInflateState.next_out = (Bytef*) mOutBuf;\n    mInflateState.avail_out = mOutBufSize;\n    mInflateState.data_type = Z_UNKNOWN;\n\n    mOutLastDecoded = mOutDeliverable = mOutCurPosition = 0;\n    mInNextChunkOffset = 0;\n    mStreamNeedsInit = true;\n\n    if (mDataMap == NULL) {\n        ::lseek(mFd, mInFileStart, SEEK_SET);\n        mInflateState.avail_in = 0; // set when a chunk is read in\n    } else {\n        mInflateState.avail_in = mInBufSize;\n    }\n}\n\n/*\n * Basic approach:\n *\n * 1. If we have undelivered uncompressed data, send it.  At this point\n *    either we've satisfied the request, or we've exhausted the available\n *    output data in mOutBuf.\n *\n * 2. While we haven't sent enough data to satisfy the request:\n *    0. if the request is for more data than exists, bail.\n *    a. if there is no input data to decode, read some into the input buffer\n *       and readjust the z_stream input pointers\n *    b. point the output to the start of the output buffer and decode what we can\n *    c. deliver whatever output data we can\n */\nssize_t StreamingZipInflater::read(void* outBuf, size_t count) {\n    uint8_t* dest = (uint8_t*) outBuf;\n    size_t bytesRead = 0;\n    size_t toRead = min_of(count, size_t(mOutTotalSize - mOutCurPosition));\n    while (toRead > 0) {\n        // First, write from whatever we already have decoded and ready to go\n        size_t deliverable = min_of(toRead, mOutLastDecoded - mOutDeliverable);\n        if (deliverable > 0) {\n            if (outBuf != NULL) memcpy(dest, mOutBuf + mOutDeliverable, deliverable);\n            mOutDeliverable += deliverable;\n            mOutCurPosition += deliverable;\n            dest += deliverable;\n            bytesRead += deliverable;\n            toRead -= deliverable;\n        }\n\n        // need more data?  time to decode some.\n        if (toRead > 0) {\n            // if we don't have any data to decode, read some in.  If we're working\n            // from mmapped data this won't happen, because the clipping to total size\n            // will prevent reading off the end of the mapped input chunk.\n            if ((mInflateState.avail_in == 0) && (mDataMap == NULL)) {\n                int err = readNextChunk();\n                if (err < 0) {\n                    ALOGE(\"Unable to access asset data: %d\", err);\n                    if (!mStreamNeedsInit) {\n                        ::inflateEnd(&mInflateState);\n                        initInflateState();\n                    }\n                    return -1;\n                }\n            }\n            // we know we've drained whatever is in the out buffer now, so just\n            // start from scratch there, reading all the input we have at present.\n            mInflateState.next_out = (Bytef*) mOutBuf;\n            mInflateState.avail_out = mOutBufSize;\n\n            /*\n            ALOGV(\"Inflating to outbuf: avail_in=%u avail_out=%u next_in=%p next_out=%p\",\n                    mInflateState.avail_in, mInflateState.avail_out,\n                    mInflateState.next_in, mInflateState.next_out);\n            */\n            int result = Z_OK;\n            if (mStreamNeedsInit) {\n                ALOGV(\"Initializing zlib to inflate\");\n                result = inflateInit2(&mInflateState, -MAX_WBITS);\n                mStreamNeedsInit = false;\n            }\n            if (result == Z_OK) result = ::inflate(&mInflateState, Z_SYNC_FLUSH);\n            if (result < 0) {\n                // Whoops, inflation failed\n                ALOGE(\"Error inflating asset: %d\", result);\n                ::inflateEnd(&mInflateState);\n                initInflateState();\n                return -1;\n            } else {\n                if (result == Z_STREAM_END) {\n                    // we know we have to have reached the target size here and will\n                    // not try to read any further, so just wind things up.\n                    ::inflateEnd(&mInflateState);\n                }\n\n                // Note how much data we got, and off we go\n                mOutDeliverable = 0;\n                mOutLastDecoded = mOutBufSize - mInflateState.avail_out;\n            }\n        }\n    }\n    return bytesRead;\n}\n\nint StreamingZipInflater::readNextChunk() {\n    assert(mDataMap == NULL);\n\n    if (mInNextChunkOffset < mInTotalSize) {\n        size_t toRead = min_of(mInBufSize, mInTotalSize - mInNextChunkOffset);\n        if (toRead > 0) {\n            ssize_t didRead = TEMP_FAILURE_RETRY(::read(mFd, mInBuf, toRead));\n            if (kIsDebug) {\n                ALOGV(\"Reading input chunk, size %08zx didread %08zx\", toRead, didRead);\n            }\n            if (didRead < 0) {\n                ALOGE(\"Error reading asset data: %s\", strerror(errno));\n                return didRead;\n            } else {\n                mInNextChunkOffset += didRead;\n                mInflateState.next_in = (Bytef*) mInBuf;\n                mInflateState.avail_in = didRead;\n            }\n        }\n    }\n    return 0;\n}\n\n// seeking backwards requires uncompressing fom the beginning, so is very\n// expensive.  seeking forwards only requires uncompressing from the current\n// position to the destination.\noff64_t StreamingZipInflater::seekAbsolute(off64_t absoluteInputPosition) {\n    if (absoluteInputPosition < mOutCurPosition) {\n        // rewind and reprocess the data from the beginning\n        if (!mStreamNeedsInit) {\n            ::inflateEnd(&mInflateState);\n        }\n        initInflateState();\n        read(NULL, absoluteInputPosition);\n    } else if (absoluteInputPosition > mOutCurPosition) {\n        read(NULL, absoluteInputPosition - mOutCurPosition);\n    }\n    // else if the target position *is* our current position, do nothing\n    return absoluteInputPosition;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/TypeWrappers.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/TypeWrappers.h>\n\nnamespace android {\n\nTypeVariant::iterator& TypeVariant::iterator::operator++() {\n    mIndex++;\n    if (mIndex > dtohl(mTypeVariant->data->entryCount)) {\n        mIndex = dtohl(mTypeVariant->data->entryCount);\n    }\n    return *this;\n}\n\nconst ResTable_entry* TypeVariant::iterator::operator*() const {\n    const ResTable_type* type = mTypeVariant->data;\n    const uint32_t entryCount = dtohl(type->entryCount);\n    if (mIndex >= entryCount) {\n        return NULL;\n    }\n\n    const uintptr_t containerEnd = reinterpret_cast<uintptr_t>(type)\n            + dtohl(type->header.size);\n    const uint32_t* const entryIndices = reinterpret_cast<const uint32_t*>(\n            reinterpret_cast<uintptr_t>(type) + dtohs(type->header.headerSize));\n    if (reinterpret_cast<uintptr_t>(entryIndices) + (sizeof(uint32_t) * entryCount) > containerEnd) {\n        ALOGE(\"Type's entry indices extend beyond its boundaries\");\n        return NULL;\n    }\n\n    const uint32_t entryOffset = dtohl(entryIndices[mIndex]);\n    if (entryOffset == ResTable_type::NO_ENTRY) {\n        return NULL;\n    }\n\n    if ((entryOffset & 0x3) != 0) {\n        ALOGE(\"Index %u points to entry with unaligned offset 0x%08x\", mIndex, entryOffset);\n        return NULL;\n    }\n\n    const ResTable_entry* entry = reinterpret_cast<const ResTable_entry*>(\n            reinterpret_cast<uintptr_t>(type) + dtohl(type->entriesStart) + entryOffset);\n    if (reinterpret_cast<uintptr_t>(entry) > containerEnd - sizeof(*entry)) {\n        ALOGE(\"Entry offset at index %u points outside the Type's boundaries\", mIndex);\n        return NULL;\n    } else if (reinterpret_cast<uintptr_t>(entry) + dtohs(entry->size) > containerEnd) {\n        ALOGE(\"Entry at index %u extends beyond Type's boundaries\", mIndex);\n        return NULL;\n    } else if (dtohs(entry->size) < sizeof(*entry)) {\n        ALOGE(\"Entry at index %u is too small (%u)\", mIndex, dtohs(entry->size));\n        return NULL;\n    }\n    return entry;\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/ZipFileRO.cpp",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Read-only access to Zip archives, with minimal heap allocation.\n//\n#define LOG_TAG \"zipro\"\n//#define LOG_NDEBUG 0\n#include <androidfw/ZipFileRO.h>\n#include <utils/Log.h>\n#include <utils/Compat.h>\n#include <utils/misc.h>\n#include <utils/threads.h>\n#include <ziparchive/zip_archive.h>\n\n#include <zlib.h>\n\n#include <string.h>\n#include <fcntl.h>\n#include <errno.h>\n#include <assert.h>\n#include <unistd.h>\n\nusing namespace android;\n\nclass _ZipEntryRO {\npublic:\n    ZipEntry entry;\n    ZipString name;\n    void *cookie;\n\n    _ZipEntryRO() : cookie(NULL) {}\n\n    ~_ZipEntryRO() {\n      EndIteration(cookie);\n    }\n\nprivate:\n    _ZipEntryRO(const _ZipEntryRO& other);\n    _ZipEntryRO& operator=(const _ZipEntryRO& other);\n};\n\nZipFileRO::~ZipFileRO() {\n    CloseArchive(mHandle);\n    free(mFileName);\n}\n\n/*\n * Open the specified file read-only.  We memory-map the entire thing and\n * close the file before returning.\n */\n/* static */ ZipFileRO* ZipFileRO::open(const char* zipFileName)\n{\n    ZipArchiveHandle handle;\n    const int32_t error = OpenArchive(zipFileName, &handle);\n    if (error) {\n        ALOGW(\"Error opening archive %s: %s\", zipFileName, ErrorCodeString(error));\n        CloseArchive(handle);\n        return NULL;\n    }\n\n    return new ZipFileRO(handle, strdup(zipFileName));\n}\n\n\nZipEntryRO ZipFileRO::findEntryByName(const char* entryName) const\n{\n    _ZipEntryRO* data = new _ZipEntryRO;\n\n    data->name = ZipString(entryName);\n\n    const int32_t error = FindEntry(mHandle, data->name, &(data->entry));\n    if (error) {\n        delete data;\n        return NULL;\n    }\n\n    return (ZipEntryRO) data;\n}\n\n/*\n * Get the useful fields from the zip entry.\n *\n * Returns \"false\" if the offsets to the fields or the contents of the fields\n * appear to be bogus.\n */\nbool ZipFileRO::getEntryInfo(ZipEntryRO entry, uint16_t* pMethod,\n    uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset,\n    uint32_t* pModWhen, uint32_t* pCrc32) const\n{\n    const _ZipEntryRO* zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);\n    const ZipEntry& ze = zipEntry->entry;\n\n    if (pMethod != NULL) {\n        *pMethod = ze.method;\n    }\n    if (pUncompLen != NULL) {\n        *pUncompLen = ze.uncompressed_length;\n    }\n    if (pCompLen != NULL) {\n        *pCompLen = ze.compressed_length;\n    }\n    if (pOffset != NULL) {\n        *pOffset = ze.offset;\n    }\n    if (pModWhen != NULL) {\n        *pModWhen = ze.mod_time;\n    }\n    if (pCrc32 != NULL) {\n        *pCrc32 = ze.crc32;\n    }\n\n    return true;\n}\n\nbool ZipFileRO::startIteration(void** cookie) {\n  return startIteration(cookie, NULL, NULL);\n}\n\nbool ZipFileRO::startIteration(void** cookie, const char* prefix, const char* suffix)\n{\n    _ZipEntryRO* ze = new _ZipEntryRO;\n    ZipString pe(prefix ? prefix : \"\");\n    ZipString se(suffix ? suffix : \"\");\n    int32_t error = StartIteration(mHandle, &(ze->cookie),\n                                   prefix ? &pe : NULL,\n                                   suffix ? &se : NULL);\n    if (error) {\n        ALOGW(\"Could not start iteration over %s: %s\", mFileName, ErrorCodeString(error));\n        delete ze;\n        return false;\n    }\n\n    *cookie = ze;\n    return true;\n}\n\nZipEntryRO ZipFileRO::nextEntry(void* cookie)\n{\n    _ZipEntryRO* ze = reinterpret_cast<_ZipEntryRO*>(cookie);\n    int32_t error = Next(ze->cookie, &(ze->entry), &(ze->name));\n    if (error) {\n        if (error != -1) {\n            ALOGW(\"Error iteration over %s: %s\", mFileName, ErrorCodeString(error));\n        }\n        return NULL;\n    }\n\n    return &(ze->entry);\n}\n\nvoid ZipFileRO::endIteration(void* cookie)\n{\n    delete reinterpret_cast<_ZipEntryRO*>(cookie);\n}\n\nvoid ZipFileRO::releaseEntry(ZipEntryRO entry) const\n{\n    delete reinterpret_cast<_ZipEntryRO*>(entry);\n}\n\n/*\n * Copy the entry's filename to the buffer.\n */\nint ZipFileRO::getEntryFileName(ZipEntryRO entry, char* buffer, size_t bufLen)\n    const\n{\n    const _ZipEntryRO* zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);\n    const uint16_t requiredSize = zipEntry->name.name_length + 1;\n\n    if (bufLen < requiredSize) {\n        ALOGW(\"Buffer too short, requires %d bytes for entry name\", requiredSize);\n        return requiredSize;\n    }\n\n    memcpy(buffer, zipEntry->name.name, requiredSize - 1);\n    buffer[requiredSize - 1] = '\\0';\n\n    return 0;\n}\n\n/*\n * Create a new FileMap object that spans the data in \"entry\".\n */\nFileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const\n{\n    const _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);\n    const ZipEntry& ze = zipEntry->entry;\n    int fd = GetFileDescriptor(mHandle);\n    size_t actualLen = 0;\n\n    if (ze.method == kCompressStored) {\n        actualLen = ze.uncompressed_length;\n    } else {\n        actualLen = ze.compressed_length;\n    }\n\n    FileMap* newMap = new FileMap();\n    if (!newMap->create(mFileName, fd, ze.offset, actualLen, true)) {\n        delete newMap;\n        return NULL;\n    }\n\n    return newMap;\n}\n\n/*\n * Uncompress an entry, in its entirety, into the provided output buffer.\n *\n * This doesn't verify the data's CRC, which might be useful for\n * uncompressed data.  The caller should be able to manage it.\n */\nbool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer, size_t size) const\n{\n    _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);\n    const int32_t error = ExtractToMemory(mHandle, &(zipEntry->entry),\n        (uint8_t*) buffer, size);\n    if (error) {\n        ALOGW(\"ExtractToMemory failed with %s\", ErrorCodeString(error));\n        return false;\n    }\n\n    return true;\n}\n\n/*\n * Uncompress an entry, in its entirety, to an open file descriptor.\n *\n * This doesn't verify the data's CRC, but probably should.\n */\nbool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const\n{\n    _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);\n    const int32_t error = ExtractEntryToFile(mHandle, &(zipEntry->entry), fd);\n    if (error) {\n        ALOGW(\"ExtractToMemory failed with %s\", ErrorCodeString(error));\n        return false;\n    }\n\n    return true;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/ZipUtils.cpp",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Misc zip/gzip utility functions.\n//\n\n#define LOG_TAG \"ziputil\"\n\n#include <androidfw/ZipUtils.h>\n#include <androidfw/ZipFileRO.h>\n#include <utils/Log.h>\n#include <utils/Compat.h>\n\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n\n#include <zlib.h>\n\nusing namespace android;\n\nstatic inline unsigned long get4LE(const unsigned char* buf) {\n    return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);\n}\n\n\nstatic const unsigned long kReadBufSize = 32768;\n\n/*\n * Utility function that expands zip/gzip \"deflate\" compressed data\n * into a buffer.\n *\n * (This is a clone of the previous function, but it takes a FILE* instead\n * of an fd.  We could pass fileno(fd) to the above, but we can run into\n * trouble when \"fp\" has a different notion of what fd's file position is.)\n *\n * \"fp\" is an open file positioned at the start of the \"deflate\" data\n * \"buf\" must hold at least \"uncompressedLen\" bytes.\n */\n/*static*/ template<typename T> bool inflateToBuffer(T& reader, void* buf,\n    long uncompressedLen, long compressedLen)\n{\n    bool result = false;\n\n    z_stream zstream;\n    int zerr;\n    unsigned long compRemaining;\n\n    assert(uncompressedLen >= 0);\n    assert(compressedLen >= 0);\n\n    compRemaining = compressedLen;\n\n    /*\n     * Initialize the zlib stream.\n     */\n    memset(&zstream, 0, sizeof(zstream));\n    zstream.zalloc = Z_NULL;\n    zstream.zfree = Z_NULL;\n    zstream.opaque = Z_NULL;\n    zstream.next_in = NULL;\n    zstream.avail_in = 0;\n    zstream.next_out = (Bytef*) buf;\n    zstream.avail_out = uncompressedLen;\n    zstream.data_type = Z_UNKNOWN;\n\n    /*\n     * Use the undocumented \"negative window bits\" feature to tell zlib\n     * that there's no zlib header waiting for it.\n     */\n    zerr = inflateInit2(&zstream, -MAX_WBITS);\n    if (zerr != Z_OK) {\n        if (zerr == Z_VERSION_ERROR) {\n            ALOGE(\"Installed zlib is not compatible with linked version (%s)\\n\",\n                ZLIB_VERSION);\n        } else {\n            ALOGE(\"Call to inflateInit2 failed (zerr=%d)\\n\", zerr);\n        }\n        goto bail;\n    }\n\n    /*\n     * Loop while we have data.\n     */\n    do {\n        unsigned long getSize;\n\n        /* read as much as we can */\n        if (zstream.avail_in == 0) {\n            getSize = (compRemaining > kReadBufSize) ?\n                        kReadBufSize : compRemaining;\n            ALOGV(\"+++ reading %ld bytes (%ld left)\\n\",\n                getSize, compRemaining);\n\n            unsigned char* nextBuffer = NULL;\n            const unsigned long nextSize = reader.read(&nextBuffer, getSize);\n\n            if (nextSize < getSize || nextBuffer == NULL) {\n                ALOGD(\"inflate read failed (%ld vs %ld)\\n\", nextSize, getSize);\n                goto z_bail;\n            }\n\n            compRemaining -= nextSize;\n\n            zstream.next_in = nextBuffer;\n            zstream.avail_in = nextSize;\n        }\n\n        /* uncompress the data */\n        zerr = inflate(&zstream, Z_NO_FLUSH);\n        if (zerr != Z_OK && zerr != Z_STREAM_END) {\n            ALOGD(\"zlib inflate call failed (zerr=%d)\\n\", zerr);\n            goto z_bail;\n        }\n\n        /* output buffer holds all, so no need to write the output */\n    } while (zerr == Z_OK);\n\n    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */\n\n    if ((long) zstream.total_out != uncompressedLen) {\n        ALOGW(\"Size mismatch on inflated file (%ld vs %ld)\\n\",\n            zstream.total_out, uncompressedLen);\n        goto z_bail;\n    }\n\n    // success!\n    result = true;\n\nz_bail:\n    inflateEnd(&zstream);        /* free up any allocated structures */\n\nbail:\n    return result;\n}\n\nclass FileReader {\npublic:\n   FileReader(FILE* fp) :\n       mFp(fp), mReadBuf(new unsigned char[kReadBufSize])\n   {\n   }\n\n   ~FileReader() {\n       delete[] mReadBuf;\n   }\n\n   long read(unsigned char** nextBuffer, long readSize) const {\n       *nextBuffer = mReadBuf;\n       return fread(mReadBuf, 1, readSize, mFp);\n   }\n\n   FILE* mFp;\n   unsigned char* mReadBuf;\n};\n\nclass FdReader {\npublic:\n   FdReader(int fd) :\n       mFd(fd), mReadBuf(new unsigned char[kReadBufSize])\n   {\n   }\n\n   ~FdReader() {\n       delete[] mReadBuf;\n   }\n\n   long read(unsigned char** nextBuffer, long readSize) const {\n       *nextBuffer = mReadBuf;\n       return TEMP_FAILURE_RETRY(::read(mFd, mReadBuf, readSize));\n   }\n\n   int mFd;\n   unsigned char* mReadBuf;\n};\n\nclass BufferReader {\npublic:\n    BufferReader(void* input, size_t inputSize) :\n        mInput(reinterpret_cast<unsigned char*>(input)),\n        mInputSize(inputSize),\n        mBufferReturned(false)\n    {\n    }\n\n    long read(unsigned char** nextBuffer, long /*readSize*/) {\n        if (!mBufferReturned) {\n            mBufferReturned = true;\n            *nextBuffer = mInput;\n            return mInputSize;\n        }\n\n        *nextBuffer = NULL;\n        return 0;\n    }\n\n    unsigned char* mInput;\n    const size_t mInputSize;\n    bool mBufferReturned;\n};\n\n/*static*/ bool ZipUtils::inflateToBuffer(FILE* fp, void* buf,\n    long uncompressedLen, long compressedLen)\n{\n    FileReader reader(fp);\n    return ::inflateToBuffer<FileReader>(reader, buf,\n        uncompressedLen, compressedLen);\n}\n\n/*static*/ bool ZipUtils::inflateToBuffer(int fd, void* buf,\n    long uncompressedLen, long compressedLen)\n{\n    FdReader reader(fd);\n    return ::inflateToBuffer<FdReader>(reader, buf,\n        uncompressedLen, compressedLen);\n}\n\n/*static*/ bool ZipUtils::inflateToBuffer(void* in, void* buf,\n    long uncompressedLen, long compressedLen)\n{\n    BufferReader reader(in, compressedLen);\n    return ::inflateToBuffer<BufferReader>(reader, buf,\n        uncompressedLen, compressedLen);\n}\n\n\n\n/*\n * Look at the contents of a gzip archive.  We want to know where the\n * data starts, and how long it will be after it is uncompressed.\n *\n * We expect to find the CRC and length as the last 8 bytes on the file.\n * This is a pretty reasonable thing to expect for locally-compressed\n * files, but there's a small chance that some extra padding got thrown\n * on (the man page talks about compressed data written to tape).  We\n * don't currently deal with that here.  If \"gzip -l\" whines, we're going\n * to fail too.\n *\n * On exit, \"fp\" is pointing at the start of the compressed data.\n */\n/*static*/ bool ZipUtils::examineGzip(FILE* fp, int* pCompressionMethod,\n    long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32)\n{\n    enum {  // flags\n        FTEXT       = 0x01,\n        FHCRC       = 0x02,\n        FEXTRA      = 0x04,\n        FNAME       = 0x08,\n        FCOMMENT    = 0x10,\n    };\n    int ic;\n    int method, flags;\n    int i;\n\n    ic = getc(fp);\n    if (ic != 0x1f || getc(fp) != 0x8b)\n        return false;       // not gzip\n    method = getc(fp);\n    flags = getc(fp);\n\n    /* quick sanity checks */\n    if (method == EOF || flags == EOF)\n        return false;\n    if (method != ZipFileRO::kCompressDeflated)\n        return false;\n\n    /* skip over 4 bytes of mod time, 1 byte XFL, 1 byte OS */\n    for (i = 0; i < 6; i++)\n        (void) getc(fp);\n    /* consume \"extra\" field, if present */\n    if ((flags & FEXTRA) != 0) {\n        int len;\n\n        len = getc(fp);\n        len |= getc(fp) << 8;\n        while (len-- && getc(fp) != EOF)\n            ;\n    }\n    /* consume filename, if present */\n    if ((flags & FNAME) != 0) {\n        do {\n            ic = getc(fp);\n        } while (ic != 0 && ic != EOF);\n    }\n    /* consume comment, if present */\n    if ((flags & FCOMMENT) != 0) {\n        do {\n            ic = getc(fp);\n        } while (ic != 0 && ic != EOF);\n    }\n    /* consume 16-bit header CRC, if present */\n    if ((flags & FHCRC) != 0) {\n        (void) getc(fp);\n        (void) getc(fp);\n    }\n\n    if (feof(fp) || ferror(fp))\n        return false;\n\n    /* seek to the end; CRC and length are in the last 8 bytes */\n    long curPosn = ftell(fp);\n    unsigned char buf[8];\n    fseek(fp, -8, SEEK_END);\n    *pCompressedLen = ftell(fp) - curPosn;\n\n    if (fread(buf, 1, 8, fp) != 8)\n        return false;\n    /* seek back to start of compressed data */\n    fseek(fp, curPosn, SEEK_SET);\n\n    *pCompressionMethod = method;\n    *pCRC32 = get4LE(&buf[0]);\n    *pUncompressedLen = get4LE(&buf[4]);\n\n    return true;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/misc.cpp",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"misc\"\n\n//\n// Miscellaneous utility functions.\n//\n#include <androidfw/misc.h>\n\n#include <sys/stat.h>\n#include <cstring>\n#include <errno.h>\n#include <cstdio>\n\nusing namespace android;\n\nnamespace android {\n\n/*\n * Get a file's type.\n */\nFileType getFileType(const char* fileName)\n{\n    struct stat sb;\n\n    if (stat(fileName, &sb) < 0) {\n        if (errno == ENOENT || errno == ENOTDIR)\n            return kFileTypeNonexistent;\n        else {\n            fprintf(stderr, \"getFileType got errno=%d on '%s'\\n\",\n                errno, fileName);\n            return kFileTypeUnknown;\n        }\n    } else {\n        if (S_ISREG(sb.st_mode))\n            return kFileTypeRegular;\n        else if (S_ISDIR(sb.st_mode))\n            return kFileTypeDirectory;\n        else if (S_ISCHR(sb.st_mode))\n            return kFileTypeCharDev;\n        else if (S_ISBLK(sb.st_mode))\n            return kFileTypeBlockDev;\n        else if (S_ISFIFO(sb.st_mode))\n            return kFileTypeFifo;\n#if defined(S_ISLNK)\n        else if (S_ISLNK(sb.st_mode))\n            return kFileTypeSymlink;\n#endif\n#if defined(S_ISSOCK)\n        else if (S_ISSOCK(sb.st_mode))\n            return kFileTypeSocket;\n#endif\n        else\n            return kFileTypeUnknown;\n    }\n}\n\n/*\n * Get a file's modification date.\n */\ntime_t getFileModDate(const char* fileName)\n{\n    struct stat sb;\n\n    if (stat(fileName, &sb) < 0)\n        return (time_t) -1;\n\n    return sb.st_mtime;\n}\n\n}; // namespace android\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/Android.mk",
    "content": "#\n# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n# ==========================================================\n# Setup some common variables for the different build\n# targets here.\n# ==========================================================\nLOCAL_PATH:= $(call my-dir)\n\ntestFiles := \\\n    AttributeFinder_test.cpp \\\n    ByteBucketArray_test.cpp \\\n    Config_test.cpp \\\n    ConfigLocale_test.cpp \\\n    Idmap_test.cpp \\\n    ResTable_test.cpp \\\n    Split_test.cpp \\\n    TestHelpers.cpp \\\n    Theme_test.cpp \\\n    TypeWrappers_test.cpp \\\n    ZipUtils_test.cpp\n\nandroidfw_test_cflags := \\\n    -Wall \\\n    -Werror \\\n    -Wunused \\\n    -Wunreachable-code \\\n    -Wno-missing-field-initializers \\\n\n# gtest is broken.\nandroidfw_test_cflags += -Wno-unnamed-type-template-args\n\n# ==========================================================\n# Build the host tests: libandroidfw_tests\n# ==========================================================\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libandroidfw_tests\nLOCAL_CFLAGS := $(androidfw_test_cflags)\nLOCAL_SRC_FILES := $(testFiles)\nLOCAL_STATIC_LIBRARIES := \\\n    libandroidfw \\\n    libutils \\\n    libcutils \\\n    liblog \\\n    libz \\\n\ninclude $(BUILD_HOST_NATIVE_TEST)\n\n# ==========================================================\n# Build the device tests: libandroidfw_tests\n# ==========================================================\nifneq ($(SDK_ONLY),true)\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libandroidfw_tests\nLOCAL_CFLAGS := $(androidfw_test_cflags)\nLOCAL_SRC_FILES := $(testFiles) \\\n    BackupData_test.cpp \\\n    ObbFile_test.cpp \\\n\nLOCAL_SHARED_LIBRARIES := \\\n    libandroidfw \\\n    libcutils \\\n    libutils \\\n    libui \\\n\ninclude $(BUILD_NATIVE_TEST)\nendif # Not SDK_ONLY\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/AttributeFinder_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/AttributeFinder.h>\n\n#include <gtest/gtest.h>\n\nusing android::BackTrackingAttributeFinder;\n\nclass MockAttributeFinder : public BackTrackingAttributeFinder<MockAttributeFinder, int> {\npublic:\n    MockAttributeFinder(const uint32_t* attrs, int len)\n        : BackTrackingAttributeFinder(0, len) {\n        mAttrs = new uint32_t[len];\n        memcpy(mAttrs, attrs, sizeof(*attrs) * len);\n    }\n\n    ~MockAttributeFinder() {\n        delete mAttrs;\n    }\n\n    inline uint32_t getAttribute(const int index) const {\n        return mAttrs[index];\n    }\n\nprivate:\n    uint32_t* mAttrs;\n};\n\nstatic const uint32_t sortedAttributes[] = {\n        0x01010000, 0x01010001, 0x01010002, 0x01010004,\n        0x02010001, 0x02010010, 0x7f010001\n};\n\nstatic const uint32_t packageUnsortedAttributes[] = {\n        0x02010001, 0x02010010, 0x01010000, 0x01010001,\n        0x01010002, 0x01010004, 0x7f010001\n};\n\nstatic const uint32_t singlePackageAttributes[] = {\n        0x7f010007, 0x7f01000a, 0x7f01000d, 0x00000000\n};\n\nTEST(AttributeFinderTest, IteratesSequentially) {\n    const int end = sizeof(sortedAttributes) / sizeof(*sortedAttributes);\n    MockAttributeFinder finder(sortedAttributes, end);\n\n    EXPECT_EQ(0, finder.find(0x01010000));\n    EXPECT_EQ(1, finder.find(0x01010001));\n    EXPECT_EQ(2, finder.find(0x01010002));\n    EXPECT_EQ(3, finder.find(0x01010004));\n    EXPECT_EQ(4, finder.find(0x02010001));\n    EXPECT_EQ(5, finder.find(0x02010010));\n    EXPECT_EQ(6, finder.find(0x7f010001));\n    EXPECT_EQ(end, finder.find(0x7f010002));\n}\n\nTEST(AttributeFinderTest, PackagesAreOutOfOrder) {\n    const int end = sizeof(sortedAttributes) / sizeof(*sortedAttributes);\n    MockAttributeFinder finder(sortedAttributes, end);\n\n    EXPECT_EQ(6, finder.find(0x7f010001));\n    EXPECT_EQ(end, finder.find(0x7f010002));\n    EXPECT_EQ(4, finder.find(0x02010001));\n    EXPECT_EQ(5, finder.find(0x02010010));\n    EXPECT_EQ(0, finder.find(0x01010000));\n    EXPECT_EQ(1, finder.find(0x01010001));\n    EXPECT_EQ(2, finder.find(0x01010002));\n    EXPECT_EQ(3, finder.find(0x01010004));\n}\n\nTEST(AttributeFinderTest, SomeAttributesAreNotFound) {\n    const int end = sizeof(sortedAttributes) / sizeof(*sortedAttributes);\n    MockAttributeFinder finder(sortedAttributes, end);\n\n    EXPECT_EQ(0, finder.find(0x01010000));\n    EXPECT_EQ(1, finder.find(0x01010001));\n    EXPECT_EQ(2, finder.find(0x01010002));\n    EXPECT_EQ(end, finder.find(0x01010003));\n    EXPECT_EQ(3, finder.find(0x01010004));\n    EXPECT_EQ(end, finder.find(0x01010005));\n    EXPECT_EQ(end, finder.find(0x01010006));\n    EXPECT_EQ(4, finder.find(0x02010001));\n    EXPECT_EQ(end, finder.find(0x02010002));\n}\n\nTEST(AttributeFinderTest, FindAttributesInPackageUnsortedAttributeList) {\n    const int end = sizeof(packageUnsortedAttributes) / sizeof(*packageUnsortedAttributes);\n    MockAttributeFinder finder(packageUnsortedAttributes, end);\n\n    EXPECT_EQ(2, finder.find(0x01010000));\n    EXPECT_EQ(3, finder.find(0x01010001));\n    EXPECT_EQ(4, finder.find(0x01010002));\n    EXPECT_EQ(end, finder.find(0x01010003));\n    EXPECT_EQ(5, finder.find(0x01010004));\n    EXPECT_EQ(end, finder.find(0x01010005));\n    EXPECT_EQ(end, finder.find(0x01010006));\n    EXPECT_EQ(0, finder.find(0x02010001));\n    EXPECT_EQ(end, finder.find(0x02010002));\n    EXPECT_EQ(1, finder.find(0x02010010));\n    EXPECT_EQ(6, finder.find(0x7f010001));\n}\n\nTEST(AttributeFinderTest, FindAttributesInSinglePackageAttributeList) {\n    const int end = sizeof(singlePackageAttributes) / sizeof(*singlePackageAttributes);\n    MockAttributeFinder finder(singlePackageAttributes, end);\n\n    EXPECT_EQ(end, finder.find(0x010100f4));\n    EXPECT_EQ(end, finder.find(0x010100f5));\n    EXPECT_EQ(end, finder.find(0x010100f6));\n    EXPECT_EQ(end, finder.find(0x010100f7));\n    EXPECT_EQ(end, finder.find(0x010100f8));\n    EXPECT_EQ(end, finder.find(0x010100fa));\n    EXPECT_EQ(0, finder.find(0x7f010007));\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/BackupData_test.cpp",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"ObbFile_test\"\n#include <androidfw/BackupHelpers.h>\n#include <utils/Log.h>\n#include <utils/String8.h>\n\n#include <gtest/gtest.h>\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <string.h>\n\nnamespace android {\n\n#define TEST_FILENAME \"/test.bd\"\n\n// keys of different lengths to test padding\n#define KEY1 \"key1\"\n#define KEY2 \"key2a\"\n#define KEY3 \"key3bc\"\n#define KEY4 \"key4def\"\n\n// payloads of different lengths to test padding\n#define DATA1 \"abcdefg\"\n#define DATA2 \"hijklmnopq\"\n#define DATA3 \"rstuvwxyz\"\n// KEY4 is only ever deleted\n\nclass BackupDataTest : public testing::Test {\nprotected:\n    char* m_external_storage;\n    String8 mFilename;\n    String8 mKey1;\n    String8 mKey2;\n    String8 mKey3;\n    String8 mKey4;\n\n    virtual void SetUp() {\n        m_external_storage = getenv(\"EXTERNAL_STORAGE\");\n        mFilename.append(m_external_storage);\n        mFilename.append(TEST_FILENAME);\n\n        ::unlink(mFilename.string());\n        int fd = ::open(mFilename.string(), O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);\n        if (fd < 0) {\n            FAIL() << \"Couldn't create \" << mFilename.string() << \" for writing\";\n        }\n        mKey1 = String8(KEY1);\n        mKey2 = String8(KEY2);\n        mKey3 = String8(KEY3);\n        mKey4 = String8(KEY4);\n   }\n\n    virtual void TearDown() {\n    }\n};\n\nTEST_F(BackupDataTest, WriteAndReadSingle) {\n  int fd = ::open(mFilename.string(), O_WRONLY);\n  BackupDataWriter* writer = new BackupDataWriter(fd);\n\n  EXPECT_EQ(NO_ERROR, writer->WriteEntityHeader(mKey1, sizeof(DATA1)))\n          << \"WriteEntityHeader returned an error\";\n  EXPECT_EQ(NO_ERROR, writer->WriteEntityData(DATA1, sizeof(DATA1)))\n          << \"WriteEntityData returned an error\";\n\n  ::close(fd);\n  fd = ::open(mFilename.string(), O_RDONLY);\n  BackupDataReader* reader = new BackupDataReader(fd);\n  EXPECT_EQ(NO_ERROR, reader->Status())\n          << \"Reader ctor failed\";\n\n  bool done;\n  int type;\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader\";\n\n  String8 key;\n  size_t dataSize;\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error\";\n  EXPECT_EQ(mKey1, key)\n          << \"wrong key from ReadEntityHeader\";\n  EXPECT_EQ(sizeof(DATA1), dataSize)\n          << \"wrong size from ReadEntityHeader\";\n\n  char* dataBytes = new char[dataSize];\n  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))\n          << \"ReadEntityData returned an error\";\n  for (unsigned int i = 0; i < sizeof(DATA1); i++) {\n    EXPECT_EQ(DATA1[i], dataBytes[i])\n             << \"data character \" << i << \" should be equal\";\n  }\n  delete[] dataBytes;\n  delete writer;\n  delete reader;\n}\n\nTEST_F(BackupDataTest, WriteAndReadMultiple) {\n  int fd = ::open(mFilename.string(), O_WRONLY);\n  BackupDataWriter* writer = new BackupDataWriter(fd);\n  writer->WriteEntityHeader(mKey1, sizeof(DATA1));\n  writer->WriteEntityData(DATA1, sizeof(DATA1));\n  writer->WriteEntityHeader(mKey2, sizeof(DATA2));\n  writer->WriteEntityData(DATA2, sizeof(DATA2));\n\n  ::close(fd);\n  fd = ::open(mFilename.string(), O_RDONLY);\n  BackupDataReader* reader = new BackupDataReader(fd);\n\n  bool done;\n  int type;\n  String8 key;\n  size_t dataSize;\n  char* dataBytes;\n  // read first entity\n  reader->ReadNextHeader(&done, &type);\n  reader->ReadEntityHeader(&key, &dataSize);\n  dataBytes = new char[dataSize];\n  reader->ReadEntityData(dataBytes, dataSize);\n  delete dataBytes;\n\n  // read and verify second entity\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on second entity\";\n  EXPECT_EQ(mKey2, key)\n          << \"wrong key from ReadEntityHeader on second entity\";\n  EXPECT_EQ(sizeof(DATA2), dataSize)\n          << \"wrong size from ReadEntityHeader on second entity\";\n\n  dataBytes = new char[dataSize];\n  EXPECT_EQ((int)dataSize, reader->ReadEntityData(dataBytes, dataSize))\n          << \"ReadEntityData returned an error on second entity\";\n  for (unsigned int i = 0; i < sizeof(DATA2); i++) {\n    EXPECT_EQ(DATA2[i], dataBytes[i])\n             << \"data character \" << i << \" should be equal\";\n  }\n  delete dataBytes;\n  delete writer;\n  delete reader;\n}\n\nTEST_F(BackupDataTest, SkipEntity) {\n  int fd = ::open(mFilename.string(), O_WRONLY);\n  BackupDataWriter* writer = new BackupDataWriter(fd);\n  writer->WriteEntityHeader(mKey1, sizeof(DATA1));\n  writer->WriteEntityData(DATA1, sizeof(DATA1));\n  writer->WriteEntityHeader(mKey2, sizeof(DATA2));\n  writer->WriteEntityData(DATA2, sizeof(DATA2));\n  writer->WriteEntityHeader(mKey3, sizeof(DATA3));\n  writer->WriteEntityData(DATA3, sizeof(DATA3));\n\n  ::close(fd);\n  fd = ::open(mFilename.string(), O_RDONLY);\n  BackupDataReader* reader = new BackupDataReader(fd);\n\n  bool done;\n  int type;\n  String8 key;\n  size_t dataSize;\n  char* dataBytes;\n  // read first entity\n  reader->ReadNextHeader(&done, &type);\n  reader->ReadEntityHeader(&key, &dataSize);\n  dataBytes = new char[dataSize];\n  reader->ReadEntityData(dataBytes, dataSize);\n  delete dataBytes;\n\n  // skip second entity\n  reader->ReadNextHeader(&done, &type);\n  reader->ReadEntityHeader(&key, &dataSize);\n  reader->SkipEntityData();\n\n  // read and verify third entity\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader after skip\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on third entity\";\n  EXPECT_EQ(mKey3, key)\n          << \"wrong key from ReadEntityHeader on third entity\";\n  EXPECT_EQ(sizeof(DATA3), dataSize)\n          << \"wrong size from ReadEntityHeader on third entity\";\n\n  dataBytes = new char[dataSize];\n  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))\n          << \"ReadEntityData returned an error on third entity\";\n  for (unsigned int i = 0; i < sizeof(DATA3); i++) {\n    EXPECT_EQ(DATA3[i], dataBytes[i])\n             << \"data character \" << i << \" should be equal\";\n  }\n  delete dataBytes;\n  delete writer;\n  delete reader;\n}\n\nTEST_F(BackupDataTest, DeleteEntity) {\n  int fd = ::open(mFilename.string(), O_WRONLY);\n  BackupDataWriter* writer = new BackupDataWriter(fd);\n  writer->WriteEntityHeader(mKey1, sizeof(DATA1));\n  writer->WriteEntityData(DATA1, sizeof(DATA1));\n  writer->WriteEntityHeader(mKey2, -1);\n\n  ::close(fd);\n  fd = ::open(mFilename.string(), O_RDONLY);\n  BackupDataReader* reader = new BackupDataReader(fd);\n\n  bool done;\n  int type;\n  String8 key;\n  size_t dataSize;\n  char* dataBytes;\n  // read first entity\n  reader->ReadNextHeader(&done, &type);\n  reader->ReadEntityHeader(&key, &dataSize);\n  dataBytes = new char[dataSize];\n  reader->ReadEntityData(dataBytes, dataSize);\n  delete dataBytes;\n\n  // read and verify deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader on deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on second entity\";\n  EXPECT_EQ(mKey2, key)\n          << \"wrong key from ReadEntityHeader on second entity\";\n  EXPECT_EQ(-1, (int) dataSize)\n          << \"not recognizing deletion on second entity\";\n\n  delete writer;\n  delete reader;\n}\n\nTEST_F(BackupDataTest, EneityAfterDelete) {\n  int fd = ::open(mFilename.string(), O_WRONLY);\n  BackupDataWriter* writer = new BackupDataWriter(fd);\n  writer->WriteEntityHeader(mKey1, sizeof(DATA1));\n  writer->WriteEntityData(DATA1, sizeof(DATA1));\n  writer->WriteEntityHeader(mKey2, -1);\n  writer->WriteEntityHeader(mKey3, sizeof(DATA3));\n  writer->WriteEntityData(DATA3, sizeof(DATA3));\n\n  ::close(fd);\n  fd = ::open(mFilename.string(), O_RDONLY);\n  BackupDataReader* reader = new BackupDataReader(fd);\n\n  bool done;\n  int type;\n  String8 key;\n  size_t dataSize;\n  char* dataBytes;\n  // read first entity\n  reader->ReadNextHeader(&done, &type);\n  reader->ReadEntityHeader(&key, &dataSize);\n  dataBytes = new char[dataSize];\n  reader->ReadEntityData(dataBytes, dataSize);\n  delete dataBytes;\n\n  // read and verify deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader on deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on second entity\";\n  EXPECT_EQ(mKey2, key)\n          << \"wrong key from ReadEntityHeader on second entity\";\n  EXPECT_EQ(-1, (int)dataSize)\n          << \"not recognizing deletion on second entity\";\n\n  // read and verify third entity\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader after deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on third entity\";\n  EXPECT_EQ(mKey3, key)\n          << \"wrong key from ReadEntityHeader on third entity\";\n  EXPECT_EQ(sizeof(DATA3), dataSize)\n          << \"wrong size from ReadEntityHeader on third entity\";\n\n  dataBytes = new char[dataSize];\n  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))\n          << \"ReadEntityData returned an error on third entity\";\n  for (unsigned int i = 0; i < sizeof(DATA3); i++) {\n    EXPECT_EQ(DATA3[i], dataBytes[i])\n             << \"data character \" << i << \" should be equal\";\n  }\n  delete dataBytes;\n  delete writer;\n  delete reader;\n}\n\nTEST_F(BackupDataTest, OnlyDeleteEntities) {\n  int fd = ::open(mFilename.string(), O_WRONLY);\n  BackupDataWriter* writer = new BackupDataWriter(fd);\n  writer->WriteEntityHeader(mKey1, -1);\n  writer->WriteEntityHeader(mKey2, -1);\n  writer->WriteEntityHeader(mKey3, -1);\n  writer->WriteEntityHeader(mKey4, -1);\n\n  ::close(fd);\n  fd = ::open(mFilename.string(), O_RDONLY);\n  BackupDataReader* reader = new BackupDataReader(fd);\n\n  bool done;\n  int type;\n  String8 key;\n  size_t dataSize;\n  // read and verify first deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader first deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on first entity\";\n  EXPECT_EQ(mKey1, key)\n          << \"wrong key from ReadEntityHeader on first entity\";\n  EXPECT_EQ(-1, (int) dataSize)\n          << \"not recognizing deletion on first entity\";\n\n  // read and verify second deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader second deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on second entity\";\n  EXPECT_EQ(mKey2, key)\n          << \"wrong key from ReadEntityHeader on second entity\";\n  EXPECT_EQ(-1, (int) dataSize)\n          << \"not recognizing deletion on second entity\";\n\n  // read and verify third deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader third deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on third entity\";\n  EXPECT_EQ(mKey3, key)\n          << \"wrong key from ReadEntityHeader on third entity\";\n  EXPECT_EQ(-1, (int) dataSize)\n          << \"not recognizing deletion on third entity\";\n\n  // read and verify fourth deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader fourth deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on fourth entity\";\n  EXPECT_EQ(mKey4, key)\n          << \"wrong key from ReadEntityHeader on fourth entity\";\n  EXPECT_EQ(-1, (int) dataSize)\n          << \"not recognizing deletion on fourth entity\";\n\n  delete writer;\n  delete reader;\n}\n\nTEST_F(BackupDataTest, ReadDeletedEntityData) {\n  int fd = ::open(mFilename.string(), O_WRONLY);\n  BackupDataWriter* writer = new BackupDataWriter(fd);\n  writer->WriteEntityHeader(mKey1, -1);\n  writer->WriteEntityHeader(mKey2, -1);\n\n  ::close(fd);\n  fd = ::open(mFilename.string(), O_RDONLY);\n  BackupDataReader* reader = new BackupDataReader(fd);\n\n  bool done;\n  int type;\n  String8 key;\n  size_t dataSize;\n  // read and verify first deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader first deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on first entity\";\n  EXPECT_EQ(mKey1, key)\n          << \"wrong key from ReadEntityHeader on first entity\";\n  EXPECT_EQ(-1, (int) dataSize)\n          << \"not recognizing deletion on first entity\";\n\n  // erroneously try to read first entity data\n  char* dataBytes = new char[10];\n  dataBytes[0] = 'A';\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityData(dataBytes, dataSize));\n  // expect dataBytes to be unmodofied\n  EXPECT_EQ('A', dataBytes[0]);\n\n  // read and verify second deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader second deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on second entity\";\n  EXPECT_EQ(mKey2, key)\n          << \"wrong key from ReadEntityHeader on second entity\";\n  EXPECT_EQ(-1, (int) dataSize)\n          << \"not recognizing deletion on second entity\";\n\n  delete[] dataBytes;\n  delete writer;\n  delete reader;\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/ByteBucketArray_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ByteBucketArray.h>\n\n#include <gtest/gtest.h>\n\nusing android::ByteBucketArray;\n\nTEST(ByteBucketArrayTest, TestSparseInsertion) {\n    ByteBucketArray<int> bba;\n    ASSERT_TRUE(bba.set(0, 1));\n    ASSERT_TRUE(bba.set(10, 2));\n    ASSERT_TRUE(bba.set(26, 3));\n    ASSERT_TRUE(bba.set(129, 4));\n    ASSERT_TRUE(bba.set(234, 5));\n\n    for (size_t i = 0; i < bba.size(); i++) {\n        switch (i) {\n            case 0: EXPECT_EQ(1, bba[i]); break;\n            case 10: EXPECT_EQ(2, bba[i]); break;\n            case 26: EXPECT_EQ(3, bba[i]); break;\n            case 129: EXPECT_EQ(4, bba[i]); break;\n            case 234: EXPECT_EQ(5, bba[i]); break;\n            default: EXPECT_EQ(0, bba[i]); break;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/ConfigLocale_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/Log.h>\n#include <utils/String8.h>\n\n#include <gtest/gtest.h>\nnamespace android {\n\nTEST(ConfigLocaleTest, packAndUnpack2LetterLanguage) {\n     ResTable_config config;\n     config.packLanguage(\"en\");\n\n     EXPECT_EQ('e', config.language[0]);\n     EXPECT_EQ('n', config.language[1]);\n\n     char out[4] = { 1, 1, 1, 1};\n     config.unpackLanguage(out);\n     EXPECT_EQ('e', out[0]);\n     EXPECT_EQ('n', out[1]);\n     EXPECT_EQ(0, out[2]);\n     EXPECT_EQ(0, out[3]);\n\n     memset(out, 1, sizeof(out));\n     config.locale = 0;\n     config.unpackLanguage(out);\n     EXPECT_EQ(0, out[0]);\n     EXPECT_EQ(0, out[1]);\n     EXPECT_EQ(0, out[2]);\n     EXPECT_EQ(0, out[3]);\n}\n\nTEST(ConfigLocaleTest, packAndUnpack2LetterRegion) {\n     ResTable_config config;\n     config.packRegion(\"US\");\n\n     EXPECT_EQ('U', config.country[0]);\n     EXPECT_EQ('S', config.country[1]);\n\n     char out[4] = { 1, 1, 1, 1};\n     config.unpackRegion(out);\n     EXPECT_EQ('U', out[0]);\n     EXPECT_EQ('S', out[1]);\n     EXPECT_EQ(0, out[2]);\n     EXPECT_EQ(0, out[3]);\n}\n\nTEST(ConfigLocaleTest, packAndUnpack3LetterLanguage) {\n     ResTable_config config;\n     config.packLanguage(\"eng\");\n\n     // 1-00110-01 101-00100\n     EXPECT_EQ('\\x99', config.language[0]);\n     EXPECT_EQ('\\xA4', config.language[1]);\n\n     char out[4] = { 1, 1, 1, 1};\n     config.unpackLanguage(out);\n     EXPECT_EQ('e', out[0]);\n     EXPECT_EQ('n', out[1]);\n     EXPECT_EQ('g', out[2]);\n     EXPECT_EQ(0, out[3]);\n}\n\nTEST(ConfigLocaleTest, packAndUnpack3LetterLanguageAtOffset16) {\n     ResTable_config config;\n     config.packLanguage(\"tgp\");\n\n     // We had a bug where we would accidentally mask\n     // the 5th bit of both bytes\n     //\n     // packed[0] = 1011 1100\n     // packed[1] = 1101 0011\n     //\n     // which is equivalent to:\n     // 1  [0]   [1]   [2]\n     // 1-01111-00110-10011\n     EXPECT_EQ(char(0xbc), config.language[0]);\n     EXPECT_EQ(char(0xd3), config.language[1]);\n\n     char out[4] = { 1, 1, 1, 1};\n     config.unpackLanguage(out);\n     EXPECT_EQ('t', out[0]);\n     EXPECT_EQ('g', out[1]);\n     EXPECT_EQ('p', out[2]);\n     EXPECT_EQ(0, out[3]);\n}\n\nTEST(ConfigLocaleTest, packAndUnpack3LetterRegion) {\n     ResTable_config config;\n     config.packRegion(\"419\");\n\n     char out[4] = { 1, 1, 1, 1};\n     config.unpackRegion(out);\n\n     EXPECT_EQ('4', out[0]);\n     EXPECT_EQ('1', out[1]);\n     EXPECT_EQ('9', out[2]);\n}\n\n/* static */ void fillIn(const char* lang, const char* country,\n        const char* script, const char* variant, ResTable_config* out) {\n     memset(out, 0, sizeof(ResTable_config));\n     if (lang != NULL) {\n         out->packLanguage(lang);\n     }\n\n     if (country != NULL) {\n         out->packRegion(country);\n     }\n\n     if (script != NULL) {\n         memcpy(out->localeScript, script, 4);\n     }\n\n     if (variant != NULL) {\n         memcpy(out->localeVariant, variant, strlen(variant));\n     }\n}\n\nTEST(ConfigLocaleTest, IsMoreSpecificThan) {\n    ResTable_config l;\n    ResTable_config r;\n\n    fillIn(\"en\", NULL, NULL, NULL, &l);\n    fillIn(NULL, NULL, NULL, NULL, &r);\n\n    EXPECT_TRUE(l.isMoreSpecificThan(r));\n    EXPECT_FALSE(r.isMoreSpecificThan(l));\n\n    fillIn(\"eng\", NULL, NULL, NULL, &l);\n    EXPECT_TRUE(l.isMoreSpecificThan(r));\n    EXPECT_FALSE(r.isMoreSpecificThan(l));\n\n    fillIn(\"eng\", \"419\", NULL, NULL, &r);\n    EXPECT_FALSE(l.isMoreSpecificThan(r));\n    EXPECT_TRUE(r.isMoreSpecificThan(l));\n\n    fillIn(\"en\", NULL, NULL, NULL, &l);\n    fillIn(\"en\", \"US\", NULL, NULL, &r);\n    EXPECT_FALSE(l.isMoreSpecificThan(r));\n    EXPECT_TRUE(r.isMoreSpecificThan(l));\n\n    fillIn(\"en\", \"US\", NULL, NULL, &l);\n    fillIn(\"en\", \"US\", \"Latn\", NULL, &r);\n    EXPECT_FALSE(l.isMoreSpecificThan(r));\n    EXPECT_TRUE(r.isMoreSpecificThan(l));\n\n    fillIn(\"en\", \"US\", NULL, NULL, &l);\n    fillIn(\"en\", \"US\", NULL, \"POSIX\", &r);\n    EXPECT_FALSE(l.isMoreSpecificThan(r));\n    EXPECT_TRUE(r.isMoreSpecificThan(l));\n\n    fillIn(\"en\", \"US\", \"Latn\", NULL, &l);\n    fillIn(\"en\", \"US\", NULL, \"POSIX\", &r);\n    EXPECT_FALSE(l.isMoreSpecificThan(r));\n    EXPECT_TRUE(r.isMoreSpecificThan(l));\n}\n\nTEST(ConfigLocaleTest, setLocale) {\n    ResTable_config test;\n    test.setBcp47Locale(\"en-US\");\n    EXPECT_EQ('e', test.language[0]);\n    EXPECT_EQ('n', test.language[1]);\n    EXPECT_EQ('U', test.country[0]);\n    EXPECT_EQ('S', test.country[1]);\n    EXPECT_EQ(0, test.localeScript[0]);\n    EXPECT_EQ(0, test.localeVariant[0]);\n\n    test.setBcp47Locale(\"eng-419\");\n    char out[4] = { 1, 1, 1, 1};\n    test.unpackLanguage(out);\n    EXPECT_EQ('e', out[0]);\n    EXPECT_EQ('n', out[1]);\n    EXPECT_EQ('g', out[2]);\n    EXPECT_EQ(0, out[3]);\n    memset(out, 1, 4);\n    test.unpackRegion(out);\n    EXPECT_EQ('4', out[0]);\n    EXPECT_EQ('1', out[1]);\n    EXPECT_EQ('9', out[2]);\n\n\n    test.setBcp47Locale(\"en-Latn-419\");\n    memset(out, 1, 4);\n    EXPECT_EQ('e', test.language[0]);\n    EXPECT_EQ('n', test.language[1]);\n\n    EXPECT_EQ(0, memcmp(\"Latn\", test.localeScript, 4));\n    test.unpackRegion(out);\n    EXPECT_EQ('4', out[0]);\n    EXPECT_EQ('1', out[1]);\n    EXPECT_EQ('9', out[2]);\n}\n\n}  // namespace android.\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/Config_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/Log.h>\n#include <utils/String8.h>\n#include <utils/Vector.h>\n\n#include \"TestHelpers.h\"\n#include <gtest/gtest.h>\n\nnamespace android {\n\nstatic ResTable_config selectBest(const ResTable_config& target,\n        const Vector<ResTable_config>& configs) {\n    ResTable_config bestConfig;\n    memset(&bestConfig, 0, sizeof(bestConfig));\n    const size_t configCount = configs.size();\n    for (size_t i = 0; i < configCount; i++) {\n        const ResTable_config& thisConfig = configs[i];\n        if (!thisConfig.match(target)) {\n            continue;\n        }\n\n        if (thisConfig.isBetterThan(bestConfig, &target)) {\n            bestConfig = thisConfig;\n        }\n    }\n    return bestConfig;\n}\n\nstatic ResTable_config buildDensityConfig(int density) {\n    ResTable_config config;\n    memset(&config, 0, sizeof(config));\n    config.density = uint16_t(density);\n    config.sdkVersion = 4;\n    return config;\n}\n\nTEST(ConfigTest, shouldSelectBestDensity) {\n    ResTable_config deviceConfig;\n    memset(&deviceConfig, 0, sizeof(deviceConfig));\n    deviceConfig.density = ResTable_config::DENSITY_XHIGH;\n    deviceConfig.sdkVersion = 21;\n\n    Vector<ResTable_config> configs;\n\n    ResTable_config expectedBest = buildDensityConfig(ResTable_config::DENSITY_HIGH);\n    configs.add(expectedBest);\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n\n    expectedBest = buildDensityConfig(ResTable_config::DENSITY_XXHIGH);\n    configs.add(expectedBest);\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n\n    expectedBest = buildDensityConfig(int(ResTable_config::DENSITY_XXHIGH) - 20);\n    configs.add(expectedBest);\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n\n    configs.add(buildDensityConfig(int(ResTable_config::DENSITY_HIGH) + 20));\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n\n    expectedBest = buildDensityConfig(ResTable_config::DENSITY_XHIGH);\n    configs.add(expectedBest);\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n\n    expectedBest = buildDensityConfig(ResTable_config::DENSITY_ANY);\n    expectedBest.sdkVersion = 21;\n    configs.add(expectedBest);\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n}\n\nTEST(ConfigTest, shouldSelectBestDensityWhenNoneSpecified) {\n    ResTable_config deviceConfig;\n    memset(&deviceConfig, 0, sizeof(deviceConfig));\n    deviceConfig.sdkVersion = 21;\n\n    Vector<ResTable_config> configs;\n    configs.add(buildDensityConfig(ResTable_config::DENSITY_HIGH));\n\n    ResTable_config expectedBest = buildDensityConfig(ResTable_config::DENSITY_MEDIUM);\n    configs.add(expectedBest);\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n\n    expectedBest = buildDensityConfig(ResTable_config::DENSITY_ANY);\n    configs.add(expectedBest);\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n}\n\nTEST(ConfigTest, shouldMatchRoundQualifier) {\n    ResTable_config deviceConfig;\n    memset(&deviceConfig, 0, sizeof(deviceConfig));\n\n    ResTable_config roundConfig;\n    memset(&roundConfig, 0, sizeof(roundConfig));\n    roundConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;\n\n    EXPECT_FALSE(roundConfig.match(deviceConfig));\n\n    deviceConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;\n\n    EXPECT_TRUE(roundConfig.match(deviceConfig));\n\n    deviceConfig.screenLayout2 = ResTable_config::SCREENROUND_NO;\n\n    EXPECT_FALSE(roundConfig.match(deviceConfig));\n\n    ResTable_config notRoundConfig;\n    memset(&notRoundConfig, 0, sizeof(notRoundConfig));\n    notRoundConfig.screenLayout2 = ResTable_config::SCREENROUND_NO;\n\n    EXPECT_TRUE(notRoundConfig.match(deviceConfig));\n}\n\nTEST(ConfigTest, RoundQualifierShouldHaveStableSortOrder) {\n    ResTable_config defaultConfig;\n    memset(&defaultConfig, 0, sizeof(defaultConfig));\n\n    ResTable_config longConfig = defaultConfig;\n    longConfig.screenLayout = ResTable_config::SCREENLONG_YES;\n\n    ResTable_config longRoundConfig = longConfig;\n    longRoundConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;\n\n    ResTable_config longRoundPortConfig = longConfig;\n    longRoundPortConfig.orientation = ResTable_config::ORIENTATION_PORT;\n\n    EXPECT_TRUE(longConfig.compare(longRoundConfig) < 0);\n    EXPECT_TRUE(longConfig.compareLogical(longRoundConfig) < 0);\n    EXPECT_TRUE(longRoundConfig.compare(longConfig) > 0);\n    EXPECT_TRUE(longRoundConfig.compareLogical(longConfig) > 0);\n\n    EXPECT_TRUE(longRoundConfig.compare(longRoundPortConfig) < 0);\n    EXPECT_TRUE(longRoundConfig.compareLogical(longRoundPortConfig) < 0);\n    EXPECT_TRUE(longRoundPortConfig.compare(longRoundConfig) > 0);\n    EXPECT_TRUE(longRoundPortConfig.compareLogical(longRoundConfig) > 0);\n}\n\nTEST(ConfigTest, ScreenShapeHasCorrectDiff) {\n    ResTable_config defaultConfig;\n    memset(&defaultConfig, 0, sizeof(defaultConfig));\n\n    ResTable_config roundConfig = defaultConfig;\n    roundConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;\n\n    EXPECT_EQ(defaultConfig.diff(roundConfig), ResTable_config::CONFIG_SCREEN_ROUND);\n}\n\nTEST(ConfigTest, RoundIsMoreSpecific) {\n    ResTable_config deviceConfig;\n    memset(&deviceConfig, 0, sizeof(deviceConfig));\n    deviceConfig.screenLayout2 = ResTable_config::SCREENROUND_YES;\n    deviceConfig.screenLayout = ResTable_config::SCREENLONG_YES;\n\n    ResTable_config targetConfigA;\n    memset(&targetConfigA, 0, sizeof(targetConfigA));\n\n    ResTable_config targetConfigB = targetConfigA;\n    targetConfigB.screenLayout = ResTable_config::SCREENLONG_YES;\n\n    ResTable_config targetConfigC = targetConfigB;\n    targetConfigC.screenLayout2 = ResTable_config::SCREENROUND_YES;\n\n    EXPECT_TRUE(targetConfigB.isBetterThan(targetConfigA, &deviceConfig));\n    EXPECT_TRUE(targetConfigC.isBetterThan(targetConfigB, &deviceConfig));\n}\n\n}  // namespace android.\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/Idmap_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n\n#include <utils/String8.h>\n#include <utils/String16.h>\n#include \"TestHelpers.h\"\n#include \"data/basic/R.h\"\n\n#include <gtest/gtest.h>\n\nusing namespace android;\n\nnamespace {\n\n/**\n * Include a binary resource table.\n *\n * Package: com.android.test.basic\n */\n#include \"data/basic/basic_arsc.h\"\n\n/**\n * Include a binary resource table.\n * This table is an overlay.\n *\n * Package: com.android.test.basic\n */\n#include \"data/overlay/overlay_arsc.h\"\n\nenum { MAY_NOT_BE_BAG = false };\n\nclass IdmapTest : public ::testing::Test {\nprotected:\n    virtual void SetUp() {\n        ASSERT_EQ(NO_ERROR, mTargetTable.add(basic_arsc, basic_arsc_len));\n        ASSERT_EQ(NO_ERROR, mOverlayTable.add(overlay_arsc, overlay_arsc_len));\n        char targetName[256] = \"com.android.test.basic\";\n        ASSERT_EQ(NO_ERROR, mTargetTable.createIdmap(mOverlayTable, 0, 0,\n                    targetName, targetName, &mData, &mDataSize));\n    }\n\n    virtual void TearDown() {\n        free(mData);\n    }\n\n    ResTable mTargetTable;\n    ResTable mOverlayTable;\n    void* mData;\n    size_t mDataSize;\n};\n\nTEST_F(IdmapTest, canLoadIdmap) {\n    ASSERT_EQ(NO_ERROR, mTargetTable.add(overlay_arsc, overlay_arsc_len, mData, mDataSize));\n}\n\nTEST_F(IdmapTest, overlayOverridesResourceValue) {\n    Res_value val;\n    ssize_t block = mTargetTable.getResource(base::R::string::test2, &val, false);\n    ASSERT_GE(block, 0);\n    ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);\n    const ResStringPool* pool = mTargetTable.getTableStringBlock(block);\n    ASSERT_TRUE(pool != NULL);\n    ASSERT_LT(val.data, pool->size());\n\n    size_t strLen;\n    const char16_t* targetStr16 = pool->stringAt(val.data, &strLen);\n    ASSERT_TRUE(targetStr16 != NULL);\n    ASSERT_EQ(String16(\"test2\"), String16(targetStr16, strLen));\n\n    ASSERT_EQ(NO_ERROR, mTargetTable.add(overlay_arsc, overlay_arsc_len, mData, mDataSize));\n\n    ssize_t newBlock = mTargetTable.getResource(base::R::string::test2, &val, false);\n    ASSERT_GE(newBlock, 0);\n    ASSERT_NE(block, newBlock);\n    ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);\n    pool = mTargetTable.getTableStringBlock(newBlock);\n    ASSERT_TRUE(pool != NULL);\n    ASSERT_LT(val.data, pool->size());\n\n    targetStr16 = pool->stringAt(val.data, &strLen);\n    ASSERT_TRUE(targetStr16 != NULL);\n    ASSERT_EQ(String16(\"test2-overlay\"), String16(targetStr16, strLen));\n}\n\nTEST_F(IdmapTest, overlaidResourceHasSameName) {\n    ASSERT_EQ(NO_ERROR, mTargetTable.add(overlay_arsc, overlay_arsc_len, mData, mDataSize));\n\n    ResTable::resource_name resName;\n    ASSERT_TRUE(mTargetTable.getResourceName(base::R::array::integerArray1, false, &resName));\n\n    ASSERT_TRUE(resName.package != NULL);\n    ASSERT_TRUE(resName.type != NULL);\n    ASSERT_TRUE(resName.name != NULL);\n\n    EXPECT_EQ(String16(\"com.android.test.basic\"), String16(resName.package, resName.packageLen));\n    EXPECT_EQ(String16(\"array\"), String16(resName.type, resName.typeLen));\n    EXPECT_EQ(String16(\"integerArray1\"), String16(resName.name, resName.nameLen));\n}\n\n} // namespace\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/ObbFile_test.cpp",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"ObbFile_test\"\n#include <androidfw/ObbFile.h>\n#include <utils/Log.h>\n#include <utils/RefBase.h>\n#include <utils/String8.h>\n\n#include <gtest/gtest.h>\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <string.h>\n\nnamespace android {\n\n#define TEST_FILENAME \"/test.obb\"\n\nclass ObbFileTest : public testing::Test {\nprotected:\n    sp<ObbFile> mObbFile;\n    String8 mFileName;\n\n    virtual void SetUp() {\n        mObbFile = new ObbFile();\n        char* externalStorage = getenv(\"EXTERNAL_STORAGE\");\n\n        mFileName.append(externalStorage);\n        mFileName.append(TEST_FILENAME);\n\n        int fd = ::open(mFileName.string(), O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);\n        if (fd < 0) {\n            FAIL() << \"Couldn't create \" << mFileName.string() << \" for tests\";\n        }\n    }\n\n    virtual void TearDown() {\n    }\n};\n\nTEST_F(ObbFileTest, ReadFailure) {\n    EXPECT_FALSE(mObbFile->readFrom(-1))\n            << \"No failure on invalid file descriptor\";\n}\n\nTEST_F(ObbFileTest, WriteThenRead) {\n    const char* packageName = \"com.example.obbfile\";\n    const int32_t versionNum = 1;\n\n    mObbFile->setPackageName(String8(packageName));\n    mObbFile->setVersion(versionNum);\n#define SALT_SIZE 8\n    unsigned char salt[SALT_SIZE] = {0x01, 0x10, 0x55, 0xAA, 0xFF, 0x00, 0x5A, 0xA5};\n    EXPECT_TRUE(mObbFile->setSalt(salt, SALT_SIZE))\n            << \"Salt should be successfully set\";\n\n    EXPECT_TRUE(mObbFile->writeTo(mFileName.string()))\n            << \"couldn't write to fake .obb file\";\n\n    mObbFile = new ObbFile();\n\n    EXPECT_TRUE(mObbFile->readFrom(mFileName.string()))\n            << \"couldn't read from fake .obb file\";\n\n    EXPECT_EQ(versionNum, mObbFile->getVersion())\n            << \"version didn't come out the same as it went in\";\n    const char* currentPackageName = mObbFile->getPackageName().string();\n    EXPECT_STREQ(packageName, currentPackageName)\n            << \"package name didn't come out the same as it went in\";\n\n    size_t saltLen;\n    const unsigned char* newSalt = mObbFile->getSalt(&saltLen);\n\n    EXPECT_EQ(sizeof(salt), saltLen)\n            << \"salt sizes were not the same\";\n\n    for (size_t i = 0; i < sizeof(salt); i++) {\n        EXPECT_EQ(salt[i], newSalt[i])\n                << \"salt character \" << i << \" should be equal\";\n    }\n    EXPECT_TRUE(memcmp(newSalt, salt, sizeof(salt)) == 0)\n            << \"salts should be the same\";\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/ResTable_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n\n#include <codecvt>\n#include <locale>\n#include <string>\n\n#include <utils/String8.h>\n#include <utils/String16.h>\n#include \"TestHelpers.h\"\n#include \"data/basic/R.h\"\n#include \"data/lib/R.h\"\n\n#include <gtest/gtest.h>\n\nusing namespace android;\n\nnamespace {\n\n/**\n * Include a binary resource table.\n *\n * Package: com.android.test.basic\n */\n#include \"data/basic/basic_arsc.h\"\n\n#include \"data/lib/lib_arsc.h\"\n\nTEST(ResTableTest, shouldLoadSuccessfully) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n}\n\nTEST(ResTableTest, simpleTypeIsRetrievedCorrectly) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    EXPECT_TRUE(IsStringEqual(table, base::R::string::test1, \"test1\"));\n}\n\nTEST(ResTableTest, resourceNameIsResolved) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    String16 defPackage(\"com.android.test.basic\");\n    String16 testName(\"@string/test1\");\n    uint32_t resID = table.identifierForName(testName.string(), testName.size(),\n                                             0, 0,\n                                             defPackage.string(), defPackage.size());\n    ASSERT_NE(uint32_t(0x00000000), resID);\n    ASSERT_EQ(base::R::string::test1, resID);\n}\n\nTEST(ResTableTest, noParentThemeIsAppliedCorrectly) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    ResTable::Theme theme(table);\n    ASSERT_EQ(NO_ERROR, theme.applyStyle(base::R::style::Theme1));\n\n    Res_value val;\n    uint32_t specFlags = 0;\n    ssize_t index = theme.getAttribute(base::R::attr::attr1, &val, &specFlags);\n    ASSERT_GE(index, 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n    ASSERT_EQ(uint32_t(100), val.data);\n\n    index = theme.getAttribute(base::R::attr::attr2, &val, &specFlags);\n    ASSERT_GE(index, 0);\n    ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);\n    ASSERT_EQ(base::R::integer::number1, val.data);\n}\n\nTEST(ResTableTest, parentThemeIsAppliedCorrectly) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    ResTable::Theme theme(table);\n    ASSERT_EQ(NO_ERROR, theme.applyStyle(base::R::style::Theme2));\n\n    Res_value val;\n    uint32_t specFlags = 0;\n    ssize_t index = theme.getAttribute(base::R::attr::attr1, &val, &specFlags);\n    ASSERT_GE(index, 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n    ASSERT_EQ(uint32_t(300), val.data);\n\n    index = theme.getAttribute(base::R::attr::attr2, &val, &specFlags);\n    ASSERT_GE(index, 0);\n    ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);\n    ASSERT_EQ(base::R::integer::number1, val.data);\n}\n\nTEST(ResTableTest, libraryThemeIsAppliedCorrectly) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(lib_arsc, lib_arsc_len));\n\n    ResTable::Theme theme(table);\n    ASSERT_EQ(NO_ERROR, theme.applyStyle(lib::R::style::Theme));\n\n    Res_value val;\n    uint32_t specFlags = 0;\n    ssize_t index = theme.getAttribute(lib::R::attr::attr1, &val, &specFlags);\n    ASSERT_GE(index, 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n    ASSERT_EQ(uint32_t(700), val.data);\n}\n\nTEST(ResTableTest, referenceToBagIsNotResolved) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    Res_value val;\n    ssize_t block = table.getResource(base::R::integer::number2, &val, MAY_NOT_BE_BAG);\n    ASSERT_GE(block, 0);\n    ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);\n    ASSERT_EQ(base::R::array::integerArray1, val.data);\n\n    ssize_t newBlock = table.resolveReference(&val, block);\n    EXPECT_EQ(block, newBlock);\n    EXPECT_EQ(Res_value::TYPE_REFERENCE, val.dataType);\n    EXPECT_EQ(base::R::array::integerArray1, val.data);\n}\n\nTEST(ResTableTest, resourcesStillAccessibleAfterParameterChange) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    Res_value val;\n    ssize_t block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);\n    ASSERT_GE(block, 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n\n    const ResTable::bag_entry* entry;\n    ssize_t count = table.lockBag(base::R::array::integerArray1, &entry);\n    ASSERT_GE(count, 0);\n    table.unlockBag(entry);\n\n    ResTable_config param;\n    memset(&param, 0, sizeof(param));\n    param.density = 320;\n    table.setParameters(&param);\n\n    block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);\n    ASSERT_GE(block, 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n\n    count = table.lockBag(base::R::array::integerArray1, &entry);\n    ASSERT_GE(count, 0);\n    table.unlockBag(entry);\n}\n\nTEST(ResTableTest, resourceIsOverridenWithBetterConfig) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    Res_value val;\n    ssize_t block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);\n    ASSERT_GE(block, 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n    ASSERT_EQ(uint32_t(200), val.data);\n\n    ResTable_config param;\n    memset(&param, 0, sizeof(param));\n    param.language[0] = 's';\n    param.language[1] = 'v';\n    param.country[0] = 'S';\n    param.country[1] = 'E';\n    table.setParameters(&param);\n\n    block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);\n    ASSERT_GE(block, 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n    ASSERT_EQ(uint32_t(400), val.data);\n}\n\nTEST(ResTableTest, emptyTableHasSensibleDefaults) {\n    const int32_t assetCookie = 1;\n\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.addEmpty(assetCookie));\n\n    // Adding an empty table gives us one table!\n    ASSERT_EQ(uint32_t(1), table.getTableCount());\n\n    // Adding an empty table doesn't mean we get packages.\n    ASSERT_EQ(uint32_t(0), table.getBasePackageCount());\n\n    Res_value val;\n    ASSERT_LT(table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG), 0);\n}\n\nvoid testU16StringToInt(const char16_t* str, uint32_t expectedValue,\n                        bool expectSuccess, bool expectHex) {\n    size_t len = std::char_traits<char16_t>::length(str);\n\n    // Gtest can't print UTF-16 strings, so we have to convert to UTF-8 :(\n    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;\n    std::string s = convert.to_bytes(std::u16string(str, len));\n\n    Res_value out = {};\n    ASSERT_EQ(expectSuccess, U16StringToInt(str, len, &out))\n        << \"Failed with \" << s;\n\n    if (!expectSuccess) {\n        ASSERT_EQ(out.TYPE_NULL, out.dataType) << \"Failed with \" << s;\n        return;\n    }\n\n    if (expectHex) {\n        ASSERT_EQ(out.TYPE_INT_HEX, out.dataType) << \"Failed with \" << s;\n    } else {\n        ASSERT_EQ(out.TYPE_INT_DEC, out.dataType) << \"Failed with \" << s;\n    }\n\n    ASSERT_EQ(expectedValue, out.data) << \"Failed with \" << s;\n}\n\nTEST(ResTableTest, U16StringToInt) {\n    testU16StringToInt(u\"\", 0U, false, false);\n    testU16StringToInt(u\"    \", 0U, false, false);\n    testU16StringToInt(u\"\\t\\n\", 0U, false, false);\n\n    testU16StringToInt(u\"abcd\", 0U, false, false);\n    testU16StringToInt(u\"10abcd\", 0U, false, false);\n    testU16StringToInt(u\"42 42\", 0U, false, false);\n    testU16StringToInt(u\"- 42\", 0U, false, false);\n    testU16StringToInt(u\"-\", 0U, false, false);\n\n    testU16StringToInt(u\"0x\", 0U, false, true);\n    testU16StringToInt(u\"0xnope\", 0U, false, true);\n    testU16StringToInt(u\"0X42\", 0U, false, true);\n    testU16StringToInt(u\"0x42 0x42\", 0U, false, true);\n    testU16StringToInt(u\"-0x0\", 0U, false, true);\n    testU16StringToInt(u\"-0x42\", 0U, false, true);\n    testU16StringToInt(u\"- 0x42\", 0U, false, true);\n\n    // Note that u\" 42\" would pass. This preserves the old behavior, but it may\n    // not be desired.\n    testU16StringToInt(u\"42 \", 0U, false, false);\n    testU16StringToInt(u\"0x42 \", 0U, false, true);\n\n    // Decimal cases.\n    testU16StringToInt(u\"0\", 0U, true, false);\n    testU16StringToInt(u\"-0\", 0U, true, false);\n    testU16StringToInt(u\"42\", 42U, true, false);\n    testU16StringToInt(u\" 42\", 42U, true, false);\n    testU16StringToInt(u\"-42\", static_cast<uint32_t>(-42), true, false);\n    testU16StringToInt(u\" -42\", static_cast<uint32_t>(-42), true, false);\n    testU16StringToInt(u\"042\", 42U, true, false);\n    testU16StringToInt(u\"-042\", static_cast<uint32_t>(-42), true, false);\n\n    // Hex cases.\n    testU16StringToInt(u\"0x0\", 0x0, true, true);\n    testU16StringToInt(u\"0x42\", 0x42, true, true);\n    testU16StringToInt(u\" 0x42\", 0x42, true, true);\n\n    // Just before overflow cases:\n    testU16StringToInt(u\"2147483647\", INT_MAX, true, false);\n    testU16StringToInt(u\"-2147483648\", static_cast<uint32_t>(INT_MIN), true,\n                       false);\n    testU16StringToInt(u\"0xffffffff\", UINT_MAX, true, true);\n\n    // Overflow cases:\n    testU16StringToInt(u\"2147483648\", 0U, false, false);\n    testU16StringToInt(u\"-2147483649\", 0U, false, false);\n    testU16StringToInt(u\"0x1ffffffff\", 0U, false, true);\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/Split_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n\n#include <utils/String8.h>\n#include <utils/String16.h>\n#include \"TestHelpers.h\"\n#include \"data/basic/R.h\"\n\n#include <gtest/gtest.h>\n\nusing namespace android;\n\nnamespace {\n\n/**\n * Include a binary resource table. This table\n * is a base table for an APK split.\n *\n * Package: com.android.test.basic\n */\n#include \"data/basic/basic_arsc.h\"\n\n/**\n * Include a binary resource table. This table\n * is a configuration split table for an APK split.\n *\n * Package: com.android.test.basic\n */\n#include \"data/basic/split_de_fr_arsc.h\"\n#include \"data/basic/split_hdpi_v4_arsc.h\"\n#include \"data/basic/split_xhdpi_v4_arsc.h\"\n#include \"data/basic/split_xxhdpi_v4_arsc.h\"\n\n/**\n * Include a binary resource table. This table\n * is a feature split table for an APK split.\n *\n * Package: com.android.test.basic\n */\n#include \"data/feature/feature_arsc.h\"\n\nenum { MAY_NOT_BE_BAG = false };\n\nvoid makeConfigFrench(ResTable_config* config) {\n    memset(config, 0, sizeof(*config));\n    config->language[0] = 'f';\n    config->language[1] = 'r';\n}\n\nTEST(SplitTest, TestLoadBase) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n}\n\nTEST(SplitTest, TestGetResourceFromBase) {\n    ResTable_config frenchConfig;\n    makeConfigFrench(&frenchConfig);\n\n    ResTable table;\n    table.setParameters(&frenchConfig);\n\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    ResTable_config expectedConfig;\n    memset(&expectedConfig, 0, sizeof(expectedConfig));\n\n    Res_value val;\n    ResTable_config config;\n    ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, NULL, &config);\n\n    // The returned block should tell us which string pool to get the value, if it is a string.\n    EXPECT_GE(block, 0);\n\n    // We expect the default resource to be selected since it is the only resource configuration.\n    EXPECT_EQ(0, expectedConfig.compare(config));\n\n    EXPECT_EQ(Res_value::TYPE_STRING, val.dataType);\n}\n\nTEST(SplitTest, TestGetResourceFromSplit) {\n    ResTable_config expectedConfig;\n    makeConfigFrench(&expectedConfig);\n\n    ResTable table;\n    table.setParameters(&expectedConfig);\n\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n    ASSERT_EQ(NO_ERROR, table.add(split_de_fr_arsc, split_de_fr_arsc_len));\n\n    Res_value val;\n    ResTable_config config;\n    ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, NULL, &config);\n\n    EXPECT_GE(block, 0);\n\n    EXPECT_EQ(0, expectedConfig.compare(config));\n\n    EXPECT_EQ(Res_value::TYPE_STRING, val.dataType);\n}\n\nTEST(SplitTest, ResourcesFromBaseAndSplitHaveSameNames) {\n    ResTable_config expectedConfig;\n    makeConfigFrench(&expectedConfig);\n\n    ResTable table;\n    table.setParameters(&expectedConfig);\n\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    ResTable::resource_name baseName;\n    EXPECT_TRUE(table.getResourceName(base::R::string::test1, false, &baseName));\n\n    ASSERT_EQ(NO_ERROR, table.add(split_de_fr_arsc, split_de_fr_arsc_len));\n\n    ResTable::resource_name frName;\n    EXPECT_TRUE(table.getResourceName(base::R::string::test1, false, &frName));\n\n    EXPECT_EQ(\n            String16(baseName.package, baseName.packageLen),\n            String16(frName.package, frName.packageLen));\n\n    EXPECT_EQ(\n            String16(baseName.type, baseName.typeLen),\n            String16(frName.type, frName.typeLen));\n\n    EXPECT_EQ(\n            String16(baseName.name, baseName.nameLen),\n            String16(frName.name, frName.nameLen));\n}\n\nTEST(SplitTest, TypeEntrySpecFlagsAreUpdated) {\n    ResTable_config defaultConfig;\n    memset(&defaultConfig, 0, sizeof(defaultConfig));\n\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    Res_value val;\n    uint32_t specFlags = 0;\n    ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, &specFlags, NULL);\n    EXPECT_GE(block, 0);\n\n    EXPECT_EQ(static_cast<uint32_t>(0), specFlags);\n\n    ASSERT_EQ(NO_ERROR, table.add(split_de_fr_arsc, split_de_fr_arsc_len));\n\n    uint32_t frSpecFlags = 0;\n    block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, &frSpecFlags, NULL);\n    EXPECT_GE(block, 0);\n\n    EXPECT_EQ(ResTable_config::CONFIG_LOCALE, frSpecFlags);\n}\n\nTEST(SplitTest, SelectBestDensity) {\n    ResTable_config baseConfig;\n    memset(&baseConfig, 0, sizeof(baseConfig));\n    baseConfig.density = ResTable_config::DENSITY_XHIGH;\n    baseConfig.sdkVersion = 21;\n\n    ResTable table;\n    table.setParameters(&baseConfig);\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n    ASSERT_EQ(NO_ERROR, table.add(split_hdpi_v4_arsc, split_hdpi_v4_arsc_len));\n\n    EXPECT_TRUE(IsStringEqual(table, base::R::string::density, \"hdpi\"));\n\n    ASSERT_EQ(NO_ERROR, table.add(split_xhdpi_v4_arsc, split_xhdpi_v4_arsc_len));\n\n    EXPECT_TRUE(IsStringEqual(table, base::R::string::density, \"xhdpi\"));\n\n    ASSERT_EQ(NO_ERROR, table.add(split_xxhdpi_v4_arsc, split_xxhdpi_v4_arsc_len));\n\n    EXPECT_TRUE(IsStringEqual(table, base::R::string::density, \"xhdpi\"));\n\n    baseConfig.density = ResTable_config::DENSITY_XXHIGH;\n    table.setParameters(&baseConfig);\n\n    EXPECT_TRUE(IsStringEqual(table, base::R::string::density, \"xxhdpi\"));\n}\n\nTEST(SplitFeatureTest, TestNewResourceIsAccessible) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    Res_value val;\n    ssize_t block = table.getResource(base::R::string::test3, &val, MAY_NOT_BE_BAG);\n    EXPECT_LT(block, 0);\n\n    ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len));\n\n    block = table.getResource(base::R::string::test3, &val, MAY_NOT_BE_BAG);\n    EXPECT_GE(block, 0);\n\n    EXPECT_EQ(Res_value::TYPE_STRING, val.dataType);\n}\n\nTEST(SplitFeatureTest, TestNewResourceNameHasCorrectName) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    ResTable::resource_name name;\n    EXPECT_FALSE(table.getResourceName(base::R::string::test3, false, &name));\n\n    ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len));\n\n    ASSERT_TRUE(table.getResourceName(base::R::string::test3, false, &name));\n\n    EXPECT_EQ(String16(\"com.android.test.basic\"),\n            String16(name.package, name.packageLen));\n\n    EXPECT_EQ(String16(\"string\"),\n            String16(name.type, name.typeLen));\n\n    EXPECT_EQ(String16(\"test3\"),\n            String16(name.name, name.nameLen));\n}\n\nTEST(SplitFeatureTest, TestNewResourceIsAccessibleByName) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n    ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len));\n\n    const String16 name(\"test3\");\n    const String16 type(\"string\");\n    const String16 package(\"com.android.test.basic\");\n    ASSERT_EQ(base::R::string::test3, table.identifierForName(name.string(), name.size(),\n                                                              type.string(), type.size(),\n                                                              package.string(), package.size()));\n}\n\n} // namespace\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/TestHelpers.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"TestHelpers.h\"\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/String8.h>\n#include <gtest/gtest.h>\n\nnamespace android {\n\n::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resourceId, const char* expectedStr) {\n    Res_value val;\n    ssize_t block = table.getResource(resourceId, &val, MAY_NOT_BE_BAG);\n    if (block < 0) {\n        return ::testing::AssertionFailure() << \"could not find resource\";\n    }\n\n    if (val.dataType != Res_value::TYPE_STRING) {\n        return ::testing::AssertionFailure() << \"resource is not a string\";\n    }\n\n    const ResStringPool* pool = table.getTableStringBlock(block);\n    if (pool == NULL) {\n        return ::testing::AssertionFailure() << \"table has no string pool for block \" << block;\n    }\n\n    const String8 actual = pool->string8ObjectAt(val.data);\n    if (String8(expectedStr) != actual) {\n        return ::testing::AssertionFailure() << actual.string();\n    }\n    return ::testing::AssertionSuccess() << actual.string();\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/TestHelpers.h",
    "content": "#ifndef __TEST_HELPERS_H\n#define __TEST_HELPERS_H\n\n#include <ostream>\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/String8.h>\n#include <utils/String16.h>\n#include <gtest/gtest.h>\n\nstatic inline ::std::ostream& operator<<(::std::ostream& out, const android::String8& str) {\n    return out << str.string();\n}\n\nstatic inline ::std::ostream& operator<<(::std::ostream& out, const android::String16& str) {\n    return out << android::String8(str).string();\n}\n\nnamespace android {\n\nenum { MAY_NOT_BE_BAG = false };\n\nstatic inline bool operator==(const android::ResTable_config& a, const android::ResTable_config& b) {\n    return memcmp(&a, &b, sizeof(a)) == 0;\n}\n\nstatic inline ::std::ostream& operator<<(::std::ostream& out, const android::ResTable_config& c) {\n    return out << c.toString().string();\n}\n\n::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resourceId, const char* expectedStr);\n\n} // namespace android\n\n#endif // __TEST_HELPERS_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/Theme_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n\n#include <utils/String8.h>\n#include <utils/String16.h>\n#include \"TestHelpers.h\"\n#include \"data/system/R.h\"\n#include \"data/app/R.h\"\n\n#include <gtest/gtest.h>\n\nusing namespace android;\n\nnamespace {\n\n#include \"data/system/system_arsc.h\"\n#include \"data/app/app_arsc.h\"\n\nenum { MAY_NOT_BE_BAG = false };\n\n/**\n * TODO(adamlesinski): Enable when fixed.\n */\nTEST(ThemeTest, DISABLED_shouldCopyThemeFromDifferentResTable) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(system_arsc, system_arsc_len));\n    ASSERT_EQ(NO_ERROR, table.add(app_arsc, app_arsc_len));\n\n    ResTable::Theme theme1(table);\n    ASSERT_EQ(NO_ERROR, theme1.applyStyle(app::R::style::Theme_One));\n    Res_value val;\n    ASSERT_GE(theme1.getAttribute(android::R::attr::background, &val), 0);\n    ASSERT_EQ(Res_value::TYPE_INT_COLOR_RGB8, val.dataType);\n    ASSERT_EQ(uint32_t(0xffff0000), val.data);\n    ASSERT_GE(theme1.getAttribute(app::R::attr::number, &val), 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n    ASSERT_EQ(uint32_t(1), val.data);\n\n    ResTable table2;\n    ASSERT_EQ(NO_ERROR, table2.add(system_arsc, system_arsc_len));\n    ASSERT_EQ(NO_ERROR, table2.add(app_arsc, app_arsc_len));\n\n    ResTable::Theme theme2(table2);\n    ASSERT_EQ(NO_ERROR, theme2.setTo(theme1));\n    ASSERT_GE(theme2.getAttribute(android::R::attr::background, &val), 0);\n    ASSERT_EQ(Res_value::TYPE_INT_COLOR_RGB8, val.dataType);\n    ASSERT_EQ(uint32_t(0xffff0000), val.data);\n    ASSERT_GE(theme2.getAttribute(app::R::attr::number, &val), 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n    ASSERT_EQ(uint32_t(1), val.data);\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/TypeWrappers_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n#include <androidfw/TypeWrappers.h>\n#include <utils/String8.h>\n\n#include <gtest/gtest.h>\n\nnamespace android {\n\nvoid* createTypeData() {\n    ResTable_type t;\n    memset(&t, 0, sizeof(t));\n    t.header.type = RES_TABLE_TYPE_TYPE;\n    t.header.headerSize = sizeof(t);\n    t.id = 1;\n    t.entryCount = 3;\n\n    uint32_t offsets[3];\n    t.entriesStart = t.header.headerSize + sizeof(offsets);\n    t.header.size = t.entriesStart;\n\n    offsets[0] = 0;\n    ResTable_entry e1;\n    memset(&e1, 0, sizeof(e1));\n    e1.size = sizeof(e1);\n    e1.key.index = 0;\n    t.header.size += sizeof(e1);\n\n    Res_value v1;\n    memset(&v1, 0, sizeof(v1));\n    t.header.size += sizeof(v1);\n\n    offsets[1] = ResTable_type::NO_ENTRY;\n\n    offsets[2] = sizeof(e1) + sizeof(v1);\n    ResTable_entry e2;\n    memset(&e2, 0, sizeof(e2));\n    e2.size = sizeof(e2);\n    e2.key.index = 1;\n    t.header.size += sizeof(e2);\n\n    Res_value v2;\n    memset(&v2, 0, sizeof(v2));\n    t.header.size += sizeof(v2);\n\n    uint8_t* data = (uint8_t*)malloc(t.header.size);\n    uint8_t* p = data;\n    memcpy(p, &t, sizeof(t));\n    p += sizeof(t);\n    memcpy(p, offsets, sizeof(offsets));\n    p += sizeof(offsets);\n    memcpy(p, &e1, sizeof(e1));\n    p += sizeof(e1);\n    memcpy(p, &v1, sizeof(v1));\n    p += sizeof(v1);\n    memcpy(p, &e2, sizeof(e2));\n    p += sizeof(e2);\n    memcpy(p, &v2, sizeof(v2));\n    p += sizeof(v2);\n    return data;\n}\n\nTEST(TypeVariantIteratorTest, shouldIterateOverTypeWithoutErrors) {\n    ResTable_type* data = (ResTable_type*) createTypeData();\n\n    TypeVariant v(data);\n\n    TypeVariant::iterator iter = v.beginEntries();\n    ASSERT_EQ(uint32_t(0), iter.index());\n    ASSERT_TRUE(NULL != *iter);\n    ASSERT_EQ(uint32_t(0), iter->key.index);\n    ASSERT_NE(v.endEntries(), iter);\n\n    iter++;\n\n    ASSERT_EQ(uint32_t(1), iter.index());\n    ASSERT_TRUE(NULL == *iter);\n    ASSERT_NE(v.endEntries(), iter);\n\n    iter++;\n\n    ASSERT_EQ(uint32_t(2), iter.index());\n    ASSERT_TRUE(NULL != *iter);\n    ASSERT_EQ(uint32_t(1), iter->key.index);\n    ASSERT_NE(v.endEntries(), iter);\n\n    iter++;\n\n    ASSERT_EQ(v.endEntries(), iter);\n\n    free(data);\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/ZipUtils_test.cpp",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"ZipUtils_test\"\n#include <utils/Log.h>\n#include <androidfw/ZipUtils.h>\n\n#include <gtest/gtest.h>\n\n#include <fcntl.h>\n#include <string.h>\n\nnamespace android {\n\nclass ZipUtilsTest : public testing::Test {\nprotected:\n    virtual void SetUp() {\n    }\n\n    virtual void TearDown() {\n    }\n};\n\nTEST_F(ZipUtilsTest, ZipTimeConvertSuccess) {\n    struct tm t;\n\n    // 2011-06-29 14:40:40\n    long when = 0x3EDD7514;\n\n    ZipUtils::zipTimeToTimespec(when, &t);\n\n    EXPECT_EQ(2011, t.tm_year + 1900)\n            << \"Year was improperly converted.\";\n\n    EXPECT_EQ(6, t.tm_mon)\n            << \"Month was improperly converted.\";\n\n    EXPECT_EQ(29, t.tm_mday)\n            << \"Day was improperly converted.\";\n\n    EXPECT_EQ(14, t.tm_hour)\n            << \"Hour was improperly converted.\";\n\n    EXPECT_EQ(40, t.tm_min)\n            << \"Minute was improperly converted.\";\n\n    EXPECT_EQ(40, t.tm_sec)\n            << \"Second was improperly converted.\";\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/.gitignore",
    "content": "*.apk\n*.arsc\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/app/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.android.app\">\n</manifest>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/app/R.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __APP_R_H\n#define __APP_R_H\n\nnamespace app {\nnamespace R {\n\nnamespace attr {\n    enum {\n        number         = 0x7f010000,   // default\n    };\n}\n\nnamespace style {\n    enum {\n        Theme_One      = 0x7f020000,   // default\n    };\n}\n\n} // namespace R\n} // namespace app\n\n#endif // __APP_R_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/app/app_arsc.h",
    "content": "unsigned char app_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0xc4, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x9c, 0x02, 0x00, 0x00,\n  0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,\n  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,\n  0x64, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x70, 0x00, 0x70, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00,\n  0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00,\n  0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,\n  0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x6e, 0x00,\n  0x75, 0x00, 0x6d, 0x00, 0x62, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00,\n  0x09, 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00,\n  0x2e, 0x00, 0x4f, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00,\n  0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00,\n  0x64, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x01, 0x7f, 0x08, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00\n};\nunsigned int app_arsc_len = 708;\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/app/build",
    "content": "#!/bin/bash\n#\n# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\naapt package -v -I ../system/bundle.apk -M AndroidManifest.xml -S res -F bundle.apk -f && \\\nunzip bundle.apk resources.arsc && \\\nmv resources.arsc app.arsc && \\\nxxd -i app.arsc > app_arsc.h\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/app/res/values/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<resources>\n    <attr name=\"number\" format=\"integer\"/>\n    <style name=\"Theme.One\" parent=\"@android:style/Theme.One\">\n        <item name=\"number\">1</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.android.test.basic\">\n    <application>\n    </application>\n</manifest>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/R.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __BASE_R_H\n#define __BASE_R_H\n\nnamespace base {\nnamespace R {\n\nnamespace attr {\n    enum {\n        attr1       = 0x7f010000, // default\n        attr2       = 0x7f010001, // default\n    };\n}\n\nnamespace layout {\n    enum {\n        main        = 0x7f020000,  // default, fr-sw600dp-v13\n    };\n}\n\nnamespace string {\n    enum {\n        test1       = 0x7f030000,   // default\n        test2       = 0x7f030001,   // default\n        density     = 0x7f030002,   // default\n\n        test3       = 0x7f080000,   // default (in feature)\n        test4       = 0x7f080001,   // default (in feature)\n    };\n}\n\nnamespace integer {\n    enum {\n        number1     = 0x7f040000,   // default, sv\n        number2     = 0x7f040001,   // default\n\n        test3       = 0x7f090000,   // default (in feature)\n    };\n}\n\nnamespace style {\n    enum {\n        Theme1      = 0x7f050000,   // default\n        Theme2      = 0x7f050001,   // default\n    };\n}\n\nnamespace array {\n    enum {\n        integerArray1 = 0x7f060000,   // default\n    };\n}\n\n} // namespace R\n} // namespace base\n\n#endif // __BASE_R_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/basic_arsc.h",
    "content": "unsigned char basic_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0x68, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,\n  0x72, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x13, 0x00, 0x72, 0x00,\n  0x65, 0x00, 0x73, 0x00, 0x2f, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00,\n  0x6f, 0x00, 0x75, 0x00, 0x74, 0x00, 0x2f, 0x00, 0x6d, 0x00, 0x61, 0x00,\n  0x69, 0x00, 0x6e, 0x00, 0x2e, 0x00, 0x78, 0x00, 0x6d, 0x00, 0x6c, 0x00,\n  0x00, 0x00, 0x22, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2f, 0x00,\n  0x6c, 0x00, 0x61, 0x00, 0x79, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x74, 0x00,\n  0x2d, 0x00, 0x66, 0x00, 0x72, 0x00, 0x2d, 0x00, 0x73, 0x00, 0x77, 0x00,\n  0x36, 0x00, 0x30, 0x00, 0x30, 0x00, 0x64, 0x00, 0x70, 0x00, 0x2d, 0x00,\n  0x76, 0x00, 0x31, 0x00, 0x33, 0x00, 0x2f, 0x00, 0x6d, 0x00, 0x61, 0x00,\n  0x69, 0x00, 0x6e, 0x00, 0x2e, 0x00, 0x78, 0x00, 0x6d, 0x00, 0x6c, 0x00,\n  0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x31, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00,\n  0x74, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01,\n  0xa0, 0x06, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00,\n  0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00,\n  0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00,\n  0x73, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00,\n  0x69, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x20, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00,\n  0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,\n  0x90, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,\n  0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x00, 0x00,\n  0x06, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00, 0x6f, 0x00, 0x75, 0x00,\n  0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00,\n  0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x00, 0x00, 0x07, 0x00, 0x69, 0x00,\n  0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00,\n  0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00, 0x6c, 0x00,\n  0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00, 0x72, 0x00, 0x72, 0x00,\n  0x61, 0x00, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,\n  0xec, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,\n  0x28, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,\n  0x56, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,\n  0x88, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00,\n  0x72, 0x00, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00, 0x74, 0x00,\n  0x74, 0x00, 0x72, 0x00, 0x32, 0x00, 0x00, 0x00, 0x04, 0x00, 0x6d, 0x00,\n  0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00,\n  0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00,\n  0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x32, 0x00, 0x00, 0x00,\n  0x07, 0x00, 0x6e, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x62, 0x00, 0x65, 0x00,\n  0x72, 0x00, 0x31, 0x00, 0x00, 0x00, 0x07, 0x00, 0x6e, 0x00, 0x75, 0x00,\n  0x6d, 0x00, 0x62, 0x00, 0x65, 0x00, 0x72, 0x00, 0x32, 0x00, 0x00, 0x00,\n  0x06, 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00,\n  0x31, 0x00, 0x00, 0x00, 0x06, 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 0x00,\n  0x6d, 0x00, 0x65, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x69, 0x00,\n  0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00,\n  0x41, 0x00, 0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00, 0x31, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x84, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00,\n  0x10, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10,\n  0x05, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x24, 0x00, 0x00,\n  0x01, 0x02, 0x44, 0x00, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x58, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x72, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\n  0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x02, 0x44, 0x00, 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,\n  0x03, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x6c, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0xc8, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01,\n  0x00, 0x00, 0x06, 0x7f, 0x01, 0x02, 0x44, 0x00, 0x5c, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x76, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x90, 0x01, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x02, 0x44, 0x00, 0x90, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x28, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f,\n  0x08, 0x00, 0x00, 0x10, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7f,\n  0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x7f, 0x10, 0x00, 0x01, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x7f, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x01, 0x7f, 0x08, 0x00, 0x00, 0x10, 0x2c, 0x01, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00,\n  0x7c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\n  0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x00\n};\nunsigned int basic_arsc_len = 1896;\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/build",
    "content": "#!/bin/bash\n#\n# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\nPATH_TO_FRAMEWORK_RES=$(gettop)/prebuilts/sdk/current/android.jar\n\naapt package -M AndroidManifest.xml -S res -I $PATH_TO_FRAMEWORK_RES --split hdpi --split xhdpi --split xxhdpi --split fr,de -F bundle.apk -f && \\\nunzip bundle.apk resources.arsc && \\\nmv resources.arsc basic.arsc && \\\nxxd -i basic.arsc > basic_arsc.h && \\\n\\\nunzip bundle_de_fr.apk resources.arsc && \\\nmv resources.arsc split_de_fr.arsc && \\\nxxd -i split_de_fr.arsc > split_de_fr_arsc.h && \\\n\\\nunzip bundle_hdpi-v4.apk resources.arsc && \\\nmv resources.arsc split_hdpi_v4.arsc && \\\nxxd -i split_hdpi_v4.arsc > split_hdpi_v4_arsc.h && \\\n\\\nunzip bundle_xhdpi-v4.apk resources.arsc && \\\nmv resources.arsc split_xhdpi_v4.arsc && \\\nxxd -i split_xhdpi_v4.arsc > split_xhdpi_v4_arsc.h && \\\n\\\nunzip bundle_xxhdpi-v4.apk resources.arsc && \\\nmv resources.arsc split_xxhdpi_v4.arsc && \\\nxxd -i split_xxhdpi_v4.arsc > split_xxhdpi_v4_arsc.h \\\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/res/layout/main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<merge>\n</merge>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/res/layout-fr-sw600dp/main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<merge>\n</merge>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/res/values/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<resources>\n    <attr name=\"attr1\" format=\"reference|integer\" />\n    <attr name=\"attr2\" format=\"reference|integer\" />\n\n    <string name=\"test1\">test1</string>\n    <string name=\"test2\">test2</string>\n\n    <integer name=\"number1\">200</integer>\n    <integer name=\"number2\">@array/integerArray1</integer>\n\n    <style name=\"Theme1\">\n        <item name=\"com.android.test.basic:attr1\">100</item>\n        <item name=\"com.android.test.basic:attr2\">@integer/number1</item>\n    </style>\n\n    <style name=\"Theme2\" parent=\"@com.android.test.basic:style/Theme1\">\n        <item name=\"com.android.test.basic:attr1\">300</item>\n    </style>\n\n    <integer-array name=\"integerArray1\">\n        <item>1</item>\n        <item>2</item>\n        <item>3</item>\n    </integer-array>\n</resources>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/res/values-de/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<resources>\n    <string name=\"test1\">versuch 1</string>\n    <string name=\"test2\">versuch 2</string>\n</resources>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/res/values-fr/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<resources>\n    <string name=\"test1\">essai 1</string>\n    <string name=\"test2\">essai 2</string>\n</resources>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/res/values-hdpi/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<resources>\n    <string name=\"density\">hdpi</string>\n</resources>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/res/values-sv/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<resources>\n    <integer name=\"number1\">400</integer>\n</resources>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/res/values-xhdpi/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<resources>\n    <string name=\"density\">xhdpi</string>\n</resources>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/res/values-xxhdpi/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<resources>\n    <string name=\"density\">xxhdpi</string>\n</resources>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/split_de_fr_arsc.h",
    "content": "unsigned char split_de_fr_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n  0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x09, 0x00, 0x76, 0x00,\n  0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x75, 0x00, 0x63, 0x00, 0x68, 0x00,\n  0x20, 0x00, 0x31, 0x00, 0x00, 0x00, 0x09, 0x00, 0x76, 0x00, 0x65, 0x00,\n  0x72, 0x00, 0x73, 0x00, 0x75, 0x00, 0x63, 0x00, 0x68, 0x00, 0x20, 0x00,\n  0x32, 0x00, 0x00, 0x00, 0x07, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00,\n  0x61, 0x00, 0x69, 0x00, 0x20, 0x00, 0x31, 0x00, 0x00, 0x00, 0x07, 0x00,\n  0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x61, 0x00, 0x69, 0x00, 0x20, 0x00,\n  0x32, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x5c, 0x03, 0x00, 0x00,\n  0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,\n  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,\n  0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,\n  0x06, 0x00, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x90, 0x00, 0x00, 0x00,\n  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,\n  0x3e, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00,\n  0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x00, 0x00, 0x06, 0x00, 0x6c, 0x00,\n  0x61, 0x00, 0x79, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x74, 0x00, 0x00, 0x00,\n  0x06, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00,\n  0x67, 0x00, 0x00, 0x00, 0x07, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00,\n  0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00,\n  0x73, 0x00, 0x74, 0x00, 0x79, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x61, 0x00, 0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00,\n  0x74, 0x00, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00,\n  0x73, 0x00, 0x74, 0x00, 0x32, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\n  0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\n  0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x1c, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00,\n  0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x64, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n  0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x02, 0x44, 0x00, 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x66, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,\n  0x03, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00,\n  0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\nunsigned int split_de_fr_arsc_len = 996;\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/split_hdpi_v4_arsc.h",
    "content": "unsigned char split_hdpi_v4_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0x08, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x68, 0x00,\n  0x64, 0x00, 0x70, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01,\n  0xd0, 0x02, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00,\n  0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00,\n  0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00,\n  0x73, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00,\n  0x69, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x20, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,\n  0x90, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,\n  0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x00, 0x00,\n  0x06, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00, 0x6f, 0x00, 0x75, 0x00,\n  0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00,\n  0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x00, 0x00, 0x07, 0x00, 0x69, 0x00,\n  0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00,\n  0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00, 0x6c, 0x00,\n  0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00, 0x72, 0x00, 0x72, 0x00,\n  0x61, 0x00, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,\n  0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6e, 0x00,\n  0x73, 0x00, 0x69, 0x00, 0x74, 0x00, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\n  0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x02, 0x44, 0x00, 0x60, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\n  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\nunsigned int split_hdpi_v4_arsc_len = 776;\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/split_xhdpi_v4_arsc.h",
    "content": "unsigned char split_xhdpi_v4_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x78, 0x00,\n  0x68, 0x00, 0x64, 0x00, 0x70, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x02, 0x20, 0x01, 0xd0, 0x02, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,\n  0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00,\n  0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00,\n  0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x62, 0x00,\n  0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n  0xb0, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x90, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,\n  0x1c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,\n  0x4c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00,\n  0x72, 0x00, 0x00, 0x00, 0x06, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00,\n  0x6f, 0x00, 0x75, 0x00, 0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x73, 0x00,\n  0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x00, 0x00,\n  0x07, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00,\n  0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x79, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00,\n  0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x64, 0x00,\n  0x65, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x69, 0x00, 0x74, 0x00, 0x79, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x60, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00,\n  0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\nunsigned int split_xhdpi_v4_arsc_len = 780;\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/basic/split_xxhdpi_v4_arsc.h",
    "content": "unsigned char split_xxhdpi_v4_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x78, 0x00,\n  0x78, 0x00, 0x68, 0x00, 0x64, 0x00, 0x70, 0x00, 0x69, 0x00, 0x00, 0x00,\n  0x00, 0x02, 0x20, 0x01, 0xd0, 0x02, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,\n  0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00,\n  0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00,\n  0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x62, 0x00,\n  0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n  0xb0, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x90, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,\n  0x1c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,\n  0x4c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00,\n  0x72, 0x00, 0x00, 0x00, 0x06, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00,\n  0x6f, 0x00, 0x75, 0x00, 0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x73, 0x00,\n  0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x00, 0x00,\n  0x07, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00,\n  0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x79, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00,\n  0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x64, 0x00,\n  0x65, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x69, 0x00, 0x74, 0x00, 0x79, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x60, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00,\n  0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\nunsigned int split_xxhdpi_v4_arsc_len = 780;\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/feature/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.android.test.basic\">\n</manifest>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/feature/build",
    "content": "#!/bin/bash\n#\n# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\naapt package -M AndroidManifest.xml -S res --feature-of ../basic/bundle.apk -F bundle.apk -f && \\\nunzip bundle.apk resources.arsc && \\\nmv resources.arsc feature.arsc && \\\nxxd -i feature.arsc > feature_arsc.h\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/feature/feature_arsc.h",
    "content": "unsigned char feature_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0x44, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x33, 0x00,\n  0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x34, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xf8, 0x02, 0x00, 0x00,\n  0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,\n  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,\n  0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,\n  0x09, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x00,\n  0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n  0x1e, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x3c, 0x00,\n  0x65, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x74, 0x00, 0x79, 0x00, 0x3e, 0x00,\n  0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00,\n  0x00, 0x00, 0x06, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00,\n  0x6e, 0x00, 0x67, 0x00, 0x00, 0x00, 0x07, 0x00, 0x69, 0x00, 0x6e, 0x00,\n  0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x58, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,\n  0x1c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00,\n  0x74, 0x00, 0x33, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00,\n  0x73, 0x00, 0x74, 0x00, 0x34, 0x00, 0x00, 0x00, 0x07, 0x00, 0x6e, 0x00,\n  0x75, 0x00, 0x6d, 0x00, 0x62, 0x00, 0x65, 0x00, 0x72, 0x00, 0x33, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00,\n  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\n  0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00,\n  0x6c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,\n  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\n  0x14, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x58, 0x00, 0x00, 0x00,\n  0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x10, 0xc8, 0x00, 0x00, 0x00\n};\nunsigned int feature_arsc_len = 836;\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/feature/res/values/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<resources>\n    <string name=\"test3\">test3</string>\n    <string name=\"test4\">test4</string>\n\n    <integer name=\"number3\">200</integer>\n</resources>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/lib/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.android.test.basic\">\n    <application>\n    </application>\n</manifest>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/lib/R.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __LIB_R_H\n#define __LIB_R_H\n\nnamespace lib {\nnamespace R {\n\nnamespace attr {\n    enum {\n        attr1       = 0x02010000, // default\n    };\n}\n\nnamespace style {\n    enum {\n        Theme        = 0x02020000,  // default\n    };\n}\n\n} // namespace R\n} // namespace lib\n\n#endif // __LIB_R_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/lib/build",
    "content": "#!/bin/bash\n#\n# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\naapt package -M AndroidManifest.xml -S res -F bundle.apk -f --shared-lib && \\\nunzip bundle.apk resources.arsc && \\\nmv resources.arsc lib.arsc && \\\nxxd -i lib.arsc > lib_arsc.h\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/lib/lib_arsc.h",
    "content": "unsigned char lib_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0xb8, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x90, 0x02, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,\n  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,\n  0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00,\n  0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00,\n  0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,\n  0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00,\n  0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00,\n  0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00,\n  0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00,\n  0x64, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x10, 0xbc, 0x02, 0x00, 0x00\n};\nunsigned int lib_arsc_len = 696;\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/lib/res/values/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<resources>\n    <attr name=\"attr1\" format=\"integer\" />\n\n    <style name=\"Theme\">\n        <item name=\"com.android.test.basic:attr1\">700</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/overlay/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.android.test.basic\">\n    <application>\n    </application>\n</manifest>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/overlay/build",
    "content": "#!/bin/bash\n#\n# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\naapt package -M AndroidManifest.xml -S res -F bundle.apk -f && \\\nunzip bundle.apk resources.arsc && \\\nmv resources.arsc overlay.arsc && \\\nxxd -i overlay.arsc > overlay_arsc.h\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/overlay/overlay_arsc.h",
    "content": "unsigned char overlay_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0x10, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x74, 0x00,\n  0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x32, 0x00, 0x2d, 0x00, 0x6f, 0x00,\n  0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xc4, 0x02, 0x00, 0x00,\n  0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,\n  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,\n  0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x54, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00,\n  0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x00, 0x00, 0x06, 0x00, 0x73, 0x00,\n  0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x61, 0x00, 0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x50, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00,\n  0x74, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x69, 0x00, 0x6e, 0x00,\n  0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00, 0x41, 0x00,\n  0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00, 0x31, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x02, 0x44, 0x00, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x02, 0x44, 0x00, 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x10, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10,\n  0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10,\n  0x0b, 0x00, 0x00, 0x00\n};\nunsigned int overlay_arsc_len = 784;\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/overlay/res/values/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<resources>\n    <string name=\"test2\">test2-overlay</string>\n    <integer-array name=\"integerArray1\">\n        <item>10</item>\n        <item>11</item>\n    </integer-array>\n</resources>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/system/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"android\">\n</manifest>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/system/R.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __ANDROID_R_H\n#define __ANDROID_R_H\n\nnamespace android {\nnamespace R {\n\nnamespace attr {\n    enum {\n        background  = 0x01010000, // default\n        foreground  = 0x01010001, // default\n    };\n}\n\nnamespace style {\n    enum {\n        Theme_One      = 0x01020000,   // default\n    };\n}\n\n} // namespace R\n} // namespace android\n\n#endif // __ANDROID_R_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/system/build",
    "content": "#!/bin/bash\n#\n# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\naapt package -x -M AndroidManifest.xml -S res -F bundle.apk -f && \\\nunzip bundle.apk resources.arsc && \\\nmv resources.arsc system.arsc && \\\nxxd -i system.arsc > system_arsc.h\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/system/res/values/themes.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<resources>\n    <public name=\"background\" type=\"attr\" id=\"0x01010000\"/>\n    <public name=\"foreground\" type=\"attr\" id=\"0x01010001\"/>\n    <public name=\"Theme.One\" type=\"style\" id=\"0x01020000\"/>\n\n    <attr name=\"background\" format=\"color|reference\"/>\n    <attr name=\"foreground\" format=\"color|reference\"/>\n    <style name=\"Theme.One\" parent=\"\">\n        <item name=\"android:background\">#ff0000</item>\n        <item name=\"android:foreground\">#000000</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/libs/androidfw/tests/data/system/system_arsc.h",
    "content": "unsigned char system_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0x18, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xf0, 0x02, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00,\n  0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00,\n  0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00,\n  0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,\n  0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x0a, 0x00, 0x62, 0x00, 0x61, 0x00, 0x63, 0x00, 0x6b, 0x00, 0x67, 0x00,\n  0x72, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x00, 0x00,\n  0x0a, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x67, 0x00,\n  0x72, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x00, 0x00,\n  0x09, 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00,\n  0x2e, 0x00, 0x4f, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40,\n  0x01, 0x02, 0x44, 0x00, 0x84, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x1c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\n  0x08, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x02, 0x44, 0x00,\n  0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x01, 0x01, 0x08, 0x00, 0x00, 0x1d, 0x00, 0x00, 0xff, 0xff,\n  0x01, 0x00, 0x01, 0x01, 0x08, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xff\n};\nunsigned int system_arsc_len = 792;\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/AaptAssets.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n\n#include \"AaptAssets.h\"\n#include \"AaptConfig.h\"\n#include \"AaptUtil.h\"\n#include \"Main.h\"\n#include \"ResourceFilter.h\"\n\n#include <utils/misc.h>\n#include <utils/SortedVector.h>\n\n#include <ctype.h>\n#include <dirent.h>\n#include <errno.h>\n\nstatic const char* kAssetDir = \"assets\";\nstatic const char* kResourceDir = \"res\";\nstatic const char* kValuesDir = \"values\";\nstatic const char* kMipmapDir = \"mipmap\";\nstatic const char* kInvalidChars = \"/\\\\:\";\nstatic const size_t kMaxAssetFileName = 100;\n\nstatic const String8 kResString(kResourceDir);\n\n/*\n * Names of asset files must meet the following criteria:\n *\n *  - the filename length must be less than kMaxAssetFileName bytes long\n *    (and can't be empty)\n *  - all characters must be 7-bit printable ASCII\n *  - none of { '/' '\\\\' ':' }\n *\n * Pass in just the filename, not the full path.\n */\nstatic bool validateFileName(const char* fileName)\n{\n    const char* cp = fileName;\n    size_t len = 0;\n\n    while (*cp != '\\0') {\n        if ((*cp & 0x80) != 0)\n            return false;           // reject high ASCII\n        if (*cp < 0x20 || *cp >= 0x7f)\n            return false;           // reject control chars and 0x7f\n        if (strchr(kInvalidChars, *cp) != NULL)\n            return false;           // reject path sep chars\n        cp++;\n        len++;\n    }\n\n    if (len < 1 || len > kMaxAssetFileName)\n        return false;               // reject empty or too long\n\n    return true;\n}\n\n// The default to use if no other ignore pattern is defined.\nconst char * const gDefaultIgnoreAssets =\n    \"!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~\";\n// The ignore pattern that can be passed via --ignore-assets in Main.cpp\nconst char * gUserIgnoreAssets = NULL;\n\nstatic bool isHidden(const char *root, const char *path)\n{\n    // Patterns syntax:\n    // - Delimiter is :\n    // - Entry can start with the flag ! to avoid printing a warning\n    //   about the file being ignored.\n    // - Entry can have the flag \"<dir>\" to match only directories\n    //   or <file> to match only files. Default is to match both.\n    // - Entry can be a simplified glob \"<prefix>*\" or \"*<suffix>\"\n    //   where prefix/suffix must have at least 1 character (so that\n    //   we don't match a '*' catch-all pattern.)\n    // - The special filenames \".\" and \"..\" are always ignored.\n    // - Otherwise the full string is matched.\n    // - match is not case-sensitive.\n\n    if (strcmp(path, \".\") == 0 || strcmp(path, \"..\") == 0) {\n        return true;\n    }\n\n    const char *delim = \":\";\n    const char *p = gUserIgnoreAssets;\n    if (!p || !p[0]) {\n        p = getenv(\"ANDROID_AAPT_IGNORE\");\n    }\n    if (!p || !p[0]) {\n        p = gDefaultIgnoreAssets;\n    }\n    char *patterns = strdup(p);\n\n    bool ignore = false;\n    bool chatty = true;\n    char *matchedPattern = NULL;\n\n    String8 fullPath(root);\n    fullPath.appendPath(path);\n    FileType type = getFileType(fullPath);\n\n    int plen = strlen(path);\n\n    // Note: we don't have strtok_r under mingw.\n    for(char *token = strtok(patterns, delim);\n            !ignore && token != NULL;\n            token = strtok(NULL, delim)) {\n        chatty = token[0] != '!';\n        if (!chatty) token++; // skip !\n        if (strncasecmp(token, \"<dir>\" , 5) == 0) {\n            if (type != kFileTypeDirectory) continue;\n            token += 5;\n        }\n        if (strncasecmp(token, \"<file>\", 6) == 0) {\n            if (type != kFileTypeRegular) continue;\n            token += 6;\n        }\n\n        matchedPattern = token;\n        int n = strlen(token);\n\n        if (token[0] == '*') {\n            // Match *suffix\n            token++;\n            n--;\n            if (n <= plen) {\n                ignore = strncasecmp(token, path + plen - n, n) == 0;\n            }\n        } else if (n > 1 && token[n - 1] == '*') {\n            // Match prefix*\n            ignore = strncasecmp(token, path, n - 1) == 0;\n        } else {\n            ignore = strcasecmp(token, path) == 0;\n        }\n    }\n\n    if (ignore && chatty) {\n        fprintf(stderr, \"    (skipping %s '%s' due to ANDROID_AAPT_IGNORE pattern '%s')\\n\",\n                type == kFileTypeDirectory ? \"dir\" : \"file\",\n                path,\n                matchedPattern ? matchedPattern : \"\");\n    }\n\n    free(patterns);\n    return ignore;\n}\n\n// =========================================================================\n// =========================================================================\n// =========================================================================\n\n/* static */\ninline bool isAlpha(const String8& string) {\n     const size_t length = string.length();\n     for (size_t i = 0; i < length; ++i) {\n          if (!isalpha(string[i])) {\n              return false;\n          }\n     }\n\n     return true;\n}\n\n/* static */\ninline bool isNumber(const String8& string) {\n     const size_t length = string.length();\n     for (size_t i = 0; i < length; ++i) {\n          if (!isdigit(string[i])) {\n              return false;\n          }\n     }\n\n     return true;\n}\n\nvoid AaptLocaleValue::setLanguage(const char* languageChars) {\n     size_t i = 0;\n     while ((*languageChars) != '\\0' && i < sizeof(language)/sizeof(language[0])) {\n          language[i++] = tolower(*languageChars);\n          languageChars++;\n     }\n}\n\nvoid AaptLocaleValue::setRegion(const char* regionChars) {\n    size_t i = 0;\n    while ((*regionChars) != '\\0' && i < sizeof(region)/sizeof(region[0])) {\n         region[i++] = toupper(*regionChars);\n         regionChars++;\n    }\n}\n\nvoid AaptLocaleValue::setScript(const char* scriptChars) {\n    size_t i = 0;\n    while ((*scriptChars) != '\\0' && i < sizeof(script)/sizeof(script[0])) {\n         if (i == 0) {\n             script[i++] = toupper(*scriptChars);\n         } else {\n             script[i++] = tolower(*scriptChars);\n         }\n         scriptChars++;\n    }\n}\n\nvoid AaptLocaleValue::setVariant(const char* variantChars) {\n     size_t i = 0;\n     while ((*variantChars) != '\\0' && i < sizeof(variant)/sizeof(variant[0])) {\n          variant[i++] = *variantChars;\n          variantChars++;\n     }\n}\n\nbool AaptLocaleValue::initFromFilterString(const String8& str) {\n     // A locale (as specified in the filter) is an underscore separated name such\n     // as \"en_US\", \"en_Latn_US\", or \"en_US_POSIX\".\n     Vector<String8> parts = AaptUtil::splitAndLowerCase(str, '_');\n\n     const int numTags = parts.size();\n     bool valid = false;\n     if (numTags >= 1) {\n         const String8& lang = parts[0];\n         if (isAlpha(lang) && (lang.length() == 2 || lang.length() == 3)) {\n             setLanguage(lang.string());\n             valid = true;\n         }\n     }\n\n     if (!valid || numTags == 1) {\n         return valid;\n     }\n\n     // At this point, valid == true && numTags > 1.\n     const String8& part2 = parts[1];\n     if ((part2.length() == 2 && isAlpha(part2)) ||\n         (part2.length() == 3 && isNumber(part2))) {\n         setRegion(part2.string());\n     } else if (part2.length() == 4 && isAlpha(part2)) {\n         setScript(part2.string());\n     } else if (part2.length() >= 4 && part2.length() <= 8) {\n         setVariant(part2.string());\n     } else {\n         valid = false;\n     }\n\n     if (!valid || numTags == 2) {\n         return valid;\n     }\n\n     // At this point, valid == true && numTags > 1.\n     const String8& part3 = parts[2];\n     if (((part3.length() == 2 && isAlpha(part3)) ||\n         (part3.length() == 3 && isNumber(part3))) && script[0]) {\n         setRegion(part3.string());\n     } else if (part3.length() >= 4 && part3.length() <= 8) {\n         setVariant(part3.string());\n     } else {\n         valid = false;\n     }\n\n     if (!valid || numTags == 3) {\n         return valid;\n     }\n\n     const String8& part4 = parts[3];\n     if (part4.length() >= 4 && part4.length() <= 8) {\n         setVariant(part4.string());\n     } else {\n         valid = false;\n     }\n\n     if (!valid || numTags > 4) {\n         return false;\n     }\n\n     return true;\n}\n\nint AaptLocaleValue::initFromDirName(const Vector<String8>& parts, const int startIndex) {\n    const int size = parts.size();\n    int currentIndex = startIndex;\n\n    String8 part = parts[currentIndex];\n    if (part[0] == 'b' && part[1] == '+') {\n        // This is a \"modified\" BCP 47 language tag. Same semantics as BCP 47 tags,\n        // except that the separator is \"+\" and not \"-\".\n        Vector<String8> subtags = AaptUtil::splitAndLowerCase(part, '+');\n        subtags.removeItemsAt(0);\n        if (subtags.size() == 1) {\n            setLanguage(subtags[0]);\n        } else if (subtags.size() == 2) {\n            setLanguage(subtags[0]);\n\n            // The second tag can either be a region, a variant or a script.\n            switch (subtags[1].size()) {\n                case 2:\n                case 3:\n                    setRegion(subtags[1]);\n                    break;\n                case 4:\n                    if (isAlpha(subtags[1])) {\n                        setScript(subtags[1]);\n                        break;\n                    }\n                    // This is not alphabetical, so we fall through to variant\n                case 5:\n                case 6:\n                case 7:\n                case 8:\n                    setVariant(subtags[1]);\n                    break;\n                default:\n                    fprintf(stderr, \"ERROR: Invalid BCP 47 tag in directory name %s\\n\",\n                            part.string());\n                    return -1;\n            }\n        } else if (subtags.size() == 3) {\n            // The language is always the first subtag.\n            setLanguage(subtags[0]);\n\n            // The second subtag can either be a script or a region code.\n            // If its size is 4, it's a script code, else it's a region code.\n            bool hasRegion = false;\n            if (subtags[1].size() == 4) {\n                setScript(subtags[1]);\n            } else if (subtags[1].size() == 2 || subtags[1].size() == 3) {\n                setRegion(subtags[1]);\n                hasRegion = true;\n            } else {\n                fprintf(stderr, \"ERROR: Invalid BCP 47 tag in directory name %s\\n\", part.string());\n                return -1;\n            }\n\n            // The third tag can either be a region code (if the second tag was\n            // a script), else a variant code.\n            if (subtags[2].size() >= 4) {\n                setVariant(subtags[2]);\n            } else {\n                setRegion(subtags[2]);\n            }\n        } else if (subtags.size() == 4) {\n            setLanguage(subtags[0]);\n            setScript(subtags[1]);\n            setRegion(subtags[2]);\n            setVariant(subtags[3]);\n        } else {\n            fprintf(stderr, \"ERROR: Invalid BCP 47 tag in directory name: %s\\n\", part.string());\n            return -1;\n        }\n\n        return ++currentIndex;\n    } else {\n        if ((part.length() == 2 || part.length() == 3)\n               && isAlpha(part) && strcmp(\"car\", part.string())) {\n            setLanguage(part);\n            if (++currentIndex == size) {\n                return size;\n            }\n        } else {\n            return currentIndex;\n        }\n\n        part = parts[currentIndex];\n        if (part.string()[0] == 'r' && part.length() == 3) {\n            setRegion(part.string() + 1);\n            if (++currentIndex == size) {\n                return size;\n            }\n        }\n    }\n\n    return currentIndex;\n}\n\nvoid AaptLocaleValue::initFromResTable(const ResTable_config& config) {\n    config.unpackLanguage(language);\n    config.unpackRegion(region);\n    if (config.localeScript[0] && !config.localeScriptWasComputed) {\n        memcpy(script, config.localeScript, sizeof(config.localeScript));\n    }\n\n    if (config.localeVariant[0]) {\n        memcpy(variant, config.localeVariant, sizeof(config.localeVariant));\n    }\n}\n\nvoid AaptLocaleValue::writeTo(ResTable_config* out) const {\n    out->packLanguage(language);\n    out->packRegion(region);\n\n    if (script[0]) {\n        memcpy(out->localeScript, script, sizeof(out->localeScript));\n    }\n\n    if (variant[0]) {\n        memcpy(out->localeVariant, variant, sizeof(out->localeVariant));\n    }\n}\n\nbool\nAaptGroupEntry::initFromDirName(const char* dir, String8* resType)\n{\n    const char* q = strchr(dir, '-');\n    size_t typeLen;\n    if (q != NULL) {\n        typeLen = q - dir;\n    } else {\n        typeLen = strlen(dir);\n    }\n\n    String8 type(dir, typeLen);\n    if (!isValidResourceType(type)) {\n        return false;\n    }\n\n    if (q != NULL) {\n        if (!AaptConfig::parse(String8(q + 1), &mParams)) {\n            return false;\n        }\n    }\n\n    *resType = type;\n    return true;\n}\n\nString8\nAaptGroupEntry::toDirName(const String8& resType) const\n{\n    String8 s = resType;\n    String8 params = mParams.toString();\n    if (params.length() > 0) {\n        if (s.length() > 0) {\n            s += \"-\";\n        }\n        s += params;\n    }\n    return s;\n}\n\n\n// =========================================================================\n// =========================================================================\n// =========================================================================\n\nvoid* AaptFile::editData(size_t size)\n{\n    if (size <= mBufferSize) {\n        mDataSize = size;\n        return mData;\n    }\n    size_t allocSize = (size*3)/2;\n    void* buf = realloc(mData, allocSize);\n    if (buf == NULL) {\n        return NULL;\n    }\n    mData = buf;\n    mDataSize = size;\n    mBufferSize = allocSize;\n    return buf;\n}\n\nvoid* AaptFile::editDataInRange(size_t offset, size_t size)\n{\n    return (void*)(((uint8_t*) editData(offset + size)) + offset);\n}\n\nvoid* AaptFile::editData(size_t* outSize)\n{\n    if (outSize) {\n        *outSize = mDataSize;\n    }\n    return mData;\n}\n\nvoid* AaptFile::padData(size_t wordSize)\n{\n    const size_t extra = mDataSize%wordSize;\n    if (extra == 0) {\n        return mData;\n    }\n\n    size_t initial = mDataSize;\n    void* data = editData(initial+(wordSize-extra));\n    if (data != NULL) {\n        memset(((uint8_t*)data) + initial, 0, wordSize-extra);\n    }\n    return data;\n}\n\nstatus_t AaptFile::writeData(const void* data, size_t size)\n{\n    size_t end = mDataSize;\n    size_t total = size + end;\n    void* buf = editData(total);\n    if (buf == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    memcpy(((char*)buf)+end, data, size);\n    return NO_ERROR;\n}\n\nvoid AaptFile::clearData()\n{\n    if (mData != NULL) free(mData);\n    mData = NULL;\n    mDataSize = 0;\n    mBufferSize = 0;\n}\n\nString8 AaptFile::getPrintableSource() const\n{\n    if (hasData()) {\n        String8 name(mGroupEntry.toDirName(String8()));\n        name.appendPath(mPath);\n        name.append(\" #generated\");\n        return name;\n    }\n    return mSourceFile;\n}\n\n// =========================================================================\n// =========================================================================\n// =========================================================================\n\nstatus_t AaptGroup::addFile(const sp<AaptFile>& file, const bool overwriteDuplicate)\n{\n    ssize_t index = mFiles.indexOfKey(file->getGroupEntry());\n    if (index >= 0 && overwriteDuplicate) {\n        fprintf(stderr, \"warning: overwriting '%s' with '%s'\\n\",\n                mFiles[index]->getSourceFile().string(),\n                file->getSourceFile().string());\n        removeFile(index);\n        index = -1;\n    }\n\n    if (index < 0) {\n        file->mPath = mPath;\n        mFiles.add(file->getGroupEntry(), file);\n        return NO_ERROR;\n    }\n\n    // Check if the version is automatically applied. This is a common source of\n    // error.\n    ConfigDescription withoutVersion = file->getGroupEntry().toParams();\n    withoutVersion.version = 0;\n    AaptConfig::applyVersionForCompatibility(&withoutVersion);\n\n    const sp<AaptFile>& originalFile = mFiles.valueAt(index);\n    SourcePos(file->getSourceFile(), -1)\n            .error(\"Duplicate file.\\n%s: Original is here. %s\",\n                   originalFile->getPrintableSource().string(),\n                   (withoutVersion.version != 0) ? \"The version qualifier may be implied.\" : \"\");\n    return UNKNOWN_ERROR;\n}\n\nvoid AaptGroup::removeFile(size_t index)\n{\n\tmFiles.removeItemsAt(index);\n}\n\nvoid AaptGroup::print(const String8& prefix) const\n{\n    printf(\"%s%s\\n\", prefix.string(), getPath().string());\n    const size_t N=mFiles.size();\n    size_t i;\n    for (i=0; i<N; i++) {\n        sp<AaptFile> file = mFiles.valueAt(i);\n        const AaptGroupEntry& e = file->getGroupEntry();\n        if (file->hasData()) {\n            printf(\"%s  Gen: (%s) %d bytes\\n\", prefix.string(), e.toDirName(String8()).string(),\n                    (int)file->getSize());\n        } else {\n            printf(\"%s  Src: (%s) %s\\n\", prefix.string(), e.toDirName(String8()).string(),\n                    file->getPrintableSource().string());\n        }\n        //printf(\"%s  File Group Entry: %s\\n\", prefix.string(),\n        //        file->getGroupEntry().toDirName(String8()).string());\n    }\n}\n\nString8 AaptGroup::getPrintableSource() const\n{\n    if (mFiles.size() > 0) {\n        // Arbitrarily pull the first source file out of the list.\n        return mFiles.valueAt(0)->getPrintableSource();\n    }\n\n    // Should never hit this case, but to be safe...\n    return getPath();\n\n}\n\n// =========================================================================\n// =========================================================================\n// =========================================================================\n\nstatus_t AaptDir::addFile(const String8& name, const sp<AaptGroup>& file)\n{\n    if (mFiles.indexOfKey(name) >= 0) {\n        return ALREADY_EXISTS;\n    }\n    mFiles.add(name, file);\n    return NO_ERROR;\n}\n\nstatus_t AaptDir::addDir(const String8& name, const sp<AaptDir>& dir)\n{\n    if (mDirs.indexOfKey(name) >= 0) {\n        return ALREADY_EXISTS;\n    }\n    mDirs.add(name, dir);\n    return NO_ERROR;\n}\n\nsp<AaptDir> AaptDir::makeDir(const String8& path)\n{\n    String8 name;\n    String8 remain = path;\n\n    sp<AaptDir> subdir = this;\n    while (name = remain.walkPath(&remain), remain != \"\") {\n        subdir = subdir->makeDir(name);\n    }\n\n    ssize_t i = subdir->mDirs.indexOfKey(name);\n    if (i >= 0) {\n        return subdir->mDirs.valueAt(i);\n    }\n    sp<AaptDir> dir = new AaptDir(name, subdir->mPath.appendPathCopy(name));\n    subdir->mDirs.add(name, dir);\n    return dir;\n}\n\nvoid AaptDir::removeFile(const String8& name)\n{\n    mFiles.removeItem(name);\n}\n\nvoid AaptDir::removeDir(const String8& name)\n{\n    mDirs.removeItem(name);\n}\n\nstatus_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file,\n        const bool overwrite)\n{\n    sp<AaptGroup> group;\n    if (mFiles.indexOfKey(leafName) >= 0) {\n        group = mFiles.valueFor(leafName);\n    } else {\n        group = new AaptGroup(leafName, mPath.appendPathCopy(leafName));\n        mFiles.add(leafName, group);\n    }\n\n    return group->addFile(file, overwrite);\n}\n\nssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir,\n                            const AaptGroupEntry& kind, const String8& resType,\n                            sp<FilePathStore>& fullResPaths, const bool overwrite)\n{\n    Vector<String8> fileNames;\n    {\n        DIR* dir = NULL;\n\n        dir = opendir(srcDir.string());\n        if (dir == NULL) {\n            fprintf(stderr, \"ERROR: opendir(%s): %s\\n\", srcDir.string(), strerror(errno));\n            return UNKNOWN_ERROR;\n        }\n\n        /*\n         * Slurp the filenames out of the directory.\n         */\n        while (1) {\n            struct dirent* entry;\n\n            entry = readdir(dir);\n            if (entry == NULL)\n                break;\n\n            if (isHidden(srcDir.string(), entry->d_name))\n                continue;\n\n            String8 name(entry->d_name);\n            fileNames.add(name);\n            // Add fully qualified path for dependency purposes\n            // if we're collecting them\n            if (fullResPaths != NULL) {\n                fullResPaths->add(srcDir.appendPathCopy(name));\n            }\n        }\n        closedir(dir);\n    }\n\n    ssize_t count = 0;\n\n    /*\n     * Stash away the files and recursively descend into subdirectories.\n     */\n    const size_t N = fileNames.size();\n    size_t i;\n    for (i = 0; i < N; i++) {\n        String8 pathName(srcDir);\n        FileType type;\n\n        pathName.appendPath(fileNames[i].string());\n        type = getFileType(pathName.string());\n        if (type == kFileTypeDirectory) {\n            sp<AaptDir> subdir;\n            bool notAdded = false;\n            if (mDirs.indexOfKey(fileNames[i]) >= 0) {\n                subdir = mDirs.valueFor(fileNames[i]);\n            } else {\n                subdir = new AaptDir(fileNames[i], mPath.appendPathCopy(fileNames[i]));\n                notAdded = true;\n            }\n            ssize_t res = subdir->slurpFullTree(bundle, pathName, kind,\n                                                resType, fullResPaths, overwrite);\n            if (res < NO_ERROR) {\n                return res;\n            }\n            if (res > 0 && notAdded) {\n                mDirs.add(fileNames[i], subdir);\n            }\n            count += res;\n        } else if (type == kFileTypeRegular) {\n            sp<AaptFile> file = new AaptFile(pathName, kind, resType);\n            status_t err = addLeafFile(fileNames[i], file, overwrite);\n            if (err != NO_ERROR) {\n                return err;\n            }\n\n            count++;\n\n        } else {\n            if (bundle->getVerbose())\n                printf(\"   (ignoring non-file/dir '%s')\\n\", pathName.string());\n        }\n    }\n\n    return count;\n}\n\nstatus_t AaptDir::validate() const\n{\n    const size_t NF = mFiles.size();\n    const size_t ND = mDirs.size();\n    size_t i;\n    for (i = 0; i < NF; i++) {\n        if (!validateFileName(mFiles.valueAt(i)->getLeaf().string())) {\n            SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error(\n                    \"Invalid filename.  Unable to add.\");\n            return UNKNOWN_ERROR;\n        }\n\n        size_t j;\n        for (j = i+1; j < NF; j++) {\n            if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(),\n                           mFiles.valueAt(j)->getLeaf().string()) == 0) {\n                SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error(\n                        \"File is case-insensitive equivalent to: %s\",\n                        mFiles.valueAt(j)->getPrintableSource().string());\n                return UNKNOWN_ERROR;\n            }\n\n            // TODO: if \".gz\", check for non-.gz; if non-, check for \".gz\"\n            // (this is mostly caught by the \"marked\" stuff, below)\n        }\n\n        for (j = 0; j < ND; j++) {\n            if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(),\n                           mDirs.valueAt(j)->getLeaf().string()) == 0) {\n                SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error(\n                        \"File conflicts with dir from: %s\",\n                        mDirs.valueAt(j)->getPrintableSource().string());\n                return UNKNOWN_ERROR;\n            }\n        }\n    }\n\n    for (i = 0; i < ND; i++) {\n        if (!validateFileName(mDirs.valueAt(i)->getLeaf().string())) {\n            SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error(\n                    \"Invalid directory name, unable to add.\");\n            return UNKNOWN_ERROR;\n        }\n\n        size_t j;\n        for (j = i+1; j < ND; j++) {\n            if (strcasecmp(mDirs.valueAt(i)->getLeaf().string(),\n                           mDirs.valueAt(j)->getLeaf().string()) == 0) {\n                SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error(\n                        \"Directory is case-insensitive equivalent to: %s\",\n                        mDirs.valueAt(j)->getPrintableSource().string());\n                return UNKNOWN_ERROR;\n            }\n        }\n\n        status_t err = mDirs.valueAt(i)->validate();\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    return NO_ERROR;\n}\n\nvoid AaptDir::print(const String8& prefix) const\n{\n    const size_t ND=getDirs().size();\n    size_t i;\n    for (i=0; i<ND; i++) {\n        getDirs().valueAt(i)->print(prefix);\n    }\n\n    const size_t NF=getFiles().size();\n    for (i=0; i<NF; i++) {\n        getFiles().valueAt(i)->print(prefix);\n    }\n}\n\nString8 AaptDir::getPrintableSource() const\n{\n    if (mFiles.size() > 0) {\n        // Arbitrarily pull the first file out of the list as the source dir.\n        return mFiles.valueAt(0)->getPrintableSource().getPathDir();\n    }\n    if (mDirs.size() > 0) {\n        // Or arbitrarily pull the first dir out of the list as the source dir.\n        return mDirs.valueAt(0)->getPrintableSource().getPathDir();\n    }\n\n    // Should never hit this case, but to be safe...\n    return mPath;\n\n}\n\n// =========================================================================\n// =========================================================================\n// =========================================================================\n\nstatus_t AaptSymbols::applyJavaSymbols(const sp<AaptSymbols>& javaSymbols)\n{\n    status_t err = NO_ERROR;\n    size_t N = javaSymbols->mSymbols.size();\n    for (size_t i=0; i<N; i++) {\n        const String8& name = javaSymbols->mSymbols.keyAt(i);\n        const AaptSymbolEntry& entry = javaSymbols->mSymbols.valueAt(i);\n        ssize_t pos = mSymbols.indexOfKey(name);\n        if (pos < 0) {\n            entry.sourcePos.error(\"Symbol '%s' declared with <java-symbol> not defined\\n\", name.string());\n            err = UNKNOWN_ERROR;\n            continue;\n        }\n        //printf(\"**** setting symbol #%d/%d %s to isJavaSymbol=%d\\n\",\n        //        i, N, name.string(), entry.isJavaSymbol ? 1 : 0);\n        mSymbols.editValueAt(pos).isJavaSymbol = entry.isJavaSymbol;\n    }\n\n    N = javaSymbols->mNestedSymbols.size();\n    for (size_t i=0; i<N; i++) {\n        const String8& name = javaSymbols->mNestedSymbols.keyAt(i);\n        const sp<AaptSymbols>& symbols = javaSymbols->mNestedSymbols.valueAt(i);\n        ssize_t pos = mNestedSymbols.indexOfKey(name);\n        if (pos < 0) {\n            SourcePos pos;\n            pos.error(\"Java symbol dir %s not defined\\n\", name.string());\n            err = UNKNOWN_ERROR;\n            continue;\n        }\n        //printf(\"**** applying java symbols in dir %s\\n\", name.string());\n        status_t myerr = mNestedSymbols.valueAt(pos)->applyJavaSymbols(symbols);\n        if (myerr != NO_ERROR) {\n            err = myerr;\n        }\n    }\n\n    return err;\n}\n\n// =========================================================================\n// =========================================================================\n// =========================================================================\n\nAaptAssets::AaptAssets()\n    : AaptDir(String8(), String8()),\n      mHavePrivateSymbols(false),\n      mChanged(false), mHaveIncludedAssets(false),\n      mRes(NULL) {}\n\nconst SortedVector<AaptGroupEntry>& AaptAssets::getGroupEntries() const {\n    if (mChanged) {\n    }\n    return mGroupEntries;\n}\n\nstatus_t AaptAssets::addFile(const String8& name, const sp<AaptGroup>& file)\n{\n    mChanged = true;\n    return AaptDir::addFile(name, file);\n}\n\nsp<AaptFile> AaptAssets::addFile(\n        const String8& filePath, const AaptGroupEntry& entry,\n        const String8& srcDir, sp<AaptGroup>* outGroup,\n        const String8& resType)\n{\n    sp<AaptDir> dir = this;\n    sp<AaptGroup> group;\n    sp<AaptFile> file;\n    String8 root, remain(filePath), partialPath;\n    while (remain.length() > 0) {\n        root = remain.walkPath(&remain);\n        partialPath.appendPath(root);\n\n        const String8 rootStr(root);\n\n        if (remain.length() == 0) {\n            ssize_t i = dir->getFiles().indexOfKey(rootStr);\n            if (i >= 0) {\n                group = dir->getFiles().valueAt(i);\n            } else {\n                group = new AaptGroup(rootStr, filePath);\n                status_t res = dir->addFile(rootStr, group);\n                if (res != NO_ERROR) {\n                    return NULL;\n                }\n            }\n            file = new AaptFile(srcDir.appendPathCopy(filePath), entry, resType);\n            status_t res = group->addFile(file);\n            if (res != NO_ERROR) {\n                return NULL;\n            }\n            break;\n\n        } else {\n            ssize_t i = dir->getDirs().indexOfKey(rootStr);\n            if (i >= 0) {\n                dir = dir->getDirs().valueAt(i);\n            } else {\n                sp<AaptDir> subdir = new AaptDir(rootStr, partialPath);\n                status_t res = dir->addDir(rootStr, subdir);\n                if (res != NO_ERROR) {\n                    return NULL;\n                }\n                dir = subdir;\n            }\n        }\n    }\n\n    mGroupEntries.add(entry);\n    if (outGroup) *outGroup = group;\n    return file;\n}\n\nvoid AaptAssets::addResource(const String8& leafName, const String8& path,\n                const sp<AaptFile>& file, const String8& resType)\n{\n    sp<AaptDir> res = AaptDir::makeDir(kResString);\n    String8 dirname = file->getGroupEntry().toDirName(resType);\n    sp<AaptDir> subdir = res->makeDir(dirname);\n    sp<AaptGroup> grr = new AaptGroup(leafName, path);\n    grr->addFile(file);\n\n    subdir->addFile(leafName, grr);\n}\n\n\nssize_t AaptAssets::slurpFromArgs(Bundle* bundle)\n{\n    int count;\n    int totalCount = 0;\n    FileType type;\n    const Vector<const char *>& resDirs = bundle->getResourceSourceDirs();\n    const size_t dirCount =resDirs.size();\n    sp<AaptAssets> current = this;\n\n    const int N = bundle->getFileSpecCount();\n\n    /*\n     * If a package manifest was specified, include that first.\n     */\n    if (bundle->getAndroidManifestFile() != NULL) {\n        // place at root of zip.\n        String8 srcFile(bundle->getAndroidManifestFile());\n        addFile(srcFile.getPathLeaf(), AaptGroupEntry(), srcFile.getPathDir(),\n                NULL, String8());\n        totalCount++;\n    }\n\n    /*\n     * If a directory of custom assets was supplied, slurp 'em up.\n     */\n    const Vector<const char*>& assetDirs = bundle->getAssetSourceDirs();\n    const int AN = assetDirs.size();\n    for (int i = 0; i < AN; i++) {\n        FileType type = getFileType(assetDirs[i]);\n        if (type == kFileTypeNonexistent) {\n            fprintf(stderr, \"ERROR: asset directory '%s' does not exist\\n\", assetDirs[i]);\n            return UNKNOWN_ERROR;\n        }\n        if (type != kFileTypeDirectory) {\n            fprintf(stderr, \"ERROR: '%s' is not a directory\\n\", assetDirs[i]);\n            return UNKNOWN_ERROR;\n        }\n\n        String8 assetRoot(assetDirs[i]);\n        sp<AaptDir> assetAaptDir = makeDir(String8(kAssetDir));\n        AaptGroupEntry group;\n        count = assetAaptDir->slurpFullTree(bundle, assetRoot, group,\n                                            String8(), mFullAssetPaths, true);\n        if (count < 0) {\n            totalCount = count;\n            goto bail;\n        }\n        if (count > 0) {\n            mGroupEntries.add(group);\n        }\n        totalCount += count;\n\n        if (bundle->getVerbose()) {\n            printf(\"Found %d custom asset file%s in %s\\n\",\n                   count, (count==1) ? \"\" : \"s\", assetDirs[i]);\n        }\n    }\n\n    /*\n     * If a directory of resource-specific assets was supplied, slurp 'em up.\n     */\n    for (size_t i=0; i<dirCount; i++) {\n        const char *res = resDirs[i];\n        if (res) {\n            type = getFileType(res);\n            if (type == kFileTypeNonexistent) {\n                fprintf(stderr, \"ERROR: resource directory '%s' does not exist\\n\", res);\n                return UNKNOWN_ERROR;\n            }\n            if (type == kFileTypeDirectory) {\n                if (i>0) {\n                    sp<AaptAssets> nextOverlay = new AaptAssets();\n                    current->setOverlay(nextOverlay);\n                    current = nextOverlay;\n                    current->setFullResPaths(mFullResPaths);\n                }\n                count = current->slurpResourceTree(bundle, String8(res));\n                if (i > 0 && count > 0) {\n                  count = current->filter(bundle);\n                }\n\n                if (count < 0) {\n                    totalCount = count;\n                    goto bail;\n                }\n                totalCount += count;\n            }\n            else {\n                fprintf(stderr, \"ERROR: '%s' is not a directory\\n\", res);\n                return UNKNOWN_ERROR;\n            }\n        }\n        \n    }\n    /*\n     * Now do any additional raw files.\n     */\n    for (int arg=0; arg<N; arg++) {\n        const char* assetDir = bundle->getFileSpecEntry(arg);\n\n        FileType type = getFileType(assetDir);\n        if (type == kFileTypeNonexistent) {\n            fprintf(stderr, \"ERROR: input directory '%s' does not exist\\n\", assetDir);\n            return UNKNOWN_ERROR;\n        }\n        if (type != kFileTypeDirectory) {\n            fprintf(stderr, \"ERROR: '%s' is not a directory\\n\", assetDir);\n            return UNKNOWN_ERROR;\n        }\n\n        String8 assetRoot(assetDir);\n\n        if (bundle->getVerbose())\n            printf(\"Processing raw dir '%s'\\n\", (const char*) assetDir);\n\n        /*\n         * Do a recursive traversal of subdir tree.  We don't make any\n         * guarantees about ordering, so we're okay with an inorder search\n         * using whatever order the OS happens to hand back to us.\n         */\n        count = slurpFullTree(bundle, assetRoot, AaptGroupEntry(), String8(), mFullAssetPaths);\n        if (count < 0) {\n            /* failure; report error and remove archive */\n            totalCount = count;\n            goto bail;\n        }\n        totalCount += count;\n\n        if (bundle->getVerbose())\n            printf(\"Found %d asset file%s in %s\\n\",\n                   count, (count==1) ? \"\" : \"s\", assetDir);\n    }\n\n    count = validate();\n    if (count != NO_ERROR) {\n        totalCount = count;\n        goto bail;\n    }\n\n    count = filter(bundle);\n    if (count != NO_ERROR) {\n        totalCount = count;\n        goto bail;\n    }\n\nbail:\n    return totalCount;\n}\n\nssize_t AaptAssets::slurpFullTree(Bundle* bundle, const String8& srcDir,\n                                    const AaptGroupEntry& kind,\n                                    const String8& resType,\n                                    sp<FilePathStore>& fullResPaths,\n                                    const bool overwrite)\n{\n    ssize_t res = AaptDir::slurpFullTree(bundle, srcDir, kind, resType, fullResPaths, overwrite);\n    if (res > 0) {\n        mGroupEntries.add(kind);\n    }\n\n    return res;\n}\n\nssize_t AaptAssets::slurpResourceTree(Bundle* bundle, const String8& srcDir)\n{\n    ssize_t err = 0;\n\n    DIR* dir = opendir(srcDir.string());\n    if (dir == NULL) {\n        fprintf(stderr, \"ERROR: opendir(%s): %s\\n\", srcDir.string(), strerror(errno));\n        return UNKNOWN_ERROR;\n    }\n\n    status_t count = 0;\n\n    /*\n     * Run through the directory, looking for dirs that match the\n     * expected pattern.\n     */\n    while (1) {\n        struct dirent* entry = readdir(dir);\n        if (entry == NULL) {\n            break;\n        }\n\n        if (isHidden(srcDir.string(), entry->d_name)) {\n            continue;\n        }\n\n        String8 subdirName(srcDir);\n        subdirName.appendPath(entry->d_name);\n\n        AaptGroupEntry group;\n        String8 resType;\n        bool b = group.initFromDirName(entry->d_name, &resType);\n        if (!b) {\n            fprintf(stderr, \"invalid resource directory name: %s %s\\n\", srcDir.string(),\n                    entry->d_name);\n            err = -1;\n            continue;\n        }\n\n        if (bundle->getMaxResVersion() != NULL && group.getVersionString().length() != 0) {\n            int maxResInt = atoi(bundle->getMaxResVersion());\n            const char *verString = group.getVersionString().string();\n            int dirVersionInt = atoi(verString + 1); // skip 'v' in version name\n            if (dirVersionInt > maxResInt) {\n              fprintf(stderr, \"max res %d, skipping %s\\n\", maxResInt, entry->d_name);\n              continue;\n            }\n        }\n\n        FileType type = getFileType(subdirName.string());\n\n        if (type == kFileTypeDirectory) {\n            sp<AaptDir> dir = makeDir(resType);\n            ssize_t res = dir->slurpFullTree(bundle, subdirName, group,\n                                                resType, mFullResPaths);\n            if (res < 0) {\n                count = res;\n                goto bail;\n            }\n            if (res > 0) {\n                mGroupEntries.add(group);\n                count += res;\n            }\n\n            // Only add this directory if we don't already have a resource dir\n            // for the current type.  This ensures that we only add the dir once\n            // for all configs.\n            sp<AaptDir> rdir = resDir(resType);\n            if (rdir == NULL) {\n                mResDirs.add(dir);\n            }\n        } else {\n            if (bundle->getVerbose()) {\n                fprintf(stderr, \"   (ignoring file '%s')\\n\", subdirName.string());\n            }\n        }\n    }\n\nbail:\n    closedir(dir);\n    dir = NULL;\n\n    if (err != 0) {\n        return err;\n    }\n    return count;\n}\n\nssize_t\nAaptAssets::slurpResourceZip(Bundle* /* bundle */, const char* filename)\n{\n    int count = 0;\n    SortedVector<AaptGroupEntry> entries;\n\n    ZipFile* zip = new ZipFile;\n    status_t err = zip->open(filename, ZipFile::kOpenReadOnly);\n    if (err != NO_ERROR) {\n        fprintf(stderr, \"error opening zip file %s\\n\", filename);\n        count = err;\n        delete zip;\n        return -1;\n    }\n\n    const int N = zip->getNumEntries();\n    for (int i=0; i<N; i++) {\n        ZipEntry* entry = zip->getEntryByIndex(i);\n        if (entry->getDeleted()) {\n            continue;\n        }\n\n        String8 entryName(entry->getFileName());\n\n        String8 dirName = entryName.getPathDir();\n        sp<AaptDir> dir = dirName == \"\" ? this : makeDir(dirName);\n\n        String8 resType;\n        AaptGroupEntry kind;\n\n        String8 remain;\n        if (entryName.walkPath(&remain) == kResourceDir) {\n            // these are the resources, pull their type out of the directory name\n            kind.initFromDirName(remain.walkPath().string(), &resType);\n        } else {\n            // these are untyped and don't have an AaptGroupEntry\n        }\n        if (entries.indexOf(kind) < 0) {\n            entries.add(kind);\n            mGroupEntries.add(kind);\n        }\n\n        // use the one from the zip file if they both exist.\n        dir->removeFile(entryName.getPathLeaf());\n\n        sp<AaptFile> file = new AaptFile(entryName, kind, resType);\n        status_t err = dir->addLeafFile(entryName.getPathLeaf(), file);\n        if (err != NO_ERROR) {\n            fprintf(stderr, \"err=%s entryName=%s\\n\", strerror(err), entryName.string());\n            count = err;\n            goto bail;\n        }\n        file->setCompressionMethod(entry->getCompressionMethod());\n\n#if 0\n        if (entryName == \"AndroidManifest.xml\") {\n            printf(\"AndroidManifest.xml\\n\");\n        }\n        printf(\"\\n\\nfile: %s\\n\", entryName.string());\n#endif\n\n        size_t len = entry->getUncompressedLen();\n        void* data = zip->uncompress(entry);\n        void* buf = file->editData(len);\n        memcpy(buf, data, len);\n\n#if 0\n        const int OFF = 0;\n        const unsigned char* p = (unsigned char*)data;\n        const unsigned char* end = p+len;\n        p += OFF;\n        for (int i=0; i<32 && p < end; i++) {\n            printf(\"0x%03x \", i*0x10 + OFF);\n            for (int j=0; j<0x10 && p < end; j++) {\n                printf(\" %02x\", *p);\n                p++;\n            }\n            printf(\"\\n\");\n        }\n#endif\n\n        free(data);\n\n        count++;\n    }\n\nbail:\n    delete zip;\n    return count;\n}\n\nstatus_t AaptAssets::filter(Bundle* bundle)\n{\n    WeakResourceFilter reqFilter;\n    status_t err = reqFilter.parse(bundle->getConfigurations());\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    uint32_t preferredDensity = 0;\n    if (bundle->getPreferredDensity().size() > 0) {\n        ResTable_config preferredConfig;\n        if (!AaptConfig::parseDensity(bundle->getPreferredDensity().string(), &preferredConfig)) {\n            fprintf(stderr, \"Error parsing preferred density: %s\\n\",\n                    bundle->getPreferredDensity().string());\n            return UNKNOWN_ERROR;\n        }\n        preferredDensity = preferredConfig.density;\n    }\n\n    if (reqFilter.isEmpty() && preferredDensity == 0) {\n        return NO_ERROR;\n    }\n\n    if (bundle->getVerbose()) {\n        if (!reqFilter.isEmpty()) {\n            printf(\"Applying required filter: %s\\n\",\n                    bundle->getConfigurations().string());\n        }\n        if (preferredDensity > 0) {\n            printf(\"Applying preferred density filter: %s\\n\",\n                    bundle->getPreferredDensity().string());\n        }\n    }\n\n    const Vector<sp<AaptDir> >& resdirs = mResDirs;\n    const size_t ND = resdirs.size();\n    for (size_t i=0; i<ND; i++) {\n        const sp<AaptDir>& dir = resdirs.itemAt(i);\n        if (dir->getLeaf() == kValuesDir) {\n            // The \"value\" dir is special since a single file defines\n            // multiple resources, so we can not do filtering on the\n            // files themselves.\n            continue;\n        }\n        if (dir->getLeaf() == kMipmapDir) {\n            // We also skip the \"mipmap\" directory, since the point of this\n            // is to include all densities without stripping.  If you put\n            // other configurations in here as well they won't be stripped\n            // either...  So don't do that.  Seriously.  What is wrong with you?\n            continue;\n        }\n\n        const size_t NG = dir->getFiles().size();\n        for (size_t j=0; j<NG; j++) {\n            sp<AaptGroup> grp = dir->getFiles().valueAt(j);\n\n            // First remove any configurations we know we don't need.\n            for (size_t k=0; k<grp->getFiles().size(); k++) {\n                sp<AaptFile> file = grp->getFiles().valueAt(k);\n                if (k == 0 && grp->getFiles().size() == 1) {\n                    // If this is the only file left, we need to keep it.\n                    // Otherwise the resource IDs we are using will be inconsistent\n                    // with what we get when not stripping.  Sucky, but at least\n                    // for now we can rely on the back-end doing another filtering\n                    // pass to take this out and leave us with this resource name\n                    // containing no entries.\n                    continue;\n                }\n                if (file->getPath().getPathExtension() == \".xml\") {\n                    // We can't remove .xml files at this point, because when\n                    // we parse them they may add identifier resources, so\n                    // removing them can cause our resource identifiers to\n                    // become inconsistent.\n                    continue;\n                }\n                const ResTable_config& config(file->getGroupEntry().toParams());\n                if (!reqFilter.match(config)) {\n                    if (bundle->getVerbose()) {\n                        printf(\"Pruning unneeded resource: %s\\n\",\n                                file->getPrintableSource().string());\n                    }\n                    grp->removeFile(k);\n                    k--;\n                }\n            }\n\n            // Quick check: no preferred filters, nothing more to do.\n            if (preferredDensity == 0) {\n                continue;\n            }\n\n            // Get the preferred density if there is one. We do not match exactly for density.\n            // If our preferred density is hdpi but we only have mdpi and xhdpi resources, we\n            // pick xhdpi.\n            for (size_t k=0; k<grp->getFiles().size(); k++) {\n                sp<AaptFile> file = grp->getFiles().valueAt(k);\n                if (k == 0 && grp->getFiles().size() == 1) {\n                    // If this is the only file left, we need to keep it.\n                    // Otherwise the resource IDs we are using will be inconsistent\n                    // with what we get when not stripping.  Sucky, but at least\n                    // for now we can rely on the back-end doing another filtering\n                    // pass to take this out and leave us with this resource name\n                    // containing no entries.\n                    continue;\n                }\n                if (file->getPath().getPathExtension() == \".xml\") {\n                    // We can't remove .xml files at this point, because when\n                    // we parse them they may add identifier resources, so\n                    // removing them can cause our resource identifiers to\n                    // become inconsistent.\n                    continue;\n                }\n                const ResTable_config& config(file->getGroupEntry().toParams());\n                if (config.density != 0 && config.density != preferredDensity) {\n                    // This is a resource we would prefer not to have.  Check\n                    // to see if have a similar variation that we would like\n                    // to have and, if so, we can drop it.\n                    uint32_t bestDensity = config.density;\n\n                    for (size_t m=0; m<grp->getFiles().size(); m++) {\n                        if (m == k) {\n                            continue;\n                        }\n\n                        sp<AaptFile> mfile = grp->getFiles().valueAt(m);\n                        const ResTable_config& mconfig(mfile->getGroupEntry().toParams());\n                        if (AaptConfig::isSameExcept(config, mconfig, ResTable_config::CONFIG_DENSITY)) {\n                            // See if there is a better density resource\n                            if (mconfig.density < bestDensity &&\n                                    mconfig.density >= preferredDensity &&\n                                    bestDensity > preferredDensity) {\n                                // This density is our preferred density, or between our best density and\n                                // the preferred density, therefore it is better.\n                                bestDensity = mconfig.density;\n                            } else if (mconfig.density > bestDensity &&\n                                    bestDensity < preferredDensity) {\n                                // This density is better than our best density and\n                                // our best density was smaller than our preferred\n                                // density, so it is better.\n                                bestDensity = mconfig.density;\n                            }\n                        }\n                    }\n\n                    if (bestDensity != config.density) {\n                        if (bundle->getVerbose()) {\n                            printf(\"Pruning unneeded resource: %s\\n\",\n                                    file->getPrintableSource().string());\n                        }\n                        grp->removeFile(k);\n                        k--;\n                    }\n                }\n            }\n        }\n    }\n\n    return NO_ERROR;\n}\n\nsp<AaptSymbols> AaptAssets::getSymbolsFor(const String8& name)\n{\n    sp<AaptSymbols> sym = mSymbols.valueFor(name);\n    if (sym == NULL) {\n        sym = new AaptSymbols();\n        mSymbols.add(name, sym);\n    }\n    return sym;\n}\n\nsp<AaptSymbols> AaptAssets::getJavaSymbolsFor(const String8& name)\n{\n    sp<AaptSymbols> sym = mJavaSymbols.valueFor(name);\n    if (sym == NULL) {\n        sym = new AaptSymbols();\n        mJavaSymbols.add(name, sym);\n    }\n    return sym;\n}\n\nstatus_t AaptAssets::applyJavaSymbols()\n{\n    size_t N = mJavaSymbols.size();\n    for (size_t i=0; i<N; i++) {\n        const String8& name = mJavaSymbols.keyAt(i);\n        const sp<AaptSymbols>& symbols = mJavaSymbols.valueAt(i);\n        ssize_t pos = mSymbols.indexOfKey(name);\n        if (pos < 0) {\n            SourcePos pos;\n            pos.error(\"Java symbol dir %s not defined\\n\", name.string());\n            return UNKNOWN_ERROR;\n        }\n        //printf(\"**** applying java symbols in dir %s\\n\", name.string());\n        status_t err = mSymbols.valueAt(pos)->applyJavaSymbols(symbols);\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    return NO_ERROR;\n}\n\nbool AaptAssets::isJavaSymbol(const AaptSymbolEntry& sym, bool includePrivate) const {\n    //printf(\"isJavaSymbol %s: public=%d, includePrivate=%d, isJavaSymbol=%d\\n\",\n    //        sym.name.string(), sym.isPublic ? 1 : 0, includePrivate ? 1 : 0,\n    //        sym.isJavaSymbol ? 1 : 0);\n    if (!mHavePrivateSymbols) return true;\n    if (sym.isPublic) return true;\n    if (includePrivate && sym.isJavaSymbol) return true;\n    return false;\n}\n\nstatus_t AaptAssets::buildIncludedResources(Bundle* bundle)\n{\n    if (mHaveIncludedAssets) {\n        return NO_ERROR;\n    }\n\n    // Add in all includes.\n    const Vector<String8>& includes = bundle->getPackageIncludes();\n    const size_t packageIncludeCount = includes.size();\n    for (size_t i = 0; i < packageIncludeCount; i++) {\n        if (bundle->getVerbose()) {\n            printf(\"Including resources from package: %s\\n\", includes[i].string());\n        }\n\n        if (!mIncludedAssets.addAssetPath(includes[i], NULL)) {\n            fprintf(stderr, \"ERROR: Asset package include '%s' not found.\\n\",\n                    includes[i].string());\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    const String8& featureOfBase = bundle->getFeatureOfPackage();\n    if (!featureOfBase.isEmpty()) {\n        if (bundle->getVerbose()) {\n            printf(\"Including base feature resources from package: %s\\n\",\n                    featureOfBase.string());\n        }\n\n        if (!mIncludedAssets.addAssetPath(featureOfBase, NULL)) {\n            fprintf(stderr, \"ERROR: base feature package '%s' not found.\\n\",\n                    featureOfBase.string());\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    if (bundle->getBaselinePackage().size() > 0){\n        String8 baseline = bundle->getBaselinePackage();\n        if (!baseline.isEmpty()) {\n            if (bundle->getVerbose()) {\n                printf(\"Including baseline resources from package: %s\\n\",\n                        baseline.string());\n            }\n    \n            if (!mBaselineAssets.addAssetPath(baseline, NULL)) {\n                fprintf(stderr, \"ERROR: baseline package '%s' not found.\\n\",\n                        baseline.string());\n                return UNKNOWN_ERROR;\n            }\n        }\n    }\n    mHaveIncludedAssets = true;\n\n    return NO_ERROR;\n}\n\nstatus_t AaptAssets::addIncludedResources(const sp<AaptFile>& file)\n{\n    const ResTable& res = getIncludedResources();\n    // XXX dirty!\n    return const_cast<ResTable&>(res).add(file->getData(), file->getSize());\n}\n\nconst ResTable& AaptAssets::getIncludedResources() const\n{\n    return mIncludedAssets.getResources(false);\n}\n\nAssetManager& AaptAssets::getAssetManager()\n{\n    return mIncludedAssets;\n}\n\nconst ResTable& AaptAssets::getBaselineResources() const\n{\n    return mBaselineAssets.getResources(false);\n}\n\nAssetManager& AaptAssets::getBaselineAssetManager()\n{\n    return mBaselineAssets;\n}\n\nvoid AaptAssets::print(const String8& prefix) const\n{\n    String8 innerPrefix(prefix);\n    innerPrefix.append(\"  \");\n    String8 innerInnerPrefix(innerPrefix);\n    innerInnerPrefix.append(\"  \");\n    printf(\"%sConfigurations:\\n\", prefix.string());\n    const size_t N=mGroupEntries.size();\n    for (size_t i=0; i<N; i++) {\n        String8 cname = mGroupEntries.itemAt(i).toDirName(String8());\n        printf(\"%s %s\\n\", prefix.string(),\n                cname != \"\" ? cname.string() : \"(default)\");\n    }\n\n    printf(\"\\n%sFiles:\\n\", prefix.string());\n    AaptDir::print(innerPrefix);\n\n    printf(\"\\n%sResource Dirs:\\n\", prefix.string());\n    const Vector<sp<AaptDir> >& resdirs = mResDirs;\n    const size_t NR = resdirs.size();\n    for (size_t i=0; i<NR; i++) {\n        const sp<AaptDir>& d = resdirs.itemAt(i);\n        printf(\"%s  Type %s\\n\", prefix.string(), d->getLeaf().string());\n        d->print(innerInnerPrefix);\n    }\n}\n\nsp<AaptDir> AaptAssets::resDir(const String8& name) const\n{\n    const Vector<sp<AaptDir> >& resdirs = mResDirs;\n    const size_t N = resdirs.size();\n    for (size_t i=0; i<N; i++) {\n        const sp<AaptDir>& d = resdirs.itemAt(i);\n        if (d->getLeaf() == name) {\n            return d;\n        }\n    }\n    return NULL;\n}\n\nbool\nvalid_symbol_name(const String8& symbol)\n{\n    static char const * const KEYWORDS[] = {\n        \"abstract\", \"assert\", \"boolean\", \"break\",\n        \"byte\", \"case\", \"catch\", \"char\", \"class\", \"const\", \"continue\",\n        \"default\", \"do\", \"double\", \"else\", \"enum\", \"extends\", \"final\",\n        \"finally\", \"float\", \"for\", \"goto\", \"if\", \"implements\", \"import\",\n        \"instanceof\", \"int\", \"interface\", \"long\", \"native\", \"new\", \"package\",\n        \"private\", \"protected\", \"public\", \"return\", \"short\", \"static\",\n        \"strictfp\", \"super\", \"switch\", \"synchronized\", \"this\", \"throw\",\n        \"throws\", \"transient\", \"try\", \"void\", \"volatile\", \"while\",\n        \"true\", \"false\", \"null\",\n        NULL\n    };\n    const char*const* k = KEYWORDS;\n    const char*const s = symbol.string();\n    while (*k) {\n        if (0 == strcmp(s, *k)) {\n            return false;\n        }\n        k++;\n    }\n    return true;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/AaptAssets.h",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Information about assets being operated on.\n//\n#ifndef __AAPT_ASSETS_H\n#define __AAPT_ASSETS_H\n\n#include <androidfw/AssetManager.h>\n#include <androidfw/ResourceTypes.h>\n#include <stdlib.h>\n#include <set>\n#include <utils/KeyedVector.h>\n#include <utils/RefBase.h>\n#include <utils/SortedVector.h>\n#include <utils/String8.h>\n#include <utils/Vector.h>\n\n#include \"AaptConfig.h\"\n#include \"Bundle.h\"\n#include \"ConfigDescription.h\"\n#include \"SourcePos.h\"\n#include \"ZipFile.h\"\n\nusing namespace android;\n\nextern const char * const gDefaultIgnoreAssets;\nextern const char * gUserIgnoreAssets;\n\nbool valid_symbol_name(const String8& str);\n\nclass AaptAssets;\n\nenum {\n    AXIS_NONE = 0,\n    AXIS_MCC = 1,\n    AXIS_MNC,\n    AXIS_LOCALE,\n    AXIS_SCREENLAYOUTSIZE,\n    AXIS_SCREENLAYOUTLONG,\n    AXIS_ORIENTATION,\n    AXIS_UIMODETYPE,\n    AXIS_UIMODENIGHT,\n    AXIS_DENSITY,\n    AXIS_TOUCHSCREEN,\n    AXIS_KEYSHIDDEN,\n    AXIS_KEYBOARD,\n    AXIS_NAVHIDDEN,\n    AXIS_NAVIGATION,\n    AXIS_SCREENSIZE,\n    AXIS_SMALLESTSCREENWIDTHDP,\n    AXIS_SCREENWIDTHDP,\n    AXIS_SCREENHEIGHTDP,\n    AXIS_LAYOUTDIR,\n    AXIS_VERSION,\n\n    AXIS_START = AXIS_MCC,\n    AXIS_END = AXIS_VERSION,\n};\n\nstruct AaptLocaleValue {\n     char language[4];\n     char region[4];\n     char script[4];\n     char variant[8];\n\n     AaptLocaleValue() {\n         memset(this, 0, sizeof(AaptLocaleValue));\n     }\n\n     // Initialize this AaptLocaleValue from a config string.\n     bool initFromFilterString(const String8& config);\n\n     int initFromDirName(const Vector<String8>& parts, const int startIndex);\n\n     // Initialize this AaptLocaleValue from a ResTable_config.\n     void initFromResTable(const ResTable_config& config);\n\n     void writeTo(ResTable_config* out) const;\n\n     int compare(const AaptLocaleValue& other) const {\n         return memcmp(this, &other, sizeof(AaptLocaleValue));\n     }\n\n     inline bool operator<(const AaptLocaleValue& o) const { return compare(o) < 0; }\n     inline bool operator<=(const AaptLocaleValue& o) const { return compare(o) <= 0; }\n     inline bool operator==(const AaptLocaleValue& o) const { return compare(o) == 0; }\n     inline bool operator!=(const AaptLocaleValue& o) const { return compare(o) != 0; }\n     inline bool operator>=(const AaptLocaleValue& o) const { return compare(o) >= 0; }\n     inline bool operator>(const AaptLocaleValue& o) const { return compare(o) > 0; }\nprivate:\n     void setLanguage(const char* language);\n     void setRegion(const char* language);\n     void setScript(const char* script);\n     void setVariant(const char* variant);\n};\n\n/**\n * This structure contains a specific variation of a single file out\n * of all the variations it can have that we can have.\n */\nstruct AaptGroupEntry\n{\npublic:\n    AaptGroupEntry() {}\n    AaptGroupEntry(const ConfigDescription& config) : mParams(config) {}\n\n    bool initFromDirName(const char* dir, String8* resType);\n\n    inline const ConfigDescription& toParams() const { return mParams; }\n\n    inline int compare(const AaptGroupEntry& o) const { return mParams.compareLogical(o.mParams); }\n    inline bool operator<(const AaptGroupEntry& o) const { return compare(o) < 0; }\n    inline bool operator<=(const AaptGroupEntry& o) const { return compare(o) <= 0; }\n    inline bool operator==(const AaptGroupEntry& o) const { return compare(o) == 0; }\n    inline bool operator!=(const AaptGroupEntry& o) const { return compare(o) != 0; }\n    inline bool operator>=(const AaptGroupEntry& o) const { return compare(o) >= 0; }\n    inline bool operator>(const AaptGroupEntry& o) const { return compare(o) > 0; }\n\n    String8 toString() const { return mParams.toString(); }\n    String8 toDirName(const String8& resType) const;\n\n    const String8 getVersionString() const { return AaptConfig::getVersion(mParams); }\n\nprivate:\n    ConfigDescription mParams;\n};\n\ninline int compare_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs)\n{\n    return lhs.compare(rhs);\n}\n\ninline int strictly_order_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs)\n{\n    return compare_type(lhs, rhs) < 0;\n}\n\nclass AaptGroup;\nclass FilePathStore;\n\n/**\n * A single asset file we know about.\n */\nclass AaptFile : public RefBase\n{\npublic:\n    AaptFile(const String8& sourceFile, const AaptGroupEntry& groupEntry,\n             const String8& resType)\n        : mGroupEntry(groupEntry)\n        , mResourceType(resType)\n        , mSourceFile(sourceFile)\n        , mData(NULL)\n        , mDataSize(0)\n        , mBufferSize(0)\n        , mCompression(ZipEntry::kCompressStored)\n        {\n            //printf(\"new AaptFile created %s\\n\", (const char*)sourceFile);\n        }\n    virtual ~AaptFile() {\n        free(mData);\n    }\n\n    const String8& getPath() const { return mPath; }\n    const AaptGroupEntry& getGroupEntry() const { return mGroupEntry; }\n\n    // Data API.  If there is data attached to the file,\n    // getSourceFile() is not used.\n    bool hasData() const { return mData != NULL; }\n    const void* getData() const { return mData; }\n    size_t getSize() const { return mDataSize; }\n    void* editData(size_t size);\n    void* editData(size_t* outSize = NULL);\n    void* editDataInRange(size_t offset, size_t size);\n    void* padData(size_t wordSize);\n    status_t writeData(const void* data, size_t size);\n    void clearData();\n\n    const String8& getResourceType() const { return mResourceType; }\n\n    // File API.  If the file does not hold raw data, this is\n    // a full path to a file on the filesystem that holds its data.\n    const String8& getSourceFile() const { return mSourceFile; }\n\n    String8 getPrintableSource() const;\n\n    // Desired compression method, as per utils/ZipEntry.h.  For example,\n    // no compression is ZipEntry::kCompressStored.\n    int getCompressionMethod() const { return mCompression; }\n    void setCompressionMethod(int c) { mCompression = c; }\nprivate:\n    friend class AaptGroup;\n\n    String8 mPath;\n    AaptGroupEntry mGroupEntry;\n    String8 mResourceType;\n    String8 mSourceFile;\n    void* mData;\n    size_t mDataSize;\n    size_t mBufferSize;\n    int mCompression;\n};\n\n/**\n * A group of related files (the same file, with different\n * vendor/locale variations).\n */\nclass AaptGroup : public RefBase\n{\npublic:\n    AaptGroup(const String8& leaf, const String8& path)\n        : mLeaf(leaf), mPath(path) { }\n    virtual ~AaptGroup() { }\n\n    const String8& getLeaf() const { return mLeaf; }\n\n    // Returns the relative path after the AaptGroupEntry dirs.\n    const String8& getPath() const { return mPath; }\n\n    const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& getFiles() const\n        { return mFiles; }\n\n    status_t addFile(const sp<AaptFile>& file, const bool overwriteDuplicate=false);\n    void removeFile(size_t index);\n\n    void print(const String8& prefix) const;\n\n    String8 getPrintableSource() const;\n\nprivate:\n    String8 mLeaf;\n    String8 mPath;\n\n    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > mFiles;\n};\n\n/**\n * A single directory of assets, which can contain files and other\n * sub-directories.\n */\nclass AaptDir : public RefBase\n{\npublic:\n    AaptDir(const String8& leaf, const String8& path)\n        : mLeaf(leaf), mPath(path) { }\n    virtual ~AaptDir() { }\n\n    const String8& getLeaf() const { return mLeaf; }\n\n    const String8& getPath() const { return mPath; }\n\n    const DefaultKeyedVector<String8, sp<AaptGroup> >& getFiles() const { return mFiles; }\n    const DefaultKeyedVector<String8, sp<AaptDir> >& getDirs() const { return mDirs; }\n\n    virtual status_t addFile(const String8& name, const sp<AaptGroup>& file);\n\n    void removeFile(const String8& name);\n    void removeDir(const String8& name);\n\n    /*\n     * Perform some sanity checks on the names of files and directories here.\n     * In particular:\n     *  - Check for illegal chars in filenames.\n     *  - Check filename length.\n     *  - Check for presence of \".gz\" and non-\".gz\" copies of same file.\n     *  - Check for multiple files whose names match in a case-insensitive\n     *    fashion (problematic for some systems).\n     *\n     * Comparing names against all other names is O(n^2).  We could speed\n     * it up some by sorting the entries and being smarter about what we\n     * compare against, but I'm not expecting to have enough files in a\n     * single directory to make a noticeable difference in speed.\n     *\n     * Note that sorting here is not enough to guarantee that the package\n     * contents are sorted -- subsequent updates can rearrange things.\n     */\n    status_t validate() const;\n\n    void print(const String8& prefix) const;\n\n    String8 getPrintableSource() const;\n\nprivate:\n    friend class AaptAssets;\n\n    status_t addDir(const String8& name, const sp<AaptDir>& dir);\n    sp<AaptDir> makeDir(const String8& name);\n    status_t addLeafFile(const String8& leafName,\n                         const sp<AaptFile>& file,\n                         const bool overwrite=false);\n    virtual ssize_t slurpFullTree(Bundle* bundle,\n                                  const String8& srcDir,\n                                  const AaptGroupEntry& kind,\n                                  const String8& resType,\n                                  sp<FilePathStore>& fullResPaths,\n                                  const bool overwrite=false);\n\n    String8 mLeaf;\n    String8 mPath;\n\n    DefaultKeyedVector<String8, sp<AaptGroup> > mFiles;\n    DefaultKeyedVector<String8, sp<AaptDir> > mDirs;\n};\n\n/**\n * All information we know about a particular symbol.\n */\nclass AaptSymbolEntry\n{\npublic:\n    AaptSymbolEntry()\n        : isPublic(false), isJavaSymbol(false), typeCode(TYPE_UNKNOWN)\n    {\n    }\n    AaptSymbolEntry(const String8& _name)\n        : name(_name), isPublic(false), isJavaSymbol(false), typeCode(TYPE_UNKNOWN)\n    {\n    }\n    AaptSymbolEntry(const AaptSymbolEntry& o)\n        : name(o.name), sourcePos(o.sourcePos), isPublic(o.isPublic)\n        , isJavaSymbol(o.isJavaSymbol), comment(o.comment), typeComment(o.typeComment)\n        , typeCode(o.typeCode), int32Val(o.int32Val), stringVal(o.stringVal)\n    {\n    }\n    AaptSymbolEntry operator=(const AaptSymbolEntry& o)\n    {\n        sourcePos = o.sourcePos;\n        isPublic = o.isPublic;\n        isJavaSymbol = o.isJavaSymbol;\n        comment = o.comment;\n        typeComment = o.typeComment;\n        typeCode = o.typeCode;\n        int32Val = o.int32Val;\n        stringVal = o.stringVal;\n        return *this;\n    }\n    \n    const String8 name;\n    \n    SourcePos sourcePos;\n    bool isPublic;\n    bool isJavaSymbol;\n    \n    String16 comment;\n    String16 typeComment;\n    \n    enum {\n        TYPE_UNKNOWN = 0,\n        TYPE_INT32,\n        TYPE_STRING\n    };\n    \n    int typeCode;\n    \n    // Value.  May be one of these.\n    int32_t int32Val;\n    String8 stringVal;\n};\n\n/**\n * A group of related symbols (such as indices into a string block)\n * that have been generated from the assets.\n */\nclass AaptSymbols : public RefBase\n{\npublic:\n    AaptSymbols() { }\n    virtual ~AaptSymbols() { }\n\n    status_t addSymbol(const String8& name, int32_t value, const SourcePos& pos) {\n        if (!check_valid_symbol_name(name, pos, \"symbol\")) {\n            return BAD_VALUE;\n        }\n        AaptSymbolEntry& sym = edit_symbol(name, &pos);\n        sym.typeCode = AaptSymbolEntry::TYPE_INT32;\n        sym.int32Val = value;\n        return NO_ERROR;\n    }\n\n    status_t addStringSymbol(const String8& name, const String8& value,\n            const SourcePos& pos) {\n        if (!check_valid_symbol_name(name, pos, \"symbol\")) {\n            return BAD_VALUE;\n        }\n        AaptSymbolEntry& sym = edit_symbol(name, &pos);\n        sym.typeCode = AaptSymbolEntry::TYPE_STRING;\n        sym.stringVal = value;\n        return NO_ERROR;\n    }\n\n    status_t makeSymbolPublic(const String8& name, const SourcePos& pos) {\n        if (!check_valid_symbol_name(name, pos, \"symbol\")) {\n            return BAD_VALUE;\n        }\n        AaptSymbolEntry& sym = edit_symbol(name, &pos);\n        sym.isPublic = true;\n        return NO_ERROR;\n    }\n\n    status_t makeSymbolJavaSymbol(const String8& name, const SourcePos& pos) {\n        if (!check_valid_symbol_name(name, pos, \"symbol\")) {\n            return BAD_VALUE;\n        }\n        AaptSymbolEntry& sym = edit_symbol(name, &pos);\n        sym.isJavaSymbol = true;\n        return NO_ERROR;\n    }\n\n    void appendComment(const String8& name, const String16& comment, const SourcePos& pos) {\n        if (comment.size() <= 0) {\n            return;\n        }\n        AaptSymbolEntry& sym = edit_symbol(name, &pos);\n        if (sym.comment.size() == 0) {\n            sym.comment = comment;\n        } else {\n            sym.comment.append(String16(\"\\n\"));\n            sym.comment.append(comment);\n        }\n    }\n\n    void appendTypeComment(const String8& name, const String16& comment) {\n        if (comment.size() <= 0) {\n            return;\n        }\n        AaptSymbolEntry& sym = edit_symbol(name, NULL);\n        if (sym.typeComment.size() == 0) {\n            sym.typeComment = comment;\n        } else {\n            sym.typeComment.append(String16(\"\\n\"));\n            sym.typeComment.append(comment);\n        }\n    }\n    \n    sp<AaptSymbols> addNestedSymbol(const String8& name, const SourcePos& pos) {\n        if (!check_valid_symbol_name(name, pos, \"nested symbol\")) {\n            return NULL;\n        }\n        \n        sp<AaptSymbols> sym = mNestedSymbols.valueFor(name);\n        if (sym == NULL) {\n            sym = new AaptSymbols();\n            mNestedSymbols.add(name, sym);\n        }\n\n        return sym;\n    }\n\n    status_t applyJavaSymbols(const sp<AaptSymbols>& javaSymbols);\n\n    const KeyedVector<String8, AaptSymbolEntry>& getSymbols() const\n        { return mSymbols; }\n    const DefaultKeyedVector<String8, sp<AaptSymbols> >& getNestedSymbols() const\n        { return mNestedSymbols; }\n\n    const String16& getComment(const String8& name) const\n        { return get_symbol(name).comment; }\n    const String16& getTypeComment(const String8& name) const\n        { return get_symbol(name).typeComment; }\n\nprivate:\n    bool check_valid_symbol_name(const String8& symbol, const SourcePos& pos, const char* label) {\n        if (valid_symbol_name(symbol)) {\n            return true;\n        }\n        pos.error(\"invalid %s: '%s'\\n\", label, symbol.string());\n        return false;\n    }\n    AaptSymbolEntry& edit_symbol(const String8& symbol, const SourcePos* pos) {\n        ssize_t i = mSymbols.indexOfKey(symbol);\n        if (i < 0) {\n            i = mSymbols.add(symbol, AaptSymbolEntry(symbol));\n        }\n        AaptSymbolEntry& sym = mSymbols.editValueAt(i);\n        if (pos != NULL && sym.sourcePos.line < 0) {\n            sym.sourcePos = *pos;\n        }\n        return sym;\n    }\n    const AaptSymbolEntry& get_symbol(const String8& symbol) const {\n        ssize_t i = mSymbols.indexOfKey(symbol);\n        if (i >= 0) {\n            return mSymbols.valueAt(i);\n        }\n        return mDefSymbol;\n    }\n\n    KeyedVector<String8, AaptSymbolEntry>           mSymbols;\n    DefaultKeyedVector<String8, sp<AaptSymbols> >   mNestedSymbols;\n    AaptSymbolEntry                                 mDefSymbol;\n};\n\nclass ResourceTypeSet : public RefBase,\n                        public KeyedVector<String8,sp<AaptGroup> >\n{\npublic:\n    ResourceTypeSet();\n};\n\n// Storage for lists of fully qualified paths for\n// resources encountered during slurping.\nclass FilePathStore : public RefBase,\n                      public Vector<String8>\n{\npublic:\n    FilePathStore();\n};\n\n/**\n * Asset hierarchy being operated on.\n */\nclass AaptAssets : public AaptDir\n{\npublic:\n    AaptAssets();\n    virtual ~AaptAssets() { delete mRes; }\n\n    const String8& getPackage() const { return mPackage; }\n    void setPackage(const String8& package) {\n        mPackage = package;\n        mSymbolsPrivatePackage = package;\n        mHavePrivateSymbols = false;\n    }\n\n    const SortedVector<AaptGroupEntry>& getGroupEntries() const;\n\n    virtual status_t addFile(const String8& name, const sp<AaptGroup>& file);\n\n    sp<AaptFile> addFile(const String8& filePath,\n                         const AaptGroupEntry& entry,\n                         const String8& srcDir,\n                         sp<AaptGroup>* outGroup,\n                         const String8& resType);\n\n    void addResource(const String8& leafName,\n                     const String8& path,\n                     const sp<AaptFile>& file,\n                     const String8& resType);\n\n    void addGroupEntry(const AaptGroupEntry& entry) { mGroupEntries.add(entry); }\n    \n    ssize_t slurpFromArgs(Bundle* bundle);\n\n    sp<AaptSymbols> getSymbolsFor(const String8& name);\n\n    sp<AaptSymbols> getJavaSymbolsFor(const String8& name);\n\n    status_t applyJavaSymbols();\n\n    const DefaultKeyedVector<String8, sp<AaptSymbols> >& getSymbols() const { return mSymbols; }\n\n    String8 getSymbolsPrivatePackage() const { return mSymbolsPrivatePackage; }\n    void setSymbolsPrivatePackage(const String8& pkg) {\n        mSymbolsPrivatePackage = pkg;\n        mHavePrivateSymbols = mSymbolsPrivatePackage != mPackage;\n    }\n\n    bool havePrivateSymbols() const { return mHavePrivateSymbols; }\n\n    bool isJavaSymbol(const AaptSymbolEntry& sym, bool includePrivate) const;\n\n    status_t buildIncludedResources(Bundle* bundle);\n    status_t addIncludedResources(const sp<AaptFile>& file);\n    const ResTable& getIncludedResources() const;\n    AssetManager& getAssetManager();\n    const ResTable& getBaselineResources() const;\n    AssetManager& getBaselineAssetManager();\n\n    void print(const String8& prefix) const;\n\n    inline const Vector<sp<AaptDir> >& resDirs() const { return mResDirs; }\n    sp<AaptDir> resDir(const String8& name) const;\n\n    inline sp<AaptAssets> getOverlay() { return mOverlay; }\n    inline void setOverlay(sp<AaptAssets>& overlay) { mOverlay = overlay; }\n    \n    inline KeyedVector<String8, sp<ResourceTypeSet> >* getResources() { return mRes; }\n    inline void \n        setResources(KeyedVector<String8, sp<ResourceTypeSet> >* res) { delete mRes; mRes = res; }\n\n    inline sp<FilePathStore>& getFullResPaths() { return mFullResPaths; }\n    inline void\n        setFullResPaths(sp<FilePathStore>& res) { mFullResPaths = res; }\n\n    inline sp<FilePathStore>& getFullAssetPaths() { return mFullAssetPaths; }\n    inline void\n        setFullAssetPaths(sp<FilePathStore>& res) { mFullAssetPaths = res; }\n\nprivate:\n    virtual ssize_t slurpFullTree(Bundle* bundle,\n                                  const String8& srcDir,\n                                  const AaptGroupEntry& kind,\n                                  const String8& resType,\n                                  sp<FilePathStore>& fullResPaths,\n                                  const bool overwrite=false);\n\n    ssize_t slurpResourceTree(Bundle* bundle, const String8& srcDir);\n    ssize_t slurpResourceZip(Bundle* bundle, const char* filename);\n\n    status_t filter(Bundle* bundle);\n\n    String8 mPackage;\n    SortedVector<AaptGroupEntry> mGroupEntries;\n    DefaultKeyedVector<String8, sp<AaptSymbols> > mSymbols;\n    DefaultKeyedVector<String8, sp<AaptSymbols> > mJavaSymbols;\n    String8 mSymbolsPrivatePackage;\n    bool mHavePrivateSymbols;\n\n    Vector<sp<AaptDir> > mResDirs;\n\n    bool mChanged;\n\n    bool mHaveIncludedAssets;\n    AssetManager mIncludedAssets;\n    AssetManager mBaselineAssets;\n\n    sp<AaptAssets> mOverlay;\n    KeyedVector<String8, sp<ResourceTypeSet> >* mRes;\n\n    sp<FilePathStore> mFullResPaths;\n    sp<FilePathStore> mFullAssetPaths;\n};\n\n#endif // __AAPT_ASSETS_H\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/AaptConfig.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n#include <ctype.h>\n\n#include \"AaptConfig.h\"\n#include \"AaptAssets.h\"\n#include \"AaptUtil.h\"\n#include \"ResourceFilter.h\"\n#include \"SdkConstants.h\"\n\nusing android::String8;\nusing android::Vector;\nusing android::ResTable_config;\n\nnamespace AaptConfig {\n\nstatic const char* kWildcardName = \"any\";\n\nbool parse(const String8& str, ConfigDescription* out) {\n    Vector<String8> parts = AaptUtil::splitAndLowerCase(str, '-');\n\n    ConfigDescription config;\n    AaptLocaleValue locale;\n    ssize_t index = 0;\n    ssize_t localeIndex = 0;\n    const ssize_t N = parts.size();\n    const char* part = parts[index].string();\n\n    if (str.length() == 0) {\n        goto success;\n    }\n\n    if (parseMcc(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseMnc(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    // Locale spans a few '-' separators, so we let it\n    // control the index.\n    localeIndex = locale.initFromDirName(parts, index);\n    if (localeIndex < 0) {\n        return false;\n    } else if (localeIndex > index) {\n        locale.writeTo(&config);\n        index = localeIndex;\n        if (index >= N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseLayoutDirection(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseSmallestScreenWidthDp(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseScreenWidthDp(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseScreenHeightDp(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseScreenLayoutSize(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseScreenLayoutLong(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseScreenRound(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseOrientation(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseUiModeType(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseUiModeNight(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseDensity(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseTouchscreen(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseKeysHidden(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseKeyboard(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseNavHidden(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseNavigation(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseScreenSize(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseVersion(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    // Unrecognized.\n    return false;\n\nsuccess:\n    if (out != NULL) {\n        applyVersionForCompatibility(&config);\n        *out = config;\n    }\n    return true;\n}\n\nbool parseCommaSeparatedList(const String8& str, std::set<ConfigDescription>* outSet) {\n    Vector<String8> parts = AaptUtil::splitAndLowerCase(str, ',');\n    const size_t N = parts.size();\n    for (size_t i = 0; i < N; i++) {\n        ConfigDescription config;\n        if (!parse(parts[i], &config)) {\n            return false;\n        }\n        outSet->insert(config);\n    }\n    return true;\n}\n\nvoid applyVersionForCompatibility(ConfigDescription* config) {\n    if (config == NULL) {\n        return;\n    }\n\n    uint16_t minSdk = 0;\n    if (config->screenLayout2 & ResTable_config::MASK_SCREENROUND) {\n        minSdk = SDK_MNC;\n    } else if (config->density == ResTable_config::DENSITY_ANY) {\n        minSdk = SDK_LOLLIPOP;\n    } else if (config->smallestScreenWidthDp != ResTable_config::SCREENWIDTH_ANY\n            || config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY\n            || config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {\n        minSdk = SDK_HONEYCOMB_MR2;\n    } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE)\n                != ResTable_config::UI_MODE_TYPE_ANY\n            ||  (config->uiMode & ResTable_config::MASK_UI_MODE_NIGHT)\n                != ResTable_config::UI_MODE_NIGHT_ANY) {\n        minSdk = SDK_FROYO;\n    } else if ((config->screenLayout & ResTable_config::MASK_SCREENSIZE)\n                != ResTable_config::SCREENSIZE_ANY\n            ||  (config->screenLayout & ResTable_config::MASK_SCREENLONG)\n                != ResTable_config::SCREENLONG_ANY\n            || config->density != ResTable_config::DENSITY_DEFAULT) {\n        minSdk = SDK_DONUT;\n    }\n\n    if (minSdk > config->sdkVersion) {\n        config->sdkVersion = minSdk;\n    }\n}\n\nbool parseMcc(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->mcc = 0;\n        return true;\n    }\n    const char* c = name;\n    if (tolower(*c) != 'm') return false;\n    c++;\n    if (tolower(*c) != 'c') return false;\n    c++;\n    if (tolower(*c) != 'c') return false;\n    c++;\n\n    const char* val = c;\n\n    while (*c >= '0' && *c <= '9') {\n        c++;\n    }\n    if (*c != 0) return false;\n    if (c-val != 3) return false;\n\n    int d = atoi(val);\n    if (d != 0) {\n        if (out) out->mcc = d;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseMnc(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->mcc = 0;\n        return true;\n    }\n    const char* c = name;\n    if (tolower(*c) != 'm') return false;\n    c++;\n    if (tolower(*c) != 'n') return false;\n    c++;\n    if (tolower(*c) != 'c') return false;\n    c++;\n\n    const char* val = c;\n\n    while (*c >= '0' && *c <= '9') {\n        c++;\n    }\n    if (*c != 0) return false;\n    if (c-val == 0 || c-val > 3) return false;\n\n    if (out) {\n        out->mnc = atoi(val);\n        if (out->mnc == 0) {\n            out->mnc = ACONFIGURATION_MNC_ZERO;\n        }\n    }\n\n    return true;\n}\n\nbool parseLayoutDirection(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)\n                | ResTable_config::LAYOUTDIR_ANY;\n        return true;\n    } else if (strcmp(name, \"ldltr\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)\n                | ResTable_config::LAYOUTDIR_LTR;\n        return true;\n    } else if (strcmp(name, \"ldrtl\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)\n                | ResTable_config::LAYOUTDIR_RTL;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseScreenLayoutSize(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)\n                | ResTable_config::SCREENSIZE_ANY;\n        return true;\n    } else if (strcmp(name, \"small\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)\n                | ResTable_config::SCREENSIZE_SMALL;\n        return true;\n    } else if (strcmp(name, \"normal\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)\n                | ResTable_config::SCREENSIZE_NORMAL;\n        return true;\n    } else if (strcmp(name, \"large\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)\n                | ResTable_config::SCREENSIZE_LARGE;\n        return true;\n    } else if (strcmp(name, \"xlarge\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)\n                | ResTable_config::SCREENSIZE_XLARGE;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseScreenLayoutLong(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)\n                | ResTable_config::SCREENLONG_ANY;\n        return true;\n    } else if (strcmp(name, \"long\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)\n                | ResTable_config::SCREENLONG_YES;\n        return true;\n    } else if (strcmp(name, \"notlong\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)\n                | ResTable_config::SCREENLONG_NO;\n        return true;\n    }\n    return false;\n}\n\nbool parseScreenRound(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->screenLayout2 =\n                (out->screenLayout2&~ResTable_config::MASK_SCREENROUND)\n                | ResTable_config::SCREENROUND_ANY;\n        return true;\n    } else if (strcmp(name, \"round\") == 0) {\n        if (out) out->screenLayout2 =\n                (out->screenLayout2&~ResTable_config::MASK_SCREENROUND)\n                | ResTable_config::SCREENROUND_YES;\n        return true;\n    } else if (strcmp(name, \"notround\") == 0) {\n        if (out) out->screenLayout2 =\n                (out->screenLayout2&~ResTable_config::MASK_SCREENROUND)\n                | ResTable_config::SCREENROUND_NO;\n        return true;\n    }\n    return false;\n}\n\nbool parseOrientation(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->orientation = out->ORIENTATION_ANY;\n        return true;\n    } else if (strcmp(name, \"port\") == 0) {\n        if (out) out->orientation = out->ORIENTATION_PORT;\n        return true;\n    } else if (strcmp(name, \"land\") == 0) {\n        if (out) out->orientation = out->ORIENTATION_LAND;\n        return true;\n    } else if (strcmp(name, \"square\") == 0) {\n        if (out) out->orientation = out->ORIENTATION_SQUARE;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseUiModeType(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->uiMode =\n                (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n                | ResTable_config::UI_MODE_TYPE_ANY;\n        return true;\n    } else if (strcmp(name, \"desk\") == 0) {\n      if (out) out->uiMode =\n              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n              | ResTable_config::UI_MODE_TYPE_DESK;\n        return true;\n    } else if (strcmp(name, \"car\") == 0) {\n      if (out) out->uiMode =\n              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n              | ResTable_config::UI_MODE_TYPE_CAR;\n        return true;\n    } else if (strcmp(name, \"television\") == 0) {\n      if (out) out->uiMode =\n              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n              | ResTable_config::UI_MODE_TYPE_TELEVISION;\n        return true;\n    } else if (strcmp(name, \"appliance\") == 0) {\n      if (out) out->uiMode =\n              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n              | ResTable_config::UI_MODE_TYPE_APPLIANCE;\n        return true;\n    } else if (strcmp(name, \"watch\") == 0) {\n      if (out) out->uiMode =\n              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n              | ResTable_config::UI_MODE_TYPE_WATCH;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseUiModeNight(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->uiMode =\n                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)\n                | ResTable_config::UI_MODE_NIGHT_ANY;\n        return true;\n    } else if (strcmp(name, \"night\") == 0) {\n        if (out) out->uiMode =\n                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)\n                | ResTable_config::UI_MODE_NIGHT_YES;\n        return true;\n    } else if (strcmp(name, \"notnight\") == 0) {\n      if (out) out->uiMode =\n              (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)\n              | ResTable_config::UI_MODE_NIGHT_NO;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseDensity(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->density = ResTable_config::DENSITY_DEFAULT;\n        return true;\n    }\n\n    if (strcmp(name, \"anydpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_ANY;\n        return true;\n    }\n\n    if (strcmp(name, \"nodpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_NONE;\n        return true;\n    }\n\n    if (strcmp(name, \"ldpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_LOW;\n        return true;\n    }\n\n    if (strcmp(name, \"mdpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_MEDIUM;\n        return true;\n    }\n\n    if (strcmp(name, \"tvdpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_TV;\n        return true;\n    }\n\n    if (strcmp(name, \"hdpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_HIGH;\n        return true;\n    }\n\n    if (strcmp(name, \"xhdpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_XHIGH;\n        return true;\n    }\n\n    if (strcmp(name, \"xxhdpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_XXHIGH;\n        return true;\n    }\n\n    if (strcmp(name, \"xxxhdpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_XXXHIGH;\n        return true;\n    }\n\n    char* c = (char*)name;\n    while (*c >= '0' && *c <= '9') {\n        c++;\n    }\n\n    // check that we have 'dpi' after the last digit.\n    if (toupper(c[0]) != 'D' ||\n            toupper(c[1]) != 'P' ||\n            toupper(c[2]) != 'I' ||\n            c[3] != 0) {\n        return false;\n    }\n\n    // temporarily replace the first letter with \\0 to\n    // use atoi.\n    char tmp = c[0];\n    c[0] = '\\0';\n\n    int d = atoi(name);\n    c[0] = tmp;\n\n    if (d != 0) {\n        if (out) out->density = d;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseTouchscreen(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->touchscreen = out->TOUCHSCREEN_ANY;\n        return true;\n    } else if (strcmp(name, \"notouch\") == 0) {\n        if (out) out->touchscreen = out->TOUCHSCREEN_NOTOUCH;\n        return true;\n    } else if (strcmp(name, \"stylus\") == 0) {\n        if (out) out->touchscreen = out->TOUCHSCREEN_STYLUS;\n        return true;\n    } else if (strcmp(name, \"finger\") == 0) {\n        if (out) out->touchscreen = out->TOUCHSCREEN_FINGER;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseKeysHidden(const char* name, ResTable_config* out) {\n    uint8_t mask = 0;\n    uint8_t value = 0;\n    if (strcmp(name, kWildcardName) == 0) {\n        mask = ResTable_config::MASK_KEYSHIDDEN;\n        value = ResTable_config::KEYSHIDDEN_ANY;\n    } else if (strcmp(name, \"keysexposed\") == 0) {\n        mask = ResTable_config::MASK_KEYSHIDDEN;\n        value = ResTable_config::KEYSHIDDEN_NO;\n    } else if (strcmp(name, \"keyshidden\") == 0) {\n        mask = ResTable_config::MASK_KEYSHIDDEN;\n        value = ResTable_config::KEYSHIDDEN_YES;\n    } else if (strcmp(name, \"keyssoft\") == 0) {\n        mask = ResTable_config::MASK_KEYSHIDDEN;\n        value = ResTable_config::KEYSHIDDEN_SOFT;\n    }\n\n    if (mask != 0) {\n        if (out) out->inputFlags = (out->inputFlags&~mask) | value;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseKeyboard(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->keyboard = out->KEYBOARD_ANY;\n        return true;\n    } else if (strcmp(name, \"nokeys\") == 0) {\n        if (out) out->keyboard = out->KEYBOARD_NOKEYS;\n        return true;\n    } else if (strcmp(name, \"qwerty\") == 0) {\n        if (out) out->keyboard = out->KEYBOARD_QWERTY;\n        return true;\n    } else if (strcmp(name, \"12key\") == 0) {\n        if (out) out->keyboard = out->KEYBOARD_12KEY;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseNavHidden(const char* name, ResTable_config* out) {\n    uint8_t mask = 0;\n    uint8_t value = 0;\n    if (strcmp(name, kWildcardName) == 0) {\n        mask = ResTable_config::MASK_NAVHIDDEN;\n        value = ResTable_config::NAVHIDDEN_ANY;\n    } else if (strcmp(name, \"navexposed\") == 0) {\n        mask = ResTable_config::MASK_NAVHIDDEN;\n        value = ResTable_config::NAVHIDDEN_NO;\n    } else if (strcmp(name, \"navhidden\") == 0) {\n        mask = ResTable_config::MASK_NAVHIDDEN;\n        value = ResTable_config::NAVHIDDEN_YES;\n    }\n\n    if (mask != 0) {\n        if (out) out->inputFlags = (out->inputFlags&~mask) | value;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseNavigation(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->navigation = out->NAVIGATION_ANY;\n        return true;\n    } else if (strcmp(name, \"nonav\") == 0) {\n        if (out) out->navigation = out->NAVIGATION_NONAV;\n        return true;\n    } else if (strcmp(name, \"dpad\") == 0) {\n        if (out) out->navigation = out->NAVIGATION_DPAD;\n        return true;\n    } else if (strcmp(name, \"trackball\") == 0) {\n        if (out) out->navigation = out->NAVIGATION_TRACKBALL;\n        return true;\n    } else if (strcmp(name, \"wheel\") == 0) {\n        if (out) out->navigation = out->NAVIGATION_WHEEL;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseScreenSize(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) {\n            out->screenWidth = out->SCREENWIDTH_ANY;\n            out->screenHeight = out->SCREENHEIGHT_ANY;\n        }\n        return true;\n    }\n\n    const char* x = name;\n    while (*x >= '0' && *x <= '9') x++;\n    if (x == name || *x != 'x') return false;\n    String8 xName(name, x-name);\n    x++;\n\n    const char* y = x;\n    while (*y >= '0' && *y <= '9') y++;\n    if (y == name || *y != 0) return false;\n    String8 yName(x, y-x);\n\n    uint16_t w = (uint16_t)atoi(xName.string());\n    uint16_t h = (uint16_t)atoi(yName.string());\n    if (w < h) {\n        return false;\n    }\n\n    if (out) {\n        out->screenWidth = w;\n        out->screenHeight = h;\n    }\n\n    return true;\n}\n\nbool parseSmallestScreenWidthDp(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) {\n            out->smallestScreenWidthDp = out->SCREENWIDTH_ANY;\n        }\n        return true;\n    }\n\n    if (*name != 's') return false;\n    name++;\n    if (*name != 'w') return false;\n    name++;\n    const char* x = name;\n    while (*x >= '0' && *x <= '9') x++;\n    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;\n    String8 xName(name, x-name);\n\n    if (out) {\n        out->smallestScreenWidthDp = (uint16_t)atoi(xName.string());\n    }\n\n    return true;\n}\n\nbool parseScreenWidthDp(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) {\n            out->screenWidthDp = out->SCREENWIDTH_ANY;\n        }\n        return true;\n    }\n\n    if (*name != 'w') return false;\n    name++;\n    const char* x = name;\n    while (*x >= '0' && *x <= '9') x++;\n    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;\n    String8 xName(name, x-name);\n\n    if (out) {\n        out->screenWidthDp = (uint16_t)atoi(xName.string());\n    }\n\n    return true;\n}\n\nbool parseScreenHeightDp(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) {\n            out->screenHeightDp = out->SCREENWIDTH_ANY;\n        }\n        return true;\n    }\n\n    if (*name != 'h') return false;\n    name++;\n    const char* x = name;\n    while (*x >= '0' && *x <= '9') x++;\n    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;\n    String8 xName(name, x-name);\n\n    if (out) {\n        out->screenHeightDp = (uint16_t)atoi(xName.string());\n    }\n\n    return true;\n}\n\nbool parseVersion(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) {\n            out->sdkVersion = out->SDKVERSION_ANY;\n            out->minorVersion = out->MINORVERSION_ANY;\n        }\n        return true;\n    }\n\n    if (*name != 'v') {\n        return false;\n    }\n\n    name++;\n    const char* s = name;\n    while (*s >= '0' && *s <= '9') s++;\n    if (s == name || *s != 0) return false;\n    String8 sdkName(name, s-name);\n\n    if (out) {\n        out->sdkVersion = (uint16_t)atoi(sdkName.string());\n        out->minorVersion = 0;\n    }\n\n    return true;\n}\n\nString8 getVersion(const ResTable_config& config) {\n    return String8::format(\"v%u\", config.sdkVersion);\n}\n\nbool isSameExcept(const ResTable_config& a, const ResTable_config& b, int axisMask) {\n    return a.diff(b) == axisMask;\n}\n\nbool isDensityOnly(const ResTable_config& config) {\n    if (config.density == ResTable_config::DENSITY_DEFAULT) {\n        return false;\n    }\n\n    if (config.density == ResTable_config::DENSITY_ANY) {\n        if (config.sdkVersion != SDK_LOLLIPOP) {\n            // Someone modified the sdkVersion from the default, this is not safe to assume.\n            return false;\n        }\n    } else if (config.sdkVersion != SDK_DONUT) {\n        return false;\n    }\n\n    const uint32_t mask = ResTable_config::CONFIG_DENSITY | ResTable_config::CONFIG_VERSION;\n    const ConfigDescription nullConfig;\n    return (nullConfig.diff(config) & ~mask) == 0;\n}\n\n} // namespace AaptConfig\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/AaptConfig.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __AAPT_CONFIG_H\n#define __AAPT_CONFIG_H\n\n#include <set>\n#include <utils/String8.h>\n\n#include \"ConfigDescription.h\"\n\n/**\n * Utility methods for dealing with configurations.\n */\nnamespace AaptConfig {\n\n/**\n * Parse a string of the form 'fr-sw600dp-land' and fill in the\n * given ResTable_config with resulting configuration parameters.\n *\n * The resulting configuration has the appropriate sdkVersion defined\n * for backwards compatibility.\n */\nbool parse(const android::String8& str, ConfigDescription* out = NULL);\n\n/**\n * Parse a comma separated list of configuration strings. Duplicate configurations\n * will be removed.\n *\n * Example input: \"fr,de-land,fr-sw600dp-land\"\n */\nbool parseCommaSeparatedList(const android::String8& str, std::set<ConfigDescription>* outSet);\n\n/**\n * If the configuration uses an axis that was added after\n * the original Android release, make sure the SDK version\n * is set accordingly.\n */\nvoid applyVersionForCompatibility(ConfigDescription* config);\n\n// Individual axis\nbool parseMcc(const char* str, android::ResTable_config* out = NULL);\nbool parseMnc(const char* str, android::ResTable_config* out = NULL);\nbool parseLayoutDirection(const char* str, android::ResTable_config* out = NULL);\nbool parseSmallestScreenWidthDp(const char* str, android::ResTable_config* out = NULL);\nbool parseScreenWidthDp(const char* str, android::ResTable_config* out = NULL);\nbool parseScreenHeightDp(const char* str, android::ResTable_config* out = NULL);\nbool parseScreenLayoutSize(const char* str, android::ResTable_config* out = NULL);\nbool parseScreenLayoutLong(const char* str, android::ResTable_config* out = NULL);\nbool parseScreenRound(const char* name, android::ResTable_config* out = NULL);\nbool parseOrientation(const char* str, android::ResTable_config* out = NULL);\nbool parseUiModeType(const char* str, android::ResTable_config* out = NULL);\nbool parseUiModeNight(const char* str, android::ResTable_config* out = NULL);\nbool parseDensity(const char* str, android::ResTable_config* out = NULL);\nbool parseTouchscreen(const char* str, android::ResTable_config* out = NULL);\nbool parseKeysHidden(const char* str, android::ResTable_config* out = NULL);\nbool parseKeyboard(const char* str, android::ResTable_config* out = NULL);\nbool parseNavHidden(const char* str, android::ResTable_config* out = NULL);\nbool parseNavigation(const char* str, android::ResTable_config* out = NULL);\nbool parseScreenSize(const char* str, android::ResTable_config* out = NULL);\nbool parseVersion(const char* str, android::ResTable_config* out = NULL);\n\nandroid::String8 getVersion(const android::ResTable_config& config);\n\n/**\n * Returns true if the two configurations only differ by the specified axis.\n * The axis mask is a bitmask of CONFIG_* constants.\n */\nbool isSameExcept(const android::ResTable_config& a, const android::ResTable_config& b, int configMask);\n\n/**\n * Returns true if the configuration only has the density specified. In the case\n * of 'anydpi', the version is ignored.\n */\nbool isDensityOnly(const android::ResTable_config& config);\n\n} // namespace AaptConfig\n\n#endif // __AAPT_CONFIG_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/AaptUtil.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"AaptUtil.h\"\n\nusing android::Vector;\nusing android::String8;\n\nnamespace AaptUtil {\n\nVector<String8> split(const String8& str, const char sep) {\n    Vector<String8> parts;\n    const char* p = str.string();\n    const char* q;\n\n    while (true) {\n        q = strchr(p, sep);\n        if (q == NULL) {\n            parts.add(String8(p, strlen(p)));\n            return parts;\n        }\n\n        parts.add(String8(p, q-p));\n        p = q + 1;\n    }\n    return parts;\n}\n\nVector<String8> splitAndLowerCase(const String8& str, const char sep) {\n    Vector<String8> parts;\n    const char* p = str.string();\n    const char* q;\n\n    while (true) {\n        q = strchr(p, sep);\n        if (q == NULL) {\n            String8 val(p, strlen(p));\n            val.toLower();\n            parts.add(val);\n            return parts;\n        }\n\n        String8 val(p, q-p);\n        val.toLower();\n        parts.add(val);\n        p = q + 1;\n    }\n    return parts;\n}\n\n} // namespace AaptUtil\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/AaptUtil.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef H_AAPT_UTIL\n#define H_AAPT_UTIL\n\n#include <utils/KeyedVector.h>\n#include <utils/SortedVector.h>\n#include <utils/String8.h>\n#include <utils/Vector.h>\n\nnamespace AaptUtil {\n\nandroid::Vector<android::String8> split(const android::String8& str, const char sep);\nandroid::Vector<android::String8> splitAndLowerCase(const android::String8& str, const char sep);\n\ntemplate <typename KEY, typename VALUE>\nvoid appendValue(android::KeyedVector<KEY, android::Vector<VALUE> >& keyedVector,\n        const KEY& key, const VALUE& value);\n\ntemplate <typename KEY, typename VALUE>\nvoid appendValue(android::KeyedVector<KEY, android::SortedVector<VALUE> >& keyedVector,\n        const KEY& key, const VALUE& value);\n\n//\n// Implementations\n//\n\ntemplate <typename KEY, typename VALUE>\nvoid appendValue(android::KeyedVector<KEY, android::Vector<VALUE> >& keyedVector,\n        const KEY& key, const VALUE& value) {\n    ssize_t idx = keyedVector.indexOfKey(key);\n    if (idx < 0) {\n        idx = keyedVector.add(key, android::Vector<VALUE>());\n    }\n    keyedVector.editValueAt(idx).add(value);\n}\n\ntemplate <typename KEY, typename VALUE>\nvoid appendValue(android::KeyedVector<KEY, android::SortedVector<VALUE> >& keyedVector,\n        const KEY& key, const VALUE& value) {\n    ssize_t idx = keyedVector.indexOfKey(key);\n    if (idx < 0) {\n        idx = keyedVector.add(key, android::SortedVector<VALUE>());\n    }\n    keyedVector.editValueAt(idx).add(value);\n}\n\n} // namespace AaptUtil\n\n#endif // H_AAPT_UTIL\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/AaptXml.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/String8.h>\n\n#include \"AaptXml.h\"\n\nusing namespace android;\n\nnamespace AaptXml {\n\nstatic String8 getStringAttributeAtIndex(const ResXMLTree& tree, ssize_t attrIndex,\n        String8* outError) {\n    Res_value value;\n    if (tree.getAttributeValue(attrIndex, &value) < 0) {\n        if (outError != NULL) {\n            *outError = \"could not find attribute at index\";\n        }\n        return String8();\n    }\n\n    if (value.dataType != Res_value::TYPE_STRING) {\n        if (outError != NULL) {\n            *outError = \"attribute is not a string value\";\n        }\n        return String8();\n    }\n\n    size_t len;\n    const char16_t* str = tree.getAttributeStringValue(attrIndex, &len);\n    return str ? String8(str, len) : String8();\n}\n\nstatic int32_t getIntegerAttributeAtIndex(const ResXMLTree& tree, ssize_t attrIndex,\n    int32_t defValue, String8* outError) {\n    Res_value value;\n    if (tree.getAttributeValue(attrIndex, &value) < 0) {\n        if (outError != NULL) {\n            *outError = \"could not find attribute at index\";\n        }\n        return defValue;\n    }\n\n    if (value.dataType < Res_value::TYPE_FIRST_INT\n            || value.dataType > Res_value::TYPE_LAST_INT) {\n        if (outError != NULL) {\n            *outError = \"attribute is not an integer value\";\n        }\n        return defValue;\n    }\n    return value.data;\n}\n\n\nssize_t indexOfAttribute(const ResXMLTree& tree, uint32_t attrRes) {\n    size_t attrCount = tree.getAttributeCount();\n    for (size_t i = 0; i < attrCount; i++) {\n        if (tree.getAttributeNameResID(i) == attrRes) {\n            return (ssize_t)i;\n        }\n    }\n    return -1;\n}\n\nString8 getAttribute(const ResXMLTree& tree, const char* ns,\n        const char* attr, String8* outError) {\n    ssize_t idx = tree.indexOfAttribute(ns, attr);\n    if (idx < 0) {\n        return String8();\n    }\n    return getStringAttributeAtIndex(tree, idx, outError);\n}\n\nString8 getAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* outError) {\n    ssize_t idx = indexOfAttribute(tree, attrRes);\n    if (idx < 0) {\n        return String8();\n    }\n    return getStringAttributeAtIndex(tree, idx, outError);\n}\n\nString8 getResolvedAttribute(const ResTable& resTable, const ResXMLTree& tree,\n        uint32_t attrRes, String8* outError) {\n    ssize_t idx = indexOfAttribute(tree, attrRes);\n    if (idx < 0) {\n        return String8();\n    }\n    Res_value value;\n    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {\n        if (value.dataType == Res_value::TYPE_STRING) {\n            size_t len;\n            const char16_t* str = tree.getAttributeStringValue(idx, &len);\n            return str ? String8(str, len) : String8();\n        }\n        resTable.resolveReference(&value, 0);\n        if (value.dataType != Res_value::TYPE_STRING) {\n            if (outError != NULL) {\n                *outError = \"attribute is not a string value\";\n            }\n            return String8();\n        }\n    }\n    size_t len;\n    const Res_value* value2 = &value;\n    const char16_t* str = resTable.valueToString(value2, 0, NULL, &len);\n    return str ? String8(str, len) : String8();\n}\n\nint32_t getIntegerAttribute(const ResXMLTree& tree, const char* ns,\n        const char* attr, int32_t defValue, String8* outError) {\n    ssize_t idx = tree.indexOfAttribute(ns, attr);\n    if (idx < 0) {\n        return defValue;\n    }\n    return getIntegerAttributeAtIndex(tree, idx, defValue, outError);\n}\n\nint32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes, int32_t defValue,\n        String8* outError) {\n    ssize_t idx = indexOfAttribute(tree, attrRes);\n    if (idx < 0) {\n        return defValue;\n    }\n    return getIntegerAttributeAtIndex(tree, idx, defValue, outError);\n}\n\nint32_t getResolvedIntegerAttribute(const ResTable& resTable, const ResXMLTree& tree,\n        uint32_t attrRes, int32_t defValue, String8* outError) {\n    ssize_t idx = indexOfAttribute(tree, attrRes);\n    if (idx < 0) {\n        return defValue;\n    }\n    Res_value value;\n    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {\n        if (value.dataType == Res_value::TYPE_REFERENCE) {\n            resTable.resolveReference(&value, 0);\n        }\n        if (value.dataType < Res_value::TYPE_FIRST_INT\n                || value.dataType > Res_value::TYPE_LAST_INT) {\n            if (outError != NULL) {\n                *outError = \"attribute is not an integer value\";\n            }\n            return defValue;\n        }\n    }\n    return value.data;\n}\n\nvoid getResolvedResourceAttribute(const ResTable& resTable, const ResXMLTree& tree,\n        uint32_t attrRes, Res_value* outValue, String8* outError) {\n    ssize_t idx = indexOfAttribute(tree, attrRes);\n    if (idx < 0) {\n        if (outError != NULL) {\n            *outError = \"attribute could not be found\";\n        }\n        return;\n    }\n    if (tree.getAttributeValue(idx, outValue) != NO_ERROR) {\n        if (outValue->dataType == Res_value::TYPE_REFERENCE) {\n            resTable.resolveReference(outValue, 0);\n        }\n        // The attribute was found and was resolved if need be.\n        return;\n    }\n    if (outError != NULL) {\n        *outError = \"error getting resolved resource attribute\";\n    }\n}\n\n} // namespace AaptXml\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/AaptXml.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __AAPT_XML_H\n#define __AAPT_XML_H\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/String8.h>\n\n/**\n * Utility methods for dealing with ResXMLTree.\n */\nnamespace AaptXml {\n\n/**\n * Returns the index of the attribute, or < 0 if it was not found.\n */\nssize_t indexOfAttribute(const android::ResXMLTree& tree, uint32_t attrRes);\n\n/**\n * Returns the string value for the specified attribute.\n * The string must be present in the ResXMLTree's string pool (inline in the XML).\n */\nandroid::String8 getAttribute(const android::ResXMLTree& tree, const char* ns,\n        const char* attr, android::String8* outError = NULL);\n\n/**\n * Returns the string value for the specified attribute, or an empty string\n * if the attribute does not exist.\n * The string must be present in the ResXMLTree's string pool (inline in the XML).\n */\nandroid::String8 getAttribute(const android::ResXMLTree& tree, uint32_t attrRes,\n        android::String8* outError = NULL);\n\n/**\n * Returns the integer value for the specified attribute, or the default value\n * if the attribute does not exist.\n * The integer must be declared inline in the XML.\n */\nint32_t getIntegerAttribute(const android::ResXMLTree& tree, const char* ns,\n        const char* attr, int32_t defValue = -1, android::String8* outError = NULL);\n\n/**\n * Returns the integer value for the specified attribute, or the default value\n * if the attribute does not exist.\n * The integer must be declared inline in the XML.\n */\ninline int32_t getIntegerAttribute(const android::ResXMLTree& tree, const char* ns,\n        const char* attr, android::String8* outError) {\n    return getIntegerAttribute(tree, ns, attr, -1, outError);\n}\n\n/**\n * Returns the integer value for the specified attribute, or the default value\n * if the attribute does not exist.\n * The integer must be declared inline in the XML.\n */\nint32_t getIntegerAttribute(const android::ResXMLTree& tree, uint32_t attrRes,\n        int32_t defValue = -1, android::String8* outError = NULL);\n\n/**\n * Returns the integer value for the specified attribute, or the default value\n * if the attribute does not exist.\n * The integer must be declared inline in the XML.\n */\ninline int32_t getIntegerAttribute(const android::ResXMLTree& tree, uint32_t attrRes,\n        android::String8* outError) {\n    return getIntegerAttribute(tree, attrRes, -1, outError);\n}\n\n/**\n * Returns the integer value for the specified attribute, or the default value\n * if the attribute does not exist.\n * The integer may be a resource in the supplied ResTable.\n */\nint32_t getResolvedIntegerAttribute(const android::ResTable& resTable,\n        const android::ResXMLTree& tree, uint32_t attrRes, int32_t defValue = -1,\n        android::String8* outError = NULL);\n\n/**\n * Returns the integer value for the specified attribute, or the default value\n * if the attribute does not exist.\n * The integer may be a resource in the supplied ResTable.\n */\ninline int32_t getResolvedIntegerAttribute(const android::ResTable& resTable,\n        const android::ResXMLTree& tree, uint32_t attrRes,\n        android::String8* outError) {\n    return getResolvedIntegerAttribute(resTable, tree, attrRes, -1, outError);\n}\n\n/**\n * Returns the string value for the specified attribute, or an empty string\n * if the attribute does not exist.\n * The string may be a resource in the supplied ResTable.\n */\nandroid::String8 getResolvedAttribute(const android::ResTable& resTable,\n        const android::ResXMLTree& tree, uint32_t attrRes,\n        android::String8* outError = NULL);\n\n/**\n * Returns the resource for the specified attribute in the outValue parameter.\n * The resource may be a resource in the supplied ResTable.\n */\nvoid getResolvedResourceAttribute(const android::ResTable& resTable,\n        const android::ResXMLTree& tree, uint32_t attrRes, android::Res_value* outValue,\n        android::String8* outError = NULL);\n\n} // namespace AaptXml\n\n#endif // __AAPT_XML_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/Android.mk",
    "content": "#\n# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n# This tool is prebuilt if we're doing an app-only build.\nifeq ($(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)),)\n\n# ==========================================================\n# Setup some common variables for the different build\n# targets here.\n# ==========================================================\nLOCAL_PATH:= $(call my-dir)\n\naaptMain := Main.cpp\naaptSources := \\\n    AaptAssets.cpp \\\n    AaptConfig.cpp \\\n    AaptUtil.cpp \\\n    AaptXml.cpp \\\n    ApkBuilder.cpp \\\n    Command.cpp \\\n    CrunchCache.cpp \\\n    FileFinder.cpp \\\n    Images.cpp \\\n    Package.cpp \\\n    pseudolocalize.cpp \\\n    Resource.cpp \\\n    ResourceFilter.cpp \\\n    ResourceIdCache.cpp \\\n    ResourceTable.cpp \\\n    SourcePos.cpp \\\n    StringPool.cpp \\\n    WorkQueue.cpp \\\n    XMLNode.cpp \\\n    ZipEntry.cpp \\\n    ZipFile.cpp\n\naaptTests := \\\n    tests/AaptConfig_test.cpp \\\n    tests/AaptGroupEntry_test.cpp \\\n    tests/Pseudolocales_test.cpp \\\n    tests/ResourceFilter_test.cpp \\\n    tests/ResourceTable_test.cpp\n\naaptHostStaticLibs := \\\n    libandroidfw \\\n    libpng \\\n    libutils \\\n    liblog \\\n    libcutils \\\n    libexpat \\\n    libziparchive-host \\\n    libbase\n\naaptCFlags := -DAAPT_VERSION=\\\"$(BUILD_NUMBER_FROM_FILE)\\\"\naaptCFlags += -Wall -Werror\n\naaptHostLdLibs_linux := -lrt -ldl -lpthread\n\n# Statically link libz for MinGW (Win SDK under Linux),\n# and dynamically link for all others.\naaptHostStaticLibs_windows := libz\naaptHostLdLibs_linux += -lz\naaptHostLdLibs_darwin := -lz\n\n\n# ==========================================================\n# Build the host static library: libaapt\n# ==========================================================\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libaapt\nLOCAL_MODULE_HOST_OS := darwin linux windows\nLOCAL_CFLAGS := -Wno-format-y2k -DSTATIC_ANDROIDFW_FOR_TOOLS $(aaptCFlags)\nLOCAL_CPPFLAGS := $(aaptCppFlags)\nLOCAL_CFLAGS_darwin := -D_DARWIN_UNLIMITED_STREAMS\nLOCAL_SRC_FILES := $(aaptSources)\nLOCAL_STATIC_LIBRARIES := $(aaptHostStaticLibs)\nLOCAL_STATIC_LIBRARIES_windows := $(aaptHostStaticLibs_windows)\n\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\n# ==========================================================\n# Build the host executable: aapt\n# ==========================================================\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := aapt\nLOCAL_MODULE_HOST_OS := darwin linux windows\nLOCAL_CFLAGS := $(aaptCFlags)\nLOCAL_CPPFLAGS := $(aaptCppFlags)\nLOCAL_LDLIBS_darwin := $(aaptHostLdLibs_darwin)\nLOCAL_LDLIBS_linux := $(aaptHostLdLibs_linux)\nLOCAL_SRC_FILES := $(aaptMain)\nLOCAL_STATIC_LIBRARIES := libaapt $(aaptHostStaticLibs)\nLOCAL_STATIC_LIBRARIES_windows := $(aaptHostStaticLibs_windows)\n\ninclude $(BUILD_HOST_EXECUTABLE)\n\n\n# ==========================================================\n# Build the host tests: libaapt_tests\n# ==========================================================\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libaapt_tests\nLOCAL_CFLAGS := $(aaptCFlags)\nLOCAL_CPPFLAGS := $(aaptCppFlags)\nLOCAL_LDLIBS_darwin := $(aaptHostLdLibs_darwin)\nLOCAL_LDLIBS_linux := $(aaptHostLdLibs_linux)\nLOCAL_SRC_FILES := $(aaptTests)\nLOCAL_C_INCLUDES := $(LOCAL_PATH)\nLOCAL_STATIC_LIBRARIES := libaapt $(aaptHostStaticLibs)\nLOCAL_STATIC_LIBRARIES_windows := $(aaptHostStaticLibs_windows)\n\ninclude $(BUILD_HOST_NATIVE_TEST)\n\n\nendif # No TARGET_BUILD_APPS or TARGET_BUILD_PDK\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/ApkBuilder.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"AaptAssets.h\"\n#include \"ApkBuilder.h\"\n\nusing namespace android;\n\nApkBuilder::ApkBuilder(const sp<WeakResourceFilter>& configFilter)\n    : mConfigFilter(configFilter)\n    , mDefaultFilter(new AndResourceFilter()) {\n    // Add the default split, which is present for all APKs.\n    mDefaultFilter->addFilter(mConfigFilter);\n    mSplits.add(new ApkSplit(std::set<ConfigDescription>(), mDefaultFilter, true));\n}\n\nstatus_t ApkBuilder::createSplitForConfigs(const std::set<ConfigDescription>& configs) {\n    const size_t N = mSplits.size();\n    for (size_t i = 0; i < N; i++) {\n        const std::set<ConfigDescription>& splitConfigs = mSplits[i]->getConfigs();\n        std::set<ConfigDescription>::const_iterator iter = configs.begin();\n        for (; iter != configs.end(); iter++) {\n            if (splitConfigs.count(*iter) > 0) {\n                // Can't have overlapping configurations.\n                fprintf(stderr, \"ERROR: Split configuration '%s' is already defined \"\n                        \"in another split.\\n\", iter->toString().string());\n                return ALREADY_EXISTS;\n            }\n        }\n    }\n\n    sp<StrongResourceFilter> splitFilter = new StrongResourceFilter(configs);\n\n    // Add the inverse filter of this split filter to the base apk filter so it will\n    // omit resources that belong in this split.\n    mDefaultFilter->addFilter(new InverseResourceFilter(splitFilter));\n\n    // Now add the apk-wide config filter to our split filter.\n    sp<AndResourceFilter> filter = new AndResourceFilter();\n    filter->addFilter(splitFilter);\n    filter->addFilter(mConfigFilter);\n    mSplits.add(new ApkSplit(configs, filter));\n    return NO_ERROR;\n}\n\nstatus_t ApkBuilder::addEntry(const String8& path, const sp<AaptFile>& file) {\n    const size_t N = mSplits.size();\n    for (size_t i = 0; i < N; i++) {\n        if (mSplits[i]->matches(file)) {\n            return mSplits.editItemAt(i)->addEntry(path, file);\n        }\n    }\n    // Entry can be dropped if it doesn't match any split. This will only happen\n    // if the enry doesn't mConfigFilter.\n    return NO_ERROR;\n}\n\nvoid ApkBuilder::print() const {\n    fprintf(stderr, \"APK Builder\\n\");\n    fprintf(stderr, \"-----------\\n\");\n    const size_t N = mSplits.size();\n    for (size_t i = 0; i < N; i++) {\n        mSplits[i]->print();\n        fprintf(stderr, \"\\n\");\n    }\n}\n\nApkSplit::ApkSplit(const std::set<ConfigDescription>& configs, const sp<ResourceFilter>& filter, bool isBase)\n    : mConfigs(configs), mFilter(filter), mIsBase(isBase) {\n    std::set<ConfigDescription>::const_iterator iter = configs.begin();\n    for (; iter != configs.end(); iter++) {\n        if (mName.size() > 0) {\n            mName.append(\",\");\n            mDirName.append(\"_\");\n            mPackageSafeName.append(\".\");\n        }\n\n        String8 configStr = iter->toString();\n        String8 packageConfigStr(configStr);\n        size_t len = packageConfigStr.length();\n        if (len > 0) {\n            char* buf = packageConfigStr.lockBuffer(len);\n            for (char* end = buf + len; buf < end; ++buf) {\n                if (*buf == '-') {\n                    *buf = '_';\n                }\n            }\n            packageConfigStr.unlockBuffer(len);\n        }\n        mName.append(configStr);\n        mDirName.append(configStr);\n        mPackageSafeName.append(packageConfigStr);\n    }\n}\n\nstatus_t ApkSplit::addEntry(const String8& path, const sp<AaptFile>& file) {\n    if (!mFiles.insert(OutputEntry(path, file)).second) {\n        // Duplicate file.\n        return ALREADY_EXISTS;\n    }\n    return NO_ERROR;\n}\n\nvoid ApkSplit::print() const {\n    fprintf(stderr, \"APK Split '%s'\\n\", mName.string());\n\n    std::set<OutputEntry>::const_iterator iter = mFiles.begin();\n    for (; iter != mFiles.end(); iter++) {\n        fprintf(stderr, \"  %s (%s)\\n\", iter->getPath().string(), iter->getFile()->getSourceFile().string());\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/ApkBuilder.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __APK_BUILDER_H\n#define __APK_BUILDER_H\n\n#include <set>\n#include <utils/Errors.h>\n#include <utils/String8.h>\n#include <utils/StrongPointer.h>\n#include <utils/Vector.h>\n\n#include \"ConfigDescription.h\"\n#include \"OutputSet.h\"\n#include \"ResourceFilter.h\"\n\nclass ApkSplit;\nclass AaptFile;\n\nclass ApkBuilder : public android::RefBase {\npublic:\n    ApkBuilder(const sp<WeakResourceFilter>& configFilter);\n\n    /**\n     * Tells the builder to generate a separate APK for resources that\n     * match the configurations specified. Split APKs can not have\n     * overlapping resources.\n     *\n     * NOTE: All splits should be set up before any files are added.\n     */\n    android::status_t createSplitForConfigs(const std::set<ConfigDescription>& configs);\n\n    /**\n     * Adds a file to be written to the final APK. It's name must not collide\n     * with that of any files previously added. When a Split APK is being\n     * generated, duplicates can exist as long as they are in different splits\n     * (resources.arsc, AndroidManifest.xml).\n     */\n    android::status_t addEntry(const String8& path, const android::sp<AaptFile>& file);\n\n    android::Vector<sp<ApkSplit> >& getSplits() {\n        return mSplits;\n    }\n\n    android::sp<ApkSplit> getBaseSplit() {\n        return mSplits[0];\n    }\n\n    void print() const;\n\nprivate:\n    android::sp<ResourceFilter> mConfigFilter;\n    android::sp<AndResourceFilter> mDefaultFilter;\n    android::Vector<sp<ApkSplit> > mSplits;\n};\n\nclass ApkSplit : public OutputSet {\npublic:\n    android::status_t addEntry(const String8& path, const android::sp<AaptFile>& file);\n\n    const std::set<OutputEntry>& getEntries() const {\n        return mFiles;\n    }\n\n    const std::set<ConfigDescription>& getConfigs() const {\n        return mConfigs;\n    }\n\n    bool matches(const sp<AaptFile>& file) const {\n        return mFilter->match(file->getGroupEntry().toParams());\n    }\n\n    sp<ResourceFilter> getResourceFilter() const {\n        return mFilter;\n    }\n\n    const android::String8& getPrintableName() const {\n        return mName;\n    }\n\n    const android::String8& getDirectorySafeName() const {\n        return mDirName;\n    }\n\n    const android::String8& getPackageSafeName() const {\n        return mPackageSafeName;\n    }\n\n    bool isBase() const {\n        return mIsBase;\n    }\n\n    void print() const;\n\nprivate:\n    friend class ApkBuilder;\n\n    ApkSplit(const std::set<ConfigDescription>& configs, const android::sp<ResourceFilter>& filter, bool isBase=false);\n\n    std::set<ConfigDescription> mConfigs;\n    const sp<ResourceFilter> mFilter;\n    const bool mIsBase;\n    String8 mName;\n    String8 mDirName;\n    String8 mPackageSafeName;\n    std::set<OutputEntry> mFiles;\n};\n\n#endif // __APK_BUILDER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/Bundle.h",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// State bundle.  Used to pass around stuff like command-line args.\n//\n#ifndef __BUNDLE_H\n#define __BUNDLE_H\n\n#include <stdlib.h>\n#include <utils/Log.h>\n#include <utils/threads.h>\n#include <utils/List.h>\n#include <utils/Errors.h>\n#include <utils/String8.h>\n#include <utils/Vector.h>\n\n#include \"SdkConstants.h\"\n\n/*\n * Things we can do.\n */\ntypedef enum Command {\n    kCommandUnknown = 0,\n    kCommandVersion,\n    kCommandList,\n    kCommandDump,\n    kCommandAdd,\n    kCommandRemove,\n    kCommandPackage,\n    kCommandCrunch,\n    kCommandSingleCrunch,\n    kCommandDaemon\n} Command;\n\n/*\n * Pseudolocalization methods\n */\ntypedef enum PseudolocalizationMethod {\n    NO_PSEUDOLOCALIZATION = 0,\n    PSEUDO_ACCENTED,\n    PSEUDO_BIDI,\n} PseudolocalizationMethod;\n\n/*\n * Bundle of goodies, including everything specified on the command line.\n */\nclass Bundle {\npublic:\n    Bundle(void)\n        : mCmd(kCommandUnknown), mVerbose(false), mAndroidList(false),\n          mForce(false), mGrayscaleTolerance(0), mMakePackageDirs(false),\n          mUpdate(false), mExtending(false),\n          mRequireLocalization(false), mPseudolocalize(NO_PSEUDOLOCALIZATION),\n          mWantUTF16(false), mValues(false), mIncludeMetaData(false),\n          mCompressionMethod(0), mJunkPath(false), mOutputAPKFile(NULL),\n          mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),\n          mAutoAddOverlay(false), mGenDependencies(false), mNoVersionVectors(false),\n          mCrunchedOutputDir(NULL), mProguardFile(NULL), mMainDexProguardFile(NULL),\n          mAndroidManifestFile(NULL), mPublicOutputFile(NULL),\n          mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),\n          mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),\n          mVersionCode(NULL), mVersionName(NULL), mReplaceVersion(false), mCustomPackage(NULL),\n          mExtraPackages(NULL), mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false),\n          mSkipSymbolsWithoutDefaultLocalization(false),\n          mProduct(NULL), mUseCrunchCache(false), mErrorOnFailedInsert(false),\n          mErrorOnMissingConfigEntry(false), mOutputTextSymbols(NULL),\n          mSingleCrunchInputFile(NULL), mSingleCrunchOutputFile(NULL),\n          mBuildSharedLibrary(false),\n          mBuildAppAsSharedLibrary(false),\n          mArgc(0), mArgv(NULL)\n        {}\n    ~Bundle(void) {}\n\n    /*\n     * Set the command value.  Returns \"false\" if it was previously set.\n     */\n    Command getCommand(void) const { return mCmd; }\n    void setCommand(Command cmd) { mCmd = cmd; }\n\n    /*\n     * Command modifiers.  Not all modifiers are appropriate for all\n     * commands.\n     */\n    bool getVerbose(void) const { return mVerbose; }\n    void setVerbose(bool val) { mVerbose = val; }\n    bool getAndroidList(void) const { return mAndroidList; }\n    void setAndroidList(bool val) { mAndroidList = val; }\n    bool getForce(void) const { return mForce; }\n    void setForce(bool val) { mForce = val; }\n    void setGrayscaleTolerance(int val) { mGrayscaleTolerance = val; }\n    int  getGrayscaleTolerance() const { return mGrayscaleTolerance; }\n    bool getMakePackageDirs(void) const { return mMakePackageDirs; }\n    void setMakePackageDirs(bool val) { mMakePackageDirs = val; }\n    bool getUpdate(void) const { return mUpdate; }\n    void setUpdate(bool val) { mUpdate = val; }\n    bool getExtending(void) const { return mExtending; }\n    void setExtending(bool val) { mExtending = val; }\n    bool getRequireLocalization(void) const { return mRequireLocalization; }\n    void setRequireLocalization(bool val) { mRequireLocalization = val; }\n    short getPseudolocalize(void) const { return mPseudolocalize; }\n    void setPseudolocalize(short val) { mPseudolocalize = val; }\n    void setWantUTF16(bool val) { mWantUTF16 = val; }\n    bool getValues(void) const { return mValues; }\n    void setValues(bool val) { mValues = val; }\n    bool getIncludeMetaData(void) const { return mIncludeMetaData; }\n    void setIncludeMetaData(bool val) { mIncludeMetaData = val; }\n    int getCompressionMethod(void) const { return mCompressionMethod; }\n    void setCompressionMethod(int val) { mCompressionMethod = val; }\n    bool getJunkPath(void) const { return mJunkPath; }\n    void setJunkPath(bool val) { mJunkPath = val; }\n    const char* getOutputAPKFile() const { return mOutputAPKFile; }\n    void setOutputAPKFile(const char* val) { mOutputAPKFile = val; }\n    const char* getManifestPackageNameOverride() const { return mManifestPackageNameOverride; }\n    void setManifestPackageNameOverride(const char * val) { mManifestPackageNameOverride = val; }\n    const char* getInstrumentationPackageNameOverride() const { return mInstrumentationPackageNameOverride; }\n    void setInstrumentationPackageNameOverride(const char * val) { mInstrumentationPackageNameOverride = val; }\n    bool getAutoAddOverlay() { return mAutoAddOverlay; }\n    void setAutoAddOverlay(bool val) { mAutoAddOverlay = val; }\n    bool getGenDependencies() { return mGenDependencies; }\n    void setGenDependencies(bool val) { mGenDependencies = val; }\n    bool getErrorOnFailedInsert() { return mErrorOnFailedInsert; }\n    void setErrorOnFailedInsert(bool val) { mErrorOnFailedInsert = val; }\n    bool getErrorOnMissingConfigEntry() { return mErrorOnMissingConfigEntry; }\n    void setErrorOnMissingConfigEntry(bool val) { mErrorOnMissingConfigEntry = val; }\n    const android::String8& getPlatformBuildVersionCode() { return mPlatformVersionCode; }\n    void setPlatformBuildVersionCode(const android::String8& code) { mPlatformVersionCode = code; }\n    const android::String8& getPlatformBuildVersionName() { return mPlatformVersionName; }\n    void setPlatformBuildVersionName(const android::String8& name) { mPlatformVersionName = name; }\n\n    const android::String8& getPrivateSymbolsPackage() const { return mPrivateSymbolsPackage; }\n\n    void setPrivateSymbolsPackage(const android::String8& package) {\n        mPrivateSymbolsPackage = package;\n    }\n\n    bool getUTF16StringsOption() {\n        return mWantUTF16 || !isMinSdkAtLeast(SDK_FROYO);\n    }\n\n    /*\n     * Input options.\n     */\n    const android::Vector<const char*>& getAssetSourceDirs() const { return mAssetSourceDirs; }\n    void addAssetSourceDir(const char* dir) { mAssetSourceDirs.insertAt(dir,0); }\n    const char* getCrunchedOutputDir() const { return mCrunchedOutputDir; }\n    void setCrunchedOutputDir(const char* dir) { mCrunchedOutputDir = dir; }\n    const char* getProguardFile() const { return mProguardFile; }\n    void setProguardFile(const char* file) { mProguardFile = file; }\n    const char* getMainDexProguardFile() const { return mMainDexProguardFile; }\n    void setMainDexProguardFile(const char* file) { mMainDexProguardFile = file; }\n    const android::Vector<const char*>& getResourceSourceDirs() const { return mResourceSourceDirs; }\n    void addResourceSourceDir(const char* dir) { mResourceSourceDirs.insertAt(dir,0); }\n    const char* getAndroidManifestFile() const { return mAndroidManifestFile; }\n    void setAndroidManifestFile(const char* file) { mAndroidManifestFile = file; }\n    const char* getPublicOutputFile() const { return mPublicOutputFile; }\n    void setPublicOutputFile(const char* file) { mPublicOutputFile = file; }\n    const char* getRClassDir() const { return mRClassDir; }\n    void setRClassDir(const char* dir) { mRClassDir = dir; }\n    const android::String8& getConfigurations() const { return mConfigurations; }\n    void addConfigurations(const char* val) { if (mConfigurations.size() > 0) { mConfigurations.append(\",\"); mConfigurations.append(val); } else { mConfigurations = val; } }\n    const android::String8& getPreferredDensity() const { return mPreferredDensity; }\n    void setPreferredDensity(const char* val) { mPreferredDensity = val; }\n    void addSplitConfigurations(const char* val) { mPartialConfigurations.add(android::String8(val)); }\n    const android::Vector<android::String8>& getSplitConfigurations() const { return mPartialConfigurations; }\n    const char* getResourceIntermediatesDir() const { return mResourceIntermediatesDir; }\n    void setResourceIntermediatesDir(const char* dir) { mResourceIntermediatesDir = dir; }\n    const android::Vector<android::String8>& getPackageIncludes() const { return mPackageIncludes; }\n    void addPackageInclude(const char* file) { mPackageIncludes.add(android::String8(file)); }\n    void setBaselinePackage(const char* str) { mBaselinePackage = str; }\n    const android::String8& getBaselinePackage() const { return mBaselinePackage; }\n    const android::Vector<const char*>& getJarFiles() const { return mJarFiles; }\n    void addJarFile(const char* file) { mJarFiles.add(file); }\n    const android::Vector<const char*>& getNoCompressExtensions() const { return mNoCompressExtensions; }\n    void addNoCompressExtension(const char* ext) { mNoCompressExtensions.add(ext); }\n    void setFeatureOfPackage(const char* str) { mFeatureOfPackage = str; }\n    const android::String8& getFeatureOfPackage() const { return mFeatureOfPackage; }\n    void setFeatureAfterPackage(const char* str) { mFeatureAfterPackage = str; }\n    const android::String8& getFeatureAfterPackage() const { return mFeatureAfterPackage; }\n\n    const char*  getManifestMinSdkVersion() const { return mManifestMinSdkVersion; }\n    void setManifestMinSdkVersion(const char*  val) { mManifestMinSdkVersion = val; }\n    const char*  getMinSdkVersion() const { return mMinSdkVersion; }\n    void setMinSdkVersion(const char*  val) { mMinSdkVersion = val; }\n    const char*  getTargetSdkVersion() const { return mTargetSdkVersion; }\n    void setTargetSdkVersion(const char*  val) { mTargetSdkVersion = val; }\n    const char*  getMaxSdkVersion() const { return mMaxSdkVersion; }\n    void setMaxSdkVersion(const char*  val) { mMaxSdkVersion = val; }\n    const char*  getVersionCode() const { return mVersionCode; }\n    void setVersionCode(const char*  val) { mVersionCode = val; }\n    const char* getVersionName() const { return mVersionName; }\n    void setVersionName(const char* val) { mVersionName = val; }\n    bool getReplaceVersion() { return mReplaceVersion; }\n    void setReplaceVersion(bool val) { mReplaceVersion = val; }\n    const android::String8& getRevisionCode() { return mRevisionCode; }\n    void setRevisionCode(const char* val) { mRevisionCode = android::String8(val); }\n    const char* getCustomPackage() const { return mCustomPackage; }\n    void setCustomPackage(const char* val) { mCustomPackage = val; }\n    const char* getExtraPackages() const { return mExtraPackages; }\n    void setExtraPackages(const char* val) { mExtraPackages = val; }\n    const char* getMaxResVersion() const { return mMaxResVersion; }\n    void setMaxResVersion(const char * val) { mMaxResVersion = val; }\n    bool getDebugMode() const { return mDebugMode; }\n    void setDebugMode(bool val) { mDebugMode = val; }\n    bool getNonConstantId() const { return mNonConstantId; }\n    void setNonConstantId(bool val) { mNonConstantId = val; }\n    bool getSkipSymbolsWithoutDefaultLocalization() const { return mSkipSymbolsWithoutDefaultLocalization; }\n    void setSkipSymbolsWithoutDefaultLocalization(bool val) { mSkipSymbolsWithoutDefaultLocalization = val; }\n    const char* getProduct() const { return mProduct; }\n    void setProduct(const char * val) { mProduct = val; }\n    void setUseCrunchCache(bool val) { mUseCrunchCache = val; }\n    bool getUseCrunchCache() const { return mUseCrunchCache; }\n    const char* getOutputTextSymbols() const { return mOutputTextSymbols; }\n    void setOutputTextSymbols(const char* val) { mOutputTextSymbols = val; }\n    const char* getSingleCrunchInputFile() const { return mSingleCrunchInputFile; }\n    void setSingleCrunchInputFile(const char* val) { mSingleCrunchInputFile = val; }\n    const char* getSingleCrunchOutputFile() const { return mSingleCrunchOutputFile; }\n    void setSingleCrunchOutputFile(const char* val) { mSingleCrunchOutputFile = val; }\n    bool getBuildSharedLibrary() const { return mBuildSharedLibrary; }\n    void setBuildSharedLibrary(bool val) { mBuildSharedLibrary = val; }\n    bool getBuildAppAsSharedLibrary() const { return mBuildAppAsSharedLibrary; }\n    void setBuildAppAsSharedLibrary(bool val) { mBuildAppAsSharedLibrary = val; }\n    void setNoVersionVectors(bool val) { mNoVersionVectors = val; }\n    bool getNoVersionVectors() const { return mNoVersionVectors; }\n\n    /*\n     * Set and get the file specification.\n     *\n     * Note this does NOT make a copy of argv.\n     */\n    void setFileSpec(char* const argv[], int argc) {\n        mArgc = argc;\n        mArgv = argv;\n    }\n    int getFileSpecCount(void) const { return mArgc; }\n    const char* getFileSpecEntry(int idx) const { return mArgv[idx]; }\n    void eatArgs(int n) {\n        if (n > mArgc) n = mArgc;\n        mArgv += n;\n        mArgc -= n;\n    }\n\n#if 0\n    /*\n     * Package count.  Nothing to do with anything else here; this is\n     * just a convenient place to stuff it so we don't have to pass it\n     * around everywhere.\n     */\n    int getPackageCount(void) const { return mPackageCount; }\n    void setPackageCount(int val) { mPackageCount = val; }\n#endif\n\n    /* Certain features may only be available on a specific SDK level or\n     * above. SDK levels that have a non-numeric identifier are assumed\n     * to be newer than any SDK level that has a number designated.\n     */\n    bool isMinSdkAtLeast(int desired) const {\n        /* If the application specifies a minSdkVersion in the manifest\n         * then use that. Otherwise, check what the user specified on\n         * the command line. If neither, it's not available since\n         * the minimum SDK version is assumed to be 1.\n         */\n        const char *minVer;\n        if (mManifestMinSdkVersion != NULL) {\n            minVer = mManifestMinSdkVersion;\n        } else if (mMinSdkVersion != NULL) {\n            minVer = mMinSdkVersion;\n        } else {\n            return false;\n        }\n\n        char *end;\n        int minSdkNum = (int)strtol(minVer, &end, 0);\n        if (*end == '\\0') {\n            if (minSdkNum < desired) {\n                return false;\n            }\n        }\n        return true;\n    }\n\nprivate:\n    /* commands & modifiers */\n    Command     mCmd;\n    bool        mVerbose;\n    bool        mAndroidList;\n    bool        mForce;\n    int         mGrayscaleTolerance;\n    bool        mMakePackageDirs;\n    bool        mUpdate;\n    bool        mExtending;\n    bool        mRequireLocalization;\n    short       mPseudolocalize;\n    bool        mWantUTF16;\n    bool        mValues;\n    bool        mIncludeMetaData;\n    int         mCompressionMethod;\n    bool        mJunkPath;\n    const char* mOutputAPKFile;\n    const char* mManifestPackageNameOverride;\n    const char* mInstrumentationPackageNameOverride;\n    bool        mAutoAddOverlay;\n    bool        mGenDependencies;\n    bool        mNoVersionVectors;\n    const char* mCrunchedOutputDir;\n    const char* mProguardFile;\n    const char* mMainDexProguardFile;\n    const char* mAndroidManifestFile;\n    const char* mPublicOutputFile;\n    const char* mRClassDir;\n    const char* mResourceIntermediatesDir;\n    android::String8 mConfigurations;\n    android::String8 mPreferredDensity;\n    android::Vector<android::String8> mPartialConfigurations;\n    android::Vector<android::String8> mPackageIncludes;\n    android::String8 mBaselinePackage;\n    android::Vector<const char*> mJarFiles;\n    android::Vector<const char*> mNoCompressExtensions;\n    android::Vector<const char*> mAssetSourceDirs;\n    android::Vector<const char*> mResourceSourceDirs;\n\n    android::String8 mFeatureOfPackage;\n    android::String8 mFeatureAfterPackage;\n    android::String8 mRevisionCode;\n    const char* mManifestMinSdkVersion;\n    const char* mMinSdkVersion;\n    const char* mTargetSdkVersion;\n    const char* mMaxSdkVersion;\n    const char* mVersionCode;\n    const char* mVersionName;\n    bool        mReplaceVersion;\n    const char* mCustomPackage;\n    const char* mExtraPackages;\n    const char* mMaxResVersion;\n    bool        mDebugMode;\n    bool        mNonConstantId;\n    bool        mSkipSymbolsWithoutDefaultLocalization;\n    const char* mProduct;\n    bool        mUseCrunchCache;\n    bool        mErrorOnFailedInsert;\n    bool        mErrorOnMissingConfigEntry;\n    const char* mOutputTextSymbols;\n    const char* mSingleCrunchInputFile;\n    const char* mSingleCrunchOutputFile;\n    bool        mBuildSharedLibrary;\n    bool        mBuildAppAsSharedLibrary;\n    android::String8 mPlatformVersionCode;\n    android::String8 mPlatformVersionName;\n    android::String8 mPrivateSymbolsPackage;\n\n    /* file specification */\n    int         mArgc;\n    char* const* mArgv;\n\n#if 0\n    /* misc stuff */\n    int         mPackageCount;\n#endif\n\n};\n\n#endif // __BUNDLE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/CacheUpdater.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n// Abstraction of calls to system to make directories and delete files and\n// wrapper to image processing.\n\n#ifndef CACHE_UPDATER_H\n#define CACHE_UPDATER_H\n\n#include <utils/String8.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <stdio.h>\n#include \"Images.h\"\n#ifdef _WIN32\n#include <direct.h>\n#endif\n\nusing namespace android;\n\n/** CacheUpdater\n *  This is a pure virtual class that declares abstractions of functions useful\n *  for managing a cache files. This manager is set up to be used in a\n *  mirror cache where the source tree is duplicated and filled with processed\n *  images. This class is abstracted to allow for dependency injection during\n *  unit testing.\n *  Usage:\n *      To update/add a file to the cache, call processImage\n *      To remove a file from the cache, call deleteFile\n */\nclass CacheUpdater {\npublic:\n    virtual ~CacheUpdater() {}\n\n    // Make sure all the directories along this path exist\n    virtual void ensureDirectoriesExist(String8 path) = 0;\n\n    // Delete a file\n    virtual void deleteFile(String8 path) = 0;\n\n    // Process an image from source out to dest\n    virtual void processImage(String8 source, String8 dest) = 0;\nprivate:\n};\n\n/** SystemCacheUpdater\n * This is an implementation of the above virtual cache updater specification.\n * This implementations hits the filesystem to manage a cache and calls out to\n * the PNG crunching in images.h to process images out to its cache components.\n */\nclass SystemCacheUpdater : public CacheUpdater {\npublic:\n    // Constructor to set bundle to pass to preProcessImage\n    SystemCacheUpdater (Bundle* b)\n        : bundle(b) { };\n\n    // Make sure all the directories along this path exist\n    virtual void ensureDirectoriesExist(String8 path)\n    {\n        // Check to see if we're dealing with a fully qualified path\n        String8 existsPath;\n        String8 toCreate;\n        String8 remains;\n        struct stat s;\n\n        // Check optomistically to see if all directories exist.\n        // If something in the path doesn't exist, then walk the path backwards\n        // and find the place to start creating directories forward.\n        if (stat(path.string(),&s) == -1) {\n            // Walk backwards to find place to start creating directories\n            existsPath = path;\n            do {\n                // As we remove the end of existsPath add it to\n                // the string of paths to create.\n                toCreate = existsPath.getPathLeaf().appendPath(toCreate);\n                existsPath = existsPath.getPathDir();\n            } while (stat(existsPath.string(),&s) == -1);\n\n            // Walk forwards and build directories as we go\n            do {\n                // Advance to the next segment of the path\n                existsPath.appendPath(toCreate.walkPath(&remains));\n                toCreate = remains;\n#ifdef _WIN32\n                _mkdir(existsPath.string());\n#else\n                mkdir(existsPath.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);\n#endif\n            } while (remains.length() > 0);\n        } //if\n    };\n\n    // Delete a file\n    virtual void deleteFile(String8 path)\n    {\n        if (remove(path.string()) != 0)\n            fprintf(stderr,\"ERROR DELETING %s\\n\",path.string());\n    };\n\n    // Process an image from source out to dest\n    virtual void processImage(String8 source, String8 dest)\n    {\n        // Make sure we're trying to write to a directory that is extant\n        ensureDirectoriesExist(dest.getPathDir());\n\n        preProcessImageToCache(bundle, source, dest);\n    };\nprivate:\n    Bundle* bundle;\n};\n\n#endif // CACHE_UPDATER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/Command.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Android Asset Packaging Tool main entry point.\n//\n#include \"AaptXml.h\"\n#include \"ApkBuilder.h\"\n#include \"Bundle.h\"\n#include \"Images.h\"\n#include \"Main.h\"\n#include \"ResourceFilter.h\"\n#include \"ResourceTable.h\"\n#include \"XMLNode.h\"\n\n#include <utils/Errors.h>\n#include <utils/KeyedVector.h>\n#include <utils/List.h>\n#include <utils/Log.h>\n#include <utils/SortedVector.h>\n#include <utils/threads.h>\n#include <utils/Vector.h>\n\n#include <errno.h>\n#include <fcntl.h>\n\n#include <iostream>\n#include <string>\n#include <sstream>\n#include <androidfw/ResourcePackageId.h>\n\nusing namespace android;\n\n#ifndef AAPT_VERSION\n    #define AAPT_VERSION \"\"\n#endif\n\n/*\n * Show version info.  All the cool kids do it.\n */\nint doVersion(Bundle* bundle)\n{\n    if (bundle->getFileSpecCount() != 0) {\n        printf(\"(ignoring extra arguments)\\n\");\n    }\n    printf(\"Android Asset Packaging Tool, v0.2-\" AAPT_VERSION \"\\n\");\n\n    return 0;\n}\n\n\n/*\n * Open the file read only.  The call fails if the file doesn't exist.\n *\n * Returns NULL on failure.\n */\nZipFile* openReadOnly(const char* fileName)\n{\n    ZipFile* zip;\n    status_t result;\n\n    zip = new ZipFile;\n    result = zip->open(fileName, ZipFile::kOpenReadOnly);\n    if (result != NO_ERROR) {\n        if (result == NAME_NOT_FOUND) {\n            fprintf(stderr, \"ERROR: '%s' not found\\n\", fileName);\n        } else if (result == PERMISSION_DENIED) {\n            fprintf(stderr, \"ERROR: '%s' access denied\\n\", fileName);\n        } else {\n            fprintf(stderr, \"ERROR: failed opening '%s' as Zip file\\n\",\n                fileName);\n        }\n        delete zip;\n        return NULL;\n    }\n\n    return zip;\n}\n\n/*\n * Open the file read-write.  The file will be created if it doesn't\n * already exist and \"okayToCreate\" is set.\n *\n * Returns NULL on failure.\n */\nZipFile* openReadWrite(const char* fileName, bool okayToCreate)\n{\n    ZipFile* zip = NULL;\n    status_t result;\n    int flags;\n\n    flags = ZipFile::kOpenReadWrite;\n    if (okayToCreate) {\n        flags |= ZipFile::kOpenCreate;\n    }\n\n    zip = new ZipFile;\n    result = zip->open(fileName, flags);\n    if (result != NO_ERROR) {\n        delete zip;\n        zip = NULL;\n        goto bail;\n    }\n\nbail:\n    return zip;\n}\n\n\n/*\n * Return a short string describing the compression method.\n */\nconst char* compressionName(int method)\n{\n    if (method == ZipEntry::kCompressStored) {\n        return \"Stored\";\n    } else if (method == ZipEntry::kCompressDeflated) {\n        return \"Deflated\";\n    } else {\n        return \"Unknown\";\n    }\n}\n\n/*\n * Return the percent reduction in size (0% == no compression).\n */\nint calcPercent(long uncompressedLen, long compressedLen)\n{\n    if (!uncompressedLen) {\n        return 0;\n    } else {\n        return (int) (100.0 - (compressedLen * 100.0) / uncompressedLen + 0.5);\n    }\n}\n\n/*\n * Handle the \"list\" command, which can be a simple file dump or\n * a verbose listing.\n *\n * The verbose listing closely matches the output of the Info-ZIP \"unzip\"\n * command.\n */\nint doList(Bundle* bundle)\n{\n    int result = 1;\n    ZipFile* zip = NULL;\n    const ZipEntry* entry;\n    long totalUncLen, totalCompLen;\n    const char* zipFileName;\n\n    if (bundle->getFileSpecCount() != 1) {\n        fprintf(stderr, \"ERROR: specify zip file name (only)\\n\");\n        goto bail;\n    }\n    zipFileName = bundle->getFileSpecEntry(0);\n\n    zip = openReadOnly(zipFileName);\n    if (zip == NULL) {\n        goto bail;\n    }\n\n    int count, i;\n\n    if (bundle->getVerbose()) {\n        printf(\"Archive:  %s\\n\", zipFileName);\n        printf(\n            \" Length   Method    Size  Ratio   Offset      Date  Time  CRC-32    Name\\n\");\n        printf(\n            \"--------  ------  ------- -----  -------      ----  ----  ------    ----\\n\");\n    }\n\n    totalUncLen = totalCompLen = 0;\n\n    count = zip->getNumEntries();\n    for (i = 0; i < count; i++) {\n        entry = zip->getEntryByIndex(i);\n        if (bundle->getVerbose()) {\n            char dateBuf[32];\n            time_t when;\n\n            when = entry->getModWhen();\n            strftime(dateBuf, sizeof(dateBuf), \"%m-%d-%y %H:%M\",\n                localtime(&when));\n\n            printf(\"%8ld  %-7.7s %7ld %3d%%  %8zd  %s  %08lx  %s\\n\",\n                (long) entry->getUncompressedLen(),\n                compressionName(entry->getCompressionMethod()),\n                (long) entry->getCompressedLen(),\n                calcPercent(entry->getUncompressedLen(),\n                            entry->getCompressedLen()),\n                (size_t) entry->getLFHOffset(),\n                dateBuf,\n                entry->getCRC32(),\n                entry->getFileName());\n        } else {\n            printf(\"%s\\n\", entry->getFileName());\n        }\n\n        totalUncLen += entry->getUncompressedLen();\n        totalCompLen += entry->getCompressedLen();\n    }\n\n    if (bundle->getVerbose()) {\n        printf(\n        \"--------          -------  ---                            -------\\n\");\n        printf(\"%8ld          %7ld  %2d%%                            %d files\\n\",\n            totalUncLen,\n            totalCompLen,\n            calcPercent(totalUncLen, totalCompLen),\n            zip->getNumEntries());\n    }\n\n    if (bundle->getAndroidList()) {\n        AssetManager assets;\n        if (!assets.addAssetPath(String8(zipFileName), NULL)) {\n            fprintf(stderr, \"ERROR: list -a failed because assets could not be loaded\\n\");\n            goto bail;\n        }\n\n#ifdef __ANDROID__\n        static const bool kHaveAndroidOs = true;\n#else\n        static const bool kHaveAndroidOs = false;\n#endif\n        const ResTable& res = assets.getResources(false);\n        if (!kHaveAndroidOs) {\n            printf(\"\\nResource table:\\n\");\n            res.print(false);\n        }\n\n        Asset* manifestAsset = assets.openNonAsset(\"AndroidManifest.xml\",\n                                                   Asset::ACCESS_BUFFER);\n        if (manifestAsset == NULL) {\n            printf(\"\\nNo AndroidManifest.xml found.\\n\");\n        } else {\n            printf(\"\\nAndroid manifest:\\n\");\n            ResXMLTree tree;\n            tree.setTo(manifestAsset->getBuffer(true),\n                       manifestAsset->getLength());\n            printXMLBlock(&tree);\n        }\n        delete manifestAsset;\n    }\n\n    result = 0;\n\nbail:\n    delete zip;\n    return result;\n}\n\nstatic void printResolvedResourceAttribute(const ResTable& resTable, const ResXMLTree& tree,\n        uint32_t attrRes, String8 attrLabel, String8* outError)\n{\n    Res_value value;\n    AaptXml::getResolvedResourceAttribute(resTable, tree, attrRes, &value, outError);\n    if (*outError != \"\") {\n        *outError = \"error print resolved resource attribute\";\n        return;\n    }\n    if (value.dataType == Res_value::TYPE_STRING) {\n        String8 result = AaptXml::getResolvedAttribute(resTable, tree, attrRes, outError);\n        printf(\"%s='%s'\", attrLabel.string(),\n                ResTable::normalizeForOutput(result.string()).string());\n    } else if (Res_value::TYPE_FIRST_INT <= value.dataType &&\n            value.dataType <= Res_value::TYPE_LAST_INT) {\n        printf(\"%s='%d'\", attrLabel.string(), value.data);\n    } else {\n        printf(\"%s='0x%x'\", attrLabel.string(), (int)value.data);\n    }\n}\n\n// These are attribute resource constants for the platform, as found\n// in android.R.attr\nenum {\n    LABEL_ATTR = 0x01010001,\n    ICON_ATTR = 0x01010002,\n    NAME_ATTR = 0x01010003,\n    PERMISSION_ATTR = 0x01010006,\n    EXPORTED_ATTR = 0x01010010,\n    GRANT_URI_PERMISSIONS_ATTR = 0x0101001b,\n    RESOURCE_ATTR = 0x01010025,\n    DEBUGGABLE_ATTR = 0x0101000f,\n    VALUE_ATTR = 0x01010024,\n    VERSION_CODE_ATTR = 0x0101021b,\n    VERSION_NAME_ATTR = 0x0101021c,\n    SCREEN_ORIENTATION_ATTR = 0x0101001e,\n    MIN_SDK_VERSION_ATTR = 0x0101020c,\n    MAX_SDK_VERSION_ATTR = 0x01010271,\n    REQ_TOUCH_SCREEN_ATTR = 0x01010227,\n    REQ_KEYBOARD_TYPE_ATTR = 0x01010228,\n    REQ_HARD_KEYBOARD_ATTR = 0x01010229,\n    REQ_NAVIGATION_ATTR = 0x0101022a,\n    REQ_FIVE_WAY_NAV_ATTR = 0x01010232,\n    TARGET_SDK_VERSION_ATTR = 0x01010270,\n    TEST_ONLY_ATTR = 0x01010272,\n    ANY_DENSITY_ATTR = 0x0101026c,\n    GL_ES_VERSION_ATTR = 0x01010281,\n    SMALL_SCREEN_ATTR = 0x01010284,\n    NORMAL_SCREEN_ATTR = 0x01010285,\n    LARGE_SCREEN_ATTR = 0x01010286,\n    XLARGE_SCREEN_ATTR = 0x010102bf,\n    REQUIRED_ATTR = 0x0101028e,\n    INSTALL_LOCATION_ATTR = 0x010102b7,\n    SCREEN_SIZE_ATTR = 0x010102ca,\n    SCREEN_DENSITY_ATTR = 0x010102cb,\n    REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364,\n    COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365,\n    LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366,\n    PUBLIC_KEY_ATTR = 0x010103a6,\n    CATEGORY_ATTR = 0x010103e8,\n    BANNER_ATTR = 0x10103f2,\n    ISGAME_ATTR = 0x10103f4,\n};\n\nString8 getComponentName(String8 &pkgName, String8 &componentName) {\n    ssize_t idx = componentName.find(\".\");\n    String8 retStr(pkgName);\n    if (idx == 0) {\n        retStr += componentName;\n    } else if (idx < 0) {\n        retStr += \".\";\n        retStr += componentName;\n    } else {\n        return componentName;\n    }\n    return retStr;\n}\n\nstatic void printCompatibleScreens(ResXMLTree& tree, String8* outError) {\n    size_t len;\n    ResXMLTree::event_code_t code;\n    int depth = 0;\n    bool first = true;\n    printf(\"compatible-screens:\");\n    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::END_TAG) {\n            depth--;\n            if (depth < 0) {\n                break;\n            }\n            continue;\n        }\n        if (code != ResXMLTree::START_TAG) {\n            continue;\n        }\n        depth++;\n        const char16_t* ctag16 = tree.getElementName(&len);\n        if (ctag16 == NULL) {\n            *outError = \"failed to get XML element name (bad string pool)\";\n            return;\n        }\n        String8 tag(ctag16);\n        if (tag == \"screen\") {\n            int32_t screenSize = AaptXml::getIntegerAttribute(tree,\n                    SCREEN_SIZE_ATTR);\n            int32_t screenDensity = AaptXml::getIntegerAttribute(tree,\n                    SCREEN_DENSITY_ATTR);\n            if (screenSize > 0 && screenDensity > 0) {\n                if (!first) {\n                    printf(\",\");\n                }\n                first = false;\n                printf(\"'%d/%d'\", screenSize, screenDensity);\n            }\n        }\n    }\n    printf(\"\\n\");\n}\n\nstatic void printUsesPermission(const String8& name, bool optional=false, int maxSdkVersion=-1) {\n    printf(\"uses-permission: name='%s'\", ResTable::normalizeForOutput(name.string()).string());\n    if (maxSdkVersion != -1) {\n         printf(\" maxSdkVersion='%d'\", maxSdkVersion);\n    }\n    printf(\"\\n\");\n\n    if (optional) {\n        printf(\"optional-permission: name='%s'\",\n                ResTable::normalizeForOutput(name.string()).string());\n        if (maxSdkVersion != -1) {\n            printf(\" maxSdkVersion='%d'\", maxSdkVersion);\n        }\n        printf(\"\\n\");\n    }\n}\n\nstatic void printUsesPermissionSdk23(const String8& name, int maxSdkVersion=-1) {\n    printf(\"uses-permission-sdk-23: \");\n\n    printf(\"name='%s'\", ResTable::normalizeForOutput(name.string()).string());\n    if (maxSdkVersion != -1) {\n        printf(\" maxSdkVersion='%d'\", maxSdkVersion);\n    }\n    printf(\"\\n\");\n}\n\nstatic void printUsesImpliedPermission(const String8& name, const String8& reason) {\n    printf(\"uses-implied-permission: name='%s' reason='%s'\\n\",\n            ResTable::normalizeForOutput(name.string()).string(),\n            ResTable::normalizeForOutput(reason.string()).string());\n}\n\nVector<String8> getNfcAidCategories(AssetManager& assets, String8 xmlPath, bool offHost,\n        String8 *outError = NULL)\n{\n    Asset* aidAsset = assets.openNonAsset(xmlPath, Asset::ACCESS_BUFFER);\n    if (aidAsset == NULL) {\n        if (outError != NULL) *outError = \"xml resource does not exist\";\n        return Vector<String8>();\n    }\n\n    const String8 serviceTagName(offHost ? \"offhost-apdu-service\" : \"host-apdu-service\");\n\n    bool withinApduService = false;\n    Vector<String8> categories;\n\n    String8 error;\n    ResXMLTree tree;\n    tree.setTo(aidAsset->getBuffer(true), aidAsset->getLength());\n\n    size_t len;\n    int depth = 0;\n    ResXMLTree::event_code_t code;\n    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::END_TAG) {\n            depth--;\n            const char16_t* ctag16 = tree.getElementName(&len);\n            if (ctag16 == NULL) {\n                *outError = \"failed to get XML element name (bad string pool)\";\n                return Vector<String8>();\n            }\n            String8 tag(ctag16);\n\n            if (depth == 0 && tag == serviceTagName) {\n                withinApduService = false;\n            }\n\n        } else if (code == ResXMLTree::START_TAG) {\n            depth++;\n            const char16_t* ctag16 = tree.getElementName(&len);\n            if (ctag16 == NULL) {\n                *outError = \"failed to get XML element name (bad string pool)\";\n                return Vector<String8>();\n            }\n            String8 tag(ctag16);\n\n            if (depth == 1) {\n                if (tag == serviceTagName) {\n                    withinApduService = true;\n                }\n            } else if (depth == 2 && withinApduService) {\n                if (tag == \"aid-group\") {\n                    String8 category = AaptXml::getAttribute(tree, CATEGORY_ATTR, &error);\n                    if (error != \"\") {\n                        if (outError != NULL) *outError = error;\n                        return Vector<String8>();\n                    }\n\n                    categories.add(category);\n                }\n            }\n        }\n    }\n    aidAsset->close();\n    return categories;\n}\n\nstatic void printComponentPresence(const char* componentName) {\n    printf(\"provides-component:'%s'\\n\", componentName);\n}\n\n/**\n * Represents a feature that has been automatically added due to\n * a pre-requisite or some other reason.\n */\nstruct ImpliedFeature {\n    ImpliedFeature() : impliedBySdk23(false) {}\n    ImpliedFeature(const String8& n, bool sdk23) : name(n), impliedBySdk23(sdk23) {}\n\n    /**\n     * Name of the implied feature.\n     */\n    String8 name;\n\n    /**\n     * Was this implied by a permission from SDK 23 (<uses-permission-sdk-23 />)?\n     */\n    bool impliedBySdk23;\n\n    /**\n     * List of human-readable reasons for why this feature was implied.\n     */\n    SortedVector<String8> reasons;\n};\n\nstruct Feature {\n    Feature() : required(false), version(-1) {}\n    Feature(bool required, int32_t version = -1) : required(required), version(version) {}\n\n    /**\n     * Whether the feature is required.\n     */\n    bool required;\n\n    /**\n     * What version of the feature is requested.\n     */\n    int32_t version;\n};\n\n/**\n * Represents a <feature-group> tag in the AndroidManifest.xml\n */\nstruct FeatureGroup {\n    FeatureGroup() : openGLESVersion(-1) {}\n\n    /**\n     * Human readable label\n     */\n    String8 label;\n\n    /**\n     * Explicit features defined in the group\n     */\n    KeyedVector<String8, Feature> features;\n\n    /**\n     * OpenGL ES version required\n     */\n    int openGLESVersion;\n};\n\nstatic void addImpliedFeature(KeyedVector<String8, ImpliedFeature>* impliedFeatures,\n                              const char* name, const char* reason, bool sdk23) {\n    String8 name8(name);\n    ssize_t idx = impliedFeatures->indexOfKey(name8);\n    if (idx < 0) {\n        idx = impliedFeatures->add(name8, ImpliedFeature(name8, sdk23));\n    }\n\n    ImpliedFeature* feature = &impliedFeatures->editValueAt(idx);\n\n    // A non-sdk 23 implied feature takes precedence.\n    if (feature->impliedBySdk23 && !sdk23) {\n        feature->impliedBySdk23 = false;\n    }\n    feature->reasons.add(String8(reason));\n}\n\nstatic void printFeatureGroupImpl(const FeatureGroup& grp,\n                                  const KeyedVector<String8, ImpliedFeature>* impliedFeatures) {\n    printf(\"feature-group: label='%s'\\n\", grp.label.string());\n\n    if (grp.openGLESVersion > 0) {\n        printf(\"  uses-gl-es: '0x%x'\\n\", grp.openGLESVersion);\n    }\n\n    const size_t numFeatures = grp.features.size();\n    for (size_t i = 0; i < numFeatures; i++) {\n        const Feature& feature = grp.features[i];\n        const bool required = feature.required;\n        const int32_t version = feature.version;\n\n        const String8& featureName = grp.features.keyAt(i);\n        printf(\"  uses-feature%s: name='%s'\", (required ? \"\" : \"-not-required\"),\n                ResTable::normalizeForOutput(featureName.string()).string());\n\n        if (version > 0) {\n            printf(\" version='%d'\", version);\n        }\n        printf(\"\\n\");\n    }\n\n    const size_t numImpliedFeatures =\n        (impliedFeatures != NULL) ? impliedFeatures->size() : 0;\n    for (size_t i = 0; i < numImpliedFeatures; i++) {\n        const ImpliedFeature& impliedFeature = impliedFeatures->valueAt(i);\n        if (grp.features.indexOfKey(impliedFeature.name) >= 0) {\n            // The feature is explicitly set, no need to use implied\n            // definition.\n            continue;\n        }\n\n        String8 printableFeatureName(ResTable::normalizeForOutput(\n                    impliedFeature.name.string()));\n        const char* sdk23Suffix = impliedFeature.impliedBySdk23 ? \"-sdk-23\" : \"\";\n\n        printf(\"  uses-feature%s: name='%s'\\n\", sdk23Suffix, printableFeatureName.string());\n        printf(\"  uses-implied-feature%s: name='%s' reason='\", sdk23Suffix,\n               printableFeatureName.string());\n        const size_t numReasons = impliedFeature.reasons.size();\n        for (size_t j = 0; j < numReasons; j++) {\n            printf(\"%s\", impliedFeature.reasons[j].string());\n            if (j + 2 < numReasons) {\n                printf(\", \");\n            } else if (j + 1 < numReasons) {\n                printf(\", and \");\n            }\n        }\n        printf(\"'\\n\");\n    }\n}\n\nstatic void printFeatureGroup(const FeatureGroup& grp) {\n    printFeatureGroupImpl(grp, NULL);\n}\n\nstatic void printDefaultFeatureGroup(const FeatureGroup& grp,\n                                     const KeyedVector<String8, ImpliedFeature>& impliedFeatures) {\n    printFeatureGroupImpl(grp, &impliedFeatures);\n}\n\nstatic void addParentFeatures(FeatureGroup* grp, const String8& name) {\n    if (name == \"android.hardware.camera.autofocus\" ||\n            name == \"android.hardware.camera.flash\") {\n        grp->features.add(String8(\"android.hardware.camera\"), Feature(true));\n    } else if (name == \"android.hardware.location.gps\" ||\n            name == \"android.hardware.location.network\") {\n        grp->features.add(String8(\"android.hardware.location\"), Feature(true));\n    } else if (name == \"android.hardware.touchscreen.multitouch\") {\n        grp->features.add(String8(\"android.hardware.touchscreen\"), Feature(true));\n    } else if (name == \"android.hardware.touchscreen.multitouch.distinct\") {\n        grp->features.add(String8(\"android.hardware.touchscreen.multitouch\"), Feature(true));\n        grp->features.add(String8(\"android.hardware.touchscreen\"), Feature(true));\n    } else if (name == \"android.hardware.opengles.aep\") {\n        const int openGLESVersion31 = 0x00030001;\n        if (openGLESVersion31 > grp->openGLESVersion) {\n            grp->openGLESVersion = openGLESVersion31;\n        }\n    }\n}\n\nstatic void addImpliedFeaturesForPermission(const int targetSdk, const String8& name,\n                                            KeyedVector<String8, ImpliedFeature>* impliedFeatures,\n                                            bool impliedBySdk23Permission) {\n    if (name == \"android.permission.CAMERA\") {\n        addImpliedFeature(impliedFeatures, \"android.hardware.camera\",\n                String8::format(\"requested %s permission\", name.string())\n                .string(), impliedBySdk23Permission);\n    } else if (name == \"android.permission.ACCESS_FINE_LOCATION\") {\n        addImpliedFeature(impliedFeatures, \"android.hardware.location.gps\",\n                String8::format(\"requested %s permission\", name.string())\n                .string(), impliedBySdk23Permission);\n        addImpliedFeature(impliedFeatures, \"android.hardware.location\",\n                String8::format(\"requested %s permission\", name.string())\n                .string(), impliedBySdk23Permission);\n    } else if (name == \"android.permission.ACCESS_MOCK_LOCATION\") {\n        addImpliedFeature(impliedFeatures, \"android.hardware.location\",\n                String8::format(\"requested %s permission\", name.string())\n                .string(), impliedBySdk23Permission);\n    } else if (name == \"android.permission.ACCESS_COARSE_LOCATION\") {\n        addImpliedFeature(impliedFeatures, \"android.hardware.location.network\",\n                String8::format(\"requested %s permission\", name.string())\n                .string(), impliedBySdk23Permission);\n        addImpliedFeature(impliedFeatures, \"android.hardware.location\",\n                String8::format(\"requested %s permission\", name.string())\n                .string(), impliedBySdk23Permission);\n    } else if (name == \"android.permission.ACCESS_LOCATION_EXTRA_COMMANDS\" ||\n               name == \"android.permission.INSTALL_LOCATION_PROVIDER\") {\n        addImpliedFeature(impliedFeatures, \"android.hardware.location\",\n                String8::format(\"requested %s permission\", name.string())\n                .string(), impliedBySdk23Permission);\n    } else if (name == \"android.permission.BLUETOOTH\" ||\n               name == \"android.permission.BLUETOOTH_ADMIN\") {\n        if (targetSdk > 4) {\n            addImpliedFeature(impliedFeatures, \"android.hardware.bluetooth\",\n                    String8::format(\"requested %s permission\", name.string())\n                    .string(), impliedBySdk23Permission);\n            addImpliedFeature(impliedFeatures, \"android.hardware.bluetooth\",\n                    \"targetSdkVersion > 4\", impliedBySdk23Permission);\n        }\n    } else if (name == \"android.permission.RECORD_AUDIO\") {\n        addImpliedFeature(impliedFeatures, \"android.hardware.microphone\",\n                String8::format(\"requested %s permission\", name.string())\n                .string(), impliedBySdk23Permission);\n    } else if (name == \"android.permission.ACCESS_WIFI_STATE\" ||\n               name == \"android.permission.CHANGE_WIFI_STATE\" ||\n               name == \"android.permission.CHANGE_WIFI_MULTICAST_STATE\") {\n        addImpliedFeature(impliedFeatures, \"android.hardware.wifi\",\n                String8::format(\"requested %s permission\", name.string())\n                .string(), impliedBySdk23Permission);\n    } else if (name == \"android.permission.CALL_PHONE\" ||\n               name == \"android.permission.CALL_PRIVILEGED\" ||\n               name == \"android.permission.MODIFY_PHONE_STATE\" ||\n               name == \"android.permission.PROCESS_OUTGOING_CALLS\" ||\n               name == \"android.permission.READ_SMS\" ||\n               name == \"android.permission.RECEIVE_SMS\" ||\n               name == \"android.permission.RECEIVE_MMS\" ||\n               name == \"android.permission.RECEIVE_WAP_PUSH\" ||\n               name == \"android.permission.SEND_SMS\" ||\n               name == \"android.permission.WRITE_APN_SETTINGS\" ||\n               name == \"android.permission.WRITE_SMS\") {\n        addImpliedFeature(impliedFeatures, \"android.hardware.telephony\",\n                String8(\"requested a telephony permission\").string(),\n                impliedBySdk23Permission);\n    }\n}\n\n/*\n * Handle the \"dump\" command, to extract select data from an archive.\n */\nextern char CONSOLE_DATA[2925]; // see EOF\nint doDump(Bundle* bundle)\n{\n    status_t result = UNKNOWN_ERROR;\n\n    if (bundle->getFileSpecCount() < 1) {\n        fprintf(stderr, \"ERROR: no dump option specified\\n\");\n        return 1;\n    }\n\n    if (bundle->getFileSpecCount() < 2) {\n        fprintf(stderr, \"ERROR: no dump file specified\\n\");\n        return 1;\n    }\n\n    const char* option = bundle->getFileSpecEntry(0);\n    const char* filename = bundle->getFileSpecEntry(1);\n\n    AssetManager assets;\n    int32_t assetsCookie;\n    if (!assets.addAssetPath(String8(filename), &assetsCookie)) {\n        fprintf(stderr, \"ERROR: dump failed because assets could not be loaded\\n\");\n        return 1;\n    }\n\n    // Make a dummy config for retrieving resources...  we need to supply\n    // non-default values for some configs so that we can retrieve resources\n    // in the app that don't have a default.  The most important of these is\n    // the API version because key resources like icons will have an implicit\n    // version if they are using newer config types like density.\n    ResTable_config config;\n    memset(&config, 0, sizeof(ResTable_config));\n    config.language[0] = 'e';\n    config.language[1] = 'n';\n    config.country[0] = 'U';\n    config.country[1] = 'S';\n    config.orientation = ResTable_config::ORIENTATION_PORT;\n    config.density = ResTable_config::DENSITY_MEDIUM;\n    config.sdkVersion = 10000; // Very high.\n    config.screenWidthDp = 320;\n    config.screenHeightDp = 480;\n    config.smallestScreenWidthDp = 320;\n    config.screenLayout |= ResTable_config::SCREENSIZE_NORMAL;\n    assets.setConfiguration(config);\n\n    const ResTable& res = assets.getResources(false);\n    if (res.getError() != NO_ERROR) {\n        fprintf(stderr, \"ERROR: dump failed because the resource table is invalid/corrupt.\\n\");\n        return 1;\n    }\n\n    // Source for AndroidManifest.xml\n    const String8 manifestFile = String8::format(\"%s@AndroidManifest.xml\", filename);\n\n    // The dynamicRefTable can be null if there are no resources for this asset cookie.\n    // This fine.\n    const DynamicRefTable* dynamicRefTable = res.getDynamicRefTableForCookie(assetsCookie);\n\n    Asset* asset = NULL;\n\n    if (strcmp(\"resources\", option) == 0) {\n#ifndef __ANDROID__\n        res.print(bundle->getValues());\n#endif\n\n    } else if (strcmp(\"strings\", option) == 0) {\n        const ResStringPool* pool = res.getTableStringBlock(0);\n        printStringPool(pool);\n\n    } else if (strcmp(\"xmltree\", option) == 0) {\n        if (bundle->getFileSpecCount() < 3) {\n            fprintf(stderr, \"ERROR: no dump xmltree resource file specified\\n\");\n            goto bail;\n        }\n\n        for (int i=2; i<bundle->getFileSpecCount(); i++) {\n            const char* resname = bundle->getFileSpecEntry(i);\n            ResXMLTree tree(dynamicRefTable);\n            asset = assets.openNonAsset(assetsCookie, resname, Asset::ACCESS_BUFFER);\n            if (asset == NULL) {\n                fprintf(stderr, \"ERROR: dump failed because resource %s found\\n\", resname);\n                goto bail;\n            }\n\n            if (tree.setTo(asset->getBuffer(true),\n                           asset->getLength()) != NO_ERROR) {\n                fprintf(stderr, \"ERROR: Resource %s is corrupt\\n\", resname);\n                goto bail;\n            }\n            tree.restart();\n            printXMLBlock(&tree);\n            tree.uninit();\n            delete asset;\n            asset = NULL;\n        }\n\n    } else if (strcmp(\"xmlstrings\", option) == 0) {\n        if (bundle->getFileSpecCount() < 3) {\n            fprintf(stderr, \"ERROR: no dump xmltree resource file specified\\n\");\n            goto bail;\n        }\n\n        for (int i=2; i<bundle->getFileSpecCount(); i++) {\n            const char* resname = bundle->getFileSpecEntry(i);\n            asset = assets.openNonAsset(assetsCookie, resname, Asset::ACCESS_BUFFER);\n            if (asset == NULL) {\n                fprintf(stderr, \"ERROR: dump failed because resource %s found\\n\", resname);\n                goto bail;\n            }\n\n            ResXMLTree tree(dynamicRefTable);\n            if (tree.setTo(asset->getBuffer(true),\n                           asset->getLength()) != NO_ERROR) {\n                fprintf(stderr, \"ERROR: Resource %s is corrupt\\n\", resname);\n                goto bail;\n            }\n            printStringPool(&tree.getStrings());\n            delete asset;\n            asset = NULL;\n        }\n\n    } else {\n        asset = assets.openNonAsset(assetsCookie, \"AndroidManifest.xml\", Asset::ACCESS_BUFFER);\n        if (asset == NULL) {\n            fprintf(stderr, \"ERROR: dump failed because no AndroidManifest.xml found\\n\");\n            goto bail;\n        }\n\n        ResXMLTree tree(dynamicRefTable);\n        if (tree.setTo(asset->getBuffer(true),\n                       asset->getLength()) != NO_ERROR) {\n            fprintf(stderr, \"ERROR: AndroidManifest.xml is corrupt\\n\");\n            goto bail;\n        }\n        tree.restart();\n\n        if (strcmp(\"permissions\", option) == 0) {\n            size_t len;\n            ResXMLTree::event_code_t code;\n            int depth = 0;\n            while ((code=tree.next()) != ResXMLTree::END_DOCUMENT &&\n                    code != ResXMLTree::BAD_DOCUMENT) {\n                if (code == ResXMLTree::END_TAG) {\n                    depth--;\n                    continue;\n                }\n                if (code != ResXMLTree::START_TAG) {\n                    continue;\n                }\n                depth++;\n                const char16_t* ctag16 = tree.getElementName(&len);\n                if (ctag16 == NULL) {\n                    fprintf(stderr, \"ERROR: failed to get XML element name (bad string pool)\\n\");\n                    goto bail;\n                }\n                String8 tag(ctag16);\n                //printf(\"Depth %d tag %s\\n\", depth, tag.string());\n                if (depth == 1) {\n                    if (tag != \"manifest\") {\n                        fprintf(stderr, \"ERROR: manifest does not start with <manifest> tag\\n\");\n                        goto bail;\n                    }\n                    String8 pkg = AaptXml::getAttribute(tree, NULL, \"package\", NULL);\n                    printf(\"package: %s\\n\", ResTable::normalizeForOutput(pkg.string()).string());\n                } else if (depth == 2) {\n                    if (tag == \"permission\") {\n                        String8 error;\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR: %s\\n\", error.string());\n                            goto bail;\n                        }\n\n                        if (name == \"\") {\n                            fprintf(stderr, \"ERROR: missing 'android:name' for permission\\n\");\n                            goto bail;\n                        }\n                        printf(\"permission: %s\\n\",\n                                ResTable::normalizeForOutput(name.string()).string());\n                    } else if (tag == \"uses-permission\") {\n                        String8 error;\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR: %s\\n\", error.string());\n                            goto bail;\n                        }\n\n                        if (name == \"\") {\n                            fprintf(stderr, \"ERROR: missing 'android:name' for uses-permission\\n\");\n                            goto bail;\n                        }\n                        printUsesPermission(name,\n                                AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1) == 0,\n                                AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR));\n                    } else if (tag == \"uses-permission-sdk-23\" || tag == \"uses-permission-sdk-m\") {\n                        String8 error;\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR: %s\\n\", error.string());\n                            goto bail;\n                        }\n\n                        if (name == \"\") {\n                            fprintf(stderr, \"ERROR: missing 'android:name' for \"\n                                    \"uses-permission-sdk-23\\n\");\n                            goto bail;\n                        }\n                        printUsesPermissionSdk23(\n                                name,\n                                AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR));\n                    }\n                }\n            }\n        } else if (strcmp(\"badging\", option) == 0) {\n            Vector<String8> locales;\n            res.getLocales(&locales);\n\n            Vector<ResTable_config> configs;\n            res.getConfigurations(&configs);\n            SortedVector<int> densities;\n            const size_t NC = configs.size();\n            for (size_t i=0; i<NC; i++) {\n                int dens = configs[i].density;\n                if (dens == 0) {\n                    dens = 160;\n                }\n                densities.add(dens);\n            }\n\n            size_t len;\n            ResXMLTree::event_code_t code;\n            int depth = 0;\n            String8 error;\n            bool withinActivity = false;\n            bool isMainActivity = false;\n            bool isLauncherActivity = false;\n            bool isLeanbackLauncherActivity = false;\n            bool isSearchable = false;\n            bool withinApplication = false;\n            bool withinSupportsInput = false;\n            bool withinFeatureGroup = false;\n            bool withinReceiver = false;\n            bool withinService = false;\n            bool withinProvider = false;\n            bool withinIntentFilter = false;\n            bool hasMainActivity = false;\n            bool hasOtherActivities = false;\n            bool hasOtherReceivers = false;\n            bool hasOtherServices = false;\n            bool hasIntentFilter = false;\n\n            bool hasWallpaperService = false;\n            bool hasImeService = false;\n            bool hasAccessibilityService = false;\n            bool hasPrintService = false;\n            bool hasWidgetReceivers = false;\n            bool hasDeviceAdminReceiver = false;\n            bool hasPaymentService = false;\n            bool hasDocumentsProvider = false;\n            bool hasCameraActivity = false;\n            bool hasCameraSecureActivity = false;\n            bool hasLauncher = false;\n            bool hasNotificationListenerService = false;\n            bool hasDreamService = false;\n\n            bool actMainActivity = false;\n            bool actWidgetReceivers = false;\n            bool actDeviceAdminEnabled = false;\n            bool actImeService = false;\n            bool actWallpaperService = false;\n            bool actAccessibilityService = false;\n            bool actPrintService = false;\n            bool actHostApduService = false;\n            bool actOffHostApduService = false;\n            bool actDocumentsProvider = false;\n            bool actNotificationListenerService = false;\n            bool actDreamService = false;\n            bool actCamera = false;\n            bool actCameraSecure = false;\n            bool catLauncher = false;\n            bool hasMetaHostPaymentCategory = false;\n            bool hasMetaOffHostPaymentCategory = false;\n\n            // These permissions are required by services implementing services\n            // the system binds to (IME, Accessibility, PrintServices, etc.)\n            bool hasBindDeviceAdminPermission = false;\n            bool hasBindInputMethodPermission = false;\n            bool hasBindAccessibilityServicePermission = false;\n            bool hasBindPrintServicePermission = false;\n            bool hasBindNfcServicePermission = false;\n            bool hasRequiredSafAttributes = false;\n            bool hasBindNotificationListenerServicePermission = false;\n            bool hasBindDreamServicePermission = false;\n\n            // These two implement the implicit permissions that are granted\n            // to pre-1.6 applications.\n            bool hasWriteExternalStoragePermission = false;\n            bool hasReadPhoneStatePermission = false;\n\n            // If an app requests write storage, they will also get read storage.\n            bool hasReadExternalStoragePermission = false;\n\n            // Implement transition to read and write call log.\n            bool hasReadContactsPermission = false;\n            bool hasWriteContactsPermission = false;\n            bool hasReadCallLogPermission = false;\n            bool hasWriteCallLogPermission = false;\n\n            // If an app declares itself as multiArch, we report the\n            // native libraries differently.\n            bool hasMultiArch = false;\n\n            // This next group of variables is used to implement a group of\n            // backward-compatibility heuristics necessitated by the addition of\n            // some new uses-feature constants in 2.1 and 2.2. In most cases, the\n            // heuristic is \"if an app requests a permission but doesn't explicitly\n            // request the corresponding <uses-feature>, presume it's there anyway\".\n\n            // 2.2 also added some other features that apps can request, but that\n            // have no corresponding permission, so we cannot implement any\n            // back-compatibility heuristic for them. The below are thus unnecessary\n            // (but are retained here for documentary purposes.)\n            //bool specCompassFeature = false;\n            //bool specAccelerometerFeature = false;\n            //bool specProximityFeature = false;\n            //bool specAmbientLightFeature = false;\n            //bool specLiveWallpaperFeature = false;\n\n            int targetSdk = 0;\n            int smallScreen = 1;\n            int normalScreen = 1;\n            int largeScreen = 1;\n            int xlargeScreen = 1;\n            int anyDensity = 1;\n            int requiresSmallestWidthDp = 0;\n            int compatibleWidthLimitDp = 0;\n            int largestWidthLimitDp = 0;\n            String8 pkg;\n            String8 activityName;\n            String8 activityLabel;\n            String8 activityIcon;\n            String8 activityBanner;\n            String8 receiverName;\n            String8 serviceName;\n            Vector<String8> supportedInput;\n\n            FeatureGroup commonFeatures;\n            Vector<FeatureGroup> featureGroups;\n            KeyedVector<String8, ImpliedFeature> impliedFeatures;\n\n            while ((code=tree.next()) != ResXMLTree::END_DOCUMENT &&\n                    code != ResXMLTree::BAD_DOCUMENT) {\n                if (code == ResXMLTree::END_TAG) {\n                    depth--;\n                    if (depth < 2) {\n                        if (withinSupportsInput && !supportedInput.isEmpty()) {\n                            printf(\"supports-input: '\");\n                            const size_t N = supportedInput.size();\n                            for (size_t i=0; i<N; i++) {\n                                printf(\"%s\", ResTable::normalizeForOutput(\n                                        supportedInput[i].string()).string());\n                                if (i != N - 1) {\n                                    printf(\"' '\");\n                                } else {\n                                    printf(\"'\\n\");\n                                }\n                            }\n                            supportedInput.clear();\n                        }\n                        withinApplication = false;\n                        withinSupportsInput = false;\n                        withinFeatureGroup = false;\n                    } else if (depth < 3) {\n                        if (withinActivity && isMainActivity) {\n                            String8 aName(getComponentName(pkg, activityName));\n                            if (isLauncherActivity) {\n                                printf(\"launchable-activity:\");\n                                if (aName.length() > 0) {\n                                    printf(\" name='%s' \",\n                                            ResTable::normalizeForOutput(aName.string()).string());\n                                }\n                                printf(\" label='%s' icon='%s'\\n\",\n                                       ResTable::normalizeForOutput(activityLabel.string())\n                                                .string(),\n                                       ResTable::normalizeForOutput(activityIcon.string())\n                                                .string());\n                            }\n                            if (isLeanbackLauncherActivity) {\n                                printf(\"leanback-launchable-activity:\");\n                                if (aName.length() > 0) {\n                                    printf(\" name='%s' \",\n                                            ResTable::normalizeForOutput(aName.string()).string());\n                                }\n                                printf(\" label='%s' icon='%s' banner='%s'\\n\",\n                                       ResTable::normalizeForOutput(activityLabel.string())\n                                                .string(),\n                                       ResTable::normalizeForOutput(activityIcon.string())\n                                                .string(),\n                                       ResTable::normalizeForOutput(activityBanner.string())\n                                                .string());\n                            }\n                        }\n                        if (!hasIntentFilter) {\n                            hasOtherActivities |= withinActivity;\n                            hasOtherReceivers |= withinReceiver;\n                            hasOtherServices |= withinService;\n                        } else {\n                            if (withinService) {\n                                hasPaymentService |= (actHostApduService && hasMetaHostPaymentCategory &&\n                                        hasBindNfcServicePermission);\n                                hasPaymentService |= (actOffHostApduService && hasMetaOffHostPaymentCategory &&\n                                        hasBindNfcServicePermission);\n                            }\n                        }\n                        withinActivity = false;\n                        withinService = false;\n                        withinReceiver = false;\n                        withinProvider = false;\n                        hasIntentFilter = false;\n                        isMainActivity = isLauncherActivity = isLeanbackLauncherActivity = false;\n                    } else if (depth < 4) {\n                        if (withinIntentFilter) {\n                            if (withinActivity) {\n                                hasMainActivity |= actMainActivity;\n                                hasLauncher |= catLauncher;\n                                hasCameraActivity |= actCamera;\n                                hasCameraSecureActivity |= actCameraSecure;\n                                hasOtherActivities |=\n                                        !actMainActivity && !actCamera && !actCameraSecure;\n                            } else if (withinReceiver) {\n                                hasWidgetReceivers |= actWidgetReceivers;\n                                hasDeviceAdminReceiver |= (actDeviceAdminEnabled &&\n                                        hasBindDeviceAdminPermission);\n                                hasOtherReceivers |=\n                                        (!actWidgetReceivers && !actDeviceAdminEnabled);\n                            } else if (withinService) {\n                                hasImeService |= actImeService;\n                                hasWallpaperService |= actWallpaperService;\n                                hasAccessibilityService |= (actAccessibilityService &&\n                                        hasBindAccessibilityServicePermission);\n                                hasPrintService |=\n                                        (actPrintService && hasBindPrintServicePermission);\n                                hasNotificationListenerService |= actNotificationListenerService &&\n                                        hasBindNotificationListenerServicePermission;\n                                hasDreamService |= actDreamService && hasBindDreamServicePermission;\n                                hasOtherServices |= (!actImeService && !actWallpaperService &&\n                                        !actAccessibilityService && !actPrintService &&\n                                        !actHostApduService && !actOffHostApduService &&\n                                        !actNotificationListenerService);\n                            } else if (withinProvider) {\n                                hasDocumentsProvider |=\n                                        actDocumentsProvider && hasRequiredSafAttributes;\n                            }\n                        }\n                        withinIntentFilter = false;\n                    }\n                    continue;\n                }\n                if (code != ResXMLTree::START_TAG) {\n                    continue;\n                }\n                depth++;\n\n                const char16_t* ctag16 = tree.getElementName(&len);\n                if (ctag16 == NULL) {\n                    fprintf(stderr, \"ERROR: failed to get XML element name (bad string pool)\\n\");\n                    goto bail;\n                }\n                String8 tag(ctag16);\n                //printf(\"Depth %d,  %s\\n\", depth, tag.string());\n                if (depth == 1) {\n                    if (tag != \"manifest\") {\n                        fprintf(stderr, \"ERROR: manifest does not start with <manifest> tag\\n\");\n                        goto bail;\n                    }\n                    pkg = AaptXml::getAttribute(tree, NULL, \"package\", NULL);\n                    printf(\"package: name='%s' \",\n                            ResTable::normalizeForOutput(pkg.string()).string());\n                    int32_t versionCode = AaptXml::getIntegerAttribute(tree, VERSION_CODE_ATTR,\n                            &error);\n                    if (error != \"\") {\n                        fprintf(stderr, \"ERROR getting 'android:versionCode' attribute: %s\\n\",\n                                error.string());\n                        goto bail;\n                    }\n                    if (versionCode > 0) {\n                        printf(\"versionCode='%d' \", versionCode);\n                    } else {\n                        printf(\"versionCode='' \");\n                    }\n                    String8 versionName = AaptXml::getResolvedAttribute(res, tree,\n                            VERSION_NAME_ATTR, &error);\n                    if (error != \"\") {\n                        fprintf(stderr, \"ERROR getting 'android:versionName' attribute: %s\\n\",\n                                error.string());\n                        goto bail;\n                    }\n                    printf(\"versionName='%s'\",\n                            ResTable::normalizeForOutput(versionName.string()).string());\n\n                    String8 splitName = AaptXml::getAttribute(tree, NULL, \"split\");\n                    if (!splitName.isEmpty()) {\n                        printf(\" split='%s'\", ResTable::normalizeForOutput(\n                                    splitName.string()).string());\n                    }\n\n                    String8 platformVersionName = AaptXml::getAttribute(tree, NULL,\n                            \"platformBuildVersionName\");\n                    printf(\" platformBuildVersionName='%s'\", platformVersionName.string());\n                    printf(\"\\n\");\n\n                    int32_t installLocation = AaptXml::getResolvedIntegerAttribute(res, tree,\n                            INSTALL_LOCATION_ATTR, &error);\n                    if (error != \"\") {\n                        fprintf(stderr, \"ERROR getting 'android:installLocation' attribute: %s\\n\",\n                                error.string());\n                        goto bail;\n                    }\n\n                    if (installLocation >= 0) {\n                        printf(\"install-location:'\");\n                        switch (installLocation) {\n                            case 0:\n                                printf(\"auto\");\n                                break;\n                            case 1:\n                                printf(\"internalOnly\");\n                                break;\n                            case 2:\n                                printf(\"preferExternal\");\n                                break;\n                            default:\n                                fprintf(stderr, \"Invalid installLocation %d\\n\", installLocation);\n                                goto bail;\n                        }\n                        printf(\"'\\n\");\n                    }\n                } else if (depth == 2) {\n                    withinApplication = false;\n                    if (tag == \"application\") {\n                        withinApplication = true;\n\n                        String8 label;\n                        const size_t NL = locales.size();\n                        for (size_t i=0; i<NL; i++) {\n                            const char* localeStr =  locales[i].string();\n                            assets.setLocale(localeStr != NULL ? localeStr : \"\");\n                            String8 llabel = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR,\n                                    &error);\n                            if (llabel != \"\") {\n                                if (localeStr == NULL || strlen(localeStr) == 0) {\n                                    label = llabel;\n                                    printf(\"application-label:'%s'\\n\",\n                                            ResTable::normalizeForOutput(llabel.string()).string());\n                                } else {\n                                    if (label == \"\") {\n                                        label = llabel;\n                                    }\n                                    printf(\"application-label-%s:'%s'\\n\", localeStr,\n                                           ResTable::normalizeForOutput(llabel.string()).string());\n                                }\n                            }\n                        }\n\n                        ResTable_config tmpConfig = config;\n                        const size_t ND = densities.size();\n                        for (size_t i=0; i<ND; i++) {\n                            tmpConfig.density = densities[i];\n                            assets.setConfiguration(tmpConfig);\n                            String8 icon = AaptXml::getResolvedAttribute(res, tree, ICON_ATTR,\n                                    &error);\n                            if (icon != \"\") {\n                                printf(\"application-icon-%d:'%s'\\n\", densities[i],\n                                        ResTable::normalizeForOutput(icon.string()).string());\n                            }\n                        }\n                        assets.setConfiguration(config);\n\n                        String8 icon = AaptXml::getResolvedAttribute(res, tree, ICON_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:icon' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n                        int32_t testOnly = AaptXml::getIntegerAttribute(tree, TEST_ONLY_ATTR, 0,\n                                &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:testOnly' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n\n                        String8 banner = AaptXml::getResolvedAttribute(res, tree, BANNER_ATTR,\n                                                                       &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:banner' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n                        printf(\"application: label='%s' \",\n                                ResTable::normalizeForOutput(label.string()).string());\n                        printf(\"icon='%s'\", ResTable::normalizeForOutput(icon.string()).string());\n                        if (banner != \"\") {\n                            printf(\" banner='%s'\",\n                                   ResTable::normalizeForOutput(banner.string()).string());\n                        }\n                        printf(\"\\n\");\n                        if (testOnly != 0) {\n                            printf(\"testOnly='%d'\\n\", testOnly);\n                        }\n\n                        int32_t isGame = AaptXml::getResolvedIntegerAttribute(res, tree,\n                                ISGAME_ATTR, 0, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:isGame' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n                        if (isGame != 0) {\n                            printf(\"application-isGame\\n\");\n                        }\n\n                        int32_t debuggable = AaptXml::getResolvedIntegerAttribute(res, tree,\n                                DEBUGGABLE_ATTR, 0, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:debuggable' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n                        if (debuggable != 0) {\n                            printf(\"application-debuggable\\n\");\n                        }\n\n                        // We must search by name because the multiArch flag hasn't been API\n                        // frozen yet.\n                        int32_t multiArchIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE,\n                                \"multiArch\");\n                        if (multiArchIndex >= 0) {\n                            Res_value value;\n                            if (tree.getAttributeValue(multiArchIndex, &value) != NO_ERROR) {\n                                if (value.dataType >= Res_value::TYPE_FIRST_INT &&\n                                        value.dataType <= Res_value::TYPE_LAST_INT) {\n                                    hasMultiArch = value.data;\n                                }\n                            }\n                        }\n                    } else if (tag == \"uses-sdk\") {\n                        int32_t code = AaptXml::getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR,\n                                                                    &error);\n                        if (error != \"\") {\n                            error = \"\";\n                            String8 name = AaptXml::getResolvedAttribute(res, tree,\n                                    MIN_SDK_VERSION_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr,\n                                        \"ERROR getting 'android:minSdkVersion' attribute: %s\\n\",\n                                        error.string());\n                                goto bail;\n                            }\n                            if (name == \"Donut\") targetSdk = 4;\n                            printf(\"sdkVersion:'%s'\\n\",\n                                    ResTable::normalizeForOutput(name.string()).string());\n                        } else if (code != -1) {\n                            targetSdk = code;\n                            printf(\"sdkVersion:'%d'\\n\", code);\n                        }\n                        code = AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR);\n                        if (code != -1) {\n                            printf(\"maxSdkVersion:'%d'\\n\", code);\n                        }\n                        code = AaptXml::getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error);\n                        if (error != \"\") {\n                            error = \"\";\n                            String8 name = AaptXml::getResolvedAttribute(res, tree,\n                                    TARGET_SDK_VERSION_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr,\n                                        \"ERROR getting 'android:targetSdkVersion' attribute: %s\\n\",\n                                        error.string());\n                                goto bail;\n                            }\n                            if (name == \"Donut\" && targetSdk < 4) targetSdk = 4;\n                            printf(\"targetSdkVersion:'%s'\\n\",\n                                    ResTable::normalizeForOutput(name.string()).string());\n                        } else if (code != -1) {\n                            if (targetSdk < code) {\n                                targetSdk = code;\n                            }\n                            printf(\"targetSdkVersion:'%d'\\n\", code);\n                        }\n                    } else if (tag == \"uses-configuration\") {\n                        int32_t reqTouchScreen = AaptXml::getIntegerAttribute(tree,\n                                REQ_TOUCH_SCREEN_ATTR, 0);\n                        int32_t reqKeyboardType = AaptXml::getIntegerAttribute(tree,\n                                REQ_KEYBOARD_TYPE_ATTR, 0);\n                        int32_t reqHardKeyboard = AaptXml::getIntegerAttribute(tree,\n                                REQ_HARD_KEYBOARD_ATTR, 0);\n                        int32_t reqNavigation = AaptXml::getIntegerAttribute(tree,\n                                REQ_NAVIGATION_ATTR, 0);\n                        int32_t reqFiveWayNav = AaptXml::getIntegerAttribute(tree,\n                                REQ_FIVE_WAY_NAV_ATTR, 0);\n                        printf(\"uses-configuration:\");\n                        if (reqTouchScreen != 0) {\n                            printf(\" reqTouchScreen='%d'\", reqTouchScreen);\n                        }\n                        if (reqKeyboardType != 0) {\n                            printf(\" reqKeyboardType='%d'\", reqKeyboardType);\n                        }\n                        if (reqHardKeyboard != 0) {\n                            printf(\" reqHardKeyboard='%d'\", reqHardKeyboard);\n                        }\n                        if (reqNavigation != 0) {\n                            printf(\" reqNavigation='%d'\", reqNavigation);\n                        }\n                        if (reqFiveWayNav != 0) {\n                            printf(\" reqFiveWayNav='%d'\", reqFiveWayNav);\n                        }\n                        printf(\"\\n\");\n                    } else if (tag == \"supports-input\") {\n                        withinSupportsInput = true;\n                    } else if (tag == \"supports-screens\") {\n                        smallScreen = AaptXml::getIntegerAttribute(tree,\n                                SMALL_SCREEN_ATTR, 1);\n                        normalScreen = AaptXml::getIntegerAttribute(tree,\n                                NORMAL_SCREEN_ATTR, 1);\n                        largeScreen = AaptXml::getIntegerAttribute(tree,\n                                LARGE_SCREEN_ATTR, 1);\n                        xlargeScreen = AaptXml::getIntegerAttribute(tree,\n                                XLARGE_SCREEN_ATTR, 1);\n                        anyDensity = AaptXml::getIntegerAttribute(tree,\n                                ANY_DENSITY_ATTR, 1);\n                        requiresSmallestWidthDp = AaptXml::getIntegerAttribute(tree,\n                                REQUIRES_SMALLEST_WIDTH_DP_ATTR, 0);\n                        compatibleWidthLimitDp = AaptXml::getIntegerAttribute(tree,\n                                COMPATIBLE_WIDTH_LIMIT_DP_ATTR, 0);\n                        largestWidthLimitDp = AaptXml::getIntegerAttribute(tree,\n                                LARGEST_WIDTH_LIMIT_DP_ATTR, 0);\n                    } else if (tag == \"feature-group\") {\n                        withinFeatureGroup = true;\n                        FeatureGroup group;\n                        group.label = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:label' attribute:\"\n                                    \" %s\\n\", error.string());\n                            goto bail;\n                        }\n                        featureGroups.add(group);\n\n                    } else if (tag == \"uses-feature\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (name != \"\" && error == \"\") {\n                            const char* androidSchema =\n                                    \"http://schemas.android.com/apk/res/android\";\n\n                            int32_t req = AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1,\n                                                                       &error);\n                            if (error != \"\") {\n                                SourcePos(manifestFile, tree.getLineNumber()).error(\n                                        \"failed to read attribute 'android:required': %s\",\n                                        error.string());\n                                goto bail;\n                            }\n\n                            int32_t version = AaptXml::getIntegerAttribute(tree, androidSchema,\n                                                                           \"version\", 0, &error);\n                            if (error != \"\") {\n                                SourcePos(manifestFile, tree.getLineNumber()).error(\n                                        \"failed to read attribute 'android:version': %s\",\n                                        error.string());\n                                goto bail;\n                            }\n\n                            commonFeatures.features.add(name, Feature(req != 0, version));\n                            if (req) {\n                                addParentFeatures(&commonFeatures, name);\n                            }\n                        } else {\n                            int vers = AaptXml::getIntegerAttribute(tree,\n                                    GL_ES_VERSION_ATTR, &error);\n                            if (error == \"\") {\n                                if (vers > commonFeatures.openGLESVersion) {\n                                    commonFeatures.openGLESVersion = vers;\n                                }\n                            }\n                        }\n                    } else if (tag == \"uses-permission\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n\n                        if (name == \"\") {\n                            fprintf(stderr, \"ERROR: missing 'android:name' for uses-permission\\n\");\n                            goto bail;\n                        }\n\n                        addImpliedFeaturesForPermission(targetSdk, name, &impliedFeatures, false);\n\n                        if (name == \"android.permission.WRITE_EXTERNAL_STORAGE\") {\n                            hasWriteExternalStoragePermission = true;\n                        } else if (name == \"android.permission.READ_EXTERNAL_STORAGE\") {\n                            hasReadExternalStoragePermission = true;\n                        } else if (name == \"android.permission.READ_PHONE_STATE\") {\n                            hasReadPhoneStatePermission = true;\n                        } else if (name == \"android.permission.READ_CONTACTS\") {\n                            hasReadContactsPermission = true;\n                        } else if (name == \"android.permission.WRITE_CONTACTS\") {\n                            hasWriteContactsPermission = true;\n                        } else if (name == \"android.permission.READ_CALL_LOG\") {\n                            hasReadCallLogPermission = true;\n                        } else if (name == \"android.permission.WRITE_CALL_LOG\") {\n                            hasWriteCallLogPermission = true;\n                        }\n\n                        printUsesPermission(name,\n                                AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1) == 0,\n                                AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR));\n\n                    } else if (tag == \"uses-permission-sdk-23\" || tag == \"uses-permission-sdk-m\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n\n                        if (name == \"\") {\n                            fprintf(stderr, \"ERROR: missing 'android:name' for \"\n                                    \"uses-permission-sdk-23\\n\");\n                            goto bail;\n                        }\n\n                        addImpliedFeaturesForPermission(targetSdk, name, &impliedFeatures, true);\n\n                        printUsesPermissionSdk23(\n                                name, AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR));\n\n                    } else if (tag == \"uses-package\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (name != \"\" && error == \"\") {\n                            printf(\"uses-package:'%s'\\n\",\n                                    ResTable::normalizeForOutput(name.string()).string());\n                        } else {\n                            fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                    error.string());\n                                goto bail;\n                        }\n                    } else if (tag == \"original-package\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (name != \"\" && error == \"\") {\n                            printf(\"original-package:'%s'\\n\",\n                                    ResTable::normalizeForOutput(name.string()).string());\n                        } else {\n                            fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                    error.string());\n                                goto bail;\n                        }\n                    } else if (tag == \"supports-gl-texture\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (name != \"\" && error == \"\") {\n                            printf(\"supports-gl-texture:'%s'\\n\",\n                                    ResTable::normalizeForOutput(name.string()).string());\n                        } else {\n                            fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                    error.string());\n                                goto bail;\n                        }\n                    } else if (tag == \"compatible-screens\") {\n                        printCompatibleScreens(tree, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting compatible screens: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n                        depth--;\n                    } else if (tag == \"package-verifier\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (name != \"\" && error == \"\") {\n                            String8 publicKey = AaptXml::getAttribute(tree, PUBLIC_KEY_ATTR,\n                                                                      &error);\n                            if (publicKey != \"\" && error == \"\") {\n                                printf(\"package-verifier: name='%s' publicKey='%s'\\n\",\n                                        ResTable::normalizeForOutput(name.string()).string(),\n                                        ResTable::normalizeForOutput(publicKey.string()).string());\n                            }\n                        }\n                    }\n                } else if (depth == 3) {\n                    withinActivity = false;\n                    withinReceiver = false;\n                    withinService = false;\n                    withinProvider = false;\n                    hasIntentFilter = false;\n                    hasMetaHostPaymentCategory = false;\n                    hasMetaOffHostPaymentCategory = false;\n                    hasBindDeviceAdminPermission = false;\n                    hasBindInputMethodPermission = false;\n                    hasBindAccessibilityServicePermission = false;\n                    hasBindPrintServicePermission = false;\n                    hasBindNfcServicePermission = false;\n                    hasRequiredSafAttributes = false;\n                    hasBindNotificationListenerServicePermission = false;\n                    hasBindDreamServicePermission = false;\n                    if (withinApplication) {\n                        if(tag == \"activity\") {\n                            withinActivity = true;\n                            activityName = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                        error.string());\n                                goto bail;\n                            }\n\n                            activityLabel = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR,\n                                    &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:label' attribute: %s\\n\",\n                                        error.string());\n                                goto bail;\n                            }\n\n                            activityIcon = AaptXml::getResolvedAttribute(res, tree, ICON_ATTR,\n                                    &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:icon' attribute: %s\\n\",\n                                        error.string());\n                                goto bail;\n                            }\n\n                            activityBanner = AaptXml::getResolvedAttribute(res, tree, BANNER_ATTR,\n                                    &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:banner' attribute: %s\\n\",\n                                        error.string());\n                                goto bail;\n                            }\n\n                            int32_t orien = AaptXml::getResolvedIntegerAttribute(res, tree,\n                                    SCREEN_ORIENTATION_ATTR, &error);\n                            if (error == \"\") {\n                                if (orien == 0 || orien == 6 || orien == 8) {\n                                    // Requests landscape, sensorLandscape, or reverseLandscape.\n                                    addImpliedFeature(&impliedFeatures,\n                                                      \"android.hardware.screen.landscape\",\n                                                      \"one or more activities have specified a \"\n                                                      \"landscape orientation\",\n                                                      false);\n                                } else if (orien == 1 || orien == 7 || orien == 9) {\n                                    // Requests portrait, sensorPortrait, or reversePortrait.\n                                    addImpliedFeature(&impliedFeatures,\n                                                      \"android.hardware.screen.portrait\",\n                                                      \"one or more activities have specified a \"\n                                                      \"portrait orientation\",\n                                                      false);\n                                }\n                            }\n                        } else if (tag == \"uses-library\") {\n                            String8 libraryName = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr,\n                                        \"ERROR getting 'android:name' attribute for uses-library\"\n                                        \" %s\\n\", error.string());\n                                goto bail;\n                            }\n                            int req = AaptXml::getIntegerAttribute(tree,\n                                    REQUIRED_ATTR, 1);\n                            printf(\"uses-library%s:'%s'\\n\",\n                                    req ? \"\" : \"-not-required\", ResTable::normalizeForOutput(\n                                            libraryName.string()).string());\n                        } else if (tag == \"receiver\") {\n                            withinReceiver = true;\n                            receiverName = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n\n                            if (error != \"\") {\n                                fprintf(stderr,\n                                        \"ERROR getting 'android:name' attribute for receiver:\"\n                                        \" %s\\n\", error.string());\n                                goto bail;\n                            }\n\n                            String8 permission = AaptXml::getAttribute(tree, PERMISSION_ATTR,\n                                    &error);\n                            if (error == \"\") {\n                                if (permission == \"android.permission.BIND_DEVICE_ADMIN\") {\n                                    hasBindDeviceAdminPermission = true;\n                                }\n                            } else {\n                                fprintf(stderr,\n                                        \"ERROR getting 'android:permission' attribute for\"\n                                        \" receiver '%s': %s\\n\",\n                                        receiverName.string(), error.string());\n                            }\n                        } else if (tag == \"service\") {\n                            withinService = true;\n                            serviceName = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:name' attribute for \"\n                                        \"service:%s\\n\", error.string());\n                                goto bail;\n                            }\n\n                            String8 permission = AaptXml::getAttribute(tree, PERMISSION_ATTR,\n                                    &error);\n                            if (error == \"\") {\n                                if (permission == \"android.permission.BIND_INPUT_METHOD\") {\n                                    hasBindInputMethodPermission = true;\n                                } else if (permission ==\n                                        \"android.permission.BIND_ACCESSIBILITY_SERVICE\") {\n                                    hasBindAccessibilityServicePermission = true;\n                                } else if (permission ==\n                                        \"android.permission.BIND_PRINT_SERVICE\") {\n                                    hasBindPrintServicePermission = true;\n                                } else if (permission ==\n                                        \"android.permission.BIND_NFC_SERVICE\") {\n                                    hasBindNfcServicePermission = true;\n                                } else if (permission ==\n                                        \"android.permission.BIND_NOTIFICATION_LISTENER_SERVICE\") {\n                                    hasBindNotificationListenerServicePermission = true;\n                                } else if (permission == \"android.permission.BIND_DREAM_SERVICE\") {\n                                    hasBindDreamServicePermission = true;\n                                }\n                            } else {\n                                fprintf(stderr, \"ERROR getting 'android:permission' attribute for \"\n                                        \"service '%s': %s\\n\", serviceName.string(), error.string());\n                            }\n                        } else if (tag == \"provider\") {\n                            withinProvider = true;\n\n                            bool exported = AaptXml::getResolvedIntegerAttribute(res, tree,\n                                    EXPORTED_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr,\n                                        \"ERROR getting 'android:exported' attribute for provider:\"\n                                        \" %s\\n\", error.string());\n                                goto bail;\n                            }\n\n                            bool grantUriPermissions = AaptXml::getResolvedIntegerAttribute(\n                                    res, tree, GRANT_URI_PERMISSIONS_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr,\n                                        \"ERROR getting 'android:grantUriPermissions' attribute for \"\n                                        \"provider: %s\\n\", error.string());\n                                goto bail;\n                            }\n\n                            String8 permission = AaptXml::getResolvedAttribute(res, tree,\n                                    PERMISSION_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:permission' attribute for \"\n                                        \"provider: %s\\n\", error.string());\n                                goto bail;\n                            }\n\n                            hasRequiredSafAttributes |= exported && grantUriPermissions &&\n                                permission == \"android.permission.MANAGE_DOCUMENTS\";\n\n                        } else if (bundle->getIncludeMetaData() && tag == \"meta-data\") {\n                            String8 metaDataName = AaptXml::getResolvedAttribute(res, tree,\n                                    NAME_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:name' attribute for \"\n                                        \"meta-data:%s\\n\", error.string());\n                                goto bail;\n                            }\n                            printf(\"meta-data: name='%s' \",\n                                    ResTable::normalizeForOutput(metaDataName.string()).string());\n                            printResolvedResourceAttribute(res, tree, VALUE_ATTR, String8(\"value\"),\n                                    &error);\n                            if (error != \"\") {\n                                // Try looking for a RESOURCE_ATTR\n                                error = \"\";\n                                printResolvedResourceAttribute(res, tree, RESOURCE_ATTR,\n                                        String8(\"resource\"), &error);\n                                if (error != \"\") {\n                                    fprintf(stderr, \"ERROR getting 'android:value' or \"\n                                            \"'android:resource' attribute for \"\n                                            \"meta-data:%s\\n\", error.string());\n                                    goto bail;\n                                }\n                            }\n                            printf(\"\\n\");\n                        } else if (withinSupportsInput && tag == \"input-type\") {\n                            String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                            if (name != \"\" && error == \"\") {\n                                supportedInput.add(name);\n                            } else {\n                                fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                        error.string());\n                                goto bail;\n                            }\n                        }\n                    } else if (withinFeatureGroup && tag == \"uses-feature\") {\n                        const String8 androidSchema(\"http://schemas.android.com/apk/res/android\");\n                        FeatureGroup& top = featureGroups.editTop();\n\n                        String8 name = AaptXml::getResolvedAttribute(res, tree, NAME_ATTR, &error);\n                        if (name != \"\" && error == \"\") {\n                            Feature feature(true);\n\n                            int32_t featureVers = AaptXml::getIntegerAttribute(\n                                    tree, androidSchema.string(), \"version\", 0, &error);\n                            if (error == \"\") {\n                                feature.version = featureVers;\n                            } else {\n                                SourcePos(manifestFile, tree.getLineNumber()).error(\n                                        \"failed to read attribute 'android:version': %s\",\n                                        error.string());\n                                goto bail;\n                            }\n\n                            top.features.add(name, feature);\n                            addParentFeatures(&top, name);\n\n                        } else {\n                            int vers = AaptXml::getIntegerAttribute(tree, GL_ES_VERSION_ATTR,\n                                    &error);\n                            if (error == \"\") {\n                                if (vers > top.openGLESVersion) {\n                                    top.openGLESVersion = vers;\n                                }\n                            }\n                        }\n                    }\n                } else if (depth == 4) {\n                    if (tag == \"intent-filter\") {\n                        hasIntentFilter = true;\n                        withinIntentFilter = true;\n                        actMainActivity = false;\n                        actWidgetReceivers = false;\n                        actImeService = false;\n                        actWallpaperService = false;\n                        actAccessibilityService = false;\n                        actPrintService = false;\n                        actDeviceAdminEnabled = false;\n                        actHostApduService = false;\n                        actOffHostApduService = false;\n                        actDocumentsProvider = false;\n                        actNotificationListenerService = false;\n                        actDreamService = false;\n                        actCamera = false;\n                        actCameraSecure = false;\n                        catLauncher = false;\n                    } else if (withinService && tag == \"meta-data\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:name' attribute for \"\n                                    \"meta-data tag in service '%s': %s\\n\", serviceName.string(),\n                                    error.string());\n                            goto bail;\n                        }\n\n                        if (name == \"android.nfc.cardemulation.host_apdu_service\" ||\n                                name == \"android.nfc.cardemulation.off_host_apdu_service\") {\n                            bool offHost = true;\n                            if (name == \"android.nfc.cardemulation.host_apdu_service\") {\n                                offHost = false;\n                            }\n\n                            String8 xmlPath = AaptXml::getResolvedAttribute(res, tree,\n                                    RESOURCE_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:resource' attribute for \"\n                                        \"meta-data tag in service '%s': %s\\n\",\n                                        serviceName.string(), error.string());\n                                goto bail;\n                            }\n\n                            Vector<String8> categories = getNfcAidCategories(assets, xmlPath,\n                                    offHost, &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting AID category for service '%s'\\n\",\n                                        serviceName.string());\n                                goto bail;\n                            }\n\n                            const size_t catLen = categories.size();\n                            for (size_t i = 0; i < catLen; i++) {\n                                bool paymentCategory = (categories[i] == \"payment\");\n                                if (offHost) {\n                                    hasMetaOffHostPaymentCategory |= paymentCategory;\n                                } else {\n                                    hasMetaHostPaymentCategory |= paymentCategory;\n                                }\n                            }\n                        }\n                    }\n                } else if ((depth == 5) && withinIntentFilter) {\n                    String8 action;\n                    if (tag == \"action\") {\n                        action = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n\n                        if (withinActivity) {\n                            if (action == \"android.intent.action.MAIN\") {\n                                isMainActivity = true;\n                                actMainActivity = true;\n                            } else if (action == \"android.media.action.STILL_IMAGE_CAMERA\" ||\n                                    action == \"android.media.action.VIDEO_CAMERA\") {\n                                actCamera = true;\n                            } else if (action == \"android.media.action.STILL_IMAGE_CAMERA_SECURE\") {\n                                actCameraSecure = true;\n                            }\n                        } else if (withinReceiver) {\n                            if (action == \"android.appwidget.action.APPWIDGET_UPDATE\") {\n                                actWidgetReceivers = true;\n                            } else if (action == \"android.app.action.DEVICE_ADMIN_ENABLED\") {\n                                actDeviceAdminEnabled = true;\n                            }\n                        } else if (withinService) {\n                            if (action == \"android.view.InputMethod\") {\n                                actImeService = true;\n                            } else if (action == \"android.service.wallpaper.WallpaperService\") {\n                                actWallpaperService = true;\n                            } else if (action ==\n                                    \"android.accessibilityservice.AccessibilityService\") {\n                                actAccessibilityService = true;\n                            } else if (action ==\"android.printservice.PrintService\") {\n                                actPrintService = true;\n                            } else if (action ==\n                                    \"android.nfc.cardemulation.action.HOST_APDU_SERVICE\") {\n                                actHostApduService = true;\n                            } else if (action ==\n                                    \"android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE\") {\n                                actOffHostApduService = true;\n                            } else if (action ==\n                                    \"android.service.notification.NotificationListenerService\") {\n                                actNotificationListenerService = true;\n                            } else if (action == \"android.service.dreams.DreamService\") {\n                                actDreamService = true;\n                            }\n                        } else if (withinProvider) {\n                            if (action == \"android.content.action.DOCUMENTS_PROVIDER\") {\n                                actDocumentsProvider = true;\n                            }\n                        }\n                        if (action == \"android.intent.action.SEARCH\") {\n                            isSearchable = true;\n                        }\n                    }\n\n                    if (tag == \"category\") {\n                        String8 category = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'name' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n                        if (withinActivity) {\n                            if (category == \"android.intent.category.LAUNCHER\") {\n                                isLauncherActivity = true;\n                            } else if (category == \"android.intent.category.LEANBACK_LAUNCHER\") {\n                                isLeanbackLauncherActivity = true;\n                            } else if (category == \"android.intent.category.HOME\") {\n                                catLauncher = true;\n                            }\n                        }\n                    }\n                }\n            }\n\n            // Pre-1.6 implicitly granted permission compatibility logic\n            if (targetSdk < 4) {\n                if (!hasWriteExternalStoragePermission) {\n                    printUsesPermission(String8(\"android.permission.WRITE_EXTERNAL_STORAGE\"));\n                    printUsesImpliedPermission(String8(\"android.permission.WRITE_EXTERNAL_STORAGE\"),\n                            String8(\"targetSdkVersion < 4\"));\n                    hasWriteExternalStoragePermission = true;\n                }\n                if (!hasReadPhoneStatePermission) {\n                    printUsesPermission(String8(\"android.permission.READ_PHONE_STATE\"));\n                    printUsesImpliedPermission(String8(\"android.permission.READ_PHONE_STATE\"),\n                            String8(\"targetSdkVersion < 4\"));\n                }\n            }\n\n            // If the application has requested WRITE_EXTERNAL_STORAGE, we will\n            // force them to always take READ_EXTERNAL_STORAGE as well.  We always\n            // do this (regardless of target API version) because we can't have\n            // an app with write permission but not read permission.\n            if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) {\n                printUsesPermission(String8(\"android.permission.READ_EXTERNAL_STORAGE\"));\n                printUsesImpliedPermission(String8(\"android.permission.READ_EXTERNAL_STORAGE\"),\n                        String8(\"requested WRITE_EXTERNAL_STORAGE\"));\n            }\n\n            // Pre-JellyBean call log permission compatibility.\n            if (targetSdk < 16) {\n                if (!hasReadCallLogPermission && hasReadContactsPermission) {\n                    printUsesPermission(String8(\"android.permission.READ_CALL_LOG\"));\n                    printUsesImpliedPermission(String8(\"android.permission.READ_CALL_LOG\"),\n                            String8(\"targetSdkVersion < 16 and requested READ_CONTACTS\"));\n                }\n                if (!hasWriteCallLogPermission && hasWriteContactsPermission) {\n                    printUsesPermission(String8(\"android.permission.WRITE_CALL_LOG\"));\n                    printUsesImpliedPermission(String8(\"android.permission.WRITE_CALL_LOG\"),\n                            String8(\"targetSdkVersion < 16 and requested WRITE_CONTACTS\"));\n                }\n            }\n\n            addImpliedFeature(&impliedFeatures, \"android.hardware.touchscreen\",\n                    \"default feature for all apps\", false);\n\n            const size_t numFeatureGroups = featureGroups.size();\n            if (numFeatureGroups == 0) {\n                // If no <feature-group> tags were defined, apply auto-implied features.\n                printDefaultFeatureGroup(commonFeatures, impliedFeatures);\n\n            } else {\n                // <feature-group> tags are defined, so we ignore implied features and\n                for (size_t i = 0; i < numFeatureGroups; i++) {\n                    FeatureGroup& grp = featureGroups.editItemAt(i);\n\n                    if (commonFeatures.openGLESVersion > grp.openGLESVersion) {\n                        grp.openGLESVersion = commonFeatures.openGLESVersion;\n                    }\n\n                    // Merge the features defined in the top level (not inside a <feature-group>)\n                    // with this feature group.\n                    const size_t numCommonFeatures = commonFeatures.features.size();\n                    for (size_t j = 0; j < numCommonFeatures; j++) {\n                        if (grp.features.indexOfKey(commonFeatures.features.keyAt(j)) < 0) {\n                            grp.features.add(commonFeatures.features.keyAt(j),\n                                    commonFeatures.features[j]);\n                        }\n                    }\n\n                    if (!grp.features.isEmpty()) {\n                        printFeatureGroup(grp);\n                    }\n                }\n            }\n\n\n            if (hasWidgetReceivers) {\n                printComponentPresence(\"app-widget\");\n            }\n            if (hasDeviceAdminReceiver) {\n                printComponentPresence(\"device-admin\");\n            }\n            if (hasImeService) {\n                printComponentPresence(\"ime\");\n            }\n            if (hasWallpaperService) {\n                printComponentPresence(\"wallpaper\");\n            }\n            if (hasAccessibilityService) {\n                printComponentPresence(\"accessibility\");\n            }\n            if (hasPrintService) {\n                printComponentPresence(\"print-service\");\n            }\n            if (hasPaymentService) {\n                printComponentPresence(\"payment\");\n            }\n            if (isSearchable) {\n                printComponentPresence(\"search\");\n            }\n            if (hasDocumentsProvider) {\n                printComponentPresence(\"document-provider\");\n            }\n            if (hasLauncher) {\n                printComponentPresence(\"launcher\");\n            }\n            if (hasNotificationListenerService) {\n                printComponentPresence(\"notification-listener\");\n            }\n            if (hasDreamService) {\n                printComponentPresence(\"dream\");\n            }\n            if (hasCameraActivity) {\n                printComponentPresence(\"camera\");\n            }\n            if (hasCameraSecureActivity) {\n                printComponentPresence(\"camera-secure\");\n            }\n\n            if (hasMainActivity) {\n                printf(\"main\\n\");\n            }\n            if (hasOtherActivities) {\n                printf(\"other-activities\\n\");\n            }\n             if (hasOtherReceivers) {\n                printf(\"other-receivers\\n\");\n            }\n            if (hasOtherServices) {\n                printf(\"other-services\\n\");\n            }\n\n            // For modern apps, if screen size buckets haven't been specified\n            // but the new width ranges have, then infer the buckets from them.\n            if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0\n                    && requiresSmallestWidthDp > 0) {\n                int compatWidth = compatibleWidthLimitDp;\n                if (compatWidth <= 0) {\n                    compatWidth = requiresSmallestWidthDp;\n                }\n                if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) {\n                    smallScreen = -1;\n                } else {\n                    smallScreen = 0;\n                }\n                if (requiresSmallestWidthDp <= 320 && compatWidth >= 320) {\n                    normalScreen = -1;\n                } else {\n                    normalScreen = 0;\n                }\n                if (requiresSmallestWidthDp <= 480 && compatWidth >= 480) {\n                    largeScreen = -1;\n                } else {\n                    largeScreen = 0;\n                }\n                if (requiresSmallestWidthDp <= 720 && compatWidth >= 720) {\n                    xlargeScreen = -1;\n                } else {\n                    xlargeScreen = 0;\n                }\n            }\n\n            // Determine default values for any unspecified screen sizes,\n            // based on the target SDK of the package.  As of 4 (donut)\n            // the screen size support was introduced, so all default to\n            // enabled.\n            if (smallScreen > 0) {\n                smallScreen = targetSdk >= 4 ? -1 : 0;\n            }\n            if (normalScreen > 0) {\n                normalScreen = -1;\n            }\n            if (largeScreen > 0) {\n                largeScreen = targetSdk >= 4 ? -1 : 0;\n            }\n            if (xlargeScreen > 0) {\n                // Introduced in Gingerbread.\n                xlargeScreen = targetSdk >= 9 ? -1 : 0;\n            }\n            if (anyDensity > 0) {\n                anyDensity = (targetSdk >= 4 || requiresSmallestWidthDp > 0\n                        || compatibleWidthLimitDp > 0) ? -1 : 0;\n            }\n            printf(\"supports-screens:\");\n            if (smallScreen != 0) {\n                printf(\" 'small'\");\n            }\n            if (normalScreen != 0) {\n                printf(\" 'normal'\");\n            }\n            if (largeScreen != 0) {\n                printf(\" 'large'\");\n            }\n            if (xlargeScreen != 0) {\n                printf(\" 'xlarge'\");\n            }\n            printf(\"\\n\");\n            printf(\"supports-any-density: '%s'\\n\", anyDensity ? \"true\" : \"false\");\n            if (requiresSmallestWidthDp > 0) {\n                printf(\"requires-smallest-width:'%d'\\n\", requiresSmallestWidthDp);\n            }\n            if (compatibleWidthLimitDp > 0) {\n                printf(\"compatible-width-limit:'%d'\\n\", compatibleWidthLimitDp);\n            }\n            if (largestWidthLimitDp > 0) {\n                printf(\"largest-width-limit:'%d'\\n\", largestWidthLimitDp);\n            }\n\n            printf(\"locales:\");\n            const size_t NL = locales.size();\n            for (size_t i=0; i<NL; i++) {\n                const char* localeStr =  locales[i].string();\n                if (localeStr == NULL || strlen(localeStr) == 0) {\n                    localeStr = \"--_--\";\n                }\n                printf(\" '%s'\", localeStr);\n            }\n            printf(\"\\n\");\n\n            printf(\"densities:\");\n            const size_t ND = densities.size();\n            for (size_t i=0; i<ND; i++) {\n                printf(\" '%d'\", densities[i]);\n            }\n            printf(\"\\n\");\n\n            AssetDir* dir = assets.openNonAssetDir(assetsCookie, \"lib\");\n            if (dir != NULL) {\n                if (dir->getFileCount() > 0) {\n                    SortedVector<String8> architectures;\n                    for (size_t i=0; i<dir->getFileCount(); i++) {\n                        architectures.add(ResTable::normalizeForOutput(\n                                dir->getFileName(i).string()));\n                    }\n\n                    bool outputAltNativeCode = false;\n                    // A multiArch package is one that contains 64-bit and\n                    // 32-bit versions of native code and expects 3rd-party\n                    // apps to load these native code libraries. Since most\n                    // 64-bit systems also support 32-bit apps, the apps\n                    // loading this multiArch package's code may be either\n                    // 32-bit or 64-bit.\n                    if (hasMultiArch) {\n                        // If this is a multiArch package, report the 64-bit\n                        // version only. Then as a separate entry, report the\n                        // rest.\n                        //\n                        // If we report the 32-bit architecture, this APK will\n                        // be installed on a 32-bit device, causing a large waste\n                        // of bandwidth and disk space. This assumes that\n                        // the developer of the multiArch package has also\n                        // made a version that is 32-bit only.\n                        String8 intel64(\"x86_64\");\n                        String8 arm64(\"arm64-v8a\");\n                        ssize_t index = architectures.indexOf(intel64);\n                        if (index < 0) {\n                            index = architectures.indexOf(arm64);\n                        }\n\n                        if (index >= 0) {\n                            printf(\"native-code: '%s'\\n\", architectures[index].string());\n                            architectures.removeAt(index);\n                            outputAltNativeCode = true;\n                        }\n                    }\n\n                    const size_t archCount = architectures.size();\n                    if (archCount > 0) {\n                        if (outputAltNativeCode) {\n                            printf(\"alt-\");\n                        }\n                        printf(\"native-code:\");\n                        for (size_t i = 0; i < archCount; i++) {\n                            printf(\" '%s'\", architectures[i].string());\n                        }\n                        printf(\"\\n\");\n                    }\n                }\n                delete dir;\n            }\n        } else if (strcmp(\"badger\", option) == 0) {\n            printf(\"%s\", CONSOLE_DATA);\n        } else if (strcmp(\"configurations\", option) == 0) {\n            Vector<ResTable_config> configs;\n            res.getConfigurations(&configs);\n            const size_t N = configs.size();\n            for (size_t i=0; i<N; i++) {\n                printf(\"%s\\n\", configs[i].toString().string());\n            }\n        } else {\n            fprintf(stderr, \"ERROR: unknown dump option '%s'\\n\", option);\n            goto bail;\n        }\n    }\n\n    result = NO_ERROR;\n\nbail:\n    if (asset) {\n        delete asset;\n    }\n    return (result != NO_ERROR);\n}\n\n\n/*\n * Handle the \"add\" command, which wants to add files to a new or\n * pre-existing archive.\n */\nint doAdd(Bundle* bundle)\n{\n    ZipFile* zip = NULL;\n    status_t result = UNKNOWN_ERROR;\n    const char* zipFileName;\n\n    if (bundle->getUpdate()) {\n        /* avoid confusion */\n        fprintf(stderr, \"ERROR: can't use '-u' with add\\n\");\n        goto bail;\n    }\n\n    if (bundle->getFileSpecCount() < 1) {\n        fprintf(stderr, \"ERROR: must specify zip file name\\n\");\n        goto bail;\n    }\n    zipFileName = bundle->getFileSpecEntry(0);\n\n    if (bundle->getFileSpecCount() < 2) {\n        fprintf(stderr, \"NOTE: nothing to do\\n\");\n        goto bail;\n    }\n\n    zip = openReadWrite(zipFileName, true);\n    if (zip == NULL) {\n        fprintf(stderr, \"ERROR: failed opening/creating '%s' as Zip file\\n\", zipFileName);\n        goto bail;\n    }\n\n    for (int i = 1; i < bundle->getFileSpecCount(); i++) {\n        const char* fileName = bundle->getFileSpecEntry(i);\n\n        if (strcasecmp(String8(fileName).getPathExtension().string(), \".gz\") == 0) {\n            printf(\" '%s'... (from gzip)\\n\", fileName);\n            result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL);\n        } else {\n            if (bundle->getJunkPath()) {\n                String8 storageName = String8(fileName).getPathLeaf();\n                printf(\" '%s' as '%s'...\\n\", fileName,\n                        ResTable::normalizeForOutput(storageName.string()).string());\n                result = zip->add(fileName, storageName.string(),\n                                  bundle->getCompressionMethod(), NULL);\n            } else {\n                printf(\" '%s'...\\n\", fileName);\n                result = zip->add(fileName, bundle->getCompressionMethod(), NULL);\n            }\n        }\n        if (result != NO_ERROR) {\n            fprintf(stderr, \"Unable to add '%s' to '%s'\", bundle->getFileSpecEntry(i), zipFileName);\n            if (result == NAME_NOT_FOUND) {\n                fprintf(stderr, \": file not found\\n\");\n            } else if (result == ALREADY_EXISTS) {\n                fprintf(stderr, \": already exists in archive\\n\");\n            } else {\n                fprintf(stderr, \"\\n\");\n            }\n            goto bail;\n        }\n    }\n\n    result = NO_ERROR;\n\nbail:\n    delete zip;\n    return (result != NO_ERROR);\n}\n\n\n/*\n * Delete files from an existing archive.\n */\nint doRemove(Bundle* bundle)\n{\n    ZipFile* zip = NULL;\n    status_t result = UNKNOWN_ERROR;\n    const char* zipFileName;\n\n    if (bundle->getFileSpecCount() < 1) {\n        fprintf(stderr, \"ERROR: must specify zip file name\\n\");\n        goto bail;\n    }\n    zipFileName = bundle->getFileSpecEntry(0);\n\n    if (bundle->getFileSpecCount() < 2) {\n        fprintf(stderr, \"NOTE: nothing to do\\n\");\n        goto bail;\n    }\n\n    zip = openReadWrite(zipFileName, false);\n    if (zip == NULL) {\n        fprintf(stderr, \"ERROR: failed opening Zip archive '%s'\\n\",\n            zipFileName);\n        goto bail;\n    }\n\n    for (int i = 1; i < bundle->getFileSpecCount(); i++) {\n        const char* fileName = bundle->getFileSpecEntry(i);\n        ZipEntry* entry;\n\n        entry = zip->getEntryByName(fileName);\n        if (entry == NULL) {\n            printf(\" '%s' NOT FOUND\\n\", fileName);\n            continue;\n        }\n\n        result = zip->remove(entry);\n\n        if (result != NO_ERROR) {\n            fprintf(stderr, \"Unable to delete '%s' from '%s'\\n\",\n                bundle->getFileSpecEntry(i), zipFileName);\n            goto bail;\n        }\n    }\n\n    /* update the archive */\n    zip->flush();\n\nbail:\n    delete zip;\n    return (result != NO_ERROR);\n}\n\nstatic status_t addResourcesToBuilder(const sp<AaptDir>& dir, const sp<ApkBuilder>& builder, bool ignoreConfig=false) {\n    const size_t numDirs = dir->getDirs().size();\n    for (size_t i = 0; i < numDirs; i++) {\n        bool ignore = ignoreConfig;\n        const sp<AaptDir>& subDir = dir->getDirs().valueAt(i);\n        const char* dirStr = subDir->getLeaf().string();\n        if (!ignore && strstr(dirStr, \"mipmap\") == dirStr) {\n            ignore = true;\n        }\n        status_t err = addResourcesToBuilder(subDir, builder, ignore);\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    const size_t numFiles = dir->getFiles().size();\n    for (size_t i = 0; i < numFiles; i++) {\n        sp<AaptGroup> gp = dir->getFiles().valueAt(i);\n        const size_t numConfigs = gp->getFiles().size();\n        for (size_t j = 0; j < numConfigs; j++) {\n            status_t err = NO_ERROR;\n            if (ignoreConfig) {\n                err = builder->getBaseSplit()->addEntry(gp->getPath(), gp->getFiles().valueAt(j));\n            } else {\n                err = builder->addEntry(gp->getPath(), gp->getFiles().valueAt(j));\n            }\n            if (err != NO_ERROR) {\n                fprintf(stderr, \"Failed to add %s (%s) to builder.\\n\",\n                        gp->getPath().string(), gp->getFiles()[j]->getPrintableSource().string());\n                return err;\n            }\n        }\n    }\n    return NO_ERROR;\n}\n\nstatic String8 buildApkName(const String8& original, const sp<ApkSplit>& split) {\n    if (split->isBase()) {\n        return original;\n    }\n\n    String8 ext(original.getPathExtension());\n    if (ext == String8(\".apk\")) {\n        return String8::format(\"%s_%s%s\",\n                original.getBasePath().string(),\n                split->getDirectorySafeName().string(),\n                ext.string());\n    }\n\n    return String8::format(\"%s_%s\", original.string(),\n            split->getDirectorySafeName().string());\n}\n\n/*\n * Package up an asset directory and associated application files.\n */\nint doPackage(Bundle* bundle)\n{\n    const char* outputAPKFile;\n    int retVal = 1;\n    status_t err;\n    sp<AaptAssets> assets;\n    int N;\n    FILE* fp;\n    String8 dependencyFile;\n    sp<ApkBuilder> builder;\n\n    // -c en_XA or/and ar_XB means do pseudolocalization\n    sp<WeakResourceFilter> configFilter = new WeakResourceFilter();\n    err = configFilter->parse(bundle->getConfigurations());\n    if (err != NO_ERROR) {\n        goto bail;\n    }\n    if (configFilter->containsPseudo()) {\n        bundle->setPseudolocalize(bundle->getPseudolocalize() | PSEUDO_ACCENTED);\n    }\n    if (configFilter->containsPseudoBidi()) {\n        bundle->setPseudolocalize(bundle->getPseudolocalize() | PSEUDO_BIDI);\n    }\n\n    N = bundle->getFileSpecCount();\n    if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0\n            && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDirs().size() == 0) {\n        fprintf(stderr, \"ERROR: no input files\\n\");\n        goto bail;\n    }\n\n    outputAPKFile = bundle->getOutputAPKFile();\n\n    // Make sure the filenames provided exist and are of the appropriate type.\n    if (outputAPKFile) {\n        FileType type;\n        type = getFileType(outputAPKFile);\n        if (type != kFileTypeNonexistent && type != kFileTypeRegular) {\n            fprintf(stderr,\n                \"ERROR: output file '%s' exists but is not regular file\\n\",\n                outputAPKFile);\n            goto bail;\n        }\n    }\n\n    // Load the assets.\n    assets = new AaptAssets();\n\n    // Set up the resource gathering in assets if we're going to generate\n    // dependency files. Every time we encounter a resource while slurping\n    // the tree, we'll add it to these stores so we have full resource paths\n    // to write to a dependency file.\n    if (bundle->getGenDependencies()) {\n        sp<FilePathStore> resPathStore = new FilePathStore;\n        assets->setFullResPaths(resPathStore);\n        sp<FilePathStore> assetPathStore = new FilePathStore;\n        assets->setFullAssetPaths(assetPathStore);\n    }\n\n    err = assets->slurpFromArgs(bundle);\n    if (err < 0) {\n        goto bail;\n    }\n\n    if (bundle->getVerbose()) {\n        assets->print(String8());\n    }\n\n    // Create the ApkBuilder, which will collect the compiled files\n    // to write to the final APK (or sets of APKs if we are building\n    // a Split APK.\n    builder = new ApkBuilder(configFilter);\n\n    // If we are generating a Split APK, find out which configurations to split on.\n    if (bundle->getSplitConfigurations().size() > 0) {\n        const Vector<String8>& splitStrs = bundle->getSplitConfigurations();\n        const size_t numSplits = splitStrs.size();\n        for (size_t i = 0; i < numSplits; i++) {\n            std::set<ConfigDescription> configs;\n            if (!AaptConfig::parseCommaSeparatedList(splitStrs[i], &configs)) {\n                fprintf(stderr, \"ERROR: failed to parse split configuration '%s'\\n\", splitStrs[i].string());\n                goto bail;\n            }\n\n            err = builder->createSplitForConfigs(configs);\n            if (err != NO_ERROR) {\n                goto bail;\n            }\n        }\n    }\n\n    // If they asked for any fileAs that need to be compiled, do so.\n    if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) {\n        err = buildResources(bundle, assets, builder);\n        if (err != 0) {\n            goto bail;\n        }\n    }\n\n    // At this point we've read everything and processed everything.  From here\n    // on out it's just writing output files.\n    if (SourcePos::hasErrors()) {\n        goto bail;\n    }\n\n    // Update symbols with information about which ones are needed as Java symbols.\n    assets->applyJavaSymbols();\n    if (SourcePos::hasErrors()) {\n        goto bail;\n    }\n\n    // If we've been asked to generate a dependency file, do that here\n    if (bundle->getGenDependencies()) {\n        // If this is the packaging step, generate the dependency file next to\n        // the output apk (e.g. bin/resources.ap_.d)\n        if (outputAPKFile) {\n            dependencyFile = String8(outputAPKFile);\n            // Add the .d extension to the dependency file.\n            dependencyFile.append(\".d\");\n        } else {\n            // Else if this is the R.java dependency generation step,\n            // generate the dependency file in the R.java package subdirectory\n            // e.g. gen/com/foo/app/R.java.d\n            dependencyFile = String8(bundle->getRClassDir());\n            dependencyFile.appendPath(\"R.java.d\");\n        }\n        // Make sure we have a clean dependency file to start with\n        fp = fopen(dependencyFile, \"w\");\n        fclose(fp);\n    }\n\n    // Write out R.java constants\n    if (!assets->havePrivateSymbols()) {\n        if (bundle->getCustomPackage() == NULL) {\n            // Write the R.java file into the appropriate class directory\n            // e.g. gen/com/foo/app/R.java\n            err = writeResourceSymbols(bundle, assets, assets->getPackage(), true,\n                    bundle->getBuildSharedLibrary() || bundle->getBuildAppAsSharedLibrary());\n        } else {\n            const String8 customPkg(bundle->getCustomPackage());\n            err = writeResourceSymbols(bundle, assets, customPkg, true,\n                    bundle->getBuildSharedLibrary() || bundle->getBuildAppAsSharedLibrary());\n        }\n        if (err < 0 && (sktPackageName != NULL)) {\n            err = writeResourceSymbols(bundle, assets, String8(sktPackageName), true,\n                    bundle->getBuildSharedLibrary());\n        }\n        if (err < 0) {\n            goto bail;\n        }\n        // If we have library files, we're going to write our R.java file into\n        // the appropriate class directory for those libraries as well.\n        // e.g. gen/com/foo/app/lib/R.java\n        if (bundle->getExtraPackages() != NULL) {\n            // Split on colon\n            String8 libs(bundle->getExtraPackages());\n            char* packageString = strtok(libs.lockBuffer(libs.length()), \":\");\n            while (packageString != NULL) {\n                // Write the R.java file out with the correct package name\n                err = writeResourceSymbols(bundle, assets, String8(packageString), true,\n                        bundle->getBuildSharedLibrary() || bundle->getBuildAppAsSharedLibrary());\n                if (err < 0) {\n                    goto bail;\n                }\n                packageString = strtok(NULL, \":\");\n            }\n            libs.unlockBuffer();\n        }\n    } else {\n        err = writeResourceSymbols(bundle, assets, assets->getPackage(), false, false);\n        if (err < 0) {\n            goto bail;\n        }\n        err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true, false);\n        if (err < 0) {\n            goto bail;\n        }\n    }\n\n    // Write out the ProGuard file\n    err = writeProguardFile(bundle, assets);\n    if (err < 0) {\n        goto bail;\n    }\n\n    // Write out the Main Dex ProGuard file\n    err = writeMainDexProguardFile(bundle, assets);\n    if (err < 0) {\n        goto bail;\n    }\n\n    // Write the apk\n    if (outputAPKFile) {\n        // Gather all resources and add them to the APK Builder. The builder will then\n        // figure out which Split they belong in.\n        err = addResourcesToBuilder(assets, builder);\n        if (err != NO_ERROR) {\n            goto bail;\n        }\n\n        const Vector<sp<ApkSplit> >& splits = builder->getSplits();\n        const size_t numSplits = splits.size();\n        for (size_t i = 0; i < numSplits; i++) {\n            const sp<ApkSplit>& split = splits[i];\n            String8 outputPath = buildApkName(String8(outputAPKFile), split);\n            err = writeAPK(bundle, outputPath, split);\n            if (err != NO_ERROR) {\n                fprintf(stderr, \"ERROR: packaging of '%s' failed\\n\", outputPath.string());\n                goto bail;\n            }\n        }\n    }\n\n    // If we've been asked to generate a dependency file, we need to finish up here.\n    // the writeResourceSymbols and writeAPK functions have already written the target\n    // half of the dependency file, now we need to write the prerequisites. (files that\n    // the R.java file or .ap_ file depend on)\n    if (bundle->getGenDependencies()) {\n        // Now that writeResourceSymbols or writeAPK has taken care of writing\n        // the targets to our dependency file, we'll write the prereqs\n        fp = fopen(dependencyFile, \"a+\");\n        fprintf(fp, \" : \");\n        bool includeRaw = (outputAPKFile != NULL);\n        err = writeDependencyPreReqs(bundle, assets, fp, includeRaw);\n        // Also manually add the AndroidManifeset since it's not under res/ or assets/\n        // and therefore was not added to our pathstores during slurping\n        fprintf(fp, \"%s \\\\\\n\", bundle->getAndroidManifestFile());\n        fclose(fp);\n    }\n\n    retVal = 0;\nbail:\n    if (SourcePos::hasErrors()) {\n        SourcePos::printErrors(stderr);\n    }\n    return retVal;\n}\n\n/*\n * Do PNG Crunching\n * PRECONDITIONS\n *  -S flag points to a source directory containing drawable* folders\n *  -C flag points to destination directory. The folder structure in the\n *     source directory will be mirrored to the destination (cache) directory\n *\n * POSTCONDITIONS\n *  Destination directory will be updated to match the PNG files in\n *  the source directory.\n */\nint doCrunch(Bundle* bundle)\n{\n    fprintf(stdout, \"Crunching PNG Files in \");\n    fprintf(stdout, \"source dir: %s\\n\", bundle->getResourceSourceDirs()[0]);\n    fprintf(stdout, \"To destination dir: %s\\n\", bundle->getCrunchedOutputDir());\n\n    updatePreProcessedCache(bundle);\n\n    return NO_ERROR;\n}\n\n/*\n * Do PNG Crunching on a single flag\n *  -i points to a single png file\n *  -o points to a single png output file\n */\nint doSingleCrunch(Bundle* bundle)\n{\n    fprintf(stdout, \"Crunching single PNG file: %s\\n\", bundle->getSingleCrunchInputFile());\n    fprintf(stdout, \"\\tOutput file: %s\\n\", bundle->getSingleCrunchOutputFile());\n\n    String8 input(bundle->getSingleCrunchInputFile());\n    String8 output(bundle->getSingleCrunchOutputFile());\n\n    if (preProcessImageToCache(bundle, input, output) != NO_ERROR) {\n        // we can't return the status_t as it gets truncate to the lower 8 bits.\n        return 42;\n    }\n\n    return NO_ERROR;\n}\n\nint runInDaemonMode(Bundle* bundle) {\n    std::cout << \"Ready\" << std::endl;\n    for (std::string cmd; std::getline(std::cin, cmd);) {\n        if (cmd == \"quit\") {\n            return NO_ERROR;\n        } else if (cmd == \"s\") {\n            // Two argument crunch\n            std::string inputFile, outputFile;\n            std::getline(std::cin, inputFile);\n            std::getline(std::cin, outputFile);\n            bundle->setSingleCrunchInputFile(inputFile.c_str());\n            bundle->setSingleCrunchOutputFile(outputFile.c_str());\n            std::cout << \"Crunching \" << inputFile << std::endl;\n            if (doSingleCrunch(bundle) != NO_ERROR) {\n                std::cout << \"Error\" << std::endl;\n            }\n            std::cout << \"Done\" << std::endl;\n        } else {\n            // in case of invalid command, just bail out.\n            std::cerr << \"Unknown command\" << std::endl;\n            return -1;\n        }\n    }\n    return -1;\n}\n\nchar CONSOLE_DATA[2925] = {\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63,\n    86, 35, 40, 46, 46, 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83,\n    62, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 46, 58, 59, 61, 59, 61, 81,\n    81, 81, 81, 66, 96, 61, 61, 58, 46, 46, 46, 58, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81, 81, 81, 102, 59, 61, 59,\n    59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59,\n    59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59, 46, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87,\n    58, 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46,\n    47, 61, 59, 59, 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58,\n    121, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81,\n    81, 81, 81, 109, 58, 59, 59, 59, 59, 61, 109, 81, 81, 76, 46, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81, 81, 81, 81, 81, 59, 61, 59,\n    59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 81, 91, 59,\n    59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81, 81, 76, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81,\n    70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 93, 40, 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81,\n    81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 46, 46, 46, 32, 46, 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109,\n    81, 81, 81, 87, 46, 58, 61, 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,\n    32, 32, 32, 32, 32, 32, 32, 46, 46, 61, 59, 61, 61, 61, 59, 61, 61, 59,\n    59, 59, 58, 58, 46, 46, 41, 58, 59, 58, 81, 81, 81, 81, 69, 58, 59, 59,\n    60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 58, 59,\n    61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 46,\n    61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68, 96, 32, 32, 32,\n    46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59,\n    59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36, 81,\n    109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81,\n    67, 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,\n    59, 59, 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58,\n    61, 59, 59, 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59,\n    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37,\n    73, 108, 108, 62, 52, 81, 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59,\n    59, 61, 59, 61, 61, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10,\n    32, 46, 45, 57, 101, 43, 43, 61, 61, 59, 59, 59, 59, 59, 59, 61, 59, 59,\n    59, 59, 59, 59, 59, 59, 59, 58, 97, 46, 61, 108, 62, 126, 58, 106, 80, 96,\n    46, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61,\n    97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 45, 46, 32,\n    46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 58, 59, 59, 59, 59, 61,\n    119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61, 58, 59, 59, 59,\n    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81, 99, 32, 32,\n    32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119,\n    119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59,\n    59, 59, 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 61, 58, 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81,\n    81, 58, 59, 59, 59, 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41,\n    87, 66, 33, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81,\n    81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58,\n    45, 32, 46, 32, 32, 32, 32, 32, 46, 32, 126, 96, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81,\n    81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58,\n    59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58,\n    59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81,\n    81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,\n    81, 81, 40, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106,\n    81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59,\n    32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 61, 58, 58, 81, 81, 81, 81, 81, 81, 81, 81,\n    81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 59,\n    61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81, 81,\n    81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81,\n    81, 102, 94, 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59,\n    59, 59, 43, 63, 36, 81, 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59,\n    59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 43, 33,\n    58, 126, 126, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46,\n    61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61, 59, 59, 59, 59, 59,\n    59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 58, 95,\n    32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59, 59,\n    61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45,\n    59, 58, 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59,\n    59, 59, 59, 59, 59, 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59,\n    59, 59, 59, 59, 59, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 45, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 58, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 61,\n    46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59,\n    59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59, 59, 59,\n    59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32,\n    32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61,\n    59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59,\n    59, 59, 59, 58, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 61, 59, 58, 45, 45, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10\n  };\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/ConfigDescription.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CONFIG_DESCRIPTION_H\n#define __CONFIG_DESCRIPTION_H\n\n#include <androidfw/ResourceTypes.h>\n\n/**\n * Subclass of ResTable_config that adds convenient\n * initialization and comparison methods.\n */\nstruct ConfigDescription : public android::ResTable_config {\n    ConfigDescription() {\n        memset(this, 0, sizeof(*this));\n        size = sizeof(android::ResTable_config);\n    }\n\n    ConfigDescription(const android::ResTable_config&o) {\n        *static_cast<android::ResTable_config*>(this) = o;\n        size = sizeof(android::ResTable_config);\n    }\n\n    ConfigDescription(const ConfigDescription&o) {\n        *static_cast<android::ResTable_config*>(this) = o;\n    }\n\n    ConfigDescription& operator=(const android::ResTable_config& o) {\n        *static_cast<android::ResTable_config*>(this) = o;\n        size = sizeof(android::ResTable_config);\n        return *this;\n    }\n\n    ConfigDescription& operator=(const ConfigDescription& o) {\n        *static_cast<android::ResTable_config*>(this) = o;\n        return *this;\n    }\n\n    inline bool operator<(const ConfigDescription& o) const { return compare(o) < 0; }\n    inline bool operator<=(const ConfigDescription& o) const { return compare(o) <= 0; }\n    inline bool operator==(const ConfigDescription& o) const { return compare(o) == 0; }\n    inline bool operator!=(const ConfigDescription& o) const { return compare(o) != 0; }\n    inline bool operator>=(const ConfigDescription& o) const { return compare(o) >= 0; }\n    inline bool operator>(const ConfigDescription& o) const { return compare(o) > 0; }\n};\n\n#endif // __CONFIG_DESCRIPTION_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/CrunchCache.cpp",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n// Implementation file for CrunchCache\n// This file defines functions laid out and documented in\n// CrunchCache.h\n\n#include <utils/Compat.h>\n#include <utils/Vector.h>\n#include <utils/String8.h>\n\n#include \"DirectoryWalker.h\"\n#include \"FileFinder.h\"\n#include \"CacheUpdater.h\"\n#include \"CrunchCache.h\"\n\nusing namespace android;\n\nCrunchCache::CrunchCache(String8 sourcePath, String8 destPath, FileFinder* ff)\n    : mSourcePath(sourcePath), mDestPath(destPath), mSourceFiles(0), mDestFiles(0), mFileFinder(ff)\n{\n    // We initialize the default value to return to 0 so if a file doesn't exist\n    // then all files are automatically \"newer\" than it.\n\n    // Set file extensions to look for. Right now just pngs.\n    mExtensions.push(String8(\".png\"));\n\n    // Load files into our data members\n    loadFiles();\n}\n\nsize_t CrunchCache::crunch(CacheUpdater* cu, bool forceOverwrite)\n{\n    size_t numFilesUpdated = 0;\n\n    // Iterate through the source files and compare to cache.\n    // After processing a file, remove it from the source files and\n    // from the dest files.\n    // We're done when we're out of files in source.\n    String8 relativePath;\n    while (mSourceFiles.size() > 0) {\n        // Get the full path to the source file, then convert to a c-string\n        // and offset our beginning pointer to the length of the sourcePath\n        // This efficiently strips the source directory prefix from our path.\n        // Also, String8 doesn't have a substring method so this is what we've\n        // got to work with.\n        const char* rPathPtr = mSourceFiles.keyAt(0).string()+mSourcePath.length();\n        // Strip leading slash if present\n        int offset = 0;\n        if (rPathPtr[0] == OS_PATH_SEPARATOR)\n            offset = 1;\n        relativePath = String8(rPathPtr + offset);\n\n        if (forceOverwrite || needsUpdating(relativePath)) {\n            cu->processImage(mSourcePath.appendPathCopy(relativePath),\n                             mDestPath.appendPathCopy(relativePath));\n            numFilesUpdated++;\n            // crunchFile(relativePath);\n        }\n        // Delete this file from the source files and (if it exists) from the\n        // dest files.\n        mSourceFiles.removeItemsAt(0);\n        mDestFiles.removeItem(mDestPath.appendPathCopy(relativePath));\n    }\n\n    // Iterate through what's left of destFiles and delete leftovers\n    while (mDestFiles.size() > 0) {\n        cu->deleteFile(mDestFiles.keyAt(0));\n        mDestFiles.removeItemsAt(0);\n    }\n\n    // Update our knowledge of the files cache\n    // both source and dest should be empty by now.\n    loadFiles();\n\n    return numFilesUpdated;\n}\n\nvoid CrunchCache::loadFiles()\n{\n    // Clear out our data structures to avoid putting in duplicates\n    mSourceFiles.clear();\n    mDestFiles.clear();\n\n    // Make a directory walker that points to the system.\n    DirectoryWalker* dw = new SystemDirectoryWalker();\n\n    // Load files in the source directory\n    mFileFinder->findFiles(mSourcePath, mExtensions, mSourceFiles,dw);\n\n    // Load files in the destination directory\n    mFileFinder->findFiles(mDestPath,mExtensions,mDestFiles,dw);\n\n    delete dw;\n}\n\nbool CrunchCache::needsUpdating(String8 relativePath) const\n{\n    // Retrieve modification dates for this file entry under the source and\n    // cache directory trees. The vectors will return a modification date of 0\n    // if the file doesn't exist.\n    time_t sourceDate = mSourceFiles.valueFor(mSourcePath.appendPathCopy(relativePath));\n    time_t destDate = mDestFiles.valueFor(mDestPath.appendPathCopy(relativePath));\n    return sourceDate > destDate;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/CrunchCache.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n// Cache manager for pre-processed PNG files.\n// Contains code for managing which PNG files get processed\n// at build time.\n//\n\n#ifndef CRUNCHCACHE_H\n#define CRUNCHCACHE_H\n\n#include <utils/KeyedVector.h>\n#include <utils/String8.h>\n#include \"FileFinder.h\"\n#include \"CacheUpdater.h\"\n\nusing namespace android;\n\n/** CrunchCache\n *  This class is a cache manager which can pre-process PNG files and store\n *  them in a mirror-cache. It's capable of doing incremental updates to its\n *  cache.\n *\n *  Usage:\n *      Create an instance initialized with the root of the source tree, the\n *      root location to store the cache files, and an instance of a file finder.\n *      Then update the cache by calling crunch.\n */\nclass CrunchCache {\npublic:\n    // Constructor\n    CrunchCache(String8 sourcePath, String8 destPath, FileFinder* ff);\n\n    // Nobody should be calling the default constructor\n    // So this space is intentionally left blank\n\n    // Default Copy Constructor and Destructor are fine\n\n    /** crunch is the workhorse of this class.\n     * It goes through all the files found in the sourcePath and compares\n     * them to the cached versions in the destPath. If the optional\n     * argument forceOverwrite is set to true, then all source files are\n     * re-crunched even if they have not been modified recently. Otherwise,\n     * source files are only crunched when they needUpdating. Afterwards,\n     * we delete any leftover files in the cache that are no longer present\n     * in source.\n     *\n     * PRECONDITIONS:\n     *      No setup besides construction is needed\n     * POSTCONDITIONS:\n     *      The cache is updated to fully reflect all changes in source.\n     *      The function then returns the number of files changed in cache\n     *      (counting deletions).\n     */\n    size_t crunch(CacheUpdater* cu, bool forceOverwrite=false);\n\nprivate:\n    /** loadFiles is a wrapper to the FileFinder that places matching\n     * files into mSourceFiles and mDestFiles.\n     *\n     *  POSTCONDITIONS\n     *      mDestFiles and mSourceFiles are refreshed to reflect the current\n     *      state of the files in the source and dest directories.\n     *      Any previous contents of mSourceFiles and mDestFiles are cleared.\n     */\n    void loadFiles();\n\n    /** needsUpdating takes a file path\n     * and returns true if the file represented by this path is newer in the\n     * sourceFiles than in the cache (mDestFiles).\n     *\n     * PRECONDITIONS:\n     *      mSourceFiles and mDestFiles must be initialized and filled.\n     * POSTCONDITIONS:\n     *      returns true if and only if source file's modification time\n     *      is greater than the cached file's mod-time. Otherwise returns false.\n     *\n     * USAGE:\n     *      Should be used something like the following:\n     *      if (needsUpdating(filePath))\n     *          // Recrunch sourceFile out to destFile.\n     *\n     */\n    bool needsUpdating(String8 relativePath) const;\n\n    // DATA MEMBERS ====================================================\n\n    String8 mSourcePath;\n    String8 mDestPath;\n\n    Vector<String8> mExtensions;\n\n    // Each vector of paths contains one entry per PNG file encountered.\n    // Each entry consists of a path pointing to that PNG.\n    DefaultKeyedVector<String8,time_t> mSourceFiles;\n    DefaultKeyedVector<String8,time_t> mDestFiles;\n\n    // Pointer to a FileFinder to use\n    FileFinder* mFileFinder;\n};\n\n#endif // CRUNCHCACHE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/DirectoryWalker.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n// Defines an abstraction for opening a directory on the filesystem and\n// iterating through it.\n\n#ifndef DIRECTORYWALKER_H\n#define DIRECTORYWALKER_H\n\n#include <dirent.h>\n#include <sys/types.h>\n#include <sys/param.h>\n#include <sys/stat.h>\n#include <unistd.h>\n#include <utils/String8.h>\n\n#include <stdio.h>\n\nusing namespace android;\n\n// Directory Walker\n// This is an abstraction for walking through a directory and getting files\n// and descriptions.\n\nclass DirectoryWalker {\npublic:\n    virtual ~DirectoryWalker() {};\n    virtual bool openDir(String8 path) = 0;\n    virtual bool openDir(const char* path) = 0;\n    // Advance to next directory entry\n    virtual struct dirent* nextEntry() = 0;\n    // Get the stats for the current entry\n    virtual struct stat*   entryStats() = 0;\n    // Clean Up\n    virtual void closeDir() = 0;\n    // This class is able to replicate itself on the heap\n    virtual DirectoryWalker* clone() = 0;\n\n    // DATA MEMBERS\n    // Current directory entry\n    struct dirent mEntry;\n    // Stats for that directory entry\n    struct stat mStats;\n    // Base path\n    String8 mBasePath;\n};\n\n// System Directory Walker\n// This is an implementation of the above abstraction that calls\n// real system calls and is fully functional.\n// functions are inlined since they're very short and simple\n\nclass SystemDirectoryWalker : public DirectoryWalker {\n\n    // Default constructor, copy constructor, and destructor are fine\npublic:\n    virtual bool openDir(String8 path) {\n        mBasePath = path;\n        dir = NULL;\n        dir = opendir(mBasePath.string() );\n\n        if (dir == NULL)\n            return false;\n\n        return true;\n    };\n    virtual bool openDir(const char* path) {\n        String8 p(path);\n        openDir(p);\n        return true;\n    };\n    // Advance to next directory entry\n    virtual struct dirent* nextEntry() {\n        struct dirent* entryPtr = readdir(dir);\n        if (entryPtr == NULL)\n            return NULL;\n\n        mEntry = *entryPtr;\n        // Get stats\n        String8 fullPath = mBasePath.appendPathCopy(mEntry.d_name);\n        stat(fullPath.string(),&mStats);\n        return &mEntry;\n    };\n    // Get the stats for the current entry\n    virtual struct stat*   entryStats() {\n        return &mStats;\n    };\n    virtual void closeDir() {\n        closedir(dir);\n    };\n    virtual DirectoryWalker* clone() {\n        return new SystemDirectoryWalker(*this);\n    };\nprivate:\n    DIR* dir;\n};\n\n#endif // DIRECTORYWALKER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/FileFinder.cpp",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n\n// File Finder implementation.\n// Implementation for the functions declared and documented in FileFinder.h\n\n#include <utils/Vector.h>\n#include <utils/String8.h>\n#include <utils/KeyedVector.h>\n\n#include <dirent.h>\n#include <sys/stat.h>\n\n#include \"DirectoryWalker.h\"\n#include \"FileFinder.h\"\n\n//#define DEBUG\n\nusing android::String8;\n\n// Private function to check whether a file is a directory or not\nbool isDirectory(const char* filename) {\n    struct stat fileStat;\n    if (stat(filename, &fileStat) == -1) {\n        return false;\n    }\n    return(S_ISDIR(fileStat.st_mode));\n}\n\n\n// Private function to check whether a file is a regular file or not\nbool isFile(const char* filename) {\n    struct stat fileStat;\n    if (stat(filename, &fileStat) == -1) {\n        return false;\n    }\n    return(S_ISREG(fileStat.st_mode));\n}\n\nbool SystemFileFinder::findFiles(String8 basePath, Vector<String8>& extensions,\n                                 KeyedVector<String8,time_t>& fileStore,\n                                 DirectoryWalker* dw)\n{\n    // Scan the directory pointed to by basePath\n    // check files and recurse into subdirectories.\n    if (!dw->openDir(basePath)) {\n        return false;\n    }\n    /*\n     *  Go through all directory entries. Check each file using checkAndAddFile\n     *  and recurse into sub-directories.\n     */\n    struct dirent* entry;\n    while ((entry = dw->nextEntry()) != NULL) {\n        String8 entryName(entry->d_name);\n        if (entry->d_name[0] == '.') // Skip hidden files and directories\n            continue;\n\n        String8 fullPath = basePath.appendPathCopy(entryName);\n        // If this entry is a directory we'll recurse into it\n        if (isDirectory(fullPath.string()) ) {\n            DirectoryWalker* copy = dw->clone();\n            findFiles(fullPath, extensions, fileStore,copy);\n            delete copy;\n        }\n\n        // If this entry is a file, we'll pass it over to checkAndAddFile\n        if (isFile(fullPath.string()) ) {\n            checkAndAddFile(fullPath,dw->entryStats(),extensions,fileStore);\n        }\n    }\n\n    // Clean up\n    dw->closeDir();\n\n    return true;\n}\n\nvoid SystemFileFinder::checkAndAddFile(String8 path, const struct stat* stats,\n                                       Vector<String8>& extensions,\n                                       KeyedVector<String8,time_t>& fileStore)\n{\n    // Loop over the extensions, checking for a match\n    bool done = false;\n    String8 ext(path.getPathExtension());\n    ext.toLower();\n    for (size_t i = 0; i < extensions.size() && !done; ++i) {\n        String8 ext2 = extensions[i].getPathExtension();\n        ext2.toLower();\n        // Compare the extensions. If a match is found, add to storage.\n        if (ext == ext2) {\n            done = true;\n            fileStore.add(path,stats->st_mtime);\n        }\n    }\n}\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/FileFinder.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n\n// File Finder.\n// This is a collection of useful functions for finding paths and modification\n// times of files that match an extension pattern in a directory tree.\n// and finding files in it.\n\n#ifndef FILEFINDER_H\n#define FILEFINDER_H\n\n#include <utils/Vector.h>\n#include <utils/KeyedVector.h>\n#include <utils/String8.h>\n\n#include \"DirectoryWalker.h\"\n\nusing namespace android;\n\n// Abstraction to allow for dependency injection. See MockFileFinder.h\n// for the testing implementation.\nclass FileFinder {\npublic:\n    virtual bool findFiles(String8 basePath, Vector<String8>& extensions,\n                           KeyedVector<String8,time_t>& fileStore,\n                           DirectoryWalker* dw) = 0;\n\n    virtual ~FileFinder() {};\n};\n\nclass SystemFileFinder : public FileFinder {\npublic:\n\n    /* findFiles takes a path, a Vector of extensions, and a destination KeyedVector\n     *           and places path/modification date key/values pointing to\n     *          all files with matching extensions found into the KeyedVector\n     * PRECONDITIONS\n     *     path is a valid system path\n     *     extensions should include leading \".\"\n     *                This is not necessary, but the comparison directly\n     *                compares the end of the path string so if the \".\"\n     *                is excluded there is a small chance you could have\n     *                a false positive match. (For example: extension \"png\"\n     *                would match a file called \"blahblahpng\")\n     *\n     * POSTCONDITIONS\n     *     fileStore contains (in no guaranteed order) paths to all\n     *                matching files encountered in subdirectories of path\n     *                as keys in the KeyedVector. Each key has the modification time\n     *                of the file as its value.\n     *\n     * Calls checkAndAddFile on each file encountered in the directory tree\n     * Recursively descends into subdirectories.\n     */\n    virtual bool findFiles(String8 basePath, Vector<String8>& extensions,\n                           KeyedVector<String8,time_t>& fileStore,\n                           DirectoryWalker* dw);\n\nprivate:\n    /**\n     * checkAndAddFile looks at a single file path and stat combo\n     * to determine whether it is a matching file (by looking at\n     * the extension)\n     *\n     * PRECONDITIONS\n     *    no setup is needed\n     *\n     * POSTCONDITIONS\n     *    If the given file has a matching extension then a new entry\n     *    is added to the KeyedVector with the path as the key and the modification\n     *    time as the value.\n     *\n     */\n    static void checkAndAddFile(String8 path, const struct stat* stats,\n                                Vector<String8>& extensions,\n                                KeyedVector<String8,time_t>& fileStore);\n\n};\n#endif // FILEFINDER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/Images.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#define PNG_INTERNAL\n\n#include \"Images.h\"\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/ByteOrder.h>\n\n#include <png.h>\n#include <zlib.h>\n\n// Change this to true for noisy debug output.\nstatic const bool kIsDebug = false;\n\nstatic void\npng_write_aapt_file(png_structp png_ptr, png_bytep data, png_size_t length)\n{\n    AaptFile* aaptfile = (AaptFile*) png_get_io_ptr(png_ptr);\n    status_t err = aaptfile->writeData(data, length);\n    if (err != NO_ERROR) {\n        png_error(png_ptr, \"Write Error\");\n    }\n}\n\n\nstatic void\npng_flush_aapt_file(png_structp /* png_ptr */)\n{\n}\n\n// This holds an image as 8bpp RGBA.\nstruct image_info\n{\n    image_info() : rows(NULL), is9Patch(false),\n        xDivs(NULL), yDivs(NULL), colors(NULL), allocRows(NULL) { }\n\n    ~image_info() {\n        if (rows && rows != allocRows) {\n            free(rows);\n        }\n        if (allocRows) {\n            for (int i=0; i<(int)allocHeight; i++) {\n                free(allocRows[i]);\n            }\n            free(allocRows);\n        }\n        free(xDivs);\n        free(yDivs);\n        free(colors);\n    }\n\n    void* serialize9patch() {\n        void* serialized = Res_png_9patch::serialize(info9Patch, xDivs, yDivs, colors);\n        reinterpret_cast<Res_png_9patch*>(serialized)->deviceToFile();\n        return serialized;\n    }\n\n    png_uint_32 width;\n    png_uint_32 height;\n    png_bytepp rows;\n\n    // 9-patch info.\n    bool is9Patch;\n    Res_png_9patch info9Patch;\n    int32_t* xDivs;\n    int32_t* yDivs;\n    uint32_t* colors;\n\n    // Layout padding, if relevant\n    bool haveLayoutBounds;\n    int32_t layoutBoundsLeft;\n    int32_t layoutBoundsTop;\n    int32_t layoutBoundsRight;\n    int32_t layoutBoundsBottom;\n\n    // Round rect outline description\n    int32_t outlineInsetsLeft;\n    int32_t outlineInsetsTop;\n    int32_t outlineInsetsRight;\n    int32_t outlineInsetsBottom;\n    float outlineRadius;\n    uint8_t outlineAlpha;\n\n    png_uint_32 allocHeight;\n    png_bytepp allocRows;\n};\n\nstatic void log_warning(png_structp png_ptr, png_const_charp warning_message)\n{\n    const char* imageName = (const char*) png_get_error_ptr(png_ptr);\n    fprintf(stderr, \"%s: libpng warning: %s\\n\", imageName, warning_message);\n}\n\nstatic void read_png(const char* imageName,\n                     png_structp read_ptr, png_infop read_info,\n                     image_info* outImageInfo)\n{\n    int color_type;\n    int bit_depth, interlace_type, compression_type;\n    int i;\n\n    png_set_error_fn(read_ptr, const_cast<char*>(imageName),\n            NULL /* use default errorfn */, log_warning);\n    png_read_info(read_ptr, read_info);\n\n    png_get_IHDR(read_ptr, read_info, &outImageInfo->width,\n       &outImageInfo->height, &bit_depth, &color_type,\n       &interlace_type, &compression_type, NULL);\n\n    //printf(\"Image %s:\\n\", imageName);\n    //printf(\"color_type=%d, bit_depth=%d, interlace_type=%d, compression_type=%d\\n\",\n    //       color_type, bit_depth, interlace_type, compression_type);\n\n    if (color_type == PNG_COLOR_TYPE_PALETTE)\n        png_set_palette_to_rgb(read_ptr);\n\n    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)\n        png_set_expand_gray_1_2_4_to_8(read_ptr);\n\n    if (png_get_valid(read_ptr, read_info, PNG_INFO_tRNS)) {\n        //printf(\"Has PNG_INFO_tRNS!\\n\");\n        png_set_tRNS_to_alpha(read_ptr);\n    }\n\n    if (bit_depth == 16)\n        png_set_strip_16(read_ptr);\n\n    if ((color_type&PNG_COLOR_MASK_ALPHA) == 0)\n        png_set_add_alpha(read_ptr, 0xFF, PNG_FILLER_AFTER);\n\n    if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n        png_set_gray_to_rgb(read_ptr);\n\n    png_set_interlace_handling(read_ptr);\n\n    png_read_update_info(read_ptr, read_info);\n\n    outImageInfo->rows = (png_bytepp)malloc(\n        outImageInfo->height * sizeof(png_bytep));\n    outImageInfo->allocHeight = outImageInfo->height;\n    outImageInfo->allocRows = outImageInfo->rows;\n\n    png_set_rows(read_ptr, read_info, outImageInfo->rows);\n\n    for (i = 0; i < (int)outImageInfo->height; i++)\n    {\n        outImageInfo->rows[i] = (png_bytep)\n            malloc(png_get_rowbytes(read_ptr, read_info));\n    }\n\n    png_read_image(read_ptr, outImageInfo->rows);\n\n    png_read_end(read_ptr, read_info);\n\n    if (kIsDebug) {\n        printf(\"Image %s: w=%d, h=%d, d=%d, colors=%d, inter=%d, comp=%d\\n\",\n                imageName,\n                (int)outImageInfo->width, (int)outImageInfo->height,\n                bit_depth, color_type,\n                interlace_type, compression_type);\n    }\n\n    png_get_IHDR(read_ptr, read_info, &outImageInfo->width,\n       &outImageInfo->height, &bit_depth, &color_type,\n       &interlace_type, &compression_type, NULL);\n}\n\n#define COLOR_TRANSPARENT 0\n#define COLOR_WHITE 0xFFFFFFFF\n#define COLOR_TICK  0xFF000000\n#define COLOR_LAYOUT_BOUNDS_TICK 0xFF0000FF\n\nenum {\n    TICK_TYPE_NONE,\n    TICK_TYPE_TICK,\n    TICK_TYPE_LAYOUT_BOUNDS,\n    TICK_TYPE_BOTH\n};\n\nstatic int tick_type(png_bytep p, bool transparent, const char** outError)\n{\n    png_uint_32 color = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);\n\n    if (transparent) {\n        if (p[3] == 0) {\n            return TICK_TYPE_NONE;\n        }\n        if (color == COLOR_LAYOUT_BOUNDS_TICK) {\n            return TICK_TYPE_LAYOUT_BOUNDS;\n        }\n        if (color == COLOR_TICK) {\n            return TICK_TYPE_TICK;\n        }\n\n        // Error cases\n        if (p[3] != 0xff) {\n            *outError = \"Frame pixels must be either solid or transparent (not intermediate alphas)\";\n            return TICK_TYPE_NONE;\n        }\n        if (p[0] != 0 || p[1] != 0 || p[2] != 0) {\n            *outError = \"Ticks in transparent frame must be black or red\";\n        }\n        return TICK_TYPE_TICK;\n    }\n\n    if (p[3] != 0xFF) {\n        *outError = \"White frame must be a solid color (no alpha)\";\n    }\n    if (color == COLOR_WHITE) {\n        return TICK_TYPE_NONE;\n    }\n    if (color == COLOR_TICK) {\n        return TICK_TYPE_TICK;\n    }\n    if (color == COLOR_LAYOUT_BOUNDS_TICK) {\n        return TICK_TYPE_LAYOUT_BOUNDS;\n    }\n\n    if (p[0] != 0 || p[1] != 0 || p[2] != 0) {\n        *outError = \"Ticks in white frame must be black or red\";\n        return TICK_TYPE_NONE;\n    }\n    return TICK_TYPE_TICK;\n}\n\nenum {\n    TICK_START,\n    TICK_INSIDE_1,\n    TICK_OUTSIDE_1\n};\n\nstatic status_t get_horizontal_ticks(\n        png_bytep row, int width, bool transparent, bool required,\n        int32_t* outLeft, int32_t* outRight, const char** outError,\n        uint8_t* outDivs, bool multipleAllowed)\n{\n    int i;\n    *outLeft = *outRight = -1;\n    int state = TICK_START;\n    bool found = false;\n\n    for (i=1; i<width-1; i++) {\n        if (TICK_TYPE_TICK == tick_type(row+i*4, transparent, outError)) {\n            if (state == TICK_START ||\n                (state == TICK_OUTSIDE_1 && multipleAllowed)) {\n                *outLeft = i-1;\n                *outRight = width-2;\n                found = true;\n                if (outDivs != NULL) {\n                    *outDivs += 2;\n                }\n                state = TICK_INSIDE_1;\n            } else if (state == TICK_OUTSIDE_1) {\n                *outError = \"Can't have more than one marked region along edge\";\n                *outLeft = i;\n                return UNKNOWN_ERROR;\n            }\n        } else if (*outError == NULL) {\n            if (state == TICK_INSIDE_1) {\n                // We're done with this div.  Move on to the next.\n                *outRight = i-1;\n                outRight += 2;\n                outLeft += 2;\n                state = TICK_OUTSIDE_1;\n            }\n        } else {\n            *outLeft = i;\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    if (required && !found) {\n        *outError = \"No marked region found along edge\";\n        *outLeft = -1;\n        return UNKNOWN_ERROR;\n    }\n\n    return NO_ERROR;\n}\n\nstatic status_t get_vertical_ticks(\n        png_bytepp rows, int offset, int height, bool transparent, bool required,\n        int32_t* outTop, int32_t* outBottom, const char** outError,\n        uint8_t* outDivs, bool multipleAllowed)\n{\n    int i;\n    *outTop = *outBottom = -1;\n    int state = TICK_START;\n    bool found = false;\n\n    for (i=1; i<height-1; i++) {\n        if (TICK_TYPE_TICK == tick_type(rows[i]+offset, transparent, outError)) {\n            if (state == TICK_START ||\n                (state == TICK_OUTSIDE_1 && multipleAllowed)) {\n                *outTop = i-1;\n                *outBottom = height-2;\n                found = true;\n                if (outDivs != NULL) {\n                    *outDivs += 2;\n                }\n                state = TICK_INSIDE_1;\n            } else if (state == TICK_OUTSIDE_1) {\n                *outError = \"Can't have more than one marked region along edge\";\n                *outTop = i;\n                return UNKNOWN_ERROR;\n            }\n        } else if (*outError == NULL) {\n            if (state == TICK_INSIDE_1) {\n                // We're done with this div.  Move on to the next.\n                *outBottom = i-1;\n                outTop += 2;\n                outBottom += 2;\n                state = TICK_OUTSIDE_1;\n            }\n        } else {\n            *outTop = i;\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    if (required && !found) {\n        *outError = \"No marked region found along edge\";\n        *outTop = -1;\n        return UNKNOWN_ERROR;\n    }\n\n    return NO_ERROR;\n}\n\nstatic status_t get_horizontal_layout_bounds_ticks(\n        png_bytep row, int width, bool transparent, bool /* required */,\n        int32_t* outLeft, int32_t* outRight, const char** outError)\n{\n    int i;\n    *outLeft = *outRight = 0;\n\n    // Look for left tick\n    if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(row + 4, transparent, outError)) {\n        // Starting with a layout padding tick\n        i = 1;\n        while (i < width - 1) {\n            (*outLeft)++;\n            i++;\n            int tick = tick_type(row + i * 4, transparent, outError);\n            if (tick != TICK_TYPE_LAYOUT_BOUNDS) {\n                break;\n            }\n        }\n    }\n\n    // Look for right tick\n    if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(row + (width - 2) * 4, transparent, outError)) {\n        // Ending with a layout padding tick\n        i = width - 2;\n        while (i > 1) {\n            (*outRight)++;\n            i--;\n            int tick = tick_type(row+i*4, transparent, outError);\n            if (tick != TICK_TYPE_LAYOUT_BOUNDS) {\n                break;\n            }\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatic status_t get_vertical_layout_bounds_ticks(\n        png_bytepp rows, int offset, int height, bool transparent, bool /* required */,\n        int32_t* outTop, int32_t* outBottom, const char** outError)\n{\n    int i;\n    *outTop = *outBottom = 0;\n\n    // Look for top tick\n    if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(rows[1] + offset, transparent, outError)) {\n        // Starting with a layout padding tick\n        i = 1;\n        while (i < height - 1) {\n            (*outTop)++;\n            i++;\n            int tick = tick_type(rows[i] + offset, transparent, outError);\n            if (tick != TICK_TYPE_LAYOUT_BOUNDS) {\n                break;\n            }\n        }\n    }\n\n    // Look for bottom tick\n    if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(rows[height - 2] + offset, transparent, outError)) {\n        // Ending with a layout padding tick\n        i = height - 2;\n        while (i > 1) {\n            (*outBottom)++;\n            i--;\n            int tick = tick_type(rows[i] + offset, transparent, outError);\n            if (tick != TICK_TYPE_LAYOUT_BOUNDS) {\n                break;\n            }\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatic void find_max_opacity(png_byte** rows,\n                             int startX, int startY, int endX, int endY, int dX, int dY,\n                             int* out_inset)\n{\n    uint8_t max_opacity = 0;\n    int inset = 0;\n    *out_inset = 0;\n    for (int x = startX, y = startY; x != endX && y != endY; x += dX, y += dY, inset++) {\n        png_byte* color = rows[y] + x * 4;\n        uint8_t opacity = color[3];\n        if (opacity > max_opacity) {\n            max_opacity = opacity;\n            *out_inset = inset;\n        }\n        if (opacity == 0xff) return;\n    }\n}\n\nstatic uint8_t max_alpha_over_row(png_byte* row, int startX, int endX)\n{\n    uint8_t max_alpha = 0;\n    for (int x = startX; x < endX; x++) {\n        uint8_t alpha = (row + x * 4)[3];\n        if (alpha > max_alpha) max_alpha = alpha;\n    }\n    return max_alpha;\n}\n\nstatic uint8_t max_alpha_over_col(png_byte** rows, int offsetX, int startY, int endY)\n{\n    uint8_t max_alpha = 0;\n    for (int y = startY; y < endY; y++) {\n        uint8_t alpha = (rows[y] + offsetX * 4)[3];\n        if (alpha > max_alpha) max_alpha = alpha;\n    }\n    return max_alpha;\n}\n\nstatic void get_outline(image_info* image)\n{\n    int midX = image->width / 2;\n    int midY = image->height / 2;\n    int endX = image->width - 2;\n    int endY = image->height - 2;\n\n    // find left and right extent of nine patch content on center row\n    if (image->width > 4) {\n        find_max_opacity(image->rows, 1, midY, midX, -1, 1, 0, &image->outlineInsetsLeft);\n        find_max_opacity(image->rows, endX, midY, midX, -1, -1, 0, &image->outlineInsetsRight);\n    } else {\n        image->outlineInsetsLeft = 0;\n        image->outlineInsetsRight = 0;\n    }\n\n    // find top and bottom extent of nine patch content on center column\n    if (image->height > 4) {\n        find_max_opacity(image->rows, midX, 1, -1, midY, 0, 1, &image->outlineInsetsTop);\n        find_max_opacity(image->rows, midX, endY, -1, midY, 0, -1, &image->outlineInsetsBottom);\n    } else {\n        image->outlineInsetsTop = 0;\n        image->outlineInsetsBottom = 0;\n    }\n\n    int innerStartX = 1 + image->outlineInsetsLeft;\n    int innerStartY = 1 + image->outlineInsetsTop;\n    int innerEndX = endX - image->outlineInsetsRight;\n    int innerEndY = endY - image->outlineInsetsBottom;\n    int innerMidX = (innerEndX + innerStartX) / 2;\n    int innerMidY = (innerEndY + innerStartY) / 2;\n\n    // assuming the image is a round rect, compute the radius by marching\n    // diagonally from the top left corner towards the center\n    image->outlineAlpha = std::max(\n        max_alpha_over_row(image->rows[innerMidY], innerStartX, innerEndX),\n        max_alpha_over_col(image->rows, innerMidX, innerStartY, innerStartY));\n\n    int diagonalInset = 0;\n    find_max_opacity(image->rows, innerStartX, innerStartY, innerMidX, innerMidY, 1, 1,\n            &diagonalInset);\n\n    /* Determine source radius based upon inset:\n     *     sqrt(r^2 + r^2) = sqrt(i^2 + i^2) + r\n     *     sqrt(2) * r = sqrt(2) * i + r\n     *     (sqrt(2) - 1) * r = sqrt(2) * i\n     *     r = sqrt(2) / (sqrt(2) - 1) * i\n     */\n    image->outlineRadius = 3.4142f * diagonalInset;\n\n    if (kIsDebug) {\n        printf(\"outline insets %d %d %d %d, rad %f, alpha %x\\n\",\n                image->outlineInsetsLeft,\n                image->outlineInsetsTop,\n                image->outlineInsetsRight,\n                image->outlineInsetsBottom,\n                image->outlineRadius,\n                image->outlineAlpha);\n    }\n}\n\n\nstatic uint32_t get_color(\n    png_bytepp rows, int left, int top, int right, int bottom)\n{\n    png_bytep color = rows[top] + left*4;\n\n    if (left > right || top > bottom) {\n        return Res_png_9patch::TRANSPARENT_COLOR;\n    }\n\n    while (top <= bottom) {\n        for (int i = left; i <= right; i++) {\n            png_bytep p = rows[top]+i*4;\n            if (color[3] == 0) {\n                if (p[3] != 0) {\n                    return Res_png_9patch::NO_COLOR;\n                }\n            } else if (p[0] != color[0] || p[1] != color[1]\n                       || p[2] != color[2] || p[3] != color[3]) {\n                return Res_png_9patch::NO_COLOR;\n            }\n        }\n        top++;\n    }\n\n    if (color[3] == 0) {\n        return Res_png_9patch::TRANSPARENT_COLOR;\n    }\n    return (color[3]<<24) | (color[0]<<16) | (color[1]<<8) | color[2];\n}\n\nstatic status_t do_9patch(const char* imageName, image_info* image)\n{\n    image->is9Patch = true;\n\n    int W = image->width;\n    int H = image->height;\n    int i, j;\n\n    int maxSizeXDivs = W * sizeof(int32_t);\n    int maxSizeYDivs = H * sizeof(int32_t);\n    int32_t* xDivs = image->xDivs = (int32_t*) malloc(maxSizeXDivs);\n    int32_t* yDivs = image->yDivs = (int32_t*) malloc(maxSizeYDivs);\n    uint8_t numXDivs = 0;\n    uint8_t numYDivs = 0;\n\n    int8_t numColors;\n    int numRows;\n    int numCols;\n    int top;\n    int left;\n    int right;\n    int bottom;\n    memset(xDivs, -1, maxSizeXDivs);\n    memset(yDivs, -1, maxSizeYDivs);\n    image->info9Patch.paddingLeft = image->info9Patch.paddingRight =\n        image->info9Patch.paddingTop = image->info9Patch.paddingBottom = -1;\n\n    image->layoutBoundsLeft = image->layoutBoundsRight =\n        image->layoutBoundsTop = image->layoutBoundsBottom = 0;\n\n    png_bytep p = image->rows[0];\n    bool transparent = p[3] == 0;\n    bool hasColor = false;\n\n    const char* errorMsg = NULL;\n    int errorPixel = -1;\n    const char* errorEdge = NULL;\n\n    int colorIndex = 0;\n\n    // Validate size...\n    if (W < 3 || H < 3) {\n        errorMsg = \"Image must be at least 3x3 (1x1 without frame) pixels\";\n        goto getout;\n    }\n\n    // Validate frame...\n    if (!transparent &&\n        (p[0] != 0xFF || p[1] != 0xFF || p[2] != 0xFF || p[3] != 0xFF)) {\n        errorMsg = \"Must have one-pixel frame that is either transparent or white\";\n        goto getout;\n    }\n\n    // Find left and right of sizing areas...\n    if (get_horizontal_ticks(p, W, transparent, true, &xDivs[0],\n                             &xDivs[1], &errorMsg, &numXDivs, true) != NO_ERROR) {\n        errorPixel = xDivs[0];\n        errorEdge = \"top\";\n        goto getout;\n    }\n\n    // Find top and bottom of sizing areas...\n    if (get_vertical_ticks(image->rows, 0, H, transparent, true, &yDivs[0],\n                           &yDivs[1], &errorMsg, &numYDivs, true) != NO_ERROR) {\n        errorPixel = yDivs[0];\n        errorEdge = \"left\";\n        goto getout;\n    }\n\n    // Copy patch size data into image...\n    image->info9Patch.numXDivs = numXDivs;\n    image->info9Patch.numYDivs = numYDivs;\n\n    // Find left and right of padding area...\n    if (get_horizontal_ticks(image->rows[H-1], W, transparent, false, &image->info9Patch.paddingLeft,\n                             &image->info9Patch.paddingRight, &errorMsg, NULL, false) != NO_ERROR) {\n        errorPixel = image->info9Patch.paddingLeft;\n        errorEdge = \"bottom\";\n        goto getout;\n    }\n\n    // Find top and bottom of padding area...\n    if (get_vertical_ticks(image->rows, (W-1)*4, H, transparent, false, &image->info9Patch.paddingTop,\n                           &image->info9Patch.paddingBottom, &errorMsg, NULL, false) != NO_ERROR) {\n        errorPixel = image->info9Patch.paddingTop;\n        errorEdge = \"right\";\n        goto getout;\n    }\n\n    // Find left and right of layout padding...\n    get_horizontal_layout_bounds_ticks(image->rows[H-1], W, transparent, false,\n                                        &image->layoutBoundsLeft,\n                                        &image->layoutBoundsRight, &errorMsg);\n\n    get_vertical_layout_bounds_ticks(image->rows, (W-1)*4, H, transparent, false,\n                                        &image->layoutBoundsTop,\n                                        &image->layoutBoundsBottom, &errorMsg);\n\n    image->haveLayoutBounds = image->layoutBoundsLeft != 0\n                               || image->layoutBoundsRight != 0\n                               || image->layoutBoundsTop != 0\n                               || image->layoutBoundsBottom != 0;\n\n    if (image->haveLayoutBounds) {\n        if (kIsDebug) {\n            printf(\"layoutBounds=%d %d %d %d\\n\", image->layoutBoundsLeft, image->layoutBoundsTop,\n                    image->layoutBoundsRight, image->layoutBoundsBottom);\n        }\n    }\n\n    // use opacity of pixels to estimate the round rect outline\n    get_outline(image);\n\n    // If padding is not yet specified, take values from size.\n    if (image->info9Patch.paddingLeft < 0) {\n        image->info9Patch.paddingLeft = xDivs[0];\n        image->info9Patch.paddingRight = W - 2 - xDivs[1];\n    } else {\n        // Adjust value to be correct!\n        image->info9Patch.paddingRight = W - 2 - image->info9Patch.paddingRight;\n    }\n    if (image->info9Patch.paddingTop < 0) {\n        image->info9Patch.paddingTop = yDivs[0];\n        image->info9Patch.paddingBottom = H - 2 - yDivs[1];\n    } else {\n        // Adjust value to be correct!\n        image->info9Patch.paddingBottom = H - 2 - image->info9Patch.paddingBottom;\n    }\n\n    if (kIsDebug) {\n        printf(\"Size ticks for %s: x0=%d, x1=%d, y0=%d, y1=%d\\n\", imageName,\n                xDivs[0], xDivs[1],\n                yDivs[0], yDivs[1]);\n        printf(\"padding ticks for %s: l=%d, r=%d, t=%d, b=%d\\n\", imageName,\n                image->info9Patch.paddingLeft, image->info9Patch.paddingRight,\n                image->info9Patch.paddingTop, image->info9Patch.paddingBottom);\n    }\n\n    // Remove frame from image.\n    image->rows = (png_bytepp)malloc((H-2) * sizeof(png_bytep));\n    for (i=0; i<(H-2); i++) {\n        image->rows[i] = image->allocRows[i+1];\n        memmove(image->rows[i], image->rows[i]+4, (W-2)*4);\n    }\n    image->width -= 2;\n    W = image->width;\n    image->height -= 2;\n    H = image->height;\n\n    // Figure out the number of rows and columns in the N-patch\n    numCols = numXDivs + 1;\n    if (xDivs[0] == 0) {  // Column 1 is strechable\n        numCols--;\n    }\n    if (xDivs[numXDivs - 1] == W) {\n        numCols--;\n    }\n    numRows = numYDivs + 1;\n    if (yDivs[0] == 0) {  // Row 1 is strechable\n        numRows--;\n    }\n    if (yDivs[numYDivs - 1] == H) {\n        numRows--;\n    }\n\n    // Make sure the amount of rows and columns will fit in the number of\n    // colors we can use in the 9-patch format.\n    if (numRows * numCols > 0x7F) {\n        errorMsg = \"Too many rows and columns in 9-patch perimeter\";\n        goto getout;\n    }\n\n    numColors = numRows * numCols;\n    image->info9Patch.numColors = numColors;\n    image->colors = (uint32_t*)malloc(numColors * sizeof(uint32_t));\n\n    // Fill in color information for each patch.\n\n    uint32_t c;\n    top = 0;\n\n    // The first row always starts with the top being at y=0 and the bottom\n    // being either yDivs[1] (if yDivs[0]=0) of yDivs[0].  In the former case\n    // the first row is stretchable along the Y axis, otherwise it is fixed.\n    // The last row always ends with the bottom being bitmap.height and the top\n    // being either yDivs[numYDivs-2] (if yDivs[numYDivs-1]=bitmap.height) or\n    // yDivs[numYDivs-1]. In the former case the last row is stretchable along\n    // the Y axis, otherwise it is fixed.\n    //\n    // The first and last columns are similarly treated with respect to the X\n    // axis.\n    //\n    // The above is to help explain some of the special casing that goes on the\n    // code below.\n\n    // The initial yDiv and whether the first row is considered stretchable or\n    // not depends on whether yDiv[0] was zero or not.\n    for (j = (yDivs[0] == 0 ? 1 : 0);\n          j <= numYDivs && top < H;\n          j++) {\n        if (j == numYDivs) {\n            bottom = H;\n        } else {\n            bottom = yDivs[j];\n        }\n        left = 0;\n        // The initial xDiv and whether the first column is considered\n        // stretchable or not depends on whether xDiv[0] was zero or not.\n        for (i = xDivs[0] == 0 ? 1 : 0;\n              i <= numXDivs && left < W;\n              i++) {\n            if (i == numXDivs) {\n                right = W;\n            } else {\n                right = xDivs[i];\n            }\n            c = get_color(image->rows, left, top, right - 1, bottom - 1);\n            image->colors[colorIndex++] = c;\n            if (kIsDebug) {\n                if (c != Res_png_9patch::NO_COLOR)\n                    hasColor = true;\n            }\n            left = right;\n        }\n        top = bottom;\n    }\n\n    assert(colorIndex == numColors);\n\n    for (i=0; i<numColors; i++) {\n        if (hasColor) {\n            if (i == 0) printf(\"Colors in %s:\\n \", imageName);\n            printf(\" #%08x\", image->colors[i]);\n            if (i == numColors - 1) printf(\"\\n\");\n        }\n    }\ngetout:\n    if (errorMsg) {\n        fprintf(stderr,\n            \"ERROR: 9-patch image %s malformed.\\n\"\n            \"       %s.\\n\", imageName, errorMsg);\n        if (errorEdge != NULL) {\n            if (errorPixel >= 0) {\n                fprintf(stderr,\n                    \"       Found at pixel #%d along %s edge.\\n\", errorPixel, errorEdge);\n            } else {\n                fprintf(stderr,\n                    \"       Found along %s edge.\\n\", errorEdge);\n            }\n        }\n        return UNKNOWN_ERROR;\n    }\n    return NO_ERROR;\n}\n\nstatic void checkNinePatchSerialization(Res_png_9patch* inPatch,  void* data)\n{\n    size_t patchSize = inPatch->serializedSize();\n    void* newData = malloc(patchSize);\n    memcpy(newData, data, patchSize);\n    Res_png_9patch* outPatch = inPatch->deserialize(newData);\n    // deserialization is done in place, so outPatch == newData\n    assert(outPatch == newData);\n    assert(outPatch->numXDivs == inPatch->numXDivs);\n    assert(outPatch->numYDivs == inPatch->numYDivs);\n    assert(outPatch->paddingLeft == inPatch->paddingLeft);\n    assert(outPatch->paddingRight == inPatch->paddingRight);\n    assert(outPatch->paddingTop == inPatch->paddingTop);\n    assert(outPatch->paddingBottom == inPatch->paddingBottom);\n    for (int i = 0; i < outPatch->numXDivs; i++) {\n        assert(outPatch->xDivs[i] == inPatch->xDivs[i]);\n    }\n    for (int i = 0; i < outPatch->numYDivs; i++) {\n        assert(outPatch->yDivs[i] == inPatch->yDivs[i]);\n    }\n    for (int i = 0; i < outPatch->numColors; i++) {\n        assert(outPatch->colors[i] == inPatch->colors[i]);\n    }\n    free(newData);\n}\n\nstatic void dump_image(int w, int h, png_bytepp rows, int color_type)\n{\n    int i, j, rr, gg, bb, aa;\n\n    int bpp;\n    if (color_type == PNG_COLOR_TYPE_PALETTE || color_type == PNG_COLOR_TYPE_GRAY) {\n        bpp = 1;\n    } else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {\n        bpp = 2;\n    } else if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) {\n        // We use a padding byte even when there is no alpha\n        bpp = 4;\n    } else {\n        printf(\"Unknown color type %d.\\n\", color_type);\n    }\n\n    for (j = 0; j < h; j++) {\n        png_bytep row = rows[j];\n        for (i = 0; i < w; i++) {\n            rr = row[0];\n            gg = row[1];\n            bb = row[2];\n            aa = row[3];\n            row += bpp;\n\n            if (i == 0) {\n                printf(\"Row %d:\", j);\n            }\n            switch (bpp) {\n            case 1:\n                printf(\" (%d)\", rr);\n                break;\n            case 2:\n                printf(\" (%d %d\", rr, gg);\n                break;\n            case 3:\n                printf(\" (%d %d %d)\", rr, gg, bb);\n                break;\n            case 4:\n                printf(\" (%d %d %d %d)\", rr, gg, bb, aa);\n                break;\n            }\n            if (i == (w - 1)) {\n                printf(\"\\n\");\n            }\n        }\n    }\n}\n\n#define MAX(a,b) ((a)>(b)?(a):(b))\n#define ABS(a)   ((a)<0?-(a):(a))\n\nstatic void analyze_image(const char *imageName, image_info &imageInfo, int grayscaleTolerance,\n                          png_colorp rgbPalette, png_bytep alphaPalette,\n                          int *paletteEntries, int *alphaPaletteEntries, bool *hasTransparency,\n                          int *colorType, png_bytepp outRows)\n{\n    int w = imageInfo.width;\n    int h = imageInfo.height;\n    int i, j, rr, gg, bb, aa, idx;;\n    uint32_t opaqueColors[256], alphaColors[256];\n    uint32_t col;\n    int numOpaqueColors = 0, numAlphaColors = 0;\n    int maxGrayDeviation = 0;\n\n    bool isOpaque = true;\n    bool isPalette = true;\n    bool isGrayscale = true;\n\n    // Scan the entire image and determine if:\n    // 1. Every pixel has R == G == B (grayscale)\n    // 2. Every pixel has A == 255 (opaque)\n    // 3. There are no more than 256 distinct RGBA colors\n    //        We will track opaque colors separately from colors with\n    //        alpha.  This allows us to reencode the color table more\n    //        efficiently (color tables entries without a corresponding\n    //        alpha value are assumed to be opaque).\n\n    if (kIsDebug) {\n        printf(\"Initial image data:\\n\");\n        dump_image(w, h, imageInfo.rows, PNG_COLOR_TYPE_RGB_ALPHA);\n    }\n\n    for (j = 0; j < h; j++) {\n        png_bytep row = imageInfo.rows[j];\n        png_bytep out = outRows[j];\n        for (i = 0; i < w; i++) {\n\n            // Make sure any zero alpha pixels are fully zeroed.  On average,\n            // each of our PNG assets seem to have about four distinct pixels\n            // with zero alpha.\n            // There are several advantages to setting these to zero:\n            // (1) Images are more likely able to be encodable with a palette.\n            // (2) Image palettes will be smaller.\n            // (3) Premultiplied and unpremultiplied PNG decodes can skip\n            //     writing zeros to memory, often saving significant numbers\n            //     of memory pages.\n            aa = *(row + 3);\n            if (aa == 0) {\n                rr = 0;\n                gg = 0;\n                bb = 0;\n\n                // Also set red, green, and blue to zero in \"row\".  If we later\n                // decide to encode the PNG as RGB or RGBA, we will use the\n                // values stored there.\n                *(row) = 0;\n                *(row + 1) = 0;\n                *(row + 2) = 0;\n            } else {\n                rr = *(row);\n                gg = *(row + 1);\n                bb = *(row + 2);\n            }\n            row += 4;\n\n            int odev = maxGrayDeviation;\n            maxGrayDeviation = MAX(ABS(rr - gg), maxGrayDeviation);\n            maxGrayDeviation = MAX(ABS(gg - bb), maxGrayDeviation);\n            maxGrayDeviation = MAX(ABS(bb - rr), maxGrayDeviation);\n            if (maxGrayDeviation > odev) {\n                if (kIsDebug) {\n                    printf(\"New max dev. = %d at pixel (%d, %d) = (%d %d %d %d)\\n\",\n                            maxGrayDeviation, i, j, rr, gg, bb, aa);\n                }\n            }\n\n            // Check if image is really grayscale\n            if (isGrayscale) {\n                if (rr != gg || rr != bb) {\n                    if (kIsDebug) {\n                        printf(\"Found a non-gray pixel at %d, %d = (%d %d %d %d)\\n\",\n                                i, j, rr, gg, bb, aa);\n                    }\n                    isGrayscale = false;\n                }\n            }\n\n            // Check if image is really opaque\n            if (isOpaque) {\n                if (aa != 0xff) {\n                    if (kIsDebug) {\n                        printf(\"Found a non-opaque pixel at %d, %d = (%d %d %d %d)\\n\",\n                                i, j, rr, gg, bb, aa);\n                    }\n                    isOpaque = false;\n                }\n            }\n\n            // Check if image is really <= 256 colors\n            if (isPalette) {\n                col = (uint32_t) ((rr << 24) | (gg << 16) | (bb << 8) | aa);\n                bool match = false;\n\n                if (aa == 0xff) {\n                    for (idx = 0; idx < numOpaqueColors; idx++) {\n                        if (opaqueColors[idx] == col) {\n                            match = true;\n                            break;\n                        }\n                    }\n\n                    if (!match) {\n                        if (numOpaqueColors < 256) {\n                            opaqueColors[numOpaqueColors] = col;\n                        }\n                        numOpaqueColors++;\n                    }\n\n                    // Write the palette index for the pixel to outRows optimistically.\n                    // We might overwrite it later if we decide to encode as gray or\n                    // gray + alpha.  We may also need to overwrite it when we combine\n                    // into a single palette.\n                    *out++ = idx;\n                } else {\n                    for (idx = 0; idx < numAlphaColors; idx++) {\n                        if (alphaColors[idx] == col) {\n                            match = true;\n                            break;\n                        }\n                    }\n\n                    if (!match) {\n                        if (numAlphaColors < 256) {\n                            alphaColors[numAlphaColors] = col;\n                        }\n                        numAlphaColors++;\n                    }\n\n                    // Write the palette index for the pixel to outRows optimistically.\n                    // We might overwrite it later if we decide to encode as gray or\n                    // gray + alpha.\n                    *out++ = idx;\n                }\n\n                if (numOpaqueColors + numAlphaColors > 256) {\n                    if (kIsDebug) {\n                        printf(\"Found 257th color at %d, %d\\n\", i, j);\n                    }\n                    isPalette = false;\n                }\n            }\n        }\n    }\n\n    // If we decide to encode the image using a palette, we will reset these counts\n    // to the appropriate values later.  Initializing them here avoids compiler\n    // complaints about uses of possibly uninitialized variables.\n    *paletteEntries = 0;\n    *alphaPaletteEntries = 0;\n\n    *hasTransparency = !isOpaque;\n    int paletteSize = w * h + 3 * numOpaqueColors + 4 * numAlphaColors;\n\n    int bpp = isOpaque ? 3 : 4;\n    if (kIsDebug) {\n        printf(\"isGrayscale = %s\\n\", isGrayscale ? \"true\" : \"false\");\n        printf(\"isOpaque = %s\\n\", isOpaque ? \"true\" : \"false\");\n        printf(\"isPalette = %s\\n\", isPalette ? \"true\" : \"false\");\n        printf(\"Size w/ palette = %d, gray+alpha = %d, rgb(a) = %d\\n\",\n                paletteSize, 2 * w * h, bpp * w * h);\n        printf(\"Max gray deviation = %d, tolerance = %d\\n\", maxGrayDeviation, grayscaleTolerance);\n    }\n\n    // Choose the best color type for the image.\n    // 1. Opaque gray - use COLOR_TYPE_GRAY at 1 byte/pixel\n    // 2. Gray + alpha - use COLOR_TYPE_PALETTE if the number of distinct combinations\n    //     is sufficiently small, otherwise use COLOR_TYPE_GRAY_ALPHA\n    // 3. RGB(A) - use COLOR_TYPE_PALETTE if the number of distinct colors is sufficiently\n    //     small, otherwise use COLOR_TYPE_RGB{_ALPHA}\n    if (isGrayscale) {\n        if (isOpaque) {\n            *colorType = PNG_COLOR_TYPE_GRAY; // 1 byte/pixel\n        } else {\n            // Use a simple heuristic to determine whether using a palette will\n            // save space versus using gray + alpha for each pixel.\n            // This doesn't take into account chunk overhead, filtering, LZ\n            // compression, etc.\n            if (isPalette && (paletteSize < 2 * w * h)) {\n                *colorType = PNG_COLOR_TYPE_PALETTE; // 1 byte/pixel + 4 bytes/color\n            } else {\n                *colorType = PNG_COLOR_TYPE_GRAY_ALPHA; // 2 bytes per pixel\n            }\n        }\n    } else if (isPalette && (paletteSize < bpp * w * h)) {\n        *colorType = PNG_COLOR_TYPE_PALETTE;\n    } else {\n        if (maxGrayDeviation <= grayscaleTolerance) {\n            printf(\"%s: forcing image to gray (max deviation = %d)\\n\", imageName, maxGrayDeviation);\n            *colorType = isOpaque ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_GRAY_ALPHA;\n        } else {\n            *colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;\n        }\n    }\n\n    // Perform postprocessing of the image or palette data based on the final\n    // color type chosen\n\n    if (*colorType == PNG_COLOR_TYPE_PALETTE) {\n        // Combine the alphaColors and the opaqueColors into a single palette.\n        // The alphaColors must be at the start of the palette.\n        uint32_t* colors = alphaColors;\n        memcpy(colors + numAlphaColors, opaqueColors, 4 * numOpaqueColors);\n\n        // Fix the indices of the opaque colors in the image.\n        for (j = 0; j < h; j++) {\n            png_bytep row = imageInfo.rows[j];\n            png_bytep out = outRows[j];\n            for (i = 0; i < w; i++) {\n                uint32_t pixel = ((uint32_t*) row)[i];\n                if (pixel >> 24 == 0xFF) {\n                    out[i] += numAlphaColors;\n                }\n            }\n        }\n\n        // Create separate RGB and Alpha palettes and set the number of colors\n        int numColors = numOpaqueColors + numAlphaColors;\n        *paletteEntries = numColors;\n        *alphaPaletteEntries = numAlphaColors;\n\n        // Create the RGB and alpha palettes\n        for (int idx = 0; idx < numColors; idx++) {\n            col = colors[idx];\n            rgbPalette[idx].red   = (png_byte) ((col >> 24) & 0xff);\n            rgbPalette[idx].green = (png_byte) ((col >> 16) & 0xff);\n            rgbPalette[idx].blue  = (png_byte) ((col >>  8) & 0xff);\n            if (idx < numAlphaColors) {\n                alphaPalette[idx] = (png_byte)  (col        & 0xff);\n            }\n        }\n    } else if (*colorType == PNG_COLOR_TYPE_GRAY || *colorType == PNG_COLOR_TYPE_GRAY_ALPHA) {\n        // If the image is gray or gray + alpha, compact the pixels into outRows\n        for (j = 0; j < h; j++) {\n            png_bytep row = imageInfo.rows[j];\n            png_bytep out = outRows[j];\n            for (i = 0; i < w; i++) {\n                rr = *row++;\n                gg = *row++;\n                bb = *row++;\n                aa = *row++;\n                \n                if (isGrayscale) {\n                    *out++ = rr;\n                } else {\n                    *out++ = (png_byte) (rr * 0.2126f + gg * 0.7152f + bb * 0.0722f);\n                }\n                if (!isOpaque) {\n                    *out++ = aa;\n                }\n           }\n        }\n    }\n}\n\nstatic void write_png(const char* imageName,\n                      png_structp write_ptr, png_infop write_info,\n                      image_info& imageInfo, const Bundle* bundle)\n{\n    png_uint_32 width, height;\n    int color_type;\n    int bit_depth, interlace_type, compression_type;\n    int i;\n\n    png_unknown_chunk unknowns[3];\n    unknowns[0].data = NULL;\n    unknowns[1].data = NULL;\n    unknowns[2].data = NULL;\n\n    png_bytepp outRows = (png_bytepp) malloc((int) imageInfo.height * sizeof(png_bytep));\n    if (outRows == (png_bytepp) 0) {\n        printf(\"Can't allocate output buffer!\\n\");\n        exit(1);\n    }\n    for (i = 0; i < (int) imageInfo.height; i++) {\n        outRows[i] = (png_bytep) malloc(2 * (int) imageInfo.width);\n        if (outRows[i] == (png_bytep) 0) {\n            printf(\"Can't allocate output buffer!\\n\");\n            exit(1);\n        }\n    }\n\n    png_set_compression_level(write_ptr, Z_BEST_COMPRESSION);\n\n    if (kIsDebug) {\n        printf(\"Writing image %s: w = %d, h = %d\\n\", imageName,\n                (int) imageInfo.width, (int) imageInfo.height);\n    }\n\n    png_color rgbPalette[256];\n    png_byte alphaPalette[256];\n    bool hasTransparency;\n    int paletteEntries, alphaPaletteEntries;\n\n    int grayscaleTolerance = bundle->getGrayscaleTolerance();\n    analyze_image(imageName, imageInfo, grayscaleTolerance, rgbPalette, alphaPalette,\n                  &paletteEntries, &alphaPaletteEntries, &hasTransparency, &color_type, outRows);\n\n    // Legacy versions of aapt would always encode 9patch PNGs as RGBA.  This had the unintended\n    // benefit of working around a bug decoding paletted images in Android 4.1.\n    // https://code.google.com/p/android/issues/detail?id=34619\n    //\n    // If SDK_JELLY_BEAN is supported, we need to avoid a paletted encoding in order to not expose\n    // this bug.\n    if (!bundle->isMinSdkAtLeast(SDK_JELLY_BEAN_MR1)) {\n        if (imageInfo.is9Patch && PNG_COLOR_TYPE_PALETTE == color_type) {\n            if (hasTransparency) {\n                color_type = PNG_COLOR_TYPE_RGB_ALPHA;\n            } else {\n                color_type = PNG_COLOR_TYPE_RGB;\n            }\n        }\n    }\n\n    if (kIsDebug) {\n        switch (color_type) {\n        case PNG_COLOR_TYPE_PALETTE:\n            printf(\"Image %s has %d colors%s, using PNG_COLOR_TYPE_PALETTE\\n\",\n                    imageName, paletteEntries,\n                    hasTransparency ? \" (with alpha)\" : \"\");\n            break;\n        case PNG_COLOR_TYPE_GRAY:\n            printf(\"Image %s is opaque gray, using PNG_COLOR_TYPE_GRAY\\n\", imageName);\n            break;\n        case PNG_COLOR_TYPE_GRAY_ALPHA:\n            printf(\"Image %s is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA\\n\", imageName);\n            break;\n        case PNG_COLOR_TYPE_RGB:\n            printf(\"Image %s is opaque RGB, using PNG_COLOR_TYPE_RGB\\n\", imageName);\n            break;\n        case PNG_COLOR_TYPE_RGB_ALPHA:\n            printf(\"Image %s is RGB + alpha, using PNG_COLOR_TYPE_RGB_ALPHA\\n\", imageName);\n            break;\n        }\n    }\n\n    png_set_IHDR(write_ptr, write_info, imageInfo.width, imageInfo.height,\n                 8, color_type, PNG_INTERLACE_NONE,\n                 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);\n\n    if (color_type == PNG_COLOR_TYPE_PALETTE) {\n        png_set_PLTE(write_ptr, write_info, rgbPalette, paletteEntries);\n        if (hasTransparency) {\n            png_set_tRNS(write_ptr, write_info, alphaPalette, alphaPaletteEntries,\n                    (png_color_16p) 0);\n        }\n       png_set_filter(write_ptr, 0, PNG_NO_FILTERS);\n    } else {\n       png_set_filter(write_ptr, 0, PNG_ALL_FILTERS);\n    }\n\n    if (imageInfo.is9Patch) {\n        int chunk_count = 2 + (imageInfo.haveLayoutBounds ? 1 : 0);\n        int p_index = imageInfo.haveLayoutBounds ? 2 : 1;\n        int b_index = 1;\n        int o_index = 0;\n\n        // Chunks ordered thusly because older platforms depend on the base 9 patch data being last\n        png_byte *chunk_names = imageInfo.haveLayoutBounds\n                ? (png_byte*)\"npOl\\0npLb\\0npTc\\0\"\n                : (png_byte*)\"npOl\\0npTc\";\n\n        // base 9 patch data\n        if (kIsDebug) {\n            printf(\"Adding 9-patch info...\\n\");\n        }\n        strcpy((char*)unknowns[p_index].name, \"npTc\");\n        unknowns[p_index].data = (png_byte*)imageInfo.serialize9patch();\n        unknowns[p_index].size = imageInfo.info9Patch.serializedSize();\n        // TODO: remove the check below when everything works\n        checkNinePatchSerialization(&imageInfo.info9Patch, unknowns[p_index].data);\n\n        // automatically generated 9 patch outline data\n        int chunk_size = sizeof(png_uint_32) * 6;\n        strcpy((char*)unknowns[o_index].name, \"npOl\");\n        unknowns[o_index].data = (png_byte*) calloc(chunk_size, 1);\n        png_byte outputData[chunk_size];\n        memcpy(&outputData, &imageInfo.outlineInsetsLeft, 4 * sizeof(png_uint_32));\n        ((float*) outputData)[4] = imageInfo.outlineRadius;\n        ((png_uint_32*) outputData)[5] = imageInfo.outlineAlpha;\n        memcpy(unknowns[o_index].data, &outputData, chunk_size);\n        unknowns[o_index].size = chunk_size;\n\n        // optional optical inset / layout bounds data\n        if (imageInfo.haveLayoutBounds) {\n            int chunk_size = sizeof(png_uint_32) * 4;\n            strcpy((char*)unknowns[b_index].name, \"npLb\");\n            unknowns[b_index].data = (png_byte*) calloc(chunk_size, 1);\n            memcpy(unknowns[b_index].data, &imageInfo.layoutBoundsLeft, chunk_size);\n            unknowns[b_index].size = chunk_size;\n        }\n\n        for (int i = 0; i < chunk_count; i++) {\n            unknowns[i].location = PNG_HAVE_IHDR;\n        }\n        png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS,\n                                    chunk_names, chunk_count);\n        png_set_unknown_chunks(write_ptr, write_info, unknowns, chunk_count);\n    }\n\n\n    png_write_info(write_ptr, write_info);\n\n    png_bytepp rows;\n    if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) {\n        if (color_type == PNG_COLOR_TYPE_RGB) {\n            png_set_filler(write_ptr, 0, PNG_FILLER_AFTER);\n        }\n        rows = imageInfo.rows;\n    } else {\n        rows = outRows;\n    }\n    png_write_image(write_ptr, rows);\n\n    if (kIsDebug) {\n        printf(\"Final image data:\\n\");\n        dump_image(imageInfo.width, imageInfo.height, rows, color_type);\n    }\n\n    png_write_end(write_ptr, write_info);\n\n    for (i = 0; i < (int) imageInfo.height; i++) {\n        free(outRows[i]);\n    }\n    free(outRows);\n    free(unknowns[0].data);\n    free(unknowns[1].data);\n    free(unknowns[2].data);\n\n    png_get_IHDR(write_ptr, write_info, &width, &height,\n       &bit_depth, &color_type, &interlace_type,\n       &compression_type, NULL);\n\n    if (kIsDebug) {\n        printf(\"Image written: w=%d, h=%d, d=%d, colors=%d, inter=%d, comp=%d\\n\",\n                (int)width, (int)height, bit_depth, color_type, interlace_type,\n                compression_type);\n    }\n}\n\nstatic bool read_png_protected(png_structp read_ptr, String8& printableName, png_infop read_info,\n                               const sp<AaptFile>& file, FILE* fp, image_info* imageInfo) {\n    if (setjmp(png_jmpbuf(read_ptr))) {\n        return false;\n    }\n\n    png_init_io(read_ptr, fp);\n\n    read_png(printableName.string(), read_ptr, read_info, imageInfo);\n\n    const size_t nameLen = file->getPath().length();\n    if (nameLen > 6) {\n        const char* name = file->getPath().string();\n        if (name[nameLen-5] == '9' && name[nameLen-6] == '.') {\n            if (do_9patch(printableName.string(), imageInfo) != NO_ERROR) {\n                return false;\n            }\n        }\n    }\n\n    return true;\n}\n\nstatic bool write_png_protected(png_structp write_ptr, String8& printableName, png_infop write_info,\n                                image_info* imageInfo, const Bundle* bundle) {\n    if (setjmp(png_jmpbuf(write_ptr))) {\n        return false;\n    }\n\n    write_png(printableName.string(), write_ptr, write_info, *imageInfo, bundle);\n\n    return true;\n}\n\nstatus_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& /* assets */,\n                         const sp<AaptFile>& file, String8* /* outNewLeafName */)\n{\n    String8 ext(file->getPath().getPathExtension());\n\n    // We currently only process PNG images.\n    if (strcmp(ext.string(), \".png\") != 0) {\n        return NO_ERROR;\n    }\n\n    // Example of renaming a file:\n    //*outNewLeafName = file->getPath().getBasePath().getFileName();\n    //outNewLeafName->append(\".nupng\");\n\n    String8 printableName(file->getPrintableSource());\n\n    if (bundle->getVerbose()) {\n        printf(\"Processing image: %s\\n\", printableName.string());\n    }\n\n    png_structp read_ptr = NULL;\n    png_infop read_info = NULL;\n    FILE* fp;\n\n    image_info imageInfo;\n\n    png_structp write_ptr = NULL;\n    png_infop write_info = NULL;\n\n    status_t error = UNKNOWN_ERROR;\n\n    fp = fopen(file->getSourceFile().string(), \"rb\");\n    if (fp == NULL) {\n        fprintf(stderr, \"%s: ERROR: Unable to open PNG file\\n\", printableName.string());\n        goto bail;\n    }\n\n    read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, (png_error_ptr)NULL,\n                                        (png_error_ptr)NULL);\n    if (!read_ptr) {\n        goto bail;\n    }\n\n    read_info = png_create_info_struct(read_ptr);\n    if (!read_info) {\n        goto bail;\n    }\n\n    if (!read_png_protected(read_ptr, printableName, read_info, file, fp, &imageInfo)) {\n        goto bail;\n    }\n\n    write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, (png_error_ptr)NULL,\n                                        (png_error_ptr)NULL);\n    if (!write_ptr)\n    {\n        goto bail;\n    }\n\n    write_info = png_create_info_struct(write_ptr);\n    if (!write_info)\n    {\n        goto bail;\n    }\n\n    png_set_write_fn(write_ptr, (void*)file.get(),\n                     png_write_aapt_file, png_flush_aapt_file);\n\n    if (!write_png_protected(write_ptr, printableName, write_info, &imageInfo, bundle)) {\n        goto bail;\n    }\n\n    error = NO_ERROR;\n\n    if (bundle->getVerbose()) {\n        fseek(fp, 0, SEEK_END);\n        size_t oldSize = (size_t)ftell(fp);\n        size_t newSize = file->getSize();\n        float factor = ((float)newSize)/oldSize;\n        int percent = (int)(factor*100);\n        printf(\"    (processed image %s: %d%% size of source)\\n\", printableName.string(), percent);\n    }\n\nbail:\n    if (read_ptr) {\n        png_destroy_read_struct(&read_ptr, &read_info, (png_infopp)NULL);\n    }\n    if (fp) {\n        fclose(fp);\n    }\n    if (write_ptr) {\n        png_destroy_write_struct(&write_ptr, &write_info);\n    }\n\n    if (error != NO_ERROR) {\n        fprintf(stderr, \"ERROR: Failure processing PNG image %s\\n\",\n                file->getPrintableSource().string());\n    }\n    return error;\n}\n\nstatus_t preProcessImageToCache(const Bundle* bundle, const String8& source, const String8& dest)\n{\n    png_structp read_ptr = NULL;\n    png_infop read_info = NULL;\n\n    FILE* fp;\n\n    image_info imageInfo;\n\n    png_structp write_ptr = NULL;\n    png_infop write_info = NULL;\n\n    status_t error = UNKNOWN_ERROR;\n\n    if (bundle->getVerbose()) {\n        printf(\"Processing image to cache: %s => %s\\n\", source.string(), dest.string());\n    }\n\n    // Get a file handler to read from\n    fp = fopen(source.string(),\"rb\");\n    if (fp == NULL) {\n        fprintf(stderr, \"%s ERROR: Unable to open PNG file\\n\", source.string());\n        return error;\n    }\n\n    // Call libpng to get a struct to read image data into\n    read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);\n    if (!read_ptr) {\n        fclose(fp);\n        png_destroy_read_struct(&read_ptr, &read_info,NULL);\n        return error;\n    }\n\n    // Call libpng to get a struct to read image info into\n    read_info = png_create_info_struct(read_ptr);\n    if (!read_info) {\n        fclose(fp);\n        png_destroy_read_struct(&read_ptr, &read_info,NULL);\n        return error;\n    }\n\n    // Set a jump point for libpng to long jump back to on error\n    if (setjmp(png_jmpbuf(read_ptr))) {\n        fclose(fp);\n        png_destroy_read_struct(&read_ptr, &read_info,NULL);\n        return error;\n    }\n\n    // Set up libpng to read from our file.\n    png_init_io(read_ptr,fp);\n\n    // Actually read data from the file\n    read_png(source.string(), read_ptr, read_info, &imageInfo);\n\n    // We're done reading so we can clean up\n    // Find old file size before releasing handle\n    fseek(fp, 0, SEEK_END);\n    size_t oldSize = (size_t)ftell(fp);\n    fclose(fp);\n    png_destroy_read_struct(&read_ptr, &read_info,NULL);\n\n    // Check to see if we're dealing with a 9-patch\n    // If we are, process appropriately\n    if (source.getBasePath().getPathExtension() == \".9\")  {\n        if (do_9patch(source.string(), &imageInfo) != NO_ERROR) {\n            return error;\n        }\n    }\n\n    // Call libpng to create a structure to hold the processed image data\n    // that can be written to disk\n    write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);\n    if (!write_ptr) {\n        png_destroy_write_struct(&write_ptr, &write_info);\n        return error;\n    }\n\n    // Call libpng to create a structure to hold processed image info that can\n    // be written to disk\n    write_info = png_create_info_struct(write_ptr);\n    if (!write_info) {\n        png_destroy_write_struct(&write_ptr, &write_info);\n        return error;\n    }\n\n    // Open up our destination file for writing\n    fp = fopen(dest.string(), \"wb\");\n    if (!fp) {\n        fprintf(stderr, \"%s ERROR: Unable to open PNG file\\n\", dest.string());\n        png_destroy_write_struct(&write_ptr, &write_info);\n        return error;\n    }\n\n    // Set up libpng to write to our file\n    png_init_io(write_ptr, fp);\n\n    // Set up a jump for libpng to long jump back on on errors\n    if (setjmp(png_jmpbuf(write_ptr))) {\n        fclose(fp);\n        png_destroy_write_struct(&write_ptr, &write_info);\n        return error;\n    }\n\n    // Actually write out to the new png\n    write_png(dest.string(), write_ptr, write_info, imageInfo, bundle);\n\n    if (bundle->getVerbose()) {\n        // Find the size of our new file\n        FILE* reader = fopen(dest.string(), \"rb\");\n        fseek(reader, 0, SEEK_END);\n        size_t newSize = (size_t)ftell(reader);\n        fclose(reader);\n\n        float factor = ((float)newSize)/oldSize;\n        int percent = (int)(factor*100);\n        printf(\"  (processed image to cache entry %s: %d%% size of source)\\n\",\n               dest.string(), percent);\n    }\n\n    //Clean up\n    fclose(fp);\n    png_destroy_write_struct(&write_ptr, &write_info);\n\n    return NO_ERROR;\n}\n\nstatus_t postProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,\n                          ResourceTable* table, const sp<AaptFile>& file)\n{\n    String8 ext(file->getPath().getPathExtension());\n\n    // At this point, now that we have all the resource data, all we need to\n    // do is compile XML files.\n    if (strcmp(ext.string(), \".xml\") == 0) {\n        String16 resourceName(parseResourceName(file->getSourceFile().getPathLeaf()));\n        return compileXmlFile(bundle, assets, resourceName, file, table);\n    }\n\n    return NO_ERROR;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/Images.h",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#ifndef IMAGES_H\n#define IMAGES_H\n\n#include \"ResourceTable.h\"\n#include \"Bundle.h\"\n\n#include <utils/String8.h>\n#include <utils/RefBase.h>\n\nusing android::String8;\n\nstatus_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,\n                         const sp<AaptFile>& file, String8* outNewLeafName);\n\nstatus_t preProcessImageToCache(const Bundle* bundle, const String8& source, const String8& dest);\n\nstatus_t postProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,\n                          ResourceTable* table, const sp<AaptFile>& file);\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/IndentPrinter.h",
    "content": "#ifndef __INDENT_PRINTER_H\n#define __INDENT_PRINTER_H\n\nclass IndentPrinter {\npublic:\n    IndentPrinter(FILE* stream, int indentSize=2)\n        : mStream(stream)\n        , mIndentSize(indentSize)\n        , mIndent(0)\n        , mNeedsIndent(true) {\n    }\n\n    void indent(int amount = 1) {\n        mIndent += amount;\n        if (mIndent < 0) {\n            mIndent = 0;\n        }\n    }\n\n    void print(const char* fmt, ...) {\n        doIndent();\n        va_list args;\n        va_start(args, fmt);\n        vfprintf(mStream, fmt, args);\n        va_end(args);\n    }\n\n    void println(const char* fmt, ...) {\n        doIndent();\n        va_list args;\n        va_start(args, fmt);\n        vfprintf(mStream, fmt, args);\n        va_end(args);\n        fputs(\"\\n\", mStream);\n        mNeedsIndent = true;\n    }\n\n    void println() {\n        doIndent();\n        fputs(\"\\n\", mStream);\n        mNeedsIndent = true;\n    }\n\nprivate:\n    void doIndent() {\n        if (mNeedsIndent) {\n            int numSpaces = mIndent * mIndentSize;\n            while (numSpaces > 0) {\n                fputs(\" \", mStream);\n                numSpaces--;\n            }\n            mNeedsIndent = false;\n        }\n    }\n\n    FILE* mStream;\n    const int mIndentSize;\n    int mIndent;\n    bool mNeedsIndent;\n};\n\n#endif // __INDENT_PRINTER_H\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/Main.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Android Asset Packaging Tool main entry point.\n//\n#include \"Main.h\"\n#include \"Bundle.h\"\n\n#include <utils/Compat.h>\n#include <utils/Log.h>\n#include <utils/threads.h>\n#include <utils/List.h>\n#include <utils/Errors.h>\n\n#include <cstdlib>\n#include <getopt.h>\n#include <cassert>\n#include <androidfw/ResourcePackageId.h>\n\nusing namespace android;\n\nstatic const char* gProgName = \"aapt\";\n\n/*\n * When running under Cygwin on Windows, this will convert slash-based\n * paths into back-slash-based ones. Otherwise the ApptAssets file comparisons\n * fail later as they use back-slash separators under Windows.\n *\n * This operates in-place on the path string.\n */\nvoid convertPath(char *path) {\n  if (path != NULL && OS_PATH_SEPARATOR != '/') {\n    for (; *path; path++) {\n      if (*path == '/') {\n        *path = OS_PATH_SEPARATOR;\n      }\n    }\n  }\n}\n\n/*\n * Print usage info.\n */\nvoid usage(void)\n{\n    fprintf(stderr, \"Android Asset Packaging Tool\\n\\n\");\n    fprintf(stderr, \"Usage:\\n\");\n    fprintf(stderr,\n        \" %s l[ist] [-v] [-a] file.{zip,jar,apk}\\n\"\n        \"   List contents of Zip-compatible archive.\\n\\n\", gProgName);\n    fprintf(stderr,\n        \" %s d[ump] [--values] [--include-meta-data] WHAT file.{apk} [asset [asset ...]]\\n\"\n        \"   strings          Print the contents of the resource table string pool in the APK.\\n\"\n        \"   badging          Print the label and icon for the app declared in APK.\\n\"\n        \"   permissions      Print the permissions from the APK.\\n\"\n        \"   resources        Print the resource table from the APK.\\n\"\n        \"   configurations   Print the configurations in the APK.\\n\"\n        \"   xmltree          Print the compiled xmls in the given assets.\\n\"\n        \"   xmlstrings       Print the strings of the given compiled xml assets.\\n\\n\", gProgName);\n    fprintf(stderr,\n        \" %s p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] \\\\\\n\"\n        \"        [-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] \\\\\\n\"\n        \"        [--debug-mode] [--min-sdk-version VAL] [--target-sdk-version VAL] \\\\\\n\"\n        \"        [--app-version VAL] [--app-version-name TEXT] [--custom-package VAL] \\\\\\n\"\n        \"        [--rename-manifest-package PACKAGE] \\\\\\n\"\n        \"        [--rename-instrumentation-target-package PACKAGE] \\\\\\n\"\n        \"        [--utf16] [--auto-add-overlay] \\\\\\n\"\n        \"        [--max-res-version VAL] \\\\\\n\"\n        \"        [-I base-package [-I base-package ...]] \\\\\\n\"\n        \"        [-A asset-source-dir]  [-G class-list-file] [-P public-definitions-file] \\\\\\n\"\n        \"        [-D main-dex-class-list-file] \\\\\\n\"\n        \"        [-S resource-sources [-S resource-sources ...]] \\\\\\n\"\n        \"        [-F apk-file] [-J R-file-dir] \\\\\\n\"\n        \"        [--product product1,product2,...] \\\\\\n\"\n        \"        [-c CONFIGS] [--preferred-density DENSITY] \\\\\\n\"\n        \"        [--split CONFIGS [--split CONFIGS]] \\\\\\n\"\n        \"        [--feature-of package [--feature-after package]] \\\\\\n\"\n        \"        [raw-files-dir [raw-files-dir] ...] \\\\\\n\"\n        \"        [-B apk-file] \\\\\\n\"\n        \"        [--output-text-symbols DIR]\\n\"\n        \"\\n\"\n        \"   Package the android resources.  It will read assets and resources that are\\n\"\n        \"   supplied with the -M -A -S or raw-files-dir arguments.  The -J -P -F and -R\\n\"\n        \"   options control which files are output.\\n\\n\"\n        , gProgName);\n    fprintf(stderr,\n        \" %s r[emove] [-v] file.{zip,jar,apk} file1 [file2 ...]\\n\"\n        \"   Delete specified files from Zip-compatible archive.\\n\\n\",\n        gProgName);\n    fprintf(stderr,\n        \" %s a[dd] [-v] file.{zip,jar,apk} file1 [file2 ...]\\n\"\n        \"   Add specified files to Zip-compatible archive.\\n\\n\", gProgName);\n    fprintf(stderr,\n        \" %s c[runch] [-v] -S resource-sources ... -C output-folder ...\\n\"\n        \"   Do PNG preprocessing on one or several resource folders\\n\"\n        \"   and store the results in the output folder.\\n\\n\", gProgName);\n    fprintf(stderr,\n        \" %s s[ingleCrunch] [-v] -i input-file -o outputfile\\n\"\n        \"   Do PNG preprocessing on a single file.\\n\\n\", gProgName);\n    fprintf(stderr,\n        \" %s v[ersion]\\n\"\n        \"   Print program version.\\n\\n\", gProgName);\n    fprintf(stderr,\n        \" Modifiers:\\n\"\n        \"   -a  print Android-specific data (resources, manifest) when listing\\n\"\n        \"   -c  specify which configurations to include.  The default is all\\n\"\n        \"       configurations.  The value of the parameter should be a comma\\n\"\n        \"       separated list of configuration values.  Locales should be specified\\n\"\n        \"       as either a language or language-region pair.  Some examples:\\n\"\n        \"            en\\n\"\n        \"            port,en\\n\"\n        \"            port,land,en_US\\n\"\n        \"   -d  one or more device assets to include, separated by commas\\n\"\n        \"   -f  force overwrite of existing files\\n\"\n        \"   -g  specify a pixel tolerance to force images to grayscale, default 0\\n\"\n        \"   -j  specify a jar or zip file containing classes to include\\n\"\n        \"   -k  junk path of file(s) added\\n\"\n        \"   -m  make package directories under location specified by -J\\n\"\n        \"   -u  update existing packages (add new, replace older, remove deleted files)\\n\"\n        \"   -v  verbose output\\n\"\n        \"   -x  create extending (non-application) resource IDs\\n\"\n        \"   -z  require localization of resource attributes marked with\\n\"\n        \"       localization=\\\"suggested\\\"\\n\"\n        \"   -A  additional directory in which to find raw asset files\\n\"\n        \"   -G  A file to output proguard options into.\\n\"\n        \"   -D  A file to output proguard options for the main dex into.\\n\"\n        \"   -F  specify the apk file to output\\n\"\n        \"   -I  add an existing package to base include set\\n\"\n        \"   -J  specify where to output R.java resource constant definitions\\n\"\n        \"   -M  specify full path to AndroidManifest.xml to include in zip\\n\"\n        \"   -P  specify where to output public resource definitions\\n\"\n        \"   -S  directory in which to find resources.  Multiple directories will be scanned\\n\"\n        \"       and the first match found (left to right) will take precedence.\\n\"\n        \"   -0  specifies an additional extension for which such files will not\\n\"\n        \"       be stored compressed in the .apk.  An empty string means to not\\n\"\n        \"       compress any files at all.\\n\"\n        \"   --debug-mode\\n\"\n        \"       inserts android:debuggable=\\\"true\\\" in to the application node of the\\n\"\n        \"       manifest, making the application debuggable even on production devices.\\n\"\n        \"   --include-meta-data\\n\"\n        \"       when used with \\\"dump badging\\\" also includes meta-data tags.\\n\"\n        \"   --pseudo-localize\\n\"\n        \"       generate resources for pseudo-locales (en-XA and ar-XB).\\n\"\n        \"   --min-sdk-version\\n\"\n        \"       inserts android:minSdkVersion in to manifest.  If the version is 7 or\\n\"\n        \"       higher, the default encoding for resources will be in UTF-8.\\n\"\n        \"   --target-sdk-version\\n\"\n        \"       inserts android:targetSdkVersion in to manifest.\\n\"\n        \"   --max-res-version\\n\"\n        \"       ignores versioned resource directories above the given value.\\n\"\n        \"   --values\\n\"\n        \"       when used with \\\"dump resources\\\" also includes resource values.\\n\"\n        \"   --version-code\\n\"\n        \"       inserts android:versionCode in to manifest.\\n\"\n        \"   --version-name\\n\"\n        \"       inserts android:versionName in to manifest.\\n\"\n        \"   --replace-version\\n\"\n        \"       If --version-code and/or --version-name are specified, these\\n\"\n        \"       values will replace any value already in the manifest. By\\n\"\n        \"       default, nothing is changed if the manifest already defines\\n\"\n        \"       these attributes.\\n\"\n        \"   --custom-package\\n\"\n        \"       generates R.java into a different package.\\n\"\n        \"   --extra-packages\\n\"\n        \"       generate R.java for libraries. Separate libraries with ':'.\\n\"\n        \"   --generate-dependencies\\n\"\n        \"       generate dependency files in the same directories for R.java and resource package\\n\"\n        \"   --auto-add-overlay\\n\"\n        \"       Automatically add resources that are only in overlays.\\n\"\n        \"   --preferred-density\\n\"\n        \"       Specifies a preference for a particular density. Resources that do not\\n\"\n        \"       match this density and have variants that are a closer match are removed.\\n\"\n        \"   --split\\n\"\n        \"       Builds a separate split APK for the configurations listed. This can\\n\"\n        \"       be loaded alongside the base APK at runtime.\\n\"\n        \"   --feature-of\\n\"\n        \"       Builds a split APK that is a feature of the apk specified here. Resources\\n\"\n        \"       in the base APK can be referenced from the the feature APK.\\n\"\n        \"   --feature-after\\n\"\n        \"       An app can have multiple Feature Split APKs which must be totally ordered.\\n\"\n        \"       If --feature-of is specified, this flag specifies which Feature Split APK\\n\"\n        \"       comes before this one. The first Feature Split APK should not define\\n\"\n        \"       anything here.\\n\"\n        \"   --rename-manifest-package\\n\"\n        \"       Rewrite the manifest so that its package name is the package name\\n\"\n        \"       given here.  Relative class names (for example .Foo) will be\\n\"\n        \"       changed to absolute names with the old package so that the code\\n\"\n        \"       does not need to change.\\n\"\n        \"   --rename-instrumentation-target-package\\n\"\n        \"       Rewrite the manifest so that all of its instrumentation\\n\"\n        \"       components target the given package.  Useful when used in\\n\"\n        \"       conjunction with --rename-manifest-package to fix tests against\\n\"\n        \"       a package that has been renamed.\\n\"\n        \"   --product\\n\"\n        \"       Specifies which variant to choose for strings that have\\n\"\n        \"       product variants\\n\"\n        \"   --utf16\\n\"\n        \"       changes default encoding for resources to UTF-16.  Only useful when API\\n\"\n        \"       level is set to 7 or higher where the default encoding is UTF-8.\\n\"\n        \"   --non-constant-id\\n\"\n        \"       Make the resources ID non constant. This is required to make an R java class\\n\"\n        \"       that does not contain the final value but is used to make reusable compiled\\n\"\n        \"       libraries that need to access resources.\\n\"\n        \"   --shared-lib\\n\"\n        \"       Make a shared library resource package that can be loaded by an application\\n\"\n        \"       at runtime to access the libraries resources. Implies --non-constant-id.\\n\"\n        \"   --app-as-shared-lib\\n\"\n        \"       Make an app resource package that also can be loaded as shared library at runtime.\\n\"\n        \"       Implies --non-constant-id.\\n\"\n        \"   --error-on-failed-insert\\n\"\n        \"       Forces aapt to return an error if it fails to insert values into the manifest\\n\"\n        \"       with --debug-mode, --min-sdk-version, --target-sdk-version --version-code\\n\"\n        \"       and --version-name.\\n\"\n        \"       Insertion typically fails if the manifest already defines the attribute.\\n\"\n        \"   --error-on-missing-config-entry\\n\"\n        \"       Forces aapt to return an error if it fails to find an entry for a configuration.\\n\"\n        \"   --output-text-symbols\\n\"\n        \"       Generates a text file containing the resource symbols of the R class in the\\n\"\n        \"       specified folder.\\n\"\n        \"   --ignore-assets\\n\"\n        \"       Assets to be ignored. Default pattern is:\\n\"\n        \"       %s\\n\"\n        \"   --skip-symbols-without-default-localization\\n\"\n        \"       Prevents symbols from being generated for strings that do not have a default\\n\"\n        \"       localization\\n\"\n        \"   --no-version-vectors\\n\"\n        \"       Do not automatically generate versioned copies of vector XML resources.\\n\"\n        \"   --private-symbols\\n\"\n        \"       Java package name to use when generating R.java for private resources.\\n\"/*,*/\n        \"   --customized-package-id\\n\"\n        \"       By default, package id should be 127 in R.java of application,\\n\"\n        \"       using thie parametor would change the id to other value\\n\"\n        \"   --use-skt-package-name\\n\"\n        \"       use skt package name as resource arsc package name !!\\n\"\n        \"   -B  specify the baseline apk file for output\\n\",\n        gDefaultIgnoreAssets);\n}\n\n/*\n * Dispatch the command.\n */\nint handleCommand(Bundle* bundle)\n{\n    //printf(\"--- command %d (verbose=%d force=%d):\\n\",\n    //    bundle->getCommand(), bundle->getVerbose(), bundle->getForce());\n    //for (int i = 0; i < bundle->getFileSpecCount(); i++)\n    //    printf(\"  %d: '%s'\\n\", i, bundle->getFileSpecEntry(i));\n\n    switch (bundle->getCommand()) {\n    case kCommandVersion:      return doVersion(bundle);\n    case kCommandList:         return doList(bundle);\n    case kCommandDump:         return doDump(bundle);\n    case kCommandAdd:          return doAdd(bundle);\n    case kCommandRemove:       return doRemove(bundle);\n    case kCommandPackage:      return doPackage(bundle);\n    case kCommandCrunch:       return doCrunch(bundle);\n    case kCommandSingleCrunch: return doSingleCrunch(bundle);\n    case kCommandDaemon:       return runInDaemonMode(bundle);\n    default:\n        fprintf(stderr, \"%s: requested command not yet supported\\n\", gProgName);\n        return 1;\n    }\n}\n\n/*\n * Parse args.\n */\nint main(int argc, char* const argv[])\n{\n    char *prog = argv[0];\n    Bundle bundle;\n    bool wantUsage = false;\n    int result = 1;    // pessimistically assume an error.\n    int tolerance = 0;\n\n    /* default to compression */\n    bundle.setCompressionMethod(ZipEntry::kCompressDeflated);\n\n    if (argc < 2) {\n        wantUsage = true;\n        goto bail;\n    }\n\n    if (argv[1][0] == 'v')\n        bundle.setCommand(kCommandVersion);\n    else if (argv[1][0] == 'd')\n        bundle.setCommand(kCommandDump);\n    else if (argv[1][0] == 'l')\n        bundle.setCommand(kCommandList);\n    else if (argv[1][0] == 'a')\n        bundle.setCommand(kCommandAdd);\n    else if (argv[1][0] == 'r')\n        bundle.setCommand(kCommandRemove);\n    else if (argv[1][0] == 'p')\n        bundle.setCommand(kCommandPackage);\n    else if (argv[1][0] == 'c')\n        bundle.setCommand(kCommandCrunch);\n    else if (argv[1][0] == 's')\n        bundle.setCommand(kCommandSingleCrunch);\n    else if (argv[1][0] == 'm')\n        bundle.setCommand(kCommandDaemon);\n    else {\n        fprintf(stderr, \"ERROR: Unknown command '%s'\\n\", argv[1]);\n        wantUsage = true;\n        goto bail;\n    }\n    argc -= 2;\n    argv += 2;\n\n    /*\n     * Pull out flags.  We support \"-fv\" and \"-f -v\".\n     */\n    while (argc && argv[0][0] == '-') {\n        /* flag(s) found */\n        const char* cp = argv[0] +1;\n\n        while (*cp != '\\0') {\n            switch (*cp) {\n            case 'v':\n                bundle.setVerbose(true);\n                break;\n            case 'a':\n                bundle.setAndroidList(true);\n                break;\n            case 'c':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-c' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                bundle.addConfigurations(argv[0]);\n                break;\n            case 'f':\n                bundle.setForce(true);\n                break;\n            case 'g':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-g' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                tolerance = atoi(argv[0]);\n                bundle.setGrayscaleTolerance(tolerance);\n                printf(\"%s: Images with deviation <= %d will be forced to grayscale.\\n\", prog, tolerance);\n                break;\n            case 'k':\n                bundle.setJunkPath(true);\n                break;\n            case 'm':\n                bundle.setMakePackageDirs(true);\n                break;\n#if 0\n            case 'p':\n                bundle.setPseudolocalize(true);\n                break;\n#endif\n            case 'u':\n                bundle.setUpdate(true);\n                break;\n            case 'x':\n                bundle.setExtending(true);\n                break;\n            case 'z':\n                bundle.setRequireLocalization(true);\n                break;\n            case 'j':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-j' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.addJarFile(argv[0]);\n                break;\n            case 'A':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-A' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.addAssetSourceDir(argv[0]);\n                break;\n            case 'G':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-G' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setProguardFile(argv[0]);\n                break;\n            case 'D':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-D' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setMainDexProguardFile(argv[0]);\n                break;\n            case 'I':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-I' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.addPackageInclude(argv[0]);\n                break;\n            case 'B':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-B' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setBaselinePackage(argv[0]);\n                break;\n            case 'F':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-F' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setOutputAPKFile(argv[0]);\n                break;\n            case 'J':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-J' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setRClassDir(argv[0]);\n                break;\n            case 'M':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-M' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setAndroidManifestFile(argv[0]);\n                break;\n            case 'P':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-P' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setPublicOutputFile(argv[0]);\n                break;\n            case 'S':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-S' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.addResourceSourceDir(argv[0]);\n                break;\n            case 'C':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-C' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setCrunchedOutputDir(argv[0]);\n                break;\n            case 'i':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-i' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setSingleCrunchInputFile(argv[0]);\n                break;\n            case 'o':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-o' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setSingleCrunchOutputFile(argv[0]);\n                break;\n            case '0':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-e' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                if (argv[0][0] != 0) {\n                    bundle.addNoCompressExtension(argv[0]);\n                } else {\n                    bundle.setCompressionMethod(ZipEntry::kCompressStored);\n                }\n                break;\n            case '-':\n                if (strcmp(cp, \"-debug-mode\") == 0) {\n                    bundle.setDebugMode(true);\n                } else if (strcmp(cp, \"-min-sdk-version\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--min-sdk-version' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setMinSdkVersion(argv[0]);\n                } else if (strcmp(cp, \"-target-sdk-version\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--target-sdk-version' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setTargetSdkVersion(argv[0]);\n                } else if (strcmp(cp, \"-max-sdk-version\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--max-sdk-version' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setMaxSdkVersion(argv[0]);\n                } else if (strcmp(cp, \"-max-res-version\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--max-res-version' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setMaxResVersion(argv[0]);\n                } else if (strcmp(cp, \"-version-code\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--version-code' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setVersionCode(argv[0]);\n                } else if (strcmp(cp, \"-version-name\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--version-name' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setVersionName(argv[0]);\n                } else if (strcmp(cp, \"-replace-version\") == 0) {\n                    bundle.setReplaceVersion(true);\n                } else if (strcmp(cp, \"-values\") == 0) {\n                    bundle.setValues(true);\n                } else if (strcmp(cp, \"-include-meta-data\") == 0) {\n                    bundle.setIncludeMetaData(true);\n                } else if (strcmp(cp, \"-custom-package\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--custom-package' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setCustomPackage(argv[0]);\n                } else if (strcmp(cp, \"-extra-packages\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--extra-packages' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setExtraPackages(argv[0]);\n                } else if (strcmp(cp, \"-generate-dependencies\") == 0) {\n                    bundle.setGenDependencies(true);\n                } else if (strcmp(cp, \"-utf16\") == 0) {\n                    bundle.setWantUTF16(true);\n                } else if (strcmp(cp, \"-preferred-density\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--preferred-density' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setPreferredDensity(argv[0]);\n                } else if (strcmp(cp, \"-split\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--split' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.addSplitConfigurations(argv[0]);\n                } else if (strcmp(cp, \"-feature-of\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--feature-of' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setFeatureOfPackage(argv[0]);\n                } else if (strcmp(cp, \"-feature-after\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--feature-after' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setFeatureAfterPackage(argv[0]);\n                } else if (strcmp(cp, \"-rename-manifest-package\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--rename-manifest-package' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setManifestPackageNameOverride(argv[0]);\n                } else if (strcmp(cp, \"-rename-instrumentation-target-package\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--rename-instrumentation-target-package' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setInstrumentationPackageNameOverride(argv[0]);\n                } else if (strcmp(cp, \"-auto-add-overlay\") == 0) {\n                    bundle.setAutoAddOverlay(true);\n                } else if (strcmp(cp, \"-error-on-failed-insert\") == 0) {\n                    bundle.setErrorOnFailedInsert(true);\n                } else if (strcmp(cp, \"-error-on-missing-config-entry\") == 0) {\n                    bundle.setErrorOnMissingConfigEntry(true);\n                } else if (strcmp(cp, \"-output-text-symbols\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '-output-text-symbols' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setOutputTextSymbols(argv[0]);\n                } else if (strcmp(cp, \"-product\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--product' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setProduct(argv[0]);\n                } else if (strcmp(cp, \"-non-constant-id\") == 0) {\n                    bundle.setNonConstantId(true);\n                } else if (strcmp(cp, \"-skip-symbols-without-default-localization\") == 0) {\n                    bundle.setSkipSymbolsWithoutDefaultLocalization(true);\n                } else if (strcmp(cp, \"-shared-lib\") == 0) {\n                    bundle.setNonConstantId(true);\n                    bundle.setBuildSharedLibrary(true);\n                } else if (strcmp(cp, \"-app-as-shared-lib\") == 0) {\n                    bundle.setNonConstantId(true);\n                    bundle.setBuildAppAsSharedLibrary(true);\n                } else if (strcmp(cp, \"-no-crunch\") == 0) {\n                    bundle.setUseCrunchCache(true);\n                } else if (strcmp(cp, \"-ignore-assets\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--ignore-assets' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    gUserIgnoreAssets = argv[0];\n                } else if (strcmp(cp, \"-pseudo-localize\") == 0) {\n                    bundle.setPseudolocalize(PSEUDO_ACCENTED | PSEUDO_BIDI);\n                } else if (strcmp(cp, \"-no-version-vectors\") == 0) {\n                    bundle.setNoVersionVectors(true);\n                } else if (strcmp(cp, \"-private-symbols\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for \"\n                                \"'--private-symbols' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setPrivateSymbolsPackage(String8(argv[0]));\n                } else if (strcmp(cp, \"-customized-package-id\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--customized-package-id' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    customePackageId = atoi(argv[0]); \n                    if (customePackageId > 127 || customePackageId <= 0) {\n                        fprintf(stderr, \"ERROR:  '--customized-package-id' option value should between 0 and 127\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                } else if (strcmp(cp, \"-use-skt-package-name\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--use-skt-package-name' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    sktPackageName = argv[0];  \n                } else {\n                    fprintf(stderr, \"ERROR: Unknown option '-%s'\\n\", cp);\n                    wantUsage = true;\n                    goto bail;\n                }\n                cp += strlen(cp) - 1;\n                break;\n            default:\n                fprintf(stderr, \"ERROR: Unknown flag '-%c'\\n\", *cp);\n                wantUsage = true;\n                goto bail;\n            }\n\n            cp++;\n        }\n        argc--;\n        argv++;\n    }\n\n    /*\n     * We're past the flags.  The rest all goes straight in.\n     */\n    bundle.setFileSpec(argv, argc);\n\n    result = handleCommand(&bundle);\n\nbail:\n    if (wantUsage) {\n        usage();\n        result = 2;\n    }\n\n    //printf(\"--> returning %d\\n\", result);\n    return result;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/Main.h",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Some global defines that don't really merit their own header.\n//\n#ifndef __MAIN_H\n#define __MAIN_H\n\n#include <utils/Log.h>\n#include <utils/threads.h>\n#include <utils/List.h>\n#include <utils/Errors.h>\n#include <utils/StrongPointer.h>\n\n#include \"AaptAssets.h\"\n#include \"ApkBuilder.h\"\n#include \"Bundle.h\"\n#include \"ResourceFilter.h\"\n#include \"ZipFile.h\"\n\n\n/* Benchmarking Flag */\n//#define BENCHMARK 1\n\n#if BENCHMARK\n    #include <time.h>\n#endif /* BENCHMARK */\n\nclass OutputSet;\n\nextern int doVersion(Bundle* bundle);\nextern int doList(Bundle* bundle);\nextern int doDump(Bundle* bundle);\nextern int doAdd(Bundle* bundle);\nextern int doRemove(Bundle* bundle);\nextern int doPackage(Bundle* bundle);\nextern int doCrunch(Bundle* bundle);\nextern int doSingleCrunch(Bundle* bundle);\nextern int runInDaemonMode(Bundle* bundle);\n\nextern int calcPercent(long uncompressedLen, long compressedLen);\n\nextern android::status_t writeAPK(Bundle* bundle,\n    const android::String8& outputFile,\n    const android::sp<OutputSet>& outputSet);\n\nextern android::status_t updatePreProcessedCache(Bundle* bundle);\n\nextern android::status_t buildResources(Bundle* bundle,\n    const sp<AaptAssets>& assets, sp<ApkBuilder>& builder);\n\nextern android::status_t writeResourceSymbols(Bundle* bundle,\n        const sp<AaptAssets>& assets, const String8& pkgName,\n        bool includePrivate, bool emitCallback);\n\nextern android::status_t writeProguardFile(Bundle* bundle, const sp<AaptAssets>& assets);\nextern android::status_t writeMainDexProguardFile(Bundle* bundle, const sp<AaptAssets>& assets);\n\nextern bool isValidResourceType(const String8& type);\n\nextern status_t filterResources(Bundle* bundle, const sp<AaptAssets>& assets);\n\nint dumpResources(Bundle* bundle);\n\nstatus_t writeDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets,\n                                FILE* fp, bool includeRaw);\n\nandroid::String8 parseResourceName(const String8& pathLeaf);\n\n#endif // __MAIN_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/NOTICE",
    "content": "\n   Copyright (c) 2005-2008, The Android Open Source Project\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/OutputSet.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __OUTPUT_SET_H\n#define __OUTPUT_SET_H\n\n#include <set>\n#include <utils/Errors.h>\n#include <utils/String8.h>\n#include <utils/StrongPointer.h>\n\nclass AaptFile;\n\nclass OutputEntry {\npublic:\n    OutputEntry() {}\n    OutputEntry(const android::String8& path, const android::sp<const AaptFile>& file)\n        : mPath(path), mFile(file) {}\n\n    inline const android::sp<const AaptFile>& getFile() const {\n        return mFile;\n    }\n\n    inline const android::String8& getPath() const {\n        return mPath;\n    }\n\n    bool operator<(const OutputEntry& o) const { return getPath() < o.mPath; }\n    bool operator==(const OutputEntry& o) const { return getPath() == o.mPath; }\n\nprivate:\n    android::String8 mPath;\n    android::sp<const AaptFile> mFile;\n};\n\nclass OutputSet : public virtual android::RefBase {\npublic:\n    virtual const std::set<OutputEntry>& getEntries() const = 0;\n\n    virtual ~OutputSet() {}\n};\n\n#endif // __OUTPUT_SET_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/Package.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Package assets into Zip files.\n//\n#include \"Main.h\"\n#include \"AaptAssets.h\"\n#include \"OutputSet.h\"\n#include \"ResourceTable.h\"\n#include \"ResourceFilter.h\"\n\n#include <androidfw/misc.h>\n\n#include <utils/Log.h>\n#include <utils/threads.h>\n#include <utils/List.h>\n#include <utils/Errors.h>\n#include <utils/misc.h>\n\n#include <sys/types.h>\n#include <dirent.h>\n#include <ctype.h>\n#include <errno.h>\n\nusing namespace android;\n\nstatic const char* kExcludeExtension = \".EXCLUDE\";\n\n/* these formats are already compressed, or don't compress well */\nstatic const char* kNoCompressExt[] = {\n    \".jpg\", \".jpeg\", \".png\", \".gif\",\n    \".wav\", \".mp2\", \".mp3\", \".ogg\", \".aac\",\n    \".mpg\", \".mpeg\", \".mid\", \".midi\", \".smf\", \".jet\",\n    \".rtttl\", \".imy\", \".xmf\", \".mp4\", \".m4a\",\n    \".m4v\", \".3gp\", \".3gpp\", \".3g2\", \".3gpp2\",\n    \".amr\", \".awb\", \".wma\", \".wmv\", \".webm\", \".mkv\"\n};\n\n/* fwd decls, so I can write this downward */\nssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<const OutputSet>& outputSet);\nbool processFile(Bundle* bundle, ZipFile* zip, String8 storageName, const sp<const AaptFile>& file);\nbool okayToCompress(Bundle* bundle, const String8& pathName);\nssize_t processJarFiles(Bundle* bundle, ZipFile* zip);\n\n/*\n * The directory hierarchy looks like this:\n * \"outputDir\" and \"assetRoot\" are existing directories.\n *\n * On success, \"bundle->numPackages\" will be the number of Zip packages\n * we created.\n */\nstatus_t writeAPK(Bundle* bundle, const String8& outputFile, const sp<OutputSet>& outputSet)\n{\n    #if BENCHMARK\n    fprintf(stdout, \"BENCHMARK: Starting APK Bundling \\n\");\n    long startAPKTime = clock();\n    #endif /* BENCHMARK */\n\n    status_t result = NO_ERROR;\n    ZipFile* zip = NULL;\n    int count;\n\n    //bundle->setPackageCount(0);\n\n    /*\n     * Prep the Zip archive.\n     *\n     * If the file already exists, fail unless \"update\" or \"force\" is set.\n     * If \"update\" is set, update the contents of the existing archive.\n     * Else, if \"force\" is set, remove the existing archive.\n     */\n    FileType fileType = getFileType(outputFile.string());\n    if (fileType == kFileTypeNonexistent) {\n        // okay, create it below\n    } else if (fileType == kFileTypeRegular) {\n        if (bundle->getUpdate()) {\n            // okay, open it below\n        } else if (bundle->getForce()) {\n            if (unlink(outputFile.string()) != 0) {\n                fprintf(stderr, \"ERROR: unable to remove '%s': %s\\n\", outputFile.string(),\n                        strerror(errno));\n                goto bail;\n            }\n        } else {\n            fprintf(stderr, \"ERROR: '%s' exists (use '-f' to force overwrite)\\n\",\n                    outputFile.string());\n            goto bail;\n        }\n    } else {\n        fprintf(stderr, \"ERROR: '%s' exists and is not a regular file\\n\", outputFile.string());\n        goto bail;\n    }\n\n    if (bundle->getVerbose()) {\n        printf(\"%s '%s'\\n\", (fileType == kFileTypeNonexistent) ? \"Creating\" : \"Opening\",\n                outputFile.string());\n    }\n\n    status_t status;\n    zip = new ZipFile;\n    status = zip->open(outputFile.string(), ZipFile::kOpenReadWrite | ZipFile::kOpenCreate);\n    if (status != NO_ERROR) {\n        fprintf(stderr, \"ERROR: unable to open '%s' as Zip file for writing\\n\",\n                outputFile.string());\n        goto bail;\n    }\n\n    if (bundle->getVerbose()) {\n        printf(\"Writing all files...\\n\");\n    }\n\n    count = processAssets(bundle, zip, outputSet);\n    if (count < 0) {\n        fprintf(stderr, \"ERROR: unable to process assets while packaging '%s'\\n\",\n                outputFile.string());\n        result = count;\n        goto bail;\n    }\n\n    if (bundle->getVerbose()) {\n        printf(\"Generated %d file%s\\n\", count, (count==1) ? \"\" : \"s\");\n    }\n    \n    count = processJarFiles(bundle, zip);\n    if (count < 0) {\n        fprintf(stderr, \"ERROR: unable to process jar files while packaging '%s'\\n\",\n                outputFile.string());\n        result = count;\n        goto bail;\n    }\n    \n    if (bundle->getVerbose())\n        printf(\"Included %d file%s from jar/zip files.\\n\", count, (count==1) ? \"\" : \"s\");\n    \n    result = NO_ERROR;\n\n    /*\n     * Check for cruft.  We set the \"marked\" flag on all entries we created\n     * or decided not to update.  If the entry isn't already slated for\n     * deletion, remove it now.\n     */\n    {\n        if (bundle->getVerbose())\n            printf(\"Checking for deleted files\\n\");\n        int i, removed = 0;\n        for (i = 0; i < zip->getNumEntries(); i++) {\n            ZipEntry* entry = zip->getEntryByIndex(i);\n\n            if (!entry->getMarked() && entry->getDeleted()) {\n                if (bundle->getVerbose()) {\n                    printf(\"      (removing crufty '%s')\\n\",\n                        entry->getFileName());\n                }\n                zip->remove(entry);\n                removed++;\n            }\n        }\n        if (bundle->getVerbose() && removed > 0)\n            printf(\"Removed %d file%s\\n\", removed, (removed==1) ? \"\" : \"s\");\n    }\n\n    /* tell Zip lib to process deletions and other pending changes */\n    result = zip->flush();\n    if (result != NO_ERROR) {\n        fprintf(stderr, \"ERROR: Zip flush failed, archive may be hosed\\n\");\n        goto bail;\n    }\n\n    /* anything here? */\n    if (zip->getNumEntries() == 0) {\n        if (bundle->getVerbose()) {\n            printf(\"Archive is empty -- removing %s\\n\", outputFile.getPathLeaf().string());\n        }\n        delete zip;        // close the file so we can remove it in Win32\n        zip = NULL;\n        if (unlink(outputFile.string()) != 0) {\n            fprintf(stderr, \"warning: could not unlink '%s'\\n\", outputFile.string());\n        }\n    }\n\n    // If we've been asked to generate a dependency file for the .ap_ package,\n    // do so here\n    if (bundle->getGenDependencies()) {\n        // The dependency file gets output to the same directory\n        // as the specified output file with an additional .d extension.\n        // e.g. bin/resources.ap_.d\n        String8 dependencyFile = outputFile;\n        dependencyFile.append(\".d\");\n\n        FILE* fp = fopen(dependencyFile.string(), \"a\");\n        // Add this file to the dependency file\n        fprintf(fp, \"%s \\\\\\n\", outputFile.string());\n        fclose(fp);\n    }\n\n    assert(result == NO_ERROR);\n\nbail:\n    delete zip;        // must close before remove in Win32\n    if (result != NO_ERROR) {\n        if (bundle->getVerbose()) {\n            printf(\"Removing %s due to earlier failures\\n\", outputFile.string());\n        }\n        if (unlink(outputFile.string()) != 0) {\n            fprintf(stderr, \"warning: could not unlink '%s'\\n\", outputFile.string());\n        }\n    }\n\n    if (result == NO_ERROR && bundle->getVerbose())\n        printf(\"Done!\\n\");\n\n    #if BENCHMARK\n    fprintf(stdout, \"BENCHMARK: End APK Bundling. Time Elapsed: %f ms \\n\",(clock() - startAPKTime)/1000.0);\n    #endif /* BENCHMARK */\n    return result;\n}\n\nssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<const OutputSet>& outputSet)\n{\n    ssize_t count = 0;\n    const std::set<OutputEntry>& entries = outputSet->getEntries();\n    std::set<OutputEntry>::const_iterator iter = entries.begin();\n    for (; iter != entries.end(); iter++) {\n        const OutputEntry& entry = *iter;\n        if (entry.getFile() == NULL) {\n            fprintf(stderr, \"warning: null file being processed.\\n\");\n        } else {\n            String8 storagePath(entry.getPath());\n            storagePath.convertToResPath();\n            if (!processFile(bundle, zip, storagePath, entry.getFile())) {\n                return UNKNOWN_ERROR;\n            }\n            count++;\n        }\n    }\n    return count;\n}\n\n/*\n * Process a regular file, adding it to the archive if appropriate.\n *\n * If we're in \"update\" mode, and the file already exists in the archive,\n * delete the existing entry before adding the new one.\n */\nbool processFile(Bundle* bundle, ZipFile* zip,\n                 String8 storageName, const sp<const AaptFile>& file)\n{\n    const bool hasData = file->hasData();\n\n    ZipEntry* entry;\n    bool fromGzip = false;\n    status_t result;\n\n    /*\n     * See if the filename ends in \".EXCLUDE\".  We can't use\n     * String8::getPathExtension() because the length of what it considers\n     * to be an extension is capped.\n     *\n     * The Asset Manager doesn't check for \".EXCLUDE\" in Zip archives,\n     * so there's no value in adding them (and it makes life easier on\n     * the AssetManager lib if we don't).\n     *\n     * NOTE: this restriction has been removed.  If you're in this code, you\n     * should clean this up, but I'm in here getting rid of Path Name, and I\n     * don't want to make other potentially breaking changes --joeo\n     */\n    int fileNameLen = storageName.length();\n    int excludeExtensionLen = strlen(kExcludeExtension);\n    if (fileNameLen > excludeExtensionLen\n            && (0 == strcmp(storageName.string() + (fileNameLen - excludeExtensionLen),\n                            kExcludeExtension))) {\n        fprintf(stderr, \"warning: '%s' not added to Zip\\n\", storageName.string());\n        return true;\n    }\n\n    if (strcasecmp(storageName.getPathExtension().string(), \".gz\") == 0) {\n        fromGzip = true;\n        storageName = storageName.getBasePath();\n    }\n\n    if (bundle->getUpdate()) {\n        entry = zip->getEntryByName(storageName.string());\n        if (entry != NULL) {\n            /* file already exists in archive; there can be only one */\n            if (entry->getMarked()) {\n                fprintf(stderr,\n                        \"ERROR: '%s' exists twice (check for with & w/o '.gz'?)\\n\",\n                        file->getPrintableSource().string());\n                return false;\n            }\n            if (!hasData) {\n                const String8& srcName = file->getSourceFile();\n                time_t fileModWhen;\n                fileModWhen = getFileModDate(srcName.string());\n                if (fileModWhen == (time_t) -1) { // file existence tested earlier,\n                    return false;                 //  not expecting an error here\n                }\n    \n                if (fileModWhen > entry->getModWhen()) {\n                    // mark as deleted so add() will succeed\n                    if (bundle->getVerbose()) {\n                        printf(\"      (removing old '%s')\\n\", storageName.string());\n                    }\n    \n                    zip->remove(entry);\n                } else {\n                    // version in archive is newer\n                    if (bundle->getVerbose()) {\n                        printf(\"      (not updating '%s')\\n\", storageName.string());\n                    }\n                    entry->setMarked(true);\n                    return true;\n                }\n            } else {\n                // Generated files are always replaced.\n                zip->remove(entry);\n            }\n        }\n    }\n\n    //android_setMinPriority(NULL, ANDROID_LOG_VERBOSE);\n\n    if (fromGzip) {\n        result = zip->addGzip(file->getSourceFile().string(), storageName.string(), &entry);\n    } else if (!hasData) {\n        /* don't compress certain files, e.g. PNGs */\n        int compressionMethod = bundle->getCompressionMethod();\n        if (!okayToCompress(bundle, storageName)) {\n            compressionMethod = ZipEntry::kCompressStored;\n        }\n        result = zip->add(file->getSourceFile().string(), storageName.string(), compressionMethod,\n                            &entry);\n    } else {\n        result = zip->add(file->getData(), file->getSize(), storageName.string(),\n                           file->getCompressionMethod(), &entry);\n    }\n    if (result == NO_ERROR) {\n        if (bundle->getVerbose()) {\n            printf(\"      '%s'%s\", storageName.string(), fromGzip ? \" (from .gz)\" : \"\");\n            if (entry->getCompressionMethod() == ZipEntry::kCompressStored) {\n                printf(\" (not compressed)\\n\");\n            } else {\n                printf(\" (compressed %d%%)\\n\", calcPercent(entry->getUncompressedLen(),\n                            entry->getCompressedLen()));\n            }\n        }\n        entry->setMarked(true);\n    } else {\n        if (result == ALREADY_EXISTS) {\n            fprintf(stderr, \"      Unable to add '%s': file already in archive (try '-u'?)\\n\",\n                    file->getPrintableSource().string());\n        } else {\n            fprintf(stderr, \"      Unable to add '%s': Zip add failed (%d)\\n\",\n                    file->getPrintableSource().string(), result);\n        }\n        return false;\n    }\n\n    return true;\n}\n\n/*\n * Determine whether or not we want to try to compress this file based\n * on the file extension.\n */\nbool okayToCompress(Bundle* bundle, const String8& pathName)\n{\n    String8 ext = pathName.getPathExtension();\n    int i;\n\n    if (ext.length() == 0)\n        return true;\n\n    for (i = 0; i < NELEM(kNoCompressExt); i++) {\n        if (strcasecmp(ext.string(), kNoCompressExt[i]) == 0)\n            return false;\n    }\n\n    const android::Vector<const char*>& others(bundle->getNoCompressExtensions());\n    for (i = 0; i < (int)others.size(); i++) {\n        const char* str = others[i];\n        int pos = pathName.length() - strlen(str);\n        if (pos < 0) {\n            continue;\n        }\n        const char* path = pathName.string();\n        if (strcasecmp(path + pos, str) == 0) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\nbool endsWith(const char* haystack, const char* needle)\n{\n    size_t a = strlen(haystack);\n    size_t b = strlen(needle);\n    if (a < b) return false;\n    return strcasecmp(haystack+(a-b), needle) == 0;\n}\n\nssize_t processJarFile(ZipFile* jar, ZipFile* out)\n{\n    size_t N = jar->getNumEntries();\n    size_t count = 0;\n    for (size_t i=0; i<N; i++) {\n        ZipEntry* entry = jar->getEntryByIndex(i);\n        const char* storageName = entry->getFileName();\n        if (endsWith(storageName, \".class\")) {\n            int compressionMethod = entry->getCompressionMethod();\n            size_t size = entry->getUncompressedLen();\n            const void* data = jar->uncompress(entry);\n            if (data == NULL) {\n                fprintf(stderr, \"ERROR: unable to uncompress entry '%s'\\n\",\n                    storageName);\n                return -1;\n            }\n            out->add(data, size, storageName, compressionMethod, NULL);\n            free((void*)data);\n        }\n        count++;\n    }\n    return count;\n}\n\nssize_t processJarFiles(Bundle* bundle, ZipFile* zip)\n{\n    status_t err;\n    ssize_t count = 0;\n    const android::Vector<const char*>& jars = bundle->getJarFiles();\n\n    size_t N = jars.size();\n    for (size_t i=0; i<N; i++) {\n        ZipFile jar;\n        err = jar.open(jars[i], ZipFile::kOpenReadOnly);\n        if (err != 0) {\n            fprintf(stderr, \"ERROR: unable to open '%s' as a zip file: %d\\n\",\n                jars[i], err);\n            return err;\n        }\n        err += processJarFile(&jar, zip);\n        if (err < 0) {\n            fprintf(stderr, \"ERROR: unable to process '%s'\\n\", jars[i]);\n            return err;\n        }\n        count += err;\n    }\n\n    return count;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/Resource.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n#include \"AaptAssets.h\"\n#include \"AaptUtil.h\"\n#include \"AaptXml.h\"\n#include \"CacheUpdater.h\"\n#include \"CrunchCache.h\"\n#include \"FileFinder.h\"\n#include \"Images.h\"\n#include \"IndentPrinter.h\"\n#include \"Main.h\"\n#include \"ResourceTable.h\"\n#include \"StringPool.h\"\n#include \"Symbol.h\"\n#include \"WorkQueue.h\"\n#include \"XMLNode.h\"\n\n#include <algorithm>\n#include <androidfw/ResourcePackageId.h>\n\n// STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary.\n\n#if !defined(_WIN32)\n#  define ZD \"%zd\"\n#  define ZD_TYPE ssize_t\n#  define STATUST(x) x\n#else\n#  define ZD \"%ld\"\n#  define ZD_TYPE long\n#  define STATUST(x) (status_t)x\n#endif\n\n// Set to true for noisy debug output.\nstatic const bool kIsDebug = false;\n\n// Number of threads to use for preprocessing images.\nstatic const size_t MAX_THREADS = 4;\n\n// ==========================================================================\n// ==========================================================================\n// ==========================================================================\n\nclass PackageInfo\n{\npublic:\n    PackageInfo()\n    {\n    }\n    ~PackageInfo()\n    {\n    }\n\n    status_t parsePackage(const sp<AaptGroup>& grp);\n};\n\n// ==========================================================================\n// ==========================================================================\n// ==========================================================================\n\nString8 parseResourceName(const String8& leaf)\n{\n    const char* firstDot = strchr(leaf.string(), '.');\n    const char* str = leaf.string();\n\n    if (firstDot) {\n        return String8(str, firstDot-str);\n    } else {\n        return String8(str);\n    }\n}\n\nResourceTypeSet::ResourceTypeSet()\n    :RefBase(),\n     KeyedVector<String8,sp<AaptGroup> >()\n{\n}\n\nFilePathStore::FilePathStore()\n    :RefBase(),\n     Vector<String8>()\n{\n}\n\nclass ResourceDirIterator\n{\npublic:\n    ResourceDirIterator(const sp<ResourceTypeSet>& set, const String8& resType)\n        : mResType(resType), mSet(set), mSetPos(0), mGroupPos(0)\n    {\n        memset(&mParams, 0, sizeof(ResTable_config));\n    }\n\n    inline const sp<AaptGroup>& getGroup() const { return mGroup; }\n    inline const sp<AaptFile>& getFile() const { return mFile; }\n\n    inline const String8& getBaseName() const { return mBaseName; }\n    inline const String8& getLeafName() const { return mLeafName; }\n    inline String8 getPath() const { return mPath; }\n    inline const ResTable_config& getParams() const { return mParams; }\n\n    enum {\n        EOD = 1\n    };\n\n    ssize_t next()\n    {\n        while (true) {\n            sp<AaptGroup> group;\n            sp<AaptFile> file;\n\n            // Try to get next file in this current group.\n            if (mGroup != NULL && mGroupPos < mGroup->getFiles().size()) {\n                group = mGroup;\n                file = group->getFiles().valueAt(mGroupPos++);\n\n            // Try to get the next group/file in this directory\n            } else if (mSetPos < mSet->size()) {\n                mGroup = group = mSet->valueAt(mSetPos++);\n                if (group->getFiles().size() < 1) {\n                    continue;\n                }\n                file = group->getFiles().valueAt(0);\n                mGroupPos = 1;\n\n            // All done!\n            } else {\n                return EOD;\n            }\n\n            mFile = file;\n\n            String8 leaf(group->getLeaf());\n            mLeafName = String8(leaf);\n            mParams = file->getGroupEntry().toParams();\n            if (kIsDebug) {\n                printf(\"Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d ui=%d density=%d touch=%d key=%d inp=%d nav=%d\\n\",\n                        group->getPath().string(), mParams.mcc, mParams.mnc,\n                        mParams.language[0] ? mParams.language[0] : '-',\n                        mParams.language[1] ? mParams.language[1] : '-',\n                        mParams.country[0] ? mParams.country[0] : '-',\n                        mParams.country[1] ? mParams.country[1] : '-',\n                        mParams.orientation, mParams.uiMode,\n                        mParams.density, mParams.touchscreen, mParams.keyboard,\n                        mParams.inputFlags, mParams.navigation);\n            }\n            mPath = \"res\";\n            mPath.appendPath(file->getGroupEntry().toDirName(mResType));\n            mPath.appendPath(leaf);\n            mBaseName = parseResourceName(leaf);\n            if (mBaseName == \"\") {\n                fprintf(stderr, \"Error: malformed resource filename %s\\n\",\n                        file->getPrintableSource().string());\n                return UNKNOWN_ERROR;\n            }\n\n            if (kIsDebug) {\n                printf(\"file name=%s\\n\", mBaseName.string());\n            }\n\n            return NO_ERROR;\n        }\n    }\n\nprivate:\n    String8 mResType;\n\n    const sp<ResourceTypeSet> mSet;\n    size_t mSetPos;\n\n    sp<AaptGroup> mGroup;\n    size_t mGroupPos;\n\n    sp<AaptFile> mFile;\n    String8 mBaseName;\n    String8 mLeafName;\n    String8 mPath;\n    ResTable_config mParams;\n};\n\nclass AnnotationProcessor {\npublic:\n    AnnotationProcessor() : mDeprecated(false), mSystemApi(false) { }\n\n    void preprocessComment(String8& comment) {\n        if (comment.size() > 0) {\n            if (comment.contains(\"@deprecated\")) {\n                mDeprecated = true;\n            }\n            if (comment.removeAll(\"@SystemApi\")) {\n                mSystemApi = true;\n            }\n        }\n    }\n\n    void printAnnotations(FILE* fp, const char* indentStr) {\n        if (mDeprecated) {\n            fprintf(fp, \"%s@Deprecated\\n\", indentStr);\n        }\n        if (mSystemApi) {\n            fprintf(fp, \"%s@android.annotation.SystemApi\\n\", indentStr);\n        }\n    }\n\nprivate:\n    bool mDeprecated;\n    bool mSystemApi;\n};\n\n// ==========================================================================\n// ==========================================================================\n// ==========================================================================\n\nbool isValidResourceType(const String8& type)\n{\n    return type == \"anim\" || type == \"animator\" || type == \"interpolator\"\n        || type == \"transition\"\n        || type == \"drawable\" || type == \"layout\"\n        || type == \"values\" || type == \"xml\" || type == \"raw\"\n        || type == \"color\" || type == \"menu\" || type == \"mipmap\";\n}\n\nstatic status_t parsePackage(Bundle* bundle, const sp<AaptAssets>& assets,\n    const sp<AaptGroup>& grp)\n{\n    if (grp->getFiles().size() != 1) {\n        fprintf(stderr, \"warning: Multiple AndroidManifest.xml files found, using %s\\n\",\n                grp->getFiles().valueAt(0)->getPrintableSource().string());\n    }\n\n    sp<AaptFile> file = grp->getFiles().valueAt(0);\n\n    ResXMLTree block;\n    status_t err = parseXMLResource(file, &block);\n    if (err != NO_ERROR) {\n        return err;\n    }\n    //printXMLBlock(&block);\n\n    ResXMLTree::event_code_t code;\n    while ((code=block.next()) != ResXMLTree::START_TAG\n           && code != ResXMLTree::END_DOCUMENT\n           && code != ResXMLTree::BAD_DOCUMENT) {\n    }\n\n    size_t len;\n    if (code != ResXMLTree::START_TAG) {\n        fprintf(stderr, \"%s:%d: No start tag found\\n\",\n                file->getPrintableSource().string(), block.getLineNumber());\n        return UNKNOWN_ERROR;\n    }\n    if (strcmp16(block.getElementName(&len), String16(\"manifest\").string()) != 0) {\n        fprintf(stderr, \"%s:%d: Invalid start tag %s, expected <manifest>\\n\",\n                file->getPrintableSource().string(), block.getLineNumber(),\n                String8(block.getElementName(&len)).string());\n        return UNKNOWN_ERROR;\n    }\n\n    ssize_t nameIndex = block.indexOfAttribute(NULL, \"package\");\n    if (nameIndex < 0) {\n        fprintf(stderr, \"%s:%d: <manifest> does not have package attribute.\\n\",\n                file->getPrintableSource().string(), block.getLineNumber());\n        return UNKNOWN_ERROR;\n    }\n\n    assets->setPackage(String8(block.getAttributeStringValue(nameIndex, &len)));\n\n    ssize_t revisionCodeIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, \"revisionCode\");\n    if (revisionCodeIndex >= 0) {\n        bundle->setRevisionCode(String8(block.getAttributeStringValue(revisionCodeIndex, &len)).string());\n    }\n\n    String16 uses_sdk16(\"uses-sdk\");\n    while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n           && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::START_TAG) {\n            if (strcmp16(block.getElementName(&len), uses_sdk16.string()) == 0) {\n                ssize_t minSdkIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE,\n                                                             \"minSdkVersion\");\n                if (minSdkIndex >= 0) {\n                    const char16_t* minSdk16 = block.getAttributeStringValue(minSdkIndex, &len);\n                    const char* minSdk8 = strdup(String8(minSdk16).string());\n                    bundle->setManifestMinSdkVersion(minSdk8);\n                }\n            }\n        }\n    }\n\n    return NO_ERROR;\n}\n\n// ==========================================================================\n// ==========================================================================\n// ==========================================================================\n\nstatic status_t makeFileResources(Bundle* bundle, const sp<AaptAssets>& assets,\n                                  ResourceTable* table,\n                                  const sp<ResourceTypeSet>& set,\n                                  const char* resType)\n{\n    String8 type8(resType);\n    String16 type16(resType);\n\n    bool hasErrors = false;\n\n    ResourceDirIterator it(set, String8(resType));\n    ssize_t res;\n    while ((res=it.next()) == NO_ERROR) {\n        if (bundle->getVerbose()) {\n            printf(\"    (new resource id %s from %s)\\n\",\n                   it.getBaseName().string(), it.getFile()->getPrintableSource().string());\n        }\n        String16 baseName(it.getBaseName());\n        const char16_t* str = baseName.string();\n        const char16_t* const end = str + baseName.size();\n        while (str < end) {\n            if (!((*str >= 'a' && *str <= 'z')\n                    || (*str >= '0' && *str <= '9')\n                    || *str == '_' || *str == '.')) {\n                fprintf(stderr, \"%s: Invalid file name: must contain only [a-z0-9_.]\\n\",\n                        it.getPath().string());\n                hasErrors = true;\n            }\n            str++;\n        }\n        String8 resPath = it.getPath();\n        resPath.convertToResPath();\n        table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()),\n                        type16,\n                        baseName,\n                        String16(resPath),\n                        NULL,\n                        &it.getParams());\n        assets->addResource(it.getLeafName(), resPath, it.getFile(), type8);\n    }\n\n    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;\n}\n\nclass PreProcessImageWorkUnit : public WorkQueue::WorkUnit {\npublic:\n    PreProcessImageWorkUnit(const Bundle* bundle, const sp<AaptAssets>& assets,\n            const sp<AaptFile>& file, volatile bool* hasErrors) :\n            mBundle(bundle), mAssets(assets), mFile(file), mHasErrors(hasErrors) {\n    }\n\n    virtual bool run() {\n        status_t status = preProcessImage(mBundle, mAssets, mFile, NULL);\n        if (status) {\n            *mHasErrors = true;\n        }\n        return true; // continue even if there are errors\n    }\n\nprivate:\n    const Bundle* mBundle;\n    sp<AaptAssets> mAssets;\n    sp<AaptFile> mFile;\n    volatile bool* mHasErrors;\n};\n\nstatic status_t preProcessImages(const Bundle* bundle, const sp<AaptAssets>& assets,\n                          const sp<ResourceTypeSet>& set, const char* type)\n{\n    volatile bool hasErrors = false;\n    ssize_t res = NO_ERROR;\n    if (bundle->getUseCrunchCache() == false) {\n        WorkQueue wq(MAX_THREADS, false);\n        ResourceDirIterator it(set, String8(type));\n        while ((res=it.next()) == NO_ERROR) {\n            PreProcessImageWorkUnit* w = new PreProcessImageWorkUnit(\n                    bundle, assets, it.getFile(), &hasErrors);\n            status_t status = wq.schedule(w);\n            if (status) {\n                fprintf(stderr, \"preProcessImages failed: schedule() returned %d\\n\", status);\n                hasErrors = true;\n                delete w;\n                break;\n            }\n        }\n        status_t status = wq.finish();\n        if (status) {\n            fprintf(stderr, \"preProcessImages failed: finish() returned %d\\n\", status);\n            hasErrors = true;\n        }\n    }\n    return (hasErrors || (res < NO_ERROR)) ? STATUST(UNKNOWN_ERROR) : NO_ERROR;\n}\n\nstatic void collect_files(const sp<AaptDir>& dir,\n        KeyedVector<String8, sp<ResourceTypeSet> >* resources)\n{\n    const DefaultKeyedVector<String8, sp<AaptGroup> >& groups = dir->getFiles();\n    int N = groups.size();\n    for (int i=0; i<N; i++) {\n        String8 leafName = groups.keyAt(i);\n        const sp<AaptGroup>& group = groups.valueAt(i);\n\n        const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files\n                = group->getFiles();\n\n        if (files.size() == 0) {\n            continue;\n        }\n\n        String8 resType = files.valueAt(0)->getResourceType();\n\n        ssize_t index = resources->indexOfKey(resType);\n\n        if (index < 0) {\n            sp<ResourceTypeSet> set = new ResourceTypeSet();\n            if (kIsDebug) {\n                printf(\"Creating new resource type set for leaf %s with group %s (%p)\\n\",\n                        leafName.string(), group->getPath().string(), group.get());\n            }\n            set->add(leafName, group);\n            resources->add(resType, set);\n        } else {\n            sp<ResourceTypeSet> set = resources->valueAt(index);\n            index = set->indexOfKey(leafName);\n            if (index < 0) {\n                if (kIsDebug) {\n                    printf(\"Adding to resource type set for leaf %s group %s (%p)\\n\",\n                            leafName.string(), group->getPath().string(), group.get());\n                }\n                set->add(leafName, group);\n            } else {\n                sp<AaptGroup> existingGroup = set->valueAt(index);\n                if (kIsDebug) {\n                    printf(\"Extending to resource type set for leaf %s group %s (%p)\\n\",\n                            leafName.string(), group->getPath().string(), group.get());\n                }\n                for (size_t j=0; j<files.size(); j++) {\n                    if (kIsDebug) {\n                        printf(\"Adding file %s in group %s resType %s\\n\",\n                                files.valueAt(j)->getSourceFile().string(),\n                                files.keyAt(j).toDirName(String8()).string(),\n                                resType.string());\n                    }\n                    existingGroup->addFile(files.valueAt(j));\n                }\n            }\n        }\n    }\n}\n\nstatic void collect_files(const sp<AaptAssets>& ass,\n        KeyedVector<String8, sp<ResourceTypeSet> >* resources)\n{\n    const Vector<sp<AaptDir> >& dirs = ass->resDirs();\n    int N = dirs.size();\n\n    for (int i=0; i<N; i++) {\n        sp<AaptDir> d = dirs.itemAt(i);\n        if (kIsDebug) {\n            printf(\"Collecting dir #%d %p: %s, leaf %s\\n\", i, d.get(), d->getPath().string(),\n                    d->getLeaf().string());\n        }\n        collect_files(d, resources);\n\n        // don't try to include the res dir\n        if (kIsDebug) {\n            printf(\"Removing dir leaf %s\\n\", d->getLeaf().string());\n        }\n        ass->removeDir(d->getLeaf());\n    }\n}\n\nenum {\n    ATTR_OKAY = -1,\n    ATTR_NOT_FOUND = -2,\n    ATTR_LEADING_SPACES = -3,\n    ATTR_TRAILING_SPACES = -4\n};\nstatic int validateAttr(const String8& path, const ResTable& table,\n        const ResXMLParser& parser,\n        const char* ns, const char* attr, const char* validChars, bool required)\n{\n    size_t len;\n\n    ssize_t index = parser.indexOfAttribute(ns, attr);\n    const char16_t* str;\n    Res_value value;\n    if (index >= 0 && parser.getAttributeValue(index, &value) >= 0) {\n        const ResStringPool* pool = &parser.getStrings();\n        if (value.dataType == Res_value::TYPE_REFERENCE) {\n            uint32_t specFlags = 0;\n            int strIdx;\n            if ((strIdx=table.resolveReference(&value, 0x10000000, NULL, &specFlags)) < 0) {\n                fprintf(stderr, \"%s:%d: Tag <%s> attribute %s references unknown resid 0x%08x.\\n\",\n                        path.string(), parser.getLineNumber(),\n                        String8(parser.getElementName(&len)).string(), attr,\n                        value.data);\n                return ATTR_NOT_FOUND;\n            }\n            \n            pool = table.getTableStringBlock(strIdx);\n            #if 0\n            if (pool != NULL) {\n                str = pool->stringAt(value.data, &len);\n            }\n            printf(\"***** RES ATTR: %s specFlags=0x%x strIdx=%d: %s\\n\", attr,\n                    specFlags, strIdx, str != NULL ? String8(str).string() : \"???\");\n            #endif\n            if ((specFlags&~ResTable_typeSpec::SPEC_PUBLIC) != 0 && false) {\n                fprintf(stderr, \"%s:%d: Tag <%s> attribute %s varies by configurations 0x%x.\\n\",\n                        path.string(), parser.getLineNumber(),\n                        String8(parser.getElementName(&len)).string(), attr,\n                        specFlags);\n                return ATTR_NOT_FOUND;\n            }\n        }\n        if (value.dataType == Res_value::TYPE_STRING) {\n            if (pool == NULL) {\n                fprintf(stderr, \"%s:%d: Tag <%s> attribute %s has no string block.\\n\",\n                        path.string(), parser.getLineNumber(),\n                        String8(parser.getElementName(&len)).string(), attr);\n                return ATTR_NOT_FOUND;\n            }\n            if ((str=pool->stringAt(value.data, &len)) == NULL) {\n                fprintf(stderr, \"%s:%d: Tag <%s> attribute %s has corrupt string value.\\n\",\n                        path.string(), parser.getLineNumber(),\n                        String8(parser.getElementName(&len)).string(), attr);\n                return ATTR_NOT_FOUND;\n            }\n        } else {\n            fprintf(stderr, \"%s:%d: Tag <%s> attribute %s has invalid type %d.\\n\",\n                    path.string(), parser.getLineNumber(),\n                    String8(parser.getElementName(&len)).string(), attr,\n                    value.dataType);\n            return ATTR_NOT_FOUND;\n        }\n        if (validChars) {\n            for (size_t i=0; i<len; i++) {\n                char16_t c = str[i];\n                const char* p = validChars;\n                bool okay = false;\n                while (*p) {\n                    if (c == *p) {\n                        okay = true;\n                        break;\n                    }\n                    p++;\n                }\n                if (!okay) {\n                    fprintf(stderr, \"%s:%d: Tag <%s> attribute %s has invalid character '%c'.\\n\",\n                            path.string(), parser.getLineNumber(),\n                            String8(parser.getElementName(&len)).string(), attr, (char)str[i]);\n                    return (int)i;\n                }\n            }\n        }\n        if (*str == ' ') {\n            fprintf(stderr, \"%s:%d: Tag <%s> attribute %s can not start with a space.\\n\",\n                    path.string(), parser.getLineNumber(),\n                    String8(parser.getElementName(&len)).string(), attr);\n            return ATTR_LEADING_SPACES;\n        }\n        if (len != 0 && str[len-1] == ' ') {\n            fprintf(stderr, \"%s:%d: Tag <%s> attribute %s can not end with a space.\\n\",\n                    path.string(), parser.getLineNumber(),\n                    String8(parser.getElementName(&len)).string(), attr);\n            return ATTR_TRAILING_SPACES;\n        }\n        return ATTR_OKAY;\n    }\n    if (required) {\n        fprintf(stderr, \"%s:%d: Tag <%s> missing required attribute %s.\\n\",\n                path.string(), parser.getLineNumber(),\n                String8(parser.getElementName(&len)).string(), attr);\n        return ATTR_NOT_FOUND;\n    }\n    return ATTR_OKAY;\n}\n\nstatic void checkForIds(const String8& path, ResXMLParser& parser)\n{\n    ResXMLTree::event_code_t code;\n    while ((code=parser.next()) != ResXMLTree::END_DOCUMENT\n           && code > ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::START_TAG) {\n            ssize_t index = parser.indexOfAttribute(NULL, \"id\");\n            if (index >= 0) {\n                fprintf(stderr, \"%s:%d: warning: found plain 'id' attribute; did you mean the new 'android:id' name?\\n\",\n                        path.string(), parser.getLineNumber());\n            }\n        }\n    }\n}\n\nstatic bool applyFileOverlay(Bundle *bundle,\n                             const sp<AaptAssets>& assets,\n                             sp<ResourceTypeSet> *baseSet,\n                             const char *resType)\n{\n    if (bundle->getVerbose()) {\n        printf(\"applyFileOverlay for %s\\n\", resType);\n    }\n\n    // Replace any base level files in this category with any found from the overlay\n    // Also add any found only in the overlay.\n    sp<AaptAssets> overlay = assets->getOverlay();\n    String8 resTypeString(resType);\n\n    // work through the linked list of overlays\n    while (overlay.get()) {\n        KeyedVector<String8, sp<ResourceTypeSet> >* overlayRes = overlay->getResources();\n\n        // get the overlay resources of the requested type\n        ssize_t index = overlayRes->indexOfKey(resTypeString);\n        if (index >= 0) {\n            sp<ResourceTypeSet> overlaySet = overlayRes->valueAt(index);\n\n            // for each of the resources, check for a match in the previously built\n            // non-overlay \"baseset\".\n            size_t overlayCount = overlaySet->size();\n            for (size_t overlayIndex=0; overlayIndex<overlayCount; overlayIndex++) {\n                if (bundle->getVerbose()) {\n                    printf(\"trying overlaySet Key=%s\\n\",overlaySet->keyAt(overlayIndex).string());\n                }\n                ssize_t baseIndex = -1;\n                if (baseSet->get() != NULL) {\n                    baseIndex = (*baseSet)->indexOfKey(overlaySet->keyAt(overlayIndex));\n                }\n                if (baseIndex >= 0) {\n                    // look for same flavor.  For a given file (strings.xml, for example)\n                    // there may be a locale specific or other flavors - we want to match\n                    // the same flavor.\n                    sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex);\n                    sp<AaptGroup> baseGroup = (*baseSet)->valueAt(baseIndex);\n\n                    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =\n                            overlayGroup->getFiles();\n                    if (bundle->getVerbose()) {\n                        DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > baseFiles =\n                                baseGroup->getFiles();\n                        for (size_t i=0; i < baseFiles.size(); i++) {\n                            printf(\"baseFile \" ZD \" has flavor %s\\n\", (ZD_TYPE) i,\n                                    baseFiles.keyAt(i).toString().string());\n                        }\n                        for (size_t i=0; i < overlayFiles.size(); i++) {\n                            printf(\"overlayFile \" ZD \" has flavor %s\\n\", (ZD_TYPE) i,\n                                    overlayFiles.keyAt(i).toString().string());\n                        }\n                    }\n\n                    size_t overlayGroupSize = overlayFiles.size();\n                    for (size_t overlayGroupIndex = 0;\n                            overlayGroupIndex<overlayGroupSize;\n                            overlayGroupIndex++) {\n                        ssize_t baseFileIndex =\n                                baseGroup->getFiles().indexOfKey(overlayFiles.\n                                keyAt(overlayGroupIndex));\n                        if (baseFileIndex >= 0) {\n                            if (bundle->getVerbose()) {\n                                printf(\"found a match (\" ZD \") for overlay file %s, for flavor %s\\n\",\n                                        (ZD_TYPE) baseFileIndex,\n                                        overlayGroup->getLeaf().string(),\n                                        overlayFiles.keyAt(overlayGroupIndex).toString().string());\n                            }\n                            baseGroup->removeFile(baseFileIndex);\n                        } else {\n                            // didn't find a match fall through and add it..\n                            if (true || bundle->getVerbose()) {\n                                printf(\"nothing matches overlay file %s, for flavor %s\\n\",\n                                        overlayGroup->getLeaf().string(),\n                                        overlayFiles.keyAt(overlayGroupIndex).toString().string());\n                            }\n                        }\n                        baseGroup->addFile(overlayFiles.valueAt(overlayGroupIndex));\n                        assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));\n                    }\n                } else {\n                    if (baseSet->get() == NULL) {\n                        *baseSet = new ResourceTypeSet();\n                        assets->getResources()->add(String8(resType), *baseSet);\n                    }\n                    // this group doesn't exist (a file that's only in the overlay)\n                    (*baseSet)->add(overlaySet->keyAt(overlayIndex),\n                            overlaySet->valueAt(overlayIndex));\n                    // make sure all flavors are defined in the resources.\n                    sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex);\n                    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =\n                            overlayGroup->getFiles();\n                    size_t overlayGroupSize = overlayFiles.size();\n                    for (size_t overlayGroupIndex = 0;\n                            overlayGroupIndex<overlayGroupSize;\n                            overlayGroupIndex++) {\n                        assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));\n                    }\n                }\n            }\n            // this overlay didn't have resources for this type\n        }\n        // try next overlay\n        overlay = overlay->getOverlay();\n    }\n    return true;\n}\n\n/*\n * Inserts an attribute in a given node.\n * If errorOnFailedInsert is true, and the attribute already exists, returns false.\n * If replaceExisting is true, the attribute will be updated if it already exists.\n * Returns true otherwise, even if the attribute already exists, and does not modify\n * the existing attribute's value.\n */\nbool addTagAttribute(const sp<XMLNode>& node, const char* ns8,\n        const char* attr8, const char* value, bool errorOnFailedInsert,\n        bool replaceExisting)\n{\n    if (value == NULL) {\n        return true;\n    }\n\n    const String16 ns(ns8);\n    const String16 attr(attr8);\n\n    XMLNode::attribute_entry* existingEntry = node->editAttribute(ns, attr);\n    if (existingEntry != NULL) {\n        if (replaceExisting) {\n            if (kIsDebug) {\n                printf(\"Info: AndroidManifest.xml already defines %s (in %s);\"\n                        \" overwriting existing value from manifest.\\n\",\n                        String8(attr).string(), String8(ns).string());\n            }\n            existingEntry->string = String16(value);\n            return true;\n        }\n\n        if (errorOnFailedInsert) {\n            fprintf(stderr, \"Error: AndroidManifest.xml already defines %s (in %s);\"\n                            \" cannot insert new value %s.\\n\",\n                    String8(attr).string(), String8(ns).string(), value);\n            return false;\n        }\n\n        fprintf(stderr, \"Warning: AndroidManifest.xml already defines %s (in %s);\"\n                        \" using existing value in manifest.\\n\",\n                String8(attr).string(), String8(ns).string());\n\n        // don't stop the build.\n        return true;\n    }\n    \n    node->addAttribute(ns, attr, String16(value));\n    return true;\n}\n\n/*\n * Inserts an attribute in a given node, only if the attribute does not\n * exist.\n * If errorOnFailedInsert is true, and the attribute already exists, returns false.\n * Returns true otherwise, even if the attribute already exists.\n */\nbool addTagAttribute(const sp<XMLNode>& node, const char* ns8,\n        const char* attr8, const char* value, bool errorOnFailedInsert)\n{\n    return addTagAttribute(node, ns8, attr8, value, errorOnFailedInsert, false);\n}\n\nstatic void fullyQualifyClassName(const String8& package, sp<XMLNode> node,\n        const String16& attrName) {\n    XMLNode::attribute_entry* attr = node->editAttribute(\n            String16(\"http://schemas.android.com/apk/res/android\"), attrName);\n    if (attr != NULL) {\n        String8 name(attr->string);\n\n        // asdf     --> package.asdf\n        // .asdf  .a.b  --> package.asdf package.a.b\n        // asdf.adsf --> asdf.asdf\n        String8 className;\n        const char* p = name.string();\n        const char* q = strchr(p, '.');\n        if (p == q) {\n            className += package;\n            className += name;\n        } else if (q == NULL) {\n            className += package;\n            className += \".\";\n            className += name;\n        } else {\n            className += name;\n        }\n        if (kIsDebug) {\n            printf(\"Qualifying class '%s' to '%s'\", name.string(), className.string());\n        }\n        attr->string.setTo(String16(className));\n    }\n}\n\nstatus_t massageManifest(Bundle* bundle, sp<XMLNode> root)\n{\n    root = root->searchElement(String16(), String16(\"manifest\"));\n    if (root == NULL) {\n        fprintf(stderr, \"No <manifest> tag.\\n\");\n        return UNKNOWN_ERROR;\n    }\n\n    bool errorOnFailedInsert = bundle->getErrorOnFailedInsert();\n    bool replaceVersion = bundle->getReplaceVersion();\n\n    if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, \"versionCode\",\n            bundle->getVersionCode(), errorOnFailedInsert, replaceVersion)) {\n        return UNKNOWN_ERROR;\n    } else {\n        const XMLNode::attribute_entry* attr = root->getAttribute(\n                String16(RESOURCES_ANDROID_NAMESPACE), String16(\"versionCode\"));\n        if (attr != NULL) {\n            bundle->setVersionCode(strdup(String8(attr->string).string()));\n        }\n    }\n\n    if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, \"versionName\",\n            bundle->getVersionName(), errorOnFailedInsert, replaceVersion)) {\n        return UNKNOWN_ERROR;\n    } else {\n        const XMLNode::attribute_entry* attr = root->getAttribute(\n                String16(RESOURCES_ANDROID_NAMESPACE), String16(\"versionName\"));\n        if (attr != NULL) {\n            bundle->setVersionName(strdup(String8(attr->string).string()));\n        }\n    }\n    \n    sp<XMLNode> vers = root->getChildElement(String16(), String16(\"uses-sdk\"));\n    if (bundle->getMinSdkVersion() != NULL\n            || bundle->getTargetSdkVersion() != NULL\n            || bundle->getMaxSdkVersion() != NULL) {\n        if (vers == NULL) {\n            vers = XMLNode::newElement(root->getFilename(), String16(), String16(\"uses-sdk\"));\n            root->insertChildAt(vers, 0);\n        }\n        \n        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, \"minSdkVersion\",\n                bundle->getMinSdkVersion(), errorOnFailedInsert)) {\n            return UNKNOWN_ERROR;\n        }\n        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, \"targetSdkVersion\",\n                bundle->getTargetSdkVersion(), errorOnFailedInsert)) {\n            return UNKNOWN_ERROR;\n        }\n        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, \"maxSdkVersion\",\n                bundle->getMaxSdkVersion(), errorOnFailedInsert)) {\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    if (vers != NULL) {\n        const XMLNode::attribute_entry* attr = vers->getAttribute(\n                String16(RESOURCES_ANDROID_NAMESPACE), String16(\"minSdkVersion\"));\n        if (attr != NULL) {\n            bundle->setMinSdkVersion(strdup(String8(attr->string).string()));\n        }\n    }\n\n    if (bundle->getPlatformBuildVersionCode() != \"\") {\n        if (!addTagAttribute(root, \"\", \"platformBuildVersionCode\",\n                    bundle->getPlatformBuildVersionCode(), errorOnFailedInsert, true)) {\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    if (bundle->getPlatformBuildVersionName() != \"\") {\n        if (!addTagAttribute(root, \"\", \"platformBuildVersionName\",\n                    bundle->getPlatformBuildVersionName(), errorOnFailedInsert, true)) {\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    if (bundle->getDebugMode()) {\n        sp<XMLNode> application = root->getChildElement(String16(), String16(\"application\"));\n        if (application != NULL) {\n            if (!addTagAttribute(application, RESOURCES_ANDROID_NAMESPACE, \"debuggable\", \"true\",\n                    errorOnFailedInsert)) {\n                return UNKNOWN_ERROR;\n            }\n        }\n    }\n\n    // Deal with manifest package name overrides\n    const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride();\n    if (manifestPackageNameOverride != NULL) {\n        // Update the actual package name\n        XMLNode::attribute_entry* attr = root->editAttribute(String16(), String16(\"package\"));\n        if (attr == NULL) {\n            fprintf(stderr, \"package name is required with --rename-manifest-package.\\n\");\n            return UNKNOWN_ERROR;\n        }\n        String8 origPackage(attr->string);\n        attr->string.setTo(String16(manifestPackageNameOverride));\n        if (kIsDebug) {\n            printf(\"Overriding package '%s' to be '%s'\\n\", origPackage.string(),\n                    manifestPackageNameOverride);\n        }\n\n        // Make class names fully qualified\n        sp<XMLNode> application = root->getChildElement(String16(), String16(\"application\"));\n        if (application != NULL) {\n            fullyQualifyClassName(origPackage, application, String16(\"name\"));\n            fullyQualifyClassName(origPackage, application, String16(\"backupAgent\"));\n\n            Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(application->getChildren());\n            for (size_t i = 0; i < children.size(); i++) {\n                sp<XMLNode> child = children.editItemAt(i);\n                String8 tag(child->getElementName());\n                if (tag == \"activity\" || tag == \"service\" || tag == \"receiver\" || tag == \"provider\") {\n                    fullyQualifyClassName(origPackage, child, String16(\"name\"));\n                } else if (tag == \"activity-alias\") {\n                    fullyQualifyClassName(origPackage, child, String16(\"name\"));\n                    fullyQualifyClassName(origPackage, child, String16(\"targetActivity\"));\n                }\n            }\n        }\n    }\n\n    // Deal with manifest package name overrides\n    const char* instrumentationPackageNameOverride = bundle->getInstrumentationPackageNameOverride();\n    if (instrumentationPackageNameOverride != NULL) {\n        // Fix up instrumentation targets.\n        Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(root->getChildren());\n        for (size_t i = 0; i < children.size(); i++) {\n            sp<XMLNode> child = children.editItemAt(i);\n            String8 tag(child->getElementName());\n            if (tag == \"instrumentation\") {\n                XMLNode::attribute_entry* attr = child->editAttribute(\n                        String16(\"http://schemas.android.com/apk/res/android\"), String16(\"targetPackage\"));\n                if (attr != NULL) {\n                    attr->string.setTo(String16(instrumentationPackageNameOverride));\n                }\n            }\n        }\n    }\n    \n    // Generate split name if feature is present.\n    const XMLNode::attribute_entry* attr = root->getAttribute(String16(), String16(\"featureName\"));\n    if (attr != NULL) {\n        String16 splitName(\"feature_\");\n        splitName.append(attr->string);\n        status_t err = root->addAttribute(String16(), String16(\"split\"), splitName);\n        if (err != NO_ERROR) {\n            ALOGE(\"Failed to insert split name into AndroidManifest.xml\");\n            return err;\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatic int32_t getPlatformAssetCookie(const AssetManager& assets) {\n    // Find the system package (0x01). AAPT always generates attributes\n    // with the type 0x01, so we're looking for the first attribute\n    // resource in the system package.\n    const ResTable& table = assets.getResources(true);\n    Res_value val;\n    ssize_t idx = table.getResource(0x01010000, &val, true);\n    if (idx != NO_ERROR) {\n        // Try as a bag.\n        const ResTable::bag_entry* entry;\n        ssize_t cnt = table.lockBag(0x01010000, &entry);\n        if (cnt >= 0) {\n            idx = entry->stringBlock;\n        }\n        table.unlockBag(entry);\n    }\n\n    if (idx < 0) {\n        return 0;\n    }\n    return table.getTableCookie(idx);\n}\n\nenum {\n    VERSION_CODE_ATTR = 0x0101021b,\n    VERSION_NAME_ATTR = 0x0101021c,\n};\n\nstatic ssize_t extractPlatformBuildVersion(ResXMLTree& tree, Bundle* bundle) {\n    size_t len;\n    ResXMLTree::event_code_t code;\n    while ((code = tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code != ResXMLTree::START_TAG) {\n            continue;\n        }\n\n        const char16_t* ctag16 = tree.getElementName(&len);\n        if (ctag16 == NULL) {\n            fprintf(stderr, \"ERROR: failed to get XML element name (bad string pool)\\n\");\n            return UNKNOWN_ERROR;\n        }\n\n        String8 tag(ctag16, len);\n        if (tag != \"manifest\") {\n            continue;\n        }\n\n        String8 error;\n        int32_t versionCode = AaptXml::getIntegerAttribute(tree, VERSION_CODE_ATTR, &error);\n        if (error != \"\") {\n            fprintf(stderr, \"ERROR: failed to get platform version code\\n\");\n            return UNKNOWN_ERROR;\n        }\n\n        if (versionCode >= 0 && bundle->getPlatformBuildVersionCode() == \"\") {\n            bundle->setPlatformBuildVersionCode(String8::format(\"%d\", versionCode));\n        }\n\n        String8 versionName = AaptXml::getAttribute(tree, VERSION_NAME_ATTR, &error);\n        if (error != \"\") {\n            fprintf(stderr, \"ERROR: failed to get platform version name\\n\");\n            return UNKNOWN_ERROR;\n        }\n\n        if (versionName != \"\" && bundle->getPlatformBuildVersionName() == \"\") {\n            bundle->setPlatformBuildVersionName(versionName);\n        }\n        return NO_ERROR;\n    }\n\n    fprintf(stderr, \"ERROR: no <manifest> tag found in platform AndroidManifest.xml\\n\");\n    return UNKNOWN_ERROR;\n}\n\nstatic ssize_t extractPlatformBuildVersion(AssetManager& assets, Bundle* bundle) {\n    int32_t cookie = getPlatformAssetCookie(assets);\n    if (cookie == 0) {\n        // No platform was loaded.\n        return NO_ERROR;\n    }\n\n    ResXMLTree tree;\n    Asset* asset = assets.openNonAsset(cookie, \"AndroidManifest.xml\", Asset::ACCESS_STREAMING);\n    if (asset == NULL) {\n        fprintf(stderr, \"ERROR: Platform AndroidManifest.xml not found\\n\");\n        return UNKNOWN_ERROR;\n    }\n\n    ssize_t result = NO_ERROR;\n    if (tree.setTo(asset->getBuffer(true), asset->getLength()) != NO_ERROR) {\n        fprintf(stderr, \"ERROR: Platform AndroidManifest.xml is corrupt\\n\");\n        result = UNKNOWN_ERROR;\n    } else {\n        result = extractPlatformBuildVersion(tree, bundle);\n    }\n\n    delete asset;\n    return result;\n}\n\n#define ASSIGN_IT(n) \\\n        do { \\\n            ssize_t index = resources->indexOfKey(String8(#n)); \\\n            if (index >= 0) { \\\n                n ## s = resources->valueAt(index); \\\n            } \\\n        } while (0)\n\nstatus_t updatePreProcessedCache(Bundle* bundle)\n{\n    #if BENCHMARK\n    fprintf(stdout, \"BENCHMARK: Starting PNG PreProcessing \\n\");\n    long startPNGTime = clock();\n    #endif /* BENCHMARK */\n\n    String8 source(bundle->getResourceSourceDirs()[0]);\n    String8 dest(bundle->getCrunchedOutputDir());\n\n    FileFinder* ff = new SystemFileFinder();\n    CrunchCache cc(source,dest,ff);\n\n    CacheUpdater* cu = new SystemCacheUpdater(bundle);\n    size_t numFiles = cc.crunch(cu);\n\n    if (bundle->getVerbose())\n        fprintf(stdout, \"Crunched %d PNG files to update cache\\n\", (int)numFiles);\n\n    delete ff;\n    delete cu;\n\n    #if BENCHMARK\n    fprintf(stdout, \"BENCHMARK: End PNG PreProcessing. Time Elapsed: %f ms \\n\"\n            ,(clock() - startPNGTime)/1000.0);\n    #endif /* BENCHMARK */\n    return 0;\n}\n\nstatus_t generateAndroidManifestForSplit(Bundle* bundle, const sp<AaptAssets>& assets,\n        const sp<ApkSplit>& split, sp<AaptFile>& outFile, ResourceTable* table) {\n    const String8 filename(\"AndroidManifest.xml\");\n    const String16 androidPrefix(\"android\");\n    const String16 androidNSUri(\"http://schemas.android.com/apk/res/android\");\n    sp<XMLNode> root = XMLNode::newNamespace(filename, androidPrefix, androidNSUri);\n\n    // Build the <manifest> tag\n    sp<XMLNode> manifest = XMLNode::newElement(filename, String16(), String16(\"manifest\"));\n\n    // Add the 'package' attribute which is set to the package name.\n    const char* packageName = assets->getPackage();\n    const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride();\n    if (manifestPackageNameOverride != NULL) {\n        packageName = manifestPackageNameOverride;\n    }\n    manifest->addAttribute(String16(), String16(\"package\"), String16(packageName));\n\n    // Add the 'versionCode' attribute which is set to the original version code.\n    if (!addTagAttribute(manifest, RESOURCES_ANDROID_NAMESPACE, \"versionCode\",\n            bundle->getVersionCode(), true, true)) {\n        return UNKNOWN_ERROR;\n    }\n\n    // Add the 'revisionCode' attribute, which is set to the original revisionCode.\n    if (bundle->getRevisionCode().size() > 0) {\n        if (!addTagAttribute(manifest, RESOURCES_ANDROID_NAMESPACE, \"revisionCode\",\n                    bundle->getRevisionCode().string(), true, true)) {\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    // Add the 'split' attribute which describes the configurations included.\n    String8 splitName(\"config.\");\n    splitName.append(split->getPackageSafeName());\n    manifest->addAttribute(String16(), String16(\"split\"), String16(splitName));\n\n    // Build an empty <application> tag (required).\n    sp<XMLNode> app = XMLNode::newElement(filename, String16(), String16(\"application\"));\n\n    // Add the 'hasCode' attribute which is never true for resource splits.\n    if (!addTagAttribute(app, RESOURCES_ANDROID_NAMESPACE, \"hasCode\",\n            \"false\", true, true)) {\n        return UNKNOWN_ERROR;\n    }\n\n    manifest->addChild(app);\n    root->addChild(manifest);\n\n    int err = compileXmlFile(bundle, assets, String16(), root, outFile, table);\n    if (err < NO_ERROR) {\n        return err;\n    }\n    outFile->setCompressionMethod(ZipEntry::kCompressDeflated);\n    return NO_ERROR;\n}\n\nstatus_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuilder>& builder)\n{\n    // First, look for a package file to parse.  This is required to\n    // be able to generate the resource information.\n    sp<AaptGroup> androidManifestFile =\n            assets->getFiles().valueFor(String8(\"AndroidManifest.xml\"));\n    if (androidManifestFile == NULL) {\n        fprintf(stderr, \"ERROR: No AndroidManifest.xml file found.\\n\");\n        return UNKNOWN_ERROR;\n    }\n\n    status_t err = parsePackage(bundle, assets, androidManifestFile);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    if (kIsDebug) {\n        printf(\"Creating resources for package %s\\n\", assets->getPackage().string());\n    }\n\n    // Set the private symbols package if it was declared.\n    // This can also be declared in XML as <private-symbols name=\"package\" />\n    if (bundle->getPrivateSymbolsPackage().size() != 0) {\n        assets->setSymbolsPrivatePackage(bundle->getPrivateSymbolsPackage());\n    }\n\n    ResourceTable::PackageType packageType = ResourceTable::App;\n    if (bundle->getBuildSharedLibrary()) {\n        packageType = ResourceTable::SharedLibrary;\n    } else if (bundle->getExtending()) {\n        packageType = ResourceTable::System;\n    } else if (!bundle->getFeatureOfPackage().isEmpty()) {\n        packageType = ResourceTable::AppFeature;\n    }\n\n    ResourceTable table(bundle, String16(assets->getPackage()), packageType);\n    err = table.addIncludedResources(bundle, assets);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    if (kIsDebug) {\n        printf(\"Found %d included resource packages\\n\", (int)table.size());\n    }\n\n    // Standard flags for compiled XML and optional UTF-8 encoding\n    int xmlFlags = XML_COMPILE_STANDARD_RESOURCE;\n\n    /* Only enable UTF-8 if the caller of aapt didn't specifically\n     * request UTF-16 encoding and the parameters of this package\n     * allow UTF-8 to be used.\n     */\n    if (!bundle->getUTF16StringsOption()) {\n        xmlFlags |= XML_COMPILE_UTF8;\n    }\n\n    // --------------------------------------------------------------\n    // First, gather all resource information.\n    // --------------------------------------------------------------\n\n    // resType -> leafName -> group\n    KeyedVector<String8, sp<ResourceTypeSet> > *resources = \n            new KeyedVector<String8, sp<ResourceTypeSet> >;\n    collect_files(assets, resources);\n\n    sp<ResourceTypeSet> drawables;\n    sp<ResourceTypeSet> layouts;\n    sp<ResourceTypeSet> anims;\n    sp<ResourceTypeSet> animators;\n    sp<ResourceTypeSet> interpolators;\n    sp<ResourceTypeSet> transitions;\n    sp<ResourceTypeSet> xmls;\n    sp<ResourceTypeSet> raws;\n    sp<ResourceTypeSet> colors;\n    sp<ResourceTypeSet> menus;\n    sp<ResourceTypeSet> mipmaps;\n\n    ASSIGN_IT(drawable);\n    ASSIGN_IT(layout);\n    ASSIGN_IT(anim);\n    ASSIGN_IT(animator);\n    ASSIGN_IT(interpolator);\n    ASSIGN_IT(transition);\n    ASSIGN_IT(xml);\n    ASSIGN_IT(raw);\n    ASSIGN_IT(color);\n    ASSIGN_IT(menu);\n    ASSIGN_IT(mipmap);\n\n    assets->setResources(resources);\n    // now go through any resource overlays and collect their files\n    sp<AaptAssets> current = assets->getOverlay();\n    while(current.get()) {\n        KeyedVector<String8, sp<ResourceTypeSet> > *resources = \n                new KeyedVector<String8, sp<ResourceTypeSet> >;\n        current->setResources(resources);\n        collect_files(current, resources);\n        current = current->getOverlay();\n    }\n    // apply the overlay files to the base set\n    if (!applyFileOverlay(bundle, assets, &drawables, \"drawable\") ||\n            !applyFileOverlay(bundle, assets, &layouts, \"layout\") ||\n            !applyFileOverlay(bundle, assets, &anims, \"anim\") ||\n            !applyFileOverlay(bundle, assets, &animators, \"animator\") ||\n            !applyFileOverlay(bundle, assets, &interpolators, \"interpolator\") ||\n            !applyFileOverlay(bundle, assets, &transitions, \"transition\") ||\n            !applyFileOverlay(bundle, assets, &xmls, \"xml\") ||\n            !applyFileOverlay(bundle, assets, &raws, \"raw\") ||\n            !applyFileOverlay(bundle, assets, &colors, \"color\") ||\n            !applyFileOverlay(bundle, assets, &menus, \"menu\") ||\n            !applyFileOverlay(bundle, assets, &mipmaps, \"mipmap\")) {\n        return UNKNOWN_ERROR;\n    }\n\n    bool hasErrors = false;\n\n    if (drawables != NULL) {\n        if (bundle->getOutputAPKFile() != NULL) {\n            err = preProcessImages(bundle, assets, drawables, \"drawable\");\n        }\n        if (err == NO_ERROR) {\n            err = makeFileResources(bundle, assets, &table, drawables, \"drawable\");\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        } else {\n            hasErrors = true;\n        }\n    }\n\n    if (mipmaps != NULL) {\n        if (bundle->getOutputAPKFile() != NULL) {\n            err = preProcessImages(bundle, assets, mipmaps, \"mipmap\");\n        }\n        if (err == NO_ERROR) {\n            err = makeFileResources(bundle, assets, &table, mipmaps, \"mipmap\");\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        } else {\n            hasErrors = true;\n        }\n    }\n\n    if (layouts != NULL) {\n        err = makeFileResources(bundle, assets, &table, layouts, \"layout\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (anims != NULL) {\n        err = makeFileResources(bundle, assets, &table, anims, \"anim\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (animators != NULL) {\n        err = makeFileResources(bundle, assets, &table, animators, \"animator\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (transitions != NULL) {\n        err = makeFileResources(bundle, assets, &table, transitions, \"transition\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (interpolators != NULL) {\n        err = makeFileResources(bundle, assets, &table, interpolators, \"interpolator\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (xmls != NULL) {\n        err = makeFileResources(bundle, assets, &table, xmls, \"xml\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (raws != NULL) {\n        err = makeFileResources(bundle, assets, &table, raws, \"raw\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    // compile resources\n    current = assets;\n    while(current.get()) {\n        KeyedVector<String8, sp<ResourceTypeSet> > *resources = \n                current->getResources();\n\n        ssize_t index = resources->indexOfKey(String8(\"values\"));\n        if (index >= 0) {\n            ResourceDirIterator it(resources->valueAt(index), String8(\"values\"));\n            ssize_t res;\n            while ((res=it.next()) == NO_ERROR) {\n                sp<AaptFile> file = it.getFile();\n                res = compileResourceFile(bundle, assets, file, it.getParams(), \n                                          (current!=assets), &table);\n                if (res != NO_ERROR) {\n                    hasErrors = true;\n                }\n            }\n        }\n        current = current->getOverlay();\n    }\n\n    if (colors != NULL) {\n        err = makeFileResources(bundle, assets, &table, colors, \"color\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (menus != NULL) {\n        err = makeFileResources(bundle, assets, &table, menus, \"menu\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    // --------------------------------------------------------------------\n    // Assignment of resource IDs and initial generation of resource table.\n    // --------------------------------------------------------------------\n\n    if (table.hasResources()) {\n        err = table.assignResourceIds(bundle);\n        if (err < NO_ERROR) {\n            return err;\n        }\n    }\n\n    // --------------------------------------------------------------\n    // Finally, we can now we can compile XML files, which may reference\n    // resources.\n    // --------------------------------------------------------------\n\n    if (layouts != NULL) {\n        ResourceDirIterator it(layouts, String8(\"layout\"));\n        while ((err=it.next()) == NO_ERROR) {\n            String8 src = it.getFile()->getPrintableSource();\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err == NO_ERROR) {\n                ResXMLTree block;\n                block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);\n                checkForIds(src, block);\n            } else {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (anims != NULL) {\n        ResourceDirIterator it(anims, String8(\"anim\"));\n        while ((err=it.next()) == NO_ERROR) {\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (animators != NULL) {\n        ResourceDirIterator it(animators, String8(\"animator\"));\n        while ((err=it.next()) == NO_ERROR) {\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (interpolators != NULL) {\n        ResourceDirIterator it(interpolators, String8(\"interpolator\"));\n        while ((err=it.next()) == NO_ERROR) {\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (transitions != NULL) {\n        ResourceDirIterator it(transitions, String8(\"transition\"));\n        while ((err=it.next()) == NO_ERROR) {\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (xmls != NULL) {\n        ResourceDirIterator it(xmls, String8(\"xml\"));\n        while ((err=it.next()) == NO_ERROR) {\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (drawables != NULL) {\n        ResourceDirIterator it(drawables, String8(\"drawable\"));\n        while ((err=it.next()) == NO_ERROR) {\n            err = postProcessImage(bundle, assets, &table, it.getFile());\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (colors != NULL) {\n        ResourceDirIterator it(colors, String8(\"color\"));\n        while ((err=it.next()) == NO_ERROR) {\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (menus != NULL) {\n        ResourceDirIterator it(menus, String8(\"menu\"));\n        while ((err=it.next()) == NO_ERROR) {\n            String8 src = it.getFile()->getPrintableSource();\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err == NO_ERROR) {\n                ResXMLTree block;\n                block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);\n                checkForIds(src, block);\n            } else {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    // Now compile any generated resources.\n    std::queue<CompileResourceWorkItem>& workQueue = table.getWorkQueue();\n    while (!workQueue.empty()) {\n        CompileResourceWorkItem& workItem = workQueue.front();\n        int xmlCompilationFlags = xmlFlags | XML_COMPILE_PARSE_VALUES\n                | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS;\n        if (!workItem.needsCompiling) {\n            xmlCompilationFlags &= ~XML_COMPILE_ASSIGN_ATTRIBUTE_IDS;\n            xmlCompilationFlags &= ~XML_COMPILE_PARSE_VALUES;\n        }\n        err = compileXmlFile(bundle, assets, workItem.resourceName, workItem.xmlRoot,\n                             workItem.file, &table, xmlCompilationFlags);\n\n        if (err == NO_ERROR) {\n            assets->addResource(workItem.resPath.getPathLeaf(),\n                                workItem.resPath,\n                                workItem.file,\n                                workItem.file->getResourceType());\n        } else {\n            hasErrors = true;\n        }\n        workQueue.pop();\n    }\n\n    if (table.validateLocalizations()) {\n        hasErrors = true;\n    }\n    \n    if (hasErrors) {\n        return UNKNOWN_ERROR;\n    }\n\n    // If we're not overriding the platform build versions,\n    // extract them from the platform APK.\n    if (packageType != ResourceTable::System &&\n            (bundle->getPlatformBuildVersionCode() == \"\" ||\n            bundle->getPlatformBuildVersionName() == \"\")) {\n        err = extractPlatformBuildVersion(assets->getAssetManager(), bundle);\n        if (err != NO_ERROR) {\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    const sp<AaptFile> manifestFile(androidManifestFile->getFiles().valueAt(0));\n    String8 manifestPath(manifestFile->getPrintableSource());\n\n    // Generate final compiled manifest file.\n    manifestFile->clearData();\n    sp<XMLNode> manifestTree = XMLNode::parse(manifestFile);\n    if (manifestTree == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    err = massageManifest(bundle, manifestTree);\n    if (err < NO_ERROR) {\n        return err;\n    }\n    err = compileXmlFile(bundle, assets, String16(), manifestTree, manifestFile, &table);\n    if (err < NO_ERROR) {\n        return err;\n    }\n\n    if (table.modifyForCompat(bundle) != NO_ERROR) {\n        return UNKNOWN_ERROR;\n    }\n\n    //block.restart();\n    //printXMLBlock(&block);\n\n    // --------------------------------------------------------------\n    // Generate the final resource table.\n    // Re-flatten because we may have added new resource IDs\n    // --------------------------------------------------------------\n\n\n    ResTable finalResTable;\n    sp<AaptFile> resFile;\n    \n    if (table.hasResources()) {\n        sp<AaptSymbols> symbols = assets->getSymbolsFor(String8(\"R\"));\n        err = table.addSymbols(symbols, bundle->getSkipSymbolsWithoutDefaultLocalization());\n        if (err < NO_ERROR) {\n            return err;\n        }\n\n        KeyedVector<Symbol, Vector<SymbolDefinition> > densityVaryingResources;\n        if (builder->getSplits().size() > 1) {\n            // Only look for density varying resources if we're generating\n            // splits.\n            table.getDensityVaryingResources(densityVaryingResources);\n        }\n\n        Vector<sp<ApkSplit> >& splits = builder->getSplits();\n        const size_t numSplits = splits.size();\n        for (size_t i = 0; i < numSplits; i++) {\n            sp<ApkSplit>& split = splits.editItemAt(i);\n            sp<AaptFile> flattenedTable = new AaptFile(String8(\"resources.arsc\"),\n                    AaptGroupEntry(), String8());\n            err = table.flatten(bundle, split->getResourceFilter(),\n                    flattenedTable, split->isBase());\n            if (err != NO_ERROR) {\n                fprintf(stderr, \"Failed to generate resource table for split '%s'\\n\",\n                        split->getPrintableName().string());\n                return err;\n            }\n            split->addEntry(String8(\"resources.arsc\"), flattenedTable);\n\n            if (split->isBase()) {\n                resFile = flattenedTable;\n                err = finalResTable.add(flattenedTable->getData(), flattenedTable->getSize());\n                if (err != NO_ERROR) {\n                    fprintf(stderr, \"Generated resource table is corrupt.\\n\");\n                    return err;\n                }\n            } else {\n                ResTable resTable;\n                err = resTable.add(flattenedTable->getData(), flattenedTable->getSize());\n                if (err != NO_ERROR) {\n                    fprintf(stderr, \"Generated resource table for split '%s' is corrupt.\\n\",\n                            split->getPrintableName().string());\n                    return err;\n                }\n\n                bool hasError = false;\n                const std::set<ConfigDescription>& splitConfigs = split->getConfigs();\n                for (std::set<ConfigDescription>::const_iterator iter = splitConfigs.begin();\n                        iter != splitConfigs.end();\n                        ++iter) {\n                    const ConfigDescription& config = *iter;\n                    if (AaptConfig::isDensityOnly(config)) {\n                        // Each density only split must contain all\n                        // density only resources.\n                        Res_value val;\n                        resTable.setParameters(&config);\n                        const size_t densityVaryingResourceCount = densityVaryingResources.size();\n                        for (size_t k = 0; k < densityVaryingResourceCount; k++) {\n                            const Symbol& symbol = densityVaryingResources.keyAt(k);\n                            ssize_t block = resTable.getResource(symbol.id, &val, true);\n                            if (block < 0) {\n                                // Maybe it's in the base?\n                                finalResTable.setParameters(&config);\n                                block = finalResTable.getResource(symbol.id, &val, true);\n                            }\n\n                            if (block < 0) {\n                                hasError = true;\n                                SourcePos().error(\"%s has no definition for density split '%s'\",\n                                        symbol.toString().string(), config.toString().string());\n\n                                if (bundle->getVerbose()) {\n                                    const Vector<SymbolDefinition>& defs = densityVaryingResources[k];\n                                    const size_t defCount = std::min(size_t(5), defs.size());\n                                    for (size_t d = 0; d < defCount; d++) {\n                                        const SymbolDefinition& def = defs[d];\n                                        def.source.error(\"%s has definition for %s\",\n                                                symbol.toString().string(), def.config.toString().string());\n                                    }\n\n                                    if (defCount < defs.size()) {\n                                        SourcePos().error(\"and %d more ...\", (int) (defs.size() - defCount));\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n\n                if (hasError) {\n                    return UNKNOWN_ERROR;\n                }\n\n                // Generate the AndroidManifest for this split.\n                sp<AaptFile> generatedManifest = new AaptFile(String8(\"AndroidManifest.xml\"),\n                        AaptGroupEntry(), String8());\n                err = generateAndroidManifestForSplit(bundle, assets, split,\n                        generatedManifest, &table);\n                if (err != NO_ERROR) {\n                    fprintf(stderr, \"Failed to generate AndroidManifest.xml for split '%s'\\n\",\n                            split->getPrintableName().string());\n                    return err;\n                }\n                split->addEntry(String8(\"AndroidManifest.xml\"), generatedManifest);\n            }\n        }\n\n        if (bundle->getPublicOutputFile()) {\n            FILE* fp = fopen(bundle->getPublicOutputFile(), \"w+\");\n            if (fp == NULL) {\n                fprintf(stderr, \"ERROR: Unable to open public definitions output file %s: %s\\n\",\n                        (const char*)bundle->getPublicOutputFile(), strerror(errno));\n                return UNKNOWN_ERROR;\n            }\n            if (bundle->getVerbose()) {\n                printf(\"  Writing public definitions to %s.\\n\", bundle->getPublicOutputFile());\n            }\n            table.writePublicDefinitions(String16(assets->getPackage()), fp);\n            fclose(fp);\n        }\n\n        if (finalResTable.getTableCount() == 0 || resFile == NULL) {\n            fprintf(stderr, \"No resource table was generated.\\n\");\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    // Perform a basic validation of the manifest file.  This time we\n    // parse it with the comments intact, so that we can use them to\n    // generate java docs...  so we are not going to write this one\n    // back out to the final manifest data.\n    sp<AaptFile> outManifestFile = new AaptFile(manifestFile->getSourceFile(),\n            manifestFile->getGroupEntry(),\n            manifestFile->getResourceType());\n    err = compileXmlFile(bundle, assets, String16(), manifestFile,\n            outManifestFile, &table, XML_COMPILE_STANDARD_RESOURCE & ~XML_COMPILE_STRIP_COMMENTS);\n    if (err < NO_ERROR) {\n        return err;\n    }\n    ResXMLTree block;\n    block.setTo(outManifestFile->getData(), outManifestFile->getSize(), true);\n    String16 manifest16(\"manifest\");\n    String16 permission16(\"permission\");\n    String16 permission_group16(\"permission-group\");\n    String16 uses_permission16(\"uses-permission\");\n    String16 instrumentation16(\"instrumentation\");\n    String16 application16(\"application\");\n    String16 provider16(\"provider\");\n    String16 service16(\"service\");\n    String16 receiver16(\"receiver\");\n    String16 activity16(\"activity\");\n    String16 action16(\"action\");\n    String16 category16(\"category\");\n    String16 data16(\"scheme\");\n    String16 feature_group16(\"feature-group\");\n    String16 uses_feature16(\"uses-feature\");\n    const char* packageIdentChars = \"abcdefghijklmnopqrstuvwxyz\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789\";\n    const char* packageIdentCharsWithTheStupid = \"abcdefghijklmnopqrstuvwxyz\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-\";\n    const char* classIdentChars = \"abcdefghijklmnopqrstuvwxyz\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789$\";\n    const char* processIdentChars = \"abcdefghijklmnopqrstuvwxyz\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:\";\n    const char* authoritiesIdentChars = \"abcdefghijklmnopqrstuvwxyz\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-:;\";\n    const char* typeIdentChars = \"abcdefghijklmnopqrstuvwxyz\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:-/*+\";\n    const char* schemeIdentChars = \"abcdefghijklmnopqrstuvwxyz\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-\";\n    ResXMLTree::event_code_t code;\n    sp<AaptSymbols> permissionSymbols;\n    sp<AaptSymbols> permissionGroupSymbols;\n    while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n           && code > ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::START_TAG) {\n            size_t len;\n            if (block.getElementNamespace(&len) != NULL) {\n                continue;\n            }\n            if (strcmp16(block.getElementName(&len), manifest16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block, NULL, \"package\",\n                                 packageIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,\n                                 \"sharedUserId\", packageIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), permission16.string()) == 0\n                    || strcmp16(block.getElementName(&len), permission_group16.string()) == 0) {\n                const bool isGroup = strcmp16(block.getElementName(&len),\n                        permission_group16.string()) == 0;\n                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,\n                                 \"name\", isGroup ? packageIdentCharsWithTheStupid\n                                 : packageIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                SourcePos srcPos(manifestPath, block.getLineNumber());\n                sp<AaptSymbols> syms;\n                if (!isGroup) {\n                    syms = permissionSymbols;\n                    if (syms == NULL) {\n                        sp<AaptSymbols> symbols =\n                                assets->getSymbolsFor(String8(\"Manifest\"));\n                        syms = permissionSymbols = symbols->addNestedSymbol(\n                                String8(\"permission\"), srcPos);\n                    }\n                } else {\n                    syms = permissionGroupSymbols;\n                    if (syms == NULL) {\n                        sp<AaptSymbols> symbols =\n                                assets->getSymbolsFor(String8(\"Manifest\"));\n                        syms = permissionGroupSymbols = symbols->addNestedSymbol(\n                                String8(\"permission_group\"), srcPos);\n                    }\n                }\n                size_t len;\n                ssize_t index = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, \"name\");\n                const char16_t* id = block.getAttributeStringValue(index, &len);\n                if (id == NULL) {\n                    fprintf(stderr, \"%s:%d: missing name attribute in element <%s>.\\n\", \n                            manifestPath.string(), block.getLineNumber(),\n                            String8(block.getElementName(&len)).string());\n                    hasErrors = true;\n                    break;\n                }\n                String8 idStr(id);\n                char* p = idStr.lockBuffer(idStr.size());\n                char* e = p + idStr.size();\n                bool begins_with_digit = true;  // init to true so an empty string fails\n                while (e > p) {\n                    e--;\n                    if (*e >= '0' && *e <= '9') {\n                      begins_with_digit = true;\n                      continue;\n                    }\n                    if ((*e >= 'a' && *e <= 'z') ||\n                        (*e >= 'A' && *e <= 'Z') ||\n                        (*e == '_')) {\n                      begins_with_digit = false;\n                      continue;\n                    }\n                    if (isGroup && (*e == '-')) {\n                        *e = '_';\n                        begins_with_digit = false;\n                        continue;\n                    }\n                    e++;\n                    break;\n                }\n                idStr.unlockBuffer();\n                // verify that we stopped because we hit a period or\n                // the beginning of the string, and that the\n                // identifier didn't begin with a digit.\n                if (begins_with_digit || (e != p && *(e-1) != '.')) {\n                  fprintf(stderr,\n                          \"%s:%d: Permission name <%s> is not a valid Java symbol\\n\",\n                          manifestPath.string(), block.getLineNumber(), idStr.string());\n                  hasErrors = true;\n                }\n                syms->addStringSymbol(String8(e), idStr, srcPos);\n                const char16_t* cmt = block.getComment(&len);\n                if (cmt != NULL && *cmt != 0) {\n                    //printf(\"Comment of %s: %s\\n\", String8(e).string(),\n                    //        String8(cmt).string());\n                    syms->appendComment(String8(e), String16(cmt), srcPos);\n                }\n                syms->makeSymbolPublic(String8(e), srcPos);\n            } else if (strcmp16(block.getElementName(&len), uses_permission16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,\n                                 \"name\", packageIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), instrumentation16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,\n                                 \"name\", classIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"targetPackage\",\n                                 packageIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), application16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,\n                                 \"name\", classIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"permission\",\n                                 packageIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"process\",\n                                 processIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"taskAffinity\",\n                                 processIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), provider16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,\n                                 \"name\", classIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"authorities\",\n                                 authoritiesIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"permission\",\n                                 packageIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"process\",\n                                 processIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), service16.string()) == 0\n                       || strcmp16(block.getElementName(&len), receiver16.string()) == 0\n                       || strcmp16(block.getElementName(&len), activity16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,\n                                 \"name\", classIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"permission\",\n                                 packageIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"process\",\n                                 processIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"taskAffinity\",\n                                 processIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), action16.string()) == 0\n                       || strcmp16(block.getElementName(&len), category16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"name\",\n                                 packageIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), data16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"mimeType\",\n                                 typeIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"scheme\",\n                                 schemeIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), feature_group16.string()) == 0) {\n                int depth = 1;\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n                       && code > ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::START_TAG) {\n                        depth++;\n                        if (strcmp16(block.getElementName(&len), uses_feature16.string()) == 0) {\n                            ssize_t idx = block.indexOfAttribute(\n                                    RESOURCES_ANDROID_NAMESPACE, \"required\");\n                            if (idx < 0) {\n                                continue;\n                            }\n\n                            int32_t data = block.getAttributeData(idx);\n                            if (data == 0) {\n                                fprintf(stderr, \"%s:%d: Tag <uses-feature> can not have \"\n                                        \"android:required=\\\"false\\\" when inside a \"\n                                        \"<feature-group> tag.\\n\",\n                                        manifestPath.string(), block.getLineNumber());\n                                hasErrors = true;\n                            }\n                        }\n                    } else if (code == ResXMLTree::END_TAG) {\n                        depth--;\n                        if (depth == 0) {\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    if (hasErrors) {\n        return UNKNOWN_ERROR;\n    }\n\n    if (resFile != NULL) {\n        // These resources are now considered to be a part of the included\n        // resources, for others to reference.\n        err = assets->addIncludedResources(resFile);\n        if (err < NO_ERROR) {\n            fprintf(stderr, \"ERROR: Unable to parse generated resources, aborting.\\n\");\n            return err;\n        }\n    }\n    \n    return err;\n}\n\nstatic const char* getIndentSpace(int indent)\n{\nstatic const char whitespace[] =\n\"                                                                                       \";\n\n    return whitespace + sizeof(whitespace) - 1 - indent*4;\n}\n\nstatic String8 flattenSymbol(const String8& symbol) {\n    String8 result(symbol);\n    ssize_t first;\n    if ((first = symbol.find(\":\", 0)) >= 0\n            || (first = symbol.find(\".\", 0)) >= 0) {\n        size_t size = symbol.size();\n        char* buf = result.lockBuffer(size);\n        for (size_t i = first; i < size; i++) {\n            if (buf[i] == ':' || buf[i] == '.') {\n                buf[i] = '_';\n            }\n        }\n        result.unlockBuffer(size);\n    }\n    return result;\n}\n\nstatic String8 getSymbolPackage(const String8& symbol, const sp<AaptAssets>& assets, bool pub) {\n    ssize_t colon = symbol.find(\":\", 0);\n    if (colon >= 0) {\n        return String8(symbol.string(), colon);\n    }\n    return pub ? assets->getPackage() : assets->getSymbolsPrivatePackage();\n}\n\nstatic String8 getSymbolName(const String8& symbol) {\n    ssize_t colon = symbol.find(\":\", 0);\n    if (colon >= 0) {\n        return String8(symbol.string() + colon + 1);\n    }\n    return symbol;\n}\n\nstatic String16 getAttributeComment(const sp<AaptAssets>& assets,\n                                    const String8& name,\n                                    String16* outTypeComment = NULL)\n{\n    sp<AaptSymbols> asym = assets->getSymbolsFor(String8(\"R\"));\n    if (asym != NULL) {\n        //printf(\"Got R symbols!\\n\");\n        asym = asym->getNestedSymbols().valueFor(String8(\"attr\"));\n        if (asym != NULL) {\n            //printf(\"Got attrs symbols! comment %s=%s\\n\",\n            //     name.string(), String8(asym->getComment(name)).string());\n            if (outTypeComment != NULL) {\n                *outTypeComment = asym->getTypeComment(name);\n            }\n            return asym->getComment(name);\n        }\n    }\n    return String16();\n}\n\nstatic status_t writeResourceLoadedCallbackForLayoutClasses(\n    FILE* fp, const sp<AaptAssets>& assets,\n    const sp<AaptSymbols>& symbols, int indent, bool /* includePrivate */)\n{\n    String16 attr16(\"attr\");\n    String16 package16(assets->getPackage());\n\n    const char* indentStr = getIndentSpace(indent);\n    bool hasErrors = false;\n\n    size_t i;\n    size_t N = symbols->getNestedSymbols().size();\n    for (i=0; i<N; i++) {\n        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);\n        String8 realClassName(symbols->getNestedSymbols().keyAt(i));\n        String8 nclassName(flattenSymbol(realClassName));\n\n        fprintf(fp,\n                \"%sfor(int i = 0; i < styleable.%s.length; ++i) {\\n\"\n                \"%sstyleable.%s[i] = (styleable.%s[i] & 0x00ffffff) | (packageId << 24);\\n\"\n                \"%s}\\n\",\n                indentStr, nclassName.string(),\n                getIndentSpace(indent+1), nclassName.string(), nclassName.string(),\n                indentStr);\n    }\n\n    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;\n}\n\nstatic status_t writeResourceLoadedCallback(\n    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,\n    const sp<AaptSymbols>& symbols, const String8& className, int indent)\n{\n    size_t i;\n    status_t err = NO_ERROR;\n\n    size_t N = symbols->getSymbols().size();\n    for (i=0; i<N; i++) {\n        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);\n        if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) {\n            continue;\n        }\n        if (!assets->isJavaSymbol(sym, includePrivate)) {\n            continue;\n        }\n        String8 flat_name(flattenSymbol(sym.name));\n        fprintf(fp,\n                \"%s%s.%s = (%s.%s & 0x00ffffff) | (packageId << 24);\\n\",\n                getIndentSpace(indent), className.string(), flat_name.string(),\n                className.string(), flat_name.string());\n    }\n\n    N = symbols->getNestedSymbols().size();\n    for (i=0; i<N; i++) {\n        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);\n        String8 nclassName(symbols->getNestedSymbols().keyAt(i));\n        if (nclassName == \"styleable\") {\n            err = writeResourceLoadedCallbackForLayoutClasses(\n                    fp, assets, nsymbols, indent, includePrivate);\n        } else {\n            err = writeResourceLoadedCallback(fp, assets, includePrivate, nsymbols,\n                    nclassName, indent);\n        }\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatic status_t writeLayoutClasses(\n    FILE* fp, const sp<AaptAssets>& assets,\n    const sp<AaptSymbols>& symbols, int indent, bool includePrivate, bool nonConstantId)\n{\n    const char* indentStr = getIndentSpace(indent);\n    if (!includePrivate) {\n        fprintf(fp, \"%s/** @doconly */\\n\", indentStr);\n    }\n    fprintf(fp, \"%spublic static final class styleable {\\n\", indentStr);\n    indent++;\n\n    String16 attr16(\"attr\");\n    String16 package16(assets->getPackage());\n\n    indentStr = getIndentSpace(indent);\n    bool hasErrors = false;\n\n    size_t i;\n    size_t N = symbols->getNestedSymbols().size();\n    for (i=0; i<N; i++) {\n        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);\n        String8 realClassName(symbols->getNestedSymbols().keyAt(i));\n        String8 nclassName(flattenSymbol(realClassName));\n\n        SortedVector<uint32_t> idents;\n        Vector<uint32_t> origOrder;\n        Vector<bool> publicFlags;\n\n        size_t a;\n        size_t NA = nsymbols->getSymbols().size();\n        for (a=0; a<NA; a++) {\n            const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a));\n            int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32\n                    ? sym.int32Val : 0;\n            bool isPublic = true;\n            if (code == 0) {\n                String16 name16(sym.name);\n                uint32_t typeSpecFlags;\n                code = assets->getIncludedResources().identifierForName(\n                    name16.string(), name16.size(),\n                    attr16.string(), attr16.size(),\n                    package16.string(), package16.size(), &typeSpecFlags);\n                if (code == 0) {\n                    String16 package16_taobao(sktPackageName);\n                    code = assets->getIncludedResources().identifierForName(\n                        name16.string(), name16.size(),\n                        attr16.string(), attr16.size(),\n                        package16_taobao.string(), package16_taobao.size(), &typeSpecFlags);\n                }\n                // if (code ==0) {\n                // String16 package16_taobao(sktPackageName);\n                // code = assets->getIncludedResources().identifierForName(\n                //     name16.string(), name16.size(),\n                //     attr16.string(), attr16.size(),\n                //     package16_taobao.string(), package16_taobao.size(), &typeSpecFlags);\n                // }\n                if (code == 0) {\n                    fprintf(stderr, \"ERROR: In <declare-styleable> %s, unable to find attribute %s\\n\",\n                            nclassName.string(), sym.name.string());\n                    hasErrors = true;\n                }\n                isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;\n            }\n            idents.add(code);\n            origOrder.add(code);\n            publicFlags.add(isPublic);\n        }\n\n        NA = idents.size();\n\n        String16 comment = symbols->getComment(realClassName);\n        AnnotationProcessor ann;\n        fprintf(fp, \"%s/** \", indentStr);\n        if (comment.size() > 0) {\n            String8 cmt(comment);\n            ann.preprocessComment(cmt);\n            fprintf(fp, \"%s\\n\", cmt.string());\n        } else {\n            fprintf(fp, \"Attributes that can be used with a %s.\\n\", nclassName.string());\n        }\n        bool hasTable = false;\n        for (a=0; a<NA; a++) {\n            ssize_t pos = idents.indexOf(origOrder.itemAt(a));\n            if (pos >= 0) {\n                if (!hasTable) {\n                    hasTable = true;\n                    fprintf(fp,\n                            \"%s   <p>Includes the following attributes:</p>\\n\"\n                            \"%s   <table>\\n\"\n                            \"%s   <colgroup align=\\\"left\\\" />\\n\"\n                            \"%s   <colgroup align=\\\"left\\\" />\\n\"\n                            \"%s   <tr><th>Attribute</th><th>Description</th></tr>\\n\",\n                            indentStr,\n                            indentStr,\n                            indentStr,\n                            indentStr,\n                            indentStr);\n                }\n                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);\n                if (!publicFlags.itemAt(a) && !includePrivate) {\n                    continue;\n                }\n                String8 name8(sym.name);\n                String16 comment(sym.comment);\n                if (comment.size() <= 0) {\n                    comment = getAttributeComment(assets, name8);\n                }\n                if (comment.contains(u\"@removed\")) {\n                    continue;\n                }\n                if (comment.size() > 0) {\n                    const char16_t* p = comment.string();\n                    while (*p != 0 && *p != '.') {\n                        if (*p == '{') {\n                            while (*p != 0 && *p != '}') {\n                                p++;\n                            }\n                        } else {\n                            p++;\n                        }\n                    }\n                    if (*p == '.') {\n                        p++;\n                    }\n                    comment = String16(comment.string(), p-comment.string());\n                }\n                fprintf(fp, \"%s   <tr><td><code>{@link #%s_%s %s:%s}</code></td><td>%s</td></tr>\\n\",\n                        indentStr, nclassName.string(),\n                        flattenSymbol(name8).string(),\n                        getSymbolPackage(name8, assets, true).string(),\n                        getSymbolName(name8).string(),\n                        String8(comment).string());\n            }\n        }\n        if (hasTable) {\n            fprintf(fp, \"%s   </table>\\n\", indentStr);\n        }\n        for (a=0; a<NA; a++) {\n            ssize_t pos = idents.indexOf(origOrder.itemAt(a));\n            if (pos >= 0) {\n                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);\n                if (!publicFlags.itemAt(a) && !includePrivate) {\n                    continue;\n                }\n                fprintf(fp, \"%s   @see #%s_%s\\n\",\n                        indentStr, nclassName.string(),\n                        flattenSymbol(sym.name).string());\n            }\n        }\n        fprintf(fp, \"%s */\\n\", getIndentSpace(indent));\n\n        ann.printAnnotations(fp, indentStr);\n        \n        fprintf(fp,\n                \"%spublic static final int[] %s = {\\n\"\n                \"%s\",\n                indentStr, nclassName.string(),\n                getIndentSpace(indent+1));\n\n        for (a=0; a<NA; a++) {\n            if (a != 0) {\n                if ((a&3) == 0) {\n                    fprintf(fp, \",\\n%s\", getIndentSpace(indent+1));\n                } else {\n                    fprintf(fp, \", \");\n                }\n            }\n            fprintf(fp, \"0x%08x\", idents[a]);\n        }\n\n        fprintf(fp, \"\\n%s};\\n\", indentStr);\n\n        for (a=0; a<NA; a++) {\n            ssize_t pos = idents.indexOf(origOrder.itemAt(a));\n            if (pos >= 0) {\n                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);\n                if (!publicFlags.itemAt(a) && !includePrivate) {\n                    continue;\n                }\n                String8 name8(sym.name);\n                String16 comment(sym.comment);\n                String16 typeComment;\n                if (comment.size() <= 0) {\n                    comment = getAttributeComment(assets, name8, &typeComment);\n                } else {\n                    getAttributeComment(assets, name8, &typeComment);\n                }\n\n                uint32_t typeSpecFlags = 0;\n                String16 name16(sym.name);\n                assets->getIncludedResources().identifierForName(\n                    name16.string(), name16.size(),\n                    attr16.string(), attr16.size(),\n                    package16.string(), package16.size(), &typeSpecFlags);\n                //printf(\"%s:%s/%s: 0x%08x\\n\", String8(package16).string(),\n                //    String8(attr16).string(), String8(name16).string(), typeSpecFlags);\n                const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;\n\n                AnnotationProcessor ann;\n                fprintf(fp, \"%s/**\\n\", indentStr);\n                if (comment.size() > 0) {\n                    String8 cmt(comment);\n                    ann.preprocessComment(cmt);\n                    fprintf(fp, \"%s  <p>\\n%s  @attr description\\n\", indentStr, indentStr);\n                    fprintf(fp, \"%s  %s\\n\", indentStr, cmt.string());\n                } else {\n                    fprintf(fp,\n                            \"%s  <p>This symbol is the offset where the {@link %s.R.attr#%s}\\n\"\n                            \"%s  attribute's value can be found in the {@link #%s} array.\\n\",\n                            indentStr,\n                            getSymbolPackage(name8, assets, pub).string(),\n                            getSymbolName(name8).string(),\n                            indentStr, nclassName.string());\n                }\n                if (typeComment.size() > 0) {\n                    String8 cmt(typeComment);\n                    ann.preprocessComment(cmt);\n                    fprintf(fp, \"\\n\\n%s  %s\\n\", indentStr, cmt.string());\n                }\n                if (comment.size() > 0) {\n                    if (pub) {\n                        fprintf(fp,\n                                \"%s  <p>This corresponds to the global attribute\\n\"\n                                \"%s  resource symbol {@link %s.R.attr#%s}.\\n\",\n                                indentStr, indentStr,\n                                getSymbolPackage(name8, assets, true).string(),\n                                getSymbolName(name8).string());\n                    } else {\n                        fprintf(fp,\n                                \"%s  <p>This is a private symbol.\\n\", indentStr);\n                    }\n                }\n                fprintf(fp, \"%s  @attr name %s:%s\\n\", indentStr,\n                        getSymbolPackage(name8, assets, pub).string(),\n                        getSymbolName(name8).string());\n                fprintf(fp, \"%s*/\\n\", indentStr);\n                ann.printAnnotations(fp, indentStr);\n\n                const char * id_format = nonConstantId ?\n                        \"%spublic static int %s_%s = %d;\\n\" :\n                        \"%spublic static final int %s_%s = %d;\\n\";\n\n                fprintf(fp,\n                        id_format,\n                        indentStr, nclassName.string(),\n                        flattenSymbol(name8).string(), (int)pos);\n            }\n        }\n    }\n\n    indent--;\n    fprintf(fp, \"%s};\\n\", getIndentSpace(indent));\n    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;\n}\n\nstatic status_t writeTextLayoutClasses(\n    FILE* fp, const sp<AaptAssets>& assets,\n    const sp<AaptSymbols>& symbols, bool includePrivate)\n{\n    String16 attr16(\"attr\");\n    String16 package16(assets->getPackage());\n\n    bool hasErrors = false;\n\n    size_t i;\n    size_t N = symbols->getNestedSymbols().size();\n    for (i=0; i<N; i++) {\n        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);\n        String8 realClassName(symbols->getNestedSymbols().keyAt(i));\n        String8 nclassName(flattenSymbol(realClassName));\n\n        SortedVector<uint32_t> idents;\n        Vector<uint32_t> origOrder;\n        Vector<bool> publicFlags;\n\n        size_t a;\n        size_t NA = nsymbols->getSymbols().size();\n        for (a=0; a<NA; a++) {\n            const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a));\n            int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32\n                    ? sym.int32Val : 0;\n            bool isPublic = true;\n            if (code == 0) {\n                String16 name16(sym.name);\n                uint32_t typeSpecFlags;\n                code = assets->getIncludedResources().identifierForName(\n                    name16.string(), name16.size(),\n                    attr16.string(), attr16.size(),\n                    package16.string(), package16.size(), &typeSpecFlags);\n                if (code ==0) {\n                String16 package16_taobao(sktPackageName);\n                code = assets->getIncludedResources().identifierForName(\n                    name16.string(), name16.size(),\n                    attr16.string(), attr16.size(),\n                    package16_taobao.string(), package16_taobao.size(), &typeSpecFlags);\n                }\n                if (code == 0) {\n                    fprintf(stderr, \"ERROR: In <declare-styleable> %s, unable to find attribute %s\\n\",\n                            nclassName.string(), sym.name.string());\n                    hasErrors = true;\n                }\n                isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;\n            }\n            idents.add(code);\n            origOrder.add(code);\n            publicFlags.add(isPublic);\n        }\n\n        NA = idents.size();\n\n        fprintf(fp, \"int[] styleable %s {\", nclassName.string());\n\n        for (a=0; a<NA; a++) {\n            if (a != 0) {\n                fprintf(fp, \",\");\n            }\n            fprintf(fp, \" 0x%08x\", idents[a]);\n        }\n\n        fprintf(fp, \" }\\n\");\n\n        for (a=0; a<NA; a++) {\n            ssize_t pos = idents.indexOf(origOrder.itemAt(a));\n            if (pos >= 0) {\n                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);\n                if (!publicFlags.itemAt(a) && !includePrivate) {\n                    continue;\n                }\n                String8 name8(sym.name);\n                String16 comment(sym.comment);\n                String16 typeComment;\n                if (comment.size() <= 0) {\n                    comment = getAttributeComment(assets, name8, &typeComment);\n                } else {\n                    getAttributeComment(assets, name8, &typeComment);\n                }\n\n                uint32_t typeSpecFlags = 0;\n                String16 name16(sym.name);\n                assets->getIncludedResources().identifierForName(\n                    name16.string(), name16.size(),\n                    attr16.string(), attr16.size(),\n                    package16.string(), package16.size(), &typeSpecFlags);\n                //printf(\"%s:%s/%s: 0x%08x\\n\", String8(package16).string(),\n                //    String8(attr16).string(), String8(name16).string(), typeSpecFlags);\n                //const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;\n\n                fprintf(fp,\n                        \"int styleable %s_%s %d\\n\",\n                        nclassName.string(),\n                        flattenSymbol(name8).string(), (int)pos);\n            }\n        }\n    }\n\n    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;\n}\n\nstatic status_t writeSymbolClass(\n    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,\n    const sp<AaptSymbols>& symbols, const String8& className, int indent,\n    bool nonConstantId, bool emitCallback)\n{\n    fprintf(fp, \"%spublic %sfinal class %s {\\n\",\n            getIndentSpace(indent),\n            indent != 0 ? \"static \" : \"\", className.string());\n    indent++;\n\n    size_t i;\n    status_t err = NO_ERROR;\n\n    const char * id_format = nonConstantId ?\n            \"%spublic static int %s=0x%08x;\\n\" :\n            \"%spublic static final int %s=0x%08x;\\n\";\n\n    size_t N = symbols->getSymbols().size();\n    for (i=0; i<N; i++) {\n        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);\n        if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) {\n            continue;\n        }\n        if (!assets->isJavaSymbol(sym, includePrivate)) {\n            continue;\n        }\n        String8 name8(sym.name);\n        String16 comment(sym.comment);\n        bool haveComment = false;\n        AnnotationProcessor ann;\n        if (comment.size() > 0) {\n            haveComment = true;\n            String8 cmt(comment);\n            ann.preprocessComment(cmt);\n            fprintf(fp,\n                    \"%s/** %s\\n\",\n                    getIndentSpace(indent), cmt.string());\n        }\n        String16 typeComment(sym.typeComment);\n        if (typeComment.size() > 0) {\n            String8 cmt(typeComment);\n            ann.preprocessComment(cmt);\n            if (!haveComment) {\n                haveComment = true;\n                fprintf(fp,\n                        \"%s/** %s\\n\", getIndentSpace(indent), cmt.string());\n            } else {\n                fprintf(fp,\n                        \"%s %s\\n\", getIndentSpace(indent), cmt.string());\n            }\n        }\n        if (haveComment) {\n            fprintf(fp,\"%s */\\n\", getIndentSpace(indent));\n        }\n        ann.printAnnotations(fp, getIndentSpace(indent));\n        fprintf(fp, id_format,\n                getIndentSpace(indent),\n                flattenSymbol(name8).string(), (int)sym.int32Val);\n    }\n\n    for (i=0; i<N; i++) {\n        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);\n        if (sym.typeCode != AaptSymbolEntry::TYPE_STRING) {\n            continue;\n        }\n        if (!assets->isJavaSymbol(sym, includePrivate)) {\n            continue;\n        }\n        String8 name8(sym.name);\n        String16 comment(sym.comment);\n        AnnotationProcessor ann;\n        if (comment.size() > 0) {\n            String8 cmt(comment);\n            ann.preprocessComment(cmt);\n            fprintf(fp,\n                    \"%s/** %s\\n\"\n                     \"%s */\\n\",\n                    getIndentSpace(indent), cmt.string(),\n                    getIndentSpace(indent));\n        }\n        ann.printAnnotations(fp, getIndentSpace(indent));\n        fprintf(fp, \"%spublic static final String %s=\\\"%s\\\";\\n\",\n                getIndentSpace(indent),\n                flattenSymbol(name8).string(), sym.stringVal.string());\n    }\n\n    sp<AaptSymbols> styleableSymbols;\n\n    N = symbols->getNestedSymbols().size();\n    for (i=0; i<N; i++) {\n        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);\n        String8 nclassName(symbols->getNestedSymbols().keyAt(i));\n        if (nclassName == \"styleable\") {\n            styleableSymbols = nsymbols;\n        } else {\n            err = writeSymbolClass(fp, assets, includePrivate, nsymbols, nclassName,\n                    indent, nonConstantId, false);\n        }\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    if (styleableSymbols != NULL) {\n        err = writeLayoutClasses(fp, assets, styleableSymbols, indent, includePrivate, nonConstantId);\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    if (emitCallback) {\n        fprintf(fp, \"%spublic static void onResourcesLoaded(int packageId) {\\n\",\n                getIndentSpace(indent));\n        writeResourceLoadedCallback(fp, assets, includePrivate, symbols, className, indent + 1);\n        fprintf(fp, \"%s}\\n\", getIndentSpace(indent));\n    }\n\n    indent--;\n    fprintf(fp, \"%s}\\n\", getIndentSpace(indent));\n    return NO_ERROR;\n}\n\nstatic status_t writeTextSymbolClass(\n    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,\n    const sp<AaptSymbols>& symbols, const String8& className)\n{\n    size_t i;\n    status_t err = NO_ERROR;\n\n    size_t N = symbols->getSymbols().size();\n    for (i=0; i<N; i++) {\n        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);\n        if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) {\n            continue;\n        }\n\n        if (!assets->isJavaSymbol(sym, includePrivate)) {\n            continue;\n        }\n\n        String8 name8(sym.name);\n        fprintf(fp, \"int %s %s 0x%08x\\n\",\n                className.string(),\n                flattenSymbol(name8).string(), (int)sym.int32Val);\n    }\n\n    N = symbols->getNestedSymbols().size();\n    for (i=0; i<N; i++) {\n        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);\n        String8 nclassName(symbols->getNestedSymbols().keyAt(i));\n        if (nclassName == \"styleable\") {\n            err = writeTextLayoutClasses(fp, assets, nsymbols, includePrivate);\n        } else {\n            err = writeTextSymbolClass(fp, assets, includePrivate, nsymbols, nclassName);\n        }\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets,\n    const String8& package, bool includePrivate, bool emitCallback)\n{\n    if (!bundle->getRClassDir()) {\n        return NO_ERROR;\n    }\n\n    const char* textSymbolsDest = bundle->getOutputTextSymbols();\n\n    String8 R(\"R\");\n    const size_t N = assets->getSymbols().size();\n    for (size_t i=0; i<N; i++) {\n        sp<AaptSymbols> symbols = assets->getSymbols().valueAt(i);\n        String8 className(assets->getSymbols().keyAt(i));\n        String8 dest(bundle->getRClassDir());\n\n        if (bundle->getMakePackageDirs()) {\n            String8 pkg(package);\n            const char* last = pkg.string();\n            const char* s = last-1;\n            do {\n                s++;\n                if (s > last && (*s == '.' || *s == 0)) {\n                    String8 part(last, s-last);\n                    dest.appendPath(part);\n#ifdef _WIN32\n                    _mkdir(dest.string());\n#else\n                    mkdir(dest.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);\n#endif\n                    last = s+1;\n                }\n            } while (*s);\n        }\n        dest.appendPath(className);\n        dest.append(\".java\");\n        FILE* fp = fopen(dest.string(), \"w+\");\n        if (fp == NULL) {\n            fprintf(stderr, \"ERROR: Unable to open class file %s: %s\\n\",\n                    dest.string(), strerror(errno));\n            return UNKNOWN_ERROR;\n        }\n        if (bundle->getVerbose()) {\n            printf(\"  Writing symbols for class %s.\\n\", className.string());\n        }\n\n        fprintf(fp,\n            \"/* AUTO-GENERATED FILE.  DO NOT MODIFY.\\n\"\n            \" *\\n\"\n            \" * This class was automatically generated by the\\n\"\n            \" * aapt tool from the resource data it found.  It\\n\"\n            \" * should not be modified by hand.\\n\"\n            \" */\\n\"\n            \"\\n\"\n            \"package %s;\\n\\n\", package.string());\n\n        status_t err = writeSymbolClass(fp, assets, includePrivate, symbols,\n                className, 0, bundle->getNonConstantId(), emitCallback);\n        fclose(fp);\n        if (err != NO_ERROR) {\n            return err;\n        }\n\n        if (textSymbolsDest != NULL && R == className) {\n            String8 textDest(textSymbolsDest);\n            textDest.appendPath(className);\n            textDest.append(\".txt\");\n\n            FILE* fp = fopen(textDest.string(), \"w+\");\n            if (fp == NULL) {\n                fprintf(stderr, \"ERROR: Unable to open text symbol file %s: %s\\n\",\n                        textDest.string(), strerror(errno));\n                return UNKNOWN_ERROR;\n            }\n            if (bundle->getVerbose()) {\n                printf(\"  Writing text symbols for class %s.\\n\", className.string());\n            }\n\n            status_t err = writeTextSymbolClass(fp, assets, includePrivate, symbols,\n                    className);\n            fclose(fp);\n            if (err != NO_ERROR) {\n                return err;\n            }\n        }\n\n        // If we were asked to generate a dependency file, we'll go ahead and add this R.java\n        // as a target in the dependency file right next to it.\n        if (bundle->getGenDependencies() && R == className) {\n            // Add this R.java to the dependency file\n            String8 dependencyFile(bundle->getRClassDir());\n            dependencyFile.appendPath(\"R.java.d\");\n\n            FILE *fp = fopen(dependencyFile.string(), \"a\");\n            fprintf(fp,\"%s \\\\\\n\", dest.string());\n            fclose(fp);\n        }\n    }\n\n    return NO_ERROR;\n}\n\n\nclass ProguardKeepSet\n{\npublic:\n    // { rule --> { file locations } }\n    KeyedVector<String8, SortedVector<String8> > rules;\n\n    void add(const String8& rule, const String8& where);\n};\n\nvoid ProguardKeepSet::add(const String8& rule, const String8& where)\n{\n    ssize_t index = rules.indexOfKey(rule);\n    if (index < 0) {\n        index = rules.add(rule, SortedVector<String8>());\n    }\n    rules.editValueAt(index).add(where);\n}\n\nvoid\naddProguardKeepRule(ProguardKeepSet* keep, const String8& inClassName,\n        const char* pkg, const String8& srcName, int line)\n{\n    String8 className(inClassName);\n    if (pkg != NULL) {\n        // asdf     --> package.asdf\n        // .asdf  .a.b  --> package.asdf package.a.b\n        // asdf.adsf --> asdf.asdf\n        const char* p = className.string();\n        const char* q = strchr(p, '.');\n        if (p == q) {\n            className = pkg;\n            className.append(inClassName);\n        } else if (q == NULL) {\n            className = pkg;\n            className.append(\".\");\n            className.append(inClassName);\n        }\n    }\n\n    String8 rule(\"-keep class \");\n    rule += className;\n    rule += \" { <init>(...); }\";\n\n    String8 location(\"view \");\n    location += srcName;\n    char lineno[20];\n    sprintf(lineno, \":%d\", line);\n    location += lineno;\n\n    keep->add(rule, location);\n}\n\nvoid\naddProguardKeepMethodRule(ProguardKeepSet* keep, const String8& memberName,\n        const char* /* pkg */, const String8& srcName, int line)\n{\n    String8 rule(\"-keepclassmembers class * { *** \");\n    rule += memberName;\n    rule += \"(...); }\";\n\n    String8 location(\"onClick \");\n    location += srcName;\n    char lineno[20];\n    sprintf(lineno, \":%d\", line);\n    location += lineno;\n\n    keep->add(rule, location);\n}\n\nstatus_t\nwriteProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& assets, bool mainDex)\n{\n    status_t err;\n    ResXMLTree tree;\n    size_t len;\n    ResXMLTree::event_code_t code;\n    int depth = 0;\n    bool inApplication = false;\n    String8 error;\n    sp<AaptGroup> assGroup;\n    sp<AaptFile> assFile;\n    String8 pkg;\n    String8 defaultProcess;\n\n    // First, look for a package file to parse.  This is required to\n    // be able to generate the resource information.\n    assGroup = assets->getFiles().valueFor(String8(\"AndroidManifest.xml\"));\n    if (assGroup == NULL) {\n        fprintf(stderr, \"ERROR: No AndroidManifest.xml file found.\\n\");\n        return -1;\n    }\n\n    if (assGroup->getFiles().size() != 1) {\n        fprintf(stderr, \"warning: Multiple AndroidManifest.xml files found, using %s\\n\",\n                assGroup->getFiles().valueAt(0)->getPrintableSource().string());\n    }\n\n    assFile = assGroup->getFiles().valueAt(0);\n\n    err = parseXMLResource(assFile, &tree);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    tree.restart();\n\n    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::END_TAG) {\n            if (/* name == \"Application\" && */ depth == 2) {\n                inApplication = false;\n            }\n            depth--;\n            continue;\n        }\n        if (code != ResXMLTree::START_TAG) {\n            continue;\n        }\n        depth++;\n        String8 tag(tree.getElementName(&len));\n        // printf(\"Depth %d tag %s\\n\", depth, tag.string());\n        bool keepTag = false;\n        if (depth == 1) {\n            if (tag != \"manifest\") {\n                fprintf(stderr, \"ERROR: manifest does not start with <manifest> tag\\n\");\n                return -1;\n            }\n            pkg = AaptXml::getAttribute(tree, NULL, \"package\");\n        } else if (depth == 2) {\n            if (tag == \"application\") {\n                inApplication = true;\n                keepTag = true;\n\n                String8 agent = AaptXml::getAttribute(tree,\n                        \"http://schemas.android.com/apk/res/android\",\n                        \"backupAgent\", &error);\n                if (agent.length() > 0) {\n                    addProguardKeepRule(keep, agent, pkg.string(),\n                            assFile->getPrintableSource(), tree.getLineNumber());\n                }\n\n                if (mainDex) {\n                    defaultProcess = AaptXml::getAttribute(tree,\n                            \"http://schemas.android.com/apk/res/android\", \"process\", &error);\n                    if (error != \"\") {\n                        fprintf(stderr, \"ERROR: %s\\n\", error.string());\n                        return -1;\n                    }\n                }\n            } else if (tag == \"instrumentation\") {\n                keepTag = true;\n            }\n        }\n        if (!keepTag && inApplication && depth == 3) {\n            if (tag == \"activity\" || tag == \"service\" || tag == \"receiver\" || tag == \"provider\") {\n                keepTag = true;\n            }\n        }\n        if (keepTag) {\n            String8 name = AaptXml::getAttribute(tree,\n                    \"http://schemas.android.com/apk/res/android\", \"name\", &error);\n            if (error != \"\") {\n                fprintf(stderr, \"ERROR: %s\\n\", error.string());\n                return -1;\n            }\n\n            keepTag = name.length() > 0;\n\n            if (keepTag && mainDex) {\n                String8 componentProcess = AaptXml::getAttribute(tree,\n                        \"http://schemas.android.com/apk/res/android\", \"process\", &error);\n                if (error != \"\") {\n                    fprintf(stderr, \"ERROR: %s\\n\", error.string());\n                    return -1;\n                }\n\n                const String8& process =\n                        componentProcess.length() > 0 ? componentProcess : defaultProcess;\n                keepTag = process.length() > 0 && process.find(\":\") != 0;\n            }\n\n            if (keepTag) {\n                addProguardKeepRule(keep, name, pkg.string(),\n                        assFile->getPrintableSource(), tree.getLineNumber());\n            }\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstruct NamespaceAttributePair {\n    const char* ns;\n    const char* attr;\n\n    NamespaceAttributePair(const char* n, const char* a) : ns(n), attr(a) {}\n    NamespaceAttributePair() : ns(NULL), attr(NULL) {}\n};\n\nstatus_t\nwriteProguardForXml(ProguardKeepSet* keep, const sp<AaptFile>& layoutFile,\n        const Vector<String8>& startTags, const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs)\n{\n    status_t err;\n    ResXMLTree tree;\n    size_t len;\n    ResXMLTree::event_code_t code;\n\n    err = parseXMLResource(layoutFile, &tree);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    tree.restart();\n\n    if (!startTags.isEmpty()) {\n        bool haveStart = false;\n        while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n            if (code != ResXMLTree::START_TAG) {\n                continue;\n            }\n            String8 tag(tree.getElementName(&len));\n            const size_t numStartTags = startTags.size();\n            for (size_t i = 0; i < numStartTags; i++) {\n                if (tag == startTags[i]) {\n                    haveStart = true;\n                }\n            }\n            break;\n        }\n        if (!haveStart) {\n            return NO_ERROR;\n        }\n    }\n\n    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code != ResXMLTree::START_TAG) {\n            continue;\n        }\n        String8 tag(tree.getElementName(&len));\n\n        // If there is no '.', we'll assume that it's one of the built in names.\n        if (strchr(tag.string(), '.')) {\n            addProguardKeepRule(keep, tag, NULL,\n                    layoutFile->getPrintableSource(), tree.getLineNumber());\n        } else if (tagAttrPairs != NULL) {\n            ssize_t tagIndex = tagAttrPairs->indexOfKey(tag);\n            if (tagIndex >= 0) {\n                const Vector<NamespaceAttributePair>& nsAttrVector = tagAttrPairs->valueAt(tagIndex);\n                for (size_t i = 0; i < nsAttrVector.size(); i++) {\n                    const NamespaceAttributePair& nsAttr = nsAttrVector[i];\n\n                    ssize_t attrIndex = tree.indexOfAttribute(nsAttr.ns, nsAttr.attr);\n                    if (attrIndex < 0) {\n                        // fprintf(stderr, \"%s:%d: <%s> does not have attribute %s:%s.\\n\",\n                        //        layoutFile->getPrintableSource().string(), tree.getLineNumber(),\n                        //        tag.string(), nsAttr.ns, nsAttr.attr);\n                    } else {\n                        size_t len;\n                        addProguardKeepRule(keep,\n                                            String8(tree.getAttributeStringValue(attrIndex, &len)), NULL,\n                                            layoutFile->getPrintableSource(), tree.getLineNumber());\n                    }\n                }\n            }\n        }\n        ssize_t attrIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, \"onClick\");\n        if (attrIndex >= 0) {\n            size_t len;\n            addProguardKeepMethodRule(keep,\n                                String8(tree.getAttributeStringValue(attrIndex, &len)), NULL,\n                                layoutFile->getPrintableSource(), tree.getLineNumber());\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatic void addTagAttrPair(KeyedVector<String8, Vector<NamespaceAttributePair> >* dest,\n        const char* tag, const char* ns, const char* attr) {\n    String8 tagStr(tag);\n    ssize_t index = dest->indexOfKey(tagStr);\n\n    if (index < 0) {\n        Vector<NamespaceAttributePair> vector;\n        vector.add(NamespaceAttributePair(ns, attr));\n        dest->add(tagStr, vector);\n    } else {\n        dest->editValueAt(index).add(NamespaceAttributePair(ns, attr));\n    }\n}\n\nstatus_t\nwriteProguardForLayouts(ProguardKeepSet* keep, const sp<AaptAssets>& assets)\n{\n    status_t err;\n    const char* kClass = \"class\";\n    const char* kFragment = \"fragment\";\n    const String8 kTransition(\"transition\");\n    const String8 kTransitionPrefix(\"transition-\");\n\n    // tag:attribute pairs that should be checked in layout files.\n    KeyedVector<String8, Vector<NamespaceAttributePair> > kLayoutTagAttrPairs;\n    addTagAttrPair(&kLayoutTagAttrPairs, \"view\", NULL, kClass);\n    addTagAttrPair(&kLayoutTagAttrPairs, kFragment, NULL, kClass);\n    addTagAttrPair(&kLayoutTagAttrPairs, kFragment, RESOURCES_ANDROID_NAMESPACE, \"name\");\n\n    // tag:attribute pairs that should be checked in xml files.\n    KeyedVector<String8, Vector<NamespaceAttributePair> > kXmlTagAttrPairs;\n    addTagAttrPair(&kXmlTagAttrPairs, \"PreferenceScreen\", RESOURCES_ANDROID_NAMESPACE, kFragment);\n    addTagAttrPair(&kXmlTagAttrPairs, \"header\", RESOURCES_ANDROID_NAMESPACE, kFragment);\n\n    // tag:attribute pairs that should be checked in transition files.\n    KeyedVector<String8, Vector<NamespaceAttributePair> > kTransitionTagAttrPairs;\n    addTagAttrPair(&kTransitionTagAttrPairs, kTransition.string(), NULL, kClass);\n    addTagAttrPair(&kTransitionTagAttrPairs, \"pathMotion\", NULL, kClass);\n\n    const Vector<sp<AaptDir> >& dirs = assets->resDirs();\n    const size_t K = dirs.size();\n    for (size_t k=0; k<K; k++) {\n        const sp<AaptDir>& d = dirs.itemAt(k);\n        const String8& dirName = d->getLeaf();\n        Vector<String8> startTags;\n        const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs = NULL;\n        if ((dirName == String8(\"layout\")) || (strncmp(dirName.string(), \"layout-\", 7) == 0)) {\n            tagAttrPairs = &kLayoutTagAttrPairs;\n        } else if ((dirName == String8(\"xml\")) || (strncmp(dirName.string(), \"xml-\", 4) == 0)) {\n            startTags.add(String8(\"PreferenceScreen\"));\n            startTags.add(String8(\"preference-headers\"));\n            tagAttrPairs = &kXmlTagAttrPairs;\n        } else if ((dirName == String8(\"menu\")) || (strncmp(dirName.string(), \"menu-\", 5) == 0)) {\n            startTags.add(String8(\"menu\"));\n            tagAttrPairs = NULL;\n        } else if (dirName == kTransition || (strncmp(dirName.string(), kTransitionPrefix.string(),\n                        kTransitionPrefix.size()) == 0)) {\n            tagAttrPairs = &kTransitionTagAttrPairs;\n        } else {\n            continue;\n        }\n\n        const KeyedVector<String8,sp<AaptGroup> > groups = d->getFiles();\n        const size_t N = groups.size();\n        for (size_t i=0; i<N; i++) {\n            const sp<AaptGroup>& group = groups.valueAt(i);\n            const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files = group->getFiles();\n            const size_t M = files.size();\n            for (size_t j=0; j<M; j++) {\n                err = writeProguardForXml(keep, files.valueAt(j), startTags, tagAttrPairs);\n                if (err < 0) {\n                    return err;\n                }\n            }\n        }\n    }\n    // Handle the overlays\n    sp<AaptAssets> overlay = assets->getOverlay();\n    if (overlay.get()) {\n        return writeProguardForLayouts(keep, overlay);\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t\nwriteProguardSpec(const char* filename, const ProguardKeepSet& keep, status_t err)\n{\n    FILE* fp = fopen(filename, \"w+\");\n    if (fp == NULL) {\n        fprintf(stderr, \"ERROR: Unable to open class file %s: %s\\n\",\n                filename, strerror(errno));\n        return UNKNOWN_ERROR;\n    }\n\n    const KeyedVector<String8, SortedVector<String8> >& rules = keep.rules;\n    const size_t N = rules.size();\n    for (size_t i=0; i<N; i++) {\n        const SortedVector<String8>& locations = rules.valueAt(i);\n        const size_t M = locations.size();\n        for (size_t j=0; j<M; j++) {\n            fprintf(fp, \"# %s\\n\", locations.itemAt(j).string());\n        }\n        fprintf(fp, \"%s\\n\\n\", rules.keyAt(i).string());\n    }\n    fclose(fp);\n\n    return err;\n}\n\nstatus_t\nwriteProguardFile(Bundle* bundle, const sp<AaptAssets>& assets)\n{\n    status_t err = -1;\n\n    if (!bundle->getProguardFile()) {\n        return NO_ERROR;\n    }\n\n    ProguardKeepSet keep;\n\n    err = writeProguardForAndroidManifest(&keep, assets, false);\n    if (err < 0) {\n        return err;\n    }\n\n    err = writeProguardForLayouts(&keep, assets);\n    if (err < 0) {\n        return err;\n    }\n\n    return writeProguardSpec(bundle->getProguardFile(), keep, err);\n}\n\nstatus_t\nwriteMainDexProguardFile(Bundle* bundle, const sp<AaptAssets>& assets)\n{\n    status_t err = -1;\n\n    if (!bundle->getMainDexProguardFile()) {\n        return NO_ERROR;\n    }\n\n    ProguardKeepSet keep;\n\n    err = writeProguardForAndroidManifest(&keep, assets, true);\n    if (err < 0) {\n        return err;\n    }\n\n    return writeProguardSpec(bundle->getMainDexProguardFile(), keep, err);\n}\n\n// Loops through the string paths and writes them to the file pointer\n// Each file path is written on its own line with a terminating backslash.\nstatus_t writePathsToFile(const sp<FilePathStore>& files, FILE* fp)\n{\n    status_t deps = -1;\n    for (size_t file_i = 0; file_i < files->size(); ++file_i) {\n        // Add the full file path to the dependency file\n        fprintf(fp, \"%s \\\\\\n\", files->itemAt(file_i).string());\n        deps++;\n    }\n    return deps;\n}\n\nstatus_t\nwriteDependencyPreReqs(Bundle* /* bundle */, const sp<AaptAssets>& assets, FILE* fp, bool includeRaw)\n{\n    status_t deps = -1;\n    deps += writePathsToFile(assets->getFullResPaths(), fp);\n    if (includeRaw) {\n        deps += writePathsToFile(assets->getFullAssetPaths(), fp);\n    }\n    return deps;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/ResourceFilter.cpp",
    "content": "//\n// Copyright 2014 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#include \"ResourceFilter.h\"\n#include \"AaptUtil.h\"\n#include \"AaptConfig.h\"\n\nstatus_t\nWeakResourceFilter::parse(const String8& str)\n{\n    Vector<String8> configStrs = AaptUtil::split(str, ',');\n    const size_t N = configStrs.size();\n    mConfigs.clear();\n    mConfigMask = 0;\n    mConfigs.resize(N);\n    for (size_t i = 0; i < N; i++) {\n        const String8& part = configStrs[i];\n        if (part == \"en_XA\") {\n            mContainsPseudoAccented = true;\n        } else if (part == \"ar_XB\") {\n            mContainsPseudoBidi = true;\n        }\n\n        std::pair<ConfigDescription, uint32_t>& entry = mConfigs.editItemAt(i);\n\n        AaptLocaleValue val;\n        if (val.initFromFilterString(part)) {\n            // For backwards compatibility, we accept configurations that\n            // only specify locale in the standard 'en_US' format.\n            val.writeTo(&entry.first);\n        } else if (!AaptConfig::parse(part, &entry.first)) {\n            fprintf(stderr, \"Invalid configuration: %s\\n\", part.string());\n            return UNKNOWN_ERROR;\n        }\n\n        entry.second = mDefault.diff(entry.first);\n\n        // Ignore the version\n        entry.second &= ~ResTable_config::CONFIG_VERSION;\n\n        // Ignore any densities. Those are best handled in --preferred-density\n        if ((entry.second & ResTable_config::CONFIG_DENSITY) != 0) {\n            fprintf(stderr, \"warning: ignoring flag -c %s. Use --preferred-density instead.\\n\", entry.first.toString().string());\n            entry.first.density = 0;\n            entry.second &= ~ResTable_config::CONFIG_DENSITY;\n        }\n\n        mConfigMask |= entry.second;\n    }\n\n    return NO_ERROR;\n}\n\nbool\nWeakResourceFilter::match(const ResTable_config& config) const\n{\n    uint32_t mask = mDefault.diff(config);\n    if ((mConfigMask & mask) == 0) {\n        // The two configurations don't have any common axis.\n        return true;\n    }\n\n    uint32_t matchedAxis = 0x0;\n    const size_t N = mConfigs.size();\n    for (size_t i = 0; i < N; i++) {\n        const std::pair<ConfigDescription, uint32_t>& entry = mConfigs[i];\n        uint32_t diff = entry.first.diff(config);\n        if ((diff & entry.second) == 0) {\n            // Mark the axis that was matched.\n            matchedAxis |= entry.second;\n        } else if ((diff & entry.second) == ResTable_config::CONFIG_LOCALE) {\n            // If the locales differ, but the languages are the same and\n            // the locale we are matching only has a language specified,\n            // we match.\n            if (config.language[0] &&\n                    memcmp(config.language, entry.first.language, sizeof(config.language)) == 0) {\n                if (config.country[0] == 0) {\n                    matchedAxis |= ResTable_config::CONFIG_LOCALE;\n                }\n            }\n        } else if ((diff & entry.second) == ResTable_config::CONFIG_SMALLEST_SCREEN_SIZE) {\n            // Special case if the smallest screen width doesn't match. We check that the\n            // config being matched has a smaller screen width than the filter specified.\n            if (config.smallestScreenWidthDp != 0 &&\n                    config.smallestScreenWidthDp < entry.first.smallestScreenWidthDp) {\n                matchedAxis |= ResTable_config::CONFIG_SMALLEST_SCREEN_SIZE;\n            }\n        }\n    }\n    return matchedAxis == (mConfigMask & mask);\n}\n\nstatus_t\nStrongResourceFilter::parse(const String8& str) {\n    Vector<String8> configStrs = AaptUtil::split(str, ',');\n    ConfigDescription config;\n    mConfigs.clear();\n    for (size_t i = 0; i < configStrs.size(); i++) {\n        if (!AaptConfig::parse(configStrs[i], &config)) {\n            fprintf(stderr, \"Invalid configuration: %s\\n\", configStrs[i].string());\n            return UNKNOWN_ERROR;\n        }\n        mConfigs.insert(config);\n    }\n    return NO_ERROR;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/ResourceFilter.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#ifndef RESOURCE_FILTER_H\n#define RESOURCE_FILTER_H\n\n#include <androidfw/ResourceTypes.h>\n#include <set>\n#include <utility>\n#include <utils/Errors.h>\n#include <utils/String8.h>\n#include <utils/StrongPointer.h>\n#include <utils/Vector.h>\n\n#include \"AaptAssets.h\"\n#include \"ConfigDescription.h\"\n\nclass ResourceFilter : public virtual android::RefBase {\npublic:\n    virtual bool match(const android::ResTable_config& config) const = 0;\n};\n\n/**\n * Implements logic for parsing and handling \"-c\" options.\n */\nclass WeakResourceFilter : public ResourceFilter {\npublic:\n    WeakResourceFilter()\n        : mContainsPseudoAccented(false)\n        , mContainsPseudoBidi(false) {}\n\n    android::status_t parse(const android::String8& str);\n\n    bool match(const android::ResTable_config& config) const;\n\n    inline bool isEmpty() const {\n        return mConfigMask == 0;\n    }\n\n    inline bool containsPseudo() const {\n        return mContainsPseudoAccented;\n    }\n\n    inline bool containsPseudoBidi() const {\n        return mContainsPseudoBidi;\n    }\n\nprivate:\n    ConfigDescription mDefault;\n    uint32_t mConfigMask;\n    android::Vector<std::pair<ConfigDescription, uint32_t> > mConfigs;\n\n    bool mContainsPseudoAccented;\n    bool mContainsPseudoBidi;\n};\n\n/**\n * Matches resources that have at least one of the configurations\n * that this filter is looking for. In order to match a configuration,\n * the resource must have the exact same configuration.\n *\n * This filter acts as a logical OR when matching resources.\n *\n * For example, if the filter is looking for resources with\n * fr-land, de-land, or sw600dp:\n *\n * (PASS) fr-land\n * (FAIL) fr\n * (PASS) de-land\n * (FAIL) de\n * (FAIL) de-sw600dp\n * (PASS) sw600dp\n * (FAIL) sw600dp-land\n */\nclass StrongResourceFilter : public ResourceFilter {\npublic:\n    StrongResourceFilter() {}\n    StrongResourceFilter(const std::set<ConfigDescription>& configs)\n        : mConfigs(configs) {}\n\n    android::status_t parse(const android::String8& str);\n\n    bool match(const android::ResTable_config& config) const {\n        std::set<ConfigDescription>::const_iterator iter = mConfigs.begin();\n        for (; iter != mConfigs.end(); iter++) {\n            if (iter->compare(config) == 0) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    inline const std::set<ConfigDescription>& getConfigs() const {\n        return mConfigs;\n    }\n\nprivate:\n    std::set<ConfigDescription> mConfigs;\n};\n\n/**\n * Negates the response of the target filter.\n */\nclass InverseResourceFilter : public ResourceFilter {\npublic:\n    InverseResourceFilter(const android::sp<ResourceFilter>& filter)\n        : mFilter(filter) {}\n\n    bool match(const android::ResTable_config& config) const {\n        return !mFilter->match(config);\n    }\n\nprivate:\n    const android::sp<ResourceFilter> mFilter;\n};\n\n/**\n * A logical AND of all the added filters.\n */\nclass AndResourceFilter : public ResourceFilter {\npublic:\n    void addFilter(const android::sp<ResourceFilter>& filter) {\n        mFilters.add(filter);\n    }\n\n    bool match(const android::ResTable_config& config) const {\n        const size_t N = mFilters.size();\n        for (size_t i = 0; i < N; i++) {\n            if (!mFilters[i]->match(config)) {\n                return false;\n            }\n        }\n        return true;\n    }\n\nprivate:\n    android::Vector<android::sp<ResourceFilter> > mFilters;\n};\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/ResourceIdCache.cpp",
    "content": "//\n// Copyright 2012 The Android Open Source Project\n//\n// Manage a resource ID cache.\n\n#define LOG_TAG \"ResourceIdCache\"\n\n#include <utils/String16.h>\n#include <utils/Log.h>\n#include \"ResourceIdCache.h\"\n#include <map>\n\nstatic size_t mHits = 0;\nstatic size_t mMisses = 0;\nstatic size_t mCollisions = 0;\n\nstatic const size_t MAX_CACHE_ENTRIES = 2048;\nstatic const android::String16 TRUE16(\"1\");\nstatic const android::String16 FALSE16(\"0\");\n\nstruct CacheEntry {\n    // concatenation of the relevant strings into a single instance\n    android::String16 hashedName;\n    uint32_t id;\n\n    CacheEntry() {}\n    CacheEntry(const android::String16& name, uint32_t resId) : hashedName(name), id(resId) { }\n};\n\nstatic std::map< uint32_t, CacheEntry > mIdMap;\n\n\n// djb2; reasonable choice for strings when collisions aren't particularly important\nstatic inline uint32_t hashround(uint32_t hash, int c) {\n    return ((hash << 5) + hash) + c;    /* hash * 33 + c */\n}\n\nstatic uint32_t hash(const android::String16& hashableString) {\n    uint32_t hash = 5381;\n    const char16_t* str = hashableString.string();\n    while (int c = *str++) hash = hashround(hash, c);\n    return hash;\n}\n\nnamespace android {\n\nstatic inline String16 makeHashableName(const android::String16& package,\n        const android::String16& type,\n        const android::String16& name,\n        bool onlyPublic) {\n    String16 hashable = String16(name);\n    hashable += type;\n    hashable += package;\n    hashable += (onlyPublic ? TRUE16 : FALSE16);\n    return hashable;\n}\n\nuint32_t ResourceIdCache::lookup(const android::String16& package,\n        const android::String16& type,\n        const android::String16& name,\n        bool onlyPublic) {\n    const String16 hashedName = makeHashableName(package, type, name, onlyPublic);\n    const uint32_t hashcode = hash(hashedName);\n    std::map<uint32_t, CacheEntry>::iterator item = mIdMap.find(hashcode);\n    if (item == mIdMap.end()) {\n        // cache miss\n        mMisses++;\n        return 0;\n    }\n\n    // legit match?\n    if (hashedName == (*item).second.hashedName) {\n        mHits++;\n        return (*item).second.id;\n    }\n\n    // collision\n    mCollisions++;\n    mIdMap.erase(hashcode);\n    return 0;\n}\n\n// returns the resource ID being stored, for callsite convenience\nuint32_t ResourceIdCache::store(const android::String16& package,\n        const android::String16& type,\n        const android::String16& name,\n        bool onlyPublic,\n        uint32_t resId) {\n    if (mIdMap.size() < MAX_CACHE_ENTRIES) {\n        const String16 hashedName = makeHashableName(package, type, name, onlyPublic);\n        const uint32_t hashcode = hash(hashedName);\n        mIdMap[hashcode] = CacheEntry(hashedName, resId);\n    }\n    return resId;\n}\n\nvoid ResourceIdCache::dump() {\n    printf(\"ResourceIdCache dump:\\n\");\n    printf(\"Size: %zd\\n\", mIdMap.size());\n    printf(\"Hits:   %zd\\n\", mHits);\n    printf(\"Misses: %zd\\n\", mMisses);\n    printf(\"(Collisions: %zd)\\n\", mCollisions);\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/ResourceIdCache.h",
    "content": "//\n// Copyright 2012 The Android Open Source Project\n//\n// Manage a resource ID cache.\n\n#ifndef RESOURCE_ID_CACHE_H\n#define RESOURCE_ID_CACHE_H\n\n#include <utils/String16.h>\n\nnamespace android {\n\nclass ResourceIdCache {\npublic:\n    static uint32_t lookup(const String16& package,\n            const String16& type,\n            const String16& name,\n            bool onlyPublic);\n\n    static uint32_t store(const String16& package,\n            const String16& type,\n            const String16& name,\n            bool onlyPublic,\n            uint32_t resId);\n\n    static void dump(void);\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/ResourceTable.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#include \"ResourceTable.h\"\n\n#include \"AaptUtil.h\"\n#include \"XMLNode.h\"\n#include \"ResourceFilter.h\"\n#include \"ResourceIdCache.h\"\n#include \"SdkConstants.h\"\n\n#include <algorithm>\n#include <androidfw/ResourcePackageId.h>\n#include <androidfw/ResourceTypes.h>\n#include <utils/ByteOrder.h>\n#include <utils/TypeHelpers.h>\n#include <utils/Log.h>\n#include <stdarg.h>\n\n// SSIZE: mingw does not have signed size_t == ssize_t.\n// STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary.\n#if !defined(_WIN32)\n#  define SSIZE(x) x\n#  define STATUST(x) x\n#else\n#  define SSIZE(x) (signed size_t)x\n#  define STATUST(x) (status_t)x\n#endif\n\n// Set to true for noisy debug output.\nstatic const bool kIsDebug = false;\n\n#if PRINT_STRING_METRICS\nstatic const bool kPrintStringMetrics = true;\n#else\nstatic const bool kPrintStringMetrics = false;\n#endif\n\nstatic const char* kAttrPrivateType = \"^attr-private\";\n\nstatus_t compileXmlFile(const Bundle* bundle,\n                        const sp<AaptAssets>& assets,\n                        const String16& resourceName,\n                        const sp<AaptFile>& target,\n                        ResourceTable* table,\n                        int options)\n{\n    sp<XMLNode> root = XMLNode::parse(target);\n    if (root == NULL) {\n        return UNKNOWN_ERROR;\n    }\n\n    return compileXmlFile(bundle, assets, resourceName, root, target, table, options);\n}\n\nstatus_t compileXmlFile(const Bundle* bundle,\n                        const sp<AaptAssets>& assets,\n                        const String16& resourceName,\n                        const sp<AaptFile>& target,\n                        const sp<AaptFile>& outTarget,\n                        ResourceTable* table,\n                        int options)\n{\n    sp<XMLNode> root = XMLNode::parse(target);\n    if (root == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    \n    return compileXmlFile(bundle, assets, resourceName, root, outTarget, table, options);\n}\n\nstatus_t compileXmlFile(const Bundle* bundle,\n                        const sp<AaptAssets>& assets,\n                        const String16& resourceName,\n                        const sp<XMLNode>& root,\n                        const sp<AaptFile>& target,\n                        ResourceTable* table,\n                        int options)\n{\n    if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) {\n        root->removeWhitespace(true, NULL);\n    } else  if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) {\n        root->removeWhitespace(false, NULL);\n    }\n\n    if ((options&XML_COMPILE_UTF8) != 0) {\n        root->setUTF8(true);\n    }\n\n    if (table->processBundleFormat(bundle, resourceName, target, root) != NO_ERROR) {\n        return UNKNOWN_ERROR;\n    }\n    \n    bool hasErrors = false;\n    if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) {\n        status_t err = root->assignResourceIds(assets, table, bundle);\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if ((options&XML_COMPILE_PARSE_VALUES) != 0) {\n        status_t err = root->parseValues(assets, table, bundle);\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (hasErrors) {\n        return UNKNOWN_ERROR;\n    }\n\n    if (table->modifyForCompat(bundle, resourceName, target, root) != NO_ERROR) {\n        return UNKNOWN_ERROR;\n    }\n\n    if (kIsDebug) {\n        printf(\"Input XML Resource:\\n\");\n        root->print();\n    }\n    status_t err = root->flatten(target,\n            (options&XML_COMPILE_STRIP_COMMENTS) != 0,\n            (options&XML_COMPILE_STRIP_RAW_VALUES) != 0);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    if (kIsDebug) {\n        printf(\"Output XML Resource:\\n\");\n        ResXMLTree tree;\n        tree.setTo(target->getData(), target->getSize());\n        printXMLBlock(&tree);\n    }\n\n    target->setCompressionMethod(ZipEntry::kCompressDeflated);\n    \n    return err;\n}\n\nstruct flag_entry\n{\n    const char16_t* name;\n    size_t nameLen;\n    uint32_t value;\n    const char* description;\n};\n\nstatic const char16_t referenceArray[] =\n    { 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e' };\nstatic const char16_t stringArray[] =\n    { 's', 't', 'r', 'i', 'n', 'g' };\nstatic const char16_t integerArray[] =\n    { 'i', 'n', 't', 'e', 'g', 'e', 'r' };\nstatic const char16_t booleanArray[] =\n    { 'b', 'o', 'o', 'l', 'e', 'a', 'n' };\nstatic const char16_t colorArray[] =\n    { 'c', 'o', 'l', 'o', 'r' };\nstatic const char16_t floatArray[] =\n    { 'f', 'l', 'o', 'a', 't' };\nstatic const char16_t dimensionArray[] =\n    { 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n' };\nstatic const char16_t fractionArray[] =\n    { 'f', 'r', 'a', 'c', 't', 'i', 'o', 'n' };\nstatic const char16_t enumArray[] =\n    { 'e', 'n', 'u', 'm' };\nstatic const char16_t flagsArray[] =\n    { 'f', 'l', 'a', 'g', 's' };\n\nstatic const flag_entry gFormatFlags[] = {\n    { referenceArray, sizeof(referenceArray)/2, ResTable_map::TYPE_REFERENCE,\n      \"a reference to another resource, in the form \\\"<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>\\\"\\n\"\n      \"or to a theme attribute in the form \\\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\\\".\"},\n    { stringArray, sizeof(stringArray)/2, ResTable_map::TYPE_STRING,\n      \"a string value, using '\\\\\\\\;' to escape characters such as '\\\\\\\\n' or '\\\\\\\\uxxxx' for a unicode character.\" },\n    { integerArray, sizeof(integerArray)/2, ResTable_map::TYPE_INTEGER,\n      \"an integer value, such as \\\"<code>100</code>\\\".\" },\n    { booleanArray, sizeof(booleanArray)/2, ResTable_map::TYPE_BOOLEAN,\n      \"a boolean value, either \\\"<code>true</code>\\\" or \\\"<code>false</code>\\\".\" },\n    { colorArray, sizeof(colorArray)/2, ResTable_map::TYPE_COLOR,\n      \"a color value, in the form of \\\"<code>#<i>rgb</i></code>\\\", \\\"<code>#<i>argb</i></code>\\\",\\n\"\n      \"\\\"<code>#<i>rrggbb</i></code>\\\", or \\\"<code>#<i>aarrggbb</i></code>\\\".\" },\n    { floatArray, sizeof(floatArray)/2, ResTable_map::TYPE_FLOAT,\n      \"a floating point value, such as \\\"<code>1.2</code>\\\".\"},\n    { dimensionArray, sizeof(dimensionArray)/2, ResTable_map::TYPE_DIMENSION,\n      \"a dimension value, which is a floating point number appended with a unit such as \\\"<code>14.5sp</code>\\\".\\n\"\n      \"Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),\\n\"\n      \"in (inches), mm (millimeters).\" },\n    { fractionArray, sizeof(fractionArray)/2, ResTable_map::TYPE_FRACTION,\n      \"a fractional value, which is a floating point number appended with either % or %p, such as \\\"<code>14.5%</code>\\\".\\n\"\n      \"The % suffix always means a percentage of the base size; the optional %p suffix provides a size relative to\\n\"\n      \"some parent container.\" },\n    { enumArray, sizeof(enumArray)/2, ResTable_map::TYPE_ENUM, NULL },\n    { flagsArray, sizeof(flagsArray)/2, ResTable_map::TYPE_FLAGS, NULL },\n    { NULL, 0, 0, NULL }\n};\n\nstatic const char16_t suggestedArray[] = { 's', 'u', 'g', 'g', 'e', 's', 't', 'e', 'd' };\n\nstatic const flag_entry l10nRequiredFlags[] = {\n    { suggestedArray, sizeof(suggestedArray)/2, ResTable_map::L10N_SUGGESTED, NULL },\n    { NULL, 0, 0, NULL }\n};\n\nstatic const char16_t nulStr[] = { 0 };\n\nstatic uint32_t parse_flags(const char16_t* str, size_t len,\n                             const flag_entry* flags, bool* outError = NULL)\n{\n    while (len > 0 && isspace(*str)) {\n        str++;\n        len--;\n    }\n    while (len > 0 && isspace(str[len-1])) {\n        len--;\n    }\n\n    const char16_t* const end = str + len;\n    uint32_t value = 0;\n\n    while (str < end) {\n        const char16_t* div = str;\n        while (div < end && *div != '|') {\n            div++;\n        }\n\n        const flag_entry* cur = flags;\n        while (cur->name) {\n            if (strzcmp16(cur->name, cur->nameLen, str, div-str) == 0) {\n                value |= cur->value;\n                break;\n            }\n            cur++;\n        }\n\n        if (!cur->name) {\n            if (outError) *outError = true;\n            return 0;\n        }\n\n        str = div < end ? div+1 : div;\n    }\n\n    if (outError) *outError = false;\n    return value;\n}\n\nstatic String16 mayOrMust(int type, int flags)\n{\n    if ((type&(~flags)) == 0) {\n        return String16(\"<p>Must\");\n    }\n    \n    return String16(\"<p>May\");\n}\n\nstatic void appendTypeInfo(ResourceTable* outTable, const String16& pkg,\n        const String16& typeName, const String16& ident, int type,\n        const flag_entry* flags)\n{\n    bool hadType = false;\n    while (flags->name) {\n        if ((type&flags->value) != 0 && flags->description != NULL) {\n            String16 fullMsg(mayOrMust(type, flags->value));\n            fullMsg.append(String16(\" be \"));\n            fullMsg.append(String16(flags->description));\n            outTable->appendTypeComment(pkg, typeName, ident, fullMsg);\n            hadType = true;\n        }\n        flags++;\n    }\n    if (hadType && (type&ResTable_map::TYPE_REFERENCE) == 0) {\n        outTable->appendTypeComment(pkg, typeName, ident,\n                String16(\"<p>This may also be a reference to a resource (in the form\\n\"\n                         \"\\\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\\\") or\\n\"\n                         \"theme attribute (in the form\\n\"\n                         \"\\\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\\\")\\n\"\n                         \"containing a value of this type.\"));\n    }\n}\n\nstruct PendingAttribute\n{\n    const String16 myPackage;\n    const SourcePos sourcePos;\n    const bool appendComment;\n    int32_t type;\n    String16 ident;\n    String16 comment;\n    bool hasErrors;\n    bool added;\n    \n    PendingAttribute(String16 _package, const sp<AaptFile>& in,\n            ResXMLTree& block, bool _appendComment)\n        : myPackage(_package)\n        , sourcePos(in->getPrintableSource(), block.getLineNumber())\n        , appendComment(_appendComment)\n        , type(ResTable_map::TYPE_ANY)\n        , hasErrors(false)\n        , added(false)\n    {\n    }\n    \n    status_t createIfNeeded(ResourceTable* outTable)\n    {\n        if (added || hasErrors) {\n            return NO_ERROR;\n        }\n        added = true;\n\n        if (!outTable->makeAttribute(myPackage, ident, sourcePos, type, comment, appendComment)) {\n            hasErrors = true;\n            return UNKNOWN_ERROR;\n        }\n        return NO_ERROR;\n    }\n};\n\nstatic status_t compileAttribute(const sp<AaptFile>& in,\n                                 ResXMLTree& block,\n                                 const String16& myPackage,\n                                 ResourceTable* outTable,\n                                 String16* outIdent = NULL,\n                                 bool inStyleable = false)\n{\n    PendingAttribute attr(myPackage, in, block, inStyleable);\n    \n    const String16 attr16(\"attr\");\n    const String16 id16(\"id\");\n\n    // Attribute type constants.\n    const String16 enum16(\"enum\");\n    const String16 flag16(\"flag\");\n\n    ResXMLTree::event_code_t code;\n    size_t len;\n    status_t err;\n    \n    ssize_t identIdx = block.indexOfAttribute(NULL, \"name\");\n    if (identIdx >= 0) {\n        attr.ident = String16(block.getAttributeStringValue(identIdx, &len));\n        if (outIdent) {\n            *outIdent = attr.ident;\n        }\n    } else {\n        attr.sourcePos.error(\"A 'name' attribute is required for <attr>\\n\");\n        attr.hasErrors = true;\n    }\n\n    attr.comment = String16(\n            block.getComment(&len) ? block.getComment(&len) : nulStr);\n\n    ssize_t typeIdx = block.indexOfAttribute(NULL, \"format\");\n    if (typeIdx >= 0) {\n        String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len));\n        attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags);\n        if (attr.type == 0) {\n            attr.sourcePos.error(\"Tag <attr> 'format' attribute value \\\"%s\\\" not valid\\n\",\n                    String8(typeStr).string());\n            attr.hasErrors = true;\n        }\n        attr.createIfNeeded(outTable);\n    } else if (!inStyleable) {\n        // Attribute definitions outside of styleables always define the\n        // attribute as a generic value.\n        attr.createIfNeeded(outTable);\n    }\n\n    //printf(\"Attribute %s: type=0x%08x\\n\", String8(attr.ident).string(), attr.type);\n\n    ssize_t minIdx = block.indexOfAttribute(NULL, \"min\");\n    if (minIdx >= 0) {\n        String16 val = String16(block.getAttributeStringValue(minIdx, &len));\n        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {\n            attr.sourcePos.error(\"Tag <attr> 'min' attribute must be a number, not \\\"%s\\\"\\n\",\n                    String8(val).string());\n            attr.hasErrors = true;\n        }\n        attr.createIfNeeded(outTable);\n        if (!attr.hasErrors) {\n            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,\n                    String16(\"\"), String16(\"^min\"), String16(val), NULL, NULL);\n            if (err != NO_ERROR) {\n                attr.hasErrors = true;\n            }\n        }\n    }\n\n    ssize_t maxIdx = block.indexOfAttribute(NULL, \"max\");\n    if (maxIdx >= 0) {\n        String16 val = String16(block.getAttributeStringValue(maxIdx, &len));\n        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {\n            attr.sourcePos.error(\"Tag <attr> 'max' attribute must be a number, not \\\"%s\\\"\\n\",\n                    String8(val).string());\n            attr.hasErrors = true;\n        }\n        attr.createIfNeeded(outTable);\n        if (!attr.hasErrors) {\n            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,\n                    String16(\"\"), String16(\"^max\"), String16(val), NULL, NULL);\n            attr.hasErrors = true;\n        }\n    }\n\n    if ((minIdx >= 0 || maxIdx >= 0) && (attr.type&ResTable_map::TYPE_INTEGER) == 0) {\n        attr.sourcePos.error(\"Tag <attr> must have format=integer attribute if using max or min\\n\");\n        attr.hasErrors = true;\n    }\n\n    ssize_t l10nIdx = block.indexOfAttribute(NULL, \"localization\");\n    if (l10nIdx >= 0) {\n        const char16_t* str = block.getAttributeStringValue(l10nIdx, &len);\n        bool error;\n        uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error);\n        if (error) {\n            attr.sourcePos.error(\"Tag <attr> 'localization' attribute value \\\"%s\\\" not valid\\n\",\n                    String8(str).string());\n            attr.hasErrors = true;\n        }\n        attr.createIfNeeded(outTable);\n        if (!attr.hasErrors) {\n            char buf[11];\n            sprintf(buf, \"%d\", l10n_required);\n            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,\n                    String16(\"\"), String16(\"^l10n\"), String16(buf), NULL, NULL);\n            if (err != NO_ERROR) {\n                attr.hasErrors = true;\n            }\n        }\n    }\n\n    String16 enumOrFlagsComment;\n    \n    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::START_TAG) {\n            uint32_t localType = 0;\n            if (strcmp16(block.getElementName(&len), enum16.string()) == 0) {\n                localType = ResTable_map::TYPE_ENUM;\n            } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) {\n                localType = ResTable_map::TYPE_FLAGS;\n            } else {\n                SourcePos(in->getPrintableSource(), block.getLineNumber())\n                        .error(\"Tag <%s> can not appear inside <attr>, only <enum> or <flag>\\n\",\n                        String8(block.getElementName(&len)).string());\n                return UNKNOWN_ERROR;\n            }\n\n            attr.createIfNeeded(outTable);\n            \n            if (attr.type == ResTable_map::TYPE_ANY) {\n                // No type was explicitly stated, so supplying enum tags\n                // implicitly creates an enum or flag.\n                attr.type = 0;\n            }\n\n            if ((attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) == 0) {\n                // Wasn't originally specified as an enum, so update its type.\n                attr.type |= localType;\n                if (!attr.hasErrors) {\n                    char numberStr[16];\n                    sprintf(numberStr, \"%d\", attr.type);\n                    err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),\n                            myPackage, attr16, attr.ident, String16(\"\"),\n                            String16(\"^type\"), String16(numberStr), NULL, NULL, true);\n                    if (err != NO_ERROR) {\n                        attr.hasErrors = true;\n                    }\n                }\n            } else if ((uint32_t)(attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) != localType) {\n                if (localType == ResTable_map::TYPE_ENUM) {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber())\n                            .error(\"<enum> attribute can not be used inside a flags format\\n\");\n                    attr.hasErrors = true;\n                } else {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber())\n                            .error(\"<flag> attribute can not be used inside a enum format\\n\");\n                    attr.hasErrors = true;\n                }\n            }\n\n            String16 itemIdent;\n            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, \"name\");\n            if (itemIdentIdx >= 0) {\n                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));\n            } else {\n                SourcePos(in->getPrintableSource(), block.getLineNumber())\n                        .error(\"A 'name' attribute is required for <enum> or <flag>\\n\");\n                attr.hasErrors = true;\n            }\n\n            String16 value;\n            ssize_t valueIdx = block.indexOfAttribute(NULL, \"value\");\n            if (valueIdx >= 0) {\n                value = String16(block.getAttributeStringValue(valueIdx, &len));\n            } else {\n                SourcePos(in->getPrintableSource(), block.getLineNumber())\n                        .error(\"A 'value' attribute is required for <enum> or <flag>\\n\");\n                attr.hasErrors = true;\n            }\n            if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) {\n                SourcePos(in->getPrintableSource(), block.getLineNumber())\n                        .error(\"Tag <enum> or <flag> 'value' attribute must be a number,\"\n                        \" not \\\"%s\\\"\\n\",\n                        String8(value).string());\n                attr.hasErrors = true;\n            }\n\n            if (!attr.hasErrors) {\n                if (enumOrFlagsComment.size() == 0) {\n                    enumOrFlagsComment.append(mayOrMust(attr.type,\n                            ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS));\n                    enumOrFlagsComment.append((attr.type&ResTable_map::TYPE_ENUM)\n                                       ? String16(\" be one of the following constant values.\")\n                                       : String16(\" be one or more (separated by '|') of the following constant values.\"));\n                    enumOrFlagsComment.append(String16(\"</p>\\n<table>\\n\"\n                                                \"<colgroup align=\\\"left\\\" />\\n\"\n                                                \"<colgroup align=\\\"left\\\" />\\n\"\n                                                \"<colgroup align=\\\"left\\\" />\\n\"\n                                                \"<tr><th>Constant</th><th>Value</th><th>Description</th></tr>\"));\n                }\n                \n                enumOrFlagsComment.append(String16(\"\\n<tr><td><code>\"));\n                enumOrFlagsComment.append(itemIdent);\n                enumOrFlagsComment.append(String16(\"</code></td><td>\"));\n                enumOrFlagsComment.append(value);\n                enumOrFlagsComment.append(String16(\"</td><td>\"));\n                if (block.getComment(&len)) {\n                    enumOrFlagsComment.append(String16(block.getComment(&len)));\n                }\n                enumOrFlagsComment.append(String16(\"</td></tr>\"));\n                \n                err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),\n                                       myPackage,\n                                       attr16, attr.ident, String16(\"\"),\n                                       itemIdent, value, NULL, NULL, false, true);\n                if (err != NO_ERROR) {\n                    attr.hasErrors = true;\n                }\n            }\n        } else if (code == ResXMLTree::END_TAG) {\n            if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {\n                break;\n            }\n            if ((attr.type&ResTable_map::TYPE_ENUM) != 0) {\n                if (strcmp16(block.getElementName(&len), enum16.string()) != 0) {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber())\n                            .error(\"Found tag </%s> where </enum> is expected\\n\",\n                            String8(block.getElementName(&len)).string());\n                    return UNKNOWN_ERROR;\n                }\n            } else {\n                if (strcmp16(block.getElementName(&len), flag16.string()) != 0) {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber())\n                            .error(\"Found tag </%s> where </flag> is expected\\n\",\n                            String8(block.getElementName(&len)).string());\n                    return UNKNOWN_ERROR;\n                }\n            }\n        }\n    }\n    \n    if (!attr.hasErrors && attr.added) {\n        appendTypeInfo(outTable, myPackage, attr16, attr.ident, attr.type, gFormatFlags);\n    }\n    \n    if (!attr.hasErrors && enumOrFlagsComment.size() > 0) {\n        enumOrFlagsComment.append(String16(\"\\n</table>\"));\n        outTable->appendTypeComment(myPackage, attr16, attr.ident, enumOrFlagsComment);\n    }\n\n\n    return NO_ERROR;\n}\n\nbool localeIsDefined(const ResTable_config& config)\n{\n    return config.locale == 0;\n}\n\nstatus_t parseAndAddBag(Bundle* bundle,\n                        const sp<AaptFile>& in,\n                        ResXMLTree* block,\n                        const ResTable_config& config,\n                        const String16& myPackage,\n                        const String16& curType,\n                        const String16& ident,\n                        const String16& parentIdent,\n                        const String16& itemIdent,\n                        int32_t curFormat,\n                        bool isFormatted,\n                        const String16& /* product */,\n                        PseudolocalizationMethod pseudolocalize,\n                        const bool overwrite,\n                        ResourceTable* outTable)\n{\n    status_t err;\n    const String16 item16(\"item\");\n\n    String16 str;\n    Vector<StringPool::entry_style_span> spans;\n    err = parseStyledString(bundle, in->getPrintableSource().string(),\n                            block, item16, &str, &spans, isFormatted,\n                            pseudolocalize);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    if (kIsDebug) {\n        printf(\"Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d \"\n                \" pid=%s, bag=%s, id=%s: %s\\n\",\n                config.language[0], config.language[1],\n                config.country[0], config.country[1],\n                config.orientation, config.density,\n                String8(parentIdent).string(),\n                String8(ident).string(),\n                String8(itemIdent).string(),\n                String8(str).string());\n    }\n\n    err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()),\n                           myPackage, curType, ident, parentIdent, itemIdent, str,\n                           &spans, &config, overwrite, false, curFormat);\n    return err;\n}\n\n/*\n * Returns true if needle is one of the elements in the comma-separated list\n * haystack, false otherwise.\n */\nbool isInProductList(const String16& needle, const String16& haystack) {\n    const char16_t *needle2 = needle.string();\n    const char16_t *haystack2 = haystack.string();\n    size_t needlesize = needle.size();\n\n    while (*haystack2 != '\\0') {\n        if (strncmp16(haystack2, needle2, needlesize) == 0) {\n            if (haystack2[needlesize] == '\\0' || haystack2[needlesize] == ',') {\n                return true;\n            }\n        }\n\n        while (*haystack2 != '\\0' && *haystack2 != ',') {\n            haystack2++;\n        }\n        if (*haystack2 == ',') {\n            haystack2++;\n        }\n    }\n\n    return false;\n}\n\n/*\n * A simple container that holds a resource type and name. It is ordered first by type then\n * by name.\n */\nstruct type_ident_pair_t {\n    String16 type;\n    String16 ident;\n\n    type_ident_pair_t() { };\n    type_ident_pair_t(const String16& t, const String16& i) : type(t), ident(i) { }\n    type_ident_pair_t(const type_ident_pair_t& o) : type(o.type), ident(o.ident) { }\n    inline bool operator < (const type_ident_pair_t& o) const {\n        int cmp = compare_type(type, o.type);\n        if (cmp < 0) {\n            return true;\n        } else if (cmp > 0) {\n            return false;\n        } else {\n            return strictly_order_type(ident, o.ident);\n        }\n    }\n};\n\n\nstatus_t parseAndAddEntry(Bundle* bundle,\n                        const sp<AaptFile>& in,\n                        ResXMLTree* block,\n                        const ResTable_config& config,\n                        const String16& myPackage,\n                        const String16& curType,\n                        const String16& ident,\n                        const String16& curTag,\n                        bool curIsStyled,\n                        int32_t curFormat,\n                        bool isFormatted,\n                        const String16& product,\n                        PseudolocalizationMethod pseudolocalize,\n                        const bool overwrite,\n                        KeyedVector<type_ident_pair_t, bool>* skippedResourceNames,\n                        ResourceTable* outTable)\n{\n    status_t err;\n\n    String16 str;\n    Vector<StringPool::entry_style_span> spans;\n    err = parseStyledString(bundle, in->getPrintableSource().string(), block,\n                            curTag, &str, curIsStyled ? &spans : NULL,\n                            isFormatted, pseudolocalize);\n\n    if (err < NO_ERROR) { \n        return err;\n    }\n\n    /*\n     * If a product type was specified on the command line\n     * and also in the string, and the two are not the same,\n     * return without adding the string.\n     */\n\n    const char *bundleProduct = bundle->getProduct();\n    if (bundleProduct == NULL) {\n        bundleProduct = \"\";\n    }\n\n    if (product.size() != 0) {\n        /*\n         * If the command-line-specified product is empty, only \"default\"\n         * matches.  Other variants are skipped.  This is so generation\n         * of the R.java file when the product is not known is predictable.\n         */\n\n        if (bundleProduct[0] == '\\0') {\n            if (strcmp16(String16(\"default\").string(), product.string()) != 0) {\n                /*\n                 * This string has a product other than 'default'. Do not add it,\n                 * but record it so that if we do not see the same string with\n                 * product 'default' or no product, then report an error.\n                 */\n                skippedResourceNames->replaceValueFor(\n                        type_ident_pair_t(curType, ident), true);\n                return NO_ERROR;\n            }\n        } else {\n            /*\n             * The command-line product is not empty.\n             * If the product for this string is on the command-line list,\n             * it matches.  \"default\" also matches, but only if nothing\n             * else has matched already.\n             */\n\n            if (isInProductList(product, String16(bundleProduct))) {\n                ;\n            } else if (strcmp16(String16(\"default\").string(), product.string()) == 0 &&\n                       !outTable->hasBagOrEntry(myPackage, curType, ident, config)) {\n                ;\n            } else {\n                return NO_ERROR;\n            }\n        }\n    }\n\n    if (kIsDebug) {\n        printf(\"Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\\n\",\n                config.language[0], config.language[1],\n                config.country[0], config.country[1],\n                config.orientation, config.density,\n                String8(ident).string(), String8(str).string());\n    }\n\n    err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()),\n                             myPackage, curType, ident, str, &spans, &config,\n                             false, curFormat, overwrite);\n\n    return err;\n}\n\nstatus_t compileResourceFile(Bundle* bundle,\n                             const sp<AaptAssets>& assets,\n                             const sp<AaptFile>& in,\n                             const ResTable_config& defParams,\n                             const bool overwrite,\n                             ResourceTable* outTable)\n{\n    ResXMLTree block;\n    status_t err = parseXMLResource(in, &block, false, true);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    // Top-level tag.\n    const String16 resources16(\"resources\");\n\n    // Identifier declaration tags.\n    const String16 declare_styleable16(\"declare-styleable\");\n    const String16 attr16(\"attr\");\n\n    // Data creation organizational tags.\n    const String16 string16(\"string\");\n    const String16 drawable16(\"drawable\");\n    const String16 color16(\"color\");\n    const String16 bool16(\"bool\");\n    const String16 integer16(\"integer\");\n    const String16 dimen16(\"dimen\");\n    const String16 fraction16(\"fraction\");\n    const String16 style16(\"style\");\n    const String16 plurals16(\"plurals\");\n    const String16 array16(\"array\");\n    const String16 string_array16(\"string-array\");\n    const String16 integer_array16(\"integer-array\");\n    const String16 public16(\"public\");\n    const String16 public_padding16(\"public-padding\");\n    const String16 private_symbols16(\"private-symbols\");\n    const String16 java_symbol16(\"java-symbol\");\n    const String16 add_resource16(\"add-resource\");\n    const String16 skip16(\"skip\");\n    const String16 eat_comment16(\"eat-comment\");\n\n    // Data creation tags.\n    const String16 bag16(\"bag\");\n    const String16 item16(\"item\");\n\n    // Attribute type constants.\n    const String16 enum16(\"enum\");\n\n    // plural values\n    const String16 other16(\"other\");\n    const String16 quantityOther16(\"^other\");\n    const String16 zero16(\"zero\");\n    const String16 quantityZero16(\"^zero\");\n    const String16 one16(\"one\");\n    const String16 quantityOne16(\"^one\");\n    const String16 two16(\"two\");\n    const String16 quantityTwo16(\"^two\");\n    const String16 few16(\"few\");\n    const String16 quantityFew16(\"^few\");\n    const String16 many16(\"many\");\n    const String16 quantityMany16(\"^many\");\n\n    // useful attribute names and special values\n    const String16 name16(\"name\");\n    const String16 translatable16(\"translatable\");\n    const String16 formatted16(\"formatted\");\n    const String16 false16(\"false\");\n\n    const String16 myPackage(assets->getPackage());\n\n    bool hasErrors = false;\n\n    bool fileIsTranslatable = true;\n    if (strstr(in->getPrintableSource().string(), \"donottranslate\") != NULL) {\n        fileIsTranslatable = false;\n    }\n\n    DefaultKeyedVector<String16, uint32_t> nextPublicId(0);\n\n    // Stores the resource names that were skipped. Typically this happens when\n    // AAPT is invoked without a product specified and a resource has no\n    // 'default' product attribute.\n    KeyedVector<type_ident_pair_t, bool> skippedResourceNames;\n\n    ResXMLTree::event_code_t code;\n    do {\n        code = block.next();\n    } while (code == ResXMLTree::START_NAMESPACE);\n\n    size_t len;\n    if (code != ResXMLTree::START_TAG) {\n        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                \"No start tag found\\n\");\n        return UNKNOWN_ERROR;\n    }\n    if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {\n        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                \"Invalid start tag %s\\n\", String8(block.getElementName(&len)).string());\n        return UNKNOWN_ERROR;\n    }\n\n    ResTable_config curParams(defParams);\n\n    ResTable_config pseudoParams(curParams);\n        pseudoParams.language[0] = 'e';\n        pseudoParams.language[1] = 'n';\n        pseudoParams.country[0] = 'X';\n        pseudoParams.country[1] = 'A';\n\n    ResTable_config pseudoBidiParams(curParams);\n        pseudoBidiParams.language[0] = 'a';\n        pseudoBidiParams.language[1] = 'r';\n        pseudoBidiParams.country[0] = 'X';\n        pseudoBidiParams.country[1] = 'B';\n\n    // We should skip resources for pseudolocales if they were\n    // already added automatically. This is a fix for a transition period when\n    // manually pseudolocalized resources may be expected.\n    // TODO: remove this check after next SDK version release.\n    if ((bundle->getPseudolocalize() & PSEUDO_ACCENTED &&\n         curParams.locale == pseudoParams.locale) ||\n        (bundle->getPseudolocalize() & PSEUDO_BIDI &&\n         curParams.locale == pseudoBidiParams.locale)) {\n        SourcePos(in->getPrintableSource(), 0).warning(\n                \"Resource file %s is skipped as pseudolocalization\"\n                \" was done automatically.\",\n                in->getPrintableSource().string());\n        return NO_ERROR;\n    }\n\n    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::START_TAG) {\n            const String16* curTag = NULL;\n            String16 curType;\n            String16 curName;\n            int32_t curFormat = ResTable_map::TYPE_ANY;\n            bool curIsBag = false;\n            bool curIsBagReplaceOnOverwrite = false;\n            bool curIsStyled = false;\n            bool curIsPseudolocalizable = false;\n            bool curIsFormatted = fileIsTranslatable;\n            bool localHasErrors = false;\n\n            if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n                        && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {\n                            break;\n                        }\n                    }\n                }\n                continue;\n\n            } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n                        && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {\n                            break;\n                        }\n                    }\n                }\n                continue;\n\n            } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) {\n                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());\n            \n                String16 type;\n                ssize_t typeIdx = block.indexOfAttribute(NULL, \"type\");\n                if (typeIdx < 0) {\n                    srcPos.error(\"A 'type' attribute is required for <public>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                type = String16(block.getAttributeStringValue(typeIdx, &len));\n\n                String16 name;\n                ssize_t nameIdx = block.indexOfAttribute(NULL, \"name\");\n                if (nameIdx < 0) {\n                    srcPos.error(\"A 'name' attribute is required for <public>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                name = String16(block.getAttributeStringValue(nameIdx, &len));\n\n                uint32_t ident = 0;\n                ssize_t identIdx = block.indexOfAttribute(NULL, \"id\");\n                if (identIdx >= 0) {\n                    const char16_t* identStr = block.getAttributeStringValue(identIdx, &len);\n                    Res_value identValue;\n                    if (!ResTable::stringToInt(identStr, len, &identValue)) {\n                        srcPos.error(\"Given 'id' attribute is not an integer: %s\\n\",\n                                String8(block.getAttributeStringValue(identIdx, &len)).string());\n                        hasErrors = localHasErrors = true;\n                    } else {\n                        ident = identValue.data;\n                        nextPublicId.replaceValueFor(type, ident+1);\n                    }\n                } else if (nextPublicId.indexOfKey(type) < 0) {\n                    srcPos.error(\"No 'id' attribute supplied <public>,\"\n                            \" and no previous id defined in this file.\\n\");\n                    hasErrors = localHasErrors = true;\n                } else if (!localHasErrors) {\n                    ident = nextPublicId.valueFor(type);\n                    nextPublicId.replaceValueFor(type, ident+1);\n                }\n\n                if (!localHasErrors) {\n                    err = outTable->addPublic(srcPos, myPackage, type, name, ident);\n                    if (err < NO_ERROR) {\n                        hasErrors = localHasErrors = true;\n                    }\n                }\n                if (!localHasErrors) {\n                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8(\"R\"));\n                    if (symbols != NULL) {\n                        symbols = symbols->addNestedSymbol(String8(type), srcPos);\n                    }\n                    if (symbols != NULL) {\n                        symbols->makeSymbolPublic(String8(name), srcPos);\n                        String16 comment(\n                            block.getComment(&len) ? block.getComment(&len) : nulStr);\n                        symbols->appendComment(String8(name), comment, srcPos);\n                    } else {\n                        srcPos.error(\"Unable to create symbols!\\n\");\n                        hasErrors = localHasErrors = true;\n                    }\n                }\n\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), public16.string()) == 0) {\n                            break;\n                        }\n                    }\n                }\n                continue;\n\n            } else if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {\n                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());\n            \n                String16 type;\n                ssize_t typeIdx = block.indexOfAttribute(NULL, \"type\");\n                if (typeIdx < 0) {\n                    srcPos.error(\"A 'type' attribute is required for <public-padding>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                type = String16(block.getAttributeStringValue(typeIdx, &len));\n\n                String16 name;\n                ssize_t nameIdx = block.indexOfAttribute(NULL, \"name\");\n                if (nameIdx < 0) {\n                    srcPos.error(\"A 'name' attribute is required for <public-padding>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                name = String16(block.getAttributeStringValue(nameIdx, &len));\n\n                uint32_t start = 0;\n                ssize_t startIdx = block.indexOfAttribute(NULL, \"start\");\n                if (startIdx >= 0) {\n                    const char16_t* startStr = block.getAttributeStringValue(startIdx, &len);\n                    Res_value startValue;\n                    if (!ResTable::stringToInt(startStr, len, &startValue)) {\n                        srcPos.error(\"Given 'start' attribute is not an integer: %s\\n\",\n                                String8(block.getAttributeStringValue(startIdx, &len)).string());\n                        hasErrors = localHasErrors = true;\n                    } else {\n                        start = startValue.data;\n                    }\n                } else if (nextPublicId.indexOfKey(type) < 0) {\n                    srcPos.error(\"No 'start' attribute supplied <public-padding>,\"\n                            \" and no previous id defined in this file.\\n\");\n                    hasErrors = localHasErrors = true;\n                } else if (!localHasErrors) {\n                    start = nextPublicId.valueFor(type);\n                }\n\n                uint32_t end = 0;\n                ssize_t endIdx = block.indexOfAttribute(NULL, \"end\");\n                if (endIdx >= 0) {\n                    const char16_t* endStr = block.getAttributeStringValue(endIdx, &len);\n                    Res_value endValue;\n                    if (!ResTable::stringToInt(endStr, len, &endValue)) {\n                        srcPos.error(\"Given 'end' attribute is not an integer: %s\\n\",\n                                String8(block.getAttributeStringValue(endIdx, &len)).string());\n                        hasErrors = localHasErrors = true;\n                    } else {\n                        end = endValue.data;\n                    }\n                } else {\n                    srcPos.error(\"No 'end' attribute supplied <public-padding>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n\n                if (end >= start) {\n                    nextPublicId.replaceValueFor(type, end+1);\n                } else {\n                    srcPos.error(\"Padding start '%ul' is after end '%ul'\\n\",\n                            start, end);\n                    hasErrors = localHasErrors = true;\n                }\n                \n                String16 comment(\n                    block.getComment(&len) ? block.getComment(&len) : nulStr);\n                for (uint32_t curIdent=start; curIdent<=end; curIdent++) {\n                    if (localHasErrors) {\n                        break;\n                    }\n                    String16 curName(name);\n                    char buf[64];\n                    sprintf(buf, \"%d\", (int)(end-curIdent+1));\n                    curName.append(String16(buf));\n                    \n                    err = outTable->addEntry(srcPos, myPackage, type, curName,\n                                             String16(\"padding\"), NULL, &curParams, false,\n                                             ResTable_map::TYPE_STRING, overwrite);\n                    if (err < NO_ERROR) {\n                        hasErrors = localHasErrors = true;\n                        break;\n                    }\n                    err = outTable->addPublic(srcPos, myPackage, type,\n                            curName, curIdent);\n                    if (err < NO_ERROR) {\n                        hasErrors = localHasErrors = true;\n                        break;\n                    }\n                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8(\"R\"));\n                    if (symbols != NULL) {\n                        symbols = symbols->addNestedSymbol(String8(type), srcPos);\n                    }\n                    if (symbols != NULL) {\n                        symbols->makeSymbolPublic(String8(curName), srcPos);\n                        symbols->appendComment(String8(curName), comment, srcPos);\n                    } else {\n                        srcPos.error(\"Unable to create symbols!\\n\");\n                        hasErrors = localHasErrors = true;\n                    }\n                }\n\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {\n                            break;\n                        }\n                    }\n                }\n                continue;\n\n            } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {\n                String16 pkg;\n                ssize_t pkgIdx = block.indexOfAttribute(NULL, \"package\");\n                if (pkgIdx < 0) {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                            \"A 'package' attribute is required for <private-symbols>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                pkg = String16(block.getAttributeStringValue(pkgIdx, &len));\n                if (!localHasErrors) {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber()).warning(\n                            \"<private-symbols> is deprecated. Use the command line flag \"\n                            \"--private-symbols instead.\\n\");\n                    if (assets->havePrivateSymbols()) {\n                        SourcePos(in->getPrintableSource(), block.getLineNumber()).warning(\n                                \"private symbol package already specified. Ignoring...\\n\");\n                    } else {\n                        assets->setSymbolsPrivatePackage(String8(pkg));\n                    }\n                }\n\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {\n                            break;\n                        }\n                    }\n                }\n                continue;\n\n            } else if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) {\n                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());\n            \n                String16 type;\n                ssize_t typeIdx = block.indexOfAttribute(NULL, \"type\");\n                if (typeIdx < 0) {\n                    srcPos.error(\"A 'type' attribute is required for <public>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                type = String16(block.getAttributeStringValue(typeIdx, &len));\n\n                String16 name;\n                ssize_t nameIdx = block.indexOfAttribute(NULL, \"name\");\n                if (nameIdx < 0) {\n                    srcPos.error(\"A 'name' attribute is required for <public>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                name = String16(block.getAttributeStringValue(nameIdx, &len));\n\n                sp<AaptSymbols> symbols = assets->getJavaSymbolsFor(String8(\"R\"));\n                if (symbols != NULL) {\n                    symbols = symbols->addNestedSymbol(String8(type), srcPos);\n                }\n                if (symbols != NULL) {\n                    symbols->makeSymbolJavaSymbol(String8(name), srcPos);\n                    String16 comment(\n                        block.getComment(&len) ? block.getComment(&len) : nulStr);\n                    symbols->appendComment(String8(name), comment, srcPos);\n                } else {\n                    srcPos.error(\"Unable to create symbols!\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) {\n                            break;\n                        }\n                    }\n                }\n                continue;\n\n\n            } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {\n                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());\n            \n                String16 typeName;\n                ssize_t typeIdx = block.indexOfAttribute(NULL, \"type\");\n                if (typeIdx < 0) {\n                    srcPos.error(\"A 'type' attribute is required for <add-resource>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                typeName = String16(block.getAttributeStringValue(typeIdx, &len));\n\n                String16 name;\n                ssize_t nameIdx = block.indexOfAttribute(NULL, \"name\");\n                if (nameIdx < 0) {\n                    srcPos.error(\"A 'name' attribute is required for <add-resource>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                name = String16(block.getAttributeStringValue(nameIdx, &len));\n\n                outTable->canAddEntry(srcPos, myPackage, typeName, name);\n\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {\n                            break;\n                        }\n                    }\n                }\n                continue;\n                \n            } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {\n                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());\n                                \n                String16 ident;\n                ssize_t identIdx = block.indexOfAttribute(NULL, \"name\");\n                if (identIdx < 0) {\n                    srcPos.error(\"A 'name' attribute is required for <declare-styleable>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                ident = String16(block.getAttributeStringValue(identIdx, &len));\n\n                sp<AaptSymbols> symbols = assets->getSymbolsFor(String8(\"R\"));\n                if (!localHasErrors) {\n                    if (symbols != NULL) {\n                        symbols = symbols->addNestedSymbol(String8(\"styleable\"), srcPos);\n                    }\n                    sp<AaptSymbols> styleSymbols = symbols;\n                    if (symbols != NULL) {\n                        symbols = symbols->addNestedSymbol(String8(ident), srcPos);\n                    }\n                    if (symbols == NULL) {\n                        srcPos.error(\"Unable to create symbols!\\n\");\n                        return UNKNOWN_ERROR;\n                    }\n                    \n                    String16 comment(\n                        block.getComment(&len) ? block.getComment(&len) : nulStr);\n                    styleSymbols->appendComment(String8(ident), comment, srcPos);\n                } else {\n                    symbols = NULL;\n                }\n\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::START_TAG) {\n                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {\n                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n                                   && code != ResXMLTree::BAD_DOCUMENT) {\n                                if (code == ResXMLTree::END_TAG) {\n                                    if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {\n                                        break;\n                                    }\n                                }\n                            }\n                            continue;\n                        } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {\n                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n                                   && code != ResXMLTree::BAD_DOCUMENT) {\n                                if (code == ResXMLTree::END_TAG) {\n                                    if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {\n                                        break;\n                                    }\n                                }\n                            }\n                            continue;\n                        } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) {\n                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                    \"Tag <%s> can not appear inside <declare-styleable>, only <attr>\\n\",\n                                    String8(block.getElementName(&len)).string());\n                            return UNKNOWN_ERROR;\n                        }\n\n                        String16 comment(\n                            block.getComment(&len) ? block.getComment(&len) : nulStr);\n                        String16 itemIdent;\n                        err = compileAttribute(in, block, myPackage, outTable, &itemIdent, true);\n                        if (err != NO_ERROR) {\n                            hasErrors = localHasErrors = true;\n                        }\n\n                        if (symbols != NULL) {\n                            SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber());\n                            symbols->addSymbol(String8(itemIdent), 0, srcPos);\n                            symbols->appendComment(String8(itemIdent), comment, srcPos);\n                            //printf(\"Attribute %s comment: %s\\n\", String8(itemIdent).string(),\n                            //     String8(comment).string());\n                        }\n                    } else if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {\n                            break;\n                        }\n\n                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                \"Found tag </%s> where </attr> is expected\\n\",\n                                String8(block.getElementName(&len)).string());\n                        return UNKNOWN_ERROR;\n                    }\n                }\n                continue;\n\n            } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {\n                err = compileAttribute(in, block, myPackage, outTable, NULL);\n                if (err != NO_ERROR) {\n                    hasErrors = true;\n                }\n                continue;\n\n            } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) {\n                curTag = &item16;\n                ssize_t attri = block.indexOfAttribute(NULL, \"type\");\n                if (attri >= 0) {\n                    curType = String16(block.getAttributeStringValue(attri, &len));\n                    ssize_t nameIdx = block.indexOfAttribute(NULL, \"name\");\n                    if (nameIdx >= 0) {\n                        curName = String16(block.getAttributeStringValue(nameIdx, &len));\n                    }\n                    ssize_t formatIdx = block.indexOfAttribute(NULL, \"format\");\n                    if (formatIdx >= 0) {\n                        String16 formatStr = String16(block.getAttributeStringValue(\n                                formatIdx, &len));\n                        curFormat = parse_flags(formatStr.string(), formatStr.size(),\n                                                gFormatFlags);\n                        if (curFormat == 0) {\n                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                    \"Tag <item> 'format' attribute value \\\"%s\\\" not valid\\n\",\n                                    String8(formatStr).string());\n                            hasErrors = localHasErrors = true;\n                        }\n                    }\n                } else {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                            \"A 'type' attribute is required for <item>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                curIsStyled = true;\n            } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) {\n                // Note the existence and locale of every string we process\n                char rawLocale[RESTABLE_MAX_LOCALE_LEN];\n                curParams.getBcp47Locale(rawLocale);\n                String8 locale(rawLocale);\n                String16 name;\n                String16 translatable;\n                String16 formatted;\n\n                size_t n = block.getAttributeCount();\n                for (size_t i = 0; i < n; i++) {\n                    size_t length;\n                    const char16_t* attr = block.getAttributeName(i, &length);\n                    if (strcmp16(attr, name16.string()) == 0) {\n                        name.setTo(block.getAttributeStringValue(i, &length));\n                    } else if (strcmp16(attr, translatable16.string()) == 0) {\n                        translatable.setTo(block.getAttributeStringValue(i, &length));\n                    } else if (strcmp16(attr, formatted16.string()) == 0) {\n                        formatted.setTo(block.getAttributeStringValue(i, &length));\n                    }\n                }\n                \n                if (name.size() > 0) {\n                    if (locale.size() == 0) {\n                        outTable->addDefaultLocalization(name);\n                    }\n                    if (translatable == false16) {\n                        curIsFormatted = false;\n                        // Untranslatable strings must only exist in the default [empty] locale\n                        if (locale.size() > 0) {\n                            SourcePos(in->getPrintableSource(), block.getLineNumber()).warning(\n                                    \"string '%s' marked untranslatable but exists in locale '%s'\\n\",\n                                    String8(name).string(),\n                                    locale.string());\n                            // hasErrors = localHasErrors = true;\n                        } else {\n                            // Intentionally empty block:\n                            //\n                            // Don't add untranslatable strings to the localization table; that\n                            // way if we later see localizations of them, they'll be flagged as\n                            // having no default translation.\n                        }\n                    } else {\n                        outTable->addLocalization(\n                                name,\n                                locale,\n                                SourcePos(in->getPrintableSource(), block.getLineNumber()));\n                    }\n\n                    if (formatted == false16) {\n                        curIsFormatted = false;\n                    }\n                }\n\n                curTag = &string16;\n                curType = string16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;\n                curIsStyled = true;\n                curIsPseudolocalizable = fileIsTranslatable && (translatable != false16);\n            } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) {\n                curTag = &drawable16;\n                curType = drawable16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;\n            } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) {\n                curTag = &color16;\n                curType = color16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;\n            } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) {\n                curTag = &bool16;\n                curType = bool16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN;\n            } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) {\n                curTag = &integer16;\n                curType = integer16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;\n            } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) {\n                curTag = &dimen16;\n                curType = dimen16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION;\n            } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) {\n                curTag = &fraction16;\n                curType = fraction16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION;\n            } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) {\n                curTag = &bag16;\n                curIsBag = true;\n                ssize_t attri = block.indexOfAttribute(NULL, \"type\");\n                if (attri >= 0) {\n                    curType = String16(block.getAttributeStringValue(attri, &len));\n                } else {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                            \"A 'type' attribute is required for <bag>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) {\n                curTag = &style16;\n                curType = style16;\n                curIsBag = true;\n            } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) {\n                curTag = &plurals16;\n                curType = plurals16;\n                curIsBag = true;\n                curIsPseudolocalizable = fileIsTranslatable;\n            } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) {\n                curTag = &array16;\n                curType = array16;\n                curIsBag = true;\n                curIsBagReplaceOnOverwrite = true;\n                ssize_t formatIdx = block.indexOfAttribute(NULL, \"format\");\n                if (formatIdx >= 0) {\n                    String16 formatStr = String16(block.getAttributeStringValue(\n                            formatIdx, &len));\n                    curFormat = parse_flags(formatStr.string(), formatStr.size(),\n                                            gFormatFlags);\n                    if (curFormat == 0) {\n                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                \"Tag <array> 'format' attribute value \\\"%s\\\" not valid\\n\",\n                                String8(formatStr).string());\n                        hasErrors = localHasErrors = true;\n                    }\n                }\n            } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) {\n                // Check whether these strings need valid formats.\n                // (simplified form of what string16 does above)\n                bool isTranslatable = false;\n                size_t n = block.getAttributeCount();\n\n                // Pseudolocalizable by default, unless this string array isn't\n                // translatable.\n                for (size_t i = 0; i < n; i++) {\n                    size_t length;\n                    const char16_t* attr = block.getAttributeName(i, &length);\n                    if (strcmp16(attr, formatted16.string()) == 0) {\n                        const char16_t* value = block.getAttributeStringValue(i, &length);\n                        if (strcmp16(value, false16.string()) == 0) {\n                            curIsFormatted = false;\n                        }\n                    } else if (strcmp16(attr, translatable16.string()) == 0) {\n                        const char16_t* value = block.getAttributeStringValue(i, &length);\n                        if (strcmp16(value, false16.string()) == 0) {\n                            isTranslatable = false;\n                        }\n                    }\n                }\n\n                curTag = &string_array16;\n                curType = array16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;\n                curIsBag = true;\n                curIsBagReplaceOnOverwrite = true;\n                curIsPseudolocalizable = isTranslatable && fileIsTranslatable;\n            } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) {\n                curTag = &integer_array16;\n                curType = array16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;\n                curIsBag = true;\n                curIsBagReplaceOnOverwrite = true;\n            } else {\n                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                        \"Found tag %s where item is expected\\n\",\n                        String8(block.getElementName(&len)).string());\n                return UNKNOWN_ERROR;\n            }\n\n            String16 ident;\n            ssize_t identIdx = block.indexOfAttribute(NULL, \"name\");\n            if (identIdx >= 0) {\n                ident = String16(block.getAttributeStringValue(identIdx, &len));\n            } else {\n                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                        \"A 'name' attribute is required for <%s>\\n\",\n                        String8(*curTag).string());\n                hasErrors = localHasErrors = true;\n            }\n\n            String16 product;\n            identIdx = block.indexOfAttribute(NULL, \"product\");\n            if (identIdx >= 0) {\n                product = String16(block.getAttributeStringValue(identIdx, &len));\n            }\n\n            String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr);\n            \n            if (curIsBag) {\n                // Figure out the parent of this bag...\n                String16 parentIdent;\n                ssize_t parentIdentIdx = block.indexOfAttribute(NULL, \"parent\");\n                if (parentIdentIdx >= 0) {\n                    parentIdent = String16(block.getAttributeStringValue(parentIdentIdx, &len));\n                } else {\n                    ssize_t sep = ident.findLast('.');\n                    if (sep >= 0) {\n                        parentIdent.setTo(ident, sep);\n                    }\n                }\n\n                if (!localHasErrors) {\n                    err = outTable->startBag(SourcePos(in->getPrintableSource(),\n                            block.getLineNumber()), myPackage, curType, ident,\n                            parentIdent, &curParams,\n                            overwrite, curIsBagReplaceOnOverwrite);\n                    if (err != NO_ERROR) {\n                        hasErrors = localHasErrors = true;\n                    }\n                }\n                \n                ssize_t elmIndex = 0;\n                char elmIndexStr[14];\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n                        && code != ResXMLTree::BAD_DOCUMENT) {\n\n                    if (code == ResXMLTree::START_TAG) {\n                        if (strcmp16(block.getElementName(&len), item16.string()) != 0) {\n                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                    \"Tag <%s> can not appear inside <%s>, only <item>\\n\",\n                                    String8(block.getElementName(&len)).string(),\n                                    String8(*curTag).string());\n                            return UNKNOWN_ERROR;\n                        }\n\n                        String16 itemIdent;\n                        if (curType == array16) {\n                            sprintf(elmIndexStr, \"^index_%d\", (int)elmIndex++);\n                            itemIdent = String16(elmIndexStr);\n                        } else if (curType == plurals16) {\n                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, \"quantity\");\n                            if (itemIdentIdx >= 0) {\n                                String16 quantity16(block.getAttributeStringValue(itemIdentIdx, &len));\n                                if (quantity16 == other16) {\n                                    itemIdent = quantityOther16;\n                                }\n                                else if (quantity16 == zero16) {\n                                    itemIdent = quantityZero16;\n                                }\n                                else if (quantity16 == one16) {\n                                    itemIdent = quantityOne16;\n                                }\n                                else if (quantity16 == two16) {\n                                    itemIdent = quantityTwo16;\n                                }\n                                else if (quantity16 == few16) {\n                                    itemIdent = quantityFew16;\n                                }\n                                else if (quantity16 == many16) {\n                                    itemIdent = quantityMany16;\n                                }\n                                else {\n                                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                            \"Illegal 'quantity' attribute is <item> inside <plurals>\\n\");\n                                    hasErrors = localHasErrors = true;\n                                }\n                            } else {\n                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                        \"A 'quantity' attribute is required for <item> inside <plurals>\\n\");\n                                hasErrors = localHasErrors = true;\n                            }\n                        } else {\n                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, \"name\");\n                            if (itemIdentIdx >= 0) {\n                                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));\n                            } else {\n                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                        \"A 'name' attribute is required for <item>\\n\");\n                                hasErrors = localHasErrors = true;\n                            }\n                        }\n\n                        ResXMLParser::ResXMLPosition parserPosition;\n                        block.getPosition(&parserPosition);\n\n                        err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType,\n                                ident, parentIdent, itemIdent, curFormat, curIsFormatted,\n                                product, NO_PSEUDOLOCALIZATION, overwrite, outTable);\n                        if (err == NO_ERROR) {\n                            if (curIsPseudolocalizable && localeIsDefined(curParams)\n                                    && bundle->getPseudolocalize() > 0) {\n                                // pseudolocalize here\n                                if ((PSEUDO_ACCENTED & bundle->getPseudolocalize()) ==\n                                   PSEUDO_ACCENTED) {\n                                    block.setPosition(parserPosition);\n                                    err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage,\n                                            curType, ident, parentIdent, itemIdent, curFormat,\n                                            curIsFormatted, product, PSEUDO_ACCENTED,\n                                            overwrite, outTable);\n                                }\n                                if ((PSEUDO_BIDI & bundle->getPseudolocalize()) ==\n                                   PSEUDO_BIDI) {\n                                    block.setPosition(parserPosition);\n                                    err = parseAndAddBag(bundle, in, &block, pseudoBidiParams, myPackage,\n                                            curType, ident, parentIdent, itemIdent, curFormat,\n                                            curIsFormatted, product, PSEUDO_BIDI,\n                                            overwrite, outTable);\n                                }\n                            }\n                        }\n                        if (err != NO_ERROR) {\n                            hasErrors = localHasErrors = true;\n                        }\n                    } else if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), curTag->string()) != 0) {\n                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                    \"Found tag </%s> where </%s> is expected\\n\",\n                                    String8(block.getElementName(&len)).string(),\n                                    String8(*curTag).string());\n                            return UNKNOWN_ERROR;\n                        }\n                        break;\n                    }\n                }\n            } else {\n                ResXMLParser::ResXMLPosition parserPosition;\n                block.getPosition(&parserPosition);\n\n                err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident,\n                        *curTag, curIsStyled, curFormat, curIsFormatted,\n                        product, NO_PSEUDOLOCALIZATION, overwrite, &skippedResourceNames, outTable);\n\n                if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR?\n                    hasErrors = localHasErrors = true;\n                }\n                else if (err == NO_ERROR) {\n                    if (curType == string16 && !curParams.language[0] && !curParams.country[0]) {\n                        outTable->addDefaultLocalization(curName);\n                    }\n                    if (curIsPseudolocalizable && localeIsDefined(curParams)\n                            && bundle->getPseudolocalize() > 0) {\n                        // pseudolocalize here\n                        if ((PSEUDO_ACCENTED & bundle->getPseudolocalize()) ==\n                           PSEUDO_ACCENTED) {\n                            block.setPosition(parserPosition);\n                            err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType,\n                                    ident, *curTag, curIsStyled, curFormat,\n                                    curIsFormatted, product,\n                                    PSEUDO_ACCENTED, overwrite, &skippedResourceNames, outTable);\n                        }\n                        if ((PSEUDO_BIDI & bundle->getPseudolocalize()) ==\n                           PSEUDO_BIDI) {\n                            block.setPosition(parserPosition);\n                            err = parseAndAddEntry(bundle, in, &block, pseudoBidiParams,\n                                    myPackage, curType, ident, *curTag, curIsStyled, curFormat,\n                                    curIsFormatted, product,\n                                    PSEUDO_BIDI, overwrite, &skippedResourceNames, outTable);\n                        }\n                        if (err != NO_ERROR) {\n                            hasErrors = localHasErrors = true;\n                        }\n                    }\n                }\n            }\n\n#if 0\n            if (comment.size() > 0) {\n                printf(\"Comment for @%s:%s/%s: %s\\n\", String8(myPackage).string(),\n                       String8(curType).string(), String8(ident).string(),\n                       String8(comment).string());\n            }\n#endif\n            if (!localHasErrors) {\n                outTable->appendComment(myPackage, curType, ident, comment, false);\n            }\n        }\n        else if (code == ResXMLTree::END_TAG) {\n            if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {\n                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                        \"Unexpected end tag %s\\n\", String8(block.getElementName(&len)).string());\n                return UNKNOWN_ERROR;\n            }\n        }\n        else if (code == ResXMLTree::START_NAMESPACE || code == ResXMLTree::END_NAMESPACE) {\n        }\n        else if (code == ResXMLTree::TEXT) {\n            if (isWhitespace(block.getText(&len))) {\n                continue;\n            }\n            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                    \"Found text \\\"%s\\\" where item tag is expected\\n\",\n                    String8(block.getText(&len)).string());\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    // For every resource defined, there must be exist one variant with a product attribute\n    // set to 'default' (or no product attribute at all).\n    // We check to see that for every resource that was ignored because of a mismatched\n    // product attribute, some product variant of that resource was processed.\n    for (size_t i = 0; i < skippedResourceNames.size(); i++) {\n        if (skippedResourceNames[i]) {\n            const type_ident_pair_t& p = skippedResourceNames.keyAt(i);\n            if (!outTable->hasBagOrEntry(myPackage, p.type, p.ident)) {\n                const char* bundleProduct =\n                        (bundle->getProduct() == NULL) ? \"\" : bundle->getProduct();\n                fprintf(stderr, \"In resource file %s: %s\\n\",\n                        in->getPrintableSource().string(),\n                        curParams.toString().string());\n\n                fprintf(stderr, \"\\t%s '%s' does not match product %s.\\n\"\n                        \"\\tYou may have forgotten to include a 'default' product variant\"\n                        \" of the resource.\\n\",\n                        String8(p.type).string(), String8(p.ident).string(),\n                        bundleProduct[0] == 0 ? \"default\" : bundleProduct);\n                return UNKNOWN_ERROR;\n            }\n        }\n    }\n\n    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;\n}\n\nResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage, ResourceTable::PackageType type)\n    : mAssetsPackage(assetsPackage)\n    , mPackageType(type)\n    , mTypeIdOffset(0)\n    , mNumLocal(0)\n    , mBundle(bundle)\n{\n    ssize_t packageId = -1;\n    switch (mPackageType) {\n        case App:\n        case AppFeature:\n            packageId = customePackageId;\n            break;\n\n        case System:\n            packageId = 0x01;\n            break;\n\n        case SharedLibrary:\n            packageId = 0x00;\n            break;\n\n        default:\n            assert(0);\n            break;\n    }\n    sp<Package> package = new Package(mAssetsPackage, packageId);\n    mPackages.add(assetsPackage, package);\n    mOrderedPackages.add(package);\n\n    // Every resource table always has one first entry, the bag attributes.\n    const SourcePos unknown(String8(\"????\"), 0);\n    getType(mAssetsPackage, String16(\"attr\"), unknown);\n}\n\nstatic uint32_t findLargestTypeIdForPackage(const ResTable& table, const String16& packageName) {\n    const size_t basePackageCount = table.getBasePackageCount();\n    for (size_t i = 0; i < basePackageCount; i++) {\n        if ((packageName == table.getBasePackageName(i)) || \n               (table.getBasePackageId(i) == customePackageId)) {\n            return table.getLastTypeIdForPackage(i);\n        }\n    }\n    return 0;\n}\n\nstatus_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets)\n{\n    status_t err = assets->buildIncludedResources(bundle);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    mAssets = assets;\n    mTypeIdOffset = findLargestTypeIdForPackage(assets->getIncludedResources(), mAssetsPackage);\n\n    const KeyedVector<uint32_t, ResTable::resource_name> resourceEntries = mAssets->getBaselineResources().getResourceEntries();\n    const size_t N = resourceEntries.size();\n    for (size_t i=0; i<N; i++) {\n        const uint32_t resID = resourceEntries.keyAt(i);\n        const ResTable::resource_name resName = resourceEntries.valueAt(i);\n        String8 type8;\n        String8 name8;\n        if (resName.type8 != NULL) {\n            type8 = String8(resName.type8, resName.typeLen);\n        } else {\n            type8 = String8(resName.type, resName.typeLen);\n        }\n        if (resName.name8 != NULL) {\n            name8 = String8(resName.name8, resName.nameLen);\n        } else {\n            name8 = String8(resName.name, resName.nameLen);\n        }\n        if (strncmp(name8.string(), \"null\", strlen(\"null\")) != 0) {\n            err = addPublic(SourcePos(), String16(resName.package,resName.packageLen), String16(type8), String16(name8), resID);\n        }\n    }\n    if (err != NO_ERROR) {\n        return err;\n    }\n    const String8& featureAfter = bundle->getFeatureAfterPackage();\n    if (!featureAfter.isEmpty()) {\n        AssetManager featureAssetManager;\n        if (!featureAssetManager.addAssetPath(featureAfter, NULL)) {\n            fprintf(stderr, \"ERROR: Feature package '%s' not found.\\n\",\n                    featureAfter.string());\n            return UNKNOWN_ERROR;\n        }\n\n        const ResTable& featureTable = featureAssetManager.getResources(false);\n        mTypeIdOffset = std::max(mTypeIdOffset,\n                findLargestTypeIdForPackage(featureTable, mAssetsPackage)); \n    }\n\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::addPublic(const SourcePos& sourcePos,\n                                  const String16& package,\n                                  const String16& type,\n                                  const String16& name,\n                                  const uint32_t ident)\n{\n    uint32_t rid = mAssets->getIncludedResources()\n        .identifierForName(name.string(), name.size(),\n                           type.string(), type.size(),\n                           package.string(), package.size());\n    if (rid != 0) {\n        sourcePos.error(\"Error declaring public resource %s/%s for included package %s\\n\",\n                String8(type).string(), String8(name).string(),\n                String8(package).string());\n        return UNKNOWN_ERROR;\n    }\n\n    sp<Type> t = getType(package, type, sourcePos);\n    if (t == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    return t->addPublic(sourcePos, name, ident);\n}\n\nstatus_t ResourceTable::addEntry(const SourcePos& sourcePos,\n                                 const String16& package,\n                                 const String16& type,\n                                 const String16& name,\n                                 const String16& value,\n                                 const Vector<StringPool::entry_style_span>* style,\n                                 const ResTable_config* params,\n                                 const bool doSetIndex,\n                                 const int32_t format,\n                                 const bool overwrite)\n{\n    uint32_t rid = mAssets->getIncludedResources()\n        .identifierForName(name.string(), name.size(),\n                           type.string(), type.size(),\n                           package.string(), package.size());\n    if (rid != 0) {\n        sourcePos.error(\"Resource entry %s/%s is already defined in package %s.\",\n                String8(type).string(), String8(name).string(), String8(package).string());\n        return UNKNOWN_ERROR;\n    }\n    \n    sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite,\n                           params, doSetIndex);\n    if (e == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    status_t err = e->setItem(sourcePos, value, style, format, overwrite);\n    if (err == NO_ERROR) {\n        mNumLocal++;\n    }\n    return err;\n}\n\nstatus_t ResourceTable::startBag(const SourcePos& sourcePos,\n                                 const String16& package,\n                                 const String16& type,\n                                 const String16& name,\n                                 const String16& bagParent,\n                                 const ResTable_config* params,\n                                 bool overlay,\n                                 bool replace, bool /* isId */)\n{\n    status_t result = NO_ERROR;\n\n    // Check for adding entries in other packages...  for now we do\n    // nothing.  We need to do the right thing here to support skinning.\n    uint32_t rid = mAssets->getIncludedResources()\n    .identifierForName(name.string(), name.size(),\n                       type.string(), type.size(),\n                       package.string(), package.size());\n    if (rid != 0) {\n        sourcePos.error(\"Resource entry %s/%s is already defined in package %s.\",\n                String8(type).string(), String8(name).string(), String8(package).string());\n        return UNKNOWN_ERROR;\n    }\n\n    if (overlay && !mBundle->getAutoAddOverlay() && !hasBagOrEntry(package, type, name)) {\n        bool canAdd = false;\n        sp<Package> p = mPackages.valueFor(package);\n        if (p != NULL) {\n            sp<Type> t = p->getTypes().valueFor(type);\n            if (t != NULL) {\n                if (t->getCanAddEntries().indexOf(name) >= 0) {\n                    canAdd = true;\n                }\n            }\n        }\n        if (!canAdd) {\n            sourcePos.error(\"Resource does not already exist in overlay at '%s'; use <add-resource> to add.\\n\",\n                            String8(name).string());\n            return UNKNOWN_ERROR;\n        }\n    }\n    sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params);\n    if (e == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    \n    // If a parent is explicitly specified, set it.\n    if (bagParent.size() > 0) {\n        e->setParent(bagParent);\n    }\n\n    if ((result = e->makeItABag(sourcePos)) != NO_ERROR) {\n        return result;\n    }\n\n    if (overlay && replace) { \n        return e->emptyBag(sourcePos);\n    }\n    return result;\n}\n\nstatus_t ResourceTable::addBag(const SourcePos& sourcePos,\n                               const String16& package,\n                               const String16& type,\n                               const String16& name,\n                               const String16& bagParent,\n                               const String16& bagKey,\n                               const String16& value,\n                               const Vector<StringPool::entry_style_span>* style,\n                               const ResTable_config* params,\n                               bool replace, bool isId, const int32_t format)\n{\n    // Check for adding entries in other packages...  for now we do\n    // nothing.  We need to do the right thing here to support skinning.\n    uint32_t rid = mAssets->getIncludedResources()\n        .identifierForName(name.string(), name.size(),\n                           type.string(), type.size(),\n                           package.string(), package.size());\n    if (rid != 0) {\n        return NO_ERROR;\n    }\n\n#if 0\n    if (name == String16(\"left\")) {\n        printf(\"Adding bag left: file=%s, line=%d, type=%s\\n\",\n               sourcePos.file.striing(), sourcePos.line, String8(type).string());\n    }\n#endif\n    sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params);\n    if (e == NULL) {\n        return UNKNOWN_ERROR;\n    }\n\n    // If a parent is explicitly specified, set it.\n    if (bagParent.size() > 0) {\n        e->setParent(bagParent);\n    }\n\n    const bool first = e->getBag().indexOfKey(bagKey) < 0;\n    status_t err = e->addToBag(sourcePos, bagKey, value, style, replace, isId, format);\n    if (err == NO_ERROR && first) {\n        mNumLocal++;\n    }\n    return err;\n}\n\nbool ResourceTable::hasBagOrEntry(const String16& package,\n                                  const String16& type,\n                                  const String16& name) const\n{\n    // First look for this in the included resources...\n    uint32_t rid = mAssets->getIncludedResources()\n        .identifierForName(name.string(), name.size(),\n                           type.string(), type.size(),\n                           package.string(), package.size());\n    if (rid != 0) {\n        return true;\n    }\n\n    sp<Package> p = mPackages.valueFor(package);\n    if (p != NULL) {\n        sp<Type> t = p->getTypes().valueFor(type);\n        if (t != NULL) {\n            sp<ConfigList> c =  t->getConfigs().valueFor(name);\n            if (c != NULL) return true;\n        }\n    }\n\n    return false;\n}\n\nbool ResourceTable::hasBagOrEntry(const String16& package,\n                                  const String16& type,\n                                  const String16& name,\n                                  const ResTable_config& config) const\n{\n    // First look for this in the included resources...\n    uint32_t rid = mAssets->getIncludedResources()\n        .identifierForName(name.string(), name.size(),\n                           type.string(), type.size(),\n                           package.string(), package.size());\n    if (rid != 0) {\n        return true;\n    }\n\n    sp<Package> p = mPackages.valueFor(package);\n    if (p != NULL) {\n        sp<Type> t = p->getTypes().valueFor(type);\n        if (t != NULL) {\n            sp<ConfigList> c =  t->getConfigs().valueFor(name);\n            if (c != NULL) {\n                sp<Entry> e = c->getEntries().valueFor(config);\n                if (e != NULL) {\n                    return true;\n                }\n            }\n        }\n    }\n\n    return false;\n}\n\nbool ResourceTable::hasBagOrEntry(const String16& ref,\n                                  const String16* defType,\n                                  const String16* defPackage)\n{\n    String16 package, type, name;\n    if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name,\n                defType, defPackage ? defPackage:&mAssetsPackage, NULL)) {\n        return false;\n    }\n    return hasBagOrEntry(package, type, name);\n}\n\nbool ResourceTable::appendComment(const String16& package,\n                                  const String16& type,\n                                  const String16& name,\n                                  const String16& comment,\n                                  bool onlyIfEmpty)\n{\n    if (comment.size() <= 0) {\n        return true;\n    }\n\n    sp<Package> p = mPackages.valueFor(package);\n    if (p != NULL) {\n        sp<Type> t = p->getTypes().valueFor(type);\n        if (t != NULL) {\n            sp<ConfigList> c =  t->getConfigs().valueFor(name);\n            if (c != NULL) {\n                c->appendComment(comment, onlyIfEmpty);\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nbool ResourceTable::appendTypeComment(const String16& package,\n                                      const String16& type,\n                                      const String16& name,\n                                      const String16& comment)\n{\n    if (comment.size() <= 0) {\n        return true;\n    }\n    \n    sp<Package> p = mPackages.valueFor(package);\n    if (p != NULL) {\n        sp<Type> t = p->getTypes().valueFor(type);\n        if (t != NULL) {\n            sp<ConfigList> c =  t->getConfigs().valueFor(name);\n            if (c != NULL) {\n                c->appendTypeComment(comment);\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nbool ResourceTable::makeAttribute(const String16& package,\n                                  const String16& name,\n                                  const SourcePos& source,\n                                  int32_t format,\n                                  const String16& comment,\n                                  bool shouldAppendComment) {\n    const String16 attr16(\"attr\");\n\n    // First look for this in the included resources...\n    uint32_t rid = mAssets->getIncludedResources()\n            .identifierForName(name.string(), name.size(),\n                               attr16.string(), attr16.size(),\n                               package.string(), package.size());\n    if (rid != 0) {\n        source.error(\"Attribute \\\"%s\\\" has already been defined\", String8(name).string());\n        return false;\n    }\n\n    sp<ResourceTable::Entry> entry = getEntry(package, attr16, name, source, false);\n    if (entry == NULL) {\n        source.error(\"Failed to create entry attr/%s\", String8(name).string());\n        return false;\n    }\n\n    if (entry->makeItABag(source) != NO_ERROR) {\n        return false;\n    }\n\n    const String16 formatKey16(\"^type\");\n    const String16 formatValue16(String8::format(\"%d\", format));\n\n    ssize_t idx = entry->getBag().indexOfKey(formatKey16);\n    if (idx >= 0) {\n        // We have already set a format for this attribute, check if they are different.\n        // We allow duplicate attribute definitions so long as they are identical.\n        // This is to ensure inter-operation with libraries that define the same generic attribute.\n        const Item& formatItem = entry->getBag().valueAt(idx);\n        if ((format & (ResTable_map::TYPE_ENUM | ResTable_map::TYPE_FLAGS)) ||\n                formatItem.value != formatValue16) {\n            source.error(\"Attribute \\\"%s\\\" already defined with incompatible format.\\n\"\n                         \"%s:%d: Original attribute defined here.\",\n                         String8(name).string(), formatItem.sourcePos.file.string(),\n                         formatItem.sourcePos.line);\n            return false;\n        }\n    } else {\n        entry->addToBag(source, formatKey16, formatValue16);\n        // Increment the number of resources we have. This is used to determine if we should\n        // even generate a resource table.\n        mNumLocal++;\n    }\n    appendComment(package, attr16, name, comment, shouldAppendComment);\n    return true;\n}\n\nvoid ResourceTable::canAddEntry(const SourcePos& pos,\n        const String16& package, const String16& type, const String16& name)\n{\n    sp<Type> t = getType(package, type, pos);\n    if (t != NULL) {\n        t->canAddEntry(name);\n    }\n}\n\nsize_t ResourceTable::size() const {\n    return mPackages.size();\n}\n\nsize_t ResourceTable::numLocalResources() const {\n    return mNumLocal;\n}\n\nbool ResourceTable::hasResources() const {\n    return mNumLocal > 0;\n}\n\nsp<AaptFile> ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,\n        const bool isBase)\n{\n    sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());\n    status_t err = flatten(bundle, filter, data, isBase);\n    return err == NO_ERROR ? data : NULL;\n}\n\ninline uint32_t ResourceTable::getResId(const sp<Package>& p,\n                                        const sp<Type>& t,\n                                        uint32_t nameId)\n{\n    return makeResId(p->getAssignedId(), t->getIndex(), nameId);\n}\n\nuint32_t ResourceTable::getResId(const String16& package,\n                                 const String16& type,\n                                 const String16& name,\n                                 bool onlyPublic) const\n{\n    uint32_t id = ResourceIdCache::lookup(package, type, name, onlyPublic);\n    if (id != 0) return id;     // cache hit\n\n    // First look for this in the included resources...\n    uint32_t specFlags = 0;\n    uint32_t rid = mAssets->getIncludedResources()\n        .identifierForName(name.string(), name.size(),\n                           type.string(), type.size(),\n                           package.string(), package.size(),\n                           &specFlags);\n    if (rid != 0) {\n        if (onlyPublic) {\n            if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) {\n                return 0;\n            }\n        }\n        \n        return ResourceIdCache::store(package, type, name, onlyPublic, rid);\n    }\n\n    sp<Package> p = mPackages.valueFor(package);\n    if (p == NULL) return 0;\n    sp<Type> t = p->getTypes().valueFor(type);\n    if (t == NULL) return 0;\n    sp<ConfigList> c = t->getConfigs().valueFor(name);\n    if (mBundle->getBaselinePackage().size() > 0 && c == NULL) {\n        int32_t idx = t->getPublicIndex(name);\n        if (idx > 0) {\n            return idx;\n        }\n    }\n    if (c == NULL) {\n        if (type != String16(\"attr\")) {\n            return 0;\n        }\n        t = p->getTypes().valueFor(String16(kAttrPrivateType));\n        if (t == NULL) return 0;\n        c = t->getConfigs().valueFor(name);\n        if (c == NULL) return 0;\n    }\n    int32_t ei = c->getEntryIndex();\n    if (ei < 0) return 0;\n\n    return ResourceIdCache::store(package, type, name, onlyPublic,\n            getResId(p, t, ei));\n}\n\nuint32_t ResourceTable::getResId(const String16& ref,\n                                 const String16* defType,\n                                 const String16* defPackage,\n                                 const char** outErrorMsg,\n                                 bool onlyPublic) const\n{\n    String16 package, type, name;\n    bool refOnlyPublic = true;\n    if (!ResTable::expandResourceRef(\n        ref.string(), ref.size(), &package, &type, &name,\n        defType, defPackage ? defPackage:&mAssetsPackage,\n        outErrorMsg, &refOnlyPublic)) {\n        if (kIsDebug) {\n            printf(\"Expanding resource: ref=%s\\n\", String8(ref).string());\n            printf(\"Expanding resource: defType=%s\\n\",\n                    defType ? String8(*defType).string() : \"NULL\");\n            printf(\"Expanding resource: defPackage=%s\\n\",\n                    defPackage ? String8(*defPackage).string() : \"NULL\");\n            printf(\"Expanding resource: ref=%s\\n\", String8(ref).string());\n            printf(\"Expanded resource: p=%s, t=%s, n=%s, res=0\\n\",\n                    String8(package).string(), String8(type).string(),\n                    String8(name).string());\n        }\n        return 0;\n    }\n    uint32_t res = getResId(package, type, name, onlyPublic && refOnlyPublic);\n    if (kIsDebug) {\n        printf(\"Expanded resource: p=%s, t=%s, n=%s, res=%d\\n\",\n                String8(package).string(), String8(type).string(),\n                String8(name).string(), res);\n    }\n    if (res == 0) {\n        //if (outErrorMsg)\n            //*outErrorMsg = \"No resource found that matches the given name\";\n    }\n    return res;\n}\n\nbool ResourceTable::isValidResourceName(const String16& s)\n{\n    const char16_t* p = s.string();\n    bool first = true;\n    while (*p) {\n        if ((*p >= 'a' && *p <= 'z')\n            || (*p >= 'A' && *p <= 'Z')\n            || *p == '_'\n            || (!first && *p >= '0' && *p <= '9')) {\n            first = false;\n            p++;\n            continue;\n        }\n        return false;\n    }\n    return true;\n}\n\nbool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool,\n                                  const String16& str,\n                                  bool preserveSpaces, bool coerceType,\n                                  uint32_t attrID,\n                                  const Vector<StringPool::entry_style_span>* style,\n                                  String16* outStr, void* accessorCookie,\n                                  uint32_t attrType, const String8* configTypeName,\n                                  const ConfigDescription* config)\n{\n    String16 finalStr;\n\n    bool res = true;\n    if (style == NULL || style->size() == 0) {\n        // Text is not styled so it can be any type...  let's figure it out.\n        res = mAssets->getIncludedResources()\n            .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces,\n                            coerceType, attrID, NULL, &mAssetsPackage, this,\n                           accessorCookie, attrType, true, sktPackageName == NULL);\n        if (!res){\n            String16 packageName = String16(sktPackageName);\n            // Text is not styled so it can be any type...  let's figure it out.\n            res = mAssets->getIncludedResources()\n                .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces,\n                            coerceType, attrID, NULL, &packageName, this,\n                           accessorCookie, attrType, false);\n        }\n    } else {\n        // Styled text can only be a string, and while collecting the style\n        // information we have already processed that string!\n        outValue->size = sizeof(Res_value);\n        outValue->res0 = 0;\n        outValue->dataType = outValue->TYPE_STRING;\n        outValue->data = 0;\n        finalStr = str;\n    }\n\n    if (!res) {\n        return false;\n    }\n\n    if (outValue->dataType == outValue->TYPE_STRING) {\n        // Should do better merging styles.\n        if (pool) {\n            String8 configStr;\n            if (config != NULL) {\n                configStr = config->toString();\n            } else {\n                configStr = \"(null)\";\n            }\n            if (kIsDebug) {\n                printf(\"Adding to pool string style #%zu config %s: %s\\n\",\n                        style != NULL ? style->size() : 0U,\n                        configStr.string(), String8(finalStr).string());\n            }\n            if (style != NULL && style->size() > 0) {\n                outValue->data = pool->add(finalStr, *style, configTypeName, config);\n            } else {\n                outValue->data = pool->add(finalStr, true, configTypeName, config);\n            }\n        } else {\n            // Caller will fill this in later.\n            outValue->data = 0;\n        }\n    \n        if (outStr) {\n            *outStr = finalStr;\n        }\n\n    }\n\n    return true;\n}\n\nuint32_t ResourceTable::getCustomResource(\n    const String16& package, const String16& type, const String16& name) const\n{\n    //printf(\"getCustomResource: %s %s %s\\n\", String8(package).string(),\n    //       String8(type).string(), String8(name).string());\n    sp<Package> p = mPackages.valueFor(package);\n    if (p == NULL) return 0;\n    sp<Type> t = p->getTypes().valueFor(type);\n    if (t == NULL) return 0;\n    sp<ConfigList> c =  t->getConfigs().valueFor(name);\n    if (mBundle->getBaselinePackage().size() > 0 && c == NULL) {\n        int32_t idx = t->getPublicIndex(name);\n        if (idx > 0) {\n            return idx;\n        }\n    }\n    if (c == NULL) {\n        if (type != String16(\"attr\")) {\n            return 0;\n        }\n        t = p->getTypes().valueFor(String16(kAttrPrivateType));\n        if (t == NULL) return 0;\n        c = t->getConfigs().valueFor(name);\n        if (c == NULL) return 0;\n    }\n    int32_t ei = c->getEntryIndex();\n    if (ei < 0) return 0;\n    return getResId(p, t, ei);\n}\n\nuint32_t ResourceTable::getCustomResourceWithCreation(\n        const String16& package, const String16& type, const String16& name,\n        const bool createIfNotFound)\n{\n    uint32_t resId = getCustomResource(package, type, name);\n    if (resId != 0 || !createIfNotFound) {\n        return resId;\n    }\n\n    if (mAssetsPackage != package) {\n        mCurrentXmlPos.error(\"creating resource for external package %s: %s/%s.\",\n                String8(package).string(), String8(type).string(), String8(name).string());\n        if (package == String16(\"android\")) {\n            mCurrentXmlPos.printf(\"did you mean to use @+id instead of @+android:id?\");\n        }\n        return 0;\n    }\n\n    String16 value(\"false\");\n    status_t status = addEntry(mCurrentXmlPos, package, type, name, value, NULL, NULL, true);\n    if (status == NO_ERROR) {\n        resId = getResId(package, type, name);\n        return resId;\n    }\n    return 0;\n}\n\nuint32_t ResourceTable::getRemappedPackage(uint32_t origPackage) const\n{\n    return origPackage;\n}\n\nbool ResourceTable::getAttributeType(uint32_t attrID, uint32_t* outType)\n{\n    //printf(\"getAttributeType #%08x\\n\", attrID);\n    Res_value value;\n    if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) {\n        //printf(\"getAttributeType #%08x (%s): #%08x\\n\", attrID,\n        //       String8(getEntry(attrID)->getName()).string(), value.data);\n        *outType = value.data;\n        return true;\n    }\n    return false;\n}\n\nbool ResourceTable::getAttributeMin(uint32_t attrID, uint32_t* outMin)\n{\n    //printf(\"getAttributeMin #%08x\\n\", attrID);\n    Res_value value;\n    if (getItemValue(attrID, ResTable_map::ATTR_MIN, &value)) {\n        *outMin = value.data;\n        return true;\n    }\n    return false;\n}\n\nbool ResourceTable::getAttributeMax(uint32_t attrID, uint32_t* outMax)\n{\n    //printf(\"getAttributeMax #%08x\\n\", attrID);\n    Res_value value;\n    if (getItemValue(attrID, ResTable_map::ATTR_MAX, &value)) {\n        *outMax = value.data;\n        return true;\n    }\n    return false;\n}\n\nuint32_t ResourceTable::getAttributeL10N(uint32_t attrID)\n{\n    //printf(\"getAttributeL10N #%08x\\n\", attrID);\n    Res_value value;\n    if (getItemValue(attrID, ResTable_map::ATTR_L10N, &value)) {\n        return value.data;\n    }\n    return ResTable_map::L10N_NOT_REQUIRED;\n}\n\nbool ResourceTable::getLocalizationSetting()\n{\n    return mBundle->getRequireLocalization();\n}\n\nvoid ResourceTable::reportError(void* accessorCookie, const char* fmt, ...)\n{\n    if (accessorCookie != NULL && fmt != NULL) {\n        AccessorCookie* ac = (AccessorCookie*)accessorCookie;\n        int retval=0;\n        char buf[1024];\n        va_list ap;\n        va_start(ap, fmt);\n        retval = vsnprintf(buf, sizeof(buf), fmt, ap);\n        va_end(ap);\n        ac->sourcePos.error(\"Error: %s (at '%s' with value '%s').\\n\",\n                            buf, ac->attr.string(), ac->value.string());\n    }\n}\n\nbool ResourceTable::getAttributeKeys(\n    uint32_t attrID, Vector<String16>* outKeys)\n{\n    sp<const Entry> e = getEntry(attrID);\n    if (e != NULL) {\n        const size_t N = e->getBag().size();\n        for (size_t i=0; i<N; i++) {\n            const String16& key = e->getBag().keyAt(i);\n            if (key.size() > 0 && key.string()[0] != '^') {\n                outKeys->add(key);\n            }\n        }\n        return true;\n    }\n    return false;\n}\n\nbool ResourceTable::getAttributeEnum(\n    uint32_t attrID, const char16_t* name, size_t nameLen,\n    Res_value* outValue)\n{\n    //printf(\"getAttributeEnum #%08x %s\\n\", attrID, String8(name, nameLen).string());\n    String16 nameStr(name, nameLen);\n    sp<const Entry> e = getEntry(attrID);\n    if (e != NULL) {\n        const size_t N = e->getBag().size();\n        for (size_t i=0; i<N; i++) {\n            //printf(\"Comparing %s to %s\\n\", String8(name, nameLen).string(),\n            //       String8(e->getBag().keyAt(i)).string());\n            if (e->getBag().keyAt(i) == nameStr) {\n                return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue);\n            }\n        }\n    }\n    return false;\n}\n\nbool ResourceTable::getAttributeFlags(\n    uint32_t attrID, const char16_t* name, size_t nameLen,\n    Res_value* outValue)\n{\n    outValue->dataType = Res_value::TYPE_INT_HEX;\n    outValue->data = 0;\n\n    //printf(\"getAttributeFlags #%08x %s\\n\", attrID, String8(name, nameLen).string());\n    String16 nameStr(name, nameLen);\n    sp<const Entry> e = getEntry(attrID);\n    if (e != NULL) {\n        const size_t N = e->getBag().size();\n\n        const char16_t* end = name + nameLen;\n        const char16_t* pos = name;\n        while (pos < end) {\n            const char16_t* start = pos;\n            while (pos < end && *pos != '|') {\n                pos++;\n            }\n\n            String16 nameStr(start, pos-start);\n            size_t i;\n            for (i=0; i<N; i++) {\n                //printf(\"Comparing \\\"%s\\\" to \\\"%s\\\"\\n\", String8(nameStr).string(),\n                //       String8(e->getBag().keyAt(i)).string());\n                if (e->getBag().keyAt(i) == nameStr) {\n                    Res_value val;\n                    bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val);\n                    if (!got) {\n                        return false;\n                    }\n                    //printf(\"Got value: 0x%08x\\n\", val.data);\n                    outValue->data |= val.data;\n                    break;\n                }\n            }\n\n            if (i >= N) {\n                // Didn't find this flag identifier.\n                return false;\n            }\n            pos++;\n        }\n\n        return true;\n    }\n    return false;\n}\n\nstatus_t ResourceTable::assignResourceIds(Bundle *bundle)\n{\n    const size_t N = mOrderedPackages.size();\n    size_t pi;\n    status_t firstError = NO_ERROR;\n\n    // First generate all bag attributes and assign indices.\n    for (pi=0; pi<N; pi++) {\n        sp<Package> p = mOrderedPackages.itemAt(pi);\n        if (p == NULL || p->getTypes().size() == 0) {\n            // Empty, skip!\n            continue;\n        }\n\n        if (mPackageType == System) {\n            p->movePrivateAttrs();\n        }\n\n        // This has no sense for packages being built as AppFeature (aka with a non-zero offset).\n        status_t err = p->applyPublicTypeOrder();\n        if (err != NO_ERROR && firstError == NO_ERROR) {\n            firstError = err;\n        }\n\n        // Generate attributes...\n        const size_t N = p->getOrderedTypes().size();\n        size_t ti;\n        for (ti=0; ti<N; ti++) {\n            sp<Type> t = p->getOrderedTypes().itemAt(ti);\n            if (t == NULL) {\n                continue;\n            }\n            const size_t N = t->getOrderedConfigs().size();\n            for (size_t ci=0; ci<N; ci++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);\n                if (c == NULL) {\n                    continue;\n                }\n                const size_t N = c->getEntries().size();\n                for (size_t ei=0; ei<N; ei++) {\n                    sp<Entry> e = c->getEntries().valueAt(ei);\n                    if (e == NULL) {\n                        continue;\n                    }\n                    status_t err = e->generateAttributes(this, p->getName());\n                    if (err != NO_ERROR && firstError == NO_ERROR) {\n                        firstError = err;\n                    }\n                }\n            }\n        }\n\n        uint32_t typeIdOffset = 0;\n        if (mPackageType == AppFeature && p->getName() == mAssetsPackage) {\n            typeIdOffset = mTypeIdOffset;\n        }\n\n        const SourcePos unknown(String8(\"????\"), 0);\n        sp<Type> attr = p->getType(String16(\"attr\"), unknown);\n\n        // Assign indices...\n        const size_t typeCount = p->getOrderedTypes().size();\n        for (size_t ti = 0; ti < typeCount; ti++) {\n            sp<Type> t = p->getOrderedTypes().itemAt(ti);\n            if (t == NULL) {\n                continue;\n            }\n\n            err = t->applyPublicEntryOrder(mBundle->getBaselinePackage().size() > 0);\n            if (err != NO_ERROR && firstError == NO_ERROR) {\n                firstError = err;\n            }\n\n            const size_t N = t->getOrderedConfigs().size();\n            t->setIndex(ti + 1 + typeIdOffset);\n\n            LOG_ALWAYS_FATAL_IF(ti == 0 && attr != t,\n                                \"First type is not attr!\");\n\n            for (size_t ei=0; ei<N; ei++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ei);\n                if (c == NULL) {\n                    continue;\n                }\n                c->setEntryIndex(ei);\n            }\n        }\n\n\n        // Assign resource IDs to keys in bags...\n        for (size_t ti = 0; ti < typeCount; ti++) {\n            sp<Type> t = p->getOrderedTypes().itemAt(ti);\n            if (t == NULL) {\n                continue;\n            }\n\n            const size_t N = t->getOrderedConfigs().size();\n            for (size_t ci=0; ci<N; ci++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);\n                if (c == NULL) {\n                    continue;\n                }\n                //printf(\"Ordered config #%d: %p\\n\", ci, c.get());\n                const size_t N = c->getEntries().size();\n                for (size_t ei=0; ei<N; ei++) {\n                    sp<Entry> e = c->getEntries().valueAt(ei);\n                    if (e == NULL) {\n                        continue;\n                    }\n                    status_t err = e->assignResourceIds(this, p->getName(), bundle);\n                    if (err != NO_ERROR && firstError == NO_ERROR) {\n                        firstError = err;\n                    }\n                }\n            }\n        }\n    }\n    return firstError;\n}\n\nstatus_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols,\n        bool skipSymbolsWithoutDefaultLocalization) {\n    const size_t N = mOrderedPackages.size();\n    const String8 defaultLocale;\n    const String16 stringType(\"string\");\n    size_t pi;\n\n    for (pi=0; pi<N; pi++) {\n        sp<Package> p = mOrderedPackages.itemAt(pi);\n        if (p->getTypes().size() == 0) {\n            // Empty, skip!\n            continue;\n        }\n\n        const size_t N = p->getOrderedTypes().size();\n        size_t ti;\n\n        for (ti=0; ti<N; ti++) {\n            sp<Type> t = p->getOrderedTypes().itemAt(ti);\n            if (t == NULL) {\n                continue;\n            }\n\n            const size_t N = t->getOrderedConfigs().size();\n            sp<AaptSymbols> typeSymbols;\n            if (t->getName() == String16(kAttrPrivateType)) {\n                typeSymbols = outSymbols->addNestedSymbol(String8(\"attr\"), t->getPos());\n            } else {\n                typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos());\n            }\n\n            if (typeSymbols == NULL) {\n                return UNKNOWN_ERROR;\n            }\n\n            for (size_t ci=0; ci<N; ci++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);\n                if (c == NULL) {\n                    continue;\n                }\n                uint32_t rid = getResId(p, t, ci);\n                if (rid == 0) {\n                    return UNKNOWN_ERROR;\n                }\n                if (Res_GETPACKAGE(rid) + 1 == p->getAssignedId()) {\n\n                    if (skipSymbolsWithoutDefaultLocalization &&\n                            t->getName() == stringType) {\n\n                        // Don't generate symbols for strings without a default localization.\n                        if (mHasDefaultLocalization.find(c->getName())\n                                == mHasDefaultLocalization.end()) {\n                            // printf(\"Skip symbol [%08x] %s\\n\", rid,\n                            //          String8(c->getName()).string());\n                            continue;\n                        }\n                    }\n\n                    typeSymbols->addSymbol(String8(c->getName()), rid, c->getPos());\n                    \n                    String16 comment(c->getComment());\n                    typeSymbols->appendComment(String8(c->getName()), comment, c->getPos());\n                    //printf(\"Type symbol [%08x] %s comment: %s\\n\", rid,\n                    //        String8(c->getName()).string(), String8(comment).string());\n                    comment = c->getTypeComment();\n                    typeSymbols->appendTypeComment(String8(c->getName()), comment);\n                }\n            }\n        }\n    }\n    return NO_ERROR;\n}\n\n\nvoid\nResourceTable::addLocalization(const String16& name, const String8& locale, const SourcePos& src)\n{\n    mLocalizations[name][locale] = src;\n}\n\nvoid\nResourceTable::addDefaultLocalization(const String16& name)\n{\n    mHasDefaultLocalization.insert(name);\n}\n\n\n/*!\n * Flag various sorts of localization problems.  '+' indicates checks already implemented;\n * '-' indicates checks that will be implemented in the future.\n *\n * + A localized string for which no default-locale version exists => warning\n * + A string for which no version in an explicitly-requested locale exists => warning\n * + A localized translation of an translateable=\"false\" string => warning\n * - A localized string not provided in every locale used by the table\n */\nstatus_t\nResourceTable::validateLocalizations(void)\n{\n    status_t err = NO_ERROR;\n    const String8 defaultLocale;\n\n    // For all strings...\n    for (const auto& nameIter : mLocalizations) {\n        const std::map<String8, SourcePos>& configSrcMap = nameIter.second;\n\n        // Look for strings with no default localization\n        if (configSrcMap.count(defaultLocale) == 0) {\n            SourcePos().warning(\"string '%s' has no default translation.\",\n                    String8(nameIter.first).string());\n            if (mBundle->getVerbose()) {\n                for (const auto& locale : configSrcMap) {\n                    locale.second.printf(\"locale %s found\", locale.first.string());\n                }\n            }\n            // !!! TODO: throw an error here in some circumstances\n        }\n\n        // Check that all requested localizations are present for this string\n        if (mBundle->getConfigurations().size() > 0 && mBundle->getRequireLocalization()) {\n            const char* allConfigs = mBundle->getConfigurations().string();\n            const char* start = allConfigs;\n            const char* comma;\n\n            std::set<String8> missingConfigs;\n            AaptLocaleValue locale;\n            do {\n                String8 config;\n                comma = strchr(start, ',');\n                if (comma != NULL) {\n                    config.setTo(start, comma - start);\n                    start = comma + 1;\n                } else {\n                    config.setTo(start);\n                }\n\n                if (!locale.initFromFilterString(config)) {\n                    continue;\n                }\n\n                // don't bother with the pseudolocale \"en_XA\" or \"ar_XB\"\n                if (config != \"en_XA\" && config != \"ar_XB\") {\n                    if (configSrcMap.find(config) == configSrcMap.end()) {\n                        // okay, no specific localization found.  it's possible that we are\n                        // requiring a specific regional localization [e.g. de_DE] but there is an\n                        // available string in the generic language localization [e.g. de];\n                        // consider that string to have fulfilled the localization requirement.\n                        String8 region(config.string(), 2);\n                        if (configSrcMap.find(region) == configSrcMap.end() &&\n                                configSrcMap.count(defaultLocale) == 0) {\n                            missingConfigs.insert(config);\n                        }\n                    }\n                }\n            } while (comma != NULL);\n\n            if (!missingConfigs.empty()) {\n                String8 configStr;\n                for (const auto& iter : missingConfigs) {\n                    configStr.appendFormat(\" %s\", iter.string());\n                }\n                SourcePos().warning(\"string '%s' is missing %u required localizations:%s\",\n                        String8(nameIter.first).string(),\n                        (unsigned int)missingConfigs.size(),\n                        configStr.string());\n            }\n        }\n    }\n\n    return err;\n}\n\nstatus_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,\n        const sp<AaptFile>& dest,\n        const bool isBase)\n{\n    const ConfigDescription nullConfig;\n\n    const size_t N = mOrderedPackages.size();\n    size_t pi;\n\n    const static String16 mipmap16(\"mipmap\");\n\n    bool useUTF8 = !bundle->getUTF16StringsOption();\n\n    // The libraries this table references.\n    Vector<sp<Package> > libraryPackages;\n    const ResTable& table = mAssets->getIncludedResources();\n    const size_t basePackageCount = table.getBasePackageCount();\n    for (size_t i = 0; i < basePackageCount; i++) {\n        size_t packageId = table.getBasePackageId(i);\n        String16 packageName(table.getBasePackageName(i));\n        if (packageId > 0x01 && packageId != customePackageId&&\n                packageName != String16(\"android\")) {\n            libraryPackages.add(sp<Package>(new Package(packageName, packageId)));\n        }\n    }\n\n    // Iterate through all data, collecting all values (strings,\n    // references, etc).\n    StringPool valueStrings(useUTF8);\n    Vector<sp<Entry> > allEntries;\n    for (pi=0; pi<N; pi++) {\n        sp<Package> p = mOrderedPackages.itemAt(pi);\n        if (p->getTypes().size() == 0) {\n            continue;\n        }\n        const String16 packageName(p->getName());\n\n        StringPool typeStrings(useUTF8);\n        StringPool keyStrings(useUTF8);\n\n        ssize_t stringsAdded = 0;\n        const size_t N = p->getOrderedTypes().size();\n        for (size_t ti=0; ti<N; ti++) {\n            sp<Type> t = p->getOrderedTypes().itemAt(ti);\n            if (t == NULL) {\n                typeStrings.add(String16(\"<empty>\"), false);\n                stringsAdded++;\n                continue;\n            }\n\n            while (stringsAdded < t->getIndex() - 1) {\n                typeStrings.add(String16(\"<empty>\"), false);\n                stringsAdded++;\n            }\n\n            const String16 typeName(t->getName());\n            typeStrings.add(typeName, false);\n            stringsAdded++;\n\n            // This is a hack to tweak the sorting order of the final strings,\n            // to put stuff that is generally not language-specific first.\n            String8 configTypeName(typeName);\n            if (configTypeName == \"drawable\" || configTypeName == \"layout\"\n                    || configTypeName == \"color\" || configTypeName == \"anim\"\n                    || configTypeName == \"interpolator\" || configTypeName == \"animator\"\n                    || configTypeName == \"xml\" || configTypeName == \"menu\"\n                    || configTypeName == \"mipmap\" || configTypeName == \"raw\") {\n                configTypeName = \"1complex\";\n            } else {\n                configTypeName = \"2value\";\n            }\n\n            // mipmaps don't get filtered, so they will\n            // allways end up in the base. Make sure they\n            // don't end up in a split.\n            if (typeName == mipmap16 && !isBase) {\n                continue;\n            }\n\n            const bool filterable = (typeName != mipmap16);\n\n            if (bundle->getBaselinePackage().size() <= 0) {\n                for (size_t ci=0; ci<0x7f; ci++) {\n                    String16 value(\"false\");\n                    status_t err = addEntry(SourcePos(), packageName, typeName, String16(String8::format(\"%s_%zu\", String8(value).string(), ci)), value);\n                    if (err != NO_ERROR) {\n                        return err;\n                    }\n                }\n            }\n            const size_t N = t->getOrderedConfigs().size();\n            for (size_t ci=0; ci<N; ci++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);\n                if (c == NULL) {\n                    continue;\n                }\n                const size_t N = c->getEntries().size();\n                for (size_t ei=0; ei<N; ei++) {\n                    ConfigDescription config = c->getEntries().keyAt(ei);\n                    if (filterable && !filter->match(config)) {\n                        continue;\n                    }\n                    sp<Entry> e = c->getEntries().valueAt(ei);\n                    if (e == NULL) {\n                        continue;\n                    }\n                    e->setNameIndex(keyStrings.add(e->getName(), true));\n\n                    // If this entry has no values for other configs,\n                    // and is the default config, then it is special.  Otherwise\n                    // we want to add it with the config info.\n                    ConfigDescription* valueConfig = NULL;\n                    if (N != 1 || config == nullConfig) {\n                        valueConfig = &config;\n                    }\n\n                    status_t err = e->prepareFlatten(&valueStrings, this,\n                            &configTypeName, &config);\n                    if (err != NO_ERROR) {\n                        return err;\n                    }\n                    allEntries.add(e);\n                }\n            }\n        }\n\n        p->setTypeStrings(typeStrings.createStringBlock());\n        p->setKeyStrings(keyStrings.createStringBlock());\n    }\n\n    if (bundle->getOutputAPKFile() != NULL) {\n        // Now we want to sort the value strings for better locality.  This will\n        // cause the positions of the strings to change, so we need to go back\n        // through out resource entries and update them accordingly.  Only need\n        // to do this if actually writing the output file.\n        valueStrings.sortByConfig();\n        for (pi=0; pi<allEntries.size(); pi++) {\n            allEntries[pi]->remapStringValue(&valueStrings);\n        }\n    }\n\n    ssize_t strAmt = 0;\n\n    // Now build the array of package chunks.\n    Vector<sp<AaptFile> > flatPackages;\n    for (pi=0; pi<N; pi++) {\n        sp<Package> p = mOrderedPackages.itemAt(pi);\n        if (p->getTypes().size() == 0) {\n            // Empty, skip!\n            continue;\n        }\n\n        const size_t N = p->getTypeStrings().size();\n\n        const size_t baseSize = sizeof(ResTable_package);\n\n        // Start the package data.\n        sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());\n        ResTable_package* header = (ResTable_package*)data->editData(baseSize);\n        if (header == NULL) {\n            fprintf(stderr, \"ERROR: out of memory creating ResTable_package\\n\");\n            return NO_MEMORY;\n        }\n        memset(header, 0, sizeof(*header));\n        header->header.type = htods(RES_TABLE_PACKAGE_TYPE);\n        header->header.headerSize = htods(sizeof(*header));\n        header->id = htodl(static_cast<uint32_t>(p->getAssignedId()));\n        strcpy16_htod(header->name, sktPackageName? \n                                    String16(sktPackageName):\n                                    p->getName().string());\n\n        // Write the string blocks.\n        const size_t typeStringsStart = data->getSize();\n        sp<AaptFile> strFile = p->getTypeStringsData();\n        ssize_t amt = data->writeData(strFile->getData(), strFile->getSize());\n        if (kPrintStringMetrics) {\n            fprintf(stderr, \"**** type strings: %zd\\n\", SSIZE(amt));\n        }\n        strAmt += amt;\n        if (amt < 0) {\n            return amt;\n        }\n        const size_t keyStringsStart = data->getSize();\n        strFile = p->getKeyStringsData();\n        amt = data->writeData(strFile->getData(), strFile->getSize());\n        if (kPrintStringMetrics) {\n            fprintf(stderr, \"**** key strings: %zd\\n\", SSIZE(amt));\n        }\n        strAmt += amt;\n        if (amt < 0) {\n            return amt;\n        }\n\n        if (isBase) {\n            status_t err = flattenLibraryTable(data, libraryPackages);\n            if (err != NO_ERROR) {\n                fprintf(stderr, \"ERROR: failed to write library table\\n\");\n                return err;\n            }\n        }\n\n        // Build the type chunks inside of this package.\n        for (size_t ti=0; ti<N; ti++) {\n            // Retrieve them in the same order as the type string block.\n            size_t len;\n            String16 typeName(p->getTypeStrings().stringAt(ti, &len));\n            sp<Type> t = p->getTypes().valueFor(typeName);\n            LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16(\"<empty>\"),\n                                \"Type name %s not found\",\n                                String8(typeName).string());\n            if (t == NULL) {\n                continue;\n            }\n            const bool filterable = (typeName != mipmap16);\n            const bool skipEntireType = (typeName == mipmap16 && !isBase);\n\n            const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0;\n\n            // Until a non-NO_ENTRY value has been written for a resource,\n            // that resource is invalid; validResources[i] represents\n            // the item at t->getOrderedConfigs().itemAt(i).\n            Vector<bool> validResources;\n            validResources.insertAt(false, 0, N);\n            \n            // First write the typeSpec chunk, containing information about\n            // each resource entry in this type.\n            {\n                const size_t typeSpecSize = sizeof(ResTable_typeSpec) + sizeof(uint32_t)*N;\n                const size_t typeSpecStart = data->getSize();\n                ResTable_typeSpec* tsHeader = (ResTable_typeSpec*)\n                    (((uint8_t*)data->editData(typeSpecStart+typeSpecSize)) + typeSpecStart);\n                if (tsHeader == NULL) {\n                    fprintf(stderr, \"ERROR: out of memory creating ResTable_typeSpec\\n\");\n                    return NO_MEMORY;\n                }\n                memset(tsHeader, 0, sizeof(*tsHeader));\n                tsHeader->header.type = htods(RES_TABLE_TYPE_SPEC_TYPE);\n                tsHeader->header.headerSize = htods(sizeof(*tsHeader));\n                tsHeader->header.size = htodl(typeSpecSize);\n                tsHeader->id = ti+1;\n                tsHeader->entryCount = htodl(N);\n                \n                uint32_t* typeSpecFlags = (uint32_t*)\n                    (((uint8_t*)data->editData())\n                        + typeSpecStart + sizeof(ResTable_typeSpec));\n                memset(typeSpecFlags, 0, sizeof(uint32_t)*N);\n\n                for (size_t ei=0; ei<N; ei++) {\n                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);\n                    if (cl == NULL) {\n                        continue;\n                    }\n\n                    if (cl->getPublic()) {\n                        typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC);\n                    }\n\n                    if (skipEntireType) {\n                        continue;\n                    }\n\n                    const size_t CN = cl->getEntries().size();\n                    for (size_t ci=0; ci<CN; ci++) {\n                        if (filterable && !filter->match(cl->getEntries().keyAt(ci))) {\n                            continue;\n                        }\n                        for (size_t cj=ci+1; cj<CN; cj++) {\n                            if (filterable && !filter->match(cl->getEntries().keyAt(cj))) {\n                                continue;\n                            }\n                            typeSpecFlags[ei] |= htodl(\n                                cl->getEntries().keyAt(ci).diff(cl->getEntries().keyAt(cj)));\n                        }\n                    }\n                }\n            }\n            \n            if (skipEntireType) {\n                continue;\n            }\n\n            // We need to write one type chunk for each configuration for\n            // which we have entries in this type.\n            SortedVector<ConfigDescription> uniqueConfigs;\n            if (t != NULL) {\n                uniqueConfigs = t->getUniqueConfigs();\n            }\n            \n            const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N;\n            \n            const size_t NC = uniqueConfigs.size();\n            for (size_t ci=0; ci<NC; ci++) {\n                const ConfigDescription& config = uniqueConfigs[ci];\n\n                if (kIsDebug) {\n                    printf(\"Writing config %zu config: imsi:%d/%d lang:%c%c cnt:%c%c \"\n                        \"orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d \"\n                        \"sw%ddp w%ddp h%ddp layout:%d\\n\",\n                        ti + 1,\n                        config.mcc, config.mnc,\n                        config.language[0] ? config.language[0] : '-',\n                        config.language[1] ? config.language[1] : '-',\n                        config.country[0] ? config.country[0] : '-',\n                        config.country[1] ? config.country[1] : '-',\n                        config.orientation,\n                        config.uiMode,\n                        config.touchscreen,\n                        config.density,\n                        config.keyboard,\n                        config.inputFlags,\n                        config.navigation,\n                        config.screenWidth,\n                        config.screenHeight,\n                        config.smallestScreenWidthDp,\n                        config.screenWidthDp,\n                        config.screenHeightDp,\n                        config.screenLayout);\n                }\n                      \n                if (filterable && !filter->match(config)) {\n                    continue;\n                }\n                \n                const size_t typeStart = data->getSize();\n\n                ResTable_type* tHeader = (ResTable_type*)\n                    (((uint8_t*)data->editData(typeStart+typeSize)) + typeStart);\n                if (tHeader == NULL) {\n                    fprintf(stderr, \"ERROR: out of memory creating ResTable_type\\n\");\n                    return NO_MEMORY;\n                }\n\n                memset(tHeader, 0, sizeof(*tHeader));\n                tHeader->header.type = htods(RES_TABLE_TYPE_TYPE);\n                tHeader->header.headerSize = htods(sizeof(*tHeader));\n                tHeader->id = ti+1;\n                tHeader->entryCount = htodl(N);\n                tHeader->entriesStart = htodl(typeSize);\n                tHeader->config = config;\n                if (kIsDebug) {\n                    printf(\"Writing type %zu config: imsi:%d/%d lang:%c%c cnt:%c%c \"\n                        \"orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d \"\n                        \"sw%ddp w%ddp h%ddp layout:%d\\n\",\n                        ti + 1,\n                        tHeader->config.mcc, tHeader->config.mnc,\n                        tHeader->config.language[0] ? tHeader->config.language[0] : '-',\n                        tHeader->config.language[1] ? tHeader->config.language[1] : '-',\n                        tHeader->config.country[0] ? tHeader->config.country[0] : '-',\n                        tHeader->config.country[1] ? tHeader->config.country[1] : '-',\n                        tHeader->config.orientation,\n                        tHeader->config.uiMode,\n                        tHeader->config.touchscreen,\n                        tHeader->config.density,\n                        tHeader->config.keyboard,\n                        tHeader->config.inputFlags,\n                        tHeader->config.navigation,\n                        tHeader->config.screenWidth,\n                        tHeader->config.screenHeight,\n                        tHeader->config.smallestScreenWidthDp,\n                        tHeader->config.screenWidthDp,\n                        tHeader->config.screenHeightDp,\n                        tHeader->config.screenLayout);\n                }\n                tHeader->config.swapHtoD();\n\n                // Build the entries inside of this type.\n                for (size_t ei=0; ei<N; ei++) {\n                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);\n                    sp<Entry> e = NULL;\n                    if (cl != NULL) {\n                        e = cl->getEntries().valueFor(config);\n                    }\n\n                    // Set the offset for this entry in its type.\n                    uint32_t* index = (uint32_t*)\n                        (((uint8_t*)data->editData())\n                            + typeStart + sizeof(ResTable_type));\n                    if (e != NULL) {\n                        index[ei] = htodl(data->getSize()-typeStart-typeSize);\n\n                        // Create the entry.\n                        ssize_t amt = e->flatten(bundle, data, cl->getPublic());\n                        if (amt < 0) {\n                            return amt;\n                        }\n                        validResources.editItemAt(ei) = true;\n                    } else {\n                        index[ei] = htodl(ResTable_type::NO_ENTRY);\n                    }\n                }\n\n                // Fill in the rest of the type information.\n                tHeader = (ResTable_type*)\n                    (((uint8_t*)data->editData()) + typeStart);\n                tHeader->header.size = htodl(data->getSize()-typeStart);\n            }\n\n            // If we're building splits, then each invocation of the flattening\n            // step will have 'missing' entries. Don't warn/error for this case.\n            if (bundle->getSplitConfigurations().isEmpty()) {\n                bool missing_entry = false;\n                const char* log_prefix = bundle->getErrorOnMissingConfigEntry() ?\n                        \"error\" : \"warning\";\n                for (size_t i = 0; i < N; ++i) {\n                    if (!validResources[i]) {\n                        sp<ConfigList> c = t->getOrderedConfigs().itemAt(i);\n                        if (c != NULL) {\n                            fprintf(stderr, \"%s: no entries written for %s/%s (0x%08zx)\\n\", log_prefix,\n                                    String8(typeName).string(), String8(c->getName()).string(),\n                                    Res_MAKEID(p->getAssignedId() - 1, ti, i));\n                        }\n                        missing_entry = true;\n                    }\n                }\n                if (bundle->getErrorOnMissingConfigEntry() && missing_entry) {\n                    fprintf(stderr, \"Error: Missing entries, quit!\\n\");\n                    return NOT_ENOUGH_DATA;\n                }\n            }\n        }\n\n        // Fill in the rest of the package information.\n        header = (ResTable_package*)data->editData();\n        header->header.size = htodl(data->getSize());\n        header->typeStrings = htodl(typeStringsStart);\n        header->lastPublicType = htodl(p->getTypeStrings().size());\n        header->keyStrings = htodl(keyStringsStart);\n        header->lastPublicKey = htodl(p->getKeyStrings().size());\n\n        flatPackages.add(data);\n    }\n\n    // And now write out the final chunks.\n    const size_t dataStart = dest->getSize();\n\n    {\n        // blah\n        ResTable_header header;\n        memset(&header, 0, sizeof(header));\n        header.header.type = htods(RES_TABLE_TYPE);\n        header.header.headerSize = htods(sizeof(header));\n        header.packageCount = htodl(flatPackages.size());\n        status_t err = dest->writeData(&header, sizeof(header));\n        if (err != NO_ERROR) {\n            fprintf(stderr, \"ERROR: out of memory creating ResTable_header\\n\");\n            return err;\n        }\n    }\n    \n    ssize_t strStart = dest->getSize();\n    status_t err = valueStrings.writeStringBlock(dest);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    ssize_t amt = (dest->getSize()-strStart);\n    strAmt += amt;\n    if (kPrintStringMetrics) {\n        fprintf(stderr, \"**** value strings: %zd\\n\", SSIZE(amt));\n        fprintf(stderr, \"**** total strings: %zd\\n\", SSIZE(strAmt));\n    }\n\n    for (pi=0; pi<flatPackages.size(); pi++) {\n        err = dest->writeData(flatPackages[pi]->getData(),\n                              flatPackages[pi]->getSize());\n        if (err != NO_ERROR) {\n            fprintf(stderr, \"ERROR: out of memory creating package chunk for ResTable_header\\n\");\n            return err;\n        }\n    }\n\n    ResTable_header* header = (ResTable_header*)\n        (((uint8_t*)dest->getData()) + dataStart);\n    header->header.size = htodl(dest->getSize() - dataStart);\n\n    if (kPrintStringMetrics) {\n        fprintf(stderr, \"**** total resource table size: %zu / %zu%% strings\\n\",\n                dest->getSize(), (size_t)(strAmt*100)/dest->getSize());\n    }\n    \n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs) {\n    // Write out the library table if necessary\n    if (libs.size() > 0) {\n        if (kIsDebug) {\n            fprintf(stderr, \"Writing library reference table\\n\");\n        }\n\n        const size_t libStart = dest->getSize();\n        const size_t count = libs.size();\n        ResTable_lib_header* libHeader = (ResTable_lib_header*) dest->editDataInRange(\n                libStart, sizeof(ResTable_lib_header));\n\n        memset(libHeader, 0, sizeof(*libHeader));\n        libHeader->header.type = htods(RES_TABLE_LIBRARY_TYPE);\n        libHeader->header.headerSize = htods(sizeof(*libHeader));\n        libHeader->header.size = htodl(sizeof(*libHeader) + (sizeof(ResTable_lib_entry) * count));\n        libHeader->count = htodl(count);\n\n        // Write the library entries\n        for (size_t i = 0; i < count; i++) {\n            const size_t entryStart = dest->getSize();\n            sp<Package> libPackage = libs[i];\n            if (kIsDebug) {\n                fprintf(stderr, \"  Entry %s -> 0x%02x\\n\",\n                        String8(libPackage->getName()).string(),\n                        (uint8_t)libPackage->getAssignedId());\n            }\n\n            ResTable_lib_entry* entry = (ResTable_lib_entry*) dest->editDataInRange(\n                    entryStart, sizeof(ResTable_lib_entry));\n            memset(entry, 0, sizeof(*entry));\n            entry->packageId = htodl(libPackage->getAssignedId());\n            strcpy16_htod(entry->packageName, libPackage->getName().string());\n        }\n    }\n    return NO_ERROR;\n}\n\nvoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp)\n{\n    fprintf(fp,\n    \"<!-- This file contains <public> resource definitions for all\\n\"\n    \"     resources that were generated from the source data. -->\\n\"\n    \"\\n\"\n    \"<resources>\\n\");\n\n    writePublicDefinitions(package, fp, true);\n    writePublicDefinitions(package, fp, false);\n\n    fprintf(fp,\n    \"\\n\"\n    \"</resources>\\n\");\n}\n\nvoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp, bool pub)\n{\n    bool didHeader = false;\n\n    sp<Package> pkg = mPackages.valueFor(package);\n    if (pkg != NULL) {\n        const size_t NT = pkg->getOrderedTypes().size();\n        for (size_t i=0; i<NT; i++) {\n            sp<Type> t = pkg->getOrderedTypes().itemAt(i);\n            if (t == NULL) {\n                continue;\n            }\n\n            bool didType = false;\n\n            const size_t NC = t->getOrderedConfigs().size();\n            for (size_t j=0; j<NC; j++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(j);\n                if (c == NULL) {\n                    continue;\n                }\n\n                if (c->getPublic() != pub) {\n                    continue;\n                }\n\n                int32_t ei = c->getEntryIndex();\n                if (ei < 0) continue;\n\n                if (!didType) {\n                    fprintf(fp, \"\\n\");\n                    didType = true;\n                }\n                if (!didHeader) {\n                    if (pub) {\n                        fprintf(fp,\"  <!-- PUBLIC SECTION.  These resources have been declared public.\\n\");\n                        fprintf(fp,\"       Changes to these definitions will break binary compatibility. -->\\n\\n\");\n                    } else {\n                        fprintf(fp,\"  <!-- PRIVATE SECTION.  These resources have not been declared public.\\n\");\n                        fprintf(fp,\"       You can make them public my moving these lines into a file in res/values. -->\\n\\n\");\n                    }\n                    didHeader = true;\n                }\n                if (!pub) {\n                    const size_t NE = c->getEntries().size();\n                    for (size_t k=0; k<NE; k++) {\n                        const SourcePos& pos = c->getEntries().valueAt(k)->getPos();\n                        if (pos.file != \"\") {\n                            fprintf(fp,\"  <!-- Declared at %s:%d -->\\n\",\n                                    pos.file.string(), pos.line);\n                        }\n                    }\n                }\n                fprintf(fp, \"  <public type=\\\"%s\\\" name=\\\"%s\\\" id=\\\"0x%08x\\\" />\\n\",\n                        String8(t->getName()).string(),\n                        String8(c->getName()).string(),\n                        getResId(pkg, t, ei));\n            }\n        }\n    }\n}\n\nResourceTable::Item::Item(const SourcePos& _sourcePos,\n                          bool _isId,\n                          const String16& _value,\n                          const Vector<StringPool::entry_style_span>* _style,\n                          int32_t _format)\n    : sourcePos(_sourcePos)\n    , isId(_isId)\n    , value(_value)\n    , format(_format)\n    , bagKeyId(0)\n    , evaluating(false)\n{\n    if (_style) {\n        style = *_style;\n    }\n}\n\nResourceTable::Entry::Entry(const Entry& entry)\n    : RefBase()\n    , mName(entry.mName)\n    , mParent(entry.mParent)\n    , mType(entry.mType)\n    , mItem(entry.mItem)\n    , mItemFormat(entry.mItemFormat)\n    , mBag(entry.mBag)\n    , mNameIndex(entry.mNameIndex)\n    , mParentId(entry.mParentId)\n    , mPos(entry.mPos) {}\n\nResourceTable::Entry& ResourceTable::Entry::operator=(const Entry& entry) {\n    mName = entry.mName;\n    mParent = entry.mParent;\n    mType = entry.mType;\n    mItem = entry.mItem;\n    mItemFormat = entry.mItemFormat;\n    mBag = entry.mBag;\n    mNameIndex = entry.mNameIndex;\n    mParentId = entry.mParentId;\n    mPos = entry.mPos;\n    return *this;\n}\n\nstatus_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos)\n{\n    if (mType == TYPE_BAG) {\n        return NO_ERROR;\n    }\n    if (mType == TYPE_UNKNOWN) {\n        mType = TYPE_BAG;\n        return NO_ERROR;\n    }\n    sourcePos.error(\"Resource entry %s is already defined as a single item.\\n\"\n                    \"%s:%d: Originally defined here.\\n\",\n                    String8(mName).string(),\n                    mItem.sourcePos.file.string(), mItem.sourcePos.line);\n    return UNKNOWN_ERROR;\n}\n\nstatus_t ResourceTable::Entry::setItem(const SourcePos& sourcePos,\n                                       const String16& value,\n                                       const Vector<StringPool::entry_style_span>* style,\n                                       int32_t format,\n                                       const bool overwrite)\n{\n    Item item(sourcePos, false, value, style);\n\n    if (mType == TYPE_BAG) {\n        if (mBag.size() == 0) {\n            sourcePos.error(\"Resource entry %s is already defined as a bag.\",\n                    String8(mName).string());\n        } else {\n            const Item& item(mBag.valueAt(0));\n            sourcePos.error(\"Resource entry %s is already defined as a bag.\\n\"\n                            \"%s:%d: Originally defined here.\\n\",\n                            String8(mName).string(),\n                            item.sourcePos.file.string(), item.sourcePos.line);\n        }\n        return UNKNOWN_ERROR;\n    }\n    if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) {\n        sourcePos.error(\"Resource entry %s is already defined.\\n\"\n                        \"%s:%d: Originally defined here.\\n\",\n                        String8(mName).string(),\n                        mItem.sourcePos.file.string(), mItem.sourcePos.line);\n        return UNKNOWN_ERROR;\n    }\n\n    mType = TYPE_ITEM;\n    mItem = item;\n    mItemFormat = format;\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Entry::addToBag(const SourcePos& sourcePos,\n                                        const String16& key, const String16& value,\n                                        const Vector<StringPool::entry_style_span>* style,\n                                        bool replace, bool isId, int32_t format)\n{\n    status_t err = makeItABag(sourcePos);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    Item item(sourcePos, isId, value, style, format);\n    \n    // XXX NOTE: there is an error if you try to have a bag with two keys,\n    // one an attr and one an id, with the same name.  Not something we\n    // currently ever have to worry about.\n    ssize_t origKey = mBag.indexOfKey(key);\n    if (origKey >= 0) {\n        if (!replace) {\n            const Item& item(mBag.valueAt(origKey));\n            sourcePos.error(\"Resource entry %s already has bag item %s.\\n\"\n                    \"%s:%d: Originally defined here.\\n\",\n                    String8(mName).string(), String8(key).string(),\n                    item.sourcePos.file.string(), item.sourcePos.line);\n            return UNKNOWN_ERROR;\n        }\n        //printf(\"Replacing %s with %s\\n\",\n        //       String8(mBag.valueFor(key).value).string(), String8(value).string());\n        mBag.replaceValueFor(key, item);\n    }\n\n    mBag.add(key, item);\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Entry::removeFromBag(const String16& key) {\n    if (mType != Entry::TYPE_BAG) {\n        return NO_ERROR;\n    }\n\n    if (mBag.removeItem(key) >= 0) {\n        return NO_ERROR;\n    }\n    return UNKNOWN_ERROR;\n}\n\nstatus_t ResourceTable::Entry::emptyBag(const SourcePos& sourcePos)\n{\n    status_t err = makeItABag(sourcePos);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    mBag.clear();\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Entry::generateAttributes(ResourceTable* table,\n                                                  const String16& package)\n{\n    const String16 attr16(\"attr\");\n    const String16 id16(\"id\");\n    const size_t N = mBag.size();\n    for (size_t i=0; i<N; i++) {\n        const String16& key = mBag.keyAt(i);\n        const Item& it = mBag.valueAt(i);\n        if (it.isId) {\n            if (!table->hasBagOrEntry(key, &id16, &package)) {\n                String16 value(\"false\");\n                if (kIsDebug) {\n                    fprintf(stderr, \"Generating %s:id/%s\\n\",\n                            String8(package).string(),\n                            String8(key).string());\n                }\n                status_t err = table->addEntry(SourcePos(String8(\"<generated>\"), 0), package,\n                                               id16, key, value);\n                if (err != NO_ERROR) {\n                    return err;\n                }\n            }\n        } else if (!table->hasBagOrEntry(key, &attr16, &package)) {\n\n#if 1\n//             fprintf(stderr, \"ERROR: Bag attribute '%s' has not been defined.\\n\",\n//                     String8(key).string());\n//             const Item& item(mBag.valueAt(i));\n//             fprintf(stderr, \"Referenced from file %s line %d\\n\",\n//                     item.sourcePos.file.string(), item.sourcePos.line);\n//             return UNKNOWN_ERROR;\n#else\n            char numberStr[16];\n            sprintf(numberStr, \"%d\", ResTable_map::TYPE_ANY);\n            status_t err = table->addBag(SourcePos(\"<generated>\", 0), package,\n                                         attr16, key, String16(\"\"),\n                                         String16(\"^type\"),\n                                         String16(numberStr), NULL, NULL);\n            if (err != NO_ERROR) {\n                return err;\n            }\n#endif\n        }\n    }\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Entry::assignResourceIds(ResourceTable* table,\n                                                 const String16& /*package*/,\n                                                 Bundle* /*bundle*/)\n{\n    bool hasErrors = false;\n    \n    if (mType == TYPE_BAG) {\n        const char* errorMsg;\n        const String16 style16(\"style\");\n        const String16 attr16(\"attr\");\n        const String16 id16(\"id\");\n        mParentId = 0;\n        if (mParent.size() > 0) {\n            mParentId = table->getResId(mParent, &style16, NULL, &errorMsg);\n            if (mParentId == 0 && sktPackageName != NULL) {\n                String16 defPackage = String16(sktPackageName);\n                mParentId = table->getResId(mParent, &style16, &defPackage, &errorMsg, false);\n            }\n\n            if (mParentId == 0) {\n                mPos.error(\"Error retrieving parent for item: %s '%s'.\\n\",\n                        errorMsg, String8(mParent).string());\n                hasErrors = true;\n            }\n        }\n        const size_t N = mBag.size();\n        for (size_t i=0; i<N; i++) {\n            const String16& key = mBag.keyAt(i);\n            Item& it = mBag.editValueAt(i);\n            it.bagKeyId = table->getResId(key,\n                    it.isId ? &id16 : &attr16, NULL, &errorMsg);\n            //printf(\"Bag key of %s: #%08x\\n\", String8(key).string(), it.bagKeyId);\n            if (it.bagKeyId == 0 && sktPackageName != NULL) {\n                String16 defPackage = String16(sktPackageName);\n                it.bagKeyId = table->getResId(key,\n                    it.isId ? &id16 : &attr16, &defPackage, &errorMsg, false);\n            }\n            if (it.bagKeyId == 0) {\n                it.sourcePos.error(\"Error: %s: %s '%s'.\\n\", errorMsg,\n                        String8(it.isId ? id16 : attr16).string(),\n                        String8(key).string());\n                hasErrors = true;\n            }\n        }\n    }\n    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;\n}\n\nstatus_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table,\n        const String8* configTypeName, const ConfigDescription* config)\n{\n    if (mType == TYPE_ITEM) {\n        Item& it = mItem;\n        AccessorCookie ac(it.sourcePos, String8(mName), String8(it.value));\n        if (!table->stringToValue(&it.parsedValue, strings,\n                                  it.value, false, true, 0,\n                                  &it.style, NULL, &ac, mItemFormat,\n                                  configTypeName, config)) {\n            return UNKNOWN_ERROR;\n        }\n    } else if (mType == TYPE_BAG) {\n        const size_t N = mBag.size();\n        for (size_t i=0; i<N; i++) {\n            const String16& key = mBag.keyAt(i);\n            Item& it = mBag.editValueAt(i);\n            AccessorCookie ac(it.sourcePos, String8(key), String8(it.value));\n            if (!table->stringToValue(&it.parsedValue, strings,\n                                      it.value, false, true, it.bagKeyId,\n                                      &it.style, NULL, &ac, it.format,\n                                      configTypeName, config)) {\n                return UNKNOWN_ERROR;\n            }\n        }\n    } else {\n        mPos.error(\"Error: entry %s is not a single item or a bag.\\n\",\n                   String8(mName).string());\n        return UNKNOWN_ERROR;\n    }\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Entry::remapStringValue(StringPool* strings)\n{\n    if (mType == TYPE_ITEM) {\n        Item& it = mItem;\n        if (it.parsedValue.dataType == Res_value::TYPE_STRING) {\n            it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data);\n        }\n    } else if (mType == TYPE_BAG) {\n        const size_t N = mBag.size();\n        for (size_t i=0; i<N; i++) {\n            Item& it = mBag.editValueAt(i);\n            if (it.parsedValue.dataType == Res_value::TYPE_STRING) {\n                it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data);\n            }\n        }\n    } else {\n        mPos.error(\"Error: entry %s is not a single item or a bag.\\n\",\n                   String8(mName).string());\n        return UNKNOWN_ERROR;\n    }\n    return NO_ERROR;\n}\n\nssize_t ResourceTable::Entry::flatten(Bundle* /* bundle */, const sp<AaptFile>& data, bool isPublic)\n{\n    size_t amt = 0;\n    ResTable_entry header;\n    memset(&header, 0, sizeof(header));\n    header.size = htods(sizeof(header));\n    const type ty = mType;\n    if (ty == TYPE_BAG) {\n        header.flags |= htods(header.FLAG_COMPLEX);\n    }\n    if (isPublic) {\n        header.flags |= htods(header.FLAG_PUBLIC);\n    }\n    header.key.index = htodl(mNameIndex);\n    if (ty != TYPE_BAG) {\n        status_t err = data->writeData(&header, sizeof(header));\n        if (err != NO_ERROR) {\n            fprintf(stderr, \"ERROR: out of memory creating ResTable_entry\\n\");\n            return err;\n        }\n\n        const Item& it = mItem;\n        Res_value par;\n        memset(&par, 0, sizeof(par));\n        par.size = htods(it.parsedValue.size);\n        par.dataType = it.parsedValue.dataType;\n        par.res0 = it.parsedValue.res0;\n        par.data = htodl(it.parsedValue.data);\n        #if 0\n        printf(\"Writing item (%s): type=%d, data=0x%x, res0=0x%x\\n\",\n               String8(mName).string(), it.parsedValue.dataType,\n               it.parsedValue.data, par.res0);\n        #endif\n        err = data->writeData(&par, it.parsedValue.size);\n        if (err != NO_ERROR) {\n            fprintf(stderr, \"ERROR: out of memory creating Res_value\\n\");\n            return err;\n        }\n        amt += it.parsedValue.size;\n    } else {\n        size_t N = mBag.size();\n        size_t i;\n        // Create correct ordering of items.\n        KeyedVector<uint32_t, const Item*> items;\n        for (i=0; i<N; i++) {\n            const Item& it = mBag.valueAt(i);\n            items.add(it.bagKeyId, &it);\n        }\n        N = items.size();\n        \n        ResTable_map_entry mapHeader;\n        memcpy(&mapHeader, &header, sizeof(header));\n        mapHeader.size = htods(sizeof(mapHeader));\n        mapHeader.parent.ident = htodl(mParentId);\n        mapHeader.count = htodl(N);\n        status_t err = data->writeData(&mapHeader, sizeof(mapHeader));\n        if (err != NO_ERROR) {\n            fprintf(stderr, \"ERROR: out of memory creating ResTable_entry\\n\");\n            return err;\n        }\n\n        for (i=0; i<N; i++) {\n            const Item& it = *items.valueAt(i);\n            ResTable_map map;\n            map.name.ident = htodl(it.bagKeyId);\n            map.value.size = htods(it.parsedValue.size);\n            map.value.dataType = it.parsedValue.dataType;\n            map.value.res0 = it.parsedValue.res0;\n            map.value.data = htodl(it.parsedValue.data);\n            err = data->writeData(&map, sizeof(map));\n            if (err != NO_ERROR) {\n                fprintf(stderr, \"ERROR: out of memory creating Res_value\\n\");\n                return err;\n            }\n            amt += sizeof(map);\n        }\n    }\n    return amt;\n}\n\nvoid ResourceTable::ConfigList::appendComment(const String16& comment,\n                                              bool onlyIfEmpty)\n{\n    if (comment.size() <= 0) {\n        return;\n    }\n    if (onlyIfEmpty && mComment.size() > 0) {\n        return;\n    }\n    if (mComment.size() > 0) {\n        mComment.append(String16(\"\\n\"));\n    }\n    mComment.append(comment);\n}\n\nvoid ResourceTable::ConfigList::appendTypeComment(const String16& comment)\n{\n    if (comment.size() <= 0) {\n        return;\n    }\n    if (mTypeComment.size() > 0) {\n        mTypeComment.append(String16(\"\\n\"));\n    }\n    mTypeComment.append(comment);\n}\n\nstatus_t ResourceTable::Type::addPublic(const SourcePos& sourcePos,\n                                        const String16& name,\n                                        const uint32_t ident)\n{\n    #if 0\n    int32_t entryIdx = Res_GETENTRY(ident);\n    if (entryIdx < 0) {\n        sourcePos.error(\"Public resource %s/%s has an invalid 0 identifier (0x%08x).\\n\",\n                String8(mName).string(), String8(name).string(), ident);\n        return UNKNOWN_ERROR;\n    }\n    #endif\n\n    int32_t typeIdx = Res_GETTYPE(ident);\n    if (typeIdx >= 0) {\n        typeIdx++;\n        if (mPublicIndex > 0 && mPublicIndex != typeIdx) {\n            sourcePos.error(\"Public resource %s/%s has conflicting type codes for its\"\n                    \" public identifiers (0x%x vs 0x%x).\\n\",\n                    String8(mName).string(), String8(name).string(),\n                    mPublicIndex, typeIdx);\n            return UNKNOWN_ERROR;\n        }\n        mPublicIndex = typeIdx;\n    }\n\n    if (mFirstPublicSourcePos == NULL) {\n        mFirstPublicSourcePos = new SourcePos(sourcePos);\n    }\n\n    if (mPublic.indexOfKey(name) < 0) {\n        mPublic.add(name, Public(sourcePos, String16(), ident));\n    } else {\n        Public& p = mPublic.editValueFor(name);\n        if (p.ident != ident) {\n            sourcePos.error(\"Public resource %s/%s has conflicting public identifiers\"\n                    \" (0x%08x vs 0x%08x).\\n\"\n                    \"%s:%d: Originally defined here.\\n\",\n                    String8(mName).string(), String8(name).string(), p.ident, ident,\n                    p.sourcePos.file.string(), p.sourcePos.line);\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    return NO_ERROR;\n}\n\nvoid ResourceTable::Type::canAddEntry(const String16& name)\n{\n    mCanAddEntries.add(name);\n}\n\nsp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,\n                                                       const SourcePos& sourcePos,\n                                                       const ResTable_config* config,\n                                                       bool doSetIndex,\n                                                       bool overlay,\n                                                       bool autoAddOverlay)\n{\n    int pos = -1;\n    sp<ConfigList> c = mConfigs.valueFor(entry);\n    if (c == NULL) {\n        if (overlay && !autoAddOverlay && mCanAddEntries.indexOf(entry) < 0) {\n            sourcePos.error(\"Resource at %s appears in overlay but not\"\n                            \" in the base package; use <add-resource> to add.\\n\",\n                            String8(entry).string());\n            return NULL;\n        }\n        c = new ConfigList(entry, sourcePos);\n        mConfigs.add(entry, c);\n        pos = (int)mOrderedConfigs.size();\n        mOrderedConfigs.add(c);\n        if (doSetIndex) {\n            c->setEntryIndex(pos);\n        }\n    }\n    \n    ConfigDescription cdesc;\n    if (config) cdesc = *config;\n    \n    sp<Entry> e = c->getEntries().valueFor(cdesc);\n    if (e == NULL) {\n        if (kIsDebug) {\n            if (config != NULL) {\n                printf(\"New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c \"\n                    \"orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d \"\n                    \"sw%ddp w%ddp h%ddp layout:%d\\n\",\n                      sourcePos.file.string(), sourcePos.line,\n                      config->mcc, config->mnc,\n                      config->language[0] ? config->language[0] : '-',\n                      config->language[1] ? config->language[1] : '-',\n                      config->country[0] ? config->country[0] : '-',\n                      config->country[1] ? config->country[1] : '-',\n                      config->orientation,\n                      config->touchscreen,\n                      config->density,\n                      config->keyboard,\n                      config->inputFlags,\n                      config->navigation,\n                      config->screenWidth,\n                      config->screenHeight,\n                      config->smallestScreenWidthDp,\n                      config->screenWidthDp,\n                      config->screenHeightDp,\n                      config->screenLayout);\n            } else {\n                printf(\"New entry at %s:%d: NULL config\\n\",\n                        sourcePos.file.string(), sourcePos.line);\n            }\n        }\n        e = new Entry(entry, sourcePos);\n        c->addEntry(cdesc, e);\n        /*\n        if (doSetIndex) {\n            if (pos < 0) {\n                for (pos=0; pos<(int)mOrderedConfigs.size(); pos++) {\n                    if (mOrderedConfigs[pos] == c) {\n                        break;\n                    }\n                }\n                if (pos >= (int)mOrderedConfigs.size()) {\n                    sourcePos.error(\"Internal error: config not found in mOrderedConfigs when adding entry\");\n                    return NULL;\n                }\n            }\n            e->setEntryIndex(pos);\n        }\n        */\n    }\n    \n    return e;\n}\n\nsp<ResourceTable::ConfigList> ResourceTable::Type::removeEntry(const String16& entry) {\n    ssize_t idx = mConfigs.indexOfKey(entry);\n    if (idx < 0) {\n        return NULL;\n    }\n\n    sp<ConfigList> removed = mConfigs.valueAt(idx);\n    mConfigs.removeItemsAt(idx);\n\n    Vector<sp<ConfigList> >::iterator iter = std::find(\n            mOrderedConfigs.begin(), mOrderedConfigs.end(), removed);\n    if (iter != mOrderedConfigs.end()) {\n        mOrderedConfigs.erase(iter);\n    }\n\n    mPublic.removeItem(entry);\n    return removed;\n}\n\nSortedVector<ConfigDescription> ResourceTable::Type::getUniqueConfigs() const {\n    SortedVector<ConfigDescription> unique;\n    const size_t entryCount = mOrderedConfigs.size();\n    for (size_t i = 0; i < entryCount; i++) {\n        if (mOrderedConfigs[i] == NULL) {\n            continue;\n        }\n        const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configs =\n                mOrderedConfigs[i]->getEntries();\n        const size_t configCount = configs.size();\n        for (size_t j = 0; j < configCount; j++) {\n            unique.add(configs.keyAt(j));\n        }\n    }\n    return unique;\n}\n\nstatus_t ResourceTable::Type::getPublicIndex(const String16& entry) /*const*/\n{\n    if (mPublic.indexOfKey(/*name*/entry) < 0) {\n        return -1;\n    } else {\n        Public& p = mPublic.editValueFor(/*name*/entry);\n        return p.ident;\n    }\n}\n\nstatus_t ResourceTable::Type::applyPublicEntryOrder(bool patch)\n{\n    size_t N = mOrderedConfigs.size();\n    Vector<sp<ConfigList> > origOrder(mOrderedConfigs);\n    bool hasError = false;\n\n    size_t i;\n    for (i=0; i<N; i++) {\n        mOrderedConfigs.replaceAt(NULL, i);\n    }\n\n    const size_t NP = mPublic.size();\n    //printf(\"Ordering %d configs from %d public defs\\n\", N, NP);\n    size_t j;\n    for (j=0; j<NP; j++) {\n        const String16& name = mPublic.keyAt(j);\n        const Public& p = mPublic.valueAt(j);\n        int32_t idx = Res_GETENTRY(p.ident);\n        //printf(\"Looking for entry \\\"%s\\\"/\\\"%s\\\" (0x%08x) in %d...\\n\",\n        //       String8(mName).string(), String8(name).string(), p.ident, N);\n        if (patch) {\n            if (idx >= (int32_t)mOrderedConfigs.size()) {\n                mOrderedConfigs.resize(idx + 1);\n            }\n        }\n        bool found = false;\n        for (i=0; i<N; i++) {\n            sp<ConfigList> e = origOrder.itemAt(i);\n            //printf(\"#%d: \\\"%s\\\"\\n\", i, String8(e->getName()).string());\n            if (e->getName() == name) {\n                if (idx >= (int32_t)mOrderedConfigs.size()) {\n                    mOrderedConfigs.resize(idx + 1);\n                }\n\n                if (mOrderedConfigs.itemAt(idx) == NULL) {\n                    e->setPublic(true);\n                    e->setPublicSourcePos(p.sourcePos);\n                    mOrderedConfigs.replaceAt(e, idx);\n                    origOrder.removeAt(i);\n                    N--;\n                    found = true;\n                    break;\n                } else {\n                    sp<ConfigList> oe = mOrderedConfigs.itemAt(idx);\n\n                    p.sourcePos.error(\"Multiple entry names declared for public entry\"\n                            \" identifier 0x%x in type %s (%s vs %s).\\n\"\n                            \"%s:%d: Originally defined here.\",\n                            idx+1, String8(mName).string(),\n                            String8(oe->getName()).string(),\n                            String8(name).string(),\n                            oe->getPublicSourcePos().file.string(),\n                            oe->getPublicSourcePos().line);\n                    hasError = true;\n                }\n            }\n        }\n\n        if (!patch && !found) {\n            p.sourcePos.error(\"Public symbol %s/%s declared here is not defined.\",\n                    String8(mName).string(), String8(name).string());\n            hasError = true;\n        }\n    }\n\n    //printf(\"Copying back in %d non-public configs, have %d\\n\", N, origOrder.size());\n    \n    if (N != origOrder.size()) {\n        printf(\"Internal error: remaining private symbol count mismatch\\n\");\n        N = origOrder.size();\n    }\n    \n    j = 0;\n    for (i=0; i<N; i++) {\n        sp<ConfigList> e = origOrder.itemAt(i);\n        if (patch) {\n            mOrderedConfigs.add(e);\n        } else {\n            // There will always be enough room for the remaining entries.\n            while (mOrderedConfigs.itemAt(j) != NULL) {\n                j++;\n            }\n            mOrderedConfigs.replaceAt(e, j);\n            j++;\n        }\n    }\n\n    return hasError ? STATUST(UNKNOWN_ERROR) : NO_ERROR;\n}\n\nResourceTable::Package::Package(const String16& name, size_t packageId)\n    : mName(name), mPackageId(packageId),\n      mTypeStringsMapping(0xffffffff),\n      mKeyStringsMapping(0xffffffff)\n{\n}\n\nsp<ResourceTable::Type> ResourceTable::Package::getType(const String16& type,\n                                                        const SourcePos& sourcePos,\n                                                        bool doSetIndex)\n{\n    sp<Type> t = mTypes.valueFor(type);\n    if (t == NULL) {\n        t = new Type(type, sourcePos);\n        mTypes.add(type, t);\n        mOrderedTypes.add(t);\n        if (doSetIndex) {\n            // For some reason the type's index is set to one plus the index\n            // in the mOrderedTypes list, rather than just the index.\n            t->setIndex(mOrderedTypes.size());\n        }\n    }\n    return t;\n}\n\nstatus_t ResourceTable::Package::setTypeStrings(const sp<AaptFile>& data)\n{\n    status_t err = setStrings(data, &mTypeStrings, &mTypeStringsMapping);\n    if (err != NO_ERROR) {\n        fprintf(stderr, \"ERROR: Type string data is corrupt!\\n\");\n        return err;\n    }\n\n    // Retain a reference to the new data after we've successfully replaced\n    // all uses of the old reference (in setStrings() ).\n    mTypeStringsData = data;\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Package::setKeyStrings(const sp<AaptFile>& data)\n{\n    status_t err = setStrings(data, &mKeyStrings, &mKeyStringsMapping);\n    if (err != NO_ERROR) {\n        fprintf(stderr, \"ERROR: Key string data is corrupt!\\n\");\n        return err;\n    }\n\n    // Retain a reference to the new data after we've successfully replaced\n    // all uses of the old reference (in setStrings() ).\n    mKeyStringsData = data;\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Package::setStrings(const sp<AaptFile>& data,\n                                            ResStringPool* strings,\n                                            DefaultKeyedVector<String16, uint32_t>* mappings)\n{\n    if (data->getData() == NULL) {\n        return UNKNOWN_ERROR;\n    }\n\n    status_t err = strings->setTo(data->getData(), data->getSize());\n    if (err == NO_ERROR) {\n        const size_t N = strings->size();\n        for (size_t i=0; i<N; i++) {\n            size_t len;\n            mappings->add(String16(strings->stringAt(i, &len)), i);\n        }\n    }\n    return err;\n}\n\nstatus_t ResourceTable::Package::applyPublicTypeOrder()\n{\n    size_t N = mOrderedTypes.size();\n    Vector<sp<Type> > origOrder(mOrderedTypes);\n\n    size_t i;\n    for (i=0; i<N; i++) {\n        mOrderedTypes.replaceAt(NULL, i);\n    }\n\n    for (i=0; i<N; i++) {\n        sp<Type> t = origOrder.itemAt(i);\n        int32_t idx = t->getPublicIndex();\n        if (idx > 0) {\n            idx--;\n            while (idx >= (int32_t)mOrderedTypes.size()) {\n                mOrderedTypes.add();\n            }\n            if (mOrderedTypes.itemAt(idx) != NULL) {\n                sp<Type> ot = mOrderedTypes.itemAt(idx);\n                t->getFirstPublicSourcePos().error(\"Multiple type names declared for public type\"\n                        \" identifier 0x%x (%s vs %s).\\n\"\n                        \"%s:%d: Originally defined here.\",\n                        idx, String8(ot->getName()).string(),\n                        String8(t->getName()).string(),\n                        ot->getFirstPublicSourcePos().file.string(),\n                        ot->getFirstPublicSourcePos().line);\n                return UNKNOWN_ERROR;\n            }\n            mOrderedTypes.replaceAt(t, idx);\n            origOrder.removeAt(i);\n            i--;\n            N--;\n        }\n    }\n\n    size_t j=0;\n    for (i=0; i<N; i++) {\n        sp<Type> t = origOrder.itemAt(i);\n        // There will always be enough room for the remaining types.\n        while (mOrderedTypes.itemAt(j) != NULL) {\n            j++;\n        }\n        mOrderedTypes.replaceAt(t, j);\n    }\n\n    return NO_ERROR;\n}\n\nvoid ResourceTable::Package::movePrivateAttrs() {\n    sp<Type> attr = mTypes.valueFor(String16(\"attr\"));\n    if (attr == NULL) {\n        // Nothing to do.\n        return;\n    }\n\n    Vector<sp<ConfigList> > privateAttrs;\n\n    bool hasPublic = false;\n    const Vector<sp<ConfigList> >& configs = attr->getOrderedConfigs();\n    const size_t configCount = configs.size();\n    for (size_t i = 0; i < configCount; i++) {\n        if (configs[i] == NULL) {\n            continue;\n        }\n\n        if (attr->isPublic(configs[i]->getName())) {\n            hasPublic = true;\n        } else {\n            privateAttrs.add(configs[i]);\n        }\n    }\n\n    // Only if we have public attributes do we create a separate type for\n    // private attributes.\n    if (!hasPublic) {\n        return;\n    }\n\n    // Create a new type for private attributes.\n    sp<Type> privateAttrType = getType(String16(kAttrPrivateType), SourcePos());\n\n    const size_t privateAttrCount = privateAttrs.size();\n    for (size_t i = 0; i < privateAttrCount; i++) {\n        const sp<ConfigList>& cl = privateAttrs[i];\n\n        // Remove the private attributes from their current type.\n        attr->removeEntry(cl->getName());\n\n        // Add it to the new type.\n        const DefaultKeyedVector<ConfigDescription, sp<Entry> >& entries = cl->getEntries();\n        const size_t entryCount = entries.size();\n        for (size_t j = 0; j < entryCount; j++) {\n            const sp<Entry>& oldEntry = entries[j];\n            sp<Entry> entry = privateAttrType->getEntry(\n                    cl->getName(), oldEntry->getPos(), &entries.keyAt(j));\n            *entry = *oldEntry;\n        }\n\n        // Move the symbols to the new type.\n\n    }\n}\n\nsp<ResourceTable::Package> ResourceTable::getPackage(const String16& package)\n{\n    if (package != mAssetsPackage) {\n        return NULL;\n    }\n    return mPackages.valueFor(package);\n}\n\nsp<ResourceTable::Type> ResourceTable::getType(const String16& package,\n                                               const String16& type,\n                                               const SourcePos& sourcePos,\n                                               bool doSetIndex)\n{\n    sp<Package> p = getPackage(package);\n    if (p == NULL) {\n        return NULL;\n    }\n    return p->getType(type, sourcePos, doSetIndex);\n}\n\nsp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package,\n                                                 const String16& type,\n                                                 const String16& name,\n                                                 const SourcePos& sourcePos,\n                                                 bool overlay,\n                                                 const ResTable_config* config,\n                                                 bool doSetIndex)\n{\n    sp<Type> t = getType(package, type, sourcePos, doSetIndex);\n    if (t == NULL) {\n        return NULL;\n    }\n    return t->getEntry(name, sourcePos, config, doSetIndex, overlay, mBundle->getAutoAddOverlay());\n}\n\nsp<ResourceTable::ConfigList> ResourceTable::getConfigList(const String16& package,\n        const String16& type, const String16& name) const\n{\n    const size_t packageCount = mOrderedPackages.size();\n    for (size_t pi = 0; pi < packageCount; pi++) {\n        const sp<Package>& p = mOrderedPackages[pi];\n        if (p == NULL || p->getName() != package) {\n            continue;\n        }\n\n        const Vector<sp<Type> >& types = p->getOrderedTypes();\n        const size_t typeCount = types.size();\n        for (size_t ti = 0; ti < typeCount; ti++) {\n            const sp<Type>& t = types[ti];\n            if (t == NULL || t->getName() != type) {\n                continue;\n            }\n\n            const Vector<sp<ConfigList> >& configs = t->getOrderedConfigs();\n            const size_t configCount = configs.size();\n            for (size_t ci = 0; ci < configCount; ci++) {\n                const sp<ConfigList>& cl = configs[ci];\n                if (cl == NULL || cl->getName() != name) {\n                    continue;\n                }\n\n                return cl;\n            }\n        }\n    }\n    return NULL;\n}\n\nsp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID,\n                                                       const ResTable_config* config) const\n{\n    size_t pid = Res_GETPACKAGE(resID)+1;\n    const size_t N = mOrderedPackages.size();\n    sp<Package> p;\n    for (size_t i = 0; i < N; i++) {\n        sp<Package> check = mOrderedPackages[i];\n        if (check->getAssignedId() == pid) {\n            p = check;\n            break;\n        }\n\n    }\n    if (p == NULL) {\n        fprintf(stderr, \"warning: Package not found for resource #%08x\\n\", resID);\n        return NULL;\n    }\n\n    int tid = Res_GETTYPE(resID);\n    if (tid < 0 || tid >= (int)p->getOrderedTypes().size()) {\n        fprintf(stderr, \"warning: Type not found for resource #%08x\\n\", resID);\n        return NULL;\n    }\n    sp<Type> t = p->getOrderedTypes()[tid];\n\n    int eid = Res_GETENTRY(resID);\n    if (eid < 0 || eid >= (int)t->getOrderedConfigs().size()) {\n        fprintf(stderr, \"warning: Entry not found for resource #%08x\\n\", resID);\n        return NULL;\n    }\n\n    sp<ConfigList> c = t->getOrderedConfigs()[eid];\n    if (c == NULL) {\n        fprintf(stderr, \"warning: Entry not found for resource #%08x\\n\", resID);\n        return NULL;\n    }\n    \n    ConfigDescription cdesc;\n    if (config) cdesc = *config;\n    sp<Entry> e = c->getEntries().valueFor(cdesc);\n    if (c == NULL) {\n        fprintf(stderr, \"warning: Entry configuration not found for resource #%08x\\n\", resID);\n        return NULL;\n    }\n    \n    return e;\n}\n\nconst ResourceTable::Item* ResourceTable::getItem(uint32_t resID, uint32_t attrID) const\n{\n    sp<const Entry> e = getEntry(resID);\n    if (e == NULL) {\n        return NULL;\n    }\n\n    const size_t N = e->getBag().size();\n    for (size_t i=0; i<N; i++) {\n        const Item& it = e->getBag().valueAt(i);\n        if (it.bagKeyId == 0) {\n            fprintf(stderr, \"warning: ID not yet assigned to '%s' in bag '%s'\\n\",\n                    String8(e->getName()).string(),\n                    String8(e->getBag().keyAt(i)).string());\n        }\n        if (it.bagKeyId == attrID) {\n            return &it;\n        }\n    }\n\n    return NULL;\n}\n\nbool ResourceTable::getItemValue(\n    uint32_t resID, uint32_t attrID, Res_value* outValue)\n{\n    const Item* item = getItem(resID, attrID);\n\n    bool res = false;\n    if (item != NULL) {\n        if (item->evaluating) {\n            sp<const Entry> e = getEntry(resID);\n            const size_t N = e->getBag().size();\n            size_t i;\n            for (i=0; i<N; i++) {\n                if (&e->getBag().valueAt(i) == item) {\n                    break;\n                }\n            }\n            fprintf(stderr, \"warning: Circular reference detected in key '%s' of bag '%s'\\n\",\n                    String8(e->getName()).string(),\n                    String8(e->getBag().keyAt(i)).string());\n            return false;\n        }\n        item->evaluating = true;\n        res = stringToValue(outValue, NULL, item->value, false, false, item->bagKeyId);\n        if (kIsDebug) {\n            if (res) {\n                printf(\"getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\\n\",\n                       resID, attrID, String8(getEntry(resID)->getName()).string(),\n                       outValue->dataType, outValue->data);\n            } else {\n                printf(\"getItemValue of #%08x[#%08x]: failed\\n\",\n                       resID, attrID);\n            }\n        }\n        item->evaluating = false;\n    }\n    return res;\n}\n\n/**\n * Returns the SDK version at which the attribute was\n * made public, or -1 if the resource ID is not an attribute\n * or is not public.\n */\nint ResourceTable::getPublicAttributeSdkLevel(uint32_t attrId) const {\n    if (Res_GETPACKAGE(attrId) + 1 != 0x01 || Res_GETTYPE(attrId) + 1 != 0x01) {\n        return -1;\n    }\n\n    uint32_t specFlags;\n    if (!mAssets->getIncludedResources().getResourceFlags(attrId, &specFlags)) {\n        return -1;\n    }\n\n    if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) {\n        return -1;\n    }\n\n    const size_t entryId = Res_GETENTRY(attrId);\n    if (entryId <= 0x021c) {\n        return 1;\n    } else if (entryId <= 0x021d) {\n        return 2;\n    } else if (entryId <= 0x0269) {\n        return SDK_CUPCAKE;\n    } else if (entryId <= 0x028d) {\n        return SDK_DONUT;\n    } else if (entryId <= 0x02ad) {\n        return SDK_ECLAIR;\n    } else if (entryId <= 0x02b3) {\n        return SDK_ECLAIR_0_1;\n    } else if (entryId <= 0x02b5) {\n        return SDK_ECLAIR_MR1;\n    } else if (entryId <= 0x02bd) {\n        return SDK_FROYO;\n    } else if (entryId <= 0x02cb) {\n        return SDK_GINGERBREAD;\n    } else if (entryId <= 0x0361) {\n        return SDK_HONEYCOMB;\n    } else if (entryId <= 0x0366) {\n        return SDK_HONEYCOMB_MR1;\n    } else if (entryId <= 0x03a6) {\n        return SDK_HONEYCOMB_MR2;\n    } else if (entryId <= 0x03ae) {\n        return SDK_JELLY_BEAN;\n    } else if (entryId <= 0x03cc) {\n        return SDK_JELLY_BEAN_MR1;\n    } else if (entryId <= 0x03da) {\n        return SDK_JELLY_BEAN_MR2;\n    } else if (entryId <= 0x03f1) {\n        return SDK_KITKAT;\n    } else if (entryId <= 0x03f6) {\n        return SDK_KITKAT_WATCH;\n    } else if (entryId <= 0x04ce) {\n        return SDK_LOLLIPOP;\n    } else {\n        // Anything else is marked as defined in\n        // SDK_LOLLIPOP_MR1 since after this\n        // version no attribute compat work\n        // needs to be done.\n        return SDK_LOLLIPOP_MR1;\n    }\n}\n\n/**\n * First check the Manifest, then check the command line flag.\n */\nstatic int getMinSdkVersion(const Bundle* bundle) {\n    if (bundle->getManifestMinSdkVersion() != NULL && strlen(bundle->getManifestMinSdkVersion()) > 0) {\n        return atoi(bundle->getManifestMinSdkVersion());\n    } else if (bundle->getMinSdkVersion() != NULL && strlen(bundle->getMinSdkVersion()) > 0) {\n        return atoi(bundle->getMinSdkVersion());\n    }\n    return 0;\n}\n\nbool ResourceTable::shouldGenerateVersionedResource(\n        const sp<ResourceTable::ConfigList>& configList,\n        const ConfigDescription& sourceConfig,\n        const int sdkVersionToGenerate) {\n    assert(sdkVersionToGenerate > sourceConfig.sdkVersion);\n    const DefaultKeyedVector<ConfigDescription, sp<ResourceTable::Entry>>& entries\n            = configList->getEntries();\n    ssize_t idx = entries.indexOfKey(sourceConfig);\n\n    // The source config came from this list, so it should be here.\n    assert(idx >= 0);\n\n    // The next configuration either only varies in sdkVersion, or it is completely different\n    // and therefore incompatible. If it is incompatible, we must generate the versioned resource.\n\n    // NOTE: The ordering of configurations takes sdkVersion as higher precedence than other\n    // qualifiers, so we need to iterate through the entire list to be sure there\n    // are no higher sdk level versions of this resource.\n    ConfigDescription tempConfig(sourceConfig);\n    for (size_t i = static_cast<size_t>(idx) + 1; i < entries.size(); i++) {\n        const ConfigDescription& nextConfig = entries.keyAt(i);\n        tempConfig.sdkVersion = nextConfig.sdkVersion;\n        if (tempConfig == nextConfig) {\n            // The two configs are the same, check the sdk version.\n            return sdkVersionToGenerate < nextConfig.sdkVersion;\n        }\n    }\n\n    // No match was found, so we should generate the versioned resource.\n    return true;\n}\n\n/**\n * Modifies the entries in the resource table to account for compatibility\n * issues with older versions of Android.\n *\n * This primarily handles the issue of private/public attribute clashes\n * in framework resources.\n *\n * AAPT has traditionally assigned resource IDs to public attributes,\n * and then followed those public definitions with private attributes.\n *\n * --- PUBLIC ---\n * | 0x01010234 | attr/color\n * | 0x01010235 | attr/background\n *\n * --- PRIVATE ---\n * | 0x01010236 | attr/secret\n * | 0x01010237 | attr/shhh\n *\n * Each release, when attributes are added, they take the place of the private\n * attributes and the private attributes are shifted down again.\n *\n * --- PUBLIC ---\n * | 0x01010234 | attr/color\n * | 0x01010235 | attr/background\n * | 0x01010236 | attr/shinyNewAttr\n * | 0x01010237 | attr/highlyValuedFeature\n *\n * --- PRIVATE ---\n * | 0x01010238 | attr/secret\n * | 0x01010239 | attr/shhh\n *\n * Platform code may look for private attributes set in a theme. If an app\n * compiled against a newer version of the platform uses a new public\n * attribute that happens to have the same ID as the private attribute\n * the older platform is expecting, then the behavior is undefined.\n *\n * We get around this by detecting any newly defined attributes (in L),\n * copy the resource into a -v21 qualified resource, and delete the\n * attribute from the original resource. This ensures that older platforms\n * don't see the new attribute, but when running on L+ platforms, the\n * attribute will be respected.\n */\nstatus_t ResourceTable::modifyForCompat(const Bundle* bundle) {\n    const int minSdk = getMinSdkVersion(bundle);\n    if (minSdk >= SDK_LOLLIPOP_MR1) {\n        // Lollipop MR1 and up handles public attributes differently, no\n        // need to do any compat modifications.\n        return NO_ERROR;\n    }\n\n    const String16 attr16(\"attr\");\n\n    const size_t packageCount = mOrderedPackages.size();\n    for (size_t pi = 0; pi < packageCount; pi++) {\n        sp<Package> p = mOrderedPackages.itemAt(pi);\n        if (p == NULL || p->getTypes().size() == 0) {\n            // Empty, skip!\n            continue;\n        }\n\n        const size_t typeCount = p->getOrderedTypes().size();\n        for (size_t ti = 0; ti < typeCount; ti++) {\n            sp<Type> t = p->getOrderedTypes().itemAt(ti);\n            if (t == NULL) {\n                continue;\n            }\n\n            const size_t configCount = t->getOrderedConfigs().size();\n            for (size_t ci = 0; ci < configCount; ci++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);\n                if (c == NULL) {\n                    continue;\n                }\n\n                Vector<key_value_pair_t<ConfigDescription, sp<Entry> > > entriesToAdd;\n                const DefaultKeyedVector<ConfigDescription, sp<Entry> >& entries =\n                        c->getEntries();\n                const size_t entryCount = entries.size();\n                for (size_t ei = 0; ei < entryCount; ei++) {\n                    sp<Entry> e = entries.valueAt(ei);\n                    if (e == NULL || e->getType() != Entry::TYPE_BAG) {\n                        continue;\n                    }\n\n                    const ConfigDescription& config = entries.keyAt(ei);\n                    if (config.sdkVersion >= SDK_LOLLIPOP_MR1) {\n                        continue;\n                    }\n\n                    KeyedVector<int, Vector<String16> > attributesToRemove;\n                    const KeyedVector<String16, Item>& bag = e->getBag();\n                    const size_t bagCount = bag.size();\n                    for (size_t bi = 0; bi < bagCount; bi++) {\n                        const uint32_t attrId = getResId(bag.keyAt(bi), &attr16);\n                        const int sdkLevel = getPublicAttributeSdkLevel(attrId);\n                        if (sdkLevel > 1 && sdkLevel > config.sdkVersion && sdkLevel > minSdk) {\n                            AaptUtil::appendValue(attributesToRemove, sdkLevel, bag.keyAt(bi));\n                        }\n                    }\n\n                    if (attributesToRemove.isEmpty()) {\n                        continue;\n                    }\n\n                    const size_t sdkCount = attributesToRemove.size();\n                    for (size_t i = 0; i < sdkCount; i++) {\n                        const int sdkLevel = attributesToRemove.keyAt(i);\n\n                        if (!shouldGenerateVersionedResource(c, config, sdkLevel)) {\n                            // There is a style that will override this generated one.\n                            continue;\n                        }\n\n                        // Duplicate the entry under the same configuration\n                        // but with sdkVersion == sdkLevel.\n                        ConfigDescription newConfig(config);\n                        newConfig.sdkVersion = sdkLevel;\n\n                        sp<Entry> newEntry = new Entry(*e);\n\n                        // Remove all items that have a higher SDK level than\n                        // the one we are synthesizing.\n                        for (size_t j = 0; j < sdkCount; j++) {\n                            if (j == i) {\n                                continue;\n                            }\n\n                            if (attributesToRemove.keyAt(j) > sdkLevel) {\n                                const size_t attrCount = attributesToRemove[j].size();\n                                for (size_t k = 0; k < attrCount; k++) {\n                                    newEntry->removeFromBag(attributesToRemove[j][k]);\n                                }\n                            }\n                        }\n\n                        entriesToAdd.add(key_value_pair_t<ConfigDescription, sp<Entry> >(\n                                newConfig, newEntry));\n                    }\n\n                    // Remove the attribute from the original.\n                    for (size_t i = 0; i < attributesToRemove.size(); i++) {\n                        for (size_t j = 0; j < attributesToRemove[i].size(); j++) {\n                            e->removeFromBag(attributesToRemove[i][j]);\n                        }\n                    }\n                }\n\n                const size_t entriesToAddCount = entriesToAdd.size();\n                for (size_t i = 0; i < entriesToAddCount; i++) {\n                    assert(entries.indexOfKey(entriesToAdd[i].key) < 0);\n\n                    if (bundle->getVerbose()) {\n                        entriesToAdd[i].value->getPos()\n                                .printf(\"using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.\",\n                                        entriesToAdd[i].key.sdkVersion,\n                                        String8(p->getName()).string(),\n                                        String8(t->getName()).string(),\n                                        String8(entriesToAdd[i].value->getName()).string(),\n                                        entriesToAdd[i].key.toString().string());\n                    }\n\n                    sp<Entry> newEntry = t->getEntry(c->getName(),\n                            entriesToAdd[i].value->getPos(),\n                            &entriesToAdd[i].key);\n\n                    *newEntry = *entriesToAdd[i].value;\n                }\n            }\n        }\n    }\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::modifyForCompat(const Bundle* bundle,\n                                        const String16& resourceName,\n                                        const sp<AaptFile>& target,\n                                        const sp<XMLNode>& root) {\n    const String16 vector16(\"vector\");\n    const String16 animatedVector16(\"animated-vector\");\n\n    const int minSdk = getMinSdkVersion(bundle);\n    if (minSdk >= SDK_LOLLIPOP_MR1) {\n        // Lollipop MR1 and up handles public attributes differently, no\n        // need to do any compat modifications.\n        return NO_ERROR;\n    }\n\n    const ConfigDescription config(target->getGroupEntry().toParams());\n    if (target->getResourceType() == \"\" || config.sdkVersion >= SDK_LOLLIPOP_MR1) {\n        // Skip resources that have no type (AndroidManifest.xml) or are already version qualified\n        // with v21 or higher.\n        return NO_ERROR;\n    }\n\n    sp<XMLNode> newRoot = NULL;\n    int sdkVersionToGenerate = SDK_LOLLIPOP_MR1;\n\n    Vector<sp<XMLNode> > nodesToVisit;\n    nodesToVisit.push(root);\n    while (!nodesToVisit.isEmpty()) {\n        sp<XMLNode> node = nodesToVisit.top();\n        nodesToVisit.pop();\n\n        if (bundle->getNoVersionVectors() && (node->getElementName() == vector16 ||\n                    node->getElementName() == animatedVector16)) {\n            // We were told not to version vector tags, so skip the children here.\n            continue;\n        }\n\n        const Vector<XMLNode::attribute_entry>& attrs = node->getAttributes();\n        for (size_t i = 0; i < attrs.size(); i++) {\n            const XMLNode::attribute_entry& attr = attrs[i];\n            const int sdkLevel = getPublicAttributeSdkLevel(attr.nameResId);\n            if (sdkLevel > 1 && sdkLevel > config.sdkVersion && sdkLevel > minSdk) {\n                if (newRoot == NULL) {\n                    newRoot = root->clone();\n                }\n\n                // Find the smallest sdk version that we need to synthesize for\n                // and do that one. Subsequent versions will be processed on\n                // the next pass.\n                sdkVersionToGenerate = std::min(sdkLevel, sdkVersionToGenerate);\n\n                if (bundle->getVerbose()) {\n                    SourcePos(node->getFilename(), node->getStartLineNumber()).printf(\n                            \"removing attribute %s%s%s from <%s>\",\n                            String8(attr.ns).string(),\n                            (attr.ns.size() == 0 ? \"\" : \":\"),\n                            String8(attr.name).string(),\n                            String8(node->getElementName()).string());\n                }\n                node->removeAttribute(i);\n                i--;\n            }\n        }\n\n        // Schedule a visit to the children.\n        const Vector<sp<XMLNode> >& children = node->getChildren();\n        const size_t childCount = children.size();\n        for (size_t i = 0; i < childCount; i++) {\n            nodesToVisit.push(children[i]);\n        }\n    }\n\n    if (newRoot == NULL) {\n        return NO_ERROR;\n    }\n\n    // Look to see if we already have an overriding v21 configuration.\n    sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()),\n            String16(target->getResourceType()), resourceName);\n    if (shouldGenerateVersionedResource(cl, config, sdkVersionToGenerate)) {\n        // We don't have an overriding entry for v21, so we must duplicate this one.\n        ConfigDescription newConfig(config);\n        newConfig.sdkVersion = sdkVersionToGenerate;\n        sp<AaptFile> newFile = new AaptFile(target->getSourceFile(),\n                AaptGroupEntry(newConfig), target->getResourceType());\n        String8 resPath = String8::format(\"res/%s/%s.xml\",\n                newFile->getGroupEntry().toDirName(target->getResourceType()).string(),\n                String8(resourceName).string());\n        resPath.convertToResPath();\n\n        // Add a resource table entry.\n        if (bundle->getVerbose()) {\n            SourcePos(target->getSourceFile(), -1).printf(\n                    \"using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.\",\n                    newConfig.sdkVersion,\n                    mAssets->getPackage().string(),\n                    newFile->getResourceType().string(),\n                    String8(resourceName).string(),\n                    newConfig.toString().string());\n        }\n\n        addEntry(SourcePos(),\n                String16(mAssets->getPackage()),\n                String16(target->getResourceType()),\n                resourceName,\n                String16(resPath),\n                NULL,\n                &newConfig);\n\n        // Schedule this to be compiled.\n        CompileResourceWorkItem item;\n        item.resourceName = resourceName;\n        item.resPath = resPath;\n        item.file = newFile;\n        item.xmlRoot = newRoot;\n        item.needsCompiling = false;    // This step occurs after we parse/assign, so we don't need\n                                        // to do it again.\n        mWorkQueue.push(item);\n    }\n    return NO_ERROR;\n}\n\nvoid ResourceTable::getDensityVaryingResources(\n        KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) {\n    const ConfigDescription nullConfig;\n\n    const size_t packageCount = mOrderedPackages.size();\n    for (size_t p = 0; p < packageCount; p++) {\n        const Vector<sp<Type> >& types = mOrderedPackages[p]->getOrderedTypes();\n        const size_t typeCount = types.size();\n        for (size_t t = 0; t < typeCount; t++) {\n            const Vector<sp<ConfigList> >& configs = types[t]->getOrderedConfigs();\n            const size_t configCount = configs.size();\n            for (size_t c = 0; c < configCount; c++) {\n                const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries\n                        = configs[c]->getEntries();\n                const size_t configEntryCount = configEntries.size();\n                for (size_t ce = 0; ce < configEntryCount; ce++) {\n                    const ConfigDescription& config = configEntries.keyAt(ce);\n                    if (AaptConfig::isDensityOnly(config)) {\n                        // This configuration only varies with regards to density.\n                        const Symbol symbol(\n                                mOrderedPackages[p]->getName(),\n                                types[t]->getName(),\n                                configs[c]->getName(),\n                                getResId(mOrderedPackages[p], types[t],\n                                         configs[c]->getEntryIndex()));\n\n                        const sp<Entry>& entry = configEntries.valueAt(ce);\n                        AaptUtil::appendValue(resources, symbol,\n                                              SymbolDefinition(symbol, config, entry->getPos()));\n                    }\n                }\n            }\n        }\n    }\n}\n\nstatic String16 buildNamespace(const String16& package) {\n    return String16(\"http://schemas.android.com/apk/res/\") + package;\n}\n\nstatic sp<XMLNode> findOnlyChildElement(const sp<XMLNode>& parent) {\n    const Vector<sp<XMLNode> >& children = parent->getChildren();\n    sp<XMLNode> onlyChild;\n    for (size_t i = 0; i < children.size(); i++) {\n        if (children[i]->getType() != XMLNode::TYPE_CDATA) {\n            if (onlyChild != NULL) {\n                return NULL;\n            }\n            onlyChild = children[i];\n        }\n    }\n    return onlyChild;\n}\n\n/**\n * Detects use of the `bundle' format and extracts nested resources into their own top level\n * resources. The bundle format looks like this:\n *\n * <!-- res/drawable/bundle.xml -->\n * <animated-vector xmlns:aapt=\"http://schemas.android.com/aapt\">\n *   <aapt:attr name=\"android:drawable\">\n *     <vector android:width=\"60dp\"\n *             android:height=\"60dp\">\n *       <path android:name=\"v\"\n *             android:fillColor=\"#000000\"\n *             android:pathData=\"M300,70 l 0,-70 70,...\" />\n *     </vector>\n *   </aapt:attr>\n * </animated-vector>\n *\n * When AAPT sees the <aapt:attr> tag, it will extract its single element and its children\n * into a new high-level resource, assigning it a name and ID. Then value of the `name`\n * attribute must be a resource attribute. That resource attribute is inserted into the parent\n * with the reference to the extracted resource as the value.\n *\n * <!-- res/drawable/bundle.xml -->\n * <animated-vector android:drawable=\"@drawable/bundle_1.xml\">\n * </animated-vector>\n *\n * <!-- res/drawable/bundle_1.xml -->\n * <vector android:width=\"60dp\"\n *         android:height=\"60dp\">\n *   <path android:name=\"v\"\n *         android:fillColor=\"#000000\"\n *         android:pathData=\"M300,70 l 0,-70 70,...\" />\n * </vector>\n */\nstatus_t ResourceTable::processBundleFormat(const Bundle* bundle,\n                                            const String16& resourceName,\n                                            const sp<AaptFile>& target,\n                                            const sp<XMLNode>& root) {\n    Vector<sp<XMLNode> > namespaces;\n    if (root->getType() == XMLNode::TYPE_NAMESPACE) {\n        namespaces.push(root);\n    }\n    return processBundleFormatImpl(bundle, resourceName, target, root, &namespaces);\n}\n\nstatus_t ResourceTable::processBundleFormatImpl(const Bundle* bundle,\n                                                const String16& resourceName,\n                                                const sp<AaptFile>& target,\n                                                const sp<XMLNode>& parent,\n                                                Vector<sp<XMLNode> >* namespaces) {\n    const String16 kAaptNamespaceUri16(\"http://schemas.android.com/aapt\");\n    const String16 kName16(\"name\");\n    const String16 kAttr16(\"attr\");\n    const String16 kAssetPackage16(mAssets->getPackage());\n\n    Vector<sp<XMLNode> >& children = parent->getChildren();\n    for (size_t i = 0; i < children.size(); i++) {\n        const sp<XMLNode>& child = children[i];\n\n        if (child->getType() == XMLNode::TYPE_CDATA) {\n            continue;\n        } else if (child->getType() == XMLNode::TYPE_NAMESPACE) {\n            namespaces->push(child);\n        }\n\n        if (child->getElementNamespace() != kAaptNamespaceUri16 ||\n                child->getElementName() != kAttr16) {\n            status_t result = processBundleFormatImpl(bundle, resourceName, target, child,\n                                                      namespaces);\n            if (result != NO_ERROR) {\n                return result;\n            }\n\n            if (child->getType() == XMLNode::TYPE_NAMESPACE) {\n                namespaces->pop();\n            }\n            continue;\n        }\n\n        // This is the <aapt:attr> tag. Look for the 'name' attribute.\n        SourcePos source(child->getFilename(), child->getStartLineNumber());\n\n        sp<XMLNode> nestedRoot = findOnlyChildElement(child);\n        if (nestedRoot == NULL) {\n            source.error(\"<%s:%s> must have exactly one child element\",\n                         String8(child->getElementNamespace()).string(),\n                         String8(child->getElementName()).string());\n            return UNKNOWN_ERROR;\n        }\n\n        // Find the special attribute 'parent-attr'. This attribute's value contains\n        // the resource attribute for which this element should be assigned in the parent.\n        const XMLNode::attribute_entry* attr = child->getAttribute(String16(), kName16);\n        if (attr == NULL) {\n            source.error(\"inline resource definition must specify an attribute via 'name'\");\n            return UNKNOWN_ERROR;\n        }\n\n        // Parse the attribute name.\n        const char* errorMsg = NULL;\n        String16 attrPackage, attrType, attrName;\n        bool result = ResTable::expandResourceRef(attr->string.string(),\n                                                  attr->string.size(),\n                                                  &attrPackage, &attrType, &attrName,\n                                                  &kAttr16, &kAssetPackage16,\n                                                  &errorMsg, NULL);\n        if (!result) {\n            source.error(\"invalid attribute name for 'name': %s\", errorMsg);\n            return UNKNOWN_ERROR;\n        }\n\n        if (attrType != kAttr16) {\n            // The value of the 'name' attribute must be an attribute reference.\n            source.error(\"value of 'name' must be an attribute reference.\");\n            return UNKNOWN_ERROR;\n        }\n\n        // Generate a name for this nested resource and try to add it to the table.\n        // We do this in a loop because the name may be taken, in which case we will\n        // increment a suffix until we succeed.\n        String8 nestedResourceName;\n        String8 nestedResourcePath;\n        int suffix = 1;\n        while (true) {\n            // This child element will be extracted into its own resource file.\n            // Generate a name and path for it from its parent.\n            nestedResourceName = String8::format(\"%s_%d\",\n                        String8(resourceName).string(), suffix++);\n            nestedResourcePath = String8::format(\"res/%s/%s.xml\",\n                        target->getGroupEntry().toDirName(target->getResourceType())\n                                               .string(),\n                        nestedResourceName.string());\n\n            // Lookup or create the entry for this name.\n            sp<Entry> entry = getEntry(kAssetPackage16,\n                                       String16(target->getResourceType()),\n                                       String16(nestedResourceName),\n                                       source,\n                                       false,\n                                       &target->getGroupEntry().toParams(),\n                                       true);\n            if (entry == NULL) {\n                return UNKNOWN_ERROR;\n            }\n\n            if (entry->getType() == Entry::TYPE_UNKNOWN) {\n                // The value for this resource has never been set,\n                // meaning we're good!\n                entry->setItem(source, String16(nestedResourcePath));\n                break;\n            }\n\n            // We failed (name already exists), so try with a different name\n            // (increment the suffix).\n        }\n\n        if (bundle->getVerbose()) {\n            source.printf(\"generating nested resource %s:%s/%s\",\n                    mAssets->getPackage().string(), target->getResourceType().string(),\n                    nestedResourceName.string());\n        }\n\n        // Build the attribute reference and assign it to the parent.\n        String16 nestedResourceRef = String16(String8::format(\"@%s:%s/%s\",\n                    mAssets->getPackage().string(), target->getResourceType().string(),\n                    nestedResourceName.string()));\n\n        String16 attrNs = buildNamespace(attrPackage);\n        if (parent->getAttribute(attrNs, attrName) != NULL) {\n            SourcePos(parent->getFilename(), parent->getStartLineNumber())\n                    .error(\"parent of nested resource already defines attribute '%s:%s'\",\n                           String8(attrPackage).string(), String8(attrName).string());\n            return UNKNOWN_ERROR;\n        }\n\n        // Add the reference to the inline resource.\n        parent->addAttribute(attrNs, attrName, nestedResourceRef);\n\n        // Remove the <aapt:attr> child element from here.\n        children.removeAt(i);\n        i--;\n\n        // Append all namespace declarations that we've seen on this branch in the XML tree\n        // to this resource.\n        // We do this because the order of namespace declarations and prefix usage is determined\n        // by the developer and we do not want to override any decisions. Be conservative.\n        for (size_t nsIndex = namespaces->size(); nsIndex > 0; nsIndex--) {\n            const sp<XMLNode>& ns = namespaces->itemAt(nsIndex - 1);\n            sp<XMLNode> newNs = XMLNode::newNamespace(ns->getFilename(), ns->getNamespacePrefix(),\n                                                      ns->getNamespaceUri());\n            newNs->addChild(nestedRoot);\n            nestedRoot = newNs;\n        }\n\n        // Schedule compilation of the nested resource.\n        CompileResourceWorkItem workItem;\n        workItem.resPath = nestedResourcePath;\n        workItem.resourceName = String16(nestedResourceName);\n        workItem.xmlRoot = nestedRoot;\n        workItem.file = new AaptFile(target->getSourceFile(), target->getGroupEntry(),\n                                     target->getResourceType());\n        mWorkQueue.push(workItem);\n    }\n    return NO_ERROR;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/ResourceTable.h",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#ifndef RESOURCE_TABLE_H\n#define RESOURCE_TABLE_H\n\n#include <map>\n#include <queue>\n#include <set>\n\n#include \"ConfigDescription.h\"\n#include \"ResourceFilter.h\"\n#include \"SourcePos.h\"\n#include \"StringPool.h\"\n#include \"Symbol.h\"\n\nclass XMLNode;\nclass ResourceTable;\n\nenum {\n    XML_COMPILE_STRIP_COMMENTS = 1<<0,\n    XML_COMPILE_ASSIGN_ATTRIBUTE_IDS = 1<<1,\n    XML_COMPILE_PARSE_VALUES = 1 << 2,\n    XML_COMPILE_COMPACT_WHITESPACE = 1<<3,\n    XML_COMPILE_STRIP_WHITESPACE = 1<<4,\n    XML_COMPILE_STRIP_RAW_VALUES = 1<<5,\n    XML_COMPILE_UTF8 = 1<<6,\n\n    XML_COMPILE_STANDARD_RESOURCE =\n            XML_COMPILE_STRIP_COMMENTS | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS | XML_COMPILE_PARSE_VALUES\n            | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES\n};\n\nstatus_t compileXmlFile(const Bundle* bundle,\n                        const sp<AaptAssets>& assets,\n                        const String16& resourceName,\n                        const sp<AaptFile>& target,\n                        ResourceTable* table,\n                        int options = XML_COMPILE_STANDARD_RESOURCE);\n\nstatus_t compileXmlFile(const Bundle* bundle,\n                        const sp<AaptAssets>& assets,\n                        const String16& resourceName,\n                        const sp<AaptFile>& target,\n                        const sp<AaptFile>& outTarget,\n                        ResourceTable* table,\n                        int options = XML_COMPILE_STANDARD_RESOURCE);\n\nstatus_t compileXmlFile(const Bundle* bundle,\n                        const sp<AaptAssets>& assets,\n                        const String16& resourceName,\n                        const sp<XMLNode>& xmlTree,\n                        const sp<AaptFile>& target,\n                        ResourceTable* table,\n                        int options = XML_COMPILE_STANDARD_RESOURCE);\n\nstatus_t compileResourceFile(Bundle* bundle,\n                             const sp<AaptAssets>& assets,\n                             const sp<AaptFile>& in,\n                             const ResTable_config& defParams,\n                             const bool overwrite,\n                             ResourceTable* outTable);\n\nstruct AccessorCookie\n{\n    SourcePos sourcePos;\n    String8 attr;\n    String8 value;\n\n    AccessorCookie(const SourcePos&p, const String8& a, const String8& v)\n        :sourcePos(p),\n         attr(a),\n         value(v)\n    {\n    }\n};\n\n// Holds the necessary information to compile the\n// resource.\nstruct CompileResourceWorkItem {\n    String16 resourceName;\n    String8 resPath;\n    sp<AaptFile> file;\n    sp<XMLNode> xmlRoot;\n    bool needsCompiling = true;\n};\n\nclass ResourceTable : public ResTable::Accessor\n{\npublic:\n    // The type of package to build.\n    enum PackageType {\n        App,\n        System,\n        SharedLibrary,\n        AppFeature\n    };\n\n    class Package;\n    class Type;\n    class Entry;\n    class ConfigList;\n\n    /**\n     * Exposed for testing. Determines whether a versioned resource should be generated\n     * based on the other available configurations for that resource.\n     */\n    static bool shouldGenerateVersionedResource(const sp<ConfigList>& configList,\n                                                const ConfigDescription& sourceConfig,\n                                                const int sdkVersionToGenerate);\n\n    ResourceTable(Bundle* bundle, const String16& assetsPackage, PackageType type);\n\n    const String16& getAssetsPackage() const {\n        return mAssetsPackage;\n    }\n\n    /**\n     * Returns the queue of resources that need to be compiled.\n     * This is only used for resources that have been generated\n     * during the compilation phase. If they were just added\n     * to the AaptAssets, then they may be skipped over\n     * and would mess up iteration order for the existing\n     * resources.\n     */\n    std::queue<CompileResourceWorkItem>& getWorkQueue() {\n        return mWorkQueue;\n    }\n\n    status_t addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets);\n\n    status_t addPublic(const SourcePos& pos,\n                       const String16& package,\n                       const String16& type,\n                       const String16& name,\n                       const uint32_t ident);\n\n    status_t addEntry(const SourcePos& pos,\n                      const String16& package,\n                      const String16& type,\n                      const String16& name,\n                      const String16& value,\n                      const Vector<StringPool::entry_style_span>* style = NULL,\n                      const ResTable_config* params = NULL,\n                      const bool doSetIndex = false,\n                      const int32_t format = ResTable_map::TYPE_ANY,\n                      const bool overwrite = false);\n\n    status_t startBag(const SourcePos& pos,\n                    const String16& package,\n                    const String16& type,\n                    const String16& name,\n                    const String16& bagParent,\n                    const ResTable_config* params = NULL,\n                    bool overlay = false,\n                    bool replace = false,\n                    bool isId = false);\n    \n    status_t addBag(const SourcePos& pos,\n                    const String16& package,\n                    const String16& type,\n                    const String16& name,\n                    const String16& bagParent,\n                    const String16& bagKey,\n                    const String16& value,\n                    const Vector<StringPool::entry_style_span>* style = NULL,\n                    const ResTable_config* params = NULL,\n                    bool replace = false,\n                    bool isId = false,\n                    const int32_t format = ResTable_map::TYPE_ANY);\n\n    bool hasBagOrEntry(const String16& package,\n                       const String16& type,\n                       const String16& name) const;\n\n    bool hasBagOrEntry(const String16& package,\n                       const String16& type,\n                       const String16& name,\n                       const ResTable_config& config) const;\n\n    bool hasBagOrEntry(const String16& ref,\n                       const String16* defType = NULL,\n                       const String16* defPackage = NULL);\n\n    bool appendComment(const String16& package,\n                       const String16& type,\n                       const String16& name,\n                       const String16& comment,\n                       bool onlyIfEmpty = false);\n\n    bool appendTypeComment(const String16& package,\n                           const String16& type,\n                           const String16& name,\n                           const String16& comment);\n    \n    void canAddEntry(const SourcePos& pos,\n        const String16& package, const String16& type, const String16& name);\n        \n    size_t size() const;\n    size_t numLocalResources() const;\n    bool hasResources() const;\n\n    status_t modifyForCompat(const Bundle* bundle);\n    status_t modifyForCompat(const Bundle* bundle,\n                             const String16& resourceName,\n                             const sp<AaptFile>& file,\n                             const sp<XMLNode>& root);\n\n    status_t processBundleFormat(const Bundle* bundle,\n                                 const String16& resourceName,\n                                 const sp<AaptFile>& file,\n                                 const sp<XMLNode>& parent);\n\n\n    sp<AaptFile> flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,\n            const bool isBase);\n\n    static inline uint32_t makeResId(uint32_t packageId,\n                                     uint32_t typeId,\n                                     uint32_t nameId)\n    {\n        return nameId | (typeId<<16) | (packageId<<24);\n    }\n\n    static inline uint32_t getResId(const sp<Package>& p,\n                                    const sp<Type>& t,\n                                    uint32_t nameId);\n\n    uint32_t getResId(const String16& package,\n                      const String16& type,\n                      const String16& name,\n                      bool onlyPublic = true) const;\n\n    uint32_t getResId(const String16& ref,\n                      const String16* defType = NULL,\n                      const String16* defPackage = NULL,\n                      const char** outErrorMsg = NULL,\n                      bool onlyPublic = true) const;\n\n    static bool isValidResourceName(const String16& s);\n    \n    bool stringToValue(Res_value* outValue, StringPool* pool,\n                       const String16& str,\n                       bool preserveSpaces, bool coerceType,\n                       uint32_t attrID,\n                       const Vector<StringPool::entry_style_span>* style = NULL,\n                       String16* outStr = NULL, void* accessorCookie = NULL,\n                       uint32_t attrType = ResTable_map::TYPE_ANY,\n                       const String8* configTypeName = NULL,\n                       const ConfigDescription* config = NULL);\n\n    status_t assignResourceIds(Bundle *bundle);\n    status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL,\n                        bool skipSymbolsWithoutDefaultLocalization = false);\n    void addLocalization(const String16& name, const String8& locale, const SourcePos& src);\n    void addDefaultLocalization(const String16& name);\n    status_t validateLocalizations(void);\n\n    status_t flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,\n            const sp<AaptFile>& dest, const bool isBase);\n    status_t flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs);\n\n    void writePublicDefinitions(const String16& package, FILE* fp);\n\n    virtual uint32_t getCustomResource(const String16& package,\n                                       const String16& type,\n                                       const String16& name) const;\n    virtual uint32_t getCustomResourceWithCreation(const String16& package,\n                                                   const String16& type,\n                                                   const String16& name,\n                                                   const bool createIfNeeded);\n    virtual uint32_t getRemappedPackage(uint32_t origPackage) const;\n    virtual bool getAttributeType(uint32_t attrID, uint32_t* outType);\n    virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin);\n    virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax);\n    virtual bool getAttributeKeys(uint32_t attrID, Vector<String16>* outKeys);\n    virtual bool getAttributeEnum(uint32_t attrID,\n                                  const char16_t* name, size_t nameLen,\n                                  Res_value* outValue);\n    virtual bool getAttributeFlags(uint32_t attrID,\n                                   const char16_t* name, size_t nameLen,\n                                   Res_value* outValue);\n    virtual uint32_t getAttributeL10N(uint32_t attrID);\n\n    virtual bool getLocalizationSetting();\n    virtual void reportError(void* accessorCookie, const char* fmt, ...);\n\n    void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; }\n\n    class Item {\n    public:\n        Item() : isId(false), format(ResTable_map::TYPE_ANY), bagKeyId(0), evaluating(false)\n            { memset(&parsedValue, 0, sizeof(parsedValue)); }\n        Item(const SourcePos& pos,\n             bool _isId,\n             const String16& _value,\n             const Vector<StringPool::entry_style_span>* _style = NULL,\n             int32_t format = ResTable_map::TYPE_ANY);\n        Item(const Item& o) : sourcePos(o.sourcePos),\n            isId(o.isId), value(o.value), style(o.style),\n            format(o.format), bagKeyId(o.bagKeyId), evaluating(false) {\n            memset(&parsedValue, 0, sizeof(parsedValue));\n        }\n        ~Item() { }\n\n        Item& operator=(const Item& o) {\n            sourcePos = o.sourcePos;\n            isId = o.isId;\n            value = o.value;\n            style = o.style;\n            format = o.format;\n            bagKeyId = o.bagKeyId;\n            parsedValue = o.parsedValue;\n            return *this;\n        }\n\n        SourcePos                               sourcePos;\n        mutable bool                            isId;\n        String16                                value;\n        Vector<StringPool::entry_style_span>    style;\n        int32_t                                 format;\n        uint32_t                                bagKeyId;\n        mutable bool                            evaluating;\n        Res_value                               parsedValue;\n    };\n\n    class Entry : public RefBase {\n    public:\n        Entry(const String16& name, const SourcePos& pos)\n            : mName(name), mType(TYPE_UNKNOWN),\n              mItemFormat(ResTable_map::TYPE_ANY), mNameIndex(-1), mPos(pos)\n        { }\n\n        Entry(const Entry& entry);\n        Entry& operator=(const Entry& entry);\n\n        virtual ~Entry() { }\n\n        enum type {\n            TYPE_UNKNOWN = 0,\n            TYPE_ITEM,\n            TYPE_BAG\n        };\n        \n        String16 getName() const { return mName; }\n        type getType() const { return mType; }\n\n        void setParent(const String16& parent) { mParent = parent; }\n        String16 getParent() const { return mParent; }\n\n        status_t makeItABag(const SourcePos& sourcePos);\n\n        status_t emptyBag(const SourcePos& sourcePos);\n \n        status_t setItem(const SourcePos& pos,\n                         const String16& value,\n                         const Vector<StringPool::entry_style_span>* style = NULL,\n                         int32_t format = ResTable_map::TYPE_ANY,\n                         const bool overwrite = false);\n\n        status_t addToBag(const SourcePos& pos,\n                          const String16& key, const String16& value,\n                          const Vector<StringPool::entry_style_span>* style = NULL,\n                          bool replace=false, bool isId = false,\n                          int32_t format = ResTable_map::TYPE_ANY);\n\n        status_t removeFromBag(const String16& key);\n\n        // Index of the entry's name string in the key pool.\n        int32_t getNameIndex() const { return mNameIndex; }\n        void setNameIndex(int32_t index) { mNameIndex = index; }\n\n        const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; }\n        const KeyedVector<String16, Item>& getBag() const { return mBag; }\n\n        status_t generateAttributes(ResourceTable* table,\n                                    const String16& package);\n\n        status_t assignResourceIds(ResourceTable* table,\n                                   const String16& package,\n                                   Bundle *bundle);\n\n        status_t prepareFlatten(StringPool* strings, ResourceTable* table,\n               const String8* configTypeName, const ConfigDescription* config);\n\n        status_t remapStringValue(StringPool* strings);\n\n        ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic);\n\n        const SourcePos& getPos() const { return mPos; }\n\n    private:\n        String16 mName;\n        String16 mParent;\n        type mType;\n        Item mItem;\n        int32_t mItemFormat;\n        KeyedVector<String16, Item> mBag;\n        int32_t mNameIndex;\n        uint32_t mParentId;\n        SourcePos mPos;\n    };\n    \n    class ConfigList : public RefBase {\n    public:\n        ConfigList(const String16& name, const SourcePos& pos)\n            : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { }\n        virtual ~ConfigList() { }\n        \n        String16 getName() const { return mName; }\n        const SourcePos& getPos() const { return mPos; }\n        \n        void appendComment(const String16& comment, bool onlyIfEmpty = false);\n        const String16& getComment() const { return mComment; }\n        \n        void appendTypeComment(const String16& comment);\n        const String16& getTypeComment() const { return mTypeComment; }\n        \n        // Index of this entry in its Type.\n        int32_t getEntryIndex() const { return mEntryIndex; }\n        void setEntryIndex(int32_t index) { mEntryIndex = index; }\n        \n        void setPublic(bool pub) { mPublic = pub; }\n        bool getPublic() const { return mPublic; }\n        void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; }\n        const SourcePos& getPublicSourcePos() { return mPublicSourcePos; }\n        \n        void addEntry(const ResTable_config& config, const sp<Entry>& entry) {\n            mEntries.add(config, entry);\n        }\n        \n        const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; }\n    private:\n        const String16 mName;\n        const SourcePos mPos;\n        String16 mComment;\n        String16 mTypeComment;\n        bool mPublic;\n        SourcePos mPublicSourcePos;\n        int32_t mEntryIndex;\n        DefaultKeyedVector<ConfigDescription, sp<Entry> > mEntries;\n    };\n    \n    class Public {\n    public:\n        Public() : sourcePos(), ident(0) { }\n        Public(const SourcePos& pos,\n               const String16& _comment,\n               uint32_t _ident)\n            : sourcePos(pos),\n            comment(_comment), ident(_ident) { }\n        Public(const Public& o) : sourcePos(o.sourcePos),\n            comment(o.comment), ident(o.ident) { }\n        ~Public() { }\n        \n        Public& operator=(const Public& o) {\n            sourcePos = o.sourcePos;\n            comment = o.comment;\n            ident = o.ident;\n            return *this;\n        }\n        \n        SourcePos   sourcePos;\n        String16    comment;\n        uint32_t    ident;\n    };\n    \n    class Type : public RefBase {\n    public:\n        Type(const String16& name, const SourcePos& pos)\n                : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos)\n        { }\n        virtual ~Type() { delete mFirstPublicSourcePos; }\n\n        status_t addPublic(const SourcePos& pos,\n                           const String16& name,\n                           const uint32_t ident);\n                           \n        void canAddEntry(const String16& name);\n        \n        String16 getName() const { return mName; }\n        sp<Entry> getEntry(const String16& entry,\n                           const SourcePos& pos,\n                           const ResTable_config* config = NULL,\n                           bool doSetIndex = false,\n                           bool overlay = false,\n                           bool autoAddOverlay = false);\n\n        bool isPublic(const String16& entry) const {\n            return mPublic.indexOfKey(entry) >= 0;\n        }\n\n        sp<ConfigList> removeEntry(const String16& entry);\n\n        SortedVector<ConfigDescription> getUniqueConfigs() const;\n\n        const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }\n\n        int32_t getPublicIndex(const String16& entry) /*const*/;\n\n        int32_t getPublicIndex() const { return mPublicIndex; }\n\n        int32_t getIndex() const { return mIndex; }\n        void setIndex(int32_t index) { mIndex = index; }\n\n        status_t applyPublicEntryOrder(bool patch);\n\n        const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }\n        const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }\n        const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }\n        \n        const SourcePos& getPos() const { return mPos; }\n\n    private:\n        String16 mName;\n        SourcePos* mFirstPublicSourcePos;\n        DefaultKeyedVector<String16, Public> mPublic;\n        DefaultKeyedVector<String16, sp<ConfigList> > mConfigs;\n        Vector<sp<ConfigList> > mOrderedConfigs;\n        SortedVector<String16> mCanAddEntries;\n        int32_t mPublicIndex;\n        int32_t mIndex;\n        SourcePos mPos;\n    };\n\n    class Package : public RefBase {\n    public:\n        Package(const String16& name, size_t packageId);\n        virtual ~Package() { }\n\n        String16 getName() const { return mName; }\n        sp<Type> getType(const String16& type,\n                         const SourcePos& pos,\n                         bool doSetIndex = false);\n\n        size_t getAssignedId() const { return mPackageId; }\n\n        const ResStringPool& getTypeStrings() const { return mTypeStrings; }\n        uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); }\n        const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; }\n        status_t setTypeStrings(const sp<AaptFile>& data);\n\n        const ResStringPool& getKeyStrings() const { return mKeyStrings; }\n        uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); }\n        const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; }\n        status_t setKeyStrings(const sp<AaptFile>& data);\n\n        status_t applyPublicTypeOrder();\n\n        const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; }\n        const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; }\n\n        void movePrivateAttrs();\n\n    private:\n        status_t setStrings(const sp<AaptFile>& data,\n                            ResStringPool* strings,\n                            DefaultKeyedVector<String16, uint32_t>* mappings);\n\n        const String16 mName;\n        const size_t mPackageId;\n        DefaultKeyedVector<String16, sp<Type> > mTypes;\n        Vector<sp<Type> > mOrderedTypes;\n        sp<AaptFile> mTypeStringsData;\n        sp<AaptFile> mKeyStringsData;\n        ResStringPool mTypeStrings;\n        ResStringPool mKeyStrings;\n        DefaultKeyedVector<String16, uint32_t> mTypeStringsMapping;\n        DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;\n    };\n\n    void getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources);\n\n    /**\n     * Make an attribute with the specified format. If another attribute with the same name but\n     * different format exists, this method returns false. If the name is not taken, or if the\n     * format is identical, this returns true.\n     */\n    bool makeAttribute(const String16& package,\n                       const String16& name,\n                       const SourcePos& source,\n                       int32_t format,\n                       const String16& comment,\n                       bool appendComment);\n\nprivate:\n    void writePublicDefinitions(const String16& package, FILE* fp, bool pub);\n    sp<Package> getPackage(const String16& package);\n    sp<Type> getType(const String16& package,\n                     const String16& type,\n                     const SourcePos& pos,\n                     bool doSetIndex = false);\n    sp<Entry> getEntry(const String16& package,\n                       const String16& type,\n                       const String16& name,\n                       const SourcePos& pos,\n                       bool overlay,\n                       const ResTable_config* config = NULL,\n                       bool doSetIndex = false);\n    sp<const Entry> getEntry(uint32_t resID,\n                             const ResTable_config* config = NULL) const;\n    sp<ConfigList> getConfigList(const String16& package,\n                                 const String16& type,\n                                 const String16& name) const;\n    const Item* getItem(uint32_t resID, uint32_t attrID) const;\n    bool getItemValue(uint32_t resID, uint32_t attrID,\n                      Res_value* outValue);\n    int getPublicAttributeSdkLevel(uint32_t attrId) const;\n\n    status_t processBundleFormatImpl(const Bundle* bundle,\n                                     const String16& resourceName,\n                                     const sp<AaptFile>& file,\n                                     const sp<XMLNode>& parent,\n                                     Vector<sp<XMLNode> >* namespaces);\n\n    String16 mAssetsPackage;\n    PackageType mPackageType;\n    sp<AaptAssets> mAssets;\n    uint32_t mTypeIdOffset;\n    DefaultKeyedVector<String16, sp<Package> > mPackages;\n    Vector<sp<Package> > mOrderedPackages;\n    size_t mNumLocal;\n    SourcePos mCurrentXmlPos;\n    Bundle* mBundle;\n\n    // key = string resource name, value = set of locales in which that name is defined\n    std::map<String16, std::map<String8, SourcePos>> mLocalizations;\n    // set of string resources names that have a default localization\n    std::set<String16> mHasDefaultLocalization;\n    std::queue<CompileResourceWorkItem> mWorkQueue;\n};\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/SdkConstants.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef H_AAPT_SDK_CONSTANTS\n#define H_AAPT_SDK_CONSTANTS\n\nenum {\n    SDK_CUPCAKE = 3,\n    SDK_DONUT = 4,\n    SDK_ECLAIR = 5,\n    SDK_ECLAIR_0_1 = 6,\n    SDK_ECLAIR_MR1 = 7,\n    SDK_FROYO = 8,\n    SDK_GINGERBREAD = 9,\n    SDK_GINGERBREAD_MR1 = 10,\n    SDK_HONEYCOMB = 11,\n    SDK_HONEYCOMB_MR1 = 12,\n    SDK_HONEYCOMB_MR2 = 13,\n    SDK_ICE_CREAM_SANDWICH = 14,\n    SDK_ICE_CREAM_SANDWICH_MR1 = 15,\n    SDK_JELLY_BEAN = 16,\n    SDK_JELLY_BEAN_MR1 = 17,\n    SDK_JELLY_BEAN_MR2 = 18,\n    SDK_KITKAT = 19,\n    SDK_KITKAT_WATCH = 20,\n    SDK_LOLLIPOP = 21,\n    SDK_LOLLIPOP_MR1 = 22,\n    SDK_MNC = 23,\n};\n\n#endif // H_AAPT_SDK_CONSTANTS\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/SourcePos.cpp",
    "content": "#include \"SourcePos.h\"\n\n#include <stdarg.h>\n#include <vector>\n\nusing namespace std;\n\n\n// ErrorPos\n// =============================================================================\nstruct ErrorPos\n{\n    enum Level {\n        NOTE,\n        WARNING,\n        ERROR\n    };\n\n    String8 file;\n    int line;\n    String8 error;\n    Level level;\n\n    ErrorPos();\n    ErrorPos(const ErrorPos& that);\n    ErrorPos(const String8& file, int line, const String8& error, Level level);\n    ErrorPos& operator=(const ErrorPos& rhs);\n\n    void print(FILE* to) const;\n};\n\nstatic vector<ErrorPos> g_errors;\n\nErrorPos::ErrorPos()\n    :line(-1), level(NOTE)\n{\n}\n\nErrorPos::ErrorPos(const ErrorPos& that)\n    :file(that.file),\n     line(that.line),\n     error(that.error),\n     level(that.level)\n{\n}\n\nErrorPos::ErrorPos(const String8& f, int l, const String8& e, Level lev)\n    :file(f),\n     line(l),\n     error(e),\n     level(lev)\n{\n}\n\nErrorPos&\nErrorPos::operator=(const ErrorPos& rhs)\n{\n    this->file = rhs.file;\n    this->line = rhs.line;\n    this->error = rhs.error;\n    this->level = rhs.level;\n    return *this;\n}\n\nvoid\nErrorPos::print(FILE* to) const\n{\n    const char* type = \"\";\n    switch (level) {\n    case NOTE:\n        type = \"note: \";\n        break;\n    case WARNING:\n        type = \"warning: \";\n        break;\n    case ERROR:\n        type = \"error: \";\n        break;\n    }\n    \n    if (!this->file.isEmpty()) {\n        if (this->line >= 0) {\n            fprintf(to, \"%s:%d: %s%s\\n\", this->file.string(), this->line, type, this->error.string());\n        } else {\n            fprintf(to, \"%s: %s%s\\n\", this->file.string(), type, this->error.string());\n        }\n    } else {\n        fprintf(to, \"%s%s\\n\", type, this->error.string());\n    }\n}\n\n// SourcePos\n// =============================================================================\nSourcePos::SourcePos(const String8& f, int l)\n    : file(f), line(l)\n{\n}\n\nSourcePos::SourcePos(const SourcePos& that)\n    : file(that.file), line(that.line)\n{\n}\n\nSourcePos::SourcePos()\n    : file(\"???\", 0), line(-1)\n{\n}\n\nSourcePos::~SourcePos()\n{\n}\n\nvoid\nSourcePos::error(const char* fmt, ...) const\n{\n    va_list ap;\n    va_start(ap, fmt);\n    String8 msg = String8::formatV(fmt, ap);\n    va_end(ap);\n    g_errors.push_back(ErrorPos(this->file, this->line, msg, ErrorPos::ERROR));\n}\n\nvoid\nSourcePos::warning(const char* fmt, ...) const\n{\n    va_list ap;\n    va_start(ap, fmt);\n    String8 msg = String8::formatV(fmt, ap);\n    va_end(ap);\n    ErrorPos(this->file, this->line, msg, ErrorPos::WARNING).print(stderr);\n}\n\nvoid\nSourcePos::printf(const char* fmt, ...) const\n{\n    va_list ap;\n    va_start(ap, fmt);\n    String8 msg = String8::formatV(fmt, ap);\n    va_end(ap);\n    ErrorPos(this->file, this->line, msg, ErrorPos::NOTE).print(stderr);\n}\n\nbool\nSourcePos::operator<(const SourcePos& rhs) const\n{\n    return (file < rhs.file) || (line < rhs.line);\n}\n\nbool\nSourcePos::hasErrors()\n{\n    return g_errors.size() > 0;\n}\n\nvoid\nSourcePos::printErrors(FILE* to)\n{\n    vector<ErrorPos>::const_iterator it;\n    for (it=g_errors.begin(); it!=g_errors.end(); it++) {\n        it->print(to);\n    }\n}\n\n\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/SourcePos.h",
    "content": "#ifndef SOURCEPOS_H\n#define SOURCEPOS_H\n\n#include <utils/String8.h>\n#include <stdio.h>\n\nusing namespace android;\n\nclass SourcePos\n{\npublic:\n    String8 file;\n    int line;\n\n    SourcePos(const String8& f, int l);\n    SourcePos(const SourcePos& that);\n    SourcePos();\n    ~SourcePos();\n\n    void error(const char* fmt, ...) const;\n    void warning(const char* fmt, ...) const;\n    void printf(const char* fmt, ...) const;\n\n    bool operator<(const SourcePos& rhs) const;\n\n    static bool hasErrors();\n    static void printErrors(FILE* to);\n};\n\n\n#endif // SOURCEPOS_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/StringPool.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n#include \"StringPool.h\"\n\n#include <utils/ByteOrder.h>\n#include <utils/SortedVector.h>\n\n#include <algorithm>\n\n#include \"ResourceTable.h\"\n\n// SSIZE: mingw does not have signed size_t == ssize_t.\n#if !defined(_WIN32)\n#  define ZD \"%zd\"\n#  define ZD_TYPE ssize_t\n#  define SSIZE(x) x\n#else\n#  define ZD \"%ld\"\n#  define ZD_TYPE long\n#  define SSIZE(x) (signed size_t)x\n#endif\n\n// Set to true for noisy debug output.\nstatic const bool kIsDebug = false;\n\n#if __cplusplus >= 201103L\nvoid strcpy16_htod(char16_t* dst, const char16_t* src)\n{\n    while (*src) {\n        char16_t s = htods(*src);\n        *dst++ = s;\n        src++;\n    }\n    *dst = 0;\n}\n#endif\n\nvoid strcpy16_htod(uint16_t* dst, const char16_t* src)\n{\n    while (*src) {\n        uint16_t s = htods(static_cast<uint16_t>(*src));\n        *dst++ = s;\n        src++;\n    }\n    *dst = 0;\n}\n\nvoid printStringPool(const ResStringPool* pool)\n{\n    if (pool->getError() == NO_INIT) {\n        printf(\"String pool is unitialized.\\n\");\n        return;\n    } else if (pool->getError() != NO_ERROR) {\n        printf(\"String pool is corrupt/invalid.\\n\");\n        return;\n    }\n\n    SortedVector<const void*> uniqueStrings;\n    const size_t N = pool->size();\n    for (size_t i=0; i<N; i++) {\n        size_t len;\n        if (pool->isUTF8()) {\n            uniqueStrings.add(pool->string8At(i, &len));\n        } else {\n            uniqueStrings.add(pool->stringAt(i, &len));\n        }\n    }\n\n    printf(\"String pool of \" ZD \" unique %s %s strings, \" ZD \" entries and \"\n            ZD \" styles using \" ZD \" bytes:\\n\",\n            (ZD_TYPE)uniqueStrings.size(), pool->isUTF8() ? \"UTF-8\" : \"UTF-16\",\n            pool->isSorted() ? \"sorted\" : \"non-sorted\",\n            (ZD_TYPE)N, (ZD_TYPE)pool->styleCount(), (ZD_TYPE)pool->bytes());\n\n    const size_t NS = pool->size();\n    for (size_t s=0; s<NS; s++) {\n        String8 str = pool->string8ObjectAt(s);\n        printf(\"String #\" ZD \": %s\\n\", (ZD_TYPE) s, str.string());\n    }\n}\n\nString8 StringPool::entry::makeConfigsString() const {\n    String8 configStr(configTypeName);\n    if (configStr.size() > 0) configStr.append(\" \");\n    if (configs.size() > 0) {\n        for (size_t j=0; j<configs.size(); j++) {\n            if (j > 0) configStr.append(\", \");\n            configStr.append(configs[j].toString());\n        }\n    } else {\n        configStr = \"(none)\";\n    }\n    return configStr;\n}\n\nint StringPool::entry::compare(const entry& o) const {\n    // Strings with styles go first, to reduce the size of the styles array.\n    // We don't care about the relative order of these strings.\n    if (hasStyles) {\n        return o.hasStyles ? 0 : -1;\n    }\n    if (o.hasStyles) {\n        return 1;\n    }\n\n    // Sort unstyled strings by type, then by logical configuration.\n    int comp = configTypeName.compare(o.configTypeName);\n    if (comp != 0) {\n        return comp;\n    }\n    const size_t LHN = configs.size();\n    const size_t RHN = o.configs.size();\n    size_t i=0;\n    while (i < LHN && i < RHN) {\n        comp = configs[i].compareLogical(o.configs[i]);\n        if (comp != 0) {\n            return comp;\n        }\n        i++;\n    }\n    if (LHN < RHN) return -1;\n    else if (LHN > RHN) return 1;\n    return 0;\n}\n\nStringPool::StringPool(bool utf8) :\n        mUTF8(utf8), mValues(-1)\n{\n}\n\nssize_t StringPool::add(const String16& value, const Vector<entry_style_span>& spans,\n        const String8* configTypeName, const ResTable_config* config)\n{\n    ssize_t res = add(value, false, configTypeName, config);\n    if (res >= 0) {\n        addStyleSpans(res, spans);\n    }\n    return res;\n}\n\nssize_t StringPool::add(const String16& value,\n        bool mergeDuplicates, const String8* configTypeName, const ResTable_config* config)\n{\n    ssize_t vidx = mValues.indexOfKey(value);\n    ssize_t pos = vidx >= 0 ? mValues.valueAt(vidx) : -1;\n    ssize_t eidx = pos >= 0 ? mEntryArray.itemAt(pos) : -1;\n    if (eidx < 0) {\n        eidx = mEntries.add(entry(value));\n        if (eidx < 0) {\n            fprintf(stderr, \"Failure adding string %s\\n\", String8(value).string());\n            return eidx;\n        }\n    }\n\n    if (configTypeName != NULL) {\n        entry& ent = mEntries.editItemAt(eidx);\n        if (kIsDebug) {\n            printf(\"*** adding config type name %s, was %s\\n\",\n                    configTypeName->string(), ent.configTypeName.string());\n        }\n        if (ent.configTypeName.size() <= 0) {\n            ent.configTypeName = *configTypeName;\n        } else if (ent.configTypeName != *configTypeName) {\n            ent.configTypeName = \" \";\n        }\n    }\n\n    if (config != NULL) {\n        // Add this to the set of configs associated with the string.\n        entry& ent = mEntries.editItemAt(eidx);\n        size_t addPos;\n        for (addPos=0; addPos<ent.configs.size(); addPos++) {\n            int cmp = ent.configs.itemAt(addPos).compareLogical(*config);\n            if (cmp >= 0) {\n                if (cmp > 0) {\n                    if (kIsDebug) {\n                        printf(\"*** inserting config: %s\\n\", config->toString().string());\n                    }\n                    ent.configs.insertAt(*config, addPos);\n                }\n                break;\n            }\n        }\n        if (addPos >= ent.configs.size()) {\n            if (kIsDebug) {\n                printf(\"*** adding config: %s\\n\", config->toString().string());\n            }\n            ent.configs.add(*config);\n        }\n    }\n\n    const bool first = vidx < 0;\n    const bool styled = (pos >= 0 && (size_t)pos < mEntryStyleArray.size()) ?\n        mEntryStyleArray[pos].spans.size() : 0;\n    if (first || styled || !mergeDuplicates) {\n        pos = mEntryArray.add(eidx);\n        if (first) {\n            vidx = mValues.add(value, pos);\n        }\n        entry& ent = mEntries.editItemAt(eidx);\n        ent.indices.add(pos);\n    }\n\n    if (kIsDebug) {\n        printf(\"Adding string %s to pool: pos=%zd eidx=%zd vidx=%zd\\n\",\n                String8(value).string(), SSIZE(pos), SSIZE(eidx), SSIZE(vidx));\n    }\n\n    return pos;\n}\n\nstatus_t StringPool::addStyleSpan(size_t idx, const String16& name,\n                                  uint32_t start, uint32_t end)\n{\n    entry_style_span span;\n    span.name = name;\n    span.span.firstChar = start;\n    span.span.lastChar = end;\n    return addStyleSpan(idx, span);\n}\n\nstatus_t StringPool::addStyleSpans(size_t idx, const Vector<entry_style_span>& spans)\n{\n    const size_t N=spans.size();\n    for (size_t i=0; i<N; i++) {\n        status_t err = addStyleSpan(idx, spans[i]);\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n    return NO_ERROR;\n}\n\nstatus_t StringPool::addStyleSpan(size_t idx, const entry_style_span& span)\n{\n    // Place blank entries in the span array up to this index.\n    while (mEntryStyleArray.size() <= idx) {\n        mEntryStyleArray.add();\n    }\n\n    entry_style& style = mEntryStyleArray.editItemAt(idx);\n    style.spans.add(span);\n    mEntries.editItemAt(mEntryArray[idx]).hasStyles = true;\n    return NO_ERROR;\n}\n\nStringPool::ConfigSorter::ConfigSorter(const StringPool& pool) : pool(pool)\n{\n}\n\nbool StringPool::ConfigSorter::operator()(size_t l, size_t r)\n{\n    const StringPool::entry& lhe = pool.mEntries[pool.mEntryArray[l]];\n    const StringPool::entry& rhe = pool.mEntries[pool.mEntryArray[r]];\n    return lhe.compare(rhe) < 0;\n}\n\nvoid StringPool::sortByConfig()\n{\n    LOG_ALWAYS_FATAL_IF(mOriginalPosToNewPos.size() > 0, \"Can't sort string pool after already sorted.\");\n\n    const size_t N = mEntryArray.size();\n\n    // This is a vector that starts out with a 1:1 mapping to entries\n    // in the array, which we will sort to come up with the desired order.\n    // At that point it maps from the new position in the array to the\n    // original position the entry appeared.\n    Vector<size_t> newPosToOriginalPos;\n    newPosToOriginalPos.setCapacity(N);\n    for (size_t i=0; i < N; i++) {\n        newPosToOriginalPos.add(i);\n    }\n\n    // Sort the array.\n    if (kIsDebug) {\n        printf(\"SORTING STRINGS BY CONFIGURATION...\\n\");\n    }\n    ConfigSorter sorter(*this);\n    std::sort(newPosToOriginalPos.begin(), newPosToOriginalPos.end(), sorter);\n    if (kIsDebug) {\n        printf(\"DONE SORTING STRINGS BY CONFIGURATION.\\n\");\n    }\n\n    // Create the reverse mapping from the original position in the array\n    // to the new position where it appears in the sorted array.  This is\n    // so that clients can re-map any positions they had previously stored.\n    mOriginalPosToNewPos = newPosToOriginalPos;\n    for (size_t i=0; i<N; i++) {\n        mOriginalPosToNewPos.editItemAt(newPosToOriginalPos[i]) = i;\n    }\n\n#if 0\n    SortedVector<entry> entries;\n\n    for (size_t i=0; i<N; i++) {\n        printf(\"#%d was %d: %s\\n\", i, newPosToOriginalPos[i],\n                mEntries[mEntryArray[newPosToOriginalPos[i]]].makeConfigsString().string());\n        entries.add(mEntries[mEntryArray[i]]);\n    }\n\n    for (size_t i=0; i<entries.size(); i++) {\n        printf(\"Sorted config #%d: %s\\n\", i,\n                entries[i].makeConfigsString().string());\n    }\n#endif\n\n    // Now we rebuild the arrays.\n    Vector<entry> newEntries;\n    Vector<size_t> newEntryArray;\n    Vector<entry_style> newEntryStyleArray;\n    DefaultKeyedVector<size_t, size_t> origOffsetToNewOffset;\n\n    for (size_t i=0; i<N; i++) {\n        // We are filling in new offset 'i'; oldI is where we can find it\n        // in the original data structure.\n        size_t oldI = newPosToOriginalPos[i];\n        // This is the actual entry associated with the old offset.\n        const entry& oldEnt = mEntries[mEntryArray[oldI]];\n        // This is the same entry the last time we added it to the\n        // new entry array, if any.\n        ssize_t newIndexOfOffset = origOffsetToNewOffset.indexOfKey(oldI);\n        size_t newOffset;\n        if (newIndexOfOffset < 0) {\n            // This is the first time we have seen the entry, so add\n            // it.\n            newOffset = newEntries.add(oldEnt);\n            newEntries.editItemAt(newOffset).indices.clear();\n        } else {\n            // We have seen this entry before, use the existing one\n            // instead of adding it again.\n            newOffset = origOffsetToNewOffset.valueAt(newIndexOfOffset);\n        }\n        // Update the indices to include this new position.\n        newEntries.editItemAt(newOffset).indices.add(i);\n        // And add the offset of the entry to the new entry array.\n        newEntryArray.add(newOffset);\n        // Add any old style to the new style array.\n        if (mEntryStyleArray.size() > 0) {\n            if (oldI < mEntryStyleArray.size()) {\n                newEntryStyleArray.add(mEntryStyleArray[oldI]);\n            } else {\n                newEntryStyleArray.add(entry_style());\n            }\n        }\n    }\n\n    // Now trim any entries at the end of the new style array that are\n    // not needed.\n    for (ssize_t i=newEntryStyleArray.size()-1; i>=0; i--) {\n        const entry_style& style = newEntryStyleArray[i];\n        if (style.spans.size() > 0) {\n            // That's it.\n            break;\n        }\n        // This one is not needed; remove.\n        newEntryStyleArray.removeAt(i);\n    }\n\n    // All done, install the new data structures and upate mValues with\n    // the new positions.\n    mEntries = newEntries;\n    mEntryArray = newEntryArray;\n    mEntryStyleArray = newEntryStyleArray;\n    mValues.clear();\n    for (size_t i=0; i<mEntries.size(); i++) {\n        const entry& ent = mEntries[i];\n        mValues.add(ent.value, ent.indices[0]);\n    }\n\n#if 0\n    printf(\"FINAL SORTED STRING CONFIGS:\\n\");\n    for (size_t i=0; i<mEntries.size(); i++) {\n        const entry& ent = mEntries[i];\n        printf(\"#\" ZD \" %s: %s\\n\", (ZD_TYPE)i, ent.makeConfigsString().string(),\n                String8(ent.value).string());\n    }\n#endif\n}\n\nsp<AaptFile> StringPool::createStringBlock()\n{\n    sp<AaptFile> pool = new AaptFile(String8(), AaptGroupEntry(),\n                                     String8());\n    status_t err = writeStringBlock(pool);\n    return err == NO_ERROR ? pool : NULL;\n}\n\n#define ENCODE_LENGTH(str, chrsz, strSize) \\\n{ \\\n    size_t maxMask = 1 << ((chrsz*8)-1); \\\n    size_t maxSize = maxMask-1; \\\n    if (strSize > maxSize) { \\\n        *str++ = maxMask | ((strSize>>(chrsz*8))&maxSize); \\\n    } \\\n    *str++ = strSize; \\\n}\n\nstatus_t StringPool::writeStringBlock(const sp<AaptFile>& pool)\n{\n    // Allow appending.  Sorry this is a little wacky.\n    if (pool->getSize() > 0) {\n        sp<AaptFile> block = createStringBlock();\n        if (block == NULL) {\n            return UNKNOWN_ERROR;\n        }\n        ssize_t res = pool->writeData(block->getData(), block->getSize());\n        return (res >= 0) ? (status_t)NO_ERROR : res;\n    }\n\n    // First we need to add all style span names to the string pool.\n    // We do this now (instead of when the span is added) so that these\n    // will appear at the end of the pool, not disrupting the order\n    // our client placed their own strings in it.\n    \n    const size_t STYLES = mEntryStyleArray.size();\n    size_t i;\n\n    for (i=0; i<STYLES; i++) {\n        entry_style& style = mEntryStyleArray.editItemAt(i);\n        const size_t N = style.spans.size();\n        for (size_t i=0; i<N; i++) {\n            entry_style_span& span = style.spans.editItemAt(i);\n            ssize_t idx = add(span.name, true);\n            if (idx < 0) {\n                fprintf(stderr, \"Error adding span for style tag '%s'\\n\",\n                        String8(span.name).string());\n                return idx;\n            }\n            span.span.name.index = (uint32_t)idx;\n        }\n    }\n\n    const size_t ENTRIES = mEntryArray.size();\n\n    // Now build the pool of unique strings.\n\n    const size_t STRINGS = mEntries.size();\n    const size_t preSize = sizeof(ResStringPool_header)\n                         + (sizeof(uint32_t)*ENTRIES)\n                         + (sizeof(uint32_t)*STYLES);\n    if (pool->editData(preSize) == NULL) {\n        fprintf(stderr, \"ERROR: Out of memory for string pool\\n\");\n        return NO_MEMORY;\n    }\n\n    const size_t charSize = mUTF8 ? sizeof(uint8_t) : sizeof(uint16_t);\n\n    size_t strPos = 0;\n    for (i=0; i<STRINGS; i++) {\n        entry& ent = mEntries.editItemAt(i);\n        const size_t strSize = (ent.value.size());\n        const size_t lenSize = strSize > (size_t)(1<<((charSize*8)-1))-1 ?\n            charSize*2 : charSize;\n\n        String8 encStr;\n        if (mUTF8) {\n            encStr = String8(ent.value);\n        }\n\n        const size_t encSize = mUTF8 ? encStr.size() : 0;\n        const size_t encLenSize = mUTF8 ?\n            (encSize > (size_t)(1<<((charSize*8)-1))-1 ?\n                charSize*2 : charSize) : 0;\n\n        ent.offset = strPos;\n\n        const size_t totalSize = lenSize + encLenSize +\n            ((mUTF8 ? encSize : strSize)+1)*charSize;\n\n        void* dat = (void*)pool->editData(preSize + strPos + totalSize);\n        if (dat == NULL) {\n            fprintf(stderr, \"ERROR: Out of memory for string pool\\n\");\n            return NO_MEMORY;\n        }\n        dat = (uint8_t*)dat + preSize + strPos;\n        if (mUTF8) {\n            uint8_t* strings = (uint8_t*)dat;\n\n            ENCODE_LENGTH(strings, sizeof(uint8_t), strSize)\n\n            ENCODE_LENGTH(strings, sizeof(uint8_t), encSize)\n\n            strncpy((char*)strings, encStr, encSize+1);\n        } else {\n            char16_t* strings = (char16_t*)dat;\n\n            ENCODE_LENGTH(strings, sizeof(char16_t), strSize)\n\n            strcpy16_htod(strings, ent.value);\n        }\n\n        strPos += totalSize;\n    }\n\n    // Pad ending string position up to a uint32_t boundary.\n\n    if (strPos&0x3) {\n        size_t padPos = ((strPos+3)&~0x3);\n        uint8_t* dat = (uint8_t*)pool->editData(preSize + padPos);\n        if (dat == NULL) {\n            fprintf(stderr, \"ERROR: Out of memory padding string pool\\n\");\n            return NO_MEMORY;\n        }\n        memset(dat+preSize+strPos, 0, padPos-strPos);\n        strPos = padPos;\n    }\n\n    // Build the pool of style spans.\n\n    size_t styPos = strPos;\n    for (i=0; i<STYLES; i++) {\n        entry_style& ent = mEntryStyleArray.editItemAt(i);\n        const size_t N = ent.spans.size();\n        const size_t totalSize = (N*sizeof(ResStringPool_span))\n                               + sizeof(ResStringPool_ref);\n\n        ent.offset = styPos-strPos;\n        uint8_t* dat = (uint8_t*)pool->editData(preSize + styPos + totalSize);\n        if (dat == NULL) {\n            fprintf(stderr, \"ERROR: Out of memory for string styles\\n\");\n            return NO_MEMORY;\n        }\n        ResStringPool_span* span = (ResStringPool_span*)(dat+preSize+styPos);\n        for (size_t i=0; i<N; i++) {\n            span->name.index = htodl(ent.spans[i].span.name.index);\n            span->firstChar = htodl(ent.spans[i].span.firstChar);\n            span->lastChar = htodl(ent.spans[i].span.lastChar);\n            span++;\n        }\n        span->name.index = htodl(ResStringPool_span::END);\n\n        styPos += totalSize;\n    }\n\n    if (STYLES > 0) {\n        // Add full terminator at the end (when reading we validate that\n        // the end of the pool is fully terminated to simplify error\n        // checking).\n        size_t extra = sizeof(ResStringPool_span)-sizeof(ResStringPool_ref);\n        uint8_t* dat = (uint8_t*)pool->editData(preSize + styPos + extra);\n        if (dat == NULL) {\n            fprintf(stderr, \"ERROR: Out of memory for string styles\\n\");\n            return NO_MEMORY;\n        }\n        uint32_t* p = (uint32_t*)(dat+preSize+styPos);\n        while (extra > 0) {\n            *p++ = htodl(ResStringPool_span::END);\n            extra -= sizeof(uint32_t);\n        }\n        styPos += extra;\n    }\n\n    // Write header.\n\n    ResStringPool_header* header =\n        (ResStringPool_header*)pool->padData(sizeof(uint32_t));\n    if (header == NULL) {\n        fprintf(stderr, \"ERROR: Out of memory for string pool\\n\");\n        return NO_MEMORY;\n    }\n    memset(header, 0, sizeof(*header));\n    header->header.type = htods(RES_STRING_POOL_TYPE);\n    header->header.headerSize = htods(sizeof(*header));\n    header->header.size = htodl(pool->getSize());\n    header->stringCount = htodl(ENTRIES);\n    header->styleCount = htodl(STYLES);\n    if (mUTF8) {\n        header->flags |= htodl(ResStringPool_header::UTF8_FLAG);\n    }\n    header->stringsStart = htodl(preSize);\n    header->stylesStart = htodl(STYLES > 0 ? (preSize+strPos) : 0);\n\n    // Write string index array.\n\n    uint32_t* index = (uint32_t*)(header+1);\n    for (i=0; i<ENTRIES; i++) {\n        entry& ent = mEntries.editItemAt(mEntryArray[i]);\n        *index++ = htodl(ent.offset);\n        if (kIsDebug) {\n            printf(\"Writing entry #%zu: \\\"%s\\\" ent=%zu off=%zu\\n\",\n                    i,\n                    String8(ent.value).string(),\n                    mEntryArray[i],\n                    ent.offset);\n        }\n    }\n\n    // Write style index array.\n\n    for (i=0; i<STYLES; i++) {\n        *index++ = htodl(mEntryStyleArray[i].offset);\n    }\n\n    return NO_ERROR;\n}\n\nssize_t StringPool::offsetForString(const String16& val) const\n{\n    const Vector<size_t>* indices = offsetsForString(val);\n    ssize_t res = indices != NULL && indices->size() > 0 ? indices->itemAt(0) : -1;\n    if (kIsDebug) {\n        printf(\"Offset for string %s: %zd (%s)\\n\", String8(val).string(), SSIZE(res),\n                res >= 0 ? String8(mEntries[mEntryArray[res]].value).string() : String8());\n    }\n    return res;\n}\n\nconst Vector<size_t>* StringPool::offsetsForString(const String16& val) const\n{\n    ssize_t pos = mValues.valueFor(val);\n    if (pos < 0) {\n        return NULL;\n    }\n    return &mEntries[mEntryArray[pos]].indices;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/StringPool.h",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#ifndef STRING_POOL_H\n#define STRING_POOL_H\n\n#include \"Main.h\"\n#include \"AaptAssets.h\"\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/String16.h>\n#include <utils/TypeHelpers.h>\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <ctype.h>\n#include <errno.h>\n\nusing namespace android;\n\n#define PRINT_STRING_METRICS 0\n\n#if __cplusplus >= 201103L\nvoid strcpy16_htod(char16_t* dst, const char16_t* src);\n#endif\nvoid strcpy16_htod(uint16_t* dst, const char16_t* src);\n\nvoid printStringPool(const ResStringPool* pool);\n\n/**\n * The StringPool class is used as an intermediate representation for\n * generating the string pool resource data structure that can be parsed with\n * ResStringPool in include/utils/ResourceTypes.h.\n */\nclass StringPool\n{\npublic:\n    struct entry {\n        entry() : offset(0) { }\n        entry(const String16& _value) : value(_value), offset(0), hasStyles(false) { }\n        entry(const entry& o) : value(o.value), offset(o.offset),\n                hasStyles(o.hasStyles), indices(o.indices),\n                configTypeName(o.configTypeName), configs(o.configs) { }\n\n        String16 value;\n        size_t offset;\n        bool hasStyles;\n        Vector<size_t> indices;\n        String8 configTypeName;\n        Vector<ResTable_config> configs;\n\n        String8 makeConfigsString() const;\n\n        int compare(const entry& o) const;\n\n        inline bool operator<(const entry& o) const { return compare(o) < 0; }\n        inline bool operator<=(const entry& o) const { return compare(o) <= 0; }\n        inline bool operator==(const entry& o) const { return compare(o) == 0; }\n        inline bool operator!=(const entry& o) const { return compare(o) != 0; }\n        inline bool operator>=(const entry& o) const { return compare(o) >= 0; }\n        inline bool operator>(const entry& o) const { return compare(o) > 0; }\n    };\n\n    struct entry_style_span {\n        String16 name;\n        ResStringPool_span span;\n    };\n\n    struct entry_style {\n        entry_style() : offset(0) { }\n\n        entry_style(const entry_style& o) : offset(o.offset), spans(o.spans) { }\n\n        size_t offset;\n        Vector<entry_style_span> spans;\n    };\n\n    /**\n     * If 'utf8' is true, strings will be encoded with UTF-8 instead of\n     * left in Java's native UTF-16.\n     */\n    explicit StringPool(bool utf8 = false);\n\n    /**\n     * Add a new string to the pool.  If mergeDuplicates is true, thenif\n     * the string already exists the existing entry for it will be used;\n     * otherwise, or if the value doesn't already exist, a new entry is\n     * created.\n     *\n     * Returns the index in the entry array of the new string entry.\n     */\n    ssize_t add(const String16& value, bool mergeDuplicates = false,\n            const String8* configTypeName = NULL, const ResTable_config* config = NULL);\n\n    ssize_t add(const String16& value, const Vector<entry_style_span>& spans,\n            const String8* configTypeName = NULL, const ResTable_config* config = NULL);\n\n    status_t addStyleSpan(size_t idx, const String16& name,\n                          uint32_t start, uint32_t end);\n    status_t addStyleSpans(size_t idx, const Vector<entry_style_span>& spans);\n    status_t addStyleSpan(size_t idx, const entry_style_span& span);\n\n    // Sort the contents of the string block by the configuration associated\n    // with each item.  After doing this you can use mapOriginalPosToNewPos()\n    // to find out the new position given the position originally returned by\n    // add().\n    void sortByConfig();\n\n    // For use after sortByConfig() to map from the original position of\n    // a string to its new sorted position.\n    size_t mapOriginalPosToNewPos(size_t originalPos) const {\n        return mOriginalPosToNewPos.itemAt(originalPos);\n    }\n\n    sp<AaptFile> createStringBlock();\n\n    status_t writeStringBlock(const sp<AaptFile>& pool);\n\n    /**\n     * Find out an offset in the pool for a particular string.  If the string\n     * pool is sorted, this can not be called until after createStringBlock()\n     * or writeStringBlock() has been called\n     * (which determines the offsets).  In the case of a string that appears\n     * multiple times in the pool, the first offset will be returned.  Returns\n     * -1 if the string does not exist.\n     */\n    ssize_t offsetForString(const String16& val) const;\n\n    /**\n     * Find all of the offsets in the pool for a particular string.  If the\n     * string pool is sorted, this can not be called until after\n     * createStringBlock() or writeStringBlock() has been called\n     * (which determines the offsets).  Returns NULL if the string does not exist.\n     */\n    const Vector<size_t>* offsetsForString(const String16& val) const;\n\nprivate:\n    class ConfigSorter\n    {\n    public:\n        explicit ConfigSorter(const StringPool&);\n        bool operator()(size_t l, size_t r);\n    private:\n        const StringPool& pool;\n    };\n\n    const bool                              mUTF8;\n\n    // The following data structures represent the actual structures\n    // that will be generated for the final string pool.\n\n    // Raw array of unique strings, in some arbitrary order.  This is the\n    // actual strings that appear in the final string pool, in the order\n    // that they will be written.\n    Vector<entry>                           mEntries;\n    // Array of indices into mEntries, in the order they were\n    // added to the pool.  This can be different than mEntries\n    // if the same string was added multiple times (it will appear\n    // once in mEntries, with multiple occurrences in this array).\n    // This is the lookup array that will be written for finding\n    // the string for each offset/position in the string pool.\n    Vector<size_t>                          mEntryArray;\n    // Optional style span information associated with each index of\n    // mEntryArray.\n    Vector<entry_style>                     mEntryStyleArray;\n\n    // The following data structures are used for book-keeping as the\n    // string pool is constructed.\n\n    // Unique set of all the strings added to the pool, mapped to\n    // the first index of mEntryArray where the value was added.\n    DefaultKeyedVector<String16, ssize_t>   mValues;\n    // This array maps from the original position a string was placed at\n    // in mEntryArray to its new position after being sorted with sortByConfig().\n    Vector<size_t>                          mOriginalPosToNewPos;\n};\n\n// The entry types are trivially movable because all fields they contain, including\n// the vectors and strings, are trivially movable.\nnamespace android {\n    ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry);\n    ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry_style_span);\n    ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry_style);\n};\n\n#endif\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/Symbol.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef AAPT_SYMBOL_H\n#define AAPT_SYMBOL_H\n\n#include <utils/String8.h>\n#include <utils/String16.h>\n\n#include \"ConfigDescription.h\"\n#include \"SourcePos.h\"\n\n/**\n * A resource symbol, not attached to any configuration or context.\n */\nstruct Symbol {\n    inline Symbol();\n    inline Symbol(const android::String16& p, const android::String16& t, const android::String16& n, uint32_t i);\n    inline android::String8 toString() const;\n    inline bool operator<(const Symbol& rhs) const;\n\n    android::String16 package;\n    android::String16 type;\n    android::String16 name;\n    uint32_t id;\n\n};\n\n/**\n * A specific defintion of a symbol, defined with a configuration and a definition site.\n */\nstruct SymbolDefinition {\n    inline SymbolDefinition();\n    inline SymbolDefinition(const Symbol& s, const ConfigDescription& c, const SourcePos& src);\n    inline bool operator<(const SymbolDefinition& rhs) const;\n\n    Symbol symbol;\n    ConfigDescription config;\n    SourcePos source;\n};\n\n//\n// Implementations\n//\n\nSymbol::Symbol() {\n}\n\nSymbol::Symbol(const android::String16& p, const android::String16& t, const android::String16& n, uint32_t i)\n    : package(p)\n    , type(t)\n    , name(n)\n    , id(i) {\n}\n\nandroid::String8 Symbol::toString() const {\n    return android::String8::format(\"%s:%s/%s (0x%08x)\",\n            android::String8(package).string(),\n            android::String8(type).string(),\n            android::String8(name).string(),\n            (int) id);\n}\n\nbool Symbol::operator<(const Symbol& rhs) const {\n    return (package < rhs.package) || (type < rhs.type) || (name < rhs.name) || (id < rhs.id);\n}\n\nSymbolDefinition::SymbolDefinition() {\n}\n\nSymbolDefinition::SymbolDefinition(const Symbol& s, const ConfigDescription& c, const SourcePos& src)\n    : symbol(s)\n    , config(c)\n    , source(src) {\n}\n\nbool SymbolDefinition::operator<(const SymbolDefinition& rhs) const {\n    return (symbol < rhs.symbol) || (config < rhs.config) || (source < rhs.source);\n}\n\n#endif // AAPT_SYMBOL_H\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/WorkQueue.cpp",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #define LOG_NDEBUG 0\n#define LOG_TAG \"WorkQueue\"\n\n#include <utils/Log.h>\n#include \"WorkQueue.h\"\n\nnamespace android {\n\n// --- WorkQueue ---\n\nWorkQueue::WorkQueue(size_t maxThreads, bool canCallJava) :\n        mMaxThreads(maxThreads), mCanCallJava(canCallJava),\n        mCanceled(false), mFinished(false), mIdleThreads(0) {\n}\n\nWorkQueue::~WorkQueue() {\n    if (!cancel()) {\n        finish();\n    }\n}\n\nstatus_t WorkQueue::schedule(WorkUnit* workUnit, size_t backlog) {\n    AutoMutex _l(mLock);\n\n    if (mFinished || mCanceled) {\n        return INVALID_OPERATION;\n    }\n\n    if (mWorkThreads.size() < mMaxThreads\n            && mIdleThreads < mWorkUnits.size() + 1) {\n        sp<WorkThread> workThread = new WorkThread(this, mCanCallJava);\n        status_t status = workThread->run(\"WorkQueue::WorkThread\");\n        if (status) {\n            return status;\n        }\n        mWorkThreads.add(workThread);\n        mIdleThreads += 1;\n    } else if (backlog) {\n        while (mWorkUnits.size() >= mMaxThreads * backlog) {\n            mWorkDequeuedCondition.wait(mLock);\n            if (mFinished || mCanceled) {\n                return INVALID_OPERATION;\n            }\n        }\n    }\n\n    mWorkUnits.add(workUnit);\n    mWorkChangedCondition.broadcast();\n    return OK;\n}\n\nstatus_t WorkQueue::cancel() {\n    AutoMutex _l(mLock);\n\n    return cancelLocked();\n}\n\nstatus_t WorkQueue::cancelLocked() {\n    if (mFinished) {\n        return INVALID_OPERATION;\n    }\n\n    if (!mCanceled) {\n        mCanceled = true;\n\n        size_t count = mWorkUnits.size();\n        for (size_t i = 0; i < count; i++) {\n            delete mWorkUnits.itemAt(i);\n        }\n        mWorkUnits.clear();\n        mWorkChangedCondition.broadcast();\n        mWorkDequeuedCondition.broadcast();\n    }\n    return OK;\n}\n\nstatus_t WorkQueue::finish() {\n    { // acquire lock\n        AutoMutex _l(mLock);\n\n        if (mFinished) {\n            return INVALID_OPERATION;\n        }\n\n        mFinished = true;\n        mWorkChangedCondition.broadcast();\n    } // release lock\n\n    // It is not possible for the list of work threads to change once the mFinished\n    // flag has been set, so we can access mWorkThreads outside of the lock here.\n    size_t count = mWorkThreads.size();\n    for (size_t i = 0; i < count; i++) {\n        mWorkThreads.itemAt(i)->join();\n    }\n    mWorkThreads.clear();\n    return OK;\n}\n\nbool WorkQueue::threadLoop() {\n    WorkUnit* workUnit;\n    { // acquire lock\n        AutoMutex _l(mLock);\n\n        for (;;) {\n            if (mCanceled) {\n                return false;\n            }\n\n            if (!mWorkUnits.isEmpty()) {\n                workUnit = mWorkUnits.itemAt(0);\n                mWorkUnits.removeAt(0);\n                mIdleThreads -= 1;\n                mWorkDequeuedCondition.broadcast();\n                break;\n            }\n\n            if (mFinished) {\n                return false;\n            }\n\n            mWorkChangedCondition.wait(mLock);\n        }\n    } // release lock\n\n    bool shouldContinue = workUnit->run();\n    delete workUnit;\n\n    { // acquire lock\n        AutoMutex _l(mLock);\n\n        mIdleThreads += 1;\n\n        if (!shouldContinue) {\n            cancelLocked();\n            return false;\n        }\n    } // release lock\n\n    return true;\n}\n\n// --- WorkQueue::WorkThread ---\n\nWorkQueue::WorkThread::WorkThread(WorkQueue* workQueue, bool canCallJava) :\n        Thread(canCallJava), mWorkQueue(workQueue) {\n}\n\nWorkQueue::WorkThread::~WorkThread() {\n}\n\nbool WorkQueue::WorkThread::threadLoop() {\n    return mWorkQueue->threadLoop();\n}\n\n};  // namespace android\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/WorkQueue.h",
    "content": "/*]\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef AAPT_WORK_QUEUE_H\n#define AAPT_WORK_QUEUE_H\n\n#include <utils/Errors.h>\n#include <utils/Vector.h>\n#include <utils/threads.h>\n\nnamespace android {\n\n/*\n * A threaded work queue.\n *\n * This class is designed to make it easy to run a bunch of isolated work\n * units in parallel, using up to the specified number of threads.\n * To use it, write a loop to post work units to the work queue, then synchronize\n * on the queue at the end.\n */\nclass WorkQueue {\npublic:\n    class WorkUnit {\n    public:\n        WorkUnit() { }\n        virtual ~WorkUnit() { }\n\n        /*\n         * Runs the work unit.\n         * If the result is 'true' then the work queue continues scheduling work as usual.\n         * If the result is 'false' then the work queue is canceled.\n         */\n        virtual bool run() = 0;\n    };\n\n    /* Creates a work queue with the specified maximum number of work threads. */\n    WorkQueue(size_t maxThreads, bool canCallJava = true);\n\n    /* Destroys the work queue.\n     * Cancels pending work and waits for all remaining threads to complete.\n     */\n    ~WorkQueue();\n\n    /* Posts a work unit to run later.\n     * If the work queue has been canceled or is already finished, returns INVALID_OPERATION\n     * and does not take ownership of the work unit (caller must destroy it itself).\n     * Otherwise, returns OK and takes ownership of the work unit (the work queue will\n     * destroy it automatically).\n     *\n     * For flow control, this method blocks when the size of the pending work queue is more\n     * 'backlog' times the number of threads.  This condition reduces the rate of entry into\n     * the pending work queue and prevents it from growing much more rapidly than the\n     * work threads can actually handle.\n     *\n     * If 'backlog' is 0, then no throttle is applied.\n     */\n    status_t schedule(WorkUnit* workUnit, size_t backlog = 2);\n\n    /* Cancels all pending work.\n     * If the work queue is already finished, returns INVALID_OPERATION.\n     * If the work queue is already canceled, returns OK and does nothing else.\n     * Otherwise, returns OK, discards all pending work units and prevents additional\n     * work units from being scheduled.\n     *\n     * Call finish() after cancel() to wait for all remaining work to complete.\n     */\n    status_t cancel();\n\n    /* Waits for all work to complete.\n     * If the work queue is already finished, returns INVALID_OPERATION.\n     * Otherwise, waits for all work to complete and returns OK.\n     */\n    status_t finish();\n\nprivate:\n    class WorkThread : public Thread {\n    public:\n        WorkThread(WorkQueue* workQueue, bool canCallJava);\n        virtual ~WorkThread();\n\n    private:\n        virtual bool threadLoop();\n\n        WorkQueue* const mWorkQueue;\n    };\n\n    status_t cancelLocked();\n    bool threadLoop(); // called from each work thread\n\n    const size_t mMaxThreads;\n    const bool mCanCallJava;\n\n    Mutex mLock;\n    Condition mWorkChangedCondition;\n    Condition mWorkDequeuedCondition;\n\n    bool mCanceled;\n    bool mFinished;\n    size_t mIdleThreads;\n    Vector<sp<WorkThread> > mWorkThreads;\n    Vector<WorkUnit*> mWorkUnits;\n};\n\n}; // namespace android\n\n#endif // AAPT_WORK_QUEUE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/XMLNode.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#include \"XMLNode.h\"\n#include \"ResourceTable.h\"\n#include \"pseudolocalize.h\"\n\n#include <utils/ByteOrder.h>\n#include <errno.h>\n#include <string.h>\n#include <androidfw/ResourcePackageId.h>\n\n#ifndef _WIN32\n#define O_BINARY 0\n#endif\n\n// SSIZE: mingw does not have signed size_t == ssize_t.\n// STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary.\n#if !defined(_WIN32)\n#  define SSIZE(x) x\n#  define STATUST(x) x\n#else\n#  define SSIZE(x) (signed size_t)x\n#  define STATUST(x) (status_t)x\n#endif\n\n// Set to true for noisy debug output.\nstatic const bool kIsDebug = false;\n// Set to true for noisy debug output of parsing.\nstatic const bool kIsDebugParse = false;\n\n#if PRINT_STRING_METRICS\nstatic const bool kPrintStringMetrics = true;\n#else\nstatic const bool kPrintStringMetrics = false;\n#endif\n\nconst char* const RESOURCES_ROOT_NAMESPACE = \"http://schemas.android.com/apk/res/\";\nconst char* const RESOURCES_ANDROID_NAMESPACE = \"http://schemas.android.com/apk/res/android\";\nconst char* const RESOURCES_AUTO_PACKAGE_NAMESPACE = \"http://schemas.android.com/apk/res-auto\";\nconst char* const RESOURCES_ROOT_PRV_NAMESPACE = \"http://schemas.android.com/apk/prv/res/\";\n\nconst char* const XLIFF_XMLNS = \"urn:oasis:names:tc:xliff:document:1.2\";\nconst char* const ALLOWED_XLIFF_ELEMENTS[] = {\n        \"bpt\",\n        \"ept\",\n        \"it\",\n        \"ph\",\n        \"g\",\n        \"bx\",\n        \"ex\",\n        \"x\"\n    };\n\nbool isWhitespace(const char16_t* str)\n{\n    while (*str != 0 && *str < 128 && isspace(*str)) {\n        str++;\n    }\n    return *str == 0;\n}\n\nstatic const String16 RESOURCES_PREFIX(RESOURCES_ROOT_NAMESPACE);\nstatic const String16 RESOURCES_PREFIX_AUTO_PACKAGE(RESOURCES_AUTO_PACKAGE_NAMESPACE);\nstatic const String16 RESOURCES_PRV_PREFIX(RESOURCES_ROOT_PRV_NAMESPACE);\nstatic const String16 RESOURCES_TOOLS_NAMESPACE(\"http://schemas.android.com/tools\");\n\nString16 getNamespaceResourcePackage(String16 appPackage, String16 namespaceUri, bool* outIsPublic)\n{\n    //printf(\"%s starts with %s?\\n\", String8(namespaceUri).string(),\n    //       String8(RESOURCES_PREFIX).string());\n    size_t prefixSize;\n    bool isPublic = true;\n    if(namespaceUri.startsWith(RESOURCES_PREFIX_AUTO_PACKAGE)) {\n        if (kIsDebug) {\n            printf(\"Using default application package: %s -> %s\\n\", String8(namespaceUri).string(),\n                   String8(appPackage).string());\n        }\n        isPublic = true;\n        return appPackage;\n    } else if (namespaceUri.startsWith(RESOURCES_PREFIX)) {\n        prefixSize = RESOURCES_PREFIX.size();\n    } else if (namespaceUri.startsWith(RESOURCES_PRV_PREFIX)) {\n        isPublic = false;\n        prefixSize = RESOURCES_PRV_PREFIX.size();\n    } else {\n        if (outIsPublic) *outIsPublic = isPublic; // = true\n        return String16();\n    }\n\n    //printf(\"YES!\\n\");\n    //printf(\"namespace: %s\\n\", String8(String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize)).string());\n    if (outIsPublic) *outIsPublic = isPublic;\n    return String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize);\n}\n\nstatus_t hasSubstitutionErrors(const char* fileName,\n                               ResXMLTree* inXml,\n                               String16 str16)\n{\n    const char16_t* str = str16.string();\n    const char16_t* p = str;\n    const char16_t* end = str + str16.size();\n\n    bool nonpositional = false;\n    int argCount = 0;\n\n    while (p < end) {\n        /*\n         * Look for the start of a Java-style substitution sequence.\n         */\n        if (*p == '%' && p + 1 < end) {\n            p++;\n\n            // A literal percent sign represented by %%\n            if (*p == '%') {\n                p++;\n                continue;\n            }\n\n            argCount++;\n\n            if (*p >= '0' && *p <= '9') {\n                do {\n                    p++;\n                } while (*p >= '0' && *p <= '9');\n                if (*p != '$') {\n                    // This must be a size specification instead of position.\n                    nonpositional = true;\n                }\n            } else if (*p == '<') {\n                // Reusing last argument; bad idea since it can be re-arranged.\n                nonpositional = true;\n                p++;\n\n                // Optionally '$' can be specified at the end.\n                if (p < end && *p == '$') {\n                    p++;\n                }\n            } else {\n                nonpositional = true;\n            }\n\n            // Ignore flags and widths\n            while (p < end && (*p == '-' ||\n                    *p == '#' ||\n                    *p == '+' ||\n                    *p == ' ' ||\n                    *p == ',' ||\n                    *p == '(' ||\n                    (*p >= '0' && *p <= '9'))) {\n                p++;\n            }\n\n            /*\n             * This is a shortcut to detect strings that are going to Time.format()\n             * instead of String.format()\n             *\n             * Comparison of String.format() and Time.format() args:\n             *\n             * String: ABC E GH  ST X abcdefgh  nost x\n             *   Time:    DEFGHKMS W Za  d   hkm  s w yz\n             *\n             * Therefore we know it's definitely Time if we have:\n             *     DFKMWZkmwyz\n             */\n            if (p < end) {\n                switch (*p) {\n                case 'D':\n                case 'F':\n                case 'K':\n                case 'M':\n                case 'W':\n                case 'Z':\n                case 'k':\n                case 'm':\n                case 'w':\n                case 'y':\n                case 'z':\n                    return NO_ERROR;\n                }\n            }\n        }\n\n        p++;\n    }\n\n    /*\n     * If we have more than one substitution in this string and any of them\n     * are not in positional form, give the user an error.\n     */\n    if (argCount > 1 && nonpositional) {\n        SourcePos(String8(fileName), inXml->getLineNumber()).error(\n                \"Multiple substitutions specified in non-positional format; \"\n                \"did you mean to add the formatted=\\\"false\\\" attribute?\\n\");\n        return NOT_ENOUGH_DATA;\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t parseStyledString(Bundle* /* bundle */,\n                           const char* fileName,\n                           ResXMLTree* inXml,\n                           const String16& endTag,\n                           String16* outString,\n                           Vector<StringPool::entry_style_span>* outSpans,\n                           bool isFormatted,\n                           PseudolocalizationMethod pseudolocalize)\n{\n    Vector<StringPool::entry_style_span> spanStack;\n    String16 curString;\n    String16 rawString;\n    Pseudolocalizer pseudo(pseudolocalize);\n    const char* errorMsg;\n    int xliffDepth = 0;\n    bool firstTime = true;\n\n    size_t len;\n    ResXMLTree::event_code_t code;\n    curString.append(pseudo.start());\n    while ((code=inXml->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::TEXT) {\n            String16 text(inXml->getText(&len));\n            if (firstTime && text.size() > 0) {\n                firstTime = false;\n                if (text.string()[0] == '@') {\n                    // If this is a resource reference, don't do the pseudoloc.\n                    pseudolocalize = NO_PSEUDOLOCALIZATION;\n                    pseudo.setMethod(pseudolocalize);\n                    curString = String16();\n                }\n            }\n            if (xliffDepth == 0 && pseudolocalize > 0) {\n                curString.append(pseudo.text(text));\n            } else {\n                if (isFormatted && hasSubstitutionErrors(fileName, inXml, text) != NO_ERROR) {\n                    return UNKNOWN_ERROR;\n                } else {\n                    curString.append(text);\n                }\n            }\n        } else if (code == ResXMLTree::START_TAG) {\n            const String16 element16(inXml->getElementName(&len));\n            const String8 element8(element16);\n\n            size_t nslen;\n            const char16_t* ns = inXml->getElementNamespace(&nslen);\n            if (ns == NULL) {\n                ns = (const char16_t*)\"\\0\\0\";\n                nslen = 0;\n            }\n            const String8 nspace(String16(ns, nslen));\n            if (nspace == XLIFF_XMLNS) {\n                const int N = sizeof(ALLOWED_XLIFF_ELEMENTS)/sizeof(ALLOWED_XLIFF_ELEMENTS[0]);\n                for (int i=0; i<N; i++) {\n                    if (element8 == ALLOWED_XLIFF_ELEMENTS[i]) {\n                        xliffDepth++;\n                        // in this case, treat it like it was just text, in other words, do nothing\n                        // here and silently drop this element\n                        goto moveon;\n                    }\n                }\n                {\n                    SourcePos(String8(fileName), inXml->getLineNumber()).error(\n                            \"Found unsupported XLIFF tag <%s>\\n\",\n                            element8.string());\n                    return UNKNOWN_ERROR;\n                }\nmoveon:\n                continue;\n            }\n\n            if (outSpans == NULL) {\n                SourcePos(String8(fileName), inXml->getLineNumber()).error(\n                        \"Found style tag <%s> where styles are not allowed\\n\", element8.string());\n                return UNKNOWN_ERROR;\n            }\n\n            if (!ResTable::collectString(outString, curString.string(),\n                                         curString.size(), false, &errorMsg, true)) {\n                SourcePos(String8(fileName), inXml->getLineNumber()).error(\"%s (in %s)\\n\",\n                        errorMsg, String8(curString).string());\n                return UNKNOWN_ERROR;\n            }\n            rawString.append(curString);\n            curString = String16();\n\n            StringPool::entry_style_span span;\n            span.name = element16;\n            for (size_t ai=0; ai<inXml->getAttributeCount(); ai++) {\n                span.name.append(String16(\";\"));\n                const char16_t* str = inXml->getAttributeName(ai, &len);\n                span.name.append(str, len);\n                span.name.append(String16(\"=\"));\n                str = inXml->getAttributeStringValue(ai, &len);\n                span.name.append(str, len);\n            }\n            //printf(\"Span: %s\\n\", String8(span.name).string());\n            span.span.firstChar = span.span.lastChar = outString->size();\n            spanStack.push(span);\n\n        } else if (code == ResXMLTree::END_TAG) {\n            size_t nslen;\n            const char16_t* ns = inXml->getElementNamespace(&nslen);\n            if (ns == NULL) {\n                ns = (const char16_t*)\"\\0\\0\";\n                nslen = 0;\n            }\n            const String8 nspace(String16(ns, nslen));\n            if (nspace == XLIFF_XMLNS) {\n                xliffDepth--;\n                continue;\n            }\n            if (!ResTable::collectString(outString, curString.string(),\n                                         curString.size(), false, &errorMsg, true)) {\n                SourcePos(String8(fileName), inXml->getLineNumber()).error(\"%s (in %s)\\n\",\n                        errorMsg, String8(curString).string());\n                return UNKNOWN_ERROR;\n            }\n            rawString.append(curString);\n            curString = String16();\n\n            if (spanStack.size() == 0) {\n                if (strcmp16(inXml->getElementName(&len), endTag.string()) != 0) {\n                    SourcePos(String8(fileName), inXml->getLineNumber()).error(\n                            \"Found tag %s where <%s> close is expected\\n\",\n                            String8(inXml->getElementName(&len)).string(),\n                            String8(endTag).string());\n                    return UNKNOWN_ERROR;\n                }\n                break;\n            }\n            StringPool::entry_style_span span = spanStack.top();\n            String16 spanTag;\n            ssize_t semi = span.name.findFirst(';');\n            if (semi >= 0) {\n                spanTag.setTo(span.name.string(), semi);\n            } else {\n                spanTag.setTo(span.name);\n            }\n            if (strcmp16(inXml->getElementName(&len), spanTag.string()) != 0) {\n                SourcePos(String8(fileName), inXml->getLineNumber()).error(\n                        \"Found close tag %s where close tag %s is expected\\n\",\n                        String8(inXml->getElementName(&len)).string(),\n                        String8(spanTag).string());\n                return UNKNOWN_ERROR;\n            }\n            bool empty = true;\n            if (outString->size() > 0) {\n                span.span.lastChar = outString->size()-1;\n                if (span.span.lastChar >= span.span.firstChar) {\n                    empty = false;\n                    outSpans->add(span);\n                }\n            }\n            spanStack.pop();\n\n            /*\n             * This warning seems to be just an irritation to most people,\n             * since it is typically introduced by translators who then never\n             * see the warning.\n             */\n            if (0 && empty) {\n                fprintf(stderr, \"%s:%d: warning: empty '%s' span found in text '%s'\\n\",\n                        fileName, inXml->getLineNumber(),\n                        String8(spanTag).string(), String8(*outString).string());\n\n            }\n        } else if (code == ResXMLTree::START_NAMESPACE) {\n            // nothing\n        }\n    }\n\n    curString.append(pseudo.end());\n\n    if (code == ResXMLTree::BAD_DOCUMENT) {\n            SourcePos(String8(fileName), inXml->getLineNumber()).error(\n                    \"Error parsing XML\\n\");\n    }\n\n    if (outSpans != NULL && outSpans->size() > 0) {\n        if (curString.size() > 0) {\n            if (!ResTable::collectString(outString, curString.string(),\n                                         curString.size(), false, &errorMsg, true)) {\n                SourcePos(String8(fileName), inXml->getLineNumber()).error(\n                        \"%s (in %s)\\n\",\n                        errorMsg, String8(curString).string());\n                return UNKNOWN_ERROR;\n            }\n        }\n    } else {\n        // There is no style information, so string processing will happen\n        // later as part of the overall type conversion.  Return to the\n        // client the raw unprocessed text.\n        rawString.append(curString);\n        outString->setTo(rawString);\n    }\n\n    return NO_ERROR;\n}\n\nstruct namespace_entry {\n    String8 prefix;\n    String8 uri;\n};\n\nstatic String8 make_prefix(int depth)\n{\n    String8 prefix;\n    int i;\n    for (i=0; i<depth; i++) {\n        prefix.append(\"  \");\n    }\n    return prefix;\n}\n\nstatic String8 build_namespace(const Vector<namespace_entry>& namespaces,\n        const char16_t* ns)\n{\n    String8 str;\n    if (ns != NULL) {\n        str = String8(ns);\n        const size_t N = namespaces.size();\n        for (size_t i=0; i<N; i++) {\n            const namespace_entry& ne = namespaces.itemAt(i);\n            if (ne.uri == str) {\n                str = ne.prefix;\n                break;\n            }\n        }\n        str.append(\":\");\n    }\n    return str;\n}\n\nvoid printXMLBlock(ResXMLTree* block)\n{\n    block->restart();\n\n    Vector<namespace_entry> namespaces;\n\n    ResXMLTree::event_code_t code;\n    int depth = 0;\n    while ((code=block->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        String8 prefix = make_prefix(depth);\n        int i;\n        if (code == ResXMLTree::START_TAG) {\n            size_t len;\n            const char16_t* ns16 = block->getElementNamespace(&len);\n            String8 elemNs = build_namespace(namespaces, ns16);\n            const char16_t* com16 = block->getComment(&len);\n            if (com16) {\n                printf(\"%s <!-- %s -->\\n\", prefix.string(), String8(com16).string());\n            }\n            printf(\"%sE: %s%s (line=%d)\\n\", prefix.string(), elemNs.string(),\n                   String8(block->getElementName(&len)).string(),\n                   block->getLineNumber());\n            int N = block->getAttributeCount();\n            depth++;\n            prefix = make_prefix(depth);\n            for (i=0; i<N; i++) {\n                uint32_t res = block->getAttributeNameResID(i);\n                ns16 = block->getAttributeNamespace(i, &len);\n                String8 ns = build_namespace(namespaces, ns16);\n                String8 name(block->getAttributeName(i, &len));\n                printf(\"%sA: \", prefix.string());\n                if (res) {\n                    printf(\"%s%s(0x%08x)\", ns.string(), name.string(), res);\n                } else {\n                    printf(\"%s%s\", ns.string(), name.string());\n                }\n                Res_value value;\n                block->getAttributeValue(i, &value);\n                if (value.dataType == Res_value::TYPE_NULL) {\n                    printf(\"=(null)\");\n                } else if (value.dataType == Res_value::TYPE_REFERENCE) {\n                    printf(\"=@0x%x\", (int)value.data);\n                } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) {\n                    printf(\"=?0x%x\", (int)value.data);\n                } else if (value.dataType == Res_value::TYPE_STRING) {\n                    printf(\"=\\\"%s\\\"\",\n                            ResTable::normalizeForOutput(String8(block->getAttributeStringValue(i,\n                                        &len)).string()).string());\n                } else {\n                    printf(\"=(type 0x%x)0x%x\", (int)value.dataType, (int)value.data);\n                }\n                const char16_t* val = block->getAttributeStringValue(i, &len);\n                if (val != NULL) {\n                    printf(\" (Raw: \\\"%s\\\")\", ResTable::normalizeForOutput(String8(val).string()).\n                            string());\n                }\n                printf(\"\\n\");\n            }\n        } else if (code == ResXMLTree::END_TAG) {\n            // Invalid tag nesting can be misused to break the parsing\n            // code below. Break if detected.\n            if (--depth < 0) {\n                printf(\"***BAD DEPTH in XMLBlock: %d\\n\", depth);\n                break;\n            }\n        } else if (code == ResXMLTree::START_NAMESPACE) {\n            namespace_entry ns;\n            size_t len;\n            const char16_t* prefix16 = block->getNamespacePrefix(&len);\n            if (prefix16) {\n                ns.prefix = String8(prefix16);\n            } else {\n                ns.prefix = \"<DEF>\";\n            }\n            ns.uri = String8(block->getNamespaceUri(&len));\n            namespaces.push(ns);\n            printf(\"%sN: %s=%s\\n\", prefix.string(), ns.prefix.string(),\n                    ns.uri.string());\n            depth++;\n        } else if (code == ResXMLTree::END_NAMESPACE) {\n            if (--depth < 0) {\n                printf(\"***BAD DEPTH in XMLBlock: %d\\n\", depth);\n                break;\n            }\n            const namespace_entry& ns = namespaces.top();\n            size_t len;\n            const char16_t* prefix16 = block->getNamespacePrefix(&len);\n            String8 pr;\n            if (prefix16) {\n                pr = String8(prefix16);\n            } else {\n                pr = \"<DEF>\";\n            }\n            if (ns.prefix != pr) {\n                prefix = make_prefix(depth);\n                printf(\"%s*** BAD END NS PREFIX: found=%s, expected=%s\\n\",\n                        prefix.string(), pr.string(), ns.prefix.string());\n            }\n            String8 uri = String8(block->getNamespaceUri(&len));\n            if (ns.uri != uri) {\n                prefix = make_prefix(depth);\n                printf(\"%s *** BAD END NS URI: found=%s, expected=%s\\n\",\n                        prefix.string(), uri.string(), ns.uri.string());\n            }\n            namespaces.pop();\n        } else if (code == ResXMLTree::TEXT) {\n            size_t len;\n            printf(\"%sC: \\\"%s\\\"\\n\", prefix.string(),\n                    ResTable::normalizeForOutput(String8(block->getText(&len)).string()).string());\n        }\n    }\n\n    block->restart();\n}\n\nstatus_t parseXMLResource(const sp<AaptFile>& file, ResXMLTree* outTree,\n                          bool stripAll, bool keepComments,\n                          const char** cDataTags)\n{\n    sp<XMLNode> root = XMLNode::parse(file);\n    if (root == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    root->removeWhitespace(stripAll, cDataTags);\n\n    if (kIsDebug) {\n        printf(\"Input XML from %s:\\n\", (const char*)file->getPrintableSource());\n        root->print();\n    }\n    sp<AaptFile> rsc = new AaptFile(String8(), AaptGroupEntry(), String8());\n    status_t err = root->flatten(rsc, !keepComments, false);\n    if (err != NO_ERROR) {\n        return err;\n    }\n    err = outTree->setTo(rsc->getData(), rsc->getSize(), true);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    if (kIsDebug) {\n        printf(\"Output XML:\\n\");\n        printXMLBlock(outTree);\n    }\n\n    return NO_ERROR;\n}\n\nsp<XMLNode> XMLNode::parse(const sp<AaptFile>& file)\n{\n    char buf[16384];\n    int fd = open(file->getSourceFile().string(), O_RDONLY | O_BINARY);\n    if (fd < 0) {\n        SourcePos(file->getSourceFile(), -1).error(\"Unable to open file for read: %s\",\n                strerror(errno));\n        return NULL;\n    }\n\n    XML_Parser parser = XML_ParserCreateNS(NULL, 1);\n    ParseState state;\n    state.filename = file->getPrintableSource();\n    state.parser = parser;\n    XML_SetUserData(parser, &state);\n    XML_SetElementHandler(parser, startElement, endElement);\n    XML_SetNamespaceDeclHandler(parser, startNamespace, endNamespace);\n    XML_SetCharacterDataHandler(parser, characterData);\n    XML_SetCommentHandler(parser, commentData);\n\n    ssize_t len;\n    bool done;\n    do {\n        len = read(fd, buf, sizeof(buf));\n        done = len < (ssize_t)sizeof(buf);\n        if (len < 0) {\n            SourcePos(file->getSourceFile(), -1).error(\"Error reading file: %s\\n\", strerror(errno));\n            close(fd);\n            return NULL;\n        }\n        if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) {\n            SourcePos(file->getSourceFile(), (int)XML_GetCurrentLineNumber(parser)).error(\n                    \"Error parsing XML: %s\\n\", XML_ErrorString(XML_GetErrorCode(parser)));\n            close(fd);\n            return NULL;\n        }\n    } while (!done);\n\n    XML_ParserFree(parser);\n    if (state.root == NULL) {\n        SourcePos(file->getSourceFile(), -1).error(\"No XML data generated when parsing\");\n    }\n    close(fd);\n    return state.root;\n}\n\nXMLNode::XMLNode()\n    : mNextAttributeIndex(0x80000000)\n    , mStartLineNumber(0)\n    , mEndLineNumber(0)\n    , mUTF8(false) {}\n\nXMLNode::XMLNode(const String8& filename, const String16& s1, const String16& s2, bool isNamespace)\n    : mNextAttributeIndex(0x80000000)\n    , mFilename(filename)\n    , mStartLineNumber(0)\n    , mEndLineNumber(0)\n    , mUTF8(false)\n{\n    if (isNamespace) {\n        mNamespacePrefix = s1;\n        mNamespaceUri = s2;\n    } else {\n        mNamespaceUri = s1;\n        mElementName = s2;\n    }\n}\n\nXMLNode::XMLNode(const String8& filename)\n    : mFilename(filename)\n{\n    memset(&mCharsValue, 0, sizeof(mCharsValue));\n}\n\nXMLNode::type XMLNode::getType() const\n{\n    if (mElementName.size() != 0) {\n        return TYPE_ELEMENT;\n    }\n    if (mNamespaceUri.size() != 0) {\n        return TYPE_NAMESPACE;\n    }\n    return TYPE_CDATA;\n}\n\nconst String16& XMLNode::getNamespacePrefix() const\n{\n    return mNamespacePrefix;\n}\n\nconst String16& XMLNode::getNamespaceUri() const\n{\n    return mNamespaceUri;\n}\n\nconst String16& XMLNode::getElementNamespace() const\n{\n    return mNamespaceUri;\n}\n\nconst String16& XMLNode::getElementName() const\n{\n    return mElementName;\n}\n\nconst Vector<sp<XMLNode> >& XMLNode::getChildren() const\n{\n    return mChildren;\n}\n\n\nVector<sp<XMLNode> >& XMLNode::getChildren()\n{\n    return mChildren;\n}\n\nconst String8& XMLNode::getFilename() const\n{\n    return mFilename;\n}\n\nconst Vector<XMLNode::attribute_entry>&\n    XMLNode::getAttributes() const\n{\n    return mAttributes;\n}\n\nconst XMLNode::attribute_entry* XMLNode::getAttribute(const String16& ns,\n        const String16& name) const\n{\n    for (size_t i=0; i<mAttributes.size(); i++) {\n        const attribute_entry& ae(mAttributes.itemAt(i));\n        if (ae.ns == ns && ae.name == name) {\n            return &ae;\n        }\n    }\n\n    return NULL;\n}\n\nbool XMLNode::removeAttribute(const String16& ns, const String16& name)\n{\n    for (size_t i = 0; i < mAttributes.size(); i++) {\n        const attribute_entry& ae(mAttributes.itemAt(i));\n        if (ae.ns == ns && ae.name == name) {\n            removeAttribute(i);\n            return true;\n        }\n    }\n    return false;\n}\n\nXMLNode::attribute_entry* XMLNode::editAttribute(const String16& ns,\n        const String16& name)\n{\n    for (size_t i=0; i<mAttributes.size(); i++) {\n        attribute_entry * ae = &mAttributes.editItemAt(i);\n        if (ae->ns == ns && ae->name == name) {\n            return ae;\n        }\n    }\n\n    return NULL;\n}\n\nconst String16& XMLNode::getCData() const\n{\n    return mChars;\n}\n\nconst String16& XMLNode::getComment() const\n{\n    return mComment;\n}\n\nint32_t XMLNode::getStartLineNumber() const\n{\n    return mStartLineNumber;\n}\n\nint32_t XMLNode::getEndLineNumber() const\n{\n    return mEndLineNumber;\n}\n\nsp<XMLNode> XMLNode::searchElement(const String16& tagNamespace, const String16& tagName)\n{\n    if (getType() == XMLNode::TYPE_ELEMENT\n            && mNamespaceUri == tagNamespace\n            && mElementName == tagName) {\n        return this;\n    }\n\n    for (size_t i=0; i<mChildren.size(); i++) {\n        sp<XMLNode> found = mChildren.itemAt(i)->searchElement(tagNamespace, tagName);\n        if (found != NULL) {\n            return found;\n        }\n    }\n\n    return NULL;\n}\n\nsp<XMLNode> XMLNode::getChildElement(const String16& tagNamespace, const String16& tagName)\n{\n    for (size_t i=0; i<mChildren.size(); i++) {\n        sp<XMLNode> child = mChildren.itemAt(i);\n        if (child->getType() == XMLNode::TYPE_ELEMENT\n                && child->mNamespaceUri == tagNamespace\n                && child->mElementName == tagName) {\n            return child;\n        }\n    }\n\n    return NULL;\n}\n\nstatus_t XMLNode::addChild(const sp<XMLNode>& child)\n{\n    if (getType() == TYPE_CDATA) {\n        SourcePos(mFilename, child->getStartLineNumber()).error(\"Child to CDATA node.\");\n        return UNKNOWN_ERROR;\n    }\n    //printf(\"Adding child %p to parent %p\\n\", child.get(), this);\n    mChildren.add(child);\n    return NO_ERROR;\n}\n\nstatus_t XMLNode::insertChildAt(const sp<XMLNode>& child, size_t index)\n{\n    if (getType() == TYPE_CDATA) {\n        SourcePos(mFilename, child->getStartLineNumber()).error(\"Child to CDATA node.\");\n        return UNKNOWN_ERROR;\n    }\n    //printf(\"Adding child %p to parent %p\\n\", child.get(), this);\n    mChildren.insertAt(child, index);\n    return NO_ERROR;\n}\n\nstatus_t XMLNode::addAttribute(const String16& ns, const String16& name,\n                               const String16& value)\n{\n    if (getType() == TYPE_CDATA) {\n        SourcePos(mFilename, getStartLineNumber()).error(\"Child to CDATA node.\");\n        return UNKNOWN_ERROR;\n    }\n\n    if (ns != RESOURCES_TOOLS_NAMESPACE) {\n        attribute_entry e;\n        e.index = mNextAttributeIndex++;\n        e.ns = ns;\n        e.name = name;\n        e.string = value;\n        mAttributes.add(e);\n        mAttributeOrder.add(e.index, mAttributes.size()-1);\n    }\n    return NO_ERROR;\n}\n\nstatus_t XMLNode::removeAttribute(size_t index)\n{\n    if (getType() == TYPE_CDATA) {\n        return UNKNOWN_ERROR;\n    }\n\n    if (index >= mAttributes.size()) {\n        return UNKNOWN_ERROR;\n    }\n\n    const attribute_entry& e = mAttributes[index];\n    const uint32_t key = e.nameResId ? e.nameResId : e.index;\n    mAttributeOrder.removeItem(key);\n    mAttributes.removeAt(index);\n\n    // Shift all the indices.\n    const size_t attrCount = mAttributeOrder.size();\n    for (size_t i = 0; i < attrCount; i++) {\n        size_t attrIdx = mAttributeOrder[i];\n        if (attrIdx > index) {\n            mAttributeOrder.replaceValueAt(i, attrIdx - 1);\n        }\n    }\n    return NO_ERROR;\n}\n\nvoid XMLNode::setAttributeResID(size_t attrIdx, uint32_t resId)\n{\n    attribute_entry& e = mAttributes.editItemAt(attrIdx);\n    if (e.nameResId) {\n        mAttributeOrder.removeItem(e.nameResId);\n    } else {\n        mAttributeOrder.removeItem(e.index);\n    }\n    if (kIsDebug) {\n        printf(\"Elem %s %s=\\\"%s\\\": set res id = 0x%08x\\n\",\n                String8(getElementName()).string(),\n                String8(mAttributes.itemAt(attrIdx).name).string(),\n                String8(mAttributes.itemAt(attrIdx).string).string(),\n                resId);\n    }\n    mAttributes.editItemAt(attrIdx).nameResId = resId;\n    mAttributeOrder.add(resId, attrIdx);\n}\n\nstatus_t XMLNode::appendChars(const String16& chars)\n{\n    if (getType() != TYPE_CDATA) {\n        SourcePos(mFilename, getStartLineNumber()).error(\"Adding characters to element node.\");\n        return UNKNOWN_ERROR;\n    }\n    mChars.append(chars);\n    return NO_ERROR;\n}\n\nstatus_t XMLNode::appendComment(const String16& comment)\n{\n    if (mComment.size() > 0) {\n        mComment.append(String16(\"\\n\"));\n    }\n    mComment.append(comment);\n    return NO_ERROR;\n}\n\nvoid XMLNode::setStartLineNumber(int32_t line)\n{\n    mStartLineNumber = line;\n}\n\nvoid XMLNode::setEndLineNumber(int32_t line)\n{\n    mEndLineNumber = line;\n}\n\nvoid XMLNode::removeWhitespace(bool stripAll, const char** cDataTags)\n{\n    //printf(\"Removing whitespace in %s\\n\", String8(mElementName).string());\n    size_t N = mChildren.size();\n    if (cDataTags) {\n        String8 tag(mElementName);\n        const char** p = cDataTags;\n        while (*p) {\n            if (tag == *p) {\n                stripAll = false;\n                break;\n            }\n        }\n    }\n    for (size_t i=0; i<N; i++) {\n        sp<XMLNode> node = mChildren.itemAt(i);\n        if (node->getType() == TYPE_CDATA) {\n            // This is a CDATA node...\n            const char16_t* p = node->mChars.string();\n            while (*p != 0 && *p < 128 && isspace(*p)) {\n                p++;\n            }\n            //printf(\"Space ends at %d in \\\"%s\\\"\\n\",\n            //       (int)(p-node->mChars.string()),\n            //       String8(node->mChars).string());\n            if (*p == 0) {\n                if (stripAll) {\n                    // Remove this node!\n                    mChildren.removeAt(i);\n                    N--;\n                    i--;\n                } else {\n                    node->mChars = String16(\" \");\n                }\n            } else {\n                // Compact leading/trailing whitespace.\n                const char16_t* e = node->mChars.string()+node->mChars.size()-1;\n                while (e > p && *e < 128 && isspace(*e)) {\n                    e--;\n                }\n                if (p > node->mChars.string()) {\n                    p--;\n                }\n                if (e < (node->mChars.string()+node->mChars.size()-1)) {\n                    e++;\n                }\n                if (p > node->mChars.string() ||\n                    e < (node->mChars.string()+node->mChars.size()-1)) {\n                    String16 tmp(p, e-p+1);\n                    node->mChars = tmp;\n                }\n            }\n        } else {\n            node->removeWhitespace(stripAll, cDataTags);\n        }\n    }\n}\n\nstatus_t XMLNode::parseValues(const sp<AaptAssets>& assets,\n                              ResourceTable* table, const Bundle *bundle)\n{\n    bool hasErrors = false;\n\n    if (getType() == TYPE_ELEMENT) {\n        const size_t N = mAttributes.size();\n        String16 defPackage(assets->getPackage());\n        for (size_t i=0; i<N; i++) {\n            attribute_entry& e = mAttributes.editItemAt(i);\n            AccessorCookie ac(SourcePos(mFilename, getStartLineNumber()), String8(e.name),\n                    String8(e.string));\n            table->setCurrentXmlPos(SourcePos(mFilename, getStartLineNumber()));\n            bool failGetFromDefaultPackage = false;\n            if (!assets->getIncludedResources()\n                    .stringToValue(&e.value, &e.string,\n                                  e.string.string(), e.string.size(), true, true,\n                                  e.nameResId, NULL, &defPackage, table, &ac, \n                                  ResTable_map::TYPE_ANY, true, sktPackageName == NULL)) {\n                failGetFromDefaultPackage = true;\n            }\n            if (failGetFromDefaultPackage && (sktPackageName != NULL)){\n                String16 defPackage = String16(sktPackageName);\n                if (!assets->getIncludedResources().stringToValue(&e.value, &e.string,\n                     e.string.string(), e.string.size(), true, true, e.nameResId, \n                     NULL, &defPackage, table, &ac, ResTable_map::TYPE_ANY, true, true)) {\n                     hasErrors = true;\n                }\n            } else if (failGetFromDefaultPackage){\n                hasErrors = true;\n            }\n            if (kIsDebug) {\n                printf(\"Attr %s: type=0x%x, str=%s\\n\",\n                        String8(e.name).string(), e.value.dataType,\n                        String8(e.string).string());\n            }\n        }\n    }\n    const size_t N = mChildren.size();\n    for (size_t i=0; i<N; i++) {\n        status_t err = mChildren.itemAt(i)->parseValues(assets, table, bundle);\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;\n}\n\nstatus_t XMLNode::assignResourceIds(const sp<AaptAssets>& assets,\n                                    const ResourceTable* table,\n                                    const Bundle* bundle)\n{\n    bool hasErrors = false;\n\n    if (getType() == TYPE_ELEMENT) {\n        String16 attr(\"attr\");\n        const char* errorMsg;\n        const size_t N = mAttributes.size();\n        for (size_t i=0; i<N; i++) {\n            const attribute_entry& e = mAttributes.itemAt(i);\n            if (e.ns.size() <= 0) continue;\n            bool nsIsPublic = true;\n            String16 pkg(getNamespaceResourcePackage(String16(assets->getPackage()), e.ns, &nsIsPublic));\n            if (kIsDebug) {\n                printf(\"Elem %s %s=\\\"%s\\\": namespace(%s) %s ===> %s\\n\",\n                        String8(getElementName()).string(),\n                        String8(e.name).string(),\n                        String8(e.string).string(),\n                        String8(e.ns).string(),\n                        (nsIsPublic) ? \"public\" : \"private\",\n                        String8(pkg).string());\n            }\n            if (pkg.size() <= 0) continue;\n            uint32_t res = table != NULL\n                ? table->getResId(e.name, &attr, &pkg, &errorMsg, nsIsPublic)\n                : assets->getIncludedResources().\n                    identifierForName(e.name.string(), e.name.size(),\n                                      attr.string(), attr.size(),\n                                      pkg.string(), pkg.size());\n            if (res == 0){\n                if (sktPackageName != NULL){\n                    String16 defPackage = String16(sktPackageName);\n                    res = table != NULL ? table->getResId(e.name, &attr, &defPackage, &errorMsg, false) : 0;\n                }\n            }\n            if (res != 0) {\n                if (kIsDebug) {\n                    printf(\"XML attribute name %s: resid=0x%08x\\n\",\n                            String8(e.name).string(), res);\n                }\n                setAttributeResID(i, res);\n            } else {\n                SourcePos(mFilename, getStartLineNumber()).error(\n                        \"No resource identifier found for attribute '%s' in package '%s'\\n\",\n                        String8(e.name).string(), String8(pkg).string());\n                hasErrors = true;\n            }\n        }\n    }\n    const size_t N = mChildren.size();\n    for (size_t i=0; i<N; i++) {\n        status_t err = mChildren.itemAt(i)->assignResourceIds(assets, table, bundle);\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;\n}\n\nsp<XMLNode> XMLNode::clone() const {\n    sp<XMLNode> copy = new XMLNode();\n    copy->mNamespacePrefix = mNamespacePrefix;\n    copy->mNamespaceUri = mNamespaceUri;\n    copy->mElementName = mElementName;\n\n    const size_t childCount = mChildren.size();\n    for (size_t i = 0; i < childCount; i++) {\n        copy->mChildren.add(mChildren[i]->clone());\n    }\n\n    copy->mAttributes = mAttributes;\n    copy->mAttributeOrder = mAttributeOrder;\n    copy->mNextAttributeIndex = mNextAttributeIndex;\n    copy->mChars = mChars;\n    memcpy(&copy->mCharsValue, &mCharsValue, sizeof(mCharsValue));\n    copy->mComment = mComment;\n    copy->mFilename = mFilename;\n    copy->mStartLineNumber = mStartLineNumber;\n    copy->mEndLineNumber = mEndLineNumber;\n    copy->mUTF8 = mUTF8;\n    return copy;\n}\n\nstatus_t XMLNode::flatten(const sp<AaptFile>& dest,\n        bool stripComments, bool stripRawValues) const\n{\n    StringPool strings(mUTF8);\n    Vector<uint32_t> resids;\n\n    // First collect just the strings for attribute names that have a\n    // resource ID assigned to them.  This ensures that the resource ID\n    // array is compact, and makes it easier to deal with attribute names\n    // in different namespaces (and thus with different resource IDs).\n    collect_resid_strings(&strings, &resids);\n\n    // Next collect all remainibng strings.\n    collect_strings(&strings, &resids, stripComments, stripRawValues);\n\n    sp<AaptFile> stringPool = strings.createStringBlock();\n\n    ResXMLTree_header header;\n    memset(&header, 0, sizeof(header));\n    header.header.type = htods(RES_XML_TYPE);\n    header.header.headerSize = htods(sizeof(header));\n\n    const size_t basePos = dest->getSize();\n    dest->writeData(&header, sizeof(header));\n    dest->writeData(stringPool->getData(), stringPool->getSize());\n\n    // If we have resource IDs, write them.\n    if (resids.size() > 0) {\n        const size_t resIdsPos = dest->getSize();\n        const size_t resIdsSize =\n            sizeof(ResChunk_header)+(sizeof(uint32_t)*resids.size());\n        ResChunk_header* idsHeader = (ResChunk_header*)\n            (((const uint8_t*)dest->editData(resIdsPos+resIdsSize))+resIdsPos);\n        idsHeader->type = htods(RES_XML_RESOURCE_MAP_TYPE);\n        idsHeader->headerSize = htods(sizeof(*idsHeader));\n        idsHeader->size = htodl(resIdsSize);\n        uint32_t* ids = (uint32_t*)(idsHeader+1);\n        for (size_t i=0; i<resids.size(); i++) {\n            *ids++ = htodl(resids[i]);\n        }\n    }\n\n    flatten_node(strings, dest, stripComments, stripRawValues);\n\n    void* data = dest->editData();\n    ResXMLTree_header* hd = (ResXMLTree_header*)(((uint8_t*)data)+basePos);\n    hd->header.size = htodl(dest->getSize()-basePos);\n\n    if (kPrintStringMetrics) {\n        fprintf(stderr, \"**** total xml size: %zu / %zu%% strings (in %s)\\n\",\n                dest->getSize(), (stringPool->getSize()*100)/dest->getSize(),\n                dest->getPath().string());\n    }\n\n    return NO_ERROR;\n}\n\nvoid XMLNode::print(int indent)\n{\n    String8 prefix;\n    int i;\n    for (i=0; i<indent; i++) {\n        prefix.append(\"  \");\n    }\n    if (getType() == TYPE_ELEMENT) {\n        String8 elemNs(getNamespaceUri());\n        if (elemNs.size() > 0) {\n            elemNs.append(\":\");\n        }\n        printf(\"%s E: %s%s\", prefix.string(),\n               elemNs.string(), String8(getElementName()).string());\n        int N = mAttributes.size();\n        for (i=0; i<N; i++) {\n            ssize_t idx = mAttributeOrder.valueAt(i);\n            if (i == 0) {\n                printf(\" / \");\n            } else {\n                printf(\", \");\n            }\n            const attribute_entry& attr = mAttributes.itemAt(idx);\n            String8 attrNs(attr.ns);\n            if (attrNs.size() > 0) {\n                attrNs.append(\":\");\n            }\n            if (attr.nameResId) {\n                printf(\"%s%s(0x%08x)\", attrNs.string(),\n                       String8(attr.name).string(), attr.nameResId);\n            } else {\n                printf(\"%s%s\", attrNs.string(), String8(attr.name).string());\n            }\n            printf(\"=%s\", String8(attr.string).string());\n        }\n        printf(\"\\n\");\n    } else if (getType() == TYPE_NAMESPACE) {\n        printf(\"%s N: %s=%s\\n\", prefix.string(),\n               getNamespacePrefix().size() > 0\n                    ? String8(getNamespacePrefix()).string() : \"<DEF>\",\n               String8(getNamespaceUri()).string());\n    } else {\n        printf(\"%s C: \\\"%s\\\"\\n\", prefix.string(), String8(getCData()).string());\n    }\n    int N = mChildren.size();\n    for (i=0; i<N; i++) {\n        mChildren.itemAt(i)->print(indent+1);\n    }\n}\n\nstatic void splitName(const char* name, String16* outNs, String16* outName)\n{\n    const char* p = name;\n    while (*p != 0 && *p != 1) {\n        p++;\n    }\n    if (*p == 0) {\n        *outNs = String16();\n        *outName = String16(name);\n    } else {\n        *outNs = String16(name, (p-name));\n        *outName = String16(p+1);\n    }\n}\n\nvoid XMLCALL\nXMLNode::startNamespace(void *userData, const char *prefix, const char *uri)\n{\n    if (kIsDebugParse) {\n        printf(\"Start Namespace: %s %s\\n\", prefix, uri);\n    }\n    ParseState* st = (ParseState*)userData;\n    sp<XMLNode> node = XMLNode::newNamespace(st->filename,\n            String16(prefix != NULL ? prefix : \"\"), String16(uri));\n    node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser));\n    if (st->stack.size() > 0) {\n        st->stack.itemAt(st->stack.size()-1)->addChild(node);\n    } else {\n        st->root = node;\n    }\n    st->stack.push(node);\n}\n\nvoid XMLCALL\nXMLNode::startElement(void *userData, const char *name, const char **atts)\n{\n    if (kIsDebugParse) {\n        printf(\"Start Element: %s\\n\", name);\n    }\n    ParseState* st = (ParseState*)userData;\n    String16 ns16, name16;\n    splitName(name, &ns16, &name16);\n    sp<XMLNode> node = XMLNode::newElement(st->filename, ns16, name16);\n    node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser));\n    if (st->pendingComment.size() > 0) {\n        node->appendComment(st->pendingComment);\n        st->pendingComment = String16();\n    }\n    if (st->stack.size() > 0) {\n        st->stack.itemAt(st->stack.size()-1)->addChild(node);\n    } else {\n        st->root = node;\n    }\n    st->stack.push(node);\n\n    for (int i = 0; atts[i]; i += 2) {\n        splitName(atts[i], &ns16, &name16);\n        node->addAttribute(ns16, name16, String16(atts[i+1]));\n    }\n}\n\nvoid XMLCALL\nXMLNode::characterData(void *userData, const XML_Char *s, int len)\n{\n    if (kIsDebugParse) {\n        printf(\"CDATA: \\\"%s\\\"\\n\", String8(s, len).string());\n    }\n    ParseState* st = (ParseState*)userData;\n    sp<XMLNode> node = NULL;\n    if (st->stack.size() == 0) {\n        return;\n    }\n    sp<XMLNode> parent = st->stack.itemAt(st->stack.size()-1);\n    if (parent != NULL && parent->getChildren().size() > 0) {\n        node = parent->getChildren()[parent->getChildren().size()-1];\n        if (node->getType() != TYPE_CDATA) {\n            // Last node is not CDATA, need to make a new node.\n            node = NULL;\n        }\n    }\n\n    if (node == NULL) {\n        node = XMLNode::newCData(st->filename);\n        node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser));\n        parent->addChild(node);\n    }\n\n    node->appendChars(String16(s, len));\n}\n\nvoid XMLCALL\nXMLNode::endElement(void *userData, const char *name)\n{\n    if (kIsDebugParse) {\n        printf(\"End Element: %s\\n\", name);\n    }\n    ParseState* st = (ParseState*)userData;\n    sp<XMLNode> node = st->stack.itemAt(st->stack.size()-1);\n    node->setEndLineNumber(XML_GetCurrentLineNumber(st->parser));\n    if (st->pendingComment.size() > 0) {\n        node->appendComment(st->pendingComment);\n        st->pendingComment = String16();\n    }\n    String16 ns16, name16;\n    splitName(name, &ns16, &name16);\n    LOG_ALWAYS_FATAL_IF(node->getElementNamespace() != ns16\n                        || node->getElementName() != name16,\n                        \"Bad end element %s\", name);\n    st->stack.pop();\n}\n\nvoid XMLCALL\nXMLNode::endNamespace(void *userData, const char *prefix)\n{\n    const char* nonNullPrefix = prefix != NULL ? prefix : \"\";\n    if (kIsDebugParse) {\n        printf(\"End Namespace: %s\\n\", prefix);\n    }\n    ParseState* st = (ParseState*)userData;\n    sp<XMLNode> node = st->stack.itemAt(st->stack.size()-1);\n    node->setEndLineNumber(XML_GetCurrentLineNumber(st->parser));\n    LOG_ALWAYS_FATAL_IF(node->getNamespacePrefix() != String16(nonNullPrefix),\n                        \"Bad end namespace %s\", prefix);\n    st->stack.pop();\n}\n\nvoid XMLCALL\nXMLNode::commentData(void *userData, const char *comment)\n{\n    if (kIsDebugParse) {\n        printf(\"Comment: %s\\n\", comment);\n    }\n    ParseState* st = (ParseState*)userData;\n    if (st->pendingComment.size() > 0) {\n        st->pendingComment.append(String16(\"\\n\"));\n    }\n    st->pendingComment.append(String16(comment));\n}\n\nstatus_t XMLNode::collect_strings(StringPool* dest, Vector<uint32_t>* outResIds,\n        bool stripComments, bool stripRawValues) const\n{\n    collect_attr_strings(dest, outResIds, true);\n\n    int i;\n    if (RESOURCES_TOOLS_NAMESPACE != mNamespaceUri) {\n        if (mNamespacePrefix.size() > 0) {\n            dest->add(mNamespacePrefix, true);\n        }\n        if (mNamespaceUri.size() > 0) {\n            dest->add(mNamespaceUri, true);\n        }\n    }\n    if (mElementName.size() > 0) {\n        dest->add(mElementName, true);\n    }\n\n    if (!stripComments && mComment.size() > 0) {\n        dest->add(mComment, true);\n    }\n\n    const int NA = mAttributes.size();\n\n    for (i=0; i<NA; i++) {\n        const attribute_entry& ae = mAttributes.itemAt(i);\n        if (ae.ns.size() > 0) {\n            dest->add(ae.ns, true);\n        }\n        if (!stripRawValues || ae.needStringValue()) {\n            dest->add(ae.string, true);\n        }\n        /*\n        if (ae.value.dataType == Res_value::TYPE_NULL\n                || ae.value.dataType == Res_value::TYPE_STRING) {\n            dest->add(ae.string, true);\n        }\n        */\n    }\n\n    if (mElementName.size() == 0) {\n        // If not an element, include the CDATA, even if it is empty.\n        dest->add(mChars, true);\n    }\n\n    const int NC = mChildren.size();\n\n    for (i=0; i<NC; i++) {\n        mChildren.itemAt(i)->collect_strings(dest, outResIds,\n                stripComments, stripRawValues);\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t XMLNode::collect_attr_strings(StringPool* outPool,\n        Vector<uint32_t>* outResIds, bool allAttrs) const {\n    const int NA = mAttributes.size();\n\n    for (int i=0; i<NA; i++) {\n        const attribute_entry& attr = mAttributes.itemAt(i);\n        uint32_t id = attr.nameResId;\n        if (id || allAttrs) {\n            // See if we have already assigned this resource ID to a pooled\n            // string...\n            const Vector<size_t>* indices = outPool->offsetsForString(attr.name);\n            ssize_t idx = -1;\n            if (indices != NULL) {\n                const int NJ = indices->size();\n                const size_t NR = outResIds->size();\n                for (int j=0; j<NJ; j++) {\n                    size_t strIdx = indices->itemAt(j);\n                    if (strIdx >= NR) {\n                        if (id == 0) {\n                            // We don't need to assign a resource ID for this one.\n                            idx = strIdx;\n                            break;\n                        }\n                        // Just ignore strings that are out of range of\n                        // the currently assigned resource IDs...  we add\n                        // strings as we assign the first ID.\n                    } else if (outResIds->itemAt(strIdx) == id) {\n                        idx = strIdx;\n                        break;\n                    }\n                }\n            }\n            if (idx < 0) {\n                idx = outPool->add(attr.name);\n                if (kIsDebug) {\n                    printf(\"Adding attr %s (resid 0x%08x) to pool: idx=%zd\\n\",\n                            String8(attr.name).string(), id, SSIZE(idx));\n                }\n                if (id != 0) {\n                    while ((ssize_t)outResIds->size() <= idx) {\n                        outResIds->add(0);\n                    }\n                    outResIds->replaceAt(id, idx);\n                }\n            }\n            attr.namePoolIdx = idx;\n            if (kIsDebug) {\n                printf(\"String %s offset=0x%08zd\\n\", String8(attr.name).string(), SSIZE(idx));\n            }\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t XMLNode::collect_resid_strings(StringPool* outPool,\n        Vector<uint32_t>* outResIds) const\n{\n    collect_attr_strings(outPool, outResIds, false);\n\n    const int NC = mChildren.size();\n\n    for (int i=0; i<NC; i++) {\n        mChildren.itemAt(i)->collect_resid_strings(outPool, outResIds);\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t XMLNode::flatten_node(const StringPool& strings, const sp<AaptFile>& dest,\n        bool stripComments, bool stripRawValues) const\n{\n    ResXMLTree_node node;\n    ResXMLTree_cdataExt cdataExt;\n    ResXMLTree_namespaceExt namespaceExt;\n    ResXMLTree_attrExt attrExt;\n    const void* extData = NULL;\n    size_t extSize = 0;\n    ResXMLTree_attribute attr;\n    bool writeCurrentNode = true;\n\n    const size_t NA = mAttributes.size();\n    const size_t NC = mChildren.size();\n    size_t i;\n\n    LOG_ALWAYS_FATAL_IF(NA != mAttributeOrder.size(), \"Attributes messed up!\");\n\n    const String16 id16(\"id\");\n    const String16 class16(\"class\");\n    const String16 style16(\"style\");\n\n    const type type = getType();\n\n    memset(&node, 0, sizeof(node));\n    memset(&attr, 0, sizeof(attr));\n    node.header.headerSize = htods(sizeof(node));\n    node.lineNumber = htodl(getStartLineNumber());\n    if (!stripComments) {\n        node.comment.index = htodl(\n            mComment.size() > 0 ? strings.offsetForString(mComment) : -1);\n        //if (mComment.size() > 0) {\n        //  printf(\"Flattening comment: %s\\n\", String8(mComment).string());\n        //}\n    } else {\n        node.comment.index = htodl((uint32_t)-1);\n    }\n    if (type == TYPE_ELEMENT) {\n        node.header.type = htods(RES_XML_START_ELEMENT_TYPE);\n        extData = &attrExt;\n        extSize = sizeof(attrExt);\n        memset(&attrExt, 0, sizeof(attrExt));\n        if (mNamespaceUri.size() > 0) {\n            attrExt.ns.index = htodl(strings.offsetForString(mNamespaceUri));\n        } else {\n            attrExt.ns.index = htodl((uint32_t)-1);\n        }\n        attrExt.name.index = htodl(strings.offsetForString(mElementName));\n        attrExt.attributeStart = htods(sizeof(attrExt));\n        attrExt.attributeSize = htods(sizeof(attr));\n        attrExt.attributeCount = htods(NA);\n        attrExt.idIndex = htods(0);\n        attrExt.classIndex = htods(0);\n        attrExt.styleIndex = htods(0);\n        for (i=0; i<NA; i++) {\n            ssize_t idx = mAttributeOrder.valueAt(i);\n            const attribute_entry& ae = mAttributes.itemAt(idx);\n            if (ae.ns.size() == 0) {\n                if (ae.name == id16) {\n                    attrExt.idIndex = htods(i+1);\n                } else if (ae.name == class16) {\n                    attrExt.classIndex = htods(i+1);\n                } else if (ae.name == style16) {\n                    attrExt.styleIndex = htods(i+1);\n                }\n            }\n        }\n    } else if (type == TYPE_NAMESPACE) {\n        if (mNamespaceUri == RESOURCES_TOOLS_NAMESPACE) {\n            writeCurrentNode = false;\n        } else {\n            node.header.type = htods(RES_XML_START_NAMESPACE_TYPE);\n            extData = &namespaceExt;\n            extSize = sizeof(namespaceExt);\n            memset(&namespaceExt, 0, sizeof(namespaceExt));\n            if (mNamespacePrefix.size() > 0) {\n                namespaceExt.prefix.index = htodl(strings.offsetForString(mNamespacePrefix));\n            } else {\n                namespaceExt.prefix.index = htodl((uint32_t)-1);\n            }\n            namespaceExt.prefix.index = htodl(strings.offsetForString(mNamespacePrefix));\n            namespaceExt.uri.index = htodl(strings.offsetForString(mNamespaceUri));\n        }\n        LOG_ALWAYS_FATAL_IF(NA != 0, \"Namespace nodes can't have attributes!\");\n    } else if (type == TYPE_CDATA) {\n        node.header.type = htods(RES_XML_CDATA_TYPE);\n        extData = &cdataExt;\n        extSize = sizeof(cdataExt);\n        memset(&cdataExt, 0, sizeof(cdataExt));\n        cdataExt.data.index = htodl(strings.offsetForString(mChars));\n        cdataExt.typedData.size = htods(sizeof(cdataExt.typedData));\n        cdataExt.typedData.res0 = 0;\n        cdataExt.typedData.dataType = mCharsValue.dataType;\n        cdataExt.typedData.data = htodl(mCharsValue.data);\n        LOG_ALWAYS_FATAL_IF(NA != 0, \"CDATA nodes can't have attributes!\");\n    }\n\n    node.header.size = htodl(sizeof(node) + extSize + (sizeof(attr)*NA));\n\n    if (writeCurrentNode) {\n        dest->writeData(&node, sizeof(node));\n        if (extSize > 0) {\n            dest->writeData(extData, extSize);\n        }\n    }\n\n    for (i=0; i<NA; i++) {\n        ssize_t idx = mAttributeOrder.valueAt(i);\n        const attribute_entry& ae = mAttributes.itemAt(idx);\n        if (ae.ns.size() > 0) {\n            attr.ns.index = htodl(strings.offsetForString(ae.ns));\n        } else {\n            attr.ns.index = htodl((uint32_t)-1);\n        }\n        attr.name.index = htodl(ae.namePoolIdx);\n\n        if (!stripRawValues || ae.needStringValue()) {\n            attr.rawValue.index = htodl(strings.offsetForString(ae.string));\n        } else {\n            attr.rawValue.index = htodl((uint32_t)-1);\n        }\n        attr.typedValue.size = htods(sizeof(attr.typedValue));\n        if (ae.value.dataType == Res_value::TYPE_NULL\n                || ae.value.dataType == Res_value::TYPE_STRING) {\n            attr.typedValue.res0 = 0;\n            attr.typedValue.dataType = Res_value::TYPE_STRING;\n            attr.typedValue.data = htodl(strings.offsetForString(ae.string));\n        } else {\n            attr.typedValue.res0 = 0;\n            attr.typedValue.dataType = ae.value.dataType;\n            attr.typedValue.data = htodl(ae.value.data);\n        }\n        dest->writeData(&attr, sizeof(attr));\n    }\n\n    for (i=0; i<NC; i++) {\n        status_t err = mChildren.itemAt(i)->flatten_node(strings, dest,\n                stripComments, stripRawValues);\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    if (type == TYPE_ELEMENT) {\n        ResXMLTree_endElementExt endElementExt;\n        memset(&endElementExt, 0, sizeof(endElementExt));\n        node.header.type = htods(RES_XML_END_ELEMENT_TYPE);\n        node.header.size = htodl(sizeof(node)+sizeof(endElementExt));\n        node.lineNumber = htodl(getEndLineNumber());\n        node.comment.index = htodl((uint32_t)-1);\n        endElementExt.ns.index = attrExt.ns.index;\n        endElementExt.name.index = attrExt.name.index;\n        dest->writeData(&node, sizeof(node));\n        dest->writeData(&endElementExt, sizeof(endElementExt));\n    } else if (type == TYPE_NAMESPACE) {\n        if (writeCurrentNode) {\n            node.header.type = htods(RES_XML_END_NAMESPACE_TYPE);\n            node.lineNumber = htodl(getEndLineNumber());\n            node.comment.index = htodl((uint32_t)-1);\n            node.header.size = htodl(sizeof(node)+extSize);\n            dest->writeData(&node, sizeof(node));\n            dest->writeData(extData, extSize);\n        }\n    }\n\n    return NO_ERROR;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/XMLNode.h",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#ifndef XML_NODE_H\n#define XML_NODE_H\n\n#include \"StringPool.h\"\n#include \"ResourceTable.h\"\n\n#include <expat.h>\n\nclass XMLNode;\n\nextern const char* const RESOURCES_ROOT_NAMESPACE;\nextern const char* const RESOURCES_ANDROID_NAMESPACE;\n\nbool isWhitespace(const char16_t* str);\n\nString16 getNamespaceResourcePackage(String16 namespaceUri, bool* outIsPublic = NULL);\n\nstatus_t parseStyledString(Bundle* bundle,\n                           const char* fileName,\n                           ResXMLTree* inXml,\n                           const String16& endTag,\n                           String16* outString,\n                           Vector<StringPool::entry_style_span>* outSpans,\n                           bool isFormatted,\n                           PseudolocalizationMethod isPseudolocalizable);\n\nvoid printXMLBlock(ResXMLTree* block);\n\nstatus_t parseXMLResource(const sp<AaptFile>& file, ResXMLTree* outTree,\n                          bool stripAll=true, bool keepComments=false,\n                          const char** cDataTags=NULL);\n\nclass XMLNode : public RefBase\n{\npublic:\n    static sp<XMLNode> parse(const sp<AaptFile>& file);\n\n    static inline\n    sp<XMLNode> newNamespace(const String8& filename, const String16& prefix, const String16& uri) {\n        return new XMLNode(filename, prefix, uri, true);\n    }\n    \n    static inline\n    sp<XMLNode> newElement(const String8& filename, const String16& ns, const String16& name) {\n        return new XMLNode(filename, ns, name, false);\n    }\n    \n    static inline\n    sp<XMLNode> newCData(const String8& filename) {\n        return new XMLNode(filename);\n    }\n\n    enum type {\n        TYPE_NAMESPACE,\n        TYPE_ELEMENT,\n        TYPE_CDATA\n    };\n    \n    type getType() const;\n    \n    const String16& getNamespacePrefix() const;\n    const String16& getNamespaceUri() const;\n    \n    const String16& getElementNamespace() const;\n    const String16& getElementName() const;\n    const Vector<sp<XMLNode> >& getChildren() const;\n    Vector<sp<XMLNode> >& getChildren();\n\n    const String8& getFilename() const;\n    \n    struct attribute_entry {\n        attribute_entry() : index(~(uint32_t)0), nameResId(0)\n        {\n            value.dataType = Res_value::TYPE_NULL;\n        }\n\n        bool needStringValue() const {\n            return nameResId == 0\n                || value.dataType == Res_value::TYPE_NULL\n                || value.dataType == Res_value::TYPE_STRING;\n        }\n        \n        String16 ns;\n        String16 name;\n        String16 string;\n        Res_value value;\n        uint32_t index;\n        uint32_t nameResId;\n        mutable uint32_t namePoolIdx;\n    };\n\n    const Vector<attribute_entry>& getAttributes() const;\n\n    const attribute_entry* getAttribute(const String16& ns, const String16& name) const;\n    bool removeAttribute(const String16& ns, const String16& name);\n    \n    attribute_entry* editAttribute(const String16& ns, const String16& name);\n\n    const String16& getCData() const;\n\n    const String16& getComment() const;\n\n    int32_t getStartLineNumber() const;\n    int32_t getEndLineNumber() const;\n\n    sp<XMLNode> searchElement(const String16& tagNamespace, const String16& tagName);\n    \n    sp<XMLNode> getChildElement(const String16& tagNamespace, const String16& tagName);\n    \n    status_t addChild(const sp<XMLNode>& child);\n\n    status_t insertChildAt(const sp<XMLNode>& child, size_t index);\n\n    status_t addAttribute(const String16& ns, const String16& name,\n                          const String16& value);\n\n    status_t removeAttribute(size_t index);\n\n    void setAttributeResID(size_t attrIdx, uint32_t resId);\n\n    status_t appendChars(const String16& chars);\n\n    status_t appendComment(const String16& comment);\n\n    void setStartLineNumber(int32_t line);\n    void setEndLineNumber(int32_t line);\n\n    void removeWhitespace(bool stripAll=true, const char** cDataTags=NULL);\n\n    void setUTF8(bool val) { mUTF8 = val; }\n\n    status_t parseValues(const sp<AaptAssets>& assets, ResourceTable* table, const Bundle *bundle);\n\n    status_t assignResourceIds(const sp<AaptAssets>& assets,\n                               const ResourceTable* table = NULL,\n                               const Bundle *bundle = NULL);\n\n    status_t flatten(const sp<AaptFile>& dest, bool stripComments,\n            bool stripRawValues) const;\n\n    sp<XMLNode> clone() const;\n\n    void print(int indent=0);\n\nprivate:\n    struct ParseState\n    {\n        String8 filename;\n        XML_Parser parser;\n        sp<XMLNode> root;\n        Vector<sp<XMLNode> > stack;\n        String16 pendingComment;\n    };\n\n    static void XMLCALL\n    startNamespace(void *userData, const char *prefix, const char *uri);\n    static void XMLCALL\n    startElement(void *userData, const char *name, const char **atts);\n    static void XMLCALL\n    characterData(void *userData, const XML_Char *s, int len);\n    static void XMLCALL\n    endElement(void *userData, const char *name);\n    static void XMLCALL\n    endNamespace(void *userData, const char *prefix);\n    \n    static void XMLCALL\n    commentData(void *userData, const char *comment);\n    \n    // For cloning\n    XMLNode();\n\n    // Creating an element node.\n    XMLNode(const String8& filename, const String16& s1, const String16& s2, bool isNamespace);\n    \n    // Creating a CDATA node.\n    XMLNode(const String8& filename);\n    \n    status_t collect_strings(StringPool* dest, Vector<uint32_t>* outResIds,\n            bool stripComments, bool stripRawValues) const;\n\n    status_t collect_attr_strings(StringPool* outPool,\n        Vector<uint32_t>* outResIds, bool allAttrs) const;\n        \n    status_t collect_resid_strings(StringPool* outPool,\n            Vector<uint32_t>* outResIds) const;\n\n    status_t flatten_node(const StringPool& strings, const sp<AaptFile>& dest,\n            bool stripComments, bool stripRawValues) const;\n\n    String16 mNamespacePrefix;\n    String16 mNamespaceUri;\n    String16 mElementName;\n    Vector<sp<XMLNode> > mChildren;\n    Vector<attribute_entry> mAttributes;\n    KeyedVector<uint32_t, uint32_t> mAttributeOrder;\n    uint32_t mNextAttributeIndex;\n    String16 mChars;\n    Res_value mCharsValue;\n    String16 mComment;\n    String8 mFilename;\n    int32_t mStartLineNumber;\n    int32_t mEndLineNumber;\n\n    // Encode compiled XML with UTF-8 StringPools?\n    bool mUTF8;\n};\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/ZipEntry.cpp",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Access to entries in a Zip archive.\n//\n\n#define LOG_TAG \"zip\"\n\n#include \"ZipEntry.h\"\n#include <utils/Log.h>\n\n#include <stdio.h>\n#include <string.h>\n#include <assert.h>\n\nusing namespace android;\n\n/*\n * Initialize a new ZipEntry structure from a FILE* positioned at a\n * CentralDirectoryEntry.\n *\n * On exit, the file pointer will be at the start of the next CDE or\n * at the EOCD.\n */\nstatus_t ZipEntry::initFromCDE(FILE* fp)\n{\n    status_t result;\n    long posn;\n    bool hasDD;\n\n    //ALOGV(\"initFromCDE ---\\n\");\n\n    /* read the CDE */\n    result = mCDE.read(fp);\n    if (result != NO_ERROR) {\n        ALOGD(\"mCDE.read failed\\n\");\n        return result;\n    }\n\n    //mCDE.dump();\n\n    /* using the info in the CDE, go load up the LFH */\n    posn = ftell(fp);\n    if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {\n        ALOGD(\"local header seek failed (%ld)\\n\",\n            mCDE.mLocalHeaderRelOffset);\n        return UNKNOWN_ERROR;\n    }\n\n    result = mLFH.read(fp);\n    if (result != NO_ERROR) {\n        ALOGD(\"mLFH.read failed\\n\");\n        return result;\n    }\n\n    if (fseek(fp, posn, SEEK_SET) != 0)\n        return UNKNOWN_ERROR;\n\n    //mLFH.dump();\n\n    /*\n     * We *might* need to read the Data Descriptor at this point and\n     * integrate it into the LFH.  If this bit is set, the CRC-32,\n     * compressed size, and uncompressed size will be zero.  In practice\n     * these seem to be rare.\n     */\n    hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0;\n    if (hasDD) {\n        // do something clever\n        //ALOGD(\"+++ has data descriptor\\n\");\n    }\n\n    /*\n     * Sanity-check the LFH.  Note that this will fail if the \"kUsesDataDescr\"\n     * flag is set, because the LFH is incomplete.  (Not a problem, since we\n     * prefer the CDE values.)\n     */\n    if (!hasDD && !compareHeaders()) {\n        ALOGW(\"warning: header mismatch\\n\");\n        // keep going?\n    }\n\n    /*\n     * If the mVersionToExtract is greater than 20, we may have an\n     * issue unpacking the record -- could be encrypted, compressed\n     * with something we don't support, or use Zip64 extensions.  We\n     * can defer worrying about that to when we're extracting data.\n     */\n\n    return NO_ERROR;\n}\n\n/*\n * Initialize a new entry.  Pass in the file name and an optional comment.\n *\n * Initializes the CDE and the LFH.\n */\nvoid ZipEntry::initNew(const char* fileName, const char* comment)\n{\n    assert(fileName != NULL && *fileName != '\\0');  // name required\n\n    /* most fields are properly initialized by constructor */\n    mCDE.mVersionMadeBy = kDefaultMadeBy;\n    mCDE.mVersionToExtract = kDefaultVersion;\n    mCDE.mCompressionMethod = kCompressStored;\n    mCDE.mFileNameLength = strlen(fileName);\n    if (comment != NULL)\n        mCDE.mFileCommentLength = strlen(comment);\n    mCDE.mExternalAttrs = 0x81b60020;   // matches what WinZip does\n\n    if (mCDE.mFileNameLength > 0) {\n        mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];\n        strcpy((char*) mCDE.mFileName, fileName);\n    }\n    if (mCDE.mFileCommentLength > 0) {\n        /* TODO: stop assuming null-terminated ASCII here? */\n        mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];\n        strcpy((char*) mCDE.mFileComment, comment);\n    }\n\n    copyCDEtoLFH();\n}\n\n/*\n * Initialize a new entry, starting with the ZipEntry from a different\n * archive.\n *\n * Initializes the CDE and the LFH.\n */\nstatus_t ZipEntry::initFromExternal(const ZipFile* /* pZipFile */,\n    const ZipEntry* pEntry)\n{\n    mCDE = pEntry->mCDE;\n    // Check whether we got all the memory needed.\n    if ((mCDE.mFileNameLength > 0 && mCDE.mFileName == NULL) ||\n            (mCDE.mFileCommentLength > 0 && mCDE.mFileComment == NULL) ||\n            (mCDE.mExtraFieldLength > 0 && mCDE.mExtraField == NULL)) {\n        return NO_MEMORY;\n    }\n\n    /* construct the LFH from the CDE */\n    copyCDEtoLFH();\n\n    /*\n     * The LFH \"extra\" field is independent of the CDE \"extra\", so we\n     * handle it here.\n     */\n    assert(mLFH.mExtraField == NULL);\n    mLFH.mExtraFieldLength = pEntry->mLFH.mExtraFieldLength;\n    if (mLFH.mExtraFieldLength > 0) {\n        mLFH.mExtraField = new unsigned char[mLFH.mExtraFieldLength+1];\n        if (mLFH.mExtraField == NULL)\n            return NO_MEMORY;\n        memcpy(mLFH.mExtraField, pEntry->mLFH.mExtraField,\n            mLFH.mExtraFieldLength+1);\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Insert pad bytes in the LFH by tweaking the \"extra\" field.  This will\n * potentially confuse something that put \"extra\" data in here earlier,\n * but I can't find an actual problem.\n */\nstatus_t ZipEntry::addPadding(int padding)\n{\n    if (padding <= 0)\n        return INVALID_OPERATION;\n\n    //ALOGI(\"HEY: adding %d pad bytes to existing %d in %s\\n\",\n    //    padding, mLFH.mExtraFieldLength, mCDE.mFileName);\n\n    if (mLFH.mExtraFieldLength > 0) {\n        /* extend existing field */\n        unsigned char* newExtra;\n\n        newExtra = new unsigned char[mLFH.mExtraFieldLength + padding];\n        if (newExtra == NULL)\n            return NO_MEMORY;\n        memset(newExtra + mLFH.mExtraFieldLength, 0, padding);\n        memcpy(newExtra, mLFH.mExtraField, mLFH.mExtraFieldLength);\n\n        delete[] mLFH.mExtraField;\n        mLFH.mExtraField = newExtra;\n        mLFH.mExtraFieldLength += padding;\n    } else {\n        /* create new field */\n        mLFH.mExtraField = new unsigned char[padding];\n        memset(mLFH.mExtraField, 0, padding);\n        mLFH.mExtraFieldLength = padding;\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Set the fields in the LFH equal to the corresponding fields in the CDE.\n *\n * This does not touch the LFH \"extra\" field.\n */\nvoid ZipEntry::copyCDEtoLFH(void)\n{\n    mLFH.mVersionToExtract  = mCDE.mVersionToExtract;\n    mLFH.mGPBitFlag         = mCDE.mGPBitFlag;\n    mLFH.mCompressionMethod = mCDE.mCompressionMethod;\n    mLFH.mLastModFileTime   = mCDE.mLastModFileTime;\n    mLFH.mLastModFileDate   = mCDE.mLastModFileDate;\n    mLFH.mCRC32             = mCDE.mCRC32;\n    mLFH.mCompressedSize    = mCDE.mCompressedSize;\n    mLFH.mUncompressedSize  = mCDE.mUncompressedSize;\n    mLFH.mFileNameLength    = mCDE.mFileNameLength;\n    // the \"extra field\" is independent\n\n    delete[] mLFH.mFileName;\n    if (mLFH.mFileNameLength > 0) {\n        mLFH.mFileName = new unsigned char[mLFH.mFileNameLength+1];\n        strcpy((char*) mLFH.mFileName, (const char*) mCDE.mFileName);\n    } else {\n        mLFH.mFileName = NULL;\n    }\n}\n\n/*\n * Set some information about a file after we add it.\n */\nvoid ZipEntry::setDataInfo(long uncompLen, long compLen, unsigned long crc32,\n    int compressionMethod)\n{\n    mCDE.mCompressionMethod = compressionMethod;\n    mCDE.mCRC32 = crc32;\n    mCDE.mCompressedSize = compLen;\n    mCDE.mUncompressedSize = uncompLen;\n    mCDE.mCompressionMethod = compressionMethod;\n    if (compressionMethod == kCompressDeflated) {\n        mCDE.mGPBitFlag |= 0x0002;      // indicates maximum compression used\n    }\n    copyCDEtoLFH();\n}\n\n/*\n * See if the data in mCDE and mLFH match up.  This is mostly useful for\n * debugging these classes, but it can be used to identify damaged\n * archives.\n *\n * Returns \"false\" if they differ.\n */\nbool ZipEntry::compareHeaders(void) const\n{\n    if (mCDE.mVersionToExtract != mLFH.mVersionToExtract) {\n        ALOGV(\"cmp: VersionToExtract\\n\");\n        return false;\n    }\n    if (mCDE.mGPBitFlag != mLFH.mGPBitFlag) {\n        ALOGV(\"cmp: GPBitFlag\\n\");\n        return false;\n    }\n    if (mCDE.mCompressionMethod != mLFH.mCompressionMethod) {\n        ALOGV(\"cmp: CompressionMethod\\n\");\n        return false;\n    }\n    if (mCDE.mLastModFileTime != mLFH.mLastModFileTime) {\n        ALOGV(\"cmp: LastModFileTime\\n\");\n        return false;\n    }\n    if (mCDE.mLastModFileDate != mLFH.mLastModFileDate) {\n        ALOGV(\"cmp: LastModFileDate\\n\");\n        return false;\n    }\n    if (mCDE.mCRC32 != mLFH.mCRC32) {\n        ALOGV(\"cmp: CRC32\\n\");\n        return false;\n    }\n    if (mCDE.mCompressedSize != mLFH.mCompressedSize) {\n        ALOGV(\"cmp: CompressedSize\\n\");\n        return false;\n    }\n    if (mCDE.mUncompressedSize != mLFH.mUncompressedSize) {\n        ALOGV(\"cmp: UncompressedSize\\n\");\n        return false;\n    }\n    if (mCDE.mFileNameLength != mLFH.mFileNameLength) {\n        ALOGV(\"cmp: FileNameLength\\n\");\n        return false;\n    }\n#if 0       // this seems to be used for padding, not real data\n    if (mCDE.mExtraFieldLength != mLFH.mExtraFieldLength) {\n        ALOGV(\"cmp: ExtraFieldLength\\n\");\n        return false;\n    }\n#endif\n    if (mCDE.mFileName != NULL) {\n        if (strcmp((char*) mCDE.mFileName, (char*) mLFH.mFileName) != 0) {\n            ALOGV(\"cmp: FileName\\n\");\n            return false;\n        }\n    }\n\n    return true;\n}\n\n\n/*\n * Convert the DOS date/time stamp into a UNIX time stamp.\n */\ntime_t ZipEntry::getModWhen(void) const\n{\n    struct tm parts;\n\n    parts.tm_sec = (mCDE.mLastModFileTime & 0x001f) << 1;\n    parts.tm_min = (mCDE.mLastModFileTime & 0x07e0) >> 5;\n    parts.tm_hour = (mCDE.mLastModFileTime & 0xf800) >> 11;\n    parts.tm_mday = (mCDE.mLastModFileDate & 0x001f);\n    parts.tm_mon = ((mCDE.mLastModFileDate & 0x01e0) >> 5) -1;\n    parts.tm_year = ((mCDE.mLastModFileDate & 0xfe00) >> 9) + 80;\n    parts.tm_wday = parts.tm_yday = 0;\n    parts.tm_isdst = -1;        // DST info \"not available\"\n\n    return mktime(&parts);\n}\n\n/*\n * Set the CDE/LFH timestamp from UNIX time.\n */\nvoid ZipEntry::setModWhen(time_t when)\n{\n#if !defined(_WIN32)\n    struct tm tmResult;\n#endif\n    time_t even;\n    unsigned short zdate, ztime;\n\n    struct tm* ptm;\n\n    /* round up to an even number of seconds */\n    even = (time_t)(((unsigned long)(when) + 1) & (~1));\n\n    /* expand */\n#if !defined(_WIN32)\n    ptm = localtime_r(&even, &tmResult);\n#else\n    ptm = localtime(&even);\n#endif\n\n    int year;\n    year = ptm->tm_year;\n    if (year < 80)\n        year = 80;\n\n    zdate = (year - 80) << 9 | (ptm->tm_mon+1) << 5 | ptm->tm_mday;\n    ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;\n\n    mCDE.mLastModFileTime = mLFH.mLastModFileTime = ztime;\n    mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate;\n}\n\n\n/*\n * ===========================================================================\n *      ZipEntry::LocalFileHeader\n * ===========================================================================\n */\n\n/*\n * Read a local file header.\n *\n * On entry, \"fp\" points to the signature at the start of the header.\n * On exit, \"fp\" points to the start of data.\n */\nstatus_t ZipEntry::LocalFileHeader::read(FILE* fp)\n{\n    status_t result = NO_ERROR;\n    unsigned char buf[kLFHLen];\n\n    assert(mFileName == NULL);\n    assert(mExtraField == NULL);\n\n    if (fread(buf, 1, kLFHLen, fp) != kLFHLen) {\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {\n        ALOGD(\"whoops: didn't find expected signature\\n\");\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    mVersionToExtract = ZipEntry::getShortLE(&buf[0x04]);\n    mGPBitFlag = ZipEntry::getShortLE(&buf[0x06]);\n    mCompressionMethod = ZipEntry::getShortLE(&buf[0x08]);\n    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0a]);\n    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0c]);\n    mCRC32 = ZipEntry::getLongLE(&buf[0x0e]);\n    mCompressedSize = ZipEntry::getLongLE(&buf[0x12]);\n    mUncompressedSize = ZipEntry::getLongLE(&buf[0x16]);\n    mFileNameLength = ZipEntry::getShortLE(&buf[0x1a]);\n    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1c]);\n\n    // TODO: validate sizes\n\n    /* grab filename */\n    if (mFileNameLength != 0) {\n        mFileName = new unsigned char[mFileNameLength+1];\n        if (mFileName == NULL) {\n            result = NO_MEMORY;\n            goto bail;\n        }\n        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {\n            result = UNKNOWN_ERROR;\n            goto bail;\n        }\n        mFileName[mFileNameLength] = '\\0';\n    }\n\n    /* grab extra field */\n    if (mExtraFieldLength != 0) {\n        mExtraField = new unsigned char[mExtraFieldLength+1];\n        if (mExtraField == NULL) {\n            result = NO_MEMORY;\n            goto bail;\n        }\n        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {\n            result = UNKNOWN_ERROR;\n            goto bail;\n        }\n        mExtraField[mExtraFieldLength] = '\\0';\n    }\n\nbail:\n    return result;\n}\n\n/*\n * Write a local file header.\n */\nstatus_t ZipEntry::LocalFileHeader::write(FILE* fp)\n{\n    unsigned char buf[kLFHLen];\n\n    ZipEntry::putLongLE(&buf[0x00], kSignature);\n    ZipEntry::putShortLE(&buf[0x04], mVersionToExtract);\n    ZipEntry::putShortLE(&buf[0x06], mGPBitFlag);\n    ZipEntry::putShortLE(&buf[0x08], mCompressionMethod);\n    ZipEntry::putShortLE(&buf[0x0a], mLastModFileTime);\n    ZipEntry::putShortLE(&buf[0x0c], mLastModFileDate);\n    ZipEntry::putLongLE(&buf[0x0e], mCRC32);\n    ZipEntry::putLongLE(&buf[0x12], mCompressedSize);\n    ZipEntry::putLongLE(&buf[0x16], mUncompressedSize);\n    ZipEntry::putShortLE(&buf[0x1a], mFileNameLength);\n    ZipEntry::putShortLE(&buf[0x1c], mExtraFieldLength);\n\n    if (fwrite(buf, 1, kLFHLen, fp) != kLFHLen)\n        return UNKNOWN_ERROR;\n\n    /* write filename */\n    if (mFileNameLength != 0) {\n        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)\n            return UNKNOWN_ERROR;\n    }\n\n    /* write \"extra field\" */\n    if (mExtraFieldLength != 0) {\n        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)\n            return UNKNOWN_ERROR;\n    }\n\n    return NO_ERROR;\n}\n\n\n/*\n * Dump the contents of a LocalFileHeader object.\n */\nvoid ZipEntry::LocalFileHeader::dump(void) const\n{\n    ALOGD(\" LocalFileHeader contents:\\n\");\n    ALOGD(\"  versToExt=%u gpBits=0x%04x compression=%u\\n\",\n        mVersionToExtract, mGPBitFlag, mCompressionMethod);\n    ALOGD(\"  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\\n\",\n        mLastModFileTime, mLastModFileDate, mCRC32);\n    ALOGD(\"  compressedSize=%lu uncompressedSize=%lu\\n\",\n        mCompressedSize, mUncompressedSize);\n    ALOGD(\"  filenameLen=%u extraLen=%u\\n\",\n        mFileNameLength, mExtraFieldLength);\n    if (mFileName != NULL)\n        ALOGD(\"  filename: '%s'\\n\", mFileName);\n}\n\n\n/*\n * ===========================================================================\n *      ZipEntry::CentralDirEntry\n * ===========================================================================\n */\n\n/*\n * Read the central dir entry that appears next in the file.\n *\n * On entry, \"fp\" should be positioned on the signature bytes for the\n * entry.  On exit, \"fp\" will point at the signature word for the next\n * entry or for the EOCD.\n */\nstatus_t ZipEntry::CentralDirEntry::read(FILE* fp)\n{\n    status_t result = NO_ERROR;\n    unsigned char buf[kCDELen];\n\n    /* no re-use */\n    assert(mFileName == NULL);\n    assert(mExtraField == NULL);\n    assert(mFileComment == NULL);\n\n    if (fread(buf, 1, kCDELen, fp) != kCDELen) {\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {\n        ALOGD(\"Whoops: didn't find expected signature\\n\");\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    mVersionMadeBy = ZipEntry::getShortLE(&buf[0x04]);\n    mVersionToExtract = ZipEntry::getShortLE(&buf[0x06]);\n    mGPBitFlag = ZipEntry::getShortLE(&buf[0x08]);\n    mCompressionMethod = ZipEntry::getShortLE(&buf[0x0a]);\n    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0c]);\n    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0e]);\n    mCRC32 = ZipEntry::getLongLE(&buf[0x10]);\n    mCompressedSize = ZipEntry::getLongLE(&buf[0x14]);\n    mUncompressedSize = ZipEntry::getLongLE(&buf[0x18]);\n    mFileNameLength = ZipEntry::getShortLE(&buf[0x1c]);\n    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1e]);\n    mFileCommentLength = ZipEntry::getShortLE(&buf[0x20]);\n    mDiskNumberStart = ZipEntry::getShortLE(&buf[0x22]);\n    mInternalAttrs = ZipEntry::getShortLE(&buf[0x24]);\n    mExternalAttrs = ZipEntry::getLongLE(&buf[0x26]);\n    mLocalHeaderRelOffset = ZipEntry::getLongLE(&buf[0x2a]);\n\n    // TODO: validate sizes and offsets\n\n    /* grab filename */\n    if (mFileNameLength != 0) {\n        mFileName = new unsigned char[mFileNameLength+1];\n        if (mFileName == NULL) {\n            result = NO_MEMORY;\n            goto bail;\n        }\n        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {\n            result = UNKNOWN_ERROR;\n            goto bail;\n        }\n        mFileName[mFileNameLength] = '\\0';\n    }\n\n    /* read \"extra field\" */\n    if (mExtraFieldLength != 0) {\n        mExtraField = new unsigned char[mExtraFieldLength+1];\n        if (mExtraField == NULL) {\n            result = NO_MEMORY;\n            goto bail;\n        }\n        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {\n            result = UNKNOWN_ERROR;\n            goto bail;\n        }\n        mExtraField[mExtraFieldLength] = '\\0';\n    }\n\n\n    /* grab comment, if any */\n    if (mFileCommentLength != 0) {\n        mFileComment = new unsigned char[mFileCommentLength+1];\n        if (mFileComment == NULL) {\n            result = NO_MEMORY;\n            goto bail;\n        }\n        if (fread(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)\n        {\n            result = UNKNOWN_ERROR;\n            goto bail;\n        }\n        mFileComment[mFileCommentLength] = '\\0';\n    }\n\nbail:\n    return result;\n}\n\n/*\n * Write a central dir entry.\n */\nstatus_t ZipEntry::CentralDirEntry::write(FILE* fp)\n{\n    unsigned char buf[kCDELen];\n\n    ZipEntry::putLongLE(&buf[0x00], kSignature);\n    ZipEntry::putShortLE(&buf[0x04], mVersionMadeBy);\n    ZipEntry::putShortLE(&buf[0x06], mVersionToExtract);\n    ZipEntry::putShortLE(&buf[0x08], mGPBitFlag);\n    ZipEntry::putShortLE(&buf[0x0a], mCompressionMethod);\n    ZipEntry::putShortLE(&buf[0x0c], mLastModFileTime);\n    ZipEntry::putShortLE(&buf[0x0e], mLastModFileDate);\n    ZipEntry::putLongLE(&buf[0x10], mCRC32);\n    ZipEntry::putLongLE(&buf[0x14], mCompressedSize);\n    ZipEntry::putLongLE(&buf[0x18], mUncompressedSize);\n    ZipEntry::putShortLE(&buf[0x1c], mFileNameLength);\n    ZipEntry::putShortLE(&buf[0x1e], mExtraFieldLength);\n    ZipEntry::putShortLE(&buf[0x20], mFileCommentLength);\n    ZipEntry::putShortLE(&buf[0x22], mDiskNumberStart);\n    ZipEntry::putShortLE(&buf[0x24], mInternalAttrs);\n    ZipEntry::putLongLE(&buf[0x26], mExternalAttrs);\n    ZipEntry::putLongLE(&buf[0x2a], mLocalHeaderRelOffset);\n\n    if (fwrite(buf, 1, kCDELen, fp) != kCDELen)\n        return UNKNOWN_ERROR;\n\n    /* write filename */\n    if (mFileNameLength != 0) {\n        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)\n            return UNKNOWN_ERROR;\n    }\n\n    /* write \"extra field\" */\n    if (mExtraFieldLength != 0) {\n        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)\n            return UNKNOWN_ERROR;\n    }\n\n    /* write comment */\n    if (mFileCommentLength != 0) {\n        if (fwrite(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)\n            return UNKNOWN_ERROR;\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Dump the contents of a CentralDirEntry object.\n */\nvoid ZipEntry::CentralDirEntry::dump(void) const\n{\n    ALOGD(\" CentralDirEntry contents:\\n\");\n    ALOGD(\"  versMadeBy=%u versToExt=%u gpBits=0x%04x compression=%u\\n\",\n        mVersionMadeBy, mVersionToExtract, mGPBitFlag, mCompressionMethod);\n    ALOGD(\"  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\\n\",\n        mLastModFileTime, mLastModFileDate, mCRC32);\n    ALOGD(\"  compressedSize=%lu uncompressedSize=%lu\\n\",\n        mCompressedSize, mUncompressedSize);\n    ALOGD(\"  filenameLen=%u extraLen=%u commentLen=%u\\n\",\n        mFileNameLength, mExtraFieldLength, mFileCommentLength);\n    ALOGD(\"  diskNumStart=%u intAttr=0x%04x extAttr=0x%08lx relOffset=%lu\\n\",\n        mDiskNumberStart, mInternalAttrs, mExternalAttrs,\n        mLocalHeaderRelOffset);\n\n    if (mFileName != NULL)\n        ALOGD(\"  filename: '%s'\\n\", mFileName);\n    if (mFileComment != NULL)\n        ALOGD(\"  comment: '%s'\\n\", mFileComment);\n}\n\n/*\n * Copy-assignment operator for CentralDirEntry.\n */\nZipEntry::CentralDirEntry& ZipEntry::CentralDirEntry::operator=(const ZipEntry::CentralDirEntry& src) {\n    if (this == &src) {\n        return *this;\n    }\n\n    // Free up old data.\n    delete[] mFileName;\n    delete[] mExtraField;\n    delete[] mFileComment;\n\n    // Copy scalars.\n    mVersionMadeBy = src.mVersionMadeBy;\n    mVersionToExtract = src.mVersionToExtract;\n    mGPBitFlag = src.mGPBitFlag;\n    mCompressionMethod = src.mCompressionMethod;\n    mLastModFileTime = src.mLastModFileTime;\n    mLastModFileDate = src.mLastModFileDate;\n    mCRC32 = src.mCRC32;\n    mCompressedSize = src.mCompressedSize;\n    mUncompressedSize = src.mUncompressedSize;\n    mFileNameLength = src.mFileNameLength;\n    mExtraFieldLength = src.mExtraFieldLength;\n    mFileCommentLength = src.mFileCommentLength;\n    mDiskNumberStart = src.mDiskNumberStart;\n    mInternalAttrs = src.mInternalAttrs;\n    mExternalAttrs = src.mExternalAttrs;\n    mLocalHeaderRelOffset = src.mLocalHeaderRelOffset;\n\n    // Copy strings, if necessary.\n    if (mFileNameLength > 0) {\n        mFileName = new unsigned char[mFileNameLength + 1];\n        if (mFileName != NULL)\n            strcpy((char*)mFileName, (char*)src.mFileName);\n    } else {\n        mFileName = NULL;\n    }\n    if (mFileCommentLength > 0) {\n        mFileComment = new unsigned char[mFileCommentLength + 1];\n        if (mFileComment != NULL)\n            strcpy((char*)mFileComment, (char*)src.mFileComment);\n    } else {\n        mFileComment = NULL;\n    }\n    if (mExtraFieldLength > 0) {\n        /* we null-terminate this, though it may not be a string */\n        mExtraField = new unsigned char[mExtraFieldLength + 1];\n        if (mExtraField != NULL)\n            memcpy(mExtraField, src.mExtraField, mExtraFieldLength + 1);\n    } else {\n        mExtraField = NULL;\n    }\n\n    return *this;\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/ZipEntry.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Zip archive entries.\n//\n// The ZipEntry class is tightly meshed with the ZipFile class.\n//\n#ifndef __LIBS_ZIPENTRY_H\n#define __LIBS_ZIPENTRY_H\n\n#include <utils/Errors.h>\n\n#include <stdlib.h>\n#include <stdio.h>\n\nnamespace android {\n\nclass ZipFile;\n\n/*\n * ZipEntry objects represent a single entry in a Zip archive.\n *\n * You can use one of these to get or set information about an entry, but\n * there are no functions here for accessing the data itself.  (We could\n * tuck a pointer to the ZipFile in here for convenience, but that raises\n * the likelihood of using ZipEntry objects after discarding the ZipFile.)\n *\n * File information is stored in two places: next to the file data (the Local\n * File Header, and possibly a Data Descriptor), and at the end of the file\n * (the Central Directory Entry).  The two must be kept in sync.\n */\nclass ZipEntry {\npublic:\n    friend class ZipFile;\n\n    ZipEntry(void)\n        : mDeleted(false), mMarked(false)\n        {}\n    ~ZipEntry(void) {}\n\n    /*\n     * Returns \"true\" if the data is compressed.\n     */\n    bool isCompressed(void) const {\n        return mCDE.mCompressionMethod != kCompressStored;\n    }\n    int getCompressionMethod(void) const { return mCDE.mCompressionMethod; }\n\n    /*\n     * Return the uncompressed length.\n     */\n    off_t getUncompressedLen(void) const { return mCDE.mUncompressedSize; }\n\n    /*\n     * Return the compressed length.  For uncompressed data, this returns\n     * the same thing as getUncompresesdLen().\n     */\n    off_t getCompressedLen(void) const { return mCDE.mCompressedSize; }\n\n    /*\n     * Return the offset of the local file header.\n     */\n    off_t getLFHOffset(void) const { return mCDE.mLocalHeaderRelOffset; }\n\n    /*\n     * Return the absolute file offset of the start of the compressed or\n     * uncompressed data.\n     */\n    off_t getFileOffset(void) const {\n        return mCDE.mLocalHeaderRelOffset +\n                LocalFileHeader::kLFHLen +\n                mLFH.mFileNameLength +\n                mLFH.mExtraFieldLength;\n    }\n\n    /*\n     * Return the data CRC.\n     */\n    unsigned long getCRC32(void) const { return mCDE.mCRC32; }\n\n    /*\n     * Return file modification time in UNIX seconds-since-epoch.\n     */\n    time_t getModWhen(void) const;\n\n    /*\n     * Return the archived file name.\n     */\n    const char* getFileName(void) const { return (const char*) mCDE.mFileName; }\n\n    /*\n     * Application-defined \"mark\".  Can be useful when synchronizing the\n     * contents of an archive with contents on disk.\n     */\n    bool getMarked(void) const { return mMarked; }\n    void setMarked(bool val) { mMarked = val; }\n\n    /*\n     * Some basic functions for raw data manipulation.  \"LE\" means\n     * Little Endian.\n     */\n    static inline unsigned short getShortLE(const unsigned char* buf) {\n        return buf[0] | (buf[1] << 8);\n    }\n    static inline unsigned long getLongLE(const unsigned char* buf) {\n        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);\n    }\n    static inline void putShortLE(unsigned char* buf, short val) {\n        buf[0] = (unsigned char) val;\n        buf[1] = (unsigned char) (val >> 8);\n    }\n    static inline void putLongLE(unsigned char* buf, long val) {\n        buf[0] = (unsigned char) val;\n        buf[1] = (unsigned char) (val >> 8);\n        buf[2] = (unsigned char) (val >> 16);\n        buf[3] = (unsigned char) (val >> 24);\n    }\n\n    /* defined for Zip archives */\n    enum {\n        kCompressStored     = 0,        // no compression\n        // shrunk           = 1,\n        // reduced 1        = 2,\n        // reduced 2        = 3,\n        // reduced 3        = 4,\n        // reduced 4        = 5,\n        // imploded         = 6,\n        // tokenized        = 7,\n        kCompressDeflated   = 8,        // standard deflate\n        // Deflate64        = 9,\n        // lib imploded     = 10,\n        // reserved         = 11,\n        // bzip2            = 12,\n    };\n\n    /*\n     * Deletion flag.  If set, the entry will be removed on the next\n     * call to \"flush\".\n     */\n    bool getDeleted(void) const { return mDeleted; }\n\nprotected:\n    /*\n     * Initialize the structure from the file, which is pointing at\n     * our Central Directory entry.\n     */\n    status_t initFromCDE(FILE* fp);\n\n    /*\n     * Initialize the structure for a new file.  We need the filename\n     * and comment so that we can properly size the LFH area.  The\n     * filename is mandatory, the comment is optional.\n     */\n    void initNew(const char* fileName, const char* comment);\n\n    /*\n     * Initialize the structure with the contents of a ZipEntry from\n     * another file.\n     */\n    status_t initFromExternal(const ZipFile* pZipFile, const ZipEntry* pEntry);\n\n    /*\n     * Add some pad bytes to the LFH.  We do this by adding or resizing\n     * the \"extra\" field.\n     */\n    status_t addPadding(int padding);\n\n    /*\n     * Set information about the data for this entry.\n     */\n    void setDataInfo(long uncompLen, long compLen, unsigned long crc32,\n        int compressionMethod);\n\n    /*\n     * Set the modification date.\n     */\n    void setModWhen(time_t when);\n\n    /*\n     * Set the offset of the local file header, relative to the start of\n     * the current file.\n     */\n    void setLFHOffset(off_t offset) {\n        mCDE.mLocalHeaderRelOffset = (long) offset;\n    }\n\n    /* mark for deletion; used by ZipFile::remove() */\n    void setDeleted(void) { mDeleted = true; }\n\nprivate:\n    /* these are private and not defined */\n    ZipEntry(const ZipEntry& src);\n    ZipEntry& operator=(const ZipEntry& src);\n\n    /* returns \"true\" if the CDE and the LFH agree */\n    bool compareHeaders(void) const;\n    void copyCDEtoLFH(void);\n\n    bool        mDeleted;       // set if entry is pending deletion\n    bool        mMarked;        // app-defined marker\n\n    /*\n     * Every entry in the Zip archive starts off with one of these.\n     */\n    class LocalFileHeader {\n    public:\n        LocalFileHeader(void) :\n            mVersionToExtract(0),\n            mGPBitFlag(0),\n            mCompressionMethod(0),\n            mLastModFileTime(0),\n            mLastModFileDate(0),\n            mCRC32(0),\n            mCompressedSize(0),\n            mUncompressedSize(0),\n            mFileNameLength(0),\n            mExtraFieldLength(0),\n            mFileName(NULL),\n            mExtraField(NULL)\n        {}\n        virtual ~LocalFileHeader(void) {\n            delete[] mFileName;\n            delete[] mExtraField;\n        }\n\n        status_t read(FILE* fp);\n        status_t write(FILE* fp);\n\n        // unsigned long mSignature;\n        unsigned short  mVersionToExtract;\n        unsigned short  mGPBitFlag;\n        unsigned short  mCompressionMethod;\n        unsigned short  mLastModFileTime;\n        unsigned short  mLastModFileDate;\n        unsigned long   mCRC32;\n        unsigned long   mCompressedSize;\n        unsigned long   mUncompressedSize;\n        unsigned short  mFileNameLength;\n        unsigned short  mExtraFieldLength;\n        unsigned char*  mFileName;\n        unsigned char*  mExtraField;\n\n        enum {\n            kSignature      = 0x04034b50,\n            kLFHLen         = 30,       // LocalFileHdr len, excl. var fields\n        };\n\n        void dump(void) const;\n    };\n\n    /*\n     * Every entry in the Zip archive has one of these in the \"central\n     * directory\" at the end of the file.\n     */\n    class CentralDirEntry {\n    public:\n        CentralDirEntry(void) :\n            mVersionMadeBy(0),\n            mVersionToExtract(0),\n            mGPBitFlag(0),\n            mCompressionMethod(0),\n            mLastModFileTime(0),\n            mLastModFileDate(0),\n            mCRC32(0),\n            mCompressedSize(0),\n            mUncompressedSize(0),\n            mFileNameLength(0),\n            mExtraFieldLength(0),\n            mFileCommentLength(0),\n            mDiskNumberStart(0),\n            mInternalAttrs(0),\n            mExternalAttrs(0),\n            mLocalHeaderRelOffset(0),\n            mFileName(NULL),\n            mExtraField(NULL),\n            mFileComment(NULL)\n        {}\n        virtual ~CentralDirEntry(void) {\n            delete[] mFileName;\n            delete[] mExtraField;\n            delete[] mFileComment;\n        }\n\n        status_t read(FILE* fp);\n        status_t write(FILE* fp);\n\n        CentralDirEntry& operator=(const CentralDirEntry& src);\n\n        // unsigned long mSignature;\n        unsigned short  mVersionMadeBy;\n        unsigned short  mVersionToExtract;\n        unsigned short  mGPBitFlag;\n        unsigned short  mCompressionMethod;\n        unsigned short  mLastModFileTime;\n        unsigned short  mLastModFileDate;\n        unsigned long   mCRC32;\n        unsigned long   mCompressedSize;\n        unsigned long   mUncompressedSize;\n        unsigned short  mFileNameLength;\n        unsigned short  mExtraFieldLength;\n        unsigned short  mFileCommentLength;\n        unsigned short  mDiskNumberStart;\n        unsigned short  mInternalAttrs;\n        unsigned long   mExternalAttrs;\n        unsigned long   mLocalHeaderRelOffset;\n        unsigned char*  mFileName;\n        unsigned char*  mExtraField;\n        unsigned char*  mFileComment;\n\n        void dump(void) const;\n\n        enum {\n            kSignature      = 0x02014b50,\n            kCDELen         = 46,       // CentralDirEnt len, excl. var fields\n        };\n    };\n\n    enum {\n        //kDataDescriptorSignature  = 0x08074b50,   // currently unused\n        kDataDescriptorLen  = 16,           // four 32-bit fields\n\n        kDefaultVersion     = 20,           // need deflate, nothing much else\n        kDefaultMadeBy      = 0x0317,       // 03=UNIX, 17=spec v2.3\n        kUsesDataDescr      = 0x0008,       // GPBitFlag bit 3\n    };\n\n    LocalFileHeader     mLFH;\n    CentralDirEntry     mCDE;\n};\n\n}; // namespace android\n\n#endif // __LIBS_ZIPENTRY_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/ZipFile.cpp",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Access to Zip archives.\n//\n\n#define LOG_TAG \"zip\"\n\n#include <androidfw/ZipUtils.h>\n#include <utils/Log.h>\n\n#include \"ZipFile.h\"\n\n#include <zlib.h>\n#define DEF_MEM_LEVEL 8                // normally in zutil.h?\n\n#include <memory.h>\n#include <sys/stat.h>\n#include <errno.h>\n#include <assert.h>\n\nusing namespace android;\n\n/*\n * Some environments require the \"b\", some choke on it.\n */\n#define FILE_OPEN_RO        \"rb\"\n#define FILE_OPEN_RW        \"r+b\"\n#define FILE_OPEN_RW_CREATE \"w+b\"\n\n/* should live somewhere else? */\nstatic status_t errnoToStatus(int err)\n{\n    if (err == ENOENT)\n        return NAME_NOT_FOUND;\n    else if (err == EACCES)\n        return PERMISSION_DENIED;\n    else\n        return UNKNOWN_ERROR;\n}\n\n/*\n * Open a file and parse its guts.\n */\nstatus_t ZipFile::open(const char* zipFileName, int flags)\n{\n    bool newArchive = false;\n\n    assert(mZipFp == NULL);     // no reopen\n\n    if ((flags & kOpenTruncate))\n        flags |= kOpenCreate;           // trunc implies create\n\n    if ((flags & kOpenReadOnly) && (flags & kOpenReadWrite))\n        return INVALID_OPERATION;       // not both\n    if (!((flags & kOpenReadOnly) || (flags & kOpenReadWrite)))\n        return INVALID_OPERATION;       // not neither\n    if ((flags & kOpenCreate) && !(flags & kOpenReadWrite))\n        return INVALID_OPERATION;       // create requires write\n\n    if (flags & kOpenTruncate) {\n        newArchive = true;\n    } else {\n        newArchive = (access(zipFileName, F_OK) != 0);\n        if (!(flags & kOpenCreate) && newArchive) {\n            /* not creating, must already exist */\n            ALOGD(\"File %s does not exist\", zipFileName);\n            return NAME_NOT_FOUND;\n        }\n    }\n\n    /* open the file */\n    const char* openflags;\n    if (flags & kOpenReadWrite) {\n        if (newArchive)\n            openflags = FILE_OPEN_RW_CREATE;\n        else\n            openflags = FILE_OPEN_RW;\n    } else {\n        openflags = FILE_OPEN_RO;\n    }\n    mZipFp = fopen(zipFileName, openflags);\n    if (mZipFp == NULL) {\n        int err = errno;\n        ALOGD(\"fopen failed: %d\\n\", err);\n        return errnoToStatus(err);\n    }\n\n    status_t result;\n    if (!newArchive) {\n        /*\n         * Load the central directory.  If that fails, then this probably\n         * isn't a Zip archive.\n         */\n        result = readCentralDir();\n    } else {\n        /*\n         * Newly-created.  The EndOfCentralDir constructor actually\n         * sets everything to be the way we want it (all zeroes).  We\n         * set mNeedCDRewrite so that we create *something* if the\n         * caller doesn't add any files.  (We could also just unlink\n         * the file if it's brand new and nothing was added, but that's\n         * probably doing more than we really should -- the user might\n         * have a need for empty zip files.)\n         */\n        mNeedCDRewrite = true;\n        result = NO_ERROR;\n    }\n\n    if (flags & kOpenReadOnly)\n        mReadOnly = true;\n    else\n        assert(!mReadOnly);\n\n    return result;\n}\n\n/*\n * Return the Nth entry in the archive.\n */\nZipEntry* ZipFile::getEntryByIndex(int idx) const\n{\n    if (idx < 0 || idx >= (int) mEntries.size())\n        return NULL;\n\n    return mEntries[idx];\n}\n\n/*\n * Find an entry by name.\n */\nZipEntry* ZipFile::getEntryByName(const char* fileName) const\n{\n    /*\n     * Do a stupid linear string-compare search.\n     *\n     * There are various ways to speed this up, especially since it's rare\n     * to intermingle changes to the archive with \"get by name\" calls.  We\n     * don't want to sort the mEntries vector itself, however, because\n     * it's used to recreate the Central Directory.\n     *\n     * (Hash table works, parallel list of pointers in sorted order is good.)\n     */\n    int idx;\n\n    for (idx = mEntries.size()-1; idx >= 0; idx--) {\n        ZipEntry* pEntry = mEntries[idx];\n        if (!pEntry->getDeleted() &&\n            strcmp(fileName, pEntry->getFileName()) == 0)\n        {\n            return pEntry;\n        }\n    }\n\n    return NULL;\n}\n\n/*\n * Empty the mEntries vector.\n */\nvoid ZipFile::discardEntries(void)\n{\n    int count = mEntries.size();\n\n    while (--count >= 0)\n        delete mEntries[count];\n\n    mEntries.clear();\n}\n\n\n/*\n * Find the central directory and read the contents.\n *\n * The fun thing about ZIP archives is that they may or may not be\n * readable from start to end.  In some cases, notably for archives\n * that were written to stdout, the only length information is in the\n * central directory at the end of the file.\n *\n * Of course, the central directory can be followed by a variable-length\n * comment field, so we have to scan through it backwards.  The comment\n * is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff\n * itself, plus apparently sometimes people throw random junk on the end\n * just for the fun of it.\n *\n * This is all a little wobbly.  If the wrong value ends up in the EOCD\n * area, we're hosed.  This appears to be the way that everbody handles\n * it though, so we're in pretty good company if this fails.\n */\nstatus_t ZipFile::readCentralDir(void)\n{\n    status_t result = NO_ERROR;\n    unsigned char* buf = NULL;\n    off_t fileLength, seekStart;\n    long readAmount;\n    int i;\n\n    fseek(mZipFp, 0, SEEK_END);\n    fileLength = ftell(mZipFp);\n    rewind(mZipFp);\n\n    /* too small to be a ZIP archive? */\n    if (fileLength < EndOfCentralDir::kEOCDLen) {\n        ALOGD(\"Length is %ld -- too small\\n\", (long)fileLength);\n        result = INVALID_OPERATION;\n        goto bail;\n    }\n\n    buf = new unsigned char[EndOfCentralDir::kMaxEOCDSearch];\n    if (buf == NULL) {\n        ALOGD(\"Failure allocating %d bytes for EOCD search\",\n             EndOfCentralDir::kMaxEOCDSearch);\n        result = NO_MEMORY;\n        goto bail;\n    }\n\n    if (fileLength > EndOfCentralDir::kMaxEOCDSearch) {\n        seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch;\n        readAmount = EndOfCentralDir::kMaxEOCDSearch;\n    } else {\n        seekStart = 0;\n        readAmount = (long) fileLength;\n    }\n    if (fseek(mZipFp, seekStart, SEEK_SET) != 0) {\n        ALOGD(\"Failure seeking to end of zip at %ld\", (long) seekStart);\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    /* read the last part of the file into the buffer */\n    if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) {\n        ALOGD(\"short file? wanted %ld\\n\", readAmount);\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    /* find the end-of-central-dir magic */\n    for (i = readAmount - 4; i >= 0; i--) {\n        if (buf[i] == 0x50 &&\n            ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature)\n        {\n            ALOGV(\"+++ Found EOCD at buf+%d\\n\", i);\n            break;\n        }\n    }\n    if (i < 0) {\n        ALOGD(\"EOCD not found, not Zip\\n\");\n        result = INVALID_OPERATION;\n        goto bail;\n    }\n\n    /* extract eocd values */\n    result = mEOCD.readBuf(buf + i, readAmount - i);\n    if (result != NO_ERROR) {\n        ALOGD(\"Failure reading %ld bytes of EOCD values\", readAmount - i);\n        goto bail;\n    }\n    //mEOCD.dump();\n\n    if (mEOCD.mDiskNumber != 0 || mEOCD.mDiskWithCentralDir != 0 ||\n        mEOCD.mNumEntries != mEOCD.mTotalNumEntries)\n    {\n        ALOGD(\"Archive spanning not supported\\n\");\n        result = INVALID_OPERATION;\n        goto bail;\n    }\n\n    /*\n     * So far so good.  \"mCentralDirSize\" is the size in bytes of the\n     * central directory, so we can just seek back that far to find it.\n     * We can also seek forward mCentralDirOffset bytes from the\n     * start of the file.\n     *\n     * We're not guaranteed to have the rest of the central dir in the\n     * buffer, nor are we guaranteed that the central dir will have any\n     * sort of convenient size.  We need to skip to the start of it and\n     * read the header, then the other goodies.\n     *\n     * The only thing we really need right now is the file comment, which\n     * we're hoping to preserve.\n     */\n    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {\n        ALOGD(\"Failure seeking to central dir offset %ld\\n\",\n             mEOCD.mCentralDirOffset);\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    /*\n     * Loop through and read the central dir entries.\n     */\n    ALOGV(\"Scanning %d entries...\\n\", mEOCD.mTotalNumEntries);\n    int entry;\n    for (entry = 0; entry < mEOCD.mTotalNumEntries; entry++) {\n        ZipEntry* pEntry = new ZipEntry;\n\n        result = pEntry->initFromCDE(mZipFp);\n        if (result != NO_ERROR) {\n            ALOGD(\"initFromCDE failed\\n\");\n            delete pEntry;\n            goto bail;\n        }\n\n        mEntries.add(pEntry);\n    }\n\n\n    /*\n     * If all went well, we should now be back at the EOCD.\n     */\n    {\n        unsigned char checkBuf[4];\n        if (fread(checkBuf, 1, 4, mZipFp) != 4) {\n            ALOGD(\"EOCD check read failed\\n\");\n            result = INVALID_OPERATION;\n            goto bail;\n        }\n        if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) {\n            ALOGD(\"EOCD read check failed\\n\");\n            result = UNKNOWN_ERROR;\n            goto bail;\n        }\n        ALOGV(\"+++ EOCD read check passed\\n\");\n    }\n\nbail:\n    delete[] buf;\n    return result;\n}\n\n\n/*\n * Add a new file to the archive.\n *\n * This requires creating and populating a ZipEntry structure, and copying\n * the data into the file at the appropriate position.  The \"appropriate\n * position\" is the current location of the central directory, which we\n * casually overwrite (we can put it back later).\n *\n * If we were concerned about safety, we would want to make all changes\n * in a temp file and then overwrite the original after everything was\n * safely written.  Not really a concern for us.\n */\nstatus_t ZipFile::addCommon(const char* fileName, const void* data, size_t size,\n    const char* storageName, int sourceType, int compressionMethod,\n    ZipEntry** ppEntry)\n{\n    ZipEntry* pEntry = NULL;\n    status_t result = NO_ERROR;\n    long lfhPosn, startPosn, endPosn, uncompressedLen;\n    FILE* inputFp = NULL;\n    unsigned long crc;\n    time_t modWhen = 0;\n\n    if (mReadOnly)\n        return INVALID_OPERATION;\n\n    assert(compressionMethod == ZipEntry::kCompressDeflated ||\n           compressionMethod == ZipEntry::kCompressStored);\n\n    /* make sure we're in a reasonable state */\n    assert(mZipFp != NULL);\n    assert(mEntries.size() == mEOCD.mTotalNumEntries);\n\n    /* make sure it doesn't already exist */\n    if (getEntryByName(storageName) != NULL)\n        return ALREADY_EXISTS;\n\n    if (!data) {\n        inputFp = fopen(fileName, FILE_OPEN_RO);\n        if (inputFp == NULL)\n            return errnoToStatus(errno);\n    }\n\n    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    pEntry = new ZipEntry;\n    pEntry->initNew(storageName, NULL);\n\n    /*\n     * From here on out, failures are more interesting.\n     */\n    mNeedCDRewrite = true;\n\n    /*\n     * Write the LFH, even though it's still mostly blank.  We need it\n     * as a place-holder.  In theory the LFH isn't necessary, but in\n     * practice some utilities demand it.\n     */\n    lfhPosn = ftell(mZipFp);\n    pEntry->mLFH.write(mZipFp);\n    startPosn = ftell(mZipFp);\n\n    /*\n     * Copy the data in, possibly compressing it as we go.\n     */\n    if (sourceType == ZipEntry::kCompressStored) {\n        if (compressionMethod == ZipEntry::kCompressDeflated) {\n            bool failed = false;\n            result = compressFpToFp(mZipFp, inputFp, data, size, &crc);\n            if (result != NO_ERROR) {\n                ALOGD(\"compression failed, storing\\n\");\n                failed = true;\n            } else {\n                /*\n                 * Make sure it has compressed \"enough\".  This probably ought\n                 * to be set through an API call, but I don't expect our\n                 * criteria to change over time.\n                 */\n                long src = inputFp ? ftell(inputFp) : size;\n                long dst = ftell(mZipFp) - startPosn;\n                if (dst + (dst / 10) > src) {\n                    ALOGD(\"insufficient compression (src=%ld dst=%ld), storing\\n\",\n                        src, dst);\n                    failed = true;\n                }\n            }\n\n            if (failed) {\n                compressionMethod = ZipEntry::kCompressStored;\n                if (inputFp) rewind(inputFp);\n                fseek(mZipFp, startPosn, SEEK_SET);\n                /* fall through to kCompressStored case */\n            }\n        }\n        /* handle \"no compression\" request, or failed compression from above */\n        if (compressionMethod == ZipEntry::kCompressStored) {\n            if (inputFp) {\n                result = copyFpToFp(mZipFp, inputFp, &crc);\n            } else {\n                result = copyDataToFp(mZipFp, data, size, &crc);\n            }\n            if (result != NO_ERROR) {\n                // don't need to truncate; happens in CDE rewrite\n                ALOGD(\"failed copying data in\\n\");\n                goto bail;\n            }\n        }\n\n        // currently seeked to end of file\n        uncompressedLen = inputFp ? ftell(inputFp) : size;\n    } else if (sourceType == ZipEntry::kCompressDeflated) {\n        /* we should support uncompressed-from-compressed, but it's not\n         * important right now */\n        assert(compressionMethod == ZipEntry::kCompressDeflated);\n\n        bool scanResult;\n        int method;\n        long compressedLen;\n\n        scanResult = ZipUtils::examineGzip(inputFp, &method, &uncompressedLen,\n                        &compressedLen, &crc);\n        if (!scanResult || method != ZipEntry::kCompressDeflated) {\n            ALOGD(\"this isn't a deflated gzip file?\");\n            result = UNKNOWN_ERROR;\n            goto bail;\n        }\n\n        result = copyPartialFpToFp(mZipFp, inputFp, compressedLen, NULL);\n        if (result != NO_ERROR) {\n            ALOGD(\"failed copying gzip data in\\n\");\n            goto bail;\n        }\n    } else {\n        assert(false);\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    /*\n     * We could write the \"Data Descriptor\", but there doesn't seem to\n     * be any point since we're going to go back and write the LFH.\n     *\n     * Update file offsets.\n     */\n    endPosn = ftell(mZipFp);            // seeked to end of compressed data\n\n    /*\n     * Success!  Fill out new values.\n     */\n    pEntry->setDataInfo(uncompressedLen, endPosn - startPosn, crc,\n        compressionMethod);\n    pEntry->setModWhen(modWhen);\n    pEntry->setLFHOffset(lfhPosn);\n    mEOCD.mNumEntries++;\n    mEOCD.mTotalNumEntries++;\n    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()\n    mEOCD.mCentralDirOffset = endPosn;\n\n    /*\n     * Go back and write the LFH.\n     */\n    if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) {\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n    pEntry->mLFH.write(mZipFp);\n\n    /*\n     * Add pEntry to the list.\n     */\n    mEntries.add(pEntry);\n    if (ppEntry != NULL)\n        *ppEntry = pEntry;\n    pEntry = NULL;\n\nbail:\n    if (inputFp != NULL)\n        fclose(inputFp);\n    delete pEntry;\n    return result;\n}\n\n/*\n * Add an entry by copying it from another zip file.  If \"padding\" is\n * nonzero, the specified number of bytes will be added to the \"extra\"\n * field in the header.\n *\n * If \"ppEntry\" is non-NULL, a pointer to the new entry will be returned.\n */\nstatus_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,\n    int padding, ZipEntry** ppEntry)\n{\n    ZipEntry* pEntry = NULL;\n    status_t result;\n    long lfhPosn, endPosn;\n\n    if (mReadOnly)\n        return INVALID_OPERATION;\n\n    /* make sure we're in a reasonable state */\n    assert(mZipFp != NULL);\n    assert(mEntries.size() == mEOCD.mTotalNumEntries);\n\n    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    pEntry = new ZipEntry;\n    if (pEntry == NULL) {\n        result = NO_MEMORY;\n        goto bail;\n    }\n\n    result = pEntry->initFromExternal(pSourceZip, pSourceEntry);\n    if (result != NO_ERROR)\n        goto bail;\n    if (padding != 0) {\n        result = pEntry->addPadding(padding);\n        if (result != NO_ERROR)\n            goto bail;\n    }\n\n    /*\n     * From here on out, failures are more interesting.\n     */\n    mNeedCDRewrite = true;\n\n    /*\n     * Write the LFH.  Since we're not recompressing the data, we already\n     * have all of the fields filled out.\n     */\n    lfhPosn = ftell(mZipFp);\n    pEntry->mLFH.write(mZipFp);\n\n    /*\n     * Copy the data over.\n     *\n     * If the \"has data descriptor\" flag is set, we want to copy the DD\n     * fields as well.  This is a fixed-size area immediately following\n     * the data.\n     */\n    if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0)\n    {\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    off_t copyLen;\n    copyLen = pSourceEntry->getCompressedLen();\n    if ((pSourceEntry->mLFH.mGPBitFlag & ZipEntry::kUsesDataDescr) != 0)\n        copyLen += ZipEntry::kDataDescriptorLen;\n\n    if (copyPartialFpToFp(mZipFp, pSourceZip->mZipFp, copyLen, NULL)\n        != NO_ERROR)\n    {\n        ALOGW(\"copy of '%s' failed\\n\", pEntry->mCDE.mFileName);\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    /*\n     * Update file offsets.\n     */\n    endPosn = ftell(mZipFp);\n\n    /*\n     * Success!  Fill out new values.\n     */\n    pEntry->setLFHOffset(lfhPosn);      // sets mCDE.mLocalHeaderRelOffset\n    mEOCD.mNumEntries++;\n    mEOCD.mTotalNumEntries++;\n    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()\n    mEOCD.mCentralDirOffset = endPosn;\n\n    /*\n     * Add pEntry to the list.\n     */\n    mEntries.add(pEntry);\n    if (ppEntry != NULL)\n        *ppEntry = pEntry;\n    pEntry = NULL;\n\n    result = NO_ERROR;\n\nbail:\n    delete pEntry;\n    return result;\n}\n\n/*\n * Copy all of the bytes in \"src\" to \"dst\".\n *\n * On exit, \"srcFp\" will be seeked to the end of the file, and \"dstFp\"\n * will be seeked immediately past the data.\n */\nstatus_t ZipFile::copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32)\n{\n    unsigned char tmpBuf[32768];\n    size_t count;\n\n    *pCRC32 = crc32(0L, Z_NULL, 0);\n\n    while (1) {\n        count = fread(tmpBuf, 1, sizeof(tmpBuf), srcFp);\n        if (ferror(srcFp) || ferror(dstFp))\n            return errnoToStatus(errno);\n        if (count == 0)\n            break;\n\n        *pCRC32 = crc32(*pCRC32, tmpBuf, count);\n\n        if (fwrite(tmpBuf, 1, count, dstFp) != count) {\n            ALOGD(\"fwrite %d bytes failed\\n\", (int) count);\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Copy all of the bytes in \"src\" to \"dst\".\n *\n * On exit, \"dstFp\" will be seeked immediately past the data.\n */\nstatus_t ZipFile::copyDataToFp(FILE* dstFp,\n    const void* data, size_t size, unsigned long* pCRC32)\n{\n    *pCRC32 = crc32(0L, Z_NULL, 0);\n    if (size > 0) {\n        *pCRC32 = crc32(*pCRC32, (const unsigned char*)data, size);\n        if (fwrite(data, 1, size, dstFp) != size) {\n            ALOGD(\"fwrite %d bytes failed\\n\", (int) size);\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Copy some of the bytes in \"src\" to \"dst\".\n *\n * If \"pCRC32\" is NULL, the CRC will not be computed.\n *\n * On exit, \"srcFp\" will be seeked to the end of the file, and \"dstFp\"\n * will be seeked immediately past the data just written.\n */\nstatus_t ZipFile::copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,\n    unsigned long* pCRC32)\n{\n    unsigned char tmpBuf[32768];\n    size_t count;\n\n    if (pCRC32 != NULL)\n        *pCRC32 = crc32(0L, Z_NULL, 0);\n\n    while (length) {\n        long readSize;\n        \n        readSize = sizeof(tmpBuf);\n        if (readSize > length)\n            readSize = length;\n\n        count = fread(tmpBuf, 1, readSize, srcFp);\n        if ((long) count != readSize) {     // error or unexpected EOF\n            ALOGD(\"fread %d bytes failed\\n\", (int) readSize);\n            return UNKNOWN_ERROR;\n        }\n\n        if (pCRC32 != NULL)\n            *pCRC32 = crc32(*pCRC32, tmpBuf, count);\n\n        if (fwrite(tmpBuf, 1, count, dstFp) != count) {\n            ALOGD(\"fwrite %d bytes failed\\n\", (int) count);\n            return UNKNOWN_ERROR;\n        }\n\n        length -= readSize;\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Compress all of the data in \"srcFp\" and write it to \"dstFp\".\n *\n * On exit, \"srcFp\" will be seeked to the end of the file, and \"dstFp\"\n * will be seeked immediately past the compressed data.\n */\nstatus_t ZipFile::compressFpToFp(FILE* dstFp, FILE* srcFp,\n    const void* data, size_t size, unsigned long* pCRC32)\n{\n    status_t result = NO_ERROR;\n    const size_t kBufSize = 32768;\n    unsigned char* inBuf = NULL;\n    unsigned char* outBuf = NULL;\n    z_stream zstream;\n    bool atEof = false;     // no feof() aviailable yet\n    unsigned long crc;\n    int zerr;\n\n    /*\n     * Create an input buffer and an output buffer.\n     */\n    inBuf = new unsigned char[kBufSize];\n    outBuf = new unsigned char[kBufSize];\n    if (inBuf == NULL || outBuf == NULL) {\n        result = NO_MEMORY;\n        goto bail;\n    }\n\n    /*\n     * Initialize the zlib stream.\n     */\n    memset(&zstream, 0, sizeof(zstream));\n    zstream.zalloc = Z_NULL;\n    zstream.zfree = Z_NULL;\n    zstream.opaque = Z_NULL;\n    zstream.next_in = NULL;\n    zstream.avail_in = 0;\n    zstream.next_out = outBuf;\n    zstream.avail_out = kBufSize;\n    zstream.data_type = Z_UNKNOWN;\n\n    zerr = deflateInit2(&zstream, Z_BEST_COMPRESSION,\n        Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);\n    if (zerr != Z_OK) {\n        result = UNKNOWN_ERROR;\n        if (zerr == Z_VERSION_ERROR) {\n            ALOGE(\"Installed zlib is not compatible with linked version (%s)\\n\",\n                ZLIB_VERSION);\n        } else {\n            ALOGD(\"Call to deflateInit2 failed (zerr=%d)\\n\", zerr);\n        }\n        goto bail;\n    }\n\n    crc = crc32(0L, Z_NULL, 0);\n\n    /*\n     * Loop while we have data.\n     */\n    do {\n        size_t getSize;\n        int flush;\n\n        /* only read if the input buffer is empty */\n        if (zstream.avail_in == 0 && !atEof) {\n            ALOGV(\"+++ reading %d bytes\\n\", (int)kBufSize);\n            if (data) {\n                getSize = size > kBufSize ? kBufSize : size;\n                memcpy(inBuf, data, getSize);\n                data = ((const char*)data) + getSize;\n                size -= getSize;\n            } else {\n                getSize = fread(inBuf, 1, kBufSize, srcFp);\n                if (ferror(srcFp)) {\n                    ALOGD(\"deflate read failed (errno=%d)\\n\", errno);\n                    goto z_bail;\n                }\n            }\n            if (getSize < kBufSize) {\n                ALOGV(\"+++  got %d bytes, EOF reached\\n\",\n                    (int)getSize);\n                atEof = true;\n            }\n\n            crc = crc32(crc, inBuf, getSize);\n\n            zstream.next_in = inBuf;\n            zstream.avail_in = getSize;\n        }\n\n        if (atEof)\n            flush = Z_FINISH;       /* tell zlib that we're done */\n        else\n            flush = Z_NO_FLUSH;     /* more to come! */\n\n        zerr = deflate(&zstream, flush);\n        if (zerr != Z_OK && zerr != Z_STREAM_END) {\n            ALOGD(\"zlib deflate call failed (zerr=%d)\\n\", zerr);\n            result = UNKNOWN_ERROR;\n            goto z_bail;\n        }\n\n        /* write when we're full or when we're done */\n        if (zstream.avail_out == 0 ||\n            (zerr == Z_STREAM_END && zstream.avail_out != (uInt) kBufSize))\n        {\n            ALOGV(\"+++ writing %d bytes\\n\", (int) (zstream.next_out - outBuf));\n            if (fwrite(outBuf, 1, zstream.next_out - outBuf, dstFp) !=\n                (size_t)(zstream.next_out - outBuf))\n            {\n                ALOGD(\"write %d failed in deflate\\n\",\n                    (int) (zstream.next_out - outBuf));\n                goto z_bail;\n            }\n\n            zstream.next_out = outBuf;\n            zstream.avail_out = kBufSize;\n        }\n    } while (zerr == Z_OK);\n\n    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */\n\n    *pCRC32 = crc;\n\nz_bail:\n    deflateEnd(&zstream);        /* free up any allocated structures */\n\nbail:\n    delete[] inBuf;\n    delete[] outBuf;\n\n    return result;\n}\n\n/*\n * Mark an entry as deleted.\n *\n * We will eventually need to crunch the file down, but if several files\n * are being removed (perhaps as part of an \"update\" process) we can make\n * things considerably faster by deferring the removal to \"flush\" time.\n */\nstatus_t ZipFile::remove(ZipEntry* pEntry)\n{\n    /*\n     * Should verify that pEntry is actually part of this archive, and\n     * not some stray ZipEntry from a different file.\n     */\n\n    /* mark entry as deleted, and mark archive as dirty */\n    pEntry->setDeleted();\n    mNeedCDRewrite = true;\n    return NO_ERROR;\n}\n\n/*\n * Flush any pending writes.\n *\n * In particular, this will crunch out deleted entries, and write the\n * Central Directory and EOCD if we have stomped on them.\n */\nstatus_t ZipFile::flush(void)\n{\n    status_t result = NO_ERROR;\n    long eocdPosn;\n    int i, count;\n\n    if (mReadOnly)\n        return INVALID_OPERATION;\n    if (!mNeedCDRewrite)\n        return NO_ERROR;\n\n    assert(mZipFp != NULL);\n\n    result = crunchArchive();\n    if (result != NO_ERROR)\n        return result;\n\n    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0)\n        return UNKNOWN_ERROR;\n\n    count = mEntries.size();\n    for (i = 0; i < count; i++) {\n        ZipEntry* pEntry = mEntries[i];\n        pEntry->mCDE.write(mZipFp);\n    }\n\n    eocdPosn = ftell(mZipFp);\n    mEOCD.mCentralDirSize = eocdPosn - mEOCD.mCentralDirOffset;\n\n    mEOCD.write(mZipFp);\n\n    /*\n     * If we had some stuff bloat up during compression and get replaced\n     * with plain files, or if we deleted some entries, there's a lot\n     * of wasted space at the end of the file.  Remove it now.\n     */\n    if (ftruncate(fileno(mZipFp), ftell(mZipFp)) != 0) {\n        ALOGW(\"ftruncate failed %ld: %s\\n\", ftell(mZipFp), strerror(errno));\n        // not fatal\n    }\n\n    /* should we clear the \"newly added\" flag in all entries now? */\n\n    mNeedCDRewrite = false;\n    return NO_ERROR;\n}\n\n/*\n * Crunch deleted files out of an archive by shifting the later files down.\n *\n * Because we're not using a temp file, we do the operation inside the\n * current file.\n */\nstatus_t ZipFile::crunchArchive(void)\n{\n    status_t result = NO_ERROR;\n    int i, count;\n    long delCount, adjust;\n\n#if 0\n    printf(\"CONTENTS:\\n\");\n    for (i = 0; i < (int) mEntries.size(); i++) {\n        printf(\" %d: lfhOff=%ld del=%d\\n\",\n            i, mEntries[i]->getLFHOffset(), mEntries[i]->getDeleted());\n    }\n    printf(\"  END is %ld\\n\", (long) mEOCD.mCentralDirOffset);\n#endif\n\n    /*\n     * Roll through the set of files, shifting them as appropriate.  We\n     * could probably get a slight performance improvement by sliding\n     * multiple files down at once (because we could use larger reads\n     * when operating on batches of small files), but it's not that useful.\n     */\n    count = mEntries.size();\n    delCount = adjust = 0;\n    for (i = 0; i < count; i++) {\n        ZipEntry* pEntry = mEntries[i];\n        long span;\n\n        if (pEntry->getLFHOffset() != 0) {\n            long nextOffset;\n\n            /* Get the length of this entry by finding the offset\n             * of the next entry.  Directory entries don't have\n             * file offsets, so we need to find the next non-directory\n             * entry.\n             */\n            nextOffset = 0;\n            for (int ii = i+1; nextOffset == 0 && ii < count; ii++)\n                nextOffset = mEntries[ii]->getLFHOffset();\n            if (nextOffset == 0)\n                nextOffset = mEOCD.mCentralDirOffset;\n            span = nextOffset - pEntry->getLFHOffset();\n\n            assert(span >= ZipEntry::LocalFileHeader::kLFHLen);\n        } else {\n            /* This is a directory entry.  It doesn't have\n             * any actual file contents, so there's no need to\n             * move anything.\n             */\n            span = 0;\n        }\n\n        //printf(\"+++ %d: off=%ld span=%ld del=%d [count=%d]\\n\",\n        //    i, pEntry->getLFHOffset(), span, pEntry->getDeleted(), count);\n\n        if (pEntry->getDeleted()) {\n            adjust += span;\n            delCount++;\n\n            delete pEntry;\n            mEntries.removeAt(i);\n\n            /* adjust loop control */\n            count--;\n            i--;\n        } else if (span != 0 && adjust > 0) {\n            /* shuffle this entry back */\n            //printf(\"+++ Shuffling '%s' back %ld\\n\",\n            //    pEntry->getFileName(), adjust);\n            result = filemove(mZipFp, pEntry->getLFHOffset() - adjust,\n                        pEntry->getLFHOffset(), span);\n            if (result != NO_ERROR) {\n                /* this is why you use a temp file */\n                ALOGE(\"error during crunch - archive is toast\\n\");\n                return result;\n            }\n\n            pEntry->setLFHOffset(pEntry->getLFHOffset() - adjust);\n        }\n    }\n\n    /*\n     * Fix EOCD info.  We have to wait until the end to do some of this\n     * because we use mCentralDirOffset to determine \"span\" for the\n     * last entry.\n     */\n    mEOCD.mCentralDirOffset -= adjust;\n    mEOCD.mNumEntries -= delCount;\n    mEOCD.mTotalNumEntries -= delCount;\n    mEOCD.mCentralDirSize = 0;  // mark invalid; set by flush()\n\n    assert(mEOCD.mNumEntries == mEOCD.mTotalNumEntries);\n    assert(mEOCD.mNumEntries == count);\n\n    return result;\n}\n\n/*\n * Works like memmove(), but on pieces of a file.\n */\nstatus_t ZipFile::filemove(FILE* fp, off_t dst, off_t src, size_t n)\n{\n    if (dst == src || n <= 0)\n        return NO_ERROR;\n\n    unsigned char readBuf[32768];\n\n    if (dst < src) {\n        /* shift stuff toward start of file; must read from start */\n        while (n != 0) {\n            size_t getSize = sizeof(readBuf);\n            if (getSize > n)\n                getSize = n;\n\n            if (fseek(fp, (long) src, SEEK_SET) != 0) {\n                ALOGD(\"filemove src seek %ld failed\\n\", (long) src);\n                return UNKNOWN_ERROR;\n            }\n\n            if (fread(readBuf, 1, getSize, fp) != getSize) {\n                ALOGD(\"filemove read %ld off=%ld failed\\n\",\n                    (long) getSize, (long) src);\n                return UNKNOWN_ERROR;\n            }\n\n            if (fseek(fp, (long) dst, SEEK_SET) != 0) {\n                ALOGD(\"filemove dst seek %ld failed\\n\", (long) dst);\n                return UNKNOWN_ERROR;\n            }\n\n            if (fwrite(readBuf, 1, getSize, fp) != getSize) {\n                ALOGD(\"filemove write %ld off=%ld failed\\n\",\n                    (long) getSize, (long) dst);\n                return UNKNOWN_ERROR;\n            }\n\n            src += getSize;\n            dst += getSize;\n            n -= getSize;\n        }\n    } else {\n        /* shift stuff toward end of file; must read from end */\n        assert(false);      // write this someday, maybe\n        return UNKNOWN_ERROR;\n    }\n\n    return NO_ERROR;\n}\n\n\n/*\n * Get the modification time from a file descriptor.\n */\ntime_t ZipFile::getModTime(int fd)\n{\n    struct stat sb;\n\n    if (fstat(fd, &sb) < 0) {\n        ALOGD(\"HEY: fstat on fd %d failed\\n\", fd);\n        return (time_t) -1;\n    }\n\n    return sb.st_mtime;\n}\n\n\n#if 0       /* this is a bad idea */\n/*\n * Get a copy of the Zip file descriptor.\n *\n * We don't allow this if the file was opened read-write because we tend\n * to leave the file contents in an uncertain state between calls to\n * flush().  The duplicated file descriptor should only be valid for reads.\n */\nint ZipFile::getZipFd(void) const\n{\n    if (!mReadOnly)\n        return INVALID_OPERATION;\n    assert(mZipFp != NULL);\n\n    int fd;\n    fd = dup(fileno(mZipFp));\n    if (fd < 0) {\n        ALOGD(\"didn't work, errno=%d\\n\", errno);\n    }\n\n    return fd;\n}\n#endif\n\n\n#if 0\n/*\n * Expand data.\n */\nbool ZipFile::uncompress(const ZipEntry* pEntry, void* buf) const\n{\n    return false;\n}\n#endif\n\n// free the memory when you're done\nvoid* ZipFile::uncompress(const ZipEntry* entry)\n{\n    size_t unlen = entry->getUncompressedLen();\n    size_t clen = entry->getCompressedLen();\n\n    void* buf = malloc(unlen);\n    if (buf == NULL) {\n        return NULL;\n    }\n\n    fseek(mZipFp, 0, SEEK_SET);\n\n    off_t offset = entry->getFileOffset();\n    if (fseek(mZipFp, offset, SEEK_SET) != 0) {\n        goto bail;\n    }\n\n    switch (entry->getCompressionMethod())\n    {\n        case ZipEntry::kCompressStored: {\n            ssize_t amt = fread(buf, 1, unlen, mZipFp);\n            if (amt != (ssize_t)unlen) {\n                goto bail;\n            }\n#if 0\n            printf(\"data...\\n\");\n            const unsigned char* p = (unsigned char*)buf;\n            const unsigned char* end = p+unlen;\n            for (int i=0; i<32 && p < end; i++) {\n                printf(\"0x%08x \", (int)(offset+(i*0x10)));\n                for (int j=0; j<0x10 && p < end; j++) {\n                    printf(\" %02x\", *p);\n                    p++;\n                }\n                printf(\"\\n\");\n            }\n#endif\n\n            }\n            break;\n        case ZipEntry::kCompressDeflated: {\n            if (!ZipUtils::inflateToBuffer(mZipFp, buf, unlen, clen)) {\n                goto bail;\n            }\n            }\n            break;\n        default:\n            goto bail;\n    }\n    return buf;\n\nbail:\n    free(buf);\n    return NULL;\n}\n\n\n/*\n * ===========================================================================\n *      ZipFile::EndOfCentralDir\n * ===========================================================================\n */\n\n/*\n * Read the end-of-central-dir fields.\n *\n * \"buf\" should be positioned at the EOCD signature, and should contain\n * the entire EOCD area including the comment.\n */\nstatus_t ZipFile::EndOfCentralDir::readBuf(const unsigned char* buf, int len)\n{\n    /* don't allow re-use */\n    assert(mComment == NULL);\n\n    if (len < kEOCDLen) {\n        /* looks like ZIP file got truncated */\n        ALOGD(\" Zip EOCD: expected >= %d bytes, found %d\\n\",\n            kEOCDLen, len);\n        return INVALID_OPERATION;\n    }\n\n    /* this should probably be an assert() */\n    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature)\n        return UNKNOWN_ERROR;\n\n    mDiskNumber = ZipEntry::getShortLE(&buf[0x04]);\n    mDiskWithCentralDir = ZipEntry::getShortLE(&buf[0x06]);\n    mNumEntries = ZipEntry::getShortLE(&buf[0x08]);\n    mTotalNumEntries = ZipEntry::getShortLE(&buf[0x0a]);\n    mCentralDirSize = ZipEntry::getLongLE(&buf[0x0c]);\n    mCentralDirOffset = ZipEntry::getLongLE(&buf[0x10]);\n    mCommentLen = ZipEntry::getShortLE(&buf[0x14]);\n\n    // TODO: validate mCentralDirOffset\n\n    if (mCommentLen > 0) {\n        if (kEOCDLen + mCommentLen > len) {\n            ALOGD(\"EOCD(%d) + comment(%d) exceeds len (%d)\\n\",\n                kEOCDLen, mCommentLen, len);\n            return UNKNOWN_ERROR;\n        }\n        mComment = new unsigned char[mCommentLen];\n        memcpy(mComment, buf + kEOCDLen, mCommentLen);\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Write an end-of-central-directory section.\n */\nstatus_t ZipFile::EndOfCentralDir::write(FILE* fp)\n{\n    unsigned char buf[kEOCDLen];\n\n    ZipEntry::putLongLE(&buf[0x00], kSignature);\n    ZipEntry::putShortLE(&buf[0x04], mDiskNumber);\n    ZipEntry::putShortLE(&buf[0x06], mDiskWithCentralDir);\n    ZipEntry::putShortLE(&buf[0x08], mNumEntries);\n    ZipEntry::putShortLE(&buf[0x0a], mTotalNumEntries);\n    ZipEntry::putLongLE(&buf[0x0c], mCentralDirSize);\n    ZipEntry::putLongLE(&buf[0x10], mCentralDirOffset);\n    ZipEntry::putShortLE(&buf[0x14], mCommentLen);\n\n    if (fwrite(buf, 1, kEOCDLen, fp) != kEOCDLen)\n        return UNKNOWN_ERROR;\n    if (mCommentLen > 0) {\n        assert(mComment != NULL);\n        if (fwrite(mComment, mCommentLen, 1, fp) != mCommentLen)\n            return UNKNOWN_ERROR;\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Dump the contents of an EndOfCentralDir object.\n */\nvoid ZipFile::EndOfCentralDir::dump(void) const\n{\n    ALOGD(\" EndOfCentralDir contents:\\n\");\n    ALOGD(\"  diskNum=%u diskWCD=%u numEnt=%u totalNumEnt=%u\\n\",\n        mDiskNumber, mDiskWithCentralDir, mNumEntries, mTotalNumEntries);\n    ALOGD(\"  centDirSize=%lu centDirOff=%lu commentLen=%u\\n\",\n        mCentralDirSize, mCentralDirOffset, mCommentLen);\n}\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/ZipFile.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// General-purpose Zip archive access.  This class allows both reading and\n// writing to Zip archives, including deletion of existing entries.\n//\n#ifndef __LIBS_ZIPFILE_H\n#define __LIBS_ZIPFILE_H\n\n#include <utils/Vector.h>\n#include <utils/Errors.h>\n#include <stdio.h>\n\n#include \"ZipEntry.h\"\n\nnamespace android {\n\n/*\n * Manipulate a Zip archive.\n *\n * Some changes will not be visible in the until until \"flush\" is called.\n *\n * The correct way to update a file archive is to make all changes to a\n * copy of the archive in a temporary file, and then unlink/rename over\n * the original after everything completes.  Because we're only interested\n * in using this for packaging, we don't worry about such things.  Crashing\n * after making changes and before flush() completes could leave us with\n * an unusable Zip archive.\n */\nclass ZipFile {\npublic:\n    ZipFile(void)\n      : mZipFp(NULL), mReadOnly(false), mNeedCDRewrite(false)\n      {}\n    ~ZipFile(void) {\n        if (!mReadOnly)\n            flush();\n        if (mZipFp != NULL)\n            fclose(mZipFp);\n        discardEntries();\n    }\n\n    /*\n     * Open a new or existing archive.\n     */\n    enum {\n        kOpenReadOnly   = 0x01,\n        kOpenReadWrite  = 0x02,\n        kOpenCreate     = 0x04,     // create if it doesn't exist\n        kOpenTruncate   = 0x08,     // if it exists, empty it\n    };\n    status_t open(const char* zipFileName, int flags);\n\n    /*\n     * Add a file to the end of the archive.  Specify whether you want the\n     * library to try to store it compressed.\n     *\n     * If \"storageName\" is specified, the archive will use that instead\n     * of \"fileName\".\n     *\n     * If there is already an entry with the same name, the call fails.\n     * Existing entries with the same name must be removed first.\n     *\n     * If \"ppEntry\" is non-NULL, a pointer to the new entry will be returned.\n     */\n    status_t add(const char* fileName, int compressionMethod,\n        ZipEntry** ppEntry)\n    {\n        return add(fileName, fileName, compressionMethod, ppEntry);\n    }\n    status_t add(const char* fileName, const char* storageName,\n        int compressionMethod, ZipEntry** ppEntry)\n    {\n        return addCommon(fileName, NULL, 0, storageName,\n                         ZipEntry::kCompressStored,\n                         compressionMethod, ppEntry);\n    }\n\n    /*\n     * Add a file that is already compressed with gzip.\n     *\n     * If \"ppEntry\" is non-NULL, a pointer to the new entry will be returned.\n     */\n    status_t addGzip(const char* fileName, const char* storageName,\n        ZipEntry** ppEntry)\n    {\n        return addCommon(fileName, NULL, 0, storageName,\n                         ZipEntry::kCompressDeflated,\n                         ZipEntry::kCompressDeflated, ppEntry);\n    }\n\n    /*\n     * Add a file from an in-memory data buffer.\n     *\n     * If \"ppEntry\" is non-NULL, a pointer to the new entry will be returned.\n     */\n    status_t add(const void* data, size_t size, const char* storageName,\n        int compressionMethod, ZipEntry** ppEntry)\n    {\n        return addCommon(NULL, data, size, storageName,\n                         ZipEntry::kCompressStored,\n                         compressionMethod, ppEntry);\n    }\n\n    /*\n     * Add an entry by copying it from another zip file.  If \"padding\" is\n     * nonzero, the specified number of bytes will be added to the \"extra\"\n     * field in the header.\n     *\n     * If \"ppEntry\" is non-NULL, a pointer to the new entry will be returned.\n     */\n    status_t add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,\n        int padding, ZipEntry** ppEntry);\n\n    /*\n     * Mark an entry as having been removed.  It is not actually deleted\n     * from the archive or our internal data structures until flush() is\n     * called.\n     */\n    status_t remove(ZipEntry* pEntry);\n\n    /*\n     * Flush changes.  If mNeedCDRewrite is set, this writes the central dir.\n     */\n    status_t flush(void);\n\n    /*\n     * Expand the data into the buffer provided.  The buffer must hold\n     * at least <uncompressed len> bytes.  Variation expands directly\n     * to a file.\n     *\n     * Returns \"false\" if an error was encountered in the compressed data.\n     */\n    //bool uncompress(const ZipEntry* pEntry, void* buf) const;\n    //bool uncompress(const ZipEntry* pEntry, FILE* fp) const;\n    void* uncompress(const ZipEntry* pEntry);\n\n    /*\n     * Get an entry, by name.  Returns NULL if not found.\n     *\n     * Does not return entries pending deletion.\n     */\n    ZipEntry* getEntryByName(const char* fileName) const;\n\n    /*\n     * Get the Nth entry in the archive.\n     *\n     * This will return an entry that is pending deletion.\n     */\n    int getNumEntries(void) const { return mEntries.size(); }\n    ZipEntry* getEntryByIndex(int idx) const;\n\nprivate:\n    /* these are private and not defined */\n    ZipFile(const ZipFile& src);\n    ZipFile& operator=(const ZipFile& src);\n\n    class EndOfCentralDir {\n    public:\n        EndOfCentralDir(void) :\n            mDiskNumber(0),\n            mDiskWithCentralDir(0),\n            mNumEntries(0),\n            mTotalNumEntries(0),\n            mCentralDirSize(0),\n            mCentralDirOffset(0),\n            mCommentLen(0),\n            mComment(NULL)\n            {}\n        virtual ~EndOfCentralDir(void) {\n            delete[] mComment;\n        }\n\n        status_t readBuf(const unsigned char* buf, int len);\n        status_t write(FILE* fp);\n\n        //unsigned long   mSignature;\n        unsigned short  mDiskNumber;\n        unsigned short  mDiskWithCentralDir;\n        unsigned short  mNumEntries;\n        unsigned short  mTotalNumEntries;\n        unsigned long   mCentralDirSize;\n        unsigned long   mCentralDirOffset;      // offset from first disk\n        unsigned short  mCommentLen;\n        unsigned char*  mComment;\n\n        enum {\n            kSignature      = 0x06054b50,\n            kEOCDLen        = 22,       // EndOfCentralDir len, excl. comment\n\n            kMaxCommentLen  = 65535,    // longest possible in ushort\n            kMaxEOCDSearch  = kMaxCommentLen + EndOfCentralDir::kEOCDLen,\n\n        };\n\n        void dump(void) const;\n    };\n\n\n    /* read all entries in the central dir */\n    status_t readCentralDir(void);\n\n    /* crunch deleted entries out */\n    status_t crunchArchive(void);\n\n    /* clean up mEntries */\n    void discardEntries(void);\n\n    /* common handler for all \"add\" functions */\n    status_t addCommon(const char* fileName, const void* data, size_t size,\n        const char* storageName, int sourceType, int compressionMethod,\n        ZipEntry** ppEntry);\n\n    /* copy all of \"srcFp\" into \"dstFp\" */\n    status_t copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32);\n    /* copy all of \"data\" into \"dstFp\" */\n    status_t copyDataToFp(FILE* dstFp,\n        const void* data, size_t size, unsigned long* pCRC32);\n    /* copy some of \"srcFp\" into \"dstFp\" */\n    status_t copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,\n        unsigned long* pCRC32);\n    /* like memmove(), but on parts of a single file */\n    status_t filemove(FILE* fp, off_t dest, off_t src, size_t n);\n    /* compress all of \"srcFp\" into \"dstFp\", using Deflate */\n    status_t compressFpToFp(FILE* dstFp, FILE* srcFp,\n        const void* data, size_t size, unsigned long* pCRC32);\n\n    /* get modification date from a file descriptor */\n    time_t getModTime(int fd);\n\n    /*\n     * We use stdio FILE*, which gives us buffering but makes dealing\n     * with files >2GB awkward.  Until we support Zip64, we're fine.\n     */\n    FILE*           mZipFp;             // Zip file pointer\n\n    /* one of these per file */\n    EndOfCentralDir mEOCD;\n\n    /* did we open this read-only? */\n    bool            mReadOnly;\n\n    /* set this when we trash the central dir */\n    bool            mNeedCDRewrite;\n\n    /*\n     * One ZipEntry per entry in the zip file.  I'm using pointers instead\n     * of objects because it's easier than making operator= work for the\n     * classes and sub-classes.\n     */\n    Vector<ZipEntry*>   mEntries;\n};\n\n}; // namespace android\n\n#endif // __LIBS_ZIPFILE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/pseudolocalize.cpp",
    "content": "#include \"pseudolocalize.h\"\n\nusing namespace std;\n\n// String basis to generate expansion\nstatic const String16 k_expansion_string = String16(\"one two three \"\n    \"four five six seven eight nine ten eleven twelve thirteen \"\n    \"fourteen fiveteen sixteen seventeen nineteen twenty\");\n\n// Special unicode characters to override directionality of the words\nstatic const String16 k_rlm = String16(\"\\xe2\\x80\\x8f\");\nstatic const String16 k_rlo = String16(\"\\xE2\\x80\\xae\");\nstatic const String16 k_pdf = String16(\"\\xE2\\x80\\xac\");\n\n// Placeholder marks\nstatic const String16 k_placeholder_open = String16(\"\\xc2\\xbb\");\nstatic const String16 k_placeholder_close = String16(\"\\xc2\\xab\");\n\nstatic const char16_t k_arg_start = '{';\nstatic const char16_t k_arg_end = '}';\n\nPseudolocalizer::Pseudolocalizer(PseudolocalizationMethod m)\n    : mImpl(nullptr), mLastDepth(0) {\n  setMethod(m);\n}\n\nvoid Pseudolocalizer::setMethod(PseudolocalizationMethod m) {\n  if (mImpl) {\n    delete mImpl;\n  }\n  if (m == PSEUDO_ACCENTED) {\n    mImpl = new PseudoMethodAccent();\n  } else if (m == PSEUDO_BIDI) {\n    mImpl = new PseudoMethodBidi();\n  } else {\n    mImpl = new PseudoMethodNone();\n  }\n}\n\nString16 Pseudolocalizer::text(const String16& text) {\n  String16 out;\n  size_t depth = mLastDepth;\n  size_t lastpos, pos;\n  const size_t length= text.size();\n  const char16_t* str = text.string();\n  bool escaped = false;\n  for (lastpos = pos = 0; pos < length; pos++) {\n    char16_t c = str[pos];\n    if (escaped) {\n      escaped = false;\n      continue;\n    }\n    if (c == '\\'') {\n      escaped = true;\n      continue;\n    }\n\n    if (c == k_arg_start) {\n      depth++;\n    } else if (c == k_arg_end && depth) {\n      depth--;\n    }\n\n    if (mLastDepth != depth || pos == length - 1) {\n      bool pseudo = ((mLastDepth % 2) == 0);\n      size_t nextpos = pos;\n      if (!pseudo || depth == mLastDepth) {\n        nextpos++;\n      }\n      size_t size = nextpos - lastpos;\n      if (size) {\n        String16 chunk = String16(text, size, lastpos);\n        if (pseudo) {\n          chunk = mImpl->text(chunk);\n        } else if (str[lastpos] == k_arg_start &&\n                   str[nextpos - 1] == k_arg_end) {\n          chunk = mImpl->placeholder(chunk);\n        }\n        out.append(chunk);\n      }\n      if (pseudo && depth < mLastDepth) { // End of message\n        out.append(mImpl->end());\n      } else if (!pseudo && depth > mLastDepth) { // Start of message\n        out.append(mImpl->start());\n      }\n      lastpos = nextpos;\n      mLastDepth = depth;\n    }\n  }\n  return out;\n}\n\nstatic const char*\npseudolocalize_char(const char16_t c)\n{\n    switch (c) {\n        case 'a':   return \"\\xc3\\xa5\";\n        case 'b':   return \"\\xc9\\x93\";\n        case 'c':   return \"\\xc3\\xa7\";\n        case 'd':   return \"\\xc3\\xb0\";\n        case 'e':   return \"\\xc3\\xa9\";\n        case 'f':   return \"\\xc6\\x92\";\n        case 'g':   return \"\\xc4\\x9d\";\n        case 'h':   return \"\\xc4\\xa5\";\n        case 'i':   return \"\\xc3\\xae\";\n        case 'j':   return \"\\xc4\\xb5\";\n        case 'k':   return \"\\xc4\\xb7\";\n        case 'l':   return \"\\xc4\\xbc\";\n        case 'm':   return \"\\xe1\\xb8\\xbf\";\n        case 'n':   return \"\\xc3\\xb1\";\n        case 'o':   return \"\\xc3\\xb6\";\n        case 'p':   return \"\\xc3\\xbe\";\n        case 'q':   return \"\\x51\";\n        case 'r':   return \"\\xc5\\x95\";\n        case 's':   return \"\\xc5\\xa1\";\n        case 't':   return \"\\xc5\\xa3\";\n        case 'u':   return \"\\xc3\\xbb\";\n        case 'v':   return \"\\x56\";\n        case 'w':   return \"\\xc5\\xb5\";\n        case 'x':   return \"\\xd1\\x85\";\n        case 'y':   return \"\\xc3\\xbd\";\n        case 'z':   return \"\\xc5\\xbe\";\n        case 'A':   return \"\\xc3\\x85\";\n        case 'B':   return \"\\xce\\xb2\";\n        case 'C':   return \"\\xc3\\x87\";\n        case 'D':   return \"\\xc3\\x90\";\n        case 'E':   return \"\\xc3\\x89\";\n        case 'G':   return \"\\xc4\\x9c\";\n        case 'H':   return \"\\xc4\\xa4\";\n        case 'I':   return \"\\xc3\\x8e\";\n        case 'J':   return \"\\xc4\\xb4\";\n        case 'K':   return \"\\xc4\\xb6\";\n        case 'L':   return \"\\xc4\\xbb\";\n        case 'M':   return \"\\xe1\\xb8\\xbe\";\n        case 'N':   return \"\\xc3\\x91\";\n        case 'O':   return \"\\xc3\\x96\";\n        case 'P':   return \"\\xc3\\x9e\";\n        case 'Q':   return \"\\x71\";\n        case 'R':   return \"\\xc5\\x94\";\n        case 'S':   return \"\\xc5\\xa0\";\n        case 'T':   return \"\\xc5\\xa2\";\n        case 'U':   return \"\\xc3\\x9b\";\n        case 'V':   return \"\\xce\\xbd\";\n        case 'W':   return \"\\xc5\\xb4\";\n        case 'X':   return \"\\xc3\\x97\";\n        case 'Y':   return \"\\xc3\\x9d\";\n        case 'Z':   return \"\\xc5\\xbd\";\n        case '!':   return \"\\xc2\\xa1\";\n        case '?':   return \"\\xc2\\xbf\";\n        case '$':   return \"\\xe2\\x82\\xac\";\n        default:    return NULL;\n    }\n}\n\nstatic bool is_possible_normal_placeholder_end(const char16_t c) {\n    switch (c) {\n        case 's': return true;\n        case 'S': return true;\n        case 'c': return true;\n        case 'C': return true;\n        case 'd': return true;\n        case 'o': return true;\n        case 'x': return true;\n        case 'X': return true;\n        case 'f': return true;\n        case 'e': return true;\n        case 'E': return true;\n        case 'g': return true;\n        case 'G': return true;\n        case 'a': return true;\n        case 'A': return true;\n        case 'b': return true;\n        case 'B': return true;\n        case 'h': return true;\n        case 'H': return true;\n        case '%': return true;\n        case 'n': return true;\n        default:  return false;\n    }\n}\n\nstatic String16 pseudo_generate_expansion(const unsigned int length) {\n    String16 result = k_expansion_string;\n    const char16_t* s = result.string();\n    if (result.size() < length) {\n        result += String16(\" \");\n        result += pseudo_generate_expansion(length - result.size());\n    } else {\n        int ext = 0;\n        // Should contain only whole words, so looking for a space\n        for (unsigned int i = length + 1; i < result.size(); ++i) {\n          ++ext;\n          if (s[i] == ' ') {\n            break;\n          }\n        }\n        result.remove(length + ext, 0);\n    }\n    return result;\n}\n\nstatic bool is_space(const char16_t c) {\n  return (c == ' ' || c == '\\t' || c == '\\n');\n}\n\nString16 PseudoMethodAccent::start() {\n  String16 result;\n  if (mDepth == 0) {\n    result = String16(String8(\"[\"));\n  }\n  mWordCount = mLength = 0;\n  mDepth++;\n  return result;\n}\n\nString16 PseudoMethodAccent::end() {\n  String16 result;\n  if (mLength) {\n    result.append(String16(String8(\" \")));\n    result.append(pseudo_generate_expansion(\n        mWordCount > 3 ? mLength : mLength / 2));\n  }\n  mWordCount = mLength = 0;\n  mDepth--;\n  if (mDepth == 0) {\n    result.append(String16(String8(\"]\")));\n  }\n  return result;\n}\n\n/**\n * Converts characters so they look like they've been localized.\n *\n * Note: This leaves escape sequences untouched so they can later be\n * processed by ResTable::collectString in the normal way.\n */\nString16 PseudoMethodAccent::text(const String16& source)\n{\n    const char16_t* s = source.string();\n    String16 result;\n    const size_t I = source.size();\n    bool lastspace = true;\n    for (size_t i=0; i<I; i++) {\n        char16_t c = s[i];\n        if (c == '\\\\') {\n            // Escape syntax, no need to pseudolocalize\n            if (i<I-1) {\n                result += String16(\"\\\\\");\n                i++;\n                c = s[i];\n                switch (c) {\n                    case 'u':\n                        // this one takes up 5 chars\n                        result += String16(s+i, 5);\n                        i += 4;\n                        break;\n                    case 't':\n                    case 'n':\n                    case '#':\n                    case '@':\n                    case '?':\n                    case '\"':\n                    case '\\'':\n                    case '\\\\':\n                    default:\n                        result.append(&c, 1);\n                        break;\n                }\n            } else {\n                result.append(&c, 1);\n            }\n        } else if (c == '%') {\n            // Placeholder syntax, no need to pseudolocalize\n            String16 chunk;\n            bool end = false;\n            chunk.append(&c, 1);\n            while (!end && i < I) {\n                ++i;\n                c = s[i];\n                chunk.append(&c, 1);\n                if (is_possible_normal_placeholder_end(c)) {\n                    end = true;\n                } else if (c == 't') {\n                    ++i;\n                    c = s[i];\n                    chunk.append(&c, 1);\n                    end = true;\n                }\n            }\n            // Treat chunk as a placeholder unless it ends with %.\n            result += ((c == '%') ? chunk : placeholder(chunk));\n        } else if (c == '<' || c == '&') {\n            // html syntax, no need to pseudolocalize\n            bool tag_closed = false;\n            while (!tag_closed && i < I) {\n                if (c == '&') {\n                    String16 escape_text;\n                    escape_text.append(&c, 1);\n                    bool end = false;\n                    size_t htmlCodePos = i;\n                    while (!end && htmlCodePos < I) {\n                        ++htmlCodePos;\n                        c = s[htmlCodePos];\n                        escape_text.append(&c, 1);\n                        // Valid html code\n                        if (c == ';') {\n                            end = true;\n                            i = htmlCodePos;\n                        }\n                        // Wrong html code\n                        else if (!((c == '#' ||\n                                 (c >= 'a' && c <= 'z') ||\n                                 (c >= 'A' && c <= 'Z') ||\n                                 (c >= '0' && c <= '9')))) {\n                            end = true;\n                        }\n                    }\n                    result += escape_text;\n                    if (escape_text != String16(\"&lt;\")) {\n                        tag_closed = true;\n                    }\n                    continue;\n                }\n                if (c == '>') {\n                    tag_closed = true;\n                    result.append(&c, 1);\n                    continue;\n                }\n                result.append(&c, 1);\n                i++;\n                c = s[i];\n            }\n        } else {\n            // This is a pure text that should be pseudolocalized\n            const char* p = pseudolocalize_char(c);\n            if (p != NULL) {\n                result += String16(p);\n            } else {\n                bool space = is_space(c);\n                if (lastspace && !space) {\n                  mWordCount++;\n                }\n                lastspace = space;\n                result.append(&c, 1);\n            }\n            // Count only pseudolocalizable chars and delimiters\n            mLength++;\n        }\n    }\n    return result;\n}\nString16 PseudoMethodAccent::placeholder(const String16& source) {\n  // Surround a placeholder with brackets\n  return k_placeholder_open + source + k_placeholder_close;\n}\n\nString16 PseudoMethodBidi::text(const String16& source)\n{\n    const char16_t* s = source.string();\n    String16 result;\n    bool lastspace = true;\n    bool space = true;\n    for (size_t i=0; i<source.size(); i++) {\n        char16_t c = s[i];\n        space = is_space(c);\n        if (lastspace && !space) {\n          // Word start\n          result += k_rlm + k_rlo;\n        } else if (!lastspace && space) {\n          // Word end\n          result += k_pdf + k_rlm;\n        }\n        lastspace = space;\n        result.append(&c, 1);\n    }\n    if (!lastspace) {\n      // End of last word\n      result += k_pdf + k_rlm;\n    }\n    return result;\n}\n\nString16 PseudoMethodBidi::placeholder(const String16& source) {\n  // Surround a placeholder with directionality change sequence\n  return k_rlm + k_rlo + source + k_pdf + k_rlm;\n}\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/pseudolocalize.h",
    "content": "#ifndef HOST_PSEUDOLOCALIZE_H\n#define HOST_PSEUDOLOCALIZE_H\n\n#include <android-base/macros.h>\n#include \"StringPool.h\"\n\nclass PseudoMethodImpl {\n public:\n  virtual ~PseudoMethodImpl() {}\n  virtual String16 start() { return String16(); }\n  virtual String16 end() { return String16(); }\n  virtual String16 text(const String16& text) = 0;\n  virtual String16 placeholder(const String16& text) = 0;\n};\n\nclass PseudoMethodNone : public PseudoMethodImpl {\n public:\n  PseudoMethodNone() {}\n  String16 text(const String16& text) { return text; }\n  String16 placeholder(const String16& text) { return text; }\n private:\n  DISALLOW_COPY_AND_ASSIGN(PseudoMethodNone);\n};\n\nclass PseudoMethodBidi : public PseudoMethodImpl {\n public:\n  String16 text(const String16& text);\n  String16 placeholder(const String16& text);\n};\n\nclass PseudoMethodAccent : public PseudoMethodImpl {\n public:\n  PseudoMethodAccent() : mDepth(0), mWordCount(0), mLength(0) {}\n  String16 start();\n  String16 end();\n  String16 text(const String16& text);\n  String16 placeholder(const String16& text);\n private:\n  size_t mDepth;\n  size_t mWordCount;\n  size_t mLength;\n};\n\nclass Pseudolocalizer {\n public:\n  Pseudolocalizer(PseudolocalizationMethod m);\n  ~Pseudolocalizer() { if (mImpl) delete mImpl; }\n  void setMethod(PseudolocalizationMethod m);\n  String16 start() { return mImpl->start(); }\n  String16 end() { return mImpl->end(); }\n  String16 text(const String16& text);\n private:\n  PseudoMethodImpl *mImpl;\n  size_t mLastDepth;\n};\n\n#endif // HOST_PSEUDOLOCALIZE_H\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/tests/AaptConfig_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <utils/String8.h>\n#include <gtest/gtest.h>\n\n#include \"AaptConfig.h\"\n#include \"ConfigDescription.h\"\n#include \"SdkConstants.h\"\n#include \"TestHelper.h\"\n\nusing android::String8;\n\nstatic ::testing::AssertionResult TestParse(const String8& input, ConfigDescription* config=NULL) {\n    if (AaptConfig::parse(String8(input), config)) {\n        return ::testing::AssertionSuccess() << input << \" was successfully parsed\";\n    }\n    return ::testing::AssertionFailure() << input << \" could not be parsed\";\n}\n\nstatic ::testing::AssertionResult TestParse(const char* input, ConfigDescription* config=NULL) {\n    return TestParse(String8(input), config);\n}\n\nTEST(AaptConfigTest, ParseFailWhenQualifiersAreOutOfOrder) {\n    EXPECT_FALSE(TestParse(\"en-sw600dp-ldrtl\"));\n    EXPECT_FALSE(TestParse(\"land-en\"));\n    EXPECT_FALSE(TestParse(\"hdpi-320dpi\"));\n}\n\nTEST(AaptConfigTest, ParseFailWhenQualifiersAreNotMatched) {\n    EXPECT_FALSE(TestParse(\"en-sw600dp-ILLEGAL\"));\n}\n\nTEST(AaptConfigTest, ParseFailWhenQualifiersHaveTrailingDash) {\n    EXPECT_FALSE(TestParse(\"en-sw600dp-land-\"));\n}\n\nTEST(AaptConfigTest, ParseBasicQualifiers) {\n    ConfigDescription config;\n    EXPECT_TRUE(TestParse(\"\", &config));\n    EXPECT_EQ(String8(\"\"), config.toString());\n\n    EXPECT_TRUE(TestParse(\"fr-land\", &config));\n    EXPECT_EQ(String8(\"fr-land\"), config.toString());\n\n    EXPECT_TRUE(TestParse(\"mcc310-pl-sw720dp-normal-long-port-night-\"\n                \"xhdpi-keyssoft-qwerty-navexposed-nonav\", &config));\n    EXPECT_EQ(String8(\"mcc310-pl-sw720dp-normal-long-port-night-\"\n                \"xhdpi-keyssoft-qwerty-navexposed-nonav-v13\"), config.toString());\n}\n\nTEST(AaptConfigTest, ParseLocales) {\n    ConfigDescription config;\n    EXPECT_TRUE(TestParse(\"en-rUS\", &config));\n    EXPECT_EQ(String8(\"en-rUS\"), config.toString());\n}\n\nTEST(AaptConfigTest, ParseQualifierAddedInApi13) {\n    ConfigDescription config;\n    EXPECT_TRUE(TestParse(\"sw600dp\", &config));\n    EXPECT_EQ(String8(\"sw600dp-v13\"), config.toString());\n\n    EXPECT_TRUE(TestParse(\"sw600dp-v8\", &config));\n    EXPECT_EQ(String8(\"sw600dp-v13\"), config.toString());\n}\n\nTEST(AaptConfigTest, TestParsingOfCarAttribute) {\n    ConfigDescription config;\n    EXPECT_TRUE(TestParse(\"car\", &config));\n    EXPECT_EQ(android::ResTable_config::UI_MODE_TYPE_CAR, config.uiMode);\n}\n\nTEST(AaptConfigTest, TestParsingRoundQualifier) {\n    ConfigDescription config;\n    EXPECT_TRUE(TestParse(\"round\", &config));\n    EXPECT_EQ(android::ResTable_config::SCREENROUND_YES,\n              config.screenLayout2 & android::ResTable_config::MASK_SCREENROUND);\n    EXPECT_EQ(SDK_MNC, config.sdkVersion);\n    EXPECT_EQ(String8(\"round-v23\"), config.toString());\n\n    EXPECT_TRUE(TestParse(\"notround\", &config));\n    EXPECT_EQ(android::ResTable_config::SCREENROUND_NO,\n              config.screenLayout2 & android::ResTable_config::MASK_SCREENROUND);\n    EXPECT_EQ(SDK_MNC, config.sdkVersion);\n    EXPECT_EQ(String8(\"notround-v23\"), config.toString());\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/tests/AaptGroupEntry_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <utils/String8.h>\n#include <gtest/gtest.h>\n\n#include \"AaptAssets.h\"\n#include \"ResourceFilter.h\"\n#include \"TestHelper.h\"\n\nusing android::String8;\n\nstatic ::testing::AssertionResult TestParse(AaptGroupEntry& entry, const String8& dirName,\n        String8* outType) {\n    if (entry.initFromDirName(dirName, outType)) {\n        return ::testing::AssertionSuccess() << dirName << \" was successfully parsed\";\n    }\n    return ::testing::AssertionFailure() << dirName << \" could not be parsed\";\n}\n\nstatic ::testing::AssertionResult TestParse(AaptGroupEntry& entry, const char* input,\n        String8* outType) {\n    return TestParse(entry, String8(input), outType);\n}\n\nTEST(AaptGroupEntryTest, ParseNoQualifier) {\n    AaptGroupEntry entry;\n    String8 type;\n    EXPECT_TRUE(TestParse(entry, \"menu\", &type));\n    EXPECT_EQ(String8(\"menu\"), type);\n}\n\nTEST(AaptGroupEntryTest, ParseCorrectType) {\n    AaptGroupEntry entry;\n    String8 type;\n    EXPECT_TRUE(TestParse(entry, \"anim\", &type));\n    EXPECT_EQ(String8(\"anim\"), type);\n\n    EXPECT_TRUE(TestParse(entry, \"animator\", &type));\n    EXPECT_EQ(String8(\"animator\"), type);\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/tests/CrunchCache_test.cpp",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n#include <utils/String8.h>\n#include <iostream>\n#include <errno.h>\n\n#include \"CrunchCache.h\"\n#include \"FileFinder.h\"\n#include \"MockFileFinder.h\"\n#include \"CacheUpdater.h\"\n#include \"MockCacheUpdater.h\"\n\nusing namespace android;\nusing std::cout;\nusing std::endl;\n\nvoid expectEqual(int got, int expected, const char* desc) {\n    cout << \"Checking \" << desc << \": \";\n    cout << \"Got \" << got << \", expected \" << expected << \"...\";\n    cout << ( (got == expected) ? \"PASSED\" : \"FAILED\") << endl;\n    errno += ((got == expected) ? 0 : 1);\n}\n\nint main() {\n\n    errno = 0;\n\n    String8 source(\"res\");\n    String8 dest(\"res2\");\n\n    // Create data for MockFileFinder to feed to the cache\n    KeyedVector<String8, time_t> sourceData;\n    // This shouldn't be updated\n    sourceData.add(String8(\"res/drawable/hello.png\"),3);\n    // This should be updated\n    sourceData.add(String8(\"res/drawable/world.png\"),5);\n    // This should cause make directory to be called\n    sourceData.add(String8(\"res/drawable-cool/hello.png\"),3);\n\n    KeyedVector<String8, time_t> destData;\n    destData.add(String8(\"res2/drawable/hello.png\"),3);\n    destData.add(String8(\"res2/drawable/world.png\"),3);\n    // this should call delete\n    destData.add(String8(\"res2/drawable/dead.png\"),3);\n\n    // Package up data and create mock file finder\n    KeyedVector<String8, KeyedVector<String8,time_t> > data;\n    data.add(source,sourceData);\n    data.add(dest,destData);\n    FileFinder* ff = new MockFileFinder(data);\n    CrunchCache cc(source,dest,ff);\n\n    MockCacheUpdater* mcu = new MockCacheUpdater();\n    CacheUpdater* cu(mcu);\n\n    cout << \"Running Crunch...\";\n    int result = cc.crunch(cu);\n    cout << ((result > 0) ? \"PASSED\" : \"FAILED\") << endl;\n    errno += ((result > 0) ? 0 : 1);\n\n    const int EXPECTED_RESULT = 2;\n    expectEqual(result, EXPECTED_RESULT, \"number of files touched\");\n\n    cout << \"Checking calls to deleteFile and processImage:\" << endl;\n    const int EXPECTED_DELETES = 1;\n    const int EXPECTED_PROCESSED = 2;\n    // Deletes\n    expectEqual(mcu->deleteCount, EXPECTED_DELETES, \"deleteFile\");\n    // processImage\n    expectEqual(mcu->processCount, EXPECTED_PROCESSED, \"processImage\");\n\n    const int EXPECTED_OVERWRITES = 3;\n    result = cc.crunch(cu, true);\n    expectEqual(result, EXPECTED_OVERWRITES, \"number of files touched with overwrite\");\n    \\\n\n    if (errno == 0)\n        cout << \"ALL TESTS PASSED!\" << endl;\n    else\n        cout << errno << \" TESTS FAILED\" << endl;\n\n    delete ff;\n    delete cu;\n\n    // TESTS BELOW WILL GO AWAY SOON\n\n    String8 source2(\"ApiDemos/res\");\n    String8 dest2(\"ApiDemos/res2\");\n\n    FileFinder* sff = new SystemFileFinder();\n    CacheUpdater* scu = new SystemCacheUpdater();\n\n    CrunchCache scc(source2,dest2,sff);\n\n    scc.crunch(scu);\n}"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/tests/FileFinder_test.cpp",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n#include <utils/Vector.h>\n#include <utils/KeyedVector.h>\n#include <iostream>\n#include <cassert>\n#include <utils/String8.h>\n#include <utility>\n\n#include \"DirectoryWalker.h\"\n#include \"MockDirectoryWalker.h\"\n#include \"FileFinder.h\"\n\nusing namespace android;\n\nusing std::pair;\nusing std::cout;\nusing std::endl;\n\n\n\nint main()\n{\n\n    cout << \"\\n\\n STARTING FILE FINDER TESTS\" << endl;\n    String8 path(\"ApiDemos\");\n\n    // Storage to pass to findFiles()\n    KeyedVector<String8,time_t> testStorage;\n\n    // Mock Directory Walker initialization. First data, then sdw\n    Vector< pair<String8,time_t> > data;\n    data.push( pair<String8,time_t>(String8(\"hello.png\"),3) );\n    data.push( pair<String8,time_t>(String8(\"world.PNG\"),3) );\n    data.push( pair<String8,time_t>(String8(\"foo.pNg\"),3) );\n    // Neither of these should be found\n    data.push( pair<String8,time_t>(String8(\"hello.jpg\"),3) );\n    data.push( pair<String8,time_t>(String8(\".hidden.png\"),3));\n\n    DirectoryWalker* sdw = new StringDirectoryWalker(path,data);\n\n    // Extensions to look for\n    Vector<String8> exts;\n    exts.push(String8(\".png\"));\n\n    errno = 0;\n\n    // Make sure we get a valid mock directory walker\n    // Make sure we finish without errors\n    cout << \"Checking DirectoryWalker...\";\n    assert(sdw != NULL);\n    cout << \"PASSED\" << endl;\n\n    // Make sure we finish without errors\n    cout << \"Running findFiles()...\";\n    bool findStatus = FileFinder::findFiles(path,exts, testStorage, sdw);\n    assert(findStatus);\n    cout << \"PASSED\" << endl;\n\n    const size_t SIZE_EXPECTED = 3;\n    // Check to make sure we have the right number of things in our storage\n    cout << \"Running size comparison: Size is \" << testStorage.size() << \", \";\n    cout << \"Expected \" << SIZE_EXPECTED << \"...\";\n    if(testStorage.size() == SIZE_EXPECTED)\n        cout << \"PASSED\" << endl;\n    else {\n        cout << \"FAILED\" << endl;\n        errno++;\n    }\n\n    // Check to make sure that each of our found items has the right extension\n    cout << \"Checking Returned Extensions...\";\n    bool extsOkay = true;\n    String8 wrongExts;\n    for (size_t i = 0; i < SIZE_EXPECTED; ++i) {\n        String8 testExt(testStorage.keyAt(i).getPathExtension());\n        testExt.toLower();\n        if (testExt != \".png\") {\n            wrongExts += testStorage.keyAt(i);\n            wrongExts += \"\\n\";\n            extsOkay = false;\n        }\n    }\n    if (extsOkay)\n        cout << \"PASSED\" << endl;\n    else {\n        cout << \"FAILED\" << endl;\n        cout << \"The following extensions didn't check out\" << endl << wrongExts;\n    }\n\n    // Clean up\n    delete sdw;\n\n    if(errno == 0) {\n        cout << \"ALL TESTS PASSED\" << endl;\n    } else {\n        cout << errno << \" TESTS FAILED\" << endl;\n    }\n    return errno;\n}"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/tests/MockCacheUpdater.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n#ifndef MOCKCACHEUPDATER_H\n#define MOCKCACHEUPDATER_H\n\n#include <utils/String8.h>\n#include \"CacheUpdater.h\"\n\nusing namespace android;\n\nclass MockCacheUpdater : public CacheUpdater {\npublic:\n\n    MockCacheUpdater()\n        : deleteCount(0), processCount(0) { };\n\n    // Make sure all the directories along this path exist\n    virtual void ensureDirectoriesExist(String8 path)\n    {\n        // Nothing to do\n    };\n\n    // Delete a file\n    virtual void deleteFile(String8 path) {\n        deleteCount++;\n    };\n\n    // Process an image from source out to dest\n    virtual void processImage(String8 source, String8 dest) {\n        processCount++;\n    };\n\n    // DATA MEMBERS\n    int deleteCount;\n    int processCount;\nprivate:\n};\n\n#endif // MOCKCACHEUPDATER_H"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/tests/MockDirectoryWalker.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n#ifndef MOCKDIRECTORYWALKER_H\n#define MOCKDIRECTORYWALKER_H\n\n#include <utils/Vector.h>\n#include <utils/String8.h>\n#include <utility>\n#include \"DirectoryWalker.h\"\n\nusing namespace android;\nusing std::pair;\n\n// String8 Directory Walker\n// This is an implementation of the Directory Walker abstraction that is built\n// for testing.\n// Instead of system calls it queries a private data structure for the directory\n// entries. It takes a path and a map of filenames and their modification times.\n// functions are inlined since they are short and simple\n\nclass StringDirectoryWalker : public DirectoryWalker {\npublic:\n    StringDirectoryWalker(String8& path, Vector< pair<String8,time_t> >& data)\n        :  mPos(0), mBasePath(path), mData(data) {\n        //fprintf(stdout,\"StringDW built to mimic %s with %d files\\n\",\n        //       mBasePath.string());\n    };\n    // Default copy constructor, and destructor are fine\n\n    virtual bool openDir(String8 path) {\n        // If the user is trying to query the \"directory\" that this\n        // walker was initialized with, then return success. Else fail.\n        return path == mBasePath;\n    };\n    virtual bool openDir(const char* path) {\n        String8 p(path);\n        openDir(p);\n        return true;\n    };\n    // Advance to next entry in the Vector\n    virtual struct dirent* nextEntry() {\n        // Advance position and check to see if we're done\n        if (mPos >= mData.size())\n            return NULL;\n\n        // Place data in the entry descriptor. This class only returns files.\n        mEntry.d_type = DT_REG;\n        mEntry.d_ino = mPos;\n        // Copy chars from the string name to the entry name\n        size_t i = 0;\n        for (i; i < mData[mPos].first.size(); ++i)\n            mEntry.d_name[i] = mData[mPos].first[i];\n        mEntry.d_name[i] = '\\0';\n\n        // Place data in stats\n        mStats.st_ino = mPos;\n        mStats.st_mtime = mData[mPos].second;\n\n        // Get ready to move to the next entry\n        mPos++;\n\n        return &mEntry;\n    };\n    // Get the stats for the current entry\n    virtual struct stat*   entryStats() {\n        return &mStats;\n    };\n    // Nothing to do in clean up\n    virtual void closeDir() {\n        // Nothing to do\n    };\n    virtual DirectoryWalker* clone() {\n        return new StringDirectoryWalker(*this);\n    };\nprivate:\n    // Current position in the Vector\n    size_t mPos;\n    // Base path\n    String8 mBasePath;\n    // Data to simulate a directory full of files.\n    Vector< pair<String8,time_t> > mData;\n};\n\n#endif // MOCKDIRECTORYWALKER_H"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/tests/MockFileFinder.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n\n#ifndef MOCKFILEFINDER_H\n#define MOCKFILEFINDER_H\n\n#include <utils/Vector.h>\n#include <utils/KeyedVector.h>\n#include <utils/String8.h>\n\n#include \"DirectoryWalker.h\"\n\nusing namespace android;\n\nclass MockFileFinder : public FileFinder {\npublic:\n    MockFileFinder (KeyedVector<String8, KeyedVector<String8,time_t> >& files)\n        : mFiles(files)\n    {\n        // Nothing left to do\n    };\n\n    /**\n     * findFiles implementation for the abstraction.\n     * PRECONDITIONS:\n     *  No checking is done, so there MUST be an entry in mFiles with\n     *  path matching basePath.\n     *\n     * POSTCONDITIONS:\n     *  fileStore is filled with a copy of the data in mFiles corresponding\n     *  to the basePath.\n     */\n\n    virtual bool findFiles(String8 basePath, Vector<String8>& extensions,\n                           KeyedVector<String8,time_t>& fileStore,\n                           DirectoryWalker* dw)\n    {\n        const KeyedVector<String8,time_t>* payload(&mFiles.valueFor(basePath));\n        // Since KeyedVector doesn't implement swap\n        // (who doesn't use swap??) we loop and add one at a time.\n        for (size_t i = 0; i < payload->size(); ++i) {\n            fileStore.add(payload->keyAt(i),payload->valueAt(i));\n        }\n        return true;\n    }\n\nprivate:\n    // Virtual mapping between \"directories\" and the \"files\" contained\n    // in them\n    KeyedVector<String8, KeyedVector<String8,time_t> > mFiles;\n};\n\n\n#endif // MOCKFILEFINDER_H"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/tests/Pseudolocales_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/String8.h>\n#include <gtest/gtest.h>\n\n#include \"Bundle.h\"\n#include \"pseudolocalize.h\"\n\nusing android::String8;\n\n// In this context, 'Axis' represents a particular field in the configuration,\n// such as language or density.\n\nstatic void simple_helper(const char* input, const char* expected, PseudolocalizationMethod method) {\n    Pseudolocalizer pseudo(method);\n    String16 result = pseudo.start() + pseudo.text(String16(String8(input))) + pseudo.end();\n    //std::cout << String8(result).string() << std::endl;\n    ASSERT_EQ(String8(expected), String8(result));\n}\n\nstatic void compound_helper(const char* in1, const char* in2, const char *in3,\n                            const char* expected, PseudolocalizationMethod method) {\n    Pseudolocalizer pseudo(method);\n    String16 result = pseudo.start() + \\\n                      pseudo.text(String16(String8(in1))) + \\\n                      pseudo.text(String16(String8(in2))) + \\\n                      pseudo.text(String16(String8(in3))) + \\\n                      pseudo.end();\n    ASSERT_EQ(String8(expected), String8(result));\n}\n\nTEST(Pseudolocales, NoPseudolocalization) {\n  simple_helper(\"\", \"\", NO_PSEUDOLOCALIZATION);\n  simple_helper(\"Hello, world\", \"Hello, world\", NO_PSEUDOLOCALIZATION);\n\n  compound_helper(\"Hello,\", \" world\", \"\",\n                  \"Hello, world\", NO_PSEUDOLOCALIZATION);\n}\n\nTEST(Pseudolocales, PlaintextAccent) {\n  simple_helper(\"\", \"[]\", PSEUDO_ACCENTED);\n  simple_helper(\"Hello, world\",\n                \"[Ĥéļļö, ŵöŕļð one two]\", PSEUDO_ACCENTED);\n\n  simple_helper(\"Hello, %1d\",\n                \"[Ĥéļļö, »%1d« one two]\", PSEUDO_ACCENTED);\n\n  simple_helper(\"Battery %1d%%\",\n                \"[βåţţéŕý »%1d«%% one two]\", PSEUDO_ACCENTED);\n\n  compound_helper(\"\", \"\", \"\", \"[]\", PSEUDO_ACCENTED);\n  compound_helper(\"Hello,\", \" world\", \"\",\n                  \"[Ĥéļļö, ŵöŕļð one two]\", PSEUDO_ACCENTED);\n}\n\nTEST(Pseudolocales, PlaintextBidi) {\n  simple_helper(\"\", \"\", PSEUDO_BIDI);\n  simple_helper(\"word\",\n                \"\\xe2\\x80\\x8f\\xE2\\x80\\xaeword\\xE2\\x80\\xac\\xe2\\x80\\x8f\",\n                PSEUDO_BIDI);\n  simple_helper(\"  word  \",\n                \"  \\xe2\\x80\\x8f\\xE2\\x80\\xaeword\\xE2\\x80\\xac\\xe2\\x80\\x8f  \",\n                PSEUDO_BIDI);\n  simple_helper(\"  word  \",\n                \"  \\xe2\\x80\\x8f\\xE2\\x80\\xaeword\\xE2\\x80\\xac\\xe2\\x80\\x8f  \",\n                PSEUDO_BIDI);\n  simple_helper(\"hello\\n  world\\n\",\n                \"\\xe2\\x80\\x8f\\xE2\\x80\\xaehello\\xE2\\x80\\xac\\xe2\\x80\\x8f\\n\" \\\n                \"  \\xe2\\x80\\x8f\\xE2\\x80\\xaeworld\\xE2\\x80\\xac\\xe2\\x80\\x8f\\n\",\n                PSEUDO_BIDI);\n  compound_helper(\"hello\", \"\\n \", \" world\\n\",\n                \"\\xe2\\x80\\x8f\\xE2\\x80\\xaehello\\xE2\\x80\\xac\\xe2\\x80\\x8f\\n\" \\\n                \"  \\xe2\\x80\\x8f\\xE2\\x80\\xaeworld\\xE2\\x80\\xac\\xe2\\x80\\x8f\\n\",\n                PSEUDO_BIDI);\n}\n\nTEST(Pseudolocales, SimpleICU) {\n  // Single-fragment messages\n  simple_helper(\"{placeholder}\", \"[»{placeholder}«]\", PSEUDO_ACCENTED);\n  simple_helper(\"{USER} is offline\",\n              \"[»{USER}« îš öƒƒļîñé one two]\", PSEUDO_ACCENTED);\n  simple_helper(\"Copy from {path1} to {path2}\",\n              \"[Çöþý ƒŕöḿ »{path1}« ţö »{path2}« one two three]\", PSEUDO_ACCENTED);\n  simple_helper(\"Today is {1,date} {1,time}\",\n              \"[Ţöðåý îš »{1,date}« »{1,time}« one two]\", PSEUDO_ACCENTED);\n\n  // Multi-fragment messages\n  compound_helper(\"{USER}\", \" \", \"is offline\",\n                  \"[»{USER}« îš öƒƒļîñé one two]\",\n                  PSEUDO_ACCENTED);\n  compound_helper(\"Copy from \", \"{path1}\", \" to {path2}\",\n                  \"[Çöþý ƒŕöḿ »{path1}« ţö »{path2}« one two three]\",\n                  PSEUDO_ACCENTED);\n}\n\nTEST(Pseudolocales, ICUBidi) {\n  // Single-fragment messages\n  simple_helper(\"{placeholder}\",\n                \"\\xe2\\x80\\x8f\\xE2\\x80\\xae{placeholder}\\xE2\\x80\\xac\\xe2\\x80\\x8f\",\n                PSEUDO_BIDI);\n  simple_helper(\n      \"{COUNT, plural, one {one} other {other}}\",\n      \"{COUNT, plural, \" \\\n          \"one {\\xe2\\x80\\x8f\\xE2\\x80\\xaeone\\xE2\\x80\\xac\\xe2\\x80\\x8f} \" \\\n        \"other {\\xe2\\x80\\x8f\\xE2\\x80\\xaeother\\xE2\\x80\\xac\\xe2\\x80\\x8f}}\",\n      PSEUDO_BIDI\n  );\n}\n\nTEST(Pseudolocales, Escaping) {\n  // Single-fragment messages\n  simple_helper(\"'{USER'} is offline\",\n                \"['{ÛŠÉŔ'} îš öƒƒļîñé one two three]\", PSEUDO_ACCENTED);\n\n  // Multi-fragment messages\n  compound_helper(\"'{USER}\", \" \", \"''is offline\",\n                  \"['{ÛŠÉŔ} ''îš öƒƒļîñé one two three]\", PSEUDO_ACCENTED);\n}\n\nTEST(Pseudolocales, PluralsAndSelects) {\n  simple_helper(\n      \"{COUNT, plural, one {Delete a file} other {Delete {COUNT} files}}\",\n      \"[{COUNT, plural, one {Ðéļéţé å ƒîļé one two} \" \\\n                     \"other {Ðéļéţé »{COUNT}« ƒîļéš one two}}]\",\n      PSEUDO_ACCENTED\n  );\n  simple_helper(\n      \"Distance is {COUNT, plural, one {# mile} other {# miles}}\",\n      \"[Ðîšţåñçé îš {COUNT, plural, one {# ḿîļé one two} \" \\\n                                 \"other {# ḿîļéš one two}}]\",\n      PSEUDO_ACCENTED\n  );\n  simple_helper(\n      \"{1, select, female {{1} added you} \" \\\n        \"male {{1} added you} other {{1} added you}}\",\n      \"[{1, select, female {»{1}« åððéð ýöû one two} \" \\\n        \"male {»{1}« åððéð ýöû one two} other {»{1}« åððéð ýöû one two}}]\",\n      PSEUDO_ACCENTED\n  );\n\n  compound_helper(\n      \"{COUNT, plural, one {Delete a file} \" \\\n        \"other {Delete \", \"{COUNT}\", \" files}}\",\n      \"[{COUNT, plural, one {Ðéļéţé å ƒîļé one two} \" \\\n        \"other {Ðéļéţé »{COUNT}« ƒîļéš one two}}]\",\n      PSEUDO_ACCENTED\n  );\n}\n\nTEST(Pseudolocales, NestedICU) {\n  simple_helper(\n      \"{person, select, \" \\\n        \"female {\" \\\n          \"{num_circles, plural,\" \\\n            \"=0{{person} didn't add you to any of her circles.}\" \\\n            \"=1{{person} added you to one of her circles.}\" \\\n            \"other{{person} added you to her # circles.}}}\" \\\n        \"male {\" \\\n          \"{num_circles, plural,\" \\\n            \"=0{{person} didn't add you to any of his circles.}\" \\\n            \"=1{{person} added you to one of his circles.}\" \\\n            \"other{{person} added you to his # circles.}}}\" \\\n        \"other {\" \\\n          \"{num_circles, plural,\" \\\n            \"=0{{person} didn't add you to any of their circles.}\" \\\n            \"=1{{person} added you to one of their circles.}\" \\\n            \"other{{person} added you to their # circles.}}}}\",\n      \"[{person, select, \" \\\n        \"female {\" \\\n          \"{num_circles, plural,\" \\\n            \"=0{»{person}« ðîðñ'ţ åðð ýöû ţö åñý öƒ ĥéŕ çîŕçļéš.\" \\\n              \" one two three four five}\" \\\n            \"=1{»{person}« åððéð ýöû ţö öñé öƒ ĥéŕ çîŕçļéš.\" \\\n              \" one two three four}\" \\\n            \"other{»{person}« åððéð ýöû ţö ĥéŕ # çîŕçļéš.\" \\\n              \" one two three four}}}\" \\\n        \"male {\" \\\n          \"{num_circles, plural,\" \\\n            \"=0{»{person}« ðîðñ'ţ åðð ýöû ţö åñý öƒ ĥîš çîŕçļéš.\" \\\n              \" one two three four five}\" \\\n            \"=1{»{person}« åððéð ýöû ţö öñé öƒ ĥîš çîŕçļéš.\" \\\n              \" one two three four}\" \\\n            \"other{»{person}« åððéð ýöû ţö ĥîš # çîŕçļéš.\" \\\n              \" one two three four}}}\" \\\n        \"other {{num_circles, plural,\" \\\n          \"=0{»{person}« ðîðñ'ţ åðð ýöû ţö åñý öƒ ţĥéîŕ çîŕçļéš.\" \\\n            \" one two three four five}\" \\\n          \"=1{»{person}« åððéð ýöû ţö öñé öƒ ţĥéîŕ çîŕçļéš.\" \\\n            \" one two three four}\" \\\n          \"other{»{person}« åððéð ýöû ţö ţĥéîŕ # çîŕçļéš.\" \\\n            \" one two three four}}}}]\",\n      PSEUDO_ACCENTED\n  );\n}\n\nTEST(Pseudolocales, RedefineMethod) {\n  Pseudolocalizer pseudo(PSEUDO_ACCENTED);\n  String16 result = pseudo.text(String16(String8(\"Hello, \")));\n  pseudo.setMethod(NO_PSEUDOLOCALIZATION);\n  result.append(pseudo.text(String16(String8(\"world!\"))));\n  ASSERT_EQ(String8(\"Ĥéļļö, world!\"), String8(result));\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/tests/ResourceFilter_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/String8.h>\n#include <gtest/gtest.h>\n\n#include \"AaptConfig.h\"\n#include \"ResourceFilter.h\"\n#include \"ConfigDescription.h\"\n\nusing android::String8;\n\n// In this context, 'Axis' represents a particular field in the configuration,\n// such as language or density.\n\nTEST(WeakResourceFilterTest, EmptyFilterMatchesAnything) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"\")));\n\n    ConfigDescription config;\n    config.density = 320;\n\n    EXPECT_TRUE(filter.match(config));\n\n    config.language[0] = 'f';\n    config.language[1] = 'r';\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, MatchesConfigWithUnrelatedAxis) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"fr\")));\n\n    ConfigDescription config;\n    config.density = 320;\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, MatchesConfigWithSameValueAxis) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"fr\")));\n\n    ConfigDescription config;\n    config.language[0] = 'f';\n    config.language[1] = 'r';\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, MatchesConfigWithSameValueAxisAndOtherUnrelatedAxis) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"fr\")));\n\n    ConfigDescription config;\n    config.language[0] = 'f';\n    config.language[1] = 'r';\n    config.density = 320;\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, MatchesConfigWithOneMatchingAxis) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"fr_FR,sw360dp,normal,en_US\")));\n\n    ConfigDescription config;\n    config.language[0] = 'e';\n    config.language[1] = 'n';\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, DoesNotMatchConfigWithDifferentValueAxis) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"fr\")));\n\n    ConfigDescription config;\n    config.language[0] = 'd';\n    config.language[1] = 'e';\n\n    EXPECT_FALSE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, DoesNotMatchWhenOneQualifierIsExplicitlyNotMatched) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"fr_FR,en_US,normal,large,xxhdpi,sw320dp\")));\n\n    ConfigDescription config;\n    config.language[0] = 'f';\n    config.language[1] = 'r';\n    config.smallestScreenWidthDp = 600;\n    config.version = 13;\n\n    EXPECT_FALSE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, MatchesSmallestWidthWhenSmaller) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"sw600dp\")));\n\n    ConfigDescription config;\n    config.language[0] = 'f';\n    config.language[1] = 'r';\n    config.smallestScreenWidthDp = 320;\n    config.version = 13;\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, MatchesConfigWithSameLanguageButNoRegionSpecified) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"de-rDE\")));\n\n    ConfigDescription config;\n    config.language[0] = 'd';\n    config.language[1] = 'e';\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, ParsesStandardLocaleOnlyString) {\n    WeakResourceFilter filter;\n    EXPECT_EQ(NO_ERROR, filter.parse(String8(\"de_DE\")));\n}\n\nTEST(WeakResourceFilterTest, IgnoresVersion) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"normal-v4\")));\n\n    ConfigDescription config;\n    config.smallestScreenWidthDp = 600;\n    config.version = 13;\n\n    // The configs don't match on any axis besides version, which should be ignored.\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, MatchesConfigWithRegion) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"kok,kok_IN,kok_419\")));\n\n    ConfigDescription config;\n    AaptLocaleValue val;\n    ASSERT_TRUE(val.initFromFilterString(String8(\"kok_IN\")));\n    val.writeTo(&config);\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(StrongResourceFilterTest, MatchesDensities) {\n    ConfigDescription config;\n    config.density = 160;\n    config.version = 4;\n    std::set<ConfigDescription> configs;\n    configs.insert(config);\n\n    StrongResourceFilter filter(configs);\n\n    ConfigDescription expectedConfig;\n    expectedConfig.density = 160;\n    expectedConfig.version = 4;\n    ASSERT_TRUE(filter.match(expectedConfig));\n}\n\nTEST(StrongResourceFilterTest, MatchOnlyMdpiAndExcludeAllOthers) {\n    std::set<ConfigDescription> configsToMatch;\n    ConfigDescription config;\n    config.density = 160;\n    config.version = 4;\n    configsToMatch.insert(config);\n\n    std::set<ConfigDescription> configsToNotMatch;\n    config.density = 480;\n    configsToNotMatch.insert(config);\n\n    AndResourceFilter filter;\n    filter.addFilter(new InverseResourceFilter(new StrongResourceFilter(configsToNotMatch)));\n    filter.addFilter(new StrongResourceFilter(configsToMatch));\n\n    ConfigDescription expectedConfig;\n    expectedConfig.density = 160;\n    expectedConfig.version = 4;\n    ASSERT_TRUE(filter.match(expectedConfig));\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/tests/ResourceTable_test.cpp",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <utils/String8.h>\n#include <gtest/gtest.h>\n\n#include \"ConfigDescription.h\"\n#include \"ResourceTable.h\"\n#include \"TestHelper.h\"\n\nusing android::String16;\n\nTEST(ResourceTableTest, generateVersionedResources) {\n    sp<ResourceTable::ConfigList> configs(new ResourceTable::ConfigList(String16(), SourcePos()));\n\n    ConfigDescription defaultConfig = {};\n\n    ConfigDescription landConfig = {};\n    landConfig.orientation = ResTable_config::ORIENTATION_LAND;\n\n    ConfigDescription sw600dpLandConfig = {};\n    sw600dpLandConfig.orientation = ResTable_config::ORIENTATION_LAND;\n    sw600dpLandConfig.smallestScreenWidthDp = 600;\n\n    configs->addEntry(defaultConfig, new ResourceTable::Entry(String16(), SourcePos()));\n    configs->addEntry(landConfig, new ResourceTable::Entry(String16(), SourcePos()));\n    configs->addEntry(sw600dpLandConfig, new ResourceTable::Entry(String16(), SourcePos()));\n\n    EXPECT_TRUE(ResourceTable::shouldGenerateVersionedResource(configs, defaultConfig, 17));\n    EXPECT_TRUE(ResourceTable::shouldGenerateVersionedResource(configs, landConfig, 17));\n}\n\nTEST(ResourceTableTest, generateVersionedResourceWhenHigherVersionExists) {\n    sp<ResourceTable::ConfigList> configs(new ResourceTable::ConfigList(String16(), SourcePos()));\n\n    ConfigDescription defaultConfig = {};\n\n    ConfigDescription v21Config = {};\n    v21Config.sdkVersion = 21;\n\n    ConfigDescription sw600dpV13Config = {};\n    sw600dpV13Config.smallestScreenWidthDp = 600;\n    sw600dpV13Config.sdkVersion = 13;\n\n    configs->addEntry(defaultConfig, new ResourceTable::Entry(String16(), SourcePos()));\n    configs->addEntry(v21Config, new ResourceTable::Entry(String16(), SourcePos()));\n    configs->addEntry(sw600dpV13Config, new ResourceTable::Entry(String16(), SourcePos()));\n\n    EXPECT_TRUE(ResourceTable::shouldGenerateVersionedResource(configs, defaultConfig, 17));\n    EXPECT_FALSE(ResourceTable::shouldGenerateVersionedResource(configs, defaultConfig, 22));\n}\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/tests/TestHelper.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __TEST_HELPER_H\n#define __TEST_HELPER_H\n\n#include <utils/String8.h>\n\nnamespace android {\n\n/**\n * Stream operator for nicely printing String8's in gtest output.\n */\ninline std::ostream& operator<<(std::ostream& stream, const String8& str) {\n    return stream << str.string();\n}\n\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/tests/plurals/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.android.aapt.test.plurals\">\n\n</manifest>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/tests/plurals/res/values/strings.xml",
    "content": "<resources xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n    <string name=\"ok\">OK</string>\n    <plurals name=\"a_plural\">\n        <item quantity=\"one\">A dog</item>\n        <item quantity=\"other\">Some dogs</item>\n    </plurals>\n</resources>\n"
  },
  {
    "path": "atlas-aapt/frameworks/base/tools/aapt/tests/plurals/run.sh",
    "content": "TEST_DIR=tools/aapt/tests/plurals\nTEST_OUT_DIR=out/plurals_test\n\nrm -rf $TEST_OUT_DIR\nmkdir -p $TEST_OUT_DIR\nmkdir -p $TEST_OUT_DIR/java\n\n#gdb --args \\\naapt package -v -x -m -z  -J $TEST_OUT_DIR/java -M $TEST_DIR/AndroidManifest.xml \\\n             -I out/target/common/obj/APPS/framework-res_intermediates/package-export.apk \\\n             -P $TEST_OUT_DIR/public_resources.xml \\\n             -S $TEST_DIR/res\n\necho\necho \"==================== FILES CREATED ==================== \"\nfind $TEST_OUT_DIR -type f\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/asset_manager.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup Asset\n * @{\n */\n\n/**\n * @file asset_manager.h\n */\n\n#ifndef ANDROID_ASSET_MANAGER_H\n#define ANDROID_ASSET_MANAGER_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct AAssetManager;\n/**\n * {@link AAssetManager} provides access to an application's raw assets by\n * creating {@link AAsset} objects.\n *\n * AAssetManager is a wrapper to the low-level native implementation\n * of the java {@link AAssetManager}, a pointer can be obtained using\n * AAssetManager_fromJava().\n *\n * The asset hierarchy may be examined like a filesystem, using\n * {@link AAssetDir} objects to peruse a single directory.\n *\n * A native {@link AAssetManager} pointer may be shared across multiple threads.\n */\ntypedef struct AAssetManager AAssetManager;\n\nstruct AAssetDir;\n/**\n * {@link AAssetDir} provides access to a chunk of the asset hierarchy as if\n * it were a single directory. The contents are populated by the\n * {@link AAssetManager}.\n *\n * The list of files will be sorted in ascending order by ASCII value.\n */\ntypedef struct AAssetDir AAssetDir;\n\nstruct AAsset;\n/**\n * {@link AAsset} provides access to a read-only asset.\n *\n * {@link AAsset} objects are NOT thread-safe, and should not be shared across\n * threads.\n */\ntypedef struct AAsset AAsset;\n\n/** Available access modes for opening assets with {@link AAssetManager_open} */\nenum {\n    /** No specific information about how data will be accessed. **/\n    AASSET_MODE_UNKNOWN      = 0,\n    /** Read chunks, and seek forward and backward. */\n    AASSET_MODE_RANDOM       = 1,\n    /** Read sequentially, with an occasional forward seek. */\n    AASSET_MODE_STREAMING    = 2,\n    /** Caller plans to ask for a read-only buffer with all data. */\n    AASSET_MODE_BUFFER       = 3\n};\n\n\n/**\n * Open the named directory within the asset hierarchy.  The directory can then\n * be inspected with the AAssetDir functions.  To open the top-level directory,\n * pass in \"\" as the dirName.\n *\n * The object returned here should be freed by calling AAssetDir_close().\n */\nAAssetDir* AAssetManager_openDir(AAssetManager* mgr, const char* dirName);\n\n/**\n * Open an asset.\n *\n * The object returned here should be freed by calling AAsset_close().\n */\nAAsset* AAssetManager_open(AAssetManager* mgr, const char* filename, int mode);\n\n/**\n * Iterate over the files in an asset directory.  A NULL string is returned\n * when all the file names have been returned.\n *\n * The returned file name is suitable for passing to AAssetManager_open().\n *\n * The string returned here is owned by the AssetDir implementation and is not\n * guaranteed to remain valid if any other calls are made on this AAssetDir\n * instance.\n */\nconst char* AAssetDir_getNextFileName(AAssetDir* assetDir);\n\n/**\n * Reset the iteration state of AAssetDir_getNextFileName() to the beginning.\n */\nvoid AAssetDir_rewind(AAssetDir* assetDir);\n\n/**\n * Close an opened AAssetDir, freeing any related resources.\n */\nvoid AAssetDir_close(AAssetDir* assetDir);\n\n/**\n * Attempt to read 'count' bytes of data from the current offset.\n *\n * Returns the number of bytes read, zero on EOF, or < 0 on error.\n */\nint AAsset_read(AAsset* asset, void* buf, size_t count);\n\n/**\n * Seek to the specified offset within the asset data.  'whence' uses the\n * same constants as lseek()/fseek().\n *\n * Returns the new position on success, or (off_t) -1 on error.\n */\noff_t AAsset_seek(AAsset* asset, off_t offset, int whence);\n\n/**\n * Seek to the specified offset within the asset data.  'whence' uses the\n * same constants as lseek()/fseek().\n *\n * Uses 64-bit data type for large files as opposed to the 32-bit type used\n * by AAsset_seek.\n *\n * Returns the new position on success, or (off64_t) -1 on error.\n */\noff64_t AAsset_seek64(AAsset* asset, off64_t offset, int whence);\n\n/**\n * Close the asset, freeing all associated resources.\n */\nvoid AAsset_close(AAsset* asset);\n\n/**\n * Get a pointer to a buffer holding the entire contents of the assset.\n *\n * Returns NULL on failure.\n */\nconst void* AAsset_getBuffer(AAsset* asset);\n\n/**\n * Report the total size of the asset data.\n */\noff_t AAsset_getLength(AAsset* asset);\n\n/**\n * Report the total size of the asset data. Reports the size using a 64-bit\n * number insted of 32-bit as AAsset_getLength.\n */\noff64_t AAsset_getLength64(AAsset* asset);\n\n/**\n * Report the total amount of asset data that can be read from the current position.\n */\noff_t AAsset_getRemainingLength(AAsset* asset);\n\n/**\n * Report the total amount of asset data that can be read from the current position.\n *\n * Uses a 64-bit number instead of a 32-bit number as AAsset_getRemainingLength does.\n */\noff64_t AAsset_getRemainingLength64(AAsset* asset);\n\n/**\n * Open a new file descriptor that can be used to read the asset data. If the\n * start or length cannot be represented by a 32-bit number, it will be\n * truncated. If the file is large, use AAsset_openFileDescriptor64 instead.\n *\n * Returns < 0 if direct fd access is not possible (for example, if the asset is\n * compressed).\n */\nint AAsset_openFileDescriptor(AAsset* asset, off_t* outStart, off_t* outLength);\n\n/**\n * Open a new file descriptor that can be used to read the asset data.\n *\n * Uses a 64-bit number for the offset and length instead of 32-bit instead of\n * as AAsset_openFileDescriptor does.\n *\n * Returns < 0 if direct fd access is not possible (for example, if the asset is\n * compressed).\n */\nint AAsset_openFileDescriptor64(AAsset* asset, off64_t* outStart, off64_t* outLength);\n\n/**\n * Returns whether this asset's internal buffer is allocated in ordinary RAM (i.e. not\n * mmapped).\n */\nint AAsset_isAllocated(AAsset* asset);\n\n\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif      // ANDROID_ASSET_MANAGER_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/asset_manager_jni.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup Asset\n * @{\n */\n\n/**\n * @file asset_manager_jni.h\n */\n\n#ifndef ANDROID_ASSET_MANAGER_JNI_H\n#define ANDROID_ASSET_MANAGER_JNI_H\n\n#include <android/asset_manager.h>\n#include <jni.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Given a Dalvik AssetManager object, obtain the corresponding native AAssetManager\n * object.  Note that the caller is responsible for obtaining and holding a VM reference\n * to the jobject to prevent its being garbage collected while the native object is\n * in use.\n */\nAAssetManager* AAssetManager_fromJava(JNIEnv* env, jobject assetManager);\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif      // ANDROID_ASSET_MANAGER_JNI_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/bitmap.h",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup Bitmap\n * @{\n */\n\n/**\n * @file bitmap.h\n */\n\n#ifndef ANDROID_BITMAP_H\n#define ANDROID_BITMAP_H\n\n#include <stdint.h>\n#include <jni.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** AndroidBitmap functions result code. */\nenum {\n    /** Operation was successful. */\n    ANDROID_BITMAP_RESULT_SUCCESS           = 0,\n    /** Bad parameter. */\n    ANDROID_BITMAP_RESULT_BAD_PARAMETER     = -1,\n    /** JNI exception occured. */\n    ANDROID_BITMAP_RESULT_JNI_EXCEPTION     = -2,\n    /** Allocation failed. */\n    ANDROID_BITMAP_RESULT_ALLOCATION_FAILED = -3,\n};\n\n/** Backward compatibility: this macro used to be misspelled. */\n#define ANDROID_BITMAP_RESUT_SUCCESS ANDROID_BITMAP_RESULT_SUCCESS\n\n/** Bitmap pixel format. */\nenum AndroidBitmapFormat {\n    /** No format. */\n    ANDROID_BITMAP_FORMAT_NONE      = 0,\n    /** Red: 8 bits, Green: 8 bits, Blue: 8 bits, Alpha: 8 bits. **/\n    ANDROID_BITMAP_FORMAT_RGBA_8888 = 1,\n    /** Red: 5 bits, Green: 6 bits, Blue: 5 bits. **/\n    ANDROID_BITMAP_FORMAT_RGB_565   = 4,\n    /** Red: 4 bits, Green: 4 bits, Blue: 4 bits, Alpha: 4 bits. **/\n    ANDROID_BITMAP_FORMAT_RGBA_4444 = 7,\n    /** Deprecated. */\n    ANDROID_BITMAP_FORMAT_A_8       = 8,\n};\n\n/** Bitmap info, see AndroidBitmap_getInfo(). */\ntypedef struct {\n    /** The bitmap width in pixels. */\n    uint32_t    width;\n    /** The bitmap height in pixels. */\n    uint32_t    height;\n    /** The number of byte per row. */\n    uint32_t    stride;\n    /** The bitmap pixel format. See {@link AndroidBitmapFormat} */\n    int32_t     format;\n    /** Unused. */\n    uint32_t    flags;      // 0 for now\n} AndroidBitmapInfo;\n\n/**\n * Given a java bitmap object, fill out the AndroidBitmapInfo struct for it.\n * If the call fails, the info parameter will be ignored.\n */\nint AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap,\n                          AndroidBitmapInfo* info);\n\n/**\n * Given a java bitmap object, attempt to lock the pixel address.\n * Locking will ensure that the memory for the pixels will not move\n * until the unlockPixels call, and ensure that, if the pixels had been\n * previously purged, they will have been restored.\n *\n * If this call succeeds, it must be balanced by a call to\n * AndroidBitmap_unlockPixels, after which time the address of the pixels should\n * no longer be used.\n *\n * If this succeeds, *addrPtr will be set to the pixel address. If the call\n * fails, addrPtr will be ignored.\n */\nint AndroidBitmap_lockPixels(JNIEnv* env, jobject jbitmap, void** addrPtr);\n\n/**\n * Call this to balance a successful call to AndroidBitmap_lockPixels.\n */\nint AndroidBitmap_unlockPixels(JNIEnv* env, jobject jbitmap);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/choreographer.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup Choreographer\n * @{\n */\n\n/**\n * @file choreographer.h\n */\n\n#ifndef ANDROID_CHOREOGRAPHER_H\n#define ANDROID_CHOREOGRAPHER_H\n\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\nstruct AChoreographer;\ntypedef struct AChoreographer AChoreographer;\n\n/**\n * Prototype of the function that is called when a new frame is being rendered.\n * It's passed the time that the frame is being rendered as nanoseconds in the\n * CLOCK_MONOTONIC time base, as well as the data pointer provided by the\n * application that registered a callback. All callbacks that run as part of\n * rendering a frame will observe the same frame time, so it should be used\n * whenever events need to be synchronized (e.g. animations).\n */\ntypedef void (*AChoreographer_frameCallback)(long frameTimeNanos, void* data);\n\n/**\n * Get the AChoreographer instance for the current thread. This must be called\n * on an ALooper thread.\n */\nAChoreographer* AChoreographer_getInstance();\n\n/**\n * Post a callback to be run on the next frame. The data pointer provided will\n * be passed to the callback function when it's called.\n */\nvoid AChoreographer_postFrameCallback(AChoreographer* choreographer,\n                AChoreographer_frameCallback callback, void* data);\n/**\n * Post a callback to be run on the frame following the specified delay. The\n * data pointer provided will be passed to the callback function when it's\n * called.\n */\nvoid AChoreographer_postFrameCallbackDelayed(AChoreographer* choreographer,\n                AChoreographer_frameCallback callback, void* data, long delayMillis);\n__END_DECLS\n\n#endif // ANDROID_CHOREOGRAPHER_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/configuration.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup Configuration\n * @{\n */\n\n/**\n * @file configuration.h\n */\n\n#ifndef ANDROID_CONFIGURATION_H\n#define ANDROID_CONFIGURATION_H\n\n#include <android/asset_manager.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct AConfiguration;\n/**\n * {@link AConfiguration} is an opaque type used to get and set\n * various subsystem configurations.\n *\n * A {@link AConfiguration} pointer can be obtained using:\n * - AConfiguration_new()\n * - AConfiguration_fromAssetManager()\n */\ntypedef struct AConfiguration AConfiguration;\n\n\n/**\n * Define flags and constants for various subsystem configurations.\n */\nenum {\n    /** Orientation: not specified. */\n    ACONFIGURATION_ORIENTATION_ANY  = 0x0000,\n    /**\n     * Orientation: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#OrientationQualifier\">port</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_ORIENTATION_PORT = 0x0001,\n    /**\n     * Orientation: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#OrientationQualifier\">land</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_ORIENTATION_LAND = 0x0002,\n    /** @deprecated Not currently supported or used. */\n    ACONFIGURATION_ORIENTATION_SQUARE = 0x0003,\n\n    /** Touchscreen: not specified. */\n    ACONFIGURATION_TOUCHSCREEN_ANY  = 0x0000,\n    /**\n     * Touchscreen: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#TouchscreenQualifier\">notouch</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_TOUCHSCREEN_NOTOUCH  = 0x0001,\n    /** @deprecated Not currently supported or used. */\n    ACONFIGURATION_TOUCHSCREEN_STYLUS  = 0x0002,\n    /**\n     * Touchscreen: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#TouchscreenQualifier\">finger</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_TOUCHSCREEN_FINGER  = 0x0003,\n\n    /** Density: default density. */\n    ACONFIGURATION_DENSITY_DEFAULT = 0,\n    /**\n     * Density: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier\">ldpi</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_DENSITY_LOW = 120,\n    /**\n     * Density: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier\">mdpi</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_DENSITY_MEDIUM = 160,\n    /**\n     * Density: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier\">tvdpi</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_DENSITY_TV = 213,\n    /**\n     * Density: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier\">hdpi</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_DENSITY_HIGH = 240,\n    /**\n     * Density: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier\">xhdpi</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_DENSITY_XHIGH = 320,\n    /**\n     * Density: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier\">xxhdpi</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_DENSITY_XXHIGH = 480,\n    /**\n     * Density: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier\">xxxhdpi</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_DENSITY_XXXHIGH = 640,\n    /** Density: any density. */\n    ACONFIGURATION_DENSITY_ANY = 0xfffe,\n    /** Density: no density specified. */\n    ACONFIGURATION_DENSITY_NONE = 0xffff,\n\n    /** Keyboard: not specified. */\n    ACONFIGURATION_KEYBOARD_ANY  = 0x0000,\n    /**\n     * Keyboard: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#ImeQualifier\">nokeys</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_KEYBOARD_NOKEYS  = 0x0001,\n    /**\n     * Keyboard: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#ImeQualifier\">qwerty</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_KEYBOARD_QWERTY  = 0x0002,\n    /**\n     * Keyboard: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#ImeQualifier\">12key</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_KEYBOARD_12KEY  = 0x0003,\n\n    /** Navigation: not specified. */\n    ACONFIGURATION_NAVIGATION_ANY  = 0x0000,\n    /**\n     * Navigation: value corresponding to the\n     * <a href=\"@@dacRoot/guide/topics/resources/providing-resources.html#NavigationQualifier\">nonav</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_NAVIGATION_NONAV  = 0x0001,\n    /**\n     * Navigation: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#NavigationQualifier\">dpad</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_NAVIGATION_DPAD  = 0x0002,\n    /**\n     * Navigation: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#NavigationQualifier\">trackball</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_NAVIGATION_TRACKBALL  = 0x0003,\n    /**\n     * Navigation: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#NavigationQualifier\">wheel</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_NAVIGATION_WHEEL  = 0x0004,\n\n    /** Keyboard availability: not specified. */\n    ACONFIGURATION_KEYSHIDDEN_ANY = 0x0000,\n    /**\n     * Keyboard availability: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#KeyboardAvailQualifier\">keysexposed</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_KEYSHIDDEN_NO = 0x0001,\n    /**\n     * Keyboard availability: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#KeyboardAvailQualifier\">keyshidden</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_KEYSHIDDEN_YES = 0x0002,\n    /**\n     * Keyboard availability: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#KeyboardAvailQualifier\">keyssoft</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_KEYSHIDDEN_SOFT = 0x0003,\n\n    /** Navigation availability: not specified. */\n    ACONFIGURATION_NAVHIDDEN_ANY = 0x0000,\n    /**\n     * Navigation availability: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#NavAvailQualifier\">navexposed</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_NAVHIDDEN_NO = 0x0001,\n    /**\n     * Navigation availability: value corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#NavAvailQualifier\">navhidden</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_NAVHIDDEN_YES = 0x0002,\n\n    /** Screen size: not specified. */\n    ACONFIGURATION_SCREENSIZE_ANY  = 0x00,\n    /**\n     * Screen size: value indicating the screen is at least\n     * approximately 320x426 dp units, corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#ScreenSizeQualifier\">small</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_SCREENSIZE_SMALL = 0x01,\n    /**\n     * Screen size: value indicating the screen is at least\n     * approximately 320x470 dp units, corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#ScreenSizeQualifier\">normal</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_SCREENSIZE_NORMAL = 0x02,\n    /**\n     * Screen size: value indicating the screen is at least\n     * approximately 480x640 dp units, corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#ScreenSizeQualifier\">large</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_SCREENSIZE_LARGE = 0x03,\n    /**\n     * Screen size: value indicating the screen is at least\n     * approximately 720x960 dp units, corresponding to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#ScreenSizeQualifier\">xlarge</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_SCREENSIZE_XLARGE = 0x04,\n\n    /** Screen layout: not specified. */\n    ACONFIGURATION_SCREENLONG_ANY = 0x00,\n    /**\n     * Screen layout: value that corresponds to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#ScreenAspectQualifier\">notlong</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_SCREENLONG_NO = 0x1,\n    /**\n     * Screen layout: value that corresponds to the\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#ScreenAspectQualifier\">long</a>\n     * resource qualifier.\n     */\n    ACONFIGURATION_SCREENLONG_YES = 0x2,\n\n    ACONFIGURATION_SCREENROUND_ANY = 0x00,\n    ACONFIGURATION_SCREENROUND_NO = 0x1,\n    ACONFIGURATION_SCREENROUND_YES = 0x2,\n\n    /** UI mode: not specified. */\n    ACONFIGURATION_UI_MODE_TYPE_ANY = 0x00,\n    /**\n     * UI mode: value that corresponds to\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier\">no\n     * UI mode type</a> resource qualifier specified.\n     */\n    ACONFIGURATION_UI_MODE_TYPE_NORMAL = 0x01,\n    /**\n     * UI mode: value that corresponds to\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier\">desk</a> resource qualifier specified.\n     */\n    ACONFIGURATION_UI_MODE_TYPE_DESK = 0x02,\n    /**\n     * UI mode: value that corresponds to\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier\">car</a> resource qualifier specified.\n     */\n    ACONFIGURATION_UI_MODE_TYPE_CAR = 0x03,\n    /**\n     * UI mode: value that corresponds to\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier\">television</a> resource qualifier specified.\n     */\n    ACONFIGURATION_UI_MODE_TYPE_TELEVISION = 0x04,\n    /**\n     * UI mode: value that corresponds to\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier\">appliance</a> resource qualifier specified.\n     */\n    ACONFIGURATION_UI_MODE_TYPE_APPLIANCE = 0x05,\n    /**\n     * UI mode: value that corresponds to\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier\">watch</a> resource qualifier specified.\n     */\n    ACONFIGURATION_UI_MODE_TYPE_WATCH = 0x06,\n\n    /** UI night mode: not specified.*/\n    ACONFIGURATION_UI_MODE_NIGHT_ANY = 0x00,\n    /**\n     * UI night mode: value that corresponds to\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#NightQualifier\">notnight</a> resource qualifier specified.\n     */\n    ACONFIGURATION_UI_MODE_NIGHT_NO = 0x1,\n    /**\n     * UI night mode: value that corresponds to\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#NightQualifier\">night</a> resource qualifier specified.\n     */\n    ACONFIGURATION_UI_MODE_NIGHT_YES = 0x2,\n\n    /** Screen width DPI: not specified. */\n    ACONFIGURATION_SCREEN_WIDTH_DP_ANY = 0x0000,\n\n    /** Screen height DPI: not specified. */\n    ACONFIGURATION_SCREEN_HEIGHT_DP_ANY = 0x0000,\n\n    /** Smallest screen width DPI: not specified.*/\n    ACONFIGURATION_SMALLEST_SCREEN_WIDTH_DP_ANY = 0x0000,\n\n    /** Layout direction: not specified. */\n    ACONFIGURATION_LAYOUTDIR_ANY  = 0x00,\n    /**\n     * Layout direction: value that corresponds to\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#LayoutDirectionQualifier\">ldltr</a> resource qualifier specified.\n     */\n    ACONFIGURATION_LAYOUTDIR_LTR  = 0x01,\n    /**\n     * Layout direction: value that corresponds to\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#LayoutDirectionQualifier\">ldrtl</a> resource qualifier specified.\n     */\n    ACONFIGURATION_LAYOUTDIR_RTL  = 0x02,\n\n    /**\n     * Bit mask for\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#MccQualifier\">mcc</a>\n     * configuration.\n     */\n    ACONFIGURATION_MCC = 0x0001,\n    /**\n     * Bit mask for\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#MccQualifier\">mnc</a>\n     * configuration.\n     */\n    ACONFIGURATION_MNC = 0x0002,\n    /**\n     * Bit mask for\n     * <a href=\"{@docRoot}guide/topics/resources/providing-resources.html#LocaleQualifier\">locale</a>\n     * configuration.\n     */\n    ACONFIGURATION_LOCALE = 0x0004,\n    /**\n     * Bit mask for\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#TouchscreenQualifier\">touchscreen</a>\n     * configuration.\n     */\n    ACONFIGURATION_TOUCHSCREEN = 0x0008,\n    /**\n     * Bit mask for\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#ImeQualifier\">keyboard</a>\n     * configuration.\n     */\n    ACONFIGURATION_KEYBOARD = 0x0010,\n    /**\n     * Bit mask for\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#KeyboardAvailQualifier\">keyboardHidden</a>\n     * configuration.\n     */\n    ACONFIGURATION_KEYBOARD_HIDDEN = 0x0020,\n    /**\n     * Bit mask for\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#NavigationQualifier\">navigation</a>\n     * configuration.\n     */\n    ACONFIGURATION_NAVIGATION = 0x0040,\n    /**\n     * Bit mask for\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#OrientationQualifier\">orientation</a>\n     * configuration.\n     */\n    ACONFIGURATION_ORIENTATION = 0x0080,\n    /**\n     * Bit mask for\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier\">density</a>\n     * configuration.\n     */\n    ACONFIGURATION_DENSITY = 0x0100,\n    /**\n     * Bit mask for\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#ScreenSizeQualifier\">screen size</a>\n     * configuration.\n     */\n    ACONFIGURATION_SCREEN_SIZE = 0x0200,\n    /**\n     * Bit mask for\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#VersionQualifier\">platform version</a>\n     * configuration.\n     */\n    ACONFIGURATION_VERSION = 0x0400,\n    /**\n     * Bit mask for screen layout configuration.\n     */\n    ACONFIGURATION_SCREEN_LAYOUT = 0x0800,\n    /**\n     * Bit mask for\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier\">ui mode</a>\n     * configuration.\n     */\n    ACONFIGURATION_UI_MODE = 0x1000,\n    /**\n     * Bit mask for\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#SmallestScreenWidthQualifier\">smallest screen width</a>\n     * configuration.\n     */\n    ACONFIGURATION_SMALLEST_SCREEN_SIZE = 0x2000,\n    /**\n     * Bit mask for\n     * <a href=\"@dacRoot/guide/topics/resources/providing-resources.html#LayoutDirectionQualifier\">layout direction</a>\n     * configuration.\n     */\n    ACONFIGURATION_LAYOUTDIR = 0x4000,\n    ACONFIGURATION_SCREEN_ROUND = 0x8000,\n    /**\n     * Constant used to to represent MNC (Mobile Network Code) zero.\n     * 0 cannot be used, since it is used to represent an undefined MNC.\n     */\n    ACONFIGURATION_MNC_ZERO = 0xffff,\n};\n\n/**\n * Create a new AConfiguration, initialized with no values set.\n */\nAConfiguration* AConfiguration_new();\n\n/**\n * Free an AConfiguration that was previously created with\n * AConfiguration_new().\n */\nvoid AConfiguration_delete(AConfiguration* config);\n\n/**\n * Create and return a new AConfiguration based on the current configuration in\n * use in the given {@link AAssetManager}.\n */\nvoid AConfiguration_fromAssetManager(AConfiguration* out, AAssetManager* am);\n\n/**\n * Copy the contents of 'src' to 'dest'.\n */\nvoid AConfiguration_copy(AConfiguration* dest, AConfiguration* src);\n\n/**\n * Return the current MCC set in the configuration.  0 if not set.\n */\nint32_t AConfiguration_getMcc(AConfiguration* config);\n\n/**\n * Set the current MCC in the configuration.  0 to clear.\n */\nvoid AConfiguration_setMcc(AConfiguration* config, int32_t mcc);\n\n/**\n * Return the current MNC set in the configuration.  0 if not set.\n */\nint32_t AConfiguration_getMnc(AConfiguration* config);\n\n/**\n * Set the current MNC in the configuration.  0 to clear.\n */\nvoid AConfiguration_setMnc(AConfiguration* config, int32_t mnc);\n\n/**\n * Return the current language code set in the configuration.  The output will\n * be filled with an array of two characters.  They are not 0-terminated.  If\n * a language is not set, they will be 0.\n */\nvoid AConfiguration_getLanguage(AConfiguration* config, char* outLanguage);\n\n/**\n * Set the current language code in the configuration, from the first two\n * characters in the string.\n */\nvoid AConfiguration_setLanguage(AConfiguration* config, const char* language);\n\n/**\n * Return the current country code set in the configuration.  The output will\n * be filled with an array of two characters.  They are not 0-terminated.  If\n * a country is not set, they will be 0.\n */\nvoid AConfiguration_getCountry(AConfiguration* config, char* outCountry);\n\n/**\n * Set the current country code in the configuration, from the first two\n * characters in the string.\n */\nvoid AConfiguration_setCountry(AConfiguration* config, const char* country);\n\n/**\n * Return the current ACONFIGURATION_ORIENTATION_* set in the configuration.\n */\nint32_t AConfiguration_getOrientation(AConfiguration* config);\n\n/**\n * Set the current orientation in the configuration.\n */\nvoid AConfiguration_setOrientation(AConfiguration* config, int32_t orientation);\n\n/**\n * Return the current ACONFIGURATION_TOUCHSCREEN_* set in the configuration.\n */\nint32_t AConfiguration_getTouchscreen(AConfiguration* config);\n\n/**\n * Set the current touchscreen in the configuration.\n */\nvoid AConfiguration_setTouchscreen(AConfiguration* config, int32_t touchscreen);\n\n/**\n * Return the current ACONFIGURATION_DENSITY_* set in the configuration.\n */\nint32_t AConfiguration_getDensity(AConfiguration* config);\n\n/**\n * Set the current density in the configuration.\n */\nvoid AConfiguration_setDensity(AConfiguration* config, int32_t density);\n\n/**\n * Return the current ACONFIGURATION_KEYBOARD_* set in the configuration.\n */\nint32_t AConfiguration_getKeyboard(AConfiguration* config);\n\n/**\n * Set the current keyboard in the configuration.\n */\nvoid AConfiguration_setKeyboard(AConfiguration* config, int32_t keyboard);\n\n/**\n * Return the current ACONFIGURATION_NAVIGATION_* set in the configuration.\n */\nint32_t AConfiguration_getNavigation(AConfiguration* config);\n\n/**\n * Set the current navigation in the configuration.\n */\nvoid AConfiguration_setNavigation(AConfiguration* config, int32_t navigation);\n\n/**\n * Return the current ACONFIGURATION_KEYSHIDDEN_* set in the configuration.\n */\nint32_t AConfiguration_getKeysHidden(AConfiguration* config);\n\n/**\n * Set the current keys hidden in the configuration.\n */\nvoid AConfiguration_setKeysHidden(AConfiguration* config, int32_t keysHidden);\n\n/**\n * Return the current ACONFIGURATION_NAVHIDDEN_* set in the configuration.\n */\nint32_t AConfiguration_getNavHidden(AConfiguration* config);\n\n/**\n * Set the current nav hidden in the configuration.\n */\nvoid AConfiguration_setNavHidden(AConfiguration* config, int32_t navHidden);\n\n/**\n * Return the current SDK (API) version set in the configuration.\n */\nint32_t AConfiguration_getSdkVersion(AConfiguration* config);\n\n/**\n * Set the current SDK version in the configuration.\n */\nvoid AConfiguration_setSdkVersion(AConfiguration* config, int32_t sdkVersion);\n\n/**\n * Return the current ACONFIGURATION_SCREENSIZE_* set in the configuration.\n */\nint32_t AConfiguration_getScreenSize(AConfiguration* config);\n\n/**\n * Set the current screen size in the configuration.\n */\nvoid AConfiguration_setScreenSize(AConfiguration* config, int32_t screenSize);\n\n/**\n * Return the current ACONFIGURATION_SCREENLONG_* set in the configuration.\n */\nint32_t AConfiguration_getScreenLong(AConfiguration* config);\n\n/**\n * Set the current screen long in the configuration.\n */\nvoid AConfiguration_setScreenLong(AConfiguration* config, int32_t screenLong);\n\n/**\n * Return the current ACONFIGURATION_SCREENROUND_* set in the configuration.\n */\nint32_t AConfiguration_getScreenRound(AConfiguration* config);\n\n/**\n * Set the current screen round in the configuration.\n */\nvoid AConfiguration_setScreenRound(AConfiguration* config, int32_t screenRound);\n\n/**\n * Return the current ACONFIGURATION_UI_MODE_TYPE_* set in the configuration.\n */\nint32_t AConfiguration_getUiModeType(AConfiguration* config);\n\n/**\n * Set the current UI mode type in the configuration.\n */\nvoid AConfiguration_setUiModeType(AConfiguration* config, int32_t uiModeType);\n\n/**\n * Return the current ACONFIGURATION_UI_MODE_NIGHT_* set in the configuration.\n */\nint32_t AConfiguration_getUiModeNight(AConfiguration* config);\n\n/**\n * Set the current UI mode night in the configuration.\n */\nvoid AConfiguration_setUiModeNight(AConfiguration* config, int32_t uiModeNight);\n\n/**\n * Return the current configuration screen width in dp units, or\n * ACONFIGURATION_SCREEN_WIDTH_DP_ANY if not set.\n */\nint32_t AConfiguration_getScreenWidthDp(AConfiguration* config);\n\n/**\n * Set the configuration's current screen width in dp units.\n */\nvoid AConfiguration_setScreenWidthDp(AConfiguration* config, int32_t value);\n\n/**\n * Return the current configuration screen height in dp units, or\n * ACONFIGURATION_SCREEN_HEIGHT_DP_ANY if not set.\n */\nint32_t AConfiguration_getScreenHeightDp(AConfiguration* config);\n\n/**\n * Set the configuration's current screen width in dp units.\n */\nvoid AConfiguration_setScreenHeightDp(AConfiguration* config, int32_t value);\n\n/**\n * Return the configuration's smallest screen width in dp units, or\n * ACONFIGURATION_SMALLEST_SCREEN_WIDTH_DP_ANY if not set.\n */\nint32_t AConfiguration_getSmallestScreenWidthDp(AConfiguration* config);\n\n/**\n * Set the configuration's smallest screen width in dp units.\n */\nvoid AConfiguration_setSmallestScreenWidthDp(AConfiguration* config, int32_t value);\n\n/**\n * Return the configuration's layout direction, or\n * ACONFIGURATION_LAYOUTDIR_ANY if not set.\n */\nint32_t AConfiguration_getLayoutDirection(AConfiguration* config);\n\n/**\n * Set the configuration's layout direction.\n */\nvoid AConfiguration_setLayoutDirection(AConfiguration* config, int32_t value);\n\n/**\n * Perform a diff between two configurations.  Returns a bit mask of\n * ACONFIGURATION_* constants, each bit set meaning that configuration element\n * is different between them.\n */\nint32_t AConfiguration_diff(AConfiguration* config1, AConfiguration* config2);\n\n/**\n * Determine whether 'base' is a valid configuration for use within the\n * environment 'requested'.  Returns 0 if there are any values in 'base'\n * that conflict with 'requested'.  Returns 1 if it does not conflict.\n */\nint32_t AConfiguration_match(AConfiguration* base, AConfiguration* requested);\n\n/**\n * Determine whether the configuration in 'test' is better than the existing\n * configuration in 'base'.  If 'requested' is non-NULL, this decision is based\n * on the overall configuration given there.  If it is NULL, this decision is\n * simply based on which configuration is more specific.  Returns non-0 if\n * 'test' is better than 'base'.\n *\n * This assumes you have already filtered the configurations with\n * AConfiguration_match().\n */\nint32_t AConfiguration_isBetterThan(AConfiguration* base, AConfiguration* test,\n        AConfiguration* requested);\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif // ANDROID_CONFIGURATION_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/input.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup Input\n * @{\n */\n\n/**\n * @file input.h\n */\n\n#ifndef _ANDROID_INPUT_H\n#define _ANDROID_INPUT_H\n\n/******************************************************************\n *\n * IMPORTANT NOTICE:\n *\n *   This file is part of Android's set of stable system headers\n *   exposed by the Android NDK (Native Development Kit).\n *\n *   Third-party source AND binary code relies on the definitions\n *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.\n *\n *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)\n *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS\n *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY\n *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES\n */\n\n/*\n * Structures and functions to receive and process input events in\n * native code.\n *\n * NOTE: These functions MUST be implemented by /system/lib/libui.so\n */\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <android/keycodes.h>\n#include <android/looper.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Key states (may be returned by queries about the current state of a\n * particular key code, scan code or switch).\n */\nenum {\n    /** The key state is unknown or the requested key itself is not supported. */\n    AKEY_STATE_UNKNOWN = -1,\n\n    /** The key is up. */\n    AKEY_STATE_UP = 0,\n\n    /** The key is down. */\n    AKEY_STATE_DOWN = 1,\n\n    /** The key is down but is a virtual key press that is being emulated by the system. */\n    AKEY_STATE_VIRTUAL = 2\n};\n\n/**\n * Meta key / modifer state.\n */\nenum {\n    /** No meta keys are pressed. */\n    AMETA_NONE = 0,\n\n    /** This mask is used to check whether one of the ALT meta keys is pressed. */\n    AMETA_ALT_ON = 0x02,\n\n    /** This mask is used to check whether the left ALT meta key is pressed. */\n    AMETA_ALT_LEFT_ON = 0x10,\n\n    /** This mask is used to check whether the right ALT meta key is pressed. */\n    AMETA_ALT_RIGHT_ON = 0x20,\n\n    /** This mask is used to check whether one of the SHIFT meta keys is pressed. */\n    AMETA_SHIFT_ON = 0x01,\n\n    /** This mask is used to check whether the left SHIFT meta key is pressed. */\n    AMETA_SHIFT_LEFT_ON = 0x40,\n\n    /** This mask is used to check whether the right SHIFT meta key is pressed. */\n    AMETA_SHIFT_RIGHT_ON = 0x80,\n\n    /** This mask is used to check whether the SYM meta key is pressed. */\n    AMETA_SYM_ON = 0x04,\n\n    /** This mask is used to check whether the FUNCTION meta key is pressed. */\n    AMETA_FUNCTION_ON = 0x08,\n\n    /** This mask is used to check whether one of the CTRL meta keys is pressed. */\n    AMETA_CTRL_ON = 0x1000,\n\n    /** This mask is used to check whether the left CTRL meta key is pressed. */\n    AMETA_CTRL_LEFT_ON = 0x2000,\n\n    /** This mask is used to check whether the right CTRL meta key is pressed. */\n    AMETA_CTRL_RIGHT_ON = 0x4000,\n\n    /** This mask is used to check whether one of the META meta keys is pressed. */\n    AMETA_META_ON = 0x10000,\n\n    /** This mask is used to check whether the left META meta key is pressed. */\n    AMETA_META_LEFT_ON = 0x20000,\n\n    /** This mask is used to check whether the right META meta key is pressed. */\n    AMETA_META_RIGHT_ON = 0x40000,\n\n    /** This mask is used to check whether the CAPS LOCK meta key is on. */\n    AMETA_CAPS_LOCK_ON = 0x100000,\n\n    /** This mask is used to check whether the NUM LOCK meta key is on. */\n    AMETA_NUM_LOCK_ON = 0x200000,\n\n    /** This mask is used to check whether the SCROLL LOCK meta key is on. */\n    AMETA_SCROLL_LOCK_ON = 0x400000,\n};\n\nstruct AInputEvent;\n/**\n * Input events.\n *\n * Input events are opaque structures.  Use the provided accessors functions to\n * read their properties.\n */\ntypedef struct AInputEvent AInputEvent;\n\n/**\n * Input event types.\n */\nenum {\n    /** Indicates that the input event is a key event. */\n    AINPUT_EVENT_TYPE_KEY = 1,\n\n    /** Indicates that the input event is a motion event. */\n    AINPUT_EVENT_TYPE_MOTION = 2\n};\n\n/**\n * Key event actions.\n */\nenum {\n    /** The key has been pressed down. */\n    AKEY_EVENT_ACTION_DOWN = 0,\n\n    /** The key has been released. */\n    AKEY_EVENT_ACTION_UP = 1,\n\n    /**\n     * Multiple duplicate key events have occurred in a row, or a\n     * complex string is being delivered.  The repeat_count property\n     * of the key event contains the number of times the given key\n     * code should be executed.\n     */\n    AKEY_EVENT_ACTION_MULTIPLE = 2\n};\n\n/**\n * Key event flags.\n */\nenum {\n    /** This mask is set if the device woke because of this key event. */\n    AKEY_EVENT_FLAG_WOKE_HERE = 0x1,\n\n    /** This mask is set if the key event was generated by a software keyboard. */\n    AKEY_EVENT_FLAG_SOFT_KEYBOARD = 0x2,\n\n    /** This mask is set if we don't want the key event to cause us to leave touch mode. */\n    AKEY_EVENT_FLAG_KEEP_TOUCH_MODE = 0x4,\n\n    /**\n     * This mask is set if an event was known to come from a trusted\n     * part of the system.  That is, the event is known to come from\n     * the user, and could not have been spoofed by a third party\n     * component.\n     */\n    AKEY_EVENT_FLAG_FROM_SYSTEM = 0x8,\n\n    /**\n     * This mask is used for compatibility, to identify enter keys that are\n     * coming from an IME whose enter key has been auto-labelled \"next\" or\n     * \"done\".  This allows TextView to dispatch these as normal enter keys\n     * for old applications, but still do the appropriate action when\n     * receiving them.\n     */\n    AKEY_EVENT_FLAG_EDITOR_ACTION = 0x10,\n\n    /**\n     * When associated with up key events, this indicates that the key press\n     * has been canceled.  Typically this is used with virtual touch screen\n     * keys, where the user can slide from the virtual key area on to the\n     * display: in that case, the application will receive a canceled up\n     * event and should not perform the action normally associated with the\n     * key.  Note that for this to work, the application can not perform an\n     * action for a key until it receives an up or the long press timeout has\n     * expired.\n     */\n    AKEY_EVENT_FLAG_CANCELED = 0x20,\n\n    /**\n     * This key event was generated by a virtual (on-screen) hard key area.\n     * Typically this is an area of the touchscreen, outside of the regular\n     * display, dedicated to \"hardware\" buttons.\n     */\n    AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY = 0x40,\n\n    /**\n     * This flag is set for the first key repeat that occurs after the\n     * long press timeout.\n     */\n    AKEY_EVENT_FLAG_LONG_PRESS = 0x80,\n\n    /**\n     * Set when a key event has AKEY_EVENT_FLAG_CANCELED set because a long\n     * press action was executed while it was down.\n     */\n    AKEY_EVENT_FLAG_CANCELED_LONG_PRESS = 0x100,\n\n    /**\n     * Set for AKEY_EVENT_ACTION_UP when this event's key code is still being\n     * tracked from its initial down.  That is, somebody requested that tracking\n     * started on the key down and a long press has not caused\n     * the tracking to be canceled.\n     */\n    AKEY_EVENT_FLAG_TRACKING = 0x200,\n\n    /**\n     * Set when a key event has been synthesized to implement default behavior\n     * for an event that the application did not handle.\n     * Fallback key events are generated by unhandled trackball motions\n     * (to emulate a directional keypad) and by certain unhandled key presses\n     * that are declared in the key map (such as special function numeric keypad\n     * keys when numlock is off).\n     */\n    AKEY_EVENT_FLAG_FALLBACK = 0x400,\n};\n\n/**\n * Bit shift for the action bits holding the pointer index as\n * defined by AMOTION_EVENT_ACTION_POINTER_INDEX_MASK.\n */\n#define AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT 8\n\n/** Motion event actions */\nenum {\n    /** Bit mask of the parts of the action code that are the action itself. */\n    AMOTION_EVENT_ACTION_MASK = 0xff,\n\n    /**\n     * Bits in the action code that represent a pointer index, used with\n     * AMOTION_EVENT_ACTION_POINTER_DOWN and AMOTION_EVENT_ACTION_POINTER_UP.  Shifting\n     * down by AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT provides the actual pointer\n     * index where the data for the pointer going up or down can be found.\n     */\n    AMOTION_EVENT_ACTION_POINTER_INDEX_MASK  = 0xff00,\n\n    /** A pressed gesture has started, the motion contains the initial starting location. */\n    AMOTION_EVENT_ACTION_DOWN = 0,\n\n    /**\n     * A pressed gesture has finished, the motion contains the final release location\n     * as well as any intermediate points since the last down or move event.\n     */\n    AMOTION_EVENT_ACTION_UP = 1,\n\n    /**\n     * A change has happened during a press gesture (between AMOTION_EVENT_ACTION_DOWN and\n     * AMOTION_EVENT_ACTION_UP).  The motion contains the most recent point, as well as\n     * any intermediate points since the last down or move event.\n     */\n    AMOTION_EVENT_ACTION_MOVE = 2,\n\n    /**\n     * The current gesture has been aborted.\n     * You will not receive any more points in it.  You should treat this as\n     * an up event, but not perform any action that you normally would.\n     */\n    AMOTION_EVENT_ACTION_CANCEL = 3,\n\n    /**\n     * A movement has happened outside of the normal bounds of the UI element.\n     * This does not provide a full gesture, but only the initial location of the movement/touch.\n     */\n    AMOTION_EVENT_ACTION_OUTSIDE = 4,\n\n    /**\n     * A non-primary pointer has gone down.\n     * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.\n     */\n    AMOTION_EVENT_ACTION_POINTER_DOWN = 5,\n\n    /**\n     * A non-primary pointer has gone up.\n     * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.\n     */\n    AMOTION_EVENT_ACTION_POINTER_UP = 6,\n\n    /**\n     * A change happened but the pointer is not down (unlike AMOTION_EVENT_ACTION_MOVE).\n     * The motion contains the most recent point, as well as any intermediate points since\n     * the last hover move event.\n     */\n    AMOTION_EVENT_ACTION_HOVER_MOVE = 7,\n\n    /**\n     * The motion event contains relative vertical and/or horizontal scroll offsets.\n     * Use getAxisValue to retrieve the information from AMOTION_EVENT_AXIS_VSCROLL\n     * and AMOTION_EVENT_AXIS_HSCROLL.\n     * The pointer may or may not be down when this event is dispatched.\n     * This action is always delivered to the winder under the pointer, which\n     * may not be the window currently touched.\n     */\n    AMOTION_EVENT_ACTION_SCROLL = 8,\n\n    /** The pointer is not down but has entered the boundaries of a window or view. */\n    AMOTION_EVENT_ACTION_HOVER_ENTER = 9,\n\n    /** The pointer is not down but has exited the boundaries of a window or view. */\n    AMOTION_EVENT_ACTION_HOVER_EXIT = 10,\n\n    /* One or more buttons have been pressed. */\n    AMOTION_EVENT_ACTION_BUTTON_PRESS = 11,\n\n    /* One or more buttons have been released. */\n    AMOTION_EVENT_ACTION_BUTTON_RELEASE = 12,\n};\n\n/**\n * Motion event flags.\n */\nenum {\n    /**\n     * This flag indicates that the window that received this motion event is partly\n     * or wholly obscured by another visible window above it.  This flag is set to true\n     * even if the event did not directly pass through the obscured area.\n     * A security sensitive application can check this flag to identify situations in which\n     * a malicious application may have covered up part of its content for the purpose\n     * of misleading the user or hijacking touches.  An appropriate response might be\n     * to drop the suspect touches or to take additional precautions to confirm the user's\n     * actual intent.\n     */\n    AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED = 0x1,\n};\n\n/**\n * Motion event edge touch flags.\n */\nenum {\n    /** No edges intersected. */\n    AMOTION_EVENT_EDGE_FLAG_NONE = 0,\n\n    /** Flag indicating the motion event intersected the top edge of the screen. */\n    AMOTION_EVENT_EDGE_FLAG_TOP = 0x01,\n\n    /** Flag indicating the motion event intersected the bottom edge of the screen. */\n    AMOTION_EVENT_EDGE_FLAG_BOTTOM = 0x02,\n\n    /** Flag indicating the motion event intersected the left edge of the screen. */\n    AMOTION_EVENT_EDGE_FLAG_LEFT = 0x04,\n\n    /** Flag indicating the motion event intersected the right edge of the screen. */\n    AMOTION_EVENT_EDGE_FLAG_RIGHT = 0x08\n};\n\n/**\n * Constants that identify each individual axis of a motion event.\n * @anchor AMOTION_EVENT_AXIS\n */\nenum {\n    /**\n     * Axis constant: X axis of a motion event.\n     *\n     * - For a touch screen, reports the absolute X screen position of the center of\n     * the touch contact area.  The units are display pixels.\n     * - For a touch pad, reports the absolute X surface position of the center of the touch\n     * contact area. The units are device-dependent.\n     * - For a mouse, reports the absolute X screen position of the mouse pointer.\n     * The units are display pixels.\n     * - For a trackball, reports the relative horizontal displacement of the trackball.\n     * The value is normalized to a range from -1.0 (left) to 1.0 (right).\n     * - For a joystick, reports the absolute X position of the joystick.\n     * The value is normalized to a range from -1.0 (left) to 1.0 (right).\n     */\n    AMOTION_EVENT_AXIS_X = 0,\n    /**\n     * Axis constant: Y axis of a motion event.\n     *\n     * - For a touch screen, reports the absolute Y screen position of the center of\n     * the touch contact area.  The units are display pixels.\n     * - For a touch pad, reports the absolute Y surface position of the center of the touch\n     * contact area. The units are device-dependent.\n     * - For a mouse, reports the absolute Y screen position of the mouse pointer.\n     * The units are display pixels.\n     * - For a trackball, reports the relative vertical displacement of the trackball.\n     * The value is normalized to a range from -1.0 (up) to 1.0 (down).\n     * - For a joystick, reports the absolute Y position of the joystick.\n     * The value is normalized to a range from -1.0 (up or far) to 1.0 (down or near).\n     */\n    AMOTION_EVENT_AXIS_Y = 1,\n    /**\n     * Axis constant: Pressure axis of a motion event.\n     *\n     * - For a touch screen or touch pad, reports the approximate pressure applied to the surface\n     * by a finger or other tool.  The value is normalized to a range from\n     * 0 (no pressure at all) to 1 (normal pressure), although values higher than 1\n     * may be generated depending on the calibration of the input device.\n     * - For a trackball, the value is set to 1 if the trackball button is pressed\n     * or 0 otherwise.\n     * - For a mouse, the value is set to 1 if the primary mouse button is pressed\n     * or 0 otherwise.\n     */\n    AMOTION_EVENT_AXIS_PRESSURE = 2,\n    /**\n     * Axis constant: Size axis of a motion event.\n     *\n     * - For a touch screen or touch pad, reports the approximate size of the contact area in\n     * relation to the maximum detectable size for the device.  The value is normalized\n     * to a range from 0 (smallest detectable size) to 1 (largest detectable size),\n     * although it is not a linear scale. This value is of limited use.\n     * To obtain calibrated size information, see\n     * {@link AMOTION_EVENT_AXIS_TOUCH_MAJOR} or {@link AMOTION_EVENT_AXIS_TOOL_MAJOR}.\n     */\n    AMOTION_EVENT_AXIS_SIZE = 3,\n    /**\n     * Axis constant: TouchMajor axis of a motion event.\n     *\n     * - For a touch screen, reports the length of the major axis of an ellipse that\n     * represents the touch area at the point of contact.\n     * The units are display pixels.\n     * - For a touch pad, reports the length of the major axis of an ellipse that\n     * represents the touch area at the point of contact.\n     * The units are device-dependent.\n     */\n    AMOTION_EVENT_AXIS_TOUCH_MAJOR = 4,\n    /**\n     * Axis constant: TouchMinor axis of a motion event.\n     *\n     * - For a touch screen, reports the length of the minor axis of an ellipse that\n     * represents the touch area at the point of contact.\n     * The units are display pixels.\n     * - For a touch pad, reports the length of the minor axis of an ellipse that\n     * represents the touch area at the point of contact.\n     * The units are device-dependent.\n     *\n     * When the touch is circular, the major and minor axis lengths will be equal to one another.\n     */\n    AMOTION_EVENT_AXIS_TOUCH_MINOR = 5,\n    /**\n     * Axis constant: ToolMajor axis of a motion event.\n     *\n     * - For a touch screen, reports the length of the major axis of an ellipse that\n     * represents the size of the approaching finger or tool used to make contact.\n     * - For a touch pad, reports the length of the major axis of an ellipse that\n     * represents the size of the approaching finger or tool used to make contact.\n     * The units are device-dependent.\n     *\n     * When the touch is circular, the major and minor axis lengths will be equal to one another.\n     *\n     * The tool size may be larger than the touch size since the tool may not be fully\n     * in contact with the touch sensor.\n     */\n    AMOTION_EVENT_AXIS_TOOL_MAJOR = 6,\n    /**\n     * Axis constant: ToolMinor axis of a motion event.\n     *\n     * - For a touch screen, reports the length of the minor axis of an ellipse that\n     * represents the size of the approaching finger or tool used to make contact.\n     * - For a touch pad, reports the length of the minor axis of an ellipse that\n     * represents the size of the approaching finger or tool used to make contact.\n     * The units are device-dependent.\n     *\n     * When the touch is circular, the major and minor axis lengths will be equal to one another.\n     *\n     * The tool size may be larger than the touch size since the tool may not be fully\n     * in contact with the touch sensor.\n     */\n    AMOTION_EVENT_AXIS_TOOL_MINOR = 7,\n    /**\n     * Axis constant: Orientation axis of a motion event.\n     *\n     * - For a touch screen or touch pad, reports the orientation of the finger\n     * or tool in radians relative to the vertical plane of the device.\n     * An angle of 0 radians indicates that the major axis of contact is oriented\n     * upwards, is perfectly circular or is of unknown orientation.  A positive angle\n     * indicates that the major axis of contact is oriented to the right.  A negative angle\n     * indicates that the major axis of contact is oriented to the left.\n     * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians\n     * (finger pointing fully right).\n     * - For a stylus, the orientation indicates the direction in which the stylus\n     * is pointing in relation to the vertical axis of the current orientation of the screen.\n     * The range is from -PI radians to PI radians, where 0 is pointing up,\n     * -PI/2 radians is pointing left, -PI or PI radians is pointing down, and PI/2 radians\n     * is pointing right.  See also {@link AMOTION_EVENT_AXIS_TILT}.\n     */\n    AMOTION_EVENT_AXIS_ORIENTATION = 8,\n    /**\n     * Axis constant: Vertical Scroll axis of a motion event.\n     *\n     * - For a mouse, reports the relative movement of the vertical scroll wheel.\n     * The value is normalized to a range from -1.0 (down) to 1.0 (up).\n     *\n     * This axis should be used to scroll views vertically.\n     */\n    AMOTION_EVENT_AXIS_VSCROLL = 9,\n    /**\n     * Axis constant: Horizontal Scroll axis of a motion event.\n     *\n     * - For a mouse, reports the relative movement of the horizontal scroll wheel.\n     * The value is normalized to a range from -1.0 (left) to 1.0 (right).\n     *\n     * This axis should be used to scroll views horizontally.\n     */\n    AMOTION_EVENT_AXIS_HSCROLL = 10,\n    /**\n     * Axis constant: Z axis of a motion event.\n     *\n     * - For a joystick, reports the absolute Z position of the joystick.\n     * The value is normalized to a range from -1.0 (high) to 1.0 (low).\n     * <em>On game pads with two analog joysticks, this axis is often reinterpreted\n     * to report the absolute X position of the second joystick instead.</em>\n     */\n    AMOTION_EVENT_AXIS_Z = 11,\n    /**\n     * Axis constant: X Rotation axis of a motion event.\n     *\n     * - For a joystick, reports the absolute rotation angle about the X axis.\n     * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).\n     */\n    AMOTION_EVENT_AXIS_RX = 12,\n    /**\n     * Axis constant: Y Rotation axis of a motion event.\n     *\n     * - For a joystick, reports the absolute rotation angle about the Y axis.\n     * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).\n     */\n    AMOTION_EVENT_AXIS_RY = 13,\n    /**\n     * Axis constant: Z Rotation axis of a motion event.\n     *\n     * - For a joystick, reports the absolute rotation angle about the Z axis.\n     * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).\n     * On game pads with two analog joysticks, this axis is often reinterpreted\n     * to report the absolute Y position of the second joystick instead.\n     */\n    AMOTION_EVENT_AXIS_RZ = 14,\n    /**\n     * Axis constant: Hat X axis of a motion event.\n     *\n     * - For a joystick, reports the absolute X position of the directional hat control.\n     * The value is normalized to a range from -1.0 (left) to 1.0 (right).\n     */\n    AMOTION_EVENT_AXIS_HAT_X = 15,\n    /**\n     * Axis constant: Hat Y axis of a motion event.\n     *\n     * - For a joystick, reports the absolute Y position of the directional hat control.\n     * The value is normalized to a range from -1.0 (up) to 1.0 (down).\n     */\n    AMOTION_EVENT_AXIS_HAT_Y = 16,\n    /**\n     * Axis constant: Left Trigger axis of a motion event.\n     *\n     * - For a joystick, reports the absolute position of the left trigger control.\n     * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed).\n     */\n    AMOTION_EVENT_AXIS_LTRIGGER = 17,\n    /**\n     * Axis constant: Right Trigger axis of a motion event.\n     *\n     * - For a joystick, reports the absolute position of the right trigger control.\n     * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed).\n     */\n    AMOTION_EVENT_AXIS_RTRIGGER = 18,\n    /**\n     * Axis constant: Throttle axis of a motion event.\n     *\n     * - For a joystick, reports the absolute position of the throttle control.\n     * The value is normalized to a range from 0.0 (fully open) to 1.0 (fully closed).\n     */\n    AMOTION_EVENT_AXIS_THROTTLE = 19,\n    /**\n     * Axis constant: Rudder axis of a motion event.\n     *\n     * - For a joystick, reports the absolute position of the rudder control.\n     * The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right).\n     */\n    AMOTION_EVENT_AXIS_RUDDER = 20,\n    /**\n     * Axis constant: Wheel axis of a motion event.\n     *\n     * - For a joystick, reports the absolute position of the steering wheel control.\n     * The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right).\n     */\n    AMOTION_EVENT_AXIS_WHEEL = 21,\n    /**\n     * Axis constant: Gas axis of a motion event.\n     *\n     * - For a joystick, reports the absolute position of the gas (accelerator) control.\n     * The value is normalized to a range from 0.0 (no acceleration)\n     * to 1.0 (maximum acceleration).\n     */\n    AMOTION_EVENT_AXIS_GAS = 22,\n    /**\n     * Axis constant: Brake axis of a motion event.\n     *\n     * - For a joystick, reports the absolute position of the brake control.\n     * The value is normalized to a range from 0.0 (no braking) to 1.0 (maximum braking).\n     */\n    AMOTION_EVENT_AXIS_BRAKE = 23,\n    /**\n     * Axis constant: Distance axis of a motion event.\n     *\n     * - For a stylus, reports the distance of the stylus from the screen.\n     * A value of 0.0 indicates direct contact and larger values indicate increasing\n     * distance from the surface.\n     */\n    AMOTION_EVENT_AXIS_DISTANCE = 24,\n    /**\n     * Axis constant: Tilt axis of a motion event.\n     *\n     * - For a stylus, reports the tilt angle of the stylus in radians where\n     * 0 radians indicates that the stylus is being held perpendicular to the\n     * surface, and PI/2 radians indicates that the stylus is being held flat\n     * against the surface.\n     */\n    AMOTION_EVENT_AXIS_TILT = 25,\n    /**\n     * Axis constant:  Generic scroll axis of a motion event.\n     *\n     * - This is used for scroll axis motion events that can't be classified as strictly\n     *   vertical or horizontal. The movement of a rotating scroller is an example of this.\n     */\n    AMOTION_EVENT_AXIS_SCROLL = 26,\n    /**\n     * Axis constant: The movement of x position of a motion event.\n     *\n     * - For a mouse, reports a difference of x position between the previous position.\n     * This is useful when pointer is captured, in that case the mouse pointer doesn't\n     * change the location but this axis reports the difference which allows the app\n     * to see how the mouse is moved.\n     */\n    AMOTION_EVENT_AXIS_RELATIVE_X = 27,\n    /**\n     * Axis constant: The movement of y position of a motion event.\n     *\n     * Same as {@link RELATIVE_X}, but for y position.\n     */\n    AMOTION_EVENT_AXIS_RELATIVE_Y = 28,\n    /**\n     * Axis constant: Generic 1 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_1 = 32,\n    /**\n     * Axis constant: Generic 2 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_2 = 33,\n    /**\n     * Axis constant: Generic 3 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_3 = 34,\n    /**\n     * Axis constant: Generic 4 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_4 = 35,\n    /**\n     * Axis constant: Generic 5 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_5 = 36,\n    /**\n     * Axis constant: Generic 6 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_6 = 37,\n    /**\n     * Axis constant: Generic 7 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_7 = 38,\n    /**\n     * Axis constant: Generic 8 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_8 = 39,\n    /**\n     * Axis constant: Generic 9 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_9 = 40,\n    /**\n     * Axis constant: Generic 10 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_10 = 41,\n    /**\n     * Axis constant: Generic 11 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_11 = 42,\n    /**\n     * Axis constant: Generic 12 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_12 = 43,\n    /**\n     * Axis constant: Generic 13 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_13 = 44,\n    /**\n     * Axis constant: Generic 14 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_14 = 45,\n    /**\n     * Axis constant: Generic 15 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_15 = 46,\n    /**\n     * Axis constant: Generic 16 axis of a motion event.\n     * The interpretation of a generic axis is device-specific.\n     */\n    AMOTION_EVENT_AXIS_GENERIC_16 = 47,\n\n    // NOTE: If you add a new axis here you must also add it to several other files.\n    //       Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.\n};\n\n/**\n * Constants that identify buttons that are associated with motion events.\n * Refer to the documentation on the MotionEvent class for descriptions of each button.\n */\nenum {\n    /** primary */\n    AMOTION_EVENT_BUTTON_PRIMARY = 1 << 0,\n    /** secondary */\n    AMOTION_EVENT_BUTTON_SECONDARY = 1 << 1,\n    /** tertiary */\n    AMOTION_EVENT_BUTTON_TERTIARY = 1 << 2,\n    /** back */\n    AMOTION_EVENT_BUTTON_BACK = 1 << 3,\n    /** forward */\n    AMOTION_EVENT_BUTTON_FORWARD = 1 << 4,\n    AMOTION_EVENT_BUTTON_STYLUS_PRIMARY = 1 << 5,\n    AMOTION_EVENT_BUTTON_STYLUS_SECONDARY = 1 << 6,\n};\n\n/**\n * Constants that identify tool types.\n * Refer to the documentation on the MotionEvent class for descriptions of each tool type.\n */\nenum {\n    /** unknown */\n    AMOTION_EVENT_TOOL_TYPE_UNKNOWN = 0,\n    /** finger */\n    AMOTION_EVENT_TOOL_TYPE_FINGER = 1,\n    /** stylus */\n    AMOTION_EVENT_TOOL_TYPE_STYLUS = 2,\n    /** mouse */\n    AMOTION_EVENT_TOOL_TYPE_MOUSE = 3,\n    /** eraser */\n    AMOTION_EVENT_TOOL_TYPE_ERASER = 4,\n};\n\n/**\n * Input source masks.\n *\n * Refer to the documentation on android.view.InputDevice for more details about input sources\n * and their correct interpretation.\n */\nenum {\n    /** mask */\n    AINPUT_SOURCE_CLASS_MASK = 0x000000ff,\n\n    /** none */\n    AINPUT_SOURCE_CLASS_NONE = 0x00000000,\n    /** button */\n    AINPUT_SOURCE_CLASS_BUTTON = 0x00000001,\n    /** pointer */\n    AINPUT_SOURCE_CLASS_POINTER = 0x00000002,\n    /** navigation */\n    AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004,\n    /** position */\n    AINPUT_SOURCE_CLASS_POSITION = 0x00000008,\n    /** joystick */\n    AINPUT_SOURCE_CLASS_JOYSTICK = 0x00000010,\n};\n\n/**\n * Input sources.\n */\nenum {\n    /** unknown */\n    AINPUT_SOURCE_UNKNOWN = 0x00000000,\n\n    /** keyboard */\n    AINPUT_SOURCE_KEYBOARD = 0x00000100 | AINPUT_SOURCE_CLASS_BUTTON,\n    /** dpad */\n    AINPUT_SOURCE_DPAD = 0x00000200 | AINPUT_SOURCE_CLASS_BUTTON,\n    /** gamepad */\n    AINPUT_SOURCE_GAMEPAD = 0x00000400 | AINPUT_SOURCE_CLASS_BUTTON,\n    /** touchscreen */\n    AINPUT_SOURCE_TOUCHSCREEN = 0x00001000 | AINPUT_SOURCE_CLASS_POINTER,\n    /** mouse */\n    AINPUT_SOURCE_MOUSE = 0x00002000 | AINPUT_SOURCE_CLASS_POINTER,\n    /** stylus */\n    AINPUT_SOURCE_STYLUS = 0x00004000 | AINPUT_SOURCE_CLASS_POINTER,\n    /** bluetooth stylus */\n    AINPUT_SOURCE_BLUETOOTH_STYLUS = 0x00008000 | AINPUT_SOURCE_STYLUS,\n    /** trackball */\n    AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION,\n    /** touchpad */\n    AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION,\n    /** navigation */\n    AINPUT_SOURCE_TOUCH_NAVIGATION = 0x00200000 | AINPUT_SOURCE_CLASS_NONE,\n    /** joystick */\n    AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,\n    /** rotary encoder */\n    AINPUT_SOURCE_ROTARY_ENCODER = 0x00400000 | AINPUT_SOURCE_CLASS_NONE,\n\n    /** any */\n    AINPUT_SOURCE_ANY = 0xffffff00,\n};\n\n/**\n * Keyboard types.\n *\n * Refer to the documentation on android.view.InputDevice for more details.\n */\nenum {\n    /** none */\n    AINPUT_KEYBOARD_TYPE_NONE = 0,\n    /** non alphabetic */\n    AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC = 1,\n    /** alphabetic */\n    AINPUT_KEYBOARD_TYPE_ALPHABETIC = 2,\n};\n\n/**\n * Constants used to retrieve information about the range of motion for a particular\n * coordinate of a motion event.\n *\n * Refer to the documentation on android.view.InputDevice for more details about input sources\n * and their correct interpretation.\n *\n * @deprecated These constants are deprecated. Use {@link AMOTION_EVENT_AXIS AMOTION_EVENT_AXIS_*} constants instead.\n */\nenum {\n    /** x */\n    AINPUT_MOTION_RANGE_X = AMOTION_EVENT_AXIS_X,\n    /** y */\n    AINPUT_MOTION_RANGE_Y = AMOTION_EVENT_AXIS_Y,\n    /** pressure */\n    AINPUT_MOTION_RANGE_PRESSURE = AMOTION_EVENT_AXIS_PRESSURE,\n    /** size */\n    AINPUT_MOTION_RANGE_SIZE = AMOTION_EVENT_AXIS_SIZE,\n    /** touch major */\n    AINPUT_MOTION_RANGE_TOUCH_MAJOR = AMOTION_EVENT_AXIS_TOUCH_MAJOR,\n    /** touch minor */\n    AINPUT_MOTION_RANGE_TOUCH_MINOR = AMOTION_EVENT_AXIS_TOUCH_MINOR,\n    /** tool major */\n    AINPUT_MOTION_RANGE_TOOL_MAJOR = AMOTION_EVENT_AXIS_TOOL_MAJOR,\n    /** tool minor */\n    AINPUT_MOTION_RANGE_TOOL_MINOR = AMOTION_EVENT_AXIS_TOOL_MINOR,\n    /** orientation */\n    AINPUT_MOTION_RANGE_ORIENTATION = AMOTION_EVENT_AXIS_ORIENTATION,\n};\n\n\n/**\n * Input event accessors.\n *\n * Note that most functions can only be used on input events that are of a given type.\n * Calling these functions on input events of other types will yield undefined behavior.\n */\n\n/*** Accessors for all input events. ***/\n\n/** Get the input event type. */\nint32_t AInputEvent_getType(const AInputEvent* event);\n\n/** Get the id for the device that an input event came from.\n *\n * Input events can be generated by multiple different input devices.\n * Use the input device id to obtain information about the input\n * device that was responsible for generating a particular event.\n *\n * An input device id of 0 indicates that the event didn't come from a physical device;\n * other numbers are arbitrary and you shouldn't depend on the values.\n * Use the provided input device query API to obtain information about input devices.\n */\nint32_t AInputEvent_getDeviceId(const AInputEvent* event);\n\n/** Get the input event source. */\nint32_t AInputEvent_getSource(const AInputEvent* event);\n\n/*** Accessors for key events only. ***/\n\n/** Get the key event action. */\nint32_t AKeyEvent_getAction(const AInputEvent* key_event);\n\n/** Get the key event flags. */\nint32_t AKeyEvent_getFlags(const AInputEvent* key_event);\n\n/**\n * Get the key code of the key event.\n * This is the physical key that was pressed, not the Unicode character.\n */\nint32_t AKeyEvent_getKeyCode(const AInputEvent* key_event);\n\n/**\n * Get the hardware key id of this key event.\n * These values are not reliable and vary from device to device.\n */\nint32_t AKeyEvent_getScanCode(const AInputEvent* key_event);\n\n/** Get the meta key state. */\nint32_t AKeyEvent_getMetaState(const AInputEvent* key_event);\n\n/**\n * Get the repeat count of the event.\n * For both key up an key down events, this is the number of times the key has\n * repeated with the first down starting at 0 and counting up from there.  For\n * multiple key events, this is the number of down/up pairs that have occurred.\n */\nint32_t AKeyEvent_getRepeatCount(const AInputEvent* key_event);\n\n/**\n * Get the time of the most recent key down event, in the\n * java.lang.System.nanoTime() time base.  If this is a down event,\n * this will be the same as eventTime.\n * Note that when chording keys, this value is the down time of the most recently\n * pressed key, which may not be the same physical key of this event.\n */\nint64_t AKeyEvent_getDownTime(const AInputEvent* key_event);\n\n/**\n * Get the time this event occurred, in the\n * java.lang.System.nanoTime() time base.\n */\nint64_t AKeyEvent_getEventTime(const AInputEvent* key_event);\n\n/*** Accessors for motion events only. ***/\n\n/** Get the combined motion event action code and pointer index. */\nint32_t AMotionEvent_getAction(const AInputEvent* motion_event);\n\n/** Get the motion event flags. */\nint32_t AMotionEvent_getFlags(const AInputEvent* motion_event);\n\n/**\n * Get the state of any meta / modifier keys that were in effect when the\n * event was generated.\n */\nint32_t AMotionEvent_getMetaState(const AInputEvent* motion_event);\n\n/** Get the button state of all buttons that are pressed. */\nint32_t AMotionEvent_getButtonState(const AInputEvent* motion_event);\n\n/**\n * Get a bitfield indicating which edges, if any, were touched by this motion event.\n * For touch events, clients can use this to determine if the user's finger was\n * touching the edge of the display.\n */\nint32_t AMotionEvent_getEdgeFlags(const AInputEvent* motion_event);\n\n/**\n * Get the time when the user originally pressed down to start a stream of\n * position events, in the java.lang.System.nanoTime() time base.\n */\nint64_t AMotionEvent_getDownTime(const AInputEvent* motion_event);\n\n/**\n * Get the time when this specific event was generated,\n * in the java.lang.System.nanoTime() time base.\n */\nint64_t AMotionEvent_getEventTime(const AInputEvent* motion_event);\n\n/**\n * Get the X coordinate offset.\n * For touch events on the screen, this is the delta that was added to the raw\n * screen coordinates to adjust for the absolute position of the containing windows\n * and views.\n */\nfloat AMotionEvent_getXOffset(const AInputEvent* motion_event);\n\n/**\n * Get the Y coordinate offset.\n * For touch events on the screen, this is the delta that was added to the raw\n * screen coordinates to adjust for the absolute position of the containing windows\n * and views.\n */\nfloat AMotionEvent_getYOffset(const AInputEvent* motion_event);\n\n/**\n * Get the precision of the X coordinates being reported.\n * You can multiply this number with an X coordinate sample to find the\n * actual hardware value of the X coordinate.\n */\nfloat AMotionEvent_getXPrecision(const AInputEvent* motion_event);\n\n/**\n * Get the precision of the Y coordinates being reported.\n * You can multiply this number with a Y coordinate sample to find the\n * actual hardware value of the Y coordinate.\n */\nfloat AMotionEvent_getYPrecision(const AInputEvent* motion_event);\n\n/**\n * Get the number of pointers of data contained in this event.\n * Always >= 1.\n */\nsize_t AMotionEvent_getPointerCount(const AInputEvent* motion_event);\n\n/**\n * Get the pointer identifier associated with a particular pointer\n * data index in this event.  The identifier tells you the actual pointer\n * number associated with the data, accounting for individual pointers\n * going up and down since the start of the current gesture.\n */\nint32_t AMotionEvent_getPointerId(const AInputEvent* motion_event, size_t pointer_index);\n\n/**\n * Get the tool type of a pointer for the given pointer index.\n * The tool type indicates the type of tool used to make contact such as a\n * finger or stylus, if known.\n */\nint32_t AMotionEvent_getToolType(const AInputEvent* motion_event, size_t pointer_index);\n\n/**\n * Get the original raw X coordinate of this event.\n * For touch events on the screen, this is the original location of the event\n * on the screen, before it had been adjusted for the containing window\n * and views.\n */\nfloat AMotionEvent_getRawX(const AInputEvent* motion_event, size_t pointer_index);\n\n/**\n * Get the original raw X coordinate of this event.\n * For touch events on the screen, this is the original location of the event\n * on the screen, before it had been adjusted for the containing window\n * and views.\n */\nfloat AMotionEvent_getRawY(const AInputEvent* motion_event, size_t pointer_index);\n\n/**\n * Get the current X coordinate of this event for the given pointer index.\n * Whole numbers are pixels; the value may have a fraction for input devices\n * that are sub-pixel precise.\n */\nfloat AMotionEvent_getX(const AInputEvent* motion_event, size_t pointer_index);\n\n/**\n * Get the current Y coordinate of this event for the given pointer index.\n * Whole numbers are pixels; the value may have a fraction for input devices\n * that are sub-pixel precise.\n */\nfloat AMotionEvent_getY(const AInputEvent* motion_event, size_t pointer_index);\n\n/**\n * Get the current pressure of this event for the given pointer index.\n * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),\n * although values higher than 1 may be generated depending on the calibration of\n * the input device.\n */\nfloat AMotionEvent_getPressure(const AInputEvent* motion_event, size_t pointer_index);\n\n/**\n * Get the current scaled value of the approximate size for the given pointer index.\n * This represents some approximation of the area of the screen being\n * pressed; the actual value in pixels corresponding to the\n * touch is normalized with the device specific range of values\n * and scaled to a value between 0 and 1.  The value of size can be used to\n * determine fat touch events.\n */\nfloat AMotionEvent_getSize(const AInputEvent* motion_event, size_t pointer_index);\n\n/**\n * Get the current length of the major axis of an ellipse that describes the touch area\n * at the point of contact for the given pointer index.\n */\nfloat AMotionEvent_getTouchMajor(const AInputEvent* motion_event, size_t pointer_index);\n\n/**\n * Get the current length of the minor axis of an ellipse that describes the touch area\n * at the point of contact for the given pointer index.\n */\nfloat AMotionEvent_getTouchMinor(const AInputEvent* motion_event, size_t pointer_index);\n\n/**\n * Get the current length of the major axis of an ellipse that describes the size\n * of the approaching tool for the given pointer index.\n * The tool area represents the estimated size of the finger or pen that is\n * touching the device independent of its actual touch area at the point of contact.\n */\nfloat AMotionEvent_getToolMajor(const AInputEvent* motion_event, size_t pointer_index);\n\n/**\n * Get the current length of the minor axis of an ellipse that describes the size\n * of the approaching tool for the given pointer index.\n * The tool area represents the estimated size of the finger or pen that is\n * touching the device independent of its actual touch area at the point of contact.\n */\nfloat AMotionEvent_getToolMinor(const AInputEvent* motion_event, size_t pointer_index);\n\n/**\n * Get the current orientation of the touch area and tool area in radians clockwise from\n * vertical for the given pointer index.\n * An angle of 0 degrees indicates that the major axis of contact is oriented\n * upwards, is perfectly circular or is of unknown orientation.  A positive angle\n * indicates that the major axis of contact is oriented to the right.  A negative angle\n * indicates that the major axis of contact is oriented to the left.\n * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians\n * (finger pointing fully right).\n */\nfloat AMotionEvent_getOrientation(const AInputEvent* motion_event, size_t pointer_index);\n\n/** Get the value of the request axis for the given pointer index. */\nfloat AMotionEvent_getAxisValue(const AInputEvent* motion_event,\n        int32_t axis, size_t pointer_index);\n\n/**\n * Get the number of historical points in this event.  These are movements that\n * have occurred between this event and the previous event.  This only applies\n * to AMOTION_EVENT_ACTION_MOVE events -- all other actions will have a size of 0.\n * Historical samples are indexed from oldest to newest.\n */\nsize_t AMotionEvent_getHistorySize(const AInputEvent* motion_event);\n\n/**\n * Get the time that a historical movement occurred between this event and\n * the previous event, in the java.lang.System.nanoTime() time base.\n */\nint64_t AMotionEvent_getHistoricalEventTime(const AInputEvent* motion_event,\n        size_t history_index);\n\n/**\n * Get the historical raw X coordinate of this event for the given pointer index that\n * occurred between this event and the previous motion event.\n * For touch events on the screen, this is the original location of the event\n * on the screen, before it had been adjusted for the containing window\n * and views.\n * Whole numbers are pixels; the value may have a fraction for input devices\n * that are sub-pixel precise.\n */\nfloat AMotionEvent_getHistoricalRawX(const AInputEvent* motion_event, size_t pointer_index,\n        size_t history_index);\n\n/**\n * Get the historical raw Y coordinate of this event for the given pointer index that\n * occurred between this event and the previous motion event.\n * For touch events on the screen, this is the original location of the event\n * on the screen, before it had been adjusted for the containing window\n * and views.\n * Whole numbers are pixels; the value may have a fraction for input devices\n * that are sub-pixel precise.\n */\nfloat AMotionEvent_getHistoricalRawY(const AInputEvent* motion_event, size_t pointer_index,\n        size_t history_index);\n\n/**\n * Get the historical X coordinate of this event for the given pointer index that\n * occurred between this event and the previous motion event.\n * Whole numbers are pixels; the value may have a fraction for input devices\n * that are sub-pixel precise.\n */\nfloat AMotionEvent_getHistoricalX(const AInputEvent* motion_event, size_t pointer_index,\n        size_t history_index);\n\n/**\n * Get the historical Y coordinate of this event for the given pointer index that\n * occurred between this event and the previous motion event.\n * Whole numbers are pixels; the value may have a fraction for input devices\n * that are sub-pixel precise.\n */\nfloat AMotionEvent_getHistoricalY(const AInputEvent* motion_event, size_t pointer_index,\n        size_t history_index);\n\n/**\n * Get the historical pressure of this event for the given pointer index that\n * occurred between this event and the previous motion event.\n * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),\n * although values higher than 1 may be generated depending on the calibration of\n * the input device.\n */\nfloat AMotionEvent_getHistoricalPressure(const AInputEvent* motion_event, size_t pointer_index,\n        size_t history_index);\n\n/**\n * Get the current scaled value of the approximate size for the given pointer index that\n * occurred between this event and the previous motion event.\n * This represents some approximation of the area of the screen being\n * pressed; the actual value in pixels corresponding to the\n * touch is normalized with the device specific range of values\n * and scaled to a value between 0 and 1.  The value of size can be used to\n * determine fat touch events.\n */\nfloat AMotionEvent_getHistoricalSize(const AInputEvent* motion_event, size_t pointer_index,\n        size_t history_index);\n\n/**\n * Get the historical length of the major axis of an ellipse that describes the touch area\n * at the point of contact for the given pointer index that\n * occurred between this event and the previous motion event.\n */\nfloat AMotionEvent_getHistoricalTouchMajor(const AInputEvent* motion_event, size_t pointer_index,\n        size_t history_index);\n\n/**\n * Get the historical length of the minor axis of an ellipse that describes the touch area\n * at the point of contact for the given pointer index that\n * occurred between this event and the previous motion event.\n */\nfloat AMotionEvent_getHistoricalTouchMinor(const AInputEvent* motion_event, size_t pointer_index,\n        size_t history_index);\n\n/**\n * Get the historical length of the major axis of an ellipse that describes the size\n * of the approaching tool for the given pointer index that\n * occurred between this event and the previous motion event.\n * The tool area represents the estimated size of the finger or pen that is\n * touching the device independent of its actual touch area at the point of contact.\n */\nfloat AMotionEvent_getHistoricalToolMajor(const AInputEvent* motion_event, size_t pointer_index,\n        size_t history_index);\n\n/**\n * Get the historical length of the minor axis of an ellipse that describes the size\n * of the approaching tool for the given pointer index that\n * occurred between this event and the previous motion event.\n * The tool area represents the estimated size of the finger or pen that is\n * touching the device independent of its actual touch area at the point of contact.\n */\nfloat AMotionEvent_getHistoricalToolMinor(const AInputEvent* motion_event, size_t pointer_index,\n        size_t history_index);\n\n/**\n * Get the historical orientation of the touch area and tool area in radians clockwise from\n * vertical for the given pointer index that\n * occurred between this event and the previous motion event.\n * An angle of 0 degrees indicates that the major axis of contact is oriented\n * upwards, is perfectly circular or is of unknown orientation.  A positive angle\n * indicates that the major axis of contact is oriented to the right.  A negative angle\n * indicates that the major axis of contact is oriented to the left.\n * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians\n * (finger pointing fully right).\n */\nfloat AMotionEvent_getHistoricalOrientation(const AInputEvent* motion_event, size_t pointer_index,\n        size_t history_index);\n\n/**\n * Get the historical value of the request axis for the given pointer index\n * that occurred between this event and the previous motion event.\n */\nfloat AMotionEvent_getHistoricalAxisValue(const AInputEvent* motion_event,\n        int32_t axis, size_t pointer_index, size_t history_index);\n\n\nstruct AInputQueue;\n/**\n * Input queue\n *\n * An input queue is the facility through which you retrieve input\n * events.\n */\ntypedef struct AInputQueue AInputQueue;\n\n/**\n * Add this input queue to a looper for processing.  See\n * ALooper_addFd() for information on the ident, callback, and data params.\n */\nvoid AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper,\n        int ident, ALooper_callbackFunc callback, void* data);\n\n/**\n * Remove the input queue from the looper it is currently attached to.\n */\nvoid AInputQueue_detachLooper(AInputQueue* queue);\n\n/**\n * Returns true if there are one or more events available in the\n * input queue.  Returns 1 if the queue has events; 0 if\n * it does not have events; and a negative value if there is an error.\n */\nint32_t AInputQueue_hasEvents(AInputQueue* queue);\n\n/**\n * Returns the next available event from the queue.  Returns a negative\n * value if no events are available or an error has occurred.\n */\nint32_t AInputQueue_getEvent(AInputQueue* queue, AInputEvent** outEvent);\n\n/**\n * Sends the key for standard pre-dispatching -- that is, possibly deliver\n * it to the current IME to be consumed before the app.  Returns 0 if it\n * was not pre-dispatched, meaning you can process it right now.  If non-zero\n * is returned, you must abandon the current event processing and allow the\n * event to appear again in the event queue (if it does not get consumed during\n * pre-dispatching).\n */\nint32_t AInputQueue_preDispatchEvent(AInputQueue* queue, AInputEvent* event);\n\n/**\n * Report that dispatching has finished with the given event.\n * This must be called after receiving an event with AInputQueue_get_event().\n */\nvoid AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // _ANDROID_INPUT_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/keycodes.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup Input\n * @{\n */\n\n/**\n * @file keycodes.h\n */\n\n#ifndef _ANDROID_KEYCODES_H\n#define _ANDROID_KEYCODES_H\n\n/******************************************************************\n *\n * IMPORTANT NOTICE:\n *\n *   This file is part of Android's set of stable system headers\n *   exposed by the Android NDK (Native Development Kit).\n *\n *   Third-party source AND binary code relies on the definitions\n *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.\n *\n *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)\n *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS\n *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY\n *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES\n */\n\n#include <sys/types.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Key codes.\n */\nenum {\n    /** Unknown key code. */\n    AKEYCODE_UNKNOWN         = 0,\n    /** Soft Left key.\n     * Usually situated below the display on phones and used as a multi-function\n     * feature key for selecting a software defined function shown on the bottom left\n     * of the display. */\n    AKEYCODE_SOFT_LEFT       = 1,\n    /** Soft Right key.\n     * Usually situated below the display on phones and used as a multi-function\n     * feature key for selecting a software defined function shown on the bottom right\n     * of the display. */\n    AKEYCODE_SOFT_RIGHT      = 2,\n    /** Home key.\n     * This key is handled by the framework and is never delivered to applications. */\n    AKEYCODE_HOME            = 3,\n    /** Back key. */\n    AKEYCODE_BACK            = 4,\n    /** Call key. */\n    AKEYCODE_CALL            = 5,\n    /** End Call key. */\n    AKEYCODE_ENDCALL         = 6,\n    /** '0' key. */\n    AKEYCODE_0               = 7,\n    /** '1' key. */\n    AKEYCODE_1               = 8,\n    /** '2' key. */\n    AKEYCODE_2               = 9,\n    /** '3' key. */\n    AKEYCODE_3               = 10,\n    /** '4' key. */\n    AKEYCODE_4               = 11,\n    /** '5' key. */\n    AKEYCODE_5               = 12,\n    /** '6' key. */\n    AKEYCODE_6               = 13,\n    /** '7' key. */\n    AKEYCODE_7               = 14,\n    /** '8' key. */\n    AKEYCODE_8               = 15,\n    /** '9' key. */\n    AKEYCODE_9               = 16,\n    /** '*' key. */\n    AKEYCODE_STAR            = 17,\n    /** '#' key. */\n    AKEYCODE_POUND           = 18,\n    /** Directional Pad Up key.\n     * May also be synthesized from trackball motions. */\n    AKEYCODE_DPAD_UP         = 19,\n    /** Directional Pad Down key.\n     * May also be synthesized from trackball motions. */\n    AKEYCODE_DPAD_DOWN       = 20,\n    /** Directional Pad Left key.\n     * May also be synthesized from trackball motions. */\n    AKEYCODE_DPAD_LEFT       = 21,\n    /** Directional Pad Right key.\n     * May also be synthesized from trackball motions. */\n    AKEYCODE_DPAD_RIGHT      = 22,\n    /** Directional Pad Center key.\n     * May also be synthesized from trackball motions. */\n    AKEYCODE_DPAD_CENTER     = 23,\n    /** Volume Up key.\n     * Adjusts the speaker volume up. */\n    AKEYCODE_VOLUME_UP       = 24,\n    /** Volume Down key.\n     * Adjusts the speaker volume down. */\n    AKEYCODE_VOLUME_DOWN     = 25,\n    /** Power key. */\n    AKEYCODE_POWER           = 26,\n    /** Camera key.\n     * Used to launch a camera application or take pictures. */\n    AKEYCODE_CAMERA          = 27,\n    /** Clear key. */\n    AKEYCODE_CLEAR           = 28,\n    /** 'A' key. */\n    AKEYCODE_A               = 29,\n    /** 'B' key. */\n    AKEYCODE_B               = 30,\n    /** 'C' key. */\n    AKEYCODE_C               = 31,\n    /** 'D' key. */\n    AKEYCODE_D               = 32,\n    /** 'E' key. */\n    AKEYCODE_E               = 33,\n    /** 'F' key. */\n    AKEYCODE_F               = 34,\n    /** 'G' key. */\n    AKEYCODE_G               = 35,\n    /** 'H' key. */\n    AKEYCODE_H               = 36,\n    /** 'I' key. */\n    AKEYCODE_I               = 37,\n    /** 'J' key. */\n    AKEYCODE_J               = 38,\n    /** 'K' key. */\n    AKEYCODE_K               = 39,\n    /** 'L' key. */\n    AKEYCODE_L               = 40,\n    /** 'M' key. */\n    AKEYCODE_M               = 41,\n    /** 'N' key. */\n    AKEYCODE_N               = 42,\n    /** 'O' key. */\n    AKEYCODE_O               = 43,\n    /** 'P' key. */\n    AKEYCODE_P               = 44,\n    /** 'Q' key. */\n    AKEYCODE_Q               = 45,\n    /** 'R' key. */\n    AKEYCODE_R               = 46,\n    /** 'S' key. */\n    AKEYCODE_S               = 47,\n    /** 'T' key. */\n    AKEYCODE_T               = 48,\n    /** 'U' key. */\n    AKEYCODE_U               = 49,\n    /** 'V' key. */\n    AKEYCODE_V               = 50,\n    /** 'W' key. */\n    AKEYCODE_W               = 51,\n    /** 'X' key. */\n    AKEYCODE_X               = 52,\n    /** 'Y' key. */\n    AKEYCODE_Y               = 53,\n    /** 'Z' key. */\n    AKEYCODE_Z               = 54,\n    /** ',' key. */\n    AKEYCODE_COMMA           = 55,\n    /** '.' key. */\n    AKEYCODE_PERIOD          = 56,\n    /** Left Alt modifier key. */\n    AKEYCODE_ALT_LEFT        = 57,\n    /** Right Alt modifier key. */\n    AKEYCODE_ALT_RIGHT       = 58,\n    /** Left Shift modifier key. */\n    AKEYCODE_SHIFT_LEFT      = 59,\n    /** Right Shift modifier key. */\n    AKEYCODE_SHIFT_RIGHT     = 60,\n    /** Tab key. */\n    AKEYCODE_TAB             = 61,\n    /** Space key. */\n    AKEYCODE_SPACE           = 62,\n    /** Symbol modifier key.\n     * Used to enter alternate symbols. */\n    AKEYCODE_SYM             = 63,\n    /** Explorer special function key.\n     * Used to launch a browser application. */\n    AKEYCODE_EXPLORER        = 64,\n    /** Envelope special function key.\n     * Used to launch a mail application. */\n    AKEYCODE_ENVELOPE        = 65,\n    /** Enter key. */\n    AKEYCODE_ENTER           = 66,\n    /** Backspace key.\n     * Deletes characters before the insertion point, unlike {@link AKEYCODE_FORWARD_DEL}. */\n    AKEYCODE_DEL             = 67,\n    /** '`' (backtick) key. */\n    AKEYCODE_GRAVE           = 68,\n    /** '-'. */\n    AKEYCODE_MINUS           = 69,\n    /** '=' key. */\n    AKEYCODE_EQUALS          = 70,\n    /** '[' key. */\n    AKEYCODE_LEFT_BRACKET    = 71,\n    /** ']' key. */\n    AKEYCODE_RIGHT_BRACKET   = 72,\n    /** '\\' key. */\n    AKEYCODE_BACKSLASH       = 73,\n    /** ';' key. */\n    AKEYCODE_SEMICOLON       = 74,\n    /** ''' (apostrophe) key. */\n    AKEYCODE_APOSTROPHE      = 75,\n    /** '/' key. */\n    AKEYCODE_SLASH           = 76,\n    /** '@' key. */\n    AKEYCODE_AT              = 77,\n    /** Number modifier key.\n     * Used to enter numeric symbols.\n     * This key is not {@link AKEYCODE_NUM_LOCK}; it is more like {@link AKEYCODE_ALT_LEFT}. */\n    AKEYCODE_NUM             = 78,\n    /** Headset Hook key.\n     * Used to hang up calls and stop media. */\n    AKEYCODE_HEADSETHOOK     = 79,\n    /** Camera Focus key.\n     * Used to focus the camera. */\n    AKEYCODE_FOCUS           = 80,\n    /** '+' key. */\n    AKEYCODE_PLUS            = 81,\n    /** Menu key. */\n    AKEYCODE_MENU            = 82,\n    /** Notification key. */\n    AKEYCODE_NOTIFICATION    = 83,\n    /** Search key. */\n    AKEYCODE_SEARCH          = 84,\n    /** Play/Pause media key. */\n    AKEYCODE_MEDIA_PLAY_PAUSE= 85,\n    /** Stop media key. */\n    AKEYCODE_MEDIA_STOP      = 86,\n    /** Play Next media key. */\n    AKEYCODE_MEDIA_NEXT      = 87,\n    /** Play Previous media key. */\n    AKEYCODE_MEDIA_PREVIOUS  = 88,\n    /** Rewind media key. */\n    AKEYCODE_MEDIA_REWIND    = 89,\n    /** Fast Forward media key. */\n    AKEYCODE_MEDIA_FAST_FORWARD = 90,\n    /** Mute key.\n     * Mutes the microphone, unlike {@link AKEYCODE_VOLUME_MUTE}. */\n    AKEYCODE_MUTE            = 91,\n    /** Page Up key. */\n    AKEYCODE_PAGE_UP         = 92,\n    /** Page Down key. */\n    AKEYCODE_PAGE_DOWN       = 93,\n    /** Picture Symbols modifier key.\n     * Used to switch symbol sets (Emoji, Kao-moji). */\n    AKEYCODE_PICTSYMBOLS     = 94,\n    /** Switch Charset modifier key.\n     * Used to switch character sets (Kanji, Katakana). */\n    AKEYCODE_SWITCH_CHARSET  = 95,\n    /** A Button key.\n     * On a game controller, the A button should be either the button labeled A\n     * or the first button on the bottom row of controller buttons. */\n    AKEYCODE_BUTTON_A        = 96,\n    /** B Button key.\n     * On a game controller, the B button should be either the button labeled B\n     * or the second button on the bottom row of controller buttons. */\n    AKEYCODE_BUTTON_B        = 97,\n    /** C Button key.\n     * On a game controller, the C button should be either the button labeled C\n     * or the third button on the bottom row of controller buttons. */\n    AKEYCODE_BUTTON_C        = 98,\n    /** X Button key.\n     * On a game controller, the X button should be either the button labeled X\n     * or the first button on the upper row of controller buttons. */\n    AKEYCODE_BUTTON_X        = 99,\n    /** Y Button key.\n     * On a game controller, the Y button should be either the button labeled Y\n     * or the second button on the upper row of controller buttons. */\n    AKEYCODE_BUTTON_Y        = 100,\n    /** Z Button key.\n     * On a game controller, the Z button should be either the button labeled Z\n     * or the third button on the upper row of controller buttons. */\n    AKEYCODE_BUTTON_Z        = 101,\n    /** L1 Button key.\n     * On a game controller, the L1 button should be either the button labeled L1 (or L)\n     * or the top left trigger button. */\n    AKEYCODE_BUTTON_L1       = 102,\n    /** R1 Button key.\n     * On a game controller, the R1 button should be either the button labeled R1 (or R)\n     * or the top right trigger button. */\n    AKEYCODE_BUTTON_R1       = 103,\n    /** L2 Button key.\n     * On a game controller, the L2 button should be either the button labeled L2\n     * or the bottom left trigger button. */\n    AKEYCODE_BUTTON_L2       = 104,\n    /** R2 Button key.\n     * On a game controller, the R2 button should be either the button labeled R2\n     * or the bottom right trigger button. */\n    AKEYCODE_BUTTON_R2       = 105,\n    /** Left Thumb Button key.\n     * On a game controller, the left thumb button indicates that the left (or only)\n     * joystick is pressed. */\n    AKEYCODE_BUTTON_THUMBL   = 106,\n    /** Right Thumb Button key.\n     * On a game controller, the right thumb button indicates that the right\n     * joystick is pressed. */\n    AKEYCODE_BUTTON_THUMBR   = 107,\n    /** Start Button key.\n     * On a game controller, the button labeled Start. */\n    AKEYCODE_BUTTON_START    = 108,\n    /** Select Button key.\n     * On a game controller, the button labeled Select. */\n    AKEYCODE_BUTTON_SELECT   = 109,\n    /** Mode Button key.\n     * On a game controller, the button labeled Mode. */\n    AKEYCODE_BUTTON_MODE     = 110,\n    /** Escape key. */\n    AKEYCODE_ESCAPE          = 111,\n    /** Forward Delete key.\n     * Deletes characters ahead of the insertion point, unlike {@link AKEYCODE_DEL}. */\n    AKEYCODE_FORWARD_DEL     = 112,\n    /** Left Control modifier key. */\n    AKEYCODE_CTRL_LEFT       = 113,\n    /** Right Control modifier key. */\n    AKEYCODE_CTRL_RIGHT      = 114,\n    /** Caps Lock key. */\n    AKEYCODE_CAPS_LOCK       = 115,\n    /** Scroll Lock key. */\n    AKEYCODE_SCROLL_LOCK     = 116,\n    /** Left Meta modifier key. */\n    AKEYCODE_META_LEFT       = 117,\n    /** Right Meta modifier key. */\n    AKEYCODE_META_RIGHT      = 118,\n    /** Function modifier key. */\n    AKEYCODE_FUNCTION        = 119,\n    /** System Request / Print Screen key. */\n    AKEYCODE_SYSRQ           = 120,\n    /** Break / Pause key. */\n    AKEYCODE_BREAK           = 121,\n    /** Home Movement key.\n     * Used for scrolling or moving the cursor around to the start of a line\n     * or to the top of a list. */\n    AKEYCODE_MOVE_HOME       = 122,\n    /** End Movement key.\n     * Used for scrolling or moving the cursor around to the end of a line\n     * or to the bottom of a list. */\n    AKEYCODE_MOVE_END        = 123,\n    /** Insert key.\n     * Toggles insert / overwrite edit mode. */\n    AKEYCODE_INSERT          = 124,\n    /** Forward key.\n     * Navigates forward in the history stack.  Complement of {@link AKEYCODE_BACK}. */\n    AKEYCODE_FORWARD         = 125,\n    /** Play media key. */\n    AKEYCODE_MEDIA_PLAY      = 126,\n    /** Pause media key. */\n    AKEYCODE_MEDIA_PAUSE     = 127,\n    /** Close media key.\n     * May be used to close a CD tray, for example. */\n    AKEYCODE_MEDIA_CLOSE     = 128,\n    /** Eject media key.\n     * May be used to eject a CD tray, for example. */\n    AKEYCODE_MEDIA_EJECT     = 129,\n    /** Record media key. */\n    AKEYCODE_MEDIA_RECORD    = 130,\n    /** F1 key. */\n    AKEYCODE_F1              = 131,\n    /** F2 key. */\n    AKEYCODE_F2              = 132,\n    /** F3 key. */\n    AKEYCODE_F3              = 133,\n    /** F4 key. */\n    AKEYCODE_F4              = 134,\n    /** F5 key. */\n    AKEYCODE_F5              = 135,\n    /** F6 key. */\n    AKEYCODE_F6              = 136,\n    /** F7 key. */\n    AKEYCODE_F7              = 137,\n    /** F8 key. */\n    AKEYCODE_F8              = 138,\n    /** F9 key. */\n    AKEYCODE_F9              = 139,\n    /** F10 key. */\n    AKEYCODE_F10             = 140,\n    /** F11 key. */\n    AKEYCODE_F11             = 141,\n    /** F12 key. */\n    AKEYCODE_F12             = 142,\n    /** Num Lock key.\n     * This is the Num Lock key; it is different from {@link AKEYCODE_NUM}.\n     * This key alters the behavior of other keys on the numeric keypad. */\n    AKEYCODE_NUM_LOCK        = 143,\n    /** Numeric keypad '0' key. */\n    AKEYCODE_NUMPAD_0        = 144,\n    /** Numeric keypad '1' key. */\n    AKEYCODE_NUMPAD_1        = 145,\n    /** Numeric keypad '2' key. */\n    AKEYCODE_NUMPAD_2        = 146,\n    /** Numeric keypad '3' key. */\n    AKEYCODE_NUMPAD_3        = 147,\n    /** Numeric keypad '4' key. */\n    AKEYCODE_NUMPAD_4        = 148,\n    /** Numeric keypad '5' key. */\n    AKEYCODE_NUMPAD_5        = 149,\n    /** Numeric keypad '6' key. */\n    AKEYCODE_NUMPAD_6        = 150,\n    /** Numeric keypad '7' key. */\n    AKEYCODE_NUMPAD_7        = 151,\n    /** Numeric keypad '8' key. */\n    AKEYCODE_NUMPAD_8        = 152,\n    /** Numeric keypad '9' key. */\n    AKEYCODE_NUMPAD_9        = 153,\n    /** Numeric keypad '/' key (for division). */\n    AKEYCODE_NUMPAD_DIVIDE   = 154,\n    /** Numeric keypad '*' key (for multiplication). */\n    AKEYCODE_NUMPAD_MULTIPLY = 155,\n    /** Numeric keypad '-' key (for subtraction). */\n    AKEYCODE_NUMPAD_SUBTRACT = 156,\n    /** Numeric keypad '+' key (for addition). */\n    AKEYCODE_NUMPAD_ADD      = 157,\n    /** Numeric keypad '.' key (for decimals or digit grouping). */\n    AKEYCODE_NUMPAD_DOT      = 158,\n    /** Numeric keypad ',' key (for decimals or digit grouping). */\n    AKEYCODE_NUMPAD_COMMA    = 159,\n    /** Numeric keypad Enter key. */\n    AKEYCODE_NUMPAD_ENTER    = 160,\n    /** Numeric keypad '=' key. */\n    AKEYCODE_NUMPAD_EQUALS   = 161,\n    /** Numeric keypad '(' key. */\n    AKEYCODE_NUMPAD_LEFT_PAREN = 162,\n    /** Numeric keypad ')' key. */\n    AKEYCODE_NUMPAD_RIGHT_PAREN = 163,\n    /** Volume Mute key.\n     * Mutes the speaker, unlike {@link AKEYCODE_MUTE}.\n     * This key should normally be implemented as a toggle such that the first press\n     * mutes the speaker and the second press restores the original volume. */\n    AKEYCODE_VOLUME_MUTE     = 164,\n    /** Info key.\n     * Common on TV remotes to show additional information related to what is\n     * currently being viewed. */\n    AKEYCODE_INFO            = 165,\n    /** Channel up key.\n     * On TV remotes, increments the television channel. */\n    AKEYCODE_CHANNEL_UP      = 166,\n    /** Channel down key.\n     * On TV remotes, decrements the television channel. */\n    AKEYCODE_CHANNEL_DOWN    = 167,\n    /** Zoom in key. */\n    AKEYCODE_ZOOM_IN         = 168,\n    /** Zoom out key. */\n    AKEYCODE_ZOOM_OUT        = 169,\n    /** TV key.\n     * On TV remotes, switches to viewing live TV. */\n    AKEYCODE_TV              = 170,\n    /** Window key.\n     * On TV remotes, toggles picture-in-picture mode or other windowing functions. */\n    AKEYCODE_WINDOW          = 171,\n    /** Guide key.\n     * On TV remotes, shows a programming guide. */\n    AKEYCODE_GUIDE           = 172,\n    /** DVR key.\n     * On some TV remotes, switches to a DVR mode for recorded shows. */\n    AKEYCODE_DVR             = 173,\n    /** Bookmark key.\n     * On some TV remotes, bookmarks content or web pages. */\n    AKEYCODE_BOOKMARK        = 174,\n    /** Toggle captions key.\n     * Switches the mode for closed-captioning text, for example during television shows. */\n    AKEYCODE_CAPTIONS        = 175,\n    /** Settings key.\n     * Starts the system settings activity. */\n    AKEYCODE_SETTINGS        = 176,\n    /** TV power key.\n     * On TV remotes, toggles the power on a television screen. */\n    AKEYCODE_TV_POWER        = 177,\n    /** TV input key.\n     * On TV remotes, switches the input on a television screen. */\n    AKEYCODE_TV_INPUT        = 178,\n    /** Set-top-box power key.\n     * On TV remotes, toggles the power on an external Set-top-box. */\n    AKEYCODE_STB_POWER       = 179,\n    /** Set-top-box input key.\n     * On TV remotes, switches the input mode on an external Set-top-box. */\n    AKEYCODE_STB_INPUT       = 180,\n    /** A/V Receiver power key.\n     * On TV remotes, toggles the power on an external A/V Receiver. */\n    AKEYCODE_AVR_POWER       = 181,\n    /** A/V Receiver input key.\n     * On TV remotes, switches the input mode on an external A/V Receiver. */\n    AKEYCODE_AVR_INPUT       = 182,\n    /** Red \"programmable\" key.\n     * On TV remotes, acts as a contextual/programmable key. */\n    AKEYCODE_PROG_RED        = 183,\n    /** Green \"programmable\" key.\n     * On TV remotes, actsas a contextual/programmable key. */\n    AKEYCODE_PROG_GREEN      = 184,\n    /** Yellow \"programmable\" key.\n     * On TV remotes, acts as a contextual/programmable key. */\n    AKEYCODE_PROG_YELLOW     = 185,\n    /** Blue \"programmable\" key.\n     * On TV remotes, acts as a contextual/programmable key. */\n    AKEYCODE_PROG_BLUE       = 186,\n    /** App switch key.\n     * Should bring up the application switcher dialog. */\n    AKEYCODE_APP_SWITCH      = 187,\n    /** Generic Game Pad Button #1.*/\n    AKEYCODE_BUTTON_1        = 188,\n    /** Generic Game Pad Button #2.*/\n    AKEYCODE_BUTTON_2        = 189,\n    /** Generic Game Pad Button #3.*/\n    AKEYCODE_BUTTON_3        = 190,\n    /** Generic Game Pad Button #4.*/\n    AKEYCODE_BUTTON_4        = 191,\n    /** Generic Game Pad Button #5.*/\n    AKEYCODE_BUTTON_5        = 192,\n    /** Generic Game Pad Button #6.*/\n    AKEYCODE_BUTTON_6        = 193,\n    /** Generic Game Pad Button #7.*/\n    AKEYCODE_BUTTON_7        = 194,\n    /** Generic Game Pad Button #8.*/\n    AKEYCODE_BUTTON_8        = 195,\n    /** Generic Game Pad Button #9.*/\n    AKEYCODE_BUTTON_9        = 196,\n    /** Generic Game Pad Button #10.*/\n    AKEYCODE_BUTTON_10       = 197,\n    /** Generic Game Pad Button #11.*/\n    AKEYCODE_BUTTON_11       = 198,\n    /** Generic Game Pad Button #12.*/\n    AKEYCODE_BUTTON_12       = 199,\n    /** Generic Game Pad Button #13.*/\n    AKEYCODE_BUTTON_13       = 200,\n    /** Generic Game Pad Button #14.*/\n    AKEYCODE_BUTTON_14       = 201,\n    /** Generic Game Pad Button #15.*/\n    AKEYCODE_BUTTON_15       = 202,\n    /** Generic Game Pad Button #16.*/\n    AKEYCODE_BUTTON_16       = 203,\n    /** Language Switch key.\n     * Toggles the current input language such as switching between English and Japanese on\n     * a QWERTY keyboard.  On some devices, the same function may be performed by\n     * pressing Shift+Spacebar. */\n    AKEYCODE_LANGUAGE_SWITCH = 204,\n    /** Manner Mode key.\n     * Toggles silent or vibrate mode on and off to make the device behave more politely\n     * in certain settings such as on a crowded train.  On some devices, the key may only\n     * operate when long-pressed. */\n    AKEYCODE_MANNER_MODE     = 205,\n    /** 3D Mode key.\n     * Toggles the display between 2D and 3D mode. */\n    AKEYCODE_3D_MODE         = 206,\n    /** Contacts special function key.\n     * Used to launch an address book application. */\n    AKEYCODE_CONTACTS        = 207,\n    /** Calendar special function key.\n     * Used to launch a calendar application. */\n    AKEYCODE_CALENDAR        = 208,\n    /** Music special function key.\n     * Used to launch a music player application. */\n    AKEYCODE_MUSIC           = 209,\n    /** Calculator special function key.\n     * Used to launch a calculator application. */\n    AKEYCODE_CALCULATOR      = 210,\n    /** Japanese full-width / half-width key. */\n    AKEYCODE_ZENKAKU_HANKAKU = 211,\n    /** Japanese alphanumeric key. */\n    AKEYCODE_EISU            = 212,\n    /** Japanese non-conversion key. */\n    AKEYCODE_MUHENKAN        = 213,\n    /** Japanese conversion key. */\n    AKEYCODE_HENKAN          = 214,\n    /** Japanese katakana / hiragana key. */\n    AKEYCODE_KATAKANA_HIRAGANA = 215,\n    /** Japanese Yen key. */\n    AKEYCODE_YEN             = 216,\n    /** Japanese Ro key. */\n    AKEYCODE_RO              = 217,\n    /** Japanese kana key. */\n    AKEYCODE_KANA            = 218,\n    /** Assist key.\n     * Launches the global assist activity.  Not delivered to applications. */\n    AKEYCODE_ASSIST          = 219,\n    /** Brightness Down key.\n     * Adjusts the screen brightness down. */\n    AKEYCODE_BRIGHTNESS_DOWN = 220,\n    /** Brightness Up key.\n     * Adjusts the screen brightness up. */\n    AKEYCODE_BRIGHTNESS_UP   = 221,\n    /** Audio Track key.\n     * Switches the audio tracks. */\n    AKEYCODE_MEDIA_AUDIO_TRACK = 222,\n    /** Sleep key.\n     * Puts the device to sleep.  Behaves somewhat like {@link AKEYCODE_POWER} but it\n     * has no effect if the device is already asleep. */\n    AKEYCODE_SLEEP           = 223,\n    /** Wakeup key.\n     * Wakes up the device.  Behaves somewhat like {@link AKEYCODE_POWER} but it\n     * has no effect if the device is already awake. */\n    AKEYCODE_WAKEUP          = 224,\n    /** Pairing key.\n     * Initiates peripheral pairing mode. Useful for pairing remote control\n     * devices or game controllers, especially if no other input mode is\n     * available. */\n    AKEYCODE_PAIRING         = 225,\n    /** Media Top Menu key.\n     * Goes to the top of media menu. */\n    AKEYCODE_MEDIA_TOP_MENU  = 226,\n    /** '11' key. */\n    AKEYCODE_11              = 227,\n    /** '12' key. */\n    AKEYCODE_12              = 228,\n    /** Last Channel key.\n     * Goes to the last viewed channel. */\n    AKEYCODE_LAST_CHANNEL    = 229,\n    /** TV data service key.\n     * Displays data services like weather, sports. */\n    AKEYCODE_TV_DATA_SERVICE = 230,\n    /** Voice Assist key.\n     * Launches the global voice assist activity. Not delivered to applications. */\n    AKEYCODE_VOICE_ASSIST    = 231,\n    /** Radio key.\n     * Toggles TV service / Radio service. */\n    AKEYCODE_TV_RADIO_SERVICE = 232,\n    /** Teletext key.\n     * Displays Teletext service. */\n    AKEYCODE_TV_TELETEXT     = 233,\n    /** Number entry key.\n     * Initiates to enter multi-digit channel nubmber when each digit key is assigned\n     * for selecting separate channel. Corresponds to Number Entry Mode (0x1D) of CEC\n     * User Control Code. */\n    AKEYCODE_TV_NUMBER_ENTRY = 234,\n    /** Analog Terrestrial key.\n     * Switches to analog terrestrial broadcast service. */\n    AKEYCODE_TV_TERRESTRIAL_ANALOG = 235,\n    /** Digital Terrestrial key.\n     * Switches to digital terrestrial broadcast service. */\n    AKEYCODE_TV_TERRESTRIAL_DIGITAL = 236,\n    /** Satellite key.\n     * Switches to digital satellite broadcast service. */\n    AKEYCODE_TV_SATELLITE    = 237,\n    /** BS key.\n     * Switches to BS digital satellite broadcasting service available in Japan. */\n    AKEYCODE_TV_SATELLITE_BS = 238,\n    /** CS key.\n     * Switches to CS digital satellite broadcasting service available in Japan. */\n    AKEYCODE_TV_SATELLITE_CS = 239,\n    /** BS/CS key.\n     * Toggles between BS and CS digital satellite services. */\n    AKEYCODE_TV_SATELLITE_SERVICE = 240,\n    /** Toggle Network key.\n     * Toggles selecting broacast services. */\n    AKEYCODE_TV_NETWORK      = 241,\n    /** Antenna/Cable key.\n     * Toggles broadcast input source between antenna and cable. */\n    AKEYCODE_TV_ANTENNA_CABLE = 242,\n    /** HDMI #1 key.\n     * Switches to HDMI input #1. */\n    AKEYCODE_TV_INPUT_HDMI_1 = 243,\n    /** HDMI #2 key.\n     * Switches to HDMI input #2. */\n    AKEYCODE_TV_INPUT_HDMI_2 = 244,\n    /** HDMI #3 key.\n     * Switches to HDMI input #3. */\n    AKEYCODE_TV_INPUT_HDMI_3 = 245,\n    /** HDMI #4 key.\n     * Switches to HDMI input #4. */\n    AKEYCODE_TV_INPUT_HDMI_4 = 246,\n    /** Composite #1 key.\n     * Switches to composite video input #1. */\n    AKEYCODE_TV_INPUT_COMPOSITE_1 = 247,\n    /** Composite #2 key.\n     * Switches to composite video input #2. */\n    AKEYCODE_TV_INPUT_COMPOSITE_2 = 248,\n    /** Component #1 key.\n     * Switches to component video input #1. */\n    AKEYCODE_TV_INPUT_COMPONENT_1 = 249,\n    /** Component #2 key.\n     * Switches to component video input #2. */\n    AKEYCODE_TV_INPUT_COMPONENT_2 = 250,\n    /** VGA #1 key.\n     * Switches to VGA (analog RGB) input #1. */\n    AKEYCODE_TV_INPUT_VGA_1  = 251,\n    /** Audio description key.\n     * Toggles audio description off / on. */\n    AKEYCODE_TV_AUDIO_DESCRIPTION = 252,\n    /** Audio description mixing volume up key.\n     * Louden audio description volume as compared with normal audio volume. */\n    AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP = 253,\n    /** Audio description mixing volume down key.\n     * Lessen audio description volume as compared with normal audio volume. */\n    AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN = 254,\n    /** Zoom mode key.\n     * Changes Zoom mode (Normal, Full, Zoom, Wide-zoom, etc.) */\n    AKEYCODE_TV_ZOOM_MODE    = 255,\n    /** Contents menu key.\n     * Goes to the title list. Corresponds to Contents Menu (0x0B) of CEC User Control\n     * Code */\n    AKEYCODE_TV_CONTENTS_MENU = 256,\n    /** Media context menu key.\n     * Goes to the context menu of media contents. Corresponds to Media Context-sensitive\n     * Menu (0x11) of CEC User Control Code. */\n    AKEYCODE_TV_MEDIA_CONTEXT_MENU = 257,\n    /** Timer programming key.\n     * Goes to the timer recording menu. Corresponds to Timer Programming (0x54) of\n     * CEC User Control Code. */\n    AKEYCODE_TV_TIMER_PROGRAMMING = 258,\n    /** Help key. */\n    AKEYCODE_HELP            = 259,\n    AKEYCODE_NAVIGATE_PREVIOUS = 260,\n    AKEYCODE_NAVIGATE_NEXT   = 261,\n    AKEYCODE_NAVIGATE_IN     = 262,\n    AKEYCODE_NAVIGATE_OUT    = 263,\n    /** Primary stem key for Wear\n     * Main power/reset button on watch. */\n    AKEYCODE_STEM_PRIMARY = 264,\n    /** Generic stem key 1 for Wear */\n    AKEYCODE_STEM_1 = 265,\n    /** Generic stem key 2 for Wear */\n    AKEYCODE_STEM_2 = 266,\n    /** Generic stem key 3 for Wear */\n    AKEYCODE_STEM_3 = 267,\n    /** Directional Pad Up-Left */\n    AKEYCODE_DPAD_UP_LEFT    = 268,\n    /** Directional Pad Down-Left */\n    AKEYCODE_DPAD_DOWN_LEFT  = 269,\n    /** Directional Pad Up-Right */\n    AKEYCODE_DPAD_UP_RIGHT   = 270,\n    /** Directional Pad Down-Right */\n    AKEYCODE_DPAD_DOWN_RIGHT = 271,\n    /** Skip forward media key */\n    AKEYCODE_MEDIA_SKIP_FORWARD = 272,\n    /** Skip backward media key */\n    AKEYCODE_MEDIA_SKIP_BACKWARD = 273,\n    /** Step forward media key.\n     * Steps media forward one from at a time. */\n    AKEYCODE_MEDIA_STEP_FORWARD = 274,\n    /** Step backward media key.\n     * Steps media backward one from at a time. */\n    AKEYCODE_MEDIA_STEP_BACKWARD = 275,\n    /** Put device to sleep unless a wakelock is held. */\n    AKEYCODE_SOFT_SLEEP = 276,\n    /** Cut key. */\n    AKEYCODE_CUT = 277,\n    /** Copy key. */\n    AKEYCODE_COPY = 278,\n    /** Paste key. */\n    AKEYCODE_PASTE = 279\n\n    // NOTE: If you add a new keycode here you must also add it to several other files.\n    //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.\n};\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // _ANDROID_KEYCODES_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/looper.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup Looper\n * @{\n */\n\n/**\n * @file looper.h\n */\n\n#ifndef ANDROID_LOOPER_H\n#define ANDROID_LOOPER_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct ALooper;\n/**\n * ALooper\n *\n * A looper is the state tracking an event loop for a thread.\n * Loopers do not define event structures or other such things; rather\n * they are a lower-level facility to attach one or more discrete objects\n * listening for an event.  An \"event\" here is simply data available on\n * a file descriptor: each attached object has an associated file descriptor,\n * and waiting for \"events\" means (internally) polling on all of these file\n * descriptors until one or more of them have data available.\n *\n * A thread can have only one ALooper associated with it.\n */\ntypedef struct ALooper ALooper;\n\n/**\n * Returns the looper associated with the calling thread, or NULL if\n * there is not one.\n */\nALooper* ALooper_forThread();\n\n/** Option for for ALooper_prepare(). */\nenum {\n    /**\n     * This looper will accept calls to ALooper_addFd() that do not\n     * have a callback (that is provide NULL for the callback).  In\n     * this case the caller of ALooper_pollOnce() or ALooper_pollAll()\n     * MUST check the return from these functions to discover when\n     * data is available on such fds and process it.\n     */\n    ALOOPER_PREPARE_ALLOW_NON_CALLBACKS = 1<<0\n};\n\n/**\n * Prepares a looper associated with the calling thread, and returns it.\n * If the thread already has a looper, it is returned.  Otherwise, a new\n * one is created, associated with the thread, and returned.\n *\n * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0.\n */\nALooper* ALooper_prepare(int opts);\n\n/** Result from ALooper_pollOnce() and ALooper_pollAll(). */\nenum {\n    /**\n     * The poll was awoken using wake() before the timeout expired\n     * and no callbacks were executed and no other file descriptors were ready.\n     */\n    ALOOPER_POLL_WAKE = -1,\n\n    /**\n     * Result from ALooper_pollOnce() and ALooper_pollAll():\n     * One or more callbacks were executed.\n     */\n    ALOOPER_POLL_CALLBACK = -2,\n\n    /**\n     * Result from ALooper_pollOnce() and ALooper_pollAll():\n     * The timeout expired.\n     */\n    ALOOPER_POLL_TIMEOUT = -3,\n\n    /**\n     * Result from ALooper_pollOnce() and ALooper_pollAll():\n     * An error occurred.\n     */\n    ALOOPER_POLL_ERROR = -4,\n};\n\n/**\n * Acquire a reference on the given ALooper object.  This prevents the object\n * from being deleted until the reference is removed.  This is only needed\n * to safely hand an ALooper from one thread to another.\n */\nvoid ALooper_acquire(ALooper* looper);\n\n/**\n * Remove a reference that was previously acquired with ALooper_acquire().\n */\nvoid ALooper_release(ALooper* looper);\n\n/**\n * Flags for file descriptor events that a looper can monitor.\n *\n * These flag bits can be combined to monitor multiple events at once.\n */\nenum {\n    /**\n     * The file descriptor is available for read operations.\n     */\n    ALOOPER_EVENT_INPUT = 1 << 0,\n\n    /**\n     * The file descriptor is available for write operations.\n     */\n    ALOOPER_EVENT_OUTPUT = 1 << 1,\n\n    /**\n     * The file descriptor has encountered an error condition.\n     *\n     * The looper always sends notifications about errors; it is not necessary\n     * to specify this event flag in the requested event set.\n     */\n    ALOOPER_EVENT_ERROR = 1 << 2,\n\n    /**\n     * The file descriptor was hung up.\n     * For example, indicates that the remote end of a pipe or socket was closed.\n     *\n     * The looper always sends notifications about hangups; it is not necessary\n     * to specify this event flag in the requested event set.\n     */\n    ALOOPER_EVENT_HANGUP = 1 << 3,\n\n    /**\n     * The file descriptor is invalid.\n     * For example, the file descriptor was closed prematurely.\n     *\n     * The looper always sends notifications about invalid file descriptors; it is not necessary\n     * to specify this event flag in the requested event set.\n     */\n    ALOOPER_EVENT_INVALID = 1 << 4,\n};\n\n/**\n * For callback-based event loops, this is the prototype of the function\n * that is called when a file descriptor event occurs.\n * It is given the file descriptor it is associated with,\n * a bitmask of the poll events that were triggered (typically ALOOPER_EVENT_INPUT),\n * and the data pointer that was originally supplied.\n *\n * Implementations should return 1 to continue receiving callbacks, or 0\n * to have this file descriptor and callback unregistered from the looper.\n */\ntypedef int (*ALooper_callbackFunc)(int fd, int events, void* data);\n\n/**\n * Waits for events to be available, with optional timeout in milliseconds.\n * Invokes callbacks for all file descriptors on which an event occurred.\n *\n * If the timeout is zero, returns immediately without blocking.\n * If the timeout is negative, waits indefinitely until an event appears.\n *\n * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before\n * the timeout expired and no callbacks were invoked and no other file\n * descriptors were ready.\n *\n * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked.\n *\n * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given\n * timeout expired.\n *\n * Returns ALOOPER_POLL_ERROR if an error occurred.\n *\n * Returns a value >= 0 containing an identifier (the same identifier\n * `ident` passed to ALooper_addFd()) if its file descriptor has data\n * and it has no callback function (requiring the caller here to\n * handle it).  In this (and only this) case outFd, outEvents and\n * outData will contain the poll events and data associated with the\n * fd, otherwise they will be set to NULL.\n *\n * This method does not return until it has finished invoking the appropriate callbacks\n * for all file descriptors that were signalled.\n */\nint ALooper_pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);\n\n/**\n * Like ALooper_pollOnce(), but performs all pending callbacks until all\n * data has been consumed or a file descriptor is available with no callback.\n * This function will never return ALOOPER_POLL_CALLBACK.\n */\nint ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);\n\n/**\n * Wakes the poll asynchronously.\n *\n * This method can be called on any thread.\n * This method returns immediately.\n */\nvoid ALooper_wake(ALooper* looper);\n\n/**\n * Adds a new file descriptor to be polled by the looper.\n * If the same file descriptor was previously added, it is replaced.\n *\n * \"fd\" is the file descriptor to be added.\n * \"ident\" is an identifier for this event, which is returned from ALooper_pollOnce().\n * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback.\n * \"events\" are the poll events to wake up on.  Typically this is ALOOPER_EVENT_INPUT.\n * \"callback\" is the function to call when there is an event on the file descriptor.\n * \"data\" is a private data pointer to supply to the callback.\n *\n * There are two main uses of this function:\n *\n * (1) If \"callback\" is non-NULL, then this function will be called when there is\n * data on the file descriptor.  It should execute any events it has pending,\n * appropriately reading from the file descriptor.  The 'ident' is ignored in this case.\n *\n * (2) If \"callback\" is NULL, the 'ident' will be returned by ALooper_pollOnce\n * when its file descriptor has data available, requiring the caller to take\n * care of processing it.\n *\n * Returns 1 if the file descriptor was added or -1 if an error occurred.\n *\n * This method can be called on any thread.\n * This method may block briefly if it needs to wake the poll.\n */\nint ALooper_addFd(ALooper* looper, int fd, int ident, int events,\n        ALooper_callbackFunc callback, void* data);\n\n/**\n * Removes a previously added file descriptor from the looper.\n *\n * When this method returns, it is safe to close the file descriptor since the looper\n * will no longer have a reference to it.  However, it is possible for the callback to\n * already be running or for it to run one last time if the file descriptor was already\n * signalled.  Calling code is responsible for ensuring that this case is safely handled.\n * For example, if the callback takes care of removing itself during its own execution either\n * by returning 0 or by calling this method, then it can be guaranteed to not be invoked\n * again at any later time unless registered anew.\n *\n * Returns 1 if the file descriptor was removed, 0 if none was previously registered\n * or -1 if an error occurred.\n *\n * This method can be called on any thread.\n * This method may block briefly if it needs to wake the poll.\n */\nint ALooper_removeFd(ALooper* looper, int fd);\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif // ANDROID_LOOPER_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/multinetwork.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_MULTINETWORK_H\n#define ANDROID_MULTINETWORK_H\n\n#include <netdb.h>\n#include <stdlib.h>\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\n/**\n * The corresponding C type for android.net.Network#getNetworkHandle() return\n * values.  The Java signed long value can be safely cast to a net_handle_t:\n *\n *     [C]    ((net_handle_t) java_long_network_handle)\n *     [C++]  static_cast<net_handle_t>(java_long_network_handle)\n *\n * as appropriate.\n */\ntypedef uint64_t net_handle_t;\n\n/**\n * The value NETWORK_UNSPECIFIED indicates no specific network.\n *\n * For some functions (documented below), a previous binding may be cleared\n * by an invocation with NETWORK_UNSPECIFIED.\n *\n * Depending on the context it may indicate an error.  It is expressly\n * not used to indicate some notion of the \"current default network\".\n */\n#define NETWORK_UNSPECIFIED  ((net_handle_t)0)\n\n\n/**\n * All functions below that return an int return 0 on success or -1\n * on failure with an appropriate errno value set.\n */\n\n\n/**\n * Set the network to be used by the given socket file descriptor.\n *\n * To clear a previous socket binding invoke with NETWORK_UNSPECIFIED.\n *\n * This is the equivalent of:\n *\n *     [ android.net.Network#bindSocket() ]\n *     https://developer.android.com/reference/android/net/Network.html#bindSocket(java.net.Socket)\n */\nint android_setsocknetwork(net_handle_t network, int fd);\n\n\n/**\n * Binds the current process to |network|.  All sockets created in the future\n * (and not explicitly bound via android_setsocknetwork()) will be bound to\n * |network|.  All host name resolutions will be limited to |network| as well.\n * Note that if the network identified by |network| ever disconnects, all\n * sockets created in this way will cease to work and all host name\n * resolutions will fail.  This is by design so an application doesn't\n * accidentally use sockets it thinks are still bound to a particular network.\n *\n * To clear a previous process binding invoke with NETWORK_UNSPECIFIED.\n *\n * This is the equivalent of:\n *\n *     [ android.net.ConnectivityManager#setProcessDefaultNetwork() ]\n *     https://developer.android.com/reference/android/net/ConnectivityManager.html#setProcessDefaultNetwork(android.net.Network)\n */\nint android_setprocnetwork(net_handle_t network);\n\n\n/**\n * Perform hostname resolution via the DNS servers associated with |network|.\n *\n * All arguments (apart from |network|) are used identically as those passed\n * to getaddrinfo(3).  Return and error values are identical to those of\n * getaddrinfo(3), and in particular gai_strerror(3) can be used as expected.\n * Similar to getaddrinfo(3):\n *     - |hints| may be NULL (in which case man page documented defaults apply)\n *     - either |node| or |service| may be NULL, but not both\n *     - |res| must not be NULL\n *\n * This is the equivalent of:\n *\n *     [ android.net.Network#getAllByName() ]\n *     https://developer.android.com/reference/android/net/Network.html#getAllByName(java.lang.String)\n */\nint android_getaddrinfofornetwork(net_handle_t network,\n        const char *node, const char *service,\n        const struct addrinfo *hints, struct addrinfo **res);\n\n__END_DECLS\n\n#endif  // ANDROID_MULTINETWORK_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/native_activity.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup NativeActivity Native Activity\n * @{\n */\n\n/**\n * @file native_activity.h\n */\n\n#ifndef ANDROID_NATIVE_ACTIVITY_H\n#define ANDROID_NATIVE_ACTIVITY_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <jni.h>\n\n#include <android/asset_manager.h>\n#include <android/input.h>\n#include <android/native_window.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * {@link ANativeActivityCallbacks}\n */\nstruct ANativeActivityCallbacks;\n\n/**\n * This structure defines the native side of an android.app.NativeActivity.\n * It is created by the framework, and handed to the application's native\n * code as it is being launched.\n */\ntypedef struct ANativeActivity {\n    /**\n     * Pointer to the callback function table of the native application.\n     * You can set the functions here to your own callbacks.  The callbacks\n     * pointer itself here should not be changed; it is allocated and managed\n     * for you by the framework.\n     */\n    struct ANativeActivityCallbacks* callbacks;\n\n    /**\n     * The global handle on the process's Java VM.\n     */\n    JavaVM* vm;\n\n    /**\n     * JNI context for the main thread of the app.  Note that this field\n     * can ONLY be used from the main thread of the process; that is, the\n     * thread that calls into the ANativeActivityCallbacks.\n     */\n    JNIEnv* env;\n\n    /**\n     * The NativeActivity object handle.\n     *\n     * IMPORTANT NOTE: This member is mis-named. It should really be named\n     * 'activity' instead of 'clazz', since it's a reference to the\n     * NativeActivity instance created by the system for you.\n     *\n     * We unfortunately cannot change this without breaking NDK\n     * source-compatibility.\n     */\n    jobject clazz;\n\n    /**\n     * Path to this application's internal data directory.\n     */\n    const char* internalDataPath;\n\n    /**\n     * Path to this application's external (removable/mountable) data directory.\n     */\n    const char* externalDataPath;\n\n    /**\n     * The platform's SDK version code.\n     */\n    int32_t sdkVersion;\n\n    /**\n     * This is the native instance of the application.  It is not used by\n     * the framework, but can be set by the application to its own instance\n     * state.\n     */\n    void* instance;\n\n    /**\n     * Pointer to the Asset Manager instance for the application.  The application\n     * uses this to access binary assets bundled inside its own .apk file.\n     */\n    AAssetManager* assetManager;\n\n    /**\n     * Available starting with Honeycomb: path to the directory containing\n     * the application's OBB files (if any).  If the app doesn't have any\n     * OBB files, this directory may not exist.\n     */\n    const char* obbPath;\n} ANativeActivity;\n\n/**\n * These are the callbacks the framework makes into a native application.\n * All of these callbacks happen on the main thread of the application.\n * By default, all callbacks are NULL; set to a pointer to your own function\n * to have it called.\n */\ntypedef struct ANativeActivityCallbacks {\n    /**\n     * NativeActivity has started.  See Java documentation for Activity.onStart()\n     * for more information.\n     */\n    void (*onStart)(ANativeActivity* activity);\n\n    /**\n     * NativeActivity has resumed.  See Java documentation for Activity.onResume()\n     * for more information.\n     */\n    void (*onResume)(ANativeActivity* activity);\n\n    /**\n     * Framework is asking NativeActivity to save its current instance state.\n     * See Java documentation for Activity.onSaveInstanceState() for more\n     * information.  The returned pointer needs to be created with malloc();\n     * the framework will call free() on it for you.  You also must fill in\n     * outSize with the number of bytes in the allocation.  Note that the\n     * saved state will be persisted, so it can not contain any active\n     * entities (pointers to memory, file descriptors, etc).\n     */\n    void* (*onSaveInstanceState)(ANativeActivity* activity, size_t* outSize);\n\n    /**\n     * NativeActivity has paused.  See Java documentation for Activity.onPause()\n     * for more information.\n     */\n    void (*onPause)(ANativeActivity* activity);\n\n    /**\n     * NativeActivity has stopped.  See Java documentation for Activity.onStop()\n     * for more information.\n     */\n    void (*onStop)(ANativeActivity* activity);\n\n    /**\n     * NativeActivity is being destroyed.  See Java documentation for Activity.onDestroy()\n     * for more information.\n     */\n    void (*onDestroy)(ANativeActivity* activity);\n\n    /**\n     * Focus has changed in this NativeActivity's window.  This is often used,\n     * for example, to pause a game when it loses input focus.\n     */\n    void (*onWindowFocusChanged)(ANativeActivity* activity, int hasFocus);\n\n    /**\n     * The drawing window for this native activity has been created.  You\n     * can use the given native window object to start drawing.\n     */\n    void (*onNativeWindowCreated)(ANativeActivity* activity, ANativeWindow* window);\n\n    /**\n     * The drawing window for this native activity has been resized.  You should\n     * retrieve the new size from the window and ensure that your rendering in\n     * it now matches.\n     */\n    void (*onNativeWindowResized)(ANativeActivity* activity, ANativeWindow* window);\n\n    /**\n     * The drawing window for this native activity needs to be redrawn.  To avoid\n     * transient artifacts during screen changes (such resizing after rotation),\n     * applications should not return from this function until they have finished\n     * drawing their window in its current state.\n     */\n    void (*onNativeWindowRedrawNeeded)(ANativeActivity* activity, ANativeWindow* window);\n\n    /**\n     * The drawing window for this native activity is going to be destroyed.\n     * You MUST ensure that you do not touch the window object after returning\n     * from this function: in the common case of drawing to the window from\n     * another thread, that means the implementation of this callback must\n     * properly synchronize with the other thread to stop its drawing before\n     * returning from here.\n     */\n    void (*onNativeWindowDestroyed)(ANativeActivity* activity, ANativeWindow* window);\n\n    /**\n     * The input queue for this native activity's window has been created.\n     * You can use the given input queue to start retrieving input events.\n     */\n    void (*onInputQueueCreated)(ANativeActivity* activity, AInputQueue* queue);\n\n    /**\n     * The input queue for this native activity's window is being destroyed.\n     * You should no longer try to reference this object upon returning from this\n     * function.\n     */\n    void (*onInputQueueDestroyed)(ANativeActivity* activity, AInputQueue* queue);\n\n    /**\n     * The rectangle in the window in which content should be placed has changed.\n     */\n    void (*onContentRectChanged)(ANativeActivity* activity, const ARect* rect);\n\n    /**\n     * The current device AConfiguration has changed.  The new configuration can\n     * be retrieved from assetManager.\n     */\n    void (*onConfigurationChanged)(ANativeActivity* activity);\n\n    /**\n     * The system is running low on memory.  Use this callback to release\n     * resources you do not need, to help the system avoid killing more\n     * important processes.\n     */\n    void (*onLowMemory)(ANativeActivity* activity);\n} ANativeActivityCallbacks;\n\n/**\n * This is the function that must be in the native code to instantiate the\n * application's native activity.  It is called with the activity instance (see\n * above); if the code is being instantiated from a previously saved instance,\n * the savedState will be non-NULL and point to the saved data.  You must make\n * any copy of this data you need -- it will be released after you return from\n * this function.\n */\ntypedef void ANativeActivity_createFunc(ANativeActivity* activity,\n        void* savedState, size_t savedStateSize);\n\n/**\n * The name of the function that NativeInstance looks for when launching its\n * native code.  This is the default function that is used, you can specify\n * \"android.app.func_name\" string meta-data in your manifest to use a different\n * function.\n */\nextern ANativeActivity_createFunc ANativeActivity_onCreate;\n\n/**\n * Finish the given activity.  Its finish() method will be called, causing it\n * to be stopped and destroyed.  Note that this method can be called from\n * *any* thread; it will send a message to the main thread of the process\n * where the Java finish call will take place.\n */\nvoid ANativeActivity_finish(ANativeActivity* activity);\n\n/**\n * Change the window format of the given activity.  Calls getWindow().setFormat()\n * of the given activity.  Note that this method can be called from\n * *any* thread; it will send a message to the main thread of the process\n * where the Java finish call will take place.\n */\nvoid ANativeActivity_setWindowFormat(ANativeActivity* activity, int32_t format);\n\n/**\n * Change the window flags of the given activity.  Calls getWindow().setFlags()\n * of the given activity.  Note that this method can be called from\n * *any* thread; it will send a message to the main thread of the process\n * where the Java finish call will take place.  See window.h for flag constants.\n */\nvoid ANativeActivity_setWindowFlags(ANativeActivity* activity,\n        uint32_t addFlags, uint32_t removeFlags);\n\n/**\n * Flags for ANativeActivity_showSoftInput; see the Java InputMethodManager\n * API for documentation.\n */\nenum {\n    /**\n     * Implicit request to show the input window, not as the result\n     * of a direct request by the user.\n     */\n    ANATIVEACTIVITY_SHOW_SOFT_INPUT_IMPLICIT = 0x0001,\n\n    /**\n     * The user has forced the input method open (such as by\n     * long-pressing menu) so it should not be closed until they\n     * explicitly do so.\n     */\n    ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED = 0x0002,\n};\n\n/**\n * Show the IME while in the given activity.  Calls InputMethodManager.showSoftInput()\n * for the given activity.  Note that this method can be called from\n * *any* thread; it will send a message to the main thread of the process\n * where the Java finish call will take place.\n */\nvoid ANativeActivity_showSoftInput(ANativeActivity* activity, uint32_t flags);\n\n/**\n * Flags for ANativeActivity_hideSoftInput; see the Java InputMethodManager\n * API for documentation.\n */\nenum {\n    /**\n     * The soft input window should only be hidden if it was not\n     * explicitly shown by the user.\n     */\n    ANATIVEACTIVITY_HIDE_SOFT_INPUT_IMPLICIT_ONLY = 0x0001,\n    /**\n     * The soft input window should normally be hidden, unless it was\n     * originally shown with {@link ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED}.\n     */\n    ANATIVEACTIVITY_HIDE_SOFT_INPUT_NOT_ALWAYS = 0x0002,\n};\n\n/**\n * Hide the IME while in the given activity.  Calls InputMethodManager.hideSoftInput()\n * for the given activity.  Note that this method can be called from\n * *any* thread; it will send a message to the main thread of the process\n * where the Java finish call will take place.\n */\nvoid ANativeActivity_hideSoftInput(ANativeActivity* activity, uint32_t flags);\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif // ANDROID_NATIVE_ACTIVITY_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/native_window.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup NativeActivity Native Activity\n * @{\n */\n\n/**\n * @file native_window.h\n */\n\n#ifndef ANDROID_NATIVE_WINDOW_H\n#define ANDROID_NATIVE_WINDOW_H\n\n#include <android/rect.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Pixel formats that a window can use.\n */\nenum {\n    /** Red: 8 bits, Green: 8 bits, Blue: 8 bits, Alpha: 8 bits. **/\n    WINDOW_FORMAT_RGBA_8888          = 1,\n    /** Red: 8 bits, Green: 8 bits, Blue: 8 bits, Unused: 8 bits. **/\n    WINDOW_FORMAT_RGBX_8888          = 2,\n    /** Red: 5 bits, Green: 6 bits, Blue: 5 bits. **/\n    WINDOW_FORMAT_RGB_565            = 4,\n};\n\nstruct ANativeWindow;\n/**\n * {@link ANativeWindow} is opaque type that provides access to a native window.\n *\n * A pointer can be obtained using ANativeWindow_fromSurface().\n */\ntypedef struct ANativeWindow ANativeWindow;\n\n/**\n * {@link ANativeWindow} is a struct that represents a windows buffer.\n *\n * A pointer can be obtained using ANativeWindow_lock().\n */\ntypedef struct ANativeWindow_Buffer {\n    // The number of pixels that are show horizontally.\n    int32_t width;\n\n    // The number of pixels that are shown vertically.\n    int32_t height;\n\n    // The number of *pixels* that a line in the buffer takes in\n    // memory.  This may be >= width.\n    int32_t stride;\n\n    // The format of the buffer.  One of WINDOW_FORMAT_*\n    int32_t format;\n\n    // The actual bits.\n    void* bits;\n\n    // Do not touch.\n    uint32_t reserved[6];\n} ANativeWindow_Buffer;\n\n/**\n * Acquire a reference on the given ANativeWindow object.  This prevents the object\n * from being deleted until the reference is removed.\n */\nvoid ANativeWindow_acquire(ANativeWindow* window);\n\n/**\n * Remove a reference that was previously acquired with ANativeWindow_acquire().\n */\nvoid ANativeWindow_release(ANativeWindow* window);\n\n/**\n * Return the current width in pixels of the window surface.  Returns a\n * negative value on error.\n */\nint32_t ANativeWindow_getWidth(ANativeWindow* window);\n\n/**\n * Return the current height in pixels of the window surface.  Returns a\n * negative value on error.\n */\nint32_t ANativeWindow_getHeight(ANativeWindow* window);\n\n/**\n * Return the current pixel format of the window surface.  Returns a\n * negative value on error.\n */\nint32_t ANativeWindow_getFormat(ANativeWindow* window);\n\n/**\n * Change the format and size of the window buffers.\n *\n * The width and height control the number of pixels in the buffers, not the\n * dimensions of the window on screen.  If these are different than the\n * window's physical size, then it buffer will be scaled to match that size\n * when compositing it to the screen.\n *\n * For all of these parameters, if 0 is supplied then the window's base\n * value will come back in force.\n *\n * width and height must be either both zero or both non-zero.\n *\n */\nint32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window,\n        int32_t width, int32_t height, int32_t format);\n\n/**\n * Lock the window's next drawing surface for writing.\n * inOutDirtyBounds is used as an in/out parameter, upon entering the\n * function, it contains the dirty region, that is, the region the caller\n * intends to redraw. When the function returns, inOutDirtyBounds is updated\n * with the actual area the caller needs to redraw -- this region is often\n * extended by ANativeWindow_lock.\n */\nint32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,\n        ARect* inOutDirtyBounds);\n\n/**\n * Unlock the window's drawing surface after previously locking it,\n * posting the new buffer to the display.\n */\nint32_t ANativeWindow_unlockAndPost(ANativeWindow* window);\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif // ANDROID_NATIVE_WINDOW_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/native_window_jni.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup NativeActivity Native Activity\n * @{\n */\n\n/**\n * @file native_window_jni.h\n */\n\n#ifndef ANDROID_NATIVE_WINDOW_JNI_H\n#define ANDROID_NATIVE_WINDOW_JNI_H\n\n#include <android/native_window.h>\n\n#include <jni.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Return the ANativeWindow associated with a Java Surface object,\n * for interacting with it through native code.  This acquires a reference\n * on the ANativeWindow that is returned; be sure to use ANativeWindow_release()\n * when done with it so that it doesn't leak.\n */\nANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface);\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif // ANDROID_NATIVE_WINDOW_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/obb.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup Storage\n * @{\n */\n\n/**\n * @file obb.h\n */\n\n#ifndef ANDROID_OBB_H\n#define ANDROID_OBB_H\n\n#include <sys/types.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct AObbInfo;\n/** {@link AObbInfo} is an opaque type representing information for obb storage. */\ntypedef struct AObbInfo AObbInfo;\n\n/** Flag for an obb file, returned by AObbInfo_getFlags(). */\nenum {\n    /** overlay */\n    AOBBINFO_OVERLAY = 0x0001,\n};\n\n/**\n * Scan an OBB and get information about it.\n */\nAObbInfo* AObbScanner_getObbInfo(const char* filename);\n\n/**\n * Destroy the AObbInfo object. You must call this when finished with the object.\n */\nvoid AObbInfo_delete(AObbInfo* obbInfo);\n\n/**\n * Get the package name for the OBB.\n */\nconst char* AObbInfo_getPackageName(AObbInfo* obbInfo);\n\n/**\n * Get the version of an OBB file.\n */\nint32_t AObbInfo_getVersion(AObbInfo* obbInfo);\n\n/**\n * Get the flags of an OBB file.\n */\nint32_t AObbInfo_getFlags(AObbInfo* obbInfo);\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif      // ANDROID_OBB_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/rect.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup NativeActivity Native Activity\n * @{\n */\n\n/**\n * @file rect.h\n */\n\n#ifndef ANDROID_RECT_H\n#define ANDROID_RECT_H\n\n#include <stdint.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * {@link ARect} is a struct that represents a rectangular window area.\n *\n * It is used with {@link\n * ANativeActivityCallbacks::onContentRectChanged} event callback and\n * ANativeWindow_lock() function.\n */\ntypedef struct ARect {\n#ifdef __cplusplus\n    typedef int32_t value_type;\n#endif\n    /** left position */\n    int32_t left;\n    /** top position */\n    int32_t top;\n    /** left position */\n    int32_t right;\n    /** bottom position */\n    int32_t bottom;\n} ARect;\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif // ANDROID_RECT_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/sensor.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup Sensor\n * @{\n */\n\n/**\n * @file sensor.h\n */\n\n#ifndef ANDROID_SENSOR_H\n#define ANDROID_SENSOR_H\n\n/******************************************************************\n *\n * IMPORTANT NOTICE:\n *\n *   This file is part of Android's set of stable system headers\n *   exposed by the Android NDK (Native Development Kit).\n *\n *   Third-party source AND binary code relies on the definitions\n *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.\n *\n *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)\n *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS\n *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY\n *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES\n */\n\n/**\n * Structures and functions to receive and process sensor events in\n * native code.\n *\n */\n\n#include <sys/types.h>\n\n#include <android/looper.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/**\n * Sensor types.\n * (keep in sync with hardware/sensors.h)\n */\nenum {\n    /**\n     * {@link ASENSOR_TYPE_ACCELEROMETER}\n     * reporting-mode: continuous\n     *\n     *  All values are in SI units (m/s^2) and measure the acceleration of the\n     *  device minus the force of gravity.\n     */\n    ASENSOR_TYPE_ACCELEROMETER       = 1,\n    /**\n     * {@link ASENSOR_TYPE_MAGNETIC_FIELD}\n     * reporting-mode: continuous\n     *\n     *  All values are in micro-Tesla (uT) and measure the geomagnetic\n     *  field in the X, Y and Z axis.\n     */\n    ASENSOR_TYPE_MAGNETIC_FIELD      = 2,\n    /**\n     * {@link ASENSOR_TYPE_GYROSCOPE}\n     * reporting-mode: continuous\n     *\n     *  All values are in radians/second and measure the rate of rotation\n     *  around the X, Y and Z axis.\n     */\n    ASENSOR_TYPE_GYROSCOPE           = 4,\n    /**\n     * {@link ASENSOR_TYPE_LIGHT}\n     * reporting-mode: on-change\n     *\n     * The light sensor value is returned in SI lux units.\n     */\n    ASENSOR_TYPE_LIGHT               = 5,\n    /**\n     * {@link ASENSOR_TYPE_PROXIMITY}\n     * reporting-mode: on-change\n     *\n     * The proximity sensor which turns the screen off and back on during calls is the\n     * wake-up proximity sensor. Implement wake-up proximity sensor before implementing\n     * a non wake-up proximity sensor. For the wake-up proximity sensor set the flag\n     * SENSOR_FLAG_WAKE_UP.\n     * The value corresponds to the distance to the nearest object in centimeters.\n     */\n    ASENSOR_TYPE_PROXIMITY           = 8,\n    /**\n     * {@link ASENSOR_TYPE_LINEAR_ACCELERATION}\n     * reporting-mode: continuous\n     *\n     *  All values are in SI units (m/s^2) and measure the acceleration of the\n     *  device not including the force of gravity.\n     */\n    ASENSOR_TYPE_LINEAR_ACCELERATION = 10\n};\n\n/**\n * Sensor accuracy measure.\n */\nenum {\n    /** no contact */\n    ASENSOR_STATUS_NO_CONTACT       = -1,\n    /** unreliable */\n    ASENSOR_STATUS_UNRELIABLE       = 0,\n    /** low accuracy */\n    ASENSOR_STATUS_ACCURACY_LOW     = 1,\n    /** medium accuracy */\n    ASENSOR_STATUS_ACCURACY_MEDIUM  = 2,\n    /** high accuracy */\n    ASENSOR_STATUS_ACCURACY_HIGH    = 3\n};\n\n/**\n * Sensor Reporting Modes.\n */\nenum {\n    /** continuous reporting */\n    AREPORTING_MODE_CONTINUOUS = 0,\n    /** reporting on change */\n    AREPORTING_MODE_ON_CHANGE = 1,\n    /** on shot reporting */\n    AREPORTING_MODE_ONE_SHOT = 2,\n    /** special trigger reporting */\n    AREPORTING_MODE_SPECIAL_TRIGGER = 3\n};\n\n/*\n * A few useful constants\n */\n\n/** Earth's gravity in m/s^2 */\n#define ASENSOR_STANDARD_GRAVITY            (9.80665f)\n/** Maximum magnetic field on Earth's surface in uT */\n#define ASENSOR_MAGNETIC_FIELD_EARTH_MAX    (60.0f)\n/** Minimum magnetic field on Earth's surface in uT*/\n#define ASENSOR_MAGNETIC_FIELD_EARTH_MIN    (30.0f)\n\n/**\n * A sensor event.\n */\n\n/* NOTE: Must match hardware/sensors.h */\ntypedef struct ASensorVector {\n    union {\n        float v[3];\n        struct {\n            float x;\n            float y;\n            float z;\n        };\n        struct {\n            float azimuth;\n            float pitch;\n            float roll;\n        };\n    };\n    int8_t status;\n    uint8_t reserved[3];\n} ASensorVector;\n\ntypedef struct AMetaDataEvent {\n    int32_t what;\n    int32_t sensor;\n} AMetaDataEvent;\n\ntypedef struct AUncalibratedEvent {\n    union {\n        float uncalib[3];\n        struct {\n            float x_uncalib;\n            float y_uncalib;\n            float z_uncalib;\n        };\n    };\n    union {\n        float bias[3];\n        struct {\n            float x_bias;\n            float y_bias;\n            float z_bias;\n        };\n    };\n} AUncalibratedEvent;\n\ntypedef struct AHeartRateEvent {\n    float bpm;\n    int8_t status;\n} AHeartRateEvent;\n\ntypedef struct ADynamicSensorEvent {\n    int32_t  connected;\n    int32_t  handle;\n} ADynamicSensorEvent;\n\ntypedef struct {\n    int32_t type;\n    int32_t serial;\n    union {\n        int32_t data_int32[14];\n        float   data_float[14];\n    };\n} AAdditionalInfoEvent;\n\n/* NOTE: Must match hardware/sensors.h */\ntypedef struct ASensorEvent {\n    int32_t version; /* sizeof(struct ASensorEvent) */\n    int32_t sensor;\n    int32_t type;\n    int32_t reserved0;\n    int64_t timestamp;\n    union {\n        union {\n            float           data[16];\n            ASensorVector   vector;\n            ASensorVector   acceleration;\n            ASensorVector   magnetic;\n            float           temperature;\n            float           distance;\n            float           light;\n            float           pressure;\n            float           relative_humidity;\n            AUncalibratedEvent uncalibrated_gyro;\n            AUncalibratedEvent uncalibrated_magnetic;\n            AMetaDataEvent meta_data;\n            AHeartRateEvent heart_rate;\n            ADynamicSensorEvent dynamic_sensor_meta;\n            AAdditionalInfoEvent additional_info;\n        };\n        union {\n            uint64_t        data[8];\n            uint64_t        step_counter;\n        } u64;\n    };\n\n    uint32_t flags;\n    int32_t reserved1[3];\n} ASensorEvent;\n\nstruct ASensorManager;\n/**\n * {@link ASensorManager} is an opaque type to manage sensors and\n * events queues.\n *\n * {@link ASensorManager} is a singleton that can be obtained using\n * ASensorManager_getInstance().\n *\n * This file provides a set of functions that uses {@link\n * ASensorManager} to access and list hardware sensors, and\n * create and destroy event queues:\n * - ASensorManager_getSensorList()\n * - ASensorManager_getDefaultSensor()\n * - ASensorManager_getDefaultSensorEx()\n * - ASensorManager_createEventQueue()\n * - ASensorManager_destroyEventQueue()\n */\ntypedef struct ASensorManager ASensorManager;\n\n\nstruct ASensorEventQueue;\n/**\n * {@link ASensorEventQueue} is an opaque type that provides access to\n * {@link ASensorEvent} from hardware sensors.\n *\n * A new {@link ASensorEventQueue} can be obtained using ASensorManager_createEventQueue().\n *\n * This file provides a set of functions to enable and disable\n * sensors, check and get events, and set event rates on a {@link\n * ASensorEventQueue}.\n * - ASensorEventQueue_enableSensor()\n * - ASensorEventQueue_disableSensor()\n * - ASensorEventQueue_hasEvents()\n * - ASensorEventQueue_getEvents()\n * - ASensorEventQueue_setEventRate()\n */\ntypedef struct ASensorEventQueue ASensorEventQueue;\n\nstruct ASensor;\n/**\n * {@link ASensor} is an opaque type that provides information about\n * an hardware sensors.\n *\n * A {@link ASensor} pointer can be obtained using\n * ASensorManager_getDefaultSensor(),\n * ASensorManager_getDefaultSensorEx() or from a {@link ASensorList}.\n *\n * This file provides a set of functions to access properties of a\n * {@link ASensor}:\n * - ASensor_getName()\n * - ASensor_getVendor()\n * - ASensor_getType()\n * - ASensor_getResolution()\n * - ASensor_getMinDelay()\n * - ASensor_getFifoMaxEventCount()\n * - ASensor_getFifoReservedEventCount()\n * - ASensor_getStringType()\n * - ASensor_getReportingMode()\n * - ASensor_isWakeUpSensor()\n */\ntypedef struct ASensor ASensor;\n/**\n * {@link ASensorRef} is a type for constant pointers to {@link ASensor}.\n *\n * This is used to define entry in {@link ASensorList} arrays.\n */\ntypedef ASensor const* ASensorRef;\n/**\n * {@link ASensorList} is an array of reference to {@link ASensor}.\n *\n * A {@link ASensorList} can be initialized using ASensorManager_getSensorList().\n */\ntypedef ASensorRef const* ASensorList;\n\n/*****************************************************************************/\n\n/**\n * Get a reference to the sensor manager. ASensorManager is a singleton\n * per package as different packages may have access to different sensors.\n *\n * Deprecated: Use ASensorManager_getInstanceForPackage(const char*) instead.\n *\n * Example:\n *\n *     ASensorManager* sensorManager = ASensorManager_getInstance();\n *\n */\n__attribute__ ((deprecated)) ASensorManager* ASensorManager_getInstance();\n\n/*\n * Get a reference to the sensor manager. ASensorManager is a singleton\n * per package as different packages may have access to different sensors.\n *\n * Example:\n *\n *    ASensorManager* sensorManager = ASensorManager_getInstanceForPackage(\"foo.bar.baz\");\n *\n */\nASensorManager* ASensorManager_getInstanceForPackage(const char* packageName);\n\n/**\n * Returns the list of available sensors.\n */\nint ASensorManager_getSensorList(ASensorManager* manager, ASensorList* list);\n\n/**\n * Returns the default sensor for the given type, or NULL if no sensor\n * of that type exists.\n */\nASensor const* ASensorManager_getDefaultSensor(ASensorManager* manager, int type);\n\n/**\n * Returns the default sensor with the given type and wakeUp properties or NULL if no sensor\n * of this type and wakeUp properties exists.\n */\nASensor const* ASensorManager_getDefaultSensorEx(ASensorManager* manager, int type,\n        bool wakeUp);\n\n/**\n * Creates a new sensor event queue and associate it with a looper.\n *\n * \"ident\" is a identifier for the events that will be returned when\n * calling ALooper_pollOnce(). The identifier must be >= 0, or\n * ALOOPER_POLL_CALLBACK if providing a non-NULL callback.\n */\nASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager,\n        ALooper* looper, int ident, ALooper_callbackFunc callback, void* data);\n\n/**\n * Destroys the event queue and free all resources associated to it.\n */\nint ASensorManager_destroyEventQueue(ASensorManager* manager, ASensorEventQueue* queue);\n\n\n/*****************************************************************************/\n\n/**\n * Enable the selected sensor with a specified sampling period and max batch report latency.\n * Returns a negative error code on failure.\n */\nint ASensorEventQueue_registerSensor(ASensorEventQueue* queue, ASensor const* sensor,\n        int32_t samplingPeriodUs, int maxBatchReportLatencyUs);\n\n/**\n * Enable the selected sensor. Returns a negative error code on failure.\n */\nint ASensorEventQueue_enableSensor(ASensorEventQueue* queue, ASensor const* sensor);\n\n/**\n * Disable the selected sensor. Returns a negative error code on failure.\n */\nint ASensorEventQueue_disableSensor(ASensorEventQueue* queue, ASensor const* sensor);\n\n/**\n * Sets the delivery rate of events in microseconds for the given sensor.\n * Note that this is a hint only, generally event will arrive at a higher\n * rate. It is an error to set a rate inferior to the value returned by\n * ASensor_getMinDelay().\n * Returns a negative error code on failure.\n */\nint ASensorEventQueue_setEventRate(ASensorEventQueue* queue, ASensor const* sensor, int32_t usec);\n\n/**\n * Returns true if there are one or more events available in the\n * sensor queue.  Returns 1 if the queue has events; 0 if\n * it does not have events; and a negative value if there is an error.\n */\nint ASensorEventQueue_hasEvents(ASensorEventQueue* queue);\n\n/**\n * Returns the next available events from the queue.  Returns a negative\n * value if no events are available or an error has occurred, otherwise\n * the number of events returned.\n *\n * Examples:\n *   ASensorEvent event;\n *   ssize_t numEvent = ASensorEventQueue_getEvents(queue, &event, 1);\n *\n *   ASensorEvent eventBuffer[8];\n *   ssize_t numEvent = ASensorEventQueue_getEvents(queue, eventBuffer, 8);\n *\n */\nssize_t ASensorEventQueue_getEvents(ASensorEventQueue* queue,\n                ASensorEvent* events, size_t count);\n\n\n/*****************************************************************************/\n\n/**\n * Returns this sensor's name (non localized)\n */\nconst char* ASensor_getName(ASensor const* sensor);\n\n/**\n * Returns this sensor's vendor's name (non localized)\n */\nconst char* ASensor_getVendor(ASensor const* sensor);\n\n/**\n * Return this sensor's type\n */\nint ASensor_getType(ASensor const* sensor);\n\n/**\n * Returns this sensors's resolution\n */\nfloat ASensor_getResolution(ASensor const* sensor);\n\n/**\n * Returns the minimum delay allowed between events in microseconds.\n * A value of zero means that this sensor doesn't report events at a\n * constant rate, but rather only when a new data is available.\n */\nint ASensor_getMinDelay(ASensor const* sensor);\n\n/**\n * Returns the maximum size of batches for this sensor. Batches will often be\n * smaller, as the hardware fifo might be used for other sensors.\n */\nint ASensor_getFifoMaxEventCount(ASensor const* sensor);\n\n/**\n * Returns the hardware batch fifo size reserved to this sensor.\n */\nint ASensor_getFifoReservedEventCount(ASensor const* sensor);\n\n/**\n * Returns this sensor's string type.\n */\nconst char* ASensor_getStringType(ASensor const* sensor);\n\n/**\n * Returns the reporting mode for this sensor. One of AREPORTING_MODE_* constants.\n */\nint ASensor_getReportingMode(ASensor const* sensor);\n\n/**\n * Returns true if this is a wake up sensor, false otherwise.\n */\nbool ASensor_isWakeUpSensor(ASensor const* sensor);\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif // ANDROID_SENSOR_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/storage_manager.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup Storage\n * @{\n */\n\n/**\n * @file storage_manager.h\n */\n\n#ifndef ANDROID_STORAGE_MANAGER_H\n#define ANDROID_STORAGE_MANAGER_H\n\n#include <stdint.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct AStorageManager;\n/**\n * {@link AStorageManager} manages application OBB storage, a pointer\n * can be obtained with AStorageManager_new().\n */\ntypedef struct AStorageManager AStorageManager;\n\n/**\n * The different states of a OBB storage passed to AStorageManager_obbCallbackFunc().\n */\nenum {\n    /**\n     * The OBB container is now mounted and ready for use. Can be returned\n     * as the status for callbacks made during asynchronous OBB actions.\n     */\n    AOBB_STATE_MOUNTED = 1,\n\n    /**\n     * The OBB container is now unmounted and not usable. Can be returned\n     * as the status for callbacks made during asynchronous OBB actions.\n     */\n    AOBB_STATE_UNMOUNTED = 2,\n\n    /**\n     * There was an internal system error encountered while trying to\n     * mount the OBB. Can be returned as the status for callbacks made\n     * during asynchronous OBB actions.\n     */\n    AOBB_STATE_ERROR_INTERNAL = 20,\n\n    /**\n     * The OBB could not be mounted by the system. Can be returned as the\n     * status for callbacks made during asynchronous OBB actions.\n     */\n    AOBB_STATE_ERROR_COULD_NOT_MOUNT = 21,\n\n    /**\n     * The OBB could not be unmounted. This most likely indicates that a\n     * file is in use on the OBB. Can be returned as the status for\n     * callbacks made during asynchronous OBB actions.\n     */\n    AOBB_STATE_ERROR_COULD_NOT_UNMOUNT = 22,\n\n    /**\n     * A call was made to unmount the OBB when it was not mounted. Can be\n     * returned as the status for callbacks made during asynchronous OBB\n     * actions.\n     */\n    AOBB_STATE_ERROR_NOT_MOUNTED = 23,\n\n    /**\n     * The OBB has already been mounted. Can be returned as the status for\n     * callbacks made during asynchronous OBB actions.\n     */\n    AOBB_STATE_ERROR_ALREADY_MOUNTED = 24,\n\n    /**\n     * The current application does not have permission to use this OBB.\n     * This could be because the OBB indicates it's owned by a different\n     * package. Can be returned as the status for callbacks made during\n     * asynchronous OBB actions.\n     */\n    AOBB_STATE_ERROR_PERMISSION_DENIED = 25,\n};\n\n/**\n * Obtains a new instance of AStorageManager.\n */\nAStorageManager* AStorageManager_new();\n\n/**\n * Release AStorageManager instance.\n */\nvoid AStorageManager_delete(AStorageManager* mgr);\n\n/**\n * Callback function for asynchronous calls made on OBB files.\n *\n * \"state\" is one of the following constants:\n * - {@link AOBB_STATE_MOUNTED}\n * - {@link AOBB_STATE_UNMOUNTED}\n * - {@link AOBB_STATE_ERROR_INTERNAL}\n * - {@link AOBB_STATE_ERROR_COULD_NOT_MOUNT}\n * - {@link AOBB_STATE_ERROR_COULD_NOT_UNMOUNT}\n * - {@link AOBB_STATE_ERROR_NOT_MOUNTED}\n * - {@link AOBB_STATE_ERROR_ALREADY_MOUNTED}\n * - {@link AOBB_STATE_ERROR_PERMISSION_DENIED}\n */\ntypedef void (*AStorageManager_obbCallbackFunc)(const char* filename, const int32_t state, void* data);\n\n/**\n * Attempts to mount an OBB file. This is an asynchronous operation.\n */\nvoid AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key,\n        AStorageManager_obbCallbackFunc cb, void* data);\n\n/**\n * Attempts to unmount an OBB file. This is an asynchronous operation.\n */\nvoid AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force,\n        AStorageManager_obbCallbackFunc cb, void* data);\n\n/**\n * Check whether an OBB is mounted.\n */\nint AStorageManager_isObbMounted(AStorageManager* mgr, const char* filename);\n\n/**\n * Get the mounted path for an OBB.\n */\nconst char* AStorageManager_getMountedObbPath(AStorageManager* mgr, const char* filename);\n\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif      // ANDROID_STORAGE_MANAGER_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/trace.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n#ifndef ANDROID_NATIVE_TRACE_H\n#define ANDROID_NATIVE_TRACE_H\n\n#include <stdbool.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Returns true if tracing is enabled. Use this signal to avoid expensive computation only necessary\n * when tracing is enabled.\n */\nbool ATrace_isEnabled();\n\n/**\n * Writes a tracing message to indicate that the given section of code has begun. This call must be\n * followed by a corresponding call to endSection() on the same thread.\n *\n * Note: At this time the vertical bar character '|' and newline character '\\n' are used internally\n * by the tracing mechanism. If sectionName contains these characters they will be replaced with a\n * space character in the trace.\n */\nvoid ATrace_beginSection(const char* sectionName);\n\n/**\n * Writes a tracing message to indicate that a given section of code has ended. This call must be\n * preceeded by a corresponding call to beginSection(char*) on the same thread. Calling this method\n * will mark the end of the most recently begun section of code, so care must be taken to ensure\n * that beginSection / endSection pairs are properly nested and called from the same thread.\n */\nvoid ATrace_endSection();\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif // ANDROID_NATIVE_TRACE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/android/window.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @addtogroup NativeActivity Native Activity\n * @{\n */\n\n/**\n * @file window.h\n */\n\n#ifndef ANDROID_WINDOW_H\n#define ANDROID_WINDOW_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Window flags, as per the Java API at android.view.WindowManager.LayoutParams.\n */\nenum {\n    /**\n     * As long as this window is visible to the user, allow the lock\n     * screen to activate while the screen is on.  This can be used\n     * independently, or in combination with {@link\n     * AWINDOW_FLAG_KEEP_SCREEN_ON} and/or {@link\n     * AWINDOW_FLAG_SHOW_WHEN_LOCKED}\n     */\n    AWINDOW_FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001,\n    /** Everything behind this window will be dimmed. */\n    AWINDOW_FLAG_DIM_BEHIND                 = 0x00000002,\n    /**\n     * Blur everything behind this window.\n     * @deprecated Blurring is no longer supported.\n     */\n    AWINDOW_FLAG_BLUR_BEHIND                = 0x00000004,\n    /**\n     * This window won't ever get key input focus, so the\n     * user can not send key or other button events to it.  Those will\n     * instead go to whatever focusable window is behind it.  This flag\n     * will also enable {@link AWINDOW_FLAG_NOT_TOUCH_MODAL} whether or not that\n     * is explicitly set.\n     *\n     * Setting this flag also implies that the window will not need to\n     * interact with\n     * a soft input method, so it will be Z-ordered and positioned\n     * independently of any active input method (typically this means it\n     * gets Z-ordered on top of the input method, so it can use the full\n     * screen for its content and cover the input method if needed.  You\n     * can use {@link AWINDOW_FLAG_ALT_FOCUSABLE_IM} to modify this behavior.\n     */\n    AWINDOW_FLAG_NOT_FOCUSABLE              = 0x00000008,\n    /** this window can never receive touch events. */\n    AWINDOW_FLAG_NOT_TOUCHABLE              = 0x00000010,\n    /**\n     * Even when this window is focusable (its\n     * {@link AWINDOW_FLAG_NOT_FOCUSABLE} is not set), allow any pointer events\n     * outside of the window to be sent to the windows behind it.  Otherwise\n     * it will consume all pointer events itself, regardless of whether they\n     * are inside of the window.\n     */\n    AWINDOW_FLAG_NOT_TOUCH_MODAL            = 0x00000020,\n    /**\n     * When set, if the device is asleep when the touch\n     * screen is pressed, you will receive this first touch event.  Usually\n     * the first touch event is consumed by the system since the user can\n     * not see what they are pressing on.\n     *\n     * @deprecated This flag has no effect.\n     */\n    AWINDOW_FLAG_TOUCHABLE_WHEN_WAKING      = 0x00000040,\n    /**\n     * As long as this window is visible to the user, keep\n     * the device's screen turned on and bright.\n     */\n    AWINDOW_FLAG_KEEP_SCREEN_ON             = 0x00000080,\n    /**\n     * Place the window within the entire screen, ignoring\n     * decorations around the border (such as the status bar).  The\n     * window must correctly position its contents to take the screen\n     * decoration into account.\n     */\n    AWINDOW_FLAG_LAYOUT_IN_SCREEN           = 0x00000100,\n    /** allow window to extend outside of the screen. */\n    AWINDOW_FLAG_LAYOUT_NO_LIMITS           = 0x00000200,\n    /**\n     * Hide all screen decorations (such as the status\n     * bar) while this window is displayed.  This allows the window to\n     * use the entire display space for itself -- the status bar will\n     * be hidden when an app window with this flag set is on the top\n     * layer. A fullscreen window will ignore a value of {@link\n     * AWINDOW_SOFT_INPUT_ADJUST_RESIZE}; the window will stay\n     * fullscreen and will not resize.\n     */\n    AWINDOW_FLAG_FULLSCREEN                 = 0x00000400,\n    /**\n     * Override {@link AWINDOW_FLAG_FULLSCREEN} and force the\n     * screen decorations (such as the status bar) to be shown.\n     */\n    AWINDOW_FLAG_FORCE_NOT_FULLSCREEN       = 0x00000800,\n    /**\n     * Turn on dithering when compositing this window to\n     * the screen.\n     * @deprecated This flag is no longer used.\n     */\n    AWINDOW_FLAG_DITHER                     = 0x00001000,\n    /**\n     * Treat the content of the window as secure, preventing\n     * it from appearing in screenshots or from being viewed on non-secure\n     * displays.\n     */\n    AWINDOW_FLAG_SECURE                     = 0x00002000,\n    /**\n     * A special mode where the layout parameters are used\n     * to perform scaling of the surface when it is composited to the\n     * screen.\n     */\n    AWINDOW_FLAG_SCALED                     = 0x00004000,\n    /**\n     * Intended for windows that will often be used when the user is\n     * holding the screen against their face, it will aggressively\n     * filter the event stream to prevent unintended presses in this\n     * situation that may not be desired for a particular window, when\n     * such an event stream is detected, the application will receive\n     * a {@link AMOTION_EVENT_ACTION_CANCEL} to indicate this so\n     * applications can handle this accordingly by taking no action on\n     * the event until the finger is released.\n     */\n    AWINDOW_FLAG_IGNORE_CHEEK_PRESSES       = 0x00008000,\n    /**\n     * A special option only for use in combination with\n     * {@link AWINDOW_FLAG_LAYOUT_IN_SCREEN}.  When requesting layout in the\n     * screen your window may appear on top of or behind screen decorations\n     * such as the status bar.  By also including this flag, the window\n     * manager will report the inset rectangle needed to ensure your\n     * content is not covered by screen decorations.\n     */\n    AWINDOW_FLAG_LAYOUT_INSET_DECOR         = 0x00010000,\n    /**\n     * Invert the state of {@link AWINDOW_FLAG_NOT_FOCUSABLE} with\n     * respect to how this window interacts with the current method.\n     * That is, if FLAG_NOT_FOCUSABLE is set and this flag is set,\n     * then the window will behave as if it needs to interact with the\n     * input method and thus be placed behind/away from it; if {@link\n     * AWINDOW_FLAG_NOT_FOCUSABLE} is not set and this flag is set,\n     * then the window will behave as if it doesn't need to interact\n     * with the input method and can be placed to use more space and\n     * cover the input method.\n     */\n    AWINDOW_FLAG_ALT_FOCUSABLE_IM           = 0x00020000,\n    /**\n     * If you have set {@link AWINDOW_FLAG_NOT_TOUCH_MODAL}, you\n     * can set this flag to receive a single special MotionEvent with\n     * the action\n     * {@link AMOTION_EVENT_ACTION_OUTSIDE} for\n     * touches that occur outside of your window.  Note that you will not\n     * receive the full down/move/up gesture, only the location of the\n     * first down as an {@link AMOTION_EVENT_ACTION_OUTSIDE}.\n     */\n    AWINDOW_FLAG_WATCH_OUTSIDE_TOUCH        = 0x00040000,\n    /**\n     * Special flag to let windows be shown when the screen\n     * is locked. This will let application windows take precedence over\n     * key guard or any other lock screens. Can be used with\n     * {@link AWINDOW_FLAG_KEEP_SCREEN_ON} to turn screen on and display windows\n     * directly before showing the key guard window.  Can be used with\n     * {@link AWINDOW_FLAG_DISMISS_KEYGUARD} to automatically fully dismisss\n     * non-secure keyguards.  This flag only applies to the top-most\n     * full-screen window.\n     */\n    AWINDOW_FLAG_SHOW_WHEN_LOCKED           = 0x00080000,\n    /**\n     * Ask that the system wallpaper be shown behind\n     * your window.  The window surface must be translucent to be able\n     * to actually see the wallpaper behind it; this flag just ensures\n     * that the wallpaper surface will be there if this window actually\n     * has translucent regions.\n     */\n    AWINDOW_FLAG_SHOW_WALLPAPER             = 0x00100000,\n    /**\n     * When set as a window is being added or made\n     * visible, once the window has been shown then the system will\n     * poke the power manager's user activity (as if the user had woken\n     * up the device) to turn the screen on.\n     */\n    AWINDOW_FLAG_TURN_SCREEN_ON             = 0x00200000,\n    /**\n     * When set the window will cause the keyguard to\n     * be dismissed, only if it is not a secure lock keyguard.  Because such\n     * a keyguard is not needed for security, it will never re-appear if\n     * the user navigates to another window (in contrast to\n     * {@link AWINDOW_FLAG_SHOW_WHEN_LOCKED}, which will only temporarily\n     * hide both secure and non-secure keyguards but ensure they reappear\n     * when the user moves to another UI that doesn't hide them).\n     * If the keyguard is currently active and is secure (requires an\n     * unlock pattern) than the user will still need to confirm it before\n     * seeing this window, unless {@link AWINDOW_FLAG_SHOW_WHEN_LOCKED} has\n     * also been set.\n     */\n    AWINDOW_FLAG_DISMISS_KEYGUARD           = 0x00400000,\n};\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif // ANDROID_WINDOW_H\n\n/** @} */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/batteryservice/BatteryService.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BATTERYSERVICE_H\n#define ANDROID_BATTERYSERVICE_H\n\n#include <binder/Parcel.h>\n#include <sys/types.h>\n#include <utils/Errors.h>\n#include <utils/String8.h>\n\nnamespace android {\n\n// must be kept in sync with definitions in BatteryManager.java\nenum {\n    BATTERY_STATUS_UNKNOWN = 1, // equals BatteryManager.BATTERY_STATUS_UNKNOWN constant\n    BATTERY_STATUS_CHARGING = 2, // equals BatteryManager.BATTERY_STATUS_CHARGING constant\n    BATTERY_STATUS_DISCHARGING = 3, // equals BatteryManager.BATTERY_STATUS_DISCHARGING constant\n    BATTERY_STATUS_NOT_CHARGING = 4, // equals BatteryManager.BATTERY_STATUS_NOT_CHARGING constant\n    BATTERY_STATUS_FULL = 5, // equals BatteryManager.BATTERY_STATUS_FULL constant\n};\n\n// must be kept in sync with definitions in BatteryManager.java\nenum {\n    BATTERY_HEALTH_UNKNOWN = 1, // equals BatteryManager.BATTERY_HEALTH_UNKNOWN constant\n    BATTERY_HEALTH_GOOD = 2, // equals BatteryManager.BATTERY_HEALTH_GOOD constant\n    BATTERY_HEALTH_OVERHEAT = 3, // equals BatteryManager.BATTERY_HEALTH_OVERHEAT constant\n    BATTERY_HEALTH_DEAD = 4, // equals BatteryManager.BATTERY_HEALTH_DEAD constant\n    BATTERY_HEALTH_OVER_VOLTAGE = 5, // equals BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE constant\n    BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6, // equals BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE constant\n    BATTERY_HEALTH_COLD = 7, // equals BatteryManager.BATTERY_HEALTH_COLD constant\n};\n\n// must be kept in sync with definitions in BatteryProperty.java\nenum {\n    BATTERY_PROP_CHARGE_COUNTER = 1, // equals BatteryProperty.CHARGE_COUNTER constant\n    BATTERY_PROP_CURRENT_NOW = 2, // equals BatteryProperty.CURRENT_NOW constant\n    BATTERY_PROP_CURRENT_AVG = 3, // equals BatteryProperty.CURRENT_AVG constant\n    BATTERY_PROP_CAPACITY = 4, // equals BatteryProperty.CAPACITY constant\n    BATTERY_PROP_ENERGY_COUNTER = 5, // equals BatteryProperty.ENERGY_COUNTER constant\n};\n\nstruct BatteryProperties {\n    bool chargerAcOnline;\n    bool chargerUsbOnline;\n    bool chargerWirelessOnline;\n    int maxChargingCurrent;\n    int maxChargingVoltage;\n    int batteryStatus;\n    int batteryHealth;\n    bool batteryPresent;\n    int batteryLevel;\n    int batteryVoltage;\n    int batteryTemperature;\n    int batteryCurrent;\n    int batteryCycleCount;\n    int batteryFullCharge;\n    int batteryChargeCounter;\n    String8 batteryTechnology;\n\n    status_t writeToParcel(Parcel* parcel) const;\n    status_t readFromParcel(Parcel* parcel);\n};\n\nstruct BatteryProperty {\n    int64_t valueInt64;\n\n    status_t writeToParcel(Parcel* parcel) const;\n    status_t readFromParcel(Parcel* parcel);\n};\n\n}; // namespace android\n\n#endif // ANDROID_BATTERYSERVICE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/batteryservice/IBatteryPropertiesListener.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_IBATTERYPROPERTIESLISTENER_H\n#define ANDROID_IBATTERYPROPERTIESLISTENER_H\n\n#include <binder/IBinder.h>\n#include <binder/IInterface.h>\n\n#include <batteryservice/BatteryService.h>\n\nnamespace android {\n\n// must be kept in sync with interface defined in IBatteryPropertiesListener.aidl\nenum {\n        TRANSACT_BATTERYPROPERTIESCHANGED = IBinder::FIRST_CALL_TRANSACTION,\n};\n\n// ----------------------------------------------------------------------------\n\nclass IBatteryPropertiesListener : public IInterface {\npublic:\n    DECLARE_META_INTERFACE(BatteryPropertiesListener);\n\n    virtual void batteryPropertiesChanged(struct BatteryProperties props) = 0;\n};\n\n// ----------------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_IBATTERYPROPERTIESLISTENER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/batteryservice/IBatteryPropertiesRegistrar.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_IBATTERYPROPERTIESREGISTRAR_H\n#define ANDROID_IBATTERYPROPERTIESREGISTRAR_H\n\n#include <binder/IInterface.h>\n#include <batteryservice/IBatteryPropertiesListener.h>\n\nnamespace android {\n\n// must be kept in sync with interface defined in IBatteryPropertiesRegistrar.aidl\nenum {\n    REGISTER_LISTENER = IBinder::FIRST_CALL_TRANSACTION,\n    UNREGISTER_LISTENER,\n    GET_PROPERTY,\n};\n\nclass IBatteryPropertiesRegistrar : public IInterface {\npublic:\n    DECLARE_META_INTERFACE(BatteryPropertiesRegistrar);\n\n    virtual void registerListener(const sp<IBatteryPropertiesListener>& listener) = 0;\n    virtual void unregisterListener(const sp<IBatteryPropertiesListener>& listener) = 0;\n    virtual status_t getProperty(int id, struct BatteryProperty *val) = 0;\n};\n\nclass BnBatteryPropertiesRegistrar : public BnInterface<IBatteryPropertiesRegistrar> {\npublic:\n    virtual status_t onTransact(uint32_t code, const Parcel& data,\n                                Parcel* reply, uint32_t flags = 0);\n};\n\n}; // namespace android\n\n#endif // ANDROID_IBATTERYPROPERTIESREGISTRAR_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/AppOpsManager.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_APP_OPS_MANAGER_H\n#define ANDROID_APP_OPS_MANAGER_H\n\n#include <binder/IAppOpsService.h>\n\n#include <utils/threads.h>\n\n// ---------------------------------------------------------------------------\nnamespace android {\n\nclass AppOpsManager\n{\npublic:\n    enum {\n        MODE_ALLOWED = IAppOpsService::MODE_ALLOWED,\n        MODE_IGNORED = IAppOpsService::MODE_IGNORED,\n        MODE_ERRORED = IAppOpsService::MODE_ERRORED\n    };\n\n    enum {\n        OP_NONE = -1,\n        OP_COARSE_LOCATION = 0,\n        OP_FINE_LOCATION = 1,\n        OP_GPS = 2,\n        OP_VIBRATE = 3,\n        OP_READ_CONTACTS = 4,\n        OP_WRITE_CONTACTS = 5,\n        OP_READ_CALL_LOG = 6,\n        OP_WRITE_CALL_LOG = 7,\n        OP_READ_CALENDAR = 8,\n        OP_WRITE_CALENDAR = 9,\n        OP_WIFI_SCAN = 10,\n        OP_POST_NOTIFICATION = 11,\n        OP_NEIGHBORING_CELLS = 12,\n        OP_CALL_PHONE = 13,\n        OP_READ_SMS = 14,\n        OP_WRITE_SMS = 15,\n        OP_RECEIVE_SMS = 16,\n        OP_RECEIVE_EMERGECY_SMS = 17,\n        OP_RECEIVE_MMS = 18,\n        OP_RECEIVE_WAP_PUSH = 19,\n        OP_SEND_SMS = 20,\n        OP_READ_ICC_SMS = 21,\n        OP_WRITE_ICC_SMS = 22,\n        OP_WRITE_SETTINGS = 23,\n        OP_SYSTEM_ALERT_WINDOW = 24,\n        OP_ACCESS_NOTIFICATIONS = 25,\n        OP_CAMERA = 26,\n        OP_RECORD_AUDIO = 27,\n        OP_PLAY_AUDIO = 28,\n        OP_READ_CLIPBOARD = 29,\n        OP_WRITE_CLIPBOARD = 30,\n        OP_TAKE_MEDIA_BUTTONS = 31,\n        OP_TAKE_AUDIO_FOCUS = 32,\n        OP_AUDIO_MASTER_VOLUME = 33,\n        OP_AUDIO_VOICE_VOLUME = 34,\n        OP_AUDIO_RING_VOLUME = 35,\n        OP_AUDIO_MEDIA_VOLUME = 36,\n        OP_AUDIO_ALARM_VOLUME = 37,\n        OP_AUDIO_NOTIFICATION_VOLUME = 38,\n        OP_AUDIO_BLUETOOTH_VOLUME = 39,\n        OP_WAKE_LOCK = 40,\n        OP_MONITOR_LOCATION = 41,\n        OP_MONITOR_HIGH_POWER_LOCATION = 42,\n        OP_GET_USAGE_STATS = 43,\n        OP_MUTE_MICROPHONE = 44,\n        OP_TOAST_WINDOW = 45,\n        OP_PROJECT_MEDIA = 46,\n        OP_ACTIVATE_VPN = 47,\n        OP_WRITE_WALLPAPER = 48,\n        OP_ASSIST_STRUCTURE = 49,\n        OP_ASSIST_SCREENSHOT = 50,\n        OP_READ_PHONE_STATE = 51,\n        OP_ADD_VOICEMAIL = 52,\n        OP_USE_SIP = 53,\n        OP_PROCESS_OUTGOING_CALLS = 54,\n        OP_USE_FINGERPRINT = 55,\n        OP_BODY_SENSORS = 56\n    };\n\n    AppOpsManager();\n\n    int32_t checkOp(int32_t op, int32_t uid, const String16& callingPackage);\n    int32_t noteOp(int32_t op, int32_t uid, const String16& callingPackage);\n    int32_t startOp(int32_t op, int32_t uid, const String16& callingPackage);\n    void finishOp(int32_t op, int32_t uid, const String16& callingPackage);\n    void startWatchingMode(int32_t op, const String16& packageName,\n            const sp<IAppOpsCallback>& callback);\n    void stopWatchingMode(const sp<IAppOpsCallback>& callback);\n    int32_t permissionToOpCode(const String16& permission);\n\nprivate:\n    Mutex mLock;\n    sp<IAppOpsService> mService;\n\n    sp<IAppOpsService> getService();\n};\n\n\n}; // namespace android\n// ---------------------------------------------------------------------------\n#endif // ANDROID_APP_OPS_MANAGER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/Binder.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BINDER_H\n#define ANDROID_BINDER_H\n\n#include <atomic>\n#include <stdint.h>\n#include <binder/IBinder.h>\n\n// ---------------------------------------------------------------------------\nnamespace android {\n\nclass BBinder : public IBinder\n{\npublic:\n                        BBinder();\n\n    virtual const String16& getInterfaceDescriptor() const;\n    virtual bool        isBinderAlive() const;\n    virtual status_t    pingBinder();\n    virtual status_t    dump(int fd, const Vector<String16>& args);\n\n    virtual status_t    transact(   uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n\n    virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,\n                                    void* cookie = NULL,\n                                    uint32_t flags = 0);\n\n    virtual status_t    unlinkToDeath(  const wp<DeathRecipient>& recipient,\n                                        void* cookie = NULL,\n                                        uint32_t flags = 0,\n                                        wp<DeathRecipient>* outRecipient = NULL);\n\n    virtual void        attachObject(   const void* objectID,\n                                        void* object,\n                                        void* cleanupCookie,\n                                        object_cleanup_func func);\n    virtual void*       findObject(const void* objectID) const;\n    virtual void        detachObject(const void* objectID);\n\n    virtual BBinder*    localBinder();\n\nprotected:\n    virtual             ~BBinder();\n\n    virtual status_t    onTransact( uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n\nprivate:\n                        BBinder(const BBinder& o);\n            BBinder&    operator=(const BBinder& o);\n\n    class Extras;\n\n    std::atomic<Extras*> mExtras;\n            void*       mReserved0;\n};\n\n// ---------------------------------------------------------------------------\n\nclass BpRefBase : public virtual RefBase\n{\nprotected:\n                            BpRefBase(const sp<IBinder>& o);\n    virtual                 ~BpRefBase();\n    virtual void            onFirstRef();\n    virtual void            onLastStrongRef(const void* id);\n    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);\n\n    inline  IBinder*        remote()                { return mRemote; }\n    inline  IBinder*        remote() const          { return mRemote; }\n\nprivate:\n                            BpRefBase(const BpRefBase& o);\n    BpRefBase&              operator=(const BpRefBase& o);\n\n    IBinder* const          mRemote;\n    RefBase::weakref_type*  mRefs;\n    std::atomic<int32_t>    mState;\n};\n\n}; // namespace android\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_BINDER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/BinderService.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BINDER_SERVICE_H\n#define ANDROID_BINDER_SERVICE_H\n\n#include <stdint.h>\n\n#include <utils/Errors.h>\n#include <utils/String16.h>\n\n#include <binder/IServiceManager.h>\n#include <binder/IPCThreadState.h>\n#include <binder/ProcessState.h>\n#include <binder/IServiceManager.h>\n\n// ---------------------------------------------------------------------------\nnamespace android {\n\ntemplate<typename SERVICE>\nclass BinderService\n{\npublic:\n    static status_t publish(bool allowIsolated = false) {\n        sp<IServiceManager> sm(defaultServiceManager());\n        return sm->addService(\n                String16(SERVICE::getServiceName()),\n                new SERVICE(), allowIsolated);\n    }\n\n    static void publishAndJoinThreadPool(bool allowIsolated = false) {\n        publish(allowIsolated);\n        joinThreadPool();\n    }\n\n    static void instantiate() { publish(); }\n\n    static status_t shutdown() { return NO_ERROR; }\n\nprivate:\n    static void joinThreadPool() {\n        sp<ProcessState> ps(ProcessState::self());\n        ps->startThreadPool();\n        ps->giveThreadPoolName();\n        IPCThreadState::self()->joinThreadPool();\n    }\n};\n\n\n}; // namespace android\n// ---------------------------------------------------------------------------\n#endif // ANDROID_BINDER_SERVICE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/BpBinder.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BPBINDER_H\n#define ANDROID_BPBINDER_H\n\n#include <binder/IBinder.h>\n#include <utils/KeyedVector.h>\n#include <utils/threads.h>\n\n// ---------------------------------------------------------------------------\nnamespace android {\n\nclass BpBinder : public IBinder\n{\npublic:\n                        BpBinder(int32_t handle);\n\n    inline  int32_t     handle() const { return mHandle; }\n\n    virtual const String16&    getInterfaceDescriptor() const;\n    virtual bool        isBinderAlive() const;\n    virtual status_t    pingBinder();\n    virtual status_t    dump(int fd, const Vector<String16>& args);\n\n    virtual status_t    transact(   uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n\n    virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,\n                                    void* cookie = NULL,\n                                    uint32_t flags = 0);\n    virtual status_t    unlinkToDeath(  const wp<DeathRecipient>& recipient,\n                                        void* cookie = NULL,\n                                        uint32_t flags = 0,\n                                        wp<DeathRecipient>* outRecipient = NULL);\n\n    virtual void        attachObject(   const void* objectID,\n                                        void* object,\n                                        void* cleanupCookie,\n                                        object_cleanup_func func);\n    virtual void*       findObject(const void* objectID) const;\n    virtual void        detachObject(const void* objectID);\n\n    virtual BpBinder*   remoteBinder();\n\n            status_t    setConstantData(const void* data, size_t size);\n            void        sendObituary();\n\n    class ObjectManager\n    {\n    public:\n                    ObjectManager();\n                    ~ObjectManager();\n\n        void        attach( const void* objectID,\n                            void* object,\n                            void* cleanupCookie,\n                            IBinder::object_cleanup_func func);\n        void*       find(const void* objectID) const;\n        void        detach(const void* objectID);\n\n        void        kill();\n\n    private:\n                    ObjectManager(const ObjectManager&);\n        ObjectManager& operator=(const ObjectManager&);\n\n        struct entry_t\n        {\n            void* object;\n            void* cleanupCookie;\n            IBinder::object_cleanup_func func;\n        };\n\n        KeyedVector<const void*, entry_t> mObjects;\n    };\n\nprotected:\n    virtual             ~BpBinder();\n    virtual void        onFirstRef();\n    virtual void        onLastStrongRef(const void* id);\n    virtual bool        onIncStrongAttempted(uint32_t flags, const void* id);\n\nprivate:\n    const   int32_t             mHandle;\n\n    struct Obituary {\n        wp<DeathRecipient> recipient;\n        void* cookie;\n        uint32_t flags;\n    };\n\n            void                reportOneDeath(const Obituary& obit);\n            bool                isDescriptorCached() const;\n\n    mutable Mutex               mLock;\n            volatile int32_t    mAlive;\n            volatile int32_t    mObitsSent;\n            Vector<Obituary>*   mObituaries;\n            ObjectManager       mObjects;\n            Parcel*             mConstantData;\n    mutable String16            mDescriptorCache;\n};\n\n}; // namespace android\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_BPBINDER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/BufferedTextOutput.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BUFFEREDTEXTOUTPUT_H\n#define ANDROID_BUFFEREDTEXTOUTPUT_H\n\n#include <binder/TextOutput.h>\n#include <utils/threads.h>\n#include <sys/uio.h>\n\n// ---------------------------------------------------------------------------\nnamespace android {\n\nclass BufferedTextOutput : public TextOutput\n{\npublic:\n    //** Flags for constructor */\n    enum {\n        MULTITHREADED = 0x0001\n    };\n    \n                        BufferedTextOutput(uint32_t flags = 0);\n    virtual             ~BufferedTextOutput();\n    \n    virtual status_t    print(const char* txt, size_t len);\n    virtual void        moveIndent(int delta);\n    \n    virtual void        pushBundle();\n    virtual void        popBundle();\n    \nprotected:\n    virtual status_t    writeLines(const struct iovec& vec, size_t N) = 0;\n\nprivate:\n    struct BufferState;\n    struct ThreadState;\n    \n    static  ThreadState*getThreadState();\n    static  void        threadDestructor(void *st);\n    \n            BufferState*getBuffer() const;\n            \n    uint32_t            mFlags;\n    const int32_t       mSeq;\n    const int32_t       mIndex;\n    \n    Mutex               mLock;\n    BufferState*        mGlobalState;\n};\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_BUFFEREDTEXTOUTPUT_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/Debug.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BINDER_DEBUG_H\n#define ANDROID_BINDER_DEBUG_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\nnamespace android {\n// ---------------------------------------------------------------------------\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nconst char* stringForIndent(int32_t indentLevel);\n\ntypedef void (*debugPrintFunc)(void* cookie, const char* txt);\n\nvoid printTypeCode(uint32_t typeCode,\n    debugPrintFunc func = 0, void* cookie = 0);\n\nvoid printHexData(int32_t indent, const void *buf, size_t length,\n    size_t bytesPerLine=16, int32_t singleLineBytesCutoff=16,\n    size_t alignment=0, bool cArrayStyle=false,\n    debugPrintFunc func = 0, void* cookie = 0);\n\n#ifdef __cplusplus\n}\n#endif\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_BINDER_DEBUG_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/IAppOpsCallback.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n#ifndef ANDROID_IAPP_OPS_CALLBACK_H\n#define ANDROID_IAPP_OPS_CALLBACK_H\n\n#include <binder/IInterface.h>\n\nnamespace android {\n\n// ----------------------------------------------------------------------\n\nclass IAppOpsCallback : public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(AppOpsCallback);\n\n    virtual void opChanged(int32_t op, const String16& packageName) = 0;\n\n    enum {\n        OP_CHANGED_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION\n    };\n};\n\n// ----------------------------------------------------------------------\n\nclass BnAppOpsCallback : public BnInterface<IAppOpsCallback>\n{\npublic:\n    virtual status_t    onTransact( uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_IAPP_OPS_CALLBACK_H\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/IAppOpsService.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n#ifndef ANDROID_IAPP_OPS_SERVICE_H\n#define ANDROID_IAPP_OPS_SERVICE_H\n\n#include <binder/IAppOpsCallback.h>\n#include <binder/IInterface.h>\n\nnamespace android {\n\n// ----------------------------------------------------------------------\n\nclass IAppOpsService : public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(AppOpsService);\n\n    virtual int32_t checkOperation(int32_t code, int32_t uid, const String16& packageName) = 0;\n    virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName) = 0;\n    virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid,\n            const String16& packageName) = 0;\n    virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid,\n            const String16& packageName) = 0;\n    virtual void startWatchingMode(int32_t op, const String16& packageName,\n            const sp<IAppOpsCallback>& callback) = 0;\n    virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) = 0;\n    virtual sp<IBinder> getToken(const sp<IBinder>& clientToken) = 0;\n    virtual int32_t permissionToOpCode(const String16& permission) = 0;\n\n    enum {\n        CHECK_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,\n        NOTE_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+1,\n        START_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+2,\n        FINISH_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+3,\n        START_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+4,\n        STOP_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+5,\n        GET_TOKEN_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+6,\n        PERMISSION_TO_OP_CODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+7,\n    };\n\n    enum {\n        MODE_ALLOWED = 0,\n        MODE_IGNORED = 1,\n        MODE_ERRORED = 2\n    };\n};\n\n// ----------------------------------------------------------------------\n\nclass BnAppOpsService : public BnInterface<IAppOpsService>\n{\npublic:\n    virtual status_t    onTransact( uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_IAPP_OPS_SERVICE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/IBatteryStats.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_IBATTERYSTATS_H\n#define ANDROID_IBATTERYSTATS_H\n\n#include <binder/IInterface.h>\n\nnamespace android {\n\n// ----------------------------------------------------------------------\n\nclass IBatteryStats : public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(BatteryStats);\n\n    virtual void noteStartSensor(int uid, int sensor) = 0;\n    virtual void noteStopSensor(int uid, int sensor) = 0;\n    virtual void noteStartVideo(int uid) = 0;\n    virtual void noteStopVideo(int uid) = 0;\n    virtual void noteStartAudio(int uid) = 0;\n    virtual void noteStopAudio(int uid) = 0;\n    virtual void noteResetVideo() = 0;\n    virtual void noteResetAudio() = 0;\n    virtual void noteFlashlightOn(int uid) = 0;\n    virtual void noteFlashlightOff(int uid) = 0;\n    virtual void noteStartCamera(int uid) = 0;\n    virtual void noteStopCamera(int uid) = 0;\n    virtual void noteResetCamera() = 0;\n    virtual void noteResetFlashlight() = 0;\n\n    enum {\n        NOTE_START_SENSOR_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,\n        NOTE_STOP_SENSOR_TRANSACTION,\n        NOTE_START_VIDEO_TRANSACTION,\n        NOTE_STOP_VIDEO_TRANSACTION,\n        NOTE_START_AUDIO_TRANSACTION,\n        NOTE_STOP_AUDIO_TRANSACTION,\n        NOTE_RESET_VIDEO_TRANSACTION,\n        NOTE_RESET_AUDIO_TRANSACTION,\n        NOTE_FLASHLIGHT_ON_TRANSACTION,\n        NOTE_FLASHLIGHT_OFF_TRANSACTION,\n        NOTE_START_CAMERA_TRANSACTION,\n        NOTE_STOP_CAMERA_TRANSACTION,\n        NOTE_RESET_CAMERA_TRANSACTION,\n        NOTE_RESET_FLASHLIGHT_TRANSACTION\n    };\n};\n\n// ----------------------------------------------------------------------\n\nclass BnBatteryStats : public BnInterface<IBatteryStats>\n{\npublic:\n    virtual status_t    onTransact( uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_IBATTERYSTATS_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/IBinder.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_IBINDER_H\n#define ANDROID_IBINDER_H\n\n#include <utils/Errors.h>\n#include <utils/RefBase.h>\n#include <utils/String16.h>\n#include <utils/Vector.h>\n\n\n// linux/binder.h already defines this, but we can't just include it from there\n// because there are host builds that include this file.\n#ifndef B_PACK_CHARS\n#define B_PACK_CHARS(c1, c2, c3, c4) \\\n    ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4))\n#endif  // B_PACK_CHARS\n\n// ---------------------------------------------------------------------------\nnamespace android {\n\nclass BBinder;\nclass BpBinder;\nclass IInterface;\nclass Parcel;\nclass IResultReceiver;\n\n/**\n * Base class and low-level protocol for a remotable object.\n * You can derive from this class to create an object for which other\n * processes can hold references to it.  Communication between processes\n * (method calls, property get and set) is down through a low-level\n * protocol implemented on top of the transact() API.\n */\nclass IBinder : public virtual RefBase\n{\npublic:\n    enum {\n        FIRST_CALL_TRANSACTION  = 0x00000001,\n        LAST_CALL_TRANSACTION   = 0x00ffffff,\n\n        PING_TRANSACTION        = B_PACK_CHARS('_','P','N','G'),\n        DUMP_TRANSACTION        = B_PACK_CHARS('_','D','M','P'),\n        SHELL_COMMAND_TRANSACTION = B_PACK_CHARS('_','C','M','D'),\n        INTERFACE_TRANSACTION   = B_PACK_CHARS('_', 'N', 'T', 'F'),\n        SYSPROPS_TRANSACTION    = B_PACK_CHARS('_', 'S', 'P', 'R'),\n\n        // Corresponds to TF_ONE_WAY -- an asynchronous call.\n        FLAG_ONEWAY             = 0x00000001\n    };\n\n                          IBinder();\n\n    /**\n     * Check if this IBinder implements the interface named by\n     * @a descriptor.  If it does, the base pointer to it is returned,\n     * which you can safely static_cast<> to the concrete C++ interface.\n     */\n    virtual sp<IInterface>  queryLocalInterface(const String16& descriptor);\n\n    /**\n     * Return the canonical name of the interface provided by this IBinder\n     * object.\n     */\n    virtual const String16& getInterfaceDescriptor() const = 0;\n\n    virtual bool            isBinderAlive() const = 0;\n    virtual status_t        pingBinder() = 0;\n    virtual status_t        dump(int fd, const Vector<String16>& args) = 0;\n    static  status_t        shellCommand(const sp<IBinder>& target, int in, int out, int err,\n                                         Vector<String16>& args,\n                                         const sp<IResultReceiver>& resultReceiver);\n\n    virtual status_t        transact(   uint32_t code,\n                                        const Parcel& data,\n                                        Parcel* reply,\n                                        uint32_t flags = 0) = 0;\n\n    class DeathRecipient : public virtual RefBase\n    {\n    public:\n        virtual void binderDied(const wp<IBinder>& who) = 0;\n    };\n\n    /**\n     * Register the @a recipient for a notification if this binder\n     * goes away.  If this binder object unexpectedly goes away\n     * (typically because its hosting process has been killed),\n     * then DeathRecipient::binderDied() will be called with a reference\n     * to this.\n     *\n     * The @a cookie is optional -- if non-NULL, it should be a\n     * memory address that you own (that is, you know it is unique).\n     *\n     * @note You will only receive death notifications for remote binders,\n     * as local binders by definition can't die without you dying as well.\n     * Trying to use this function on a local binder will result in an\n     * INVALID_OPERATION code being returned and nothing happening.\n     *\n     * @note This link always holds a weak reference to its recipient.\n     *\n     * @note You will only receive a weak reference to the dead\n     * binder.  You should not try to promote this to a strong reference.\n     * (Nor should you need to, as there is nothing useful you can\n     * directly do with it now that it has passed on.)\n     */\n    virtual status_t        linkToDeath(const sp<DeathRecipient>& recipient,\n                                        void* cookie = NULL,\n                                        uint32_t flags = 0) = 0;\n\n    /**\n     * Remove a previously registered death notification.\n     * The @a recipient will no longer be called if this object\n     * dies.  The @a cookie is optional.  If non-NULL, you can\n     * supply a NULL @a recipient, and the recipient previously\n     * added with that cookie will be unlinked.\n     */\n    virtual status_t        unlinkToDeath(  const wp<DeathRecipient>& recipient,\n                                            void* cookie = NULL,\n                                            uint32_t flags = 0,\n                                            wp<DeathRecipient>* outRecipient = NULL) = 0;\n\n    virtual bool            checkSubclass(const void* subclassID) const;\n\n    typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie);\n\n    virtual void            attachObject(   const void* objectID,\n                                            void* object,\n                                            void* cleanupCookie,\n                                            object_cleanup_func func) = 0;\n    virtual void*           findObject(const void* objectID) const = 0;\n    virtual void            detachObject(const void* objectID) = 0;\n\n    virtual BBinder*        localBinder();\n    virtual BpBinder*       remoteBinder();\n\nprotected:\n    virtual          ~IBinder();\n\nprivate:\n};\n\n}; // namespace android\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_IBINDER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/IInterface.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n#ifndef ANDROID_IINTERFACE_H\n#define ANDROID_IINTERFACE_H\n\n#include <binder/Binder.h>\n\nnamespace android {\n\n// ----------------------------------------------------------------------\n\nclass IInterface : public virtual RefBase\n{\npublic:\n            IInterface();\n            static sp<IBinder>  asBinder(const IInterface*);\n            static sp<IBinder>  asBinder(const sp<IInterface>&);\n\nprotected:\n    virtual                     ~IInterface();\n    virtual IBinder*            onAsBinder() = 0;\n};\n\n// ----------------------------------------------------------------------\n\ntemplate<typename INTERFACE>\ninline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)\n{\n    return INTERFACE::asInterface(obj);\n}\n\n// ----------------------------------------------------------------------\n\ntemplate<typename INTERFACE>\nclass BnInterface : public INTERFACE, public BBinder\n{\npublic:\n    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);\n    virtual const String16&     getInterfaceDescriptor() const;\n\nprotected:\n    virtual IBinder*            onAsBinder();\n};\n\n// ----------------------------------------------------------------------\n\ntemplate<typename INTERFACE>\nclass BpInterface : public INTERFACE, public BpRefBase\n{\npublic:\n                                BpInterface(const sp<IBinder>& remote);\n\nprotected:\n    virtual IBinder*            onAsBinder();\n};\n\n// ----------------------------------------------------------------------\n\n#define DECLARE_META_INTERFACE(INTERFACE)                               \\\n    static const android::String16 descriptor;                          \\\n    static android::sp<I##INTERFACE> asInterface(                       \\\n            const android::sp<android::IBinder>& obj);                  \\\n    virtual const android::String16& getInterfaceDescriptor() const;    \\\n    I##INTERFACE();                                                     \\\n    virtual ~I##INTERFACE();                                            \\\n\n\n#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \\\n    const android::String16 I##INTERFACE::descriptor(NAME);             \\\n    const android::String16&                                            \\\n            I##INTERFACE::getInterfaceDescriptor() const {              \\\n        return I##INTERFACE::descriptor;                                \\\n    }                                                                   \\\n    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \\\n            const android::sp<android::IBinder>& obj)                   \\\n    {                                                                   \\\n        android::sp<I##INTERFACE> intr;                                 \\\n        if (obj != NULL) {                                              \\\n            intr = static_cast<I##INTERFACE*>(                          \\\n                obj->queryLocalInterface(                               \\\n                        I##INTERFACE::descriptor).get());               \\\n            if (intr == NULL) {                                         \\\n                intr = new Bp##INTERFACE(obj);                          \\\n            }                                                           \\\n        }                                                               \\\n        return intr;                                                    \\\n    }                                                                   \\\n    I##INTERFACE::I##INTERFACE() { }                                    \\\n    I##INTERFACE::~I##INTERFACE() { }                                   \\\n\n\n#define CHECK_INTERFACE(interface, data, reply)                         \\\n    if (!data.checkInterface(this)) { return PERMISSION_DENIED; }       \\\n\n\n// ----------------------------------------------------------------------\n// No user-serviceable parts after this...\n\ntemplate<typename INTERFACE>\ninline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(\n        const String16& _descriptor)\n{\n    if (_descriptor == INTERFACE::descriptor) return this;\n    return NULL;\n}\n\ntemplate<typename INTERFACE>\ninline const String16& BnInterface<INTERFACE>::getInterfaceDescriptor() const\n{\n    return INTERFACE::getInterfaceDescriptor();\n}\n\ntemplate<typename INTERFACE>\nIBinder* BnInterface<INTERFACE>::onAsBinder()\n{\n    return this;\n}\n\ntemplate<typename INTERFACE>\ninline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)\n    : BpRefBase(remote)\n{\n}\n\ntemplate<typename INTERFACE>\ninline IBinder* BpInterface<INTERFACE>::onAsBinder()\n{\n    return remote();\n}\n    \n// ----------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_IINTERFACE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/IMediaResourceMonitor.h",
    "content": "/*\n * Copyright 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_I_MEDIA_RESOURCE_MONITOR_H\n#define ANDROID_I_MEDIA_RESOURCE_MONITOR_H\n\n#include <binder/IInterface.h>\n\nnamespace android {\n\n// ----------------------------------------------------------------------\n\nclass IMediaResourceMonitor : public IInterface {\npublic:\n    DECLARE_META_INTERFACE(MediaResourceMonitor);\n\n    // Values should be in sync with Intent.EXTRA_MEDIA_RESOURCE_TYPE_XXX.\n    enum {\n        TYPE_VIDEO_CODEC = 0,\n        TYPE_AUDIO_CODEC = 1,\n    };\n\n    virtual void notifyResourceGranted(/*in*/ int32_t pid, /*in*/ const int32_t type) = 0;\n\n    enum {\n        NOTIFY_RESOURCE_GRANTED = IBinder::FIRST_CALL_TRANSACTION,\n    };\n};\n\n// ----------------------------------------------------------------------\n\nclass BnMediaResourceMonitor : public BnInterface<IMediaResourceMonitor> {\npublic:\n    virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,\n            uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_I_MEDIA_RESOURCE_MONITOR_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/IMemory.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_IMEMORY_H\n#define ANDROID_IMEMORY_H\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <sys/mman.h>\n\n#include <utils/RefBase.h>\n#include <utils/Errors.h>\n#include <binder/IInterface.h>\n\nnamespace android {\n\n// ----------------------------------------------------------------------------\n\nclass IMemoryHeap : public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(MemoryHeap);\n\n    // flags returned by getFlags()\n    enum {\n        READ_ONLY   = 0x00000001\n    };\n\n    virtual int         getHeapID() const = 0;\n    virtual void*       getBase() const = 0;\n    virtual size_t      getSize() const = 0;\n    virtual uint32_t    getFlags() const = 0;\n    virtual uint32_t    getOffset() const = 0;\n\n    // these are there just for backward source compatibility\n    int32_t heapID() const { return getHeapID(); }\n    void*   base() const  { return getBase(); }\n    size_t  virtualSize() const { return getSize(); }\n};\n\nclass BnMemoryHeap : public BnInterface<IMemoryHeap>\n{\npublic:\n    virtual status_t onTransact( \n            uint32_t code,\n            const Parcel& data,\n            Parcel* reply,\n            uint32_t flags = 0);\n    \n    BnMemoryHeap();\nprotected:\n    virtual ~BnMemoryHeap();\n};\n\n// ----------------------------------------------------------------------------\n\nclass IMemory : public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(Memory);\n\n    virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const = 0;\n\n    // helpers\n    void* fastPointer(const sp<IBinder>& heap, ssize_t offset) const;\n    void* pointer() const;\n    size_t size() const;\n    ssize_t offset() const;\n};\n\nclass BnMemory : public BnInterface<IMemory>\n{\npublic:\n    virtual status_t onTransact(\n            uint32_t code,\n            const Parcel& data,\n            Parcel* reply,\n            uint32_t flags = 0);\n\n    BnMemory();\nprotected:\n    virtual ~BnMemory();\n};\n\n// ----------------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_IMEMORY_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/IPCThreadState.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_IPC_THREAD_STATE_H\n#define ANDROID_IPC_THREAD_STATE_H\n\n#include <utils/Errors.h>\n#include <binder/Parcel.h>\n#include <binder/ProcessState.h>\n#include <utils/Vector.h>\n\n#if defined(_WIN32)\ntypedef  int  uid_t;\n#endif\n\n// ---------------------------------------------------------------------------\nnamespace android {\n\nclass IPCThreadState\n{\npublic:\n    static  IPCThreadState*     self();\n    static  IPCThreadState*     selfOrNull();  // self(), but won't instantiate\n    \n            sp<ProcessState>    process();\n            \n            status_t            clearLastError();\n\n            pid_t               getCallingPid() const;\n            uid_t               getCallingUid() const;\n\n            void                setStrictModePolicy(int32_t policy);\n            int32_t             getStrictModePolicy() const;\n\n            void                setLastTransactionBinderFlags(int32_t flags);\n            int32_t             getLastTransactionBinderFlags() const;\n\n            int64_t             clearCallingIdentity();\n            void                restoreCallingIdentity(int64_t token);\n            \n            int                 setupPolling(int* fd);\n            status_t            handlePolledCommands();\n            void                flushCommands();\n\n            void                joinThreadPool(bool isMain = true);\n            \n            // Stop the local process.\n            void                stopProcess(bool immediate = true);\n            \n            status_t            transact(int32_t handle,\n                                         uint32_t code, const Parcel& data,\n                                         Parcel* reply, uint32_t flags);\n\n            void                incStrongHandle(int32_t handle);\n            void                decStrongHandle(int32_t handle);\n            void                incWeakHandle(int32_t handle);\n            void                decWeakHandle(int32_t handle);\n            status_t            attemptIncStrongHandle(int32_t handle);\n    static  void                expungeHandle(int32_t handle, IBinder* binder);\n            status_t            requestDeathNotification(   int32_t handle,\n                                                            BpBinder* proxy); \n            status_t            clearDeathNotification( int32_t handle,\n                                                        BpBinder* proxy); \n\n    static  void                shutdown();\n\n    // Call this to disable switching threads to background scheduling when\n    // receiving incoming IPC calls.  This is specifically here for the\n    // Android system process, since it expects to have background apps calling\n    // in to it but doesn't want to acquire locks in its services while in\n    // the background.\n    static  void                disableBackgroundScheduling(bool disable);\n\n            // Call blocks until the number of executing binder threads is less than\n            // the maximum number of binder threads threads allowed for this process.\n            void                blockUntilThreadAvailable();\n\nprivate:\n                                IPCThreadState();\n                                ~IPCThreadState();\n\n            status_t            sendReply(const Parcel& reply, uint32_t flags);\n            status_t            waitForResponse(Parcel *reply,\n                                                status_t *acquireResult=NULL);\n            status_t            talkWithDriver(bool doReceive=true);\n            status_t            writeTransactionData(int32_t cmd,\n                                                     uint32_t binderFlags,\n                                                     int32_t handle,\n                                                     uint32_t code,\n                                                     const Parcel& data,\n                                                     status_t* statusBuffer);\n            status_t            getAndExecuteCommand();\n            status_t            executeCommand(int32_t command);\n            void                processPendingDerefs();\n\n            void                clearCaller();\n\n    static  void                threadDestructor(void *st);\n    static  void                freeBuffer(Parcel* parcel,\n                                           const uint8_t* data, size_t dataSize,\n                                           const binder_size_t* objects, size_t objectsSize,\n                                           void* cookie);\n    \n    const   sp<ProcessState>    mProcess;\n    const   pid_t               mMyThreadId;\n            Vector<BBinder*>    mPendingStrongDerefs;\n            Vector<RefBase::weakref_type*> mPendingWeakDerefs;\n\n            Parcel              mIn;\n            Parcel              mOut;\n            status_t            mLastError;\n            pid_t               mCallingPid;\n            uid_t               mCallingUid;\n            int32_t             mStrictModePolicy;\n            int32_t             mLastTransactionBinderFlags;\n};\n\n}; // namespace android\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_IPC_THREAD_STATE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/IPermissionController.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n#ifndef ANDROID_IPERMISSION_CONTROLLER_H\n#define ANDROID_IPERMISSION_CONTROLLER_H\n\n#include <binder/IInterface.h>\n#include <stdlib.h>\n\nnamespace android {\n\n// ----------------------------------------------------------------------\n\nclass IPermissionController : public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(PermissionController);\n\n    virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid) = 0;\n\n    virtual void getPackagesForUid(const uid_t uid, Vector<String16> &packages) = 0;\n\n    virtual bool isRuntimePermission(const String16& permission) = 0;\n\n    enum {\n        CHECK_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,\n        GET_PACKAGES_FOR_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1,\n        IS_RUNTIME_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 2\n    };\n};\n\n// ----------------------------------------------------------------------\n\nclass BnPermissionController : public BnInterface<IPermissionController>\n{\npublic:\n    virtual status_t    onTransact( uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_IPERMISSION_CONTROLLER_H\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/IProcessInfoService.h",
    "content": "/*\n * Copyright 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_I_PROCESS_INFO_SERVICE_H\n#define ANDROID_I_PROCESS_INFO_SERVICE_H\n\n#include <binder/IInterface.h>\n\nnamespace android {\n\n// ----------------------------------------------------------------------\n\nclass IProcessInfoService : public IInterface {\npublic:\n    DECLARE_META_INTERFACE(ProcessInfoService);\n\n    virtual status_t    getProcessStatesFromPids( size_t length,\n                                                  /*in*/ int32_t* pids,\n                                                  /*out*/ int32_t* states) = 0;\n\n    virtual status_t    getProcessStatesAndOomScoresFromPids( size_t length,\n                                                  /*in*/ int32_t* pids,\n                                                  /*out*/ int32_t* states,\n                                                  /*out*/ int32_t* scores) = 0;\n\n    enum {\n        GET_PROCESS_STATES_FROM_PIDS = IBinder::FIRST_CALL_TRANSACTION,\n        GET_PROCESS_STATES_AND_OOM_SCORES_FROM_PIDS,\n    };\n};\n\n// ----------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_I_PROCESS_INFO_SERVICE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/IResultReceiver.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n#ifndef ANDROID_IRESULT_RECEIVER_H\n#define ANDROID_IRESULT_RECEIVER_H\n\n#include <binder/IInterface.h>\n\nnamespace android {\n\n// ----------------------------------------------------------------------\n\nclass IResultReceiver : public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(ResultReceiver);\n\n    virtual void send(int32_t resultCode) = 0;\n\n    enum {\n        OP_SEND = IBinder::FIRST_CALL_TRANSACTION\n    };\n};\n\n// ----------------------------------------------------------------------\n\nclass BnResultReceiver : public BnInterface<IResultReceiver>\n{\npublic:\n    virtual status_t    onTransact( uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_IRESULT_RECEIVER_H\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/IServiceManager.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n#ifndef ANDROID_ISERVICE_MANAGER_H\n#define ANDROID_ISERVICE_MANAGER_H\n\n#include <binder/IInterface.h>\n#include <binder/IPermissionController.h>\n#include <utils/Vector.h>\n#include <utils/String16.h>\n\nnamespace android {\n\n// ----------------------------------------------------------------------\n\nclass IServiceManager : public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(ServiceManager);\n\n    /**\n     * Retrieve an existing service, blocking for a few seconds\n     * if it doesn't yet exist.\n     */\n    virtual sp<IBinder>         getService( const String16& name) const = 0;\n\n    /**\n     * Retrieve an existing service, non-blocking.\n     */\n    virtual sp<IBinder>         checkService( const String16& name) const = 0;\n\n    /**\n     * Register a service.\n     */\n    virtual status_t            addService( const String16& name,\n                                            const sp<IBinder>& service,\n                                            bool allowIsolated = false) = 0;\n\n    /**\n     * Return list of all existing services.\n     */\n    virtual Vector<String16>    listServices() = 0;\n\n    enum {\n        GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,\n        CHECK_SERVICE_TRANSACTION,\n        ADD_SERVICE_TRANSACTION,\n        LIST_SERVICES_TRANSACTION,\n    };\n};\n\nsp<IServiceManager> defaultServiceManager();\n\ntemplate<typename INTERFACE>\nstatus_t getService(const String16& name, sp<INTERFACE>* outService)\n{\n    const sp<IServiceManager> sm = defaultServiceManager();\n    if (sm != NULL) {\n        *outService = interface_cast<INTERFACE>(sm->getService(name));\n        if ((*outService) != NULL) return NO_ERROR;\n    }\n    return NAME_NOT_FOUND;\n}\n\nbool checkCallingPermission(const String16& permission);\nbool checkCallingPermission(const String16& permission,\n                            int32_t* outPid, int32_t* outUid);\nbool checkPermission(const String16& permission, pid_t pid, uid_t uid);\n\n}; // namespace android\n\n#endif // ANDROID_ISERVICE_MANAGER_H\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/MemoryBase.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_MEMORY_BASE_H\n#define ANDROID_MEMORY_BASE_H\n\n#include <stdlib.h>\n#include <stdint.h>\n\n#include <binder/IMemory.h>\n\n\nnamespace android {\n\n// ---------------------------------------------------------------------------\n\nclass MemoryBase : public BnMemory \n{\npublic:\n    MemoryBase(const sp<IMemoryHeap>& heap, ssize_t offset, size_t size);\n    virtual ~MemoryBase();\n    virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;\n\nprotected:\n    size_t getSize() const { return mSize; }\n    ssize_t getOffset() const { return mOffset; }\n    const sp<IMemoryHeap>& getHeap() const { return mHeap; }\n\nprivate:\n    size_t          mSize;\n    ssize_t         mOffset;\n    sp<IMemoryHeap> mHeap;\n};\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_MEMORY_BASE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/MemoryDealer.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_MEMORY_DEALER_H\n#define ANDROID_MEMORY_DEALER_H\n\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <binder/IMemory.h>\n#include <binder/MemoryHeapBase.h>\n\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass SimpleBestFitAllocator;\n\n// ----------------------------------------------------------------------------\n\nclass MemoryDealer : public RefBase\n{\npublic:\n    MemoryDealer(size_t size, const char* name = 0,\n            uint32_t flags = 0 /* or bits such as MemoryHeapBase::READ_ONLY */ );\n\n    virtual sp<IMemory> allocate(size_t size);\n    virtual void        deallocate(size_t offset);\n    virtual void        dump(const char* what) const;\n\n    // allocations are aligned to some value. return that value so clients can account for it.\n    static size_t      getAllocationAlignment();\n\n    sp<IMemoryHeap> getMemoryHeap() const { return heap(); }\n\nprotected:\n    virtual ~MemoryDealer();\n\nprivate:\n    const sp<IMemoryHeap>&      heap() const;\n    SimpleBestFitAllocator*     allocator() const;\n\n    sp<IMemoryHeap>             mHeap;\n    SimpleBestFitAllocator*     mAllocator;\n};\n\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_MEMORY_DEALER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/MemoryHeapBase.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_MEMORY_HEAP_BASE_H\n#define ANDROID_MEMORY_HEAP_BASE_H\n\n#include <stdlib.h>\n#include <stdint.h>\n\n#include <binder/IMemory.h>\n\n\nnamespace android {\n\n// ---------------------------------------------------------------------------\n\nclass MemoryHeapBase : public virtual BnMemoryHeap\n{\npublic:\n    enum {\n        READ_ONLY = IMemoryHeap::READ_ONLY,\n        // memory won't be mapped locally, but will be mapped in the remote\n        // process.\n        DONT_MAP_LOCALLY = 0x00000100,\n        NO_CACHING = 0x00000200\n    };\n\n    /*\n     * maps the memory referenced by fd. but DOESN'T take ownership\n     * of the filedescriptor (it makes a copy with dup()\n     */\n    MemoryHeapBase(int fd, size_t size, uint32_t flags = 0, uint32_t offset = 0);\n\n    /*\n     * maps memory from the given device\n     */\n    MemoryHeapBase(const char* device, size_t size = 0, uint32_t flags = 0);\n\n    /*\n     * maps memory from ashmem, with the given name for debugging\n     */\n    MemoryHeapBase(size_t size, uint32_t flags = 0, char const* name = NULL);\n\n    virtual ~MemoryHeapBase();\n\n    /* implement IMemoryHeap interface */\n    virtual int         getHeapID() const;\n\n    /* virtual address of the heap. returns MAP_FAILED in case of error */\n    virtual void*       getBase() const;\n\n    virtual size_t      getSize() const;\n    virtual uint32_t    getFlags() const;\n    virtual uint32_t    getOffset() const;\n\n    const char*         getDevice() const;\n\n    /* this closes this heap -- use carefully */\n    void dispose();\n\n    /* this is only needed as a workaround, use only if you know\n     * what you are doing */\n    status_t setDevice(const char* device) {\n        if (mDevice == 0)\n            mDevice = device;\n        return mDevice ? NO_ERROR : ALREADY_EXISTS;\n    }\n\nprotected:\n            MemoryHeapBase();\n    // init() takes ownership of fd\n    status_t init(int fd, void *base, int size,\n            int flags = 0, const char* device = NULL);\n\nprivate:\n    status_t mapfd(int fd, size_t size, uint32_t offset = 0);\n\n    int         mFD;\n    size_t      mSize;\n    void*       mBase;\n    uint32_t    mFlags;\n    const char* mDevice;\n    bool        mNeedUnmap;\n    uint32_t    mOffset;\n};\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_MEMORY_HEAP_BASE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/Parcel.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_PARCEL_H\n#define ANDROID_PARCEL_H\n\n#include <string>\n#include <vector>\n\n#include <cutils/native_handle.h>\n#include <nativehelper/ScopedFd.h>\n#include <utils/Errors.h>\n#include <utils/RefBase.h>\n#include <utils/String16.h>\n#include <utils/Vector.h>\n#include <utils/Flattenable.h>\n#include <linux/binder.h>\n\n#include <binder/IInterface.h>\n#include <binder/Parcelable.h>\n\n// ---------------------------------------------------------------------------\nnamespace android {\n\ntemplate <typename T> class Flattenable;\ntemplate <typename T> class LightFlattenable;\nclass IBinder;\nclass IPCThreadState;\nclass ProcessState;\nclass String8;\nclass TextOutput;\n\nclass Parcel {\n    friend class IPCThreadState;\npublic:\n    class ReadableBlob;\n    class WritableBlob;\n\n                        Parcel();\n                        ~Parcel();\n    \n    const uint8_t*      data() const;\n    size_t              dataSize() const;\n    size_t              dataAvail() const;\n    size_t              dataPosition() const;\n    size_t              dataCapacity() const;\n\n    status_t            setDataSize(size_t size);\n    void                setDataPosition(size_t pos) const;\n    status_t            setDataCapacity(size_t size);\n    \n    status_t            setData(const uint8_t* buffer, size_t len);\n\n    status_t            appendFrom(const Parcel *parcel,\n                                   size_t start, size_t len);\n\n    bool                allowFds() const;\n    bool                pushAllowFds(bool allowFds);\n    void                restoreAllowFds(bool lastValue);\n\n    bool                hasFileDescriptors() const;\n\n    // Writes the RPC header.\n    status_t            writeInterfaceToken(const String16& interface);\n\n    // Parses the RPC header, returning true if the interface name\n    // in the header matches the expected interface from the caller.\n    //\n    // Additionally, enforceInterface does part of the work of\n    // propagating the StrictMode policy mask, populating the current\n    // IPCThreadState, which as an optimization may optionally be\n    // passed in.\n    bool                enforceInterface(const String16& interface,\n                                         IPCThreadState* threadState = NULL) const;\n    bool                checkInterface(IBinder*) const;\n\n    void                freeData();\n\nprivate:\n    const binder_size_t* objects() const;\n\npublic:\n    size_t              objectsCount() const;\n    \n    status_t            errorCheck() const;\n    void                setError(status_t err);\n    \n    status_t            write(const void* data, size_t len);\n    void*               writeInplace(size_t len);\n    status_t            writeUnpadded(const void* data, size_t len);\n    status_t            writeInt32(int32_t val);\n    status_t            writeUint32(uint32_t val);\n    status_t            writeInt64(int64_t val);\n    status_t            writeUint64(uint64_t val);\n    status_t            writeFloat(float val);\n    status_t            writeDouble(double val);\n    status_t            writeCString(const char* str);\n    status_t            writeString8(const String8& str);\n    status_t            writeString16(const String16& str);\n    status_t            writeString16(const std::unique_ptr<String16>& str);\n    status_t            writeString16(const char16_t* str, size_t len);\n    status_t            writeStrongBinder(const sp<IBinder>& val);\n    status_t            writeWeakBinder(const wp<IBinder>& val);\n    status_t            writeInt32Array(size_t len, const int32_t *val);\n    status_t            writeByteArray(size_t len, const uint8_t *val);\n    status_t            writeBool(bool val);\n    status_t            writeChar(char16_t val);\n    status_t            writeByte(int8_t val);\n\n    // Take a UTF8 encoded string, convert to UTF16, write it to the parcel.\n    status_t            writeUtf8AsUtf16(const std::string& str);\n    status_t            writeUtf8AsUtf16(const std::unique_ptr<std::string>& str);\n\n    status_t            writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val);\n    status_t            writeByteVector(const std::vector<int8_t>& val);\n    status_t            writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val);\n    status_t            writeByteVector(const std::vector<uint8_t>& val);\n    status_t            writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val);\n    status_t            writeInt32Vector(const std::vector<int32_t>& val);\n    status_t            writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val);\n    status_t            writeInt64Vector(const std::vector<int64_t>& val);\n    status_t            writeFloatVector(const std::unique_ptr<std::vector<float>>& val);\n    status_t            writeFloatVector(const std::vector<float>& val);\n    status_t            writeDoubleVector(const std::unique_ptr<std::vector<double>>& val);\n    status_t            writeDoubleVector(const std::vector<double>& val);\n    status_t            writeBoolVector(const std::unique_ptr<std::vector<bool>>& val);\n    status_t            writeBoolVector(const std::vector<bool>& val);\n    status_t            writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val);\n    status_t            writeCharVector(const std::vector<char16_t>& val);\n    status_t            writeString16Vector(\n                            const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val);\n    status_t            writeString16Vector(const std::vector<String16>& val);\n    status_t            writeUtf8VectorAsUtf16Vector(\n                            const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val);\n    status_t            writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val);\n\n    status_t            writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val);\n    status_t            writeStrongBinderVector(const std::vector<sp<IBinder>>& val);\n\n    template<typename T>\n    status_t            writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val);\n    template<typename T>\n    status_t            writeParcelableVector(const std::vector<T>& val);\n\n    template<typename T>\n    status_t            writeNullableParcelable(const std::unique_ptr<T>& parcelable);\n\n    status_t            writeParcelable(const Parcelable& parcelable);\n\n    template<typename T>\n    status_t            write(const Flattenable<T>& val);\n\n    template<typename T>\n    status_t            write(const LightFlattenable<T>& val);\n\n\n    // Place a native_handle into the parcel (the native_handle's file-\n    // descriptors are dup'ed, so it is safe to delete the native_handle\n    // when this function returns).\n    // Doesn't take ownership of the native_handle.\n    status_t            writeNativeHandle(const native_handle* handle);\n    \n    // Place a file descriptor into the parcel.  The given fd must remain\n    // valid for the lifetime of the parcel.\n    // The Parcel does not take ownership of the given fd unless you ask it to.\n    status_t            writeFileDescriptor(int fd, bool takeOwnership = false);\n    \n    // Place a file descriptor into the parcel.  A dup of the fd is made, which\n    // will be closed once the parcel is destroyed.\n    status_t            writeDupFileDescriptor(int fd);\n\n    // Place a file descriptor into the parcel.  This will not affect the\n    // semantics of the smart file descriptor. A new descriptor will be\n    // created, and will be closed when the parcel is destroyed.\n    status_t            writeUniqueFileDescriptor(\n                            const ScopedFd& fd);\n\n    // Place a vector of file desciptors into the parcel. Each descriptor is\n    // dup'd as in writeDupFileDescriptor\n    status_t            writeUniqueFileDescriptorVector(\n                            const std::unique_ptr<std::vector<ScopedFd>>& val);\n    status_t            writeUniqueFileDescriptorVector(\n                            const std::vector<ScopedFd>& val);\n\n    // Writes a blob to the parcel.\n    // If the blob is small, then it is stored in-place, otherwise it is\n    // transferred by way of an anonymous shared memory region.  Prefer sending\n    // immutable blobs if possible since they may be subsequently transferred between\n    // processes without further copying whereas mutable blobs always need to be copied.\n    // The caller should call release() on the blob after writing its contents.\n    status_t            writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob);\n\n    // Write an existing immutable blob file descriptor to the parcel.\n    // This allows the client to send the same blob to multiple processes\n    // as long as it keeps a dup of the blob file descriptor handy for later.\n    status_t            writeDupImmutableBlobFileDescriptor(int fd);\n\n    status_t            writeObject(const flat_binder_object& val, bool nullMetaData);\n\n    // Like Parcel.java's writeNoException().  Just writes a zero int32.\n    // Currently the native implementation doesn't do any of the StrictMode\n    // stack gathering and serialization that the Java implementation does.\n    status_t            writeNoException();\n\n    void                remove(size_t start, size_t amt);\n    \n    status_t            read(void* outData, size_t len) const;\n    const void*         readInplace(size_t len) const;\n    int32_t             readInt32() const;\n    status_t            readInt32(int32_t *pArg) const;\n    uint32_t            readUint32() const;\n    status_t            readUint32(uint32_t *pArg) const;\n    int64_t             readInt64() const;\n    status_t            readInt64(int64_t *pArg) const;\n    uint64_t            readUint64() const;\n    status_t            readUint64(uint64_t *pArg) const;\n    float               readFloat() const;\n    status_t            readFloat(float *pArg) const;\n    double              readDouble() const;\n    status_t            readDouble(double *pArg) const;\n    intptr_t            readIntPtr() const;\n    status_t            readIntPtr(intptr_t *pArg) const;\n    bool                readBool() const;\n    status_t            readBool(bool *pArg) const;\n    char16_t            readChar() const;\n    status_t            readChar(char16_t *pArg) const;\n    int8_t              readByte() const;\n    status_t            readByte(int8_t *pArg) const;\n\n    // Read a UTF16 encoded string, convert to UTF8\n    status_t            readUtf8FromUtf16(std::string* str) const;\n    status_t            readUtf8FromUtf16(std::unique_ptr<std::string>* str) const;\n\n    const char*         readCString() const;\n    String8             readString8() const;\n    String16            readString16() const;\n    status_t            readString16(String16* pArg) const;\n    status_t            readString16(std::unique_ptr<String16>* pArg) const;\n    const char16_t*     readString16Inplace(size_t* outLen) const;\n    sp<IBinder>         readStrongBinder() const;\n    status_t            readStrongBinder(sp<IBinder>* val) const;\n    wp<IBinder>         readWeakBinder() const;\n\n    template<typename T>\n    status_t            readParcelableVector(\n                            std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const;\n    template<typename T>\n    status_t            readParcelableVector(std::vector<T>* val) const;\n\n    status_t            readParcelable(Parcelable* parcelable) const;\n\n    template<typename T>\n    status_t            readParcelable(std::unique_ptr<T>* parcelable) const;\n\n    template<typename T>\n    status_t            readStrongBinder(sp<T>* val) const;\n\n    status_t            readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const;\n    status_t            readStrongBinderVector(std::vector<sp<IBinder>>* val) const;\n\n    status_t            readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const;\n    status_t            readByteVector(std::vector<int8_t>* val) const;\n    status_t            readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const;\n    status_t            readByteVector(std::vector<uint8_t>* val) const;\n    status_t            readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const;\n    status_t            readInt32Vector(std::vector<int32_t>* val) const;\n    status_t            readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const;\n    status_t            readInt64Vector(std::vector<int64_t>* val) const;\n    status_t            readFloatVector(std::unique_ptr<std::vector<float>>* val) const;\n    status_t            readFloatVector(std::vector<float>* val) const;\n    status_t            readDoubleVector(std::unique_ptr<std::vector<double>>* val) const;\n    status_t            readDoubleVector(std::vector<double>* val) const;\n    status_t            readBoolVector(std::unique_ptr<std::vector<bool>>* val) const;\n    status_t            readBoolVector(std::vector<bool>* val) const;\n    status_t            readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const;\n    status_t            readCharVector(std::vector<char16_t>* val) const;\n    status_t            readString16Vector(\n                            std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const;\n    status_t            readString16Vector(std::vector<String16>* val) const;\n    status_t            readUtf8VectorFromUtf16Vector(\n                            std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const;\n    status_t            readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const;\n\n    template<typename T>\n    status_t            read(Flattenable<T>& val) const;\n\n    template<typename T>\n    status_t            read(LightFlattenable<T>& val) const;\n\n    // Like Parcel.java's readExceptionCode().  Reads the first int32\n    // off of a Parcel's header, returning 0 or the negative error\n    // code on exceptions, but also deals with skipping over rich\n    // response headers.  Callers should use this to read & parse the\n    // response headers rather than doing it by hand.\n    int32_t             readExceptionCode() const;\n\n    // Retrieve native_handle from the parcel. This returns a copy of the\n    // parcel's native_handle (the caller takes ownership). The caller\n    // must free the native_handle with native_handle_close() and \n    // native_handle_delete().\n    native_handle*     readNativeHandle() const;\n\n    \n    // Retrieve a file descriptor from the parcel.  This returns the raw fd\n    // in the parcel, which you do not own -- use dup() to get your own copy.\n    int                 readFileDescriptor() const;\n\n    // Retrieve a smart file descriptor from the parcel.\n    status_t            readUniqueFileDescriptor(\n                            ScopedFd* val) const;\n\n\n    // Retrieve a vector of smart file descriptors from the parcel.\n    status_t            readUniqueFileDescriptorVector(\n                            std::unique_ptr<std::vector<ScopedFd>>* val) const;\n    status_t            readUniqueFileDescriptorVector(\n                            std::vector<ScopedFd>* val) const;\n\n    // Reads a blob from the parcel.\n    // The caller should call release() on the blob after reading its contents.\n    status_t            readBlob(size_t len, ReadableBlob* outBlob) const;\n\n    const flat_binder_object* readObject(bool nullMetaData) const;\n\n    // Explicitly close all file descriptors in the parcel.\n    void                closeFileDescriptors();\n\n    // Debugging: get metrics on current allocations.\n    static size_t       getGlobalAllocSize();\n    static size_t       getGlobalAllocCount();\n\nprivate:\n    typedef void        (*release_func)(Parcel* parcel,\n                                        const uint8_t* data, size_t dataSize,\n                                        const binder_size_t* objects, size_t objectsSize,\n                                        void* cookie);\n                        \n    uintptr_t           ipcData() const;\n    size_t              ipcDataSize() const;\n    uintptr_t           ipcObjects() const;\n    size_t              ipcObjectsCount() const;\n    void                ipcSetDataReference(const uint8_t* data, size_t dataSize,\n                                            const binder_size_t* objects, size_t objectsCount,\n                                            release_func relFunc, void* relCookie);\n    \npublic:\n    void                print(TextOutput& to, uint32_t flags = 0) const;\n\nprivate:\n                        Parcel(const Parcel& o);\n    Parcel&             operator=(const Parcel& o);\n    \n    status_t            finishWrite(size_t len);\n    void                releaseObjects();\n    void                acquireObjects();\n    status_t            growData(size_t len);\n    status_t            restartWrite(size_t desired);\n    status_t            continueWrite(size_t desired);\n    status_t            writePointer(uintptr_t val);\n    status_t            readPointer(uintptr_t *pArg) const;\n    uintptr_t           readPointer() const;\n    void                freeDataNoInit();\n    void                initState();\n    void                scanForFds() const;\n                        \n    template<class T>\n    status_t            readAligned(T *pArg) const;\n\n    template<class T>   T readAligned() const;\n\n    template<class T>\n    status_t            writeAligned(T val);\n\n    status_t            writeRawNullableParcelable(const Parcelable*\n                                                   parcelable);\n\n    template<typename T, typename U>\n    status_t            unsafeReadTypedVector(std::vector<T>* val,\n                                              status_t(Parcel::*read_func)(U*) const) const;\n    template<typename T>\n    status_t            readNullableTypedVector(std::unique_ptr<std::vector<T>>* val,\n                                                status_t(Parcel::*read_func)(T*) const) const;\n    template<typename T>\n    status_t            readTypedVector(std::vector<T>* val,\n                                        status_t(Parcel::*read_func)(T*) const) const;\n    template<typename T, typename U>\n    status_t            unsafeWriteTypedVector(const std::vector<T>& val,\n                                               status_t(Parcel::*write_func)(U));\n    template<typename T>\n    status_t            writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,\n                                                 status_t(Parcel::*write_func)(const T&));\n    template<typename T>\n    status_t            writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,\n                                                 status_t(Parcel::*write_func)(T));\n    template<typename T>\n    status_t            writeTypedVector(const std::vector<T>& val,\n                                         status_t(Parcel::*write_func)(const T&));\n    template<typename T>\n    status_t            writeTypedVector(const std::vector<T>& val,\n                                         status_t(Parcel::*write_func)(T));\n\n    status_t            mError;\n    uint8_t*            mData;\n    size_t              mDataSize;\n    size_t              mDataCapacity;\n    mutable size_t      mDataPos;\n    binder_size_t*      mObjects;\n    size_t              mObjectsSize;\n    size_t              mObjectsCapacity;\n    mutable size_t      mNextObjectHint;\n\n    mutable bool        mFdsKnown;\n    mutable bool        mHasFds;\n    bool                mAllowFds;\n\n    release_func        mOwner;\n    void*               mOwnerCookie;\n\n    class Blob {\n    public:\n        Blob();\n        ~Blob();\n\n        void clear();\n        void release();\n        inline size_t size() const { return mSize; }\n        inline int fd() const { return mFd; };\n        inline bool isMutable() const { return mMutable; }\n\n    protected:\n        void init(int fd, void* data, size_t size, bool isMutable);\n\n        int mFd; // owned by parcel so not closed when released\n        void* mData;\n        size_t mSize;\n        bool mMutable;\n    };\n\n    class FlattenableHelperInterface {\n    protected:\n        ~FlattenableHelperInterface() { }\n    public:\n        virtual size_t getFlattenedSize() const = 0;\n        virtual size_t getFdCount() const = 0;\n        virtual status_t flatten(void* buffer, size_t size, int* fds, size_t count) const = 0;\n        virtual status_t unflatten(void const* buffer, size_t size, int const* fds, size_t count) = 0;\n    };\n\n    template<typename T>\n    class FlattenableHelper : public FlattenableHelperInterface {\n        friend class Parcel;\n        const Flattenable<T>& val;\n        explicit FlattenableHelper(const Flattenable<T>& val) : val(val) { }\n\n    public:\n        virtual size_t getFlattenedSize() const {\n            return val.getFlattenedSize();\n        }\n        virtual size_t getFdCount() const {\n            return val.getFdCount();\n        }\n        virtual status_t flatten(void* buffer, size_t size, int* fds, size_t count) const {\n            return val.flatten(buffer, size, fds, count);\n        }\n        virtual status_t unflatten(void const* buffer, size_t size, int const* fds, size_t count) {\n            return const_cast<Flattenable<T>&>(val).unflatten(buffer, size, fds, count);\n        }\n    };\n    status_t write(const FlattenableHelperInterface& val);\n    status_t read(FlattenableHelperInterface& val) const;\n\npublic:\n    class ReadableBlob : public Blob {\n        friend class Parcel;\n    public:\n        inline const void* data() const { return mData; }\n        inline void* mutableData() { return isMutable() ? mData : NULL; }\n    };\n\n    class WritableBlob : public Blob {\n        friend class Parcel;\n    public:\n        inline void* data() { return mData; }\n    };\n\nprivate:\n    size_t mOpenAshmemSize;\n\npublic:\n    // TODO: Remove once ABI can be changed.\n    size_t getBlobAshmemSize() const;\n    size_t getOpenAshmemSize() const;\n};\n\n// ---------------------------------------------------------------------------\n\ntemplate<typename T>\nstatus_t Parcel::write(const Flattenable<T>& val) {\n    const FlattenableHelper<T> helper(val);\n    return write(helper);\n}\n\ntemplate<typename T>\nstatus_t Parcel::write(const LightFlattenable<T>& val) {\n    size_t size(val.getFlattenedSize());\n    if (!val.isFixedSize()) {\n        status_t err = writeInt32(size);\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n    if (size) {\n        void* buffer = writeInplace(size);\n        if (buffer == NULL)\n            return NO_MEMORY;\n        return val.flatten(buffer, size);\n    }\n    return NO_ERROR;\n}\n\ntemplate<typename T>\nstatus_t Parcel::read(Flattenable<T>& val) const {\n    FlattenableHelper<T> helper(val);\n    return read(helper);\n}\n\ntemplate<typename T>\nstatus_t Parcel::read(LightFlattenable<T>& val) const {\n    size_t size;\n    if (val.isFixedSize()) {\n        size = val.getFlattenedSize();\n    } else {\n        int32_t s;\n        status_t err = readInt32(&s);\n        if (err != NO_ERROR) {\n            return err;\n        }\n        size = s;\n    }\n    if (size) {\n        void const* buffer = readInplace(size);\n        return buffer == NULL ? NO_MEMORY :\n                val.unflatten(buffer, size);\n    }\n    return NO_ERROR;\n}\n\ntemplate<typename T>\nstatus_t Parcel::readStrongBinder(sp<T>* val) const {\n    sp<IBinder> tmp;\n    status_t ret = readStrongBinder(&tmp);\n\n    if (ret == OK) {\n        *val = interface_cast<T>(tmp);\n\n        if (val->get() == nullptr) {\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    return ret;\n}\n\ntemplate<typename T, typename U>\nstatus_t Parcel::unsafeReadTypedVector(\n        std::vector<T>* val,\n        status_t(Parcel::*read_func)(U*) const) const {\n    int32_t size;\n    status_t status = this->readInt32(&size);\n\n    if (status != OK) {\n        return status;\n    }\n\n    if (size < 0) {\n        return UNEXPECTED_NULL;\n    }\n\n    val->resize(size);\n\n    for (auto& v: *val) {\n        status = (this->*read_func)(&v);\n\n        if (status != OK) {\n            return status;\n        }\n    }\n\n    return OK;\n}\n\ntemplate<typename T>\nstatus_t Parcel::readTypedVector(std::vector<T>* val,\n                                 status_t(Parcel::*read_func)(T*) const) const {\n    return unsafeReadTypedVector(val, read_func);\n}\n\ntemplate<typename T>\nstatus_t Parcel::readNullableTypedVector(std::unique_ptr<std::vector<T>>* val,\n                                         status_t(Parcel::*read_func)(T*) const) const {\n    const int32_t start = dataPosition();\n    int32_t size;\n    status_t status = readInt32(&size);\n    val->reset();\n\n    if (status != OK || size < 0) {\n        return status;\n    }\n\n    setDataPosition(start);\n    val->reset(new std::vector<T>());\n\n    status = unsafeReadTypedVector(val->get(), read_func);\n\n    if (status != OK) {\n        val->reset();\n    }\n\n    return status;\n}\n\ntemplate<typename T, typename U>\nstatus_t Parcel::unsafeWriteTypedVector(const std::vector<T>& val,\n                                        status_t(Parcel::*write_func)(U)) {\n    if (val.size() > std::numeric_limits<int32_t>::max()) {\n        return BAD_VALUE;\n    }\n\n    status_t status = this->writeInt32(val.size());\n\n    if (status != OK) {\n        return status;\n    }\n\n    for (const auto& item : val) {\n        status = (this->*write_func)(item);\n\n        if (status != OK) {\n            return status;\n        }\n    }\n\n    return OK;\n}\n\ntemplate<typename T>\nstatus_t Parcel::writeTypedVector(const std::vector<T>& val,\n                                  status_t(Parcel::*write_func)(const T&)) {\n    return unsafeWriteTypedVector(val, write_func);\n}\n\ntemplate<typename T>\nstatus_t Parcel::writeTypedVector(const std::vector<T>& val,\n                                  status_t(Parcel::*write_func)(T)) {\n    return unsafeWriteTypedVector(val, write_func);\n}\n\ntemplate<typename T>\nstatus_t Parcel::writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,\n                                          status_t(Parcel::*write_func)(const T&)) {\n    if (val.get() == nullptr) {\n        return this->writeInt32(-1);\n    }\n\n    return unsafeWriteTypedVector(*val, write_func);\n}\n\ntemplate<typename T>\nstatus_t Parcel::writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,\n                                          status_t(Parcel::*write_func)(T)) {\n    if (val.get() == nullptr) {\n        return this->writeInt32(-1);\n    }\n\n    return unsafeWriteTypedVector(*val, write_func);\n}\n\ntemplate<typename T>\nstatus_t Parcel::readParcelableVector(std::vector<T>* val) const {\n    return unsafeReadTypedVector<T, Parcelable>(val, &Parcel::readParcelable);\n}\n\ntemplate<typename T>\nstatus_t Parcel::readParcelableVector(std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const {\n    const int32_t start = dataPosition();\n    int32_t size;\n    status_t status = readInt32(&size);\n    val->reset();\n\n    if (status != OK || size < 0) {\n        return status;\n    }\n\n    setDataPosition(start);\n    val->reset(new std::vector<std::unique_ptr<T>>());\n\n    status = unsafeReadTypedVector(val->get(), &Parcel::readParcelable<T>);\n\n    if (status != OK) {\n        val->reset();\n    }\n\n    return status;\n}\n\ntemplate<typename T>\nstatus_t Parcel::readParcelable(std::unique_ptr<T>* parcelable) const {\n    const int32_t start = dataPosition();\n    int32_t present;\n    status_t status = readInt32(&present);\n    parcelable->reset();\n\n    if (status != OK || !present) {\n        return status;\n    }\n\n    setDataPosition(start);\n    parcelable->reset(new T());\n\n    status = readParcelable(parcelable->get());\n\n    if (status != OK) {\n        parcelable->reset();\n    }\n\n    return status;\n}\n\ntemplate<typename T>\nstatus_t Parcel::writeNullableParcelable(const std::unique_ptr<T>& parcelable) {\n    return writeRawNullableParcelable(parcelable.get());\n}\n\ntemplate<typename T>\nstatus_t Parcel::writeParcelableVector(const std::vector<T>& val) {\n    return unsafeWriteTypedVector<T,const Parcelable&>(val, &Parcel::writeParcelable);\n}\n\ntemplate<typename T>\nstatus_t Parcel::writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val) {\n    if (val.get() == nullptr) {\n        return this->writeInt32(-1);\n    }\n\n    return unsafeWriteTypedVector(*val, &Parcel::writeParcelable);\n}\n\n// ---------------------------------------------------------------------------\n\ninline TextOutput& operator<<(TextOutput& to, const Parcel& parcel)\n{\n    parcel.print(to);\n    return to;\n}\n\n// ---------------------------------------------------------------------------\n\n// Generic acquire and release of objects.\nvoid acquire_object(const sp<ProcessState>& proc,\n                    const flat_binder_object& obj, const void* who);\nvoid release_object(const sp<ProcessState>& proc,\n                    const flat_binder_object& obj, const void* who);\n\nvoid flatten_binder(const sp<ProcessState>& proc,\n                    const sp<IBinder>& binder, flat_binder_object* out);\nvoid flatten_binder(const sp<ProcessState>& proc,\n                    const wp<IBinder>& binder, flat_binder_object* out);\nstatus_t unflatten_binder(const sp<ProcessState>& proc,\n                          const flat_binder_object& flat, sp<IBinder>* out);\nstatus_t unflatten_binder(const sp<ProcessState>& proc,\n                          const flat_binder_object& flat, wp<IBinder>* out);\n\n}; // namespace android\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_PARCEL_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/Parcelable.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_PARCELABLE_H\n#define ANDROID_PARCELABLE_H\n\n#include <vector>\n\n#include <utils/Errors.h>\n#include <utils/String16.h>\n\nnamespace android {\n\nclass Parcel;\n\n// Abstract interface of all parcelables.\nclass Parcelable {\npublic:\n    virtual ~Parcelable() = default;\n\n    // Write |this| parcelable to the given |parcel|.  Keep in mind that\n    // implementations of writeToParcel must be manually kept in sync\n    // with readFromParcel and the Java equivalent versions of these methods.\n    //\n    // Returns android::OK on success and an appropriate error otherwise.\n    virtual status_t writeToParcel(Parcel* parcel) const = 0;\n\n    // Read data from the given |parcel| into |this|.  After readFromParcel\n    // completes, |this| should have equivalent state to the object that\n    // wrote itself to the parcel.\n    //\n    // Returns android::OK on success and an appropriate error otherwise.\n    virtual status_t readFromParcel(const Parcel* parcel) = 0;\n};  // class Parcelable\n\n}  // namespace android\n\n#endif // ANDROID_PARCELABLE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/PermissionCache.h",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef BINDER_PERMISSION_H\n#define BINDER_PERMISSION_H\n\n#include <stdint.h>\n#include <unistd.h>\n\n#include <utils/String16.h>\n#include <utils/Singleton.h>\n#include <utils/SortedVector.h>\n\nnamespace android {\n// ---------------------------------------------------------------------------\n\n/*\n * PermissionCache caches permission checks for a given uid.\n *\n * Currently the cache is not updated when there is a permission change,\n * for instance when an application is uninstalled.\n *\n * IMPORTANT: for the reason stated above, only system permissions are safe\n * to cache. This restriction may be lifted at a later time.\n *\n */\n\nclass PermissionCache : Singleton<PermissionCache> {\n    struct Entry {\n        String16    name;\n        uid_t       uid;\n        bool        granted;\n        inline bool operator < (const Entry& e) const {\n            return (uid == e.uid) ? (name < e.name) : (uid < e.uid);\n        }\n    };\n    mutable Mutex mLock;\n    // we pool all the permission names we see, as many permissions checks\n    // will have identical names\n    SortedVector< String16 > mPermissionNamesPool;\n    // this is our cache per say. it stores pooled names.\n    SortedVector< Entry > mCache;\n\n    // free the whole cache, but keep the permission name pool\n    void purge();\n\n    status_t check(bool* granted,\n            const String16& permission, uid_t uid) const;\n\n    void cache(const String16& permission, uid_t uid, bool granted);\n\npublic:\n    PermissionCache();\n\n    static bool checkCallingPermission(const String16& permission);\n\n    static bool checkCallingPermission(const String16& permission,\n                                int32_t* outPid, int32_t* outUid);\n\n    static bool checkPermission(const String16& permission,\n            pid_t pid, uid_t uid);\n};\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n\n#endif /* BINDER_PERMISSION_H */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/PersistableBundle.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_PERSISTABLE_BUNDLE_H\n#define ANDROID_PERSISTABLE_BUNDLE_H\n\n#include <map>\n#include <vector>\n\n#include <binder/Parcelable.h>\n#include <utils/String16.h>\n#include <utils/StrongPointer.h>\n\nnamespace android {\n\nnamespace os {\n\n/*\n * C++ implementation of PersistableBundle, a mapping from String values to\n * various types that can be saved to persistent and later restored.\n */\nclass PersistableBundle : public Parcelable {\npublic:\n    PersistableBundle() = default;\n    virtual ~PersistableBundle() = default;\n    PersistableBundle(const PersistableBundle& bundle) = default;\n\n    status_t writeToParcel(Parcel* parcel) const override;\n    status_t readFromParcel(const Parcel* parcel) override;\n\n    bool empty() const;\n    size_t size() const;\n    size_t erase(const String16& key);\n\n    /*\n     * Setters for PersistableBundle. Adds a a key-value pair instantiated with\n     * |key| and |value| into the member map appropriate for the type of |value|.\n     * If there is already an existing value for |key|, |value| will replace it.\n     */\n    void putBoolean(const String16& key, bool value);\n    void putInt(const String16& key, int32_t value);\n    void putLong(const String16& key, int64_t value);\n    void putDouble(const String16& key, double value);\n    void putString(const String16& key, const String16& value);\n    void putBooleanVector(const String16& key, const std::vector<bool>& value);\n    void putIntVector(const String16& key, const std::vector<int32_t>& value);\n    void putLongVector(const String16& key, const std::vector<int64_t>& value);\n    void putDoubleVector(const String16& key, const std::vector<double>& value);\n    void putStringVector(const String16& key, const std::vector<String16>& value);\n    void putPersistableBundle(const String16& key, const PersistableBundle& value);\n\n    /*\n     * Getters for PersistableBundle. If |key| exists, these methods write the\n     * value associated with |key| into |out|, and return true. Otherwise, these\n     * methods return false.\n     */\n    bool getBoolean(const String16& key, bool* out) const;\n    bool getInt(const String16& key, int32_t* out) const;\n    bool getLong(const String16& key, int64_t* out) const;\n    bool getDouble(const String16& key, double* out) const;\n    bool getString(const String16& key, String16* out) const;\n    bool getBooleanVector(const String16& key, std::vector<bool>* out) const;\n    bool getIntVector(const String16& key, std::vector<int32_t>* out) const;\n    bool getLongVector(const String16& key, std::vector<int64_t>* out) const;\n    bool getDoubleVector(const String16& key, std::vector<double>* out) const;\n    bool getStringVector(const String16& key, std::vector<String16>* out) const;\n    bool getPersistableBundle(const String16& key, PersistableBundle* out) const;\n\n    friend bool operator==(const PersistableBundle& lhs, const PersistableBundle& rhs) {\n        return (lhs.mBoolMap == rhs.mBoolMap && lhs.mIntMap == rhs.mIntMap &&\n                lhs.mLongMap == rhs.mLongMap && lhs.mDoubleMap == rhs.mDoubleMap &&\n                lhs.mStringMap == rhs.mStringMap && lhs.mBoolVectorMap == rhs.mBoolVectorMap &&\n                lhs.mIntVectorMap == rhs.mIntVectorMap &&\n                lhs.mLongVectorMap == rhs.mLongVectorMap &&\n                lhs.mDoubleVectorMap == rhs.mDoubleVectorMap &&\n                lhs.mStringVectorMap == rhs.mStringVectorMap &&\n                lhs.mPersistableBundleMap == rhs.mPersistableBundleMap);\n    }\n\n    friend bool operator!=(const PersistableBundle& lhs, const PersistableBundle& rhs) {\n        return !(lhs == rhs);\n    }\n\nprivate:\n    status_t writeToParcelInner(Parcel* parcel) const;\n    status_t readFromParcelInner(const Parcel* parcel, size_t length);\n\n    std::map<String16, bool> mBoolMap;\n    std::map<String16, int32_t> mIntMap;\n    std::map<String16, int64_t> mLongMap;\n    std::map<String16, double> mDoubleMap;\n    std::map<String16, String16> mStringMap;\n    std::map<String16, std::vector<bool>> mBoolVectorMap;\n    std::map<String16, std::vector<int32_t>> mIntVectorMap;\n    std::map<String16, std::vector<int64_t>> mLongVectorMap;\n    std::map<String16, std::vector<double>> mDoubleVectorMap;\n    std::map<String16, std::vector<String16>> mStringVectorMap;\n    std::map<String16, PersistableBundle> mPersistableBundleMap;\n};\n\n}  // namespace os\n\n}  // namespace android\n\n#endif  // ANDROID_PERSISTABLE_BUNDLE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/ProcessInfoService.h",
    "content": "/*\n * Copyright 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_PROCESS_INFO_SERVICE_H\n#define ANDROID_PROCESS_INFO_SERVICE_H\n\n#include <binder/IProcessInfoService.h>\n#include <utils/Errors.h>\n#include <utils/Singleton.h>\n#include <sys/types.h>\n\nnamespace android {\n\n// ----------------------------------------------------------------------\n\nclass ProcessInfoService : public Singleton<ProcessInfoService> {\n\n    friend class Singleton<ProcessInfoService>;\n    sp<IProcessInfoService> mProcessInfoService;\n    Mutex mProcessInfoLock;\n\n    ProcessInfoService();\n\n    status_t getProcessStatesImpl(size_t length, /*in*/ int32_t* pids, /*out*/ int32_t* states);\n    void updateBinderLocked();\n\n    static const int BINDER_ATTEMPT_LIMIT = 5;\n\npublic:\n\n    /**\n     * For each PID in the given \"pids\" input array, write the current process state\n     * for that process into the \"states\" output array, or\n     * ActivityManager.PROCESS_STATE_NONEXISTENT * to indicate that no process with the given PID\n     * exists.\n     *\n     * Returns NO_ERROR if this operation was successful, or a negative error code otherwise.\n     */\n    static status_t getProcessStatesFromPids(size_t length, /*in*/ int32_t* pids,\n            /*out*/ int32_t* states) {\n        return ProcessInfoService::getInstance().getProcessStatesImpl(length, /*in*/ pids,\n                /*out*/ states);\n    }\n\n};\n\n// ----------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_PROCESS_INFO_SERVICE_H\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/ProcessState.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_PROCESS_STATE_H\n#define ANDROID_PROCESS_STATE_H\n\n#include <binder/IBinder.h>\n#include <utils/KeyedVector.h>\n#include <utils/String8.h>\n#include <utils/String16.h>\n\n#include <utils/threads.h>\n\n#include <pthread.h>\n\n// ---------------------------------------------------------------------------\nnamespace android {\n\nclass IPCThreadState;\n\nclass ProcessState : public virtual RefBase\n{\npublic:\n    static  sp<ProcessState>    self();\n\n            void                setContextObject(const sp<IBinder>& object);\n            sp<IBinder>         getContextObject(const sp<IBinder>& caller);\n        \n            void                setContextObject(const sp<IBinder>& object,\n                                                 const String16& name);\n            sp<IBinder>         getContextObject(const String16& name,\n                                                 const sp<IBinder>& caller);\n\n            void                startThreadPool();\n                        \n    typedef bool (*context_check_func)(const String16& name,\n                                       const sp<IBinder>& caller,\n                                       void* userData);\n        \n            bool                isContextManager(void) const;\n            bool                becomeContextManager(\n                                    context_check_func checkFunc,\n                                    void* userData);\n\n            sp<IBinder>         getStrongProxyForHandle(int32_t handle);\n            wp<IBinder>         getWeakProxyForHandle(int32_t handle);\n            void                expungeHandle(int32_t handle, IBinder* binder);\n\n            void                spawnPooledThread(bool isMain);\n            \n            status_t            setThreadPoolMaxThreadCount(size_t maxThreads);\n            void                giveThreadPoolName();\n\nprivate:\n    friend class IPCThreadState;\n    \n                                ProcessState();\n                                ~ProcessState();\n\n                                ProcessState(const ProcessState& o);\n            ProcessState&       operator=(const ProcessState& o);\n            String8             makeBinderThreadName();\n\n            struct handle_entry {\n                IBinder* binder;\n                RefBase::weakref_type* refs;\n            };\n\n            handle_entry*       lookupHandleLocked(int32_t handle);\n\n            int                 mDriverFD;\n            void*               mVMStart;\n\n            // Protects thread count variable below.\n            pthread_mutex_t     mThreadCountLock;\n            pthread_cond_t      mThreadCountDecrement;\n            // Number of binder threads current executing a command.\n            size_t              mExecutingThreadsCount;\n            // Maximum number for binder threads allowed for this process.\n            size_t              mMaxThreads;\n            // Time when thread pool was emptied\n            int64_t             mStarvationStartTimeMs;\n\n    mutable Mutex               mLock;  // protects everything below.\n\n            Vector<handle_entry>mHandleToObject;\n\n            bool                mManagesContexts;\n            context_check_func  mBinderContextCheckFunc;\n            void*               mBinderContextUserData;\n\n            KeyedVector<String16, sp<IBinder> >\n                                mContexts;\n\n\n            String8             mRootDir;\n            bool                mThreadPoolStarted;\n    volatile int32_t            mThreadPoolSeq;\n};\n    \n}; // namespace android\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_PROCESS_STATE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/Status.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BINDER_STATUS_H\n#define ANDROID_BINDER_STATUS_H\n\n#include <cstdint>\n\n#include <binder/Parcel.h>\n#include <utils/String8.h>\n\nnamespace android {\nnamespace binder {\n\n// An object similar in function to a status_t except that it understands\n// how exceptions are encoded in the prefix of a Parcel. Used like:\n//\n//     Parcel data;\n//     Parcel reply;\n//     status_t status;\n//     binder::Status remote_exception;\n//     if ((status = data.writeInterfaceToken(interface_descriptor)) != OK ||\n//         (status = data.writeInt32(function_input)) != OK) {\n//         // We failed to write into the memory of our local parcel?\n//     }\n//     if ((status = remote()->transact(transaction, data, &reply)) != OK) {\n//        // Something has gone wrong in the binder driver or libbinder.\n//     }\n//     if ((status = remote_exception.readFromParcel(reply)) != OK) {\n//         // The remote didn't correctly write the exception header to the\n//         // reply.\n//     }\n//     if (!remote_exception.isOk()) {\n//         // The transaction went through correctly, but the remote reported an\n//         // exception during handling.\n//     }\n//\nclass Status final {\npublic:\n    // Keep the exception codes in sync with android/os/Parcel.java.\n    enum Exception {\n        EX_NONE = 0,\n        EX_SECURITY = -1,\n        EX_BAD_PARCELABLE = -2,\n        EX_ILLEGAL_ARGUMENT = -3,\n        EX_NULL_POINTER = -4,\n        EX_ILLEGAL_STATE = -5,\n        EX_NETWORK_MAIN_THREAD = -6,\n        EX_UNSUPPORTED_OPERATION = -7,\n        EX_SERVICE_SPECIFIC = -8,\n\n        // This is special and Java specific; see Parcel.java.\n        EX_HAS_REPLY_HEADER = -128,\n        // This is special, and indicates to C++ binder proxies that the\n        // transaction has failed at a low level.\n        EX_TRANSACTION_FAILED = -129,\n    };\n\n    // A more readable alias for the default constructor.\n    static Status ok();\n    // Authors should explicitly pick whether their integer is:\n    //  - an exception code (EX_* above)\n    //  - service specific error code\n    //  - status_t\n    //\n    //  Prefer a generic exception code when possible, then a service specific\n    //  code, and finally a status_t for low level failures or legacy support.\n    //  Exception codes and service specific errors map to nicer exceptions for\n    //  Java clients.\n    static Status fromExceptionCode(int32_t exceptionCode);\n    static Status fromExceptionCode(int32_t exceptionCode,\n                                    const String8& message);\n    static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode);\n    static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode,\n                                           const String8& message);\n    static Status fromStatusT(status_t status);\n\n    Status() = default;\n    ~Status() = default;\n\n    // Status objects are copyable and contain just simple data.\n    Status(const Status& status) = default;\n    Status(Status&& status) = default;\n    Status& operator=(const Status& status) = default;\n\n    // Bear in mind that if the client or service is a Java endpoint, this\n    // is not the logic which will provide/interpret the data here.\n    status_t readFromParcel(const Parcel& parcel);\n    status_t writeToParcel(Parcel* parcel) const;\n\n    // Set one of the pre-defined exception types defined above.\n    void setException(int32_t ex, const String8& message);\n    // Set a service specific exception with error code.\n    void setServiceSpecificError(int32_t errorCode, const String8& message);\n    // Setting a |status| != OK causes generated code to return |status|\n    // from Binder transactions, rather than writing an exception into the\n    // reply Parcel.  This is the least preferable way of reporting errors.\n    void setFromStatusT(status_t status);\n\n    // Get information about an exception.\n    int32_t exceptionCode() const  { return mException; }\n    const String8& exceptionMessage() const { return mMessage; }\n    status_t transactionError() const {\n        return mException == EX_TRANSACTION_FAILED ? mErrorCode : OK;\n    }\n    int32_t serviceSpecificErrorCode() const {\n        return mException == EX_SERVICE_SPECIFIC ? mErrorCode : 0;\n    }\n\n    bool isOk() const { return mException == EX_NONE; }\n\n    // For logging.\n    String8 toString8() const;\n\nprivate:\n    Status(int32_t exceptionCode, int32_t errorCode);\n    Status(int32_t exceptionCode, int32_t errorCode, const String8& message);\n\n    // If |mException| == EX_TRANSACTION_FAILED, generated code will return\n    // |mErrorCode| as the result of the transaction rather than write an\n    // exception to the reply parcel.\n    //\n    // Otherwise, we always write |mException| to the parcel.\n    // If |mException| !=  EX_NONE, we write |mMessage| as well.\n    // If |mException| == EX_SERVICE_SPECIFIC we write |mErrorCode| as well.\n    int32_t mException = EX_NONE;\n    int32_t mErrorCode = 0;\n    String8 mMessage;\n};  // class Status\n\n// For gtest output logging\ntemplate<typename T>\nT& operator<< (T& stream, const Status& s) {\n    stream << s.toString8().string();\n    return stream;\n}\n\n}  // namespace binder\n}  // namespace android\n\n#endif // ANDROID_BINDER_STATUS_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/binder/TextOutput.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_TEXTOUTPUT_H\n#define ANDROID_TEXTOUTPUT_H\n\n#include <utils/Errors.h>\n\n#include <stdint.h>\n#include <string.h>\n\n// ---------------------------------------------------------------------------\nnamespace android {\n\nclass String8;\nclass String16;\n\nclass TextOutput\n{\npublic:\n                        TextOutput();\n    virtual             ~TextOutput();\n    \n    virtual status_t    print(const char* txt, size_t len) = 0;\n    virtual void        moveIndent(int delta) = 0;\n    \n    class Bundle {\n    public:\n        inline Bundle(TextOutput& to) : mTO(to) { to.pushBundle(); }\n        inline ~Bundle() { mTO.popBundle(); }\n    private:\n        TextOutput&     mTO;\n    };\n    \n    virtual void        pushBundle() = 0;\n    virtual void        popBundle() = 0;\n};\n\n// ---------------------------------------------------------------------------\n\n// Text output stream for printing to the log (via utils/Log.h).\nextern TextOutput& alog;\n\n// Text output stream for printing to stdout.\nextern TextOutput& aout;\n\n// Text output stream for printing to stderr.\nextern TextOutput& aerr;\n\ntypedef TextOutput& (*TextOutputManipFunc)(TextOutput&);\n\nTextOutput& endl(TextOutput& to);\nTextOutput& indent(TextOutput& to);\nTextOutput& dedent(TextOutput& to);\n\nTextOutput& operator<<(TextOutput& to, const char* str);\nTextOutput& operator<<(TextOutput& to, char);     // writes raw character\nTextOutput& operator<<(TextOutput& to, bool);\nTextOutput& operator<<(TextOutput& to, int);\nTextOutput& operator<<(TextOutput& to, long);\nTextOutput& operator<<(TextOutput& to, unsigned int);\nTextOutput& operator<<(TextOutput& to, unsigned long);\nTextOutput& operator<<(TextOutput& to, long long);\nTextOutput& operator<<(TextOutput& to, unsigned long long);\nTextOutput& operator<<(TextOutput& to, float);\nTextOutput& operator<<(TextOutput& to, double);\nTextOutput& operator<<(TextOutput& to, TextOutputManipFunc func);\nTextOutput& operator<<(TextOutput& to, const void*);\nTextOutput& operator<<(TextOutput& to, const String8& val);\nTextOutput& operator<<(TextOutput& to, const String16& val);\n\nclass TypeCode \n{\npublic:\n    inline TypeCode(uint32_t code);\n    inline ~TypeCode();\n\n    inline uint32_t typeCode() const;\n    \nprivate:\n    uint32_t mCode;\n};\n\nTextOutput& operator<<(TextOutput& to, const TypeCode& val);\n\nclass HexDump\n{\npublic:\n    HexDump(const void *buf, size_t size, size_t bytesPerLine=16);\n    inline ~HexDump();\n    \n    inline HexDump& setBytesPerLine(size_t bytesPerLine);\n    inline HexDump& setSingleLineCutoff(int32_t bytes);\n    inline HexDump& setAlignment(size_t alignment);\n    inline HexDump& setCArrayStyle(bool enabled);\n    \n    inline const void* buffer() const;\n    inline size_t size() const;\n    inline size_t bytesPerLine() const;\n    inline int32_t singleLineCutoff() const;\n    inline size_t alignment() const;\n    inline bool carrayStyle() const;\n\nprivate:\n    const void* mBuffer;\n    size_t mSize;\n    size_t mBytesPerLine;\n    int32_t mSingleLineCutoff;\n    size_t mAlignment;\n    bool mCArrayStyle;\n};\n\nTextOutput& operator<<(TextOutput& to, const HexDump& val);\n\n// ---------------------------------------------------------------------------\n// No user servicable parts below.\n\ninline TextOutput& endl(TextOutput& to)\n{\n    to.print(\"\\n\", 1);\n    return to;\n}\n\ninline TextOutput& indent(TextOutput& to)\n{\n    to.moveIndent(1);\n    return to;\n}\n\ninline TextOutput& dedent(TextOutput& to)\n{\n    to.moveIndent(-1);\n    return to;\n}\n\ninline TextOutput& operator<<(TextOutput& to, const char* str)\n{\n    to.print(str, strlen(str));\n    return to;\n}\n\ninline TextOutput& operator<<(TextOutput& to, char c)\n{\n    to.print(&c, 1);\n    return to;\n}\n\ninline TextOutput& operator<<(TextOutput& to, TextOutputManipFunc func)\n{\n    return (*func)(to);\n}\n\ninline TypeCode::TypeCode(uint32_t code) : mCode(code) { }\ninline TypeCode::~TypeCode() { }\ninline uint32_t TypeCode::typeCode() const { return mCode; }\n\ninline HexDump::~HexDump() { }\n\ninline HexDump& HexDump::setBytesPerLine(size_t bytesPerLine) {\n    mBytesPerLine = bytesPerLine; return *this;\n}\ninline HexDump& HexDump::setSingleLineCutoff(int32_t bytes) {\n    mSingleLineCutoff = bytes; return *this;\n}\ninline HexDump& HexDump::setAlignment(size_t alignment) {\n    mAlignment = alignment; return *this;\n}\ninline HexDump& HexDump::setCArrayStyle(bool enabled) {\n    mCArrayStyle = enabled; return *this;\n}\n\ninline const void* HexDump::buffer() const { return mBuffer; }\ninline size_t HexDump::size() const { return mSize; }\ninline size_t HexDump::bytesPerLine() const { return mBytesPerLine; }\ninline int32_t HexDump::singleLineCutoff() const { return mSingleLineCutoff; }\ninline size_t HexDump::alignment() const { return mAlignment; }\ninline bool HexDump::carrayStyle() const { return mCArrayStyle; }\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_TEXTOUTPUT_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/diskusage/dirsize.h",
    "content": "/*\n *\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __LIBDISKUSAGE_DIRSIZE_H\n#define __LIBDISKUSAGE_DIRSIZE_H\n\n#include <stdint.h>\n\n__BEGIN_DECLS\n\nint64_t stat_size(struct stat *s);\nint64_t calculate_dir_size(int dfd);\n\n__END_DECLS\n\n#endif /* __LIBDISKUSAGE_DIRSIZE_H */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/BitTube.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_SENSOR_CHANNEL_H\n#define ANDROID_GUI_SENSOR_CHANNEL_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Errors.h>\n#include <utils/RefBase.h>\n#include <cutils/log.h>\n\n\nnamespace android {\n// ----------------------------------------------------------------------------\nclass Parcel;\n\nclass BitTube : public RefBase\n{\npublic:\n\n    // creates a BitTube with a default (4KB) send buffer\n    BitTube();\n\n    // creates a BitTube with a a specified send and receive buffer size\n    explicit BitTube(size_t bufsize);\n\n    explicit BitTube(const Parcel& data);\n    virtual ~BitTube();\n\n    // check state after construction\n    status_t initCheck() const;\n\n    // get receive file-descriptor\n    int getFd() const;\n\n    // get the send file-descriptor.\n    int getSendFd() const;\n\n    // send objects (sized blobs). All objects are guaranteed to be written or the call fails.\n    template <typename T>\n    static ssize_t sendObjects(const sp<BitTube>& tube,\n            T const* events, size_t count) {\n        return sendObjects(tube, events, count, sizeof(T));\n    }\n\n    // receive objects (sized blobs). If the receiving buffer isn't large enough,\n    // excess messages are silently discarded.\n    template <typename T>\n    static ssize_t recvObjects(const sp<BitTube>& tube,\n            T* events, size_t count) {\n        return recvObjects(tube, events, count, sizeof(T));\n    }\n\n    // parcels this BitTube\n    status_t writeToParcel(Parcel* reply) const;\n\nprivate:\n    void init(size_t rcvbuf, size_t sndbuf);\n\n    // send a message. The write is guaranteed to send the whole message or fail.\n    ssize_t write(void const* vaddr, size_t size);\n\n    // receive a message. the passed buffer must be at least as large as the\n    // write call used to send the message, excess data is silently discarded.\n    ssize_t read(void* vaddr, size_t size);\n\n    int mSendFd;\n    mutable int mReceiveFd;\n\n    static ssize_t sendObjects(const sp<BitTube>& tube,\n            void const* events, size_t count, size_t objSize);\n\n    static ssize_t recvObjects(const sp<BitTube>& tube,\n            void* events, size_t count, size_t objSize);\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_SENSOR_CHANNEL_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/BufferItem.h",
    "content": "/*\n * Copyright 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_BUFFERITEM_H\n#define ANDROID_GUI_BUFFERITEM_H\n\n#include <EGL/egl.h>\n#include <EGL/eglext.h>\n\n#include <ui/Rect.h>\n#include <ui/Region.h>\n\n#include <system/graphics.h>\n\n#include <utils/Flattenable.h>\n#include <utils/StrongPointer.h>\n\nnamespace android {\n\nclass Fence;\nclass GraphicBuffer;\n\nclass BufferItem : public Flattenable<BufferItem> {\n    friend class Flattenable<BufferItem>;\n    size_t getPodSize() const;\n    size_t getFlattenedSize() const;\n    size_t getFdCount() const;\n    status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;\n    status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);\n\n    public:\n    // The default value of mBuf, used to indicate this doesn't correspond to a slot.\n    enum { INVALID_BUFFER_SLOT = -1 };\n    BufferItem();\n    ~BufferItem();\n\n    static const char* scalingModeName(uint32_t scalingMode);\n\n    // mGraphicBuffer points to the buffer allocated for this slot, or is NULL\n    // if the buffer in this slot has been acquired in the past (see\n    // BufferSlot.mAcquireCalled).\n    sp<GraphicBuffer> mGraphicBuffer;\n\n    // mFence is a fence that will signal when the buffer is idle.\n    sp<Fence> mFence;\n\n    // mCrop is the current crop rectangle for this buffer slot.\n    Rect mCrop;\n\n    // mTransform is the current transform flags for this buffer slot.\n    // refer to NATIVE_WINDOW_TRANSFORM_* in <window.h>\n    uint32_t mTransform;\n\n    // mScalingMode is the current scaling mode for this buffer slot.\n    // refer to NATIVE_WINDOW_SCALING_* in <window.h>\n    uint32_t mScalingMode;\n\n    // mTimestamp is the current timestamp for this buffer slot. This gets\n    // to set by queueBuffer each time this slot is queued. This value\n    // is guaranteed to be monotonically increasing for each newly\n    // acquired buffer.\n    union {\n        int64_t mTimestamp;\n        struct {\n            uint32_t mTimestampLo;\n            uint32_t mTimestampHi;\n        };\n    };\n\n    // mIsAutoTimestamp indicates whether mTimestamp was generated\n    // automatically when the buffer was queued.\n    bool mIsAutoTimestamp;\n\n    // mDataSpace is the current dataSpace value for this buffer slot. This gets\n    // set by queueBuffer each time this slot is queued. The meaning of the\n    // dataSpace is format-dependent.\n    android_dataspace mDataSpace;\n\n    // mFrameNumber is the number of the queued frame for this slot.\n    union {\n        uint64_t mFrameNumber;\n        struct {\n            uint32_t mFrameNumberLo;\n            uint32_t mFrameNumberHi;\n        };\n    };\n\n    // mSlot is the slot index of this buffer (default INVALID_BUFFER_SLOT).\n    int mSlot;\n\n    // mIsDroppable whether this buffer was queued with the\n    // property that it can be replaced by a new buffer for the purpose of\n    // making sure dequeueBuffer() won't block.\n    // i.e.: was the BufferQueue in \"mDequeueBufferCannotBlock\" when this buffer\n    // was queued.\n    bool mIsDroppable;\n\n    // Indicates whether this buffer has been seen by a consumer yet\n    bool mAcquireCalled;\n\n    // Indicates this buffer must be transformed by the inverse transform of the screen\n    // it is displayed onto. This is applied after mTransform.\n    bool mTransformToDisplayInverse;\n\n    // Describes the portion of the surface that has been modified since the\n    // previous frame\n    Region mSurfaceDamage;\n\n    // Indicates that the consumer should acquire the next frame as soon as it\n    // can and not wait for a frame to become available. This is only relevant\n    // in shared buffer mode.\n    bool mAutoRefresh;\n\n    // Indicates that this buffer was queued by the producer. When in shared\n    // buffer mode acquire() can return a BufferItem that wasn't in the queue.\n    bool mQueuedBuffer;\n\n    // Indicates that this BufferItem contains a stale buffer which has already\n    // been released by the BufferQueue.\n    bool mIsStale;\n};\n\n} // namespace android\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/BufferItemConsumer.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_BUFFERITEMCONSUMER_H\n#define ANDROID_GUI_BUFFERITEMCONSUMER_H\n\n#include <gui/ConsumerBase.h>\n\n#include <ui/GraphicBuffer.h>\n\n#include <utils/String8.h>\n#include <utils/Vector.h>\n#include <utils/threads.h>\n\n#define ANDROID_GRAPHICS_BUFFERITEMCONSUMER_JNI_ID \"mBufferItemConsumer\"\n\nnamespace android {\n\nclass BufferQueue;\n\n/**\n * BufferItemConsumer is a BufferQueue consumer endpoint that allows clients\n * access to the whole BufferItem entry from BufferQueue. Multiple buffers may\n * be acquired at once, to be used concurrently by the client. This consumer can\n * operate either in synchronous or asynchronous mode.\n */\nclass BufferItemConsumer: public ConsumerBase\n{\n  public:\n    typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;\n\n    enum { DEFAULT_MAX_BUFFERS = -1 };\n    enum { INVALID_BUFFER_SLOT = BufferQueue::INVALID_BUFFER_SLOT };\n    enum { NO_BUFFER_AVAILABLE = BufferQueue::NO_BUFFER_AVAILABLE };\n\n    // Create a new buffer item consumer. The consumerUsage parameter determines\n    // the consumer usage flags passed to the graphics allocator. The\n    // bufferCount parameter specifies how many buffers can be locked for user\n    // access at the same time.\n    // controlledByApp tells whether this consumer is controlled by the\n    // application.\n    BufferItemConsumer(const sp<IGraphicBufferConsumer>& consumer,\n            uint32_t consumerUsage, int bufferCount = DEFAULT_MAX_BUFFERS,\n            bool controlledByApp = false);\n\n    virtual ~BufferItemConsumer();\n\n    // set the name of the BufferItemConsumer that will be used to identify it in\n    // log messages.\n    void setName(const String8& name);\n\n    // Gets the next graphics buffer from the producer, filling out the\n    // passed-in BufferItem structure. Returns NO_BUFFER_AVAILABLE if the queue\n    // of buffers is empty, and INVALID_OPERATION if the maximum number of\n    // buffers is already acquired.\n    //\n    // Only a fixed number of buffers can be acquired at a time, determined by\n    // the construction-time bufferCount parameter. If INVALID_OPERATION is\n    // returned by acquireBuffer, then old buffers must be returned to the\n    // queue by calling releaseBuffer before more buffers can be acquired.\n    //\n    // If waitForFence is true, and the acquired BufferItem has a valid fence object,\n    // acquireBuffer will wait on the fence with no timeout before returning.\n    status_t acquireBuffer(BufferItem* item, nsecs_t presentWhen,\n            bool waitForFence = true);\n\n    // Returns an acquired buffer to the queue, allowing it to be reused. Since\n    // only a fixed number of buffers may be acquired at a time, old buffers\n    // must be released by calling releaseBuffer to ensure new buffers can be\n    // acquired by acquireBuffer. Once a BufferItem is released, the caller must\n    // not access any members of the BufferItem, and should immediately remove\n    // all of its references to the BufferItem itself.\n    status_t releaseBuffer(const BufferItem &item,\n            const sp<Fence>& releaseFence = Fence::NO_FENCE);\n\n};\n\n} // namespace android\n\n#endif // ANDROID_GUI_CPUCONSUMER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/BufferQueue.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_BUFFERQUEUE_H\n#define ANDROID_GUI_BUFFERQUEUE_H\n\n#include <gui/BufferItem.h>\n#include <gui/BufferQueueDefs.h>\n#include <gui/IGraphicBufferConsumer.h>\n#include <gui/IGraphicBufferProducer.h>\n#include <gui/IConsumerListener.h>\n\n// These are only required to keep other parts of the framework with incomplete\n// dependencies building successfully\n#include <gui/IGraphicBufferAlloc.h>\n\nnamespace android {\n\nclass BufferQueue {\npublic:\n    // BufferQueue will keep track of at most this value of buffers.\n    // Attempts at runtime to increase the number of buffers past this will fail.\n    enum { NUM_BUFFER_SLOTS = BufferQueueDefs::NUM_BUFFER_SLOTS };\n    // Used as a placeholder slot# when the value isn't pointing to an existing buffer.\n    enum { INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT };\n    // Alias to <IGraphicBufferConsumer.h> -- please scope from there in future code!\n    enum {\n        NO_BUFFER_AVAILABLE = IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,\n        PRESENT_LATER = IGraphicBufferConsumer::PRESENT_LATER,\n    };\n\n    // When in async mode we reserve two slots in order to guarantee that the\n    // producer and consumer can run asynchronously.\n    enum { MAX_MAX_ACQUIRED_BUFFERS = NUM_BUFFER_SLOTS - 2 };\n\n    // for backward source compatibility\n    typedef ::android::ConsumerListener ConsumerListener;\n\n    // ProxyConsumerListener is a ConsumerListener implementation that keeps a weak\n    // reference to the actual consumer object.  It forwards all calls to that\n    // consumer object so long as it exists.\n    //\n    // This class exists to avoid having a circular reference between the\n    // BufferQueue object and the consumer object.  The reason this can't be a weak\n    // reference in the BufferQueue class is because we're planning to expose the\n    // consumer side of a BufferQueue as a binder interface, which doesn't support\n    // weak references.\n    class ProxyConsumerListener : public BnConsumerListener {\n    public:\n        ProxyConsumerListener(const wp<ConsumerListener>& consumerListener);\n        virtual ~ProxyConsumerListener();\n        virtual void onFrameAvailable(const BufferItem& item) override;\n        virtual void onFrameReplaced(const BufferItem& item) override;\n        virtual void onBuffersReleased() override;\n        virtual void onSidebandStreamChanged() override;\n    private:\n        // mConsumerListener is a weak reference to the IConsumerListener.  This is\n        // the raison d'etre of ProxyConsumerListener.\n        wp<ConsumerListener> mConsumerListener;\n    };\n\n    // BufferQueue manages a pool of gralloc memory slots to be used by\n    // producers and consumers. allocator is used to allocate all the\n    // needed gralloc buffers.\n    static void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,\n            sp<IGraphicBufferConsumer>* outConsumer,\n            const sp<IGraphicBufferAlloc>& allocator = NULL);\n\nprivate:\n    BufferQueue(); // Create through createBufferQueue\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_BUFFERQUEUE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/BufferQueueConsumer.h",
    "content": "/*\n * Copyright 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_BUFFERQUEUECONSUMER_H\n#define ANDROID_GUI_BUFFERQUEUECONSUMER_H\n\n#include <EGL/egl.h>\n#include <EGL/eglext.h>\n\n#include <gui/BufferQueueDefs.h>\n#include <gui/IGraphicBufferConsumer.h>\n\nnamespace android {\n\nclass BufferQueueCore;\n\nclass BufferQueueConsumer : public BnGraphicBufferConsumer {\n\npublic:\n    BufferQueueConsumer(const sp<BufferQueueCore>& core);\n    virtual ~BufferQueueConsumer();\n\n    // acquireBuffer attempts to acquire ownership of the next pending buffer in\n    // the BufferQueue. If no buffer is pending then it returns\n    // NO_BUFFER_AVAILABLE. If a buffer is successfully acquired, the\n    // information about the buffer is returned in BufferItem.  If the buffer\n    // returned had previously been acquired then the BufferItem::mGraphicBuffer\n    // field of buffer is set to NULL and it is assumed that the consumer still\n    // holds a reference to the buffer.\n    //\n    // If expectedPresent is nonzero, it indicates the time when the buffer\n    // will be displayed on screen. If the buffer's timestamp is farther in the\n    // future, the buffer won't be acquired, and PRESENT_LATER will be\n    // returned.  The presentation time is in nanoseconds, and the time base\n    // is CLOCK_MONOTONIC.\n    virtual status_t acquireBuffer(BufferItem* outBuffer,\n            nsecs_t expectedPresent, uint64_t maxFrameNumber = 0) override;\n\n    // See IGraphicBufferConsumer::detachBuffer\n    virtual status_t detachBuffer(int slot);\n\n    // See IGraphicBufferConsumer::attachBuffer\n    virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer);\n\n    // releaseBuffer releases a buffer slot from the consumer back to the\n    // BufferQueue.  This may be done while the buffer's contents are still\n    // being accessed.  The fence will signal when the buffer is no longer\n    // in use. frameNumber is used to indentify the exact buffer returned.\n    //\n    // If releaseBuffer returns STALE_BUFFER_SLOT, then the consumer must free\n    // any references to the just-released buffer that it might have, as if it\n    // had received a onBuffersReleased() call with a mask set for the released\n    // buffer.\n    //\n    // Note that the dependencies on EGL will be removed once we switch to using\n    // the Android HW Sync HAL.\n    virtual status_t releaseBuffer(int slot, uint64_t frameNumber,\n            const sp<Fence>& releaseFence, EGLDisplay display,\n            EGLSyncKHR fence);\n\n    // connect connects a consumer to the BufferQueue.  Only one\n    // consumer may be connected, and when that consumer disconnects the\n    // BufferQueue is placed into the \"abandoned\" state, causing most\n    // interactions with the BufferQueue by the producer to fail.\n    // controlledByApp indicates whether the consumer is controlled by\n    // the application.\n    //\n    // consumerListener may not be NULL.\n    virtual status_t connect(const sp<IConsumerListener>& consumerListener,\n            bool controlledByApp);\n\n    // disconnect disconnects a consumer from the BufferQueue. All\n    // buffers will be freed and the BufferQueue is placed in the \"abandoned\"\n    // state, causing most interactions with the BufferQueue by the producer to\n    // fail.\n    virtual status_t disconnect();\n\n    // getReleasedBuffers sets the value pointed to by outSlotMask to a bit mask\n    // indicating which buffer slots have been released by the BufferQueue\n    // but have not yet been released by the consumer.\n    //\n    // This should be called from the onBuffersReleased() callback.\n    virtual status_t getReleasedBuffers(uint64_t* outSlotMask);\n\n    // setDefaultBufferSize is used to set the size of buffers returned by\n    // dequeueBuffer when a width and height of zero is requested.  Default\n    // is 1x1.\n    virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height);\n\n    // see IGraphicBufferConsumer::setMaxBufferCount\n    virtual status_t setMaxBufferCount(int bufferCount);\n\n    // setMaxAcquiredBufferCount sets the maximum number of buffers that can\n    // be acquired by the consumer at one time (default 1).  This call will\n    // fail if a producer is connected to the BufferQueue.\n    virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers);\n\n    // setConsumerName sets the name used in logging\n    virtual void setConsumerName(const String8& name);\n\n    // setDefaultBufferFormat allows the BufferQueue to create\n    // GraphicBuffers of a defaultFormat if no format is specified\n    // in dequeueBuffer. The initial default is HAL_PIXEL_FORMAT_RGBA_8888.\n    virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat);\n\n    // setDefaultBufferDataSpace allows the BufferQueue to create\n    // GraphicBuffers of a defaultDataSpace if no data space is specified\n    // in queueBuffer.\n    // The initial default is HAL_DATASPACE_UNKNOWN\n    virtual status_t setDefaultBufferDataSpace(\n            android_dataspace defaultDataSpace);\n\n    // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer.\n    // These are merged with the bits passed to dequeueBuffer.  The values are\n    // enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER; the default is 0.\n    virtual status_t setConsumerUsageBits(uint32_t usage);\n\n    // setTransformHint bakes in rotation to buffers so overlays can be used.\n    // The values are enumerated in window.h, e.g.\n    // NATIVE_WINDOW_TRANSFORM_ROT_90.  The default is 0 (no transform).\n    virtual status_t setTransformHint(uint32_t hint);\n\n    // Retrieve the sideband buffer stream, if any.\n    virtual sp<NativeHandle> getSidebandStream() const;\n\n    // dump our state in a String\n    virtual void dump(String8& result, const char* prefix) const;\n\n    // Functions required for backwards compatibility.\n    // These will be modified/renamed in IGraphicBufferConsumer and will be\n    // removed from this class at that time. See b/13306289.\n\n    virtual status_t releaseBuffer(int buf, uint64_t frameNumber,\n            EGLDisplay display, EGLSyncKHR fence,\n            const sp<Fence>& releaseFence) {\n        return releaseBuffer(buf, frameNumber, releaseFence, display, fence);\n    }\n\n    virtual status_t consumerConnect(const sp<IConsumerListener>& consumer,\n            bool controlledByApp) {\n        return connect(consumer, controlledByApp);\n    }\n\n    virtual status_t consumerDisconnect() { return disconnect(); }\n\n    // End functions required for backwards compatibility\n\nprivate:\n    sp<BufferQueueCore> mCore;\n\n    // This references mCore->mSlots. Lock mCore->mMutex while accessing.\n    BufferQueueDefs::SlotsType& mSlots;\n\n    // This is a cached copy of the name stored in the BufferQueueCore.\n    // It's updated during setConsumerName.\n    String8 mConsumerName;\n\n}; // class BufferQueueConsumer\n\n} // namespace android\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/BufferQueueCore.h",
    "content": "/*\n * Copyright 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_BUFFERQUEUECORE_H\n#define ANDROID_GUI_BUFFERQUEUECORE_H\n\n#include <gui/BufferItem.h>\n#include <gui/BufferQueueDefs.h>\n#include <gui/BufferSlot.h>\n\n#include <utils/Condition.h>\n#include <utils/Mutex.h>\n#include <utils/NativeHandle.h>\n#include <utils/RefBase.h>\n#include <utils/String8.h>\n#include <utils/StrongPointer.h>\n#include <utils/Trace.h>\n#include <utils/Vector.h>\n\n#include <list>\n#include <set>\n\n#define BQ_LOGV(x, ...) ALOGV(\"[%s] \" x, mConsumerName.string(), ##__VA_ARGS__)\n#define BQ_LOGD(x, ...) ALOGD(\"[%s] \" x, mConsumerName.string(), ##__VA_ARGS__)\n#define BQ_LOGI(x, ...) ALOGI(\"[%s] \" x, mConsumerName.string(), ##__VA_ARGS__)\n#define BQ_LOGW(x, ...) ALOGW(\"[%s] \" x, mConsumerName.string(), ##__VA_ARGS__)\n#define BQ_LOGE(x, ...) ALOGE(\"[%s] \" x, mConsumerName.string(), ##__VA_ARGS__)\n\n#define ATRACE_BUFFER_INDEX(index)                                   \\\n    if (ATRACE_ENABLED()) {                                          \\\n        char ___traceBuf[1024];                                      \\\n        snprintf(___traceBuf, 1024, \"%s: %d\",                        \\\n                mCore->mConsumerName.string(), (index));             \\\n        android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf);  \\\n    }\n\nnamespace android {\n\nclass IConsumerListener;\nclass IGraphicBufferAlloc;\nclass IProducerListener;\n\nclass BufferQueueCore : public virtual RefBase {\n\n    friend class BufferQueueProducer;\n    friend class BufferQueueConsumer;\n\npublic:\n    // Used as a placeholder slot number when the value isn't pointing to an\n    // existing buffer.\n    enum { INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT };\n\n    // We reserve two slots in order to guarantee that the producer and\n    // consumer can run asynchronously.\n    enum { MAX_MAX_ACQUIRED_BUFFERS = BufferQueueDefs::NUM_BUFFER_SLOTS - 2 };\n\n    enum {\n        // The API number used to indicate the currently connected producer\n        CURRENTLY_CONNECTED_API = -1,\n\n        // The API number used to indicate that no producer is connected\n        NO_CONNECTED_API        = 0,\n    };\n\n    typedef Vector<BufferItem> Fifo;\n\n    // BufferQueueCore manages a pool of gralloc memory slots to be used by\n    // producers and consumers. allocator is used to allocate all the needed\n    // gralloc buffers.\n    BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator = NULL);\n    virtual ~BufferQueueCore();\n\nprivate:\n    // Dump our state in a string\n    void dump(String8& result, const char* prefix) const;\n\n    // getMinUndequeuedBufferCountLocked returns the minimum number of buffers\n    // that must remain in a state other than DEQUEUED. The async parameter\n    // tells whether we're in asynchronous mode.\n    int getMinUndequeuedBufferCountLocked() const;\n\n    // getMinMaxBufferCountLocked returns the minimum number of buffers allowed\n    // given the current BufferQueue state. The async parameter tells whether\n    // we're in asynchonous mode.\n    int getMinMaxBufferCountLocked() const;\n\n    // getMaxBufferCountLocked returns the maximum number of buffers that can be\n    // allocated at once. This value depends on the following member variables:\n    //\n    //     mMaxDequeuedBufferCount\n    //     mMaxAcquiredBufferCount\n    //     mMaxBufferCount\n    //     mAsyncMode\n    //     mDequeueBufferCannotBlock\n    //\n    // Any time one of these member variables is changed while a producer is\n    // connected, mDequeueCondition must be broadcast.\n    int getMaxBufferCountLocked() const;\n\n    // This performs the same computation but uses the given arguments instead\n    // of the member variables for mMaxBufferCount, mAsyncMode, and\n    // mDequeueBufferCannotBlock.\n    int getMaxBufferCountLocked(bool asyncMode,\n            bool dequeueBufferCannotBlock, int maxBufferCount) const;\n\n    // clearBufferSlotLocked frees the GraphicBuffer and sync resources for the\n    // given slot.\n    void clearBufferSlotLocked(int slot);\n\n    // freeAllBuffersLocked frees the GraphicBuffer and sync resources for\n    // all slots, even if they're currently dequeued, queued, or acquired.\n    void freeAllBuffersLocked();\n\n    // If delta is positive, makes more slots available. If negative, takes\n    // away slots. Returns false if the request can't be met.\n    bool adjustAvailableSlotsLocked(int delta);\n\n    // waitWhileAllocatingLocked blocks until mIsAllocating is false.\n    void waitWhileAllocatingLocked() const;\n\n#if DEBUG_ONLY_CODE\n    // validateConsistencyLocked ensures that the free lists are in sync with\n    // the information stored in mSlots\n    void validateConsistencyLocked() const;\n#endif\n\n    // mAllocator is the connection to SurfaceFlinger that is used to allocate\n    // new GraphicBuffer objects.\n    sp<IGraphicBufferAlloc> mAllocator;\n\n    // mMutex is the mutex used to prevent concurrent access to the member\n    // variables of BufferQueueCore objects. It must be locked whenever any\n    // member variable is accessed.\n    mutable Mutex mMutex;\n\n    // mIsAbandoned indicates that the BufferQueue will no longer be used to\n    // consume image buffers pushed to it using the IGraphicBufferProducer\n    // interface. It is initialized to false, and set to true in the\n    // consumerDisconnect method. A BufferQueue that is abandoned will return\n    // the NO_INIT error from all IGraphicBufferProducer methods capable of\n    // returning an error.\n    bool mIsAbandoned;\n\n    // mConsumerControlledByApp indicates whether the connected consumer is\n    // controlled by the application.\n    bool mConsumerControlledByApp;\n\n    // mConsumerName is a string used to identify the BufferQueue in log\n    // messages. It is set by the IGraphicBufferConsumer::setConsumerName\n    // method.\n    String8 mConsumerName;\n\n    // mConsumerListener is used to notify the connected consumer of\n    // asynchronous events that it may wish to react to. It is initially\n    // set to NULL and is written by consumerConnect and consumerDisconnect.\n    sp<IConsumerListener> mConsumerListener;\n\n    // mConsumerUsageBits contains flags that the consumer wants for\n    // GraphicBuffers.\n    uint32_t mConsumerUsageBits;\n\n    // mConnectedApi indicates the producer API that is currently connected\n    // to this BufferQueue. It defaults to NO_CONNECTED_API, and gets updated\n    // by the connect and disconnect methods.\n    int mConnectedApi;\n\n    // mConnectedProducerToken is used to set a binder death notification on\n    // the producer.\n    sp<IProducerListener> mConnectedProducerListener;\n\n    // mSlots is an array of buffer slots that must be mirrored on the producer\n    // side. This allows buffer ownership to be transferred between the producer\n    // and consumer without sending a GraphicBuffer over Binder. The entire\n    // array is initialized to NULL at construction time, and buffers are\n    // allocated for a slot when requestBuffer is called with that slot's index.\n    BufferQueueDefs::SlotsType mSlots;\n\n    // mQueue is a FIFO of queued buffers used in synchronous mode.\n    Fifo mQueue;\n\n    // mFreeSlots contains all of the slots which are FREE and do not currently\n    // have a buffer attached.\n    std::set<int> mFreeSlots;\n\n    // mFreeBuffers contains all of the slots which are FREE and currently have\n    // a buffer attached.\n    std::list<int> mFreeBuffers;\n\n    // mUnusedSlots contains all slots that are currently unused. They should be\n    // free and not have a buffer attached.\n    std::list<int> mUnusedSlots;\n\n    // mActiveBuffers contains all slots which have a non-FREE buffer attached.\n    std::set<int> mActiveBuffers;\n\n    // mDequeueCondition is a condition variable used for dequeueBuffer in\n    // synchronous mode.\n    mutable Condition mDequeueCondition;\n\n    // mDequeueBufferCannotBlock indicates whether dequeueBuffer is allowed to\n    // block. This flag is set during connect when both the producer and\n    // consumer are controlled by the application.\n    bool mDequeueBufferCannotBlock;\n\n    // mDefaultBufferFormat can be set so it will override the buffer format\n    // when it isn't specified in dequeueBuffer.\n    PixelFormat mDefaultBufferFormat;\n\n    // mDefaultWidth holds the default width of allocated buffers. It is used\n    // in dequeueBuffer if a width and height of 0 are specified.\n    uint32_t mDefaultWidth;\n\n    // mDefaultHeight holds the default height of allocated buffers. It is used\n    // in dequeueBuffer if a width and height of 0 are specified.\n    uint32_t mDefaultHeight;\n\n    // mDefaultBufferDataSpace holds the default dataSpace of queued buffers.\n    // It is used in queueBuffer if a dataspace of 0 (HAL_DATASPACE_UNKNOWN)\n    // is specified.\n    android_dataspace mDefaultBufferDataSpace;\n\n    // mMaxBufferCount is the limit on the number of buffers that will be\n    // allocated at one time. This limit can be set by the consumer.\n    int mMaxBufferCount;\n\n    // mMaxAcquiredBufferCount is the number of buffers that the consumer may\n    // acquire at one time. It defaults to 1, and can be changed by the consumer\n    // via setMaxAcquiredBufferCount, but this may only be done while no\n    // producer is connected to the BufferQueue. This value is used to derive\n    // the value returned for the MIN_UNDEQUEUED_BUFFERS query to the producer.\n    int mMaxAcquiredBufferCount;\n\n    // mMaxDequeuedBufferCount is the number of buffers that the producer may\n    // dequeue at one time. It defaults to 1, and can be changed by the producer\n    // via setMaxDequeuedBufferCount.\n    int mMaxDequeuedBufferCount;\n\n    // mBufferHasBeenQueued is true once a buffer has been queued. It is reset\n    // when something causes all buffers to be freed (e.g., changing the buffer\n    // count).\n    bool mBufferHasBeenQueued;\n\n    // mFrameCounter is the free running counter, incremented on every\n    // successful queueBuffer call and buffer allocation.\n    uint64_t mFrameCounter;\n\n    // mTransformHint is used to optimize for screen rotations.\n    uint32_t mTransformHint;\n\n    // mSidebandStream is a handle to the sideband buffer stream, if any\n    sp<NativeHandle> mSidebandStream;\n\n    // mIsAllocating indicates whether a producer is currently trying to allocate buffers (which\n    // releases mMutex while doing the allocation proper). Producers should not modify any of the\n    // FREE slots while this is true. mIsAllocatingCondition is signaled when this value changes to\n    // false.\n    bool mIsAllocating;\n\n    // mIsAllocatingCondition is a condition variable used by producers to wait until mIsAllocating\n    // becomes false.\n    mutable Condition mIsAllocatingCondition;\n\n    // mAllowAllocation determines whether dequeueBuffer is allowed to allocate\n    // new buffers\n    bool mAllowAllocation;\n\n    // mBufferAge tracks the age of the contents of the most recently dequeued\n    // buffer as the number of frames that have elapsed since it was last queued\n    uint64_t mBufferAge;\n\n    // mGenerationNumber stores the current generation number of the attached\n    // producer. Any attempt to attach a buffer with a different generation\n    // number will fail.\n    uint32_t mGenerationNumber;\n\n    // mAsyncMode indicates whether or not async mode is enabled.\n    // In async mode an extra buffer will be allocated to allow the producer to\n    // enqueue buffers without blocking.\n    bool mAsyncMode;\n\n    // mSharedBufferMode indicates whether or not shared buffer mode is enabled.\n    bool mSharedBufferMode;\n\n    // When shared buffer mode is enabled, this indicates whether the consumer\n    // should acquire buffers even if BufferQueue doesn't indicate that they are\n    // available.\n    bool mAutoRefresh;\n\n    // When shared buffer mode is enabled, this tracks which slot contains the\n    // shared buffer.\n    int mSharedBufferSlot;\n\n    // Cached data about the shared buffer in shared buffer mode\n    struct SharedBufferCache {\n        SharedBufferCache(Rect _crop, uint32_t _transform, int _scalingMode,\n                android_dataspace _dataspace)\n        : crop(_crop),\n          transform(_transform),\n          scalingMode(_scalingMode),\n          dataspace(_dataspace) {\n        };\n\n        Rect crop;\n        uint32_t transform;\n        uint32_t scalingMode;\n        android_dataspace dataspace;\n    } mSharedBufferCache;\n\n    // The slot of the last queued buffer\n    int mLastQueuedSlot;\n\n    const uint64_t mUniqueId;\n\n}; // class BufferQueueCore\n\n} // namespace android\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/BufferQueueDefs.h",
    "content": "/*\n * Copyright 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_BUFFERQUEUECOREDEFS_H\n#define ANDROID_GUI_BUFFERQUEUECOREDEFS_H\n\n#include <gui/BufferSlot.h>\n\nnamespace android {\n    class BufferQueueCore;\n\n    namespace BufferQueueDefs {\n        // BufferQueue will keep track of at most this value of buffers.\n        // Attempts at runtime to increase the number of buffers past this\n        // will fail.\n        enum { NUM_BUFFER_SLOTS = 64 };\n\n        typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS];\n    } // namespace BufferQueueDefs\n} // namespace android\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/BufferQueueProducer.h",
    "content": "/*\n * Copyright 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_BUFFERQUEUEPRODUCER_H\n#define ANDROID_GUI_BUFFERQUEUEPRODUCER_H\n\n#include <gui/BufferQueueDefs.h>\n#include <gui/IGraphicBufferProducer.h>\n\nnamespace android {\n\nclass BufferSlot;\n\nclass BufferQueueProducer : public BnGraphicBufferProducer,\n                            private IBinder::DeathRecipient {\npublic:\n    friend class BufferQueue; // Needed to access binderDied\n\n    BufferQueueProducer(const sp<BufferQueueCore>& core);\n    virtual ~BufferQueueProducer();\n\n    // requestBuffer returns the GraphicBuffer for slot N.\n    //\n    // In normal operation, this is called the first time slot N is returned\n    // by dequeueBuffer.  It must be called again if dequeueBuffer returns\n    // flags indicating that previously-returned buffers are no longer valid.\n    virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf);\n\n    // see IGraphicsBufferProducer::setMaxDequeuedBufferCount\n    virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers);\n\n    // see IGraphicsBufferProducer::setAsyncMode\n    virtual status_t setAsyncMode(bool async);\n\n    // dequeueBuffer gets the next buffer slot index for the producer to use.\n    // If a buffer slot is available then that slot index is written to the\n    // location pointed to by the buf argument and a status of OK is returned.\n    // If no slot is available then a status of -EBUSY is returned and buf is\n    // unmodified.\n    //\n    // The outFence parameter will be updated to hold the fence associated with\n    // the buffer. The contents of the buffer must not be overwritten until the\n    // fence signals. If the fence is Fence::NO_FENCE, the buffer may be\n    // written immediately.\n    //\n    // The width and height parameters must be no greater than the minimum of\n    // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv).\n    // An error due to invalid dimensions might not be reported until\n    // updateTexImage() is called.  If width and height are both zero, the\n    // default values specified by setDefaultBufferSize() are used instead.\n    //\n    // If the format is 0, the default format will be used.\n    //\n    // The usage argument specifies gralloc buffer usage flags.  The values\n    // are enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER.  These\n    // will be merged with the usage flags specified by setConsumerUsageBits.\n    //\n    // The return value may be a negative error value or a non-negative\n    // collection of flags.  If the flags are set, the return values are\n    // valid, but additional actions must be performed.\n    //\n    // If IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION is set, the\n    // producer must discard cached GraphicBuffer references for the slot\n    // returned in buf.\n    // If IGraphicBufferProducer::RELEASE_ALL_BUFFERS is set, the producer\n    // must discard cached GraphicBuffer references for all slots.\n    //\n    // In both cases, the producer will need to call requestBuffer to get a\n    // GraphicBuffer handle for the returned slot.\n    virtual status_t dequeueBuffer(int *outSlot, sp<Fence>* outFence,\n            uint32_t width, uint32_t height, PixelFormat format,\n            uint32_t usage);\n\n    // See IGraphicBufferProducer::detachBuffer\n    virtual status_t detachBuffer(int slot);\n\n    // See IGraphicBufferProducer::detachNextBuffer\n    virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,\n            sp<Fence>* outFence);\n\n    // See IGraphicBufferProducer::attachBuffer\n    virtual status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer);\n\n    // queueBuffer returns a filled buffer to the BufferQueue.\n    //\n    // Additional data is provided in the QueueBufferInput struct.  Notably,\n    // a timestamp must be provided for the buffer. The timestamp is in\n    // nanoseconds, and must be monotonically increasing. Its other semantics\n    // (zero point, etc) are producer-specific and should be documented by the\n    // producer.\n    //\n    // The caller may provide a fence that signals when all rendering\n    // operations have completed.  Alternatively, NO_FENCE may be used,\n    // indicating that the buffer is ready immediately.\n    //\n    // Some values are returned in the output struct: the current settings\n    // for default width and height, the current transform hint, and the\n    // number of queued buffers.\n    virtual status_t queueBuffer(int slot,\n            const QueueBufferInput& input, QueueBufferOutput* output);\n\n    // cancelBuffer returns a dequeued buffer to the BufferQueue, but doesn't\n    // queue it for use by the consumer.\n    //\n    // The buffer will not be overwritten until the fence signals.  The fence\n    // will usually be the one obtained from dequeueBuffer.\n    virtual status_t cancelBuffer(int slot, const sp<Fence>& fence);\n\n    // Query native window attributes.  The \"what\" values are enumerated in\n    // window.h (e.g. NATIVE_WINDOW_FORMAT).\n    virtual int query(int what, int* outValue);\n\n    // connect attempts to connect a producer API to the BufferQueue.  This\n    // must be called before any other IGraphicBufferProducer methods are\n    // called except for getAllocator.  A consumer must already be connected.\n    //\n    // This method will fail if connect was previously called on the\n    // BufferQueue and no corresponding disconnect call was made (i.e. if\n    // it's still connected to a producer).\n    //\n    // APIs are enumerated in window.h (e.g. NATIVE_WINDOW_API_CPU).\n    virtual status_t connect(const sp<IProducerListener>& listener,\n            int api, bool producerControlledByApp, QueueBufferOutput* output);\n\n    // disconnect attempts to disconnect a producer API from the BufferQueue.\n    // Calling this method will cause any subsequent calls to other\n    // IGraphicBufferProducer methods to fail except for getAllocator and connect.\n    // Successfully calling connect after this will allow the other methods to\n    // succeed again.\n    //\n    // This method will fail if the the BufferQueue is not currently\n    // connected to the specified producer API.\n    virtual status_t disconnect(int api);\n\n    // Attaches a sideband buffer stream to the IGraphicBufferProducer.\n    //\n    // A sideband stream is a device-specific mechanism for passing buffers\n    // from the producer to the consumer without using dequeueBuffer/\n    // queueBuffer. If a sideband stream is present, the consumer can choose\n    // whether to acquire buffers from the sideband stream or from the queued\n    // buffers.\n    //\n    // Passing NULL or a different stream handle will detach the previous\n    // handle if any.\n    virtual status_t setSidebandStream(const sp<NativeHandle>& stream);\n\n    // See IGraphicBufferProducer::allocateBuffers\n    virtual void allocateBuffers(uint32_t width, uint32_t height,\n            PixelFormat format, uint32_t usage);\n\n    // See IGraphicBufferProducer::allowAllocation\n    virtual status_t allowAllocation(bool allow);\n\n    // See IGraphicBufferProducer::setGenerationNumber\n    virtual status_t setGenerationNumber(uint32_t generationNumber);\n\n    // See IGraphicBufferProducer::getConsumerName\n    virtual String8 getConsumerName() const override;\n\n    // See IGraphicBufferProducer::getNextFrameNumber\n    virtual uint64_t getNextFrameNumber() const override;\n\n    // See IGraphicBufferProducer::setSharedBufferMode\n    virtual status_t setSharedBufferMode(bool sharedBufferMode) override;\n\n    // See IGraphicBufferProducer::setAutoRefresh\n    virtual status_t setAutoRefresh(bool autoRefresh) override;\n\n    // See IGraphicBufferProducer::setDequeueTimeout\n    virtual status_t setDequeueTimeout(nsecs_t timeout) override;\n\n    // See IGraphicBufferProducer::getLastQueuedBuffer\n    virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,\n            sp<Fence>* outFence, float outTransformMatrix[16]) override;\n\n    // See IGraphicBufferProducer::getUniqueId\n    virtual status_t getUniqueId(uint64_t* outId) const override;\n\nprivate:\n    // This is required by the IBinder::DeathRecipient interface\n    virtual void binderDied(const wp<IBinder>& who);\n\n    // Returns the slot of the next free buffer if one is available or\n    // BufferQueueCore::INVALID_BUFFER_SLOT otherwise\n    int getFreeBufferLocked() const;\n\n    // Returns the next free slot if one is available or\n    // BufferQueueCore::INVALID_BUFFER_SLOT otherwise\n    int getFreeSlotLocked() const;\n\n    // waitForFreeSlotThenRelock finds the oldest slot in the FREE state. It may\n    // block if there are no available slots and we are not in non-blocking\n    // mode (producer and consumer controlled by the application). If it blocks,\n    // it will release mCore->mMutex while blocked so that other operations on\n    // the BufferQueue may succeed.\n    enum class FreeSlotCaller {\n        Dequeue,\n        Attach,\n    };\n    status_t waitForFreeSlotThenRelock(FreeSlotCaller caller, int* found) const;\n\n    sp<BufferQueueCore> mCore;\n\n    // This references mCore->mSlots. Lock mCore->mMutex while accessing.\n    BufferQueueDefs::SlotsType& mSlots;\n\n    // This is a cached copy of the name stored in the BufferQueueCore.\n    // It's updated during connect and dequeueBuffer (which should catch\n    // most updates).\n    String8 mConsumerName;\n\n    uint32_t mStickyTransform;\n\n    // This saves the fence from the last queueBuffer, such that the\n    // next queueBuffer call can throttle buffer production. The prior\n    // queueBuffer's fence is not nessessarily available elsewhere,\n    // since the previous buffer might have already been acquired.\n    sp<Fence> mLastQueueBufferFence;\n\n    Rect mLastQueuedCrop;\n    uint32_t mLastQueuedTransform;\n\n    // Take-a-ticket system for ensuring that onFrame* callbacks are called in\n    // the order that frames are queued. While the BufferQueue lock\n    // (mCore->mMutex) is held, a ticket is retained by the producer. After\n    // dropping the BufferQueue lock, the producer must wait on the condition\n    // variable until the current callback ticket matches its retained ticket.\n    Mutex mCallbackMutex;\n    int mNextCallbackTicket; // Protected by mCore->mMutex\n    int mCurrentCallbackTicket; // Protected by mCallbackMutex\n    Condition mCallbackCondition;\n\n    // Sets how long dequeueBuffer or attachBuffer will block if a buffer or\n    // slot is not yet available.\n    nsecs_t mDequeueTimeout;\n\n}; // class BufferQueueProducer\n\n} // namespace android\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/BufferSlot.h",
    "content": "/*\n * Copyright 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_BUFFERSLOT_H\n#define ANDROID_GUI_BUFFERSLOT_H\n\n#include <ui/Fence.h>\n#include <ui/GraphicBuffer.h>\n\n#include <EGL/egl.h>\n#include <EGL/eglext.h>\n\n#include <utils/StrongPointer.h>\n\nnamespace android {\n\nclass Fence;\n\n// BufferState tracks the states in which a buffer slot can be.\nstruct BufferState {\n\n    // All slots are initially FREE (not dequeued, queued, acquired, or shared).\n    BufferState()\n    : mDequeueCount(0),\n      mQueueCount(0),\n      mAcquireCount(0),\n      mShared(false) {\n    }\n\n    uint32_t mDequeueCount;\n    uint32_t mQueueCount;\n    uint32_t mAcquireCount;\n    bool mShared;\n\n    // A buffer can be in one of five states, represented as below:\n    //\n    //         | mShared | mDequeueCount | mQueueCount | mAcquireCount |\n    // --------|---------|---------------|-------------|---------------|\n    // FREE    |  false  |       0       |      0      |       0       |\n    // DEQUEUED|  false  |       1       |      0      |       0       |\n    // QUEUED  |  false  |       0       |      1      |       0       |\n    // ACQUIRED|  false  |       0       |      0      |       1       |\n    // SHARED  |  true   |      any      |     any     |      any      |\n    //\n    // FREE indicates that the buffer is available to be dequeued by the\n    // producer. The slot is \"owned\" by BufferQueue. It transitions to DEQUEUED\n    // when dequeueBuffer is called.\n    //\n    // DEQUEUED indicates that the buffer has been dequeued by the producer, but\n    // has not yet been queued or canceled. The producer may modify the\n    // buffer's contents as soon as the associated release fence is signaled.\n    // The slot is \"owned\" by the producer. It can transition to QUEUED (via\n    // queueBuffer or attachBuffer) or back to FREE (via cancelBuffer or\n    // detachBuffer).\n    //\n    // QUEUED indicates that the buffer has been filled by the producer and\n    // queued for use by the consumer. The buffer contents may continue to be\n    // modified for a finite time, so the contents must not be accessed until\n    // the associated fence is signaled. The slot is \"owned\" by BufferQueue. It\n    // can transition to ACQUIRED (via acquireBuffer) or to FREE (if another\n    // buffer is queued in asynchronous mode).\n    //\n    // ACQUIRED indicates that the buffer has been acquired by the consumer. As\n    // with QUEUED, the contents must not be accessed by the consumer until the\n    // acquire fence is signaled. The slot is \"owned\" by the consumer. It\n    // transitions to FREE when releaseBuffer (or detachBuffer) is called. A\n    // detached buffer can also enter the ACQUIRED state via attachBuffer.\n    //\n    // SHARED indicates that this buffer is being used in shared buffer\n    // mode. It can be in any combination of the other states at the same time,\n    // except for FREE (since that excludes being in any other state). It can\n    // also be dequeued, queued, or acquired multiple times.\n\n    inline bool isFree() const {\n        return !isAcquired() && !isDequeued() && !isQueued();\n    }\n\n    inline bool isDequeued() const {\n        return mDequeueCount > 0;\n    }\n\n    inline bool isQueued() const {\n        return mQueueCount > 0;\n    }\n\n    inline bool isAcquired() const {\n        return mAcquireCount > 0;\n    }\n\n    inline bool isShared() const {\n        return mShared;\n    }\n\n    inline void reset() {\n        *this = BufferState();\n    }\n\n    const char* string() const;\n\n    inline void dequeue() {\n        mDequeueCount++;\n    }\n\n    inline void detachProducer() {\n        if (mDequeueCount > 0) {\n            mDequeueCount--;\n        }\n    }\n\n    inline void attachProducer() {\n        mDequeueCount++;\n    }\n\n    inline void queue() {\n        if (mDequeueCount > 0) {\n            mDequeueCount--;\n        }\n        mQueueCount++;\n    }\n\n    inline void cancel() {\n        if (mDequeueCount > 0) {\n            mDequeueCount--;\n        }\n    }\n\n    inline void freeQueued() {\n        if (mQueueCount > 0) {\n            mQueueCount--;\n        }\n    }\n\n    inline void acquire() {\n        if (mQueueCount > 0) {\n            mQueueCount--;\n        }\n        mAcquireCount++;\n    }\n\n    inline void acquireNotInQueue() {\n        mAcquireCount++;\n    }\n\n    inline void release() {\n        if (mAcquireCount > 0) {\n            mAcquireCount--;\n        }\n    }\n\n    inline void detachConsumer() {\n        if (mAcquireCount > 0) {\n            mAcquireCount--;\n        }\n    }\n\n    inline void attachConsumer() {\n        mAcquireCount++;\n    }\n};\n\nstruct BufferSlot {\n\n    BufferSlot()\n    : mGraphicBuffer(nullptr),\n      mEglDisplay(EGL_NO_DISPLAY),\n      mBufferState(),\n      mRequestBufferCalled(false),\n      mFrameNumber(0),\n      mEglFence(EGL_NO_SYNC_KHR),\n      mFence(Fence::NO_FENCE),\n      mAcquireCalled(false),\n      mNeedsReallocation(false) {\n    }\n\n    // mGraphicBuffer points to the buffer allocated for this slot or is NULL\n    // if no buffer has been allocated.\n    sp<GraphicBuffer> mGraphicBuffer;\n\n    // mEglDisplay is the EGLDisplay used to create EGLSyncKHR objects.\n    EGLDisplay mEglDisplay;\n\n    // mBufferState is the current state of this buffer slot.\n    BufferState mBufferState;\n\n    // mRequestBufferCalled is used for validating that the producer did\n    // call requestBuffer() when told to do so. Technically this is not\n    // needed but useful for debugging and catching producer bugs.\n    bool mRequestBufferCalled;\n\n    // mFrameNumber is the number of the queued frame for this slot.  This\n    // is used to dequeue buffers in LRU order (useful because buffers\n    // may be released before their release fence is signaled).\n    uint64_t mFrameNumber;\n\n    // mEglFence is the EGL sync object that must signal before the buffer\n    // associated with this buffer slot may be dequeued. It is initialized\n    // to EGL_NO_SYNC_KHR when the buffer is created and may be set to a\n    // new sync object in releaseBuffer.  (This is deprecated in favor of\n    // mFence, below.)\n    EGLSyncKHR mEglFence;\n\n    // mFence is a fence which will signal when work initiated by the\n    // previous owner of the buffer is finished. When the buffer is FREE,\n    // the fence indicates when the consumer has finished reading\n    // from the buffer, or when the producer has finished writing if it\n    // called cancelBuffer after queueing some writes. When the buffer is\n    // QUEUED, it indicates when the producer has finished filling the\n    // buffer. When the buffer is DEQUEUED or ACQUIRED, the fence has been\n    // passed to the consumer or producer along with ownership of the\n    // buffer, and mFence is set to NO_FENCE.\n    sp<Fence> mFence;\n\n    // Indicates whether this buffer has been seen by a consumer yet\n    bool mAcquireCalled;\n\n    // Indicates whether the buffer was re-allocated without notifying the\n    // producer. If so, it needs to set the BUFFER_NEEDS_REALLOCATION flag when\n    // dequeued to prevent the producer from using a stale cached buffer.\n    bool mNeedsReallocation;\n};\n\n} // namespace android\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/ConsumerBase.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_CONSUMERBASE_H\n#define ANDROID_GUI_CONSUMERBASE_H\n\n#include <gui/BufferQueue.h>\n\n#include <ui/GraphicBuffer.h>\n\n#include <utils/String8.h>\n#include <utils/Vector.h>\n#include <utils/threads.h>\n#include <gui/IConsumerListener.h>\n\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass String8;\n\n// ConsumerBase is a base class for BufferQueue consumer end-points. It\n// handles common tasks like management of the connection to the BufferQueue\n// and the buffer pool.\nclass ConsumerBase : public virtual RefBase,\n        protected ConsumerListener {\npublic:\n    struct FrameAvailableListener : public virtual RefBase {\n        // See IConsumerListener::onFrame{Available,Replaced}\n        virtual void onFrameAvailable(const BufferItem& item) = 0;\n        virtual void onFrameReplaced(const BufferItem& /* item */) {}\n    };\n\n    virtual ~ConsumerBase();\n\n    // abandon frees all the buffers and puts the ConsumerBase into the\n    // 'abandoned' state.  Once put in this state the ConsumerBase can never\n    // leave it.  When in the 'abandoned' state, all methods of the\n    // IGraphicBufferProducer interface will fail with the NO_INIT error.\n    //\n    // Note that while calling this method causes all the buffers to be freed\n    // from the perspective of the the ConsumerBase, if there are additional\n    // references on the buffers (e.g. if a buffer is referenced by a client\n    // or by OpenGL ES as a texture) then those buffer will remain allocated.\n    void abandon();\n\n    // Returns true if the ConsumerBase is in the 'abandoned' state\n    bool isAbandoned();\n\n    // set the name of the ConsumerBase that will be used to identify it in\n    // log messages.\n    void setName(const String8& name);\n\n    // dump writes the current state to a string. Child classes should add\n    // their state to the dump by overriding the dumpLocked method, which is\n    // called by these methods after locking the mutex.\n    void dump(String8& result) const;\n    void dump(String8& result, const char* prefix) const;\n\n    // setFrameAvailableListener sets the listener object that will be notified\n    // when a new frame becomes available.\n    void setFrameAvailableListener(const wp<FrameAvailableListener>& listener);\n\n    // See IGraphicBufferConsumer::detachBuffer\n    status_t detachBuffer(int slot);\n\n    // See IGraphicBufferConsumer::setDefaultBufferSize\n    status_t setDefaultBufferSize(uint32_t width, uint32_t height);\n\n    // See IGraphicBufferConsumer::setDefaultBufferFormat\n    status_t setDefaultBufferFormat(PixelFormat defaultFormat);\n\n    // See IGraphicBufferConsumer::setDefaultBufferDataSpace\n    status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace);\n\nprivate:\n    ConsumerBase(const ConsumerBase&);\n    void operator=(const ConsumerBase&);\n\nprotected:\n    // ConsumerBase constructs a new ConsumerBase object to consume image\n    // buffers from the given IGraphicBufferConsumer.\n    // The controlledByApp flag indicates that this consumer is under the application's\n    // control.\n    ConsumerBase(const sp<IGraphicBufferConsumer>& consumer, bool controlledByApp = false);\n\n    // onLastStrongRef gets called by RefBase just before the dtor of the most\n    // derived class.  It is used to clean up the buffers so that ConsumerBase\n    // can coordinate the clean-up by calling into virtual methods implemented\n    // by the derived classes.  This would not be possible from the\n    // ConsuemrBase dtor because by the time that gets called the derived\n    // classes have already been destructed.\n    //\n    // This methods should not need to be overridden by derived classes, but\n    // if they are overridden the ConsumerBase implementation must be called\n    // from the derived class.\n    virtual void onLastStrongRef(const void* id);\n\n    // Implementation of the IConsumerListener interface.  These\n    // calls are used to notify the ConsumerBase of asynchronous events in the\n    // BufferQueue.  The onFrameAvailable, onFrameReplaced, and\n    // onBuffersReleased methods should not need to be overridden by derived\n    // classes, but if they are overridden the ConsumerBase implementation must\n    // be called from the derived class. The ConsumerBase version of\n    // onSidebandStreamChanged does nothing and can be overriden by derived\n    // classes if they want the notification.\n    virtual void onFrameAvailable(const BufferItem& item) override;\n    virtual void onFrameReplaced(const BufferItem& item) override;\n    virtual void onBuffersReleased() override;\n    virtual void onSidebandStreamChanged() override;\n\n    // freeBufferLocked frees up the given buffer slot.  If the slot has been\n    // initialized this will release the reference to the GraphicBuffer in that\n    // slot.  Otherwise it has no effect.\n    //\n    // Derived classes should override this method to clean up any state they\n    // keep per slot.  If it is overridden, the derived class's implementation\n    // must call ConsumerBase::freeBufferLocked.\n    //\n    // This method must be called with mMutex locked.\n    virtual void freeBufferLocked(int slotIndex);\n\n    // abandonLocked puts the BufferQueue into the abandoned state, causing\n    // all future operations on it to fail. This method rather than the public\n    // abandon method should be overridden by child classes to add abandon-\n    // time behavior.\n    //\n    // Derived classes should override this method to clean up any object\n    // state they keep (as opposed to per-slot state).  If it is overridden,\n    // the derived class's implementation must call ConsumerBase::abandonLocked.\n    //\n    // This method must be called with mMutex locked.\n    virtual void abandonLocked();\n\n    // dumpLocked dumps the current state of the ConsumerBase object to the\n    // result string.  Each line is prefixed with the string pointed to by the\n    // prefix argument.  The buffer argument points to a buffer that may be\n    // used for intermediate formatting data, and the size of that buffer is\n    // indicated by the size argument.\n    //\n    // Derived classes should override this method to dump their internal\n    // state.  If this method is overridden the derived class's implementation\n    // should call ConsumerBase::dumpLocked.\n    //\n    // This method must be called with mMutex locked.\n    virtual void dumpLocked(String8& result, const char* prefix) const;\n\n    // acquireBufferLocked fetches the next buffer from the BufferQueue and\n    // updates the buffer slot for the buffer returned.\n    //\n    // Derived classes should override this method to perform any\n    // initialization that must take place the first time a buffer is assigned\n    // to a slot.  If it is overridden the derived class's implementation must\n    // call ConsumerBase::acquireBufferLocked.\n    virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen,\n            uint64_t maxFrameNumber = 0);\n\n    // releaseBufferLocked relinquishes control over a buffer, returning that\n    // control to the BufferQueue.\n    //\n    // Derived classes should override this method to perform any cleanup that\n    // must take place when a buffer is released back to the BufferQueue.  If\n    // it is overridden the derived class's implementation must call\n    // ConsumerBase::releaseBufferLocked.e\n    virtual status_t releaseBufferLocked(int slot,\n            const sp<GraphicBuffer> graphicBuffer,\n            EGLDisplay display, EGLSyncKHR eglFence);\n\n    // returns true iff the slot still has the graphicBuffer in it.\n    bool stillTracking(int slot, const sp<GraphicBuffer> graphicBuffer);\n\n    // addReleaseFence* adds the sync points associated with a fence to the set\n    // of sync points that must be reached before the buffer in the given slot\n    // may be used after the slot has been released.  This should be called by\n    // derived classes each time some asynchronous work is kicked off that\n    // references the buffer.\n    status_t addReleaseFence(int slot,\n            const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence);\n    status_t addReleaseFenceLocked(int slot,\n            const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence);\n\n    // Slot contains the information and object references that\n    // ConsumerBase maintains about a BufferQueue buffer slot.\n    struct Slot {\n        // mGraphicBuffer is the Gralloc buffer store in the slot or NULL if\n        // no Gralloc buffer is in the slot.\n        sp<GraphicBuffer> mGraphicBuffer;\n\n        // mFence is a fence which will signal when the buffer associated with\n        // this buffer slot is no longer being used by the consumer and can be\n        // overwritten. The buffer can be dequeued before the fence signals;\n        // the producer is responsible for delaying writes until it signals.\n        sp<Fence> mFence;\n\n        // the frame number of the last acquired frame for this slot\n        uint64_t mFrameNumber;\n    };\n\n    // mSlots stores the buffers that have been allocated by the BufferQueue\n    // for each buffer slot.  It is initialized to null pointers, and gets\n    // filled in with the result of BufferQueue::acquire when the\n    // client dequeues a buffer from a\n    // slot that has not yet been used. The buffer allocated to a slot will also\n    // be replaced if the requested buffer usage or geometry differs from that\n    // of the buffer allocated to a slot.\n    Slot mSlots[BufferQueue::NUM_BUFFER_SLOTS];\n\n    // mAbandoned indicates that the BufferQueue will no longer be used to\n    // consume images buffers pushed to it using the IGraphicBufferProducer\n    // interface. It is initialized to false, and set to true in the abandon\n    // method.  A BufferQueue that has been abandoned will return the NO_INIT\n    // error from all IConsumerBase methods capable of returning an error.\n    bool mAbandoned;\n\n    // mName is a string used to identify the ConsumerBase in log messages.\n    // It can be set by the setName method.\n    String8 mName;\n\n    // mFrameAvailableListener is the listener object that will be called when a\n    // new frame becomes available. If it is not NULL it will be called from\n    // queueBuffer.\n    wp<FrameAvailableListener> mFrameAvailableListener;\n\n    // The ConsumerBase has-a BufferQueue and is responsible for creating this object\n    // if none is supplied\n    sp<IGraphicBufferConsumer> mConsumer;\n\n    // mMutex is the mutex used to prevent concurrent access to the member\n    // variables of ConsumerBase objects. It must be locked whenever the\n    // member variables are accessed or when any of the *Locked methods are\n    // called.\n    //\n    // This mutex is intended to be locked by derived classes.\n    mutable Mutex mMutex;\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_CONSUMERBASE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/CpuConsumer.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_CPUCONSUMER_H\n#define ANDROID_GUI_CPUCONSUMER_H\n\n#include <gui/ConsumerBase.h>\n\n#include <ui/GraphicBuffer.h>\n\n#include <utils/String8.h>\n#include <utils/Vector.h>\n#include <utils/threads.h>\n\n\nnamespace android {\n\nclass BufferQueue;\n\n/**\n * CpuConsumer is a BufferQueue consumer endpoint that allows direct CPU\n * access to the underlying gralloc buffers provided by BufferQueue. Multiple\n * buffers may be acquired by it at once, to be used concurrently by the\n * CpuConsumer owner. Sets gralloc usage flags to be software-read-only.\n * This queue is synchronous by default.\n */\n\nclass CpuConsumer : public ConsumerBase\n{\n  public:\n    typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;\n\n    struct LockedBuffer {\n        uint8_t    *data;\n        uint32_t    width;\n        uint32_t    height;\n        PixelFormat format;\n        uint32_t    stride;\n        Rect        crop;\n        uint32_t    transform;\n        uint32_t    scalingMode;\n        int64_t     timestamp;\n        android_dataspace dataSpace;\n        uint64_t    frameNumber;\n        // this is the same as format, except for formats that are compatible with\n        // a flexible format (e.g. HAL_PIXEL_FORMAT_YCbCr_420_888). In the latter\n        // case this contains that flexible format\n        PixelFormat flexFormat;\n        // Values below are only valid when using HAL_PIXEL_FORMAT_YCbCr_420_888\n        // or compatible format, in which case LockedBuffer::data\n        // contains the Y channel, and stride is the Y channel stride. For other\n        // formats, these will all be 0.\n        uint8_t    *dataCb;\n        uint8_t    *dataCr;\n        uint32_t    chromaStride;\n        uint32_t    chromaStep;\n\n        LockedBuffer() :\n            data(NULL),\n            width(0),\n            height(0),\n            format(PIXEL_FORMAT_NONE),\n            stride(0),\n            crop(Rect::EMPTY_RECT),\n            transform(0),\n            scalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),\n            timestamp(0),\n            dataSpace(HAL_DATASPACE_UNKNOWN),\n            frameNumber(0),\n            flexFormat(PIXEL_FORMAT_NONE),\n            dataCb(NULL),\n            dataCr(NULL),\n            chromaStride(0),\n            chromaStep(0)\n        {}\n    };\n\n    // Create a new CPU consumer. The maxLockedBuffers parameter specifies\n    // how many buffers can be locked for user access at the same time.\n    CpuConsumer(const sp<IGraphicBufferConsumer>& bq,\n            size_t maxLockedBuffers, bool controlledByApp = false);\n\n    virtual ~CpuConsumer();\n\n    // set the name of the CpuConsumer that will be used to identify it in\n    // log messages.\n    void setName(const String8& name);\n\n    // Gets the next graphics buffer from the producer and locks it for CPU use,\n    // filling out the passed-in locked buffer structure with the native pointer\n    // and metadata. Returns BAD_VALUE if no new buffer is available, and\n    // NOT_ENOUGH_DATA if the maximum number of buffers is already locked.\n    //\n    // Only a fixed number of buffers can be locked at a time, determined by the\n    // construction-time maxLockedBuffers parameter. If INVALID_OPERATION is\n    // returned by lockNextBuffer, then old buffers must be returned to the queue\n    // by calling unlockBuffer before more buffers can be acquired.\n    status_t lockNextBuffer(LockedBuffer *nativeBuffer);\n\n    // Returns a locked buffer to the queue, allowing it to be reused. Since\n    // only a fixed number of buffers may be locked at a time, old buffers must\n    // be released by calling unlockBuffer to ensure new buffers can be acquired by\n    // lockNextBuffer.\n    status_t unlockBuffer(const LockedBuffer &nativeBuffer);\n\n  private:\n    // Maximum number of buffers that can be locked at a time\n    size_t mMaxLockedBuffers;\n\n    status_t releaseAcquiredBufferLocked(size_t lockedIdx);\n\n    virtual void freeBufferLocked(int slotIndex);\n\n    // Tracking for buffers acquired by the user\n    struct AcquiredBuffer {\n        // Need to track the original mSlot index and the buffer itself because\n        // the mSlot entry may be freed/reused before the acquired buffer is\n        // released.\n        int mSlot;\n        sp<GraphicBuffer> mGraphicBuffer;\n        void *mBufferPointer;\n\n        AcquiredBuffer() :\n                mSlot(BufferQueue::INVALID_BUFFER_SLOT),\n                mBufferPointer(NULL) {\n        }\n    };\n    Vector<AcquiredBuffer> mAcquiredBuffers;\n\n    // Count of currently locked buffers\n    size_t mCurrentLockedBuffers;\n\n};\n\n} // namespace android\n\n#endif // ANDROID_GUI_CPUCONSUMER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/DisplayEventReceiver.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_DISPLAY_EVENT_H\n#define ANDROID_GUI_DISPLAY_EVENT_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Errors.h>\n#include <utils/RefBase.h>\n#include <utils/Timers.h>\n\n#include <binder/IInterface.h>\n\n// ----------------------------------------------------------------------------\n\nnamespace android {\n\n// ----------------------------------------------------------------------------\n\nclass BitTube;\nclass IDisplayEventConnection;\n\n// ----------------------------------------------------------------------------\n\nclass DisplayEventReceiver {\npublic:\n    enum {\n        DISPLAY_EVENT_VSYNC = 'vsyn',\n        DISPLAY_EVENT_HOTPLUG = 'plug'\n    };\n\n    struct Event {\n\n        struct Header {\n            uint32_t type;\n            uint32_t id;\n            nsecs_t timestamp __attribute__((aligned(8)));\n        };\n\n        struct VSync {\n            uint32_t count;\n        };\n\n        struct Hotplug {\n            bool connected;\n        };\n\n        Header header;\n        union {\n            VSync vsync;\n            Hotplug hotplug;\n        };\n    };\n\npublic:\n    /*\n     * DisplayEventReceiver creates and registers an event connection with\n     * SurfaceFlinger. VSync events are disabled by default. Call setVSyncRate\n     * or requestNextVsync to receive them.\n     * Other events start being delivered immediately.\n     */\n    DisplayEventReceiver();\n\n    /*\n     * ~DisplayEventReceiver severs the connection with SurfaceFlinger, new events\n     * stop being delivered immediately. Note that the queue could have\n     * some events pending. These will be delivered.\n     */\n    ~DisplayEventReceiver();\n\n    /*\n     * initCheck returns the state of DisplayEventReceiver after construction.\n     */\n    status_t initCheck() const;\n\n    /*\n     * getFd returns the file descriptor to use to receive events.\n     * OWNERSHIP IS RETAINED by DisplayEventReceiver. DO NOT CLOSE this\n     * file-descriptor.\n     */\n    int getFd() const;\n\n    /*\n     * getEvents reads events from the queue and returns how many events were\n     * read. Returns 0 if there are no more events or a negative error code.\n     * If NOT_ENOUGH_DATA is returned, the object has become invalid forever, it\n     * should be destroyed and getEvents() shouldn't be called again.\n     */\n    ssize_t getEvents(Event* events, size_t count);\n    static ssize_t getEvents(const sp<BitTube>& dataChannel,\n            Event* events, size_t count);\n\n    /*\n     * sendEvents write events to the queue and returns how many events were\n     * written.\n     */\n    static ssize_t sendEvents(const sp<BitTube>& dataChannel,\n            Event const* events, size_t count);\n\n    /*\n     * setVsyncRate() sets the Event::VSync delivery rate. A value of\n     * 1 returns every Event::VSync. A value of 2 returns every other event,\n     * etc... a value of 0 returns no event unless  requestNextVsync() has\n     * been called.\n     */\n    status_t setVsyncRate(uint32_t count);\n\n    /*\n     * requestNextVsync() schedules the next Event::VSync. It has no effect\n     * if the vsync rate is > 0.\n     */\n    status_t requestNextVsync();\n\nprivate:\n    sp<IDisplayEventConnection> mEventConnection;\n    sp<BitTube> mDataChannel;\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_DISPLAY_EVENT_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/GLConsumer.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_CONSUMER_H\n#define ANDROID_GUI_CONSUMER_H\n\n#include <EGL/egl.h>\n#include <EGL/eglext.h>\n\n#include <gui/IGraphicBufferProducer.h>\n#include <gui/BufferQueue.h>\n#include <gui/ConsumerBase.h>\n\n#include <ui/GraphicBuffer.h>\n\n#include <utils/String8.h>\n#include <utils/Vector.h>\n#include <utils/threads.h>\n\nnamespace android {\n// ----------------------------------------------------------------------------\n\n\nclass String8;\n\n/*\n * GLConsumer consumes buffers of graphics data from a BufferQueue,\n * and makes them available to OpenGL as a texture.\n *\n * A typical usage pattern is to set up the GLConsumer with the\n * desired options, and call updateTexImage() when a new frame is desired.\n * If a new frame is available, the texture will be updated.  If not,\n * the previous contents are retained.\n *\n * By default, the texture is attached to the GL_TEXTURE_EXTERNAL_OES\n * texture target, in the EGL context of the first thread that calls\n * updateTexImage().\n *\n * This class was previously called SurfaceTexture.\n */\nclass GLConsumer : public ConsumerBase {\npublic:\n    enum { TEXTURE_EXTERNAL = 0x8D65 }; // GL_TEXTURE_EXTERNAL_OES\n    typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;\n\n    // GLConsumer constructs a new GLConsumer object. If the constructor with\n    // the tex parameter is used, tex indicates the name of the OpenGL ES\n    // texture to which images are to be streamed. texTarget specifies the\n    // OpenGL ES texture target to which the texture will be bound in\n    // updateTexImage. useFenceSync specifies whether fences should be used to\n    // synchronize access to buffers if that behavior is enabled at\n    // compile-time.\n    //\n    // A GLConsumer may be detached from one OpenGL ES context and then\n    // attached to a different context using the detachFromContext and\n    // attachToContext methods, respectively. The intention of these methods is\n    // purely to allow a GLConsumer to be transferred from one consumer\n    // context to another. If such a transfer is not needed there is no\n    // requirement that either of these methods be called.\n    //\n    // If the constructor with the tex parameter is used, the GLConsumer is\n    // created in a state where it is considered attached to an OpenGL ES\n    // context for the purposes of the attachToContext and detachFromContext\n    // methods. However, despite being considered \"attached\" to a context, the\n    // specific OpenGL ES context doesn't get latched until the first call to\n    // updateTexImage. After that point, all calls to updateTexImage must be\n    // made with the same OpenGL ES context current.\n    //\n    // If the constructor without the tex parameter is used, the GLConsumer is\n    // created in a detached state, and attachToContext must be called before\n    // calls to updateTexImage.\n    GLConsumer(const sp<IGraphicBufferConsumer>& bq,\n            uint32_t tex, uint32_t texureTarget, bool useFenceSync,\n            bool isControlledByApp);\n\n    GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texureTarget,\n            bool useFenceSync, bool isControlledByApp);\n\n    // updateTexImage acquires the most recently queued buffer, and sets the\n    // image contents of the target texture to it.\n    //\n    // This call may only be made while the OpenGL ES context to which the\n    // target texture belongs is bound to the calling thread.\n    //\n    // This calls doGLFenceWait to ensure proper synchronization.\n    status_t updateTexImage();\n\n    // releaseTexImage releases the texture acquired in updateTexImage().\n    // This is intended to be used in single buffer mode.\n    //\n    // This call may only be made while the OpenGL ES context to which the\n    // target texture belongs is bound to the calling thread.\n    status_t releaseTexImage();\n\n    // setReleaseFence stores a fence that will signal when the current buffer\n    // is no longer being read. This fence will be returned to the producer\n    // when the current buffer is released by updateTexImage(). Multiple\n    // fences can be set for a given buffer; they will be merged into a single\n    // union fence.\n    virtual void setReleaseFence(const sp<Fence>& fence);\n\n    // getTransformMatrix retrieves the 4x4 texture coordinate transform matrix\n    // associated with the texture image set by the most recent call to\n    // updateTexImage.\n    //\n    // This transform matrix maps 2D homogeneous texture coordinates of the form\n    // (s, t, 0, 1) with s and t in the inclusive range [0, 1] to the texture\n    // coordinate that should be used to sample that location from the texture.\n    // Sampling the texture outside of the range of this transform is undefined.\n    //\n    // This transform is necessary to compensate for transforms that the stream\n    // content producer may implicitly apply to the content. By forcing users of\n    // a GLConsumer to apply this transform we avoid performing an extra\n    // copy of the data that would be needed to hide the transform from the\n    // user.\n    //\n    // The matrix is stored in column-major order so that it may be passed\n    // directly to OpenGL ES via the glLoadMatrixf or glUniformMatrix4fv\n    // functions.\n    void getTransformMatrix(float mtx[16]);\n\n    // Computes the transform matrix documented by getTransformMatrix\n    // from the BufferItem sub parts.\n    static void computeTransformMatrix(float outTransform[16],\n            const sp<GraphicBuffer>& buf, const Rect& cropRect,\n            uint32_t transform, bool filtering);\n\n    // getTimestamp retrieves the timestamp associated with the texture image\n    // set by the most recent call to updateTexImage.\n    //\n    // The timestamp is in nanoseconds, and is monotonically increasing. Its\n    // other semantics (zero point, etc) are source-dependent and should be\n    // documented by the source.\n    int64_t getTimestamp();\n\n    // getFrameNumber retrieves the frame number associated with the texture\n    // image set by the most recent call to updateTexImage.\n    //\n    // The frame number is an incrementing counter set to 0 at the creation of\n    // the BufferQueue associated with this consumer.\n    uint64_t getFrameNumber();\n\n    // setDefaultBufferSize is used to set the size of buffers returned by\n    // requestBuffers when a with and height of zero is requested.\n    // A call to setDefaultBufferSize() may trigger requestBuffers() to\n    // be called from the client.\n    // The width and height parameters must be no greater than the minimum of\n    // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv).\n    // An error due to invalid dimensions might not be reported until\n    // updateTexImage() is called.\n    status_t setDefaultBufferSize(uint32_t width, uint32_t height);\n\n    // setFilteringEnabled sets whether the transform matrix should be computed\n    // for use with bilinear filtering.\n    void setFilteringEnabled(bool enabled);\n\n    // getCurrentBuffer returns the buffer associated with the current image.\n    sp<GraphicBuffer> getCurrentBuffer() const;\n\n    // getCurrentTextureTarget returns the texture target of the current\n    // texture as returned by updateTexImage().\n    uint32_t getCurrentTextureTarget() const;\n\n    // getCurrentCrop returns the cropping rectangle of the current buffer.\n    Rect getCurrentCrop() const;\n\n    // getCurrentTransform returns the transform of the current buffer.\n    uint32_t getCurrentTransform() const;\n\n    // getCurrentScalingMode returns the scaling mode of the current buffer.\n    uint32_t getCurrentScalingMode() const;\n\n    // getCurrentFence returns the fence indicating when the current buffer is\n    // ready to be read from.\n    sp<Fence> getCurrentFence() const;\n\n    // doGLFenceWait inserts a wait command into the OpenGL ES command stream\n    // to ensure that it is safe for future OpenGL ES commands to access the\n    // current texture buffer.\n    status_t doGLFenceWait() const;\n\n    // set the name of the GLConsumer that will be used to identify it in\n    // log messages.\n    void setName(const String8& name);\n\n    // These functions call the corresponding BufferQueue implementation\n    // so the refactoring can proceed smoothly\n    status_t setDefaultBufferFormat(PixelFormat defaultFormat);\n    status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace);\n    status_t setConsumerUsageBits(uint32_t usage);\n    status_t setTransformHint(uint32_t hint);\n    status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers);\n\n    // detachFromContext detaches the GLConsumer from the calling thread's\n    // current OpenGL ES context.  This context must be the same as the context\n    // that was current for previous calls to updateTexImage.\n    //\n    // Detaching a GLConsumer from an OpenGL ES context will result in the\n    // deletion of the OpenGL ES texture object into which the images were being\n    // streamed.  After a GLConsumer has been detached from the OpenGL ES\n    // context calls to updateTexImage will fail returning INVALID_OPERATION\n    // until the GLConsumer is attached to a new OpenGL ES context using the\n    // attachToContext method.\n    status_t detachFromContext();\n\n    // attachToContext attaches a GLConsumer that is currently in the\n    // 'detached' state to the current OpenGL ES context.  A GLConsumer is\n    // in the 'detached' state iff detachFromContext has successfully been\n    // called and no calls to attachToContext have succeeded since the last\n    // detachFromContext call.  Calls to attachToContext made on a\n    // GLConsumer that is not in the 'detached' state will result in an\n    // INVALID_OPERATION error.\n    //\n    // The tex argument specifies the OpenGL ES texture object name in the\n    // new context into which the image contents will be streamed.  A successful\n    // call to attachToContext will result in this texture object being bound to\n    // the texture target and populated with the image contents that were\n    // current at the time of the last call to detachFromContext.\n    status_t attachToContext(uint32_t tex);\n\nprotected:\n\n    // abandonLocked overrides the ConsumerBase method to clear\n    // mCurrentTextureImage in addition to the ConsumerBase behavior.\n    virtual void abandonLocked();\n\n    // dumpLocked overrides the ConsumerBase method to dump GLConsumer-\n    // specific info in addition to the ConsumerBase behavior.\n    virtual void dumpLocked(String8& result, const char* prefix) const;\n\n    // acquireBufferLocked overrides the ConsumerBase method to update the\n    // mEglSlots array in addition to the ConsumerBase behavior.\n    virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen,\n            uint64_t maxFrameNumber = 0) override;\n\n    // releaseBufferLocked overrides the ConsumerBase method to update the\n    // mEglSlots array in addition to the ConsumerBase.\n    virtual status_t releaseBufferLocked(int slot,\n            const sp<GraphicBuffer> graphicBuffer,\n            EGLDisplay display, EGLSyncKHR eglFence);\n\n    status_t releaseBufferLocked(int slot,\n            const sp<GraphicBuffer> graphicBuffer, EGLSyncKHR eglFence) {\n        return releaseBufferLocked(slot, graphicBuffer, mEglDisplay, eglFence);\n    }\n\n    static bool isExternalFormat(PixelFormat format);\n\n    struct PendingRelease {\n        PendingRelease() : isPending(false), currentTexture(-1),\n                graphicBuffer(), display(nullptr), fence(nullptr) {}\n\n        bool isPending;\n        int currentTexture;\n        sp<GraphicBuffer> graphicBuffer;\n        EGLDisplay display;\n        EGLSyncKHR fence;\n    };\n\n    // This releases the buffer in the slot referenced by mCurrentTexture,\n    // then updates state to refer to the BufferItem, which must be a\n    // newly-acquired buffer. If pendingRelease is not null, the parameters\n    // which would have been passed to releaseBufferLocked upon the successful\n    // completion of the method will instead be returned to the caller, so that\n    // it may call releaseBufferLocked itself later.\n    status_t updateAndReleaseLocked(const BufferItem& item,\n            PendingRelease* pendingRelease = nullptr);\n\n    // Binds mTexName and the current buffer to mTexTarget.  Uses\n    // mCurrentTexture if it's set, mCurrentTextureImage if not.  If the\n    // bind succeeds, this calls doGLFenceWait.\n    status_t bindTextureImageLocked();\n\n    // Gets the current EGLDisplay and EGLContext values, and compares them\n    // to mEglDisplay and mEglContext.  If the fields have been previously\n    // set, the values must match; if not, the fields are set to the current\n    // values.\n    // The contextCheck argument is used to ensure that a GL context is\n    // properly set; when set to false, the check is not performed.\n    status_t checkAndUpdateEglStateLocked(bool contextCheck = false);\n\nprivate:\n    // EglImage is a utility class for tracking and creating EGLImageKHRs. There\n    // is primarily just one image per slot, but there is also special cases:\n    //  - For releaseTexImage, we use a debug image (mReleasedTexImage)\n    //  - After freeBuffer, we must still keep the current image/buffer\n    // Reference counting EGLImages lets us handle all these cases easily while\n    // also only creating new EGLImages from buffers when required.\n    class EglImage : public LightRefBase<EglImage>  {\n    public:\n        EglImage(sp<GraphicBuffer> graphicBuffer);\n\n        // createIfNeeded creates an EGLImage if required (we haven't created\n        // one yet, or the EGLDisplay or crop-rect has changed).\n        status_t createIfNeeded(EGLDisplay display,\n                                const Rect& cropRect,\n                                bool forceCreate = false);\n\n        // This calls glEGLImageTargetTexture2DOES to bind the image to the\n        // texture in the specified texture target.\n        void bindToTextureTarget(uint32_t texTarget);\n\n        const sp<GraphicBuffer>& graphicBuffer() { return mGraphicBuffer; }\n        const native_handle* graphicBufferHandle() {\n            return mGraphicBuffer == NULL ? NULL : mGraphicBuffer->handle;\n        }\n\n    private:\n        // Only allow instantiation using ref counting.\n        friend class LightRefBase<EglImage>;\n        virtual ~EglImage();\n\n        // createImage creates a new EGLImage from a GraphicBuffer.\n        EGLImageKHR createImage(EGLDisplay dpy,\n                const sp<GraphicBuffer>& graphicBuffer, const Rect& crop);\n\n        // Disallow copying\n        EglImage(const EglImage& rhs);\n        void operator = (const EglImage& rhs);\n\n        // mGraphicBuffer is the buffer that was used to create this image.\n        sp<GraphicBuffer> mGraphicBuffer;\n\n        // mEglImage is the EGLImage created from mGraphicBuffer.\n        EGLImageKHR mEglImage;\n\n        // mEGLDisplay is the EGLDisplay that was used to create mEglImage.\n        EGLDisplay mEglDisplay;\n\n        // mCropRect is the crop rectangle passed to EGL when mEglImage\n        // was created.\n        Rect mCropRect;\n    };\n\n    // freeBufferLocked frees up the given buffer slot. If the slot has been\n    // initialized this will release the reference to the GraphicBuffer in that\n    // slot and destroy the EGLImage in that slot.  Otherwise it has no effect.\n    //\n    // This method must be called with mMutex locked.\n    virtual void freeBufferLocked(int slotIndex);\n\n    // computeCurrentTransformMatrixLocked computes the transform matrix for the\n    // current texture.  It uses mCurrentTransform and the current GraphicBuffer\n    // to compute this matrix and stores it in mCurrentTransformMatrix.\n    // mCurrentTextureImage must not be NULL.\n    void computeCurrentTransformMatrixLocked();\n\n    // doGLFenceWaitLocked inserts a wait command into the OpenGL ES command\n    // stream to ensure that it is safe for future OpenGL ES commands to\n    // access the current texture buffer.\n    status_t doGLFenceWaitLocked() const;\n\n    // syncForReleaseLocked performs the synchronization needed to release the\n    // current slot from an OpenGL ES context.  If needed it will set the\n    // current slot's fence to guard against a producer accessing the buffer\n    // before the outstanding accesses have completed.\n    status_t syncForReleaseLocked(EGLDisplay dpy);\n\n    // returns a graphic buffer used when the texture image has been released\n    static sp<GraphicBuffer> getDebugTexImageBuffer();\n\n    // The default consumer usage flags that GLConsumer always sets on its\n    // BufferQueue instance; these will be OR:d with any additional flags passed\n    // from the GLConsumer user. In particular, GLConsumer will always\n    // consume buffers as hardware textures.\n    static const uint32_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE;\n\n    // mCurrentTextureImage is the EglImage/buffer of the current texture. It's\n    // possible that this buffer is not associated with any buffer slot, so we\n    // must track it separately in order to support the getCurrentBuffer method.\n    sp<EglImage> mCurrentTextureImage;\n\n    // mCurrentCrop is the crop rectangle that applies to the current texture.\n    // It gets set each time updateTexImage is called.\n    Rect mCurrentCrop;\n\n    // mCurrentTransform is the transform identifier for the current texture. It\n    // gets set each time updateTexImage is called.\n    uint32_t mCurrentTransform;\n\n    // mCurrentScalingMode is the scaling mode for the current texture. It gets\n    // set each time updateTexImage is called.\n    uint32_t mCurrentScalingMode;\n\n    // mCurrentFence is the fence received from BufferQueue in updateTexImage.\n    sp<Fence> mCurrentFence;\n\n    // mCurrentTransformMatrix is the transform matrix for the current texture.\n    // It gets computed by computeTransformMatrix each time updateTexImage is\n    // called.\n    float mCurrentTransformMatrix[16];\n\n    // mCurrentTimestamp is the timestamp for the current texture. It\n    // gets set each time updateTexImage is called.\n    int64_t mCurrentTimestamp;\n\n    // mCurrentFrameNumber is the frame counter for the current texture.\n    // It gets set each time updateTexImage is called.\n    uint64_t mCurrentFrameNumber;\n\n    uint32_t mDefaultWidth, mDefaultHeight;\n\n    // mFilteringEnabled indicates whether the transform matrix is computed for\n    // use with bilinear filtering. It defaults to true and is changed by\n    // setFilteringEnabled().\n    bool mFilteringEnabled;\n\n    // mTexName is the name of the OpenGL texture to which streamed images will\n    // be bound when updateTexImage is called. It is set at construction time\n    // and can be changed with a call to attachToContext.\n    uint32_t mTexName;\n\n    // mUseFenceSync indicates whether creation of the EGL_KHR_fence_sync\n    // extension should be used to prevent buffers from being dequeued before\n    // it's safe for them to be written. It gets set at construction time and\n    // never changes.\n    const bool mUseFenceSync;\n\n    // mTexTarget is the GL texture target with which the GL texture object is\n    // associated.  It is set in the constructor and never changed.  It is\n    // almost always GL_TEXTURE_EXTERNAL_OES except for one use case in Android\n    // Browser.  In that case it is set to GL_TEXTURE_2D to allow\n    // glCopyTexSubImage to read from the texture.  This is a hack to work\n    // around a GL driver limitation on the number of FBO attachments, which the\n    // browser's tile cache exceeds.\n    const uint32_t mTexTarget;\n\n    // EGLSlot contains the information and object references that\n    // GLConsumer maintains about a BufferQueue buffer slot.\n    struct EglSlot {\n        EglSlot() : mEglFence(EGL_NO_SYNC_KHR) {}\n\n        // mEglImage is the EGLImage created from mGraphicBuffer.\n        sp<EglImage> mEglImage;\n\n        // mFence is the EGL sync object that must signal before the buffer\n        // associated with this buffer slot may be dequeued. It is initialized\n        // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based\n        // on a compile-time option) set to a new sync object in updateTexImage.\n        EGLSyncKHR mEglFence;\n    };\n\n    // mEglDisplay is the EGLDisplay with which this GLConsumer is currently\n    // associated.  It is intialized to EGL_NO_DISPLAY and gets set to the\n    // current display when updateTexImage is called for the first time and when\n    // attachToContext is called.\n    EGLDisplay mEglDisplay;\n\n    // mEglContext is the OpenGL ES context with which this GLConsumer is\n    // currently associated.  It is initialized to EGL_NO_CONTEXT and gets set\n    // to the current GL context when updateTexImage is called for the first\n    // time and when attachToContext is called.\n    EGLContext mEglContext;\n\n    // mEGLSlots stores the buffers that have been allocated by the BufferQueue\n    // for each buffer slot.  It is initialized to null pointers, and gets\n    // filled in with the result of BufferQueue::acquire when the\n    // client dequeues a buffer from a\n    // slot that has not yet been used. The buffer allocated to a slot will also\n    // be replaced if the requested buffer usage or geometry differs from that\n    // of the buffer allocated to a slot.\n    EglSlot mEglSlots[BufferQueue::NUM_BUFFER_SLOTS];\n\n    // mCurrentTexture is the buffer slot index of the buffer that is currently\n    // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT,\n    // indicating that no buffer slot is currently bound to the texture. Note,\n    // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean\n    // that no buffer is bound to the texture. A call to setBufferCount will\n    // reset mCurrentTexture to INVALID_BUFFER_SLOT.\n    int mCurrentTexture;\n\n    // mAttached indicates whether the ConsumerBase is currently attached to\n    // an OpenGL ES context.  For legacy reasons, this is initialized to true,\n    // indicating that the ConsumerBase is considered to be attached to\n    // whatever context is current at the time of the first updateTexImage call.\n    // It is set to false by detachFromContext, and then set to true again by\n    // attachToContext.\n    bool mAttached;\n\n    // protects static initialization\n    static Mutex sStaticInitLock;\n\n    // mReleasedTexImageBuffer is a dummy buffer used when in single buffer\n    // mode and releaseTexImage() has been called\n    static sp<GraphicBuffer> sReleasedTexImageBuffer;\n    sp<EglImage> mReleasedTexImage;\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_CONSUMER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/GraphicBufferAlloc.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H\n#define ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <gui/IGraphicBufferAlloc.h>\n#include <ui/PixelFormat.h>\n#include <utils/Errors.h>\n\nnamespace android {\n// ---------------------------------------------------------------------------\n\nclass GraphicBuffer;\n\nclass GraphicBufferAlloc : public BnGraphicBufferAlloc {\npublic:\n    GraphicBufferAlloc();\n    virtual ~GraphicBufferAlloc();\n    virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width,\n            uint32_t height, PixelFormat format, uint32_t usage,\n            status_t* error);\n};\n\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/GuiConfig.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_CONFIG_H\n#define ANDROID_GUI_CONFIG_H\n\n#include <utils/String8.h>\n\nnamespace android {\n\n// Append the libgui configuration details to configStr.\nvoid appendGuiConfigString(String8& configStr);\n\n}; // namespace android\n\n#endif /*ANDROID_GUI_CONFIG_H*/\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/IConsumerListener.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_ICONSUMERLISTENER_H\n#define ANDROID_GUI_ICONSUMERLISTENER_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Errors.h>\n#include <utils/RefBase.h>\n\n#include <binder/IInterface.h>\n\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass BufferItem;\n\n// ConsumerListener is the interface through which the BufferQueue notifies\n// the consumer of events that the consumer may wish to react to.  Because\n// the consumer will generally have a mutex that is locked during calls from\n// the consumer to the BufferQueue, these calls from the BufferQueue to the\n// consumer *MUST* be called only when the BufferQueue mutex is NOT locked.\n\nclass ConsumerListener : public virtual RefBase {\npublic:\n    ConsumerListener() { }\n    virtual ~ConsumerListener() { }\n\n    // onFrameAvailable is called from queueBuffer each time an additional\n    // frame becomes available for consumption. This means that frames that\n    // are queued while in asynchronous mode only trigger the callback if no\n    // previous frames are pending. Frames queued while in synchronous mode\n    // always trigger the callback. The item passed to the callback will contain\n    // all of the information about the queued frame except for its\n    // GraphicBuffer pointer, which will always be null.\n    //\n    // This is called without any lock held and can be called concurrently\n    // by multiple threads.\n    virtual void onFrameAvailable(const BufferItem& item) = 0; /* Asynchronous */\n\n    // onFrameReplaced is called from queueBuffer if the frame being queued is\n    // replacing an existing slot in the queue. Any call to queueBuffer that\n    // doesn't call onFrameAvailable will call this callback instead. The item\n    // passed to the callback will contain all of the information about the\n    // queued frame except for its GraphicBuffer pointer, which will always be\n    // null.\n    //\n    // This is called without any lock held and can be called concurrently\n    // by multiple threads.\n    virtual void onFrameReplaced(const BufferItem& /* item */) {} /* Asynchronous */\n\n    // onBuffersReleased is called to notify the buffer consumer that the\n    // BufferQueue has released its references to one or more GraphicBuffers\n    // contained in its slots.  The buffer consumer should then call\n    // BufferQueue::getReleasedBuffers to retrieve the list of buffers\n    //\n    // This is called without any lock held and can be called concurrently\n    // by multiple threads.\n    virtual void onBuffersReleased() = 0; /* Asynchronous */\n\n    // onSidebandStreamChanged is called to notify the buffer consumer that the\n    // BufferQueue's sideband buffer stream has changed. This is called when a\n    // stream is first attached and when it is either detached or replaced by a\n    // different stream.\n    virtual void onSidebandStreamChanged() = 0; /* Asynchronous */\n};\n\n\nclass IConsumerListener : public ConsumerListener, public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(ConsumerListener);\n};\n\n// ----------------------------------------------------------------------------\n\nclass BnConsumerListener : public BnInterface<IConsumerListener>\n{\npublic:\n    virtual status_t    onTransact( uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_ICONSUMERLISTENER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/IDisplayEventConnection.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H\n#define ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Errors.h>\n#include <utils/RefBase.h>\n\n#include <binder/IInterface.h>\n\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass BitTube;\n\nclass IDisplayEventConnection : public IInterface\n{\npublic:\n\n    DECLARE_META_INTERFACE(DisplayEventConnection);\n\n    /*\n     * getDataChannel() returns a BitTube where to receive the events from\n     */\n    virtual sp<BitTube> getDataChannel() const = 0;\n\n    /*\n     * setVsyncRate() sets the vsync event delivery rate. A value of\n     * 1 returns every vsync events. A value of 2 returns every other events,\n     * etc... a value of 0 returns no event unless  requestNextVsync() has\n     * been called.\n     */\n    virtual void setVsyncRate(uint32_t count) = 0;\n\n    /*\n     * requestNextVsync() schedules the next vsync event. It has no effect\n     * if the vsync rate is > 0.\n     */\n    virtual void requestNextVsync() = 0;    // asynchronous\n};\n\n// ----------------------------------------------------------------------------\n\nclass BnDisplayEventConnection : public BnInterface<IDisplayEventConnection>\n{\npublic:\n    virtual status_t    onTransact( uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/IGraphicBufferAlloc.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_IGRAPHIC_BUFFER_ALLOC_H\n#define ANDROID_GUI_IGRAPHIC_BUFFER_ALLOC_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <binder/IInterface.h>\n#include <ui/PixelFormat.h>\n#include <utils/RefBase.h>\n\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass GraphicBuffer;\n\nclass IGraphicBufferAlloc : public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(GraphicBufferAlloc);\n\n    /* Create a new GraphicBuffer for the client to use.\n     */\n    virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,\n            PixelFormat format, uint32_t usage, status_t* error) = 0;\n};\n\n// ----------------------------------------------------------------------------\n\nclass BnGraphicBufferAlloc : public BnInterface<IGraphicBufferAlloc>\n{\npublic:\n    virtual status_t onTransact(uint32_t code,\n                                const Parcel& data,\n                                Parcel* reply,\n                                uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_GUI_IGRAPHIC_BUFFER_ALLOC_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/IGraphicBufferConsumer.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_IGRAPHICBUFFERCONSUMER_H\n#define ANDROID_GUI_IGRAPHICBUFFERCONSUMER_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Errors.h>\n#include <utils/RefBase.h>\n#include <utils/Timers.h>\n\n#include <binder/IInterface.h>\n#include <ui/PixelFormat.h>\n#include <ui/Rect.h>\n\n#include <EGL/egl.h>\n#include <EGL/eglext.h>\n\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass BufferItem;\nclass Fence;\nclass GraphicBuffer;\nclass IConsumerListener;\nclass NativeHandle;\n\nclass IGraphicBufferConsumer : public IInterface {\n\npublic:\n    enum {\n        // Returned by releaseBuffer, after which the consumer must\n        // free any references to the just-released buffer that it might have.\n        STALE_BUFFER_SLOT = 1,\n        // Returned by dequeueBuffer if there are no pending buffers available.\n        NO_BUFFER_AVAILABLE,\n        // Returned by dequeueBuffer if it's too early for the buffer to be acquired.\n        PRESENT_LATER,\n    };\n\n    // acquireBuffer attempts to acquire ownership of the next pending buffer in\n    // the BufferQueue.  If no buffer is pending then it returns\n    // NO_BUFFER_AVAILABLE.  If a buffer is successfully acquired, the\n    // information about the buffer is returned in BufferItem.\n    //\n    // If the buffer returned had previously been\n    // acquired then the BufferItem::mGraphicBuffer field of buffer is set to\n    // NULL and it is assumed that the consumer still holds a reference to the\n    // buffer.\n    //\n    // If presentWhen is non-zero, it indicates the time when the buffer will\n    // be displayed on screen.  If the buffer's timestamp is farther in the\n    // future, the buffer won't be acquired, and PRESENT_LATER will be\n    // returned.  The presentation time is in nanoseconds, and the time base\n    // is CLOCK_MONOTONIC.\n    //\n    // If maxFrameNumber is non-zero, it indicates that acquireBuffer should\n    // only return a buffer with a frame number less than or equal to\n    // maxFrameNumber. If no such frame is available (such as when a buffer has\n    // been replaced but the consumer has not received the onFrameReplaced\n    // callback), then PRESENT_LATER will be returned.\n    //\n    // Return of NO_ERROR means the operation completed as normal.\n    //\n    // Return of a positive value means the operation could not be completed\n    //    at this time, but the user should try again later:\n    // * NO_BUFFER_AVAILABLE - no buffer is pending (nothing queued by producer)\n    // * PRESENT_LATER - the buffer's timestamp is farther in the future\n    //\n    // Return of a negative value means an error has occurred:\n    // * INVALID_OPERATION - too many buffers have been acquired\n    virtual status_t acquireBuffer(BufferItem* buffer, nsecs_t presentWhen,\n            uint64_t maxFrameNumber = 0) = 0;\n\n    // detachBuffer attempts to remove all ownership of the buffer in the given\n    // slot from the buffer queue. If this call succeeds, the slot will be\n    // freed, and there will be no way to obtain the buffer from this interface.\n    // The freed slot will remain unallocated until either it is selected to\n    // hold a freshly allocated buffer in dequeueBuffer or a buffer is attached\n    // to the slot. The buffer must have already been acquired.\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * BAD_VALUE - the given slot number is invalid, either because it is\n    //               out of the range [0, NUM_BUFFER_SLOTS) or because the slot\n    //               it refers to is not currently acquired.\n    virtual status_t detachBuffer(int slot) = 0;\n\n    // attachBuffer attempts to transfer ownership of a buffer to the buffer\n    // queue. If this call succeeds, it will be as if this buffer was acquired\n    // from the returned slot number. As such, this call will fail if attaching\n    // this buffer would cause too many buffers to be simultaneously acquired.\n    //\n    // If the buffer is successfully attached, its frameNumber is initialized\n    // to 0. This must be passed into the releaseBuffer call or else the buffer\n    // will be deallocated as stale.\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * BAD_VALUE - outSlot or buffer were NULL, or the generation number of\n    //               the buffer did not match the buffer queue.\n    // * INVALID_OPERATION - cannot attach the buffer because it would cause too\n    //                       many buffers to be acquired.\n    // * NO_MEMORY - no free slots available\n    virtual status_t attachBuffer(int *outSlot,\n            const sp<GraphicBuffer>& buffer) = 0;\n\n    // releaseBuffer releases a buffer slot from the consumer back to the\n    // BufferQueue.  This may be done while the buffer's contents are still\n    // being accessed.  The fence will signal when the buffer is no longer\n    // in use. frameNumber is used to indentify the exact buffer returned.\n    //\n    // If releaseBuffer returns STALE_BUFFER_SLOT, then the consumer must free\n    // any references to the just-released buffer that it might have, as if it\n    // had received a onBuffersReleased() call with a mask set for the released\n    // buffer.\n    //\n    // Note that the dependencies on EGL will be removed once we switch to using\n    // the Android HW Sync HAL.\n    //\n    // Return of NO_ERROR means the operation completed as normal.\n    //\n    // Return of a positive value means the operation could not be completed\n    //    at this time, but the user should try again later:\n    // * STALE_BUFFER_SLOT - see above (second paragraph)\n    //\n    // Return of a negative value means an error has occurred:\n    // * BAD_VALUE - one of the following could've happened:\n    //               * the buffer slot was invalid\n    //               * the fence was NULL\n    //               * the buffer slot specified is not in the acquired state\n    virtual status_t releaseBuffer(int buf, uint64_t frameNumber,\n            EGLDisplay display, EGLSyncKHR fence,\n            const sp<Fence>& releaseFence) = 0;\n\n    // consumerConnect connects a consumer to the BufferQueue.  Only one\n    // consumer may be connected, and when that consumer disconnects the\n    // BufferQueue is placed into the \"abandoned\" state, causing most\n    // interactions with the BufferQueue by the producer to fail.\n    // controlledByApp indicates whether the consumer is controlled by\n    // the application.\n    //\n    // consumer may not be NULL.\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * NO_INIT - the buffer queue has been abandoned\n    // * BAD_VALUE - a NULL consumer was provided\n    virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) = 0;\n\n    // consumerDisconnect disconnects a consumer from the BufferQueue. All\n    // buffers will be freed and the BufferQueue is placed in the \"abandoned\"\n    // state, causing most interactions with the BufferQueue by the producer to\n    // fail.\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * BAD_VALUE - no consumer is currently connected\n    virtual status_t consumerDisconnect() = 0;\n\n    // getReleasedBuffers sets the value pointed to by slotMask to a bit set.\n    // Each bit index with a 1 corresponds to a released buffer slot with that\n    // index value.  In particular, a released buffer is one that has\n    // been released by the BufferQueue but have not yet been released by the consumer.\n    //\n    // This should be called from the onBuffersReleased() callback.\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * NO_INIT - the buffer queue has been abandoned.\n    virtual status_t getReleasedBuffers(uint64_t* slotMask) = 0;\n\n    // setDefaultBufferSize is used to set the size of buffers returned by\n    // dequeueBuffer when a width and height of zero is requested.  Default\n    // is 1x1.\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * BAD_VALUE - either w or h was zero\n    virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) = 0;\n\n    // setMaxBufferCount sets the maximum value for the number of buffers used\n    // in the buffer queue (the initial default is NUM_BUFFER_SLOTS). If a call\n    // to setMaxAcquiredBufferCount (by the consumer), or a call to setAsyncMode\n    // or setMaxDequeuedBufferCount (by the producer), would cause this value to\n    // be exceeded then that call will fail. This call will fail if a producer\n    // is connected to the BufferQueue.\n    //\n    // The count must be between 1 and NUM_BUFFER_SLOTS, inclusive. The count\n    // cannot be less than maxAcquiredBufferCount.\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * BAD_VALUE - one of the below conditions occurred:\n    //             * bufferCount was out of range (see above).\n    //             * failure to adjust the number of available slots.\n    // * INVALID_OPERATION - attempting to call this after a producer connected.\n    virtual status_t setMaxBufferCount(int bufferCount) = 0;\n\n    // setMaxAcquiredBufferCount sets the maximum number of buffers that can\n    // be acquired by the consumer at one time (default 1). If this method\n    // succeeds, any new buffer slots will be both unallocated and owned by the\n    // BufferQueue object (i.e. they are not owned by the producer or consumer).\n    // Calling this may also cause some buffer slots to be emptied.\n    //\n    // This function should not be called with a value of maxAcquiredBuffers\n    // that is less than the number of currently acquired buffer slots. Doing so\n    // will result in a BAD_VALUE error.\n    //\n    // maxAcquiredBuffers must be (inclusive) between 1 and\n    // MAX_MAX_ACQUIRED_BUFFERS. It also cannot cause the maxBufferCount value\n    // to be exceeded.\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * NO_INIT - the buffer queue has been abandoned\n    // * BAD_VALUE - one of the below conditions occurred:\n    //             * maxAcquiredBuffers was out of range (see above).\n    //             * failure to adjust the number of available slots.\n    //             * client would have more than the requested number of\n    //               acquired buffers after this call\n    // * INVALID_OPERATION - attempting to call this after a producer connected.\n    virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) = 0;\n\n    // setConsumerName sets the name used in logging\n    virtual void setConsumerName(const String8& name) = 0;\n\n    // setDefaultBufferFormat allows the BufferQueue to create\n    // GraphicBuffers of a defaultFormat if no format is specified\n    // in dequeueBuffer.\n    // The initial default is PIXEL_FORMAT_RGBA_8888.\n    //\n    // Return of a value other than NO_ERROR means an unknown error has occurred.\n    virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat) = 0;\n\n    // setDefaultBufferDataSpace is a request to the producer to provide buffers\n    // of the indicated dataSpace. The producer may ignore this request.\n    // The initial default is HAL_DATASPACE_UNKNOWN.\n    //\n    // Return of a value other than NO_ERROR means an unknown error has occurred.\n    virtual status_t setDefaultBufferDataSpace(\n            android_dataspace defaultDataSpace) = 0;\n\n    // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer.\n    // These are merged with the bits passed to dequeueBuffer.  The values are\n    // enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER; the default is 0.\n    //\n    // Return of a value other than NO_ERROR means an unknown error has occurred.\n    virtual status_t setConsumerUsageBits(uint32_t usage) = 0;\n\n    // setTransformHint bakes in rotation to buffers so overlays can be used.\n    // The values are enumerated in window.h, e.g.\n    // NATIVE_WINDOW_TRANSFORM_ROT_90.  The default is 0 (no transform).\n    //\n    // Return of a value other than NO_ERROR means an unknown error has occurred.\n    virtual status_t setTransformHint(uint32_t hint) = 0;\n\n    // Retrieve the sideband buffer stream, if any.\n    virtual sp<NativeHandle> getSidebandStream() const = 0;\n\n    // dump state into a string\n    virtual void dump(String8& result, const char* prefix) const = 0;\n\npublic:\n    DECLARE_META_INTERFACE(GraphicBufferConsumer);\n};\n\n// ----------------------------------------------------------------------------\n\nclass BnGraphicBufferConsumer : public BnInterface<IGraphicBufferConsumer>\n{\npublic:\n    virtual status_t    onTransact( uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_IGRAPHICBUFFERCONSUMER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/IGraphicBufferProducer.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_IGRAPHICBUFFERPRODUCER_H\n#define ANDROID_GUI_IGRAPHICBUFFERPRODUCER_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Errors.h>\n#include <utils/RefBase.h>\n\n#include <binder/IInterface.h>\n\n#include <ui/Fence.h>\n#include <ui/GraphicBuffer.h>\n#include <ui/Rect.h>\n#include <ui/Region.h>\n\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass IProducerListener;\nclass NativeHandle;\nclass Surface;\n\n/*\n * This class defines the Binder IPC interface for the producer side of\n * a queue of graphics buffers.  It's used to send graphics data from one\n * component to another.  For example, a class that decodes video for\n * playback might use this to provide frames.  This is typically done\n * indirectly, through Surface.\n *\n * The underlying mechanism is a BufferQueue, which implements\n * BnGraphicBufferProducer.  In normal operation, the producer calls\n * dequeueBuffer() to get an empty buffer, fills it with data, then\n * calls queueBuffer() to make it available to the consumer.\n *\n * This class was previously called ISurfaceTexture.\n */\nclass IGraphicBufferProducer : public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(GraphicBufferProducer);\n\n    enum {\n        // A flag returned by dequeueBuffer when the client needs to call\n        // requestBuffer immediately thereafter.\n        BUFFER_NEEDS_REALLOCATION = 0x1,\n        // A flag returned by dequeueBuffer when all mirrored slots should be\n        // released by the client. This flag should always be processed first.\n        RELEASE_ALL_BUFFERS       = 0x2,\n    };\n\n    // requestBuffer requests a new buffer for the given index. The server (i.e.\n    // the IGraphicBufferProducer implementation) assigns the newly created\n    // buffer to the given slot index, and the client is expected to mirror the\n    // slot->buffer mapping so that it's not necessary to transfer a\n    // GraphicBuffer for every dequeue operation.\n    //\n    // The slot must be in the range of [0, NUM_BUFFER_SLOTS).\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * NO_INIT - the buffer queue has been abandoned or the producer is not\n    //             connected.\n    // * BAD_VALUE - one of the two conditions occurred:\n    //              * slot was out of range (see above)\n    //              * buffer specified by the slot is not dequeued\n    virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0;\n\n    // setMaxDequeuedBufferCount sets the maximum number of buffers that can be\n    // dequeued by the producer at one time. If this method succeeds, any new\n    // buffer slots will be both unallocated and owned by the BufferQueue object\n    // (i.e. they are not owned by the producer or consumer). Calling this may\n    // also cause some buffer slots to be emptied. If the caller is caching the\n    // contents of the buffer slots, it should empty that cache after calling\n    // this method.\n    //\n    // This function should not be called with a value of maxDequeuedBuffers\n    // that is less than the number of currently dequeued buffer slots. Doing so\n    // will result in a BAD_VALUE error.\n    //\n    // The buffer count should be at least 1 (inclusive), but at most\n    // (NUM_BUFFER_SLOTS - the minimum undequeued buffer count) (exclusive). The\n    // minimum undequeued buffer count can be obtained by calling\n    // query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS).\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * NO_INIT - the buffer queue has been abandoned.\n    // * BAD_VALUE - one of the below conditions occurred:\n    //     * bufferCount was out of range (see above).\n    //     * client would have more than the requested number of dequeued\n    //       buffers after this call.\n    //     * this call would cause the maxBufferCount value to be exceeded.\n    //     * failure to adjust the number of available slots.\n    virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) = 0;\n\n    // Set the async flag if the producer intends to asynchronously queue\n    // buffers without blocking. Typically this is used for triple-buffering\n    // and/or when the swap interval is set to zero.\n    //\n    // Enabling async mode will internally allocate an additional buffer to\n    // allow for the asynchronous behavior. If it is not enabled queue/dequeue\n    // calls may block.\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * NO_INIT - the buffer queue has been abandoned.\n    // * BAD_VALUE - one of the following has occurred:\n    //             * this call would cause the maxBufferCount value to be\n    //               exceeded\n    //             * failure to adjust the number of available slots.\n    virtual status_t setAsyncMode(bool async) = 0;\n\n    // dequeueBuffer requests a new buffer slot for the client to use. Ownership\n    // of the slot is transfered to the client, meaning that the server will not\n    // use the contents of the buffer associated with that slot.\n    //\n    // The slot index returned may or may not contain a buffer (client-side).\n    // If the slot is empty the client should call requestBuffer to assign a new\n    // buffer to that slot.\n    //\n    // Once the client is done filling this buffer, it is expected to transfer\n    // buffer ownership back to the server with either cancelBuffer on\n    // the dequeued slot or to fill in the contents of its associated buffer\n    // contents and call queueBuffer.\n    //\n    // If dequeueBuffer returns the BUFFER_NEEDS_REALLOCATION flag, the client is\n    // expected to call requestBuffer immediately.\n    //\n    // If dequeueBuffer returns the RELEASE_ALL_BUFFERS flag, the client is\n    // expected to release all of the mirrored slot->buffer mappings.\n    //\n    // The fence parameter will be updated to hold the fence associated with\n    // the buffer. The contents of the buffer must not be overwritten until the\n    // fence signals. If the fence is Fence::NO_FENCE, the buffer may be written\n    // immediately.\n    //\n    // The width and height parameters must be no greater than the minimum of\n    // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv).\n    // An error due to invalid dimensions might not be reported until\n    // updateTexImage() is called.  If width and height are both zero, the\n    // default values specified by setDefaultBufferSize() are used instead.\n    //\n    // If the format is 0, the default format will be used.\n    //\n    // The usage argument specifies gralloc buffer usage flags.  The values\n    // are enumerated in <gralloc.h>, e.g. GRALLOC_USAGE_HW_RENDER.  These\n    // will be merged with the usage flags specified by\n    // IGraphicBufferConsumer::setConsumerUsageBits.\n    //\n    // This call will block until a buffer is available to be dequeued. If\n    // both the producer and consumer are controlled by the app, then this call\n    // can never block and will return WOULD_BLOCK if no buffer is available.\n    //\n    // A non-negative value with flags set (see above) will be returned upon\n    // success.\n    //\n    // Return of a negative means an error has occurred:\n    // * NO_INIT - the buffer queue has been abandoned or the producer is not\n    //             connected.\n    // * BAD_VALUE - both in async mode and buffer count was less than the\n    //               max numbers of buffers that can be allocated at once.\n    // * INVALID_OPERATION - cannot attach the buffer because it would cause\n    //                       too many buffers to be dequeued, either because\n    //                       the producer already has a single buffer dequeued\n    //                       and did not set a buffer count, or because a\n    //                       buffer count was set and this call would cause\n    //                       it to be exceeded.\n    // * WOULD_BLOCK - no buffer is currently available, and blocking is disabled\n    //                 since both the producer/consumer are controlled by app\n    // * NO_MEMORY - out of memory, cannot allocate the graphics buffer.\n    // * TIMED_OUT - the timeout set by setDequeueTimeout was exceeded while\n    //               waiting for a buffer to become available.\n    //\n    // All other negative values are an unknown error returned downstream\n    // from the graphics allocator (typically errno).\n    virtual status_t dequeueBuffer(int* slot, sp<Fence>* fence, uint32_t w,\n            uint32_t h, PixelFormat format, uint32_t usage) = 0;\n\n    // detachBuffer attempts to remove all ownership of the buffer in the given\n    // slot from the buffer queue. If this call succeeds, the slot will be\n    // freed, and there will be no way to obtain the buffer from this interface.\n    // The freed slot will remain unallocated until either it is selected to\n    // hold a freshly allocated buffer in dequeueBuffer or a buffer is attached\n    // to the slot. The buffer must have already been dequeued, and the caller\n    // must already possesses the sp<GraphicBuffer> (i.e., must have called\n    // requestBuffer).\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * NO_INIT - the buffer queue has been abandoned or the producer is not\n    //             connected.\n    // * BAD_VALUE - the given slot number is invalid, either because it is\n    //               out of the range [0, NUM_BUFFER_SLOTS), or because the slot\n    //               it refers to is not currently dequeued and requested.\n    virtual status_t detachBuffer(int slot) = 0;\n\n    // detachNextBuffer is equivalent to calling dequeueBuffer, requestBuffer,\n    // and detachBuffer in sequence, except for two things:\n    //\n    // 1) It is unnecessary to know the dimensions, format, or usage of the\n    //    next buffer.\n    // 2) It will not block, since if it cannot find an appropriate buffer to\n    //    return, it will return an error instead.\n    //\n    // Only slots that are free but still contain a GraphicBuffer will be\n    // considered, and the oldest of those will be returned. outBuffer is\n    // equivalent to outBuffer from the requestBuffer call, and outFence is\n    // equivalent to fence from the dequeueBuffer call.\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * NO_INIT - the buffer queue has been abandoned or the producer is not\n    //             connected.\n    // * BAD_VALUE - either outBuffer or outFence were NULL.\n    // * NO_MEMORY - no slots were found that were both free and contained a\n    //               GraphicBuffer.\n    virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,\n            sp<Fence>* outFence) = 0;\n\n    // attachBuffer attempts to transfer ownership of a buffer to the buffer\n    // queue. If this call succeeds, it will be as if this buffer was dequeued\n    // from the returned slot number. As such, this call will fail if attaching\n    // this buffer would cause too many buffers to be simultaneously dequeued.\n    //\n    // If attachBuffer returns the RELEASE_ALL_BUFFERS flag, the caller is\n    // expected to release all of the mirrored slot->buffer mappings.\n    //\n    // A non-negative value with flags set (see above) will be returned upon\n    // success.\n    //\n    // Return of a negative value means an error has occurred:\n    // * NO_INIT - the buffer queue has been abandoned or the producer is not\n    //             connected.\n    // * BAD_VALUE - outSlot or buffer were NULL, invalid combination of\n    //               async mode and buffer count override, or the generation\n    //               number of the buffer did not match the buffer queue.\n    // * INVALID_OPERATION - cannot attach the buffer because it would cause\n    //                       too many buffers to be dequeued, either because\n    //                       the producer already has a single buffer dequeued\n    //                       and did not set a buffer count, or because a\n    //                       buffer count was set and this call would cause\n    //                       it to be exceeded.\n    // * WOULD_BLOCK - no buffer slot is currently available, and blocking is\n    //                 disabled since both the producer/consumer are\n    //                 controlled by the app.\n    // * TIMED_OUT - the timeout set by setDequeueTimeout was exceeded while\n    //               waiting for a slot to become available.\n    virtual status_t attachBuffer(int* outSlot,\n            const sp<GraphicBuffer>& buffer) = 0;\n\n    // queueBuffer indicates that the client has finished filling in the\n    // contents of the buffer associated with slot and transfers ownership of\n    // that slot back to the server.\n    //\n    // It is not valid to call queueBuffer on a slot that is not owned\n    // by the client or one for which a buffer associated via requestBuffer\n    // (an attempt to do so will fail with a return value of BAD_VALUE).\n    //\n    // In addition, the input must be described by the client (as documented\n    // below). Any other properties (zero point, etc)\n    // are client-dependent, and should be documented by the client.\n    //\n    // The slot must be in the range of [0, NUM_BUFFER_SLOTS).\n    //\n    // Upon success, the output will be filled with meaningful values\n    // (refer to the documentation below).\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * NO_INIT - the buffer queue has been abandoned or the producer is not\n    //             connected.\n    // * BAD_VALUE - one of the below conditions occurred:\n    //              * fence was NULL\n    //              * scaling mode was unknown\n    //              * both in async mode and buffer count was less than the\n    //                max numbers of buffers that can be allocated at once\n    //              * slot index was out of range (see above).\n    //              * the slot was not in the dequeued state\n    //              * the slot was enqueued without requesting a buffer\n    //              * crop rect is out of bounds of the buffer dimensions\n\n    struct QueueBufferInput : public Flattenable<QueueBufferInput> {\n        friend class Flattenable<QueueBufferInput>;\n        inline QueueBufferInput(const Parcel& parcel);\n        // timestamp - a monotonically increasing value in nanoseconds\n        // isAutoTimestamp - if the timestamp was synthesized at queue time\n        // dataSpace - description of the contents, interpretation depends on format\n        // crop - a crop rectangle that's used as a hint to the consumer\n        // scalingMode - a set of flags from NATIVE_WINDOW_SCALING_* in <window.h>\n        // transform - a set of flags from NATIVE_WINDOW_TRANSFORM_* in <window.h>\n        // fence - a fence that the consumer must wait on before reading the buffer,\n        //         set this to Fence::NO_FENCE if the buffer is ready immediately\n        // sticky - the sticky transform set in Surface (only used by the LEGACY\n        //          camera mode).\n        inline QueueBufferInput(int64_t timestamp, bool isAutoTimestamp,\n                android_dataspace dataSpace, const Rect& crop, int scalingMode,\n                uint32_t transform, const sp<Fence>& fence, uint32_t sticky = 0)\n                : timestamp(timestamp), isAutoTimestamp(isAutoTimestamp),\n                  dataSpace(dataSpace), crop(crop), scalingMode(scalingMode),\n                  transform(transform), stickyTransform(sticky), fence(fence),\n                  surfaceDamage() { }\n        inline void deflate(int64_t* outTimestamp, bool* outIsAutoTimestamp,\n                android_dataspace* outDataSpace,\n                Rect* outCrop, int* outScalingMode,\n                uint32_t* outTransform, sp<Fence>* outFence,\n                uint32_t* outStickyTransform = NULL) const {\n            *outTimestamp = timestamp;\n            *outIsAutoTimestamp = bool(isAutoTimestamp);\n            *outDataSpace = dataSpace;\n            *outCrop = crop;\n            *outScalingMode = scalingMode;\n            *outTransform = transform;\n            *outFence = fence;\n            if (outStickyTransform != NULL) {\n                *outStickyTransform = stickyTransform;\n            }\n        }\n\n        // Flattenable protocol\n        size_t getFlattenedSize() const;\n        size_t getFdCount() const;\n        status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;\n        status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);\n\n        const Region& getSurfaceDamage() const { return surfaceDamage; }\n        void setSurfaceDamage(const Region& damage) { surfaceDamage = damage; }\n\n    private:\n        int64_t timestamp;\n        int isAutoTimestamp;\n        android_dataspace dataSpace;\n        Rect crop;\n        int scalingMode;\n        uint32_t transform;\n        uint32_t stickyTransform;\n        sp<Fence> fence;\n        Region surfaceDamage;\n    };\n\n    // QueueBufferOutput must be a POD structure\n    struct __attribute__ ((__packed__)) QueueBufferOutput {\n        inline QueueBufferOutput() { }\n        // outWidth - filled with default width applied to the buffer\n        // outHeight - filled with default height applied to the buffer\n        // outTransformHint - filled with default transform applied to the buffer\n        // outNumPendingBuffers - num buffers queued that haven't yet been acquired\n        //                        (counting the currently queued buffer)\n        inline void deflate(uint32_t* outWidth,\n                uint32_t* outHeight,\n                uint32_t* outTransformHint,\n                uint32_t* outNumPendingBuffers) const {\n            *outWidth = width;\n            *outHeight = height;\n            *outTransformHint = transformHint;\n            *outNumPendingBuffers = numPendingBuffers;\n        }\n        inline void inflate(uint32_t inWidth, uint32_t inHeight,\n                uint32_t inTransformHint, uint32_t inNumPendingBuffers) {\n            width = inWidth;\n            height = inHeight;\n            transformHint = inTransformHint;\n            numPendingBuffers = inNumPendingBuffers;\n        }\n    private:\n        uint32_t width;\n        uint32_t height;\n        uint32_t transformHint;\n        uint32_t numPendingBuffers;\n    };\n\n    virtual status_t queueBuffer(int slot, const QueueBufferInput& input,\n            QueueBufferOutput* output) = 0;\n\n    // cancelBuffer indicates that the client does not wish to fill in the\n    // buffer associated with slot and transfers ownership of the slot back to\n    // the server.\n    //\n    // The buffer is not queued for use by the consumer.\n    //\n    // The slot must be in the range of [0, NUM_BUFFER_SLOTS).\n    //\n    // The buffer will not be overwritten until the fence signals.  The fence\n    // will usually be the one obtained from dequeueBuffer.\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * NO_INIT - the buffer queue has been abandoned or the producer is not\n    //             connected.\n    // * BAD_VALUE - one of the below conditions occurred:\n    //              * fence was NULL\n    //              * slot index was out of range (see above).\n    //              * the slot was not in the dequeued state\n    virtual status_t cancelBuffer(int slot, const sp<Fence>& fence) = 0;\n\n    // query retrieves some information for this surface\n    // 'what' tokens allowed are that of NATIVE_WINDOW_* in <window.h>\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * NO_INIT - the buffer queue has been abandoned.\n    // * BAD_VALUE - what was out of range\n    virtual int query(int what, int* value) = 0;\n\n    // connect attempts to connect a client API to the IGraphicBufferProducer.\n    // This must be called before any other IGraphicBufferProducer methods are\n    // called except for getAllocator. A consumer must be already connected.\n    //\n    // This method will fail if the connect was previously called on the\n    // IGraphicBufferProducer and no corresponding disconnect call was made.\n    //\n    // The listener is an optional binder callback object that can be used if\n    // the producer wants to be notified when the consumer releases a buffer\n    // back to the BufferQueue. It is also used to detect the death of the\n    // producer. If only the latter functionality is desired, there is a\n    // DummyProducerListener class in IProducerListener.h that can be used.\n    //\n    // The api should be one of the NATIVE_WINDOW_API_* values in <window.h>\n    //\n    // The producerControlledByApp should be set to true if the producer is hosted\n    // by an untrusted process (typically app_process-forked processes). If both\n    // the producer and the consumer are app-controlled then all buffer queues\n    // will operate in async mode regardless of the async flag.\n    //\n    // Upon success, the output will be filled with meaningful data\n    // (refer to QueueBufferOutput documentation above).\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * NO_INIT - one of the following occurred:\n    //             * the buffer queue was abandoned\n    //             * no consumer has yet connected\n    // * BAD_VALUE - one of the following has occurred:\n    //             * the producer is already connected\n    //             * api was out of range (see above).\n    //             * output was NULL.\n    //             * Failure to adjust the number of available slots. This can\n    //               happen because of trying to allocate/deallocate the async\n    //               buffer in response to the value of producerControlledByApp.\n    // * DEAD_OBJECT - the token is hosted by an already-dead process\n    //\n    // Additional negative errors may be returned by the internals, they\n    // should be treated as opaque fatal unrecoverable errors.\n    virtual status_t connect(const sp<IProducerListener>& listener,\n            int api, bool producerControlledByApp, QueueBufferOutput* output) = 0;\n\n    // disconnect attempts to disconnect a client API from the\n    // IGraphicBufferProducer.  Calling this method will cause any subsequent\n    // calls to other IGraphicBufferProducer methods to fail except for\n    // getAllocator and connect.  Successfully calling connect after this will\n    // allow the other methods to succeed again.\n    //\n    // This method will fail if the the IGraphicBufferProducer is not currently\n    // connected to the specified client API.\n    //\n    // The api should be one of the NATIVE_WINDOW_API_* values in <window.h>\n    //\n    // Disconnecting from an abandoned IGraphicBufferProducer is legal and\n    // is considered a no-op.\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * BAD_VALUE - one of the following has occurred:\n    //             * the api specified does not match the one that was connected\n    //             * api was out of range (see above).\n    // * DEAD_OBJECT - the token is hosted by an already-dead process\n    virtual status_t disconnect(int api) = 0;\n\n    // Attaches a sideband buffer stream to the IGraphicBufferProducer.\n    //\n    // A sideband stream is a device-specific mechanism for passing buffers\n    // from the producer to the consumer without using dequeueBuffer/\n    // queueBuffer. If a sideband stream is present, the consumer can choose\n    // whether to acquire buffers from the sideband stream or from the queued\n    // buffers.\n    //\n    // Passing NULL or a different stream handle will detach the previous\n    // handle if any.\n    virtual status_t setSidebandStream(const sp<NativeHandle>& stream) = 0;\n\n    // Allocates buffers based on the given dimensions/format.\n    //\n    // This function will allocate up to the maximum number of buffers\n    // permitted by the current BufferQueue configuration. It will use the\n    // given format, dimensions, and usage bits, which are interpreted in the\n    // same way as for dequeueBuffer, and the async flag must be set the same\n    // way as for dequeueBuffer to ensure that the correct number of buffers are\n    // allocated. This is most useful to avoid an allocation delay during\n    // dequeueBuffer. If there are already the maximum number of buffers\n    // allocated, this function has no effect.\n    virtual void allocateBuffers(uint32_t width, uint32_t height,\n            PixelFormat format, uint32_t usage) = 0;\n\n    // Sets whether dequeueBuffer is allowed to allocate new buffers.\n    //\n    // Normally dequeueBuffer does not discriminate between free slots which\n    // already have an allocated buffer and those which do not, and will\n    // allocate a new buffer if the slot doesn't have a buffer or if the slot's\n    // buffer doesn't match the requested size, format, or usage. This method\n    // allows the producer to restrict the eligible slots to those which already\n    // have an allocated buffer of the correct size, format, and usage. If no\n    // eligible slot is available, dequeueBuffer will block or return an error\n    // as usual.\n    virtual status_t allowAllocation(bool allow) = 0;\n\n    // Sets the current generation number of the BufferQueue.\n    //\n    // This generation number will be inserted into any buffers allocated by the\n    // BufferQueue, and any attempts to attach a buffer with a different\n    // generation number will fail. Buffers already in the queue are not\n    // affected and will retain their current generation number. The generation\n    // number defaults to 0.\n    virtual status_t setGenerationNumber(uint32_t generationNumber) = 0;\n\n    // Returns the name of the connected consumer.\n    virtual String8 getConsumerName() const = 0;\n\n    // Returns the number of the next frame which will be dequeued.\n    virtual uint64_t getNextFrameNumber() const = 0;\n\n    // Used to enable/disable shared buffer mode.\n    //\n    // When shared buffer mode is enabled the first buffer that is queued or\n    // dequeued will be cached and returned to all subsequent calls to\n    // dequeueBuffer and acquireBuffer. This allows the producer and consumer to\n    // simultaneously access the same buffer.\n    virtual status_t setSharedBufferMode(bool sharedBufferMode) = 0;\n\n    // Used to enable/disable auto-refresh.\n    //\n    // Auto refresh has no effect outside of shared buffer mode. In shared\n    // buffer mode, when enabled, it indicates to the consumer that it should\n    // attempt to acquire buffers even if it is not aware of any being\n    // available.\n    virtual status_t setAutoRefresh(bool autoRefresh) = 0;\n\n    // Sets how long dequeueBuffer will wait for a buffer to become available\n    // before returning an error (TIMED_OUT).\n    //\n    // This timeout also affects the attachBuffer call, which will block if\n    // there is not a free slot available into which the attached buffer can be\n    // placed.\n    //\n    // By default, the BufferQueue will wait forever, which is indicated by a\n    // timeout of -1. If set (to a value other than -1), this will disable\n    // non-blocking mode and its corresponding spare buffer (which is used to\n    // ensure a buffer is always available).\n    //\n    // Return of a value other than NO_ERROR means an error has occurred:\n    // * BAD_VALUE - Failure to adjust the number of available slots. This can\n    //               happen because of trying to allocate/deallocate the async\n    //               buffer.\n    virtual status_t setDequeueTimeout(nsecs_t timeout) = 0;\n\n    // Returns the last queued buffer along with a fence which must signal\n    // before the contents of the buffer are read. If there are no buffers in\n    // the queue, outBuffer will be populated with nullptr and outFence will be\n    // populated with Fence::NO_FENCE\n    //\n    // outTransformMatrix is not modified if outBuffer is null.\n    //\n    // Returns NO_ERROR or the status of the Binder transaction\n    virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,\n            sp<Fence>* outFence, float outTransformMatrix[16]) = 0;\n\n    // Returns a unique id for this BufferQueue\n    virtual status_t getUniqueId(uint64_t* outId) const = 0;\n};\n\n// ----------------------------------------------------------------------------\n\nclass BnGraphicBufferProducer : public BnInterface<IGraphicBufferProducer>\n{\npublic:\n    virtual status_t    onTransact( uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_IGRAPHICBUFFERPRODUCER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/IProducerListener.h",
    "content": "/*\n * Copyright 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_IPRODUCERLISTENER_H\n#define ANDROID_GUI_IPRODUCERLISTENER_H\n\n#include <binder/IInterface.h>\n\n#include <utils/RefBase.h>\n\nnamespace android {\n\n// ProducerListener is the interface through which the BufferQueue notifies the\n// producer of events that the producer may wish to react to. Because the\n// producer will generally have a mutex that is locked during calls from the\n// producer to the BufferQueue, these calls from the BufferQueue to the\n// producer *MUST* be called only when the BufferQueue mutex is NOT locked.\n\nclass ProducerListener : public virtual RefBase\n{\npublic:\n    ProducerListener() {}\n    virtual ~ProducerListener() {}\n\n    // onBufferReleased is called from IGraphicBufferConsumer::releaseBuffer to\n    // notify the producer that a new buffer is free and ready to be dequeued.\n    //\n    // This is called without any lock held and can be called concurrently by\n    // multiple threads.\n    virtual void onBufferReleased() = 0; // Asynchronous\n};\n\nclass IProducerListener : public ProducerListener, public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(ProducerListener)\n};\n\nclass BnProducerListener : public BnInterface<IProducerListener>\n{\npublic:\n    virtual status_t onTransact(uint32_t code, const Parcel& data,\n            Parcel* reply, uint32_t flags = 0);\n};\n\nclass DummyProducerListener : public BnProducerListener\n{\npublic:\n    virtual void onBufferReleased() {}\n};\n\n} // namespace android\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/ISensorEventConnection.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_ISENSOR_EVENT_CONNECTION_H\n#define ANDROID_GUI_ISENSOR_EVENT_CONNECTION_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Errors.h>\n#include <utils/RefBase.h>\n\n#include <binder/IInterface.h>\n\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass BitTube;\n\nclass ISensorEventConnection : public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(SensorEventConnection);\n\n    virtual sp<BitTube> getSensorChannel() const = 0;\n    virtual status_t enableDisable(int handle, bool enabled, nsecs_t samplingPeriodNs,\n                                   nsecs_t maxBatchReportLatencyNs, int reservedFlags) = 0;\n    virtual status_t setEventRate(int handle, nsecs_t ns) = 0;\n    virtual status_t flush() = 0;\n};\n\n// ----------------------------------------------------------------------------\n\nclass BnSensorEventConnection : public BnInterface<ISensorEventConnection>\n{\npublic:\n    virtual status_t    onTransact( uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_ISENSOR_EVENT_CONNECTION_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/ISensorServer.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_ISENSORSERVER_H\n#define ANDROID_GUI_ISENSORSERVER_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Errors.h>\n#include <utils/RefBase.h>\n\n#include <binder/IInterface.h>\n\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass Sensor;\nclass ISensorEventConnection;\nclass String8;\n\nclass ISensorServer : public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(SensorServer);\n\n    virtual Vector<Sensor> getSensorList(const String16& opPackageName) = 0;\n    virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName) = 0;\n\n    virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,\n             int mode, const String16& opPackageName) = 0;\n    virtual int32_t isDataInjectionEnabled() = 0;\n};\n\n// ----------------------------------------------------------------------------\n\nclass BnSensorServer : public BnInterface<ISensorServer>\n{\npublic:\n    virtual status_t    onTransact( uint32_t code,\n                                    const Parcel& data,\n                                    Parcel* reply,\n                                    uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_ISENSORSERVER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/ISurfaceComposer.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_ISURFACE_COMPOSER_H\n#define ANDROID_GUI_ISURFACE_COMPOSER_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/RefBase.h>\n#include <utils/Errors.h>\n#include <utils/Timers.h>\n#include <utils/Vector.h>\n\n#include <binder/IInterface.h>\n\n#include <ui/FrameStats.h>\n\n#include <gui/IGraphicBufferAlloc.h>\n#include <gui/ISurfaceComposerClient.h>\n\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass ComposerState;\nclass DisplayState;\nstruct DisplayInfo;\nstruct DisplayStatInfo;\nclass HdrCapabilities;\nclass IDisplayEventConnection;\nclass IMemoryHeap;\nclass Rect;\n\n/*\n * This class defines the Binder IPC interface for accessing various\n * SurfaceFlinger features.\n */\nclass ISurfaceComposer: public IInterface {\npublic:\n    DECLARE_META_INTERFACE(SurfaceComposer);\n\n    // flags for setTransactionState()\n    enum {\n        eSynchronous = 0x01,\n        eAnimation   = 0x02,\n    };\n\n    enum {\n        eDisplayIdMain = 0,\n        eDisplayIdHdmi = 1\n    };\n\n    enum Rotation {\n        eRotateNone = 0,\n        eRotate90   = 1,\n        eRotate180  = 2,\n        eRotate270  = 3\n    };\n\n    /* create connection with surface flinger, requires\n     * ACCESS_SURFACE_FLINGER permission\n     */\n    virtual sp<ISurfaceComposerClient> createConnection() = 0;\n\n    /* create a graphic buffer allocator\n     */\n    virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc() = 0;\n\n    /* return an IDisplayEventConnection */\n    virtual sp<IDisplayEventConnection> createDisplayEventConnection() = 0;\n\n    /* create a virtual display\n     * requires ACCESS_SURFACE_FLINGER permission.\n     */\n    virtual sp<IBinder> createDisplay(const String8& displayName,\n            bool secure) = 0;\n\n    /* destroy a virtual display\n     * requires ACCESS_SURFACE_FLINGER permission.\n     */\n    virtual void destroyDisplay(const sp<IBinder>& display) = 0;\n\n    /* get the token for the existing default displays. possible values\n     * for id are eDisplayIdMain and eDisplayIdHdmi.\n     */\n    virtual sp<IBinder> getBuiltInDisplay(int32_t id) = 0;\n\n    /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */\n    virtual void setTransactionState(const Vector<ComposerState>& state,\n            const Vector<DisplayState>& displays, uint32_t flags) = 0;\n\n    /* signal that we're done booting.\n     * Requires ACCESS_SURFACE_FLINGER permission\n     */\n    virtual void bootFinished() = 0;\n\n    /* verify that an IGraphicBufferProducer was created by SurfaceFlinger.\n     */\n    virtual bool authenticateSurfaceTexture(\n            const sp<IGraphicBufferProducer>& surface) const = 0;\n\n    /* set display power mode. depending on the mode, it can either trigger\n     * screen on, off or low power mode and wait for it to complete.\n     * requires ACCESS_SURFACE_FLINGER permission.\n     */\n    virtual void setPowerMode(const sp<IBinder>& display, int mode) = 0;\n\n    /* returns information for each configuration of the given display\n     * intended to be used to get information about built-in displays */\n    virtual status_t getDisplayConfigs(const sp<IBinder>& display,\n            Vector<DisplayInfo>* configs) = 0;\n\n    /* returns display statistics for a given display\n     * intended to be used by the media framework to properly schedule\n     * video frames */\n    virtual status_t getDisplayStats(const sp<IBinder>& display,\n            DisplayStatInfo* stats) = 0;\n\n    /* indicates which of the configurations returned by getDisplayInfo is\n     * currently active */\n    virtual int getActiveConfig(const sp<IBinder>& display) = 0;\n\n    /* specifies which configuration (of those returned by getDisplayInfo)\n     * should be used */\n    virtual status_t setActiveConfig(const sp<IBinder>& display, int id) = 0;\n\n    /* Capture the specified screen. requires READ_FRAME_BUFFER permission\n     * This function will fail if there is a secure window on screen.\n     */\n    virtual status_t captureScreen(const sp<IBinder>& display,\n            const sp<IGraphicBufferProducer>& producer,\n            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,\n            uint32_t minLayerZ, uint32_t maxLayerZ,\n            bool useIdentityTransform,\n            Rotation rotation = eRotateNone) = 0;\n\n    /* Clears the frame statistics for animations.\n     *\n     * Requires the ACCESS_SURFACE_FLINGER permission.\n     */\n    virtual status_t clearAnimationFrameStats() = 0;\n\n    /* Gets the frame statistics for animations.\n     *\n     * Requires the ACCESS_SURFACE_FLINGER permission.\n     */\n    virtual status_t getAnimationFrameStats(FrameStats* outStats) const = 0;\n\n    /* Gets the supported HDR capabilities of the given display.\n     *\n     * Requires the ACCESS_SURFACE_FLINGER permission.\n     */\n    virtual status_t getHdrCapabilities(const sp<IBinder>& display,\n            HdrCapabilities* outCapabilities) const = 0;\n};\n\n// ----------------------------------------------------------------------------\n\nclass BnSurfaceComposer: public BnInterface<ISurfaceComposer> {\npublic:\n    enum {\n        // Note: BOOT_FINISHED must remain this value, it is called from\n        // Java by ActivityManagerService.\n        BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,\n        CREATE_CONNECTION,\n        CREATE_GRAPHIC_BUFFER_ALLOC,\n        CREATE_DISPLAY_EVENT_CONNECTION,\n        CREATE_DISPLAY,\n        DESTROY_DISPLAY,\n        GET_BUILT_IN_DISPLAY,\n        SET_TRANSACTION_STATE,\n        AUTHENTICATE_SURFACE,\n        GET_DISPLAY_CONFIGS,\n        GET_ACTIVE_CONFIG,\n        SET_ACTIVE_CONFIG,\n        CONNECT_DISPLAY,\n        CAPTURE_SCREEN,\n        CLEAR_ANIMATION_FRAME_STATS,\n        GET_ANIMATION_FRAME_STATS,\n        SET_POWER_MODE,\n        GET_DISPLAY_STATS,\n        GET_HDR_CAPABILITIES,\n    };\n\n    virtual status_t onTransact(uint32_t code, const Parcel& data,\n            Parcel* reply, uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_GUI_ISURFACE_COMPOSER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/ISurfaceComposerClient.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_ISURFACE_COMPOSER_CLIENT_H\n#define ANDROID_GUI_ISURFACE_COMPOSER_CLIENT_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Errors.h>\n#include <utils/RefBase.h>\n\n#include <binder/IInterface.h>\n\n#include <ui/FrameStats.h>\n#include <ui/PixelFormat.h>\n\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass IGraphicBufferProducer;\n\nclass ISurfaceComposerClient : public IInterface\n{\npublic:\n    DECLARE_META_INTERFACE(SurfaceComposerClient);\n\n    // flags for createSurface()\n    enum { // (keep in sync with Surface.java)\n        eHidden             = 0x00000004,\n        eDestroyBackbuffer  = 0x00000020,\n        eSecure             = 0x00000080,\n        eNonPremultiplied   = 0x00000100,\n        eOpaque             = 0x00000400,\n        eProtectedByApp     = 0x00000800,\n        eProtectedByDRM     = 0x00001000,\n        eCursorWindow       = 0x00002000,\n\n        eFXSurfaceNormal    = 0x00000000,\n        eFXSurfaceDim       = 0x00020000,\n        eFXSurfaceMask      = 0x000F0000,\n    };\n\n    /*\n     * Requires ACCESS_SURFACE_FLINGER permission\n     */\n    virtual status_t createSurface(\n            const String8& name, uint32_t w, uint32_t h,\n            PixelFormat format, uint32_t flags,\n            sp<IBinder>* handle,\n            sp<IGraphicBufferProducer>* gbp) = 0;\n\n    /*\n     * Requires ACCESS_SURFACE_FLINGER permission\n     */\n    virtual status_t destroySurface(const sp<IBinder>& handle) = 0;\n\n    /*\n     * Requires ACCESS_SURFACE_FLINGER permission\n     */\n    virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const = 0;\n\n    /*\n     * Requires ACCESS_SURFACE_FLINGER permission\n     */\n    virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const = 0;\n};\n\n// ----------------------------------------------------------------------------\n\nclass BnSurfaceComposerClient: public BnInterface<ISurfaceComposerClient> {\npublic:\n    virtual status_t onTransact(uint32_t code, const Parcel& data,\n            Parcel* reply, uint32_t flags = 0);\n};\n\n// ----------------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_GUI_ISURFACE_COMPOSER_CLIENT_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/Sensor.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_SENSOR_H\n#define ANDROID_GUI_SENSOR_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Errors.h>\n#include <utils/Flattenable.h>\n#include <utils/String8.h>\n#include <utils/Timers.h>\n\n#include <hardware/sensors.h>\n\n#include <android/sensor.h>\n\n// ----------------------------------------------------------------------------\n// Concrete types for the NDK\nstruct ASensor { };\n\n// ----------------------------------------------------------------------------\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass Parcel;\n\n// ----------------------------------------------------------------------------\n\nclass Sensor : public ASensor, public LightFlattenable<Sensor>\n{\npublic:\n    enum {\n        TYPE_ACCELEROMETER  = ASENSOR_TYPE_ACCELEROMETER,\n        TYPE_MAGNETIC_FIELD = ASENSOR_TYPE_MAGNETIC_FIELD,\n        TYPE_GYROSCOPE      = ASENSOR_TYPE_GYROSCOPE,\n        TYPE_LIGHT          = ASENSOR_TYPE_LIGHT,\n        TYPE_PROXIMITY      = ASENSOR_TYPE_PROXIMITY\n    };\n\n    struct uuid_t{\n        union {\n            uint8_t b[16];\n            int64_t i64[2];\n        };\n        uuid_t(const uint8_t (&uuid)[16]) { memcpy(b, uuid, sizeof(b));}\n        uuid_t() : b{0} {}\n    };\n\n    Sensor(const char * name = \"\");\n    Sensor(struct sensor_t const* hwSensor, int halVersion = 0);\n    Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersion = 0);\n    ~Sensor();\n\n    const String8& getName() const;\n    const String8& getVendor() const;\n    int32_t getHandle() const;\n    int32_t getType() const;\n    float getMinValue() const;\n    float getMaxValue() const;\n    float getResolution() const;\n    float getPowerUsage() const;\n    int32_t getMinDelay() const;\n    nsecs_t getMinDelayNs() const;\n    int32_t getVersion() const;\n    uint32_t getFifoReservedEventCount() const;\n    uint32_t getFifoMaxEventCount() const;\n    const String8& getStringType() const;\n    const String8& getRequiredPermission() const;\n    bool isRequiredPermissionRuntime() const;\n    int32_t getRequiredAppOp() const;\n    int32_t getMaxDelay() const;\n    uint32_t getFlags() const;\n    bool isWakeUpSensor() const;\n    bool isDynamicSensor() const;\n    bool hasAdditionalInfo() const;\n    int32_t getReportingMode() const;\n\n    // Note that after setId() has been called, getUuid() no longer\n    // returns the UUID.\n    // TODO(b/29547335): Remove getUuid(), add getUuidIndex(), and\n    //     make sure setId() doesn't change the UuidIndex.\n    const uuid_t& getUuid() const;\n    int32_t getId() const;\n    void setId(int32_t id);\n\n    // LightFlattenable protocol\n    inline bool isFixedSize() const { return false; }\n    size_t getFlattenedSize() const;\n    status_t flatten(void* buffer, size_t size) const;\n    status_t unflatten(void const* buffer, size_t size);\n\nprivate:\n    String8 mName;\n    String8 mVendor;\n    int32_t mHandle;\n    int32_t mType;\n    float   mMinValue;\n    float   mMaxValue;\n    float   mResolution;\n    float   mPower;\n    int32_t mMinDelay;\n    int32_t mVersion;\n    uint32_t mFifoReservedEventCount;\n    uint32_t mFifoMaxEventCount;\n    String8 mStringType;\n    String8 mRequiredPermission;\n    bool mRequiredPermissionRuntime = false;\n    int32_t mRequiredAppOp;\n    int32_t mMaxDelay;\n    uint32_t mFlags;\n    // TODO(b/29547335): Get rid of this field and replace with an index.\n    //     The index will be into a separate global vector of UUIDs.\n    //     Also add an mId field (and change flatten/unflatten appropriately).\n    uuid_t  mUuid;\n    static void flattenString8(void*& buffer, size_t& size, const String8& string8);\n    static bool unflattenString8(void const*& buffer, size_t& size, String8& outputString8);\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_SENSOR_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/SensorEventQueue.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_SENSOR_EVENT_QUEUE_H\n#define ANDROID_SENSOR_EVENT_QUEUE_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Errors.h>\n#include <utils/RefBase.h>\n#include <utils/Timers.h>\n#include <utils/String16.h>\n\n#include <gui/BitTube.h>\n\n// ----------------------------------------------------------------------------\n#define WAKE_UP_SENSOR_EVENT_NEEDS_ACK (1U << 31)\nstruct ALooper;\nstruct ASensorEvent;\n\n// Concrete types for the NDK\nstruct ASensorEventQueue {\n    ALooper* looper;\n};\n\n// ----------------------------------------------------------------------------\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass ISensorEventConnection;\nclass Sensor;\nclass Looper;\n\n// ----------------------------------------------------------------------------\n\nclass SensorEventQueue : public ASensorEventQueue, public RefBase\n{\npublic:\n\n    enum { MAX_RECEIVE_BUFFER_EVENT_COUNT = 256 };\n\n    /**\n     * Typical sensor delay (sample period) in microseconds.\n     */\n    // Fastest sampling, system will bound it to minDelay\n    static constexpr int32_t SENSOR_DELAY_FASTEST = 0;\n    // Typical sample period for game, 50Hz;\n    static constexpr int32_t SENSOR_DELAY_GAME = 20000;\n    // Typical sample period for UI, 15Hz\n    static constexpr int32_t SENSOR_DELAY_UI = 66667;\n    // Default sensor sample period\n    static constexpr int32_t SENSOR_DELAY_NORMAL = 200000;\n\n    SensorEventQueue(const sp<ISensorEventConnection>& connection);\n    virtual ~SensorEventQueue();\n    virtual void onFirstRef();\n\n    int getFd() const;\n\n    static ssize_t write(const sp<BitTube>& tube,\n            ASensorEvent const* events, size_t numEvents);\n\n    ssize_t read(ASensorEvent* events, size_t numEvents);\n\n    status_t waitForEvent() const;\n    status_t wake() const;\n\n    status_t enableSensor(Sensor const* sensor) const;\n    status_t enableSensor(Sensor const* sensor, int32_t samplingPeriodUs) const;\n    status_t disableSensor(Sensor const* sensor) const;\n    status_t setEventRate(Sensor const* sensor, nsecs_t ns) const;\n\n    // these are here only to support SensorManager.java\n    status_t enableSensor(int32_t handle, int32_t samplingPeriodUs, int maxBatchReportLatencyUs,\n                          int reservedFlags) const;\n    status_t disableSensor(int32_t handle) const;\n    status_t flush() const;\n    // Send an ack for every wake_up sensor event that is set to WAKE_UP_SENSOR_EVENT_NEEDS_ACK.\n    void sendAck(const ASensorEvent* events, int count);\n\n    status_t injectSensorEvent(const ASensorEvent& event);\nprivate:\n    sp<Looper> getLooper() const;\n    sp<ISensorEventConnection> mSensorEventConnection;\n    sp<BitTube> mSensorChannel;\n    mutable Mutex mLock;\n    mutable sp<Looper> mLooper;\n    ASensorEvent* mRecBuffer;\n    size_t mAvailable;\n    size_t mConsumed;\n    uint32_t mNumAcksToSend;\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_SENSOR_EVENT_QUEUE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/SensorManager.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_SENSOR_MANAGER_H\n#define ANDROID_GUI_SENSOR_MANAGER_H\n\n#include <map>\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <binder/IBinder.h>\n#include <binder/IPCThreadState.h>\n#include <binder/IServiceManager.h>\n\n#include <utils/Errors.h>\n#include <utils/RefBase.h>\n#include <utils/Singleton.h>\n#include <utils/Vector.h>\n#include <utils/String8.h>\n\n#include <gui/SensorEventQueue.h>\n\n// ----------------------------------------------------------------------------\n// Concrete types for the NDK\nstruct ASensorManager { };\n\n// ----------------------------------------------------------------------------\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass ISensorServer;\nclass Sensor;\nclass SensorEventQueue;\n// ----------------------------------------------------------------------------\n\nclass SensorManager :\n    public ASensorManager\n{\npublic:\n    static SensorManager& getInstanceForPackage(const String16& packageName);\n    ~SensorManager();\n\n    ssize_t getSensorList(Sensor const* const** list);\n    ssize_t getDynamicSensorList(Vector<Sensor>& list);\n    Sensor const* getDefaultSensor(int type);\n    sp<SensorEventQueue> createEventQueue(String8 packageName = String8(\"\"), int mode = 0);\n    bool isDataInjectionEnabled();\n\nprivate:\n    // DeathRecipient interface\n    void sensorManagerDied();\n\n    SensorManager(const String16& opPackageName);\n    status_t assertStateLocked();\n\nprivate:\n    static Mutex sLock;\n    static std::map<String16, SensorManager*> sPackageInstances;\n\n    Mutex mLock;\n    sp<ISensorServer> mSensorServer;\n    Sensor const** mSensorList;\n    Vector<Sensor> mSensors;\n    sp<IBinder::DeathRecipient> mDeathObserver;\n    const String16 mOpPackageName;\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_SENSOR_MANAGER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/StreamSplitter.h",
    "content": "/*\n * Copyright 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_STREAMSPLITTER_H\n#define ANDROID_GUI_STREAMSPLITTER_H\n\n#include <gui/IConsumerListener.h>\n#include <gui/IProducerListener.h>\n\n#include <utils/Condition.h>\n#include <utils/KeyedVector.h>\n#include <utils/Mutex.h>\n#include <utils/StrongPointer.h>\n\nnamespace android {\n\nclass GraphicBuffer;\nclass IGraphicBufferConsumer;\nclass IGraphicBufferProducer;\n\n// StreamSplitter is an autonomous class that manages one input BufferQueue\n// and multiple output BufferQueues. By using the buffer attach and detach logic\n// in BufferQueue, it is able to present the illusion of a single split\n// BufferQueue, where each buffer queued to the input is available to be\n// acquired by each of the outputs, and is able to be dequeued by the input\n// again only once all of the outputs have released it.\nclass StreamSplitter : public BnConsumerListener {\npublic:\n    // createSplitter creates a new splitter, outSplitter, using inputQueue as\n    // the input BufferQueue. Output BufferQueues must be added using addOutput\n    // before queueing any buffers to the input.\n    //\n    // A return value other than NO_ERROR means that an error has occurred and\n    // outSplitter has not been modified. BAD_VALUE is returned if inputQueue or\n    // outSplitter is NULL. See IGraphicBufferConsumer::consumerConnect for\n    // explanations of other error codes.\n    static status_t createSplitter(const sp<IGraphicBufferConsumer>& inputQueue,\n            sp<StreamSplitter>* outSplitter);\n\n    // addOutput adds an output BufferQueue to the splitter. The splitter\n    // connects to outputQueue as a CPU producer, and any buffers queued\n    // to the input will be queued to each output. It is assumed that all of the\n    // outputs are added before any buffers are queued on the input. If any\n    // output is abandoned by its consumer, the splitter will abandon its input\n    // queue (see onAbandoned).\n    //\n    // A return value other than NO_ERROR means that an error has occurred and\n    // outputQueue has not been added to the splitter. BAD_VALUE is returned if\n    // outputQueue is NULL. See IGraphicBufferProducer::connect for explanations\n    // of other error codes.\n    status_t addOutput(const sp<IGraphicBufferProducer>& outputQueue);\n\n    // setName sets the consumer name of the input queue\n    void setName(const String8& name);\n\nprivate:\n    // From IConsumerListener\n    //\n    // During this callback, we store some tracking information, detach the\n    // buffer from the input, and attach it to each of the outputs. This call\n    // can block if there are too many outstanding buffers. If it blocks, it\n    // will resume when onBufferReleasedByOutput releases a buffer back to the\n    // input.\n    virtual void onFrameAvailable(const BufferItem& item);\n\n    // From IConsumerListener\n    // We don't care about released buffers because we detach each buffer as\n    // soon as we acquire it. See the comment for onBufferReleased below for\n    // some clarifying notes about the name.\n    virtual void onBuffersReleased() {}\n\n    // From IConsumerListener\n    // We don't care about sideband streams, since we won't be splitting them\n    virtual void onSidebandStreamChanged() {}\n\n    // This is the implementation of the onBufferReleased callback from\n    // IProducerListener. It gets called from an OutputListener (see below), and\n    // 'from' is which producer interface from which the callback was received.\n    //\n    // During this callback, we detach the buffer from the output queue that\n    // generated the callback, update our state tracking to see if this is the\n    // last output releasing the buffer, and if so, release it to the input.\n    // If we release the buffer to the input, we allow a blocked\n    // onFrameAvailable call to proceed.\n    void onBufferReleasedByOutput(const sp<IGraphicBufferProducer>& from);\n\n    // When this is called, the splitter disconnects from (i.e., abandons) its\n    // input queue and signals any waiting onFrameAvailable calls to wake up.\n    // It still processes callbacks from other outputs, but only detaches their\n    // buffers so they can continue operating until they run out of buffers to\n    // acquire. This must be called with mMutex locked.\n    void onAbandonedLocked();\n\n    // This is a thin wrapper class that lets us determine which BufferQueue\n    // the IProducerListener::onBufferReleased callback is associated with. We\n    // create one of these per output BufferQueue, and then pass the producer\n    // into onBufferReleasedByOutput above.\n    class OutputListener : public BnProducerListener,\n                           public IBinder::DeathRecipient {\n    public:\n        OutputListener(const sp<StreamSplitter>& splitter,\n                const sp<IGraphicBufferProducer>& output);\n        virtual ~OutputListener();\n\n        // From IProducerListener\n        virtual void onBufferReleased();\n\n        // From IBinder::DeathRecipient\n        virtual void binderDied(const wp<IBinder>& who);\n\n    private:\n        sp<StreamSplitter> mSplitter;\n        sp<IGraphicBufferProducer> mOutput;\n    };\n\n    class BufferTracker : public LightRefBase<BufferTracker> {\n    public:\n        BufferTracker(const sp<GraphicBuffer>& buffer);\n\n        const sp<GraphicBuffer>& getBuffer() const { return mBuffer; }\n        const sp<Fence>& getMergedFence() const { return mMergedFence; }\n\n        void mergeFence(const sp<Fence>& with);\n\n        // Returns the new value\n        // Only called while mMutex is held\n        size_t incrementReleaseCountLocked() { return ++mReleaseCount; }\n\n    private:\n        // Only destroy through LightRefBase\n        friend LightRefBase<BufferTracker>;\n        ~BufferTracker();\n\n        // Disallow copying\n        BufferTracker(const BufferTracker& other);\n        BufferTracker& operator=(const BufferTracker& other);\n\n        sp<GraphicBuffer> mBuffer; // One instance that holds this native handle\n        sp<Fence> mMergedFence;\n        size_t mReleaseCount;\n    };\n\n    // Only called from createSplitter\n    StreamSplitter(const sp<IGraphicBufferConsumer>& inputQueue);\n\n    // Must be accessed through RefBase\n    virtual ~StreamSplitter();\n\n    static const int MAX_OUTSTANDING_BUFFERS = 2;\n\n    // mIsAbandoned is set to true when an output dies. Once the StreamSplitter\n    // has been abandoned, it will continue to detach buffers from other\n    // outputs, but it will disconnect from the input and not attempt to\n    // communicate with it further.\n    bool mIsAbandoned;\n\n    Mutex mMutex;\n    Condition mReleaseCondition;\n    int mOutstandingBuffers;\n    sp<IGraphicBufferConsumer> mInput;\n    Vector<sp<IGraphicBufferProducer> > mOutputs;\n\n    // Map of GraphicBuffer IDs (GraphicBuffer::getId()) to buffer tracking\n    // objects (which are mostly for counting how many outputs have released the\n    // buffer, but also contain merged release fences).\n    KeyedVector<uint64_t, sp<BufferTracker> > mBuffers;\n};\n\n} // namespace android\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/Surface.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_SURFACE_H\n#define ANDROID_GUI_SURFACE_H\n\n#include <gui/IGraphicBufferProducer.h>\n#include <gui/BufferQueue.h>\n\n#include <ui/ANativeObjectBase.h>\n#include <ui/Region.h>\n\n#include <binder/Parcelable.h>\n\n#include <utils/RefBase.h>\n#include <utils/threads.h>\n#include <utils/KeyedVector.h>\n\nstruct ANativeWindow_Buffer;\n\nnamespace android {\n\n/*\n * An implementation of ANativeWindow that feeds graphics buffers into a\n * BufferQueue.\n *\n * This is typically used by programs that want to render frames through\n * some means (maybe OpenGL, a software renderer, or a hardware decoder)\n * and have the frames they create forwarded to SurfaceFlinger for\n * compositing.  For example, a video decoder could render a frame and call\n * eglSwapBuffers(), which invokes ANativeWindow callbacks defined by\n * Surface.  Surface then forwards the buffers through Binder IPC\n * to the BufferQueue's producer interface, providing the new frame to a\n * consumer such as GLConsumer.\n */\nclass Surface\n    : public ANativeObjectBase<ANativeWindow, Surface, RefBase>\n{\npublic:\n\n    /*\n     * creates a Surface from the given IGraphicBufferProducer (which concrete\n     * implementation is a BufferQueue).\n     *\n     * Surface is mainly state-less while it's disconnected, it can be\n     * viewed as a glorified IGraphicBufferProducer holder. It's therefore\n     * safe to create other Surfaces from the same IGraphicBufferProducer.\n     *\n     * However, once a Surface is connected, it'll prevent other Surfaces\n     * referring to the same IGraphicBufferProducer to become connected and\n     * therefore prevent them to be used as actual producers of buffers.\n     *\n     * the controlledByApp flag indicates that this Surface (producer) is\n     * controlled by the application. This flag is used at connect time.\n     */\n    Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp = false);\n\n    /* getIGraphicBufferProducer() returns the IGraphicBufferProducer this\n     * Surface was created with. Usually it's an error to use the\n     * IGraphicBufferProducer while the Surface is connected.\n     */\n    sp<IGraphicBufferProducer> getIGraphicBufferProducer() const;\n\n    /* convenience function to check that the given surface is non NULL as\n     * well as its IGraphicBufferProducer */\n    static bool isValid(const sp<Surface>& surface) {\n        return surface != NULL && surface->getIGraphicBufferProducer() != NULL;\n    }\n\n    /* Attaches a sideband buffer stream to the Surface's IGraphicBufferProducer.\n     *\n     * A sideband stream is a device-specific mechanism for passing buffers\n     * from the producer to the consumer without using dequeueBuffer/\n     * queueBuffer. If a sideband stream is present, the consumer can choose\n     * whether to acquire buffers from the sideband stream or from the queued\n     * buffers.\n     *\n     * Passing NULL or a different stream handle will detach the previous\n     * handle if any.\n     */\n    void setSidebandStream(const sp<NativeHandle>& stream);\n\n    /* Allocates buffers based on the current dimensions/format.\n     *\n     * This function will allocate up to the maximum number of buffers\n     * permitted by the current BufferQueue configuration. It will use the\n     * default format and dimensions. This is most useful to avoid an allocation\n     * delay during dequeueBuffer. If there are already the maximum number of\n     * buffers allocated, this function has no effect.\n     */\n    void allocateBuffers();\n\n    /* Sets the generation number on the IGraphicBufferProducer and updates the\n     * generation number on any buffers attached to the Surface after this call.\n     * See IGBP::setGenerationNumber for more information. */\n    status_t setGenerationNumber(uint32_t generationNumber);\n\n    // See IGraphicBufferProducer::getConsumerName\n    String8 getConsumerName() const;\n\n    // See IGraphicBufferProducer::getNextFrameNumber\n    uint64_t getNextFrameNumber() const;\n\n    /* Set the scaling mode to be used with a Surface.\n     * See NATIVE_WINDOW_SET_SCALING_MODE and its parameters\n     * in <system/window.h>. */\n    int setScalingMode(int mode);\n\n    // See IGraphicBufferProducer::setDequeueTimeout\n    status_t setDequeueTimeout(nsecs_t timeout);\n\n    /*\n     * Wait for frame number to increase past lastFrame for at most\n     * timeoutNs. Useful for one thread to wait for another unknown\n     * thread to queue a buffer.\n     */\n    bool waitForNextFrame(uint64_t lastFrame, nsecs_t timeout);\n\n    // See IGraphicBufferProducer::getLastQueuedBuffer\n    // See GLConsumer::getTransformMatrix for outTransformMatrix format\n    status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,\n            sp<Fence>* outFence, float outTransformMatrix[16]);\n\n    status_t getUniqueId(uint64_t* outId) const;\n\nprotected:\n    virtual ~Surface();\n\nprivate:\n    // can't be copied\n    Surface& operator = (const Surface& rhs);\n    Surface(const Surface& rhs);\n\n    // ANativeWindow hooks\n    static int hook_cancelBuffer(ANativeWindow* window,\n            ANativeWindowBuffer* buffer, int fenceFd);\n    static int hook_dequeueBuffer(ANativeWindow* window,\n            ANativeWindowBuffer** buffer, int* fenceFd);\n    static int hook_perform(ANativeWindow* window, int operation, ...);\n    static int hook_query(const ANativeWindow* window, int what, int* value);\n    static int hook_queueBuffer(ANativeWindow* window,\n            ANativeWindowBuffer* buffer, int fenceFd);\n    static int hook_setSwapInterval(ANativeWindow* window, int interval);\n\n    static int hook_cancelBuffer_DEPRECATED(ANativeWindow* window,\n            ANativeWindowBuffer* buffer);\n    static int hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,\n            ANativeWindowBuffer** buffer);\n    static int hook_lockBuffer_DEPRECATED(ANativeWindow* window,\n            ANativeWindowBuffer* buffer);\n    static int hook_queueBuffer_DEPRECATED(ANativeWindow* window,\n            ANativeWindowBuffer* buffer);\n\n    int dispatchConnect(va_list args);\n    int dispatchDisconnect(va_list args);\n    int dispatchSetBufferCount(va_list args);\n    int dispatchSetBuffersGeometry(va_list args);\n    int dispatchSetBuffersDimensions(va_list args);\n    int dispatchSetBuffersUserDimensions(va_list args);\n    int dispatchSetBuffersFormat(va_list args);\n    int dispatchSetScalingMode(va_list args);\n    int dispatchSetBuffersTransform(va_list args);\n    int dispatchSetBuffersStickyTransform(va_list args);\n    int dispatchSetBuffersTimestamp(va_list args);\n    int dispatchSetCrop(va_list args);\n    int dispatchSetPostTransformCrop(va_list args);\n    int dispatchSetUsage(va_list args);\n    int dispatchLock(va_list args);\n    int dispatchUnlockAndPost(va_list args);\n    int dispatchSetSidebandStream(va_list args);\n    int dispatchSetBuffersDataSpace(va_list args);\n    int dispatchSetSurfaceDamage(va_list args);\n    int dispatchSetSharedBufferMode(va_list args);\n    int dispatchSetAutoRefresh(va_list args);\n\nprotected:\n    virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd);\n    virtual int cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd);\n    virtual int queueBuffer(ANativeWindowBuffer* buffer, int fenceFd);\n    virtual int perform(int operation, va_list args);\n    virtual int query(int what, int* value) const;\n    virtual int setSwapInterval(int interval);\n\n    virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer);\n\n    virtual int connect(int api);\n    virtual int disconnect(int api);\n    virtual int setBufferCount(int bufferCount);\n    virtual int setBuffersDimensions(uint32_t width, uint32_t height);\n    virtual int setBuffersUserDimensions(uint32_t width, uint32_t height);\n    virtual int setBuffersFormat(PixelFormat format);\n    virtual int setBuffersTransform(uint32_t transform);\n    virtual int setBuffersStickyTransform(uint32_t transform);\n    virtual int setBuffersTimestamp(int64_t timestamp);\n    virtual int setBuffersDataSpace(android_dataspace dataSpace);\n    virtual int setCrop(Rect const* rect);\n    virtual int setUsage(uint32_t reqUsage);\n    virtual void setSurfaceDamage(android_native_rect_t* rects, size_t numRects);\n\npublic:\n    virtual int setMaxDequeuedBufferCount(int maxDequeuedBuffers);\n    virtual int setAsyncMode(bool async);\n    virtual int setSharedBufferMode(bool sharedBufferMode);\n    virtual int setAutoRefresh(bool autoRefresh);\n    virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);\n    virtual int unlockAndPost();\n\n    virtual int connect(int api, const sp<IProducerListener>& listener);\n    virtual int detachNextBuffer(sp<GraphicBuffer>* outBuffer,\n            sp<Fence>* outFence);\n    virtual int attachBuffer(ANativeWindowBuffer*);\n\nprotected:\n    enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS };\n    enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };\n\nprivate:\n    void freeAllBuffers();\n    int getSlotFromBufferLocked(android_native_buffer_t* buffer) const;\n\n    struct BufferSlot {\n        sp<GraphicBuffer> buffer;\n        Region dirtyRegion;\n    };\n\n    // mSurfaceTexture is the interface to the surface texture server. All\n    // operations on the surface texture client ultimately translate into\n    // interactions with the server using this interface.\n    // TODO: rename to mBufferProducer\n    sp<IGraphicBufferProducer> mGraphicBufferProducer;\n\n    // mSlots stores the buffers that have been allocated for each buffer slot.\n    // It is initialized to null pointers, and gets filled in with the result of\n    // IGraphicBufferProducer::requestBuffer when the client dequeues a buffer from a\n    // slot that has not yet been used. The buffer allocated to a slot will also\n    // be replaced if the requested buffer usage or geometry differs from that\n    // of the buffer allocated to a slot.\n    BufferSlot mSlots[NUM_BUFFER_SLOTS];\n\n    // mReqWidth is the buffer width that will be requested at the next dequeue\n    // operation. It is initialized to 1.\n    uint32_t mReqWidth;\n\n    // mReqHeight is the buffer height that will be requested at the next\n    // dequeue operation. It is initialized to 1.\n    uint32_t mReqHeight;\n\n    // mReqFormat is the buffer pixel format that will be requested at the next\n    // deuque operation. It is initialized to PIXEL_FORMAT_RGBA_8888.\n    PixelFormat mReqFormat;\n\n    // mReqUsage is the set of buffer usage flags that will be requested\n    // at the next deuque operation. It is initialized to 0.\n    uint32_t mReqUsage;\n\n    // mTimestamp is the timestamp that will be used for the next buffer queue\n    // operation. It defaults to NATIVE_WINDOW_TIMESTAMP_AUTO, which means that\n    // a timestamp is auto-generated when queueBuffer is called.\n    int64_t mTimestamp;\n\n    // mDataSpace is the buffer dataSpace that will be used for the next buffer\n    // queue operation. It defaults to HAL_DATASPACE_UNKNOWN, which\n    // means that the buffer contains some type of color data.\n    android_dataspace mDataSpace;\n\n    // mCrop is the crop rectangle that will be used for the next buffer\n    // that gets queued. It is set by calling setCrop.\n    Rect mCrop;\n\n    // mScalingMode is the scaling mode that will be used for the next\n    // buffers that get queued. It is set by calling setScalingMode.\n    int mScalingMode;\n\n    // mTransform is the transform identifier that will be used for the next\n    // buffer that gets queued. It is set by calling setTransform.\n    uint32_t mTransform;\n\n    // mStickyTransform is a transform that is applied on top of mTransform\n    // in each buffer that is queued.  This is typically used to force the\n    // compositor to apply a transform, and will prevent the transform hint\n    // from being set by the compositor.\n    uint32_t mStickyTransform;\n\n    // mDefaultWidth is default width of the buffers, regardless of the\n    // native_window_set_buffers_dimensions call.\n    uint32_t mDefaultWidth;\n\n    // mDefaultHeight is default height of the buffers, regardless of the\n    // native_window_set_buffers_dimensions call.\n    uint32_t mDefaultHeight;\n\n    // mUserWidth, if non-zero, is an application-specified override\n    // of mDefaultWidth.  This is lower priority than the width set by\n    // native_window_set_buffers_dimensions.\n    uint32_t mUserWidth;\n\n    // mUserHeight, if non-zero, is an application-specified override\n    // of mDefaultHeight.  This is lower priority than the height set\n    // by native_window_set_buffers_dimensions.\n    uint32_t mUserHeight;\n\n    // mTransformHint is the transform probably applied to buffers of this\n    // window. this is only a hint, actual transform may differ.\n    uint32_t mTransformHint;\n\n    // mProducerControlledByApp whether this buffer producer is controlled\n    // by the application\n    bool mProducerControlledByApp;\n\n    // mSwapIntervalZero set if we should drop buffers at queue() time to\n    // achieve an asynchronous swap interval\n    bool mSwapIntervalZero;\n\n    // mConsumerRunningBehind whether the consumer is running more than\n    // one buffer behind the producer.\n    mutable bool mConsumerRunningBehind;\n\n    // mMutex is the mutex used to prevent concurrent access to the member\n    // variables of Surface objects. It must be locked whenever the\n    // member variables are accessed.\n    mutable Mutex mMutex;\n\n    // must be used from the lock/unlock thread\n    sp<GraphicBuffer>           mLockedBuffer;\n    sp<GraphicBuffer>           mPostedBuffer;\n    bool                        mConnectedToCpu;\n\n    // When a CPU producer is attached, this reflects the region that the\n    // producer wished to update as well as whether the Surface was able to copy\n    // the previous buffer back to allow a partial update.\n    //\n    // When a non-CPU producer is attached, this reflects the surface damage\n    // (the change since the previous frame) passed in by the producer.\n    Region mDirtyRegion;\n\n    // Stores the current generation number. See setGenerationNumber and\n    // IGraphicBufferProducer::setGenerationNumber for more information.\n    uint32_t mGenerationNumber;\n\n    // Caches the values that have been passed to the producer.\n    bool mSharedBufferMode;\n    bool mAutoRefresh;\n\n    // If in shared buffer mode and auto refresh is enabled, store the shared\n    // buffer slot and return it for all calls to queue/dequeue without going\n    // over Binder.\n    int mSharedBufferSlot;\n\n    // This is true if the shared buffer has already been queued/canceled. It's\n    // used to prevent a mismatch between the number of queue/dequeue calls.\n    bool mSharedBufferHasBeenQueued;\n\n    Condition mQueueBufferCondition;\n};\n\nnamespace view {\n\n/**\n * A simple holder for an IGraphicBufferProducer, to match the managed-side\n * android.view.Surface parcelable behavior.\n *\n * This implements android/view/Surface.aidl\n *\n * TODO: Convert IGraphicBufferProducer into AIDL so that it can be directly\n * used in managed Binder calls.\n */\nclass Surface : public Parcelable {\n  public:\n\n    String16 name;\n    sp<IGraphicBufferProducer> graphicBufferProducer;\n\n    virtual status_t writeToParcel(Parcel* parcel) const override;\n    virtual status_t readFromParcel(const Parcel* parcel) override;\n\n    // nameAlreadyWritten set to true by Surface.java, because it splits\n    // Parceling itself between managed and native code, so it only wants a part\n    // of the full parceling to happen on its native side.\n    status_t writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const;\n\n    // nameAlreadyRead set to true by Surface.java, because it splits\n    // Parceling itself between managed and native code, so it only wants a part\n    // of the full parceling to happen on its native side.\n    status_t readFromParcel(const Parcel* parcel, bool nameAlreadyRead);\n\n  private:\n\n    static String16 readMaybeEmptyString16(const Parcel* parcel);\n};\n\n} // namespace view\n\n}; // namespace android\n\n#endif  // ANDROID_GUI_SURFACE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/SurfaceComposerClient.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H\n#define ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <binder/IBinder.h>\n#include <binder/IMemory.h>\n\n#include <utils/RefBase.h>\n#include <utils/Singleton.h>\n#include <utils/SortedVector.h>\n#include <utils/threads.h>\n\n#include <ui/FrameStats.h>\n#include <ui/PixelFormat.h>\n\n#include <gui/CpuConsumer.h>\n#include <gui/SurfaceControl.h>\n\nnamespace android {\n\n// ---------------------------------------------------------------------------\n\nclass DisplayInfo;\nclass Composer;\nclass HdrCapabilities;\nclass ISurfaceComposerClient;\nclass IGraphicBufferProducer;\nclass Region;\n\n// ---------------------------------------------------------------------------\n\nclass SurfaceComposerClient : public RefBase\n{\n    friend class Composer;\npublic:\n                SurfaceComposerClient();\n    virtual     ~SurfaceComposerClient();\n\n    // Always make sure we could initialize\n    status_t    initCheck() const;\n\n    // Return the connection of this client\n    sp<IBinder> connection() const;\n\n    // Forcibly remove connection before all references have gone away.\n    void        dispose();\n\n    // callback when the composer is dies\n    status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,\n            void* cookie = NULL, uint32_t flags = 0);\n\n    // Get a list of supported configurations for a given display\n    static status_t getDisplayConfigs(const sp<IBinder>& display,\n            Vector<DisplayInfo>* configs);\n\n    // Get the DisplayInfo for the currently-active configuration\n    static status_t getDisplayInfo(const sp<IBinder>& display,\n            DisplayInfo* info);\n\n    // Get the index of the current active configuration (relative to the list\n    // returned by getDisplayInfo)\n    static int getActiveConfig(const sp<IBinder>& display);\n\n    // Set a new active configuration using an index relative to the list\n    // returned by getDisplayInfo\n    static status_t setActiveConfig(const sp<IBinder>& display, int id);\n\n    /* Triggers screen on/off or low power mode and waits for it to complete */\n    static void setDisplayPowerMode(const sp<IBinder>& display, int mode);\n\n    // ------------------------------------------------------------------------\n    // surface creation / destruction\n\n    //! Create a surface\n    sp<SurfaceControl> createSurface(\n            const String8& name,// name of the surface\n            uint32_t w,         // width in pixel\n            uint32_t h,         // height in pixel\n            PixelFormat format, // pixel-format desired\n            uint32_t flags = 0  // usage flags\n    );\n\n    //! Create a virtual display\n    static sp<IBinder> createDisplay(const String8& displayName, bool secure);\n\n    //! Destroy a virtual display\n    static void destroyDisplay(const sp<IBinder>& display);\n\n    //! Get the token for the existing default displays.\n    //! Possible values for id are eDisplayIdMain and eDisplayIdHdmi.\n    static sp<IBinder> getBuiltInDisplay(int32_t id);\n\n    // ------------------------------------------------------------------------\n    // Composer parameters\n    // All composer parameters must be changed within a transaction\n    // several surfaces can be updated in one transaction, all changes are\n    // committed at once when the transaction is closed.\n    // closeGlobalTransaction() requires an IPC with the server.\n\n    //! Open a composer transaction on all active SurfaceComposerClients.\n    static void openGlobalTransaction();\n\n    //! Close a composer transaction on all active SurfaceComposerClients.\n    static void closeGlobalTransaction(bool synchronous = false);\n\n    //! Flag the currently open transaction as an animation transaction.\n    static void setAnimationTransaction();\n\n    status_t    hide(const sp<IBinder>& id);\n    status_t    show(const sp<IBinder>& id);\n    status_t    setFlags(const sp<IBinder>& id, uint32_t flags, uint32_t mask);\n    status_t    setTransparentRegionHint(const sp<IBinder>& id, const Region& transparent);\n    status_t    setLayer(const sp<IBinder>& id, uint32_t layer);\n    status_t    setAlpha(const sp<IBinder>& id, float alpha=1.0f);\n    status_t    setMatrix(const sp<IBinder>& id, float dsdx, float dtdx, float dsdy, float dtdy);\n    status_t    setPosition(const sp<IBinder>& id, float x, float y);\n    status_t    setSize(const sp<IBinder>& id, uint32_t w, uint32_t h);\n    status_t    setCrop(const sp<IBinder>& id, const Rect& crop);\n    status_t    setFinalCrop(const sp<IBinder>& id, const Rect& crop);\n    status_t    setLayerStack(const sp<IBinder>& id, uint32_t layerStack);\n    status_t    deferTransactionUntil(const sp<IBinder>& id,\n            const sp<IBinder>& handle, uint64_t frameNumber);\n    status_t    setOverrideScalingMode(const sp<IBinder>& id,\n            int32_t overrideScalingMode);\n    status_t    setPositionAppliesWithResize(const sp<IBinder>& id);\n\n    status_t    destroySurface(const sp<IBinder>& id);\n\n    status_t clearLayerFrameStats(const sp<IBinder>& token) const;\n    status_t getLayerFrameStats(const sp<IBinder>& token, FrameStats* outStats) const;\n\n    static status_t clearAnimationFrameStats();\n    static status_t getAnimationFrameStats(FrameStats* outStats);\n\n    static status_t getHdrCapabilities(const sp<IBinder>& display,\n            HdrCapabilities* outCapabilities);\n\n    static void setDisplaySurface(const sp<IBinder>& token,\n            const sp<IGraphicBufferProducer>& bufferProducer);\n    static void setDisplayLayerStack(const sp<IBinder>& token,\n            uint32_t layerStack);\n    static void setDisplaySize(const sp<IBinder>& token, uint32_t width, uint32_t height);\n\n    /* setDisplayProjection() defines the projection of layer stacks\n     * to a given display.\n     *\n     * - orientation defines the display's orientation.\n     * - layerStackRect defines which area of the window manager coordinate\n     * space will be used.\n     * - displayRect defines where on the display will layerStackRect be\n     * mapped to. displayRect is specified post-orientation, that is\n     * it uses the orientation seen by the end-user.\n     */\n    static void setDisplayProjection(const sp<IBinder>& token,\n            uint32_t orientation,\n            const Rect& layerStackRect,\n            const Rect& displayRect);\n\nprivate:\n    virtual void onFirstRef();\n    Composer& getComposer();\n\n    mutable     Mutex                       mLock;\n                status_t                    mStatus;\n                sp<ISurfaceComposerClient>  mClient;\n                Composer&                   mComposer;\n};\n\n// ---------------------------------------------------------------------------\n\nclass ScreenshotClient\n{\npublic:\n    // if cropping isn't required, callers may pass in a default Rect, e.g.:\n    //   capture(display, producer, Rect(), reqWidth, ...);\n    static status_t capture(\n            const sp<IBinder>& display,\n            const sp<IGraphicBufferProducer>& producer,\n            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,\n            uint32_t minLayerZ, uint32_t maxLayerZ,\n            bool useIdentityTransform);\n\nprivate:\n    mutable sp<CpuConsumer> mCpuConsumer;\n    mutable sp<IGraphicBufferProducer> mProducer;\n    CpuConsumer::LockedBuffer mBuffer;\n    bool mHaveBuffer;\n\npublic:\n    ScreenshotClient();\n    ~ScreenshotClient();\n\n    // frees the previous screenshot and captures a new one\n    // if cropping isn't required, callers may pass in a default Rect, e.g.:\n    //   update(display, Rect(), useIdentityTransform);\n    status_t update(const sp<IBinder>& display,\n            Rect sourceCrop, bool useIdentityTransform);\n    status_t update(const sp<IBinder>& display,\n            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,\n            bool useIdentityTransform);\n    status_t update(const sp<IBinder>& display,\n            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,\n            uint32_t minLayerZ, uint32_t maxLayerZ,\n            bool useIdentityTransform);\n    status_t update(const sp<IBinder>& display,\n            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,\n            uint32_t minLayerZ, uint32_t maxLayerZ,\n            bool useIdentityTransform, uint32_t rotation);\n\n    sp<CpuConsumer> getCpuConsumer() const;\n\n    // release memory occupied by the screenshot\n    void release();\n\n    // pixels are valid until this object is freed or\n    // release() or update() is called\n    void const* getPixels() const;\n\n    uint32_t getWidth() const;\n    uint32_t getHeight() const;\n    PixelFormat getFormat() const;\n    uint32_t getStride() const;\n    // size of allocated memory in bytes\n    size_t getSize() const;\n};\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/gui/SurfaceControl.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_SURFACE_CONTROL_H\n#define ANDROID_GUI_SURFACE_CONTROL_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/KeyedVector.h>\n#include <utils/RefBase.h>\n#include <utils/threads.h>\n\n#include <ui/FrameStats.h>\n#include <ui/PixelFormat.h>\n#include <ui/Region.h>\n\n#include <gui/ISurfaceComposerClient.h>\n\nnamespace android {\n\n// ---------------------------------------------------------------------------\n\nclass IGraphicBufferProducer;\nclass Surface;\nclass SurfaceComposerClient;\n\n// ---------------------------------------------------------------------------\n\nclass SurfaceControl : public RefBase\n{\npublic:\n    static bool isValid(const sp<SurfaceControl>& surface) {\n        return (surface != 0) && surface->isValid();\n    }\n\n    bool isValid() {\n        return mHandle!=0 && mClient!=0;\n    }\n\n    static bool isSameSurface(\n            const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);\n\n    // release surface data from java\n    void        clear();\n\n    // disconnect any api that's connected\n    void        disconnect();\n\n    status_t    setLayerStack(uint32_t layerStack);\n    status_t    setLayer(uint32_t layer);\n    status_t    setPosition(float x, float y);\n    status_t    setSize(uint32_t w, uint32_t h);\n    status_t    hide();\n    status_t    show();\n    status_t    setFlags(uint32_t flags, uint32_t mask);\n    status_t    setTransparentRegionHint(const Region& transparent);\n    status_t    setAlpha(float alpha=1.0f);\n    status_t    setMatrix(float dsdx, float dtdx, float dsdy, float dtdy);\n    status_t    setCrop(const Rect& crop);\n    status_t    setFinalCrop(const Rect& crop);\n\n    // If the size changes in this transaction, position updates specified\n    // in this transaction will not complete until a buffer of the new size\n    // arrives.\n    status_t    setPositionAppliesWithResize();\n\n    // Defers applying any changes made in this transaction until the Layer\n    // identified by handle reaches the given frameNumber\n    status_t deferTransactionUntil(sp<IBinder> handle, uint64_t frameNumber);\n\n    // Set an override scaling mode as documented in <system/window.h>\n    // the override scaling mode will take precedence over any client\n    // specified scaling mode. -1 will clear the override scaling mode.\n    status_t setOverrideScalingMode(int32_t overrideScalingMode);\n\n    static status_t writeSurfaceToParcel(\n            const sp<SurfaceControl>& control, Parcel* parcel);\n\n    sp<Surface> getSurface() const;\n    sp<IBinder> getHandle() const;\n\n    status_t clearLayerFrameStats() const;\n    status_t getLayerFrameStats(FrameStats* outStats) const;\n\nprivate:\n    // can't be copied\n    SurfaceControl& operator = (SurfaceControl& rhs);\n    SurfaceControl(const SurfaceControl& rhs);\n\n    friend class SurfaceComposerClient;\n    friend class Surface;\n\n    SurfaceControl(\n            const sp<SurfaceComposerClient>& client,\n            const sp<IBinder>& handle,\n            const sp<IGraphicBufferProducer>& gbp);\n\n    ~SurfaceControl();\n\n    status_t validate() const;\n    void destroy();\n\n    sp<SurfaceComposerClient>   mClient;\n    sp<IBinder>                 mHandle;\n    sp<IGraphicBufferProducer>  mGraphicBufferProducer;\n    mutable Mutex               mLock;\n    mutable sp<Surface>         mSurfaceData;\n};\n\n}; // namespace android\n\n#endif // ANDROID_GUI_SURFACE_CONTROL_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/input/IInputFlinger.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBINPUT_IINPUT_FLINGER_H\n#define _LIBINPUT_IINPUT_FLINGER_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <binder/IInterface.h>\n\nnamespace android {\n\n/*\n * This class defines the Binder IPC interface for accessing various\n * InputFlinger features.\n */\nclass IInputFlinger : public IInterface {\npublic:\n    DECLARE_META_INTERFACE(InputFlinger);\n};\n\n\n/**\n * Binder implementation.\n */\nclass BnInputFlinger : public BnInterface<IInputFlinger> {\npublic:\n    enum {\n        DO_SOMETHING_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,\n    };\n\n    virtual status_t onTransact(uint32_t code, const Parcel& data,\n            Parcel* reply, uint32_t flags = 0);\n};\n\n} // namespace android\n\n#endif // _LIBINPUT_IINPUT_FLINGER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/input/Input.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBINPUT_INPUT_H\n#define _LIBINPUT_INPUT_H\n\n/**\n * Native input event structures.\n */\n\n#include <android/input.h>\n#include <utils/BitSet.h>\n#include <utils/KeyedVector.h>\n#include <utils/RefBase.h>\n#include <utils/String8.h>\n#include <utils/Timers.h>\n#include <utils/Vector.h>\n#include <stdint.h>\n\n/*\n * Additional private constants not defined in ndk/ui/input.h.\n */\nenum {\n    /* Signifies that the key is being predispatched */\n    AKEY_EVENT_FLAG_PREDISPATCH = 0x20000000,\n\n    /* Private control to determine when an app is tracking a key sequence. */\n    AKEY_EVENT_FLAG_START_TRACKING = 0x40000000,\n\n    /* Key event is inconsistent with previously sent key events. */\n    AKEY_EVENT_FLAG_TAINTED = 0x80000000,\n};\n\nenum {\n\n    /**\n     * This flag indicates that the window that received this motion event is partly\n     * or wholly obscured by another visible window above it.  This flag is set to true\n     * even if the event did not directly pass through the obscured area.\n     * A security sensitive application can check this flag to identify situations in which\n     * a malicious application may have covered up part of its content for the purpose\n     * of misleading the user or hijacking touches.  An appropriate response might be\n     * to drop the suspect touches or to take additional precautions to confirm the user's\n     * actual intent.\n     */\n    AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED = 0x2,\n\n    /* Motion event is inconsistent with previously sent motion events. */\n    AMOTION_EVENT_FLAG_TAINTED = 0x80000000,\n};\n\nenum {\n    /* Used when a motion event is not associated with any display.\n     * Typically used for non-pointer events. */\n    ADISPLAY_ID_NONE = -1,\n\n    /* The default display id. */\n    ADISPLAY_ID_DEFAULT = 0,\n};\n\nenum {\n    /*\n     * Indicates that an input device has switches.\n     * This input source flag is hidden from the API because switches are only used by the system\n     * and applications have no way to interact with them.\n     */\n    AINPUT_SOURCE_SWITCH = 0x80000000,\n};\n\nenum {\n    /**\n     * Constants for LEDs. Hidden from the API since we don't actually expose a way to interact\n     * with LEDs to developers\n     *\n     * NOTE: If you add LEDs here, you must also add them to InputEventLabels.h\n     */\n\n    ALED_NUM_LOCK = 0x00,\n    ALED_CAPS_LOCK = 0x01,\n    ALED_SCROLL_LOCK = 0x02,\n    ALED_COMPOSE = 0x03,\n    ALED_KANA = 0x04,\n    ALED_SLEEP = 0x05,\n    ALED_SUSPEND = 0x06,\n    ALED_MUTE = 0x07,\n    ALED_MISC = 0x08,\n    ALED_MAIL = 0x09,\n    ALED_CHARGING = 0x0a,\n    ALED_CONTROLLER_1 = 0x10,\n    ALED_CONTROLLER_2 = 0x11,\n    ALED_CONTROLLER_3 = 0x12,\n    ALED_CONTROLLER_4 = 0x13,\n};\n\n/* Maximum number of controller LEDs we support */\n#define MAX_CONTROLLER_LEDS 4\n\n/*\n * SystemUiVisibility constants from View.\n */\nenum {\n    ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE = 0,\n    ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN = 0x00000001,\n};\n\n/*\n * Maximum number of pointers supported per motion event.\n * Smallest number of pointers is 1.\n * (We want at least 10 but some touch controllers obstensibly configured for 10 pointers\n * will occasionally emit 11.  There is not much harm making this constant bigger.)\n */\n#define MAX_POINTERS 16\n\n/*\n * Maximum number of samples supported per motion event.\n */\n#define MAX_SAMPLES UINT16_MAX\n\n/*\n * Maximum pointer id value supported in a motion event.\n * Smallest pointer id is 0.\n * (This is limited by our use of BitSet32 to track pointer assignments.)\n */\n#define MAX_POINTER_ID 31\n\n/*\n * Declare a concrete type for the NDK's input event forward declaration.\n */\nstruct AInputEvent {\n    virtual ~AInputEvent() { }\n};\n\n/*\n * Declare a concrete type for the NDK's input device forward declaration.\n */\nstruct AInputDevice {\n    virtual ~AInputDevice() { }\n};\n\n\nnamespace android {\n\n#ifdef __ANDROID__\nclass Parcel;\n#endif\n\n/*\n * Flags that flow alongside events in the input dispatch system to help with certain\n * policy decisions such as waking from device sleep.\n *\n * These flags are also defined in frameworks/base/core/java/android/view/WindowManagerPolicy.java.\n */\nenum {\n    /* These flags originate in RawEvents and are generally set in the key map.\n     * NOTE: If you want a flag to be able to set in a keylayout file, then you must add it to\n     * InputEventLabels.h as well. */\n\n    // Indicates that the event should wake the device.\n    POLICY_FLAG_WAKE = 0x00000001,\n\n    // Indicates that the key is virtual, such as a capacitive button, and should\n    // generate haptic feedback.  Virtual keys may be suppressed for some time\n    // after a recent touch to prevent accidental activation of virtual keys adjacent\n    // to the touch screen during an edge swipe.\n    POLICY_FLAG_VIRTUAL = 0x00000002,\n\n    // Indicates that the key is the special function modifier.\n    POLICY_FLAG_FUNCTION = 0x00000004,\n\n    // Indicates that the key represents a special gesture that has been detected by\n    // the touch firmware or driver.  Causes touch events from the same device to be canceled.\n    POLICY_FLAG_GESTURE = 0x00000008,\n\n    POLICY_FLAG_RAW_MASK = 0x0000ffff,\n\n    /* These flags are set by the input dispatcher. */\n\n    // Indicates that the input event was injected.\n    POLICY_FLAG_INJECTED = 0x01000000,\n\n    // Indicates that the input event is from a trusted source such as a directly attached\n    // input device or an application with system-wide event injection permission.\n    POLICY_FLAG_TRUSTED = 0x02000000,\n\n    // Indicates that the input event has passed through an input filter.\n    POLICY_FLAG_FILTERED = 0x04000000,\n\n    // Disables automatic key repeating behavior.\n    POLICY_FLAG_DISABLE_KEY_REPEAT = 0x08000000,\n\n    /* These flags are set by the input reader policy as it intercepts each event. */\n\n    // Indicates that the device was in an interactive state when the\n    // event was intercepted.\n    POLICY_FLAG_INTERACTIVE = 0x20000000,\n\n    // Indicates that the event should be dispatched to applications.\n    // The input event should still be sent to the InputDispatcher so that it can see all\n    // input events received include those that it will not deliver.\n    POLICY_FLAG_PASS_TO_USER = 0x40000000,\n};\n\n/*\n * Pointer coordinate data.\n */\nstruct PointerCoords {\n    enum { MAX_AXES = 30 }; // 30 so that sizeof(PointerCoords) == 128\n\n    // Bitfield of axes that are present in this structure.\n    uint64_t bits __attribute__((aligned(8)));\n\n    // Values of axes that are stored in this structure packed in order by axis id\n    // for each axis that is present in the structure according to 'bits'.\n    float values[MAX_AXES];\n\n    inline void clear() {\n        BitSet64::clear(bits);\n    }\n\n    bool isEmpty() const {\n        return BitSet64::isEmpty(bits);\n    }\n\n    float getAxisValue(int32_t axis) const;\n    status_t setAxisValue(int32_t axis, float value);\n\n    void scale(float scale);\n    void applyOffset(float xOffset, float yOffset);\n\n    inline float getX() const {\n        return getAxisValue(AMOTION_EVENT_AXIS_X);\n    }\n\n    inline float getY() const {\n        return getAxisValue(AMOTION_EVENT_AXIS_Y);\n    }\n\n#ifdef __ANDROID__\n    status_t readFromParcel(Parcel* parcel);\n    status_t writeToParcel(Parcel* parcel) const;\n#endif\n\n    bool operator==(const PointerCoords& other) const;\n    inline bool operator!=(const PointerCoords& other) const {\n        return !(*this == other);\n    }\n\n    void copyFrom(const PointerCoords& other);\n\nprivate:\n    void tooManyAxes(int axis);\n};\n\n/*\n * Pointer property data.\n */\nstruct PointerProperties {\n    // The id of the pointer.\n    int32_t id;\n\n    // The pointer tool type.\n    int32_t toolType;\n\n    inline void clear() {\n        id = -1;\n        toolType = 0;\n    }\n\n    bool operator==(const PointerProperties& other) const;\n    inline bool operator!=(const PointerProperties& other) const {\n        return !(*this == other);\n    }\n\n    void copyFrom(const PointerProperties& other);\n};\n\n/*\n * Input events.\n */\nclass InputEvent : public AInputEvent {\npublic:\n    virtual ~InputEvent() { }\n\n    virtual int32_t getType() const = 0;\n\n    inline int32_t getDeviceId() const { return mDeviceId; }\n\n    inline int32_t getSource() const { return mSource; }\n\n    inline void setSource(int32_t source) { mSource = source; }\n\nprotected:\n    void initialize(int32_t deviceId, int32_t source);\n    void initialize(const InputEvent& from);\n\n    int32_t mDeviceId;\n    int32_t mSource;\n};\n\n/*\n * Key events.\n */\nclass KeyEvent : public InputEvent {\npublic:\n    virtual ~KeyEvent() { }\n\n    virtual int32_t getType() const { return AINPUT_EVENT_TYPE_KEY; }\n\n    inline int32_t getAction() const { return mAction; }\n\n    inline int32_t getFlags() const { return mFlags; }\n\n    inline void setFlags(int32_t flags) { mFlags = flags; }\n\n    inline int32_t getKeyCode() const { return mKeyCode; }\n\n    inline int32_t getScanCode() const { return mScanCode; }\n\n    inline int32_t getMetaState() const { return mMetaState; }\n\n    inline int32_t getRepeatCount() const { return mRepeatCount; }\n\n    inline nsecs_t getDownTime() const { return mDownTime; }\n\n    inline nsecs_t getEventTime() const { return mEventTime; }\n\n    static const char* getLabel(int32_t keyCode);\n    static int32_t getKeyCodeFromLabel(const char* label);\n    \n    void initialize(\n            int32_t deviceId,\n            int32_t source,\n            int32_t action,\n            int32_t flags,\n            int32_t keyCode,\n            int32_t scanCode,\n            int32_t metaState,\n            int32_t repeatCount,\n            nsecs_t downTime,\n            nsecs_t eventTime);\n    void initialize(const KeyEvent& from);\n\nprotected:\n    int32_t mAction;\n    int32_t mFlags;\n    int32_t mKeyCode;\n    int32_t mScanCode;\n    int32_t mMetaState;\n    int32_t mRepeatCount;\n    nsecs_t mDownTime;\n    nsecs_t mEventTime;\n};\n\n/*\n * Motion events.\n */\nclass MotionEvent : public InputEvent {\npublic:\n    virtual ~MotionEvent() { }\n\n    virtual int32_t getType() const { return AINPUT_EVENT_TYPE_MOTION; }\n\n    inline int32_t getAction() const { return mAction; }\n\n    inline int32_t getActionMasked() const { return mAction & AMOTION_EVENT_ACTION_MASK; }\n\n    inline int32_t getActionIndex() const {\n        return (mAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)\n                >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;\n    }\n\n    inline void setAction(int32_t action) { mAction = action; }\n\n    inline int32_t getFlags() const { return mFlags; }\n\n    inline void setFlags(int32_t flags) { mFlags = flags; }\n\n    inline int32_t getEdgeFlags() const { return mEdgeFlags; }\n\n    inline void setEdgeFlags(int32_t edgeFlags) { mEdgeFlags = edgeFlags; }\n\n    inline int32_t getMetaState() const { return mMetaState; }\n\n    inline void setMetaState(int32_t metaState) { mMetaState = metaState; }\n\n    inline int32_t getButtonState() const { return mButtonState; }\n\n    inline int32_t setButtonState(int32_t buttonState) { mButtonState = buttonState; }\n\n    inline int32_t getActionButton() const { return mActionButton; }\n\n    inline void setActionButton(int32_t button) { mActionButton = button; }\n\n    inline float getXOffset() const { return mXOffset; }\n\n    inline float getYOffset() const { return mYOffset; }\n\n    inline float getXPrecision() const { return mXPrecision; }\n\n    inline float getYPrecision() const { return mYPrecision; }\n\n    inline nsecs_t getDownTime() const { return mDownTime; }\n\n    inline void setDownTime(nsecs_t downTime) { mDownTime = downTime; }\n\n    inline size_t getPointerCount() const { return mPointerProperties.size(); }\n\n    inline const PointerProperties* getPointerProperties(size_t pointerIndex) const {\n        return &mPointerProperties[pointerIndex];\n    }\n\n    inline int32_t getPointerId(size_t pointerIndex) const {\n        return mPointerProperties[pointerIndex].id;\n    }\n\n    inline int32_t getToolType(size_t pointerIndex) const {\n        return mPointerProperties[pointerIndex].toolType;\n    }\n\n    inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; }\n\n    const PointerCoords* getRawPointerCoords(size_t pointerIndex) const;\n\n    float getRawAxisValue(int32_t axis, size_t pointerIndex) const;\n\n    inline float getRawX(size_t pointerIndex) const {\n        return getRawAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);\n    }\n\n    inline float getRawY(size_t pointerIndex) const {\n        return getRawAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);\n    }\n\n    float getAxisValue(int32_t axis, size_t pointerIndex) const;\n\n    inline float getX(size_t pointerIndex) const {\n        return getAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);\n    }\n\n    inline float getY(size_t pointerIndex) const {\n        return getAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);\n    }\n\n    inline float getPressure(size_t pointerIndex) const {\n        return getAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pointerIndex);\n    }\n\n    inline float getSize(size_t pointerIndex) const {\n        return getAxisValue(AMOTION_EVENT_AXIS_SIZE, pointerIndex);\n    }\n\n    inline float getTouchMajor(size_t pointerIndex) const {\n        return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex);\n    }\n\n    inline float getTouchMinor(size_t pointerIndex) const {\n        return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex);\n    }\n\n    inline float getToolMajor(size_t pointerIndex) const {\n        return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex);\n    }\n\n    inline float getToolMinor(size_t pointerIndex) const {\n        return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex);\n    }\n\n    inline float getOrientation(size_t pointerIndex) const {\n        return getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex);\n    }\n\n    inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; }\n\n    inline nsecs_t getHistoricalEventTime(size_t historicalIndex) const {\n        return mSampleEventTimes[historicalIndex];\n    }\n\n    const PointerCoords* getHistoricalRawPointerCoords(\n            size_t pointerIndex, size_t historicalIndex) const;\n\n    float getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,\n            size_t historicalIndex) const;\n\n    inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const {\n        return getHistoricalRawAxisValue(\n                AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);\n    }\n\n    inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const {\n        return getHistoricalRawAxisValue(\n                AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);\n    }\n\n    float getHistoricalAxisValue(int32_t axis, size_t pointerIndex, size_t historicalIndex) const;\n\n    inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const {\n        return getHistoricalAxisValue(\n                AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);\n    }\n\n    inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const {\n        return getHistoricalAxisValue(\n                AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);\n    }\n\n    inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const {\n        return getHistoricalAxisValue(\n                AMOTION_EVENT_AXIS_PRESSURE, pointerIndex, historicalIndex);\n    }\n\n    inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const {\n        return getHistoricalAxisValue(\n                AMOTION_EVENT_AXIS_SIZE, pointerIndex, historicalIndex);\n    }\n\n    inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const {\n        return getHistoricalAxisValue(\n                AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex, historicalIndex);\n    }\n\n    inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const {\n        return getHistoricalAxisValue(\n                AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex, historicalIndex);\n    }\n\n    inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const {\n        return getHistoricalAxisValue(\n                AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex, historicalIndex);\n    }\n\n    inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const {\n        return getHistoricalAxisValue(\n                AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex, historicalIndex);\n    }\n\n    inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const {\n        return getHistoricalAxisValue(\n                AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historicalIndex);\n    }\n\n    ssize_t findPointerIndex(int32_t pointerId) const;\n\n    void initialize(\n            int32_t deviceId,\n            int32_t source,\n            int32_t action,\n            int32_t actionButton,\n            int32_t flags,\n            int32_t edgeFlags,\n            int32_t metaState,\n            int32_t buttonState,\n            float xOffset,\n            float yOffset,\n            float xPrecision,\n            float yPrecision,\n            nsecs_t downTime,\n            nsecs_t eventTime,\n            size_t pointerCount,\n            const PointerProperties* pointerProperties,\n            const PointerCoords* pointerCoords);\n\n    void copyFrom(const MotionEvent* other, bool keepHistory);\n\n    void addSample(\n            nsecs_t eventTime,\n            const PointerCoords* pointerCoords);\n\n    void offsetLocation(float xOffset, float yOffset);\n\n    void scale(float scaleFactor);\n\n    // Apply 3x3 perspective matrix transformation.\n    // Matrix is in row-major form and compatible with SkMatrix.\n    void transform(const float matrix[9]);\n\n#ifdef __ANDROID__\n    status_t readFromParcel(Parcel* parcel);\n    status_t writeToParcel(Parcel* parcel) const;\n#endif\n\n    static bool isTouchEvent(int32_t source, int32_t action);\n    inline bool isTouchEvent() const {\n        return isTouchEvent(mSource, mAction);\n    }\n\n    // Low-level accessors.\n    inline const PointerProperties* getPointerProperties() const {\n        return mPointerProperties.array();\n    }\n    inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); }\n    inline const PointerCoords* getSamplePointerCoords() const {\n            return mSamplePointerCoords.array();\n    }\n\n    static const char* getLabel(int32_t axis);\n    static int32_t getAxisFromLabel(const char* label);\n\nprotected:\n    int32_t mAction;\n    int32_t mActionButton;\n    int32_t mFlags;\n    int32_t mEdgeFlags;\n    int32_t mMetaState;\n    int32_t mButtonState;\n    float mXOffset;\n    float mYOffset;\n    float mXPrecision;\n    float mYPrecision;\n    nsecs_t mDownTime;\n    Vector<PointerProperties> mPointerProperties;\n    Vector<nsecs_t> mSampleEventTimes;\n    Vector<PointerCoords> mSamplePointerCoords;\n};\n\n/*\n * Input event factory.\n */\nclass InputEventFactoryInterface {\nprotected:\n    virtual ~InputEventFactoryInterface() { }\n\npublic:\n    InputEventFactoryInterface() { }\n\n    virtual KeyEvent* createKeyEvent() = 0;\n    virtual MotionEvent* createMotionEvent() = 0;\n};\n\n/*\n * A simple input event factory implementation that uses a single preallocated instance\n * of each type of input event that are reused for each request.\n */\nclass PreallocatedInputEventFactory : public InputEventFactoryInterface {\npublic:\n    PreallocatedInputEventFactory() { }\n    virtual ~PreallocatedInputEventFactory() { }\n\n    virtual KeyEvent* createKeyEvent() { return & mKeyEvent; }\n    virtual MotionEvent* createMotionEvent() { return & mMotionEvent; }\n\nprivate:\n    KeyEvent mKeyEvent;\n    MotionEvent mMotionEvent;\n};\n\n/*\n * An input event factory implementation that maintains a pool of input events.\n */\nclass PooledInputEventFactory : public InputEventFactoryInterface {\npublic:\n    PooledInputEventFactory(size_t maxPoolSize = 20);\n    virtual ~PooledInputEventFactory();\n\n    virtual KeyEvent* createKeyEvent();\n    virtual MotionEvent* createMotionEvent();\n\n    void recycle(InputEvent* event);\n\nprivate:\n    const size_t mMaxPoolSize;\n\n    Vector<KeyEvent*> mKeyEventPool;\n    Vector<MotionEvent*> mMotionEventPool;\n};\n\n} // namespace android\n\n#endif // _LIBINPUT_INPUT_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/input/InputDevice.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBINPUT_INPUT_DEVICE_H\n#define _LIBINPUT_INPUT_DEVICE_H\n\n#include <input/Input.h>\n#include <input/KeyCharacterMap.h>\n\nnamespace android {\n\n/*\n * Identifies a device.\n */\nstruct InputDeviceIdentifier {\n    inline InputDeviceIdentifier() :\n            bus(0), vendor(0), product(0), version(0) {\n    }\n\n    // Information provided by the kernel.\n    String8 name;\n    String8 location;\n    String8 uniqueId;\n    uint16_t bus;\n    uint16_t vendor;\n    uint16_t product;\n    uint16_t version;\n\n    // A composite input device descriptor string that uniquely identifies the device\n    // even across reboots or reconnections.  The value of this field is used by\n    // upper layers of the input system to associate settings with individual devices.\n    // It is hashed from whatever kernel provided information is available.\n    // Ideally, the way this value is computed should not change between Android releases\n    // because that would invalidate persistent settings that rely on it.\n    String8 descriptor;\n\n    // A value added to uniquely identify a device in the absence of a unique id. This\n    // is intended to be a minimum way to distinguish from other active devices and may\n    // reuse values that are not associated with an input anymore.\n    uint16_t nonce;\n};\n\n/*\n * Describes the characteristics and capabilities of an input device.\n */\nclass InputDeviceInfo {\npublic:\n    InputDeviceInfo();\n    InputDeviceInfo(const InputDeviceInfo& other);\n    ~InputDeviceInfo();\n\n    struct MotionRange {\n        int32_t axis;\n        uint32_t source;\n        float min;\n        float max;\n        float flat;\n        float fuzz;\n        float resolution;\n    };\n\n    void initialize(int32_t id, int32_t generation, int32_t controllerNumber,\n            const InputDeviceIdentifier& identifier, const String8& alias, bool isExternal,\n            bool hasMic);\n\n    inline int32_t getId() const { return mId; }\n    inline int32_t getControllerNumber() const { return mControllerNumber; }\n    inline int32_t getGeneration() const { return mGeneration; }\n    inline const InputDeviceIdentifier& getIdentifier() const { return mIdentifier; }\n    inline const String8& getAlias() const { return mAlias; }\n    inline const String8& getDisplayName() const {\n        return mAlias.isEmpty() ? mIdentifier.name : mAlias;\n    }\n    inline bool isExternal() const { return mIsExternal; }\n    inline bool hasMic() const { return mHasMic; }\n    inline uint32_t getSources() const { return mSources; }\n\n    const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;\n\n    void addSource(uint32_t source);\n    void addMotionRange(int32_t axis, uint32_t source,\n            float min, float max, float flat, float fuzz, float resolution);\n    void addMotionRange(const MotionRange& range);\n\n    inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }\n    inline int32_t getKeyboardType() const { return mKeyboardType; }\n\n    inline void setKeyCharacterMap(const sp<KeyCharacterMap>& value) {\n        mKeyCharacterMap = value;\n    }\n\n    inline sp<KeyCharacterMap> getKeyCharacterMap() const {\n        return mKeyCharacterMap;\n    }\n\n    inline void setVibrator(bool hasVibrator) { mHasVibrator = hasVibrator; }\n    inline bool hasVibrator() const { return mHasVibrator; }\n\n    inline void setButtonUnderPad(bool hasButton) { mHasButtonUnderPad = hasButton; }\n    inline bool hasButtonUnderPad() const { return mHasButtonUnderPad; }\n\n    inline const Vector<MotionRange>& getMotionRanges() const {\n        return mMotionRanges;\n    }\n\nprivate:\n    int32_t mId;\n    int32_t mGeneration;\n    int32_t mControllerNumber;\n    InputDeviceIdentifier mIdentifier;\n    String8 mAlias;\n    bool mIsExternal;\n    bool mHasMic;\n    uint32_t mSources;\n    int32_t mKeyboardType;\n    sp<KeyCharacterMap> mKeyCharacterMap;\n    bool mHasVibrator;\n    bool mHasButtonUnderPad;\n\n    Vector<MotionRange> mMotionRanges;\n};\n\n/* Types of input device configuration files. */\nenum InputDeviceConfigurationFileType {\n    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0,     /* .idc file */\n    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1,        /* .kl file */\n    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file */\n};\n\n/*\n * Gets the path of an input device configuration file, if one is available.\n * Considers both system provided and user installed configuration files.\n *\n * The device identifier is used to construct several default configuration file\n * names to try based on the device name, vendor, product, and version.\n *\n * Returns an empty string if not found.\n */\nextern String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(\n        const InputDeviceIdentifier& deviceIdentifier,\n        InputDeviceConfigurationFileType type);\n\n/*\n * Gets the path of an input device configuration file, if one is available.\n * Considers both system provided and user installed configuration files.\n *\n * The name is case-sensitive and is used to construct the filename to resolve.\n * All characters except 'a'-'z', 'A'-'Z', '0'-'9', '-', and '_' are replaced by underscores.\n *\n * Returns an empty string if not found.\n */\nextern String8 getInputDeviceConfigurationFilePathByName(\n        const String8& name, InputDeviceConfigurationFileType type);\n\n} // namespace android\n\n#endif // _LIBINPUT_INPUT_DEVICE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/input/InputEventLabels.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBINPUT_INPUT_EVENT_LABELS_H\n#define _LIBINPUT_INPUT_EVENT_LABELS_H\n\n#include <input/Input.h>\n#include <android/keycodes.h>\n\n#define DEFINE_KEYCODE(key) { #key, AKEYCODE_##key }\n#define DEFINE_AXIS(axis) { #axis, AMOTION_EVENT_AXIS_##axis }\n#define DEFINE_LED(led) { #led, ALED_##led }\n#define DEFINE_FLAG(flag) { #flag, POLICY_FLAG_##flag }\n\nnamespace android {\n\ntemplate<typename T, size_t N>\nsize_t size(T (&)[N]) { return N; }\n\nstruct InputEventLabel {\n    const char *literal;\n    int value;\n};\n\n\nstatic const InputEventLabel KEYCODES[] = {\n    // NOTE: If you add a new keycode here you must also add it to several other files.\n    //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.\n    DEFINE_KEYCODE(UNKNOWN),\n    DEFINE_KEYCODE(SOFT_LEFT),\n    DEFINE_KEYCODE(SOFT_RIGHT),\n    DEFINE_KEYCODE(HOME),\n    DEFINE_KEYCODE(BACK),\n    DEFINE_KEYCODE(CALL),\n    DEFINE_KEYCODE(ENDCALL),\n    DEFINE_KEYCODE(0),\n    DEFINE_KEYCODE(1),\n    DEFINE_KEYCODE(2),\n    DEFINE_KEYCODE(3),\n    DEFINE_KEYCODE(4),\n    DEFINE_KEYCODE(5),\n    DEFINE_KEYCODE(6),\n    DEFINE_KEYCODE(7),\n    DEFINE_KEYCODE(8),\n    DEFINE_KEYCODE(9),\n    DEFINE_KEYCODE(STAR),\n    DEFINE_KEYCODE(POUND),\n    DEFINE_KEYCODE(DPAD_UP),\n    DEFINE_KEYCODE(DPAD_DOWN),\n    DEFINE_KEYCODE(DPAD_LEFT),\n    DEFINE_KEYCODE(DPAD_RIGHT),\n    DEFINE_KEYCODE(DPAD_CENTER),\n    DEFINE_KEYCODE(VOLUME_UP),\n    DEFINE_KEYCODE(VOLUME_DOWN),\n    DEFINE_KEYCODE(POWER),\n    DEFINE_KEYCODE(CAMERA),\n    DEFINE_KEYCODE(CLEAR),\n    DEFINE_KEYCODE(A),\n    DEFINE_KEYCODE(B),\n    DEFINE_KEYCODE(C),\n    DEFINE_KEYCODE(D),\n    DEFINE_KEYCODE(E),\n    DEFINE_KEYCODE(F),\n    DEFINE_KEYCODE(G),\n    DEFINE_KEYCODE(H),\n    DEFINE_KEYCODE(I),\n    DEFINE_KEYCODE(J),\n    DEFINE_KEYCODE(K),\n    DEFINE_KEYCODE(L),\n    DEFINE_KEYCODE(M),\n    DEFINE_KEYCODE(N),\n    DEFINE_KEYCODE(O),\n    DEFINE_KEYCODE(P),\n    DEFINE_KEYCODE(Q),\n    DEFINE_KEYCODE(R),\n    DEFINE_KEYCODE(S),\n    DEFINE_KEYCODE(T),\n    DEFINE_KEYCODE(U),\n    DEFINE_KEYCODE(V),\n    DEFINE_KEYCODE(W),\n    DEFINE_KEYCODE(X),\n    DEFINE_KEYCODE(Y),\n    DEFINE_KEYCODE(Z),\n    DEFINE_KEYCODE(COMMA),\n    DEFINE_KEYCODE(PERIOD),\n    DEFINE_KEYCODE(ALT_LEFT),\n    DEFINE_KEYCODE(ALT_RIGHT),\n    DEFINE_KEYCODE(SHIFT_LEFT),\n    DEFINE_KEYCODE(SHIFT_RIGHT),\n    DEFINE_KEYCODE(TAB),\n    DEFINE_KEYCODE(SPACE),\n    DEFINE_KEYCODE(SYM),\n    DEFINE_KEYCODE(EXPLORER),\n    DEFINE_KEYCODE(ENVELOPE),\n    DEFINE_KEYCODE(ENTER),\n    DEFINE_KEYCODE(DEL),\n    DEFINE_KEYCODE(GRAVE),\n    DEFINE_KEYCODE(MINUS),\n    DEFINE_KEYCODE(EQUALS),\n    DEFINE_KEYCODE(LEFT_BRACKET),\n    DEFINE_KEYCODE(RIGHT_BRACKET),\n    DEFINE_KEYCODE(BACKSLASH),\n    DEFINE_KEYCODE(SEMICOLON),\n    DEFINE_KEYCODE(APOSTROPHE),\n    DEFINE_KEYCODE(SLASH),\n    DEFINE_KEYCODE(AT),\n    DEFINE_KEYCODE(NUM),\n    DEFINE_KEYCODE(HEADSETHOOK),\n    DEFINE_KEYCODE(FOCUS),   // *Camera* focus\n    DEFINE_KEYCODE(PLUS),\n    DEFINE_KEYCODE(MENU),\n    DEFINE_KEYCODE(NOTIFICATION),\n    DEFINE_KEYCODE(SEARCH),\n    DEFINE_KEYCODE(MEDIA_PLAY_PAUSE),\n    DEFINE_KEYCODE(MEDIA_STOP),\n    DEFINE_KEYCODE(MEDIA_NEXT),\n    DEFINE_KEYCODE(MEDIA_PREVIOUS),\n    DEFINE_KEYCODE(MEDIA_REWIND),\n    DEFINE_KEYCODE(MEDIA_FAST_FORWARD),\n    DEFINE_KEYCODE(MUTE),\n    DEFINE_KEYCODE(PAGE_UP),\n    DEFINE_KEYCODE(PAGE_DOWN),\n    DEFINE_KEYCODE(PICTSYMBOLS),\n    DEFINE_KEYCODE(SWITCH_CHARSET),\n    DEFINE_KEYCODE(BUTTON_A),\n    DEFINE_KEYCODE(BUTTON_B),\n    DEFINE_KEYCODE(BUTTON_C),\n    DEFINE_KEYCODE(BUTTON_X),\n    DEFINE_KEYCODE(BUTTON_Y),\n    DEFINE_KEYCODE(BUTTON_Z),\n    DEFINE_KEYCODE(BUTTON_L1),\n    DEFINE_KEYCODE(BUTTON_R1),\n    DEFINE_KEYCODE(BUTTON_L2),\n    DEFINE_KEYCODE(BUTTON_R2),\n    DEFINE_KEYCODE(BUTTON_THUMBL),\n    DEFINE_KEYCODE(BUTTON_THUMBR),\n    DEFINE_KEYCODE(BUTTON_START),\n    DEFINE_KEYCODE(BUTTON_SELECT),\n    DEFINE_KEYCODE(BUTTON_MODE),\n    DEFINE_KEYCODE(ESCAPE),\n    DEFINE_KEYCODE(FORWARD_DEL),\n    DEFINE_KEYCODE(CTRL_LEFT),\n    DEFINE_KEYCODE(CTRL_RIGHT),\n    DEFINE_KEYCODE(CAPS_LOCK),\n    DEFINE_KEYCODE(SCROLL_LOCK),\n    DEFINE_KEYCODE(META_LEFT),\n    DEFINE_KEYCODE(META_RIGHT),\n    DEFINE_KEYCODE(FUNCTION),\n    DEFINE_KEYCODE(SYSRQ),\n    DEFINE_KEYCODE(BREAK),\n    DEFINE_KEYCODE(MOVE_HOME),\n    DEFINE_KEYCODE(MOVE_END),\n    DEFINE_KEYCODE(INSERT),\n    DEFINE_KEYCODE(FORWARD),\n    DEFINE_KEYCODE(MEDIA_PLAY),\n    DEFINE_KEYCODE(MEDIA_PAUSE),\n    DEFINE_KEYCODE(MEDIA_CLOSE),\n    DEFINE_KEYCODE(MEDIA_EJECT),\n    DEFINE_KEYCODE(MEDIA_RECORD),\n    DEFINE_KEYCODE(F1),\n    DEFINE_KEYCODE(F2),\n    DEFINE_KEYCODE(F3),\n    DEFINE_KEYCODE(F4),\n    DEFINE_KEYCODE(F5),\n    DEFINE_KEYCODE(F6),\n    DEFINE_KEYCODE(F7),\n    DEFINE_KEYCODE(F8),\n    DEFINE_KEYCODE(F9),\n    DEFINE_KEYCODE(F10),\n    DEFINE_KEYCODE(F11),\n    DEFINE_KEYCODE(F12),\n    DEFINE_KEYCODE(NUM_LOCK),\n    DEFINE_KEYCODE(NUMPAD_0),\n    DEFINE_KEYCODE(NUMPAD_1),\n    DEFINE_KEYCODE(NUMPAD_2),\n    DEFINE_KEYCODE(NUMPAD_3),\n    DEFINE_KEYCODE(NUMPAD_4),\n    DEFINE_KEYCODE(NUMPAD_5),\n    DEFINE_KEYCODE(NUMPAD_6),\n    DEFINE_KEYCODE(NUMPAD_7),\n    DEFINE_KEYCODE(NUMPAD_8),\n    DEFINE_KEYCODE(NUMPAD_9),\n    DEFINE_KEYCODE(NUMPAD_DIVIDE),\n    DEFINE_KEYCODE(NUMPAD_MULTIPLY),\n    DEFINE_KEYCODE(NUMPAD_SUBTRACT),\n    DEFINE_KEYCODE(NUMPAD_ADD),\n    DEFINE_KEYCODE(NUMPAD_DOT),\n    DEFINE_KEYCODE(NUMPAD_COMMA),\n    DEFINE_KEYCODE(NUMPAD_ENTER),\n    DEFINE_KEYCODE(NUMPAD_EQUALS),\n    DEFINE_KEYCODE(NUMPAD_LEFT_PAREN),\n    DEFINE_KEYCODE(NUMPAD_RIGHT_PAREN),\n    DEFINE_KEYCODE(VOLUME_MUTE),\n    DEFINE_KEYCODE(INFO),\n    DEFINE_KEYCODE(CHANNEL_UP),\n    DEFINE_KEYCODE(CHANNEL_DOWN),\n    DEFINE_KEYCODE(ZOOM_IN),\n    DEFINE_KEYCODE(ZOOM_OUT),\n    DEFINE_KEYCODE(TV),\n    DEFINE_KEYCODE(WINDOW),\n    DEFINE_KEYCODE(GUIDE),\n    DEFINE_KEYCODE(DVR),\n    DEFINE_KEYCODE(BOOKMARK),\n    DEFINE_KEYCODE(CAPTIONS),\n    DEFINE_KEYCODE(SETTINGS),\n    DEFINE_KEYCODE(TV_POWER),\n    DEFINE_KEYCODE(TV_INPUT),\n    DEFINE_KEYCODE(STB_POWER),\n    DEFINE_KEYCODE(STB_INPUT),\n    DEFINE_KEYCODE(AVR_POWER),\n    DEFINE_KEYCODE(AVR_INPUT),\n    DEFINE_KEYCODE(PROG_RED),\n    DEFINE_KEYCODE(PROG_GREEN),\n    DEFINE_KEYCODE(PROG_YELLOW),\n    DEFINE_KEYCODE(PROG_BLUE),\n    DEFINE_KEYCODE(APP_SWITCH),\n    DEFINE_KEYCODE(BUTTON_1),\n    DEFINE_KEYCODE(BUTTON_2),\n    DEFINE_KEYCODE(BUTTON_3),\n    DEFINE_KEYCODE(BUTTON_4),\n    DEFINE_KEYCODE(BUTTON_5),\n    DEFINE_KEYCODE(BUTTON_6),\n    DEFINE_KEYCODE(BUTTON_7),\n    DEFINE_KEYCODE(BUTTON_8),\n    DEFINE_KEYCODE(BUTTON_9),\n    DEFINE_KEYCODE(BUTTON_10),\n    DEFINE_KEYCODE(BUTTON_11),\n    DEFINE_KEYCODE(BUTTON_12),\n    DEFINE_KEYCODE(BUTTON_13),\n    DEFINE_KEYCODE(BUTTON_14),\n    DEFINE_KEYCODE(BUTTON_15),\n    DEFINE_KEYCODE(BUTTON_16),\n    DEFINE_KEYCODE(LANGUAGE_SWITCH),\n    DEFINE_KEYCODE(MANNER_MODE),\n    DEFINE_KEYCODE(3D_MODE),\n    DEFINE_KEYCODE(CONTACTS),\n    DEFINE_KEYCODE(CALENDAR),\n    DEFINE_KEYCODE(MUSIC),\n    DEFINE_KEYCODE(CALCULATOR),\n    DEFINE_KEYCODE(ZENKAKU_HANKAKU),\n    DEFINE_KEYCODE(EISU),\n    DEFINE_KEYCODE(MUHENKAN),\n    DEFINE_KEYCODE(HENKAN),\n    DEFINE_KEYCODE(KATAKANA_HIRAGANA),\n    DEFINE_KEYCODE(YEN),\n    DEFINE_KEYCODE(RO),\n    DEFINE_KEYCODE(KANA),\n    DEFINE_KEYCODE(ASSIST),\n    DEFINE_KEYCODE(BRIGHTNESS_DOWN),\n    DEFINE_KEYCODE(BRIGHTNESS_UP),\n    DEFINE_KEYCODE(MEDIA_AUDIO_TRACK),\n    DEFINE_KEYCODE(SLEEP),\n    DEFINE_KEYCODE(WAKEUP),\n    DEFINE_KEYCODE(PAIRING),\n    DEFINE_KEYCODE(MEDIA_TOP_MENU),\n    DEFINE_KEYCODE(11),\n    DEFINE_KEYCODE(12),\n    DEFINE_KEYCODE(LAST_CHANNEL),\n    DEFINE_KEYCODE(TV_DATA_SERVICE),\n    DEFINE_KEYCODE(VOICE_ASSIST),\n    DEFINE_KEYCODE(TV_RADIO_SERVICE),\n    DEFINE_KEYCODE(TV_TELETEXT),\n    DEFINE_KEYCODE(TV_NUMBER_ENTRY),\n    DEFINE_KEYCODE(TV_TERRESTRIAL_ANALOG),\n    DEFINE_KEYCODE(TV_TERRESTRIAL_DIGITAL),\n    DEFINE_KEYCODE(TV_SATELLITE),\n    DEFINE_KEYCODE(TV_SATELLITE_BS),\n    DEFINE_KEYCODE(TV_SATELLITE_CS),\n    DEFINE_KEYCODE(TV_SATELLITE_SERVICE),\n    DEFINE_KEYCODE(TV_NETWORK),\n    DEFINE_KEYCODE(TV_ANTENNA_CABLE),\n    DEFINE_KEYCODE(TV_INPUT_HDMI_1),\n    DEFINE_KEYCODE(TV_INPUT_HDMI_2),\n    DEFINE_KEYCODE(TV_INPUT_HDMI_3),\n    DEFINE_KEYCODE(TV_INPUT_HDMI_4),\n    DEFINE_KEYCODE(TV_INPUT_COMPOSITE_1),\n    DEFINE_KEYCODE(TV_INPUT_COMPOSITE_2),\n    DEFINE_KEYCODE(TV_INPUT_COMPONENT_1),\n    DEFINE_KEYCODE(TV_INPUT_COMPONENT_2),\n    DEFINE_KEYCODE(TV_INPUT_VGA_1),\n    DEFINE_KEYCODE(TV_AUDIO_DESCRIPTION),\n    DEFINE_KEYCODE(TV_AUDIO_DESCRIPTION_MIX_UP),\n    DEFINE_KEYCODE(TV_AUDIO_DESCRIPTION_MIX_DOWN),\n    DEFINE_KEYCODE(TV_ZOOM_MODE),\n    DEFINE_KEYCODE(TV_CONTENTS_MENU),\n    DEFINE_KEYCODE(TV_MEDIA_CONTEXT_MENU),\n    DEFINE_KEYCODE(TV_TIMER_PROGRAMMING),\n    DEFINE_KEYCODE(HELP),\n    DEFINE_KEYCODE(NAVIGATE_PREVIOUS),\n    DEFINE_KEYCODE(NAVIGATE_NEXT),\n    DEFINE_KEYCODE(NAVIGATE_IN),\n    DEFINE_KEYCODE(NAVIGATE_OUT),\n    DEFINE_KEYCODE(STEM_PRIMARY),\n    DEFINE_KEYCODE(STEM_1),\n    DEFINE_KEYCODE(STEM_2),\n    DEFINE_KEYCODE(STEM_3),\n    DEFINE_KEYCODE(DPAD_UP_LEFT),\n    DEFINE_KEYCODE(DPAD_DOWN_LEFT),\n    DEFINE_KEYCODE(DPAD_UP_RIGHT),\n    DEFINE_KEYCODE(DPAD_DOWN_RIGHT),\n    DEFINE_KEYCODE(MEDIA_SKIP_FORWARD),\n    DEFINE_KEYCODE(MEDIA_SKIP_BACKWARD),\n    DEFINE_KEYCODE(MEDIA_STEP_FORWARD),\n    DEFINE_KEYCODE(MEDIA_STEP_BACKWARD),\n    DEFINE_KEYCODE(SOFT_SLEEP),\n    DEFINE_KEYCODE(CUT),\n    DEFINE_KEYCODE(COPY),\n    DEFINE_KEYCODE(PASTE),\n\n    { NULL, 0 }\n};\n\nstatic const InputEventLabel AXES[] = {\n    DEFINE_AXIS(X),\n    DEFINE_AXIS(Y),\n    DEFINE_AXIS(PRESSURE),\n    DEFINE_AXIS(SIZE),\n    DEFINE_AXIS(TOUCH_MAJOR),\n    DEFINE_AXIS(TOUCH_MINOR),\n    DEFINE_AXIS(TOOL_MAJOR),\n    DEFINE_AXIS(TOOL_MINOR),\n    DEFINE_AXIS(ORIENTATION),\n    DEFINE_AXIS(VSCROLL),\n    DEFINE_AXIS(HSCROLL),\n    DEFINE_AXIS(Z),\n    DEFINE_AXIS(RX),\n    DEFINE_AXIS(RY),\n    DEFINE_AXIS(RZ),\n    DEFINE_AXIS(HAT_X),\n    DEFINE_AXIS(HAT_Y),\n    DEFINE_AXIS(LTRIGGER),\n    DEFINE_AXIS(RTRIGGER),\n    DEFINE_AXIS(THROTTLE),\n    DEFINE_AXIS(RUDDER),\n    DEFINE_AXIS(WHEEL),\n    DEFINE_AXIS(GAS),\n    DEFINE_AXIS(BRAKE),\n    DEFINE_AXIS(DISTANCE),\n    DEFINE_AXIS(TILT),\n    DEFINE_AXIS(GENERIC_1),\n    DEFINE_AXIS(GENERIC_2),\n    DEFINE_AXIS(GENERIC_3),\n    DEFINE_AXIS(GENERIC_4),\n    DEFINE_AXIS(GENERIC_5),\n    DEFINE_AXIS(GENERIC_6),\n    DEFINE_AXIS(GENERIC_7),\n    DEFINE_AXIS(GENERIC_8),\n    DEFINE_AXIS(GENERIC_9),\n    DEFINE_AXIS(GENERIC_10),\n    DEFINE_AXIS(GENERIC_11),\n    DEFINE_AXIS(GENERIC_12),\n    DEFINE_AXIS(GENERIC_13),\n    DEFINE_AXIS(GENERIC_14),\n    DEFINE_AXIS(GENERIC_15),\n    DEFINE_AXIS(GENERIC_16),\n\n    // NOTE: If you add a new axis here you must also add it to several other files.\n    //       Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.\n    { NULL, 0 }\n};\n\nstatic const InputEventLabel LEDS[] = {\n    DEFINE_LED(NUM_LOCK),\n    DEFINE_LED(CAPS_LOCK),\n    DEFINE_LED(SCROLL_LOCK),\n    DEFINE_LED(COMPOSE),\n    DEFINE_LED(KANA),\n    DEFINE_LED(SLEEP),\n    DEFINE_LED(SUSPEND),\n    DEFINE_LED(MUTE),\n    DEFINE_LED(MISC),\n    DEFINE_LED(MAIL),\n    DEFINE_LED(CHARGING),\n    DEFINE_LED(CONTROLLER_1),\n    DEFINE_LED(CONTROLLER_2),\n    DEFINE_LED(CONTROLLER_3),\n    DEFINE_LED(CONTROLLER_4),\n\n    // NOTE: If you add new LEDs here, you must also add them to Input.h\n    { NULL, 0 }\n};\n\nstatic const InputEventLabel FLAGS[] = {\n    DEFINE_FLAG(VIRTUAL),\n    DEFINE_FLAG(FUNCTION),\n    DEFINE_FLAG(GESTURE),\n\n    { NULL, 0 }\n};\n\nstatic int lookupValueByLabel(const char* literal, const InputEventLabel *list) {\n    while (list->literal) {\n        if (strcmp(literal, list->literal) == 0) {\n            return list->value;\n        }\n        list++;\n    }\n    return list->value;\n}\n\nstatic const char* lookupLabelByValue(int value, const InputEventLabel* list) {\n    while (list->literal) {\n        if (list->value == value) {\n            return list->literal;\n        }\n        list++;\n    }\n    return NULL;\n}\n\nstatic int32_t getKeyCodeByLabel(const char* label) {\n    return int32_t(lookupValueByLabel(label, KEYCODES));\n}\n\nstatic const char* getLabelByKeyCode(int32_t keyCode) {\n    if (keyCode >= 0 && keyCode < size(KEYCODES)) {\n        return KEYCODES[keyCode].literal;\n    }\n    return NULL;\n}\n\nstatic uint32_t getKeyFlagByLabel(const char* label) {\n    return uint32_t(lookupValueByLabel(label, FLAGS));\n}\n\nstatic int32_t getAxisByLabel(const char* label) {\n    return int32_t(lookupValueByLabel(label, AXES));\n}\n\nstatic const char* getAxisLabel(int32_t axisId) {\n    return lookupLabelByValue(axisId, AXES);\n}\n\nstatic int32_t getLedByLabel(const char* label) {\n    return int32_t(lookupValueByLabel(label, LEDS));\n}\n\n\n} // namespace android\n#endif // _LIBINPUT_INPUT_EVENT_LABELS_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/input/InputTransport.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBINPUT_INPUT_TRANSPORT_H\n#define _LIBINPUT_INPUT_TRANSPORT_H\n\n/**\n * Native input transport.\n *\n * The InputChannel provides a mechanism for exchanging InputMessage structures across processes.\n *\n * The InputPublisher and InputConsumer each handle one end-point of an input channel.\n * The InputPublisher is used by the input dispatcher to send events to the application.\n * The InputConsumer is used by the application to receive events from the input dispatcher.\n */\n\n#include <input/Input.h>\n#include <utils/Errors.h>\n#include <utils/Timers.h>\n#include <utils/RefBase.h>\n#include <utils/String8.h>\n#include <utils/Vector.h>\n#include <utils/BitSet.h>\n\nnamespace android {\n\n/*\n * Intermediate representation used to send input events and related signals.\n *\n * Note that this structure is used for IPCs so its layout must be identical\n * on 64 and 32 bit processes. This is tested in StructLayout_test.cpp.\n */\nstruct InputMessage {\n    enum {\n        TYPE_KEY = 1,\n        TYPE_MOTION = 2,\n        TYPE_FINISHED = 3,\n    };\n\n    struct Header {\n        uint32_t type;\n        // We don't need this field in order to align the body below but we\n        // leave it here because InputMessage::size() and other functions\n        // compute the size of this structure as sizeof(Header) + sizeof(Body).\n        uint32_t padding;\n    } header;\n\n    // Body *must* be 8 byte aligned.\n    union Body {\n        struct Key {\n            uint32_t seq;\n            nsecs_t eventTime __attribute__((aligned(8)));\n            int32_t deviceId;\n            int32_t source;\n            int32_t action;\n            int32_t flags;\n            int32_t keyCode;\n            int32_t scanCode;\n            int32_t metaState;\n            int32_t repeatCount;\n            nsecs_t downTime __attribute__((aligned(8)));\n\n            inline size_t size() const {\n                return sizeof(Key);\n            }\n        } key;\n\n        struct Motion {\n            uint32_t seq;\n            nsecs_t eventTime __attribute__((aligned(8)));\n            int32_t deviceId;\n            int32_t source;\n            int32_t action;\n            int32_t actionButton;\n            int32_t flags;\n            int32_t metaState;\n            int32_t buttonState;\n            int32_t edgeFlags;\n            nsecs_t downTime __attribute__((aligned(8)));\n            float xOffset;\n            float yOffset;\n            float xPrecision;\n            float yPrecision;\n            uint32_t pointerCount;\n            // Note that PointerCoords requires 8 byte alignment.\n            struct Pointer {\n                PointerProperties properties;\n                PointerCoords coords;\n            } pointers[MAX_POINTERS];\n\n            int32_t getActionId() const {\n                uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)\n                        >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;\n                return pointers[index].properties.id;\n            }\n\n            inline size_t size() const {\n                return sizeof(Motion) - sizeof(Pointer) * MAX_POINTERS\n                        + sizeof(Pointer) * pointerCount;\n            }\n        } motion;\n\n        struct Finished {\n            uint32_t seq;\n            bool handled;\n\n            inline size_t size() const {\n                return sizeof(Finished);\n            }\n        } finished;\n    } __attribute__((aligned(8))) body;\n\n    bool isValid(size_t actualSize) const;\n    size_t size() const;\n};\n\n/*\n * An input channel consists of a local unix domain socket used to send and receive\n * input messages across processes.  Each channel has a descriptive name for debugging purposes.\n *\n * Each endpoint has its own InputChannel object that specifies its file descriptor.\n *\n * The input channel is closed when all references to it are released.\n */\nclass InputChannel : public RefBase {\nprotected:\n    virtual ~InputChannel();\n\npublic:\n    InputChannel(const String8& name, int fd);\n\n    /* Creates a pair of input channels.\n     *\n     * Returns OK on success.\n     */\n    static status_t openInputChannelPair(const String8& name,\n            sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel);\n\n    inline String8 getName() const { return mName; }\n    inline int getFd() const { return mFd; }\n\n    /* Sends a message to the other endpoint.\n     *\n     * If the channel is full then the message is guaranteed not to have been sent at all.\n     * Try again after the consumer has sent a finished signal indicating that it has\n     * consumed some of the pending messages from the channel.\n     *\n     * Returns OK on success.\n     * Returns WOULD_BLOCK if the channel is full.\n     * Returns DEAD_OBJECT if the channel's peer has been closed.\n     * Other errors probably indicate that the channel is broken.\n     */\n    status_t sendMessage(const InputMessage* msg);\n\n    /* Receives a message sent by the other endpoint.\n     *\n     * If there is no message present, try again after poll() indicates that the fd\n     * is readable.\n     *\n     * Returns OK on success.\n     * Returns WOULD_BLOCK if there is no message present.\n     * Returns DEAD_OBJECT if the channel's peer has been closed.\n     * Other errors probably indicate that the channel is broken.\n     */\n    status_t receiveMessage(InputMessage* msg);\n\n    /* Returns a new object that has a duplicate of this channel's fd. */\n    sp<InputChannel> dup() const;\n\nprivate:\n    String8 mName;\n    int mFd;\n};\n\n/*\n * Publishes input events to an input channel.\n */\nclass InputPublisher {\npublic:\n    /* Creates a publisher associated with an input channel. */\n    explicit InputPublisher(const sp<InputChannel>& channel);\n\n    /* Destroys the publisher and releases its input channel. */\n    ~InputPublisher();\n\n    /* Gets the underlying input channel. */\n    inline sp<InputChannel> getChannel() { return mChannel; }\n\n    /* Publishes a key event to the input channel.\n     *\n     * Returns OK on success.\n     * Returns WOULD_BLOCK if the channel is full.\n     * Returns DEAD_OBJECT if the channel's peer has been closed.\n     * Returns BAD_VALUE if seq is 0.\n     * Other errors probably indicate that the channel is broken.\n     */\n    status_t publishKeyEvent(\n            uint32_t seq,\n            int32_t deviceId,\n            int32_t source,\n            int32_t action,\n            int32_t flags,\n            int32_t keyCode,\n            int32_t scanCode,\n            int32_t metaState,\n            int32_t repeatCount,\n            nsecs_t downTime,\n            nsecs_t eventTime);\n\n    /* Publishes a motion event to the input channel.\n     *\n     * Returns OK on success.\n     * Returns WOULD_BLOCK if the channel is full.\n     * Returns DEAD_OBJECT if the channel's peer has been closed.\n     * Returns BAD_VALUE if seq is 0 or if pointerCount is less than 1 or greater than MAX_POINTERS.\n     * Other errors probably indicate that the channel is broken.\n     */\n    status_t publishMotionEvent(\n            uint32_t seq,\n            int32_t deviceId,\n            int32_t source,\n            int32_t action,\n            int32_t actionButton,\n            int32_t flags,\n            int32_t edgeFlags,\n            int32_t metaState,\n            int32_t buttonState,\n            float xOffset,\n            float yOffset,\n            float xPrecision,\n            float yPrecision,\n            nsecs_t downTime,\n            nsecs_t eventTime,\n            uint32_t pointerCount,\n            const PointerProperties* pointerProperties,\n            const PointerCoords* pointerCoords);\n\n    /* Receives the finished signal from the consumer in reply to the original dispatch signal.\n     * If a signal was received, returns the message sequence number,\n     * and whether the consumer handled the message.\n     *\n     * The returned sequence number is never 0 unless the operation failed.\n     *\n     * Returns OK on success.\n     * Returns WOULD_BLOCK if there is no signal present.\n     * Returns DEAD_OBJECT if the channel's peer has been closed.\n     * Other errors probably indicate that the channel is broken.\n     */\n    status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled);\n\nprivate:\n    sp<InputChannel> mChannel;\n};\n\n/*\n * Consumes input events from an input channel.\n */\nclass InputConsumer {\npublic:\n    /* Creates a consumer associated with an input channel. */\n    explicit InputConsumer(const sp<InputChannel>& channel);\n\n    /* Destroys the consumer and releases its input channel. */\n    ~InputConsumer();\n\n    /* Gets the underlying input channel. */\n    inline sp<InputChannel> getChannel() { return mChannel; }\n\n    /* Consumes an input event from the input channel and copies its contents into\n     * an InputEvent object created using the specified factory.\n     *\n     * Tries to combine a series of move events into larger batches whenever possible.\n     *\n     * If consumeBatches is false, then defers consuming pending batched events if it\n     * is possible for additional samples to be added to them later.  Call hasPendingBatch()\n     * to determine whether a pending batch is available to be consumed.\n     *\n     * If consumeBatches is true, then events are still batched but they are consumed\n     * immediately as soon as the input channel is exhausted.\n     *\n     * The frameTime parameter specifies the time when the current display frame started\n     * rendering in the CLOCK_MONOTONIC time base, or -1 if unknown.\n     *\n     * The returned sequence number is never 0 unless the operation failed.\n     *\n     * Returns OK on success.\n     * Returns WOULD_BLOCK if there is no event present.\n     * Returns DEAD_OBJECT if the channel's peer has been closed.\n     * Returns NO_MEMORY if the event could not be created.\n     * Other errors probably indicate that the channel is broken.\n     */\n    status_t consume(InputEventFactoryInterface* factory, bool consumeBatches,\n            nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);\n\n    /* Sends a finished signal to the publisher to inform it that the message\n     * with the specified sequence number has finished being process and whether\n     * the message was handled by the consumer.\n     *\n     * Returns OK on success.\n     * Returns BAD_VALUE if seq is 0.\n     * Other errors probably indicate that the channel is broken.\n     */\n    status_t sendFinishedSignal(uint32_t seq, bool handled);\n\n    /* Returns true if there is a deferred event waiting.\n     *\n     * Should be called after calling consume() to determine whether the consumer\n     * has a deferred event to be processed.  Deferred events are somewhat special in\n     * that they have already been removed from the input channel.  If the input channel\n     * becomes empty, the client may need to do extra work to ensure that it processes\n     * the deferred event despite the fact that the input channel's file descriptor\n     * is not readable.\n     *\n     * One option is simply to call consume() in a loop until it returns WOULD_BLOCK.\n     * This guarantees that all deferred events will be processed.\n     *\n     * Alternately, the caller can call hasDeferredEvent() to determine whether there is\n     * a deferred event waiting and then ensure that its event loop wakes up at least\n     * one more time to consume the deferred event.\n     */\n    bool hasDeferredEvent() const;\n\n    /* Returns true if there is a pending batch.\n     *\n     * Should be called after calling consume() with consumeBatches == false to determine\n     * whether consume() should be called again later on with consumeBatches == true.\n     */\n    bool hasPendingBatch() const;\n\nprivate:\n    // True if touch resampling is enabled.\n    const bool mResampleTouch;\n\n    // The input channel.\n    sp<InputChannel> mChannel;\n\n    // The current input message.\n    InputMessage mMsg;\n\n    // True if mMsg contains a valid input message that was deferred from the previous\n    // call to consume and that still needs to be handled.\n    bool mMsgDeferred;\n\n    // Batched motion events per device and source.\n    struct Batch {\n        Vector<InputMessage> samples;\n    };\n    Vector<Batch> mBatches;\n\n    // Touch state per device and source, only for sources of class pointer.\n    struct History {\n        nsecs_t eventTime;\n        BitSet32 idBits;\n        int32_t idToIndex[MAX_POINTER_ID + 1];\n        PointerCoords pointers[MAX_POINTERS];\n\n        void initializeFrom(const InputMessage* msg) {\n            eventTime = msg->body.motion.eventTime;\n            idBits.clear();\n            for (uint32_t i = 0; i < msg->body.motion.pointerCount; i++) {\n                uint32_t id = msg->body.motion.pointers[i].properties.id;\n                idBits.markBit(id);\n                idToIndex[id] = i;\n                pointers[i].copyFrom(msg->body.motion.pointers[i].coords);\n            }\n        }\n\n        const PointerCoords& getPointerById(uint32_t id) const {\n            return pointers[idToIndex[id]];\n        }\n    };\n    struct TouchState {\n        int32_t deviceId;\n        int32_t source;\n        size_t historyCurrent;\n        size_t historySize;\n        History history[2];\n        History lastResample;\n\n        void initialize(int32_t deviceId, int32_t source) {\n            this->deviceId = deviceId;\n            this->source = source;\n            historyCurrent = 0;\n            historySize = 0;\n            lastResample.eventTime = 0;\n            lastResample.idBits.clear();\n        }\n\n        void addHistory(const InputMessage* msg) {\n            historyCurrent ^= 1;\n            if (historySize < 2) {\n                historySize += 1;\n            }\n            history[historyCurrent].initializeFrom(msg);\n        }\n\n        const History* getHistory(size_t index) const {\n            return &history[(historyCurrent + index) & 1];\n        }\n    };\n    Vector<TouchState> mTouchStates;\n\n    // Chain of batched sequence numbers.  When multiple input messages are combined into\n    // a batch, we append a record here that associates the last sequence number in the\n    // batch with the previous one.  When the finished signal is sent, we traverse the\n    // chain to individually finish all input messages that were part of the batch.\n    struct SeqChain {\n        uint32_t seq;   // sequence number of batched input message\n        uint32_t chain; // sequence number of previous batched input message\n    };\n    Vector<SeqChain> mSeqChains;\n\n    status_t consumeBatch(InputEventFactoryInterface* factory,\n            nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);\n    status_t consumeSamples(InputEventFactoryInterface* factory,\n            Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent);\n\n    void updateTouchState(InputMessage* msg);\n    void rewriteMessage(const TouchState& state, InputMessage* msg);\n    void resampleTouchState(nsecs_t frameTime, MotionEvent* event,\n            const InputMessage *next);\n\n    ssize_t findBatch(int32_t deviceId, int32_t source) const;\n    ssize_t findTouchState(int32_t deviceId, int32_t source) const;\n\n    status_t sendUnchainedFinishedSignal(uint32_t seq, bool handled);\n\n    static void initializeKeyEvent(KeyEvent* event, const InputMessage* msg);\n    static void initializeMotionEvent(MotionEvent* event, const InputMessage* msg);\n    static void addSample(MotionEvent* event, const InputMessage* msg);\n    static bool canAddSample(const Batch& batch, const InputMessage* msg);\n    static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time);\n    static bool shouldResampleTool(int32_t toolType);\n\n    static bool isTouchResamplingEnabled();\n};\n\n} // namespace android\n\n#endif // _LIBINPUT_INPUT_TRANSPORT_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/input/KeyCharacterMap.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBINPUT_KEY_CHARACTER_MAP_H\n#define _LIBINPUT_KEY_CHARACTER_MAP_H\n\n#include <stdint.h>\n\n#ifdef __ANDROID__\n#include <binder/IBinder.h>\n#endif\n\n#include <input/Input.h>\n#include <utils/Errors.h>\n#include <utils/KeyedVector.h>\n#include <utils/Tokenizer.h>\n#include <utils/String8.h>\n#include <utils/Unicode.h>\n#include <utils/RefBase.h>\n\n// Maximum number of keys supported by KeyCharacterMaps\n#define MAX_KEYS 8192\n\nnamespace android {\n\n/**\n * Describes a mapping from Android key codes to characters.\n * Also specifies other functions of the keyboard such as the keyboard type\n * and key modifier semantics.\n *\n * This object is immutable after it has been loaded.\n */\nclass KeyCharacterMap : public RefBase {\npublic:\n    enum KeyboardType {\n        KEYBOARD_TYPE_UNKNOWN = 0,\n        KEYBOARD_TYPE_NUMERIC = 1,\n        KEYBOARD_TYPE_PREDICTIVE = 2,\n        KEYBOARD_TYPE_ALPHA = 3,\n        KEYBOARD_TYPE_FULL = 4,\n        KEYBOARD_TYPE_SPECIAL_FUNCTION = 5,\n        KEYBOARD_TYPE_OVERLAY = 6,\n    };\n\n    enum Format {\n        // Base keyboard layout, may contain device-specific options, such as \"type\" declaration.\n        FORMAT_BASE = 0,\n        // Overlay keyboard layout, more restrictive, may be published by applications,\n        // cannot override device-specific options.\n        FORMAT_OVERLAY = 1,\n        // Either base or overlay layout ok.\n        FORMAT_ANY = 2,\n    };\n\n    // Substitute key code and meta state for fallback action.\n    struct FallbackAction {\n        int32_t keyCode;\n        int32_t metaState;\n    };\n\n    /* Loads a key character map from a file. */\n    static status_t load(const String8& filename, Format format, sp<KeyCharacterMap>* outMap);\n\n    /* Loads a key character map from its string contents. */\n    static status_t loadContents(const String8& filename,\n            const char* contents, Format format, sp<KeyCharacterMap>* outMap);\n\n    /* Combines a base key character map and an overlay. */\n    static sp<KeyCharacterMap> combine(const sp<KeyCharacterMap>& base,\n            const sp<KeyCharacterMap>& overlay);\n\n    /* Returns an empty key character map. */\n    static sp<KeyCharacterMap> empty();\n\n    /* Gets the keyboard type. */\n    int32_t getKeyboardType() const;\n\n    /* Gets the primary character for this key as in the label physically printed on it.\n     * Returns 0 if none (eg. for non-printing keys). */\n    char16_t getDisplayLabel(int32_t keyCode) const;\n\n    /* Gets the Unicode character for the number or symbol generated by the key\n     * when the keyboard is used as a dialing pad.\n     * Returns 0 if no number or symbol is generated.\n     */\n    char16_t getNumber(int32_t keyCode) const;\n\n    /* Gets the Unicode character generated by the key and meta key modifiers.\n     * Returns 0 if no character is generated.\n     */\n    char16_t getCharacter(int32_t keyCode, int32_t metaState) const;\n\n    /* Gets the fallback action to use by default if the application does not\n     * handle the specified key.\n     * Returns true if an action was available, false if none.\n     */\n    bool getFallbackAction(int32_t keyCode, int32_t metaState,\n            FallbackAction* outFallbackAction) const;\n\n    /* Gets the first matching Unicode character that can be generated by the key,\n     * preferring the one with the specified meta key modifiers.\n     * Returns 0 if no matching character is generated.\n     */\n    char16_t getMatch(int32_t keyCode, const char16_t* chars,\n            size_t numChars, int32_t metaState) const;\n\n    /* Gets a sequence of key events that could plausibly generate the specified\n     * character sequence.  Returns false if some of the characters cannot be generated.\n     */\n    bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,\n            Vector<KeyEvent>& outEvents) const;\n\n    /* Maps a scan code and usage code to a key code, in case this key map overrides\n     * the mapping in some way. */\n    status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const;\n\n    /* Tries to find a replacement key code for a given key code and meta state\n     * in character map. */\n    void tryRemapKey(int32_t scanCode, int32_t metaState,\n            int32_t* outKeyCode, int32_t* outMetaState) const;\n\n#ifdef __ANDROID__\n    /* Reads a key map from a parcel. */\n    static sp<KeyCharacterMap> readFromParcel(Parcel* parcel);\n\n    /* Writes a key map to a parcel. */\n    void writeToParcel(Parcel* parcel) const;\n#endif\n\nprotected:\n    virtual ~KeyCharacterMap();\n\nprivate:\n    struct Behavior {\n        Behavior();\n        Behavior(const Behavior& other);\n\n        /* The next behavior in the list, or NULL if none. */\n        Behavior* next;\n\n        /* The meta key modifiers for this behavior. */\n        int32_t metaState;\n\n        /* The character to insert. */\n        char16_t character;\n\n        /* The fallback keycode if the key is not handled. */\n        int32_t fallbackKeyCode;\n\n        /* The replacement keycode if the key has to be replaced outright. */\n        int32_t replacementKeyCode;\n    };\n\n    struct Key {\n        Key();\n        Key(const Key& other);\n        ~Key();\n\n        /* The single character label printed on the key, or 0 if none. */\n        char16_t label;\n\n        /* The number or symbol character generated by the key, or 0 if none. */\n        char16_t number;\n\n        /* The list of key behaviors sorted from most specific to least specific\n         * meta key binding. */\n        Behavior* firstBehavior;\n    };\n\n    class Parser {\n        enum State {\n            STATE_TOP = 0,\n            STATE_KEY = 1,\n        };\n\n        enum {\n            PROPERTY_LABEL = 1,\n            PROPERTY_NUMBER = 2,\n            PROPERTY_META = 3,\n        };\n\n        struct Property {\n            inline Property(int32_t property = 0, int32_t metaState = 0) :\n                    property(property), metaState(metaState) { }\n\n            int32_t property;\n            int32_t metaState;\n        };\n\n        KeyCharacterMap* mMap;\n        Tokenizer* mTokenizer;\n        Format mFormat;\n        State mState;\n        int32_t mKeyCode;\n\n    public:\n        Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format);\n        ~Parser();\n        status_t parse();\n\n    private:\n        status_t parseType();\n        status_t parseMap();\n        status_t parseMapKey();\n        status_t parseKey();\n        status_t parseKeyProperty();\n        status_t finishKey(Key* key);\n        status_t parseModifier(const String8& token, int32_t* outMetaState);\n        status_t parseCharacterLiteral(char16_t* outCharacter);\n    };\n\n    static sp<KeyCharacterMap> sEmpty;\n\n    KeyedVector<int32_t, Key*> mKeys;\n    int mType;\n\n    KeyedVector<int32_t, int32_t> mKeysByScanCode;\n    KeyedVector<int32_t, int32_t> mKeysByUsageCode;\n\n    KeyCharacterMap();\n    KeyCharacterMap(const KeyCharacterMap& other);\n\n    bool getKey(int32_t keyCode, const Key** outKey) const;\n    bool getKeyBehavior(int32_t keyCode, int32_t metaState,\n            const Key** outKey, const Behavior** outBehavior) const;\n    static bool matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState);\n\n    bool findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const;\n\n    static status_t load(Tokenizer* tokenizer, Format format, sp<KeyCharacterMap>* outMap);\n\n    static void addKey(Vector<KeyEvent>& outEvents,\n            int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time);\n    static void addMetaKeys(Vector<KeyEvent>& outEvents,\n            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,\n            int32_t* currentMetaState);\n    static bool addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents,\n            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,\n            int32_t keyCode, int32_t keyMetaState,\n            int32_t* currentMetaState);\n    static void addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents,\n            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,\n            int32_t leftKeyCode, int32_t leftKeyMetaState,\n            int32_t rightKeyCode, int32_t rightKeyMetaState,\n            int32_t eitherKeyMetaState,\n            int32_t* currentMetaState);\n    static void addLockedMetaKey(Vector<KeyEvent>& outEvents,\n            int32_t deviceId, int32_t metaState, nsecs_t time,\n            int32_t keyCode, int32_t keyMetaState,\n            int32_t* currentMetaState);\n};\n\n} // namespace android\n\n#endif // _LIBINPUT_KEY_CHARACTER_MAP_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/input/KeyLayoutMap.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBINPUT_KEY_LAYOUT_MAP_H\n#define _LIBINPUT_KEY_LAYOUT_MAP_H\n\n#include <stdint.h>\n#include <utils/Errors.h>\n#include <utils/KeyedVector.h>\n#include <utils/Tokenizer.h>\n#include <utils/RefBase.h>\n\nnamespace android {\n\nstruct AxisInfo {\n    enum Mode {\n        // Axis value is reported directly.\n        MODE_NORMAL = 0,\n        // Axis value should be inverted before reporting.\n        MODE_INVERT = 1,\n        // Axis value should be split into two axes\n        MODE_SPLIT = 2,\n    };\n\n    // Axis mode.\n    Mode mode;\n\n    // Axis id.\n    // When split, this is the axis used for values smaller than the split position.\n    int32_t axis;\n\n    // When split, this is the axis used for values after higher than the split position.\n    int32_t highAxis;\n\n    // The split value, or 0 if not split.\n    int32_t splitValue;\n\n    // The flat value, or -1 if none.\n    int32_t flatOverride;\n\n    AxisInfo() : mode(MODE_NORMAL), axis(-1), highAxis(-1), splitValue(0), flatOverride(-1) {\n    }\n};\n\n/**\n * Describes a mapping from keyboard scan codes and joystick axes to Android key codes and axes.\n *\n * This object is immutable after it has been loaded.\n */\nclass KeyLayoutMap : public RefBase {\npublic:\n    static status_t load(const String8& filename, sp<KeyLayoutMap>* outMap);\n\n    status_t mapKey(int32_t scanCode, int32_t usageCode,\n            int32_t* outKeyCode, uint32_t* outFlags) const;\n    status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const;\n    status_t findScanCodeForLed(int32_t ledCode, int32_t* outScanCode) const;\n    status_t findUsageCodeForLed(int32_t ledCode, int32_t* outUsageCode) const;\n\n    status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const;\n\nprotected:\n    virtual ~KeyLayoutMap();\n\nprivate:\n    struct Key {\n        int32_t keyCode;\n        uint32_t flags;\n    };\n\n    struct Led {\n        int32_t ledCode;\n    };\n\n\n    KeyedVector<int32_t, Key> mKeysByScanCode;\n    KeyedVector<int32_t, Key> mKeysByUsageCode;\n    KeyedVector<int32_t, AxisInfo> mAxes;\n    KeyedVector<int32_t, Led> mLedsByScanCode;\n    KeyedVector<int32_t, Led> mLedsByUsageCode;\n\n    KeyLayoutMap();\n\n    const Key* getKey(int32_t scanCode, int32_t usageCode) const;\n\n    class Parser {\n        KeyLayoutMap* mMap;\n        Tokenizer* mTokenizer;\n\n    public:\n        Parser(KeyLayoutMap* map, Tokenizer* tokenizer);\n        ~Parser();\n        status_t parse();\n\n    private:\n        status_t parseKey();\n        status_t parseAxis();\n        status_t parseLed();\n    };\n};\n\n} // namespace android\n\n#endif // _LIBINPUT_KEY_LAYOUT_MAP_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/input/Keyboard.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBINPUT_KEYBOARD_H\n#define _LIBINPUT_KEYBOARD_H\n\n#include <input/Input.h>\n#include <input/InputDevice.h>\n#include <input/InputEventLabels.h>\n#include <utils/Errors.h>\n#include <utils/String8.h>\n#include <utils/PropertyMap.h>\n\nnamespace android {\n\nenum {\n    /* Device id of the built in keyboard. */\n    DEVICE_ID_BUILT_IN_KEYBOARD = 0,\n\n    /* Device id of a generic virtual keyboard with a full layout that can be used\n     * to synthesize key events. */\n    DEVICE_ID_VIRTUAL_KEYBOARD = -1,\n};\n\nclass KeyLayoutMap;\nclass KeyCharacterMap;\n\n/**\n * Loads the key layout map and key character map for a keyboard device.\n */\nclass KeyMap {\npublic:\n    String8 keyLayoutFile;\n    sp<KeyLayoutMap> keyLayoutMap;\n\n    String8 keyCharacterMapFile;\n    sp<KeyCharacterMap> keyCharacterMap;\n\n    KeyMap();\n    ~KeyMap();\n\n    status_t load(const InputDeviceIdentifier& deviceIdenfier,\n            const PropertyMap* deviceConfiguration);\n\n    inline bool haveKeyLayout() const {\n        return !keyLayoutFile.isEmpty();\n    }\n\n    inline bool haveKeyCharacterMap() const {\n        return !keyCharacterMapFile.isEmpty();\n    }\n\n    inline bool isComplete() const {\n        return haveKeyLayout() && haveKeyCharacterMap();\n    }\n\nprivate:\n    bool probeKeyMap(const InputDeviceIdentifier& deviceIdentifier, const String8& name);\n    status_t loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier, const String8& name);\n    status_t loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,\n            const String8& name);\n    String8 getPath(const InputDeviceIdentifier& deviceIdentifier,\n            const String8& name, InputDeviceConfigurationFileType type);\n};\n\n/**\n * Returns true if the keyboard is eligible for use as a built-in keyboard.\n */\nextern bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,\n        const PropertyMap* deviceConfiguration, const KeyMap* keyMap);\n\n/**\n * Updates a meta state field when a key is pressed or released.\n */\nextern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);\n\n/**\n * Normalizes the meta state such that if either the left or right modifier\n * meta state bits are set then the result will also include the universal\n * bit for that modifier.\n */\nextern int32_t normalizeMetaState(int32_t oldMetaState);\n\n/**\n * Returns true if a key is a meta key like ALT or CAPS_LOCK.\n */\nextern bool isMetaKey(int32_t keyCode);\n\n} // namespace android\n\n#endif // _LIBINPUT_KEYBOARD_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/input/VelocityControl.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBINPUT_VELOCITY_CONTROL_H\n#define _LIBINPUT_VELOCITY_CONTROL_H\n\n#include <input/Input.h>\n#include <input/VelocityTracker.h>\n#include <utils/Timers.h>\n\nnamespace android {\n\n/*\n * Specifies parameters that govern pointer or wheel acceleration.\n */\nstruct VelocityControlParameters {\n    // A scale factor that is multiplied with the raw velocity deltas\n    // prior to applying any other velocity control factors.  The scale\n    // factor should be used to adapt the input device resolution\n    // (eg. counts per inch) to the output device resolution (eg. pixels per inch).\n    //\n    // Must be a positive value.\n    // Default is 1.0 (no scaling).\n    float scale;\n\n    // The scaled speed at which acceleration begins to be applied.\n    // This value establishes the upper bound of a low speed regime for\n    // small precise motions that are performed without any acceleration.\n    //\n    // Must be a non-negative value.\n    // Default is 0.0 (no low threshold).\n    float lowThreshold;\n\n    // The scaled speed at which maximum acceleration is applied.\n    // The difference between highThreshold and lowThreshold controls\n    // the range of speeds over which the acceleration factor is interpolated.\n    // The wider the range, the smoother the acceleration.\n    //\n    // Must be a non-negative value greater than or equal to lowThreshold.\n    // Default is 0.0 (no high threshold).\n    float highThreshold;\n\n    // The acceleration factor.\n    // When the speed is above the low speed threshold, the velocity will scaled\n    // by an interpolated value between 1.0 and this amount.\n    //\n    // Must be a positive greater than or equal to 1.0.\n    // Default is 1.0 (no acceleration).\n    float acceleration;\n\n    VelocityControlParameters() :\n            scale(1.0f), lowThreshold(0.0f), highThreshold(0.0f), acceleration(1.0f) {\n    }\n\n    VelocityControlParameters(float scale, float lowThreshold,\n            float highThreshold, float acceleration) :\n            scale(scale), lowThreshold(lowThreshold),\n            highThreshold(highThreshold), acceleration(acceleration) {\n    }\n};\n\n/*\n * Implements mouse pointer and wheel speed control and acceleration.\n */\nclass VelocityControl {\npublic:\n    VelocityControl();\n\n    /* Sets the various parameters. */\n    void setParameters(const VelocityControlParameters& parameters);\n\n    /* Resets the current movement counters to zero.\n     * This has the effect of nullifying any acceleration. */\n    void reset();\n\n    /* Translates a raw movement delta into an appropriately\n     * scaled / accelerated delta based on the current velocity. */\n    void move(nsecs_t eventTime, float* deltaX, float* deltaY);\n\nprivate:\n    // If no movements are received within this amount of time,\n    // we assume the movement has stopped and reset the movement counters.\n    static const nsecs_t STOP_TIME = 500 * 1000000; // 500 ms\n\n    VelocityControlParameters mParameters;\n\n    nsecs_t mLastMovementTime;\n    VelocityTracker::Position mRawPosition;\n    VelocityTracker mVelocityTracker;\n};\n\n} // namespace android\n\n#endif // _LIBINPUT_VELOCITY_CONTROL_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/input/VelocityTracker.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBINPUT_VELOCITY_TRACKER_H\n#define _LIBINPUT_VELOCITY_TRACKER_H\n\n#include <input/Input.h>\n#include <utils/Timers.h>\n#include <utils/BitSet.h>\n\nnamespace android {\n\nclass VelocityTrackerStrategy;\n\n/*\n * Calculates the velocity of pointer movements over time.\n */\nclass VelocityTracker {\npublic:\n    struct Position {\n        float x, y;\n    };\n\n    struct Estimator {\n        static const size_t MAX_DEGREE = 4;\n\n        // Estimator time base.\n        nsecs_t time;\n\n        // Polynomial coefficients describing motion in X and Y.\n        float xCoeff[MAX_DEGREE + 1], yCoeff[MAX_DEGREE + 1];\n\n        // Polynomial degree (number of coefficients), or zero if no information is\n        // available.\n        uint32_t degree;\n\n        // Confidence (coefficient of determination), between 0 (no fit) and 1 (perfect fit).\n        float confidence;\n\n        inline void clear() {\n            time = 0;\n            degree = 0;\n            confidence = 0;\n            for (size_t i = 0; i <= MAX_DEGREE; i++) {\n                xCoeff[i] = 0;\n                yCoeff[i] = 0;\n            }\n        }\n    };\n\n    // Creates a velocity tracker using the specified strategy.\n    // If strategy is NULL, uses the default strategy for the platform.\n    VelocityTracker(const char* strategy = NULL);\n\n    ~VelocityTracker();\n\n    // Resets the velocity tracker state.\n    void clear();\n\n    // Resets the velocity tracker state for specific pointers.\n    // Call this method when some pointers have changed and may be reusing\n    // an id that was assigned to a different pointer earlier.\n    void clearPointers(BitSet32 idBits);\n\n    // Adds movement information for a set of pointers.\n    // The idBits bitfield specifies the pointer ids of the pointers whose positions\n    // are included in the movement.\n    // The positions array contains position information for each pointer in order by\n    // increasing id.  Its size should be equal to the number of one bits in idBits.\n    void addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions);\n\n    // Adds movement information for all pointers in a MotionEvent, including historical samples.\n    void addMovement(const MotionEvent* event);\n\n    // Gets the velocity of the specified pointer id in position units per second.\n    // Returns false and sets the velocity components to zero if there is\n    // insufficient movement information for the pointer.\n    bool getVelocity(uint32_t id, float* outVx, float* outVy) const;\n\n    // Gets an estimator for the recent movements of the specified pointer id.\n    // Returns false and clears the estimator if there is no information available\n    // about the pointer.\n    bool getEstimator(uint32_t id, Estimator* outEstimator) const;\n\n    // Gets the active pointer id, or -1 if none.\n    inline int32_t getActivePointerId() const { return mActivePointerId; }\n\n    // Gets a bitset containing all pointer ids from the most recent movement.\n    inline BitSet32 getCurrentPointerIdBits() const { return mCurrentPointerIdBits; }\n\nprivate:\n    static const char* DEFAULT_STRATEGY;\n\n    nsecs_t mLastEventTime;\n    BitSet32 mCurrentPointerIdBits;\n    int32_t mActivePointerId;\n    VelocityTrackerStrategy* mStrategy;\n\n    bool configureStrategy(const char* strategy);\n\n    static VelocityTrackerStrategy* createStrategy(const char* strategy);\n};\n\n\n/*\n * Implements a particular velocity tracker algorithm.\n */\nclass VelocityTrackerStrategy {\nprotected:\n    VelocityTrackerStrategy() { }\n\npublic:\n    virtual ~VelocityTrackerStrategy() { }\n\n    virtual void clear() = 0;\n    virtual void clearPointers(BitSet32 idBits) = 0;\n    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,\n            const VelocityTracker::Position* positions) = 0;\n    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const = 0;\n};\n\n\n/*\n * Velocity tracker algorithm based on least-squares linear regression.\n */\nclass LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy {\npublic:\n    enum Weighting {\n        // No weights applied.  All data points are equally reliable.\n        WEIGHTING_NONE,\n\n        // Weight by time delta.  Data points clustered together are weighted less.\n        WEIGHTING_DELTA,\n\n        // Weight such that points within a certain horizon are weighed more than those\n        // outside of that horizon.\n        WEIGHTING_CENTRAL,\n\n        // Weight such that points older than a certain amount are weighed less.\n        WEIGHTING_RECENT,\n    };\n\n    // Degree must be no greater than Estimator::MAX_DEGREE.\n    LeastSquaresVelocityTrackerStrategy(uint32_t degree, Weighting weighting = WEIGHTING_NONE);\n    virtual ~LeastSquaresVelocityTrackerStrategy();\n\n    virtual void clear();\n    virtual void clearPointers(BitSet32 idBits);\n    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,\n            const VelocityTracker::Position* positions);\n    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;\n\nprivate:\n    // Sample horizon.\n    // We don't use too much history by default since we want to react to quick\n    // changes in direction.\n    static const nsecs_t HORIZON = 100 * 1000000; // 100 ms\n\n    // Number of samples to keep.\n    static const uint32_t HISTORY_SIZE = 20;\n\n    struct Movement {\n        nsecs_t eventTime;\n        BitSet32 idBits;\n        VelocityTracker::Position positions[MAX_POINTERS];\n\n        inline const VelocityTracker::Position& getPosition(uint32_t id) const {\n            return positions[idBits.getIndexOfBit(id)];\n        }\n    };\n\n    float chooseWeight(uint32_t index) const;\n\n    const uint32_t mDegree;\n    const Weighting mWeighting;\n    uint32_t mIndex;\n    Movement mMovements[HISTORY_SIZE];\n};\n\n\n/*\n * Velocity tracker algorithm that uses an IIR filter.\n */\nclass IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy {\npublic:\n    // Degree must be 1 or 2.\n    IntegratingVelocityTrackerStrategy(uint32_t degree);\n    ~IntegratingVelocityTrackerStrategy();\n\n    virtual void clear();\n    virtual void clearPointers(BitSet32 idBits);\n    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,\n            const VelocityTracker::Position* positions);\n    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;\n\nprivate:\n    // Current state estimate for a particular pointer.\n    struct State {\n        nsecs_t updateTime;\n        uint32_t degree;\n\n        float xpos, xvel, xaccel;\n        float ypos, yvel, yaccel;\n    };\n\n    const uint32_t mDegree;\n    BitSet32 mPointerIdBits;\n    State mPointerState[MAX_POINTER_ID + 1];\n\n    void initState(State& state, nsecs_t eventTime, float xpos, float ypos) const;\n    void updateState(State& state, nsecs_t eventTime, float xpos, float ypos) const;\n    void populateEstimator(const State& state, VelocityTracker::Estimator* outEstimator) const;\n};\n\n\n/*\n * Velocity tracker strategy used prior to ICS.\n */\nclass LegacyVelocityTrackerStrategy : public VelocityTrackerStrategy {\npublic:\n    LegacyVelocityTrackerStrategy();\n    virtual ~LegacyVelocityTrackerStrategy();\n\n    virtual void clear();\n    virtual void clearPointers(BitSet32 idBits);\n    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,\n            const VelocityTracker::Position* positions);\n    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;\n\nprivate:\n    // Oldest sample to consider when calculating the velocity.\n    static const nsecs_t HORIZON = 200 * 1000000; // 100 ms\n\n    // Number of samples to keep.\n    static const uint32_t HISTORY_SIZE = 20;\n\n    // The minimum duration between samples when estimating velocity.\n    static const nsecs_t MIN_DURATION = 10 * 1000000; // 10 ms\n\n    struct Movement {\n        nsecs_t eventTime;\n        BitSet32 idBits;\n        VelocityTracker::Position positions[MAX_POINTERS];\n\n        inline const VelocityTracker::Position& getPosition(uint32_t id) const {\n            return positions[idBits.getIndexOfBit(id)];\n        }\n    };\n\n    uint32_t mIndex;\n    Movement mMovements[HISTORY_SIZE];\n};\n\n} // namespace android\n\n#endif // _LIBINPUT_VELOCITY_TRACKER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/input/VirtualKeyMap.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBINPUT_VIRTUAL_KEY_MAP_H\n#define _LIBINPUT_VIRTUAL_KEY_MAP_H\n\n#include <stdint.h>\n\n#include <input/Input.h>\n#include <utils/Errors.h>\n#include <utils/KeyedVector.h>\n#include <utils/Tokenizer.h>\n#include <utils/String8.h>\n#include <utils/Unicode.h>\n\nnamespace android {\n\n/* Describes a virtual key. */\nstruct VirtualKeyDefinition {\n    int32_t scanCode;\n\n    // configured position data, specified in display coords\n    int32_t centerX;\n    int32_t centerY;\n    int32_t width;\n    int32_t height;\n};\n\n\n/**\n * Describes a collection of virtual keys on a touch screen in terms of\n * virtual scan codes and hit rectangles.\n *\n * This object is immutable after it has been loaded.\n */\nclass VirtualKeyMap {\npublic:\n    ~VirtualKeyMap();\n\n    static status_t load(const String8& filename, VirtualKeyMap** outMap);\n\n    inline const Vector<VirtualKeyDefinition>& getVirtualKeys() const {\n        return mVirtualKeys;\n    }\n\nprivate:\n    class Parser {\n        VirtualKeyMap* mMap;\n        Tokenizer* mTokenizer;\n\n    public:\n        Parser(VirtualKeyMap* map, Tokenizer* tokenizer);\n        ~Parser();\n        status_t parse();\n\n    private:\n        bool consumeFieldDelimiterAndSkipWhitespace();\n        bool parseNextIntField(int32_t* outValue);\n    };\n\n    Vector<VirtualKeyDefinition> mVirtualKeys;\n\n    VirtualKeyMap();\n};\n\n} // namespace android\n\n#endif // _LIBINPUT_KEY_CHARACTER_MAP_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/drm/DrmAPI.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef DRM_API_H_\n#define DRM_API_H_\n\n#include <utils/List.h>\n#include <utils/String8.h>\n#include <utils/Vector.h>\n#include <utils/KeyedVector.h>\n#include <utils/RefBase.h>\n#include <utils/Mutex.h>\n#include <media/stagefright/foundation/ABase.h>\n\n//  Loadable DrmEngine shared libraries should define the entry points\n//  createDrmFactory and createCryptoFactory as shown below:\n//\n//  extern \"C\" {\n//      extern android::DrmFactory *createDrmFactory();\n//      extern android::CryptoFactory *createCryptoFactory();\n//  }\n\nnamespace android {\n\n    class DrmPlugin;\n    class DrmPluginListener;\n\n    // DRMs are implemented in DrmEngine plugins, which are dynamically\n    // loadable shared libraries that implement the entry points\n    // createDrmFactory and createCryptoFactory.  createDrmFactory\n    // constructs and returns an instance of a DrmFactory object.  Similarly,\n    // createCryptoFactory creates an instance of a CryptoFactory object.\n    // When a MediaCrypto or MediaDrm object needs to be constructed, all\n    // available DrmEngines present in the plugins directory on the device\n    // are scanned for a matching DrmEngine that can support the crypto\n    // scheme.  When a match is found, the DrmEngine's createCryptoPlugin and\n    // createDrmPlugin methods are used to create CryptoPlugin or\n    // DrmPlugin instances to support that DRM scheme.\n\n    class DrmFactory {\n    public:\n        DrmFactory() {}\n        virtual ~DrmFactory() {}\n\n        // DrmFactory::isCryptoSchemeSupported can be called to determine\n        // if the plugin factory is able to construct plugins that support a\n        // given crypto scheme, which is specified by a UUID.\n        virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) = 0;\n\n        // DrmFactory::isContentTypeSupported can be called to determine\n        // if the plugin factory is able to construct plugins that support a\n        // given media container format specified by mimeType\n        virtual bool isContentTypeSupported(const String8 &mimeType) = 0;\n\n        // Construct a DrmPlugin for the crypto scheme specified by UUID.\n        virtual status_t createDrmPlugin(\n                const uint8_t uuid[16], DrmPlugin **plugin) = 0;\n\n    private:\n        DrmFactory(const DrmFactory &);\n        DrmFactory &operator=(const DrmFactory &);\n    };\n\n    class DrmPlugin {\n    public:\n        enum EventType {\n            kDrmPluginEventProvisionRequired = 1,\n            kDrmPluginEventKeyNeeded,\n            kDrmPluginEventKeyExpired,\n            kDrmPluginEventVendorDefined,\n            kDrmPluginEventSessionReclaimed,\n            kDrmPluginEventExpirationUpdate,\n            kDrmPluginEventKeysChange,\n        };\n\n        // Drm keys can be for offline content or for online streaming.\n        // Offline keys are persisted on the device and may be used when the device\n        // is disconnected from the network.  The Release type is used to request\n        // that offline keys be no longer restricted to offline use.\n        enum KeyType {\n            kKeyType_Offline,\n            kKeyType_Streaming,\n            kKeyType_Release\n        };\n\n        // Enumerate KeyRequestTypes to allow an app to determine the\n        // type of a key request returned from getKeyRequest.\n        enum KeyRequestType {\n            kKeyRequestType_Unknown,\n            kKeyRequestType_Initial,\n            kKeyRequestType_Renewal,\n            kKeyRequestType_Release\n        };\n\n        // Enumerate KeyStatusTypes which indicate the state of a key\n        enum KeyStatusType\n        {\n            kKeyStatusType_Usable,\n            kKeyStatusType_Expired,\n            kKeyStatusType_OutputNotAllowed,\n            kKeyStatusType_StatusPending,\n            kKeyStatusType_InternalError\n        };\n\n        // Used by sendKeysChange to report the usability status of each\n        // key to the app.\n        struct KeyStatus\n        {\n            Vector<uint8_t> mKeyId;\n            KeyStatusType mType;\n        };\n\n        DrmPlugin() {}\n        virtual ~DrmPlugin() {}\n\n        // Open a new session with the DrmPlugin object.  A session ID is returned\n        // in the sessionId parameter.\n        virtual status_t openSession(Vector<uint8_t> &sessionId) = 0;\n\n        // Close a session on the DrmPlugin object.\n        virtual status_t closeSession(Vector<uint8_t> const &sessionId) = 0;\n\n        // A key request/response exchange occurs between the app and a License\n        // Server to obtain the keys required to decrypt the content.  getKeyRequest()\n        // is used to obtain an opaque key request blob that is delivered to the\n        // license server.\n        //\n        // The scope parameter may be a sessionId or a keySetId, depending on the\n        // specified keyType.  When the keyType is kKeyType_Offline or\n        // kKeyType_Streaming, scope should be set to the sessionId the keys will be\n        // provided to.  When the keyType is kKeyType_Release, scope should be set to\n        // the keySetId of the keys being released.  Releasing keys from a device\n        // invalidates them for all sessions.\n        //\n        // The init data passed to getKeyRequest is container-specific and its\n        // meaning is interpreted based on the mime type provided in the mimeType\n        // parameter to getKeyRequest.  It could contain, for example, the content\n        // ID, key ID or other data obtained from the content metadata that is required\n        // in generating the key request.  Init may be null when keyType is\n        // kKeyType_Release.\n        //\n        // mimeType identifies the mime type of the content\n        //\n        // keyType specifies if the keys are to be used for streaming or offline content\n        //\n        // optionalParameters are included in the key request message to allow a\n        // client application to provide additional message parameters to the server.\n        //\n        // If successful, the opaque key request blob is returned to the caller.\n        virtual status_t\n            getKeyRequest(Vector<uint8_t> const &scope,\n                          Vector<uint8_t> const &initData,\n                          String8 const &mimeType, KeyType keyType,\n                          KeyedVector<String8, String8> const &optionalParameters,\n                          Vector<uint8_t> &request, String8 &defaultUrl,\n                          KeyRequestType *keyRequestType) = 0;\n\n        //\n        // After a key response is received by the app, it is provided to the\n        // Drm plugin using provideKeyResponse.\n        //\n        // scope may be a sessionId or a keySetId depending on the type of the\n        // response.  Scope should be set to the sessionId when the response is\n        // for either streaming or offline key requests.  Scope should be set to the\n        // keySetId when the response is for a release request.\n        //\n        // When the response is for an offline key request, a keySetId is returned\n        // in the keySetId vector parameter that can be used to later restore the\n        // keys to a new session with the method restoreKeys. When the response is\n        // for a streaming or release request, no keySetId is returned.\n        //\n        virtual status_t provideKeyResponse(Vector<uint8_t> const &scope,\n                                            Vector<uint8_t> const &response,\n                                            Vector<uint8_t> &keySetId) = 0;\n\n        // Remove the current keys from a session\n        virtual status_t removeKeys(Vector<uint8_t> const &sessionId) = 0;\n\n        // Restore persisted offline keys into a new session.  keySetId identifies\n        // the keys to load, obtained from a prior call to provideKeyResponse().\n        virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,\n                                     Vector<uint8_t> const &keySetId) = 0;\n\n        // Request an informative description of the license for the session.  The status\n        // is in the form of {name, value} pairs.  Since DRM license policies vary by\n        // vendor, the specific status field names are determined by each DRM vendor.\n        // Refer to your DRM provider documentation for definitions of the field names\n        // for a particular DrmEngine.\n        virtual status_t\n            queryKeyStatus(Vector<uint8_t> const &sessionId,\n                           KeyedVector<String8, String8> &infoMap) const = 0;\n\n        // A provision request/response exchange occurs between the app and a\n        // provisioning server to retrieve a device certificate.  getProvisionRequest\n        // is used to obtain an opaque key request blob that is delivered to the\n        // provisioning server.\n        //\n        // If successful, the opaque provision request blob is returned to the caller.\n        virtual status_t getProvisionRequest(String8 const &cert_type,\n                                             String8 const &cert_authority,\n                                             Vector<uint8_t> &request,\n                                             String8 &defaultUrl) = 0;\n\n        // After a provision response is received by the app, it is provided to the\n        // Drm plugin using provideProvisionResponse.\n        virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,\n                                                  Vector<uint8_t> &certificate,\n                                                  Vector<uint8_t> &wrapped_key) = 0;\n\n        // A means of enforcing the contractual requirement for a concurrent stream\n        // limit per subscriber across devices is provided via SecureStop.  SecureStop\n        // is a means of securely monitoring the lifetime of sessions. Since playback\n        // on a device can be interrupted due to reboot, power failure, etc. a means\n        // of persisting the lifetime information on the device is needed.\n        //\n        // A signed version of the sessionID is written to persistent storage on the\n        // device when each MediaCrypto object is created. The sessionID is signed by\n        // the device private key to prevent tampering.\n        //\n        // In the normal case, playback will be completed, the session destroyed and\n        // the Secure Stops will be queried. The App queries secure stops and forwards\n        // the secure stop message to the server which verifies the signature and\n        // notifies the server side database that the session destruction has been\n        // confirmed. The persisted record on the client is only removed after positive\n        // confirmation that the server received the message using releaseSecureStops().\n        virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0;\n        virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) = 0;\n        virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0;\n        virtual status_t releaseAllSecureStops() = 0;\n\n        // Read a property value given the device property string.  There are a few forms\n        // of property access methods, depending on the data type returned.\n        // Since DRM plugin properties may vary, additional field names may be defined\n        // by each DRM vendor.  Refer to your DRM provider documentation for definitions\n        // of its additional field names.\n        //\n        // Standard values are:\n        //   \"vendor\" [string] identifies the maker of the plugin\n        //   \"version\" [string] identifies the version of the plugin\n        //   \"description\" [string] describes the plugin\n        //   'deviceUniqueId' [byte array] The device unique identifier is established\n        //   during device provisioning and provides a means of uniquely identifying\n        //   each device.\n        virtual status_t getPropertyString(String8 const &name, String8 &value ) const = 0;\n        virtual status_t getPropertyByteArray(String8 const &name,\n                                              Vector<uint8_t> &value ) const = 0;\n\n        // Write  a property value given the device property string.  There are a few forms\n        // of property setting methods, depending on the data type.\n        // Since DRM plugin properties may vary, additional field names may be defined\n        // by each DRM vendor.  Refer to your DRM provider documentation for definitions\n        // of its field names.\n        virtual status_t setPropertyString(String8 const &name,\n                                           String8 const &value ) = 0;\n        virtual status_t setPropertyByteArray(String8 const &name,\n                                              Vector<uint8_t> const &value ) = 0;\n\n        // The following methods implement operations on a CryptoSession to support\n        // encrypt, decrypt, sign verify operations on operator-provided\n        // session keys.\n\n        //\n        // The algorithm string conforms to JCA Standard Names for Cipher\n        // Transforms and is case insensitive.  For example \"AES/CBC/PKCS5Padding\".\n        //\n        // Return OK if the algorithm is supported, otherwise return BAD_VALUE\n        //\n        virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,\n                                            String8 const &algorithm) = 0;\n\n        //\n        // The algorithm string conforms to JCA Standard Names for Mac\n        // Algorithms and is case insensitive.  For example \"HmacSHA256\".\n        //\n        // Return OK if the algorithm is supported, otherwise return BAD_VALUE\n        //\n        virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,\n                                         String8 const &algorithm) = 0;\n\n        // Encrypt the provided input buffer with the cipher algorithm\n        // specified by setCipherAlgorithm and the key selected by keyId,\n        // and return the encrypted data.\n        virtual status_t encrypt(Vector<uint8_t> const &sessionId,\n                                 Vector<uint8_t> const &keyId,\n                                 Vector<uint8_t> const &input,\n                                 Vector<uint8_t> const &iv,\n                                 Vector<uint8_t> &output) = 0;\n\n        // Decrypt the provided input buffer with the cipher algorithm\n        // specified by setCipherAlgorithm and the key selected by keyId,\n        // and return the decrypted data.\n        virtual status_t decrypt(Vector<uint8_t> const &sessionId,\n                                 Vector<uint8_t> const &keyId,\n                                 Vector<uint8_t> const &input,\n                                 Vector<uint8_t> const &iv,\n                                 Vector<uint8_t> &output) = 0;\n\n        // Compute a signature on the provided message using the mac algorithm\n        // specified by setMacAlgorithm and the key selected by keyId,\n        // and return the signature.\n        virtual status_t sign(Vector<uint8_t> const &sessionId,\n                              Vector<uint8_t> const &keyId,\n                              Vector<uint8_t> const &message,\n                              Vector<uint8_t> &signature) = 0;\n\n        // Compute a signature on the provided message using the mac algorithm\n        // specified by setMacAlgorithm and the key selected by keyId,\n        // and compare with the expected result.  Set result to true or\n        // false depending on the outcome.\n        virtual status_t verify(Vector<uint8_t> const &sessionId,\n                                Vector<uint8_t> const &keyId,\n                                Vector<uint8_t> const &message,\n                                Vector<uint8_t> const &signature,\n                                bool &match) = 0;\n\n\n        // Compute an RSA signature on the provided message using the algorithm\n        // specified by algorithm.\n        virtual status_t signRSA(Vector<uint8_t> const &sessionId,\n                                 String8 const &algorithm,\n                                 Vector<uint8_t> const &message,\n                                 Vector<uint8_t> const &wrapped_key,\n                                 Vector<uint8_t> &signature) = 0;\n\n\n        status_t setListener(const sp<DrmPluginListener>& listener) {\n            Mutex::Autolock lock(mEventLock);\n            mListener = listener;\n            return OK;\n        }\n\n    protected:\n        // Plugins call these methods to deliver events to the java app\n        void sendEvent(EventType eventType, int extra,\n                       Vector<uint8_t> const *sessionId,\n                       Vector<uint8_t> const *data);\n\n        void sendExpirationUpdate(Vector<uint8_t> const *sessionId,\n                                  int64_t expiryTimeInMS);\n\n        void sendKeysChange(Vector<uint8_t> const *sessionId,\n                            Vector<DrmPlugin::KeyStatus> const *keyStatusList,\n                            bool hasNewUsableKey);\n\n    private:\n        Mutex mEventLock;\n        sp<DrmPluginListener> mListener;\n\n        DISALLOW_EVIL_CONSTRUCTORS(DrmPlugin);\n    };\n\n    class DrmPluginListener: virtual public RefBase\n    {\n    public:\n        virtual void sendEvent(DrmPlugin::EventType eventType, int extra,\n                               Vector<uint8_t> const *sessionId,\n                               Vector<uint8_t> const *data) = 0;\n\n        virtual void sendExpirationUpdate(Vector<uint8_t> const *sessionId,\n                                          int64_t expiryTimeInMS) = 0;\n\n        virtual void sendKeysChange(Vector<uint8_t> const *sessionId,\n                                    Vector<DrmPlugin::KeyStatus> const *keyStatusList,\n                                    bool hasNewUsableKey) = 0;\n    };\n\n    inline void DrmPlugin::sendEvent(EventType eventType, int extra,\n                                     Vector<uint8_t> const *sessionId,\n                                     Vector<uint8_t> const *data) {\n        mEventLock.lock();\n        sp<DrmPluginListener> listener = mListener;\n        mEventLock.unlock();\n\n        if (listener != NULL) {\n            listener->sendEvent(eventType, extra, sessionId, data);\n        }\n    }\n\n    inline void DrmPlugin::sendExpirationUpdate(Vector<uint8_t> const *sessionId,\n                                                int64_t expiryTimeInMS) {\n        mEventLock.lock();\n        sp<DrmPluginListener> listener = mListener;\n        mEventLock.unlock();\n\n        if (listener != NULL) {\n            listener->sendExpirationUpdate(sessionId, expiryTimeInMS);\n        }\n    }\n\n    inline void DrmPlugin::sendKeysChange(Vector<uint8_t> const *sessionId,\n                                          Vector<DrmPlugin::KeyStatus> const *keyStatusList,\n                                          bool hasNewUsableKey) {\n        mEventLock.lock();\n        sp<DrmPluginListener> listener = mListener;\n        mEventLock.unlock();\n\n        if (listener != NULL) {\n            listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);\n        }\n    }\n}  // namespace android\n\n#endif // DRM_API_H_\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/editor/II420ColorConverter.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef II420_COLOR_CONVERTER_H\n\n#define II420_COLOR_CONVERTER_H\n\n#include <stdint.h>\n#include <android/rect.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef struct II420ColorConverter {\n\n    /*\n     * getDecoderOutputFormat\n     * Returns the color format (OMX_COLOR_FORMATTYPE) of the decoder output.\n     * If it is I420 (OMX_COLOR_FormatYUV420Planar), no conversion is needed,\n     * and convertDecoderOutputToI420() can be a no-op.\n     */\n    int (*getDecoderOutputFormat)();\n\n    /*\n     * convertDecoderOutputToI420\n     * @Desc     Converts from the decoder output format to I420 format.\n     * @note     Caller (e.g. VideoEditor) owns the buffers\n     * @param    decoderBits   (IN) Pointer to the buffer contains decoder output\n     * @param    decoderWidth  (IN) Buffer width, as reported by the decoder\n     *                              metadata (kKeyWidth)\n     * @param    decoderHeight (IN) Buffer height, as reported by the decoder\n     *                              metadata (kKeyHeight)\n     * @param    decoderRect   (IN) The rectangle of the actual frame, as\n     *                              reported by decoder metadata (kKeyCropRect)\n     * @param    dstBits      (OUT) Pointer to the output I420 buffer\n     * @return   -1 Any error\n     * @return   0  No Error\n     */\n    int (*convertDecoderOutputToI420)(\n        void* decoderBits, int decoderWidth, int decoderHeight,\n        ARect decoderRect, void* dstBits);\n\n    /*\n     * getEncoderIntputFormat\n     * Returns the color format (OMX_COLOR_FORMATTYPE) of the encoder input.\n     * If it is I420 (OMX_COLOR_FormatYUV420Planar), no conversion is needed,\n     * and convertI420ToEncoderInput() and getEncoderInputBufferInfo() can\n     * be no-ops.\n     */\n    int (*getEncoderInputFormat)();\n\n    /* convertI420ToEncoderInput\n     * @Desc     This function converts from I420 to the encoder input format\n     * @note     Caller (e.g. VideoEditor) owns the buffers\n     * @param    srcBits       (IN) Pointer to the input I420 buffer\n     * @param    srcWidth      (IN) Width of the I420 frame\n     * @param    srcHeight     (IN) Height of the I420 frame\n     * @param    encoderWidth  (IN) Encoder buffer width, as calculated by\n     *                              getEncoderBufferInfo()\n     * @param    encoderHeight (IN) Encoder buffer height, as calculated by\n     *                              getEncoderBufferInfo()\n     * @param    encoderRect   (IN) Rect coordinates of the actual frame inside\n     *                              the encoder buffer, as calculated by\n     *                              getEncoderBufferInfo().\n     * @param    encoderBits  (OUT) Pointer to the output buffer. The size of\n     *                              this buffer is calculated by\n     *                              getEncoderBufferInfo()\n     * @return   -1 Any error\n     * @return   0  No Error\n     */\n    int (*convertI420ToEncoderInput)(\n        void* srcBits, int srcWidth, int srcHeight,\n        int encoderWidth, int encoderHeight, ARect encoderRect,\n        void* encoderBits);\n\n    /* getEncoderInputBufferInfo\n     * @Desc     This function returns metadata for the encoder input buffer\n     *           based on the actual I420 frame width and height.\n     * @note     This API should be be used to obtain the necessary information\n     *           before calling convertI420ToEncoderInput().\n     *           VideoEditor knows only the width and height of the I420 buffer,\n     *           but it also needs know the width, height, and size of the\n     *           encoder input buffer. The encoder input buffer width and height\n     *           are used to set the metadata for the encoder.\n     * @param    srcWidth      (IN) Width of the I420 frame\n     * @param    srcHeight     (IN) Height of the I420 frame\n     * @param    encoderWidth  (OUT) Encoder buffer width needed\n     * @param    encoderHeight (OUT) Encoder buffer height needed\n     * @param    encoderRect   (OUT) Rect coordinates of the actual frame inside\n     *                               the encoder buffer\n     * @param    encoderBufferSize  (OUT) The size of the buffer that need to be\n     *                              allocated by the caller before invoking\n     *                              convertI420ToEncoderInput().\n     * @return   -1 Any error\n     * @return   0  No Error\n     */\n    int (*getEncoderInputBufferInfo)(\n        int srcWidth, int srcHeight,\n        int* encoderWidth, int* encoderHeight,\n        ARect* encoderRect, int* encoderBufferSize);\n\n} II420ColorConverter;\n\n/* The only function that the shared library needs to expose: It fills the\n   function pointers in II420ColorConverter */\nvoid getI420ColorConverter(II420ColorConverter *converter);\n\n#if defined(__cplusplus)\n}\n#endif\n\n#endif  // II420_COLOR_CONVERTER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/hardware/CryptoAPI.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <media/stagefright/MediaErrors.h>\n#include <utils/Errors.h>\n#include <utils/Vector.h>\n\n#ifndef CRYPTO_API_H_\n\n#define CRYPTO_API_H_\n\nnamespace android {\n\nstruct AString;\nstruct CryptoPlugin;\n\nstruct CryptoFactory {\n    CryptoFactory() {}\n    virtual ~CryptoFactory() {}\n\n    virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) const = 0;\n\n    virtual status_t createPlugin(\n            const uint8_t uuid[16], const void *data, size_t size,\n            CryptoPlugin **plugin) = 0;\n\nprivate:\n    CryptoFactory(const CryptoFactory &);\n    CryptoFactory &operator=(const CryptoFactory &);\n};\n\nstruct CryptoPlugin {\n    enum Mode {\n        kMode_Unencrypted = 0,\n        kMode_AES_CTR     = 1,\n        kMode_AES_WV      = 2,\n        kMode_AES_CBC     = 3,\n    };\n\n    struct SubSample {\n        uint32_t mNumBytesOfClearData;\n        uint32_t mNumBytesOfEncryptedData;\n    };\n\n    struct Pattern {\n        // Number of blocks to be encrypted in the pattern. If zero, pattern\n        // encryption is inoperative.\n        uint32_t mEncryptBlocks;\n\n        // Number of blocks to be skipped (left clear) in the pattern. If zero,\n        // pattern encryption is inoperative.\n        uint32_t mSkipBlocks;\n    };\n\n    CryptoPlugin() {}\n    virtual ~CryptoPlugin() {}\n\n    // If this method returns false, a non-secure decoder will be used to\n    // decode the data after decryption. The decrypt API below will have\n    // to support insecure decryption of the data (secure = false) for\n    // media data of the given mime type.\n    virtual bool requiresSecureDecoderComponent(const char *mime) const = 0;\n\n    // To implement resolution constraints, the crypto plugin needs to know\n    // the resolution of the video being decrypted.  The media player should\n    // call this method when the resolution is determined and any time it\n    // is subsequently changed.\n\n    virtual void notifyResolution(uint32_t /* width */, uint32_t /* height */) {}\n\n    // A MediaDrm session may be associated with a MediaCrypto session.  The\n    // associated MediaDrm session is used to load decryption keys\n    // into the crypto/drm plugin.  The keys are then referenced by key-id\n    // in the 'key' parameter to the decrypt() method.\n    // Should return NO_ERROR on success, ERROR_DRM_SESSION_NOT_OPENED if\n    // the session is not opened and a code from MediaErrors.h otherwise.\n    virtual status_t setMediaDrmSession(const Vector<uint8_t> & /*sessionId */) {\n        return ERROR_UNSUPPORTED;\n    }\n\n    // If the error returned falls into the range\n    // ERROR_DRM_VENDOR_MIN..ERROR_DRM_VENDOR_MAX, errorDetailMsg should be\n    // filled in with an appropriate string.\n    // At the java level these special errors will then trigger a\n    // MediaCodec.CryptoException that gives clients access to both\n    // the error code and the errorDetailMsg.\n    // Returns a non-negative result to indicate the number of bytes written\n    // to the dstPtr, or a negative result to indicate an error.\n    virtual ssize_t decrypt(\n            bool secure,\n            const uint8_t key[16],\n            const uint8_t iv[16],\n            Mode mode,\n            const Pattern &pattern,\n            const void *srcPtr,\n            const SubSample *subSamples, size_t numSubSamples,\n            void *dstPtr,\n            AString *errorDetailMsg) = 0;\n\nprivate:\n    CryptoPlugin(const CryptoPlugin &);\n    CryptoPlugin &operator=(const CryptoPlugin &);\n};\n\n}  // namespace android\n\nextern \"C\" {\n    extern android::CryptoFactory *createCryptoFactory();\n}\n\n#endif  // CRYPTO_API_H_\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/hardware/HDCPAPI.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef HDCP_API_H_\n\n#define HDCP_API_H_\n\n#include <utils/Errors.h>\n#include <system/window.h>\n\nnamespace android {\n\n// Two different kinds of modules are covered under the same HDCPModule\n// structure below, a module either implements decryption or encryption.\nstruct HDCPModule {\n    typedef void (*ObserverFunc)(void *cookie, int msg, int ext1, int ext2);\n\n    // The msg argument in calls to the observer notification function.\n    enum {\n        // Sent in response to a call to \"HDCPModule::initAsync\" once\n        // initialization has either been successfully completed,\n        // i.e. the HDCP session is now fully setup (AKE, Locality Check,\n        // SKE and any authentication with repeaters completed) or failed.\n        // ext1 should be a suitable error code (status_t), ext2 is\n        // unused for ENCRYPTION and in the case of HDCP_INITIALIZATION_COMPLETE\n        // holds the local TCP port the module is listening on.\n        HDCP_INITIALIZATION_COMPLETE,\n        HDCP_INITIALIZATION_FAILED,\n\n        // Sent upon completion of a call to \"HDCPModule::shutdownAsync\".\n        // ext1 should be a suitable error code, ext2 is unused.\n        HDCP_SHUTDOWN_COMPLETE,\n        HDCP_SHUTDOWN_FAILED,\n\n        HDCP_UNAUTHENTICATED_CONNECTION,\n        HDCP_UNAUTHORIZED_CONNECTION,\n        HDCP_REVOKED_CONNECTION,\n        HDCP_TOPOLOGY_EXECEEDED,\n        HDCP_UNKNOWN_ERROR,\n\n        // DECRYPTION only: Indicates that a client has successfully connected,\n        // a secure session established and the module is ready to accept\n        // future calls to \"decrypt\".\n        HDCP_SESSION_ESTABLISHED,\n    };\n\n    // HDCPModule capability bit masks\n    enum {\n        // HDCP_CAPS_ENCRYPT: mandatory, meaning the HDCP module can encrypt\n        // from an input byte-array buffer to an output byte-array buffer\n        HDCP_CAPS_ENCRYPT = (1 << 0),\n        // HDCP_CAPS_ENCRYPT_NATIVE: the HDCP module supports encryption from\n        // a native buffer to an output byte-array buffer. The format of the\n        // input native buffer is specific to vendor's encoder implementation.\n        // It is the same format as that used by the encoder when\n        // \"storeMetaDataInBuffers\" extension is enabled on its output port.\n        HDCP_CAPS_ENCRYPT_NATIVE = (1 << 1),\n    };\n\n    // Module can call the notification function to signal completion/failure\n    // of asynchronous operations (such as initialization) or out of band\n    // events.\n    HDCPModule(void *cookie, ObserverFunc observerNotify) {};\n\n    virtual ~HDCPModule() {};\n\n    // ENCRYPTION: Request to setup an HDCP session with the host specified\n    // by addr and listening on the specified port.\n    // DECRYPTION: Request to setup an HDCP session, addr is the interface\n    // address the module should bind its socket to. port will be 0.\n    // The module will pick the port to listen on itself and report its choice\n    // in the \"ext2\" argument of the HDCP_INITIALIZATION_COMPLETE callback.\n    virtual status_t initAsync(const char *addr, unsigned port) = 0;\n\n    // Request to shutdown the active HDCP session.\n    virtual status_t shutdownAsync() = 0;\n\n    // Returns the capability bitmask of this HDCP session.\n    virtual uint32_t getCaps() {\n        return HDCP_CAPS_ENCRYPT;\n    }\n\n    // ENCRYPTION only:\n    // Encrypt data according to the HDCP spec. \"size\" bytes of data are\n    // available at \"inData\" (virtual address), \"size\" may not be a multiple\n    // of 128 bits (16 bytes). An equal number of encrypted bytes should be\n    // written to the buffer at \"outData\" (virtual address).\n    // This operation is to be synchronous, i.e. this call does not return\n    // until outData contains size bytes of encrypted data.\n    // streamCTR will be assigned by the caller (to 0 for the first PES stream,\n    // 1 for the second and so on)\n    // inputCTR _will_be_maintained_by_the_callee_ for each PES stream.\n    virtual status_t encrypt(\n            const void *inData, size_t size, uint32_t streamCTR,\n            uint64_t *outInputCTR, void *outData) {\n        return INVALID_OPERATION;\n    }\n\n    // Encrypt data according to the HDCP spec. \"size\" bytes of data starting\n    // at location \"offset\" are available in \"buffer\" (buffer handle). \"size\"\n    // may not be a multiple of 128 bits (16 bytes). An equal number of\n    // encrypted bytes should be written to the buffer at \"outData\" (virtual\n    // address). This operation is to be synchronous, i.e. this call does not\n    // return until outData contains size bytes of encrypted data.\n    // streamCTR will be assigned by the caller (to 0 for the first PES stream,\n    // 1 for the second and so on)\n    // inputCTR _will_be_maintained_by_the_callee_ for each PES stream.\n    virtual status_t encryptNative(\n            buffer_handle_t buffer, size_t offset, size_t size,\n            uint32_t streamCTR, uint64_t *outInputCTR, void *outData) {\n        return INVALID_OPERATION;\n    }\n    // DECRYPTION only:\n    // Decrypt data according to the HDCP spec.\n    // \"size\" bytes of encrypted data are available at \"inData\"\n    // (virtual address), \"size\" may not be a multiple of 128 bits (16 bytes).\n    // An equal number of decrypted bytes should be written to the buffer\n    // at \"outData\" (virtual address).\n    // This operation is to be synchronous, i.e. this call does not return\n    // until outData contains size bytes of decrypted data.\n    // Both streamCTR and inputCTR will be provided by the caller.\n    virtual status_t decrypt(\n            const void *inData, size_t size,\n            uint32_t streamCTR, uint64_t inputCTR,\n            void *outData) {\n        return INVALID_OPERATION;\n    }\n\nprivate:\n    HDCPModule(const HDCPModule &);\n    HDCPModule &operator=(const HDCPModule &);\n};\n\n}  // namespace android\n\n// A shared library exporting the following methods should be included to\n// support HDCP functionality. The shared library must be called\n// \"libstagefright_hdcp.so\", it will be dynamically loaded into the\n// mediaserver process.\nextern \"C\" {\n    // Create a module for ENCRYPTION.\n    extern android::HDCPModule *createHDCPModule(\n            void *cookie, android::HDCPModule::ObserverFunc);\n\n    // Create a module for DECRYPTION.\n    extern android::HDCPModule *createHDCPModuleForDecryption(\n            void *cookie, android::HDCPModule::ObserverFunc);\n}\n\n#endif  // HDCP_API_H_\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/hardware/HardwareAPI.h",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef HARDWARE_API_H_\n\n#define HARDWARE_API_H_\n\n#include <media/hardware/OMXPluginBase.h>\n#include <media/hardware/MetadataBufferType.h>\n#include <system/window.h>\n#include <utils/RefBase.h>\n\n#include \"VideoAPI.h\"\n\n#include <OMX_Component.h>\n\nnamespace android {\n\n// This structure is used to enable Android native buffer use for either\n// graphic buffers or secure buffers.\n//\n// TO CONTROL ANDROID GRAPHIC BUFFER USAGE:\n//\n// A pointer to this struct is passed to the OMX_SetParameter when the extension\n// index for the 'OMX.google.android.index.enableAndroidNativeBuffers' extension\n// is given.\n//\n// When Android native buffer use is disabled for a port (the default state),\n// the OMX node should operate as normal, and expect UseBuffer calls to set its\n// buffers.  This is the mode that will be used when CPU access to the buffer is\n// required.\n//\n// When Android native buffer use has been enabled for a given port, the video\n// color format for the port is to be interpreted as an Android pixel format\n// rather than an OMX color format.  Enabling Android native buffers may also\n// change how the component receives the native buffers.  If store-metadata-mode\n// is enabled on the port, the component will receive the buffers as specified\n// in the section below. Otherwise, unless the node supports the\n// 'OMX.google.android.index.useAndroidNativeBuffer2' extension, it should\n// expect to receive UseAndroidNativeBuffer calls (via OMX_SetParameter) rather\n// than UseBuffer calls for that port.\n//\n// TO CONTROL ANDROID SECURE BUFFER USAGE:\n//\n// A pointer to this struct is passed to the OMX_SetParameter when the extension\n// index for the 'OMX.google.android.index.allocateNativeHandle' extension\n// is given.\n//\n// When native handle use is disabled for a port (the default state),\n// the OMX node should operate as normal, and expect AllocateBuffer calls to\n// return buffer pointers. This is the mode that will be used for non-secure\n// buffers if component requires allocate buffers instead of use buffers.\n//\n// When native handle use has been enabled for a given port, the component\n// shall allocate native_buffer_t objects containing  that can be passed between\n// processes using binder. This is the mode that will be used for secure buffers.\n// When an OMX component allocates native handle for buffers, it must close and\n// delete that handle when it frees those buffers. Even though pBuffer will point\n// to a native handle, nFilledLength, nAllocLength and nOffset will correspond\n// to the data inside the opaque buffer.\nstruct EnableAndroidNativeBuffersParams {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL enable;\n};\n\ntypedef struct EnableAndroidNativeBuffersParams AllocateNativeHandleParams;\n\n// A pointer to this struct is passed to OMX_SetParameter() when the extension index\n// \"OMX.google.android.index.storeMetaDataInBuffers\" or\n// \"OMX.google.android.index.storeANWBufferInMetadata\" is given.\n//\n// When meta data is stored in the video buffers passed between OMX clients\n// and OMX components, interpretation of the buffer data is up to the\n// buffer receiver, and the data may or may not be the actual video data, but\n// some information helpful for the receiver to locate the actual data.\n// The buffer receiver thus needs to know how to interpret what is stored\n// in these buffers, with mechanisms pre-determined externally. How to\n// interpret the meta data is outside of the scope of this parameter.\n//\n// Currently, this is used to pass meta data from video source (camera component, for instance) to\n// video encoder to avoid memcpying of input video frame data, as well as to pass dynamic output\n// buffer to video decoder. To do this, bStoreMetaData is set to OMX_TRUE.\n//\n// If bStoreMetaData is set to false, real YUV frame data will be stored in input buffers, and\n// the output buffers contain either real YUV frame data, or are themselves native handles as\n// directed by enable/use-android-native-buffer parameter settings.\n// In addition, if no OMX_SetParameter() call is made on a port with the corresponding extension\n// index, the component should not assume that the client is not using metadata mode for the port.\n//\n// If the component supports this using the \"OMX.google.android.index.storeANWBufferInMetadata\"\n// extension and bStoreMetaData is set to OMX_TRUE, data is passed using the VideoNativeMetadata\n// layout as defined below. Each buffer will be accompanied by a fence. The fence must signal\n// before the buffer can be used (e.g. read from or written into). When returning such buffer to\n// the client, component must provide a new fence that must signal before the returned buffer can\n// be used (e.g. read from or written into). The component owns the incoming fenceFd, and must close\n// it when fence has signaled. The client will own and close the returned fence file descriptor.\n//\n// If the component supports this using the \"OMX.google.android.index.storeMetaDataInBuffers\"\n// extension and bStoreMetaData is set to OMX_TRUE, data is passed using VideoGrallocMetadata\n// (the layout of which is the VideoGrallocMetadata defined below). Camera input can be also passed\n// as \"CameraSource\", the layout of which is vendor dependent.\n//\n// Metadata buffers are registered with the component using UseBuffer calls, or can be allocated\n// by the component for encoder-metadata-output buffers.\nstruct StoreMetaDataInBuffersParams {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL bStoreMetaData;\n};\n\n// Meta data buffer layout used to transport output frames to the decoder for\n// dynamic buffer handling.\nstruct VideoGrallocMetadata {\n    MetadataBufferType eType;               // must be kMetadataBufferTypeGrallocSource\n#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS\n    OMX_PTR pHandle;\n#else\n    buffer_handle_t pHandle;\n#endif\n};\n\n// Legacy name for VideoGrallocMetadata struct.\nstruct VideoDecoderOutputMetaData : public VideoGrallocMetadata {};\n\nstruct VideoNativeMetadata {\n    MetadataBufferType eType;               // must be kMetadataBufferTypeANWBuffer\n#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS\n    OMX_PTR pBuffer;\n#else\n    struct ANativeWindowBuffer* pBuffer;\n#endif\n    int nFenceFd;                           // -1 if unused\n};\n\n// Meta data buffer layout for passing a native_handle to codec\nstruct VideoNativeHandleMetadata {\n    MetadataBufferType eType;               // must be kMetadataBufferTypeNativeHandleSource\n\n#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS\n    OMX_PTR pHandle;\n#else\n    native_handle_t *pHandle;\n#endif\n};\n\n// A pointer to this struct is passed to OMX_SetParameter() when the extension\n// index \"OMX.google.android.index.prepareForAdaptivePlayback\" is given.\n//\n// This method is used to signal a video decoder, that the user has requested\n// seamless resolution change support (if bEnable is set to OMX_TRUE).\n// nMaxFrameWidth and nMaxFrameHeight are the dimensions of the largest\n// anticipated frames in the video.  If bEnable is OMX_FALSE, no resolution\n// change is expected, and the nMaxFrameWidth/Height fields are unused.\n//\n// If the decoder supports dynamic output buffers, it may ignore this\n// request.  Otherwise, it shall request resources in such a way so that it\n// avoids full port-reconfiguration (due to output port-definition change)\n// during resolution changes.\n//\n// DO NOT USE THIS STRUCTURE AS IT WILL BE REMOVED.  INSTEAD, IMPLEMENT\n// METADATA SUPPORT FOR VIDEO DECODERS.\nstruct PrepareForAdaptivePlaybackParams {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL bEnable;\n    OMX_U32 nMaxFrameWidth;\n    OMX_U32 nMaxFrameHeight;\n};\n\n// A pointer to this struct is passed to OMX_SetParameter when the extension\n// index for the 'OMX.google.android.index.useAndroidNativeBuffer' extension is\n// given.  This call will only be performed if a prior call was made with the\n// 'OMX.google.android.index.enableAndroidNativeBuffers' extension index,\n// enabling use of Android native buffers.\nstruct UseAndroidNativeBufferParams {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_PTR pAppPrivate;\n    OMX_BUFFERHEADERTYPE **bufferHeader;\n    const sp<ANativeWindowBuffer>& nativeBuffer;\n};\n\n// A pointer to this struct is passed to OMX_GetParameter when the extension\n// index for the 'OMX.google.android.index.getAndroidNativeBufferUsage'\n// extension is given.  The usage bits returned from this query will be used to\n// allocate the Gralloc buffers that get passed to the useAndroidNativeBuffer\n// command.\nstruct GetAndroidNativeBufferUsageParams {\n    OMX_U32 nSize;              // IN\n    OMX_VERSIONTYPE nVersion;   // IN\n    OMX_U32 nPortIndex;         // IN\n    OMX_U32 nUsage;             // OUT\n};\n\n// An enum OMX_COLOR_FormatAndroidOpaque to indicate an opaque colorformat\n// is declared in media/stagefright/openmax/OMX_IVCommon.h\n// This will inform the encoder that the actual\n// colorformat will be relayed by the GRalloc Buffers.\n// OMX_COLOR_FormatAndroidOpaque  = 0x7F000001,\n\n// A pointer to this struct is passed to OMX_SetParameter when the extension\n// index for the 'OMX.google.android.index.prependSPSPPSToIDRFrames' extension\n// is given.\n// A successful result indicates that future IDR frames will be prefixed by\n// SPS/PPS.\nstruct PrependSPSPPSToIDRFramesParams {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_BOOL bEnable;\n};\n\n// A pointer to this struct is passed to OMX_GetParameter when the extension\n// index for the 'OMX.google.android.index.describeColorFormat'\n// extension is given.  This method can be called from any component state\n// other than invalid.  The color-format, frame width/height, and stride/\n// slice-height parameters are ones that are associated with a raw video\n// port (input or output), but the stride/slice height parameters may be\n// incorrect. bUsingNativeBuffers is OMX_TRUE if native android buffers will\n// be used (while specifying this color format).\n//\n// The component shall fill out the MediaImage structure that\n// corresponds to the described raw video format, and the potentially corrected\n// stride and slice-height info.\n//\n// The behavior is slightly different if bUsingNativeBuffers is OMX_TRUE,\n// though most implementations can ignore this difference. When using native buffers,\n// the component may change the configured color format to an optimized format.\n// Additionally, when allocating these buffers for flexible usecase, the framework\n// will set the SW_READ/WRITE_OFTEN usage flags. In this case (if bUsingNativeBuffers\n// is OMX_TRUE), the component shall fill out the MediaImage information for the\n// scenario when these SW-readable/writable buffers are locked using gralloc_lock.\n// Note, that these buffers may also be locked using gralloc_lock_ycbcr, which must\n// be supported for vendor-specific formats.\n//\n// For non-YUV packed planar/semiplanar image formats, or if bUsingNativeBuffers\n// is OMX_TRUE and the component does not support this color format with native\n// buffers, the component shall set mNumPlanes to 0, and mType to MEDIA_IMAGE_TYPE_UNKNOWN.\n\n// @deprecated: use DescribeColorFormat2Params\nstruct DescribeColorFormat2Params;\nstruct DescribeColorFormatParams {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    // input: parameters from OMX_VIDEO_PORTDEFINITIONTYPE\n    OMX_COLOR_FORMATTYPE eColorFormat;\n    OMX_U32 nFrameWidth;\n    OMX_U32 nFrameHeight;\n    OMX_U32 nStride;\n    OMX_U32 nSliceHeight;\n    OMX_BOOL bUsingNativeBuffers;\n\n    // output: fill out the MediaImage fields\n    MediaImage sMediaImage;\n\n    DescribeColorFormatParams(const DescribeColorFormat2Params&); // for internal use only\n};\n\n// A pointer to this struct is passed to OMX_GetParameter when the extension\n// index for the 'OMX.google.android.index.describeColorFormat2'\n// extension is given. This is operationally the same as DescribeColorFormatParams\n// but can be used for HDR and RGBA/YUVA formats.\nstruct DescribeColorFormat2Params {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    // input: parameters from OMX_VIDEO_PORTDEFINITIONTYPE\n    OMX_COLOR_FORMATTYPE eColorFormat;\n    OMX_U32 nFrameWidth;\n    OMX_U32 nFrameHeight;\n    OMX_U32 nStride;\n    OMX_U32 nSliceHeight;\n    OMX_BOOL bUsingNativeBuffers;\n\n    // output: fill out the MediaImage2 fields\n    MediaImage2 sMediaImage;\n\n    void initFromV1(const DescribeColorFormatParams&); // for internal use only\n};\n\n// A pointer to this struct is passed to OMX_SetParameter or OMX_GetParameter\n// when the extension index for the\n// 'OMX.google.android.index.configureVideoTunnelMode' extension is  given.\n// If the extension is supported then tunneled playback mode should be supported\n// by the codec. If bTunneled is set to OMX_TRUE then the video decoder should\n// operate in \"tunneled\" mode and output its decoded frames directly to the\n// sink. In this case nAudioHwSync is the HW SYNC ID of the audio HAL Output\n// stream to sync the video with. If bTunneled is set to OMX_FALSE, \"tunneled\"\n// mode should be disabled and nAudioHwSync should be ignored.\n// OMX_GetParameter is used to query tunneling configuration. bTunneled should\n// return whether decoder is operating in tunneled mode, and if it is,\n// pSidebandWindow should contain the codec allocated sideband window handle.\nstruct ConfigureVideoTunnelModeParams {\n    OMX_U32 nSize;              // IN\n    OMX_VERSIONTYPE nVersion;   // IN\n    OMX_U32 nPortIndex;         // IN\n    OMX_BOOL bTunneled;         // IN/OUT\n    OMX_U32 nAudioHwSync;       // IN\n    OMX_PTR pSidebandWindow;    // OUT\n};\n\n// Color space description (aspects) parameters.\n// This is passed via OMX_SetConfig or OMX_GetConfig to video encoders and decoders when the\n// 'OMX.google.android.index.describeColorAspects' extension is given. Component SHALL behave\n// as described below if it supports this extension.\n//\n// bDataSpaceChanged and bRequestingDataSpace is assumed to be OMX_FALSE unless noted otherwise.\n//\n// VIDEO ENCODERS: the framework uses OMX_SetConfig to specify color aspects of the coded video.\n// This may happen:\n//   a) before the component transitions to idle state\n//   b) before the input frame is sent via OMX_EmptyThisBuffer in executing state\n//   c) during execution, just before an input frame with a different color aspect information\n//      is sent.\n//\n// The framework also uses OMX_GetConfig to\n//   d) verify the color aspects that will be written to the stream\n//   e) (optional) verify the color aspects that should be reported to the container for a\n//      given dataspace/pixelformat received\n//\n// 1. Encoders SHOULD maintain an internal color aspect state, initialized to Unspecified values.\n//    This represents the values that will be written into the bitstream.\n// 2. Upon OMX_SetConfig, they SHOULD update their internal state to the aspects received\n//    (including Unspecified values). For specific aspect values that are not supported by the\n//    codec standard, encoders SHOULD substitute Unspecified values; or they MAY use a suitable\n//    alternative (e.g. to suggest the use of BT.709 EOTF instead of SMPTE 240M.)\n// 3. OMX_GetConfig SHALL return the internal state (values that will be written).\n// 4. OMX_SetConfig SHALL always succeed before receiving the first frame. It MAY fail afterwards,\n//    but only if the configured values would change AND the component does not support updating the\n//    color information to those values mid-stream. If component supports updating a portion of\n//    the color information, those values should be updated in the internal state, and OMX_SetConfig\n//    SHALL succeed. Otherwise, the internal state SHALL remain intact and OMX_SetConfig SHALL fail\n//    with OMX_ErrorUnsupportedSettings.\n// 5. When the framework receives an input frame with an unexpected dataspace, it will query\n//    encoders for the color aspects that should be reported to the container using OMX_GetConfig\n//    with bDataSpaceChanged set to OMX_TRUE, and nPixelFormat/nDataSpace containing the new\n//    format/dataspace values. This allows vendors to use extended dataspace during capture and\n//    composition (e.g. screenrecord) - while performing color-space conversion inside the encoder -\n//    and encode and report a different color-space information in the bitstream/container.\n//    sColorAspects contains the requested color aspects by the client for reference, which may\n//    include aspects not supported by the encoding. This is used together with guidance for\n//    dataspace selection; see 6. below.\n//\n// VIDEO DECODERS: the framework uses OMX_SetConfig to specify the default color aspects to use\n// for the video.\n// This may happen:\n//   a) before the component transitions to idle state\n//   b) during execution, when the resolution or the default color aspects change.\n//\n// The framework also uses OMX_GetConfig to\n//   c) get the final color aspects reported by the coded bitstream after taking the default values\n//      into account.\n//\n// 1. Decoders should maintain two color aspect states - the default state as reported by the\n//    framework, and the coded state as reported by the bitstream - as each state can change\n//    independently from the other.\n// 2. Upon OMX_SetConfig, it SHALL update its default state regardless of whether such aspects\n//    could be supplied by the component bitstream. (E.g. it should blindly support all enumeration\n//    values, even unknown ones, and the Other value). This SHALL always succeed.\n// 3. Upon OMX_GetConfig, the component SHALL return the final color aspects by replacing\n//    Unspecified coded values with the default values. This SHALL always succeed.\n// 4. Whenever the component processes color aspect information in the bitstream even with an\n//    Unspecified value, it SHOULD update its internal coded state with that information just before\n//    the frame with the new information would be outputted, and the component SHALL signal an\n//    OMX_EventPortSettingsChanged event with data2 set to the extension index.\n// NOTE: Component SHOULD NOT signal a separate event purely for color aspect change, if it occurs\n//    together with a port definition (e.g. size) or crop change.\n// 5. If the aspects a component encounters in the bitstream cannot be represented with enumeration\n//    values as defined below, the component SHALL set those aspects to Other. Restricted values in\n//    the bitstream SHALL be treated as defined by the relevant bitstream specifications/standards,\n//    or as Unspecified, if not defined.\n//\n// BOTH DECODERS AND ENCODERS: the framework uses OMX_GetConfig during idle and executing state to\n//   f) (optional) get guidance for the dataspace to set for given color aspects, by setting\n//      bRequestingDataSpace to OMX_TRUE. The component SHALL return OMX_ErrorUnsupportedSettings\n//      IF it does not support this request.\n//\n// 6. This is an information request that can happen at any time, independent of the normal\n//    configuration process. This allows vendors to use extended dataspace during capture, playback\n//    and composition - while performing color-space conversion inside the component. Component\n//    SHALL set the desired dataspace into nDataSpace. Otherwise, it SHALL return\n//    OMX_ErrorUnsupportedSettings to let the framework choose a nearby standard dataspace.\n//\n// 6.a. For encoders, this query happens before the first frame is received using surface encoding.\n//    This allows the encoder to use a specific dataspace for the color aspects (e.g. because the\n//    device supports additional dataspaces, or because it wants to perform color-space extension\n//    to facilitate a more optimal rendering/capture pipeline.).\n//\n// 6.b. For decoders, this query happens before the first frame, and every time the color aspects\n//    change, while using surface buffers. This allows the decoder to use a specific dataspace for\n//    the color aspects (e.g. because the device supports additional dataspaces, or because it wants\n//    to perform color-space extension by inline color-space conversion to facilitate a more optimal\n//    rendering pipeline.).\n//\n// Note: the size of sAspects may increase in the future by additional fields.\n// Implementations SHOULD NOT require a certain size.\nstruct DescribeColorAspectsParams {\n    OMX_U32 nSize;                 // IN\n    OMX_VERSIONTYPE nVersion;      // IN\n    OMX_U32 nPortIndex;            // IN\n    OMX_BOOL bRequestingDataSpace; // IN\n    OMX_BOOL bDataSpaceChanged;    // IN\n    OMX_U32 nPixelFormat;          // IN\n    OMX_U32 nDataSpace;            // OUT\n    ColorAspects sAspects;         // IN/OUT\n};\n\n// HDR color description parameters.\n// This is passed via OMX_SetConfig or OMX_GetConfig to video encoders and decoders when the\n// 'OMX.google.android.index.describeHDRColorInfo' extension is given and an HDR stream\n// is detected.  Component SHALL behave as described below if it supports this extension.\n//\n// Currently, only Static Metadata Descriptor Type 1 support is required.\n//\n// VIDEO ENCODERS: the framework uses OMX_SetConfig to specify the HDR static information of the\n// coded video.\n// This may happen:\n//   a) before the component transitions to idle state\n//   b) before the input frame is sent via OMX_EmptyThisBuffer in executing state\n//   c) during execution, just before an input frame with a different HDR static\n//      information is sent.\n//\n// The framework also uses OMX_GetConfig to\n//   d) verify the HDR static information that will be written to the stream.\n//\n// 1. Encoders SHOULD maintain an internal HDR static info data, initialized to Unspecified values.\n//    This represents the values that will be written into the bitstream.\n// 2. Upon OMX_SetConfig, they SHOULD update their internal state to the info received\n//    (including Unspecified values). For specific parameters that are not supported by the\n//    codec standard, encoders SHOULD substitute Unspecified values. NOTE: no other substitution\n//    is allowed.\n// 3. OMX_GetConfig SHALL return the internal state (values that will be written).\n// 4. OMX_SetConfig SHALL always succeed before receiving the first frame if the encoder is\n//    configured into an HDR compatible profile. It MAY fail with OMX_ErrorUnsupportedSettings error\n//    code if it is not configured into such a profile, OR if the configured values would change\n//    AND the component does not support updating the HDR static information mid-stream. If the\n//    component supports updating a portion of the information, those values should be updated in\n//    the internal state, and OMX_SetConfig SHALL succeed. Otherwise, the internal state SHALL\n//    remain intact.\n//\n// VIDEO DECODERS: the framework uses OMX_SetConfig to specify the default HDR static information\n// to use for the video.\n//   a) This only happens if the client supplies this information, in which case it occurs before\n//      the component transitions to idle state.\n//   b) This may also happen subsequently if the default HDR static information changes.\n//\n// The framework also uses OMX_GetConfig to\n//   c) get the final HDR static information reported by the coded bitstream after taking the\n//      default values into account.\n//\n// 1. Decoders should maintain two HDR static information structures - the default values as\n//    reported by the framework, and the coded values as reported by the bitstream - as each\n//    structure can change independently from the other.\n// 2. Upon OMX_SetConfig, it SHALL update its default structure regardless of whether such static\n//    parameters could be supplied by the component bitstream. (E.g. it should blindly support all\n//    parameter values, even seemingly illegal ones). This SHALL always succeed.\n//  Note: The descriptor ID used in sInfo may change in subsequent calls. (although for now only\n//    Type 1 support is required.)\n// 3. Upon OMX_GetConfig, the component SHALL return the final HDR static information by replacing\n//    Unspecified coded values with the default values. This SHALL always succeed. This may be\n//    provided using any supported descriptor ID (currently only Type 1) with the goal of expressing\n//    the most of the available static information.\n// 4. Whenever the component processes HDR static information in the bitstream even ones with\n//    Unspecified parameters, it SHOULD update its internal coded structure with that information\n//    just before the frame with the new information would be outputted, and the component SHALL\n//    signal an OMX_EventPortSettingsChanged event with data2 set to the extension index.\n// NOTE: Component SHOULD NOT signal a separate event purely for HDR static info change, if it\n//    occurs together with a port definition (e.g. size), color aspect or crop change.\n// 5. If certain parameters of the HDR static information encountered in the bitstream cannot be\n//    represented using sInfo, the component SHALL use the closest representation.\n//\n// Note: the size of sInfo may increase in the future by supporting additional descriptor types.\n// Implementations SHOULD NOT require a certain size.\nstruct DescribeHDRStaticInfoParams {\n    OMX_U32 nSize;                 // IN\n    OMX_VERSIONTYPE nVersion;      // IN\n    OMX_U32 nPortIndex;            // IN\n    HDRStaticInfo sInfo;           // IN/OUT\n};\n\n}  // namespace android\n\nextern android::OMXPluginBase *createOMXPlugin();\n\n#endif  // HARDWARE_API_H_\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/hardware/MetadataBufferType.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef METADATA_BUFFER_TYPE_H\n#define METADATA_BUFFER_TYPE_H\n\n#ifdef __cplusplus\nextern \"C\" {\nnamespace android {\n#endif\n\n/*\n * MetadataBufferType defines the type of the metadata buffers that\n * can be passed to video encoder component for encoding, via Stagefright\n * media recording framework. To see how to work with the metadata buffers\n * in media recording framework, please consult HardwareAPI.h\n *\n * The creator of metadata buffers and video encoder share common knowledge\n * on what is actually being stored in these metadata buffers, and\n * how the information can be used by the video encoder component\n * to locate the actual pixel data as the source input for video\n * encoder, plus whatever other information that is necessary. Stagefright\n * media recording framework does not need to know anything specific about the\n * metadata buffers, except for receving each individual metadata buffer\n * as the source input, making a copy of the metadata buffer, and passing the\n * copy via OpenMAX API to the video encoder component.\n *\n * The creator of the metadata buffers must ensure that the first\n * 4 bytes in every metadata buffer indicates its buffer type,\n * and the rest of the metadata buffer contains the\n * actual metadata information. When a video encoder component receives\n * a metadata buffer, it uses the first 4 bytes in that buffer to find\n * out the type of the metadata buffer, and takes action appropriate\n * to that type of metadata buffers (for instance, locate the actual\n * pixel data input and then encoding the input data to produce a\n * compressed output buffer).\n *\n * The following shows the layout of a metadata buffer,\n * where buffer type is a 4-byte field of MetadataBufferType,\n * and the payload is the metadata information.\n *\n * --------------------------------------------------------------\n * |  buffer type  |          payload                           |\n * --------------------------------------------------------------\n *\n */\ntypedef enum {\n\n    /*\n     * kMetadataBufferTypeCameraSource is used to indicate that\n     * the source of the metadata buffer is the camera component.\n     */\n    kMetadataBufferTypeCameraSource  = 0,\n\n    /*\n     * kMetadataBufferTypeGrallocSource is used to indicate that\n     * the payload of the metadata buffers can be interpreted as\n     * a buffer_handle_t.\n     * So in this case,the metadata that the encoder receives\n     * will have a byte stream that consists of two parts:\n     * 1. First, there is an integer indicating that it is a GRAlloc\n     * source (kMetadataBufferTypeGrallocSource)\n     * 2. This is followed by the buffer_handle_t that is a handle to the\n     * GRalloc buffer. The encoder needs to interpret this GRalloc handle\n     * and encode the frames.\n     * --------------------------------------------------------------\n     * |  kMetadataBufferTypeGrallocSource | buffer_handle_t buffer |\n     * --------------------------------------------------------------\n     *\n     * See the VideoGrallocMetadata structure.\n     */\n    kMetadataBufferTypeGrallocSource = 1,\n\n    /*\n     * kMetadataBufferTypeGraphicBuffer is used to indicate that\n     * the payload of the metadata buffers can be interpreted as\n     * an ANativeWindowBuffer, and that a fence is provided.\n     *\n     * In this case, the metadata will have a byte stream that consists of three parts:\n     * 1. First, there is an integer indicating that the metadata\n     * contains an ANativeWindowBuffer (kMetadataBufferTypeANWBuffer)\n     * 2. This is followed by the pointer to the ANativeWindowBuffer.\n     * Codec must not free this buffer as it does not actually own this buffer.\n     * 3. Finally, there is an integer containing a fence file descriptor.\n     * The codec must wait on the fence before encoding or decoding into this\n     * buffer. When the buffer is returned, codec must replace this file descriptor\n     * with a new fence, that will be waited on before the buffer is replaced\n     * (encoder) or read (decoder).\n     * ---------------------------------\n     * |  kMetadataBufferTypeANWBuffer |\n     * ---------------------------------\n     * |  ANativeWindowBuffer *buffer  |\n     * ---------------------------------\n     * |  int fenceFd                  |\n     * ---------------------------------\n     *\n     * See the VideoNativeMetadata structure.\n     */\n    kMetadataBufferTypeANWBuffer = 2,\n\n    /*\n     * kMetadataBufferTypeNativeHandleSource is used to indicate that\n     * the payload of the metadata buffers can be interpreted as\n     * a native_handle_t.\n     *\n     * In this case, the metadata that the encoder receives\n     * will have a byte stream that consists of two parts:\n     * 1. First, there is an integer indicating that the metadata contains a\n     * native handle (kMetadataBufferTypeNativeHandleSource).\n     * 2. This is followed by a pointer to native_handle_t. The encoder needs\n     * to interpret this native handle and encode the frame. The encoder must\n     * not free this native handle as it does not actually own this native\n     * handle. The handle will be freed after the encoder releases the buffer\n     * back to camera.\n     * ----------------------------------------------------------------\n     * |  kMetadataBufferTypeNativeHandleSource | native_handle_t* nh |\n     * ----------------------------------------------------------------\n     *\n     * See the VideoNativeHandleMetadata structure.\n     */\n    kMetadataBufferTypeNativeHandleSource = 3,\n\n    /* This value is used by framework, but is never used inside a metadata buffer  */\n    kMetadataBufferTypeInvalid = -1,\n\n\n    // Add more here...\n\n} MetadataBufferType;\n\n#ifdef __cplusplus\n}  // namespace android\n}\n#endif\n\n#endif  // METADATA_BUFFER_TYPE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/hardware/OMXPluginBase.h",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef OMX_PLUGIN_BASE_H_\n\n#define OMX_PLUGIN_BASE_H_\n\n#include <sys/types.h>\n\n#include <OMX_Component.h>\n\n#include <utils/String8.h>\n#include <utils/Vector.h>\n\nnamespace android {\n\nstruct OMXPluginBase {\n    OMXPluginBase() {}\n    virtual ~OMXPluginBase() {}\n\n    virtual OMX_ERRORTYPE makeComponentInstance(\n            const char *name,\n            const OMX_CALLBACKTYPE *callbacks,\n            OMX_PTR appData,\n            OMX_COMPONENTTYPE **component) = 0;\n\n    virtual OMX_ERRORTYPE destroyComponentInstance(\n            OMX_COMPONENTTYPE *component) = 0;\n\n    virtual OMX_ERRORTYPE enumerateComponents(\n            OMX_STRING name,\n            size_t size,\n            OMX_U32 index) = 0;\n\n    virtual OMX_ERRORTYPE getRolesOfComponent(\n            const char *name,\n            Vector<String8> *roles) = 0;\n\nprivate:\n    OMXPluginBase(const OMXPluginBase &);\n    OMXPluginBase &operator=(const OMXPluginBase &);\n};\n\n}  // namespace android\n\n#endif  // OMX_PLUGIN_BASE_H_\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/hardware/VideoAPI.h",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef VIDEO_API_H_\n\n#define VIDEO_API_H_\n\nnamespace android {\n\n/**\n * Structure describing a media image (frame)\n * Currently only supporting YUV\n * @deprecated. Use MediaImage2 instead\n */\nstruct MediaImage {\n    enum Type {\n        MEDIA_IMAGE_TYPE_UNKNOWN = 0,\n        MEDIA_IMAGE_TYPE_YUV,\n    };\n\n    enum PlaneIndex {\n        Y = 0,\n        U,\n        V,\n        MAX_NUM_PLANES\n    };\n\n    Type mType;\n    uint32_t mNumPlanes;              // number of planes\n    uint32_t mWidth;                  // width of largest plane (unpadded, as in nFrameWidth)\n    uint32_t mHeight;                 // height of largest plane (unpadded, as in nFrameHeight)\n    uint32_t mBitDepth;               // useable bit depth\n    struct PlaneInfo {\n        uint32_t mOffset;             // offset of first pixel of the plane in bytes\n                                      // from buffer offset\n        uint32_t mColInc;             // column increment in bytes\n        uint32_t mRowInc;             // row increment in bytes\n        uint32_t mHorizSubsampling;   // subsampling compared to the largest plane\n        uint32_t mVertSubsampling;    // subsampling compared to the largest plane\n    };\n    PlaneInfo mPlane[MAX_NUM_PLANES];\n};\n\n/**\n * Structure describing a media image (frame)\n */\nstruct __attribute__ ((__packed__)) MediaImage2 {\n    enum Type : uint32_t {\n        MEDIA_IMAGE_TYPE_UNKNOWN = 0,\n        MEDIA_IMAGE_TYPE_YUV,\n        MEDIA_IMAGE_TYPE_YUVA,\n        MEDIA_IMAGE_TYPE_RGB,\n        MEDIA_IMAGE_TYPE_RGBA,\n        MEDIA_IMAGE_TYPE_Y,\n    };\n\n    enum PlaneIndex : uint32_t {\n        Y = 0,\n        U = 1,\n        V = 2,\n        R = 0,\n        G = 1,\n        B = 2,\n        A = 3,\n        MAX_NUM_PLANES = 4,\n    };\n\n    Type mType;\n    uint32_t mNumPlanes;              // number of planes\n    uint32_t mWidth;                  // width of largest plane (unpadded, as in nFrameWidth)\n    uint32_t mHeight;                 // height of largest plane (unpadded, as in nFrameHeight)\n    uint32_t mBitDepth;               // useable bit depth (always MSB)\n    uint32_t mBitDepthAllocated;      // bits per component (must be 8 or 16)\n\n    struct __attribute__ ((__packed__)) PlaneInfo {\n        uint32_t mOffset;             // offset of first pixel of the plane in bytes\n                                      // from buffer offset\n        int32_t mColInc;              // column increment in bytes\n        int32_t mRowInc;              // row increment in bytes\n        uint32_t mHorizSubsampling;   // subsampling compared to the largest plane\n        uint32_t mVertSubsampling;    // subsampling compared to the largest plane\n    };\n    PlaneInfo mPlane[MAX_NUM_PLANES];\n\n    void initFromV1(const MediaImage&); // for internal use only\n};\n\nstatic_assert(sizeof(MediaImage2::PlaneInfo) == 20, \"wrong struct size\");\nstatic_assert(sizeof(MediaImage2) == 104, \"wrong struct size\");\n\n/**\n * Aspects of color.\n */\n\n// NOTE: this structure is expected to grow in the future if new color aspects are\n// added to codec bitstreams. OMX component should not require a specific nSize\n// though could verify that nSize is at least the size of the structure at the\n// time of implementation. All new fields will be added at the end of the structure\n// ensuring backward compatibility.\nstruct __attribute__ ((__packed__)) ColorAspects {\n    // this is in sync with the range values in graphics.h\n    enum Range : uint32_t {\n        RangeUnspecified,\n        RangeFull,\n        RangeLimited,\n        RangeOther = 0xff,\n    };\n\n    enum Primaries : uint32_t {\n        PrimariesUnspecified,\n        PrimariesBT709_5,       // Rec.ITU-R BT.709-5 or equivalent\n        PrimariesBT470_6M,      // Rec.ITU-R BT.470-6 System M or equivalent\n        PrimariesBT601_6_625,   // Rec.ITU-R BT.601-6 625 or equivalent\n        PrimariesBT601_6_525,   // Rec.ITU-R BT.601-6 525 or equivalent\n        PrimariesGenericFilm,   // Generic Film\n        PrimariesBT2020,        // Rec.ITU-R BT.2020 or equivalent\n        PrimariesOther = 0xff,\n    };\n\n    // this partially in sync with the transfer values in graphics.h prior to the transfers\n    // unlikely to be required by Android section\n    enum Transfer : uint32_t {\n        TransferUnspecified,\n        TransferLinear,         // Linear transfer characteristics\n        TransferSRGB,           // sRGB or equivalent\n        TransferSMPTE170M,      // SMPTE 170M or equivalent (e.g. BT.601/709/2020)\n        TransferGamma22,        // Assumed display gamma 2.2\n        TransferGamma28,        // Assumed display gamma 2.8\n        TransferST2084,         // SMPTE ST 2084 for 10/12/14/16 bit systems\n        TransferHLG,            // ARIB STD-B67 hybrid-log-gamma\n\n        // transfers unlikely to be required by Android\n        TransferSMPTE240M = 0x40, // SMPTE 240M\n        TransferXvYCC,          // IEC 61966-2-4\n        TransferBT1361,         // Rec.ITU-R BT.1361 extended gamut\n        TransferST428,          // SMPTE ST 428-1\n        TransferOther = 0xff,\n    };\n\n    enum MatrixCoeffs : uint32_t {\n        MatrixUnspecified,\n        MatrixBT709_5,          // Rec.ITU-R BT.709-5 or equivalent\n        MatrixBT470_6M,         // KR=0.30, KB=0.11 or equivalent\n        MatrixBT601_6,          // Rec.ITU-R BT.601-6 625 or equivalent\n        MatrixSMPTE240M,        // SMPTE 240M or equivalent\n        MatrixBT2020,           // Rec.ITU-R BT.2020 non-constant luminance\n        MatrixBT2020Constant,   // Rec.ITU-R BT.2020 constant luminance\n        MatrixOther = 0xff,\n    };\n\n    // this is in sync with the standard values in graphics.h\n    enum Standard : uint32_t {\n        StandardUnspecified,\n        StandardBT709,                  // PrimariesBT709_5 and MatrixBT709_5\n        StandardBT601_625,              // PrimariesBT601_6_625 and MatrixBT601_6\n        StandardBT601_625_Unadjusted,   // PrimariesBT601_6_625 and KR=0.222, KB=0.071\n        StandardBT601_525,              // PrimariesBT601_6_525 and MatrixBT601_6\n        StandardBT601_525_Unadjusted,   // PrimariesBT601_6_525 and MatrixSMPTE240M\n        StandardBT2020,                 // PrimariesBT2020 and MatrixBT2020\n        StandardBT2020Constant,         // PrimariesBT2020 and MatrixBT2020Constant\n        StandardBT470M,                 // PrimariesBT470_6M and MatrixBT470_6M\n        StandardFilm,                   // PrimariesGenericFilm and KR=0.253, KB=0.068\n        StandardOther = 0xff,\n    };\n\n    Range mRange;                // IN/OUT\n    Primaries mPrimaries;        // IN/OUT\n    Transfer mTransfer;          // IN/OUT\n    MatrixCoeffs mMatrixCoeffs;  // IN/OUT\n};\n\nstatic_assert(sizeof(ColorAspects) == 16, \"wrong struct size\");\n\n/**\n * HDR Metadata.\n */\n\n// HDR Static Metadata Descriptor as defined by CTA-861-3.\nstruct __attribute__ ((__packed__)) HDRStaticInfo {\n    // Static_Metadata_Descriptor_ID\n    enum ID : uint8_t {\n        kType1 = 0, // Static Metadata Type 1\n    } mID;\n\n    struct __attribute__ ((__packed__)) Primaries1 {\n        // values are in units of 0.00002\n        uint16_t x;\n        uint16_t y;\n    };\n\n    // Static Metadata Descriptor Type 1\n    struct __attribute__ ((__packed__)) Type1 {\n        Primaries1 mR; // display primary 0\n        Primaries1 mG; // display primary 1\n        Primaries1 mB; // display primary 2\n        Primaries1 mW; // white point\n        uint16_t mMaxDisplayLuminance; // in cd/m^2\n        uint16_t mMinDisplayLuminance; // in 0.0001 cd/m^2\n        uint16_t mMaxContentLightLevel; // in cd/m^2\n        uint16_t mMaxFrameAverageLightLevel; // in cd/m^2\n    };\n\n    union {\n         Type1 sType1;\n    };\n};\n\nstatic_assert(sizeof(HDRStaticInfo::Primaries1) == 4, \"wrong struct size\");\nstatic_assert(sizeof(HDRStaticInfo::Type1) == 24, \"wrong struct size\");\nstatic_assert(sizeof(HDRStaticInfo) == 25, \"wrong struct size\");\n\n#ifdef STRINGIFY_ENUMS\n\ninline static const char *asString(MediaImage::Type i, const char *def = \"??\") {\n    switch (i) {\n        case MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN: return \"Unknown\";\n        case MediaImage::MEDIA_IMAGE_TYPE_YUV:     return \"YUV\";\n        default:                                   return def;\n    }\n}\n\ninline static const char *asString(MediaImage::PlaneIndex i, const char *def = \"??\") {\n    switch (i) {\n        case MediaImage::Y: return \"Y\";\n        case MediaImage::U: return \"U\";\n        case MediaImage::V: return \"V\";\n        default:            return def;\n    }\n}\n\ninline static const char *asString(MediaImage2::Type i, const char *def = \"??\") {\n    switch (i) {\n        case MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN: return \"Unknown\";\n        case MediaImage2::MEDIA_IMAGE_TYPE_YUV:     return \"YUV\";\n        case MediaImage2::MEDIA_IMAGE_TYPE_YUVA:    return \"YUVA\";\n        case MediaImage2::MEDIA_IMAGE_TYPE_RGB:     return \"RGB\";\n        case MediaImage2::MEDIA_IMAGE_TYPE_RGBA:    return \"RGBA\";\n        case MediaImage2::MEDIA_IMAGE_TYPE_Y:       return \"Y\";\n        default:                                    return def;\n    }\n}\n\ninline static char asChar2(\n        MediaImage2::PlaneIndex i, MediaImage2::Type j, char def = '?') {\n    const char *planes = asString(j, NULL);\n    // handle unknown values\n    if (j == MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN || planes == NULL || i >= strlen(planes)) {\n        return def;\n    }\n    return planes[i];\n}\n\ninline static const char *asString(ColorAspects::Range i, const char *def = \"??\") {\n    switch (i) {\n        case ColorAspects::RangeUnspecified: return \"Unspecified\";\n        case ColorAspects::RangeFull:        return \"Full\";\n        case ColorAspects::RangeLimited:     return \"Limited\";\n        case ColorAspects::RangeOther:       return \"Other\";\n        default:                             return def;\n    }\n}\n\ninline static const char *asString(ColorAspects::Primaries i, const char *def = \"??\") {\n    switch (i) {\n        case ColorAspects::PrimariesUnspecified: return \"Unspecified\";\n        case ColorAspects::PrimariesBT709_5:     return \"BT709_5\";\n        case ColorAspects::PrimariesBT470_6M:    return \"BT470_6M\";\n        case ColorAspects::PrimariesBT601_6_625: return \"BT601_6_625\";\n        case ColorAspects::PrimariesBT601_6_525: return \"BT601_6_525\";\n        case ColorAspects::PrimariesGenericFilm: return \"GenericFilm\";\n        case ColorAspects::PrimariesBT2020:      return \"BT2020\";\n        case ColorAspects::PrimariesOther:       return \"Other\";\n        default:                                 return def;\n    }\n}\n\ninline static const char *asString(ColorAspects::Transfer i, const char *def = \"??\") {\n    switch (i) {\n        case ColorAspects::TransferUnspecified: return \"Unspecified\";\n        case ColorAspects::TransferLinear:      return \"Linear\";\n        case ColorAspects::TransferSRGB:        return \"SRGB\";\n        case ColorAspects::TransferSMPTE170M:   return \"SMPTE170M\";\n        case ColorAspects::TransferGamma22:     return \"Gamma22\";\n        case ColorAspects::TransferGamma28:     return \"Gamma28\";\n        case ColorAspects::TransferST2084:      return \"ST2084\";\n        case ColorAspects::TransferHLG:         return \"HLG\";\n        case ColorAspects::TransferSMPTE240M:   return \"SMPTE240M\";\n        case ColorAspects::TransferXvYCC:       return \"XvYCC\";\n        case ColorAspects::TransferBT1361:      return \"BT1361\";\n        case ColorAspects::TransferST428:       return \"ST428\";\n        case ColorAspects::TransferOther:       return \"Other\";\n        default:                                return def;\n    }\n}\n\ninline static const char *asString(ColorAspects::MatrixCoeffs i, const char *def = \"??\") {\n    switch (i) {\n        case ColorAspects::MatrixUnspecified:    return \"Unspecified\";\n        case ColorAspects::MatrixBT709_5:        return \"BT709_5\";\n        case ColorAspects::MatrixBT470_6M:       return \"BT470_6M\";\n        case ColorAspects::MatrixBT601_6:        return \"BT601_6\";\n        case ColorAspects::MatrixSMPTE240M:      return \"SMPTE240M\";\n        case ColorAspects::MatrixBT2020:         return \"BT2020\";\n        case ColorAspects::MatrixBT2020Constant: return \"BT2020Constant\";\n        case ColorAspects::MatrixOther:          return \"Other\";\n        default:                                 return def;\n    }\n}\n\ninline static const char *asString(ColorAspects::Standard i, const char *def = \"??\") {\n    switch (i) {\n        case ColorAspects::StandardUnspecified:          return \"Unspecified\";\n        case ColorAspects::StandardBT709:                return \"BT709\";\n        case ColorAspects::StandardBT601_625:            return \"BT601_625\";\n        case ColorAspects::StandardBT601_625_Unadjusted: return \"BT601_625_Unadjusted\";\n        case ColorAspects::StandardBT601_525:            return \"BT601_525\";\n        case ColorAspects::StandardBT601_525_Unadjusted: return \"BT601_525_Unadjusted\";\n        case ColorAspects::StandardBT2020:               return \"BT2020\";\n        case ColorAspects::StandardBT2020Constant:       return \"BT2020Constant\";\n        case ColorAspects::StandardBT470M:               return \"BT470M\";\n        case ColorAspects::StandardFilm:                 return \"Film\";\n        case ColorAspects::StandardOther:                return \"Other\";\n        default:                                         return def;\n    }\n}\n\n#endif\n\n}  // namespace android\n\n#endif  // VIDEO_API_H_\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/openmax/OMX_AsString.h",
    "content": "/*\n * Copyright 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* NOTE: This file contains several sections for individual OMX include files.\n   Each section has its own include guard.  This file should be included AFTER\n   the OMX include files. */\n\n#ifdef ANDROID\nnamespace android {\n#endif\n\n#ifdef OMX_Audio_h\n/* asString definitions if media/openmax/OMX_Audio.h was included */\n\n#ifndef AS_STRING_FOR_OMX_AUDIO_H\n#define AS_STRING_FOR_OMX_AUDIO_H\n\ninline static const char *asString(OMX_AUDIO_CODINGTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_AUDIO_CodingUnused:     return \"Unused\";      // unused\n        case OMX_AUDIO_CodingAutoDetect: return \"AutoDetect\";  // unused\n        case OMX_AUDIO_CodingPCM:        return \"PCM\";\n        case OMX_AUDIO_CodingADPCM:      return \"ADPCM\";       // unused\n        case OMX_AUDIO_CodingAMR:        return \"AMR\";\n        case OMX_AUDIO_CodingGSMFR:      return \"GSMFR\";\n        case OMX_AUDIO_CodingGSMEFR:     return \"GSMEFR\";      // unused\n        case OMX_AUDIO_CodingGSMHR:      return \"GSMHR\";       // unused\n        case OMX_AUDIO_CodingPDCFR:      return \"PDCFR\";       // unused\n        case OMX_AUDIO_CodingPDCEFR:     return \"PDCEFR\";      // unused\n        case OMX_AUDIO_CodingPDCHR:      return \"PDCHR\";       // unused\n        case OMX_AUDIO_CodingTDMAFR:     return \"TDMAFR\";      // unused\n        case OMX_AUDIO_CodingTDMAEFR:    return \"TDMAEFR\";     // unused\n        case OMX_AUDIO_CodingQCELP8:     return \"QCELP8\";      // unused\n        case OMX_AUDIO_CodingQCELP13:    return \"QCELP13\";     // unused\n        case OMX_AUDIO_CodingEVRC:       return \"EVRC\";        // unused\n        case OMX_AUDIO_CodingSMV:        return \"SMV\";         // unused\n        case OMX_AUDIO_CodingG711:       return \"G711\";\n        case OMX_AUDIO_CodingG723:       return \"G723\";        // unused\n        case OMX_AUDIO_CodingG726:       return \"G726\";        // unused\n        case OMX_AUDIO_CodingG729:       return \"G729\";        // unused\n        case OMX_AUDIO_CodingAAC:        return \"AAC\";\n        case OMX_AUDIO_CodingMP3:        return \"MP3\";\n        case OMX_AUDIO_CodingSBC:        return \"SBC\";         // unused\n        case OMX_AUDIO_CodingVORBIS:     return \"VORBIS\";\n        case OMX_AUDIO_CodingWMA:        return \"WMA\";         // unused\n        case OMX_AUDIO_CodingRA:         return \"RA\";          // unused\n        case OMX_AUDIO_CodingMIDI:       return \"MIDI\";        // unused\n        case OMX_AUDIO_CodingFLAC:       return \"FLAC\";\n        default:                         return def;\n    }\n}\n\ninline static const char *asString(OMX_AUDIO_PCMMODETYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_AUDIO_PCMModeLinear: return \"Linear\";\n        case OMX_AUDIO_PCMModeALaw:   return \"ALaw\";\n        case OMX_AUDIO_PCMModeMULaw:  return \"MULaw\";\n        default:                      return def;\n    }\n}\n\ninline static const char *asString(OMX_AUDIO_CHANNELTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_AUDIO_ChannelNone: return \"None\";  // unused\n        case OMX_AUDIO_ChannelLF:   return \"LF\";\n        case OMX_AUDIO_ChannelRF:   return \"RF\";\n        case OMX_AUDIO_ChannelCF:   return \"CF\";\n        case OMX_AUDIO_ChannelLS:   return \"LS\";\n        case OMX_AUDIO_ChannelRS:   return \"RS\";\n        case OMX_AUDIO_ChannelLFE:  return \"LFE\";\n        case OMX_AUDIO_ChannelCS:   return \"CS\";\n        case OMX_AUDIO_ChannelLR:   return \"LR\";\n        case OMX_AUDIO_ChannelRR:   return \"RR\";\n        default:                    return def;\n    }\n}\n\ninline static const char *asString(OMX_AUDIO_CHANNELMODETYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_AUDIO_ChannelModeStereo:      return \"Stereo\";\n//      case OMX_AUDIO_ChannelModeJointStereo: return \"JointStereo\";\n//      case OMX_AUDIO_ChannelModeDual:        return \"Dual\";\n        case OMX_AUDIO_ChannelModeMono:        return \"Mono\";\n        default:                               return def;\n    }\n}\n\ninline static const char *asString(OMX_AUDIO_AACPROFILETYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_AUDIO_AACObjectNull:     return \"Null\";\n        case OMX_AUDIO_AACObjectMain:     return \"Main\";\n        case OMX_AUDIO_AACObjectLC:       return \"LC\";\n        case OMX_AUDIO_AACObjectSSR:      return \"SSR\";\n        case OMX_AUDIO_AACObjectLTP:      return \"LTP\";\n        case OMX_AUDIO_AACObjectHE:       return \"HE\";\n        case OMX_AUDIO_AACObjectScalable: return \"Scalable\";\n        case OMX_AUDIO_AACObjectERLC:     return \"ERLC\";\n        case OMX_AUDIO_AACObjectLD:       return \"LD\";\n        case OMX_AUDIO_AACObjectHE_PS:    return \"HE_PS\";\n        default:                          return def;\n    }\n}\n\ninline static const char *asString(OMX_AUDIO_AACSTREAMFORMATTYPE i, const char *def = \"??\") {\n    switch (i) {\n//      case OMX_AUDIO_AACStreamFormatMP2ADTS: return \"MP2ADTS\";\n        case OMX_AUDIO_AACStreamFormatMP4ADTS: return \"MP4ADTS\";\n//      case OMX_AUDIO_AACStreamFormatMP4LOAS: return \"MP4LOAS\";\n//      case OMX_AUDIO_AACStreamFormatMP4LATM: return \"MP4LATM\";\n//      case OMX_AUDIO_AACStreamFormatADIF:    return \"ADIF\";\n        case OMX_AUDIO_AACStreamFormatMP4FF:   return \"MP4FF\";\n//      case OMX_AUDIO_AACStreamFormatRAW:     return \"RAW\";\n        default:                               return def;\n    }\n}\n\ninline static const char *asString(OMX_AUDIO_AMRFRAMEFORMATTYPE i, const char *def = \"??\") {\n    switch (i) {\n//      case OMX_AUDIO_AMRFrameFormatConformance: return \"Conformance\";\n//      case OMX_AUDIO_AMRFrameFormatIF1:         return \"IF1\";\n//      case OMX_AUDIO_AMRFrameFormatIF2:         return \"IF2\";\n        case OMX_AUDIO_AMRFrameFormatFSF:         return \"FSF\";\n//      case OMX_AUDIO_AMRFrameFormatRTPPayload:  return \"RTPPayload\";\n//      case OMX_AUDIO_AMRFrameFormatITU:         return \"ITU\";\n        default:                                  return def;\n    }\n}\n\ninline static const char *asString(OMX_AUDIO_AMRBANDMODETYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_AUDIO_AMRBandModeUnused: return \"Unused\";\n        case OMX_AUDIO_AMRBandModeNB0:    return \"NB0\";\n        case OMX_AUDIO_AMRBandModeNB1:    return \"NB1\";\n        case OMX_AUDIO_AMRBandModeNB2:    return \"NB2\";\n        case OMX_AUDIO_AMRBandModeNB3:    return \"NB3\";\n        case OMX_AUDIO_AMRBandModeNB4:    return \"NB4\";\n        case OMX_AUDIO_AMRBandModeNB5:    return \"NB5\";\n        case OMX_AUDIO_AMRBandModeNB6:    return \"NB6\";\n        case OMX_AUDIO_AMRBandModeNB7:    return \"NB7\";\n        case OMX_AUDIO_AMRBandModeWB0:    return \"WB0\";\n        case OMX_AUDIO_AMRBandModeWB1:    return \"WB1\";\n        case OMX_AUDIO_AMRBandModeWB2:    return \"WB2\";\n        case OMX_AUDIO_AMRBandModeWB3:    return \"WB3\";\n        case OMX_AUDIO_AMRBandModeWB4:    return \"WB4\";\n        case OMX_AUDIO_AMRBandModeWB5:    return \"WB5\";\n        case OMX_AUDIO_AMRBandModeWB6:    return \"WB6\";\n        case OMX_AUDIO_AMRBandModeWB7:    return \"WB7\";\n        case OMX_AUDIO_AMRBandModeWB8:    return \"WB8\";\n        default:                          return def;\n    }\n}\n\ninline static const char *asString(OMX_AUDIO_AMRDTXMODETYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_AUDIO_AMRDTXModeOff:    return \"ModeOff\";\n//      case OMX_AUDIO_AMRDTXModeOnVAD1: return \"ModeOnVAD1\";\n//      case OMX_AUDIO_AMRDTXModeOnVAD2: return \"ModeOnVAD2\";\n//      case OMX_AUDIO_AMRDTXModeOnAuto: return \"ModeOnAuto\";\n//      case OMX_AUDIO_AMRDTXasEFR:      return \"asEFR\";\n        default:                         return def;\n    }\n}\n\n#endif // AS_STRING_FOR_OMX_AUDIO_H\n\n#endif // OMX_Audio_h\n\n#ifdef OMX_AudioExt_h\n/* asString definitions if media/openmax/OMX_AudioExt.h was included */\n\n#ifndef AS_STRING_FOR_OMX_AUDIOEXT_H\n#define AS_STRING_FOR_OMX_AUDIOEXT_H\n\ninline static const char *asString(OMX_AUDIO_CODINGEXTTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_AUDIO_CodingAndroidAC3:  return \"AndroidAC3\";\n        case OMX_AUDIO_CodingAndroidOPUS: return \"AndroidOPUS\";\n        default:                          return asString((OMX_AUDIO_CODINGTYPE)i, def);\n    }\n}\n\n#endif // AS_STRING_FOR_OMX_AUDIOEXT_H\n\n#endif // OMX_AudioExt_h\n\n#ifdef OMX_Component_h\n/* asString definitions if media/openmax/OMX_Component.h was included */\n\n#ifndef AS_STRING_FOR_OMX_COMPONENT_H\n#define AS_STRING_FOR_OMX_COMPONENT_H\n\ninline static const char *asString(OMX_PORTDOMAINTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_PortDomainAudio: return \"Audio\";\n        case OMX_PortDomainVideo: return \"Video\";\n        case OMX_PortDomainImage: return \"Image\";\n//      case OMX_PortDomainOther: return \"Other\";\n        default:                  return def;\n    }\n}\n\n#endif // AS_STRING_FOR_OMX_COMPONENT_H\n\n#endif // OMX_Component_h\n\n#ifdef OMX_Core_h\n/* asString definitions if media/openmax/OMX_Core.h was included */\n\n#ifndef AS_STRING_FOR_OMX_CORE_H\n#define AS_STRING_FOR_OMX_CORE_H\n\ninline static const char *asString(OMX_COMMANDTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_CommandStateSet:    return \"StateSet\";\n        case OMX_CommandFlush:       return \"Flush\";\n        case OMX_CommandPortDisable: return \"PortDisable\";\n        case OMX_CommandPortEnable:  return \"PortEnable\";\n//      case OMX_CommandMarkBuffer:  return \"MarkBuffer\";\n        default:                     return def;\n    }\n}\n\ninline static const char *asString(OMX_STATETYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_StateInvalid:          return \"Invalid\";\n        case OMX_StateLoaded:           return \"Loaded\";\n        case OMX_StateIdle:             return \"Idle\";\n        case OMX_StateExecuting:        return \"Executing\";\n//      case OMX_StatePause:            return \"Pause\";\n//      case OMX_StateWaitForResources: return \"WaitForResources\";\n        default:                        return def;\n    }\n}\n\ninline static const char *asString(OMX_ERRORTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_ErrorNone:                               return \"None\";\n        case OMX_ErrorInsufficientResources:              return \"InsufficientResources\";\n        case OMX_ErrorUndefined:                          return \"Undefined\";\n        case OMX_ErrorInvalidComponentName:               return \"InvalidComponentName\";\n        case OMX_ErrorComponentNotFound:                  return \"ComponentNotFound\";\n        case OMX_ErrorInvalidComponent:                   return \"InvalidComponent\";       // unused\n        case OMX_ErrorBadParameter:                       return \"BadParameter\";\n        case OMX_ErrorNotImplemented:                     return \"NotImplemented\";\n        case OMX_ErrorUnderflow:                          return \"Underflow\";              // unused\n        case OMX_ErrorOverflow:                           return \"Overflow\";               // unused\n        case OMX_ErrorHardware:                           return \"Hardware\";               // unused\n        case OMX_ErrorInvalidState:                       return \"InvalidState\";\n        case OMX_ErrorStreamCorrupt:                      return \"StreamCorrupt\";\n        case OMX_ErrorPortsNotCompatible:                 return \"PortsNotCompatible\";     // unused\n        case OMX_ErrorResourcesLost:                      return \"ResourcesLost\";\n        case OMX_ErrorNoMore:                             return \"NoMore\";\n        case OMX_ErrorVersionMismatch:                    return \"VersionMismatch\";        // unused\n        case OMX_ErrorNotReady:                           return \"NotReady\";               // unused\n        case OMX_ErrorTimeout:                            return \"Timeout\";                // unused\n        case OMX_ErrorSameState:                          return \"SameState\";              // unused\n        case OMX_ErrorResourcesPreempted:                 return \"ResourcesPreempted\";     // unused\n        case OMX_ErrorPortUnresponsiveDuringAllocation:\n            return \"PortUnresponsiveDuringAllocation\";    // unused\n        case OMX_ErrorPortUnresponsiveDuringDeallocation:\n            return \"PortUnresponsiveDuringDeallocation\";  // unused\n        case OMX_ErrorPortUnresponsiveDuringStop:\n            return \"PortUnresponsiveDuringStop\";          // unused\n        case OMX_ErrorIncorrectStateTransition:\n            return \"IncorrectStateTransition\";            // unused\n        case OMX_ErrorIncorrectStateOperation:\n            return \"IncorrectStateOperation\";             // unused\n        case OMX_ErrorUnsupportedSetting:                 return \"UnsupportedSetting\";\n        case OMX_ErrorUnsupportedIndex:                   return \"UnsupportedIndex\";\n        case OMX_ErrorBadPortIndex:                       return \"BadPortIndex\";\n        case OMX_ErrorPortUnpopulated:                    return \"PortUnpopulated\";        // unused\n        case OMX_ErrorComponentSuspended:                 return \"ComponentSuspended\";     // unused\n        case OMX_ErrorDynamicResourcesUnavailable:\n            return \"DynamicResourcesUnavailable\";         // unused\n        case OMX_ErrorMbErrorsInFrame:                    return \"MbErrorsInFrame\";        // unused\n        case OMX_ErrorFormatNotDetected:                  return \"FormatNotDetected\";      // unused\n        case OMX_ErrorContentPipeOpenFailed:              return \"ContentPipeOpenFailed\";  // unused\n        case OMX_ErrorContentPipeCreationFailed:\n            return \"ContentPipeCreationFailed\";           // unused\n        case OMX_ErrorSeperateTablesUsed:                 return \"SeperateTablesUsed\";     // unused\n        case OMX_ErrorTunnelingUnsupported:               return \"TunnelingUnsupported\";   // unused\n        default:                                          return def;\n    }\n}\n\ninline static const char *asString(OMX_EVENTTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_EventCmdComplete:               return \"CmdComplete\";\n        case OMX_EventError:                     return \"Error\";\n//      case OMX_EventMark:                      return \"Mark\";\n        case OMX_EventPortSettingsChanged:       return \"PortSettingsChanged\";\n        case OMX_EventBufferFlag:                return \"BufferFlag\";\n//      case OMX_EventResourcesAcquired:         return \"ResourcesAcquired\";\n//      case OMX_EventComponentResumed:          return \"ComponentResumed\";\n//      case OMX_EventDynamicResourcesAvailable: return \"DynamicResourcesAvailable\";\n//      case OMX_EventPortFormatDetected:        return \"PortFormatDetected\";\n        case OMX_EventOutputRendered:            return \"OutputRendered\";\n        case OMX_EventDataSpaceChanged:          return \"DataSpaceChanged\";\n        default:                                 return def;\n    }\n}\n\n#endif // AS_STRING_FOR_OMX_CORE_H\n\n#endif // OMX_Core_h\n\n#ifdef OMX_Image_h\n/* asString definitions if media/openmax/OMX_Image.h was included */\n\n#ifndef AS_STRING_FOR_OMX_IMAGE_H\n#define AS_STRING_FOR_OMX_IMAGE_H\n\ninline static const char *asString(OMX_IMAGE_CODINGTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_IMAGE_CodingUnused:     return \"Unused\";\n        case OMX_IMAGE_CodingAutoDetect: return \"AutoDetect\";  // unused\n        case OMX_IMAGE_CodingJPEG:       return \"JPEG\";\n        case OMX_IMAGE_CodingJPEG2K:     return \"JPEG2K\";      // unused\n        case OMX_IMAGE_CodingEXIF:       return \"EXIF\";        // unused\n        case OMX_IMAGE_CodingTIFF:       return \"TIFF\";        // unused\n        case OMX_IMAGE_CodingGIF:        return \"GIF\";         // unused\n        case OMX_IMAGE_CodingPNG:        return \"PNG\";         // unused\n        case OMX_IMAGE_CodingLZW:        return \"LZW\";         // unused\n        case OMX_IMAGE_CodingBMP:        return \"BMP\";         // unused\n        default:                         return def;\n    }\n}\n\n#endif // AS_STRING_FOR_OMX_IMAGE_H\n\n#endif // OMX_Image_h\n\n#ifdef OMX_Index_h\n/* asString definitions if media/openmax/OMX_Index.h was included */\n\n#ifndef AS_STRING_FOR_OMX_INDEX_H\n#define AS_STRING_FOR_OMX_INDEX_H\n\ninline static const char *asString(OMX_INDEXTYPE i, const char *def = \"??\") {\n    switch (i) {\n//      case OMX_IndexParamPriorityMgmt:                    return \"ParamPriorityMgmt\";\n//      case OMX_IndexParamAudioInit:                       return \"ParamAudioInit\";\n//      case OMX_IndexParamImageInit:                       return \"ParamImageInit\";\n//      case OMX_IndexParamVideoInit:                       return \"ParamVideoInit\";\n//      case OMX_IndexParamOtherInit:                       return \"ParamOtherInit\";\n//      case OMX_IndexParamNumAvailableStreams:             return \"ParamNumAvailableStreams\";\n//      case OMX_IndexParamActiveStream:                    return \"ParamActiveStream\";\n//      case OMX_IndexParamSuspensionPolicy:                return \"ParamSuspensionPolicy\";\n//      case OMX_IndexParamComponentSuspended:              return \"ParamComponentSuspended\";\n//      case OMX_IndexConfigCapturing:                      return \"ConfigCapturing\";\n//      case OMX_IndexConfigCaptureMode:                    return \"ConfigCaptureMode\";\n//      case OMX_IndexAutoPauseAfterCapture:                return \"AutoPauseAfterCapture\";\n//      case OMX_IndexParamContentURI:                      return \"ParamContentURI\";\n//      case OMX_IndexParamCustomContentPipe:               return \"ParamCustomContentPipe\";\n//      case OMX_IndexParamDisableResourceConcealment:\n//          return \"ParamDisableResourceConcealment\";\n//      case OMX_IndexConfigMetadataItemCount:              return \"ConfigMetadataItemCount\";\n//      case OMX_IndexConfigContainerNodeCount:             return \"ConfigContainerNodeCount\";\n//      case OMX_IndexConfigMetadataItem:                   return \"ConfigMetadataItem\";\n//      case OMX_IndexConfigCounterNodeID:                  return \"ConfigCounterNodeID\";\n//      case OMX_IndexParamMetadataFilterType:              return \"ParamMetadataFilterType\";\n//      case OMX_IndexParamMetadataKeyFilter:               return \"ParamMetadataKeyFilter\";\n//      case OMX_IndexConfigPriorityMgmt:                   return \"ConfigPriorityMgmt\";\n        case OMX_IndexParamStandardComponentRole:           return \"ParamStandardComponentRole\";\n        case OMX_IndexParamPortDefinition:                  return \"ParamPortDefinition\";\n//      case OMX_IndexParamCompBufferSupplier:              return \"ParamCompBufferSupplier\";\n        case OMX_IndexParamAudioPortFormat:                 return \"ParamAudioPortFormat\";\n        case OMX_IndexParamAudioPcm:                        return \"ParamAudioPcm\";\n        case OMX_IndexParamAudioAac:                        return \"ParamAudioAac\";\n//      case OMX_IndexParamAudioRa:                         return \"ParamAudioRa\";\n        case OMX_IndexParamAudioMp3:                        return \"ParamAudioMp3\";\n//      case OMX_IndexParamAudioAdpcm:                      return \"ParamAudioAdpcm\";\n//      case OMX_IndexParamAudioG723:                       return \"ParamAudioG723\";\n//      case OMX_IndexParamAudioG729:                       return \"ParamAudioG729\";\n        case OMX_IndexParamAudioAmr:                        return \"ParamAudioAmr\";\n//      case OMX_IndexParamAudioWma:                        return \"ParamAudioWma\";\n//      case OMX_IndexParamAudioSbc:                        return \"ParamAudioSbc\";\n//      case OMX_IndexParamAudioMidi:                       return \"ParamAudioMidi\";\n//      case OMX_IndexParamAudioGsm_FR:                     return \"ParamAudioGsm_FR\";\n//      case OMX_IndexParamAudioMidiLoadUserSound:          return \"ParamAudioMidiLoadUserSound\";\n//      case OMX_IndexParamAudioG726:                       return \"ParamAudioG726\";\n//      case OMX_IndexParamAudioGsm_EFR:                    return \"ParamAudioGsm_EFR\";\n//      case OMX_IndexParamAudioGsm_HR:                     return \"ParamAudioGsm_HR\";\n//      case OMX_IndexParamAudioPdc_FR:                     return \"ParamAudioPdc_FR\";\n//      case OMX_IndexParamAudioPdc_EFR:                    return \"ParamAudioPdc_EFR\";\n//      case OMX_IndexParamAudioPdc_HR:                     return \"ParamAudioPdc_HR\";\n//      case OMX_IndexParamAudioTdma_FR:                    return \"ParamAudioTdma_FR\";\n//      case OMX_IndexParamAudioTdma_EFR:                   return \"ParamAudioTdma_EFR\";\n//      case OMX_IndexParamAudioQcelp8:                     return \"ParamAudioQcelp8\";\n//      case OMX_IndexParamAudioQcelp13:                    return \"ParamAudioQcelp13\";\n//      case OMX_IndexParamAudioEvrc:                       return \"ParamAudioEvrc\";\n//      case OMX_IndexParamAudioSmv:                        return \"ParamAudioSmv\";\n        case OMX_IndexParamAudioVorbis:                     return \"ParamAudioVorbis\";\n        case OMX_IndexParamAudioFlac:                       return \"ParamAudioFlac\";\n//      case OMX_IndexConfigAudioMidiImmediateEvent:        return \"ConfigAudioMidiImmediateEvent\";\n//      case OMX_IndexConfigAudioMidiControl:               return \"ConfigAudioMidiControl\";\n//      case OMX_IndexConfigAudioMidiSoundBankProgram:\n//          return \"ConfigAudioMidiSoundBankProgram\";\n//      case OMX_IndexConfigAudioMidiStatus:                return \"ConfigAudioMidiStatus\";\n//      case OMX_IndexConfigAudioMidiMetaEvent:             return \"ConfigAudioMidiMetaEvent\";\n//      case OMX_IndexConfigAudioMidiMetaEventData:         return \"ConfigAudioMidiMetaEventData\";\n//      case OMX_IndexConfigAudioVolume:                    return \"ConfigAudioVolume\";\n//      case OMX_IndexConfigAudioBalance:                   return \"ConfigAudioBalance\";\n//      case OMX_IndexConfigAudioChannelMute:               return \"ConfigAudioChannelMute\";\n//      case OMX_IndexConfigAudioMute:                      return \"ConfigAudioMute\";\n//      case OMX_IndexConfigAudioLoudness:                  return \"ConfigAudioLoudness\";\n//      case OMX_IndexConfigAudioEchoCancelation:           return \"ConfigAudioEchoCancelation\";\n//      case OMX_IndexConfigAudioNoiseReduction:            return \"ConfigAudioNoiseReduction\";\n//      case OMX_IndexConfigAudioBass:                      return \"ConfigAudioBass\";\n//      case OMX_IndexConfigAudioTreble:                    return \"ConfigAudioTreble\";\n//      case OMX_IndexConfigAudioStereoWidening:            return \"ConfigAudioStereoWidening\";\n//      case OMX_IndexConfigAudioChorus:                    return \"ConfigAudioChorus\";\n//      case OMX_IndexConfigAudioEqualizer:                 return \"ConfigAudioEqualizer\";\n//      case OMX_IndexConfigAudioReverberation:             return \"ConfigAudioReverberation\";\n//      case OMX_IndexConfigAudioChannelVolume:             return \"ConfigAudioChannelVolume\";\n//      case OMX_IndexParamImagePortFormat:                 return \"ParamImagePortFormat\";\n//      case OMX_IndexParamFlashControl:                    return \"ParamFlashControl\";\n//      case OMX_IndexConfigFocusControl:                   return \"ConfigFocusControl\";\n//      case OMX_IndexParamQFactor:                         return \"ParamQFactor\";\n//      case OMX_IndexParamQuantizationTable:               return \"ParamQuantizationTable\";\n//      case OMX_IndexParamHuffmanTable:                    return \"ParamHuffmanTable\";\n//      case OMX_IndexConfigFlashControl:                   return \"ConfigFlashControl\";\n        case OMX_IndexParamVideoPortFormat:                 return \"ParamVideoPortFormat\";\n//      case OMX_IndexParamVideoQuantization:               return \"ParamVideoQuantization\";\n//      case OMX_IndexParamVideoFastUpdate:                 return \"ParamVideoFastUpdate\";\n        case OMX_IndexParamVideoBitrate:                    return \"ParamVideoBitrate\";\n//      case OMX_IndexParamVideoMotionVector:               return \"ParamVideoMotionVector\";\n        case OMX_IndexParamVideoIntraRefresh:               return \"ParamVideoIntraRefresh\";\n        case OMX_IndexParamVideoErrorCorrection:            return \"ParamVideoErrorCorrection\";\n//      case OMX_IndexParamVideoVBSMC:                      return \"ParamVideoVBSMC\";\n//      case OMX_IndexParamVideoMpeg2:                      return \"ParamVideoMpeg2\";\n        case OMX_IndexParamVideoMpeg4:                      return \"ParamVideoMpeg4\";\n//      case OMX_IndexParamVideoWmv:                        return \"ParamVideoWmv\";\n//      case OMX_IndexParamVideoRv:                         return \"ParamVideoRv\";\n        case OMX_IndexParamVideoAvc:                        return \"ParamVideoAvc\";\n        case OMX_IndexParamVideoH263:                       return \"ParamVideoH263\";\n        case OMX_IndexParamVideoProfileLevelQuerySupported:\n            return \"ParamVideoProfileLevelQuerySupported\";\n        case OMX_IndexParamVideoProfileLevelCurrent:        return \"ParamVideoProfileLevelCurrent\";\n        case OMX_IndexConfigVideoBitrate:                   return \"ConfigVideoBitrate\";\n//      case OMX_IndexConfigVideoFramerate:                 return \"ConfigVideoFramerate\";\n        case OMX_IndexConfigVideoIntraVOPRefresh:           return \"ConfigVideoIntraVOPRefresh\";\n//      case OMX_IndexConfigVideoIntraMBRefresh:            return \"ConfigVideoIntraMBRefresh\";\n//      case OMX_IndexConfigVideoMBErrorReporting:          return \"ConfigVideoMBErrorReporting\";\n//      case OMX_IndexParamVideoMacroblocksPerFrame:        return \"ParamVideoMacroblocksPerFrame\";\n//      case OMX_IndexConfigVideoMacroBlockErrorMap:        return \"ConfigVideoMacroBlockErrorMap\";\n//      case OMX_IndexParamVideoSliceFMO:                   return \"ParamVideoSliceFMO\";\n//      case OMX_IndexConfigVideoAVCIntraPeriod:            return \"ConfigVideoAVCIntraPeriod\";\n//      case OMX_IndexConfigVideoNalSize:                   return \"ConfigVideoNalSize\";\n//      case OMX_IndexParamCommonDeblocking:                return \"ParamCommonDeblocking\";\n//      case OMX_IndexParamCommonSensorMode:                return \"ParamCommonSensorMode\";\n//      case OMX_IndexParamCommonInterleave:                return \"ParamCommonInterleave\";\n//      case OMX_IndexConfigCommonColorFormatConversion:\n//          return \"ConfigCommonColorFormatConversion\";\n        case OMX_IndexConfigCommonScale:                    return \"ConfigCommonScale\";\n//      case OMX_IndexConfigCommonImageFilter:              return \"ConfigCommonImageFilter\";\n//      case OMX_IndexConfigCommonColorEnhancement:         return \"ConfigCommonColorEnhancement\";\n//      case OMX_IndexConfigCommonColorKey:                 return \"ConfigCommonColorKey\";\n//      case OMX_IndexConfigCommonColorBlend:               return \"ConfigCommonColorBlend\";\n//      case OMX_IndexConfigCommonFrameStabilisation:       return \"ConfigCommonFrameStabilisation\";\n//      case OMX_IndexConfigCommonRotate:                   return \"ConfigCommonRotate\";\n//      case OMX_IndexConfigCommonMirror:                   return \"ConfigCommonMirror\";\n//      case OMX_IndexConfigCommonOutputPosition:           return \"ConfigCommonOutputPosition\";\n        case OMX_IndexConfigCommonInputCrop:                return \"ConfigCommonInputCrop\";\n        case OMX_IndexConfigCommonOutputCrop:               return \"ConfigCommonOutputCrop\";\n//      case OMX_IndexConfigCommonDigitalZoom:              return \"ConfigCommonDigitalZoom\";\n//      case OMX_IndexConfigCommonOpticalZoom:              return \"ConfigCommonOpticalZoom\";\n//      case OMX_IndexConfigCommonWhiteBalance:             return \"ConfigCommonWhiteBalance\";\n//      case OMX_IndexConfigCommonExposure:                 return \"ConfigCommonExposure\";\n//      case OMX_IndexConfigCommonContrast:                 return \"ConfigCommonContrast\";\n//      case OMX_IndexConfigCommonBrightness:               return \"ConfigCommonBrightness\";\n//      case OMX_IndexConfigCommonBacklight:                return \"ConfigCommonBacklight\";\n//      case OMX_IndexConfigCommonGamma:                    return \"ConfigCommonGamma\";\n//      case OMX_IndexConfigCommonSaturation:               return \"ConfigCommonSaturation\";\n//      case OMX_IndexConfigCommonLightness:                return \"ConfigCommonLightness\";\n//      case OMX_IndexConfigCommonExclusionRect:            return \"ConfigCommonExclusionRect\";\n//      case OMX_IndexConfigCommonDithering:                return \"ConfigCommonDithering\";\n//      case OMX_IndexConfigCommonPlaneBlend:               return \"ConfigCommonPlaneBlend\";\n//      case OMX_IndexConfigCommonExposureValue:            return \"ConfigCommonExposureValue\";\n//      case OMX_IndexConfigCommonOutputSize:               return \"ConfigCommonOutputSize\";\n//      case OMX_IndexParamCommonExtraQuantData:            return \"ParamCommonExtraQuantData\";\n//      case OMX_IndexConfigCommonFocusRegion:              return \"ConfigCommonFocusRegion\";\n//      case OMX_IndexConfigCommonFocusStatus:              return \"ConfigCommonFocusStatus\";\n//      case OMX_IndexConfigCommonTransitionEffect:         return \"ConfigCommonTransitionEffect\";\n//      case OMX_IndexParamOtherPortFormat:                 return \"ParamOtherPortFormat\";\n//      case OMX_IndexConfigOtherPower:                     return \"ConfigOtherPower\";\n//      case OMX_IndexConfigOtherStats:                     return \"ConfigOtherStats\";\n//      case OMX_IndexConfigTimeScale:                      return \"ConfigTimeScale\";\n//      case OMX_IndexConfigTimeClockState:                 return \"ConfigTimeClockState\";\n//      case OMX_IndexConfigTimeActiveRefClock:             return \"ConfigTimeActiveRefClock\";\n//      case OMX_IndexConfigTimeCurrentMediaTime:           return \"ConfigTimeCurrentMediaTime\";\n//      case OMX_IndexConfigTimeCurrentWallTime:            return \"ConfigTimeCurrentWallTime\";\n//      case OMX_IndexConfigTimeCurrentAudioReference:\n//          return \"ConfigTimeCurrentAudioReference\";\n//      case OMX_IndexConfigTimeCurrentVideoReference:\n//          return \"ConfigTimeCurrentVideoReference\";\n//      case OMX_IndexConfigTimeMediaTimeRequest:           return \"ConfigTimeMediaTimeRequest\";\n//      case OMX_IndexConfigTimeClientStartTime:            return \"ConfigTimeClientStartTime\";\n//      case OMX_IndexConfigTimePosition:                   return \"ConfigTimePosition\";\n//      case OMX_IndexConfigTimeSeekMode:                   return \"ConfigTimeSeekMode\";\n        default:                                            return def;\n    }\n}\n\n#endif // AS_STRING_FOR_OMX_INDEX_H\n\n#endif // OMX_Index_h\n\n#ifdef OMX_IndexExt_h\n/* asString definitions if media/openmax/OMX_IndexExt.h was included */\n\n#ifndef AS_STRING_FOR_OMX_INDEXEXT_H\n#define AS_STRING_FOR_OMX_INDEXEXT_H\n\ninline static const char *asString(OMX_INDEXEXTTYPE i, const char *def = \"??\") {\n    switch (i) {\n//      case OMX_IndexConfigCallbackRequest:            return \"ConfigCallbackRequest\";\n//      case OMX_IndexConfigCommitMode:                 return \"ConfigCommitMode\";\n//      case OMX_IndexConfigCommit:                     return \"ConfigCommit\";\n        case OMX_IndexParamAudioAndroidAc3:             return \"ParamAudioAndroidAc3\";\n        case OMX_IndexParamAudioAndroidOpus:            return \"ParamAudioAndroidOpus\";\n        case OMX_IndexParamAudioAndroidAacPresentation: return \"ParamAudioAndroidAacPresentation\";\n//      case OMX_IndexParamNalStreamFormatSupported:    return \"ParamNalStreamFormatSupported\";\n//      case OMX_IndexParamNalStreamFormat:             return \"ParamNalStreamFormat\";\n//      case OMX_IndexParamNalStreamFormatSelect:       return \"ParamNalStreamFormatSelect\";\n        case OMX_IndexParamVideoVp8:                    return \"ParamVideoVp8\";\n//      case OMX_IndexConfigVideoVp8ReferenceFrame:     return \"ConfigVideoVp8ReferenceFrame\";\n//      case OMX_IndexConfigVideoVp8ReferenceFrameType: return \"ConfigVideoVp8ReferenceFrameType\";\n        case OMX_IndexParamVideoAndroidVp8Encoder:      return \"ParamVideoAndroidVp8Encoder\";\n        case OMX_IndexParamVideoHevc:                   return \"ParamVideoHevc\";\n//      case OMX_IndexParamSliceSegments:               return \"ParamSliceSegments\";\n        case OMX_IndexConfigAndroidIntraRefresh:        return \"ConfigAndroidIntraRefresh\";\n        case OMX_IndexConfigAutoFramerateConversion:    return \"ConfigAutoFramerateConversion\";\n        case OMX_IndexConfigPriority:                   return \"ConfigPriority\";\n        case OMX_IndexConfigOperatingRate:              return \"ConfigOperatingRate\";\n        case OMX_IndexParamConsumerUsageBits:           return \"ParamConsumerUsageBits\";\n        default:                                        return asString((OMX_INDEXTYPE)i, def);\n    }\n}\n\n#endif // AS_STRING_FOR_OMX_INDEXEXT_H\n\n#endif // OMX_IndexExt_h\n\n#ifdef OMX_IVCommon_h\n/* asString definitions if media/openmax/OMX_IVCommon.h was included */\n\n#ifndef AS_STRING_FOR_OMX_IVCOMMON_H\n#define AS_STRING_FOR_OMX_IVCOMMON_H\n\ninline static const char *asString(OMX_COLOR_FORMATTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_COLOR_FormatUnused:\n            return \"COLOR_FormatUnused\";\n        case OMX_COLOR_FormatMonochrome:\n            return \"COLOR_FormatMonochrome\";\n        case OMX_COLOR_Format8bitRGB332:\n            return \"COLOR_Format8bitRGB332\";\n        case OMX_COLOR_Format12bitRGB444:\n            return \"COLOR_Format12bitRGB444\";\n        case OMX_COLOR_Format16bitARGB4444:\n            return \"COLOR_Format16bitARGB4444\";\n        case OMX_COLOR_Format16bitARGB1555:\n            return \"COLOR_Format16bitARGB1555\";\n        case OMX_COLOR_Format16bitRGB565:\n            return \"COLOR_Format16bitRGB565\";\n        case OMX_COLOR_Format16bitBGR565:\n            return \"COLOR_Format16bitBGR565\";\n        case OMX_COLOR_Format18bitRGB666:\n            return \"COLOR_Format18bitRGB666\";\n        case OMX_COLOR_Format18bitARGB1665:\n            return \"COLOR_Format18bitARGB1665\";\n        case OMX_COLOR_Format19bitARGB1666:\n            return \"COLOR_Format19bitARGB1666\";\n        case OMX_COLOR_Format24bitRGB888:\n            return \"COLOR_Format24bitRGB888\";\n        case OMX_COLOR_Format24bitBGR888:\n            return \"COLOR_Format24bitBGR888\";\n        case OMX_COLOR_Format24bitARGB1887:\n            return \"COLOR_Format24bitARGB1887\";\n        case OMX_COLOR_Format25bitARGB1888:\n            return \"COLOR_Format25bitARGB1888\";\n        case OMX_COLOR_Format32bitBGRA8888:\n            return \"COLOR_Format32bitBGRA8888\";\n        case OMX_COLOR_Format32bitARGB8888:\n            return \"COLOR_Format32bitARGB8888\";\n        case OMX_COLOR_FormatYUV411Planar:\n            return \"COLOR_FormatYUV411Planar\";\n        case OMX_COLOR_FormatYUV411PackedPlanar:\n            return \"COLOR_FormatYUV411PackedPlanar\";\n        case OMX_COLOR_FormatYUV420Planar:\n            return \"COLOR_FormatYUV420Planar\";\n        case OMX_COLOR_FormatYUV420PackedPlanar:\n            return \"COLOR_FormatYUV420PackedPlanar\";\n        case OMX_COLOR_FormatYUV420SemiPlanar:\n            return \"COLOR_FormatYUV420SemiPlanar\";\n        case OMX_COLOR_FormatYUV422Planar:\n            return \"COLOR_FormatYUV422Planar\";\n        case OMX_COLOR_FormatYUV422PackedPlanar:\n            return \"COLOR_FormatYUV422PackedPlanar\";\n        case OMX_COLOR_FormatYUV422SemiPlanar:\n            return \"COLOR_FormatYUV422SemiPlanar\";\n        case OMX_COLOR_FormatYCbYCr:\n            return \"COLOR_FormatYCbYCr\";\n        case OMX_COLOR_FormatYCrYCb:\n            return \"COLOR_FormatYCrYCb\";\n        case OMX_COLOR_FormatCbYCrY:\n            return \"COLOR_FormatCbYCrY\";\n        case OMX_COLOR_FormatCrYCbY:\n            return \"COLOR_FormatCrYCbY\";\n        case OMX_COLOR_FormatYUV444Interleaved:\n            return \"COLOR_FormatYUV444Interleaved\";\n        case OMX_COLOR_FormatRawBayer8bit:\n            return \"COLOR_FormatRawBayer8bit\";\n        case OMX_COLOR_FormatRawBayer10bit:\n            return \"COLOR_FormatRawBayer10bit\";\n        case OMX_COLOR_FormatRawBayer8bitcompressed:\n            return \"COLOR_FormatRawBayer8bitcompressed\";\n        case OMX_COLOR_FormatL2:\n            return \"COLOR_FormatL2\";\n        case OMX_COLOR_FormatL4:\n            return \"COLOR_FormatL4\";\n        case OMX_COLOR_FormatL8:\n            return \"COLOR_FormatL8\";\n        case OMX_COLOR_FormatL16:\n            return \"COLOR_FormatL16\";\n        case OMX_COLOR_FormatL24:\n            return \"COLOR_FormatL24\";\n        case OMX_COLOR_FormatL32:\n            return \"COLOR_FormatL32\";\n        case OMX_COLOR_FormatYUV420PackedSemiPlanar:\n            return \"COLOR_FormatYUV420PackedSemiPlanar\";\n        case OMX_COLOR_FormatYUV422PackedSemiPlanar:\n            return \"COLOR_FormatYUV422PackedSemiPlanar\";\n        case OMX_COLOR_Format18BitBGR666:\n            return \"COLOR_Format18BitBGR666\";\n        case OMX_COLOR_Format24BitARGB6666:\n            return \"COLOR_Format24BitARGB6666\";\n        case OMX_COLOR_Format24BitABGR6666:\n            return \"COLOR_Format24BitABGR6666\";\n        case OMX_COLOR_FormatAndroidOpaque:\n            return \"COLOR_FormatAndroidOpaque\";\n        case OMX_COLOR_FormatYUV420Flexible:\n            return \"COLOR_FormatYUV420Flexible\";\n        case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:\n            return \"TI_COLOR_FormatYUV420PackedSemiPlanar\";\n        case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:\n            return \"QCOM_COLOR_FormatYVU420SemiPlanar\";\n//      case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka:\n//          return \"QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka\";\n//      case OMX_SEC_COLOR_FormatNV12Tiled:\n//          return \"SEC_COLOR_FormatNV12Tiled\";\n//      case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m:\n//          return \"QCOM_COLOR_FormatYUV420PackedSemiPlanar32m\";\n        default:\n            return def;\n    }\n}\n\n#endif // AS_STRING_FOR_OMX_IVCOMMON_H\n\n#endif // OMX_IVCommon_h\n\n#ifdef OMX_Types_h\n/* asString definitions if media/openmax/OMX_Types.h was included */\n\n#ifndef AS_STRING_FOR_OMX_TYPES_H\n#define AS_STRING_FOR_OMX_TYPES_H\n\ninline static const char *asString(OMX_BOOL i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_FALSE: return \"FALSE\";\n        case OMX_TRUE:  return \"TRUE\";\n        default:        return def;\n    }\n}\n\ninline static const char *asString(OMX_DIRTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_DirInput:  return \"Input\";\n        case OMX_DirOutput: return \"Output\";\n        default:            return def;\n    }\n}\n\ninline static const char *asString(OMX_ENDIANTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_EndianBig:    return \"Big\";\n//      case OMX_EndianLittle: return \"Little\";\n        default:               return def;\n    }\n}\n\ninline static const char *asString(OMX_NUMERICALDATATYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_NumericalDataSigned:   return \"Signed\";\n//      case OMX_NumericalDataUnsigned: return \"Unsigned\";\n        default:                        return def;\n    }\n}\n\n#endif // AS_STRING_FOR_OMX_TYPES_H\n\n#endif // OMX_Types_h\n\n#ifdef OMX_Video_h\n/* asString definitions if media/openmax/OMX_Video.h was included */\n\n#ifndef AS_STRING_FOR_OMX_VIDEO_H\n#define AS_STRING_FOR_OMX_VIDEO_H\n\ninline static const char *asString(OMX_VIDEO_CODINGTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_CodingUnused:     return \"Unused\";\n        case OMX_VIDEO_CodingAutoDetect: return \"AutoDetect\";  // unused\n        case OMX_VIDEO_CodingMPEG2:      return \"MPEG2\";\n        case OMX_VIDEO_CodingH263:       return \"H263\";\n        case OMX_VIDEO_CodingMPEG4:      return \"MPEG4\";\n        case OMX_VIDEO_CodingWMV:        return \"WMV\";         // unused\n        case OMX_VIDEO_CodingRV:         return \"RV\";          // unused\n        case OMX_VIDEO_CodingAVC:        return \"AVC\";\n        case OMX_VIDEO_CodingMJPEG:      return \"MJPEG\";       // unused\n        case OMX_VIDEO_CodingVP8:        return \"VP8\";\n        case OMX_VIDEO_CodingVP9:        return \"VP9\";\n        case OMX_VIDEO_CodingHEVC:       return \"HEVC\";\n        case OMX_VIDEO_CodingDolbyVision:return \"DolbyVision\";\n        default:                         return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_CONTROLRATETYPE i, const char *def = \"??\") {\n    switch (i) {\n//      case OMX_Video_ControlRateDisable:            return \"Disable\";\n        case OMX_Video_ControlRateVariable:           return \"Variable\";\n        case OMX_Video_ControlRateConstant:           return \"Constant\";\n//      case OMX_Video_ControlRateVariableSkipFrames: return \"VariableSkipFrames\";\n//      case OMX_Video_ControlRateConstantSkipFrames: return \"ConstantSkipFrames\";\n        default:                                      return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_INTRAREFRESHTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_IntraRefreshCyclic:   return \"Cyclic\";\n        case OMX_VIDEO_IntraRefreshAdaptive: return \"Adaptive\";\n        case OMX_VIDEO_IntraRefreshBoth:     return \"Both\";\n        default:                             return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_H263PROFILETYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_H263ProfileBaseline:           return \"Baseline\";\n        case OMX_VIDEO_H263ProfileH320Coding:         return \"H320Coding\";\n        case OMX_VIDEO_H263ProfileBackwardCompatible: return \"BackwardCompatible\";\n        case OMX_VIDEO_H263ProfileISWV2:              return \"ISWV2\";\n        case OMX_VIDEO_H263ProfileISWV3:              return \"ISWV3\";\n        case OMX_VIDEO_H263ProfileHighCompression:    return \"HighCompression\";\n        case OMX_VIDEO_H263ProfileInternet:           return \"Internet\";\n        case OMX_VIDEO_H263ProfileInterlace:          return \"Interlace\";\n        case OMX_VIDEO_H263ProfileHighLatency:        return \"HighLatency\";\n        default:                                      return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_H263LEVELTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_H263Level10: return \"Level10\";\n        case OMX_VIDEO_H263Level20: return \"Level20\";\n        case OMX_VIDEO_H263Level30: return \"Level30\";\n        case OMX_VIDEO_H263Level40: return \"Level40\";\n        case OMX_VIDEO_H263Level45: return \"Level45\";\n        case OMX_VIDEO_H263Level50: return \"Level50\";\n        case OMX_VIDEO_H263Level60: return \"Level60\";\n        case OMX_VIDEO_H263Level70: return \"Level70\";\n        default:                    return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_PICTURETYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_PictureTypeI:  return \"I\";\n        case OMX_VIDEO_PictureTypeP:  return \"P\";\n        case OMX_VIDEO_PictureTypeB:  return \"B\";\n//      case OMX_VIDEO_PictureTypeSI: return \"SI\";\n//      case OMX_VIDEO_PictureTypeSP: return \"SP\";\n//      case OMX_VIDEO_PictureTypeEI: return \"EI\";\n//      case OMX_VIDEO_PictureTypeEP: return \"EP\";\n//      case OMX_VIDEO_PictureTypeS:  return \"S\";\n        default:                      return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_MPEG4PROFILETYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_MPEG4ProfileSimple:           return \"Simple\";\n        case OMX_VIDEO_MPEG4ProfileSimpleScalable:   return \"SimpleScalable\";\n        case OMX_VIDEO_MPEG4ProfileCore:             return \"Core\";\n        case OMX_VIDEO_MPEG4ProfileMain:             return \"Main\";\n        case OMX_VIDEO_MPEG4ProfileNbit:             return \"Nbit\";\n        case OMX_VIDEO_MPEG4ProfileScalableTexture:  return \"ScalableTexture\";\n        case OMX_VIDEO_MPEG4ProfileSimpleFace:       return \"SimpleFace\";\n        case OMX_VIDEO_MPEG4ProfileSimpleFBA:        return \"SimpleFBA\";\n        case OMX_VIDEO_MPEG4ProfileBasicAnimated:    return \"BasicAnimated\";\n        case OMX_VIDEO_MPEG4ProfileHybrid:           return \"Hybrid\";\n        case OMX_VIDEO_MPEG4ProfileAdvancedRealTime: return \"AdvancedRealTime\";\n        case OMX_VIDEO_MPEG4ProfileCoreScalable:     return \"CoreScalable\";\n        case OMX_VIDEO_MPEG4ProfileAdvancedCoding:   return \"AdvancedCoding\";\n        case OMX_VIDEO_MPEG4ProfileAdvancedCore:     return \"AdvancedCore\";\n        case OMX_VIDEO_MPEG4ProfileAdvancedScalable: return \"AdvancedScalable\";\n        case OMX_VIDEO_MPEG4ProfileAdvancedSimple:   return \"AdvancedSimple\";\n        default:                                     return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_MPEG4LEVELTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_MPEG4Level0:  return \"Level0\";\n        case OMX_VIDEO_MPEG4Level0b: return \"Level0b\";\n        case OMX_VIDEO_MPEG4Level1:  return \"Level1\";\n        case OMX_VIDEO_MPEG4Level2:  return \"Level2\";\n        case OMX_VIDEO_MPEG4Level3:  return \"Level3\";\n        case OMX_VIDEO_MPEG4Level3b: return \"Level3b\";\n        case OMX_VIDEO_MPEG4Level4:  return \"Level4\";\n        case OMX_VIDEO_MPEG4Level4a: return \"Level4a\";\n        case OMX_VIDEO_MPEG4Level5:  return \"Level5\";\n        case OMX_VIDEO_MPEG4Level6:  return \"Level6\";\n        default:                     return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_MPEG2PROFILETYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_MPEG2ProfileSimple:  return \"Simple\";\n        case OMX_VIDEO_MPEG2ProfileMain:    return \"Main\";\n        case OMX_VIDEO_MPEG2Profile422:     return \"4:2:2\";\n        case OMX_VIDEO_MPEG2ProfileSNR:     return \"SNR\";\n        case OMX_VIDEO_MPEG2ProfileSpatial: return \"Spatial\";\n        case OMX_VIDEO_MPEG2ProfileHigh:    return \"High\";\n        default:                            return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_MPEG2LEVELTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_MPEG2LevelLL:  return \"Low\";\n        case OMX_VIDEO_MPEG2LevelML:  return \"Main\";\n        case OMX_VIDEO_MPEG2LevelH14: return \"High1440\";\n        case OMX_VIDEO_MPEG2LevelHL:  return \"High\";\n        default:                      return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_AVCPROFILETYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_AVCProfileBaseline: return \"Baseline\";\n        case OMX_VIDEO_AVCProfileMain:     return \"Main\";\n        case OMX_VIDEO_AVCProfileExtended: return \"Extended\";\n        case OMX_VIDEO_AVCProfileHigh:     return \"High\";\n        case OMX_VIDEO_AVCProfileHigh10:   return \"High10\";\n        case OMX_VIDEO_AVCProfileHigh422:  return \"High422\";\n        case OMX_VIDEO_AVCProfileHigh444:  return \"High444\";\n        default:                           return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_AVCLEVELTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_AVCLevel1:  return \"Level1\";\n        case OMX_VIDEO_AVCLevel1b: return \"Level1b\";\n        case OMX_VIDEO_AVCLevel11: return \"Level11\";\n        case OMX_VIDEO_AVCLevel12: return \"Level12\";\n        case OMX_VIDEO_AVCLevel13: return \"Level13\";\n        case OMX_VIDEO_AVCLevel2:  return \"Level2\";\n        case OMX_VIDEO_AVCLevel21: return \"Level21\";\n        case OMX_VIDEO_AVCLevel22: return \"Level22\";\n        case OMX_VIDEO_AVCLevel3:  return \"Level3\";\n        case OMX_VIDEO_AVCLevel31: return \"Level31\";\n        case OMX_VIDEO_AVCLevel32: return \"Level32\";\n        case OMX_VIDEO_AVCLevel4:  return \"Level4\";\n        case OMX_VIDEO_AVCLevel41: return \"Level41\";\n        case OMX_VIDEO_AVCLevel42: return \"Level42\";\n        case OMX_VIDEO_AVCLevel5:  return \"Level5\";\n        case OMX_VIDEO_AVCLevel51: return \"Level51\";\n        case OMX_VIDEO_AVCLevel52: return \"Level52\";\n        default:                   return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_AVCLOOPFILTERTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_AVCLoopFilterEnable:               return \"Enable\";\n//      case OMX_VIDEO_AVCLoopFilterDisable:              return \"Disable\";\n//      case OMX_VIDEO_AVCLoopFilterDisableSliceBoundary: return \"DisableSliceBoundary\";\n        default:                                          return def;\n    }\n}\n\n#endif // AS_STRING_FOR_OMX_VIDEO_H\n\n#endif // OMX_Video_h\n\n#ifdef OMX_VideoExt_h\n/* asString definitions if media/openmax/OMX_VideoExt.h was included */\n\n#ifndef AS_STRING_FOR_OMX_VIDEOEXT_H\n#define AS_STRING_FOR_OMX_VIDEOEXT_H\n\ninline static const char *asString(OMX_VIDEO_VP8PROFILETYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_VP8ProfileMain:    return \"Main\";\n        case OMX_VIDEO_VP8ProfileUnknown: return \"Unknown\";  // unused\n        default:                          return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_VP8LEVELTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_VP8Level_Version0: return \"_Version0\";\n        case OMX_VIDEO_VP8Level_Version1: return \"_Version1\";\n        case OMX_VIDEO_VP8Level_Version2: return \"_Version2\";\n        case OMX_VIDEO_VP8Level_Version3: return \"_Version3\";\n        case OMX_VIDEO_VP8LevelUnknown:   return \"Unknown\";    // unused\n        default:                          return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_VP9PROFILETYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_VP9Profile0:    return \"Profile0\";\n        case OMX_VIDEO_VP9Profile1:    return \"Profile1\";\n        case OMX_VIDEO_VP9Profile2:    return \"Profile2\";\n        case OMX_VIDEO_VP9Profile3:    return \"Profile3\";\n        case OMX_VIDEO_VP9Profile2HDR: return \"Profile2HDR\";\n        case OMX_VIDEO_VP9Profile3HDR: return \"Profile3HDR\";\n        default:                       return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_VP9LEVELTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_VP9Level1:  return \"Level1\";\n        case OMX_VIDEO_VP9Level11: return \"Level11\";\n        case OMX_VIDEO_VP9Level2:  return \"Level2\";\n        case OMX_VIDEO_VP9Level21: return \"Level21\";\n        case OMX_VIDEO_VP9Level3:  return \"Level3\";\n        case OMX_VIDEO_VP9Level31: return \"Level31\";\n        case OMX_VIDEO_VP9Level4:  return \"Level4\";\n        case OMX_VIDEO_VP9Level41: return \"Level41\";\n        case OMX_VIDEO_VP9Level5:  return \"Level5\";\n        case OMX_VIDEO_VP9Level51: return \"Level51\";\n        case OMX_VIDEO_VP9Level52: return \"Level52\";\n        case OMX_VIDEO_VP9Level6:  return \"Level6\";\n        case OMX_VIDEO_VP9Level61: return \"Level61\";\n        case OMX_VIDEO_VP9Level62: return \"Level62\";\n        default:                   return def;\n    }\n}\n\ninline static const char *asString(\n        OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE i, const char *def = \"??\") {\n    switch (i) {\n        case OMX_VIDEO_VPXTemporalLayerPatternNone:   return \"VPXTemporalLayerPatternNone\";\n        case OMX_VIDEO_VPXTemporalLayerPatternWebRTC: return \"VPXTemporalLayerPatternWebRTC\";\n        default:                                      return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_HEVCPROFILETYPE i, const char *def = \"!!\") {\n    switch (i) {\n        case OMX_VIDEO_HEVCProfileUnknown:      return \"Unknown\";  // unused\n        case OMX_VIDEO_HEVCProfileMain:         return \"Main\";\n        case OMX_VIDEO_HEVCProfileMain10:       return \"Main10\";\n        case OMX_VIDEO_HEVCProfileMain10HDR10:  return \"Main10HDR10\";\n        default:                                return def;\n    }\n}\n\ninline static const char *asString(OMX_VIDEO_HEVCLEVELTYPE i, const char *def = \"!!\") {\n    switch (i) {\n        case OMX_VIDEO_HEVCLevelUnknown:    return \"LevelUnknown\";     // unused\n        case OMX_VIDEO_HEVCMainTierLevel1:  return \"MainTierLevel1\";\n        case OMX_VIDEO_HEVCHighTierLevel1:  return \"HighTierLevel1\";\n        case OMX_VIDEO_HEVCMainTierLevel2:  return \"MainTierLevel2\";\n        case OMX_VIDEO_HEVCHighTierLevel2:  return \"HighTierLevel2\";\n        case OMX_VIDEO_HEVCMainTierLevel21: return \"MainTierLevel21\";\n        case OMX_VIDEO_HEVCHighTierLevel21: return \"HighTierLevel21\";\n        case OMX_VIDEO_HEVCMainTierLevel3:  return \"MainTierLevel3\";\n        case OMX_VIDEO_HEVCHighTierLevel3:  return \"HighTierLevel3\";\n        case OMX_VIDEO_HEVCMainTierLevel31: return \"MainTierLevel31\";\n        case OMX_VIDEO_HEVCHighTierLevel31: return \"HighTierLevel31\";\n        case OMX_VIDEO_HEVCMainTierLevel4:  return \"MainTierLevel4\";\n        case OMX_VIDEO_HEVCHighTierLevel4:  return \"HighTierLevel4\";\n        case OMX_VIDEO_HEVCMainTierLevel41: return \"MainTierLevel41\";\n        case OMX_VIDEO_HEVCHighTierLevel41: return \"HighTierLevel41\";\n        case OMX_VIDEO_HEVCMainTierLevel5:  return \"MainTierLevel5\";\n        case OMX_VIDEO_HEVCHighTierLevel5:  return \"HighTierLevel5\";\n        case OMX_VIDEO_HEVCMainTierLevel51: return \"MainTierLevel51\";\n        case OMX_VIDEO_HEVCHighTierLevel51: return \"HighTierLevel51\";\n        case OMX_VIDEO_HEVCMainTierLevel52: return \"MainTierLevel52\";\n        case OMX_VIDEO_HEVCHighTierLevel52: return \"HighTierLevel52\";\n        case OMX_VIDEO_HEVCMainTierLevel6:  return \"MainTierLevel6\";\n        case OMX_VIDEO_HEVCHighTierLevel6:  return \"HighTierLevel6\";\n        case OMX_VIDEO_HEVCMainTierLevel61: return \"MainTierLevel61\";\n        case OMX_VIDEO_HEVCHighTierLevel61: return \"HighTierLevel61\";\n        case OMX_VIDEO_HEVCMainTierLevel62: return \"MainTierLevel62\";\n        case OMX_VIDEO_HEVCHighTierLevel62: return \"HighTierLevel62\";\n        default:                            return def;\n    }\n}\n\n#endif // AS_STRING_FOR_OMX_VIDEOEXT_H\n\n#endif // OMX_VideoExt_h\n\n#ifdef ANDROID\n} // namespace android\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/openmax/OMX_Audio.h",
    "content": "/* ------------------------------------------------------------------\n * Copyright (C) 1998-2009 PacketVideo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n * express or implied.\n * See the License for the specific language governing permissions\n * and limitations under the License.\n * -------------------------------------------------------------------\n */\n/*\n * Copyright (c) 2008 The Khronos Group Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject\n * to the following conditions:\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n/** @file OMX_Audio.h - OpenMax IL version 1.1.2\n *  The structures needed by Audio components to exchange\n *  parameters and configuration data with the componenmilts.\n */\n\n#ifndef OMX_Audio_h\n#define OMX_Audio_h\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/* Each OMX header must include all required header files to allow the\n *  header to compile without errors.  The includes below are required\n *  for this header file to compile successfully\n */\n\n#include <OMX_Core.h>\n\n/** @defgroup midi MIDI\n * @ingroup audio\n */\n\n/** @defgroup effects Audio effects\n * @ingroup audio\n */\n\n/** @defgroup audio OpenMAX IL Audio Domain\n * Structures for OpenMAX IL Audio domain\n * @{\n */\n\n/** Enumeration used to define the possible audio codings.\n *  If \"OMX_AUDIO_CodingUnused\" is selected, the coding selection must\n *  be done in a vendor specific way.  Since this is for an audio\n *  processing element this enum is relevant.  However, for another\n *  type of component other enums would be in this area.\n */\ntypedef enum OMX_AUDIO_CODINGTYPE {\n    OMX_AUDIO_CodingUnused = 0,  /**< Placeholder value when coding is N/A  */\n    OMX_AUDIO_CodingAutoDetect,  /**< auto detection of audio format */\n    OMX_AUDIO_CodingPCM,         /**< Any variant of PCM coding */\n    OMX_AUDIO_CodingADPCM,       /**< Any variant of ADPCM encoded data */\n    OMX_AUDIO_CodingAMR,         /**< Any variant of AMR encoded data */\n    OMX_AUDIO_CodingGSMFR,       /**< Any variant of GSM fullrate (i.e. GSM610) */\n    OMX_AUDIO_CodingGSMEFR,      /**< Any variant of GSM Enhanced Fullrate encoded data*/\n    OMX_AUDIO_CodingGSMHR,       /**< Any variant of GSM Halfrate encoded data */\n    OMX_AUDIO_CodingPDCFR,       /**< Any variant of PDC Fullrate encoded data */\n    OMX_AUDIO_CodingPDCEFR,      /**< Any variant of PDC Enhanced Fullrate encoded data */\n    OMX_AUDIO_CodingPDCHR,       /**< Any variant of PDC Halfrate encoded data */\n    OMX_AUDIO_CodingTDMAFR,      /**< Any variant of TDMA Fullrate encoded data (TIA/EIA-136-420) */\n    OMX_AUDIO_CodingTDMAEFR,     /**< Any variant of TDMA Enhanced Fullrate encoded data (TIA/EIA-136-410) */\n    OMX_AUDIO_CodingQCELP8,      /**< Any variant of QCELP 8kbps encoded data */\n    OMX_AUDIO_CodingQCELP13,     /**< Any variant of QCELP 13kbps encoded data */\n    OMX_AUDIO_CodingEVRC,        /**< Any variant of EVRC encoded data */\n    OMX_AUDIO_CodingSMV,         /**< Any variant of SMV encoded data */\n    OMX_AUDIO_CodingG711,        /**< Any variant of G.711 encoded data */\n    OMX_AUDIO_CodingG723,        /**< Any variant of G.723 dot 1 encoded data */\n    OMX_AUDIO_CodingG726,        /**< Any variant of G.726 encoded data */\n    OMX_AUDIO_CodingG729,        /**< Any variant of G.729 encoded data */\n    OMX_AUDIO_CodingAAC,         /**< Any variant of AAC encoded data */\n    OMX_AUDIO_CodingMP3,         /**< Any variant of MP3 encoded data */\n    OMX_AUDIO_CodingSBC,         /**< Any variant of SBC encoded data */\n    OMX_AUDIO_CodingVORBIS,      /**< Any variant of VORBIS encoded data */\n    OMX_AUDIO_CodingWMA,         /**< Any variant of WMA encoded data */\n    OMX_AUDIO_CodingRA,          /**< Any variant of RA encoded data */\n    OMX_AUDIO_CodingMIDI,        /**< Any variant of MIDI encoded data */\n    OMX_AUDIO_CodingFLAC,        /**< Any variant of FLAC encoded data */\n    OMX_AUDIO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_CodingMax = 0x7FFFFFFF\n} OMX_AUDIO_CODINGTYPE;\n\n\n/** The PortDefinition structure is used to define all of the parameters\n *  necessary for the compliant component to setup an input or an output audio\n *  path.  If additional information is needed to define the parameters of the\n *  port (such as frequency), additional structures must be sent such as the\n *  OMX_AUDIO_PARAM_PCMMODETYPE structure to supply the extra parameters for the port.\n */\ntypedef struct OMX_AUDIO_PORTDEFINITIONTYPE {\n    OMX_STRING cMIMEType;            /**< MIME type of data for the port */\n    OMX_NATIVE_DEVICETYPE pNativeRender; /** < platform specific reference\n                                               for an output device,\n                                               otherwise this field is 0 */\n    OMX_BOOL bFlagErrorConcealment;  /**< Turns on error concealment if it is\n                                          supported by the OMX component */\n    OMX_AUDIO_CODINGTYPE eEncoding;  /**< Type of data expected for this\n                                          port (e.g. PCM, AMR, MP3, etc) */\n} OMX_AUDIO_PORTDEFINITIONTYPE;\n\n\n/**  Port format parameter.  This structure is used to enumerate\n  *  the various data input/output format supported by the port.\n  */\ntypedef struct OMX_AUDIO_PARAM_PORTFORMATTYPE {\n    OMX_U32 nSize;                  /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */\n    OMX_U32 nPortIndex;             /**< Indicates which port to set */\n    OMX_U32 nIndex;                 /**< Indicates the enumeration index for the format from 0x0 to N-1 */\n    OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this port (e.g. PCM, AMR, MP3, etc) */\n} OMX_AUDIO_PARAM_PORTFORMATTYPE;\n\n\n/** PCM mode type  */\ntypedef enum OMX_AUDIO_PCMMODETYPE {\n    OMX_AUDIO_PCMModeLinear = 0,  /**< Linear PCM encoded data */\n    OMX_AUDIO_PCMModeALaw,        /**< A law PCM encoded data (G.711) */\n    OMX_AUDIO_PCMModeMULaw,       /**< Mu law PCM encoded data (G.711)  */\n    OMX_AUDIO_PCMModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_PCMModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_PCMModeMax = 0x7FFFFFFF\n} OMX_AUDIO_PCMMODETYPE;\n\n\ntypedef enum OMX_AUDIO_CHANNELTYPE {\n    OMX_AUDIO_ChannelNone = 0x0,    /**< Unused or empty */\n    OMX_AUDIO_ChannelLF   = 0x1,    /**< Left front */\n    OMX_AUDIO_ChannelRF   = 0x2,    /**< Right front */\n    OMX_AUDIO_ChannelCF   = 0x3,    /**< Center front */\n    OMX_AUDIO_ChannelLS   = 0x4,    /**< Left surround */\n    OMX_AUDIO_ChannelRS   = 0x5,    /**< Right surround */\n    OMX_AUDIO_ChannelLFE  = 0x6,    /**< Low frequency effects */\n    OMX_AUDIO_ChannelCS   = 0x7,    /**< Back surround */\n    OMX_AUDIO_ChannelLR   = 0x8,    /**< Left rear. */\n    OMX_AUDIO_ChannelRR   = 0x9,    /**< Right rear. */\n    OMX_AUDIO_ChannelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_ChannelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_ChannelMax  = 0x7FFFFFFF\n} OMX_AUDIO_CHANNELTYPE;\n\n#define OMX_AUDIO_MAXCHANNELS 16  /**< maximum number distinct audio channels that a buffer may contain */\n#define OMX_MIN_PCMPAYLOAD_MSEC 5 /**< Minimum audio buffer payload size for uncompressed (PCM) audio */\n\n/** PCM format description */\ntypedef struct OMX_AUDIO_PARAM_PCMMODETYPE {\n    OMX_U32 nSize;                    /**< Size of this structure, in Bytes */\n    OMX_VERSIONTYPE nVersion;         /**< OMX specification version information */\n    OMX_U32 nPortIndex;               /**< port that this structure applies to */\n    OMX_U32 nChannels;                /**< Number of channels (e.g. 2 for stereo) */\n    OMX_NUMERICALDATATYPE eNumData;   /**< indicates PCM data as signed, unsigned or floating pt. */\n    OMX_ENDIANTYPE eEndian;           /**< indicates PCM data as little or big endian */\n    OMX_BOOL bInterleaved;            /**< True for normal interleaved data; false for\n                                           non-interleaved data (e.g. block data) */\n    OMX_U32 nBitPerSample;            /**< Bit per sample */\n    OMX_U32 nSamplingRate;            /**< Sampling rate of the source data.  Use 0 for\n                                           variable or unknown sampling rate. */\n    OMX_AUDIO_PCMMODETYPE ePCMMode;   /**< PCM mode enumeration */\n    OMX_AUDIO_CHANNELTYPE eChannelMapping[OMX_AUDIO_MAXCHANNELS]; /**< Slot i contains channel defined by eChannelMap[i] */\n\n} OMX_AUDIO_PARAM_PCMMODETYPE;\n\n\n/** Audio channel mode.  This is used by both AAC and MP3, although the names are more appropriate\n * for the MP3.  For example, JointStereo for MP3 is CouplingChannels for AAC.\n */\ntypedef enum OMX_AUDIO_CHANNELMODETYPE {\n    OMX_AUDIO_ChannelModeStereo = 0,  /**< 2 channels, the bitrate allocation between those\n                                          two channels changes accordingly to each channel information */\n    OMX_AUDIO_ChannelModeJointStereo, /**< mode that takes advantage of what is common between\n                                           2 channels for higher compression gain */\n    OMX_AUDIO_ChannelModeDual,        /**< 2 mono-channels, each channel is encoded with half\n                                           the bitrate of the overall bitrate */\n    OMX_AUDIO_ChannelModeMono,        /**< Mono channel mode */\n    OMX_AUDIO_ChannelModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_ChannelModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_ChannelModeMax = 0x7FFFFFFF\n} OMX_AUDIO_CHANNELMODETYPE;\n\n\ntypedef enum OMX_AUDIO_MP3STREAMFORMATTYPE {\n    OMX_AUDIO_MP3StreamFormatMP1Layer3 = 0, /**< MP3 Audio MPEG 1 Layer 3 Stream format */\n    OMX_AUDIO_MP3StreamFormatMP2Layer3,     /**< MP3 Audio MPEG 2 Layer 3 Stream format */\n    OMX_AUDIO_MP3StreamFormatMP2_5Layer3,   /**< MP3 Audio MPEG2.5 Layer 3 Stream format */\n    OMX_AUDIO_MP3StreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_MP3StreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_MP3StreamFormatMax = 0x7FFFFFFF\n} OMX_AUDIO_MP3STREAMFORMATTYPE;\n\n/** MP3 params */\ntypedef struct OMX_AUDIO_PARAM_MP3TYPE {\n    OMX_U32 nSize;                 /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */\n    OMX_U32 nPortIndex;            /**< port that this structure applies to */\n    OMX_U32 nChannels;             /**< Number of channels */\n    OMX_U32 nBitRate;              /**< Bit rate of the input data.  Use 0 for variable\n                                        rate or unknown bit rates */\n    OMX_U32 nSampleRate;           /**< Sampling rate of the source data.  Use 0 for\n                                        variable or unknown sampling rate. */\n    OMX_U32 nAudioBandWidth;       /**< Audio band width (in Hz) to which an encoder should\n                                        limit the audio signal. Use 0 to let encoder decide */\n    OMX_AUDIO_CHANNELMODETYPE eChannelMode;   /**< Channel mode enumeration */\n    OMX_AUDIO_MP3STREAMFORMATTYPE eFormat;  /**< MP3 stream format */\n} OMX_AUDIO_PARAM_MP3TYPE;\n\n\ntypedef enum OMX_AUDIO_AACSTREAMFORMATTYPE {\n    OMX_AUDIO_AACStreamFormatMP2ADTS = 0, /**< AAC Audio Data Transport Stream 2 format */\n    OMX_AUDIO_AACStreamFormatMP4ADTS,     /**< AAC Audio Data Transport Stream 4 format */\n    OMX_AUDIO_AACStreamFormatMP4LOAS,     /**< AAC Low Overhead Audio Stream format */\n    OMX_AUDIO_AACStreamFormatMP4LATM,     /**< AAC Low overhead Audio Transport Multiplex */\n    OMX_AUDIO_AACStreamFormatADIF,        /**< AAC Audio Data Interchange Format */\n    OMX_AUDIO_AACStreamFormatMP4FF,       /**< AAC inside MPEG-4/ISO File Format */\n    OMX_AUDIO_AACStreamFormatRAW,         /**< AAC Raw Format */\n    OMX_AUDIO_AACStreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_AACStreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_AACStreamFormatMax = 0x7FFFFFFF\n} OMX_AUDIO_AACSTREAMFORMATTYPE;\n\n\n/** AAC mode type.  Note that the term profile is used with the MPEG-2\n * standard and the term object type and profile is used with MPEG-4 */\ntypedef enum OMX_AUDIO_AACPROFILETYPE{\n  OMX_AUDIO_AACObjectNull = 0,      /**< Null, not used */\n  OMX_AUDIO_AACObjectMain = 1,      /**< AAC Main object */\n  OMX_AUDIO_AACObjectLC,            /**< AAC Low Complexity object (AAC profile) */\n  OMX_AUDIO_AACObjectSSR,           /**< AAC Scalable Sample Rate object */\n  OMX_AUDIO_AACObjectLTP,           /**< AAC Long Term Prediction object */\n  OMX_AUDIO_AACObjectHE,            /**< AAC High Efficiency (object type SBR, HE-AAC profile) */\n  OMX_AUDIO_AACObjectScalable,      /**< AAC Scalable object */\n  OMX_AUDIO_AACObjectERLC = 17,     /**< ER AAC Low Complexity object (Error Resilient AAC-LC) */\n  OMX_AUDIO_AACObjectLD = 23,       /**< AAC Low Delay object (Error Resilient) */\n  OMX_AUDIO_AACObjectHE_PS = 29,    /**< AAC High Efficiency with Parametric Stereo coding (HE-AAC v2, object type PS) */\n  OMX_AUDIO_AACObjectELD = 39,      /** AAC Enhanced Low Delay. NOTE: Pending Khronos standardization **/\n  OMX_AUDIO_AACObjectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n  OMX_AUDIO_AACObjectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n  OMX_AUDIO_AACObjectMax = 0x7FFFFFFF\n} OMX_AUDIO_AACPROFILETYPE;\n\n\n/** AAC tool usage (for nAACtools in OMX_AUDIO_PARAM_AACPROFILETYPE).\n * Required for encoder configuration and optional as decoder info output.\n * For MP3, OMX_AUDIO_CHANNELMODETYPE is sufficient. */\n#define OMX_AUDIO_AACToolNone 0x00000000 /**< no AAC tools allowed (encoder config) or active (decoder info output) */\n#define OMX_AUDIO_AACToolMS   0x00000001 /**< MS: Mid/side joint coding tool allowed or active */\n#define OMX_AUDIO_AACToolIS   0x00000002 /**< IS: Intensity stereo tool allowed or active */\n#define OMX_AUDIO_AACToolTNS  0x00000004 /**< TNS: Temporal Noise Shaping tool allowed or active */\n#define OMX_AUDIO_AACToolPNS  0x00000008 /**< PNS: MPEG-4 Perceptual Noise substitution tool allowed or active */\n#define OMX_AUDIO_AACToolLTP  0x00000010 /**< LTP: MPEG-4 Long Term Prediction tool allowed or active */\n#define OMX_AUDIO_AACToolVendor 0x00010000 /**< NOT A KHRONOS VALUE, offset for vendor-specific additions */\n#define OMX_AUDIO_AACToolAll  0x7FFFFFFF /**< all AAC tools allowed or active (*/\n\n/** MPEG-4 AAC error resilience (ER) tool usage (for nAACERtools in OMX_AUDIO_PARAM_AACPROFILETYPE).\n * Required for ER encoder configuration and optional as decoder info output */\n#define OMX_AUDIO_AACERNone  0x00000000  /**< no AAC ER tools allowed/used */\n#define OMX_AUDIO_AACERVCB11 0x00000001  /**< VCB11: Virtual Code Books for AAC section data */\n#define OMX_AUDIO_AACERRVLC  0x00000002  /**< RVLC: Reversible Variable Length Coding */\n#define OMX_AUDIO_AACERHCR   0x00000004  /**< HCR: Huffman Codeword Reordering */\n#define OMX_AUDIO_AACERAll   0x7FFFFFFF  /**< all AAC ER tools allowed/used */\n\n\n/** AAC params */\ntypedef struct OMX_AUDIO_PARAM_AACPROFILETYPE {\n    OMX_U32 nSize;                 /**< Size of this structure, in Bytes */\n    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */\n    OMX_U32 nPortIndex;            /**< Port that this structure applies to */\n    OMX_U32 nChannels;             /**< Number of channels */\n    OMX_U32 nSampleRate;           /**< Sampling rate of the source data.  Use 0 for\n                                        variable or unknown sampling rate. */\n    OMX_U32 nBitRate;              /**< Bit rate of the input data.  Use 0 for variable\n                                        rate or unknown bit rates */\n    OMX_U32 nAudioBandWidth;       /**< Audio band width (in Hz) to which an encoder should\n                                        limit the audio signal. Use 0 to let encoder decide */\n    OMX_U32 nFrameLength;          /**< Frame length (in audio samples per channel) of the codec.\n                                        Can be 1024 or 960 (AAC-LC), 2048 (HE-AAC), 480 or 512 (AAC-LD).\n                                        Use 0 to let encoder decide */\n    OMX_U32 nAACtools;             /**< AAC tool usage */\n    OMX_U32 nAACERtools;           /**< MPEG-4 AAC error resilience tool usage */\n    OMX_AUDIO_AACPROFILETYPE eAACProfile;   /**< AAC profile enumeration */\n    OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat; /**< AAC stream format enumeration */\n    OMX_AUDIO_CHANNELMODETYPE eChannelMode;   /**< Channel mode enumeration */\n} OMX_AUDIO_PARAM_AACPROFILETYPE;\n\n\n/** VORBIS params */\ntypedef struct OMX_AUDIO_PARAM_VORBISTYPE {\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex;       /**< port that this structure applies to */\n    OMX_U32 nChannels;        /**< Number of channels */\n    OMX_U32 nBitRate;         /**< Bit rate of the encoded data data.  Use 0 for variable\n                                   rate or unknown bit rates. Encoding is set to the\n                                   bitrate closest to specified  value (in bps) */\n    OMX_U32 nMinBitRate;      /**< Sets minimum bitrate (in bps). */\n    OMX_U32 nMaxBitRate;      /**< Sets maximum bitrate (in bps). */\n\n    OMX_U32 nSampleRate;      /**< Sampling rate of the source data.  Use 0 for\n                                   variable or unknown sampling rate. */\n    OMX_U32 nAudioBandWidth;  /**< Audio band width (in Hz) to which an encoder should\n                                   limit the audio signal. Use 0 to let encoder decide */\n    OMX_S32 nQuality;         /**< Sets encoding quality to n, between -1 (low) and 10 (high).\n                                   In the default mode of operation, teh quality level is 3.\n                                   Normal quality range is 0 - 10. */\n    OMX_BOOL bManaged;        /**< Set  bitrate  management  mode. This turns off the\n                                   normal VBR encoding, but allows hard or soft bitrate\n                                   constraints to be enforced by the encoder. This mode can\n                                   be slower, and may also be lower quality. It is\n                                   primarily useful for streaming. */\n    OMX_BOOL bDownmix;        /**< Downmix input from stereo to mono (has no effect on\n                                   non-stereo streams). Useful for lower-bitrate encoding. */\n} OMX_AUDIO_PARAM_VORBISTYPE;\n\n\n/** FLAC params */\ntypedef struct OMX_AUDIO_PARAM_FLACTYPE {\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex;       /**< port that this structure applies to */\n    OMX_U32 nChannels;        /**< Number of channels */\n    OMX_U32 nSampleRate;      /**< Sampling rate of the source data.  Use 0 for\n                                   unknown sampling rate. */\n    OMX_U32 nCompressionLevel;/**< FLAC compression level, from 0 (fastest compression)\n                                   to 8 (highest compression */\n} OMX_AUDIO_PARAM_FLACTYPE;\n\n\n/** WMA Version */\ntypedef enum OMX_AUDIO_WMAFORMATTYPE {\n  OMX_AUDIO_WMAFormatUnused = 0, /**< format unused or unknown */\n  OMX_AUDIO_WMAFormat7,          /**< Windows Media Audio format 7 */\n  OMX_AUDIO_WMAFormat8,          /**< Windows Media Audio format 8 */\n  OMX_AUDIO_WMAFormat9,          /**< Windows Media Audio format 9 */\n  OMX_AUDIO_WMAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n  OMX_AUDIO_WMAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n  OMX_AUDIO_WMAFormatMax = 0x7FFFFFFF\n} OMX_AUDIO_WMAFORMATTYPE;\n\n\n/** WMA Profile */\ntypedef enum OMX_AUDIO_WMAPROFILETYPE {\n  OMX_AUDIO_WMAProfileUnused = 0,  /**< profile unused or unknown */\n  OMX_AUDIO_WMAProfileL1,          /**< Windows Media audio version 9 profile L1 */\n  OMX_AUDIO_WMAProfileL2,          /**< Windows Media audio version 9 profile L2 */\n  OMX_AUDIO_WMAProfileL3,          /**< Windows Media audio version 9 profile L3 */\n  OMX_AUDIO_WMAProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n  OMX_AUDIO_WMAProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n  OMX_AUDIO_WMAProfileMax = 0x7FFFFFFF\n} OMX_AUDIO_WMAPROFILETYPE;\n\n\n/** WMA params */\ntypedef struct OMX_AUDIO_PARAM_WMATYPE {\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex;       /**< port that this structure applies to */\n    OMX_U16 nChannels;        /**< Number of channels */\n    OMX_U32 nBitRate;         /**< Bit rate of the input data.  Use 0 for variable\n                                   rate or unknown bit rates */\n    OMX_AUDIO_WMAFORMATTYPE eFormat; /**< Version of WMA stream / data */\n    OMX_AUDIO_WMAPROFILETYPE eProfile;  /**< Profile of WMA stream / data */\n    OMX_U32 nSamplingRate;    /**< Sampling rate of the source data */\n    OMX_U16 nBlockAlign;      /**< is the block alignment, or block size, in bytes of the audio codec */\n    OMX_U16 nEncodeOptions;   /**< WMA Type-specific data */\n    OMX_U32 nSuperBlockAlign; /**< WMA Type-specific data */\n} OMX_AUDIO_PARAM_WMATYPE;\n\n/**\n * RealAudio format\n */\ntypedef enum OMX_AUDIO_RAFORMATTYPE {\n    OMX_AUDIO_RAFormatUnused = 0, /**< Format unused or unknown */\n    OMX_AUDIO_RA8,                /**< RealAudio 8 codec */\n    OMX_AUDIO_RA9,                /**< RealAudio 9 codec */\n    OMX_AUDIO_RA10_AAC,           /**< MPEG-4 AAC codec for bitrates of more than 128kbps */\n    OMX_AUDIO_RA10_CODEC,         /**< RealAudio codec for bitrates less than 128 kbps */\n    OMX_AUDIO_RA10_LOSSLESS,      /**< RealAudio Lossless */\n    OMX_AUDIO_RA10_MULTICHANNEL,  /**< RealAudio Multichannel */\n    OMX_AUDIO_RA10_VOICE,         /**< RealAudio Voice for bitrates below 15 kbps */\n    OMX_AUDIO_RAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_RAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_RAFormatMax = 0x7FFFFFFF\n} OMX_AUDIO_RAFORMATTYPE;\n\n/** RA (Real Audio) params */\ntypedef struct OMX_AUDIO_PARAM_RATYPE {\n    OMX_U32 nSize;              /**< Size of this structure, in Bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_U32 nPortIndex;         /**< Port that this structure applies to */\n    OMX_U32 nChannels;          /**< Number of channels */\n    OMX_U32 nSamplingRate;      /**< is the sampling rate of the source data */\n    OMX_U32 nBitsPerFrame;      /**< is the value for bits per frame  */\n    OMX_U32 nSamplePerFrame;    /**< is the value for samples per frame */\n    OMX_U32 nCouplingQuantBits; /**< is the number of coupling quantization bits in the stream */\n    OMX_U32 nCouplingStartRegion;   /**< is the coupling start region in the stream  */\n    OMX_U32 nNumRegions;        /**< is the number of regions value */\n    OMX_AUDIO_RAFORMATTYPE eFormat; /**< is the RealAudio audio format */\n} OMX_AUDIO_PARAM_RATYPE;\n\n\n/** SBC Allocation Method Type */\ntypedef enum OMX_AUDIO_SBCALLOCMETHODTYPE {\n  OMX_AUDIO_SBCAllocMethodLoudness, /**< Loudness allocation method */\n  OMX_AUDIO_SBCAllocMethodSNR,      /**< SNR allocation method */\n  OMX_AUDIO_SBCAllocMethodKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n  OMX_AUDIO_SBCAllocMethodVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n  OMX_AUDIO_SBCAllocMethodMax = 0x7FFFFFFF\n} OMX_AUDIO_SBCALLOCMETHODTYPE;\n\n\n/** SBC params */\ntypedef struct OMX_AUDIO_PARAM_SBCTYPE {\n    OMX_U32 nSize;             /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */\n    OMX_U32 nPortIndex;        /**< port that this structure applies to */\n    OMX_U32 nChannels;         /**< Number of channels */\n    OMX_U32 nBitRate;          /**< Bit rate of the input data.  Use 0 for variable\n                                    rate or unknown bit rates */\n    OMX_U32 nSampleRate;       /**< Sampling rate of the source data.  Use 0 for\n                                    variable or unknown sampling rate. */\n    OMX_U32 nBlocks;           /**< Number of blocks */\n    OMX_U32 nSubbands;         /**< Number of subbands */\n    OMX_U32 nBitPool;          /**< Bitpool value */\n    OMX_BOOL bEnableBitrate;   /**< Use bitrate value instead of bitpool */\n    OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */\n    OMX_AUDIO_SBCALLOCMETHODTYPE eSBCAllocType;   /**< SBC Allocation method type */\n} OMX_AUDIO_PARAM_SBCTYPE;\n\n\n/** ADPCM stream format parameters */\ntypedef struct OMX_AUDIO_PARAM_ADPCMTYPE {\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_U32 nPortIndex;         /**< port that this structure applies to */\n    OMX_U32 nChannels;          /**< Number of channels in the data stream (not\n                                     necessarily the same as the number of channels\n                                     to be rendered. */\n    OMX_U32 nBitsPerSample;     /**< Number of bits in each sample */\n    OMX_U32 nSampleRate;        /**< Sampling rate of the source data.  Use 0 for\n                                    variable or unknown sampling rate. */\n} OMX_AUDIO_PARAM_ADPCMTYPE;\n\n\n/** G723 rate */\ntypedef enum OMX_AUDIO_G723RATE {\n    OMX_AUDIO_G723ModeUnused = 0,  /**< AMRNB Mode unused / unknown */\n    OMX_AUDIO_G723ModeLow,         /**< 5300 bps */\n    OMX_AUDIO_G723ModeHigh,        /**< 6300 bps */\n    OMX_AUDIO_G723ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_G723ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_G723ModeMax = 0x7FFFFFFF\n} OMX_AUDIO_G723RATE;\n\n\n/** G723 - Sample rate must be 8 KHz */\ntypedef struct OMX_AUDIO_PARAM_G723TYPE {\n    OMX_U32 nSize;                /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */\n    OMX_U32 nPortIndex;           /**< port that this structure applies to */\n    OMX_U32 nChannels;            /**< Number of channels in the data stream (not\n                                       necessarily the same as the number of channels\n                                       to be rendered. */\n    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */\n    OMX_AUDIO_G723RATE eBitRate;  /**< todo: Should this be moved to a config? */\n    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */\n    OMX_BOOL bPostFilter;         /**< Enable Post Filter */\n} OMX_AUDIO_PARAM_G723TYPE;\n\n\n/** ITU G726 (ADPCM) rate */\ntypedef enum OMX_AUDIO_G726MODE {\n    OMX_AUDIO_G726ModeUnused = 0,  /**< G726 Mode unused / unknown */\n    OMX_AUDIO_G726Mode16,          /**< 16 kbps */\n    OMX_AUDIO_G726Mode24,          /**< 24 kbps */\n    OMX_AUDIO_G726Mode32,          /**< 32 kbps, most common rate, also G721 */\n    OMX_AUDIO_G726Mode40,          /**< 40 kbps */\n    OMX_AUDIO_G726ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_G726ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_G726ModeMax = 0x7FFFFFFF\n} OMX_AUDIO_G726MODE;\n\n\n/** G.726 stream format parameters - must be at 8KHz */\ntypedef struct OMX_AUDIO_PARAM_G726TYPE {\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_U32 nPortIndex;         /**< port that this structure applies to */\n    OMX_U32 nChannels;          /**< Number of channels in the data stream (not\n                                     necessarily the same as the number of channels\n                                     to be rendered. */\n     OMX_AUDIO_G726MODE eG726Mode;\n} OMX_AUDIO_PARAM_G726TYPE;\n\n\n/** G729 coder type */\ntypedef enum OMX_AUDIO_G729TYPE {\n    OMX_AUDIO_G729 = 0,           /**< ITU G.729  encoded data */\n    OMX_AUDIO_G729A,              /**< ITU G.729 annex A  encoded data */\n    OMX_AUDIO_G729B,              /**< ITU G.729 with annex B encoded data */\n    OMX_AUDIO_G729AB,             /**< ITU G.729 annexes A and B encoded data */\n    OMX_AUDIO_G729KhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_G729VendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_G729Max = 0x7FFFFFFF\n} OMX_AUDIO_G729TYPE;\n\n\n/** G729 stream format parameters - fixed 6KHz sample rate */\ntypedef struct OMX_AUDIO_PARAM_G729TYPE {\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex;       /**< port that this structure applies to */\n    OMX_U32 nChannels;        /**< Number of channels in the data stream (not\n                                   necessarily the same as the number of channels\n                                   to be rendered. */\n    OMX_BOOL bDTX;            /**< Enable Discontinuous Transmisssion */\n    OMX_AUDIO_G729TYPE eBitType;\n} OMX_AUDIO_PARAM_G729TYPE;\n\n\n/** AMR Frame format */\ntypedef enum OMX_AUDIO_AMRFRAMEFORMATTYPE {\n    OMX_AUDIO_AMRFrameFormatConformance = 0,  /**< Frame Format is AMR Conformance\n                                                   (Standard) Format */\n    OMX_AUDIO_AMRFrameFormatIF1,              /**< Frame Format is AMR Interface\n                                                   Format 1 */\n    OMX_AUDIO_AMRFrameFormatIF2,              /**< Frame Format is AMR Interface\n                                                   Format 2*/\n    OMX_AUDIO_AMRFrameFormatFSF,              /**< Frame Format is AMR File Storage\n                                                   Format */\n    OMX_AUDIO_AMRFrameFormatRTPPayload,       /**< Frame Format is AMR Real-Time\n                                                   Transport Protocol Payload Format */\n    OMX_AUDIO_AMRFrameFormatITU,              /**< Frame Format is ITU Format (added at Motorola request) */\n    OMX_AUDIO_AMRFrameFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_AMRFrameFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_AMRFrameFormatMax = 0x7FFFFFFF\n} OMX_AUDIO_AMRFRAMEFORMATTYPE;\n\n\n/** AMR band mode */\ntypedef enum OMX_AUDIO_AMRBANDMODETYPE {\n    OMX_AUDIO_AMRBandModeUnused = 0,          /**< AMRNB Mode unused / unknown */\n    OMX_AUDIO_AMRBandModeNB0,                 /**< AMRNB Mode 0 =  4750 bps */\n    OMX_AUDIO_AMRBandModeNB1,                 /**< AMRNB Mode 1 =  5150 bps */\n    OMX_AUDIO_AMRBandModeNB2,                 /**< AMRNB Mode 2 =  5900 bps */\n    OMX_AUDIO_AMRBandModeNB3,                 /**< AMRNB Mode 3 =  6700 bps */\n    OMX_AUDIO_AMRBandModeNB4,                 /**< AMRNB Mode 4 =  7400 bps */\n    OMX_AUDIO_AMRBandModeNB5,                 /**< AMRNB Mode 5 =  7950 bps */\n    OMX_AUDIO_AMRBandModeNB6,                 /**< AMRNB Mode 6 = 10200 bps */\n    OMX_AUDIO_AMRBandModeNB7,                 /**< AMRNB Mode 7 = 12200 bps */\n    OMX_AUDIO_AMRBandModeWB0,                 /**< AMRWB Mode 0 =  6600 bps */\n    OMX_AUDIO_AMRBandModeWB1,                 /**< AMRWB Mode 1 =  8850 bps */\n    OMX_AUDIO_AMRBandModeWB2,                 /**< AMRWB Mode 2 = 12650 bps */\n    OMX_AUDIO_AMRBandModeWB3,                 /**< AMRWB Mode 3 = 14250 bps */\n    OMX_AUDIO_AMRBandModeWB4,                 /**< AMRWB Mode 4 = 15850 bps */\n    OMX_AUDIO_AMRBandModeWB5,                 /**< AMRWB Mode 5 = 18250 bps */\n    OMX_AUDIO_AMRBandModeWB6,                 /**< AMRWB Mode 6 = 19850 bps */\n    OMX_AUDIO_AMRBandModeWB7,                 /**< AMRWB Mode 7 = 23050 bps */\n    OMX_AUDIO_AMRBandModeWB8,                 /**< AMRWB Mode 8 = 23850 bps */\n    OMX_AUDIO_AMRBandModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_AMRBandModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_AMRBandModeMax = 0x7FFFFFFF\n} OMX_AUDIO_AMRBANDMODETYPE;\n\n\n/** AMR Discontinuous Transmission mode */\ntypedef enum OMX_AUDIO_AMRDTXMODETYPE {\n    OMX_AUDIO_AMRDTXModeOff = 0,        /**< AMR Discontinuous Transmission Mode is disabled */\n    OMX_AUDIO_AMRDTXModeOnVAD1,         /**< AMR Discontinuous Transmission Mode using\n                                             Voice Activity Detector 1 (VAD1) is enabled */\n    OMX_AUDIO_AMRDTXModeOnVAD2,         /**< AMR Discontinuous Transmission Mode using\n                                             Voice Activity Detector 2 (VAD2) is enabled */\n    OMX_AUDIO_AMRDTXModeOnAuto,         /**< The codec will automatically select between\n                                             Off, VAD1 or VAD2 modes */\n\n    OMX_AUDIO_AMRDTXasEFR,             /**< DTX as EFR instead of AMR standard (3GPP 26.101, frame type =8,9,10) */\n\n    OMX_AUDIO_AMRDTXModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_AMRDTXModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_AMRDTXModeMax = 0x7FFFFFFF\n} OMX_AUDIO_AMRDTXMODETYPE;\n\n\n/** AMR params */\ntypedef struct OMX_AUDIO_PARAM_AMRTYPE {\n    OMX_U32 nSize;                          /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;               /**< OMX specification version information */\n    OMX_U32 nPortIndex;                     /**< port that this structure applies to */\n    OMX_U32 nChannels;                      /**< Number of channels */\n    OMX_U32 nBitRate;                       /**< Bit rate read only field */\n    OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode; /**< AMR Band Mode enumeration */\n    OMX_AUDIO_AMRDTXMODETYPE  eAMRDTXMode;  /**< AMR DTX Mode enumeration */\n    OMX_AUDIO_AMRFRAMEFORMATTYPE eAMRFrameFormat; /**< AMR frame format enumeration */\n} OMX_AUDIO_PARAM_AMRTYPE;\n\n\n/** GSM_FR (ETSI 06.10, 3GPP 46.010) stream format parameters */\ntypedef struct OMX_AUDIO_PARAM_GSMFRTYPE {\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex;       /**< port that this structure applies to */\n    OMX_BOOL bDTX;            /**< Enable Discontinuous Transmisssion */\n    OMX_BOOL bHiPassFilter;   /**< Enable High Pass Filter */\n} OMX_AUDIO_PARAM_GSMFRTYPE;\n\n\n/** GSM-HR (ETSI 06.20, 3GPP 46.020) stream format parameters */\ntypedef struct OMX_AUDIO_PARAM_GSMHRTYPE {\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex;       /**< port that this structure applies to */\n    OMX_BOOL bDTX;            /**< Enable Discontinuous Transmisssion */\n    OMX_BOOL bHiPassFilter;   /**< Enable High Pass Filter */\n} OMX_AUDIO_PARAM_GSMHRTYPE;\n\n\n/** GSM-EFR (ETSI 06.60, 3GPP 46.060) stream format parameters */\ntypedef struct OMX_AUDIO_PARAM_GSMEFRTYPE {\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex;       /**< port that this structure applies to */\n    OMX_BOOL bDTX;            /**< Enable Discontinuous Transmisssion */\n    OMX_BOOL bHiPassFilter;   /**< Enable High Pass Filter */\n} OMX_AUDIO_PARAM_GSMEFRTYPE;\n\n\n/** TDMA FR (TIA/EIA-136-420, VSELP 7.95kbps coder) stream format parameters */\ntypedef struct OMX_AUDIO_PARAM_TDMAFRTYPE {\n    OMX_U32 nSize;                /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */\n    OMX_U32 nPortIndex;           /**< port that this structure applies to */\n    OMX_U32 nChannels;            /**< Number of channels in the data stream (not\n                                       necessarily the same as the number of channels\n                                       to be rendered. */\n    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */\n    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */\n} OMX_AUDIO_PARAM_TDMAFRTYPE;\n\n\n/** TDMA EFR (TIA/EIA-136-410, ACELP 7.4kbps coder) stream format parameters */\ntypedef struct OMX_AUDIO_PARAM_TDMAEFRTYPE {\n    OMX_U32 nSize;                /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */\n    OMX_U32 nPortIndex;           /**< port that this structure applies to */\n    OMX_U32 nChannels;            /**< Number of channels in the data stream (not\n                                       necessarily the same as the number of channels\n                                       to be rendered. */\n    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */\n    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */\n} OMX_AUDIO_PARAM_TDMAEFRTYPE;\n\n\n/** PDC FR ( RCR-27, VSELP 6.7kbps coder) stream format parameters */\ntypedef struct OMX_AUDIO_PARAM_PDCFRTYPE {\n    OMX_U32 nSize;                /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */\n    OMX_U32 nPortIndex;           /**< port that this structure applies to */\n    OMX_U32 nChannels;            /**< Number of channels in the data stream (not\n                                       necessarily the same as the number of channels\n                                       to be rendered. */\n    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */\n    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */\n} OMX_AUDIO_PARAM_PDCFRTYPE;\n\n\n/** PDC EFR ( RCR-27, ACELP 6.7kbps coder) stream format parameters */\ntypedef struct OMX_AUDIO_PARAM_PDCEFRTYPE {\n    OMX_U32 nSize;                /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */\n    OMX_U32 nPortIndex;           /**< port that this structure applies to */\n    OMX_U32 nChannels;            /**< Number of channels in the data stream (not\n                                       necessarily the same as the number of channels\n                                       to be rendered. */\n    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */\n    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */\n} OMX_AUDIO_PARAM_PDCEFRTYPE;\n\n/** PDC HR ( RCR-27, PSI-CELP 3.45kbps coder) stream format parameters */\ntypedef struct OMX_AUDIO_PARAM_PDCHRTYPE {\n    OMX_U32 nSize;                /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */\n    OMX_U32 nPortIndex;           /**< port that this structure applies to */\n    OMX_U32 nChannels;            /**< Number of channels in the data stream (not\n                                       necessarily the same as the number of channels\n                                       to be rendered. */\n    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */\n    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */\n} OMX_AUDIO_PARAM_PDCHRTYPE;\n\n\n/** CDMA Rate types */\ntypedef enum OMX_AUDIO_CDMARATETYPE {\n    OMX_AUDIO_CDMARateBlank = 0,          /**< CDMA encoded frame is blank */\n    OMX_AUDIO_CDMARateFull,               /**< CDMA encoded frame in full rate */\n    OMX_AUDIO_CDMARateHalf,               /**< CDMA encoded frame in half rate */\n    OMX_AUDIO_CDMARateQuarter,            /**< CDMA encoded frame in quarter rate */\n    OMX_AUDIO_CDMARateEighth,             /**< CDMA encoded frame in eighth rate (DTX)*/\n    OMX_AUDIO_CDMARateErasure,            /**< CDMA erasure frame */\n    OMX_AUDIO_CDMARateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_CDMARateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_CDMARateMax = 0x7FFFFFFF\n} OMX_AUDIO_CDMARATETYPE;\n\n\n/** QCELP8 (TIA/EIA-96, up to 8kbps coder) stream format parameters */\ntypedef struct OMX_AUDIO_PARAM_QCELP8TYPE {\n    OMX_U32 nSize;                /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */\n    OMX_U32 nPortIndex;           /**< port that this structure applies to */\n    OMX_U32 nChannels;            /**< Number of channels in the data stream (not\n                                       necessarily the same as the number of channels\n                                       to be rendered. */\n    OMX_U32 nBitRate;             /**< Bit rate of the input data.  Use 0 for variable\n                                       rate or unknown bit rates */\n    OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */\n    OMX_U32 nMinBitRate;          /**< minmal rate for the encoder = 1,2,3,4, default = 1 */\n    OMX_U32 nMaxBitRate;          /**< maximal rate for the encoder = 1,2,3,4, default = 4 */\n} OMX_AUDIO_PARAM_QCELP8TYPE;\n\n\n/** QCELP13 ( CDMA, EIA/TIA-733, 13.3kbps coder) stream format parameters */\ntypedef struct OMX_AUDIO_PARAM_QCELP13TYPE {\n    OMX_U32 nSize;                /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */\n    OMX_U32 nPortIndex;           /**< port that this structure applies to */\n    OMX_U32 nChannels;            /**< Number of channels in the data stream (not\n                                       necessarily the same as the number of channels\n                                       to be rendered. */\n    OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */\n    OMX_U32 nMinBitRate;          /**< minmal rate for the encoder = 1,2,3,4, default = 1 */\n    OMX_U32 nMaxBitRate;          /**< maximal rate for the encoder = 1,2,3,4, default = 4 */\n} OMX_AUDIO_PARAM_QCELP13TYPE;\n\n\n/** EVRC ( CDMA, EIA/TIA-127, RCELP up to 8.55kbps coder) stream format parameters */\ntypedef struct OMX_AUDIO_PARAM_EVRCTYPE {\n    OMX_U32 nSize;                /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */\n    OMX_U32 nPortIndex;           /**< port that this structure applies to */\n    OMX_U32 nChannels;            /**< Number of channels in the data stream (not\n                                       necessarily the same as the number of channels\n                                       to be rendered. */\n    OMX_AUDIO_CDMARATETYPE eCDMARate; /**< actual Frame rate */\n    OMX_BOOL bRATE_REDUCon;       /**< RATE_REDUCtion is requested for this frame */\n    OMX_U32 nMinBitRate;          /**< minmal rate for the encoder = 1,2,3,4, default = 1 */\n    OMX_U32 nMaxBitRate;          /**< maximal rate for the encoder = 1,2,3,4, default = 4 */\n    OMX_BOOL bHiPassFilter;       /**< Enable encoder's High Pass Filter */\n    OMX_BOOL bNoiseSuppressor;    /**< Enable encoder's noise suppressor pre-processing */\n    OMX_BOOL bPostFilter;         /**< Enable decoder's post Filter */\n} OMX_AUDIO_PARAM_EVRCTYPE;\n\n\n/** SMV ( up to 8.55kbps coder) stream format parameters */\ntypedef struct OMX_AUDIO_PARAM_SMVTYPE {\n    OMX_U32 nSize;                /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */\n    OMX_U32 nPortIndex;           /**< port that this structure applies to */\n    OMX_U32 nChannels;            /**< Number of channels in the data stream (not\n                                       necessarily the same as the number of channels\n                                       to be rendered. */\n    OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */\n    OMX_BOOL bRATE_REDUCon;           /**< RATE_REDUCtion is requested for this frame */\n    OMX_U32 nMinBitRate;          /**< minmal rate for the encoder = 1,2,3,4, default = 1 ??*/\n    OMX_U32 nMaxBitRate;          /**< maximal rate for the encoder = 1,2,3,4, default = 4 ??*/\n    OMX_BOOL bHiPassFilter;       /**< Enable encoder's High Pass Filter ??*/\n    OMX_BOOL bNoiseSuppressor;    /**< Enable encoder's noise suppressor pre-processing */\n    OMX_BOOL bPostFilter;         /**< Enable decoder's post Filter ??*/\n} OMX_AUDIO_PARAM_SMVTYPE;\n\n\n/** MIDI Format\n * @ingroup midi\n */\ntypedef enum OMX_AUDIO_MIDIFORMATTYPE\n{\n    OMX_AUDIO_MIDIFormatUnknown = 0, /**< MIDI Format unknown or don't care */\n    OMX_AUDIO_MIDIFormatSMF0,        /**< Standard MIDI File Type 0 */\n    OMX_AUDIO_MIDIFormatSMF1,        /**< Standard MIDI File Type 1 */\n    OMX_AUDIO_MIDIFormatSMF2,        /**< Standard MIDI File Type 2 */\n    OMX_AUDIO_MIDIFormatSPMIDI,      /**< SP-MIDI */\n    OMX_AUDIO_MIDIFormatXMF0,        /**< eXtensible Music Format type 0 */\n    OMX_AUDIO_MIDIFormatXMF1,        /**< eXtensible Music Format type 1 */\n    OMX_AUDIO_MIDIFormatMobileXMF,   /**< Mobile XMF (eXtensible Music Format type 2) */\n    OMX_AUDIO_MIDIFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_MIDIFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_MIDIFormatMax = 0x7FFFFFFF\n} OMX_AUDIO_MIDIFORMATTYPE;\n\n\n/** MIDI params\n * @ingroup midi\n */\ntypedef struct OMX_AUDIO_PARAM_MIDITYPE {\n    OMX_U32 nSize;                 /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */\n    OMX_U32 nPortIndex;            /**< port that this structure applies to */\n    OMX_U32 nFileSize;             /**< size of the MIDI file in bytes, where the entire\n                                        MIDI file passed in, otherwise if 0x0, the MIDI data\n                                        is merged and streamed (instead of passed as an\n                                        entire MIDI file) */\n    OMX_BU32 sMaxPolyphony;        /**< Specifies the maximum simultaneous polyphonic\n                                        voices. A value of zero indicates that the default\n                                        polyphony of the device is used  */\n    OMX_BOOL bLoadDefaultSound;    /**< Whether to load default sound\n                                        bank at initialization */\n    OMX_AUDIO_MIDIFORMATTYPE eMidiFormat; /**< Version of the MIDI file */\n} OMX_AUDIO_PARAM_MIDITYPE;\n\n\n/** Type of the MIDI sound bank\n * @ingroup midi\n */\ntypedef enum OMX_AUDIO_MIDISOUNDBANKTYPE {\n    OMX_AUDIO_MIDISoundBankUnused = 0,           /**< unused/unknown soundbank type */\n    OMX_AUDIO_MIDISoundBankDLS1,                 /**< DLS version 1 */\n    OMX_AUDIO_MIDISoundBankDLS2,                 /**< DLS version 2 */\n    OMX_AUDIO_MIDISoundBankMobileDLSBase,        /**< Mobile DLS, using the base functionality */\n    OMX_AUDIO_MIDISoundBankMobileDLSPlusOptions, /**< Mobile DLS, using the specification-defined optional feature set */\n    OMX_AUDIO_MIDISoundBankKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_MIDISoundBankVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_MIDISoundBankMax = 0x7FFFFFFF\n} OMX_AUDIO_MIDISOUNDBANKTYPE;\n\n\n/** Bank Layout describes how bank MSB & LSB are used in the DLS instrument definitions sound bank\n * @ingroup midi\n */\ntypedef enum OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE {\n   OMX_AUDIO_MIDISoundBankLayoutUnused = 0,   /**< unused/unknown soundbank type */\n   OMX_AUDIO_MIDISoundBankLayoutGM,           /**< GS layout (based on bank MSB 0x00) */\n   OMX_AUDIO_MIDISoundBankLayoutGM2,          /**< General MIDI 2 layout (using MSB 0x78/0x79, LSB 0x00) */\n   OMX_AUDIO_MIDISoundBankLayoutUser,         /**< Does not conform to any bank numbering standards */\n   OMX_AUDIO_MIDISoundBankLayoutKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n   OMX_AUDIO_MIDISoundBankLayoutVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n   OMX_AUDIO_MIDISoundBankLayoutMax = 0x7FFFFFFF\n} OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE;\n\n\n/** MIDI params to load/unload user soundbank\n * @ingroup midi\n */\ntypedef struct OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE {\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex;       /**< port that this structure applies to */\n    OMX_U32 nDLSIndex;        /**< DLS file index to be loaded */\n    OMX_U32 nDLSSize;         /**< Size in bytes */\n    OMX_PTR pDLSData;         /**< Pointer to DLS file data */\n    OMX_AUDIO_MIDISOUNDBANKTYPE eMidiSoundBank;   /**< Midi sound bank type enumeration */\n    OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE eMidiSoundBankLayout; /**< Midi sound bank layout enumeration */\n} OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE;\n\n\n/** Structure for Live MIDI events and MIP messages.\n * (MIP = Maximum Instantaneous Polyphony; part of the SP-MIDI standard.)\n * @ingroup midi\n */\ntypedef struct OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE {\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex;       /**< Port that this structure applies to */\n    OMX_U32 nMidiEventSize;   /**< Size of immediate MIDI events or MIP message in bytes  */\n    OMX_U8 nMidiEvents[1];    /**< MIDI event array to be rendered immediately, or an\n                                   array for the MIP message buffer, where the size is\n                                   indicated by nMidiEventSize */\n} OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE;\n\n\n/** MIDI sound bank/ program pair in a given channel\n * @ingroup midi\n */\ntypedef struct OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE {\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_U32 nPortIndex;         /**< Port that this structure applies to */\n    OMX_U32 nChannel;           /**< Valid channel values range from 1 to 16 */\n    OMX_U16 nIDProgram;         /**< Valid program ID range is 1 to 128 */\n    OMX_U16 nIDSoundBank;       /**< Sound bank ID */\n    OMX_U32 nUserSoundBankIndex;/**< User soundbank index, easier to access soundbanks\n                                     by index if multiple banks are present */\n} OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE;\n\n\n/** MIDI control\n * @ingroup midi\n */\ntypedef struct OMX_AUDIO_CONFIG_MIDICONTROLTYPE {\n    OMX_U32 nSize;                /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */\n    OMX_U32 nPortIndex;           /**< port that this structure applies to */\n    OMX_BS32 sPitchTransposition; /**< Pitch transposition in semitones, stored as Q22.10\n                                       format based on JAVA MMAPI (JSR-135) requirement */\n    OMX_BU32 sPlayBackRate;       /**< Relative playback rate, stored as Q14.17 fixed-point\n                                       number based on JSR-135 requirement */\n    OMX_BU32 sTempo ;             /**< Tempo in beats per minute (BPM), stored as Q22.10\n                                       fixed-point number based on JSR-135 requirement */\n    OMX_U32 nMaxPolyphony;        /**< Specifies the maximum simultaneous polyphonic\n                                       voices. A value of zero indicates that the default\n                                       polyphony of the device is used  */\n    OMX_U32 nNumRepeat;           /**< Number of times to repeat playback */\n    OMX_U32 nStopTime;            /**< Time in milliseconds to indicate when playback\n                                       will stop automatically.  Set to zero if not used */\n    OMX_U16 nChannelMuteMask;     /**< 16 bit mask for channel mute status */\n    OMX_U16 nChannelSoloMask;     /**< 16 bit mask for channel solo status */\n    OMX_U32 nTrack0031MuteMask;   /**< 32 bit mask for track mute status. Note: This is for tracks 0-31 */\n    OMX_U32 nTrack3263MuteMask;   /**< 32 bit mask for track mute status. Note: This is for tracks 32-63 */\n    OMX_U32 nTrack0031SoloMask;   /**< 32 bit mask for track solo status. Note: This is for tracks 0-31 */\n    OMX_U32 nTrack3263SoloMask;   /**< 32 bit mask for track solo status. Note: This is for tracks 32-63 */\n\n} OMX_AUDIO_CONFIG_MIDICONTROLTYPE;\n\n\n/** MIDI Playback States\n * @ingroup midi\n */\ntypedef enum OMX_AUDIO_MIDIPLAYBACKSTATETYPE {\n  OMX_AUDIO_MIDIPlayBackStateUnknown = 0,      /**< Unknown state or state does not map to\n                                                    other defined states */\n  OMX_AUDIO_MIDIPlayBackStateClosedEngaged,    /**< No MIDI resource is currently open.\n                                                    The MIDI engine is currently processing\n                                                    MIDI events. */\n  OMX_AUDIO_MIDIPlayBackStateParsing,          /**< A MIDI resource is open and is being\n                                                    primed. The MIDI engine is currently\n                                                    processing MIDI events. */\n  OMX_AUDIO_MIDIPlayBackStateOpenEngaged,      /**< A MIDI resource is open and primed but\n                                                    not playing. The MIDI engine is currently\n                                                    processing MIDI events. The transition to\n                                                    this state is only possible from the\n                                                    OMX_AUDIO_MIDIPlayBackStatePlaying state,\n                                                    when the 'playback head' reaches the end\n                                                    of media data or the playback stops due\n                                                    to stop time set.*/\n  OMX_AUDIO_MIDIPlayBackStatePlaying,          /**< A MIDI resource is open and currently\n                                                    playing. The MIDI engine is currently\n                                                    processing MIDI events.*/\n  OMX_AUDIO_MIDIPlayBackStatePlayingPartially, /**< Best-effort playback due to SP-MIDI/DLS\n                                                    resource constraints */\n  OMX_AUDIO_MIDIPlayBackStatePlayingSilently,  /**< Due to system resource constraints and\n                                                    SP-MIDI content constraints, there is\n                                                    no audible MIDI content during playback\n                                                    currently. The situation may change if\n                                                    resources are freed later.*/\n  OMX_AUDIO_MIDIPlayBackStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n  OMX_AUDIO_MIDIPlayBackStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n  OMX_AUDIO_MIDIPlayBackStateMax = 0x7FFFFFFF\n} OMX_AUDIO_MIDIPLAYBACKSTATETYPE;\n\n\n/** MIDI status\n * @ingroup midi\n */\ntypedef struct OMX_AUDIO_CONFIG_MIDISTATUSTYPE {\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_U32 nPortIndex;         /**< port that this structure applies to */\n    OMX_U16 nNumTracks;         /**< Number of MIDI tracks in the file, read only field.\n                                     NOTE: May not return a meaningful value until the entire\n                                     file is parsed and buffered.  */\n    OMX_U32 nDuration;          /**< The length of the currently open MIDI resource\n                                     in milliseconds. NOTE: May not return a meaningful value\n                                     until the entire file is parsed and buffered.  */\n    OMX_U32 nPosition;          /**< Current Position of the MIDI resource being played\n                                     in milliseconds */\n    OMX_BOOL bVibra;            /**< Does Vibra track exist? NOTE: May not return a meaningful\n                                     value until the entire file is parsed and buffered. */\n    OMX_U32 nNumMetaEvents;     /**< Total number of MIDI Meta Events in the currently\n                                     open MIDI resource. NOTE: May not return a meaningful value\n                                     until the entire file is parsed and buffered.  */\n    OMX_U32 nNumActiveVoices;   /**< Number of active voices in the currently playing\n                                     MIDI resource. NOTE: May not return a meaningful value until\n                                     the entire file is parsed and buffered. */\n    OMX_AUDIO_MIDIPLAYBACKSTATETYPE eMIDIPlayBackState;  /**< MIDI playback state enumeration, read only field */\n} OMX_AUDIO_CONFIG_MIDISTATUSTYPE;\n\n\n/** MIDI Meta Event structure one per Meta Event.\n *  MIDI Meta Events are like audio metadata, except that they are interspersed\n *  with the MIDI content throughout the file and are not localized in the header.\n *  As such, it is necessary to retrieve information about these Meta Events from\n *  the engine, as it encounters these Meta Events within the MIDI content.\n *  For example, SMF files can have up to 14 types of MIDI Meta Events (copyright,\n *  author, default tempo, etc.) scattered throughout the file.\n *  @ingroup midi\n */\ntypedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE{\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex;       /**< port that this structure applies to */\n    OMX_U32 nIndex;           /**< Index of Meta Event */\n    OMX_U8 nMetaEventType;    /**< Meta Event Type, 7bits (i.e. 0 - 127) */\n    OMX_U32 nMetaEventSize;   /**< size of the Meta Event in bytes */\n    OMX_U32 nTrack;           /**< track number for the meta event */\n    OMX_U32 nPosition;        /**< Position of the meta-event in milliseconds */\n} OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE;\n\n\n/** MIDI Meta Event Data structure - one per Meta Event.\n * @ingroup midi\n */\ntypedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE{\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex;       /**< port that this structure applies to */\n    OMX_U32 nIndex;           /**< Index of Meta Event */\n    OMX_U32 nMetaEventSize;   /**< size of the Meta Event in bytes */\n    OMX_U8 nData[1];          /**< array of one or more bytes of meta data\n                                   as indicated by the nMetaEventSize field */\n} OMX_AUDIO_CONFIG__MIDIMETAEVENTDATATYPE;\n\n\n/** Audio Volume adjustment for a port */\ntypedef struct OMX_AUDIO_CONFIG_VOLUMETYPE {\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_U32 nPortIndex;         /**< Port index indicating which port to\n                                     set.  Select the input port to set\n                                     just that port's volume.  Select the\n                                     output port to adjust the master\n                                     volume. */\n    OMX_BOOL bLinear;           /**< Is the volume to be set in linear (0.100)\n                                     or logarithmic scale (mB) */\n    OMX_BS32 sVolume;           /**< Volume linear setting in the 0..100 range, OR\n                                     Volume logarithmic setting for this port.  The values\n                                     for volume are in mB (millibels = 1/100 dB) relative\n                                     to a gain of 1 (e.g. the output is the same as the\n                                     input level).  Values are in mB from nMax\n                                     (maximum volume) to nMin mB (typically negative).\n                                     Since the volume is \"voltage\"\n                                     and not a \"power\", it takes a setting of\n                                     -600 mB to decrease the volume by 1/2.  If\n                                     a component cannot accurately set the\n                                     volume to the requested value, it must\n                                     set the volume to the closest value BELOW\n                                     the requested value.  When getting the\n                                     volume setting, the current actual volume\n                                     must be returned. */\n} OMX_AUDIO_CONFIG_VOLUMETYPE;\n\n\n/** Audio Volume adjustment for a channel */\ntypedef struct OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE {\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_U32 nPortIndex;         /**< Port index indicating which port to\n                                     set.  Select the input port to set\n                                     just that port's volume.  Select the\n                                     output port to adjust the master\n                                     volume. */\n    OMX_U32 nChannel;           /**< channel to select from 0 to N-1,\n                                     using OMX_ALL to apply volume settings\n                                     to all channels */\n    OMX_BOOL bLinear;           /**< Is the volume to be set in linear (0.100) or\n                                     logarithmic scale (mB) */\n    OMX_BS32 sVolume;           /**< Volume linear setting in the 0..100 range, OR\n                                     Volume logarithmic setting for this port.\n                                     The values for volume are in mB\n                                     (millibels = 1/100 dB) relative to a gain\n                                     of 1 (e.g. the output is the same as the\n                                     input level).  Values are in mB from nMax\n                                     (maximum volume) to nMin mB (typically negative).\n                                     Since the volume is \"voltage\"\n                                     and not a \"power\", it takes a setting of\n                                     -600 mB to decrease the volume by 1/2.  If\n                                     a component cannot accurately set the\n                                     volume to the requested value, it must\n                                     set the volume to the closest value BELOW\n                                     the requested value.  When getting the\n                                     volume setting, the current actual volume\n                                     must be returned. */\n    OMX_BOOL bIsMIDI;           /**< TRUE if nChannel refers to a MIDI channel,\n                                     FALSE otherwise */\n} OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE;\n\n\n/** Audio balance setting */\ntypedef struct OMX_AUDIO_CONFIG_BALANCETYPE {\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_U32 nPortIndex;         /**< Port index indicating which port to\n                                     set.  Select the input port to set\n                                     just that port's balance.  Select the\n                                     output port to adjust the master\n                                     balance. */\n    OMX_S32 nBalance;           /**< balance setting for this port\n                                     (-100 to 100, where -100 indicates\n                                     all left, and no right */\n} OMX_AUDIO_CONFIG_BALANCETYPE;\n\n\n/** Audio Port mute */\ntypedef struct OMX_AUDIO_CONFIG_MUTETYPE {\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_U32 nPortIndex;         /**< Port index indicating which port to\n                                     set.  Select the input port to set\n                                     just that port's mute.  Select the\n                                     output port to adjust the master\n                                     mute. */\n    OMX_BOOL bMute;             /**< Mute setting for this port */\n} OMX_AUDIO_CONFIG_MUTETYPE;\n\n\n/** Audio Channel mute */\ntypedef struct OMX_AUDIO_CONFIG_CHANNELMUTETYPE {\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_U32 nPortIndex;         /**< port that this structure applies to */\n    OMX_U32 nChannel;           /**< channel to select from 0 to N-1,\n                                     using OMX_ALL to apply mute settings\n                                     to all channels */\n    OMX_BOOL bMute;             /**< Mute setting for this channel */\n    OMX_BOOL bIsMIDI;           /**< TRUE if nChannel refers to a MIDI channel,\n                                     FALSE otherwise */\n} OMX_AUDIO_CONFIG_CHANNELMUTETYPE;\n\n\n\n/** Enable / Disable for loudness control, which boosts bass and to a\n *  smaller extent high end frequencies to compensate for hearing\n *  ability at the extreme ends of the audio spectrum\n */\ntypedef struct OMX_AUDIO_CONFIG_LOUDNESSTYPE {\n    OMX_U32 nSize;             /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */\n    OMX_U32 nPortIndex;        /**< port that this structure applies to */\n    OMX_BOOL bLoudness;        /**< Enable/disable for loudness */\n} OMX_AUDIO_CONFIG_LOUDNESSTYPE;\n\n\n/** Enable / Disable for bass, which controls low frequencies\n */\ntypedef struct OMX_AUDIO_CONFIG_BASSTYPE {\n    OMX_U32 nSize;             /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */\n    OMX_U32 nPortIndex;        /**< port that this structure applies to */\n    OMX_BOOL bEnable;          /**< Enable/disable for bass control */\n    OMX_S32 nBass;             /**< bass setting for the port, as a\n                                    continuous value from -100 to 100\n                                    (0 means no change in bass level)*/\n} OMX_AUDIO_CONFIG_BASSTYPE;\n\n\n/** Enable / Disable for treble, which controls high frequencies tones\n */\ntypedef struct OMX_AUDIO_CONFIG_TREBLETYPE {\n    OMX_U32 nSize;             /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */\n    OMX_U32 nPortIndex;        /**< port that this structure applies to */\n    OMX_BOOL bEnable;          /**< Enable/disable for treble control */\n    OMX_S32  nTreble;          /**< treble setting for the port, as a\n                                    continuous value from -100 to 100\n                                    (0 means no change in treble level) */\n} OMX_AUDIO_CONFIG_TREBLETYPE;\n\n\n/** An equalizer is typically used for two reasons: to compensate for an\n *  sub-optimal frequency response of a system to make it sound more natural\n *  or to create intentionally some unnatural coloring to the sound to create\n *  an effect.\n *  @ingroup effects\n */\ntypedef struct OMX_AUDIO_CONFIG_EQUALIZERTYPE {\n    OMX_U32 nSize;             /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */\n    OMX_U32 nPortIndex;        /**< port that this structure applies to */\n    OMX_BOOL bEnable;          /**< Enable/disable for equalizer */\n    OMX_BU32 sBandIndex;       /**< Band number to be set.  Upper Limit is\n                                    N-1, where N is the number of bands, lower limit is 0 */\n    OMX_BU32 sCenterFreq;      /**< Center frequecies in Hz.  This is a\n                                    read only element and is used to determine\n                                    the lower, center and upper frequency of\n                                    this band.  */\n    OMX_BS32 sBandLevel;       /**< band level in millibels */\n} OMX_AUDIO_CONFIG_EQUALIZERTYPE;\n\n\n/** Stereo widening mode type\n * @ingroup effects\n */\ntypedef enum OMX_AUDIO_STEREOWIDENINGTYPE {\n    OMX_AUDIO_StereoWideningHeadphones,    /**< Stereo widening for loudspeakers */\n    OMX_AUDIO_StereoWideningLoudspeakers,  /**< Stereo widening for closely spaced loudspeakers */\n    OMX_AUDIO_StereoWideningKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_AUDIO_StereoWideningVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_AUDIO_StereoWideningMax = 0x7FFFFFFF\n} OMX_AUDIO_STEREOWIDENINGTYPE;\n\n\n/** Control for stereo widening, which is a special 2-channel\n *  case of the audio virtualizer effect. For example, for 5.1-channel\n *  output, it translates to virtual surround sound.\n * @ingroup effects\n */\ntypedef struct OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE {\n    OMX_U32 nSize;             /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */\n    OMX_U32 nPortIndex;        /**< port that this structure applies to */\n    OMX_BOOL bEnable;          /**< Enable/disable for stereo widening control */\n    OMX_AUDIO_STEREOWIDENINGTYPE eWideningType; /**< Stereo widening algorithm type */\n    OMX_U32  nStereoWidening;  /**< stereo widening setting for the port,\n                                    as a continuous value from 0 to 100  */\n} OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE;\n\n\n/** The chorus effect (or ``choralizer'') is any signal processor which makes\n *  one sound source (such as a voice) sound like many such sources singing\n *  (or playing) in unison. Since performance in unison is never exact, chorus\n *  effects simulate this by making independently modified copies of the input\n *  signal. Modifications may include (1) delay, (2) frequency shift, and\n *  (3) amplitude modulation.\n * @ingroup effects\n */\ntypedef struct OMX_AUDIO_CONFIG_CHORUSTYPE {\n    OMX_U32 nSize;             /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */\n    OMX_U32 nPortIndex;        /**< port that this structure applies to */\n    OMX_BOOL bEnable;          /**< Enable/disable for chorus */\n    OMX_BU32 sDelay;           /**< average delay in milliseconds */\n    OMX_BU32 sModulationRate;  /**< rate of modulation in millihertz */\n    OMX_U32 nModulationDepth;  /**< depth of modulation as a percentage of\n                                    delay (i.e. 0 to 100) */\n    OMX_BU32 nFeedback;        /**< Feedback from chorus output to input in percentage */\n} OMX_AUDIO_CONFIG_CHORUSTYPE;\n\n\n/** Reverberation is part of the reflected sound that follows the early\n *  reflections. In a typical room, this consists of a dense succession of\n *  echoes whose energy decays exponentially. The reverberation effect structure\n *  as defined here includes both (early) reflections as well as (late) reverberations.\n * @ingroup effects\n */\ntypedef struct OMX_AUDIO_CONFIG_REVERBERATIONTYPE {\n    OMX_U32 nSize;                /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */\n    OMX_U32 nPortIndex;           /**< port that this structure applies to */\n    OMX_BOOL bEnable;             /**< Enable/disable for reverberation control */\n    OMX_BS32 sRoomLevel;          /**< Intensity level for the whole room effect\n                                       (i.e. both early reflections and late\n                                       reverberation) in millibels */\n    OMX_BS32 sRoomHighFreqLevel;  /**< Attenuation at high frequencies\n                                       relative to the intensity at low\n                                       frequencies in millibels */\n    OMX_BS32 sReflectionsLevel;   /**< Intensity level of early reflections\n                                       (relative to room value), in millibels */\n    OMX_BU32 sReflectionsDelay;   /**< Delay time of the first reflection relative\n                                       to the direct path, in milliseconds */\n    OMX_BS32 sReverbLevel;        /**< Intensity level of late reverberation\n                                       relative to room level, in millibels */\n    OMX_BU32 sReverbDelay;        /**< Time delay from the first early reflection\n                                       to the beginning of the late reverberation\n                                       section, in milliseconds */\n    OMX_BU32 sDecayTime;          /**< Late reverberation decay time at low\n                                       frequencies, in milliseconds */\n    OMX_BU32 nDecayHighFreqRatio; /**< Ratio of high frequency decay time relative\n                                       to low frequency decay time in percent  */\n    OMX_U32 nDensity;             /**< Modal density in the late reverberation decay,\n                                       in percent (i.e. 0 - 100) */\n    OMX_U32 nDiffusion;           /**< Echo density in the late reverberation decay,\n                                       in percent (i.e. 0 - 100) */\n    OMX_BU32 sReferenceHighFreq;  /**< Reference high frequency in Hertz. This is\n                                       the frequency used as the reference for all\n                                       the high-frequency settings above */\n\n} OMX_AUDIO_CONFIG_REVERBERATIONTYPE;\n\n\n/** Possible settings for the Echo Cancelation structure to use\n * @ingroup effects\n */\ntypedef enum OMX_AUDIO_ECHOCANTYPE {\n   OMX_AUDIO_EchoCanOff = 0,    /**< Echo Cancellation is disabled */\n   OMX_AUDIO_EchoCanNormal,     /**< Echo Cancellation normal operation -\n                                     echo from plastics and face */\n   OMX_AUDIO_EchoCanHFree,      /**< Echo Cancellation optimized for\n                                     Hands Free operation */\n   OMX_AUDIO_EchoCanCarKit,    /**< Echo Cancellation optimized for\n                                     Car Kit (longer echo) */\n   OMX_AUDIO_EchoCanKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n   OMX_AUDIO_EchoCanVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n   OMX_AUDIO_EchoCanMax = 0x7FFFFFFF\n} OMX_AUDIO_ECHOCANTYPE;\n\n\n/** Enable / Disable for echo cancelation, which removes undesired echo's\n *  from the audio\n * @ingroup effects\n */\ntypedef struct OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE {\n    OMX_U32 nSize;             /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */\n    OMX_U32 nPortIndex;        /**< port that this structure applies to */\n    OMX_AUDIO_ECHOCANTYPE eEchoCancelation; /**< Echo cancelation settings */\n} OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE;\n\n\n/** Enable / Disable for noise reduction, which undesired noise from\n * the audio\n * @ingroup effects\n */\ntypedef struct OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE {\n    OMX_U32 nSize;             /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */\n    OMX_U32 nPortIndex;        /**< port that this structure applies to */\n    OMX_BOOL bNoiseReduction;  /**< Enable/disable for noise reduction */\n} OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE;\n\n/** @} */\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n/* File EOF */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/openmax/OMX_AudioExt.h",
    "content": "/*\n * Copyright (c) 2010 The Khronos Group Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject\n * to the following conditions:\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n/** OMX_AudioExt.h - OpenMax IL version 1.1.2\n * The OMX_AudioExt header file contains extensions to the\n * definitions used by both the application and the component to\n * access video items.\n */\n\n#ifndef OMX_AudioExt_h\n#define OMX_AudioExt_h\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/* Each OMX header shall include all required header files to allow the\n * header to compile without errors.  The includes below are required\n * for this header file to compile successfully\n */\n#include <OMX_Core.h>\n\n#define OMX_AUDIO_AACToolAndroidSSBR (OMX_AUDIO_AACToolVendor << 0) /**< SSBR: MPEG-4 Single-rate (downsampled) Spectral Band Replication tool allowed or active */\n#define OMX_AUDIO_AACToolAndroidDSBR (OMX_AUDIO_AACToolVendor << 1) /**< DSBR: MPEG-4 Dual-rate Spectral Band Replication tool allowed or active */\n\ntypedef enum OMX_AUDIO_CODINGEXTTYPE {\n    OMX_AUDIO_CodingAndroidUnused = OMX_AUDIO_CodingKhronosExtensions + 0x00100000,\n    OMX_AUDIO_CodingAndroidAC3,         /**< AC3 encoded data */\n    OMX_AUDIO_CodingAndroidOPUS,        /**< OPUS encoded data */\n    OMX_AUDIO_CodingAndroidEAC3,        /**< EAC3 encoded data */\n} OMX_AUDIO_CODINGEXTTYPE;\n\ntypedef struct OMX_AUDIO_PARAM_ANDROID_AC3TYPE {\n    OMX_U32 nSize;                 /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */\n    OMX_U32 nPortIndex;            /**< port that this structure applies to */\n    OMX_U32 nChannels;             /**< Number of channels */\n    OMX_U32 nSampleRate;           /**< Sampling rate of the source data.  Use 0 for\n                                        variable or unknown sampling rate. */\n} OMX_AUDIO_PARAM_ANDROID_AC3TYPE;\n\ntypedef struct OMX_AUDIO_PARAM_ANDROID_EAC3TYPE {\n    OMX_U32 nSize;                 /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */\n    OMX_U32 nPortIndex;            /**< port that this structure applies to */\n    OMX_U32 nChannels;             /**< Number of channels */\n    OMX_U32 nSampleRate;           /**< Sampling rate of the source data.  Use 0 for\n                                        variable or unknown sampling rate. */\n} OMX_AUDIO_PARAM_ANDROID_EAC3TYPE;\n\ntypedef struct OMX_AUDIO_PARAM_ANDROID_OPUSTYPE {\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex;       /**< port that this structure applies to */\n    OMX_U32 nChannels;        /**< Number of channels */\n    OMX_U32 nBitRate;         /**< Bit rate of the encoded data data.  Use 0 for variable\n                                   rate or unknown bit rates. Encoding is set to the\n                                   bitrate closest to specified  value (in bps) */\n    OMX_U32 nSampleRate;      /**< Sampling rate of the source data.  Use 0 for\n                                   variable or unknown sampling rate. */\n    OMX_U32 nAudioBandWidth;  /**< Audio band width (in Hz) to which an encoder should\n                                   limit the audio signal. Use 0 to let encoder decide */\n} OMX_AUDIO_PARAM_ANDROID_OPUSTYPE;\n\ntypedef struct OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE {\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_S32 nMaxOutputChannels;    /**< Maximum channel count to be output, -1 if unspecified, 0 if downmixing disabled */\n    OMX_S32 nDrcCut;               /**< The DRC attenuation factor, between 0 and 127, -1 if unspecified */\n    OMX_S32 nDrcBoost;             /**< The DRC amplification factor, between 0 and 127, -1 if unspecified */\n    OMX_S32 nHeavyCompression;     /**< 0 for light compression, 1 for heavy compression, -1 if unspecified */\n    OMX_S32 nTargetReferenceLevel; /**< Target reference level, between 0 and 127, -1 if unspecified */\n    OMX_S32 nEncodedTargetLevel;   /**< Target reference level assumed at the encoder, between 0 and 127, -1 if unspecified */\n    OMX_S32 nPCMLimiterEnable;     /**< Signal level limiting, 0 for disable, 1 for enable, -1 if unspecified */\n} OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE;\n\ntypedef struct OMX_AUDIO_PARAM_ANDROID_PROFILETYPE {\n   OMX_U32 nSize;\n   OMX_VERSIONTYPE nVersion;\n   OMX_U32 nPortIndex;\n   OMX_U32 eProfile;      /**< type is OMX_AUDIO_AACPROFILETYPE or OMX_AUDIO_WMAPROFILETYPE\n                                 depending on context */\n   OMX_U32 nProfileIndex; /**< Used to query for individual profile support information */\n} OMX_AUDIO_PARAM_ANDROID_PROFILETYPE;\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* OMX_AudioExt_h */\n/* File EOF */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/openmax/OMX_Component.h",
    "content": "/* ------------------------------------------------------------------\n * Copyright (C) 1998-2009 PacketVideo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n * express or implied.\n * See the License for the specific language governing permissions\n * and limitations under the License.\n * -------------------------------------------------------------------\n */\n/*\n * Copyright (c) 2008 The Khronos Group Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject\n * to the following conditions:\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n/** OMX_Component.h - OpenMax IL version 1.1.2\n *  The OMX_Component header file contains the definitions used to define\n *  the public interface of a component.  This header file is intended to\n *  be used by both the application and the component.\n */\n\n#ifndef OMX_Component_h\n#define OMX_Component_h\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n\n\n/* Each OMX header must include all required header files to allow the\n *  header to compile without errors.  The includes below are required\n *  for this header file to compile successfully\n */\n\n#include <OMX_Audio.h>\n#include <OMX_Video.h>\n#include <OMX_Image.h>\n#include <OMX_Other.h>\n\n/** @ingroup comp */\ntypedef enum OMX_PORTDOMAINTYPE {\n    OMX_PortDomainAudio,\n    OMX_PortDomainVideo,\n    OMX_PortDomainImage,\n    OMX_PortDomainOther,\n    OMX_PortDomainKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_PortDomainVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_PortDomainMax = 0x7ffffff\n} OMX_PORTDOMAINTYPE;\n\n/** @ingroup comp */\ntypedef struct OMX_PARAM_PORTDEFINITIONTYPE {\n    OMX_U32 nSize;                 /**< Size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */\n    OMX_U32 nPortIndex;            /**< Port number the structure applies to */\n    OMX_DIRTYPE eDir;              /**< Direction (input or output) of this port */\n    OMX_U32 nBufferCountActual;    /**< The actual number of buffers allocated on this port */\n    OMX_U32 nBufferCountMin;       /**< The minimum number of buffers this port requires */\n    OMX_U32 nBufferSize;           /**< Size, in bytes, for buffers to be used for this channel */\n    OMX_BOOL bEnabled;             /**< Ports default to enabled and are enabled/disabled by\n                                        OMX_CommandPortEnable/OMX_CommandPortDisable.\n                                        When disabled a port is unpopulated. A disabled port\n                                        is not populated with buffers on a transition to IDLE. */\n    OMX_BOOL bPopulated;           /**< Port is populated with all of its buffers as indicated by\n                                        nBufferCountActual. A disabled port is always unpopulated.\n                                        An enabled port is populated on a transition to OMX_StateIdle\n                                        and unpopulated on a transition to loaded. */\n    OMX_PORTDOMAINTYPE eDomain;    /**< Domain of the port. Determines the contents of metadata below. */\n    union {\n        OMX_AUDIO_PORTDEFINITIONTYPE audio;\n        OMX_VIDEO_PORTDEFINITIONTYPE video;\n        OMX_IMAGE_PORTDEFINITIONTYPE image;\n        OMX_OTHER_PORTDEFINITIONTYPE other;\n    } format;\n    OMX_BOOL bBuffersContiguous;\n    OMX_U32 nBufferAlignment;\n} OMX_PARAM_PORTDEFINITIONTYPE;\n\n/** @ingroup comp */\ntypedef struct OMX_PARAM_U32TYPE {\n    OMX_U32 nSize;                    /**< Size of this structure, in Bytes */\n    OMX_VERSIONTYPE nVersion;         /**< OMX specification version information */\n    OMX_U32 nPortIndex;               /**< port that this structure applies to */\n    OMX_U32 nU32;                     /**< U32 value */\n} OMX_PARAM_U32TYPE;\n\n/** @ingroup rpm */\ntypedef enum OMX_SUSPENSIONPOLICYTYPE {\n    OMX_SuspensionDisabled, /**< No suspension; v1.0 behavior */\n    OMX_SuspensionEnabled,  /**< Suspension allowed */\n    OMX_SuspensionPolicyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_SuspensionPolicyStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_SuspensionPolicyMax = 0x7fffffff\n} OMX_SUSPENSIONPOLICYTYPE;\n\n/** @ingroup rpm */\ntypedef struct OMX_PARAM_SUSPENSIONPOLICYTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_SUSPENSIONPOLICYTYPE ePolicy;\n} OMX_PARAM_SUSPENSIONPOLICYTYPE;\n\n/** @ingroup rpm */\ntypedef enum OMX_SUSPENSIONTYPE {\n    OMX_NotSuspended, /**< component is not suspended */\n    OMX_Suspended,    /**< component is suspended */\n    OMX_SuspensionKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_SuspensionVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_SuspendMax = 0x7FFFFFFF\n} OMX_SUSPENSIONTYPE;\n\n/** @ingroup rpm */\ntypedef struct OMX_PARAM_SUSPENSIONTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_SUSPENSIONTYPE eType;\n} OMX_PARAM_SUSPENSIONTYPE ;\n\ntypedef struct OMX_CONFIG_BOOLEANTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_BOOL bEnabled;\n} OMX_CONFIG_BOOLEANTYPE;\n\n/* Parameter specifying the content uri to use. */\n/** @ingroup cp */\ntypedef struct OMX_PARAM_CONTENTURITYPE\n{\n    OMX_U32 nSize;                      /**< size of the structure in bytes, including\n                                             actual URI name */\n    OMX_VERSIONTYPE nVersion;           /**< OMX specification version information */\n    OMX_U8 contentURI[1];               /**< The URI name */\n} OMX_PARAM_CONTENTURITYPE;\n\n/* Parameter specifying the pipe to use. */\n/** @ingroup cp */\ntypedef struct OMX_PARAM_CONTENTPIPETYPE\n{\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_HANDLETYPE hPipe;       /**< The pipe handle*/\n} OMX_PARAM_CONTENTPIPETYPE;\n\n/** @ingroup rpm */\ntypedef struct OMX_RESOURCECONCEALMENTTYPE {\n    OMX_U32 nSize;             /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */\n    OMX_BOOL bResourceConcealmentForbidden; /**< disallow the use of resource concealment\n                                            methods (like degrading algorithm quality to\n                                            lower resource consumption or functional bypass)\n                                            on a component as a resolution to resource conflicts. */\n} OMX_RESOURCECONCEALMENTTYPE;\n\n\n/** @ingroup metadata */\ntypedef enum OMX_METADATACHARSETTYPE {\n    OMX_MetadataCharsetUnknown = 0,\n    OMX_MetadataCharsetASCII,\n    OMX_MetadataCharsetBinary,\n    OMX_MetadataCharsetCodePage1252,\n    OMX_MetadataCharsetUTF8,\n    OMX_MetadataCharsetJavaConformantUTF8,\n    OMX_MetadataCharsetUTF7,\n    OMX_MetadataCharsetImapUTF7,\n    OMX_MetadataCharsetUTF16LE,\n    OMX_MetadataCharsetUTF16BE,\n    OMX_MetadataCharsetGB12345,\n    OMX_MetadataCharsetHZGB2312,\n    OMX_MetadataCharsetGB2312,\n    OMX_MetadataCharsetGB18030,\n    OMX_MetadataCharsetGBK,\n    OMX_MetadataCharsetBig5,\n    OMX_MetadataCharsetISO88591,\n    OMX_MetadataCharsetISO88592,\n    OMX_MetadataCharsetISO88593,\n    OMX_MetadataCharsetISO88594,\n    OMX_MetadataCharsetISO88595,\n    OMX_MetadataCharsetISO88596,\n    OMX_MetadataCharsetISO88597,\n    OMX_MetadataCharsetISO88598,\n    OMX_MetadataCharsetISO88599,\n    OMX_MetadataCharsetISO885910,\n    OMX_MetadataCharsetISO885913,\n    OMX_MetadataCharsetISO885914,\n    OMX_MetadataCharsetISO885915,\n    OMX_MetadataCharsetShiftJIS,\n    OMX_MetadataCharsetISO2022JP,\n    OMX_MetadataCharsetISO2022JP1,\n    OMX_MetadataCharsetISOEUCJP,\n    OMX_MetadataCharsetSMS7Bit,\n    OMX_MetadataCharsetKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_MetadataCharsetVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_MetadataCharsetTypeMax= 0x7FFFFFFF\n} OMX_METADATACHARSETTYPE;\n\n/** @ingroup metadata */\ntypedef enum OMX_METADATASCOPETYPE\n{\n    OMX_MetadataScopeAllLevels,\n    OMX_MetadataScopeTopLevel,\n    OMX_MetadataScopePortLevel,\n    OMX_MetadataScopeNodeLevel,\n    OMX_MetadataScopeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_MetadataScopeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_MetadataScopeTypeMax = 0x7fffffff\n} OMX_METADATASCOPETYPE;\n\n/** @ingroup metadata */\ntypedef enum OMX_METADATASEARCHMODETYPE\n{\n    OMX_MetadataSearchValueSizeByIndex,\n    OMX_MetadataSearchItemByIndex,\n    OMX_MetadataSearchNextItemByKey,\n    OMX_MetadataSearchKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_MetadataSearchVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_MetadataSearchTypeMax = 0x7fffffff\n} OMX_METADATASEARCHMODETYPE;\n/** @ingroup metadata */\ntypedef struct OMX_CONFIG_METADATAITEMCOUNTTYPE\n{\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_METADATASCOPETYPE eScopeMode;\n    OMX_U32 nScopeSpecifier;\n    OMX_U32 nMetadataItemCount;\n} OMX_CONFIG_METADATAITEMCOUNTTYPE;\n\n/** @ingroup metadata */\ntypedef struct OMX_CONFIG_METADATAITEMTYPE\n{\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_METADATASCOPETYPE eScopeMode;\n    OMX_U32 nScopeSpecifier;\n    OMX_U32 nMetadataItemIndex;\n    OMX_METADATASEARCHMODETYPE eSearchMode;\n    OMX_METADATACHARSETTYPE eKeyCharset;\n    OMX_U8 nKeySizeUsed;\n    OMX_U8 nKey[128];\n    OMX_METADATACHARSETTYPE eValueCharset;\n    OMX_STRING sLanguageCountry;\n    OMX_U32 nValueMaxSize;\n    OMX_U32 nValueSizeUsed;\n    OMX_U8 nValue[1];\n} OMX_CONFIG_METADATAITEMTYPE;\n\n/* @ingroup metadata */\ntypedef struct OMX_CONFIG_CONTAINERNODECOUNTTYPE\n{\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_BOOL bAllKeys;\n    OMX_U32 nParentNodeID;\n    OMX_U32 nNumNodes;\n} OMX_CONFIG_CONTAINERNODECOUNTTYPE;\n\n/** @ingroup metadata */\ntypedef struct OMX_CONFIG_CONTAINERNODEIDTYPE\n{\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_BOOL bAllKeys;\n    OMX_U32 nParentNodeID;\n    OMX_U32 nNodeIndex;\n    OMX_U32 nNodeID;\n    OMX_STRING cNodeName;\n    OMX_BOOL bIsLeafType;\n} OMX_CONFIG_CONTAINERNODEIDTYPE;\n\n/** @ingroup metadata */\ntypedef struct OMX_PARAM_METADATAFILTERTYPE\n{\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_BOOL bAllKeys;  /* if true then this structure refers to all keys and\n                         * the three key fields below are ignored */\n    OMX_METADATACHARSETTYPE eKeyCharset;\n    OMX_U32 nKeySizeUsed;\n    OMX_U8   nKey [128];\n    OMX_U32 nLanguageCountrySizeUsed;\n    OMX_U8 nLanguageCountry[128];\n    OMX_BOOL bEnabled;  /* if true then key is part of filter (e.g.\n                         * retained for query later). If false then\n                         * key is not part of filter */\n} OMX_PARAM_METADATAFILTERTYPE;\n\n/** The OMX_HANDLETYPE structure defines the component handle.  The component\n *  handle is used to access all of the component's public methods and also\n *  contains pointers to the component's private data area.  The component\n *  handle is initialized by the OMX core (with help from the component)\n *  during the process of loading the component.  After the component is\n *  successfully loaded, the application can safely access any of the\n *  component's public functions (although some may return an error because\n *  the state is inappropriate for the access).\n *\n *  @ingroup comp\n */\ntypedef struct OMX_COMPONENTTYPE\n{\n    /** The size of this structure, in bytes.  It is the responsibility\n        of the allocator of this structure to fill in this value.  Since\n        this structure is allocated by the GetHandle function, this\n        function will fill in this value. */\n    OMX_U32 nSize;\n\n    /** nVersion is the version of the OMX specification that the structure\n        is built against.  It is the responsibility of the creator of this\n        structure to initialize this value and every user of this structure\n        should verify that it knows how to use the exact version of\n        this structure found herein. */\n    OMX_VERSIONTYPE nVersion;\n\n    /** pComponentPrivate is a pointer to the component private data area.\n        This member is allocated and initialized by the component when the\n        component is first loaded.  The application should not access this\n        data area. */\n    OMX_PTR pComponentPrivate;\n\n    /** pApplicationPrivate is a pointer that is a parameter to the\n        OMX_GetHandle method, and contains an application private value\n        provided by the IL client.  This application private data is\n        returned to the IL Client by OMX in all callbacks */\n    OMX_PTR pApplicationPrivate;\n\n    /** refer to OMX_GetComponentVersion in OMX_core.h or the OMX IL\n        specification for details on the GetComponentVersion method.\n     */\n    OMX_ERRORTYPE (*GetComponentVersion)(\n            OMX_IN  OMX_HANDLETYPE hComponent,\n            OMX_OUT OMX_STRING pComponentName,\n            OMX_OUT OMX_VERSIONTYPE* pComponentVersion,\n            OMX_OUT OMX_VERSIONTYPE* pSpecVersion,\n            OMX_OUT OMX_UUIDTYPE* pComponentUUID);\n\n    /** refer to OMX_SendCommand in OMX_core.h or the OMX IL\n        specification for details on the SendCommand method.\n     */\n    OMX_ERRORTYPE (*SendCommand)(\n            OMX_IN  OMX_HANDLETYPE hComponent,\n            OMX_IN  OMX_COMMANDTYPE Cmd,\n            OMX_IN  OMX_U32 nParam1,\n            OMX_IN  OMX_PTR pCmdData);\n\n    /** refer to OMX_GetParameter in OMX_core.h or the OMX IL\n        specification for details on the GetParameter method.\n     */\n    OMX_ERRORTYPE (*GetParameter)(\n            OMX_IN  OMX_HANDLETYPE hComponent,\n            OMX_IN  OMX_INDEXTYPE nParamIndex,\n            OMX_INOUT OMX_PTR pComponentParameterStructure);\n\n\n    /** refer to OMX_SetParameter in OMX_core.h or the OMX IL\n        specification for details on the SetParameter method.\n     */\n    OMX_ERRORTYPE (*SetParameter)(\n            OMX_IN  OMX_HANDLETYPE hComponent,\n            OMX_IN  OMX_INDEXTYPE nIndex,\n            OMX_IN  OMX_PTR pComponentParameterStructure);\n\n\n    /** refer to OMX_GetConfig in OMX_core.h or the OMX IL\n        specification for details on the GetConfig method.\n     */\n    OMX_ERRORTYPE (*GetConfig)(\n            OMX_IN  OMX_HANDLETYPE hComponent,\n            OMX_IN  OMX_INDEXTYPE nIndex,\n            OMX_INOUT OMX_PTR pComponentConfigStructure);\n\n\n    /** refer to OMX_SetConfig in OMX_core.h or the OMX IL\n        specification for details on the SetConfig method.\n     */\n    OMX_ERRORTYPE (*SetConfig)(\n            OMX_IN  OMX_HANDLETYPE hComponent,\n            OMX_IN  OMX_INDEXTYPE nIndex,\n            OMX_IN  OMX_PTR pComponentConfigStructure);\n\n\n    /** refer to OMX_GetExtensionIndex in OMX_core.h or the OMX IL\n        specification for details on the GetExtensionIndex method.\n     */\n    OMX_ERRORTYPE (*GetExtensionIndex)(\n            OMX_IN  OMX_HANDLETYPE hComponent,\n            OMX_IN  OMX_STRING cParameterName,\n            OMX_OUT OMX_INDEXTYPE* pIndexType);\n\n\n    /** refer to OMX_GetState in OMX_core.h or the OMX IL\n        specification for details on the GetState method.\n     */\n    OMX_ERRORTYPE (*GetState)(\n            OMX_IN  OMX_HANDLETYPE hComponent,\n            OMX_OUT OMX_STATETYPE* pState);\n\n\n    /** The ComponentTunnelRequest method will interact with another OMX\n        component to determine if tunneling is possible and to setup the\n        tunneling.  The return codes for this method can be used to\n        determine if tunneling is not possible, or if tunneling is not\n        supported.\n\n        Base profile components (i.e. non-interop) do not support this\n        method and should return OMX_ErrorNotImplemented\n\n        The interop profile component MUST support tunneling to another\n        interop profile component with a compatible port parameters.\n        A component may also support proprietary communication.\n\n        If proprietary communication is supported the negotiation of\n        proprietary communication is done outside of OMX in a vendor\n        specific way. It is only required that the proper result be\n        returned and the details of how the setup is done is left\n        to the component implementation.\n\n        When this method is invoked when nPort in an output port, the\n        component will:\n        1.  Populate the pTunnelSetup structure with the output port's\n            requirements and constraints for the tunnel.\n\n        When this method is invoked when nPort in an input port, the\n        component will:\n        1.  Query the necessary parameters from the output port to\n            determine if the ports are compatible for tunneling\n        2.  If the ports are compatible, the component should store\n            the tunnel step provided by the output port\n        3.  Determine which port (either input or output) is the buffer\n            supplier, and call OMX_SetParameter on the output port to\n            indicate this selection.\n\n        The component will return from this call within 5 msec.\n\n        @param [in] hComp\n            Handle of the component to be accessed.  This is the component\n            handle returned by the call to the OMX_GetHandle method.\n        @param [in] nPort\n            nPort is used to select the port on the component to be used\n            for tunneling.\n        @param [in] hTunneledComp\n            Handle of the component to tunnel with.  This is the component\n            handle returned by the call to the OMX_GetHandle method.  When\n            this parameter is 0x0 the component should setup the port for\n            communication with the application / IL Client.\n        @param [in] nPortOutput\n            nPortOutput is used indicate the port the component should\n            tunnel with.\n        @param [in] pTunnelSetup\n            Pointer to the tunnel setup structure.  When nPort is an output port\n            the component should populate the fields of this structure.  When\n            When nPort is an input port the component should review the setup\n            provided by the component with the output port.\n        @return OMX_ERRORTYPE\n            If the command successfully executes, the return code will be\n            OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n        @ingroup tun\n    */\n\n    OMX_ERRORTYPE (*ComponentTunnelRequest)(\n        OMX_IN  OMX_HANDLETYPE hComp,\n        OMX_IN  OMX_U32 nPort,\n        OMX_IN  OMX_HANDLETYPE hTunneledComp,\n        OMX_IN  OMX_U32 nTunneledPort,\n        OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup);\n\n    /** refer to OMX_UseBuffer in OMX_core.h or the OMX IL\n        specification for details on the UseBuffer method.\n        @ingroup buf\n     */\n    OMX_ERRORTYPE (*UseBuffer)(\n            OMX_IN OMX_HANDLETYPE hComponent,\n            OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,\n            OMX_IN OMX_U32 nPortIndex,\n            OMX_IN OMX_PTR pAppPrivate,\n            OMX_IN OMX_U32 nSizeBytes,\n            OMX_IN OMX_U8* pBuffer);\n\n    /** refer to OMX_AllocateBuffer in OMX_core.h or the OMX IL\n        specification for details on the AllocateBuffer method.\n        @ingroup buf\n     */\n    OMX_ERRORTYPE (*AllocateBuffer)(\n            OMX_IN OMX_HANDLETYPE hComponent,\n            OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer,\n            OMX_IN OMX_U32 nPortIndex,\n            OMX_IN OMX_PTR pAppPrivate,\n            OMX_IN OMX_U32 nSizeBytes);\n\n    /** refer to OMX_FreeBuffer in OMX_core.h or the OMX IL\n        specification for details on the FreeBuffer method.\n        @ingroup buf\n     */\n    OMX_ERRORTYPE (*FreeBuffer)(\n            OMX_IN  OMX_HANDLETYPE hComponent,\n            OMX_IN  OMX_U32 nPortIndex,\n            OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);\n\n    /** refer to OMX_EmptyThisBuffer in OMX_core.h or the OMX IL\n        specification for details on the EmptyThisBuffer method.\n        @ingroup buf\n     */\n    OMX_ERRORTYPE (*EmptyThisBuffer)(\n            OMX_IN  OMX_HANDLETYPE hComponent,\n            OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);\n\n    /** refer to OMX_FillThisBuffer in OMX_core.h or the OMX IL\n        specification for details on the FillThisBuffer method.\n        @ingroup buf\n     */\n    OMX_ERRORTYPE (*FillThisBuffer)(\n            OMX_IN  OMX_HANDLETYPE hComponent,\n            OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);\n\n    /** The SetCallbacks method is used by the core to specify the callback\n        structure from the application to the component.  This is a blocking\n        call.  The component will return from this call within 5 msec.\n        @param [in] hComponent\n            Handle of the component to be accessed.  This is the component\n            handle returned by the call to the GetHandle function.\n        @param [in] pCallbacks\n            pointer to an OMX_CALLBACKTYPE structure used to provide the\n            callback information to the component\n        @param [in] pAppData\n            pointer to an application defined value.  It is anticipated that\n            the application will pass a pointer to a data structure or a \"this\n            pointer\" in this area to allow the callback (in the application)\n            to determine the context of the call\n        @return OMX_ERRORTYPE\n            If the command successfully executes, the return code will be\n            OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n     */\n    OMX_ERRORTYPE (*SetCallbacks)(\n            OMX_IN  OMX_HANDLETYPE hComponent,\n            OMX_IN  OMX_CALLBACKTYPE* pCallbacks,\n            OMX_IN  OMX_PTR pAppData);\n\n    /** ComponentDeInit method is used to deinitialize the component\n        providing a means to free any resources allocated at component\n        initialization.  NOTE:  After this call the component handle is\n        not valid for further use.\n        @param [in] hComponent\n            Handle of the component to be accessed.  This is the component\n            handle returned by the call to the GetHandle function.\n        @return OMX_ERRORTYPE\n            If the command successfully executes, the return code will be\n            OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n     */\n    OMX_ERRORTYPE (*ComponentDeInit)(\n            OMX_IN  OMX_HANDLETYPE hComponent);\n\n    /** @ingroup buf */\n    OMX_ERRORTYPE (*UseEGLImage)(\n            OMX_IN OMX_HANDLETYPE hComponent,\n            OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,\n            OMX_IN OMX_U32 nPortIndex,\n            OMX_IN OMX_PTR pAppPrivate,\n            OMX_IN void* eglImage);\n\n    OMX_ERRORTYPE (*ComponentRoleEnum)(\n        OMX_IN OMX_HANDLETYPE hComponent,\n        OMX_OUT OMX_U8 *cRole,\n        OMX_IN OMX_U32 nIndex);\n\n} OMX_COMPONENTTYPE;\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n/* File EOF */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/openmax/OMX_ContentPipe.h",
    "content": "/* ------------------------------------------------------------------\n * Copyright (C) 1998-2009 PacketVideo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n * express or implied.\n * See the License for the specific language governing permissions\n * and limitations under the License.\n * -------------------------------------------------------------------\n */\n/*\n * Copyright (c) 2008 The Khronos Group Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject\n * to the following conditions:\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n/** OMX_ContentPipe.h - OpenMax IL version 1.1.2\n *  The OMX_ContentPipe header file contains the definitions used to define\n *  the public interface for content piples.  This header file is intended to\n *  be used by the component.\n */\n\n#ifndef OMX_CONTENTPIPE_H\n#define OMX_CONTENTPIPE_H\n\n#ifndef KD_EACCES\n/* OpenKODE error codes. CPResult values may be zero (indicating success\n   or one of the following values) */\n#define KD_EACCES (1)\n#define KD_EADDRINUSE (2)\n#define KD_EAGAIN (5)\n#define KD_EBADF (7)\n#define KD_EBUSY (8)\n#define KD_ECONNREFUSED (9)\n#define KD_ECONNRESET (10)\n#define KD_EDEADLK (11)\n#define KD_EDESTADDRREQ (12)\n#define KD_ERANGE (35)\n#define KD_EEXIST (13)\n#define KD_EFBIG (14)\n#define KD_EHOSTUNREACH (15)\n#define KD_EINVAL (17)\n#define KD_EIO (18)\n#define KD_EISCONN (20)\n#define KD_EISDIR (21)\n#define KD_EMFILE (22)\n#define KD_ENAMETOOLONG (23)\n#define KD_ENOENT (24)\n#define KD_ENOMEM (25)\n#define KD_ENOSPC (26)\n#define KD_ENOSYS (27)\n#define KD_ENOTCONN (28)\n#define KD_EPERM (33)\n#define KD_ETIMEDOUT (36)\n#define KD_EILSEQ (19)\n#endif\n\n/** Map types from OMX standard types only here so interface is as generic as possible. */\ntypedef OMX_U32    CPresult;\ntypedef char *     CPstring;\ntypedef void *     CPhandle;\ntypedef OMX_U32    CPuint;\ntypedef OMX_S32    CPint;\ntypedef char       CPbyte;\ntypedef OMX_BOOL   CPbool;\n\n/** enumeration of origin types used in the CP_PIPETYPE's Seek function\n * @ingroup cp\n */\ntypedef enum CP_ORIGINTYPE {\n    CP_OriginBegin,\n    CP_OriginCur,\n    CP_OriginEnd,\n    CP_OriginKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    CP_OriginVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    CP_OriginMax = 0X7FFFFFFF\n} CP_ORIGINTYPE;\n\n/** enumeration of contact access types used in the CP_PIPETYPE's Open function\n * @ingroup cp\n */\ntypedef enum CP_ACCESSTYPE {\n    CP_AccessRead,\n    CP_AccessWrite,\n    CP_AccessReadWrite,\n    CP_AccessKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    CP_AccessVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    CP_AccessMax = 0X7FFFFFFF\n} CP_ACCESSTYPE;\n\n/** enumeration of results returned by the CP_PIPETYPE's CheckAvailableBytes function\n * @ingroup cp\n */\ntypedef enum CP_CHECKBYTESRESULTTYPE\n{\n    CP_CheckBytesOk,                    /**< There are at least the request number\n                                              of bytes available */\n    CP_CheckBytesNotReady,              /**< The pipe is still retrieving bytes\n                                              and presently lacks sufficient bytes.\n                                              Client will be called when they are\n                                              sufficient bytes are available. */\n    CP_CheckBytesInsufficientBytes,     /**< The pipe has retrieved all bytes\n                                              but those available are less than those\n                                              requested */\n    CP_CheckBytesAtEndOfStream,         /**< The pipe has reached the end of stream\n                                              and no more bytes are available. */\n    CP_CheckBytesOutOfBuffers,          /**< All read/write buffers are currently in use. */\n    CP_CheckBytesKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    CP_CheckBytesVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    CP_CheckBytesMax = 0X7FFFFFFF\n} CP_CHECKBYTESRESULTTYPE;\n\n/** enumeration of content pipe events sent to the client callback.\n * @ingroup cp\n */\ntypedef enum CP_EVENTTYPE{\n    CP_BytesAvailable,                      /** bytes requested in a CheckAvailableBytes call are now available*/\n    CP_Overflow,                            /** enumeration of content pipe events sent to the client callback*/\n    CP_PipeDisconnected,                    /** enumeration of content pipe events sent to the client callback*/\n    CP_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    CP_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    CP_EventMax = 0X7FFFFFFF\n} CP_EVENTTYPE;\n\n/** content pipe definition\n * @ingroup cp\n */\ntypedef struct CP_PIPETYPE\n{\n    /** Open a content stream for reading or writing. */\n    CPresult (*Open)( CPhandle* hContent, CPstring szURI, CP_ACCESSTYPE eAccess );\n\n    /** Close a content stream. */\n    CPresult (*Close)( CPhandle hContent );\n\n    /** Create a content source and open it for writing. */\n    CPresult (*Create)( CPhandle *hContent, CPstring szURI );\n\n    /** Check the that specified number of bytes are available for reading or writing (depending on access type).*/\n    CPresult (*CheckAvailableBytes)( CPhandle hContent, CPuint nBytesRequested, CP_CHECKBYTESRESULTTYPE *eResult );\n\n    /** Seek to certain position in the content relative to the specified origin. */\n    CPresult (*SetPosition)( CPhandle  hContent, CPint nOffset, CP_ORIGINTYPE eOrigin);\n\n    /** Retrieve the current position relative to the start of the content. */\n    CPresult (*GetPosition)( CPhandle hContent, CPuint *pPosition);\n\n    /** Retrieve data of the specified size from the content stream (advance content pointer by size of data).\n       Note: pipe client provides pointer. This function is appropriate for small high frequency reads. */\n    CPresult (*Read)( CPhandle hContent, CPbyte *pData, CPuint nSize);\n\n    /** Retrieve a buffer allocated by the pipe that contains the requested number of bytes.\n       Buffer contains the next block of bytes, as specified by nSize, of the content. nSize also\n       returns the size of the block actually read. Content pointer advances the by the returned size.\n       Note: pipe provides pointer. This function is appropriate for large reads. The client must call\n       ReleaseReadBuffer when done with buffer.\n\n       In some cases the requested block may not reside in contiguous memory within the\n       pipe implementation. For instance if the pipe leverages a circular buffer then the requested\n       block may straddle the boundary of the circular buffer. By default a pipe implementation\n       performs a copy in this case to provide the block to the pipe client in one contiguous buffer.\n       If, however, the client sets bForbidCopy, then the pipe returns only those bytes preceding the memory\n       boundary. Here the client may retrieve the data in segments over successive calls. */\n    CPresult (*ReadBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint *nSize, CPbool bForbidCopy);\n\n    /** Release a buffer obtained by ReadBuffer back to the pipe. */\n    CPresult (*ReleaseReadBuffer)(CPhandle hContent, CPbyte *pBuffer);\n\n    /** Write data of the specified size to the content (advance content pointer by size of data).\n       Note: pipe client provides pointer. This function is appropriate for small high frequency writes. */\n    CPresult (*Write)( CPhandle hContent, CPbyte *data, CPuint nSize);\n\n    /** Retrieve a buffer allocated by the pipe used to write data to the content.\n       Client will fill buffer with output data. Note: pipe provides pointer. This function is appropriate\n       for large writes. The client must call WriteBuffer when done it has filled the buffer with data.*/\n    CPresult (*GetWriteBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint nSize);\n\n    /** Deliver a buffer obtained via GetWriteBuffer to the pipe. Pipe will write the\n       the contents of the buffer to content and advance content pointer by the size of the buffer */\n    CPresult (*WriteBuffer)( CPhandle hContent, CPbyte *pBuffer, CPuint nFilledSize);\n\n    /** Register a per-handle client callback with the content pipe. */\n    CPresult (*RegisterCallback)( CPhandle hContent, CPresult (*ClientCallback)(CP_EVENTTYPE eEvent, CPuint iParam));\n\n} CP_PIPETYPE;\n\n#endif\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/openmax/OMX_Core.h",
    "content": "/* ------------------------------------------------------------------\n * Copyright (C) 1998-2009 PacketVideo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n * express or implied.\n * See the License for the specific language governing permissions\n * and limitations under the License.\n * -------------------------------------------------------------------\n */\n/*\n * Copyright (c) 2008 The Khronos Group Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject\n * to the following conditions:\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n/** OMX_Core.h - OpenMax IL version 1.1.2\n *  The OMX_Core header file contains the definitions used by both the\n *  application and the component to access common items.\n */\n\n#ifndef OMX_Core_h\n#define OMX_Core_h\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n\n/* Each OMX header shall include all required header files to allow the\n *  header to compile without errors.  The includes below are required\n *  for this header file to compile successfully\n */\n\n#include <OMX_Index.h>\n\n\n/** The OMX_COMMANDTYPE enumeration is used to specify the action in the\n *  OMX_SendCommand macro.\n *  @ingroup core\n */\ntypedef enum OMX_COMMANDTYPE\n{\n    OMX_CommandStateSet,    /**< Change the component state */\n    OMX_CommandFlush,       /**< Flush the data queue(s) of a component */\n    OMX_CommandPortDisable, /**< Disable a port on a component. */\n    OMX_CommandPortEnable,  /**< Enable a port on a component. */\n    OMX_CommandMarkBuffer,  /**< Mark a component/buffer for observation */\n    OMX_CommandKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_CommandVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_CommandMax = 0X7FFFFFFF\n} OMX_COMMANDTYPE;\n\n\n\n/** The OMX_STATETYPE enumeration is used to indicate or change the component\n *  state.  This enumeration reflects the current state of the component when\n *  used with the OMX_GetState macro or becomes the parameter in a state change\n *  command when used with the OMX_SendCommand macro.\n *\n *  The component will be in the Loaded state after the component is initially\n *  loaded into memory.  In the Loaded state, the component is not allowed to\n *  allocate or hold resources other than to build it's internal parameter\n *  and configuration tables.  The application will send one or more\n *  SetParameters/GetParameters and SetConfig/GetConfig commands to the\n *  component and the component will record each of these parameter and\n *  configuration changes for use later.  When the application sends the\n *  Idle command, the component will acquire the resources needed for the\n *  specified configuration and will transition to the idle state if the\n *  allocation is successful.  If the component cannot successfully\n *  transition to the idle state for any reason, the state of the component\n *  shall be fully rolled back to the Loaded state (e.g. all allocated\n *  resources shall be released).  When the component receives the command\n *  to go to the Executing state, it shall begin processing buffers by\n *  sending all input buffers it holds to the application.  While\n *  the component is in the Idle state, the application may also send the\n *  Pause command.  If the component receives the pause command while in the\n *  Idle state, the component shall send all input buffers it holds to the\n *  application, but shall not begin processing buffers.  This will allow the\n *  application to prefill buffers.\n *\n *  @ingroup comp\n */\n\ntypedef enum OMX_STATETYPE\n{\n    OMX_StateInvalid,      /**< component has detected that it's internal data\n                                structures are corrupted to the point that\n                                it cannot determine it's state properly */\n    OMX_StateLoaded,      /**< component has been loaded but has not completed\n                                initialization.  The OMX_SetParameter macro\n                                and the OMX_GetParameter macro are the only\n                                valid macros allowed to be sent to the\n                                component in this state. */\n    OMX_StateIdle,        /**< component initialization has been completed\n                                successfully and the component is ready to\n                                to start. */\n    OMX_StateExecuting,   /**< component has accepted the start command and\n                                is processing data (if data is available) */\n    OMX_StatePause,       /**< component has received pause command */\n    OMX_StateWaitForResources, /**< component is waiting for resources, either after\n                                preemption or before it gets the resources requested.\n                                See specification for complete details. */\n    OMX_StateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_StateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_StateMax = 0X7FFFFFFF\n} OMX_STATETYPE;\n\n/** The OMX_ERRORTYPE enumeration defines the standard OMX Errors.  These\n *  errors should cover most of the common failure cases.  However,\n *  vendors are free to add additional error messages of their own as\n *  long as they follow these rules:\n *  1.  Vendor error messages shall be in the range of 0x90000000 to\n *      0x9000FFFF.\n *  2.  Vendor error messages shall be defined in a header file provided\n *      with the component.  No error messages are allowed that are\n *      not defined.\n */\ntypedef enum OMX_ERRORTYPE\n{\n  OMX_ErrorNone = 0,\n\n  /** There were insufficient resources to perform the requested operation */\n  OMX_ErrorInsufficientResources = (OMX_S32) 0x80001000,\n\n  /** There was an error, but the cause of the error could not be determined */\n  OMX_ErrorUndefined = (OMX_S32) 0x80001001,\n\n  /** The component name string was not valid */\n  OMX_ErrorInvalidComponentName = (OMX_S32) 0x80001002,\n\n  /** No component with the specified name string was found */\n  OMX_ErrorComponentNotFound = (OMX_S32) 0x80001003,\n\n  /** The component specified did not have a \"OMX_ComponentInit\" or\n      \"OMX_ComponentDeInit entry point */\n  OMX_ErrorInvalidComponent = (OMX_S32) 0x80001004,\n\n  /** One or more parameters were not valid */\n  OMX_ErrorBadParameter = (OMX_S32) 0x80001005,\n\n  /** The requested function is not implemented */\n  OMX_ErrorNotImplemented = (OMX_S32) 0x80001006,\n\n  /** The buffer was emptied before the next buffer was ready */\n  OMX_ErrorUnderflow = (OMX_S32) 0x80001007,\n\n  /** The buffer was not available when it was needed */\n  OMX_ErrorOverflow = (OMX_S32) 0x80001008,\n\n  /** The hardware failed to respond as expected */\n  OMX_ErrorHardware = (OMX_S32) 0x80001009,\n\n  /** The component is in the state OMX_StateInvalid */\n  OMX_ErrorInvalidState = (OMX_S32) 0x8000100A,\n\n  /** Stream is found to be corrupt */\n  OMX_ErrorStreamCorrupt = (OMX_S32) 0x8000100B,\n\n  /** Ports being connected are not compatible */\n  OMX_ErrorPortsNotCompatible = (OMX_S32) 0x8000100C,\n\n  /** Resources allocated to an idle component have been\n      lost resulting in the component returning to the loaded state */\n  OMX_ErrorResourcesLost = (OMX_S32) 0x8000100D,\n\n  /** No more indicies can be enumerated */\n  OMX_ErrorNoMore = (OMX_S32) 0x8000100E,\n\n  /** The component detected a version mismatch */\n  OMX_ErrorVersionMismatch = (OMX_S32) 0x8000100F,\n\n  /** The component is not ready to return data at this time */\n  OMX_ErrorNotReady = (OMX_S32) 0x80001010,\n\n  /** There was a timeout that occurred */\n  OMX_ErrorTimeout = (OMX_S32) 0x80001011,\n\n  /** This error occurs when trying to transition into the state you are already in */\n  OMX_ErrorSameState = (OMX_S32) 0x80001012,\n\n  /** Resources allocated to an executing or paused component have been\n      preempted, causing the component to return to the idle state */\n  OMX_ErrorResourcesPreempted = (OMX_S32) 0x80001013,\n\n  /** A non-supplier port sends this error to the IL client (via the EventHandler callback)\n      during the allocation of buffers (on a transition from the LOADED to the IDLE state or\n      on a port restart) when it deems that it has waited an unusually long time for the supplier\n      to send it an allocated buffer via a UseBuffer call. */\n  OMX_ErrorPortUnresponsiveDuringAllocation = (OMX_S32) 0x80001014,\n\n  /** A non-supplier port sends this error to the IL client (via the EventHandler callback)\n      during the deallocation of buffers (on a transition from the IDLE to LOADED state or\n      on a port stop) when it deems that it has waited an unusually long time for the supplier\n      to request the deallocation of a buffer header via a FreeBuffer call. */\n  OMX_ErrorPortUnresponsiveDuringDeallocation = (OMX_S32) 0x80001015,\n\n  /** A supplier port sends this error to the IL client (via the EventHandler callback)\n      during the stopping of a port (either on a transition from the IDLE to LOADED\n      state or a port stop) when it deems that it has waited an unusually long time for\n      the non-supplier to return a buffer via an EmptyThisBuffer or FillThisBuffer call. */\n  OMX_ErrorPortUnresponsiveDuringStop = (OMX_S32) 0x80001016,\n\n  /** Attempting a state transtion that is not allowed */\n  OMX_ErrorIncorrectStateTransition = (OMX_S32) 0x80001017,\n\n  /* Attempting a command that is not allowed during the present state. */\n  OMX_ErrorIncorrectStateOperation = (OMX_S32) 0x80001018,\n\n  /** The values encapsulated in the parameter or config structure are not supported. */\n  OMX_ErrorUnsupportedSetting = (OMX_S32) 0x80001019,\n\n  /** The parameter or config indicated by the given index is not supported. */\n  OMX_ErrorUnsupportedIndex = (OMX_S32) 0x8000101A,\n\n  /** The port index supplied is incorrect. */\n  OMX_ErrorBadPortIndex = (OMX_S32) 0x8000101B,\n\n  /** The port has lost one or more of its buffers and it thus unpopulated. */\n  OMX_ErrorPortUnpopulated = (OMX_S32) 0x8000101C,\n\n  /** Component suspended due to temporary loss of resources */\n  OMX_ErrorComponentSuspended = (OMX_S32) 0x8000101D,\n\n  /** Component suspended due to an inability to acquire dynamic resources */\n  OMX_ErrorDynamicResourcesUnavailable = (OMX_S32) 0x8000101E,\n\n  /** When the macroblock error reporting is enabled the component returns new error\n  for every frame that has errors */\n  OMX_ErrorMbErrorsInFrame = (OMX_S32) 0x8000101F,\n\n  /** A component reports this error when it cannot parse or determine the format of an input stream. */\n  OMX_ErrorFormatNotDetected = (OMX_S32) 0x80001020,\n\n  /** The content open operation failed. */\n  OMX_ErrorContentPipeOpenFailed = (OMX_S32) 0x80001021,\n\n  /** The content creation operation failed. */\n  OMX_ErrorContentPipeCreationFailed = (OMX_S32) 0x80001022,\n\n  /** Separate table information is being used */\n  OMX_ErrorSeperateTablesUsed = (OMX_S32) 0x80001023,\n\n  /** Tunneling is unsupported by the component*/\n  OMX_ErrorTunnelingUnsupported = (OMX_S32) 0x80001024,\n\n  OMX_ErrorKhronosExtensions = (OMX_S32)0x8F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n  OMX_ErrorVendorStartUnused = (OMX_S32)0x90000000, /**< Reserved region for introducing Vendor Extensions */\n  OMX_ErrorMax = 0x7FFFFFFF\n} OMX_ERRORTYPE;\n\n/** @ingroup core */\ntypedef OMX_ERRORTYPE (* OMX_COMPONENTINITTYPE)(OMX_IN  OMX_HANDLETYPE hComponent);\n\n/** @ingroup core */\ntypedef struct OMX_COMPONENTREGISTERTYPE\n{\n  const char          * pName;       /* Component name, 128 byte limit (including '\\0') applies */\n  OMX_COMPONENTINITTYPE pInitialize; /* Component instance initialization function */\n} OMX_COMPONENTREGISTERTYPE;\n\n/** @ingroup core */\nextern OMX_COMPONENTREGISTERTYPE OMX_ComponentRegistered[];\n\n/** @ingroup rpm */\ntypedef struct OMX_PRIORITYMGMTTYPE {\n OMX_U32 nSize;             /**< size of the structure in bytes */\n OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */\n OMX_U32 nGroupPriority;            /**< Priority of the component group */\n OMX_U32 nGroupID;                  /**< ID of the component group */\n} OMX_PRIORITYMGMTTYPE;\n\n/* Component name and Role names are limited to 128 characters including the terminating '\\0'. */\n#define OMX_MAX_STRINGNAME_SIZE 128\n\n/** @ingroup comp */\ntypedef struct OMX_PARAM_COMPONENTROLETYPE {\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_U8 cRole[OMX_MAX_STRINGNAME_SIZE];  /**< name of standard component which defines component role */\n} OMX_PARAM_COMPONENTROLETYPE;\n\n/** End of Stream Buffer Flag:\n  *\n  * A component sets EOS when it has no more data to emit on a particular\n  * output port. Thus an output port shall set EOS on the last buffer it\n  * emits. A component's determination of when an output port should\n  * cease sending data is implemenation specific.\n  * @ingroup buf\n  */\n\n#define OMX_BUFFERFLAG_EOS 0x00000001\n\n/** Start Time Buffer Flag:\n *\n * The source of a stream (e.g. a demux component) sets the STARTTIME\n * flag on the buffer that contains the starting timestamp for the\n * stream. The starting timestamp corresponds to the first data that\n * should be displayed at startup or after a seek.\n * The first timestamp of the stream is not necessarily the start time.\n * For instance, in the case of a seek to a particular video frame,\n * the target frame may be an interframe. Thus the first buffer of\n * the stream will be the intra-frame preceding the target frame and\n * the starttime will occur with the target frame (with any other\n * required frames required to reconstruct the target intervening).\n *\n * The STARTTIME flag is directly associated with the buffer's\n * timestamp ' thus its association to buffer data and its\n * propagation is identical to the timestamp's.\n *\n * When a Sync Component client receives a buffer with the\n * STARTTIME flag it shall perform a SetConfig on its sync port\n * using OMX_ConfigTimeClientStartTime and passing the buffer's\n * timestamp.\n *\n * @ingroup buf\n */\n\n#define OMX_BUFFERFLAG_STARTTIME 0x00000002\n\n\n\n/** Decode Only Buffer Flag:\n *\n * The source of a stream (e.g. a demux component) sets the DECODEONLY\n * flag on any buffer that should shall be decoded but should not be\n * displayed. This flag is used, for instance, when a source seeks to\n * a target interframe that requires the decode of frames preceding the\n * target to facilitate the target's reconstruction. In this case the\n * source would emit the frames preceding the target downstream\n * but mark them as decode only.\n *\n * The DECODEONLY is associated with buffer data and propagated in a\n * manner identical to the buffer timestamp.\n *\n * A component that renders data should ignore all buffers with\n * the DECODEONLY flag set.\n *\n * @ingroup buf\n */\n\n#define OMX_BUFFERFLAG_DECODEONLY 0x00000004\n\n\n/* Data Corrupt Flag: This flag is set when the IL client believes the data in the associated buffer is corrupt\n * @ingroup buf\n */\n\n#define OMX_BUFFERFLAG_DATACORRUPT 0x00000008\n\n/* End of Frame: The buffer contains exactly one end of frame and no data\n *  occurs after the end of frame. This flag is an optional hint. The absence\n *  of this flag does not imply the absence of an end of frame within the buffer.\n * @ingroup buf\n*/\n#define OMX_BUFFERFLAG_ENDOFFRAME 0x00000010\n\n/* Sync Frame Flag: This flag is set when the buffer content contains a coded sync frame '\n *  a frame that has no dependency on any other frame information\n *  @ingroup buf\n */\n#define OMX_BUFFERFLAG_SYNCFRAME 0x00000020\n\n/* Extra data present flag: there is extra data appended to the data stream\n * residing in the buffer\n * @ingroup buf\n */\n#define OMX_BUFFERFLAG_EXTRADATA 0x00000040\n\n/** Codec Config Buffer Flag:\n* OMX_BUFFERFLAG_CODECCONFIG is an optional flag that is set by an\n* output port when all bytes in the buffer form part or all of a set of\n* codec specific configuration data.  Examples include SPS/PPS nal units\n* for OMX_VIDEO_CodingAVC or AudioSpecificConfig data for\n* OMX_AUDIO_CodingAAC.  Any component that for a given stream sets\n* OMX_BUFFERFLAG_CODECCONFIG shall not mix codec configuration bytes\n* with frame data in the same buffer, and shall send all buffers\n* containing codec configuration bytes before any buffers containing\n* frame data that those configurations bytes describe.\n* If the stream format for a particular codec has a frame specific\n* header at the start of each frame, for example OMX_AUDIO_CodingMP3 or\n* OMX_AUDIO_CodingAAC in ADTS mode, then these shall be presented as\n* normal without setting OMX_BUFFERFLAG_CODECCONFIG.\n * @ingroup buf\n */\n#define OMX_BUFFERFLAG_CODECCONFIG 0x00000080\n\n\n\n/** @ingroup buf */\ntypedef struct OMX_BUFFERHEADERTYPE\n{\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_U8* pBuffer;            /**< Pointer to actual block of memory\n                                     that is acting as the buffer */\n    OMX_U32 nAllocLen;          /**< size of the buffer allocated, in bytes */\n    OMX_U32 nFilledLen;         /**< number of bytes currently in the\n                                     buffer */\n    OMX_U32 nOffset;            /**< start offset of valid data in bytes from\n                                     the start of the buffer */\n    OMX_PTR pAppPrivate;        /**< pointer to any data the application\n                                     wants to associate with this buffer */\n    OMX_PTR pPlatformPrivate;   /**< pointer to any data the platform\n                                     wants to associate with this buffer */\n    OMX_PTR pInputPortPrivate;  /**< pointer to any data the input port\n                                     wants to associate with this buffer */\n    OMX_PTR pOutputPortPrivate; /**< pointer to any data the output port\n                                     wants to associate with this buffer */\n    OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will generate a\n                                              mark event upon processing this buffer. */\n    OMX_PTR pMarkData;          /**< Application specific data associated with\n                                     the mark sent on a mark event to disambiguate\n                                     this mark from others. */\n    OMX_U32 nTickCount;         /**< Optional entry that the component and\n                                     application can update with a tick count\n                                     when they access the component.  This\n                                     value should be in microseconds.  Since\n                                     this is a value relative to an arbitrary\n                                     starting point, this value cannot be used\n                                     to determine absolute time.  This is an\n                                     optional entry and not all components\n                                     will update it.*/\n OMX_TICKS nTimeStamp;          /**< Timestamp corresponding to the sample\n                                     starting at the first logical sample\n                                     boundary in the buffer. Timestamps of\n                                     successive samples within the buffer may\n                                     be inferred by adding the duration of the\n                                     of the preceding buffer to the timestamp\n                                     of the preceding buffer.*/\n  OMX_U32     nFlags;           /**< buffer specific flags */\n  OMX_U32 nOutputPortIndex;     /**< The index of the output port (if any) using\n                                     this buffer */\n  OMX_U32 nInputPortIndex;      /**< The index of the input port (if any) using\n                                     this buffer */\n} OMX_BUFFERHEADERTYPE;\n\n/** The OMX_EXTRADATATYPE enumeration is used to define the\n * possible extra data payload types.\n * NB: this enum is binary backwards compatible with the previous\n * OMX_EXTRADATA_QUANT define.  This should be replaced with\n * OMX_ExtraDataQuantization.\n */\ntypedef enum OMX_EXTRADATATYPE\n{\n   OMX_ExtraDataNone = 0,                       /**< Indicates that no more extra data sections follow */\n   OMX_ExtraDataQuantization,                   /**< The data payload contains quantization data */\n   OMX_ExtraDataKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n   OMX_ExtraDataVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n   OMX_ExtraDataMax = 0x7FFFFFFF\n} OMX_EXTRADATATYPE;\n\n\ntypedef struct OMX_OTHER_EXTRADATATYPE  {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_EXTRADATATYPE eType;       /* Extra Data type */\n    OMX_U32 nDataSize;   /* Size of the supporting data to follow */\n    OMX_U8  data[1];     /* Supporting data hint  */\n} OMX_OTHER_EXTRADATATYPE;\n\n/** @ingroup comp */\ntypedef struct OMX_PORT_PARAM_TYPE {\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_U32 nPorts;             /**< The number of ports for this component */\n    OMX_U32 nStartPortNumber;   /** first port number for this type of port */\n} OMX_PORT_PARAM_TYPE;\n\n/** @ingroup comp */\ntypedef enum OMX_EVENTTYPE\n{\n    OMX_EventCmdComplete,         /**< component has sucessfully completed a command */\n    OMX_EventError,               /**< component has detected an error condition */\n    OMX_EventMark,                /**< component has detected a buffer mark */\n    OMX_EventPortSettingsChanged, /**< component is reported a port settings change */\n    OMX_EventBufferFlag,          /**< component has detected an EOS */\n    OMX_EventResourcesAcquired,   /**< component has been granted resources and is\n                                       automatically starting the state change from\n                                       OMX_StateWaitForResources to OMX_StateIdle. */\n    OMX_EventComponentResumed,     /**< Component resumed due to reacquisition of resources */\n    OMX_EventDynamicResourcesAvailable, /**< Component has acquired previously unavailable dynamic resources */\n    OMX_EventPortFormatDetected,      /**< Component has detected a supported format. */\n    OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n\n    /** Event when tunneled decoder has rendered an output or reached EOS\n     *  nData1 must contain the number of timestamps returned\n     *  pEventData must point to an array of the OMX_VIDEO_RENDEREVENTTYPE structs containing the\n     *  render-timestamps of each frame. Component may batch rendered timestamps using this event,\n     *  but must signal the event no more than 40ms after the first frame in the batch. The frames\n     *  must be ordered by system timestamp inside and across batches.\n     *\n     *  If component is doing frame-rate conversion, it must signal the render time of each\n     *  converted frame, and must interpolate media timestamps for in-between frames.\n     *\n     *  When the component reached EOS, it must signal an EOS timestamp using the same mechanism.\n     *  This is in addition to the timestamp of the last rendered frame, and should follow that\n     *  frame.\n     */\n    OMX_EventOutputRendered = 0x7F000001,\n\n    /** For framework internal use only: event sent by OMXNodeInstance when it receives a graphic\n     *  input buffer with a new dataspace for encoding. |arg1| will contain the dataspace. |arg2|\n     *  will contain the ColorAspects requested by the component (or framework defaults) using\n     *  the following bitfield layout:\n     *\n     *       +----------+-------------+----------------+------------+\n     *       |   Range  |  Primaries  |  MatrixCoeffs  |  Transfer  |\n     *       +----------+-------------+----------------+------------+\n     *  bits:  31....24   23.......16   15...........8   7........0\n     *\n     *  TODO: We would really need to tie this to an output buffer, but OMX does not provide a\n     *  fool-proof way to do that for video encoders.\n     */\n    OMX_EventDataSpaceChanged,\n    OMX_EventMax = 0x7FFFFFFF\n} OMX_EVENTTYPE;\n\ntypedef struct OMX_CALLBACKTYPE\n{\n    /** The EventHandler method is used to notify the application when an\n        event of interest occurs.  Events are defined in the OMX_EVENTTYPE\n        enumeration.  Please see that enumeration for details of what will\n        be returned for each type of event. Callbacks should not return\n        an error to the component, so if an error occurs, the application\n        shall handle it internally.  This is a blocking call.\n\n        The application should return from this call within 5 msec to avoid\n        blocking the component for an excessively long period of time.\n\n        @param hComponent\n            handle of the component to access.  This is the component\n            handle returned by the call to the GetHandle function.\n        @param pAppData\n            pointer to an application defined value that was provided in the\n            pAppData parameter to the OMX_GetHandle method for the component.\n            This application defined value is provided so that the application\n            can have a component specific context when receiving the callback.\n        @param eEvent\n            Event that the component wants to notify the application about.\n        @param nData1\n            nData will be the OMX_ERRORTYPE for an error event and will be\n            an OMX_COMMANDTYPE for a command complete event and OMX_INDEXTYPE for a OMX_PortSettingsChanged event.\n         @param nData2\n            nData2 will hold further information related to the event. Can be OMX_STATETYPE for\n            a OMX_CommandStateSet command or port index for a OMX_PortSettingsChanged event.\n            Default value is 0 if not used. )\n        @param pEventData\n            Pointer to additional event-specific data (see spec for meaning).\n      */\n\n   OMX_ERRORTYPE (*EventHandler)(\n        OMX_IN OMX_HANDLETYPE hComponent,\n        OMX_IN OMX_PTR pAppData,\n        OMX_IN OMX_EVENTTYPE eEvent,\n        OMX_IN OMX_U32 nData1,\n        OMX_IN OMX_U32 nData2,\n        OMX_IN OMX_PTR pEventData);\n\n    /** The EmptyBufferDone method is used to return emptied buffers from an\n        input port back to the application for reuse.  This is a blocking call\n        so the application should not attempt to refill the buffers during this\n        call, but should queue them and refill them in another thread.  There\n        is no error return, so the application shall handle any errors generated\n        internally.\n\n        The application should return from this call within 5 msec.\n\n        @param hComponent\n            handle of the component to access.  This is the component\n            handle returned by the call to the GetHandle function.\n        @param pAppData\n            pointer to an application defined value that was provided in the\n            pAppData parameter to the OMX_GetHandle method for the component.\n            This application defined value is provided so that the application\n            can have a component specific context when receiving the callback.\n        @param pBuffer\n            pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer\n            or AllocateBuffer indicating the buffer that was emptied.\n        @ingroup buf\n     */\n    OMX_ERRORTYPE (*EmptyBufferDone)(\n        OMX_IN OMX_HANDLETYPE hComponent,\n        OMX_IN OMX_PTR pAppData,\n        OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);\n\n    /** The FillBufferDone method is used to return filled buffers from an\n        output port back to the application for emptying and then reuse.\n        This is a blocking call so the application should not attempt to\n        empty the buffers during this call, but should queue the buffers\n        and empty them in another thread.  There is no error return, so\n        the application shall handle any errors generated internally.  The\n        application shall also update the buffer header to indicate the\n        number of bytes placed into the buffer.\n\n        The application should return from this call within 5 msec.\n\n        @param hComponent\n            handle of the component to access.  This is the component\n            handle returned by the call to the GetHandle function.\n        @param pAppData\n            pointer to an application defined value that was provided in the\n            pAppData parameter to the OMX_GetHandle method for the component.\n            This application defined value is provided so that the application\n            can have a component specific context when receiving the callback.\n        @param pBuffer\n            pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer\n            or AllocateBuffer indicating the buffer that was filled.\n        @ingroup buf\n     */\n    OMX_ERRORTYPE (*FillBufferDone)(\n        OMX_OUT OMX_HANDLETYPE hComponent,\n        OMX_OUT OMX_PTR pAppData,\n        OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer);\n\n} OMX_CALLBACKTYPE;\n\n/** The OMX_BUFFERSUPPLIERTYPE enumeration is used to dictate port supplier\n    preference when tunneling between two ports.\n    @ingroup tun buf\n*/\ntypedef enum OMX_BUFFERSUPPLIERTYPE\n{\n    OMX_BufferSupplyUnspecified = 0x0, /**< port supplying the buffers is unspecified,\n                                              or don't care */\n    OMX_BufferSupplyInput,             /**< input port supplies the buffers */\n    OMX_BufferSupplyOutput,            /**< output port supplies the buffers */\n    OMX_BufferSupplyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_BufferSupplyVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_BufferSupplyMax = 0x7FFFFFFF\n} OMX_BUFFERSUPPLIERTYPE;\n\n\n/** buffer supplier parameter\n * @ingroup tun\n */\ntypedef struct OMX_PARAM_BUFFERSUPPLIERTYPE {\n    OMX_U32 nSize; /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex; /**< port that this structure applies to */\n    OMX_BUFFERSUPPLIERTYPE eBufferSupplier; /**< buffer supplier */\n} OMX_PARAM_BUFFERSUPPLIERTYPE;\n\n\n/**< indicates that buffers received by an input port of a tunnel\n     may not modify the data in the buffers\n     @ingroup tun\n */\n#define OMX_PORTTUNNELFLAG_READONLY 0x00000001\n\n\n/** The OMX_TUNNELSETUPTYPE structure is used to pass data from an output\n    port to an input port as part the two ComponentTunnelRequest calls\n    resulting from a OMX_SetupTunnel call from the IL Client.\n    @ingroup tun\n */\ntypedef struct OMX_TUNNELSETUPTYPE\n{\n    OMX_U32 nTunnelFlags;             /**< bit flags for tunneling */\n    OMX_BUFFERSUPPLIERTYPE eSupplier; /**< supplier preference */\n} OMX_TUNNELSETUPTYPE;\n\n/* OMX Component headers is included to enable the core to use\n   macros for functions into the component for OMX release 1.0.\n   Developers should not access any structures or data from within\n   the component header directly */\n/* TO BE REMOVED - #include <OMX_Component.h> */\n\n/** GetComponentVersion will return information about the component.\n    This is a blocking call.  This macro will go directly from the\n    application to the component (via a core macro).  The\n    component will return from this call within 5 msec.\n    @param [in] hComponent\n        handle of component to execute the command\n    @param [out] pComponentName\n        pointer to an empty string of length 128 bytes.  The component\n        will write its name into this string.  The name will be\n        terminated by a single zero byte.  The name of a component will\n        be 127 bytes or less to leave room for the trailing zero byte.\n        An example of a valid component name is \"OMX.ABC.ChannelMixer\\0\".\n    @param [out] pComponentVersion\n        pointer to an OMX Version structure that the component will fill\n        in.  The component will fill in a value that indicates the\n        component version.  NOTE: the component version is NOT the same\n        as the OMX Specification version (found in all structures).  The\n        component version is defined by the vendor of the component and\n        its value is entirely up to the component vendor.\n    @param [out] pSpecVersion\n        pointer to an OMX Version structure that the component will fill\n        in.  The SpecVersion is the version of the specification that the\n        component was built against.  Please note that this value may or\n        may not match the structure's version.  For example, if the\n        component was built against the 2.0 specification, but the\n        application (which creates the structure is built against the\n        1.0 specification the versions would be different.\n    @param [out] pComponentUUID\n        pointer to the UUID of the component which will be filled in by\n        the component.  The UUID is a unique identifier that is set at\n        RUN time for the component and is unique to each instantion of\n        the component.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup comp\n */\n#define OMX_GetComponentVersion(                            \\\n        hComponent,                                         \\\n        pComponentName,                                     \\\n        pComponentVersion,                                  \\\n        pSpecVersion,                                       \\\n        pComponentUUID)                                     \\\n    ((OMX_COMPONENTTYPE*)hComponent)->GetComponentVersion(  \\\n        hComponent,                                         \\\n        pComponentName,                                     \\\n        pComponentVersion,                                  \\\n        pSpecVersion,                                       \\\n        pComponentUUID)                 /* Macro End */\n\n\n/** Send a command to the component.  This call is a non-blocking call.\n    The component should check the parameters and then queue the command\n    to the component thread to be executed.  The component thread shall\n    send the EventHandler() callback at the conclusion of the command.\n    This macro will go directly from the application to the component (via\n    a core macro).  The component will return from this call within 5 msec.\n\n    When the command is \"OMX_CommandStateSet\" the component will queue a\n    state transition to the new state idenfied in nParam.\n\n    When the command is \"OMX_CommandFlush\", to flush a port's buffer queues,\n    the command will force the component to return all buffers NOT CURRENTLY\n    BEING PROCESSED to the application, in the order in which the buffers\n    were received.\n\n    When the command is \"OMX_CommandPortDisable\" or\n    \"OMX_CommandPortEnable\", the component's port (given by the value of\n    nParam) will be stopped or restarted.\n\n    When the command \"OMX_CommandMarkBuffer\" is used to mark a buffer, the\n    pCmdData will point to a OMX_MARKTYPE structure containing the component\n    handle of the component to examine the buffer chain for the mark.  nParam1\n    contains the index of the port on which the buffer mark is applied.\n\n    Specification text for more details.\n\n    @param [in] hComponent\n        handle of component to execute the command\n    @param [in] Cmd\n        Command for the component to execute\n    @param [in] nParam\n        Parameter for the command to be executed.  When Cmd has the value\n        OMX_CommandStateSet, value is a member of OMX_STATETYPE.  When Cmd has\n        the value OMX_CommandFlush, value of nParam indicates which port(s)\n        to flush. -1 is used to flush all ports a single port index will\n        only flush that port.  When Cmd has the value \"OMX_CommandPortDisable\"\n        or \"OMX_CommandPortEnable\", the component's port is given by\n        the value of nParam.  When Cmd has the value \"OMX_CommandMarkBuffer\"\n        the components pot is given by the value of nParam.\n    @param [in] pCmdData\n        Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value\n        \"OMX_CommandMarkBuffer\".\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup comp\n */\n#define OMX_SendCommand(                                    \\\n         hComponent,                                        \\\n         Cmd,                                               \\\n         nParam,                                            \\\n         pCmdData)                                          \\\n     ((OMX_COMPONENTTYPE*)hComponent)->SendCommand(         \\\n         hComponent,                                        \\\n         Cmd,                                               \\\n         nParam,                                            \\\n         pCmdData)                          /* Macro End */\n\n\n/** The OMX_GetParameter macro will get one of the current parameter\n    settings from the component.  This macro cannot only be invoked when\n    the component is in the OMX_StateInvalid state.  The nParamIndex\n    parameter is used to indicate which structure is being requested from\n    the component.  The application shall allocate the correct structure\n    and shall fill in the structure size and version information before\n    invoking this macro.  When the parameter applies to a port, the\n    caller shall fill in the appropriate nPortIndex value indicating the\n    port on which the parameter applies. If the component has not had\n    any settings changed, then the component should return a set of\n    valid DEFAULT  parameters for the component.  This is a blocking\n    call.\n\n    The component should return from this call within 20 msec.\n\n    @param [in] hComponent\n        Handle of the component to be accessed.  This is the component\n        handle returned by the call to the OMX_GetHandle function.\n    @param [in] nParamIndex\n        Index of the structure to be filled.  This value is from the\n        OMX_INDEXTYPE enumeration.\n    @param [in,out] pComponentParameterStructure\n        Pointer to application allocated structure to be filled by the\n        component.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup comp\n */\n#define OMX_GetParameter(                                   \\\n        hComponent,                                         \\\n        nParamIndex,                                        \\\n        pComponentParameterStructure)                        \\\n    ((OMX_COMPONENTTYPE*)hComponent)->GetParameter(         \\\n        hComponent,                                         \\\n        nParamIndex,                                        \\\n        pComponentParameterStructure)    /* Macro End */\n\n\n/** The OMX_SetParameter macro will send an initialization parameter\n    structure to a component.  Each structure shall be sent one at a time,\n    in a separate invocation of the macro.  This macro can only be\n    invoked when the component is in the OMX_StateLoaded state, or the\n    port is disabled (when the parameter applies to a port). The\n    nParamIndex parameter is used to indicate which structure is being\n    passed to the component.  The application shall allocate the\n    correct structure and shall fill in the structure size and version\n    information (as well as the actual data) before invoking this macro.\n    The application is free to dispose of this structure after the call\n    as the component is required to copy any data it shall retain.  This\n    is a blocking call.\n\n    The component should return from this call within 20 msec.\n\n    @param [in] hComponent\n        Handle of the component to be accessed.  This is the component\n        handle returned by the call to the OMX_GetHandle function.\n    @param [in] nIndex\n        Index of the structure to be sent.  This value is from the\n        OMX_INDEXTYPE enumeration.\n    @param [in] pComponentParameterStructure\n        pointer to application allocated structure to be used for\n        initialization by the component.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup comp\n */\n#define OMX_SetParameter(                                   \\\n        hComponent,                                         \\\n        nParamIndex,                                        \\\n        pComponentParameterStructure)                        \\\n    ((OMX_COMPONENTTYPE*)hComponent)->SetParameter(         \\\n        hComponent,                                         \\\n        nParamIndex,                                        \\\n        pComponentParameterStructure)    /* Macro End */\n\n\n/** The OMX_GetConfig macro will get one of the configuration structures\n    from a component.  This macro can be invoked anytime after the\n    component has been loaded.  The nParamIndex call parameter is used to\n    indicate which structure is being requested from the component.  The\n    application shall allocate the correct structure and shall fill in the\n    structure size and version information before invoking this macro.\n    If the component has not had this configuration parameter sent before,\n    then the component should return a set of valid DEFAULT values for the\n    component.  This is a blocking call.\n\n    The component should return from this call within 5 msec.\n\n    @param [in] hComponent\n        Handle of the component to be accessed.  This is the component\n        handle returned by the call to the OMX_GetHandle function.\n    @param [in] nIndex\n        Index of the structure to be filled.  This value is from the\n        OMX_INDEXTYPE enumeration.\n    @param [in,out] pComponentConfigStructure\n        pointer to application allocated structure to be filled by the\n        component.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup comp\n*/\n#define OMX_GetConfig(                                      \\\n        hComponent,                                         \\\n        nConfigIndex,                                       \\\n        pComponentConfigStructure)                           \\\n    ((OMX_COMPONENTTYPE*)hComponent)->GetConfig(            \\\n        hComponent,                                         \\\n        nConfigIndex,                                       \\\n        pComponentConfigStructure)       /* Macro End */\n\n\n/** The OMX_SetConfig macro will send one of the configuration\n    structures to a component.  Each structure shall be sent one at a time,\n    each in a separate invocation of the macro.  This macro can be invoked\n    anytime after the component has been loaded.  The application shall\n    allocate the correct structure and shall fill in the structure size\n    and version information (as well as the actual data) before invoking\n    this macro.  The application is free to dispose of this structure after\n    the call as the component is required to copy any data it shall retain.\n    This is a blocking call.\n\n    The component should return from this call within 5 msec.\n\n    @param [in] hComponent\n        Handle of the component to be accessed.  This is the component\n        handle returned by the call to the OMX_GetHandle function.\n    @param [in] nConfigIndex\n        Index of the structure to be sent.  This value is from the\n        OMX_INDEXTYPE enumeration above.\n    @param [in] pComponentConfigStructure\n        pointer to application allocated structure to be used for\n        initialization by the component.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup comp\n */\n#define OMX_SetConfig(                                      \\\n        hComponent,                                         \\\n        nConfigIndex,                                       \\\n        pComponentConfigStructure)                           \\\n    ((OMX_COMPONENTTYPE*)hComponent)->SetConfig(            \\\n        hComponent,                                         \\\n        nConfigIndex,                                       \\\n        pComponentConfigStructure)       /* Macro End */\n\n\n/** The OMX_GetExtensionIndex macro will invoke a component to translate\n    a vendor specific configuration or parameter string into an OMX\n    structure index.  There is no requirement for the vendor to support\n    this command for the indexes already found in the OMX_INDEXTYPE\n    enumeration (this is done to save space in small components).  The\n    component shall support all vendor supplied extension indexes not found\n    in the master OMX_INDEXTYPE enumeration.  This is a blocking call.\n\n    The component should return from this call within 5 msec.\n\n    @param [in] hComponent\n        Handle of the component to be accessed.  This is the component\n        handle returned by the call to the GetHandle function.\n    @param [in] cParameterName\n        OMX_STRING that shall be less than 128 characters long including\n        the trailing null byte.  This is the string that will get\n        translated by the component into a configuration index.\n    @param [out] pIndexType\n        a pointer to a OMX_INDEXTYPE to receive the index value.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup comp\n */\n#define OMX_GetExtensionIndex(                              \\\n        hComponent,                                         \\\n        cParameterName,                                     \\\n        pIndexType)                                         \\\n    ((OMX_COMPONENTTYPE*)hComponent)->GetExtensionIndex(    \\\n        hComponent,                                         \\\n        cParameterName,                                     \\\n        pIndexType)                     /* Macro End */\n\n\n/** The OMX_GetState macro will invoke the component to get the current\n    state of the component and place the state value into the location\n    pointed to by pState.\n\n    The component should return from this call within 5 msec.\n\n    @param [in] hComponent\n        Handle of the component to be accessed.  This is the component\n        handle returned by the call to the OMX_GetHandle function.\n    @param [out] pState\n        pointer to the location to receive the state.  The value returned\n        is one of the OMX_STATETYPE members\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup comp\n */\n#define OMX_GetState(                                       \\\n        hComponent,                                         \\\n        pState)                                             \\\n    ((OMX_COMPONENTTYPE*)hComponent)->GetState(             \\\n        hComponent,                                         \\\n        pState)                         /* Macro End */\n\n\n/** The OMX_UseBuffer macro will request that the component use\n    a buffer (and allocate its own buffer header) already allocated\n    by another component, or by the IL Client. This is a blocking\n    call.\n\n    The component should return from this call within 20 msec.\n\n    @param [in] hComponent\n        Handle of the component to be accessed.  This is the component\n        handle returned by the call to the OMX_GetHandle function.\n    @param [out] ppBuffer\n        pointer to an OMX_BUFFERHEADERTYPE structure used to receive the\n        pointer to the buffer header\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup comp buf\n */\n\n#define OMX_UseBuffer(                                      \\\n           hComponent,                                      \\\n           ppBufferHdr,                                     \\\n           nPortIndex,                                      \\\n           pAppPrivate,                                     \\\n           nSizeBytes,                                      \\\n           pBuffer)                                         \\\n    ((OMX_COMPONENTTYPE*)hComponent)->UseBuffer(            \\\n           hComponent,                                      \\\n           ppBufferHdr,                                     \\\n           nPortIndex,                                      \\\n           pAppPrivate,                                     \\\n           nSizeBytes,                                      \\\n           pBuffer)\n\n\n/** The OMX_AllocateBuffer macro will request that the component allocate\n    a new buffer and buffer header.  The component will allocate the\n    buffer and the buffer header and return a pointer to the buffer\n    header.  This is a blocking call.\n\n    The component should return from this call within 5 msec.\n\n    @param [in] hComponent\n        Handle of the component to be accessed.  This is the component\n        handle returned by the call to the OMX_GetHandle function.\n    @param [out] ppBuffer\n        pointer to an OMX_BUFFERHEADERTYPE structure used to receive\n        the pointer to the buffer header\n    @param [in] nPortIndex\n        nPortIndex is used to select the port on the component the buffer will\n        be used with.  The port can be found by using the nPortIndex\n        value as an index into the Port Definition array of the component.\n    @param [in] pAppPrivate\n        pAppPrivate is used to initialize the pAppPrivate member of the\n        buffer header structure.\n    @param [in] nSizeBytes\n        size of the buffer to allocate.  Used when bAllocateNew is true.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup comp buf\n */\n#define OMX_AllocateBuffer(                                 \\\n        hComponent,                                         \\\n        ppBuffer,                                           \\\n        nPortIndex,                                         \\\n        pAppPrivate,                                        \\\n        nSizeBytes)                                         \\\n    ((OMX_COMPONENTTYPE*)hComponent)->AllocateBuffer(       \\\n        hComponent,                                         \\\n        ppBuffer,                                           \\\n        nPortIndex,                                         \\\n        pAppPrivate,                                        \\\n        nSizeBytes)                     /* Macro End */\n\n\n/** The OMX_FreeBuffer macro will release a buffer header from the component\n    which was allocated using either OMX_AllocateBuffer or OMX_UseBuffer. If\n    the component allocated the buffer (see the OMX_UseBuffer macro) then\n    the component shall free the buffer and buffer header. This is a\n    blocking call.\n\n    The component should return from this call within 20 msec.\n\n    @param [in] hComponent\n        Handle of the component to be accessed.  This is the component\n        handle returned by the call to the OMX_GetHandle function.\n    @param [in] nPortIndex\n        nPortIndex is used to select the port on the component the buffer will\n        be used with.\n    @param [in] pBuffer\n        pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer\n        or AllocateBuffer.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup comp buf\n */\n#define OMX_FreeBuffer(                                     \\\n        hComponent,                                         \\\n        nPortIndex,                                         \\\n        pBuffer)                                            \\\n    ((OMX_COMPONENTTYPE*)hComponent)->FreeBuffer(           \\\n        hComponent,                                         \\\n        nPortIndex,                                         \\\n        pBuffer)                        /* Macro End */\n\n\n/** The OMX_EmptyThisBuffer macro will send a buffer full of data to an\n    input port of a component.  The buffer will be emptied by the component\n    and returned to the application via the EmptyBufferDone call back.\n    This is a non-blocking call in that the component will record the buffer\n    and return immediately and then empty the buffer, later, at the proper\n    time.  As expected, this macro may be invoked only while the component\n    is in the OMX_StateExecuting.  If nPortIndex does not specify an input\n    port, the component shall return an error.\n\n    The component should return from this call within 5 msec.\n\n    @param [in] hComponent\n        Handle of the component to be accessed.  This is the component\n        handle returned by the call to the OMX_GetHandle function.\n    @param [in] pBuffer\n        pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer\n        or AllocateBuffer.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup comp buf\n */\n#define OMX_EmptyThisBuffer(                                \\\n        hComponent,                                         \\\n        pBuffer)                                            \\\n    ((OMX_COMPONENTTYPE*)hComponent)->EmptyThisBuffer(      \\\n        hComponent,                                         \\\n        pBuffer)                        /* Macro End */\n\n\n/** The OMX_FillThisBuffer macro will send an empty buffer to an\n    output port of a component.  The buffer will be filled by the component\n    and returned to the application via the FillBufferDone call back.\n    This is a non-blocking call in that the component will record the buffer\n    and return immediately and then fill the buffer, later, at the proper\n    time.  As expected, this macro may be invoked only while the component\n    is in the OMX_ExecutingState.  If nPortIndex does not specify an output\n    port, the component shall return an error.\n\n    The component should return from this call within 5 msec.\n\n    @param [in] hComponent\n        Handle of the component to be accessed.  This is the component\n        handle returned by the call to the OMX_GetHandle function.\n    @param [in] pBuffer\n        pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer\n        or AllocateBuffer.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup comp buf\n */\n#define OMX_FillThisBuffer(                                 \\\n        hComponent,                                         \\\n        pBuffer)                                            \\\n    ((OMX_COMPONENTTYPE*)hComponent)->FillThisBuffer(       \\\n        hComponent,                                         \\\n        pBuffer)                        /* Macro End */\n\n\n\n/** The OMX_UseEGLImage macro will request that the component use\n    a EGLImage provided by EGL (and allocate its own buffer header)\n    This is a blocking call.\n\n    The component should return from this call within 20 msec.\n\n    @param [in] hComponent\n        Handle of the component to be accessed.  This is the component\n        handle returned by the call to the OMX_GetHandle function.\n    @param [out] ppBuffer\n        pointer to an OMX_BUFFERHEADERTYPE structure used to receive the\n        pointer to the buffer header.  Note that the memory location used\n        for this buffer is NOT visible to the IL Client.\n    @param [in] nPortIndex\n        nPortIndex is used to select the port on the component the buffer will\n        be used with.  The port can be found by using the nPortIndex\n        value as an index into the Port Definition array of the component.\n    @param [in] pAppPrivate\n        pAppPrivate is used to initialize the pAppPrivate member of the\n        buffer header structure.\n    @param [in] eglImage\n        eglImage contains the handle of the EGLImage to use as a buffer on the\n        specified port.  The component is expected to validate properties of\n        the EGLImage against the configuration of the port to ensure the component\n        can use the EGLImage as a buffer.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup comp buf\n */\n#define OMX_UseEGLImage(                                    \\\n           hComponent,                                      \\\n           ppBufferHdr,                                     \\\n           nPortIndex,                                      \\\n           pAppPrivate,                                     \\\n           eglImage)                                        \\\n    ((OMX_COMPONENTTYPE*)hComponent)->UseEGLImage(          \\\n           hComponent,                                      \\\n           ppBufferHdr,                                     \\\n           nPortIndex,                                      \\\n           pAppPrivate,                                     \\\n           eglImage)\n\n/** The OMX_Init method is used to initialize the OMX core.  It shall be the\n    first call made into OMX and it should only be executed one time without\n    an interviening OMX_Deinit call.\n\n    The core should return from this call within 20 msec.\n\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup core\n */\nOMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void);\n\n\n/** The OMX_Deinit method is used to deinitialize the OMX core.  It shall be\n    the last call made into OMX. In the event that the core determines that\n    thare are components loaded when this call is made, the core may return\n    with an error rather than try to unload the components.\n\n    The core should return from this call within 20 msec.\n\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup core\n */\nOMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void);\n\n\n/** The OMX_ComponentNameEnum method will enumerate through all the names of\n    recognised valid components in the system. This function is provided\n    as a means to detect all the components in the system run-time. There is\n    no strict ordering to the enumeration order of component names, although\n    each name will only be enumerated once.  If the OMX core supports run-time\n    installation of new components, it is only requried to detect newly\n    installed components when the first call to enumerate component names\n    is made (i.e. when nIndex is 0x0).\n\n    The core should return from this call in 20 msec.\n\n    @param [out] cComponentName\n        pointer to a null terminated string with the component name.  The\n        names of the components are strings less than 127 bytes in length\n        plus the trailing null for a maximum size of 128 bytes.  An example\n        of a valid component name is \"OMX.TI.AUDIO.DSP.MIXER\\0\".  Names are\n        assigned by the vendor, but shall start with \"OMX.\" and then have\n        the Vendor designation next.\n    @param [in] nNameLength\n        number of characters in the cComponentName string.  With all\n        component name strings restricted to less than 128 characters\n        (including the trailing null) it is recomended that the caller\n        provide a input string for the cComponentName of 128 characters.\n    @param [in] nIndex\n        number containing the enumeration index for the component.\n        Multiple calls to OMX_ComponentNameEnum with increasing values\n        of nIndex will enumerate through the component names in the\n        system until OMX_ErrorNoMore is returned.  The value of nIndex\n        is 0 to (N-1), where N is the number of valid installed components\n        in the system.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  When the value of nIndex exceeds the number of\n        components in the system minus 1, OMX_ErrorNoMore will be\n        returned. Otherwise the appropriate OMX error will be returned.\n    @ingroup core\n */\nOMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum(\n    OMX_OUT OMX_STRING cComponentName,\n    OMX_IN  OMX_U32 nNameLength,\n    OMX_IN  OMX_U32 nIndex);\n\n\n/** The OMX_GetHandle method will locate the component specified by the\n    component name given, load that component into memory and then invoke\n    the component's methods to create an instance of the component.\n\n    The core should return from this call within 20 msec.\n\n    @param [out] pHandle\n        pointer to an OMX_HANDLETYPE pointer to be filled in by this method.\n    @param [in] cComponentName\n        pointer to a null terminated string with the component name.  The\n        names of the components are strings less than 127 bytes in length\n        plus the trailing null for a maximum size of 128 bytes.  An example\n        of a valid component name is \"OMX.TI.AUDIO.DSP.MIXER\\0\".  Names are\n        assigned by the vendor, but shall start with \"OMX.\" and then have\n        the Vendor designation next.\n    @param [in] pAppData\n        pointer to an application defined value that will be returned\n        during callbacks so that the application can identify the source\n        of the callback.\n    @param [in] pCallBacks\n        pointer to a OMX_CALLBACKTYPE structure that will be passed to the\n        component to initialize it with.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup core\n */\nOMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(\n    OMX_OUT OMX_HANDLETYPE* pHandle,\n    OMX_IN  OMX_STRING cComponentName,\n    OMX_IN  OMX_PTR pAppData,\n    OMX_IN  OMX_CALLBACKTYPE* pCallBacks);\n\n\n/** The OMX_FreeHandle method will free a handle allocated by the OMX_GetHandle\n    method.  If the component reference count goes to zero, the component will\n    be unloaded from memory.\n\n    The core should return from this call within 20 msec when the component is\n    in the OMX_StateLoaded state.\n\n    @param [in] hComponent\n        Handle of the component to be accessed.  This is the component\n        handle returned by the call to the GetHandle function.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n    @ingroup core\n */\nOMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(\n    OMX_IN  OMX_HANDLETYPE hComponent);\n\n\n\n/** The OMX_SetupTunnel method will handle the necessary calls to the components\n    to setup the specified tunnel the two components.  NOTE: This is\n    an actual method (not a #define macro).  This method will make calls into\n    the component ComponentTunnelRequest method to do the actual tunnel\n    connection.\n\n    The ComponentTunnelRequest method on both components will be called.\n    This method shall not be called unless the component is in the\n    OMX_StateLoaded state except when the ports used for the tunnel are\n    disabled. In this case, the component may be in the OMX_StateExecuting,\n    OMX_StatePause, or OMX_StateIdle states.\n\n    The core should return from this call within 20 msec.\n\n    @param [in] hOutput\n        Handle of the component to be accessed.  Also this is the handle\n        of the component whose port, specified in the nPortOutput parameter\n        will be used the source for the tunnel. This is the component handle\n        returned by the call to the OMX_GetHandle function.  There is a\n        requirement that hOutput be the source for the data when\n        tunelling (i.e. nPortOutput is an output port).  If 0x0, the component\n        specified in hInput will have it's port specified in nPortInput\n        setup for communication with the application / IL client.\n    @param [in] nPortOutput\n        nPortOutput is used to select the source port on component to be\n        used in the tunnel.\n    @param [in] hInput\n        This is the component to setup the tunnel with. This is the handle\n        of the component whose port, specified in the nPortInput parameter\n        will be used the destination for the tunnel. This is the component handle\n        returned by the call to the OMX_GetHandle function.  There is a\n        requirement that hInput be the destination for the data when\n        tunelling (i.e. nPortInut is an input port).   If 0x0, the component\n        specified in hOutput will have it's port specified in nPortPOutput\n        setup for communication with the application / IL client.\n    @param [in] nPortInput\n        nPortInput is used to select the destination port on component to be\n        used in the tunnel.\n    @return OMX_ERRORTYPE\n        If the command successfully executes, the return code will be\n        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.\n        When OMX_ErrorNotImplemented is returned, one or both components is\n        a non-interop component and does not support tunneling.\n\n        On failure, the ports of both components are setup for communication\n        with the application / IL Client.\n    @ingroup core tun\n */\nOMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel(\n    OMX_IN  OMX_HANDLETYPE hOutput,\n    OMX_IN  OMX_U32 nPortOutput,\n    OMX_IN  OMX_HANDLETYPE hInput,\n    OMX_IN  OMX_U32 nPortInput);\n\n/** @ingroup cp */\nOMX_API OMX_ERRORTYPE   OMX_GetContentPipe(\n    OMX_OUT OMX_HANDLETYPE *hPipe,\n    OMX_IN OMX_STRING szURI);\n\n/** The OMX_GetComponentsOfRole method will return the number of components that support the given\n    role and (if the compNames field is non-NULL) the names of those components. The call will fail if\n    an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the\n    client should:\n        * first call this function with the compNames field NULL to determine the number of component names\n        * second call this function with the compNames field pointing to an array of names allocated\n          according to the number returned by the first call.\n\n    The core should return from this call within 5 msec.\n\n    @param [in] role\n        This is generic standard component name consisting only of component class\n        name and the type within that class (e.g. 'audio_decoder.aac').\n    @param [inout] pNumComps\n        This is used both as input and output.\n\n        If compNames is NULL, the input is ignored and the output specifies how many components support\n        the given role.\n\n        If compNames is not NULL, on input it bounds the size of the input structure and\n        on output, it specifies the number of components string names listed within the compNames parameter.\n    @param [inout] compNames\n        If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings which accepts\n        a list of the names of all physical components that implement the specified standard component name.\n        Each name is NULL terminated. numComps indicates the number of names.\n    @ingroup core\n */\nOMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole (\n    OMX_IN      OMX_STRING role,\n    OMX_INOUT   OMX_U32 *pNumComps,\n    OMX_INOUT   OMX_U8  **compNames);\n\n/** The OMX_GetRolesOfComponent method will return the number of roles supported by the given\n    component and (if the roles field is non-NULL) the names of those roles. The call will fail if\n    an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the\n    client should:\n        * first call this function with the roles field NULL to determine the number of role names\n        * second call this function with the roles field pointing to an array of names allocated\n          according to the number returned by the first call.\n\n    The core should return from this call within 5 msec.\n\n    @param [in] compName\n        This is the name of the component being queried about.\n    @param [inout] pNumRoles\n        This is used both as input and output.\n\n        If roles is NULL, the input is ignored and the output specifies how many roles the component supports.\n\n        If compNames is not NULL, on input it bounds the size of the input structure and\n        on output, it specifies the number of roles string names listed within the roles parameter.\n    @param [out] roles\n        If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings\n        which accepts a list of the names of all standard components roles implemented on the\n        specified component name. numComps indicates the number of names.\n    @ingroup core\n */\nOMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent (\n    OMX_IN      OMX_STRING compName,\n    OMX_INOUT   OMX_U32 *pNumRoles,\n    OMX_OUT     OMX_U8 **roles);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n/* File EOF */\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/openmax/OMX_IVCommon.h",
    "content": "/* ------------------------------------------------------------------\n * Copyright (C) 1998-2009 PacketVideo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n * express or implied.\n * See the License for the specific language governing permissions\n * and limitations under the License.\n * -------------------------------------------------------------------\n */\n/**\n * Copyright (c) 2008 The Khronos Group Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject\n * to the following conditions:\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n/**\n * @file OMX_IVCommon.h - OpenMax IL version 1.1.2\n *  The structures needed by Video and Image components to exchange\n *  parameters and configuration data with the components.\n */\n#ifndef OMX_IVCommon_h\n#define OMX_IVCommon_h\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/**\n * Each OMX header must include all required header files to allow the header\n * to compile without errors.  The includes below are required for this header\n * file to compile successfully\n */\n\n#include <OMX_Core.h>\n\n/** @defgroup iv OpenMAX IL Imaging and Video Domain\n * Common structures for OpenMAX IL Imaging and Video domains\n * @{\n */\n\n\n/**\n * Enumeration defining possible uncompressed image/video formats.\n *\n * ENUMS:\n *  Unused                 : Placeholder value when format is N/A\n *  Monochrome             : black and white\n *  8bitRGB332             : Red 7:5, Green 4:2, Blue 1:0\n *  12bitRGB444            : Red 11:8, Green 7:4, Blue 3:0\n *  16bitARGB4444          : Alpha 15:12, Red 11:8, Green 7:4, Blue 3:0\n *  16bitARGB1555          : Alpha 15, Red 14:10, Green 9:5, Blue 4:0\n *  16bitRGB565            : Red 15:11, Green 10:5, Blue 4:0\n *  16bitBGR565            : Blue 15:11, Green 10:5, Red 4:0\n *  18bitRGB666            : Red 17:12, Green 11:6, Blue 5:0\n *  18bitARGB1665          : Alpha 17, Red 16:11, Green 10:5, Blue 4:0\n *  19bitARGB1666          : Alpha 18, Red 17:12, Green 11:6, Blue 5:0\n *  24bitRGB888            : Red 24:16, Green 15:8, Blue 7:0\n *  24bitBGR888            : Blue 24:16, Green 15:8, Red 7:0\n *  24bitARGB1887          : Alpha 23, Red 22:15, Green 14:7, Blue 6:0\n *  25bitARGB1888          : Alpha 24, Red 23:16, Green 15:8, Blue 7:0\n *  32bitBGRA8888          : Blue 31:24, Green 23:16, Red 15:8, Alpha 7:0\n *  32bitARGB8888          : Alpha 31:24, Red 23:16, Green 15:8, Blue 7:0\n *  YUV411Planar           : U,Y are subsampled by a factor of 4 horizontally\n *  YUV411PackedPlanar     : packed per payload in planar slices\n *  YUV420Planar           : Three arrays Y,U,V.\n *  YUV420PackedPlanar     : packed per payload in planar slices\n *  YUV420SemiPlanar       : Two arrays, one is all Y, the other is U and V\n *  YUV422Planar           : Three arrays Y,U,V.\n *  YUV422PackedPlanar     : packed per payload in planar slices\n *  YUV422SemiPlanar       : Two arrays, one is all Y, the other is U and V\n *  YCbYCr                 : Organized as 16bit YUYV (i.e. YCbYCr)\n *  YCrYCb                 : Organized as 16bit YVYU (i.e. YCrYCb)\n *  CbYCrY                 : Organized as 16bit UYVY (i.e. CbYCrY)\n *  CrYCbY                 : Organized as 16bit VYUY (i.e. CrYCbY)\n *  YUV444Interleaved      : Each pixel contains equal parts YUV\n *  RawBayer8bit           : SMIA camera output format\n *  RawBayer10bit          : SMIA camera output format\n *  RawBayer8bitcompressed : SMIA camera output format\n */\ntypedef enum OMX_COLOR_FORMATTYPE {\n    OMX_COLOR_FormatUnused,\n    OMX_COLOR_FormatMonochrome,\n    OMX_COLOR_Format8bitRGB332,\n    OMX_COLOR_Format12bitRGB444,\n    OMX_COLOR_Format16bitARGB4444,\n    OMX_COLOR_Format16bitARGB1555,\n    OMX_COLOR_Format16bitRGB565,\n    OMX_COLOR_Format16bitBGR565,\n    OMX_COLOR_Format18bitRGB666,\n    OMX_COLOR_Format18bitARGB1665,\n    OMX_COLOR_Format19bitARGB1666,\n    OMX_COLOR_Format24bitRGB888,\n    OMX_COLOR_Format24bitBGR888,\n    OMX_COLOR_Format24bitARGB1887,\n    OMX_COLOR_Format25bitARGB1888,\n    OMX_COLOR_Format32bitBGRA8888,\n    OMX_COLOR_Format32bitARGB8888,\n    OMX_COLOR_FormatYUV411Planar,\n    OMX_COLOR_FormatYUV411PackedPlanar,\n    OMX_COLOR_FormatYUV420Planar,\n    OMX_COLOR_FormatYUV420PackedPlanar,\n    OMX_COLOR_FormatYUV420SemiPlanar,\n    OMX_COLOR_FormatYUV422Planar,\n    OMX_COLOR_FormatYUV422PackedPlanar,\n    OMX_COLOR_FormatYUV422SemiPlanar,\n    OMX_COLOR_FormatYCbYCr,\n    OMX_COLOR_FormatYCrYCb,\n    OMX_COLOR_FormatCbYCrY,\n    OMX_COLOR_FormatCrYCbY,\n    OMX_COLOR_FormatYUV444Interleaved,\n    OMX_COLOR_FormatRawBayer8bit,\n    OMX_COLOR_FormatRawBayer10bit,\n    OMX_COLOR_FormatRawBayer8bitcompressed,\n    OMX_COLOR_FormatL2,\n    OMX_COLOR_FormatL4,\n    OMX_COLOR_FormatL8,\n    OMX_COLOR_FormatL16,\n    OMX_COLOR_FormatL24,\n    OMX_COLOR_FormatL32,\n    OMX_COLOR_FormatYUV420PackedSemiPlanar,\n    OMX_COLOR_FormatYUV422PackedSemiPlanar,\n    OMX_COLOR_Format18BitBGR666,\n    OMX_COLOR_Format24BitARGB6666,\n    OMX_COLOR_Format24BitABGR6666,\n    OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    /**<Reserved android opaque colorformat. Tells the encoder that\n     * the actual colorformat will be  relayed by the\n     * Gralloc Buffers.\n     * FIXME: In the process of reserving some enum values for\n     * Android-specific OMX IL colorformats. Change this enum to\n     * an acceptable range once that is done.\n     * */\n    OMX_COLOR_FormatAndroidOpaque = 0x7F000789,\n    OMX_COLOR_Format32BitRGBA8888 = 0x7F00A000,\n    /** Flexible 8-bit YUV format.  Codec should report this format\n     *  as being supported if it supports any YUV420 packed planar\n     *  or semiplanar formats.  When port is set to use this format,\n     *  codec can substitute any YUV420 packed planar or semiplanar\n     *  format for it. */\n    OMX_COLOR_FormatYUV420Flexible = 0x7F420888,\n\n    OMX_TI_COLOR_FormatYUV420PackedSemiPlanar = 0x7F000100,\n    OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00,\n    OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7FA30C03,\n    OMX_SEC_COLOR_FormatNV12Tiled = 0x7FC00002,\n    OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m = 0x7FA30C04,\n    OMX_COLOR_FormatMax = 0x7FFFFFFF\n} OMX_COLOR_FORMATTYPE;\n\n\n/**\n * Defines the matrix for conversion from RGB to YUV or vice versa.\n * iColorMatrix should be initialized with the fixed point values\n * used in converting between formats.\n */\ntypedef struct OMX_CONFIG_COLORCONVERSIONTYPE {\n    OMX_U32 nSize;              /**< Size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version info */\n    OMX_U32 nPortIndex;         /**< Port that this struct applies to */\n    OMX_S32 xColorMatrix[3][3]; /**< Stored in signed Q16 format */\n    OMX_S32 xColorOffset[4];    /**< Stored in signed Q16 format */\n}OMX_CONFIG_COLORCONVERSIONTYPE;\n\n\n/**\n * Structure defining percent to scale each frame dimension.  For example:\n * To make the width 50% larger, use fWidth = 1.5 and to make the width\n * 1/2 the original size, use fWidth = 0.5\n */\ntypedef struct OMX_CONFIG_SCALEFACTORTYPE {\n    OMX_U32 nSize;            /**< Size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version info */\n    OMX_U32 nPortIndex;       /**< Port that this struct applies to */\n    OMX_S32 xWidth;           /**< Fixed point value stored as Q16 */\n    OMX_S32 xHeight;          /**< Fixed point value stored as Q16 */\n}OMX_CONFIG_SCALEFACTORTYPE;\n\n\n/**\n * Enumeration of possible image filter types\n */\ntypedef enum OMX_IMAGEFILTERTYPE {\n    OMX_ImageFilterNone,\n    OMX_ImageFilterNoise,\n    OMX_ImageFilterEmboss,\n    OMX_ImageFilterNegative,\n    OMX_ImageFilterSketch,\n    OMX_ImageFilterOilPaint,\n    OMX_ImageFilterHatch,\n    OMX_ImageFilterGpen,\n    OMX_ImageFilterAntialias,\n    OMX_ImageFilterDeRing,\n    OMX_ImageFilterSolarize,\n    OMX_ImageFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_ImageFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_ImageFilterMax = 0x7FFFFFFF\n} OMX_IMAGEFILTERTYPE;\n\n\n/**\n * Image filter configuration\n *\n * STRUCT MEMBERS:\n *  nSize        : Size of the structure in bytes\n *  nVersion     : OMX specification version information\n *  nPortIndex   : Port that this structure applies to\n *  eImageFilter : Image filter type enumeration\n */\ntypedef struct OMX_CONFIG_IMAGEFILTERTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_IMAGEFILTERTYPE eImageFilter;\n} OMX_CONFIG_IMAGEFILTERTYPE;\n\n\n/**\n * Customized U and V for color enhancement\n *\n * STRUCT MEMBERS:\n *  nSize             : Size of the structure in bytes\n *  nVersion          : OMX specification version information\n *  nPortIndex        : Port that this structure applies to\n *  bColorEnhancement : Enable/disable color enhancement\n *  nCustomizedU      : Practical values: 16-240, range: 0-255, value set for\n *                      U component\n *  nCustomizedV      : Practical values: 16-240, range: 0-255, value set for\n *                      V component\n */\ntypedef struct OMX_CONFIG_COLORENHANCEMENTTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL bColorEnhancement;\n    OMX_U8 nCustomizedU;\n    OMX_U8 nCustomizedV;\n} OMX_CONFIG_COLORENHANCEMENTTYPE;\n\n\n/**\n * Define color key and color key mask\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nARGBColor : 32bit Alpha, Red, Green, Blue Color\n *  nARGBMask  : 32bit Mask for Alpha, Red, Green, Blue channels\n */\ntypedef struct OMX_CONFIG_COLORKEYTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nARGBColor;\n    OMX_U32 nARGBMask;\n} OMX_CONFIG_COLORKEYTYPE;\n\n\n/**\n * List of color blend types for pre/post processing\n *\n * ENUMS:\n *  None          : No color blending present\n *  AlphaConstant : Function is (alpha_constant * src) +\n *                  (1 - alpha_constant) * dst)\n *  AlphaPerPixel : Function is (alpha * src) + (1 - alpha) * dst)\n *  Alternate     : Function is alternating pixels from src and dst\n *  And           : Function is (src & dst)\n *  Or            : Function is (src | dst)\n *  Invert        : Function is ~src\n */\ntypedef enum OMX_COLORBLENDTYPE {\n    OMX_ColorBlendNone,\n    OMX_ColorBlendAlphaConstant,\n    OMX_ColorBlendAlphaPerPixel,\n    OMX_ColorBlendAlternate,\n    OMX_ColorBlendAnd,\n    OMX_ColorBlendOr,\n    OMX_ColorBlendInvert,\n    OMX_ColorBlendKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_ColorBlendVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_ColorBlendMax = 0x7FFFFFFF\n} OMX_COLORBLENDTYPE;\n\n\n/**\n * Color blend configuration\n *\n * STRUCT MEMBERS:\n *  nSize             : Size of the structure in bytes\n *  nVersion          : OMX specification version information\n *  nPortIndex        : Port that this structure applies to\n *  nRGBAlphaConstant : Constant global alpha values when global alpha is used\n *  eColorBlend       : Color blend type enumeration\n */\ntypedef struct OMX_CONFIG_COLORBLENDTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nRGBAlphaConstant;\n    OMX_COLORBLENDTYPE  eColorBlend;\n} OMX_CONFIG_COLORBLENDTYPE;\n\n\n/**\n * Hold frame dimension\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nWidth     : Frame width in pixels\n *  nHeight    : Frame height in pixels\n */\ntypedef struct OMX_FRAMESIZETYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nWidth;\n    OMX_U32 nHeight;\n} OMX_FRAMESIZETYPE;\n\n\n/**\n * Rotation configuration\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nRotation  : +/- integer rotation value\n */\ntypedef struct OMX_CONFIG_ROTATIONTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_S32 nRotation;\n} OMX_CONFIG_ROTATIONTYPE;\n\n\n/**\n * Possible mirroring directions for pre/post processing\n *\n * ENUMS:\n *  None       : No mirroring\n *  Vertical   : Vertical mirroring, flip on X axis\n *  Horizontal : Horizontal mirroring, flip on Y axis\n *  Both       : Both vertical and horizontal mirroring\n */\ntypedef enum OMX_MIRRORTYPE {\n    OMX_MirrorNone = 0,\n    OMX_MirrorVertical,\n    OMX_MirrorHorizontal,\n    OMX_MirrorBoth,\n    OMX_MirrorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_MirrorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_MirrorMax = 0x7FFFFFFF\n} OMX_MIRRORTYPE;\n\n\n/**\n * Mirroring configuration\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  eMirror    : Mirror type enumeration\n */\ntypedef struct OMX_CONFIG_MIRRORTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_MIRRORTYPE  eMirror;\n} OMX_CONFIG_MIRRORTYPE;\n\n\n/**\n * Position information only\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nX         : X coordinate for the point\n *  nY         : Y coordinate for the point\n */\ntypedef struct OMX_CONFIG_POINTTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_S32 nX;\n    OMX_S32 nY;\n} OMX_CONFIG_POINTTYPE;\n\n\n/**\n * Frame size plus position\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nLeft      : X Coordinate of the top left corner of the rectangle\n *  nTop       : Y Coordinate of the top left corner of the rectangle\n *  nWidth     : Width of the rectangle\n *  nHeight    : Height of the rectangle\n */\ntypedef struct OMX_CONFIG_RECTTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_S32 nLeft;\n    OMX_S32 nTop;\n    OMX_U32 nWidth;\n    OMX_U32 nHeight;\n} OMX_CONFIG_RECTTYPE;\n\n\n/**\n * Deblocking state; it is required to be set up before starting the codec\n *\n * STRUCT MEMBERS:\n *  nSize       : Size of the structure in bytes\n *  nVersion    : OMX specification version information\n *  nPortIndex  : Port that this structure applies to\n *  bDeblocking : Enable/disable deblocking mode\n */\ntypedef struct OMX_PARAM_DEBLOCKINGTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL bDeblocking;\n} OMX_PARAM_DEBLOCKINGTYPE;\n\n\n/**\n * Stabilization state\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  bStab      : Enable/disable frame stabilization state\n */\ntypedef struct OMX_CONFIG_FRAMESTABTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL bStab;\n} OMX_CONFIG_FRAMESTABTYPE;\n\n\n/**\n * White Balance control type\n *\n * STRUCT MEMBERS:\n *  SunLight : Referenced in JSR-234\n *  Flash    : Optimal for device's integrated flash\n */\ntypedef enum OMX_WHITEBALCONTROLTYPE {\n    OMX_WhiteBalControlOff = 0,\n    OMX_WhiteBalControlAuto,\n    OMX_WhiteBalControlSunLight,\n    OMX_WhiteBalControlCloudy,\n    OMX_WhiteBalControlShade,\n    OMX_WhiteBalControlTungsten,\n    OMX_WhiteBalControlFluorescent,\n    OMX_WhiteBalControlIncandescent,\n    OMX_WhiteBalControlFlash,\n    OMX_WhiteBalControlHorizon,\n    OMX_WhiteBalControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_WhiteBalControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_WhiteBalControlMax = 0x7FFFFFFF\n} OMX_WHITEBALCONTROLTYPE;\n\n\n/**\n * White Balance control configuration\n *\n * STRUCT MEMBERS:\n *  nSize            : Size of the structure in bytes\n *  nVersion         : OMX specification version information\n *  nPortIndex       : Port that this structure applies to\n *  eWhiteBalControl : White balance enumeration\n */\ntypedef struct OMX_CONFIG_WHITEBALCONTROLTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_WHITEBALCONTROLTYPE eWhiteBalControl;\n} OMX_CONFIG_WHITEBALCONTROLTYPE;\n\n\n/**\n * Exposure control type\n */\ntypedef enum OMX_EXPOSURECONTROLTYPE {\n    OMX_ExposureControlOff = 0,\n    OMX_ExposureControlAuto,\n    OMX_ExposureControlNight,\n    OMX_ExposureControlBackLight,\n    OMX_ExposureControlSpotLight,\n    OMX_ExposureControlSports,\n    OMX_ExposureControlSnow,\n    OMX_ExposureControlBeach,\n    OMX_ExposureControlLargeAperture,\n    OMX_ExposureControlSmallApperture,\n    OMX_ExposureControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_ExposureControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_ExposureControlMax = 0x7FFFFFFF\n} OMX_EXPOSURECONTROLTYPE;\n\n\n/**\n * White Balance control configuration\n *\n * STRUCT MEMBERS:\n *  nSize            : Size of the structure in bytes\n *  nVersion         : OMX specification version information\n *  nPortIndex       : Port that this structure applies to\n *  eExposureControl : Exposure control enumeration\n */\ntypedef struct OMX_CONFIG_EXPOSURECONTROLTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_EXPOSURECONTROLTYPE eExposureControl;\n} OMX_CONFIG_EXPOSURECONTROLTYPE;\n\n\n/**\n * Defines sensor supported mode.\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nFrameRate : Single shot mode is indicated by a 0\n *  bOneShot   : Enable for single shot, disable for streaming\n *  sFrameSize : Framesize\n */\ntypedef struct OMX_PARAM_SENSORMODETYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nFrameRate;\n    OMX_BOOL bOneShot;\n    OMX_FRAMESIZETYPE sFrameSize;\n} OMX_PARAM_SENSORMODETYPE;\n\n\n/**\n * Defines contrast level\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nContrast  : Values allowed for contrast -100 to 100, zero means no change\n */\ntypedef struct OMX_CONFIG_CONTRASTTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_S32 nContrast;\n} OMX_CONFIG_CONTRASTTYPE;\n\n\n/**\n * Defines brightness level\n *\n * STRUCT MEMBERS:\n *  nSize       : Size of the structure in bytes\n *  nVersion    : OMX specification version information\n *  nPortIndex  : Port that this structure applies to\n *  nBrightness : 0-100%\n */\ntypedef struct OMX_CONFIG_BRIGHTNESSTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nBrightness;\n} OMX_CONFIG_BRIGHTNESSTYPE;\n\n\n/**\n * Defines backlight level configuration for a video sink, e.g. LCD panel\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nBacklight : Values allowed for backlight 0-100%\n *  nTimeout   : Number of milliseconds before backlight automatically turns\n *               off.  A value of 0x0 disables backight timeout\n */\ntypedef struct OMX_CONFIG_BACKLIGHTTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nBacklight;\n    OMX_U32 nTimeout;\n} OMX_CONFIG_BACKLIGHTTYPE;\n\n\n/**\n * Defines setting for Gamma\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nGamma     : Values allowed for gamma -100 to 100, zero means no change\n */\ntypedef struct OMX_CONFIG_GAMMATYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_S32 nGamma;\n} OMX_CONFIG_GAMMATYPE;\n\n\n/**\n * Define for setting saturation\n *\n * STRUCT MEMBERS:\n *  nSize       : Size of the structure in bytes\n *  nVersion    : OMX specification version information\n *  nPortIndex  : Port that this structure applies to\n *  nSaturation : Values allowed for saturation -100 to 100, zero means\n *                no change\n */\ntypedef struct OMX_CONFIG_SATURATIONTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_S32 nSaturation;\n} OMX_CONFIG_SATURATIONTYPE;\n\n\n/**\n * Define for setting Lightness\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nLightness : Values allowed for lightness -100 to 100, zero means no\n *               change\n */\ntypedef struct OMX_CONFIG_LIGHTNESSTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_S32 nLightness;\n} OMX_CONFIG_LIGHTNESSTYPE;\n\n\n/**\n * Plane blend configuration\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Index of input port associated with the plane.\n *  nDepth     : Depth of the plane in relation to the screen. Higher\n *               numbered depths are \"behind\" lower number depths.\n *               This number defaults to the Port Index number.\n *  nAlpha     : Transparency blending component for the entire plane.\n *               See blending modes for more detail.\n */\ntypedef struct OMX_CONFIG_PLANEBLENDTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nDepth;\n    OMX_U32 nAlpha;\n} OMX_CONFIG_PLANEBLENDTYPE;\n\n\n/**\n * Define interlace type\n *\n * STRUCT MEMBERS:\n *  nSize                 : Size of the structure in bytes\n *  nVersion              : OMX specification version information\n *  nPortIndex            : Port that this structure applies to\n *  bEnable               : Enable control variable for this functionality\n *                          (see below)\n *  nInterleavePortIndex  : Index of input or output port associated with\n *                          the interleaved plane.\n *  pPlanarPortIndexes[4] : Index of input or output planar ports.\n */\ntypedef struct OMX_PARAM_INTERLEAVETYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL bEnable;\n    OMX_U32 nInterleavePortIndex;\n} OMX_PARAM_INTERLEAVETYPE;\n\n\n/**\n * Defines the picture effect used for an input picture\n */\ntypedef enum OMX_TRANSITIONEFFECTTYPE {\n    OMX_EffectNone,\n    OMX_EffectFadeFromBlack,\n    OMX_EffectFadeToBlack,\n    OMX_EffectUnspecifiedThroughConstantColor,\n    OMX_EffectDissolve,\n    OMX_EffectWipe,\n    OMX_EffectUnspecifiedMixOfTwoScenes,\n    OMX_EffectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_EffectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_EffectMax = 0x7FFFFFFF\n} OMX_TRANSITIONEFFECTTYPE;\n\n\n/**\n * Structure used to configure current transition effect\n *\n * STRUCT MEMBERS:\n * nSize      : Size of the structure in bytes\n * nVersion   : OMX specification version information\n * nPortIndex : Port that this structure applies to\n * eEffect    : Effect to enable\n */\ntypedef struct OMX_CONFIG_TRANSITIONEFFECTTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_TRANSITIONEFFECTTYPE eEffect;\n} OMX_CONFIG_TRANSITIONEFFECTTYPE;\n\n\n/**\n * Defines possible data unit types for encoded video data. The data unit\n * types are used both for encoded video input for playback as well as\n * encoded video output from recording.\n */\ntypedef enum OMX_DATAUNITTYPE {\n    OMX_DataUnitCodedPicture,\n    OMX_DataUnitVideoSegment,\n    OMX_DataUnitSeveralSegments,\n    OMX_DataUnitArbitraryStreamSection,\n    OMX_DataUnitKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_DataUnitVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_DataUnitMax = 0x7FFFFFFF\n} OMX_DATAUNITTYPE;\n\n\n/**\n * Defines possible encapsulation types for coded video data unit. The\n * encapsulation information is used both for encoded video input for\n * playback as well as encoded video output from recording.\n */\ntypedef enum OMX_DATAUNITENCAPSULATIONTYPE {\n    OMX_DataEncapsulationElementaryStream,\n    OMX_DataEncapsulationGenericPayload,\n    OMX_DataEncapsulationRtpPayload,\n    OMX_DataEncapsulationKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_DataEncapsulationVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_DataEncapsulationMax = 0x7FFFFFFF\n} OMX_DATAUNITENCAPSULATIONTYPE;\n\n\n/**\n * Structure used to configure the type of being decoded/encoded\n */\ntypedef struct OMX_PARAM_DATAUNITTYPE {\n    OMX_U32 nSize;            /**< Size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex;       /**< Port that this structure applies to */\n    OMX_DATAUNITTYPE eUnitType;\n    OMX_DATAUNITENCAPSULATIONTYPE eEncapsulationType;\n} OMX_PARAM_DATAUNITTYPE;\n\n\n/**\n * Defines dither types\n */\ntypedef enum OMX_DITHERTYPE {\n    OMX_DitherNone,\n    OMX_DitherOrdered,\n    OMX_DitherErrorDiffusion,\n    OMX_DitherOther,\n    OMX_DitherKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_DitherVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_DitherMax = 0x7FFFFFFF\n} OMX_DITHERTYPE;\n\n\n/**\n * Structure used to configure current type of dithering\n */\ntypedef struct OMX_CONFIG_DITHERTYPE {\n    OMX_U32 nSize;            /**< Size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex;       /**< Port that this structure applies to */\n    OMX_DITHERTYPE eDither;   /**< Type of dithering to use */\n} OMX_CONFIG_DITHERTYPE;\n\ntypedef struct OMX_CONFIG_CAPTUREMODETYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;     /**< Port that this structure applies to */\n    OMX_BOOL bContinuous;   /**< If true then ignore frame rate and emit capture\n                             *   data as fast as possible (otherwise obey port's frame rate). */\n    OMX_BOOL bFrameLimited; /**< If true then terminate capture after the port emits the\n                             *   specified number of frames (otherwise the port does not\n                             *   terminate the capture until instructed to do so by the client).\n                             *   Even if set, the client may manually terminate the capture prior\n                             *   to reaching the limit. */\n    OMX_U32 nFrameLimit;      /**< Limit on number of frames emitted during a capture (only\n                               *   valid if bFrameLimited is set). */\n} OMX_CONFIG_CAPTUREMODETYPE;\n\ntypedef enum OMX_METERINGTYPE {\n\n    OMX_MeteringModeAverage,     /**< Center-weighted average metering. */\n    OMX_MeteringModeSpot,        /**< Spot (partial) metering. */\n    OMX_MeteringModeMatrix,      /**< Matrix or evaluative metering. */\n\n    OMX_MeteringKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_MeteringVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_EVModeMax = 0x7fffffff\n} OMX_METERINGTYPE;\n\ntypedef struct OMX_CONFIG_EXPOSUREVALUETYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_METERINGTYPE eMetering;\n    OMX_S32 xEVCompensation;      /**< Fixed point value stored as Q16 */\n    OMX_U32 nApertureFNumber;     /**< e.g. nApertureFNumber = 2 implies \"f/2\" - Q16 format */\n    OMX_BOOL bAutoAperture;       /**< Whether aperture number is defined automatically */\n    OMX_U32 nShutterSpeedMsec;    /**< Shutterspeed in milliseconds */\n    OMX_BOOL bAutoShutterSpeed;   /**< Whether shutter speed is defined automatically */\n    OMX_U32 nSensitivity;         /**< e.g. nSensitivity = 100 implies \"ISO 100\" */\n    OMX_BOOL bAutoSensitivity;    /**< Whether sensitivity is defined automatically */\n} OMX_CONFIG_EXPOSUREVALUETYPE;\n\n/**\n * Focus region configuration\n *\n * STRUCT MEMBERS:\n *  nSize           : Size of the structure in bytes\n *  nVersion        : OMX specification version information\n *  nPortIndex      : Port that this structure applies to\n *  bCenter         : Use center region as focus region of interest\n *  bLeft           : Use left region as focus region of interest\n *  bRight          : Use right region as focus region of interest\n *  bTop            : Use top region as focus region of interest\n *  bBottom         : Use bottom region as focus region of interest\n *  bTopLeft        : Use top left region as focus region of interest\n *  bTopRight       : Use top right region as focus region of interest\n *  bBottomLeft     : Use bottom left region as focus region of interest\n *  bBottomRight    : Use bottom right region as focus region of interest\n */\ntypedef struct OMX_CONFIG_FOCUSREGIONTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL bCenter;\n    OMX_BOOL bLeft;\n    OMX_BOOL bRight;\n    OMX_BOOL bTop;\n    OMX_BOOL bBottom;\n    OMX_BOOL bTopLeft;\n    OMX_BOOL bTopRight;\n    OMX_BOOL bBottomLeft;\n    OMX_BOOL bBottomRight;\n} OMX_CONFIG_FOCUSREGIONTYPE;\n\n/**\n * Focus Status type\n */\ntypedef enum OMX_FOCUSSTATUSTYPE {\n    OMX_FocusStatusOff = 0,\n    OMX_FocusStatusRequest,\n    OMX_FocusStatusReached,\n    OMX_FocusStatusUnableToReach,\n    OMX_FocusStatusLost,\n    OMX_FocusStatusKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_FocusStatusVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_FocusStatusMax = 0x7FFFFFFF\n} OMX_FOCUSSTATUSTYPE;\n\n/**\n * Focus status configuration\n *\n * STRUCT MEMBERS:\n *  nSize               : Size of the structure in bytes\n *  nVersion            : OMX specification version information\n *  nPortIndex          : Port that this structure applies to\n *  eFocusStatus        : Specifies the focus status\n *  bCenterStatus       : Use center region as focus region of interest\n *  bLeftStatus         : Use left region as focus region of interest\n *  bRightStatus        : Use right region as focus region of interest\n *  bTopStatus          : Use top region as focus region of interest\n *  bBottomStatus       : Use bottom region as focus region of interest\n *  bTopLeftStatus      : Use top left region as focus region of interest\n *  bTopRightStatus     : Use top right region as focus region of interest\n *  bBottomLeftStatus   : Use bottom left region as focus region of interest\n *  bBottomRightStatus  : Use bottom right region as focus region of interest\n */\ntypedef struct OMX_PARAM_FOCUSSTATUSTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_FOCUSSTATUSTYPE eFocusStatus;\n    OMX_BOOL bCenterStatus;\n    OMX_BOOL bLeftStatus;\n    OMX_BOOL bRightStatus;\n    OMX_BOOL bTopStatus;\n    OMX_BOOL bBottomStatus;\n    OMX_BOOL bTopLeftStatus;\n    OMX_BOOL bTopRightStatus;\n    OMX_BOOL bBottomLeftStatus;\n    OMX_BOOL bBottomRightStatus;\n} OMX_PARAM_FOCUSSTATUSTYPE;\n\n/** @} */\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n/* File EOF */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/openmax/OMX_Image.h",
    "content": "/* ------------------------------------------------------------------\n * Copyright (C) 1998-2009 PacketVideo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n * express or implied.\n * See the License for the specific language governing permissions\n * and limitations under the License.\n * -------------------------------------------------------------------\n */\n/**\n * Copyright (c) 2008 The Khronos Group Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject\n * to the following conditions:\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n/**\n * @file OMX_Image.h - OpenMax IL version 1.1.2\n * The structures needed by Image components to exchange parameters and\n * configuration data with the components.\n */\n#ifndef OMX_Image_h\n#define OMX_Image_h\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n\n/**\n * Each OMX header must include all required header files to allow the\n * header to compile without errors.  The includes below are required\n * for this header file to compile successfully\n */\n\n#include <OMX_IVCommon.h>\n\n/** @defgroup imaging OpenMAX IL Imaging Domain\n * @ingroup iv\n * Structures for OpenMAX IL Imaging domain\n * @{\n */\n\n/**\n * Enumeration used to define the possible image compression coding.\n */\ntypedef enum OMX_IMAGE_CODINGTYPE {\n    OMX_IMAGE_CodingUnused,      /**< Value when format is N/A */\n    OMX_IMAGE_CodingAutoDetect,  /**< Auto detection of image format */\n    OMX_IMAGE_CodingJPEG,        /**< JPEG/JFIF image format */\n    OMX_IMAGE_CodingJPEG2K,      /**< JPEG 2000 image format */\n    OMX_IMAGE_CodingEXIF,        /**< EXIF image format */\n    OMX_IMAGE_CodingTIFF,        /**< TIFF image format */\n    OMX_IMAGE_CodingGIF,         /**< Graphics image format */\n    OMX_IMAGE_CodingPNG,         /**< PNG image format */\n    OMX_IMAGE_CodingLZW,         /**< LZW image format */\n    OMX_IMAGE_CodingBMP,         /**< Windows Bitmap format */\n    OMX_IMAGE_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_IMAGE_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_IMAGE_CodingMax = 0x7FFFFFFF\n} OMX_IMAGE_CODINGTYPE;\n\n\n/**\n * Data structure used to define an image path. The number of image paths\n * for input and output will vary by type of the image component.\n *\n *  Input (aka Source) : Zero Inputs, one Output,\n *  Splitter           : One Input, 2 or more Outputs,\n *  Processing Element : One Input, one output,\n *  Mixer              : 2 or more inputs, one output,\n *  Output (aka Sink)  : One Input, zero outputs.\n *\n * The PortDefinition structure is used to define all of the parameters\n * necessary for the compliant component to setup an input or an output\n * image path.  If additional vendor specific data is required, it should\n * be transmitted to the component using the CustomCommand function.\n * Compliant components will prepopulate this structure with optimal\n * values during the OMX_GetParameter() command.\n *\n * STRUCT MEMBERS:\n *  cMIMEType             : MIME type of data for the port\n *  pNativeRender         : Platform specific reference for a display if a\n *                          sync, otherwise this field is 0\n *  nFrameWidth           : Width of frame to be used on port if\n *                          uncompressed format is used.  Use 0 for\n *                          unknown, don't care or variable\n *  nFrameHeight          : Height of frame to be used on port if\n *                          uncompressed format is used. Use 0 for\n *                          unknown, don't care or variable\n *  nStride               : Number of bytes per span of an image (i.e.\n *                          indicates the number of bytes to get from\n *                          span N to span N+1, where negative stride\n *                          indicates the image is bottom up\n *  nSliceHeight          : Height used when encoding in slices\n *  bFlagErrorConcealment : Turns on error concealment if it is supported by\n *                          the OMX component\n *  eCompressionFormat    : Compression format used in this instance of\n *                          the component. When OMX_IMAGE_CodingUnused is\n *                          specified, eColorFormat is valid\n *  eColorFormat          : Decompressed format used by this component\n *  pNativeWindow         : Platform specific reference for a window object if a\n *                          display sink , otherwise this field is 0x0.\n */\ntypedef struct OMX_IMAGE_PORTDEFINITIONTYPE {\n    OMX_STRING cMIMEType;\n    OMX_NATIVE_DEVICETYPE pNativeRender;\n    OMX_U32 nFrameWidth;\n    OMX_U32 nFrameHeight;\n    OMX_S32 nStride;\n    OMX_U32 nSliceHeight;\n    OMX_BOOL bFlagErrorConcealment;\n    OMX_IMAGE_CODINGTYPE eCompressionFormat;\n    OMX_COLOR_FORMATTYPE eColorFormat;\n    OMX_NATIVE_WINDOWTYPE pNativeWindow;\n} OMX_IMAGE_PORTDEFINITIONTYPE;\n\n\n/**\n * Port format parameter.  This structure is used to enumerate the various\n * data input/output format supported by the port.\n *\n * STRUCT MEMBERS:\n *  nSize              : Size of the structure in bytes\n *  nVersion           : OMX specification version information\n *  nPortIndex         : Indicates which port to set\n *  nIndex             : Indicates the enumeration index for the format from\n *                       0x0 to N-1\n *  eCompressionFormat : Compression format used in this instance of the\n *                       component. When OMX_IMAGE_CodingUnused is specified,\n *                       eColorFormat is valid\n *  eColorFormat       : Decompressed format used by this component\n */\ntypedef struct OMX_IMAGE_PARAM_PORTFORMATTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nIndex;\n    OMX_IMAGE_CODINGTYPE eCompressionFormat;\n    OMX_COLOR_FORMATTYPE eColorFormat;\n} OMX_IMAGE_PARAM_PORTFORMATTYPE;\n\n\n/**\n * Flash control type\n *\n * ENUMS\n *  Torch : Flash forced constantly on\n */\ntypedef enum OMX_IMAGE_FLASHCONTROLTYPE {\n    OMX_IMAGE_FlashControlOn = 0,\n    OMX_IMAGE_FlashControlOff,\n    OMX_IMAGE_FlashControlAuto,\n    OMX_IMAGE_FlashControlRedEyeReduction,\n    OMX_IMAGE_FlashControlFillin,\n    OMX_IMAGE_FlashControlTorch,\n    OMX_IMAGE_FlashControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_IMAGE_FlashControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_IMAGE_FlashControlMax = 0x7FFFFFFF\n} OMX_IMAGE_FLASHCONTROLTYPE;\n\n\n/**\n * Flash control configuration\n *\n * STRUCT MEMBERS:\n *  nSize         : Size of the structure in bytes\n *  nVersion      : OMX specification version information\n *  nPortIndex    : Port that this structure applies to\n *  eFlashControl : Flash control type\n */\ntypedef struct OMX_IMAGE_PARAM_FLASHCONTROLTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_IMAGE_FLASHCONTROLTYPE eFlashControl;\n} OMX_IMAGE_PARAM_FLASHCONTROLTYPE;\n\n\n/**\n * Focus control type\n */\ntypedef enum OMX_IMAGE_FOCUSCONTROLTYPE {\n    OMX_IMAGE_FocusControlOn = 0,\n    OMX_IMAGE_FocusControlOff,\n    OMX_IMAGE_FocusControlAuto,\n    OMX_IMAGE_FocusControlAutoLock,\n    OMX_IMAGE_FocusControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_IMAGE_FocusControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_IMAGE_FocusControlMax = 0x7FFFFFFF\n} OMX_IMAGE_FOCUSCONTROLTYPE;\n\n\n/**\n * Focus control configuration\n *\n * STRUCT MEMBERS:\n *  nSize           : Size of the structure in bytes\n *  nVersion        : OMX specification version information\n *  nPortIndex      : Port that this structure applies to\n *  eFocusControl   : Focus control\n *  nFocusSteps     : Focus can take on values from 0 mm to infinity.\n *                    Interest is only in number of steps over this range.\n *  nFocusStepIndex : Current focus step index\n */\ntypedef struct OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_IMAGE_FOCUSCONTROLTYPE eFocusControl;\n    OMX_U32 nFocusSteps;\n    OMX_U32 nFocusStepIndex;\n} OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE;\n\n\n/**\n * Q Factor for JPEG compression, which controls the tradeoff between image\n * quality and size.  Q Factor provides a more simple means of controlling\n * JPEG compression quality, without directly programming Quantization\n * tables for chroma and luma\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nQFactor   : JPEG Q factor value in the range of 1-100. A factor of 1\n *               produces the smallest, worst quality images, and a factor\n *               of 100 produces the largest, best quality images.  A\n *               typical default is 75 for small good quality images\n */\ntypedef struct OMX_IMAGE_PARAM_QFACTORTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nQFactor;\n} OMX_IMAGE_PARAM_QFACTORTYPE;\n\n/**\n * Quantization table type\n */\n\ntypedef enum OMX_IMAGE_QUANTIZATIONTABLETYPE {\n    OMX_IMAGE_QuantizationTableLuma = 0,\n    OMX_IMAGE_QuantizationTableChroma,\n    OMX_IMAGE_QuantizationTableChromaCb,\n    OMX_IMAGE_QuantizationTableChromaCr,\n    OMX_IMAGE_QuantizationTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_IMAGE_QuantizationTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_IMAGE_QuantizationTableMax = 0x7FFFFFFF\n} OMX_IMAGE_QUANTIZATIONTABLETYPE;\n\n/**\n * JPEG quantization tables are used to determine DCT compression for\n * YUV data, as an alternative to specifying Q factor, providing exact\n * control of compression\n *\n * STRUCT MEMBERS:\n *  nSize                   : Size of the structure in bytes\n *  nVersion                : OMX specification version information\n *  nPortIndex              : Port that this structure applies to\n *  eQuantizationTable      : Quantization table type\n *  nQuantizationMatrix[64] : JPEG quantization table of coefficients stored\n *                            in increasing columns then by rows of data (i.e.\n *                            row 1, ... row 8). Quantization values are in\n *                            the range 0-255 and stored in linear order\n *                            (i.e. the component will zig-zag the\n *                            quantization table data if required internally)\n */\ntypedef struct OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_IMAGE_QUANTIZATIONTABLETYPE eQuantizationTable;\n    OMX_U8 nQuantizationMatrix[64];\n} OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE;\n\n\n/**\n * Huffman table type, the same Huffman table is applied for chroma and\n * luma component\n */\ntypedef enum OMX_IMAGE_HUFFMANTABLETYPE {\n    OMX_IMAGE_HuffmanTableAC = 0,\n    OMX_IMAGE_HuffmanTableDC,\n    OMX_IMAGE_HuffmanTableACLuma,\n    OMX_IMAGE_HuffmanTableACChroma,\n    OMX_IMAGE_HuffmanTableDCLuma,\n    OMX_IMAGE_HuffmanTableDCChroma,\n    OMX_IMAGE_HuffmanTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_IMAGE_HuffmanTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_IMAGE_HuffmanTableMax = 0x7FFFFFFF\n} OMX_IMAGE_HUFFMANTABLETYPE;\n\n/**\n * JPEG Huffman table\n *\n * STRUCT MEMBERS:\n *  nSize                            : Size of the structure in bytes\n *  nVersion                         : OMX specification version information\n *  nPortIndex                       : Port that this structure applies to\n *  eHuffmanTable                    : Huffman table type\n *  nNumberOfHuffmanCodeOfLength[16] : 0-16, number of Huffman codes of each\n *                                     possible length\n *  nHuffmanTable[256]               : 0-255, the size used for AC and DC\n *                                     HuffmanTable are 16 and 162\n */\ntypedef struct OMX_IMAGE_PARAM_HUFFMANTTABLETYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_IMAGE_HUFFMANTABLETYPE eHuffmanTable;\n    OMX_U8 nNumberOfHuffmanCodeOfLength[16];\n    OMX_U8 nHuffmanTable[256];\n}OMX_IMAGE_PARAM_HUFFMANTTABLETYPE;\n\n/** @} */\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n/* File EOF */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/openmax/OMX_Index.h",
    "content": "/* ------------------------------------------------------------------\n * Copyright (C) 1998-2009 PacketVideo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n * express or implied.\n * See the License for the specific language governing permissions\n * and limitations under the License.\n * -------------------------------------------------------------------\n */\n/*\n * Copyright (c) 2008 The Khronos Group Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject\n * to the following conditions:\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n/** @file OMX_Index.h - OpenMax IL version 1.1.2\n *  The OMX_Index header file contains the definitions for both applications\n *  and components .\n */\n\n\n#ifndef OMX_Index_h\n#define OMX_Index_h\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/* Each OMX header must include all required header files to allow the\n *  header to compile without errors.  The includes below are required\n *  for this header file to compile successfully\n */\n#include <OMX_Types.h>\n\n/** The OMX_INDEXTYPE enumeration is used to select a structure when either\n *  getting or setting parameters and/or configuration data.  Each entry in\n *  this enumeration maps to an OMX specified structure.  When the\n *  OMX_GetParameter, OMX_SetParameter, OMX_GetConfig or OMX_SetConfig methods\n *  are used, the second parameter will always be an entry from this enumeration\n *  and the third entry will be the structure shown in the comments for the entry.\n *  For example, if the application is initializing a cropping function, the\n *  OMX_SetConfig command would have OMX_IndexConfigCommonInputCrop as the second parameter\n *  and would send a pointer to an initialized OMX_RECTTYPE structure as the\n *  third parameter.\n *\n *  The enumeration entries named with the OMX_Config prefix are sent using\n *  the OMX_SetConfig command and the enumeration entries named with the\n *  OMX_PARAM_ prefix are sent using the OMX_SetParameter command.\n */\ntypedef enum OMX_INDEXTYPE {\n\n    OMX_IndexComponentStartUnused = 0x01000000,\n    OMX_IndexParamPriorityMgmt,             /**< reference: OMX_PRIORITYMGMTTYPE */\n    OMX_IndexParamAudioInit,                /**< reference: OMX_PORT_PARAM_TYPE */\n    OMX_IndexParamImageInit,                /**< reference: OMX_PORT_PARAM_TYPE */\n    OMX_IndexParamVideoInit,                /**< reference: OMX_PORT_PARAM_TYPE */\n    OMX_IndexParamOtherInit,                /**< reference: OMX_PORT_PARAM_TYPE */\n    OMX_IndexParamNumAvailableStreams,      /**< reference: OMX_PARAM_U32TYPE */\n    OMX_IndexParamActiveStream,             /**< reference: OMX_PARAM_U32TYPE */\n    OMX_IndexParamSuspensionPolicy,         /**< reference: OMX_PARAM_SUSPENSIONPOLICYTYPE */\n    OMX_IndexParamComponentSuspended,       /**< reference: OMX_PARAM_SUSPENSIONTYPE */\n    OMX_IndexConfigCapturing,               /**< reference: OMX_CONFIG_BOOLEANTYPE */\n    OMX_IndexConfigCaptureMode,             /**< reference: OMX_CONFIG_CAPTUREMODETYPE */\n    OMX_IndexAutoPauseAfterCapture,         /**< reference: OMX_CONFIG_BOOLEANTYPE */\n    OMX_IndexParamContentURI,               /**< reference: OMX_PARAM_CONTENTURITYPE */\n    OMX_IndexParamCustomContentPipe,        /**< reference: OMX_PARAM_CONTENTPIPETYPE */\n    OMX_IndexParamDisableResourceConcealment, /**< reference: OMX_RESOURCECONCEALMENTTYPE */\n    OMX_IndexConfigMetadataItemCount,       /**< reference: OMX_CONFIG_METADATAITEMCOUNTTYPE */\n    OMX_IndexConfigContainerNodeCount,      /**< reference: OMX_CONFIG_CONTAINERNODECOUNTTYPE */\n    OMX_IndexConfigMetadataItem,            /**< reference: OMX_CONFIG_METADATAITEMTYPE */\n    OMX_IndexConfigCounterNodeID,           /**< reference: OMX_CONFIG_CONTAINERNODEIDTYPE */\n    OMX_IndexParamMetadataFilterType,       /**< reference: OMX_PARAM_METADATAFILTERTYPE */\n    OMX_IndexParamMetadataKeyFilter,        /**< reference: OMX_PARAM_METADATAFILTERTYPE */\n    OMX_IndexConfigPriorityMgmt,            /**< reference: OMX_PRIORITYMGMTTYPE */\n    OMX_IndexParamStandardComponentRole,    /**< reference: OMX_PARAM_COMPONENTROLETYPE */\n\n    OMX_IndexPortStartUnused = 0x02000000,\n    OMX_IndexParamPortDefinition,           /**< reference: OMX_PARAM_PORTDEFINITIONTYPE */\n    OMX_IndexParamCompBufferSupplier,       /**< reference: OMX_PARAM_BUFFERSUPPLIERTYPE */\n    OMX_IndexReservedStartUnused = 0x03000000,\n\n    /* Audio parameters and configurations */\n    OMX_IndexAudioStartUnused = 0x04000000,\n    OMX_IndexParamAudioPortFormat,          /**< reference: OMX_AUDIO_PARAM_PORTFORMATTYPE */\n    OMX_IndexParamAudioPcm,                 /**< reference: OMX_AUDIO_PARAM_PCMMODETYPE */\n    OMX_IndexParamAudioAac,                 /**< reference: OMX_AUDIO_PARAM_AACPROFILETYPE */\n    OMX_IndexParamAudioRa,                  /**< reference: OMX_AUDIO_PARAM_RATYPE */\n    OMX_IndexParamAudioMp3,                 /**< reference: OMX_AUDIO_PARAM_MP3TYPE */\n    OMX_IndexParamAudioAdpcm,               /**< reference: OMX_AUDIO_PARAM_ADPCMTYPE */\n    OMX_IndexParamAudioG723,                /**< reference: OMX_AUDIO_PARAM_G723TYPE */\n    OMX_IndexParamAudioG729,                /**< reference: OMX_AUDIO_PARAM_G729TYPE */\n    OMX_IndexParamAudioAmr,                 /**< reference: OMX_AUDIO_PARAM_AMRTYPE */\n    OMX_IndexParamAudioWma,                 /**< reference: OMX_AUDIO_PARAM_WMATYPE */\n    OMX_IndexParamAudioSbc,                 /**< reference: OMX_AUDIO_PARAM_SBCTYPE */\n    OMX_IndexParamAudioMidi,                /**< reference: OMX_AUDIO_PARAM_MIDITYPE */\n    OMX_IndexParamAudioGsm_FR,              /**< reference: OMX_AUDIO_PARAM_GSMFRTYPE */\n    OMX_IndexParamAudioMidiLoadUserSound,   /**< reference: OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE */\n    OMX_IndexParamAudioG726,                /**< reference: OMX_AUDIO_PARAM_G726TYPE */\n    OMX_IndexParamAudioGsm_EFR,             /**< reference: OMX_AUDIO_PARAM_GSMEFRTYPE */\n    OMX_IndexParamAudioGsm_HR,              /**< reference: OMX_AUDIO_PARAM_GSMHRTYPE */\n    OMX_IndexParamAudioPdc_FR,              /**< reference: OMX_AUDIO_PARAM_PDCFRTYPE */\n    OMX_IndexParamAudioPdc_EFR,             /**< reference: OMX_AUDIO_PARAM_PDCEFRTYPE */\n    OMX_IndexParamAudioPdc_HR,              /**< reference: OMX_AUDIO_PARAM_PDCHRTYPE */\n    OMX_IndexParamAudioTdma_FR,             /**< reference: OMX_AUDIO_PARAM_TDMAFRTYPE */\n    OMX_IndexParamAudioTdma_EFR,            /**< reference: OMX_AUDIO_PARAM_TDMAEFRTYPE */\n    OMX_IndexParamAudioQcelp8,              /**< reference: OMX_AUDIO_PARAM_QCELP8TYPE */\n    OMX_IndexParamAudioQcelp13,             /**< reference: OMX_AUDIO_PARAM_QCELP13TYPE */\n    OMX_IndexParamAudioEvrc,                /**< reference: OMX_AUDIO_PARAM_EVRCTYPE */\n    OMX_IndexParamAudioSmv,                 /**< reference: OMX_AUDIO_PARAM_SMVTYPE */\n    OMX_IndexParamAudioVorbis,              /**< reference: OMX_AUDIO_PARAM_VORBISTYPE */\n    OMX_IndexParamAudioFlac,                /**< reference: OMX_AUDIO_PARAM_FLACTYPE */\n\n    OMX_IndexConfigAudioMidiImmediateEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE */\n    OMX_IndexConfigAudioMidiControl,        /**< reference: OMX_AUDIO_CONFIG_MIDICONTROLTYPE */\n    OMX_IndexConfigAudioMidiSoundBankProgram, /**< reference: OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE */\n    OMX_IndexConfigAudioMidiStatus,         /**< reference: OMX_AUDIO_CONFIG_MIDISTATUSTYPE */\n    OMX_IndexConfigAudioMidiMetaEvent,      /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE */\n    OMX_IndexConfigAudioMidiMetaEventData,  /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE */\n    OMX_IndexConfigAudioVolume,             /**< reference: OMX_AUDIO_CONFIG_VOLUMETYPE */\n    OMX_IndexConfigAudioBalance,            /**< reference: OMX_AUDIO_CONFIG_BALANCETYPE */\n    OMX_IndexConfigAudioChannelMute,        /**< reference: OMX_AUDIO_CONFIG_CHANNELMUTETYPE */\n    OMX_IndexConfigAudioMute,               /**< reference: OMX_AUDIO_CONFIG_MUTETYPE */\n    OMX_IndexConfigAudioLoudness,           /**< reference: OMX_AUDIO_CONFIG_LOUDNESSTYPE */\n    OMX_IndexConfigAudioEchoCancelation,    /**< reference: OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE */\n    OMX_IndexConfigAudioNoiseReduction,     /**< reference: OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE */\n    OMX_IndexConfigAudioBass,               /**< reference: OMX_AUDIO_CONFIG_BASSTYPE */\n    OMX_IndexConfigAudioTreble,             /**< reference: OMX_AUDIO_CONFIG_TREBLETYPE */\n    OMX_IndexConfigAudioStereoWidening,     /**< reference: OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE */\n    OMX_IndexConfigAudioChorus,             /**< reference: OMX_AUDIO_CONFIG_CHORUSTYPE */\n    OMX_IndexConfigAudioEqualizer,          /**< reference: OMX_AUDIO_CONFIG_EQUALIZERTYPE */\n    OMX_IndexConfigAudioReverberation,      /**< reference: OMX_AUDIO_CONFIG_REVERBERATIONTYPE */\n    OMX_IndexConfigAudioChannelVolume,      /**< reference: OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE */\n\n    /* Image specific parameters and configurations */\n    OMX_IndexImageStartUnused = 0x05000000,\n    OMX_IndexParamImagePortFormat,          /**< reference: OMX_IMAGE_PARAM_PORTFORMATTYPE */\n    OMX_IndexParamFlashControl,             /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */\n    OMX_IndexConfigFocusControl,            /**< reference: OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE */\n    OMX_IndexParamQFactor,                  /**< reference: OMX_IMAGE_PARAM_QFACTORTYPE */\n    OMX_IndexParamQuantizationTable,        /**< reference: OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE */\n    OMX_IndexParamHuffmanTable,             /**< reference: OMX_IMAGE_PARAM_HUFFMANTTABLETYPE */\n    OMX_IndexConfigFlashControl,            /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */\n\n    /* Video specific parameters and configurations */\n    OMX_IndexVideoStartUnused = 0x06000000,\n    OMX_IndexParamVideoPortFormat,          /**< reference: OMX_VIDEO_PARAM_PORTFORMATTYPE */\n    OMX_IndexParamVideoQuantization,        /**< reference: OMX_VIDEO_PARAM_QUANTIZATIONTYPE */\n    OMX_IndexParamVideoFastUpdate,          /**< reference: OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE */\n    OMX_IndexParamVideoBitrate,             /**< reference: OMX_VIDEO_PARAM_BITRATETYPE */\n    OMX_IndexParamVideoMotionVector,        /**< reference: OMX_VIDEO_PARAM_MOTIONVECTORTYPE */\n    OMX_IndexParamVideoIntraRefresh,        /**< reference: OMX_VIDEO_PARAM_INTRAREFRESHTYPE */\n    OMX_IndexParamVideoErrorCorrection,     /**< reference: OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE */\n    OMX_IndexParamVideoVBSMC,               /**< reference: OMX_VIDEO_PARAM_VBSMCTYPE */\n    OMX_IndexParamVideoMpeg2,               /**< reference: OMX_VIDEO_PARAM_MPEG2TYPE */\n    OMX_IndexParamVideoMpeg4,               /**< reference: OMX_VIDEO_PARAM_MPEG4TYPE */\n    OMX_IndexParamVideoWmv,                 /**< reference: OMX_VIDEO_PARAM_WMVTYPE */\n    OMX_IndexParamVideoRv,                  /**< reference: OMX_VIDEO_PARAM_RVTYPE */\n    OMX_IndexParamVideoAvc,                 /**< reference: OMX_VIDEO_PARAM_AVCTYPE */\n    OMX_IndexParamVideoH263,                /**< reference: OMX_VIDEO_PARAM_H263TYPE */\n    OMX_IndexParamVideoProfileLevelQuerySupported, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */\n    OMX_IndexParamVideoProfileLevelCurrent, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */\n    OMX_IndexConfigVideoBitrate,            /**< reference: OMX_VIDEO_CONFIG_BITRATETYPE */\n    OMX_IndexConfigVideoFramerate,          /**< reference: OMX_CONFIG_FRAMERATETYPE */\n    OMX_IndexConfigVideoIntraVOPRefresh,    /**< reference: OMX_CONFIG_INTRAREFRESHVOPTYPE */\n    OMX_IndexConfigVideoIntraMBRefresh,     /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */\n    OMX_IndexConfigVideoMBErrorReporting,   /**< reference: OMX_CONFIG_MBERRORREPORTINGTYPE */\n    OMX_IndexParamVideoMacroblocksPerFrame, /**< reference: OMX_PARAM_MACROBLOCKSTYPE */\n    OMX_IndexConfigVideoMacroBlockErrorMap, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */\n    OMX_IndexParamVideoSliceFMO,            /**< reference: OMX_VIDEO_PARAM_AVCSLICEFMO */\n    OMX_IndexConfigVideoAVCIntraPeriod,     /**< reference: OMX_VIDEO_CONFIG_AVCINTRAPERIOD */\n    OMX_IndexConfigVideoNalSize,            /**< reference: OMX_VIDEO_CONFIG_NALSIZE */\n\n    /* Image & Video common Configurations */\n    OMX_IndexCommonStartUnused = 0x07000000,\n    OMX_IndexParamCommonDeblocking,         /**< reference: OMX_PARAM_DEBLOCKINGTYPE */\n    OMX_IndexParamCommonSensorMode,         /**< reference: OMX_PARAM_SENSORMODETYPE */\n    OMX_IndexParamCommonInterleave,         /**< reference: OMX_PARAM_INTERLEAVETYPE */\n    OMX_IndexConfigCommonColorFormatConversion, /**< reference: OMX_CONFIG_COLORCONVERSIONTYPE */\n    OMX_IndexConfigCommonScale,             /**< reference: OMX_CONFIG_SCALEFACTORTYPE */\n    OMX_IndexConfigCommonImageFilter,       /**< reference: OMX_CONFIG_IMAGEFILTERTYPE */\n    OMX_IndexConfigCommonColorEnhancement,  /**< reference: OMX_CONFIG_COLORENHANCEMENTTYPE */\n    OMX_IndexConfigCommonColorKey,          /**< reference: OMX_CONFIG_COLORKEYTYPE */\n    OMX_IndexConfigCommonColorBlend,        /**< reference: OMX_CONFIG_COLORBLENDTYPE */\n    OMX_IndexConfigCommonFrameStabilisation,/**< reference: OMX_CONFIG_FRAMESTABTYPE */\n    OMX_IndexConfigCommonRotate,            /**< reference: OMX_CONFIG_ROTATIONTYPE */\n    OMX_IndexConfigCommonMirror,            /**< reference: OMX_CONFIG_MIRRORTYPE */\n    OMX_IndexConfigCommonOutputPosition,    /**< reference: OMX_CONFIG_POINTTYPE */\n    OMX_IndexConfigCommonInputCrop,         /**< reference: OMX_CONFIG_RECTTYPE */\n    OMX_IndexConfigCommonOutputCrop,        /**< reference: OMX_CONFIG_RECTTYPE */\n    OMX_IndexConfigCommonDigitalZoom,       /**< reference: OMX_CONFIG_SCALEFACTORTYPE */\n    OMX_IndexConfigCommonOpticalZoom,       /**< reference: OMX_CONFIG_SCALEFACTORTYPE*/\n    OMX_IndexConfigCommonWhiteBalance,      /**< reference: OMX_CONFIG_WHITEBALCONTROLTYPE */\n    OMX_IndexConfigCommonExposure,          /**< reference: OMX_CONFIG_EXPOSURECONTROLTYPE */\n    OMX_IndexConfigCommonContrast,          /**< reference: OMX_CONFIG_CONTRASTTYPE */\n    OMX_IndexConfigCommonBrightness,        /**< reference: OMX_CONFIG_BRIGHTNESSTYPE */\n    OMX_IndexConfigCommonBacklight,         /**< reference: OMX_CONFIG_BACKLIGHTTYPE */\n    OMX_IndexConfigCommonGamma,             /**< reference: OMX_CONFIG_GAMMATYPE */\n    OMX_IndexConfigCommonSaturation,        /**< reference: OMX_CONFIG_SATURATIONTYPE */\n    OMX_IndexConfigCommonLightness,         /**< reference: OMX_CONFIG_LIGHTNESSTYPE */\n    OMX_IndexConfigCommonExclusionRect,     /**< reference: OMX_CONFIG_RECTTYPE */\n    OMX_IndexConfigCommonDithering,         /**< reference: OMX_CONFIG_DITHERTYPE */\n    OMX_IndexConfigCommonPlaneBlend,        /**< reference: OMX_CONFIG_PLANEBLENDTYPE */\n    OMX_IndexConfigCommonExposureValue,     /**< reference: OMX_CONFIG_EXPOSUREVALUETYPE */\n    OMX_IndexConfigCommonOutputSize,        /**< reference: OMX_FRAMESIZETYPE */\n    OMX_IndexParamCommonExtraQuantData,     /**< reference: OMX_OTHER_EXTRADATATYPE */\n    OMX_IndexConfigCommonFocusRegion,       /**< reference: OMX_CONFIG_FOCUSREGIONTYPE */\n    OMX_IndexConfigCommonFocusStatus,       /**< reference: OMX_PARAM_FOCUSSTATUSTYPE */\n    OMX_IndexConfigCommonTransitionEffect,  /**< reference: OMX_CONFIG_TRANSITIONEFFECTTYPE */\n\n    /* Reserved Configuration range */\n    OMX_IndexOtherStartUnused = 0x08000000,\n    OMX_IndexParamOtherPortFormat,          /**< reference: OMX_OTHER_PARAM_PORTFORMATTYPE */\n    OMX_IndexConfigOtherPower,              /**< reference: OMX_OTHER_CONFIG_POWERTYPE */\n    OMX_IndexConfigOtherStats,              /**< reference: OMX_OTHER_CONFIG_STATSTYPE */\n\n\n    /* Reserved Time range */\n    OMX_IndexTimeStartUnused = 0x09000000,\n    OMX_IndexConfigTimeScale,               /**< reference: OMX_TIME_CONFIG_SCALETYPE */\n    OMX_IndexConfigTimeClockState,          /**< reference: OMX_TIME_CONFIG_CLOCKSTATETYPE */\n    OMX_IndexConfigTimeActiveRefClock,      /**< reference: OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE */\n    OMX_IndexConfigTimeCurrentMediaTime,    /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */\n    OMX_IndexConfigTimeCurrentWallTime,     /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */\n    OMX_IndexConfigTimeCurrentAudioReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */\n    OMX_IndexConfigTimeCurrentVideoReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */\n    OMX_IndexConfigTimeMediaTimeRequest,    /**< reference: OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE (write only) */\n    OMX_IndexConfigTimeClientStartTime,     /**<reference:  OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */\n    OMX_IndexConfigTimePosition,            /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE */\n    OMX_IndexConfigTimeSeekMode,            /**< reference: OMX_TIME_CONFIG_SEEKMODETYPE */\n\n\n    OMX_IndexKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    /* Vendor specific area */\n    OMX_IndexVendorStartUnused = 0x7F000000,\n    /* Vendor specific structures should be in the range of 0x7F000000\n       to 0x7FFFFFFE.  This range is not broken out by vendor, so\n       private indexes are not guaranteed unique and therefore should\n       only be sent to the appropriate component. */\n\n    OMX_IndexMax = 0x7FFFFFFF\n\n} OMX_INDEXTYPE;\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n/* File EOF */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/openmax/OMX_IndexExt.h",
    "content": "/*\n * Copyright (c) 2010 The Khronos Group Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject\n * to the following conditions:\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n/** @file OMX_IndexExt.h - OpenMax IL version 1.1.2\n * The OMX_IndexExt header file contains extensions to the definitions\n * for both applications and components .\n */\n\n#ifndef OMX_IndexExt_h\n#define OMX_IndexExt_h\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/* Each OMX header shall include all required header files to allow the\n * header to compile without errors.  The includes below are required\n * for this header file to compile successfully\n */\n#include <OMX_Index.h>\n\n\n/** Khronos standard extension indices.\n\nThis enum lists the current Khronos extension indices to OpenMAX IL.\n*/\ntypedef enum OMX_INDEXEXTTYPE {\n\n    /* Component parameters and configurations */\n    OMX_IndexExtComponentStartUnused = OMX_IndexKhronosExtensions + 0x00100000,\n    OMX_IndexConfigCallbackRequest,                 /**< reference: OMX_CONFIG_CALLBACKREQUESTTYPE */\n    OMX_IndexConfigCommitMode,                      /**< reference: OMX_CONFIG_COMMITMODETYPE */\n    OMX_IndexConfigCommit,                          /**< reference: OMX_CONFIG_COMMITTYPE */\n\n    /* Port parameters and configurations */\n    OMX_IndexExtPortStartUnused = OMX_IndexKhronosExtensions + 0x00200000,\n\n    /* Audio parameters and configurations */\n    OMX_IndexExtAudioStartUnused = OMX_IndexKhronosExtensions + 0x00400000,\n    OMX_IndexParamAudioAndroidAc3,                  /**< reference: OMX_AUDIO_PARAM_ANDROID_AC3TYPE */\n    OMX_IndexParamAudioAndroidOpus,                 /**< reference: OMX_AUDIO_PARAM_ANDROID_OPUSTYPE */\n    OMX_IndexParamAudioAndroidAacPresentation,      /**< reference: OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE */\n    OMX_IndexParamAudioAndroidEac3,                 /**< reference: OMX_AUDIO_PARAM_ANDROID_EAC3TYPE */\n    OMX_IndexParamAudioProfileQuerySupported,       /**< reference: OMX_AUDIO_PARAM_ANDROID_PROFILETYPE */\n\n    /* Image parameters and configurations */\n    OMX_IndexExtImageStartUnused = OMX_IndexKhronosExtensions + 0x00500000,\n\n    /* Video parameters and configurations */\n    OMX_IndexExtVideoStartUnused = OMX_IndexKhronosExtensions + 0x00600000,\n    OMX_IndexParamNalStreamFormatSupported,         /**< reference: OMX_NALSTREAMFORMATTYPE */\n    OMX_IndexParamNalStreamFormat,                  /**< reference: OMX_NALSTREAMFORMATTYPE */\n    OMX_IndexParamNalStreamFormatSelect,            /**< reference: OMX_NALSTREAMFORMATTYPE */\n    OMX_IndexParamVideoVp8,                         /**< reference: OMX_VIDEO_PARAM_VP8TYPE */\n    OMX_IndexConfigVideoVp8ReferenceFrame,          /**< reference: OMX_VIDEO_VP8REFERENCEFRAMETYPE */\n    OMX_IndexConfigVideoVp8ReferenceFrameType,      /**< reference: OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE */\n    OMX_IndexParamVideoAndroidVp8Encoder,           /**< reference: OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE */\n    OMX_IndexParamVideoHevc,                        /**< reference: OMX_VIDEO_PARAM_HEVCTYPE */\n    OMX_IndexParamSliceSegments,                    /**< reference: OMX_VIDEO_SLICESEGMENTSTYPE */\n    OMX_IndexConfigAndroidIntraRefresh,             /**< reference: OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE */\n\n    /* Image & Video common configurations */\n    OMX_IndexExtCommonStartUnused = OMX_IndexKhronosExtensions + 0x00700000,\n\n    /* Other configurations */\n    OMX_IndexExtOtherStartUnused = OMX_IndexKhronosExtensions + 0x00800000,\n    OMX_IndexConfigAutoFramerateConversion,         /**< reference: OMX_CONFIG_BOOLEANTYPE */\n    OMX_IndexConfigPriority,                        /**< reference: OMX_PARAM_U32TYPE */\n    OMX_IndexConfigOperatingRate,                   /**< reference: OMX_PARAM_U32TYPE in Q16 format for video and in Hz for audio */\n    OMX_IndexParamConsumerUsageBits,                /**< reference: OMX_PARAM_U32TYPE */\n\n    /* Time configurations */\n    OMX_IndexExtTimeStartUnused = OMX_IndexKhronosExtensions + 0x00900000,\n\n    OMX_IndexExtMax = 0x7FFFFFFF\n} OMX_INDEXEXTTYPE;\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* OMX_IndexExt_h */\n/* File EOF */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/openmax/OMX_Other.h",
    "content": "/* ------------------------------------------------------------------\n * Copyright (C) 1998-2009 PacketVideo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n * express or implied.\n * See the License for the specific language governing permissions\n * and limitations under the License.\n * -------------------------------------------------------------------\n */\n/*\n * Copyright (c) 2008 The Khronos Group Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject\n * to the following conditions:\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n/** @file OMX_Other.h - OpenMax IL version 1.1.2\n *  The structures needed by Other components to exchange\n *  parameters and configuration data with the components.\n */\n\n#ifndef OMX_Other_h\n#define OMX_Other_h\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n\n/* Each OMX header must include all required header files to allow the\n *  header to compile without errors.  The includes below are required\n *  for this header file to compile successfully\n */\n\n#include <OMX_Core.h>\n\n\n/**\n * Enumeration of possible data types which match to multiple domains or no\n * domain at all.  For types which are vendor specific, a value above\n * OMX_OTHER_VENDORTSTART should be used.\n */\ntypedef enum OMX_OTHER_FORMATTYPE {\n    OMX_OTHER_FormatTime = 0, /**< Transmission of various timestamps, elapsed time,\n                                   time deltas, etc */\n    OMX_OTHER_FormatPower,    /**< Perhaps used for enabling/disabling power\n                                   management, setting clocks? */\n    OMX_OTHER_FormatStats,    /**< Could be things such as frame rate, frames\n                                   dropped, etc */\n    OMX_OTHER_FormatBinary,   /**< Arbitrary binary data */\n    OMX_OTHER_FormatVendorReserved = 1000, /**< Starting value for vendor specific\n                                                formats */\n\n    OMX_OTHER_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_OTHER_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_OTHER_FormatMax = 0x7FFFFFFF\n} OMX_OTHER_FORMATTYPE;\n\n/**\n * Enumeration of seek modes.\n */\ntypedef enum OMX_TIME_SEEKMODETYPE {\n    OMX_TIME_SeekModeFast = 0, /**< Prefer seeking to an approximation\n                                * of the requested seek position over\n                                * the actual seek position if it\n                                * results in a faster seek. */\n    OMX_TIME_SeekModeAccurate, /**< Prefer seeking to the actual seek\n                                * position over an approximation\n                                * of the requested seek position even\n                                * if it results in a slower seek. */\n    OMX_TIME_SeekModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_TIME_SeekModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_TIME_SeekModeMax = 0x7FFFFFFF\n} OMX_TIME_SEEKMODETYPE;\n\n/* Structure representing the seekmode of the component */\ntypedef struct OMX_TIME_CONFIG_SEEKMODETYPE {\n    OMX_U32 nSize;                  /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */\n    OMX_TIME_SEEKMODETYPE eType;    /**< The seek mode */\n} OMX_TIME_CONFIG_SEEKMODETYPE;\n\n/** Structure representing a time stamp used with the following configs\n * on the Clock Component (CC):\n *\n * OMX_IndexConfigTimeCurrentWallTime: query of the CC's current wall\n *     time\n * OMX_IndexConfigTimeCurrentMediaTime: query of the CC's current media\n *     time\n * OMX_IndexConfigTimeCurrentAudioReference and\n * OMX_IndexConfigTimeCurrentVideoReference: audio/video reference\n *     clock sending SC its reference time\n * OMX_IndexConfigTimeClientStartTime: a Clock Component client sends\n *     this structure to the Clock Component via a SetConfig on its\n *     client port when it receives a buffer with\n *     OMX_BUFFERFLAG_STARTTIME set. It must use the timestamp\n *     specified by that buffer for nStartTimestamp.\n *\n * It's also used with the following config on components in general:\n *\n * OMX_IndexConfigTimePosition: IL client querying component position\n * (GetConfig) or commanding a component to seek to the given location\n * (SetConfig)\n */\ntypedef struct OMX_TIME_CONFIG_TIMESTAMPTYPE {\n    OMX_U32 nSize;               /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;    /**< OMX specification version\n                                  *   information */\n    OMX_U32 nPortIndex;          /**< port that this structure applies to */\n    OMX_TICKS nTimestamp;        /**< timestamp .*/\n} OMX_TIME_CONFIG_TIMESTAMPTYPE;\n\n/** Enumeration of possible reference clocks to the media time. */\ntypedef enum OMX_TIME_UPDATETYPE {\n      OMX_TIME_UpdateRequestFulfillment,    /**< Update is the fulfillment of a media time request. */\n      OMX_TIME_UpdateScaleChanged,          /**< Update was generated because the scale chagned. */\n      OMX_TIME_UpdateClockStateChanged,     /**< Update was generated because the clock state changed. */\n      OMX_TIME_UpdateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n      OMX_TIME_UpdateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n      OMX_TIME_UpdateMax = 0x7FFFFFFF\n} OMX_TIME_UPDATETYPE;\n\n/** Enumeration of possible reference clocks to the media time. */\ntypedef enum OMX_TIME_REFCLOCKTYPE {\n      OMX_TIME_RefClockNone,    /**< Use no references. */\n      OMX_TIME_RefClockAudio,   /**< Use references sent through OMX_IndexConfigTimeCurrentAudioReference */\n      OMX_TIME_RefClockVideo,   /**< Use references sent through OMX_IndexConfigTimeCurrentVideoReference */\n      OMX_TIME_RefClockKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n      OMX_TIME_RefClockVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n      OMX_TIME_RefClockMax = 0x7FFFFFFF\n} OMX_TIME_REFCLOCKTYPE;\n\n/** Enumeration of clock states. */\ntypedef enum OMX_TIME_CLOCKSTATE {\n      OMX_TIME_ClockStateRunning,             /**< Clock running. */\n      OMX_TIME_ClockStateWaitingForStartTime, /**< Clock waiting until the\n                                               *   prescribed clients emit their\n                                               *   start time. */\n      OMX_TIME_ClockStateStopped,             /**< Clock stopped. */\n      OMX_TIME_ClockStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n      OMX_TIME_ClockStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n      OMX_TIME_ClockStateMax = 0x7FFFFFFF\n} OMX_TIME_CLOCKSTATE;\n\n/** Structure representing a media time request to the clock component.\n *\n *  A client component sends this structure to the Clock Component via a SetConfig\n *  on its client port to specify a media timestamp the Clock Component\n *  should emit.  The Clock Component should fulfill the request by sending a\n *  OMX_TIME_MEDIATIMETYPE when its media clock matches the requested\n *  timestamp.\n *\n *  The client may require a media time request be fulfilled slightly\n *  earlier than the media time specified. In this case the client specifies\n *  an offset which is equal to the difference between wall time corresponding\n *  to the requested media time and the wall time when it will be\n *  fulfilled.\n *\n *  A client component may uses these requests and the OMX_TIME_MEDIATIMETYPE to\n *  time events according to timestamps. If a client must perform an operation O at\n *  a time T (e.g. deliver a video frame at its corresponding timestamp), it makes a\n *  media time request at T (perhaps specifying an offset to ensure the request fulfillment\n *  is a little early). When the clock component passes the resulting OMX_TIME_MEDIATIMETYPE\n *  structure back to the client component, the client may perform operation O (perhaps having\n *  to wait a slight amount more time itself as specified by the return values).\n */\n\ntypedef struct OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE {\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */\n    OMX_U32 nPortIndex;         /**< port that this structure applies to */\n    OMX_PTR pClientPrivate;     /**< Client private data to disabiguate this media time\n                                 *   from others (e.g. the number of the frame to deliver).\n                                 *   Duplicated in the media time structure that fulfills\n                                 *   this request. A value of zero is reserved for time scale\n                                 *   updates. */\n    OMX_TICKS nMediaTimestamp;  /**< Media timestamp requested.*/\n    OMX_TICKS nOffset;          /**< Amount of wall clock time by which this\n                                 *   request should be fulfilled early */\n} OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE;\n\n/**< Structure sent from the clock component client either when fulfilling\n *   a media time request or when the time scale has changed.\n *\n *   In the former case the Clock Component fills this structure and times its emission\n *   to a client component (via the client port) according to the corresponding media\n *   time request sent by the client. The Clock Component should time the emission to occur\n *   when the requested timestamp matches the Clock Component's media time but also the\n *   prescribed offset early.\n *\n *   Upon scale changes the clock component clears the nClientPrivate data, sends the current\n *   media time and sets the nScale to the new scale via the client port. It emits a\n *   OMX_TIME_MEDIATIMETYPE to all clients independent of any requests. This allows clients to\n *   alter processing to accomodate scaling. For instance a video component might skip inter-frames\n *   in the case of extreme fastforward. Likewise an audio component might add or remove samples\n *   from an audio frame to scale audio data.\n *\n *   It is expected that some clock components may not be able to fulfill requests\n *   at exactly the prescribed time. This is acceptable so long as the request is\n *   fulfilled at least as early as described and not later. This structure provides\n *   fields the client may use to wait for the remaining time.\n *\n *   The client may use either the nOffset or nWallTimeAtMedia fields to determine the\n *   wall time until the nMediaTimestamp actually occurs. In the latter case the\n *   client can get a more accurate value for offset by getting the current wall\n *   from the cloc component and subtracting it from nWallTimeAtMedia.\n */\n\ntypedef struct OMX_TIME_MEDIATIMETYPE {\n    OMX_U32 nSize;                  /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */\n    OMX_U32 nClientPrivate;         /**< Client private data to disabiguate this media time\n                                     *   from others. Copied from the media time request.\n                                     *   A value of zero is reserved for time scale updates. */\n    OMX_TIME_UPDATETYPE eUpdateType; /**< Reason for the update */\n    OMX_TICKS nMediaTimestamp;      /**< Media time requested. If no media time was\n                                     *   requested then this is the current media time. */\n    OMX_TICKS nOffset;              /**< Amount of wall clock time by which this\n                                     *   request was actually fulfilled early */\n\n    OMX_TICKS nWallTimeAtMediaTime; /**< Wall time corresponding to nMediaTimeStamp.\n                                     *   A client may compare this value to current\n                                     *   media time obtained from the Clock Component to determine\n                                     *   the wall time until the media timestamp is really\n                                     *   current. */\n    OMX_S32 xScale;                 /**< Current media time scale in Q16 format. */\n    OMX_TIME_CLOCKSTATE eState;     /* Seeking Change. Added 7/12.*/\n                                    /**< State of the media time. */\n} OMX_TIME_MEDIATIMETYPE;\n\n/** Structure representing the current media time scale factor. Applicable only to clock\n *  component, other components see scale changes via OMX_TIME_MEDIATIMETYPE buffers sent via\n *  the clock component client ports. Upon recieving this config the clock component changes\n *  the rate by which the media time increases or decreases effectively implementing trick modes.\n */\ntypedef struct OMX_TIME_CONFIG_SCALETYPE {\n    OMX_U32 nSize;                  /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */\n    OMX_S32 xScale;                 /**< This is a value in Q16 format which is used for\n                                     * scaling the media time */\n} OMX_TIME_CONFIG_SCALETYPE;\n\n/** Bits used to identify a clock port. Used in OMX_TIME_CONFIG_CLOCKSTATETYPE's nWaitMask field */\n#define OMX_CLOCKPORT0 0x00000001\n#define OMX_CLOCKPORT1 0x00000002\n#define OMX_CLOCKPORT2 0x00000004\n#define OMX_CLOCKPORT3 0x00000008\n#define OMX_CLOCKPORT4 0x00000010\n#define OMX_CLOCKPORT5 0x00000020\n#define OMX_CLOCKPORT6 0x00000040\n#define OMX_CLOCKPORT7 0x00000080\n\n/** Structure representing the current mode of the media clock.\n *  IL Client uses this config to change or query the mode of the\n *  media clock of the clock component. Applicable only to clock\n *  component.\n *\n *  On a SetConfig if eState is OMX_TIME_ClockStateRunning media time\n *  starts immediately at the prescribed start time. If\n *  OMX_TIME_ClockStateWaitingForStartTime the Clock Component ignores\n *  the given nStartTime and waits for all clients specified in the\n *  nWaitMask to send starttimes (via\n *  OMX_IndexConfigTimeClientStartTime). The Clock Component then starts\n *  the media clock using the earliest start time supplied. */\ntypedef struct OMX_TIME_CONFIG_CLOCKSTATETYPE {\n    OMX_U32 nSize;              /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;   /**< OMX specification version\n                                 *   information */\n    OMX_TIME_CLOCKSTATE eState; /**< State of the media time. */\n    OMX_TICKS nStartTime;       /**< Start time of the media time. */\n    OMX_TICKS nOffset;          /**< Time to offset the media time by\n                                 * (e.g. preroll). Media time will be\n                                 * reported to be nOffset ticks earlier.\n                                 */\n    OMX_U32 nWaitMask;          /**< Mask of OMX_CLOCKPORT values. */\n} OMX_TIME_CONFIG_CLOCKSTATETYPE;\n\n/** Structure representing the reference clock currently being used to\n *  compute media time. IL client uses this config to change or query the\n *  clock component's active reference clock */\ntypedef struct OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE {\n    OMX_U32 nSize;                  /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */\n    OMX_TIME_REFCLOCKTYPE eClock;   /**< Reference clock used to compute media time */\n} OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE;\n\n/** Descriptor for setting specifics of power type.\n *  Note: this structure is listed for backwards compatibility. */\ntypedef struct OMX_OTHER_CONFIG_POWERTYPE {\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_BOOL bEnablePM;       /**< Flag to enable Power Management */\n} OMX_OTHER_CONFIG_POWERTYPE;\n\n\n/** Descriptor for setting specifics of stats type.\n *  Note: this structure is listed for backwards compatibility. */\ntypedef struct OMX_OTHER_CONFIG_STATSTYPE {\n    OMX_U32 nSize;            /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    /* what goes here */\n} OMX_OTHER_CONFIG_STATSTYPE;\n\n\n/**\n * The PortDefinition structure is used to define all of the parameters\n * necessary for the compliant component to setup an input or an output other\n * path.\n */\ntypedef struct OMX_OTHER_PORTDEFINITIONTYPE {\n    OMX_OTHER_FORMATTYPE eFormat;  /**< Type of data expected for this channel */\n} OMX_OTHER_PORTDEFINITIONTYPE;\n\n/**  Port format parameter.  This structure is used to enumerate\n  *  the various data input/output format supported by the port.\n  */\ntypedef struct OMX_OTHER_PARAM_PORTFORMATTYPE {\n    OMX_U32 nSize; /**< size of the structure in bytes */\n    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\n    OMX_U32 nPortIndex; /**< Indicates which port to set */\n    OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */\n    OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */\n} OMX_OTHER_PARAM_PORTFORMATTYPE;\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n/* File EOF */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/openmax/OMX_Types.h",
    "content": "/* ------------------------------------------------------------------\n * Copyright (C) 1998-2009 PacketVideo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n * express or implied.\n * See the License for the specific language governing permissions\n * and limitations under the License.\n * -------------------------------------------------------------------\n */\n/*\n * Copyright (c) 2008 The Khronos Group Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject\n * to the following conditions:\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n/** OMX_Types.h - OpenMax IL version 1.1.2\n *  The OMX_Types header file contains the primitive type definitions used by\n *  the core, the application and the component.  This file may need to be\n *  modified to be used on systems that do not have \"char\" set to 8 bits,\n *  \"short\" set to 16 bits and \"long\" set to 32 bits.\n */\n\n#ifndef OMX_Types_h\n#define OMX_Types_h\n\n#include <stdint.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/** The OMX_API and OMX_APIENTRY are platform specific definitions used\n *  to declare OMX function prototypes.  They are modified to meet the\n *  requirements for a particular platform */\n#ifdef __SYMBIAN32__\n#   ifdef __OMX_EXPORTS\n#       define OMX_API __declspec(dllexport)\n#   else\n#       ifdef _WIN32\n#           define OMX_API __declspec(dllexport)\n#       else\n#           define OMX_API __declspec(dllimport)\n#       endif\n#   endif\n#else\n#   ifdef _WIN32\n#      ifdef __OMX_EXPORTS\n#          define OMX_API __declspec(dllexport)\n#      else\n//#          define OMX_API __declspec(dllimport)\n#define OMX_API\n#      endif\n#   else\n#      ifdef __OMX_EXPORTS\n#          define OMX_API\n#      else\n#          define OMX_API extern\n#      endif\n#   endif\n#endif\n\n#ifndef OMX_APIENTRY\n#define OMX_APIENTRY\n#endif\n\n/** OMX_IN is used to identify inputs to an OMX function.  This designation\n    will also be used in the case of a pointer that points to a parameter\n    that is used as an output. */\n#ifndef OMX_IN\n#define OMX_IN\n#endif\n\n/** OMX_OUT is used to identify outputs from an OMX function.  This\n    designation will also be used in the case of a pointer that points\n    to a parameter that is used as an input. */\n#ifndef OMX_OUT\n#define OMX_OUT\n#endif\n\n\n/** OMX_INOUT is used to identify parameters that may be either inputs or\n    outputs from an OMX function at the same time.  This designation will\n    also be used in the case of a pointer that  points to a parameter that\n    is used both as an input and an output. */\n#ifndef OMX_INOUT\n#define OMX_INOUT\n#endif\n\n/** OMX_ALL is used to as a wildcard to select all entities of the same type\n *  when specifying the index, or referring to a object by an index.  (i.e.\n *  use OMX_ALL to indicate all N channels). When used as a port index\n *  for a config or parameter this OMX_ALL denotes that the config or\n *  parameter applies to the entire component not just one port. */\n#define OMX_ALL 0xFFFFFFFF\n\n/** In the following we define groups that help building doxygen documentation */\n\n/** @defgroup core OpenMAX IL core\n * Functions and structure related to the OMX IL core\n */\n\n /** @defgroup comp OpenMAX IL component\n * Functions and structure related to the OMX IL component\n */\n\n/** @defgroup rpm Resource and Policy Management\n * Structures for resource and policy management of components\n */\n\n/** @defgroup buf Buffer Management\n * Buffer handling functions and structures\n */\n\n/** @defgroup tun Tunneling\n * @ingroup core comp\n * Structures and functions to manage tunnels among component ports\n */\n\n/** @defgroup cp Content Pipes\n *  @ingroup core\n */\n\n /** @defgroup metadata Metadata handling\n  *\n  */\n\n/** OMX_U8 is an 8 bit unsigned quantity that is byte aligned */\ntypedef unsigned char OMX_U8;\n\n/** OMX_S8 is an 8 bit signed quantity that is byte aligned */\ntypedef signed char OMX_S8;\n\n/** OMX_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */\ntypedef unsigned short OMX_U16;\n\n/** OMX_S16 is a 16 bit signed quantity that is 16 bit word aligned */\ntypedef signed short OMX_S16;\n\n/** OMX_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */\ntypedef uint32_t OMX_U32;\n\n/** OMX_S32 is a 32 bit signed quantity that is 32 bit word aligned */\ntypedef int32_t OMX_S32;\n\n\n/* Users with compilers that cannot accept the \"long long\" designation should\n   define the OMX_SKIP64BIT macro.  It should be noted that this may cause\n   some components to fail to compile if the component was written to require\n   64 bit integral types.  However, these components would NOT compile anyway\n   since the compiler does not support the way the component was written.\n*/\n#ifndef OMX_SKIP64BIT\n#ifdef __SYMBIAN32__\n/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */\ntypedef unsigned long long OMX_U64;\n\n/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */\ntypedef signed long long OMX_S64;\n\n#elif defined(WIN32)\n\n/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */\ntypedef unsigned __int64  OMX_U64;\n\n/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */\ntypedef signed   __int64  OMX_S64;\n\n#else /* WIN32 */\n\n/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */\ntypedef unsigned long long OMX_U64;\n\n/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */\ntypedef signed long long OMX_S64;\n\n#endif /* WIN32 */\n#endif\n\n\n/** The OMX_BOOL type is intended to be used to represent a true or a false\n    value when passing parameters to and from the OMX core and components.  The\n    OMX_BOOL is a 32 bit quantity and is aligned on a 32 bit word boundary.\n */\ntypedef enum OMX_BOOL {\n    OMX_FALSE = 0,\n    OMX_TRUE = !OMX_FALSE,\n    OMX_BOOL_MAX = 0x7FFFFFFF\n} OMX_BOOL;\n\n/*\n * Temporary Android 64 bit modification\n *\n * #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS\n * overrides all OMX pointer types to be uint32_t.\n *\n * After this change, OMX codecs will work in 32 bit only, so 64 bit processes\n * must communicate to a remote 32 bit process for OMX to work.\n */\n\n#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS\n\ntypedef uint32_t OMX_PTR;\ntypedef OMX_PTR OMX_STRING;\ntypedef OMX_PTR OMX_BYTE;\n\n#else /* OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS */\n\n/** The OMX_PTR type is intended to be used to pass pointers between the OMX\n    applications and the OMX Core and components.  This is a 32 bit pointer and\n    is aligned on a 32 bit boundary.\n */\ntypedef void* OMX_PTR;\n\n/** The OMX_STRING type is intended to be used to pass \"C\" type strings between\n    the application and the core and component.  The OMX_STRING type is a 32\n    bit pointer to a zero terminated string.  The  pointer is word aligned and\n    the string is byte aligned.\n */\ntypedef char* OMX_STRING;\n\n/** The OMX_BYTE type is intended to be used to pass arrays of bytes such as\n    buffers between the application and the component and core.  The OMX_BYTE\n    type is a 32 bit pointer to a zero terminated string.  The  pointer is word\n    aligned and the string is byte aligned.\n */\ntypedef unsigned char* OMX_BYTE;\n\n#endif /* OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS */\n\n/** OMX_UUIDTYPE is a very long unique identifier to uniquely identify\n    at runtime.  This identifier should be generated by a component in a way\n    that guarantees that every instance of the identifier running on the system\n    is unique. */\ntypedef unsigned char OMX_UUIDTYPE[128];\n\n/** The OMX_DIRTYPE enumeration is used to indicate if a port is an input or\n    an output port.  This enumeration is common across all component types.\n */\ntypedef enum OMX_DIRTYPE\n{\n    OMX_DirInput,              /**< Port is an input port */\n    OMX_DirOutput,             /**< Port is an output port */\n    OMX_DirMax = 0x7FFFFFFF\n} OMX_DIRTYPE;\n\n/** The OMX_ENDIANTYPE enumeration is used to indicate the bit ordering\n    for numerical data (i.e. big endian, or little endian).\n */\ntypedef enum OMX_ENDIANTYPE\n{\n    OMX_EndianBig, /**< big endian */\n    OMX_EndianLittle, /**< little endian */\n    OMX_EndianMax = 0x7FFFFFFF\n} OMX_ENDIANTYPE;\n\n\n/** The OMX_NUMERICALDATATYPE enumeration is used to indicate if data\n    is signed, unsigned or floating point (Android extension).\n\n    Android floating point support policy:\n    If component does not support floating point raw audio, it can reset\n    configuration to signed 16-bit integer (support for which is required.)\n    nBitsPerSample will be set to 32 for float data.\n */\ntypedef enum OMX_NUMERICALDATATYPE\n{\n    OMX_NumericalDataSigned, /**< signed data */\n    OMX_NumericalDataUnsigned, /**< unsigned data */\n    OMX_NumericalDataFloat = 0x7F000001, /**< floating point data */\n    OMX_NumercialDataMax = 0x7FFFFFFF\n} OMX_NUMERICALDATATYPE;\n\n\n/** Unsigned bounded value type */\ntypedef struct OMX_BU32 {\n    OMX_U32 nValue; /**< actual value */\n    OMX_U32 nMin;   /**< minimum for value (i.e. nValue >= nMin) */\n    OMX_U32 nMax;   /**< maximum for value (i.e. nValue <= nMax) */\n} OMX_BU32;\n\n\n/** Signed bounded value type */\ntypedef struct OMX_BS32 {\n    OMX_S32 nValue; /**< actual value */\n    OMX_S32 nMin;   /**< minimum for value (i.e. nValue >= nMin) */\n    OMX_S32 nMax;   /**< maximum for value (i.e. nValue <= nMax) */\n} OMX_BS32;\n\n\n/** Structure representing some time or duration in microseconds. This structure\n  *  must be interpreted as a signed 64 bit value. The quantity is signed to accommodate\n  *  negative deltas and preroll scenarios. The quantity is represented in microseconds\n  *  to accomodate high resolution timestamps (e.g. DVD presentation timestamps based\n  *  on a 90kHz clock) and to allow more accurate and synchronized delivery (e.g.\n  *  individual audio samples delivered at 192 kHz). The quantity is 64 bit to\n  *  accommodate a large dynamic range (signed 32 bit values would allow only for plus\n  *  or minus 35 minutes).\n  *\n  *  Implementations with limited precision may convert the signed 64 bit value to\n  *  a signed 32 bit value internally but risk loss of precision.\n  */\n#ifndef OMX_SKIP64BIT\ntypedef OMX_S64 OMX_TICKS;\n#else\ntypedef struct OMX_TICKS\n{\n    OMX_U32 nLowPart;    /** low bits of the signed 64 bit tick value */\n    OMX_U32 nHighPart;   /** high bits of the signed 64 bit tick value */\n} OMX_TICKS;\n#endif\n#define OMX_TICKS_PER_SECOND 1000000\n\n/** Define the public interface for the OMX Handle.  The core will not use\n    this value internally, but the application should only use this value.\n */\ntypedef OMX_PTR OMX_HANDLETYPE;\n\ntypedef struct OMX_MARKTYPE\n{\n    OMX_HANDLETYPE hMarkTargetComponent;   /**< The component that will\n                                                generate a mark event upon\n                                                processing the mark. */\n    OMX_PTR pMarkData;   /**< Application specific data associated with\n                              the mark sent on a mark event to disambiguate\n                              this mark from others. */\n} OMX_MARKTYPE;\n\n\n/** OMX_NATIVE_DEVICETYPE is used to map a OMX video port to the\n *  platform & operating specific object used to reference the display\n *  or can be used by a audio port for native audio rendering */\ntypedef OMX_PTR OMX_NATIVE_DEVICETYPE;\n\n/** OMX_NATIVE_WINDOWTYPE is used to map a OMX video port to the\n *  platform & operating specific object used to reference the window */\ntypedef OMX_PTR OMX_NATIVE_WINDOWTYPE;\n\n/** The OMX_VERSIONTYPE union is used to specify the version for\n    a structure or component.  For a component, the version is entirely\n    specified by the component vendor.  Components doing the same function\n    from different vendors may or may not have the same version.  For\n    structures, the version shall be set by the entity that allocates the\n    structure.  For structures specified in the OMX 1.1 specification, the\n    value of the version shall be set to 1.1.0.0 in all cases.  Access to the\n    OMX_VERSIONTYPE can be by a single 32 bit access (e.g. by nVersion) or\n    by accessing one of the structure elements to, for example, check only\n    the Major revision.\n */\ntypedef union OMX_VERSIONTYPE\n{\n    struct\n    {\n        OMX_U8 nVersionMajor;   /**< Major version accessor element */\n        OMX_U8 nVersionMinor;   /**< Minor version accessor element */\n        OMX_U8 nRevision;       /**< Revision version accessor element */\n        OMX_U8 nStep;           /**< Step version accessor element */\n    } s;\n    OMX_U32 nVersion;           /**< 32 bit value to make accessing the\n                                    version easily done in a single word\n                                    size copy/compare operation */\n} OMX_VERSIONTYPE;\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n/* File EOF */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/openmax/OMX_Video.h",
    "content": "/* ------------------------------------------------------------------\n * Copyright (C) 1998-2009 PacketVideo\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n * express or implied.\n * See the License for the specific language governing permissions\n * and limitations under the License.\n * -------------------------------------------------------------------\n */\n/**\n * Copyright (c) 2008 The Khronos Group Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject\n * to the following conditions:\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n/**\n *  @file OMX_Video.h - OpenMax IL version 1.1.2\n *  The structures is needed by Video components to exchange parameters\n *  and configuration data with OMX components.\n */\n#ifndef OMX_Video_h\n#define OMX_Video_h\n\n/** @defgroup video OpenMAX IL Video Domain\n * @ingroup iv\n * Structures for OpenMAX IL Video domain\n * @{\n */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n\n/**\n * Each OMX header must include all required header files to allow the\n * header to compile without errors.  The includes below are required\n * for this header file to compile successfully\n */\n\n#include <OMX_IVCommon.h>\n\n\n/**\n * Enumeration used to define the possible video compression codings.\n * NOTE:  This essentially refers to file extensions. If the coding is\n *        being used to specify the ENCODE type, then additional work\n *        must be done to configure the exact flavor of the compression\n *        to be used.  For decode cases where the user application can\n *        not differentiate between MPEG-4 and H.264 bit streams, it is\n *        up to the codec to handle this.\n */\ntypedef enum OMX_VIDEO_CODINGTYPE {\n    OMX_VIDEO_CodingUnused,     /**< Value when coding is N/A */\n    OMX_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */\n    OMX_VIDEO_CodingMPEG2,      /**< AKA: H.262 */\n    OMX_VIDEO_CodingH263,       /**< H.263 */\n    OMX_VIDEO_CodingMPEG4,      /**< MPEG-4 */\n    OMX_VIDEO_CodingWMV,        /**< all versions of Windows Media Video */\n    OMX_VIDEO_CodingRV,         /**< all versions of Real Video */\n    OMX_VIDEO_CodingAVC,        /**< H.264/AVC */\n    OMX_VIDEO_CodingMJPEG,      /**< Motion JPEG */\n    OMX_VIDEO_CodingVP8,        /**< Google VP8, formerly known as On2 VP8 */\n    OMX_VIDEO_CodingVP9,        /**< Google VP9 */\n    OMX_VIDEO_CodingHEVC,       /**< ITU H.265/HEVC */\n    OMX_VIDEO_CodingDolbyVision,/**< Dolby Vision */\n    OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_CodingMax = 0x7FFFFFFF\n} OMX_VIDEO_CODINGTYPE;\n\n\n/**\n * Data structure used to define a video path.  The number of Video paths for\n * input and output will vary by type of the Video component.\n *\n *    Input (aka Source) : zero Inputs, one Output,\n *    Splitter           : one Input, 2 or more Outputs,\n *    Processing Element : one Input, one output,\n *    Mixer              : 2 or more inputs, one output,\n *    Output (aka Sink)  : one Input, zero outputs.\n *\n * The PortDefinition structure is used to define all of the parameters\n * necessary for the compliant component to setup an input or an output video\n * path.  If additional vendor specific data is required, it should be\n * transmitted to the component using the CustomCommand function.  Compliant\n * components will prepopulate this structure with optimal values during the\n * GetDefaultInitParams command.\n *\n * STRUCT MEMBERS:\n *  cMIMEType             : MIME type of data for the port\n *  pNativeRender         : Platform specific reference for a display if a\n *                          sync, otherwise this field is 0\n *  nFrameWidth           : Width of frame to be used on channel if\n *                          uncompressed format is used.  Use 0 for unknown,\n *                          don't care or variable\n *  nFrameHeight          : Height of frame to be used on channel if\n *                          uncompressed format is used. Use 0 for unknown,\n *                          don't care or variable\n *  nStride               : Number of bytes per span of an image\n *                          (i.e. indicates the number of bytes to get\n *                          from span N to span N+1, where negative stride\n *                          indicates the image is bottom up\n *  nSliceHeight          : Height used when encoding in slices\n *  nBitrate              : Bit rate of frame to be used on channel if\n *                          compressed format is used. Use 0 for unknown,\n *                          don't care or variable\n *  xFramerate            : Frame rate to be used on channel if uncompressed\n *                          format is used. Use 0 for unknown, don't care or\n *                          variable.  Units are Q16 frames per second.\n *  bFlagErrorConcealment : Turns on error concealment if it is supported by\n *                          the OMX component\n *  eCompressionFormat    : Compression format used in this instance of the\n *                          component. When OMX_VIDEO_CodingUnused is\n *                          specified, eColorFormat is used\n *  eColorFormat : Decompressed format used by this component\n *  pNativeWindow : Platform specific reference for a window object if a\n *                          display sink , otherwise this field is 0x0.\n */\ntypedef struct OMX_VIDEO_PORTDEFINITIONTYPE {\n    OMX_STRING cMIMEType;\n    OMX_NATIVE_DEVICETYPE pNativeRender;\n    OMX_U32 nFrameWidth;\n    OMX_U32 nFrameHeight;\n    OMX_S32 nStride;\n    OMX_U32 nSliceHeight;\n    OMX_U32 nBitrate;\n    OMX_U32 xFramerate;\n    OMX_BOOL bFlagErrorConcealment;\n    OMX_VIDEO_CODINGTYPE eCompressionFormat;\n    OMX_COLOR_FORMATTYPE eColorFormat;\n    OMX_NATIVE_WINDOWTYPE pNativeWindow;\n} OMX_VIDEO_PORTDEFINITIONTYPE;\n\n/**\n * Port format parameter.  This structure is used to enumerate the various\n * data input/output format supported by the port.\n *\n * STRUCT MEMBERS:\n *  nSize              : Size of the structure in bytes\n *  nVersion           : OMX specification version information\n *  nPortIndex         : Indicates which port to set\n *  nIndex             : Indicates the enumeration index for the format from\n *                       0x0 to N-1\n *  eCompressionFormat : Compression format used in this instance of the\n *                       component. When OMX_VIDEO_CodingUnused is specified,\n *                       eColorFormat is used\n *  eColorFormat       : Decompressed format used by this component\n *  xFrameRate         : Indicates the video frame rate in Q16 format\n */\ntypedef struct OMX_VIDEO_PARAM_PORTFORMATTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nIndex;\n    OMX_VIDEO_CODINGTYPE eCompressionFormat;\n    OMX_COLOR_FORMATTYPE eColorFormat;\n    OMX_U32 xFramerate;\n} OMX_VIDEO_PARAM_PORTFORMATTYPE;\n\n\n/**\n * This is a structure for configuring video compression quantization\n * parameter values.  Codecs may support different QP values for different\n * frame types.\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version info\n *  nPortIndex : Port that this structure applies to\n *  nQpI       : QP value to use for index frames\n *  nQpP       : QP value to use for P frames\n *  nQpB       : QP values to use for bidirectional frames\n */\ntypedef struct OMX_VIDEO_PARAM_QUANTIZATIONTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nQpI;\n    OMX_U32 nQpP;\n    OMX_U32 nQpB;\n} OMX_VIDEO_PARAM_QUANTIZATIONTYPE;\n\n\n/**\n * Structure for configuration of video fast update parameters.\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version info\n *  nPortIndex : Port that this structure applies to\n *  bEnableVFU : Enable/Disable video fast update\n *  nFirstGOB  : Specifies the number of the first macroblock row\n *  nFirstMB   : specifies the first MB relative to the specified first GOB\n *  nNumMBs    : Specifies the number of MBs to be refreshed from nFirstGOB\n *               and nFirstMB\n */\ntypedef struct OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL bEnableVFU;\n    OMX_U32 nFirstGOB;\n    OMX_U32 nFirstMB;\n    OMX_U32 nNumMBs;\n} OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE;\n\n\n/**\n * Enumeration of possible bitrate control types\n */\ntypedef enum OMX_VIDEO_CONTROLRATETYPE {\n    OMX_Video_ControlRateDisable,\n    OMX_Video_ControlRateVariable,\n    OMX_Video_ControlRateConstant,\n    OMX_Video_ControlRateVariableSkipFrames,\n    OMX_Video_ControlRateConstantSkipFrames,\n    OMX_Video_ControlRateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_Video_ControlRateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_Video_ControlRateMax = 0x7FFFFFFF\n} OMX_VIDEO_CONTROLRATETYPE;\n\n\n/**\n * Structure for configuring bitrate mode of a codec.\n *\n * STRUCT MEMBERS:\n *  nSize          : Size of the struct in bytes\n *  nVersion       : OMX spec version info\n *  nPortIndex     : Port that this struct applies to\n *  eControlRate   : Control rate type enum\n *  nTargetBitrate : Target bitrate to encode with\n */\ntypedef struct OMX_VIDEO_PARAM_BITRATETYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_VIDEO_CONTROLRATETYPE eControlRate;\n    OMX_U32 nTargetBitrate;\n} OMX_VIDEO_PARAM_BITRATETYPE;\n\n\n/**\n * Enumeration of possible motion vector (MV) types\n */\ntypedef enum OMX_VIDEO_MOTIONVECTORTYPE {\n    OMX_Video_MotionVectorPixel,\n    OMX_Video_MotionVectorHalfPel,\n    OMX_Video_MotionVectorQuarterPel,\n    OMX_Video_MotionVectorEighthPel,\n    OMX_Video_MotionVectorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_Video_MotionVectorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_Video_MotionVectorMax = 0x7FFFFFFF\n} OMX_VIDEO_MOTIONVECTORTYPE;\n\n\n/**\n * Structure for configuring the number of motion vectors used as well\n * as their accuracy.\n *\n * STRUCT MEMBERS:\n *  nSize            : Size of the struct in bytes\n *  nVersion         : OMX spec version info\n *  nPortIndex       : port that this structure applies to\n *  eAccuracy        : Enumerated MV accuracy\n *  bUnrestrictedMVs : Allow unrestricted MVs\n *  bFourMV          : Allow use of 4 MVs\n *  sXSearchRange    : Search range in horizontal direction for MVs\n *  sYSearchRange    : Search range in vertical direction for MVs\n */\ntypedef struct OMX_VIDEO_PARAM_MOTIONVECTORTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_VIDEO_MOTIONVECTORTYPE eAccuracy;\n    OMX_BOOL bUnrestrictedMVs;\n    OMX_BOOL bFourMV;\n    OMX_S32 sXSearchRange;\n    OMX_S32 sYSearchRange;\n} OMX_VIDEO_PARAM_MOTIONVECTORTYPE;\n\n\n/**\n * Enumeration of possible methods to use for Intra Refresh\n */\ntypedef enum OMX_VIDEO_INTRAREFRESHTYPE {\n    OMX_VIDEO_IntraRefreshCyclic,\n    OMX_VIDEO_IntraRefreshAdaptive,\n    OMX_VIDEO_IntraRefreshBoth,\n    OMX_VIDEO_IntraRefreshKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_IntraRefreshVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_IntraRefreshMax = 0x7FFFFFFF\n} OMX_VIDEO_INTRAREFRESHTYPE;\n\n\n/**\n * Structure for configuring intra refresh mode\n *\n * STRUCT MEMBERS:\n *  nSize        : Size of the structure in bytes\n *  nVersion     : OMX specification version information\n *  nPortIndex   : Port that this structure applies to\n *  eRefreshMode : Cyclic, Adaptive, or Both\n *  nAirMBs      : Number of intra macroblocks to refresh in a frame when\n *                 AIR is enabled\n *  nAirRef      : Number of times a motion marked macroblock has to be\n *                 intra coded\n *  nCirMBs      : Number of consecutive macroblocks to be coded as \"intra\"\n *                 when CIR is enabled\n */\ntypedef struct OMX_VIDEO_PARAM_INTRAREFRESHTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_VIDEO_INTRAREFRESHTYPE eRefreshMode;\n    OMX_U32 nAirMBs;\n    OMX_U32 nAirRef;\n    OMX_U32 nCirMBs;\n} OMX_VIDEO_PARAM_INTRAREFRESHTYPE;\n\n\n/**\n * Structure for enabling various error correction methods for video\n * compression.\n *\n * STRUCT MEMBERS:\n *  nSize                   : Size of the structure in bytes\n *  nVersion                : OMX specification version information\n *  nPortIndex              : Port that this structure applies to\n *  bEnableHEC              : Enable/disable header extension codes (HEC)\n *  bEnableResync           : Enable/disable resynchronization markers\n *  nResynchMarkerSpacing   : Resynch markers interval (in bits) to be\n *                            applied in the stream\n *  bEnableDataPartitioning : Enable/disable data partitioning\n *  bEnableRVLC             : Enable/disable reversible variable length\n *                            coding\n */\ntypedef struct OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL bEnableHEC;\n    OMX_BOOL bEnableResync;\n    OMX_U32  nResynchMarkerSpacing;\n    OMX_BOOL bEnableDataPartitioning;\n    OMX_BOOL bEnableRVLC;\n} OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE;\n\n\n/**\n * Configuration of variable block-size motion compensation (VBSMC)\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  b16x16     : Enable inter block search 16x16\n *  b16x8      : Enable inter block search 16x8\n *  b8x16      : Enable inter block search 8x16\n *  b8x8       : Enable inter block search 8x8\n *  b8x4       : Enable inter block search 8x4\n *  b4x8       : Enable inter block search 4x8\n *  b4x4       : Enable inter block search 4x4\n */\ntypedef struct OMX_VIDEO_PARAM_VBSMCTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL b16x16;\n    OMX_BOOL b16x8;\n    OMX_BOOL b8x16;\n    OMX_BOOL b8x8;\n    OMX_BOOL b8x4;\n    OMX_BOOL b4x8;\n    OMX_BOOL b4x4;\n} OMX_VIDEO_PARAM_VBSMCTYPE;\n\n\n/**\n * H.263 profile types, each profile indicates support for various\n * performance bounds and different annexes.\n *\n * ENUMS:\n *  Baseline           : Baseline Profile: H.263 (V1), no optional modes\n *  H320 Coding        : H.320 Coding Efficiency Backward Compatibility\n *                       Profile: H.263+ (V2), includes annexes I, J, L.4\n *                       and T\n *  BackwardCompatible : Backward Compatibility Profile: H.263 (V1),\n *                       includes annex F\n *  ISWV2              : Interactive Streaming Wireless Profile: H.263+\n *                       (V2), includes annexes I, J, K and T\n *  ISWV3              : Interactive Streaming Wireless Profile: H.263++\n *                       (V3), includes profile 3 and annexes V and W.6.3.8\n *  HighCompression    : Conversational High Compression Profile: H.263++\n *                       (V3), includes profiles 1 & 2 and annexes D and U\n *  Internet           : Conversational Internet Profile: H.263++ (V3),\n *                       includes profile 5 and annex K\n *  Interlace          : Conversational Interlace Profile: H.263++ (V3),\n *                       includes profile 5 and annex W.6.3.11\n *  HighLatency        : High Latency Profile: H.263++ (V3), includes\n *                       profile 6 and annexes O.1 and P.5\n */\ntypedef enum OMX_VIDEO_H263PROFILETYPE {\n    OMX_VIDEO_H263ProfileBaseline            = 0x01,\n    OMX_VIDEO_H263ProfileH320Coding          = 0x02,\n    OMX_VIDEO_H263ProfileBackwardCompatible  = 0x04,\n    OMX_VIDEO_H263ProfileISWV2               = 0x08,\n    OMX_VIDEO_H263ProfileISWV3               = 0x10,\n    OMX_VIDEO_H263ProfileHighCompression     = 0x20,\n    OMX_VIDEO_H263ProfileInternet            = 0x40,\n    OMX_VIDEO_H263ProfileInterlace           = 0x80,\n    OMX_VIDEO_H263ProfileHighLatency         = 0x100,\n    OMX_VIDEO_H263ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_H263ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_H263ProfileMax                 = 0x7FFFFFFF\n} OMX_VIDEO_H263PROFILETYPE;\n\n\n/**\n * H.263 level types, each level indicates support for various frame sizes,\n * bit rates, decoder frame rates.\n */\ntypedef enum OMX_VIDEO_H263LEVELTYPE {\n    OMX_VIDEO_H263Level10  = 0x01,\n    OMX_VIDEO_H263Level20  = 0x02,\n    OMX_VIDEO_H263Level30  = 0x04,\n    OMX_VIDEO_H263Level40  = 0x08,\n    OMX_VIDEO_H263Level45  = 0x10,\n    OMX_VIDEO_H263Level50  = 0x20,\n    OMX_VIDEO_H263Level60  = 0x40,\n    OMX_VIDEO_H263Level70  = 0x80,\n    OMX_VIDEO_H263LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_H263LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_H263LevelMax = 0x7FFFFFFF\n} OMX_VIDEO_H263LEVELTYPE;\n\n\n/**\n * Specifies the picture type. These values should be OR'd to signal all\n * pictures types which are allowed.\n *\n * ENUMS:\n *  Generic Picture Types:          I, P and B\n *  H.263 Specific Picture Types:   SI and SP\n *  H.264 Specific Picture Types:   EI and EP\n *  MPEG-4 Specific Picture Types:  S\n */\ntypedef enum OMX_VIDEO_PICTURETYPE {\n    OMX_VIDEO_PictureTypeI   = 0x01,\n    OMX_VIDEO_PictureTypeP   = 0x02,\n    OMX_VIDEO_PictureTypeB   = 0x04,\n    OMX_VIDEO_PictureTypeSI  = 0x08,\n    OMX_VIDEO_PictureTypeSP  = 0x10,\n    OMX_VIDEO_PictureTypeEI  = 0x11,\n    OMX_VIDEO_PictureTypeEP  = 0x12,\n    OMX_VIDEO_PictureTypeS   = 0x14,\n    OMX_VIDEO_PictureTypeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_PictureTypeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_PictureTypeMax = 0x7FFFFFFF\n} OMX_VIDEO_PICTURETYPE;\n\n\n/**\n * H.263 Params\n *\n * STRUCT MEMBERS:\n *  nSize                    : Size of the structure in bytes\n *  nVersion                 : OMX specification version information\n *  nPortIndex               : Port that this structure applies to\n *  nPFrames                 : Number of P frames between each I frame\n *  nBFrames                 : Number of B frames between each I frame\n *  eProfile                 : H.263 profile(s) to use\n *  eLevel                   : H.263 level(s) to use\n *  bPLUSPTYPEAllowed        : Indicating that it is allowed to use PLUSPTYPE\n *                             (specified in the 1998 version of H.263) to\n *                             indicate custom picture sizes or clock\n *                             frequencies\n *  nAllowedPictureTypes     : Specifies the picture types allowed in the\n *                             bitstream\n *  bForceRoundingTypeToZero : value of the RTYPE bit (bit 6 of MPPTYPE) is\n *                             not constrained. It is recommended to change\n *                             the value of the RTYPE bit for each reference\n *                             picture in error-free communication\n *  nPictureHeaderRepetition : Specifies the frequency of picture header\n *                             repetition\n *  nGOBHeaderInterval       : Specifies the interval of non-empty GOB\n *                             headers in units of GOBs\n */\ntypedef struct OMX_VIDEO_PARAM_H263TYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nPFrames;\n    OMX_U32 nBFrames;\n    OMX_VIDEO_H263PROFILETYPE eProfile;\n    OMX_VIDEO_H263LEVELTYPE eLevel;\n    OMX_BOOL bPLUSPTYPEAllowed;\n    OMX_U32 nAllowedPictureTypes;\n    OMX_BOOL bForceRoundingTypeToZero;\n    OMX_U32 nPictureHeaderRepetition;\n    OMX_U32 nGOBHeaderInterval;\n} OMX_VIDEO_PARAM_H263TYPE;\n\n\n/**\n * MPEG-2 profile types, each profile indicates support for various\n * performance bounds and different annexes.\n */\ntypedef enum OMX_VIDEO_MPEG2PROFILETYPE {\n    OMX_VIDEO_MPEG2ProfileSimple = 0,  /**< Simple Profile */\n    OMX_VIDEO_MPEG2ProfileMain,        /**< Main Profile */\n    OMX_VIDEO_MPEG2Profile422,         /**< 4:2:2 Profile */\n    OMX_VIDEO_MPEG2ProfileSNR,         /**< SNR Profile */\n    OMX_VIDEO_MPEG2ProfileSpatial,     /**< Spatial Profile */\n    OMX_VIDEO_MPEG2ProfileHigh,        /**< High Profile */\n    OMX_VIDEO_MPEG2ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_MPEG2ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_MPEG2ProfileMax = 0x7FFFFFFF\n} OMX_VIDEO_MPEG2PROFILETYPE;\n\n\n/**\n * MPEG-2 level types, each level indicates support for various frame\n * sizes, bit rates, decoder frame rates.  No need\n */\ntypedef enum OMX_VIDEO_MPEG2LEVELTYPE {\n    OMX_VIDEO_MPEG2LevelLL = 0,  /**< Low Level */\n    OMX_VIDEO_MPEG2LevelML,      /**< Main Level */\n    OMX_VIDEO_MPEG2LevelH14,     /**< High 1440 */\n    OMX_VIDEO_MPEG2LevelHL,      /**< High Level */\n    OMX_VIDEO_MPEG2LevelHP,      /**< HighP Level */\n    OMX_VIDEO_MPEG2LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_MPEG2LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_MPEG2LevelMax = 0x7FFFFFFF\n} OMX_VIDEO_MPEG2LEVELTYPE;\n\n\n/**\n * MPEG-2 params\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nPFrames   : Number of P frames between each I frame\n *  nBFrames   : Number of B frames between each I frame\n *  eProfile   : MPEG-2 profile(s) to use\n *  eLevel     : MPEG-2 levels(s) to use\n */\ntypedef struct OMX_VIDEO_PARAM_MPEG2TYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nPFrames;\n    OMX_U32 nBFrames;\n    OMX_VIDEO_MPEG2PROFILETYPE eProfile;\n    OMX_VIDEO_MPEG2LEVELTYPE eLevel;\n} OMX_VIDEO_PARAM_MPEG2TYPE;\n\n\n/**\n * MPEG-4 profile types, each profile indicates support for various\n * performance bounds and different annexes.\n *\n * ENUMS:\n *  - Simple Profile, Levels 1-3\n *  - Simple Scalable Profile, Levels 1-2\n *  - Core Profile, Levels 1-2\n *  - Main Profile, Levels 2-4\n *  - N-bit Profile, Level 2\n *  - Scalable Texture Profile, Level 1\n *  - Simple Face Animation Profile, Levels 1-2\n *  - Simple Face and Body Animation (FBA) Profile, Levels 1-2\n *  - Basic Animated Texture Profile, Levels 1-2\n *  - Hybrid Profile, Levels 1-2\n *  - Advanced Real Time Simple Profiles, Levels 1-4\n *  - Core Scalable Profile, Levels 1-3\n *  - Advanced Coding Efficiency Profile, Levels 1-4\n *  - Advanced Core Profile, Levels 1-2\n *  - Advanced Scalable Texture, Levels 2-3\n */\ntypedef enum OMX_VIDEO_MPEG4PROFILETYPE {\n    OMX_VIDEO_MPEG4ProfileSimple           = 0x01,\n    OMX_VIDEO_MPEG4ProfileSimpleScalable   = 0x02,\n    OMX_VIDEO_MPEG4ProfileCore             = 0x04,\n    OMX_VIDEO_MPEG4ProfileMain             = 0x08,\n    OMX_VIDEO_MPEG4ProfileNbit             = 0x10,\n    OMX_VIDEO_MPEG4ProfileScalableTexture  = 0x20,\n    OMX_VIDEO_MPEG4ProfileSimpleFace       = 0x40,\n    OMX_VIDEO_MPEG4ProfileSimpleFBA        = 0x80,\n    OMX_VIDEO_MPEG4ProfileBasicAnimated    = 0x100,\n    OMX_VIDEO_MPEG4ProfileHybrid           = 0x200,\n    OMX_VIDEO_MPEG4ProfileAdvancedRealTime = 0x400,\n    OMX_VIDEO_MPEG4ProfileCoreScalable     = 0x800,\n    OMX_VIDEO_MPEG4ProfileAdvancedCoding   = 0x1000,\n    OMX_VIDEO_MPEG4ProfileAdvancedCore     = 0x2000,\n    OMX_VIDEO_MPEG4ProfileAdvancedScalable = 0x4000,\n    OMX_VIDEO_MPEG4ProfileAdvancedSimple   = 0x8000,\n    OMX_VIDEO_MPEG4ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_MPEG4ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_MPEG4ProfileMax              = 0x7FFFFFFF\n} OMX_VIDEO_MPEG4PROFILETYPE;\n\n\n/**\n * MPEG-4 level types, each level indicates support for various frame\n * sizes, bit rates, decoder frame rates.  No need\n */\ntypedef enum OMX_VIDEO_MPEG4LEVELTYPE {\n    OMX_VIDEO_MPEG4Level0  = 0x01,   /**< Level 0 */\n    OMX_VIDEO_MPEG4Level0b = 0x02,   /**< Level 0b */\n    OMX_VIDEO_MPEG4Level1  = 0x04,   /**< Level 1 */\n    OMX_VIDEO_MPEG4Level2  = 0x08,   /**< Level 2 */\n    OMX_VIDEO_MPEG4Level3  = 0x10,   /**< Level 3 */\n    /* normally levels are powers of 2s, but 3b was missed and levels must be properly ordered */\n    OMX_VIDEO_MPEG4Level3b = 0x18,   /**< Level 3a */\n    OMX_VIDEO_MPEG4Level4  = 0x20,   /**< Level 4 */\n    OMX_VIDEO_MPEG4Level4a = 0x40,   /**< Level 4a */\n    OMX_VIDEO_MPEG4Level5  = 0x80,   /**< Level 5 */\n    OMX_VIDEO_MPEG4Level6  = 0x100,  /**< Level 6 */\n    OMX_VIDEO_MPEG4LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_MPEG4LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_MPEG4LevelMax = 0x7FFFFFFF\n} OMX_VIDEO_MPEG4LEVELTYPE;\n\n\n/**\n * MPEG-4 configuration.  This structure handles configuration options\n * which are specific to MPEG4 algorithms\n *\n * STRUCT MEMBERS:\n *  nSize                : Size of the structure in bytes\n *  nVersion             : OMX specification version information\n *  nPortIndex           : Port that this structure applies to\n *  nSliceHeaderSpacing  : Number of macroblocks between slice header (H263+\n *                         Annex K). Put zero if not used\n *  bSVH                 : Enable Short Video Header mode\n *  bGov                 : Flag to enable GOV\n *  nPFrames             : Number of P frames between each I frame (also called\n *                         GOV period)\n *  nBFrames             : Number of B frames between each I frame\n *  nIDCVLCThreshold     : Value of intra DC VLC threshold\n *  bACPred              : Flag to use ac prediction\n *  nMaxPacketSize       : Maximum size of packet in bytes.\n *  nTimeIncRes          : Used to pass VOP time increment resolution for MPEG4.\n *                         Interpreted as described in MPEG4 standard.\n *  eProfile             : MPEG-4 profile(s) to use.\n *  eLevel               : MPEG-4 level(s) to use.\n *  nAllowedPictureTypes : Specifies the picture types allowed in the bitstream\n *  nHeaderExtension     : Specifies the number of consecutive video packet\n *                         headers within a VOP\n *  bReversibleVLC       : Specifies whether reversible variable length coding\n *                         is in use\n */\ntypedef struct OMX_VIDEO_PARAM_MPEG4TYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nSliceHeaderSpacing;\n    OMX_BOOL bSVH;\n    OMX_BOOL bGov;\n    OMX_U32 nPFrames;\n    OMX_U32 nBFrames;\n    OMX_U32 nIDCVLCThreshold;\n    OMX_BOOL bACPred;\n    OMX_U32 nMaxPacketSize;\n    OMX_U32 nTimeIncRes;\n    OMX_VIDEO_MPEG4PROFILETYPE eProfile;\n    OMX_VIDEO_MPEG4LEVELTYPE eLevel;\n    OMX_U32 nAllowedPictureTypes;\n    OMX_U32 nHeaderExtension;\n    OMX_BOOL bReversibleVLC;\n} OMX_VIDEO_PARAM_MPEG4TYPE;\n\n\n/**\n * WMV Versions\n */\ntypedef enum OMX_VIDEO_WMVFORMATTYPE {\n    OMX_VIDEO_WMVFormatUnused = 0x01,   /**< Format unused or unknown */\n    OMX_VIDEO_WMVFormat7      = 0x02,   /**< Windows Media Video format 7 */\n    OMX_VIDEO_WMVFormat8      = 0x04,   /**< Windows Media Video format 8 */\n    OMX_VIDEO_WMVFormat9      = 0x08,   /**< Windows Media Video format 9 */\n    OMX_VIDEO_WMFFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_WMFFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_WMVFormatMax    = 0x7FFFFFFF\n} OMX_VIDEO_WMVFORMATTYPE;\n\n\n/**\n * WMV Params\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  eFormat    : Version of WMV stream / data\n */\ntypedef struct OMX_VIDEO_PARAM_WMVTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_VIDEO_WMVFORMATTYPE eFormat;\n} OMX_VIDEO_PARAM_WMVTYPE;\n\n\n/**\n * Real Video Version\n */\ntypedef enum OMX_VIDEO_RVFORMATTYPE {\n    OMX_VIDEO_RVFormatUnused = 0, /**< Format unused or unknown */\n    OMX_VIDEO_RVFormat8,          /**< Real Video format 8 */\n    OMX_VIDEO_RVFormat9,          /**< Real Video format 9 */\n    OMX_VIDEO_RVFormatG2,         /**< Real Video Format G2 */\n    OMX_VIDEO_RVFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_RVFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_RVFormatMax = 0x7FFFFFFF\n} OMX_VIDEO_RVFORMATTYPE;\n\n\n/**\n * Real Video Params\n *\n * STUCT MEMBERS:\n *  nSize              : Size of the structure in bytes\n *  nVersion           : OMX specification version information\n *  nPortIndex         : Port that this structure applies to\n *  eFormat            : Version of RV stream / data\n *  nBitsPerPixel      : Bits per pixel coded in the frame\n *  nPaddedWidth       : Padded width in pixel of a video frame\n *  nPaddedHeight      : Padded Height in pixels of a video frame\n *  nFrameRate         : Rate of video in frames per second\n *  nBitstreamFlags    : Flags which internal information about the bitstream\n *  nBitstreamVersion  : Bitstream version\n *  nMaxEncodeFrameSize: Max encoded frame size\n *  bEnablePostFilter  : Turn on/off post filter\n *  bEnableTemporalInterpolation : Turn on/off temporal interpolation\n *  bEnableLatencyMode : When enabled, the decoder does not display a decoded\n *                       frame until it has detected that no enhancement layer\n *                       frames or dependent B frames will be coming. This\n *                       detection usually occurs when a subsequent non-B\n *                       frame is encountered\n */\ntypedef struct OMX_VIDEO_PARAM_RVTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_VIDEO_RVFORMATTYPE eFormat;\n    OMX_U16 nBitsPerPixel;\n    OMX_U16 nPaddedWidth;\n    OMX_U16 nPaddedHeight;\n    OMX_U32 nFrameRate;\n    OMX_U32 nBitstreamFlags;\n    OMX_U32 nBitstreamVersion;\n    OMX_U32 nMaxEncodeFrameSize;\n    OMX_BOOL bEnablePostFilter;\n    OMX_BOOL bEnableTemporalInterpolation;\n    OMX_BOOL bEnableLatencyMode;\n} OMX_VIDEO_PARAM_RVTYPE;\n\n\n/**\n * AVC profile types, each profile indicates support for various\n * performance bounds and different annexes.\n */\ntypedef enum OMX_VIDEO_AVCPROFILETYPE {\n    OMX_VIDEO_AVCProfileBaseline = 0x01,   /**< Baseline profile */\n    OMX_VIDEO_AVCProfileMain     = 0x02,   /**< Main profile */\n    OMX_VIDEO_AVCProfileExtended = 0x04,   /**< Extended profile */\n    OMX_VIDEO_AVCProfileHigh     = 0x08,   /**< High profile */\n    OMX_VIDEO_AVCProfileHigh10   = 0x10,   /**< High 10 profile */\n    OMX_VIDEO_AVCProfileHigh422  = 0x20,   /**< High 4:2:2 profile */\n    OMX_VIDEO_AVCProfileHigh444  = 0x40,   /**< High 4:4:4 profile */\n    OMX_VIDEO_AVCProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_AVCProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_AVCProfileMax      = 0x7FFFFFFF\n} OMX_VIDEO_AVCPROFILETYPE;\n\n\n/**\n * AVC level types, each level indicates support for various frame sizes,\n * bit rates, decoder frame rates.  No need\n */\ntypedef enum OMX_VIDEO_AVCLEVELTYPE {\n    OMX_VIDEO_AVCLevel1   = 0x01,     /**< Level 1 */\n    OMX_VIDEO_AVCLevel1b  = 0x02,     /**< Level 1b */\n    OMX_VIDEO_AVCLevel11  = 0x04,     /**< Level 1.1 */\n    OMX_VIDEO_AVCLevel12  = 0x08,     /**< Level 1.2 */\n    OMX_VIDEO_AVCLevel13  = 0x10,     /**< Level 1.3 */\n    OMX_VIDEO_AVCLevel2   = 0x20,     /**< Level 2 */\n    OMX_VIDEO_AVCLevel21  = 0x40,     /**< Level 2.1 */\n    OMX_VIDEO_AVCLevel22  = 0x80,     /**< Level 2.2 */\n    OMX_VIDEO_AVCLevel3   = 0x100,    /**< Level 3 */\n    OMX_VIDEO_AVCLevel31  = 0x200,    /**< Level 3.1 */\n    OMX_VIDEO_AVCLevel32  = 0x400,    /**< Level 3.2 */\n    OMX_VIDEO_AVCLevel4   = 0x800,    /**< Level 4 */\n    OMX_VIDEO_AVCLevel41  = 0x1000,   /**< Level 4.1 */\n    OMX_VIDEO_AVCLevel42  = 0x2000,   /**< Level 4.2 */\n    OMX_VIDEO_AVCLevel5   = 0x4000,   /**< Level 5 */\n    OMX_VIDEO_AVCLevel51  = 0x8000,   /**< Level 5.1 */\n    OMX_VIDEO_AVCLevel52  = 0x10000,  /**< Level 5.2 */\n    OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_AVCLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF\n} OMX_VIDEO_AVCLEVELTYPE;\n\n\n/**\n * AVC loop filter modes\n *\n * OMX_VIDEO_AVCLoopFilterEnable               : Enable\n * OMX_VIDEO_AVCLoopFilterDisable              : Disable\n * OMX_VIDEO_AVCLoopFilterDisableSliceBoundary : Disabled on slice boundaries\n */\ntypedef enum OMX_VIDEO_AVCLOOPFILTERTYPE {\n    OMX_VIDEO_AVCLoopFilterEnable = 0,\n    OMX_VIDEO_AVCLoopFilterDisable,\n    OMX_VIDEO_AVCLoopFilterDisableSliceBoundary,\n    OMX_VIDEO_AVCLoopFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_AVCLoopFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_AVCLoopFilterMax = 0x7FFFFFFF\n} OMX_VIDEO_AVCLOOPFILTERTYPE;\n\n\n/**\n * AVC params\n *\n * STRUCT MEMBERS:\n *  nSize                     : Size of the structure in bytes\n *  nVersion                  : OMX specification version information\n *  nPortIndex                : Port that this structure applies to\n *  nSliceHeaderSpacing       : Number of macroblocks between slice header, put\n *                              zero if not used\n *  nPFrames                  : Number of P frames between each I frame\n *  nBFrames                  : Number of B frames between each I frame\n *  bUseHadamard              : Enable/disable Hadamard transform\n *  nRefFrames                : Max number of reference frames to use for inter\n *                              motion search (1-16)\n *  nRefIdxTrailing           : Pic param set ref frame index (index into ref\n *                              frame buffer of trailing frames list), B frame\n *                              support\n *  nRefIdxForward            : Pic param set ref frame index (index into ref\n *                              frame buffer of forward frames list), B frame\n *                              support\n *  bEnableUEP                : Enable/disable unequal error protection. This\n *                              is only valid of data partitioning is enabled.\n *  bEnableFMO                : Enable/disable flexible macroblock ordering\n *  bEnableASO                : Enable/disable arbitrary slice ordering\n *  bEnableRS                 : Enable/disable sending of redundant slices\n *  eProfile                  : AVC profile(s) to use\n *  eLevel                    : AVC level(s) to use\n *  nAllowedPictureTypes      : Specifies the picture types allowed in the\n *                              bitstream\n *  bFrameMBsOnly             : specifies that every coded picture of the\n *                              coded video sequence is a coded frame\n *                              containing only frame macroblocks\n *  bMBAFF                    : Enable/disable switching between frame and\n *                              field macroblocks within a picture\n *  bEntropyCodingCABAC       : Entropy decoding method to be applied for the\n *                              syntax elements for which two descriptors appear\n *                              in the syntax tables\n *  bWeightedPPrediction      : Enable/disable weighted prediction shall not\n *                              be applied to P and SP slices\n *  nWeightedBipredicitonMode : Default weighted prediction is applied to B\n *                              slices\n *  bconstIpred               : Enable/disable intra prediction\n *  bDirect8x8Inference       : Specifies the method used in the derivation\n *                              process for luma motion vectors for B_Skip,\n *                              B_Direct_16x16 and B_Direct_8x8 as specified\n *                              in subclause 8.4.1.2 of the AVC spec\n *  bDirectSpatialTemporal    : Flag indicating spatial or temporal direct\n *                              mode used in B slice coding (related to\n *                              bDirect8x8Inference) . Spatial direct mode is\n *                              more common and should be the default.\n *  nCabacInitIdx             : Index used to init CABAC contexts\n *  eLoopFilterMode           : Enable/disable loop filter\n */\ntypedef struct OMX_VIDEO_PARAM_AVCTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nSliceHeaderSpacing;\n    OMX_U32 nPFrames;\n    OMX_U32 nBFrames;\n    OMX_BOOL bUseHadamard;\n    OMX_U32 nRefFrames;\n    OMX_U32 nRefIdx10ActiveMinus1;\n    OMX_U32 nRefIdx11ActiveMinus1;\n    OMX_BOOL bEnableUEP;\n    OMX_BOOL bEnableFMO;\n    OMX_BOOL bEnableASO;\n    OMX_BOOL bEnableRS;\n    OMX_VIDEO_AVCPROFILETYPE eProfile;\n    OMX_VIDEO_AVCLEVELTYPE eLevel;\n    OMX_U32 nAllowedPictureTypes;\n    OMX_BOOL bFrameMBsOnly;\n    OMX_BOOL bMBAFF;\n    OMX_BOOL bEntropyCodingCABAC;\n    OMX_BOOL bWeightedPPrediction;\n    OMX_U32 nWeightedBipredicitonMode;\n    OMX_BOOL bconstIpred ;\n    OMX_BOOL bDirect8x8Inference;\n    OMX_BOOL bDirectSpatialTemporal;\n    OMX_U32 nCabacInitIdc;\n    OMX_VIDEO_AVCLOOPFILTERTYPE eLoopFilterMode;\n} OMX_VIDEO_PARAM_AVCTYPE;\n\ntypedef struct OMX_VIDEO_PARAM_PROFILELEVELTYPE {\n   OMX_U32 nSize;\n   OMX_VERSIONTYPE nVersion;\n   OMX_U32 nPortIndex;\n   OMX_U32 eProfile;      /**< type is OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE,\n                                 or OMX_VIDEO_MPEG4PROFILETYPE depending on context */\n   OMX_U32 eLevel;        /**< type is OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE,\n                                 or OMX_VIDEO_MPEG4PROFILETYPE depending on context */\n   OMX_U32 nProfileIndex; /**< Used to query for individual profile support information,\n                               This parameter is valid only for\n                               OMX_IndexParamVideoProfileLevelQuerySupported index,\n                               For all other indices this parameter is to be ignored. */\n} OMX_VIDEO_PARAM_PROFILELEVELTYPE;\n\n/**\n * Structure for dynamically configuring bitrate mode of a codec.\n *\n * STRUCT MEMBERS:\n *  nSize          : Size of the struct in bytes\n *  nVersion       : OMX spec version info\n *  nPortIndex     : Port that this struct applies to\n *  nEncodeBitrate : Target average bitrate to be generated in bps\n */\ntypedef struct OMX_VIDEO_CONFIG_BITRATETYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nEncodeBitrate;\n} OMX_VIDEO_CONFIG_BITRATETYPE;\n\n/**\n * Defines Encoder Frame Rate setting\n *\n * STRUCT MEMBERS:\n *  nSize            : Size of the structure in bytes\n *  nVersion         : OMX specification version information\n *  nPortIndex       : Port that this structure applies to\n *  xEncodeFramerate : Encoding framerate represented in Q16 format\n */\ntypedef struct OMX_CONFIG_FRAMERATETYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 xEncodeFramerate; /* Q16 format */\n} OMX_CONFIG_FRAMERATETYPE;\n\ntypedef struct OMX_CONFIG_INTRAREFRESHVOPTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL IntraRefreshVOP;\n} OMX_CONFIG_INTRAREFRESHVOPTYPE;\n\ntypedef struct OMX_CONFIG_MACROBLOCKERRORMAPTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nErrMapSize;           /* Size of the Error Map in bytes */\n    OMX_U8  ErrMap[1];             /* Error map hint */\n} OMX_CONFIG_MACROBLOCKERRORMAPTYPE;\n\ntypedef struct OMX_CONFIG_MBERRORREPORTINGTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL bEnabled;\n} OMX_CONFIG_MBERRORREPORTINGTYPE;\n\ntypedef struct OMX_PARAM_MACROBLOCKSTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nMacroblocks;\n} OMX_PARAM_MACROBLOCKSTYPE;\n\n/**\n * AVC Slice Mode modes\n *\n * OMX_VIDEO_SLICEMODE_AVCDefault   : Normal frame encoding, one slice per frame\n * OMX_VIDEO_SLICEMODE_AVCMBSlice   : NAL mode, number of MBs per frame\n * OMX_VIDEO_SLICEMODE_AVCByteSlice : NAL mode, number of bytes per frame\n */\ntypedef enum OMX_VIDEO_AVCSLICEMODETYPE {\n    OMX_VIDEO_SLICEMODE_AVCDefault = 0,\n    OMX_VIDEO_SLICEMODE_AVCMBSlice,\n    OMX_VIDEO_SLICEMODE_AVCByteSlice,\n    OMX_VIDEO_SLICEMODE_AVCKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */\n    OMX_VIDEO_SLICEMODE_AVCVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */\n    OMX_VIDEO_SLICEMODE_AVCLevelMax = 0x7FFFFFFF\n} OMX_VIDEO_AVCSLICEMODETYPE;\n\n/**\n * AVC FMO Slice Mode Params\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nNumSliceGroups : Specifies the number of slice groups\n *  nSliceGroupMapType : Specifies the type of slice groups\n *  eSliceMode : Specifies the type of slice\n */\ntypedef struct OMX_VIDEO_PARAM_AVCSLICEFMO {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U8 nNumSliceGroups;\n    OMX_U8 nSliceGroupMapType;\n    OMX_VIDEO_AVCSLICEMODETYPE eSliceMode;\n} OMX_VIDEO_PARAM_AVCSLICEFMO;\n\n/**\n * AVC IDR Period Configs\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nIDRPeriod : Specifies periodicity of IDR frames\n *  nPFrames : Specifies internal of coding Intra frames\n */\ntypedef struct OMX_VIDEO_CONFIG_AVCINTRAPERIOD {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nIDRPeriod;\n    OMX_U32 nPFrames;\n} OMX_VIDEO_CONFIG_AVCINTRAPERIOD;\n\n/**\n * AVC NAL Size Configs\n *\n * STRUCT MEMBERS:\n *  nSize      : Size of the structure in bytes\n *  nVersion   : OMX specification version information\n *  nPortIndex : Port that this structure applies to\n *  nNaluBytes : Specifies the NAL unit size\n */\ntypedef struct OMX_VIDEO_CONFIG_NALSIZE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nNaluBytes;\n} OMX_VIDEO_CONFIG_NALSIZE;\n\n/** @} */\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif\n/* File EOF */\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/media/openmax/OMX_VideoExt.h",
    "content": "/*\n * Copyright (c) 2010 The Khronos Group Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject\n * to the following conditions:\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n/** OMX_VideoExt.h - OpenMax IL version 1.1.2\n * The OMX_VideoExt header file contains extensions to the\n * definitions used by both the application and the component to\n * access video items.\n */\n\n#ifndef OMX_VideoExt_h\n#define OMX_VideoExt_h\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/* Each OMX header shall include all required header files to allow the\n * header to compile without errors.  The includes below are required\n * for this header file to compile successfully\n */\n#include <OMX_Core.h>\n\n/** NALU Formats */\ntypedef enum OMX_NALUFORMATSTYPE {\n    OMX_NaluFormatStartCodes = 1,\n    OMX_NaluFormatOneNaluPerBuffer = 2,\n    OMX_NaluFormatOneByteInterleaveLength = 4,\n    OMX_NaluFormatTwoByteInterleaveLength = 8,\n    OMX_NaluFormatFourByteInterleaveLength = 16,\n    OMX_NaluFormatCodingMax = 0x7FFFFFFF\n} OMX_NALUFORMATSTYPE;\n\n/** NAL Stream Format */\ntypedef struct OMX_NALSTREAMFORMATTYPE{\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_NALUFORMATSTYPE eNaluFormat;\n} OMX_NALSTREAMFORMATTYPE;\n\n/** VP8 profiles */\ntypedef enum OMX_VIDEO_VP8PROFILETYPE {\n    OMX_VIDEO_VP8ProfileMain = 0x01,\n    OMX_VIDEO_VP8ProfileUnknown = 0x6EFFFFFF,\n    OMX_VIDEO_VP8ProfileMax = 0x7FFFFFFF\n} OMX_VIDEO_VP8PROFILETYPE;\n\n/** VP8 levels */\ntypedef enum OMX_VIDEO_VP8LEVELTYPE {\n    OMX_VIDEO_VP8Level_Version0 = 0x01,\n    OMX_VIDEO_VP8Level_Version1 = 0x02,\n    OMX_VIDEO_VP8Level_Version2 = 0x04,\n    OMX_VIDEO_VP8Level_Version3 = 0x08,\n    OMX_VIDEO_VP8LevelUnknown = 0x6EFFFFFF,\n    OMX_VIDEO_VP8LevelMax = 0x7FFFFFFF\n} OMX_VIDEO_VP8LEVELTYPE;\n\n/** VP9 profiles */\ntypedef enum OMX_VIDEO_VP9PROFILETYPE {\n    OMX_VIDEO_VP9Profile0       = 0x1,\n    OMX_VIDEO_VP9Profile1       = 0x2,\n    OMX_VIDEO_VP9Profile2       = 0x4,\n    OMX_VIDEO_VP9Profile3       = 0x8,\n    // HDR profiles also support passing HDR metadata\n    OMX_VIDEO_VP9Profile2HDR    = 0x1000,\n    OMX_VIDEO_VP9Profile3HDR    = 0x2000,\n    OMX_VIDEO_VP9ProfileUnknown = 0x6EFFFFFF,\n    OMX_VIDEO_VP9ProfileMax     = 0x7FFFFFFF\n} OMX_VIDEO_VP9PROFILETYPE;\n\n/** VP9 levels */\ntypedef enum OMX_VIDEO_VP9LEVELTYPE {\n    OMX_VIDEO_VP9Level1       = 0x1,\n    OMX_VIDEO_VP9Level11      = 0x2,\n    OMX_VIDEO_VP9Level2       = 0x4,\n    OMX_VIDEO_VP9Level21      = 0x8,\n    OMX_VIDEO_VP9Level3       = 0x10,\n    OMX_VIDEO_VP9Level31      = 0x20,\n    OMX_VIDEO_VP9Level4       = 0x40,\n    OMX_VIDEO_VP9Level41      = 0x80,\n    OMX_VIDEO_VP9Level5       = 0x100,\n    OMX_VIDEO_VP9Level51      = 0x200,\n    OMX_VIDEO_VP9Level52      = 0x400,\n    OMX_VIDEO_VP9Level6       = 0x800,\n    OMX_VIDEO_VP9Level61      = 0x1000,\n    OMX_VIDEO_VP9Level62      = 0x2000,\n    OMX_VIDEO_VP9LevelUnknown = 0x6EFFFFFF,\n    OMX_VIDEO_VP9LevelMax     = 0x7FFFFFFF\n} OMX_VIDEO_VP9LEVELTYPE;\n\n/** VP8 Param */\ntypedef struct OMX_VIDEO_PARAM_VP8TYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_VIDEO_VP8PROFILETYPE eProfile;\n    OMX_VIDEO_VP8LEVELTYPE eLevel;\n    OMX_U32 nDCTPartitions;\n    OMX_BOOL bErrorResilientMode;\n} OMX_VIDEO_PARAM_VP8TYPE;\n\n/** Structure for configuring VP8 reference frames */\ntypedef struct OMX_VIDEO_VP8REFERENCEFRAMETYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL bPreviousFrameRefresh;\n    OMX_BOOL bGoldenFrameRefresh;\n    OMX_BOOL bAlternateFrameRefresh;\n    OMX_BOOL bUsePreviousFrame;\n    OMX_BOOL bUseGoldenFrame;\n    OMX_BOOL bUseAlternateFrame;\n} OMX_VIDEO_VP8REFERENCEFRAMETYPE;\n\n/** Structure for querying VP8 reference frame type */\ntypedef struct OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL bIsIntraFrame;\n    OMX_BOOL bIsGoldenOrAlternateFrame;\n} OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE;\n\n/** Maximum number of VP8 temporal layers */\n#define OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS 3\n\n/** VP8 temporal layer patterns */\ntypedef enum OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE {\n    OMX_VIDEO_VPXTemporalLayerPatternNone = 0,\n    OMX_VIDEO_VPXTemporalLayerPatternWebRTC = 1,\n    OMX_VIDEO_VPXTemporalLayerPatternMax = 0x7FFFFFFF\n} OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE;\n\n/**\n * Android specific VP8 encoder params\n *\n * STRUCT MEMBERS:\n *  nSize                      : Size of the structure in bytes\n *  nVersion                   : OMX specification version information\n *  nPortIndex                 : Port that this structure applies to\n *  nKeyFrameInterval          : Key frame interval in frames\n *  eTemporalPattern           : Type of temporal layer pattern\n *  nTemporalLayerCount        : Number of temporal coding layers\n *  nTemporalLayerBitrateRatio : Bitrate ratio allocation between temporal\n *                               streams in percentage\n *  nMinQuantizer              : Minimum (best quality) quantizer\n *  nMaxQuantizer              : Maximum (worst quality) quantizer\n */\ntypedef struct OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nKeyFrameInterval;\n    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE eTemporalPattern;\n    OMX_U32 nTemporalLayerCount;\n    OMX_U32 nTemporalLayerBitrateRatio[OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS];\n    OMX_U32 nMinQuantizer;\n    OMX_U32 nMaxQuantizer;\n} OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE;\n\n/** HEVC Profile enum type */\ntypedef enum OMX_VIDEO_HEVCPROFILETYPE {\n    OMX_VIDEO_HEVCProfileUnknown      = 0x0,\n    OMX_VIDEO_HEVCProfileMain         = 0x1,\n    OMX_VIDEO_HEVCProfileMain10       = 0x2,\n    // Main10 profile with HDR SEI support.\n    OMX_VIDEO_HEVCProfileMain10HDR10  = 0x1000,\n    OMX_VIDEO_HEVCProfileMax          = 0x7FFFFFFF\n} OMX_VIDEO_HEVCPROFILETYPE;\n\n/** HEVC Level enum type */\ntypedef enum OMX_VIDEO_HEVCLEVELTYPE {\n    OMX_VIDEO_HEVCLevelUnknown    = 0x0,\n    OMX_VIDEO_HEVCMainTierLevel1  = 0x1,\n    OMX_VIDEO_HEVCHighTierLevel1  = 0x2,\n    OMX_VIDEO_HEVCMainTierLevel2  = 0x4,\n    OMX_VIDEO_HEVCHighTierLevel2  = 0x8,\n    OMX_VIDEO_HEVCMainTierLevel21 = 0x10,\n    OMX_VIDEO_HEVCHighTierLevel21 = 0x20,\n    OMX_VIDEO_HEVCMainTierLevel3  = 0x40,\n    OMX_VIDEO_HEVCHighTierLevel3  = 0x80,\n    OMX_VIDEO_HEVCMainTierLevel31 = 0x100,\n    OMX_VIDEO_HEVCHighTierLevel31 = 0x200,\n    OMX_VIDEO_HEVCMainTierLevel4  = 0x400,\n    OMX_VIDEO_HEVCHighTierLevel4  = 0x800,\n    OMX_VIDEO_HEVCMainTierLevel41 = 0x1000,\n    OMX_VIDEO_HEVCHighTierLevel41 = 0x2000,\n    OMX_VIDEO_HEVCMainTierLevel5  = 0x4000,\n    OMX_VIDEO_HEVCHighTierLevel5  = 0x8000,\n    OMX_VIDEO_HEVCMainTierLevel51 = 0x10000,\n    OMX_VIDEO_HEVCHighTierLevel51 = 0x20000,\n    OMX_VIDEO_HEVCMainTierLevel52 = 0x40000,\n    OMX_VIDEO_HEVCHighTierLevel52 = 0x80000,\n    OMX_VIDEO_HEVCMainTierLevel6  = 0x100000,\n    OMX_VIDEO_HEVCHighTierLevel6  = 0x200000,\n    OMX_VIDEO_HEVCMainTierLevel61 = 0x400000,\n    OMX_VIDEO_HEVCHighTierLevel61 = 0x800000,\n    OMX_VIDEO_HEVCMainTierLevel62 = 0x1000000,\n    OMX_VIDEO_HEVCHighTierLevel62 = 0x2000000,\n    OMX_VIDEO_HEVCHighTiermax     = 0x7FFFFFFF\n} OMX_VIDEO_HEVCLEVELTYPE;\n\n/** Structure for controlling HEVC video encoding */\ntypedef struct OMX_VIDEO_PARAM_HEVCTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_VIDEO_HEVCPROFILETYPE eProfile;\n    OMX_VIDEO_HEVCLEVELTYPE eLevel;\n    OMX_U32 nKeyFrameInterval;\n} OMX_VIDEO_PARAM_HEVCTYPE;\n\n/** Structure to define if dependent slice segments should be used */\ntypedef struct OMX_VIDEO_SLICESEGMENTSTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_BOOL bDepedentSegments;\n    OMX_BOOL bEnableLoopFilterAcrossSlices;\n} OMX_VIDEO_SLICESEGMENTSTYPE;\n\n/** Structure to return timestamps of rendered output frames as well as EOS\n *  for tunneled components.\n */\ntypedef struct OMX_VIDEO_RENDEREVENTTYPE {\n    OMX_S64 nMediaTimeUs;  // timestamp of rendered video frame\n    OMX_S64 nSystemTimeNs; // system monotonic time at the time frame was rendered\n                           // Use INT64_MAX for nMediaTimeUs to signal that the EOS\n                           // has been reached. In this case, nSystemTimeNs MUST be\n                           // the system time when the last frame was rendered.\n                           // This MUST be done in addition to returning (and\n                           // following) the render information for the last frame.\n} OMX_VIDEO_RENDEREVENTTYPE;\n\n/** Dolby Vision Profile enum type */\ntypedef enum OMX_VIDEO_DOLBYVISIONPROFILETYPE {\n    OMX_VIDEO_DolbyVisionProfileUnknown = 0x0,\n    OMX_VIDEO_DolbyVisionProfileDvavPer = 0x1,\n    OMX_VIDEO_DolbyVisionProfileDvavPen = 0x2,\n    OMX_VIDEO_DolbyVisionProfileDvheDer = 0x4,\n    OMX_VIDEO_DolbyVisionProfileDvheDen = 0x8,\n    OMX_VIDEO_DolbyVisionProfileDvheDtr = 0x10,\n    OMX_VIDEO_DolbyVisionProfileDvheStn = 0x20,\n    OMX_VIDEO_DolbyVisionProfileDvheDth = 0x40,\n    OMX_VIDEO_DolbyVisionProfileDvheDtb = 0x80,\n    OMX_VIDEO_DolbyVisionProfileMax     = 0x7FFFFFFF\n} OMX_VIDEO_DOLBYVISIONPROFILETYPE;\n\n/** Dolby Vision Level enum type */\ntypedef enum OMX_VIDEO_DOLBYVISIONLEVELTYPE {\n    OMX_VIDEO_DolbyVisionLevelUnknown = 0x0,\n    OMX_VIDEO_DolbyVisionLevelHd24    = 0x1,\n    OMX_VIDEO_DolbyVisionLevelHd30    = 0x2,\n    OMX_VIDEO_DolbyVisionLevelFhd24   = 0x4,\n    OMX_VIDEO_DolbyVisionLevelFhd30   = 0x8,\n    OMX_VIDEO_DolbyVisionLevelFhd60   = 0x10,\n    OMX_VIDEO_DolbyVisionLevelUhd24   = 0x20,\n    OMX_VIDEO_DolbyVisionLevelUhd30   = 0x40,\n    OMX_VIDEO_DolbyVisionLevelUhd48   = 0x80,\n    OMX_VIDEO_DolbyVisionLevelUhd60   = 0x100,\n    OMX_VIDEO_DolbyVisionLevelmax     = 0x7FFFFFFF\n} OMX_VIDEO_DOLBYVISIONLEVELTYPE;\n\n/**\n * Structure for configuring video compression intra refresh period\n *\n * STRUCT MEMBERS:\n *  nSize               : Size of the structure in bytes\n *  nVersion            : OMX specification version information\n *  nPortIndex          : Port that this structure applies to\n *  nRefreshPeriod      : Intra refreh period in frames. Value 0 means disable intra refresh\n*/\ntypedef struct OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE {\n    OMX_U32 nSize;\n    OMX_VERSIONTYPE nVersion;\n    OMX_U32 nPortIndex;\n    OMX_U32 nRefreshPeriod;\n} OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE;\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* OMX_VideoExt_h */\n/* File EOF */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/powermanager/IPowerManager.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_IPOWERMANAGER_H\n#define ANDROID_IPOWERMANAGER_H\n\n#include <utils/Errors.h>\n#include <binder/IInterface.h>\n#include <hardware/power.h>\n\nnamespace android {\n\n// ----------------------------------------------------------------------------\n\nclass IPowerManager : public IInterface\n{\npublic:\n    // These transaction IDs must be kept in sync with the method order from\n    // IPowerManager.aidl.\n    enum {\n        ACQUIRE_WAKE_LOCK            = IBinder::FIRST_CALL_TRANSACTION,\n        ACQUIRE_WAKE_LOCK_UID        = IBinder::FIRST_CALL_TRANSACTION + 1,\n        RELEASE_WAKE_LOCK            = IBinder::FIRST_CALL_TRANSACTION + 2,\n        UPDATE_WAKE_LOCK_UIDS        = IBinder::FIRST_CALL_TRANSACTION + 3,\n        POWER_HINT                   = IBinder::FIRST_CALL_TRANSACTION + 4,\n        UPDATE_WAKE_LOCK_SOURCE      = IBinder::FIRST_CALL_TRANSACTION + 5,\n        IS_WAKE_LOCK_LEVEL_SUPPORTED = IBinder::FIRST_CALL_TRANSACTION + 6,\n        USER_ACTIVITY                = IBinder::FIRST_CALL_TRANSACTION + 7,\n        WAKE_UP                      = IBinder::FIRST_CALL_TRANSACTION + 8,\n        GO_TO_SLEEP                  = IBinder::FIRST_CALL_TRANSACTION + 9,\n        NAP                          = IBinder::FIRST_CALL_TRANSACTION + 10,\n        IS_INTERACTIVE               = IBinder::FIRST_CALL_TRANSACTION + 11,\n        IS_POWER_SAVE_MODE           = IBinder::FIRST_CALL_TRANSACTION + 12,\n        SET_POWER_SAVE_MODE          = IBinder::FIRST_CALL_TRANSACTION + 13,\n        REBOOT                       = IBinder::FIRST_CALL_TRANSACTION + 14,\n        SHUTDOWN                     = IBinder::FIRST_CALL_TRANSACTION + 15,\n        CRASH                        = IBinder::FIRST_CALL_TRANSACTION + 16,\n    };\n\n    DECLARE_META_INTERFACE(PowerManager);\n\n    // The parcels created by these methods must be kept in sync with the\n    // corresponding methods from IPowerManager.aidl.\n    // FIXME remove the bool isOneWay parameters as they are not oneway in the .aidl\n    virtual status_t acquireWakeLock(int flags, const sp<IBinder>& lock, const String16& tag,\n            const String16& packageName, bool isOneWay = false) = 0;\n    virtual status_t acquireWakeLockWithUid(int flags, const sp<IBinder>& lock, const String16& tag,\n            const String16& packageName, int uid, bool isOneWay = false) = 0;\n    virtual status_t releaseWakeLock(const sp<IBinder>& lock, int flags, bool isOneWay = false) = 0;\n    virtual status_t updateWakeLockUids(const sp<IBinder>& lock, int len, const int *uids,\n            bool isOneWay = false) = 0;\n    virtual status_t powerHint(int hintId, int data) = 0;\n    virtual status_t goToSleep(int64_t event_time_ms, int reason, int flags) = 0;\n    virtual status_t reboot(bool confirm, const String16& reason, bool wait) = 0;\n    virtual status_t shutdown(bool confirm, const String16& reason, bool wait) = 0;\n    virtual status_t crash(const String16& message) = 0;\n};\n\n// ----------------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_IPOWERMANAGER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/powermanager/PowerManager.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_POWERMANAGER_H\n#define ANDROID_POWERMANAGER_H\n\nnamespace android {\n\n// must be kept in sync with definitions in PowerManager.java\nenum {\n    POWERMANAGER_PARTIAL_WAKE_LOCK = 1, // equals PowerManager.PARTIAL_WAKE_LOCK constant\n};\n\nenum {\n    USER_ACTIVITY_EVENT_OTHER = 0,\n    USER_ACTIVITY_EVENT_BUTTON = 1,\n    USER_ACTIVITY_EVENT_TOUCH = 2,\n    USER_ACTIVITY_EVENT_ACCESSIBILITY = 3,\n\n    USER_ACTIVITY_EVENT_LAST = USER_ACTIVITY_EVENT_ACCESSIBILITY, // Last valid event code.\n};\n\n}; // namespace android\n\n#endif // ANDROID_POWERMANAGER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/private/binder/Static.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// All static variables go here, to control initialization and\n// destruction order in the library.\n\n#include <utils/threads.h>\n\n#include <binder/IBinder.h>\n#include <binder/IMemory.h>\n#include <binder/ProcessState.h>\n#include <binder/IPermissionController.h>\n#include <binder/IServiceManager.h>\n\nnamespace android {\n\n// For TextStream.cpp\nextern Vector<int32_t> gTextBuffers;\n\n// For ProcessState.cpp\nextern Mutex gProcessMutex;\nextern sp<ProcessState> gProcess;\n\n// For IServiceManager.cpp\nextern Mutex gDefaultServiceManagerLock;\nextern sp<IServiceManager> gDefaultServiceManager;\nextern sp<IPermissionController> gPermissionController;\n\n}   // namespace android\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/private/binder/binder_module.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _BINDER_MODULE_H_\n#define _BINDER_MODULE_H_\n\n#ifdef __cplusplus\nnamespace android {\n#endif\n\n/* obtain structures and constants from the kernel header */\n\n#include <sys/ioctl.h>\n#include <linux/binder.h>\n\n#ifdef __cplusplus\n}   // namespace android\n#endif\n\n#endif // _BINDER_MODULE_H_\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/private/gui/ComposerService.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H\n#define ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Singleton.h>\n#include <utils/StrongPointer.h>\n\n\nnamespace android {\n\n// ---------------------------------------------------------------------------\n\nclass IMemoryHeap;\nclass ISurfaceComposer;\n\n// ---------------------------------------------------------------------------\n\n// This holds our connection to the composer service (i.e. SurfaceFlinger).\n// If the remote side goes away, we will re-establish the connection.\n// Users of this class should not retain the value from\n// getComposerService() for an extended period.\n//\n// (It's not clear that using Singleton is useful here anymore.)\nclass ComposerService : public Singleton<ComposerService>\n{\n    sp<ISurfaceComposer> mComposerService;\n    sp<IBinder::DeathRecipient> mDeathObserver;\n    Mutex mLock;\n\n    ComposerService();\n    void connectLocked();\n    void composerServiceDied();\n    friend class Singleton<ComposerService>;\npublic:\n\n    // Get a connection to the Composer Service.  This will block until\n    // a connection is established.\n    static sp<ISurfaceComposer> getComposerService();\n};\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/private/gui/LayerState.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_SF_LAYER_STATE_H\n#define ANDROID_SF_LAYER_STATE_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Errors.h>\n\n#include <ui/Region.h>\n#include <ui/Rect.h>\n\nnamespace android {\n\nclass Parcel;\nclass ISurfaceComposerClient;\n\n/*\n * Used to communicate layer information between SurfaceFlinger and its clients.\n */\nstruct layer_state_t {\n\n\n    enum {\n        eLayerHidden        = 0x01,     // SURFACE_HIDDEN in SurfaceControl.java\n        eLayerOpaque        = 0x02,     // SURFACE_OPAQUE\n        eLayerSecure        = 0x80,     // SECURE\n    };\n\n    enum {\n        ePositionChanged            = 0x00000001,\n        eLayerChanged               = 0x00000002,\n        eSizeChanged                = 0x00000004,\n        eAlphaChanged               = 0x00000008,\n        eMatrixChanged              = 0x00000010,\n        eTransparentRegionChanged   = 0x00000020,\n        eFlagsChanged               = 0x00000040,\n        eLayerStackChanged          = 0x00000080,\n        eCropChanged                = 0x00000100,\n        eDeferTransaction           = 0x00000200,\n        eFinalCropChanged           = 0x00000400,\n        eOverrideScalingModeChanged = 0x00000800,\n        ePositionAppliesWithResize  = 0x00001000,\n    };\n\n    layer_state_t()\n        :   what(0),\n            x(0), y(0), z(0), w(0), h(0), layerStack(0),\n            alpha(0), flags(0), mask(0),\n            reserved(0), crop(Rect::INVALID_RECT),\n            finalCrop(Rect::INVALID_RECT), frameNumber(0),\n            overrideScalingMode(-1)\n    {\n        matrix.dsdx = matrix.dtdy = 1.0f;\n        matrix.dsdy = matrix.dtdx = 0.0f;\n    }\n\n    status_t    write(Parcel& output) const;\n    status_t    read(const Parcel& input);\n\n            struct matrix22_t {\n                float   dsdx;\n                float   dtdx;\n                float   dsdy;\n                float   dtdy;\n            };\n            sp<IBinder>     surface;\n            uint32_t        what;\n            float           x;\n            float           y;\n            uint32_t        z;\n            uint32_t        w;\n            uint32_t        h;\n            uint32_t        layerStack;\n            float           alpha;\n            uint8_t         flags;\n            uint8_t         mask;\n            uint8_t         reserved;\n            matrix22_t      matrix;\n            Rect            crop;\n            Rect            finalCrop;\n            sp<IBinder>     handle;\n            uint64_t        frameNumber;\n            int32_t         overrideScalingMode;\n            // non POD must be last. see write/read\n            Region          transparentRegion;\n};\n\nstruct ComposerState {\n    sp<ISurfaceComposerClient> client;\n    layer_state_t state;\n    status_t    write(Parcel& output) const;\n    status_t    read(const Parcel& input);\n};\n\nstruct DisplayState {\n\n    enum {\n        eOrientationDefault     = 0,\n        eOrientation90          = 1,\n        eOrientation180         = 2,\n        eOrientation270         = 3,\n        eOrientationUnchanged   = 4,\n        eOrientationSwapMask    = 0x01\n    };\n\n    enum {\n        eSurfaceChanged             = 0x01,\n        eLayerStackChanged          = 0x02,\n        eDisplayProjectionChanged   = 0x04,\n        eDisplaySizeChanged         = 0x08\n    };\n\n    DisplayState();\n\n    uint32_t what;\n    sp<IBinder> token;\n    sp<IGraphicBufferProducer> surface;\n    uint32_t layerStack;\n    uint32_t orientation;\n    Rect viewport;\n    Rect frame;\n    uint32_t width, height;\n    status_t write(Parcel& output) const;\n    status_t read(const Parcel& input);\n};\n\n}; // namespace android\n\n#endif // ANDROID_SF_LAYER_STATE_H\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/private/gui/SyncFeatures.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GUI_SYNC_FEATURES_H\n#define ANDROID_GUI_SYNC_FEATURES_H\n\n#include <utils/Singleton.h>\n#include <utils/String8.h>\n\n\nnamespace android {\n// ----------------------------------------------------------------------------\n\nclass SyncFeatures : public Singleton<SyncFeatures> {\n    friend class Singleton<SyncFeatures>;\n    bool mHasNativeFenceSync;\n    bool mHasFenceSync;\n    bool mHasWaitSync;\n    String8 mString;\n    SyncFeatures();\n\npublic:\n    bool useNativeFenceSync() const;\n    bool useFenceSync() const;\n    bool useWaitSync() const;\n    String8 toString() const;\n};\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_GUI_SYNC_FEATURES_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/private/ui/RegionHelper.h",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UI_PRIVATE_REGION_HELPER_H\n#define ANDROID_UI_PRIVATE_REGION_HELPER_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\nnamespace android {\n// ----------------------------------------------------------------------------\n\ntemplate<typename RECT>\nclass region_operator\n{\npublic:\n    typedef typename RECT::value_type TYPE;    \n    static const TYPE max_value = 0x7FFFFFF;\n\n    /* \n     * Common boolean operations:\n     * value is computed as 0b101 op 0b110\n     *    other boolean operation are possible, simply compute\n     *    their corresponding value with the above formulae and use\n     *    it when instantiating a region_operator.\n     */\n    static const uint32_t LHS = 0x5;  // 0b101\n    static const uint32_t RHS = 0x6;  // 0b110\n    enum {\n        op_nand = LHS & ~RHS,\n        op_and  = LHS &  RHS,\n        op_or   = LHS |  RHS,\n        op_xor  = LHS ^  RHS\n    };\n\n    struct region {\n        RECT const* rects;\n        size_t count;\n        TYPE dx;\n        TYPE dy;\n        inline region(const region& rhs) \n            : rects(rhs.rects), count(rhs.count), dx(rhs.dx), dy(rhs.dy) { }\n        inline region(RECT const* r, size_t c) \n            : rects(r), count(c), dx(), dy() { }\n        inline region(RECT const* r, size_t c, TYPE dx, TYPE dy) \n            : rects(r), count(c), dx(dx), dy(dy) { }\n    };\n\n    class region_rasterizer {\n        friend class region_operator;\n        virtual void operator()(const RECT& rect) = 0;\n    public:\n        virtual ~region_rasterizer() { };\n    };\n    \n    inline region_operator(int op, const region& lhs, const region& rhs) \n        : op_mask(op), spanner(lhs, rhs) \n    {\n    }\n\n    void operator()(region_rasterizer& rasterizer) {\n        RECT current(Rect::EMPTY_RECT);\n        do {\n            SpannerInner spannerInner(spanner.lhs, spanner.rhs);\n            int inside = spanner.next(current.top, current.bottom);\n            spannerInner.prepare(inside);\n            do {\n                TYPE left, right;\n                int inside = spannerInner.next(current.left, current.right);\n                if ((op_mask >> inside) & 1) {\n                    if (current.left < current.right && \n                            current.top < current.bottom) {\n                        rasterizer(current);\n                    }\n                }\n            } while(!spannerInner.isDone());\n        } while(!spanner.isDone());\n    }\n\nprivate:    \n    uint32_t op_mask;\n\n    class SpannerBase\n    {\n    public:\n        SpannerBase()\n            : lhs_head(max_value), lhs_tail(max_value),\n              rhs_head(max_value), rhs_tail(max_value) {\n        }\n\n        enum {\n            lhs_before_rhs   = 0,\n            lhs_after_rhs    = 1,\n            lhs_coincide_rhs = 2\n        };\n\n    protected:\n        TYPE lhs_head;\n        TYPE lhs_tail;\n        TYPE rhs_head;\n        TYPE rhs_tail;\n\n        inline int next(TYPE& head, TYPE& tail,\n                bool& more_lhs, bool& more_rhs) \n        {\n            int inside;\n            more_lhs = false;\n            more_rhs = false;\n            if (lhs_head < rhs_head) {\n                inside = lhs_before_rhs;\n                head = lhs_head;\n                if (lhs_tail <= rhs_head) {\n                    tail = lhs_tail;\n                    more_lhs = true;\n                } else {\n                    lhs_head = rhs_head;\n                    tail = rhs_head;\n                }\n            } else if (rhs_head < lhs_head) {\n                inside = lhs_after_rhs;\n                head = rhs_head;\n                if (rhs_tail <= lhs_head) {\n                    tail = rhs_tail;\n                    more_rhs = true;\n                } else {\n                    rhs_head = lhs_head;\n                    tail = lhs_head;\n                }\n            } else {\n                inside = lhs_coincide_rhs;\n                head = lhs_head;\n                if (lhs_tail <= rhs_tail) {\n                    tail = rhs_head = lhs_tail;\n                    more_lhs = true;\n                }\n                if (rhs_tail <= lhs_tail) {\n                    tail = lhs_head = rhs_tail;\n                    more_rhs = true;\n                }\n            }\n            return inside;\n        }\n    };\n\n    class Spanner : protected SpannerBase \n    {\n        friend class region_operator;\n        region lhs;\n        region rhs;\n\n    public:\n        inline Spanner(const region& lhs, const region& rhs)\n        : lhs(lhs), rhs(rhs)\n        {\n            if (lhs.count) {\n                SpannerBase::lhs_head = lhs.rects->top      + lhs.dy;\n                SpannerBase::lhs_tail = lhs.rects->bottom   + lhs.dy;\n            }\n            if (rhs.count) {\n                SpannerBase::rhs_head = rhs.rects->top      + rhs.dy;\n                SpannerBase::rhs_tail = rhs.rects->bottom   + rhs.dy;\n            }\n        }\n\n        inline bool isDone() const {\n            return !rhs.count && !lhs.count;\n        }\n\n        inline int next(TYPE& top, TYPE& bottom) \n        {\n            bool more_lhs = false;\n            bool more_rhs = false;\n            int inside = SpannerBase::next(top, bottom, more_lhs, more_rhs);\n            if (more_lhs) {\n                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);\n            }\n            if (more_rhs) {\n                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);\n            }\n            return inside;\n        }\n\n    private:\n        static inline \n        void advance(region& reg, TYPE& aTop, TYPE& aBottom) {\n            // got to next span\n            size_t count = reg.count;\n            RECT const * rects = reg.rects;\n            RECT const * const end = rects + count;\n            const int top = rects->top;\n            while (rects != end && rects->top == top) {\n                rects++;\n                count--;\n            }\n            if (rects != end) {\n                aTop    = rects->top    + reg.dy;\n                aBottom = rects->bottom + reg.dy;\n            } else {\n                aTop    = max_value;\n                aBottom = max_value;\n            }\n            reg.rects = rects;\n            reg.count = count;\n        }\n    };\n\n    class SpannerInner : protected SpannerBase \n    {\n        region lhs;\n        region rhs;\n        \n    public:\n        inline SpannerInner(const region& lhs, const region& rhs)\n            : lhs(lhs), rhs(rhs) \n        {\n        }\n\n        inline void prepare(int inside) {\n            if (inside == SpannerBase::lhs_before_rhs) {\n                if (lhs.count) {\n                    SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;\n                    SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;\n                }\n                SpannerBase::rhs_head = max_value;\n                SpannerBase::rhs_tail = max_value;\n            } else if (inside == SpannerBase::lhs_after_rhs) {\n                SpannerBase::lhs_head = max_value;\n                SpannerBase::lhs_tail = max_value;\n                if (rhs.count) {\n                    SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;\n                    SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;\n                }\n            } else {\n                if (lhs.count) {\n                    SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;\n                    SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;\n                }\n                if (rhs.count) {\n                    SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;\n                    SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;\n                }\n            }\n        }\n\n        inline bool isDone() const {\n            return SpannerBase::lhs_head == max_value && \n                   SpannerBase::rhs_head == max_value;\n        }\n\n        inline int next(TYPE& left, TYPE& right) \n        {\n            bool more_lhs = false;\n            bool more_rhs = false;\n            int inside = SpannerBase::next(left, right, more_lhs, more_rhs);\n            if (more_lhs) {\n                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);\n            }\n            if (more_rhs) {\n                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);\n            }\n            return inside;\n        }\n\n    private:\n        static inline \n        void advance(region& reg, TYPE& left, TYPE& right) {\n            if (reg.rects && reg.count) {\n                const int cur_span_top = reg.rects->top;\n                reg.rects++;\n                reg.count--;\n                if (!reg.count || reg.rects->top != cur_span_top) {\n                    left  = max_value;\n                    right = max_value;\n                } else {\n                    left  = reg.rects->left  + reg.dx;\n                    right = reg.rects->right + reg.dx;\n                }\n            }\n        }\n    };\n\n    Spanner spanner;\n};\n\n// ----------------------------------------------------------------------------\n};\n\n#endif /* ANDROID_UI_PRIVATE_REGION_HELPER_H */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/ANativeObjectBase.h",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_ANDROID_NATIVES_H\n#define ANDROID_ANDROID_NATIVES_H\n\n#include <sys/types.h>\n#include <string.h>\n\n#include <hardware/gralloc.h>\n#include <system/window.h>\n\n// ---------------------------------------------------------------------------\n\n/* FIXME: this is legacy for pixmaps */\ntypedef struct egl_native_pixmap_t\n{\n    int32_t     version;    /* must be 32 */\n    int32_t     width;\n    int32_t     height;\n    int32_t     stride;\n    uint8_t*    data;\n    uint8_t     format;\n    uint8_t     rfu[3];\n    union {\n        uint32_t    compressedFormat;\n        int32_t     vstride;\n    };\n    int32_t     reserved;\n} egl_native_pixmap_t;\n\n/*****************************************************************************/\n\n#ifdef __cplusplus\n\n#include <utils/RefBase.h>\n\nnamespace android {\n\n/*\n * This helper class turns a ANativeXXX object type into a C++\n * reference-counted object; with proper type conversions.\n */\ntemplate <typename NATIVE_TYPE, typename TYPE, typename REF>\nclass ANativeObjectBase : public NATIVE_TYPE, public REF\n{\npublic:\n    // Disambiguate between the incStrong in REF and NATIVE_TYPE\n    void incStrong(const void* id) const {\n        REF::incStrong(id);\n    }\n    void decStrong(const void* id) const {\n        REF::decStrong(id);\n    }\n\nprotected:\n    typedef ANativeObjectBase<NATIVE_TYPE, TYPE, REF> BASE;\n    ANativeObjectBase() : NATIVE_TYPE(), REF() {\n        NATIVE_TYPE::common.incRef = incRef;\n        NATIVE_TYPE::common.decRef = decRef;\n    }\n    static inline TYPE* getSelf(NATIVE_TYPE* self) {\n        return static_cast<TYPE*>(self);\n    }\n    static inline TYPE const* getSelf(NATIVE_TYPE const* self) {\n        return static_cast<TYPE const *>(self);\n    }\n    static inline TYPE* getSelf(android_native_base_t* base) {\n        return getSelf(reinterpret_cast<NATIVE_TYPE*>(base));\n    }\n    static inline TYPE const * getSelf(android_native_base_t const* base) {\n        return getSelf(reinterpret_cast<NATIVE_TYPE const*>(base));\n    }\n    static void incRef(android_native_base_t* base) {\n        ANativeObjectBase* self = getSelf(base);\n        self->incStrong(self);\n    }\n    static void decRef(android_native_base_t* base) {\n        ANativeObjectBase* self = getSelf(base);\n        self->decStrong(self);\n    }\n};\n\n} // namespace android\n#endif // __cplusplus\n\n/*****************************************************************************/\n\n#endif /* ANDROID_ANDROID_NATIVES_H */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/DisplayInfo.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UI_DISPLAY_INFO_H\n#define ANDROID_UI_DISPLAY_INFO_H\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <utils/Timers.h>\n\n#include <ui/PixelFormat.h>\n\nnamespace android {\n\nstruct DisplayInfo {\n    uint32_t w;\n    uint32_t h;\n    float xdpi;\n    float ydpi;\n    float fps;\n    float density;\n    uint8_t orientation;\n    bool secure;\n    nsecs_t appVsyncOffset;\n    nsecs_t presentationDeadline;\n    int colorTransform;\n};\n\n/* Display orientations as defined in Surface.java and ISurfaceComposer.h. */\nenum {\n    DISPLAY_ORIENTATION_0 = 0,\n    DISPLAY_ORIENTATION_90 = 1,\n    DISPLAY_ORIENTATION_180 = 2,\n    DISPLAY_ORIENTATION_270 = 3\n};\n\n}; // namespace android\n\n#endif // ANDROID_COMPOSER_DISPLAY_INFO_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/DisplayStatInfo.h",
    "content": "/*\n * Copyright 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UI_DISPLAY_STAT_INFO_H\n#define ANDROID_UI_DISPLAY_STAT_INFO_H\n\n#include <utils/Timers.h>\n\nnamespace android {\n\nstruct DisplayStatInfo {\n    nsecs_t vsyncTime;\n    nsecs_t vsyncPeriod;\n};\n\n}; // namespace android\n\n#endif // ANDROID_COMPOSER_DISPLAY_STAT_INFO_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/Fence.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_FENCE_H\n#define ANDROID_FENCE_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <ui/ANativeObjectBase.h>\n#include <ui/PixelFormat.h>\n#include <ui/Rect.h>\n#include <utils/Flattenable.h>\n#include <utils/String8.h>\n#include <utils/Timers.h>\n\nstruct ANativeWindowBuffer;\n\nnamespace android {\n\n// ===========================================================================\n// Fence\n// ===========================================================================\n\nclass Fence\n    : public LightRefBase<Fence>, public Flattenable<Fence>\n{\npublic:\n    static const sp<Fence> NO_FENCE;\n\n    // TIMEOUT_NEVER may be passed to the wait method to indicate that it\n    // should wait indefinitely for the fence to signal.\n    enum { TIMEOUT_NEVER = -1 };\n\n    // Construct a new Fence object with an invalid file descriptor.  This\n    // should be done when the Fence object will be set up by unflattening\n    // serialized data.\n    Fence();\n\n    // Construct a new Fence object to manage a given fence file descriptor.\n    // When the new Fence object is destructed the file descriptor will be\n    // closed.\n    Fence(int fenceFd);\n\n    // Check whether the Fence has an open fence file descriptor. Most Fence\n    // methods treat an invalid file descriptor just like a valid fence that\n    // is already signalled, so using this is usually not necessary.\n    bool isValid() const { return mFenceFd != -1; }\n\n    // wait waits for up to timeout milliseconds for the fence to signal.  If\n    // the fence signals then NO_ERROR is returned. If the timeout expires\n    // before the fence signals then -ETIME is returned.  A timeout of\n    // TIMEOUT_NEVER may be used to indicate that the call should wait\n    // indefinitely for the fence to signal.\n    status_t wait(int timeout);\n\n    // waitForever is a convenience function for waiting forever for a fence to\n    // signal (just like wait(TIMEOUT_NEVER)), but issuing an error to the\n    // system log and fence state to the kernel log if the wait lasts longer\n    // than a warning timeout.\n    // The logname argument should be a string identifying\n    // the caller and will be included in the log message.\n    status_t waitForever(const char* logname);\n\n    // merge combines two Fence objects, creating a new Fence object that\n    // becomes signaled when both f1 and f2 are signaled (even if f1 or f2 is\n    // destroyed before it becomes signaled).  The name argument specifies the\n    // human-readable name to associated with the new Fence object.\n    static sp<Fence> merge(const String8& name, const sp<Fence>& f1,\n            const sp<Fence>& f2);\n\n    // Return a duplicate of the fence file descriptor. The caller is\n    // responsible for closing the returned file descriptor. On error, -1 will\n    // be returned and errno will indicate the problem.\n    int dup() const;\n\n    // getSignalTime returns the system monotonic clock time at which the\n    // fence transitioned to the signaled state.  If the fence is not signaled\n    // then INT64_MAX is returned.  If the fence is invalid or if an error\n    // occurs then -1 is returned.\n    nsecs_t getSignalTime() const;\n\n    // Flattenable interface\n    size_t getFlattenedSize() const;\n    size_t getFdCount() const;\n    status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;\n    status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);\n\nprivate:\n    // Only allow instantiation using ref counting.\n    friend class LightRefBase<Fence>;\n    ~Fence();\n\n    // Disallow copying\n    Fence(const Fence& rhs);\n    Fence& operator = (const Fence& rhs);\n    const Fence& operator = (const Fence& rhs) const;\n\n    int mFenceFd;\n};\n\n}; // namespace android\n\n#endif // ANDROID_FENCE_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/FrameStats.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UI_FRAME_STATS_H\n#define ANDROID_UI_FRAME_STATS_H\n\n#include <utils/Flattenable.h>\n#include <utils/Timers.h>\n#include <utils/Vector.h>\n\nnamespace android {\n\nclass FrameStats : public LightFlattenable<FrameStats> {\npublic:\n    FrameStats() : refreshPeriodNano(0) {};\n\n    /*\n     * Approximate refresh time, in nanoseconds.\n     */\n    nsecs_t refreshPeriodNano;\n\n   /*\n    * The times in nanoseconds for when the frame contents were posted by the producer (e.g.\n    * the application). They are either explicitly set or defaulted to the time when\n    * Surface::queueBuffer() was called.\n    */\n    Vector<nsecs_t> desiredPresentTimesNano;\n\n   /*\n    * The times in milliseconds for when the frame contents were presented on the screen.\n    */\n    Vector<nsecs_t> actualPresentTimesNano;\n\n   /*\n    * The times in nanoseconds for when the frame contents were ready to be presented. Note that\n    * a frame can be posted and still it contents being rendered asynchronously in GL. In such a\n    * case these are the times when the frame contents were completely rendered (i.e. their fences\n    * signaled).\n    */\n    Vector<nsecs_t> frameReadyTimesNano;\n\n    // LightFlattenable\n    bool isFixedSize() const;\n    size_t getFlattenedSize() const;\n    status_t flatten(void* buffer, size_t size) const;\n    status_t unflatten(void const* buffer, size_t size);\n};\n\n}; // namespace android\n\n#endif // ANDROID_UI_FRAME_STATS_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/GraphicBuffer.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_GRAPHIC_BUFFER_H\n#define ANDROID_GRAPHIC_BUFFER_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <ui/ANativeObjectBase.h>\n#include <ui/PixelFormat.h>\n#include <ui/Rect.h>\n#include <utils/Flattenable.h>\n#include <utils/RefBase.h>\n\n\nstruct ANativeWindowBuffer;\n\nnamespace android {\n\nclass GraphicBufferMapper;\n\n// ===========================================================================\n// GraphicBuffer\n// ===========================================================================\n\nclass GraphicBuffer\n    : public ANativeObjectBase< ANativeWindowBuffer, GraphicBuffer, RefBase >,\n      public Flattenable<GraphicBuffer>\n{\n    friend class Flattenable<GraphicBuffer>;\npublic:\n\n    enum {\n        USAGE_SW_READ_NEVER     = GRALLOC_USAGE_SW_READ_NEVER,\n        USAGE_SW_READ_RARELY    = GRALLOC_USAGE_SW_READ_RARELY,\n        USAGE_SW_READ_OFTEN     = GRALLOC_USAGE_SW_READ_OFTEN,\n        USAGE_SW_READ_MASK      = GRALLOC_USAGE_SW_READ_MASK,\n\n        USAGE_SW_WRITE_NEVER    = GRALLOC_USAGE_SW_WRITE_NEVER,\n        USAGE_SW_WRITE_RARELY   = GRALLOC_USAGE_SW_WRITE_RARELY,\n        USAGE_SW_WRITE_OFTEN    = GRALLOC_USAGE_SW_WRITE_OFTEN,\n        USAGE_SW_WRITE_MASK     = GRALLOC_USAGE_SW_WRITE_MASK,\n\n        USAGE_SOFTWARE_MASK     = USAGE_SW_READ_MASK|USAGE_SW_WRITE_MASK,\n\n        USAGE_PROTECTED         = GRALLOC_USAGE_PROTECTED,\n\n        USAGE_HW_TEXTURE        = GRALLOC_USAGE_HW_TEXTURE,\n        USAGE_HW_RENDER         = GRALLOC_USAGE_HW_RENDER,\n        USAGE_HW_2D             = GRALLOC_USAGE_HW_2D,\n        USAGE_HW_COMPOSER       = GRALLOC_USAGE_HW_COMPOSER,\n        USAGE_HW_VIDEO_ENCODER  = GRALLOC_USAGE_HW_VIDEO_ENCODER,\n        USAGE_HW_MASK           = GRALLOC_USAGE_HW_MASK,\n\n        USAGE_CURSOR            = GRALLOC_USAGE_CURSOR,\n    };\n\n    GraphicBuffer();\n\n    // creates w * h buffer\n    GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,\n            uint32_t inUsage);\n\n    // create a buffer from an existing handle\n    GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,\n            uint32_t inUsage, uint32_t inStride, native_handle_t* inHandle,\n            bool keepOwnership);\n\n    // create a buffer from an existing ANativeWindowBuffer\n    GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership);\n\n    // return status\n    status_t initCheck() const;\n\n    uint32_t getWidth() const           { return static_cast<uint32_t>(width); }\n    uint32_t getHeight() const          { return static_cast<uint32_t>(height); }\n    uint32_t getStride() const          { return static_cast<uint32_t>(stride); }\n    uint32_t getUsage() const           { return static_cast<uint32_t>(usage); }\n    PixelFormat getPixelFormat() const  { return format; }\n    Rect getBounds() const              { return Rect(width, height); }\n    uint64_t getId() const              { return mId; }\n\n    uint32_t getGenerationNumber() const { return mGenerationNumber; }\n    void setGenerationNumber(uint32_t generation) {\n        mGenerationNumber = generation;\n    }\n\n    status_t reallocate(uint32_t inWidth, uint32_t inHeight,\n            PixelFormat inFormat, uint32_t inUsage);\n\n    bool needsReallocation(uint32_t inWidth, uint32_t inHeight,\n            PixelFormat inFormat, uint32_t inUsage);\n\n    status_t lock(uint32_t inUsage, void** vaddr);\n    status_t lock(uint32_t inUsage, const Rect& rect, void** vaddr);\n    // For HAL_PIXEL_FORMAT_YCbCr_420_888\n    status_t lockYCbCr(uint32_t inUsage, android_ycbcr *ycbcr);\n    status_t lockYCbCr(uint32_t inUsage, const Rect& rect,\n            android_ycbcr *ycbcr);\n    status_t unlock();\n    status_t lockAsync(uint32_t inUsage, void** vaddr, int fenceFd);\n    status_t lockAsync(uint32_t inUsage, const Rect& rect, void** vaddr,\n            int fenceFd);\n    status_t lockAsyncYCbCr(uint32_t inUsage, android_ycbcr *ycbcr,\n            int fenceFd);\n    status_t lockAsyncYCbCr(uint32_t inUsage, const Rect& rect,\n            android_ycbcr *ycbcr, int fenceFd);\n    status_t unlockAsync(int *fenceFd);\n\n    ANativeWindowBuffer* getNativeBuffer() const;\n\n    // for debugging\n    static void dumpAllocationsToSystemLog();\n\n    // Flattenable protocol\n    size_t getFlattenedSize() const;\n    size_t getFdCount() const;\n    status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;\n    status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);\n\nprivate:\n    ~GraphicBuffer();\n\n    enum {\n        ownNone   = 0,\n        ownHandle = 1,\n        ownData   = 2,\n    };\n\n    inline const GraphicBufferMapper& getBufferMapper() const {\n        return mBufferMapper;\n    }\n    inline GraphicBufferMapper& getBufferMapper() {\n        return mBufferMapper;\n    }\n    uint8_t mOwner;\n\nprivate:\n    friend class Surface;\n    friend class BpSurface;\n    friend class BnSurface;\n    friend class LightRefBase<GraphicBuffer>;\n    GraphicBuffer(const GraphicBuffer& rhs);\n    GraphicBuffer& operator = (const GraphicBuffer& rhs);\n    const GraphicBuffer& operator = (const GraphicBuffer& rhs) const;\n\n    status_t initSize(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,\n            uint32_t inUsage);\n\n    void free_handle();\n\n    GraphicBufferMapper& mBufferMapper;\n    ssize_t mInitCheck;\n\n    // If we're wrapping another buffer then this reference will make sure it\n    // doesn't get freed.\n    sp<ANativeWindowBuffer> mWrappedBuffer;\n\n    uint64_t mId;\n\n    // Stores the generation number of this buffer. If this number does not\n    // match the BufferQueue's internal generation number (set through\n    // IGBP::setGenerationNumber), attempts to attach the buffer will fail.\n    uint32_t mGenerationNumber;\n};\n\n}; // namespace android\n\n#endif // ANDROID_GRAPHIC_BUFFER_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/GraphicBufferAllocator.h",
    "content": "/*\n**\n** Copyright 2009, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\");\n** you may not use this file except in compliance with the License.\n** You may obtain a copy of the License at\n**\n**     http://www.apache.org/licenses/LICENSE-2.0\n**\n** Unless required by applicable law or agreed to in writing, software\n** distributed under the License is distributed on an \"AS IS\" BASIS,\n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n** See the License for the specific language governing permissions and\n** limitations under the License.\n*/\n\n#ifndef ANDROID_BUFFER_ALLOCATOR_H\n#define ANDROID_BUFFER_ALLOCATOR_H\n\n#include <stdint.h>\n\n#include <cutils/native_handle.h>\n\n#include <utils/Errors.h>\n#include <utils/KeyedVector.h>\n#include <utils/threads.h>\n#include <utils/Singleton.h>\n\n#include <ui/PixelFormat.h>\n\n#include <hardware/gralloc.h>\n\n\nnamespace android {\n// ---------------------------------------------------------------------------\n\nclass String8;\n\nclass GraphicBufferAllocator : public Singleton<GraphicBufferAllocator>\n{\npublic:\n    enum {\n        USAGE_SW_READ_NEVER     = GRALLOC_USAGE_SW_READ_NEVER,\n        USAGE_SW_READ_RARELY    = GRALLOC_USAGE_SW_READ_RARELY,\n        USAGE_SW_READ_OFTEN     = GRALLOC_USAGE_SW_READ_OFTEN,\n        USAGE_SW_READ_MASK      = GRALLOC_USAGE_SW_READ_MASK,\n\n        USAGE_SW_WRITE_NEVER    = GRALLOC_USAGE_SW_WRITE_NEVER,\n        USAGE_SW_WRITE_RARELY   = GRALLOC_USAGE_SW_WRITE_RARELY,\n        USAGE_SW_WRITE_OFTEN    = GRALLOC_USAGE_SW_WRITE_OFTEN,\n        USAGE_SW_WRITE_MASK     = GRALLOC_USAGE_SW_WRITE_MASK,\n\n        USAGE_SOFTWARE_MASK     = USAGE_SW_READ_MASK|USAGE_SW_WRITE_MASK,\n\n        USAGE_HW_TEXTURE        = GRALLOC_USAGE_HW_TEXTURE,\n        USAGE_HW_RENDER         = GRALLOC_USAGE_HW_RENDER,\n        USAGE_HW_2D             = GRALLOC_USAGE_HW_2D,\n        USAGE_HW_MASK           = GRALLOC_USAGE_HW_MASK\n    };\n\n    static inline GraphicBufferAllocator& get() { return getInstance(); }\n\n    status_t alloc(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage,\n            buffer_handle_t* handle, uint32_t* stride);\n\n    status_t free(buffer_handle_t handle);\n\n    void dump(String8& res) const;\n    static void dumpToSystemLog();\n\nprivate:\n    struct alloc_rec_t {\n        uint32_t width;\n        uint32_t height;\n        uint32_t stride;\n        PixelFormat format;\n        uint32_t usage;\n        size_t size;\n    };\n\n    static Mutex sLock;\n    static KeyedVector<buffer_handle_t, alloc_rec_t> sAllocList;\n\n    friend class Singleton<GraphicBufferAllocator>;\n    GraphicBufferAllocator();\n    ~GraphicBufferAllocator();\n\n    alloc_device_t  *mAllocDev;\n};\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_BUFFER_ALLOCATOR_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/GraphicBufferMapper.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UI_BUFFER_MAPPER_H\n#define ANDROID_UI_BUFFER_MAPPER_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Singleton.h>\n\n#include <hardware/gralloc.h>\n\n\nstruct gralloc_module_t;\n\nnamespace android {\n\n// ---------------------------------------------------------------------------\n\nclass Rect;\n\nclass GraphicBufferMapper : public Singleton<GraphicBufferMapper>\n{\npublic:\n    static inline GraphicBufferMapper& get() { return getInstance(); }\n\n    status_t registerBuffer(buffer_handle_t handle);\n\n    status_t unregisterBuffer(buffer_handle_t handle);\n\n    status_t lock(buffer_handle_t handle,\n            uint32_t usage, const Rect& bounds, void** vaddr);\n\n    status_t lockYCbCr(buffer_handle_t handle,\n            uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr);\n\n    status_t unlock(buffer_handle_t handle);\n\n    status_t lockAsync(buffer_handle_t handle,\n            uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd);\n\n    status_t lockAsyncYCbCr(buffer_handle_t handle,\n            uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr,\n            int fenceFd);\n\n    status_t unlockAsync(buffer_handle_t handle, int *fenceFd);\n\n    // dumps information about the mapping of this handle\n    void dump(buffer_handle_t handle);\n\nprivate:\n    friend class Singleton<GraphicBufferMapper>;\n    GraphicBufferMapper();\n    gralloc_module_t const *mAllocMod;\n};\n\n// ---------------------------------------------------------------------------\n\n}; // namespace android\n\n#endif // ANDROID_UI_BUFFER_MAPPER_H\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/HdrCapabilities.h",
    "content": "/*\n * Copyright 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UI_HDR_CAPABILTIES_H\n#define ANDROID_UI_HDR_CAPABILTIES_H\n\n#include <binder/Parcelable.h>\n\nnamespace android {\n\nclass HdrCapabilities : public Parcelable\n{\npublic:\n    HdrCapabilities(const std::vector<int32_t /*android_hdr_t*/>& types,\n            float maxLuminance, float maxAverageLuminance, float minLuminance)\n      : mSupportedHdrTypes(types),\n        mMaxLuminance(maxLuminance),\n        mMaxAverageLuminance(maxAverageLuminance),\n        mMinLuminance(minLuminance) {}\n\n    // Make this move-constructable and move-assignable\n    HdrCapabilities(HdrCapabilities&& other) = default;\n    HdrCapabilities& operator=(HdrCapabilities&& other) = default;\n\n    HdrCapabilities()\n      : mSupportedHdrTypes(),\n        mMaxLuminance(-1.0f),\n        mMaxAverageLuminance(-1.0f),\n        mMinLuminance(-1.0f) {}\n\n    virtual ~HdrCapabilities() = default;\n\n    const std::vector<int32_t /*android_hdr_t*/>& getSupportedHdrTypes() const {\n        return mSupportedHdrTypes;\n    }\n    float getDesiredMaxLuminance() const { return mMaxLuminance; }\n    float getDesiredMaxAverageLuminance() const { return mMaxAverageLuminance; }\n    float getDesiredMinLuminance() const { return mMinLuminance; }\n\n    // Parcelable interface\n    virtual status_t writeToParcel(Parcel* parcel) const override;\n    virtual status_t readFromParcel(const Parcel* parcel) override;\n\nprivate:\n    std::vector<int32_t /*android_hdr_t*/> mSupportedHdrTypes;\n    float mMaxLuminance;\n    float mMaxAverageLuminance;\n    float mMinLuminance;\n};\n\n} // namespace android\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/PixelFormat.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n\n// Pixel formats used across the system.\n// These formats might not all be supported by all renderers, for instance\n// skia or SurfaceFlinger are not required to support all of these formats\n// (either as source or destination)\n\n\n#ifndef UI_PIXELFORMAT_H\n#define UI_PIXELFORMAT_H\n\n#include <hardware/hardware.h>\n\nnamespace android {\n\nenum {\n    //\n    // these constants need to match those\n    // in graphics/PixelFormat.java & pixelflinger/format.h\n    //\n    PIXEL_FORMAT_UNKNOWN    =   0,\n    PIXEL_FORMAT_NONE       =   0,\n\n    // logical pixel formats used by the SurfaceFlinger -----------------------\n    PIXEL_FORMAT_CUSTOM         = -4,\n        // Custom pixel-format described by a PixelFormatInfo structure\n\n    PIXEL_FORMAT_TRANSLUCENT    = -3,\n        // System chooses a format that supports translucency (many alpha bits)\n\n    PIXEL_FORMAT_TRANSPARENT    = -2,\n        // System chooses a format that supports transparency\n        // (at least 1 alpha bit)\n\n    PIXEL_FORMAT_OPAQUE         = -1,\n        // System chooses an opaque format (no alpha bits required)\n\n    // real pixel formats supported for rendering -----------------------------\n\n    PIXEL_FORMAT_RGBA_8888   = HAL_PIXEL_FORMAT_RGBA_8888,   // 4x8-bit RGBA\n    PIXEL_FORMAT_RGBX_8888   = HAL_PIXEL_FORMAT_RGBX_8888,   // 4x8-bit RGB0\n    PIXEL_FORMAT_RGB_888     = HAL_PIXEL_FORMAT_RGB_888,     // 3x8-bit RGB\n    PIXEL_FORMAT_RGB_565     = HAL_PIXEL_FORMAT_RGB_565,     // 16-bit RGB\n    PIXEL_FORMAT_BGRA_8888   = HAL_PIXEL_FORMAT_BGRA_8888,   // 4x8-bit BGRA\n    PIXEL_FORMAT_RGBA_5551   = 6,                            // 16-bit ARGB\n    PIXEL_FORMAT_RGBA_4444   = 7,                            // 16-bit ARGB\n};\n\ntypedef int32_t PixelFormat;\n\nuint32_t bytesPerPixel(PixelFormat format);\nuint32_t bitsPerPixel(PixelFormat format);\n\n}; // namespace android\n\n#endif // UI_PIXELFORMAT_H\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/Point.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UI_POINT\n#define ANDROID_UI_POINT\n\n#include <utils/Flattenable.h>\n#include <utils/TypeHelpers.h>\n\nnamespace android {\n\nclass Point : public LightFlattenablePod<Point>\n{\npublic:\n    int x;\n    int y;\n\n    // we don't provide copy-ctor and operator= on purpose\n    // because we want the compiler generated versions\n\n    // Default constructor doesn't initialize the Point\n    inline Point() {\n    }\n    inline Point(int x, int y) : x(x), y(y) {\n    }\n\n    inline bool operator == (const Point& rhs) const {\n        return (x == rhs.x) && (y == rhs.y);\n    }\n    inline bool operator != (const Point& rhs) const {\n        return !operator == (rhs);\n    }\n\n    inline bool isOrigin() const {\n        return !(x|y);\n    }\n\n    // operator < defines an order which allows to use points in sorted\n    // vectors.\n    bool operator < (const Point& rhs) const {\n        return y<rhs.y || (y==rhs.y && x<rhs.x);\n    }\n\n    inline Point& operator - () {\n        x = -x;\n        y = -y;\n        return *this;\n    }\n    \n    inline Point& operator += (const Point& rhs) {\n        x += rhs.x;\n        y += rhs.y;\n        return *this;\n    }\n    inline Point& operator -= (const Point& rhs) {\n        x -= rhs.x;\n        y -= rhs.y;\n        return *this;\n    }\n    \n    const Point operator + (const Point& rhs) const {\n        const Point result(x+rhs.x, y+rhs.y);\n        return result;\n    }\n    const Point operator - (const Point& rhs) const {\n        const Point result(x-rhs.x, y-rhs.y);\n        return result;\n    }    \n};\n\nANDROID_BASIC_TYPES_TRAITS(Point)\n\n}; // namespace android\n\n#endif // ANDROID_UI_POINT\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/Rect.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UI_RECT\n#define ANDROID_UI_RECT\n\n#include <utils/Flattenable.h>\n#include <utils/Log.h>\n#include <utils/TypeHelpers.h>\n#include <ui/Point.h>\n\n#include <android/rect.h>\n\nnamespace android {\n\nclass Rect : public ARect, public LightFlattenablePod<Rect>\n{\npublic:\n    typedef ARect::value_type value_type;\n\n    static const Rect INVALID_RECT;\n    static const Rect EMPTY_RECT;\n\n    // we don't provide copy-ctor and operator= on purpose\n    // because we want the compiler generated versions\n\n    inline Rect() : Rect(INVALID_RECT) {}\n\n    template <typename T>\n    inline Rect(T w, T h) {\n        if (w > INT32_MAX) {\n            ALOG(LOG_WARN, \"Rect\",\n                    \"Width %u too large for Rect class, clamping\", w);\n            w = INT32_MAX;\n        }\n        if (h > INT32_MAX) {\n            ALOG(LOG_WARN, \"Rect\",\n                    \"Height %u too large for Rect class, clamping\", h);\n            h = INT32_MAX;\n        }\n        left = top = 0;\n        right = static_cast<int32_t>(w);\n        bottom = static_cast<int32_t>(h);\n    }\n\n    inline Rect(int32_t l, int32_t t, int32_t r, int32_t b) {\n        left = l;\n        top = t;\n        right = r;\n        bottom = b;\n    }\n\n    inline Rect(const Point& lt, const Point& rb) {\n        left = lt.x;\n        top = lt.y;\n        right = rb.x;\n        bottom = rb.y;\n    }\n\n    void makeInvalid();\n\n    inline void clear() {\n        left = top = right = bottom = 0;\n    }\n\n    // a valid rectangle has a non negative width and height\n    inline bool isValid() const {\n        return (getWidth() >= 0) && (getHeight() >= 0);\n    }\n\n    // an empty rect has a zero width or height, or is invalid\n    inline bool isEmpty() const {\n        return (getWidth() <= 0) || (getHeight() <= 0);\n    }\n\n    // rectangle's width\n    inline int32_t getWidth() const {\n        return right - left;\n    }\n\n    // rectangle's height\n    inline int32_t getHeight() const {\n        return bottom - top;\n    }\n\n    inline Rect getBounds() const {\n        return Rect(right - left, bottom - top);\n    }\n\n    void setLeftTop(const Point& lt) {\n        left = lt.x;\n        top = lt.y;\n    }\n\n    void setRightBottom(const Point& rb) {\n        right = rb.x;\n        bottom = rb.y;\n    }\n    \n    // the following 4 functions return the 4 corners of the rect as Point\n    Point leftTop() const {\n        return Point(left, top);\n    }\n    Point rightBottom() const {\n        return Point(right, bottom);\n    }\n    Point rightTop() const {\n        return Point(right, top);\n    }\n    Point leftBottom() const {\n        return Point(left, bottom);\n    }\n\n    // comparisons\n    inline bool operator == (const Rect& rhs) const {\n        return (left == rhs.left) && (top == rhs.top) &&\n               (right == rhs.right) && (bottom == rhs.bottom);\n    }\n\n    inline bool operator != (const Rect& rhs) const {\n        return !operator == (rhs);\n    }\n\n    // operator < defines an order which allows to use rectangles in sorted\n    // vectors.\n    bool operator < (const Rect& rhs) const;\n\n    const Rect operator + (const Point& rhs) const;\n    const Rect operator - (const Point& rhs) const;\n\n    Rect& operator += (const Point& rhs) {\n        return offsetBy(rhs.x, rhs.y);\n    }\n    Rect& operator -= (const Point& rhs) {\n        return offsetBy(-rhs.x, -rhs.y);\n    }\n\n    Rect& offsetToOrigin() {\n        right -= left;\n        bottom -= top;\n        left = top = 0;\n        return *this;\n    }\n    Rect& offsetTo(const Point& p) {\n        return offsetTo(p.x, p.y);\n    }\n    Rect& offsetBy(const Point& dp) {\n        return offsetBy(dp.x, dp.y);\n    }\n\n    Rect& offsetTo(int32_t x, int32_t y);\n    Rect& offsetBy(int32_t x, int32_t y);\n\n    bool intersect(const Rect& with, Rect* result) const;\n\n    // Create a new Rect by transforming this one using a graphics HAL\n    // transform.  This rectangle is defined in a coordinate space starting at\n    // the origin and extending to (width, height).  If the transform includes\n    // a ROT90 then the output rectangle is defined in a space extending to\n    // (height, width).  Otherwise the output rectangle is in the same space as\n    // the input.\n    Rect transform(uint32_t xform, int32_t width, int32_t height) const;\n\n    // this calculates (Region(*this) - exclude).bounds() efficiently\n    Rect reduce(const Rect& exclude) const;\n\n\n    // for backward compatibility\n    inline int32_t width() const { return getWidth(); }\n    inline int32_t height() const { return getHeight(); }\n    inline void set(const Rect& rhs) { operator = (rhs); }\n};\n\nANDROID_BASIC_TYPES_TRAITS(Rect)\n\n}; // namespace android\n\n#endif // ANDROID_UI_RECT\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/Region.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UI_REGION_H\n#define ANDROID_UI_REGION_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Vector.h>\n\n#include <ui/Rect.h>\n#include <utils/Flattenable.h>\n\nnamespace android {\n// ---------------------------------------------------------------------------\n\nclass String8;\n\n// ---------------------------------------------------------------------------\nclass Region : public LightFlattenable<Region>\n{\npublic:\n    static const Region INVALID_REGION;\n\n                        Region();\n                        Region(const Region& rhs);\n    explicit            Region(const Rect& rhs);\n                        ~Region();\n\n    static  Region      createTJunctionFreeRegion(const Region& r);\n\n        Region& operator = (const Region& rhs);\n\n    inline  bool        isEmpty() const     { return getBounds().isEmpty(); }\n    inline  bool        isRect() const      { return mStorage.size() == 1; }\n\n    inline  Rect        getBounds() const   { return mStorage[mStorage.size() - 1]; }\n    inline  Rect        bounds() const      { return getBounds(); }\n\n            bool        contains(const Point& point) const;\n            bool        contains(int x, int y) const;\n\n            // the region becomes its bounds\n            Region&     makeBoundsSelf();\n\n            void        clear();\n            void        set(const Rect& r);\n            void        set(int32_t w, int32_t h);\n            void        set(uint32_t w, uint32_t h);\n\n            Region&     orSelf(const Rect& rhs);\n            Region&     xorSelf(const Rect& rhs);\n            Region&     andSelf(const Rect& rhs);\n            Region&     subtractSelf(const Rect& rhs);\n\n            // boolean operators, applied on this\n            Region&     orSelf(const Region& rhs);\n            Region&     xorSelf(const Region& rhs);\n            Region&     andSelf(const Region& rhs);\n            Region&     subtractSelf(const Region& rhs);\n\n            // boolean operators\n    const   Region      merge(const Rect& rhs) const;\n    const   Region      mergeExclusive(const Rect& rhs) const;\n    const   Region      intersect(const Rect& rhs) const;\n    const   Region      subtract(const Rect& rhs) const;\n\n            // boolean operators\n    const   Region      merge(const Region& rhs) const;\n    const   Region      mergeExclusive(const Region& rhs) const;\n    const   Region      intersect(const Region& rhs) const;\n    const   Region      subtract(const Region& rhs) const;\n\n            // these translate rhs first\n            Region&     translateSelf(int dx, int dy);\n            Region&     orSelf(const Region& rhs, int dx, int dy);\n            Region&     xorSelf(const Region& rhs, int dx, int dy);\n            Region&     andSelf(const Region& rhs, int dx, int dy);\n            Region&     subtractSelf(const Region& rhs, int dx, int dy);\n\n            // these translate rhs first\n    const   Region      translate(int dx, int dy) const;\n    const   Region      merge(const Region& rhs, int dx, int dy) const;\n    const   Region      mergeExclusive(const Region& rhs, int dx, int dy) const;\n    const   Region      intersect(const Region& rhs, int dx, int dy) const;\n    const   Region      subtract(const Region& rhs, int dx, int dy) const;\n\n    // convenience operators overloads\n    inline  const Region      operator | (const Region& rhs) const;\n    inline  const Region      operator ^ (const Region& rhs) const;\n    inline  const Region      operator & (const Region& rhs) const;\n    inline  const Region      operator - (const Region& rhs) const;\n    inline  const Region      operator + (const Point& pt) const;\n\n    inline  Region&     operator |= (const Region& rhs);\n    inline  Region&     operator ^= (const Region& rhs);\n    inline  Region&     operator &= (const Region& rhs);\n    inline  Region&     operator -= (const Region& rhs);\n    inline  Region&     operator += (const Point& pt);\n\n\n    // returns true if the regions share the same underlying storage\n    bool isTriviallyEqual(const Region& region) const;\n\n\n    /* various ways to access the rectangle list */\n\n\n    // STL-like iterators\n    typedef Rect const* const_iterator;\n    const_iterator begin() const;\n    const_iterator end() const;\n\n    // returns an array of rect which has the same life-time has this\n    // Region object.\n    Rect const* getArray(size_t* count) const;\n\n    /* no user serviceable parts here... */\n\n            // add a rectangle to the internal list. This rectangle must\n            // be sorted in Y and X and must not make the region invalid.\n            void        addRectUnchecked(int l, int t, int r, int b);\n\n    inline  bool        isFixedSize() const { return false; }\n            size_t      getFlattenedSize() const;\n            status_t    flatten(void* buffer, size_t size) const;\n            status_t    unflatten(void const* buffer, size_t size);\n\n    void        dump(String8& out, const char* what, uint32_t flags=0) const;\n    void        dump(const char* what, uint32_t flags=0) const;\n\nprivate:\n    class rasterizer;\n    friend class rasterizer;\n\n    Region& operationSelf(const Rect& r, int op);\n    Region& operationSelf(const Region& r, int op);\n    Region& operationSelf(const Region& r, int dx, int dy, int op);\n    const Region operation(const Rect& rhs, int op) const;\n    const Region operation(const Region& rhs, int op) const;\n    const Region operation(const Region& rhs, int dx, int dy, int op) const;\n\n    static void boolean_operation(int op, Region& dst,\n            const Region& lhs, const Region& rhs, int dx, int dy);\n    static void boolean_operation(int op, Region& dst,\n            const Region& lhs, const Rect& rhs, int dx, int dy);\n\n    static void boolean_operation(int op, Region& dst,\n            const Region& lhs, const Region& rhs);\n    static void boolean_operation(int op, Region& dst,\n            const Region& lhs, const Rect& rhs);\n\n    static void translate(Region& reg, int dx, int dy);\n    static void translate(Region& dst, const Region& reg, int dx, int dy);\n\n    static bool validate(const Region& reg,\n            const char* name, bool silent = false);\n\n    // mStorage is a (manually) sorted array of Rects describing the region\n    // with an extra Rect as the last element which is set to the\n    // bounds of the region. However, if the region is\n    // a simple Rect then mStorage contains only that rect.\n    Vector<Rect> mStorage;\n};\n\n\nconst Region Region::operator | (const Region& rhs) const {\n    return merge(rhs);\n}\nconst Region Region::operator ^ (const Region& rhs) const {\n    return mergeExclusive(rhs);\n}\nconst Region Region::operator & (const Region& rhs) const {\n    return intersect(rhs);\n}\nconst Region Region::operator - (const Region& rhs) const {\n    return subtract(rhs);\n}\nconst Region Region::operator + (const Point& pt) const {\n    return translate(pt.x, pt.y);\n}\n\n\nRegion& Region::operator |= (const Region& rhs) {\n    return orSelf(rhs);\n}\nRegion& Region::operator ^= (const Region& rhs) {\n    return xorSelf(rhs);\n}\nRegion& Region::operator &= (const Region& rhs) {\n    return andSelf(rhs);\n}\nRegion& Region::operator -= (const Region& rhs) {\n    return subtractSelf(rhs);\n}\nRegion& Region::operator += (const Point& pt) {\n    return translateSelf(pt.x, pt.y);\n}\n// ---------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_UI_REGION_H\n\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/TMatHelpers.h",
    "content": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef TMAT_IMPLEMENTATION\n#error \"Don't include TMatHelpers.h directly. use ui/mat*.h instead\"\n#else\n#undef TMAT_IMPLEMENTATION\n#endif\n\n\n#ifndef UI_TMAT_HELPERS_H\n#define UI_TMAT_HELPERS_H\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <math.h>\n#include <utils/Debug.h>\n#include <utils/String8.h>\n\n#define PURE __attribute__((pure))\n\nnamespace android {\n// -------------------------------------------------------------------------------------\n\n/*\n * No user serviceable parts here.\n *\n * Don't use this file directly, instead include ui/mat*.h\n */\n\n\n/*\n * Matrix utilities\n */\n\nnamespace matrix {\n\ninline int     PURE transpose(int v)    { return v; }\ninline float   PURE transpose(float v)  { return v; }\ninline double  PURE transpose(double v) { return v; }\n\ninline int     PURE trace(int v)    { return v; }\ninline float   PURE trace(float v)  { return v; }\ninline double  PURE trace(double v) { return v; }\n\ntemplate<typename MATRIX>\nMATRIX PURE inverse(const MATRIX& src) {\n\n    COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::COL_SIZE == MATRIX::ROW_SIZE );\n\n    typename MATRIX::value_type t;\n    const size_t N = MATRIX::col_size();\n    size_t swap;\n    MATRIX tmp(src);\n    MATRIX inverse(1);\n\n    for (size_t i=0 ; i<N ; i++) {\n        // look for largest element in column\n        swap = i;\n        for (size_t j=i+1 ; j<N ; j++) {\n            if (fabs(tmp[j][i]) > fabs(tmp[i][i])) {\n                swap = j;\n            }\n        }\n\n        if (swap != i) {\n            /* swap rows. */\n            for (size_t k=0 ; k<N ; k++) {\n                t = tmp[i][k];\n                tmp[i][k] = tmp[swap][k];\n                tmp[swap][k] = t;\n\n                t = inverse[i][k];\n                inverse[i][k] = inverse[swap][k];\n                inverse[swap][k] = t;\n            }\n        }\n\n        t = 1 / tmp[i][i];\n        for (size_t k=0 ; k<N ; k++) {\n            tmp[i][k] *= t;\n            inverse[i][k] *= t;\n        }\n        for (size_t j=0 ; j<N ; j++) {\n            if (j != i) {\n                t = tmp[j][i];\n                for (size_t k=0 ; k<N ; k++) {\n                    tmp[j][k] -= tmp[i][k] * t;\n                    inverse[j][k] -= inverse[i][k] * t;\n                }\n            }\n        }\n    }\n    return inverse;\n}\n\ntemplate<typename MATRIX_R, typename MATRIX_A, typename MATRIX_B>\nMATRIX_R PURE multiply(const MATRIX_A& lhs, const MATRIX_B& rhs) {\n    // pre-requisite:\n    //  lhs : D columns, R rows\n    //  rhs : C columns, D rows\n    //  res : C columns, R rows\n\n    COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_A::ROW_SIZE == MATRIX_B::COL_SIZE );\n    COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_R::ROW_SIZE == MATRIX_B::ROW_SIZE );\n    COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_R::COL_SIZE == MATRIX_A::COL_SIZE );\n\n    MATRIX_R res(MATRIX_R::NO_INIT);\n    for (size_t r=0 ; r<MATRIX_R::row_size() ; r++) {\n        res[r] = lhs * rhs[r];\n    }\n    return res;\n}\n\n// transpose. this handles matrices of matrices\ntemplate <typename MATRIX>\nMATRIX PURE transpose(const MATRIX& m) {\n    // for now we only handle square matrix transpose\n    COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );\n    MATRIX result(MATRIX::NO_INIT);\n    for (size_t r=0 ; r<MATRIX::row_size() ; r++)\n        for (size_t c=0 ; c<MATRIX::col_size() ; c++)\n            result[c][r] = transpose(m[r][c]);\n    return result;\n}\n\n// trace. this handles matrices of matrices\ntemplate <typename MATRIX>\ntypename MATRIX::value_type PURE trace(const MATRIX& m) {\n    COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );\n    typename MATRIX::value_type result(0);\n    for (size_t r=0 ; r<MATRIX::row_size() ; r++)\n        result += trace(m[r][r]);\n    return result;\n}\n\n// trace. this handles matrices of matrices\ntemplate <typename MATRIX>\ntypename MATRIX::col_type PURE diag(const MATRIX& m) {\n    COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );\n    typename MATRIX::col_type result(MATRIX::col_type::NO_INIT);\n    for (size_t r=0 ; r<MATRIX::row_size() ; r++)\n        result[r] = m[r][r];\n    return result;\n}\n\ntemplate <typename MATRIX>\nString8 asString(const MATRIX& m) {\n    String8 s;\n    for (size_t c=0 ; c<MATRIX::col_size() ; c++) {\n        s.append(\"|  \");\n        for (size_t r=0 ; r<MATRIX::row_size() ; r++) {\n            s.appendFormat(\"%7.2f  \", m[r][c]);\n        }\n        s.append(\"|\\n\");\n    }\n    return s;\n}\n\n}; // namespace matrix\n\n// -------------------------------------------------------------------------------------\n\n/*\n * TMatProductOperators implements basic arithmetic and basic compound assignments\n * operators on a vector of type BASE<T>.\n *\n * BASE only needs to implement operator[] and size().\n * By simply inheriting from TMatProductOperators<BASE, T> BASE will automatically\n * get all the functionality here.\n */\n\ntemplate <template<typename T> class BASE, typename T>\nclass TMatProductOperators {\npublic:\n    // multiply by a scalar\n    BASE<T>& operator *= (T v) {\n        BASE<T>& lhs(static_cast< BASE<T>& >(*this));\n        for (size_t r=0 ; r<lhs.row_size() ; r++) {\n            lhs[r] *= v;\n        }\n        return lhs;\n    }\n\n    // divide by a scalar\n    BASE<T>& operator /= (T v) {\n        BASE<T>& lhs(static_cast< BASE<T>& >(*this));\n        for (size_t r=0 ; r<lhs.row_size() ; r++) {\n            lhs[r] /= v;\n        }\n        return lhs;\n    }\n\n    // matrix * matrix, result is a matrix of the same type than the lhs matrix\n    template<typename U>\n    friend BASE<T> PURE operator *(const BASE<T>& lhs, const BASE<U>& rhs) {\n        return matrix::multiply<BASE<T> >(lhs, rhs);\n    }\n};\n\n\n/*\n * TMatSquareFunctions implements functions on a matrix of type BASE<T>.\n *\n * BASE only needs to implement:\n *  - operator[]\n *  - col_type\n *  - row_type\n *  - COL_SIZE\n *  - ROW_SIZE\n *\n * By simply inheriting from TMatSquareFunctions<BASE, T> BASE will automatically\n * get all the functionality here.\n */\n\ntemplate<template<typename U> class BASE, typename T>\nclass TMatSquareFunctions {\npublic:\n    /*\n     * NOTE: the functions below ARE NOT member methods. They are friend functions\n     * with they definition inlined with their declaration. This makes these\n     * template functions available to the compiler when (and only when) this class\n     * is instantiated, at which point they're only templated on the 2nd parameter\n     * (the first one, BASE<T> being known).\n     */\n    friend BASE<T> PURE inverse(const BASE<T>& m)   { return matrix::inverse(m); }\n    friend BASE<T> PURE transpose(const BASE<T>& m) { return matrix::transpose(m); }\n    friend T       PURE trace(const BASE<T>& m)     { return matrix::trace(m); }\n};\n\ntemplate <template<typename T> class BASE, typename T>\nclass TMatDebug {\npublic:\n    String8 asString() const {\n        return matrix::asString( static_cast< const BASE<T>& >(*this) );\n    }\n};\n\n// -------------------------------------------------------------------------------------\n}; // namespace android\n\n#undef PURE\n\n#endif /* UI_TMAT_HELPERS_H */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/TVecHelpers.h",
    "content": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef TVEC_IMPLEMENTATION\n#error \"Don't include TVecHelpers.h directly. use ui/vec*.h instead\"\n#else\n#undef TVEC_IMPLEMENTATION\n#endif\n\n\n#ifndef UI_TVEC_HELPERS_H\n#define UI_TVEC_HELPERS_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#define PURE __attribute__((pure))\n\nnamespace android {\n// -------------------------------------------------------------------------------------\n\n/*\n * No user serviceable parts here.\n *\n * Don't use this file directly, instead include ui/vec{2|3|4}.h\n */\n\n/*\n * This class casts itself into anything and assign itself from anything!\n * Use with caution!\n */\ntemplate <typename TYPE>\nstruct Impersonator {\n    Impersonator& operator = (const TYPE& rhs) {\n        reinterpret_cast<TYPE&>(*this) = rhs;\n        return *this;\n    }\n    operator TYPE& () {\n        return reinterpret_cast<TYPE&>(*this);\n    }\n    operator TYPE const& () const {\n        return reinterpret_cast<TYPE const&>(*this);\n    }\n};\n\n/*\n * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments\n * operators on a vector of type BASE<T>.\n *\n * BASE only needs to implement operator[] and size().\n * By simply inheriting from TVec{Add|Product}Operators<BASE, T> BASE will automatically\n * get all the functionality here.\n */\n\ntemplate <template<typename T> class BASE, typename T>\nclass TVecAddOperators {\npublic:\n    /* compound assignment from a another vector of the same size but different\n     * element type.\n     */\n    template <typename OTHER>\n    BASE<T>& operator += (const BASE<OTHER>& v) {\n        BASE<T>& rhs = static_cast<BASE<T>&>(*this);\n        for (size_t i=0 ; i<BASE<T>::size() ; i++) {\n            rhs[i] += v[i];\n        }\n        return rhs;\n    }\n    template <typename OTHER>\n    BASE<T>& operator -= (const BASE<OTHER>& v) {\n        BASE<T>& rhs = static_cast<BASE<T>&>(*this);\n        for (size_t i=0 ; i<BASE<T>::size() ; i++) {\n            rhs[i] -= v[i];\n        }\n        return rhs;\n    }\n\n    /* compound assignment from a another vector of the same type.\n     * These operators can be used for implicit conversion and  handle operations\n     * like \"vector *= scalar\" by letting the compiler implicitly convert a scalar\n     * to a vector (assuming the BASE<T> allows it).\n     */\n    BASE<T>& operator += (const BASE<T>& v) {\n        BASE<T>& rhs = static_cast<BASE<T>&>(*this);\n        for (size_t i=0 ; i<BASE<T>::size() ; i++) {\n            rhs[i] += v[i];\n        }\n        return rhs;\n    }\n    BASE<T>& operator -= (const BASE<T>& v) {\n        BASE<T>& rhs = static_cast<BASE<T>&>(*this);\n        for (size_t i=0 ; i<BASE<T>::size() ; i++) {\n            rhs[i] -= v[i];\n        }\n        return rhs;\n    }\n\n    /*\n     * NOTE: the functions below ARE NOT member methods. They are friend functions\n     * with they definition inlined with their declaration. This makes these\n     * template functions available to the compiler when (and only when) this class\n     * is instantiated, at which point they're only templated on the 2nd parameter\n     * (the first one, BASE<T> being known).\n     */\n\n    /* The operators below handle operation between vectors of the same side\n     * but of a different element type.\n     */\n    template<typename RT>\n    friend inline\n    BASE<T> PURE operator +(const BASE<T>& lv, const BASE<RT>& rv) {\n        return BASE<T>(lv) += rv;\n    }\n    template<typename RT>\n    friend inline\n    BASE<T> PURE operator -(const BASE<T>& lv, const BASE<RT>& rv) {\n        return BASE<T>(lv) -= rv;\n    }\n\n    /* The operators below (which are not templates once this class is instanced,\n     * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.\n     * These handle operations like \"vector * scalar\" and \"scalar * vector\" by\n     * letting the compiler implicitly convert a scalar to a vector (assuming\n     * the BASE<T> allows it).\n     */\n    friend inline\n    BASE<T> PURE operator +(const BASE<T>& lv, const BASE<T>& rv) {\n        return BASE<T>(lv) += rv;\n    }\n    friend inline\n    BASE<T> PURE operator -(const BASE<T>& lv, const BASE<T>& rv) {\n        return BASE<T>(lv) -= rv;\n    }\n};\n\ntemplate <template<typename T> class BASE, typename T>\nclass TVecProductOperators {\npublic:\n    /* compound assignment from a another vector of the same size but different\n     * element type.\n     */\n    template <typename OTHER>\n    BASE<T>& operator *= (const BASE<OTHER>& v) {\n        BASE<T>& rhs = static_cast<BASE<T>&>(*this);\n        for (size_t i=0 ; i<BASE<T>::size() ; i++) {\n            rhs[i] *= v[i];\n        }\n        return rhs;\n    }\n    template <typename OTHER>\n    BASE<T>& operator /= (const BASE<OTHER>& v) {\n        BASE<T>& rhs = static_cast<BASE<T>&>(*this);\n        for (size_t i=0 ; i<BASE<T>::size() ; i++) {\n            rhs[i] /= v[i];\n        }\n        return rhs;\n    }\n\n    /* compound assignment from a another vector of the same type.\n     * These operators can be used for implicit conversion and  handle operations\n     * like \"vector *= scalar\" by letting the compiler implicitly convert a scalar\n     * to a vector (assuming the BASE<T> allows it).\n     */\n    BASE<T>& operator *= (const BASE<T>& v) {\n        BASE<T>& rhs = static_cast<BASE<T>&>(*this);\n        for (size_t i=0 ; i<BASE<T>::size() ; i++) {\n            rhs[i] *= v[i];\n        }\n        return rhs;\n    }\n    BASE<T>& operator /= (const BASE<T>& v) {\n        BASE<T>& rhs = static_cast<BASE<T>&>(*this);\n        for (size_t i=0 ; i<BASE<T>::size() ; i++) {\n            rhs[i] /= v[i];\n        }\n        return rhs;\n    }\n\n    /*\n     * NOTE: the functions below ARE NOT member methods. They are friend functions\n     * with they definition inlined with their declaration. This makes these\n     * template functions available to the compiler when (and only when) this class\n     * is instantiated, at which point they're only templated on the 2nd parameter\n     * (the first one, BASE<T> being known).\n     */\n\n    /* The operators below handle operation between vectors of the same side\n     * but of a different element type.\n     */\n    template<typename RT>\n    friend inline\n    BASE<T> PURE operator *(const BASE<T>& lv, const BASE<RT>& rv) {\n        return BASE<T>(lv) *= rv;\n    }\n    template<typename RT>\n    friend inline\n    BASE<T> PURE operator /(const BASE<T>& lv, const BASE<RT>& rv) {\n        return BASE<T>(lv) /= rv;\n    }\n\n    /* The operators below (which are not templates once this class is instanced,\n     * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.\n     * These handle operations like \"vector * scalar\" and \"scalar * vector\" by\n     * letting the compiler implicitly convert a scalar to a vector (assuming\n     * the BASE<T> allows it).\n     */\n    friend inline\n    BASE<T> PURE operator *(const BASE<T>& lv, const BASE<T>& rv) {\n        return BASE<T>(lv) *= rv;\n    }\n    friend inline\n    BASE<T> PURE operator /(const BASE<T>& lv, const BASE<T>& rv) {\n        return BASE<T>(lv) /= rv;\n    }\n};\n\n/*\n * TVecUnaryOperators implements unary operators on a vector of type BASE<T>.\n *\n * BASE only needs to implement operator[] and size().\n * By simply inheriting from TVecUnaryOperators<BASE, T> BASE will automatically\n * get all the functionality here.\n *\n * These operators are implemented as friend functions of TVecUnaryOperators<BASE, T>\n */\ntemplate <template<typename T> class BASE, typename T>\nclass TVecUnaryOperators {\npublic:\n    BASE<T>& operator ++ () {\n        BASE<T>& rhs = static_cast<BASE<T>&>(*this);\n        for (size_t i=0 ; i<BASE<T>::size() ; i++) {\n            ++rhs[i];\n        }\n        return rhs;\n    }\n    BASE<T>& operator -- () {\n        BASE<T>& rhs = static_cast<BASE<T>&>(*this);\n        for (size_t i=0 ; i<BASE<T>::size() ; i++) {\n            --rhs[i];\n        }\n        return rhs;\n    }\n    BASE<T> operator - () const {\n        BASE<T> r(BASE<T>::NO_INIT);\n        BASE<T> const& rv(static_cast<BASE<T> const&>(*this));\n        for (size_t i=0 ; i<BASE<T>::size() ; i++) {\n            r[i] = -rv[i];\n        }\n        return r;\n    }\n};\n\n\n/*\n * TVecComparisonOperators implements relational/comparison operators\n * on a vector of type BASE<T>.\n *\n * BASE only needs to implement operator[] and size().\n * By simply inheriting from TVecComparisonOperators<BASE, T> BASE will automatically\n * get all the functionality here.\n */\ntemplate <template<typename T> class BASE, typename T>\nclass TVecComparisonOperators {\npublic:\n    /*\n     * NOTE: the functions below ARE NOT member methods. They are friend functions\n     * with they definition inlined with their declaration. This makes these\n     * template functions available to the compiler when (and only when) this class\n     * is instantiated, at which point they're only templated on the 2nd parameter\n     * (the first one, BASE<T> being known).\n     */\n    template<typename RT>\n    friend inline\n    bool PURE operator ==(const BASE<T>& lv, const BASE<RT>& rv) {\n        for (size_t i = 0; i < BASE<T>::size(); i++)\n            if (lv[i] != rv[i])\n                return false;\n        return true;\n    }\n\n    template<typename RT>\n    friend inline\n    bool PURE operator !=(const BASE<T>& lv, const BASE<RT>& rv) {\n        return !operator ==(lv, rv);\n    }\n\n    template<typename RT>\n    friend inline\n    bool PURE operator >(const BASE<T>& lv, const BASE<RT>& rv) {\n        for (size_t i = 0; i < BASE<T>::size(); i++)\n            if (lv[i] <= rv[i])\n                return false;\n        return true;\n    }\n\n    template<typename RT>\n    friend inline\n    bool PURE operator <=(const BASE<T>& lv, const BASE<RT>& rv) {\n        return !(lv > rv);\n    }\n\n    template<typename RT>\n    friend inline\n    bool PURE operator <(const BASE<T>& lv, const BASE<RT>& rv) {\n        for (size_t i = 0; i < BASE<T>::size(); i++)\n            if (lv[i] >= rv[i])\n                return false;\n        return true;\n    }\n\n    template<typename RT>\n    friend inline\n    bool PURE operator >=(const BASE<T>& lv, const BASE<RT>& rv) {\n        return !(lv < rv);\n    }\n};\n\n\n/*\n * TVecFunctions implements functions on a vector of type BASE<T>.\n *\n * BASE only needs to implement operator[] and size().\n * By simply inheriting from TVecFunctions<BASE, T> BASE will automatically\n * get all the functionality here.\n */\ntemplate <template<typename T> class BASE, typename T>\nclass TVecFunctions {\npublic:\n    /*\n     * NOTE: the functions below ARE NOT member methods. They are friend functions\n     * with they definition inlined with their declaration. This makes these\n     * template functions available to the compiler when (and only when) this class\n     * is instantiated, at which point they're only templated on the 2nd parameter\n     * (the first one, BASE<T> being known).\n     */\n    template<typename RT>\n    friend inline\n    T PURE dot(const BASE<T>& lv, const BASE<RT>& rv) {\n        T r(0);\n        for (size_t i = 0; i < BASE<T>::size(); i++)\n            r += lv[i]*rv[i];\n        return r;\n    }\n\n    friend inline\n    T PURE length(const BASE<T>& lv) {\n        return sqrt( dot(lv, lv) );\n    }\n\n    template<typename RT>\n    friend inline\n    T PURE distance(const BASE<T>& lv, const BASE<RT>& rv) {\n        return length(rv - lv);\n    }\n\n    friend inline\n    BASE<T> PURE normalize(const BASE<T>& lv) {\n        return lv * (1 / length(lv));\n    }\n};\n\n#undef PURE\n\n// -------------------------------------------------------------------------------------\n}; // namespace android\n\n\n#endif /* UI_TVEC_HELPERS_H */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/UiConfig.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UI_CONFIG_H\n#define ANDROID_UI_CONFIG_H\n\n#include <utils/String8.h>\n\nnamespace android {\n\n// Append the libui configuration details to configStr.\nvoid appendUiConfigString(String8& configStr);\n\n}; // namespace android\n\n#endif /*ANDROID_UI_CONFIG_H*/\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/mat4.h",
    "content": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef UI_MAT4_H\n#define UI_MAT4_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <ui/vec4.h>\n#include <utils/String8.h>\n\n#define TMAT_IMPLEMENTATION\n#include <ui/TMatHelpers.h>\n\n#define PURE __attribute__((pure))\n\nnamespace android {\n// -------------------------------------------------------------------------------------\n\ntemplate <typename T>\nclass tmat44 :  public TVecUnaryOperators<tmat44, T>,\n                public TVecComparisonOperators<tmat44, T>,\n                public TVecAddOperators<tmat44, T>,\n                public TMatProductOperators<tmat44, T>,\n                public TMatSquareFunctions<tmat44, T>,\n                public TMatDebug<tmat44, T>\n{\npublic:\n    enum no_init { NO_INIT };\n    typedef T value_type;\n    typedef T& reference;\n    typedef T const& const_reference;\n    typedef size_t size_type;\n    typedef tvec4<T> col_type;\n    typedef tvec4<T> row_type;\n\n    // size of a column (i.e.: number of rows)\n    enum { COL_SIZE = col_type::SIZE };\n    static inline size_t col_size() { return COL_SIZE; }\n\n    // size of a row (i.e.: number of columns)\n    enum { ROW_SIZE = row_type::SIZE };\n    static inline size_t row_size() { return ROW_SIZE; }\n    static inline size_t size()     { return row_size(); }  // for TVec*<>\n\nprivate:\n\n    /*\n     *  <--  N columns  -->\n     *\n     *  a00 a10 a20 ... aN0    ^\n     *  a01 a11 a21 ... aN1    |\n     *  a02 a12 a22 ... aN2  M rows\n     *  ...                    |\n     *  a0M a1M a2M ... aNM    v\n     *\n     *  COL_SIZE = M\n     *  ROW_SIZE = N\n     *  m[0] = [a00 a01 a02 ... a01M]\n     */\n\n    col_type mValue[ROW_SIZE];\n\npublic:\n    // array access\n    inline col_type const& operator [] (size_t i) const { return mValue[i]; }\n    inline col_type&       operator [] (size_t i)       { return mValue[i]; }\n\n    T const* asArray() const { return &mValue[0][0]; }\n\n    // -----------------------------------------------------------------------\n    // we don't provide copy-ctor and operator= on purpose\n    // because we want the compiler generated versions\n\n    /*\n     *  constructors\n     */\n\n    // leaves object uninitialized. use with caution.\n    explicit tmat44(no_init) { }\n\n    // initialize to identity\n    tmat44();\n\n    // initialize to Identity*scalar.\n    template<typename U>\n    explicit tmat44(U v);\n\n    // sets the diagonal to the passed vector\n    template <typename U>\n    explicit tmat44(const tvec4<U>& rhs);\n\n    // construct from another matrix of the same size\n    template <typename U>\n    explicit tmat44(const tmat44<U>& rhs);\n\n    // construct from 4 column vectors\n    template <typename A, typename B, typename C, typename D>\n    tmat44(const tvec4<A>& v0, const tvec4<B>& v1, const tvec4<C>& v2, const tvec4<D>& v3);\n\n    // construct from 16 scalars\n    template <\n        typename A, typename B, typename C, typename D,\n        typename E, typename F, typename G, typename H,\n        typename I, typename J, typename K, typename L,\n        typename M, typename N, typename O, typename P>\n    tmat44( A m00, B m01, C m02, D m03,\n            E m10, F m11, G m12, H m13,\n            I m20, J m21, K m22, L m23,\n            M m30, N m31, O m32, P m33);\n\n    // construct from a C array\n    template <typename U>\n    explicit tmat44(U const* rawArray);\n\n    /*\n     *  helpers\n     */\n\n    static tmat44 ortho(T left, T right, T bottom, T top, T near, T far);\n\n    static tmat44 frustum(T left, T right, T bottom, T top, T near, T far);\n\n    template <typename A, typename B, typename C>\n    static tmat44 lookAt(const tvec3<A>& eye, const tvec3<B>& center, const tvec3<C>& up);\n\n    template <typename A>\n    static tmat44 translate(const tvec4<A>& t);\n\n    template <typename A>\n    static tmat44 scale(const tvec4<A>& s);\n\n    template <typename A, typename B>\n    static tmat44 rotate(A radian, const tvec3<B>& about);\n};\n\n// ----------------------------------------------------------------------------------------\n// Constructors\n// ----------------------------------------------------------------------------------------\n\n/*\n * Since the matrix code could become pretty big quickly, we don't inline most\n * operations.\n */\n\ntemplate <typename T>\ntmat44<T>::tmat44() {\n    mValue[0] = col_type(1,0,0,0);\n    mValue[1] = col_type(0,1,0,0);\n    mValue[2] = col_type(0,0,1,0);\n    mValue[3] = col_type(0,0,0,1);\n}\n\ntemplate <typename T>\ntemplate <typename U>\ntmat44<T>::tmat44(U v) {\n    mValue[0] = col_type(v,0,0,0);\n    mValue[1] = col_type(0,v,0,0);\n    mValue[2] = col_type(0,0,v,0);\n    mValue[3] = col_type(0,0,0,v);\n}\n\ntemplate<typename T>\ntemplate<typename U>\ntmat44<T>::tmat44(const tvec4<U>& v) {\n    mValue[0] = col_type(v.x,0,0,0);\n    mValue[1] = col_type(0,v.y,0,0);\n    mValue[2] = col_type(0,0,v.z,0);\n    mValue[3] = col_type(0,0,0,v.w);\n}\n\n// construct from 16 scalars\ntemplate<typename T>\ntemplate <\n    typename A, typename B, typename C, typename D,\n    typename E, typename F, typename G, typename H,\n    typename I, typename J, typename K, typename L,\n    typename M, typename N, typename O, typename P>\ntmat44<T>::tmat44(  A m00, B m01, C m02, D m03,\n                    E m10, F m11, G m12, H m13,\n                    I m20, J m21, K m22, L m23,\n                    M m30, N m31, O m32, P m33) {\n    mValue[0] = col_type(m00, m01, m02, m03);\n    mValue[1] = col_type(m10, m11, m12, m13);\n    mValue[2] = col_type(m20, m21, m22, m23);\n    mValue[3] = col_type(m30, m31, m32, m33);\n}\n\ntemplate <typename T>\ntemplate <typename U>\ntmat44<T>::tmat44(const tmat44<U>& rhs) {\n    for (size_t r=0 ; r<row_size() ; r++)\n        mValue[r] = rhs[r];\n}\n\ntemplate <typename T>\ntemplate <typename A, typename B, typename C, typename D>\ntmat44<T>::tmat44(const tvec4<A>& v0, const tvec4<B>& v1, const tvec4<C>& v2, const tvec4<D>& v3) {\n    mValue[0] = v0;\n    mValue[1] = v1;\n    mValue[2] = v2;\n    mValue[3] = v3;\n}\n\ntemplate <typename T>\ntemplate <typename U>\ntmat44<T>::tmat44(U const* rawArray) {\n    for (size_t r=0 ; r<row_size() ; r++)\n        for (size_t c=0 ; c<col_size() ; c++)\n            mValue[r][c] = *rawArray++;\n}\n\n// ----------------------------------------------------------------------------------------\n// Helpers\n// ----------------------------------------------------------------------------------------\n\ntemplate <typename T>\ntmat44<T> tmat44<T>::ortho(T left, T right, T bottom, T top, T near, T far) {\n    tmat44<T> m;\n    m[0][0] =  2 / (right - left);\n    m[1][1] =  2 / (top   - bottom);\n    m[2][2] = -2 / (far   - near);\n    m[3][0] = -(right + left)   / (right - left);\n    m[3][1] = -(top   + bottom) / (top   - bottom);\n    m[3][2] = -(far   + near)   / (far   - near);\n    return m;\n}\n\ntemplate <typename T>\ntmat44<T> tmat44<T>::frustum(T left, T right, T bottom, T top, T near, T far) {\n    tmat44<T> m;\n    T A = (right + left)   / (right - left);\n    T B = (top   + bottom) / (top   - bottom);\n    T C = (far   + near)   / (far   - near);\n    T D = (2 * far * near) / (far   - near);\n    m[0][0] = (2 * near) / (right - left);\n    m[1][1] = (2 * near) / (top   - bottom);\n    m[2][0] = A;\n    m[2][1] = B;\n    m[2][2] = C;\n    m[2][3] =-1;\n    m[3][2] = D;\n    m[3][3] = 0;\n    return m;\n}\n\ntemplate <typename T>\ntemplate <typename A, typename B, typename C>\ntmat44<T> tmat44<T>::lookAt(const tvec3<A>& eye, const tvec3<B>& center, const tvec3<C>& up) {\n    tvec3<T> L(normalize(center - eye));\n    tvec3<T> S(normalize( cross(L, up) ));\n    tvec3<T> U(cross(S, L));\n    return tmat44<T>(\n            tvec4<T>( S, 0),\n            tvec4<T>( U, 0),\n            tvec4<T>(-L, 0),\n            tvec4<T>(-eye, 1));\n}\n\ntemplate <typename T>\ntemplate <typename A>\ntmat44<T> tmat44<T>::translate(const tvec4<A>& t) {\n    tmat44<T> r;\n    r[3] = t;\n    return r;\n}\n\ntemplate <typename T>\ntemplate <typename A>\ntmat44<T> tmat44<T>::scale(const tvec4<A>& s) {\n    tmat44<T> r;\n    r[0][0] = s[0];\n    r[1][1] = s[1];\n    r[2][2] = s[2];\n    r[3][3] = s[3];\n    return r;\n}\n\ntemplate <typename T>\ntemplate <typename A, typename B>\ntmat44<T> tmat44<T>::rotate(A radian, const tvec3<B>& about) {\n    tmat44<T> rotation;\n    T* r = const_cast<T*>(rotation.asArray());\n    T c = cos(radian);\n    T s = sin(radian);\n    if (about.x==1 && about.y==0 && about.z==0) {\n        r[5] = c;   r[10]= c;\n        r[6] = s;   r[9] = -s;\n    } else if (about.x==0 && about.y==1 && about.z==0) {\n        r[0] = c;   r[10]= c;\n        r[8] = s;   r[2] = -s;\n    } else if (about.x==0 && about.y==0 && about.z==1) {\n        r[0] = c;   r[5] = c;\n        r[1] = s;   r[4] = -s;\n    } else {\n        tvec3<B> nabout = normalize(about);\n        B x = nabout.x;\n        B y = nabout.y;\n        B z = nabout.z;\n        T nc = 1 - c;\n        T xy = x * y;\n        T yz = y * z;\n        T zx = z * x;\n        T xs = x * s;\n        T ys = y * s;\n        T zs = z * s;\n        r[ 0] = x*x*nc +  c;    r[ 4] =  xy*nc - zs;    r[ 8] =  zx*nc + ys;\n        r[ 1] =  xy*nc + zs;    r[ 5] = y*y*nc +  c;    r[ 9] =  yz*nc - xs;\n        r[ 2] =  zx*nc - ys;    r[ 6] =  yz*nc + xs;    r[10] = z*z*nc +  c;\n    }\n    return rotation;\n}\n\n// ----------------------------------------------------------------------------------------\n// Arithmetic operators outside of class\n// ----------------------------------------------------------------------------------------\n\n/* We use non-friend functions here to prevent the compiler from using\n * implicit conversions, for instance of a scalar to a vector. The result would\n * not be what the caller expects.\n *\n * Also note that the order of the arguments in the inner loop is important since\n * it determines the output type (only relevant when T != U).\n */\n\n// matrix * vector, result is a vector of the same type than the input vector\ntemplate <typename T, typename U>\ntypename tmat44<U>::col_type PURE operator *(const tmat44<T>& lv, const tvec4<U>& rv) {\n    typename tmat44<U>::col_type result;\n    for (size_t r=0 ; r<tmat44<T>::row_size() ; r++)\n        result += rv[r]*lv[r];\n    return result;\n}\n\n// vector * matrix, result is a vector of the same type than the input vector\ntemplate <typename T, typename U>\ntypename tmat44<U>::row_type PURE operator *(const tvec4<U>& rv, const tmat44<T>& lv) {\n    typename tmat44<U>::row_type result(tmat44<U>::row_type::NO_INIT);\n    for (size_t r=0 ; r<tmat44<T>::row_size() ; r++)\n        result[r] = dot(rv, lv[r]);\n    return result;\n}\n\n// matrix * scalar, result is a matrix of the same type than the input matrix\ntemplate <typename T, typename U>\ntmat44<T> PURE operator *(const tmat44<T>& lv, U rv) {\n    tmat44<T> result(tmat44<T>::NO_INIT);\n    for (size_t r=0 ; r<tmat44<T>::row_size() ; r++)\n        result[r] = lv[r]*rv;\n    return result;\n}\n\n// scalar * matrix, result is a matrix of the same type than the input matrix\ntemplate <typename T, typename U>\ntmat44<T> PURE operator *(U rv, const tmat44<T>& lv) {\n    tmat44<T> result(tmat44<T>::NO_INIT);\n    for (size_t r=0 ; r<tmat44<T>::row_size() ; r++)\n        result[r] = lv[r]*rv;\n    return result;\n}\n\n// ----------------------------------------------------------------------------------------\n\n/* FIXME: this should go into TMatSquareFunctions<> but for some reason\n * BASE<T>::col_type is not accessible from there (???)\n */\ntemplate<typename T>\ntypename tmat44<T>::col_type PURE diag(const tmat44<T>& m) {\n    return matrix::diag(m);\n}\n\n// ----------------------------------------------------------------------------------------\n\ntypedef tmat44<float> mat4;\n\n// ----------------------------------------------------------------------------------------\n}; // namespace android\n\n#undef PURE\n\n#endif /* UI_MAT4_H */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/vec2.h",
    "content": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef UI_VEC2_H\n#define UI_VEC2_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#define TVEC_IMPLEMENTATION\n#include <ui/TVecHelpers.h>\n\nnamespace android {\n// -------------------------------------------------------------------------------------\n\ntemplate <typename T>\nclass tvec2 :   public TVecProductOperators<tvec2, T>,\n                public TVecAddOperators<tvec2, T>,\n                public TVecUnaryOperators<tvec2, T>,\n                public TVecComparisonOperators<tvec2, T>,\n                public TVecFunctions<tvec2, T>\n{\npublic:\n    enum no_init { NO_INIT };\n    typedef T value_type;\n    typedef T& reference;\n    typedef T const& const_reference;\n    typedef size_t size_type;\n\n    union {\n        struct { T x, y; };\n        struct { T s, t; };\n        struct { T r, g; };\n    };\n\n    enum { SIZE = 2 };\n    inline static size_type size() { return SIZE; }\n\n    // array access\n    inline T const& operator [] (size_t i) const { return (&x)[i]; }\n    inline T&       operator [] (size_t i)       { return (&x)[i]; }\n\n    // -----------------------------------------------------------------------\n    // we don't provide copy-ctor and operator= on purpose\n    // because we want the compiler generated versions\n\n    // constructors\n\n    // leaves object uninitialized. use with caution.\n    explicit tvec2(no_init) { }\n\n    // default constructor\n    tvec2() : x(0), y(0) { }\n\n    // handles implicit conversion to a tvec4. must not be explicit.\n    template<typename A>\n    tvec2(A v) : x(v), y(v) { }\n\n    template<typename A, typename B>\n    tvec2(A x, B y) : x(x), y(y) { }\n\n    template<typename A>\n    explicit tvec2(const tvec2<A>& v) : x(v.x), y(v.y) { }\n\n    template<typename A>\n    tvec2(const Impersonator< tvec2<A> >& v)\n        : x(((const tvec2<A>&)v).x),\n          y(((const tvec2<A>&)v).y) { }\n};\n\n// ----------------------------------------------------------------------------------------\n\ntypedef tvec2<float> vec2;\n\n// ----------------------------------------------------------------------------------------\n}; // namespace android\n\n#endif /* UI_VEC4_H */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/vec3.h",
    "content": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef UI_VEC3_H\n#define UI_VEC3_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <ui/vec2.h>\n\nnamespace android {\n// -------------------------------------------------------------------------------------\n\ntemplate <typename T>\nclass tvec3 :   public TVecProductOperators<tvec3, T>,\n                public TVecAddOperators<tvec3, T>,\n                public TVecUnaryOperators<tvec3, T>,\n                public TVecComparisonOperators<tvec3, T>,\n                public TVecFunctions<tvec3, T>\n{\npublic:\n    enum no_init { NO_INIT };\n    typedef T value_type;\n    typedef T& reference;\n    typedef T const& const_reference;\n    typedef size_t size_type;\n\n    union {\n        struct { T x, y, z; };\n        struct { T s, t, p; };\n        struct { T r, g, b; };\n        Impersonator< tvec2<T> > xy;\n        Impersonator< tvec2<T> > st;\n        Impersonator< tvec2<T> > rg;\n    };\n\n    enum { SIZE = 3 };\n    inline static size_type size() { return SIZE; }\n\n    // array access\n    inline T const& operator [] (size_t i) const { return (&x)[i]; }\n    inline T&       operator [] (size_t i)       { return (&x)[i]; }\n\n    // -----------------------------------------------------------------------\n    // we don't provide copy-ctor and operator= on purpose\n    // because we want the compiler generated versions\n\n    // constructors\n    // leaves object uninitialized. use with caution.\n    explicit tvec3(no_init) { }\n\n    // default constructor\n    tvec3() : x(0), y(0), z(0) { }\n\n    // handles implicit conversion to a tvec4. must not be explicit.\n    template<typename A>\n    tvec3(A v) : x(v), y(v), z(v) { }\n\n    template<typename A, typename B, typename C>\n    tvec3(A x, B y, C z) : x(x), y(y), z(z) { }\n\n    template<typename A, typename B>\n    tvec3(const tvec2<A>& v, B z) : x(v.x), y(v.y), z(z) { }\n\n    template<typename A>\n    explicit tvec3(const tvec3<A>& v) : x(v.x), y(v.y), z(v.z) { }\n\n    template<typename A>\n    tvec3(const Impersonator< tvec3<A> >& v)\n        : x(((const tvec3<A>&)v).x),\n          y(((const tvec3<A>&)v).y),\n          z(((const tvec3<A>&)v).z) { }\n\n    template<typename A, typename B>\n    tvec3(const Impersonator< tvec2<A> >& v, B z)\n        : x(((const tvec2<A>&)v).x),\n          y(((const tvec2<A>&)v).y),\n          z(z) { }\n\n    // cross product works only on vectors of size 3\n    template <typename RT>\n    friend inline\n    tvec3 __attribute__((pure)) cross(const tvec3& u, const tvec3<RT>& v) {\n        return tvec3(\n                u.y*v.z - u.z*v.y,\n                u.z*v.x - u.x*v.z,\n                u.x*v.y - u.y*v.x);\n    }\n};\n\n\n// ----------------------------------------------------------------------------------------\n\ntypedef tvec3<float> vec3;\n\n// ----------------------------------------------------------------------------------------\n}; // namespace android\n\n#endif /* UI_VEC4_H */\n"
  },
  {
    "path": "atlas-aapt/frameworks/native/include/ui/vec4.h",
    "content": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef UI_VEC4_H\n#define UI_VEC4_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <ui/vec3.h>\n\nnamespace android {\n// -------------------------------------------------------------------------------------\n\ntemplate <typename T>\nclass tvec4 :   public TVecProductOperators<tvec4, T>,\n                public TVecAddOperators<tvec4, T>,\n                public TVecUnaryOperators<tvec4, T>,\n                public TVecComparisonOperators<tvec4, T>,\n                public TVecFunctions<tvec4, T>\n{\npublic:\n    enum no_init { NO_INIT };\n    typedef T value_type;\n    typedef T& reference;\n    typedef T const& const_reference;\n    typedef size_t size_type;\n\n    union {\n        struct { T x, y, z, w; };\n        struct { T s, t, p, q; };\n        struct { T r, g, b, a; };\n        Impersonator< tvec2<T> > xy;\n        Impersonator< tvec2<T> > st;\n        Impersonator< tvec2<T> > rg;\n        Impersonator< tvec3<T> > xyz;\n        Impersonator< tvec3<T> > stp;\n        Impersonator< tvec3<T> > rgb;\n    };\n\n    enum { SIZE = 4 };\n    inline static size_type size() { return SIZE; }\n\n    // array access\n    inline T const& operator [] (size_t i) const { return (&x)[i]; }\n    inline T&       operator [] (size_t i)       { return (&x)[i]; }\n\n    // -----------------------------------------------------------------------\n    // we don't provide copy-ctor and operator= on purpose\n    // because we want the compiler generated versions\n\n    // constructors\n\n    // leaves object uninitialized. use with caution.\n    explicit tvec4(no_init) { }\n\n    // default constructor\n    tvec4() : x(0), y(0), z(0), w(0) { }\n\n    // handles implicit conversion to a tvec4. must not be explicit.\n    template<typename A>\n    tvec4(A v) : x(v), y(v), z(v), w(v) { }\n\n    template<typename A, typename B, typename C, typename D>\n    tvec4(A x, B y, C z, D w) : x(x), y(y), z(z), w(w) { }\n\n    template<typename A, typename B, typename C>\n    tvec4(const tvec2<A>& v, B z, C w) : x(v.x), y(v.y), z(z), w(w) { }\n\n    template<typename A, typename B>\n    tvec4(const tvec3<A>& v, B w) : x(v.x), y(v.y), z(v.z), w(w) { }\n\n    template<typename A>\n    explicit tvec4(const tvec4<A>& v) : x(v.x), y(v.y), z(v.z), w(v.w) { }\n\n    template<typename A>\n    tvec4(const Impersonator< tvec4<A> >& v)\n        : x(((const tvec4<A>&)v).x),\n          y(((const tvec4<A>&)v).y),\n          z(((const tvec4<A>&)v).z),\n          w(((const tvec4<A>&)v).w) { }\n\n    template<typename A, typename B>\n    tvec4(const Impersonator< tvec3<A> >& v, B w)\n        : x(((const tvec3<A>&)v).x),\n          y(((const tvec3<A>&)v).y),\n          z(((const tvec3<A>&)v).z),\n          w(w) { }\n\n    template<typename A, typename B, typename C>\n    tvec4(const Impersonator< tvec2<A> >& v, B z, C w)\n        : x(((const tvec2<A>&)v).x),\n          y(((const tvec2<A>&)v).y),\n          z(z),\n          w(w) { }\n};\n\n// ----------------------------------------------------------------------------------------\n\ntypedef tvec4<float> vec4;\n\n// ----------------------------------------------------------------------------------------\n}; // namespace android\n\n#endif /* UI_VEC4_H */\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/ALog-priv.h",
    "content": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef NATIVEHELPER_ALOGPRIV_H_\n#define NATIVEHELPER_ALOGPRIV_H_\n\n#include <android/log.h>\n\n#ifndef LOG_NDEBUG\n#ifdef NDEBUG\n#define LOG_NDEBUG 1\n#else\n#define LOG_NDEBUG 0\n#endif\n#endif\n\n\n/*\n * Basic log message macros intended to emulate the behavior of log/log.h\n * in system core.  This should be dependent only on ndk exposed logging\n * functionality.\n */\n\n#ifndef ALOG\n#define ALOG(priority, tag, fmt...) \\\n    __android_log_print(ANDROID_##priority, tag, fmt)\n#endif\n\n#ifndef ALOGV\n#if LOG_NDEBUG\n#define ALOGV(...)   ((void)0)\n#else\n#define ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))\n#endif\n#endif\n\n#ifndef ALOGD\n#define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef ALOGI\n#define ALOGI(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef ALOGW\n#define ALOGW(...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef ALOGE\n#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__))\n#endif\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/Android.mk",
    "content": "# Copyright (C) 2009 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\nLOCAL_PATH := $(call my-dir)\n\nlocal_src_files := \\\n    JNIHelp.cpp \\\n    JniConstants.cpp \\\n    toStringArray.cpp\n\n#\n# Build for the target (device).\n#\n\ninclude $(CLEAR_VARS)\nLOCAL_SRC_FILES := \\\n    $(local_src_files) \\\n    JniInvocation.cpp \\\n    AsynchronousCloseMonitor.cpp\n\nLOCAL_SHARED_LIBRARIES := liblog\nLOCAL_MODULE_TAGS := optional\nLOCAL_MODULE := libnativehelper\nLOCAL_CLANG := true\nLOCAL_CFLAGS := -Werror -fvisibility=protected\nLOCAL_C_INCLUDES := libcore/include\nLOCAL_SHARED_LIBRARIES += libdl\nLOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk\ninclude $(BUILD_SHARED_LIBRARY)\n\n\n#\n# NDK-only build for the target (device), using libc++.\n# - Relies only on NDK exposed functionality.\n# - This doesn't include JniInvocation.\n#\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE_TAGS := optional\nLOCAL_MODULE := libnativehelper_compat_libc++\nLOCAL_CLANG := true\nLOCAL_C_INCLUDES := \\\n    $(LOCAL_PATH)/include/nativehelper\nLOCAL_EXPORT_C_INCLUDE_DIRS := \\\n    $(LOCAL_PATH)/include/nativehelper\nLOCAL_CFLAGS := -Werror\nLOCAL_SRC_FILES := $(local_src_files)\nLOCAL_LDFLAGS := -llog -ldl\nLOCAL_SDK_VERSION := 19\nLOCAL_NDK_STL_VARIANT := c++_static\nLOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk\ninclude $(BUILD_SHARED_LIBRARY)\n\n\n#\n# Build for the host.\n#\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libnativehelper\nLOCAL_MODULE_TAGS := optional\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := \\\n    $(local_src_files) \\\n    JniInvocation.cpp\nifeq ($(HOST_OS),linux)\nLOCAL_SRC_FILES += AsynchronousCloseMonitor.cpp\nendif\nLOCAL_CFLAGS := -Werror -fvisibility=protected\nLOCAL_C_INCLUDES := libcore/include\nLOCAL_SHARED_LIBRARIES := liblog\nLOCAL_LDFLAGS := -ldl\nLOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk\nLOCAL_MULTILIB := both\ninclude $(BUILD_HOST_SHARED_LIBRARY)\n\n\n#\n# Build static for the host.\n#\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libnativehelper\nLOCAL_MODULE_TAGS := optional\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := \\\n    $(local_src_files) \\\n    JniInvocation.cpp\nifeq ($(HOST_OS),linux)\nLOCAL_SRC_FILES += AsynchronousCloseMonitor.cpp\nendif\nLOCAL_CFLAGS := -Werror -fvisibility=protected\nLOCAL_C_INCLUDES := libcore/include\nLOCAL_STATIC_LIBRARIES := liblog\nLOCAL_LDFLAGS := -ldl\nLOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk\nLOCAL_MULTILIB := both\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\n\n#\n# Tests.\n#\n\ninclude $(LOCAL_PATH)/tests/Android.mk\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/AsynchronousCloseMonitor.cpp",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"AsynchronousCloseMonitor\"\n\n#include \"AsynchronousCloseMonitor.h\"\n#include \"cutils/log.h\"\n\n#include <errno.h>\n#include <signal.h>\n#include <string.h>\n\n/**\n * We use an intrusive doubly-linked list to keep track of blocked threads.\n * This gives us O(1) insertion and removal, and means we don't need to do any allocation.\n * (The objects themselves are stack-allocated.)\n * Waking potentially-blocked threads when a file descriptor is closed is O(n) in the total number\n * of blocked threads (not the number of threads actually blocked on the file descriptor in\n * question). For now at least, this seems like a good compromise for Android.\n */\nstatic pthread_mutex_t blockedThreadListMutex = PTHREAD_MUTEX_INITIALIZER;\nstatic AsynchronousCloseMonitor* blockedThreadList = NULL;\n\n/**\n * The specific signal chosen here is arbitrary, but bionic needs to know so that SIGRTMIN\n * starts at a higher value.\n */\nstatic const int BLOCKED_THREAD_SIGNAL = __SIGRTMIN + 2;\n\nstatic void blockedThreadSignalHandler(int /*signal*/) {\n    // Do nothing. We only sent this signal for its side-effect of interrupting syscalls.\n}\n\nvoid AsynchronousCloseMonitor::init() {\n    // Ensure that the signal we send interrupts system calls but doesn't kill threads.\n    // Using sigaction(2) lets us ensure that the SA_RESTART flag is not set.\n    // (The whole reason we're sending this signal is to unblock system calls!)\n    struct sigaction sa;\n    memset(&sa, 0, sizeof(sa));\n    sa.sa_handler = blockedThreadSignalHandler;\n    sa.sa_flags = 0;\n    int rc = sigaction(BLOCKED_THREAD_SIGNAL, &sa, NULL);\n    if (rc == -1) {\n        ALOGE(\"setting blocked thread signal handler failed: %s\", strerror(errno));\n    }\n}\n\nvoid AsynchronousCloseMonitor::signalBlockedThreads(int fd) {\n    ScopedPthreadMutexLock lock(&blockedThreadListMutex);\n    for (AsynchronousCloseMonitor* it = blockedThreadList; it != NULL; it = it->mNext) {\n        if (it->mFd == fd) {\n            it->mSignaled = true;\n            pthread_kill(it->mThread, BLOCKED_THREAD_SIGNAL);\n            // Keep going, because there may be more than one thread...\n        }\n    }\n}\n\nbool AsynchronousCloseMonitor::wasSignaled() const {\n    return mSignaled;\n}\n\nAsynchronousCloseMonitor::AsynchronousCloseMonitor(int fd) {\n    ScopedPthreadMutexLock lock(&blockedThreadListMutex);\n    // Who are we, and what are we waiting for?\n    mThread = pthread_self();\n    mFd = fd;\n    mSignaled = false;\n    // Insert ourselves at the head of the intrusive doubly-linked list...\n    mPrev = NULL;\n    mNext = blockedThreadList;\n    if (mNext != NULL) {\n        mNext->mPrev = this;\n    }\n    blockedThreadList = this;\n}\n\nAsynchronousCloseMonitor::~AsynchronousCloseMonitor() {\n    ScopedPthreadMutexLock lock(&blockedThreadListMutex);\n    // Unlink ourselves from the intrusive doubly-linked list...\n    if (mNext != NULL) {\n        mNext->mPrev = mPrev;\n    }\n    if (mPrev == NULL) {\n        blockedThreadList = mNext;\n    } else {\n        mPrev->mNext = mNext;\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/JNIHelp.cpp",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#if defined(__ANDROID__)\n/* libnativehelper is built by NDK 19 in one variant, which doesn't yet have the GNU strerror_r. */\n#undef _GNU_SOURCE\n#endif\n\n#define LOG_TAG \"JNIHelp\"\n\n#include \"JniConstants.h\"\n#include \"JNIHelp.h\"\n#include \"ALog-priv.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n\n#include <string>\n\n/**\n * Equivalent to ScopedLocalRef, but for C_JNIEnv instead. (And slightly more powerful.)\n */\ntemplate<typename T>\nclass scoped_local_ref {\npublic:\n    scoped_local_ref(C_JNIEnv* env, T localRef = NULL)\n    : mEnv(env), mLocalRef(localRef)\n    {\n    }\n\n    ~scoped_local_ref() {\n        reset();\n    }\n\n    void reset(T localRef = NULL) {\n        if (mLocalRef != NULL) {\n            (*mEnv)->DeleteLocalRef(reinterpret_cast<JNIEnv*>(mEnv), mLocalRef);\n            mLocalRef = localRef;\n        }\n    }\n\n    T get() const {\n        return mLocalRef;\n    }\n\nprivate:\n    C_JNIEnv* const mEnv;\n    T mLocalRef;\n\n    DISALLOW_COPY_AND_ASSIGN(scoped_local_ref);\n};\n\nstatic jclass findClass(C_JNIEnv* env, const char* className) {\n    JNIEnv* e = reinterpret_cast<JNIEnv*>(env);\n    return (*env)->FindClass(e, className);\n}\n\nextern \"C\" int jniRegisterNativeMethods(C_JNIEnv* env, const char* className,\n    const JNINativeMethod* gMethods, int numMethods)\n{\n    JNIEnv* e = reinterpret_cast<JNIEnv*>(env);\n\n    ALOGV(\"Registering %s's %d native methods...\", className, numMethods);\n\n    scoped_local_ref<jclass> c(env, findClass(env, className));\n    if (c.get() == NULL) {\n        char* tmp;\n        const char* msg;\n        if (asprintf(&tmp,\n                     \"Native registration unable to find class '%s'; aborting...\",\n                     className) == -1) {\n            // Allocation failed, print default warning.\n            msg = \"Native registration unable to find class; aborting...\";\n        } else {\n            msg = tmp;\n        }\n        e->FatalError(msg);\n    }\n\n    if ((*env)->RegisterNatives(e, c.get(), gMethods, numMethods) < 0) {\n        char* tmp;\n        const char* msg;\n        if (asprintf(&tmp, \"RegisterNatives failed for '%s'; aborting...\", className) == -1) {\n            // Allocation failed, print default warning.\n            msg = \"RegisterNatives failed; aborting...\";\n        } else {\n            msg = tmp;\n        }\n        e->FatalError(msg);\n    }\n\n    return 0;\n}\n\n/*\n * Returns a human-readable summary of an exception object.  The buffer will\n * be populated with the \"binary\" class name and, if present, the\n * exception message.\n */\nstatic bool getExceptionSummary(C_JNIEnv* env, jthrowable exception, std::string& result) {\n    JNIEnv* e = reinterpret_cast<JNIEnv*>(env);\n\n    /* get the name of the exception's class */\n    scoped_local_ref<jclass> exceptionClass(env, (*env)->GetObjectClass(e, exception)); // can't fail\n    scoped_local_ref<jclass> classClass(env,\n            (*env)->GetObjectClass(e, exceptionClass.get())); // java.lang.Class, can't fail\n    jmethodID classGetNameMethod =\n            (*env)->GetMethodID(e, classClass.get(), \"getName\", \"()Ljava/lang/String;\");\n    scoped_local_ref<jstring> classNameStr(env,\n            (jstring) (*env)->CallObjectMethod(e, exceptionClass.get(), classGetNameMethod));\n    if (classNameStr.get() == NULL) {\n        (*env)->ExceptionClear(e);\n        result = \"<error getting class name>\";\n        return false;\n    }\n    const char* classNameChars = (*env)->GetStringUTFChars(e, classNameStr.get(), NULL);\n    if (classNameChars == NULL) {\n        (*env)->ExceptionClear(e);\n        result = \"<error getting class name UTF-8>\";\n        return false;\n    }\n    result += classNameChars;\n    (*env)->ReleaseStringUTFChars(e, classNameStr.get(), classNameChars);\n\n    /* if the exception has a detail message, get that */\n    jmethodID getMessage =\n            (*env)->GetMethodID(e, exceptionClass.get(), \"getMessage\", \"()Ljava/lang/String;\");\n    scoped_local_ref<jstring> messageStr(env,\n            (jstring) (*env)->CallObjectMethod(e, exception, getMessage));\n    if (messageStr.get() == NULL) {\n        return true;\n    }\n\n    result += \": \";\n\n    const char* messageChars = (*env)->GetStringUTFChars(e, messageStr.get(), NULL);\n    if (messageChars != NULL) {\n        result += messageChars;\n        (*env)->ReleaseStringUTFChars(e, messageStr.get(), messageChars);\n    } else {\n        result += \"<error getting message>\";\n        (*env)->ExceptionClear(e); // clear OOM\n    }\n\n    return true;\n}\n\n/*\n * Returns an exception (with stack trace) as a string.\n */\nstatic bool getStackTrace(C_JNIEnv* env, jthrowable exception, std::string& result) {\n    JNIEnv* e = reinterpret_cast<JNIEnv*>(env);\n\n    scoped_local_ref<jclass> stringWriterClass(env, findClass(env, \"java/io/StringWriter\"));\n    if (stringWriterClass.get() == NULL) {\n        return false;\n    }\n\n    jmethodID stringWriterCtor = (*env)->GetMethodID(e, stringWriterClass.get(), \"<init>\", \"()V\");\n    jmethodID stringWriterToStringMethod =\n            (*env)->GetMethodID(e, stringWriterClass.get(), \"toString\", \"()Ljava/lang/String;\");\n\n    scoped_local_ref<jclass> printWriterClass(env, findClass(env, \"java/io/PrintWriter\"));\n    if (printWriterClass.get() == NULL) {\n        return false;\n    }\n\n    jmethodID printWriterCtor =\n            (*env)->GetMethodID(e, printWriterClass.get(), \"<init>\", \"(Ljava/io/Writer;)V\");\n\n    scoped_local_ref<jobject> stringWriter(env,\n            (*env)->NewObject(e, stringWriterClass.get(), stringWriterCtor));\n    if (stringWriter.get() == NULL) {\n        return false;\n    }\n\n    scoped_local_ref<jobject> printWriter(env,\n            (*env)->NewObject(e, printWriterClass.get(), printWriterCtor, stringWriter.get()));\n    if (printWriter.get() == NULL) {\n        return false;\n    }\n\n    scoped_local_ref<jclass> exceptionClass(env, (*env)->GetObjectClass(e, exception)); // can't fail\n    jmethodID printStackTraceMethod =\n            (*env)->GetMethodID(e, exceptionClass.get(), \"printStackTrace\", \"(Ljava/io/PrintWriter;)V\");\n    (*env)->CallVoidMethod(e, exception, printStackTraceMethod, printWriter.get());\n\n    if ((*env)->ExceptionCheck(e)) {\n        return false;\n    }\n\n    scoped_local_ref<jstring> messageStr(env,\n            (jstring) (*env)->CallObjectMethod(e, stringWriter.get(), stringWriterToStringMethod));\n    if (messageStr.get() == NULL) {\n        return false;\n    }\n\n    const char* utfChars = (*env)->GetStringUTFChars(e, messageStr.get(), NULL);\n    if (utfChars == NULL) {\n        return false;\n    }\n\n    result = utfChars;\n\n    (*env)->ReleaseStringUTFChars(e, messageStr.get(), utfChars);\n    return true;\n}\n\nextern \"C\" int jniThrowException(C_JNIEnv* env, const char* className, const char* msg) {\n    JNIEnv* e = reinterpret_cast<JNIEnv*>(env);\n\n    if ((*env)->ExceptionCheck(e)) {\n        /* TODO: consider creating the new exception with this as \"cause\" */\n        scoped_local_ref<jthrowable> exception(env, (*env)->ExceptionOccurred(e));\n        (*env)->ExceptionClear(e);\n\n        if (exception.get() != NULL) {\n            std::string text;\n            getExceptionSummary(env, exception.get(), text);\n            ALOGW(\"Discarding pending exception (%s) to throw %s\", text.c_str(), className);\n        }\n    }\n\n    scoped_local_ref<jclass> exceptionClass(env, findClass(env, className));\n    if (exceptionClass.get() == NULL) {\n        ALOGE(\"Unable to find exception class %s\", className);\n        /* ClassNotFoundException now pending */\n        return -1;\n    }\n\n    if ((*env)->ThrowNew(e, exceptionClass.get(), msg) != JNI_OK) {\n        ALOGE(\"Failed throwing '%s' '%s'\", className, msg);\n        /* an exception, most likely OOM, will now be pending */\n        return -1;\n    }\n\n    return 0;\n}\n\nint jniThrowExceptionFmt(C_JNIEnv* env, const char* className, const char* fmt, va_list args) {\n    char msgBuf[512];\n    vsnprintf(msgBuf, sizeof(msgBuf), fmt, args);\n    return jniThrowException(env, className, msgBuf);\n}\n\nint jniThrowNullPointerException(C_JNIEnv* env, const char* msg) {\n    return jniThrowException(env, \"java/lang/NullPointerException\", msg);\n}\n\nint jniThrowRuntimeException(C_JNIEnv* env, const char* msg) {\n    return jniThrowException(env, \"java/lang/RuntimeException\", msg);\n}\n\nint jniThrowIOException(C_JNIEnv* env, int errnum) {\n    char buffer[80];\n    const char* message = jniStrError(errnum, buffer, sizeof(buffer));\n    return jniThrowException(env, \"java/io/IOException\", message);\n}\n\nstatic std::string jniGetStackTrace(C_JNIEnv* env, jthrowable exception) {\n    JNIEnv* e = reinterpret_cast<JNIEnv*>(env);\n\n    scoped_local_ref<jthrowable> currentException(env, (*env)->ExceptionOccurred(e));\n    if (exception == NULL) {\n        exception = currentException.get();\n        if (exception == NULL) {\n          return \"<no pending exception>\";\n        }\n    }\n\n    if (currentException.get() != NULL) {\n        (*env)->ExceptionClear(e);\n    }\n\n    std::string trace;\n    if (!getStackTrace(env, exception, trace)) {\n        (*env)->ExceptionClear(e);\n        getExceptionSummary(env, exception, trace);\n    }\n\n    if (currentException.get() != NULL) {\n        (*env)->Throw(e, currentException.get()); // rethrow\n    }\n\n    return trace;\n}\n\nvoid jniLogException(C_JNIEnv* env, int priority, const char* tag, jthrowable exception) {\n    std::string trace(jniGetStackTrace(env, exception));\n    __android_log_write(priority, tag, trace.c_str());\n}\n\nconst char* jniStrError(int errnum, char* buf, size_t buflen) {\n#if __GLIBC__\n    // Note: glibc has a nonstandard strerror_r that returns char* rather than POSIX's int.\n    // char *strerror_r(int errnum, char *buf, size_t n);\n    return strerror_r(errnum, buf, buflen);\n#else\n    int rc = strerror_r(errnum, buf, buflen);\n    if (rc != 0) {\n        // (POSIX only guarantees a value other than 0. The safest\n        // way to implement this function is to use C++ and overload on the\n        // type of strerror_r to accurately distinguish GNU from POSIX.)\n        snprintf(buf, buflen, \"errno %d\", errnum);\n    }\n    return buf;\n#endif\n}\n\njobject jniCreateFileDescriptor(C_JNIEnv* env, int fd) {\n    JNIEnv* e = reinterpret_cast<JNIEnv*>(env);\n    JniConstants::init(e);\n    static jmethodID ctor = e->GetMethodID(JniConstants::fileDescriptorClass, \"<init>\", \"()V\");\n    jobject fileDescriptor = (*env)->NewObject(e, JniConstants::fileDescriptorClass, ctor);\n    // NOTE: NewObject ensures that an OutOfMemoryError will be seen by the Java\n    // caller if the alloc fails, so we just return NULL when that happens.\n    if (fileDescriptor != NULL)  {\n        jniSetFileDescriptorOfFD(env, fileDescriptor, fd);\n    }\n    return fileDescriptor;\n}\n\nint jniGetFDFromFileDescriptor(C_JNIEnv* env, jobject fileDescriptor) {\n    JNIEnv* e = reinterpret_cast<JNIEnv*>(env);\n    JniConstants::init(e);\n    static jfieldID fid = e->GetFieldID(JniConstants::fileDescriptorClass, \"descriptor\", \"I\");\n    if (fileDescriptor != NULL) {\n        return (*env)->GetIntField(e, fileDescriptor, fid);\n    } else {\n        return -1;\n    }\n}\n\nvoid jniSetFileDescriptorOfFD(C_JNIEnv* env, jobject fileDescriptor, int value) {\n    JNIEnv* e = reinterpret_cast<JNIEnv*>(env);\n    JniConstants::init(e);\n    static jfieldID fid = e->GetFieldID(JniConstants::fileDescriptorClass, \"descriptor\", \"I\");\n    (*env)->SetIntField(e, fileDescriptor, fid, value);\n}\n\njobject jniGetReferent(C_JNIEnv* env, jobject ref) {\n    JNIEnv* e = reinterpret_cast<JNIEnv*>(env);\n    JniConstants::init(e);\n    static jmethodID get = e->GetMethodID(JniConstants::referenceClass, \"get\", \"()Ljava/lang/Object;\");\n    return (*env)->CallObjectMethod(e, ref, get);\n}\n\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/JniConstants.cpp",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"JniConstants\"\n\n#include \"ALog-priv.h\"\n#include \"JniConstants.h\"\n#include \"ScopedLocalRef.h\"\n\n#include <stdlib.h>\n\n#include <atomic>\n#include <mutex>\n\nstatic std::atomic<bool> g_constants_initialized(false);\nstatic std::mutex g_constants_mutex;\n\njclass JniConstants::bigDecimalClass;\njclass JniConstants::booleanClass;\njclass JniConstants::byteArrayClass;\njclass JniConstants::byteClass;\njclass JniConstants::calendarClass;\njclass JniConstants::characterClass;\njclass JniConstants::charsetICUClass;\njclass JniConstants::constructorClass;\njclass JniConstants::deflaterClass;\njclass JniConstants::doubleClass;\njclass JniConstants::errnoExceptionClass;\njclass JniConstants::fieldClass;\njclass JniConstants::fileDescriptorClass;\njclass JniConstants::floatClass;\njclass JniConstants::gaiExceptionClass;\njclass JniConstants::inet6AddressClass;\njclass JniConstants::inetAddressClass;\njclass JniConstants::inetAddressHolderClass;\njclass JniConstants::inetSocketAddressClass;\njclass JniConstants::inetSocketAddressHolderClass;\njclass JniConstants::inflaterClass;\njclass JniConstants::inputStreamClass;\njclass JniConstants::integerClass;\njclass JniConstants::localeDataClass;\njclass JniConstants::longClass;\njclass JniConstants::methodClass;\njclass JniConstants::mutableIntClass;\njclass JniConstants::mutableLongClass;\njclass JniConstants::netlinkSocketAddressClass;\njclass JniConstants::objectClass;\njclass JniConstants::objectArrayClass;\njclass JniConstants::outputStreamClass;\njclass JniConstants::packetSocketAddressClass;\njclass JniConstants::parsePositionClass;\njclass JniConstants::patternSyntaxExceptionClass;\njclass JniConstants::referenceClass;\njclass JniConstants::shortClass;\njclass JniConstants::socketClass;\njclass JniConstants::socketImplClass;\njclass JniConstants::socketTaggerClass;\njclass JniConstants::stringClass;\njclass JniConstants::structAddrinfoClass;\njclass JniConstants::structFlockClass;\njclass JniConstants::structGroupReqClass;\njclass JniConstants::structGroupSourceReqClass;\njclass JniConstants::structLingerClass;\njclass JniConstants::structPasswdClass;\njclass JniConstants::structPollfdClass;\njclass JniConstants::structStatClass;\njclass JniConstants::structStatVfsClass;\njclass JniConstants::structTimevalClass;\njclass JniConstants::structUcredClass;\njclass JniConstants::structUtsnameClass;\njclass JniConstants::unixSocketAddressClass;\njclass JniConstants::zipEntryClass;\n\nstatic jclass findClass(JNIEnv* env, const char* name) {\n    ScopedLocalRef<jclass> localClass(env, env->FindClass(name));\n    jclass result = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));\n    if (result == NULL) {\n        ALOGE(\"failed to find class '%s'\", name);\n        abort();\n    }\n    return result;\n}\n\nvoid JniConstants::init(JNIEnv* env) {\n    // Fast check\n    if (g_constants_initialized) {\n      // already initialized\n      return;\n    }\n\n    // Slightly slower check\n    std::lock_guard<std::mutex> guard(g_constants_mutex);\n    if (g_constants_initialized) {\n      // already initialized\n      return;\n    }\n\n    bigDecimalClass = findClass(env, \"java/math/BigDecimal\");\n    booleanClass = findClass(env, \"java/lang/Boolean\");\n    byteClass = findClass(env, \"java/lang/Byte\");\n    byteArrayClass = findClass(env, \"[B\");\n    calendarClass = findClass(env, \"java/util/Calendar\");\n    characterClass = findClass(env, \"java/lang/Character\");\n    charsetICUClass = findClass(env, \"java/nio/charset/CharsetICU\");\n    constructorClass = findClass(env, \"java/lang/reflect/Constructor\");\n    floatClass = findClass(env, \"java/lang/Float\");\n    deflaterClass = findClass(env, \"java/util/zip/Deflater\");\n    doubleClass = findClass(env, \"java/lang/Double\");\n    errnoExceptionClass = findClass(env, \"android/system/ErrnoException\");\n    fieldClass = findClass(env, \"java/lang/reflect/Field\");\n    fileDescriptorClass = findClass(env, \"java/io/FileDescriptor\");\n    gaiExceptionClass = findClass(env, \"android/system/GaiException\");\n    inet6AddressClass = findClass(env, \"java/net/Inet6Address\");\n    inetAddressClass = findClass(env, \"java/net/InetAddress\");\n    inetAddressHolderClass = findClass(env, \"java/net/InetAddress$InetAddressHolder\");\n    inetSocketAddressClass = findClass(env, \"java/net/InetSocketAddress\");\n    inetSocketAddressHolderClass = findClass(env, \"java/net/InetSocketAddress$InetSocketAddressHolder\");\n    inflaterClass = findClass(env, \"java/util/zip/Inflater\");\n    inputStreamClass = findClass(env, \"java/io/InputStream\");\n    integerClass = findClass(env, \"java/lang/Integer\");\n    localeDataClass = findClass(env, \"libcore/icu/LocaleData\");\n    longClass = findClass(env, \"java/lang/Long\");\n    methodClass = findClass(env, \"java/lang/reflect/Method\");\n    mutableIntClass = findClass(env, \"android/util/MutableInt\");\n    mutableLongClass = findClass(env, \"android/util/MutableLong\");\n    netlinkSocketAddressClass = findClass(env, \"android/system/NetlinkSocketAddress\");\n    objectClass = findClass(env, \"java/lang/Object\");\n    objectArrayClass = findClass(env, \"[Ljava/lang/Object;\");\n    outputStreamClass = findClass(env, \"java/io/OutputStream\");\n    packetSocketAddressClass = findClass(env, \"android/system/PacketSocketAddress\");\n    parsePositionClass = findClass(env, \"java/text/ParsePosition\");\n    patternSyntaxExceptionClass = findClass(env, \"java/util/regex/PatternSyntaxException\");\n    referenceClass = findClass(env, \"java/lang/ref/Reference\");\n    shortClass = findClass(env, \"java/lang/Short\");\n    socketClass = findClass(env, \"java/net/Socket\");\n    socketTaggerClass = findClass(env, \"dalvik/system/SocketTagger\");\n    socketImplClass = findClass(env, \"java/net/SocketImpl\");\n    stringClass = findClass(env, \"java/lang/String\");\n    structAddrinfoClass = findClass(env, \"android/system/StructAddrinfo\");\n    structFlockClass = findClass(env, \"android/system/StructFlock\");\n    structGroupReqClass = findClass(env, \"android/system/StructGroupReq\");\n    structGroupSourceReqClass = findClass(env, \"android/system/StructGroupSourceReq\");\n    structLingerClass = findClass(env, \"android/system/StructLinger\");\n    structPasswdClass = findClass(env, \"android/system/StructPasswd\");\n    structPollfdClass = findClass(env, \"android/system/StructPollfd\");\n    structStatClass = findClass(env, \"android/system/StructStat\");\n    structStatVfsClass = findClass(env, \"android/system/StructStatVfs\");\n    structTimevalClass = findClass(env, \"android/system/StructTimeval\");\n    structUcredClass = findClass(env, \"android/system/StructUcred\");\n    structUtsnameClass = findClass(env, \"android/system/StructUtsname\");\n    unixSocketAddressClass = findClass(env, \"android/system/UnixSocketAddress\");\n    zipEntryClass = findClass(env, \"java/util/zip/ZipEntry\");\n\n    g_constants_initialized = true;\n}\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/JniInvocation.cpp",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"JniInvocation.h\"\n\n#include <dlfcn.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <cstddef>\n\n#define LOG_TAG \"JniInvocation\"\n#include \"cutils/log.h\"\n\n#ifdef __ANDROID__\n#include <sys/system_properties.h>\n#endif\n\nJniInvocation* JniInvocation::jni_invocation_ = NULL;\n\nJniInvocation::JniInvocation() :\n    handle_(NULL),\n    JNI_GetDefaultJavaVMInitArgs_(NULL),\n    JNI_CreateJavaVM_(NULL),\n    JNI_GetCreatedJavaVMs_(NULL) {\n\n  LOG_ALWAYS_FATAL_IF(jni_invocation_ != NULL, \"JniInvocation instance already initialized\");\n  jni_invocation_ = this;\n}\n\nJniInvocation::~JniInvocation() {\n  jni_invocation_ = NULL;\n  if (handle_ != NULL) {\n    dlclose(handle_);\n  }\n}\n\n#ifdef __ANDROID__\nstatic const char* kLibrarySystemProperty = \"persist.sys.dalvik.vm.lib.2\";\nstatic const char* kDebuggableSystemProperty = \"ro.debuggable\";\n#endif\nstatic const char* kLibraryFallback = \"libart.so\";\n\ntemplate<typename T> void UNUSED(const T&) {}\n\nconst char* JniInvocation::GetLibrary(const char* library, char* buffer) {\n#ifdef __ANDROID__\n  const char* default_library;\n\n  char debuggable[PROP_VALUE_MAX];\n  __system_property_get(kDebuggableSystemProperty, debuggable);\n\n  if (strcmp(debuggable, \"1\") != 0) {\n    // Not a debuggable build.\n    // Do not allow arbitrary library. Ignore the library parameter. This\n    // will also ignore the default library, but initialize to fallback\n    // for cleanliness.\n    library = kLibraryFallback;\n    default_library = kLibraryFallback;\n  } else {\n    // Debuggable build.\n    // Accept the library parameter. For the case it is NULL, load the default\n    // library from the system property.\n    if (buffer != NULL) {\n      if (__system_property_get(kLibrarySystemProperty, buffer) > 0) {\n        default_library = buffer;\n      } else {\n        default_library = kLibraryFallback;\n      }\n    } else {\n      // No buffer given, just use default fallback.\n      default_library = kLibraryFallback;\n    }\n  }\n#else\n  UNUSED(buffer);\n  const char* default_library = kLibraryFallback;\n#endif\n  if (library == NULL) {\n    library = default_library;\n  }\n\n  return library;\n}\n\nbool JniInvocation::Init(const char* library) {\n#ifdef __ANDROID__\n  char buffer[PROP_VALUE_MAX];\n#else\n  char* buffer = NULL;\n#endif\n  library = GetLibrary(library, buffer);\n  // Load with RTLD_NODELETE in order to ensure that libart.so is not unmapped when it is closed.\n  // This is due to the fact that it is possible that some threads might have yet to finish\n  // exiting even after JNI_DeleteJavaVM returns, which can lead to segfaults if the library is\n  // unloaded.\n  const int kDlopenFlags = RTLD_NOW | RTLD_NODELETE;\n  handle_ = dlopen(library, kDlopenFlags);\n  if (handle_ == NULL) {\n    if (strcmp(library, kLibraryFallback) == 0) {\n      // Nothing else to try.\n      ALOGE(\"Failed to dlopen %s: %s\", library, dlerror());\n      return false;\n    }\n    // Note that this is enough to get something like the zygote\n    // running, we can't property_set here to fix this for the future\n    // because we are root and not the system user. See\n    // RuntimeInit.commonInit for where we fix up the property to\n    // avoid future fallbacks. http://b/11463182\n    ALOGW(\"Falling back from %s to %s after dlopen error: %s\",\n          library, kLibraryFallback, dlerror());\n    library = kLibraryFallback;\n    handle_ = dlopen(library, kDlopenFlags);\n    if (handle_ == NULL) {\n      ALOGE(\"Failed to dlopen %s: %s\", library, dlerror());\n      return false;\n    }\n  }\n  if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetDefaultJavaVMInitArgs_),\n                  \"JNI_GetDefaultJavaVMInitArgs\")) {\n    return false;\n  }\n  if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_),\n                  \"JNI_CreateJavaVM\")) {\n    return false;\n  }\n  if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetCreatedJavaVMs_),\n                  \"JNI_GetCreatedJavaVMs\")) {\n    return false;\n  }\n  return true;\n}\n\njint JniInvocation::JNI_GetDefaultJavaVMInitArgs(void* vmargs) {\n  return JNI_GetDefaultJavaVMInitArgs_(vmargs);\n}\n\njint JniInvocation::JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {\n  return JNI_CreateJavaVM_(p_vm, p_env, vm_args);\n}\n\njint JniInvocation::JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count) {\n  return JNI_GetCreatedJavaVMs_(vms, size, vm_count);\n}\n\nbool JniInvocation::FindSymbol(void** pointer, const char* symbol) {\n  *pointer = dlsym(handle_, symbol);\n  if (*pointer == NULL) {\n    ALOGE(\"Failed to find symbol %s: %s\\n\", symbol, dlerror());\n    dlclose(handle_);\n    handle_ = NULL;\n    return false;\n  }\n  return true;\n}\n\nJniInvocation& JniInvocation::GetJniInvocation() {\n  LOG_ALWAYS_FATAL_IF(jni_invocation_ == NULL,\n                      \"Failed to create JniInvocation instance before using JNI invocation API\");\n  return *jni_invocation_;\n}\n\nextern \"C\" jint JNI_GetDefaultJavaVMInitArgs(void* vm_args) {\n  return JniInvocation::GetJniInvocation().JNI_GetDefaultJavaVMInitArgs(vm_args);\n}\n\nextern \"C\" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {\n  return JniInvocation::GetJniInvocation().JNI_CreateJavaVM(p_vm, p_env, vm_args);\n}\n\nextern \"C\" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count) {\n  return JniInvocation::GetJniInvocation().JNI_GetCreatedJavaVMs(vms, size, vm_count);\n}\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/MODULE_LICENSE_APACHE2",
    "content": ""
  },
  {
    "path": "atlas-aapt/libnativehelper/NOTICE",
    "content": "\n   Copyright (c) 2005-2008, The Android Open Source Project\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/README",
    "content": "Support functions for Android's class libraries\n\n\nThese are VM-agnostic native functions that implement methods for system\nclass libraries.  All code here:\n\n - MUST not be associated with an android.* class (that code lives in\n   frameworks/base/).\n - SHOULD be written in C rather than C++ where possible.\n\nSome helper functions are defined in include/nativehelper/JNIHelp.h.\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/include/nativehelper/AsynchronousCloseMonitor.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ASYNCHRONOUS_CLOSE_MONITOR_H_included\n#define ASYNCHRONOUS_CLOSE_MONITOR_H_included\n\n#include \"ScopedPthreadMutexLock.h\"\n#include <pthread.h>\n\n/**\n * AsynchronousCloseMonitor helps implement Java's asynchronous close semantics.\n *\n * AsynchronousCloseMonitor::init must be called before anything else.\n *\n * Every blocking I/O operation must be surrounded by an AsynchronousCloseMonitor\n * instance. For example:\n *\n *   {\n *     AsynchronousCloseMonitor monitor(fd);\n *     byteCount = ::read(fd, buf, sizeof(buf));\n *   }\n *\n * To interrupt all threads currently blocked on file descriptor 'fd', call signalBlockedThreads:\n *\n *   AsynchronousCloseMonitor::signalBlockedThreads(fd);\n *\n * To test to see if the interruption was due to the signalBlockedThreads call:\n *\n *   monitor.wasSignaled();\n */\nclass AsynchronousCloseMonitor {\npublic:\n    AsynchronousCloseMonitor(int fd);\n    ~AsynchronousCloseMonitor();\n    bool wasSignaled() const;\n\n    static void init();\n\n    static void signalBlockedThreads(int fd);\n\nprivate:\n    AsynchronousCloseMonitor* mPrev;\n    AsynchronousCloseMonitor* mNext;\n    pthread_t mThread;\n    int mFd;\n    bool mSignaled;\n\n    // Disallow copy and assignment.\n    AsynchronousCloseMonitor(const AsynchronousCloseMonitor&);\n    void operator=(const AsynchronousCloseMonitor&);\n};\n\n#endif  // ASYNCHRONOUS_CLOSE_MONITOR_H_included\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/include/nativehelper/JNIHelp.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * JNI helper functions.\n *\n * This file may be included by C or C++ code, which is trouble because jni.h\n * uses different typedefs for JNIEnv in each language.\n *\n * TODO: remove C support.\n */\n#ifndef NATIVEHELPER_JNIHELP_H_\n#define NATIVEHELPER_JNIHELP_H_\n\n#include \"jni.h\"\n#include <errno.h>\n#include <unistd.h>\n\n#ifndef NELEM\n# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n * Register one or more native methods with a particular class.\n * \"className\" looks like \"java/lang/String\". Aborts on failure.\n * TODO: fix all callers and change the return type to void.\n */\nint jniRegisterNativeMethods(C_JNIEnv* env, const char* className, const JNINativeMethod* gMethods, int numMethods);\n\n/*\n * Throw an exception with the specified class and an optional message.\n *\n * The \"className\" argument will be passed directly to FindClass, which\n * takes strings with slashes (e.g. \"java/lang/Object\").\n *\n * If an exception is currently pending, we log a warning message and\n * clear it.\n *\n * Returns 0 on success, nonzero if something failed (e.g. the exception\n * class couldn't be found, so *an* exception will still be pending).\n *\n * Currently aborts the VM if it can't throw the exception.\n */\nint jniThrowException(C_JNIEnv* env, const char* className, const char* msg);\n\n/*\n * Throw a java.lang.NullPointerException, with an optional message.\n */\nint jniThrowNullPointerException(C_JNIEnv* env, const char* msg);\n\n/*\n * Throw a java.lang.RuntimeException, with an optional message.\n */\nint jniThrowRuntimeException(C_JNIEnv* env, const char* msg);\n\n/*\n * Throw a java.io.IOException, generating the message from errno.\n */\nint jniThrowIOException(C_JNIEnv* env, int errnum);\n\n/*\n * Return a pointer to a locale-dependent error string explaining errno\n * value 'errnum'. The returned pointer may or may not be equal to 'buf'.\n * This function is thread-safe (unlike strerror) and portable (unlike\n * strerror_r).\n */\nconst char* jniStrError(int errnum, char* buf, size_t buflen);\n\n/*\n * Returns a new java.io.FileDescriptor for the given int fd.\n */\njobject jniCreateFileDescriptor(C_JNIEnv* env, int fd);\n\n/*\n * Returns the int fd from a java.io.FileDescriptor.\n */\nint jniGetFDFromFileDescriptor(C_JNIEnv* env, jobject fileDescriptor);\n\n/*\n * Sets the int fd in a java.io.FileDescriptor.\n */\nvoid jniSetFileDescriptorOfFD(C_JNIEnv* env, jobject fileDescriptor, int value);\n\n/*\n * Returns the reference from a java.lang.ref.Reference.\n */\njobject jniGetReferent(C_JNIEnv* env, jobject ref);\n\n/*\n * Log a message and an exception.\n * If exception is NULL, logs the current exception in the JNI environment.\n */\nvoid jniLogException(C_JNIEnv* env, int priority, const char* tag, jthrowable exception);\n\n#ifdef __cplusplus\n}\n#endif\n\n\n/*\n * For C++ code, we provide inlines that map to the C functions.  g++ always\n * inlines these, even on non-optimized builds.\n */\n#if defined(__cplusplus)\ninline int jniRegisterNativeMethods(JNIEnv* env, const char* className, const JNINativeMethod* gMethods, int numMethods) {\n    return jniRegisterNativeMethods(&env->functions, className, gMethods, numMethods);\n}\n\ninline int jniThrowException(JNIEnv* env, const char* className, const char* msg) {\n    return jniThrowException(&env->functions, className, msg);\n}\n\nextern \"C\" int jniThrowExceptionFmt(C_JNIEnv* env, const char* className, const char* fmt, va_list args);\n\n/*\n * Equivalent to jniThrowException but with a printf-like format string and\n * variable-length argument list. This is only available in C++.\n */\ninline int jniThrowExceptionFmt(JNIEnv* env, const char* className, const char* fmt, ...) {\n    va_list args;\n    va_start(args, fmt);\n    return jniThrowExceptionFmt(&env->functions, className, fmt, args);\n    va_end(args);\n}\n\ninline int jniThrowNullPointerException(JNIEnv* env, const char* msg) {\n    return jniThrowNullPointerException(&env->functions, msg);\n}\n\ninline int jniThrowRuntimeException(JNIEnv* env, const char* msg) {\n    return jniThrowRuntimeException(&env->functions, msg);\n}\n\ninline int jniThrowIOException(JNIEnv* env, int errnum) {\n    return jniThrowIOException(&env->functions, errnum);\n}\n\ninline jobject jniCreateFileDescriptor(JNIEnv* env, int fd) {\n    return jniCreateFileDescriptor(&env->functions, fd);\n}\n\ninline int jniGetFDFromFileDescriptor(JNIEnv* env, jobject fileDescriptor) {\n    return jniGetFDFromFileDescriptor(&env->functions, fileDescriptor);\n}\n\ninline void jniSetFileDescriptorOfFD(JNIEnv* env, jobject fileDescriptor, int value) {\n    jniSetFileDescriptorOfFD(&env->functions, fileDescriptor, value);\n}\n\ninline jobject jniGetReferent(JNIEnv* env, jobject ref) {\n    return jniGetReferent(&env->functions, ref);\n}\n\ninline void jniLogException(JNIEnv* env, int priority, const char* tag, jthrowable exception = NULL) {\n    jniLogException(&env->functions, priority, tag, exception);\n}\n\n#if !defined(DISALLOW_COPY_AND_ASSIGN)\n// DISALLOW_COPY_AND_ASSIGN disallows the copy and operator= functions. It goes in the private:\n// declarations in a class.\n#if __cplusplus >= 201103L\n#define DISALLOW_COPY_AND_ASSIGN(TypeName) \\\n  TypeName(const TypeName&) = delete;  \\\n  void operator=(const TypeName&) = delete\n#else\n#define DISALLOW_COPY_AND_ASSIGN(TypeName) \\\n  TypeName(const TypeName&);  \\\n  void operator=(const TypeName&)\n#endif  // __has_feature(cxx_deleted_functions)\n#endif  // !defined(DISALLOW_COPY_AND_ASSIGN)\n\n#endif\n\n/*\n * TEMP_FAILURE_RETRY is defined by some, but not all, versions of\n * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's\n * not already defined, then define it here.\n */\n#ifndef TEMP_FAILURE_RETRY\n/* Used to retry syscalls that can return EINTR. */\n#define TEMP_FAILURE_RETRY(exp) ({         \\\n    typeof (exp) _rc;                      \\\n    do {                                   \\\n        _rc = (exp);                       \\\n    } while (_rc == -1 && errno == EINTR); \\\n    _rc; })\n#endif\n\n#endif  /* NATIVEHELPER_JNIHELP_H_ */\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/include/nativehelper/JniConstants.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef JNI_CONSTANTS_H_included\n#define JNI_CONSTANTS_H_included\n\n#include \"JNIHelp.h\"\n\n/**\n * A cache to avoid calling FindClass at runtime.\n *\n * Class lookup is relatively expensive, so we do these lookups at startup. This means that code\n * that never uses, say, java.util.zip.Deflater still has to pay for the lookup, but it means that\n * on device the cost is paid during boot and amortized. A central cache also removes the temptation\n * to dynamically call FindClass rather than add a small cache to each file that needs one. Another\n * cost is that each class cached here requires a global reference, though in practice we save\n * enough by not having a global reference for each file that uses a class such as java.lang.String\n * which is used in several files.\n *\n * FindClass is still called in a couple of situations: when throwing exceptions, and in some of\n * the serialization code. The former is clearly not a performance case, and we're currently\n * assuming that neither is the latter.\n *\n * TODO: similar arguments hold for field and method IDs; we should cache them centrally too.\n */\nstruct JniConstants {\n    static void init(JNIEnv* env);\n\n    static jclass bigDecimalClass;\n    static jclass booleanClass;\n    static jclass byteArrayClass;\n    static jclass byteClass;\n    static jclass calendarClass;\n    static jclass characterClass;\n    static jclass charsetICUClass;\n    static jclass constructorClass;\n    static jclass deflaterClass;\n    static jclass doubleClass;\n    static jclass errnoExceptionClass;\n    static jclass fieldClass;\n    static jclass fileDescriptorClass;\n    static jclass floatClass;\n    static jclass gaiExceptionClass;\n    static jclass inet6AddressClass;\n    static jclass inetAddressClass;\n    static jclass inetAddressHolderClass;\n    static jclass inetSocketAddressClass;\n    static jclass inetSocketAddressHolderClass;\n    static jclass inflaterClass;\n    static jclass inputStreamClass;\n    static jclass integerClass;\n    static jclass localeDataClass;\n    static jclass longClass;\n    static jclass methodClass;\n    static jclass mutableIntClass;\n    static jclass mutableLongClass;\n    static jclass netlinkSocketAddressClass;\n    static jclass objectClass;\n    static jclass objectArrayClass;\n    static jclass outputStreamClass;\n    static jclass packetSocketAddressClass;\n    static jclass parsePositionClass;\n    static jclass patternSyntaxExceptionClass;\n    static jclass referenceClass;\n    static jclass shortClass;\n    static jclass socketClass;\n    static jclass socketImplClass;\n    static jclass socketTaggerClass;\n    static jclass stringClass;\n    static jclass structAddrinfoClass;\n    static jclass structFlockClass;\n    static jclass structGroupReqClass;\n    static jclass structGroupSourceReqClass;\n    static jclass structLingerClass;\n    static jclass structPasswdClass;\n    static jclass structPollfdClass;\n    static jclass structStatClass;\n    static jclass structStatVfsClass;\n    static jclass structTimevalClass;\n    static jclass structUcredClass;\n    static jclass structUtsnameClass;\n    static jclass unixSocketAddressClass;\n    static jclass zipEntryClass;\n};\n\n#define NATIVE_METHOD(className, functionName, signature) \\\n    { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName) }\n\n#endif  // JNI_CONSTANTS_H_included\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/include/nativehelper/JniInvocation.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef JNI_INVOCATION_H_included\n#define JNI_INVOCATION_H_included\n\n#include <jni.h>\n\n// JniInvocation adds a layer of indirection for applications using\n// the JNI invocation API to allow the JNI implementation to be\n// selected dynamically. Apps can specify a specific implementation to\n// be used by calling InitJniInvocation. If this is not done, the\n// library will chosen based on the value of Android system property\n// persist.sys.dalvik.vm.lib on the device, and otherwise fall back to\n// a hard-coded default implementation.\nclass JniInvocation {\n public:\n  JniInvocation();\n\n  ~JniInvocation();\n\n  // Initialize JNI invocation API. library should specifiy a valid\n  // shared library for opening via dlopen providing a JNI invocation\n  // implementation, or null to allow defaulting via\n  // persist.sys.dalvik.vm.lib.\n  bool Init(const char* library);\n\n  // Exposes which library is actually loaded from the given name. The\n  // buffer of size PROPERTY_VALUE_MAX will be used to load the system\n  // property for the default library, if necessary. If no buffer is\n  // provided, the fallback value will be used.\n  static const char* GetLibrary(const char* library, char* buffer);\n\n private:\n\n  bool FindSymbol(void** pointer, const char* symbol);\n\n  static JniInvocation& GetJniInvocation();\n\n  jint JNI_GetDefaultJavaVMInitArgs(void* vmargs);\n  jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args);\n  jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count);\n\n  static JniInvocation* jni_invocation_;\n\n  void* handle_;\n  jint (*JNI_GetDefaultJavaVMInitArgs_)(void*);\n  jint (*JNI_CreateJavaVM_)(JavaVM**, JNIEnv**, void*);\n  jint (*JNI_GetCreatedJavaVMs_)(JavaVM**, jsize, jsize*);\n\n  friend jint JNI_GetDefaultJavaVMInitArgs(void* vm_args);\n  friend jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args);\n  friend jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count);\n};\n\n#endif  // JNI_INVOCATION_H_included\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/include/nativehelper/ScopedBytes.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef SCOPED_BYTES_H_included\n#define SCOPED_BYTES_H_included\n\n#include \"JNIHelp.h\"\n\n/**\n * ScopedBytesRO and ScopedBytesRW attempt to paper over the differences between byte[]s and\n * ByteBuffers. This in turn helps paper over the differences between non-direct ByteBuffers backed\n * by byte[]s, direct ByteBuffers backed by bytes[]s, and direct ByteBuffers not backed by byte[]s.\n * (On Android, this last group only contains MappedByteBuffers.)\n */\ntemplate<bool readOnly>\nclass ScopedBytes {\npublic:\n    ScopedBytes(JNIEnv* env, jobject object)\n    : mEnv(env), mObject(object), mByteArray(NULL), mPtr(NULL)\n    {\n        if (mObject == NULL) {\n            jniThrowNullPointerException(mEnv, NULL);\n        } else if (mEnv->IsInstanceOf(mObject, JniConstants::byteArrayClass)) {\n            mByteArray = reinterpret_cast<jbyteArray>(mObject);\n            mPtr = mEnv->GetByteArrayElements(mByteArray, NULL);\n        } else {\n            mPtr = reinterpret_cast<jbyte*>(mEnv->GetDirectBufferAddress(mObject));\n        }\n    }\n\n    ~ScopedBytes() {\n        if (mByteArray != NULL) {\n            mEnv->ReleaseByteArrayElements(mByteArray, mPtr, readOnly ? JNI_ABORT : 0);\n        }\n    }\n\nprivate:\n    JNIEnv* const mEnv;\n    const jobject mObject;\n    jbyteArray mByteArray;\n\nprotected:\n    jbyte* mPtr;\n\nprivate:\n    DISALLOW_COPY_AND_ASSIGN(ScopedBytes);\n};\n\nclass ScopedBytesRO : public ScopedBytes<true> {\npublic:\n    ScopedBytesRO(JNIEnv* env, jobject object) : ScopedBytes<true>(env, object) {}\n    const jbyte* get() const {\n        return mPtr;\n    }\n};\n\nclass ScopedBytesRW : public ScopedBytes<false> {\npublic:\n    ScopedBytesRW(JNIEnv* env, jobject object) : ScopedBytes<false>(env, object) {}\n    jbyte* get() {\n        return mPtr;\n    }\n};\n\n#endif  // SCOPED_BYTES_H_included\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/include/nativehelper/ScopedFd.h",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef SCOPED_FD_H_included\n#define SCOPED_FD_H_included\n\n#include <unistd.h>\n#include \"JNIHelp.h\"  // for DISALLOW_COPY_AND_ASSIGN.\n\n// A smart pointer that closes the given fd on going out of scope.\n// Use this when the fd is incidental to the purpose of your function,\n// but needs to be cleaned up on exit.\nclass ScopedFd final {\npublic:\n    explicit ScopedFd(int fd) : fd_(fd) {\n    }\n    ScopedFd() : ScopedFd(-1) {}\n\n    ~ScopedFd() {\n      reset();\n    }\n\n    ScopedFd(ScopedFd&& other) : fd_(other.release()) {}\n    ScopedFd& operator = (ScopedFd&& s) {\n        reset(s.release());\n        return *this;\n    }\n\n    int get() const {\n        return fd_;\n    }\n\n    int release() __attribute__((warn_unused_result)) {\n        int localFd = fd_;\n        fd_ = -1;\n        return localFd;\n    }\n\n    void reset(int new_fd = -1) {\n      if (fd_ != -1) {\n        // Even if close(2) fails with EINTR, the fd will have been closed.\n        // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone else's fd.\n        // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html\n        close(fd_);\n      }\n      fd_ = new_fd;\n    }\n\nprivate:\n    int fd_;\n\n    DISALLOW_COPY_AND_ASSIGN(ScopedFd);\n};\n\n#endif  // SCOPED_FD_H_included\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/include/nativehelper/ScopedLocalFrame.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *      http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef SCOPED_LOCAL_FRAME_H_included\n#define SCOPED_LOCAL_FRAME_H_included\n\n#include \"JNIHelp.h\"\n\nclass ScopedLocalFrame {\npublic:\n    ScopedLocalFrame(JNIEnv* env) : mEnv(env) {\n        mEnv->PushLocalFrame(128);\n    }\n\n    ~ScopedLocalFrame() {\n        mEnv->PopLocalFrame(NULL);\n    }\n\nprivate:\n    JNIEnv* const mEnv;\n\n    DISALLOW_COPY_AND_ASSIGN(ScopedLocalFrame);\n};\n\n#endif  // SCOPED_LOCAL_FRAME_H_included\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/include/nativehelper/ScopedLocalRef.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef SCOPED_LOCAL_REF_H_included\n#define SCOPED_LOCAL_REF_H_included\n\n#include \"jni.h\"\n\n#include <stddef.h>\n#include \"JNIHelp.h\"  // for DISALLOW_COPY_AND_ASSIGN.\n\n// A smart pointer that deletes a JNI local reference when it goes out of scope.\ntemplate<typename T>\nclass ScopedLocalRef {\npublic:\n    ScopedLocalRef(JNIEnv* env, T localRef) : mEnv(env), mLocalRef(localRef) {\n    }\n\n    ~ScopedLocalRef() {\n        reset();\n    }\n\n    void reset(T ptr = NULL) {\n        if (ptr != mLocalRef) {\n            if (mLocalRef != NULL) {\n                mEnv->DeleteLocalRef(mLocalRef);\n            }\n            mLocalRef = ptr;\n        }\n    }\n\n    T release() __attribute__((warn_unused_result)) {\n        T localRef = mLocalRef;\n        mLocalRef = NULL;\n        return localRef;\n    }\n\n    T get() const {\n        return mLocalRef;\n    }\n\nprivate:\n    JNIEnv* const mEnv;\n    T mLocalRef;\n\n    DISALLOW_COPY_AND_ASSIGN(ScopedLocalRef);\n};\n\n#endif  // SCOPED_LOCAL_REF_H_included\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/include/nativehelper/ScopedPrimitiveArray.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef SCOPED_PRIMITIVE_ARRAY_H_included\n#define SCOPED_PRIMITIVE_ARRAY_H_included\n\n#include \"JNIHelp.h\"\n\n// ScopedBooleanArrayRO, ScopedByteArrayRO, ScopedCharArrayRO, ScopedDoubleArrayRO,\n// ScopedFloatArrayRO, ScopedIntArrayRO, ScopedLongArrayRO, and ScopedShortArrayRO provide\n// convenient read-only access to Java arrays from JNI code. This is cheaper than read-write\n// access and should be used by default.\n#define INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(PRIMITIVE_TYPE, NAME) \\\n    class Scoped ## NAME ## ArrayRO { \\\n    public: \\\n        explicit Scoped ## NAME ## ArrayRO(JNIEnv* env) \\\n        : mEnv(env), mJavaArray(NULL), mRawArray(NULL), mSize(0) {} \\\n        Scoped ## NAME ## ArrayRO(JNIEnv* env, PRIMITIVE_TYPE ## Array javaArray) \\\n        : mEnv(env) { \\\n            if (javaArray == NULL) { \\\n                mJavaArray = NULL; \\\n                mSize = 0; \\\n                mRawArray = NULL; \\\n                jniThrowNullPointerException(mEnv, NULL); \\\n            } else { \\\n                reset(javaArray); \\\n            } \\\n        } \\\n        ~Scoped ## NAME ## ArrayRO() { \\\n            if (mRawArray != NULL && mRawArray != mBuffer) { \\\n                mEnv->Release ## NAME ## ArrayElements(mJavaArray, mRawArray, JNI_ABORT); \\\n            } \\\n        } \\\n        void reset(PRIMITIVE_TYPE ## Array javaArray) { \\\n            mJavaArray = javaArray; \\\n            mSize = mEnv->GetArrayLength(mJavaArray); \\\n            if (mSize <= buffer_size) { \\\n                mEnv->Get ## NAME ## ArrayRegion(mJavaArray, 0, mSize, mBuffer); \\\n                mRawArray = mBuffer; \\\n            } else { \\\n                mRawArray = mEnv->Get ## NAME ## ArrayElements(mJavaArray, NULL); \\\n            } \\\n        } \\\n        const PRIMITIVE_TYPE* get() const { return mRawArray; } \\\n        PRIMITIVE_TYPE ## Array getJavaArray() const { return mJavaArray; } \\\n        const PRIMITIVE_TYPE& operator[](size_t n) const { return mRawArray[n]; } \\\n        size_t size() const { return mSize; } \\\n    private: \\\n        static const jsize buffer_size = 1024; \\\n        JNIEnv* const mEnv; \\\n        PRIMITIVE_TYPE ## Array mJavaArray; \\\n        PRIMITIVE_TYPE* mRawArray; \\\n        jsize mSize; \\\n        PRIMITIVE_TYPE mBuffer[buffer_size]; \\\n        DISALLOW_COPY_AND_ASSIGN(Scoped ## NAME ## ArrayRO); \\\n    }\n\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jboolean, Boolean);\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jbyte, Byte);\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jchar, Char);\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jdouble, Double);\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jfloat, Float);\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jint, Int);\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jlong, Long);\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jshort, Short);\n\n#undef INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO\n\n// ScopedBooleanArrayRW, ScopedByteArrayRW, ScopedCharArrayRW, ScopedDoubleArrayRW,\n// ScopedFloatArrayRW, ScopedIntArrayRW, ScopedLongArrayRW, and ScopedShortArrayRW provide\n// convenient read-write access to Java arrays from JNI code. These are more expensive,\n// since they entail a copy back onto the Java heap, and should only be used when necessary.\n#define INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(PRIMITIVE_TYPE, NAME) \\\n    class Scoped ## NAME ## ArrayRW { \\\n    public: \\\n        explicit Scoped ## NAME ## ArrayRW(JNIEnv* env) \\\n        : mEnv(env), mJavaArray(NULL), mRawArray(NULL) {} \\\n        Scoped ## NAME ## ArrayRW(JNIEnv* env, PRIMITIVE_TYPE ## Array javaArray) \\\n        : mEnv(env), mJavaArray(javaArray), mRawArray(NULL) { \\\n            if (mJavaArray == NULL) { \\\n                jniThrowNullPointerException(mEnv, NULL); \\\n            } else { \\\n                mRawArray = mEnv->Get ## NAME ## ArrayElements(mJavaArray, NULL); \\\n            } \\\n        } \\\n        ~Scoped ## NAME ## ArrayRW() { \\\n            if (mRawArray) { \\\n                mEnv->Release ## NAME ## ArrayElements(mJavaArray, mRawArray, 0); \\\n            } \\\n        } \\\n        void reset(PRIMITIVE_TYPE ## Array javaArray) { \\\n            mJavaArray = javaArray; \\\n            mRawArray = mEnv->Get ## NAME ## ArrayElements(mJavaArray, NULL); \\\n        } \\\n        const PRIMITIVE_TYPE* get() const { return mRawArray; } \\\n        PRIMITIVE_TYPE ## Array getJavaArray() const { return mJavaArray; } \\\n        const PRIMITIVE_TYPE& operator[](size_t n) const { return mRawArray[n]; } \\\n        PRIMITIVE_TYPE* get() { return mRawArray; } \\\n        PRIMITIVE_TYPE& operator[](size_t n) { return mRawArray[n]; } \\\n        size_t size() const { return mEnv->GetArrayLength(mJavaArray); } \\\n    private: \\\n        JNIEnv* const mEnv; \\\n        PRIMITIVE_TYPE ## Array mJavaArray; \\\n        PRIMITIVE_TYPE* mRawArray; \\\n        DISALLOW_COPY_AND_ASSIGN(Scoped ## NAME ## ArrayRW); \\\n    }\n\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jboolean, Boolean);\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jbyte, Byte);\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jchar, Char);\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jdouble, Double);\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jfloat, Float);\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jint, Int);\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jlong, Long);\nINSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jshort, Short);\n\n#undef INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW\n\n#endif  // SCOPED_PRIMITIVE_ARRAY_H_included\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/include/nativehelper/ScopedStringChars.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef SCOPED_STRING_CHARS_H_included\n#define SCOPED_STRING_CHARS_H_included\n\n#include \"JNIHelp.h\"\n\n// A smart pointer that provides access to a jchar* given a JNI jstring.\n// Unlike GetStringChars, we throw NullPointerException rather than abort if\n// passed a null jstring, and get will return NULL.\n// This makes the correct idiom very simple:\n//\n//   ScopedStringChars name(env, java_name);\n//   if (name.get() == NULL) {\n//     return NULL;\n//   }\nclass ScopedStringChars {\n public:\n  ScopedStringChars(JNIEnv* env, jstring s) : env_(env), string_(s), size_(0) {\n    if (s == NULL) {\n      chars_ = NULL;\n      jniThrowNullPointerException(env, NULL);\n    } else {\n      chars_ = env->GetStringChars(string_, NULL);\n      if (chars_ != NULL) {\n        size_ = env->GetStringLength(string_);\n      }\n    }\n  }\n\n  ~ScopedStringChars() {\n    if (chars_ != NULL) {\n      env_->ReleaseStringChars(string_, chars_);\n    }\n  }\n\n  const jchar* get() const {\n    return chars_;\n  }\n\n  size_t size() const {\n    return size_;\n  }\n\n  const jchar& operator[](size_t n) const {\n    return chars_[n];\n  }\n\n private:\n  JNIEnv* const env_;\n  const jstring string_;\n  const jchar* chars_;\n  size_t size_;\n\n  DISALLOW_COPY_AND_ASSIGN(ScopedStringChars);\n};\n\n#endif  // SCOPED_STRING_CHARS_H_included\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/include/nativehelper/ScopedUtfChars.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef SCOPED_UTF_CHARS_H_included\n#define SCOPED_UTF_CHARS_H_included\n\n#include \"JNIHelp.h\"\n#include <string.h>\n\n// A smart pointer that provides read-only access to a Java string's UTF chars.\n// Unlike GetStringUTFChars, we throw NullPointerException rather than abort if\n// passed a null jstring, and c_str will return NULL.\n// This makes the correct idiom very simple:\n//\n//   ScopedUtfChars name(env, java_name);\n//   if (name.c_str() == NULL) {\n//     return NULL;\n//   }\nclass ScopedUtfChars {\n public:\n  ScopedUtfChars(JNIEnv* env, jstring s) : env_(env), string_(s) {\n    if (s == NULL) {\n      utf_chars_ = NULL;\n      jniThrowNullPointerException(env, NULL);\n    } else {\n      utf_chars_ = env->GetStringUTFChars(s, NULL);\n    }\n  }\n\n  ~ScopedUtfChars() {\n    if (utf_chars_) {\n      env_->ReleaseStringUTFChars(string_, utf_chars_);\n    }\n  }\n\n  const char* c_str() const {\n    return utf_chars_;\n  }\n\n  size_t size() const {\n    return strlen(utf_chars_);\n  }\n\n  const char& operator[](size_t n) const {\n    return utf_chars_[n];\n  }\n\n private:\n  JNIEnv* const env_;\n  const jstring string_;\n  const char* utf_chars_;\n\n  DISALLOW_COPY_AND_ASSIGN(ScopedUtfChars);\n};\n\n#endif  // SCOPED_UTF_CHARS_H_included\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/include/nativehelper/UniquePtr.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef UNIQUE_PTR_H_included\n#define UNIQUE_PTR_H_included\n\n#include <cstdlib> // For NULL.\n#include \"JNIHelp.h\"  // For DISALLOW_COPY_AND_ASSIGN.\n\n// Default deleter for pointer types.\ntemplate <typename T>\nstruct DefaultDelete {\n    enum { type_must_be_complete = sizeof(T) };\n    DefaultDelete() {}\n    void operator()(T* p) const {\n        delete p;\n    }\n};\n\n// Default deleter for array types.\ntemplate <typename T>\nstruct DefaultDelete<T[]> {\n    enum { type_must_be_complete = sizeof(T) };\n    void operator()(T* p) const {\n        delete[] p;\n    }\n};\n\n// A smart pointer that deletes the given pointer on destruction.\n// Equivalent to C++0x's std::unique_ptr (a combination of boost::scoped_ptr\n// and boost::scoped_array).\n// Named to be in keeping with Android style but also to avoid\n// collision with any other implementation, until we can switch over\n// to unique_ptr.\n// Use thus:\n//   UniquePtr<C> c(new C);\ntemplate <typename T, typename D = DefaultDelete<T> >\nclass UniquePtr {\npublic:\n    // Construct a new UniquePtr, taking ownership of the given raw pointer.\n    explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) {\n    }\n\n    ~UniquePtr() {\n        reset();\n    }\n\n    // Accessors.\n    T& operator*() const { return *mPtr; }\n    T* operator->() const { return mPtr; }\n    T* get() const { return mPtr; }\n\n    // Returns the raw pointer and hands over ownership to the caller.\n    // The pointer will not be deleted by UniquePtr.\n    T* release() __attribute__((warn_unused_result)) {\n        T* result = mPtr;\n        mPtr = NULL;\n        return result;\n    }\n\n    // Takes ownership of the given raw pointer.\n    // If this smart pointer previously owned a different raw pointer, that\n    // raw pointer will be freed.\n    void reset(T* ptr = NULL) {\n        if (ptr != mPtr) {\n            D()(mPtr);\n            mPtr = ptr;\n        }\n    }\n\nprivate:\n    // The raw pointer.\n    T* mPtr;\n\n    // Comparing unique pointers is probably a mistake, since they're unique.\n    template <typename T2> bool operator==(const UniquePtr<T2>& p) const;\n    template <typename T2> bool operator!=(const UniquePtr<T2>& p) const;\n\n    DISALLOW_COPY_AND_ASSIGN(UniquePtr);\n};\n\n// Partial specialization for array types. Like std::unique_ptr, this removes\n// operator* and operator-> but adds operator[].\ntemplate <typename T, typename D>\nclass UniquePtr<T[], D> {\npublic:\n    explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) {\n    }\n\n    ~UniquePtr() {\n        reset();\n    }\n\n    T& operator[](size_t i) const {\n        return mPtr[i];\n    }\n    T* get() const { return mPtr; }\n\n    T* release() __attribute__((warn_unused_result)) {\n        T* result = mPtr;\n        mPtr = NULL;\n        return result;\n    }\n\n    void reset(T* ptr = NULL) {\n        if (ptr != mPtr) {\n            D()(mPtr);\n            mPtr = ptr;\n        }\n    }\n\nprivate:\n    T* mPtr;\n\n    DISALLOW_COPY_AND_ASSIGN(UniquePtr);\n};\n\n#if UNIQUE_PTR_TESTS\n\n// Run these tests with:\n// g++ -g -DUNIQUE_PTR_TESTS -x c++ UniquePtr.h && ./a.out\n\n#include <stdio.h>\n\nstatic void assert(bool b) {\n    if (!b) {\n        fprintf(stderr, \"FAIL\\n\");\n        abort();\n    }\n    fprintf(stderr, \"OK\\n\");\n}\nstatic int cCount = 0;\nstruct C {\n    C() { ++cCount; }\n    ~C() { --cCount; }\n};\nstatic bool freed = false;\nstruct Freer {\n    void operator()(int* p) {\n        assert(*p == 123);\n        free(p);\n        freed = true;\n    }\n};\n\nint main(int argc, char* argv[]) {\n    //\n    // UniquePtr<T> tests...\n    //\n\n    // Can we free a single object?\n    {\n        UniquePtr<C> c(new C);\n        assert(cCount == 1);\n    }\n    assert(cCount == 0);\n    // Does release work?\n    C* rawC;\n    {\n        UniquePtr<C> c(new C);\n        assert(cCount == 1);\n        rawC = c.release();\n    }\n    assert(cCount == 1);\n    delete rawC;\n    // Does reset work?\n    {\n        UniquePtr<C> c(new C);\n        assert(cCount == 1);\n        c.reset(new C);\n        assert(cCount == 1);\n    }\n    assert(cCount == 0);\n\n    //\n    // UniquePtr<T[]> tests...\n    //\n\n    // Can we free an array?\n    {\n        UniquePtr<C[]> cs(new C[4]);\n        assert(cCount == 4);\n    }\n    assert(cCount == 0);\n    // Does release work?\n    {\n        UniquePtr<C[]> c(new C[4]);\n        assert(cCount == 4);\n        rawC = c.release();\n    }\n    assert(cCount == 4);\n    delete[] rawC;\n    // Does reset work?\n    {\n        UniquePtr<C[]> c(new C[4]);\n        assert(cCount == 4);\n        c.reset(new C[2]);\n        assert(cCount == 2);\n    }\n    assert(cCount == 0);\n\n    //\n    // Custom deleter tests...\n    //\n    assert(!freed);\n    {\n        UniquePtr<int, Freer> i(reinterpret_cast<int*>(malloc(sizeof(int))));\n        *i = 123;\n    }\n    assert(freed);\n    return 0;\n}\n#endif\n\n#endif  // UNIQUE_PTR_H_included\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/include/nativehelper/jni.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * JNI specification, as defined by Sun:\n * http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html\n *\n * Everything here is expected to be VM-neutral.\n */\n\n#ifndef JNI_H_\n#define JNI_H_\n\n#include <stdarg.h>\n#include <stdint.h>\n\n/* Primitive types that match up with Java equivalents. */\ntypedef uint8_t  jboolean; /* unsigned 8 bits */\ntypedef int8_t   jbyte;    /* signed 8 bits */\ntypedef uint16_t jchar;    /* unsigned 16 bits */\ntypedef int16_t  jshort;   /* signed 16 bits */\ntypedef int32_t  jint;     /* signed 32 bits */\ntypedef int64_t  jlong;    /* signed 64 bits */\ntypedef float    jfloat;   /* 32-bit IEEE 754 */\ntypedef double   jdouble;  /* 64-bit IEEE 754 */\n\n/* \"cardinal indices and sizes\" */\ntypedef jint     jsize;\n\n#ifdef __cplusplus\n/*\n * Reference types, in C++\n */\nclass _jobject {};\nclass _jclass : public _jobject {};\nclass _jstring : public _jobject {};\nclass _jarray : public _jobject {};\nclass _jobjectArray : public _jarray {};\nclass _jbooleanArray : public _jarray {};\nclass _jbyteArray : public _jarray {};\nclass _jcharArray : public _jarray {};\nclass _jshortArray : public _jarray {};\nclass _jintArray : public _jarray {};\nclass _jlongArray : public _jarray {};\nclass _jfloatArray : public _jarray {};\nclass _jdoubleArray : public _jarray {};\nclass _jthrowable : public _jobject {};\n\ntypedef _jobject*       jobject;\ntypedef _jclass*        jclass;\ntypedef _jstring*       jstring;\ntypedef _jarray*        jarray;\ntypedef _jobjectArray*  jobjectArray;\ntypedef _jbooleanArray* jbooleanArray;\ntypedef _jbyteArray*    jbyteArray;\ntypedef _jcharArray*    jcharArray;\ntypedef _jshortArray*   jshortArray;\ntypedef _jintArray*     jintArray;\ntypedef _jlongArray*    jlongArray;\ntypedef _jfloatArray*   jfloatArray;\ntypedef _jdoubleArray*  jdoubleArray;\ntypedef _jthrowable*    jthrowable;\ntypedef _jobject*       jweak;\n\n\n#else /* not __cplusplus */\n\n/*\n * Reference types, in C.\n */\ntypedef void*           jobject;\ntypedef jobject         jclass;\ntypedef jobject         jstring;\ntypedef jobject         jarray;\ntypedef jarray          jobjectArray;\ntypedef jarray          jbooleanArray;\ntypedef jarray          jbyteArray;\ntypedef jarray          jcharArray;\ntypedef jarray          jshortArray;\ntypedef jarray          jintArray;\ntypedef jarray          jlongArray;\ntypedef jarray          jfloatArray;\ntypedef jarray          jdoubleArray;\ntypedef jobject         jthrowable;\ntypedef jobject         jweak;\n\n#endif /* not __cplusplus */\n\nstruct _jfieldID;                       /* opaque structure */\ntypedef struct _jfieldID* jfieldID;     /* field IDs */\n\nstruct _jmethodID;                      /* opaque structure */\ntypedef struct _jmethodID* jmethodID;   /* method IDs */\n\nstruct JNIInvokeInterface;\n\ntypedef union jvalue {\n    jboolean    z;\n    jbyte       b;\n    jchar       c;\n    jshort      s;\n    jint        i;\n    jlong       j;\n    jfloat      f;\n    jdouble     d;\n    jobject     l;\n} jvalue;\n\ntypedef enum jobjectRefType {\n    JNIInvalidRefType = 0,\n    JNILocalRefType = 1,\n    JNIGlobalRefType = 2,\n    JNIWeakGlobalRefType = 3\n} jobjectRefType;\n\ntypedef struct {\n    const char* name;\n    const char* signature;\n    void*       fnPtr;\n} JNINativeMethod;\n\nstruct _JNIEnv;\nstruct _JavaVM;\ntypedef const struct JNINativeInterface* C_JNIEnv;\n\n#if defined(__cplusplus)\ntypedef _JNIEnv JNIEnv;\ntypedef _JavaVM JavaVM;\n#else\ntypedef const struct JNINativeInterface* JNIEnv;\ntypedef const struct JNIInvokeInterface* JavaVM;\n#endif\n\n/*\n * Table of interface function pointers.\n */\nstruct JNINativeInterface {\n    void*       reserved0;\n    void*       reserved1;\n    void*       reserved2;\n    void*       reserved3;\n\n    jint        (*GetVersion)(JNIEnv *);\n\n    jclass      (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*,\n                        jsize);\n    jclass      (*FindClass)(JNIEnv*, const char*);\n\n    jmethodID   (*FromReflectedMethod)(JNIEnv*, jobject);\n    jfieldID    (*FromReflectedField)(JNIEnv*, jobject);\n    /* spec doesn't show jboolean parameter */\n    jobject     (*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean);\n\n    jclass      (*GetSuperclass)(JNIEnv*, jclass);\n    jboolean    (*IsAssignableFrom)(JNIEnv*, jclass, jclass);\n\n    /* spec doesn't show jboolean parameter */\n    jobject     (*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean);\n\n    jint        (*Throw)(JNIEnv*, jthrowable);\n    jint        (*ThrowNew)(JNIEnv *, jclass, const char *);\n    jthrowable  (*ExceptionOccurred)(JNIEnv*);\n    void        (*ExceptionDescribe)(JNIEnv*);\n    void        (*ExceptionClear)(JNIEnv*);\n    void        (*FatalError)(JNIEnv*, const char*);\n\n    jint        (*PushLocalFrame)(JNIEnv*, jint);\n    jobject     (*PopLocalFrame)(JNIEnv*, jobject);\n\n    jobject     (*NewGlobalRef)(JNIEnv*, jobject);\n    void        (*DeleteGlobalRef)(JNIEnv*, jobject);\n    void        (*DeleteLocalRef)(JNIEnv*, jobject);\n    jboolean    (*IsSameObject)(JNIEnv*, jobject, jobject);\n\n    jobject     (*NewLocalRef)(JNIEnv*, jobject);\n    jint        (*EnsureLocalCapacity)(JNIEnv*, jint);\n\n    jobject     (*AllocObject)(JNIEnv*, jclass);\n    jobject     (*NewObject)(JNIEnv*, jclass, jmethodID, ...);\n    jobject     (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list);\n    jobject     (*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*);\n\n    jclass      (*GetObjectClass)(JNIEnv*, jobject);\n    jboolean    (*IsInstanceOf)(JNIEnv*, jobject, jclass);\n    jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);\n\n    jobject     (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);\n    jobject     (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);\n    jobject     (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);\n    jboolean    (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);\n    jboolean    (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);\n    jboolean    (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);\n    jbyte       (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...);\n    jbyte       (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);\n    jbyte       (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);\n    jchar       (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...);\n    jchar       (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);\n    jchar       (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);\n    jshort      (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...);\n    jshort      (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);\n    jshort      (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);\n    jint        (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);\n    jint        (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);\n    jint        (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);\n    jlong       (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...);\n    jlong       (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);\n    jlong       (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);\n    jfloat      (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...);\n    jfloat      (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list);\n    jfloat      (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);\n    jdouble     (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...);\n    jdouble     (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list);\n    jdouble     (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);\n    void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);\n    void        (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);\n    void        (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);\n\n    jobject     (*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass,\n                        jmethodID, ...);\n    jobject     (*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass,\n                        jmethodID, va_list);\n    jobject     (*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass,\n                        jmethodID, jvalue*);\n    jboolean    (*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass,\n                        jmethodID, ...);\n    jboolean    (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass,\n                         jmethodID, va_list);\n    jboolean    (*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass,\n                         jmethodID, jvalue*);\n    jbyte       (*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass,\n                        jmethodID, ...);\n    jbyte       (*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass,\n                        jmethodID, va_list);\n    jbyte       (*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass,\n                        jmethodID, jvalue*);\n    jchar       (*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass,\n                        jmethodID, ...);\n    jchar       (*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass,\n                        jmethodID, va_list);\n    jchar       (*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass,\n                        jmethodID, jvalue*);\n    jshort      (*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass,\n                        jmethodID, ...);\n    jshort      (*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass,\n                        jmethodID, va_list);\n    jshort      (*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass,\n                        jmethodID, jvalue*);\n    jint        (*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass,\n                        jmethodID, ...);\n    jint        (*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass,\n                        jmethodID, va_list);\n    jint        (*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass,\n                        jmethodID, jvalue*);\n    jlong       (*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass,\n                        jmethodID, ...);\n    jlong       (*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass,\n                        jmethodID, va_list);\n    jlong       (*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass,\n                        jmethodID, jvalue*);\n    jfloat      (*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass,\n                        jmethodID, ...);\n    jfloat      (*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass,\n                        jmethodID, va_list);\n    jfloat      (*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass,\n                        jmethodID, jvalue*);\n    jdouble     (*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass,\n                        jmethodID, ...);\n    jdouble     (*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass,\n                        jmethodID, va_list);\n    jdouble     (*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass,\n                        jmethodID, jvalue*);\n    void        (*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass,\n                        jmethodID, ...);\n    void        (*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass,\n                        jmethodID, va_list);\n    void        (*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass,\n                        jmethodID, jvalue*);\n\n    jfieldID    (*GetFieldID)(JNIEnv*, jclass, const char*, const char*);\n\n    jobject     (*GetObjectField)(JNIEnv*, jobject, jfieldID);\n    jboolean    (*GetBooleanField)(JNIEnv*, jobject, jfieldID);\n    jbyte       (*GetByteField)(JNIEnv*, jobject, jfieldID);\n    jchar       (*GetCharField)(JNIEnv*, jobject, jfieldID);\n    jshort      (*GetShortField)(JNIEnv*, jobject, jfieldID);\n    jint        (*GetIntField)(JNIEnv*, jobject, jfieldID);\n    jlong       (*GetLongField)(JNIEnv*, jobject, jfieldID);\n    jfloat      (*GetFloatField)(JNIEnv*, jobject, jfieldID);\n    jdouble     (*GetDoubleField)(JNIEnv*, jobject, jfieldID);\n\n    void        (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject);\n    void        (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean);\n    void        (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte);\n    void        (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar);\n    void        (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort);\n    void        (*SetIntField)(JNIEnv*, jobject, jfieldID, jint);\n    void        (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong);\n    void        (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat);\n    void        (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble);\n\n    jmethodID   (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);\n\n    jobject     (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...);\n    jobject     (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list);\n    jobject     (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);\n    jboolean    (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...);\n    jboolean    (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID,\n                        va_list);\n    jboolean    (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID,\n                        jvalue*);\n    jbyte       (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...);\n    jbyte       (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list);\n    jbyte       (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);\n    jchar       (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...);\n    jchar       (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list);\n    jchar       (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);\n    jshort      (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...);\n    jshort      (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list);\n    jshort      (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);\n    jint        (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...);\n    jint        (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list);\n    jint        (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);\n    jlong       (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...);\n    jlong       (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list);\n    jlong       (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);\n    jfloat      (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...);\n    jfloat      (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list);\n    jfloat      (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);\n    jdouble     (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...);\n    jdouble     (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list);\n    jdouble     (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);\n    void        (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);\n    void        (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list);\n    void        (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);\n\n    jfieldID    (*GetStaticFieldID)(JNIEnv*, jclass, const char*,\n                        const char*);\n\n    jobject     (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID);\n    jboolean    (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID);\n    jbyte       (*GetStaticByteField)(JNIEnv*, jclass, jfieldID);\n    jchar       (*GetStaticCharField)(JNIEnv*, jclass, jfieldID);\n    jshort      (*GetStaticShortField)(JNIEnv*, jclass, jfieldID);\n    jint        (*GetStaticIntField)(JNIEnv*, jclass, jfieldID);\n    jlong       (*GetStaticLongField)(JNIEnv*, jclass, jfieldID);\n    jfloat      (*GetStaticFloatField)(JNIEnv*, jclass, jfieldID);\n    jdouble     (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID);\n\n    void        (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject);\n    void        (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean);\n    void        (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte);\n    void        (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar);\n    void        (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort);\n    void        (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint);\n    void        (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong);\n    void        (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat);\n    void        (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble);\n\n    jstring     (*NewString)(JNIEnv*, const jchar*, jsize);\n    jsize       (*GetStringLength)(JNIEnv*, jstring);\n    const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*);\n    void        (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*);\n    jstring     (*NewStringUTF)(JNIEnv*, const char*);\n    jsize       (*GetStringUTFLength)(JNIEnv*, jstring);\n    /* JNI spec says this returns const jbyte*, but that's inconsistent */\n    const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);\n    void        (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*);\n    jsize       (*GetArrayLength)(JNIEnv*, jarray);\n    jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject);\n    jobject     (*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize);\n    void        (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject);\n\n    jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize);\n    jbyteArray    (*NewByteArray)(JNIEnv*, jsize);\n    jcharArray    (*NewCharArray)(JNIEnv*, jsize);\n    jshortArray   (*NewShortArray)(JNIEnv*, jsize);\n    jintArray     (*NewIntArray)(JNIEnv*, jsize);\n    jlongArray    (*NewLongArray)(JNIEnv*, jsize);\n    jfloatArray   (*NewFloatArray)(JNIEnv*, jsize);\n    jdoubleArray  (*NewDoubleArray)(JNIEnv*, jsize);\n\n    jboolean*   (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*);\n    jbyte*      (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*);\n    jchar*      (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*);\n    jshort*     (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*);\n    jint*       (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);\n    jlong*      (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*);\n    jfloat*     (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*);\n    jdouble*    (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*);\n\n    void        (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray,\n                        jboolean*, jint);\n    void        (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray,\n                        jbyte*, jint);\n    void        (*ReleaseCharArrayElements)(JNIEnv*, jcharArray,\n                        jchar*, jint);\n    void        (*ReleaseShortArrayElements)(JNIEnv*, jshortArray,\n                        jshort*, jint);\n    void        (*ReleaseIntArrayElements)(JNIEnv*, jintArray,\n                        jint*, jint);\n    void        (*ReleaseLongArrayElements)(JNIEnv*, jlongArray,\n                        jlong*, jint);\n    void        (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray,\n                        jfloat*, jint);\n    void        (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray,\n                        jdouble*, jint);\n\n    void        (*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray,\n                        jsize, jsize, jboolean*);\n    void        (*GetByteArrayRegion)(JNIEnv*, jbyteArray,\n                        jsize, jsize, jbyte*);\n    void        (*GetCharArrayRegion)(JNIEnv*, jcharArray,\n                        jsize, jsize, jchar*);\n    void        (*GetShortArrayRegion)(JNIEnv*, jshortArray,\n                        jsize, jsize, jshort*);\n    void        (*GetIntArrayRegion)(JNIEnv*, jintArray,\n                        jsize, jsize, jint*);\n    void        (*GetLongArrayRegion)(JNIEnv*, jlongArray,\n                        jsize, jsize, jlong*);\n    void        (*GetFloatArrayRegion)(JNIEnv*, jfloatArray,\n                        jsize, jsize, jfloat*);\n    void        (*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray,\n                        jsize, jsize, jdouble*);\n\n    /* spec shows these without const; some jni.h do, some don't */\n    void        (*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray,\n                        jsize, jsize, const jboolean*);\n    void        (*SetByteArrayRegion)(JNIEnv*, jbyteArray,\n                        jsize, jsize, const jbyte*);\n    void        (*SetCharArrayRegion)(JNIEnv*, jcharArray,\n                        jsize, jsize, const jchar*);\n    void        (*SetShortArrayRegion)(JNIEnv*, jshortArray,\n                        jsize, jsize, const jshort*);\n    void        (*SetIntArrayRegion)(JNIEnv*, jintArray,\n                        jsize, jsize, const jint*);\n    void        (*SetLongArrayRegion)(JNIEnv*, jlongArray,\n                        jsize, jsize, const jlong*);\n    void        (*SetFloatArrayRegion)(JNIEnv*, jfloatArray,\n                        jsize, jsize, const jfloat*);\n    void        (*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray,\n                        jsize, jsize, const jdouble*);\n\n    jint        (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*,\n                        jint);\n    jint        (*UnregisterNatives)(JNIEnv*, jclass);\n    jint        (*MonitorEnter)(JNIEnv*, jobject);\n    jint        (*MonitorExit)(JNIEnv*, jobject);\n    jint        (*GetJavaVM)(JNIEnv*, JavaVM**);\n\n    void        (*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*);\n    void        (*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*);\n\n    void*       (*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*);\n    void        (*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint);\n\n    const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*);\n    void        (*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*);\n\n    jweak       (*NewWeakGlobalRef)(JNIEnv*, jobject);\n    void        (*DeleteWeakGlobalRef)(JNIEnv*, jweak);\n\n    jboolean    (*ExceptionCheck)(JNIEnv*);\n\n    jobject     (*NewDirectByteBuffer)(JNIEnv*, void*, jlong);\n    void*       (*GetDirectBufferAddress)(JNIEnv*, jobject);\n    jlong       (*GetDirectBufferCapacity)(JNIEnv*, jobject);\n\n    /* added in JNI 1.6 */\n    jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject);\n};\n\n/*\n * C++ object wrapper.\n *\n * This is usually overlaid on a C struct whose first element is a\n * JNINativeInterface*.  We rely somewhat on compiler behavior.\n */\nstruct _JNIEnv {\n    /* do not rename this; it does not seem to be entirely opaque */\n    const struct JNINativeInterface* functions;\n\n#if defined(__cplusplus)\n\n    jint GetVersion()\n    { return functions->GetVersion(this); }\n\n    jclass DefineClass(const char *name, jobject loader, const jbyte* buf,\n        jsize bufLen)\n    { return functions->DefineClass(this, name, loader, buf, bufLen); }\n\n    jclass FindClass(const char* name)\n    { return functions->FindClass(this, name); }\n\n    jmethodID FromReflectedMethod(jobject method)\n    { return functions->FromReflectedMethod(this, method); }\n\n    jfieldID FromReflectedField(jobject field)\n    { return functions->FromReflectedField(this, field); }\n\n    jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic)\n    { return functions->ToReflectedMethod(this, cls, methodID, isStatic); }\n\n    jclass GetSuperclass(jclass clazz)\n    { return functions->GetSuperclass(this, clazz); }\n\n    jboolean IsAssignableFrom(jclass clazz1, jclass clazz2)\n    { return functions->IsAssignableFrom(this, clazz1, clazz2); }\n\n    jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic)\n    { return functions->ToReflectedField(this, cls, fieldID, isStatic); }\n\n    jint Throw(jthrowable obj)\n    { return functions->Throw(this, obj); }\n\n    jint ThrowNew(jclass clazz, const char* message)\n    { return functions->ThrowNew(this, clazz, message); }\n\n    jthrowable ExceptionOccurred()\n    { return functions->ExceptionOccurred(this); }\n\n    void ExceptionDescribe()\n    { functions->ExceptionDescribe(this); }\n\n    void ExceptionClear()\n    { functions->ExceptionClear(this); }\n\n    void FatalError(const char* msg)\n    { functions->FatalError(this, msg); }\n\n    jint PushLocalFrame(jint capacity)\n    { return functions->PushLocalFrame(this, capacity); }\n\n    jobject PopLocalFrame(jobject result)\n    { return functions->PopLocalFrame(this, result); }\n\n    jobject NewGlobalRef(jobject obj)\n    { return functions->NewGlobalRef(this, obj); }\n\n    void DeleteGlobalRef(jobject globalRef)\n    { functions->DeleteGlobalRef(this, globalRef); }\n\n    void DeleteLocalRef(jobject localRef)\n    { functions->DeleteLocalRef(this, localRef); }\n\n    jboolean IsSameObject(jobject ref1, jobject ref2)\n    { return functions->IsSameObject(this, ref1, ref2); }\n\n    jobject NewLocalRef(jobject ref)\n    { return functions->NewLocalRef(this, ref); }\n\n    jint EnsureLocalCapacity(jint capacity)\n    { return functions->EnsureLocalCapacity(this, capacity); }\n\n    jobject AllocObject(jclass clazz)\n    { return functions->AllocObject(this, clazz); }\n\n    jobject NewObject(jclass clazz, jmethodID methodID, ...)\n    {\n        va_list args;\n        va_start(args, methodID);\n        jobject result = functions->NewObjectV(this, clazz, methodID, args);\n        va_end(args);\n        return result;\n    }\n\n    jobject NewObjectV(jclass clazz, jmethodID methodID, va_list args)\n    { return functions->NewObjectV(this, clazz, methodID, args); }\n\n    jobject NewObjectA(jclass clazz, jmethodID methodID, jvalue* args)\n    { return functions->NewObjectA(this, clazz, methodID, args); }\n\n    jclass GetObjectClass(jobject obj)\n    { return functions->GetObjectClass(this, obj); }\n\n    jboolean IsInstanceOf(jobject obj, jclass clazz)\n    { return functions->IsInstanceOf(this, obj, clazz); }\n\n    jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)\n    { return functions->GetMethodID(this, clazz, name, sig); }\n\n#define CALL_TYPE_METHOD(_jtype, _jname)                                    \\\n    _jtype Call##_jname##Method(jobject obj, jmethodID methodID, ...)       \\\n    {                                                                       \\\n        _jtype result;                                                      \\\n        va_list args;                                                       \\\n        va_start(args, methodID);                                           \\\n        result = functions->Call##_jname##MethodV(this, obj, methodID,      \\\n                    args);                                                  \\\n        va_end(args);                                                       \\\n        return result;                                                      \\\n    }\n#define CALL_TYPE_METHODV(_jtype, _jname)                                   \\\n    _jtype Call##_jname##MethodV(jobject obj, jmethodID methodID,           \\\n        va_list args)                                                       \\\n    { return functions->Call##_jname##MethodV(this, obj, methodID, args); }\n#define CALL_TYPE_METHODA(_jtype, _jname)                                   \\\n    _jtype Call##_jname##MethodA(jobject obj, jmethodID methodID,           \\\n        jvalue* args)                                                       \\\n    { return functions->Call##_jname##MethodA(this, obj, methodID, args); }\n\n#define CALL_TYPE(_jtype, _jname)                                           \\\n    CALL_TYPE_METHOD(_jtype, _jname)                                        \\\n    CALL_TYPE_METHODV(_jtype, _jname)                                       \\\n    CALL_TYPE_METHODA(_jtype, _jname)\n\n    CALL_TYPE(jobject, Object)\n    CALL_TYPE(jboolean, Boolean)\n    CALL_TYPE(jbyte, Byte)\n    CALL_TYPE(jchar, Char)\n    CALL_TYPE(jshort, Short)\n    CALL_TYPE(jint, Int)\n    CALL_TYPE(jlong, Long)\n    CALL_TYPE(jfloat, Float)\n    CALL_TYPE(jdouble, Double)\n\n    void CallVoidMethod(jobject obj, jmethodID methodID, ...)\n    {\n        va_list args;\n        va_start(args, methodID);\n        functions->CallVoidMethodV(this, obj, methodID, args);\n        va_end(args);\n    }\n    void CallVoidMethodV(jobject obj, jmethodID methodID, va_list args)\n    { functions->CallVoidMethodV(this, obj, methodID, args); }\n    void CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args)\n    { functions->CallVoidMethodA(this, obj, methodID, args); }\n\n#define CALL_NONVIRT_TYPE_METHOD(_jtype, _jname)                            \\\n    _jtype CallNonvirtual##_jname##Method(jobject obj, jclass clazz,        \\\n        jmethodID methodID, ...)                                            \\\n    {                                                                       \\\n        _jtype result;                                                      \\\n        va_list args;                                                       \\\n        va_start(args, methodID);                                           \\\n        result = functions->CallNonvirtual##_jname##MethodV(this, obj,      \\\n                    clazz, methodID, args);                                 \\\n        va_end(args);                                                       \\\n        return result;                                                      \\\n    }\n#define CALL_NONVIRT_TYPE_METHODV(_jtype, _jname)                           \\\n    _jtype CallNonvirtual##_jname##MethodV(jobject obj, jclass clazz,       \\\n        jmethodID methodID, va_list args)                                   \\\n    { return functions->CallNonvirtual##_jname##MethodV(this, obj, clazz,   \\\n        methodID, args); }\n#define CALL_NONVIRT_TYPE_METHODA(_jtype, _jname)                           \\\n    _jtype CallNonvirtual##_jname##MethodA(jobject obj, jclass clazz,       \\\n        jmethodID methodID, jvalue* args)                                   \\\n    { return functions->CallNonvirtual##_jname##MethodA(this, obj, clazz,   \\\n        methodID, args); }\n\n#define CALL_NONVIRT_TYPE(_jtype, _jname)                                   \\\n    CALL_NONVIRT_TYPE_METHOD(_jtype, _jname)                                \\\n    CALL_NONVIRT_TYPE_METHODV(_jtype, _jname)                               \\\n    CALL_NONVIRT_TYPE_METHODA(_jtype, _jname)\n\n    CALL_NONVIRT_TYPE(jobject, Object)\n    CALL_NONVIRT_TYPE(jboolean, Boolean)\n    CALL_NONVIRT_TYPE(jbyte, Byte)\n    CALL_NONVIRT_TYPE(jchar, Char)\n    CALL_NONVIRT_TYPE(jshort, Short)\n    CALL_NONVIRT_TYPE(jint, Int)\n    CALL_NONVIRT_TYPE(jlong, Long)\n    CALL_NONVIRT_TYPE(jfloat, Float)\n    CALL_NONVIRT_TYPE(jdouble, Double)\n\n    void CallNonvirtualVoidMethod(jobject obj, jclass clazz,\n        jmethodID methodID, ...)\n    {\n        va_list args;\n        va_start(args, methodID);\n        functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args);\n        va_end(args);\n    }\n    void CallNonvirtualVoidMethodV(jobject obj, jclass clazz,\n        jmethodID methodID, va_list args)\n    { functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); }\n    void CallNonvirtualVoidMethodA(jobject obj, jclass clazz,\n        jmethodID methodID, jvalue* args)\n    { functions->CallNonvirtualVoidMethodA(this, obj, clazz, methodID, args); }\n\n    jfieldID GetFieldID(jclass clazz, const char* name, const char* sig)\n    { return functions->GetFieldID(this, clazz, name, sig); }\n\n    jobject GetObjectField(jobject obj, jfieldID fieldID)\n    { return functions->GetObjectField(this, obj, fieldID); }\n    jboolean GetBooleanField(jobject obj, jfieldID fieldID)\n    { return functions->GetBooleanField(this, obj, fieldID); }\n    jbyte GetByteField(jobject obj, jfieldID fieldID)\n    { return functions->GetByteField(this, obj, fieldID); }\n    jchar GetCharField(jobject obj, jfieldID fieldID)\n    { return functions->GetCharField(this, obj, fieldID); }\n    jshort GetShortField(jobject obj, jfieldID fieldID)\n    { return functions->GetShortField(this, obj, fieldID); }\n    jint GetIntField(jobject obj, jfieldID fieldID)\n    { return functions->GetIntField(this, obj, fieldID); }\n    jlong GetLongField(jobject obj, jfieldID fieldID)\n    { return functions->GetLongField(this, obj, fieldID); }\n    jfloat GetFloatField(jobject obj, jfieldID fieldID)\n    { return functions->GetFloatField(this, obj, fieldID); }\n    jdouble GetDoubleField(jobject obj, jfieldID fieldID)\n    { return functions->GetDoubleField(this, obj, fieldID); }\n\n    void SetObjectField(jobject obj, jfieldID fieldID, jobject value)\n    { functions->SetObjectField(this, obj, fieldID, value); }\n    void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value)\n    { functions->SetBooleanField(this, obj, fieldID, value); }\n    void SetByteField(jobject obj, jfieldID fieldID, jbyte value)\n    { functions->SetByteField(this, obj, fieldID, value); }\n    void SetCharField(jobject obj, jfieldID fieldID, jchar value)\n    { functions->SetCharField(this, obj, fieldID, value); }\n    void SetShortField(jobject obj, jfieldID fieldID, jshort value)\n    { functions->SetShortField(this, obj, fieldID, value); }\n    void SetIntField(jobject obj, jfieldID fieldID, jint value)\n    { functions->SetIntField(this, obj, fieldID, value); }\n    void SetLongField(jobject obj, jfieldID fieldID, jlong value)\n    { functions->SetLongField(this, obj, fieldID, value); }\n    void SetFloatField(jobject obj, jfieldID fieldID, jfloat value)\n    { functions->SetFloatField(this, obj, fieldID, value); }\n    void SetDoubleField(jobject obj, jfieldID fieldID, jdouble value)\n    { functions->SetDoubleField(this, obj, fieldID, value); }\n\n    jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig)\n    { return functions->GetStaticMethodID(this, clazz, name, sig); }\n\n#define CALL_STATIC_TYPE_METHOD(_jtype, _jname)                             \\\n    _jtype CallStatic##_jname##Method(jclass clazz, jmethodID methodID,     \\\n        ...)                                                                \\\n    {                                                                       \\\n        _jtype result;                                                      \\\n        va_list args;                                                       \\\n        va_start(args, methodID);                                           \\\n        result = functions->CallStatic##_jname##MethodV(this, clazz,        \\\n                    methodID, args);                                        \\\n        va_end(args);                                                       \\\n        return result;                                                      \\\n    }\n#define CALL_STATIC_TYPE_METHODV(_jtype, _jname)                            \\\n    _jtype CallStatic##_jname##MethodV(jclass clazz, jmethodID methodID,    \\\n        va_list args)                                                       \\\n    { return functions->CallStatic##_jname##MethodV(this, clazz, methodID,  \\\n        args); }\n#define CALL_STATIC_TYPE_METHODA(_jtype, _jname)                            \\\n    _jtype CallStatic##_jname##MethodA(jclass clazz, jmethodID methodID,    \\\n        jvalue* args)                                                       \\\n    { return functions->CallStatic##_jname##MethodA(this, clazz, methodID,  \\\n        args); }\n\n#define CALL_STATIC_TYPE(_jtype, _jname)                                    \\\n    CALL_STATIC_TYPE_METHOD(_jtype, _jname)                                 \\\n    CALL_STATIC_TYPE_METHODV(_jtype, _jname)                                \\\n    CALL_STATIC_TYPE_METHODA(_jtype, _jname)\n\n    CALL_STATIC_TYPE(jobject, Object)\n    CALL_STATIC_TYPE(jboolean, Boolean)\n    CALL_STATIC_TYPE(jbyte, Byte)\n    CALL_STATIC_TYPE(jchar, Char)\n    CALL_STATIC_TYPE(jshort, Short)\n    CALL_STATIC_TYPE(jint, Int)\n    CALL_STATIC_TYPE(jlong, Long)\n    CALL_STATIC_TYPE(jfloat, Float)\n    CALL_STATIC_TYPE(jdouble, Double)\n\n    void CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...)\n    {\n        va_list args;\n        va_start(args, methodID);\n        functions->CallStaticVoidMethodV(this, clazz, methodID, args);\n        va_end(args);\n    }\n    void CallStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args)\n    { functions->CallStaticVoidMethodV(this, clazz, methodID, args); }\n    void CallStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args)\n    { functions->CallStaticVoidMethodA(this, clazz, methodID, args); }\n\n    jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig)\n    { return functions->GetStaticFieldID(this, clazz, name, sig); }\n\n    jobject GetStaticObjectField(jclass clazz, jfieldID fieldID)\n    { return functions->GetStaticObjectField(this, clazz, fieldID); }\n    jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID)\n    { return functions->GetStaticBooleanField(this, clazz, fieldID); }\n    jbyte GetStaticByteField(jclass clazz, jfieldID fieldID)\n    { return functions->GetStaticByteField(this, clazz, fieldID); }\n    jchar GetStaticCharField(jclass clazz, jfieldID fieldID)\n    { return functions->GetStaticCharField(this, clazz, fieldID); }\n    jshort GetStaticShortField(jclass clazz, jfieldID fieldID)\n    { return functions->GetStaticShortField(this, clazz, fieldID); }\n    jint GetStaticIntField(jclass clazz, jfieldID fieldID)\n    { return functions->GetStaticIntField(this, clazz, fieldID); }\n    jlong GetStaticLongField(jclass clazz, jfieldID fieldID)\n    { return functions->GetStaticLongField(this, clazz, fieldID); }\n    jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID)\n    { return functions->GetStaticFloatField(this, clazz, fieldID); }\n    jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID)\n    { return functions->GetStaticDoubleField(this, clazz, fieldID); }\n\n    void SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value)\n    { functions->SetStaticObjectField(this, clazz, fieldID, value); }\n    void SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value)\n    { functions->SetStaticBooleanField(this, clazz, fieldID, value); }\n    void SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value)\n    { functions->SetStaticByteField(this, clazz, fieldID, value); }\n    void SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value)\n    { functions->SetStaticCharField(this, clazz, fieldID, value); }\n    void SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value)\n    { functions->SetStaticShortField(this, clazz, fieldID, value); }\n    void SetStaticIntField(jclass clazz, jfieldID fieldID, jint value)\n    { functions->SetStaticIntField(this, clazz, fieldID, value); }\n    void SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value)\n    { functions->SetStaticLongField(this, clazz, fieldID, value); }\n    void SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value)\n    { functions->SetStaticFloatField(this, clazz, fieldID, value); }\n    void SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value)\n    { functions->SetStaticDoubleField(this, clazz, fieldID, value); }\n\n    jstring NewString(const jchar* unicodeChars, jsize len)\n    { return functions->NewString(this, unicodeChars, len); }\n\n    jsize GetStringLength(jstring string)\n    { return functions->GetStringLength(this, string); }\n\n    const jchar* GetStringChars(jstring string, jboolean* isCopy)\n    { return functions->GetStringChars(this, string, isCopy); }\n\n    void ReleaseStringChars(jstring string, const jchar* chars)\n    { functions->ReleaseStringChars(this, string, chars); }\n\n    jstring NewStringUTF(const char* bytes)\n    { return functions->NewStringUTF(this, bytes); }\n\n    jsize GetStringUTFLength(jstring string)\n    { return functions->GetStringUTFLength(this, string); }\n\n    const char* GetStringUTFChars(jstring string, jboolean* isCopy)\n    { return functions->GetStringUTFChars(this, string, isCopy); }\n\n    void ReleaseStringUTFChars(jstring string, const char* utf)\n    { functions->ReleaseStringUTFChars(this, string, utf); }\n\n    jsize GetArrayLength(jarray array)\n    { return functions->GetArrayLength(this, array); }\n\n    jobjectArray NewObjectArray(jsize length, jclass elementClass,\n        jobject initialElement)\n    { return functions->NewObjectArray(this, length, elementClass,\n        initialElement); }\n\n    jobject GetObjectArrayElement(jobjectArray array, jsize index)\n    { return functions->GetObjectArrayElement(this, array, index); }\n\n    void SetObjectArrayElement(jobjectArray array, jsize index, jobject value)\n    { functions->SetObjectArrayElement(this, array, index, value); }\n\n    jbooleanArray NewBooleanArray(jsize length)\n    { return functions->NewBooleanArray(this, length); }\n    jbyteArray NewByteArray(jsize length)\n    { return functions->NewByteArray(this, length); }\n    jcharArray NewCharArray(jsize length)\n    { return functions->NewCharArray(this, length); }\n    jshortArray NewShortArray(jsize length)\n    { return functions->NewShortArray(this, length); }\n    jintArray NewIntArray(jsize length)\n    { return functions->NewIntArray(this, length); }\n    jlongArray NewLongArray(jsize length)\n    { return functions->NewLongArray(this, length); }\n    jfloatArray NewFloatArray(jsize length)\n    { return functions->NewFloatArray(this, length); }\n    jdoubleArray NewDoubleArray(jsize length)\n    { return functions->NewDoubleArray(this, length); }\n\n    jboolean* GetBooleanArrayElements(jbooleanArray array, jboolean* isCopy)\n    { return functions->GetBooleanArrayElements(this, array, isCopy); }\n    jbyte* GetByteArrayElements(jbyteArray array, jboolean* isCopy)\n    { return functions->GetByteArrayElements(this, array, isCopy); }\n    jchar* GetCharArrayElements(jcharArray array, jboolean* isCopy)\n    { return functions->GetCharArrayElements(this, array, isCopy); }\n    jshort* GetShortArrayElements(jshortArray array, jboolean* isCopy)\n    { return functions->GetShortArrayElements(this, array, isCopy); }\n    jint* GetIntArrayElements(jintArray array, jboolean* isCopy)\n    { return functions->GetIntArrayElements(this, array, isCopy); }\n    jlong* GetLongArrayElements(jlongArray array, jboolean* isCopy)\n    { return functions->GetLongArrayElements(this, array, isCopy); }\n    jfloat* GetFloatArrayElements(jfloatArray array, jboolean* isCopy)\n    { return functions->GetFloatArrayElements(this, array, isCopy); }\n    jdouble* GetDoubleArrayElements(jdoubleArray array, jboolean* isCopy)\n    { return functions->GetDoubleArrayElements(this, array, isCopy); }\n\n    void ReleaseBooleanArrayElements(jbooleanArray array, jboolean* elems,\n        jint mode)\n    { functions->ReleaseBooleanArrayElements(this, array, elems, mode); }\n    void ReleaseByteArrayElements(jbyteArray array, jbyte* elems,\n        jint mode)\n    { functions->ReleaseByteArrayElements(this, array, elems, mode); }\n    void ReleaseCharArrayElements(jcharArray array, jchar* elems,\n        jint mode)\n    { functions->ReleaseCharArrayElements(this, array, elems, mode); }\n    void ReleaseShortArrayElements(jshortArray array, jshort* elems,\n        jint mode)\n    { functions->ReleaseShortArrayElements(this, array, elems, mode); }\n    void ReleaseIntArrayElements(jintArray array, jint* elems,\n        jint mode)\n    { functions->ReleaseIntArrayElements(this, array, elems, mode); }\n    void ReleaseLongArrayElements(jlongArray array, jlong* elems,\n        jint mode)\n    { functions->ReleaseLongArrayElements(this, array, elems, mode); }\n    void ReleaseFloatArrayElements(jfloatArray array, jfloat* elems,\n        jint mode)\n    { functions->ReleaseFloatArrayElements(this, array, elems, mode); }\n    void ReleaseDoubleArrayElements(jdoubleArray array, jdouble* elems,\n        jint mode)\n    { functions->ReleaseDoubleArrayElements(this, array, elems, mode); }\n\n    void GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,\n        jboolean* buf)\n    { functions->GetBooleanArrayRegion(this, array, start, len, buf); }\n    void GetByteArrayRegion(jbyteArray array, jsize start, jsize len,\n        jbyte* buf)\n    { functions->GetByteArrayRegion(this, array, start, len, buf); }\n    void GetCharArrayRegion(jcharArray array, jsize start, jsize len,\n        jchar* buf)\n    { functions->GetCharArrayRegion(this, array, start, len, buf); }\n    void GetShortArrayRegion(jshortArray array, jsize start, jsize len,\n        jshort* buf)\n    { functions->GetShortArrayRegion(this, array, start, len, buf); }\n    void GetIntArrayRegion(jintArray array, jsize start, jsize len,\n        jint* buf)\n    { functions->GetIntArrayRegion(this, array, start, len, buf); }\n    void GetLongArrayRegion(jlongArray array, jsize start, jsize len,\n        jlong* buf)\n    { functions->GetLongArrayRegion(this, array, start, len, buf); }\n    void GetFloatArrayRegion(jfloatArray array, jsize start, jsize len,\n        jfloat* buf)\n    { functions->GetFloatArrayRegion(this, array, start, len, buf); }\n    void GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,\n        jdouble* buf)\n    { functions->GetDoubleArrayRegion(this, array, start, len, buf); }\n\n    void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,\n        const jboolean* buf)\n    { functions->SetBooleanArrayRegion(this, array, start, len, buf); }\n    void SetByteArrayRegion(jbyteArray array, jsize start, jsize len,\n        const jbyte* buf)\n    { functions->SetByteArrayRegion(this, array, start, len, buf); }\n    void SetCharArrayRegion(jcharArray array, jsize start, jsize len,\n        const jchar* buf)\n    { functions->SetCharArrayRegion(this, array, start, len, buf); }\n    void SetShortArrayRegion(jshortArray array, jsize start, jsize len,\n        const jshort* buf)\n    { functions->SetShortArrayRegion(this, array, start, len, buf); }\n    void SetIntArrayRegion(jintArray array, jsize start, jsize len,\n        const jint* buf)\n    { functions->SetIntArrayRegion(this, array, start, len, buf); }\n    void SetLongArrayRegion(jlongArray array, jsize start, jsize len,\n        const jlong* buf)\n    { functions->SetLongArrayRegion(this, array, start, len, buf); }\n    void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len,\n        const jfloat* buf)\n    { functions->SetFloatArrayRegion(this, array, start, len, buf); }\n    void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,\n        const jdouble* buf)\n    { functions->SetDoubleArrayRegion(this, array, start, len, buf); }\n\n    jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,\n        jint nMethods)\n    { return functions->RegisterNatives(this, clazz, methods, nMethods); }\n\n    jint UnregisterNatives(jclass clazz)\n    { return functions->UnregisterNatives(this, clazz); }\n\n    jint MonitorEnter(jobject obj)\n    { return functions->MonitorEnter(this, obj); }\n\n    jint MonitorExit(jobject obj)\n    { return functions->MonitorExit(this, obj); }\n\n    jint GetJavaVM(JavaVM** vm)\n    { return functions->GetJavaVM(this, vm); }\n\n    void GetStringRegion(jstring str, jsize start, jsize len, jchar* buf)\n    { functions->GetStringRegion(this, str, start, len, buf); }\n\n    void GetStringUTFRegion(jstring str, jsize start, jsize len, char* buf)\n    { return functions->GetStringUTFRegion(this, str, start, len, buf); }\n\n    void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy)\n    { return functions->GetPrimitiveArrayCritical(this, array, isCopy); }\n\n    void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode)\n    { functions->ReleasePrimitiveArrayCritical(this, array, carray, mode); }\n\n    const jchar* GetStringCritical(jstring string, jboolean* isCopy)\n    { return functions->GetStringCritical(this, string, isCopy); }\n\n    void ReleaseStringCritical(jstring string, const jchar* carray)\n    { functions->ReleaseStringCritical(this, string, carray); }\n\n    jweak NewWeakGlobalRef(jobject obj)\n    { return functions->NewWeakGlobalRef(this, obj); }\n\n    void DeleteWeakGlobalRef(jweak obj)\n    { functions->DeleteWeakGlobalRef(this, obj); }\n\n    jboolean ExceptionCheck()\n    { return functions->ExceptionCheck(this); }\n\n    jobject NewDirectByteBuffer(void* address, jlong capacity)\n    { return functions->NewDirectByteBuffer(this, address, capacity); }\n\n    void* GetDirectBufferAddress(jobject buf)\n    { return functions->GetDirectBufferAddress(this, buf); }\n\n    jlong GetDirectBufferCapacity(jobject buf)\n    { return functions->GetDirectBufferCapacity(this, buf); }\n\n    /* added in JNI 1.6 */\n    jobjectRefType GetObjectRefType(jobject obj)\n    { return functions->GetObjectRefType(this, obj); }\n#endif /*__cplusplus*/\n};\n\n\n/*\n * JNI invocation interface.\n */\nstruct JNIInvokeInterface {\n    void*       reserved0;\n    void*       reserved1;\n    void*       reserved2;\n\n    jint        (*DestroyJavaVM)(JavaVM*);\n    jint        (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);\n    jint        (*DetachCurrentThread)(JavaVM*);\n    jint        (*GetEnv)(JavaVM*, void**, jint);\n    jint        (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);\n};\n\n/*\n * C++ version.\n */\nstruct _JavaVM {\n    const struct JNIInvokeInterface* functions;\n\n#if defined(__cplusplus)\n    jint DestroyJavaVM()\n    { return functions->DestroyJavaVM(this); }\n    jint AttachCurrentThread(JNIEnv** p_env, void* thr_args)\n    { return functions->AttachCurrentThread(this, p_env, thr_args); }\n    jint DetachCurrentThread()\n    { return functions->DetachCurrentThread(this); }\n    jint GetEnv(void** env, jint version)\n    { return functions->GetEnv(this, env, version); }\n    jint AttachCurrentThreadAsDaemon(JNIEnv** p_env, void* thr_args)\n    { return functions->AttachCurrentThreadAsDaemon(this, p_env, thr_args); }\n#endif /*__cplusplus*/\n};\n\nstruct JavaVMAttachArgs {\n    jint        version;    /* must be >= JNI_VERSION_1_2 */\n    const char* name;       /* NULL or name of thread as modified UTF-8 str */\n    jobject     group;      /* global ref of a ThreadGroup object, or NULL */\n};\ntypedef struct JavaVMAttachArgs JavaVMAttachArgs;\n\n/*\n * JNI 1.2+ initialization.  (As of 1.6, the pre-1.2 structures are no\n * longer supported.)\n */\ntypedef struct JavaVMOption {\n    const char* optionString;\n    void*       extraInfo;\n} JavaVMOption;\n\ntypedef struct JavaVMInitArgs {\n    jint        version;    /* use JNI_VERSION_1_2 or later */\n\n    jint        nOptions;\n    JavaVMOption* options;\n    jboolean    ignoreUnrecognized;\n} JavaVMInitArgs;\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n/*\n * VM initialization functions.\n *\n * Note these are the only symbols exported for JNI by the VM.\n */\njint JNI_GetDefaultJavaVMInitArgs(void*);\njint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);\njint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*);\n\n#define JNIIMPORT\n#define JNIEXPORT  __attribute__ ((visibility (\"default\")))\n#define JNICALL\n\n/*\n * Prototypes for functions exported by loadable shared libs.  These are\n * called by JNI, not provided by JNI.\n */\nJNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved);\nJNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved);\n\n#ifdef __cplusplus\n}\n#endif\n\n\n/*\n * Manifest constants.\n */\n#define JNI_FALSE   0\n#define JNI_TRUE    1\n\n#define JNI_VERSION_1_1 0x00010001\n#define JNI_VERSION_1_2 0x00010002\n#define JNI_VERSION_1_4 0x00010004\n#define JNI_VERSION_1_6 0x00010006\n\n#define JNI_OK          (0)         /* no error */\n#define JNI_ERR         (-1)        /* generic error */\n#define JNI_EDETACHED   (-2)        /* thread detached from the VM */\n#define JNI_EVERSION    (-3)        /* JNI version error */\n\n#define JNI_COMMIT      1           /* copy content, do not free buffer */\n#define JNI_ABORT       2           /* free buffer w/o copying back */\n\n#endif  /* JNI_H_ */\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/include/nativehelper/toStringArray.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef TO_STRING_ARRAY_H_included\n#define TO_STRING_ARRAY_H_included\n\n#include \"jni.h\"\n#include \"ScopedLocalRef.h\"\n\n#include <string>\n#include <vector>\n\njobjectArray newStringArray(JNIEnv* env, size_t count);\n\ntemplate <typename Counter, typename Getter>\njobjectArray toStringArray(JNIEnv* env, Counter* counter, Getter* getter) {\n    size_t count = (*counter)();\n    jobjectArray result = newStringArray(env, count);\n    if (result == NULL) {\n        return NULL;\n    }\n    for (size_t i = 0; i < count; ++i) {\n        ScopedLocalRef<jstring> s(env, env->NewStringUTF((*getter)(i)));\n        if (env->ExceptionCheck()) {\n            return NULL;\n        }\n        env->SetObjectArrayElement(result, i, s.get());\n        if (env->ExceptionCheck()) {\n            return NULL;\n        }\n    }\n    return result;\n}\n\nstruct VectorCounter {\n    const std::vector<std::string>& strings;\n    VectorCounter(const std::vector<std::string>& strings) : strings(strings) {}\n    size_t operator()() {\n        return strings.size();\n    }\n};\nstruct VectorGetter {\n    const std::vector<std::string>& strings;\n    VectorGetter(const std::vector<std::string>& strings) : strings(strings) {}\n    const char* operator()(size_t i) {\n        return strings[i].c_str();\n    }\n};\n\ninline jobjectArray toStringArray(JNIEnv* env, const std::vector<std::string>& strings) {\n    VectorCounter counter(strings);\n    VectorGetter getter(strings);\n    return toStringArray<VectorCounter, VectorGetter>(env, &counter, &getter);\n}\n\nJNIEXPORT jobjectArray toStringArray(JNIEnv* env, const char* const* strings);\n\n#endif  // TO_STRING_ARRAY_H_included\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/tests/Android.mk",
    "content": "# Build the unit tests.\nLOCAL_PATH := $(call my-dir)\ninclude $(CLEAR_VARS)\n\n# Target unit test.\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := JniInvocation_test\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := JniInvocation_test.cpp\nLOCAL_SHARED_LIBRARIES := libnativehelper\ninclude $(BUILD_NATIVE_TEST)\n\n# Host unit test.\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := JniInvocation_test\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := JniInvocation_test.cpp\nLOCAL_SHARED_LIBRARIES := libnativehelper\ninclude $(BUILD_HOST_NATIVE_TEST)\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/tests/JniInvocation_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"NativeBridge_test\"\n\n#include <JniInvocation.h>\n#include <gtest/gtest.h>\n\n\n#include \"string.h\"\n\n#if defined(__ANDROID__) && defined(__BIONIC__)\n#define HAVE_TEST_STUFF 1\n#else\n#undef HAVE_TEST_STUFF\n#endif\n\n#ifdef HAVE_TEST_STUFF\n\n// PROPERTY_VALUE_MAX.\n#include \"cutils/properties.h\"\n\n// Ability to have fake local system properties.\n#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_\n#include <sys/_system_properties.h>\n\nextern void *__system_property_area__;\n\nstruct LocalPropertyTestState {\n    LocalPropertyTestState() : valid(false) {\n        const char* ANDROID_DATA = getenv(\"ANDROID_DATA\");\n        char dir_template[PATH_MAX];\n        snprintf(dir_template, sizeof(dir_template), \"%s/local/tmp/prop-XXXXXX\", ANDROID_DATA);\n        char* dirname = mkdtemp(dir_template);\n        if (!dirname) {\n            fprintf(stderr, \"making temp file for test state failed (is %s writable?): %s\",\n                    dir_template, strerror(errno));\n            return;\n        }\n\n        old_pa = __system_property_area__;\n        __system_property_area__ = NULL;\n\n        pa_dirname = dirname;\n        pa_filename = pa_dirname + \"/__properties__\";\n\n        __system_property_set_filename(pa_filename.c_str());\n        __system_property_area_init();\n        valid = true;\n    }\n\n    ~LocalPropertyTestState() {\n        if (!valid) {\n            return;\n        }\n\n        __system_property_area__ = old_pa;\n\n        __system_property_set_filename(PROP_FILENAME);\n        unlink(pa_filename.c_str());\n        rmdir(pa_dirname.c_str());\n    }\npublic:\n    bool valid;\nprivate:\n    std::string pa_dirname;\n    std::string pa_filename;\n    void *old_pa;\n};\n#endif\n\nnamespace android {\n\nclass JNIInvocationTest : public testing::Test {\n};\n\n#ifdef HAVE_TEST_STUFF\nstatic const char* kDebuggableSystemProperty = \"ro.debuggable\";\nstatic const char* kIsDebuggableValue = \"1\";\nstatic const char* kIsNotDebuggableValue = \"0\";\n\nstatic const char* kLibrarySystemProperty = \"persist.sys.dalvik.vm.lib.2\";\nstatic const char* kTestNonNull = \"libartd.so\";\nstatic const char* kTestNonNull2 = \"libartd2.so\";\nstatic const char* kExpected = \"libart.so\";\n#endif\n\nTEST_F(JNIInvocationTest, Debuggable) {\n#ifdef HAVE_TEST_STUFF\n    LocalPropertyTestState pa;\n    ASSERT_TRUE(pa.valid);\n    ASSERT_EQ(0, __system_property_add(kDebuggableSystemProperty, 13, kIsDebuggableValue, 1));\n    ASSERT_EQ(0, __system_property_add(kLibrarySystemProperty, 27, kTestNonNull2, 11));\n\n    char buffer[PROPERTY_VALUE_MAX];\n    const char* result = JniInvocation::GetLibrary(NULL, buffer);\n    EXPECT_FALSE(result == NULL);\n    if (result != NULL) {\n        EXPECT_TRUE(strcmp(result, kTestNonNull2) == 0);\n        EXPECT_FALSE(strcmp(result, kExpected) == 0);\n    }\n\n    result = JniInvocation::GetLibrary(kTestNonNull, buffer);\n    EXPECT_FALSE(result == NULL);\n    if (result != NULL) {\n        EXPECT_TRUE(strcmp(result, kTestNonNull) == 0);\n        EXPECT_FALSE(strcmp(result, kTestNonNull2) == 0);\n    }\n#else\n    GTEST_LOG_(WARNING) << \"Host testing unsupported. Please run target tests.\";\n#endif\n}\n\nTEST_F(JNIInvocationTest, NonDebuggable) {\n#ifdef HAVE_TEST_STUFF\n    LocalPropertyTestState pa;\n    ASSERT_TRUE(pa.valid);\n    ASSERT_EQ(0, __system_property_add(kDebuggableSystemProperty, 13, kIsNotDebuggableValue, 1));\n\n    char buffer[PROPERTY_VALUE_MAX];\n    const char* result = JniInvocation::GetLibrary(NULL, buffer);\n    EXPECT_FALSE(result == NULL);\n    if (result != NULL) {\n        EXPECT_TRUE(strcmp(result, kExpected) == 0);\n        EXPECT_FALSE(strcmp(result, kTestNonNull) == 0);\n        EXPECT_FALSE(strcmp(result, kTestNonNull2) == 0);\n    }\n\n    result = JniInvocation::GetLibrary(kTestNonNull, buffer);\n    EXPECT_FALSE(result == NULL);\n    if (result != NULL) {\n        EXPECT_TRUE(strcmp(result, kExpected) == 0);\n        EXPECT_FALSE(strcmp(result, kTestNonNull) == 0);\n    }\n#else\n    GTEST_LOG_(WARNING) << \"Host testing unsupported. Please run target tests.\";\n#endif\n}\n\n}  // namespace android\n"
  },
  {
    "path": "atlas-aapt/libnativehelper/toStringArray.cpp",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"JniConstants.h\"\n#include \"toStringArray.h\"\n\njobjectArray newStringArray(JNIEnv* env, size_t count) {\n    return env->NewObjectArray(count, JniConstants::stringClass, NULL);\n}\n\nstruct ArrayCounter {\n    const char* const* strings;\n    ArrayCounter(const char* const* strings) : strings(strings) {}\n    size_t operator()() {\n        size_t count = 0;\n        while (strings[count] != NULL) {\n            ++count;\n        }\n        return count;\n    }\n};\n\nstruct ArrayGetter {\n    const char* const* strings;\n    ArrayGetter(const char* const* strings) : strings(strings) {}\n    const char* operator()(size_t i) {\n        return strings[i];\n    }\n};\n\njobjectArray toStringArray(JNIEnv* env, const char* const* strings) {\n    ArrayCounter counter(strings);\n    ArrayGetter getter(strings);\n    return toStringArray(env, &counter, &getter);\n}\n"
  },
  {
    "path": "atlas-aapt/patch/0001-patch-code.patch",
    "content": "From 169d35c037957b9399a624657d4e3236002d08e8 Mon Sep 17 00:00:00 2001\nFrom: Rover12421 <rover12421@163.com>\nDate: Wed, 18 Nov 2015 16:59:29 +0800\nSubject: [PATCH] patch code\n\n---\n development/build/tools/windows_sdk.mk           |  3 ++\n external/expat/lib/xmltok.c                      | 12 +++++\n frameworks/base/libs/androidfw/AssetManager.cpp  | 13 +++--\n frameworks/base/libs/androidfw/ResourceTypes.cpp | 10 ++++\n frameworks/base/tools/aapt/AaptAssets.cpp        |  3 ++\n frameworks/base/tools/aapt/AaptAssets.h          |  3 ++\n frameworks/base/tools/aapt/AaptConfig.cpp        | 40 ++++++++++++++-\n frameworks/base/tools/aapt/Bundle.h              | 12 +++++\n frameworks/base/tools/aapt/Main.cpp              | 18 +++++++\n frameworks/base/tools/aapt/Resource.cpp          | 58 ++++++++++++++++-----\n frameworks/base/tools/aapt/ResourceTable.cpp     | 64 ++++++++++++++++++------\n 11 files changed, 204 insertions(+), 32 deletions(-)\n\ndiff --git a/development/build/tools/windows_sdk.mk b/development/build/tools/windows_sdk.mk\nindex 7d586a8..8734b56 100644\n--- a/development/build/tools/windows_sdk.mk\n+++ b/development/build/tools/windows_sdk.mk\n@@ -42,6 +42,9 @@ WIN_TARGETS := \\\n \tsplit-select \\\n \t$(WIN_SDK_TARGETS)\n \n+#[Rover12421]>\n+WIN_TARGETS := aapt\n+#[Rover12421]<\n WIN_TARGETS := $(foreach t,$(WIN_TARGETS),$(ALL_MODULES.host_cross_$(t).INSTALLED))\n \n # MAIN_SDK_NAME/DIR is set in build/core/Makefile\ndiff --git a/external/expat/lib/xmltok.c b/external/expat/lib/xmltok.c\nindex bf09dfc..f359ecf 100644\n--- a/external/expat/lib/xmltok.c\n+++ b/external/expat/lib/xmltok.c\n@@ -273,6 +273,18 @@ sb_byteToAscii(const ENCODING *enc, const char *p)\n #define IS_INVALID_CHAR(enc, p, n) \\\n  (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p))\n \n+//[Rover12421]>\n+#ifdef IS_NAME_CHAR\n+#undef IS_NAME_CHAR\n+#endif\n+#define IS_NAME_CHAR(enc, p, n) (1)\n+\n+#ifdef IS_INVALID_CHAR\n+#undef IS_INVALID_CHAR\n+#endif\n+#define IS_INVALID_CHAR(enc, p, n) (0)\n+//[Rover12421]<\n+\n #ifdef XML_MIN_SIZE\n #define IS_NAME_CHAR_MINBPC(enc, p) \\\n  (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))\ndiff --git a/frameworks/base/libs/androidfw/AssetManager.cpp b/frameworks/base/libs/androidfw/AssetManager.cpp\nindex 623ea89..8bf6f05 100644\n--- a/frameworks/base/libs/androidfw/AssetManager.cpp\n+++ b/frameworks/base/libs/androidfw/AssetManager.cpp\n@@ -215,12 +215,17 @@ bool AssetManager::addAssetPath(const String8& path, int32_t* cookie)\n     // Check that the path has an AndroidManifest.xml\n     Asset* manifestAsset = const_cast<AssetManager*>(this)->openNonAssetInPathLocked(\n             kAndroidManifest, Asset::ACCESS_BUFFER, ap);\n-    if (manifestAsset == NULL) {\n-        // This asset path does not contain any resources.\n+    //[Rover12421]>\n+//    if (manifestAsset == NULL) {\n+//        // This asset path does not contain any resources.\n+//        delete manifestAsset;\n+//        return false;\n+//    }\n+//    delete manifestAsset;\n+    if (manifestAsset != NULL) {\n         delete manifestAsset;\n-        return false;\n     }\n-    delete manifestAsset;\n+    //[Rover12421]<\n \n     mAssetPaths.add(ap);\n \ndiff --git a/frameworks/base/libs/androidfw/ResourceTypes.cpp b/frameworks/base/libs/androidfw/ResourceTypes.cpp\nindex 806eeda..c8abf0d 100644\n--- a/frameworks/base/libs/androidfw/ResourceTypes.cpp\n+++ b/frameworks/base/libs/androidfw/ResourceTypes.cpp\n@@ -5065,6 +5065,16 @@ bool ResTable::stringToValue(Res_value* outValue, String16* outString,\n                         outValue->data = rid;\n                         return true;\n                     }\n+                    //[Rover12421]>\n+                    if (packageId > 0) {\n+                        /**\n+                         * 只要packageId>0是正常的即可\n+                         * 原罗辑packageId实际是package类型了.只有0x00(库),0x7f(app),0x01(系统)三种了\n+                         */\n+                        outValue->data = rid;\n+                        return true;\n+                    }\n+                    //[Rover12421]<\n                 }\n             }\n         }\ndiff --git a/frameworks/base/tools/aapt/AaptAssets.cpp b/frameworks/base/tools/aapt/AaptAssets.cpp\nindex d346731..e1453b1 100644\n--- a/frameworks/base/tools/aapt/AaptAssets.cpp\n+++ b/frameworks/base/tools/aapt/AaptAssets.cpp\n@@ -739,6 +739,9 @@ ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir,\n \n status_t AaptDir::validate() const\n {\n+    //[Rover12421]>\n+    return NO_ERROR;\n+    //[Rover12421]<\n     const size_t NF = mFiles.size();\n     const size_t ND = mDirs.size();\n     size_t i;\ndiff --git a/frameworks/base/tools/aapt/AaptAssets.h b/frameworks/base/tools/aapt/AaptAssets.h\nindex 4fdc964..9264097 100644\n--- a/frameworks/base/tools/aapt/AaptAssets.h\n+++ b/frameworks/base/tools/aapt/AaptAssets.h\n@@ -460,6 +460,9 @@ public:\n \n private:\n     bool check_valid_symbol_name(const String8& symbol, const SourcePos& pos, const char* label) {\n+        //[Rover12421]>\n+        return true;\n+        //[Rover12421]<\n         if (valid_symbol_name(symbol)) {\n             return true;\n         }\ndiff --git a/frameworks/base/tools/aapt/AaptConfig.cpp b/frameworks/base/tools/aapt/AaptConfig.cpp\nindex b12867a..d4e088e 100644\n--- a/frameworks/base/tools/aapt/AaptConfig.cpp\n+++ b/frameworks/base/tools/aapt/AaptConfig.cpp\n@@ -244,6 +244,12 @@ bool parseCommaSeparatedList(const String8& str, std::set<ConfigDescription>* ou\n }\n \n void applyVersionForCompatibility(ConfigDescription* config) {\n+    //[Rover12421]>\n+    /**\n+     * Prevent implicit addition of version qualifiers\n+     */\n+    return;\n+    //[Rover12421]<\n     if (config == NULL) {\n         return;\n     }\n@@ -294,7 +300,10 @@ bool parseMcc(const char* name, ResTable_config* out) {\n         c++;\n     }\n     if (*c != 0) return false;\n-    if (c-val != 3) return false;\n+    //[Rover12421]>\n+    //if (c-val != 3) return false;\n+    if (c-val != 3 && c-val != 4) return false;\n+    //[Rover12421]<\n \n     int d = atoi(val);\n     if (d != 0) {\n@@ -324,7 +333,10 @@ bool parseMnc(const char* name, ResTable_config* out) {\n         c++;\n     }\n     if (*c != 0) return false;\n-    if (c-val == 0 || c-val > 3) return false;\n+    //[Rover12421]>\n+    //if (c-val == 0 || c-val > 3) return false;\n+    if (c-val == 0 || c-val > 4) return false;\n+    //[Rover12421]<\n \n     if (out) {\n         out->mnc = atoi(val);\n@@ -478,6 +490,30 @@ bool parseUiModeType(const char* name, ResTable_config* out) {\n               | ResTable_config::UI_MODE_TYPE_WATCH;\n         return true;\n     }\n+    //[Rover12421]> port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n+    else if (strcmp(name, \"smallui\") == 0) {\n+        if (out) out->uiMode =\n+                         (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n+                         | 0xc;\n+        return true;\n+    } else if (strcmp(name, \"mediumui\") == 0) {\n+        if (out) out->uiMode =\n+                         (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n+                         | 0xd;\n+        return true;\n+    } else if (strcmp(name, \"largeui\") == 0) {\n+        if (out) out->uiMode =\n+                         (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n+                         | 0xe;\n+        return true;\n+    } else if (strcmp(name, \"hugeui\") == 0) {\n+        if (out) out->uiMode = 0xf;\n+        return true;\n+    } else if (strcmp(name, \"godzillaui\") == 0) {\n+        if (out) out->uiMode = 0xb;\n+        return true;\n+    }\n+    //[Rover12421]< port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n \n     return false;\n }\ndiff --git a/frameworks/base/tools/aapt/Bundle.h b/frameworks/base/tools/aapt/Bundle.h\nindex cbe7c5d..062f88e 100644\n--- a/frameworks/base/tools/aapt/Bundle.h\n+++ b/frameworks/base/tools/aapt/Bundle.h\n@@ -66,6 +66,9 @@ public:\n           mErrorOnMissingConfigEntry(false), mOutputTextSymbols(NULL),\n           mSingleCrunchInputFile(NULL), mSingleCrunchOutputFile(NULL),\n           mBuildSharedLibrary(false),\n+          //[Rover12421]> port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n+          mForcedPackageId(-1),\n+          //[Rover12421]< port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n           mArgc(0), mArgv(NULL)\n         {}\n     ~Bundle(void) {}\n@@ -209,6 +212,11 @@ public:\n     void setNoVersionVectors(bool val) { mNoVersionVectors = val; }\n     bool getNoVersionVectors() const { return mNoVersionVectors; }\n \n+    //[Rover12421]> port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n+    int getForcedPackageId() const { return mForcedPackageId; }\n+    void setForcedPackageId(int val) { mForcedPackageId = val; }\n+    //[Rover12421]< port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n+\n     /*\n      * Set and get the file specification.\n      *\n@@ -330,6 +338,10 @@ private:\n     android::String8 mPlatformVersionCode;\n     android::String8 mPlatformVersionName;\n \n+    //[Rover12421]> port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n+    int \t    mForcedPackageId;\n+    //[Rover12421]< port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n+\n     /* file specification */\n     int         mArgc;\n     char* const* mArgv;\ndiff --git a/frameworks/base/tools/aapt/Main.cpp b/frameworks/base/tools/aapt/Main.cpp\nindex bcf0d5e..d234bea 100644\n--- a/frameworks/base/tools/aapt/Main.cpp\n+++ b/frameworks/base/tools/aapt/Main.cpp\n@@ -60,6 +60,9 @@ void usage(void)\n         \" %s p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] \\\\\\n\"\n         \"        [-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] \\\\\\n\"\n         \"        [--debug-mode] [--min-sdk-version VAL] [--target-sdk-version VAL] \\\\\\n\"\n+        //[Rover12421]> port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n+        \"        [--forced-package-id VAL] \\\\\\n\"\n+        //[Rover12421]< port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n         \"        [--app-version VAL] [--app-version-name TEXT] [--custom-package VAL] \\\\\\n\"\n         \"        [--rename-manifest-package PACKAGE] \\\\\\n\"\n         \"        [--rename-instrumentation-target-package PACKAGE] \\\\\\n\"\n@@ -142,6 +145,10 @@ void usage(void)\n         \"       higher, the default encoding for resources will be in UTF-8.\\n\"\n         \"   --target-sdk-version\\n\"\n         \"       inserts android:targetSdkVersion in to manifest.\\n\"\n+        //[Rover12421]> port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n+        \"   --forced-package-id\\n\"\n+        \"       forces value as package-id\\n\"\n+        //[Rover12421]< port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n         \"   --max-res-version\\n\"\n         \"       ignores versioned resource directories above the given value.\\n\"\n         \"   --values\\n\"\n@@ -501,6 +508,17 @@ int main(int argc, char* const argv[])\n             case '-':\n                 if (strcmp(cp, \"-debug-mode\") == 0) {\n                     bundle.setDebugMode(true);\n+                //[Rover12421]> port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n+                } else if (strcmp(cp, \"-forced-package-id\") == 0) {\n+                    argc--;\n+                    argv++;\n+                    if (!argc) {\n+                        fprintf(stderr, \"ERROR: No argument supplied for '--forced-package-id' option\\n\");\n+                        wantUsage = true;\n+                        goto bail;\n+                    }\n+                    bundle.setForcedPackageId(atoi(argv[0]));\n+                //[Rover12421]< port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n                 } else if (strcmp(cp, \"-min-sdk-version\") == 0) {\n                     argc--;\n                     argv++;\ndiff --git a/frameworks/base/tools/aapt/Resource.cpp b/frameworks/base/tools/aapt/Resource.cpp\nindex a4e5d3d..a3280f2 100644\n--- a/frameworks/base/tools/aapt/Resource.cpp\n+++ b/frameworks/base/tools/aapt/Resource.cpp\n@@ -64,6 +64,28 @@ String8 parseResourceName(const String8& leaf)\n     const char* firstDot = strchr(leaf.string(), '.');\n     const char* str = leaf.string();\n \n+    //[Rover12421]>\n+    while (firstDot) {\n+        const char* secondDot = strchr(firstDot+1, '.');\n+        if (secondDot) {\n+            const char* thridDot = strchr(secondDot+1, '.');\n+            if (thridDot) {\n+                firstDot = secondDot;\n+            } else {\n+                if (secondDot - firstDot == 2 && *(firstDot+1) == '9') {\n+                    //过滤.9.x的扩展\n+                    break;\n+                } else {\n+                    firstDot = secondDot;\n+                    break;\n+                }\n+            }\n+        } else {\n+            break;\n+        }\n+    }\n+    //[Rover12421]<\n+\n     if (firstDot) {\n         return String8(str, firstDot-str);\n     } else {\n@@ -312,18 +334,20 @@ static status_t makeFileResources(Bundle* bundle, const sp<AaptAssets>& assets,\n                    it.getBaseName().string(), it.getFile()->getPrintableSource().string());\n         }\n         String16 baseName(it.getBaseName());\n-        const char16_t* str = baseName.string();\n-        const char16_t* const end = str + baseName.size();\n-        while (str < end) {\n-            if (!((*str >= 'a' && *str <= 'z')\n-                    || (*str >= '0' && *str <= '9')\n-                    || *str == '_' || *str == '.')) {\n-                fprintf(stderr, \"%s: Invalid file name: must contain only [a-z0-9_.]\\n\",\n-                        it.getPath().string());\n-                hasErrors = true;\n-            }\n-            str++;\n-        }\n+        //[Rover12421]>\n+//        const char16_t* str = baseName.string();\n+//        const char16_t* const end = str + baseName.size();\n+//        while (str < end) {\n+//            if (!((*str >= 'a' && *str <= 'z')\n+//                    || (*str >= '0' && *str <= '9')\n+//                    || *str == '_' || *str == '.')) {\n+//                fprintf(stderr, \"%s: Invalid file name: must contain only [a-z0-9_.]\\n\",\n+//                        it.getPath().string());\n+//                hasErrors = true;\n+//            }\n+//            str++;\n+//        }\n+        //[Rover12421]<\n         String8 resPath = it.getPath();\n         resPath.convertToResPath();\n         table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()),\n@@ -477,6 +501,9 @@ static int validateAttr(const String8& path, const ResTable& table,\n         const ResXMLParser& parser,\n         const char* ns, const char* attr, const char* validChars, bool required)\n {\n+    //[Rover12421]>\n+    return ATTR_OKAY;\n+    //[Rover12421]<\n     size_t len;\n \n     ssize_t index = parser.indexOfAttribute(ns, attr);\n@@ -1031,6 +1058,13 @@ static ssize_t extractPlatformBuildVersion(AssetManager& assets, Bundle* bundle)\n     ResXMLTree tree;\n     Asset* asset = assets.openNonAsset(cookie, \"AndroidManifest.xml\", Asset::ACCESS_STREAMING);\n     if (asset == NULL) {\n+        //[Rover12421]>\n+        /**\n+         * Remove limitations on host side tools\n+         * - Allows Apktool framework files (only containing resources.arsc) to work\n+         */\n+        return NO_ERROR;\n+        //[Rover12421]<\n         fprintf(stderr, \"ERROR: Platform AndroidManifest.xml not found\\n\");\n         return UNKNOWN_ERROR;\n     }\ndiff --git a/frameworks/base/tools/aapt/ResourceTable.cpp b/frameworks/base/tools/aapt/ResourceTable.cpp\nindex d5a09d8..a60b741 100644\n--- a/frameworks/base/tools/aapt/ResourceTable.cpp\n+++ b/frameworks/base/tools/aapt/ResourceTable.cpp\n@@ -1761,24 +1761,54 @@ ResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage, Reso\n     , mBundle(bundle)\n {\n     ssize_t packageId = -1;\n-    switch (mPackageType) {\n-        case App:\n-        case AppFeature:\n-            packageId = 0x7f;\n-            break;\n+    //[Rover12421]> port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n+    packageId = mBundle->getForcedPackageId();\n+    /**\n+     * port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n+     * 的时候是`packageId == -1`\n+     * [skip] only get packageId, if forced isn't passed\n+     * #25db569 的时候修改为`packageId == -1`\n+     */\n+    if (packageId == -1) {\n+//    ssize_t packageId = -1;\n+        switch (mPackageType) {\n+            case App:\n+            case AppFeature:\n+                packageId = 0x7f;\n+                break;\n \n-        case System:\n-            packageId = 0x01;\n-            break;\n+            case System:\n+                packageId = 0x01;\n+                break;\n \n-        case SharedLibrary:\n-            packageId = 0x00;\n-            break;\n+            case SharedLibrary:\n+                packageId = 0x00;\n+                break;\n \n-        default:\n-            assert(0);\n-            break;\n+            default:\n+                assert(0);\n+                break;\n+        }\n     }\n+//    switch (mPackageType) {\n+//        case App:\n+//        case AppFeature:\n+//            packageId = 0x7f;\n+//            break;\n+//\n+//        case System:\n+//            packageId = 0x01;\n+//            break;\n+//\n+//        case SharedLibrary:\n+//            packageId = 0x00;\n+//            break;\n+//\n+//        default:\n+//            assert(0);\n+//            break;\n+//    }\n+    //[Rover12421]< port 549aeb943bb64c59a9b9f557e9166195bdda30d4 to lollipop\n     sp<Package> package = new Package(mAssetsPackage, packageId);\n     mPackages.add(assetsPackage, package);\n     mOrderedPackages.add(package);\n@@ -4541,6 +4571,9 @@ bool ResourceTable::shouldGenerateVersionedResource(\n  * attribute will be respected.\n  */\n status_t ResourceTable::modifyForCompat(const Bundle* bundle) {\n+    //[Rover12421]>\n+    return NO_ERROR;\n+    //[Rover12421]<\n     const int minSdk = getMinSdkVersion(bundle);\n     if (minSdk >= SDK_LOLLIPOP_MR1) {\n         // Lollipop MR1 and up handles public attributes differently, no\n@@ -4675,6 +4708,9 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle,\n                                         const String16& resourceName,\n                                         const sp<AaptFile>& target,\n                                         const sp<XMLNode>& root) {\n+    //[Rover12421]>\n+    return NO_ERROR;\n+    //[Rover12421]<\n     const String16 vector16(\"vector\");\n     const String16 animatedVector16(\"animated-vector\");\n \n-- \n1.9.1\n\n"
  },
  {
    "path": "atlas-aapt/patch/0002-static-build.patch",
    "content": "From d89cdb131f04ae547f05b92fb519a5e4a90c4f01 Mon Sep 17 00:00:00 2001\nFrom: Rover12421 <rover12421@163.com>\nDate: Wed, 18 Nov 2015 17:21:45 +0800\nSubject: [PATCH] static build\n\n---\n frameworks/base/tools/aapt/Android.mk | 5 +++++\n 1 file changed, 5 insertions(+)\n\ndiff --git a/frameworks/base/tools/aapt/Android.mk b/frameworks/base/tools/aapt/Android.mk\nindex b701445..3276108 100644\n--- a/frameworks/base/tools/aapt/Android.mk\n+++ b/frameworks/base/tools/aapt/Android.mk\n@@ -106,6 +106,11 @@ LOCAL_LDLIBS_linux := $(aaptHostLdLibs_linux)\n LOCAL_SRC_FILES := $(aaptMain)\n LOCAL_STATIC_LIBRARIES := libaapt $(aaptHostStaticLibs)\n LOCAL_STATIC_LIBRARIES_windows := $(aaptHostStaticLibs_windows)\n+#[Rover12421]>\n+ifneq ($($(my_prefix)OS),windows)\n+LOCAL_CXX_STL := libc++_static\n+endif\n+#[Rover12421]<\n \n include $(BUILD_HOST_EXECUTABLE)\n \n-- \n1.9.1\n\n"
  },
  {
    "path": "atlas-aapt/patch/003-rewrite-parseResourceName.patch",
    "content": "From 981e647c95e59a133c88da952142167d24aa0ccf Mon Sep 17 00:00:00 2001\nFrom: Rover12421 <rover12421@163.com>\nDate: Thu, 19 Nov 2015 13:07:56 +0800\nSubject: [PATCH] rewrite parseResourceName. support htc .r.9.png\n\npass drawableXhdpiTest\n---\n frameworks/base/tools/aapt/Resource.cpp | 29 ++++++++++++++---------------\n 1 file changed, 14 insertions(+), 15 deletions(-)\n\ndiff --git a/frameworks/base/tools/aapt/Resource.cpp b/frameworks/base/tools/aapt/Resource.cpp\nindex a3280f2..9509bef 100644\n--- a/frameworks/base/tools/aapt/Resource.cpp\n+++ b/frameworks/base/tools/aapt/Resource.cpp\n@@ -65,23 +65,22 @@ String8 parseResourceName(const String8& leaf)\n     const char* str = leaf.string();\n \n     //[Rover12421]>\n-    while (firstDot) {\n-        const char* secondDot = strchr(firstDot+1, '.');\n-        if (secondDot) {\n-            const char* thridDot = strchr(secondDot+1, '.');\n-            if (thridDot) {\n-                firstDot = secondDot;\n-            } else {\n-                if (secondDot - firstDot == 2 && *(firstDot+1) == '9') {\n-                    //过滤.9.x的扩展\n-                    break;\n-                } else {\n-                    firstDot = secondDot;\n-                    break;\n+    //最后一个.作为分割\n+    firstDot = strrchr(str, '.');\n+    if (firstDot) {\n+        size_t len = strlen(str);\n+        size_t extLen = strlen(firstDot);\n+        if (len > extLen+2) {\n+            const char* end9 = str + (len-(extLen+2));\n+            if (end9[0] == '.' && end9[1] == '9') {\n+                firstDot = end9;\n+                if (len > extLen+4) {\n+                    const char* endr = str + (len-(extLen+4));\n+                    if (endr[0] == '.' && endr[1] == 'r') {\n+                        firstDot = endr;\n+                    }\n                 }\n             }\n-        } else {\n-            break;\n         }\n     }\n     //[Rover12421]<\n-- \n1.9.1\n\n"
  },
  {
    "path": "atlas-aapt/system/core/base/.clang-format",
    "content": "BasedOnStyle: Google\nAllowShortBlocksOnASingleLine: false\nAllowShortFunctionsOnASingleLine: false\n\nCommentPragmas: NOLINT:.*\nDerivePointerAlignment: false\nIndentWidth: 2\nPointerAlignment: Left\nTabWidth: 2\nUseTab: Never\nPenaltyExcessCharacter: 32\n"
  },
  {
    "path": "atlas-aapt/system/core/base/Android.mk",
    "content": "#\n# Copyright (C) 2015 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\nLOCAL_PATH := $(call my-dir)\n\nlibbase_src_files := \\\n    file.cpp \\\n    logging.cpp \\\n    parsenetaddress.cpp \\\n    stringprintf.cpp \\\n    strings.cpp \\\n    test_utils.cpp \\\n\nlibbase_linux_src_files := \\\n    errors_unix.cpp \\\n\nlibbase_darwin_src_files := \\\n    errors_unix.cpp \\\n\nlibbase_windows_src_files := \\\n    errors_windows.cpp \\\n    utf8.cpp \\\n\nlibbase_test_src_files := \\\n    errors_test.cpp \\\n    file_test.cpp \\\n    logging_test.cpp \\\n    parseint_test.cpp \\\n    parsenetaddress_test.cpp \\\n    stringprintf_test.cpp \\\n    strings_test.cpp \\\n    test_main.cpp \\\n\nlibbase_test_windows_src_files := \\\n    utf8_test.cpp \\\n\nlibbase_cppflags := \\\n    -Wall \\\n    -Wextra \\\n    -Werror \\\n\nlibbase_linux_cppflags := \\\n    -Wexit-time-destructors \\\n\nlibbase_darwin_cppflags := \\\n    -Wexit-time-destructors \\\n\n# Device\n# ------------------------------------------------------------------------------\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libbase\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := $(libbase_src_files) $(libbase_linux_src_files)\nLOCAL_C_INCLUDES := $(LOCAL_PATH)/include\nLOCAL_CPPFLAGS := $(libbase_cppflags) $(libbase_linux_cppflags)\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include\nLOCAL_STATIC_LIBRARIES := liblog\nLOCAL_MULTILIB := both\ninclude $(BUILD_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libbase\nLOCAL_CLANG := true\nLOCAL_WHOLE_STATIC_LIBRARIES := libbase\nLOCAL_SHARED_LIBRARIES := liblog\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include\nLOCAL_MULTILIB := both\ninclude $(BUILD_SHARED_LIBRARY)\n\n# Host\n# ------------------------------------------------------------------------------\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libbase\nLOCAL_SRC_FILES := $(libbase_src_files)\nLOCAL_SRC_FILES_darwin := $(libbase_darwin_src_files)\nLOCAL_SRC_FILES_linux := $(libbase_linux_src_files)\nLOCAL_SRC_FILES_windows := $(libbase_windows_src_files)\nLOCAL_C_INCLUDES := $(LOCAL_PATH)/include\nLOCAL_CPPFLAGS := $(libbase_cppflags)\nLOCAL_CPPFLAGS_darwin := $(libbase_darwin_cppflags)\nLOCAL_CPPFLAGS_linux := $(libbase_linux_cppflags)\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include\nLOCAL_STATIC_LIBRARIES := liblog\nLOCAL_MULTILIB := both\nLOCAL_MODULE_HOST_OS := darwin linux windows\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libbase\nLOCAL_WHOLE_STATIC_LIBRARIES := libbase\nLOCAL_SHARED_LIBRARIES := liblog\nLOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include\nLOCAL_MULTILIB := both\nLOCAL_MODULE_HOST_OS := darwin linux windows\ninclude $(BUILD_HOST_SHARED_LIBRARY)\n\n# Tests\n# ------------------------------------------------------------------------------\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libbase_test\nLOCAL_CLANG := true\nLOCAL_SRC_FILES := $(libbase_test_src_files)\nLOCAL_SRC_FILES_darwin := $(libbase_test_darwin_src_files)\nLOCAL_SRC_FILES_linux := $(libbase_test_linux_src_files)\nLOCAL_SRC_FILES_windows := $(libbase_test_windows_src_files)\nLOCAL_C_INCLUDES := $(LOCAL_PATH)\nLOCAL_CPPFLAGS := $(libbase_cppflags)\nLOCAL_SHARED_LIBRARIES := libbase\nLOCAL_MULTILIB := both\nLOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32\nLOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64\ninclude $(BUILD_NATIVE_TEST)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libbase_test\nLOCAL_MODULE_HOST_OS := darwin linux windows\nLOCAL_SRC_FILES := $(libbase_test_src_files)\nLOCAL_SRC_FILES_darwin := $(libbase_test_darwin_src_files)\nLOCAL_SRC_FILES_linux := $(libbase_test_linux_src_files)\nLOCAL_SRC_FILES_windows := $(libbase_test_windows_src_files)\nLOCAL_C_INCLUDES := $(LOCAL_PATH)\nLOCAL_CPPFLAGS := $(libbase_cppflags)\nLOCAL_SHARED_LIBRARIES := libbase\nLOCAL_MULTILIB := both\nLOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32\nLOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64\ninclude $(BUILD_HOST_NATIVE_TEST)\n"
  },
  {
    "path": "atlas-aapt/system/core/base/CPPLINT.cfg",
    "content": "set noparent\nfilter=-build/header_guard,-build/include,-build/c++11,-whitespace/operators\n"
  },
  {
    "path": "atlas-aapt/system/core/base/errors_test.cpp",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"android-base/errors.h\"\n\n#include <gtest/gtest.h>\n\nnamespace android {\nnamespace base {\n\n// Error strings aren't consistent enough across systems to test the output,\n// just make sure we can compile correctly and nothing crashes even if we send\n// it possibly bogus error codes.\nTEST(ErrorsTest, TestSystemErrorString) {\n  SystemErrorCodeToString(-1);\n  SystemErrorCodeToString(0);\n  SystemErrorCodeToString(1);\n}\n\n}  // namespace base\n}  // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/base/errors_unix.cpp",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"android-base/errors.h\"\n\n#include <errno.h>\n\nnamespace android {\nnamespace base {\n\nstd::string SystemErrorCodeToString(int error_code) {\n  return strerror(error_code);\n}\n\n}  // namespace base\n}  // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/base/errors_windows.cpp",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"android-base/errors.h\"\n\n#include <windows.h>\n\n#include \"android-base/stringprintf.h\"\n#include \"android-base/strings.h\"\n#include \"android-base/utf8.h\"\n\n// A Windows error code is a DWORD. It's simpler to use an int error code for\n// both Unix and Windows if possible, but if this fails we'll need a different\n// function signature for each.\nstatic_assert(sizeof(int) >= sizeof(DWORD),\n              \"Windows system error codes are too large to fit in an int.\");\n\nnamespace android {\nnamespace base {\n\nstatic constexpr DWORD kErrorMessageBufferSize = 256;\n\nstd::string SystemErrorCodeToString(int int_error_code) {\n  WCHAR msgbuf[kErrorMessageBufferSize];\n  DWORD error_code = int_error_code;\n  DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;\n  DWORD len = FormatMessageW(flags, nullptr, error_code, 0, msgbuf,\n                             kErrorMessageBufferSize, nullptr);\n  if (len == 0) {\n    return android::base::StringPrintf(\n        \"Error %lu while retrieving message for error %lu\", GetLastError(),\n        error_code);\n  }\n\n  // Convert UTF-16 to UTF-8.\n  std::string msg;\n  if (!android::base::WideToUTF8(msgbuf, &msg)) {\n    return android::base::StringPrintf(\n        \"Error %lu while converting message for error %lu from UTF-16 to UTF-8\",\n        GetLastError(), error_code);\n  }\n\n  // Messages returned by the system end with line breaks.\n  msg = android::base::Trim(msg);\n\n  // There are many Windows error messages compared to POSIX, so include the\n  // numeric error code for easier, quicker, accurate identification. Use\n  // decimal instead of hex because there are decimal ranges like 10000-11999\n  // for Winsock.\n  android::base::StringAppendF(&msg, \" (%lu)\", error_code);\n  return msg;\n}\n\n}  // namespace base\n}  // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/base/file.cpp",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"android-base/file.h\"\n\n#include <errno.h>\n#include <fcntl.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n\n#include <string>\n\n#include \"android-base/macros.h\"  // For TEMP_FAILURE_RETRY on Darwin.\n#include \"android-base/utf8.h\"\n#define LOG_TAG \"base.file\"\n#include \"cutils/log.h\"\n#include \"utils/Compat.h\"\n\nnamespace android {\nnamespace base {\n\n// Versions of standard library APIs that support UTF-8 strings.\nusing namespace android::base::utf8;\n\nbool ReadFdToString(int fd, std::string* content) {\n  content->clear();\n\n  char buf[BUFSIZ];\n  ssize_t n;\n  while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {\n    content->append(buf, n);\n  }\n  return (n == 0) ? true : false;\n}\n\nbool ReadFileToString(const std::string& path, std::string* content) {\n  content->clear();\n\n  int fd = TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_BINARY));\n  if (fd == -1) {\n    return false;\n  }\n  bool result = ReadFdToString(fd, content);\n  close(fd);\n  return result;\n}\n\nbool WriteStringToFd(const std::string& content, int fd) {\n  const char* p = content.data();\n  size_t left = content.size();\n  while (left > 0) {\n    ssize_t n = TEMP_FAILURE_RETRY(write(fd, p, left));\n    if (n == -1) {\n      return false;\n    }\n    p += n;\n    left -= n;\n  }\n  return true;\n}\n\nstatic bool CleanUpAfterFailedWrite(const std::string& path) {\n  // Something went wrong. Let's not leave a corrupt file lying around.\n  int saved_errno = errno;\n  unlink(path.c_str());\n  errno = saved_errno;\n  return false;\n}\n\n#if !defined(_WIN32)\nbool WriteStringToFile(const std::string& content, const std::string& path,\n                       mode_t mode, uid_t owner, gid_t group) {\n  int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY;\n  int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode));\n  if (fd == -1) {\n    ALOGE(\"android::WriteStringToFile open failed: %s\", strerror(errno));\n    return false;\n  }\n\n  // We do an explicit fchmod here because we assume that the caller really\n  // meant what they said and doesn't want the umask-influenced mode.\n  if (fchmod(fd, mode) == -1) {\n    ALOGE(\"android::WriteStringToFile fchmod failed: %s\", strerror(errno));\n    return CleanUpAfterFailedWrite(path);\n  }\n  if (fchown(fd, owner, group) == -1) {\n    ALOGE(\"android::WriteStringToFile fchown failed: %s\", strerror(errno));\n    return CleanUpAfterFailedWrite(path);\n  }\n  if (!WriteStringToFd(content, fd)) {\n    ALOGE(\"android::WriteStringToFile write failed: %s\", strerror(errno));\n    return CleanUpAfterFailedWrite(path);\n  }\n  close(fd);\n  return true;\n}\n#endif\n\nbool WriteStringToFile(const std::string& content, const std::string& path) {\n  int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY;\n  int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags, DEFFILEMODE));\n  if (fd == -1) {\n    return false;\n  }\n\n  bool result = WriteStringToFd(content, fd);\n  close(fd);\n  return result || CleanUpAfterFailedWrite(path);\n}\n\nbool ReadFully(int fd, void* data, size_t byte_count) {\n  uint8_t* p = reinterpret_cast<uint8_t*>(data);\n  size_t remaining = byte_count;\n  while (remaining > 0) {\n    ssize_t n = TEMP_FAILURE_RETRY(read(fd, p, remaining));\n    if (n <= 0) return false;\n    p += n;\n    remaining -= n;\n  }\n  return true;\n}\n\nbool WriteFully(int fd, const void* data, size_t byte_count) {\n  const uint8_t* p = reinterpret_cast<const uint8_t*>(data);\n  size_t remaining = byte_count;\n  while (remaining > 0) {\n    ssize_t n = TEMP_FAILURE_RETRY(write(fd, p, remaining));\n    if (n == -1) return false;\n    p += n;\n    remaining -= n;\n  }\n  return true;\n}\n\nbool RemoveFileIfExists(const std::string& path, std::string* err) {\n  struct stat st;\n#if defined(_WIN32)\n  //TODO: Windows version can't handle symbol link correctly.\n  int result = stat(path.c_str(), &st);\n  bool file_type_removable = (result == 0 && S_ISREG(st.st_mode));\n#else\n  int result = lstat(path.c_str(), &st);\n  bool file_type_removable = (result == 0 && (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)));\n#endif\n  if (result == 0) {\n    if (!file_type_removable) {\n      if (err != nullptr) {\n        *err = \"is not a regular or symbol link file\";\n      }\n      return false;\n    }\n    if (unlink(path.c_str()) == -1) {\n      if (err != nullptr) {\n        *err = strerror(errno);\n      }\n      return false;\n    }\n  }\n  return true;\n}\n\n}  // namespace base\n}  // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/base/file_test.cpp",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"android-base/file.h\"\n\n#include <gtest/gtest.h>\n\n#include <errno.h>\n#include <fcntl.h>\n#include <unistd.h>\n\n#include <string>\n\n#include \"android-base/test_utils.h\"\n\nTEST(file, ReadFileToString_ENOENT) {\n  std::string s(\"hello\");\n  errno = 0;\n  ASSERT_FALSE(android::base::ReadFileToString(\"/proc/does-not-exist\", &s));\n  EXPECT_EQ(ENOENT, errno);\n  EXPECT_EQ(\"\", s);  // s was cleared.\n}\n\nTEST(file, ReadFileToString_WriteStringToFile) {\n  TemporaryFile tf;\n  ASSERT_TRUE(tf.fd != -1);\n  ASSERT_TRUE(android::base::WriteStringToFile(\"abc\", tf.path))\n    << strerror(errno);\n  std::string s;\n  ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s))\n    << strerror(errno);\n  EXPECT_EQ(\"abc\", s);\n}\n\n// WriteStringToFile2 is explicitly for setting Unix permissions, which make no\n// sense on Windows.\n#if !defined(_WIN32)\nTEST(file, WriteStringToFile2) {\n  TemporaryFile tf;\n  ASSERT_TRUE(tf.fd != -1);\n  ASSERT_TRUE(android::base::WriteStringToFile(\"abc\", tf.path, 0660,\n                                               getuid(), getgid()))\n      << strerror(errno);\n  struct stat sb;\n  ASSERT_EQ(0, stat(tf.path, &sb));\n  ASSERT_EQ(0660U, static_cast<unsigned int>(sb.st_mode & ~S_IFMT));\n  ASSERT_EQ(getuid(), sb.st_uid);\n  ASSERT_EQ(getgid(), sb.st_gid);\n  std::string s;\n  ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s))\n    << strerror(errno);\n  EXPECT_EQ(\"abc\", s);\n}\n#endif\n\nTEST(file, WriteStringToFd) {\n  TemporaryFile tf;\n  ASSERT_TRUE(tf.fd != -1);\n  ASSERT_TRUE(android::base::WriteStringToFd(\"abc\", tf.fd));\n\n  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)) << strerror(errno);\n\n  std::string s;\n  ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)) << strerror(errno);\n  EXPECT_EQ(\"abc\", s);\n}\n\nTEST(file, WriteFully) {\n  TemporaryFile tf;\n  ASSERT_TRUE(tf.fd != -1);\n  ASSERT_TRUE(android::base::WriteFully(tf.fd, \"abc\", 3));\n\n  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)) << strerror(errno);\n\n  std::string s;\n  s.resize(3);\n  ASSERT_TRUE(android::base::ReadFully(tf.fd, &s[0], s.size()))\n    << strerror(errno);\n  EXPECT_EQ(\"abc\", s);\n\n  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)) << strerror(errno);\n\n  s.resize(1024);\n  ASSERT_FALSE(android::base::ReadFully(tf.fd, &s[0], s.size()));\n}\n\nTEST(file, RemoveFileIfExist) {\n  TemporaryFile tf;\n  ASSERT_TRUE(tf.fd != -1);\n  close(tf.fd);\n  tf.fd = -1;\n  std::string err;\n  ASSERT_TRUE(android::base::RemoveFileIfExists(tf.path, &err)) << err;\n  ASSERT_TRUE(android::base::RemoveFileIfExists(tf.path));\n  TemporaryDir td;\n  ASSERT_FALSE(android::base::RemoveFileIfExists(td.path));\n  ASSERT_FALSE(android::base::RemoveFileIfExists(td.path, &err));\n  ASSERT_EQ(\"is not a regular or symbol link file\", err);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/base/include/android-base/errors.h",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Portable error handling functions. This is only necessary for host-side\n// code that needs to be cross-platform; code that is only run on Unix should\n// just use errno and strerror() for simplicity.\n//\n// There is some complexity since Windows has (at least) three different error\n// numbers, not all of which share the same type:\n//   * errno: for C runtime errors.\n//   * GetLastError(): Windows non-socket errors.\n//   * WSAGetLastError(): Windows socket errors.\n// errno can be passed to strerror() on all platforms, but the other two require\n// special handling to get the error string. Refer to Microsoft documentation\n// to determine which error code to check for each function.\n\n#ifndef ANDROID_BASE_ERRORS_H\n#define ANDROID_BASE_ERRORS_H\n\n#include <string>\n\nnamespace android {\nnamespace base {\n\n// Returns a string describing the given system error code. |error_code| must\n// be errno on Unix or GetLastError()/WSAGetLastError() on Windows. Passing\n// errno on Windows has undefined behavior.\nstd::string SystemErrorCodeToString(int error_code);\n\n}  // namespace base\n}  // namespace android\n\n#endif  // ANDROID_BASE_ERRORS_H\n"
  },
  {
    "path": "atlas-aapt/system/core/base/include/android-base/file.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BASE_FILE_H\n#define ANDROID_BASE_FILE_H\n\n#include <sys/stat.h>\n#include <string>\n\n#if !defined(_WIN32) && !defined(O_BINARY)\n#define O_BINARY 0\n#endif\n\nnamespace android {\nnamespace base {\n\nbool ReadFdToString(int fd, std::string* content);\nbool ReadFileToString(const std::string& path, std::string* content);\n\nbool WriteStringToFile(const std::string& content, const std::string& path);\nbool WriteStringToFd(const std::string& content, int fd);\n\n#if !defined(_WIN32)\nbool WriteStringToFile(const std::string& content, const std::string& path,\n                       mode_t mode, uid_t owner, gid_t group);\n#endif\n\nbool ReadFully(int fd, void* data, size_t byte_count);\nbool WriteFully(int fd, const void* data, size_t byte_count);\n\nbool RemoveFileIfExists(const std::string& path, std::string* err = nullptr);\n\n}  // namespace base\n}  // namespace android\n\n#endif // ANDROID_BASE_FILE_H\n"
  },
  {
    "path": "atlas-aapt/system/core/base/include/android-base/logging.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BASE_LOGGING_H\n#define ANDROID_BASE_LOGGING_H\n\n// NOTE: For Windows, you must include logging.h after windows.h to allow the\n// following code to suppress the evil ERROR macro:\n#ifdef _WIN32\n// windows.h includes wingdi.h which defines an evil macro ERROR.\n#ifdef ERROR\n#undef ERROR\n#endif\n#endif\n\n#include <functional>\n#include <memory>\n#include <ostream>\n\n#include \"android-base/macros.h\"\n\nnamespace android {\nnamespace base {\n\nenum LogSeverity {\n  VERBOSE,\n  DEBUG,\n  INFO,\n  WARNING,\n  ERROR,\n  FATAL,\n};\n\nenum LogId {\n  DEFAULT,\n  MAIN,\n  SYSTEM,\n};\n\ntypedef std::function<void(LogId, LogSeverity, const char*, const char*,\n                           unsigned int, const char*)> LogFunction;\n\nextern void StderrLogger(LogId, LogSeverity, const char*, const char*,\n                         unsigned int, const char*);\n\n#ifdef __ANDROID__\n// We expose this even though it is the default because a user that wants to\n// override the default log buffer will have to construct this themselves.\nclass LogdLogger {\n public:\n  explicit LogdLogger(LogId default_log_id = android::base::MAIN);\n\n  void operator()(LogId, LogSeverity, const char* tag, const char* file,\n                  unsigned int line, const char* message);\n\n private:\n  LogId default_log_id_;\n};\n#endif\n\n// Configure logging based on ANDROID_LOG_TAGS environment variable.\n// We need to parse a string that looks like\n//\n//      *:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i\n//\n// The tag (or '*' for the global level) comes first, followed by a colon and a\n// letter indicating the minimum priority level we're expected to log.  This can\n// be used to reveal or conceal logs with specific tags.\nextern void InitLogging(char* argv[], LogFunction&& logger);\n\n// Configures logging using the default logger (logd for the device, stderr for\n// the host).\nextern void InitLogging(char* argv[]);\n\n// Replace the current logger.\nextern void SetLogger(LogFunction&& logger);\n\n// Get the minimum severity level for logging.\nextern LogSeverity GetMinimumLogSeverity();\n\nclass ErrnoRestorer {\n public:\n  ErrnoRestorer()\n      : saved_errno_(errno) {\n  }\n\n  ~ErrnoRestorer() {\n    errno = saved_errno_;\n  }\n\n  // Allow this object to be used as part of && operation.\n  operator bool() const {\n    return true;\n  }\n\n private:\n  const int saved_errno_;\n\n  DISALLOW_COPY_AND_ASSIGN(ErrnoRestorer);\n};\n\n// Logs a message to logcat on Android otherwise to stderr. If the severity is\n// FATAL it also causes an abort. For example:\n//\n//     LOG(FATAL) << \"We didn't expect to reach here\";\n#define LOG(severity) LOG_TO(DEFAULT, severity)\n\n// Logs a message to logcat with the specified log ID on Android otherwise to\n// stderr. If the severity is FATAL it also causes an abort.\n// Use an if-else statement instead of just an if statement here. So if there is a\n// else statement after LOG() macro, it won't bind to the if statement in the macro.\n// do-while(0) statement doesn't work here. Because we need to support << operator\n// following the macro, like \"LOG(DEBUG) << xxx;\".\n#define LOG_TO(dest, severity)                                                        \\\n  UNLIKELY(::android::base::severity >= ::android::base::GetMinimumLogSeverity()) &&  \\\n    ::android::base::ErrnoRestorer() &&                                               \\\n      ::android::base::LogMessage(__FILE__, __LINE__,                                 \\\n          ::android::base::dest,                                                      \\\n          ::android::base::severity, -1).stream()\n\n// A variant of LOG that also logs the current errno value. To be used when\n// library calls fail.\n#define PLOG(severity) PLOG_TO(DEFAULT, severity)\n\n// Behaves like PLOG, but logs to the specified log ID.\n#define PLOG_TO(dest, severity)                                                      \\\n  UNLIKELY(::android::base::severity >= ::android::base::GetMinimumLogSeverity()) && \\\n    ::android::base::ErrnoRestorer() &&                                              \\\n      ::android::base::LogMessage(__FILE__, __LINE__,                                \\\n          ::android::base::dest,                                                     \\\n          ::android::base::severity, errno).stream()\n\n// Marker that code is yet to be implemented.\n#define UNIMPLEMENTED(level) \\\n  LOG(level) << __PRETTY_FUNCTION__ << \" unimplemented \"\n\n// Check whether condition x holds and LOG(FATAL) if not. The value of the\n// expression x is only evaluated once. Extra logging can be appended using <<\n// after. For example:\n//\n//     CHECK(false == true) results in a log message of\n//       \"Check failed: false == true\".\n#define CHECK(x)                                                              \\\n  LIKELY((x)) ||                                                              \\\n    ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \\\n                                ::android::base::FATAL, -1).stream()          \\\n        << \"Check failed: \" #x << \" \"\n\n// Helper for CHECK_xx(x,y) macros.\n#define CHECK_OP(LHS, RHS, OP)                                              \\\n  for (auto _values = ::android::base::MakeEagerEvaluator(LHS, RHS);        \\\n       UNLIKELY(!(_values.lhs OP _values.rhs));                             \\\n       /* empty */)                                                         \\\n  ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \\\n                              ::android::base::FATAL, -1).stream()          \\\n      << \"Check failed: \" << #LHS << \" \" << #OP << \" \" << #RHS              \\\n      << \" (\" #LHS \"=\" << _values.lhs << \", \" #RHS \"=\" << _values.rhs << \") \"\n\n// Check whether a condition holds between x and y, LOG(FATAL) if not. The value\n// of the expressions x and y is evaluated once. Extra logging can be appended\n// using << after. For example:\n//\n//     CHECK_NE(0 == 1, false) results in\n//       \"Check failed: false != false (0==1=false, false=false) \".\n#define CHECK_EQ(x, y) CHECK_OP(x, y, == )\n#define CHECK_NE(x, y) CHECK_OP(x, y, != )\n#define CHECK_LE(x, y) CHECK_OP(x, y, <= )\n#define CHECK_LT(x, y) CHECK_OP(x, y, < )\n#define CHECK_GE(x, y) CHECK_OP(x, y, >= )\n#define CHECK_GT(x, y) CHECK_OP(x, y, > )\n\n// Helper for CHECK_STRxx(s1,s2) macros.\n#define CHECK_STROP(s1, s2, sense)                                         \\\n  if (LIKELY((strcmp(s1, s2) == 0) == sense))                              \\\n    ;                                                                      \\\n  else                                                                     \\\n    LOG(FATAL) << \"Check failed: \"                                         \\\n               << \"\\\"\" << s1 << \"\\\"\"                                       \\\n               << (sense ? \" == \" : \" != \") << \"\\\"\" << s2 << \"\\\"\"\n\n// Check for string (const char*) equality between s1 and s2, LOG(FATAL) if not.\n#define CHECK_STREQ(s1, s2) CHECK_STROP(s1, s2, true)\n#define CHECK_STRNE(s1, s2) CHECK_STROP(s1, s2, false)\n\n// Perform the pthread function call(args), LOG(FATAL) on error.\n#define CHECK_PTHREAD_CALL(call, args, what)                           \\\n  do {                                                                 \\\n    int rc = call args;                                                \\\n    if (rc != 0) {                                                     \\\n      errno = rc;                                                      \\\n      PLOG(FATAL) << #call << \" failed for \" << what; \\\n    }                                                                  \\\n  } while (false)\n\n// CHECK that can be used in a constexpr function. For example:\n//\n//    constexpr int half(int n) {\n//      return\n//          DCHECK_CONSTEXPR(n >= 0, , 0)\n//          CHECK_CONSTEXPR((n & 1) == 0),\n//              << \"Extra debugging output: n = \" << n, 0)\n//          n / 2;\n//    }\n#define CHECK_CONSTEXPR(x, out, dummy)                                     \\\n  (UNLIKELY(!(x)))                                                         \\\n      ? (LOG(FATAL) << \"Check failed: \" << #x out, dummy) \\\n      :\n\n// DCHECKs are debug variants of CHECKs only enabled in debug builds. Generally\n// CHECK should be used unless profiling identifies a CHECK as being in\n// performance critical code.\n#if defined(NDEBUG)\nstatic constexpr bool kEnableDChecks = false;\n#else\nstatic constexpr bool kEnableDChecks = true;\n#endif\n\n#define DCHECK(x) \\\n  if (::android::base::kEnableDChecks) CHECK(x)\n#define DCHECK_EQ(x, y) \\\n  if (::android::base::kEnableDChecks) CHECK_EQ(x, y)\n#define DCHECK_NE(x, y) \\\n  if (::android::base::kEnableDChecks) CHECK_NE(x, y)\n#define DCHECK_LE(x, y) \\\n  if (::android::base::kEnableDChecks) CHECK_LE(x, y)\n#define DCHECK_LT(x, y) \\\n  if (::android::base::kEnableDChecks) CHECK_LT(x, y)\n#define DCHECK_GE(x, y) \\\n  if (::android::base::kEnableDChecks) CHECK_GE(x, y)\n#define DCHECK_GT(x, y) \\\n  if (::android::base::kEnableDChecks) CHECK_GT(x, y)\n#define DCHECK_STREQ(s1, s2) \\\n  if (::android::base::kEnableDChecks) CHECK_STREQ(s1, s2)\n#define DCHECK_STRNE(s1, s2) \\\n  if (::android::base::kEnableDChecks) CHECK_STRNE(s1, s2)\n#if defined(NDEBUG)\n#define DCHECK_CONSTEXPR(x, out, dummy)\n#else\n#define DCHECK_CONSTEXPR(x, out, dummy) CHECK_CONSTEXPR(x, out, dummy)\n#endif\n\n// Temporary class created to evaluate the LHS and RHS, used with\n// MakeEagerEvaluator to infer the types of LHS and RHS.\ntemplate <typename LHS, typename RHS>\nstruct EagerEvaluator {\n  EagerEvaluator(LHS l, RHS r) : lhs(l), rhs(r) {\n  }\n  LHS lhs;\n  RHS rhs;\n};\n\n// Helper function for CHECK_xx.\ntemplate <typename LHS, typename RHS>\nstatic inline EagerEvaluator<LHS, RHS> MakeEagerEvaluator(LHS lhs, RHS rhs) {\n  return EagerEvaluator<LHS, RHS>(lhs, rhs);\n}\n\n// Explicitly instantiate EagerEvalue for pointers so that char*s aren't treated\n// as strings. To compare strings use CHECK_STREQ and CHECK_STRNE. We rely on\n// signed/unsigned warnings to protect you against combinations not explicitly\n// listed below.\n#define EAGER_PTR_EVALUATOR(T1, T2)               \\\n  template <>                                     \\\n  struct EagerEvaluator<T1, T2> {                 \\\n    EagerEvaluator(T1 l, T2 r)                    \\\n        : lhs(reinterpret_cast<const void*>(l)),  \\\n          rhs(reinterpret_cast<const void*>(r)) { \\\n    }                                             \\\n    const void* lhs;                              \\\n    const void* rhs;                              \\\n  }\nEAGER_PTR_EVALUATOR(const char*, const char*);\nEAGER_PTR_EVALUATOR(const char*, char*);\nEAGER_PTR_EVALUATOR(char*, const char*);\nEAGER_PTR_EVALUATOR(char*, char*);\nEAGER_PTR_EVALUATOR(const unsigned char*, const unsigned char*);\nEAGER_PTR_EVALUATOR(const unsigned char*, unsigned char*);\nEAGER_PTR_EVALUATOR(unsigned char*, const unsigned char*);\nEAGER_PTR_EVALUATOR(unsigned char*, unsigned char*);\nEAGER_PTR_EVALUATOR(const signed char*, const signed char*);\nEAGER_PTR_EVALUATOR(const signed char*, signed char*);\nEAGER_PTR_EVALUATOR(signed char*, const signed char*);\nEAGER_PTR_EVALUATOR(signed char*, signed char*);\n\n// Data for the log message, not stored in LogMessage to avoid increasing the\n// stack size.\nclass LogMessageData;\n\n// A LogMessage is a temporarily scoped object used by LOG and the unlikely part\n// of a CHECK. The destructor will abort if the severity is FATAL.\nclass LogMessage {\n public:\n  LogMessage(const char* file, unsigned int line, LogId id,\n             LogSeverity severity, int error);\n\n  ~LogMessage();\n\n  // Returns the stream associated with the message, the LogMessage performs\n  // output when it goes out of scope.\n  std::ostream& stream();\n\n  // The routine that performs the actual logging.\n  static void LogLine(const char* file, unsigned int line, LogId id,\n                      LogSeverity severity, const char* msg);\n\n private:\n  const std::unique_ptr<LogMessageData> data_;\n\n  DISALLOW_COPY_AND_ASSIGN(LogMessage);\n};\n\n// Allows to temporarily change the minimum severity level for logging.\nclass ScopedLogSeverity {\n public:\n  explicit ScopedLogSeverity(LogSeverity level);\n  ~ScopedLogSeverity();\n\n private:\n  LogSeverity old_;\n};\n\n}  // namespace base\n}  // namespace android\n\n#endif  // ANDROID_BASE_LOGGING_H\n"
  },
  {
    "path": "atlas-aapt/system/core/base/include/android-base/macros.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BASE_MACROS_H\n#define ANDROID_BASE_MACROS_H\n\n#include <stddef.h>  // for size_t\n#include <unistd.h>  // for TEMP_FAILURE_RETRY\n\n// bionic and glibc both have TEMP_FAILURE_RETRY, but eg Mac OS' libc doesn't.\n#ifndef TEMP_FAILURE_RETRY\n#define TEMP_FAILURE_RETRY(exp)            \\\n  ({                                       \\\n    decltype(exp) _rc;                     \\\n    do {                                   \\\n      _rc = (exp);                         \\\n    } while (_rc == -1 && errno == EINTR); \\\n    _rc;                                   \\\n  })\n#endif\n\n// A macro to disallow the copy constructor and operator= functions\n// This must be placed in the private: declarations for a class.\n//\n// For disallowing only assign or copy, delete the relevant operator or\n// constructor, for example:\n// void operator=(const TypeName&) = delete;\n// Note, that most uses of DISALLOW_ASSIGN and DISALLOW_COPY are broken\n// semantically, one should either use disallow both or neither. Try to\n// avoid these in new code.\n//\n// When building with C++11 toolchains, just use the language support\n// for explicitly deleted methods.\n#if __cplusplus >= 201103L\n#define DISALLOW_COPY_AND_ASSIGN(TypeName) \\\n  TypeName(const TypeName&) = delete;      \\\n  void operator=(const TypeName&) = delete\n#else\n#define DISALLOW_COPY_AND_ASSIGN(TypeName) \\\n  TypeName(const TypeName&);               \\\n  void operator=(const TypeName&)\n#endif\n\n// A macro to disallow all the implicit constructors, namely the\n// default constructor, copy constructor and operator= functions.\n//\n// This should be used in the private: declarations for a class\n// that wants to prevent anyone from instantiating it. This is\n// especially useful for classes containing only static methods.\n#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \\\n  TypeName();                                    \\\n  DISALLOW_COPY_AND_ASSIGN(TypeName)\n\n// The arraysize(arr) macro returns the # of elements in an array arr.\n// The expression is a compile-time constant, and therefore can be\n// used in defining new arrays, for example.  If you use arraysize on\n// a pointer by mistake, you will get a compile-time error.\n//\n// One caveat is that arraysize() doesn't accept any array of an\n// anonymous type or a type defined inside a function.  In these rare\n// cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below.  This is\n// due to a limitation in C++'s template system.  The limitation might\n// eventually be removed, but it hasn't happened yet.\n\n// This template function declaration is used in defining arraysize.\n// Note that the function doesn't need an implementation, as we only\n// use its type.\ntemplate <typename T, size_t N>\nchar(&ArraySizeHelper(T(&array)[N]))[N];  // NOLINT(readability/casting)\n\n#define arraysize(array) (sizeof(ArraySizeHelper(array)))\n\n// ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize,\n// but can be used on anonymous types or types defined inside\n// functions.  It's less safe than arraysize as it accepts some\n// (although not all) pointers.  Therefore, you should use arraysize\n// whenever possible.\n//\n// The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type\n// size_t.\n//\n// ARRAYSIZE_UNSAFE catches a few type errors.  If you see a compiler error\n//\n//   \"warning: division by zero in ...\"\n//\n// when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer.\n// You should only use ARRAYSIZE_UNSAFE on statically allocated arrays.\n//\n// The following comments are on the implementation details, and can\n// be ignored by the users.\n//\n// ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in\n// the array) and sizeof(*(arr)) (the # of bytes in one array\n// element).  If the former is divisible by the latter, perhaps arr is\n// indeed an array, in which case the division result is the # of\n// elements in the array.  Otherwise, arr cannot possibly be an array,\n// and we generate a compiler error to prevent the code from\n// compiling.\n//\n// Since the size of bool is implementation-defined, we need to cast\n// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final\n// result has type size_t.\n//\n// This macro is not perfect as it wrongfully accepts certain\n// pointers, namely where the pointer size is divisible by the pointee\n// size.  Since all our code has to go through a 32-bit compiler,\n// where a pointer is 4 bytes, this means all pointers to a type whose\n// size is 3 or greater than 4 will be (righteously) rejected.\n#define ARRAYSIZE_UNSAFE(a)     \\\n  ((sizeof(a) / sizeof(*(a))) / \\\n    static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))\n\n#define LIKELY(x) __builtin_expect((x), true)\n#define UNLIKELY(x) __builtin_expect((x), false)\n\n#define WARN_UNUSED __attribute__((warn_unused_result))\n\n// A deprecated function to call to create a false use of the parameter, for\n// example:\n//   int foo(int x) { UNUSED(x); return 10; }\n// to avoid compiler warnings. Going forward we prefer ATTRIBUTE_UNUSED.\ntemplate <typename... T>\nvoid UNUSED(const T&...) {\n}\n\n// An attribute to place on a parameter to a function, for example:\n//   int foo(int x ATTRIBUTE_UNUSED) { return 10; }\n// to avoid compiler warnings.\n#define ATTRIBUTE_UNUSED __attribute__((__unused__))\n\n// The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through\n// between switch labels:\n//  switch (x) {\n//    case 40:\n//    case 41:\n//      if (truth_is_out_there) {\n//        ++x;\n//        FALLTHROUGH_INTENDED;  // Use instead of/along with annotations in\n//                               // comments.\n//      } else {\n//        return x;\n//      }\n//    case 42:\n//      ...\n//\n//  As shown in the example above, the FALLTHROUGH_INTENDED macro should be\n//  followed by a semicolon. It is designed to mimic control-flow statements\n//  like 'break;', so it can be placed in most places where 'break;' can, but\n//  only if there are no statements on the execution path between it and the\n//  next switch label.\n//\n//  When compiled with clang in C++11 mode, the FALLTHROUGH_INTENDED macro is\n//  expanded to [[clang::fallthrough]] attribute, which is analysed when\n//  performing switch labels fall-through diagnostic ('-Wimplicit-fallthrough').\n//  See clang documentation on language extensions for details:\n//  http://clang.llvm.org/docs/LanguageExtensions.html#clang__fallthrough\n//\n//  When used with unsupported compilers, the FALLTHROUGH_INTENDED macro has no\n//  effect on diagnostics.\n//\n//  In either case this macro has no effect on runtime behavior and performance\n//  of code.\n#if defined(__clang__) && __cplusplus >= 201103L && defined(__has_warning)\n#if __has_feature(cxx_attributes) && __has_warning(\"-Wimplicit-fallthrough\")\n#define FALLTHROUGH_INTENDED [[clang::fallthrough]]  // NOLINT\n#endif\n#endif\n\n#ifndef FALLTHROUGH_INTENDED\n#define FALLTHROUGH_INTENDED \\\n  do {                       \\\n  } while (0)\n#endif\n\n#endif  // ANDROID_BASE_MACROS_H\n"
  },
  {
    "path": "atlas-aapt/system/core/base/include/android-base/memory.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BASE_MEMORY_H\n#define ANDROID_BASE_MEMORY_H\n\nnamespace android {\nnamespace base {\n\n// Use packed structures for access to unaligned data on targets with alignment\n// restrictions.  The compiler will generate appropriate code to access these\n// structures without generating alignment exceptions.\ntemplate <typename T>\nstatic inline T get_unaligned(const T* address) {\n  struct unaligned {\n    T v;\n  } __attribute__((packed));\n  const unaligned* p = reinterpret_cast<const unaligned*>(address);\n  return p->v;\n}\n\ntemplate <typename T>\nstatic inline void put_unaligned(T* address, T v) {\n  struct unaligned {\n    T v;\n  } __attribute__((packed));\n  unaligned* p = reinterpret_cast<unaligned*>(address);\n  p->v = v;\n}\n\n} // namespace base\n} // namespace android\n\n#endif  // ANDROID_BASE_MEMORY_H\n"
  },
  {
    "path": "atlas-aapt/system/core/base/include/android-base/parseint.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BASE_PARSEINT_H\n#define ANDROID_BASE_PARSEINT_H\n\n#include <errno.h>\n#include <stdlib.h>\n\n#include <limits>\n\nnamespace android {\nnamespace base {\n\n// Parses the unsigned decimal integer in the string 's' and sets 'out' to\n// that value. Optionally allows the caller to define a 'max' beyond which\n// otherwise valid values will be rejected. Returns boolean success.\ntemplate <typename T>\nbool ParseUint(const char* s, T* out,\n               T max = std::numeric_limits<T>::max()) {\n  int base = (s[0] == '0' && s[1] == 'x') ? 16 : 10;\n  errno = 0;\n  char* end;\n  unsigned long long int result = strtoull(s, &end, base);\n  if (errno != 0 || s == end || *end != '\\0') {\n    return false;\n  }\n  if (max < result) {\n    return false;\n  }\n  *out = static_cast<T>(result);\n  return true;\n}\n\n// Parses the signed decimal integer in the string 's' and sets 'out' to\n// that value. Optionally allows the caller to define a 'min' and 'max\n// beyond which otherwise valid values will be rejected. Returns boolean\n// success.\ntemplate <typename T>\nbool ParseInt(const char* s, T* out,\n              T min = std::numeric_limits<T>::min(),\n              T max = std::numeric_limits<T>::max()) {\n  int base = (s[0] == '0' && s[1] == 'x') ? 16 : 10;\n  errno = 0;\n  char* end;\n  long long int result = strtoll(s, &end, base);\n  if (errno != 0 || s == end || *end != '\\0') {\n    return false;\n  }\n  if (result < min || max < result) {\n    return false;\n  }\n  *out = static_cast<T>(result);\n  return true;\n}\n\n}  // namespace base\n}  // namespace android\n\n#endif  // ANDROID_BASE_PARSEINT_H\n"
  },
  {
    "path": "atlas-aapt/system/core/base/include/android-base/parsenetaddress.h",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BASE_PARSENETADDRESS_H\n#define ANDROID_BASE_PARSENETADDRESS_H\n\n#include <string>\n\nnamespace android {\nnamespace base {\n\n// Parses |address| into |host| and |port|.\n//\n// If |address| doesn't contain a port number, the default value is taken from\n// |port|. If |canonical_address| is non-null it will be set to \"host:port\" or\n// \"[host]:port\" as appropriate.\n//\n// On failure, returns false and fills |error|.\nbool ParseNetAddress(const std::string& address, std::string* host, int* port,\n                     std::string* canonical_address, std::string* error);\n\n}  // namespace base\n}  // namespace android\n\n#endif  // ANDROID_BASE_PARSENETADDRESS_H\n"
  },
  {
    "path": "atlas-aapt/system/core/base/include/android-base/stringprintf.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BASE_STRINGPRINTF_H\n#define ANDROID_BASE_STRINGPRINTF_H\n\n#include <stdarg.h>\n#include <string>\n\nnamespace android {\nnamespace base {\n\n// These printf-like functions are implemented in terms of vsnprintf, so they\n// use the same attribute for compile-time format string checking. On Windows,\n// if the mingw version of vsnprintf is used, use `gnu_printf' which allows z\n// in %zd and PRIu64 (and related) to be recognized by the compile-time\n// checking.\n#define FORMAT_ARCHETYPE __printf__\n#ifdef __USE_MINGW_ANSI_STDIO\n#if __USE_MINGW_ANSI_STDIO\n#undef FORMAT_ARCHETYPE\n#define FORMAT_ARCHETYPE gnu_printf\n#endif\n#endif\n\n// Returns a string corresponding to printf-like formatting of the arguments.\nstd::string StringPrintf(const char* fmt, ...)\n    __attribute__((__format__(FORMAT_ARCHETYPE, 1, 2)));\n\n// Appends a printf-like formatting of the arguments to 'dst'.\nvoid StringAppendF(std::string* dst, const char* fmt, ...)\n    __attribute__((__format__(FORMAT_ARCHETYPE, 2, 3)));\n\n// Appends a printf-like formatting of the arguments to 'dst'.\nvoid StringAppendV(std::string* dst, const char* format, va_list ap)\n    __attribute__((__format__(FORMAT_ARCHETYPE, 2, 0)));\n\n#undef FORMAT_ARCHETYPE\n\n}  // namespace base\n}  // namespace android\n\n#endif  // ANDROID_BASE_STRINGPRINTF_H\n"
  },
  {
    "path": "atlas-aapt/system/core/base/include/android-base/strings.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BASE_STRINGS_H\n#define ANDROID_BASE_STRINGS_H\n\n#include <sstream>\n#include <string>\n#include <vector>\n\nnamespace android {\nnamespace base {\n\n// Splits a string into a vector of strings.\n//\n// The string is split at each occurrence of a character in delimiters.\n//\n// The empty string is not a valid delimiter list.\nstd::vector<std::string> Split(const std::string& s,\n                               const std::string& delimiters);\n\n// Trims whitespace off both ends of the given string.\nstd::string Trim(const std::string& s);\n\n// Joins a container of things into a single string, using the given separator.\ntemplate <typename ContainerT, typename SeparatorT>\nstd::string Join(const ContainerT& things, SeparatorT separator) {\n  if (things.empty()) {\n    return \"\";\n  }\n\n  std::ostringstream result;\n  result << *things.begin();\n  for (auto it = std::next(things.begin()); it != things.end(); ++it) {\n    result << separator << *it;\n  }\n  return result.str();\n}\n\n// We instantiate the common cases in strings.cpp.\nextern template std::string Join(const std::vector<std::string>&, char);\nextern template std::string Join(const std::vector<const char*>&, char);\nextern template std::string Join(const std::vector<std::string>&, const std::string&);\nextern template std::string Join(const std::vector<const char*>&, const std::string&);\n\n// Tests whether 's' starts with 'prefix'.\nbool StartsWith(const std::string& s, const char* prefix);\n\n// Tests whether 's' ends with 'suffix'.\nbool EndsWith(const std::string& s, const char* suffix);\n\n}  // namespace base\n}  // namespace android\n\n#endif  // ANDROID_BASE_STRINGS_H\n"
  },
  {
    "path": "atlas-aapt/system/core/base/include/android-base/test_utils.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BASE_TEST_UTILS_H\n#define ANDROID_BASE_TEST_UTILS_H\n\n#include <string>\n\n#include <android-base/macros.h>\n\nclass TemporaryFile {\n public:\n  TemporaryFile();\n  ~TemporaryFile();\n\n  int fd;\n  char path[1024];\n\n private:\n  void init(const std::string& tmp_dir);\n\n  DISALLOW_COPY_AND_ASSIGN(TemporaryFile);\n};\n\nclass TemporaryDir {\n public:\n  TemporaryDir();\n  ~TemporaryDir();\n\n  char path[1024];\n\n private:\n  bool init(const std::string& tmp_dir);\n\n  DISALLOW_COPY_AND_ASSIGN(TemporaryDir);\n};\n\n#endif  // ANDROID_BASE_TEST_UTILS_H\n"
  },
  {
    "path": "atlas-aapt/system/core/base/include/android-base/thread_annotations.h",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BASE_THREAD_ANNOTATIONS_H\n#define ANDROID_BASE_THREAD_ANNOTATIONS_H\n\n#if defined(__SUPPORT_TS_ANNOTATION__) || defined(__clang__)\n#define THREAD_ANNOTATION_ATTRIBUTE__(x)   __attribute__((x))\n#else\n#define THREAD_ANNOTATION_ATTRIBUTE__(x)   // no-op\n#endif\n\n#define CAPABILITY(x) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(capability(x))\n\n#define SCOPED_CAPABILITY \\\n      THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)\n\n#define GUARDED_BY(x) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))\n\n#define PT_GUARDED_BY(x) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))\n\n#define ACQUIRED_BEFORE(...) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))\n\n#define ACQUIRED_AFTER(...) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))\n\n#define REQUIRES(...) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))\n\n#define REQUIRES_SHARED(...) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))\n\n#define ACQUIRE(...) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))\n\n#define ACQUIRE_SHARED(...) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))\n\n#define RELEASE(...) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))\n\n#define RELEASE_SHARED(...) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))\n\n#define TRY_ACQUIRE(...) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))\n\n#define TRY_ACQUIRE_SHARED(...) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))\n\n#define EXCLUDES(...) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))\n\n#define ASSERT_CAPABILITY(x) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))\n\n#define ASSERT_SHARED_CAPABILITY(x) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))\n\n#define RETURN_CAPABILITY(x) \\\n      THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))\n\n#define NO_THREAD_SAFETY_ANALYSIS \\\n      THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)\n\n#endif  // ANDROID_BASE_THREAD_ANNOTATIONS_H\n"
  },
  {
    "path": "atlas-aapt/system/core/base/include/android-base/unique_fd.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BASE_UNIQUE_FD_H\n#define ANDROID_BASE_UNIQUE_FD_H\n\n#include <unistd.h>\n\n// DO NOT INCLUDE OTHER LIBBASE HEADERS!\n// This file gets used in libbinder, and libbinder is used everywhere.\n// Including other headers from libbase frequently results in inclusion of\n// android-base/macros.h, which causes macro collisions.\n\n// Container for a file descriptor that automatically closes the descriptor as\n// it goes out of scope.\n//\n//      unique_fd ufd(open(\"/some/path\", \"r\"));\n//      if (ufd.get() == -1) return error;\n//\n//      // Do something useful, possibly including 'return'.\n//\n//      return 0; // Descriptor is closed for you.\n//\n// unique_fd is also known as ScopedFd/ScopedFD/scoped_fd; mentioned here to help\n// you find this class if you're searching for one of those names.\nnamespace android {\nnamespace base {\n\nstruct DefaultCloser {\n  static void Close(int fd) {\n    // Even if close(2) fails with EINTR, the fd will have been closed.\n    // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone\n    // else's fd.\n    // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html\n    ::close(fd);\n  }\n};\n\ntemplate <typename Closer>\nclass unique_fd_impl final {\n public:\n  unique_fd_impl() : value_(-1) {}\n\n  explicit unique_fd_impl(int value) : value_(value) {}\n  ~unique_fd_impl() { clear(); }\n\n  unique_fd_impl(unique_fd_impl&& other) : value_(other.release()) {}\n  unique_fd_impl& operator=(unique_fd_impl&& s) {\n    reset(s.release());\n    return *this;\n  }\n\n  void reset(int new_value) {\n    if (value_ != -1) {\n      Closer::Close(value_);\n    }\n    value_ = new_value;\n  }\n\n  void clear() {\n    reset(-1);\n  }\n\n  int get() const { return value_; }\n  operator int() const { return get(); }\n\n  int release() __attribute__((warn_unused_result)) {\n    int ret = value_;\n    value_ = -1;\n    return ret;\n  }\n\n private:\n  int value_;\n\n  unique_fd_impl(const unique_fd_impl&);\n  void operator=(const unique_fd_impl&);\n};\n\nusing unique_fd = unique_fd_impl<DefaultCloser>;\n\n}  // namespace base\n}  // namespace android\n\n#endif  // ANDROID_BASE_UNIQUE_FD_H\n"
  },
  {
    "path": "atlas-aapt/system/core/base/include/android-base/utf8.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_BASE_UTF8_H\n#define ANDROID_BASE_UTF8_H\n\n#ifdef _WIN32\n#include <string>\n#else\n// Bring in prototypes for standard APIs so that we can import them into the utf8 namespace.\n#include <fcntl.h>      // open\n#include <unistd.h>     // unlink\n#endif\n\nnamespace android {\nnamespace base {\n\n// Only available on Windows because this is only needed on Windows.\n#ifdef _WIN32\n// Convert size number of UTF-16 wchar_t's to UTF-8. Returns whether the\n// conversion was done successfully.\nbool WideToUTF8(const wchar_t* utf16, const size_t size, std::string* utf8);\n\n// Convert a NULL-terminated string of UTF-16 characters to UTF-8. Returns\n// whether the conversion was done successfully.\nbool WideToUTF8(const wchar_t* utf16, std::string* utf8);\n\n// Convert a UTF-16 std::wstring (including any embedded NULL characters) to\n// UTF-8. Returns whether the conversion was done successfully.\nbool WideToUTF8(const std::wstring& utf16, std::string* utf8);\n\n// Convert size number of UTF-8 char's to UTF-16. Returns whether the conversion\n// was done successfully.\nbool UTF8ToWide(const char* utf8, const size_t size, std::wstring* utf16);\n\n// Convert a NULL-terminated string of UTF-8 characters to UTF-16. Returns\n// whether the conversion was done successfully.\nbool UTF8ToWide(const char* utf8, std::wstring* utf16);\n\n// Convert a UTF-8 std::string (including any embedded NULL characters) to\n// UTF-16. Returns whether the conversion was done successfully.\nbool UTF8ToWide(const std::string& utf8, std::wstring* utf16);\n#endif\n\n// The functions in the utf8 namespace take UTF-8 strings. For Windows, these\n// are wrappers, for non-Windows these just expose existing APIs. To call these\n// functions, use:\n//\n// // anonymous namespace to avoid conflict with existing open(), unlink(), etc.\n// namespace {\n//   // Import functions into anonymous namespace.\n//   using namespace android::base::utf8;\n//\n//   void SomeFunction(const char* name) {\n//     int fd = open(name, ...);  // Calls android::base::utf8::open().\n//     ...\n//     unlink(name);              // Calls android::base::utf8::unlink().\n//   }\n// }\nnamespace utf8 {\n\n#ifdef _WIN32\nint open(const char* name, int flags, ...);\nint unlink(const char* name);\n#else\nusing ::open;\nusing ::unlink;\n#endif\n\n}  // namespace utf8\n}  // namespace base\n}  // namespace android\n\n#endif  // ANDROID_BASE_UTF8_H\n"
  },
  {
    "path": "atlas-aapt/system/core/base/logging.cpp",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifdef _WIN32\n#include <windows.h>\n#endif\n\n#include \"android-base/logging.h\"\n\n#include <libgen.h>\n\n// For getprogname(3) or program_invocation_short_name.\n#if defined(__ANDROID__) || defined(__APPLE__)\n#include <stdlib.h>\n#elif defined(__GLIBC__)\n#include <errno.h>\n#endif\n\n#include <iostream>\n#include <limits>\n#include <sstream>\n#include <string>\n#include <utility>\n#include <vector>\n\n#ifndef _WIN32\n#include <mutex>\n#endif\n\n#include \"android-base/macros.h\"\n#include \"android-base/strings.h\"\n#include \"cutils/threads.h\"\n\n// Headers for LogMessage::LogLine.\n#ifdef __ANDROID__\n#include <android/set_abort_message.h>\n#include \"cutils/log.h\"\n#else\n#include <sys/types.h>\n#include <unistd.h>\n#endif\n\n// For gettid.\n#if defined(__APPLE__)\n#include \"AvailabilityMacros.h\"  // For MAC_OS_X_VERSION_MAX_ALLOWED\n#include <stdint.h>\n#include <stdlib.h>\n#include <sys/syscall.h>\n#include <sys/time.h>\n#include <unistd.h>\n#elif defined(__linux__) && !defined(__ANDROID__)\n#include <syscall.h>\n#include <unistd.h>\n#elif defined(_WIN32)\n#include <windows.h>\n#endif\n\n#if defined(_WIN32)\ntypedef uint32_t thread_id;\n#else\ntypedef pid_t thread_id;\n#endif\n\nstatic thread_id GetThreadId() {\n#if defined(__BIONIC__)\n  return gettid();\n#elif defined(__APPLE__)\n  return syscall(SYS_thread_selfid);\n#elif defined(__linux__)\n  return syscall(__NR_gettid);\n#elif defined(_WIN32)\n  return GetCurrentThreadId();\n#endif\n}\n\nnamespace {\n#ifndef _WIN32\nusing std::mutex;\nusing std::lock_guard;\n\n#if defined(__GLIBC__)\nconst char* getprogname() {\n  return program_invocation_short_name;\n}\n#endif\n\n#else\nconst char* getprogname() {\n  static bool first = true;\n  static char progname[MAX_PATH] = {};\n\n  if (first) {\n    CHAR longname[MAX_PATH];\n    DWORD nchars = GetModuleFileNameA(nullptr, longname, arraysize(longname));\n    if ((nchars >= arraysize(longname)) || (nchars == 0)) {\n      // String truncation or some other error.\n      strcpy(progname, \"<unknown>\");\n    } else {\n      strcpy(progname, basename(longname));\n    }\n    first = false;\n  }\n\n  return progname;\n}\n\nclass mutex {\n public:\n  mutex() {\n    InitializeCriticalSection(&critical_section_);\n  }\n  ~mutex() {\n    DeleteCriticalSection(&critical_section_);\n  }\n\n  void lock() {\n    EnterCriticalSection(&critical_section_);\n  }\n\n  void unlock() {\n    LeaveCriticalSection(&critical_section_);\n  }\n\n private:\n  CRITICAL_SECTION critical_section_;\n};\n\ntemplate <typename LockT>\nclass lock_guard {\n public:\n  explicit lock_guard(LockT& lock) : lock_(lock) {\n    lock_.lock();\n  }\n\n  ~lock_guard() {\n    lock_.unlock();\n  }\n\n private:\n  LockT& lock_;\n\n  DISALLOW_COPY_AND_ASSIGN(lock_guard);\n};\n#endif\n} // namespace\n\nnamespace android {\nnamespace base {\n\nstatic auto& logging_lock = *new mutex();\n\n#ifdef __ANDROID__\nstatic auto& gLogger = *new LogFunction(LogdLogger());\n#else\nstatic auto& gLogger = *new LogFunction(StderrLogger);\n#endif\n\nstatic bool gInitialized = false;\nstatic LogSeverity gMinimumLogSeverity = INFO;\nstatic auto& gProgramInvocationName = *new std::unique_ptr<std::string>();\n\nLogSeverity GetMinimumLogSeverity() {\n  return gMinimumLogSeverity;\n}\n\nstatic const char* ProgramInvocationName() {\n  if (gProgramInvocationName == nullptr) {\n    gProgramInvocationName.reset(new std::string(getprogname()));\n  }\n\n  return gProgramInvocationName->c_str();\n}\n\nvoid StderrLogger(LogId, LogSeverity severity, const char*, const char* file,\n                  unsigned int line, const char* message) {\n  static const char log_characters[] = \"VDIWEF\";\n  static_assert(arraysize(log_characters) - 1 == FATAL + 1,\n                \"Mismatch in size of log_characters and values in LogSeverity\");\n  char severity_char = log_characters[severity];\n  fprintf(stderr, \"%s %c %5d %5d %s:%u] %s\\n\", ProgramInvocationName(),\n          severity_char, getpid(), GetThreadId(), file, line, message);\n}\n\n\n#ifdef __ANDROID__\nLogdLogger::LogdLogger(LogId default_log_id) : default_log_id_(default_log_id) {\n}\n\nstatic const android_LogPriority kLogSeverityToAndroidLogPriority[] = {\n    ANDROID_LOG_VERBOSE, ANDROID_LOG_DEBUG, ANDROID_LOG_INFO,\n    ANDROID_LOG_WARN,    ANDROID_LOG_ERROR, ANDROID_LOG_FATAL,\n};\nstatic_assert(arraysize(kLogSeverityToAndroidLogPriority) == FATAL + 1,\n              \"Mismatch in size of kLogSeverityToAndroidLogPriority and values \"\n              \"in LogSeverity\");\n\nstatic const log_id kLogIdToAndroidLogId[] = {\n    LOG_ID_MAX, LOG_ID_MAIN, LOG_ID_SYSTEM,\n};\nstatic_assert(arraysize(kLogIdToAndroidLogId) == SYSTEM + 1,\n              \"Mismatch in size of kLogIdToAndroidLogId and values in LogId\");\n\nvoid LogdLogger::operator()(LogId id, LogSeverity severity, const char* tag,\n                            const char* file, unsigned int line,\n                            const char* message) {\n  int priority = kLogSeverityToAndroidLogPriority[severity];\n  if (id == DEFAULT) {\n    id = default_log_id_;\n  }\n\n  log_id lg_id = kLogIdToAndroidLogId[id];\n\n  if (priority == ANDROID_LOG_FATAL) {\n    __android_log_buf_print(lg_id, priority, tag, \"%s:%u] %s\", file, line,\n                            message);\n  } else {\n    __android_log_buf_print(lg_id, priority, tag, \"%s\", message);\n  }\n}\n#endif\n\nvoid InitLogging(char* argv[], LogFunction&& logger) {\n  SetLogger(std::forward<LogFunction>(logger));\n  InitLogging(argv);\n}\n\nvoid InitLogging(char* argv[]) {\n  if (gInitialized) {\n    return;\n  }\n\n  gInitialized = true;\n\n  // Stash the command line for later use. We can use /proc/self/cmdline on\n  // Linux to recover this, but we don't have that luxury on the Mac/Windows,\n  // and there are a couple of argv[0] variants that are commonly used.\n  if (argv != nullptr) {\n    gProgramInvocationName.reset(new std::string(basename(argv[0])));\n  }\n\n  const char* tags = getenv(\"ANDROID_LOG_TAGS\");\n  if (tags == nullptr) {\n    return;\n  }\n\n  std::vector<std::string> specs = Split(tags, \" \");\n  for (size_t i = 0; i < specs.size(); ++i) {\n    // \"tag-pattern:[vdiwefs]\"\n    std::string spec(specs[i]);\n    if (spec.size() == 3 && StartsWith(spec, \"*:\")) {\n      switch (spec[2]) {\n        case 'v':\n          gMinimumLogSeverity = VERBOSE;\n          continue;\n        case 'd':\n          gMinimumLogSeverity = DEBUG;\n          continue;\n        case 'i':\n          gMinimumLogSeverity = INFO;\n          continue;\n        case 'w':\n          gMinimumLogSeverity = WARNING;\n          continue;\n        case 'e':\n          gMinimumLogSeverity = ERROR;\n          continue;\n        case 'f':\n          gMinimumLogSeverity = FATAL;\n          continue;\n        // liblog will even suppress FATAL if you say 's' for silent, but that's\n        // crazy!\n        case 's':\n          gMinimumLogSeverity = FATAL;\n          continue;\n      }\n    }\n    LOG(FATAL) << \"unsupported '\" << spec << \"' in ANDROID_LOG_TAGS (\" << tags\n               << \")\";\n  }\n}\n\nvoid SetLogger(LogFunction&& logger) {\n  lock_guard<mutex> lock(logging_lock);\n  gLogger = std::move(logger);\n}\n\nstatic const char* GetFileBasename(const char* file) {\n  // We can't use basename(3) even on Unix because the Mac doesn't\n  // have a non-modifying basename.\n  const char* last_slash = strrchr(file, '/');\n  if (last_slash != nullptr) {\n    return last_slash + 1;\n  }\n#if defined(_WIN32)\n  const char* last_backslash = strrchr(file, '\\\\');\n  if (last_backslash != nullptr) {\n    return last_backslash + 1;\n  }\n#endif\n  return file;\n}\n\n// This indirection greatly reduces the stack impact of having lots of\n// checks/logging in a function.\nclass LogMessageData {\n public:\n  LogMessageData(const char* file, unsigned int line, LogId id,\n                 LogSeverity severity, int error)\n      : file_(GetFileBasename(file)),\n        line_number_(line),\n        id_(id),\n        severity_(severity),\n        error_(error) {\n  }\n\n  const char* GetFile() const {\n    return file_;\n  }\n\n  unsigned int GetLineNumber() const {\n    return line_number_;\n  }\n\n  LogSeverity GetSeverity() const {\n    return severity_;\n  }\n\n  LogId GetId() const {\n    return id_;\n  }\n\n  int GetError() const {\n    return error_;\n  }\n\n  std::ostream& GetBuffer() {\n    return buffer_;\n  }\n\n  std::string ToString() const {\n    return buffer_.str();\n  }\n\n private:\n  std::ostringstream buffer_;\n  const char* const file_;\n  const unsigned int line_number_;\n  const LogId id_;\n  const LogSeverity severity_;\n  const int error_;\n\n  DISALLOW_COPY_AND_ASSIGN(LogMessageData);\n};\n\nLogMessage::LogMessage(const char* file, unsigned int line, LogId id,\n                       LogSeverity severity, int error)\n    : data_(new LogMessageData(file, line, id, severity, error)) {\n}\n\nLogMessage::~LogMessage() {\n  // Finish constructing the message.\n  if (data_->GetError() != -1) {\n    data_->GetBuffer() << \": \" << strerror(data_->GetError());\n  }\n  std::string msg(data_->ToString());\n\n  {\n    // Do the actual logging with the lock held.\n    lock_guard<mutex> lock(logging_lock);\n    if (msg.find('\\n') == std::string::npos) {\n      LogLine(data_->GetFile(), data_->GetLineNumber(), data_->GetId(),\n              data_->GetSeverity(), msg.c_str());\n    } else {\n      msg += '\\n';\n      size_t i = 0;\n      while (i < msg.size()) {\n        size_t nl = msg.find('\\n', i);\n        msg[nl] = '\\0';\n        LogLine(data_->GetFile(), data_->GetLineNumber(), data_->GetId(),\n                data_->GetSeverity(), &msg[i]);\n        i = nl + 1;\n      }\n    }\n  }\n\n  // Abort if necessary.\n  if (data_->GetSeverity() == FATAL) {\n#ifdef __ANDROID__\n    android_set_abort_message(msg.c_str());\n#endif\n    abort();\n  }\n}\n\nstd::ostream& LogMessage::stream() {\n  return data_->GetBuffer();\n}\n\nvoid LogMessage::LogLine(const char* file, unsigned int line, LogId id,\n                         LogSeverity severity, const char* message) {\n  const char* tag = ProgramInvocationName();\n  gLogger(id, severity, tag, file, line, message);\n}\n\nScopedLogSeverity::ScopedLogSeverity(LogSeverity level) {\n  old_ = gMinimumLogSeverity;\n  gMinimumLogSeverity = level;\n}\n\nScopedLogSeverity::~ScopedLogSeverity() {\n  gMinimumLogSeverity = old_;\n}\n\n}  // namespace base\n}  // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/base/logging_test.cpp",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"android-base/logging.h\"\n\n#include <libgen.h>\n\n#if defined(_WIN32)\n#include <signal.h>\n#endif\n\n#include <regex>\n#include <string>\n\n#include \"android-base/file.h\"\n#include \"android-base/stringprintf.h\"\n#include \"android-base/test_utils.h\"\n\n#include <gtest/gtest.h>\n\n#ifdef __ANDROID__\n#define HOST_TEST(suite, name) TEST(suite, DISABLED_ ## name)\n#else\n#define HOST_TEST(suite, name) TEST(suite, name)\n#endif\n\nclass CapturedStderr {\n public:\n  CapturedStderr() : old_stderr_(-1) {\n    init();\n  }\n\n  ~CapturedStderr() {\n    reset();\n  }\n\n  int fd() const {\n    return temp_file_.fd;\n  }\n\n private:\n  void init() {\n#if defined(_WIN32)\n    // On Windows, stderr is often buffered, so make sure it is unbuffered so\n    // that we can immediately read back what was written to stderr.\n    ASSERT_EQ(0, setvbuf(stderr, NULL, _IONBF, 0));\n#endif\n    old_stderr_ = dup(STDERR_FILENO);\n    ASSERT_NE(-1, old_stderr_);\n    ASSERT_NE(-1, dup2(fd(), STDERR_FILENO));\n  }\n\n  void reset() {\n    ASSERT_NE(-1, dup2(old_stderr_, STDERR_FILENO));\n    ASSERT_EQ(0, close(old_stderr_));\n    // Note: cannot restore prior setvbuf() setting.\n  }\n\n  TemporaryFile temp_file_;\n  int old_stderr_;\n};\n\n#if defined(_WIN32)\nstatic void ExitSignalAbortHandler(int) {\n  _exit(3);\n}\n#endif\n\nstatic void SuppressAbortUI() {\n#if defined(_WIN32)\n  // We really just want to call _set_abort_behavior(0, _CALL_REPORTFAULT) to\n  // suppress the Windows Error Reporting dialog box, but that API is not\n  // available in the OS-supplied C Runtime, msvcrt.dll, that we currently\n  // use (it is available in the Visual Studio C runtime).\n  //\n  // Instead, we setup a SIGABRT handler, which is called in abort() right\n  // before calling Windows Error Reporting. In the handler, we exit the\n  // process just like abort() does.\n  ASSERT_NE(SIG_ERR, signal(SIGABRT, ExitSignalAbortHandler));\n#endif\n}\n\nTEST(logging, CHECK) {\n  ASSERT_DEATH({SuppressAbortUI(); CHECK(false);}, \"Check failed: false \");\n  CHECK(true);\n\n  ASSERT_DEATH({SuppressAbortUI(); CHECK_EQ(0, 1);}, \"Check failed: 0 == 1 \");\n  CHECK_EQ(0, 0);\n\n  ASSERT_DEATH({SuppressAbortUI(); CHECK_STREQ(\"foo\", \"bar\");},\n               R\"(Check failed: \"foo\" == \"bar\")\");\n  CHECK_STREQ(\"foo\", \"foo\");\n\n  // Test whether CHECK() and CHECK_STREQ() have a dangling if with no else.\n  bool flag = false;\n  if (true)\n    CHECK(true);\n  else\n    flag = true;\n  EXPECT_FALSE(flag) << \"CHECK macro probably has a dangling if with no else\";\n\n  flag = false;\n  if (true)\n    CHECK_STREQ(\"foo\", \"foo\");\n  else\n    flag = true;\n  EXPECT_FALSE(flag) << \"CHECK_STREQ probably has a dangling if with no else\";\n}\n\nstd::string make_log_pattern(android::base::LogSeverity severity,\n                             const char* message) {\n  static const char* log_characters = \"VDIWEF\";\n  char log_char = log_characters[severity];\n  std::string holder(__FILE__);\n  return android::base::StringPrintf(\n      \"%c[[:space:]]+[[:digit:]]+[[:space:]]+[[:digit:]]+ %s:[[:digit:]]+] %s\",\n      log_char, basename(&holder[0]), message);\n}\n\nTEST(logging, LOG) {\n  ASSERT_DEATH({SuppressAbortUI(); LOG(FATAL) << \"foobar\";}, \"foobar\");\n\n  // We can't usefully check the output of any of these on Windows because we\n  // don't have std::regex, but we can at least make sure we printed at least as\n  // many characters are in the log message.\n  {\n    CapturedStderr cap;\n    LOG(WARNING) << \"foobar\";\n    ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET));\n\n    std::string output;\n    android::base::ReadFdToString(cap.fd(), &output);\n    ASSERT_GT(output.length(), strlen(\"foobar\"));\n\n#if !defined(_WIN32)\n    std::regex message_regex(\n        make_log_pattern(android::base::WARNING, \"foobar\"));\n    ASSERT_TRUE(std::regex_search(output, message_regex)) << output;\n#endif\n  }\n\n  {\n    CapturedStderr cap;\n    LOG(INFO) << \"foobar\";\n    ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET));\n\n    std::string output;\n    android::base::ReadFdToString(cap.fd(), &output);\n    ASSERT_GT(output.length(), strlen(\"foobar\"));\n\n#if !defined(_WIN32)\n    std::regex message_regex(\n        make_log_pattern(android::base::INFO, \"foobar\"));\n    ASSERT_TRUE(std::regex_search(output, message_regex)) << output;\n#endif\n  }\n\n  {\n    CapturedStderr cap;\n    LOG(DEBUG) << \"foobar\";\n    ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET));\n\n    std::string output;\n    android::base::ReadFdToString(cap.fd(), &output);\n    ASSERT_TRUE(output.empty());\n  }\n\n  {\n    android::base::ScopedLogSeverity severity(android::base::DEBUG);\n    CapturedStderr cap;\n    LOG(DEBUG) << \"foobar\";\n    ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET));\n\n    std::string output;\n    android::base::ReadFdToString(cap.fd(), &output);\n    ASSERT_GT(output.length(), strlen(\"foobar\"));\n\n#if !defined(_WIN32)\n    std::regex message_regex(\n        make_log_pattern(android::base::DEBUG, \"foobar\"));\n    ASSERT_TRUE(std::regex_search(output, message_regex)) << output;\n#endif\n  }\n\n  // Test whether LOG() saves and restores errno.\n  {\n    CapturedStderr cap;\n    errno = 12345;\n    LOG(INFO) << (errno = 67890);\n    EXPECT_EQ(12345, errno) << \"errno was not restored\";\n\n    ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET));\n\n    std::string output;\n    android::base::ReadFdToString(cap.fd(), &output);\n    EXPECT_NE(nullptr, strstr(output.c_str(), \"67890\")) << output;\n\n#if !defined(_WIN32)\n    std::regex message_regex(\n        make_log_pattern(android::base::INFO, \"67890\"));\n    ASSERT_TRUE(std::regex_search(output, message_regex)) << output;\n#endif\n  }\n\n  // Test whether LOG() has a dangling if with no else.\n  {\n    CapturedStderr cap;\n\n    // Do the test two ways: once where we hypothesize that LOG()'s if\n    // will evaluate to true (when severity is high enough) and once when we\n    // expect it to evaluate to false (when severity is not high enough).\n    bool flag = false;\n    if (true)\n      LOG(INFO) << \"foobar\";\n    else\n      flag = true;\n\n    EXPECT_FALSE(flag) << \"LOG macro probably has a dangling if with no else\";\n\n    flag = false;\n    if (true)\n      LOG(VERBOSE) << \"foobar\";\n    else\n      flag = true;\n\n    EXPECT_FALSE(flag) << \"LOG macro probably has a dangling if with no else\";\n  }\n}\n\nTEST(logging, PLOG) {\n  {\n    CapturedStderr cap;\n    errno = ENOENT;\n    PLOG(INFO) << \"foobar\";\n    ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET));\n\n    std::string output;\n    android::base::ReadFdToString(cap.fd(), &output);\n    ASSERT_GT(output.length(), strlen(\"foobar\"));\n\n#if !defined(_WIN32)\n    std::regex message_regex(make_log_pattern(\n        android::base::INFO, \"foobar: No such file or directory\"));\n    ASSERT_TRUE(std::regex_search(output, message_regex)) << output;\n#endif\n  }\n}\n\nTEST(logging, UNIMPLEMENTED) {\n  {\n    CapturedStderr cap;\n    errno = ENOENT;\n    UNIMPLEMENTED(ERROR);\n    ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET));\n\n    std::string output;\n    android::base::ReadFdToString(cap.fd(), &output);\n    ASSERT_GT(output.length(), strlen(\"unimplemented\"));\n\n#if !defined(_WIN32)\n    std::string expected_message =\n        android::base::StringPrintf(\"%s unimplemented \", __PRETTY_FUNCTION__);\n    std::regex message_regex(\n        make_log_pattern(android::base::ERROR, expected_message.c_str()));\n    ASSERT_TRUE(std::regex_search(output, message_regex)) << output;\n#endif\n  }\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/base/parseint_test.cpp",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"android-base/parseint.h\"\n\n#include <gtest/gtest.h>\n\nTEST(parseint, signed_smoke) {\n  int i;\n  ASSERT_FALSE(android::base::ParseInt(\"x\", &i));\n  ASSERT_FALSE(android::base::ParseInt(\"123x\", &i));\n\n  ASSERT_TRUE(android::base::ParseInt(\"123\", &i));\n  ASSERT_EQ(123, i);\n  ASSERT_TRUE(android::base::ParseInt(\"-123\", &i));\n  ASSERT_EQ(-123, i);\n\n  short s;\n  ASSERT_TRUE(android::base::ParseInt(\"1234\", &s));\n  ASSERT_EQ(1234, s);\n\n  ASSERT_TRUE(android::base::ParseInt(\"12\", &i, 0, 15));\n  ASSERT_EQ(12, i);\n  ASSERT_FALSE(android::base::ParseInt(\"-12\", &i, 0, 15));\n  ASSERT_FALSE(android::base::ParseInt(\"16\", &i, 0, 15));\n}\n\nTEST(parseint, unsigned_smoke) {\n  unsigned int i;\n  ASSERT_FALSE(android::base::ParseUint(\"x\", &i));\n  ASSERT_FALSE(android::base::ParseUint(\"123x\", &i));\n\n  ASSERT_TRUE(android::base::ParseUint(\"123\", &i));\n  ASSERT_EQ(123u, i);\n  ASSERT_FALSE(android::base::ParseUint(\"-123\", &i));\n\n  unsigned short s;\n  ASSERT_TRUE(android::base::ParseUint(\"1234\", &s));\n  ASSERT_EQ(1234u, s);\n\n  ASSERT_TRUE(android::base::ParseUint(\"12\", &i, 15u));\n  ASSERT_EQ(12u, i);\n  ASSERT_FALSE(android::base::ParseUint(\"-12\", &i, 15u));\n  ASSERT_FALSE(android::base::ParseUint(\"16\", &i, 15u));\n}\n\nTEST(parseint, no_implicit_octal) {\n  int i;\n  ASSERT_TRUE(android::base::ParseInt(\"0123\", &i));\n  ASSERT_EQ(123, i);\n\n  unsigned int u;\n  ASSERT_TRUE(android::base::ParseUint(\"0123\", &u));\n  ASSERT_EQ(123u, u);\n}\n\nTEST(parseint, explicit_hex) {\n  int i;\n  ASSERT_TRUE(android::base::ParseInt(\"0x123\", &i));\n  ASSERT_EQ(0x123, i);\n\n  unsigned int u;\n  ASSERT_TRUE(android::base::ParseUint(\"0x123\", &u));\n  ASSERT_EQ(0x123u, u);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/base/parsenetaddress.cpp",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"android-base/parsenetaddress.h\"\n\n#include <algorithm>\n\n#include \"android-base/stringprintf.h\"\n#include \"android-base/strings.h\"\n\nnamespace android {\nnamespace base {\n\nbool ParseNetAddress(const std::string& address, std::string* host, int* port,\n                     std::string* canonical_address, std::string* error) {\n  host->clear();\n\n  bool ipv6 = true;\n  bool saw_port = false;\n  size_t colons = std::count(address.begin(), address.end(), ':');\n  size_t dots = std::count(address.begin(), address.end(), '.');\n  std::string port_str;\n  if (address[0] == '[') {\n    // [::1]:123\n    if (address.rfind(\"]:\") == std::string::npos) {\n      *error = StringPrintf(\"bad IPv6 address '%s'\", address.c_str());\n      return false;\n    }\n    *host = address.substr(1, (address.find(\"]:\") - 1));\n    port_str = address.substr(address.rfind(\"]:\") + 2);\n    saw_port = true;\n  } else if (dots == 0 && colons >= 2 && colons <= 7) {\n    // ::1\n    *host = address;\n  } else if (colons <= 1) {\n    // 1.2.3.4 or some.accidental.domain.com\n    ipv6 = false;\n    std::vector<std::string> pieces = Split(address, \":\");\n    *host = pieces[0];\n    if (pieces.size() > 1) {\n      port_str = pieces[1];\n      saw_port = true;\n    }\n  }\n\n  if (host->empty()) {\n    *error = StringPrintf(\"no host in '%s'\", address.c_str());\n    return false;\n  }\n\n  if (saw_port) {\n    if (sscanf(port_str.c_str(), \"%d\", port) != 1 || *port <= 0 ||\n        *port > 65535) {\n      *error = StringPrintf(\"bad port number '%s' in '%s'\", port_str.c_str(),\n                            address.c_str());\n      return false;\n    }\n  }\n\n  if (canonical_address != nullptr) {\n    *canonical_address =\n        StringPrintf(ipv6 ? \"[%s]:%d\" : \"%s:%d\", host->c_str(), *port);\n  }\n\n  return true;\n}\n\n}  // namespace base\n}  // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/base/parsenetaddress_test.cpp",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"android-base/parsenetaddress.h\"\n\n#include <gtest/gtest.h>\n\nusing android::base::ParseNetAddress;\n\nTEST(ParseNetAddressTest, TestUrl) {\n  std::string canonical, host, error;\n  int port = 123;\n\n  EXPECT_TRUE(\n      ParseNetAddress(\"www.google.com\", &host, &port, &canonical, &error));\n  EXPECT_EQ(\"www.google.com:123\", canonical);\n  EXPECT_EQ(\"www.google.com\", host);\n  EXPECT_EQ(123, port);\n\n  EXPECT_TRUE(\n      ParseNetAddress(\"www.google.com:666\", &host, &port, &canonical, &error));\n  EXPECT_EQ(\"www.google.com:666\", canonical);\n  EXPECT_EQ(\"www.google.com\", host);\n  EXPECT_EQ(666, port);\n}\n\nTEST(ParseNetAddressTest, TestIpv4) {\n  std::string canonical, host, error;\n  int port = 123;\n\n  EXPECT_TRUE(ParseNetAddress(\"1.2.3.4\", &host, &port, &canonical, &error));\n  EXPECT_EQ(\"1.2.3.4:123\", canonical);\n  EXPECT_EQ(\"1.2.3.4\", host);\n  EXPECT_EQ(123, port);\n\n  EXPECT_TRUE(ParseNetAddress(\"1.2.3.4:666\", &host, &port, &canonical, &error));\n  EXPECT_EQ(\"1.2.3.4:666\", canonical);\n  EXPECT_EQ(\"1.2.3.4\", host);\n  EXPECT_EQ(666, port);\n}\n\nTEST(ParseNetAddressTest, TestIpv6) {\n  std::string canonical, host, error;\n  int port = 123;\n\n  EXPECT_TRUE(ParseNetAddress(\"::1\", &host, &port, &canonical, &error));\n  EXPECT_EQ(\"[::1]:123\", canonical);\n  EXPECT_EQ(\"::1\", host);\n  EXPECT_EQ(123, port);\n\n  EXPECT_TRUE(ParseNetAddress(\"fe80::200:5aee:feaa:20a2\", &host, &port,\n                              &canonical, &error));\n  EXPECT_EQ(\"[fe80::200:5aee:feaa:20a2]:123\", canonical);\n  EXPECT_EQ(\"fe80::200:5aee:feaa:20a2\", host);\n  EXPECT_EQ(123, port);\n\n  EXPECT_TRUE(ParseNetAddress(\"[::1]:666\", &host, &port, &canonical, &error));\n  EXPECT_EQ(\"[::1]:666\", canonical);\n  EXPECT_EQ(\"::1\", host);\n  EXPECT_EQ(666, port);\n\n  EXPECT_TRUE(ParseNetAddress(\"[fe80::200:5aee:feaa:20a2]:666\", &host, &port,\n                              &canonical, &error));\n  EXPECT_EQ(\"[fe80::200:5aee:feaa:20a2]:666\", canonical);\n  EXPECT_EQ(\"fe80::200:5aee:feaa:20a2\", host);\n  EXPECT_EQ(666, port);\n}\n\nTEST(ParseNetAddressTest, TestInvalidAddress) {\n  std::string canonical, host;\n  int port;\n\n  std::string failure_cases[] = {\n      // Invalid IPv4.\n      \"1.2.3.4:\",\n      \"1.2.3.4::\",\n      \":123\",\n\n      // Invalid IPv6.\n      \":1\",\n      \"::::::::1\",\n      \"[::1\",\n      \"[::1]\",\n      \"[::1]:\",\n      \"[::1]::\",\n\n      // Invalid port.\n      \"1.2.3.4:-1\",\n      \"1.2.3.4:0\",\n      \"1.2.3.4:65536\"\n      \"1.2.3.4:hello\",\n      \"[::1]:-1\",\n      \"[::1]:0\",\n      \"[::1]:65536\",\n      \"[::1]:hello\",\n  };\n\n  for (const auto& address : failure_cases) {\n    // Failure should give some non-empty error string.\n    std::string error;\n    EXPECT_FALSE(ParseNetAddress(address, &host, &port, &canonical, &error));\n    EXPECT_NE(\"\", error);\n  }\n}\n\n// Null canonical address argument.\nTEST(ParseNetAddressTest, TestNullCanonicalAddress) {\n  std::string host, error;\n  int port = 42;\n\n  EXPECT_TRUE(ParseNetAddress(\"www.google.com\", &host, &port, nullptr, &error));\n  EXPECT_TRUE(ParseNetAddress(\"1.2.3.4\", &host, &port, nullptr, &error));\n  EXPECT_TRUE(ParseNetAddress(\"::1\", &host, &port, nullptr, &error));\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/base/stringprintf.cpp",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"android-base/stringprintf.h\"\n\n#include <stdio.h>\n\n#include <string>\n\nnamespace android {\nnamespace base {\n\nvoid StringAppendV(std::string* dst, const char* format, va_list ap) {\n  // First try with a small fixed size buffer\n  char space[1024];\n\n  // It's possible for methods that use a va_list to invalidate\n  // the data in it upon use.  The fix is to make a copy\n  // of the structure before using it and use that copy instead.\n  va_list backup_ap;\n  va_copy(backup_ap, ap);\n  int result = vsnprintf(space, sizeof(space), format, backup_ap);\n  va_end(backup_ap);\n\n  if (result < static_cast<int>(sizeof(space))) {\n    if (result >= 0) {\n      // Normal case -- everything fit.\n      dst->append(space, result);\n      return;\n    }\n\n    if (result < 0) {\n      // Just an error.\n      return;\n    }\n  }\n\n  // Increase the buffer size to the size requested by vsnprintf,\n  // plus one for the closing \\0.\n  int length = result + 1;\n  char* buf = new char[length];\n\n  // Restore the va_list before we use it again\n  va_copy(backup_ap, ap);\n  result = vsnprintf(buf, length, format, backup_ap);\n  va_end(backup_ap);\n\n  if (result >= 0 && result < length) {\n    // It fit\n    dst->append(buf, result);\n  }\n  delete[] buf;\n}\n\nstd::string StringPrintf(const char* fmt, ...) {\n  va_list ap;\n  va_start(ap, fmt);\n  std::string result;\n  StringAppendV(&result, fmt, ap);\n  va_end(ap);\n  return result;\n}\n\nvoid StringAppendF(std::string* dst, const char* format, ...) {\n  va_list ap;\n  va_start(ap, format);\n  StringAppendV(dst, format, ap);\n  va_end(ap);\n}\n\n}  // namespace base\n}  // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/base/stringprintf_test.cpp",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"android-base/stringprintf.h\"\n\n#include <gtest/gtest.h>\n\n#include <string>\n\nTEST(StringPrintfTest, HexSizeT) {\n  size_t size = 0x00107e59;\n  EXPECT_EQ(\"00107e59\", android::base::StringPrintf(\"%08zx\", size));\n  EXPECT_EQ(\"0x00107e59\", android::base::StringPrintf(\"0x%08zx\", size));\n}\n\nTEST(StringPrintfTest, StringAppendF) {\n  std::string s(\"a\");\n  android::base::StringAppendF(&s, \"b\");\n  EXPECT_EQ(\"ab\", s);\n}\n\nTEST(StringPrintfTest, Errno) {\n  errno = 123;\n  android::base::StringPrintf(\"hello %s\", \"world\");\n  EXPECT_EQ(123, errno);\n}\n\nvoid TestN(size_t n) {\n  char* buf = new char[n + 1];\n  memset(buf, 'x', n);\n  buf[n] = '\\0';\n  std::string s(android::base::StringPrintf(\"%s\", buf));\n  EXPECT_EQ(buf, s);\n  delete[] buf;\n}\n\nTEST(StringPrintfTest, At1023) {\n  TestN(1023);\n}\n\nTEST(StringPrintfTest, At1024) {\n  TestN(1024);\n}\n\nTEST(StringPrintfTest, At1025) {\n  TestN(1025);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/base/strings.cpp",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"android-base/strings.h\"\n\n#include <stdlib.h>\n#include <string.h>\n\n#include <string>\n#include <vector>\n\nnamespace android {\nnamespace base {\n\n#define CHECK_NE(a, b) \\\n  if ((a) == (b)) abort();\n\nstd::vector<std::string> Split(const std::string& s,\n                               const std::string& delimiters) {\n  CHECK_NE(delimiters.size(), 0U);\n\n  std::vector<std::string> result;\n\n  size_t base = 0;\n  size_t found;\n  do {\n    found = s.find_first_of(delimiters, base);\n    result.push_back(s.substr(base, found - base));\n    base = found + 1;\n  } while (found != s.npos);\n\n  return result;\n}\n\nstd::string Trim(const std::string& s) {\n  std::string result;\n\n  if (s.size() == 0) {\n    return result;\n  }\n\n  size_t start_index = 0;\n  size_t end_index = s.size() - 1;\n\n  // Skip initial whitespace.\n  while (start_index < s.size()) {\n    if (!isspace(s[start_index])) {\n      break;\n    }\n    start_index++;\n  }\n\n  // Skip terminating whitespace.\n  while (end_index >= start_index) {\n    if (!isspace(s[end_index])) {\n      break;\n    }\n    end_index--;\n  }\n\n  // All spaces, no beef.\n  if (end_index < start_index) {\n    return \"\";\n  }\n  // Start_index is the first non-space, end_index is the last one.\n  return s.substr(start_index, end_index - start_index + 1);\n}\n\n// These cases are probably the norm, so we mark them extern in the header to\n// aid compile time and binary size.\ntemplate std::string Join(const std::vector<std::string>&, char);\ntemplate std::string Join(const std::vector<const char*>&, char);\ntemplate std::string Join(const std::vector<std::string>&, const std::string&);\ntemplate std::string Join(const std::vector<const char*>&, const std::string&);\n\nbool StartsWith(const std::string& s, const char* prefix) {\n  return s.compare(0, strlen(prefix), prefix) == 0;\n}\n\nbool EndsWith(const std::string& s, const char* suffix) {\n  size_t suffix_length = strlen(suffix);\n  size_t string_length = s.size();\n  if (suffix_length > string_length) {\n    return false;\n  }\n  size_t offset = string_length - suffix_length;\n  return s.compare(offset, suffix_length, suffix) == 0;\n}\n\n}  // namespace base\n}  // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/base/strings_test.cpp",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"android-base/strings.h\"\n\n#include <gtest/gtest.h>\n\n#include <string>\n#include <vector>\n#include <set>\n#include <unordered_set>\n\nTEST(strings, split_empty) {\n  std::vector<std::string> parts = android::base::Split(\"\", \",\");\n  ASSERT_EQ(1U, parts.size());\n  ASSERT_EQ(\"\", parts[0]);\n}\n\nTEST(strings, split_single) {\n  std::vector<std::string> parts = android::base::Split(\"foo\", \",\");\n  ASSERT_EQ(1U, parts.size());\n  ASSERT_EQ(\"foo\", parts[0]);\n}\n\nTEST(strings, split_simple) {\n  std::vector<std::string> parts = android::base::Split(\"foo,bar,baz\", \",\");\n  ASSERT_EQ(3U, parts.size());\n  ASSERT_EQ(\"foo\", parts[0]);\n  ASSERT_EQ(\"bar\", parts[1]);\n  ASSERT_EQ(\"baz\", parts[2]);\n}\n\nTEST(strings, split_with_empty_part) {\n  std::vector<std::string> parts = android::base::Split(\"foo,,bar\", \",\");\n  ASSERT_EQ(3U, parts.size());\n  ASSERT_EQ(\"foo\", parts[0]);\n  ASSERT_EQ(\"\", parts[1]);\n  ASSERT_EQ(\"bar\", parts[2]);\n}\n\nTEST(strings, split_null_char) {\n  std::vector<std::string> parts =\n      android::base::Split(std::string(\"foo\\0bar\", 7), std::string(\"\\0\", 1));\n  ASSERT_EQ(2U, parts.size());\n  ASSERT_EQ(\"foo\", parts[0]);\n  ASSERT_EQ(\"bar\", parts[1]);\n}\n\nTEST(strings, split_any) {\n  std::vector<std::string> parts = android::base::Split(\"foo:bar,baz\", \",:\");\n  ASSERT_EQ(3U, parts.size());\n  ASSERT_EQ(\"foo\", parts[0]);\n  ASSERT_EQ(\"bar\", parts[1]);\n  ASSERT_EQ(\"baz\", parts[2]);\n}\n\nTEST(strings, split_any_with_empty_part) {\n  std::vector<std::string> parts = android::base::Split(\"foo:,bar\", \",:\");\n  ASSERT_EQ(3U, parts.size());\n  ASSERT_EQ(\"foo\", parts[0]);\n  ASSERT_EQ(\"\", parts[1]);\n  ASSERT_EQ(\"bar\", parts[2]);\n}\n\nTEST(strings, trim_empty) {\n  ASSERT_EQ(\"\", android::base::Trim(\"\"));\n}\n\nTEST(strings, trim_already_trimmed) {\n  ASSERT_EQ(\"foo\", android::base::Trim(\"foo\"));\n}\n\nTEST(strings, trim_left) {\n  ASSERT_EQ(\"foo\", android::base::Trim(\" foo\"));\n}\n\nTEST(strings, trim_right) {\n  ASSERT_EQ(\"foo\", android::base::Trim(\"foo \"));\n}\n\nTEST(strings, trim_both) {\n  ASSERT_EQ(\"foo\", android::base::Trim(\" foo \"));\n}\n\nTEST(strings, trim_no_trim_middle) {\n  ASSERT_EQ(\"foo bar\", android::base::Trim(\"foo bar\"));\n}\n\nTEST(strings, trim_other_whitespace) {\n  ASSERT_EQ(\"foo\", android::base::Trim(\"\\v\\tfoo\\n\\f\"));\n}\n\nTEST(strings, join_nothing) {\n  std::vector<std::string> list = {};\n  ASSERT_EQ(\"\", android::base::Join(list, ','));\n}\n\nTEST(strings, join_single) {\n  std::vector<std::string> list = {\"foo\"};\n  ASSERT_EQ(\"foo\", android::base::Join(list, ','));\n}\n\nTEST(strings, join_simple) {\n  std::vector<std::string> list = {\"foo\", \"bar\", \"baz\"};\n  ASSERT_EQ(\"foo,bar,baz\", android::base::Join(list, ','));\n}\n\nTEST(strings, join_separator_in_vector) {\n  std::vector<std::string> list = {\",\", \",\"};\n  ASSERT_EQ(\",,,\", android::base::Join(list, ','));\n}\n\nTEST(strings, join_simple_ints) {\n  std::set<int> list = {1, 2, 3};\n  ASSERT_EQ(\"1,2,3\", android::base::Join(list, ','));\n}\n\nTEST(strings, join_unordered_set) {\n  std::unordered_set<int> list = {1, 2};\n  ASSERT_TRUE(\"1,2\" == android::base::Join(list, ',') ||\n              \"2,1\" == android::base::Join(list, ','));\n}\n\nTEST(strings, startswith_empty) {\n  ASSERT_FALSE(android::base::StartsWith(\"\", \"foo\"));\n  ASSERT_TRUE(android::base::StartsWith(\"\", \"\"));\n}\n\nTEST(strings, startswith_simple) {\n  ASSERT_TRUE(android::base::StartsWith(\"foo\", \"\"));\n  ASSERT_TRUE(android::base::StartsWith(\"foo\", \"f\"));\n  ASSERT_TRUE(android::base::StartsWith(\"foo\", \"fo\"));\n  ASSERT_TRUE(android::base::StartsWith(\"foo\", \"foo\"));\n}\n\nTEST(strings, startswith_prefix_too_long) {\n  ASSERT_FALSE(android::base::StartsWith(\"foo\", \"foobar\"));\n}\n\nTEST(strings, startswith_contains_prefix) {\n  ASSERT_FALSE(android::base::StartsWith(\"foobar\", \"oba\"));\n  ASSERT_FALSE(android::base::StartsWith(\"foobar\", \"bar\"));\n}\n\nTEST(strings, endswith_empty) {\n  ASSERT_FALSE(android::base::EndsWith(\"\", \"foo\"));\n  ASSERT_TRUE(android::base::EndsWith(\"\", \"\"));\n}\n\nTEST(strings, endswith_simple) {\n  ASSERT_TRUE(android::base::EndsWith(\"foo\", \"\"));\n  ASSERT_TRUE(android::base::EndsWith(\"foo\", \"o\"));\n  ASSERT_TRUE(android::base::EndsWith(\"foo\", \"oo\"));\n  ASSERT_TRUE(android::base::EndsWith(\"foo\", \"foo\"));\n}\n\nTEST(strings, endswith_prefix_too_long) {\n  ASSERT_FALSE(android::base::EndsWith(\"foo\", \"foobar\"));\n}\n\nTEST(strings, endswith_contains_prefix) {\n  ASSERT_FALSE(android::base::EndsWith(\"foobar\", \"oba\"));\n  ASSERT_FALSE(android::base::EndsWith(\"foobar\", \"foo\"));\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/base/test_main.cpp",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <gtest/gtest.h>\n\n#include \"android-base/logging.h\"\n\nint main(int argc, char** argv) {\n  ::testing::InitGoogleTest(&argc, argv);\n  android::base::InitLogging(argv, android::base::StderrLogger);\n  return RUN_ALL_TESTS();\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/base/test_utils.cpp",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"android-base/logging.h\"\n#include \"android-base/test_utils.h\"\n#include \"utils/Compat.h\" // For OS_PATH_SEPARATOR.\n\n#include <fcntl.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/stat.h>\n#include <unistd.h>\n\n#if defined(_WIN32)\n#include <windows.h>\n#include <direct.h>\n#endif\n\n#include <string>\n\n#ifdef _WIN32\nint mkstemp(char* template_name) {\n  if (_mktemp(template_name) == nullptr) {\n    return -1;\n  }\n  // Use open() to match the close() that TemporaryFile's destructor does.\n  // Use O_BINARY to match base file APIs.\n  return open(template_name, O_CREAT | O_EXCL | O_RDWR | O_BINARY,\n              S_IRUSR | S_IWUSR);\n}\n\nchar* mkdtemp(char* template_name) {\n  if (_mktemp(template_name) == nullptr) {\n    return nullptr;\n  }\n  if (_mkdir(template_name) == -1) {\n    return nullptr;\n  }\n  return template_name;\n}\n#endif\n\nstatic std::string GetSystemTempDir() {\n#if defined(__ANDROID__)\n  return \"/data/local/tmp\";\n#elif defined(_WIN32)\n  char tmp_dir[MAX_PATH];\n  DWORD result = GetTempPathA(sizeof(tmp_dir), tmp_dir);\n  CHECK_NE(result, 0ul) << \"GetTempPathA failed, error: \" << GetLastError();\n  CHECK_LT(result, sizeof(tmp_dir)) << \"path truncated to: \" << result;\n\n  // GetTempPath() returns a path with a trailing slash, but init()\n  // does not expect that, so remove it.\n  CHECK_EQ(tmp_dir[result - 1], '\\\\');\n  tmp_dir[result - 1] = '\\0';\n  return tmp_dir;\n#else\n  return \"/tmp\";\n#endif\n}\n\nTemporaryFile::TemporaryFile() {\n  init(GetSystemTempDir());\n}\n\nTemporaryFile::~TemporaryFile() {\n  close(fd);\n  unlink(path);\n}\n\nvoid TemporaryFile::init(const std::string& tmp_dir) {\n  snprintf(path, sizeof(path), \"%s%cTemporaryFile-XXXXXX\", tmp_dir.c_str(),\n           OS_PATH_SEPARATOR);\n  fd = mkstemp(path);\n}\n\nTemporaryDir::TemporaryDir() {\n  init(GetSystemTempDir());\n}\n\nTemporaryDir::~TemporaryDir() {\n  rmdir(path);\n}\n\nbool TemporaryDir::init(const std::string& tmp_dir) {\n  snprintf(path, sizeof(path), \"%s%cTemporaryDir-XXXXXX\", tmp_dir.c_str(),\n           OS_PATH_SEPARATOR);\n  return (mkdtemp(path) != nullptr);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/base/utf8.cpp",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <windows.h>\n\n#include \"android-base/utf8.h\"\n\n#include <fcntl.h>\n\n#include <string>\n\n#include \"android-base/logging.h\"\n\nnamespace android {\nnamespace base {\n\n// Helper to set errno based on GetLastError() after WideCharToMultiByte()/MultiByteToWideChar().\nstatic void SetErrnoFromLastError() {\n  switch (GetLastError()) {\n    case ERROR_NO_UNICODE_TRANSLATION:\n      errno = EILSEQ;\n      break;\n    default:\n      errno = EINVAL;\n      break;\n  }\n}\n\nbool WideToUTF8(const wchar_t* utf16, const size_t size, std::string* utf8) {\n  utf8->clear();\n\n  if (size == 0) {\n    return true;\n  }\n\n  // TODO: Consider using std::wstring_convert once libcxx is supported on\n  // Windows.\n\n  // Only Vista or later has this flag that causes WideCharToMultiByte() to\n  // return an error on invalid characters.\n  const DWORD flags =\n#if (WINVER >= 0x0600)\n    WC_ERR_INVALID_CHARS;\n#else\n    0;\n#endif\n\n  const int chars_required = WideCharToMultiByte(CP_UTF8, flags, utf16, size,\n                                                 NULL, 0, NULL, NULL);\n  if (chars_required <= 0) {\n    SetErrnoFromLastError();\n    return false;\n  }\n\n  // This could potentially throw a std::bad_alloc exception.\n  utf8->resize(chars_required);\n\n  const int result = WideCharToMultiByte(CP_UTF8, flags, utf16, size,\n                                         &(*utf8)[0], chars_required, NULL,\n                                         NULL);\n  if (result != chars_required) {\n    SetErrnoFromLastError();\n    CHECK_LE(result, chars_required) << \"WideCharToMultiByte wrote \" << result\n        << \" chars to buffer of \" << chars_required << \" chars\";\n    utf8->clear();\n    return false;\n  }\n\n  return true;\n}\n\nbool WideToUTF8(const wchar_t* utf16, std::string* utf8) {\n  // Compute string length of NULL-terminated string with wcslen().\n  return WideToUTF8(utf16, wcslen(utf16), utf8);\n}\n\nbool WideToUTF8(const std::wstring& utf16, std::string* utf8) {\n  // Use the stored length of the string which allows embedded NULL characters\n  // to be converted.\n  return WideToUTF8(utf16.c_str(), utf16.length(), utf8);\n}\n\n// Internal helper function that takes MultiByteToWideChar() flags.\nstatic bool UTF8ToWideWithFlags(const char* utf8, const size_t size, std::wstring* utf16,\n                                const DWORD flags) {\n  utf16->clear();\n\n  if (size == 0) {\n    return true;\n  }\n\n  // TODO: Consider using std::wstring_convert once libcxx is supported on\n  // Windows.\n  const int chars_required = MultiByteToWideChar(CP_UTF8, flags, utf8, size,\n                                                 NULL, 0);\n  if (chars_required <= 0) {\n    SetErrnoFromLastError();\n    return false;\n  }\n\n  // This could potentially throw a std::bad_alloc exception.\n  utf16->resize(chars_required);\n\n  const int result = MultiByteToWideChar(CP_UTF8, flags, utf8, size,\n                                         &(*utf16)[0], chars_required);\n  if (result != chars_required) {\n    SetErrnoFromLastError();\n    CHECK_LE(result, chars_required) << \"MultiByteToWideChar wrote \" << result\n        << \" chars to buffer of \" << chars_required << \" chars\";\n    utf16->clear();\n    return false;\n  }\n\n  return true;\n}\n\nbool UTF8ToWide(const char* utf8, const size_t size, std::wstring* utf16) {\n  // If strictly interpreting as UTF-8 succeeds, return success.\n  if (UTF8ToWideWithFlags(utf8, size, utf16, MB_ERR_INVALID_CHARS)) {\n    return true;\n  }\n\n  const int saved_errno = errno;\n\n  // Fallback to non-strict interpretation, allowing invalid characters and\n  // converting as best as possible, and return false to signify a problem.\n  (void)UTF8ToWideWithFlags(utf8, size, utf16, 0);\n  errno = saved_errno;\n  return false;\n}\n\nbool UTF8ToWide(const char* utf8, std::wstring* utf16) {\n  // Compute string length of NULL-terminated string with strlen().\n  return UTF8ToWide(utf8, strlen(utf8), utf16);\n}\n\nbool UTF8ToWide(const std::string& utf8, std::wstring* utf16) {\n  // Use the stored length of the string which allows embedded NULL characters\n  // to be converted.\n  return UTF8ToWide(utf8.c_str(), utf8.length(), utf16);\n}\n\n// Versions of standard library APIs that support UTF-8 strings.\nnamespace utf8 {\n\nint open(const char* name, int flags, ...) {\n  std::wstring name_utf16;\n  if (!UTF8ToWide(name, &name_utf16)) {\n    return -1;\n  }\n\n  int mode = 0;\n  if ((flags & O_CREAT) != 0) {\n    va_list args;\n    va_start(args, flags);\n    mode = va_arg(args, int);\n    va_end(args);\n  }\n\n  return _wopen(name_utf16.c_str(), flags, mode);\n}\n\nint unlink(const char* name) {\n  std::wstring name_utf16;\n  if (!UTF8ToWide(name, &name_utf16)) {\n    return -1;\n  }\n\n  return _wunlink(name_utf16.c_str());\n}\n\n}  // namespace utf8\n}  // namespace base\n}  // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/base/utf8_test.cpp",
    "content": "/*\n* Copyright (C) 2015 The Android Open Source Project\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n*      http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n#include \"android-base/utf8.h\"\n\n#include <gtest/gtest.h>\n\n#include \"android-base/macros.h\"\n\nnamespace android {\nnamespace base {\n\nTEST(UTFStringConversionsTest, ConvertInvalidUTF8) {\n  std::wstring wide;\n\n  errno = 0;\n\n  // Standalone \\xa2 is an invalid UTF-8 sequence, so this should return an\n  // error. Concatenate two C/C++ literal string constants to prevent the\n  // compiler from giving an error about \"\\xa2af\" containing a \"hex escape\n  // sequence out of range\".\n  EXPECT_FALSE(android::base::UTF8ToWide(\"before\\xa2\" \"after\", &wide));\n\n  EXPECT_EQ(EILSEQ, errno);\n\n  // Even if an invalid character is encountered, UTF8ToWide() should still do\n  // its best to convert the rest of the string. sysdeps_win32.cpp:\n  // _console_write_utf8() depends on this behavior.\n  //\n  // Thus, we verify that the valid characters are converted, but we ignore the\n  // specific replacement character that UTF8ToWide() may replace the invalid\n  // UTF-8 characters with because we want to allow that to change if the\n  // implementation changes.\n  EXPECT_EQ(0U, wide.find(L\"before\"));\n  const wchar_t after_wide[] = L\"after\";\n  EXPECT_EQ(wide.length() - (arraysize(after_wide) - 1), wide.find(after_wide));\n}\n\n// Below is adapted from https://chromium.googlesource.com/chromium/src/+/master/base/strings/utf_string_conversions_unittest.cc\n\n// Copyright (c) 2010 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// The tests below from utf_string_conversions_unittest.cc check for this\n// preprocessor symbol, so define it, as it is appropriate for Windows.\n#define WCHAR_T_IS_UTF16\nstatic_assert(sizeof(wchar_t) == 2, \"wchar_t is not 2 bytes\");\n\n// The tests below from utf_string_conversions_unittest.cc call versions of\n// UTF8ToWide() and WideToUTF8() that don't return success/failure, so these are\n// stub implementations with that signature. These are just for testing and\n// should not be moved to base because they assert/expect no errors which is\n// probably not a good idea (or at least it is something that should be left\n// up to the caller, not a base library).\n\nstatic std::wstring UTF8ToWide(const std::string& utf8) {\n  std::wstring utf16;\n  EXPECT_TRUE(UTF8ToWide(utf8, &utf16));\n  return utf16;\n}\n\nstatic std::string WideToUTF8(const std::wstring& utf16) {\n  std::string utf8;\n  EXPECT_TRUE(WideToUTF8(utf16, &utf8));\n  return utf8;\n}\n\nnamespace {\n\nconst wchar_t* const kConvertRoundtripCases[] = {\n  L\"Google Video\",\n  // \"网页 图片 资讯更多 »\"\n  L\"\\x7f51\\x9875\\x0020\\x56fe\\x7247\\x0020\\x8d44\\x8baf\\x66f4\\x591a\\x0020\\x00bb\",\n  //  \"Παγκόσμιος Ιστός\"\n  L\"\\x03a0\\x03b1\\x03b3\\x03ba\\x03cc\\x03c3\\x03bc\\x03b9\"\n  L\"\\x03bf\\x03c2\\x0020\\x0399\\x03c3\\x03c4\\x03cc\\x03c2\",\n  // \"Поиск страниц на русском\"\n  L\"\\x041f\\x043e\\x0438\\x0441\\x043a\\x0020\\x0441\\x0442\"\n  L\"\\x0440\\x0430\\x043d\\x0438\\x0446\\x0020\\x043d\\x0430\"\n  L\"\\x0020\\x0440\\x0443\\x0441\\x0441\\x043a\\x043e\\x043c\",\n  // \"전체서비스\"\n  L\"\\xc804\\xccb4\\xc11c\\xbe44\\xc2a4\",\n\n  // Test characters that take more than 16 bits. This will depend on whether\n  // wchar_t is 16 or 32 bits.\n#if defined(WCHAR_T_IS_UTF16)\n  L\"\\xd800\\xdf00\",\n  // ?????  (Mathematical Alphanumeric Symbols (U+011d40 - U+011d44 : A,B,C,D,E)\n  L\"\\xd807\\xdd40\\xd807\\xdd41\\xd807\\xdd42\\xd807\\xdd43\\xd807\\xdd44\",\n#elif defined(WCHAR_T_IS_UTF32)\n  L\"\\x10300\",\n  // ?????  (Mathematical Alphanumeric Symbols (U+011d40 - U+011d44 : A,B,C,D,E)\n  L\"\\x11d40\\x11d41\\x11d42\\x11d43\\x11d44\",\n#endif\n};\n\n}  // namespace\n\nTEST(UTFStringConversionsTest, ConvertUTF8AndWide) {\n  // we round-trip all the wide strings through UTF-8 to make sure everything\n  // agrees on the conversion. This uses the stream operators to test them\n  // simultaneously.\n  for (size_t i = 0; i < arraysize(kConvertRoundtripCases); ++i) {\n    std::ostringstream utf8;\n    utf8 << WideToUTF8(kConvertRoundtripCases[i]);\n    std::wostringstream wide;\n    wide << UTF8ToWide(utf8.str());\n\n    EXPECT_EQ(kConvertRoundtripCases[i], wide.str());\n  }\n}\n\nTEST(UTFStringConversionsTest, ConvertUTF8AndWideEmptyString) {\n  // An empty std::wstring should be converted to an empty std::string,\n  // and vice versa.\n  std::wstring wempty;\n  std::string empty;\n  EXPECT_EQ(empty, WideToUTF8(wempty));\n  EXPECT_EQ(wempty, UTF8ToWide(empty));\n}\n\nTEST(UTFStringConversionsTest, ConvertUTF8ToWide) {\n  struct UTF8ToWideCase {\n    const char* utf8;\n    const wchar_t* wide;\n    bool success;\n  } convert_cases[] = {\n    // Regular UTF-8 input.\n    {\"\\xe4\\xbd\\xa0\\xe5\\xa5\\xbd\", L\"\\x4f60\\x597d\", true},\n    // Non-character is passed through.\n    {\"\\xef\\xbf\\xbfHello\", L\"\\xffffHello\", true},\n    // Truncated UTF-8 sequence.\n    {\"\\xe4\\xa0\\xe5\\xa5\\xbd\", L\"\\xfffd\\x597d\", false},\n    // Truncated off the end.\n    {\"\\xe5\\xa5\\xbd\\xe4\\xa0\", L\"\\x597d\\xfffd\", false},\n    // Non-shortest-form UTF-8.\n    {\"\\xf0\\x84\\xbd\\xa0\\xe5\\xa5\\xbd\", L\"\\xfffd\\x597d\", false},\n    // This UTF-8 character decodes to a UTF-16 surrogate, which is illegal.\n    // Note that for whatever reason, this test fails on Windows XP.\n    {\"\\xed\\xb0\\x80\", L\"\\xfffd\", false},\n    // Non-BMP characters. The second is a non-character regarded as valid.\n    // The result will either be in UTF-16 or UTF-32.\n#if defined(WCHAR_T_IS_UTF16)\n    {\"A\\xF0\\x90\\x8C\\x80z\", L\"A\\xd800\\xdf00z\", true},\n    {\"A\\xF4\\x8F\\xBF\\xBEz\", L\"A\\xdbff\\xdffez\", true},\n#elif defined(WCHAR_T_IS_UTF32)\n    {\"A\\xF0\\x90\\x8C\\x80z\", L\"A\\x10300z\", true},\n    {\"A\\xF4\\x8F\\xBF\\xBEz\", L\"A\\x10fffez\", true},\n#endif\n  };\n\n  for (size_t i = 0; i < arraysize(convert_cases); i++) {\n    std::wstring converted;\n    errno = 0;\n    const bool success = UTF8ToWide(convert_cases[i].utf8,\n                                    strlen(convert_cases[i].utf8),\n                                    &converted);\n    EXPECT_EQ(convert_cases[i].success, success);\n    // The original test always compared expected and converted, but don't do\n    // that because our implementation of UTF8ToWide() does not guarantee to\n    // produce the same output in error situations.\n    if (success) {\n      std::wstring expected(convert_cases[i].wide);\n      EXPECT_EQ(expected, converted);\n    } else {\n      EXPECT_EQ(EILSEQ, errno);\n    }\n  }\n\n  // Manually test an embedded NULL.\n  std::wstring converted;\n  EXPECT_TRUE(UTF8ToWide(\"\\00Z\\t\", 3, &converted));\n  ASSERT_EQ(3U, converted.length());\n  EXPECT_EQ(static_cast<wchar_t>(0), converted[0]);\n  EXPECT_EQ('Z', converted[1]);\n  EXPECT_EQ('\\t', converted[2]);\n\n  // Make sure that conversion replaces, not appends.\n  EXPECT_TRUE(UTF8ToWide(\"B\", 1, &converted));\n  ASSERT_EQ(1U, converted.length());\n  EXPECT_EQ('B', converted[0]);\n}\n\n#if defined(WCHAR_T_IS_UTF16)\n// This test is only valid when wchar_t == UTF-16.\nTEST(UTFStringConversionsTest, ConvertUTF16ToUTF8) {\n  struct WideToUTF8Case {\n    const wchar_t* utf16;\n    const char* utf8;\n    bool success;\n  } convert_cases[] = {\n    // Regular UTF-16 input.\n    {L\"\\x4f60\\x597d\", \"\\xe4\\xbd\\xa0\\xe5\\xa5\\xbd\", true},\n    // Test a non-BMP character.\n    {L\"\\xd800\\xdf00\", \"\\xF0\\x90\\x8C\\x80\", true},\n    // Non-characters are passed through.\n    {L\"\\xffffHello\", \"\\xEF\\xBF\\xBFHello\", true},\n    {L\"\\xdbff\\xdffeHello\", \"\\xF4\\x8F\\xBF\\xBEHello\", true},\n    // The first character is a truncated UTF-16 character.\n    // Note that for whatever reason, this test fails on Windows XP.\n    {L\"\\xd800\\x597d\", \"\\xef\\xbf\\xbd\\xe5\\xa5\\xbd\",\n#if (WINVER >= 0x0600)\n    // Only Vista and later has a new API/flag that correctly returns false.\n    false\n#else\n    true\n#endif\n    },\n    // Truncated at the end.\n    // Note that for whatever reason, this test fails on Windows XP.\n    {L\"\\x597d\\xd800\", \"\\xe5\\xa5\\xbd\\xef\\xbf\\xbd\",\n#if (WINVER >= 0x0600)\n    // Only Vista and later has a new API/flag that correctly returns false.\n    false\n#else\n    true\n#endif\n    },\n  };\n\n  for (size_t i = 0; i < arraysize(convert_cases); i++) {\n    std::string converted;\n    errno = 0;\n    const bool success = WideToUTF8(convert_cases[i].utf16,\n                                    wcslen(convert_cases[i].utf16),\n                                    &converted);\n    EXPECT_EQ(convert_cases[i].success, success);\n    // The original test always compared expected and converted, but don't do\n    // that because our implementation of WideToUTF8() does not guarantee to\n    // produce the same output in error situations.\n    if (success) {\n      std::string expected(convert_cases[i].utf8);\n      EXPECT_EQ(expected, converted);\n    } else {\n      EXPECT_EQ(EILSEQ, errno);\n    }\n  }\n}\n\n#elif defined(WCHAR_T_IS_UTF32)\n// This test is only valid when wchar_t == UTF-32.\nTEST(UTFStringConversionsTest, ConvertUTF32ToUTF8) {\n  struct WideToUTF8Case {\n    const wchar_t* utf32;\n    const char* utf8;\n    bool success;\n  } convert_cases[] = {\n    // Regular 16-bit input.\n    {L\"\\x4f60\\x597d\", \"\\xe4\\xbd\\xa0\\xe5\\xa5\\xbd\", true},\n    // Test a non-BMP character.\n    {L\"A\\x10300z\", \"A\\xF0\\x90\\x8C\\x80z\", true},\n    // Non-characters are passed through.\n    {L\"\\xffffHello\", \"\\xEF\\xBF\\xBFHello\", true},\n    {L\"\\x10fffeHello\", \"\\xF4\\x8F\\xBF\\xBEHello\", true},\n    // Invalid Unicode code points.\n    {L\"\\xfffffffHello\", \"\\xEF\\xBF\\xBDHello\", false},\n    // The first character is a truncated UTF-16 character.\n    {L\"\\xd800\\x597d\", \"\\xef\\xbf\\xbd\\xe5\\xa5\\xbd\", false},\n    {L\"\\xdc01Hello\", \"\\xef\\xbf\\xbdHello\", false},\n  };\n\n  for (size_t i = 0; i < arraysize(convert_cases); i++) {\n    std::string converted;\n    EXPECT_EQ(convert_cases[i].success,\n              WideToUTF8(convert_cases[i].utf32,\n                         wcslen(convert_cases[i].utf32),\n                         &converted));\n    std::string expected(convert_cases[i].utf8);\n    EXPECT_EQ(expected, converted);\n  }\n}\n#endif  // defined(WCHAR_T_IS_UTF32)\n\n// The test below uses these types and functions, so just do enough to get the\n// test running.\ntypedef wchar_t char16;\ntypedef std::wstring string16;\n\ntemplate<typename T>\nstatic void* WriteInto(T* t, size_t size) {\n  // std::(w)string::resize() already includes space for a NULL terminator.\n  t->resize(size - 1);\n  return &(*t)[0];\n}\n\n// A stub implementation that calls a helper from above, just to get the test\n// below working. This is just for testing and should not be moved to base\n// because this ignores errors which is probably not a good idea, plus it takes\n// a string16 type which we don't really have.\nstatic std::string UTF16ToUTF8(const string16& utf16) {\n  return WideToUTF8(utf16);\n}\n\nTEST(UTFStringConversionsTest, ConvertMultiString) {\n  static char16 multi16[] = {\n    'f', 'o', 'o', '\\0',\n    'b', 'a', 'r', '\\0',\n    'b', 'a', 'z', '\\0',\n    '\\0'\n  };\n  static char multi[] = {\n    'f', 'o', 'o', '\\0',\n    'b', 'a', 'r', '\\0',\n    'b', 'a', 'z', '\\0',\n    '\\0'\n  };\n  string16 multistring16;\n  memcpy(WriteInto(&multistring16, arraysize(multi16)), multi16,\n                   sizeof(multi16));\n  EXPECT_EQ(arraysize(multi16) - 1, multistring16.length());\n  std::string expected;\n  memcpy(WriteInto(&expected, arraysize(multi)), multi, sizeof(multi));\n  EXPECT_EQ(arraysize(multi) - 1, expected.length());\n  const std::string& converted = UTF16ToUTF8(multistring16);\n  EXPECT_EQ(arraysize(multi) - 1, converted.length());\n  EXPECT_EQ(expected, converted);\n}\n\n// The tests below from sys_string_conversions_unittest.cc call SysWideToUTF8()\n// and SysUTF8ToWide(), so these are stub implementations that call the helpers\n// above. These are just for testing and should not be moved to base because\n// they ignore errors which is probably not a good idea.\n\nstatic std::string SysWideToUTF8(const std::wstring& utf16) {\n  return WideToUTF8(utf16);\n}\n\nstatic std::wstring SysUTF8ToWide(const std::string& utf8) {\n  return UTF8ToWide(utf8);\n}\n\n// Below is adapted from https://chromium.googlesource.com/chromium/src/+/master/base/strings/sys_string_conversions_unittest.cc\n\n// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n#ifdef WCHAR_T_IS_UTF32\nstatic const std::wstring kSysWideOldItalicLetterA = L\"\\x10300\";\n#else\nstatic const std::wstring kSysWideOldItalicLetterA = L\"\\xd800\\xdf00\";\n#endif\n\nTEST(SysStrings, SysWideToUTF8) {\n  EXPECT_EQ(\"Hello, world\", SysWideToUTF8(L\"Hello, world\"));\n  EXPECT_EQ(\"\\xe4\\xbd\\xa0\\xe5\\xa5\\xbd\", SysWideToUTF8(L\"\\x4f60\\x597d\"));\n\n  // >16 bits\n  EXPECT_EQ(\"\\xF0\\x90\\x8C\\x80\", SysWideToUTF8(kSysWideOldItalicLetterA));\n\n  // Error case. When Windows finds a UTF-16 character going off the end of\n  // a string, it just converts that literal value to UTF-8, even though this\n  // is invalid.\n  //\n  // This is what XP does, but Vista has different behavior, so we don't bother\n  // verifying it:\n  // EXPECT_EQ(\"\\xE4\\xBD\\xA0\\xED\\xA0\\x80zyxw\",\n  //           SysWideToUTF8(L\"\\x4f60\\xd800zyxw\"));\n\n  // Test embedded NULLs.\n  std::wstring wide_null(L\"a\");\n  wide_null.push_back(0);\n  wide_null.push_back('b');\n\n  std::string expected_null(\"a\");\n  expected_null.push_back(0);\n  expected_null.push_back('b');\n\n  EXPECT_EQ(expected_null, SysWideToUTF8(wide_null));\n}\n\nTEST(SysStrings, SysUTF8ToWide) {\n  EXPECT_EQ(L\"Hello, world\", SysUTF8ToWide(\"Hello, world\"));\n  EXPECT_EQ(L\"\\x4f60\\x597d\", SysUTF8ToWide(\"\\xe4\\xbd\\xa0\\xe5\\xa5\\xbd\"));\n  // >16 bits\n  EXPECT_EQ(kSysWideOldItalicLetterA, SysUTF8ToWide(\"\\xF0\\x90\\x8C\\x80\"));\n\n  // Error case. When Windows finds an invalid UTF-8 character, it just skips\n  // it. This seems weird because it's inconsistent with the reverse conversion.\n  //\n  // This is what XP does, but Vista has different behavior, so we don't bother\n  // verifying it:\n  // EXPECT_EQ(L\"\\x4f60zyxw\", SysUTF8ToWide(\"\\xe4\\xbd\\xa0\\xe5\\xa5zyxw\"));\n\n  // Test embedded NULLs.\n  std::string utf8_null(\"a\");\n  utf8_null.push_back(0);\n  utf8_null.push_back('b');\n\n  std::wstring expected_null(L\"a\");\n  expected_null.push_back(0);\n  expected_null.push_back('b');\n\n  EXPECT_EQ(expected_null, SysUTF8ToWide(utf8_null));\n}\n\n}  // namespace base\n}  // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/include/android/log.h",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _ANDROID_LOG_H\n#define _ANDROID_LOG_H\n\n/******************************************************************\n *\n * IMPORTANT NOTICE:\n *\n *   This file is part of Android's set of stable system headers\n *   exposed by the Android NDK (Native Development Kit) since\n *   platform release 1.5\n *\n *   Third-party source AND binary code relies on the definitions\n *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.\n *\n *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)\n *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS\n *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY\n *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES\n */\n\n/*\n * Support routines to send messages to the Android in-kernel log buffer,\n * which can later be accessed through the 'logcat' utility.\n *\n * Each log message must have\n *   - a priority\n *   - a log tag\n *   - some text\n *\n * The tag normally corresponds to the component that emits the log message,\n * and should be reasonably small.\n *\n * Log message text may be truncated to less than an implementation-specific\n * limit (e.g. 1023 characters max).\n *\n * Note that a newline character (\"\\n\") will be appended automatically to your\n * log message, if not already there. It is not possible to send several messages\n * and have them appear on a single line in logcat.\n *\n * PLEASE USE LOGS WITH MODERATION:\n *\n *  - Sending log messages eats CPU and slow down your application and the\n *    system.\n *\n *  - The circular log buffer is pretty small (<64KB), sending many messages\n *    might push off other important log messages from the rest of the system.\n *\n *  - In release builds, only send log messages to account for exceptional\n *    conditions.\n *\n * NOTE: These functions MUST be implemented by /system/lib/liblog.so\n */\n\n#include <stdarg.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n * Android log priority values, in ascending priority order.\n */\ntypedef enum android_LogPriority {\n    ANDROID_LOG_UNKNOWN = 0,\n    ANDROID_LOG_DEFAULT,    /* only for SetMinPriority() */\n    ANDROID_LOG_VERBOSE,\n    ANDROID_LOG_DEBUG,\n    ANDROID_LOG_INFO,\n    ANDROID_LOG_WARN,\n    ANDROID_LOG_ERROR,\n    ANDROID_LOG_FATAL,\n    ANDROID_LOG_SILENT,     /* only for SetMinPriority(); must be last */\n} android_LogPriority;\n\n/*\n * Send a simple string to the log.\n */\nint __android_log_write(int prio, const char *tag, const char *text);\n\n/*\n * Send a formatted string to the log, used like printf(fmt,...)\n */\nint __android_log_print(int prio, const char *tag,  const char *fmt, ...)\n#if defined(__GNUC__)\n#ifdef __USE_MINGW_ANSI_STDIO\n#if __USE_MINGW_ANSI_STDIO\n    __attribute__ ((format(gnu_printf, 3, 4)))\n#else\n    __attribute__ ((format(printf, 3, 4)))\n#endif\n#else\n    __attribute__ ((format(printf, 3, 4)))\n#endif\n#endif\n    ;\n\n/*\n * A variant of __android_log_print() that takes a va_list to list\n * additional parameters.\n */\nint __android_log_vprint(int prio, const char *tag,\n                         const char *fmt, va_list ap);\n\n/*\n * Log an assertion failure and abort the process to have a chance\n * to inspect it if a debugger is attached. This uses the FATAL priority.\n */\nvoid __android_log_assert(const char *cond, const char *tag,\n                          const char *fmt, ...)\n#if defined(__GNUC__)\n    __attribute__ ((noreturn))\n#ifdef __USE_MINGW_ANSI_STDIO\n#if __USE_MINGW_ANSI_STDIO\n    __attribute__ ((format(gnu_printf, 3, 4)))\n#else\n    __attribute__ ((format(printf, 3, 4)))\n#endif\n#else\n    __attribute__ ((format(printf, 3, 4)))\n#endif\n#endif\n    ;\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _ANDROID_LOG_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/backtrace/Backtrace.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _BACKTRACE_BACKTRACE_H\n#define _BACKTRACE_BACKTRACE_H\n\n#include <inttypes.h>\n#include <stdint.h>\n\n#include <string>\n#include <vector>\n\n#include <backtrace/backtrace_constants.h>\n#include <backtrace/BacktraceMap.h>\n\n#if __LP64__\n#define PRIPTR \"016\" PRIxPTR\ntypedef uint64_t word_t;\n#else\n#define PRIPTR \"08\" PRIxPTR\ntypedef uint32_t word_t;\n#endif\n\nenum BacktraceUnwindError : uint32_t {\n  BACKTRACE_UNWIND_NO_ERROR,\n  // Something failed while trying to perform the setup to begin the unwind.\n  BACKTRACE_UNWIND_ERROR_SETUP_FAILED,\n  // There is no map information to use with the unwind.\n  BACKTRACE_UNWIND_ERROR_MAP_MISSING,\n  // An error occurred that indicates a programming error.\n  BACKTRACE_UNWIND_ERROR_INTERNAL,\n  // The thread to unwind has disappeared before the unwind can begin.\n  BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST,\n  // The thread to unwind has not responded to a signal in a timely manner.\n  BACKTRACE_UNWIND_ERROR_THREAD_TIMEOUT,\n  // Attempt to do an unsupported operation.\n  BACKTRACE_UNWIND_ERROR_UNSUPPORTED_OPERATION,\n  // Attempt to do an offline unwind without a context.\n  BACKTRACE_UNWIND_ERROR_NO_CONTEXT,\n};\n\nstruct backtrace_frame_data_t {\n  size_t num;             // The current fame number.\n  uintptr_t pc;           // The absolute pc.\n  uintptr_t sp;           // The top of the stack.\n  size_t stack_size;      // The size of the stack, zero indicate an unknown stack size.\n  backtrace_map_t map;    // The map associated with the given pc.\n  std::string func_name;  // The function name associated with this pc, NULL if not found.\n  uintptr_t func_offset;  // pc relative to the start of the function, only valid if func_name is not NULL.\n};\n\n#if defined(__APPLE__)\nstruct __darwin_ucontext;\ntypedef __darwin_ucontext ucontext_t;\n#else\nstruct ucontext;\ntypedef ucontext ucontext_t;\n#endif\n\nstruct backtrace_stackinfo_t {\n  uint64_t start;\n  uint64_t end;\n  const uint8_t* data;\n};\n\nclass Backtrace {\npublic:\n  // Create the correct Backtrace object based on what is to be unwound.\n  // If pid < 0 or equals the current pid, then the Backtrace object\n  // corresponds to the current process.\n  // If pid < 0 or equals the current pid and tid >= 0, then the Backtrace\n  // object corresponds to a thread in the current process.\n  // If pid >= 0 and tid < 0, then the Backtrace object corresponds to a\n  // different process.\n  // Tracing a thread in a different process is not supported.\n  // If map is NULL, then create the map and manage it internally.\n  // If map is not NULL, the map is still owned by the caller.\n  static Backtrace* Create(pid_t pid, pid_t tid, BacktraceMap* map = NULL);\n\n  // Create an offline Backtrace object that can be used to do an unwind without a process\n  // that is still running. If cache_file is set to true, then elf information will be cached\n  // for this call. The cached information survives until the calling process ends. This means\n  // that subsequent calls to create offline Backtrace objects will continue to use the same\n  // cache. It also assumes that the elf files used for each offline unwind are the same.\n  static Backtrace* CreateOffline(pid_t pid, pid_t tid, BacktraceMap* map,\n                                  const backtrace_stackinfo_t& stack, bool cache_file = false);\n\n  virtual ~Backtrace();\n\n  // Get the current stack trace and store in the backtrace_ structure.\n  virtual bool Unwind(size_t num_ignore_frames, ucontext_t* context = NULL) = 0;\n\n  // Get the function name and offset into the function given the pc.\n  // If the string is empty, then no valid function name was found.\n  virtual std::string GetFunctionName(uintptr_t pc, uintptr_t* offset);\n\n  // Fill in the map data associated with the given pc.\n  virtual void FillInMap(uintptr_t pc, backtrace_map_t* map);\n\n  // Read the data at a specific address.\n  virtual bool ReadWord(uintptr_t ptr, word_t* out_value) = 0;\n\n  // Read arbitrary data from a specific address. If a read request would\n  // span from one map to another, this call only reads up until the end\n  // of the current map.\n  // Returns the total number of bytes actually read.\n  virtual size_t Read(uintptr_t addr, uint8_t* buffer, size_t bytes) = 0;\n\n  // Create a string representing the formatted line of backtrace information\n  // for a single frame.\n  virtual std::string FormatFrameData(size_t frame_num);\n  virtual std::string FormatFrameData(const backtrace_frame_data_t* frame);\n\n  pid_t Pid() const { return pid_; }\n  pid_t Tid() const { return tid_; }\n  size_t NumFrames() const { return frames_.size(); }\n\n  const backtrace_frame_data_t* GetFrame(size_t frame_num) {\n    if (frame_num >= frames_.size()) {\n      return NULL;\n    }\n    return &frames_[frame_num];\n  }\n\n  typedef std::vector<backtrace_frame_data_t>::iterator iterator;\n  iterator begin() { return frames_.begin(); }\n  iterator end() { return frames_.end(); }\n\n  typedef std::vector<backtrace_frame_data_t>::const_iterator const_iterator;\n  const_iterator begin() const { return frames_.begin(); }\n  const_iterator end() const { return frames_.end(); }\n\n  BacktraceMap* GetMap() { return map_; }\n\n  BacktraceUnwindError GetError() { return error_; }\n\n  std::string GetErrorString(BacktraceUnwindError error);\n\nprotected:\n  Backtrace(pid_t pid, pid_t tid, BacktraceMap* map);\n\n  // The name returned is not demangled, GetFunctionName() takes care of\n  // demangling the name.\n  virtual std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) = 0;\n\n  virtual bool VerifyReadWordArgs(uintptr_t ptr, word_t* out_value);\n\n  bool BuildMap();\n\n  pid_t pid_;\n  pid_t tid_;\n\n  BacktraceMap* map_;\n  bool map_shared_;\n\n  std::vector<backtrace_frame_data_t> frames_;\n\n  BacktraceUnwindError error_;\n};\n\n#endif // _BACKTRACE_BACKTRACE_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/backtrace/BacktraceMap.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _BACKTRACE_BACKTRACE_MAP_H\n#define _BACKTRACE_BACKTRACE_MAP_H\n\n#include <stdint.h>\n#include <sys/types.h>\n#ifdef USE_MINGW\n// MINGW does not define these constants.\n#define PROT_NONE 0\n#define PROT_READ 0x1\n#define PROT_WRITE 0x2\n#define PROT_EXEC 0x4\n#else\n#include <sys/mman.h>\n#endif\n\n#include <deque>\n#include <string>\n#include <vector>\n\nstruct backtrace_map_t {\n  uintptr_t start = 0;\n  uintptr_t end = 0;\n  uintptr_t offset = 0;\n  uintptr_t load_base = 0;\n  int flags = 0;\n  std::string name;\n};\n\nclass BacktraceMap {\npublic:\n  // If uncached is true, then parse the current process map as of the call.\n  // Passing a map created with uncached set to true to Backtrace::Create()\n  // is unsupported.\n  static BacktraceMap* Create(pid_t pid, bool uncached = false);\n\n  static BacktraceMap* Create(pid_t pid, const std::vector<backtrace_map_t>& maps);\n\n  virtual ~BacktraceMap();\n\n  // Fill in the map data structure for the given address.\n  virtual void FillIn(uintptr_t addr, backtrace_map_t* map);\n\n  // The flags returned are the same flags as used by the mmap call.\n  // The values are PROT_*.\n  int GetFlags(uintptr_t pc) {\n    backtrace_map_t map;\n    FillIn(pc, &map);\n    if (IsValid(map)) {\n      return map.flags;\n    }\n    return PROT_NONE;\n  }\n\n  bool IsReadable(uintptr_t pc) { return GetFlags(pc) & PROT_READ; }\n  bool IsWritable(uintptr_t pc) { return GetFlags(pc) & PROT_WRITE; }\n  bool IsExecutable(uintptr_t pc) { return GetFlags(pc) & PROT_EXEC; }\n\n  typedef std::deque<backtrace_map_t>::iterator iterator;\n  iterator begin() { return maps_.begin(); }\n  iterator end() { return maps_.end(); }\n\n  typedef std::deque<backtrace_map_t>::const_iterator const_iterator;\n  const_iterator begin() const { return maps_.begin(); }\n  const_iterator end() const { return maps_.end(); }\n\n  virtual bool Build();\n\n  static inline bool IsValid(const backtrace_map_t& map) {\n    return map.end > 0;\n  }\n\n  static uintptr_t GetRelativePc(const backtrace_map_t& map, uintptr_t pc) {\n    if (IsValid(map)) {\n      return pc - map.start + map.load_base;\n    } else {\n      return pc;\n    }\n  }\n\nprotected:\n  BacktraceMap(pid_t pid);\n\n  virtual bool ParseLine(const char* line, backtrace_map_t* map);\n\n  std::deque<backtrace_map_t> maps_;\n  pid_t pid_;\n};\n\n#endif // _BACKTRACE_BACKTRACE_MAP_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/backtrace/backtrace_constants.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _BACKTRACE_BACKTRACE_CONSTANTS_H\n#define _BACKTRACE_BACKTRACE_CONSTANTS_H\n\n// When the pid to be traced is set to this value, then trace the current\n// process. If the tid value is not BACKTRACE_NO_TID, then the specified\n// thread from the current process will be traced.\n#define BACKTRACE_CURRENT_PROCESS -1\n// When the tid to be traced is set to this value, then trace the specified\n// current thread of the specified pid.\n#define BACKTRACE_CURRENT_THREAD -1\n\n#define MAX_BACKTRACE_FRAMES 64\n\n#endif // _BACKTRACE_BACKTRACE_CONSTANTS_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/binderwrapper/binder_test_base.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_TEST_BASE_H_\n#define SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_TEST_BASE_H_\n\n#include <base/macros.h>\n#include <gtest/gtest.h>\n\nnamespace android {\n\nclass StubBinderWrapper;\n\n// Class that can be inherited from (or aliased via typedef/using) when writing\n// tests that use StubBinderManager.\nclass BinderTestBase : public ::testing::Test {\n public:\n  BinderTestBase();\n  ~BinderTestBase() override;\n\n  StubBinderWrapper* binder_wrapper() { return binder_wrapper_; }\n\n protected:\n  StubBinderWrapper* binder_wrapper_;  // Not owned.\n\n private:\n  DISALLOW_COPY_AND_ASSIGN(BinderTestBase);\n};\n\n}  // namespace android\n\n#endif  // SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_TEST_BASE_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/include/binderwrapper/binder_wrapper.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_WRAPPER_H_\n#define SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_WRAPPER_H_\n\n#include <sys/types.h>\n\n#include <string>\n\n#include <base/callback.h>\n#include <utils/StrongPointer.h>\n\nnamespace android {\n\nclass BBinder;\nclass IBinder;\n\n// Wraps libbinder to make it testable.\n// NOTE: Static methods of this class are not thread-safe.\nclass BinderWrapper {\n public:\n  virtual ~BinderWrapper() {}\n\n  // Creates and initializes the singleton (using a wrapper that communicates\n  // with the real binder system).\n  static void Create();\n\n  // Initializes |wrapper| as the singleton, taking ownership of it. Tests that\n  // want to inject their own wrappers should call this instead of Create().\n  static void InitForTesting(BinderWrapper* wrapper);\n\n  // Destroys the singleton. Must be called before calling Create() or\n  // InitForTesting() a second time.\n  static void Destroy();\n\n  // Returns the singleton instance previously created by Create() or set by\n  // InitForTesting().\n  static BinderWrapper* Get();\n\n  // Returns the singleton instance if it was previously created by Create() or\n  // set by InitForTesting(), or creates a new one by calling Create().\n  static BinderWrapper* GetOrCreateInstance();\n\n  // Gets the binder for communicating with the service identified by\n  // |service_name|, returning null immediately if it doesn't exist.\n  virtual sp<IBinder> GetService(const std::string& service_name) = 0;\n\n  // Registers |binder| as |service_name| with the service manager.\n  virtual bool RegisterService(const std::string& service_name,\n                               const sp<IBinder>& binder) = 0;\n\n  // Creates a local binder object.\n  virtual sp<BBinder> CreateLocalBinder() = 0;\n\n  // Registers |callback| to be invoked when |binder| dies. If another callback\n  // is currently registered for |binder|, it will be replaced.\n  virtual bool RegisterForDeathNotifications(\n      const sp<IBinder>& binder,\n      const base::Closure& callback) = 0;\n\n  // Unregisters the callback, if any, for |binder|.\n  virtual bool UnregisterForDeathNotifications(const sp<IBinder>& binder) = 0;\n\n  // When called while in a transaction, returns the caller's UID or PID.\n  virtual uid_t GetCallingUid() = 0;\n  virtual pid_t GetCallingPid() = 0;\n\n private:\n  static BinderWrapper* instance_;\n};\n\n}  // namespace android\n\n#endif  // SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_WRAPPER_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/include/binderwrapper/stub_binder_wrapper.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef SYSTEM_CORE_INCLUDE_BINDERWRAPPER_STUB_BINDER_WRAPPER_H_\n#define SYSTEM_CORE_INCLUDE_BINDERWRAPPER_STUB_BINDER_WRAPPER_H_\n\n#include <map>\n#include <string>\n#include <vector>\n\n#include <base/macros.h>\n#include <binder/Binder.h>\n#include <binder/IBinder.h>\n#include <binderwrapper/binder_wrapper.h>\n\nnamespace android {\n\n// Stub implementation of BinderWrapper for testing.\n//\n// Example usage:\n//\n// First, assuming a base IFoo binder interface, create a stub class that\n// derives from BnFoo to implement the receiver side of the communication:\n//\n//   class StubFoo : public BnFoo {\n//    public:\n//     ...\n//     status_t doSomething(int arg) override {\n//       // e.g. save passed-in value for later inspection by tests.\n//       return OK;\n//     }\n//   };\n//\n// Next, from your test code, inject a StubBinderManager either directly or by\n// inheriting from the BinderTestBase class:\n//\n//   StubBinderWrapper* wrapper = new StubBinderWrapper();\n//   BinderWrapper::InitForTesting(wrapper);  // Takes ownership.\n//\n// Also from your test, create a StubFoo and register it with the wrapper:\n//\n//   StubFoo* foo = new StubFoo();\n//   sp<IBinder> binder(foo);\n//   wrapper->SetBinderForService(\"foo\", binder);\n//\n// The code being tested can now use the wrapper to get the stub and call it:\n//\n//   sp<IBinder> binder = BinderWrapper::Get()->GetService(\"foo\");\n//   CHECK(binder.get());\n//   sp<IFoo> foo = interface_cast<IFoo>(binder);\n//   CHECK_EQ(foo->doSomething(3), OK);\n//\n// To create a local BBinder object, production code can call\n// CreateLocalBinder(). Then, a test can get the BBinder's address via\n// local_binders() to check that they're passed as expected in binder calls.\n//\nclass StubBinderWrapper : public BinderWrapper {\n public:\n  StubBinderWrapper();\n  ~StubBinderWrapper() override;\n\n  const std::vector<sp<BBinder>>& local_binders() const {\n    return local_binders_;\n  }\n  void clear_local_binders() { local_binders_.clear(); }\n\n  void set_calling_uid(uid_t uid) { calling_uid_ = uid; }\n  void set_calling_pid(pid_t pid) { calling_pid_ = pid; }\n\n  // Sets the binder to return when |service_name| is passed to GetService() or\n  // WaitForService().\n  void SetBinderForService(const std::string& service_name,\n                           const sp<IBinder>& binder);\n\n  // Returns the binder previously registered for |service_name| via\n  // RegisterService(), or null if the service hasn't been registered.\n  sp<IBinder> GetRegisteredService(const std::string& service_name) const;\n\n  // Run the calback in |death_callbacks_| corresponding to |binder|.\n  void NotifyAboutBinderDeath(const sp<IBinder>& binder);\n\n  // BinderWrapper:\n  sp<IBinder> GetService(const std::string& service_name) override;\n  bool RegisterService(const std::string& service_name,\n                       const sp<IBinder>& binder) override;\n  sp<BBinder> CreateLocalBinder() override;\n  bool RegisterForDeathNotifications(const sp<IBinder>& binder,\n                                     const base::Closure& callback) override;\n  bool UnregisterForDeathNotifications(const sp<IBinder>& binder) override;\n  uid_t GetCallingUid() override;\n  pid_t GetCallingPid() override;\n\n private:\n  using ServiceMap = std::map<std::string, sp<IBinder>>;\n\n  // Map from service name to associated binder handle. Used by GetService() and\n  // WaitForService().\n  ServiceMap services_to_return_;\n\n  // Map from service name to associated binder handle. Updated by\n  // RegisterService().\n  ServiceMap registered_services_;\n\n  // Local binders returned by CreateLocalBinder().\n  std::vector<sp<BBinder>> local_binders_;\n\n  // Map from binder handle to the callback that should be invoked on binder\n  // death.\n  std::map<sp<IBinder>, base::Closure> death_callbacks_;\n\n  // Values to return from GetCallingUid() and GetCallingPid();\n  uid_t calling_uid_;\n  pid_t calling_pid_;\n\n  DISALLOW_COPY_AND_ASSIGN(StubBinderWrapper);\n};\n\n}  // namespace android\n\n#endif  // SYSTEM_CORE_INCLUDE_BINDERWRAPPER_STUB_BINDER_WRAPPER_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/android_reboot.h",
    "content": "/*\n * Copyright 2011, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_ANDROID_REBOOT_H__\n#define __CUTILS_ANDROID_REBOOT_H__\n\n#include <mntent.h>\n\n__BEGIN_DECLS\n\n/* Commands */\n#define ANDROID_RB_RESTART  0xDEAD0001\n#define ANDROID_RB_POWEROFF 0xDEAD0002\n#define ANDROID_RB_RESTART2 0xDEAD0003\n\n/* Properties */\n#define ANDROID_RB_PROPERTY \"sys.powerctl\"\n\nint android_reboot(int cmd, int flags, const char *arg);\nint android_reboot_with_callback(\n    int cmd, int flags, const char *arg,\n    void (*cb_on_remount)(const struct mntent*));\n\n__END_DECLS\n\n#endif /* __CUTILS_ANDROID_REBOOT_H__ */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/ashmem.h",
    "content": "/* cutils/ashmem.h\n **\n ** Copyright 2008 The Android Open Source Project\n **\n ** This file is dual licensed.  It may be redistributed and/or modified\n ** under the terms of the Apache 2.0 License OR version 2 of the GNU\n ** General Public License.\n */\n\n#ifndef _CUTILS_ASHMEM_H\n#define _CUTILS_ASHMEM_H\n\n#include <stddef.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nint ashmem_create_region(const char *name, size_t size);\nint ashmem_set_prot_region(int fd, int prot);\nint ashmem_pin_region(int fd, size_t offset, size_t len);\nint ashmem_unpin_region(int fd, size_t offset, size_t len);\nint ashmem_get_size_region(int fd);\n\n#ifdef __cplusplus\n}\n#endif\n\n#ifndef __ASHMEMIOC\t/* in case someone included <linux/ashmem.h> too */\n\n#define ASHMEM_NAME_LEN\t\t256\n\n#define ASHMEM_NAME_DEF\t\t\"dev/ashmem\"\n\n/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */\n#define ASHMEM_NOT_PURGED\t0\n#define ASHMEM_WAS_PURGED\t1\n\n/* Return values from ASHMEM_UNPIN: Is the mapping now pinned or unpinned? */\n#define ASHMEM_IS_UNPINNED\t0\n#define ASHMEM_IS_PINNED\t1\n\n#endif\t/* ! __ASHMEMIOC */\n\n#endif\t/* _CUTILS_ASHMEM_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/atomic.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_CUTILS_ATOMIC_H\n#define ANDROID_CUTILS_ATOMIC_H\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <stdatomic.h>\n\n#ifndef ANDROID_ATOMIC_INLINE\n#define ANDROID_ATOMIC_INLINE static inline\n#endif\n\n/*\n * A handful of basic atomic operations.\n * THESE ARE HERE FOR LEGACY REASONS ONLY.  AVOID.\n *\n * PREFERRED ALTERNATIVES:\n * - Use C++/C/pthread locks/mutexes whenever there is not a\n *   convincing reason to do otherwise.  Note that very clever and\n *   complicated, but correct, lock-free code is often slower than\n *   using locks, especially where nontrivial data structures\n *   are involved.\n * - C11 stdatomic.h.\n * - Where supported, C++11 std::atomic<T> .\n *\n * PLEASE STOP READING HERE UNLESS YOU ARE TRYING TO UNDERSTAND\n * OR UPDATE OLD CODE.\n *\n * The \"acquire\" and \"release\" terms can be defined intuitively in terms\n * of the placement of memory barriers in a simple lock implementation:\n *   - wait until compare-and-swap(lock-is-free --> lock-is-held) succeeds\n *   - barrier\n *   - [do work]\n *   - barrier\n *   - store(lock-is-free)\n * In very crude terms, the initial (acquire) barrier prevents any of the\n * \"work\" from happening before the lock is held, and the later (release)\n * barrier ensures that all of the work happens before the lock is released.\n * (Think of cached writes, cache read-ahead, and instruction reordering\n * around the CAS and store instructions.)\n *\n * The barriers must apply to both the compiler and the CPU.  Note it is\n * legal for instructions that occur before an \"acquire\" barrier to be\n * moved down below it, and for instructions that occur after a \"release\"\n * barrier to be moved up above it.\n *\n * The ARM-driven implementation we use here is short on subtlety,\n * and actually requests a full barrier from the compiler and the CPU.\n * The only difference between acquire and release is in whether they\n * are issued before or after the atomic operation with which they\n * are associated.  To ease the transition to C/C++ atomic intrinsics,\n * you should not rely on this, and instead assume that only the minimal\n * acquire/release protection is provided.\n *\n * NOTE: all int32_t* values are expected to be aligned on 32-bit boundaries.\n * If they are not, atomicity is not guaranteed.\n */\n\n/*\n * Basic arithmetic and bitwise operations.  These all provide a\n * barrier with \"release\" ordering, and return the previous value.\n *\n * These have the same characteristics (e.g. what happens on overflow)\n * as the equivalent non-atomic C operations.\n */\nANDROID_ATOMIC_INLINE\nint32_t android_atomic_inc(volatile int32_t* addr)\n{\n    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;\n        /* Int32_t, if it exists, is the same as int_least32_t. */\n    return atomic_fetch_add_explicit(a, 1, memory_order_release);\n}\n\nANDROID_ATOMIC_INLINE\nint32_t android_atomic_dec(volatile int32_t* addr)\n{\n    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;\n    return atomic_fetch_sub_explicit(a, 1, memory_order_release);\n}\n\nANDROID_ATOMIC_INLINE\nint32_t android_atomic_add(int32_t value, volatile int32_t* addr)\n{\n    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;\n    return atomic_fetch_add_explicit(a, value, memory_order_release);\n}\n\nANDROID_ATOMIC_INLINE\nint32_t android_atomic_and(int32_t value, volatile int32_t* addr)\n{\n    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;\n    return atomic_fetch_and_explicit(a, value, memory_order_release);\n}\n\nANDROID_ATOMIC_INLINE\nint32_t android_atomic_or(int32_t value, volatile int32_t* addr)\n{\n    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;\n    return atomic_fetch_or_explicit(a, value, memory_order_release);\n}\n\n/*\n * Perform an atomic load with \"acquire\" or \"release\" ordering.\n *\n * Note that the notion of a \"release\" ordering for a load does not\n * really fit into the C11 or C++11 memory model.  The extra ordering\n * is normally observable only by code using memory_order_relaxed\n * atomics, or data races.  In the rare cases in which such ordering\n * is called for, use memory_order_relaxed atomics and a leading\n * atomic_thread_fence (typically with memory_order_acquire,\n * not memory_order_release!) instead.  If you do not understand\n * this comment, you are in the vast majority, and should not be\n * using release loads or replacing them with anything other than\n * locks or default sequentially consistent atomics.\n */\nANDROID_ATOMIC_INLINE\nint32_t android_atomic_acquire_load(volatile const int32_t* addr)\n{\n    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;\n    return atomic_load_explicit(a, memory_order_acquire);\n}\n\nANDROID_ATOMIC_INLINE\nint32_t android_atomic_release_load(volatile const int32_t* addr)\n{\n    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;\n    atomic_thread_fence(memory_order_seq_cst);\n    /* Any reasonable clients of this interface would probably prefer   */\n    /* something weaker.  But some remaining clients seem to be         */\n    /* abusing this API in strange ways, e.g. by using it as a fence.   */\n    /* Thus we are conservative until we can get rid of remaining       */\n    /* clients (and this function).                                     */\n    return atomic_load_explicit(a, memory_order_relaxed);\n}\n\n/*\n * Perform an atomic store with \"acquire\" or \"release\" ordering.\n *\n * Note that the notion of an \"acquire\" ordering for a store does not\n * really fit into the C11 or C++11 memory model.  The extra ordering\n * is normally observable only by code using memory_order_relaxed\n * atomics, or data races.  In the rare cases in which such ordering\n * is called for, use memory_order_relaxed atomics and a trailing\n * atomic_thread_fence (typically with memory_order_release,\n * not memory_order_acquire!) instead.\n */\nANDROID_ATOMIC_INLINE\nvoid android_atomic_acquire_store(int32_t value, volatile int32_t* addr)\n{\n    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;\n    atomic_store_explicit(a, value, memory_order_relaxed);\n    atomic_thread_fence(memory_order_seq_cst);\n    /* Again overly conservative to accomodate weird clients.   */\n}\n\nANDROID_ATOMIC_INLINE\nvoid android_atomic_release_store(int32_t value, volatile int32_t* addr)\n{\n    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;\n    atomic_store_explicit(a, value, memory_order_release);\n}\n\n/*\n * Compare-and-set operation with \"acquire\" or \"release\" ordering.\n *\n * This returns zero if the new value was successfully stored, which will\n * only happen when *addr == oldvalue.\n *\n * (The return value is inverted from implementations on other platforms,\n * but matches the ARM ldrex/strex result.)\n *\n * Implementations that use the release CAS in a loop may be less efficient\n * than possible, because we re-issue the memory barrier on each iteration.\n */\nANDROID_ATOMIC_INLINE\nint android_atomic_acquire_cas(int32_t oldvalue, int32_t newvalue,\n                           volatile int32_t* addr)\n{\n    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;\n    return (int)(!atomic_compare_exchange_strong_explicit(\n                                          a, &oldvalue, newvalue,\n                                          memory_order_acquire,\n                                          memory_order_acquire));\n}\n\nANDROID_ATOMIC_INLINE\nint android_atomic_release_cas(int32_t oldvalue, int32_t newvalue,\n                               volatile int32_t* addr)\n{\n    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;\n    return (int)(!atomic_compare_exchange_strong_explicit(\n                                          a, &oldvalue, newvalue,\n                                          memory_order_release,\n                                          memory_order_relaxed));\n}\n\n/*\n * Fence primitives.\n */\nANDROID_ATOMIC_INLINE\nvoid android_compiler_barrier(void)\n{\n    __asm__ __volatile__ (\"\" : : : \"memory\");\n    /* Could probably also be:                          */\n    /* atomic_signal_fence(memory_order_seq_cst);       */\n}\n\nANDROID_ATOMIC_INLINE\nvoid android_memory_barrier(void)\n{\n    atomic_thread_fence(memory_order_seq_cst);\n}\n\n/*\n * Aliases for code using an older version of this header.  These are now\n * deprecated and should not be used.  The definitions will be removed\n * in a future release.\n */\n#define android_atomic_write android_atomic_release_store\n#define android_atomic_cmpxchg android_atomic_release_cas\n\n#endif // ANDROID_CUTILS_ATOMIC_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/bitops.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_BITOPS_H\n#define __CUTILS_BITOPS_H\n\n#include <stdbool.h>\n#include <string.h>\n#include <strings.h>\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\n/*\n * Bitmask Operations\n *\n * Note this doesn't provide any locking/exclusion, and isn't atomic.\n * Additionally no bounds checking is done on the bitmask array.\n *\n * Example:\n *\n * int num_resources;\n * unsigned int resource_bits[BITS_TO_WORDS(num_resources)];\n * bitmask_init(resource_bits, num_resources);\n * ...\n * int bit = bitmask_ffz(resource_bits, num_resources);\n * bitmask_set(resource_bits, bit);\n * ...\n * if (bitmask_test(resource_bits, bit)) { ... }\n * ...\n * bitmask_clear(resource_bits, bit);\n *\n */\n\n#define BITS_PER_WORD    (sizeof(unsigned int) * 8)\n#define BITS_TO_WORDS(x) (((x) + BITS_PER_WORD - 1) / BITS_PER_WORD)\n#define BIT_IN_WORD(x)   ((x) % BITS_PER_WORD)\n#define BIT_WORD(x)      ((x) / BITS_PER_WORD)\n#define BIT_MASK(x)      (1 << BIT_IN_WORD(x))\n\nstatic inline void bitmask_init(unsigned int *bitmask, int num_bits)\n{\n    memset(bitmask, 0, BITS_TO_WORDS(num_bits)*sizeof(unsigned int));\n}\n\nstatic inline int bitmask_ffz(unsigned int *bitmask, int num_bits)\n{\n    int bit, result;\n    size_t i;\n\n    for (i = 0; i < BITS_TO_WORDS(num_bits); i++) {\n        bit = ffs(~bitmask[i]);\n        if (bit) {\n            // ffs is 1-indexed, return 0-indexed result\n            bit--;\n            result = BITS_PER_WORD * i + bit;\n            if (result >= num_bits)\n                return -1;\n            return result;\n        }\n    }\n    return -1;\n}\n\nstatic inline int bitmask_weight(unsigned int *bitmask, int num_bits)\n{\n    size_t i;\n    int weight = 0;\n\n    for (i = 0; i < BITS_TO_WORDS(num_bits); i++)\n        weight += __builtin_popcount(bitmask[i]);\n    return weight;\n}\n\nstatic inline void bitmask_set(unsigned int *bitmask, int bit)\n{\n    bitmask[BIT_WORD(bit)] |= BIT_MASK(bit);\n}\n\nstatic inline void bitmask_clear(unsigned int *bitmask, int bit)\n{\n    bitmask[BIT_WORD(bit)] &= ~BIT_MASK(bit);\n}\n\nstatic inline bool bitmask_test(unsigned int *bitmask, int bit)\n{\n    return bitmask[BIT_WORD(bit)] & BIT_MASK(bit);\n}\n\nstatic inline int popcount(unsigned int x)\n{\n    return __builtin_popcount(x);\n}\n\nstatic inline int popcountl(unsigned long x)\n{\n    return __builtin_popcountl(x);\n}\n\nstatic inline int popcountll(unsigned long long x)\n{\n    return __builtin_popcountll(x);\n}\n\n__END_DECLS\n\n#endif /* __CUTILS_BITOPS_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/compiler.h",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_CUTILS_COMPILER_H\n#define ANDROID_CUTILS_COMPILER_H\n\n/*\n * helps the compiler's optimizer predicting branches\n */\n\n#ifdef __cplusplus\n#   define CC_LIKELY( exp )    (__builtin_expect( !!(exp), true ))\n#   define CC_UNLIKELY( exp )  (__builtin_expect( !!(exp), false ))\n#else\n#   define CC_LIKELY( exp )    (__builtin_expect( !!(exp), 1 ))\n#   define CC_UNLIKELY( exp )  (__builtin_expect( !!(exp), 0 ))\n#endif\n\n/**\n * exports marked symbols\n *\n * if used on a C++ class declaration, this macro must be inserted\n * after the \"class\" keyword. For instance:\n *\n * template <typename TYPE>\n * class ANDROID_API Singleton { }\n */\n\n#define ANDROID_API __attribute__((visibility(\"default\")))\n\n#endif // ANDROID_CUTILS_COMPILER_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/config_utils.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_CONFIG_UTILS_H\n#define __CUTILS_CONFIG_UTILS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n    \ntypedef struct cnode cnode;\n\n\nstruct cnode\n{\n    cnode *next;\n    cnode *first_child;\n    cnode *last_child;\n    const char *name;\n    const char *value;\n};\n\n/* parse a text string into a config node tree */\nvoid config_load(cnode *root, char *data);\n\n/* parse a file into a config node tree */\nvoid config_load_file(cnode *root, const char *fn);\n\n/* create a single config node */\ncnode* config_node(const char *name, const char *value);\n\n/* locate a named child of a config node */\ncnode* config_find(cnode *root, const char *name);\n\n/* look up a child by name and return the boolean value */\nint config_bool(cnode *root, const char *name, int _default);\n\n/* look up a child by name and return the string value */\nconst char* config_str(cnode *root, const char *name, const char *_default);\n\n/* add a named child to a config node (or modify it if it already exists) */\nvoid config_set(cnode *root, const char *name, const char *value);\n\n/* free a config node tree */\nvoid config_free(cnode *root);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/debugger.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_DEBUGGER_H\n#define __CUTILS_DEBUGGER_H\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n__BEGIN_DECLS\n\n#define DEBUGGER_SOCKET_NAME \"android:debuggerd\"\n#define DEBUGGER32_SOCKET_NAME \"android:debuggerd32\"\n#define DEBUGGER64_SOCKET_NAME DEBUGGER_SOCKET_NAME\n\ntypedef enum {\n    // dump a crash\n    DEBUGGER_ACTION_CRASH,\n    // dump a tombstone file\n    DEBUGGER_ACTION_DUMP_TOMBSTONE,\n    // dump a backtrace only back to the socket\n    DEBUGGER_ACTION_DUMP_BACKTRACE,\n} debugger_action_t;\n\n// Make sure that all values have a fixed size so that this structure\n// is the same for 32 bit and 64 bit processes.\n// NOTE: Any changes to this structure must also be reflected in\n//       bionic/linker/debugger.cpp.\ntypedef struct __attribute__((packed)) {\n    int32_t action;\n    pid_t tid;\n    uint64_t abort_msg_address;\n    int32_t original_si_code;\n} debugger_msg_t;\n\n/* Dumps a process backtrace, registers, and stack to a tombstone file (requires root).\n * Stores the tombstone path in the provided buffer.\n * Returns 0 on success, -1 on error.\n */\nint dump_tombstone(pid_t tid, char* pathbuf, size_t pathlen);\n\n/* Dumps a process backtrace, registers, and stack to a tombstone file (requires root).\n * Stores the tombstone path in the provided buffer.\n * If reading debugger data from debuggerd ever takes longer than timeout_secs\n * seconds, then stop and return an error.\n * Returns 0 on success, -1 on error.\n */\nint dump_tombstone_timeout(pid_t tid, char* pathbuf, size_t pathlen, int timeout_secs);\n\n/* Dumps a process backtrace only to the specified file (requires root).\n * Returns 0 on success, -1 on error.\n */\nint dump_backtrace_to_file(pid_t tid, int fd);\n\n/* Dumps a process backtrace only to the specified file (requires root).\n * If reading debugger data from debuggerd ever takes longer than timeout_secs\n * seconds, then stop and return an error.\n * Returns 0 on success, -1 on error.\n */\nint dump_backtrace_to_file_timeout(pid_t tid, int fd, int timeout_secs);\n\n__END_DECLS\n\n#endif /* __CUTILS_DEBUGGER_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/fs.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_FS_H\n#define __CUTILS_FS_H\n\n#include <sys/types.h>\n#include <unistd.h>\n\n/*\n * TEMP_FAILURE_RETRY is defined by some, but not all, versions of\n * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's\n * not already defined, then define it here.\n */\n#ifndef TEMP_FAILURE_RETRY\n/* Used to retry syscalls that can return EINTR. */\n#define TEMP_FAILURE_RETRY(exp) ({         \\\n    typeof (exp) _rc;                      \\\n    do {                                   \\\n        _rc = (exp);                       \\\n    } while (_rc == -1 && errno == EINTR); \\\n    _rc; })\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n * Ensure that directory exists with given mode and owners.  If it exists\n * with a different mode or owners, they are fixed to match the given values.\n */\nextern int fs_prepare_dir(const char* path, mode_t mode, uid_t uid, gid_t gid);\n\n/*\n * Ensure that directory exists with given mode and owners.  If it exists\n * with different owners, they are not fixed and -1 is returned.\n */\nextern int fs_prepare_dir_strict(const char* path, mode_t mode, uid_t uid, gid_t gid);\n\n/*\n * Ensure that file exists with given mode and owners.  If it exists\n * with different owners, they are not fixed and -1 is returned.\n */\nextern int fs_prepare_file_strict(const char* path, mode_t mode, uid_t uid, gid_t gid);\n\n\n/*\n * Read single plaintext integer from given file, correctly handling files\n * partially written with fs_write_atomic_int().\n */\nextern int fs_read_atomic_int(const char* path, int* value);\n\n/*\n * Write single plaintext integer to given file, creating backup while\n * in progress.\n */\nextern int fs_write_atomic_int(const char* path, int value);\n\n/*\n * Ensure that all directories along given path exist, creating parent\n * directories as needed.  Validates that given path is absolute and that\n * it contains no relative \".\" or \"..\" paths or symlinks.  Last path segment\n * is treated as filename and ignored, unless the path ends with \"/\".\n */\nextern int fs_mkdirs(const char* path, mode_t mode);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __CUTILS_FS_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/hashmap.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Hash map.\n */\n\n#ifndef __HASHMAP_H\n#define __HASHMAP_H\n\n#include <stdbool.h>\n#include <stdlib.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** A hash map. */\ntypedef struct Hashmap Hashmap;\n\n/**\n * Creates a new hash map. Returns NULL if memory allocation fails.\n *\n * @param initialCapacity number of expected entries\n * @param hash function which hashes keys\n * @param equals function which compares keys for equality\n */\nHashmap* hashmapCreate(size_t initialCapacity,\n        int (*hash)(void* key), bool (*equals)(void* keyA, void* keyB));\n\n/**\n * Frees the hash map. Does not free the keys or values themselves.\n */\nvoid hashmapFree(Hashmap* map);\n\n/**\n * Hashes the memory pointed to by key with the given size. Useful for\n * implementing hash functions.\n */\nint hashmapHash(void* key, size_t keySize);\n\n/**\n * Puts value for the given key in the map. Returns pre-existing value if\n * any.\n *\n * If memory allocation fails, this function returns NULL, the map's size\n * does not increase, and errno is set to ENOMEM.\n */\nvoid* hashmapPut(Hashmap* map, void* key, void* value);\n\n/**\n * Gets a value from the map. Returns NULL if no entry for the given key is\n * found or if the value itself is NULL.\n */\nvoid* hashmapGet(Hashmap* map, void* key);\n\n/**\n * Returns true if the map contains an entry for the given key.\n */\nbool hashmapContainsKey(Hashmap* map, void* key);\n\n/**\n * Gets the value for a key. If a value is not found, this function gets a \n * value and creates an entry using the given callback.\n *\n * If memory allocation fails, the callback is not called, this function\n * returns NULL, and errno is set to ENOMEM.\n */\nvoid* hashmapMemoize(Hashmap* map, void* key, \n        void* (*initialValue)(void* key, void* context), void* context);\n\n/**\n * Removes an entry from the map. Returns the removed value or NULL if no\n * entry was present.\n */\nvoid* hashmapRemove(Hashmap* map, void* key);\n\n/**\n * Gets the number of entries in this map.\n */\nsize_t hashmapSize(Hashmap* map);\n\n/**\n * Invokes the given callback on each entry in the map. Stops iterating if\n * the callback returns false.\n */\nvoid hashmapForEach(Hashmap* map, \n        bool (*callback)(void* key, void* value, void* context),\n        void* context);\n\n/**\n * Concurrency support.\n */\n\n/**\n * Locks the hash map so only the current thread can access it.\n */\nvoid hashmapLock(Hashmap* map);\n\n/**\n * Unlocks the hash map so other threads can access it.\n */\nvoid hashmapUnlock(Hashmap* map);\n\n/**\n * Key utilities.\n */\n\n/**\n * Hashes int keys. 'key' is a pointer to int.\n */\nint hashmapIntHash(void* key);\n\n/**\n * Compares two int keys for equality.\n */\nbool hashmapIntEquals(void* keyA, void* keyB);\n\n/**\n * For debugging.\n */\n\n/**\n * Gets current capacity.\n */\nsize_t hashmapCurrentCapacity(Hashmap* map);\n\n/**\n * Counts the number of entry collisions.\n */\nsize_t hashmapCountCollisions(Hashmap* map);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __HASHMAP_H */ \n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/iosched_policy.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_IOSCHED_POLICY_H\n#define __CUTILS_IOSCHED_POLICY_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef enum {\n    IoSchedClass_NONE,\n    IoSchedClass_RT,\n    IoSchedClass_BE,\n    IoSchedClass_IDLE,\n} IoSchedClass;\n\nextern int android_set_ioprio(int pid, IoSchedClass clazz, int ioprio);\nextern int android_get_ioprio(int pid, IoSchedClass *clazz, int *ioprio);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __CUTILS_IOSCHED_POLICY_H */ \n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/jstring.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_STRING16_H\n#define __CUTILS_STRING16_H\n\n#include <stdint.h>\n#include <stddef.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#if __STDC_VERSION__ < 201112L && __cplusplus < 201103L\n  typedef uint16_t char16_t;\n#endif\n  // otherwise char16_t is a keyword with the right semantics\n\nextern char * strndup16to8 (const char16_t* s, size_t n);\nextern size_t strnlen16to8 (const char16_t* s, size_t n);\nextern char * strncpy16to8 (char *dest, const char16_t*s, size_t n);\n\nextern char16_t * strdup8to16 (const char* s, size_t *out_len);\nextern size_t strlen8to16 (const char* utf8Str);\nextern char16_t * strcpy8to16 (char16_t *dest, const char*s, size_t *out_len);\nextern char16_t * strcpylen8to16 (char16_t *dest, const char*s, int length,\n    size_t *out_len);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __CUTILS_STRING16_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/klog.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _CUTILS_KLOG_H_\n#define _CUTILS_KLOG_H_\n\n#include <sys/cdefs.h>\n#include <sys/uio.h>\n#include <stdarg.h>\n\n__BEGIN_DECLS\n\nvoid klog_init(void);\nint  klog_get_level(void);\nvoid klog_set_level(int level);\n/* TODO: void klog_close(void); - and make klog_fd users thread safe. */\n\nvoid klog_write(int level, const char *fmt, ...)\n    __attribute__ ((format(printf, 2, 3)));\nvoid klog_writev(int level, const struct iovec* iov, int iov_count);\n\n__END_DECLS\n\n#define KLOG_ERROR_LEVEL   3\n#define KLOG_WARNING_LEVEL 4\n#define KLOG_NOTICE_LEVEL  5\n#define KLOG_INFO_LEVEL    6\n#define KLOG_DEBUG_LEVEL   7\n\n#define KLOG_ERROR(tag,x...)   klog_write(KLOG_ERROR_LEVEL, \"<3>\" tag \": \" x)\n#define KLOG_WARNING(tag,x...) klog_write(KLOG_WARNING_LEVEL, \"<4>\" tag \": \" x)\n#define KLOG_NOTICE(tag,x...)  klog_write(KLOG_NOTICE_LEVEL, \"<5>\" tag \": \" x)\n#define KLOG_INFO(tag,x...)    klog_write(KLOG_INFO_LEVEL, \"<6>\" tag \": \" x)\n#define KLOG_DEBUG(tag,x...)   klog_write(KLOG_DEBUG_LEVEL, \"<7>\" tag \": \" x)\n\n#define KLOG_DEFAULT_LEVEL  3  /* messages <= this level are logged */\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/list.h",
    "content": "/*\n * Copyright (C) 2008-2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _CUTILS_LIST_H_\n#define _CUTILS_LIST_H_\n\n#include <stddef.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\nstruct listnode\n{\n    struct listnode *next;\n    struct listnode *prev;\n};\n\n#define node_to_item(node, container, member) \\\n    (container *) (((char*) (node)) - offsetof(container, member))\n\n#define list_declare(name) \\\n    struct listnode name = { \\\n        .next = &name, \\\n        .prev = &name, \\\n    }\n\n#define list_for_each(node, list) \\\n    for (node = (list)->next; node != (list); node = node->next)\n\n#define list_for_each_reverse(node, list) \\\n    for (node = (list)->prev; node != (list); node = node->prev)\n\n#define list_for_each_safe(node, n, list) \\\n    for (node = (list)->next, n = node->next; \\\n         node != (list); \\\n         node = n, n = node->next)\n\nstatic inline void list_init(struct listnode *node)\n{\n    node->next = node;\n    node->prev = node;\n}\n\nstatic inline void list_add_tail(struct listnode *head, struct listnode *item)\n{\n    item->next = head;\n    item->prev = head->prev;\n    head->prev->next = item;\n    head->prev = item;\n}\n\nstatic inline void list_add_head(struct listnode *head, struct listnode *item)\n{\n    item->next = head->next;\n    item->prev = head;\n    head->next->prev = item;\n    head->next = item;\n}\n\nstatic inline void list_remove(struct listnode *item)\n{\n    item->next->prev = item->prev;\n    item->prev->next = item->next;\n}\n\n#define list_empty(list) ((list) == (list)->next)\n#define list_head(list) ((list)->next)\n#define list_tail(list) ((list)->prev)\n\n#ifdef __cplusplus\n};\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/log.h",
    "content": "#include <log/log.h>\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/memory.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_CUTILS_MEMORY_H\n#define ANDROID_CUTILS_MEMORY_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* size is given in bytes and must be multiple of 2 */\nvoid android_memset16(uint16_t* dst, uint16_t value, size_t size);\n\n/* size is given in bytes and must be multiple of 4 */\nvoid android_memset32(uint32_t* dst, uint32_t value, size_t size);\n\n#if defined(__GLIBC__) || defined(_WIN32)\n/* Declaration of strlcpy() for platforms that don't already have it. */\nsize_t strlcpy(char *dst, const char *src, size_t size);\n#endif\n\n#ifdef __cplusplus\n} // extern \"C\"\n#endif\n\n#endif // ANDROID_CUTILS_MEMORY_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/misc.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_MISC_H\n#define __CUTILS_MISC_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n        /* Load an entire file into a malloc'd chunk of memory\n         * that is length_of_file + 1 (null terminator).  If\n         * sz is non-zero, return the size of the file via sz.\n         * Returns 0 on failure.\n         */\nextern void *load_file(const char *fn, unsigned *sz);\n\n        /* This is the range of UIDs (and GIDs) that are reserved\n         * for assigning to applications.\n         */\n#define FIRST_APPLICATION_UID 10000\n#define LAST_APPLICATION_UID 99999\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __CUTILS_MISC_H */ \n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/multiuser.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_MULTIUSER_H\n#define __CUTILS_MULTIUSER_H\n\n#include <sys/types.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// NOTE: keep in sync with android.os.UserId\n\n#define MULTIUSER_APP_PER_USER_RANGE 100000\n#define MULTIUSER_FIRST_SHARED_APPLICATION_GID 50000\n#define MULTIUSER_FIRST_APPLICATION_UID 10000\n\ntypedef uid_t userid_t;\ntypedef uid_t appid_t;\n\nextern userid_t multiuser_get_user_id(uid_t uid);\nextern appid_t multiuser_get_app_id(uid_t uid);\nextern uid_t multiuser_get_uid(userid_t userId, appid_t appId);\nextern appid_t multiuser_get_shared_app_gid(uid_t uid);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __CUTILS_MULTIUSER_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/native_handle.h",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef NATIVE_HANDLE_H_\n#define NATIVE_HANDLE_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef struct native_handle\n{\n    int version;        /* sizeof(native_handle_t) */\n    int numFds;         /* number of file-descriptors at &data[0] */\n    int numInts;        /* number of ints at &data[numFds] */\n    int data[0];        /* numFds + numInts ints */\n} native_handle_t;\n\n/*\n * native_handle_close\n * \n * closes the file descriptors contained in this native_handle_t\n * \n * return 0 on success, or a negative error code on failure\n * \n */\nint native_handle_close(const native_handle_t* h);\n\n\n/*\n * native_handle_create\n * \n * creates a native_handle_t and initializes it. must be destroyed with\n * native_handle_delete().\n * \n */\nnative_handle_t* native_handle_create(int numFds, int numInts);\n\n/*\n * native_handle_delete\n * \n * frees a native_handle_t allocated with native_handle_create().\n * This ONLY frees the memory allocated for the native_handle_t, but doesn't\n * close the file descriptors; which can be achieved with native_handle_close().\n * \n * return 0 on success, or a negative error code on failure\n * \n */\nint native_handle_delete(native_handle_t* h);\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* NATIVE_HANDLE_H_ */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/open_memstream.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_OPEN_MEMSTREAM_H__\n#define __CUTILS_OPEN_MEMSTREAM_H__\n\n#include <stdio.h>\n\n#if defined(__APPLE__)\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nFILE* open_memstream(char** bufp, size_t* sizep);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __APPLE__ */\n\n#endif /*__CUTILS_OPEN_MEMSTREAM_H__*/\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/partition_utils.h",
    "content": "/*\n * Copyright 2011, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_PARTITION_WIPED_H__\n#define __CUTILS_PARTITION_WIPED_H__\n\n__BEGIN_DECLS\n\nint partition_wiped(char *source);\n\n__END_DECLS\n\n#endif /* __CUTILS_PARTITION_WIPED_H__ */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/process_name.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Gives the current process a name.\n */\n\n#ifndef __PROCESS_NAME_H\n#define __PROCESS_NAME_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Sets the current process name.\n *\n * Warning: This leaks a string every time you call it. Use judiciously!\n */\nvoid set_process_name(const char* process_name);\n\n/** Gets the current process name. */\nconst char* get_process_name(void);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __PROCESS_NAME_H */ \n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/properties.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_PROPERTIES_H\n#define __CUTILS_PROPERTIES_H\n\n#include <sys/cdefs.h>\n#include <stddef.h>\n#include <sys/system_properties.h>\n#include <stdint.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* System properties are *small* name value pairs managed by the\n** property service.  If your data doesn't fit in the provided\n** space it is not appropriate for a system property.\n**\n** WARNING: system/bionic/include/sys/system_properties.h also defines\n**          these, but with different names.  (TODO: fix that)\n*/\n#define PROPERTY_KEY_MAX   PROP_NAME_MAX\n#define PROPERTY_VALUE_MAX  PROP_VALUE_MAX\n\n/* property_get: returns the length of the value which will never be\n** greater than PROPERTY_VALUE_MAX - 1 and will always be zero terminated.\n** (the length does not include the terminating zero).\n**\n** If the property read fails or returns an empty value, the default\n** value is used (if nonnull).\n*/\nint property_get(const char *key, char *value, const char *default_value);\n\n/* property_get_bool: returns the value of key coerced into a\n** boolean. If the property is not set, then the default value is returned.\n**\n* The following is considered to be true (1):\n**   \"1\", \"true\", \"y\", \"yes\", \"on\"\n**\n** The following is considered to be false (0):\n**   \"0\", \"false\", \"n\", \"no\", \"off\"\n**\n** The conversion is whitespace-sensitive (e.g. \" off\" will not be false).\n**\n** If no property with this key is set (or the key is NULL) or the boolean\n** conversion fails, the default value is returned.\n**/\nint8_t property_get_bool(const char *key, int8_t default_value);\n\n/* property_get_int64: returns the value of key truncated and coerced into a\n** int64_t. If the property is not set, then the default value is used.\n**\n** The numeric conversion is identical to strtoimax with the base inferred:\n** - All digits up to the first non-digit characters are read\n** - The longest consecutive prefix of digits is converted to a long\n**\n** Valid strings of digits are:\n** - An optional sign character + or -\n** - An optional prefix indicating the base (otherwise base 10 is assumed)\n**   -- 0 prefix is octal\n**   -- 0x / 0X prefix is hex\n**\n** Leading/trailing whitespace is ignored. Overflow/underflow will cause\n** numeric conversion to fail.\n**\n** If no property with this key is set (or the key is NULL) or the numeric\n** conversion fails, the default value is returned.\n**/\nint64_t property_get_int64(const char *key, int64_t default_value);\n\n/* property_get_int32: returns the value of key truncated and coerced into an\n** int32_t. If the property is not set, then the default value is used.\n**\n** The numeric conversion is identical to strtoimax with the base inferred:\n** - All digits up to the first non-digit characters are read\n** - The longest consecutive prefix of digits is converted to a long\n**\n** Valid strings of digits are:\n** - An optional sign character + or -\n** - An optional prefix indicating the base (otherwise base 10 is assumed)\n**   -- 0 prefix is octal\n**   -- 0x / 0X prefix is hex\n**\n** Leading/trailing whitespace is ignored. Overflow/underflow will cause\n** numeric conversion to fail.\n**\n** If no property with this key is set (or the key is NULL) or the numeric\n** conversion fails, the default value is returned.\n**/\nint32_t property_get_int32(const char *key, int32_t default_value);\n\n/* property_set: returns 0 on success, < 0 on failure\n*/\nint property_set(const char *key, const char *value);\n    \nint property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie);    \n\n#if defined(__BIONIC_FORTIFY)\n\nextern int __property_get_real(const char *, char *, const char *)\n    __asm__(__USER_LABEL_PREFIX__ \"property_get\");\n__errordecl(__property_get_too_small_error, \"property_get() called with too small of a buffer\");\n\n__BIONIC_FORTIFY_INLINE\nint property_get(const char *key, char *value, const char *default_value) {\n    size_t bos = __bos(value);\n    if (bos < PROPERTY_VALUE_MAX) {\n        __property_get_too_small_error();\n    }\n    return __property_get_real(key, value, default_value);\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/qtaguid.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_QTAGUID_H\n#define __CUTILS_QTAGUID_H\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n * Set tags (and owning UIDs) for network sockets.\n*/\nextern int qtaguid_tagSocket(int sockfd, int tag, uid_t uid);\n\n/*\n * Untag a network socket before closing.\n*/\nextern int qtaguid_untagSocket(int sockfd);\n\n/*\n * For the given uid, switch counter sets.\n * The kernel only keeps a limited number of sets.\n * 2 for now.\n */\nextern int qtaguid_setCounterSet(int counterSetNum, uid_t uid);\n\n/*\n * Delete all tag info that relates to the given tag an uid.\n * If the tag is 0, then ALL info about the uid is freeded.\n * The delete data also affects active tagged socketd, which are\n * then untagged.\n * The calling process can only operate on its own tags.\n * Unless it is part of the happy AID_NET_BW_ACCT group.\n * In which case it can clobber everything.\n */\nextern int qtaguid_deleteTagData(int tag, uid_t uid);\n\n/*\n * Enable/disable qtaguid functionnality at a lower level.\n * When pacified, the kernel will accept commands but do nothing.\n */\nextern int qtaguid_setPacifier(int on);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __CUTILS_QTAG_UID_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/record_stream.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * A simple utility for reading fixed records out of a stream fd\n */\n\n#ifndef _CUTILS_RECORD_STREAM_H\n#define _CUTILS_RECORD_STREAM_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\ntypedef struct RecordStream RecordStream;\n\nextern RecordStream *record_stream_new(int fd, size_t maxRecordLen);\nextern void record_stream_free(RecordStream *p_rs);\n\nextern int record_stream_get_next (RecordStream *p_rs, void ** p_outRecord, \n                                    size_t *p_outRecordLen);\n\n#ifdef __cplusplus\n}\n#endif\n\n\n#endif /*_CUTILS_RECORD_STREAM_H*/\n\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/sched_policy.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_SCHED_POLICY_H\n#define __CUTILS_SCHED_POLICY_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Keep in sync with THREAD_GROUP_* in frameworks/base/core/java/android/os/Process.java */\ntypedef enum {\n    SP_DEFAULT    = -1,\n    SP_BACKGROUND = 0,\n    SP_FOREGROUND = 1,\n    SP_SYSTEM     = 2,  // can't be used with set_sched_policy()\n    SP_AUDIO_APP  = 3,\n    SP_AUDIO_SYS  = 4,\n    SP_TOP_APP    = 5,\n    SP_CNT,\n    SP_MAX        = SP_CNT - 1,\n    SP_SYSTEM_DEFAULT = SP_FOREGROUND,\n} SchedPolicy;\n\nextern int set_cpuset_policy(int tid, SchedPolicy policy);\n\n/* Assign thread tid to the cgroup associated with the specified policy.\n * If the thread is a thread group leader, that is it's gettid() == getpid(),\n * then the other threads in the same thread group are _not_ affected.\n * On platforms which support gettid(), zero tid means current thread.\n * Return value: 0 for success, or -errno for error.\n */\nextern int set_sched_policy(int tid, SchedPolicy policy);\n\n/* Return the policy associated with the cgroup of thread tid via policy pointer.\n * On platforms which support gettid(), zero tid means current thread.\n * Return value: 0 for success, or -1 for error and set errno.\n */\nextern int get_sched_policy(int tid, SchedPolicy *policy);\n\n/* Return a displayable string corresponding to policy.\n * Return value: non-NULL NUL-terminated name of unspecified length;\n * the caller is responsible for displaying the useful part of the string.\n */\nextern const char *get_sched_policy_name(SchedPolicy policy);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __CUTILS_SCHED_POLICY_H */ \n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/sockets.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_SOCKETS_H\n#define __CUTILS_SOCKETS_H\n\n#include <errno.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdbool.h>\n\n#if defined(_WIN32)\n\n#include <winsock2.h>\n#include <ws2tcpip.h>\n\ntypedef int  socklen_t;\ntypedef SOCKET cutils_socket_t;\n\n#else\n\n#include <sys/socket.h>\n\ntypedef int cutils_socket_t;\n#define INVALID_SOCKET (-1)\n\n#endif\n\n#define ANDROID_SOCKET_ENV_PREFIX\t\"ANDROID_SOCKET_\"\n#define ANDROID_SOCKET_DIR\t\t\"/dev/socket\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n * android_get_control_socket - simple helper function to get the file\n * descriptor of our init-managed Unix domain socket. `name' is the name of the\n * socket, as given in init.rc. Returns -1 on error.\n *\n * This is inline and not in libcutils proper because we want to use this in\n * third-party daemons with minimal modification.\n */\nstatic inline int android_get_control_socket(const char* name)\n{\n\tchar key[64];\n\tsnprintf(key, sizeof(key), ANDROID_SOCKET_ENV_PREFIX \"%s\", name);\n\n\tconst char* val = getenv(key);\n\tif (!val) {\n\t\treturn -1;\n\t}\n\n\terrno = 0;\n\tint fd = strtol(val, NULL, 10);\n\tif (errno) {\n\t\treturn -1;\n\t}\n\n\treturn fd;\n}\n\n/*\n * See also android.os.LocalSocketAddress.Namespace\n */\n// Linux \"abstract\" (non-filesystem) namespace\n#define ANDROID_SOCKET_NAMESPACE_ABSTRACT 0\n// Android \"reserved\" (/dev/socket) namespace\n#define ANDROID_SOCKET_NAMESPACE_RESERVED 1\n// Normal filesystem namespace\n#define ANDROID_SOCKET_NAMESPACE_FILESYSTEM 2\n\n/*\n * Functions to create sockets for some common usages.\n *\n * All these functions are implemented for Unix, but only a few are implemented\n * for Windows. Those which are can be identified by the cutils_socket_t\n * return type. The idea is to be able to use this return value with the\n * standard Unix socket functions on any platform.\n *\n * On Unix the returned cutils_socket_t is a standard int file descriptor and\n * can always be used as normal with all file descriptor functions.\n *\n * On Windows utils_socket_t is an unsigned int pointer, and is only valid\n * with functions that specifically take a socket, e.g. send(), sendto(),\n * recv(), and recvfrom(). General file descriptor functions such as read(),\n * write(), and close() will not work with utils_socket_t and will require\n * special handling.\n *\n * These functions return INVALID_SOCKET (-1) on failure for all platforms.\n */\nint socket_loopback_client(int port, int type);\ncutils_socket_t socket_network_client(const char* host, int port, int type);\nint socket_network_client_timeout(const char* host, int port, int type,\n                                  int timeout, int* getaddrinfo_error);\nint socket_loopback_server(int port, int type);\nint socket_local_server(const char* name, int namespaceId, int type);\nint socket_local_server_bind(int s, const char* name, int namespaceId);\nint socket_local_client_connect(int fd, const char *name, int namespaceId,\n                                int type);\nint socket_local_client(const char* name, int namespaceId, int type);\ncutils_socket_t socket_inaddr_any_server(int port, int type);\n\n/*\n * Closes a cutils_socket_t. Windows doesn't allow calling close() on a socket\n * so this is a cross-platform way to close a cutils_socket_t.\n *\n * Returns 0 on success.\n */\nint socket_close(cutils_socket_t sock);\n\n/*\n * Sets socket receive timeout using SO_RCVTIMEO. Setting |timeout_ms| to 0\n * disables receive timeouts.\n *\n * Return 0 on success.\n */\nint socket_set_receive_timeout(cutils_socket_t sock, int timeout_ms);\n\n/*\n * Returns the local port the socket is bound to or -1 on error.\n */\nint socket_get_local_port(cutils_socket_t sock);\n\n/*\n * Sends to a socket from multiple buffers; wraps writev() on Unix or WSASend()\n * on Windows. This can give significant speedup compared to calling send()\n * multiple times.\n *\n * Example usage:\n *   cutils_socket_buffer_t buffers[2] = { {data0, len0}, {data1, len1} };\n *   socket_send_buffers(sock, buffers, 2);\n *\n * If you try to pass more than SOCKET_SEND_BUFFERS_MAX_BUFFERS buffers into\n * this function it will return -1 without sending anything.\n *\n * Returns the number of bytes written or -1 on error.\n */\ntypedef struct {\n  const void* data;\n  size_t length;\n} cutils_socket_buffer_t;\n\n#define SOCKET_SEND_BUFFERS_MAX_BUFFERS 16\n\nssize_t socket_send_buffers(cutils_socket_t sock,\n                            const cutils_socket_buffer_t* buffers,\n                            size_t num_buffers);\n\n/*\n * socket_peer_is_trusted - Takes a socket which is presumed to be a\n * connected local socket (e.g. AF_LOCAL) and returns whether the peer\n * (the userid that owns the process on the other end of that socket)\n * is one of the two trusted userids, root or shell.\n *\n * Note: This only works as advertised on the Android OS and always\n * just returns true when called on other operating systems.\n */\nextern bool socket_peer_is_trusted(int fd);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __CUTILS_SOCKETS_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/str_parms.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_STR_PARMS_H\n#define __CUTILS_STR_PARMS_H\n\n#include <stdint.h>\n#include <sys/cdefs.h>\n\n__BEGIN_DECLS\n\nstruct str_parms;\n\nstruct str_parms *str_parms_create(void);\nstruct str_parms *str_parms_create_str(const char *_string);\nvoid str_parms_destroy(struct str_parms *str_parms);\n\nvoid str_parms_del(struct str_parms *str_parms, const char *key);\n\nint str_parms_add_str(struct str_parms *str_parms, const char *key,\n                      const char *value);\nint str_parms_add_int(struct str_parms *str_parms, const char *key, int value);\n\nint str_parms_add_float(struct str_parms *str_parms, const char *key,\n                        float value);\n\n// Returns non-zero if the str_parms contains the specified key.\nint str_parms_has_key(struct str_parms *str_parms, const char *key);\n\n// Gets value associated with the specified key (if present), placing it in the buffer\n// pointed to by the out_val parameter.  Returns the length of the returned string value.\n// If 'key' isn't in the parms, then return -ENOENT (-2) and leave 'out_val' untouched.\nint str_parms_get_str(struct str_parms *str_parms, const char *key,\n                      char *out_val, int len);\nint str_parms_get_int(struct str_parms *str_parms, const char *key,\n                      int *out_val);\nint str_parms_get_float(struct str_parms *str_parms, const char *key,\n                        float *out_val);\n\nchar *str_parms_to_str(struct str_parms *str_parms);\n\n/* debug */\nvoid str_parms_dump(struct str_parms *str_parms);\n\n__END_DECLS\n\n#endif /* __CUTILS_STR_PARMS_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/threads.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBS_CUTILS_THREADS_H\n#define _LIBS_CUTILS_THREADS_H\n\n#include  <sys/types.h>\n\n#if !defined(_WIN32)\n#include <pthread.h>\n#else\n#include <windows.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/***********************************************************************/\n/***********************************************************************/\n/*****                                                             *****/\n/*****         local thread storage                                *****/\n/*****                                                             *****/\n/***********************************************************************/\n/***********************************************************************/\n\nextern pid_t gettid();\n\n#if !defined(_WIN32)\n\ntypedef struct {\n    pthread_mutex_t   lock;\n    int               has_tls;\n    pthread_key_t     tls;\n} thread_store_t;\n\n#define  THREAD_STORE_INITIALIZER  { PTHREAD_MUTEX_INITIALIZER, 0, 0 }\n\n#else // !defined(_WIN32)\n\ntypedef struct {\n    int               lock_init;\n    int               has_tls;\n    DWORD             tls;\n    CRITICAL_SECTION  lock;\n} thread_store_t;\n\n#define  THREAD_STORE_INITIALIZER  { 0, 0, 0, {0, 0, 0, 0, 0, 0} }\n\n#endif // !defined(_WIN32)\n\ntypedef void  (*thread_store_destruct_t)(void*  value);\n\nextern void*  thread_store_get(thread_store_t*  store);\n\nextern void   thread_store_set(thread_store_t*          store,\n                               void*                    value,\n                               thread_store_destruct_t  destroy);\n\n/***********************************************************************/\n/***********************************************************************/\n/*****                                                             *****/\n/*****         mutexes                                             *****/\n/*****                                                             *****/\n/***********************************************************************/\n/***********************************************************************/\n\n#if !defined(_WIN32)\n\ntypedef pthread_mutex_t   mutex_t;\n\n#define  MUTEX_INITIALIZER  PTHREAD_MUTEX_INITIALIZER\n\nstatic __inline__ void  mutex_lock(mutex_t*  lock)\n{\n    pthread_mutex_lock(lock);\n}\nstatic __inline__ void  mutex_unlock(mutex_t*  lock)\n{\n    pthread_mutex_unlock(lock);\n}\nstatic __inline__ int  mutex_init(mutex_t*  lock)\n{\n    return pthread_mutex_init(lock, NULL);\n}\nstatic __inline__ void mutex_destroy(mutex_t*  lock)\n{\n    pthread_mutex_destroy(lock);\n}\n\n#else // !defined(_WIN32)\n\ntypedef struct {\n    int                init;\n    CRITICAL_SECTION   lock[1];\n} mutex_t;\n\n#define  MUTEX_INITIALIZER  { 0, {{ NULL, 0, 0, NULL, NULL, 0 }} }\n\nstatic __inline__ void  mutex_lock(mutex_t*  lock)\n{\n    if (!lock->init) {\n        lock->init = 1;\n        InitializeCriticalSection( lock->lock );\n        lock->init = 2;\n    } else while (lock->init != 2)\n        Sleep(10);\n\n    EnterCriticalSection(lock->lock);\n}\n\nstatic __inline__ void  mutex_unlock(mutex_t*  lock)\n{\n    LeaveCriticalSection(lock->lock);\n}\nstatic __inline__ int  mutex_init(mutex_t*  lock)\n{\n    InitializeCriticalSection(lock->lock);\n    lock->init = 2;\n    return 0;\n}\nstatic __inline__ void  mutex_destroy(mutex_t*  lock)\n{\n    if (lock->init) {\n        lock->init = 0;\n        DeleteCriticalSection(lock->lock);\n    }\n}\n#endif // !defined(_WIN32)\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _LIBS_CUTILS_THREADS_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/trace.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBS_CUTILS_TRACE_H\n#define _LIBS_CUTILS_TRACE_H\n\n#include <inttypes.h>\n#include <stdatomic.h>\n#include <stdbool.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#include <cutils/compiler.h>\n\n__BEGIN_DECLS\n\n/**\n * The ATRACE_TAG macro can be defined before including this header to trace\n * using one of the tags defined below.  It must be defined to one of the\n * following ATRACE_TAG_* macros.  The trace tag is used to filter tracing in\n * userland to avoid some of the runtime cost of tracing when it is not desired.\n *\n * Defining ATRACE_TAG to be ATRACE_TAG_ALWAYS will result in the tracing always\n * being enabled - this should ONLY be done for debug code, as userland tracing\n * has a performance cost even when the trace is not being recorded.  Defining\n * ATRACE_TAG to be ATRACE_TAG_NEVER or leaving ATRACE_TAG undefined will result\n * in the tracing always being disabled.\n *\n * ATRACE_TAG_HAL should be bitwise ORed with the relevant tags for tracing\n * within a hardware module.  For example a camera hardware module would set:\n * #define ATRACE_TAG  (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)\n *\n * Keep these in sync with frameworks/base/core/java/android/os/Trace.java.\n */\n#define ATRACE_TAG_NEVER            0       // This tag is never enabled.\n#define ATRACE_TAG_ALWAYS           (1<<0)  // This tag is always enabled.\n#define ATRACE_TAG_GRAPHICS         (1<<1)\n#define ATRACE_TAG_INPUT            (1<<2)\n#define ATRACE_TAG_VIEW             (1<<3)\n#define ATRACE_TAG_WEBVIEW          (1<<4)\n#define ATRACE_TAG_WINDOW_MANAGER   (1<<5)\n#define ATRACE_TAG_ACTIVITY_MANAGER (1<<6)\n#define ATRACE_TAG_SYNC_MANAGER     (1<<7)\n#define ATRACE_TAG_AUDIO            (1<<8)\n#define ATRACE_TAG_VIDEO            (1<<9)\n#define ATRACE_TAG_CAMERA           (1<<10)\n#define ATRACE_TAG_HAL              (1<<11)\n#define ATRACE_TAG_APP              (1<<12)\n#define ATRACE_TAG_RESOURCES        (1<<13)\n#define ATRACE_TAG_DALVIK           (1<<14)\n#define ATRACE_TAG_RS               (1<<15)\n#define ATRACE_TAG_BIONIC           (1<<16)\n#define ATRACE_TAG_POWER            (1<<17)\n#define ATRACE_TAG_PACKAGE_MANAGER  (1<<18)\n#define ATRACE_TAG_SYSTEM_SERVER    (1<<19)\n#define ATRACE_TAG_DATABASE         (1<<20)\n#define ATRACE_TAG_LAST             ATRACE_TAG_DATABASE\n\n// Reserved for initialization.\n#define ATRACE_TAG_NOT_READY        (1ULL<<63)\n\n#define ATRACE_TAG_VALID_MASK ((ATRACE_TAG_LAST - 1) | ATRACE_TAG_LAST)\n\n#ifndef ATRACE_TAG\n#define ATRACE_TAG ATRACE_TAG_NEVER\n#elif ATRACE_TAG > ATRACE_TAG_VALID_MASK\n#error ATRACE_TAG must be defined to be one of the tags defined in cutils/trace.h\n#endif\n\n/**\n * Opens the trace file for writing and reads the property for initial tags.\n * The atrace.tags.enableflags property sets the tags to trace.\n * This function should not be explicitly called, the first call to any normal\n * trace function will cause it to be run safely.\n */\nvoid atrace_setup();\n\n/**\n * If tracing is ready, set atrace_enabled_tags to the system property\n * debug.atrace.tags.enableflags. Can be used as a sysprop change callback.\n */\nvoid atrace_update_tags();\n\n/**\n * Set whether the process is debuggable.  By default the process is not\n * considered debuggable.  If the process is not debuggable then application-\n * level tracing is not allowed unless the ro.debuggable system property is\n * set to '1'.\n */\nvoid atrace_set_debuggable(bool debuggable);\n\n/**\n * Set whether tracing is enabled for the current process.  This is used to\n * prevent tracing within the Zygote process.\n */\nvoid atrace_set_tracing_enabled(bool enabled);\n\n/**\n * Flag indicating whether setup has been completed, initialized to 0.\n * Nonzero indicates setup has completed.\n * Note: This does NOT indicate whether or not setup was successful.\n */\nextern atomic_bool atrace_is_ready;\n\n/**\n * Set of ATRACE_TAG flags to trace for, initialized to ATRACE_TAG_NOT_READY.\n * A value of zero indicates setup has failed.\n * Any other nonzero value indicates setup has succeeded, and tracing is on.\n */\nextern uint64_t atrace_enabled_tags;\n\n/**\n * Handle to the kernel's trace buffer, initialized to -1.\n * Any other value indicates setup has succeeded, and is a valid fd for tracing.\n */\nextern int atrace_marker_fd;\n\n/**\n * atrace_init readies the process for tracing by opening the trace_marker file.\n * Calling any trace function causes this to be run, so calling it is optional.\n * This can be explicitly run to avoid setup delay on first trace function.\n */\n#define ATRACE_INIT() atrace_init()\nstatic inline void atrace_init()\n{\n    if (CC_UNLIKELY(!atomic_load_explicit(&atrace_is_ready, memory_order_acquire))) {\n        atrace_setup();\n    }\n}\n\n/**\n * Get the mask of all tags currently enabled.\n * It can be used as a guard condition around more expensive trace calculations.\n * Every trace function calls this, which ensures atrace_init is run.\n */\n#define ATRACE_GET_ENABLED_TAGS() atrace_get_enabled_tags()\nstatic inline uint64_t atrace_get_enabled_tags()\n{\n    atrace_init();\n    return atrace_enabled_tags;\n}\n\n/**\n * Test if a given tag is currently enabled.\n * Returns nonzero if the tag is enabled, otherwise zero.\n * It can be used as a guard condition around more expensive trace calculations.\n */\n#define ATRACE_ENABLED() atrace_is_tag_enabled(ATRACE_TAG)\nstatic inline uint64_t atrace_is_tag_enabled(uint64_t tag)\n{\n    return atrace_get_enabled_tags() & tag;\n}\n\n/**\n * Trace the beginning of a context.  name is used to identify the context.\n * This is often used to time function execution.\n */\n#define ATRACE_BEGIN(name) atrace_begin(ATRACE_TAG, name)\nstatic inline void atrace_begin(uint64_t tag, const char* name)\n{\n    if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {\n        void atrace_begin_body(const char*);\n        atrace_begin_body(name);\n    }\n}\n\n/**\n * Trace the end of a context.\n * This should match up (and occur after) a corresponding ATRACE_BEGIN.\n */\n#define ATRACE_END() atrace_end(ATRACE_TAG)\nstatic inline void atrace_end(uint64_t tag)\n{\n    if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {\n        char c = 'E';\n        write(atrace_marker_fd, &c, 1);\n    }\n}\n\n/**\n * Trace the beginning of an asynchronous event. Unlike ATRACE_BEGIN/ATRACE_END\n * contexts, asynchronous events do not need to be nested. The name describes\n * the event, and the cookie provides a unique identifier for distinguishing\n * simultaneous events. The name and cookie used to begin an event must be\n * used to end it.\n */\n#define ATRACE_ASYNC_BEGIN(name, cookie) \\\n    atrace_async_begin(ATRACE_TAG, name, cookie)\nstatic inline void atrace_async_begin(uint64_t tag, const char* name,\n        int32_t cookie)\n{\n    if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {\n        void atrace_async_begin_body(const char*, int32_t);\n        atrace_async_begin_body(name, cookie);\n    }\n}\n\n/**\n * Trace the end of an asynchronous event.\n * This should have a corresponding ATRACE_ASYNC_BEGIN.\n */\n#define ATRACE_ASYNC_END(name, cookie) atrace_async_end(ATRACE_TAG, name, cookie)\nstatic inline void atrace_async_end(uint64_t tag, const char* name, int32_t cookie)\n{\n    if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {\n        void atrace_async_end_body(const char*, int32_t);\n        atrace_async_end_body(name, cookie);\n    }\n}\n\n/**\n * Traces an integer counter value.  name is used to identify the counter.\n * This can be used to track how a value changes over time.\n */\n#define ATRACE_INT(name, value) atrace_int(ATRACE_TAG, name, value)\nstatic inline void atrace_int(uint64_t tag, const char* name, int32_t value)\n{\n    if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {\n        void atrace_int_body(const char*, int32_t);\n        atrace_int_body(name, value);\n    }\n}\n\n/**\n * Traces a 64-bit integer counter value.  name is used to identify the\n * counter. This can be used to track how a value changes over time.\n */\n#define ATRACE_INT64(name, value) atrace_int64(ATRACE_TAG, name, value)\nstatic inline void atrace_int64(uint64_t tag, const char* name, int64_t value)\n{\n    if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {\n        void atrace_int64_body(const char*, int64_t);\n        atrace_int64_body(name, value);\n    }\n}\n\n__END_DECLS\n\n#endif // _LIBS_CUTILS_TRACE_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/cutils/uevent.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CUTILS_UEVENT_H\n#define __CUTILS_UEVENT_H\n\n#include <stdbool.h>\n#include <sys/socket.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nint uevent_open_socket(int buf_sz, bool passcred);\nssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length);\nssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *uid);\nssize_t uevent_kernel_recv(int socket, void *buffer, size_t length, bool require_group, uid_t *uid);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __CUTILS_UEVENT_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/diskconfig/diskconfig.h",
    "content": "/* system/core/include/diskconfig/diskconfig.h\n *\n * Copyright 2008, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __LIBS_DISKCONFIG_H\n#define __LIBS_DISKCONFIG_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define MAX_NAME_LEN                 512\n#define MAX_NUM_PARTS                16\n\n/* known partition schemes */\n#define PART_SCHEME_MBR              0x1\n#define PART_SCHEME_GPT              0x2\n\n/* PC Bios partition status */\n#define PC_PART_ACTIVE               0x80\n#define PC_PART_NORMAL               0x0\n\n/* Known (rather, used by us) partition types */\n#define PC_PART_TYPE_LINUX           0x83\n#define PC_PART_TYPE_EXTENDED        0x05\n#define PC_PART_TYPE_FAT32           0x0c\n\n#define PC_NUM_BOOT_RECORD_PARTS     4\n\n#define PC_EBR_LOGICAL_PART          0\n#define PC_EBR_NEXT_PTR_PART         1\n\n#define PC_BIOS_BOOT_SIG             0xAA55\n\n#define PC_MBR_DISK_OFFSET           0\n#define PC_MBR_SIZE                  512\n\n#define PART_ACTIVE_FLAG             0x1\n\nstruct chs {\n    uint8_t head;\n    uint8_t sector;\n    uint8_t cylinder;\n} __attribute__((__packed__));\n\n/* 16 byte pc partition descriptor that sits in MBR and EPBR.\n * Note: multi-byte entities have little-endian layout on disk */\nstruct pc_partition {\n    uint8_t status;     /* byte  0     */\n    struct chs start;   /* bytes 1-3   */\n    uint8_t type;       /* byte  4     */\n    struct chs end;     /* bytes 5-7   */\n    uint32_t start_lba; /* bytes 8-11  */\n    uint32_t len_lba;   /* bytes 12-15 */\n} __attribute__((__packed__));\n\nstruct pc_boot_record {\n    uint8_t code[440];                                      /* bytes 0-439   */\n    uint32_t disk_sig;                                      /* bytes 440-443 */\n    uint16_t pad;                                           /* bytes 444-445 */\n    struct pc_partition ptable[PC_NUM_BOOT_RECORD_PARTS];   /* bytes 446-509 */\n    uint16_t mbr_sig;                                       /* bytes 510-511 */\n} __attribute__((__packed__));\n\nstruct part_info {\n    char *name;\n    uint8_t flags;\n    uint8_t type;\n    uint32_t len_kb;       /* in 1K-bytes */\n    uint32_t start_lba;    /* the LBA where this partition begins */\n};\n\nstruct disk_info {\n    char *device;\n    uint8_t scheme;\n    int sect_size;       /* expected sector size in bytes. MUST BE POWER OF 2 */\n    uint32_t skip_lba;   /* in sectors (1 unit of LBA) */\n    uint32_t num_lba;    /* the size of the disk in LBA units */\n    struct part_info *part_lst;\n    int num_parts;\n};\n\nstruct write_list {\n    struct write_list *next;\n    loff_t offset;\n    uint32_t len;\n    uint8_t data[0];\n};\n\n\nstruct write_list *alloc_wl(uint32_t data_len);\nvoid free_wl(struct write_list *item);\nstruct write_list *wlist_add(struct write_list **lst, struct write_list *item);\nvoid wlist_free(struct write_list *lst);\nint wlist_commit(int fd, struct write_list *lst, int test);\n\nstruct disk_info *load_diskconfig(const char *fn, char *path_override);\nint dump_disk_config(struct disk_info *dinfo);\nint apply_disk_config(struct disk_info *dinfo, int test);\nchar *find_part_device(struct disk_info *dinfo, const char *name);\nint process_disk_config(struct disk_info *dinfo);\nstruct part_info *find_part(struct disk_info *dinfo, const char *name);\n\nint write_raw_image(const char *dst, const char *src, loff_t offset, int test);\n\n/* For MBR partition schemes */\nstruct write_list *config_mbr(struct disk_info *dinfo);\nchar *find_mbr_part(struct disk_info *dinfo, const char *name);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __LIBS_DISKCONFIG_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/log/event_tag_map.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBS_CUTILS_EVENTTAGMAP_H\n#define _LIBS_CUTILS_EVENTTAGMAP_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define EVENT_TAG_MAP_FILE  \"/system/etc/event-log-tags\"\n\nstruct EventTagMap;\ntypedef struct EventTagMap EventTagMap;\n\n/*\n * Open the specified file as an event log tag map.\n *\n * Returns NULL on failure.\n */\nEventTagMap* android_openEventTagMap(const char* fileName);\n\n/*\n * Close the map.\n */\nvoid android_closeEventTagMap(EventTagMap* map);\n\n/*\n * Look up a tag by index.  Returns the tag string, or NULL if not found.\n */\nconst char* android_lookupEventTag(const EventTagMap* map, int tag);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /*_LIBS_CUTILS_EVENTTAGMAP_H*/\n"
  },
  {
    "path": "atlas-aapt/system/core/include/log/log.h",
    "content": "/*\n * Copyright (C) 2005-2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// C/C++ logging functions.  See the logging documentation for API details.\n//\n// We'd like these to be available from C code (in case we import some from\n// somewhere), so this has a C interface.\n//\n// The output will be correct when the log file is shared between multiple\n// threads and/or multiple processes so long as the operating system\n// supports O_APPEND.  These calls have mutex-protected data structures\n// and so are NOT reentrant.  Do not use LOG in a signal handler.\n//\n#ifndef _LIBS_LOG_LOG_H\n#define _LIBS_LOG_LOG_H\n\n#include <stdarg.h>\n#include <stdio.h>\n#include <sys/types.h>\n#include <time.h>\n#include <unistd.h>\n\n#include <log/logd.h>\n#include <log/uio.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// ---------------------------------------------------------------------\n\n/*\n * Normally we strip ALOGV (VERBOSE messages) from release builds.\n * You can modify this (for example with \"#define LOG_NDEBUG 0\"\n * at the top of your source file) to change that behavior.\n */\n#ifndef LOG_NDEBUG\n#ifdef NDEBUG\n#define LOG_NDEBUG 1\n#else\n#define LOG_NDEBUG 0\n#endif\n#endif\n\n/*\n * This is the local tag used for the following simplified\n * logging macros.  You can change this preprocessor definition\n * before using the other macros to change the tag.\n */\n#ifndef LOG_TAG\n#define LOG_TAG NULL\n#endif\n\n// ---------------------------------------------------------------------\n\n#ifndef __predict_false\n#define __predict_false(exp) __builtin_expect((exp) != 0, 0)\n#endif\n\n/*\n *      -DLINT_RLOG in sources that you want to enforce that all logging\n * goes to the radio log buffer. If any logging goes to any of the other\n * log buffers, there will be a compile or link error to highlight the\n * problem. This is not a replacement for a full audit of the code since\n * this only catches compiled code, not ifdef'd debug code. Options to\n * defining this, either temporarily to do a spot check, or permanently\n * to enforce, in all the communications trees; We have hopes to ensure\n * that by supplying just the radio log buffer that the communications\n * teams will have their one-stop shop for triaging issues.\n */\n#ifndef LINT_RLOG\n\n/*\n * Simplified macro to send a verbose log message using the current LOG_TAG.\n */\n#ifndef ALOGV\n#define __ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))\n#if LOG_NDEBUG\n#define ALOGV(...) do { if (0) { __ALOGV(__VA_ARGS__); } } while (0)\n#else\n#define ALOGV(...) __ALOGV(__VA_ARGS__)\n#endif\n#endif\n\n#ifndef ALOGV_IF\n#if LOG_NDEBUG\n#define ALOGV_IF(cond, ...)   ((void)0)\n#else\n#define ALOGV_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n#endif\n\n/*\n * Simplified macro to send a debug log message using the current LOG_TAG.\n */\n#ifndef ALOGD\n#define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef ALOGD_IF\n#define ALOGD_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n\n/*\n * Simplified macro to send an info log message using the current LOG_TAG.\n */\n#ifndef ALOGI\n#define ALOGI(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef ALOGI_IF\n#define ALOGI_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n\n/*\n * Simplified macro to send a warning log message using the current LOG_TAG.\n */\n#ifndef ALOGW\n#define ALOGW(...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef ALOGW_IF\n#define ALOGW_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n\n/*\n * Simplified macro to send an error log message using the current LOG_TAG.\n */\n#ifndef ALOGE\n#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef ALOGE_IF\n#define ALOGE_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n\n// ---------------------------------------------------------------------\n\n/*\n * Conditional based on whether the current LOG_TAG is enabled at\n * verbose priority.\n */\n#ifndef IF_ALOGV\n#if LOG_NDEBUG\n#define IF_ALOGV() if (false)\n#else\n#define IF_ALOGV() IF_ALOG(LOG_VERBOSE, LOG_TAG)\n#endif\n#endif\n\n/*\n * Conditional based on whether the current LOG_TAG is enabled at\n * debug priority.\n */\n#ifndef IF_ALOGD\n#define IF_ALOGD() IF_ALOG(LOG_DEBUG, LOG_TAG)\n#endif\n\n/*\n * Conditional based on whether the current LOG_TAG is enabled at\n * info priority.\n */\n#ifndef IF_ALOGI\n#define IF_ALOGI() IF_ALOG(LOG_INFO, LOG_TAG)\n#endif\n\n/*\n * Conditional based on whether the current LOG_TAG is enabled at\n * warn priority.\n */\n#ifndef IF_ALOGW\n#define IF_ALOGW() IF_ALOG(LOG_WARN, LOG_TAG)\n#endif\n\n/*\n * Conditional based on whether the current LOG_TAG is enabled at\n * error priority.\n */\n#ifndef IF_ALOGE\n#define IF_ALOGE() IF_ALOG(LOG_ERROR, LOG_TAG)\n#endif\n\n\n// ---------------------------------------------------------------------\n\n/*\n * Simplified macro to send a verbose system log message using the current LOG_TAG.\n */\n#ifndef SLOGV\n#define __SLOGV(...) \\\n    ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))\n#if LOG_NDEBUG\n#define SLOGV(...) do { if (0) { __SLOGV(__VA_ARGS__); } } while (0)\n#else\n#define SLOGV(...) __SLOGV(__VA_ARGS__)\n#endif\n#endif\n\n#ifndef SLOGV_IF\n#if LOG_NDEBUG\n#define SLOGV_IF(cond, ...)   ((void)0)\n#else\n#define SLOGV_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n#endif\n\n/*\n * Simplified macro to send a debug system log message using the current LOG_TAG.\n */\n#ifndef SLOGD\n#define SLOGD(...) \\\n    ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef SLOGD_IF\n#define SLOGD_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n\n/*\n * Simplified macro to send an info system log message using the current LOG_TAG.\n */\n#ifndef SLOGI\n#define SLOGI(...) \\\n    ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef SLOGI_IF\n#define SLOGI_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n\n/*\n * Simplified macro to send a warning system log message using the current LOG_TAG.\n */\n#ifndef SLOGW\n#define SLOGW(...) \\\n    ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef SLOGW_IF\n#define SLOGW_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n\n/*\n * Simplified macro to send an error system log message using the current LOG_TAG.\n */\n#ifndef SLOGE\n#define SLOGE(...) \\\n    ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef SLOGE_IF\n#define SLOGE_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n\n#endif /* !LINT_RLOG */\n\n// ---------------------------------------------------------------------\n\n/*\n * Simplified macro to send a verbose radio log message using the current LOG_TAG.\n */\n#ifndef RLOGV\n#define __RLOGV(...) \\\n    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))\n#if LOG_NDEBUG\n#define RLOGV(...) do { if (0) { __RLOGV(__VA_ARGS__); } } while (0)\n#else\n#define RLOGV(...) __RLOGV(__VA_ARGS__)\n#endif\n#endif\n\n#ifndef RLOGV_IF\n#if LOG_NDEBUG\n#define RLOGV_IF(cond, ...)   ((void)0)\n#else\n#define RLOGV_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n#endif\n\n/*\n * Simplified macro to send a debug radio log message using the current LOG_TAG.\n */\n#ifndef RLOGD\n#define RLOGD(...) \\\n    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef RLOGD_IF\n#define RLOGD_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n\n/*\n * Simplified macro to send an info radio log message using the current LOG_TAG.\n */\n#ifndef RLOGI\n#define RLOGI(...) \\\n    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef RLOGI_IF\n#define RLOGI_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n\n/*\n * Simplified macro to send a warning radio log message using the current LOG_TAG.\n */\n#ifndef RLOGW\n#define RLOGW(...) \\\n    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef RLOGW_IF\n#define RLOGW_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n\n/*\n * Simplified macro to send an error radio log message using the current LOG_TAG.\n */\n#ifndef RLOGE\n#define RLOGE(...) \\\n    ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))\n#endif\n\n#ifndef RLOGE_IF\n#define RLOGE_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n\n\n// ---------------------------------------------------------------------\n\n/*\n * Log a fatal error.  If the given condition fails, this stops program\n * execution like a normal assertion, but also generating the given message.\n * It is NOT stripped from release builds.  Note that the condition test\n * is -inverted- from the normal assert() semantics.\n */\n#ifndef LOG_ALWAYS_FATAL_IF\n#define LOG_ALWAYS_FATAL_IF(cond, ...) \\\n    ( (__predict_false(cond)) \\\n    ? ((void)android_printAssert(#cond, LOG_TAG, ## __VA_ARGS__)) \\\n    : (void)0 )\n#endif\n\n#ifndef LOG_ALWAYS_FATAL\n#define LOG_ALWAYS_FATAL(...) \\\n    ( ((void)android_printAssert(NULL, LOG_TAG, ## __VA_ARGS__)) )\n#endif\n\n/*\n * Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that\n * are stripped out of release builds.\n */\n#if LOG_NDEBUG\n\n#ifndef LOG_FATAL_IF\n#define LOG_FATAL_IF(cond, ...) ((void)0)\n#endif\n#ifndef LOG_FATAL\n#define LOG_FATAL(...) ((void)0)\n#endif\n\n#else\n\n#ifndef LOG_FATAL_IF\n#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ## __VA_ARGS__)\n#endif\n#ifndef LOG_FATAL\n#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)\n#endif\n\n#endif\n\n/*\n * Assertion that generates a log message when the assertion fails.\n * Stripped out of release builds.  Uses the current LOG_TAG.\n */\n#ifndef ALOG_ASSERT\n#define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ## __VA_ARGS__)\n//#define ALOG_ASSERT(cond) LOG_FATAL_IF(!(cond), \"Assertion failed: \" #cond)\n#endif\n\n// ---------------------------------------------------------------------\n\n/*\n * Basic log message macro.\n *\n * Example:\n *  ALOG(LOG_WARN, NULL, \"Failed with error %d\", errno);\n *\n * The second argument may be NULL or \"\" to indicate the \"global\" tag.\n */\n#ifndef ALOG\n#define ALOG(priority, tag, ...) \\\n    LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)\n#endif\n\n/*\n * Log macro that allows you to specify a number for the priority.\n */\n#ifndef LOG_PRI\n#define LOG_PRI(priority, tag, ...) \\\n    android_printLog(priority, tag, __VA_ARGS__)\n#endif\n\n/*\n * Log macro that allows you to pass in a varargs (\"args\" is a va_list).\n */\n#ifndef LOG_PRI_VA\n#define LOG_PRI_VA(priority, tag, fmt, args) \\\n    android_vprintLog(priority, NULL, tag, fmt, args)\n#endif\n\n/*\n * Conditional given a desired logging priority and tag.\n */\n#ifndef IF_ALOG\n#define IF_ALOG(priority, tag) \\\n    if (android_testLog(ANDROID_##priority, tag))\n#endif\n\n// ---------------------------------------------------------------------\n\n/*\n * Event logging.\n */\n\n/*\n * Event log entry types.\n */\ntypedef enum {\n    /* Special markers for android_log_list_element type */\n    EVENT_TYPE_LIST_STOP = '\\n', /* declare end of list  */\n    EVENT_TYPE_UNKNOWN   = '?',  /* protocol error       */\n\n    /* must match with declaration in java/android/android/util/EventLog.java */\n    EVENT_TYPE_INT       = 0,    /* uint32_t */\n    EVENT_TYPE_LONG      = 1,    /* uint64_t */\n    EVENT_TYPE_STRING    = 2,\n    EVENT_TYPE_LIST      = 3,\n    EVENT_TYPE_FLOAT     = 4,\n} AndroidEventLogType;\n#define sizeof_AndroidEventLogType sizeof(typeof_AndroidEventLogType)\n#define typeof_AndroidEventLogType unsigned char\n\n#ifndef LOG_EVENT_INT\n#define LOG_EVENT_INT(_tag, _value) {                                       \\\n        int intBuf = _value;                                                \\\n        (void) android_btWriteLog(_tag, EVENT_TYPE_INT, &intBuf,            \\\n            sizeof(intBuf));                                                \\\n    }\n#endif\n#ifndef LOG_EVENT_LONG\n#define LOG_EVENT_LONG(_tag, _value) {                                      \\\n        long long longBuf = _value;                                         \\\n        (void) android_btWriteLog(_tag, EVENT_TYPE_LONG, &longBuf,          \\\n            sizeof(longBuf));                                               \\\n    }\n#endif\n#ifndef LOG_EVENT_FLOAT\n#define LOG_EVENT_FLOAT(_tag, _value) {                                     \\\n        float floatBuf = _value;                                            \\\n        (void) android_btWriteLog(_tag, EVENT_TYPE_FLOAT, &floatBuf,        \\\n            sizeof(floatBuf));                                              \\\n    }\n#endif\n#ifndef LOG_EVENT_STRING\n#define LOG_EVENT_STRING(_tag, _value)                                      \\\n        (void) __android_log_bswrite(_tag, _value);\n#endif\n\ntypedef enum log_id {\n    LOG_ID_MIN = 0,\n\n#ifndef LINT_RLOG\n    LOG_ID_MAIN = 0,\n#endif\n    LOG_ID_RADIO = 1,\n#ifndef LINT_RLOG\n    LOG_ID_EVENTS = 2,\n    LOG_ID_SYSTEM = 3,\n    LOG_ID_CRASH = 4,\n    LOG_ID_SECURITY = 5,\n    LOG_ID_KERNEL = 6, /* place last, third-parties can not use it */\n#endif\n\n    LOG_ID_MAX\n} log_id_t;\n#define sizeof_log_id_t sizeof(typeof_log_id_t)\n#define typeof_log_id_t unsigned char\n\n/* For manipulating lists of events. */\n\n#define ANDROID_MAX_LIST_NEST_DEPTH 8\n\n/*\n * The opaque context used to manipulate lists of events.\n */\ntypedef struct android_log_context_internal *android_log_context;\n\n/*\n * Elements returned when reading a list of events.\n */\ntypedef struct {\n    AndroidEventLogType type;\n    uint16_t complete;\n    uint16_t len;\n    union {\n        int32_t int32;\n        int64_t int64;\n        char *string;\n        float float32;\n    } data;\n} android_log_list_element;\n\n/*\n * Creates a context associated with an event tag to write elements to\n * the list of events.\n */\nandroid_log_context create_android_logger(uint32_t tag);\n\n/* All lists must be braced by a begin and end call */\n/*\n * NB: If the first level braces are missing when specifying multiple\n *     elements, we will manufacturer a list to embrace it for your API\n *     convenience. For a single element, it will remain solitary.\n */\nint android_log_write_list_begin(android_log_context ctx);\nint android_log_write_list_end(android_log_context ctx);\n\nint android_log_write_int32(android_log_context ctx, int32_t value);\nint android_log_write_int64(android_log_context ctx, int64_t value);\nint android_log_write_string8(android_log_context ctx, const char *value);\nint android_log_write_string8_len(android_log_context ctx,\n                                  const char *value, size_t maxlen);\nint android_log_write_float32(android_log_context ctx, float value);\n\n/* Submit the composed list context to the specified logger id */\n/* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */\nint android_log_write_list(android_log_context ctx, log_id_t id);\n\n/*\n * Creates a context from a raw buffer representing a list of events to be read.\n */\nandroid_log_context create_android_log_parser(const char *msg, size_t len);\n\nandroid_log_list_element android_log_read_next(android_log_context ctx);\nandroid_log_list_element android_log_peek_next(android_log_context ctx);\n\n/* Finished with reader or writer context */\nint android_log_destroy(android_log_context *ctx);\n\n/*\n * ===========================================================================\n *\n * The stuff in the rest of this file should not be used directly.\n */\n\n#define android_printLog(prio, tag, fmt...) \\\n    __android_log_print(prio, tag, fmt)\n\n#define android_vprintLog(prio, cond, tag, fmt...) \\\n    __android_log_vprint(prio, tag, fmt)\n\n/* XXX Macros to work around syntax errors in places where format string\n * arg is not passed to ALOG_ASSERT, LOG_ALWAYS_FATAL or LOG_ALWAYS_FATAL_IF\n * (happens only in debug builds).\n */\n\n/* Returns 2nd arg.  Used to substitute default value if caller's vararg list\n * is empty.\n */\n#define __android_second(dummy, second, ...)     second\n\n/* If passed multiple args, returns ',' followed by all but 1st arg, otherwise\n * returns nothing.\n */\n#define __android_rest(first, ...)               , ## __VA_ARGS__\n\n#define android_printAssert(cond, tag, fmt...) \\\n    __android_log_assert(cond, tag, \\\n        __android_second(0, ## fmt, NULL) __android_rest(fmt))\n\n#define android_writeLog(prio, tag, text) \\\n    __android_log_write(prio, tag, text)\n\n#define android_bWriteLog(tag, payload, len) \\\n    __android_log_bwrite(tag, payload, len)\n#define android_btWriteLog(tag, type, payload, len) \\\n    __android_log_btwrite(tag, type, payload, len)\n\n#define android_errorWriteLog(tag, subTag) \\\n    __android_log_error_write(tag, subTag, -1, NULL, 0)\n\n#define android_errorWriteWithInfoLog(tag, subTag, uid, data, dataLen) \\\n    __android_log_error_write(tag, subTag, uid, data, dataLen)\n\n/*\n *    IF_ALOG uses android_testLog, but IF_ALOG can be overridden.\n *    android_testLog will remain constant in its purpose as a wrapper\n *        for Android logging filter policy, and can be subject to\n *        change. It can be reused by the developers that override\n *        IF_ALOG as a convenient means to reimplement their policy\n *        over Android.\n */\n#if LOG_NDEBUG /* Production */\n#define android_testLog(prio, tag) \\\n    (__android_log_is_loggable(prio, tag, ANDROID_LOG_DEBUG) != 0)\n#else\n#define android_testLog(prio, tag) \\\n    (__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE) != 0)\n#endif\n\n/*\n * Use the per-tag properties \"log.tag.<tagname>\" to generate a runtime\n * result of non-zero to expose a log. prio is ANDROID_LOG_VERBOSE to\n * ANDROID_LOG_FATAL. default_prio if no property. Undefined behavior if\n * any other value.\n */\nint __android_log_is_loggable(int prio, const char *tag, int default_prio);\n\nint __android_log_security(); /* Device Owner is present */\n\nint __android_log_error_write(int tag, const char *subTag, int32_t uid, const char *data,\n                              uint32_t dataLen);\n\n/*\n * Send a simple string to the log.\n */\nint __android_log_buf_write(int bufID, int prio, const char *tag, const char *text);\nint __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...)\n#if defined(__GNUC__)\n    __attribute__((__format__(printf, 4, 5)))\n#endif\n    ;\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _LIBS_LOG_LOG_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/log/log_read.h",
    "content": "/*\n * Copyright (C) 2013-2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBS_LOG_LOG_READ_H\n#define _LIBS_LOG_LOG_READ_H\n\n#include <stdint.h>\n#include <time.h>\n\n/* struct log_time is a wire-format variant of struct timespec */\n#define NS_PER_SEC 1000000000ULL\n\n#ifdef __cplusplus\n\n// NB: do NOT define a copy constructor. This will result in structure\n// no longer being compatible with pass-by-value which is desired\n// efficient behavior. Also, pass-by-reference breaks C/C++ ABI.\nstruct log_time {\npublic:\n    uint32_t tv_sec; // good to Feb 5 2106\n    uint32_t tv_nsec;\n\n    static const uint32_t tv_sec_max = 0xFFFFFFFFUL;\n    static const uint32_t tv_nsec_max = 999999999UL;\n\n    log_time(const timespec &T)\n    {\n        tv_sec = T.tv_sec;\n        tv_nsec = T.tv_nsec;\n    }\n    log_time(uint32_t sec, uint32_t nsec)\n    {\n        tv_sec = sec;\n        tv_nsec = nsec;\n    }\n    static const timespec EPOCH;\n    log_time()\n    {\n    }\n    log_time(clockid_t id)\n    {\n        timespec T;\n        clock_gettime(id, &T);\n        tv_sec = T.tv_sec;\n        tv_nsec = T.tv_nsec;\n    }\n    log_time(const char *T)\n    {\n        const uint8_t *c = (const uint8_t *) T;\n        tv_sec = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);\n        tv_nsec = c[4] | (c[5] << 8) | (c[6] << 16) | (c[7] << 24);\n    }\n\n    // timespec\n    bool operator== (const timespec &T) const\n    {\n        return (tv_sec == static_cast<uint32_t>(T.tv_sec))\n            && (tv_nsec == static_cast<uint32_t>(T.tv_nsec));\n    }\n    bool operator!= (const timespec &T) const\n    {\n        return !(*this == T);\n    }\n    bool operator< (const timespec &T) const\n    {\n        return (tv_sec < static_cast<uint32_t>(T.tv_sec))\n            || ((tv_sec == static_cast<uint32_t>(T.tv_sec))\n                && (tv_nsec < static_cast<uint32_t>(T.tv_nsec)));\n    }\n    bool operator>= (const timespec &T) const\n    {\n        return !(*this < T);\n    }\n    bool operator> (const timespec &T) const\n    {\n        return (tv_sec > static_cast<uint32_t>(T.tv_sec))\n            || ((tv_sec == static_cast<uint32_t>(T.tv_sec))\n                && (tv_nsec > static_cast<uint32_t>(T.tv_nsec)));\n    }\n    bool operator<= (const timespec &T) const\n    {\n        return !(*this > T);\n    }\n    log_time operator-= (const timespec &T);\n    log_time operator- (const timespec &T) const\n    {\n        log_time local(*this);\n        return local -= T;\n    }\n    log_time operator+= (const timespec &T);\n    log_time operator+ (const timespec &T) const\n    {\n        log_time local(*this);\n        return local += T;\n    }\n\n    // log_time\n    bool operator== (const log_time &T) const\n    {\n        return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec);\n    }\n    bool operator!= (const log_time &T) const\n    {\n        return !(*this == T);\n    }\n    bool operator< (const log_time &T) const\n    {\n        return (tv_sec < T.tv_sec)\n            || ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec));\n    }\n    bool operator>= (const log_time &T) const\n    {\n        return !(*this < T);\n    }\n    bool operator> (const log_time &T) const\n    {\n        return (tv_sec > T.tv_sec)\n            || ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec));\n    }\n    bool operator<= (const log_time &T) const\n    {\n        return !(*this > T);\n    }\n    log_time operator-= (const log_time &T);\n    log_time operator- (const log_time &T) const\n    {\n        log_time local(*this);\n        return local -= T;\n    }\n    log_time operator+= (const log_time &T);\n    log_time operator+ (const log_time &T) const\n    {\n        log_time local(*this);\n        return local += T;\n    }\n\n    uint64_t nsec() const\n    {\n        return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec;\n    }\n\n    static const char default_format[];\n\n    // Add %#q for the fraction of a second to the standard library functions\n    char *strptime(const char *s, const char *format = default_format);\n} __attribute__((__packed__));\n\n#else\n\ntypedef struct log_time {\n    uint32_t tv_sec;\n    uint32_t tv_nsec;\n} __attribute__((__packed__)) log_time;\n\n#endif\n\n#endif /* define _LIBS_LOG_LOG_READ_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/log/logd.h",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _ANDROID_CUTILS_LOGD_H\n#define _ANDROID_CUTILS_LOGD_H\n\n/* the stable/frozen log-related definitions have been\n * moved to this header, which is exposed by the NDK\n */\n#include <android/log.h>\n\n/* the rest is only used internally by the system */\n#if !defined(_WIN32)\n#include <pthread.h>\n#endif\n#include <stdarg.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <sys/types.h>\n#include <time.h>\n#include <unistd.h>\n\n#include <log/uio.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nint __android_log_bwrite(int32_t tag, const void *payload, size_t len);\nint __android_log_btwrite(int32_t tag, char type, const void *payload,\n    size_t len);\nint __android_log_bswrite(int32_t tag, const char *payload);\n\nint __android_log_security_bwrite(int32_t tag, const void *payload, size_t len);\nint __android_log_security_bswrite(int32_t tag, const char *payload);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _LOGD_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/log/logger.h",
    "content": "/*\n**\n** Copyright 2007-2014, The Android Open Source Project\n**\n** This file is dual licensed.  It may be redistributed and/or modified\n** under the terms of the Apache 2.0 License OR version 2 of the GNU\n** General Public License.\n*/\n\n#ifndef _LIBS_LOG_LOGGER_H\n#define _LIBS_LOG_LOGGER_H\n\n#include <stdint.h>\n#ifdef __linux__\n#include <time.h> /* clockid_t definition */\n#endif\n\n#include <log/log.h>\n#include <log/log_read.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n * The userspace structure for version 1 of the logger_entry ABI.\n * This structure is returned to userspace by the kernel logger\n * driver unless an upgrade to a newer ABI version is requested.\n */\nstruct logger_entry {\n    uint16_t    len;    /* length of the payload */\n    uint16_t    __pad;  /* no matter what, we get 2 bytes of padding */\n    int32_t     pid;    /* generating process's pid */\n    int32_t     tid;    /* generating process's tid */\n    int32_t     sec;    /* seconds since Epoch */\n    int32_t     nsec;   /* nanoseconds */\n    char        msg[0]; /* the entry's payload */\n} __attribute__((__packed__));\n\n/*\n * The userspace structure for version 2 of the logger_entry ABI.\n * This structure is returned to userspace if ioctl(LOGGER_SET_VERSION)\n * is called with version==2; or used with the user space log daemon.\n */\nstruct logger_entry_v2 {\n    uint16_t    len;       /* length of the payload */\n    uint16_t    hdr_size;  /* sizeof(struct logger_entry_v2) */\n    int32_t     pid;       /* generating process's pid */\n    int32_t     tid;       /* generating process's tid */\n    int32_t     sec;       /* seconds since Epoch */\n    int32_t     nsec;      /* nanoseconds */\n    uint32_t    euid;      /* effective UID of logger */\n    char        msg[0];    /* the entry's payload */\n} __attribute__((__packed__));\n\nstruct logger_entry_v3 {\n    uint16_t    len;       /* length of the payload */\n    uint16_t    hdr_size;  /* sizeof(struct logger_entry_v3) */\n    int32_t     pid;       /* generating process's pid */\n    int32_t     tid;       /* generating process's tid */\n    int32_t     sec;       /* seconds since Epoch */\n    int32_t     nsec;      /* nanoseconds */\n    uint32_t    lid;       /* log id of the payload */\n    char        msg[0];    /* the entry's payload */\n} __attribute__((__packed__));\n\nstruct logger_entry_v4 {\n    uint16_t    len;       /* length of the payload */\n    uint16_t    hdr_size;  /* sizeof(struct logger_entry_v4) */\n    int32_t     pid;       /* generating process's pid */\n    uint32_t    tid;       /* generating process's tid */\n    uint32_t    sec;       /* seconds since Epoch */\n    uint32_t    nsec;      /* nanoseconds */\n    uint32_t    lid;       /* log id of the payload, bottom 4 bits currently */\n    uint32_t    uid;       /* generating process's uid */\n    char        msg[0];    /* the entry's payload */\n} __attribute__((__packed__));\n\n/*\n * The maximum size of the log entry payload that can be\n * written to the logger. An attempt to write more than\n * this amount will result in a truncated log entry.\n */\n#define LOGGER_ENTRY_MAX_PAYLOAD\t4068\n\n/*\n * The maximum size of a log entry which can be read from the\n * kernel logger driver. An attempt to read less than this amount\n * may result in read() returning EINVAL.\n */\n#define LOGGER_ENTRY_MAX_LEN\t\t(5*1024)\n\n#define NS_PER_SEC 1000000000ULL\n\nstruct log_msg {\n    union {\n        unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];\n        struct logger_entry_v4 entry;\n        struct logger_entry_v4 entry_v4;\n        struct logger_entry_v3 entry_v3;\n        struct logger_entry_v2 entry_v2;\n        struct logger_entry    entry_v1;\n    } __attribute__((aligned(4)));\n#ifdef __cplusplus\n    /* Matching log_time operators */\n    bool operator== (const log_msg &T) const\n    {\n        return (entry.sec == T.entry.sec) && (entry.nsec == T.entry.nsec);\n    }\n    bool operator!= (const log_msg &T) const\n    {\n        return !(*this == T);\n    }\n    bool operator< (const log_msg &T) const\n    {\n        return (entry.sec < T.entry.sec)\n            || ((entry.sec == T.entry.sec)\n             && (entry.nsec < T.entry.nsec));\n    }\n    bool operator>= (const log_msg &T) const\n    {\n        return !(*this < T);\n    }\n    bool operator> (const log_msg &T) const\n    {\n        return (entry.sec > T.entry.sec)\n            || ((entry.sec == T.entry.sec)\n             && (entry.nsec > T.entry.nsec));\n    }\n    bool operator<= (const log_msg &T) const\n    {\n        return !(*this > T);\n    }\n    uint64_t nsec() const\n    {\n        return static_cast<uint64_t>(entry.sec) * NS_PER_SEC + entry.nsec;\n    }\n\n    /* packet methods */\n    log_id_t id()\n    {\n        return (log_id_t) entry.lid;\n    }\n    char *msg()\n    {\n        return entry.hdr_size ? (char *) buf + entry.hdr_size : entry_v1.msg;\n    }\n    unsigned int len()\n    {\n        return (entry.hdr_size ? entry.hdr_size : sizeof(entry_v1)) + entry.len;\n    }\n#endif\n};\n\nstruct logger;\n\nlog_id_t android_logger_get_id(struct logger *logger);\n\nint android_logger_clear(struct logger *logger);\nlong android_logger_get_log_size(struct logger *logger);\nint android_logger_set_log_size(struct logger *logger, unsigned long size);\nlong android_logger_get_log_readable_size(struct logger *logger);\nint android_logger_get_log_version(struct logger *logger);\n\nstruct logger_list;\n\nssize_t android_logger_get_statistics(struct logger_list *logger_list,\n                                      char *buf, size_t len);\nssize_t android_logger_get_prune_list(struct logger_list *logger_list,\n                                      char *buf, size_t len);\nint android_logger_set_prune_list(struct logger_list *logger_list,\n                                  char *buf, size_t len);\n\n#define ANDROID_LOG_RDONLY   O_RDONLY\n#define ANDROID_LOG_WRONLY   O_WRONLY\n#define ANDROID_LOG_RDWR     O_RDWR\n#define ANDROID_LOG_ACCMODE  O_ACCMODE\n#define ANDROID_LOG_NONBLOCK O_NONBLOCK\n#define ANDROID_LOG_WRAP     0x40000000 /* Block until buffer about to wrap */\n#define ANDROID_LOG_WRAP_DEFAULT_TIMEOUT 7200 /* 2 hour default */\n#define ANDROID_LOG_PSTORE   0x80000000\n\nstruct logger_list *android_logger_list_alloc(int mode,\n                                              unsigned int tail,\n                                              pid_t pid);\nstruct logger_list *android_logger_list_alloc_time(int mode,\n                                                   log_time start,\n                                                   pid_t pid);\nvoid android_logger_list_free(struct logger_list *logger_list);\n/* In the purest sense, the following two are orthogonal interfaces */\nint android_logger_list_read(struct logger_list *logger_list,\n                             struct log_msg *log_msg);\n\n/* Multiple log_id_t opens */\nstruct logger *android_logger_open(struct logger_list *logger_list,\n                                   log_id_t id);\n#define android_logger_close android_logger_free\n/* Single log_id_t open */\nstruct logger_list *android_logger_list_open(log_id_t id,\n                                             int mode,\n                                             unsigned int tail,\n                                             pid_t pid);\n#define android_logger_list_close android_logger_list_free\n\n#ifdef __linux__\nclockid_t android_log_clockid();\n#endif\n\n/*\n * log_id_t helpers\n */\nlog_id_t android_name_to_log_id(const char *logName);\nconst char *android_log_id_to_name(log_id_t log_id);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _LIBS_LOG_LOGGER_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/log/logprint.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LOGPRINT_H\n#define _LOGPRINT_H\n\n#include <log/log.h>\n#include <log/logger.h>\n#include <log/event_tag_map.h>\n#include <pthread.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef enum {\n    FORMAT_OFF = 0,\n    FORMAT_BRIEF,\n    FORMAT_PROCESS,\n    FORMAT_TAG,\n    FORMAT_THREAD,\n    FORMAT_RAW,\n    FORMAT_TIME,\n    FORMAT_THREADTIME,\n    FORMAT_LONG,\n    /* The following are modifiers to above formats */\n    FORMAT_MODIFIER_COLOR,     /* converts priority to color */\n    FORMAT_MODIFIER_TIME_USEC, /* switches from msec to usec time precision */\n    FORMAT_MODIFIER_PRINTABLE, /* converts non-printable to printable escapes */\n    FORMAT_MODIFIER_YEAR,      /* Adds year to date */\n    FORMAT_MODIFIER_ZONE,      /* Adds zone to date */\n    FORMAT_MODIFIER_EPOCH,     /* Print time as seconds since Jan 1 1970 */\n    FORMAT_MODIFIER_MONOTONIC, /* Print cpu time as seconds since start */\n    FORMAT_MODIFIER_UID,       /* Adds uid */\n} AndroidLogPrintFormat;\n\ntypedef struct AndroidLogFormat_t AndroidLogFormat;\n\ntypedef struct AndroidLogEntry_t {\n    time_t tv_sec;\n    long tv_nsec;\n    android_LogPriority priority;\n    int32_t uid;\n    int32_t pid;\n    int32_t tid;\n    const char * tag;\n    size_t messageLen;\n    const char * message;\n} AndroidLogEntry;\n\nAndroidLogFormat *android_log_format_new();\n\nvoid android_log_format_free(AndroidLogFormat *p_format);\n\n/* currently returns 0 if format is a modifier, 1 if not */\nint android_log_setPrintFormat(AndroidLogFormat *p_format,\n        AndroidLogPrintFormat format);\n\n/**\n * Returns FORMAT_OFF on invalid string\n */\nAndroidLogPrintFormat android_log_formatFromString(const char *s);\n\n/**\n * filterExpression: a single filter expression\n * eg \"AT:d\"\n *\n * returns 0 on success and -1 on invalid expression\n *\n * Assumes single threaded execution\n *\n */\n\nint android_log_addFilterRule(AndroidLogFormat *p_format,\n        const char *filterExpression);\n\n\n/**\n * filterString: a whitespace-separated set of filter expressions\n * eg \"AT:d *:i\"\n *\n * returns 0 on success and -1 on invalid expression\n *\n * Assumes single threaded execution\n *\n */\n\nint android_log_addFilterString(AndroidLogFormat *p_format,\n        const char *filterString);\n\n\n/**\n * returns 1 if this log line should be printed based on its priority\n * and tag, and 0 if it should not\n */\nint android_log_shouldPrintLine (\n        AndroidLogFormat *p_format, const char *tag, android_LogPriority pri);\n\n\n/**\n * Splits a wire-format buffer into an AndroidLogEntry\n * entry allocated by caller. Pointers will point directly into buf\n *\n * Returns 0 on success and -1 on invalid wire format (entry will be\n * in unspecified state)\n */\nint android_log_processLogBuffer(struct logger_entry *buf,\n                                 AndroidLogEntry *entry);\n\n/**\n * Like android_log_processLogBuffer, but for binary logs.\n *\n * If \"map\" is non-NULL, it will be used to convert the log tag number\n * into a string.\n */\nint android_log_processBinaryLogBuffer(struct logger_entry *buf,\n    AndroidLogEntry *entry, const EventTagMap* map, char* messageBuf,\n    int messageBufLen);\n\n\n/**\n * Formats a log message into a buffer\n *\n * Uses defaultBuffer if it can, otherwise malloc()'s a new buffer\n * If return value != defaultBuffer, caller must call free()\n * Returns NULL on malloc error\n */\n\nchar *android_log_formatLogLine (\n    AndroidLogFormat *p_format,\n    char *defaultBuffer,\n    size_t defaultBufferSize,\n    const AndroidLogEntry *p_line,\n    size_t *p_outLength);\n\n\n/**\n * Either print or do not print log line, based on filter\n *\n * Assumes single threaded execution\n *\n */\nint android_log_printLogLine(\n    AndroidLogFormat *p_format,\n    int fd,\n    const AndroidLogEntry *entry);\n\n\n#ifdef __cplusplus\n}\n#endif\n\n\n#endif /*_LOGPRINT_H*/\n"
  },
  {
    "path": "atlas-aapt/system/core/include/log/uio.h",
    "content": "/*\n * Copyright (C) 2007-2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBS_CUTILS_UIO_H\n#define _LIBS_CUTILS_UIO_H\n\n#if !defined(_WIN32)\n\n#include <sys/uio.h>\n\n#else\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n//\n// Implementation of sys/uio.h for Win32.\n//\n\n#include <stddef.h>\n\nstruct iovec {\n    void*  iov_base;\n    size_t iov_len;\n};\n\nextern int  readv( int  fd, struct iovec*  vecs, int  count );\nextern int  writev( int  fd, const struct iovec*  vecs, int  count );\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n#endif /* _LIBS_UTILS_UIO_H */\n\n"
  },
  {
    "path": "atlas-aapt/system/core/include/memtrack/memtrack.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBMEMTRACK_MEMTRACK_H_\n#define _LIBMEMTRACK_MEMTRACK_H_\n\n#include <sys/types.h>\n#include <stddef.h>\n#include <cutils/compiler.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * struct memtrack_proc\n *\n * an opaque handle to the memory stats on a process.\n * Created with memtrack_proc_new, destroyed by\n * memtrack_proc_destroy.  Can be reused multiple times with\n * memtrack_proc_get.\n */\nstruct memtrack_proc;\n\n/**\n * memtrack_init\n *\n * Must be called once before calling any other functions.  After this function\n * is called, everything else is thread-safe.\n *\n * Returns 0 on success, -errno on error.\n */\nint memtrack_init(void);\n\n/**\n * memtrack_proc_new\n *\n * Return a new handle to hold process memory stats.\n *\n * Returns NULL on error.\n */\nstruct memtrack_proc *memtrack_proc_new(void);\n\n/**\n * memtrack_proc_destroy\n *\n * Free all memory associated with a process memory stats handle.\n */\nvoid memtrack_proc_destroy(struct memtrack_proc *p);\n\n/**\n * memtrack_proc_get\n *\n * Fill a process memory stats handle with data about the given pid.  Can be\n * called on a handle that was just allocated with memtrack_proc_new,\n * or on a handle that has been previously passed to memtrack_proc_get\n * to replace the data with new data on the same or another process.  It is\n * expected that the second call on the same handle should not require\n * allocating any new memory.\n *\n * Returns 0 on success, -errno on error.\n */\nint memtrack_proc_get(struct memtrack_proc *p, pid_t pid);\n\n/**\n * memtrack_proc_graphics_total\n *\n * Return total amount of memory that has been allocated for use as window\n * buffers.  Does not differentiate between memory that has already been\n * accounted for by reading /proc/pid/smaps and memory that has not been\n * accounted for.\n *\n * Returns non-negative size in bytes on success, -errno on error.\n */\nssize_t memtrack_proc_graphics_total(struct memtrack_proc *p);\n\n/**\n * memtrack_proc_graphics_pss\n *\n * Return total amount of memory that has been allocated for use as window\n * buffers, but has not already been accounted for by reading /proc/pid/smaps.\n * Memory that is shared across processes may already be divided by the\n * number of processes that share it (preferred), or may be charged in full to\n * every process that shares it, depending on the capabilities of the driver.\n *\n * Returns non-negative size in bytes on success, -errno on error.\n */\nssize_t memtrack_proc_graphics_pss(struct memtrack_proc *p);\n\n/**\n * memtrack_proc_gl_total\n *\n * Same as memtrack_proc_graphics_total, but counts GL memory (which\n * should not overlap with graphics memory) instead of graphics memory.\n *\n * Returns non-negative size in bytes on success, -errno on error.\n */\nssize_t memtrack_proc_gl_total(struct memtrack_proc *p);\n\n/**\n * memtrack_proc_gl_pss\n *\n * Same as memtrack_proc_graphics_total, but counts GL memory (which\n * should not overlap with graphics memory) instead of graphics memory.\n *\n * Returns non-negative size in bytes on success, -errno on error.\n */\nssize_t memtrack_proc_gl_pss(struct memtrack_proc *p);\n\n/**\n * memtrack_proc_other_total\n *\n * Same as memtrack_proc_graphics_total, but counts miscellaneous memory\n * not tracked by gl or graphics calls above.\n *\n * Returns non-negative size in bytes on success, -errno on error.\n */\nssize_t memtrack_proc_other_total(struct memtrack_proc *p);\n\n/**\n * memtrack_proc_other_pss\n *\n * Same as memtrack_proc_graphics_total, but counts miscellaneous memory\n * not tracked by gl or graphics calls above.\n *\n * Returns non-negative size in bytes on success, -errno on error.\n */\nssize_t memtrack_proc_other_pss(struct memtrack_proc *p);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/mincrypt/dsa_sig.h",
    "content": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Google Inc. nor the names of its contributors may\n *       be used to endorse or promote products derived from this software\n *       without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_DSA_SIG_H_\n#define SYSTEM_CORE_INCLUDE_MINCRYPT_DSA_SIG_H_\n\n#include \"mincrypt/p256.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// Returns 0 if input sig is not a valid ASN.1 sequence\nint dsa_sig_unpack(unsigned char* sig, int sig_len, p256_int* r_int, p256_int* s_int);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* SYSTEM_CORE_INCLUDE_MINCRYPT_DSA_SIG_H_ */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/mincrypt/hash-internal.h",
    "content": "/*\n * Copyright 2007 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Google Inc. nor the names of its contributors may\n *       be used to endorse or promote products derived from this software\n *       without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_HASH_INTERNAL_H_\n#define SYSTEM_CORE_INCLUDE_MINCRYPT_HASH_INTERNAL_H_\n\n#include <stdint.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif  // __cplusplus\n\nstruct HASH_CTX;  // forward decl\n\ntypedef struct HASH_VTAB {\n  void (* const init)(struct HASH_CTX*);\n  void (* const update)(struct HASH_CTX*, const void*, int);\n  const uint8_t* (* const final)(struct HASH_CTX*);\n  const uint8_t* (* const hash)(const void*, int, uint8_t*);\n  int size;\n} HASH_VTAB;\n\ntypedef struct HASH_CTX {\n  const HASH_VTAB * f;\n  uint64_t count;\n  uint8_t buf[64];\n  uint32_t state[8];  // upto SHA2\n} HASH_CTX;\n\n#define HASH_init(ctx) (ctx)->f->init(ctx)\n#define HASH_update(ctx, data, len) (ctx)->f->update(ctx, data, len)\n#define HASH_final(ctx) (ctx)->f->final(ctx)\n#define HASH_hash(data, len, digest) (ctx)->f->hash(data, len, digest)\n#define HASH_size(ctx) (ctx)->f->size\n\n#ifdef __cplusplus\n}\n#endif  // __cplusplus\n\n#endif  // SYSTEM_CORE_INCLUDE_MINCRYPT_HASH_INTERNAL_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/include/mincrypt/p256.h",
    "content": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Google Inc. nor the names of its contributors may\n *       be used to endorse or promote products derived from this software\n *       without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_LITE_P256_H_\n#define SYSTEM_CORE_INCLUDE_MINCRYPT_LITE_P256_H_\n\n// Collection of routines manipulating 256 bit unsigned integers.\n// Just enough to implement ecdsa-p256 and related algorithms.\n\n#include <stdint.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define P256_BITSPERDIGIT 32\n#define P256_NDIGITS 8\n#define P256_NBYTES 32\n\ntypedef int p256_err;\ntypedef uint32_t p256_digit;\ntypedef int32_t p256_sdigit;\ntypedef uint64_t p256_ddigit;\ntypedef int64_t p256_sddigit;\n\n// Defining p256_int as struct to leverage struct assigment.\ntypedef struct {\n  p256_digit a[P256_NDIGITS];\n} p256_int;\n\nextern const p256_int SECP256r1_n;  // Curve order\nextern const p256_int SECP256r1_p;  // Curve prime\nextern const p256_int SECP256r1_b;  // Curve param\n\n// Initialize a p256_int to zero.\nvoid p256_init(p256_int* a);\n\n// Clear a p256_int to zero.\nvoid p256_clear(p256_int* a);\n\n// Return bit. Index 0 is least significant.\nint p256_get_bit(const p256_int* a, int index);\n\n// b := a % MOD\nvoid p256_mod(\n    const p256_int* MOD,\n    const p256_int* a,\n    p256_int* b);\n\n// c := a * (top_b | b) % MOD\nvoid p256_modmul(\n    const p256_int* MOD,\n    const p256_int* a,\n    const p256_digit top_b,\n    const p256_int* b,\n    p256_int* c);\n\n// b := 1 / a % MOD\n// MOD best be SECP256r1_n\nvoid p256_modinv(\n    const p256_int* MOD,\n    const p256_int* a,\n    p256_int* b);\n\n// b := 1 / a % MOD\n// MOD best be SECP256r1_n\n// Faster than p256_modinv()\nvoid p256_modinv_vartime(\n    const p256_int* MOD,\n    const p256_int* a,\n    p256_int* b);\n\n// b := a << (n % P256_BITSPERDIGIT)\n// Returns the bits shifted out of most significant digit.\np256_digit p256_shl(const p256_int* a, int n, p256_int* b);\n\n// b := a >> (n % P256_BITSPERDIGIT)\nvoid p256_shr(const p256_int* a, int n, p256_int* b);\n\nint p256_is_zero(const p256_int* a);\nint p256_is_odd(const p256_int* a);\nint p256_is_even(const p256_int* a);\n\n// Returns -1, 0 or 1.\nint p256_cmp(const p256_int* a, const p256_int *b);\n\n// c: = a - b\n// Returns -1 on borrow.\nint p256_sub(const p256_int* a, const p256_int* b, p256_int* c);\n\n// c := a + b\n// Returns 1 on carry.\nint p256_add(const p256_int* a, const p256_int* b, p256_int* c);\n\n// c := a + (single digit)b\n// Returns carry 1 on carry.\nint p256_add_d(const p256_int* a, p256_digit b, p256_int* c);\n\n// ec routines.\n\n// {out_x,out_y} := nG\nvoid p256_base_point_mul(const p256_int *n,\n                         p256_int *out_x,\n                         p256_int *out_y);\n\n// {out_x,out_y} := n{in_x,in_y}\nvoid p256_point_mul(const p256_int *n,\n                    const p256_int *in_x,\n                    const p256_int *in_y,\n                    p256_int *out_x,\n                    p256_int *out_y);\n\n// {out_x,out_y} := n1G + n2{in_x,in_y}\nvoid p256_points_mul_vartime(\n    const p256_int *n1, const p256_int *n2,\n    const p256_int *in_x, const p256_int *in_y,\n    p256_int *out_x, p256_int *out_y);\n\n// Return whether point {x,y} is on curve.\nint p256_is_valid_point(const p256_int* x, const p256_int* y);\n\n// Outputs big-endian binary form. No leading zero skips.\nvoid p256_to_bin(const p256_int* src, uint8_t dst[P256_NBYTES]);\n\n// Reads from big-endian binary form,\n// thus pre-pad with leading zeros if short.\nvoid p256_from_bin(const uint8_t src[P256_NBYTES], p256_int* dst);\n\n#define P256_DIGITS(x) ((x)->a)\n#define P256_DIGIT(x,y) ((x)->a[y])\n\n#define P256_ZERO {{0}}\n#define P256_ONE {{1}}\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif  // SYSTEM_CORE_INCLUDE_MINCRYPT_LITE_P256_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/include/mincrypt/p256_ecdsa.h",
    "content": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Google Inc. nor the names of its contributors may\n *       be used to endorse or promote products derived from this software\n *       without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_P256_ECDSA_H_\n#define SYSTEM_CORE_INCLUDE_MINCRYPT_P256_ECDSA_H_\n\n// Using current directory as relative include path here since\n// this code typically gets lifted into a variety of build systems\n// and directory structures.\n#include \"p256.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// Returns 0 if {r,s} is not a signature on message for\n// public key {key_x,key_y}.\n//\n// Note: message is a p256_int.\n// Convert from a binary string using p256_from_bin().\nint p256_ecdsa_verify(const p256_int* key_x,\n                      const p256_int* key_y,\n                      const p256_int* message,\n                      const p256_int* r, const p256_int* s);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif  // SYSTEM_CORE_INCLUDE_MINCRYPT_P256_ECDSA_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/include/mincrypt/rsa.h",
    "content": "/* rsa.h\n**\n** Copyright 2008, The Android Open Source Project\n**\n** Redistribution and use in source and binary forms, with or without\n** modification, are permitted provided that the following conditions are met:\n**     * Redistributions of source code must retain the above copyright\n**       notice, this list of conditions and the following disclaimer.\n**     * Redistributions in binary form must reproduce the above copyright\n**       notice, this list of conditions and the following disclaimer in the\n**       documentation and/or other materials provided with the distribution.\n**     * Neither the name of Google Inc. nor the names of its contributors may\n**       be used to endorse or promote products derived from this software\n**       without specific prior written permission.\n**\n** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR\n** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_RSA_H_\n#define SYSTEM_CORE_INCLUDE_MINCRYPT_RSA_H_\n\n#include <inttypes.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define RSANUMBYTES 256           /* 2048 bit key length */\n#define RSANUMWORDS (RSANUMBYTES / sizeof(uint32_t))\n\ntypedef struct RSAPublicKey {\n    int len;                  /* Length of n[] in number of uint32_t */\n    uint32_t n0inv;           /* -1 / n[0] mod 2^32 */\n    uint32_t n[RSANUMWORDS];  /* modulus as little endian array */\n    uint32_t rr[RSANUMWORDS]; /* R^2 as little endian array */\n    int exponent;             /* 3 or 65537 */\n} RSAPublicKey;\n\nint RSA_verify(const RSAPublicKey *key,\n               const uint8_t* signature,\n               const int len,\n               const uint8_t* hash,\n               const int hash_len);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // SYSTEM_CORE_INCLUDE_MINCRYPT_RSA_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/include/mincrypt/sha.h",
    "content": "/*\n * Copyright 2005 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Google Inc. nor the names of its contributors may\n *       be used to endorse or promote products derived from this software\n *       without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_SHA1_H_\n#define SYSTEM_CORE_INCLUDE_MINCRYPT_SHA1_H_\n\n#include <stdint.h>\n#include \"hash-internal.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif // __cplusplus\n\ntypedef HASH_CTX SHA_CTX;\n\nvoid SHA_init(SHA_CTX* ctx);\nvoid SHA_update(SHA_CTX* ctx, const void* data, int len);\nconst uint8_t* SHA_final(SHA_CTX* ctx);\n\n// Convenience method. Returns digest address.\n// NOTE: *digest needs to hold SHA_DIGEST_SIZE bytes.\nconst uint8_t* SHA_hash(const void* data, int len, uint8_t* digest);\n\n#define SHA_DIGEST_SIZE 20\n\n#ifdef __cplusplus\n}\n#endif // __cplusplus\n\n#endif  // SYSTEM_CORE_INCLUDE_MINCRYPT_SHA1_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/include/mincrypt/sha256.h",
    "content": "/*\n * Copyright 2011 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *     * Neither the name of Google Inc. nor the names of its contributors may\n *       be used to endorse or promote products derived from this software\n *       without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_SHA256_H_\n#define SYSTEM_CORE_INCLUDE_MINCRYPT_SHA256_H_\n\n#include <stdint.h>\n#include \"hash-internal.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif // __cplusplus\n\ntypedef HASH_CTX SHA256_CTX;\n\nvoid SHA256_init(SHA256_CTX* ctx);\nvoid SHA256_update(SHA256_CTX* ctx, const void* data, int len);\nconst uint8_t* SHA256_final(SHA256_CTX* ctx);\n\n// Convenience method. Returns digest address.\nconst uint8_t* SHA256_hash(const void* data, int len, uint8_t* digest);\n\n#define SHA256_DIGEST_SIZE 32\n\n#ifdef __cplusplus\n}\n#endif // __cplusplus\n\n#endif  // SYSTEM_CORE_INCLUDE_MINCRYPT_SHA256_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/include/nativebridge/native_bridge.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef NATIVE_BRIDGE_H_\n#define NATIVE_BRIDGE_H_\n\n#include \"jni.h\"\n#include <signal.h>\n#include <stdint.h>\n#include <sys/types.h>\n\nnamespace android {\n\nstruct NativeBridgeRuntimeCallbacks;\nstruct NativeBridgeRuntimeValues;\n\n// Function pointer type for sigaction. This is mostly the signature of a signal handler, except\n// for the return type. The runtime needs to know whether the signal was handled or should be given\n// to the chain.\ntypedef bool (*NativeBridgeSignalHandlerFn)(int, siginfo_t*, void*);\n\n\n// Open the native bridge, if any. Should be called by Runtime::Init(). A null library filename\n// signals that we do not want to load a native bridge.\nbool LoadNativeBridge(const char* native_bridge_library_filename,\n                      const NativeBridgeRuntimeCallbacks* runtime_callbacks);\n\n// Quick check whether a native bridge will be needed. This is based off of the instruction set\n// of the process.\nbool NeedsNativeBridge(const char* instruction_set);\n\n// Do the early initialization part of the native bridge, if necessary. This should be done under\n// high privileges.\nbool PreInitializeNativeBridge(const char* app_data_dir, const char* instruction_set);\n\n// Initialize the native bridge, if any. Should be called by Runtime::DidForkFromZygote. The JNIEnv*\n// will be used to modify the app environment for the bridge.\nbool InitializeNativeBridge(JNIEnv* env, const char* instruction_set);\n\n// Unload the native bridge, if any. Should be called by Runtime::DidForkFromZygote.\nvoid UnloadNativeBridge();\n\n// Check whether a native bridge is available (opened or initialized). Requires a prior call to\n// LoadNativeBridge.\nbool NativeBridgeAvailable();\n\n// Check whether a native bridge is available (initialized). Requires a prior call to\n// LoadNativeBridge & InitializeNativeBridge.\nbool NativeBridgeInitialized();\n\n// Load a shared library that is supported by the native bridge.\nvoid* NativeBridgeLoadLibrary(const char* libpath, int flag);\n\n// Get a native bridge trampoline for specified native method.\nvoid* NativeBridgeGetTrampoline(void* handle, const char* name, const char* shorty, uint32_t len);\n\n// True if native library is valid and is for an ABI that is supported by native bridge.\nbool NativeBridgeIsSupported(const char* libpath);\n\n// Returns the version number of the native bridge. This information is available after a\n// successful LoadNativeBridge() and before closing it, that is, as long as NativeBridgeAvailable()\n// returns true. Returns 0 otherwise.\nuint32_t NativeBridgeGetVersion();\n\n// Returns a signal handler that the bridge would like to be managed. Only valid for a native\n// bridge supporting the version 2 interface. Will return null if the bridge does not support\n// version 2, or if it doesn't have a signal handler it wants to be known.\nNativeBridgeSignalHandlerFn NativeBridgeGetSignalHandler(int signal);\n\n// Returns whether we have seen a native bridge error. This could happen because the library\n// was not found, rejected, could not be initialized and so on.\n//\n// This functionality is mainly for testing.\nbool NativeBridgeError();\n\n// Returns whether a given string is acceptable as a native bridge library filename.\n//\n// This functionality is exposed mainly for testing.\nbool NativeBridgeNameAcceptable(const char* native_bridge_library_filename);\n\n// Native bridge interfaces to runtime.\nstruct NativeBridgeCallbacks {\n  // Version number of the interface.\n  uint32_t version;\n\n  // Initialize native bridge. Native bridge's internal implementation must ensure MT safety and\n  // that the native bridge is initialized only once. Thus it is OK to call this interface for an\n  // already initialized native bridge.\n  //\n  // Parameters:\n  //   runtime_cbs [IN] the pointer to NativeBridgeRuntimeCallbacks.\n  // Returns:\n  //   true iff initialization was successful.\n  bool (*initialize)(const NativeBridgeRuntimeCallbacks* runtime_cbs, const char* private_dir,\n                     const char* instruction_set);\n\n  // Load a shared library that is supported by the native bridge.\n  //\n  // Parameters:\n  //   libpath [IN] path to the shared library\n  //   flag [IN] the stardard RTLD_XXX defined in bionic dlfcn.h\n  // Returns:\n  //   The opaque handle of the shared library if sucessful, otherwise NULL\n  void* (*loadLibrary)(const char* libpath, int flag);\n\n  // Get a native bridge trampoline for specified native method. The trampoline has same\n  // sigature as the native method.\n  //\n  // Parameters:\n  //   handle [IN] the handle returned from loadLibrary\n  //   shorty [IN] short descriptor of native method\n  //   len [IN] length of shorty\n  // Returns:\n  //   address of trampoline if successful, otherwise NULL\n  void* (*getTrampoline)(void* handle, const char* name, const char* shorty, uint32_t len);\n\n  // Check whether native library is valid and is for an ABI that is supported by native bridge.\n  //\n  // Parameters:\n  //   libpath [IN] path to the shared library\n  // Returns:\n  //   TRUE if library is supported by native bridge, FALSE otherwise\n  bool (*isSupported)(const char* libpath);\n\n  // Provide environment values required by the app running with native bridge according to the\n  // instruction set.\n  //\n  // Parameters:\n  //    instruction_set [IN] the instruction set of the app\n  // Returns:\n  //    NULL if not supported by native bridge.\n  //    Otherwise, return all environment values to be set after fork.\n  const struct NativeBridgeRuntimeValues* (*getAppEnv)(const char* instruction_set);\n\n  // Added callbacks in version 2.\n\n  // Check whether the bridge is compatible with the given version. A bridge may decide not to be\n  // forwards- or backwards-compatible, and libnativebridge will then stop using it.\n  //\n  // Parameters:\n  //     bridge_version [IN] the version of libnativebridge.\n  // Returns:\n  //     true iff the native bridge supports the given version of libnativebridge.\n  bool (*isCompatibleWith)(uint32_t bridge_version);\n\n  // A callback to retrieve a native bridge's signal handler for the specified signal. The runtime\n  // will ensure that the signal handler is being called after the runtime's own handler, but before\n  // all chained handlers. The native bridge should not try to install the handler by itself, as\n  // that will potentially lead to cycles.\n  //\n  // Parameters:\n  //     signal [IN] the signal for which the handler is asked for. Currently, only SIGSEGV is\n  //                 supported by the runtime.\n  // Returns:\n  //     NULL if the native bridge doesn't use a handler or doesn't want it to be managed by the\n  //     runtime.\n  //     Otherwise, a pointer to the signal handler.\n  NativeBridgeSignalHandlerFn (*getSignalHandler)(int signal);\n};\n\n// Runtime interfaces to native bridge.\nstruct NativeBridgeRuntimeCallbacks {\n  // Get shorty of a Java method. The shorty is supposed to be persistent in memory.\n  //\n  // Parameters:\n  //   env [IN] pointer to JNIenv.\n  //   mid [IN] Java methodID.\n  // Returns:\n  //   short descriptor for method.\n  const char* (*getMethodShorty)(JNIEnv* env, jmethodID mid);\n\n  // Get number of native methods for specified class.\n  //\n  // Parameters:\n  //   env [IN] pointer to JNIenv.\n  //   clazz [IN] Java class object.\n  // Returns:\n  //   number of native methods.\n  uint32_t (*getNativeMethodCount)(JNIEnv* env, jclass clazz);\n\n  // Get at most 'method_count' native methods for specified class 'clazz'. Results are outputed\n  // via 'methods' [OUT]. The signature pointer in JNINativeMethod is reused as the method shorty.\n  //\n  // Parameters:\n  //   env [IN] pointer to JNIenv.\n  //   clazz [IN] Java class object.\n  //   methods [OUT] array of method with the name, shorty, and fnPtr.\n  //   method_count [IN] max number of elements in methods.\n  // Returns:\n  //   number of method it actually wrote to methods.\n  uint32_t (*getNativeMethods)(JNIEnv* env, jclass clazz, JNINativeMethod* methods,\n                               uint32_t method_count);\n};\n\n};  // namespace android\n\n#endif  // NATIVE_BRIDGE_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/include/netutils/ifc.h",
    "content": "/*\n * Copyright 2008, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n *\n *     http://www.apache.org/licenses/LICENSE-2.0 \n *\n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.\n */\n\n#ifndef _NETUTILS_IFC_H_\n#define _NETUTILS_IFC_H_\n\n#include <sys/cdefs.h>\n#include <arpa/inet.h>\n\n__BEGIN_DECLS\n\nextern int ifc_init(void);\nextern void ifc_close(void);\n\nextern int ifc_get_ifindex(const char *name, int *if_indexp);\nextern int ifc_get_hwaddr(const char *name, void *ptr);\n\nextern int ifc_up(const char *name);\nextern int ifc_down(const char *name);\n\nextern int ifc_enable(const char *ifname);\nextern int ifc_disable(const char *ifname);\n\n#define RESET_IPV4_ADDRESSES 0x01\n#define RESET_IPV6_ADDRESSES 0x02\n#define RESET_IGNORE_INTERFACE_ADDRESS 0x04\n#define RESET_ALL_ADDRESSES  (RESET_IPV4_ADDRESSES | RESET_IPV6_ADDRESSES)\nextern int ifc_reset_connections(const char *ifname, const int reset_mask);\n\nextern int ifc_get_addr(const char *name, in_addr_t *addr);\nextern int ifc_set_addr(const char *name, in_addr_t addr);\nextern int ifc_add_address(const char *name, const char *address,\n                           int prefixlen);\nextern int ifc_del_address(const char *name, const char *address,\n                           int prefixlen);\nextern int ifc_set_prefixLength(const char *name, int prefixLength);\nextern int ifc_set_hwaddr(const char *name, const void *ptr);\nextern int ifc_clear_addresses(const char *name);\n\nextern int ifc_create_default_route(const char *name, in_addr_t addr);\nextern int ifc_remove_default_route(const char *ifname);\nextern int ifc_get_info(const char *name, in_addr_t *addr, int *prefixLength,\n                        unsigned *flags);\n\nextern int ifc_configure(const char *ifname, in_addr_t address,\n                         uint32_t prefixLength, in_addr_t gateway,\n                         in_addr_t dns1, in_addr_t dns2);\n\nextern in_addr_t prefixLengthToIpv4Netmask(int prefix_length);\n\n__END_DECLS\n\n#endif /* _NETUTILS_IFC_H_ */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/private/android_filesystem_capability.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * Taken from linux/capability.h, with minor modifications\n */\n\n#ifndef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_FILESYSTEM_CAPABILITY_H\n#define _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_FILESYSTEM_CAPABILITY_H\n\n#include <stdint.h>\n\n#define __user\n#define __u32 uint32_t\n#define __le32 uint32_t\n\n#define _LINUX_CAPABILITY_VERSION_1 0x19980330\n#define _LINUX_CAPABILITY_U32S_1 1\n#define _LINUX_CAPABILITY_VERSION_2 0x20071026\n#define _LINUX_CAPABILITY_U32S_2 2\n#define _LINUX_CAPABILITY_VERSION_3 0x20080522\n#define _LINUX_CAPABILITY_U32S_3 2\n\ntypedef struct __user_cap_header_struct {\n __u32 version;\n int pid;\n} __user *cap_user_header_t;\n\ntypedef struct __user_cap_data_struct {\n __u32 effective;\n __u32 permitted;\n __u32 inheritable;\n} __user *cap_user_data_t;\n\n#define VFS_CAP_REVISION_MASK 0xFF000000\n#define VFS_CAP_REVISION_SHIFT 24\n#define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK\n#define VFS_CAP_FLAGS_EFFECTIVE 0x000001\n#define VFS_CAP_REVISION_1 0x01000000\n#define VFS_CAP_U32_1 1\n#define XATTR_CAPS_SZ_1 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_1))\n#define VFS_CAP_REVISION_2 0x02000000\n#define VFS_CAP_U32_2 2\n#define XATTR_CAPS_SZ_2 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_2))\n#define XATTR_CAPS_SZ XATTR_CAPS_SZ_2\n#define VFS_CAP_U32 VFS_CAP_U32_2\n#define VFS_CAP_REVISION VFS_CAP_REVISION_2\n\nstruct vfs_cap_data {\n __le32 magic_etc;\n struct {\n __le32 permitted;\n __le32 inheritable;\n } data[VFS_CAP_U32];\n};\n\n#define _LINUX_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_1\n#define _LINUX_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_1\n#define CAP_CHOWN 0\n#define CAP_DAC_OVERRIDE 1\n#define CAP_DAC_READ_SEARCH 2\n#define CAP_FOWNER 3\n#define CAP_FSETID 4\n#define CAP_KILL 5\n#define CAP_SETGID 6\n#define CAP_SETUID 7\n#define CAP_SETPCAP 8\n#define CAP_LINUX_IMMUTABLE 9\n#define CAP_NET_BIND_SERVICE 10\n#define CAP_NET_BROADCAST 11\n#define CAP_NET_ADMIN 12\n#define CAP_NET_RAW 13\n#define CAP_IPC_LOCK 14\n#define CAP_IPC_OWNER 15\n#define CAP_SYS_MODULE 16\n#define CAP_SYS_RAWIO 17\n#define CAP_SYS_CHROOT 18\n#define CAP_SYS_PTRACE 19\n#define CAP_SYS_PACCT 20\n#define CAP_SYS_ADMIN 21\n#define CAP_SYS_BOOT 22\n#define CAP_SYS_NICE 23\n#define CAP_SYS_RESOURCE 24\n#define CAP_SYS_TIME 25\n#define CAP_SYS_TTY_CONFIG 26\n#define CAP_MKNOD 27\n#define CAP_LEASE 28\n#define CAP_AUDIT_WRITE 29\n#define CAP_AUDIT_CONTROL 30\n#define CAP_SETFCAP 31\n#define CAP_MAC_OVERRIDE 32\n#define CAP_MAC_ADMIN 33\n#define CAP_SYSLOG 34\n#define CAP_WAKE_ALARM 35\n#define CAP_BLOCK_SUSPEND 36\n#define CAP_AUDIT_READ 37\n#define CAP_LAST_CAP CAP_AUDIT_READ\n#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)\n#define CAP_TO_INDEX(x) ((x) >> 5)\n#define CAP_TO_MASK(x) (1 << ((x) & 31))\n\n#undef __user\n#undef __u32\n#undef __le32\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/private/android_filesystem_config.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* This file is used to define the properties of the filesystem\n** images generated by build tools (mkbootfs and mkyaffs2image) and\n** by the device side of adb.\n*/\n\n#ifndef _ANDROID_FILESYSTEM_CONFIG_H_\n#define _ANDROID_FILESYSTEM_CONFIG_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <stdint.h>\n\n#if defined(__ANDROID__)\n#include <linux/capability.h>\n#else\n#include \"android_filesystem_capability.h\"\n#endif\n\n#define CAP_MASK_LONG(cap_name)  (1ULL << (cap_name))\n\n/* This is the master Users and Groups config for the platform.\n * DO NOT EVER RENUMBER\n */\n\n#define AID_ROOT             0  /* traditional unix root user */\n\n#define AID_SYSTEM        1000  /* system server */\n\n#define AID_RADIO         1001  /* telephony subsystem, RIL */\n#define AID_BLUETOOTH     1002  /* bluetooth subsystem */\n#define AID_GRAPHICS      1003  /* graphics devices */\n#define AID_INPUT         1004  /* input devices */\n#define AID_AUDIO         1005  /* audio devices */\n#define AID_CAMERA        1006  /* camera devices */\n#define AID_LOG           1007  /* log devices */\n#define AID_COMPASS       1008  /* compass device */\n#define AID_MOUNT         1009  /* mountd socket */\n#define AID_WIFI          1010  /* wifi subsystem */\n#define AID_ADB           1011  /* android debug bridge (adbd) */\n#define AID_INSTALL       1012  /* group for installing packages */\n#define AID_MEDIA         1013  /* mediaserver process */\n#define AID_DHCP          1014  /* dhcp client */\n#define AID_SDCARD_RW     1015  /* external storage write access */\n#define AID_VPN           1016  /* vpn system */\n#define AID_KEYSTORE      1017  /* keystore subsystem */\n#define AID_USB           1018  /* USB devices */\n#define AID_DRM           1019  /* DRM server */\n#define AID_MDNSR         1020  /* MulticastDNSResponder (service discovery) */\n#define AID_GPS           1021  /* GPS daemon */\n#define AID_UNUSED1       1022  /* deprecated, DO NOT USE */\n#define AID_MEDIA_RW      1023  /* internal media storage write access */\n#define AID_MTP           1024  /* MTP USB driver access */\n#define AID_UNUSED2       1025  /* deprecated, DO NOT USE */\n#define AID_DRMRPC        1026  /* group for drm rpc */\n#define AID_NFC           1027  /* nfc subsystem */\n#define AID_SDCARD_R      1028  /* external storage read access */\n#define AID_CLAT          1029  /* clat part of nat464 */\n#define AID_LOOP_RADIO    1030  /* loop radio devices */\n#define AID_MEDIA_DRM     1031  /* MediaDrm plugins */\n#define AID_PACKAGE_INFO  1032  /* access to installed package details */\n#define AID_SDCARD_PICS   1033  /* external storage photos access */\n#define AID_SDCARD_AV     1034  /* external storage audio/video access */\n#define AID_SDCARD_ALL    1035  /* access all users external storage */\n#define AID_LOGD          1036  /* log daemon */\n#define AID_SHARED_RELRO  1037  /* creator of shared GNU RELRO files */\n#define AID_DBUS          1038  /* dbus-daemon IPC broker process */\n#define AID_TLSDATE       1039  /* tlsdate unprivileged user */\n#define AID_MEDIA_EX      1040  /* mediaextractor process */\n#define AID_AUDIOSERVER   1041  /* audioserver process */\n#define AID_METRICS_COLL  1042  /* metrics_collector process */\n#define AID_METRICSD      1043  /* metricsd process */\n#define AID_WEBSERV       1044  /* webservd process */\n#define AID_DEBUGGERD     1045  /* debuggerd unprivileged user */\n#define AID_MEDIA_CODEC   1046  /* mediacodec process */\n#define AID_CAMERASERVER  1047  /* cameraserver process */\n\n#define AID_SHELL         2000  /* adb and debug shell user */\n#define AID_CACHE         2001  /* cache access */\n#define AID_DIAG          2002  /* access to diagnostic resources */\n\n/* The range 2900-2999 is reserved for OEM, and must never be\n * used here */\n#define AID_OEM_RESERVED_START 2900\n#define AID_OEM_RESERVED_END   2999\n\n/* The 3000 series are intended for use as supplemental group id's only.\n * They indicate special Android capabilities that the kernel is aware of. */\n#define AID_NET_BT_ADMIN  3001  /* bluetooth: create any socket */\n#define AID_NET_BT        3002  /* bluetooth: create sco, rfcomm or l2cap sockets */\n#define AID_INET          3003  /* can create AF_INET and AF_INET6 sockets */\n#define AID_NET_RAW       3004  /* can create raw INET sockets */\n#define AID_NET_ADMIN     3005  /* can configure interfaces and routing tables. */\n#define AID_NET_BW_STATS  3006  /* read bandwidth statistics */\n#define AID_NET_BW_ACCT   3007  /* change bandwidth statistics accounting */\n#define AID_NET_BT_STACK  3008  /* bluetooth: access config files */\n#define AID_READPROC      3009  /* Allow /proc read access */\n#define AID_WAKELOCK      3010  /* Allow system wakelock read/write access */\n\n/* The range 5000-5999 is also reserved for OEM, and must never be used here. */\n#define AID_OEM_RESERVED_2_START 5000\n#define AID_OEM_RESERVED_2_END   5999\n\n#define AID_EVERYBODY     9997  /* shared between all apps in the same profile */\n#define AID_MISC          9998  /* access to misc storage */\n#define AID_NOBODY        9999\n\n#define AID_APP          10000  /* first app user */\n\n#define AID_ISOLATED_START 99000 /* start of uids for fully isolated sandboxed processes */\n#define AID_ISOLATED_END   99999 /* end of uids for fully isolated sandboxed processes */\n\n#define AID_USER        100000  /* offset for uid ranges for each user */\n\n#define AID_SHARED_GID_START 50000 /* start of gids for apps in each user to share */\n#define AID_SHARED_GID_END   59999 /* start of gids for apps in each user to share */\n\n#if !defined(EXCLUDE_FS_CONFIG_STRUCTURES)\n/*\n * Used in:\n *  bionic/libc/bionic/stubs.cpp\n *  external/libselinux/src/android.c\n *  system/core/logd/LogStatistics.cpp\n *  system/core/init/ueventd.cpp\n *  system/core/init/util.cpp\n */\nstruct android_id_info {\n    const char *name;\n    unsigned aid;\n};\n\nstatic const struct android_id_info android_ids[] = {\n    { \"root\",          AID_ROOT, },\n\n    { \"system\",        AID_SYSTEM, },\n\n    { \"radio\",         AID_RADIO, },\n    { \"bluetooth\",     AID_BLUETOOTH, },\n    { \"graphics\",      AID_GRAPHICS, },\n    { \"input\",         AID_INPUT, },\n    { \"audio\",         AID_AUDIO, },\n    { \"camera\",        AID_CAMERA, },\n    { \"log\",           AID_LOG, },\n    { \"compass\",       AID_COMPASS, },\n    { \"mount\",         AID_MOUNT, },\n    { \"wifi\",          AID_WIFI, },\n    { \"adb\",           AID_ADB, },\n    { \"install\",       AID_INSTALL, },\n    { \"media\",         AID_MEDIA, },\n    { \"dhcp\",          AID_DHCP, },\n    { \"sdcard_rw\",     AID_SDCARD_RW, },\n    { \"vpn\",           AID_VPN, },\n    { \"keystore\",      AID_KEYSTORE, },\n    { \"usb\",           AID_USB, },\n    { \"drm\",           AID_DRM, },\n    { \"mdnsr\",         AID_MDNSR, },\n    { \"gps\",           AID_GPS, },\n    // AID_UNUSED1\n    { \"media_rw\",      AID_MEDIA_RW, },\n    { \"mtp\",           AID_MTP, },\n    // AID_UNUSED2\n    { \"drmrpc\",        AID_DRMRPC, },\n    { \"nfc\",           AID_NFC, },\n    { \"sdcard_r\",      AID_SDCARD_R, },\n    { \"clat\",          AID_CLAT, },\n    { \"loop_radio\",    AID_LOOP_RADIO, },\n    { \"mediadrm\",      AID_MEDIA_DRM, },\n    { \"package_info\",  AID_PACKAGE_INFO, },\n    { \"sdcard_pics\",   AID_SDCARD_PICS, },\n    { \"sdcard_av\",     AID_SDCARD_AV, },\n    { \"sdcard_all\",    AID_SDCARD_ALL, },\n    { \"logd\",          AID_LOGD, },\n    { \"shared_relro\",  AID_SHARED_RELRO, },\n    { \"dbus\",          AID_DBUS, },\n    { \"tlsdate\",       AID_TLSDATE, },\n    { \"mediaex\",       AID_MEDIA_EX, },\n    { \"audioserver\",   AID_AUDIOSERVER, },\n    { \"metrics_coll\",  AID_METRICS_COLL },\n    { \"metricsd\",      AID_METRICSD },\n    { \"webserv\",       AID_WEBSERV },\n    { \"debuggerd\",     AID_DEBUGGERD, },\n    { \"mediacodec\",    AID_MEDIA_CODEC, },\n    { \"cameraserver\",  AID_CAMERASERVER, },\n\n    { \"shell\",         AID_SHELL, },\n    { \"cache\",         AID_CACHE, },\n    { \"diag\",          AID_DIAG, },\n\n    { \"net_bt_admin\",  AID_NET_BT_ADMIN, },\n    { \"net_bt\",        AID_NET_BT, },\n    { \"inet\",          AID_INET, },\n    { \"net_raw\",       AID_NET_RAW, },\n    { \"net_admin\",     AID_NET_ADMIN, },\n    { \"net_bw_stats\",  AID_NET_BW_STATS, },\n    { \"net_bw_acct\",   AID_NET_BW_ACCT, },\n    { \"net_bt_stack\",  AID_NET_BT_STACK, },\n    { \"readproc\",      AID_READPROC, },\n    { \"wakelock\",      AID_WAKELOCK, },\n\n    { \"everybody\",     AID_EVERYBODY, },\n    { \"misc\",          AID_MISC, },\n    { \"nobody\",        AID_NOBODY, },\n};\n\n#define android_id_count \\\n    (sizeof(android_ids) / sizeof(android_ids[0]))\n\nstruct fs_path_config {\n    unsigned mode;\n    unsigned uid;\n    unsigned gid;\n    uint64_t capabilities;\n    const char *prefix;\n};\n\n/* Rules for directories and files has moved to system/code/libcutils/fs_config.c */\n\n__BEGIN_DECLS\n\n/*\n * Used in:\n *  build/tools/fs_config/fs_config.c\n *  build/tools/fs_get_stats/fs_get_stats.c\n *  system/extras/ext4_utils/make_ext4fs_main.c\n *  external/squashfs-tools/squashfs-tools/android.c\n *  system/core/cpio/mkbootfs.c\n *  system/core/adb/file_sync_service.cpp\n *  system/extras/ext4_utils/canned_fs_config.c\n */\nvoid fs_config(const char *path, int dir, const char *target_out_path,\n               unsigned *uid, unsigned *gid, unsigned *mode, uint64_t *capabilities);\n\nssize_t fs_config_generate(char *buffer, size_t length, const struct fs_path_config *pc);\n\n__END_DECLS\n\n#endif\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/private/android_logger.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* This file is used to define the internal protocol for the Android Logger */\n\n#ifndef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_\n#define _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_\n\n/* Android private interfaces */\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <log/log.h>\n#include <log/log_read.h>\n\n#define LOGGER_MAGIC 'l'\n\n/* Header Structure to pstore */\ntypedef struct __attribute__((__packed__)) {\n    uint8_t magic;\n    uint16_t len;\n    uint16_t uid;\n    uint16_t pid;\n} android_pmsg_log_header_t;\n\n/* Header Structure to logd, and second header for pstore */\ntypedef struct __attribute__((__packed__)) {\n    typeof_log_id_t id;\n    uint16_t tid;\n    log_time realtime;\n} android_log_header_t;\n\n/* Event Header Structure to logd */\ntypedef struct __attribute__((__packed__)) {\n    int32_t tag;  // Little Endian Order\n} android_event_header_t;\n\n/* Event payload EVENT_TYPE_INT */\ntypedef struct __attribute__((__packed__)) {\n    int8_t type;  // EVENT_TYPE_INT\n    int32_t data; // Little Endian Order\n} android_event_int_t;\n\n/* Event with single EVENT_TYPE_INT */\ntypedef struct __attribute__((__packed__)) {\n    android_event_header_t header;\n    android_event_int_t payload;\n} android_log_event_int_t;\n\n/* Event payload EVENT_TYPE_LONG */\ntypedef struct __attribute__((__packed__)) {\n    int8_t type;  // EVENT_TYPE_LONG\n    int64_t data; // Little Endian Order\n} android_event_long_t;\n\n/* Event with single EVENT_TYPE_LONG */\ntypedef struct __attribute__((__packed__)) {\n    android_event_header_t header;\n    android_event_long_t payload;\n} android_log_event_long_t;\n\n/*\n * Event payload EVENT_TYPE_STRING\n *\n * Danger: do not embed this structure into another structure.\n * This structure uses a flexible array member, and when\n * compiled using g++, __builtin_object_size(data, 1) returns\n * a bad value. This is possibly a g++ bug, or a bug due to\n * the fact that flexible array members are not supported\n * in C++.\n * http://stackoverflow.com/questions/4412749/are-flexible-array-members-valid-in-c\n */\ntypedef struct __attribute__((__packed__)) {\n    int8_t type;    // EVENT_TYPE_STRING;\n    int32_t length; // Little Endian Order\n    char data[];\n} android_event_string_t;\n\n/* Event with single EVENT_TYPE_STRING */\ntypedef struct __attribute__((__packed__)) {\n    android_event_header_t header;\n    int8_t type;    // EVENT_TYPE_STRING;\n    int32_t length; // Little Endian Order\n    char data[];\n} android_log_event_string_t;\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n#define ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE 256 /* 1MB file */\n#define ANDROID_LOG_PMSG_FILE_SEQUENCE     1000\n\nssize_t __android_log_pmsg_file_write(\n        log_id_t logId,\n        char prio,\n        const char *filename,\n        const char *buf, size_t len);\n\n#define LOG_ID_ANY      ((log_id_t)-1)\n#define ANDROID_LOG_ANY ANDROID_LOG_UNKNOWN\n\n/* first 5 arguments match __android_log_msg_file_write, a cast is safe */\ntypedef ssize_t (*__android_log_pmsg_file_read_fn)(\n        log_id_t logId,\n        char prio,\n        const char *filename,\n        const char *buf, size_t len, void *arg);\n\nssize_t __android_log_pmsg_file_read(\n        log_id_t logId, char prio, const char *prefix,\n        __android_log_pmsg_file_read_fn fn, void *arg);\n\n#if defined(__cplusplus)\n}\n#endif\n\n#endif /* _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_ */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/private/canned_fs_config.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _CANNED_FS_CONFIG_H\n#define _CANNED_FS_CONFIG_H\n\n#include <inttypes.h>\n\nint load_canned_fs_config(const char* fn);\nvoid canned_fs_config(const char* path, int dir, const char* target_out_path,\n                      unsigned* uid, unsigned* gid, unsigned* mode, uint64_t* capabilities);\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/system/camera.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef SYSTEM_CORE_INCLUDE_ANDROID_CAMERA_H\n#define SYSTEM_CORE_INCLUDE_ANDROID_CAMERA_H\n\n#include <stdint.h>\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <cutils/native_handle.h>\n#include <hardware/hardware.h>\n#include <hardware/gralloc.h>\n\n__BEGIN_DECLS\n\n/**\n * A set of bit masks for specifying how the received preview frames are\n * handled before the previewCallback() call.\n *\n * The least significant 3 bits of an \"int\" value are used for this purpose:\n *\n * ..... 0 0 0\n *       ^ ^ ^\n *       | | |---------> determine whether the callback is enabled or not\n *       | |-----------> determine whether the callback is one-shot or not\n *       |-------------> determine whether the frame is copied out or not\n *\n * WARNING: When a frame is sent directly without copying, it is the frame\n * receiver's responsiblity to make sure that the frame data won't get\n * corrupted by subsequent preview frames filled by the camera. This flag is\n * recommended only when copying out data brings significant performance price\n * and the handling/processing of the received frame data is always faster than\n * the preview frame rate so that data corruption won't occur.\n *\n * For instance,\n * 1. 0x00 disables the callback. In this case, copy out and one shot bits\n *    are ignored.\n * 2. 0x01 enables a callback without copying out the received frames. A\n *    typical use case is the Camcorder application to avoid making costly\n *    frame copies.\n * 3. 0x05 is enabling a callback with frame copied out repeatedly. A typical\n *    use case is the Camera application.\n * 4. 0x07 is enabling a callback with frame copied out only once. A typical\n *    use case is the Barcode scanner application.\n */\n\nenum {\n    CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK = 0x01,\n    CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK = 0x02,\n    CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK = 0x04,\n    /** Typical use cases */\n    CAMERA_FRAME_CALLBACK_FLAG_NOOP = 0x00,\n    CAMERA_FRAME_CALLBACK_FLAG_CAMCORDER = 0x01,\n    CAMERA_FRAME_CALLBACK_FLAG_CAMERA = 0x05,\n    CAMERA_FRAME_CALLBACK_FLAG_BARCODE_SCANNER = 0x07\n};\n\n/** msgType in notifyCallback and dataCallback functions */\nenum {\n    CAMERA_MSG_ERROR = 0x0001,            // notifyCallback\n    CAMERA_MSG_SHUTTER = 0x0002,          // notifyCallback\n    CAMERA_MSG_FOCUS = 0x0004,            // notifyCallback\n    CAMERA_MSG_ZOOM = 0x0008,             // notifyCallback\n    CAMERA_MSG_PREVIEW_FRAME = 0x0010,    // dataCallback\n    CAMERA_MSG_VIDEO_FRAME = 0x0020,      // data_timestamp_callback\n    CAMERA_MSG_POSTVIEW_FRAME = 0x0040,   // dataCallback\n    CAMERA_MSG_RAW_IMAGE = 0x0080,        // dataCallback\n    CAMERA_MSG_COMPRESSED_IMAGE = 0x0100, // dataCallback\n    CAMERA_MSG_RAW_IMAGE_NOTIFY = 0x0200, // dataCallback\n    // Preview frame metadata. This can be combined with\n    // CAMERA_MSG_PREVIEW_FRAME in dataCallback. For example, the apps can\n    // request FRAME and METADATA. Or the apps can request only FRAME or only\n    // METADATA.\n    CAMERA_MSG_PREVIEW_METADATA = 0x0400, // dataCallback\n    // Notify on autofocus start and stop. This is useful in continuous\n    // autofocus - FOCUS_MODE_CONTINUOUS_VIDEO and FOCUS_MODE_CONTINUOUS_PICTURE.\n    CAMERA_MSG_FOCUS_MOVE = 0x0800,       // notifyCallback\n    CAMERA_MSG_ALL_MSGS = 0xFFFF\n};\n\n/** cmdType in sendCommand functions */\nenum {\n    CAMERA_CMD_START_SMOOTH_ZOOM = 1,\n    CAMERA_CMD_STOP_SMOOTH_ZOOM = 2,\n\n    /**\n     * Set the clockwise rotation of preview display (setPreviewDisplay) in\n     * degrees. This affects the preview frames and the picture displayed after\n     * snapshot. This method is useful for portrait mode applications. Note\n     * that preview display of front-facing cameras is flipped horizontally\n     * before the rotation, that is, the image is reflected along the central\n     * vertical axis of the camera sensor. So the users can see themselves as\n     * looking into a mirror.\n     *\n     * This does not affect the order of byte array of\n     * CAMERA_MSG_PREVIEW_FRAME, CAMERA_MSG_VIDEO_FRAME,\n     * CAMERA_MSG_POSTVIEW_FRAME, CAMERA_MSG_RAW_IMAGE, or\n     * CAMERA_MSG_COMPRESSED_IMAGE. This is allowed to be set during preview\n     * since API level 14.\n     */\n    CAMERA_CMD_SET_DISPLAY_ORIENTATION = 3,\n\n    /**\n     * cmdType to disable/enable shutter sound. In sendCommand passing arg1 =\n     * 0 will disable, while passing arg1 = 1 will enable the shutter sound.\n     */\n    CAMERA_CMD_ENABLE_SHUTTER_SOUND = 4,\n\n    /* cmdType to play recording sound */\n    CAMERA_CMD_PLAY_RECORDING_SOUND = 5,\n\n    /**\n     * Start the face detection. This should be called after preview is started.\n     * The camera will notify the listener of CAMERA_MSG_FACE and the detected\n     * faces in the preview frame. The detected faces may be the same as the\n     * previous ones. Apps should call CAMERA_CMD_STOP_FACE_DETECTION to stop\n     * the face detection. This method is supported if CameraParameters\n     * KEY_MAX_NUM_HW_DETECTED_FACES or KEY_MAX_NUM_SW_DETECTED_FACES is\n     * bigger than 0. Hardware and software face detection should not be running\n     * at the same time. If the face detection has started, apps should not send\n     * this again.\n     *\n     * In hardware face detection mode, CameraParameters KEY_WHITE_BALANCE,\n     * KEY_FOCUS_AREAS and KEY_METERING_AREAS have no effect.\n     *\n     * arg1 is the face detection type. It can be CAMERA_FACE_DETECTION_HW or\n     * CAMERA_FACE_DETECTION_SW. If the type of face detection requested is not\n     * supported, the HAL must return BAD_VALUE.\n     */\n    CAMERA_CMD_START_FACE_DETECTION = 6,\n\n    /**\n     * Stop the face detection.\n     */\n    CAMERA_CMD_STOP_FACE_DETECTION = 7,\n\n    /**\n     * Enable/disable focus move callback (CAMERA_MSG_FOCUS_MOVE). Passing\n     * arg1 = 0 will disable, while passing arg1 = 1 will enable the callback.\n     */\n    CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG = 8,\n\n    /**\n     * Ping camera service to see if camera hardware is released.\n     *\n     * When any camera method returns error, the client can use ping command\n     * to see if the camera has been taken away by other clients. If the result\n     * is NO_ERROR, it means the camera hardware is not released. If the result\n     * is not NO_ERROR, the camera has been released and the existing client\n     * can silently finish itself or show a dialog.\n     */\n    CAMERA_CMD_PING = 9,\n\n    /**\n     * Configure the number of video buffers used for recording. The intended\n     * video buffer count for recording is passed as arg1, which must be\n     * greater than 0. This command must be sent before recording is started.\n     * This command returns INVALID_OPERATION error if it is sent after video\n     * recording is started, or the command is not supported at all. This\n     * command also returns a BAD_VALUE error if the intended video buffer\n     * count is non-positive or too big to be realized.\n     */\n    CAMERA_CMD_SET_VIDEO_BUFFER_COUNT = 10,\n\n    /**\n     * Configure an explicit format to use for video recording metadata mode.\n     * This can be used to switch the format from the\n     * default IMPLEMENTATION_DEFINED gralloc format to some other\n     * device-supported format, and the default dataspace from the BT_709 color\n     * space to some other device-supported dataspace. arg1 is the HAL pixel\n     * format, and arg2 is the HAL dataSpace. This command returns\n     * INVALID_OPERATION error if it is sent after video recording is started,\n     * or the command is not supported at all.\n     *\n     * If the gralloc format is set to a format other than\n     * IMPLEMENTATION_DEFINED, then HALv3 devices will use gralloc usage flags\n     * of SW_READ_OFTEN.\n     */\n    CAMERA_CMD_SET_VIDEO_FORMAT = 11\n};\n\n/** camera fatal errors */\nenum {\n    CAMERA_ERROR_UNKNOWN = 1,\n    /**\n     * Camera was released because another client has connected to the camera.\n     * The original client should call Camera::disconnect immediately after\n     * getting this notification. Otherwise, the camera will be released by\n     * camera service in a short time. The client should not call any method\n     * (except disconnect and sending CAMERA_CMD_PING) after getting this.\n     */\n    CAMERA_ERROR_RELEASED = 2,\n    CAMERA_ERROR_SERVER_DIED = 100\n};\n\nenum {\n    /** The facing of the camera is opposite to that of the screen. */\n    CAMERA_FACING_BACK = 0,\n    /** The facing of the camera is the same as that of the screen. */\n    CAMERA_FACING_FRONT = 1,\n    /**\n     * The facing of the camera is not fixed relative to the screen.\n     * The cameras with this facing are external cameras, e.g. USB cameras.\n     */\n    CAMERA_FACING_EXTERNAL = 2\n};\n\nenum {\n    /** Hardware face detection. It does not use much CPU. */\n    CAMERA_FACE_DETECTION_HW = 0,\n    /**\n     * Software face detection. It uses some CPU. Applications must use\n     * Camera.setPreviewTexture for preview in this mode.\n     */\n    CAMERA_FACE_DETECTION_SW = 1\n};\n\n/**\n * The information of a face from camera face detection.\n */\ntypedef struct camera_face {\n    /**\n     * Bounds of the face [left, top, right, bottom]. (-1000, -1000) represents\n     * the top-left of the camera field of view, and (1000, 1000) represents the\n     * bottom-right of the field of view. The width and height cannot be 0 or\n     * negative. This is supported by both hardware and software face detection.\n     *\n     * The direction is relative to the sensor orientation, that is, what the\n     * sensor sees. The direction is not affected by the rotation or mirroring\n     * of CAMERA_CMD_SET_DISPLAY_ORIENTATION.\n     */\n    int32_t rect[4];\n\n    /**\n     * The confidence level of the face. The range is 1 to 100. 100 is the\n     * highest confidence. This is supported by both hardware and software\n     * face detection.\n     */\n    int32_t score;\n\n    /**\n     * An unique id per face while the face is visible to the tracker. If\n     * the face leaves the field-of-view and comes back, it will get a new\n     * id. If the value is 0, id is not supported.\n     */\n    int32_t id;\n\n    /**\n     * The coordinates of the center of the left eye. The range is -1000 to\n     * 1000. -2000, -2000 if this is not supported.\n     */\n    int32_t left_eye[2];\n\n    /**\n     * The coordinates of the center of the right eye. The range is -1000 to\n     * 1000. -2000, -2000 if this is not supported.\n     */\n    int32_t right_eye[2];\n\n    /**\n     * The coordinates of the center of the mouth. The range is -1000 to 1000.\n     * -2000, -2000 if this is not supported.\n     */\n    int32_t mouth[2];\n\n} camera_face_t;\n\n/**\n * The metadata of the frame data.\n */\ntypedef struct camera_frame_metadata {\n    /**\n     * The number of detected faces in the frame.\n     */\n    int32_t number_of_faces;\n\n    /**\n     * An array of the detected faces. The length is number_of_faces.\n     */\n    camera_face_t *faces;\n} camera_frame_metadata_t;\n\n__END_DECLS\n\n#endif /* SYSTEM_CORE_INCLUDE_ANDROID_CAMERA_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/system/graphics.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef SYSTEM_CORE_INCLUDE_ANDROID_GRAPHICS_H\n#define SYSTEM_CORE_INCLUDE_ANDROID_GRAPHICS_H\n\n#include <stddef.h>\n#include <stdint.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n * If the HAL needs to create service threads to handle graphics related\n * tasks, these threads need to run at HAL_PRIORITY_URGENT_DISPLAY priority\n * if they can block the main rendering thread in any way.\n *\n * the priority of the current thread can be set with:\n *\n *      #include <sys/resource.h>\n *      setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);\n *\n */\n\n#define HAL_PRIORITY_URGENT_DISPLAY     (-8)\n\n/**\n * pixel format definitions\n */\n\ntypedef enum android_pixel_format {\n    /*\n     * \"linear\" color pixel formats:\n     *\n     * When used with ANativeWindow, the dataSpace field describes the color\n     * space of the buffer.\n     *\n     * The color space determines, for example, if the formats are linear or\n     * gamma-corrected; or whether any special operations are performed when\n     * reading or writing into a buffer in one of these formats.\n     */\n    HAL_PIXEL_FORMAT_RGBA_8888          = 1,\n    HAL_PIXEL_FORMAT_RGBX_8888          = 2,\n    HAL_PIXEL_FORMAT_RGB_888            = 3,\n    HAL_PIXEL_FORMAT_RGB_565            = 4,\n    HAL_PIXEL_FORMAT_BGRA_8888          = 5,\n\n    /*\n     * 0x100 - 0x1FF\n     *\n     * This range is reserved for pixel formats that are specific to the HAL\n     * implementation.  Implementations can use any value in this range to\n     * communicate video pixel formats between their HAL modules.  These formats\n     * must not have an alpha channel.  Additionally, an EGLimage created from a\n     * gralloc buffer of one of these formats must be supported for use with the\n     * GL_OES_EGL_image_external OpenGL ES extension.\n     */\n\n    /*\n     * Android YUV format:\n     *\n     * This format is exposed outside of the HAL to software decoders and\n     * applications.  EGLImageKHR must support it in conjunction with the\n     * OES_EGL_image_external extension.\n     *\n     * YV12 is a 4:2:0 YCrCb planar format comprised of a WxH Y plane followed\n     * by (W/2) x (H/2) Cr and Cb planes.\n     *\n     * This format assumes\n     * - an even width\n     * - an even height\n     * - a horizontal stride multiple of 16 pixels\n     * - a vertical stride equal to the height\n     *\n     *   y_size = stride * height\n     *   c_stride = ALIGN(stride/2, 16)\n     *   c_size = c_stride * height/2\n     *   size = y_size + c_size * 2\n     *   cr_offset = y_size\n     *   cb_offset = y_size + c_size\n     *\n     * When used with ANativeWindow, the dataSpace field describes the color\n     * space of the buffer.\n     */\n    HAL_PIXEL_FORMAT_YV12   = 0x32315659, // YCrCb 4:2:0 Planar\n\n\n    /*\n     * Android Y8 format:\n     *\n     * This format is exposed outside of the HAL to the framework.\n     * The expected gralloc usage flags are SW_* and HW_CAMERA_*,\n     * and no other HW_ flags will be used.\n     *\n     * Y8 is a YUV planar format comprised of a WxH Y plane,\n     * with each pixel being represented by 8 bits.\n     *\n     * It is equivalent to just the Y plane from YV12.\n     *\n     * This format assumes\n     * - an even width\n     * - an even height\n     * - a horizontal stride multiple of 16 pixels\n     * - a vertical stride equal to the height\n     *\n     *   size = stride * height\n     *\n     * When used with ANativeWindow, the dataSpace field describes the color\n     * space of the buffer.\n     */\n    HAL_PIXEL_FORMAT_Y8     = 0x20203859,\n\n    /*\n     * Android Y16 format:\n     *\n     * This format is exposed outside of the HAL to the framework.\n     * The expected gralloc usage flags are SW_* and HW_CAMERA_*,\n     * and no other HW_ flags will be used.\n     *\n     * Y16 is a YUV planar format comprised of a WxH Y plane,\n     * with each pixel being represented by 16 bits.\n     *\n     * It is just like Y8, but has double the bits per pixel (little endian).\n     *\n     * This format assumes\n     * - an even width\n     * - an even height\n     * - a horizontal stride multiple of 16 pixels\n     * - a vertical stride equal to the height\n     * - strides are specified in pixels, not in bytes\n     *\n     *   size = stride * height * 2\n     *\n     * When used with ANativeWindow, the dataSpace field describes the color\n     * space of the buffer, except that dataSpace field\n     * HAL_DATASPACE_DEPTH indicates that this buffer contains a depth\n     * image where each sample is a distance value measured by a depth camera,\n     * plus an associated confidence value.\n     */\n    HAL_PIXEL_FORMAT_Y16    = 0x20363159,\n\n    /*\n     * Android RAW sensor format:\n     *\n     * This format is exposed outside of the camera HAL to applications.\n     *\n     * RAW16 is a single-channel, 16-bit, little endian format, typically\n     * representing raw Bayer-pattern images from an image sensor, with minimal\n     * processing.\n     *\n     * The exact pixel layout of the data in the buffer is sensor-dependent, and\n     * needs to be queried from the camera device.\n     *\n     * Generally, not all 16 bits are used; more common values are 10 or 12\n     * bits. If not all bits are used, the lower-order bits are filled first.\n     * All parameters to interpret the raw data (black and white points,\n     * color space, etc) must be queried from the camera device.\n     *\n     * This format assumes\n     * - an even width\n     * - an even height\n     * - a horizontal stride multiple of 16 pixels\n     * - a vertical stride equal to the height\n     * - strides are specified in pixels, not in bytes\n     *\n     *   size = stride * height * 2\n     *\n     * This format must be accepted by the gralloc module when used with the\n     * following usage flags:\n     *    - GRALLOC_USAGE_HW_CAMERA_*\n     *    - GRALLOC_USAGE_SW_*\n     *    - GRALLOC_USAGE_RENDERSCRIPT\n     *\n     * When used with ANativeWindow, the dataSpace should be\n     * HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial\n     * extra metadata to define.\n     */\n    HAL_PIXEL_FORMAT_RAW16 = 0x20,\n\n    /*\n     * Android RAW10 format:\n     *\n     * This format is exposed outside of the camera HAL to applications.\n     *\n     * RAW10 is a single-channel, 10-bit per pixel, densely packed in each row,\n     * unprocessed format, usually representing raw Bayer-pattern images coming from\n     * an image sensor.\n     *\n     * In an image buffer with this format, starting from the first pixel of each\n     * row, each 4 consecutive pixels are packed into 5 bytes (40 bits). Each one\n     * of the first 4 bytes contains the top 8 bits of each pixel, The fifth byte\n     * contains the 2 least significant bits of the 4 pixels, the exact layout data\n     * for each 4 consecutive pixels is illustrated below (Pi[j] stands for the jth\n     * bit of the ith pixel):\n     *\n     *          bit 7                                     bit 0\n     *          =====|=====|=====|=====|=====|=====|=====|=====|\n     * Byte 0: |P0[9]|P0[8]|P0[7]|P0[6]|P0[5]|P0[4]|P0[3]|P0[2]|\n     *         |-----|-----|-----|-----|-----|-----|-----|-----|\n     * Byte 1: |P1[9]|P1[8]|P1[7]|P1[6]|P1[5]|P1[4]|P1[3]|P1[2]|\n     *         |-----|-----|-----|-----|-----|-----|-----|-----|\n     * Byte 2: |P2[9]|P2[8]|P2[7]|P2[6]|P2[5]|P2[4]|P2[3]|P2[2]|\n     *         |-----|-----|-----|-----|-----|-----|-----|-----|\n     * Byte 3: |P3[9]|P3[8]|P3[7]|P3[6]|P3[5]|P3[4]|P3[3]|P3[2]|\n     *         |-----|-----|-----|-----|-----|-----|-----|-----|\n     * Byte 4: |P3[1]|P3[0]|P2[1]|P2[0]|P1[1]|P1[0]|P0[1]|P0[0]|\n     *          ===============================================\n     *\n     * This format assumes\n     * - a width multiple of 4 pixels\n     * - an even height\n     * - a vertical stride equal to the height\n     * - strides are specified in bytes, not in pixels\n     *\n     *   size = stride * height\n     *\n     * When stride is equal to width * (10 / 8), there will be no padding bytes at\n     * the end of each row, the entire image data is densely packed. When stride is\n     * larger than width * (10 / 8), padding bytes will be present at the end of each\n     * row (including the last row).\n     *\n     * This format must be accepted by the gralloc module when used with the\n     * following usage flags:\n     *    - GRALLOC_USAGE_HW_CAMERA_*\n     *    - GRALLOC_USAGE_SW_*\n     *    - GRALLOC_USAGE_RENDERSCRIPT\n     *\n     * When used with ANativeWindow, the dataSpace field should be\n     * HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial\n     * extra metadata to define.\n     */\n    HAL_PIXEL_FORMAT_RAW10 = 0x25,\n\n    /*\n     * Android RAW12 format:\n     *\n     * This format is exposed outside of camera HAL to applications.\n     *\n     * RAW12 is a single-channel, 12-bit per pixel, densely packed in each row,\n     * unprocessed format, usually representing raw Bayer-pattern images coming from\n     * an image sensor.\n     *\n     * In an image buffer with this format, starting from the first pixel of each\n     * row, each two consecutive pixels are packed into 3 bytes (24 bits). The first\n     * and second byte contains the top 8 bits of first and second pixel. The third\n     * byte contains the 4 least significant bits of the two pixels, the exact layout\n     * data for each two consecutive pixels is illustrated below (Pi[j] stands for\n     * the jth bit of the ith pixel):\n     *\n     *           bit 7                                            bit 0\n     *          ======|======|======|======|======|======|======|======|\n     * Byte 0: |P0[11]|P0[10]|P0[ 9]|P0[ 8]|P0[ 7]|P0[ 6]|P0[ 5]|P0[ 4]|\n     *         |------|------|------|------|------|------|------|------|\n     * Byte 1: |P1[11]|P1[10]|P1[ 9]|P1[ 8]|P1[ 7]|P1[ 6]|P1[ 5]|P1[ 4]|\n     *         |------|------|------|------|------|------|------|------|\n     * Byte 2: |P1[ 3]|P1[ 2]|P1[ 1]|P1[ 0]|P0[ 3]|P0[ 2]|P0[ 1]|P0[ 0]|\n     *          =======================================================\n     *\n     * This format assumes:\n     * - a width multiple of 4 pixels\n     * - an even height\n     * - a vertical stride equal to the height\n     * - strides are specified in bytes, not in pixels\n     *\n     *   size = stride * height\n     *\n     * When stride is equal to width * (12 / 8), there will be no padding bytes at\n     * the end of each row, the entire image data is densely packed. When stride is\n     * larger than width * (12 / 8), padding bytes will be present at the end of\n     * each row (including the last row).\n     *\n     * This format must be accepted by the gralloc module when used with the\n     * following usage flags:\n     *    - GRALLOC_USAGE_HW_CAMERA_*\n     *    - GRALLOC_USAGE_SW_*\n     *    - GRALLOC_USAGE_RENDERSCRIPT\n     *\n     * When used with ANativeWindow, the dataSpace field should be\n     * HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial\n     * extra metadata to define.\n     */\n    HAL_PIXEL_FORMAT_RAW12 = 0x26,\n\n    /*\n     * Android opaque RAW format:\n     *\n     * This format is exposed outside of the camera HAL to applications.\n     *\n     * RAW_OPAQUE is a format for unprocessed raw image buffers coming from an\n     * image sensor. The actual structure of buffers of this format is\n     * implementation-dependent.\n     *\n     * This format must be accepted by the gralloc module when used with the\n     * following usage flags:\n     *    - GRALLOC_USAGE_HW_CAMERA_*\n     *    - GRALLOC_USAGE_SW_*\n     *    - GRALLOC_USAGE_RENDERSCRIPT\n     *\n     * When used with ANativeWindow, the dataSpace field should be\n     * HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial\n     * extra metadata to define.\n     */\n    HAL_PIXEL_FORMAT_RAW_OPAQUE = 0x24,\n\n    /*\n     * Android binary blob graphics buffer format:\n     *\n     * This format is used to carry task-specific data which does not have a\n     * standard image structure. The details of the format are left to the two\n     * endpoints.\n     *\n     * A typical use case is for transporting JPEG-compressed images from the\n     * Camera HAL to the framework or to applications.\n     *\n     * Buffers of this format must have a height of 1, and width equal to their\n     * size in bytes.\n     *\n     * When used with ANativeWindow, the mapping of the dataSpace field to\n     * buffer contents for BLOB is as follows:\n     *\n     *  dataSpace value               | Buffer contents\n     * -------------------------------+-----------------------------------------\n     *  HAL_DATASPACE_JFIF            | An encoded JPEG image\n     *  HAL_DATASPACE_DEPTH           | An android_depth_points buffer\n     *  Other                         | Unsupported\n     *\n     */\n    HAL_PIXEL_FORMAT_BLOB = 0x21,\n\n    /*\n     * Android format indicating that the choice of format is entirely up to the\n     * device-specific Gralloc implementation.\n     *\n     * The Gralloc implementation should examine the usage bits passed in when\n     * allocating a buffer with this format, and it should derive the pixel\n     * format from those usage flags.  This format will never be used with any\n     * of the GRALLOC_USAGE_SW_* usage flags.\n     *\n     * If a buffer of this format is to be used as an OpenGL ES texture, the\n     * framework will assume that sampling the texture will always return an\n     * alpha value of 1.0 (i.e. the buffer contains only opaque pixel values).\n     *\n     * When used with ANativeWindow, the dataSpace field describes the color\n     * space of the buffer.\n     */\n    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 0x22,\n\n    /*\n     * Android flexible YCbCr 4:2:0 formats\n     *\n     * This format allows platforms to use an efficient YCbCr/YCrCb 4:2:0\n     * buffer layout, while still describing the general format in a\n     * layout-independent manner.  While called YCbCr, it can be\n     * used to describe formats with either chromatic ordering, as well as\n     * whole planar or semiplanar layouts.\n     *\n     * struct android_ycbcr (below) is the the struct used to describe it.\n     *\n     * This format must be accepted by the gralloc module when\n     * USAGE_SW_WRITE_* or USAGE_SW_READ_* are set.\n     *\n     * This format is locked for use by gralloc's (*lock_ycbcr) method, and\n     * locking with the (*lock) method will return an error.\n     *\n     * When used with ANativeWindow, the dataSpace field describes the color\n     * space of the buffer.\n     */\n    HAL_PIXEL_FORMAT_YCbCr_420_888 = 0x23,\n\n    /*\n     * Android flexible YCbCr 4:2:2 formats\n     *\n     * This format allows platforms to use an efficient YCbCr/YCrCb 4:2:2\n     * buffer layout, while still describing the general format in a\n     * layout-independent manner.  While called YCbCr, it can be\n     * used to describe formats with either chromatic ordering, as well as\n     * whole planar or semiplanar layouts.\n     *\n     * This format is currently only used by SW readable buffers\n     * produced by MediaCodecs, so the gralloc module can ignore this format.\n     */\n    HAL_PIXEL_FORMAT_YCbCr_422_888 = 0x27,\n\n    /*\n     * Android flexible YCbCr 4:4:4 formats\n     *\n     * This format allows platforms to use an efficient YCbCr/YCrCb 4:4:4\n     * buffer layout, while still describing the general format in a\n     * layout-independent manner.  While called YCbCr, it can be\n     * used to describe formats with either chromatic ordering, as well as\n     * whole planar or semiplanar layouts.\n     *\n     * This format is currently only used by SW readable buffers\n     * produced by MediaCodecs, so the gralloc module can ignore this format.\n     */\n    HAL_PIXEL_FORMAT_YCbCr_444_888 = 0x28,\n\n    /*\n     * Android flexible RGB 888 formats\n     *\n     * This format allows platforms to use an efficient RGB/BGR/RGBX/BGRX\n     * buffer layout, while still describing the general format in a\n     * layout-independent manner.  While called RGB, it can be\n     * used to describe formats with either color ordering and optional\n     * padding, as well as whole planar layout.\n     *\n     * This format is currently only used by SW readable buffers\n     * produced by MediaCodecs, so the gralloc module can ignore this format.\n     */\n    HAL_PIXEL_FORMAT_FLEX_RGB_888 = 0x29,\n\n    /*\n     * Android flexible RGBA 8888 formats\n     *\n     * This format allows platforms to use an efficient RGBA/BGRA/ARGB/ABGR\n     * buffer layout, while still describing the general format in a\n     * layout-independent manner.  While called RGBA, it can be\n     * used to describe formats with any of the component orderings, as\n     * well as whole planar layout.\n     *\n     * This format is currently only used by SW readable buffers\n     * produced by MediaCodecs, so the gralloc module can ignore this format.\n     */\n    HAL_PIXEL_FORMAT_FLEX_RGBA_8888 = 0x2A,\n\n    /* Legacy formats (deprecated), used by ImageFormat.java */\n    HAL_PIXEL_FORMAT_YCbCr_422_SP       = 0x10, // NV16\n    HAL_PIXEL_FORMAT_YCrCb_420_SP       = 0x11, // NV21\n    HAL_PIXEL_FORMAT_YCbCr_422_I        = 0x14, // YUY2\n} android_pixel_format_t;\n\n/*\n * Structure for describing YCbCr formats for consumption by applications.\n * This is used with HAL_PIXEL_FORMAT_YCbCr_*_888.\n *\n * Buffer chroma subsampling is defined in the format.\n * e.g. HAL_PIXEL_FORMAT_YCbCr_420_888 has subsampling 4:2:0.\n *\n * Buffers must have a 8 bit depth.\n *\n * @y, @cb, and @cr point to the first byte of their respective planes.\n *\n * Stride describes the distance in bytes from the first value of one row of\n * the image to the first value of the next row.  It includes the width of the\n * image plus padding.\n * @ystride is the stride of the luma plane.\n * @cstride is the stride of the chroma planes.\n *\n * @chroma_step is the distance in bytes from one chroma pixel value to the\n * next.  This is 2 bytes for semiplanar (because chroma values are interleaved\n * and each chroma value is one byte) and 1 for planar.\n */\n\nstruct android_ycbcr {\n    void *y;\n    void *cb;\n    void *cr;\n    size_t ystride;\n    size_t cstride;\n    size_t chroma_step;\n\n    /** reserved for future use, set to 0 by gralloc's (*lock_ycbcr)() */\n    uint32_t reserved[8];\n};\n\n/**\n * Structure used to define depth point clouds for format HAL_PIXEL_FORMAT_BLOB\n * with dataSpace value of HAL_DATASPACE_DEPTH.\n * When locking a native buffer of the above format and dataSpace value,\n * the vaddr pointer can be cast to this structure.\n *\n * A variable-length list of (x,y,z, confidence) 3D points, as floats.  (x, y,\n * z) represents a measured point's position, with the coordinate system defined\n * by the data source.  Confidence represents the estimated likelihood that this\n * measurement is correct. It is between 0.f and 1.f, inclusive, with 1.f ==\n * 100% confidence.\n *\n * @num_points is the number of points in the list\n *\n * @xyz_points is the flexible array of floating-point values.\n *   It contains (num_points) * 4 floats.\n *\n *   For example:\n *     android_depth_points d = get_depth_buffer();\n *     struct {\n *       float x; float y; float z; float confidence;\n *     } firstPoint, lastPoint;\n *\n *     firstPoint.x = d.xyzc_points[0];\n *     firstPoint.y = d.xyzc_points[1];\n *     firstPoint.z = d.xyzc_points[2];\n *     firstPoint.confidence = d.xyzc_points[3];\n *     lastPoint.x = d.xyzc_points[(d.num_points - 1) * 4 + 0];\n *     lastPoint.y = d.xyzc_points[(d.num_points - 1) * 4 + 1];\n *     lastPoint.z = d.xyzc_points[(d.num_points - 1) * 4 + 2];\n *     lastPoint.confidence = d.xyzc_points[(d.num_points - 1) * 4 + 3];\n */\n\nstruct android_depth_points {\n    uint32_t num_points;\n\n    /** reserved for future use, set to 0 by gralloc's (*lock)() */\n    uint32_t reserved[8];\n\n    float xyzc_points[];\n};\n\n/**\n * Transformation definitions\n *\n * IMPORTANT NOTE:\n * HAL_TRANSFORM_ROT_90 is applied CLOCKWISE and AFTER HAL_TRANSFORM_FLIP_{H|V}.\n *\n */\n\ntypedef enum android_transform {\n    /* flip source image horizontally (around the vertical axis) */\n    HAL_TRANSFORM_FLIP_H    = 0x01,\n    /* flip source image vertically (around the horizontal axis)*/\n    HAL_TRANSFORM_FLIP_V    = 0x02,\n    /* rotate source image 90 degrees clockwise */\n    HAL_TRANSFORM_ROT_90    = 0x04,\n    /* rotate source image 180 degrees */\n    HAL_TRANSFORM_ROT_180   = 0x03,\n    /* rotate source image 270 degrees clockwise */\n    HAL_TRANSFORM_ROT_270   = 0x07,\n    /* don't use. see system/window.h */\n    HAL_TRANSFORM_RESERVED  = 0x08,\n} android_transform_t;\n\n/**\n * Dataspace Definitions\n * ======================\n *\n * Dataspace is the definition of how pixel values should be interpreted.\n *\n * For many formats, this is the colorspace of the image data, which includes\n * primaries (including white point) and the transfer characteristic function,\n * which describes both gamma curve and numeric range (within the bit depth).\n *\n * Other dataspaces include depth measurement data from a depth camera.\n *\n * A dataspace is comprised of a number of fields.\n *\n * Version\n * --------\n * The top 2 bits represent the revision of the field specification. This is\n * currently always 0.\n *\n *\n * bits    31-30 29                      -                          0\n *        +-----+----------------------------------------------------+\n * fields | Rev |            Revision specific fields                |\n *        +-----+----------------------------------------------------+\n *\n * Field layout for version = 0:\n * ----------------------------\n *\n * A dataspace is comprised of the following fields:\n *      Standard\n *      Transfer function\n *      Range\n *\n * bits    31-30 29-27 26 -  22 21 -  16 15             -           0\n *        +-----+-----+--------+--------+----------------------------+\n * fields |  0  |Range|Transfer|Standard|    Legacy and custom       |\n *        +-----+-----+--------+--------+----------------------------+\n *          VV    RRR   TTTTT    SSSSSS    LLLLLLLL       LLLLLLLL\n *\n * If range, transfer and standard fields are all 0 (e.g. top 16 bits are\n * all zeroes), the bottom 16 bits contain either a legacy dataspace value,\n * or a custom value.\n */\n\ntypedef enum android_dataspace {\n    /*\n     * Default-assumption data space, when not explicitly specified.\n     *\n     * It is safest to assume the buffer is an image with sRGB primaries and\n     * encoding ranges, but the consumer and/or the producer of the data may\n     * simply be using defaults. No automatic gamma transform should be\n     * expected, except for a possible display gamma transform when drawn to a\n     * screen.\n     */\n    HAL_DATASPACE_UNKNOWN = 0x0,\n\n    /*\n     * Arbitrary dataspace with manually defined characteristics.  Definition\n     * for colorspaces or other meaning must be communicated separately.\n     *\n     * This is used when specifying primaries, transfer characteristics,\n     * etc. separately.\n     *\n     * A typical use case is in video encoding parameters (e.g. for H.264),\n     * where a colorspace can have separately defined primaries, transfer\n     * characteristics, etc.\n     */\n    HAL_DATASPACE_ARBITRARY = 0x1,\n\n    /*\n     * Color-description aspects\n     *\n     * The following aspects define various characteristics of the color\n     * specification. These represent bitfields, so that a data space value\n     * can specify each of them independently.\n     */\n\n    HAL_DATASPACE_STANDARD_SHIFT = 16,\n\n    /*\n     * Standard aspect\n     *\n     * Defines the chromaticity coordinates of the source primaries in terms of\n     * the CIE 1931 definition of x and y specified in ISO 11664-1.\n     */\n    HAL_DATASPACE_STANDARD_MASK = 63 << HAL_DATASPACE_STANDARD_SHIFT,  // 0x3F\n\n    /*\n     * Chromacity coordinates are unknown or are determined by the application.\n     * Implementations shall use the following suggested standards:\n     *\n     * All YCbCr formats: BT709 if size is 720p or larger (since most video\n     *                    content is letterboxed this corresponds to width is\n     *                    1280 or greater, or height is 720 or greater).\n     *                    BT601_625 if size is smaller than 720p or is JPEG.\n     * All RGB formats:   BT709.\n     *\n     * For all other formats standard is undefined, and implementations should use\n     * an appropriate standard for the data represented.\n     */\n    HAL_DATASPACE_STANDARD_UNSPECIFIED = 0 << HAL_DATASPACE_STANDARD_SHIFT,\n\n    /*\n     * Primaries:       x       y\n     *  green           0.300   0.600\n     *  blue            0.150   0.060\n     *  red             0.640   0.330\n     *  white (D65)     0.3127  0.3290\n     *\n     * Use the unadjusted KR = 0.2126, KB = 0.0722 luminance interpretation\n     * for RGB conversion.\n     */\n    HAL_DATASPACE_STANDARD_BT709 = 1 << HAL_DATASPACE_STANDARD_SHIFT,\n\n    /*\n     * Primaries:       x       y\n     *  green           0.290   0.600\n     *  blue            0.150   0.060\n     *  red             0.640   0.330\n     *  white (D65)     0.3127  0.3290\n     *\n     *  KR = 0.299, KB = 0.114. This adjusts the luminance interpretation\n     *  for RGB conversion from the one purely determined by the primaries\n     *  to minimize the color shift into RGB space that uses BT.709\n     *  primaries.\n     */\n    HAL_DATASPACE_STANDARD_BT601_625 = 2 << HAL_DATASPACE_STANDARD_SHIFT,\n\n    /*\n     * Primaries:       x       y\n     *  green           0.290   0.600\n     *  blue            0.150   0.060\n     *  red             0.640   0.330\n     *  white (D65)     0.3127  0.3290\n     *\n     * Use the unadjusted KR = 0.222, KB = 0.071 luminance interpretation\n     * for RGB conversion.\n     */\n    HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED = 3 << HAL_DATASPACE_STANDARD_SHIFT,\n\n    /*\n     * Primaries:       x       y\n     *  green           0.310   0.595\n     *  blue            0.155   0.070\n     *  red             0.630   0.340\n     *  white (D65)     0.3127  0.3290\n     *\n     *  KR = 0.299, KB = 0.114. This adjusts the luminance interpretation\n     *  for RGB conversion from the one purely determined by the primaries\n     *  to minimize the color shift into RGB space that uses BT.709\n     *  primaries.\n     */\n    HAL_DATASPACE_STANDARD_BT601_525 = 4 << HAL_DATASPACE_STANDARD_SHIFT,\n\n    /*\n     * Primaries:       x       y\n     *  green           0.310   0.595\n     *  blue            0.155   0.070\n     *  red             0.630   0.340\n     *  white (D65)     0.3127  0.3290\n     *\n     * Use the unadjusted KR = 0.212, KB = 0.087 luminance interpretation\n     * for RGB conversion (as in SMPTE 240M).\n     */\n    HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED = 5 << HAL_DATASPACE_STANDARD_SHIFT,\n\n    /*\n     * Primaries:       x       y\n     *  green           0.170   0.797\n     *  blue            0.131   0.046\n     *  red             0.708   0.292\n     *  white (D65)     0.3127  0.3290\n     *\n     * Use the unadjusted KR = 0.2627, KB = 0.0593 luminance interpretation\n     * for RGB conversion.\n     */\n    HAL_DATASPACE_STANDARD_BT2020 = 6 << HAL_DATASPACE_STANDARD_SHIFT,\n\n    /*\n     * Primaries:       x       y\n     *  green           0.170   0.797\n     *  blue            0.131   0.046\n     *  red             0.708   0.292\n     *  white (D65)     0.3127  0.3290\n     *\n     * Use the unadjusted KR = 0.2627, KB = 0.0593 luminance interpretation\n     * for RGB conversion using the linear domain.\n     */\n    HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE = 7 << HAL_DATASPACE_STANDARD_SHIFT,\n\n    /*\n     * Primaries:       x      y\n     *  green           0.21   0.71\n     *  blue            0.14   0.08\n     *  red             0.67   0.33\n     *  white (C)       0.310  0.316\n     *\n     * Use the unadjusted KR = 0.30, KB = 0.11 luminance interpretation\n     * for RGB conversion.\n     */\n    HAL_DATASPACE_STANDARD_BT470M = 8 << HAL_DATASPACE_STANDARD_SHIFT,\n\n    /*\n     * Primaries:       x       y\n     *  green           0.243   0.692\n     *  blue            0.145   0.049\n     *  red             0.681   0.319\n     *  white (C)       0.310   0.316\n     *\n     * Use the unadjusted KR = 0.254, KB = 0.068 luminance interpretation\n     * for RGB conversion.\n     */\n    HAL_DATASPACE_STANDARD_FILM = 9 << HAL_DATASPACE_STANDARD_SHIFT,\n\n    HAL_DATASPACE_TRANSFER_SHIFT = 22,\n\n    /*\n     * Transfer aspect\n     *\n     * Transfer characteristics are the opto-electronic transfer characteristic\n     * at the source as a function of linear optical intensity (luminance).\n     *\n     * For digital signals, E corresponds to the recorded value. Normally, the\n     * transfer function is applied in RGB space to each of the R, G and B\n     * components independently. This may result in color shift that can be\n     * minized by applying the transfer function in Lab space only for the L\n     * component. Implementation may apply the transfer function in RGB space\n     * for all pixel formats if desired.\n     */\n\n    HAL_DATASPACE_TRANSFER_MASK = 31 << HAL_DATASPACE_TRANSFER_SHIFT,  // 0x1F\n\n    /*\n     * Transfer characteristics are unknown or are determined by the\n     * application.\n     *\n     * Implementations should use the following transfer functions:\n     *\n     * For YCbCr formats: use HAL_DATASPACE_TRANSFER_SMPTE_170M\n     * For RGB formats: use HAL_DATASPACE_TRANSFER_SRGB\n     *\n     * For all other formats transfer function is undefined, and implementations\n     * should use an appropriate standard for the data represented.\n     */\n    HAL_DATASPACE_TRANSFER_UNSPECIFIED = 0 << HAL_DATASPACE_TRANSFER_SHIFT,\n\n    /*\n     * Transfer characteristic curve:\n     *  E = L\n     *      L - luminance of image 0 <= L <= 1 for conventional colorimetry\n     *      E - corresponding electrical signal\n     */\n    HAL_DATASPACE_TRANSFER_LINEAR = 1 << HAL_DATASPACE_TRANSFER_SHIFT,\n\n    /*\n     * Transfer characteristic curve:\n     *\n     * E = 1.055 * L^(1/2.4) - 0.055  for 0.0031308 <= L <= 1\n     *   = 12.92 * L                  for 0 <= L < 0.0031308\n     *     L - luminance of image 0 <= L <= 1 for conventional colorimetry\n     *     E - corresponding electrical signal\n     */\n    HAL_DATASPACE_TRANSFER_SRGB = 2 << HAL_DATASPACE_TRANSFER_SHIFT,\n\n    /*\n     * BT.601 525, BT.601 625, BT.709, BT.2020\n     *\n     * Transfer characteristic curve:\n     *  E = 1.099 * L ^ 0.45 - 0.099  for 0.018 <= L <= 1\n     *    = 4.500 * L                 for 0 <= L < 0.018\n     *      L - luminance of image 0 <= L <= 1 for conventional colorimetry\n     *      E - corresponding electrical signal\n     */\n    HAL_DATASPACE_TRANSFER_SMPTE_170M = 3 << HAL_DATASPACE_TRANSFER_SHIFT,\n\n    /*\n     * Assumed display gamma 2.2.\n     *\n     * Transfer characteristic curve:\n     *  E = L ^ (1/2.2)\n     *      L - luminance of image 0 <= L <= 1 for conventional colorimetry\n     *      E - corresponding electrical signal\n     */\n    HAL_DATASPACE_TRANSFER_GAMMA2_2 = 4 << HAL_DATASPACE_TRANSFER_SHIFT,\n\n    /*\n     *  display gamma 2.8.\n     *\n     * Transfer characteristic curve:\n     *  E = L ^ (1/2.8)\n     *      L - luminance of image 0 <= L <= 1 for conventional colorimetry\n     *      E - corresponding electrical signal\n     */\n    HAL_DATASPACE_TRANSFER_GAMMA2_8 = 5 << HAL_DATASPACE_TRANSFER_SHIFT,\n\n    /*\n     * SMPTE ST 2084\n     *\n     * Transfer characteristic curve:\n     *  E = ((c1 + c2 * L^n) / (1 + c3 * L^n)) ^ m\n     *  c1 = c3 - c2 + 1 = 3424 / 4096 = 0.8359375\n     *  c2 = 32 * 2413 / 4096 = 18.8515625\n     *  c3 = 32 * 2392 / 4096 = 18.6875\n     *  m = 128 * 2523 / 4096 = 78.84375\n     *  n = 0.25 * 2610 / 4096 = 0.1593017578125\n     *      L - luminance of image 0 <= L <= 1 for HDR colorimetry.\n     *          L = 1 corresponds to 10000 cd/m2\n     *      E - corresponding electrical signal\n     */\n    HAL_DATASPACE_TRANSFER_ST2084 = 6 << HAL_DATASPACE_TRANSFER_SHIFT,\n\n    /*\n     * ARIB STD-B67 Hybrid Log Gamma\n     *\n     * Transfer characteristic curve:\n     *  E = r * L^0.5                 for 0 <= L <= 1\n     *    = a * ln(L - b) + c         for 1 < L\n     *  a = 0.17883277\n     *  b = 0.28466892\n     *  c = 0.55991073\n     *  r = 0.5\n     *      L - luminance of image 0 <= L for HDR colorimetry. L = 1 corresponds\n     *          to reference white level of 100 cd/m2\n     *      E - corresponding electrical signal\n     */\n    HAL_DATASPACE_TRANSFER_HLG = 7 << HAL_DATASPACE_TRANSFER_SHIFT,\n\n    HAL_DATASPACE_RANGE_SHIFT = 27,\n\n    /*\n     * Range aspect\n     *\n     * Defines the range of values corresponding to the unit range of 0-1.\n     * This is defined for YCbCr only, but can be expanded to RGB space.\n     */\n    HAL_DATASPACE_RANGE_MASK = 7 << HAL_DATASPACE_RANGE_SHIFT,  // 0x7\n\n    /*\n     * Range is unknown or are determined by the application.  Implementations\n     * shall use the following suggested ranges:\n     *\n     * All YCbCr formats: limited range.\n     * All RGB or RGBA formats (including RAW and Bayer): full range.\n     * All Y formats: full range\n     *\n     * For all other formats range is undefined, and implementations should use\n     * an appropriate range for the data represented.\n     */\n    HAL_DATASPACE_RANGE_UNSPECIFIED = 0 << HAL_DATASPACE_RANGE_SHIFT,\n\n    /*\n     * Full range uses all values for Y, Cb and Cr from\n     * 0 to 2^b-1, where b is the bit depth of the color format.\n     */\n    HAL_DATASPACE_RANGE_FULL = 1 << HAL_DATASPACE_RANGE_SHIFT,\n\n    /*\n     * Limited range uses values 16/256*2^b to 235/256*2^b for Y, and\n     * 1/16*2^b to 15/16*2^b for Cb, Cr, R, G and B, where b is the bit depth of\n     * the color format.\n     *\n     * E.g. For 8-bit-depth formats:\n     * Luma (Y) samples should range from 16 to 235, inclusive\n     * Chroma (Cb, Cr) samples should range from 16 to 240, inclusive\n     *\n     * For 10-bit-depth formats:\n     * Luma (Y) samples should range from 64 to 940, inclusive\n     * Chroma (Cb, Cr) samples should range from 64 to 960, inclusive\n     */\n    HAL_DATASPACE_RANGE_LIMITED = 2 << HAL_DATASPACE_RANGE_SHIFT,\n\n    /*\n     * Legacy dataspaces\n     */\n\n    /*\n     * sRGB linear encoding:\n     *\n     * The red, green, and blue components are stored in sRGB space, but\n     * are linear, not gamma-encoded.\n     * The RGB primaries and the white point are the same as BT.709.\n     *\n     * The values are encoded using the full range ([0,255] for 8-bit) for all\n     * components.\n     */\n    HAL_DATASPACE_SRGB_LINEAR = 0x200, // deprecated, use HAL_DATASPACE_V0_SRGB_LINEAR\n\n    HAL_DATASPACE_V0_SRGB_LINEAR = HAL_DATASPACE_STANDARD_BT709 |\n            HAL_DATASPACE_TRANSFER_LINEAR | HAL_DATASPACE_RANGE_FULL,\n\n\n    /*\n     * sRGB gamma encoding:\n     *\n     * The red, green and blue components are stored in sRGB space, and\n     * converted to linear space when read, using the SRGB transfer function\n     * for each of the R, G and B components. When written, the inverse\n     * transformation is performed.\n     *\n     * The alpha component, if present, is always stored in linear space and\n     * is left unmodified when read or written.\n     *\n     * Use full range and BT.709 standard.\n     */\n    HAL_DATASPACE_SRGB = 0x201, // deprecated, use HAL_DATASPACE_V0_SRGB\n\n    HAL_DATASPACE_V0_SRGB = HAL_DATASPACE_STANDARD_BT709 |\n            HAL_DATASPACE_TRANSFER_SRGB | HAL_DATASPACE_RANGE_FULL,\n\n\n    /*\n     * YCbCr Colorspaces\n     * -----------------\n     *\n     * Primaries are given using (x,y) coordinates in the CIE 1931 definition\n     * of x and y specified by ISO 11664-1.\n     *\n     * Transfer characteristics are the opto-electronic transfer characteristic\n     * at the source as a function of linear optical intensity (luminance).\n     */\n\n    /*\n     * JPEG File Interchange Format (JFIF)\n     *\n     * Same model as BT.601-625, but all values (Y, Cb, Cr) range from 0 to 255\n     *\n     * Use full range, BT.601 transfer and BT.601_625 standard.\n     */\n    HAL_DATASPACE_JFIF = 0x101, // deprecated, use HAL_DATASPACE_V0_JFIF\n\n    HAL_DATASPACE_V0_JFIF = HAL_DATASPACE_STANDARD_BT601_625 |\n            HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_RANGE_FULL,\n\n    /*\n     * ITU-R Recommendation 601 (BT.601) - 625-line\n     *\n     * Standard-definition television, 625 Lines (PAL)\n     *\n     * Use limited range, BT.601 transfer and BT.601_625 standard.\n     */\n    HAL_DATASPACE_BT601_625 = 0x102, // deprecated, use HAL_DATASPACE_V0_BT601_625\n\n    HAL_DATASPACE_V0_BT601_625 = HAL_DATASPACE_STANDARD_BT601_625 |\n            HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_RANGE_LIMITED,\n\n\n    /*\n     * ITU-R Recommendation 601 (BT.601) - 525-line\n     *\n     * Standard-definition television, 525 Lines (NTSC)\n     *\n     * Use limited range, BT.601 transfer and BT.601_525 standard.\n     */\n    HAL_DATASPACE_BT601_525 = 0x103, // deprecated, use HAL_DATASPACE_V0_BT601_525\n\n    HAL_DATASPACE_V0_BT601_525 = HAL_DATASPACE_STANDARD_BT601_525 |\n            HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_RANGE_LIMITED,\n\n    /*\n     * ITU-R Recommendation 709 (BT.709)\n     *\n     * High-definition television\n     *\n     * Use limited range, BT.709 transfer and BT.709 standard.\n     */\n    HAL_DATASPACE_BT709 = 0x104, // deprecated, use HAL_DATASPACE_V0_BT709\n\n    HAL_DATASPACE_V0_BT709 = HAL_DATASPACE_STANDARD_BT709 |\n            HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_RANGE_LIMITED,\n\n    /*\n     * Data spaces for non-color formats\n     */\n\n    /*\n     * The buffer contains depth ranging measurements from a depth camera.\n     * This value is valid with formats:\n     *    HAL_PIXEL_FORMAT_Y16: 16-bit samples, consisting of a depth measurement\n     *       and an associated confidence value. The 3 MSBs of the sample make\n     *       up the confidence value, and the low 13 LSBs of the sample make up\n     *       the depth measurement.\n     *       For the confidence section, 0 means 100% confidence, 1 means 0%\n     *       confidence. The mapping to a linear float confidence value between\n     *       0.f and 1.f can be obtained with\n     *         float confidence = (((depthSample >> 13) - 1) & 0x7) / 7.0f;\n     *       The depth measurement can be extracted simply with\n     *         uint16_t range = (depthSample & 0x1FFF);\n     *    HAL_PIXEL_FORMAT_BLOB: A depth point cloud, as\n     *       a variable-length float (x,y,z, confidence) coordinate point list.\n     *       The point cloud will be represented with the android_depth_points\n     *       structure.\n     */\n    HAL_DATASPACE_DEPTH = 0x1000\n\n} android_dataspace_t;\n\n/*\n * Color transforms that may be applied by hardware composer to the whole\n * display.\n */\ntypedef enum android_color_transform {\n    /* Applies no transform to the output color */\n    HAL_COLOR_TRANSFORM_IDENTITY = 0,\n\n    /* Applies an arbitrary transform defined by a 4x4 affine matrix */\n    HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX = 1,\n\n    /* Applies a transform that inverts the value or luminance of the color, but\n     * does not modify hue or saturation */\n    HAL_COLOR_TRANSFORM_VALUE_INVERSE = 2,\n\n    /* Applies a transform that maps all colors to shades of gray */\n    HAL_COLOR_TRANSFORM_GRAYSCALE = 3,\n\n    /* Applies a transform which corrects for protanopic color blindness */\n    HAL_COLOR_TRANSFORM_CORRECT_PROTANOPIA = 4,\n\n    /* Applies a transform which corrects for deuteranopic color blindness */\n    HAL_COLOR_TRANSFORM_CORRECT_DEUTERANOPIA = 5,\n\n    /* Applies a transform which corrects for tritanopic color blindness */\n    HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA = 6\n} android_color_transform_t;\n\n/*\n * Supported HDR formats. Must be kept in sync with equivalents in Display.java.\n */\ntypedef enum android_hdr {\n    /* Device supports Dolby Vision HDR */\n    HAL_HDR_DOLBY_VISION = 1,\n\n    /* Device supports HDR10 */\n    HAL_HDR_HDR10 = 2,\n\n    /* Device supports hybrid log-gamma HDR */\n    HAL_HDR_HLG = 3\n} android_hdr_t;\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* SYSTEM_CORE_INCLUDE_ANDROID_GRAPHICS_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/system/radio.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_RADIO_H\n#define ANDROID_RADIO_H\n\n#include <stdbool.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n\n#define RADIO_NUM_BANDS_MAX     16\n#define RADIO_NUM_SPACINGS_MAX  16\n#define RADIO_STRING_LEN_MAX    128\n\n/*\n * Radio hardware module class. A given radio hardware module HAL is of one class\n * only. The platform can not have more than one hardware module of each class.\n * Current version of the framework only supports RADIO_CLASS_AM_FM.\n */\ntypedef enum {\n    RADIO_CLASS_AM_FM = 0,  /* FM (including HD radio) and AM */\n    RADIO_CLASS_SAT   = 1,  /* Satellite Radio */\n    RADIO_CLASS_DT    = 2,  /* Digital Radio (DAB) */\n} radio_class_t;\n\n/* value for field \"type\" of radio band described in struct radio_hal_band_config */\ntypedef enum {\n    RADIO_BAND_AM     = 0,  /* Amplitude Modulation band: LW, MW, SW */\n    RADIO_BAND_FM     = 1,  /* Frequency Modulation band: FM */\n    RADIO_BAND_FM_HD  = 2,  /* FM HD Radio / DRM (IBOC) */\n    RADIO_BAND_AM_HD  = 3,  /* AM HD Radio / DRM (IBOC) */\n} radio_band_t;\n\n/* RDS variant implemented. A struct radio_hal_fm_band_config can list none or several. */\nenum {\n    RADIO_RDS_NONE   = 0x0,\n    RADIO_RDS_WORLD  = 0x01,\n    RADIO_RDS_US     = 0x02,\n};\ntypedef unsigned int radio_rds_t;\n\n/* FM deemphasis variant implemented. A struct radio_hal_fm_band_config can list one or more. */\nenum {\n    RADIO_DEEMPHASIS_50   = 0x1,\n    RADIO_DEEMPHASIS_75   = 0x2,\n};\ntypedef unsigned int radio_deemphasis_t;\n\n/* Region a particular radio band configuration corresponds to. Not used at the HAL.\n * Derived by the framework when converting the band descriptors retrieved from the HAL to\n * individual band descriptors for each supported region. */\ntypedef enum {\n    RADIO_REGION_NONE  = -1,\n    RADIO_REGION_ITU_1 = 0,\n    RADIO_REGION_ITU_2 = 1,\n    RADIO_REGION_OIRT  = 2,\n    RADIO_REGION_JAPAN = 3,\n    RADIO_REGION_KOREA = 4,\n} radio_region_t;\n\n/* scanning direction for scan() and step() tuner APIs */\ntypedef enum {\n    RADIO_DIRECTION_UP,\n    RADIO_DIRECTION_DOWN\n} radio_direction_t;\n\n/* unique handle allocated to a radio module */\ntypedef unsigned int radio_handle_t;\n\n/* Opaque meta data structure used by radio meta data API (see system/radio_metadata.h) */\ntypedef struct radio_medtadata radio_metadata_t;\n\n\n/* Additional attributes for an FM band configuration */\ntypedef struct radio_hal_fm_band_config {\n    radio_deemphasis_t  deemphasis; /* deemphasis variant */\n    bool                stereo;     /* stereo supported */\n    radio_rds_t         rds;        /* RDS variants supported */\n    bool                ta;         /* Traffic Announcement supported */\n    bool                af;         /* Alternate Frequency supported */\n    bool                ea;         /* Emergency announcements supported */\n} radio_hal_fm_band_config_t;\n\n/* Additional attributes for an AM band configuration */\ntypedef struct radio_hal_am_band_config {\n    bool                stereo;     /* stereo supported */\n} radio_hal_am_band_config_t;\n\n/* Radio band configuration. Describes a given band supported by the radio module.\n * The HAL can expose only one band per type with the the maximum range supported and all options.\n * THe framework will derive the actual regions were this module can operate and expose separate\n * band configurations for applications to chose from. */\ntypedef struct radio_hal_band_config {\n    radio_band_t type;\n    bool         antenna_connected;\n    unsigned int lower_limit;\n    unsigned int upper_limit;\n    unsigned int num_spacings;\n    unsigned int spacings[RADIO_NUM_SPACINGS_MAX];\n    union {\n        radio_hal_fm_band_config_t fm;\n        radio_hal_am_band_config_t am;\n    };\n} radio_hal_band_config_t;\n\n/* Used internally by the framework to represent a band for s specific region */\ntypedef struct radio_band_config {\n    radio_region_t  region;\n    radio_hal_band_config_t band;\n} radio_band_config_t;\n\n\n/* Exposes properties of a given hardware radio module.\n * NOTE: current framework implementation supports only one audio source (num_audio_sources = 1).\n * The source corresponds to AUDIO_DEVICE_IN_FM_TUNER.\n * If more than one tuner is supported (num_tuners > 1), only one can be connected to the audio\n * source. */\ntypedef struct radio_hal_properties {\n    radio_class_t   class_id;   /* Class of this module. E.g RADIO_CLASS_AM_FM */\n    char            implementor[RADIO_STRING_LEN_MAX];  /* implementor name */\n    char            product[RADIO_STRING_LEN_MAX];  /* product name */\n    char            version[RADIO_STRING_LEN_MAX];  /* product version */\n    char            serial[RADIO_STRING_LEN_MAX];  /* serial number (for subscription services) */\n    unsigned int    num_tuners;     /* number of tuners controllable independently */\n    unsigned int    num_audio_sources; /* number of audio sources driven simultaneously */\n    bool            supports_capture; /* the hardware supports capture of audio source audio HAL */\n    unsigned int    num_bands;      /* number of band descriptors */\n    radio_hal_band_config_t bands[RADIO_NUM_BANDS_MAX]; /* band descriptors */\n} radio_hal_properties_t;\n\n/* Used internally by the framework. Same information as in struct radio_hal_properties plus a\n * unique handle and one band configuration per region. */\ntypedef struct radio_properties {\n    radio_handle_t      handle;\n    radio_class_t       class_id;\n    char                implementor[RADIO_STRING_LEN_MAX];\n    char                product[RADIO_STRING_LEN_MAX];\n    char                version[RADIO_STRING_LEN_MAX];\n    char                serial[RADIO_STRING_LEN_MAX];\n    unsigned int        num_tuners;\n    unsigned int        num_audio_sources;\n    bool                supports_capture;\n    unsigned int        num_bands;\n    radio_band_config_t bands[RADIO_NUM_BANDS_MAX];\n} radio_properties_t;\n\n/* Radio program information. Returned by the HAL with event RADIO_EVENT_TUNED.\n * Contains information on currently tuned channel.\n */\ntypedef struct radio_program_info {\n    unsigned int     channel;   /* current channel. (e.g kHz for band type RADIO_BAND_FM) */\n    unsigned int     sub_channel; /* current sub channel. (used for RADIO_BAND_FM_HD) */\n    bool             tuned;     /* tuned to a program or not */\n    bool             stereo;    /* program is stereo or not */\n    bool             digital;   /* digital program or not (e.g HD Radio program) */\n    unsigned int     signal_strength; /* signal strength from 0 to 100 */\n    radio_metadata_t *metadata; /* non null if meta data are present (e.g PTY, song title ...) */\n} radio_program_info_t;\n\n\n/* Events sent to the framework via the HAL callback. An event can notify the completion of an\n * asynchronous command (configuration, tune, scan ...) or a spontaneous change (antenna connection,\n * failure, AF switching, meta data reception... */\nenum {\n    RADIO_EVENT_HW_FAILURE  = 0,  /* hardware module failure. Requires reopening the tuner */\n    RADIO_EVENT_CONFIG      = 1,  /* configuration change completed */\n    RADIO_EVENT_ANTENNA     = 2,  /* Antenna connected, disconnected */\n    RADIO_EVENT_TUNED       = 3,  /* tune, step, scan completed */\n    RADIO_EVENT_METADATA    = 4,  /* New meta data received */\n    RADIO_EVENT_TA          = 5,  /* Traffic announcement start or stop */\n    RADIO_EVENT_AF_SWITCH   = 6,  /* Switch to Alternate Frequency */\n    RADIO_EVENT_EA          = 7,  /* Emergency announcement start or stop */\n    // begin framework only events\n    RADIO_EVENT_CONTROL     = 100, /* loss/gain of tuner control */\n    RADIO_EVENT_SERVER_DIED = 101, /* radio service died */\n};\ntypedef unsigned int radio_event_type_t;\n\n/* Event passed to the framework by the HAL callback */\ntypedef struct radio_hal_event {\n    radio_event_type_t  type;       /* event type */\n    int                 status;     /* used by RADIO_EVENT_CONFIG, RADIO_EVENT_TUNED */\n    union {\n        /* RADIO_EVENT_ANTENNA, RADIO_EVENT_TA, RADIO_EVENT_EA */\n        bool                    on;\n        radio_hal_band_config_t config; /* RADIO_EVENT_CONFIG */\n        radio_program_info_t    info;   /* RADIO_EVENT_TUNED, RADIO_EVENT_AF_SWITCH */\n        radio_metadata_t        *metadata; /* RADIO_EVENT_METADATA */\n    };\n} radio_hal_event_t;\n\n/* Used internally by the framework. Same information as in struct radio_hal_event */\ntypedef struct radio_event {\n    radio_event_type_t  type;\n    int                 status;\n    union {\n        bool                    on;\n        radio_band_config_t     config;\n        radio_program_info_t    info;\n        radio_metadata_t        *metadata; /* offset from start of struct when in shared memory */\n    };\n} radio_event_t;\n\n\nstatic radio_rds_t radio_rds_for_region(bool rds, radio_region_t region) {\n    if (!rds)\n        return RADIO_RDS_NONE;\n    switch(region) {\n        case RADIO_REGION_ITU_1:\n        case RADIO_REGION_OIRT:\n        case RADIO_REGION_JAPAN:\n        case RADIO_REGION_KOREA:\n            return RADIO_RDS_WORLD;\n        case RADIO_REGION_ITU_2:\n            return RADIO_RDS_US;\n        default:\n            return RADIO_REGION_NONE;\n    }\n}\n\nstatic radio_deemphasis_t radio_demephasis_for_region(radio_region_t region) {\n    switch(region) {\n        case RADIO_REGION_KOREA:\n        case RADIO_REGION_ITU_2:\n            return RADIO_DEEMPHASIS_75;\n        case RADIO_REGION_ITU_1:\n        case RADIO_REGION_OIRT:\n        case RADIO_REGION_JAPAN:\n        default:\n            return RADIO_DEEMPHASIS_50;\n    }\n}\n\n#endif  // ANDROID_RADIO_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/system/thread_defs.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_THREAD_DEFS_H\n#define ANDROID_THREAD_DEFS_H\n\n#include \"graphics.h\"\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\nenum {\n    /*\n     * ***********************************************\n     * ** Keep in sync with android.os.Process.java **\n     * ***********************************************\n     *\n     * This maps directly to the \"nice\" priorities we use in Android.\n     * A thread priority should be chosen inverse-proportionally to\n     * the amount of work the thread is expected to do. The more work\n     * a thread will do, the less favorable priority it should get so that\n     * it doesn't starve the system. Threads not behaving properly might\n     * be \"punished\" by the kernel.\n     * Use the levels below when appropriate. Intermediate values are\n     * acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below.\n     */\n    ANDROID_PRIORITY_LOWEST         =  19,\n\n    /* use for background tasks */\n    ANDROID_PRIORITY_BACKGROUND     =  10,\n\n    /* most threads run at normal priority */\n    ANDROID_PRIORITY_NORMAL         =   0,\n\n    /* threads currently running a UI that the user is interacting with */\n    ANDROID_PRIORITY_FOREGROUND     =  -2,\n\n    /* the main UI thread has a slightly more favorable priority */\n    ANDROID_PRIORITY_DISPLAY        =  -4,\n\n    /* ui service treads might want to run at a urgent display (uncommon) */\n    ANDROID_PRIORITY_URGENT_DISPLAY =  HAL_PRIORITY_URGENT_DISPLAY,\n\n    /* all normal audio threads */\n    ANDROID_PRIORITY_AUDIO          = -16,\n\n    /* service audio threads (uncommon) */\n    ANDROID_PRIORITY_URGENT_AUDIO   = -19,\n\n    /* should never be used in practice. regular process might not\n     * be allowed to use this level */\n    ANDROID_PRIORITY_HIGHEST        = -20,\n\n    ANDROID_PRIORITY_DEFAULT        = ANDROID_PRIORITY_NORMAL,\n    ANDROID_PRIORITY_MORE_FAVORABLE = -1,\n    ANDROID_PRIORITY_LESS_FAVORABLE = +1,\n};\n\n#if defined(__cplusplus)\n}\n#endif\n\n#endif /* ANDROID_THREAD_DEFS_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/system/window.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H\n#define SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H\n\n#include <cutils/native_handle.h>\n#include <errno.h>\n#include <limits.h>\n#include <stdint.h>\n#include <string.h>\n#include <sys/cdefs.h>\n#include <system/graphics.h>\n#include <unistd.h>\n#include <stdbool.h>\n\n#ifndef __UNUSED\n#define __UNUSED __attribute__((__unused__))\n#endif\n#ifndef __deprecated\n#define __deprecated __attribute__((__deprecated__))\n#endif\n\n__BEGIN_DECLS\n\n/*****************************************************************************/\n\n#define ANDROID_NATIVE_MAKE_CONSTANT(a,b,c,d) \\\n    (((unsigned)(a)<<24)|((unsigned)(b)<<16)|((unsigned)(c)<<8)|(unsigned)(d))\n\n#define ANDROID_NATIVE_WINDOW_MAGIC \\\n    ANDROID_NATIVE_MAKE_CONSTANT('_','w','n','d')\n\n#define ANDROID_NATIVE_BUFFER_MAGIC \\\n    ANDROID_NATIVE_MAKE_CONSTANT('_','b','f','r')\n\n// ---------------------------------------------------------------------------\n\n// This #define may be used to conditionally compile device-specific code to\n// support either the prior ANativeWindow interface, which did not pass libsync\n// fences around, or the new interface that does.  This #define is only present\n// when the ANativeWindow interface does include libsync support.\n#define ANDROID_NATIVE_WINDOW_HAS_SYNC 1\n\n// ---------------------------------------------------------------------------\n\ntypedef const native_handle_t* buffer_handle_t;\n\n// ---------------------------------------------------------------------------\n\ntypedef struct android_native_rect_t\n{\n    int32_t left;\n    int32_t top;\n    int32_t right;\n    int32_t bottom;\n} android_native_rect_t;\n\n// ---------------------------------------------------------------------------\n\ntypedef struct android_native_base_t\n{\n    /* a magic value defined by the actual EGL native type */\n    int magic;\n\n    /* the sizeof() of the actual EGL native type */\n    int version;\n\n    void* reserved[4];\n\n    /* reference-counting interface */\n    void (*incRef)(struct android_native_base_t* base);\n    void (*decRef)(struct android_native_base_t* base);\n} android_native_base_t;\n\ntypedef struct ANativeWindowBuffer\n{\n#ifdef __cplusplus\n    ANativeWindowBuffer() {\n        common.magic = ANDROID_NATIVE_BUFFER_MAGIC;\n        common.version = sizeof(ANativeWindowBuffer);\n        memset(common.reserved, 0, sizeof(common.reserved));\n    }\n\n    // Implement the methods that sp<ANativeWindowBuffer> expects so that it\n    // can be used to automatically refcount ANativeWindowBuffer's.\n    void incStrong(const void* /*id*/) const {\n        common.incRef(const_cast<android_native_base_t*>(&common));\n    }\n    void decStrong(const void* /*id*/) const {\n        common.decRef(const_cast<android_native_base_t*>(&common));\n    }\n#endif\n\n    struct android_native_base_t common;\n\n    int width;\n    int height;\n    int stride;\n    int format;\n    int usage;\n\n    void* reserved[2];\n\n    buffer_handle_t handle;\n\n    void* reserved_proc[8];\n} ANativeWindowBuffer_t;\n\n// Old typedef for backwards compatibility.\ntypedef ANativeWindowBuffer_t android_native_buffer_t;\n\n// ---------------------------------------------------------------------------\n\n/* attributes queriable with query() */\nenum {\n    NATIVE_WINDOW_WIDTH     = 0,\n    NATIVE_WINDOW_HEIGHT    = 1,\n    NATIVE_WINDOW_FORMAT    = 2,\n\n    /* The minimum number of buffers that must remain un-dequeued after a buffer\n     * has been queued.  This value applies only if set_buffer_count was used to\n     * override the number of buffers and if a buffer has since been queued.\n     * Users of the set_buffer_count ANativeWindow method should query this\n     * value before calling set_buffer_count.  If it is necessary to have N\n     * buffers simultaneously dequeued as part of the steady-state operation,\n     * and this query returns M then N+M buffers should be requested via\n     * native_window_set_buffer_count.\n     *\n     * Note that this value does NOT apply until a single buffer has been\n     * queued.  In particular this means that it is possible to:\n     *\n     * 1. Query M = min undequeued buffers\n     * 2. Set the buffer count to N + M\n     * 3. Dequeue all N + M buffers\n     * 4. Cancel M buffers\n     * 5. Queue, dequeue, queue, dequeue, ad infinitum\n     */\n    NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS = 3,\n\n    /* Check whether queueBuffer operations on the ANativeWindow send the buffer\n     * to the window compositor.  The query sets the returned 'value' argument\n     * to 1 if the ANativeWindow DOES send queued buffers directly to the window\n     * compositor and 0 if the buffers do not go directly to the window\n     * compositor.\n     *\n     * This can be used to determine whether protected buffer content should be\n     * sent to the ANativeWindow.  Note, however, that a result of 1 does NOT\n     * indicate that queued buffers will be protected from applications or users\n     * capturing their contents.  If that behavior is desired then some other\n     * mechanism (e.g. the GRALLOC_USAGE_PROTECTED flag) should be used in\n     * conjunction with this query.\n     */\n    NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER = 4,\n\n    /* Get the concrete type of a ANativeWindow.  See below for the list of\n     * possible return values.\n     *\n     * This query should not be used outside the Android framework and will\n     * likely be removed in the near future.\n     */\n    NATIVE_WINDOW_CONCRETE_TYPE = 5,\n\n\n    /*\n     * Default width and height of ANativeWindow buffers, these are the\n     * dimensions of the window buffers irrespective of the\n     * NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS call and match the native window\n     * size unless overridden by NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS.\n     */\n    NATIVE_WINDOW_DEFAULT_WIDTH = 6,\n    NATIVE_WINDOW_DEFAULT_HEIGHT = 7,\n\n    /*\n     * transformation that will most-likely be applied to buffers. This is only\n     * a hint, the actual transformation applied might be different.\n     *\n     * INTENDED USE:\n     *\n     * The transform hint can be used by a producer, for instance the GLES\n     * driver, to pre-rotate the rendering such that the final transformation\n     * in the composer is identity. This can be very useful when used in\n     * conjunction with the h/w composer HAL, in situations where it\n     * cannot handle arbitrary rotations.\n     *\n     * 1. Before dequeuing a buffer, the GL driver (or any other ANW client)\n     *    queries the ANW for NATIVE_WINDOW_TRANSFORM_HINT.\n     *\n     * 2. The GL driver overrides the width and height of the ANW to\n     *    account for NATIVE_WINDOW_TRANSFORM_HINT. This is done by querying\n     *    NATIVE_WINDOW_DEFAULT_{WIDTH | HEIGHT}, swapping the dimensions\n     *    according to NATIVE_WINDOW_TRANSFORM_HINT and calling\n     *    native_window_set_buffers_dimensions().\n     *\n     * 3. The GL driver dequeues a buffer of the new pre-rotated size.\n     *\n     * 4. The GL driver renders to the buffer such that the image is\n     *    already transformed, that is applying NATIVE_WINDOW_TRANSFORM_HINT\n     *    to the rendering.\n     *\n     * 5. The GL driver calls native_window_set_transform to apply\n     *    inverse transformation to the buffer it just rendered.\n     *    In order to do this, the GL driver needs\n     *    to calculate the inverse of NATIVE_WINDOW_TRANSFORM_HINT, this is\n     *    done easily:\n     *\n     *        int hintTransform, inverseTransform;\n     *        query(..., NATIVE_WINDOW_TRANSFORM_HINT, &hintTransform);\n     *        inverseTransform = hintTransform;\n     *        if (hintTransform & HAL_TRANSFORM_ROT_90)\n     *            inverseTransform ^= HAL_TRANSFORM_ROT_180;\n     *\n     *\n     * 6. The GL driver queues the pre-transformed buffer.\n     *\n     * 7. The composer combines the buffer transform with the display\n     *    transform.  If the buffer transform happens to cancel out the\n     *    display transform then no rotation is needed.\n     *\n     */\n    NATIVE_WINDOW_TRANSFORM_HINT = 8,\n\n    /*\n     * Boolean that indicates whether the consumer is running more than\n     * one buffer behind the producer.\n     */\n    NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND = 9,\n\n    /*\n     * The consumer gralloc usage bits currently set by the consumer.\n     * The values are defined in hardware/libhardware/include/gralloc.h.\n     */\n    NATIVE_WINDOW_CONSUMER_USAGE_BITS = 10,\n\n    /**\n     * Transformation that will by applied to buffers by the hwcomposer.\n     * This must not be set or checked by producer endpoints, and will\n     * disable the transform hint set in SurfaceFlinger (see\n     * NATIVE_WINDOW_TRANSFORM_HINT).\n     *\n     * INTENDED USE:\n     * Temporary - Please do not use this.  This is intended only to be used\n     * by the camera's LEGACY mode.\n     *\n     * In situations where a SurfaceFlinger client wishes to set a transform\n     * that is not visible to the producer, and will always be applied in the\n     * hardware composer, the client can set this flag with\n     * native_window_set_buffers_sticky_transform.  This can be used to rotate\n     * and flip buffers consumed by hardware composer without actually changing\n     * the aspect ratio of the buffers produced.\n     */\n    NATIVE_WINDOW_STICKY_TRANSFORM = 11,\n\n    /**\n     * The default data space for the buffers as set by the consumer.\n     * The values are defined in graphics.h.\n     */\n    NATIVE_WINDOW_DEFAULT_DATASPACE = 12,\n\n    /*\n     * Returns the age of the contents of the most recently dequeued buffer as\n     * the number of frames that have elapsed since it was last queued. For\n     * example, if the window is double-buffered, the age of any given buffer in\n     * steady state will be 2. If the dequeued buffer has never been queued, its\n     * age will be 0.\n     */\n    NATIVE_WINDOW_BUFFER_AGE = 13,\n};\n\n/* Valid operations for the (*perform)() hook.\n *\n * Values marked as 'deprecated' are supported, but have been superceded by\n * other functionality.\n *\n * Values marked as 'private' should be considered private to the framework.\n * HAL implementation code with access to an ANativeWindow should not use these,\n * as it may not interact properly with the framework's use of the\n * ANativeWindow.\n */\nenum {\n    NATIVE_WINDOW_SET_USAGE                 =  0,\n    NATIVE_WINDOW_CONNECT                   =  1,   /* deprecated */\n    NATIVE_WINDOW_DISCONNECT                =  2,   /* deprecated */\n    NATIVE_WINDOW_SET_CROP                  =  3,   /* private */\n    NATIVE_WINDOW_SET_BUFFER_COUNT          =  4,\n    NATIVE_WINDOW_SET_BUFFERS_GEOMETRY      =  5,   /* deprecated */\n    NATIVE_WINDOW_SET_BUFFERS_TRANSFORM     =  6,\n    NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP     =  7,\n    NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS    =  8,\n    NATIVE_WINDOW_SET_BUFFERS_FORMAT        =  9,\n    NATIVE_WINDOW_SET_SCALING_MODE          = 10,   /* private */\n    NATIVE_WINDOW_LOCK                      = 11,   /* private */\n    NATIVE_WINDOW_UNLOCK_AND_POST           = 12,   /* private */\n    NATIVE_WINDOW_API_CONNECT               = 13,   /* private */\n    NATIVE_WINDOW_API_DISCONNECT            = 14,   /* private */\n    NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS = 15, /* private */\n    NATIVE_WINDOW_SET_POST_TRANSFORM_CROP   = 16,   /* private */\n    NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM = 17,/* private */\n    NATIVE_WINDOW_SET_SIDEBAND_STREAM       = 18,\n    NATIVE_WINDOW_SET_BUFFERS_DATASPACE     = 19,\n    NATIVE_WINDOW_SET_SURFACE_DAMAGE        = 20,   /* private */\n    NATIVE_WINDOW_SET_SHARED_BUFFER_MODE    = 21,\n    NATIVE_WINDOW_SET_AUTO_REFRESH          = 22,\n};\n\n/* parameter for NATIVE_WINDOW_[API_][DIS]CONNECT */\nenum {\n    /* Buffers will be queued by EGL via eglSwapBuffers after being filled using\n     * OpenGL ES.\n     */\n    NATIVE_WINDOW_API_EGL = 1,\n\n    /* Buffers will be queued after being filled using the CPU\n     */\n    NATIVE_WINDOW_API_CPU = 2,\n\n    /* Buffers will be queued by Stagefright after being filled by a video\n     * decoder.  The video decoder can either be a software or hardware decoder.\n     */\n    NATIVE_WINDOW_API_MEDIA = 3,\n\n    /* Buffers will be queued by the the camera HAL.\n     */\n    NATIVE_WINDOW_API_CAMERA = 4,\n};\n\n/* parameter for NATIVE_WINDOW_SET_BUFFERS_TRANSFORM */\nenum {\n    /* flip source image horizontally */\n    NATIVE_WINDOW_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H ,\n    /* flip source image vertically */\n    NATIVE_WINDOW_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V,\n    /* rotate source image 90 degrees clock-wise, and is applied after TRANSFORM_FLIP_{H|V} */\n    NATIVE_WINDOW_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90,\n    /* rotate source image 180 degrees */\n    NATIVE_WINDOW_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180,\n    /* rotate source image 270 degrees clock-wise */\n    NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,\n    /* transforms source by the inverse transform of the screen it is displayed onto. This\n     * transform is applied last */\n    NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY = 0x08\n};\n\n/* parameter for NATIVE_WINDOW_SET_SCALING_MODE\n * keep in sync with Surface.java in frameworks/base */\nenum {\n    /* the window content is not updated (frozen) until a buffer of\n     * the window size is received (enqueued)\n     */\n    NATIVE_WINDOW_SCALING_MODE_FREEZE           = 0,\n    /* the buffer is scaled in both dimensions to match the window size */\n    NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW  = 1,\n    /* the buffer is scaled uniformly such that the smaller dimension\n     * of the buffer matches the window size (cropping in the process)\n     */\n    NATIVE_WINDOW_SCALING_MODE_SCALE_CROP       = 2,\n    /* the window is clipped to the size of the buffer's crop rectangle; pixels\n     * outside the crop rectangle are treated as if they are completely\n     * transparent.\n     */\n    NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP    = 3,\n};\n\n/* values returned by the NATIVE_WINDOW_CONCRETE_TYPE query */\nenum {\n    NATIVE_WINDOW_FRAMEBUFFER               = 0, /* FramebufferNativeWindow */\n    NATIVE_WINDOW_SURFACE                   = 1, /* Surface */\n};\n\n/* parameter for NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP\n *\n * Special timestamp value to indicate that timestamps should be auto-generated\n * by the native window when queueBuffer is called.  This is equal to INT64_MIN,\n * defined directly to avoid problems with C99/C++ inclusion of stdint.h.\n */\nstatic const int64_t NATIVE_WINDOW_TIMESTAMP_AUTO = (-9223372036854775807LL-1);\n\nstruct ANativeWindow\n{\n#ifdef __cplusplus\n    ANativeWindow()\n        : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)\n    {\n        common.magic = ANDROID_NATIVE_WINDOW_MAGIC;\n        common.version = sizeof(ANativeWindow);\n        memset(common.reserved, 0, sizeof(common.reserved));\n    }\n\n    /* Implement the methods that sp<ANativeWindow> expects so that it\n       can be used to automatically refcount ANativeWindow's. */\n    void incStrong(const void* /*id*/) const {\n        common.incRef(const_cast<android_native_base_t*>(&common));\n    }\n    void decStrong(const void* /*id*/) const {\n        common.decRef(const_cast<android_native_base_t*>(&common));\n    }\n#endif\n\n    struct android_native_base_t common;\n\n    /* flags describing some attributes of this surface or its updater */\n    const uint32_t flags;\n\n    /* min swap interval supported by this updated */\n    const int   minSwapInterval;\n\n    /* max swap interval supported by this updated */\n    const int   maxSwapInterval;\n\n    /* horizontal and vertical resolution in DPI */\n    const float xdpi;\n    const float ydpi;\n\n    /* Some storage reserved for the OEM's driver. */\n    intptr_t    oem[4];\n\n    /*\n     * Set the swap interval for this surface.\n     *\n     * Returns 0 on success or -errno on error.\n     */\n    int     (*setSwapInterval)(struct ANativeWindow* window,\n                int interval);\n\n    /*\n     * Hook called by EGL to acquire a buffer. After this call, the buffer\n     * is not locked, so its content cannot be modified. This call may block if\n     * no buffers are available.\n     *\n     * The window holds a reference to the buffer between dequeueBuffer and\n     * either queueBuffer or cancelBuffer, so clients only need their own\n     * reference if they might use the buffer after queueing or canceling it.\n     * Holding a reference to a buffer after queueing or canceling it is only\n     * allowed if a specific buffer count has been set.\n     *\n     * Returns 0 on success or -errno on error.\n     *\n     * XXX: This function is deprecated.  It will continue to work for some\n     * time for binary compatibility, but the new dequeueBuffer function that\n     * outputs a fence file descriptor should be used in its place.\n     */\n    int     (*dequeueBuffer_DEPRECATED)(struct ANativeWindow* window,\n                struct ANativeWindowBuffer** buffer);\n\n    /*\n     * hook called by EGL to lock a buffer. This MUST be called before modifying\n     * the content of a buffer. The buffer must have been acquired with\n     * dequeueBuffer first.\n     *\n     * Returns 0 on success or -errno on error.\n     *\n     * XXX: This function is deprecated.  It will continue to work for some\n     * time for binary compatibility, but it is essentially a no-op, and calls\n     * to it should be removed.\n     */\n    int     (*lockBuffer_DEPRECATED)(struct ANativeWindow* window,\n                struct ANativeWindowBuffer* buffer);\n\n    /*\n     * Hook called by EGL when modifications to the render buffer are done.\n     * This unlocks and post the buffer.\n     *\n     * The window holds a reference to the buffer between dequeueBuffer and\n     * either queueBuffer or cancelBuffer, so clients only need their own\n     * reference if they might use the buffer after queueing or canceling it.\n     * Holding a reference to a buffer after queueing or canceling it is only\n     * allowed if a specific buffer count has been set.\n     *\n     * Buffers MUST be queued in the same order than they were dequeued.\n     *\n     * Returns 0 on success or -errno on error.\n     *\n     * XXX: This function is deprecated.  It will continue to work for some\n     * time for binary compatibility, but the new queueBuffer function that\n     * takes a fence file descriptor should be used in its place (pass a value\n     * of -1 for the fence file descriptor if there is no valid one to pass).\n     */\n    int     (*queueBuffer_DEPRECATED)(struct ANativeWindow* window,\n                struct ANativeWindowBuffer* buffer);\n\n    /*\n     * hook used to retrieve information about the native window.\n     *\n     * Returns 0 on success or -errno on error.\n     */\n    int     (*query)(const struct ANativeWindow* window,\n                int what, int* value);\n\n    /*\n     * hook used to perform various operations on the surface.\n     * (*perform)() is a generic mechanism to add functionality to\n     * ANativeWindow while keeping backward binary compatibility.\n     *\n     * DO NOT CALL THIS HOOK DIRECTLY.  Instead, use the helper functions\n     * defined below.\n     *\n     * (*perform)() returns -ENOENT if the 'what' parameter is not supported\n     * by the surface's implementation.\n     *\n     * See above for a list of valid operations, such as\n     * NATIVE_WINDOW_SET_USAGE or NATIVE_WINDOW_CONNECT\n     */\n    int     (*perform)(struct ANativeWindow* window,\n                int operation, ... );\n\n    /*\n     * Hook used to cancel a buffer that has been dequeued.\n     * No synchronization is performed between dequeue() and cancel(), so\n     * either external synchronization is needed, or these functions must be\n     * called from the same thread.\n     *\n     * The window holds a reference to the buffer between dequeueBuffer and\n     * either queueBuffer or cancelBuffer, so clients only need their own\n     * reference if they might use the buffer after queueing or canceling it.\n     * Holding a reference to a buffer after queueing or canceling it is only\n     * allowed if a specific buffer count has been set.\n     *\n     * XXX: This function is deprecated.  It will continue to work for some\n     * time for binary compatibility, but the new cancelBuffer function that\n     * takes a fence file descriptor should be used in its place (pass a value\n     * of -1 for the fence file descriptor if there is no valid one to pass).\n     */\n    int     (*cancelBuffer_DEPRECATED)(struct ANativeWindow* window,\n                struct ANativeWindowBuffer* buffer);\n\n    /*\n     * Hook called by EGL to acquire a buffer. This call may block if no\n     * buffers are available.\n     *\n     * The window holds a reference to the buffer between dequeueBuffer and\n     * either queueBuffer or cancelBuffer, so clients only need their own\n     * reference if they might use the buffer after queueing or canceling it.\n     * Holding a reference to a buffer after queueing or canceling it is only\n     * allowed if a specific buffer count has been set.\n     *\n     * The libsync fence file descriptor returned in the int pointed to by the\n     * fenceFd argument will refer to the fence that must signal before the\n     * dequeued buffer may be written to.  A value of -1 indicates that the\n     * caller may access the buffer immediately without waiting on a fence.  If\n     * a valid file descriptor is returned (i.e. any value except -1) then the\n     * caller is responsible for closing the file descriptor.\n     *\n     * Returns 0 on success or -errno on error.\n     */\n    int     (*dequeueBuffer)(struct ANativeWindow* window,\n                struct ANativeWindowBuffer** buffer, int* fenceFd);\n\n    /*\n     * Hook called by EGL when modifications to the render buffer are done.\n     * This unlocks and post the buffer.\n     *\n     * The window holds a reference to the buffer between dequeueBuffer and\n     * either queueBuffer or cancelBuffer, so clients only need their own\n     * reference if they might use the buffer after queueing or canceling it.\n     * Holding a reference to a buffer after queueing or canceling it is only\n     * allowed if a specific buffer count has been set.\n     *\n     * The fenceFd argument specifies a libsync fence file descriptor for a\n     * fence that must signal before the buffer can be accessed.  If the buffer\n     * can be accessed immediately then a value of -1 should be used.  The\n     * caller must not use the file descriptor after it is passed to\n     * queueBuffer, and the ANativeWindow implementation is responsible for\n     * closing it.\n     *\n     * Returns 0 on success or -errno on error.\n     */\n    int     (*queueBuffer)(struct ANativeWindow* window,\n                struct ANativeWindowBuffer* buffer, int fenceFd);\n\n    /*\n     * Hook used to cancel a buffer that has been dequeued.\n     * No synchronization is performed between dequeue() and cancel(), so\n     * either external synchronization is needed, or these functions must be\n     * called from the same thread.\n     *\n     * The window holds a reference to the buffer between dequeueBuffer and\n     * either queueBuffer or cancelBuffer, so clients only need their own\n     * reference if they might use the buffer after queueing or canceling it.\n     * Holding a reference to a buffer after queueing or canceling it is only\n     * allowed if a specific buffer count has been set.\n     *\n     * The fenceFd argument specifies a libsync fence file decsriptor for a\n     * fence that must signal before the buffer can be accessed.  If the buffer\n     * can be accessed immediately then a value of -1 should be used.\n     *\n     * Note that if the client has not waited on the fence that was returned\n     * from dequeueBuffer, that same fence should be passed to cancelBuffer to\n     * ensure that future uses of the buffer are preceded by a wait on that\n     * fence.  The caller must not use the file descriptor after it is passed\n     * to cancelBuffer, and the ANativeWindow implementation is responsible for\n     * closing it.\n     *\n     * Returns 0 on success or -errno on error.\n     */\n    int     (*cancelBuffer)(struct ANativeWindow* window,\n                struct ANativeWindowBuffer* buffer, int fenceFd);\n};\n\n /* Backwards compatibility: use ANativeWindow (struct ANativeWindow in C).\n  * android_native_window_t is deprecated.\n  */\ntypedef struct ANativeWindow ANativeWindow;\ntypedef struct ANativeWindow android_native_window_t __deprecated;\n\n/*\n *  native_window_set_usage(..., usage)\n *  Sets the intended usage flags for the next buffers\n *  acquired with (*lockBuffer)() and on.\n *  By default (if this function is never called), a usage of\n *      GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE\n *  is assumed.\n *  Calling this function will usually cause following buffers to be\n *  reallocated.\n */\n\nstatic inline int native_window_set_usage(\n        struct ANativeWindow* window, int usage)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_USAGE, usage);\n}\n\n/* deprecated. Always returns 0. Don't call. */\nstatic inline int native_window_connect(\n        struct ANativeWindow* window __UNUSED, int api __UNUSED) __deprecated;\n\nstatic inline int native_window_connect(\n        struct ANativeWindow* window __UNUSED, int api __UNUSED) {\n    return 0;\n}\n\n/* deprecated. Always returns 0. Don't call. */\nstatic inline int native_window_disconnect(\n        struct ANativeWindow* window __UNUSED, int api __UNUSED) __deprecated;\n\nstatic inline int native_window_disconnect(\n        struct ANativeWindow* window __UNUSED, int api __UNUSED) {\n    return 0;\n}\n\n/*\n * native_window_set_crop(..., crop)\n * Sets which region of the next queued buffers needs to be considered.\n * Depending on the scaling mode, a buffer's crop region is scaled and/or\n * cropped to match the surface's size.  This function sets the crop in\n * pre-transformed buffer pixel coordinates.\n *\n * The specified crop region applies to all buffers queued after it is called.\n *\n * If 'crop' is NULL, subsequently queued buffers won't be cropped.\n *\n * An error is returned if for instance the crop region is invalid, out of the\n * buffer's bound or if the window is invalid.\n */\nstatic inline int native_window_set_crop(\n        struct ANativeWindow* window,\n        android_native_rect_t const * crop)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_CROP, crop);\n}\n\n/*\n * native_window_set_post_transform_crop(..., crop)\n * Sets which region of the next queued buffers needs to be considered.\n * Depending on the scaling mode, a buffer's crop region is scaled and/or\n * cropped to match the surface's size.  This function sets the crop in\n * post-transformed pixel coordinates.\n *\n * The specified crop region applies to all buffers queued after it is called.\n *\n * If 'crop' is NULL, subsequently queued buffers won't be cropped.\n *\n * An error is returned if for instance the crop region is invalid, out of the\n * buffer's bound or if the window is invalid.\n */\nstatic inline int native_window_set_post_transform_crop(\n        struct ANativeWindow* window,\n        android_native_rect_t const * crop)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_POST_TRANSFORM_CROP, crop);\n}\n\n/*\n * native_window_set_active_rect(..., active_rect)\n *\n * This function is deprecated and will be removed soon.  For now it simply\n * sets the post-transform crop for compatibility while multi-project commits\n * get checked.\n */\nstatic inline int native_window_set_active_rect(\n        struct ANativeWindow* window,\n        android_native_rect_t const * active_rect) __deprecated;\n\nstatic inline int native_window_set_active_rect(\n        struct ANativeWindow* window,\n        android_native_rect_t const * active_rect)\n{\n    return native_window_set_post_transform_crop(window, active_rect);\n}\n\n/*\n * native_window_set_buffer_count(..., count)\n * Sets the number of buffers associated with this native window.\n */\nstatic inline int native_window_set_buffer_count(\n        struct ANativeWindow* window,\n        size_t bufferCount)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_BUFFER_COUNT, bufferCount);\n}\n\n/*\n * native_window_set_buffers_geometry(..., int w, int h, int format)\n * All buffers dequeued after this call will have the dimensions and format\n * specified.  A successful call to this function has the same effect as calling\n * native_window_set_buffers_size and native_window_set_buffers_format.\n *\n * XXX: This function is deprecated.  The native_window_set_buffers_dimensions\n * and native_window_set_buffers_format functions should be used instead.\n */\nstatic inline int native_window_set_buffers_geometry(\n        struct ANativeWindow* window,\n        int w, int h, int format) __deprecated;\n\nstatic inline int native_window_set_buffers_geometry(\n        struct ANativeWindow* window,\n        int w, int h, int format)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,\n            w, h, format);\n}\n\n/*\n * native_window_set_buffers_dimensions(..., int w, int h)\n * All buffers dequeued after this call will have the dimensions specified.\n * In particular, all buffers will have a fixed-size, independent from the\n * native-window size. They will be scaled according to the scaling mode\n * (see native_window_set_scaling_mode) upon window composition.\n *\n * If w and h are 0, the normal behavior is restored. That is, dequeued buffers\n * following this call will be sized to match the window's size.\n *\n * Calling this function will reset the window crop to a NULL value, which\n * disables cropping of the buffers.\n */\nstatic inline int native_window_set_buffers_dimensions(\n        struct ANativeWindow* window,\n        int w, int h)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS,\n            w, h);\n}\n\n/*\n * native_window_set_buffers_user_dimensions(..., int w, int h)\n *\n * Sets the user buffer size for the window, which overrides the\n * window's size.  All buffers dequeued after this call will have the\n * dimensions specified unless overridden by\n * native_window_set_buffers_dimensions.  All buffers will have a\n * fixed-size, independent from the native-window size. They will be\n * scaled according to the scaling mode (see\n * native_window_set_scaling_mode) upon window composition.\n *\n * If w and h are 0, the normal behavior is restored. That is, the\n * default buffer size will match the windows's size.\n *\n * Calling this function will reset the window crop to a NULL value, which\n * disables cropping of the buffers.\n */\nstatic inline int native_window_set_buffers_user_dimensions(\n        struct ANativeWindow* window,\n        int w, int h)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS,\n            w, h);\n}\n\n/*\n * native_window_set_buffers_format(..., int format)\n * All buffers dequeued after this call will have the format specified.\n *\n * If the specified format is 0, the default buffer format will be used.\n */\nstatic inline int native_window_set_buffers_format(\n        struct ANativeWindow* window,\n        int format)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_FORMAT, format);\n}\n\n/*\n * native_window_set_buffers_data_space(..., int dataSpace)\n * All buffers queued after this call will be associated with the dataSpace\n * parameter specified.\n *\n * dataSpace specifies additional information about the buffer that's dependent\n * on the buffer format and the endpoints. For example, it can be used to convey\n * the color space of the image data in the buffer, or it can be used to\n * indicate that the buffers contain depth measurement data instead of color\n * images.  The default dataSpace is 0, HAL_DATASPACE_UNKNOWN, unless it has been\n * overridden by the consumer.\n */\nstatic inline int native_window_set_buffers_data_space(\n        struct ANativeWindow* window,\n        android_dataspace_t dataSpace)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_DATASPACE,\n            dataSpace);\n}\n\n/*\n * native_window_set_buffers_transform(..., int transform)\n * All buffers queued after this call will be displayed transformed according\n * to the transform parameter specified.\n */\nstatic inline int native_window_set_buffers_transform(\n        struct ANativeWindow* window,\n        int transform)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM,\n            transform);\n}\n\n/*\n * native_window_set_buffers_sticky_transform(..., int transform)\n * All buffers queued after this call will be displayed transformed according\n * to the transform parameter specified applied on top of the regular buffer\n * transform.  Setting this transform will disable the transform hint.\n *\n * Temporary - This is only intended to be used by the LEGACY camera mode, do\n *   not use this for anything else.\n */\nstatic inline int native_window_set_buffers_sticky_transform(\n        struct ANativeWindow* window,\n        int transform)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM,\n            transform);\n}\n\n/*\n * native_window_set_buffers_timestamp(..., int64_t timestamp)\n * All buffers queued after this call will be associated with the timestamp\n * parameter specified. If the timestamp is set to NATIVE_WINDOW_TIMESTAMP_AUTO\n * (the default), timestamps will be generated automatically when queueBuffer is\n * called. The timestamp is measured in nanoseconds, and is normally monotonically\n * increasing. The timestamp should be unaffected by time-of-day adjustments,\n * and for a camera should be strictly monotonic but for a media player may be\n * reset when the position is set.\n */\nstatic inline int native_window_set_buffers_timestamp(\n        struct ANativeWindow* window,\n        int64_t timestamp)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP,\n            timestamp);\n}\n\n/*\n * native_window_set_scaling_mode(..., int mode)\n * All buffers queued after this call will be associated with the scaling mode\n * specified.\n */\nstatic inline int native_window_set_scaling_mode(\n        struct ANativeWindow* window,\n        int mode)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_SCALING_MODE,\n            mode);\n}\n\n/*\n * native_window_api_connect(..., int api)\n * connects an API to this window. only one API can be connected at a time.\n * Returns -EINVAL if for some reason the window cannot be connected, which\n * can happen if it's connected to some other API.\n */\nstatic inline int native_window_api_connect(\n        struct ANativeWindow* window, int api)\n{\n    return window->perform(window, NATIVE_WINDOW_API_CONNECT, api);\n}\n\n/*\n * native_window_api_disconnect(..., int api)\n * disconnect the API from this window.\n * An error is returned if for instance the window wasn't connected in the\n * first place.\n */\nstatic inline int native_window_api_disconnect(\n        struct ANativeWindow* window, int api)\n{\n    return window->perform(window, NATIVE_WINDOW_API_DISCONNECT, api);\n}\n\n/*\n * native_window_dequeue_buffer_and_wait(...)\n * Dequeue a buffer and wait on the fence associated with that buffer.  The\n * buffer may safely be accessed immediately upon this function returning.  An\n * error is returned if either of the dequeue or the wait operations fail.\n */\nstatic inline int native_window_dequeue_buffer_and_wait(ANativeWindow *anw,\n        struct ANativeWindowBuffer** anb) {\n    return anw->dequeueBuffer_DEPRECATED(anw, anb);\n}\n\n/*\n * native_window_set_sideband_stream(..., native_handle_t*)\n * Attach a sideband buffer stream to a native window.\n */\nstatic inline int native_window_set_sideband_stream(\n        struct ANativeWindow* window,\n        native_handle_t* sidebandHandle)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_SIDEBAND_STREAM,\n            sidebandHandle);\n}\n\n/*\n * native_window_set_surface_damage(..., android_native_rect_t* rects, int numRects)\n * Set the surface damage (i.e., the region of the surface that has changed\n * since the previous frame). The damage set by this call will be reset (to the\n * default of full-surface damage) after calling queue, so this must be called\n * prior to every frame with damage that does not cover the whole surface if the\n * caller desires downstream consumers to use this optimization.\n *\n * The damage region is specified as an array of rectangles, with the important\n * caveat that the origin of the surface is considered to be the bottom-left\n * corner, as in OpenGL ES.\n *\n * If numRects is set to 0, rects may be NULL, and the surface damage will be\n * set to the full surface (the same as if this function had not been called for\n * this frame).\n */\nstatic inline int native_window_set_surface_damage(\n        struct ANativeWindow* window,\n        const android_native_rect_t* rects, size_t numRects)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_SURFACE_DAMAGE,\n            rects, numRects);\n}\n\n/*\n * native_window_set_shared_buffer_mode(..., bool sharedBufferMode)\n * Enable/disable shared buffer mode\n */\nstatic inline int native_window_set_shared_buffer_mode(\n        struct ANativeWindow* window,\n        bool sharedBufferMode)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_SHARED_BUFFER_MODE,\n            sharedBufferMode);\n}\n\n/*\n * native_window_set_auto_refresh(..., autoRefresh)\n * Enable/disable auto refresh when in shared buffer mode\n */\nstatic inline int native_window_set_auto_refresh(\n        struct ANativeWindow* window,\n        bool autoRefresh)\n{\n    return window->perform(window, NATIVE_WINDOW_SET_AUTO_REFRESH, autoRefresh);\n}\n\n__END_DECLS\n\n#endif /* SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/sysutils/FrameworkClient.h",
    "content": "#ifndef _FRAMEWORK_CLIENT_H\n#define _FRAMEWORK_CLIENT_H\n\n#include \"List.h\"\n\n#include <pthread.h>\n\nclass FrameworkClient {\n    int             mSocket;\n    pthread_mutex_t mWriteMutex;\n\npublic:\n    FrameworkClient(int sock);\n    virtual ~FrameworkClient() {}\n\n    int sendMsg(const char *msg);\n    int sendMsg(const char *msg, const char *data);\n};\n\ntypedef android::sysutils::List<FrameworkClient *> FrameworkClientCollection;\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/sysutils/FrameworkCommand.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n#ifndef __FRAMEWORK_CMD_HANDLER_H\n#define __FRAMEWORK_CMD_HANDLER_H\n\n#include \"List.h\"\n\nclass SocketClient;\n\nclass FrameworkCommand { \nprivate:\n    const char *mCommand;\n\npublic:\n\n    FrameworkCommand(const char *cmd);\n    virtual ~FrameworkCommand() { }\n\n    virtual int runCommand(SocketClient *c, int argc, char **argv) = 0;\n\n    const char *getCommand() { return mCommand; }\n};\n\ntypedef android::sysutils::List<FrameworkCommand *> FrameworkCommandCollection;\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/sysutils/FrameworkListener.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n#ifndef _FRAMEWORKSOCKETLISTENER_H\n#define _FRAMEWORKSOCKETLISTENER_H\n\n#include \"SocketListener.h\"\n#include \"FrameworkCommand.h\"\n\nclass SocketClient;\n\nclass FrameworkListener : public SocketListener {\npublic:\n    static const int CMD_ARGS_MAX = 26;\n\n    /* 1 out of errorRate will be dropped */\n    int errorRate;\n\nprivate:\n    int mCommandCount;\n    bool mWithSeq;\n    FrameworkCommandCollection *mCommands;\n\npublic:\n    FrameworkListener(const char *socketName);\n    FrameworkListener(const char *socketName, bool withSeq);\n    FrameworkListener(int sock);\n    virtual ~FrameworkListener() {}\n\nprotected:\n    void registerCmd(FrameworkCommand *cmd);\n    virtual bool onDataAvailable(SocketClient *c);\n\nprivate:\n    void dispatchCommand(SocketClient *c, char *data);\n    void init(const char *socketName, bool withSeq);\n};\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/sysutils/List.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Templated list class.  Normally we'd use STL, but we don't have that.\n// This class mimics STL's interfaces.\n//\n// Objects are copied into the list with the '=' operator or with copy-\n// construction, so if the compiler's auto-generated versions won't work for\n// you, define your own.\n//\n// The only class you want to use from here is \"List\".\n//\n#ifndef _SYSUTILS_LIST_H\n#define _SYSUTILS_LIST_H\n\n#include <stddef.h>\n#include <stdint.h>\n\nnamespace android {\nnamespace sysutils {\n\n/*\n * Doubly-linked list.  Instantiate with \"List<MyClass> myList\".\n *\n * Objects added to the list are copied using the assignment operator,\n * so this must be defined.\n */\ntemplate<typename T> \nclass List \n{\nprotected:\n    /*\n     * One element in the list.\n     */\n    class _Node {\n    public:\n        explicit _Node(const T& val) : mVal(val) {}\n        ~_Node() {}\n        inline T& getRef() { return mVal; }\n        inline const T& getRef() const { return mVal; }\n        inline _Node* getPrev() const { return mpPrev; }\n        inline _Node* getNext() const { return mpNext; }\n        inline void setVal(const T& val) { mVal = val; }\n        inline void setPrev(_Node* ptr) { mpPrev = ptr; }\n        inline void setNext(_Node* ptr) { mpNext = ptr; }\n    private:\n        friend class List;\n        friend class _ListIterator;\n        T           mVal;\n        _Node*      mpPrev;\n        _Node*      mpNext;\n    };\n\n    /*\n     * Iterator for walking through the list.\n     */\n    \n    template <typename TYPE>\n    struct CONST_ITERATOR {\n        typedef _Node const * NodePtr;\n        typedef const TYPE Type;\n    };\n    \n    template <typename TYPE>\n    struct NON_CONST_ITERATOR {\n        typedef _Node* NodePtr;\n        typedef TYPE Type;\n    };\n    \n    template<\n        typename U,\n        template <class> class Constness\n    > \n    class _ListIterator {\n        typedef _ListIterator<U, Constness>     _Iter;\n        typedef typename Constness<U>::NodePtr  _NodePtr;\n        typedef typename Constness<U>::Type     _Type;\n\n        explicit _ListIterator(_NodePtr ptr) : mpNode(ptr) {}\n\n    public:\n        _ListIterator() {}\n        _ListIterator(const _Iter& rhs) : mpNode(rhs.mpNode) {}\n        ~_ListIterator() {}\n        \n        // this will handle conversions from iterator to const_iterator\n        // (and also all convertible iterators)\n        // Here, in this implementation, the iterators can be converted\n        // if the nodes can be converted\n        template<typename V> explicit \n        _ListIterator(const V& rhs) : mpNode(rhs.mpNode) {}\n        \n\n        /*\n         * Dereference operator.  Used to get at the juicy insides.\n         */\n        _Type& operator*() const { return mpNode->getRef(); }\n        _Type* operator->() const { return &(mpNode->getRef()); }\n\n        /*\n         * Iterator comparison.\n         */\n        inline bool operator==(const _Iter& right) const { \n            return mpNode == right.mpNode; }\n        \n        inline bool operator!=(const _Iter& right) const { \n            return mpNode != right.mpNode; }\n\n        /*\n         * handle comparisons between iterator and const_iterator\n         */\n        template<typename OTHER>\n        inline bool operator==(const OTHER& right) const { \n            return mpNode == right.mpNode; }\n        \n        template<typename OTHER>\n        inline bool operator!=(const OTHER& right) const { \n            return mpNode != right.mpNode; }\n\n        /*\n         * Incr/decr, used to move through the list.\n         */\n        inline _Iter& operator++() {     // pre-increment\n            mpNode = mpNode->getNext();\n            return *this;\n        }\n        const _Iter operator++(int) {    // post-increment\n            _Iter tmp(*this);\n            mpNode = mpNode->getNext();\n            return tmp;\n        }\n        inline _Iter& operator--() {     // pre-increment\n            mpNode = mpNode->getPrev();\n            return *this;\n        }\n        const _Iter operator--(int) {   // post-increment\n            _Iter tmp(*this);\n            mpNode = mpNode->getPrev();\n            return tmp;\n        }\n\n        inline _NodePtr getNode() const { return mpNode; }\n\n        _NodePtr mpNode;    /* should be private, but older gcc fails */\n    private:\n        friend class List;\n    };\n\npublic:\n    List() {\n        prep();\n    }\n    List(const List<T>& src) {      // copy-constructor\n        prep();\n        insert(begin(), src.begin(), src.end());\n    }\n    virtual ~List() {\n        clear();\n        delete[] (unsigned char*) mpMiddle;\n    }\n\n    typedef _ListIterator<T, NON_CONST_ITERATOR> iterator;\n    typedef _ListIterator<T, CONST_ITERATOR> const_iterator;\n\n    List<T>& operator=(const List<T>& right);\n\n    /* returns true if the list is empty */\n    inline bool empty() const { return mpMiddle->getNext() == mpMiddle; }\n\n    /* return #of elements in list */\n    size_t size() const {\n        return size_t(distance(begin(), end()));\n    }\n\n    /*\n     * Return the first element or one past the last element.  The\n     * _Node* we're returning is converted to an \"iterator\" by a\n     * constructor in _ListIterator.\n     */\n    inline iterator begin() { \n        return iterator(mpMiddle->getNext()); \n    }\n    inline const_iterator begin() const { \n        return const_iterator(const_cast<_Node const*>(mpMiddle->getNext())); \n    }\n    inline iterator end() { \n        return iterator(mpMiddle); \n    }\n    inline const_iterator end() const { \n        return const_iterator(const_cast<_Node const*>(mpMiddle)); \n    }\n\n    /* add the object to the head or tail of the list */\n    void push_front(const T& val) { insert(begin(), val); }\n    void push_back(const T& val) { insert(end(), val); }\n\n    /* insert before the current node; returns iterator at new node */\n    iterator insert(iterator posn, const T& val) \n    {\n        _Node* newNode = new _Node(val);        // alloc & copy-construct\n        newNode->setNext(posn.getNode());\n        newNode->setPrev(posn.getNode()->getPrev());\n        posn.getNode()->getPrev()->setNext(newNode);\n        posn.getNode()->setPrev(newNode);\n        return iterator(newNode);\n    }\n\n    /* insert a range of elements before the current node */\n    void insert(iterator posn, const_iterator first, const_iterator last) {\n        for ( ; first != last; ++first)\n            insert(posn, *first);\n    }\n\n    /* remove one entry; returns iterator at next node */\n    iterator erase(iterator posn) {\n        _Node* pNext = posn.getNode()->getNext();\n        _Node* pPrev = posn.getNode()->getPrev();\n        pPrev->setNext(pNext);\n        pNext->setPrev(pPrev);\n        delete posn.getNode();\n        return iterator(pNext);\n    }\n\n    /* remove a range of elements */\n    iterator erase(iterator first, iterator last) {\n        while (first != last)\n            erase(first++);     // don't erase than incr later!\n        return iterator(last);\n    }\n\n    /* remove all contents of the list */\n    void clear() {\n        _Node* pCurrent = mpMiddle->getNext();\n        _Node* pNext;\n\n        while (pCurrent != mpMiddle) {\n            pNext = pCurrent->getNext();\n            delete pCurrent;\n            pCurrent = pNext;\n        }\n        mpMiddle->setPrev(mpMiddle);\n        mpMiddle->setNext(mpMiddle);\n    }\n\n    /*\n     * Measure the distance between two iterators.  On exist, \"first\"\n     * will be equal to \"last\".  The iterators must refer to the same\n     * list.\n     *\n     * FIXME: This is actually a generic iterator function. It should be a \n     * template function at the top-level with specializations for things like\n     * vector<>, which can just do pointer math). Here we limit it to\n     * _ListIterator of the same type but different constness.\n     */\n    template<\n        typename U,\n        template <class> class CL,\n        template <class> class CR\n    > \n    ptrdiff_t distance(\n            _ListIterator<U, CL> first, _ListIterator<U, CR> last) const \n    {\n        ptrdiff_t count = 0;\n        while (first != last) {\n            ++first;\n            ++count;\n        }\n        return count;\n    }\n\nprivate:\n    /*\n     * I want a _Node but don't need it to hold valid data.  More\n     * to the point, I don't want T's constructor to fire, since it\n     * might have side-effects or require arguments.  So, we do this\n     * slightly uncouth storage alloc.\n     */\n    void prep() {\n        mpMiddle = (_Node*) new unsigned char[sizeof(_Node)];\n        mpMiddle->setPrev(mpMiddle);\n        mpMiddle->setNext(mpMiddle);\n    }\n\n    /*\n     * This node plays the role of \"pointer to head\" and \"pointer to tail\".\n     * It sits in the middle of a circular list of nodes.  The iterator\n     * runs around the circle until it encounters this one.\n     */\n    _Node*      mpMiddle;\n};\n\n/*\n * Assignment operator.\n *\n * The simplest way to do this would be to clear out the target list and\n * fill it with the source.  However, we can speed things along by\n * re-using existing elements.\n */\ntemplate<class T>\nList<T>& List<T>::operator=(const List<T>& right)\n{\n    if (this == &right)\n        return *this;       // self-assignment\n    iterator firstDst = begin();\n    iterator lastDst = end();\n    const_iterator firstSrc = right.begin();\n    const_iterator lastSrc = right.end();\n    while (firstSrc != lastSrc && firstDst != lastDst)\n        *firstDst++ = *firstSrc++;\n    if (firstSrc == lastSrc)        // ran out of elements in source?\n        erase(firstDst, lastDst);   // yes, erase any extras\n    else\n        insert(lastDst, firstSrc, lastSrc);     // copy remaining over\n    return *this;\n}\n\n}; // namespace sysutils\n}; // namespace android\n\n#endif // _SYSUTILS_LIST_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/sysutils/NetlinkEvent.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n#ifndef _NETLINKEVENT_H\n#define _NETLINKEVENT_H\n\n#include <sysutils/NetlinkListener.h>\n\n#define NL_PARAMS_MAX 32\n\nclass NetlinkEvent {\npublic:\n    enum class Action {\n        kUnknown = 0,\n        kAdd = 1,\n        kRemove = 2,\n        kChange = 3,\n        kLinkUp = 4,\n        kLinkDown = 5,\n        kAddressUpdated = 6,\n        kAddressRemoved = 7,\n        kRdnss = 8,\n        kRouteUpdated = 9,\n        kRouteRemoved = 10,\n    };\n\nprivate:\n    int  mSeq;\n    char *mPath;\n    Action mAction;\n    char *mSubsystem;\n    char *mParams[NL_PARAMS_MAX];\n\npublic:\n    NetlinkEvent();\n    virtual ~NetlinkEvent();\n\n    bool decode(char *buffer, int size, int format = NetlinkListener::NETLINK_FORMAT_ASCII);\n    const char *findParam(const char *paramName);\n\n    const char *getSubsystem() { return mSubsystem; }\n    Action getAction() { return mAction; }\n\n    void dump();\n\n protected:\n    bool parseBinaryNetlinkMessage(char *buffer, int size);\n    bool parseAsciiNetlinkMessage(char *buffer, int size);\n    bool parseIfInfoMessage(const struct nlmsghdr *nh);\n    bool parseIfAddrMessage(const struct nlmsghdr *nh);\n    bool parseUlogPacketMessage(const struct nlmsghdr *nh);\n    bool parseNfPacketMessage(struct nlmsghdr *nh);\n    bool parseRtMessage(const struct nlmsghdr *nh);\n    bool parseNdUserOptMessage(const struct nlmsghdr *nh);\n};\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/sysutils/NetlinkListener.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n#ifndef _NETLINKLISTENER_H\n#define _NETLINKLISTENER_H\n\n#include \"SocketListener.h\"\n\nclass NetlinkEvent;\n\nclass NetlinkListener : public SocketListener {\n    char mBuffer[64 * 1024] __attribute__((aligned(4)));\n    int mFormat;\n\npublic:\n    static const int NETLINK_FORMAT_ASCII = 0;\n    static const int NETLINK_FORMAT_BINARY = 1;\n    static const int NETLINK_FORMAT_BINARY_UNICAST = 2;\n\n#if 1\n    /* temporary version until we can get Motorola to update their\n     * ril.so.  Their prebuilt ril.so is using this private class\n     * so changing the NetlinkListener() constructor breaks their ril.\n     */\n    NetlinkListener(int socket);\n    NetlinkListener(int socket, int format);\n#else\n    NetlinkListener(int socket, int format = NETLINK_FORMAT_ASCII);\n#endif\n    virtual ~NetlinkListener() {}\n\nprotected:\n    virtual bool onDataAvailable(SocketClient *cli);\n    virtual void onEvent(NetlinkEvent *evt) = 0;\n};\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/sysutils/ServiceManager.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _SERVICE_MANAGER_H\n#define _SERVICE_MANAGER_H\n\nclass ServiceManager {\npublic:\n    ServiceManager();\n    virtual ~ServiceManager() {}\n\n    int start(const char *name);\n    int stop(const char *name);\n    bool isRunning(const char *name);\n};\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/sysutils/SocketClient.h",
    "content": "#ifndef _SOCKET_CLIENT_H\n#define _SOCKET_CLIENT_H\n\n#include \"List.h\"\n\n#include <pthread.h>\n#include <cutils/atomic.h>\n#include <sys/types.h>\n#include <sys/uio.h>\n\nclass SocketClient {\n    int             mSocket;\n    bool            mSocketOwned;\n    pthread_mutex_t mWriteMutex;\n\n    // Peer process ID\n    pid_t mPid;\n\n    // Peer user ID\n    uid_t mUid;\n\n    // Peer group ID\n    gid_t mGid;\n\n    // Reference count (starts at 1)\n    pthread_mutex_t mRefCountMutex;\n    int mRefCount;\n\n    int mCmdNum;\n\n    bool mUseCmdNum;\n\npublic:\n    SocketClient(int sock, bool owned);\n    SocketClient(int sock, bool owned, bool useCmdNum);\n    virtual ~SocketClient();\n\n    int getSocket() { return mSocket; }\n    pid_t getPid() const { return mPid; }\n    uid_t getUid() const { return mUid; }\n    gid_t getGid() const { return mGid; }\n    void setCmdNum(int cmdNum) {\n        android_atomic_release_store(cmdNum, &mCmdNum);\n    }\n    int getCmdNum() { return mCmdNum; }\n\n    // Send null-terminated C strings:\n    int sendMsg(int code, const char *msg, bool addErrno);\n    int sendMsg(int code, const char *msg, bool addErrno, bool useCmdNum);\n    int sendMsg(const char *msg);\n\n    // Provides a mechanism to send a response code to the client.\n    // Sends the code and a null character.\n    int sendCode(int code);\n\n    // Provides a mechanism to send binary data to client.\n    // Sends the code and a null character, followed by 4 bytes of\n    // big-endian length, and the data.\n    int sendBinaryMsg(int code, const void *data, int len);\n\n    // Sending binary data:\n    int sendData(const void *data, int len);\n    // iovec contents not preserved through call\n    int sendDatav(struct iovec *iov, int iovcnt);\n\n    // Optional reference counting.  Reference count starts at 1.  If\n    // it's decremented to 0, it deletes itself.\n    // SocketListener creates a SocketClient (at refcount 1) and calls\n    // decRef() when it's done with the client.\n    void incRef();\n    bool decRef(); // returns true at 0 (but note: SocketClient already deleted)\n\n    // return a new string in quotes with '\\\\' and '\\\"' escaped for \"my arg\"\n    // transmissions\n    static char *quoteArg(const char *arg);\n\nprivate:\n    void init(int socket, bool owned, bool useCmdNum);\n\n    // Sending binary data. The caller should make sure this is protected\n    // from multiple threads entering simultaneously.\n    // returns 0 if successful, -1 if there is a 0 byte write or if any\n    // other error occurred (use errno to get the error)\n    int sendDataLockedv(struct iovec *iov, int iovcnt);\n};\n\ntypedef android::sysutils::List<SocketClient *> SocketClientCollection;\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/sysutils/SocketClientCommand.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n#ifndef _SOCKETCLIENTCOMMAND_H\n#define _SOCKETCLIENTCOMMAND_H\n\n#include <sysutils/SocketClient.h>\n\nclass SocketClientCommand {\npublic:\n    virtual ~SocketClientCommand() { }\n    virtual void runSocketCommand(SocketClient *client) = 0;\n};\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/sysutils/SocketListener.h",
    "content": "/*\n * Copyright (C) 2008-2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n#ifndef _SOCKETLISTENER_H\n#define _SOCKETLISTENER_H\n\n#include <pthread.h>\n\n#include <sysutils/SocketClient.h>\n#include \"SocketClientCommand.h\"\n\nclass SocketListener {\n    bool                    mListen;\n    const char              *mSocketName;\n    int                     mSock;\n    SocketClientCollection  *mClients;\n    pthread_mutex_t         mClientsLock;\n    int                     mCtrlPipe[2];\n    pthread_t               mThread;\n    bool                    mUseCmdNum;\n\npublic:\n    SocketListener(const char *socketName, bool listen);\n    SocketListener(const char *socketName, bool listen, bool useCmdNum);\n    SocketListener(int socketFd, bool listen);\n\n    virtual ~SocketListener();\n    int startListener();\n    int startListener(int backlog);\n    int stopListener();\n\n    void sendBroadcast(int code, const char *msg, bool addErrno);\n\n    void runOnEachSocket(SocketClientCommand *command);\n\n    bool release(SocketClient *c) { return release(c, true); }\n\nprotected:\n    virtual bool onDataAvailable(SocketClient *c) = 0;\n\nprivate:\n    bool release(SocketClient *c, bool wakeup);\n    static void *threadStart(void *obj);\n    void runListener();\n    void init(const char *socketName, int socketFd, bool listen, bool useCmdNum);\n};\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/usbhost/usbhost.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __USB_HOST_H\n#define __USB_HOST_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#include <linux/version.h>\n#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20)\n#include <linux/usb/ch9.h>\n#else\n#include <linux/usb_ch9.h>\n#endif\n\nstruct usb_host_context;\nstruct usb_endpoint_descriptor;\n\nstruct usb_descriptor_iter {\n    unsigned char*  config;\n    unsigned char*  config_end;\n    unsigned char*  curr_desc;\n};\n\nstruct usb_request\n{\n    struct usb_device *dev;\n    void* buffer;\n    int buffer_length;\n    int actual_length;\n    int max_packet_size;\n    void *private_data; /* struct usbdevfs_urb* */\n    int endpoint;\n    void *client_data;  /* free for use by client */\n};\n\n/* Callback for notification when new USB devices are attached.\n * Return true to exit from usb_host_run.\n */\ntypedef int (* usb_device_added_cb)(const char *dev_name, void *client_data);\n\n/* Callback for notification when USB devices are removed.\n * Return true to exit from usb_host_run.\n */\ntypedef int (* usb_device_removed_cb)(const char *dev_name, void *client_data);\n\n/* Callback indicating that initial device discovery is done.\n * Return true to exit from usb_host_run.\n */\ntypedef int (* usb_discovery_done_cb)(void *client_data);\n\n/* Call this to initialize the USB host library. */\nstruct usb_host_context *usb_host_init(void);\n\n/* Call this to cleanup the USB host library. */\nvoid usb_host_cleanup(struct usb_host_context *context);\n\n/* Call this to get the inotify file descriptor. */\nint usb_host_get_fd(struct usb_host_context *context);\n\n/* Call this to initialize the usb host context. */\nint usb_host_load(struct usb_host_context *context,\n                  usb_device_added_cb added_cb,\n                  usb_device_removed_cb removed_cb,\n                  usb_discovery_done_cb discovery_done_cb,\n                  void *client_data);\n\n/* Call this to read and handle occuring usb event. */\nint usb_host_read_event(struct usb_host_context *context);\n\n/* Call this to monitor the USB bus for new and removed devices.\n * This is intended to be called from a dedicated thread,\n * as it will not return until one of the callbacks returns true.\n * added_cb will be called immediately for each existing USB device,\n * and subsequently each time a new device is added.\n * removed_cb is called when USB devices are removed from the bus.\n * discovery_done_cb is called after the initial discovery of already\n * connected devices is complete.\n */\nvoid usb_host_run(struct usb_host_context *context,\n                  usb_device_added_cb added_cb,\n                  usb_device_removed_cb removed_cb,\n                  usb_discovery_done_cb discovery_done_cb,\n                  void *client_data);\n\n/* Creates a usb_device object for a USB device */\nstruct usb_device *usb_device_open(const char *dev_name);\n\n/* Releases all resources associated with the USB device */\nvoid usb_device_close(struct usb_device *device);\n\n/* Creates a usb_device object for already open USB device */\nstruct usb_device *usb_device_new(const char *dev_name, int fd);\n\n/* Returns the file descriptor for the usb_device */\nint usb_device_get_fd(struct usb_device *device);\n\n/* Returns the name for the USB device, which is the same as\n * the dev_name passed to usb_device_open()\n */\nconst char* usb_device_get_name(struct usb_device *device);\n\n/* Returns a unique ID for the device.\n *Currently this is generated from the dev_name path.\n */\nint usb_device_get_unique_id(struct usb_device *device);\n\n/* Returns a unique ID for the device name.\n * Currently this is generated from the device path.\n */\nint usb_device_get_unique_id_from_name(const char* name);\n\n/* Returns the device name for the unique ID.\n * Call free() to deallocate the returned string */\nchar* usb_device_get_name_from_unique_id(int id);\n\n/* Returns the USB vendor ID from the device descriptor for the USB device */\nuint16_t usb_device_get_vendor_id(struct usb_device *device);\n\n/* Returns the USB product ID from the device descriptor for the USB device */\nuint16_t usb_device_get_product_id(struct usb_device *device);\n\nconst struct usb_device_descriptor* usb_device_get_device_descriptor(struct usb_device *device);\n\n/* Returns a USB descriptor string for the given string ID.\n * Used to implement usb_device_get_manufacturer_name,\n * usb_device_get_product_name and usb_device_get_serial.\n * Call free() to free the result when you are done with it.\n */\nchar* usb_device_get_string(struct usb_device *device, int id);\n\n/* Returns the manufacturer name for the USB device.\n * Call free() to free the result when you are done with it.\n */\nchar* usb_device_get_manufacturer_name(struct usb_device *device);\n\n/* Returns the product name for the USB device.\n * Call free() to free the result when you are done with it.\n */\nchar* usb_device_get_product_name(struct usb_device *device);\n\n/* Returns the version number for the USB device.\n */\nint usb_device_get_version(struct usb_device *device);\n\n/* Returns the USB serial number for the USB device.\n * Call free() to free the result when you are done with it.\n */\nchar* usb_device_get_serial(struct usb_device *device);\n\n/* Returns true if we have write access to the USB device,\n * and false if we only have access to the USB device configuration.\n */\nint usb_device_is_writeable(struct usb_device *device);\n\n/* Initializes a usb_descriptor_iter, which can be used to iterate through all\n * the USB descriptors for a USB device.\n */\nvoid usb_descriptor_iter_init(struct usb_device *device, struct usb_descriptor_iter *iter);\n\n/* Returns the next USB descriptor for a device, or NULL if we have reached the\n * end of the list.\n */\nstruct usb_descriptor_header *usb_descriptor_iter_next(struct usb_descriptor_iter *iter);\n\n/* Claims the specified interface of a USB device */\nint usb_device_claim_interface(struct usb_device *device, unsigned int interface);\n\n/* Releases the specified interface of a USB device */\nint usb_device_release_interface(struct usb_device *device, unsigned int interface);\n\n/* Requests the kernel to connect or disconnect its driver for the specified interface.\n * This can be used to ask the kernel to disconnect its driver for a device\n * so usb_device_claim_interface can claim it instead.\n */\nint usb_device_connect_kernel_driver(struct usb_device *device,\n        unsigned int interface, int connect);\n\n/* Sets the current configuration for the device to the specified configuration */\nint usb_device_set_configuration(struct usb_device *device, int configuration);\n\n/* Sets the specified interface of a USB device */\nint usb_device_set_interface(struct usb_device *device, unsigned int interface,\n                            unsigned int alt_setting);\n\n/* Sends a control message to the specified device on endpoint zero */\nint usb_device_control_transfer(struct usb_device *device,\n                            int requestType,\n                            int request,\n                            int value,\n                            int index,\n                            void* buffer,\n                            int length,\n                            unsigned int timeout);\n\n/* Reads or writes on a bulk endpoint.\n * Returns number of bytes transferred, or negative value for error.\n */\nint usb_device_bulk_transfer(struct usb_device *device,\n                            int endpoint,\n                            void* buffer,\n                            int length,\n                            unsigned int timeout);\n\n/** Reset USB bus for the device */\nint usb_device_reset(struct usb_device *device);\n\n/* Creates a new usb_request. */\nstruct usb_request *usb_request_new(struct usb_device *dev,\n        const struct usb_endpoint_descriptor *ep_desc);\n\n/* Releases all resources associated with the request */\nvoid usb_request_free(struct usb_request *req);\n\n/* Submits a read or write request on the specified device */\nint usb_request_queue(struct usb_request *req);\n\n /* Waits for the results of a previous usb_request_queue operation.\n  * Returns a usb_request, or NULL for error.\n  */\nstruct usb_request *usb_request_wait(struct usb_device *dev);\n\n/* Cancels a pending usb_request_queue() operation. */\nint usb_request_cancel(struct usb_request *req);\n\n#ifdef __cplusplus\n}\n#endif\n#endif /* __USB_HOST_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/AndroidThreads.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBS_UTILS_ANDROID_THREADS_H\n#define _LIBS_UTILS_ANDROID_THREADS_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#if !defined(_WIN32)\n# include <pthread.h>\n#endif\n\n#include <utils/ThreadDefs.h>\n\n// ---------------------------------------------------------------------------\n// C API\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// Create and run a new thread.\nextern int androidCreateThread(android_thread_func_t, void *);\n\n// Create thread with lots of parameters\nextern int androidCreateThreadEtc(android_thread_func_t entryFunction,\n                                  void *userData,\n                                  const char* threadName,\n                                  int32_t threadPriority,\n                                  size_t threadStackSize,\n                                  android_thread_id_t *threadId);\n\n// Get some sort of unique identifier for the current thread.\nextern android_thread_id_t androidGetThreadId();\n\n// Low-level thread creation -- never creates threads that can\n// interact with the Java VM.\nextern int androidCreateRawThreadEtc(android_thread_func_t entryFunction,\n                                     void *userData,\n                                     const char* threadName,\n                                     int32_t threadPriority,\n                                     size_t threadStackSize,\n                                     android_thread_id_t *threadId);\n\n// set the same of the running thread\nextern void androidSetThreadName(const char* name);\n\n// Used by the Java Runtime to control how threads are created, so that\n// they can be proper and lovely Java threads.\ntypedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,\n                                        void *userData,\n                                        const char* threadName,\n                                        int32_t threadPriority,\n                                        size_t threadStackSize,\n                                        android_thread_id_t *threadId);\n\nextern void androidSetCreateThreadFunc(android_create_thread_fn func);\n\n// ------------------------------------------------------------------\n// Extra functions working with raw pids.\n\n#if defined(__ANDROID__)\n// Change the priority AND scheduling group of a particular thread.  The priority\n// should be one of the ANDROID_PRIORITY constants.  Returns INVALID_OPERATION\n// if the priority set failed, else another value if just the group set failed;\n// in either case errno is set.  Thread ID zero means current thread.\nextern int androidSetThreadPriority(pid_t tid, int prio);\n\n// Get the current priority of a particular thread. Returns one of the\n// ANDROID_PRIORITY constants or a negative result in case of error.\nextern int androidGetThreadPriority(pid_t tid);\n#endif\n\n#ifdef __cplusplus\n} // extern \"C\"\n#endif\n\n// ----------------------------------------------------------------------------\n// C++ API\n#ifdef __cplusplus\nnamespace android {\n// ----------------------------------------------------------------------------\n\n// Create and run a new thread.\ninline bool createThread(thread_func_t f, void *a) {\n    return androidCreateThread(f, a) ? true : false;\n}\n\n// Create thread with lots of parameters\ninline bool createThreadEtc(thread_func_t entryFunction,\n                            void *userData,\n                            const char* threadName = \"android:unnamed_thread\",\n                            int32_t threadPriority = PRIORITY_DEFAULT,\n                            size_t threadStackSize = 0,\n                            thread_id_t *threadId = 0)\n{\n    return androidCreateThreadEtc(entryFunction, userData, threadName,\n        threadPriority, threadStackSize, threadId) ? true : false;\n}\n\n// Get some sort of unique identifier for the current thread.\ninline thread_id_t getThreadId() {\n    return androidGetThreadId();\n}\n\n// ----------------------------------------------------------------------------\n}; // namespace android\n#endif  // __cplusplus\n// ----------------------------------------------------------------------------\n\n#endif // _LIBS_UTILS_ANDROID_THREADS_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Atomic.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UTILS_ATOMIC_H\n#define ANDROID_UTILS_ATOMIC_H\n\n#include <cutils/atomic.h>\n\n#endif // ANDROID_UTILS_ATOMIC_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/BitSet.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef UTILS_BITSET_H\n#define UTILS_BITSET_H\n\n#include <stdint.h>\n#include <utils/TypeHelpers.h>\n\n/*\n * Contains some bit manipulation helpers.\n */\n\nnamespace android {\n\n// A simple set of 32 bits that can be individually marked or cleared.\nstruct BitSet32 {\n    uint32_t value;\n\n    inline BitSet32() : value(0UL) { }\n    explicit inline BitSet32(uint32_t value) : value(value) { }\n\n    // Gets the value associated with a particular bit index.\n    static inline uint32_t valueForBit(uint32_t n) { return 0x80000000UL >> n; }\n\n    // Clears the bit set.\n    inline void clear() { clear(value); }\n\n    static inline void clear(uint32_t& value) { value = 0UL; }\n\n    // Returns the number of marked bits in the set.\n    inline uint32_t count() const { return count(value); }\n\n    static inline uint32_t count(uint32_t value) { return __builtin_popcountl(value); }\n\n    // Returns true if the bit set does not contain any marked bits.\n    inline bool isEmpty() const { return isEmpty(value); }\n\n    static inline bool isEmpty(uint32_t value) { return ! value; }\n\n    // Returns true if the bit set does not contain any unmarked bits.\n    inline bool isFull() const { return isFull(value); }\n\n    static inline bool isFull(uint32_t value) { return value == 0xffffffffUL; }\n\n    // Returns true if the specified bit is marked.\n    inline bool hasBit(uint32_t n) const { return hasBit(value, n); }\n\n    static inline bool hasBit(uint32_t value, uint32_t n) { return value & valueForBit(n); }\n\n    // Marks the specified bit.\n    inline void markBit(uint32_t n) { markBit(value, n); }\n\n    static inline void markBit (uint32_t& value, uint32_t n) { value |= valueForBit(n); }\n\n    // Clears the specified bit.\n    inline void clearBit(uint32_t n) { clearBit(value, n); }\n\n    static inline void clearBit(uint32_t& value, uint32_t n) { value &= ~ valueForBit(n); }\n\n    // Finds the first marked bit in the set.\n    // Result is undefined if all bits are unmarked.\n    inline uint32_t firstMarkedBit() const { return firstMarkedBit(value); }\n\n    static uint32_t firstMarkedBit(uint32_t value) { return clz_checked(value); }\n\n    // Finds the first unmarked bit in the set.\n    // Result is undefined if all bits are marked.\n    inline uint32_t firstUnmarkedBit() const { return firstUnmarkedBit(value); }\n\n    static inline uint32_t firstUnmarkedBit(uint32_t value) { return clz_checked(~ value); }\n\n    // Finds the last marked bit in the set.\n    // Result is undefined if all bits are unmarked.\n    inline uint32_t lastMarkedBit() const { return lastMarkedBit(value); }\n\n    static inline uint32_t lastMarkedBit(uint32_t value) { return 31 - ctz_checked(value); }\n\n    // Finds the first marked bit in the set and clears it.  Returns the bit index.\n    // Result is undefined if all bits are unmarked.\n    inline uint32_t clearFirstMarkedBit() { return clearFirstMarkedBit(value); }\n\n    static inline uint32_t clearFirstMarkedBit(uint32_t& value) {\n        uint32_t n = firstMarkedBit(value);\n        clearBit(value, n);\n        return n;\n    }\n\n    // Finds the first unmarked bit in the set and marks it.  Returns the bit index.\n    // Result is undefined if all bits are marked.\n    inline uint32_t markFirstUnmarkedBit() { return markFirstUnmarkedBit(value); }\n\n    static inline uint32_t markFirstUnmarkedBit(uint32_t& value) {\n        uint32_t n = firstUnmarkedBit(value);\n        markBit(value, n);\n        return n;\n    }\n\n    // Finds the last marked bit in the set and clears it.  Returns the bit index.\n    // Result is undefined if all bits are unmarked.\n    inline uint32_t clearLastMarkedBit() { return clearLastMarkedBit(value); }\n\n    static inline uint32_t clearLastMarkedBit(uint32_t& value) {\n        uint32_t n = lastMarkedBit(value);\n        clearBit(value, n);\n        return n;\n    }\n\n    // Gets the index of the specified bit in the set, which is the number of\n    // marked bits that appear before the specified bit.\n    inline uint32_t getIndexOfBit(uint32_t n) const {\n        return getIndexOfBit(value, n);\n    }\n\n    static inline uint32_t getIndexOfBit(uint32_t value, uint32_t n) {\n        return __builtin_popcountl(value & ~(0xffffffffUL >> n));\n    }\n\n    inline bool operator== (const BitSet32& other) const { return value == other.value; }\n    inline bool operator!= (const BitSet32& other) const { return value != other.value; }\n    inline BitSet32 operator& (const BitSet32& other) const {\n        return BitSet32(value & other.value);\n    }\n    inline BitSet32& operator&= (const BitSet32& other) {\n        value &= other.value;\n        return *this;\n    }\n    inline BitSet32 operator| (const BitSet32& other) const {\n        return BitSet32(value | other.value);\n    }\n    inline BitSet32& operator|= (const BitSet32& other) {\n        value |= other.value;\n        return *this;\n    }\n\nprivate:\n    // We use these helpers as the signature of __builtin_c{l,t}z has \"unsigned int\" for the\n    // input, which is only guaranteed to be 16b, not 32. The compiler should optimize this away.\n    static inline uint32_t clz_checked(uint32_t value) {\n        if (sizeof(unsigned int) == sizeof(uint32_t)) {\n            return __builtin_clz(value);\n        } else {\n            return __builtin_clzl(value);\n        }\n    }\n\n    static inline uint32_t ctz_checked(uint32_t value) {\n        if (sizeof(unsigned int) == sizeof(uint32_t)) {\n            return __builtin_ctz(value);\n        } else {\n            return __builtin_ctzl(value);\n        }\n    }\n};\n\nANDROID_BASIC_TYPES_TRAITS(BitSet32)\n\n// A simple set of 64 bits that can be individually marked or cleared.\nstruct BitSet64 {\n    uint64_t value;\n\n    inline BitSet64() : value(0ULL) { }\n    explicit inline BitSet64(uint64_t value) : value(value) { }\n\n    // Gets the value associated with a particular bit index.\n    static inline uint64_t valueForBit(uint32_t n) { return 0x8000000000000000ULL >> n; }\n\n    // Clears the bit set.\n    inline void clear() { clear(value); }\n\n    static inline void clear(uint64_t& value) { value = 0ULL; }\n\n    // Returns the number of marked bits in the set.\n    inline uint32_t count() const { return count(value); }\n\n    static inline uint32_t count(uint64_t value) { return __builtin_popcountll(value); }\n\n    // Returns true if the bit set does not contain any marked bits.\n    inline bool isEmpty() const { return isEmpty(value); }\n\n    static inline bool isEmpty(uint64_t value) { return ! value; }\n\n    // Returns true if the bit set does not contain any unmarked bits.\n    inline bool isFull() const { return isFull(value); }\n\n    static inline bool isFull(uint64_t value) { return value == 0xffffffffffffffffULL; }\n\n    // Returns true if the specified bit is marked.\n    inline bool hasBit(uint32_t n) const { return hasBit(value, n); }\n\n    static inline bool hasBit(uint64_t value, uint32_t n) { return value & valueForBit(n); }\n\n    // Marks the specified bit.\n    inline void markBit(uint32_t n) { markBit(value, n); }\n\n    static inline void markBit(uint64_t& value, uint32_t n) { value |= valueForBit(n); }\n\n    // Clears the specified bit.\n    inline void clearBit(uint32_t n) { clearBit(value, n); }\n\n    static inline void clearBit(uint64_t& value, uint32_t n) { value &= ~ valueForBit(n); }\n\n    // Finds the first marked bit in the set.\n    // Result is undefined if all bits are unmarked.\n    inline uint32_t firstMarkedBit() const { return firstMarkedBit(value); }\n\n    static inline uint32_t firstMarkedBit(uint64_t value) { return __builtin_clzll(value); }\n\n    // Finds the first unmarked bit in the set.\n    // Result is undefined if all bits are marked.\n    inline uint32_t firstUnmarkedBit() const { return firstUnmarkedBit(value); }\n\n    static inline uint32_t firstUnmarkedBit(uint64_t value) { return __builtin_clzll(~ value); }\n\n    // Finds the last marked bit in the set.\n    // Result is undefined if all bits are unmarked.\n    inline uint32_t lastMarkedBit() const { return lastMarkedBit(value); }\n\n    static inline uint32_t lastMarkedBit(uint64_t value) { return 63 - __builtin_ctzll(value); }\n\n    // Finds the first marked bit in the set and clears it.  Returns the bit index.\n    // Result is undefined if all bits are unmarked.\n    inline uint32_t clearFirstMarkedBit() { return clearFirstMarkedBit(value); }\n\n    static inline uint32_t clearFirstMarkedBit(uint64_t& value) {\n        uint64_t n = firstMarkedBit(value);\n        clearBit(value, n);\n        return n;\n    }\n\n    // Finds the first unmarked bit in the set and marks it.  Returns the bit index.\n    // Result is undefined if all bits are marked.\n    inline uint32_t markFirstUnmarkedBit() { return markFirstUnmarkedBit(value); }\n\n    static inline uint32_t markFirstUnmarkedBit(uint64_t& value) {\n        uint64_t n = firstUnmarkedBit(value);\n        markBit(value, n);\n        return n;\n    }\n\n    // Finds the last marked bit in the set and clears it.  Returns the bit index.\n    // Result is undefined if all bits are unmarked.\n    inline uint32_t clearLastMarkedBit() { return clearLastMarkedBit(value); }\n\n    static inline uint32_t clearLastMarkedBit(uint64_t& value) {\n        uint64_t n = lastMarkedBit(value);\n        clearBit(value, n);\n        return n;\n    }\n\n    // Gets the index of the specified bit in the set, which is the number of\n    // marked bits that appear before the specified bit.\n    inline uint32_t getIndexOfBit(uint32_t n) const { return getIndexOfBit(value, n); }\n\n    static inline uint32_t getIndexOfBit(uint64_t value, uint32_t n) {\n        return __builtin_popcountll(value & ~(0xffffffffffffffffULL >> n));\n    }\n\n    inline bool operator== (const BitSet64& other) const { return value == other.value; }\n    inline bool operator!= (const BitSet64& other) const { return value != other.value; }\n    inline BitSet64 operator& (const BitSet64& other) const {\n        return BitSet64(value & other.value);\n    }\n    inline BitSet64& operator&= (const BitSet64& other) {\n        value &= other.value;\n        return *this;\n    }\n    inline BitSet64 operator| (const BitSet64& other) const {\n        return BitSet64(value | other.value);\n    }\n    inline BitSet64& operator|= (const BitSet64& other) {\n        value |= other.value;\n        return *this;\n    }\n};\n\nANDROID_BASIC_TYPES_TRAITS(BitSet64)\n\n} // namespace android\n\n#endif // UTILS_BITSET_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/BlobCache.h",
    "content": "/*\n ** Copyright 2011, The Android Open Source Project\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n\n#ifndef ANDROID_BLOB_CACHE_H\n#define ANDROID_BLOB_CACHE_H\n\n#include <stddef.h>\n\n#include <utils/Flattenable.h>\n#include <utils/RefBase.h>\n#include <utils/SortedVector.h>\n#include <utils/threads.h>\n\nnamespace android {\n\n// A BlobCache is an in-memory cache for binary key/value pairs.  A BlobCache\n// does NOT provide any thread-safety guarantees.\n//\n// The cache contents can be serialized to an in-memory buffer or mmap'd file\n// and then reloaded in a subsequent execution of the program.  This\n// serialization is non-portable and the data should only be used by the device\n// that generated it.\nclass BlobCache : public RefBase {\n\npublic:\n\n    // Create an empty blob cache. The blob cache will cache key/value pairs\n    // with key and value sizes less than or equal to maxKeySize and\n    // maxValueSize, respectively. The total combined size of ALL cache entries\n    // (key sizes plus value sizes) will not exceed maxTotalSize.\n    BlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize);\n\n    // set inserts a new binary value into the cache and associates it with the\n    // given binary key.  If the key or value are too large for the cache then\n    // the cache remains unchanged.  This includes the case where a different\n    // value was previously associated with the given key - the old value will\n    // remain in the cache.  If the given key and value are small enough to be\n    // put in the cache (based on the maxKeySize, maxValueSize, and maxTotalSize\n    // values specified to the BlobCache constructor), then the key/value pair\n    // will be in the cache after set returns.  Note, however, that a subsequent\n    // call to set may evict old key/value pairs from the cache.\n    //\n    // Preconditions:\n    //   key != NULL\n    //   0 < keySize\n    //   value != NULL\n    //   0 < valueSize\n    void set(const void* key, size_t keySize, const void* value,\n            size_t valueSize);\n\n    // get retrieves from the cache the binary value associated with a given\n    // binary key.  If the key is present in the cache then the length of the\n    // binary value associated with that key is returned.  If the value argument\n    // is non-NULL and the size of the cached value is less than valueSize bytes\n    // then the cached value is copied into the buffer pointed to by the value\n    // argument.  If the key is not present in the cache then 0 is returned and\n    // the buffer pointed to by the value argument is not modified.\n    //\n    // Note that when calling get multiple times with the same key, the later\n    // calls may fail, returning 0, even if earlier calls succeeded.  The return\n    // value must be checked for each call.\n    //\n    // Preconditions:\n    //   key != NULL\n    //   0 < keySize\n    //   0 <= valueSize\n    size_t get(const void* key, size_t keySize, void* value, size_t valueSize);\n\n\n    // getFlattenedSize returns the number of bytes needed to store the entire\n    // serialized cache.\n    size_t getFlattenedSize() const;\n\n    // flatten serializes the current contents of the cache into the memory\n    // pointed to by 'buffer'.  The serialized cache contents can later be\n    // loaded into a BlobCache object using the unflatten method.  The contents\n    // of the BlobCache object will not be modified.\n    //\n    // Preconditions:\n    //   size >= this.getFlattenedSize()\n    status_t flatten(void* buffer, size_t size) const;\n\n    // unflatten replaces the contents of the cache with the serialized cache\n    // contents in the memory pointed to by 'buffer'.  The previous contents of\n    // the BlobCache will be evicted from the cache.  If an error occurs while\n    // unflattening the serialized cache contents then the BlobCache will be\n    // left in an empty state.\n    //\n    status_t unflatten(void const* buffer, size_t size);\n\nprivate:\n    // Copying is disallowed.\n    BlobCache(const BlobCache&);\n    void operator=(const BlobCache&);\n\n    // A random function helper to get around MinGW not having nrand48()\n    long int blob_random();\n\n    // clean evicts a randomly chosen set of entries from the cache such that\n    // the total size of all remaining entries is less than mMaxTotalSize/2.\n    void clean();\n\n    // isCleanable returns true if the cache is full enough for the clean method\n    // to have some effect, and false otherwise.\n    bool isCleanable() const;\n\n    // A Blob is an immutable sized unstructured data blob.\n    class Blob : public RefBase {\n    public:\n        Blob(const void* data, size_t size, bool copyData);\n        ~Blob();\n\n        bool operator<(const Blob& rhs) const;\n\n        const void* getData() const;\n        size_t getSize() const;\n\n    private:\n        // Copying is not allowed.\n        Blob(const Blob&);\n        void operator=(const Blob&);\n\n        // mData points to the buffer containing the blob data.\n        const void* mData;\n\n        // mSize is the size of the blob data in bytes.\n        size_t mSize;\n\n        // mOwnsData indicates whether or not this Blob object should free the\n        // memory pointed to by mData when the Blob gets destructed.\n        bool mOwnsData;\n    };\n\n    // A CacheEntry is a single key/value pair in the cache.\n    class CacheEntry {\n    public:\n        CacheEntry();\n        CacheEntry(const sp<Blob>& key, const sp<Blob>& value);\n        CacheEntry(const CacheEntry& ce);\n\n        bool operator<(const CacheEntry& rhs) const;\n        const CacheEntry& operator=(const CacheEntry&);\n\n        sp<Blob> getKey() const;\n        sp<Blob> getValue() const;\n\n        void setValue(const sp<Blob>& value);\n\n    private:\n\n        // mKey is the key that identifies the cache entry.\n        sp<Blob> mKey;\n\n        // mValue is the cached data associated with the key.\n        sp<Blob> mValue;\n    };\n\n    // A Header is the header for the entire BlobCache serialization format. No\n    // need to make this portable, so we simply write the struct out.\n    struct Header {\n        // mMagicNumber is the magic number that identifies the data as\n        // serialized BlobCache contents.  It must always contain 'Blb$'.\n        uint32_t mMagicNumber;\n\n        // mBlobCacheVersion is the serialization format version.\n        uint32_t mBlobCacheVersion;\n\n        // mDeviceVersion is the device-specific version of the cache.  This can\n        // be used to invalidate the cache.\n        uint32_t mDeviceVersion;\n\n        // mNumEntries is number of cache entries following the header in the\n        // data.\n        size_t mNumEntries;\n\n        // mBuildId is the build id of the device when the cache was created.\n        // When an update to the build happens (via an OTA or other update) this\n        // is used to invalidate the cache.\n        int mBuildIdLength;\n        char mBuildId[];\n    };\n\n    // An EntryHeader is the header for a serialized cache entry.  No need to\n    // make this portable, so we simply write the struct out.  Each EntryHeader\n    // is followed imediately by the key data and then the value data.\n    //\n    // The beginning of each serialized EntryHeader is 4-byte aligned, so the\n    // number of bytes that a serialized cache entry will occupy is:\n    //\n    //   ((sizeof(EntryHeader) + keySize + valueSize) + 3) & ~3\n    //\n    struct EntryHeader {\n        // mKeySize is the size of the entry key in bytes.\n        size_t mKeySize;\n\n        // mValueSize is the size of the entry value in bytes.\n        size_t mValueSize;\n\n        // mData contains both the key and value data for the cache entry.  The\n        // key comes first followed immediately by the value.\n        uint8_t mData[];\n    };\n\n    // mMaxKeySize is the maximum key size that will be cached. Calls to\n    // BlobCache::set with a keySize parameter larger than mMaxKeySize will\n    // simply not add the key/value pair to the cache.\n    const size_t mMaxKeySize;\n\n    // mMaxValueSize is the maximum value size that will be cached. Calls to\n    // BlobCache::set with a valueSize parameter larger than mMaxValueSize will\n    // simply not add the key/value pair to the cache.\n    const size_t mMaxValueSize;\n\n    // mMaxTotalSize is the maximum size that all cache entries can occupy. This\n    // includes space for both keys and values. When a call to BlobCache::set\n    // would otherwise cause this limit to be exceeded, either the key/value\n    // pair passed to BlobCache::set will not be cached or other cache entries\n    // will be evicted from the cache to make room for the new entry.\n    const size_t mMaxTotalSize;\n\n    // mTotalSize is the total combined size of all keys and values currently in\n    // the cache.\n    size_t mTotalSize;\n\n    // mRandState is the pseudo-random number generator state. It is passed to\n    // nrand48 to generate random numbers when needed.\n    unsigned short mRandState[3];\n\n    // mCacheEntries stores all the cache entries that are resident in memory.\n    // Cache entries are added to it by the 'set' method.\n    SortedVector<CacheEntry> mCacheEntries;\n};\n\n}\n\n#endif // ANDROID_BLOB_CACHE_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/ByteOrder.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n\n#ifndef _LIBS_UTILS_BYTE_ORDER_H\n#define _LIBS_UTILS_BYTE_ORDER_H\n\n#include <stdint.h>\n#include <sys/types.h>\n#if defined(_WIN32)\n#include <winsock2.h>\n#else\n#include <netinet/in.h>\n#endif\n\n/*\n * These macros are like the hton/ntoh byte swapping macros,\n * except they allow you to swap to and from the \"device\" byte\n * order.  The device byte order is the endianness of the target\n * device -- for the ARM CPUs we use today, this is little endian.\n *\n * Note that the byte swapping functions have not been optimized\n * much; performance is currently not an issue for them since the\n * intent is to allow us to avoid byte swapping on the device.\n */\n\nstatic inline uint32_t android_swap_long(uint32_t v)\n{\n    return (v<<24) | ((v<<8)&0x00FF0000) | ((v>>8)&0x0000FF00) | (v>>24);\n}\n\nstatic inline uint16_t android_swap_short(uint16_t v)\n{\n    return (v<<8) | (v>>8);\n}\n\n#define DEVICE_BYTE_ORDER LITTLE_ENDIAN\n\n#if BYTE_ORDER == DEVICE_BYTE_ORDER\n\n#define\tdtohl(x)\t(x)\n#define\tdtohs(x)\t(x)\n#define\thtodl(x)\t(x)\n#define\thtods(x)\t(x)\n\n#else\n\n#define\tdtohl(x)\t(android_swap_long(x))\n#define\tdtohs(x)\t(android_swap_short(x))\n#define\thtodl(x)\t(android_swap_long(x))\n#define\thtods(x)\t(android_swap_short(x))\n\n#endif\n\n#if BYTE_ORDER == LITTLE_ENDIAN\n#define fromlel(x) (x)\n#define fromles(x) (x)\n#define tolel(x) (x)\n#define toles(x) (x)\n#else\n#define fromlel(x) (android_swap_long(x))\n#define fromles(x) (android_swap_short(x))\n#define tolel(x) (android_swap_long(x))\n#define toles(x) (android_swap_short(x))\n#endif\n\n#endif // _LIBS_UTILS_BYTE_ORDER_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/CallStack.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_CALLSTACK_H\n#define ANDROID_CALLSTACK_H\n\n#include <android/log.h>\n#include <backtrace/backtrace_constants.h>\n#include <utils/String8.h>\n#include <utils/Vector.h>\n\n#include <stdint.h>\n#include <sys/types.h>\n\nnamespace android {\n\nclass Printer;\n\n// Collect/print the call stack (function, file, line) traces for a single thread.\nclass CallStack {\npublic:\n    // Create an empty call stack. No-op.\n    CallStack();\n    // Create a callstack with the current thread's stack trace.\n    // Immediately dump it to logcat using the given logtag.\n    CallStack(const char* logtag, int32_t ignoreDepth=1);\n    ~CallStack();\n\n    // Reset the stack frames (same as creating an empty call stack).\n    void clear() { mFrameLines.clear(); }\n\n    // Immediately collect the stack traces for the specified thread.\n    // The default is to dump the stack of the current call.\n    void update(int32_t ignoreDepth=1, pid_t tid=BACKTRACE_CURRENT_THREAD);\n\n    // Dump a stack trace to the log using the supplied logtag.\n    void log(const char* logtag,\n             android_LogPriority priority = ANDROID_LOG_DEBUG,\n             const char* prefix = 0) const;\n\n    // Dump a stack trace to the specified file descriptor.\n    void dump(int fd, int indent = 0, const char* prefix = 0) const;\n\n    // Return a string (possibly very long) containing the complete stack trace.\n    String8 toString(const char* prefix = 0) const;\n\n    // Dump a serialized representation of the stack trace to the specified printer.\n    void print(Printer& printer) const;\n\n    // Get the count of stack frames that are in this call stack.\n    size_t size() const { return mFrameLines.size(); }\n\nprivate:\n    Vector<String8> mFrameLines;\n};\n\n}; // namespace android\n\n#endif // ANDROID_CALLSTACK_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Compat.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __LIB_UTILS_COMPAT_H\n#define __LIB_UTILS_COMPAT_H\n\n#include <unistd.h>\n\n#if defined(__APPLE__)\n\n/* Mac OS has always had a 64-bit off_t, so it doesn't have off64_t. */\n\ntypedef off_t off64_t;\n\nstatic inline off64_t lseek64(int fd, off64_t offset, int whence) {\n    return lseek(fd, offset, whence);\n}\n\nstatic inline ssize_t pread64(int fd, void* buf, size_t nbytes, off64_t offset) {\n    return pread(fd, buf, nbytes, offset);\n}\n\nstatic inline ssize_t pwrite64(int fd, const void* buf, size_t nbytes, off64_t offset) {\n    return pwrite(fd, buf, nbytes, offset);\n}\n\n#endif /* __APPLE__ */\n\n#if defined(_WIN32)\n#define O_CLOEXEC O_NOINHERIT\n#define O_NOFOLLOW 0\n#define DEFFILEMODE 0666\n#endif /* _WIN32 */\n\n#if defined(_WIN32)\n#define ZD \"%ld\"\n#define ZD_TYPE long\n#else\n#define ZD \"%zd\"\n#define ZD_TYPE ssize_t\n#endif\n\n/*\n * Needed for cases where something should be constexpr if possible, but not\n * being constexpr is fine if in pre-C++11 code (such as a const static float\n * member variable).\n */\n#if __cplusplus >= 201103L\n#define CONSTEXPR constexpr\n#else\n#define CONSTEXPR\n#endif\n\n/*\n * TEMP_FAILURE_RETRY is defined by some, but not all, versions of\n * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's\n * not already defined, then define it here.\n */\n#ifndef TEMP_FAILURE_RETRY\n/* Used to retry syscalls that can return EINTR. */\n#define TEMP_FAILURE_RETRY(exp) ({         \\\n    typeof (exp) _rc;                      \\\n    do {                                   \\\n        _rc = (exp);                       \\\n    } while (_rc == -1 && errno == EINTR); \\\n    _rc; })\n#endif\n\n#if defined(_WIN32)\n#define OS_PATH_SEPARATOR '\\\\'\n#else\n#define OS_PATH_SEPARATOR '/'\n#endif\n\n#endif /* __LIB_UTILS_COMPAT_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Condition.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBS_UTILS_CONDITION_H\n#define _LIBS_UTILS_CONDITION_H\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <time.h>\n\n#if !defined(_WIN32)\n# include <pthread.h>\n#endif\n\n#include <utils/Errors.h>\n#include <utils/Mutex.h>\n#include <utils/Timers.h>\n\n// ---------------------------------------------------------------------------\nnamespace android {\n// ---------------------------------------------------------------------------\n\n/*\n * Condition variable class.  The implementation is system-dependent.\n *\n * Condition variables are paired up with mutexes.  Lock the mutex,\n * call wait(), then either re-wait() if things aren't quite what you want,\n * or unlock the mutex and continue.  All threads calling wait() must\n * use the same mutex for a given Condition.\n */\nclass Condition {\npublic:\n    enum {\n        PRIVATE = 0,\n        SHARED = 1\n    };\n\n    enum WakeUpType {\n        WAKE_UP_ONE = 0,\n        WAKE_UP_ALL = 1\n    };\n\n    Condition();\n    Condition(int type);\n    ~Condition();\n    // Wait on the condition variable.  Lock the mutex before calling.\n    status_t wait(Mutex& mutex);\n    // same with relative timeout\n    status_t waitRelative(Mutex& mutex, nsecs_t reltime);\n    // Signal the condition variable, allowing exactly one thread to continue.\n    void signal();\n    // Signal the condition variable, allowing one or all threads to continue.\n    void signal(WakeUpType type) {\n        if (type == WAKE_UP_ONE) {\n            signal();\n        } else {\n            broadcast();\n        }\n    }\n    // Signal the condition variable, allowing all threads to continue.\n    void broadcast();\n\nprivate:\n#if !defined(_WIN32)\n    pthread_cond_t mCond;\n#else\n    void*   mState;\n#endif\n};\n\n// ---------------------------------------------------------------------------\n\n#if !defined(_WIN32)\n\ninline Condition::Condition() {\n    pthread_cond_init(&mCond, NULL);\n}\ninline Condition::Condition(int type) {\n    if (type == SHARED) {\n        pthread_condattr_t attr;\n        pthread_condattr_init(&attr);\n        pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);\n        pthread_cond_init(&mCond, &attr);\n        pthread_condattr_destroy(&attr);\n    } else {\n        pthread_cond_init(&mCond, NULL);\n    }\n}\ninline Condition::~Condition() {\n    pthread_cond_destroy(&mCond);\n}\ninline status_t Condition::wait(Mutex& mutex) {\n    return -pthread_cond_wait(&mCond, &mutex.mMutex);\n}\ninline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {\n#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)\n    struct timespec ts;\n    ts.tv_sec  = reltime/1000000000;\n    ts.tv_nsec = reltime%1000000000;\n    return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts);\n#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE\n    struct timespec ts;\n#if defined(__linux__)\n    clock_gettime(CLOCK_REALTIME, &ts);\n#else // __APPLE__\n    // we don't support the clocks here.\n    struct timeval t;\n    gettimeofday(&t, NULL);\n    ts.tv_sec = t.tv_sec;\n    ts.tv_nsec= t.tv_usec*1000;\n#endif\n    ts.tv_sec += reltime/1000000000;\n    ts.tv_nsec+= reltime%1000000000;\n    if (ts.tv_nsec >= 1000000000) {\n        ts.tv_nsec -= 1000000000;\n        ts.tv_sec  += 1;\n    }\n    return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts);\n#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE\n}\ninline void Condition::signal() {\n    /*\n     * POSIX says pthread_cond_signal wakes up \"one or more\" waiting threads.\n     * However bionic follows the glibc guarantee which wakes up \"exactly one\"\n     * waiting thread.\n     *\n     * man 3 pthread_cond_signal\n     *   pthread_cond_signal restarts one of the threads that are waiting on\n     *   the condition variable cond. If no threads are waiting on cond,\n     *   nothing happens. If several threads are waiting on cond, exactly one\n     *   is restarted, but it is not specified which.\n     */\n    pthread_cond_signal(&mCond);\n}\ninline void Condition::broadcast() {\n    pthread_cond_broadcast(&mCond);\n}\n\n#endif // !defined(_WIN32)\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n// ---------------------------------------------------------------------------\n\n#endif // _LIBS_UTILS_CONDITON_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Debug.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UTILS_DEBUG_H\n#define ANDROID_UTILS_DEBUG_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\nnamespace android {\n// ---------------------------------------------------------------------------\n\n#ifdef __cplusplus\ntemplate<bool> struct CompileTimeAssert;\ntemplate<> struct CompileTimeAssert<true> {};\n#define COMPILE_TIME_ASSERT(_exp) \\\n    template class CompileTimeAssert< (_exp) >;\n#endif\n#define COMPILE_TIME_ASSERT_FUNCTION_SCOPE(_exp) \\\n    CompileTimeAssert<( _exp )>();\n\n// ---------------------------------------------------------------------------\n\n#ifdef __cplusplus\ntemplate<bool C, typename LSH, typename RHS> struct CompileTimeIfElse;\ntemplate<typename LHS, typename RHS> \nstruct CompileTimeIfElse<true,  LHS, RHS> { typedef LHS TYPE; };\ntemplate<typename LHS, typename RHS> \nstruct CompileTimeIfElse<false, LHS, RHS> { typedef RHS TYPE; };\n#endif\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_UTILS_DEBUG_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Endian.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Android endian-ness defines.\n//\n#ifndef _LIBS_UTILS_ENDIAN_H\n#define _LIBS_UTILS_ENDIAN_H\n\n#if defined(__APPLE__) || defined(_WIN32)\n\n#define __BIG_ENDIAN 0x1000\n#define __LITTLE_ENDIAN 0x0001\n#define __BYTE_ORDER __LITTLE_ENDIAN\n\n#else\n\n#include <endian.h>\n\n#endif\n\n#endif /*_LIBS_UTILS_ENDIAN_H*/\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Errors.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_ERRORS_H\n#define ANDROID_ERRORS_H\n\n#include <sys/types.h>\n#include <errno.h>\n\nnamespace android {\n\n// use this type to return error codes\n#ifdef _WIN32\ntypedef int         status_t;\n#else\ntypedef int32_t     status_t;\n#endif\n\n/* the MS C runtime lacks a few error codes */\n\n/*\n * Error codes. \n * All error codes are negative values.\n */\n\n// Win32 #defines NO_ERROR as well.  It has the same value, so there's no\n// real conflict, though it's a bit awkward.\n#ifdef _WIN32\n# undef NO_ERROR\n#endif\n\nenum {\n    OK                = 0,    // Everything's swell.\n    NO_ERROR          = 0,    // No errors.\n\n    UNKNOWN_ERROR       = (-2147483647-1), // INT32_MIN value\n\n    NO_MEMORY           = -ENOMEM,\n    INVALID_OPERATION   = -ENOSYS,\n    BAD_VALUE           = -EINVAL,\n    BAD_TYPE            = (UNKNOWN_ERROR + 1),\n    NAME_NOT_FOUND      = -ENOENT,\n    PERMISSION_DENIED   = -EPERM,\n    NO_INIT             = -ENODEV,\n    ALREADY_EXISTS      = -EEXIST,\n    DEAD_OBJECT         = -EPIPE,\n    FAILED_TRANSACTION  = (UNKNOWN_ERROR + 2),\n#if !defined(_WIN32)\n    BAD_INDEX           = -EOVERFLOW,\n    NOT_ENOUGH_DATA     = -ENODATA,\n    WOULD_BLOCK         = -EWOULDBLOCK, \n    TIMED_OUT           = -ETIMEDOUT,\n    UNKNOWN_TRANSACTION = -EBADMSG,\n#else    \n    BAD_INDEX           = -E2BIG,\n    NOT_ENOUGH_DATA     = (UNKNOWN_ERROR + 3),\n    WOULD_BLOCK         = (UNKNOWN_ERROR + 4),\n    TIMED_OUT           = (UNKNOWN_ERROR + 5),\n    UNKNOWN_TRANSACTION = (UNKNOWN_ERROR + 6),\n#endif    \n    FDS_NOT_ALLOWED     = (UNKNOWN_ERROR + 7),\n    UNEXPECTED_NULL     = (UNKNOWN_ERROR + 8),\n};\n\n// Restore define; enumeration is in \"android\" namespace, so the value defined\n// there won't work for Win32 code in a different namespace.\n#ifdef _WIN32\n# define NO_ERROR 0L\n#endif\n\n}; // namespace android\n    \n// ---------------------------------------------------------------------------\n    \n#endif // ANDROID_ERRORS_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/FileMap.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Encapsulate a shared file mapping.\n//\n#ifndef __LIBS_FILE_MAP_H\n#define __LIBS_FILE_MAP_H\n\n#include <sys/types.h>\n\n#include <utils/Compat.h>\n\n#if defined(__MINGW32__)\n// Ensure that we always pull in winsock2.h before windows.h\n#if defined(_WIN32)\n#include <winsock2.h>\n#endif\n#include <windows.h>\n#endif\n\nnamespace android {\n\n/*\n * This represents a memory-mapped file.  It might be the entire file or\n * only part of it.  This requires a little bookkeeping because the mapping\n * needs to be aligned on page boundaries, and in some cases we'd like to\n * have multiple references to the mapped area without creating additional\n * maps.\n *\n * This always uses MAP_SHARED.\n *\n * TODO: we should be able to create a new FileMap that is a subset of\n * an existing FileMap and shares the underlying mapped pages.  Requires\n * completing the refcounting stuff and possibly introducing the notion\n * of a FileMap hierarchy.\n */\nclass FileMap {\npublic:\n    FileMap(void);\n\n    FileMap(FileMap&& f);\n    FileMap& operator=(FileMap&& f);\n\n    /*\n     * Create a new mapping on an open file.\n     *\n     * Closing the file descriptor does not unmap the pages, so we don't\n     * claim ownership of the fd.\n     *\n     * Returns \"false\" on failure.\n     */\n    bool create(const char* origFileName, int fd,\n                off64_t offset, size_t length, bool readOnly);\n\n    ~FileMap(void);\n\n    /*\n     * Return the name of the file this map came from, if known.\n     */\n    const char* getFileName(void) const { return mFileName; }\n    \n    /*\n     * Get a pointer to the piece of the file we requested.\n     */\n    void* getDataPtr(void) const { return mDataPtr; }\n\n    /*\n     * Get the length we requested.\n     */\n    size_t getDataLength(void) const { return mDataLength; }\n\n    /*\n     * Get the data offset used to create this map.\n     */\n    off64_t getDataOffset(void) const { return mDataOffset; }\n\n    /*\n     * This maps directly to madvise() values, but allows us to avoid\n     * including <sys/mman.h> everywhere.\n     */\n    enum MapAdvice {\n        NORMAL, RANDOM, SEQUENTIAL, WILLNEED, DONTNEED\n    };\n\n    /*\n     * Apply an madvise() call to the entire file.\n     *\n     * Returns 0 on success, -1 on failure.\n     */\n    int advise(MapAdvice advice);\n\nprotected:\n\nprivate:\n    // these are not implemented\n    FileMap(const FileMap& src);\n    const FileMap& operator=(const FileMap& src);\n\n    char*       mFileName;      // original file name, if known\n    void*       mBasePtr;       // base of mmap area; page aligned\n    size_t      mBaseLength;    // length, measured from \"mBasePtr\"\n    off64_t     mDataOffset;    // offset used when map was created\n    void*       mDataPtr;       // start of requested data, offset from base\n    size_t      mDataLength;    // length, measured from \"mDataPtr\"\n#if defined(__MINGW32__)\n    HANDLE      mFileHandle;    // Win32 file handle\n    HANDLE      mFileMapping;   // Win32 file mapping handle\n#endif\n\n    static long mPageSize;\n};\n\n}; // namespace android\n\n#endif // __LIBS_FILE_MAP_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Flattenable.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UTILS_FLATTENABLE_H\n#define ANDROID_UTILS_FLATTENABLE_H\n\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <utils/Errors.h>\n#include <utils/Debug.h>\n\nnamespace android {\n\n\nclass FlattenableUtils {\npublic:\n    template<int N>\n    static size_t align(size_t size) {\n        COMPILE_TIME_ASSERT_FUNCTION_SCOPE( !(N & (N-1)) );\n        return (size + (N-1)) & ~(N-1);\n    }\n\n    template<int N>\n    static size_t align(void const*& buffer) {\n        COMPILE_TIME_ASSERT_FUNCTION_SCOPE( !(N & (N-1)) );\n        intptr_t b = intptr_t(buffer);\n        buffer = (void*)((intptr_t(buffer) + (N-1)) & ~(N-1));\n        return size_t(intptr_t(buffer) - b);\n    }\n\n    template<int N>\n    static size_t align(void*& buffer) {\n        return align<N>( const_cast<void const*&>(buffer) );\n    }\n\n    static void advance(void*& buffer, size_t& size, size_t offset) {\n        buffer = reinterpret_cast<void*>( intptr_t(buffer) + offset );\n        size -= offset;\n    }\n\n    static void advance(void const*& buffer, size_t& size, size_t offset) {\n        buffer = reinterpret_cast<void const*>( intptr_t(buffer) + offset );\n        size -= offset;\n    }\n\n    // write a POD structure\n    template<typename T>\n    static void write(void*& buffer, size_t& size, const T& value) {\n        *static_cast<T*>(buffer) = value;\n        advance(buffer, size, sizeof(T));\n    }\n\n    // read a POD structure\n    template<typename T>\n    static void read(void const*& buffer, size_t& size, T& value) {\n        value = *static_cast<T const*>(buffer);\n        advance(buffer, size, sizeof(T));\n    }\n};\n\n\n/*\n * The Flattenable protocol allows an object to serialize itself out\n * to a byte-buffer and an array of file descriptors.\n * Flattenable objects must implement this protocol.\n */\n\ntemplate <typename T>\nclass Flattenable {\npublic:\n    // size in bytes of the flattened object\n    inline size_t getFlattenedSize() const;\n\n    // number of file descriptors to flatten\n    inline size_t getFdCount() const;\n\n    // flattens the object into buffer.\n    // size should be at least of getFlattenedSize()\n    // file descriptors are written in the fds[] array but ownership is\n    // not transfered (ie: they must be dupped by the caller of\n    // flatten() if needed).\n    inline status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;\n\n    // unflattens the object from buffer.\n    // size should be equal to the value of getFlattenedSize() when the\n    // object was flattened.\n    // unflattened file descriptors are found in the fds[] array and\n    // don't need to be dupped(). ie: the caller of unflatten doesn't\n    // keep ownership. If a fd is not retained by unflatten() it must be\n    // explicitly closed.\n    inline status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);\n};\n\ntemplate<typename T>\ninline size_t Flattenable<T>::getFlattenedSize() const {\n    return static_cast<T const*>(this)->T::getFlattenedSize();\n}\ntemplate<typename T>\ninline size_t Flattenable<T>::getFdCount() const {\n    return static_cast<T const*>(this)->T::getFdCount();\n}\ntemplate<typename T>\ninline status_t Flattenable<T>::flatten(\n        void*& buffer, size_t& size, int*& fds, size_t& count) const {\n    return static_cast<T const*>(this)->T::flatten(buffer, size, fds, count);\n}\ntemplate<typename T>\ninline status_t Flattenable<T>::unflatten(\n        void const*& buffer, size_t& size, int const*& fds, size_t& count) {\n    return static_cast<T*>(this)->T::unflatten(buffer, size, fds, count);\n}\n\n/*\n * LightFlattenable is a protocol allowing object to serialize themselves out\n * to a byte-buffer. Because it doesn't handle file-descriptors,\n * LightFlattenable is usually more size efficient than Flattenable.\n * LightFlattenable objects must implement this protocol.\n */\ntemplate <typename T>\nclass LightFlattenable {\npublic:\n    // returns whether this object always flatten into the same size.\n    // for efficiency, this should always be inline.\n    inline bool isFixedSize() const;\n\n    // returns size in bytes of the flattened object. must be a constant.\n    inline size_t getFlattenedSize() const;\n\n    // flattens the object into buffer.\n    inline status_t flatten(void* buffer, size_t size) const;\n\n    // unflattens the object from buffer of given size.\n    inline status_t unflatten(void const* buffer, size_t size);\n};\n\ntemplate <typename T>\ninline bool LightFlattenable<T>::isFixedSize() const {\n    return static_cast<T const*>(this)->T::isFixedSize();\n}\ntemplate <typename T>\ninline size_t LightFlattenable<T>::getFlattenedSize() const {\n    return static_cast<T const*>(this)->T::getFlattenedSize();\n}\ntemplate <typename T>\ninline status_t LightFlattenable<T>::flatten(void* buffer, size_t size) const {\n    return static_cast<T const*>(this)->T::flatten(buffer, size);\n}\ntemplate <typename T>\ninline status_t LightFlattenable<T>::unflatten(void const* buffer, size_t size) {\n    return static_cast<T*>(this)->T::unflatten(buffer, size);\n}\n\n/*\n * LightFlattenablePod is an implementation of the LightFlattenable protocol\n * for POD (plain-old-data) objects.\n * Simply derive from LightFlattenablePod<Foo> to make Foo flattenable; no\n * need to implement any methods; obviously Foo must be a POD structure.\n */\ntemplate <typename T>\nclass LightFlattenablePod : public LightFlattenable<T> {\npublic:\n    inline bool isFixedSize() const {\n        return true;\n    }\n\n    inline size_t getFlattenedSize() const {\n        return sizeof(T);\n    }\n    inline status_t flatten(void* buffer, size_t size) const {\n        if (size < sizeof(T)) return NO_MEMORY;\n        *reinterpret_cast<T*>(buffer) = *static_cast<T const*>(this);\n        return NO_ERROR;\n    }\n    inline status_t unflatten(void const* buffer, size_t) {\n        *static_cast<T*>(this) = *reinterpret_cast<T const*>(buffer);\n        return NO_ERROR;\n    }\n};\n\n\n}; // namespace android\n\n\n#endif /* ANDROID_UTILS_FLATTENABLE_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Functor.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_FUNCTOR_H\n#define ANDROID_FUNCTOR_H\n\n#include <utils/Errors.h>\n\nnamespace  android {\n\nclass Functor {\npublic:\n    Functor() {}\n    virtual ~Functor() {}\n    virtual status_t operator ()(int /*what*/, void* /*data*/) { return NO_ERROR; }\n};\n\n}; // namespace android\n\n#endif // ANDROID_FUNCTOR_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/JenkinsHash.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* Implementation of Jenkins one-at-a-time hash function. These choices are\n * optimized for code size and portability, rather than raw speed. But speed\n * should still be quite good.\n **/\n\n#ifndef ANDROID_JENKINS_HASH_H\n#define ANDROID_JENKINS_HASH_H\n\n#include <utils/TypeHelpers.h>\n\nnamespace android {\n\n/* The Jenkins hash of a sequence of 32 bit words A, B, C is:\n * Whiten(Mix(Mix(Mix(0, A), B), C)) */\n\n#ifdef __clang__\n__attribute__((no_sanitize(\"integer\")))\n#endif\ninline uint32_t JenkinsHashMix(uint32_t hash, uint32_t data) {\n    hash += data;\n    hash += (hash << 10);\n    hash ^= (hash >> 6);\n    return hash;\n}\n\nhash_t JenkinsHashWhiten(uint32_t hash);\n\n/* Helpful utility functions for hashing data in 32 bit chunks */\nuint32_t JenkinsHashMixBytes(uint32_t hash, const uint8_t* bytes, size_t size);\n\nuint32_t JenkinsHashMixShorts(uint32_t hash, const uint16_t* shorts, size_t size);\n\n}\n\n#endif // ANDROID_JENKINS_HASH_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/KeyedVector.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_KEYED_VECTOR_H\n#define ANDROID_KEYED_VECTOR_H\n\n#include <assert.h>\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <cutils/log.h>\n\n#include <utils/SortedVector.h>\n#include <utils/TypeHelpers.h>\n#include <utils/Errors.h>\n\n// ---------------------------------------------------------------------------\n\nnamespace android {\n\ntemplate <typename KEY, typename VALUE>\nclass KeyedVector\n{\npublic:\n    typedef KEY    key_type;\n    typedef VALUE  value_type;\n\n    inline                  KeyedVector();\n\n    /*\n     * empty the vector\n     */\n\n    inline  void            clear()                     { mVector.clear(); }\n\n    /*! \n     * vector stats\n     */\n\n    //! returns number of items in the vector\n    inline  size_t          size() const                { return mVector.size(); }\n    //! returns whether or not the vector is empty\n    inline  bool            isEmpty() const             { return mVector.isEmpty(); }\n    //! returns how many items can be stored without reallocating the backing store\n    inline  size_t          capacity() const            { return mVector.capacity(); }\n    //! sets the capacity. capacity can never be reduced less than size()\n    inline ssize_t          setCapacity(size_t size)    { return mVector.setCapacity(size); }\n\n    // returns true if the arguments is known to be identical to this vector\n    inline bool isIdenticalTo(const KeyedVector& rhs) const;\n\n    /*! \n     * accessors\n     */\n            const VALUE&    valueFor(const KEY& key) const;\n            const VALUE&    valueAt(size_t index) const;\n            const KEY&      keyAt(size_t index) const;\n            ssize_t         indexOfKey(const KEY& key) const;\n            const VALUE&    operator[] (size_t index) const;\n\n    /*!\n     * modifying the array\n     */\n\n            VALUE&          editValueFor(const KEY& key);\n            VALUE&          editValueAt(size_t index);\n\n            /*! \n             * add/insert/replace items\n             */\n             \n            ssize_t         add(const KEY& key, const VALUE& item);\n            ssize_t         replaceValueFor(const KEY& key, const VALUE& item);\n            ssize_t         replaceValueAt(size_t index, const VALUE& item);\n\n    /*!\n     * remove items\n     */\n\n            ssize_t         removeItem(const KEY& key);\n            ssize_t         removeItemsAt(size_t index, size_t count = 1);\n            \nprivate:\n            SortedVector< key_value_pair_t<KEY, VALUE> >    mVector;\n};\n\n// KeyedVector<KEY, VALUE> can be trivially moved using memcpy() because its\n// underlying SortedVector can be trivially moved.\ntemplate<typename KEY, typename VALUE> struct trait_trivial_move<KeyedVector<KEY, VALUE> > {\n    enum { value = trait_trivial_move<SortedVector< key_value_pair_t<KEY, VALUE> > >::value };\n};\n\n\n// ---------------------------------------------------------------------------\n\n/**\n * Variation of KeyedVector that holds a default value to return when\n * valueFor() is called with a key that doesn't exist.\n */\ntemplate <typename KEY, typename VALUE>\nclass DefaultKeyedVector : public KeyedVector<KEY, VALUE>\n{\npublic:\n    inline                  DefaultKeyedVector(const VALUE& defValue = VALUE());\n            const VALUE&    valueFor(const KEY& key) const;\n\nprivate:\n            VALUE                                           mDefault;\n};\n\n// ---------------------------------------------------------------------------\n\ntemplate<typename KEY, typename VALUE> inline\nKeyedVector<KEY,VALUE>::KeyedVector()\n{\n}\n\ntemplate<typename KEY, typename VALUE> inline\nbool KeyedVector<KEY,VALUE>::isIdenticalTo(const KeyedVector<KEY,VALUE>& rhs) const {\n    return mVector.array() == rhs.mVector.array();\n}\n\ntemplate<typename KEY, typename VALUE> inline\nssize_t KeyedVector<KEY,VALUE>::indexOfKey(const KEY& key) const {\n    return mVector.indexOf( key_value_pair_t<KEY,VALUE>(key) );\n}\n\ntemplate<typename KEY, typename VALUE> inline\nconst VALUE& KeyedVector<KEY,VALUE>::valueFor(const KEY& key) const {\n    ssize_t i = this->indexOfKey(key);\n    LOG_ALWAYS_FATAL_IF(i<0, \"%s: key not found\", __PRETTY_FUNCTION__);\n    return mVector.itemAt(i).value;\n}\n\ntemplate<typename KEY, typename VALUE> inline\nconst VALUE& KeyedVector<KEY,VALUE>::valueAt(size_t index) const {\n    return mVector.itemAt(index).value;\n}\n\ntemplate<typename KEY, typename VALUE> inline\nconst VALUE& KeyedVector<KEY,VALUE>::operator[] (size_t index) const {\n    return valueAt(index);\n}\n\ntemplate<typename KEY, typename VALUE> inline\nconst KEY& KeyedVector<KEY,VALUE>::keyAt(size_t index) const {\n    return mVector.itemAt(index).key;\n}\n\ntemplate<typename KEY, typename VALUE> inline\nVALUE& KeyedVector<KEY,VALUE>::editValueFor(const KEY& key) {\n    ssize_t i = this->indexOfKey(key);\n    LOG_ALWAYS_FATAL_IF(i<0, \"%s: key not found\", __PRETTY_FUNCTION__);\n    return mVector.editItemAt(i).value;\n}\n\ntemplate<typename KEY, typename VALUE> inline\nVALUE& KeyedVector<KEY,VALUE>::editValueAt(size_t index) {\n    return mVector.editItemAt(index).value;\n}\n\ntemplate<typename KEY, typename VALUE> inline\nssize_t KeyedVector<KEY,VALUE>::add(const KEY& key, const VALUE& value) {\n    return mVector.add( key_value_pair_t<KEY,VALUE>(key, value) );\n}\n\ntemplate<typename KEY, typename VALUE> inline\nssize_t KeyedVector<KEY,VALUE>::replaceValueFor(const KEY& key, const VALUE& value) {\n    key_value_pair_t<KEY,VALUE> pair(key, value);\n    mVector.remove(pair);\n    return mVector.add(pair);\n}\n\ntemplate<typename KEY, typename VALUE> inline\nssize_t KeyedVector<KEY,VALUE>::replaceValueAt(size_t index, const VALUE& item) {\n    if (index<size()) {\n        mVector.editItemAt(index).value = item;\n        return index;\n    }\n    return BAD_INDEX;\n}\n\ntemplate<typename KEY, typename VALUE> inline\nssize_t KeyedVector<KEY,VALUE>::removeItem(const KEY& key) {\n    return mVector.remove(key_value_pair_t<KEY,VALUE>(key));\n}\n\ntemplate<typename KEY, typename VALUE> inline\nssize_t KeyedVector<KEY, VALUE>::removeItemsAt(size_t index, size_t count) {\n    return mVector.removeItemsAt(index, count);\n}\n\n// ---------------------------------------------------------------------------\n\ntemplate<typename KEY, typename VALUE> inline\nDefaultKeyedVector<KEY,VALUE>::DefaultKeyedVector(const VALUE& defValue)\n    : mDefault(defValue)\n{\n}\n\ntemplate<typename KEY, typename VALUE> inline\nconst VALUE& DefaultKeyedVector<KEY,VALUE>::valueFor(const KEY& key) const {\n    ssize_t i = this->indexOfKey(key);\n    return i >= 0 ? KeyedVector<KEY,VALUE>::valueAt(i) : mDefault;\n}\n\n}; // namespace android\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_KEYED_VECTOR_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/LinearTransform.h",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBS_UTILS_LINEAR_TRANSFORM_H\n#define _LIBS_UTILS_LINEAR_TRANSFORM_H\n\n#include <stdint.h>\n\nnamespace android {\n\n// LinearTransform defines a structure which hold the definition of a\n// transformation from single dimensional coordinate system A into coordinate\n// system B (and back again).  Values in A and in B are 64 bit, the linear\n// scale factor is expressed as a rational number using two 32 bit values.\n//\n// Specifically, let\n// f(a) = b\n// F(b) = f^-1(b) = a\n// then\n//\n// f(a) = (((a - a_zero) * a_to_b_numer) / a_to_b_denom) + b_zero;\n//\n// and\n//\n// F(b) = (((b - b_zero) * a_to_b_denom) / a_to_b_numer) + a_zero;\n//\nstruct LinearTransform {\n  int64_t  a_zero;\n  int64_t  b_zero;\n  int32_t  a_to_b_numer;\n  uint32_t a_to_b_denom;\n\n  // Transform from A->B\n  // Returns true on success, or false in the case of a singularity or an\n  // overflow.\n  bool doForwardTransform(int64_t a_in, int64_t* b_out) const;\n\n  // Transform from B->A\n  // Returns true on success, or false in the case of a singularity or an\n  // overflow.\n  bool doReverseTransform(int64_t b_in, int64_t* a_out) const;\n\n  // Helpers which will reduce the fraction N/D using Euclid's method.\n  template <class T> static void reduce(T* N, T* D);\n  static void reduce(int32_t* N, uint32_t* D);\n};\n\n\n}\n\n#endif  // _LIBS_UTILS_LINEAR_TRANSFORM_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/List.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Templated list class.  Normally we'd use STL, but we don't have that.\n// This class mimics STL's interfaces.\n//\n// Objects are copied into the list with the '=' operator or with copy-\n// construction, so if the compiler's auto-generated versions won't work for\n// you, define your own.\n//\n// The only class you want to use from here is \"List\".\n//\n#ifndef _LIBS_UTILS_LIST_H\n#define _LIBS_UTILS_LIST_H\n\n#include <stddef.h>\n#include <stdint.h>\n\nnamespace android {\n\n/*\n * Doubly-linked list.  Instantiate with \"List<MyClass> myList\".\n *\n * Objects added to the list are copied using the assignment operator,\n * so this must be defined.\n */\ntemplate<typename T> \nclass List \n{\nprotected:\n    /*\n     * One element in the list.\n     */\n    class _Node {\n    public:\n        explicit _Node(const T& val) : mVal(val) {}\n        ~_Node() {}\n        inline T& getRef() { return mVal; }\n        inline const T& getRef() const { return mVal; }\n        inline _Node* getPrev() const { return mpPrev; }\n        inline _Node* getNext() const { return mpNext; }\n        inline void setVal(const T& val) { mVal = val; }\n        inline void setPrev(_Node* ptr) { mpPrev = ptr; }\n        inline void setNext(_Node* ptr) { mpNext = ptr; }\n    private:\n        friend class List;\n        friend class _ListIterator;\n        T           mVal;\n        _Node*      mpPrev;\n        _Node*      mpNext;\n    };\n\n    /*\n     * Iterator for walking through the list.\n     */\n    \n    template <typename TYPE>\n    struct CONST_ITERATOR {\n        typedef _Node const * NodePtr;\n        typedef const TYPE Type;\n    };\n    \n    template <typename TYPE>\n    struct NON_CONST_ITERATOR {\n        typedef _Node* NodePtr;\n        typedef TYPE Type;\n    };\n    \n    template<\n        typename U,\n        template <class> class Constness\n    > \n    class _ListIterator {\n        typedef _ListIterator<U, Constness>     _Iter;\n        typedef typename Constness<U>::NodePtr  _NodePtr;\n        typedef typename Constness<U>::Type     _Type;\n\n        explicit _ListIterator(_NodePtr ptr) : mpNode(ptr) {}\n\n    public:\n        _ListIterator() {}\n        _ListIterator(const _Iter& rhs) : mpNode(rhs.mpNode) {}\n        ~_ListIterator() {}\n        \n        // this will handle conversions from iterator to const_iterator\n        // (and also all convertible iterators)\n        // Here, in this implementation, the iterators can be converted\n        // if the nodes can be converted\n        template<typename V> explicit \n        _ListIterator(const V& rhs) : mpNode(rhs.mpNode) {}\n        \n\n        /*\n         * Dereference operator.  Used to get at the juicy insides.\n         */\n        _Type& operator*() const { return mpNode->getRef(); }\n        _Type* operator->() const { return &(mpNode->getRef()); }\n\n        /*\n         * Iterator comparison.\n         */\n        inline bool operator==(const _Iter& right) const { \n            return mpNode == right.mpNode; }\n        \n        inline bool operator!=(const _Iter& right) const { \n            return mpNode != right.mpNode; }\n\n        /*\n         * handle comparisons between iterator and const_iterator\n         */\n        template<typename OTHER>\n        inline bool operator==(const OTHER& right) const { \n            return mpNode == right.mpNode; }\n        \n        template<typename OTHER>\n        inline bool operator!=(const OTHER& right) const { \n            return mpNode != right.mpNode; }\n\n        /*\n         * Incr/decr, used to move through the list.\n         */\n        inline _Iter& operator++() {     // pre-increment\n            mpNode = mpNode->getNext();\n            return *this;\n        }\n        const _Iter operator++(int) {    // post-increment\n            _Iter tmp(*this);\n            mpNode = mpNode->getNext();\n            return tmp;\n        }\n        inline _Iter& operator--() {     // pre-increment\n            mpNode = mpNode->getPrev();\n            return *this;\n        }\n        const _Iter operator--(int) {   // post-increment\n            _Iter tmp(*this);\n            mpNode = mpNode->getPrev();\n            return tmp;\n        }\n\n        inline _NodePtr getNode() const { return mpNode; }\n\n        _NodePtr mpNode;    /* should be private, but older gcc fails */\n    private:\n        friend class List;\n    };\n\npublic:\n    List() {\n        prep();\n    }\n    List(const List<T>& src) {      // copy-constructor\n        prep();\n        insert(begin(), src.begin(), src.end());\n    }\n    virtual ~List() {\n        clear();\n        delete[] (unsigned char*) mpMiddle;\n    }\n\n    typedef _ListIterator<T, NON_CONST_ITERATOR> iterator;\n    typedef _ListIterator<T, CONST_ITERATOR> const_iterator;\n\n    List<T>& operator=(const List<T>& right);\n\n    /* returns true if the list is empty */\n    inline bool empty() const { return mpMiddle->getNext() == mpMiddle; }\n\n    /* return #of elements in list */\n    size_t size() const {\n        return size_t(distance(begin(), end()));\n    }\n\n    /*\n     * Return the first element or one past the last element.  The\n     * _Node* we're returning is converted to an \"iterator\" by a\n     * constructor in _ListIterator.\n     */\n    inline iterator begin() { \n        return iterator(mpMiddle->getNext()); \n    }\n    inline const_iterator begin() const { \n        return const_iterator(const_cast<_Node const*>(mpMiddle->getNext())); \n    }\n    inline iterator end() { \n        return iterator(mpMiddle); \n    }\n    inline const_iterator end() const { \n        return const_iterator(const_cast<_Node const*>(mpMiddle)); \n    }\n\n    /* add the object to the head or tail of the list */\n    void push_front(const T& val) { insert(begin(), val); }\n    void push_back(const T& val) { insert(end(), val); }\n\n    /* insert before the current node; returns iterator at new node */\n    iterator insert(iterator posn, const T& val) \n    {\n        _Node* newNode = new _Node(val);        // alloc & copy-construct\n        newNode->setNext(posn.getNode());\n        newNode->setPrev(posn.getNode()->getPrev());\n        posn.getNode()->getPrev()->setNext(newNode);\n        posn.getNode()->setPrev(newNode);\n        return iterator(newNode);\n    }\n\n    /* insert a range of elements before the current node */\n    void insert(iterator posn, const_iterator first, const_iterator last) {\n        for ( ; first != last; ++first)\n            insert(posn, *first);\n    }\n\n    /* remove one entry; returns iterator at next node */\n    iterator erase(iterator posn) {\n        _Node* pNext = posn.getNode()->getNext();\n        _Node* pPrev = posn.getNode()->getPrev();\n        pPrev->setNext(pNext);\n        pNext->setPrev(pPrev);\n        delete posn.getNode();\n        return iterator(pNext);\n    }\n\n    /* remove a range of elements */\n    iterator erase(iterator first, iterator last) {\n        while (first != last)\n            erase(first++);     // don't erase than incr later!\n        return iterator(last);\n    }\n\n    /* remove all contents of the list */\n    void clear() {\n        _Node* pCurrent = mpMiddle->getNext();\n        _Node* pNext;\n\n        while (pCurrent != mpMiddle) {\n            pNext = pCurrent->getNext();\n            delete pCurrent;\n            pCurrent = pNext;\n        }\n        mpMiddle->setPrev(mpMiddle);\n        mpMiddle->setNext(mpMiddle);\n    }\n\n    /*\n     * Measure the distance between two iterators.  On exist, \"first\"\n     * will be equal to \"last\".  The iterators must refer to the same\n     * list.\n     *\n     * FIXME: This is actually a generic iterator function. It should be a \n     * template function at the top-level with specializations for things like\n     * vector<>, which can just do pointer math). Here we limit it to\n     * _ListIterator of the same type but different constness.\n     */\n    template<\n        typename U,\n        template <class> class CL,\n        template <class> class CR\n    > \n    ptrdiff_t distance(\n            _ListIterator<U, CL> first, _ListIterator<U, CR> last) const \n    {\n        ptrdiff_t count = 0;\n        while (first != last) {\n            ++first;\n            ++count;\n        }\n        return count;\n    }\n\nprivate:\n    /*\n     * I want a _Node but don't need it to hold valid data.  More\n     * to the point, I don't want T's constructor to fire, since it\n     * might have side-effects or require arguments.  So, we do this\n     * slightly uncouth storage alloc.\n     */\n    void prep() {\n        mpMiddle = (_Node*) new unsigned char[sizeof(_Node)];\n        mpMiddle->setPrev(mpMiddle);\n        mpMiddle->setNext(mpMiddle);\n    }\n\n    /*\n     * This node plays the role of \"pointer to head\" and \"pointer to tail\".\n     * It sits in the middle of a circular list of nodes.  The iterator\n     * runs around the circle until it encounters this one.\n     */\n    _Node*      mpMiddle;\n};\n\n/*\n * Assignment operator.\n *\n * The simplest way to do this would be to clear out the target list and\n * fill it with the source.  However, we can speed things along by\n * re-using existing elements.\n */\ntemplate<class T>\nList<T>& List<T>::operator=(const List<T>& right)\n{\n    if (this == &right)\n        return *this;       // self-assignment\n    iterator firstDst = begin();\n    iterator lastDst = end();\n    const_iterator firstSrc = right.begin();\n    const_iterator lastSrc = right.end();\n    while (firstSrc != lastSrc && firstDst != lastDst)\n        *firstDst++ = *firstSrc++;\n    if (firstSrc == lastSrc)        // ran out of elements in source?\n        erase(firstDst, lastDst);   // yes, erase any extras\n    else\n        insert(lastDst, firstSrc, lastSrc);     // copy remaining over\n    return *this;\n}\n\n}; // namespace android\n\n#endif // _LIBS_UTILS_LIST_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Log.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// C/C++ logging functions.  See the logging documentation for API details.\n//\n// We'd like these to be available from C code (in case we import some from\n// somewhere), so this has a C interface.\n//\n// The output will be correct when the log file is shared between multiple\n// threads and/or multiple processes so long as the operating system\n// supports O_APPEND.  These calls have mutex-protected data structures\n// and so are NOT reentrant.  Do not use LOG in a signal handler.\n//\n#ifndef _LIBS_UTILS_LOG_H\n#define _LIBS_UTILS_LOG_H\n\n#include <cutils/log.h>\n#include <sys/types.h>\n\n#ifdef __cplusplus\n\nnamespace android {\n\n/*\n * A very simple utility that yells in the log when an operation takes too long.\n */\nclass LogIfSlow {\npublic:\n    LogIfSlow(const char* tag, android_LogPriority priority,\n            int timeoutMillis, const char* message);\n    ~LogIfSlow();\n\nprivate:\n    const char* const mTag;\n    const android_LogPriority mPriority;\n    const int mTimeoutMillis;\n    const char* const mMessage;\n    const int64_t mStart;\n};\n\n/*\n * Writes the specified debug log message if this block takes longer than the\n * specified number of milliseconds to run.  Includes the time actually taken.\n *\n * {\n *     ALOGD_IF_SLOW(50, \"Excessive delay doing something.\");\n *     doSomething();\n * }\n */\n#define ALOGD_IF_SLOW(timeoutMillis, message) \\\n    android::LogIfSlow _logIfSlow(LOG_TAG, ANDROID_LOG_DEBUG, timeoutMillis, message);\n\n} // namespace android\n\n#endif // __cplusplus\n\n#endif // _LIBS_UTILS_LOG_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Looper.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef UTILS_LOOPER_H\n#define UTILS_LOOPER_H\n\n#include <utils/threads.h>\n#include <utils/RefBase.h>\n#include <utils/KeyedVector.h>\n#include <utils/Timers.h>\n\n#include <sys/epoll.h>\n\nnamespace android {\n\n/*\n * NOTE: Since Looper is used to implement the NDK ALooper, the Looper\n * enums and the signature of Looper_callbackFunc need to align with\n * that implementation.\n */\n\n/**\n * For callback-based event loops, this is the prototype of the function\n * that is called when a file descriptor event occurs.\n * It is given the file descriptor it is associated with,\n * a bitmask of the poll events that were triggered (typically EVENT_INPUT),\n * and the data pointer that was originally supplied.\n *\n * Implementations should return 1 to continue receiving callbacks, or 0\n * to have this file descriptor and callback unregistered from the looper.\n */\ntypedef int (*Looper_callbackFunc)(int fd, int events, void* data);\n\n/**\n * A message that can be posted to a Looper.\n */\nstruct Message {\n    Message() : what(0) { }\n    Message(int what) : what(what) { }\n\n    /* The message type. (interpretation is left up to the handler) */\n    int what;\n};\n\n\n/**\n * Interface for a Looper message handler.\n *\n * The Looper holds a strong reference to the message handler whenever it has\n * a message to deliver to it.  Make sure to call Looper::removeMessages\n * to remove any pending messages destined for the handler so that the handler\n * can be destroyed.\n */\nclass MessageHandler : public virtual RefBase {\nprotected:\n    virtual ~MessageHandler() { }\n\npublic:\n    /**\n     * Handles a message.\n     */\n    virtual void handleMessage(const Message& message) = 0;\n};\n\n\n/**\n * A simple proxy that holds a weak reference to a message handler.\n */\nclass WeakMessageHandler : public MessageHandler {\nprotected:\n    virtual ~WeakMessageHandler();\n\npublic:\n    WeakMessageHandler(const wp<MessageHandler>& handler);\n    virtual void handleMessage(const Message& message);\n\nprivate:\n    wp<MessageHandler> mHandler;\n};\n\n\n/**\n * A looper callback.\n */\nclass LooperCallback : public virtual RefBase {\nprotected:\n    virtual ~LooperCallback() { }\n\npublic:\n    /**\n     * Handles a poll event for the given file descriptor.\n     * It is given the file descriptor it is associated with,\n     * a bitmask of the poll events that were triggered (typically EVENT_INPUT),\n     * and the data pointer that was originally supplied.\n     *\n     * Implementations should return 1 to continue receiving callbacks, or 0\n     * to have this file descriptor and callback unregistered from the looper.\n     */\n    virtual int handleEvent(int fd, int events, void* data) = 0;\n};\n\n/**\n * Wraps a Looper_callbackFunc function pointer.\n */\nclass SimpleLooperCallback : public LooperCallback {\nprotected:\n    virtual ~SimpleLooperCallback();\n\npublic:\n    SimpleLooperCallback(Looper_callbackFunc callback);\n    virtual int handleEvent(int fd, int events, void* data);\n\nprivate:\n    Looper_callbackFunc mCallback;\n};\n\n/**\n * A polling loop that supports monitoring file descriptor events, optionally\n * using callbacks.  The implementation uses epoll() internally.\n *\n * A looper can be associated with a thread although there is no requirement that it must be.\n */\nclass Looper : public RefBase {\nprotected:\n    virtual ~Looper();\n\npublic:\n    enum {\n        /**\n         * Result from Looper_pollOnce() and Looper_pollAll():\n         * The poll was awoken using wake() before the timeout expired\n         * and no callbacks were executed and no other file descriptors were ready.\n         */\n        POLL_WAKE = -1,\n\n        /**\n         * Result from Looper_pollOnce() and Looper_pollAll():\n         * One or more callbacks were executed.\n         */\n        POLL_CALLBACK = -2,\n\n        /**\n         * Result from Looper_pollOnce() and Looper_pollAll():\n         * The timeout expired.\n         */\n        POLL_TIMEOUT = -3,\n\n        /**\n         * Result from Looper_pollOnce() and Looper_pollAll():\n         * An error occurred.\n         */\n        POLL_ERROR = -4,\n    };\n\n    /**\n     * Flags for file descriptor events that a looper can monitor.\n     *\n     * These flag bits can be combined to monitor multiple events at once.\n     */\n    enum {\n        /**\n         * The file descriptor is available for read operations.\n         */\n        EVENT_INPUT = 1 << 0,\n\n        /**\n         * The file descriptor is available for write operations.\n         */\n        EVENT_OUTPUT = 1 << 1,\n\n        /**\n         * The file descriptor has encountered an error condition.\n         *\n         * The looper always sends notifications about errors; it is not necessary\n         * to specify this event flag in the requested event set.\n         */\n        EVENT_ERROR = 1 << 2,\n\n        /**\n         * The file descriptor was hung up.\n         * For example, indicates that the remote end of a pipe or socket was closed.\n         *\n         * The looper always sends notifications about hangups; it is not necessary\n         * to specify this event flag in the requested event set.\n         */\n        EVENT_HANGUP = 1 << 3,\n\n        /**\n         * The file descriptor is invalid.\n         * For example, the file descriptor was closed prematurely.\n         *\n         * The looper always sends notifications about invalid file descriptors; it is not necessary\n         * to specify this event flag in the requested event set.\n         */\n        EVENT_INVALID = 1 << 4,\n    };\n\n    enum {\n        /**\n         * Option for Looper_prepare: this looper will accept calls to\n         * Looper_addFd() that do not have a callback (that is provide NULL\n         * for the callback).  In this case the caller of Looper_pollOnce()\n         * or Looper_pollAll() MUST check the return from these functions to\n         * discover when data is available on such fds and process it.\n         */\n        PREPARE_ALLOW_NON_CALLBACKS = 1<<0\n    };\n\n    /**\n     * Creates a looper.\n     *\n     * If allowNonCallbaks is true, the looper will allow file descriptors to be\n     * registered without associated callbacks.  This assumes that the caller of\n     * pollOnce() is prepared to handle callback-less events itself.\n     */\n    Looper(bool allowNonCallbacks);\n\n    /**\n     * Returns whether this looper instance allows the registration of file descriptors\n     * using identifiers instead of callbacks.\n     */\n    bool getAllowNonCallbacks() const;\n\n    /**\n     * Waits for events to be available, with optional timeout in milliseconds.\n     * Invokes callbacks for all file descriptors on which an event occurred.\n     *\n     * If the timeout is zero, returns immediately without blocking.\n     * If the timeout is negative, waits indefinitely until an event appears.\n     *\n     * Returns POLL_WAKE if the poll was awoken using wake() before\n     * the timeout expired and no callbacks were invoked and no other file\n     * descriptors were ready.\n     *\n     * Returns POLL_CALLBACK if one or more callbacks were invoked.\n     *\n     * Returns POLL_TIMEOUT if there was no data before the given\n     * timeout expired.\n     *\n     * Returns POLL_ERROR if an error occurred.\n     *\n     * Returns a value >= 0 containing an identifier if its file descriptor has data\n     * and it has no callback function (requiring the caller here to handle it).\n     * In this (and only this) case outFd, outEvents and outData will contain the poll\n     * events and data associated with the fd, otherwise they will be set to NULL.\n     *\n     * This method does not return until it has finished invoking the appropriate callbacks\n     * for all file descriptors that were signalled.\n     */\n    int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);\n    inline int pollOnce(int timeoutMillis) {\n        return pollOnce(timeoutMillis, NULL, NULL, NULL);\n    }\n\n    /**\n     * Like pollOnce(), but performs all pending callbacks until all\n     * data has been consumed or a file descriptor is available with no callback.\n     * This function will never return POLL_CALLBACK.\n     */\n    int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);\n    inline int pollAll(int timeoutMillis) {\n        return pollAll(timeoutMillis, NULL, NULL, NULL);\n    }\n\n    /**\n     * Wakes the poll asynchronously.\n     *\n     * This method can be called on any thread.\n     * This method returns immediately.\n     */\n    void wake();\n\n    /**\n     * Adds a new file descriptor to be polled by the looper.\n     * If the same file descriptor was previously added, it is replaced.\n     *\n     * \"fd\" is the file descriptor to be added.\n     * \"ident\" is an identifier for this event, which is returned from pollOnce().\n     * The identifier must be >= 0, or POLL_CALLBACK if providing a non-NULL callback.\n     * \"events\" are the poll events to wake up on.  Typically this is EVENT_INPUT.\n     * \"callback\" is the function to call when there is an event on the file descriptor.\n     * \"data\" is a private data pointer to supply to the callback.\n     *\n     * There are two main uses of this function:\n     *\n     * (1) If \"callback\" is non-NULL, then this function will be called when there is\n     * data on the file descriptor.  It should execute any events it has pending,\n     * appropriately reading from the file descriptor.  The 'ident' is ignored in this case.\n     *\n     * (2) If \"callback\" is NULL, the 'ident' will be returned by Looper_pollOnce\n     * when its file descriptor has data available, requiring the caller to take\n     * care of processing it.\n     *\n     * Returns 1 if the file descriptor was added, 0 if the arguments were invalid.\n     *\n     * This method can be called on any thread.\n     * This method may block briefly if it needs to wake the poll.\n     *\n     * The callback may either be specified as a bare function pointer or as a smart\n     * pointer callback object.  The smart pointer should be preferred because it is\n     * easier to avoid races when the callback is removed from a different thread.\n     * See removeFd() for details.\n     */\n    int addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data);\n    int addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data);\n\n    /**\n     * Removes a previously added file descriptor from the looper.\n     *\n     * When this method returns, it is safe to close the file descriptor since the looper\n     * will no longer have a reference to it.  However, it is possible for the callback to\n     * already be running or for it to run one last time if the file descriptor was already\n     * signalled.  Calling code is responsible for ensuring that this case is safely handled.\n     * For example, if the callback takes care of removing itself during its own execution either\n     * by returning 0 or by calling this method, then it can be guaranteed to not be invoked\n     * again at any later time unless registered anew.\n     *\n     * A simple way to avoid this problem is to use the version of addFd() that takes\n     * a sp<LooperCallback> instead of a bare function pointer.  The LooperCallback will\n     * be released at the appropriate time by the Looper.\n     *\n     * Returns 1 if the file descriptor was removed, 0 if none was previously registered.\n     *\n     * This method can be called on any thread.\n     * This method may block briefly if it needs to wake the poll.\n     */\n    int removeFd(int fd);\n\n    /**\n     * Enqueues a message to be processed by the specified handler.\n     *\n     * The handler must not be null.\n     * This method can be called on any thread.\n     */\n    void sendMessage(const sp<MessageHandler>& handler, const Message& message);\n\n    /**\n     * Enqueues a message to be processed by the specified handler after all pending messages\n     * after the specified delay.\n     *\n     * The time delay is specified in uptime nanoseconds.\n     * The handler must not be null.\n     * This method can be called on any thread.\n     */\n    void sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,\n            const Message& message);\n\n    /**\n     * Enqueues a message to be processed by the specified handler after all pending messages\n     * at the specified time.\n     *\n     * The time is specified in uptime nanoseconds.\n     * The handler must not be null.\n     * This method can be called on any thread.\n     */\n    void sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,\n            const Message& message);\n\n    /**\n     * Removes all messages for the specified handler from the queue.\n     *\n     * The handler must not be null.\n     * This method can be called on any thread.\n     */\n    void removeMessages(const sp<MessageHandler>& handler);\n\n    /**\n     * Removes all messages of a particular type for the specified handler from the queue.\n     *\n     * The handler must not be null.\n     * This method can be called on any thread.\n     */\n    void removeMessages(const sp<MessageHandler>& handler, int what);\n\n    /**\n     * Returns whether this looper's thread is currently polling for more work to do.\n     * This is a good signal that the loop is still alive rather than being stuck\n     * handling a callback.  Note that this method is intrinsically racy, since the\n     * state of the loop can change before you get the result back.\n     */\n    bool isPolling() const;\n\n    /**\n     * Prepares a looper associated with the calling thread, and returns it.\n     * If the thread already has a looper, it is returned.  Otherwise, a new\n     * one is created, associated with the thread, and returned.\n     *\n     * The opts may be PREPARE_ALLOW_NON_CALLBACKS or 0.\n     */\n    static sp<Looper> prepare(int opts);\n\n    /**\n     * Sets the given looper to be associated with the calling thread.\n     * If another looper is already associated with the thread, it is replaced.\n     *\n     * If \"looper\" is NULL, removes the currently associated looper.\n     */\n    static void setForThread(const sp<Looper>& looper);\n\n    /**\n     * Returns the looper associated with the calling thread, or NULL if\n     * there is not one.\n     */\n    static sp<Looper> getForThread();\n\nprivate:\n    struct Request {\n        int fd;\n        int ident;\n        int events;\n        int seq;\n        sp<LooperCallback> callback;\n        void* data;\n\n        void initEventItem(struct epoll_event* eventItem) const;\n    };\n\n    struct Response {\n        int events;\n        Request request;\n    };\n\n    struct MessageEnvelope {\n        MessageEnvelope() : uptime(0) { }\n\n        MessageEnvelope(nsecs_t uptime, const sp<MessageHandler> handler,\n                const Message& message) : uptime(uptime), handler(handler), message(message) {\n        }\n\n        nsecs_t uptime;\n        sp<MessageHandler> handler;\n        Message message;\n    };\n\n    const bool mAllowNonCallbacks; // immutable\n\n    int mWakeEventFd;  // immutable\n    Mutex mLock;\n\n    Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock\n    bool mSendingMessage; // guarded by mLock\n\n    // Whether we are currently waiting for work.  Not protected by a lock,\n    // any use of it is racy anyway.\n    volatile bool mPolling;\n\n    int mEpollFd; // guarded by mLock but only modified on the looper thread\n    bool mEpollRebuildRequired; // guarded by mLock\n\n    // Locked list of file descriptor monitoring requests.\n    KeyedVector<int, Request> mRequests;  // guarded by mLock\n    int mNextRequestSeq;\n\n    // This state is only used privately by pollOnce and does not require a lock since\n    // it runs on a single thread.\n    Vector<Response> mResponses;\n    size_t mResponseIndex;\n    nsecs_t mNextMessageUptime; // set to LLONG_MAX when none\n\n    int pollInner(int timeoutMillis);\n    int removeFd(int fd, int seq);\n    void awoken();\n    void pushResponse(int events, const Request& request);\n    void rebuildEpollLocked();\n    void scheduleEpollRebuildLocked();\n\n    static void initTLSKey();\n    static void threadDestructor(void *st);\n    static void initEpollEvent(struct epoll_event* eventItem);\n};\n\n} // namespace android\n\n#endif // UTILS_LOOPER_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/LruCache.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UTILS_LRU_CACHE_H\n#define ANDROID_UTILS_LRU_CACHE_H\n\n#include <memory>\n#include <unordered_set>\n\n#include \"utils/TypeHelpers.h\"  // hash_t\n\nnamespace android {\n\n/**\n * GenerationCache callback used when an item is removed\n */\ntemplate<typename EntryKey, typename EntryValue>\nclass OnEntryRemoved {\npublic:\n    virtual ~OnEntryRemoved() { };\n    virtual void operator()(EntryKey& key, EntryValue& value) = 0;\n}; // class OnEntryRemoved\n\ntemplate <typename TKey, typename TValue>\nclass LruCache {\npublic:\n    explicit LruCache(uint32_t maxCapacity);\n    virtual ~LruCache();\n\n    enum Capacity {\n        kUnlimitedCapacity,\n    };\n\n    void setOnEntryRemovedListener(OnEntryRemoved<TKey, TValue>* listener);\n    size_t size() const;\n    const TValue& get(const TKey& key);\n    bool put(const TKey& key, const TValue& value);\n    bool remove(const TKey& key);\n    bool removeOldest();\n    void clear();\n    const TValue& peekOldestValue();\n\nprivate:\n    LruCache(const LruCache& that);  // disallow copy constructor\n\n    struct Entry {\n        TKey key;\n        TValue value;\n        Entry* parent;\n        Entry* child;\n\n        Entry(TKey key_, TValue value_) : key(key_), value(value_), parent(NULL), child(NULL) {\n        }\n        const TKey& getKey() const { return key; }\n    };\n\n    struct HashForEntry : public std::unary_function<Entry*, hash_t> {\n        size_t operator() (const Entry* entry) const {\n            return hash_type(entry->key);\n        };\n    };\n\n    struct EqualityForHashedEntries : public std::unary_function<Entry*, hash_t> {\n        bool operator() (const Entry* lhs, const Entry* rhs) const {\n            return lhs->key == rhs->key;\n        };\n    };\n\n    typedef std::unordered_set<Entry*, HashForEntry, EqualityForHashedEntries> LruCacheSet;\n\n    void attachToCache(Entry& entry);\n    void detachFromCache(Entry& entry);\n\n    typename LruCacheSet::iterator findByKey(const TKey& key) {\n        Entry entryForSearch(key, mNullValue);\n        typename LruCacheSet::iterator result = mSet->find(&entryForSearch);\n        return result;\n    }\n\n    std::unique_ptr<LruCacheSet> mSet;\n    OnEntryRemoved<TKey, TValue>* mListener;\n    Entry* mOldest;\n    Entry* mYoungest;\n    uint32_t mMaxCapacity;\n    TValue mNullValue;\n\npublic:\n    // To be used like:\n    // while (it.next()) {\n    //   it.value(); it.key();\n    // }\n    class Iterator {\n    public:\n        Iterator(const LruCache<TKey, TValue>& cache):\n                mCache(cache), mIterator(mCache.mSet->begin()), mBeginReturned(false) {\n        }\n\n        bool next() {\n            if (mIterator == mCache.mSet->end()) {\n                return false;\n            }\n            if (!mBeginReturned) {\n                // mIterator has been initialized to the beginning and\n                // hasn't been returned. Do not advance:\n                mBeginReturned = true;\n            } else {\n                std::advance(mIterator, 1);\n            }\n            bool ret = (mIterator != mCache.mSet->end());\n            return ret;\n        }\n\n        const TValue& value() const {\n            return (*mIterator)->value;\n        }\n\n        const TKey& key() const {\n            return (*mIterator)->key;\n        }\n    private:\n        const LruCache<TKey, TValue>& mCache;\n        typename LruCacheSet::iterator mIterator;\n        bool mBeginReturned;\n    };\n};\n\n// Implementation is here, because it's fully templated\ntemplate <typename TKey, typename TValue>\nLruCache<TKey, TValue>::LruCache(uint32_t maxCapacity)\n    : mSet(new LruCacheSet())\n    , mListener(NULL)\n    , mOldest(NULL)\n    , mYoungest(NULL)\n    , mMaxCapacity(maxCapacity)\n    , mNullValue(NULL) {\n    mSet->max_load_factor(1.0);\n};\n\ntemplate <typename TKey, typename TValue>\nLruCache<TKey, TValue>::~LruCache() {\n    // Need to delete created entries.\n    clear();\n};\n\ntemplate<typename K, typename V>\nvoid LruCache<K, V>::setOnEntryRemovedListener(OnEntryRemoved<K, V>* listener) {\n    mListener = listener;\n}\n\ntemplate <typename TKey, typename TValue>\nsize_t LruCache<TKey, TValue>::size() const {\n    return mSet->size();\n}\n\ntemplate <typename TKey, typename TValue>\nconst TValue& LruCache<TKey, TValue>::get(const TKey& key) {\n    typename LruCacheSet::const_iterator find_result = findByKey(key);\n    if (find_result == mSet->end()) {\n        return mNullValue;\n    }\n    Entry *entry = *find_result;\n    detachFromCache(*entry);\n    attachToCache(*entry);\n    return entry->value;\n}\n\ntemplate <typename TKey, typename TValue>\nbool LruCache<TKey, TValue>::put(const TKey& key, const TValue& value) {\n    if (mMaxCapacity != kUnlimitedCapacity && size() >= mMaxCapacity) {\n        removeOldest();\n    }\n\n    if (findByKey(key) != mSet->end()) {\n        return false;\n    }\n\n    Entry* newEntry = new Entry(key, value);\n    mSet->insert(newEntry);\n    attachToCache(*newEntry);\n    return true;\n}\n\ntemplate <typename TKey, typename TValue>\nbool LruCache<TKey, TValue>::remove(const TKey& key) {\n    typename LruCacheSet::const_iterator find_result = findByKey(key);\n    if (find_result == mSet->end()) {\n        return false;\n    }\n    Entry* entry = *find_result;\n    mSet->erase(entry);\n    if (mListener) {\n        (*mListener)(entry->key, entry->value);\n    }\n    detachFromCache(*entry);\n    delete entry;\n    return true;\n}\n\ntemplate <typename TKey, typename TValue>\nbool LruCache<TKey, TValue>::removeOldest() {\n    if (mOldest != NULL) {\n        return remove(mOldest->key);\n        // TODO: should probably abort if false\n    }\n    return false;\n}\n\ntemplate <typename TKey, typename TValue>\nconst TValue& LruCache<TKey, TValue>::peekOldestValue() {\n    if (mOldest) {\n        return mOldest->value;\n    }\n    return mNullValue;\n}\n\ntemplate <typename TKey, typename TValue>\nvoid LruCache<TKey, TValue>::clear() {\n    if (mListener) {\n        for (Entry* p = mOldest; p != NULL; p = p->child) {\n            (*mListener)(p->key, p->value);\n        }\n    }\n    mYoungest = NULL;\n    mOldest = NULL;\n    for (auto entry : *mSet.get()) {\n        delete entry;\n    }\n    mSet->clear();\n}\n\ntemplate <typename TKey, typename TValue>\nvoid LruCache<TKey, TValue>::attachToCache(Entry& entry) {\n    if (mYoungest == NULL) {\n        mYoungest = mOldest = &entry;\n    } else {\n        entry.parent = mYoungest;\n        mYoungest->child = &entry;\n        mYoungest = &entry;\n    }\n}\n\ntemplate <typename TKey, typename TValue>\nvoid LruCache<TKey, TValue>::detachFromCache(Entry& entry) {\n    if (entry.parent != NULL) {\n        entry.parent->child = entry.child;\n    } else {\n        mOldest = entry.child;\n    }\n    if (entry.child != NULL) {\n        entry.child->parent = entry.parent;\n    } else {\n        mYoungest = entry.parent;\n    }\n\n    entry.parent = NULL;\n    entry.child = NULL;\n}\n\n}\n#endif // ANDROID_UTILS_LRU_CACHE_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Mutex.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBS_UTILS_MUTEX_H\n#define _LIBS_UTILS_MUTEX_H\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <time.h>\n\n#if !defined(_WIN32)\n# include <pthread.h>\n#endif\n\n#include <utils/Errors.h>\n#include <utils/Timers.h>\n\n// ---------------------------------------------------------------------------\nnamespace android {\n// ---------------------------------------------------------------------------\n\nclass Condition;\n\n/*\n * NOTE: This class is for code that builds on Win32.  Its usage is\n * deprecated for code which doesn't build for Win32.  New code which\n * doesn't build for Win32 should use std::mutex and std::lock_guard instead.\n *\n * Simple mutex class.  The implementation is system-dependent.\n *\n * The mutex must be unlocked by the thread that locked it.  They are not\n * recursive, i.e. the same thread can't lock it multiple times.\n */\nclass Mutex {\npublic:\n    enum {\n        PRIVATE = 0,\n        SHARED = 1\n    };\n\n                Mutex();\n                Mutex(const char* name);\n                Mutex(int type, const char* name = NULL);\n                ~Mutex();\n\n    // lock or unlock the mutex\n    status_t    lock();\n    void        unlock();\n\n    // lock if possible; returns 0 on success, error otherwise\n    status_t    tryLock();\n\n#if defined(__ANDROID__)\n    // lock the mutex, but don't wait longer than timeoutMilliseconds.\n    // Returns 0 on success, TIMED_OUT for failure due to timeout expiration.\n    //\n    // OSX doesn't have pthread_mutex_timedlock() or equivalent. To keep\n    // capabilities consistent across host OSes, this method is only available\n    // when building Android binaries.\n    status_t    timedLock(nsecs_t timeoutMilliseconds);\n#endif\n\n    // Manages the mutex automatically. It'll be locked when Autolock is\n    // constructed and released when Autolock goes out of scope.\n    class Autolock {\n    public:\n        inline Autolock(Mutex& mutex) : mLock(mutex)  { mLock.lock(); }\n        inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }\n        inline ~Autolock() { mLock.unlock(); }\n    private:\n        Mutex& mLock;\n    };\n\nprivate:\n    friend class Condition;\n\n    // A mutex cannot be copied\n                Mutex(const Mutex&);\n    Mutex&      operator = (const Mutex&);\n\n#if !defined(_WIN32)\n    pthread_mutex_t mMutex;\n#else\n    void    _init();\n    void*   mState;\n#endif\n};\n\n// ---------------------------------------------------------------------------\n\n#if !defined(_WIN32)\n\ninline Mutex::Mutex() {\n    pthread_mutex_init(&mMutex, NULL);\n}\ninline Mutex::Mutex(__attribute__((unused)) const char* name) {\n    pthread_mutex_init(&mMutex, NULL);\n}\ninline Mutex::Mutex(int type, __attribute__((unused)) const char* name) {\n    if (type == SHARED) {\n        pthread_mutexattr_t attr;\n        pthread_mutexattr_init(&attr);\n        pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);\n        pthread_mutex_init(&mMutex, &attr);\n        pthread_mutexattr_destroy(&attr);\n    } else {\n        pthread_mutex_init(&mMutex, NULL);\n    }\n}\ninline Mutex::~Mutex() {\n    pthread_mutex_destroy(&mMutex);\n}\ninline status_t Mutex::lock() {\n    return -pthread_mutex_lock(&mMutex);\n}\ninline void Mutex::unlock() {\n    pthread_mutex_unlock(&mMutex);\n}\ninline status_t Mutex::tryLock() {\n    return -pthread_mutex_trylock(&mMutex);\n}\n#if defined(__ANDROID__)\ninline status_t Mutex::timedLock(nsecs_t timeoutNs) {\n    const struct timespec ts = {\n        /* .tv_sec = */ static_cast<time_t>(timeoutNs / 1000000000),\n        /* .tv_nsec = */ static_cast<long>(timeoutNs % 1000000000),\n    };\n    return -pthread_mutex_timedlock(&mMutex, &ts);\n}\n#endif\n\n#endif // !defined(_WIN32)\n\n// ---------------------------------------------------------------------------\n\n/*\n * Automatic mutex.  Declare one of these at the top of a function.\n * When the function returns, it will go out of scope, and release the\n * mutex.\n */\n\ntypedef Mutex::Autolock AutoMutex;\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n// ---------------------------------------------------------------------------\n\n#endif // _LIBS_UTILS_MUTEX_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/NativeHandle.h",
    "content": "/*\n * Copyright 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_NATIVE_HANDLE_H\n#define ANDROID_NATIVE_HANDLE_H\n\n#include <utils/RefBase.h>\n#include <utils/StrongPointer.h>\n\ntypedef struct native_handle native_handle_t;\n\nnamespace android {\n\nclass NativeHandle: public LightRefBase<NativeHandle> {\npublic:\n    // Create a refcounted wrapper around a native_handle_t, and declare\n    // whether the wrapper owns the handle (so that it should clean up the\n    // handle upon destruction) or not.\n    // If handle is NULL, no NativeHandle will be created.\n    static sp<NativeHandle> create(native_handle_t* handle, bool ownsHandle);\n\n    const native_handle_t* handle() const {\n        return mHandle;\n    }\n\nprivate:\n    // for access to the destructor\n    friend class LightRefBase<NativeHandle>;\n\n    NativeHandle(native_handle_t* handle, bool ownsHandle);\n    virtual ~NativeHandle();\n\n    native_handle_t* mHandle;\n    bool mOwnsHandle;\n\n    // non-copyable\n    NativeHandle(const NativeHandle&);\n    NativeHandle& operator=(const NativeHandle&);\n};\n\n} // namespace android\n\n#endif // ANDROID_NATIVE_HANDLE_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Printer.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_PRINTER_H\n#define ANDROID_PRINTER_H\n\n#include <android/log.h>\n\nnamespace android {\n\n// Interface for printing to an arbitrary data stream\nclass Printer {\npublic:\n    // Print a new line specified by 'string'. \\n is appended automatically.\n    // -- Assumes that the string has no new line in it.\n    virtual void printLine(const char* string = \"\") = 0;\n\n    // Print a new line specified by the format string. \\n is appended automatically.\n    // -- Assumes that the resulting string has no new line in it.\n    virtual void printFormatLine(const char* format, ...) __attribute__((format (printf, 2, 3)));\n\nprotected:\n    Printer();\n    virtual ~Printer();\n}; // class Printer\n\n// Print to logcat\nclass LogPrinter : public Printer {\npublic:\n    // Create a printer using the specified logcat and log priority\n    // - Unless ignoreBlankLines is false, print blank lines to logcat\n    // (Note that the default ALOG behavior is to ignore blank lines)\n    LogPrinter(const char* logtag,\n               android_LogPriority priority = ANDROID_LOG_DEBUG,\n               const char* prefix = 0,\n               bool ignoreBlankLines = false);\n\n    // Print the specified line to logcat. No \\n at the end is necessary.\n    virtual void printLine(const char* string);\n\nprivate:\n    void printRaw(const char* string);\n\n    const char* mLogTag;\n    android_LogPriority mPriority;\n    const char* mPrefix;\n    bool mIgnoreBlankLines;\n}; // class LogPrinter\n\n// Print to a file descriptor\nclass FdPrinter : public Printer {\npublic:\n    // Create a printer using the specified file descriptor.\n    // - Each line will be prefixed with 'indent' number of blank spaces.\n    // - In addition, each line will be prefixed with the 'prefix' string.\n    FdPrinter(int fd, unsigned int indent = 0, const char* prefix = 0);\n\n    // Print the specified line to the file descriptor. \\n is appended automatically.\n    virtual void printLine(const char* string);\n\nprivate:\n    enum {\n        MAX_FORMAT_STRING = 20,\n    };\n\n    int mFd;\n    unsigned int mIndent;\n    const char* mPrefix;\n    char mFormatString[MAX_FORMAT_STRING];\n}; // class FdPrinter\n\nclass String8;\n\n// Print to a String8\nclass String8Printer : public Printer {\npublic:\n    // Create a printer using the specified String8 as the target.\n    // - In addition, each line will be prefixed with the 'prefix' string.\n    // - target's memory lifetime must be a superset of this String8Printer.\n    String8Printer(String8* target, const char* prefix = 0);\n\n    // Append the specified line to the String8. \\n is appended automatically.\n    virtual void printLine(const char* string);\n\nprivate:\n    String8* mTarget;\n    const char* mPrefix;\n}; // class String8Printer\n\n// Print to an existing Printer by adding a prefix to each line\nclass PrefixPrinter : public Printer {\npublic:\n    // Create a printer using the specified printer as the target.\n    PrefixPrinter(Printer& printer, const char* prefix);\n\n    // Print the line (prefixed with prefix) using the printer.\n    virtual void printLine(const char* string);\n\nprivate:\n    Printer& mPrinter;\n    const char* mPrefix;\n};\n\n}; // namespace android\n\n#endif // ANDROID_PRINTER_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/ProcessCallStack.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_PROCESS_CALLSTACK_H\n#define ANDROID_PROCESS_CALLSTACK_H\n\n#include <utils/CallStack.h>\n#include <android/log.h>\n#include <utils/KeyedVector.h>\n#include <utils/String8.h>\n\n#include <time.h>\n#include <sys/types.h>\n\nnamespace android {\n\nclass Printer;\n\n// Collect/print the call stack (function, file, line) traces for all threads in a process.\nclass ProcessCallStack {\npublic:\n    // Create an empty call stack. No-op.\n    ProcessCallStack();\n    // Copy the existing process callstack (no other side effects).\n    ProcessCallStack(const ProcessCallStack& rhs);\n    ~ProcessCallStack();\n\n    // Immediately collect the stack traces for all threads.\n    void update();\n\n    // Print all stack traces to the log using the supplied logtag.\n    void log(const char* logtag, android_LogPriority priority = ANDROID_LOG_DEBUG,\n             const char* prefix = 0) const;\n\n    // Dump all stack traces to the specified file descriptor.\n    void dump(int fd, int indent = 0, const char* prefix = 0) const;\n\n    // Return a string (possibly very long) containing all the stack traces.\n    String8 toString(const char* prefix = 0) const;\n\n    // Dump a serialized representation of all the stack traces to the specified printer.\n    void print(Printer& printer) const;\n\n    // Get the number of threads whose stack traces were collected.\n    size_t size() const;\n\nprivate:\n    void printInternal(Printer& printer, Printer& csPrinter) const;\n\n    // Reset the process's stack frames and metadata.\n    void clear();\n\n    struct ThreadInfo {\n        CallStack callStack;\n        String8 threadName;\n    };\n\n    // tid -> ThreadInfo\n    KeyedVector<pid_t, ThreadInfo> mThreadMap;\n    // Time that update() was last called\n    struct tm mTimeUpdated;\n};\n\n}; // namespace android\n\n#endif // ANDROID_PROCESS_CALLSTACK_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/PropertyMap.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _UTILS_PROPERTY_MAP_H\n#define _UTILS_PROPERTY_MAP_H\n\n#include <utils/KeyedVector.h>\n#include <utils/String8.h>\n#include <utils/Errors.h>\n#include <utils/Tokenizer.h>\n\nnamespace android {\n\n/*\n * Provides a mechanism for passing around string-based property key / value pairs\n * and loading them from property files.\n *\n * The property files have the following simple structure:\n *\n * # Comment\n * key = value\n *\n * Keys and values are any sequence of printable ASCII characters.\n * The '=' separates the key from the value.\n * The key and value may not contain whitespace.\n *\n * The '\\' character is reserved for escape sequences and is not currently supported.\n * The '\"\" character is reserved for quoting and is not currently supported.\n * Files that contain the '\\' or '\"' character will fail to parse.\n *\n * The file must not contain duplicate keys.\n *\n * TODO Support escape sequences and quoted values when needed.\n */\nclass PropertyMap {\npublic:\n    /* Creates an empty property map. */\n    PropertyMap();\n    ~PropertyMap();\n\n    /* Clears the property map. */\n    void clear();\n\n    /* Adds a property.\n     * Replaces the property with the same key if it is already present.\n     */\n    void addProperty(const String8& key, const String8& value);\n\n    /* Returns true if the property map contains the specified key. */\n    bool hasProperty(const String8& key) const;\n\n    /* Gets the value of a property and parses it.\n     * Returns true and sets outValue if the key was found and its value was parsed successfully.\n     * Otherwise returns false and does not modify outValue.  (Also logs a warning.)\n     */\n    bool tryGetProperty(const String8& key, String8& outValue) const;\n    bool tryGetProperty(const String8& key, bool& outValue) const;\n    bool tryGetProperty(const String8& key, int32_t& outValue) const;\n    bool tryGetProperty(const String8& key, float& outValue) const;\n\n    /* Adds all values from the specified property map. */\n    void addAll(const PropertyMap* map);\n\n    /* Gets the underlying property map. */\n    inline const KeyedVector<String8, String8>& getProperties() const { return mProperties; }\n\n    /* Loads a property map from a file. */\n    static status_t load(const String8& filename, PropertyMap** outMap);\n\nprivate:\n    class Parser {\n        PropertyMap* mMap;\n        Tokenizer* mTokenizer;\n\n    public:\n        Parser(PropertyMap* map, Tokenizer* tokenizer);\n        ~Parser();\n        status_t parse();\n\n    private:\n        status_t parseType();\n        status_t parseKey();\n        status_t parseKeyProperty();\n        status_t parseModifier(const String8& token, int32_t* outMetaState);\n        status_t parseCharacterLiteral(char16_t* outCharacter);\n    };\n\n    KeyedVector<String8, String8> mProperties;\n};\n\n} // namespace android\n\n#endif // _UTILS_PROPERTY_MAP_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/RWLock.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBS_UTILS_RWLOCK_H\n#define _LIBS_UTILS_RWLOCK_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#if !defined(_WIN32)\n# include <pthread.h>\n#endif\n\n#include <utils/Errors.h>\n#include <utils/ThreadDefs.h>\n\n// ---------------------------------------------------------------------------\nnamespace android {\n// ---------------------------------------------------------------------------\n\n#if !defined(_WIN32)\n\n/*\n * Simple mutex class.  The implementation is system-dependent.\n *\n * The mutex must be unlocked by the thread that locked it.  They are not\n * recursive, i.e. the same thread can't lock it multiple times.\n */\nclass RWLock {\npublic:\n    enum {\n        PRIVATE = 0,\n        SHARED = 1\n    };\n\n                RWLock();\n                RWLock(const char* name);\n                RWLock(int type, const char* name = NULL);\n                ~RWLock();\n\n    status_t    readLock();\n    status_t    tryReadLock();\n    status_t    writeLock();\n    status_t    tryWriteLock();\n    void        unlock();\n\n    class AutoRLock {\n    public:\n        inline AutoRLock(RWLock& rwlock) : mLock(rwlock)  { mLock.readLock(); }\n        inline ~AutoRLock() { mLock.unlock(); }\n    private:\n        RWLock& mLock;\n    };\n\n    class AutoWLock {\n    public:\n        inline AutoWLock(RWLock& rwlock) : mLock(rwlock)  { mLock.writeLock(); }\n        inline ~AutoWLock() { mLock.unlock(); }\n    private:\n        RWLock& mLock;\n    };\n\nprivate:\n    // A RWLock cannot be copied\n                RWLock(const RWLock&);\n   RWLock&      operator = (const RWLock&);\n\n   pthread_rwlock_t mRWLock;\n};\n\ninline RWLock::RWLock() {\n    pthread_rwlock_init(&mRWLock, NULL);\n}\ninline RWLock::RWLock(__attribute__((unused)) const char* name) {\n    pthread_rwlock_init(&mRWLock, NULL);\n}\ninline RWLock::RWLock(int type, __attribute__((unused)) const char* name) {\n    if (type == SHARED) {\n        pthread_rwlockattr_t attr;\n        pthread_rwlockattr_init(&attr);\n        pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);\n        pthread_rwlock_init(&mRWLock, &attr);\n        pthread_rwlockattr_destroy(&attr);\n    } else {\n        pthread_rwlock_init(&mRWLock, NULL);\n    }\n}\ninline RWLock::~RWLock() {\n    pthread_rwlock_destroy(&mRWLock);\n}\ninline status_t RWLock::readLock() {\n    return -pthread_rwlock_rdlock(&mRWLock);\n}\ninline status_t RWLock::tryReadLock() {\n    return -pthread_rwlock_tryrdlock(&mRWLock);\n}\ninline status_t RWLock::writeLock() {\n    return -pthread_rwlock_wrlock(&mRWLock);\n}\ninline status_t RWLock::tryWriteLock() {\n    return -pthread_rwlock_trywrlock(&mRWLock);\n}\ninline void RWLock::unlock() {\n    pthread_rwlock_unlock(&mRWLock);\n}\n\n#endif // !defined(_WIN32)\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n// ---------------------------------------------------------------------------\n\n#endif // _LIBS_UTILS_RWLOCK_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/RefBase.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_REF_BASE_H\n#define ANDROID_REF_BASE_H\n\n#include <atomic>\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <utils/StrongPointer.h>\n#include <utils/TypeHelpers.h>\n\n// ---------------------------------------------------------------------------\nnamespace android {\n\nclass TextOutput;\nTextOutput& printWeakPointer(TextOutput& to, const void* val);\n\n// ---------------------------------------------------------------------------\n\n#define COMPARE_WEAK(_op_)                                      \\\ninline bool operator _op_ (const sp<T>& o) const {              \\\n    return m_ptr _op_ o.m_ptr;                                  \\\n}                                                               \\\ninline bool operator _op_ (const T* o) const {                  \\\n    return m_ptr _op_ o;                                        \\\n}                                                               \\\ntemplate<typename U>                                            \\\ninline bool operator _op_ (const sp<U>& o) const {              \\\n    return m_ptr _op_ o.m_ptr;                                  \\\n}                                                               \\\ntemplate<typename U>                                            \\\ninline bool operator _op_ (const U* o) const {                  \\\n    return m_ptr _op_ o;                                        \\\n}\n\n// ---------------------------------------------------------------------------\n\nclass ReferenceRenamer {\nprotected:\n    // destructor is purposedly not virtual so we avoid code overhead from\n    // subclasses; we have to make it protected to guarantee that it\n    // cannot be called from this base class (and to make strict compilers\n    // happy).\n    ~ReferenceRenamer() { }\npublic:\n    virtual void operator()(size_t i) const = 0;\n};\n\n// ---------------------------------------------------------------------------\n\nclass RefBase\n{\npublic:\n            void            incStrong(const void* id) const;\n            void            decStrong(const void* id) const;\n    \n            void            forceIncStrong(const void* id) const;\n\n            //! DEBUGGING ONLY: Get current strong ref count.\n            int32_t         getStrongCount() const;\n\n    class weakref_type\n    {\n    public:\n        RefBase*            refBase() const;\n        \n        void                incWeak(const void* id);\n        void                decWeak(const void* id);\n        \n        // acquires a strong reference if there is already one.\n        bool                attemptIncStrong(const void* id);\n        \n        // acquires a weak reference if there is already one.\n        // This is not always safe. see ProcessState.cpp and BpBinder.cpp\n        // for proper use.\n        bool                attemptIncWeak(const void* id);\n\n        //! DEBUGGING ONLY: Get current weak ref count.\n        int32_t             getWeakCount() const;\n\n        //! DEBUGGING ONLY: Print references held on object.\n        void                printRefs() const;\n\n        //! DEBUGGING ONLY: Enable tracking for this object.\n        // enable -- enable/disable tracking\n        // retain -- when tracking is enable, if true, then we save a stack trace\n        //           for each reference and dereference; when retain == false, we\n        //           match up references and dereferences and keep only the \n        //           outstanding ones.\n        \n        void                trackMe(bool enable, bool retain);\n    };\n    \n            weakref_type*   createWeak(const void* id) const;\n            \n            weakref_type*   getWeakRefs() const;\n\n            //! DEBUGGING ONLY: Print references held on object.\n    inline  void            printRefs() const { getWeakRefs()->printRefs(); }\n\n            //! DEBUGGING ONLY: Enable tracking of object.\n    inline  void            trackMe(bool enable, bool retain)\n    { \n        getWeakRefs()->trackMe(enable, retain); \n    }\n\n    typedef RefBase basetype;\n\nprotected:\n                            RefBase();\n    virtual                 ~RefBase();\n    \n    //! Flags for extendObjectLifetime()\n    enum {\n        OBJECT_LIFETIME_STRONG  = 0x0000,\n        OBJECT_LIFETIME_WEAK    = 0x0001,\n        OBJECT_LIFETIME_MASK    = 0x0001\n    };\n    \n            void            extendObjectLifetime(int32_t mode);\n            \n    //! Flags for onIncStrongAttempted()\n    enum {\n        FIRST_INC_STRONG = 0x0001\n    };\n    \n    virtual void            onFirstRef();\n    virtual void            onLastStrongRef(const void* id);\n    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);\n    virtual void            onLastWeakRef(const void* id);\n\nprivate:\n    friend class weakref_type;\n    class weakref_impl;\n    \n                            RefBase(const RefBase& o);\n            RefBase&        operator=(const RefBase& o);\n\nprivate:\n    friend class ReferenceMover;\n\n    static void renameRefs(size_t n, const ReferenceRenamer& renamer);\n\n    static void renameRefId(weakref_type* ref,\n            const void* old_id, const void* new_id);\n\n    static void renameRefId(RefBase* ref,\n            const void* old_id, const void* new_id);\n\n        weakref_impl* const mRefs;\n};\n\n// ---------------------------------------------------------------------------\n\ntemplate <class T>\nclass LightRefBase\n{\npublic:\n    inline LightRefBase() : mCount(0) { }\n    inline void incStrong(__attribute__((unused)) const void* id) const {\n        mCount.fetch_add(1, std::memory_order_relaxed);\n    }\n    inline void decStrong(__attribute__((unused)) const void* id) const {\n        if (mCount.fetch_sub(1, std::memory_order_release) == 1) {\n            std::atomic_thread_fence(std::memory_order_acquire);\n            delete static_cast<const T*>(this);\n        }\n    }\n    //! DEBUGGING ONLY: Get current strong ref count.\n    inline int32_t getStrongCount() const {\n        return mCount.load(std::memory_order_relaxed);\n    }\n\n    typedef LightRefBase<T> basetype;\n\nprotected:\n    inline ~LightRefBase() { }\n\nprivate:\n    friend class ReferenceMover;\n    inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { }\n    inline static void renameRefId(T* ref,\n            const void* old_id, const void* new_id) { }\n\nprivate:\n    mutable std::atomic<int32_t> mCount;\n};\n\n// This is a wrapper around LightRefBase that simply enforces a virtual\n// destructor to eliminate the template requirement of LightRefBase\nclass VirtualLightRefBase : public LightRefBase<VirtualLightRefBase> {\npublic:\n    virtual ~VirtualLightRefBase() {}\n};\n\n// ---------------------------------------------------------------------------\n\ntemplate <typename T>\nclass wp\n{\npublic:\n    typedef typename RefBase::weakref_type weakref_type;\n    \n    inline wp() : m_ptr(0) { }\n\n    wp(T* other);\n    wp(const wp<T>& other);\n    wp(const sp<T>& other);\n    template<typename U> wp(U* other);\n    template<typename U> wp(const sp<U>& other);\n    template<typename U> wp(const wp<U>& other);\n\n    ~wp();\n    \n    // Assignment\n\n    wp& operator = (T* other);\n    wp& operator = (const wp<T>& other);\n    wp& operator = (const sp<T>& other);\n    \n    template<typename U> wp& operator = (U* other);\n    template<typename U> wp& operator = (const wp<U>& other);\n    template<typename U> wp& operator = (const sp<U>& other);\n    \n    void set_object_and_refs(T* other, weakref_type* refs);\n\n    // promotion to sp\n    \n    sp<T> promote() const;\n\n    // Reset\n    \n    void clear();\n\n    // Accessors\n    \n    inline  weakref_type* get_refs() const { return m_refs; }\n    \n    inline  T* unsafe_get() const { return m_ptr; }\n\n    // Operators\n\n    COMPARE_WEAK(==)\n    COMPARE_WEAK(!=)\n    COMPARE_WEAK(>)\n    COMPARE_WEAK(<)\n    COMPARE_WEAK(<=)\n    COMPARE_WEAK(>=)\n\n    inline bool operator == (const wp<T>& o) const {\n        return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);\n    }\n    template<typename U>\n    inline bool operator == (const wp<U>& o) const {\n        return m_ptr == o.m_ptr;\n    }\n\n    inline bool operator > (const wp<T>& o) const {\n        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);\n    }\n    template<typename U>\n    inline bool operator > (const wp<U>& o) const {\n        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);\n    }\n\n    inline bool operator < (const wp<T>& o) const {\n        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);\n    }\n    template<typename U>\n    inline bool operator < (const wp<U>& o) const {\n        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);\n    }\n                         inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }\n    template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }\n                         inline bool operator <= (const wp<T>& o) const { return !operator > (o); }\n    template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }\n                         inline bool operator >= (const wp<T>& o) const { return !operator < (o); }\n    template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }\n\nprivate:\n    template<typename Y> friend class sp;\n    template<typename Y> friend class wp;\n\n    T*              m_ptr;\n    weakref_type*   m_refs;\n};\n\ntemplate <typename T>\nTextOutput& operator<<(TextOutput& to, const wp<T>& val);\n\n#undef COMPARE_WEAK\n\n// ---------------------------------------------------------------------------\n// No user serviceable parts below here.\n\ntemplate<typename T>\nwp<T>::wp(T* other)\n    : m_ptr(other)\n{\n    if (other) m_refs = other->createWeak(this);\n}\n\ntemplate<typename T>\nwp<T>::wp(const wp<T>& other)\n    : m_ptr(other.m_ptr), m_refs(other.m_refs)\n{\n    if (m_ptr) m_refs->incWeak(this);\n}\n\ntemplate<typename T>\nwp<T>::wp(const sp<T>& other)\n    : m_ptr(other.m_ptr)\n{\n    if (m_ptr) {\n        m_refs = m_ptr->createWeak(this);\n    }\n}\n\ntemplate<typename T> template<typename U>\nwp<T>::wp(U* other)\n    : m_ptr(other)\n{\n    if (other) m_refs = other->createWeak(this);\n}\n\ntemplate<typename T> template<typename U>\nwp<T>::wp(const wp<U>& other)\n    : m_ptr(other.m_ptr)\n{\n    if (m_ptr) {\n        m_refs = other.m_refs;\n        m_refs->incWeak(this);\n    }\n}\n\ntemplate<typename T> template<typename U>\nwp<T>::wp(const sp<U>& other)\n    : m_ptr(other.m_ptr)\n{\n    if (m_ptr) {\n        m_refs = m_ptr->createWeak(this);\n    }\n}\n\ntemplate<typename T>\nwp<T>::~wp()\n{\n    if (m_ptr) m_refs->decWeak(this);\n}\n\ntemplate<typename T>\nwp<T>& wp<T>::operator = (T* other)\n{\n    weakref_type* newRefs =\n        other ? other->createWeak(this) : 0;\n    if (m_ptr) m_refs->decWeak(this);\n    m_ptr = other;\n    m_refs = newRefs;\n    return *this;\n}\n\ntemplate<typename T>\nwp<T>& wp<T>::operator = (const wp<T>& other)\n{\n    weakref_type* otherRefs(other.m_refs);\n    T* otherPtr(other.m_ptr);\n    if (otherPtr) otherRefs->incWeak(this);\n    if (m_ptr) m_refs->decWeak(this);\n    m_ptr = otherPtr;\n    m_refs = otherRefs;\n    return *this;\n}\n\ntemplate<typename T>\nwp<T>& wp<T>::operator = (const sp<T>& other)\n{\n    weakref_type* newRefs =\n        other != NULL ? other->createWeak(this) : 0;\n    T* otherPtr(other.m_ptr);\n    if (m_ptr) m_refs->decWeak(this);\n    m_ptr = otherPtr;\n    m_refs = newRefs;\n    return *this;\n}\n\ntemplate<typename T> template<typename U>\nwp<T>& wp<T>::operator = (U* other)\n{\n    weakref_type* newRefs =\n        other ? other->createWeak(this) : 0;\n    if (m_ptr) m_refs->decWeak(this);\n    m_ptr = other;\n    m_refs = newRefs;\n    return *this;\n}\n\ntemplate<typename T> template<typename U>\nwp<T>& wp<T>::operator = (const wp<U>& other)\n{\n    weakref_type* otherRefs(other.m_refs);\n    U* otherPtr(other.m_ptr);\n    if (otherPtr) otherRefs->incWeak(this);\n    if (m_ptr) m_refs->decWeak(this);\n    m_ptr = otherPtr;\n    m_refs = otherRefs;\n    return *this;\n}\n\ntemplate<typename T> template<typename U>\nwp<T>& wp<T>::operator = (const sp<U>& other)\n{\n    weakref_type* newRefs =\n        other != NULL ? other->createWeak(this) : 0;\n    U* otherPtr(other.m_ptr);\n    if (m_ptr) m_refs->decWeak(this);\n    m_ptr = otherPtr;\n    m_refs = newRefs;\n    return *this;\n}\n\ntemplate<typename T>\nvoid wp<T>::set_object_and_refs(T* other, weakref_type* refs)\n{\n    if (other) refs->incWeak(this);\n    if (m_ptr) m_refs->decWeak(this);\n    m_ptr = other;\n    m_refs = refs;\n}\n\ntemplate<typename T>\nsp<T> wp<T>::promote() const\n{\n    sp<T> result;\n    if (m_ptr && m_refs->attemptIncStrong(&result)) {\n        result.set_pointer(m_ptr);\n    }\n    return result;\n}\n\ntemplate<typename T>\nvoid wp<T>::clear()\n{\n    if (m_ptr) {\n        m_refs->decWeak(this);\n        m_ptr = 0;\n    }\n}\n\ntemplate <typename T>\ninline TextOutput& operator<<(TextOutput& to, const wp<T>& val)\n{\n    return printWeakPointer(to, val.unsafe_get());\n}\n\n// ---------------------------------------------------------------------------\n\n// this class just serves as a namespace so TYPE::moveReferences can stay\n// private.\nclass ReferenceMover {\npublic:\n    // it would be nice if we could make sure no extra code is generated\n    // for sp<TYPE> or wp<TYPE> when TYPE is a descendant of RefBase:\n    // Using a sp<RefBase> override doesn't work; it's a bit like we wanted\n    // a template<typename TYPE inherits RefBase> template...\n\n    template<typename TYPE> static inline\n    void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {\n\n        class Renamer : public ReferenceRenamer {\n            sp<TYPE>* d;\n            sp<TYPE> const* s;\n            virtual void operator()(size_t i) const {\n                // The id are known to be the sp<>'s this pointer\n                TYPE::renameRefId(d[i].get(), &s[i], &d[i]);\n            }\n        public:\n            Renamer(sp<TYPE>* d, sp<TYPE> const* s) : d(d), s(s) { }\n            virtual ~Renamer() { }\n        };\n\n        memmove(d, s, n*sizeof(sp<TYPE>));\n        TYPE::renameRefs(n, Renamer(d, s));\n    }\n\n\n    template<typename TYPE> static inline\n    void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {\n\n        class Renamer : public ReferenceRenamer {\n            wp<TYPE>* d;\n            wp<TYPE> const* s;\n            virtual void operator()(size_t i) const {\n                // The id are known to be the wp<>'s this pointer\n                TYPE::renameRefId(d[i].get_refs(), &s[i], &d[i]);\n            }\n        public:\n            Renamer(wp<TYPE>* d, wp<TYPE> const* s) : d(d), s(s) { }\n            virtual ~Renamer() { }\n        };\n\n        memmove(d, s, n*sizeof(wp<TYPE>));\n        TYPE::renameRefs(n, Renamer(d, s));\n    }\n};\n\n// specialization for moving sp<> and wp<> types.\n// these are used by the [Sorted|Keyed]Vector<> implementations\n// sp<> and wp<> need to be handled specially, because they do not\n// have trivial copy operation in the general case (see RefBase.cpp\n// when DEBUG ops are enabled), but can be implemented very\n// efficiently in most cases.\n\ntemplate<typename TYPE> inline\nvoid move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {\n    ReferenceMover::move_references(d, s, n);\n}\n\ntemplate<typename TYPE> inline\nvoid move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {\n    ReferenceMover::move_references(d, s, n);\n}\n\ntemplate<typename TYPE> inline\nvoid move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {\n    ReferenceMover::move_references(d, s, n);\n}\n\ntemplate<typename TYPE> inline\nvoid move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {\n    ReferenceMover::move_references(d, s, n);\n}\n\n\n}; // namespace android\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_REF_BASE_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Singleton.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UTILS_SINGLETON_H\n#define ANDROID_UTILS_SINGLETON_H\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <utils/threads.h>\n#include <cutils/compiler.h>\n\nnamespace android {\n// ---------------------------------------------------------------------------\n\ntemplate <typename TYPE>\nclass ANDROID_API Singleton\n{\npublic:\n    static TYPE& getInstance() {\n        Mutex::Autolock _l(sLock);\n        TYPE* instance = sInstance;\n        if (instance == 0) {\n            instance = new TYPE();\n            sInstance = instance;\n        }\n        return *instance;\n    }\n\n    static bool hasInstance() {\n        Mutex::Autolock _l(sLock);\n        return sInstance != 0;\n    }\n    \nprotected:\n    ~Singleton() { };\n    Singleton() { };\n\nprivate:\n    Singleton(const Singleton&);\n    Singleton& operator = (const Singleton&);\n    static Mutex sLock;\n    static TYPE* sInstance;\n};\n\n/*\n * use ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) in your implementation file\n * (eg: <TYPE>.cpp) to create the static instance of Singleton<>'s attributes,\n * and avoid to have a copy of them in each compilation units Singleton<TYPE>\n * is used.\n * NOTE: we use a version of Mutex ctor that takes a parameter, because\n * for some unknown reason using the default ctor doesn't emit the variable!\n */\n\n#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE)                 \\\n    template<> ::android::Mutex  \\\n        (::android::Singleton< TYPE >::sLock)(::android::Mutex::PRIVATE);  \\\n    template<> TYPE* ::android::Singleton< TYPE >::sInstance(0);  \\\n    template class ::android::Singleton< TYPE >;\n\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n\n#endif // ANDROID_UTILS_SINGLETON_H\n\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/SortedVector.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_SORTED_VECTOR_H\n#define ANDROID_SORTED_VECTOR_H\n\n#include <assert.h>\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <cutils/log.h>\n\n#include <utils/Vector.h>\n#include <utils/VectorImpl.h>\n#include <utils/TypeHelpers.h>\n\n// ---------------------------------------------------------------------------\n\nnamespace android {\n\ntemplate <class TYPE>\nclass SortedVector : private SortedVectorImpl\n{\n    friend class Vector<TYPE>;\n\npublic:\n            typedef TYPE    value_type;\n    \n    /*! \n     * Constructors and destructors\n     */\n    \n                            SortedVector();\n                            SortedVector(const SortedVector<TYPE>& rhs);\n    virtual                 ~SortedVector();\n\n    /*! copy operator */\n    const SortedVector<TYPE>&   operator = (const SortedVector<TYPE>& rhs) const;    \n    SortedVector<TYPE>&         operator = (const SortedVector<TYPE>& rhs);    \n\n    /*\n     * empty the vector\n     */\n\n    inline  void            clear()             { VectorImpl::clear(); }\n\n    /*! \n     * vector stats\n     */\n\n    //! returns number of items in the vector\n    inline  size_t          size() const                { return VectorImpl::size(); }\n    //! returns whether or not the vector is empty\n    inline  bool            isEmpty() const             { return VectorImpl::isEmpty(); }\n    //! returns how many items can be stored without reallocating the backing store\n    inline  size_t          capacity() const            { return VectorImpl::capacity(); }\n    //! sets the capacity. capacity can never be reduced less than size()\n    inline  ssize_t         setCapacity(size_t size)    { return VectorImpl::setCapacity(size); }\n\n    /*! \n     * C-style array access\n     */\n     \n    //! read-only C-style access \n    inline  const TYPE*     array() const;\n\n    //! read-write C-style access. BE VERY CAREFUL when modifying the array\n    //! you must keep it sorted! You usually don't use this function.\n            TYPE*           editArray();\n\n            //! finds the index of an item\n            ssize_t         indexOf(const TYPE& item) const;\n            \n            //! finds where this item should be inserted\n            size_t          orderOf(const TYPE& item) const;\n            \n    \n    /*! \n     * accessors\n     */\n\n    //! read-only access to an item at a given index\n    inline  const TYPE&     operator [] (size_t index) const;\n    //! alternate name for operator []\n    inline  const TYPE&     itemAt(size_t index) const;\n    //! stack-usage of the vector. returns the top of the stack (last element)\n            const TYPE&     top() const;\n\n    /*!\n     * modifying the array\n     */\n\n            //! add an item in the right place (and replace the one that is there)\n            ssize_t         add(const TYPE& item);\n            \n            //! editItemAt() MUST NOT change the order of this item\n            TYPE&           editItemAt(size_t index) {\n                return *( static_cast<TYPE *>(VectorImpl::editItemLocation(index)) );\n            }\n\n            //! merges a vector into this one\n            ssize_t         merge(const Vector<TYPE>& vector);\n            ssize_t         merge(const SortedVector<TYPE>& vector);\n            \n            //! removes an item\n            ssize_t         remove(const TYPE&);\n\n    //! remove several items\n    inline  ssize_t         removeItemsAt(size_t index, size_t count = 1);\n    //! remove one item\n    inline  ssize_t         removeAt(size_t index)  { return removeItemsAt(index); }\n            \nprotected:\n    virtual void    do_construct(void* storage, size_t num) const;\n    virtual void    do_destroy(void* storage, size_t num) const;\n    virtual void    do_copy(void* dest, const void* from, size_t num) const;\n    virtual void    do_splat(void* dest, const void* item, size_t num) const;\n    virtual void    do_move_forward(void* dest, const void* from, size_t num) const;\n    virtual void    do_move_backward(void* dest, const void* from, size_t num) const;\n    virtual int     do_compare(const void* lhs, const void* rhs) const;\n};\n\n// SortedVector<T> can be trivially moved using memcpy() because moving does not\n// require any change to the underlying SharedBuffer contents or reference count.\ntemplate<typename T> struct trait_trivial_move<SortedVector<T> > { enum { value = true }; };\n\n// ---------------------------------------------------------------------------\n// No user serviceable parts from here...\n// ---------------------------------------------------------------------------\n\ntemplate<class TYPE> inline\nSortedVector<TYPE>::SortedVector()\n    : SortedVectorImpl(sizeof(TYPE),\n                ((traits<TYPE>::has_trivial_ctor   ? HAS_TRIVIAL_CTOR   : 0)\n                |(traits<TYPE>::has_trivial_dtor   ? HAS_TRIVIAL_DTOR   : 0)\n                |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0))\n                )\n{\n}\n\ntemplate<class TYPE> inline\nSortedVector<TYPE>::SortedVector(const SortedVector<TYPE>& rhs)\n    : SortedVectorImpl(rhs) {\n}\n\ntemplate<class TYPE> inline\nSortedVector<TYPE>::~SortedVector() {\n    finish_vector();\n}\n\ntemplate<class TYPE> inline\nSortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {\n    SortedVectorImpl::operator = (rhs);\n    return *this; \n}\n\ntemplate<class TYPE> inline\nconst SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {\n    SortedVectorImpl::operator = (rhs);\n    return *this; \n}\n\ntemplate<class TYPE> inline\nconst TYPE* SortedVector<TYPE>::array() const {\n    return static_cast<const TYPE *>(arrayImpl());\n}\n\ntemplate<class TYPE> inline\nTYPE* SortedVector<TYPE>::editArray() {\n    return static_cast<TYPE *>(editArrayImpl());\n}\n\n\ntemplate<class TYPE> inline\nconst TYPE& SortedVector<TYPE>::operator[](size_t index) const {\n    LOG_FATAL_IF(index>=size(),\n            \"%s: index=%u out of range (%u)\", __PRETTY_FUNCTION__,\n            int(index), int(size()));\n    return *(array() + index);\n}\n\ntemplate<class TYPE> inline\nconst TYPE& SortedVector<TYPE>::itemAt(size_t index) const {\n    return operator[](index);\n}\n\ntemplate<class TYPE> inline\nconst TYPE& SortedVector<TYPE>::top() const {\n    return *(array() + size() - 1);\n}\n\ntemplate<class TYPE> inline\nssize_t SortedVector<TYPE>::add(const TYPE& item) {\n    return SortedVectorImpl::add(&item);\n}\n\ntemplate<class TYPE> inline\nssize_t SortedVector<TYPE>::indexOf(const TYPE& item) const {\n    return SortedVectorImpl::indexOf(&item);\n}\n\ntemplate<class TYPE> inline\nsize_t SortedVector<TYPE>::orderOf(const TYPE& item) const {\n    return SortedVectorImpl::orderOf(&item);\n}\n\ntemplate<class TYPE> inline\nssize_t SortedVector<TYPE>::merge(const Vector<TYPE>& vector) {\n    return SortedVectorImpl::merge(reinterpret_cast<const VectorImpl&>(vector));\n}\n\ntemplate<class TYPE> inline\nssize_t SortedVector<TYPE>::merge(const SortedVector<TYPE>& vector) {\n    return SortedVectorImpl::merge(reinterpret_cast<const SortedVectorImpl&>(vector));\n}\n\ntemplate<class TYPE> inline\nssize_t SortedVector<TYPE>::remove(const TYPE& item) {\n    return SortedVectorImpl::remove(&item);\n}\n\ntemplate<class TYPE> inline\nssize_t SortedVector<TYPE>::removeItemsAt(size_t index, size_t count) {\n    return VectorImpl::removeItemsAt(index, count);\n}\n\n// ---------------------------------------------------------------------------\n\ntemplate<class TYPE>\nvoid SortedVector<TYPE>::do_construct(void* storage, size_t num) const {\n    construct_type( reinterpret_cast<TYPE*>(storage), num );\n}\n\ntemplate<class TYPE>\nvoid SortedVector<TYPE>::do_destroy(void* storage, size_t num) const {\n    destroy_type( reinterpret_cast<TYPE*>(storage), num );\n}\n\ntemplate<class TYPE>\nvoid SortedVector<TYPE>::do_copy(void* dest, const void* from, size_t num) const {\n    copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );\n}\n\ntemplate<class TYPE>\nvoid SortedVector<TYPE>::do_splat(void* dest, const void* item, size_t num) const {\n    splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num );\n}\n\ntemplate<class TYPE>\nvoid SortedVector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const {\n    move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );\n}\n\ntemplate<class TYPE>\nvoid SortedVector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const {\n    move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );\n}\n\ntemplate<class TYPE>\nint SortedVector<TYPE>::do_compare(const void* lhs, const void* rhs) const {\n    return compare_type( *reinterpret_cast<const TYPE*>(lhs), *reinterpret_cast<const TYPE*>(rhs) );\n}\n\n}; // namespace android\n\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_SORTED_VECTOR_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/StopWatch.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_STOPWATCH_H\n#define ANDROID_STOPWATCH_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <utils/Timers.h>\n\n// ---------------------------------------------------------------------------\n\nnamespace android {\n\nclass StopWatch\n{\npublic:\n        StopWatch(  const char *name,\n                    int clock = SYSTEM_TIME_MONOTONIC,\n                    uint32_t flags = 0);\n        ~StopWatch();\n        \n        const char* name() const;\n        nsecs_t     lap();\n        nsecs_t     elapsedTime() const;\n\n        void        reset();\n        \nprivate:\n    const char*     mName;\n    int             mClock;\n    uint32_t        mFlags;\n    \n    struct lap_t {\n        nsecs_t     soFar;\n        nsecs_t     thisLap;\n    };\n    \n    nsecs_t         mStartTime;\n    lap_t           mLaps[8];\n    int             mNumLaps;\n};\n\n\n}; // namespace android\n\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_STOPWATCH_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/String16.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_STRING16_H\n#define ANDROID_STRING16_H\n\n#include <utils/Errors.h>\n#include <utils/Unicode.h>\n#include <utils/TypeHelpers.h>\n\n// ---------------------------------------------------------------------------\n\nextern \"C\" {\n\n}\n\n// ---------------------------------------------------------------------------\n\nnamespace android {\n\n// ---------------------------------------------------------------------------\n\nclass SharedBuffer;\nclass String8;\nclass TextOutput;\n\n//! This is a string holding UTF-16 characters.\nclass String16\n{\npublic:\n    /* use String16(StaticLinkage) if you're statically linking against\n     * libutils and declaring an empty static String16, e.g.:\n     *\n     *   static String16 sAStaticEmptyString(String16::kEmptyString);\n     *   static String16 sAnotherStaticEmptyString(sAStaticEmptyString);\n     */\n    enum StaticLinkage { kEmptyString };\n\n                                String16();\n    explicit                    String16(StaticLinkage);\n                                String16(const String16& o);\n                                String16(const String16& o,\n                                         size_t len,\n                                         size_t begin=0);\n    explicit                    String16(const char16_t* o);\n    explicit                    String16(const char16_t* o, size_t len);\n    explicit                    String16(const String8& o);\n    explicit                    String16(const char* o);\n    explicit                    String16(const char* o, size_t len);\n\n                                ~String16();\n    \n    inline  const char16_t*     string() const;\n    \n            size_t              size() const;\n            void                setTo(const String16& other);\n            status_t            setTo(const char16_t* other);\n            status_t            setTo(const char16_t* other, size_t len);\n            status_t            setTo(const String16& other,\n                                      size_t len,\n                                      size_t begin=0);\n    \n            status_t            append(const String16& other);\n            status_t            append(const char16_t* other, size_t len);\n            \n    inline  String16&           operator=(const String16& other);\n    \n    inline  String16&           operator+=(const String16& other);\n    inline  String16            operator+(const String16& other) const;\n\n            status_t            insert(size_t pos, const char16_t* chrs);\n            status_t            insert(size_t pos,\n                                       const char16_t* chrs, size_t len);\n\n            ssize_t             findFirst(char16_t c) const;\n            ssize_t             findLast(char16_t c) const;\n\n            bool                startsWith(const String16& prefix) const;\n            bool                startsWith(const char16_t* prefix) const;\n\n            bool                contains(const char16_t* chrs) const;\n\n            status_t            makeLower();\n\n            status_t            replaceAll(char16_t replaceThis,\n                                           char16_t withThis);\n\n            status_t            remove(size_t len, size_t begin=0);\n\n    inline  int                 compare(const String16& other) const;\n\n    inline  bool                operator<(const String16& other) const;\n    inline  bool                operator<=(const String16& other) const;\n    inline  bool                operator==(const String16& other) const;\n    inline  bool                operator!=(const String16& other) const;\n    inline  bool                operator>=(const String16& other) const;\n    inline  bool                operator>(const String16& other) const;\n    \n    inline  bool                operator<(const char16_t* other) const;\n    inline  bool                operator<=(const char16_t* other) const;\n    inline  bool                operator==(const char16_t* other) const;\n    inline  bool                operator!=(const char16_t* other) const;\n    inline  bool                operator>=(const char16_t* other) const;\n    inline  bool                operator>(const char16_t* other) const;\n    \n    inline                      operator const char16_t*() const;\n    \nprivate:\n            const char16_t*     mString;\n};\n\n// String16 can be trivially moved using memcpy() because moving does not\n// require any change to the underlying SharedBuffer contents or reference count.\nANDROID_TRIVIAL_MOVE_TRAIT(String16)\n\n// ---------------------------------------------------------------------------\n// No user servicable parts below.\n\ninline int compare_type(const String16& lhs, const String16& rhs)\n{\n    return lhs.compare(rhs);\n}\n\ninline int strictly_order_type(const String16& lhs, const String16& rhs)\n{\n    return compare_type(lhs, rhs) < 0;\n}\n\ninline const char16_t* String16::string() const\n{\n    return mString;\n}\n\ninline String16& String16::operator=(const String16& other)\n{\n    setTo(other);\n    return *this;\n}\n\ninline String16& String16::operator+=(const String16& other)\n{\n    append(other);\n    return *this;\n}\n\ninline String16 String16::operator+(const String16& other) const\n{\n    String16 tmp(*this);\n    tmp += other;\n    return tmp;\n}\n\ninline int String16::compare(const String16& other) const\n{\n    return strzcmp16(mString, size(), other.mString, other.size());\n}\n\ninline bool String16::operator<(const String16& other) const\n{\n    return strzcmp16(mString, size(), other.mString, other.size()) < 0;\n}\n\ninline bool String16::operator<=(const String16& other) const\n{\n    return strzcmp16(mString, size(), other.mString, other.size()) <= 0;\n}\n\ninline bool String16::operator==(const String16& other) const\n{\n    return strzcmp16(mString, size(), other.mString, other.size()) == 0;\n}\n\ninline bool String16::operator!=(const String16& other) const\n{\n    return strzcmp16(mString, size(), other.mString, other.size()) != 0;\n}\n\ninline bool String16::operator>=(const String16& other) const\n{\n    return strzcmp16(mString, size(), other.mString, other.size()) >= 0;\n}\n\ninline bool String16::operator>(const String16& other) const\n{\n    return strzcmp16(mString, size(), other.mString, other.size()) > 0;\n}\n\ninline bool String16::operator<(const char16_t* other) const\n{\n    return strcmp16(mString, other) < 0;\n}\n\ninline bool String16::operator<=(const char16_t* other) const\n{\n    return strcmp16(mString, other) <= 0;\n}\n\ninline bool String16::operator==(const char16_t* other) const\n{\n    return strcmp16(mString, other) == 0;\n}\n\ninline bool String16::operator!=(const char16_t* other) const\n{\n    return strcmp16(mString, other) != 0;\n}\n\ninline bool String16::operator>=(const char16_t* other) const\n{\n    return strcmp16(mString, other) >= 0;\n}\n\ninline bool String16::operator>(const char16_t* other) const\n{\n    return strcmp16(mString, other) > 0;\n}\n\ninline String16::operator const char16_t*() const\n{\n    return mString;\n}\n\n}; // namespace android\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_STRING16_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/String8.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_STRING8_H\n#define ANDROID_STRING8_H\n\n#include <utils/Errors.h>\n#include <utils/Unicode.h>\n#include <utils/TypeHelpers.h>\n\n#include <string.h> // for strcmp\n#include <stdarg.h>\n\n// ---------------------------------------------------------------------------\n\nnamespace android {\n\nclass String16;\nclass TextOutput;\n\n//! This is a string holding UTF-8 characters. Does not allow the value more\n// than 0x10FFFF, which is not valid unicode codepoint.\nclass String8\n{\npublic:\n    /* use String8(StaticLinkage) if you're statically linking against\n     * libutils and declaring an empty static String8, e.g.:\n     *\n     *   static String8 sAStaticEmptyString(String8::kEmptyString);\n     *   static String8 sAnotherStaticEmptyString(sAStaticEmptyString);\n     */\n    enum StaticLinkage { kEmptyString };\n\n                                String8();\n    explicit                    String8(StaticLinkage);\n                                String8(const String8& o);\n    explicit                    String8(const char* o);\n    explicit                    String8(const char* o, size_t numChars);\n    \n    explicit                    String8(const String16& o);\n    explicit                    String8(const char16_t* o);\n    explicit                    String8(const char16_t* o, size_t numChars);\n    explicit                    String8(const char32_t* o);\n    explicit                    String8(const char32_t* o, size_t numChars);\n                                ~String8();\n\n    static inline const String8 empty();\n\n    static String8              format(const char* fmt, ...) __attribute__((format (printf, 1, 2)));\n    static String8              formatV(const char* fmt, va_list args);\n\n    inline  const char*         string() const;\n    inline  size_t              size() const;\n    inline  size_t              bytes() const;\n    inline  bool                isEmpty() const;\n    \n            size_t              length() const;\n    \n            void                clear();\n\n            void                setTo(const String8& other);\n            status_t            setTo(const char* other);\n            status_t            setTo(const char* other, size_t numChars);\n            status_t            setTo(const char16_t* other, size_t numChars);\n            status_t            setTo(const char32_t* other,\n                                      size_t length);\n\n            status_t            append(const String8& other);\n            status_t            append(const char* other);\n            status_t            append(const char* other, size_t numChars);\n\n            status_t            appendFormat(const char* fmt, ...)\n                    __attribute__((format (printf, 2, 3)));\n            status_t            appendFormatV(const char* fmt, va_list args);\n\n            // Note that this function takes O(N) time to calculate the value.\n            // No cache value is stored.\n            size_t              getUtf32Length() const;\n            int32_t             getUtf32At(size_t index,\n                                           size_t *next_index) const;\n            void                getUtf32(char32_t* dst) const;\n\n    inline  String8&            operator=(const String8& other);\n    inline  String8&            operator=(const char* other);\n    \n    inline  String8&            operator+=(const String8& other);\n    inline  String8             operator+(const String8& other) const;\n    \n    inline  String8&            operator+=(const char* other);\n    inline  String8             operator+(const char* other) const;\n\n    inline  int                 compare(const String8& other) const;\n\n    inline  bool                operator<(const String8& other) const;\n    inline  bool                operator<=(const String8& other) const;\n    inline  bool                operator==(const String8& other) const;\n    inline  bool                operator!=(const String8& other) const;\n    inline  bool                operator>=(const String8& other) const;\n    inline  bool                operator>(const String8& other) const;\n    \n    inline  bool                operator<(const char* other) const;\n    inline  bool                operator<=(const char* other) const;\n    inline  bool                operator==(const char* other) const;\n    inline  bool                operator!=(const char* other) const;\n    inline  bool                operator>=(const char* other) const;\n    inline  bool                operator>(const char* other) const;\n    \n    inline                      operator const char*() const;\n    \n            char*               lockBuffer(size_t size);\n            void                unlockBuffer();\n            status_t            unlockBuffer(size_t size);\n            \n            // return the index of the first byte of other in this at or after\n            // start, or -1 if not found\n            ssize_t             find(const char* other, size_t start = 0) const;\n\n            // return true if this string contains the specified substring\n    inline  bool                contains(const char* other) const;\n\n            // removes all occurrence of the specified substring\n            // returns true if any were found and removed\n            bool                removeAll(const char* other);\n\n            void                toLower();\n            void                toLower(size_t start, size_t numChars);\n            void                toUpper();\n            void                toUpper(size_t start, size_t numChars);\n\n\n    /*\n     * These methods operate on the string as if it were a path name.\n     */\n\n    /*\n     * Set the filename field to a specific value.\n     *\n     * Normalizes the filename, removing a trailing '/' if present.\n     */\n    void setPathName(const char* name);\n    void setPathName(const char* name, size_t numChars);\n\n    /*\n     * Get just the filename component.\n     *\n     * \"/tmp/foo/bar.c\" --> \"bar.c\"\n     */\n    String8 getPathLeaf(void) const;\n\n    /*\n     * Remove the last (file name) component, leaving just the directory\n     * name.\n     *\n     * \"/tmp/foo/bar.c\" --> \"/tmp/foo\"\n     * \"/tmp\" --> \"\" // ????? shouldn't this be \"/\" ???? XXX\n     * \"bar.c\" --> \"\"\n     */\n    String8 getPathDir(void) const;\n\n    /*\n     * Retrieve the front (root dir) component.  Optionally also return the\n     * remaining components.\n     *\n     * \"/tmp/foo/bar.c\" --> \"tmp\" (remain = \"foo/bar.c\")\n     * \"/tmp\" --> \"tmp\" (remain = \"\")\n     * \"bar.c\" --> \"bar.c\" (remain = \"\")\n     */\n    String8 walkPath(String8* outRemains = NULL) const;\n\n    /*\n     * Return the filename extension.  This is the last '.' and any number\n     * of characters that follow it.  The '.' is included in case we\n     * decide to expand our definition of what constitutes an extension.\n     *\n     * \"/tmp/foo/bar.c\" --> \".c\"\n     * \"/tmp\" --> \"\"\n     * \"/tmp/foo.bar/baz\" --> \"\"\n     * \"foo.jpeg\" --> \".jpeg\"\n     * \"foo.\" --> \"\"\n     */\n    String8 getPathExtension(void) const;\n\n    /*\n     * Return the path without the extension.  Rules for what constitutes\n     * an extension are described in the comment for getPathExtension().\n     *\n     * \"/tmp/foo/bar.c\" --> \"/tmp/foo/bar\"\n     */\n    String8 getBasePath(void) const;\n\n    /*\n     * Add a component to the pathname.  We guarantee that there is\n     * exactly one path separator between the old path and the new.\n     * If there is no existing name, we just copy the new name in.\n     *\n     * If leaf is a fully qualified path (i.e. starts with '/', it\n     * replaces whatever was there before.\n     */\n    String8& appendPath(const char* leaf);\n    String8& appendPath(const String8& leaf)  { return appendPath(leaf.string()); }\n\n    /*\n     * Like appendPath(), but does not affect this string.  Returns a new one instead.\n     */\n    String8 appendPathCopy(const char* leaf) const\n                                             { String8 p(*this); p.appendPath(leaf); return p; }\n    String8 appendPathCopy(const String8& leaf) const { return appendPathCopy(leaf.string()); }\n\n    /*\n     * Converts all separators in this string to /, the default path separator.\n     *\n     * If the default OS separator is backslash, this converts all\n     * backslashes to slashes, in-place. Otherwise it does nothing.\n     * Returns self.\n     */\n    String8& convertToResPath();\n\nprivate:\n            status_t            real_append(const char* other, size_t numChars);\n            char*               find_extension(void) const;\n\n            const char* mString;\n};\n\n// String8 can be trivially moved using memcpy() because moving does not\n// require any change to the underlying SharedBuffer contents or reference count.\nANDROID_TRIVIAL_MOVE_TRAIT(String8)\n\n// ---------------------------------------------------------------------------\n// No user servicable parts below.\n\ninline int compare_type(const String8& lhs, const String8& rhs)\n{\n    return lhs.compare(rhs);\n}\n\ninline int strictly_order_type(const String8& lhs, const String8& rhs)\n{\n    return compare_type(lhs, rhs) < 0;\n}\n\ninline const String8 String8::empty() {\n    return String8();\n}\n\ninline const char* String8::string() const\n{\n    return mString;\n}\n\ninline size_t String8::size() const\n{\n    return length();\n}\n\ninline bool String8::isEmpty() const\n{\n    return length() == 0;\n}\n\ninline size_t String8::bytes() const\n{\n    return length();\n}\n\ninline bool String8::contains(const char* other) const\n{\n    return find(other) >= 0;\n}\n\ninline String8& String8::operator=(const String8& other)\n{\n    setTo(other);\n    return *this;\n}\n\ninline String8& String8::operator=(const char* other)\n{\n    setTo(other);\n    return *this;\n}\n\ninline String8& String8::operator+=(const String8& other)\n{\n    append(other);\n    return *this;\n}\n\ninline String8 String8::operator+(const String8& other) const\n{\n    String8 tmp(*this);\n    tmp += other;\n    return tmp;\n}\n\ninline String8& String8::operator+=(const char* other)\n{\n    append(other);\n    return *this;\n}\n\ninline String8 String8::operator+(const char* other) const\n{\n    String8 tmp(*this);\n    tmp += other;\n    return tmp;\n}\n\ninline int String8::compare(const String8& other) const\n{\n    return strcmp(mString, other.mString);\n}\n\ninline bool String8::operator<(const String8& other) const\n{\n    return strcmp(mString, other.mString) < 0;\n}\n\ninline bool String8::operator<=(const String8& other) const\n{\n    return strcmp(mString, other.mString) <= 0;\n}\n\ninline bool String8::operator==(const String8& other) const\n{\n    return strcmp(mString, other.mString) == 0;\n}\n\ninline bool String8::operator!=(const String8& other) const\n{\n    return strcmp(mString, other.mString) != 0;\n}\n\ninline bool String8::operator>=(const String8& other) const\n{\n    return strcmp(mString, other.mString) >= 0;\n}\n\ninline bool String8::operator>(const String8& other) const\n{\n    return strcmp(mString, other.mString) > 0;\n}\n\ninline bool String8::operator<(const char* other) const\n{\n    return strcmp(mString, other) < 0;\n}\n\ninline bool String8::operator<=(const char* other) const\n{\n    return strcmp(mString, other) <= 0;\n}\n\ninline bool String8::operator==(const char* other) const\n{\n    return strcmp(mString, other) == 0;\n}\n\ninline bool String8::operator!=(const char* other) const\n{\n    return strcmp(mString, other) != 0;\n}\n\ninline bool String8::operator>=(const char* other) const\n{\n    return strcmp(mString, other) >= 0;\n}\n\ninline bool String8::operator>(const char* other) const\n{\n    return strcmp(mString, other) > 0;\n}\n\ninline String8::operator const char*() const\n{\n    return mString;\n}\n\n}  // namespace android\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_STRING8_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/StrongPointer.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_STRONG_POINTER_H\n#define ANDROID_STRONG_POINTER_H\n\n#include <cutils/atomic.h>\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <stdlib.h>\n\n// ---------------------------------------------------------------------------\nnamespace android {\n\ntemplate<typename T> class wp;\n\n// ---------------------------------------------------------------------------\n\n#define COMPARE(_op_)                                           \\\ninline bool operator _op_ (const sp<T>& o) const {              \\\n    return m_ptr _op_ o.m_ptr;                                  \\\n}                                                               \\\ninline bool operator _op_ (const T* o) const {                  \\\n    return m_ptr _op_ o;                                        \\\n}                                                               \\\ntemplate<typename U>                                            \\\ninline bool operator _op_ (const sp<U>& o) const {              \\\n    return m_ptr _op_ o.m_ptr;                                  \\\n}                                                               \\\ntemplate<typename U>                                            \\\ninline bool operator _op_ (const U* o) const {                  \\\n    return m_ptr _op_ o;                                        \\\n}                                                               \\\ninline bool operator _op_ (const wp<T>& o) const {              \\\n    return m_ptr _op_ o.m_ptr;                                  \\\n}                                                               \\\ntemplate<typename U>                                            \\\ninline bool operator _op_ (const wp<U>& o) const {              \\\n    return m_ptr _op_ o.m_ptr;                                  \\\n}\n\n// ---------------------------------------------------------------------------\n\ntemplate<typename T>\nclass sp {\npublic:\n    inline sp() : m_ptr(0) { }\n\n    sp(T* other);\n    sp(const sp<T>& other);\n    sp(sp<T>&& other);\n    template<typename U> sp(U* other);\n    template<typename U> sp(const sp<U>& other);\n    template<typename U> sp(sp<U>&& other);\n\n    ~sp();\n\n    // Assignment\n\n    sp& operator = (T* other);\n    sp& operator = (const sp<T>& other);\n    sp& operator = (sp<T>&& other);\n\n    template<typename U> sp& operator = (const sp<U>& other);\n    template<typename U> sp& operator = (sp<U>&& other);\n    template<typename U> sp& operator = (U* other);\n\n    //! Special optimization for use by ProcessState (and nobody else).\n    void force_set(T* other);\n\n    // Reset\n\n    void clear();\n\n    // Accessors\n\n    inline  T&      operator* () const  { return *m_ptr; }\n    inline  T*      operator-> () const { return m_ptr;  }\n    inline  T*      get() const         { return m_ptr; }\n\n    // Operators\n\n    COMPARE(==)\n    COMPARE(!=)\n    COMPARE(>)\n    COMPARE(<)\n    COMPARE(<=)\n    COMPARE(>=)\n\nprivate:    \n    template<typename Y> friend class sp;\n    template<typename Y> friend class wp;\n    void set_pointer(T* ptr);\n    T* m_ptr;\n};\n\n#undef COMPARE\n\n// ---------------------------------------------------------------------------\n// No user serviceable parts below here.\n\ntemplate<typename T>\nsp<T>::sp(T* other)\n        : m_ptr(other) {\n    if (other)\n        other->incStrong(this);\n}\n\ntemplate<typename T>\nsp<T>::sp(const sp<T>& other)\n        : m_ptr(other.m_ptr) {\n    if (m_ptr)\n        m_ptr->incStrong(this);\n}\n\ntemplate<typename T>\nsp<T>::sp(sp<T>&& other)\n        : m_ptr(other.m_ptr) {\n    other.m_ptr = nullptr;\n}\n\ntemplate<typename T> template<typename U>\nsp<T>::sp(U* other)\n        : m_ptr(other) {\n    if (other)\n        ((T*) other)->incStrong(this);\n}\n\ntemplate<typename T> template<typename U>\nsp<T>::sp(const sp<U>& other)\n        : m_ptr(other.m_ptr) {\n    if (m_ptr)\n        m_ptr->incStrong(this);\n}\n\ntemplate<typename T> template<typename U>\nsp<T>::sp(sp<U>&& other)\n        : m_ptr(other.m_ptr) {\n    other.m_ptr = nullptr;\n}\n\ntemplate<typename T>\nsp<T>::~sp() {\n    if (m_ptr)\n        m_ptr->decStrong(this);\n}\n\ntemplate<typename T>\nsp<T>& sp<T>::operator =(const sp<T>& other) {\n    T* otherPtr(other.m_ptr);\n    if (otherPtr)\n        otherPtr->incStrong(this);\n    if (m_ptr)\n        m_ptr->decStrong(this);\n    m_ptr = otherPtr;\n    return *this;\n}\n\ntemplate<typename T>\nsp<T>& sp<T>::operator =(sp<T>&& other) {\n    if (m_ptr)\n        m_ptr->decStrong(this);\n    m_ptr = other.m_ptr;\n    other.m_ptr = nullptr;\n    return *this;\n}\n\ntemplate<typename T>\nsp<T>& sp<T>::operator =(T* other) {\n    if (other)\n        other->incStrong(this);\n    if (m_ptr)\n        m_ptr->decStrong(this);\n    m_ptr = other;\n    return *this;\n}\n\ntemplate<typename T> template<typename U>\nsp<T>& sp<T>::operator =(const sp<U>& other) {\n    T* otherPtr(other.m_ptr);\n    if (otherPtr)\n        otherPtr->incStrong(this);\n    if (m_ptr)\n        m_ptr->decStrong(this);\n    m_ptr = otherPtr;\n    return *this;\n}\n\ntemplate<typename T> template<typename U>\nsp<T>& sp<T>::operator =(sp<U>&& other) {\n    if (m_ptr)\n        m_ptr->decStrong(this);\n    m_ptr = other.m_ptr;\n    other.m_ptr = nullptr;\n    return *this;\n}\n\ntemplate<typename T> template<typename U>\nsp<T>& sp<T>::operator =(U* other) {\n    if (other)\n        ((T*) other)->incStrong(this);\n    if (m_ptr)\n        m_ptr->decStrong(this);\n    m_ptr = other;\n    return *this;\n}\n\ntemplate<typename T>\nvoid sp<T>::force_set(T* other) {\n    other->forceIncStrong(this);\n    m_ptr = other;\n}\n\ntemplate<typename T>\nvoid sp<T>::clear() {\n    if (m_ptr) {\n        m_ptr->decStrong(this);\n        m_ptr = 0;\n    }\n}\n\ntemplate<typename T>\nvoid sp<T>::set_pointer(T* ptr) {\n    m_ptr = ptr;\n}\n\n}; // namespace android\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_STRONG_POINTER_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/SystemClock.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UTILS_SYSTEMCLOCK_H\n#define ANDROID_UTILS_SYSTEMCLOCK_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\nnamespace android {\n\nint64_t uptimeMillis();\nint64_t elapsedRealtime();\nint64_t elapsedRealtimeNano();\n\n}; // namespace android\n\n#endif // ANDROID_UTILS_SYSTEMCLOCK_H\n\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Thread.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBS_UTILS_THREAD_H\n#define _LIBS_UTILS_THREAD_H\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <time.h>\n\n#if !defined(_WIN32)\n# include <pthread.h>\n#endif\n\n#include <utils/Condition.h>\n#include <utils/Errors.h>\n#include <utils/Mutex.h>\n#include <utils/RefBase.h>\n#include <utils/Timers.h>\n#include <utils/ThreadDefs.h>\n\n// ---------------------------------------------------------------------------\nnamespace android {\n// ---------------------------------------------------------------------------\n\nclass Thread : virtual public RefBase\n{\npublic:\n    // Create a Thread object, but doesn't create or start the associated\n    // thread. See the run() method.\n                        Thread(bool canCallJava = true);\n    virtual             ~Thread();\n\n    // Start the thread in threadLoop() which needs to be implemented.\n    virtual status_t    run(    const char* name,\n                                int32_t priority = PRIORITY_DEFAULT,\n                                size_t stack = 0);\n    \n    // Ask this object's thread to exit. This function is asynchronous, when the\n    // function returns the thread might still be running. Of course, this\n    // function can be called from a different thread.\n    virtual void        requestExit();\n\n    // Good place to do one-time initializations\n    virtual status_t    readyToRun();\n    \n    // Call requestExit() and wait until this object's thread exits.\n    // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call\n    // this function from this object's thread. Will return WOULD_BLOCK in\n    // that case.\n            status_t    requestExitAndWait();\n\n    // Wait until this object's thread exits. Returns immediately if not yet running.\n    // Do not call from this object's thread; will return WOULD_BLOCK in that case.\n            status_t    join();\n\n    // Indicates whether this thread is running or not.\n            bool        isRunning() const;\n\n#if defined(__ANDROID__)\n    // Return the thread's kernel ID, same as the thread itself calling gettid(),\n    // or -1 if the thread is not running.\n            pid_t       getTid() const;\n#endif\n\nprotected:\n    // exitPending() returns true if requestExit() has been called.\n            bool        exitPending() const;\n    \nprivate:\n    // Derived class must implement threadLoop(). The thread starts its life\n    // here. There are two ways of using the Thread object:\n    // 1) loop: if threadLoop() returns true, it will be called again if\n    //          requestExit() wasn't called.\n    // 2) once: if threadLoop() returns false, the thread will exit upon return.\n    virtual bool        threadLoop() = 0;\n\nprivate:\n    Thread& operator=(const Thread&);\n    static  int             _threadLoop(void* user);\n    const   bool            mCanCallJava;\n    // always hold mLock when reading or writing\n            thread_id_t     mThread;\n    mutable Mutex           mLock;\n            Condition       mThreadExitedCondition;\n            status_t        mStatus;\n    // note that all accesses of mExitPending and mRunning need to hold mLock\n    volatile bool           mExitPending;\n    volatile bool           mRunning;\n            sp<Thread>      mHoldSelf;\n#if defined(__ANDROID__)\n    // legacy for debugging, not used by getTid() as it is set by the child thread\n    // and so is not initialized until the child reaches that point\n            pid_t           mTid;\n#endif\n};\n\n\n}; // namespace android\n\n// ---------------------------------------------------------------------------\n#endif // _LIBS_UTILS_THREAD_H\n// ---------------------------------------------------------------------------\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/ThreadDefs.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBS_UTILS_THREAD_DEFS_H\n#define _LIBS_UTILS_THREAD_DEFS_H\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <system/graphics.h>\n#include <system/thread_defs.h>\n\n// ---------------------------------------------------------------------------\n// C API\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifdef _WIN32\ntypedef uint32_t android_thread_id_t;\n#else\ntypedef void* android_thread_id_t;\n#endif\n\ntypedef int (*android_thread_func_t)(void*);\n\n#ifdef __cplusplus\n} // extern \"C\"\n#endif\n\n// ---------------------------------------------------------------------------\n// C++ API\n#ifdef __cplusplus\nnamespace android {\n// ---------------------------------------------------------------------------\n\ntypedef android_thread_id_t thread_id_t;\ntypedef android_thread_func_t thread_func_t;\n\nenum {\n    PRIORITY_LOWEST         = ANDROID_PRIORITY_LOWEST,\n    PRIORITY_BACKGROUND     = ANDROID_PRIORITY_BACKGROUND,\n    PRIORITY_NORMAL         = ANDROID_PRIORITY_NORMAL,\n    PRIORITY_FOREGROUND     = ANDROID_PRIORITY_FOREGROUND,\n    PRIORITY_DISPLAY        = ANDROID_PRIORITY_DISPLAY,\n    PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY,\n    PRIORITY_AUDIO          = ANDROID_PRIORITY_AUDIO,\n    PRIORITY_URGENT_AUDIO   = ANDROID_PRIORITY_URGENT_AUDIO,\n    PRIORITY_HIGHEST        = ANDROID_PRIORITY_HIGHEST,\n    PRIORITY_DEFAULT        = ANDROID_PRIORITY_DEFAULT,\n    PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE,\n    PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE,\n};\n\n// ---------------------------------------------------------------------------\n}; // namespace android\n#endif  // __cplusplus\n// ---------------------------------------------------------------------------\n\n\n#endif // _LIBS_UTILS_THREAD_DEFS_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Timers.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Timer functions.\n//\n#ifndef _LIBS_UTILS_TIMERS_H\n#define _LIBS_UTILS_TIMERS_H\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <sys/time.h>\n\n#include <utils/Compat.h>\n\n// ------------------------------------------------------------------\n// C API\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef int64_t nsecs_t;       // nano-seconds\n\nstatic CONSTEXPR inline nsecs_t seconds_to_nanoseconds(nsecs_t secs)\n{\n    return secs*1000000000;\n}\n\nstatic CONSTEXPR inline nsecs_t milliseconds_to_nanoseconds(nsecs_t secs)\n{\n    return secs*1000000;\n}\n\nstatic CONSTEXPR inline nsecs_t microseconds_to_nanoseconds(nsecs_t secs)\n{\n    return secs*1000;\n}\n\nstatic CONSTEXPR inline nsecs_t nanoseconds_to_seconds(nsecs_t secs)\n{\n    return secs/1000000000;\n}\n\nstatic CONSTEXPR inline nsecs_t nanoseconds_to_milliseconds(nsecs_t secs)\n{\n    return secs/1000000;\n}\n\nstatic CONSTEXPR inline nsecs_t nanoseconds_to_microseconds(nsecs_t secs)\n{\n    return secs/1000;\n}\n\nstatic CONSTEXPR inline nsecs_t s2ns(nsecs_t v)  {return seconds_to_nanoseconds(v);}\nstatic CONSTEXPR inline nsecs_t ms2ns(nsecs_t v) {return milliseconds_to_nanoseconds(v);}\nstatic CONSTEXPR inline nsecs_t us2ns(nsecs_t v) {return microseconds_to_nanoseconds(v);}\nstatic CONSTEXPR inline nsecs_t ns2s(nsecs_t v)  {return nanoseconds_to_seconds(v);}\nstatic CONSTEXPR inline nsecs_t ns2ms(nsecs_t v) {return nanoseconds_to_milliseconds(v);}\nstatic CONSTEXPR inline nsecs_t ns2us(nsecs_t v) {return nanoseconds_to_microseconds(v);}\n\nstatic CONSTEXPR inline nsecs_t seconds(nsecs_t v)      { return s2ns(v); }\nstatic CONSTEXPR inline nsecs_t milliseconds(nsecs_t v) { return ms2ns(v); }\nstatic CONSTEXPR inline nsecs_t microseconds(nsecs_t v) { return us2ns(v); }\n\nenum {\n    SYSTEM_TIME_REALTIME = 0,  // system-wide realtime clock\n    SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point\n    SYSTEM_TIME_PROCESS = 2,   // high-resolution per-process clock\n    SYSTEM_TIME_THREAD = 3,    // high-resolution per-thread clock\n    SYSTEM_TIME_BOOTTIME = 4   // same as SYSTEM_TIME_MONOTONIC, but including CPU suspend time\n};\n\n// return the system-time according to the specified clock\n#ifdef __cplusplus\nnsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC);\n#else\nnsecs_t systemTime(int clock);\n#endif // def __cplusplus\n\n/**\n * Returns the number of milliseconds to wait between the reference time and the timeout time.\n * If the timeout is in the past relative to the reference time, returns 0.\n * If the timeout is more than INT_MAX milliseconds in the future relative to the reference time,\n * such as when timeoutTime == LLONG_MAX, returns -1 to indicate an infinite timeout delay.\n * Otherwise, returns the difference between the reference time and timeout time\n * rounded up to the next millisecond.\n */\nint toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime);\n\n#ifdef __cplusplus\n} // extern \"C\"\n#endif\n\n#endif // _LIBS_UTILS_TIMERS_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Tokenizer.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _UTILS_TOKENIZER_H\n#define _UTILS_TOKENIZER_H\n\n#include <assert.h>\n#include <utils/Errors.h>\n#include <utils/FileMap.h>\n#include <utils/String8.h>\n\nnamespace android {\n\n/**\n * A simple tokenizer for loading and parsing ASCII text files line by line.\n */\nclass Tokenizer {\n    Tokenizer(const String8& filename, FileMap* fileMap, char* buffer,\n            bool ownBuffer, size_t length);\n\npublic:\n    ~Tokenizer();\n\n    /**\n     * Opens a file and maps it into memory.\n     *\n     * Returns NO_ERROR and a tokenizer for the file, if successful.\n     * Otherwise returns an error and sets outTokenizer to NULL.\n     */\n    static status_t open(const String8& filename, Tokenizer** outTokenizer);\n\n    /**\n     * Prepares to tokenize the contents of a string.\n     *\n     * Returns NO_ERROR and a tokenizer for the string, if successful.\n     * Otherwise returns an error and sets outTokenizer to NULL.\n     */\n    static status_t fromContents(const String8& filename,\n            const char* contents, Tokenizer** outTokenizer);\n\n    /**\n     * Returns true if at the end of the file.\n     */\n    inline bool isEof() const { return mCurrent == getEnd(); }\n\n    /**\n     * Returns true if at the end of the line or end of the file.\n     */\n    inline bool isEol() const { return isEof() || *mCurrent == '\\n'; }\n\n    /**\n     * Gets the name of the file.\n     */\n    inline String8 getFilename() const { return mFilename; }\n\n    /**\n     * Gets a 1-based line number index for the current position.\n     */\n    inline int32_t getLineNumber() const { return mLineNumber; }\n\n    /**\n     * Formats a location string consisting of the filename and current line number.\n     * Returns a string like \"MyFile.txt:33\".\n     */\n    String8 getLocation() const;\n\n    /**\n     * Gets the character at the current position.\n     * Returns null at end of file.\n     */\n    inline char peekChar() const { return isEof() ? '\\0' : *mCurrent; }\n\n    /**\n     * Gets the remainder of the current line as a string, excluding the newline character.\n     */\n    String8 peekRemainderOfLine() const;\n\n    /**\n     * Gets the character at the current position and advances past it.\n     * Returns null at end of file.\n     */\n    inline char nextChar() { return isEof() ? '\\0' : *(mCurrent++); }\n\n    /**\n     * Gets the next token on this line stopping at the specified delimiters\n     * or the end of the line whichever comes first and advances past it.\n     * Also stops at embedded nulls.\n     * Returns the token or an empty string if the current character is a delimiter\n     * or is at the end of the line.\n     */\n    String8 nextToken(const char* delimiters);\n\n    /**\n     * Advances to the next line.\n     * Does nothing if already at the end of the file.\n     */\n    void nextLine();\n\n    /**\n     * Skips over the specified delimiters in the line.\n     * Also skips embedded nulls.\n     */\n    void skipDelimiters(const char* delimiters);\n\nprivate:\n    Tokenizer(const Tokenizer& other); // not copyable\n\n    String8 mFilename;\n    FileMap* mFileMap;\n    char* mBuffer;\n    bool mOwnBuffer;\n    size_t mLength;\n\n    const char* mCurrent;\n    int32_t mLineNumber;\n\n    inline const char* getEnd() const { return mBuffer + mLength; }\n\n};\n\n} // namespace android\n\n#endif // _UTILS_TOKENIZER_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Trace.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_TRACE_H\n#define ANDROID_TRACE_H\n\n#if defined(__ANDROID__)\n\n#include <fcntl.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#include <cutils/compiler.h>\n#include <utils/threads.h>\n#include <cutils/trace.h>\n\n// See <cutils/trace.h> for more ATRACE_* macros.\n\n// ATRACE_NAME traces the beginning and end of the current scope.  To trace\n// the correct start and end times this macro should be declared first in the\n// scope body.\n#define ATRACE_NAME(name) android::ScopedTrace ___tracer(ATRACE_TAG, name)\n// ATRACE_CALL is an ATRACE_NAME that uses the current function name.\n#define ATRACE_CALL() ATRACE_NAME(__FUNCTION__)\n\nnamespace android {\n\nclass ScopedTrace {\npublic:\ninline ScopedTrace(uint64_t tag, const char* name)\n    : mTag(tag) {\n    atrace_begin(mTag,name);\n}\n\ninline ~ScopedTrace() {\n    atrace_end(mTag);\n}\n\nprivate:\n    uint64_t mTag;\n};\n\n}; // namespace android\n\n#else // !__ANDROID__\n\n#define ATRACE_NAME(...)\n#define ATRACE_CALL()\n\n#endif // __ANDROID__\n\n#endif // ANDROID_TRACE_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/TypeHelpers.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_TYPE_HELPERS_H\n#define ANDROID_TYPE_HELPERS_H\n\n#include <new>\n#include <stdint.h>\n#include <string.h>\n#include <sys/types.h>\n\n// ---------------------------------------------------------------------------\n\nnamespace android {\n\n/*\n * Types traits\n */\n\ntemplate <typename T> struct trait_trivial_ctor { enum { value = false }; };\ntemplate <typename T> struct trait_trivial_dtor { enum { value = false }; };\ntemplate <typename T> struct trait_trivial_copy { enum { value = false }; };\ntemplate <typename T> struct trait_trivial_move { enum { value = false }; };\ntemplate <typename T> struct trait_pointer      { enum { value = false }; };    \ntemplate <typename T> struct trait_pointer<T*>  { enum { value = true }; };\n\ntemplate <typename TYPE>\nstruct traits {\n    enum {\n        // whether this type is a pointer\n        is_pointer          = trait_pointer<TYPE>::value,\n        // whether this type's constructor is a no-op\n        has_trivial_ctor    = is_pointer || trait_trivial_ctor<TYPE>::value,\n        // whether this type's destructor is a no-op\n        has_trivial_dtor    = is_pointer || trait_trivial_dtor<TYPE>::value,\n        // whether this type type can be copy-constructed with memcpy\n        has_trivial_copy    = is_pointer || trait_trivial_copy<TYPE>::value,\n        // whether this type can be moved with memmove\n        has_trivial_move    = is_pointer || trait_trivial_move<TYPE>::value\n    };\n};\n\ntemplate <typename T, typename U>\nstruct aggregate_traits {\n    enum {\n        is_pointer          = false,\n        has_trivial_ctor    = \n            traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,\n        has_trivial_dtor    = \n            traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,\n        has_trivial_copy    = \n            traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,\n        has_trivial_move    = \n            traits<T>::has_trivial_move && traits<U>::has_trivial_move\n    };\n};\n\n#define ANDROID_TRIVIAL_CTOR_TRAIT( T ) \\\n    template<> struct trait_trivial_ctor< T >   { enum { value = true }; };\n\n#define ANDROID_TRIVIAL_DTOR_TRAIT( T ) \\\n    template<> struct trait_trivial_dtor< T >   { enum { value = true }; };\n\n#define ANDROID_TRIVIAL_COPY_TRAIT( T ) \\\n    template<> struct trait_trivial_copy< T >   { enum { value = true }; };\n\n#define ANDROID_TRIVIAL_MOVE_TRAIT( T ) \\\n    template<> struct trait_trivial_move< T >   { enum { value = true }; };\n\n#define ANDROID_BASIC_TYPES_TRAITS( T ) \\\n    ANDROID_TRIVIAL_CTOR_TRAIT( T ) \\\n    ANDROID_TRIVIAL_DTOR_TRAIT( T ) \\\n    ANDROID_TRIVIAL_COPY_TRAIT( T ) \\\n    ANDROID_TRIVIAL_MOVE_TRAIT( T )\n\n// ---------------------------------------------------------------------------\n\n/*\n * basic types traits\n */\n\nANDROID_BASIC_TYPES_TRAITS( void )\nANDROID_BASIC_TYPES_TRAITS( bool )\nANDROID_BASIC_TYPES_TRAITS( char )\nANDROID_BASIC_TYPES_TRAITS( unsigned char )\nANDROID_BASIC_TYPES_TRAITS( short )\nANDROID_BASIC_TYPES_TRAITS( unsigned short )\nANDROID_BASIC_TYPES_TRAITS( int )\nANDROID_BASIC_TYPES_TRAITS( unsigned int )\nANDROID_BASIC_TYPES_TRAITS( long )\nANDROID_BASIC_TYPES_TRAITS( unsigned long )\nANDROID_BASIC_TYPES_TRAITS( long long )\nANDROID_BASIC_TYPES_TRAITS( unsigned long long )\nANDROID_BASIC_TYPES_TRAITS( float )\nANDROID_BASIC_TYPES_TRAITS( double )\n\n// ---------------------------------------------------------------------------\n\n\n/*\n * compare and order types\n */\n\ntemplate<typename TYPE> inline\nint strictly_order_type(const TYPE& lhs, const TYPE& rhs) {\n    return (lhs < rhs) ? 1 : 0;\n}\n\ntemplate<typename TYPE> inline\nint compare_type(const TYPE& lhs, const TYPE& rhs) {\n    return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);\n}\n\n/*\n * create, destroy, copy and move types...\n */\n\ntemplate<typename TYPE> inline\nvoid construct_type(TYPE* p, size_t n) {\n    if (!traits<TYPE>::has_trivial_ctor) {\n        while (n > 0) {\n            n--;\n            new(p++) TYPE;\n        }\n    }\n}\n\ntemplate<typename TYPE> inline\nvoid destroy_type(TYPE* p, size_t n) {\n    if (!traits<TYPE>::has_trivial_dtor) {\n        while (n > 0) {\n            n--;\n            p->~TYPE();\n            p++;\n        }\n    }\n}\n\ntemplate<typename TYPE> inline\nvoid copy_type(TYPE* d, const TYPE* s, size_t n) {\n    if (!traits<TYPE>::has_trivial_copy) {\n        while (n > 0) {\n            n--;\n            new(d) TYPE(*s);\n            d++, s++;\n        }\n    } else {\n        memcpy(d,s,n*sizeof(TYPE));\n    }\n}\n\ntemplate<typename TYPE> inline\nvoid splat_type(TYPE* where, const TYPE* what, size_t n) {\n    if (!traits<TYPE>::has_trivial_copy) {\n        while (n > 0) {\n            n--;\n            new(where) TYPE(*what);\n            where++;\n        }\n    } else {\n        while (n > 0) {\n            n--;\n            *where++ = *what;\n        }\n    }\n}\n\ntemplate<typename TYPE> inline\nvoid move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {\n    if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy) \n            || traits<TYPE>::has_trivial_move) \n    {\n        memmove(d,s,n*sizeof(TYPE));\n    } else {\n        d += n;\n        s += n;\n        while (n > 0) {\n            n--;\n            --d, --s;\n            if (!traits<TYPE>::has_trivial_copy) {\n                new(d) TYPE(*s);\n            } else {\n                *d = *s;   \n            }\n            if (!traits<TYPE>::has_trivial_dtor) {\n                s->~TYPE();\n            }\n        }\n    }\n}\n\ntemplate<typename TYPE> inline\nvoid move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {\n    if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy) \n            || traits<TYPE>::has_trivial_move) \n    {\n        memmove(d,s,n*sizeof(TYPE));\n    } else {\n        while (n > 0) {\n            n--;\n            if (!traits<TYPE>::has_trivial_copy) {\n                new(d) TYPE(*s);\n            } else {\n                *d = *s;   \n            }\n            if (!traits<TYPE>::has_trivial_dtor) {\n                s->~TYPE();\n            }\n            d++, s++;\n        }\n    }\n}\n\n// ---------------------------------------------------------------------------\n\n/*\n * a key/value pair\n */\n\ntemplate <typename KEY, typename VALUE>\nstruct key_value_pair_t {\n    typedef KEY key_t;\n    typedef VALUE value_t;\n\n    KEY     key;\n    VALUE   value;\n    key_value_pair_t() { }\n    key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }\n    key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v)  { }\n    key_value_pair_t(const KEY& k) : key(k) { }\n    inline bool operator < (const key_value_pair_t& o) const {\n        return strictly_order_type(key, o.key);\n    }\n    inline const KEY& getKey() const {\n        return key;\n    }\n    inline const VALUE& getValue() const {\n        return value;\n    }\n};\n\ntemplate <typename K, typename V>\nstruct trait_trivial_ctor< key_value_pair_t<K, V> >\n{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };\ntemplate <typename K, typename V>\nstruct trait_trivial_dtor< key_value_pair_t<K, V> >\n{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };\ntemplate <typename K, typename V>\nstruct trait_trivial_copy< key_value_pair_t<K, V> >\n{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };\ntemplate <typename K, typename V>\nstruct trait_trivial_move< key_value_pair_t<K, V> >\n{ enum { value = aggregate_traits<K,V>::has_trivial_move }; };\n\n// ---------------------------------------------------------------------------\n\n/*\n * Hash codes.\n */\ntypedef uint32_t hash_t;\n\ntemplate <typename TKey>\nhash_t hash_type(const TKey& key);\n\n/* Built-in hash code specializations.\n * Assumes pointers are 32bit. */\n#define ANDROID_INT32_HASH(T) \\\n        template <> inline hash_t hash_type(const T& value) { return hash_t(value); }\n#define ANDROID_INT64_HASH(T) \\\n        template <> inline hash_t hash_type(const T& value) { \\\n                return hash_t((value >> 32) ^ value); }\n#define ANDROID_REINTERPRET_HASH(T, R) \\\n        template <> inline hash_t hash_type(const T& value) { \\\n                return hash_type(*reinterpret_cast<const R*>(&value)); }\n\nANDROID_INT32_HASH(bool)\nANDROID_INT32_HASH(int8_t)\nANDROID_INT32_HASH(uint8_t)\nANDROID_INT32_HASH(int16_t)\nANDROID_INT32_HASH(uint16_t)\nANDROID_INT32_HASH(int32_t)\nANDROID_INT32_HASH(uint32_t)\nANDROID_INT64_HASH(int64_t)\nANDROID_INT64_HASH(uint64_t)\nANDROID_REINTERPRET_HASH(float, uint32_t)\nANDROID_REINTERPRET_HASH(double, uint64_t)\n\ntemplate <typename T> inline hash_t hash_type(T* const & value) {\n    return hash_type(uintptr_t(value));\n}\n\n}; // namespace android\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_TYPE_HELPERS_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Unicode.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_UNICODE_H\n#define ANDROID_UNICODE_H\n\n#include <sys/types.h>\n#include <stdint.h>\n\nextern \"C\" {\n\n// Standard string functions on char16_t strings.\nint strcmp16(const char16_t *, const char16_t *);\nint strncmp16(const char16_t *s1, const char16_t *s2, size_t n);\nsize_t strlen16(const char16_t *);\nsize_t strnlen16(const char16_t *, size_t);\nchar16_t *strcpy16(char16_t *, const char16_t *);\nchar16_t *strncpy16(char16_t *, const char16_t *, size_t);\nchar16_t *strstr16(const char16_t*, const char16_t*);\n\n// Version of comparison that supports embedded nulls.\n// This is different than strncmp() because we don't stop\n// at a nul character and consider the strings to be different\n// if the lengths are different (thus we need to supply the\n// lengths of both strings).  This can also be used when\n// your string is not nul-terminated as it will have the\n// equivalent result as strcmp16 (unlike strncmp16).\nint strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2);\n\n// Version of strzcmp16 for comparing strings in different endianness.\nint strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2);\n\n// Standard string functions on char32_t strings.\nsize_t strlen32(const char32_t *);\nsize_t strnlen32(const char32_t *, size_t);\n\n/**\n * Measure the length of a UTF-32 string in UTF-8. If the string is invalid\n * such as containing a surrogate character, -1 will be returned.\n */\nssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len);\n\n/**\n * Stores a UTF-8 string converted from \"src\" in \"dst\", if \"dst_length\" is not\n * large enough to store the string, the part of the \"src\" string is stored\n * into \"dst\" as much as possible. See the examples for more detail.\n * Returns the size actually used for storing the string.\n * dst\" is not null-terminated when dst_len is fully used (like strncpy).\n *\n * Example 1\n * \"src\" == \\u3042\\u3044 (\\xE3\\x81\\x82\\xE3\\x81\\x84)\n * \"src_len\" == 2\n * \"dst_len\" >= 7\n * ->\n * Returned value == 6\n * \"dst\" becomes \\xE3\\x81\\x82\\xE3\\x81\\x84\\0\n * (note that \"dst\" is null-terminated)\n *\n * Example 2\n * \"src\" == \\u3042\\u3044 (\\xE3\\x81\\x82\\xE3\\x81\\x84)\n * \"src_len\" == 2\n * \"dst_len\" == 5\n * ->\n * Returned value == 3\n * \"dst\" becomes \\xE3\\x81\\x82\\0\n * (note that \"dst\" is null-terminated, but \\u3044 is not stored in \"dst\"\n * since \"dst\" does not have enough size to store the character)\n *\n * Example 3\n * \"src\" == \\u3042\\u3044 (\\xE3\\x81\\x82\\xE3\\x81\\x84)\n * \"src_len\" == 2\n * \"dst_len\" == 6\n * ->\n * Returned value == 6\n * \"dst\" becomes \\xE3\\x81\\x82\\xE3\\x81\\x84\n * (note that \"dst\" is NOT null-terminated, like strncpy)\n */\nvoid utf32_to_utf8(const char32_t* src, size_t src_len, char* dst, size_t dst_len);\n\n/**\n * Returns the unicode value at \"index\".\n * Returns -1 when the index is invalid (equals to or more than \"src_len\").\n * If returned value is positive, it is able to be converted to char32_t, which\n * is unsigned. Then, if \"next_index\" is not NULL, the next index to be used is\n * stored in \"next_index\". \"next_index\" can be NULL.\n */\nint32_t utf32_from_utf8_at(const char *src, size_t src_len, size_t index, size_t *next_index);\n\n\n/**\n * Returns the UTF-8 length of UTF-16 string \"src\".\n */\nssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len);\n\n/**\n * Converts a UTF-16 string to UTF-8. The destination buffer must be large\n * enough to fit the UTF-16 as measured by utf16_to_utf8_length with an added\n * NULL terminator.\n */\nvoid utf16_to_utf8(const char16_t* src, size_t src_len, char* dst, size_t dst_len);\n\n/**\n * Returns the length of \"src\" when \"src\" is valid UTF-8 string.\n * Returns 0 if src is NULL or 0-length string. Returns -1 when the source\n * is an invalid string.\n *\n * This function should be used to determine whether \"src\" is valid UTF-8\n * characters with valid unicode codepoints. \"src\" must be null-terminated.\n *\n * If you are going to use other utf8_to_... functions defined in this header\n * with string which may not be valid UTF-8 with valid codepoint (form 0 to\n * 0x10FFFF), you should use this function before calling others, since the\n * other functions do not check whether the string is valid UTF-8 or not.\n *\n * If you do not care whether \"src\" is valid UTF-8 or not, you should use\n * strlen() as usual, which should be much faster.\n */\nssize_t utf8_length(const char *src);\n\n/**\n * Measure the length of a UTF-32 string.\n */\nsize_t utf8_to_utf32_length(const char *src, size_t src_len);\n\n/**\n * Stores a UTF-32 string converted from \"src\" in \"dst\". \"dst\" must be large\n * enough to store the entire converted string as measured by\n * utf8_to_utf32_length plus space for a NULL terminator.\n */\nvoid utf8_to_utf32(const char* src, size_t src_len, char32_t* dst);\n\n/**\n * Returns the UTF-16 length of UTF-8 string \"src\".\n */\nssize_t utf8_to_utf16_length(const uint8_t* src, size_t srcLen);\n\n/**\n * Convert UTF-8 to UTF-16 including surrogate pairs.\n * Returns a pointer to the end of the string (where a null terminator might go\n * if you wanted to add one).\n */\nchar16_t* utf8_to_utf16_no_null_terminator(const uint8_t* src, size_t srcLen, char16_t* dst);\n\n/**\n * Convert UTF-8 to UTF-16 including surrogate pairs. The destination buffer\n * must be large enough to hold the result as measured by utf8_to_utf16_length\n * plus an added NULL terminator.\n */\nvoid utf8_to_utf16(const uint8_t* src, size_t srcLen, char16_t* dst);\n\n/**\n * Like utf8_to_utf16_no_null_terminator, but you can supply a maximum length of the\n * decoded string.  The decoded string will fill up to that length; if it is longer\n * the returned pointer will be to the character after dstLen.\n */\nchar16_t* utf8_to_utf16_n(const uint8_t* src, size_t srcLen, char16_t* dst, size_t dstLen);\n\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/Vector.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_VECTOR_H\n#define ANDROID_VECTOR_H\n\n#include <new>\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <cutils/log.h>\n\n#include <utils/VectorImpl.h>\n#include <utils/TypeHelpers.h>\n\n// ---------------------------------------------------------------------------\n\nnamespace android {\n\ntemplate <typename TYPE>\nclass SortedVector;\n\n/*!\n * The main templated vector class ensuring type safety\n * while making use of VectorImpl.\n * This is the class users want to use.\n */\n\ntemplate <class TYPE>\nclass Vector : private VectorImpl\n{\npublic:\n            typedef TYPE    value_type;\n    \n    /*! \n     * Constructors and destructors\n     */\n    \n                            Vector();\n                            Vector(const Vector<TYPE>& rhs);\n    explicit                Vector(const SortedVector<TYPE>& rhs);\n    virtual                 ~Vector();\n\n    /*! copy operator */\n            const Vector<TYPE>&     operator = (const Vector<TYPE>& rhs) const;\n            Vector<TYPE>&           operator = (const Vector<TYPE>& rhs);    \n\n            const Vector<TYPE>&     operator = (const SortedVector<TYPE>& rhs) const;\n            Vector<TYPE>&           operator = (const SortedVector<TYPE>& rhs);\n\n            /*\n     * empty the vector\n     */\n\n    inline  void            clear()             { VectorImpl::clear(); }\n\n    /*! \n     * vector stats\n     */\n\n    //! returns number of items in the vector\n    inline  size_t          size() const                { return VectorImpl::size(); }\n    //! returns whether or not the vector is empty\n    inline  bool            isEmpty() const             { return VectorImpl::isEmpty(); }\n    //! returns how many items can be stored without reallocating the backing store\n    inline  size_t          capacity() const            { return VectorImpl::capacity(); }\n    //! sets the capacity. capacity can never be reduced less than size()\n    inline  ssize_t         setCapacity(size_t size)    { return VectorImpl::setCapacity(size); }\n\n    /*!\n     * set the size of the vector. items are appended with the default\n     * constructor, or removed from the end as needed.\n     */\n    inline  ssize_t         resize(size_t size)         { return VectorImpl::resize(size); }\n\n    /*!\n     * C-style array access\n     */\n     \n    //! read-only C-style access \n    inline  const TYPE*     array() const;\n    //! read-write C-style access\n            TYPE*           editArray();\n    \n    /*! \n     * accessors\n     */\n\n    //! read-only access to an item at a given index\n    inline  const TYPE&     operator [] (size_t index) const;\n    //! alternate name for operator []\n    inline  const TYPE&     itemAt(size_t index) const;\n    //! stack-usage of the vector. returns the top of the stack (last element)\n            const TYPE&     top() const;\n\n    /*!\n     * modifying the array\n     */\n\n    //! copy-on write support, grants write access to an item\n            TYPE&           editItemAt(size_t index);\n    //! grants right access to the top of the stack (last element)\n            TYPE&           editTop();\n\n            /*! \n             * append/insert another vector\n             */\n            \n    //! insert another vector at a given index\n            ssize_t         insertVectorAt(const Vector<TYPE>& vector, size_t index);\n\n    //! append another vector at the end of this one\n            ssize_t         appendVector(const Vector<TYPE>& vector);\n\n\n    //! insert an array at a given index\n            ssize_t         insertArrayAt(const TYPE* array, size_t index, size_t length);\n\n    //! append an array at the end of this vector\n            ssize_t         appendArray(const TYPE* array, size_t length);\n\n            /*! \n             * add/insert/replace items\n             */\n             \n    //! insert one or several items initialized with their default constructor\n    inline  ssize_t         insertAt(size_t index, size_t numItems = 1);\n    //! insert one or several items initialized from a prototype item\n            ssize_t         insertAt(const TYPE& prototype_item, size_t index, size_t numItems = 1);\n    //! pop the top of the stack (removes the last element). No-op if the stack's empty\n    inline  void            pop();\n    //! pushes an item initialized with its default constructor\n    inline  void            push();\n    //! pushes an item on the top of the stack\n            void            push(const TYPE& item);\n    //! same as push() but returns the index the item was added at (or an error)\n    inline  ssize_t         add();\n    //! same as push() but returns the index the item was added at (or an error)\n            ssize_t         add(const TYPE& item);            \n    //! replace an item with a new one initialized with its default constructor\n    inline  ssize_t         replaceAt(size_t index);\n    //! replace an item with a new one\n            ssize_t         replaceAt(const TYPE& item, size_t index);\n\n    /*!\n     * remove items\n     */\n\n    //! remove several items\n    inline  ssize_t         removeItemsAt(size_t index, size_t count = 1);\n    //! remove one item\n    inline  ssize_t         removeAt(size_t index)  { return removeItemsAt(index); }\n\n    /*!\n     * sort (stable) the array\n     */\n     \n     typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs);\n     typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state);\n     \n     inline status_t        sort(compar_t cmp);\n     inline status_t        sort(compar_r_t cmp, void* state);\n\n     // for debugging only\n     inline size_t getItemSize() const { return itemSize(); }\n\n\n     /*\n      * these inlines add some level of compatibility with STL. eventually\n      * we should probably turn things around.\n      */\n     typedef TYPE* iterator;\n     typedef TYPE const* const_iterator;\n\n     inline iterator begin() { return editArray(); }\n     inline iterator end()   { return editArray() + size(); }\n     inline const_iterator begin() const { return array(); }\n     inline const_iterator end() const   { return array() + size(); }\n     inline void reserve(size_t n) { setCapacity(n); }\n     inline bool empty() const{ return isEmpty(); }\n     inline void push_back(const TYPE& item)  { insertAt(item, size(), 1); }\n     inline void push_front(const TYPE& item) { insertAt(item, 0, 1); }\n     inline iterator erase(iterator pos) {\n         ssize_t index = removeItemsAt(pos-array());\n         return begin() + index;\n     }\n\nprotected:\n    virtual void    do_construct(void* storage, size_t num) const;\n    virtual void    do_destroy(void* storage, size_t num) const;\n    virtual void    do_copy(void* dest, const void* from, size_t num) const;\n    virtual void    do_splat(void* dest, const void* item, size_t num) const;\n    virtual void    do_move_forward(void* dest, const void* from, size_t num) const;\n    virtual void    do_move_backward(void* dest, const void* from, size_t num) const;\n};\n\n// Vector<T> can be trivially moved using memcpy() because moving does not\n// require any change to the underlying SharedBuffer contents or reference count.\ntemplate<typename T> struct trait_trivial_move<Vector<T> > { enum { value = true }; };\n\n// ---------------------------------------------------------------------------\n// No user serviceable parts from here...\n// ---------------------------------------------------------------------------\n\ntemplate<class TYPE> inline\nVector<TYPE>::Vector()\n    : VectorImpl(sizeof(TYPE),\n                ((traits<TYPE>::has_trivial_ctor   ? HAS_TRIVIAL_CTOR   : 0)\n                |(traits<TYPE>::has_trivial_dtor   ? HAS_TRIVIAL_DTOR   : 0)\n                |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0))\n                )\n{\n}\n\ntemplate<class TYPE> inline\nVector<TYPE>::Vector(const Vector<TYPE>& rhs)\n    : VectorImpl(rhs) {\n}\n\ntemplate<class TYPE> inline\nVector<TYPE>::Vector(const SortedVector<TYPE>& rhs)\n    : VectorImpl(static_cast<const VectorImpl&>(rhs)) {\n}\n\ntemplate<class TYPE> inline\nVector<TYPE>::~Vector() {\n    finish_vector();\n}\n\ntemplate<class TYPE> inline\nVector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) {\n    VectorImpl::operator = (rhs);\n    return *this; \n}\n\ntemplate<class TYPE> inline\nconst Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) const {\n    VectorImpl::operator = (static_cast<const VectorImpl&>(rhs));\n    return *this;\n}\n\ntemplate<class TYPE> inline\nVector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {\n    VectorImpl::operator = (static_cast<const VectorImpl&>(rhs));\n    return *this;\n}\n\ntemplate<class TYPE> inline\nconst Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {\n    VectorImpl::operator = (rhs);\n    return *this; \n}\n\ntemplate<class TYPE> inline\nconst TYPE* Vector<TYPE>::array() const {\n    return static_cast<const TYPE *>(arrayImpl());\n}\n\ntemplate<class TYPE> inline\nTYPE* Vector<TYPE>::editArray() {\n    return static_cast<TYPE *>(editArrayImpl());\n}\n\n\ntemplate<class TYPE> inline\nconst TYPE& Vector<TYPE>::operator[](size_t index) const {\n    LOG_FATAL_IF(index>=size(),\n            \"%s: index=%u out of range (%u)\", __PRETTY_FUNCTION__,\n            int(index), int(size()));\n    return *(array() + index);\n}\n\ntemplate<class TYPE> inline\nconst TYPE& Vector<TYPE>::itemAt(size_t index) const {\n    return operator[](index);\n}\n\ntemplate<class TYPE> inline\nconst TYPE& Vector<TYPE>::top() const {\n    return *(array() + size() - 1);\n}\n\ntemplate<class TYPE> inline\nTYPE& Vector<TYPE>::editItemAt(size_t index) {\n    return *( static_cast<TYPE *>(editItemLocation(index)) );\n}\n\ntemplate<class TYPE> inline\nTYPE& Vector<TYPE>::editTop() {\n    return *( static_cast<TYPE *>(editItemLocation(size()-1)) );\n}\n\ntemplate<class TYPE> inline\nssize_t Vector<TYPE>::insertVectorAt(const Vector<TYPE>& vector, size_t index) {\n    return VectorImpl::insertVectorAt(reinterpret_cast<const VectorImpl&>(vector), index);\n}\n\ntemplate<class TYPE> inline\nssize_t Vector<TYPE>::appendVector(const Vector<TYPE>& vector) {\n    return VectorImpl::appendVector(reinterpret_cast<const VectorImpl&>(vector));\n}\n\ntemplate<class TYPE> inline\nssize_t Vector<TYPE>::insertArrayAt(const TYPE* array, size_t index, size_t length) {\n    return VectorImpl::insertArrayAt(array, index, length);\n}\n\ntemplate<class TYPE> inline\nssize_t Vector<TYPE>::appendArray(const TYPE* array, size_t length) {\n    return VectorImpl::appendArray(array, length);\n}\n\ntemplate<class TYPE> inline\nssize_t Vector<TYPE>::insertAt(const TYPE& item, size_t index, size_t numItems) {\n    return VectorImpl::insertAt(&item, index, numItems);\n}\n\ntemplate<class TYPE> inline\nvoid Vector<TYPE>::push(const TYPE& item) {\n    return VectorImpl::push(&item);\n}\n\ntemplate<class TYPE> inline\nssize_t Vector<TYPE>::add(const TYPE& item) {\n    return VectorImpl::add(&item);\n}\n\ntemplate<class TYPE> inline\nssize_t Vector<TYPE>::replaceAt(const TYPE& item, size_t index) {\n    return VectorImpl::replaceAt(&item, index);\n}\n\ntemplate<class TYPE> inline\nssize_t Vector<TYPE>::insertAt(size_t index, size_t numItems) {\n    return VectorImpl::insertAt(index, numItems);\n}\n\ntemplate<class TYPE> inline\nvoid Vector<TYPE>::pop() {\n    VectorImpl::pop();\n}\n\ntemplate<class TYPE> inline\nvoid Vector<TYPE>::push() {\n    VectorImpl::push();\n}\n\ntemplate<class TYPE> inline\nssize_t Vector<TYPE>::add() {\n    return VectorImpl::add();\n}\n\ntemplate<class TYPE> inline\nssize_t Vector<TYPE>::replaceAt(size_t index) {\n    return VectorImpl::replaceAt(index);\n}\n\ntemplate<class TYPE> inline\nssize_t Vector<TYPE>::removeItemsAt(size_t index, size_t count) {\n    return VectorImpl::removeItemsAt(index, count);\n}\n\ntemplate<class TYPE> inline\nstatus_t Vector<TYPE>::sort(Vector<TYPE>::compar_t cmp) {\n    return VectorImpl::sort((VectorImpl::compar_t)cmp);\n}\n\ntemplate<class TYPE> inline\nstatus_t Vector<TYPE>::sort(Vector<TYPE>::compar_r_t cmp, void* state) {\n    return VectorImpl::sort((VectorImpl::compar_r_t)cmp, state);\n}\n\n// ---------------------------------------------------------------------------\n\ntemplate<class TYPE>\nvoid Vector<TYPE>::do_construct(void* storage, size_t num) const {\n    construct_type( reinterpret_cast<TYPE*>(storage), num );\n}\n\ntemplate<class TYPE>\nvoid Vector<TYPE>::do_destroy(void* storage, size_t num) const {\n    destroy_type( reinterpret_cast<TYPE*>(storage), num );\n}\n\ntemplate<class TYPE>\nvoid Vector<TYPE>::do_copy(void* dest, const void* from, size_t num) const {\n    copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );\n}\n\ntemplate<class TYPE>\nvoid Vector<TYPE>::do_splat(void* dest, const void* item, size_t num) const {\n    splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num );\n}\n\ntemplate<class TYPE>\nvoid Vector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const {\n    move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );\n}\n\ntemplate<class TYPE>\nvoid Vector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const {\n    move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );\n}\n\n}; // namespace android\n\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_VECTOR_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/VectorImpl.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef ANDROID_VECTOR_IMPL_H\n#define ANDROID_VECTOR_IMPL_H\n\n#include <assert.h>\n#include <stdint.h>\n#include <sys/types.h>\n#include <utils/Errors.h>\n\n// ---------------------------------------------------------------------------\n// No user serviceable parts in here...\n// ---------------------------------------------------------------------------\n\nnamespace android {\n\n/*!\n * Implementation of the guts of the vector<> class\n * this ensures backward binary compatibility and\n * reduces code size.\n * For performance reasons, we expose mStorage and mCount\n * so these fields are set in stone.\n *\n */\n\nclass VectorImpl\n{\npublic:\n    enum { // flags passed to the ctor\n        HAS_TRIVIAL_CTOR    = 0x00000001,\n        HAS_TRIVIAL_DTOR    = 0x00000002,\n        HAS_TRIVIAL_COPY    = 0x00000004,\n    };\n\n                            VectorImpl(size_t itemSize, uint32_t flags);\n                            VectorImpl(const VectorImpl& rhs);\n    virtual                 ~VectorImpl();\n\n    /*! must be called from subclasses destructor */\n            void            finish_vector();\n\n            VectorImpl&     operator = (const VectorImpl& rhs);    \n            \n    /*! C-style array access */\n    inline  const void*     arrayImpl() const       { return mStorage; }\n            void*           editArrayImpl();\n            \n    /*! vector stats */\n    inline  size_t          size() const        { return mCount; }\n    inline  bool            isEmpty() const     { return mCount == 0; }\n            size_t          capacity() const;\n            ssize_t         setCapacity(size_t size);\n            ssize_t         resize(size_t size);\n\n            /*! append/insert another vector or array */\n            ssize_t         insertVectorAt(const VectorImpl& vector, size_t index);\n            ssize_t         appendVector(const VectorImpl& vector);\n            ssize_t         insertArrayAt(const void* array, size_t index, size_t length);\n            ssize_t         appendArray(const void* array, size_t length);\n            \n            /*! add/insert/replace items */\n            ssize_t         insertAt(size_t where, size_t numItems = 1);\n            ssize_t         insertAt(const void* item, size_t where, size_t numItems = 1);\n            void            pop();\n            void            push();\n            void            push(const void* item);\n            ssize_t         add();\n            ssize_t         add(const void* item);\n            ssize_t         replaceAt(size_t index);\n            ssize_t         replaceAt(const void* item, size_t index);\n\n            /*! remove items */\n            ssize_t         removeItemsAt(size_t index, size_t count = 1);\n            void            clear();\n\n            const void*     itemLocation(size_t index) const;\n            void*           editItemLocation(size_t index);\n\n            typedef int (*compar_t)(const void* lhs, const void* rhs);\n            typedef int (*compar_r_t)(const void* lhs, const void* rhs, void* state);\n            status_t        sort(compar_t cmp);\n            status_t        sort(compar_r_t cmp, void* state);\n\nprotected:\n            size_t          itemSize() const;\n            void            release_storage();\n\n    virtual void            do_construct(void* storage, size_t num) const = 0;\n    virtual void            do_destroy(void* storage, size_t num) const = 0;\n    virtual void            do_copy(void* dest, const void* from, size_t num) const = 0;\n    virtual void            do_splat(void* dest, const void* item, size_t num) const = 0;\n    virtual void            do_move_forward(void* dest, const void* from, size_t num) const = 0;\n    virtual void            do_move_backward(void* dest, const void* from, size_t num) const = 0;\n    \nprivate:\n        void* _grow(size_t where, size_t amount);\n        void  _shrink(size_t where, size_t amount);\n\n        inline void _do_construct(void* storage, size_t num) const;\n        inline void _do_destroy(void* storage, size_t num) const;\n        inline void _do_copy(void* dest, const void* from, size_t num) const;\n        inline void _do_splat(void* dest, const void* item, size_t num) const;\n        inline void _do_move_forward(void* dest, const void* from, size_t num) const;\n        inline void _do_move_backward(void* dest, const void* from, size_t num) const;\n\n            // These 2 fields are exposed in the inlines below,\n            // so they're set in stone.\n            void *      mStorage;   // base address of the vector\n            size_t      mCount;     // number of items\n\n    const   uint32_t    mFlags;\n    const   size_t      mItemSize;\n};\n\n\n\nclass SortedVectorImpl : public VectorImpl\n{\npublic:\n                            SortedVectorImpl(size_t itemSize, uint32_t flags);\n                            SortedVectorImpl(const VectorImpl& rhs);\n    virtual                 ~SortedVectorImpl();\n    \n    SortedVectorImpl&     operator = (const SortedVectorImpl& rhs);    \n\n    //! finds the index of an item\n            ssize_t         indexOf(const void* item) const;\n\n    //! finds where this item should be inserted\n            size_t          orderOf(const void* item) const;\n\n    //! add an item in the right place (or replaces it if there is one)\n            ssize_t         add(const void* item);\n\n    //! merges a vector into this one\n            ssize_t         merge(const VectorImpl& vector);\n            ssize_t         merge(const SortedVectorImpl& vector);\n             \n    //! removes an item\n            ssize_t         remove(const void* item);\n        \nprotected:\n    virtual int             do_compare(const void* lhs, const void* rhs) const = 0;\n\nprivate:\n            ssize_t         _indexOrderOf(const void* item, size_t* order = 0) const;\n\n            // these are made private, because they can't be used on a SortedVector\n            // (they don't have an implementation either)\n            ssize_t         add();\n            void            pop();\n            void            push();\n            void            push(const void* item);\n            ssize_t         insertVectorAt(const VectorImpl& vector, size_t index);\n            ssize_t         appendVector(const VectorImpl& vector);\n            ssize_t         insertArrayAt(const void* array, size_t index, size_t length);\n            ssize_t         appendArray(const void* array, size_t length);\n            ssize_t         insertAt(size_t where, size_t numItems = 1);\n            ssize_t         insertAt(const void* item, size_t where, size_t numItems = 1);\n            ssize_t         replaceAt(size_t index);\n            ssize_t         replaceAt(const void* item, size_t index);\n};\n\n}; // namespace android\n\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_VECTOR_IMPL_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/ashmem.h",
    "content": "/* utils/ashmem.h\n **\n ** Copyright 2008 The Android Open Source Project\n **\n ** This file is dual licensed.  It may be redistributed and/or modified\n ** under the terms of the Apache 2.0 License OR version 2 of the GNU\n ** General Public License.\n */\n\n#ifndef _UTILS_ASHMEM_H\n#define _UTILS_ASHMEM_H\n\n#include <linux/limits.h>\n#include <linux/ioctl.h>\n\n#define ASHMEM_NAME_LEN\t\t256\n\n#define ASHMEM_NAME_DEF\t\t\"dev/ashmem\"\n\n/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */\n#define ASHMEM_NOT_REAPED\t0\n#define ASHMEM_WAS_REAPED\t1\n\n/* Return values from ASHMEM_UNPIN: Is the mapping now pinned or unpinned? */\n#define ASHMEM_NOW_UNPINNED\t0\n#define ASHMEM_NOW_PINNED\t1\n\n#define __ASHMEMIOC\t\t0x77\n\n#define ASHMEM_SET_NAME\t\t_IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN])\n#define ASHMEM_GET_NAME\t\t_IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN])\n#define ASHMEM_SET_SIZE\t\t_IOW(__ASHMEMIOC, 3, size_t)\n#define ASHMEM_GET_SIZE\t\t_IO(__ASHMEMIOC, 4)\n#define ASHMEM_SET_PROT_MASK\t_IOW(__ASHMEMIOC, 5, unsigned long)\n#define ASHMEM_GET_PROT_MASK\t_IO(__ASHMEMIOC, 6)\n#define ASHMEM_PIN\t\t_IO(__ASHMEMIOC, 7)\n#define ASHMEM_UNPIN\t\t_IO(__ASHMEMIOC, 8)\n#define ASHMEM_ISPINNED\t\t_IO(__ASHMEMIOC, 9)\n#define ASHMEM_PURGE_ALL_CACHES\t_IO(__ASHMEMIOC, 10)\n\n#endif\t/* _UTILS_ASHMEM_H */\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/misc.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Handy utility functions and portability code.\n//\n#ifndef _LIBS_UTILS_MISC_H\n#define _LIBS_UTILS_MISC_H\n\n#include <utils/Endian.h>\n\n/* get #of elements in a static array */\n#ifndef NELEM\n# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))\n#endif\n\nnamespace android {\n\ntypedef void (*sysprop_change_callback)(void);\nvoid add_sysprop_change_callback(sysprop_change_callback cb, int priority);\nvoid report_sysprop_change();\n\n}; // namespace android\n\n#endif // _LIBS_UTILS_MISC_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/utils/threads.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBS_UTILS_THREADS_H\n#define _LIBS_UTILS_THREADS_H\n\n/*\n * Please, DO NOT USE!\n *\n * This file is here only for legacy reasons. Instead, include directly\n * the headers you need below.\n *\n */\n\n#include <utils/AndroidThreads.h>\n\n#ifdef __cplusplus\n#include <utils/Condition.h>\n#include <utils/Errors.h>\n#include <utils/Mutex.h>\n#include <utils/RWLock.h>\n#include <utils/Thread.h>\n#endif\n\n#endif // _LIBS_UTILS_THREADS_H\n"
  },
  {
    "path": "atlas-aapt/system/core/include/ziparchive/zip_archive.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * Read-only access to Zip archives, with minimal heap allocation.\n */\n#ifndef LIBZIPARCHIVE_ZIPARCHIVE_H_\n#define LIBZIPARCHIVE_ZIPARCHIVE_H_\n\n#include <stdint.h>\n#include <string.h>\n#include <sys/cdefs.h>\n#include <sys/types.h>\n#include <utils/Compat.h>\n\n__BEGIN_DECLS\n\n/* Zip compression methods we support */\nenum {\n  kCompressStored     = 0,        // no compression\n  kCompressDeflated   = 8,        // standard deflate\n};\n\nstruct ZipString {\n  const uint8_t* name;\n  uint16_t name_length;\n\n  ZipString() {}\n\n  /*\n   * entry_name has to be an c-style string with only ASCII characters.\n   */\n  explicit ZipString(const char* entry_name)\n      : name(reinterpret_cast<const uint8_t*>(entry_name)), name_length(strlen(entry_name)) {}\n\n  bool operator==(const ZipString& rhs) const {\n    return name && (name_length == rhs.name_length) &&\n        (memcmp(name, rhs.name, name_length) == 0);\n  }\n\n  bool StartsWith(const ZipString& prefix) const {\n    return name && (name_length >= prefix.name_length) &&\n        (memcmp(name, prefix.name, prefix.name_length) == 0);\n  }\n\n  bool EndsWith(const ZipString& suffix) const {\n    return name && (name_length >= suffix.name_length) &&\n        (memcmp(name + name_length - suffix.name_length, suffix.name,\n                suffix.name_length) == 0);\n  }\n};\n\n/*\n * Represents information about a zip entry in a zip file.\n */\nstruct ZipEntry {\n  // Compression method: One of kCompressStored or\n  // kCompressDeflated.\n  uint16_t method;\n\n  // Modification time. The zipfile format specifies\n  // that the first two little endian bytes contain the time\n  // and the last two little endian bytes contain the date.\n  uint32_t mod_time;\n\n  // 1 if this entry contains a data descriptor segment, 0\n  // otherwise.\n  uint8_t has_data_descriptor;\n\n  // Crc32 value of this ZipEntry. This information might\n  // either be stored in the local file header or in a special\n  // Data descriptor footer at the end of the file entry.\n  uint32_t crc32;\n\n  // Compressed length of this ZipEntry. Might be present\n  // either in the local file header or in the data descriptor\n  // footer.\n  uint32_t compressed_length;\n\n  // Uncompressed length of this ZipEntry. Might be present\n  // either in the local file header or in the data descriptor\n  // footer.\n  uint32_t uncompressed_length;\n\n  // The offset to the start of data for this ZipEntry.\n  off64_t offset;\n};\n\ntypedef void* ZipArchiveHandle;\n\n/*\n * Open a Zip archive, and sets handle to the value of the opaque\n * handle for the file. This handle must be released by calling\n * CloseArchive with this handle.\n *\n * Returns 0 on success, and negative values on failure.\n */\nint32_t OpenArchive(const char* fileName, ZipArchiveHandle* handle);\n\n/*\n * Like OpenArchive, but takes a file descriptor open for reading\n * at the start of the file.  The descriptor must be mappable (this does\n * not allow access to a stream).\n *\n * Sets handle to the value of the opaque handle for this file descriptor.\n * This handle must be released by calling CloseArchive with this handle.\n *\n * If assume_ownership parameter is 'true' calling CloseArchive will close\n * the file.\n *\n * This function maps and scans the central directory and builds a table\n * of entries for future lookups.\n *\n * \"debugFileName\" will appear in error messages, but is not otherwise used.\n *\n * Returns 0 on success, and negative values on failure.\n */\nint32_t OpenArchiveFd(const int fd, const char* debugFileName,\n                      ZipArchiveHandle *handle, bool assume_ownership = true);\n\n/*\n * Close archive, releasing resources associated with it. This will\n * unmap the central directory of the zipfile and free all internal\n * data structures associated with the file. It is an error to use\n * this handle for any further operations without an intervening\n * call to one of the OpenArchive variants.\n */\nvoid CloseArchive(ZipArchiveHandle handle);\n\n/*\n * Find an entry in the Zip archive, by name. |entryName| must be a null\n * terminated string, and |data| must point to a writeable memory location.\n *\n * Returns 0 if an entry is found, and populates |data| with information\n * about this entry. Returns negative values otherwise.\n *\n * It's important to note that |data->crc32|, |data->compLen| and\n * |data->uncompLen| might be set to values from the central directory\n * if this file entry contains a data descriptor footer. To verify crc32s\n * and length, a call to VerifyCrcAndLengths must be made after entry data\n * has been processed.\n *\n * On non-Windows platforms this method does not modify internal state and\n * can be called concurrently.\n */\nint32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName,\n                  ZipEntry* data);\n\n/*\n * Start iterating over all entries of a zip file. The order of iteration\n * is not guaranteed to be the same as the order of elements\n * in the central directory but is stable for a given zip file. |cookie| will\n * contain the value of an opaque cookie which can be used to make one or more\n * calls to Next. All calls to StartIteration must be matched by a call to\n * EndIteration to free any allocated memory.\n *\n * This method also accepts optional prefix and suffix to restrict iteration to\n * entry names that start with |optional_prefix| or end with |optional_suffix|.\n *\n * Returns 0 on success and negative values on failure.\n */\nint32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr,\n                       const ZipString* optional_prefix,\n                       const ZipString* optional_suffix);\n\n/*\n * Advance to the next element in the zipfile in iteration order.\n *\n * Returns 0 on success, -1 if there are no more elements in this\n * archive and lower negative values on failure.\n */\nint32_t Next(void* cookie, ZipEntry* data, ZipString* name);\n\n/*\n * End iteration over all entries of a zip file and frees the memory allocated\n * in StartIteration.\n */\nvoid EndIteration(void* cookie);\n\n/*\n * Uncompress and write an entry to an open file identified by |fd|.\n * |entry->uncompressed_length| bytes will be written to the file at\n * its current offset, and the file will be truncated at the end of\n * the uncompressed data.\n *\n * Returns 0 on success and negative values on failure.\n */\nint32_t ExtractEntryToFile(ZipArchiveHandle handle, ZipEntry* entry, int fd);\n\n/**\n * Uncompress a given zip entry to the memory region at |begin| and of\n * size |size|. This size is expected to be the same as the *declared*\n * uncompressed length of the zip entry. It is an error if the *actual*\n * number of uncompressed bytes differs from this number.\n *\n * Returns 0 on success and negative values on failure.\n */\nint32_t ExtractToMemory(ZipArchiveHandle handle, ZipEntry* entry,\n                        uint8_t* begin, uint32_t size);\n\nint GetFileDescriptor(const ZipArchiveHandle handle);\n\nconst char* ErrorCodeString(int32_t error_code);\n\n__END_DECLS\n\n#endif  // LIBZIPARCHIVE_ZIPARCHIVE_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/include/ziparchive/zip_archive_stream_entry.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Read-only stream access to Zip archives entries.\n#ifndef LIBZIPARCHIVE_ZIPARCHIVESTREAMENTRY_H_\n#define LIBZIPARCHIVE_ZIPARCHIVESTREAMENTRY_H_\n\n#include <vector>\n\n#include <ziparchive/zip_archive.h>\n\nclass ZipArchiveStreamEntry {\n public:\n  virtual ~ZipArchiveStreamEntry() {}\n\n  virtual const std::vector<uint8_t>* Read() = 0;\n\n  virtual bool Verify() = 0;\n\n  static ZipArchiveStreamEntry* Create(ZipArchiveHandle handle, const ZipEntry& entry);\n  static ZipArchiveStreamEntry* CreateRaw(ZipArchiveHandle handle, const ZipEntry& entry);\n\n protected:\n  ZipArchiveStreamEntry(ZipArchiveHandle handle) : handle_(handle) {}\n\n  virtual bool Init(const ZipEntry& entry);\n\n  ZipArchiveHandle handle_;\n\n  uint32_t crc32_;\n};\n\n#endif  // LIBZIPARCHIVE_ZIPARCHIVESTREAMENTRY_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/include/ziparchive/zip_writer.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef LIBZIPARCHIVE_ZIPWRITER_H_\n#define LIBZIPARCHIVE_ZIPWRITER_H_\n\n#include \"android-base/macros.h\"\n#include <utils/Compat.h>\n\n#include <cstdio>\n#include <ctime>\n#include <memory>\n#include <string>\n#include <vector>\n#include <zlib.h>\n\n/**\n * Writes a Zip file via a stateful interface.\n *\n * Example:\n *\n *   FILE* file = fopen(\"path/to/zip.zip\", \"wb\");\n *\n *   ZipWriter writer(file);\n *\n *   writer.StartEntry(\"test.txt\", ZipWriter::kCompress | ZipWriter::kAlign);\n *   writer.WriteBytes(buffer, bufferLen);\n *   writer.WriteBytes(buffer2, bufferLen2);\n *   writer.FinishEntry();\n *\n *   writer.StartEntry(\"empty.txt\", 0);\n *   writer.FinishEntry();\n *\n *   writer.Finish();\n *\n *   fclose(file);\n */\nclass ZipWriter {\npublic:\n  enum {\n    /**\n     * Flag to compress the zip entry using deflate.\n     */\n    kCompress = 0x01,\n\n    /**\n     * Flag to align the zip entry data on a 32bit boundary. Useful for\n     * mmapping the data at runtime.\n     */\n    kAlign32 = 0x02,\n  };\n\n  static const char* ErrorCodeString(int32_t error_code);\n\n  /**\n   * Create a ZipWriter that will write into a FILE stream. The file should be opened with\n   * open mode of \"wb\" or \"w+b\". ZipWriter does not take ownership of the file stream. The\n   * caller is responsible for closing the file.\n   */\n  explicit ZipWriter(FILE* f);\n\n  // Move constructor.\n  ZipWriter(ZipWriter&& zipWriter);\n\n  // Move assignment.\n  ZipWriter& operator=(ZipWriter&& zipWriter);\n\n  /**\n   * Starts a new zip entry with the given path and flags.\n   * Flags can be a bitwise OR of ZipWriter::kCompress and ZipWriter::kAlign.\n   * Subsequent calls to WriteBytes(const void*, size_t) will add data to this entry.\n   * Returns 0 on success, and an error value < 0 on failure.\n   */\n  int32_t StartEntry(const char* path, size_t flags);\n\n  /**\n   * Starts a new zip entry with the given path and flags, where the\n   * entry will be aligned to the given alignment.\n   * Flags can only be ZipWriter::kCompress. Using the flag ZipWriter::kAlign32\n   * will result in an error.\n   * Subsequent calls to WriteBytes(const void*, size_t) will add data to this entry.\n   * Returns 0 on success, and an error value < 0 on failure.\n   */\n  int32_t StartAlignedEntry(const char* path, size_t flags, uint32_t alignment);\n\n  /**\n   * Same as StartEntry(const char*, size_t), but sets a last modified time for the entry.\n   */\n  int32_t StartEntryWithTime(const char* path, size_t flags, time_t time);\n\n  /**\n   * Same as StartAlignedEntry(const char*, size_t), but sets a last modified time for the entry.\n   */\n  int32_t StartAlignedEntryWithTime(const char* path, size_t flags, time_t time,\n                                    uint32_t alignment);\n\n  /**\n   * Writes bytes to the zip file for the previously started zip entry.\n   * Returns 0 on success, and an error value < 0 on failure.\n   */\n  int32_t WriteBytes(const void* data, size_t len);\n\n  /**\n   * Finish a zip entry started with StartEntry(const char*, size_t) or\n   * StartEntryWithTime(const char*, size_t, time_t). This must be called before\n   * any new zip entries are started, or before Finish() is called.\n   * Returns 0 on success, and an error value < 0 on failure.\n   */\n  int32_t FinishEntry();\n\n  /**\n   * Writes the Central Directory Headers and flushes the zip file stream.\n   * Returns 0 on success, and an error value < 0 on failure.\n   */\n  int32_t Finish();\n\nprivate:\n  DISALLOW_COPY_AND_ASSIGN(ZipWriter);\n\n  struct FileInfo {\n    std::string path;\n    uint16_t compression_method;\n    uint32_t crc32;\n    uint32_t compressed_size;\n    uint32_t uncompressed_size;\n    uint16_t last_mod_time;\n    uint16_t last_mod_date;\n    uint32_t local_file_header_offset;\n  };\n\n  int32_t HandleError(int32_t error_code);\n  int32_t PrepareDeflate();\n  int32_t StoreBytes(FileInfo* file, const void* data, size_t len);\n  int32_t CompressBytes(FileInfo* file, const void* data, size_t len);\n  int32_t FlushCompressedBytes(FileInfo* file);\n\n  enum class State {\n    kWritingZip,\n    kWritingEntry,\n    kDone,\n    kError,\n  };\n\n  FILE* file_;\n  off64_t current_offset_;\n  State state_;\n  std::vector<FileInfo> files_;\n\n  std::unique_ptr<z_stream, void(*)(z_stream*)> z_stream_;\n  std::vector<uint8_t> buffer_;\n};\n\n#endif /* LIBZIPARCHIVE_ZIPWRITER_H_ */\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/Android.mk",
    "content": "#\n# Copyright (C) 2008 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nLOCAL_PATH := $(my-dir)\ninclude $(CLEAR_VARS)\n\nlibcutils_common_sources := \\\n        atomic.c.arm \\\n        config_utils.c \\\n        fs_config.c \\\n        canned_fs_config.c \\\n        hashmap.c \\\n        iosched_policy.c \\\n        load_file.c \\\n        native_handle.c \\\n        open_memstream.c \\\n        process_name.c \\\n        record_stream.c \\\n        sched_policy.c \\\n        sockets.cpp \\\n        strdup16to8.c \\\n        strdup8to16.c \\\n        strlcpy.c \\\n        threads.c \\\n\n# some files must not be compiled when building against Mingw\n# they correspond to features not used by our host development tools\n# which are also hard or even impossible to port to native Win32\nlibcutils_nonwindows_sources := \\\n        fs.c \\\n        multiuser.c \\\n        socket_inaddr_any_server_unix.c \\\n        socket_local_client_unix.c \\\n        socket_local_server_unix.c \\\n        socket_loopback_client_unix.c \\\n        socket_loopback_server_unix.c \\\n        socket_network_client_unix.c \\\n        sockets_unix.cpp \\\n        str_parms.c \\\n\nlibcutils_nonwindows_host_sources := \\\n        ashmem-host.c \\\n        trace-host.c \\\n\nlibcutils_windows_host_sources := \\\n        socket_inaddr_any_server_windows.c \\\n        socket_network_client_windows.c \\\n        sockets_windows.cpp \\\n\n# Shared and static library for host\n# Note: when linking this library on Windows, you must also link to Winsock2\n# using \"LOCAL_LDLIBS_windows := -lws2_32\".\n# ========================================================\nLOCAL_MODULE := libcutils\nLOCAL_SRC_FILES := $(libcutils_common_sources) dlmalloc_stubs.c\nLOCAL_SRC_FILES_darwin := $(libcutils_nonwindows_sources) $(libcutils_nonwindows_host_sources)\nLOCAL_SRC_FILES_linux := $(libcutils_nonwindows_sources) $(libcutils_nonwindows_host_sources)\nLOCAL_SRC_FILES_windows := $(libcutils_windows_host_sources)\nLOCAL_STATIC_LIBRARIES := liblog\nLOCAL_CFLAGS := -Werror -Wall -Wextra\nLOCAL_MULTILIB := both\nLOCAL_MODULE_HOST_OS := darwin linux windows\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libcutils\nLOCAL_SRC_FILES := $(libcutils_common_sources) dlmalloc_stubs.c\nLOCAL_SRC_FILES_darwin := $(libcutils_nonwindows_sources) $(libcutils_nonwindows_host_sources)\nLOCAL_SRC_FILES_linux := $(libcutils_nonwindows_sources) $(libcutils_nonwindows_host_sources)\nLOCAL_SHARED_LIBRARIES := liblog\nLOCAL_CFLAGS := -Werror -Wall -Wextra\nLOCAL_MULTILIB := both\ninclude $(BUILD_HOST_SHARED_LIBRARY)\n\n\n\n# Shared and static library for target\n# ========================================================\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libcutils\nLOCAL_SRC_FILES := $(libcutils_common_sources) \\\n        $(libcutils_nonwindows_sources) \\\n        android_reboot.c \\\n        ashmem-dev.c \\\n        debugger.c \\\n        klog.c \\\n        partition_utils.c \\\n        properties.c \\\n        qtaguid.c \\\n        trace-dev.c \\\n        uevent.c \\\n\nLOCAL_SRC_FILES_arm += arch-arm/memset32.S\nLOCAL_SRC_FILES_arm64 += arch-arm64/android_memset.S\n\nLOCAL_SRC_FILES_mips += arch-mips/android_memset.c\nLOCAL_SRC_FILES_mips64 += arch-mips/android_memset.c\n\nLOCAL_SRC_FILES_x86 += \\\n        arch-x86/android_memset16.S \\\n        arch-x86/android_memset32.S \\\n\nLOCAL_SRC_FILES_x86_64 += \\\n        arch-x86_64/android_memset16.S \\\n        arch-x86_64/android_memset32.S \\\n\nLOCAL_C_INCLUDES := $(libcutils_c_includes)\nLOCAL_STATIC_LIBRARIES := liblog\nifneq ($(ENABLE_CPUSETS),)\nLOCAL_CFLAGS += -DUSE_CPUSETS\nendif\nifneq ($(ENABLE_SCHEDBOOST),)\nLOCAL_CFLAGS += -DUSE_SCHEDBOOST\nendif\nLOCAL_CFLAGS += -Werror -Wall -Wextra -std=gnu90\nLOCAL_CLANG := true\nLOCAL_SANITIZE := integer\ninclude $(BUILD_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libcutils\n# TODO: remove liblog as whole static library, once we don't have prebuilt that requires\n# liblog symbols present in libcutils.\nLOCAL_WHOLE_STATIC_LIBRARIES := libcutils liblog\nLOCAL_SHARED_LIBRARIES := liblog\nifneq ($(ENABLE_CPUSETS),)\nLOCAL_CFLAGS += -DUSE_CPUSETS\nendif\nifneq ($(ENABLE_SCHEDBOOST),)\nLOCAL_CFLAGS += -DUSE_SCHEDBOOST\nendif\nLOCAL_CFLAGS += -Werror -Wall -Wextra\nLOCAL_C_INCLUDES := $(libcutils_c_includes)\nLOCAL_CLANG := true\nLOCAL_SANITIZE := integer\ninclude $(BUILD_SHARED_LIBRARY)\n\ninclude $(call all-makefiles-under,$(LOCAL_PATH))\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/MODULE_LICENSE_APACHE2",
    "content": ""
  },
  {
    "path": "atlas-aapt/system/core/libcutils/NOTICE",
    "content": "\n   Copyright (c) 2005-2008, The Android Open Source Project\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/android_reboot.c",
    "content": "/*\n * Copyright 2011, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <errno.h>\n#include <fcntl.h>\n#include <mntent.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/cdefs.h>\n#include <sys/mount.h>\n#include <sys/reboot.h>\n#include <sys/stat.h>\n#include <sys/syscall.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#include <cutils/android_reboot.h>\n#include <cutils/klog.h>\n#include <cutils/list.h>\n\n#define TAG \"android_reboot\"\n#define READONLY_CHECK_MS 5000\n#define READONLY_CHECK_TIMES 50\n\ntypedef struct {\n    struct listnode list;\n    struct mntent entry;\n} mntent_list;\n\nstatic bool has_mount_option(const char* opts, const char* opt_to_find)\n{\n  bool ret = false;\n  char* copy = NULL;\n  char* opt;\n  char* rem;\n\n  while ((opt = strtok_r(copy ? NULL : (copy = strdup(opts)), \",\", &rem))) {\n      if (!strcmp(opt, opt_to_find)) {\n          ret = true;\n          break;\n      }\n  }\n\n  free(copy);\n  return ret;\n}\n\nstatic bool is_block_device(const char* fsname)\n{\n    return !strncmp(fsname, \"/dev/block\", 10);\n}\n\n/* Find all read+write block devices in /proc/mounts and add them to\n * |rw_entries|.\n */\nstatic void find_rw(struct listnode* rw_entries)\n{\n    FILE* fp;\n    struct mntent* mentry;\n\n    if ((fp = setmntent(\"/proc/mounts\", \"r\")) == NULL) {\n        KLOG_WARNING(TAG, \"Failed to open /proc/mounts.\\n\");\n        return;\n    }\n    while ((mentry = getmntent(fp)) != NULL) {\n        if (is_block_device(mentry->mnt_fsname) &&\n            has_mount_option(mentry->mnt_opts, \"rw\")) {\n            mntent_list* item = (mntent_list*)calloc(1, sizeof(mntent_list));\n            item->entry = *mentry;\n            item->entry.mnt_fsname = strdup(mentry->mnt_fsname);\n            item->entry.mnt_dir = strdup(mentry->mnt_dir);\n            item->entry.mnt_type = strdup(mentry->mnt_type);\n            item->entry.mnt_opts = strdup(mentry->mnt_opts);\n            list_add_tail(rw_entries, &item->list);\n        }\n    }\n    endmntent(fp);\n}\n\nstatic void free_entries(struct listnode* entries)\n{\n    struct listnode* node;\n    struct listnode* n;\n    list_for_each_safe(node, n, entries) {\n        mntent_list* item = node_to_item(node, mntent_list, list);\n        free(item->entry.mnt_fsname);\n        free(item->entry.mnt_dir);\n        free(item->entry.mnt_type);\n        free(item->entry.mnt_opts);\n        free(item);\n    }\n}\n\nstatic mntent_list* find_item(struct listnode* rw_entries, const char* fsname_to_find)\n{\n    struct listnode* node;\n    list_for_each(node, rw_entries) {\n        mntent_list* item = node_to_item(node, mntent_list, list);\n        if (!strcmp(item->entry.mnt_fsname, fsname_to_find)) {\n            return item;\n        }\n    }\n    return NULL;\n}\n\n/* Remounting filesystems read-only is difficult when there are files\n * opened for writing or pending deletes on the filesystem.  There is\n * no way to force the remount with the mount(2) syscall.  The magic sysrq\n * 'u' command does an emergency remount read-only on all writable filesystems\n * that have a block device (i.e. not tmpfs filesystems) by calling\n * emergency_remount(), which knows how to force the remount to read-only.\n * Unfortunately, that is asynchronous, and just schedules the work and\n * returns.  The best way to determine if it is done is to read /proc/mounts\n * repeatedly until there are no more writable filesystems mounted on\n * block devices.\n */\nstatic void remount_ro(void (*cb_on_remount)(const struct mntent*))\n{\n    int fd, cnt;\n    FILE* fp;\n    struct mntent* mentry;\n    struct listnode* node;\n\n    list_declare(rw_entries);\n    list_declare(ro_entries);\n\n    sync();\n    find_rw(&rw_entries);\n\n    /* Trigger the remount of the filesystems as read-only,\n     * which also marks them clean.\n     */\n    fd = TEMP_FAILURE_RETRY(open(\"/proc/sysrq-trigger\", O_WRONLY));\n    if (fd < 0) {\n        KLOG_WARNING(TAG, \"Failed to open sysrq-trigger.\\n\");\n        /* TODO: Try to remount each rw parition manually in readonly mode.\n         * This may succeed if no process is using the partition.\n         */\n        goto out;\n    }\n    if (TEMP_FAILURE_RETRY(write(fd, \"u\", 1)) != 1) {\n        close(fd);\n        KLOG_WARNING(TAG, \"Failed to write to sysrq-trigger.\\n\");\n        /* TODO: The same. Manually remount the paritions. */\n        goto out;\n    }\n    close(fd);\n\n    /* Now poll /proc/mounts till it's done */\n    cnt = 0;\n    while (cnt < READONLY_CHECK_TIMES) {\n        if ((fp = setmntent(\"/proc/mounts\", \"r\")) == NULL) {\n            /* If we can't read /proc/mounts, just give up. */\n            KLOG_WARNING(TAG, \"Failed to open /proc/mounts.\\n\");\n            goto out;\n        }\n        while ((mentry = getmntent(fp)) != NULL) {\n            if (!is_block_device(mentry->mnt_fsname) ||\n                !has_mount_option(mentry->mnt_opts, \"ro\")) {\n                continue;\n            }\n            mntent_list* item = find_item(&rw_entries, mentry->mnt_fsname);\n            if (item) {\n                /* |item| has now been ro remounted. */\n                list_remove(&item->list);\n                list_add_tail(&ro_entries, &item->list);\n            }\n        }\n        endmntent(fp);\n        if (list_empty(&rw_entries)) {\n            /* All rw block devices are now readonly. */\n            break;\n        }\n        TEMP_FAILURE_RETRY(\n            usleep(READONLY_CHECK_MS * 1000 / READONLY_CHECK_TIMES));\n        cnt++;\n    }\n\n    list_for_each(node, &rw_entries) {\n        mntent_list* item = node_to_item(node, mntent_list, list);\n        KLOG_WARNING(TAG, \"Failed to remount %s in readonly mode.\\n\",\n                     item->entry.mnt_fsname);\n    }\n\n    if (cb_on_remount) {\n        list_for_each(node, &ro_entries) {\n            mntent_list* item = node_to_item(node, mntent_list, list);\n            cb_on_remount(&item->entry);\n        }\n    }\n\nout:\n    free_entries(&rw_entries);\n    free_entries(&ro_entries);\n}\n\nint android_reboot_with_callback(\n    int cmd, int flags __unused, const char *arg,\n    void (*cb_on_remount)(const struct mntent*))\n{\n    int ret;\n    remount_ro(cb_on_remount);\n    switch (cmd) {\n        case ANDROID_RB_RESTART:\n            ret = reboot(RB_AUTOBOOT);\n            break;\n\n        case ANDROID_RB_POWEROFF:\n            ret = reboot(RB_POWER_OFF);\n            break;\n\n        case ANDROID_RB_RESTART2:\n            ret = syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,\n                           LINUX_REBOOT_CMD_RESTART2, arg);\n            break;\n\n        default:\n            ret = -1;\n    }\n\n    return ret;\n}\n\nint android_reboot(int cmd, int flags, const char *arg)\n{\n    return android_reboot_with_callback(cmd, flags, arg, NULL);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/arch-arm/memset32.S",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/*\n *  memset32.S\n *\n */\n\n    .syntax unified\n\n    .text\n    .align\n\n    .global android_memset32\n    .type   android_memset32, %function\n    .global android_memset16\n    .type   android_memset16, %function\n\n        /*\n         * Optimized memset32 and memset16 for ARM.\n         *\n         * void android_memset16(uint16_t* dst, uint16_t value, size_t size);\n         * void android_memset32(uint32_t* dst, uint32_t value, size_t size);\n         *\n         */\n\nandroid_memset16:\n        .fnstart\n        cmp         r2, #1\n        bxle        lr\n\n        /* expand the data to 32 bits */\n        mov         r1, r1, lsl #16\n        orr         r1, r1, r1, lsr #16\n\n        /* align to 32 bits */\n        tst         r0, #2\n        strhne      r1, [r0], #2\n        subne       r2, r2, #2\n        .fnend\n\nandroid_memset32:\n        .fnstart\n        .cfi_startproc\n        str         lr, [sp, #-4]!\n        .cfi_def_cfa_offset 4\n        .cfi_rel_offset lr, 0\n\n        /* align the destination to a cache-line */\n        mov         r12, r1\n        mov         lr, r1\n        rsb         r3, r0, #0\n        ands        r3, r3, #0x1C\n        beq         .Laligned32\n        cmp         r3, r2\n        andhi       r3, r2, #0x1C\n        sub         r2, r2, r3\n\n        /* conditionally writes 0 to 7 words (length in r3) */\n        movs        r3, r3, lsl #28\n        stmiacs     r0!, {r1, lr}\n        stmiacs     r0!, {r1, lr}\n        stmiami     r0!, {r1, lr}\n        movs        r3, r3, lsl #2\n        strcs       r1, [r0], #4\n\n.Laligned32:\n        mov         r3, r1\n1:      subs        r2, r2, #32\n        stmiahs     r0!, {r1,r3,r12,lr}\n        stmiahs     r0!, {r1,r3,r12,lr}\n        bhs         1b\n        add         r2, r2, #32\n\n        /* conditionally stores 0 to 30 bytes */\n        movs        r2, r2, lsl #28\n        stmiacs     r0!, {r1,r3,r12,lr}\n        stmiami     r0!, {r1,lr}\n        movs        r2, r2, lsl #2\n        strcs       r1, [r0], #4\n        strhmi      lr, [r0], #2\n\n        ldr         lr, [sp], #4\n        .cfi_def_cfa_offset 0\n        .cfi_restore lr\n        bx          lr\n        .cfi_endproc\n        .fnend\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/arch-arm64/android_memset.S",
    "content": "/* Copyright (c) 2012, Linaro Limited\n   All rights reserved.\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are met:\n       * Redistributions of source code must retain the above copyright\n         notice, this list of conditions and the following disclaimer.\n       * Redistributions in binary form must reproduce the above copyright\n         notice, this list of conditions and the following disclaimer in the\n         documentation and/or other materials provided with the distribution.\n       * Neither the name of the Linaro nor the\n         names of its contributors may be used to endorse or promote products\n         derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n   HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/* Assumptions:\n *\n * ARMv8-a, AArch64\n * Unaligned accesses\n *\n */\n\n/* By default we assume that the DC instruction can be used to zero\n   data blocks more efficiently.  In some circumstances this might be\n   unsafe, for example in an asymmetric multiprocessor environment with\n   different DC clear lengths (neither the upper nor lower lengths are\n   safe to use). */\n\n#define dst  \t\tx0\n#define count\t\tx2\n#define tmp1\t\tx3\n#define tmp1w\t\tw3\n#define tmp2\t\tx4\n#define tmp2w\t\tw4\n#define zva_len_x\tx5\n#define zva_len\t\tw5\n#define zva_bits_x\tx6\n\n#define A_l\t\tx1\n#define A_lw\t\tw1\n#define tmp3w\t\tw9\n\n#define ENTRY(f) \\\n  .text; \\\n  .globl f; \\\n  .align 0; \\\n  .type f, %function; \\\n  f: \\\n  .cfi_startproc \\\n\n#define END(f) \\\n  .cfi_endproc; \\\n  .size f, .-f; \\\n\nENTRY(android_memset16)\n\tands   A_lw, A_lw, #0xffff\n\tb.eq\t.Lzero_mem\n\torr\tA_lw, A_lw, A_lw, lsl #16\n\tb .Lexpand_to_64\nEND(android_memset16)\n\nENTRY(android_memset32)\n\tcmp\t    A_lw, #0\n\tb.eq\t.Lzero_mem\n.Lexpand_to_64:\n\torr\tA_l, A_l, A_l, lsl #32\n.Ltail_maybe_long:\n\tcmp\tcount, #64\n\tb.ge\t.Lnot_short\n.Ltail_maybe_tiny:\n\tcmp\tcount, #15\n\tb.le\t.Ltail15tiny\n.Ltail63:\n\tands\ttmp1, count, #0x30\n\tb.eq\t.Ltail15\n\tadd\tdst, dst, tmp1\n\tcmp\ttmp1w, #0x20\n\tb.eq\t1f\n\tb.lt\t2f\n\tstp\tA_l, A_l, [dst, #-48]\n1:\n\tstp\tA_l, A_l, [dst, #-32]\n2:\n\tstp\tA_l, A_l, [dst, #-16]\n\n.Ltail15:\n\tand\tcount, count, #15\n\tadd\tdst, dst, count\n\tstp\tA_l, A_l, [dst, #-16]\t/* Repeat some/all of last store. */\n\tret\n\n.Ltail15tiny:\n\t/* Set up to 15 bytes.  Does not assume earlier memory\n\t   being set.  */\n\ttbz\tcount, #3, 1f\n\tstr\tA_l, [dst], #8\n1:\n\ttbz\tcount, #2, 1f\n\tstr\tA_lw, [dst], #4\n1:\n\ttbz\tcount, #1, 1f\n\tstrh\tA_lw, [dst], #2\n1:\n\tret\n\n\t/* Critical loop.  Start at a new cache line boundary.  Assuming\n\t * 64 bytes per line, this ensures the entire loop is in one line.  */\n\t.p2align 6\n.Lnot_short:\n\tneg\ttmp2, dst\n\tands\ttmp2, tmp2, #15\n\tb.eq\t2f\n\t/* Bring DST to 128-bit (16-byte) alignment.  We know that there's\n\t * more than that to set, so we simply store 16 bytes and advance by\n\t * the amount required to reach alignment.  */\n\tsub\tcount, count, tmp2\n\tstp\tA_l, A_l, [dst]\n\tadd\tdst, dst, tmp2\n\t/* There may be less than 63 bytes to go now.  */\n\tcmp\tcount, #63\n\tb.le\t.Ltail63\n2:\n\tsub\tdst, dst, #16\t\t/* Pre-bias.  */\n\tsub\tcount, count, #64\n1:\n\tstp\tA_l, A_l, [dst, #16]\n\tstp\tA_l, A_l, [dst, #32]\n\tstp\tA_l, A_l, [dst, #48]\n\tstp\tA_l, A_l, [dst, #64]!\n\tsubs\tcount, count, #64\n\tb.ge\t1b\n\ttst\tcount, #0x3f\n\tadd\tdst, dst, #16\n\tb.ne\t.Ltail63\n\tret\n\n\t/* For zeroing memory, check to see if we can use the ZVA feature to\n\t * zero entire 'cache' lines.  */\n.Lzero_mem:\n\tmov\tA_l, #0\n\tcmp\tcount, #63\n\tb.le\t.Ltail_maybe_tiny\n\tneg\ttmp2, dst\n\tands\ttmp2, tmp2, #15\n\tb.eq\t1f\n\tsub\tcount, count, tmp2\n\tstp\tA_l, A_l, [dst]\n\tadd\tdst, dst, tmp2\n\tcmp\tcount, #63\n\tb.le\t.Ltail63\n1:\n\t/* For zeroing small amounts of memory, it's not worth setting up\n\t * the line-clear code.  */\n\tcmp\tcount, #128\n\tb.lt\t.Lnot_short\n\tmrs\ttmp1, dczid_el0\n\ttbnz\ttmp1, #4, .Lnot_short\n\tmov\ttmp3w, #4\n\tand\tzva_len, tmp1w, #15\t/* Safety: other bits reserved.  */\n\tlsl\tzva_len, tmp3w, zva_len\n\n.Lzero_by_line:\n\t/* Compute how far we need to go to become suitably aligned.  We're\n\t * already at quad-word alignment.  */\n\tcmp\tcount, zva_len_x\n\tb.lt\t.Lnot_short\t\t/* Not enough to reach alignment.  */\n\tsub\tzva_bits_x, zva_len_x, #1\n\tneg\ttmp2, dst\n\tands\ttmp2, tmp2, zva_bits_x\n\tb.eq\t1f\t\t\t/* Already aligned.  */\n\t/* Not aligned, check that there's enough to copy after alignment.  */\n\tsub\ttmp1, count, tmp2\n\tcmp\ttmp1, #64\n\tccmp\ttmp1, zva_len_x, #8, ge\t/* NZCV=0b1000 */\n\tb.lt\t.Lnot_short\n\t/* We know that there's at least 64 bytes to zero and that it's safe\n\t * to overrun by 64 bytes.  */\n\tmov\tcount, tmp1\n2:\n\tstp\tA_l, A_l, [dst]\n\tstp\tA_l, A_l, [dst, #16]\n\tstp\tA_l, A_l, [dst, #32]\n\tsubs\ttmp2, tmp2, #64\n\tstp\tA_l, A_l, [dst, #48]\n\tadd\tdst, dst, #64\n\tb.ge\t2b\n\t/* We've overrun a bit, so adjust dst downwards.  */\n\tadd\tdst, dst, tmp2\n1:\n\tsub\tcount, count, zva_len_x\n3:\n\tdc\tzva, dst\n\tadd\tdst, dst, zva_len_x\n\tsubs\tcount, count, zva_len_x\n\tb.ge\t3b\n\tands\tcount, count, zva_bits_x\n\tb.ne\t.Ltail_maybe_long\n\tret\nEND(android_memset32)\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/arch-mips/android_memset.c",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/* generic C version for any machine */\n\n#include <cutils/memory.h>\n\n#ifdef __clang__\n__attribute__((no_sanitize(\"integer\")))\n#endif\nvoid android_memset16(uint16_t* dst, uint16_t value, size_t size)\n{\n   /* optimized version of\n      size >>= 1;\n      while (size--)\n        *dst++ = value;\n   */\n\n   size >>= 1;\n   if (((uintptr_t)dst & 2) && size) {\n      /* fill unpaired first elem separately */\n      *dst++ = value;\n      size--;\n   }\n   /* dst is now 32-bit-aligned */\n   /* fill body with 32-bit pairs */\n   uint32_t value32 = (((uint32_t)value) << 16) | ((uint32_t)value);\n   android_memset32((uint32_t*) dst, value32, size<<1);\n   if (size & 1) {\n      dst[size-1] = value;  /* fill unpaired last elem */\n   }\n}\n\n\n#ifdef __clang__\n__attribute__((no_sanitize(\"integer\")))\n#endif\nvoid android_memset32(uint32_t* dst, uint32_t value, size_t size)\n{\n   /* optimized version of\n      size >>= 2;\n      while (size--)\n         *dst++ = value;\n   */\n\n   size >>= 2;\n   if (((uintptr_t)dst & 4) && size) {\n      /* fill unpaired first 32-bit elem separately */\n      *dst++ = value;\n      size--;\n   }\n   /* dst is now 64-bit aligned */\n   /* fill body with 64-bit pairs */\n   uint64_t value64 = (((uint64_t)value) << 32) | ((uint64_t)value);\n   uint64_t* dst64 = (uint64_t*)dst;\n\n   while (size >= 12) {\n      dst64[0] = value64;\n      dst64[1] = value64;\n      dst64[2] = value64;\n      dst64[3] = value64;\n      dst64[4] = value64;\n      dst64[5] = value64;\n      size  -= 12;\n      dst64 += 6;\n   }\n\n   /* fill remainder with original 32-bit single-elem loop */\n   dst = (uint32_t*) dst64;\n   while (size != 0) {\n       size--;\n      *dst++ = value;\n   }\n\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/arch-x86/android_memset16.S",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"cache.h\"\n\n#ifndef MEMSET\n# define MEMSET\t\tandroid_memset16\n#endif\n\n#ifndef L\n# define L(label)\t.L##label\n#endif\n\n#ifndef ALIGN\n# define ALIGN(n)\t.p2align n\n#endif\n\n#ifndef cfi_startproc\n# define cfi_startproc\t\t\t.cfi_startproc\n#endif\n\n#ifndef cfi_endproc\n# define cfi_endproc\t\t\t.cfi_endproc\n#endif\n\n#ifndef cfi_rel_offset\n# define cfi_rel_offset(reg, off)\t.cfi_rel_offset reg, off\n#endif\n\n#ifndef cfi_restore\n# define cfi_restore(reg)\t\t.cfi_restore reg\n#endif\n\n#ifndef cfi_adjust_cfa_offset\n# define cfi_adjust_cfa_offset(off)\t.cfi_adjust_cfa_offset off\n#endif\n\n#ifndef ENTRY\n# define ENTRY(name)\t\t\t\\\n\t.type name,  @function; \t\\\n\t.globl name;\t\t\t\\\n\t.p2align 4;\t\t\t\\\nname:\t\t\t\t\t\\\n\tcfi_startproc\n#endif\n\n#ifndef END\n# define END(name)\t\t\t\\\n\tcfi_endproc;\t\t\t\\\n\t.size name, .-name\n#endif\n\n#define CFI_PUSH(REG)\t\t\t\t\t\t\\\n  cfi_adjust_cfa_offset (4);\t\t\t\t\t\\\n  cfi_rel_offset (REG, 0)\n\n#define CFI_POP(REG)\t\t\t\t\t\t\\\n  cfi_adjust_cfa_offset (-4);\t\t\t\t\t\\\n  cfi_restore (REG)\n\n#define PUSH(REG)\tpushl REG; CFI_PUSH (REG)\n#define POP(REG)\tpopl REG; CFI_POP (REG)\n\n#ifdef USE_AS_BZERO16\n# define DEST\t\tPARMS\n# define LEN\t\tDEST+4\n# define SETRTNVAL\n#else\n# define DEST\t\tPARMS\n# define CHR\t\tDEST+4\n# define LEN\t\tCHR+4\n# define SETRTNVAL\tmovl DEST(%esp), %eax\n#endif\n\n#if (defined SHARED || defined __PIC__)\n# define ENTRANCE\tPUSH (%ebx);\n# define RETURN_END\tPOP (%ebx); ret\n# define RETURN\t\tRETURN_END; CFI_PUSH (%ebx)\n# define PARMS\t\t8\t\t/* Preserve EBX.  */\n# define JMPTBL(I, B)\tI - B\n\n/* Load an entry in a jump table into EBX and branch to it.  TABLE is a\n   jump table with relative offsets.   */\n# define BRANCH_TO_JMPTBL_ENTRY(TABLE)\t\t\t\t\\\n    /* We first load PC into EBX.  */\t\t\t\t\\\n    call\t__x86.get_pc_thunk.bx;\t\t\t\t\\\n    /* Get the address of the jump table.  */\t\t\t\\\n    add\t\t$(TABLE - .), %ebx;\t\t\t\t\\\n    /* Get the entry and convert the relative offset to the\t\\\n       absolute address.  */\t\t\t\t\t\\\n    add\t\t(%ebx,%ecx,4), %ebx;\t\t\t\t\\\n    /* We loaded the jump table and adjuested EDX. Go.  */\t\\\n    jmp\t\t*%ebx\n\n\t.section\t.gnu.linkonce.t.__x86.get_pc_thunk.bx,\"ax\",@progbits\n\t.globl\t__x86.get_pc_thunk.bx\n\t.hidden\t__x86.get_pc_thunk.bx\n\tALIGN (4)\n\t.type\t__x86.get_pc_thunk.bx,@function\n__x86.get_pc_thunk.bx:\n\tmovl\t(%esp), %ebx\n\tret\n#else\n# define ENTRANCE\n# define RETURN_END\tret\n# define RETURN\t\tRETURN_END\n# define PARMS\t\t4\n# define JMPTBL(I, B)\tI\n\n/* Branch to an entry in a jump table.  TABLE is a jump table with\n   absolute offsets.  */\n# define BRANCH_TO_JMPTBL_ENTRY(TABLE)\t\t\t\t\\\n    jmp\t\t*TABLE(,%ecx,4)\n#endif\n\n\t.section .text.sse2,\"ax\",@progbits\n\tALIGN (4)\nENTRY (MEMSET)\n\tENTRANCE\n\n\tmovl\tLEN(%esp), %ecx\n\tshr\t$1, %ecx\n#ifdef USE_AS_BZERO16\n\txor\t%eax, %eax\n#else\n\tmovzwl\tCHR(%esp), %eax\n\tmov\t%eax, %edx\n\tshl\t$16, %eax\n\tor\t%edx, %eax\n#endif\n\tmovl\tDEST(%esp), %edx\n\tcmp\t$32, %ecx\n\tjae\tL(32wordsormore)\n\nL(write_less32words):\n\tlea\t(%edx, %ecx, 2), %edx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_less32words))\n\n\n\t.pushsection .rodata.sse2,\"a\",@progbits\n\tALIGN (2)\nL(table_less32words):\n\t.int\tJMPTBL (L(write_0words), L(table_less32words))\n\t.int\tJMPTBL (L(write_1words), L(table_less32words))\n\t.int\tJMPTBL (L(write_2words), L(table_less32words))\n\t.int\tJMPTBL (L(write_3words), L(table_less32words))\n\t.int\tJMPTBL (L(write_4words), L(table_less32words))\n\t.int\tJMPTBL (L(write_5words), L(table_less32words))\n\t.int\tJMPTBL (L(write_6words), L(table_less32words))\n\t.int\tJMPTBL (L(write_7words), L(table_less32words))\n\t.int\tJMPTBL (L(write_8words), L(table_less32words))\n\t.int\tJMPTBL (L(write_9words), L(table_less32words))\n\t.int\tJMPTBL (L(write_10words), L(table_less32words))\n\t.int\tJMPTBL (L(write_11words), L(table_less32words))\n\t.int\tJMPTBL (L(write_12words), L(table_less32words))\n\t.int\tJMPTBL (L(write_13words), L(table_less32words))\n\t.int\tJMPTBL (L(write_14words), L(table_less32words))\n\t.int\tJMPTBL (L(write_15words), L(table_less32words))\n\t.int\tJMPTBL (L(write_16words), L(table_less32words))\n\t.int\tJMPTBL (L(write_17words), L(table_less32words))\n\t.int\tJMPTBL (L(write_18words), L(table_less32words))\n\t.int\tJMPTBL (L(write_19words), L(table_less32words))\n\t.int\tJMPTBL (L(write_20words), L(table_less32words))\n\t.int\tJMPTBL (L(write_21words), L(table_less32words))\n\t.int\tJMPTBL (L(write_22words), L(table_less32words))\n\t.int\tJMPTBL (L(write_23words), L(table_less32words))\n\t.int\tJMPTBL (L(write_24words), L(table_less32words))\n\t.int\tJMPTBL (L(write_25words), L(table_less32words))\n\t.int\tJMPTBL (L(write_26words), L(table_less32words))\n\t.int\tJMPTBL (L(write_27words), L(table_less32words))\n\t.int\tJMPTBL (L(write_28words), L(table_less32words))\n\t.int\tJMPTBL (L(write_29words), L(table_less32words))\n\t.int\tJMPTBL (L(write_30words), L(table_less32words))\n\t.int\tJMPTBL (L(write_31words), L(table_less32words))\n\t.popsection\n\n\tALIGN (4)\nL(write_28words):\n\tmovl\t%eax, -56(%edx)\n\tmovl\t%eax, -52(%edx)\nL(write_24words):\n\tmovl\t%eax, -48(%edx)\n\tmovl\t%eax, -44(%edx)\nL(write_20words):\n\tmovl\t%eax, -40(%edx)\n\tmovl\t%eax, -36(%edx)\nL(write_16words):\n\tmovl\t%eax, -32(%edx)\n\tmovl\t%eax, -28(%edx)\nL(write_12words):\n\tmovl\t%eax, -24(%edx)\n\tmovl\t%eax, -20(%edx)\nL(write_8words):\n\tmovl\t%eax, -16(%edx)\n\tmovl\t%eax, -12(%edx)\nL(write_4words):\n\tmovl\t%eax, -8(%edx)\n\tmovl\t%eax, -4(%edx)\nL(write_0words):\n\tSETRTNVAL\n\tRETURN\n\n\tALIGN (4)\nL(write_29words):\n\tmovl\t%eax, -58(%edx)\n\tmovl\t%eax, -54(%edx)\nL(write_25words):\n\tmovl\t%eax, -50(%edx)\n\tmovl\t%eax, -46(%edx)\nL(write_21words):\n\tmovl\t%eax, -42(%edx)\n\tmovl\t%eax, -38(%edx)\nL(write_17words):\n\tmovl\t%eax, -34(%edx)\n\tmovl\t%eax, -30(%edx)\nL(write_13words):\n\tmovl\t%eax, -26(%edx)\n\tmovl\t%eax, -22(%edx)\nL(write_9words):\n\tmovl\t%eax, -18(%edx)\n\tmovl\t%eax, -14(%edx)\nL(write_5words):\n\tmovl\t%eax, -10(%edx)\n\tmovl\t%eax, -6(%edx)\nL(write_1words):\n\tmov\t%ax, -2(%edx)\n\tSETRTNVAL\n\tRETURN\n\n\tALIGN (4)\nL(write_30words):\n\tmovl\t%eax, -60(%edx)\n\tmovl\t%eax, -56(%edx)\nL(write_26words):\n\tmovl\t%eax, -52(%edx)\n\tmovl\t%eax, -48(%edx)\nL(write_22words):\n\tmovl\t%eax, -44(%edx)\n\tmovl\t%eax, -40(%edx)\nL(write_18words):\n\tmovl\t%eax, -36(%edx)\n\tmovl\t%eax, -32(%edx)\nL(write_14words):\n\tmovl\t%eax, -28(%edx)\n\tmovl\t%eax, -24(%edx)\nL(write_10words):\n\tmovl\t%eax, -20(%edx)\n\tmovl\t%eax, -16(%edx)\nL(write_6words):\n\tmovl\t%eax, -12(%edx)\n\tmovl\t%eax, -8(%edx)\nL(write_2words):\n\tmovl\t%eax, -4(%edx)\n\tSETRTNVAL\n\tRETURN\n\n\tALIGN (4)\nL(write_31words):\n\tmovl\t%eax, -62(%edx)\n\tmovl\t%eax, -58(%edx)\nL(write_27words):\n\tmovl\t%eax, -54(%edx)\n\tmovl\t%eax, -50(%edx)\nL(write_23words):\n\tmovl\t%eax, -46(%edx)\n\tmovl\t%eax, -42(%edx)\nL(write_19words):\n\tmovl\t%eax, -38(%edx)\n\tmovl\t%eax, -34(%edx)\nL(write_15words):\n\tmovl\t%eax, -30(%edx)\n\tmovl\t%eax, -26(%edx)\nL(write_11words):\n\tmovl\t%eax, -22(%edx)\n\tmovl\t%eax, -18(%edx)\nL(write_7words):\n\tmovl\t%eax, -14(%edx)\n\tmovl\t%eax, -10(%edx)\nL(write_3words):\n\tmovl\t%eax, -6(%edx)\n\tmovw\t%ax, -2(%edx)\n\tSETRTNVAL\n\tRETURN\n\n\tALIGN (4)\n\nL(32wordsormore):\n\tshl\t$1, %ecx\n\ttest\t$0x01, %edx\n\tjz\tL(aligned2bytes)\n\tmov\t%eax, (%edx)\n\tmov\t%eax, -4(%edx, %ecx)\n\tsub\t$2, %ecx\n\tadd\t$1, %edx\n\trol\t$8, %eax\nL(aligned2bytes):\n#ifdef USE_AS_BZERO16\n\tpxor\t%xmm0, %xmm0\n#else\n\tmovd\t%eax, %xmm0\n\tpshufd\t$0, %xmm0, %xmm0\n#endif\n\ttestl\t$0xf, %edx\n\tjz\tL(aligned_16)\n/* ECX > 32 and EDX is not 16 byte aligned.  */\nL(not_aligned_16):\n\tmovdqu\t%xmm0, (%edx)\n\tmovl\t%edx, %eax\n\tand\t$-16, %edx\n\tadd\t$16, %edx\n\tsub\t%edx, %eax\n\tadd\t%eax, %ecx\n\tmovd\t%xmm0, %eax\n\n\tALIGN (4)\nL(aligned_16):\n\tcmp\t$128, %ecx\n\tjae\tL(128bytesormore)\n\nL(aligned_16_less128bytes):\n\tadd\t%ecx, %edx\n\tshr\t$1, %ecx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))\n\n\tALIGN (4)\nL(128bytesormore):\n#ifdef SHARED_CACHE_SIZE\n\tPUSH (%ebx)\n\tmov\t$SHARED_CACHE_SIZE, %ebx\n#else\n# if (defined SHARED || defined __PIC__)\n\tcall\t__x86.get_pc_thunk.bx\n\tadd\t$_GLOBAL_OFFSET_TABLE_, %ebx\n\tmov\t__x86_shared_cache_size@GOTOFF(%ebx), %ebx\n# else\n\tPUSH (%ebx)\n\tmov\t__x86_shared_cache_size, %ebx\n# endif\n#endif\n\tcmp\t%ebx, %ecx\n\tjae\tL(128bytesormore_nt_start)\n\n\n#ifdef DATA_CACHE_SIZE\n\tPOP (%ebx)\n# define RESTORE_EBX_STATE CFI_PUSH (%ebx)\n\tcmp\t$DATA_CACHE_SIZE, %ecx\n#else\n# if (defined SHARED || defined __PIC__)\n#  define RESTORE_EBX_STATE\n\tcall\t__x86.get_pc_thunk.bx\n\tadd\t$_GLOBAL_OFFSET_TABLE_, %ebx\n\tcmp\t__x86_data_cache_size@GOTOFF(%ebx), %ecx\n# else\n\tPOP (%ebx)\n#  define RESTORE_EBX_STATE CFI_PUSH (%ebx)\n\tcmp\t__x86_data_cache_size, %ecx\n# endif\n#endif\n\n\tjae\tL(128bytes_L2_normal)\n\tsubl\t$128, %ecx\nL(128bytesormore_normal):\n\tsub\t$128, %ecx\n\tmovdqa\t%xmm0, (%edx)\n\tmovdqa\t%xmm0, 0x10(%edx)\n\tmovdqa\t%xmm0, 0x20(%edx)\n\tmovdqa\t%xmm0, 0x30(%edx)\n\tmovdqa\t%xmm0, 0x40(%edx)\n\tmovdqa\t%xmm0, 0x50(%edx)\n\tmovdqa\t%xmm0, 0x60(%edx)\n\tmovdqa\t%xmm0, 0x70(%edx)\n\tlea\t128(%edx), %edx\n\tjb\tL(128bytesless_normal)\n\n\n\tsub\t$128, %ecx\n\tmovdqa\t%xmm0, (%edx)\n\tmovdqa\t%xmm0, 0x10(%edx)\n\tmovdqa\t%xmm0, 0x20(%edx)\n\tmovdqa\t%xmm0, 0x30(%edx)\n\tmovdqa\t%xmm0, 0x40(%edx)\n\tmovdqa\t%xmm0, 0x50(%edx)\n\tmovdqa\t%xmm0, 0x60(%edx)\n\tmovdqa\t%xmm0, 0x70(%edx)\n\tlea\t128(%edx), %edx\n\tjae\tL(128bytesormore_normal)\n\nL(128bytesless_normal):\n\tlea\t128(%ecx), %ecx\n\tadd\t%ecx, %edx\n\tshr\t$1, %ecx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))\n\n\tALIGN (4)\nL(128bytes_L2_normal):\n\tprefetcht0\t0x380(%edx)\n\tprefetcht0\t0x3c0(%edx)\n\tsub\t$128, %ecx\n\tmovdqa\t%xmm0, (%edx)\n\tmovaps\t%xmm0, 0x10(%edx)\n\tmovaps\t%xmm0, 0x20(%edx)\n\tmovaps\t%xmm0, 0x30(%edx)\n\tmovaps\t%xmm0, 0x40(%edx)\n\tmovaps\t%xmm0, 0x50(%edx)\n\tmovaps\t%xmm0, 0x60(%edx)\n\tmovaps\t%xmm0, 0x70(%edx)\n\tadd\t$128, %edx\n\tcmp\t$128, %ecx\n\tjae\tL(128bytes_L2_normal)\n\nL(128bytesless_L2_normal):\n\tadd\t%ecx, %edx\n\tshr\t$1, %ecx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))\n\n\tRESTORE_EBX_STATE\nL(128bytesormore_nt_start):\n\tsub\t%ebx, %ecx\n\tmov\t%ebx, %eax\n\tand\t$0x7f, %eax\n\tadd\t%eax, %ecx\n\tmovd\t%xmm0, %eax\n\tALIGN (4)\nL(128bytesormore_shared_cache_loop):\n\tprefetcht0\t0x3c0(%edx)\n\tprefetcht0\t0x380(%edx)\n\tsub\t$0x80, %ebx\n\tmovdqa\t%xmm0, (%edx)\n\tmovdqa\t%xmm0, 0x10(%edx)\n\tmovdqa\t%xmm0, 0x20(%edx)\n\tmovdqa\t%xmm0, 0x30(%edx)\n\tmovdqa\t%xmm0, 0x40(%edx)\n\tmovdqa\t%xmm0, 0x50(%edx)\n\tmovdqa\t%xmm0, 0x60(%edx)\n\tmovdqa\t%xmm0, 0x70(%edx)\n\tadd\t$0x80, %edx\n\tcmp\t$0x80, %ebx\n\tjae\tL(128bytesormore_shared_cache_loop)\n\tcmp\t$0x80, %ecx\n\tjb\tL(shared_cache_loop_end)\n\tALIGN (4)\nL(128bytesormore_nt):\n\tsub\t$0x80, %ecx\n\tmovntdq\t%xmm0, (%edx)\n\tmovntdq\t%xmm0, 0x10(%edx)\n\tmovntdq\t%xmm0, 0x20(%edx)\n\tmovntdq\t%xmm0, 0x30(%edx)\n\tmovntdq\t%xmm0, 0x40(%edx)\n\tmovntdq\t%xmm0, 0x50(%edx)\n\tmovntdq\t%xmm0, 0x60(%edx)\n\tmovntdq\t%xmm0, 0x70(%edx)\n\tadd\t$0x80, %edx\n\tcmp\t$0x80, %ecx\n\tjae\tL(128bytesormore_nt)\n\tsfence\nL(shared_cache_loop_end):\n#if defined DATA_CACHE_SIZE || !(defined SHARED || defined __PIC__)\n\tPOP (%ebx)\n#endif\n\tadd\t%ecx, %edx\n\tshr\t$1, %ecx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))\n\n\n\t.pushsection .rodata.sse2,\"a\",@progbits\n\tALIGN (2)\nL(table_16_128bytes):\n\t.int\tJMPTBL (L(aligned_16_0bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_2bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_4bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_6bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_8bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_10bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_12bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_14bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_16bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_18bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_20bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_22bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_24bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_26bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_28bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_30bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_32bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_34bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_36bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_38bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_40bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_42bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_44bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_46bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_48bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_50bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_52bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_54bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_56bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_58bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_60bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_62bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_64bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_66bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_68bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_70bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_72bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_74bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_76bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_78bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_80bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_82bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_84bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_86bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_88bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_90bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_92bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_94bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_96bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_98bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_100bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_102bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_104bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_106bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_108bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_110bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_112bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_114bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_116bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_118bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_120bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_122bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_124bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_126bytes), L(table_16_128bytes))\n\t.popsection\n\n\n\tALIGN (4)\nL(aligned_16_112bytes):\n\tmovdqa\t%xmm0, -112(%edx)\nL(aligned_16_96bytes):\n\tmovdqa\t%xmm0, -96(%edx)\nL(aligned_16_80bytes):\n\tmovdqa\t%xmm0, -80(%edx)\nL(aligned_16_64bytes):\n\tmovdqa\t%xmm0, -64(%edx)\nL(aligned_16_48bytes):\n\tmovdqa\t%xmm0, -48(%edx)\nL(aligned_16_32bytes):\n\tmovdqa\t%xmm0, -32(%edx)\nL(aligned_16_16bytes):\n\tmovdqa\t%xmm0, -16(%edx)\nL(aligned_16_0bytes):\n\tSETRTNVAL\n\tRETURN\n\n\n\tALIGN (4)\nL(aligned_16_114bytes):\n\tmovdqa\t%xmm0, -114(%edx)\nL(aligned_16_98bytes):\n\tmovdqa\t%xmm0, -98(%edx)\nL(aligned_16_82bytes):\n\tmovdqa\t%xmm0, -82(%edx)\nL(aligned_16_66bytes):\n\tmovdqa\t%xmm0, -66(%edx)\nL(aligned_16_50bytes):\n\tmovdqa\t%xmm0, -50(%edx)\nL(aligned_16_34bytes):\n\tmovdqa\t%xmm0, -34(%edx)\nL(aligned_16_18bytes):\n\tmovdqa\t%xmm0, -18(%edx)\nL(aligned_16_2bytes):\n\tmovw\t%ax, -2(%edx)\n\tSETRTNVAL\n\tRETURN\n\n\tALIGN (4)\nL(aligned_16_116bytes):\n\tmovdqa\t%xmm0, -116(%edx)\nL(aligned_16_100bytes):\n\tmovdqa\t%xmm0, -100(%edx)\nL(aligned_16_84bytes):\n\tmovdqa\t%xmm0, -84(%edx)\nL(aligned_16_68bytes):\n\tmovdqa\t%xmm0, -68(%edx)\nL(aligned_16_52bytes):\n\tmovdqa\t%xmm0, -52(%edx)\nL(aligned_16_36bytes):\n\tmovdqa\t%xmm0, -36(%edx)\nL(aligned_16_20bytes):\n\tmovdqa\t%xmm0, -20(%edx)\nL(aligned_16_4bytes):\n\tmovl\t%eax, -4(%edx)\n\tSETRTNVAL\n\tRETURN\n\n\n\tALIGN (4)\nL(aligned_16_118bytes):\n\tmovdqa\t%xmm0, -118(%edx)\nL(aligned_16_102bytes):\n\tmovdqa\t%xmm0, -102(%edx)\nL(aligned_16_86bytes):\n\tmovdqa\t%xmm0, -86(%edx)\nL(aligned_16_70bytes):\n\tmovdqa\t%xmm0, -70(%edx)\nL(aligned_16_54bytes):\n\tmovdqa\t%xmm0, -54(%edx)\nL(aligned_16_38bytes):\n\tmovdqa\t%xmm0, -38(%edx)\nL(aligned_16_22bytes):\n\tmovdqa\t%xmm0, -22(%edx)\nL(aligned_16_6bytes):\n\tmovl\t%eax, -6(%edx)\n\tmovw\t%ax, -2(%edx)\n\tSETRTNVAL\n\tRETURN\n\n\n\tALIGN (4)\nL(aligned_16_120bytes):\n\tmovdqa\t%xmm0, -120(%edx)\nL(aligned_16_104bytes):\n\tmovdqa\t%xmm0, -104(%edx)\nL(aligned_16_88bytes):\n\tmovdqa\t%xmm0, -88(%edx)\nL(aligned_16_72bytes):\n\tmovdqa\t%xmm0, -72(%edx)\nL(aligned_16_56bytes):\n\tmovdqa\t%xmm0, -56(%edx)\nL(aligned_16_40bytes):\n\tmovdqa\t%xmm0, -40(%edx)\nL(aligned_16_24bytes):\n\tmovdqa\t%xmm0, -24(%edx)\nL(aligned_16_8bytes):\n\tmovq\t%xmm0, -8(%edx)\n\tSETRTNVAL\n\tRETURN\n\n\n\tALIGN (4)\nL(aligned_16_122bytes):\n\tmovdqa\t%xmm0, -122(%edx)\nL(aligned_16_106bytes):\n\tmovdqa\t%xmm0, -106(%edx)\nL(aligned_16_90bytes):\n\tmovdqa\t%xmm0, -90(%edx)\nL(aligned_16_74bytes):\n\tmovdqa\t%xmm0, -74(%edx)\nL(aligned_16_58bytes):\n\tmovdqa\t%xmm0, -58(%edx)\nL(aligned_16_42bytes):\n\tmovdqa\t%xmm0, -42(%edx)\nL(aligned_16_26bytes):\n\tmovdqa\t%xmm0, -26(%edx)\nL(aligned_16_10bytes):\n\tmovq\t%xmm0, -10(%edx)\n\tmovw\t%ax, -2(%edx)\n\tSETRTNVAL\n\tRETURN\n\n\n\tALIGN (4)\nL(aligned_16_124bytes):\n\tmovdqa\t%xmm0, -124(%edx)\nL(aligned_16_108bytes):\n\tmovdqa\t%xmm0, -108(%edx)\nL(aligned_16_92bytes):\n\tmovdqa\t%xmm0, -92(%edx)\nL(aligned_16_76bytes):\n\tmovdqa\t%xmm0, -76(%edx)\nL(aligned_16_60bytes):\n\tmovdqa\t%xmm0, -60(%edx)\nL(aligned_16_44bytes):\n\tmovdqa\t%xmm0, -44(%edx)\nL(aligned_16_28bytes):\n\tmovdqa\t%xmm0, -28(%edx)\nL(aligned_16_12bytes):\n\tmovq\t%xmm0, -12(%edx)\n\tmovl\t%eax, -4(%edx)\n\tSETRTNVAL\n\tRETURN\n\n\n\tALIGN (4)\nL(aligned_16_126bytes):\n\tmovdqa\t%xmm0, -126(%edx)\nL(aligned_16_110bytes):\n\tmovdqa\t%xmm0, -110(%edx)\nL(aligned_16_94bytes):\n\tmovdqa\t%xmm0, -94(%edx)\nL(aligned_16_78bytes):\n\tmovdqa\t%xmm0, -78(%edx)\nL(aligned_16_62bytes):\n\tmovdqa\t%xmm0, -62(%edx)\nL(aligned_16_46bytes):\n\tmovdqa\t%xmm0, -46(%edx)\nL(aligned_16_30bytes):\n\tmovdqa\t%xmm0, -30(%edx)\nL(aligned_16_14bytes):\n\tmovq\t%xmm0, -14(%edx)\n\tmovl\t%eax, -6(%edx)\n\tmovw\t%ax, -2(%edx)\n\tSETRTNVAL\n\tRETURN\n\nEND (MEMSET)\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/arch-x86/android_memset32.S",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"cache.h\"\n\n#ifndef MEMSET\n# define MEMSET \tandroid_memset32\n#endif\n\n#ifndef L\n# define L(label)\t.L##label\n#endif\n\n#ifndef ALIGN\n# define ALIGN(n)\t.p2align n\n#endif\n\n#ifndef cfi_startproc\n# define cfi_startproc\t\t\t.cfi_startproc\n#endif\n\n#ifndef cfi_endproc\n# define cfi_endproc\t\t\t.cfi_endproc\n#endif\n\n#ifndef cfi_rel_offset\n# define cfi_rel_offset(reg, off)\t.cfi_rel_offset reg, off\n#endif\n\n#ifndef cfi_restore\n# define cfi_restore(reg)\t\t.cfi_restore reg\n#endif\n\n#ifndef cfi_adjust_cfa_offset\n# define cfi_adjust_cfa_offset(off)\t.cfi_adjust_cfa_offset off\n#endif\n\n#ifndef ENTRY\n# define ENTRY(name)\t\t\t\\\n\t.type name,  @function; \t\\\n\t.globl name;\t\t\t\\\n\t.p2align 4;\t\t\t\\\nname:\t\t\t\t\t\\\n\tcfi_startproc\n#endif\n\n#ifndef END\n# define END(name)\t\t\t\\\n\tcfi_endproc;\t\t\t\\\n\t.size name, .-name\n#endif\n\n#define CFI_PUSH(REG)\t\t\t\t\t\t\\\n  cfi_adjust_cfa_offset (4);\t\t\t\t\t\\\n  cfi_rel_offset (REG, 0)\n\n#define CFI_POP(REG)\t\t\t\t\t\t\\\n  cfi_adjust_cfa_offset (-4);\t\t\t\t\t\\\n  cfi_restore (REG)\n\n#define PUSH(REG)\tpushl REG; CFI_PUSH (REG)\n#define POP(REG)\tpopl REG; CFI_POP (REG)\n\n#ifdef USE_AS_BZERO32\n# define DEST\t\tPARMS\n# define LEN\t\tDEST+4\n# define SETRTNVAL\n#else\n# define DEST\t\tPARMS\n# define DWDS\t\tDEST+4\n# define LEN\t\tDWDS+4\n# define SETRTNVAL\tmovl DEST(%esp), %eax\n#endif\n\n#if (defined SHARED || defined __PIC__)\n# define ENTRANCE\tPUSH (%ebx);\n# define RETURN_END\tPOP (%ebx); ret\n# define RETURN\t\tRETURN_END; CFI_PUSH (%ebx)\n# define PARMS\t\t8\t\t/* Preserve EBX.  */\n# define JMPTBL(I, B)\tI - B\n\n/* Load an entry in a jump table into EBX and branch to it.  TABLE is a\n   jump table with relative offsets.   */\n# define BRANCH_TO_JMPTBL_ENTRY(TABLE)\t\t\t\t\\\n    /* We first load PC into EBX.  */\t\t\t\t\\\n    call\t__x86.get_pc_thunk.bx;\t\t\t\t\\\n    /* Get the address of the jump table.  */\t\t\t\\\n    add\t\t$(TABLE - .), %ebx;\t\t\t\t\\\n    /* Get the entry and convert the relative offset to the\t\\\n       absolute address.  */\t\t\t\t\t\\\n    add\t\t(%ebx,%ecx,4), %ebx;\t\t\t\t\\\n    /* We loaded the jump table and adjuested EDX. Go.  */\t\\\n    jmp\t\t*%ebx\n\n\t.section\t.gnu.linkonce.t.__x86.get_pc_thunk.bx,\"ax\",@progbits\n\t.globl\t__x86.get_pc_thunk.bx\n\t.hidden\t__x86.get_pc_thunk.bx\n\tALIGN (4)\n\t.type\t__x86.get_pc_thunk.bx,@function\n__x86.get_pc_thunk.bx:\n\tmovl\t(%esp), %ebx\n\tret\n#else\n# define ENTRANCE\n# define RETURN_END\tret\n# define RETURN\t\tRETURN_END\n# define PARMS\t\t4\n# define JMPTBL(I, B)\tI\n\n/* Branch to an entry in a jump table.  TABLE is a jump table with\n   absolute offsets.  */\n# define BRANCH_TO_JMPTBL_ENTRY(TABLE)\t\t\t\t\\\n    jmp\t\t*TABLE(,%ecx,4)\n#endif\n\n\t.section .text.sse2,\"ax\",@progbits\n\tALIGN (4)\nENTRY (MEMSET)\n\tENTRANCE\n\n\tmovl\tLEN(%esp), %ecx\n\tshr     $2, %ecx\n#ifdef USE_AS_BZERO32\n\txor\t%eax, %eax\n#else\n\tmov\tDWDS(%esp), %eax\n\tmov\t%eax, %edx\n#endif\n\tmovl\tDEST(%esp), %edx\n\tcmp\t$16, %ecx\n\tjae\tL(16dbwordsormore)\n\nL(write_less16dbwords):\n\tlea\t(%edx, %ecx, 4), %edx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_less16dbwords))\n\n\t.pushsection .rodata.sse2,\"a\",@progbits\n\tALIGN (2)\nL(table_less16dbwords):\n\t.int\tJMPTBL (L(write_0dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_1dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_2dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_3dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_4dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_5dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_6dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_7dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_8dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_9dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_10dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_11dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_12dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_13dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_14dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_15dbwords), L(table_less16dbwords))\n\t.popsection\n\n\tALIGN (4)\nL(write_15dbwords):\n\tmovl\t%eax, -60(%edx)\nL(write_14dbwords):\n\tmovl\t%eax, -56(%edx)\nL(write_13dbwords):\n\tmovl\t%eax, -52(%edx)\nL(write_12dbwords):\n\tmovl\t%eax, -48(%edx)\nL(write_11dbwords):\n\tmovl\t%eax, -44(%edx)\nL(write_10dbwords):\n\tmovl\t%eax, -40(%edx)\nL(write_9dbwords):\n\tmovl\t%eax, -36(%edx)\nL(write_8dbwords):\n\tmovl\t%eax, -32(%edx)\nL(write_7dbwords):\n\tmovl\t%eax, -28(%edx)\nL(write_6dbwords):\n\tmovl\t%eax, -24(%edx)\nL(write_5dbwords):\n\tmovl\t%eax, -20(%edx)\nL(write_4dbwords):\n\tmovl\t%eax, -16(%edx)\nL(write_3dbwords):\n\tmovl\t%eax, -12(%edx)\nL(write_2dbwords):\n\tmovl\t%eax, -8(%edx)\nL(write_1dbwords):\n\tmovl\t%eax, -4(%edx)\nL(write_0dbwords):\n\tSETRTNVAL\n\tRETURN\n\n\tALIGN (4)\nL(16dbwordsormore):\n\ttest\t$3, %edx\n\tjz\tL(aligned4bytes)\n\tmov\t%eax, (%edx)\n\tmov\t%eax, -4(%edx, %ecx, 4)\n\tsub\t$1, %ecx\n\trol\t$24, %eax\n\tadd\t$1, %edx\n\ttest\t$3, %edx\n\tjz\tL(aligned4bytes)\n\tror\t$8, %eax\n\tadd\t$1, %edx\n\ttest\t$3, %edx\n\tjz\tL(aligned4bytes)\n\tror\t$8, %eax\n\tadd\t$1, %edx\nL(aligned4bytes):\n\tshl\t$2, %ecx\n\n#ifdef USE_AS_BZERO32\n\tpxor\t%xmm0, %xmm0\n#else\n\tmovd\t%eax, %xmm0\n\tpshufd\t$0, %xmm0, %xmm0\n#endif\n\ttestl\t$0xf, %edx\n\tjz\tL(aligned_16)\n/* ECX > 32 and EDX is not 16 byte aligned.  */\nL(not_aligned_16):\n\tmovdqu\t%xmm0, (%edx)\n\tmovl\t%edx, %eax\n\tand\t$-16, %edx\n\tadd\t$16, %edx\n\tsub\t%edx, %eax\n\tadd\t%eax, %ecx\n\tmovd\t%xmm0, %eax\n\tALIGN (4)\nL(aligned_16):\n\tcmp\t$128, %ecx\n\tjae\tL(128bytesormore)\n\nL(aligned_16_less128bytes):\n\tadd\t%ecx, %edx\n\tshr\t$2, %ecx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))\n\n\tALIGN (4)\nL(128bytesormore):\n#ifdef SHARED_CACHE_SIZE\n\tPUSH (%ebx)\n\tmov\t$SHARED_CACHE_SIZE, %ebx\n#else\n# if (defined SHARED || defined __PIC__)\n\tcall\t__x86.get_pc_thunk.bx\n\tadd\t$_GLOBAL_OFFSET_TABLE_, %ebx\n\tmov\t__x86_shared_cache_size@GOTOFF(%ebx), %ebx\n# else\n\tPUSH (%ebx)\n\tmov\t__x86_shared_cache_size, %ebx\n# endif\n#endif\n\tcmp\t%ebx, %ecx\n\tjae\tL(128bytesormore_nt_start)\n\n#ifdef DATA_CACHE_SIZE\n\tPOP (%ebx)\n# define RESTORE_EBX_STATE CFI_PUSH (%ebx)\n\tcmp\t$DATA_CACHE_SIZE, %ecx\n#else\n# if (defined SHARED || defined __PIC__)\n#  define RESTORE_EBX_STATE\n\tcall\t__x86.get_pc_thunk.bx\n\tadd\t$_GLOBAL_OFFSET_TABLE_, %ebx\n\tcmp\t__x86_data_cache_size@GOTOFF(%ebx), %ecx\n# else\n\tPOP (%ebx)\n#  define RESTORE_EBX_STATE CFI_PUSH (%ebx)\n\tcmp\t__x86_data_cache_size, %ecx\n# endif\n#endif\n\n\tjae\tL(128bytes_L2_normal)\n\tsubl\t$128, %ecx\nL(128bytesormore_normal):\n\tsub\t$128, %ecx\n\tmovdqa\t%xmm0, (%edx)\n\tmovdqa\t%xmm0, 0x10(%edx)\n\tmovdqa\t%xmm0, 0x20(%edx)\n\tmovdqa\t%xmm0, 0x30(%edx)\n\tmovdqa\t%xmm0, 0x40(%edx)\n\tmovdqa\t%xmm0, 0x50(%edx)\n\tmovdqa\t%xmm0, 0x60(%edx)\n\tmovdqa\t%xmm0, 0x70(%edx)\n\tlea\t128(%edx), %edx\n\tjb\tL(128bytesless_normal)\n\n\n\tsub\t$128, %ecx\n\tmovdqa\t%xmm0, (%edx)\n\tmovdqa\t%xmm0, 0x10(%edx)\n\tmovdqa\t%xmm0, 0x20(%edx)\n\tmovdqa\t%xmm0, 0x30(%edx)\n\tmovdqa\t%xmm0, 0x40(%edx)\n\tmovdqa\t%xmm0, 0x50(%edx)\n\tmovdqa\t%xmm0, 0x60(%edx)\n\tmovdqa\t%xmm0, 0x70(%edx)\n\tlea\t128(%edx), %edx\n\tjae\tL(128bytesormore_normal)\n\nL(128bytesless_normal):\n\tlea\t128(%ecx), %ecx\n\tadd\t%ecx, %edx\n\tshr\t$2, %ecx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))\n\n\tALIGN (4)\nL(128bytes_L2_normal):\n\tprefetcht0\t0x380(%edx)\n\tprefetcht0\t0x3c0(%edx)\n\tsub\t$128, %ecx\n\tmovdqa\t%xmm0, (%edx)\n\tmovaps\t%xmm0, 0x10(%edx)\n\tmovaps\t%xmm0, 0x20(%edx)\n\tmovaps\t%xmm0, 0x30(%edx)\n\tmovaps\t%xmm0, 0x40(%edx)\n\tmovaps\t%xmm0, 0x50(%edx)\n\tmovaps\t%xmm0, 0x60(%edx)\n\tmovaps\t%xmm0, 0x70(%edx)\n\tadd\t$128, %edx\n\tcmp\t$128, %ecx\n\tjae\tL(128bytes_L2_normal)\n\nL(128bytesless_L2_normal):\n\tadd\t%ecx, %edx\n\tshr\t$2, %ecx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))\n\n\tRESTORE_EBX_STATE\nL(128bytesormore_nt_start):\n\tsub\t%ebx, %ecx\n\tmov\t%ebx, %eax\n\tand\t$0x7f, %eax\n\tadd\t%eax, %ecx\n\tmovd\t%xmm0, %eax\n\tALIGN (4)\nL(128bytesormore_shared_cache_loop):\n\tprefetcht0\t0x3c0(%edx)\n\tprefetcht0\t0x380(%edx)\n\tsub\t$0x80, %ebx\n\tmovdqa\t%xmm0, (%edx)\n\tmovdqa\t%xmm0, 0x10(%edx)\n\tmovdqa\t%xmm0, 0x20(%edx)\n\tmovdqa\t%xmm0, 0x30(%edx)\n\tmovdqa\t%xmm0, 0x40(%edx)\n\tmovdqa\t%xmm0, 0x50(%edx)\n\tmovdqa\t%xmm0, 0x60(%edx)\n\tmovdqa\t%xmm0, 0x70(%edx)\n\tadd\t$0x80, %edx\n\tcmp\t$0x80, %ebx\n\tjae\tL(128bytesormore_shared_cache_loop)\n\tcmp\t$0x80, %ecx\n\tjb\tL(shared_cache_loop_end)\n\n\tALIGN (4)\nL(128bytesormore_nt):\n\tsub\t$0x80, %ecx\n\tmovntdq\t%xmm0, (%edx)\n\tmovntdq\t%xmm0, 0x10(%edx)\n\tmovntdq\t%xmm0, 0x20(%edx)\n\tmovntdq\t%xmm0, 0x30(%edx)\n\tmovntdq\t%xmm0, 0x40(%edx)\n\tmovntdq\t%xmm0, 0x50(%edx)\n\tmovntdq\t%xmm0, 0x60(%edx)\n\tmovntdq\t%xmm0, 0x70(%edx)\n\tadd\t$0x80, %edx\n\tcmp\t$0x80, %ecx\n\tjae\tL(128bytesormore_nt)\n\tsfence\nL(shared_cache_loop_end):\n#if defined DATA_CACHE_SIZE || !(defined SHARED || defined __PIC__)\n\tPOP (%ebx)\n#endif\n\tadd\t%ecx, %edx\n\tshr\t$2, %ecx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))\n\n\t.pushsection .rodata.sse2,\"a\",@progbits\n\tALIGN (2)\nL(table_16_128bytes):\n\t.int\tJMPTBL (L(aligned_16_0bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_4bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_8bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_12bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_16bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_20bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_24bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_28bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_32bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_36bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_40bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_44bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_48bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_52bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_56bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_60bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_64bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_68bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_72bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_76bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_80bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_84bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_88bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_92bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_96bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_100bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_104bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_108bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_112bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_116bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_120bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_124bytes), L(table_16_128bytes))\n\t.popsection\n\n\tALIGN (4)\nL(aligned_16_112bytes):\n\tmovdqa\t%xmm0, -112(%edx)\nL(aligned_16_96bytes):\n\tmovdqa\t%xmm0, -96(%edx)\nL(aligned_16_80bytes):\n\tmovdqa\t%xmm0, -80(%edx)\nL(aligned_16_64bytes):\n\tmovdqa\t%xmm0, -64(%edx)\nL(aligned_16_48bytes):\n\tmovdqa\t%xmm0, -48(%edx)\nL(aligned_16_32bytes):\n\tmovdqa\t%xmm0, -32(%edx)\nL(aligned_16_16bytes):\n\tmovdqa\t%xmm0, -16(%edx)\nL(aligned_16_0bytes):\n\tSETRTNVAL\n\tRETURN\n\n\tALIGN (4)\nL(aligned_16_116bytes):\n\tmovdqa\t%xmm0, -116(%edx)\nL(aligned_16_100bytes):\n\tmovdqa\t%xmm0, -100(%edx)\nL(aligned_16_84bytes):\n\tmovdqa\t%xmm0, -84(%edx)\nL(aligned_16_68bytes):\n\tmovdqa\t%xmm0, -68(%edx)\nL(aligned_16_52bytes):\n\tmovdqa\t%xmm0, -52(%edx)\nL(aligned_16_36bytes):\n\tmovdqa\t%xmm0, -36(%edx)\nL(aligned_16_20bytes):\n\tmovdqa\t%xmm0, -20(%edx)\nL(aligned_16_4bytes):\n\tmovl\t%eax, -4(%edx)\n\tSETRTNVAL\n\tRETURN\n\n\tALIGN (4)\nL(aligned_16_120bytes):\n\tmovdqa\t%xmm0, -120(%edx)\nL(aligned_16_104bytes):\n\tmovdqa\t%xmm0, -104(%edx)\nL(aligned_16_88bytes):\n\tmovdqa\t%xmm0, -88(%edx)\nL(aligned_16_72bytes):\n\tmovdqa\t%xmm0, -72(%edx)\nL(aligned_16_56bytes):\n\tmovdqa\t%xmm0, -56(%edx)\nL(aligned_16_40bytes):\n\tmovdqa\t%xmm0, -40(%edx)\nL(aligned_16_24bytes):\n\tmovdqa\t%xmm0, -24(%edx)\nL(aligned_16_8bytes):\n\tmovq\t%xmm0, -8(%edx)\n\tSETRTNVAL\n\tRETURN\n\n\tALIGN (4)\nL(aligned_16_124bytes):\n\tmovdqa\t%xmm0, -124(%edx)\nL(aligned_16_108bytes):\n\tmovdqa\t%xmm0, -108(%edx)\nL(aligned_16_92bytes):\n\tmovdqa\t%xmm0, -92(%edx)\nL(aligned_16_76bytes):\n\tmovdqa\t%xmm0, -76(%edx)\nL(aligned_16_60bytes):\n\tmovdqa\t%xmm0, -60(%edx)\nL(aligned_16_44bytes):\n\tmovdqa\t%xmm0, -44(%edx)\nL(aligned_16_28bytes):\n\tmovdqa\t%xmm0, -28(%edx)\nL(aligned_16_12bytes):\n\tmovq\t%xmm0, -12(%edx)\n\tmovl\t%eax, -4(%edx)\n\tSETRTNVAL\n\tRETURN\n\nEND (MEMSET)\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/arch-x86/cache.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#if defined(__slm__)\n/* Values are optimized for Silvermont */\n#define SHARED_CACHE_SIZE   (1024*1024)         /* Silvermont L2 Cache */\n#define DATA_CACHE_SIZE     (24*1024)           /* Silvermont L1 Data Cache */\n#else\n/* Values are optimized for Atom */\n#define SHARED_CACHE_SIZE   (512*1024)          /* Atom L2 Cache */\n#define DATA_CACHE_SIZE     (24*1024)           /* Atom L1 Data Cache */\n#endif\n\n#define SHARED_CACHE_SIZE_HALF  (SHARED_CACHE_SIZE / 2)\n#define DATA_CACHE_SIZE_HALF    (DATA_CACHE_SIZE / 2)\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/arch-x86_64/android_memset16.S",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"cache.h\"\n\n#ifndef MEMSET\n# define MEMSET\t\tandroid_memset16\n#endif\n\n#ifndef L\n# define L(label)\t.L##label\n#endif\n\n#ifndef ALIGN\n# define ALIGN(n)\t.p2align n\n#endif\n\n#ifndef cfi_startproc\n# define cfi_startproc\t\t\t.cfi_startproc\n#endif\n\n#ifndef cfi_endproc\n# define cfi_endproc\t\t\t.cfi_endproc\n#endif\n\n#ifndef ENTRY\n# define ENTRY(name)\t\t\t\\\n\t.type name,  @function; \t\\\n\t.globl name;\t\t\t\\\n\t.p2align 4;\t\t\t\\\nname:\t\t\t\t\t\\\n\tcfi_startproc\n#endif\n\n#ifndef END\n# define END(name)\t\t\t\\\n\tcfi_endproc;\t\t\t\\\n\t.size name, .-name\n#endif\n\n#define JMPTBL(I, B)\tI - B\n\n/* Branch to an entry in a jump table.  TABLE is a jump table with\n   relative offsets.  INDEX is a register contains the index into the\n   jump table.  SCALE is the scale of INDEX.  */\n#define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \\\n\tlea    TABLE(%rip), %r11;\t\t\t\t\t\t\\\n\tmovslq (%r11, INDEX, SCALE), INDEX;\t\t\t\t\\\n\tlea    (%r11, INDEX), INDEX;\t\t\t\t\t\\\n\tjmp    *INDEX\n\n\t.section .text.sse2,\"ax\",@progbits\n\tALIGN (4)\nENTRY (MEMSET)\t// Address in rdi\n\tshr    $1, %rdx\t\t\t// Count in rdx\n\tmovzwl %si, %ecx\n\t/* Fill the whole ECX with pattern.  */\n\tshl    $16, %esi\n\tor     %esi, %ecx\t\t// Pattern in ecx\n\n\tcmp    $32, %rdx\n\tjae    L(32wordsormore)\n\nL(write_less32words):\n\tlea    (%rdi, %rdx, 2), %rdi\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_less32words), %rdx, 4)\n\n\t.pushsection .rodata.sse2,\"a\",@progbits\n\tALIGN (2)\nL(table_less32words):\n\t.int\tJMPTBL (L(write_0words), L(table_less32words))\n\t.int\tJMPTBL (L(write_1words), L(table_less32words))\n\t.int\tJMPTBL (L(write_2words), L(table_less32words))\n\t.int\tJMPTBL (L(write_3words), L(table_less32words))\n\t.int\tJMPTBL (L(write_4words), L(table_less32words))\n\t.int\tJMPTBL (L(write_5words), L(table_less32words))\n\t.int\tJMPTBL (L(write_6words), L(table_less32words))\n\t.int\tJMPTBL (L(write_7words), L(table_less32words))\n\t.int\tJMPTBL (L(write_8words), L(table_less32words))\n\t.int\tJMPTBL (L(write_9words), L(table_less32words))\n\t.int\tJMPTBL (L(write_10words), L(table_less32words))\n\t.int\tJMPTBL (L(write_11words), L(table_less32words))\n\t.int\tJMPTBL (L(write_12words), L(table_less32words))\n\t.int\tJMPTBL (L(write_13words), L(table_less32words))\n\t.int\tJMPTBL (L(write_14words), L(table_less32words))\n\t.int\tJMPTBL (L(write_15words), L(table_less32words))\n\t.int\tJMPTBL (L(write_16words), L(table_less32words))\n\t.int\tJMPTBL (L(write_17words), L(table_less32words))\n\t.int\tJMPTBL (L(write_18words), L(table_less32words))\n\t.int\tJMPTBL (L(write_19words), L(table_less32words))\n\t.int\tJMPTBL (L(write_20words), L(table_less32words))\n\t.int\tJMPTBL (L(write_21words), L(table_less32words))\n\t.int\tJMPTBL (L(write_22words), L(table_less32words))\n\t.int\tJMPTBL (L(write_23words), L(table_less32words))\n\t.int\tJMPTBL (L(write_24words), L(table_less32words))\n\t.int\tJMPTBL (L(write_25words), L(table_less32words))\n\t.int\tJMPTBL (L(write_26words), L(table_less32words))\n\t.int\tJMPTBL (L(write_27words), L(table_less32words))\n\t.int\tJMPTBL (L(write_28words), L(table_less32words))\n\t.int\tJMPTBL (L(write_29words), L(table_less32words))\n\t.int\tJMPTBL (L(write_30words), L(table_less32words))\n\t.int\tJMPTBL (L(write_31words), L(table_less32words))\n\t.popsection\n\n\tALIGN (4)\nL(write_28words):\n\tmovl   %ecx, -56(%rdi)\n\tmovl   %ecx, -52(%rdi)\nL(write_24words):\n\tmovl   %ecx, -48(%rdi)\n\tmovl   %ecx, -44(%rdi)\nL(write_20words):\n\tmovl   %ecx, -40(%rdi)\n\tmovl   %ecx, -36(%rdi)\nL(write_16words):\n\tmovl   %ecx, -32(%rdi)\n\tmovl   %ecx, -28(%rdi)\nL(write_12words):\n\tmovl   %ecx, -24(%rdi)\n\tmovl   %ecx, -20(%rdi)\nL(write_8words):\n\tmovl   %ecx, -16(%rdi)\n\tmovl   %ecx, -12(%rdi)\nL(write_4words):\n\tmovl   %ecx, -8(%rdi)\n\tmovl   %ecx, -4(%rdi)\nL(write_0words):\n\tret\n\n\tALIGN (4)\nL(write_29words):\n\tmovl   %ecx, -58(%rdi)\n\tmovl   %ecx, -54(%rdi)\nL(write_25words):\n\tmovl   %ecx, -50(%rdi)\n\tmovl   %ecx, -46(%rdi)\nL(write_21words):\n\tmovl   %ecx, -42(%rdi)\n\tmovl   %ecx, -38(%rdi)\nL(write_17words):\n\tmovl   %ecx, -34(%rdi)\n\tmovl   %ecx, -30(%rdi)\nL(write_13words):\n\tmovl   %ecx, -26(%rdi)\n\tmovl   %ecx, -22(%rdi)\nL(write_9words):\n\tmovl   %ecx, -18(%rdi)\n\tmovl   %ecx, -14(%rdi)\nL(write_5words):\n\tmovl   %ecx, -10(%rdi)\n\tmovl   %ecx, -6(%rdi)\nL(write_1words):\n\tmov\t%cx, -2(%rdi)\n\tret\n\n\tALIGN (4)\nL(write_30words):\n\tmovl   %ecx, -60(%rdi)\n\tmovl   %ecx, -56(%rdi)\nL(write_26words):\n\tmovl   %ecx, -52(%rdi)\n\tmovl   %ecx, -48(%rdi)\nL(write_22words):\n\tmovl   %ecx, -44(%rdi)\n\tmovl   %ecx, -40(%rdi)\nL(write_18words):\n\tmovl   %ecx, -36(%rdi)\n\tmovl   %ecx, -32(%rdi)\nL(write_14words):\n\tmovl   %ecx, -28(%rdi)\n\tmovl   %ecx, -24(%rdi)\nL(write_10words):\n\tmovl   %ecx, -20(%rdi)\n\tmovl   %ecx, -16(%rdi)\nL(write_6words):\n\tmovl   %ecx, -12(%rdi)\n\tmovl   %ecx, -8(%rdi)\nL(write_2words):\n\tmovl   %ecx, -4(%rdi)\n\tret\n\n\tALIGN (4)\nL(write_31words):\n\tmovl   %ecx, -62(%rdi)\n\tmovl   %ecx, -58(%rdi)\nL(write_27words):\n\tmovl   %ecx, -54(%rdi)\n\tmovl   %ecx, -50(%rdi)\nL(write_23words):\n\tmovl   %ecx, -46(%rdi)\n\tmovl   %ecx, -42(%rdi)\nL(write_19words):\n\tmovl   %ecx, -38(%rdi)\n\tmovl   %ecx, -34(%rdi)\nL(write_15words):\n\tmovl   %ecx, -30(%rdi)\n\tmovl   %ecx, -26(%rdi)\nL(write_11words):\n\tmovl   %ecx, -22(%rdi)\n\tmovl   %ecx, -18(%rdi)\nL(write_7words):\n\tmovl   %ecx, -14(%rdi)\n\tmovl   %ecx, -10(%rdi)\nL(write_3words):\n\tmovl   %ecx, -6(%rdi)\n\tmovw   %cx, -2(%rdi)\n\tret\n\n\tALIGN (4)\nL(32wordsormore):\n\tshl    $1, %rdx\n\ttest   $0x01, %edi\n\tjz     L(aligned2bytes)\n\tmov    %ecx, (%rdi)\n\tmov    %ecx, -4(%rdi, %rdx)\n\tsub    $2, %rdx\n\tadd    $1, %rdi\n\trol    $8, %ecx\nL(aligned2bytes):\n\t/* Fill xmm0 with the pattern.  */\n\tmovd   %ecx, %xmm0\n\tpshufd $0, %xmm0, %xmm0\n\n\ttestl  $0xf, %edi\n\tjz     L(aligned_16)\n/* RDX > 32 and RDI is not 16 byte aligned.  */\n\tmovdqu %xmm0, (%rdi)\n\tmov    %rdi, %rsi\n\tand    $-16, %rdi\n\tadd    $16, %rdi\n\tsub    %rdi, %rsi\n\tadd    %rsi, %rdx\n\n\tALIGN (4)\nL(aligned_16):\n\tcmp    $128, %rdx\n\tjge    L(128bytesormore)\n\nL(aligned_16_less128bytes):\n\tadd    %rdx, %rdi\n\tshr    $1, %rdx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)\n\n\tALIGN (4)\nL(128bytesormore):\n\tcmp    $SHARED_CACHE_SIZE, %rdx\n\tjg     L(128bytesormore_nt)\n\nL(128bytesormore_normal):\n\tsub    $128, %rdx\n\tmovdqa %xmm0, (%rdi)\n\tmovdqa %xmm0, 0x10(%rdi)\n\tmovdqa %xmm0, 0x20(%rdi)\n\tmovdqa %xmm0, 0x30(%rdi)\n\tmovdqa %xmm0, 0x40(%rdi)\n\tmovdqa %xmm0, 0x50(%rdi)\n\tmovdqa %xmm0, 0x60(%rdi)\n\tmovdqa %xmm0, 0x70(%rdi)\n\tlea    128(%rdi), %rdi\n\tcmp    $128, %rdx\n\tjl     L(128bytesless_normal)\n\n\tsub    $128, %rdx\n\tmovdqa %xmm0, (%rdi)\n\tmovdqa %xmm0, 0x10(%rdi)\n\tmovdqa %xmm0, 0x20(%rdi)\n\tmovdqa %xmm0, 0x30(%rdi)\n\tmovdqa %xmm0, 0x40(%rdi)\n\tmovdqa %xmm0, 0x50(%rdi)\n\tmovdqa %xmm0, 0x60(%rdi)\n\tmovdqa %xmm0, 0x70(%rdi)\n\tlea    128(%rdi), %rdi\n\tcmp    $128, %rdx\n\tjl     L(128bytesless_normal)\n\n\tsub    $128, %rdx\n\tmovdqa %xmm0, (%rdi)\n\tmovdqa %xmm0, 0x10(%rdi)\n\tmovdqa %xmm0, 0x20(%rdi)\n\tmovdqa %xmm0, 0x30(%rdi)\n\tmovdqa %xmm0, 0x40(%rdi)\n\tmovdqa %xmm0, 0x50(%rdi)\n\tmovdqa %xmm0, 0x60(%rdi)\n\tmovdqa %xmm0, 0x70(%rdi)\n\tlea    128(%rdi), %rdi\n\tcmp    $128, %rdx\n\tjl     L(128bytesless_normal)\n\n\tsub    $128, %rdx\n\tmovdqa %xmm0, (%rdi)\n\tmovdqa %xmm0, 0x10(%rdi)\n\tmovdqa %xmm0, 0x20(%rdi)\n\tmovdqa %xmm0, 0x30(%rdi)\n\tmovdqa %xmm0, 0x40(%rdi)\n\tmovdqa %xmm0, 0x50(%rdi)\n\tmovdqa %xmm0, 0x60(%rdi)\n\tmovdqa %xmm0, 0x70(%rdi)\n\tlea    128(%rdi), %rdi\n\tcmp    $128, %rdx\n\tjge    L(128bytesormore_normal)\n\nL(128bytesless_normal):\n\tadd    %rdx, %rdi\n\tshr    $1, %rdx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)\n\n\tALIGN (4)\nL(128bytesormore_nt):\n\tsub    $128, %rdx\n\tmovntdq %xmm0, (%rdi)\n\tmovntdq %xmm0, 0x10(%rdi)\n\tmovntdq %xmm0, 0x20(%rdi)\n\tmovntdq %xmm0, 0x30(%rdi)\n\tmovntdq %xmm0, 0x40(%rdi)\n\tmovntdq %xmm0, 0x50(%rdi)\n\tmovntdq %xmm0, 0x60(%rdi)\n\tmovntdq %xmm0, 0x70(%rdi)\n\tlea    128(%rdi), %rdi\n\tcmp    $128, %rdx\n\tjge    L(128bytesormore_nt)\n\n\tsfence\n\tadd    %rdx, %rdi\n\tshr    $1, %rdx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)\n\n\t.pushsection .rodata.sse2,\"a\",@progbits\n\tALIGN (2)\nL(table_16_128bytes):\n\t.int\tJMPTBL (L(aligned_16_0bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_2bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_4bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_6bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_8bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_10bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_12bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_14bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_16bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_18bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_20bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_22bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_24bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_26bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_28bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_30bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_32bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_34bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_36bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_38bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_40bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_42bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_44bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_46bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_48bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_50bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_52bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_54bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_56bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_58bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_60bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_62bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_64bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_66bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_68bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_70bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_72bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_74bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_76bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_78bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_80bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_82bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_84bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_86bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_88bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_90bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_92bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_94bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_96bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_98bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_100bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_102bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_104bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_106bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_108bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_110bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_112bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_114bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_116bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_118bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_120bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_122bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_124bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_126bytes), L(table_16_128bytes))\n\t.popsection\n\n\tALIGN (4)\nL(aligned_16_112bytes):\n\tmovdqa %xmm0, -112(%rdi)\nL(aligned_16_96bytes):\n\tmovdqa %xmm0, -96(%rdi)\nL(aligned_16_80bytes):\n\tmovdqa %xmm0, -80(%rdi)\nL(aligned_16_64bytes):\n\tmovdqa %xmm0, -64(%rdi)\nL(aligned_16_48bytes):\n\tmovdqa %xmm0, -48(%rdi)\nL(aligned_16_32bytes):\n\tmovdqa %xmm0, -32(%rdi)\nL(aligned_16_16bytes):\n\tmovdqa %xmm0, -16(%rdi)\nL(aligned_16_0bytes):\n\tret\n\n\tALIGN (4)\nL(aligned_16_114bytes):\n\tmovdqa %xmm0, -114(%rdi)\nL(aligned_16_98bytes):\n\tmovdqa %xmm0, -98(%rdi)\nL(aligned_16_82bytes):\n\tmovdqa %xmm0, -82(%rdi)\nL(aligned_16_66bytes):\n\tmovdqa %xmm0, -66(%rdi)\nL(aligned_16_50bytes):\n\tmovdqa %xmm0, -50(%rdi)\nL(aligned_16_34bytes):\n\tmovdqa %xmm0, -34(%rdi)\nL(aligned_16_18bytes):\n\tmovdqa %xmm0, -18(%rdi)\nL(aligned_16_2bytes):\n\tmovw   %cx, -2(%rdi)\n\tret\n\n\tALIGN (4)\nL(aligned_16_116bytes):\n\tmovdqa %xmm0, -116(%rdi)\nL(aligned_16_100bytes):\n\tmovdqa %xmm0, -100(%rdi)\nL(aligned_16_84bytes):\n\tmovdqa %xmm0, -84(%rdi)\nL(aligned_16_68bytes):\n\tmovdqa %xmm0, -68(%rdi)\nL(aligned_16_52bytes):\n\tmovdqa %xmm0, -52(%rdi)\nL(aligned_16_36bytes):\n\tmovdqa %xmm0, -36(%rdi)\nL(aligned_16_20bytes):\n\tmovdqa %xmm0, -20(%rdi)\nL(aligned_16_4bytes):\n\tmovl   %ecx, -4(%rdi)\n\tret\n\n\tALIGN (4)\nL(aligned_16_118bytes):\n\tmovdqa %xmm0, -118(%rdi)\nL(aligned_16_102bytes):\n\tmovdqa %xmm0, -102(%rdi)\nL(aligned_16_86bytes):\n\tmovdqa %xmm0, -86(%rdi)\nL(aligned_16_70bytes):\n\tmovdqa %xmm0, -70(%rdi)\nL(aligned_16_54bytes):\n\tmovdqa %xmm0, -54(%rdi)\nL(aligned_16_38bytes):\n\tmovdqa %xmm0, -38(%rdi)\nL(aligned_16_22bytes):\n\tmovdqa %xmm0, -22(%rdi)\nL(aligned_16_6bytes):\n\tmovl   %ecx, -6(%rdi)\n\tmovw   %cx, -2(%rdi)\n\tret\n\n\tALIGN (4)\nL(aligned_16_120bytes):\n\tmovdqa %xmm0, -120(%rdi)\nL(aligned_16_104bytes):\n\tmovdqa %xmm0, -104(%rdi)\nL(aligned_16_88bytes):\n\tmovdqa %xmm0, -88(%rdi)\nL(aligned_16_72bytes):\n\tmovdqa %xmm0, -72(%rdi)\nL(aligned_16_56bytes):\n\tmovdqa %xmm0, -56(%rdi)\nL(aligned_16_40bytes):\n\tmovdqa %xmm0, -40(%rdi)\nL(aligned_16_24bytes):\n\tmovdqa %xmm0, -24(%rdi)\nL(aligned_16_8bytes):\n\tmovq   %xmm0, -8(%rdi)\n\tret\n\n\tALIGN (4)\nL(aligned_16_122bytes):\n\tmovdqa %xmm0, -122(%rdi)\nL(aligned_16_106bytes):\n\tmovdqa %xmm0, -106(%rdi)\nL(aligned_16_90bytes):\n\tmovdqa %xmm0, -90(%rdi)\nL(aligned_16_74bytes):\n\tmovdqa %xmm0, -74(%rdi)\nL(aligned_16_58bytes):\n\tmovdqa %xmm0, -58(%rdi)\nL(aligned_16_42bytes):\n\tmovdqa %xmm0, -42(%rdi)\nL(aligned_16_26bytes):\n\tmovdqa %xmm0, -26(%rdi)\nL(aligned_16_10bytes):\n\tmovq   %xmm0, -10(%rdi)\n\tmovw   %cx, -2(%rdi)\n\tret\n\n\tALIGN (4)\nL(aligned_16_124bytes):\n\tmovdqa %xmm0, -124(%rdi)\nL(aligned_16_108bytes):\n\tmovdqa %xmm0, -108(%rdi)\nL(aligned_16_92bytes):\n\tmovdqa %xmm0, -92(%rdi)\nL(aligned_16_76bytes):\n\tmovdqa %xmm0, -76(%rdi)\nL(aligned_16_60bytes):\n\tmovdqa %xmm0, -60(%rdi)\nL(aligned_16_44bytes):\n\tmovdqa %xmm0, -44(%rdi)\nL(aligned_16_28bytes):\n\tmovdqa %xmm0, -28(%rdi)\nL(aligned_16_12bytes):\n\tmovq   %xmm0, -12(%rdi)\n\tmovl   %ecx, -4(%rdi)\n\tret\n\n\tALIGN (4)\nL(aligned_16_126bytes):\n\tmovdqa %xmm0, -126(%rdi)\nL(aligned_16_110bytes):\n\tmovdqa %xmm0, -110(%rdi)\nL(aligned_16_94bytes):\n\tmovdqa %xmm0, -94(%rdi)\nL(aligned_16_78bytes):\n\tmovdqa %xmm0, -78(%rdi)\nL(aligned_16_62bytes):\n\tmovdqa %xmm0, -62(%rdi)\nL(aligned_16_46bytes):\n\tmovdqa %xmm0, -46(%rdi)\nL(aligned_16_30bytes):\n\tmovdqa %xmm0, -30(%rdi)\nL(aligned_16_14bytes):\n\tmovq   %xmm0, -14(%rdi)\n\tmovl   %ecx, -6(%rdi)\n\tmovw   %cx, -2(%rdi)\n\tret\n\nEND (MEMSET)\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/arch-x86_64/android_memset32.S",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"cache.h\"\n\n#ifndef MEMSET\n# define MEMSET\t\tandroid_memset32\n#endif\n\n#ifndef L\n# define L(label)\t.L##label\n#endif\n\n#ifndef ALIGN\n# define ALIGN(n)\t.p2align n\n#endif\n\n#ifndef cfi_startproc\n# define cfi_startproc\t\t\t.cfi_startproc\n#endif\n\n#ifndef cfi_endproc\n# define cfi_endproc\t\t\t.cfi_endproc\n#endif\n\n#ifndef ENTRY\n# define ENTRY(name)\t\t\t\\\n\t.type name,  @function; \t\\\n\t.globl name;\t\t\t\\\n\t.p2align 4;\t\t\t\\\nname:\t\t\t\t\t\\\n\tcfi_startproc\n#endif\n\n#ifndef END\n# define END(name)\t\t\t\\\n\tcfi_endproc;\t\t\t\\\n\t.size name, .-name\n#endif\n\n#define JMPTBL(I, B)\tI - B\n\n/* Branch to an entry in a jump table.  TABLE is a jump table with\n   relative offsets.  INDEX is a register contains the index into the\n   jump table.  SCALE is the scale of INDEX.  */\n#define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \\\n\tlea    TABLE(%rip), %r11;\t\t\t\t\t\t\\\n\tmovslq (%r11, INDEX, SCALE), INDEX;\t\t\t\t\\\n\tlea    (%r11, INDEX), INDEX;\t\t\t\t\t\\\n\tjmp    *INDEX\n\n\t.section .text.sse2,\"ax\",@progbits\n\tALIGN (4)\nENTRY (MEMSET)\t// Address in rdi\n\tshr    $2, %rdx\t\t\t// Count in rdx\n\tmovl   %esi, %ecx\t\t// Pattern in ecx\n\n\tcmp    $16, %rdx\n\tjae    L(16dbwordsormore)\n\nL(write_less16dbwords):\n\tlea    (%rdi, %rdx, 4), %rdi\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_less16dbwords), %rdx, 4)\n\n\t.pushsection .rodata.sse2,\"a\",@progbits\n\tALIGN (2)\nL(table_less16dbwords):\n\t.int\tJMPTBL (L(write_0dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_1dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_2dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_3dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_4dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_5dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_6dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_7dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_8dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_9dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_10dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_11dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_12dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_13dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_14dbwords), L(table_less16dbwords))\n\t.int\tJMPTBL (L(write_15dbwords), L(table_less16dbwords))\n\t.popsection\n\n\tALIGN (4)\nL(write_15dbwords):\n\tmovl   %ecx, -60(%rdi)\nL(write_14dbwords):\n\tmovl   %ecx, -56(%rdi)\nL(write_13dbwords):\n\tmovl   %ecx, -52(%rdi)\nL(write_12dbwords):\n\tmovl   %ecx, -48(%rdi)\nL(write_11dbwords):\n\tmovl   %ecx, -44(%rdi)\nL(write_10dbwords):\n\tmovl   %ecx, -40(%rdi)\nL(write_9dbwords):\n\tmovl   %ecx, -36(%rdi)\nL(write_8dbwords):\n\tmovl   %ecx, -32(%rdi)\nL(write_7dbwords):\n\tmovl   %ecx, -28(%rdi)\nL(write_6dbwords):\n\tmovl   %ecx, -24(%rdi)\nL(write_5dbwords):\n\tmovl   %ecx, -20(%rdi)\nL(write_4dbwords):\n\tmovl   %ecx, -16(%rdi)\nL(write_3dbwords):\n\tmovl   %ecx, -12(%rdi)\nL(write_2dbwords):\n\tmovl   %ecx, -8(%rdi)\nL(write_1dbwords):\n\tmovl   %ecx, -4(%rdi)\nL(write_0dbwords):\n\tret\n\n\tALIGN (4)\nL(16dbwordsormore):\n\ttest   $3, %edi\n\tjz     L(aligned4bytes)\n\tmov    %ecx, (%rdi)\n\tmov    %ecx, -4(%rdi, %rdx, 4)\n\tsub    $1, %rdx\n\trol    $24, %ecx\n\tadd    $1, %rdi\n\ttest   $3, %edi\n\tjz     L(aligned4bytes)\n\tror    $8, %ecx\n\tadd    $1, %rdi\n\ttest   $3, %edi\n\tjz     L(aligned4bytes)\n\tror    $8, %ecx\n\tadd    $1, %rdi\nL(aligned4bytes):\n\tshl    $2, %rdx\n\n\t/* Fill xmm0 with the pattern.  */\n\tmovd   %ecx, %xmm0\n\tpshufd $0, %xmm0, %xmm0\n\n\ttestl  $0xf, %edi\n\tjz     L(aligned_16)\n/* RDX > 32 and RDI is not 16 byte aligned.  */\n\tmovdqu %xmm0, (%rdi)\n\tmov    %rdi, %rsi\n\tand    $-16, %rdi\n\tadd    $16, %rdi\n\tsub    %rdi, %rsi\n\tadd    %rsi, %rdx\n\n\tALIGN (4)\nL(aligned_16):\n\tcmp    $128, %rdx\n\tjge    L(128bytesormore)\n\nL(aligned_16_less128bytes):\n\tadd    %rdx, %rdi\n\tshr    $2, %rdx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)\n\n\tALIGN (4)\nL(128bytesormore):\n\tcmp    $SHARED_CACHE_SIZE, %rdx\n\tjg     L(128bytesormore_nt)\n\nL(128bytesormore_normal):\n\tsub    $128, %rdx\n\tmovdqa %xmm0, (%rdi)\n\tmovdqa %xmm0, 0x10(%rdi)\n\tmovdqa %xmm0, 0x20(%rdi)\n\tmovdqa %xmm0, 0x30(%rdi)\n\tmovdqa %xmm0, 0x40(%rdi)\n\tmovdqa %xmm0, 0x50(%rdi)\n\tmovdqa %xmm0, 0x60(%rdi)\n\tmovdqa %xmm0, 0x70(%rdi)\n\tlea    128(%rdi), %rdi\n\tcmp    $128, %rdx\n\tjl     L(128bytesless_normal)\n\n\tsub    $128, %rdx\n\tmovdqa %xmm0, (%rdi)\n\tmovdqa %xmm0, 0x10(%rdi)\n\tmovdqa %xmm0, 0x20(%rdi)\n\tmovdqa %xmm0, 0x30(%rdi)\n\tmovdqa %xmm0, 0x40(%rdi)\n\tmovdqa %xmm0, 0x50(%rdi)\n\tmovdqa %xmm0, 0x60(%rdi)\n\tmovdqa %xmm0, 0x70(%rdi)\n\tlea    128(%rdi), %rdi\n\tcmp    $128, %rdx\n\tjl     L(128bytesless_normal)\n\n\tsub    $128, %rdx\n\tmovdqa %xmm0, (%rdi)\n\tmovdqa %xmm0, 0x10(%rdi)\n\tmovdqa %xmm0, 0x20(%rdi)\n\tmovdqa %xmm0, 0x30(%rdi)\n\tmovdqa %xmm0, 0x40(%rdi)\n\tmovdqa %xmm0, 0x50(%rdi)\n\tmovdqa %xmm0, 0x60(%rdi)\n\tmovdqa %xmm0, 0x70(%rdi)\n\tlea    128(%rdi), %rdi\n\tcmp    $128, %rdx\n\tjl     L(128bytesless_normal)\n\n\tsub    $128, %rdx\n\tmovdqa %xmm0, (%rdi)\n\tmovdqa %xmm0, 0x10(%rdi)\n\tmovdqa %xmm0, 0x20(%rdi)\n\tmovdqa %xmm0, 0x30(%rdi)\n\tmovdqa %xmm0, 0x40(%rdi)\n\tmovdqa %xmm0, 0x50(%rdi)\n\tmovdqa %xmm0, 0x60(%rdi)\n\tmovdqa %xmm0, 0x70(%rdi)\n\tlea    128(%rdi), %rdi\n\tcmp    $128, %rdx\n\tjge    L(128bytesormore_normal)\n\nL(128bytesless_normal):\n\tadd    %rdx, %rdi\n\tshr    $2, %rdx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)\n\n\tALIGN (4)\nL(128bytesormore_nt):\n\tsub    $128, %rdx\n\tmovntdq %xmm0, (%rdi)\n\tmovntdq %xmm0, 0x10(%rdi)\n\tmovntdq %xmm0, 0x20(%rdi)\n\tmovntdq %xmm0, 0x30(%rdi)\n\tmovntdq %xmm0, 0x40(%rdi)\n\tmovntdq %xmm0, 0x50(%rdi)\n\tmovntdq %xmm0, 0x60(%rdi)\n\tmovntdq %xmm0, 0x70(%rdi)\n\tlea    128(%rdi), %rdi\n\tcmp    $128, %rdx\n\tjge    L(128bytesormore_nt)\n\n\tsfence\n\tadd    %rdx, %rdi\n\tshr    $2, %rdx\n\tBRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)\n\n\t.pushsection .rodata.sse2,\"a\",@progbits\n\tALIGN (2)\nL(table_16_128bytes):\n\t.int\tJMPTBL (L(aligned_16_0bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_4bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_8bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_12bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_16bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_20bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_24bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_28bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_32bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_36bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_40bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_44bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_48bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_52bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_56bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_60bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_64bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_68bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_72bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_76bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_80bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_84bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_88bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_92bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_96bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_100bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_104bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_108bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_112bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_116bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_120bytes), L(table_16_128bytes))\n\t.int\tJMPTBL (L(aligned_16_124bytes), L(table_16_128bytes))\n\t.popsection\n\n\tALIGN (4)\nL(aligned_16_112bytes):\n\tmovdqa\t%xmm0, -112(%rdi)\nL(aligned_16_96bytes):\n\tmovdqa\t%xmm0, -96(%rdi)\nL(aligned_16_80bytes):\n\tmovdqa\t%xmm0, -80(%rdi)\nL(aligned_16_64bytes):\n\tmovdqa\t%xmm0, -64(%rdi)\nL(aligned_16_48bytes):\n\tmovdqa\t%xmm0, -48(%rdi)\nL(aligned_16_32bytes):\n\tmovdqa\t%xmm0, -32(%rdi)\nL(aligned_16_16bytes):\n\tmovdqa\t%xmm0, -16(%rdi)\nL(aligned_16_0bytes):\n\tret\n\n\tALIGN (4)\nL(aligned_16_116bytes):\n\tmovdqa\t%xmm0, -116(%rdi)\nL(aligned_16_100bytes):\n\tmovdqa\t%xmm0, -100(%rdi)\nL(aligned_16_84bytes):\n\tmovdqa\t%xmm0, -84(%rdi)\nL(aligned_16_68bytes):\n\tmovdqa\t%xmm0, -68(%rdi)\nL(aligned_16_52bytes):\n\tmovdqa\t%xmm0, -52(%rdi)\nL(aligned_16_36bytes):\n\tmovdqa\t%xmm0, -36(%rdi)\nL(aligned_16_20bytes):\n\tmovdqa\t%xmm0, -20(%rdi)\nL(aligned_16_4bytes):\n\tmovl\t%ecx, -4(%rdi)\n\tret\n\n\tALIGN (4)\nL(aligned_16_120bytes):\n\tmovdqa\t%xmm0, -120(%rdi)\nL(aligned_16_104bytes):\n\tmovdqa\t%xmm0, -104(%rdi)\nL(aligned_16_88bytes):\n\tmovdqa\t%xmm0, -88(%rdi)\nL(aligned_16_72bytes):\n\tmovdqa\t%xmm0, -72(%rdi)\nL(aligned_16_56bytes):\n\tmovdqa\t%xmm0, -56(%rdi)\nL(aligned_16_40bytes):\n\tmovdqa\t%xmm0, -40(%rdi)\nL(aligned_16_24bytes):\n\tmovdqa\t%xmm0, -24(%rdi)\nL(aligned_16_8bytes):\n\tmovq\t%xmm0, -8(%rdi)\n\tret\n\n\tALIGN (4)\nL(aligned_16_124bytes):\n\tmovdqa\t%xmm0, -124(%rdi)\nL(aligned_16_108bytes):\n\tmovdqa\t%xmm0, -108(%rdi)\nL(aligned_16_92bytes):\n\tmovdqa\t%xmm0, -92(%rdi)\nL(aligned_16_76bytes):\n\tmovdqa\t%xmm0, -76(%rdi)\nL(aligned_16_60bytes):\n\tmovdqa\t%xmm0, -60(%rdi)\nL(aligned_16_44bytes):\n\tmovdqa\t%xmm0, -44(%rdi)\nL(aligned_16_28bytes):\n\tmovdqa\t%xmm0, -28(%rdi)\nL(aligned_16_12bytes):\n\tmovq\t%xmm0, -12(%rdi)\n\tmovl\t%ecx, -4(%rdi)\n\tret\n\nEND (MEMSET)\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/arch-x86_64/cache.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* Values are optimized for Silvermont */\n#define SHARED_CACHE_SIZE\t(1024*1024)\t\t\t/* Silvermont L2 Cache */\n#define DATA_CACHE_SIZE\t\t(24*1024)\t\t\t/* Silvermont L1 Data Cache */\n\n#define SHARED_CACHE_SIZE_HALF\t(SHARED_CACHE_SIZE / 2)\n#define DATA_CACHE_SIZE_HALF\t(DATA_CACHE_SIZE / 2)\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/ashmem-dev.c",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * Implementation of the user-space ashmem API for devices, which have our\n * ashmem-enabled kernel. See ashmem-sim.c for the \"fake\" tmp-based version,\n * used by the simulator.\n */\n#define LOG_TAG \"ashmem\"\n\n#include <errno.h>\n#include <fcntl.h>\n#include <pthread.h>\n#include <string.h>\n#include <sys/ioctl.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#include <linux/ashmem.h>\n\n#include <cutils/ashmem.h>\n#include <log/log.h>\n\n#define ASHMEM_DEVICE \"/dev/ashmem\"\n\n/* ashmem identity */\nstatic dev_t __ashmem_rdev;\n/*\n * If we trigger a signal handler in the middle of locked activity and the\n * signal handler calls ashmem, we could get into a deadlock state.\n */\nstatic pthread_mutex_t __ashmem_lock = PTHREAD_MUTEX_INITIALIZER;\n\n/* logistics of getting file descriptor for ashmem */\nstatic int __ashmem_open_locked()\n{\n    int ret;\n    struct stat st;\n\n    int fd = TEMP_FAILURE_RETRY(open(ASHMEM_DEVICE, O_RDWR));\n    if (fd < 0) {\n        return fd;\n    }\n\n    ret = TEMP_FAILURE_RETRY(fstat(fd, &st));\n    if (ret < 0) {\n        int save_errno = errno;\n        close(fd);\n        errno = save_errno;\n        return ret;\n    }\n    if (!S_ISCHR(st.st_mode) || !st.st_rdev) {\n        close(fd);\n        errno = ENOTTY;\n        return -1;\n    }\n\n    __ashmem_rdev = st.st_rdev;\n    return fd;\n}\n\nstatic int __ashmem_open()\n{\n    int fd;\n\n    pthread_mutex_lock(&__ashmem_lock);\n    fd = __ashmem_open_locked();\n    pthread_mutex_unlock(&__ashmem_lock);\n\n    return fd;\n}\n\n/* Make sure file descriptor references ashmem, negative number means false */\nstatic int __ashmem_is_ashmem(int fd)\n{\n    dev_t rdev;\n    struct stat st;\n\n    if (TEMP_FAILURE_RETRY(fstat(fd, &st)) < 0) {\n        return -1;\n    }\n\n    rdev = 0; /* Too much complexity to sniff __ashmem_rdev */\n    if (S_ISCHR(st.st_mode) && st.st_rdev) {\n        pthread_mutex_lock(&__ashmem_lock);\n        rdev = __ashmem_rdev;\n        if (rdev) {\n            pthread_mutex_unlock(&__ashmem_lock);\n        } else {\n            int fd = __ashmem_open_locked();\n            if (fd < 0) {\n                pthread_mutex_unlock(&__ashmem_lock);\n                return -1;\n            }\n            rdev = __ashmem_rdev;\n            pthread_mutex_unlock(&__ashmem_lock);\n\n            close(fd);\n        }\n\n        if (st.st_rdev == rdev) {\n            return 0;\n        }\n    }\n\n    if (rdev) {\n        LOG_ALWAYS_FATAL(\"illegal fd=%d mode=0%o rdev=%d:%d expected 0%o %d:%d\",\n          fd, st.st_mode, major(st.st_rdev), minor(st.st_rdev),\n          S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IRGRP,\n          major(rdev), minor(rdev));\n    } else {\n        LOG_ALWAYS_FATAL(\"illegal fd=%d mode=0%o rdev=%d:%d expected 0%o\",\n          fd, st.st_mode, major(st.st_rdev), minor(st.st_rdev),\n          S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IRGRP);\n    }\n    /* NOTREACHED */\n\n    errno = ENOTTY;\n    return -1;\n}\n\n/*\n * ashmem_create_region - creates a new ashmem region and returns the file\n * descriptor, or <0 on error\n *\n * `name' is an optional label to give the region (visible in /proc/pid/maps)\n * `size' is the size of the region, in page-aligned bytes\n */\nint ashmem_create_region(const char *name, size_t size)\n{\n    int ret, save_errno;\n\n    int fd = __ashmem_open();\n    if (fd < 0) {\n        return fd;\n    }\n\n    if (name) {\n        char buf[ASHMEM_NAME_LEN] = {0};\n\n        strlcpy(buf, name, sizeof(buf));\n        ret = TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_NAME, buf));\n        if (ret < 0) {\n            goto error;\n        }\n    }\n\n    ret = TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_SIZE, size));\n    if (ret < 0) {\n        goto error;\n    }\n\n    return fd;\n\nerror:\n    save_errno = errno;\n    close(fd);\n    errno = save_errno;\n    return ret;\n}\n\nint ashmem_set_prot_region(int fd, int prot)\n{\n    int ret = __ashmem_is_ashmem(fd);\n    if (ret < 0) {\n        return ret;\n    }\n\n    return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_PROT_MASK, prot));\n}\n\nint ashmem_pin_region(int fd, size_t offset, size_t len)\n{\n    struct ashmem_pin pin = { offset, len };\n\n    int ret = __ashmem_is_ashmem(fd);\n    if (ret < 0) {\n        return ret;\n    }\n\n    return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_PIN, &pin));\n}\n\nint ashmem_unpin_region(int fd, size_t offset, size_t len)\n{\n    struct ashmem_pin pin = { offset, len };\n\n    int ret = __ashmem_is_ashmem(fd);\n    if (ret < 0) {\n        return ret;\n    }\n\n    return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_UNPIN, &pin));\n}\n\nint ashmem_get_size_region(int fd)\n{\n    int ret = __ashmem_is_ashmem(fd);\n    if (ret < 0) {\n        return ret;\n    }\n\n    return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_GET_SIZE, NULL));\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/ashmem-host.c",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * Implementation of the user-space ashmem API for the simulator, which lacks\n * an ashmem-enabled kernel. See ashmem-dev.c for the real ashmem-based version.\n */\n\n#include <errno.h>\n#include <fcntl.h>\n#include <limits.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <time.h>\n#include <unistd.h>\n\n#include <cutils/ashmem.h>\n#include <utils/Compat.h>\n\n#ifndef __unused\n#define __unused __attribute__((__unused__))\n#endif\n\nint ashmem_create_region(const char *ignored __unused, size_t size)\n{\n    char template[PATH_MAX];\n    snprintf(template, sizeof(template), \"/tmp/android-ashmem-%d-XXXXXXXXX\", getpid());\n    int fd = mkstemp(template);\n    if (fd == -1) return -1;\n\n    unlink(template);\n\n    if (TEMP_FAILURE_RETRY(ftruncate(fd, size)) == -1) {\n      close(fd);\n      return -1;\n    }\n\n    return fd;\n}\n\nint ashmem_set_prot_region(int fd __unused, int prot __unused)\n{\n    return 0;\n}\n\nint ashmem_pin_region(int fd __unused, size_t offset __unused, size_t len __unused)\n{\n    return ASHMEM_NOT_PURGED;\n}\n\nint ashmem_unpin_region(int fd __unused, size_t offset __unused, size_t len __unused)\n{\n    return ASHMEM_IS_UNPINNED;\n}\n\nint ashmem_get_size_region(int fd)\n{\n    struct stat buf;\n    int result = fstat(fd, &buf);\n    if (result == -1) {\n        return -1;\n    }\n\n    /*\n     * Check if this is an \"ashmem\" region.\n     * TODO: This is very hacky, and can easily break.\n     * We need some reliable indicator.\n     */\n    if (!(buf.st_nlink == 0 && S_ISREG(buf.st_mode))) {\n        errno = ENOTTY;\n        return -1;\n    }\n\n    return buf.st_size;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/atomic.c",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * Generate non-inlined versions of android_atomic functions.\n * Nobody should be using these, but some binary blobs currently (late 2014)\n * are.\n * If you read this in 2015 or later, please try to delete this file.\n */\n\n#define ANDROID_ATOMIC_INLINE\n\n#include <cutils/atomic.h>\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/canned_fs_config.c",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <inttypes.h>\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n#include <limits.h>\n#include <stdlib.h>\n\n#include <private/android_filesystem_config.h>\n#include <private/canned_fs_config.h>\n\ntypedef struct {\n\tconst char* path;\n\tunsigned uid;\n\tunsigned gid;\n\tunsigned mode;\n\tuint64_t capabilities;\n} Path;\n\nstatic Path* canned_data = NULL;\nstatic int canned_alloc = 0;\nstatic int canned_used = 0;\n\nstatic int path_compare(const void* a, const void* b) {\n\treturn strcmp(((Path*)a)->path, ((Path*)b)->path);\n}\n\nint load_canned_fs_config(const char* fn) {\n\tFILE* f = fopen(fn, \"r\");\n\tif (f == NULL) {\n\t\tfprintf(stderr, \"failed to open %s: %s\\n\", fn, strerror(errno));\n\t\treturn -1;\n\t}\n\n\tchar line[PATH_MAX + 200];\n\twhile (fgets(line, sizeof(line), f)) {\n\t\twhile (canned_used >= canned_alloc) {\n\t\t\tcanned_alloc = (canned_alloc+1) * 2;\n\t\t\tcanned_data = (Path*) realloc(canned_data, canned_alloc * sizeof(Path));\n\t\t}\n\t\tPath* p = canned_data + canned_used;\n\t\tp->path = strdup(strtok(line, \" \"));\n\t\tp->uid = atoi(strtok(NULL, \" \"));\n\t\tp->gid = atoi(strtok(NULL, \" \"));\n\t\tp->mode = strtol(strtok(NULL, \" \"), NULL, 8);   // mode is in octal\n\t\tp->capabilities = 0;\n\n\t\tchar* token = NULL;\n\t\tdo {\n\t\t\ttoken = strtok(NULL, \" \");\n\t\t\tif (token && strncmp(token, \"capabilities=\", 13) == 0) {\n\t\t\t\tp->capabilities = strtoll(token+13, NULL, 0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} while (token);\n\n\t\tcanned_used++;\n\t}\n\n\tfclose(f);\n\n\tqsort(canned_data, canned_used, sizeof(Path), path_compare);\n\tprintf(\"loaded %d fs_config entries\\n\", canned_used);\n\n\treturn 0;\n}\n\nstatic const int kDebugCannedFsConfig = 0;\n\nvoid canned_fs_config(const char* path, int dir, const char* target_out_path,\n\t\t\t\t\t  unsigned* uid, unsigned* gid, unsigned* mode, uint64_t* capabilities) {\n\tPath key;\n    key.path = path;\n    if (path[0] == '/')\n        key.path++;   // canned paths lack the leading '/'\n\tPath* p = (Path*) bsearch(&key, canned_data, canned_used, sizeof(Path), path_compare);\n\tif (p == NULL) {\n\t\tfprintf(stderr, \"failed to find [%s] in canned fs_config\\n\", path);\n\t\texit(1);\n\t}\n\t*uid = p->uid;\n\t*gid = p->gid;\n\t*mode = p->mode;\n\t*capabilities = p->capabilities;\n\n\tif (kDebugCannedFsConfig) {\n\t\t// for debugging, run the built-in fs_config and compare the results.\n\n\t\tunsigned c_uid, c_gid, c_mode;\n\t\tuint64_t c_capabilities;\n\t\tfs_config(path, dir, target_out_path, &c_uid, &c_gid, &c_mode, &c_capabilities);\n\n\t\tif (c_uid != *uid) printf(\"%s uid %d %d\\n\", path, *uid, c_uid);\n\t\tif (c_gid != *gid) printf(\"%s gid %d %d\\n\", path, *gid, c_gid);\n\t\tif (c_mode != *mode) printf(\"%s mode 0%o 0%o\\n\", path, *mode, c_mode);\n\t\tif (c_capabilities != *capabilities)\n\t\t\tprintf(\"%s capabilities %\" PRIx64 \" %\" PRIx64 \"\\n\",\n\t\t\t\tpath,\n\t\t\t\t*capabilities,\n\t\t\t\tc_capabilities);\n        }\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/config_utils.c",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <string.h>\n#include <ctype.h>\n#include <stdlib.h>\n#include <fcntl.h>\n#include <unistd.h>\n\n#include <cutils/config_utils.h>\n#include <cutils/misc.h>\n\ncnode* config_node(const char *name, const char *value)\n{\n    cnode *node;\n\n    node = calloc(sizeof(cnode), 1);\n    if(node) {\n        node->name = name ? name : \"\";\n        node->value = value ? value : \"\";\n    }\n\n    return node;\n}\n\ncnode* config_find(cnode *root, const char *name)\n{\n    cnode *node, *match = NULL;\n\n    /* we walk the whole list, as we need to return the last (newest) entry */\n    for(node = root->first_child; node; node = node->next)\n        if(!strcmp(node->name, name))\n            match = node;\n\n    return match;\n}\n\nstatic cnode* _config_create(cnode *root, const char *name)\n{\n    cnode *node;\n\n    node = config_node(name, NULL);\n\n    if(root->last_child)\n        root->last_child->next = node;\n    else\n        root->first_child = node;\n\n    root->last_child = node;\n\n    return node;\n}\n\nint config_bool(cnode *root, const char *name, int _default)\n{\n    cnode *node;\n        \n    node = config_find(root, name);\n    if(!node)\n        return _default;\n\n    switch(node->value[0]) {\n    case 'y':\n    case 'Y':\n    case '1':\n        return 1;\n    default:\n        return 0;\n    }\n}\n\nconst char* config_str(cnode *root, const char *name, const char *_default)\n{\n    cnode *node;\n\n    node = config_find(root, name);\n    if(!node)\n        return _default;\n    return node->value;\n}\n\nvoid config_set(cnode *root, const char *name, const char *value)\n{\n    cnode *node;\n\n    node = config_find(root, name);\n    if(node)\n        node->value = value;\n    else {\n        node = _config_create(root, name);\n        node->value = value;\n    }\n}\n\n#define T_EOF 0\n#define T_TEXT 1\n#define T_DOT 2\n#define T_OBRACE 3\n#define T_CBRACE 4\n\ntypedef struct\n{\n    char *data;\n    char *text;\n    int len;\n    char next;\n} cstate;\n\nstatic int _lex(cstate *cs, int value)\n{\n    char c;\n    char *s;\n    char *data;\n\n    data = cs->data;\n\n    if(cs->next != 0) {\n        c = cs->next;\n        cs->next = 0;\n        goto got_c;\n    }\n\nrestart:\n    for(;;) {\n        c = *data++;\n    got_c:\n        if(isspace(c))\n            continue;\n\n        switch(c) {\n        case 0:\n            return T_EOF;\n\n        case '#':\n            for(;;) {\n                switch(*data) {\n                case 0:\n                    cs->data = data;\n                    return T_EOF;\n                case '\\n':\n                    cs->data = data + 1;\n                    goto restart;\n                default:\n                    data++;\n                }\n            }\n            break;\n            \n        case '.':\n            cs->data = data;\n            return T_DOT;\n\n        case '{':\n            cs->data = data;\n            return T_OBRACE;\n\n        case '}':\n            cs->data = data;\n            return T_CBRACE;\n\n        default:\n            s = data - 1;\n\n            if(value) {\n                for(;;) {\n                    if(*data == 0) {\n                        cs->data = data;\n                        break;\n                    }\n                    if(*data == '\\n') {\n                        cs->data = data + 1;\n                        *data-- = 0;\n                        break;\n                    }\n                    data++;\n                }\n\n                    /* strip trailing whitespace */\n                while(data > s){\n                    if(!isspace(*data)) break;\n                    *data-- = 0;\n                }\n\n                goto got_text;                \n            } else {\n                for(;;) {\n                    if(isspace(*data)) {\n                        *data = 0;\n                        cs->data = data + 1;\n                        goto got_text;\n                    }\n                    switch(*data) {\n                    case 0:\n                        cs->data = data;\n                        goto got_text;\n                    case '.':\n                    case '{':\n                    case '}':\n                        cs->next = *data;\n                        *data = 0;\n                        cs->data = data + 1;\n                        goto got_text;\n                    default:\n                        data++;\n                    }\n                }\n            }\n        }\n    }\n\ngot_text:\n    cs->text = s;\n    return T_TEXT;\n}\n\n#if 0\nchar *TOKENNAMES[] = { \"EOF\", \"TEXT\", \"DOT\", \"OBRACE\", \"CBRACE\" };\n\nstatic int lex(cstate *cs, int value)\n{\n    int tok = _lex(cs, value);\n    printf(\"TOKEN(%d) %s %s\\n\", value, TOKENNAMES[tok],\n           tok == T_TEXT ? cs->text : \"\");\n    return tok;\n}\n#else\n#define lex(cs,v) _lex(cs,v)\n#endif\n\nstatic int parse_expr(cstate *cs, cnode *node);\n\nstatic int parse_block(cstate *cs, cnode *node)\n{\n    for(;;){\n        switch(lex(cs, 0)){\n        case T_TEXT:\n            if(parse_expr(cs, node)) return -1;\n            continue;\n\n        case T_CBRACE:\n            return 0;\n\n        default:\n            return -1;\n        }\n    }\n}\n\nstatic int parse_expr(cstate *cs, cnode *root)\n{\n    cnode *node;\n\n        /* last token was T_TEXT */\n    node = config_find(root, cs->text);\n    if(!node || *node->value)\n        node = _config_create(root, cs->text);\n\n    for(;;) {\n        switch(lex(cs, 1)) {\n        case T_DOT:\n            if(lex(cs, 0) != T_TEXT)\n                return -1;\n            node = _config_create(node, cs->text);\n            continue;\n\n        case T_TEXT:\n            node->value = cs->text;\n            return 0;\n\n        case T_OBRACE:\n            return parse_block(cs, node);\n\n        default:\n            return -1;\n        }\n    }\n}\n\nvoid config_load(cnode *root, char *data)\n{\n    if(data != 0) {\n        cstate cs;\n        cs.data = data;\n        cs.next = 0;\n\n        for(;;) {\n            switch(lex(&cs, 0)) {\n            case T_TEXT:\n                if(parse_expr(&cs, root))\n                    return;\n                break;\n            default:\n                return;\n            }\n        }\n    }\n}\n\nvoid config_load_file(cnode *root, const char *fn)\n{\n    char *data;\n    data = load_file(fn, 0);\n    config_load(root, data);\n}\n\nvoid config_free(cnode *root)\n{\n    cnode *cur = root->first_child;\n\n    while (cur) {\n        cnode *prev = cur;\n        config_free(cur);\n        cur = cur->next;\n        free(prev);\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/debugger.c",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <stdbool.h>\n#include <fcntl.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <unistd.h>\n\n#include <cutils/debugger.h>\n#include <cutils/sockets.h>\n\n#define LOG_TAG \"DEBUG\"\n#include <log/log.h>\n\nstatic int send_request(int sock_fd, void* msg_ptr, size_t msg_len) {\n  int result = 0;\n  if (TEMP_FAILURE_RETRY(write(sock_fd, msg_ptr, msg_len)) != (ssize_t) msg_len) {\n    result = -1;\n  } else {\n    char ack;\n    if (TEMP_FAILURE_RETRY(read(sock_fd, &ack, 1)) != 1) {\n      result = -1;\n    }\n  }\n  return result;\n}\n\nstatic int make_dump_request(debugger_action_t action, pid_t tid, int timeout_secs) {\n  debugger_msg_t msg;\n  memset(&msg, 0, sizeof(msg));\n  msg.tid = tid;\n  msg.action = action;\n\n  int sock_fd = socket_local_client(DEBUGGER_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT,\n      SOCK_STREAM | SOCK_CLOEXEC);\n  if (sock_fd < 0) {\n    return -1;\n  }\n\n  if (timeout_secs > 0) {\n    struct timeval tm;\n    tm.tv_sec = timeout_secs;\n    tm.tv_usec = 0;\n    if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tm, sizeof(tm)) == -1) {\n      ALOGE(\"WARNING: Cannot set receive timeout value on socket: %s\", strerror(errno));\n    }\n\n    if (setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, &tm, sizeof(tm)) == -1) {\n      ALOGE(\"WARNING: Cannot set send timeout value on socket: %s\", strerror(errno));\n    }\n  }\n\n  if (send_request(sock_fd, &msg, sizeof(msg)) < 0) {\n    close(sock_fd);\n    return -1;\n  }\n\n  return sock_fd;\n}\n\nint dump_backtrace_to_file(pid_t tid, int fd) {\n  return dump_backtrace_to_file_timeout(tid, fd, 0);\n}\n\nint dump_backtrace_to_file_timeout(pid_t tid, int fd, int timeout_secs) {\n  int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_BACKTRACE, tid, timeout_secs);\n  if (sock_fd < 0) {\n    return -1;\n  }\n\n  /* Write the data read from the socket to the fd. */\n  int result = 0;\n  char buffer[1024];\n  ssize_t n;\n  while ((n = TEMP_FAILURE_RETRY(read(sock_fd, buffer, sizeof(buffer)))) > 0) {\n    if (TEMP_FAILURE_RETRY(write(fd, buffer, n)) != n) {\n      result = -1;\n      break;\n    }\n  }\n  close(sock_fd);\n  return result;\n}\n\nint dump_tombstone(pid_t tid, char* pathbuf, size_t pathlen) {\n  return dump_tombstone_timeout(tid, pathbuf, pathlen, 0);\n}\n\nint dump_tombstone_timeout(pid_t tid, char* pathbuf, size_t pathlen, int timeout_secs) {\n  int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_TOMBSTONE, tid, timeout_secs);\n  if (sock_fd < 0) {\n    return -1;\n  }\n\n  /* Read the tombstone file name. */\n  char buffer[100]; /* This is larger than the largest tombstone path. */\n  int result = 0;\n  ssize_t n = TEMP_FAILURE_RETRY(read(sock_fd, buffer, sizeof(buffer) - 1));\n  if (n <= 0) {\n    result = -1;\n  } else {\n    if (pathbuf && pathlen) {\n      if (n >= (ssize_t) pathlen) {\n        n = pathlen - 1;\n      }\n      buffer[n] = '\\0';\n      memcpy(pathbuf, buffer, n + 1);\n    }\n  }\n  close(sock_fd);\n  return result;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/dlmalloc_stubs.c",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"log/log.h\"\n\n#define UNUSED __attribute__((__unused__))\n\n/*\n * Stubs for functions defined in bionic/libc/bionic/dlmalloc.c. These\n * are used in host builds, as the host libc will not contain these\n * functions.\n */\nvoid dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*) UNUSED,\n                          void* arg UNUSED)\n{\n  ALOGW(\"Called host unimplemented stub: dlmalloc_inspect_all\");\n}\n\nint dlmalloc_trim(size_t unused UNUSED)\n{\n  ALOGW(\"Called host unimplemented stub: dlmalloc_trim\");\n  return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/fs.c",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"cutils\"\n\n/* These defines are only needed because prebuilt headers are out of date */\n#define __USE_XOPEN2K8 1\n#define _ATFILE_SOURCE 1\n#define _GNU_SOURCE 1\n\n#include <cutils/fs.h>\n#include <cutils/log.h>\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <errno.h>\n#include <string.h>\n#include <limits.h>\n#include <stdlib.h>\n#include <dirent.h>\n\n#define ALL_PERMS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)\n#define BUF_SIZE 64\n\nstatic int fs_prepare_path_impl(const char* path, mode_t mode, uid_t uid, gid_t gid,\n        int allow_fixup, int prepare_as_dir) {\n    // Check if path needs to be created\n    struct stat sb;\n    int create_result = -1;\n    if (TEMP_FAILURE_RETRY(lstat(path, &sb)) == -1) {\n        if (errno == ENOENT) {\n            goto create;\n        } else {\n            ALOGE(\"Failed to lstat(%s): %s\", path, strerror(errno));\n            return -1;\n        }\n    }\n\n    // Exists, verify status\n    int type_ok = prepare_as_dir ? S_ISDIR(sb.st_mode) : S_ISREG(sb.st_mode);\n    if (!type_ok) {\n        ALOGE(\"Not a %s: %s\", (prepare_as_dir ? \"directory\" : \"regular file\"), path);\n        return -1;\n    }\n\n    int owner_match = ((sb.st_uid == uid) && (sb.st_gid == gid));\n    int mode_match = ((sb.st_mode & ALL_PERMS) == mode);\n    if (owner_match && mode_match) {\n        return 0;\n    } else if (allow_fixup) {\n        goto fixup;\n    } else {\n        if (!owner_match) {\n            ALOGE(\"Expected path %s with owner %d:%d but found %d:%d\",\n                    path, uid, gid, sb.st_uid, sb.st_gid);\n            return -1;\n        } else {\n            ALOGW(\"Expected path %s with mode %o but found %o\",\n                    path, mode, (sb.st_mode & ALL_PERMS));\n            return 0;\n        }\n    }\n\ncreate:\n    create_result = prepare_as_dir\n        ? TEMP_FAILURE_RETRY(mkdir(path, mode))\n        : TEMP_FAILURE_RETRY(open(path, O_CREAT | O_CLOEXEC | O_NOFOLLOW | O_RDONLY));\n    if (create_result == -1) {\n        if (errno != EEXIST) {\n            ALOGE(\"Failed to %s(%s): %s\",\n                    (prepare_as_dir ? \"mkdir\" : \"open\"), path, strerror(errno));\n            return -1;\n        }\n    } else if (!prepare_as_dir) {\n        // For regular files we need to make sure we close the descriptor\n        if (close(create_result) == -1) {\n            ALOGW(\"Failed to close file after create %s: %s\", path, strerror(errno));\n        }\n    }\nfixup:\n    if (TEMP_FAILURE_RETRY(chmod(path, mode)) == -1) {\n        ALOGE(\"Failed to chmod(%s, %d): %s\", path, mode, strerror(errno));\n        return -1;\n    }\n    if (TEMP_FAILURE_RETRY(chown(path, uid, gid)) == -1) {\n        ALOGE(\"Failed to chown(%s, %d, %d): %s\", path, uid, gid, strerror(errno));\n        return -1;\n    }\n\n    return 0;\n}\n\nint fs_prepare_dir(const char* path, mode_t mode, uid_t uid, gid_t gid) {\n    return fs_prepare_path_impl(path, mode, uid, gid, /*allow_fixup*/ 1, /*prepare_as_dir*/ 1);\n}\n\nint fs_prepare_dir_strict(const char* path, mode_t mode, uid_t uid, gid_t gid) {\n    return fs_prepare_path_impl(path, mode, uid, gid, /*allow_fixup*/ 0, /*prepare_as_dir*/ 1);\n}\n\nint fs_prepare_file_strict(const char* path, mode_t mode, uid_t uid, gid_t gid) {\n    return fs_prepare_path_impl(path, mode, uid, gid, /*allow_fixup*/ 0, /*prepare_as_dir*/ 0);\n}\n\nint fs_read_atomic_int(const char* path, int* out_value) {\n    int fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY));\n    if (fd == -1) {\n        ALOGE(\"Failed to read %s: %s\", path, strerror(errno));\n        return -1;\n    }\n\n    char buf[BUF_SIZE];\n    if (TEMP_FAILURE_RETRY(read(fd, buf, BUF_SIZE)) == -1) {\n        ALOGE(\"Failed to read %s: %s\", path, strerror(errno));\n        goto fail;\n    }\n    if (sscanf(buf, \"%d\", out_value) != 1) {\n        ALOGE(\"Failed to parse %s: %s\", path, strerror(errno));\n        goto fail;\n    }\n    close(fd);\n    return 0;\n\nfail:\n    close(fd);\n    *out_value = -1;\n    return -1;\n}\n\nint fs_write_atomic_int(const char* path, int value) {\n    char temp[PATH_MAX];\n    if (snprintf(temp, PATH_MAX, \"%s.XXXXXX\", path) >= PATH_MAX) {\n        ALOGE(\"Path too long\");\n        return -1;\n    }\n\n    int fd = TEMP_FAILURE_RETRY(mkstemp(temp));\n    if (fd == -1) {\n        ALOGE(\"Failed to open %s: %s\", temp, strerror(errno));\n        return -1;\n    }\n\n    char buf[BUF_SIZE];\n    int len = snprintf(buf, BUF_SIZE, \"%d\", value) + 1;\n    if (len > BUF_SIZE) {\n        ALOGE(\"Value %d too large: %s\", value, strerror(errno));\n        goto fail;\n    }\n    if (TEMP_FAILURE_RETRY(write(fd, buf, len)) < len) {\n        ALOGE(\"Failed to write %s: %s\", temp, strerror(errno));\n        goto fail;\n    }\n    if (close(fd) == -1) {\n        ALOGE(\"Failed to close %s: %s\", temp, strerror(errno));\n        goto fail_closed;\n    }\n\n    if (rename(temp, path) == -1) {\n        ALOGE(\"Failed to rename %s to %s: %s\", temp, path, strerror(errno));\n        goto fail_closed;\n    }\n\n    return 0;\n\nfail:\n    close(fd);\nfail_closed:\n    unlink(temp);\n    return -1;\n}\n\n#ifndef __APPLE__\n\nint fs_mkdirs(const char* path, mode_t mode) {\n    int res = 0;\n    int fd = 0;\n    struct stat sb;\n    char* buf = strdup(path);\n\n    if (*buf != '/') {\n        ALOGE(\"Relative paths are not allowed: %s\", buf);\n        res = -EINVAL;\n        goto done;\n    }\n\n    if ((fd = open(\"/\", 0)) == -1) {\n        ALOGE(\"Failed to open(/): %s\", strerror(errno));\n        res = -errno;\n        goto done;\n    }\n\n    char* segment = buf + 1;\n    char* p = segment;\n    while (*p != '\\0') {\n        if (*p == '/') {\n            *p = '\\0';\n\n            if (!strcmp(segment, \"..\") || !strcmp(segment, \".\") || !strcmp(segment, \"\")) {\n                ALOGE(\"Invalid path: %s\", buf);\n                res = -EINVAL;\n                goto done_close;\n            }\n\n            if (fstatat(fd, segment, &sb, AT_SYMLINK_NOFOLLOW) != 0) {\n                if (errno == ENOENT) {\n                    /* Nothing there yet; let's create it! */\n                    if (mkdirat(fd, segment, mode) != 0) {\n                        if (errno == EEXIST) {\n                            /* We raced with someone; ignore */\n                        } else {\n                            ALOGE(\"Failed to mkdirat(%s): %s\", buf, strerror(errno));\n                            res = -errno;\n                            goto done_close;\n                        }\n                    }\n                } else {\n                    ALOGE(\"Failed to fstatat(%s): %s\", buf, strerror(errno));\n                    res = -errno;\n                    goto done_close;\n                }\n            } else {\n                if (S_ISLNK(sb.st_mode)) {\n                    ALOGE(\"Symbolic links are not allowed: %s\", buf);\n                    res = -ELOOP;\n                    goto done_close;\n                }\n                if (!S_ISDIR(sb.st_mode)) {\n                    ALOGE(\"Existing segment not a directory: %s\", buf);\n                    res = -ENOTDIR;\n                    goto done_close;\n                }\n            }\n\n            /* Yay, segment is ready for us to step into */\n            int next_fd;\n            if ((next_fd = openat(fd, segment, O_NOFOLLOW | O_CLOEXEC)) == -1) {\n                ALOGE(\"Failed to openat(%s): %s\", buf, strerror(errno));\n                res = -errno;\n                goto done_close;\n            }\n\n            close(fd);\n            fd = next_fd;\n\n            *p = '/';\n            segment = p + 1;\n        }\n        p++;\n    }\n\ndone_close:\n    close(fd);\ndone:\n    free(buf);\n    return res;\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/fs_config.c",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* This file is used to define the properties of the filesystem\n** images generated by build tools (mkbootfs and mkyaffs2image) and\n** by the device side of adb.\n*/\n\n#define LOG_TAG \"fs_config\"\n\n#define _GNU_SOURCE\n\n#include <errno.h>\n#include <fcntl.h>\n#include <stdbool.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n\n#include <log/log.h>\n#include <private/android_filesystem_config.h>\n#include <utils/Compat.h>\n\n#ifndef O_BINARY\n#define O_BINARY 0\n#endif\n\n/* The following structure is stored little endian */\nstruct fs_path_config_from_file {\n    uint16_t len;\n    uint16_t mode;\n    uint16_t uid;\n    uint16_t gid;\n    uint64_t capabilities;\n    char prefix[];\n} __attribute__((__aligned__(sizeof(uint64_t))));\n\n/* My kingdom for <endian.h> */\nstatic inline uint16_t get2LE(const uint8_t* src)\n{\n    return src[0] | (src[1] << 8);\n}\n\nstatic inline uint64_t get8LE(const uint8_t* src)\n{\n    uint32_t low, high;\n\n    low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);\n    high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);\n    return ((uint64_t) high << 32) | (uint64_t) low;\n}\n\n#define ALIGN(x, alignment) ( ((x) + ((alignment) - 1)) & ~((alignment) - 1) )\n\n/* Rules for directories.\n** These rules are applied based on \"first match\", so they\n** should start with the most specific path and work their\n** way up to the root.\n*/\n\nstatic const struct fs_path_config android_dirs[] = {\n    { 00770, AID_SYSTEM, AID_CACHE,  0, \"cache\" },\n    { 00500, AID_ROOT,   AID_ROOT,   0, \"config\" },\n    { 00771, AID_SYSTEM, AID_SYSTEM, 0, \"data/app\" },\n    { 00771, AID_SYSTEM, AID_SYSTEM, 0, \"data/app-private\" },\n    { 00771, AID_SYSTEM, AID_SYSTEM, 0, \"data/app-ephemeral\" },\n    { 00771, AID_ROOT,   AID_ROOT,   0, \"data/dalvik-cache\" },\n    { 00771, AID_SYSTEM, AID_SYSTEM, 0, \"data/data\" },\n    { 00771, AID_SHELL,  AID_SHELL,  0, \"data/local/tmp\" },\n    { 00771, AID_SHELL,  AID_SHELL,  0, \"data/local\" },\n    { 01771, AID_SYSTEM, AID_MISC,   0, \"data/misc\" },\n    { 00770, AID_DHCP,   AID_DHCP,   0, \"data/misc/dhcp\" },\n    { 00771, AID_SHARED_RELRO, AID_SHARED_RELRO, 0, \"data/misc/shared_relro\" },\n    { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, \"data/media\" },\n    { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, \"data/media/Music\" },\n    { 00750, AID_ROOT,   AID_SHELL,  0, \"data/nativetest\" },\n    { 00750, AID_ROOT,   AID_SHELL,  0, \"data/nativetest64\" },\n    { 00771, AID_SYSTEM, AID_SYSTEM, 0, \"data\" },\n    { 00755, AID_ROOT,   AID_SYSTEM, 0, \"mnt\" },\n    { 00755, AID_ROOT,   AID_ROOT,   0, \"root\" },\n    { 00750, AID_ROOT,   AID_SHELL,  0, \"sbin\" },\n    { 00751, AID_ROOT,   AID_SDCARD_R, 0, \"storage\" },\n    { 00755, AID_ROOT,   AID_SHELL,  0, \"system/bin\" },\n    { 00755, AID_ROOT,   AID_SHELL,  0, \"system/vendor\" },\n    { 00755, AID_ROOT,   AID_SHELL,  0, \"system/xbin\" },\n    { 00755, AID_ROOT,   AID_ROOT,   0, \"system/etc/ppp\" },\n    { 00755, AID_ROOT,   AID_SHELL,  0, \"vendor\" },\n    { 00777, AID_ROOT,   AID_ROOT,   0, \"sdcard\" },\n    { 00755, AID_ROOT,   AID_ROOT,   0, 0 },\n};\n\n/* Rules for files.\n** These rules are applied based on \"first match\", so they\n** should start with the most specific path and work their\n** way up to the root. Prefixes ending in * denotes wildcard\n** and will allow partial matches.\n*/\nstatic const char conf_dir[] = \"/system/etc/fs_config_dirs\";\nstatic const char conf_file[] = \"/system/etc/fs_config_files\";\n\nstatic const struct fs_path_config android_files[] = {\n    { 00440, AID_ROOT,      AID_SHELL,     0, \"system/etc/init.goldfish.rc\" },\n    { 00550, AID_ROOT,      AID_SHELL,     0, \"system/etc/init.goldfish.sh\" },\n    { 00550, AID_ROOT,      AID_SHELL,     0, \"system/etc/init.ril\" },\n    { 00555, AID_ROOT,      AID_ROOT,      0, \"system/etc/ppp/*\" },\n    { 00555, AID_ROOT,      AID_ROOT,      0, \"system/etc/rc.*\" },\n    { 00440, AID_ROOT,      AID_ROOT,      0, \"system/etc/recovery.img\" },\n    { 00444, AID_ROOT,      AID_ROOT,      0, conf_dir + 1 },\n    { 00444, AID_ROOT,      AID_ROOT,      0, conf_file + 1 },\n    { 00644, AID_SYSTEM,    AID_SYSTEM,    0, \"data/app/*\" },\n    { 00644, AID_MEDIA_RW,  AID_MEDIA_RW,  0, \"data/media/*\" },\n    { 00644, AID_SYSTEM,    AID_SYSTEM,    0, \"data/app-private/*\" },\n    { 00644, AID_SYSTEM,    AID_SYSTEM,    0, \"data/app-ephemeral/*\" },\n    { 00644, AID_APP,       AID_APP,       0, \"data/data/*\" },\n    { 00640, AID_ROOT,      AID_SHELL,     0, \"data/nativetest/tests.txt\" },\n    { 00640, AID_ROOT,      AID_SHELL,     0, \"data/nativetest64/tests.txt\" },\n    { 00750, AID_ROOT,      AID_SHELL,     0, \"data/nativetest/*\" },\n    { 00750, AID_ROOT,      AID_SHELL,     0, \"data/nativetest64/*\" },\n\n    /* the following two files are INTENTIONALLY set-uid, but they\n     * are NOT included on user builds. */\n    { 04750, AID_ROOT,      AID_SHELL,     0, \"system/xbin/su\" },\n    { 06755, AID_ROOT,      AID_ROOT,      0, \"system/xbin/procmem\" },\n\n    /* the following files have enhanced capabilities and ARE included in user builds. */\n    { 00750, AID_ROOT,      AID_SHELL,     CAP_MASK_LONG(CAP_SETUID) | CAP_MASK_LONG(CAP_SETGID), \"system/bin/run-as\" },\n    { 00700, AID_SYSTEM,    AID_SHELL,     CAP_MASK_LONG(CAP_BLOCK_SUSPEND), \"system/bin/inputflinger\" },\n\n    { 00750, AID_ROOT,      AID_ROOT,      0, \"system/bin/uncrypt\" },\n    { 00750, AID_ROOT,      AID_ROOT,      0, \"system/bin/install-recovery.sh\" },\n    { 00755, AID_ROOT,      AID_SHELL,     0, \"system/bin/*\" },\n    { 00755, AID_ROOT,      AID_ROOT,      0, \"system/lib/valgrind/*\" },\n    { 00755, AID_ROOT,      AID_ROOT,      0, \"system/lib64/valgrind/*\" },\n    { 00755, AID_ROOT,      AID_SHELL,     0, \"system/xbin/*\" },\n    { 00755, AID_ROOT,      AID_SHELL,     0, \"system/vendor/bin/*\" },\n    { 00755, AID_ROOT,      AID_SHELL,     0, \"system/vendor/xbin/*\" },\n    { 00755, AID_ROOT,      AID_SHELL,     0, \"vendor/bin/*\" },\n    { 00755, AID_ROOT,      AID_SHELL,     0, \"vendor/xbin/*\" },\n    { 00750, AID_ROOT,      AID_SHELL,     0, \"sbin/*\" },\n    { 00755, AID_ROOT,      AID_ROOT,      0, \"bin/*\" },\n    { 00750, AID_ROOT,      AID_SHELL,     0, \"init*\" },\n    { 00750, AID_ROOT,      AID_SHELL,     0, \"sbin/fs_mgr\" },\n    { 00640, AID_ROOT,      AID_SHELL,     0, \"fstab.*\" },\n    { 00644, AID_ROOT,      AID_ROOT,      0, 0 },\n};\n\nstatic int fs_config_open(int dir, const char *target_out_path)\n{\n    int fd = -1;\n\n    if (target_out_path && *target_out_path) {\n        /* target_out_path is the path to the directory holding content of system partition\n           but as we cannot guaranty it ends with '/system' we need this below skip_len logic */\n        char *name = NULL;\n        int target_out_path_len = strlen(target_out_path);\n        int skip_len = strlen(\"/system\");\n\n        if (target_out_path[target_out_path_len] == '/') {\n            skip_len++;\n        }\n        if (asprintf(&name, \"%s%s\", target_out_path, (dir ? conf_dir : conf_file) + skip_len) != -1) {\n            fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_BINARY));\n            free(name);\n        }\n    }\n    if (fd < 0) {\n        fd = TEMP_FAILURE_RETRY(open(dir ? conf_dir : conf_file, O_RDONLY | O_BINARY));\n    }\n    return fd;\n}\n\nstatic bool fs_config_cmp(bool dir, const char *prefix, size_t len,\n                                    const char *path, size_t plen)\n{\n    if (dir) {\n        if (plen < len) {\n            return false;\n        }\n    } else {\n        /* If name ends in * then allow partial matches. */\n        if (prefix[len - 1] == '*') {\n            return !strncmp(prefix, path, len - 1);\n        }\n        if (plen != len) {\n            return false;\n        }\n    }\n    return !strncmp(prefix, path, len);\n}\n\nvoid fs_config(const char *path, int dir, const char *target_out_path,\n               unsigned *uid, unsigned *gid, unsigned *mode, uint64_t *capabilities)\n{\n    const struct fs_path_config *pc;\n    int fd, plen;\n\n    if (path[0] == '/') {\n        path++;\n    }\n\n    plen = strlen(path);\n\n    fd = fs_config_open(dir, target_out_path);\n    if (fd >= 0) {\n        struct fs_path_config_from_file header;\n\n        while (TEMP_FAILURE_RETRY(read(fd, &header, sizeof(header))) == sizeof(header)) {\n            char *prefix;\n            uint16_t host_len = get2LE((const uint8_t *)&header.len);\n            ssize_t len, remainder = host_len - sizeof(header);\n            if (remainder <= 0) {\n                ALOGE(\"%s len is corrupted\", dir ? conf_dir : conf_file);\n                break;\n            }\n            prefix = calloc(1, remainder);\n            if (!prefix) {\n                ALOGE(\"%s out of memory\", dir ? conf_dir : conf_file);\n                break;\n            }\n            if (TEMP_FAILURE_RETRY(read(fd, prefix, remainder)) != remainder) {\n                free(prefix);\n                ALOGE(\"%s prefix is truncated\", dir ? conf_dir : conf_file);\n                break;\n            }\n            len = strnlen(prefix, remainder);\n            if (len >= remainder) { /* missing a terminating null */\n                free(prefix);\n                ALOGE(\"%s is corrupted\", dir ? conf_dir : conf_file);\n                break;\n            }\n            if (fs_config_cmp(dir, prefix, len, path, plen)) {\n                free(prefix);\n                close(fd);\n                *uid = get2LE((const uint8_t *)&(header.uid));\n                *gid = get2LE((const uint8_t *)&(header.gid));\n                *mode = (*mode & (~07777)) | get2LE((const uint8_t *)&(header.mode));\n                *capabilities = get8LE((const uint8_t *)&(header.capabilities));\n                return;\n            }\n            free(prefix);\n        }\n        close(fd);\n    }\n\n    pc = dir ? android_dirs : android_files;\n    for(; pc->prefix; pc++){\n        if (fs_config_cmp(dir, pc->prefix, strlen(pc->prefix), path, plen)) {\n            break;\n        }\n    }\n    *uid = pc->uid;\n    *gid = pc->gid;\n    *mode = (*mode & (~07777)) | pc->mode;\n    *capabilities = pc->capabilities;\n}\n\nssize_t fs_config_generate(char *buffer, size_t length, const struct fs_path_config *pc)\n{\n    struct fs_path_config_from_file *p = (struct fs_path_config_from_file *)buffer;\n    size_t len = ALIGN(sizeof(*p) + strlen(pc->prefix) + 1, sizeof(uint64_t));\n\n    if ((length < len) || (len > UINT16_MAX)) {\n        return -ENOSPC;\n    }\n    memset(p, 0, len);\n    uint16_t host_len = len;\n    p->len = get2LE((const uint8_t *)&host_len);\n    p->mode = get2LE((const uint8_t *)&(pc->mode));\n    p->uid = get2LE((const uint8_t *)&(pc->uid));\n    p->gid = get2LE((const uint8_t *)&(pc->gid));\n    p->capabilities = get8LE((const uint8_t *)&(pc->capabilities));\n    strcpy(p->prefix, pc->prefix);\n    return len;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/hashmap.c",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <cutils/hashmap.h>\n#include <assert.h>\n#include <errno.h>\n#include <cutils/threads.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdbool.h>\n#include <sys/types.h>\n\ntypedef struct Entry Entry;\nstruct Entry {\n    void* key;\n    int hash;\n    void* value;\n    Entry* next;\n};\n\nstruct Hashmap {\n    Entry** buckets;\n    size_t bucketCount;\n    int (*hash)(void* key);\n    bool (*equals)(void* keyA, void* keyB);\n    mutex_t lock; \n    size_t size;\n};\n\nHashmap* hashmapCreate(size_t initialCapacity,\n        int (*hash)(void* key), bool (*equals)(void* keyA, void* keyB)) {\n    assert(hash != NULL);\n    assert(equals != NULL);\n    \n    Hashmap* map = malloc(sizeof(Hashmap));\n    if (map == NULL) {\n        return NULL;\n    }\n    \n    // 0.75 load factor.\n    size_t minimumBucketCount = initialCapacity * 4 / 3;\n    map->bucketCount = 1;\n    while (map->bucketCount <= minimumBucketCount) {\n        // Bucket count must be power of 2.\n        map->bucketCount <<= 1; \n    }\n\n    map->buckets = calloc(map->bucketCount, sizeof(Entry*));\n    if (map->buckets == NULL) {\n        free(map);\n        return NULL;\n    }\n    \n    map->size = 0;\n\n    map->hash = hash;\n    map->equals = equals;\n    \n    mutex_init(&map->lock);\n    \n    return map;\n}\n\n/**\n * Hashes the given key.\n */\n#ifdef __clang__\n__attribute__((no_sanitize(\"integer\")))\n#endif\nstatic inline int hashKey(Hashmap* map, void* key) {\n    int h = map->hash(key);\n\n    // We apply this secondary hashing discovered by Doug Lea to defend\n    // against bad hashes.\n    h += ~(h << 9);\n    h ^= (((unsigned int) h) >> 14);\n    h += (h << 4);\n    h ^= (((unsigned int) h) >> 10);\n       \n    return h;\n}\n\nsize_t hashmapSize(Hashmap* map) {\n    return map->size;\n}\n\nstatic inline size_t calculateIndex(size_t bucketCount, int hash) {\n    return ((size_t) hash) & (bucketCount - 1);\n}\n\nstatic void expandIfNecessary(Hashmap* map) {\n    // If the load factor exceeds 0.75...\n    if (map->size > (map->bucketCount * 3 / 4)) {\n        // Start off with a 0.33 load factor.\n        size_t newBucketCount = map->bucketCount << 1;\n        Entry** newBuckets = calloc(newBucketCount, sizeof(Entry*));\n        if (newBuckets == NULL) {\n            // Abort expansion.\n            return;\n        }\n        \n        // Move over existing entries.\n        size_t i;\n        for (i = 0; i < map->bucketCount; i++) {\n            Entry* entry = map->buckets[i];\n            while (entry != NULL) {\n                Entry* next = entry->next;\n                size_t index = calculateIndex(newBucketCount, entry->hash);\n                entry->next = newBuckets[index];\n                newBuckets[index] = entry;\n                entry = next;\n            }\n        }\n\n        // Copy over internals.\n        free(map->buckets);\n        map->buckets = newBuckets;\n        map->bucketCount = newBucketCount;\n    }\n}\n\nvoid hashmapLock(Hashmap* map) {\n    mutex_lock(&map->lock);\n}\n\nvoid hashmapUnlock(Hashmap* map) {\n    mutex_unlock(&map->lock);\n}\n\nvoid hashmapFree(Hashmap* map) {\n    size_t i;\n    for (i = 0; i < map->bucketCount; i++) {\n        Entry* entry = map->buckets[i];\n        while (entry != NULL) {\n            Entry* next = entry->next;\n            free(entry);\n            entry = next;\n        }\n    }\n    free(map->buckets);\n    mutex_destroy(&map->lock);\n    free(map);\n}\n\n#ifdef __clang__\n__attribute__((no_sanitize(\"integer\")))\n#endif\n/* FIXME: relies on signed integer overflow, which is undefined behavior */\nint hashmapHash(void* key, size_t keySize) {\n    int h = keySize;\n    char* data = (char*) key;\n    size_t i;\n    for (i = 0; i < keySize; i++) {\n        h = h * 31 + *data;\n        data++;\n    }\n    return h;\n}\n\nstatic Entry* createEntry(void* key, int hash, void* value) {\n    Entry* entry = malloc(sizeof(Entry));\n    if (entry == NULL) {\n        return NULL;\n    }\n    entry->key = key;\n    entry->hash = hash;\n    entry->value = value;\n    entry->next = NULL;\n    return entry;\n}\n\nstatic inline bool equalKeys(void* keyA, int hashA, void* keyB, int hashB,\n        bool (*equals)(void*, void*)) {\n    if (keyA == keyB) {\n        return true;\n    }\n    if (hashA != hashB) {\n        return false;\n    }\n    return equals(keyA, keyB);\n}\n\nvoid* hashmapPut(Hashmap* map, void* key, void* value) {\n    int hash = hashKey(map, key);\n    size_t index = calculateIndex(map->bucketCount, hash);\n\n    Entry** p = &(map->buckets[index]);\n    while (true) {\n        Entry* current = *p;\n\n        // Add a new entry.\n        if (current == NULL) {\n            *p = createEntry(key, hash, value);\n            if (*p == NULL) {\n                errno = ENOMEM;\n                return NULL;\n            }\n            map->size++;\n            expandIfNecessary(map);\n            return NULL;\n        }\n\n        // Replace existing entry.\n        if (equalKeys(current->key, current->hash, key, hash, map->equals)) {\n            void* oldValue = current->value;\n            current->value = value;\n            return oldValue;\n        }\n\n        // Move to next entry.\n        p = &current->next;\n    }\n}\n\nvoid* hashmapGet(Hashmap* map, void* key) {\n    int hash = hashKey(map, key);\n    size_t index = calculateIndex(map->bucketCount, hash);\n\n    Entry* entry = map->buckets[index];\n    while (entry != NULL) {\n        if (equalKeys(entry->key, entry->hash, key, hash, map->equals)) {\n            return entry->value;\n        }\n        entry = entry->next;\n    }\n\n    return NULL;\n}\n\nbool hashmapContainsKey(Hashmap* map, void* key) {\n    int hash = hashKey(map, key);\n    size_t index = calculateIndex(map->bucketCount, hash);\n\n    Entry* entry = map->buckets[index];\n    while (entry != NULL) {\n        if (equalKeys(entry->key, entry->hash, key, hash, map->equals)) {\n            return true;\n        }\n        entry = entry->next;\n    }\n\n    return false;\n}\n\nvoid* hashmapMemoize(Hashmap* map, void* key, \n        void* (*initialValue)(void* key, void* context), void* context) {\n    int hash = hashKey(map, key);\n    size_t index = calculateIndex(map->bucketCount, hash);\n\n    Entry** p = &(map->buckets[index]);\n    while (true) {\n        Entry* current = *p;\n\n        // Add a new entry.\n        if (current == NULL) {\n            *p = createEntry(key, hash, NULL);\n            if (*p == NULL) {\n                errno = ENOMEM;\n                return NULL;\n            }\n            void* value = initialValue(key, context);\n            (*p)->value = value;\n            map->size++;\n            expandIfNecessary(map);\n            return value;\n        }\n\n        // Return existing value.\n        if (equalKeys(current->key, current->hash, key, hash, map->equals)) {\n            return current->value;\n        }\n\n        // Move to next entry.\n        p = &current->next;\n    }\n}\n\nvoid* hashmapRemove(Hashmap* map, void* key) {\n    int hash = hashKey(map, key);\n    size_t index = calculateIndex(map->bucketCount, hash);\n\n    // Pointer to the current entry.\n    Entry** p = &(map->buckets[index]);\n    Entry* current;\n    while ((current = *p) != NULL) {\n        if (equalKeys(current->key, current->hash, key, hash, map->equals)) {\n            void* value = current->value;\n            *p = current->next;\n            free(current);\n            map->size--;\n            return value;\n        }\n\n        p = &current->next;\n    }\n\n    return NULL;\n}\n\nvoid hashmapForEach(Hashmap* map, \n        bool (*callback)(void* key, void* value, void* context),\n        void* context) {\n    size_t i;\n    for (i = 0; i < map->bucketCount; i++) {\n        Entry* entry = map->buckets[i];\n        while (entry != NULL) {\n            Entry *next = entry->next;\n            if (!callback(entry->key, entry->value, context)) {\n                return;\n            }\n            entry = next;\n        }\n    }\n}\n\nsize_t hashmapCurrentCapacity(Hashmap* map) {\n    size_t bucketCount = map->bucketCount;\n    return bucketCount * 3 / 4;\n}\n\nsize_t hashmapCountCollisions(Hashmap* map) {\n    size_t collisions = 0;\n    size_t i;\n    for (i = 0; i < map->bucketCount; i++) {\n        Entry* entry = map->buckets[i];\n        while (entry != NULL) {\n            if (entry->next != NULL) {\n                collisions++;\n            }\n            entry = entry->next;\n        }\n    }\n    return collisions;\n}\n\nint hashmapIntHash(void* key) {\n    // Return the key value itself.\n    return *((int*) key);\n}\n\nbool hashmapIntEquals(void* keyA, void* keyB) {\n    int a = *((int*) keyA);\n    int b = *((int*) keyB);\n    return a == b;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/iosched_policy.c",
    "content": "/*\n** Copyright 2007, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\"); \n** you may not use this file except in compliance with the License. \n** You may obtain a copy of the License at \n**\n**     http://www.apache.org/licenses/LICENSE-2.0 \n**\n** Unless required by applicable law or agreed to in writing, software \n** distributed under the License is distributed on an \"AS IS\" BASIS, \n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n** See the License for the specific language governing permissions and \n** limitations under the License.\n*/\n\n#include <errno.h>\n#include <fcntl.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include <cutils/iosched_policy.h>\n\n#if defined(__ANDROID__)\n#include <linux/ioprio.h>\n#include <sys/syscall.h>\n#define __android_unused\n#else\n#define __android_unused __attribute__((__unused__))\n#endif\n\nint android_set_ioprio(int pid __android_unused, IoSchedClass clazz __android_unused, int ioprio __android_unused) {\n#if defined(__ANDROID__)\n    if (syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, pid, ioprio | (clazz << IOPRIO_CLASS_SHIFT))) {\n        return -1;\n    }\n#endif\n    return 0;\n}\n\nint android_get_ioprio(int pid __android_unused, IoSchedClass *clazz, int *ioprio) {\n#if defined(__ANDROID__)\n    int rc;\n\n    if ((rc = syscall(SYS_ioprio_get, IOPRIO_WHO_PROCESS, pid)) < 0) {\n        return -1;\n    }\n\n    *clazz = (rc >> IOPRIO_CLASS_SHIFT);\n    *ioprio = (rc & 0xff);\n#else\n    *clazz = IoSchedClass_NONE;\n    *ioprio = 0;\n#endif\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/klog.c",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <errno.h>\n#include <fcntl.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#include <cutils/klog.h>\n\nstatic int klog_fd = -1;\nstatic int klog_level = KLOG_DEFAULT_LEVEL;\n\nint klog_get_level(void) {\n    return klog_level;\n}\n\nvoid klog_set_level(int level) {\n    klog_level = level;\n}\n\nvoid klog_init(void) {\n    if (klog_fd >= 0) return; /* Already initialized */\n\n    klog_fd = open(\"/dev/kmsg\", O_WRONLY | O_CLOEXEC);\n    if (klog_fd >= 0) {\n        return;\n    }\n\n    static const char* name = \"/dev/__kmsg__\";\n    if (mknod(name, S_IFCHR | 0600, (1 << 8) | 11) == 0) {\n        klog_fd = open(name, O_WRONLY | O_CLOEXEC);\n        unlink(name);\n    }\n}\n\n#define LOG_BUF_MAX 512\n\nvoid klog_writev(int level, const struct iovec* iov, int iov_count) {\n    if (level > klog_level) return;\n    if (klog_fd < 0) klog_init();\n    if (klog_fd < 0) return;\n    TEMP_FAILURE_RETRY(writev(klog_fd, iov, iov_count));\n}\n\nvoid klog_write(int level, const char* fmt, ...) {\n    if (level > klog_level) return;\n    char buf[LOG_BUF_MAX];\n    va_list ap;\n    va_start(ap, fmt);\n    vsnprintf(buf, sizeof(buf), fmt, ap);\n    va_end(ap);\n\n    buf[LOG_BUF_MAX - 1] = 0;\n\n    struct iovec iov[1];\n    iov[0].iov_base = buf;\n    iov[0].iov_len = strlen(buf);\n    klog_writev(level, iov, 1);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/load_file.c",
    "content": "/* libs/cutils/load_file.c\n**\n** Copyright 2006, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\"); \n** you may not use this file except in compliance with the License. \n** You may obtain a copy of the License at \n**\n**     http://www.apache.org/licenses/LICENSE-2.0 \n**\n** Unless required by applicable law or agreed to in writing, software \n** distributed under the License is distributed on an \"AS IS\" BASIS, \n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n** See the License for the specific language governing permissions and \n** limitations under the License.\n*/\n\n#include <stdlib.h>\n#include <unistd.h>\n#include <fcntl.h>\n\nvoid *load_file(const char *fn, unsigned *_sz)\n{\n    char *data;\n    int sz;\n    int fd;\n\n    data = 0;\n    fd = open(fn, O_RDONLY);\n    if(fd < 0) return 0;\n\n    sz = lseek(fd, 0, SEEK_END);\n    if(sz < 0) goto oops;\n\n    if(lseek(fd, 0, SEEK_SET) != 0) goto oops;\n\n    data = (char*) malloc(sz + 1);\n    if(data == 0) goto oops;\n\n    if(read(fd, data, sz) != sz) goto oops;\n    close(fd);\n    data[sz] = 0;\n\n    if(_sz) *_sz = sz;\n    return data;\n\noops:\n    close(fd);\n    if(data != 0) free(data);\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/multiuser.c",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <cutils/multiuser.h>\n\nuserid_t multiuser_get_user_id(uid_t uid) {\n    return uid / MULTIUSER_APP_PER_USER_RANGE;\n}\n\nappid_t multiuser_get_app_id(uid_t uid) {\n    return uid % MULTIUSER_APP_PER_USER_RANGE;\n}\n\nuid_t multiuser_get_uid(userid_t userId, appid_t appId) {\n    return userId * MULTIUSER_APP_PER_USER_RANGE + (appId % MULTIUSER_APP_PER_USER_RANGE);\n}\n\nappid_t multiuser_get_shared_app_gid(uid_t id) {\n  return MULTIUSER_FIRST_SHARED_APPLICATION_GID + (id % MULTIUSER_APP_PER_USER_RANGE)\n          - MULTIUSER_FIRST_APPLICATION_UID;\n\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/native_handle.c",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"NativeHandle\"\n\n#include <stdint.h>\n#include <errno.h>\n#include <string.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <cutils/log.h>\n#include <cutils/native_handle.h>\n\nstatic const int kMaxNativeFds = 1024;\nstatic const int kMaxNativeInts = 1024;\n\nnative_handle_t* native_handle_create(int numFds, int numInts)\n{\n    if (numFds < 0 || numInts < 0 || numFds > kMaxNativeFds || numInts > kMaxNativeInts) {\n        return NULL;\n    }\n\n    size_t mallocSize = sizeof(native_handle_t) + (sizeof(int) * (numFds + numInts));\n    native_handle_t* h = malloc(mallocSize);\n    if (h) {\n        h->version = sizeof(native_handle_t);\n        h->numFds = numFds;\n        h->numInts = numInts;\n    }\n    return h;\n}\n\nint native_handle_delete(native_handle_t* h)\n{\n    if (h) {\n        if (h->version != sizeof(native_handle_t))\n            return -EINVAL;\n        free(h);\n    }\n    return 0;\n}\n\nint native_handle_close(const native_handle_t* h)\n{\n    if (h->version != sizeof(native_handle_t))\n        return -EINVAL;\n\n    const int numFds = h->numFds;\n    int i;\n    for (i=0 ; i<numFds ; i++) {\n        close(h->data[i]);\n    }\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/open_memstream.c",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#if defined(__APPLE__)\n\n/*\n * Implementation of the POSIX open_memstream() function, which Linux has\n * but BSD lacks.\n *\n * Summary:\n * - Works like a file-backed FILE* opened with fopen(name, \"w\"), but the\n *   backing is a chunk of memory rather than a file.\n * - The buffer expands as you write more data.  Seeking past the end\n *   of the file and then writing to it zero-fills the gap.\n * - The values at \"*bufp\" and \"*sizep\" should be considered read-only,\n *   and are only valid immediately after an fflush() or fclose().\n * - A '\\0' is maintained just past the end of the file. This is not included\n *   in \"*sizep\".  (The behavior w.r.t. fseek() is not clearly defined.\n *   The spec says the null byte is written when a write() advances EOF,\n *   but it looks like glibc ensures the null byte is always found at EOF,\n *   even if you just seeked backwards.  The example on the opengroup.org\n *   page suggests that this is the expected behavior.  The null must be\n *   present after a no-op fflush(), which we can't see, so we have to save\n *   and restore it.  Annoying, but allows file truncation.)\n * - After fclose(), the caller must eventually free(*bufp).\n *\n * This is built out of funopen(), which BSD has but Linux lacks.  There is\n * no flush() operator, so we need to keep the user pointers up to date\n * after each operation.\n *\n * I don't think Windows has any of the above, but we don't need to use\n * them there, so we just supply a stub.\n */\n#include <cutils/open_memstream.h>\n#include <stdlib.h>\n#include <sys/types.h>\n#include <unistd.h>\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n#include <assert.h>\n\n#if 0\n# define DBUG(x) printf x\n#else\n# define DBUG(x) ((void)0)\n#endif\n\n/*\n * Definition of a seekable, write-only memory stream.\n */\ntypedef struct {\n    char**      bufp;       /* pointer to buffer pointer */\n    size_t*     sizep;      /* pointer to eof */\n\n    size_t      allocSize;  /* size of buffer */\n    size_t      eof;        /* furthest point we've written to */\n    size_t      offset;     /* current write offset */\n    char        saved;      /* required by NUL handling */\n} MemStream;\n\n#define kInitialSize    1024\n\n/*\n * Ensure that we have enough storage to write \"size\" bytes at the\n * current offset.  We also have to take into account the extra '\\0'\n * that we maintain just past EOF.\n *\n * Returns 0 on success.\n */\nstatic int ensureCapacity(MemStream* stream, int writeSize)\n{\n    DBUG((\"+++ ensureCap off=%d size=%d\\n\", stream->offset, writeSize));\n\n    size_t neededSize = stream->offset + writeSize + 1;\n    if (neededSize <= stream->allocSize)\n        return 0;\n\n    size_t newSize;\n\n    if (stream->allocSize == 0) {\n        newSize = kInitialSize;\n    } else {\n        newSize = stream->allocSize;\n        newSize += newSize / 2;             /* expand by 3/2 */\n    }\n\n    if (newSize < neededSize)\n        newSize = neededSize;\n    DBUG((\"+++ realloc %p->%p to size=%d\\n\",\n        stream->bufp, *stream->bufp, newSize));\n    char* newBuf = (char*) realloc(*stream->bufp, newSize);\n    if (newBuf == NULL)\n        return -1;\n\n    *stream->bufp = newBuf;\n    stream->allocSize = newSize;\n    return 0;\n}\n\n/*\n * Write data to a memstream, expanding the buffer if necessary.\n *\n * If we previously seeked beyond EOF, zero-fill the gap.\n *\n * Returns the number of bytes written.\n */\nstatic int write_memstream(void* cookie, const char* buf, int size)\n{\n    MemStream* stream = (MemStream*) cookie;\n\n    if (ensureCapacity(stream, size) < 0)\n        return -1;\n\n    /* seeked past EOF earlier? */\n    if (stream->eof < stream->offset) {\n        DBUG((\"+++ zero-fill gap from %d to %d\\n\",\n            stream->eof, stream->offset-1));\n        memset(*stream->bufp + stream->eof, '\\0',\n            stream->offset - stream->eof);\n    }\n\n    /* copy data, advance write pointer */\n    memcpy(*stream->bufp + stream->offset, buf, size);\n    stream->offset += size;\n\n    if (stream->offset > stream->eof) {\n        /* EOF has advanced, update it and append null byte */\n        DBUG((\"+++ EOF advanced to %d, appending nul\\n\", stream->offset));\n        assert(stream->offset < stream->allocSize);\n        stream->eof = stream->offset;\n    } else {\n        /* within previously-written area; save char we're about to stomp */\n        DBUG((\"+++ within written area, saving '%c' at %d\\n\",\n            *(*stream->bufp + stream->offset), stream->offset));\n        stream->saved = *(*stream->bufp + stream->offset);\n    }\n    *(*stream->bufp + stream->offset) = '\\0';\n    *stream->sizep = stream->offset;\n\n    return size;\n}\n\n/*\n * Seek within a memstream.\n *\n * Returns the new offset, or -1 on failure.\n */\nstatic fpos_t seek_memstream(void* cookie, fpos_t offset, int whence)\n{\n    MemStream* stream = (MemStream*) cookie;\n    off_t newPosn = (off_t) offset;\n\n    if (whence == SEEK_CUR) {\n        newPosn += stream->offset;\n    } else if (whence == SEEK_END) {\n        newPosn += stream->eof;\n    }\n\n    if (newPosn < 0 || ((fpos_t)((size_t) newPosn)) != newPosn) {\n        /* bad offset - negative or huge */\n        DBUG((\"+++ bogus seek offset %ld\\n\", (long) newPosn));\n        errno = EINVAL;\n        return (fpos_t) -1;\n    }\n\n    if (stream->offset < stream->eof) {\n        /*\n         * We were pointing to an area we'd already written to, which means\n         * we stomped on a character and must now restore it.\n         */\n        DBUG((\"+++ restoring char '%c' at %d\\n\",\n            stream->saved, stream->offset));\n        *(*stream->bufp + stream->offset) = stream->saved;\n    }\n\n    stream->offset = (size_t) newPosn;\n\n    if (stream->offset < stream->eof) {\n        /*\n         * We're seeked backward into the stream.  Preserve the character\n         * at EOF and stomp it with a NUL.\n         */\n        stream->saved = *(*stream->bufp + stream->offset);\n        *(*stream->bufp + stream->offset) = '\\0';\n        *stream->sizep = stream->offset;\n    } else {\n        /*\n         * We're positioned at, or possibly beyond, the EOF.  We want to\n         * publish the current EOF, not the current position.\n         */\n        *stream->sizep = stream->eof;\n    }\n\n    return newPosn;\n}\n\n/*\n * Close the memstream.  We free everything but the data buffer.\n */\nstatic int close_memstream(void* cookie)\n{\n    free(cookie);\n    return 0;\n}\n\n/*\n * Prepare a memstream.\n */\nFILE* open_memstream(char** bufp, size_t* sizep)\n{\n    FILE* fp;\n    MemStream* stream;\n\n    if (bufp == NULL || sizep == NULL) {\n        errno = EINVAL;\n        return NULL;\n    }\n\n    stream = (MemStream*) calloc(1, sizeof(MemStream));\n    if (stream == NULL)\n        return NULL;\n\n    fp = funopen(stream,\n        NULL, write_memstream, seek_memstream, close_memstream);\n    if (fp == NULL) {\n        free(stream);\n        return NULL;\n    }\n\n    *sizep = 0;\n    *bufp = NULL;\n    stream->bufp = bufp;\n    stream->sizep = sizep;\n\n    return fp;\n}\n\n\n\n\n#if 0\n#define _GNU_SOURCE\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n/*\n * Simple regression test.\n *\n * To test on desktop Linux with valgrind, it's possible to make a simple\n * change to open_memstream() to use fopencookie instead:\n *\n *  cookie_io_functions_t iofuncs =\n *      { NULL, write_memstream, seek_memstream, close_memstream };\n *  fp = fopencookie(stream, \"w\", iofuncs);\n *\n * (Some tweaks to seek_memstream are also required, as that takes a\n * pointer to an offset rather than an offset, and returns 0 or -1.)\n */\nint testMemStream(void)\n{\n    FILE *stream;\n    char *buf;\n    size_t len;\n    off_t eob;\n\n    printf(\"Test1\\n\");\n\n    /* std example */\n    stream = open_memstream(&buf, &len);\n    fprintf(stream, \"hello my world\");\n    fflush(stream);\n    printf(\"buf=%s, len=%zu\\n\", buf, len);\n    eob = ftello(stream);\n    fseeko(stream, 0, SEEK_SET);\n    fprintf(stream, \"good-bye\");\n    fseeko(stream, eob, SEEK_SET);\n    fclose(stream);\n    printf(\"buf=%s, len=%zu\\n\", buf, len);\n    free(buf);\n\n    printf(\"Test2\\n\");\n\n    /* std example without final seek-to-end */\n    stream = open_memstream(&buf, &len);\n    fprintf(stream, \"hello my world\");\n    fflush(stream);\n    printf(\"buf=%s, len=%zu\\n\", buf, len);\n    eob = ftello(stream);\n    fseeko(stream, 0, SEEK_SET);\n    fprintf(stream, \"good-bye\");\n    //fseeko(stream, eob, SEEK_SET);\n    fclose(stream);\n    printf(\"buf=%s, len=%zu\\n\", buf, len);\n    free(buf);\n\n    printf(\"Test3\\n\");\n\n    /* fancy example; should expand buffer with writes */\n    static const int kCmpLen = 1024 + 128;\n    char* cmp = malloc(kCmpLen);\n    memset(cmp, 0, 1024);\n    memset(cmp+1024, 0xff, kCmpLen-1024);\n    sprintf(cmp, \"This-is-a-tes1234\");\n    sprintf(cmp + 1022, \"abcdef\");\n\n    stream = open_memstream (&buf, &len);\n    setvbuf(stream, NULL, _IONBF, 0);   /* note: crashes in glibc with this */\n    fprintf(stream, \"This-is-a-test\");\n    fseek(stream, -1, SEEK_CUR);    /* broken in glibc; can use {13,SEEK_SET} */\n    fprintf(stream, \"1234\");\n    fseek(stream, 1022, SEEK_SET);\n    fputc('a', stream);\n    fputc('b', stream);\n    fputc('c', stream);\n    fputc('d', stream);\n    fputc('e', stream);\n    fputc('f', stream);\n    fflush(stream);\n\n    if (memcmp(buf, cmp, len+1) != 0) {\n        printf(\"mismatch\\n\");\n    } else {\n        printf(\"match\\n\");\n    }\n\n    printf(\"Test4\\n\");\n    stream = open_memstream (&buf, &len);\n    fseek(stream, 5000, SEEK_SET);\n    fseek(stream, 4096, SEEK_SET);\n    fseek(stream, -1, SEEK_SET);        /* should have no effect */\n    fputc('x', stream);\n    if (ftell(stream) == 4097)\n        printf(\"good\\n\");\n    else\n        printf(\"BAD: offset is %ld\\n\", ftell(stream));\n\n    printf(\"DONE\\n\");\n\n    return 0;\n}\n\n/* expected output:\nTest1\nbuf=hello my world, len=14\nbuf=good-bye world, len=14\nTest2\nbuf=hello my world, len=14\nbuf=good-bye, len=8\nTest3\nmatch\nTest4\ngood\nDONE\n*/\n\n#endif\n\n#endif /* __APPLE__ */\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/partition_utils.c",
    "content": "/*\n * Copyright 2011, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <fcntl.h>\n#include <sys/ioctl.h>\n#include <sys/mount.h> /* for BLKGETSIZE */\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#include <cutils/properties.h>\n\nstatic int only_one_char(char *buf, int len, char c)\n{\n    int i, ret;\n\n    ret = 1;\n    for (i=0; i<len; i++) {\n        if (buf[i] != c) {\n            ret = 0;\n            break;\n        }\n    }\n    return ret;\n}\n\nint partition_wiped(char *source)\n{\n    char buf[4096];\n    int fd, ret;\n\n    if ((fd = open(source, O_RDONLY)) < 0) {\n        return 0;\n    }\n\n    ret = read(fd, buf, sizeof(buf));\n    close(fd);\n\n    if (ret != sizeof(buf)) {\n        return 0;\n    }\n\n    /* Check for all zeros */\n    if (only_one_char(buf, sizeof(buf), 0)) {\n       return 1;\n    }\n\n    /* Check for all ones */\n    if (only_one_char(buf, sizeof(buf), 0xff)) {\n       return 1;\n    }\n\n    return 0;\n}\n\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/process_name.c",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <fcntl.h>\n#include <stdlib.h>\n#include <string.h>\n#if defined(__linux__)\n#include <sys/prctl.h>\n#endif\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#include <cutils/process_name.h>\n#if defined(__ANDROID__)\n#include <cutils/properties.h>\n#endif\n\n#define PROCESS_NAME_DEVICE \"/sys/qemu_trace/process_name\"\n\nstatic const char* process_name = \"unknown\";\n#if defined(__ANDROID__)\nstatic int running_in_emulator = -1;\n#endif\n\nvoid set_process_name(const char* new_name) {\n#if defined(__ANDROID__)\n    char  propBuf[PROPERTY_VALUE_MAX];\n#endif\n\n    if (new_name == NULL) {\n        return;\n    }\n\n    // We never free the old name. Someone else could be using it.\n    int len = strlen(new_name);\n    char* copy = (char*) malloc(len + 1);\n    strcpy(copy, new_name);\n    process_name = (const char*) copy;\n\n#if defined(__linux__)\n    if (len < 16) {\n        prctl(PR_SET_NAME, (unsigned long) new_name, 0, 0, 0);\n    } else {\n        prctl(PR_SET_NAME, (unsigned long) new_name + len - 15, 0, 0, 0);\n    }\n#endif\n\n#if defined(__ANDROID__)\n    // If we know we are not running in the emulator, then return.\n    if (running_in_emulator == 0) {\n        return;\n    }\n\n    // If the \"running_in_emulator\" variable has not been initialized,\n    // then do it now.\n    if (running_in_emulator == -1) {\n        property_get(\"ro.kernel.qemu\", propBuf, \"\");\n        if (propBuf[0] == '1') {\n            running_in_emulator = 1;\n        } else {\n            running_in_emulator = 0;\n            return;\n        }\n    }\n\n    // If the emulator was started with the \"-trace file\" command line option\n    // then we want to record the process name in the trace even if we are\n    // not currently tracing instructions (so that we will know the process\n    // name when we do start tracing instructions).  We do not need to execute\n    // this code if we are just running in the emulator without the \"-trace\"\n    // command line option, but we don't know that here and this function\n    // isn't called frequently enough to bother optimizing that case.\n    int fd = open(PROCESS_NAME_DEVICE, O_RDWR);\n    if (fd < 0)\n        return;\n    write(fd, process_name, strlen(process_name) + 1);\n    close(fd);\n#endif\n}\n\nconst char* get_process_name(void) {\n    return process_name;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/properties.c",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"properties\"\n// #define LOG_NDEBUG 0\n\n#include <stdlib.h>\n#include <string.h>\n#include <ctype.h>\n#include <unistd.h>\n#include <cutils/sockets.h>\n#include <errno.h>\n#include <assert.h>\n\n#include <cutils/properties.h>\n#include <stdbool.h>\n#include <inttypes.h>\n#include <log/log.h>\n\nint8_t property_get_bool(const char *key, int8_t default_value) {\n    if (!key) {\n        return default_value;\n    }\n\n    int8_t result = default_value;\n    char buf[PROPERTY_VALUE_MAX] = {'\\0',};\n\n    int len = property_get(key, buf, \"\");\n    if (len == 1) {\n        char ch = buf[0];\n        if (ch == '0' || ch == 'n') {\n            result = false;\n        } else if (ch == '1' || ch == 'y') {\n            result = true;\n        }\n    } else if (len > 1) {\n         if (!strcmp(buf, \"no\") || !strcmp(buf, \"false\") || !strcmp(buf, \"off\")) {\n            result = false;\n        } else if (!strcmp(buf, \"yes\") || !strcmp(buf, \"true\") || !strcmp(buf, \"on\")) {\n            result = true;\n        }\n    }\n\n    return result;\n}\n\n// Convert string property to int (default if fails); return default value if out of bounds\nstatic intmax_t property_get_imax(const char *key, intmax_t lower_bound, intmax_t upper_bound,\n        intmax_t default_value) {\n    if (!key) {\n        return default_value;\n    }\n\n    intmax_t result = default_value;\n    char buf[PROPERTY_VALUE_MAX] = {'\\0',};\n    char *end = NULL;\n\n    int len = property_get(key, buf, \"\");\n    if (len > 0) {\n        int tmp = errno;\n        errno = 0;\n\n        // Infer base automatically\n        result = strtoimax(buf, &end, /*base*/0);\n        if ((result == INTMAX_MIN || result == INTMAX_MAX) && errno == ERANGE) {\n            // Over or underflow\n            result = default_value;\n            ALOGV(\"%s(%s,%\" PRIdMAX \") - overflow\", __FUNCTION__, key, default_value);\n        } else if (result < lower_bound || result > upper_bound) {\n            // Out of range of requested bounds\n            result = default_value;\n            ALOGV(\"%s(%s,%\" PRIdMAX \") - out of range\", __FUNCTION__, key, default_value);\n        } else if (end == buf) {\n            // Numeric conversion failed\n            result = default_value;\n            ALOGV(\"%s(%s,%\" PRIdMAX \") - numeric conversion failed\",\n                    __FUNCTION__, key, default_value);\n        }\n\n        errno = tmp;\n    }\n\n    return result;\n}\n\nint64_t property_get_int64(const char *key, int64_t default_value) {\n    return (int64_t)property_get_imax(key, INT64_MIN, INT64_MAX, default_value);\n}\n\nint32_t property_get_int32(const char *key, int32_t default_value) {\n    return (int32_t)property_get_imax(key, INT32_MIN, INT32_MAX, default_value);\n}\n\n#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_\n#include <sys/_system_properties.h>\n\nint property_set(const char *key, const char *value)\n{\n    return __system_property_set(key, value);\n}\n\nint property_get(const char *key, char *value, const char *default_value)\n{\n    int len;\n\n    len = __system_property_get(key, value);\n    if(len > 0) {\n        return len;\n    }\n    if(default_value) {\n        len = strlen(default_value);\n        if (len >= PROPERTY_VALUE_MAX) {\n            len = PROPERTY_VALUE_MAX - 1;\n        }\n        memcpy(value, default_value, len);\n        value[len] = '\\0';\n    }\n    return len;\n}\n\nstruct property_list_callback_data\n{\n    void (*propfn)(const char *key, const char *value, void *cookie);\n    void *cookie;\n};\n\nstatic void property_list_callback(const prop_info *pi, void *cookie)\n{\n    char name[PROP_NAME_MAX];\n    char value[PROP_VALUE_MAX];\n    struct property_list_callback_data *data = cookie;\n\n    __system_property_read(pi, name, value);\n    data->propfn(name, value, data->cookie);\n}\n\nint property_list(\n        void (*propfn)(const char *key, const char *value, void *cookie),\n        void *cookie)\n{\n    struct property_list_callback_data data = { propfn, cookie };\n    return __system_property_foreach(property_list_callback, &data);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/qtaguid.c",
    "content": "/*\n** Copyright 2011, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\");\n** you may not use this file except in compliance with the License.\n** You may obtain a copy of the License at\n**\n**     http://www.apache.org/licenses/LICENSE-2.0\n**\n** Unless required by applicable law or agreed to in writing, software\n** distributed under the License is distributed on an \"AS IS\" BASIS,\n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n** See the License for the specific language governing permissions and\n** limitations under the License.\n*/\n\n// #define LOG_NDEBUG 0\n\n#define LOG_TAG \"qtaguid\"\n\n#include <errno.h>\n#include <fcntl.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <string.h>\n#include <unistd.h>\n\n#include <cutils/qtaguid.h>\n#include <log/log.h>\n\nstatic const char* CTRL_PROCPATH = \"/proc/net/xt_qtaguid/ctrl\";\nstatic const int CTRL_MAX_INPUT_LEN = 128;\nstatic const char *GLOBAL_PACIFIER_PARAM = \"/sys/module/xt_qtaguid/parameters/passive\";\nstatic const char *TAG_PACIFIER_PARAM = \"/sys/module/xt_qtaguid/parameters/tag_tracking_passive\";\n\n/*\n * One per proccess.\n * Once the device is open, this process will have its socket tags tracked.\n * And on exit or untimely death, all socket tags will be removed.\n * A process can only open /dev/xt_qtaguid once.\n * It should not close it unless it is really done with all the socket tags.\n * Failure to open it will be visible when socket tagging will be attempted.\n */\nstatic int resTrackFd = -1;\npthread_once_t resTrackInitDone = PTHREAD_ONCE_INIT;\n\n/* Only call once per process. */\nvoid qtaguid_resTrack(void) {\n    resTrackFd = TEMP_FAILURE_RETRY(open(\"/dev/xt_qtaguid\", O_RDONLY));\n    if (resTrackFd >=0) {\n        TEMP_FAILURE_RETRY(fcntl(resTrackFd, F_SETFD, FD_CLOEXEC));\n    }\n}\n\n/*\n * Returns:\n *   0 on success.\n *   -errno on failure.\n */\nstatic int write_ctrl(const char *cmd) {\n    int fd, res, savedErrno;\n\n    ALOGV(\"write_ctrl(%s)\", cmd);\n\n    fd = TEMP_FAILURE_RETRY(open(CTRL_PROCPATH, O_WRONLY));\n    if (fd < 0) {\n        return -errno;\n    }\n\n    res = TEMP_FAILURE_RETRY(write(fd, cmd, strlen(cmd)));\n    if (res < 0) {\n        savedErrno = errno;\n    } else {\n        savedErrno = 0;\n    }\n    if (res < 0) {\n        // ALOGV is enough because all the callers also log failures\n        ALOGV(\"Failed write_ctrl(%s) res=%d errno=%d\", cmd, res, savedErrno);\n    }\n    close(fd);\n    return -savedErrno;\n}\n\nstatic int write_param(const char *param_path, const char *value) {\n    int param_fd;\n    int res;\n\n    param_fd = TEMP_FAILURE_RETRY(open(param_path, O_WRONLY));\n    if (param_fd < 0) {\n        return -errno;\n    }\n    res = TEMP_FAILURE_RETRY(write(param_fd, value, strlen(value)));\n    if (res < 0) {\n        return -errno;\n    }\n    close(param_fd);\n    return 0;\n}\n\nint qtaguid_tagSocket(int sockfd, int tag, uid_t uid) {\n    char lineBuf[CTRL_MAX_INPUT_LEN];\n    int res;\n    uint64_t kTag = ((uint64_t)tag << 32);\n\n    pthread_once(&resTrackInitDone, qtaguid_resTrack);\n\n    snprintf(lineBuf, sizeof(lineBuf), \"t %d %\" PRIu64 \" %d\", sockfd, kTag, uid);\n\n    ALOGV(\"Tagging socket %d with tag %\" PRIx64 \"{%u,0} for uid %d\", sockfd, kTag, tag, uid);\n\n    res = write_ctrl(lineBuf);\n    if (res < 0) {\n        ALOGI(\"Tagging socket %d with tag %\" PRIx64 \"(%d) for uid %d failed errno=%d\",\n             sockfd, kTag, tag, uid, res);\n    }\n\n    return res;\n}\n\nint qtaguid_untagSocket(int sockfd) {\n    char lineBuf[CTRL_MAX_INPUT_LEN];\n    int res;\n\n    ALOGV(\"Untagging socket %d\", sockfd);\n\n    snprintf(lineBuf, sizeof(lineBuf), \"u %d\", sockfd);\n    res = write_ctrl(lineBuf);\n    if (res < 0) {\n        ALOGI(\"Untagging socket %d failed errno=%d\", sockfd, res);\n    }\n\n    return res;\n}\n\nint qtaguid_setCounterSet(int counterSetNum, uid_t uid) {\n    char lineBuf[CTRL_MAX_INPUT_LEN];\n    int res;\n\n    ALOGV(\"Setting counters to set %d for uid %d\", counterSetNum, uid);\n\n    snprintf(lineBuf, sizeof(lineBuf), \"s %d %d\", counterSetNum, uid);\n    res = write_ctrl(lineBuf);\n    return res;\n}\n\nint qtaguid_deleteTagData(int tag, uid_t uid) {\n    char lineBuf[CTRL_MAX_INPUT_LEN];\n    int cnt = 0, res = 0;\n    uint64_t kTag = (uint64_t)tag << 32;\n\n    ALOGV(\"Deleting tag data with tag %\" PRIx64 \"{%d,0} for uid %d\", kTag, tag, uid);\n\n    pthread_once(&resTrackInitDone, qtaguid_resTrack);\n\n    snprintf(lineBuf, sizeof(lineBuf), \"d %\" PRIu64 \" %d\", kTag, uid);\n    res = write_ctrl(lineBuf);\n    if (res < 0) {\n        ALOGI(\"Deleting tag data with tag %\" PRIx64 \"/%d for uid %d failed with cnt=%d errno=%d\",\n             kTag, tag, uid, cnt, errno);\n    }\n\n    return res;\n}\n\nint qtaguid_setPacifier(int on) {\n    const char *value;\n\n    value = on ? \"Y\" : \"N\";\n    if (write_param(GLOBAL_PACIFIER_PARAM, value) < 0) {\n        return -errno;\n    }\n    if (write_param(TAG_PACIFIER_PARAM, value) < 0) {\n        return -errno;\n    }\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/record_stream.c",
    "content": "/* libs/cutils/record_stream.c\n**\n** Copyright 2006, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\"); \n** you may not use this file except in compliance with the License. \n** You may obtain a copy of the License at \n**\n**     http://www.apache.org/licenses/LICENSE-2.0 \n**\n** Unless required by applicable law or agreed to in writing, software \n** distributed under the License is distributed on an \"AS IS\" BASIS, \n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n** See the License for the specific language governing permissions and \n** limitations under the License.\n*/\n\n#include <stdlib.h>\n#include <unistd.h>\n#include <assert.h>\n#include <errno.h>\n#include <cutils/record_stream.h>\n#include <string.h>\n#include <stdint.h>\n#if defined(_WIN32)\n#include <winsock2.h>   /* for ntohl */\n#else\n#include <netinet/in.h>\n#endif\n\n#define HEADER_SIZE 4\n\nstruct RecordStream {\n    int fd;\n    size_t maxRecordLen;\n\n    unsigned char *buffer;\n\n    unsigned char *unconsumed;\n    unsigned char *read_end;\n    unsigned char *buffer_end;\n};\n\n\nextern RecordStream *record_stream_new(int fd, size_t maxRecordLen)\n{\n    RecordStream *ret;\n\n    assert (maxRecordLen <= 0xffff);\n\n    ret = (RecordStream *)calloc(1, sizeof(RecordStream));\n\n    ret->fd = fd;\n    ret->maxRecordLen = maxRecordLen;\n    ret->buffer = (unsigned char *)malloc (maxRecordLen + HEADER_SIZE);\n    \n    ret->unconsumed = ret->buffer;\n    ret->read_end = ret->buffer;\n    ret->buffer_end = ret->buffer + maxRecordLen + HEADER_SIZE;\n\n    return ret;\n}\n\n\nextern void record_stream_free(RecordStream *rs)\n{\n    free(rs->buffer);\n    free(rs);\n}\n\n\n/* returns NULL; if there isn't a full record in the buffer */\nstatic unsigned char * getEndOfRecord (unsigned char *p_begin,\n                                            unsigned char *p_end)\n{\n    size_t len;\n    unsigned char * p_ret;\n\n    if (p_end < p_begin + HEADER_SIZE) {\n        return NULL;\n    }\n\n    //First four bytes are length\n    len = ntohl(*((uint32_t *)p_begin));\n\n    p_ret = p_begin + HEADER_SIZE + len;\n\n    if (p_end < p_ret) {\n        return NULL;\n    }\n\n    return p_ret;\n}\n\nstatic void *getNextRecord (RecordStream *p_rs, size_t *p_outRecordLen)\n{\n    unsigned char *record_start, *record_end;\n\n    record_end = getEndOfRecord (p_rs->unconsumed, p_rs->read_end);\n\n    if (record_end != NULL) {\n        /* one full line in the buffer */\n        record_start = p_rs->unconsumed + HEADER_SIZE;\n        p_rs->unconsumed = record_end;\n\n        *p_outRecordLen = record_end - record_start;\n\n        return record_start;\n    }\n\n    return NULL;\n}\n\n/**\n * Reads the next record from stream fd\n * Records are prefixed by a 16-bit big endian length value\n * Records may not be larger than maxRecordLen\n *\n * Doesn't guard against EINTR\n *\n * p_outRecord and p_outRecordLen may not be NULL\n *\n * Return 0 on success, -1 on fail\n * Returns 0 with *p_outRecord set to NULL on end of stream\n * Returns -1 / errno = EAGAIN if it needs to read again\n */\nint record_stream_get_next (RecordStream *p_rs, void ** p_outRecord, \n                                    size_t *p_outRecordLen)\n{\n    void *ret;\n\n    ssize_t countRead;\n\n    /* is there one record already in the buffer? */\n    ret = getNextRecord (p_rs, p_outRecordLen);\n\n    if (ret != NULL) {\n        *p_outRecord = ret;\n        return 0;\n    }\n\n    // if the buffer is full and we don't have a full record\n    if (p_rs->unconsumed == p_rs->buffer \n        && p_rs->read_end == p_rs->buffer_end\n    ) {\n        // this should never happen\n        //ALOGE(\"max record length exceeded\\n\");\n        assert (0);\n        errno = EFBIG;\n        return -1;\n    }\n\n    if (p_rs->unconsumed != p_rs->buffer) {\n        // move remainder to the beginning of the buffer\n        size_t toMove;\n\n        toMove = p_rs->read_end - p_rs->unconsumed;\n        if (toMove) {\n            memmove(p_rs->buffer, p_rs->unconsumed, toMove);\n        }\n\n        p_rs->read_end = p_rs->buffer + toMove;\n        p_rs->unconsumed = p_rs->buffer;\n    }\n\n    countRead = read (p_rs->fd, p_rs->read_end, p_rs->buffer_end - p_rs->read_end);\n\n    if (countRead <= 0) {\n        /* note: end-of-stream drops through here too */\n        *p_outRecord = NULL;\n        return countRead;\n    }\n\n    p_rs->read_end += countRead;\n\n    ret = getNextRecord (p_rs, p_outRecordLen);\n\n    if (ret == NULL) {\n        /* not enough of a buffer to for a whole command */\n        errno = EAGAIN;\n        return -1;\n    }\n\n    *p_outRecord = ret;        \n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/sched_policy.c",
    "content": "/*\n** Copyright 2007, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\");\n** you may not use this file except in compliance with the License.\n** You may obtain a copy of the License at\n**\n**     http://www.apache.org/licenses/LICENSE-2.0\n**\n** Unless required by applicable law or agreed to in writing, software\n** distributed under the License is distributed on an \"AS IS\" BASIS,\n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n** See the License for the specific language governing permissions and\n** limitations under the License.\n*/\n\n#define LOG_TAG \"SchedPolicy\"\n\n#include <errno.h>\n#include <fcntl.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include <cutils/sched_policy.h>\n#include <log/log.h>\n\n#define UNUSED __attribute__((__unused__))\n\n/* Re-map SP_DEFAULT to the system default policy, and leave other values unchanged.\n * Call this any place a SchedPolicy is used as an input parameter.\n * Returns the possibly re-mapped policy.\n */\nstatic inline SchedPolicy _policy(SchedPolicy p)\n{\n   return p == SP_DEFAULT ? SP_SYSTEM_DEFAULT : p;\n}\n\n#if defined(__ANDROID__)\n\n#include <pthread.h>\n#include <sched.h>\n#include <sys/prctl.h>\n\n#define POLICY_DEBUG 0\n\n// This prctl is only available in Android kernels.\n#define PR_SET_TIMERSLACK_PID 41\n\n// timer slack value in nS enforced when the thread moves to background\n#define TIMER_SLACK_BG 40000000\n#define TIMER_SLACK_FG 50000\n\nstatic pthread_once_t the_once = PTHREAD_ONCE_INIT;\n\nstatic int __sys_supports_schedgroups = -1;\n\n// File descriptors open to /dev/cpuctl/../tasks, setup by initialize, or -1 on error.\nstatic int bg_cgroup_fd = -1;\nstatic int fg_cgroup_fd = -1;\n\n#ifdef USE_CPUSETS\n// File descriptors open to /dev/cpuset/../tasks, setup by initialize, or -1 on error\nstatic int system_bg_cpuset_fd = -1;\nstatic int bg_cpuset_fd = -1;\nstatic int fg_cpuset_fd = -1;\nstatic int ta_cpuset_fd = -1; // special cpuset for top app\nstatic int bg_schedboost_fd = -1;\nstatic int fg_schedboost_fd = -1;\n#endif\n\n/* Add tid to the scheduling group defined by the policy */\nstatic int add_tid_to_cgroup(int tid, int fd)\n{\n    if (fd < 0) {\n        SLOGE(\"add_tid_to_cgroup failed; fd=%d\\n\", fd);\n        errno = EINVAL;\n        return -1;\n    }\n\n    // specialized itoa -- works for tid > 0\n    char text[22];\n    char *end = text + sizeof(text) - 1;\n    char *ptr = end;\n    *ptr = '\\0';\n    while (tid > 0) {\n        *--ptr = '0' + (tid % 10);\n        tid = tid / 10;\n    }\n\n    if (write(fd, ptr, end - ptr) < 0) {\n        /*\n         * If the thread is in the process of exiting,\n         * don't flag an error\n         */\n        if (errno == ESRCH)\n                return 0;\n        SLOGW(\"add_tid_to_cgroup failed to write '%s' (%s); fd=%d\\n\",\n              ptr, strerror(errno), fd);\n        errno = EINVAL;\n        return -1;\n    }\n\n    return 0;\n}\n\nstatic void __initialize(void) {\n    char* filename;\n    if (!access(\"/dev/cpuctl/tasks\", F_OK)) {\n        __sys_supports_schedgroups = 1;\n\n        filename = \"/dev/cpuctl/tasks\";\n        fg_cgroup_fd = open(filename, O_WRONLY | O_CLOEXEC);\n        if (fg_cgroup_fd < 0) {\n            SLOGE(\"open of %s failed: %s\\n\", filename, strerror(errno));\n        }\n\n        filename = \"/dev/cpuctl/bg_non_interactive/tasks\";\n        bg_cgroup_fd = open(filename, O_WRONLY | O_CLOEXEC);\n        if (bg_cgroup_fd < 0) {\n            SLOGE(\"open of %s failed: %s\\n\", filename, strerror(errno));\n        }\n    } else {\n        __sys_supports_schedgroups = 0;\n    }\n\n#ifdef USE_CPUSETS\n    if (!access(\"/dev/cpuset/tasks\", F_OK)) {\n\n        filename = \"/dev/cpuset/foreground/tasks\";\n        fg_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);\n        filename = \"/dev/cpuset/background/tasks\";\n        bg_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);\n        filename = \"/dev/cpuset/system-background/tasks\";\n        system_bg_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);\n        filename = \"/dev/cpuset/top-app/tasks\";\n        ta_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);\n\n#ifdef USE_SCHEDBOOST\n        filename = \"/dev/stune/foreground/tasks\";\n        fg_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC);\n        filename = \"/dev/stune/tasks\";\n        bg_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC);\n#endif\n    }\n#endif\n}\n\n/*\n * Returns the path under the requested cgroup subsystem (if it exists)\n *\n * The data from /proc/<pid>/cgroup looks (something) like:\n *  2:cpu:/bg_non_interactive\n *  1:cpuacct:/\n *\n * We return the part after the \"/\", which will be an empty string for\n * the default cgroup.  If the string is longer than \"bufLen\", the string\n * will be truncated.\n */\nstatic int getCGroupSubsys(int tid, const char* subsys, char* buf, size_t bufLen)\n{\n#if defined(__ANDROID__)\n    char pathBuf[32];\n    char lineBuf[256];\n    FILE *fp;\n\n    snprintf(pathBuf, sizeof(pathBuf), \"/proc/%d/cgroup\", tid);\n    if (!(fp = fopen(pathBuf, \"r\"))) {\n        return -1;\n    }\n\n    while(fgets(lineBuf, sizeof(lineBuf) -1, fp)) {\n        char *next = lineBuf;\n        char *found_subsys;\n        char *grp;\n        size_t len;\n\n        /* Junk the first field */\n        if (!strsep(&next, \":\")) {\n            goto out_bad_data;\n        }\n\n        if (!(found_subsys = strsep(&next, \":\"))) {\n            goto out_bad_data;\n        }\n\n        if (strcmp(found_subsys, subsys)) {\n            /* Not the subsys we're looking for */\n            continue;\n        }\n\n        if (!(grp = strsep(&next, \":\"))) {\n            goto out_bad_data;\n        }\n        grp++; /* Drop the leading '/' */\n        len = strlen(grp);\n        grp[len-1] = '\\0'; /* Drop the trailing '\\n' */\n\n        if (bufLen <= len) {\n            len = bufLen - 1;\n        }\n        strncpy(buf, grp, len);\n        buf[len] = '\\0';\n        fclose(fp);\n        return 0;\n    }\n\n    SLOGE(\"Failed to find subsys %s\", subsys);\n    fclose(fp);\n    return -1;\n out_bad_data:\n    SLOGE(\"Bad cgroup data {%s}\", lineBuf);\n    fclose(fp);\n    return -1;\n#else\n    errno = ENOSYS;\n    return -1;\n#endif\n}\n\nint get_sched_policy(int tid, SchedPolicy *policy)\n{\n    if (tid == 0) {\n        tid = gettid();\n    }\n    pthread_once(&the_once, __initialize);\n\n    if (__sys_supports_schedgroups) {\n        char grpBuf[32];\n#ifdef USE_CPUSETS\n        if (getCGroupSubsys(tid, \"cpuset\", grpBuf, sizeof(grpBuf)) < 0)\n            return -1;\n        if (grpBuf[0] == '\\0') {\n            *policy = SP_FOREGROUND;\n        } else if (!strcmp(grpBuf, \"foreground\")) {\n            *policy = SP_FOREGROUND;\n        } else if (!strcmp(grpBuf, \"background\")) {\n            *policy = SP_BACKGROUND;\n        } else if (!strcmp(grpBuf, \"top-app\")) {\n            *policy = SP_TOP_APP;\n        } else {\n            errno = ERANGE;\n            return -1;\n        }\n#else\n        if (getCGroupSubsys(tid, \"cpu\", grpBuf, sizeof(grpBuf)) < 0)\n            return -1;\n        if (grpBuf[0] == '\\0') {\n            *policy = SP_FOREGROUND;\n        } else if (!strcmp(grpBuf, \"bg_non_interactive\")) {\n            *policy = SP_BACKGROUND;\n        } else {\n            errno = ERANGE;\n            return -1;\n        }\n#endif\n    } else {\n        int rc = sched_getscheduler(tid);\n        if (rc < 0)\n            return -1;\n        else if (rc == SCHED_NORMAL)\n            *policy = SP_FOREGROUND;\n        else if (rc == SCHED_BATCH)\n            *policy = SP_BACKGROUND;\n        else {\n            errno = ERANGE;\n            return -1;\n        }\n    }\n    return 0;\n}\n\nint set_cpuset_policy(int tid, SchedPolicy policy)\n{\n    // in the absence of cpusets, use the old sched policy\n#ifndef USE_CPUSETS\n    return set_sched_policy(tid, policy);\n#else\n    if (tid == 0) {\n        tid = gettid();\n    }\n    policy = _policy(policy);\n    pthread_once(&the_once, __initialize);\n\n    int fd = -1;\n    int boost_fd = -1;\n    switch (policy) {\n    case SP_BACKGROUND:\n        fd = bg_cpuset_fd;\n        boost_fd = bg_schedboost_fd;\n        break;\n    case SP_FOREGROUND:\n    case SP_AUDIO_APP:\n    case SP_AUDIO_SYS:\n        fd = fg_cpuset_fd;\n        boost_fd = fg_schedboost_fd;\n        break;\n    case SP_TOP_APP :\n        fd = ta_cpuset_fd;\n        boost_fd = fg_schedboost_fd;\n        break;\n    case SP_SYSTEM:\n        fd = system_bg_cpuset_fd;\n        boost_fd = bg_schedboost_fd;\n        break;\n    default:\n        boost_fd = fd = -1;\n        break;\n    }\n\n    if (add_tid_to_cgroup(tid, fd) != 0) {\n        if (errno != ESRCH && errno != ENOENT)\n            return -errno;\n    }\n\n    if (boost_fd > 0 && add_tid_to_cgroup(tid, boost_fd) != 0) {\n        if (errno != ESRCH && errno != ENOENT)\n            return -errno;\n    }\n\n    return 0;\n#endif\n}\n\nint set_sched_policy(int tid, SchedPolicy policy)\n{\n    if (tid == 0) {\n        tid = gettid();\n    }\n    policy = _policy(policy);\n    pthread_once(&the_once, __initialize);\n\n#if POLICY_DEBUG\n    char statfile[64];\n    char statline[1024];\n    char thread_name[255];\n    int fd;\n\n    sprintf(statfile, \"/proc/%d/stat\", tid);\n    memset(thread_name, 0, sizeof(thread_name));\n\n    fd = open(statfile, O_RDONLY);\n    if (fd >= 0) {\n        int rc = read(fd, statline, 1023);\n        close(fd);\n        statline[rc] = 0;\n        char *p = statline;\n        char *q;\n\n        for (p = statline; *p != '('; p++);\n        p++;\n        for (q = p; *q != ')'; q++);\n\n        strncpy(thread_name, p, (q-p));\n    }\n    switch (policy) {\n    case SP_BACKGROUND:\n        SLOGD(\"vvv tid %d (%s)\", tid, thread_name);\n        break;\n    case SP_FOREGROUND:\n    case SP_AUDIO_APP:\n    case SP_AUDIO_SYS:\n    case SP_TOP_APP:\n        SLOGD(\"^^^ tid %d (%s)\", tid, thread_name);\n        break;\n    case SP_SYSTEM:\n        SLOGD(\"/// tid %d (%s)\", tid, thread_name);\n        break;\n    default:\n        SLOGD(\"??? tid %d (%s)\", tid, thread_name);\n        break;\n    }\n#endif\n\n    if (__sys_supports_schedgroups) {\n        int fd;\n        switch (policy) {\n        case SP_BACKGROUND:\n            fd = bg_cgroup_fd;\n            break;\n        case SP_FOREGROUND:\n        case SP_AUDIO_APP:\n        case SP_AUDIO_SYS:\n        case SP_TOP_APP:\n            fd = fg_cgroup_fd;\n            break;\n        default:\n            fd = -1;\n            break;\n        }\n\n\n        if (add_tid_to_cgroup(tid, fd) != 0) {\n            if (errno != ESRCH && errno != ENOENT)\n                return -errno;\n        }\n    } else {\n        struct sched_param param;\n\n        param.sched_priority = 0;\n        sched_setscheduler(tid,\n                           (policy == SP_BACKGROUND) ?\n                           SCHED_BATCH : SCHED_NORMAL,\n                           &param);\n    }\n\n    prctl(PR_SET_TIMERSLACK_PID,\n          policy == SP_BACKGROUND ? TIMER_SLACK_BG : TIMER_SLACK_FG, tid);\n\n    return 0;\n}\n\n#else\n\n/* Stubs for non-Android targets. */\n\nint set_sched_policy(int tid UNUSED, SchedPolicy policy UNUSED)\n{\n    return 0;\n}\n\nint get_sched_policy(int tid UNUSED, SchedPolicy *policy)\n{\n    *policy = SP_SYSTEM_DEFAULT;\n    return 0;\n}\n\n#endif\n\nconst char *get_sched_policy_name(SchedPolicy policy)\n{\n    policy = _policy(policy);\n    static const char * const strings[SP_CNT] = {\n       [SP_BACKGROUND] = \"bg\",\n       [SP_FOREGROUND] = \"fg\",\n       [SP_SYSTEM]     = \"  \",\n       [SP_AUDIO_APP]  = \"aa\",\n       [SP_AUDIO_SYS]  = \"as\",\n       [SP_TOP_APP]    = \"ta\",\n    };\n    if ((policy < SP_CNT) && (strings[policy] != NULL))\n        return strings[policy];\n    else\n        return \"error\";\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/socket_inaddr_any_server_unix.c",
    "content": "/*\n** Copyright 2006, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\"); \n** you may not use this file except in compliance with the License. \n** You may obtain a copy of the License at \n**\n**     http://www.apache.org/licenses/LICENSE-2.0 \n**\n** Unless required by applicable law or agreed to in writing, software \n** distributed under the License is distributed on an \"AS IS\" BASIS, \n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n** See the License for the specific language governing permissions and \n** limitations under the License.\n*/\n\n#include <errno.h>\n#include <stddef.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include <sys/socket.h>\n#include <sys/select.h>\n#include <sys/types.h>\n#include <netinet/in.h>\n\n#include <cutils/sockets.h>\n\n#define LISTEN_BACKLOG 4\n\n/* open listen() port on any interface */\nint socket_inaddr_any_server(int port, int type)\n{\n    struct sockaddr_in6 addr;\n    int s, n;\n\n    memset(&addr, 0, sizeof(addr));\n    addr.sin6_family = AF_INET6;\n    addr.sin6_port = htons(port);\n    addr.sin6_addr = in6addr_any;\n\n    s = socket(AF_INET6, type, 0);\n    if (s < 0) return -1;\n\n    n = 1;\n    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof(n));\n\n    if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {\n        close(s);\n        return -1;\n    }\n\n    if (type == SOCK_STREAM) {\n        int ret;\n\n        ret = listen(s, LISTEN_BACKLOG);\n\n        if (ret < 0) {\n            close(s);\n            return -1; \n        }\n    }\n\n    return s;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/socket_inaddr_any_server_windows.c",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n\n#include <cutils/sockets.h>\n\n#define LISTEN_BACKLOG 4\n\nextern bool initialize_windows_sockets();\n\nSOCKET socket_inaddr_any_server(int port, int type) {\n    if (!initialize_windows_sockets()) {\n      return INVALID_SOCKET;\n    }\n\n    SOCKET sock = socket(AF_INET6, type, 0);\n    if (sock == INVALID_SOCKET) {\n        return INVALID_SOCKET;\n    }\n\n    // Enforce exclusive addresses so nobody can steal the port from us (1),\n    // and enable dual-stack so both IPv4 and IPv6 work (2).\n    // (1) https://msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx.\n    // (2) https://msdn.microsoft.com/en-us/library/windows/desktop/bb513665(v=vs.85).aspx.\n    int exclusive = 1;\n    DWORD v6_only = 0;\n    if (setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&exclusive,\n                   sizeof(exclusive)) == SOCKET_ERROR ||\n        setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&v6_only,\n                   sizeof(v6_only)) == SOCKET_ERROR) {\n        closesocket(sock);\n        return INVALID_SOCKET;\n    }\n\n    // Bind the socket to our local port.\n    struct sockaddr_in6 addr;\n    memset(&addr, 0, sizeof(addr));\n    addr.sin6_family = AF_INET6;\n    addr.sin6_port = htons(port);\n    addr.sin6_addr = in6addr_any;\n    if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) {\n        closesocket(sock);\n        return INVALID_SOCKET;\n    }\n\n    // Start listening for connections if this is a TCP socket.\n    if (type == SOCK_STREAM && listen(sock, LISTEN_BACKLOG) == SOCKET_ERROR) {\n        closesocket(sock);\n        return INVALID_SOCKET;\n    }\n\n    return sock;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/socket_local_client_unix.c",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <errno.h>\n#include <stddef.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include <cutils/sockets.h>\n\n#if defined(_WIN32)\n\nint socket_local_client(const char *name, int namespaceId, int type)\n{\n    errno = ENOSYS;\n    return -1;\n}\n\n#else /* !_WIN32 */\n\n#include <sys/socket.h>\n#include <sys/un.h>\n#include <sys/select.h>\n#include <sys/types.h>\n\n#include \"socket_local_unix.h\"\n\n#define UNUSED __attribute__((unused))\n\n#define LISTEN_BACKLOG 4\n\n/* Documented in header file. */\nint socket_make_sockaddr_un(const char *name, int namespaceId, \n        struct sockaddr_un *p_addr, socklen_t *alen)\n{\n    memset (p_addr, 0, sizeof (*p_addr));\n    size_t namelen;\n\n    switch (namespaceId) {\n        case ANDROID_SOCKET_NAMESPACE_ABSTRACT:\n#if defined(__linux__)\n            namelen  = strlen(name);\n\n            // Test with length +1 for the *initial* '\\0'.\n            if ((namelen + 1) > sizeof(p_addr->sun_path)) {\n                goto error;\n            }\n\n            /*\n             * Note: The path in this case is *not* supposed to be\n             * '\\0'-terminated. (\"man 7 unix\" for the gory details.)\n             */\n            \n            p_addr->sun_path[0] = 0;\n            memcpy(p_addr->sun_path + 1, name, namelen);\n#else\n            /* this OS doesn't have the Linux abstract namespace */\n\n            namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX);\n            /* unix_path_max appears to be missing on linux */\n            if (namelen > sizeof(*p_addr) \n                    - offsetof(struct sockaddr_un, sun_path) - 1) {\n                goto error;\n            }\n\n            strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX);\n            strcat(p_addr->sun_path, name);\n#endif\n        break;\n\n        case ANDROID_SOCKET_NAMESPACE_RESERVED:\n            namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX);\n            /* unix_path_max appears to be missing on linux */\n            if (namelen > sizeof(*p_addr) \n                    - offsetof(struct sockaddr_un, sun_path) - 1) {\n                goto error;\n            }\n\n            strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX);\n            strcat(p_addr->sun_path, name);\n        break;\n\n        case ANDROID_SOCKET_NAMESPACE_FILESYSTEM:\n            namelen = strlen(name);\n            /* unix_path_max appears to be missing on linux */\n            if (namelen > sizeof(*p_addr) \n                    - offsetof(struct sockaddr_un, sun_path) - 1) {\n                goto error;\n            }\n\n            strcpy(p_addr->sun_path, name);\n        break;\n        default:\n            // invalid namespace id\n            return -1;\n    }\n\n    p_addr->sun_family = AF_LOCAL;\n    *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;\n    return 0;\nerror:\n    return -1;\n}\n\n/**\n * connect to peer named \"name\" on fd\n * returns same fd or -1 on error.\n * fd is not closed on error. that's your job.\n * \n * Used by AndroidSocketImpl\n */\nint socket_local_client_connect(int fd, const char *name, int namespaceId, \n        int type UNUSED)\n{\n    struct sockaddr_un addr;\n    socklen_t alen;\n    int err;\n\n    err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);\n\n    if (err < 0) {\n        goto error;\n    }\n\n    if(connect(fd, (struct sockaddr *) &addr, alen) < 0) {\n        goto error;\n    }\n\n    return fd;\n\nerror:\n    return -1;\n}\n\n/** \n * connect to peer named \"name\"\n * returns fd or -1 on error\n */\nint socket_local_client(const char *name, int namespaceId, int type)\n{\n    int s;\n\n    s = socket(AF_LOCAL, type, 0);\n    if(s < 0) return -1;\n\n    if ( 0 > socket_local_client_connect(s, name, namespaceId, type)) {\n        close(s);\n        return -1;\n    }\n\n    return s;\n}\n\n#endif /* !_WIN32 */\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/socket_local_server_unix.c",
    "content": "/* libs/cutils/socket_local_server.c\n**\n** Copyright 2006, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\"); \n** you may not use this file except in compliance with the License. \n** You may obtain a copy of the License at \n**\n**     http://www.apache.org/licenses/LICENSE-2.0 \n**\n** Unless required by applicable law or agreed to in writing, software \n** distributed under the License is distributed on an \"AS IS\" BASIS, \n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n** See the License for the specific language governing permissions and \n** limitations under the License.\n*/\n\n#include <cutils/sockets.h>\n\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n#include <errno.h>\n#include <stddef.h>\n\n#if defined(_WIN32)\n\nint socket_local_server(const char *name, int namespaceId, int type)\n{\n    errno = ENOSYS;\n    return -1;\n}\n\n#else /* !_WIN32 */\n\n#include <sys/socket.h>\n#include <sys/un.h>\n#include <sys/select.h>\n#include <sys/types.h>\n#include <netinet/in.h>\n\n#include \"socket_local_unix.h\"\n\n#define LISTEN_BACKLOG 4\n\n/* Only the bottom bits are really the socket type; there are flags too. */\n#define SOCK_TYPE_MASK 0xf\n\n/**\n * Binds a pre-created socket(AF_LOCAL) 's' to 'name'\n * returns 's' on success, -1 on fail\n *\n * Does not call listen()\n */\nint socket_local_server_bind(int s, const char *name, int namespaceId)\n{\n    struct sockaddr_un addr;\n    socklen_t alen;\n    int n;\n    int err;\n\n    err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);\n\n    if (err < 0) {\n        return -1;\n    }\n\n    /* basically: if this is a filesystem path, unlink first */\n#if !defined(__linux__)\n    if (1) {\n#else\n    if (namespaceId == ANDROID_SOCKET_NAMESPACE_RESERVED\n        || namespaceId == ANDROID_SOCKET_NAMESPACE_FILESYSTEM) {\n#endif\n        /*ignore ENOENT*/\n        unlink(addr.sun_path);\n    }\n\n    n = 1;\n    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));\n\n    if(bind(s, (struct sockaddr *) &addr, alen) < 0) {\n        return -1;\n    }\n\n    return s;\n\n}\n\n\n/** Open a server-side UNIX domain datagram socket in the Linux non-filesystem \n *  namespace\n *\n *  Returns fd on success, -1 on fail\n */\n\nint socket_local_server(const char *name, int namespace, int type)\n{\n    int err;\n    int s;\n    \n    s = socket(AF_LOCAL, type, 0);\n    if (s < 0) return -1;\n\n    err = socket_local_server_bind(s, name, namespace);\n\n    if (err < 0) {\n        close(s);\n        return -1;\n    }\n\n    if ((type & SOCK_TYPE_MASK) == SOCK_STREAM) {\n        int ret;\n\n        ret = listen(s, LISTEN_BACKLOG);\n\n        if (ret < 0) {\n            close(s);\n            return -1;\n        }\n    }\n\n    return s;\n}\n\n#endif /* !_WIN32 */\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/socket_local_unix.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __SOCKET_LOCAL_H\n#define __SOCKET_LOCAL_H\n\n#define FILESYSTEM_SOCKET_PREFIX \"/tmp/\" \n#define ANDROID_RESERVED_SOCKET_PREFIX \"/dev/socket/\"\n\n/*\n * Set up a given sockaddr_un, to have it refer to the given\n * name in the given namespace. The namespace must be one\n * of <code>ANDROID_SOCKET_NAMESPACE_ABSTRACT</code>,\n * <code>ANDROID_SOCKET_NAMESPACE_RESERVED</code>, or\n * <code>ANDROID_SOCKET_NAMESPACE_FILESYSTEM</code>. Upon success,\n * the pointed at sockaddr_un is filled in and the pointed at\n * socklen_t is set to indicate the final length. This function\n * will fail if the namespace is invalid (not one of the indicated\n * constants) or if the name is too long.\n * \n * @return 0 on success or -1 on failure\n */ \nint socket_make_sockaddr_un(const char *name, int namespaceId, \n        struct sockaddr_un *p_addr, socklen_t *alen);\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/socket_loopback_client_unix.c",
    "content": "/*\n** Copyright 2006, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\"); \n** you may not use this file except in compliance with the License. \n** You may obtain a copy of the License at \n**\n**     http://www.apache.org/licenses/LICENSE-2.0 \n**\n** Unless required by applicable law or agreed to in writing, software \n** distributed under the License is distributed on an \"AS IS\" BASIS, \n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n** See the License for the specific language governing permissions and \n** limitations under the License.\n*/\n\n#include <errno.h>\n#include <stddef.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#if !defined(_WIN32)\n#include <sys/socket.h>\n#include <sys/select.h>\n#include <sys/types.h>\n#include <netinet/in.h>\n#endif\n\n#include <cutils/sockets.h>\n\n/* Connect to port on the loopback IP interface. type is\n * SOCK_STREAM or SOCK_DGRAM. \n * return is a file descriptor or -1 on error\n */\nint socket_loopback_client(int port, int type)\n{\n    struct sockaddr_in addr;\n    int s;\n\n    memset(&addr, 0, sizeof(addr));\n    addr.sin_family = AF_INET;\n    addr.sin_port = htons(port);\n    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);\n\n    s = socket(AF_INET, type, 0);\n    if(s < 0) return -1;\n\n    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {\n        close(s);\n        return -1;\n    }\n\n    return s;\n\n}\n\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/socket_loopback_server_unix.c",
    "content": "/*\n** Copyright 2006, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\"); \n** you may not use this file except in compliance with the License. \n** You may obtain a copy of the License at \n**\n**     http://www.apache.org/licenses/LICENSE-2.0 \n**\n** Unless required by applicable law or agreed to in writing, software \n** distributed under the License is distributed on an \"AS IS\" BASIS, \n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n** See the License for the specific language governing permissions and \n** limitations under the License.\n*/\n\n#include <errno.h>\n#include <stddef.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#define LISTEN_BACKLOG 4\n\n#if !defined(_WIN32)\n#include <sys/socket.h>\n#include <sys/select.h>\n#include <sys/types.h>\n#include <netinet/in.h>\n#endif\n\n#include <cutils/sockets.h>\n\n/* open listen() port on loopback interface */\nint socket_loopback_server(int port, int type)\n{\n    struct sockaddr_in addr;\n    int s, n;\n\n    memset(&addr, 0, sizeof(addr));\n    addr.sin_family = AF_INET;\n    addr.sin_port = htons(port);\n    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);\n\n    s = socket(AF_INET, type, 0);\n    if(s < 0) return -1;\n\n    n = 1;\n    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof(n));\n\n    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {\n        close(s);\n        return -1;\n    }\n\n    if (type == SOCK_STREAM) {\n        int ret;\n\n        ret = listen(s, LISTEN_BACKLOG);\n\n        if (ret < 0) {\n            close(s);\n            return -1; \n        }\n    }\n\n    return s;\n}\n\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/socket_network_client_unix.c",
    "content": "/*\n** Copyright 2006, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\"); \n** you may not use this file except in compliance with the License. \n** You may obtain a copy of the License at \n**\n**     http://www.apache.org/licenses/LICENSE-2.0 \n**\n** Unless required by applicable law or agreed to in writing, software \n** distributed under the License is distributed on an \"AS IS\" BASIS, \n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n** See the License for the specific language governing permissions and \n** limitations under the License.\n*/\n\n#include <errno.h>\n#include <fcntl.h>\n#include <stddef.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include <sys/socket.h>\n#include <sys/select.h>\n#include <sys/types.h>\n#include <netinet/in.h>\n#include <netdb.h>\n\n#include <cutils/sockets.h>\n\nstatic int toggle_O_NONBLOCK(int s) {\n    int flags = fcntl(s, F_GETFL);\n    if (flags == -1 || fcntl(s, F_SETFL, flags ^ O_NONBLOCK) == -1) {\n        close(s);\n        return -1;\n    }\n    return s;\n}\n\n// Connect to the given host and port.\n// 'timeout' is in seconds (0 for no timeout).\n// Returns a file descriptor or -1 on error.\n// On error, check *getaddrinfo_error (for use with gai_strerror) first;\n// if that's 0, use errno instead.\nint socket_network_client_timeout(const char* host, int port, int type, int timeout,\n                                  int* getaddrinfo_error) {\n    struct addrinfo hints;\n    memset(&hints, 0, sizeof(hints));\n    hints.ai_family = AF_UNSPEC;\n    hints.ai_socktype = type;\n\n    char port_str[16];\n    snprintf(port_str, sizeof(port_str), \"%d\", port);\n\n    struct addrinfo* addrs;\n    *getaddrinfo_error = getaddrinfo(host, port_str, &hints, &addrs);\n    if (*getaddrinfo_error != 0) {\n        return -1;\n    }\n\n    // TODO: try all the addresses if there's more than one?\n    int family = addrs[0].ai_family;\n    int protocol = addrs[0].ai_protocol;\n    socklen_t addr_len = addrs[0].ai_addrlen;\n    struct sockaddr_storage addr;\n    memcpy(&addr, addrs[0].ai_addr, addr_len);\n\n    freeaddrinfo(addrs);\n\n    // The Mac doesn't have SOCK_NONBLOCK.\n    int s = socket(family, type, protocol);\n    if (s == -1 || toggle_O_NONBLOCK(s) == -1) return -1;\n\n    int rc = connect(s, (const struct sockaddr*) &addr, addr_len);\n    if (rc == 0) {\n        return toggle_O_NONBLOCK(s);\n    } else if (rc == -1 && errno != EINPROGRESS) {\n        close(s);\n        return -1;\n    }\n\n    fd_set r_set;\n    FD_ZERO(&r_set);\n    FD_SET(s, &r_set);\n    fd_set w_set = r_set;\n\n    struct timeval ts;\n    ts.tv_sec = timeout;\n    ts.tv_usec = 0;\n    if ((rc = select(s + 1, &r_set, &w_set, NULL, (timeout != 0) ? &ts : NULL)) == -1) {\n        close(s);\n        return -1;\n    }\n    if (rc == 0) {   // we had a timeout\n        errno = ETIMEDOUT;\n        close(s);\n        return -1;\n    }\n\n    int error = 0;\n    socklen_t len = sizeof(error);\n    if (FD_ISSET(s, &r_set) || FD_ISSET(s, &w_set)) {\n        if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {\n            close(s);\n            return -1;\n        }\n    } else {\n        close(s);\n        return -1;\n    }\n\n    if (error) {  // check if we had a socket error\n        errno = error;\n        close(s);\n        return -1;\n    }\n\n    return toggle_O_NONBLOCK(s);\n}\n\nint socket_network_client(const char* host, int port, int type) {\n    int getaddrinfo_error;\n    return socket_network_client_timeout(host, port, type, 0, &getaddrinfo_error);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/socket_network_client_windows.c",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <cutils/sockets.h>\n\nextern bool initialize_windows_sockets();\n\nSOCKET socket_network_client(const char* host, int port, int type) {\n    if (!initialize_windows_sockets()) {\n        return INVALID_SOCKET;\n    }\n\n    // First resolve the host and port parameters into a usable network address.\n    struct addrinfo hints;\n    memset(&hints, 0, sizeof(hints));\n    hints.ai_socktype = type;\n\n    struct addrinfo* address = NULL;\n    char port_str[16];\n    snprintf(port_str, sizeof(port_str), \"%d\", port);\n    if (getaddrinfo(host, port_str, &hints, &address) != 0 || address == NULL) {\n        if (address != NULL) {\n            freeaddrinfo(address);\n        }\n        return INVALID_SOCKET;\n    }\n\n    // Now create and connect the socket.\n    SOCKET sock = socket(address->ai_family, address->ai_socktype,\n                         address->ai_protocol);\n    if (sock == INVALID_SOCKET) {\n        freeaddrinfo(address);\n        return INVALID_SOCKET;\n    }\n\n    if (connect(sock, address->ai_addr, address->ai_addrlen) == SOCKET_ERROR) {\n        closesocket(sock);\n        freeaddrinfo(address);\n        return INVALID_SOCKET;\n    }\n\n    freeaddrinfo(address);\n    return sock;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/sockets.cpp",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n// This file contains socket implementation that can be shared between\n// platforms as long as the correct headers are included.\n\n#include <cutils/sockets.h>\n\n#if !defined(_WIN32)\n#include <netinet/in.h>\n#endif\n\nint socket_get_local_port(cutils_socket_t sock) {\n    sockaddr_storage addr;\n    socklen_t addr_size = sizeof(addr);\n\n    if (getsockname(sock, reinterpret_cast<sockaddr*>(&addr), &addr_size) == 0) {\n        // sockaddr_in and sockaddr_in6 always overlap the port field.\n        return ntohs(reinterpret_cast<sockaddr_in*>(&addr)->sin_port);\n    }\n    return -1;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/sockets_unix.cpp",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <cutils/sockets.h>\n\n#include <sys/uio.h>\n\n#include <log/log.h>\n\n#if defined(__ANDROID__)\n/* For the socket trust (credentials) check */\n#include <private/android_filesystem_config.h>\n#define __android_unused\n#else\n#define __android_unused __attribute__((__unused__))\n#endif\n\nbool socket_peer_is_trusted(int fd __android_unused) {\n#if defined(__ANDROID__)\n    ucred cr;\n    socklen_t len = sizeof(cr);\n    int n = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len);\n\n    if (n != 0) {\n        ALOGE(\"could not get socket credentials: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    if ((cr.uid != AID_ROOT) && (cr.uid != AID_SHELL)) {\n        ALOGE(\"untrusted userid on other end of socket: userid %d\\n\", cr.uid);\n        return false;\n    }\n#endif\n\n    return true;\n}\n\nint socket_close(int sock) {\n    return close(sock);\n}\n\nint socket_set_receive_timeout(cutils_socket_t sock, int timeout_ms) {\n    timeval tv;\n    tv.tv_sec = timeout_ms / 1000;\n    tv.tv_usec = (timeout_ms % 1000) * 1000;\n    return setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));\n}\n\nssize_t socket_send_buffers(cutils_socket_t sock,\n                            const cutils_socket_buffer_t* buffers,\n                            size_t num_buffers) {\n    if (num_buffers > SOCKET_SEND_BUFFERS_MAX_BUFFERS) {\n        return -1;\n    }\n\n    iovec iovec_buffers[SOCKET_SEND_BUFFERS_MAX_BUFFERS];\n    for (size_t i = 0; i < num_buffers; ++i) {\n        // It's safe to cast away const here; iovec declares non-const\n        // void* because it's used for both send and receive, but since\n        // we're only sending, the data won't be modified.\n        iovec_buffers[i].iov_base = const_cast<void*>(buffers[i].data);\n        iovec_buffers[i].iov_len = buffers[i].length;\n    }\n\n    return writev(sock, iovec_buffers, num_buffers);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/sockets_windows.cpp",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *  * Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *  * Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in\n *    the documentation and/or other materials provided with the\n *    distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <cutils/sockets.h>\n\n// https://msdn.microsoft.com/en-us/library/windows/desktop/ms741549(v=vs.85).aspx\n// claims WSACleanup() should be called before program exit, but general\n// consensus seems to be that it hasn't actually been necessary for a long time,\n// likely since Windows 3.1. Additionally, trying to properly use WSACleanup()\n// can be extremely tricky and cause deadlock when using threads or atexit().\n//\n// Both adb (1) and Chrome (2) purposefully avoid WSACleanup() with no issues.\n// (1) https://android.googlesource.com/platform/system/core.git/+/master/adb/sysdeps_win32.cpp\n// (2) https://code.google.com/p/chromium/codesearch#chromium/src/net/base/winsock_init.cc\nextern \"C\" bool initialize_windows_sockets() {\n    // There's no harm in calling WSAStartup() multiple times but no benefit\n    // either, we may as well skip it after the first.\n    static bool init_success = false;\n\n    if (!init_success) {\n        WSADATA wsaData;\n        init_success = (WSAStartup(MAKEWORD(2, 2), &wsaData) == 0);\n    }\n\n    return init_success;\n}\n\nint socket_close(cutils_socket_t sock) {\n    return closesocket(sock);\n}\n\nint socket_set_receive_timeout(cutils_socket_t sock, int timeout_ms) {\n    return setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,\n                      reinterpret_cast<char*>(&timeout_ms), sizeof(timeout_ms));\n}\n\nssize_t socket_send_buffers(cutils_socket_t sock,\n                            const cutils_socket_buffer_t* buffers,\n                            size_t num_buffers) {\n    if (num_buffers > SOCKET_SEND_BUFFERS_MAX_BUFFERS) {\n        return -1;\n    }\n\n    WSABUF wsa_buffers[SOCKET_SEND_BUFFERS_MAX_BUFFERS];\n    for (size_t i = 0; i < num_buffers; ++i) {\n        // It's safe to cast away const here; WSABUF declares non-const\n        // void* because it's used for both send and receive, but since\n        // we're only sending, the data won't be modified.\n        wsa_buffers[i].buf =\n                reinterpret_cast<char*>(const_cast<void*>(buffers[i].data));\n        wsa_buffers[i].len = buffers[i].length;\n    }\n\n    DWORD bytes_sent = 0;\n    if (WSASend(sock, wsa_buffers, num_buffers, &bytes_sent, 0, nullptr,\n                nullptr) != SOCKET_ERROR) {\n        return bytes_sent;\n    }\n\n    return -1;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/str_parms.c",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"str_params\"\n//#define LOG_NDEBUG 0\n\n#define _GNU_SOURCE 1\n#include <errno.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <cutils/hashmap.h>\n#include <cutils/memory.h>\n#include <cutils/str_parms.h>\n#include <log/log.h>\n\n#define UNUSED __attribute__((unused))\n\n/* When an object is allocated but not freed in a function,\n * because its ownership is released to other object like a hashmap,\n * call RELEASE_OWNERSHIP to tell the clang analyzer and avoid\n * false warnings about potential memory leak.\n * For now, a \"temporary\" assignment to global variables\n * is enough to confuse the clang static analyzer.\n */\n#ifdef __clang_analyzer__\nstatic void *released_pointer;\n#define RELEASE_OWNERSHIP(x) { released_pointer = x; released_pointer = 0; }\n#else\n#define RELEASE_OWNERSHIP(x)\n#endif\n\nstruct str_parms {\n    Hashmap *map;\n};\n\n\nstatic bool str_eq(void *key_a, void *key_b)\n{\n    return !strcmp((const char *)key_a, (const char *)key_b);\n}\n\n/* use djb hash unless we find it inadequate */\n#ifdef __clang__\n__attribute__((no_sanitize(\"integer\")))\n#endif\nstatic int str_hash_fn(void *str)\n{\n    uint32_t hash = 5381;\n    char *p;\n\n    for (p = str; p && *p; p++)\n        hash = ((hash << 5) + hash) + *p;\n    return (int)hash;\n}\n\nstruct str_parms *str_parms_create(void)\n{\n    struct str_parms *str_parms;\n\n    str_parms = calloc(1, sizeof(struct str_parms));\n    if (!str_parms)\n        return NULL;\n\n    str_parms->map = hashmapCreate(5, str_hash_fn, str_eq);\n    if (!str_parms->map)\n        goto err;\n\n    return str_parms;\n\nerr:\n    free(str_parms);\n    return NULL;\n}\n\nstruct remove_ctxt {\n    struct str_parms *str_parms;\n    const char *key;\n};\n\nstatic bool remove_pair(void *key, void *value, void *context)\n{\n    struct remove_ctxt *ctxt = context;\n    bool should_continue;\n\n    /*\n     * - if key is not supplied, then we are removing all entries,\n     *   so remove key and continue (i.e. return true)\n     * - if key is supplied and matches, then remove it and don't\n     *   continue (return false). Otherwise, return true and keep searching\n     *   for key.\n     *\n     */\n    if (!ctxt->key) {\n        should_continue = true;\n        goto do_remove;\n    } else if (!strcmp(ctxt->key, key)) {\n        should_continue = false;\n        goto do_remove;\n    }\n\n    return true;\n\ndo_remove:\n    hashmapRemove(ctxt->str_parms->map, key);\n    free(key);\n    free(value);\n    return should_continue;\n}\n\nvoid str_parms_del(struct str_parms *str_parms, const char *key)\n{\n    struct remove_ctxt ctxt = {\n        .str_parms = str_parms,\n        .key = key,\n    };\n    hashmapForEach(str_parms->map, remove_pair, &ctxt);\n}\n\nvoid str_parms_destroy(struct str_parms *str_parms)\n{\n    struct remove_ctxt ctxt = {\n        .str_parms = str_parms,\n    };\n\n    hashmapForEach(str_parms->map, remove_pair, &ctxt);\n    hashmapFree(str_parms->map);\n    free(str_parms);\n}\n\nstruct str_parms *str_parms_create_str(const char *_string)\n{\n    struct str_parms *str_parms;\n    char *str;\n    char *kvpair;\n    char *tmpstr;\n    int items = 0;\n\n    str_parms = str_parms_create();\n    if (!str_parms)\n        goto err_create_str_parms;\n\n    str = strdup(_string);\n    if (!str)\n        goto err_strdup;\n\n    ALOGV(\"%s: source string == '%s'\\n\", __func__, _string);\n\n    kvpair = strtok_r(str, \";\", &tmpstr);\n    while (kvpair && *kvpair) {\n        char *eq = strchr(kvpair, '='); /* would love strchrnul */\n        char *value;\n        char *key;\n        void *old_val;\n\n        if (eq == kvpair)\n            goto next_pair;\n\n        if (eq) {\n            key = strndup(kvpair, eq - kvpair);\n            if (*(++eq))\n                value = strdup(eq);\n            else\n                value = strdup(\"\");\n        } else {\n            key = strdup(kvpair);\n            value = strdup(\"\");\n        }\n\n        /* if we replaced a value, free it */\n        old_val = hashmapPut(str_parms->map, key, value);\n        RELEASE_OWNERSHIP(value);\n        if (old_val) {\n            free(old_val);\n            free(key);\n        } else {\n            RELEASE_OWNERSHIP(key);\n        }\n\n        items++;\nnext_pair:\n        kvpair = strtok_r(NULL, \";\", &tmpstr);\n    }\n\n    if (!items)\n        ALOGV(\"%s: no items found in string\\n\", __func__);\n\n    free(str);\n\n    return str_parms;\n\nerr_strdup:\n    str_parms_destroy(str_parms);\nerr_create_str_parms:\n    return NULL;\n}\n\nint str_parms_add_str(struct str_parms *str_parms, const char *key,\n                      const char *value)\n{\n    void *tmp_key = NULL;\n    void *tmp_val = NULL;\n    void *old_val = NULL;\n\n    // strdup and hashmapPut both set errno on failure.\n    // Set errno to 0 so we can recognize whether anything went wrong.\n    int saved_errno = errno;\n    errno = 0;\n\n    tmp_key = strdup(key);\n    if (tmp_key == NULL) {\n        goto clean_up;\n    }\n\n    tmp_val = strdup(value);\n    if (tmp_val == NULL) {\n        goto clean_up;\n    }\n\n    old_val = hashmapPut(str_parms->map, tmp_key, tmp_val);\n    if (old_val == NULL) {\n        // Did hashmapPut fail?\n        if (errno == ENOMEM) {\n            goto clean_up;\n        }\n        // For new keys, hashmap takes ownership of tmp_key and tmp_val.\n        RELEASE_OWNERSHIP(tmp_key);\n        RELEASE_OWNERSHIP(tmp_val);\n        tmp_key = tmp_val = NULL;\n    } else {\n        // For existing keys, hashmap takes ownership of tmp_val.\n        // (It also gives up ownership of old_val.)\n        RELEASE_OWNERSHIP(tmp_val);\n        tmp_val = NULL;\n    }\n\nclean_up:\n    free(tmp_key);\n    free(tmp_val);\n    free(old_val);\n    int result = -errno;\n    errno = saved_errno;\n    return result;\n}\n\nint str_parms_add_int(struct str_parms *str_parms, const char *key, int value)\n{\n    char val_str[12];\n    int ret;\n\n    ret = snprintf(val_str, sizeof(val_str), \"%d\", value);\n    if (ret < 0)\n        return -EINVAL;\n\n    ret = str_parms_add_str(str_parms, key, val_str);\n    return ret;\n}\n\nint str_parms_add_float(struct str_parms *str_parms, const char *key,\n                        float value)\n{\n    char val_str[23];\n    int ret;\n\n    ret = snprintf(val_str, sizeof(val_str), \"%.10f\", value);\n    if (ret < 0)\n        return -EINVAL;\n\n    ret = str_parms_add_str(str_parms, key, val_str);\n    return ret;\n}\n\nint str_parms_has_key(struct str_parms *str_parms, const char *key) {\n    return hashmapGet(str_parms->map, (void *)key) != NULL;\n}\n\nint str_parms_get_str(struct str_parms *str_parms, const char *key, char *val,\n                      int len)\n{\n    char *value;\n\n    value = hashmapGet(str_parms->map, (void *)key);\n    if (value)\n        return strlcpy(val, value, len);\n\n    return -ENOENT;\n}\n\nint str_parms_get_int(struct str_parms *str_parms, const char *key, int *val)\n{\n    char *value;\n    char *end;\n\n    value = hashmapGet(str_parms->map, (void *)key);\n    if (!value)\n        return -ENOENT;\n\n    *val = (int)strtol(value, &end, 0);\n    if (*value != '\\0' && *end == '\\0')\n        return 0;\n\n    return -EINVAL;\n}\n\nint str_parms_get_float(struct str_parms *str_parms, const char *key,\n                        float *val)\n{\n    float out;\n    char *value;\n    char *end;\n\n    value = hashmapGet(str_parms->map, (void *)key);\n    if (!value)\n        return -ENOENT;\n\n    out = strtof(value, &end);\n    if (*value == '\\0' || *end != '\\0')\n        return -EINVAL;\n\n    *val = out;\n    return 0;\n}\n\nstatic bool combine_strings(void *key, void *value, void *context)\n{\n    char **old_str = context;\n    char *new_str;\n    int ret;\n\n    ret = asprintf(&new_str, \"%s%s%s=%s\",\n                   *old_str ? *old_str : \"\",\n                   *old_str ? \";\" : \"\",\n                   (char *)key,\n                   (char *)value);\n    if (*old_str)\n        free(*old_str);\n\n    if (ret >= 0) {\n        *old_str = new_str;\n        return true;\n    }\n\n    *old_str = NULL;\n    return false;\n}\n\nchar *str_parms_to_str(struct str_parms *str_parms)\n{\n    char *str = NULL;\n\n    if (hashmapSize(str_parms->map) > 0)\n        hashmapForEach(str_parms->map, combine_strings, &str);\n    else\n        str = strdup(\"\");\n    return str;\n}\n\nstatic bool dump_entry(void *key, void *value, void *context UNUSED)\n{\n    ALOGI(\"key: '%s' value: '%s'\\n\", (char *)key, (char *)value);\n    return true;\n}\n\nvoid str_parms_dump(struct str_parms *str_parms)\n{\n    hashmapForEach(str_parms->map, dump_entry, str_parms);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/strdup16to8.c",
    "content": "/* libs/cutils/strdup16to8.c\n**\n** Copyright 2006, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\"); \n** you may not use this file except in compliance with the License. \n** You may obtain a copy of the License at \n**\n**     http://www.apache.org/licenses/LICENSE-2.0 \n**\n** Unless required by applicable law or agreed to in writing, software \n** distributed under the License is distributed on an \"AS IS\" BASIS, \n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n** See the License for the specific language governing permissions and \n** limitations under the License.\n*/\n\n#include <limits.h>  /* for SIZE_MAX */\n\n#include <cutils/jstring.h>\n#include <assert.h>\n#include <stdlib.h>\n\n\n/**\n * Given a UTF-16 string, compute the length of the corresponding UTF-8\n * string in bytes.\n */\nextern size_t strnlen16to8(const char16_t* utf16Str, size_t len)\n{\n    size_t utf8Len = 0;\n\n    /* A small note on integer overflow. The result can\n     * potentially be as big as 3*len, which will overflow\n     * for len > SIZE_MAX/3.\n     *\n     * Moreover, the result of a strnlen16to8 is typically used\n     * to allocate a destination buffer to strncpy16to8 which\n     * requires one more byte to terminate the UTF-8 copy, and\n     * this is generally done by careless users by incrementing\n     * the result without checking for integer overflows, e.g.:\n     *\n     *   dst = malloc(strnlen16to8(utf16,len)+1)\n     *\n     * Due to this, the following code will try to detect\n     * overflows, and never return more than (SIZE_MAX-1)\n     * when it detects one. A careless user will try to malloc\n     * SIZE_MAX bytes, which will return NULL which can at least\n     * be detected appropriately.\n     *\n     * As far as I know, this function is only used by strndup16(),\n     * but better be safe than sorry.\n     */\n\n    /* Fast path for the usual case where 3*len is < SIZE_MAX-1.\n     */\n    if (len < (SIZE_MAX-1)/3) {\n        while (len != 0) {\n            len--;\n            unsigned int uic = *utf16Str++;\n\n            if (uic > 0x07ff)\n                utf8Len += 3;\n            else if (uic > 0x7f || uic == 0)\n                utf8Len += 2;\n            else\n                utf8Len++;\n        }\n        return utf8Len;\n    }\n\n    /* The slower but paranoid version */\n    while (len != 0) {\n        len--;\n        unsigned int  uic     = *utf16Str++;\n        size_t        utf8Cur = utf8Len;\n\n        if (uic > 0x07ff)\n            utf8Len += 3;\n        else if (uic > 0x7f || uic == 0)\n            utf8Len += 2;\n        else\n            utf8Len++;\n\n        if (utf8Len < utf8Cur) /* overflow detected */\n            return SIZE_MAX-1;\n    }\n\n    /* don't return SIZE_MAX to avoid common user bug */\n    if (utf8Len == SIZE_MAX)\n        utf8Len = SIZE_MAX-1;\n\n    return utf8Len;\n}\n\n\n/**\n * Convert a Java-Style UTF-16 string + length to a JNI-Style UTF-8 string.\n *\n * This basically means: embedded \\0's in the UTF-16 string are encoded\n * as \"0xc0 0x80\"\n *\n * Make sure you allocate \"utf8Str\" with the result of strlen16to8() + 1,\n * not just \"len\".\n *\n * Please note, a terminated \\0 is always added, so your result will always\n * be \"strlen16to8() + 1\" bytes long.\n */\nextern char* strncpy16to8(char* utf8Str, const char16_t* utf16Str, size_t len)\n{\n    char* utf8cur = utf8Str;\n\n    /* Note on overflows: We assume the user did check the result of\n     * strnlen16to8() properly or at a minimum checked the result of\n     * its malloc(SIZE_MAX) in case of overflow.\n     */\n    while (len != 0) {\n        len--;\n        unsigned int uic = *utf16Str++;\n\n        if (uic > 0x07ff) {\n            *utf8cur++ = (uic >> 12) | 0xe0;\n            *utf8cur++ = ((uic >> 6) & 0x3f) | 0x80;\n            *utf8cur++ = (uic & 0x3f) | 0x80;\n        } else if (uic > 0x7f || uic == 0) {\n            *utf8cur++ = (uic >> 6) | 0xc0;\n            *utf8cur++ = (uic & 0x3f) | 0x80;\n        } else {\n            *utf8cur++ = uic;\n\n            if (uic == 0) {\n                break;\n            }\n        }\n    }\n\n   *utf8cur = '\\0';\n\n   return utf8Str;\n}\n\n/**\n * Convert a UTF-16 string to UTF-8.\n *\n */\nchar * strndup16to8 (const char16_t* s, size_t n)\n{\n    char*   ret;\n    size_t  len;\n\n    if (s == NULL) {\n        return NULL;\n    }\n\n    len = strnlen16to8(s, n);\n\n    /* We are paranoid, and we check for SIZE_MAX-1\n     * too since it is an overflow value for our\n     * strnlen16to8 implementation.\n     */\n    if (len >= SIZE_MAX-1)\n        return NULL;\n\n    ret = malloc(len + 1);\n    if (ret == NULL)\n        return NULL;\n\n    strncpy16to8 (ret, s, n);\n\n    return ret;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/strdup8to16.c",
    "content": "/* libs/cutils/strdup8to16.c\n**\n** Copyright 2006, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\"); \n** you may not use this file except in compliance with the License. \n** You may obtain a copy of the License at \n**\n**     http://www.apache.org/licenses/LICENSE-2.0 \n**\n** Unless required by applicable law or agreed to in writing, software \n** distributed under the License is distributed on an \"AS IS\" BASIS, \n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n** See the License for the specific language governing permissions and \n** limitations under the License.\n*/\n\n#include <cutils/jstring.h>\n#include <assert.h>\n#include <stdlib.h>\n#include <limits.h>\n\n/* See http://www.unicode.org/reports/tr22/ for discussion\n * on invalid sequences\n */\n\n#define UTF16_REPLACEMENT_CHAR 0xfffd\n\n/* Clever trick from Dianne that returns 1-4 depending on leading bit sequence*/\n#define UTF8_SEQ_LENGTH(ch) (((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1)\n\n/* note: macro expands to multiple lines */\n#define UTF8_SHIFT_AND_MASK(unicode, byte)  \\\n            (unicode)<<=6; (unicode) |= (0x3f & (byte));\n\n#define UNICODE_UPPER_LIMIT 0x10fffd    \n\n/**\n * out_len is an out parameter (which may not be null) containing the\n * length of the UTF-16 string (which may contain embedded \\0's)\n */\n\nextern char16_t * strdup8to16 (const char* s, size_t *out_len)\n{\n    char16_t *ret;\n    size_t len;\n\n    if (s == NULL) return NULL;\n\n    len = strlen8to16(s);\n\n    // fail on overflow\n    if (len && SIZE_MAX/len < sizeof(char16_t))\n        return NULL;\n\n    // no plus-one here. UTF-16 strings are not null terminated\n    ret = (char16_t *) malloc (sizeof(char16_t) * len);\n\n    return strcpy8to16 (ret, s, out_len);\n}\n\n/**\n * Like \"strlen\", but for strings encoded with Java's modified UTF-8.\n *\n * The value returned is the number of UTF-16 characters required\n * to represent this string.\n */\nextern size_t strlen8to16 (const char* utf8Str)\n{\n    size_t len = 0;\n    int ic;\n    int expected = 0;\n\n    while ((ic = *utf8Str++) != '\\0') {\n        /* bytes that start 0? or 11 are lead bytes and count as characters.*/\n        /* bytes that start 10 are extention bytes and are not counted */\n         \n        if ((ic & 0xc0) == 0x80) {\n            /* count the 0x80 extention bytes. if we have more than\n             * expected, then start counting them because strcpy8to16\n             * will insert UTF16_REPLACEMENT_CHAR's\n             */\n            expected--;\n            if (expected < 0) {\n                len++;\n            }\n        } else {\n            len++;\n            expected = UTF8_SEQ_LENGTH(ic) - 1;\n\n            /* this will result in a surrogate pair */\n            if (expected == 3) {\n                len++;\n            }\n        }\n    }\n\n    return len;\n}\n\n\n\n/*\n * Retrieve the next UTF-32 character from a UTF-8 string.\n *\n * Stops at inner \\0's\n *\n * Returns UTF16_REPLACEMENT_CHAR if an invalid sequence is encountered\n *\n * Advances \"*pUtf8Ptr\" to the start of the next character.\n */\nstatic inline uint32_t getUtf32FromUtf8(const char** pUtf8Ptr)\n{\n    uint32_t ret;\n    int seq_len;\n    int i;\n\n    /* Mask for leader byte for lengths 1, 2, 3, and 4 respectively*/\n    static const char leaderMask[4] = {0xff, 0x1f, 0x0f, 0x07};\n\n    /* Bytes that start with bits \"10\" are not leading characters. */\n    if (((**pUtf8Ptr) & 0xc0) == 0x80) {\n        (*pUtf8Ptr)++;\n        return UTF16_REPLACEMENT_CHAR;\n    }\n\n    /* note we tolerate invalid leader 11111xxx here */    \n    seq_len = UTF8_SEQ_LENGTH(**pUtf8Ptr);\n\n    ret = (**pUtf8Ptr) & leaderMask [seq_len - 1];\n\n    if (**pUtf8Ptr == '\\0') return ret;\n\n    (*pUtf8Ptr)++;\n    for (i = 1; i < seq_len ; i++, (*pUtf8Ptr)++) {\n        if ((**pUtf8Ptr) == '\\0') return UTF16_REPLACEMENT_CHAR;\n        if (((**pUtf8Ptr) & 0xc0) != 0x80) return UTF16_REPLACEMENT_CHAR;\n\n        UTF8_SHIFT_AND_MASK(ret, **pUtf8Ptr);\n    }\n\n    return ret;\n}\n\n\n/**\n * out_len is an out parameter (which may not be null) containing the\n * length of the UTF-16 string (which may contain embedded \\0's)\n */\n\nextern char16_t * strcpy8to16 (char16_t *utf16Str, const char*utf8Str, \n                                       size_t *out_len)\n{   \n    char16_t *dest = utf16Str;\n\n    while (*utf8Str != '\\0') {\n        uint32_t ret;\n\n        ret = getUtf32FromUtf8(&utf8Str);\n\n        if (ret <= 0xffff) {\n            *dest++ = (char16_t) ret;\n        } else if (ret <= UNICODE_UPPER_LIMIT)  {\n            /* Create surrogate pairs */\n            /* See http://en.wikipedia.org/wiki/UTF-16/UCS-2#Method_for_code_points_in_Plane_1.2C_Plane_2 */\n\n            *dest++ = 0xd800 | ((ret - 0x10000) >> 10);\n            *dest++ = 0xdc00 | ((ret - 0x10000) &  0x3ff);\n        } else {\n            *dest++ = UTF16_REPLACEMENT_CHAR;\n        }\n    }\n\n    *out_len = dest - utf16Str;\n\n    return utf16Str;\n}\n\n/**\n * length is the number of characters in the UTF-8 string.\n * out_len is an out parameter (which may not be null) containing the\n * length of the UTF-16 string (which may contain embedded \\0's)\n */\n\nextern char16_t * strcpylen8to16 (char16_t *utf16Str, const char*utf8Str,\n                                       int length, size_t *out_len)\n{\n    /* TODO: Share more of this code with the method above. Only 2 lines changed. */\n    \n    char16_t *dest = utf16Str;\n\n    const char *end = utf8Str + length; /* This line */\n    while (utf8Str < end) {             /* and this line changed. */\n        uint32_t ret;\n\n        ret = getUtf32FromUtf8(&utf8Str);\n\n        if (ret <= 0xffff) {\n            *dest++ = (char16_t) ret;\n        } else if (ret <= UNICODE_UPPER_LIMIT)  {\n            /* Create surrogate pairs */\n            /* See http://en.wikipedia.org/wiki/UTF-16/UCS-2#Method_for_code_points_in_Plane_1.2C_Plane_2 */\n\n            *dest++ = 0xd800 | ((ret - 0x10000) >> 10);\n            *dest++ = 0xdc00 | ((ret - 0x10000) &  0x3ff);\n        } else {\n            *dest++ = UTF16_REPLACEMENT_CHAR;\n        }\n    }\n\n    *out_len = dest - utf16Str;\n\n    return utf16Str;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/strlcpy.c",
    "content": "/*\n * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n#include <sys/types.h>\n\n#if defined(__GLIBC__) || defined(_WIN32)\n\n#include <string.h>\n\n#include <cutils/memory.h>\n\n/* Implementation of strlcpy() for platforms that don't already have it. */\n\n/*\n * Copy src to string dst of size siz.  At most siz-1 characters\n * will be copied.  Always NUL terminates (unless siz == 0).\n * Returns strlen(src); if retval >= siz, truncation occurred.\n */\nsize_t\nstrlcpy(char *dst, const char *src, size_t siz)\n{\n\tchar *d = dst;\n\tconst char *s = src;\n\tsize_t n = siz;\n\n\t/* Copy as many bytes as will fit */\n\tif (n != 0) {\n\t\twhile (--n != 0) {\n\t\t\tif ((*d++ = *s++) == '\\0')\n\t\t\t\tbreak;\n\t\t}\n  }\n\n\t/* Not enough room in dst, add NUL and traverse rest of src */\n\tif (n == 0) {\n\t\tif (siz != 0)\n\t\t\t*d = '\\0';\t\t/* NUL-terminate dst */\n\t\twhile (*s++)\n\t\t\t;\n\t}\n\n\treturn(s - src - 1);\t/* count does not include NUL */\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/tests/Android.mk",
    "content": "# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nLOCAL_PATH := $(call my-dir)\n\ntest_src_files := \\\n    test_str_parms.cpp \\\n\ntest_target_only_src_files := \\\n    MemsetTest.cpp \\\n    PropertiesTest.cpp \\\n\ntest_libraries := libcutils liblog\n\n\n#\n# Target.\n#\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libcutils_test\nLOCAL_SRC_FILES := $(test_src_files) $(test_target_only_src_files)\nLOCAL_SHARED_LIBRARIES := $(test_libraries)\nLOCAL_MULTILIB := both\nLOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32\nLOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64\ninclude $(BUILD_NATIVE_TEST)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libcutils_test_static\nLOCAL_FORCE_STATIC_EXECUTABLE := true\nLOCAL_SRC_FILES := $(test_src_files) $(test_target_only_src_files)\nLOCAL_STATIC_LIBRARIES := libc $(test_libraries)\nLOCAL_CXX_STL := libc++_static\nLOCAL_MULTILIB := both\nLOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32\nLOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64\ninclude $(BUILD_NATIVE_TEST)\n\n\n#\n# Host.\n#\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libcutils_test\nLOCAL_SRC_FILES := $(test_src_files)\nLOCAL_SHARED_LIBRARIES := $(test_libraries)\nLOCAL_MULTILIB := both\nLOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32\nLOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64\ninclude $(BUILD_HOST_NATIVE_TEST)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := libcutils_test_static\nLOCAL_SRC_FILES := $(test_src_files)\nLOCAL_STATIC_LIBRARIES := $(test_libraries)\nLOCAL_CXX_STL := libc++_static\nLOCAL_MULTILIB := both\nLOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32\nLOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64\ninclude $(BUILD_HOST_NATIVE_TEST)\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/tests/MemsetTest.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/mman.h>\n#include <sys/types.h>\n\n#include <memory>\n\n#include <cutils/memory.h>\n#include <gtest/gtest.h>\n\n#define FENCEPOST_LENGTH 8\n\n#define MAX_TEST_SIZE (64*1024)\n// Choose values that have no repeating byte values.\n#define MEMSET16_PATTERN 0xb139\n#define MEMSET32_PATTERN 0x48193a27\n\nenum test_e {\n  MEMSET16 = 0,\n  MEMSET32,\n};\n\nstatic int g_memset16_aligns[][2] = {\n  { 2, 0 },\n  { 4, 0 },\n  { 8, 0 },\n  { 16, 0 },\n  { 32, 0 },\n  { 64, 0 },\n  { 128, 0 },\n\n  { 4, 2 },\n\n  { 8, 2 },\n  { 8, 4 },\n  { 8, 6 },\n\n  { 128, 2 },\n  { 128, 4 },\n  { 128, 6 },\n  { 128, 8 },\n  { 128, 10 },\n  { 128, 12 },\n  { 128, 14 },\n  { 128, 16 },\n};\n\nstatic int g_memset32_aligns[][2] = {\n  { 4, 0 },\n  { 8, 0 },\n  { 16, 0 },\n  { 32, 0 },\n  { 64, 0 },\n  { 128, 0 },\n\n  { 8, 4 },\n\n  { 128, 4 },\n  { 128, 8 },\n  { 128, 12 },\n  { 128, 16 },\n};\n\nstatic size_t GetIncrement(size_t len, size_t min_incr) {\n  if (len >= 4096) {\n    return 1024;\n  } else if (len >= 1024) {\n    return 256;\n  }\n  return min_incr;\n}\n\n// Return a pointer into the current buffer with the specified alignment.\nstatic void *GetAlignedPtr(void *orig_ptr, int alignment, int or_mask) {\n  uint64_t ptr = reinterpret_cast<uint64_t>(orig_ptr);\n  if (alignment > 0) {\n      // When setting the alignment, set it to exactly the alignment chosen.\n      // The pointer returned will be guaranteed not to be aligned to anything\n      // more than that.\n      ptr += alignment - (ptr & (alignment - 1));\n      ptr |= alignment | or_mask;\n  }\n\n  return reinterpret_cast<void*>(ptr);\n}\n\nstatic void SetFencepost(uint8_t *buffer) {\n  for (int i = 0; i < FENCEPOST_LENGTH; i += 2) {\n    buffer[i] = 0xde;\n    buffer[i+1] = 0xad;\n  }\n}\n\nstatic void VerifyFencepost(uint8_t *buffer) {\n  for (int i = 0; i < FENCEPOST_LENGTH; i += 2) {\n    if (buffer[i] != 0xde || buffer[i+1] != 0xad) {\n      uint8_t expected_value;\n      if (buffer[i] == 0xde) {\n        i++;\n        expected_value = 0xad;\n      } else {\n        expected_value = 0xde;\n      }\n      ASSERT_EQ(expected_value, buffer[i]);\n    }\n  }\n}\n\nvoid RunMemsetTests(test_e test_type, uint32_t value, int align[][2], size_t num_aligns) {\n  size_t min_incr = 4;\n  if (test_type == MEMSET16) {\n    min_incr = 2;\n    value |= value << 16;\n  }\n  std::unique_ptr<uint32_t[]> expected_buf(new uint32_t[MAX_TEST_SIZE/sizeof(uint32_t)]);\n  for (size_t i = 0; i < MAX_TEST_SIZE/sizeof(uint32_t); i++) {\n    expected_buf[i] = value;\n  }\n\n  // Allocate one large buffer with lots of extra space so that we can\n  // guarantee that all possible alignments will fit.\n  std::unique_ptr<uint8_t[]> buf(new uint8_t[3*MAX_TEST_SIZE]);\n  uint8_t *buf_align;\n  for (size_t i = 0; i < num_aligns; i++) {\n    size_t incr = min_incr;\n    for (size_t len = incr; len <= MAX_TEST_SIZE; len += incr) {\n      incr = GetIncrement(len, min_incr);\n\n      buf_align = reinterpret_cast<uint8_t*>(GetAlignedPtr(\n          buf.get()+FENCEPOST_LENGTH, align[i][0], align[i][1]));\n\n      SetFencepost(&buf_align[-FENCEPOST_LENGTH]);\n      SetFencepost(&buf_align[len]);\n\n      memset(buf_align, 0xff, len);\n      if (test_type == MEMSET16) {\n        android_memset16(reinterpret_cast<uint16_t*>(buf_align), value, len);\n      } else {\n        android_memset32(reinterpret_cast<uint32_t*>(buf_align), value, len);\n      }\n      ASSERT_EQ(0, memcmp(expected_buf.get(), buf_align, len))\n          << \"Failed size \" << len << \" align \" << align[i][0] << \" \" << align[i][1] << \"\\n\";\n\n      VerifyFencepost(&buf_align[-FENCEPOST_LENGTH]);\n      VerifyFencepost(&buf_align[len]);\n    }\n  }\n}\n\nTEST(libcutils, android_memset16_non_zero) {\n  RunMemsetTests(MEMSET16, MEMSET16_PATTERN, g_memset16_aligns, sizeof(g_memset16_aligns)/sizeof(int[2]));\n}\n\nTEST(libcutils, android_memset16_zero) {\n  RunMemsetTests(MEMSET16, 0, g_memset16_aligns, sizeof(g_memset16_aligns)/sizeof(int[2]));\n}\n\nTEST(libcutils, android_memset32_non_zero) {\n  RunMemsetTests(MEMSET32, MEMSET32_PATTERN, g_memset32_aligns, sizeof(g_memset32_aligns)/sizeof(int[2]));\n}\n\nTEST(libcutils, android_memset32_zero) {\n  RunMemsetTests(MEMSET32, 0, g_memset32_aligns, sizeof(g_memset32_aligns)/sizeof(int[2]));\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/tests/PropertiesTest.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"Properties_test\"\n#include <utils/Log.h>\n#include <gtest/gtest.h>\n\n#include <cutils/properties.h>\n#include <limits.h>\n#include <string>\n#include <sstream>\n#include <iostream>\n\nnamespace android {\n\n#define STRINGIFY_INNER(x) #x\n#define STRINGIFY(x) STRINGIFY_INNER(x)\n#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))\n#define ASSERT_OK(x) ASSERT_EQ(0, (x))\n#define EXPECT_OK(x) EXPECT_EQ(0, (x))\n\n#define PROPERTY_TEST_KEY \"libcutils.test.key\"\n#define PROPERTY_TEST_VALUE_DEFAULT \"<<<default_value>>>\"\n\ntemplate <typename T>\nstatic std::string HexString(T value) {\n    std::stringstream ss;\n    ss << \"0x\" << std::hex << std::uppercase << value;\n    return ss.str();\n}\n\ntemplate <typename T>\nstatic ::testing::AssertionResult AssertEqualHex(const char *mExpr,\n        const char *nExpr,\n        T m,\n        T n) {\n    if (m == n) {\n        return ::testing::AssertionSuccess();\n    }\n\n    return ::testing::AssertionFailure()\n        << mExpr << \" and \" << nExpr << \" (expected: \" << HexString(m) <<\n        \", actual: \" << HexString(n) << \") are not equal\";\n}\n\nclass PropertiesTest : public testing::Test {\npublic:\n    PropertiesTest() : mValue() {}\nprotected:\n    virtual void SetUp() {\n        EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/NULL));\n    }\n\n    virtual void TearDown() {\n        EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/NULL));\n    }\n\n    char mValue[PROPERTY_VALUE_MAX];\n\n    template <typename T>\n    static std::string ToString(T value) {\n        std::stringstream ss;\n        ss << value;\n\n        return ss.str();\n    }\n\n    // Return length of property read; value is written into mValue\n    int SetAndGetProperty(const char* value, const char* defaultValue = PROPERTY_TEST_VALUE_DEFAULT) {\n        EXPECT_OK(property_set(PROPERTY_TEST_KEY, value)) << \"value: '\" << value << \"'\";\n        return property_get(PROPERTY_TEST_KEY, mValue, defaultValue);\n    }\n\n    void ResetValue(unsigned char c = 0xFF) {\n        for (size_t i = 0; i < ARRAY_SIZE(mValue); ++i) {\n            mValue[i] = (char) c;\n        }\n    }\n};\n\nTEST_F(PropertiesTest, SetString) {\n\n    // Null key -> unsuccessful set\n    {\n        // Null key -> fails\n        EXPECT_GT(0, property_set(/*key*/NULL, PROPERTY_TEST_VALUE_DEFAULT));\n    }\n\n    // Null value -> returns default value\n    {\n        // Null value -> OK , and it clears the value\n        EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/NULL));\n        ResetValue();\n\n        // Since the value is null, default value will be returned\n        int len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);\n        EXPECT_EQ(strlen(PROPERTY_TEST_VALUE_DEFAULT), len);\n        EXPECT_STREQ(PROPERTY_TEST_VALUE_DEFAULT, mValue);\n    }\n\n    // Trivial case => get returns what was set\n    {\n        int len = SetAndGetProperty(\"hello_world\");\n        EXPECT_EQ(strlen(\"hello_world\"), len) << \"hello_world key\";\n        EXPECT_STREQ(\"hello_world\", mValue);\n        ResetValue();\n    }\n\n    // Set to empty string => get returns default always\n    {\n        const char* EMPTY_STRING_DEFAULT = \"EMPTY_STRING\";\n        int len = SetAndGetProperty(\"\", EMPTY_STRING_DEFAULT);\n        EXPECT_EQ(strlen(EMPTY_STRING_DEFAULT), len) << \"empty key\";\n        EXPECT_STREQ(EMPTY_STRING_DEFAULT, mValue);\n        ResetValue();\n    }\n\n    // Set to max length => get returns what was set\n    {\n        std::string maxLengthString = std::string(PROPERTY_VALUE_MAX-1, 'a');\n\n        int len = SetAndGetProperty(maxLengthString.c_str());\n        EXPECT_EQ(PROPERTY_VALUE_MAX-1, len) << \"max length key\";\n        EXPECT_STREQ(maxLengthString.c_str(), mValue);\n        ResetValue();\n    }\n\n    // Set to max length + 1 => set fails\n    {\n        const char* VALID_TEST_VALUE = \"VALID_VALUE\";\n        ASSERT_OK(property_set(PROPERTY_TEST_KEY, VALID_TEST_VALUE));\n\n        std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a');\n\n        // Expect that the value set fails since it's too long\n        EXPECT_GT(0, property_set(PROPERTY_TEST_KEY, oneLongerString.c_str()));\n        int len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);\n\n        EXPECT_EQ(strlen(VALID_TEST_VALUE), len) << \"set should've failed\";\n        EXPECT_STREQ(VALID_TEST_VALUE, mValue);\n        ResetValue();\n    }\n}\n\nTEST_F(PropertiesTest, GetString) {\n\n    // Try to use a default value that's too long => set fails\n    {\n        ASSERT_OK(property_set(PROPERTY_TEST_KEY, \"\"));\n\n        std::string maxLengthString = std::string(PROPERTY_VALUE_MAX-1, 'a');\n        std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a');\n\n        // Expect that the value is truncated since it's too long (by 1)\n        int len = property_get(PROPERTY_TEST_KEY, mValue, oneLongerString.c_str());\n        EXPECT_EQ(PROPERTY_VALUE_MAX-1, len);\n        EXPECT_STREQ(maxLengthString.c_str(), mValue);\n        ResetValue();\n    }\n}\n\nTEST_F(PropertiesTest, GetBool) {\n    /**\n     * TRUE\n     */\n    const char *valuesTrue[] = { \"1\", \"true\", \"y\", \"yes\", \"on\", };\n    for (size_t i = 0; i < ARRAY_SIZE(valuesTrue); ++i) {\n        ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesTrue[i]));\n        bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/false);\n        EXPECT_TRUE(val) << \"Property should've been TRUE for value: '\" << valuesTrue[i] << \"'\";\n    }\n\n    /**\n     * FALSE\n     */\n    const char *valuesFalse[] = { \"0\", \"false\", \"n\", \"no\", \"off\", };\n    for (size_t i = 0; i < ARRAY_SIZE(valuesFalse); ++i) {\n        ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesFalse[i]));\n        bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/true);\n        EXPECT_FALSE(val) << \"Property shoud've been FALSE For string value: '\" << valuesFalse[i] << \"'\";\n    }\n\n    /**\n     * NEITHER\n     */\n    const char *valuesNeither[] = { \"x0\", \"x1\", \"2\", \"-2\", \"True\", \"False\", \"garbage\", \"\", \" \",\n            \"+1\", \"  1  \", \"  true\", \"  true  \", \"  y  \", \"  yes\", \"yes  \",\n            \"+0\", \"-0\", \"00\", \"  00  \", \"  false\", \"false  \",\n    };\n    for (size_t i = 0; i < ARRAY_SIZE(valuesNeither); ++i) {\n        ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesNeither[i]));\n\n        // The default value should always be used\n        bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/true);\n        EXPECT_TRUE(val) << \"Property should've been NEITHER (true) for string value: '\" << valuesNeither[i] << \"'\";\n\n        val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/false);\n        EXPECT_FALSE(val) << \"Property should've been NEITHER (false) for string value: '\" << valuesNeither[i] << \"'\";\n    }\n}\n\nTEST_F(PropertiesTest, GetInt64) {\n    const int64_t DEFAULT_VALUE = INT64_C(0xDEADBEEFBEEFDEAD);\n\n    const std::string longMaxString = ToString(INT64_MAX);\n    const std::string longStringOverflow = longMaxString + \"0\";\n\n    const std::string longMinString = ToString(INT64_MIN);\n    const std::string longStringUnderflow = longMinString + \"0\";\n\n    const char* setValues[] = {\n        // base 10\n        \"1\", \"2\", \"12345\", \"-1\", \"-2\", \"-12345\",\n        // base 16\n        \"0xFF\", \"0x0FF\", \"0xC0FFEE\",\n        // base 8\n        \"0\", \"01234\", \"07\",\n        // corner cases\n        \"       2\", \"2      \", \"+0\", \"-0\", \"  +0   \", longMaxString.c_str(), longMinString.c_str(),\n        // failing cases\n        NULL, \"\", \" \", \"    \", \"hello\", \"     true     \", \"y\",\n        longStringOverflow.c_str(), longStringUnderflow.c_str(),\n    };\n\n    int64_t getValues[] = {\n        // base 10\n        1, 2, 12345, -1, -2, -12345,\n        // base 16\n        0xFF, 0x0FF, 0xC0FFEE,\n        // base 8\n        0, 01234, 07,\n        // corner cases\n        2, 2, 0, 0, 0, INT64_MAX, INT64_MIN,\n        // failing cases\n        DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE,\n        DEFAULT_VALUE, DEFAULT_VALUE,\n    };\n\n    ASSERT_EQ(ARRAY_SIZE(setValues), ARRAY_SIZE(getValues));\n\n    for (size_t i = 0; i < ARRAY_SIZE(setValues); ++i) {\n        ASSERT_OK(property_set(PROPERTY_TEST_KEY, setValues[i]));\n\n        int64_t val = property_get_int64(PROPERTY_TEST_KEY, DEFAULT_VALUE);\n        EXPECT_PRED_FORMAT2(AssertEqualHex, getValues[i], val) << \"Property was set to '\" << setValues[i] << \"'\";\n    }\n}\n\nTEST_F(PropertiesTest, GetInt32) {\n    const int32_t DEFAULT_VALUE = INT32_C(0xDEADBEEF);\n\n    const std::string intMaxString = ToString(INT32_MAX);\n    const std::string intStringOverflow = intMaxString + \"0\";\n\n    const std::string intMinString = ToString(INT32_MIN);\n    const std::string intStringUnderflow = intMinString + \"0\";\n\n    const char* setValues[] = {\n        // base 10\n        \"1\", \"2\", \"12345\", \"-1\", \"-2\", \"-12345\",\n        // base 16\n        \"0xFF\", \"0x0FF\", \"0xC0FFEE\", \"0Xf00\",\n        // base 8\n        \"0\", \"01234\", \"07\",\n        // corner cases\n        \"       2\", \"2      \", \"+0\", \"-0\", \"  +0   \", intMaxString.c_str(), intMinString.c_str(),\n        // failing cases\n        NULL, \"\", \" \", \"    \", \"hello\", \"     true     \", \"y\",\n        intStringOverflow.c_str(), intStringUnderflow.c_str(),\n    };\n\n    int32_t getValues[] = {\n        // base 10\n        1, 2, 12345, -1, -2, -12345,\n        // base 16\n        0xFF, 0x0FF, 0xC0FFEE, 0Xf00,\n        // base 8\n        0, 01234, 07,\n        // corner cases\n        2, 2, 0, 0, 0, INT32_MAX, INT32_MIN,\n        // failing cases\n        DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE,\n        DEFAULT_VALUE, DEFAULT_VALUE,\n    };\n\n    ASSERT_EQ(ARRAY_SIZE(setValues), ARRAY_SIZE(getValues));\n\n    for (size_t i = 0; i < ARRAY_SIZE(setValues); ++i) {\n        ASSERT_OK(property_set(PROPERTY_TEST_KEY, setValues[i]));\n\n        int32_t val = property_get_int32(PROPERTY_TEST_KEY, DEFAULT_VALUE);\n        EXPECT_PRED_FORMAT2(AssertEqualHex, getValues[i], val) << \"Property was set to '\" << setValues[i] << \"'\";\n    }\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/tests/test_str_parms.cpp",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <cutils/str_parms.h>\n#include <gtest/gtest.h>\n\nstatic void test_str_parms_str(const char* str, const char* expected) {\n    str_parms* str_parms = str_parms_create_str(str);\n    str_parms_add_str(str_parms, \"dude\", \"woah\");\n    str_parms_add_str(str_parms, \"dude\", \"woah\");\n    str_parms_del(str_parms, \"dude\");\n    str_parms_dump(str_parms);\n    char* out_str = str_parms_to_str(str_parms);\n    str_parms_destroy(str_parms);\n    ASSERT_STREQ(expected, out_str) << str;\n    free(out_str);\n}\n\nTEST(str_parms, smoke) {\n    test_str_parms_str(\"\", \"\");\n    test_str_parms_str(\";\", \"\");\n    test_str_parms_str(\"=\", \"\");\n    test_str_parms_str(\"=;\", \"\");\n    test_str_parms_str(\"=bar\", \"\");\n    test_str_parms_str(\"=bar;\", \"\");\n    test_str_parms_str(\"foo=\", \"foo=\");\n    test_str_parms_str(\"foo=;\", \"foo=\");\n    test_str_parms_str(\"foo=bar\", \"foo=bar\");\n    test_str_parms_str(\"foo=bar;\", \"foo=bar\");\n    test_str_parms_str(\"foo=bar;baz\", \"foo=bar;baz=\");\n    test_str_parms_str(\"foo=bar;baz=\", \"foo=bar;baz=\");\n    test_str_parms_str(\"foo=bar;baz=bat\", \"foo=bar;baz=bat\");\n    test_str_parms_str(\"foo=bar;baz=bat;\", \"foo=bar;baz=bat\");\n    test_str_parms_str(\"foo=bar1;baz=bat;foo=bar2\", \"foo=bar2;baz=bat\");\n}\n\nTEST(str_parms, put_ENOMEM) {\n    // hashmapPut reports errors by setting errno to ENOMEM.\n    // Test that we're not confused by running in an environment where this is already true.\n    errno = ENOMEM;\n    test_str_parms_str(\"foo=bar;baz=\", \"foo=bar;baz=\");\n    ASSERT_EQ(ENOMEM, errno);\n    test_str_parms_str(\"foo=bar;baz=\", \"foo=bar;baz=\");\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/threads.c",
    "content": "/*\n** Copyright (C) 2007, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\");\n** you may not use this file except in compliance with the License.\n** You may obtain a copy of the License at\n**\n**     http://www.apache.org/licenses/LICENSE-2.0\n**\n** Unless required by applicable law or agreed to in writing, software\n** distributed under the License is distributed on an \"AS IS\" BASIS,\n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n** See the License for the specific language governing permissions and\n** limitations under the License.\n*/\n\n#include \"cutils/threads.h\"\n\n// For gettid.\n#if defined(__APPLE__)\n#include \"AvailabilityMacros.h\"  // For MAC_OS_X_VERSION_MAX_ALLOWED\n#include <stdint.h>\n#include <stdlib.h>\n#include <sys/syscall.h>\n#include <sys/time.h>\n#include <unistd.h>\n#elif defined(__linux__) && !defined(__ANDROID__)\n#include <syscall.h>\n#include <unistd.h>\n#elif defined(_WIN32)\n#include <windows.h>\n#endif\n\n// No definition needed for Android because we'll just pick up bionic's copy.\n#ifndef __ANDROID__\npid_t gettid() {\n#if defined(__APPLE__)\n  return syscall(SYS_thread_selfid);\n#elif defined(__linux__)\n  return syscall(__NR_gettid);\n#elif defined(_WIN32)\n  return GetCurrentThreadId();\n#endif\n}\n#endif  // __ANDROID__\n\n#if !defined(_WIN32)\n\nvoid*  thread_store_get( thread_store_t*  store )\n{\n    if (!store->has_tls)\n        return NULL;\n\n    return pthread_getspecific( store->tls );\n}\n\nextern void   thread_store_set( thread_store_t*          store,\n                                void*                    value,\n                                thread_store_destruct_t  destroy)\n{\n    pthread_mutex_lock( &store->lock );\n    if (!store->has_tls) {\n        if (pthread_key_create( &store->tls, destroy) != 0) {\n            pthread_mutex_unlock(&store->lock);\n            return;\n        }\n        store->has_tls = 1;\n    }\n    pthread_mutex_unlock( &store->lock );\n\n    pthread_setspecific( store->tls, value );\n}\n\n#else /* !defined(_WIN32) */\nvoid*  thread_store_get( thread_store_t*  store )\n{\n    if (!store->has_tls)\n        return NULL;\n\n    return (void*) TlsGetValue( store->tls );\n}\n\nvoid   thread_store_set( thread_store_t*          store,\n                         void*                    value,\n                         thread_store_destruct_t  destroy )\n{\n    /* XXX: can't use destructor on thread exit */\n    if (!store->lock_init) {\n        store->lock_init = -1;\n        InitializeCriticalSection( &store->lock );\n        store->lock_init = -2;\n    } else while (store->lock_init != -2) {\n        Sleep(10); /* 10ms */\n    }\n\n    EnterCriticalSection( &store->lock );\n    if (!store->has_tls) {\n        store->tls = TlsAlloc();\n        if (store->tls == TLS_OUT_OF_INDEXES) {\n            LeaveCriticalSection( &store->lock );\n            return;\n        }\n        store->has_tls = 1;\n    }\n    LeaveCriticalSection( &store->lock );\n\n    TlsSetValue( store->tls, value );\n}\n#endif /* !defined(_WIN32) */\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/trace-dev.c",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <errno.h>\n#include <fcntl.h>\n#include <limits.h>\n#include <pthread.h>\n#include <stdatomic.h>\n#include <stdbool.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/types.h>\n#include <cutils/compiler.h>\n#include <cutils/properties.h>\n#include <cutils/trace.h>\n\n#define LOG_TAG \"cutils-trace\"\n#include <log/log.h>\n\n/**\n * Maximum size of a message that can be logged to the trace buffer.\n * Note this message includes a tag, the pid, and the string given as the name.\n * Names should be kept short to get the most use of the trace buffer.\n */\n#define ATRACE_MESSAGE_LENGTH 1024\n\natomic_bool             atrace_is_ready      = ATOMIC_VAR_INIT(false);\nint                     atrace_marker_fd     = -1;\nuint64_t                atrace_enabled_tags  = ATRACE_TAG_NOT_READY;\nstatic bool             atrace_is_debuggable = false;\nstatic atomic_bool      atrace_is_enabled    = ATOMIC_VAR_INIT(true);\nstatic pthread_once_t   atrace_once_control  = PTHREAD_ONCE_INIT;\nstatic pthread_mutex_t  atrace_tags_mutex    = PTHREAD_MUTEX_INITIALIZER;\n\n// Set whether this process is debuggable, which determines whether\n// application-level tracing is allowed when the ro.debuggable system property\n// is not set to '1'.\nvoid atrace_set_debuggable(bool debuggable)\n{\n    atrace_is_debuggable = debuggable;\n    atrace_update_tags();\n}\n\n// Set whether tracing is enabled in this process.  This is used to prevent\n// the Zygote process from tracing.\nvoid atrace_set_tracing_enabled(bool enabled)\n{\n    atomic_store_explicit(&atrace_is_enabled, enabled, memory_order_release);\n    atrace_update_tags();\n}\n\n// Check whether the given command line matches one of the comma-separated\n// values listed in the app_cmdlines property.\nstatic bool atrace_is_cmdline_match(const char* cmdline)\n{\n    int count = property_get_int32(\"debug.atrace.app_number\", 0);\n\n    char buf[PROPERTY_KEY_MAX];\n    char value[PROPERTY_VALUE_MAX];\n\n    for (int i = 0; i < count; i++) {\n        snprintf(buf, sizeof(buf), \"debug.atrace.app_%d\", i);\n        property_get(buf, value, \"\");\n        if (strcmp(value, cmdline) == 0) {\n            return true;\n        }\n    }\n\n    return false;\n}\n\n// Determine whether application-level tracing is enabled for this process.\nstatic bool atrace_is_app_tracing_enabled()\n{\n    bool sys_debuggable = false;\n    char value[PROPERTY_VALUE_MAX];\n    bool result = false;\n\n    // Check whether the system is debuggable.\n    property_get(\"ro.debuggable\", value, \"0\");\n    if (value[0] == '1') {\n        sys_debuggable = true;\n    }\n\n    if (sys_debuggable || atrace_is_debuggable) {\n        // Check whether tracing is enabled for this process.\n        FILE * file = fopen(\"/proc/self/cmdline\", \"re\");\n        if (file) {\n            char cmdline[4096];\n            if (fgets(cmdline, sizeof(cmdline), file)) {\n                result = atrace_is_cmdline_match(cmdline);\n            } else {\n                ALOGE(\"Error reading cmdline: %s (%d)\", strerror(errno), errno);\n            }\n            fclose(file);\n        } else {\n            ALOGE(\"Error opening /proc/self/cmdline: %s (%d)\", strerror(errno),\n                    errno);\n        }\n    }\n\n    return result;\n}\n\n// Read the sysprop and return the value tags should be set to\nstatic uint64_t atrace_get_property()\n{\n    char value[PROPERTY_VALUE_MAX];\n    char *endptr;\n    uint64_t tags;\n\n    property_get(\"debug.atrace.tags.enableflags\", value, \"0\");\n    errno = 0;\n    tags = strtoull(value, &endptr, 0);\n    if (value[0] == '\\0' || *endptr != '\\0') {\n        ALOGE(\"Error parsing trace property: Not a number: %s\", value);\n        return 0;\n    } else if (errno == ERANGE || tags == ULLONG_MAX) {\n        ALOGE(\"Error parsing trace property: Number too large: %s\", value);\n        return 0;\n    }\n\n    // Only set the \"app\" tag if this process was selected for app-level debug\n    // tracing.\n    if (atrace_is_app_tracing_enabled()) {\n        tags |= ATRACE_TAG_APP;\n    } else {\n        tags &= ~ATRACE_TAG_APP;\n    }\n\n    return (tags | ATRACE_TAG_ALWAYS) & ATRACE_TAG_VALID_MASK;\n}\n\n// Update tags if tracing is ready. Useful as a sysprop change callback.\nvoid atrace_update_tags()\n{\n    uint64_t tags;\n    if (CC_UNLIKELY(atomic_load_explicit(&atrace_is_ready, memory_order_acquire))) {\n        if (atomic_load_explicit(&atrace_is_enabled, memory_order_acquire)) {\n            tags = atrace_get_property();\n            pthread_mutex_lock(&atrace_tags_mutex);\n            atrace_enabled_tags = tags;\n            pthread_mutex_unlock(&atrace_tags_mutex);\n        } else {\n            // Tracing is disabled for this process, so we simply don't\n            // initialize the tags.\n            pthread_mutex_lock(&atrace_tags_mutex);\n            atrace_enabled_tags = ATRACE_TAG_NOT_READY;\n            pthread_mutex_unlock(&atrace_tags_mutex);\n        }\n    }\n}\n\nstatic void atrace_init_once()\n{\n    atrace_marker_fd = open(\"/sys/kernel/debug/tracing/trace_marker\", O_WRONLY | O_CLOEXEC);\n    if (atrace_marker_fd == -1) {\n        ALOGE(\"Error opening trace file: %s (%d)\", strerror(errno), errno);\n        atrace_enabled_tags = 0;\n        goto done;\n    }\n\n    atrace_enabled_tags = atrace_get_property();\n\ndone:\n    atomic_store_explicit(&atrace_is_ready, true, memory_order_release);\n}\n\nvoid atrace_setup()\n{\n    pthread_once(&atrace_once_control, atrace_init_once);\n}\n\nvoid atrace_begin_body(const char* name)\n{\n    char buf[ATRACE_MESSAGE_LENGTH];\n\n    int len = snprintf(buf, sizeof(buf), \"B|%d|%s\", getpid(), name);\n    if (len >= (int) sizeof(buf)) {\n        ALOGW(\"Truncated name in %s: %s\\n\", __FUNCTION__, name);\n        len = sizeof(buf) - 1;\n    }\n    write(atrace_marker_fd, buf, len);\n}\n\n#define WRITE_MSG(format_begin, format_end, pid, name, value) { \\\n    char buf[ATRACE_MESSAGE_LENGTH]; \\\n    int len = snprintf(buf, sizeof(buf), format_begin \"%s\" format_end, pid, \\\n        name, value); \\\n    if (len >= (int) sizeof(buf)) { \\\n        /* Given the sizeof(buf), and all of the current format buffers, \\\n         * it is impossible for name_len to be < 0 if len >= sizeof(buf). */ \\\n        int name_len = strlen(name) - (len - sizeof(buf)) - 1; \\\n        /* Truncate the name to make the message fit. */ \\\n        ALOGW(\"Truncated name in %s: %s\\n\", __FUNCTION__, name); \\\n        len = snprintf(buf, sizeof(buf), format_begin \"%.*s\" format_end, pid, \\\n            name_len, name, value); \\\n    } \\\n    write(atrace_marker_fd, buf, len); \\\n}\n\nvoid atrace_async_begin_body(const char* name, int32_t cookie)\n{\n    WRITE_MSG(\"S|%d|\", \"|%\" PRId32, getpid(), name, cookie);\n}\n\nvoid atrace_async_end_body(const char* name, int32_t cookie)\n{\n    WRITE_MSG(\"F|%d|\", \"|%\" PRId32, getpid(), name, cookie);\n}\n\nvoid atrace_int_body(const char* name, int32_t value)\n{\n    WRITE_MSG(\"C|%d|\", \"|%\" PRId32, getpid(), name, value);\n}\n\nvoid atrace_int64_body(const char* name, int64_t value)\n{\n    WRITE_MSG(\"C|%d|\", \"|%\" PRId64, getpid(), name, value);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/trace-host.c",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <cutils/trace.h>\n\n#ifndef __unused\n#define __unused __attribute__((__unused__))\n#endif\n\natomic_bool             atrace_is_ready      = ATOMIC_VAR_INIT(true);\nint                     atrace_marker_fd     = -1;\nuint64_t                atrace_enabled_tags  = 0;\n\nvoid atrace_set_debuggable(bool debuggable __unused) { }\nvoid atrace_set_tracing_enabled(bool enabled __unused) { }\nvoid atrace_update_tags() { }\nvoid atrace_setup() { }\nvoid atrace_begin_body(const char* name __unused) { }\nvoid atrace_async_begin_body(const char* name __unused, int32_t cookie __unused) { }\nvoid atrace_async_end_body(const char* name __unused, int32_t cookie __unused) { }\nvoid atrace_int_body(const char* name __unused, int32_t value __unused) { }\nvoid atrace_int64_body(const char* name __unused, int64_t value __unused) { }\n"
  },
  {
    "path": "atlas-aapt/system/core/libcutils/uevent.c",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <cutils/uevent.h>\n\n#include <errno.h>\n#include <stdbool.h>\n#include <string.h>\n#include <strings.h>\n#include <sys/socket.h>\n#include <sys/un.h>\n#include <unistd.h>\n\n#include <linux/netlink.h>\n\n/**\n * Like recv(), but checks that messages actually originate from the kernel.\n */\nssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length)\n{\n    uid_t uid = -1;\n    return uevent_kernel_multicast_uid_recv(socket, buffer, length, &uid);\n}\n\n/**\n * Like the above, but passes a uid_t in by pointer. In the event that this\n * fails due to a bad uid check, the uid_t will be set to the uid of the\n * socket's peer.\n *\n * If this method rejects a netlink message from outside the kernel, it\n * returns -1, sets errno to EIO, and sets \"user\" to the UID associated with the\n * message. If the peer UID cannot be determined, \"user\" is set to -1.\"\n */\nssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *uid)\n{\n    return uevent_kernel_recv(socket, buffer, length, true, uid);\n}\n\nssize_t uevent_kernel_recv(int socket, void *buffer, size_t length, bool require_group, uid_t *uid)\n{\n    struct iovec iov = { buffer, length };\n    struct sockaddr_nl addr;\n    char control[CMSG_SPACE(sizeof(struct ucred))];\n    struct msghdr hdr = {\n        &addr,\n        sizeof(addr),\n        &iov,\n        1,\n        control,\n        sizeof(control),\n        0,\n    };\n\n    *uid = -1;\n    ssize_t n = recvmsg(socket, &hdr, 0);\n    if (n <= 0) {\n        return n;\n    }\n\n    struct cmsghdr *cmsg = CMSG_FIRSTHDR(&hdr);\n    if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {\n        /* ignoring netlink message with no sender credentials */\n        goto out;\n    }\n\n    struct ucred *cred = (struct ucred *)CMSG_DATA(cmsg);\n    *uid = cred->uid;\n    if (cred->uid != 0) {\n        /* ignoring netlink message from non-root user */\n        goto out;\n    }\n\n    if (addr.nl_pid != 0) {\n        /* ignore non-kernel */\n        goto out;\n    }\n    if (require_group && addr.nl_groups == 0) {\n        /* ignore unicast messages when requested */\n        goto out;\n    }\n\n    return n;\n\nout:\n    /* clear residual potentially malicious data */\n    bzero(buffer, length);\n    errno = EIO;\n    return -1;\n}\n\nint uevent_open_socket(int buf_sz, bool passcred)\n{\n    struct sockaddr_nl addr;\n    int on = passcred;\n    int s;\n\n    memset(&addr, 0, sizeof(addr));\n    addr.nl_family = AF_NETLINK;\n    addr.nl_pid = getpid();\n    addr.nl_groups = 0xffffffff;\n\n    s = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT);\n    if(s < 0)\n        return -1;\n\n    setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &buf_sz, sizeof(buf_sz));\n    setsockopt(s, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));\n\n    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {\n        close(s);\n        return -1;\n    }\n\n    return s;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/Android.bp",
    "content": "//\n// Copyright (C) 2008-2014 The Android Open Source Project\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\nliblog_sources = [\n    \"log_event_list.c\",\n    \"log_event_write.c\",\n    \"logger_write.c\",\n    \"config_write.c\",\n    \"logger_name.c\",\n    \"logger_lock.c\",\n]\nliblog_host_sources = [\n    \"fake_log_device.c\",\n    //\"event.logtags\",\n    \"fake_writer.c\",\n]\nliblog_target_sources = [\n    \"event_tag_map.c\",\n    \"config_read.c\",\n    \"log_time.cpp\",\n    \"log_is_loggable.c\",\n    \"logprint.c\",\n    \"pmsg_reader.c\",\n    \"pmsg_writer.c\",\n    \"logd_reader.c\",\n    \"logd_writer.c\",\n    \"logger_read.c\",\n]\n\n// Shared and static library for host and device\n// ========================================================\ncc_library {\n    name: \"liblog\",\n    host_supported: true,\n\n    srcs: liblog_sources,\n\n    target: {\n        host: {\n            srcs: liblog_host_sources,\n            cflags: [\"-DFAKE_LOG_DEVICE=1\"],\n        },\n        android: {\n            srcs: liblog_target_sources,\n            // AddressSanitizer runtime library depends on liblog.\n            sanitize: [\"never\"],\n        },\n        android_arm: {\n            // TODO: This is to work around b/24465209. Remove after root cause is fixed\n            ldflags: [\"-Wl,--hash-style=both\"],\n        },\n        windows: {\n            srcs: [\"uio.c\"],\n            enabled: true,\n        },\n        not_windows: {\n            srcs: [\"event_tag_map.c\"],\n        },\n        linux: {\n            host_ldlibs: [\"-lrt\"],\n        },\n    },\n\n    cflags: [\n        \"-Werror\",\n        \"-fvisibility=hidden\",\n        // This is what we want to do:\n        //  liblog_cflags := $(shell \\\n        //   sed -n \\\n        //       's/^\\([0-9]*\\)[ \\t]*liblog[ \\t].*/-DLIBLOG_LOG_TAG=\\1/p' \\\n        //       $(LOCAL_PATH)/event.logtags)\n        // so make sure we do not regret hard-coding it as follows:\n        \"-DLIBLOG_LOG_TAG=1005\",\n        \"-DSNET_EVENT_LOG_TAG=1397638484\",\n    ],\n    compile_multilib: \"both\",\n    stl: \"none\",\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/Android.mk",
    "content": "#\n# Copyright (C) 2008-2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nLOCAL_PATH := $(my-dir)\ninclude $(CLEAR_VARS)\n\n# This is what we want to do:\n#  liblog_cflags := $(shell \\\n#   sed -n \\\n#       's/^\\([0-9]*\\)[ \\t]*liblog[ \\t].*/-DLIBLOG_LOG_TAG=\\1/p' \\\n#       $(LOCAL_PATH)/event.logtags)\n# so make sure we do not regret hard-coding it as follows:\nliblog_cflags := -DLIBLOG_LOG_TAG=1005\nliblog_cflags += -DSNET_EVENT_LOG_TAG=1397638484\n\nliblog_sources := log_event_list.c log_event_write.c logger_write.c\nliblog_sources += config_write.c logger_name.c logger_lock.c\nliblog_host_sources := $(liblog_sources) fake_log_device.c event.logtags\nliblog_host_sources += fake_writer.c\nliblog_target_sources := $(liblog_sources) event_tag_map.c\nliblog_target_sources += config_read.c log_time.cpp log_is_loggable.c logprint.c\nliblog_target_sources += pmsg_reader.c pmsg_writer.c\nliblog_target_sources += logd_reader.c logd_writer.c logger_read.c\n\n# Shared and static library for host\n# ========================================================\nLOCAL_MODULE := liblog\nLOCAL_SRC_FILES := $(liblog_host_sources)\n# some files must not be compiled when building against Mingw\n# they correspond to features not used by our host development tools\n# which are also hard or even impossible to port to native Win32\nLOCAL_SRC_FILES_darwin := event_tag_map.c\nLOCAL_SRC_FILES_linux := event_tag_map.c\nLOCAL_SRC_FILES_windows := uio.c\nLOCAL_CFLAGS := -DFAKE_LOG_DEVICE=1 -Werror -fvisibility=hidden $(liblog_cflags)\nLOCAL_MULTILIB := both\nLOCAL_MODULE_HOST_OS := darwin linux windows\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := liblog\nLOCAL_WHOLE_STATIC_LIBRARIES := liblog\nLOCAL_LDLIBS_linux := -lrt\nLOCAL_MULTILIB := both\nLOCAL_CXX_STL := none\nLOCAL_MODULE_HOST_OS := darwin linux windows\ninclude $(BUILD_HOST_SHARED_LIBRARY)\n\n\n# Shared and static library for target\n# ========================================================\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := liblog\nLOCAL_SRC_FILES := $(liblog_target_sources)\nLOCAL_CFLAGS := -Werror -fvisibility=hidden $(liblog_cflags)\n# AddressSanitizer runtime library depends on liblog.\nLOCAL_SANITIZE := never\ninclude $(BUILD_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := liblog\nLOCAL_WHOLE_STATIC_LIBRARIES := liblog\nLOCAL_CFLAGS := -Werror -fvisibility=hidden $(liblog_cflags)\n\n# TODO: This is to work around b/24465209. Remove after root cause is fixed\nLOCAL_LDFLAGS_arm := -Wl,--hash-style=both\n\nLOCAL_SANITIZE := never\nLOCAL_CXX_STL := none\n\ninclude $(BUILD_SHARED_LIBRARY)\n\ninclude $(call first-makefiles-under,$(LOCAL_PATH))\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/NOTICE",
    "content": "\n   Copyright (c) 2005-2014, The Android Open Source Project\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/README",
    "content": "LIBLOG(3)               Android NDK Programming Manual               LIBLOG(3)\n\n\n\nNAME\n       liblog - Android NDK logger interfaces\n\nSYNOPSIS\n       #include <log/log.h>\n\n       ALOG(android_priority, tag, format, ...)\n       IF_ALOG(android_priority, tag)\n       LOG_PRI(priority, tag, format, ...)\n       LOG_PRI_VA(priority, tag, format, args)\n       #define LOG_TAG NULL\n       ALOGV(format, ...)\n       SLOGV(format, ...)\n       RLOGV(format, ...)\n       ALOGV_IF(cond, format, ...)\n       SLOGV_IF(cond, format, ...)\n       RLOGV_IF(cond, format, ...)\n       IF_ALOGC()\n       ALOGD(format, ...)\n       SLOGD(format, ...)\n       RLOGD(format, ...)\n       ALOGD_IF(cond, format, ...)\n       SLOGD_IF(cond, format, ...)\n       RLOGD_IF(cond, format, ...)\n       IF_ALOGD()\n       ALOGI(format, ...)\n       SLOGI(format, ...)\n       RLOGI(format, ...)\n       ALOGI_IF(cond, format, ...)\n       SLOGI_IF(cond, format, ...)\n       RLOGI_IF(cond, format, ...)\n       IF_ALOGI()\n       ALOGW(format, ...)\n       SLOGW(format, ...)\n       RLOGW(format, ...)\n       ALOGW_IF(cond, format, ...)\n       SLOGW_IF(cond, format, ...)\n       RLOGW_IF(cond, format, ...)\n       IF_ALOGW()\n       ALOGE(format, ...)\n       SLOGE(format, ...)\n       RLOGE(format, ...)\n       ALOGE_IF(cond, format, ...)\n       SLOGE_IF(cond, format, ...)\n       RLOGE_IF(cond, format, ...)\n       IF_ALOGE()\n       LOG_FATAL(format, ...)\n       LOG_ALWAYS_FATAL(format, ...)\n       LOG_FATAL_IF(cond, format, ...)\n       LOG_ALWAYS_FATAL_IF(cond, format, ...)\n       ALOG_ASSERT(cond, format, ...)\n       LOG_EVENT_INT(tag, value)\n       LOG_EVENT_LONG(tag, value)\n\n       Link with -llog\n\n       #include <log/logger.h>\n\n       log_id_t android_logger_get_id(struct logger *logger)\n       int android_logger_clear(struct logger *logger)\n       int android_logger_get_log_size(struct logger *logger)\n       int android_logger_get_log_readable_size(struct logger *logger)\n       int android_logger_get_log_version(struct logger *logger)\n\n       struct  logger_list  *android_logger_list_alloc(int  mode, unsigned int\n       tail, pid_t pid)\n       struct  logger  *android_logger_open(struct  logger_list  *logger_list,\n       log_id_t id)\n       struct  logger_list  *android_logger_list_open(log_id_t  id,  int mode,\n       unsigned int tail, pid_t pid)\n\n       int android_logger_list_read(struct  logger_list  *logger_list,  struct\n       log_msg *log_msg\n\n       void android_logger_list_free(struct logger_list *logger_list)\n\n       log_id_t android_name_to_log_id(const char *logName)\n       const char *android_log_id_to_name(log_id_t log_id)\n\n       Link with -llog\n\nDESCRIPTION\n       liblog  represents  an interface to the volatile Android Logging system\n       for NDK (Native) applications  and  libraries.  Interfaces  for  either\n       writing  or reading logs.  The log buffers are divided up in Main, Sys‐\n       tem, Radio and Events sub-logs.\n\n       The logging interfaces are a series of macros,  all  of  which  can  be\n       overridden individually in order to control the verbosity of the appli‐\n       cation or library.  [ASR]LOG[VDIWE] calls are used  to  log  to  BAsic,\n       System or Radio sub-logs in either the Verbose, Debug, Info, Warning or\n       Error priorities.  [ASR]LOG[VDIWE]_IF calls are used  to  perform  thus\n       based  on a condition being true.  IF_ALOG[VDIWE] calls are true if the\n       current LOG_TAG is enabled at the specified priority.  LOG_ALWAYS_FATAL\n       is  used to ALOG a message, then kill the process.  LOG_FATAL call is a\n       variant of LOG_ALWAYS_FATAL,  only  enabled  in  engineering,  and  not\n       release builds.  ALOG_ASSERT is used to ALOG a message if the condition\n       is  false;   the   condition   is   part   of   the   logged   message.\n       LOG_EVENT_(INT|LONG)  is  used  to  drop binary content into the Events\n       sub-log.\n\n       The log reading interfaces permit opening the  logs  either  singly  or\n       multiply,  retrieving  a  log  entry  at  a  time in time sorted order,\n       optionally limited to a specific pid and tail of the log(s) and finally\n       a  call closing the logs.  A single log can be opened with android_log‐\n       ger_list_open;  or  multiple  logs  can  be  opened  with  android_log‐\n       ger_list_alloc,  calling  in  turn the android_logger_open for each log\n       id.  Each entry can be retrieved  with  android_logger_list_read.   The\n       log(s) can be closed with android_logger_list_free.  The logs should be\n       opened  with an  ANDROID_LOG_RDONLY  mode.   ANDROID_LOG_NONBLOCK  mode\n       will report when the  log reading is done with an  EAGAIN  error return\n       code,  otherwise the  android_logger_list_read  call will block for new\n       entries.\n\n       The  ANDROID_LOG_WRAP  mode flag to the  android_logger_list_alloc_time\n       signals  logd to quiesce  the reader until the buffer is about to prune\n       at the start time then proceed to dumping content.\n\n       The  ANDROID_LOG_PSTORE mode flag to the android_logger_open is used to\n       switch from the active logs to the persistent logs from before the last\n       reboot.\n\n       The value returned by android_logger_open can be used as a parameter to\n       the  android_logger_clear  function to empty the sub-log.  It is recom‐\n       mended to only open log ANDROID_LOG_WRONLY in that case.\n\n       The value returned by android_logger_open can be used as a parameter to\n       the android_logger_get_log_(size|readable_size|version) to retrieve the\n       sub-log maximum size, readable size and log buffer format protocol ver‐\n       sion  respectively.  android_logger_get_id returns the id that was used\n       when  opening  the  sub-log.    It  is  recommended  to  open  the  log\n       ANDROID_LOG_RDONLY in these cases.\n\nERRORS\n       If messages fail, a negative error code will be returned to the caller.\n\n       The -ENOTCONN return code indicates that the logger daemon is stopped.\n\n       The  -EBADF return code indicates that the log access point can not be\n       opened, or the log buffer id is out of range.\n\n       For the  -EAGAIN  return code,  this means that the logging message was\n       temporarily backed-up either because of Denial Of Service (DOS) logging\n       pressure from some chatty application or service in the Android system,\n       or if too small of a value is set in /proc/sys/net/unix/max_dgram_qlen.\n       To aid in diagnosing the occurence of this,  a binary event from liblog\n       will be sent to the  log  daemon  once a  new  message  can get through\n       indicating how many  messages were  dropped  as a result.   Please take\n       action to resolve the structural problems at the source.\n\n       It is generally not advised for the caller to retry the  -EAGAIN return\n       code as  this  will  only  make the  problem(s)  worse  and  cause your\n       application to temporarily drop to the  logger daemon  priority,  BATCH\n       scheduling policy and background task cgroup. If you require a group of\n       messages to be passed atomically,  merge  them  into  one  message with\n       embedded newlines to the maximum length LOGGER_ENTRY_MAX_PAYLOAD.\n\n       Other return codes  from  writing operation can be returned.  Since the\n       library retries on EINTR, -EINTR should never be returned.\n\nSEE ALSO\n       syslogd(8)\n\n\n\n                                  24 Jan 2014                        LIBLOG(3)\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/config_read.c",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"config_read.h\"\n#include \"logger.h\"\n\nLIBLOG_HIDDEN struct listnode __android_log_transport_read =\n    { &__android_log_transport_read, &__android_log_transport_read };\nLIBLOG_HIDDEN struct listnode __android_log_persist_read =\n    { &__android_log_persist_read, &__android_log_persist_read };\n\nstatic void __android_log_add_transport(\n        struct listnode *list, struct android_log_transport_read *transport) {\n    size_t i;\n\n    /* Try to keep one functioning transport for each log buffer id */\n    for (i = LOG_ID_MIN; i < LOG_ID_MAX; i++) {\n        struct android_log_transport_read *transp;\n\n        if (list_empty(list)) {\n            if (!transport->available || ((*transport->available)(i) >= 0)) {\n                list_add_tail(list, &transport->node);\n                return;\n            }\n        } else {\n            read_transport_for_each(transp, list) {\n                if (!transp->available) {\n                    return;\n                }\n                if (((*transp->available)(i) < 0) &&\n                        (!transport->available ||\n                            ((*transport->available)(i) >= 0))) {\n                    list_add_tail(list, &transport->node);\n                    return;\n                }\n            }\n        }\n    }\n}\n\nLIBLOG_HIDDEN void __android_log_config_read() {\n#if (FAKE_LOG_DEVICE == 0)\n    extern struct android_log_transport_read logdLoggerRead;\n    extern struct android_log_transport_read pmsgLoggerRead;\n\n    __android_log_add_transport(&__android_log_transport_read, &logdLoggerRead);\n    __android_log_add_transport(&__android_log_persist_read, &pmsgLoggerRead);\n#endif\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/config_read.h",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBLOG_CONFIG_READ_H__\n#define _LIBLOG_CONFIG_READ_H__\n\n#include <cutils/list.h>\n\n#include \"log_portability.h\"\n\n__BEGIN_DECLS\n\nextern LIBLOG_HIDDEN struct listnode __android_log_transport_read;\nextern LIBLOG_HIDDEN struct listnode __android_log_persist_read;\n\n#define read_transport_for_each(transp, transports)                         \\\n    for (transp = node_to_item((transports)->next,                          \\\n                               struct android_log_transport_read, node);    \\\n         (transp != node_to_item(transports,                                \\\n                                 struct android_log_transport_read, node)); \\\n         transp = node_to_item(transp->node.next,                           \\\n                               struct android_log_transport_read, node))    \\\n\n#define read_transport_for_each_safe(transp, n, transports)                 \\\n    for (transp = node_to_item((transports)->next,                          \\\n                               struct android_log_transport_read, node),    \\\n         n = transp->node.next;                                             \\\n         (transp != node_to_item(transports,                                \\\n                                 struct android_log_transport_read, node)); \\\n         transp = node_to_item(n, struct android_log_transport_read, node), \\\n         n = transp->node.next)\n\nLIBLOG_HIDDEN void __android_log_config_read();\n\n__END_DECLS\n\n#endif /* _LIBLOG_CONFIG_READ_H__ */\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/config_write.c",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"config_write.h\"\n#include \"logger.h\"\n\nLIBLOG_HIDDEN struct listnode __android_log_transport_write =\n    { &__android_log_transport_write, &__android_log_transport_write };\nLIBLOG_HIDDEN struct listnode __android_log_persist_write =\n    { &__android_log_persist_write, &__android_log_persist_write};\n\nstatic void __android_log_add_transport(\n        struct listnode *list, struct android_log_transport_write *transport) {\n    size_t i;\n\n    /* Try to keep one functioning transport for each log buffer id */\n    for (i = LOG_ID_MIN; i < LOG_ID_MAX; i++) {\n        struct android_log_transport_write *transp;\n\n        if (list_empty(list)) {\n            if (!transport->available || ((*transport->available)(i) >= 0)) {\n                list_add_tail(list, &transport->node);\n                return;\n            }\n        } else {\n            write_transport_for_each(transp, list) {\n                if (!transp->available) {\n                    return;\n                }\n                if (((*transp->available)(i) < 0) &&\n                        (!transport->available ||\n                            ((*transport->available)(i) >= 0))) {\n                    list_add_tail(list, &transport->node);\n                    return;\n                }\n            }\n        }\n    }\n}\n\nLIBLOG_HIDDEN void __android_log_config_write() {\n#if (FAKE_LOG_DEVICE == 0)\n    extern struct android_log_transport_write logdLoggerWrite;\n    extern struct android_log_transport_write pmsgLoggerWrite;\n\n    __android_log_add_transport(&__android_log_transport_write, &logdLoggerWrite);\n    __android_log_add_transport(&__android_log_persist_write, &pmsgLoggerWrite);\n#else\n    extern struct android_log_transport_write fakeLoggerWrite;\n\n    __android_log_add_transport(&__android_log_transport_write, &fakeLoggerWrite);\n#endif\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/config_write.h",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBLOG_CONFIG_WRITE_H__\n#define _LIBLOG_CONFIG_WRITE_H__\n\n#include <cutils/list.h>\n\n#include \"log_portability.h\"\n\n__BEGIN_DECLS\n\nextern LIBLOG_HIDDEN struct listnode __android_log_transport_write;\nextern LIBLOG_HIDDEN struct listnode __android_log_persist_write;\n\n#define write_transport_for_each(transp, transports)                         \\\n    for (transp = node_to_item((transports)->next,                           \\\n                               struct android_log_transport_write, node);    \\\n         (transp != node_to_item(transports,                                 \\\n                                 struct android_log_transport_write, node)); \\\n         transp = node_to_item(transp->node.next,                            \\\n                               struct android_log_transport_write, node))    \\\n\n#define write_transport_for_each_safe(transp, n, transports)                 \\\n    for (transp = node_to_item((transports)->next,                           \\\n                               struct android_log_transport_write, node),    \\\n         n = transp->node.next;                                              \\\n         (transp != node_to_item(transports,                                 \\\n                                 struct android_log_transport_write, node)); \\\n         transp = node_to_item(n, struct android_log_transport_write, node), \\\n         n = transp->node.next)\n\nLIBLOG_HIDDEN void __android_log_config_write();\n\n__END_DECLS\n\n#endif /* _LIBLOG_CONFIG_WRITE_H__ */\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/event.logtags",
    "content": "# The entries in this file map a sparse set of log tag numbers to tag names.\n# This is installed on the device, in /system/etc, and parsed by logcat.\n#\n# Tag numbers are decimal integers, from 0 to 2^31.  (Let's leave the\n# negative values alone for now.)\n#\n# Tag names are one or more ASCII letters and numbers or underscores, i.e.\n# \"[A-Z][a-z][0-9]_\".  Do not include spaces or punctuation (the former\n# impacts log readability, the latter makes regex searches more annoying).\n#\n# Tag numbers and names are separated by whitespace.  Blank lines and lines\n# starting with '#' are ignored.\n#\n# Optionally, after the tag names can be put a description for the value(s)\n# of the tag. Description are in the format\n#    (<name>|data type[|data unit])\n# Multiple values are separated by commas.\n#\n# The data type is a number from the following values:\n# 1: int\n# 2: long\n# 3: string\n# 4: list\n#\n# The data unit is a number taken from the following list:\n# 1: Number of objects\n# 2: Number of bytes\n# 3: Number of milliseconds\n# 4: Number of allocations\n# 5: Id\n# 6: Percent\n# Default value for data of type int/long is 2 (bytes).\n#\n# TODO: generate \".java\" and \".h\" files with integer constants from this file.\n\n1005  liblog (dropped|1)\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/event_tag_map.c",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <assert.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/mman.h>\n\n#include <log/event_tag_map.h>\n#include <log/log.h>\n\n#include \"log_portability.h\"\n\n#define OUT_TAG \"EventTagMap\"\n\n/*\n * Single entry.\n */\ntypedef struct EventTag {\n    unsigned int    tagIndex;\n    const char*     tagStr;\n} EventTag;\n\n/*\n * Map.\n */\nstruct EventTagMap {\n    /* memory-mapped source file; we get strings from here */\n    void*           mapAddr;\n    size_t          mapLen;\n\n    /* array of event tags, sorted numerically by tag index */\n    EventTag*       tagArray;\n    int             numTags;\n};\n\n/* fwd */\nstatic int processFile(EventTagMap* map);\nstatic int countMapLines(const EventTagMap* map);\nstatic int parseMapLines(EventTagMap* map);\nstatic int scanTagLine(char** pData, EventTag* tag, int lineNum);\nstatic int sortTags(EventTagMap* map);\n\n\n/*\n * Open the map file and allocate a structure to manage it.\n *\n * We create a private mapping because we want to terminate the log tag\n * strings with '\\0'.\n */\nLIBLOG_ABI_PUBLIC EventTagMap* android_openEventTagMap(const char* fileName)\n{\n    EventTagMap* newTagMap;\n    off_t end;\n    int fd = -1;\n\n    newTagMap = calloc(1, sizeof(EventTagMap));\n    if (newTagMap == NULL)\n        return NULL;\n\n    fd = open(fileName, O_RDONLY | O_CLOEXEC);\n    if (fd < 0) {\n        fprintf(stderr, \"%s: unable to open map '%s': %s\\n\",\n            OUT_TAG, fileName, strerror(errno));\n        goto fail;\n    }\n\n    end = lseek(fd, 0L, SEEK_END);\n    (void) lseek(fd, 0L, SEEK_SET);\n    if (end < 0) {\n        fprintf(stderr, \"%s: unable to seek map '%s'\\n\", OUT_TAG, fileName);\n        goto fail;\n    }\n\n    newTagMap->mapAddr = mmap(NULL, end, PROT_READ | PROT_WRITE, MAP_PRIVATE,\n                                fd, 0);\n    if (newTagMap->mapAddr == MAP_FAILED) {\n        fprintf(stderr, \"%s: mmap(%s) failed: %s\\n\",\n            OUT_TAG, fileName, strerror(errno));\n        goto fail;\n    }\n    newTagMap->mapLen = end;\n\n    if (processFile(newTagMap) != 0)\n        goto fail;\n\n    return newTagMap;\n\nfail:\n    android_closeEventTagMap(newTagMap);\n    if (fd >= 0)\n        close(fd);\n    return NULL;\n}\n\n/*\n * Close the map.\n */\nLIBLOG_ABI_PUBLIC void android_closeEventTagMap(EventTagMap* map)\n{\n    if (map == NULL)\n        return;\n\n    munmap(map->mapAddr, map->mapLen);\n    free(map);\n}\n\n/*\n * Look up an entry in the map.\n *\n * The entries are sorted by tag number, so we can do a binary search.\n */\nLIBLOG_ABI_PUBLIC const char* android_lookupEventTag(const EventTagMap* map,\n                                                     int tag)\n{\n    int hi, lo, mid;\n\n    lo = 0;\n    hi = map->numTags-1;\n\n    while (lo <= hi) {\n        int cmp;\n\n        mid = (lo+hi)/2;\n        cmp = map->tagArray[mid].tagIndex - tag;\n        if (cmp < 0) {\n            /* tag is bigger */\n            lo = mid + 1;\n        } else if (cmp > 0) {\n            /* tag is smaller */\n            hi = mid - 1;\n        } else {\n            /* found */\n            return map->tagArray[mid].tagStr;\n        }\n    }\n\n    return NULL;\n}\n\n\n\n/*\n * Determine whether \"c\" is a whitespace char.\n */\nstatic inline int isCharWhitespace(char c)\n{\n    return (c == ' ' || c == '\\n' || c == '\\r' || c == '\\t');\n}\n\n/*\n * Determine whether \"c\" is a valid tag char.\n */\nstatic inline int isCharValidTag(char c)\n{\n    return ((c >= 'A' && c <= 'Z') ||\n            (c >= 'a' && c <= 'z') ||\n            (c >= '0' && c <= '9') ||\n            (c == '_'));\n}\n\n/*\n * Determine whether \"c\" is a valid decimal digit.\n */\nstatic inline int isCharDigit(char c)\n{\n    return (c >= '0' && c <= '9');\n}\n\n\n/*\n * Crunch through the file, parsing the contents and creating a tag index.\n */\nstatic int processFile(EventTagMap* map)\n{\n    /* get a tag count */\n    map->numTags = countMapLines(map);\n    if (map->numTags < 0)\n        return -1;\n\n    //printf(\"+++ found %d tags\\n\", map->numTags);\n\n    /* allocate storage for the tag index array */\n    map->tagArray = calloc(1, sizeof(EventTag) * map->numTags);\n    if (map->tagArray == NULL)\n        return -1;\n\n    /* parse the file, null-terminating tag strings */\n    if (parseMapLines(map) != 0) {\n        fprintf(stderr, \"%s: file parse failed\\n\", OUT_TAG);\n        return -1;\n    }\n\n    /* sort the tags and check for duplicates */\n    if (sortTags(map) != 0)\n        return -1;\n\n    return 0;\n}\n\n/*\n * Run through all lines in the file, determining whether they're blank,\n * comments, or possibly have a tag entry.\n *\n * This is a very \"loose\" scan.  We don't try to detect syntax errors here.\n * The later pass is more careful, but the number of tags found there must\n * match the number of tags found here.\n *\n * Returns the number of potential tag entries found.\n */\nstatic int countMapLines(const EventTagMap* map)\n{\n    int numTags, unknown;\n    const char* cp;\n    const char* endp;\n\n    cp = (const char*) map->mapAddr;\n    endp = cp + map->mapLen;\n\n    numTags = 0;\n    unknown = 1;\n    while (cp < endp) {\n        if (*cp == '\\n') {\n            unknown = 1;\n        } else if (unknown) {\n            if (isCharDigit(*cp)) {\n                /* looks like a tag to me */\n                numTags++;\n                unknown = 0;\n            } else if (isCharWhitespace(*cp)) {\n                /* might be leading whitespace before tag num, keep going */\n            } else {\n                /* assume comment; second pass can complain in detail */\n                unknown = 0;\n            }\n        } else {\n            /* we've made up our mind; just scan to end of line */\n        }\n        cp++;\n    }\n\n    return numTags;\n}\n\n/*\n * Parse the tags out of the file.\n */\nstatic int parseMapLines(EventTagMap* map)\n{\n    int tagNum, lineStart, lineNum;\n    char* cp;\n    char* endp;\n\n    cp = (char*) map->mapAddr;\n    endp = cp + map->mapLen;\n\n    /* insist on EOL at EOF; simplifies parsing and null-termination */\n    if (*(endp-1) != '\\n') {\n        fprintf(stderr, \"%s: map file missing EOL on last line\\n\", OUT_TAG);\n        return -1;\n    }\n\n    tagNum = 0;\n    lineStart = 1;\n    lineNum = 1;\n    while (cp < endp) {\n        //printf(\"{%02x}\", *cp); fflush(stdout);\n        if (*cp == '\\n') {\n            lineStart = 1;\n            lineNum++;\n        } else if (lineStart) {\n            if (*cp == '#') {\n                /* comment; just scan to end */\n                lineStart = 0;\n            } else if (isCharDigit(*cp)) {\n                /* looks like a tag; scan it out */\n                if (tagNum >= map->numTags) {\n                    fprintf(stderr,\n                        \"%s: more tags than expected (%d)\\n\", OUT_TAG, tagNum);\n                    return -1;\n                }\n                if (scanTagLine(&cp, &map->tagArray[tagNum], lineNum) != 0)\n                    return -1;\n                tagNum++;\n                lineNum++;      // we eat the '\\n'\n                /* leave lineStart==1 */\n            } else if (isCharWhitespace(*cp)) {\n                /* looks like leading whitespace; keep scanning */\n            } else {\n                fprintf(stderr,\n                    \"%s: unexpected chars (0x%02x) in tag number on line %d\\n\",\n                    OUT_TAG, *cp, lineNum);\n                return -1;\n            }\n        } else {\n            /* this is a blank or comment line */\n        }\n        cp++;\n    }\n\n    if (tagNum != map->numTags) {\n        fprintf(stderr, \"%s: parsed %d tags, expected %d\\n\",\n            OUT_TAG, tagNum, map->numTags);\n        return -1;\n    }\n\n    return 0;\n}\n\n/*\n * Scan one tag line.\n *\n * \"*pData\" should be pointing to the first digit in the tag number.  On\n * successful return, it will be pointing to the last character in the\n * tag line (i.e. the character before the start of the next line).\n *\n * Returns 0 on success, nonzero on failure.\n */\nstatic int scanTagLine(char** pData, EventTag* tag, int lineNum)\n{\n    char* cp = *pData;\n    char* startp;\n    char* endp;\n    unsigned long val;\n\n    startp = cp;\n    while (isCharDigit(*++cp))\n        ;\n    *cp = '\\0';\n\n    val = strtoul(startp, &endp, 10);\n    assert(endp == cp);\n    if (endp != cp)\n        fprintf(stderr, \"ARRRRGH\\n\");\n\n    tag->tagIndex = val;\n\n    while (*++cp != '\\n' && isCharWhitespace(*cp))\n        ;\n\n    if (*cp == '\\n') {\n        fprintf(stderr,\n            \"%s: missing tag string on line %d\\n\", OUT_TAG, lineNum);\n        return -1;\n    }\n\n    tag->tagStr = cp;\n\n    while (isCharValidTag(*++cp))\n        ;\n\n    if (*cp == '\\n') {\n        /* null terminate and return */\n        *cp = '\\0';\n    } else if (isCharWhitespace(*cp)) {\n        /* CRLF or trailin spaces; zap this char, then scan for the '\\n' */\n        *cp = '\\0';\n\n        /* just ignore the rest of the line till \\n\n        TODO: read the tag description that follows the tag name\n        */\n        while (*++cp != '\\n') {\n        }\n    } else {\n        fprintf(stderr,\n            \"%s: invalid tag chars on line %d\\n\", OUT_TAG, lineNum);\n        return -1;\n    }\n\n    *pData = cp;\n\n    //printf(\"+++ Line %d: got %d '%s'\\n\", lineNum, tag->tagIndex, tag->tagStr);\n    return 0;\n}\n\n/*\n * Compare two EventTags.\n */\nstatic int compareEventTags(const void* v1, const void* v2)\n{\n    const EventTag* tag1 = (const EventTag*) v1;\n    const EventTag* tag2 = (const EventTag*) v2;\n\n    return tag1->tagIndex - tag2->tagIndex;\n}\n\n/*\n * Sort the EventTag array so we can do fast lookups by tag index.  After\n * the sort we do a quick check for duplicate tag indices.\n *\n * Returns 0 on success.\n */\nstatic int sortTags(EventTagMap* map)\n{\n    int i;\n\n    qsort(map->tagArray, map->numTags, sizeof(EventTag), compareEventTags);\n\n    for (i = 1; i < map->numTags; i++) {\n        if (map->tagArray[i].tagIndex == map->tagArray[i-1].tagIndex) {\n            fprintf(stderr, \"%s: duplicate tag entries (%d:%s and %d:%s)\\n\",\n                OUT_TAG,\n                map->tagArray[i].tagIndex, map->tagArray[i].tagStr,\n                map->tagArray[i-1].tagIndex, map->tagArray[i-1].tagStr);\n            return -1;\n        }\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/fake_log_device.c",
    "content": "/*\n * Copyright (C) 2008-2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/*\n * Intercepts log messages intended for the Android log device.\n * When running in the context of the simulator, the messages are\n * passed on to the underlying (fake) log device.  When not in the\n * simulator, messages are printed to stderr.\n */\n#include <ctype.h>\n#include <errno.h>\n#include <fcntl.h>\n#if !defined(_WIN32)\n#include <pthread.h>\n#endif\n#include <stdlib.h>\n#include <string.h>\n\n#include <log/logd.h>\n\n#include \"fake_log_device.h\"\n#include \"log_portability.h\"\n\n#define kMaxTagLen  16      /* from the long-dead utils/Log.cpp */\n\n#define kTagSetSize 16      /* arbitrary */\n\n#if 0\n#define TRACE(...) printf(\"fake_log_device: \" __VA_ARGS__)\n#else\n#define TRACE(...) ((void)0)\n#endif\n\n/* from the long-dead utils/Log.cpp */\ntypedef enum {\n    FORMAT_OFF = 0,\n    FORMAT_BRIEF,\n    FORMAT_PROCESS,\n    FORMAT_TAG,\n    FORMAT_THREAD,\n    FORMAT_RAW,\n    FORMAT_TIME,\n    FORMAT_THREADTIME,\n    FORMAT_LONG\n} LogFormat;\n\n\n/*\n * Log driver state.\n */\ntypedef struct LogState {\n    /* the fake fd that's seen by the user */\n    int     fakeFd;\n\n    /* a printable name for this fake device */\n    char   debugName[sizeof(\"/dev/log/security\")];\n\n    /* nonzero if this is a binary log */\n    int     isBinary;\n\n    /* global minimum priority */\n    int     globalMinPriority;\n\n    /* output format */\n    LogFormat outputFormat;\n\n    /* tags and priorities */\n    struct {\n        char    tag[kMaxTagLen];\n        int     minPriority;\n    } tagSet[kTagSetSize];\n} LogState;\n\n\n#if !defined(_WIN32)\n/*\n * Locking.  Since we're emulating a device, we need to be prepared\n * to have multiple callers at the same time.  This lock is used\n * to both protect the fd list and to prevent LogStates from being\n * freed out from under a user.\n */\nstatic pthread_mutex_t fakeLogDeviceLock = PTHREAD_MUTEX_INITIALIZER;\n\nstatic void lock()\n{\n    /*\n     * If we trigger a signal handler in the middle of locked activity and the\n     * signal handler logs a message, we could get into a deadlock state.\n     */\n    pthread_mutex_lock(&fakeLogDeviceLock);\n}\n\nstatic void unlock()\n{\n    pthread_mutex_unlock(&fakeLogDeviceLock);\n}\n\n#else   // !defined(_WIN32)\n\n#define lock() ((void)0)\n#define unlock() ((void)0)\n\n#endif  // !defined(_WIN32)\n\n\n/*\n * File descriptor management.\n */\n#define FAKE_FD_BASE 10000\n#define MAX_OPEN_LOGS 8\nstatic LogState openLogTable[MAX_OPEN_LOGS];\n\n/*\n * Allocate an fd and associate a new LogState with it.\n * The fd is available via the fakeFd field of the return value.\n */\nstatic LogState *createLogState()\n{\n    size_t i;\n\n    for (i = 0; i < (sizeof(openLogTable) / sizeof(openLogTable[0])); i++) {\n        if (openLogTable[i].fakeFd == 0) {\n            openLogTable[i].fakeFd = FAKE_FD_BASE + i;\n            return &openLogTable[i];\n        }\n    }\n    return NULL;\n}\n\n/*\n * Translate an fd to a LogState.\n */\nstatic LogState *fdToLogState(int fd)\n{\n    if (fd >= FAKE_FD_BASE && fd < FAKE_FD_BASE + MAX_OPEN_LOGS) {\n        return &openLogTable[fd - FAKE_FD_BASE];\n    }\n    return NULL;\n}\n\n/*\n * Unregister the fake fd and free the memory it pointed to.\n */\nstatic void deleteFakeFd(int fd)\n{\n    LogState *ls;\n\n    lock();\n\n    ls = fdToLogState(fd);\n    if (ls != NULL) {\n        memset(&openLogTable[fd - FAKE_FD_BASE], 0, sizeof(openLogTable[0]));\n    }\n\n    unlock();\n}\n\n/*\n * Configure logging based on ANDROID_LOG_TAGS environment variable.  We\n * need to parse a string that looks like\n *\n *   *:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i\n *\n * The tag (or '*' for the global level) comes first, followed by a colon\n * and a letter indicating the minimum priority level we're expected to log.\n * This can be used to reveal or conceal logs with specific tags.\n *\n * We also want to check ANDROID_PRINTF_LOG to determine how the output\n * will look.\n */\nstatic void configureInitialState(const char* pathName, LogState* logState)\n{\n    static const int kDevLogLen = sizeof(\"/dev/log/\") - 1;\n\n    strncpy(logState->debugName, pathName, sizeof(logState->debugName));\n    logState->debugName[sizeof(logState->debugName) - 1] = '\\0';\n\n    /* identify binary logs */\n    if (!strcmp(pathName + kDevLogLen, \"events\") ||\n            !strcmp(pathName + kDevLogLen, \"security\")) {\n        logState->isBinary = 1;\n    }\n\n    /* global min priority defaults to \"info\" level */\n    logState->globalMinPriority = ANDROID_LOG_INFO;\n\n    /*\n     * This is based on the the long-dead utils/Log.cpp code.\n     */\n    const char* tags = getenv(\"ANDROID_LOG_TAGS\");\n    TRACE(\"Found ANDROID_LOG_TAGS='%s'\\n\", tags);\n    if (tags != NULL) {\n        int entry = 0;\n\n        while (*tags != '\\0') {\n            char tagName[kMaxTagLen];\n            int i, minPrio;\n\n            while (isspace(*tags))\n                tags++;\n\n            i = 0;\n            while (*tags != '\\0' && !isspace(*tags) && *tags != ':' &&\n                    i < kMaxTagLen) {\n                tagName[i++] = *tags++;\n            }\n            if (i == kMaxTagLen) {\n                TRACE(\"ERROR: env tag too long (%d chars max)\\n\", kMaxTagLen-1);\n                return;\n            }\n            tagName[i] = '\\0';\n\n            /* default priority, if there's no \":\" part; also zero out '*' */\n            minPrio = ANDROID_LOG_VERBOSE;\n            if (tagName[0] == '*' && tagName[1] == '\\0') {\n                minPrio = ANDROID_LOG_DEBUG;\n                tagName[0] = '\\0';\n            }\n\n            if (*tags == ':') {\n                tags++;\n                if (*tags >= '0' && *tags <= '9') {\n                    if (*tags >= ('0' + ANDROID_LOG_SILENT))\n                        minPrio = ANDROID_LOG_VERBOSE;\n                    else\n                        minPrio = *tags - '\\0';\n                } else {\n                    switch (*tags) {\n                    case 'v':   minPrio = ANDROID_LOG_VERBOSE;  break;\n                    case 'd':   minPrio = ANDROID_LOG_DEBUG;    break;\n                    case 'i':   minPrio = ANDROID_LOG_INFO;     break;\n                    case 'w':   minPrio = ANDROID_LOG_WARN;     break;\n                    case 'e':   minPrio = ANDROID_LOG_ERROR;    break;\n                    case 'f':   minPrio = ANDROID_LOG_FATAL;    break;\n                    case 's':   minPrio = ANDROID_LOG_SILENT;   break;\n                    default:    minPrio = ANDROID_LOG_DEFAULT;  break;\n                    }\n                }\n\n                tags++;\n                if (*tags != '\\0' && !isspace(*tags)) {\n                    TRACE(\"ERROR: garbage in tag env; expected whitespace\\n\");\n                    TRACE(\"       env='%s'\\n\", tags);\n                    return;\n                }\n            }\n\n            if (tagName[0] == 0) {\n                logState->globalMinPriority = minPrio;\n                TRACE(\"+++ global min prio %d\\n\", logState->globalMinPriority);\n            } else {\n                logState->tagSet[entry].minPriority = minPrio;\n                strcpy(logState->tagSet[entry].tag, tagName);\n                TRACE(\"+++ entry %d: %s:%d\\n\",\n                    entry,\n                    logState->tagSet[entry].tag,\n                    logState->tagSet[entry].minPriority);\n                entry++;\n            }\n        }\n    }\n\n\n    /*\n     * Taken from the long-dead utils/Log.cpp\n     */\n    const char* fstr = getenv(\"ANDROID_PRINTF_LOG\");\n    LogFormat format;\n    if (fstr == NULL) {\n        format = FORMAT_BRIEF;\n    } else {\n        if (strcmp(fstr, \"brief\") == 0)\n            format = FORMAT_BRIEF;\n        else if (strcmp(fstr, \"process\") == 0)\n            format = FORMAT_PROCESS;\n        else if (strcmp(fstr, \"tag\") == 0)\n            format = FORMAT_PROCESS;\n        else if (strcmp(fstr, \"thread\") == 0)\n            format = FORMAT_PROCESS;\n        else if (strcmp(fstr, \"raw\") == 0)\n            format = FORMAT_PROCESS;\n        else if (strcmp(fstr, \"time\") == 0)\n            format = FORMAT_PROCESS;\n        else if (strcmp(fstr, \"long\") == 0)\n            format = FORMAT_PROCESS;\n        else\n            format = (LogFormat) atoi(fstr);        // really?!\n    }\n\n    logState->outputFormat = format;\n}\n\n/*\n * Return a human-readable string for the priority level.  Always returns\n * a valid string.\n */\nstatic const char* getPriorityString(int priority)\n{\n    /* the first character of each string should be unique */\n    static const char* priorityStrings[] = {\n        \"Verbose\", \"Debug\", \"Info\", \"Warn\", \"Error\", \"Assert\"\n    };\n    int idx;\n\n    idx = (int)priority - (int)ANDROID_LOG_VERBOSE;\n    if (idx < 0 ||\n            idx >= (int)(sizeof(priorityStrings) / sizeof(priorityStrings[0])))\n        return \"?unknown?\";\n    return priorityStrings[idx];\n}\n\n#if defined(_WIN32)\n/*\n * WIN32 does not have writev().\n * Make up something to replace it.\n */\nstatic ssize_t fake_writev(int fd, const struct iovec *iov, int iovcnt) {\n    ssize_t result = 0;\n    const struct iovec* end = iov + iovcnt;\n    for (; iov < end; iov++) {\n        ssize_t w = write(fd, iov->iov_base, iov->iov_len);\n        if (w != (ssize_t) iov->iov_len) {\n            if (w < 0)\n                return w;\n            return result + w;\n        }\n        result += w;\n    }\n    return result;\n}\n\n#define writev fake_writev\n#endif\n\n\n/*\n * Write a filtered log message to stderr.\n *\n * Log format parsing taken from the long-dead utils/Log.cpp.\n */\nstatic void showLog(LogState *state,\n        int logPrio, const char* tag, const char* msg)\n{\n#if !defined(_WIN32)\n    struct tm tmBuf;\n#endif\n    struct tm* ptm;\n    char timeBuf[32];\n    char prefixBuf[128], suffixBuf[128];\n    char priChar;\n    time_t when;\n#if !defined(_WIN32)\n    pid_t pid, tid;\n#else\n    uint32_t pid, tid;\n#endif\n\n    TRACE(\"LOG %d: %s %s\", logPrio, tag, msg);\n\n    priChar = getPriorityString(logPrio)[0];\n    when = time(NULL);\n    pid = tid = getpid();       // find gettid()?\n\n    /*\n     * Get the current date/time in pretty form\n     *\n     * It's often useful when examining a log with \"less\" to jump to\n     * a specific point in the file by searching for the date/time stamp.\n     * For this reason it's very annoying to have regexp meta characters\n     * in the time stamp.  Don't use forward slashes, parenthesis,\n     * brackets, asterisks, or other special chars here.\n     */\n#if !defined(_WIN32)\n    ptm = localtime_r(&when, &tmBuf);\n#else\n    ptm = localtime(&when);\n#endif\n    //strftime(timeBuf, sizeof(timeBuf), \"%Y-%m-%d %H:%M:%S\", ptm);\n    strftime(timeBuf, sizeof(timeBuf), \"%m-%d %H:%M:%S\", ptm);\n\n    /*\n     * Construct a buffer containing the log header and log message.\n     */\n    size_t prefixLen, suffixLen;\n\n    switch (state->outputFormat) {\n    case FORMAT_TAG:\n        prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),\n            \"%c/%-8s: \", priChar, tag);\n        strcpy(suffixBuf, \"\\n\"); suffixLen = 1;\n        break;\n    case FORMAT_PROCESS:\n        prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),\n            \"%c(%5d) \", priChar, pid);\n        suffixLen = snprintf(suffixBuf, sizeof(suffixBuf),\n            \"  (%s)\\n\", tag);\n        break;\n    case FORMAT_THREAD:\n        prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),\n            \"%c(%5d:%5d) \", priChar, pid, tid);\n        strcpy(suffixBuf, \"\\n\"); suffixLen = 1;\n        break;\n    case FORMAT_RAW:\n        prefixBuf[0] = 0; prefixLen = 0;\n        strcpy(suffixBuf, \"\\n\"); suffixLen = 1;\n        break;\n    case FORMAT_TIME:\n        prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),\n            \"%s %-8s\\n\\t\", timeBuf, tag);\n        strcpy(suffixBuf, \"\\n\"); suffixLen = 1;\n        break;\n    case FORMAT_THREADTIME:\n        prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),\n            \"%s %5d %5d %c %-8s \\n\\t\", timeBuf, pid, tid, priChar, tag);\n        strcpy(suffixBuf, \"\\n\"); suffixLen = 1;\n        break;\n    case FORMAT_LONG:\n        prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),\n            \"[ %s %5d:%5d %c/%-8s ]\\n\",\n            timeBuf, pid, tid, priChar, tag);\n        strcpy(suffixBuf, \"\\n\\n\"); suffixLen = 2;\n        break;\n    default:\n        prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),\n            \"%c/%-8s(%5d): \", priChar, tag, pid);\n        strcpy(suffixBuf, \"\\n\"); suffixLen = 1;\n        break;\n     }\n\n    /*\n     * Figure out how many lines there will be.\n     */\n    const char* end = msg + strlen(msg);\n    size_t numLines = 0;\n    const char* p = msg;\n    while (p < end) {\n        if (*p++ == '\\n') numLines++;\n    }\n    if (p > msg && *(p-1) != '\\n') {\n        numLines++;\n    }\n\n    /*\n     * Create an array of iovecs large enough to write all of\n     * the lines with a prefix and a suffix.\n     */\n    const size_t INLINE_VECS = 64;\n    const size_t MAX_LINES   = ((size_t)~0)/(3*sizeof(struct iovec*));\n    struct iovec stackVec[INLINE_VECS];\n    struct iovec* vec = stackVec;\n    size_t numVecs;\n\n    if (numLines > MAX_LINES)\n        numLines = MAX_LINES;\n\n    numVecs = numLines * 3;  // 3 iovecs per line.\n    if (numVecs > INLINE_VECS) {\n        vec = (struct iovec*)malloc(sizeof(struct iovec)*numVecs);\n        if (vec == NULL) {\n            msg = \"LOG: write failed, no memory\";\n            numVecs = INLINE_VECS;\n            numLines = numVecs / 3;\n            vec = stackVec;\n        }\n    }\n\n    /*\n     * Fill in the iovec pointers.\n     */\n    p = msg;\n    struct iovec* v = vec;\n    int totalLen = 0;\n    while (numLines > 0 && p < end) {\n        if (prefixLen > 0) {\n            v->iov_base = prefixBuf;\n            v->iov_len = prefixLen;\n            totalLen += prefixLen;\n            v++;\n        }\n        const char* start = p;\n        while (p < end && *p != '\\n') {\n            p++;\n        }\n        if ((p-start) > 0) {\n            v->iov_base = (void*)start;\n            v->iov_len = p-start;\n            totalLen += p-start;\n            v++;\n        }\n        if (*p == '\\n') p++;\n        if (suffixLen > 0) {\n            v->iov_base = suffixBuf;\n            v->iov_len = suffixLen;\n            totalLen += suffixLen;\n            v++;\n        }\n        numLines -= 1;\n    }\n\n    /*\n     * Write the entire message to the log file with a single writev() call.\n     * We need to use this rather than a collection of printf()s on a FILE*\n     * because of multi-threading and multi-process issues.\n     *\n     * If the file was not opened with O_APPEND, this will produce interleaved\n     * output when called on the same file from multiple processes.\n     *\n     * If the file descriptor is actually a network socket, the writev()\n     * call may return with a partial write.  Putting the writev() call in\n     * a loop can result in interleaved data.  This can be alleviated\n     * somewhat by wrapping the writev call in the Mutex.\n     */\n\n    for(;;) {\n        int cc = writev(fileno(stderr), vec, v-vec);\n\n        if (cc == totalLen) break;\n\n        if (cc < 0) {\n            if(errno == EINTR) continue;\n\n                /* can't really log the failure; for now, throw out a stderr */\n            fprintf(stderr, \"+++ LOG: write failed (errno=%d)\\n\", errno);\n            break;\n        } else {\n                /* shouldn't happen when writing to file or tty */\n            fprintf(stderr, \"+++ LOG: write partial (%d of %d)\\n\", cc, totalLen);\n            break;\n        }\n    }\n\n    /* if we allocated storage for the iovecs, free it */\n    if (vec != stackVec)\n        free(vec);\n}\n\n\n/*\n * Receive a log message.  We happen to know that \"vector\" has three parts:\n *\n *  priority (1 byte)\n *  tag (N bytes -- null-terminated ASCII string)\n *  message (N bytes -- null-terminated ASCII string)\n */\nstatic ssize_t logWritev(int fd, const struct iovec* vector, int count)\n{\n    LogState* state;\n\n    /* Make sure that no-one frees the LogState while we're using it.\n     * Also guarantees that only one thread is in showLog() at a given\n     * time (if it matters).\n     */\n    lock();\n\n    state = fdToLogState(fd);\n    if (state == NULL) {\n        errno = EBADF;\n        goto error;\n    }\n\n    if (state->isBinary) {\n        TRACE(\"%s: ignoring binary log\\n\", state->debugName);\n        goto bail;\n    }\n\n    if (count != 3) {\n        TRACE(\"%s: writevLog with count=%d not expected\\n\",\n            state->debugName, count);\n        goto error;\n    }\n\n    /* pull out the three fields */\n    int logPrio = *(const char*)vector[0].iov_base;\n    const char* tag = (const char*) vector[1].iov_base;\n    const char* msg = (const char*) vector[2].iov_base;\n\n    /* see if this log tag is configured */\n    int i;\n    int minPrio = state->globalMinPriority;\n    for (i = 0; i < kTagSetSize; i++) {\n        if (state->tagSet[i].minPriority == ANDROID_LOG_UNKNOWN)\n            break;      /* reached end of configured values */\n\n        if (strcmp(state->tagSet[i].tag, tag) == 0) {\n            //TRACE(\"MATCH tag '%s'\\n\", tag);\n            minPrio = state->tagSet[i].minPriority;\n            break;\n        }\n    }\n\n    if (logPrio >= minPrio) {\n        showLog(state, logPrio, tag, msg);\n    } else {\n        //TRACE(\"+++ NOLOG(%d): %s %s\", logPrio, tag, msg);\n    }\n\nbail:\n    unlock();\n    return vector[0].iov_len + vector[1].iov_len + vector[2].iov_len;\nerror:\n    unlock();\n    return -1;\n}\n\n/*\n * Free up our state and close the fake descriptor.\n */\nstatic int logClose(int fd)\n{\n    deleteFakeFd(fd);\n    return 0;\n}\n\n/*\n * Open a log output device and return a fake fd.\n */\nstatic int logOpen(const char* pathName, int flags __unused)\n{\n    LogState *logState;\n    int fd = -1;\n\n    lock();\n\n    logState = createLogState();\n    if (logState != NULL) {\n        configureInitialState(pathName, logState);\n        fd = logState->fakeFd;\n    } else  {\n        errno = ENFILE;\n    }\n\n    unlock();\n\n    return fd;\n}\n\n\n/*\n * Runtime redirection.  If this binary is running in the simulator,\n * just pass log messages to the emulated device.  If it's running\n * outside of the simulator, write the log messages to stderr.\n */\n\nstatic int (*redirectOpen)(const char *pathName, int flags) = NULL;\nstatic int (*redirectClose)(int fd) = NULL;\nstatic ssize_t (*redirectWritev)(int fd, const struct iovec* vector, int count)\n        = NULL;\n\nstatic void setRedirects()\n{\n    const char *ws;\n\n    /* Wrapsim sets this environment variable on children that it's\n     * created using its LD_PRELOAD wrapper.\n     */\n    ws = getenv(\"ANDROID_WRAPSIM\");\n    if (ws != NULL && strcmp(ws, \"1\") == 0) {\n        /* We're running inside wrapsim, so we can just write to the device. */\n        redirectOpen = (int (*)(const char *pathName, int flags))open;\n        redirectClose = close;\n        redirectWritev = writev;\n    } else {\n        /* There's no device to delegate to; handle the logging ourselves. */\n        redirectOpen = logOpen;\n        redirectClose = logClose;\n        redirectWritev = logWritev;\n    }\n}\n\nLIBLOG_HIDDEN int fakeLogOpen(const char *pathName, int flags)\n{\n    if (redirectOpen == NULL) {\n        setRedirects();\n    }\n    return redirectOpen(pathName, flags);\n}\n\n/*\n * The logger API has no means or need to 'stop' or 'close' using the logs,\n * and as such, there is no way for that 'stop' or 'close' to translate into\n * a close operation to the fake log handler. fakeLogClose is provided for\n * completeness only.\n *\n * We have no intention of adding a log close operation as it would complicate\n * every user of the logging API with no gain since the only valid place to\n * call is in the exit handler. Logging can continue in the exit handler to\n * help debug HOST tools ...\n */\nLIBLOG_HIDDEN int fakeLogClose(int fd)\n{\n    /* Assume that open() was called first. */\n    return redirectClose(fd);\n}\n\nLIBLOG_HIDDEN ssize_t fakeLogWritev(int fd,\n                                    const struct iovec* vector, int count)\n{\n    /* Assume that open() was called first. */\n    return redirectWritev(fd, vector, count);\n}\n\nLIBLOG_ABI_PUBLIC int __android_log_is_loggable(int prio,\n                                                const char *tag __unused,\n                                                int def)\n{\n    int logLevel = def;\n    return logLevel >= 0 && prio >= logLevel;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/fake_log_device.h",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBLOG_FAKE_LOG_DEVICE_H\n#define _LIBLOG_FAKE_LOG_DEVICE_H\n\n#include <sys/types.h>\n\n#include \"log_portability.h\"\n\nstruct iovec;\n\nLIBLOG_HIDDEN int fakeLogOpen(const char *pathName, int flags);\nLIBLOG_HIDDEN int fakeLogClose(int fd);\nLIBLOG_HIDDEN ssize_t fakeLogWritev(int fd,\n                                    const struct iovec* vector, int count);\n\n#endif // _LIBLOG_FAKE_LOG_DEVICE_H\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/fake_writer.c",
    "content": "/*\n * Copyright (C) 2007-2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <errno.h>\n#include <fcntl.h>\n#include <unistd.h>\n\n#include <log/log.h>\n\n#include \"config_write.h\"\n#include \"fake_log_device.h\"\n#include \"log_portability.h\"\n#include \"logger.h\"\n\nstatic int fakeOpen();\nstatic void fakeClose();\nstatic int fakeWrite(log_id_t log_id, struct timespec *ts,\n                     struct iovec *vec, size_t nr);\n\nstatic int logFds[(int)LOG_ID_MAX] = { -1, -1, -1, -1, -1, -1 };\n\nLIBLOG_HIDDEN struct android_log_transport_write fakeLoggerWrite = {\n    .node = { &fakeLoggerWrite.node, &fakeLoggerWrite.node },\n    .context.private = &logFds,\n    .name = \"fake\",\n    .available = NULL,\n    .open = fakeOpen,\n    .close = fakeClose,\n    .write = fakeWrite,\n};\n\nstatic int fakeOpen() {\n    int i;\n\n    for (i = 0; i < LOG_ID_MAX; i++) {\n        char buf[sizeof(\"/dev/log_security\")];\n        snprintf(buf, sizeof(buf), \"/dev/log_%s\", android_log_id_to_name(i));\n        logFds[i] = fakeLogOpen(buf, O_WRONLY);\n    }\n    return 0;\n}\n\nstatic void fakeClose() {\n    int i;\n\n    for (i = 0; i < LOG_ID_MAX; i++) {\n        fakeLogClose(logFds[i]);\n        logFds[i] = -1;\n    }\n}\n\nstatic int fakeWrite(log_id_t log_id, struct timespec *ts __unused,\n                      struct iovec *vec, size_t nr)\n{\n    ssize_t ret;\n    int logFd;\n\n    if (/*(int)log_id >= 0 &&*/ (int)log_id >= (int)LOG_ID_MAX) {\n        return -EBADF;\n    }\n\n    logFd = logFds[(int)log_id];\n    ret = TEMP_FAILURE_RETRY(fakeLogWritev(logFd, vec, nr));\n    if (ret < 0) {\n        ret = -errno;\n    }\n\n    return ret;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/log_event_list.c",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <log/log.h>\n#include <log/logger.h>\n\n#include \"log_portability.h\"\n\n#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t))\n\ntypedef struct {\n    uint32_t tag;\n    unsigned pos; /* Read/write position into buffer */\n    unsigned count[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* Number of elements   */\n    unsigned list[ANDROID_MAX_LIST_NEST_DEPTH + 1];  /* pos for list counter */\n    unsigned list_nest_depth;\n    unsigned len; /* Length or raw buffer. */\n    bool overflow;\n    bool list_stop; /* next call decrement list_nest_depth and issue a stop */\n    enum {\n        kAndroidLoggerRead = 1,\n        kAndroidLoggerWrite = 2,\n    } read_write_flag;\n    uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD];\n} android_log_context_internal;\n\nLIBLOG_ABI_PUBLIC android_log_context create_android_logger(uint32_t tag) {\n    size_t needed, i;\n    android_log_context_internal *context;\n\n    context = calloc(1, sizeof(android_log_context_internal));\n    if (!context) {\n        return NULL;\n    }\n    context->tag = tag;\n    context->read_write_flag = kAndroidLoggerWrite;\n    needed = sizeof(uint8_t) + sizeof(uint8_t);\n    if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {\n        context->overflow = true;\n    }\n    /* Everything is a list */\n    context->storage[context->pos + 0] = EVENT_TYPE_LIST;\n    context->list[0] = context->pos + 1;\n    context->pos += needed;\n\n    return (android_log_context)context;\n}\n\nLIBLOG_ABI_PUBLIC android_log_context create_android_log_parser(\n        const char *msg,\n        size_t len) {\n    android_log_context_internal *context;\n    size_t i;\n\n    context = calloc(1, sizeof(android_log_context_internal));\n    if (!context) {\n        return NULL;\n    }\n    len = (len <= MAX_EVENT_PAYLOAD) ? len : MAX_EVENT_PAYLOAD;\n    context->len = len;\n    memcpy(context->storage, msg, len);\n    context->read_write_flag = kAndroidLoggerRead;\n\n    return (android_log_context)context;\n}\n\nLIBLOG_ABI_PUBLIC int android_log_destroy(android_log_context *ctx) {\n    android_log_context_internal *context;\n\n    context = (android_log_context_internal *)*ctx;\n    if (!context) {\n        return -EBADF;\n    }\n    memset(context, 0, sizeof(*context));\n    free(context);\n    *ctx = NULL;\n    return 0;\n}\n\nLIBLOG_ABI_PUBLIC int android_log_write_list_begin(android_log_context ctx) {\n    size_t needed;\n    android_log_context_internal *context;\n\n    context = (android_log_context_internal *)ctx;\n    if (!context ||\n            (kAndroidLoggerWrite != context->read_write_flag)) {\n        return -EBADF;\n    }\n    if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {\n        context->overflow = true;\n        return -EOVERFLOW;\n    }\n    needed = sizeof(uint8_t) + sizeof(uint8_t);\n    if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {\n        context->overflow = true;\n        return -EIO;\n    }\n    context->count[context->list_nest_depth]++;\n    context->list_nest_depth++;\n    if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {\n        context->overflow = true;\n        return -EOVERFLOW;\n    }\n    if (context->overflow) {\n        return -EIO;\n    }\n    context->storage[context->pos + 0] = EVENT_TYPE_LIST;\n    context->storage[context->pos + 1] = 0;\n    context->list[context->list_nest_depth] = context->pos + 1;\n    context->count[context->list_nest_depth] = 0;\n    context->pos += needed;\n    return 0;\n}\n\nstatic inline void copy4LE(uint8_t *buf, uint32_t val)\n{\n    buf[0] = val & 0xFF;\n    buf[1] = (val >> 8) & 0xFF;\n    buf[2] = (val >> 16) & 0xFF;\n    buf[3] = (val >> 24) & 0xFF;\n}\n\nLIBLOG_ABI_PUBLIC int android_log_write_int32(android_log_context ctx,\n                                              int32_t value) {\n    size_t needed;\n    android_log_context_internal *context;\n\n    context = (android_log_context_internal *)ctx;\n    if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {\n        return -EBADF;\n    }\n    if (context->overflow) {\n        return -EIO;\n    }\n    needed = sizeof(uint8_t) + sizeof(value);\n    if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {\n        context->overflow = true;\n        return -EIO;\n    }\n    context->count[context->list_nest_depth]++;\n    context->storage[context->pos + 0] = EVENT_TYPE_INT;\n    copy4LE(&context->storage[context->pos + 1], value);\n    context->pos += needed;\n    return 0;\n}\n\nstatic inline void copy8LE(uint8_t *buf, uint64_t val)\n{\n    buf[0] = val & 0xFF;\n    buf[1] = (val >> 8) & 0xFF;\n    buf[2] = (val >> 16) & 0xFF;\n    buf[3] = (val >> 24) & 0xFF;\n    buf[4] = (val >> 32) & 0xFF;\n    buf[5] = (val >> 40) & 0xFF;\n    buf[6] = (val >> 48) & 0xFF;\n    buf[7] = (val >> 56) & 0xFF;\n}\n\nLIBLOG_ABI_PUBLIC int android_log_write_int64(android_log_context ctx,\n                                              int64_t value) {\n    size_t needed;\n    android_log_context_internal *context;\n\n    context = (android_log_context_internal *)ctx;\n    if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {\n        return -EBADF;\n    }\n    if (context->overflow) {\n        return -EIO;\n    }\n    needed = sizeof(uint8_t) + sizeof(value);\n    if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {\n        context->overflow = true;\n        return -EIO;\n    }\n    context->count[context->list_nest_depth]++;\n    context->storage[context->pos + 0] = EVENT_TYPE_LONG;\n    copy8LE(&context->storage[context->pos + 1], value);\n    context->pos += needed;\n    return 0;\n}\n\nLIBLOG_ABI_PUBLIC int android_log_write_string8_len(android_log_context ctx,\n                                                    const char *value,\n                                                    size_t maxlen) {\n    size_t needed;\n    ssize_t len;\n    android_log_context_internal *context;\n\n    context = (android_log_context_internal *)ctx;\n    if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {\n        return -EBADF;\n    }\n    if (context->overflow) {\n        return -EIO;\n    }\n    if (!value) {\n        value = \"\";\n    }\n    len = strnlen(value, maxlen);\n    needed = sizeof(uint8_t) + sizeof(int32_t) + len;\n    if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {\n        /* Truncate string for delivery */\n        len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(int32_t);\n        if (len <= 0) {\n            context->overflow = true;\n            return -EIO;\n        }\n    }\n    context->count[context->list_nest_depth]++;\n    context->storage[context->pos + 0] = EVENT_TYPE_STRING;\n    copy4LE(&context->storage[context->pos + 1], len);\n    if (len) {\n        memcpy(&context->storage[context->pos + 5], value, len);\n    }\n    context->pos += needed;\n    return len;\n}\n\nLIBLOG_ABI_PUBLIC int android_log_write_string8(android_log_context ctx,\n                                                const char *value) {\n    return android_log_write_string8_len(ctx, value, MAX_EVENT_PAYLOAD);\n}\n\nLIBLOG_ABI_PUBLIC int android_log_write_float32(android_log_context ctx,\n                                                float value) {\n    size_t needed;\n    uint32_t ivalue;\n    android_log_context_internal *context;\n\n    context = (android_log_context_internal *)ctx;\n    if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {\n        return -EBADF;\n    }\n    if (context->overflow) {\n        return -EIO;\n    }\n    needed = sizeof(uint8_t) + sizeof(ivalue);\n    if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {\n        context->overflow = true;\n        return -EIO;\n    }\n    ivalue = *(uint32_t *)&value;\n    context->count[context->list_nest_depth]++;\n    context->storage[context->pos + 0] = EVENT_TYPE_FLOAT;\n    copy4LE(&context->storage[context->pos + 1], ivalue);\n    context->pos += needed;\n    return 0;\n}\n\nLIBLOG_ABI_PUBLIC int android_log_write_list_end(android_log_context ctx) {\n    android_log_context_internal *context;\n\n    context = (android_log_context_internal *)ctx;\n    if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {\n        return -EBADF;\n    }\n    if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {\n        context->overflow = true;\n        context->list_nest_depth--;\n        return -EOVERFLOW;\n    }\n    if (!context->list_nest_depth) {\n        context->overflow = true;\n        return -EOVERFLOW;\n    }\n    if (context->list[context->list_nest_depth] <= 0) {\n        context->list_nest_depth--;\n        context->overflow = true;\n        return -EOVERFLOW;\n    }\n    context->storage[context->list[context->list_nest_depth]] =\n        context->count[context->list_nest_depth];\n    context->list_nest_depth--;\n    return 0;\n}\n\n/*\n * Logs the list of elements to the event log.\n */\nLIBLOG_ABI_PUBLIC int android_log_write_list(android_log_context ctx,\n                                             log_id_t id) {\n    android_log_context_internal *context;\n    const char *msg;\n    ssize_t len;\n\n    if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY)) {\n        return -EINVAL;\n    }\n\n    context = (android_log_context_internal *)ctx;\n    if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {\n        return -EBADF;\n    }\n    if (context->list_nest_depth) {\n        return -EIO;\n    }\n    /* NB: if there was overflow, then log is truncated. Nothing reported */\n    context->storage[1] = context->count[0];\n    len = context->len = context->pos;\n    msg = (const char *)context->storage;\n    /* it'snot a list */\n    if (context->count[0] <= 1) {\n        len -= sizeof(uint8_t) + sizeof(uint8_t);\n        if (len < 0) {\n            len = 0;\n        }\n        msg += sizeof(uint8_t) + sizeof(uint8_t);\n    }\n    return (id == LOG_ID_EVENTS) ?\n        __android_log_bwrite(context->tag, msg, len) :\n        __android_log_security_bwrite(context->tag, msg, len);\n}\n\n/*\n * Extract a 4-byte value from a byte stream.\n */\nstatic inline uint32_t get4LE(const uint8_t* src)\n{\n    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);\n}\n\n/*\n * Extract an 8-byte value from a byte stream.\n */\nstatic inline uint64_t get8LE(const uint8_t* src)\n{\n    uint32_t low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);\n    uint32_t high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);\n    return ((uint64_t) high << 32) | (uint64_t) low;\n}\n\n/*\n * Gets the next element. Parsing errors result in an EVENT_TYPE_UNKNOWN type.\n * If there is nothing to process, the complete field is set to non-zero. If\n * an EVENT_TYPE_UNKNOWN type is returned once, and the caller does not check\n * this and continues to call this function, the behavior is undefined\n * (although it won't crash).\n */\nstatic android_log_list_element android_log_read_next_internal(\n        android_log_context ctx, int peek) {\n    android_log_list_element elem;\n    unsigned pos;\n    android_log_context_internal *context;\n\n    context = (android_log_context_internal *)ctx;\n\n    memset(&elem, 0, sizeof(elem));\n\n    /* Nothing to parse from this context, so return complete. */\n    if (!context || (kAndroidLoggerRead != context->read_write_flag) ||\n            (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) ||\n            (context->count[context->list_nest_depth] >=\n                (MAX_EVENT_PAYLOAD / (sizeof(uint8_t) + sizeof(uint8_t))))) {\n        elem.type = EVENT_TYPE_UNKNOWN;\n        if (context &&\n                (context->list_stop ||\n                ((context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) &&\n                    !context->count[context->list_nest_depth]))) {\n            elem.type = EVENT_TYPE_LIST_STOP;\n        }\n        elem.complete = true;\n        return elem;\n    }\n\n    /*\n     * Use a different variable to update the position in case this\n     * operation is a \"peek\".\n     */\n    pos = context->pos;\n    if (context->list_stop) {\n        elem.type = EVENT_TYPE_LIST_STOP;\n        elem.complete = !context->count[0] && (!context->list_nest_depth ||\n            ((context->list_nest_depth == 1) && !context->count[1]));\n        if (!peek) {\n            /* Suck in superfluous stop */\n            if (context->storage[pos] == EVENT_TYPE_LIST_STOP) {\n                context->pos = pos + 1;\n            }\n            if (context->list_nest_depth) {\n                --context->list_nest_depth;\n                if (context->count[context->list_nest_depth]) {\n                    context->list_stop = false;\n                }\n            } else {\n                context->list_stop = false;\n            }\n        }\n        return elem;\n    }\n    if ((pos + 1) > context->len) {\n        elem.type = EVENT_TYPE_UNKNOWN;\n        elem.complete = true;\n        return elem;\n    }\n\n    elem.type = context->storage[pos++];\n    switch ((int)elem.type) {\n    case EVENT_TYPE_FLOAT:\n        /* Rely on union to translate elem.data.int32 into elem.data.float32 */\n        /* FALLTHRU */\n    case EVENT_TYPE_INT:\n        elem.len = sizeof(int32_t);\n        if ((pos + elem.len) > context->len) {\n            elem.type = EVENT_TYPE_UNKNOWN;\n            return elem;\n        }\n        elem.data.int32 = get4LE(&context->storage[pos]);\n        /* common tangeable object suffix */\n        pos += elem.len;\n        elem.complete = !context->list_nest_depth && !context->count[0];\n        if (!peek) {\n            if (!context->count[context->list_nest_depth] ||\n                    !--(context->count[context->list_nest_depth])) {\n                context->list_stop = true;\n            }\n            context->pos = pos;\n        }\n        return elem;\n\n    case EVENT_TYPE_LONG:\n        elem.len = sizeof(int64_t);\n        if ((pos + elem.len) > context->len) {\n            elem.type = EVENT_TYPE_UNKNOWN;\n            return elem;\n        }\n        elem.data.int64 = get8LE(&context->storage[pos]);\n        /* common tangeable object suffix */\n        pos += elem.len;\n        elem.complete = !context->list_nest_depth && !context->count[0];\n        if (!peek) {\n            if (!context->count[context->list_nest_depth] ||\n                    !--(context->count[context->list_nest_depth])) {\n                context->list_stop = true;\n            }\n            context->pos = pos;\n        }\n        return elem;\n\n    case EVENT_TYPE_STRING:\n        if ((pos + sizeof(int32_t)) > context->len) {\n            elem.type = EVENT_TYPE_UNKNOWN;\n            elem.complete = true;\n            return elem;\n        }\n        elem.len = get4LE(&context->storage[pos]);\n        pos += sizeof(int32_t);\n        if ((pos + elem.len) > context->len) {\n            elem.len = context->len - pos; /* truncate string */\n            elem.complete = true;\n            if (!elem.len) {\n                elem.type = EVENT_TYPE_UNKNOWN;\n                return elem;\n            }\n        }\n        elem.data.string = (char *)&context->storage[pos];\n        /* common tangeable object suffix */\n        pos += elem.len;\n        elem.complete = !context->list_nest_depth && !context->count[0];\n        if (!peek) {\n            if (!context->count[context->list_nest_depth] ||\n                    !--(context->count[context->list_nest_depth])) {\n                context->list_stop = true;\n            }\n            context->pos = pos;\n        }\n        return elem;\n\n    case EVENT_TYPE_LIST:\n        if ((pos + sizeof(uint8_t)) > context->len) {\n            elem.type = EVENT_TYPE_UNKNOWN;\n            elem.complete = true;\n            return elem;\n        }\n        elem.complete = context->list_nest_depth >= ANDROID_MAX_LIST_NEST_DEPTH;\n        if (peek) {\n            return elem;\n        }\n        if (context->count[context->list_nest_depth]) {\n            context->count[context->list_nest_depth]--;\n        }\n        context->list_stop = !context->storage[pos];\n        context->list_nest_depth++;\n        if (context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) {\n            context->count[context->list_nest_depth] = context->storage[pos];\n        }\n        context->pos = pos + sizeof(uint8_t);\n        return elem;\n\n    case EVENT_TYPE_LIST_STOP: /* Suprise Newline terminates lists. */\n        if (!peek) {\n            context->pos = pos;\n        }\n        elem.type = EVENT_TYPE_UNKNOWN;\n        elem.complete = !context->list_nest_depth;\n        if (context->list_nest_depth > 0) {\n            elem.type = EVENT_TYPE_LIST_STOP;\n            if (!peek) {\n                context->list_nest_depth--;\n            }\n        }\n        return elem;\n\n    default:\n        elem.type = EVENT_TYPE_UNKNOWN;\n        return elem;\n    }\n}\n\nLIBLOG_ABI_PUBLIC android_log_list_element android_log_read_next(\n        android_log_context ctx) {\n    return android_log_read_next_internal(ctx, 0);\n}\n\nLIBLOG_ABI_PUBLIC android_log_list_element android_log_peek_next(\n        android_log_context ctx) {\n    return android_log_read_next_internal(ctx, 1);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/log_event_write.c",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <errno.h>\n\n#include <log/log.h>\n\n#include \"log_portability.h\"\n\n#define MAX_SUBTAG_LEN 32\n\nLIBLOG_ABI_PUBLIC int __android_log_error_write(\n        int tag,\n        const char *subTag,\n        int32_t uid,\n        const char *data, uint32_t dataLen)\n{\n    int ret = -EINVAL;\n\n    if (subTag && (data || !dataLen)) {\n        android_log_context ctx = create_android_logger(tag);\n\n        ret = -ENOMEM;\n        if (ctx) {\n            ret = android_log_write_string8_len(ctx, subTag, MAX_SUBTAG_LEN);\n            if (ret >= 0) {\n                ret = android_log_write_int32(ctx, uid);\n                if (ret >= 0) {\n                    ret = android_log_write_string8_len(ctx, data, dataLen);\n                    if (ret >= 0) {\n                        ret = android_log_write_list(ctx, LOG_ID_EVENTS);\n                    }\n                }\n            }\n            android_log_destroy(&ctx);\n        }\n    }\n    return ret;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/log_is_loggable.c",
    "content": "/*\n** Copyright 2014, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\");\n** you may not use this file except in compliance with the License.\n** You may obtain a copy of the License at\n**\n**     http://www.apache.org/licenses/LICENSE-2.0\n**\n** Unless required by applicable law or agreed to in writing, software\n** distributed under the License is distributed on an \"AS IS\" BASIS,\n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n** See the License for the specific language governing permissions and\n** limitations under the License.\n*/\n\n#include <ctype.h>\n#include <pthread.h>\n#include <stdlib.h>\n#include <string.h>\n#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_\n#include <sys/_system_properties.h>\n\n#include <android/log.h>\n\n#include \"log_portability.h\"\n\nstatic pthread_mutex_t lock_loggable = PTHREAD_MUTEX_INITIALIZER;\n\nstatic int lock()\n{\n    /*\n     * If we trigger a signal handler in the middle of locked activity and the\n     * signal handler logs a message, we could get into a deadlock state.\n     */\n    /*\n     *  Any contention, and we can turn around and use the non-cached method\n     * in less time than the system call associated with a mutex to deal with\n     * the contention.\n     */\n    return pthread_mutex_trylock(&lock_loggable);\n}\n\nstatic void unlock()\n{\n    pthread_mutex_unlock(&lock_loggable);\n}\n\nstruct cache {\n    const prop_info *pinfo;\n    uint32_t serial;\n    unsigned char c;\n};\n\nstatic int check_cache(struct cache *cache)\n{\n    return cache->pinfo\n        && __system_property_serial(cache->pinfo) != cache->serial;\n}\n\n#define BOOLEAN_TRUE 0xFF\n#define BOOLEAN_FALSE 0xFE\n\nstatic void refresh_cache(struct cache *cache, const char *key)\n{\n    char buf[PROP_VALUE_MAX];\n\n    if (!cache->pinfo) {\n        cache->pinfo = __system_property_find(key);\n        if (!cache->pinfo) {\n            return;\n        }\n    }\n    cache->serial = __system_property_serial(cache->pinfo);\n    __system_property_read(cache->pinfo, 0, buf);\n    switch(buf[0]) {\n    case 't': case 'T':\n        cache->c = strcasecmp(buf + 1, \"rue\") ? buf[0] : BOOLEAN_TRUE;\n        break;\n    case 'f': case 'F':\n        cache->c = strcasecmp(buf + 1, \"alse\") ? buf[0] : BOOLEAN_FALSE;\n        break;\n    default:\n        cache->c = buf[0];\n    }\n}\n\nstatic int __android_log_level(const char *tag, int default_prio)\n{\n    /* sizeof() is used on this array below */\n    static const char log_namespace[] = \"persist.log.tag.\";\n    static const size_t base_offset = 8; /* skip \"persist.\" */\n    /* calculate the size of our key temporary buffer */\n    const size_t taglen = (tag && *tag) ? strlen(tag) : 0;\n    /* sizeof(log_namespace) = strlen(log_namespace) + 1 */\n    char key[sizeof(log_namespace) + taglen]; /* may be > PROPERTY_KEY_MAX */\n    char *kp;\n    size_t i;\n    char c = 0;\n    /*\n     * Single layer cache of four properties. Priorities are:\n     *    log.tag.<tag>\n     *    persist.log.tag.<tag>\n     *    log.tag\n     *    persist.log.tag\n     * Where the missing tag matches all tags and becomes the\n     * system global default. We do not support ro.log.tag* .\n     */\n    static char last_tag[PROP_NAME_MAX];\n    static uint32_t global_serial;\n    /* some compilers erroneously see uninitialized use. !not_locked */\n    uint32_t current_global_serial = 0;\n    static struct cache tag_cache[2];\n    static struct cache global_cache[2];\n    int change_detected;\n    int global_change_detected;\n    int not_locked;\n\n    strcpy(key, log_namespace);\n\n    global_change_detected = change_detected = not_locked = lock();\n\n    if (!not_locked) {\n        /*\n         *  check all known serial numbers to changes.\n         */\n        for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {\n            if (check_cache(&tag_cache[i])) {\n                change_detected = 1;\n            }\n        }\n        for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {\n            if (check_cache(&global_cache[i])) {\n                global_change_detected = 1;\n            }\n        }\n\n        current_global_serial = __system_property_area_serial();\n        if (current_global_serial != global_serial) {\n            change_detected = 1;\n            global_change_detected = 1;\n        }\n    }\n\n    if (taglen) {\n        int local_change_detected = change_detected;\n        if (!not_locked) {\n            if (!last_tag[0]\n                    || (last_tag[0] != tag[0])\n                    || strncmp(last_tag + 1, tag + 1, sizeof(last_tag) - 1)) {\n                /* invalidate log.tag.<tag> cache */\n                for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {\n                    tag_cache[i].pinfo = NULL;\n                    tag_cache[i].c = '\\0';\n                }\n                last_tag[0] = '\\0';\n                local_change_detected = 1;\n            }\n            if (!last_tag[0]) {\n                strncpy(last_tag, tag, sizeof(last_tag));\n            }\n        }\n        strcpy(key + sizeof(log_namespace) - 1, tag);\n\n        kp = key;\n        for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {\n            struct cache *cache = &tag_cache[i];\n            struct cache temp_cache;\n\n            if (not_locked) {\n                temp_cache.pinfo = NULL;\n                temp_cache.c = '\\0';\n                cache = &temp_cache;\n            }\n            if (local_change_detected) {\n                refresh_cache(cache, kp);\n            }\n\n            if (cache->c) {\n                c = cache->c;\n                break;\n            }\n\n            kp = key + base_offset;\n        }\n    }\n\n    switch (toupper(c)) { /* if invalid, resort to global */\n    case 'V':\n    case 'D':\n    case 'I':\n    case 'W':\n    case 'E':\n    case 'F': /* Not officially supported */\n    case 'A':\n    case 'S':\n    case BOOLEAN_FALSE: /* Not officially supported */\n        break;\n    default:\n        /* clear '.' after log.tag */\n        key[sizeof(log_namespace) - 2] = '\\0';\n\n        kp = key;\n        for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {\n            struct cache *cache = &global_cache[i];\n            struct cache temp_cache;\n\n            if (not_locked) {\n                temp_cache = *cache;\n                if (temp_cache.pinfo != cache->pinfo) { /* check atomic */\n                    temp_cache.pinfo = NULL;\n                    temp_cache.c = '\\0';\n                }\n                cache = &temp_cache;\n            }\n            if (global_change_detected) {\n                refresh_cache(cache, kp);\n            }\n\n            if (cache->c) {\n                c = cache->c;\n                break;\n            }\n\n            kp = key + base_offset;\n        }\n        break;\n    }\n\n    if (!not_locked) {\n        global_serial = current_global_serial;\n        unlock();\n    }\n\n    switch (toupper(c)) {\n    case 'V': return ANDROID_LOG_VERBOSE;\n    case 'D': return ANDROID_LOG_DEBUG;\n    case 'I': return ANDROID_LOG_INFO;\n    case 'W': return ANDROID_LOG_WARN;\n    case 'E': return ANDROID_LOG_ERROR;\n    case 'F': /* FALLTHRU */ /* Not officially supported */\n    case 'A': return ANDROID_LOG_FATAL;\n    case BOOLEAN_FALSE: /* FALLTHRU */ /* Not Officially supported */\n    case 'S': return -1; /* ANDROID_LOG_SUPPRESS */\n    }\n    return default_prio;\n}\n\nLIBLOG_ABI_PUBLIC int __android_log_is_loggable(int prio, const char *tag,\n                                                int default_prio)\n{\n    int logLevel = __android_log_level(tag, default_prio);\n    return logLevel >= 0 && prio >= logLevel;\n}\n\nLIBLOG_HIDDEN int __android_log_is_debuggable()\n{\n    static uint32_t serial;\n    static struct cache tag_cache;\n    static const char key[] = \"ro.debuggable\";\n    int ret;\n\n    if (tag_cache.c) { /* ro property does not change after set */\n        ret = tag_cache.c == '1';\n    } else if (lock()) {\n        struct cache temp_cache = { NULL, -1, '\\0' };\n        refresh_cache(&temp_cache, key);\n        ret = temp_cache.c == '1';\n    } else {\n        int change_detected = check_cache(&tag_cache);\n        uint32_t current_serial = __system_property_area_serial();\n        if (current_serial != serial) {\n            change_detected = 1;\n        }\n        if (change_detected) {\n            refresh_cache(&tag_cache, key);\n            serial = current_serial;\n        }\n        ret = tag_cache.c == '1';\n\n        unlock();\n    }\n\n    return ret;\n}\n\n/*\n * For properties that are read often, but generally remain constant.\n * Since a change is rare, we will accept a trylock failure gracefully.\n * Use a separate lock from is_loggable to keep contention down b/25563384.\n */\nstruct cache2 {\n    pthread_mutex_t lock;\n    uint32_t serial;\n    const char *key_persist;\n    struct cache cache_persist;\n    const char *key_ro;\n    struct cache cache_ro;\n    unsigned char (*const evaluate)(const struct cache2 *self);\n};\n\nstatic inline unsigned char do_cache2(struct cache2 *self)\n{\n    uint32_t current_serial;\n    int change_detected;\n    unsigned char c;\n\n    if (pthread_mutex_trylock(&self->lock)) {\n        /* We are willing to accept some race in this context */\n        return self->evaluate(self);\n    }\n\n    change_detected = check_cache(&self->cache_persist)\n                   || check_cache(&self->cache_ro);\n    current_serial = __system_property_area_serial();\n    if (current_serial != self->serial) {\n        change_detected = 1;\n    }\n    if (change_detected) {\n        refresh_cache(&self->cache_persist, self->key_persist);\n        refresh_cache(&self->cache_ro, self->key_ro);\n        self->serial = current_serial;\n    }\n    c = self->evaluate(self);\n\n    pthread_mutex_unlock(&self->lock);\n\n    return c;\n}\n\nstatic unsigned char evaluate_persist_ro(const struct cache2 *self)\n{\n    unsigned char c = self->cache_persist.c;\n\n    if (c) {\n        return c;\n    }\n\n    return self->cache_ro.c;\n}\n\n/*\n * Timestamp state generally remains constant, but can change at any time\n * to handle developer requirements.\n */\nLIBLOG_ABI_PUBLIC clockid_t android_log_clockid()\n{\n    static struct cache2 clockid = {\n        PTHREAD_MUTEX_INITIALIZER,\n        0,\n        \"persist.logd.timestamp\",\n        { NULL, -1, '\\0' },\n        \"ro.logd.timestamp\",\n        { NULL, -1, '\\0' },\n        evaluate_persist_ro\n    };\n\n    return (tolower(do_cache2(&clockid)) == 'm')\n        ? CLOCK_MONOTONIC\n        : CLOCK_REALTIME;\n}\n\n/*\n * Security state generally remains constant, but the DO must be able\n * to turn off logging should it become spammy after an attack is detected.\n */\nstatic unsigned char evaluate_security(const struct cache2 *self)\n{\n    unsigned char c = self->cache_ro.c;\n\n    return (c != BOOLEAN_FALSE) && c && (self->cache_persist.c == BOOLEAN_TRUE);\n}\n\nLIBLOG_ABI_PUBLIC int __android_log_security()\n{\n    static struct cache2 security = {\n        PTHREAD_MUTEX_INITIALIZER,\n        0,\n        \"persist.logd.security\",\n        { NULL, -1, BOOLEAN_FALSE },\n        \"ro.device_owner\",\n        { NULL, -1, BOOLEAN_FALSE },\n        evaluate_security\n    };\n\n    return do_cache2(&security);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/log_portability.h",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBLOG_PORTABILITY_H__\n#define _LIBLOG_PORTABILITY_H__\n\n#include <sys/cdefs.h>\n#include <unistd.h>\n\n/* Helpful private sys/cdefs.h like definitions */\n\n/* Declare this library function hidden and internal */\n#if defined(_WIN32)\n#define LIBLOG_HIDDEN\n#else\n#define LIBLOG_HIDDEN __attribute__((visibility(\"hidden\")))\n#endif\n\n/* Declare this library function visible and external */\n#if defined(_WIN32)\n#define LIBLOG_ABI_PUBLIC\n#else\n#define LIBLOG_ABI_PUBLIC __attribute__((visibility(\"default\")))\n#endif\n\n/* Declare this library function visible but private */\n#define LIBLOG_ABI_PRIVATE LIBLOG_ABI_PUBLIC\n\n/*\n * Declare this library function as reimplementation.\n * Prevent circular dependencies, but allow _real_ library to hijack\n */\n#if defined(_WIN32)\n#define LIBLOG_WEAK static /* Accept that it is totally private */\n#else\n#define LIBLOG_WEAK __attribute__((weak,visibility(\"default\")))\n#endif\n\n/* possible missing definitions in sys/cdefs.h */\n\n/* DECLS */\n#ifndef __BEGIN_DECLS\n#if defined(__cplusplus)\n#define __BEGIN_DECLS           extern \"C\" {\n#define __END_DECLS             }\n#else\n#define __BEGIN_DECLS\n#define __END_DECLS\n#endif\n#endif\n\n/* Unused argument. For C code only, remove symbol name for C++ */\n#ifndef __unused\n#define __unused        __attribute__((__unused__))\n#endif\n\n/* possible missing definitions in unistd.h */\n\n#ifndef TEMP_FAILURE_RETRY\n/* Used to retry syscalls that can return EINTR. */\n#define TEMP_FAILURE_RETRY(exp) ({         \\\n    __typeof__(exp) _rc;                   \\\n    do {                                   \\\n        _rc = (exp);                       \\\n    } while (_rc == -1 && errno == EINTR); \\\n    _rc; })\n#endif\n\n#endif /* _LIBLOG_PORTABILITY_H__ */\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/log_time.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <ctype.h>\n#include <limits.h>\n#include <stdio.h>\n#include <string.h>\n\n#include <log/log_read.h>\n\n#include \"log_portability.h\"\n\nLIBLOG_ABI_PRIVATE const char log_time::default_format[] = \"%m-%d %H:%M:%S.%q\";\nLIBLOG_ABI_PRIVATE const timespec log_time::EPOCH = { 0, 0 };\n\n// Add %#q for fractional seconds to standard strptime function\n\nLIBLOG_ABI_PRIVATE char *log_time::strptime(const char *s, const char *format) {\n    time_t now;\n#ifdef __linux__\n    *this = log_time(CLOCK_REALTIME);\n    now = tv_sec;\n#else\n    time(&now);\n    tv_sec = now;\n    tv_nsec = 0;\n#endif\n\n    struct tm *ptm;\n#if !defined(_WIN32)\n    struct tm tmBuf;\n    ptm = localtime_r(&now, &tmBuf);\n#else\n    ptm = localtime(&now);\n#endif\n\n    char fmt[strlen(format) + 1];\n    strcpy(fmt, format);\n\n    char *ret = const_cast<char *> (s);\n    char *cp;\n    for (char *f = cp = fmt; ; ++cp) {\n        if (!*cp) {\n            if (f != cp) {\n                ret = ::strptime(ret, f, ptm);\n            }\n            break;\n        }\n        if (*cp != '%') {\n            continue;\n        }\n        char *e = cp;\n        ++e;\n#if (defined(__BIONIC__))\n        if (*e == 's') {\n            *cp = '\\0';\n            if (*f) {\n                ret = ::strptime(ret, f, ptm);\n                if (!ret) {\n                    break;\n                }\n            }\n            tv_sec = 0;\n            while (isdigit(*ret)) {\n                tv_sec = tv_sec * 10 + *ret - '0';\n                ++ret;\n            }\n            now = tv_sec;\n#if !defined(_WIN32)\n            ptm = localtime_r(&now, &tmBuf);\n#else\n            ptm = localtime(&now);\n#endif\n        } else\n#endif\n        {\n            unsigned num = 0;\n            while (isdigit(*e)) {\n                num = num * 10 + *e - '0';\n                ++e;\n            }\n            if (*e != 'q') {\n                continue;\n            }\n            *cp = '\\0';\n            if (*f) {\n                ret = ::strptime(ret, f, ptm);\n                if (!ret) {\n                    break;\n                }\n            }\n            unsigned long mul = NS_PER_SEC;\n            if (num == 0) {\n                num = INT_MAX;\n            }\n            tv_nsec = 0;\n            while (isdigit(*ret) && num && (mul > 1)) {\n                --num;\n                mul /= 10;\n                tv_nsec = tv_nsec + (*ret - '0') * mul;\n                ++ret;\n            }\n        }\n        f = cp = e;\n        ++f;\n    }\n\n    if (ret) {\n        tv_sec = mktime(ptm);\n        return ret;\n    }\n\n    // Upon error, place a known value into the class, the current time.\n#ifdef __linux__\n    *this = log_time(CLOCK_REALTIME);\n#else\n    time(&now);\n    tv_sec = now;\n    tv_nsec = 0;\n#endif\n    return ret;\n}\n\nLIBLOG_ABI_PRIVATE log_time log_time::operator-= (const timespec &T) {\n    // No concept of negative time, clamp to EPOCH\n    if (*this <= T) {\n        return *this = EPOCH;\n    }\n\n    if (this->tv_nsec < (unsigned long int)T.tv_nsec) {\n        --this->tv_sec;\n        this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec;\n    } else {\n        this->tv_nsec -= T.tv_nsec;\n    }\n    this->tv_sec -= T.tv_sec;\n\n    return *this;\n}\n\nLIBLOG_ABI_PRIVATE log_time log_time::operator+= (const timespec &T) {\n    this->tv_nsec += (unsigned long int)T.tv_nsec;\n    if (this->tv_nsec >= NS_PER_SEC) {\n        this->tv_nsec -= NS_PER_SEC;\n        ++this->tv_sec;\n    }\n    this->tv_sec += T.tv_sec;\n\n    return *this;\n}\n\nLIBLOG_ABI_PRIVATE log_time log_time::operator-= (const log_time &T) {\n    // No concept of negative time, clamp to EPOCH\n    if (*this <= T) {\n        return *this = EPOCH;\n    }\n\n    if (this->tv_nsec < T.tv_nsec) {\n        --this->tv_sec;\n        this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec;\n    } else {\n        this->tv_nsec -= T.tv_nsec;\n    }\n    this->tv_sec -= T.tv_sec;\n\n    return *this;\n}\n\nLIBLOG_ABI_PRIVATE log_time log_time::operator+= (const log_time &T) {\n    this->tv_nsec += T.tv_nsec;\n    if (this->tv_nsec >= NS_PER_SEC) {\n        this->tv_nsec -= NS_PER_SEC;\n        ++this->tv_sec;\n    }\n    this->tv_sec += T.tv_sec;\n\n    return *this;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/logd_reader.c",
    "content": "/*\n * Copyright (C) 2007-2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <endian.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <inttypes.h>\n#include <poll.h>\n#include <stdarg.h>\n#include <stdatomic.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <sys/un.h>\n#include <time.h>\n#include <unistd.h>\n\n#include <cutils/sockets.h>\n#include <log/logd.h>\n#include <log/logger.h>\n#include <log/log_read.h>\n#include <private/android_filesystem_config.h>\n#include <private/android_logger.h>\n\n#include \"config_read.h\"\n#include \"log_portability.h\"\n#include \"logger.h\"\n\n/* branchless on many architectures. */\n#define min(x,y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))\n\nstatic int logdAvailable(log_id_t LogId);\nstatic int logdVersion(struct android_log_logger *logger,\n                       struct android_log_transport_context *transp);\nstatic int logdRead(struct android_log_logger_list *logger_list,\n                    struct android_log_transport_context *transp,\n                    struct log_msg *log_msg);\nstatic int logdPoll(struct android_log_logger_list *logger_list,\n                    struct android_log_transport_context *transp);\nstatic void logdClose(struct android_log_logger_list *logger_list,\n                      struct android_log_transport_context *transp);\nstatic int logdClear(struct android_log_logger *logger,\n                     struct android_log_transport_context *transp);\nstatic ssize_t logdSetSize(struct android_log_logger *logger,\n                           struct android_log_transport_context *transp,\n                           size_t size);\nstatic ssize_t logdGetSize(struct android_log_logger *logger,\n                           struct android_log_transport_context *transp);\nstatic ssize_t logdGetReadableSize(struct android_log_logger *logger,\n                                   struct android_log_transport_context *transp);\nstatic ssize_t logdGetPrune(struct android_log_logger_list *logger,\n                            struct android_log_transport_context *transp,\n                            char *buf, size_t len);\nstatic ssize_t logdSetPrune(struct android_log_logger_list *logger,\n                            struct android_log_transport_context *transp,\n                            char *buf, size_t len);\nstatic ssize_t logdGetStats(struct android_log_logger_list *logger,\n                            struct android_log_transport_context *transp,\n                            char *buf, size_t len);\n\nLIBLOG_HIDDEN struct android_log_transport_read logdLoggerRead = {\n    .node = { &logdLoggerRead.node, &logdLoggerRead.node },\n    .name = \"logd\",\n    .available = logdAvailable,\n    .version = logdVersion,\n    .read = logdRead,\n    .poll = logdPoll,\n    .close = logdClose,\n    .clear = logdClear,\n    .getSize = logdGetSize,\n    .setSize = logdSetSize,\n    .getReadableSize = logdGetReadableSize,\n    .getPrune = logdGetPrune,\n    .setPrune = logdSetPrune,\n    .getStats = logdGetStats,\n};\n\nstatic int logdAvailable(log_id_t logId)\n{\n    if (logId > LOG_ID_KERNEL) {\n        return -EINVAL;\n    }\n    if (logId == LOG_ID_SECURITY) {\n        uid_t uid = __android_log_uid();\n        if (uid != AID_SYSTEM) {\n            return -EPERM;\n        }\n    }\n    if (access(\"/dev/socket/logdw\", W_OK) == 0) {\n        return 0;\n    }\n    return -EBADF;\n}\n\n/* Private copy of ../libcutils/socket_local_client.c prevent library loops */\n\n#if defined(_WIN32)\n\nLIBLOG_WEAK int socket_local_client(const char *name, int namespaceId, int type)\n{\n    errno = ENOSYS;\n    return -ENOSYS;\n}\n\n#else /* !_WIN32 */\n\n#include <sys/socket.h>\n#include <sys/un.h>\n#include <sys/select.h>\n#include <sys/types.h>\n\n/* Private copy of ../libcutils/socket_local.h prevent library loops */\n#define FILESYSTEM_SOCKET_PREFIX \"/tmp/\"\n#define ANDROID_RESERVED_SOCKET_PREFIX \"/dev/socket/\"\n/* End of ../libcutils/socket_local.h */\n\n#define LISTEN_BACKLOG 4\n\n/* Documented in header file. */\nLIBLOG_WEAK int socket_make_sockaddr_un(const char *name, int namespaceId,\n                                        struct sockaddr_un *p_addr,\n                                        socklen_t *alen)\n{\n    memset (p_addr, 0, sizeof (*p_addr));\n    size_t namelen;\n\n    switch (namespaceId) {\n    case ANDROID_SOCKET_NAMESPACE_ABSTRACT:\n#if defined(__linux__)\n        namelen  = strlen(name);\n\n        /* Test with length +1 for the *initial* '\\0'. */\n        if ((namelen + 1) > sizeof(p_addr->sun_path)) {\n            goto error;\n        }\n\n        /*\n         * Note: The path in this case is *not* supposed to be\n         * '\\0'-terminated. (\"man 7 unix\" for the gory details.)\n         */\n\n        p_addr->sun_path[0] = 0;\n        memcpy(p_addr->sun_path + 1, name, namelen);\n#else\n        /* this OS doesn't have the Linux abstract namespace */\n\n        namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX);\n        /* unix_path_max appears to be missing on linux */\n        if (namelen > sizeof(*p_addr)\n                - offsetof(struct sockaddr_un, sun_path) - 1) {\n            goto error;\n        }\n\n        strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX);\n        strcat(p_addr->sun_path, name);\n#endif\n        break;\n\n    case ANDROID_SOCKET_NAMESPACE_RESERVED:\n        namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX);\n        /* unix_path_max appears to be missing on linux */\n        if (namelen > sizeof(*p_addr)\n                - offsetof(struct sockaddr_un, sun_path) - 1) {\n            goto error;\n        }\n\n        strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX);\n        strcat(p_addr->sun_path, name);\n        break;\n\n    case ANDROID_SOCKET_NAMESPACE_FILESYSTEM:\n        namelen = strlen(name);\n        /* unix_path_max appears to be missing on linux */\n        if (namelen > sizeof(*p_addr)\n                - offsetof(struct sockaddr_un, sun_path) - 1) {\n            goto error;\n        }\n\n        strcpy(p_addr->sun_path, name);\n        break;\n\n    default:\n        /* invalid namespace id */\n        return -1;\n    }\n\n    p_addr->sun_family = AF_LOCAL;\n    *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;\n    return 0;\nerror:\n    return -1;\n}\n\n/**\n * connect to peer named \"name\" on fd\n * returns same fd or -1 on error.\n * fd is not closed on error. that's your job.\n *\n * Used by AndroidSocketImpl\n */\nLIBLOG_WEAK int socket_local_client_connect(int fd, const char *name,\n                                            int namespaceId, int type __unused)\n{\n    struct sockaddr_un addr;\n    socklen_t alen;\n    int err;\n\n    err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);\n\n    if (err < 0) {\n        goto error;\n    }\n\n    if(connect(fd, (struct sockaddr *) &addr, alen) < 0) {\n        goto error;\n    }\n\n    return fd;\n\nerror:\n    return -1;\n}\n\n/**\n * connect to peer named \"name\"\n * returns fd or -1 on error\n */\nLIBLOG_WEAK int socket_local_client(const char *name, int namespaceId, int type)\n{\n    int s;\n\n    s = socket(AF_LOCAL, type, 0);\n    if(s < 0) return -1;\n\n    if ( 0 > socket_local_client_connect(s, name, namespaceId, type)) {\n        close(s);\n        return -1;\n    }\n\n    return s;\n}\n\n#endif /* !_WIN32 */\n/* End of ../libcutils/socket_local_client.c */\n\n/* worker for sending the command to the logger */\nstatic ssize_t send_log_msg(struct android_log_logger *logger,\n                            const char *msg, char *buf, size_t buf_size)\n{\n    ssize_t ret;\n    size_t len;\n    char *cp;\n    int errno_save = 0;\n    int sock = socket_local_client(\"logd\", ANDROID_SOCKET_NAMESPACE_RESERVED,\n                                   SOCK_STREAM);\n    if (sock < 0) {\n        return sock;\n    }\n\n    if (msg) {\n        snprintf(buf, buf_size, msg, logger ? logger->logId : (unsigned) -1);\n    }\n\n    len = strlen(buf) + 1;\n    ret = TEMP_FAILURE_RETRY(write(sock, buf, len));\n    if (ret <= 0) {\n        goto done;\n    }\n\n    len = buf_size;\n    cp = buf;\n    while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) {\n        struct pollfd p;\n\n        if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) {\n            break;\n        }\n\n        len -= ret;\n        cp += ret;\n\n        memset(&p, 0, sizeof(p));\n        p.fd = sock;\n        p.events = POLLIN;\n\n        /* Give other side 20ms to refill pipe */\n        ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20));\n\n        if (ret <= 0) {\n            break;\n        }\n\n        if (!(p.revents & POLLIN)) {\n            ret = 0;\n            break;\n        }\n    }\n\n    if (ret >= 0) {\n        ret += buf_size - len;\n    }\n\ndone:\n    if ((ret == -1) && errno) {\n        errno_save = errno;\n    }\n    close(sock);\n    if (errno_save) {\n        errno = errno_save;\n    }\n    return ret;\n}\n\nstatic int check_log_success(char *buf, ssize_t ret)\n{\n    if (ret < 0) {\n        return ret;\n    }\n\n    if (strncmp(buf, \"success\", 7)) {\n        errno = EINVAL;\n        return -1;\n    }\n\n    return 0;\n}\n\nstatic int logdClear(struct android_log_logger *logger,\n                     struct android_log_transport_context *transp __unused)\n{\n    char buf[512];\n\n    return check_log_success(buf,\n        send_log_msg(logger, \"clear %d\", buf, sizeof(buf)));\n}\n\n/* returns the total size of the log's ring buffer */\nstatic ssize_t logdGetSize(struct android_log_logger *logger,\n                           struct android_log_transport_context *transp __unused)\n{\n    char buf[512];\n\n    ssize_t ret = send_log_msg(logger, \"getLogSize %d\", buf, sizeof(buf));\n    if (ret < 0) {\n        return ret;\n    }\n\n    if ((buf[0] < '0') || ('9' < buf[0])) {\n        return -1;\n    }\n\n    return atol(buf);\n}\n\nstatic ssize_t logdSetSize(\n        struct android_log_logger *logger,\n        struct android_log_transport_context *transp __unused,\n        size_t size)\n{\n    char buf[512];\n\n    snprintf(buf, sizeof(buf), \"setLogSize %d %zu\", logger->logId, size);\n\n    return check_log_success(buf, send_log_msg(NULL, NULL, buf, sizeof(buf)));\n}\n\n/*\n * returns the readable size of the log's ring buffer (that is, amount of the\n * log consumed)\n */\nstatic ssize_t logdGetReadableSize(\n       struct android_log_logger *logger,\n       struct android_log_transport_context *transp __unused)\n{\n    char buf[512];\n\n    ssize_t ret = send_log_msg(logger, \"getLogSizeUsed %d\", buf, sizeof(buf));\n    if (ret < 0) {\n        return ret;\n    }\n\n    if ((buf[0] < '0') || ('9' < buf[0])) {\n        return -1;\n    }\n\n    return atol(buf);\n}\n\n/*\n * returns the logger version\n */\nstatic int logdVersion(\n        struct android_log_logger *logger __unused,\n        struct android_log_transport_context *transp __unused)\n{\n    uid_t uid = __android_log_uid();\n    return ((uid != AID_ROOT) && (uid != AID_LOG) && (uid != AID_SYSTEM)) ? 3 : 4;\n}\n\n/*\n * returns statistics\n */\nstatic ssize_t logdGetStats(struct android_log_logger_list *logger_list,\n                            struct android_log_transport_context *transp __unused,\n                            char *buf, size_t len)\n{\n    struct android_log_logger *logger;\n    char *cp = buf;\n    size_t remaining = len;\n    size_t n;\n\n    n = snprintf(cp, remaining, \"getStatistics\");\n    n = min(n, remaining);\n    remaining -= n;\n    cp += n;\n\n    logger_for_each(logger, logger_list) {\n        n = snprintf(cp, remaining, \" %d\", logger->logId);\n        n = min(n, remaining);\n        remaining -= n;\n        cp += n;\n    }\n\n    if (logger_list->pid) {\n        snprintf(cp, remaining, \" pid=%u\", logger_list->pid);\n    }\n\n    return send_log_msg(NULL, NULL, buf, len);\n}\n\nstatic ssize_t logdGetPrune(\n        struct android_log_logger_list *logger_list __unused,\n        struct android_log_transport_context *transp __unused,\n        char *buf, size_t len)\n{\n    return send_log_msg(NULL, \"getPruneList\", buf, len);\n}\n\nstatic ssize_t logdSetPrune(\n        struct android_log_logger_list *logger_list __unused,\n        struct android_log_transport_context *transp __unused,\n        char *buf, size_t len)\n{\n    const char cmd[] = \"setPruneList \";\n    const size_t cmdlen = sizeof(cmd) - 1;\n\n    if (strlen(buf) > (len - cmdlen)) {\n        return -ENOMEM; /* KISS */\n    }\n    memmove(buf + cmdlen, buf, len - cmdlen);\n    buf[len - 1] = '\\0';\n    memcpy(buf, cmd, cmdlen);\n\n    return check_log_success(buf, send_log_msg(NULL, NULL, buf, len));\n}\n\n\nstatic void caught_signal(int signum __unused)\n{\n}\n\nstatic int logdOpen(struct android_log_logger_list *logger_list,\n                    struct android_log_transport_context *transp)\n{\n    struct android_log_logger *logger;\n    struct sigaction ignore;\n    struct sigaction old_sigaction;\n    unsigned int old_alarm = 0;\n    char buffer[256], *cp, c;\n    int e, ret, remaining;\n\n    int sock = transp->context.sock;\n    if (sock > 0) {\n        return sock;\n    }\n\n    if (!logger_list) {\n        return -EINVAL;\n    }\n\n    sock = socket_local_client(\"logdr\",\n                               ANDROID_SOCKET_NAMESPACE_RESERVED,\n                               SOCK_SEQPACKET);\n    if (sock == 0) {\n        /* Guarantee not file descriptor zero */\n        int newsock = socket_local_client(\"logdr\",\n                                   ANDROID_SOCKET_NAMESPACE_RESERVED,\n                                   SOCK_SEQPACKET);\n        close(sock);\n        sock = newsock;\n    }\n    if (sock <= 0) {\n        if ((sock == -1) && errno) {\n            return -errno;\n        }\n        return sock;\n    }\n\n    strcpy(buffer, (logger_list->mode & ANDROID_LOG_NONBLOCK) ?\n            \"dumpAndClose\" : \"stream\");\n    cp = buffer + strlen(buffer);\n\n    strcpy(cp, \" lids\");\n    cp += 5;\n    c = '=';\n    remaining = sizeof(buffer) - (cp - buffer);\n    logger_for_each(logger, logger_list) {\n        ret = snprintf(cp, remaining, \"%c%u\", c, logger->logId);\n        ret = min(ret, remaining);\n        remaining -= ret;\n        cp += ret;\n        c = ',';\n    }\n\n    if (logger_list->tail) {\n        ret = snprintf(cp, remaining, \" tail=%u\", logger_list->tail);\n        ret = min(ret, remaining);\n        remaining -= ret;\n        cp += ret;\n    }\n\n    if (logger_list->start.tv_sec || logger_list->start.tv_nsec) {\n        if (logger_list->mode & ANDROID_LOG_WRAP) {\n            // ToDo: alternate API to allow timeout to be adjusted.\n            ret = snprintf(cp, remaining, \" timeout=%u\",\n                           ANDROID_LOG_WRAP_DEFAULT_TIMEOUT);\n            ret = min(ret, remaining);\n            remaining -= ret;\n            cp += ret;\n        }\n        ret = snprintf(cp, remaining, \" start=%\" PRIu32 \".%09\" PRIu32,\n                       logger_list->start.tv_sec,\n                       logger_list->start.tv_nsec);\n        ret = min(ret, remaining);\n        remaining -= ret;\n        cp += ret;\n    }\n\n    if (logger_list->pid) {\n        ret = snprintf(cp, remaining, \" pid=%u\", logger_list->pid);\n        ret = min(ret, remaining);\n        cp += ret;\n    }\n\n    if (logger_list->mode & ANDROID_LOG_NONBLOCK) {\n        /* Deal with an unresponsive logd */\n        memset(&ignore, 0, sizeof(ignore));\n        ignore.sa_handler = caught_signal;\n        sigemptyset(&ignore.sa_mask);\n        /* particularily useful if tombstone is reporting for logd */\n        sigaction(SIGALRM, &ignore, &old_sigaction);\n        old_alarm = alarm(30);\n    }\n    ret = write(sock, buffer, cp - buffer);\n    e = errno;\n    if (logger_list->mode & ANDROID_LOG_NONBLOCK) {\n        if (e == EINTR) {\n            e = ETIMEDOUT;\n        }\n        alarm(old_alarm);\n        sigaction(SIGALRM, &old_sigaction, NULL);\n    }\n\n    if (ret <= 0) {\n        close(sock);\n        if ((ret == -1) && e) {\n            return -e;\n        }\n        if (ret == 0) {\n            return -EIO;\n        }\n        return ret;\n    }\n\n    return transp->context.sock = sock;\n}\n\n/* Read from the selected logs */\nstatic int logdRead(struct android_log_logger_list *logger_list,\n                    struct android_log_transport_context *transp,\n                    struct log_msg *log_msg)\n{\n    int ret, e;\n    struct sigaction ignore;\n    struct sigaction old_sigaction;\n    unsigned int old_alarm = 0;\n\n    ret = logdOpen(logger_list, transp);\n    if (ret < 0) {\n        return ret;\n    }\n\n    memset(log_msg, 0, sizeof(*log_msg));\n\n    if (logger_list->mode & ANDROID_LOG_NONBLOCK) {\n        memset(&ignore, 0, sizeof(ignore));\n        ignore.sa_handler = caught_signal;\n        sigemptyset(&ignore.sa_mask);\n        /* particularily useful if tombstone is reporting for logd */\n        sigaction(SIGALRM, &ignore, &old_sigaction);\n        old_alarm = alarm(30);\n    }\n\n    /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */\n    ret = recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0);\n    e = errno;\n\n    if (logger_list->mode & ANDROID_LOG_NONBLOCK) {\n        if ((ret == 0) || (e == EINTR)) {\n            e = EAGAIN;\n            ret = -1;\n        }\n        alarm(old_alarm);\n        sigaction(SIGALRM, &old_sigaction, NULL);\n    }\n\n    if ((ret == -1) && e) {\n        return -e;\n    }\n    return ret;\n}\n\nstatic int logdPoll(struct android_log_logger_list *logger_list,\n                    struct android_log_transport_context *transp)\n{\n    struct pollfd p;\n\n    int ret = logdOpen(logger_list, transp);\n    if (ret < 0) {\n        return ret;\n    }\n\n    memset(&p, 0, sizeof(p));\n    p.fd = ret;\n    p.events = POLLIN;\n    ret = poll(&p, 1, 20);\n    if ((ret > 0) && !(p.revents & POLLIN)) {\n        ret = 0;\n    }\n    if ((ret == -1) && errno) {\n        return -errno;\n    }\n    return ret;\n}\n\n/* Close all the logs */\nstatic void logdClose(struct android_log_logger_list *logger_list __unused,\n                      struct android_log_transport_context *transp)\n{\n    if (transp->context.sock > 0) {\n        close (transp->context.sock);\n        transp->context.sock = -1;\n    }\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/logd_writer.c",
    "content": "/*\n * Copyright (C) 2007-2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <endian.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <inttypes.h>\n#include <poll.h>\n#include <stdarg.h>\n#include <stdatomic.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <sys/un.h>\n#include <time.h>\n#include <unistd.h>\n\n#include <cutils/sockets.h>\n#include <log/logd.h>\n#include <log/logger.h>\n#include <log/log_read.h>\n#include <private/android_filesystem_config.h>\n#include <private/android_logger.h>\n\n#include \"config_write.h\"\n#include \"log_portability.h\"\n#include \"logger.h\"\n\n/* branchless on many architectures. */\n#define min(x,y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))\n\nstatic int logdAvailable(log_id_t LogId);\nstatic int logdOpen();\nstatic void logdClose();\nstatic int logdWrite(log_id_t logId, struct timespec *ts,\n                     struct iovec *vec, size_t nr);\n\nLIBLOG_HIDDEN struct android_log_transport_write logdLoggerWrite = {\n    .node = { &logdLoggerWrite.node, &logdLoggerWrite.node },\n    .context.sock = -1,\n    .name = \"logd\",\n    .available = logdAvailable,\n    .open = logdOpen,\n    .close = logdClose,\n    .write = logdWrite,\n};\n\n/* log_init_lock assumed */\nstatic int logdOpen()\n{\n    int i, ret = 0;\n\n    if (logdLoggerWrite.context.sock < 0) {\n        i = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0));\n        if (i < 0) {\n            ret = -errno;\n        } else if (TEMP_FAILURE_RETRY(fcntl(i, F_SETFL, O_NONBLOCK)) < 0) {\n            ret = -errno;\n            close(i);\n        } else {\n            struct sockaddr_un un;\n            memset(&un, 0, sizeof(struct sockaddr_un));\n            un.sun_family = AF_UNIX;\n            strcpy(un.sun_path, \"/dev/socket/logdw\");\n\n            if (TEMP_FAILURE_RETRY(connect(i, (struct sockaddr *)&un,\n                                           sizeof(struct sockaddr_un))) < 0) {\n                ret = -errno;\n                close(i);\n            } else {\n                logdLoggerWrite.context.sock = i;\n            }\n        }\n    }\n\n    return ret;\n}\n\nstatic void logdClose()\n{\n    if (logdLoggerWrite.context.sock >= 0) {\n        close(logdLoggerWrite.context.sock);\n        logdLoggerWrite.context.sock = -1;\n    }\n}\n\nstatic int logdAvailable(log_id_t logId)\n{\n    if (logId > LOG_ID_SECURITY) {\n        return -EINVAL;\n    }\n    if (logdLoggerWrite.context.sock < 0) {\n        if (access(\"/dev/socket/logdw\", W_OK) == 0) {\n            return 0;\n        }\n        return -EBADF;\n    }\n    return 1;\n}\n\nstatic int logdWrite(log_id_t logId, struct timespec *ts,\n                     struct iovec *vec, size_t nr)\n{\n    ssize_t ret;\n    static const unsigned headerLength = 1;\n    struct iovec newVec[nr + headerLength];\n    android_log_header_t header;\n    size_t i, payloadSize;\n    static atomic_int_fast32_t dropped;\n    static atomic_int_fast32_t droppedSecurity;\n\n    if (logdLoggerWrite.context.sock < 0) {\n        return -EBADF;\n    }\n\n    /* logd, after initialization and priv drop */\n    if (__android_log_uid() == AID_LOGD) {\n        /*\n         * ignore log messages we send to ourself (logd).\n         * Such log messages are often generated by libraries we depend on\n         * which use standard Android logging.\n         */\n        return 0;\n    }\n\n    /*\n     *  struct {\n     *      // what we provide to socket\n     *      android_log_header_t header;\n     *      // caller provides\n     *      union {\n     *          struct {\n     *              char     prio;\n     *              char     payload[];\n     *          } string;\n     *          struct {\n     *              uint32_t tag\n     *              char     payload[];\n     *          } binary;\n     *      };\n     *  };\n     */\n\n    header.tid = gettid();\n    header.realtime.tv_sec = ts->tv_sec;\n    header.realtime.tv_nsec = ts->tv_nsec;\n\n    newVec[0].iov_base = (unsigned char *)&header;\n    newVec[0].iov_len  = sizeof(header);\n\n    if (logdLoggerWrite.context.sock > 0) {\n        int32_t snapshot = atomic_exchange_explicit(&droppedSecurity, 0,\n                                                    memory_order_relaxed);\n        if (snapshot) {\n            android_log_event_int_t buffer;\n\n            header.id = LOG_ID_SECURITY;\n            buffer.header.tag = htole32(LIBLOG_LOG_TAG);\n            buffer.payload.type = EVENT_TYPE_INT;\n            buffer.payload.data = htole32(snapshot);\n\n            newVec[headerLength].iov_base = &buffer;\n            newVec[headerLength].iov_len  = sizeof(buffer);\n\n            ret = TEMP_FAILURE_RETRY(writev(logdLoggerWrite.context.sock, newVec, 2));\n            if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {\n                atomic_fetch_add_explicit(&droppedSecurity, snapshot,\n                                          memory_order_relaxed);\n            }\n        }\n        snapshot = atomic_exchange_explicit(&dropped, 0, memory_order_relaxed);\n        if (snapshot && __android_log_is_loggable(ANDROID_LOG_INFO,\n                                                  \"liblog\",\n                                                  ANDROID_LOG_VERBOSE)) {\n            android_log_event_int_t buffer;\n\n            header.id = LOG_ID_EVENTS;\n            buffer.header.tag = htole32(LIBLOG_LOG_TAG);\n            buffer.payload.type = EVENT_TYPE_INT;\n            buffer.payload.data = htole32(snapshot);\n\n            newVec[headerLength].iov_base = &buffer;\n            newVec[headerLength].iov_len  = sizeof(buffer);\n\n            ret = TEMP_FAILURE_RETRY(writev(logdLoggerWrite.context.sock, newVec, 2));\n            if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {\n                atomic_fetch_add_explicit(&dropped, snapshot,\n                                          memory_order_relaxed);\n            }\n        }\n    }\n\n    header.id = logId;\n\n    for (payloadSize = 0, i = headerLength; i < nr + headerLength; i++) {\n        newVec[i].iov_base = vec[i - headerLength].iov_base;\n        payloadSize += newVec[i].iov_len = vec[i - headerLength].iov_len;\n\n        if (payloadSize > LOGGER_ENTRY_MAX_PAYLOAD) {\n            newVec[i].iov_len -= payloadSize - LOGGER_ENTRY_MAX_PAYLOAD;\n            if (newVec[i].iov_len) {\n                ++i;\n            }\n            break;\n        }\n    }\n\n    /*\n     * The write below could be lost, but will never block.\n     *\n     * ENOTCONN occurs if logd dies.\n     * EAGAIN occurs if logd is overloaded.\n     */\n    ret = TEMP_FAILURE_RETRY(writev(logdLoggerWrite.context.sock, newVec, i));\n    if (ret < 0) {\n        ret = -errno;\n        if (ret == -ENOTCONN) {\n            __android_log_lock();\n            logdClose();\n            ret = logdOpen();\n            __android_log_unlock();\n\n            if (ret < 0) {\n                return ret;\n            }\n\n            ret = TEMP_FAILURE_RETRY(writev(logdLoggerWrite.context.sock, newVec, i));\n            if (ret < 0) {\n                ret = -errno;\n            }\n        }\n    }\n\n    if (ret > (ssize_t)sizeof(header)) {\n        ret -= sizeof(header);\n    } else if (ret == -EAGAIN) {\n        atomic_fetch_add_explicit(&dropped, 1, memory_order_relaxed);\n        if (logId == LOG_ID_SECURITY) {\n            atomic_fetch_add_explicit(&droppedSecurity, 1,\n                                      memory_order_relaxed);\n        }\n    }\n\n    return ret;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/logger.h",
    "content": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _LIBLOG_LOGGER_H__\n#define _LIBLOG_LOGGER_H__\n\n#include <stdbool.h>\n#include <log/uio.h>\n\n#include <cutils/list.h>\n#include <log/log.h>\n#include <log/log_read.h>\n#include <log/logger.h>\n\n#include \"log_portability.h\"\n\n__BEGIN_DECLS\n\n/* Union, sock or fd of zero is not allowed unless static initialized */\nunion android_log_context {\n  void *private;\n  int sock;\n  int fd;\n  struct listnode *node;\n};\n\nstruct android_log_transport_write {\n  struct listnode node;\n  const char *name;\n  unsigned logMask; /* cache of available success */\n  union android_log_context context; /* Initialized by static allocation */\n\n  int (*available)(log_id_t logId);\n  int (*open)();\n  void (*close)();\n  int (*write)(log_id_t logId, struct timespec *ts, struct iovec *vec, size_t nr);\n};\n\nstruct android_log_logger_list;\nstruct android_log_transport_context;\nstruct android_log_logger;\n\nstruct android_log_transport_read {\n  struct listnode node;\n  const char *name;\n\n  int (*available)(log_id_t logId);\n  int (*version)(struct android_log_logger *logger,\n                 struct android_log_transport_context *transp);\n  void (*close)(struct android_log_logger_list *logger_list,\n                struct android_log_transport_context *transp);\n\n  /*\n   * Expect all to instantiate open on any call, so we do not have\n   * an expicit open call\n   */\n  int (*read)(struct android_log_logger_list *logger_list,\n              struct android_log_transport_context *transp,\n              struct log_msg *log_msg);\n  /* Assumption is only called if not ANDROID_LOG_NONBLOCK */\n  int (*poll)(struct android_log_logger_list *logger_list,\n              struct android_log_transport_context *transp);\n\n  int (*clear)(struct android_log_logger *logger,\n               struct android_log_transport_context *transp);\n  ssize_t (*setSize)(struct android_log_logger *logger,\n                     struct android_log_transport_context *transp,\n                     size_t size);\n  ssize_t (*getSize)(struct android_log_logger *logger,\n                     struct android_log_transport_context *transp);\n  ssize_t (*getReadableSize)(struct android_log_logger *logger,\n                             struct android_log_transport_context *transp);\n\n  ssize_t (*getPrune)(struct android_log_logger_list *logger_list,\n                      struct android_log_transport_context *transp,\n                      char *buf, size_t len);\n  ssize_t (*setPrune)(struct android_log_logger_list *logger_list,\n                      struct android_log_transport_context *transp,\n                      char *buf, size_t len);\n  ssize_t (*getStats)(struct android_log_logger_list *logger_list,\n                      struct android_log_transport_context *transp,\n                      char *buf, size_t len);\n};\n\nstruct android_log_logger_list {\n  struct listnode logger;\n  struct listnode transport;\n  int mode;\n  unsigned int tail;\n  log_time start;\n  pid_t pid;\n};\n\nstruct android_log_logger {\n  struct listnode node;\n  struct android_log_logger_list *parent;\n\n  log_id_t logId;\n};\n\nstruct android_log_transport_context {\n  struct listnode node;\n  union android_log_context context; /* zero init per-transport context */\n  struct android_log_logger_list *parent;\n\n  struct android_log_transport_read *transport;\n  unsigned logMask;\n  int ret;\n  struct log_msg logMsg; /* valid is logMsg.len != 0 */\n};\n\n/* assumes caller has structures read-locked, single threaded, or fenced */\n#define transport_context_for_each(transp, logger_list)              \\\n  for (transp = node_to_item((logger_list)->transport.next,          \\\n                             struct android_log_transport_context,   \\\n                             node);                                  \\\n       (transp != node_to_item(&(logger_list)->transport,            \\\n                               struct android_log_transport_context, \\\n                               node)) &&                             \\\n           (transp->parent == (logger_list));                        \\\n       transp = node_to_item(transp->node.next,                      \\\n                             struct android_log_transport_context, node))\n\n#define logger_for_each(logp, logger_list)                          \\\n    for (logp = node_to_item((logger_list)->logger.next,            \\\n                             struct android_log_logger, node);      \\\n         (logp != node_to_item(&(logger_list)->logger,              \\\n                               struct android_log_logger, node)) && \\\n             (logp->parent == (logger_list));                       \\\n         logp = node_to_item((logp)->node.next,                     \\\n                             struct android_log_logger, node))\n\n/* OS specific dribs and drabs */\n\n#if defined(_WIN32)\ntypedef uint32_t uid_t;\n#endif\n\nLIBLOG_HIDDEN uid_t __android_log_uid();\nLIBLOG_HIDDEN pid_t __android_log_pid();\nLIBLOG_HIDDEN void __android_log_lock();\nLIBLOG_HIDDEN int __android_log_trylock();\nLIBLOG_HIDDEN void __android_log_unlock();\nLIBLOG_HIDDEN int __android_log_is_debuggable();\n\n__END_DECLS\n\n#endif /* _LIBLOG_LOGGER_H__ */\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/logger_lock.c",
    "content": "/*\n * Copyright (C) 2007-2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * Some OS specific dribs and drabs (locking etc).\n */\n\n#if !defined(_WIN32)\n#include <pthread.h>\n#endif\n\n#include <private/android_filesystem_config.h>\n\n#include \"logger.h\"\n\nLIBLOG_HIDDEN uid_t __android_log_uid()\n{\n#if defined(_WIN32)\n    return AID_SYSTEM;\n#else\n    static uid_t last_uid = AID_ROOT; /* logd *always* starts up as AID_ROOT */\n\n    if (last_uid == AID_ROOT) { /* have we called to get the UID yet? */\n        last_uid = getuid();\n    }\n    return last_uid;\n#endif\n}\n\nLIBLOG_HIDDEN pid_t __android_log_pid()\n{\n    static pid_t last_pid = (pid_t) -1;\n\n    if (last_pid == (pid_t) -1) {\n        last_pid = getpid();\n    }\n    return last_pid;\n}\n\n#if !defined(_WIN32)\nstatic pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;\n#endif\n\nLIBLOG_HIDDEN void __android_log_lock()\n{\n#if !defined(_WIN32)\n    /*\n     * If we trigger a signal handler in the middle of locked activity and the\n     * signal handler logs a message, we could get into a deadlock state.\n     */\n    pthread_mutex_lock(&log_init_lock);\n#endif\n}\n\nLIBLOG_HIDDEN int __android_log_trylock()\n{\n#if !defined(_WIN32)\n    return pthread_mutex_trylock(&log_init_lock);\n#else\n    return 0;\n#endif\n}\n\nLIBLOG_HIDDEN void __android_log_unlock()\n{\n#if !defined(_WIN32)\n    pthread_mutex_unlock(&log_init_lock);\n#endif\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/logger_name.c",
    "content": "/*\n** Copyright 2013-2014, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\");\n** you may not use this file except in compliance with the License.\n** You may obtain a copy of the License at\n**\n**     http://www.apache.org/licenses/LICENSE-2.0\n**\n** Unless required by applicable law or agreed to in writing, software\n** distributed under the License is distributed on an \"AS IS\" BASIS,\n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n** See the License for the specific language governing permissions and\n** limitations under the License.\n*/\n\n#include <string.h>\n\n#include <log/log.h>\n#include <log/logger.h>\n\n#include \"log_portability.h\"\n\n/* In the future, we would like to make this list extensible */\nstatic const char *LOG_NAME[LOG_ID_MAX] = {\n    [LOG_ID_MAIN] = \"main\",\n    [LOG_ID_RADIO] = \"radio\",\n    [LOG_ID_EVENTS] = \"events\",\n    [LOG_ID_SYSTEM] = \"system\",\n    [LOG_ID_CRASH] = \"crash\",\n    [LOG_ID_SECURITY] = \"security\",\n    [LOG_ID_KERNEL] = \"kernel\",\n};\n\nLIBLOG_ABI_PUBLIC const char *android_log_id_to_name(log_id_t log_id)\n{\n    if (log_id >= LOG_ID_MAX) {\n        log_id = LOG_ID_MAIN;\n    }\n    return LOG_NAME[log_id];\n}\n\nLIBLOG_ABI_PUBLIC log_id_t android_name_to_log_id(const char *logName)\n{\n    const char *b;\n    int ret;\n\n    if (!logName) {\n        return -1; /* NB: log_id_t is unsigned */\n    }\n    b = strrchr(logName, '/');\n    if (!b) {\n        b = logName;\n    } else {\n        ++b;\n    }\n\n    for(ret = LOG_ID_MIN; ret < LOG_ID_MAX; ++ret) {\n        const char *l = LOG_NAME[ret];\n        if (l && !strcmp(b, l)) {\n            return ret;\n        }\n    }\n    return -1;   /* should never happen */\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/logger_read.c",
    "content": "/*\n** Copyright 2013-2014, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\");\n** you may not use this file except in compliance with the License.\n** You may obtain a copy of the License at\n**\n**     http://www.apache.org/licenses/LICENSE-2.0\n**\n** Unless required by applicable law or agreed to in writing, software\n** distributed under the License is distributed on an \"AS IS\" BASIS,\n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n** See the License for the specific language governing permissions and\n** limitations under the License.\n*/\n\n#include <errno.h>\n#include <fcntl.h>\n#include <pthread.h>\n#include <sched.h>\n#include <stddef.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include <cutils/list.h>\n#include <log/log.h>\n#include <log/logger.h>\n#include <private/android_filesystem_config.h>\n\n#include \"config_read.h\"\n#include \"log_portability.h\"\n#include \"logger.h\"\n\n/* android_logger_alloc unimplemented, no use case */\n/* android_logger_free not exported */\nstatic void android_logger_free(struct logger *logger)\n{\n    struct android_log_logger *logger_internal =\n            (struct android_log_logger *)logger;\n\n    if (!logger_internal) {\n        return;\n    }\n\n    list_remove(&logger_internal->node);\n\n    free(logger_internal);\n}\n\n/* android_logger_alloc unimplemented, no use case */\n\n/* method for getting the associated sublog id */\nLIBLOG_ABI_PUBLIC log_id_t android_logger_get_id(struct logger *logger)\n{\n    return ((struct android_log_logger *)logger)->logId;\n}\n\nstatic int init_transport_context(struct android_log_logger_list *logger_list)\n{\n    struct android_log_transport_read *transport;\n    struct listnode *node;\n\n    if (!logger_list) {\n        return -EINVAL;\n    }\n\n    if (list_empty(&logger_list->logger)) {\n        return -EINVAL;\n    }\n\n    if (!list_empty(&logger_list->transport)) {\n        return 0;\n    }\n\n    __android_log_lock();\n    /* mini __write_to_log_initialize() to populate transports */\n    if (list_empty(&__android_log_transport_read) &&\n            list_empty(&__android_log_persist_read)) {\n        __android_log_config_read();\n    }\n    __android_log_unlock();\n\n    node = (logger_list->mode & ANDROID_LOG_PSTORE) ?\n            &__android_log_persist_read : &__android_log_transport_read;\n\n    read_transport_for_each(transport, node) {\n        struct android_log_transport_context *transp;\n        struct android_log_logger *logger;\n        unsigned logMask = 0;\n\n        logger_for_each(logger, logger_list) {\n            log_id_t logId = logger->logId;\n\n            if ((logId == LOG_ID_SECURITY) &&\n                    (__android_log_uid() != AID_SYSTEM)) {\n                continue;\n            }\n            if (transport->read &&\n                    (!transport->available ||\n                        (transport->available(logId) >= 0))) {\n                logMask |= 1 << logId;\n            }\n        }\n        if (!logMask) {\n            continue;\n        }\n        transp = calloc(1, sizeof(*transp));\n        if (!transp) {\n            return -ENOMEM;\n        }\n        transp->parent = logger_list;\n        transp->transport = transport;\n        transp->logMask = logMask;\n        transp->ret = 1;\n        list_add_tail(&logger_list->transport, &transp->node);\n    }\n    if (list_empty(&logger_list->transport)) {\n        return -ENODEV;\n    }\n    return 0;\n}\n\n#define LOGGER_FUNCTION(logger, def, func, args...)                           \\\n    ssize_t ret = -EINVAL;                                                    \\\n    struct android_log_transport_context *transp;                             \\\n    struct android_log_logger *logger_internal =                              \\\n            (struct android_log_logger *)logger;                              \\\n                                                                              \\\n    if (!logger_internal) {                                                   \\\n        return ret;                                                           \\\n    }                                                                         \\\n    ret = init_transport_context(logger_internal->parent);                    \\\n    if (ret < 0) {                                                            \\\n        return ret;                                                           \\\n    }                                                                         \\\n                                                                              \\\n    ret = (def);                                                              \\\n    transport_context_for_each(transp, logger_internal->parent) {             \\\n        if ((transp->logMask & (1 << logger_internal->logId)) &&              \\\n                transp->transport && transp->transport->func) {               \\\n            ssize_t retval = (transp->transport->func)(logger_internal,       \\\n                                                       transp, ## args);      \\\n            if ((ret >= 0) || (ret == (def))) {                               \\\n                ret = retval;                                                 \\\n            }                                                                 \\\n        }                                                                     \\\n    }                                                                         \\\n    return ret\n\nLIBLOG_ABI_PUBLIC int android_logger_clear(struct logger *logger)\n{\n    LOGGER_FUNCTION(logger, -ENODEV, clear);\n}\n\n/* returns the total size of the log's ring buffer */\nLIBLOG_ABI_PUBLIC long android_logger_get_log_size(struct logger *logger)\n{\n    LOGGER_FUNCTION(logger, -ENODEV, getSize);\n}\n\nLIBLOG_ABI_PUBLIC int android_logger_set_log_size(struct logger *logger,\n                                                  unsigned long size)\n{\n    LOGGER_FUNCTION(logger, -ENODEV, setSize, size);\n}\n\n/*\n * returns the readable size of the log's ring buffer (that is, amount of the\n * log consumed)\n */\nLIBLOG_ABI_PUBLIC long android_logger_get_log_readable_size(\n        struct logger *logger)\n{\n    LOGGER_FUNCTION(logger, -ENODEV, getReadableSize);\n}\n\n/*\n * returns the logger version\n */\nLIBLOG_ABI_PUBLIC int android_logger_get_log_version(struct logger *logger)\n{\n    LOGGER_FUNCTION(logger, 4, version);\n}\n\n#define LOGGER_LIST_FUNCTION(logger_list, def, func, args...)                 \\\n    struct android_log_transport_context *transp;                             \\\n    struct android_log_logger_list *logger_list_internal =                    \\\n            (struct android_log_logger_list *)logger_list;                    \\\n                                                                              \\\n    ssize_t ret = init_transport_context(logger_list_internal);               \\\n    if (ret < 0) {                                                            \\\n        return ret;                                                           \\\n    }                                                                         \\\n                                                                              \\\n    ret = (def);                                                              \\\n    transport_context_for_each(transp, logger_list_internal) {                \\\n        if (transp->transport && (transp->transport->func)) {                 \\\n            ssize_t retval = (transp->transport->func)(logger_list_internal,  \\\n                                                       transp, ## args);      \\\n            if ((ret >= 0) || (ret == (def))) {                               \\\n                ret = retval;                                                 \\\n            }                                                                 \\\n        }                                                                     \\\n    }                                                                         \\\n    return ret\n\n/*\n * returns statistics\n */\nLIBLOG_ABI_PUBLIC ssize_t android_logger_get_statistics(\n        struct logger_list *logger_list,\n        char *buf, size_t len)\n{\n    LOGGER_LIST_FUNCTION(logger_list, -ENODEV, getStats, buf, len);\n}\n\nLIBLOG_ABI_PUBLIC ssize_t android_logger_get_prune_list(\n        struct logger_list *logger_list,\n        char *buf, size_t len)\n{\n    LOGGER_LIST_FUNCTION(logger_list, -ENODEV, getPrune, buf, len);\n}\n\nLIBLOG_ABI_PUBLIC int android_logger_set_prune_list(\n        struct logger_list *logger_list,\n        char *buf, size_t len)\n{\n    LOGGER_LIST_FUNCTION(logger_list, -ENODEV, setPrune, buf, len);\n}\n\nLIBLOG_ABI_PUBLIC struct logger_list *android_logger_list_alloc(\n        int mode,\n        unsigned int tail,\n        pid_t pid)\n{\n    struct android_log_logger_list *logger_list;\n\n    logger_list = calloc(1, sizeof(*logger_list));\n    if (!logger_list) {\n        return NULL;\n    }\n\n    list_init(&logger_list->logger);\n    list_init(&logger_list->transport);\n    logger_list->mode = mode;\n    logger_list->tail = tail;\n    logger_list->pid = pid;\n\n    return (struct logger_list *)logger_list;\n}\n\nLIBLOG_ABI_PUBLIC struct logger_list *android_logger_list_alloc_time(\n        int mode,\n        log_time start,\n        pid_t pid)\n{\n    struct android_log_logger_list *logger_list;\n\n    logger_list = calloc(1, sizeof(*logger_list));\n    if (!logger_list) {\n        return NULL;\n    }\n\n    list_init(&logger_list->logger);\n    list_init(&logger_list->transport);\n    logger_list->mode = mode;\n    logger_list->start = start;\n    logger_list->pid = pid;\n\n    return (struct logger_list *)logger_list;\n}\n\n/* android_logger_list_register unimplemented, no use case */\n/* android_logger_list_unregister unimplemented, no use case */\n\n/* Open the named log and add it to the logger list */\nLIBLOG_ABI_PUBLIC struct logger *android_logger_open(\n        struct logger_list *logger_list,\n        log_id_t logId)\n{\n    struct android_log_logger_list *logger_list_internal =\n            (struct android_log_logger_list *)logger_list;\n    struct android_log_logger *logger;\n\n    if (!logger_list_internal || (logId >= LOG_ID_MAX)) {\n        goto err;\n    }\n\n    logger_for_each(logger, logger_list_internal) {\n        if (logger->logId == logId) {\n            goto ok;\n        }\n    }\n\n    logger = calloc(1, sizeof(*logger));\n    if (!logger) {\n        goto err;\n    }\n\n    logger->logId = logId;\n    list_add_tail(&logger_list_internal->logger, &logger->node);\n    logger->parent = logger_list_internal;\n\n    /* Reset known transports to re-evaluate, we just added one */\n    while (!list_empty(&logger_list_internal->transport)) {\n        struct listnode *node = list_head(&logger_list_internal->transport);\n        struct android_log_transport_context *transp =\n                node_to_item(node, struct android_log_transport_context, node);\n\n        list_remove(&transp->node);\n        free(transp);\n    }\n    goto ok;\n\nerr:\n    logger = NULL;\nok:\n    return (struct logger *)logger;\n}\n\n/* Open the single named log and make it part of a new logger list */\nLIBLOG_ABI_PUBLIC struct logger_list *android_logger_list_open(\n        log_id_t logId,\n        int mode,\n        unsigned int tail,\n        pid_t pid)\n{\n    struct logger_list *logger_list =\n            android_logger_list_alloc(mode, tail, pid);\n\n    if (!logger_list) {\n        return NULL;\n    }\n\n    if (!android_logger_open(logger_list, logId)) {\n        android_logger_list_free(logger_list);\n        return NULL;\n    }\n\n    return logger_list;\n}\n\n/* Read from the selected logs */\nLIBLOG_ABI_PUBLIC int android_logger_list_read(struct logger_list *logger_list,\n                                               struct log_msg *log_msg)\n{\n    struct android_log_transport_context *transp;\n    struct android_log_logger_list *logger_list_internal =\n            (struct android_log_logger_list *)logger_list;\n\n    int ret = init_transport_context(logger_list_internal);\n    if (ret < 0) {\n        return ret;\n    }\n\n    /* at least one transport */\n    transp = node_to_item(logger_list_internal->transport.next,\n                          struct android_log_transport_context, node);\n\n    /* more than one transport? */\n    if (transp->node.next != &logger_list_internal->transport) {\n        /* Poll and merge sort the entries if from multiple transports */\n        struct android_log_transport_context *oldest = NULL;\n        int ret;\n        int polled = 0;\n        do {\n            if (polled) {\n                sched_yield();\n            }\n            ret = -1000;\n            polled = 0;\n            do {\n                int retval = transp->ret;\n                if ((retval > 0) && !transp->logMsg.entry.len) {\n                    if (!transp->transport->read) {\n                        retval = transp->ret = 0;\n                    } else if ((logger_list_internal->mode &\n                                ANDROID_LOG_NONBLOCK) ||\n                            !transp->transport->poll) {\n                        retval = transp->ret = (*transp->transport->read)(\n                                logger_list_internal,\n                                transp,\n                                &transp->logMsg);\n                    } else {\n                        int pollval = (*transp->transport->poll)(\n                                logger_list_internal, transp);\n                        if (pollval <= 0) {\n                            sched_yield();\n                            pollval = (*transp->transport->poll)(\n                                    logger_list_internal, transp);\n                        }\n                        polled = 1;\n                        if (pollval < 0) {\n                            if ((pollval == -EINTR) || (pollval == -EAGAIN)) {\n                                return -EAGAIN;\n                            }\n                            retval = transp->ret = pollval;\n                        } else if (pollval > 0) {\n                            retval = transp->ret = (*transp->transport->read)(\n                                    logger_list_internal,\n                                    transp,\n                                    &transp->logMsg);\n                        }\n                    }\n                }\n                if (ret < retval) {\n                    ret = retval;\n                }\n                if ((transp->ret > 0) && transp->logMsg.entry.len &&\n                        (!oldest ||\n                            (oldest->logMsg.entry.sec >\n                                transp->logMsg.entry.sec) ||\n                            ((oldest->logMsg.entry.sec ==\n                                    transp->logMsg.entry.sec) &&\n                                (oldest->logMsg.entry.nsec >\n                                    transp->logMsg.entry.nsec)))) {\n                    oldest = transp;\n                }\n                transp = node_to_item(transp->node.next,\n                                      struct android_log_transport_context,\n                                      node);\n            } while (transp != node_to_item(\n                    &logger_list_internal->transport,\n                    struct android_log_transport_context,\n                    node));\n            if (!oldest &&\n                    (logger_list_internal->mode & ANDROID_LOG_NONBLOCK)) {\n                return (ret < 0) ? ret : -EAGAIN;\n            }\n            transp = node_to_item(logger_list_internal->transport.next,\n                                  struct android_log_transport_context, node);\n        } while (!oldest && (ret > 0));\n        if (!oldest) {\n            return ret;\n        }\n        memcpy(log_msg, &oldest->logMsg, oldest->logMsg.entry.len +\n                    (oldest->logMsg.entry.hdr_size ?\n                        oldest->logMsg.entry.hdr_size :\n                        sizeof(struct logger_entry)));\n        oldest->logMsg.entry.len = 0; /* Mark it as copied */\n        return oldest->ret;\n    }\n\n    /* if only one, no need to copy into transport_context and merge-sort */\n    return (transp->transport->read)(logger_list_internal, transp, log_msg);\n}\n\n/* Close all the logs */\nLIBLOG_ABI_PUBLIC void android_logger_list_free(struct logger_list *logger_list)\n{\n    struct android_log_logger_list *logger_list_internal =\n            (struct android_log_logger_list *)logger_list;\n\n    if (logger_list_internal == NULL) {\n        return;\n    }\n\n    while (!list_empty(&logger_list_internal->transport)) {\n        struct listnode *node = list_head(&logger_list_internal->transport);\n        struct android_log_transport_context *transp =\n                node_to_item(node, struct android_log_transport_context, node);\n\n        if (transp->transport && transp->transport->close) {\n            (*transp->transport->close)(logger_list_internal, transp);\n        }\n        list_remove(&transp->node);\n        free(transp);\n    }\n\n    while (!list_empty(&logger_list_internal->logger)) {\n        struct listnode *node = list_head(&logger_list_internal->logger);\n        struct android_log_logger *logger =\n                node_to_item(node, struct android_log_logger, node);\n        android_logger_free((struct logger *)logger);\n    }\n\n    free(logger_list_internal);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/logger_write.c",
    "content": "/*\n * Copyright (C) 2007-2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <errno.h>\n#include <stdatomic.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/time.h>\n\n#ifdef __BIONIC__\n#include <android/set_abort_message.h>\n#endif\n\n#include <log/event_tag_map.h>\n#include <log/logd.h>\n#include <log/logger.h>\n#include <log/log_read.h>\n#include <private/android_filesystem_config.h>\n#include <private/android_logger.h>\n\n#include \"config_write.h\"\n#include \"log_portability.h\"\n#include \"logger.h\"\n\n#define LOG_BUF_SIZE 1024\n\nstatic int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr);\nstatic int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init;\n\n/*\n * This is used by the C++ code to decide if it should write logs through\n * the C code.  Basically, if /dev/socket/logd is available, we're running in\n * the simulator rather than a desktop tool and want to use the device.\n */\nstatic enum {\n    kLogUninitialized, kLogNotAvailable, kLogAvailable\n} g_log_status = kLogUninitialized;\n\nstatic int check_log_uid_permissions()\n{\n#if defined(__BIONIC__)\n    uid_t uid = __android_log_uid();\n\n    /* Matches clientHasLogCredentials() in logd */\n    if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {\n        uid = geteuid();\n        if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {\n            gid_t gid = getgid();\n            if ((gid != AID_SYSTEM) &&\n                    (gid != AID_ROOT) &&\n                    (gid != AID_LOG)) {\n                gid = getegid();\n                if ((gid != AID_SYSTEM) &&\n                        (gid != AID_ROOT) &&\n                        (gid != AID_LOG)) {\n                    int num_groups;\n                    gid_t *groups;\n\n                    num_groups = getgroups(0, NULL);\n                    if (num_groups <= 0) {\n                        return -EPERM;\n                    }\n                    groups = calloc(num_groups, sizeof(gid_t));\n                    if (!groups) {\n                        return -ENOMEM;\n                    }\n                    num_groups = getgroups(num_groups, groups);\n                    while (num_groups > 0) {\n                        if (groups[num_groups - 1] == AID_LOG) {\n                            break;\n                        }\n                        --num_groups;\n                    }\n                    free(groups);\n                    if (num_groups <= 0) {\n                        return -EPERM;\n                    }\n                }\n            }\n        }\n    }\n#endif\n    return 0;\n}\n\nstatic void __android_log_cache_available(\n        struct android_log_transport_write *node)\n{\n    size_t i;\n\n    if (node->logMask) {\n        return;\n    }\n\n    for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {\n        if (node->write &&\n                (i != LOG_ID_KERNEL) &&\n                ((i != LOG_ID_SECURITY) ||\n                    (check_log_uid_permissions() == 0)) &&\n                (!node->available || ((*node->available)(i) >= 0))) {\n            node->logMask |= 1 << i;\n        }\n    }\n}\n\nLIBLOG_ABI_PUBLIC int __android_log_dev_available()\n{\n    struct android_log_transport_write *node;\n\n    if (list_empty(&__android_log_transport_write)) {\n        return kLogUninitialized;\n    }\n\n    write_transport_for_each(node, &__android_log_transport_write) {\n        __android_log_cache_available(node);\n        if (node->logMask) {\n            return kLogAvailable;\n        }\n    }\n    return kLogNotAvailable;\n}\n\n/* log_init_lock assumed */\nstatic int __write_to_log_initialize()\n{\n    struct android_log_transport_write *transport;\n    struct listnode *n;\n    int i = 0, ret = 0;\n\n    __android_log_config_write();\n    write_transport_for_each_safe(transport, n, &__android_log_transport_write) {\n        __android_log_cache_available(transport);\n        if (!transport->logMask) {\n            list_remove(&transport->node);\n            continue;\n        }\n        if (!transport->open || ((*transport->open)() < 0)) {\n            if (transport->close) {\n                (*transport->close)();\n            }\n            list_remove(&transport->node);\n            continue;\n        }\n        ++ret;\n    }\n    write_transport_for_each_safe(transport, n, &__android_log_persist_write) {\n        __android_log_cache_available(transport);\n        if (!transport->logMask) {\n            list_remove(&transport->node);\n            continue;\n        }\n        if (!transport->open || ((*transport->open)() < 0)) {\n            if (transport->close) {\n                (*transport->close)();\n            }\n            list_remove(&transport->node);\n            continue;\n        }\n        ++i;\n    }\n    if (!ret && !i) {\n        return -ENODEV;\n    }\n\n    return ret;\n}\n\n/*\n * Extract a 4-byte value from a byte stream. le32toh open coded\n */\nstatic inline uint32_t get4LE(const uint8_t* src)\n{\n    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);\n}\n\nstatic int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)\n{\n    struct android_log_transport_write *node;\n    int ret;\n    struct timespec ts;\n    size_t len, i;\n\n    for (len = i = 0; i < nr; ++i) {\n        len += vec[i].iov_len;\n    }\n    if (!len) {\n        return -EINVAL;\n    }\n\n#if defined(__BIONIC__)\n    if (log_id == LOG_ID_SECURITY) {\n        if (vec[0].iov_len < 4) {\n            return -EINVAL;\n        }\n\n        ret = check_log_uid_permissions();\n        if (ret < 0) {\n            return ret;\n        }\n        if (!__android_log_security()) {\n            /* If only we could reset downstream logd counter */\n            return -EPERM;\n        }\n    } else if (log_id == LOG_ID_EVENTS) {\n        static atomic_uintptr_t map;\n        const char *tag;\n        EventTagMap *m, *f;\n\n        if (vec[0].iov_len < 4) {\n            return -EINVAL;\n        }\n\n        tag = NULL;\n        f = NULL;\n        m = (EventTagMap *)atomic_load(&map);\n\n        if (!m) {\n            ret = __android_log_trylock();\n            m = (EventTagMap *)atomic_load(&map); /* trylock flush cache */\n            if (!m) {\n                m = android_openEventTagMap(EVENT_TAG_MAP_FILE);\n                if (ret) { /* trylock failed, use local copy, mark for close */\n                    f = m;\n                } else {\n                    if (!m) { /* One chance to open map file */\n                        m = (EventTagMap *)(uintptr_t)-1LL;\n                    }\n                    atomic_store(&map, (uintptr_t)m);\n                }\n            }\n            if (!ret) { /* trylock succeeded, unlock */\n                __android_log_unlock();\n            }\n        }\n        if (m && (m != (EventTagMap *)(uintptr_t)-1LL)) {\n            tag = android_lookupEventTag(m, get4LE(vec[0].iov_base));\n        }\n        ret = __android_log_is_loggable(ANDROID_LOG_INFO,\n                                        tag,\n                                        ANDROID_LOG_VERBOSE);\n        if (f) { /* local copy marked for close */\n            android_closeEventTagMap(f);\n        }\n        if (!ret) {\n            return -EPERM;\n        }\n    } else {\n        /* Validate the incoming tag, tag content can not split across iovec */\n        char prio = ANDROID_LOG_VERBOSE;\n        const char *tag = vec[0].iov_base;\n        size_t len = vec[0].iov_len;\n        if (!tag) {\n            len = 0;\n        }\n        if (len > 0) {\n            prio = *tag;\n            if (len > 1) {\n                --len;\n                ++tag;\n            } else {\n                len = vec[1].iov_len;\n                tag = ((const char *)vec[1].iov_base);\n                if (!tag) {\n                    len = 0;\n                }\n            }\n        }\n        /* tag must be nul terminated */\n        if (strnlen(tag, len) >= len) {\n            tag = NULL;\n        }\n\n        if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {\n            return -EPERM;\n        }\n    }\n\n    clock_gettime(android_log_clockid(), &ts);\n#else\n    /* simulate clock_gettime(CLOCK_REALTIME, &ts); */\n    {\n        struct timeval tv;\n        gettimeofday(&tv, NULL);\n        ts.tv_sec = tv.tv_sec;\n        ts.tv_nsec = tv.tv_usec * 1000;\n    }\n#endif\n\n    ret = 0;\n    i = 1 << log_id;\n    write_transport_for_each(node, &__android_log_transport_write) {\n        if (node->logMask & i) {\n            ssize_t retval;\n            retval = (*node->write)(log_id, &ts, vec, nr);\n            if (ret >= 0) {\n                ret = retval;\n            }\n        }\n    }\n\n    write_transport_for_each(node, &__android_log_persist_write) {\n        if (node->logMask & i) {\n            (void)(*node->write)(log_id, &ts, vec, nr);\n        }\n    }\n\n    return ret;\n}\n\nstatic int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr)\n{\n    __android_log_lock();\n\n    if (write_to_log == __write_to_log_init) {\n        int ret;\n\n        ret = __write_to_log_initialize();\n        if (ret < 0) {\n            __android_log_unlock();\n            if (!list_empty(&__android_log_persist_write)) {\n                __write_to_log_daemon(log_id, vec, nr);\n            }\n            return ret;\n        }\n\n        write_to_log = __write_to_log_daemon;\n    }\n\n    __android_log_unlock();\n\n    return write_to_log(log_id, vec, nr);\n}\n\nLIBLOG_ABI_PUBLIC int __android_log_write(int prio, const char *tag,\n                                          const char *msg)\n{\n    return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);\n}\n\nLIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio,\n                                              const char *tag, const char *msg)\n{\n    struct iovec vec[3];\n    char tmp_tag[32];\n\n    if (!tag)\n        tag = \"\";\n\n    /* XXX: This needs to go! */\n    if ((bufID != LOG_ID_RADIO) &&\n         (!strcmp(tag, \"HTC_RIL\") ||\n        !strncmp(tag, \"RIL\", 3) || /* Any log tag with \"RIL\" as the prefix */\n        !strncmp(tag, \"IMS\", 3) || /* Any log tag with \"IMS\" as the prefix */\n        !strcmp(tag, \"AT\") ||\n        !strcmp(tag, \"GSM\") ||\n        !strcmp(tag, \"STK\") ||\n        !strcmp(tag, \"CDMA\") ||\n        !strcmp(tag, \"PHONE\") ||\n        !strcmp(tag, \"SMS\"))) {\n            bufID = LOG_ID_RADIO;\n            /* Inform third party apps/ril/radio.. to use Rlog or RLOG */\n            snprintf(tmp_tag, sizeof(tmp_tag), \"use-Rlog/RLOG-%s\", tag);\n            tag = tmp_tag;\n    }\n\n#if __BIONIC__\n    if (prio == ANDROID_LOG_FATAL) {\n        android_set_abort_message(msg);\n    }\n#endif\n\n    vec[0].iov_base = (unsigned char *)&prio;\n    vec[0].iov_len  = 1;\n    vec[1].iov_base = (void *)tag;\n    vec[1].iov_len  = strlen(tag) + 1;\n    vec[2].iov_base = (void *)msg;\n    vec[2].iov_len  = strlen(msg) + 1;\n\n    return write_to_log(bufID, vec, 3);\n}\n\nLIBLOG_ABI_PUBLIC int __android_log_vprint(int prio, const char *tag,\n                                           const char *fmt, va_list ap)\n{\n    char buf[LOG_BUF_SIZE];\n\n    vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);\n\n    return __android_log_write(prio, tag, buf);\n}\n\nLIBLOG_ABI_PUBLIC int __android_log_print(int prio, const char *tag,\n                                          const char *fmt, ...)\n{\n    va_list ap;\n    char buf[LOG_BUF_SIZE];\n\n    va_start(ap, fmt);\n    vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);\n    va_end(ap);\n\n    return __android_log_write(prio, tag, buf);\n}\n\nLIBLOG_ABI_PUBLIC int __android_log_buf_print(int bufID, int prio,\n                                              const char *tag,\n                                              const char *fmt, ...)\n{\n    va_list ap;\n    char buf[LOG_BUF_SIZE];\n\n    va_start(ap, fmt);\n    vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);\n    va_end(ap);\n\n    return __android_log_buf_write(bufID, prio, tag, buf);\n}\n\nLIBLOG_ABI_PUBLIC void __android_log_assert(const char *cond, const char *tag,\n                                            const char *fmt, ...)\n{\n    char buf[LOG_BUF_SIZE];\n\n    if (fmt) {\n        va_list ap;\n        va_start(ap, fmt);\n        vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);\n        va_end(ap);\n    } else {\n        /* Msg not provided, log condition.  N.B. Do not use cond directly as\n         * format string as it could contain spurious '%' syntax (e.g.\n         * \"%d\" in \"blocks%devs == 0\").\n         */\n        if (cond)\n            snprintf(buf, LOG_BUF_SIZE, \"Assertion failed: %s\", cond);\n        else\n            strcpy(buf, \"Unspecified assertion failed\");\n    }\n\n    __android_log_write(ANDROID_LOG_FATAL, tag, buf);\n    abort(); /* abort so we have a chance to debug the situation */\n    /* NOTREACHED */\n}\n\nLIBLOG_ABI_PUBLIC int __android_log_bwrite(int32_t tag,\n                                           const void *payload, size_t len)\n{\n    struct iovec vec[2];\n\n    vec[0].iov_base = &tag;\n    vec[0].iov_len = sizeof(tag);\n    vec[1].iov_base = (void*)payload;\n    vec[1].iov_len = len;\n\n    return write_to_log(LOG_ID_EVENTS, vec, 2);\n}\n\nLIBLOG_ABI_PUBLIC int __android_log_security_bwrite(int32_t tag,\n                                                    const void *payload,\n                                                    size_t len)\n{\n    struct iovec vec[2];\n\n    vec[0].iov_base = &tag;\n    vec[0].iov_len = sizeof(tag);\n    vec[1].iov_base = (void*)payload;\n    vec[1].iov_len = len;\n\n    return write_to_log(LOG_ID_SECURITY, vec, 2);\n}\n\n/*\n * Like __android_log_bwrite, but takes the type as well.  Doesn't work\n * for the general case where we're generating lists of stuff, but very\n * handy if we just want to dump an integer into the log.\n */\nLIBLOG_ABI_PUBLIC int __android_log_btwrite(int32_t tag, char type,\n                                            const void *payload, size_t len)\n{\n    struct iovec vec[3];\n\n    vec[0].iov_base = &tag;\n    vec[0].iov_len = sizeof(tag);\n    vec[1].iov_base = &type;\n    vec[1].iov_len = sizeof(type);\n    vec[2].iov_base = (void*)payload;\n    vec[2].iov_len = len;\n\n    return write_to_log(LOG_ID_EVENTS, vec, 3);\n}\n\n/*\n * Like __android_log_bwrite, but used for writing strings to the\n * event log.\n */\nLIBLOG_ABI_PUBLIC int __android_log_bswrite(int32_t tag, const char *payload)\n{\n    struct iovec vec[4];\n    char type = EVENT_TYPE_STRING;\n    uint32_t len = strlen(payload);\n\n    vec[0].iov_base = &tag;\n    vec[0].iov_len = sizeof(tag);\n    vec[1].iov_base = &type;\n    vec[1].iov_len = sizeof(type);\n    vec[2].iov_base = &len;\n    vec[2].iov_len = sizeof(len);\n    vec[3].iov_base = (void*)payload;\n    vec[3].iov_len = len;\n\n    return write_to_log(LOG_ID_EVENTS, vec, 4);\n}\n\n/*\n * Like __android_log_security_bwrite, but used for writing strings to the\n * security log.\n */\nLIBLOG_ABI_PUBLIC int __android_log_security_bswrite(int32_t tag,\n                                                     const char *payload)\n{\n    struct iovec vec[4];\n    char type = EVENT_TYPE_STRING;\n    uint32_t len = strlen(payload);\n\n    vec[0].iov_base = &tag;\n    vec[0].iov_len = sizeof(tag);\n    vec[1].iov_base = &type;\n    vec[1].iov_len = sizeof(type);\n    vec[2].iov_base = &len;\n    vec[2].iov_len = sizeof(len);\n    vec[3].iov_base = (void*)payload;\n    vec[3].iov_len = len;\n\n    return write_to_log(LOG_ID_SECURITY, vec, 4);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/logprint.c",
    "content": "/*\n**\n** Copyright 2006-2014, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\");\n** you may not use this file except in compliance with the License.\n** You may obtain a copy of the License at\n**\n**     http://www.apache.org/licenses/LICENSE-2.0\n**\n** Unless required by applicable law or agreed to in writing, software\n** distributed under the License is distributed on an \"AS IS\" BASIS,\n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n** See the License for the specific language governing permissions and\n** limitations under the License.\n*/\n\n#define _GNU_SOURCE /* for asprintf */\n\n#include <arpa/inet.h>\n#include <assert.h>\n#include <ctype.h>\n#include <errno.h>\n#include <stdbool.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <inttypes.h>\n#include <sys/param.h>\n\n#include <cutils/list.h>\n#include <log/logd.h>\n#include <log/logprint.h>\n#include <private/android_filesystem_config.h>\n\n#include \"log_portability.h\"\n\n#define MS_PER_NSEC 1000000\n#define US_PER_NSEC 1000\n\ntypedef struct FilterInfo_t {\n    char *mTag;\n    android_LogPriority mPri;\n    struct FilterInfo_t *p_next;\n} FilterInfo;\n\nstruct AndroidLogFormat_t {\n    android_LogPriority global_pri;\n    FilterInfo *filters;\n    AndroidLogPrintFormat format;\n    bool colored_output;\n    bool usec_time_output;\n    bool printable_output;\n    bool year_output;\n    bool zone_output;\n    bool epoch_output;\n    bool monotonic_output;\n    bool uid_output;\n};\n\n/*\n *  gnome-terminal color tags\n *    See http://misc.flogisoft.com/bash/tip_colors_and_formatting\n *    for ideas on how to set the forground color of the text for xterm.\n *    The color manipulation character stream is defined as:\n *      ESC [ 3 8 ; 5 ; <color#> m\n */\n#define ANDROID_COLOR_BLUE     75\n#define ANDROID_COLOR_DEFAULT 231\n#define ANDROID_COLOR_GREEN    40\n#define ANDROID_COLOR_ORANGE  166\n#define ANDROID_COLOR_RED     196\n#define ANDROID_COLOR_YELLOW  226\n\nstatic FilterInfo * filterinfo_new(const char * tag, android_LogPriority pri)\n{\n    FilterInfo *p_ret;\n\n    p_ret = (FilterInfo *)calloc(1, sizeof(FilterInfo));\n    p_ret->mTag = strdup(tag);\n    p_ret->mPri = pri;\n\n    return p_ret;\n}\n\n/* balance to above, filterinfo_free left unimplemented */\n\n/*\n * Note: also accepts 0-9 priorities\n * returns ANDROID_LOG_UNKNOWN if the character is unrecognized\n */\nstatic android_LogPriority filterCharToPri (char c)\n{\n    android_LogPriority pri;\n\n    c = tolower(c);\n\n    if (c >= '0' && c <= '9') {\n        if (c >= ('0'+ANDROID_LOG_SILENT)) {\n            pri = ANDROID_LOG_VERBOSE;\n        } else {\n            pri = (android_LogPriority)(c - '0');\n        }\n    } else if (c == 'v') {\n        pri = ANDROID_LOG_VERBOSE;\n    } else if (c == 'd') {\n        pri = ANDROID_LOG_DEBUG;\n    } else if (c == 'i') {\n        pri = ANDROID_LOG_INFO;\n    } else if (c == 'w') {\n        pri = ANDROID_LOG_WARN;\n    } else if (c == 'e') {\n        pri = ANDROID_LOG_ERROR;\n    } else if (c == 'f') {\n        pri = ANDROID_LOG_FATAL;\n    } else if (c == 's') {\n        pri = ANDROID_LOG_SILENT;\n    } else if (c == '*') {\n        pri = ANDROID_LOG_DEFAULT;\n    } else {\n        pri = ANDROID_LOG_UNKNOWN;\n    }\n\n    return pri;\n}\n\nstatic char filterPriToChar (android_LogPriority pri)\n{\n    switch (pri) {\n        case ANDROID_LOG_VERBOSE:       return 'V';\n        case ANDROID_LOG_DEBUG:         return 'D';\n        case ANDROID_LOG_INFO:          return 'I';\n        case ANDROID_LOG_WARN:          return 'W';\n        case ANDROID_LOG_ERROR:         return 'E';\n        case ANDROID_LOG_FATAL:         return 'F';\n        case ANDROID_LOG_SILENT:        return 'S';\n\n        case ANDROID_LOG_DEFAULT:\n        case ANDROID_LOG_UNKNOWN:\n        default:                        return '?';\n    }\n}\n\nstatic int colorFromPri (android_LogPriority pri)\n{\n    switch (pri) {\n        case ANDROID_LOG_VERBOSE:       return ANDROID_COLOR_DEFAULT;\n        case ANDROID_LOG_DEBUG:         return ANDROID_COLOR_BLUE;\n        case ANDROID_LOG_INFO:          return ANDROID_COLOR_GREEN;\n        case ANDROID_LOG_WARN:          return ANDROID_COLOR_ORANGE;\n        case ANDROID_LOG_ERROR:         return ANDROID_COLOR_RED;\n        case ANDROID_LOG_FATAL:         return ANDROID_COLOR_RED;\n        case ANDROID_LOG_SILENT:        return ANDROID_COLOR_DEFAULT;\n\n        case ANDROID_LOG_DEFAULT:\n        case ANDROID_LOG_UNKNOWN:\n        default:                        return ANDROID_COLOR_DEFAULT;\n    }\n}\n\nstatic android_LogPriority filterPriForTag(\n        AndroidLogFormat *p_format, const char *tag)\n{\n    FilterInfo *p_curFilter;\n\n    for (p_curFilter = p_format->filters\n            ; p_curFilter != NULL\n            ; p_curFilter = p_curFilter->p_next\n    ) {\n        if (0 == strcmp(tag, p_curFilter->mTag)) {\n            if (p_curFilter->mPri == ANDROID_LOG_DEFAULT) {\n                return p_format->global_pri;\n            } else {\n                return p_curFilter->mPri;\n            }\n        }\n    }\n\n    return p_format->global_pri;\n}\n\n/**\n * returns 1 if this log line should be printed based on its priority\n * and tag, and 0 if it should not\n */\nLIBLOG_ABI_PUBLIC int android_log_shouldPrintLine (\n        AndroidLogFormat *p_format,\n        const char *tag,\n        android_LogPriority pri)\n{\n    return pri >= filterPriForTag(p_format, tag);\n}\n\nLIBLOG_ABI_PUBLIC AndroidLogFormat *android_log_format_new()\n{\n    AndroidLogFormat *p_ret;\n\n    p_ret = calloc(1, sizeof(AndroidLogFormat));\n\n    p_ret->global_pri = ANDROID_LOG_VERBOSE;\n    p_ret->format = FORMAT_BRIEF;\n    p_ret->colored_output = false;\n    p_ret->usec_time_output = false;\n    p_ret->printable_output = false;\n    p_ret->year_output = false;\n    p_ret->zone_output = false;\n    p_ret->epoch_output = false;\n    p_ret->monotonic_output = android_log_clockid() == CLOCK_MONOTONIC;\n    p_ret->uid_output = false;\n\n    return p_ret;\n}\n\nstatic list_declare(convertHead);\n\nLIBLOG_ABI_PUBLIC void android_log_format_free(AndroidLogFormat *p_format)\n{\n    FilterInfo *p_info, *p_info_old;\n\n    p_info = p_format->filters;\n\n    while (p_info != NULL) {\n        p_info_old = p_info;\n        p_info = p_info->p_next;\n\n        free(p_info_old);\n    }\n\n    free(p_format);\n\n    /* Free conversion resource, can always be reconstructed */\n    while (!list_empty(&convertHead)) {\n        struct listnode *node = list_head(&convertHead);\n        list_remove(node);\n        free(node);\n    }\n}\n\nLIBLOG_ABI_PUBLIC int android_log_setPrintFormat(\n        AndroidLogFormat *p_format,\n        AndroidLogPrintFormat format)\n{\n    switch (format) {\n    case FORMAT_MODIFIER_COLOR:\n        p_format->colored_output = true;\n        return 0;\n    case FORMAT_MODIFIER_TIME_USEC:\n        p_format->usec_time_output = true;\n        return 0;\n    case FORMAT_MODIFIER_PRINTABLE:\n        p_format->printable_output = true;\n        return 0;\n    case FORMAT_MODIFIER_YEAR:\n        p_format->year_output = true;\n        return 0;\n    case FORMAT_MODIFIER_ZONE:\n        p_format->zone_output = !p_format->zone_output;\n        return 0;\n    case FORMAT_MODIFIER_EPOCH:\n        p_format->epoch_output = true;\n        return 0;\n    case FORMAT_MODIFIER_MONOTONIC:\n        p_format->monotonic_output = true;\n        return 0;\n    case FORMAT_MODIFIER_UID:\n        p_format->uid_output = true;\n        return 0;\n    default:\n        break;\n    }\n    p_format->format = format;\n    return 1;\n}\n\nstatic const char tz[] = \"TZ\";\nstatic const char utc[] = \"UTC\";\n\n/**\n * Returns FORMAT_OFF on invalid string\n */\nLIBLOG_ABI_PUBLIC AndroidLogPrintFormat android_log_formatFromString(\n        const char * formatString)\n{\n    static AndroidLogPrintFormat format;\n\n    if (strcmp(formatString, \"brief\") == 0) format = FORMAT_BRIEF;\n    else if (strcmp(formatString, \"process\") == 0) format = FORMAT_PROCESS;\n    else if (strcmp(formatString, \"tag\") == 0) format = FORMAT_TAG;\n    else if (strcmp(formatString, \"thread\") == 0) format = FORMAT_THREAD;\n    else if (strcmp(formatString, \"raw\") == 0) format = FORMAT_RAW;\n    else if (strcmp(formatString, \"time\") == 0) format = FORMAT_TIME;\n    else if (strcmp(formatString, \"threadtime\") == 0) format = FORMAT_THREADTIME;\n    else if (strcmp(formatString, \"long\") == 0) format = FORMAT_LONG;\n    else if (strcmp(formatString, \"color\") == 0) format = FORMAT_MODIFIER_COLOR;\n    else if (strcmp(formatString, \"usec\") == 0) format = FORMAT_MODIFIER_TIME_USEC;\n    else if (strcmp(formatString, \"printable\") == 0) format = FORMAT_MODIFIER_PRINTABLE;\n    else if (strcmp(formatString, \"year\") == 0) format = FORMAT_MODIFIER_YEAR;\n    else if (strcmp(formatString, \"zone\") == 0) format = FORMAT_MODIFIER_ZONE;\n    else if (strcmp(formatString, \"epoch\") == 0) format = FORMAT_MODIFIER_EPOCH;\n    else if (strcmp(formatString, \"monotonic\") == 0) format = FORMAT_MODIFIER_MONOTONIC;\n    else if (strcmp(formatString, \"uid\") == 0) format = FORMAT_MODIFIER_UID;\n    else {\n        extern char *tzname[2];\n        static const char gmt[] = \"GMT\";\n        char *cp = getenv(tz);\n        if (cp) {\n            cp = strdup(cp);\n        }\n        setenv(tz, formatString, 1);\n        /*\n         * Run tzset here to determine if the timezone is legitimate. If the\n         * zone is GMT, check if that is what was asked for, if not then\n         * did not match any on the system; report an error to caller.\n         */\n        tzset();\n        if (!tzname[0]\n                || ((!strcmp(tzname[0], utc)\n                        || !strcmp(tzname[0], gmt)) /* error? */\n                    && strcasecmp(formatString, utc)\n                    && strcasecmp(formatString, gmt))) { /* ok */\n            if (cp) {\n                setenv(tz, cp, 1);\n            } else {\n                unsetenv(tz);\n            }\n            tzset();\n            format = FORMAT_OFF;\n        } else {\n            format = FORMAT_MODIFIER_ZONE;\n        }\n        free(cp);\n    }\n\n    return format;\n}\n\n/**\n * filterExpression: a single filter expression\n * eg \"AT:d\"\n *\n * returns 0 on success and -1 on invalid expression\n *\n * Assumes single threaded execution\n */\n\nLIBLOG_ABI_PUBLIC int android_log_addFilterRule(\n        AndroidLogFormat *p_format,\n        const char *filterExpression)\n{\n    size_t tagNameLength;\n    android_LogPriority pri = ANDROID_LOG_DEFAULT;\n\n    tagNameLength = strcspn(filterExpression, \":\");\n\n    if (tagNameLength == 0) {\n        goto error;\n    }\n\n    if(filterExpression[tagNameLength] == ':') {\n        pri = filterCharToPri(filterExpression[tagNameLength+1]);\n\n        if (pri == ANDROID_LOG_UNKNOWN) {\n            goto error;\n        }\n    }\n\n    if(0 == strncmp(\"*\", filterExpression, tagNameLength)) {\n        /*\n         * This filter expression refers to the global filter\n         * The default level for this is DEBUG if the priority\n         * is unspecified\n         */\n        if (pri == ANDROID_LOG_DEFAULT) {\n            pri = ANDROID_LOG_DEBUG;\n        }\n\n        p_format->global_pri = pri;\n    } else {\n        /*\n         * for filter expressions that don't refer to the global\n         * filter, the default is verbose if the priority is unspecified\n         */\n        if (pri == ANDROID_LOG_DEFAULT) {\n            pri = ANDROID_LOG_VERBOSE;\n        }\n\n        char *tagName;\n\n/*\n * Presently HAVE_STRNDUP is never defined, so the second case is always taken\n * Darwin doesn't have strnup, everything else does\n */\n#ifdef HAVE_STRNDUP\n        tagName = strndup(filterExpression, tagNameLength);\n#else\n        /* a few extra bytes copied... */\n        tagName = strdup(filterExpression);\n        tagName[tagNameLength] = '\\0';\n#endif /*HAVE_STRNDUP*/\n\n        FilterInfo *p_fi = filterinfo_new(tagName, pri);\n        free(tagName);\n\n        p_fi->p_next = p_format->filters;\n        p_format->filters = p_fi;\n    }\n\n    return 0;\nerror:\n    return -1;\n}\n\n\n/**\n * filterString: a comma/whitespace-separated set of filter expressions\n *\n * eg \"AT:d *:i\"\n *\n * returns 0 on success and -1 on invalid expression\n *\n * Assumes single threaded execution\n *\n */\n\nLIBLOG_ABI_PUBLIC int android_log_addFilterString(\n        AndroidLogFormat *p_format,\n        const char *filterString)\n{\n    char *filterStringCopy = strdup (filterString);\n    char *p_cur = filterStringCopy;\n    char *p_ret;\n    int err;\n\n    /* Yes, I'm using strsep */\n    while (NULL != (p_ret = strsep(&p_cur, \" \\t,\"))) {\n        /* ignore whitespace-only entries */\n        if(p_ret[0] != '\\0') {\n            err = android_log_addFilterRule(p_format, p_ret);\n\n            if (err < 0) {\n                goto error;\n            }\n        }\n    }\n\n    free (filterStringCopy);\n    return 0;\nerror:\n    free (filterStringCopy);\n    return -1;\n}\n\n/**\n * Splits a wire-format buffer into an AndroidLogEntry\n * entry allocated by caller. Pointers will point directly into buf\n *\n * Returns 0 on success and -1 on invalid wire format (entry will be\n * in unspecified state)\n */\nLIBLOG_ABI_PUBLIC int android_log_processLogBuffer(\n        struct logger_entry *buf,\n        AndroidLogEntry *entry)\n{\n    entry->tv_sec = buf->sec;\n    entry->tv_nsec = buf->nsec;\n    entry->uid = -1;\n    entry->pid = buf->pid;\n    entry->tid = buf->tid;\n\n    /*\n     * format: <priority:1><tag:N>\\0<message:N>\\0\n     *\n     * tag str\n     *   starts at buf->msg+1\n     * msg\n     *   starts at buf->msg+1+len(tag)+1\n     *\n     * The message may have been truncated by the kernel log driver.\n     * When that happens, we must null-terminate the message ourselves.\n     */\n    if (buf->len < 3) {\n        /*\n         * An well-formed entry must consist of at least a priority\n         * and two null characters\n         */\n        fprintf(stderr, \"+++ LOG: entry too small\\n\");\n        return -1;\n    }\n\n    int msgStart = -1;\n    int msgEnd = -1;\n\n    int i;\n    char *msg = buf->msg;\n    struct logger_entry_v2 *buf2 = (struct logger_entry_v2 *)buf;\n    if (buf2->hdr_size) {\n        msg = ((char *)buf2) + buf2->hdr_size;\n        if (buf2->hdr_size >= sizeof(struct logger_entry_v4)) {\n            entry->uid = ((struct logger_entry_v4 *)buf)->uid;\n        }\n    }\n    for (i = 1; i < buf->len; i++) {\n        if (msg[i] == '\\0') {\n            if (msgStart == -1) {\n                msgStart = i + 1;\n            } else {\n                msgEnd = i;\n                break;\n            }\n        }\n    }\n\n    if (msgStart == -1) {\n        /* +++ LOG: malformed log message, DYB */\n        for (i = 1; i < buf->len; i++) {\n            /* odd characters in tag? */\n            if ((msg[i] <= ' ') || (msg[i] == ':') || (msg[i] >= 0x7f)) {\n                msg[i] = '\\0';\n                msgStart = i + 1;\n                break;\n            }\n        }\n        if (msgStart == -1) {\n            msgStart = buf->len - 1; /* All tag, no message, print truncates */\n        }\n    }\n    if (msgEnd == -1) {\n        /* incoming message not null-terminated; force it */\n        msgEnd = buf->len - 1; /* may result in msgEnd < msgStart */\n        msg[msgEnd] = '\\0';\n    }\n\n    entry->priority = msg[0];\n    entry->tag = msg + 1;\n    entry->message = msg + msgStart;\n    entry->messageLen = (msgEnd < msgStart) ? 0 : (msgEnd - msgStart);\n\n    return 0;\n}\n\n/*\n * Extract a 4-byte value from a byte stream.\n */\nstatic inline uint32_t get4LE(const uint8_t* src)\n{\n    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);\n}\n\n/*\n * Extract an 8-byte value from a byte stream.\n */\nstatic inline uint64_t get8LE(const uint8_t* src)\n{\n    uint32_t low, high;\n\n    low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);\n    high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);\n    return ((uint64_t) high << 32) | (uint64_t) low;\n}\n\n\n/*\n * Recursively convert binary log data to printable form.\n *\n * This needs to be recursive because you can have lists of lists.\n *\n * If we run out of room, we stop processing immediately.  It's important\n * for us to check for space on every output element to avoid producing\n * garbled output.\n *\n * Returns 0 on success, 1 on buffer full, -1 on failure.\n */\nstatic int android_log_printBinaryEvent(const unsigned char** pEventData,\n    size_t* pEventDataLen, char** pOutBuf, size_t* pOutBufLen)\n{\n    const unsigned char* eventData = *pEventData;\n    size_t eventDataLen = *pEventDataLen;\n    char* outBuf = *pOutBuf;\n    size_t outBufLen = *pOutBufLen;\n    unsigned char type;\n    size_t outCount;\n    int result = 0;\n\n    if (eventDataLen < 1)\n        return -1;\n    type = *eventData++;\n    eventDataLen--;\n\n    switch (type) {\n    case EVENT_TYPE_INT:\n        /* 32-bit signed int */\n        {\n            int ival;\n\n            if (eventDataLen < 4)\n                return -1;\n            ival = get4LE(eventData);\n            eventData += 4;\n            eventDataLen -= 4;\n\n            outCount = snprintf(outBuf, outBufLen, \"%d\", ival);\n            if (outCount < outBufLen) {\n                outBuf += outCount;\n                outBufLen -= outCount;\n            } else {\n                /* halt output */\n                goto no_room;\n            }\n        }\n        break;\n    case EVENT_TYPE_LONG:\n        /* 64-bit signed long */\n        {\n            uint64_t lval;\n\n            if (eventDataLen < 8)\n                return -1;\n            lval = get8LE(eventData);\n            eventData += 8;\n            eventDataLen -= 8;\n\n            outCount = snprintf(outBuf, outBufLen, \"%\" PRId64, lval);\n            if (outCount < outBufLen) {\n                outBuf += outCount;\n                outBufLen -= outCount;\n            } else {\n                /* halt output */\n                goto no_room;\n            }\n        }\n        break;\n    case EVENT_TYPE_FLOAT:\n        /* float */\n        {\n            uint32_t ival;\n            float fval;\n\n            if (eventDataLen < 4)\n                return -1;\n            ival = get4LE(eventData);\n            fval = *(float*)&ival;\n            eventData += 4;\n            eventDataLen -= 4;\n\n            outCount = snprintf(outBuf, outBufLen, \"%f\", fval);\n            if (outCount < outBufLen) {\n                outBuf += outCount;\n                outBufLen -= outCount;\n            } else {\n                /* halt output */\n                goto no_room;\n            }\n        }\n        break;\n    case EVENT_TYPE_STRING:\n        /* UTF-8 chars, not NULL-terminated */\n        {\n            unsigned int strLen;\n\n            if (eventDataLen < 4)\n                return -1;\n            strLen = get4LE(eventData);\n            eventData += 4;\n            eventDataLen -= 4;\n\n            if (eventDataLen < strLen)\n                return -1;\n\n            if (strLen < outBufLen) {\n                memcpy(outBuf, eventData, strLen);\n                outBuf += strLen;\n                outBufLen -= strLen;\n            } else if (outBufLen > 0) {\n                /* copy what we can */\n                memcpy(outBuf, eventData, outBufLen);\n                outBuf += outBufLen;\n                outBufLen -= outBufLen;\n                goto no_room;\n            }\n            eventData += strLen;\n            eventDataLen -= strLen;\n            break;\n        }\n    case EVENT_TYPE_LIST:\n        /* N items, all different types */\n        {\n            unsigned char count;\n            int i;\n\n            if (eventDataLen < 1)\n                return -1;\n\n            count = *eventData++;\n            eventDataLen--;\n\n            if (outBufLen > 0) {\n                *outBuf++ = '[';\n                outBufLen--;\n            } else {\n                goto no_room;\n            }\n\n            for (i = 0; i < count; i++) {\n                result = android_log_printBinaryEvent(&eventData, &eventDataLen,\n                        &outBuf, &outBufLen);\n                if (result != 0)\n                    goto bail;\n\n                if (i < count-1) {\n                    if (outBufLen > 0) {\n                        *outBuf++ = ',';\n                        outBufLen--;\n                    } else {\n                        goto no_room;\n                    }\n                }\n            }\n\n            if (outBufLen > 0) {\n                *outBuf++ = ']';\n                outBufLen--;\n            } else {\n                goto no_room;\n            }\n        }\n        break;\n    default:\n        fprintf(stderr, \"Unknown binary event type %d\\n\", type);\n        return -1;\n    }\n\nbail:\n    *pEventData = eventData;\n    *pEventDataLen = eventDataLen;\n    *pOutBuf = outBuf;\n    *pOutBufLen = outBufLen;\n    return result;\n\nno_room:\n    result = 1;\n    goto bail;\n}\n\n/**\n * Convert a binary log entry to ASCII form.\n *\n * For convenience we mimic the processLogBuffer API.  There is no\n * pre-defined output length for the binary data, since we're free to format\n * it however we choose, which means we can't really use a fixed-size buffer\n * here.\n */\nLIBLOG_ABI_PUBLIC int android_log_processBinaryLogBuffer(\n        struct logger_entry *buf,\n        AndroidLogEntry *entry,\n        const EventTagMap *map,\n        char *messageBuf, int messageBufLen)\n{\n    size_t inCount;\n    unsigned int tagIndex;\n    const unsigned char* eventData;\n\n    entry->tv_sec = buf->sec;\n    entry->tv_nsec = buf->nsec;\n    entry->priority = ANDROID_LOG_INFO;\n    entry->uid = -1;\n    entry->pid = buf->pid;\n    entry->tid = buf->tid;\n\n    /*\n     * Pull the tag out, fill in some additional details based on incoming\n     * buffer version (v3 adds lid, v4 adds uid).\n     */\n    eventData = (const unsigned char*) buf->msg;\n    struct logger_entry_v2 *buf2 = (struct logger_entry_v2 *)buf;\n    if (buf2->hdr_size) {\n        eventData = ((unsigned char *)buf2) + buf2->hdr_size;\n        if ((buf2->hdr_size >= sizeof(struct logger_entry_v3)) &&\n                (((struct logger_entry_v3 *)buf)->lid == LOG_ID_SECURITY)) {\n            entry->priority = ANDROID_LOG_WARN;\n        }\n        if (buf2->hdr_size >= sizeof(struct logger_entry_v4)) {\n            entry->uid = ((struct logger_entry_v4 *)buf)->uid;\n        }\n    }\n    inCount = buf->len;\n    if (inCount < 4)\n        return -1;\n    tagIndex = get4LE(eventData);\n    eventData += 4;\n    inCount -= 4;\n\n    if (map != NULL) {\n        entry->tag = android_lookupEventTag(map, tagIndex);\n    } else {\n        entry->tag = NULL;\n    }\n\n    /*\n     * If we don't have a map, or didn't find the tag number in the map,\n     * stuff a generated tag value into the start of the output buffer and\n     * shift the buffer pointers down.\n     */\n    if (entry->tag == NULL) {\n        int tagLen;\n\n        tagLen = snprintf(messageBuf, messageBufLen, \"[%d]\", tagIndex);\n        entry->tag = messageBuf;\n        messageBuf += tagLen+1;\n        messageBufLen -= tagLen+1;\n    }\n\n    /*\n     * Format the event log data into the buffer.\n     */\n    char* outBuf = messageBuf;\n    size_t outRemaining = messageBufLen-1;      /* leave one for nul byte */\n    int result;\n    result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf,\n                &outRemaining);\n    if (result < 0) {\n        fprintf(stderr, \"Binary log entry conversion failed\\n\");\n        return -1;\n    } else if (result == 1) {\n        if (outBuf > messageBuf) {\n            /* leave an indicator */\n            *(outBuf-1) = '!';\n        } else {\n            /* no room to output anything at all */\n            *outBuf++ = '!';\n            outRemaining--;\n        }\n        /* pretend we ate all the data */\n        inCount = 0;\n    }\n\n    /* eat the silly terminating '\\n' */\n    if (inCount == 1 && *eventData == '\\n') {\n        eventData++;\n        inCount--;\n    }\n\n    if (inCount != 0) {\n        fprintf(stderr,\n            \"Warning: leftover binary log data (%zu bytes)\\n\", inCount);\n    }\n\n    /*\n     * Terminate the buffer.  The NUL byte does not count as part of\n     * entry->messageLen.\n     */\n    *outBuf = '\\0';\n    entry->messageLen = outBuf - messageBuf;\n    assert(entry->messageLen == (messageBufLen-1) - outRemaining);\n\n    entry->message = messageBuf;\n\n    return 0;\n}\n\n/*\n * One utf8 character at a time\n *\n * Returns the length of the utf8 character in the buffer,\n * or -1 if illegal or truncated\n *\n * Open coded from libutils/Unicode.cpp, borrowed from utf8_length(),\n * can not remove from here because of library circular dependencies.\n * Expect one-day utf8_character_length with the same signature could\n * _also_ be part of libutils/Unicode.cpp if its usefullness needs to\n * propagate globally.\n */\nLIBLOG_WEAK ssize_t utf8_character_length(const char *src, size_t len)\n{\n    const char *cur = src;\n    const char first_char = *cur++;\n    static const uint32_t kUnicodeMaxCodepoint = 0x0010FFFF;\n    int32_t mask, to_ignore_mask;\n    size_t num_to_read;\n    uint32_t utf32;\n\n    if ((first_char & 0x80) == 0) { /* ASCII */\n        return first_char ? 1 : -1;\n    }\n\n    /*\n     * (UTF-8's character must not be like 10xxxxxx,\n     *  but 110xxxxx, 1110xxxx, ... or 1111110x)\n     */\n    if ((first_char & 0x40) == 0) {\n        return -1;\n    }\n\n    for (utf32 = 1, num_to_read = 1, mask = 0x40, to_ignore_mask = 0x80;\n         num_to_read < 5 && (first_char & mask);\n         num_to_read++, to_ignore_mask |= mask, mask >>= 1) {\n        if (num_to_read > len) {\n            return -1;\n        }\n        if ((*cur & 0xC0) != 0x80) { /* can not be 10xxxxxx? */\n            return -1;\n        }\n        utf32 = (utf32 << 6) + (*cur++ & 0b00111111);\n    }\n    /* \"first_char\" must be (110xxxxx - 11110xxx) */\n    if (num_to_read >= 5) {\n        return -1;\n    }\n    to_ignore_mask |= mask;\n    utf32 |= ((~to_ignore_mask) & first_char) << (6 * (num_to_read - 1));\n    if (utf32 > kUnicodeMaxCodepoint) {\n        return -1;\n    }\n    return num_to_read;\n}\n\n/*\n * Convert to printable from message to p buffer, return string length. If p is\n * NULL, do not copy, but still return the expected string length.\n */\nstatic size_t convertPrintable(char *p, const char *message, size_t messageLen)\n{\n    char *begin = p;\n    bool print = p != NULL;\n\n    while (messageLen) {\n        char buf[6];\n        ssize_t len = sizeof(buf) - 1;\n        if ((size_t)len > messageLen) {\n            len = messageLen;\n        }\n        len = utf8_character_length(message, len);\n\n        if (len < 0) {\n            snprintf(buf, sizeof(buf),\n                     ((messageLen > 1) && isdigit(message[1]))\n                         ? \"\\\\%03o\"\n                         : \"\\\\%o\",\n                     *message & 0377);\n            len = 1;\n        } else {\n            buf[0] = '\\0';\n            if (len == 1) {\n                if (*message == '\\a') {\n                    strcpy(buf, \"\\\\a\");\n                } else if (*message == '\\b') {\n                    strcpy(buf, \"\\\\b\");\n                } else if (*message == '\\t') {\n                    strcpy(buf, \"\\t\"); // Do not escape tabs\n                } else if (*message == '\\v') {\n                    strcpy(buf, \"\\\\v\");\n                } else if (*message == '\\f') {\n                    strcpy(buf, \"\\\\f\");\n                } else if (*message == '\\r') {\n                    strcpy(buf, \"\\\\r\");\n                } else if (*message == '\\\\') {\n                    strcpy(buf, \"\\\\\\\\\");\n                } else if ((*message < ' ') || (*message & 0x80)) {\n                    snprintf(buf, sizeof(buf), \"\\\\%o\", *message & 0377);\n                }\n            }\n            if (!buf[0]) {\n                strncpy(buf, message, len);\n                buf[len] = '\\0';\n            }\n        }\n        if (print) {\n            strcpy(p, buf);\n        }\n        p += strlen(buf);\n        message += len;\n        messageLen -= len;\n    }\n    return p - begin;\n}\n\nstatic char *readSeconds(char *e, struct timespec *t)\n{\n    unsigned long multiplier;\n    char *p;\n    t->tv_sec = strtoul(e, &p, 10);\n    if (*p != '.') {\n        return NULL;\n    }\n    t->tv_nsec = 0;\n    multiplier = NS_PER_SEC;\n    while (isdigit(*++p) && (multiplier /= 10)) {\n        t->tv_nsec += (*p - '0') * multiplier;\n    }\n    return p;\n}\n\nstatic struct timespec *sumTimespec(struct timespec *left,\n                                    struct timespec *right)\n{\n    left->tv_nsec += right->tv_nsec;\n    left->tv_sec += right->tv_sec;\n    if (left->tv_nsec >= (long)NS_PER_SEC) {\n        left->tv_nsec -= NS_PER_SEC;\n        left->tv_sec += 1;\n    }\n    return left;\n}\n\nstatic struct timespec *subTimespec(struct timespec *result,\n                                    struct timespec *left,\n                                    struct timespec *right)\n{\n    result->tv_nsec = left->tv_nsec - right->tv_nsec;\n    result->tv_sec = left->tv_sec - right->tv_sec;\n    if (result->tv_nsec < 0) {\n        result->tv_nsec += NS_PER_SEC;\n        result->tv_sec -= 1;\n    }\n    return result;\n}\n\nstatic long long nsecTimespec(struct timespec *now)\n{\n    return (long long)now->tv_sec * NS_PER_SEC + now->tv_nsec;\n}\n\nstatic void convertMonotonic(struct timespec *result,\n                             const AndroidLogEntry *entry)\n{\n    struct listnode *node;\n    struct conversionList {\n        struct listnode node; /* first */\n        struct timespec time;\n        struct timespec convert;\n    } *list, *next;\n    struct timespec time, convert;\n\n    /* If we do not have a conversion list, build one up */\n    if (list_empty(&convertHead)) {\n        bool suspended_pending = false;\n        struct timespec suspended_monotonic = { 0, 0 };\n        struct timespec suspended_diff = { 0, 0 };\n\n        /*\n         * Read dmesg for _some_ synchronization markers and insert\n         * Anything in the Android Logger before the dmesg logging span will\n         * be highly suspect regarding the monotonic time calculations.\n         */\n        FILE *p = popen(\"/system/bin/dmesg\", \"re\");\n        if (p) {\n            char *line = NULL;\n            size_t len = 0;\n            while (getline(&line, &len, p) > 0) {\n                static const char suspend[] = \"PM: suspend entry \";\n                static const char resume[] = \"PM: suspend exit \";\n                static const char healthd[] = \"healthd\";\n                static const char battery[] = \": battery \";\n                static const char suspended[] = \"Suspended for \";\n                struct timespec monotonic;\n                struct tm tm;\n                char *cp, *e = line;\n                bool add_entry = true;\n\n                if (*e == '<') {\n                    while (*e && (*e != '>')) {\n                        ++e;\n                    }\n                    if (*e != '>') {\n                        continue;\n                    }\n                }\n                if (*e != '[') {\n                    continue;\n                }\n                while (*++e == ' ') {\n                    ;\n                }\n                e = readSeconds(e, &monotonic);\n                if (!e || (*e != ']')) {\n                    continue;\n                }\n\n                if ((e = strstr(e, suspend))) {\n                    e += sizeof(suspend) - 1;\n                } else if ((e = strstr(line, resume))) {\n                    e += sizeof(resume) - 1;\n                } else if (((e = strstr(line, healthd)))\n                        && ((e = strstr(e + sizeof(healthd) - 1, battery)))) {\n                    /* NB: healthd is roughly 150us late, worth the price to\n                     * deal with ntp-induced or hardware clock drift. */\n                    e += sizeof(battery) - 1;\n                } else if ((e = strstr(line, suspended))) {\n                    e += sizeof(suspended) - 1;\n                    e = readSeconds(e, &time);\n                    if (!e) {\n                        continue;\n                    }\n                    add_entry = false;\n                    suspended_pending = true;\n                    suspended_monotonic = monotonic;\n                    suspended_diff = time;\n                } else {\n                    continue;\n                }\n                if (add_entry) {\n                    /* look for \"????-??-?? ??:??:??.????????? UTC\" */\n                    cp = strstr(e, \" UTC\");\n                    if (!cp || ((cp - e) < 29) || (cp[-10] != '.')) {\n                        continue;\n                    }\n                    e = cp - 29;\n                    cp = readSeconds(cp - 10, &time);\n                    if (!cp) {\n                        continue;\n                    }\n                    cp = strptime(e, \"%Y-%m-%d %H:%M:%S.\", &tm);\n                    if (!cp) {\n                        continue;\n                    }\n                    cp = getenv(tz);\n                    if (cp) {\n                        cp = strdup(cp);\n                    }\n                    setenv(tz, utc, 1);\n                    time.tv_sec = mktime(&tm);\n                    if (cp) {\n                        setenv(tz, cp, 1);\n                        free(cp);\n                    } else {\n                        unsetenv(tz);\n                    }\n                    list = calloc(1, sizeof(struct conversionList));\n                    list_init(&list->node);\n                    list->time = time;\n                    subTimespec(&list->convert, &time, &monotonic);\n                    list_add_tail(&convertHead, &list->node);\n                }\n                if (suspended_pending && !list_empty(&convertHead)) {\n                    list = node_to_item(list_tail(&convertHead),\n                                        struct conversionList, node);\n                    if (subTimespec(&time,\n                                    subTimespec(&time,\n                                                &list->time,\n                                                &list->convert),\n                                    &suspended_monotonic)->tv_sec > 0) {\n                        /* resume, what is convert factor before? */\n                        subTimespec(&convert, &list->convert, &suspended_diff);\n                    } else {\n                        /* suspend */\n                        convert = list->convert;\n                    }\n                    time = suspended_monotonic;\n                    sumTimespec(&time, &convert);\n                    /* breakpoint just before sleep */\n                    list = calloc(1, sizeof(struct conversionList));\n                    list_init(&list->node);\n                    list->time = time;\n                    list->convert = convert;\n                    list_add_tail(&convertHead, &list->node);\n                    /* breakpoint just after sleep */\n                    list = calloc(1, sizeof(struct conversionList));\n                    list_init(&list->node);\n                    list->time = time;\n                    sumTimespec(&list->time, &suspended_diff);\n                    list->convert = convert;\n                    sumTimespec(&list->convert, &suspended_diff);\n                    list_add_tail(&convertHead, &list->node);\n                    suspended_pending = false;\n                }\n            }\n            pclose(p);\n        }\n        /* last entry is our current time conversion */\n        list = calloc(1, sizeof(struct conversionList));\n        list_init(&list->node);\n        clock_gettime(CLOCK_REALTIME, &list->time);\n        clock_gettime(CLOCK_MONOTONIC, &convert);\n        clock_gettime(CLOCK_MONOTONIC, &time);\n        /* Correct for instant clock_gettime latency (syscall or ~30ns) */\n        subTimespec(&time, &convert, subTimespec(&time, &time, &convert));\n        /* Calculate conversion factor */\n        subTimespec(&list->convert, &list->time, &time);\n        list_add_tail(&convertHead, &list->node);\n        if (suspended_pending) {\n            /* manufacture a suspend @ point before */\n            subTimespec(&convert, &list->convert, &suspended_diff);\n            time = suspended_monotonic;\n            sumTimespec(&time, &convert);\n            /* breakpoint just after sleep */\n            list = calloc(1, sizeof(struct conversionList));\n            list_init(&list->node);\n            list->time = time;\n            sumTimespec(&list->time, &suspended_diff);\n            list->convert = convert;\n            sumTimespec(&list->convert, &suspended_diff);\n            list_add_head(&convertHead, &list->node);\n            /* breakpoint just before sleep */\n            list = calloc(1, sizeof(struct conversionList));\n            list_init(&list->node);\n            list->time = time;\n            list->convert = convert;\n            list_add_head(&convertHead, &list->node);\n        }\n    }\n\n    /* Find the breakpoint in the conversion list */\n    list = node_to_item(list_head(&convertHead), struct conversionList, node);\n    next = NULL;\n    list_for_each(node, &convertHead) {\n        next = node_to_item(node, struct conversionList, node);\n        if (entry->tv_sec < next->time.tv_sec) {\n            break;\n        } else if (entry->tv_sec == next->time.tv_sec) {\n            if (entry->tv_nsec < next->time.tv_nsec) {\n                break;\n            }\n        }\n        list = next;\n    }\n\n    /* blend time from one breakpoint to the next */\n    convert = list->convert;\n    if (next) {\n        unsigned long long total, run;\n\n        total = nsecTimespec(subTimespec(&time, &next->time, &list->time));\n        time.tv_sec = entry->tv_sec;\n        time.tv_nsec = entry->tv_nsec;\n        run = nsecTimespec(subTimespec(&time, &time, &list->time));\n        if (run < total) {\n            long long crun;\n\n            float f = nsecTimespec(subTimespec(&time, &next->convert, &convert));\n            f *= run;\n            f /= total;\n            crun = f;\n            convert.tv_sec += crun / (long long)NS_PER_SEC;\n            if (crun < 0) {\n                convert.tv_nsec -= (-crun) % NS_PER_SEC;\n                if (convert.tv_nsec < 0) {\n                    convert.tv_nsec += NS_PER_SEC;\n                    convert.tv_sec -= 1;\n                }\n            } else {\n                convert.tv_nsec += crun % NS_PER_SEC;\n                if (convert.tv_nsec >= (long)NS_PER_SEC) {\n                    convert.tv_nsec -= NS_PER_SEC;\n                    convert.tv_sec += 1;\n                }\n            }\n        }\n    }\n\n    /* Apply the correction factor */\n    result->tv_sec = entry->tv_sec;\n    result->tv_nsec = entry->tv_nsec;\n    subTimespec(result, result, &convert);\n}\n\n/**\n * Formats a log message into a buffer\n *\n * Uses defaultBuffer if it can, otherwise malloc()'s a new buffer\n * If return value != defaultBuffer, caller must call free()\n * Returns NULL on malloc error\n */\n\nLIBLOG_ABI_PUBLIC char *android_log_formatLogLine (\n        AndroidLogFormat *p_format,\n        char *defaultBuffer,\n        size_t defaultBufferSize,\n        const AndroidLogEntry *entry,\n        size_t *p_outLength)\n{\n#if !defined(_WIN32)\n    struct tm tmBuf;\n#endif\n    struct tm* ptm;\n    char timeBuf[64]; /* good margin, 23+nul for msec, 26+nul for usec */\n    char prefixBuf[128], suffixBuf[128];\n    char priChar;\n    int prefixSuffixIsHeaderFooter = 0;\n    char *ret;\n    time_t now;\n    unsigned long nsec;\n\n    priChar = filterPriToChar(entry->priority);\n    size_t prefixLen = 0, suffixLen = 0;\n    size_t len;\n\n    /*\n     * Get the current date/time in pretty form\n     *\n     * It's often useful when examining a log with \"less\" to jump to\n     * a specific point in the file by searching for the date/time stamp.\n     * For this reason it's very annoying to have regexp meta characters\n     * in the time stamp.  Don't use forward slashes, parenthesis,\n     * brackets, asterisks, or other special chars here.\n     *\n     * The caller may have affected the timezone environment, this is\n     * expected to be sensitive to that.\n     */\n    now = entry->tv_sec;\n    nsec = entry->tv_nsec;\n    if (p_format->monotonic_output) {\n        // prevent convertMonotonic from being called if logd is monotonic\n        if (android_log_clockid() != CLOCK_MONOTONIC) {\n            struct timespec time;\n            convertMonotonic(&time, entry);\n            now = time.tv_sec;\n            nsec = time.tv_nsec;\n        }\n    }\n    if (now < 0) {\n        nsec = NS_PER_SEC - nsec;\n    }\n    if (p_format->epoch_output || p_format->monotonic_output) {\n        ptm = NULL;\n        snprintf(timeBuf, sizeof(timeBuf),\n                 p_format->monotonic_output ? \"%6lld\" : \"%19lld\",\n                 (long long)now);\n    } else {\n#if !defined(_WIN32)\n        ptm = localtime_r(&now, &tmBuf);\n#else\n        ptm = localtime(&now);\n#endif\n        strftime(timeBuf, sizeof(timeBuf),\n                 &\"%Y-%m-%d %H:%M:%S\"[p_format->year_output ? 0 : 3],\n                 ptm);\n    }\n    len = strlen(timeBuf);\n    if (p_format->usec_time_output) {\n        len += snprintf(timeBuf + len, sizeof(timeBuf) - len,\n                        \".%06ld\", nsec / US_PER_NSEC);\n    } else {\n        len += snprintf(timeBuf + len, sizeof(timeBuf) - len,\n                        \".%03ld\", nsec / MS_PER_NSEC);\n    }\n    if (p_format->zone_output && ptm) {\n        strftime(timeBuf + len, sizeof(timeBuf) - len, \" %z\", ptm);\n    }\n\n    /*\n     * Construct a buffer containing the log header and log message.\n     */\n    if (p_format->colored_output) {\n        prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), \"\\x1B[38;5;%dm\",\n                             colorFromPri(entry->priority));\n        prefixLen = MIN(prefixLen, sizeof(prefixBuf));\n        suffixLen = snprintf(suffixBuf, sizeof(suffixBuf), \"\\x1B[0m\");\n        suffixLen = MIN(suffixLen, sizeof(suffixBuf));\n    }\n\n    char uid[16];\n    uid[0] = '\\0';\n    if (p_format->uid_output) {\n        if (entry->uid >= 0) {\n            const struct android_id_info *info = android_ids;\n            size_t i;\n\n            for (i = 0; i < android_id_count; ++i) {\n                if (info->aid == (unsigned int)entry->uid) {\n                    break;\n                }\n                ++info;\n            }\n            if ((i < android_id_count) && (strlen(info->name) <= 5)) {\n                 snprintf(uid, sizeof(uid), \"%5s:\", info->name);\n            } else {\n                 // Not worth parsing package list, names all longer than 5\n                 snprintf(uid, sizeof(uid), \"%5d:\", entry->uid);\n            }\n        } else {\n            snprintf(uid, sizeof(uid), \"      \");\n        }\n    }\n\n    switch (p_format->format) {\n        case FORMAT_TAG:\n            len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen,\n                \"%c/%-8s: \", priChar, entry->tag);\n            strcpy(suffixBuf + suffixLen, \"\\n\");\n            ++suffixLen;\n            break;\n        case FORMAT_PROCESS:\n            len = snprintf(suffixBuf + suffixLen, sizeof(suffixBuf) - suffixLen,\n                \"  (%s)\\n\", entry->tag);\n            suffixLen += MIN(len, sizeof(suffixBuf) - suffixLen);\n            len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen,\n                \"%c(%s%5d) \", priChar, uid, entry->pid);\n            break;\n        case FORMAT_THREAD:\n            len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen,\n                \"%c(%s%5d:%5d) \", priChar, uid, entry->pid, entry->tid);\n            strcpy(suffixBuf + suffixLen, \"\\n\");\n            ++suffixLen;\n            break;\n        case FORMAT_RAW:\n            prefixBuf[prefixLen] = 0;\n            len = 0;\n            strcpy(suffixBuf + suffixLen, \"\\n\");\n            ++suffixLen;\n            break;\n        case FORMAT_TIME:\n            len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen,\n                \"%s %c/%-8s(%s%5d): \", timeBuf, priChar, entry->tag,\n                uid, entry->pid);\n            strcpy(suffixBuf + suffixLen, \"\\n\");\n            ++suffixLen;\n            break;\n        case FORMAT_THREADTIME:\n            ret = strchr(uid, ':');\n            if (ret) {\n                *ret = ' ';\n            }\n            len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen,\n                \"%s %s%5d %5d %c %-8s: \", timeBuf,\n                uid, entry->pid, entry->tid, priChar, entry->tag);\n            strcpy(suffixBuf + suffixLen, \"\\n\");\n            ++suffixLen;\n            break;\n        case FORMAT_LONG:\n            len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen,\n                \"[ %s %s%5d:%5d %c/%-8s ]\\n\",\n                timeBuf, uid, entry->pid, entry->tid, priChar, entry->tag);\n            strcpy(suffixBuf + suffixLen, \"\\n\\n\");\n            suffixLen += 2;\n            prefixSuffixIsHeaderFooter = 1;\n            break;\n        case FORMAT_BRIEF:\n        default:\n            len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen,\n                \"%c/%-8s(%s%5d): \", priChar, entry->tag, uid, entry->pid);\n            strcpy(suffixBuf + suffixLen, \"\\n\");\n            ++suffixLen;\n            break;\n    }\n\n    /* snprintf has a weird return value.   It returns what would have been\n     * written given a large enough buffer.  In the case that the prefix is\n     * longer then our buffer(128), it messes up the calculations below\n     * possibly causing heap corruption.  To avoid this we double check and\n     * set the length at the maximum (size minus null byte)\n     */\n    prefixLen += len;\n    if (prefixLen >= sizeof(prefixBuf)) {\n        prefixLen = sizeof(prefixBuf) - 1;\n        prefixBuf[sizeof(prefixBuf) - 1] = '\\0';\n    }\n    if (suffixLen >= sizeof(suffixBuf)) {\n        suffixLen = sizeof(suffixBuf) - 1;\n        suffixBuf[sizeof(suffixBuf) - 2] = '\\n';\n        suffixBuf[sizeof(suffixBuf) - 1] = '\\0';\n    }\n\n    /* the following code is tragically unreadable */\n\n    size_t numLines;\n    char *p;\n    size_t bufferSize;\n    const char *pm;\n\n    if (prefixSuffixIsHeaderFooter) {\n        /* we're just wrapping message with a header/footer */\n        numLines = 1;\n    } else {\n        pm = entry->message;\n        numLines = 0;\n\n        /*\n         * The line-end finding here must match the line-end finding\n         * in for ( ... numLines...) loop below\n         */\n        while (pm < (entry->message + entry->messageLen)) {\n            if (*pm++ == '\\n') numLines++;\n        }\n        /* plus one line for anything not newline-terminated at the end */\n        if (pm > entry->message && *(pm-1) != '\\n') numLines++;\n    }\n\n    /*\n     * this is an upper bound--newlines in message may be counted\n     * extraneously\n     */\n    bufferSize = (numLines * (prefixLen + suffixLen)) + 1;\n    if (p_format->printable_output) {\n        /* Calculate extra length to convert non-printable to printable */\n        bufferSize += convertPrintable(NULL, entry->message, entry->messageLen);\n    } else {\n        bufferSize += entry->messageLen;\n    }\n\n    if (defaultBufferSize >= bufferSize) {\n        ret = defaultBuffer;\n    } else {\n        ret = (char *)malloc(bufferSize);\n\n        if (ret == NULL) {\n            return ret;\n        }\n    }\n\n    ret[0] = '\\0';       /* to start strcat off */\n\n    p = ret;\n    pm = entry->message;\n\n    if (prefixSuffixIsHeaderFooter) {\n        strcat(p, prefixBuf);\n        p += prefixLen;\n        if (p_format->printable_output) {\n            p += convertPrintable(p, entry->message, entry->messageLen);\n        } else {\n            strncat(p, entry->message, entry->messageLen);\n            p += entry->messageLen;\n        }\n        strcat(p, suffixBuf);\n        p += suffixLen;\n    } else {\n        do {\n            const char *lineStart;\n            size_t lineLen;\n            lineStart = pm;\n\n            /* Find the next end-of-line in message */\n            while (pm < (entry->message + entry->messageLen)\n                    && *pm != '\\n') pm++;\n            lineLen = pm - lineStart;\n\n            strcat(p, prefixBuf);\n            p += prefixLen;\n            if (p_format->printable_output) {\n                p += convertPrintable(p, lineStart, lineLen);\n            } else {\n                strncat(p, lineStart, lineLen);\n                p += lineLen;\n            }\n            strcat(p, suffixBuf);\n            p += suffixLen;\n\n            if (*pm == '\\n') pm++;\n        } while (pm < (entry->message + entry->messageLen));\n    }\n\n    if (p_outLength != NULL) {\n        *p_outLength = p - ret;\n    }\n\n    return ret;\n}\n\n/**\n * Either print or do not print log line, based on filter\n *\n * Returns count bytes written\n */\n\nLIBLOG_ABI_PUBLIC int android_log_printLogLine(\n        AndroidLogFormat *p_format,\n        int fd,\n        const AndroidLogEntry *entry)\n{\n    int ret;\n    char defaultBuffer[512];\n    char *outBuffer = NULL;\n    size_t totalLen;\n\n    outBuffer = android_log_formatLogLine(p_format, defaultBuffer,\n            sizeof(defaultBuffer), entry, &totalLen);\n\n    if (!outBuffer)\n        return -1;\n\n    do {\n        ret = write(fd, outBuffer, totalLen);\n    } while (ret < 0 && errno == EINTR);\n\n    if (ret < 0) {\n        fprintf(stderr, \"+++ LOG: write failed (errno=%d)\\n\", errno);\n        ret = 0;\n        goto done;\n    }\n\n    if (((size_t)ret) < totalLen) {\n        fprintf(stderr, \"+++ LOG: write partial (%d of %d)\\n\", ret,\n                (int)totalLen);\n        goto done;\n    }\n\ndone:\n    if (outBuffer != defaultBuffer) {\n        free(outBuffer);\n    }\n\n    return ret;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/pmsg_reader.c",
    "content": "/*\n * Copyright (C) 2007-2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <ctype.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <stdbool.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/types.h>\n\n#include <private/android_filesystem_config.h>\n#include <private/android_logger.h>\n\n#include \"config_read.h\"\n#include \"logger.h\"\n\nstatic int pmsgAvailable(log_id_t logId);\nstatic int pmsgVersion(struct android_log_logger *logger,\n                       struct android_log_transport_context *transp);\nstatic int pmsgRead(struct android_log_logger_list *logger_list,\n                    struct android_log_transport_context *transp,\n                    struct log_msg *log_msg);\nstatic void pmsgClose(struct android_log_logger_list *logger_list,\n                      struct android_log_transport_context *transp);\nstatic int pmsgClear(struct android_log_logger *logger,\n                     struct android_log_transport_context *transp);\n\nLIBLOG_HIDDEN struct android_log_transport_read pmsgLoggerRead = {\n    .node = { &pmsgLoggerRead.node, &pmsgLoggerRead.node },\n    .name = \"pmsg\",\n    .available = pmsgAvailable,\n    .version = pmsgVersion,\n    .read = pmsgRead,\n    .poll = NULL,\n    .close = pmsgClose,\n    .clear = pmsgClear,\n    .setSize = NULL,\n    .getSize = NULL,\n    .getReadableSize = NULL,\n    .getPrune = NULL,\n    .setPrune = NULL,\n    .getStats = NULL,\n};\n\nstatic int pmsgAvailable(log_id_t logId)\n{\n    if (logId > LOG_ID_SECURITY) {\n        return -EINVAL;\n    }\n    if (access(\"/dev/pmsg0\", W_OK) == 0) {\n        return 0;\n    }\n    return -EBADF;\n}\n\n/* Determine the credentials of the caller */\nstatic bool uid_has_log_permission(uid_t uid)\n{\n    return (uid == AID_SYSTEM) || (uid == AID_LOG) || (uid == AID_ROOT);\n}\n\nstatic uid_t get_best_effective_uid()\n{\n    uid_t euid;\n    uid_t uid;\n    gid_t gid;\n    ssize_t i;\n    static uid_t last_uid = (uid_t) -1;\n\n    if (last_uid != (uid_t) -1) {\n        return last_uid;\n    }\n    uid = __android_log_uid();\n    if (uid_has_log_permission(uid)) {\n        return last_uid = uid;\n    }\n    euid = geteuid();\n    if (uid_has_log_permission(euid)) {\n        return last_uid = euid;\n    }\n    gid = getgid();\n    if (uid_has_log_permission(gid)) {\n        return last_uid = gid;\n    }\n    gid = getegid();\n    if (uid_has_log_permission(gid)) {\n        return last_uid = gid;\n    }\n    i = getgroups((size_t) 0, NULL);\n    if (i > 0) {\n        gid_t list[i];\n\n        getgroups(i, list);\n        while (--i >= 0) {\n            if (uid_has_log_permission(list[i])) {\n                return last_uid = list[i];\n            }\n        }\n    }\n    return last_uid = uid;\n}\n\nstatic int pmsgClear(struct android_log_logger *logger __unused,\n                     struct android_log_transport_context *transp __unused)\n{\n    if (uid_has_log_permission(get_best_effective_uid())) {\n        return unlink(\"/sys/fs/pstore/pmsg-ramoops-0\");\n    }\n    errno = EPERM;\n    return -1;\n}\n\n/*\n * returns the logger version\n */\nstatic int pmsgVersion(struct android_log_logger *logger __unused,\n                       struct android_log_transport_context *transp __unused)\n{\n    return 4;\n}\n\nstatic int pmsgRead(struct android_log_logger_list *logger_list,\n                    struct android_log_transport_context *transp,\n                    struct log_msg *log_msg)\n{\n    ssize_t ret;\n    off_t current, next;\n    uid_t uid;\n    struct android_log_logger *logger;\n    struct __attribute__((__packed__)) {\n        android_pmsg_log_header_t p;\n        android_log_header_t l;\n    } buf;\n    static uint8_t preread_count;\n    bool is_system;\n\n    memset(log_msg, 0, sizeof(*log_msg));\n\n    if (transp->context.fd <= 0) {\n        int fd = open(\"/sys/fs/pstore/pmsg-ramoops-0\", O_RDONLY | O_CLOEXEC);\n\n        if (fd < 0) {\n            return -errno;\n        }\n        if (fd == 0) { /* Argggg */\n            fd = open(\"/sys/fs/pstore/pmsg-ramoops-0\", O_RDONLY | O_CLOEXEC);\n            close(0);\n            if (fd < 0) {\n                return -errno;\n            }\n        }\n        transp->context.fd = fd;\n        preread_count = 0;\n    }\n\n    while(1) {\n        if (preread_count < sizeof(buf)) {\n            ret = TEMP_FAILURE_RETRY(read(transp->context.fd,\n                                          &buf.p.magic + preread_count,\n                                          sizeof(buf) - preread_count));\n            if (ret < 0) {\n                return -errno;\n            }\n            preread_count += ret;\n        }\n        if (preread_count != sizeof(buf)) {\n            return preread_count ? -EIO : -EAGAIN;\n        }\n        if ((buf.p.magic != LOGGER_MAGIC)\n         || (buf.p.len <= sizeof(buf))\n         || (buf.p.len > (sizeof(buf) + LOGGER_ENTRY_MAX_PAYLOAD))\n         || (buf.l.id >= LOG_ID_MAX)\n         || (buf.l.realtime.tv_nsec >= NS_PER_SEC)) {\n            do {\n                memmove(&buf.p.magic, &buf.p.magic + 1, --preread_count);\n            } while (preread_count && (buf.p.magic != LOGGER_MAGIC));\n            continue;\n        }\n        preread_count = 0;\n\n        if ((transp->logMask & (1 << buf.l.id)) &&\n                ((!logger_list->start.tv_sec && !logger_list->start.tv_nsec) ||\n                    ((logger_list->start.tv_sec <= buf.l.realtime.tv_sec) &&\n                        ((logger_list->start.tv_sec != buf.l.realtime.tv_sec) ||\n                            (logger_list->start.tv_nsec <=\n                                buf.l.realtime.tv_nsec)))) &&\n                (!logger_list->pid || (logger_list->pid == buf.p.pid))) {\n            uid = get_best_effective_uid();\n            is_system = uid_has_log_permission(uid);\n            if (is_system || (uid == buf.p.uid)) {\n                ret = TEMP_FAILURE_RETRY(read(transp->context.fd,\n                                          is_system ?\n                                              log_msg->entry_v4.msg :\n                                              log_msg->entry_v3.msg,\n                                          buf.p.len - sizeof(buf)));\n                if (ret < 0) {\n                    return -errno;\n                }\n                if (ret != (ssize_t)(buf.p.len - sizeof(buf))) {\n                    return -EIO;\n                }\n\n                log_msg->entry_v4.len = buf.p.len - sizeof(buf);\n                log_msg->entry_v4.hdr_size = is_system ?\n                    sizeof(log_msg->entry_v4) :\n                    sizeof(log_msg->entry_v3);\n                log_msg->entry_v4.pid = buf.p.pid;\n                log_msg->entry_v4.tid = buf.l.tid;\n                log_msg->entry_v4.sec = buf.l.realtime.tv_sec;\n                log_msg->entry_v4.nsec = buf.l.realtime.tv_nsec;\n                log_msg->entry_v4.lid = buf.l.id;\n                if (is_system) {\n                    log_msg->entry_v4.uid = buf.p.uid;\n                }\n\n                return ret + log_msg->entry_v4.hdr_size;\n            }\n        }\n\n        current = TEMP_FAILURE_RETRY(lseek(transp->context.fd,\n                                           (off_t)0, SEEK_CUR));\n        if (current < 0) {\n            return -errno;\n        }\n        next = TEMP_FAILURE_RETRY(lseek(transp->context.fd,\n                                        (off_t)(buf.p.len - sizeof(buf)),\n                                        SEEK_CUR));\n        if (next < 0) {\n            return -errno;\n        }\n        if ((next - current) != (ssize_t)(buf.p.len - sizeof(buf))) {\n            return -EIO;\n        }\n    }\n}\n\nstatic void pmsgClose(struct android_log_logger_list *logger_list __unused,\n                      struct android_log_transport_context *transp) {\n    if (transp->context.fd > 0) {\n        close (transp->context.fd);\n    }\n    transp->context.fd = 0;\n}\n\nLIBLOG_ABI_PRIVATE ssize_t __android_log_pmsg_file_read(\n        log_id_t logId,\n        char prio,\n        const char *prefix,\n        __android_log_pmsg_file_read_fn fn, void *arg) {\n    ssize_t ret;\n    struct android_log_logger_list logger_list;\n    struct android_log_transport_context transp;\n    struct content {\n        struct listnode node;\n        union {\n            struct logger_entry_v4 entry;\n            struct logger_entry_v4 entry_v4;\n            struct logger_entry_v3 entry_v3;\n            struct logger_entry_v2 entry_v2;\n            struct logger_entry    entry_v1;\n        };\n    } *content;\n    struct names {\n        struct listnode node;\n        struct listnode content;\n        log_id_t id;\n        char prio;\n        char name[];\n    } *names;\n    struct listnode name_list;\n    struct listnode *node, *n;\n    size_t len, prefix_len;\n\n    if (!fn) {\n        return -EINVAL;\n    }\n\n    /* Add just enough clues in logger_list and transp to make API function */\n    memset(&logger_list, 0, sizeof(logger_list));\n    memset(&transp, 0, sizeof(transp));\n\n    logger_list.mode = ANDROID_LOG_PSTORE |\n                       ANDROID_LOG_NONBLOCK |\n                       ANDROID_LOG_RDONLY;\n    transp.logMask = (unsigned)-1;\n    if (logId != LOG_ID_ANY) {\n        transp.logMask = (1 << logId);\n    }\n    transp.logMask &= ~((1 << LOG_ID_KERNEL) |\n                        (1 << LOG_ID_EVENTS) |\n                        (1 << LOG_ID_SECURITY));\n    if (!transp.logMask) {\n        return -EINVAL;\n    }\n\n    /* Initialize name list */\n    list_init(&name_list);\n\n    ret = SSIZE_MAX;\n\n    /* Validate incoming prefix, shift until it contains only 0 or 1 : or / */\n    prefix_len = 0;\n    if (prefix) {\n        const char *prev = NULL, *last = NULL, *cp = prefix;\n        while ((cp = strpbrk(cp, \"/:\"))) {\n            prev = last;\n            last = cp;\n            cp = cp + 1;\n        }\n        if (prev) {\n            prefix = prev + 1;\n        }\n        prefix_len = strlen(prefix);\n    }\n\n    /* Read the file content */\n    while (pmsgRead(&logger_list, &transp, &transp.logMsg) > 0) {\n        char *cp;\n        size_t hdr_size = transp.logMsg.entry.hdr_size ?\n            transp.logMsg.entry.hdr_size : sizeof(transp.logMsg.entry_v1);\n        char *msg = (char *)&transp.logMsg + hdr_size;\n        char *split = NULL;\n\n        /* Check for invalid sequence number */\n        if ((transp.logMsg.entry.nsec % ANDROID_LOG_PMSG_FILE_SEQUENCE) ||\n                ((transp.logMsg.entry.nsec / ANDROID_LOG_PMSG_FILE_SEQUENCE) >=\n                    ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE)) {\n            continue;\n        }\n\n        /* Determine if it has <dirbase>:<filebase> format for tag */\n        len = transp.logMsg.entry.len - sizeof(prio);\n        for (cp = msg + sizeof(prio);\n                *cp && isprint(*cp) && !isspace(*cp) && --len;\n                ++cp) {\n            if (*cp == ':') {\n                if (split) {\n                    break;\n                }\n                split = cp;\n            }\n        }\n        if (*cp || !split) {\n            continue;\n        }\n\n        /* Filters */\n        if (prefix_len && strncmp(msg + sizeof(prio), prefix, prefix_len)) {\n            size_t offset;\n            /*\n             *   Allow : to be a synonym for /\n             * Things we do dealing with const char * and do not alloc\n             */\n            split = strchr(prefix, ':');\n            if (split) {\n                continue;\n            }\n            split = strchr(prefix, '/');\n            if (!split) {\n                continue;\n            }\n            offset = split - prefix;\n            if ((msg[offset + sizeof(prio)] != ':') ||\n                    strncmp(msg + sizeof(prio), prefix, offset)) {\n                continue;\n            }\n            ++offset;\n            if ((prefix_len > offset) &&\n                    strncmp(&msg[offset + sizeof(prio)], split + 1, prefix_len - offset)) {\n                continue;\n            }\n        }\n\n        if ((prio != ANDROID_LOG_ANY) && (*msg < prio)) {\n            continue;\n        }\n\n        /* check if there is an existing entry */\n        list_for_each(node, &name_list) {\n            names = node_to_item(node, struct names, node);\n            if (!strcmp(names->name, msg + sizeof(prio)) &&\n                    (names->id == transp.logMsg.entry.lid) &&\n                    (names->prio == *msg)) {\n                break;\n            }\n        }\n\n        /* We do not have an existing entry, create and add one */\n        if (node == &name_list) {\n            static const char numbers[] = \"0123456789\";\n            unsigned long long nl;\n\n            len = strlen(msg + sizeof(prio)) + 1;\n            names = calloc(1, sizeof(*names) + len);\n            if (!names) {\n                ret = -ENOMEM;\n                break;\n            }\n            strcpy(names->name, msg + sizeof(prio));\n            names->id = transp.logMsg.entry.lid;\n            names->prio = *msg;\n            list_init(&names->content);\n            /*\n             * Insert in reverse numeric _then_ alpha sorted order as\n             * representative of log rotation:\n             *\n             *   log.10\n             *   klog.10\n             *   . . .\n             *   log.2\n             *   klog.2\n             *   log.1\n             *   klog.1\n             *   log\n             *   klog\n             *\n             * thus when we present the content, we are provided the oldest\n             * first, which when 'refreshed' could spill off the end of the\n             * pmsg FIFO but retaining the newest data for last with best\n             * chances to survive.\n             */\n            nl = 0;\n            cp = strpbrk(names->name, numbers);\n            if (cp) {\n                nl = strtoull(cp, NULL, 10);\n            }\n            list_for_each_reverse(node, &name_list) {\n                struct names *a_name = node_to_item(node, struct names, node);\n                const char *r = a_name->name;\n                int compare = 0;\n\n                unsigned long long nr = 0;\n                cp = strpbrk(r, numbers);\n                if (cp) {\n                    nr = strtoull(cp, NULL, 10);\n                }\n                if (nr != nl) {\n                    compare = (nl > nr) ? 1 : -1;\n                }\n                if (compare == 0) {\n                    compare = strcmp(names->name, r);\n                }\n                if (compare <= 0) {\n                    break;\n                }\n            }\n            list_add_head(node, &names->node);\n        }\n\n        /* Remove any file fragments that match our sequence number */\n        list_for_each_safe(node, n, &names->content) {\n            content = node_to_item(node, struct content, node);\n            if (transp.logMsg.entry.nsec == content->entry.nsec) {\n                list_remove(&content->node);\n                free(content);\n            }\n        }\n\n        /* Add content */\n        content = calloc(1, sizeof(content->node) +\n                hdr_size + transp.logMsg.entry.len);\n        if (!content) {\n            ret = -ENOMEM;\n            break;\n        }\n        memcpy(&content->entry, &transp.logMsg.entry,\n               hdr_size + transp.logMsg.entry.len);\n\n        /* Insert in sequence number sorted order, to ease reconstruction */\n        list_for_each_reverse(node, &names->content) {\n            if ((node_to_item(node, struct content, node))->entry.nsec <\n                    transp.logMsg.entry.nsec) {\n                break;\n            }\n        }\n        list_add_head(node, &content->node);\n    }\n    pmsgClose(&logger_list, &transp);\n\n    /* Progress through all the collected files */\n    list_for_each_safe(node, n, &name_list) {\n        struct listnode *content_node, *m;\n        char *buf;\n        size_t sequence, tag_len;\n\n        names = node_to_item(node, struct names, node);\n\n        /* Construct content into a linear buffer */\n        buf = NULL;\n        len = 0;\n        sequence = 0;\n        tag_len = strlen(names->name) + sizeof(char); /* tag + nul */\n        list_for_each_safe(content_node, m, &names->content) {\n            ssize_t add_len;\n\n            content = node_to_item(content_node, struct content, node);\n            add_len = content->entry.len - tag_len - sizeof(prio);\n            if (add_len <= 0) {\n                list_remove(content_node);\n                free(content);\n                continue;\n            }\n\n            if (!buf) {\n                buf = malloc(sizeof(char));\n                if (!buf) {\n                    ret = -ENOMEM;\n                    list_remove(content_node);\n                    free(content);\n                    continue;\n                }\n                *buf = '\\0';\n            }\n\n            /* Missing sequence numbers */\n            while (sequence < content->entry.nsec) {\n                /* plus space for enforced nul */\n                buf = realloc(buf, len + sizeof(char) + sizeof(char));\n                if (!buf) {\n                    break;\n                }\n                buf[len] = '\\f'; /* Mark missing content with a form feed */\n                buf[++len] = '\\0';\n                sequence += ANDROID_LOG_PMSG_FILE_SEQUENCE;\n            }\n            if (!buf) {\n                ret = -ENOMEM;\n                list_remove(content_node);\n                free(content);\n                continue;\n            }\n            /* plus space for enforced nul */\n            buf = realloc(buf, len + add_len + sizeof(char));\n            if (!buf) {\n                ret = -ENOMEM;\n                list_remove(content_node);\n                free(content);\n                continue;\n            }\n            memcpy(buf + len,\n                   (char *)&content->entry + content->entry.hdr_size +\n                       tag_len + sizeof(prio),\n                   add_len);\n            len += add_len;\n            buf[len] = '\\0'; /* enforce trailing hidden nul */\n            sequence = content->entry.nsec + ANDROID_LOG_PMSG_FILE_SEQUENCE;\n\n            list_remove(content_node);\n            free(content);\n        }\n        if (buf) {\n            if (len) {\n                /* Buffer contains enforced trailing nul just beyond length */\n                ssize_t r;\n                *strchr(names->name, ':') = '/'; /* Convert back to filename */\n                r = (*fn)(names->id, names->prio, names->name, buf, len, arg);\n                if ((ret >= 0) && (r > 0)) {\n                    if (ret == SSIZE_MAX) {\n                        ret = r;\n                    } else {\n                        ret += r;\n                    }\n                } else if (r < ret) {\n                    ret = r;\n                }\n            }\n            free(buf);\n        }\n        list_remove(node);\n        free(names);\n    }\n    return (ret == SSIZE_MAX) ? -ENOENT : ret;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/pmsg_writer.c",
    "content": "/*\n * Copyright (C) 2007-2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * pmsg write handler\n */\n\n#include <errno.h>\n#include <fcntl.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/types.h>\n#include <time.h>\n\n#include <log/log.h>\n#include <log/logger.h>\n\n#include <private/android_filesystem_config.h>\n#include <private/android_logger.h>\n\n#include \"config_write.h\"\n#include \"log_portability.h\"\n#include \"logger.h\"\n\nstatic int pmsgOpen();\nstatic void pmsgClose();\nstatic int pmsgAvailable(log_id_t logId);\nstatic int pmsgWrite(log_id_t logId, struct timespec *ts,\n                      struct iovec *vec, size_t nr);\n\nLIBLOG_HIDDEN struct android_log_transport_write pmsgLoggerWrite = {\n    .node = { &pmsgLoggerWrite.node, &pmsgLoggerWrite.node },\n    .context.fd = -1,\n    .name = \"pmsg\",\n    .available = pmsgAvailable,\n    .open = pmsgOpen,\n    .close = pmsgClose,\n    .write = pmsgWrite,\n};\n\nstatic int pmsgOpen()\n{\n    if (pmsgLoggerWrite.context.fd < 0) {\n        pmsgLoggerWrite.context.fd = TEMP_FAILURE_RETRY(open(\"/dev/pmsg0\", O_WRONLY | O_CLOEXEC));\n    }\n\n    return pmsgLoggerWrite.context.fd;\n}\n\nstatic void pmsgClose()\n{\n    if (pmsgLoggerWrite.context.fd >= 0) {\n        close(pmsgLoggerWrite.context.fd);\n        pmsgLoggerWrite.context.fd = -1;\n    }\n}\n\nstatic int pmsgAvailable(log_id_t logId)\n{\n    if (logId > LOG_ID_SECURITY) {\n        return -EINVAL;\n    }\n    if ((logId != LOG_ID_SECURITY) &&\n            (logId != LOG_ID_EVENTS) &&\n            !__android_log_is_debuggable()) {\n        return -EINVAL;\n    }\n    if (pmsgLoggerWrite.context.fd < 0) {\n        if (access(\"/dev/pmsg0\", W_OK) == 0) {\n            return 0;\n        }\n        return -EBADF;\n    }\n    return 1;\n}\n\n/*\n * Extract a 4-byte value from a byte stream.\n */\nstatic inline uint32_t get4LE(const uint8_t* src)\n{\n    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);\n}\n\nstatic int pmsgWrite(log_id_t logId, struct timespec *ts,\n                      struct iovec *vec, size_t nr)\n{\n    static const unsigned headerLength = 2;\n    struct iovec newVec[nr + headerLength];\n    android_log_header_t header;\n    android_pmsg_log_header_t pmsgHeader;\n    size_t i, payloadSize;\n    ssize_t ret;\n\n    if ((logId == LOG_ID_EVENTS) && !__android_log_is_debuggable()) {\n        if (vec[0].iov_len < 4) {\n            return -EINVAL;\n        }\n\n        if (SNET_EVENT_LOG_TAG != get4LE(vec[0].iov_base)) {\n            return -EPERM;\n        }\n    }\n\n    if (pmsgLoggerWrite.context.fd < 0) {\n        return -EBADF;\n    }\n\n    /*\n     *  struct {\n     *      // what we provide to pstore\n     *      android_pmsg_log_header_t pmsgHeader;\n     *      // what we provide to file\n     *      android_log_header_t header;\n     *      // caller provides\n     *      union {\n     *          struct {\n     *              char     prio;\n     *              char     payload[];\n     *          } string;\n     *          struct {\n     *              uint32_t tag\n     *              char     payload[];\n     *          } binary;\n     *      };\n     *  };\n     */\n\n    pmsgHeader.magic = LOGGER_MAGIC;\n    pmsgHeader.len = sizeof(pmsgHeader) + sizeof(header);\n    pmsgHeader.uid = __android_log_uid();\n    pmsgHeader.pid = __android_log_pid();\n\n    header.id = logId;\n    header.tid = gettid();\n    header.realtime.tv_sec = ts->tv_sec;\n    header.realtime.tv_nsec = ts->tv_nsec;\n\n    newVec[0].iov_base   = (unsigned char *)&pmsgHeader;\n    newVec[0].iov_len    = sizeof(pmsgHeader);\n    newVec[1].iov_base   = (unsigned char *)&header;\n    newVec[1].iov_len    = sizeof(header);\n\n    for (payloadSize = 0, i = headerLength; i < nr + headerLength; i++) {\n        newVec[i].iov_base = vec[i - headerLength].iov_base;\n        payloadSize += newVec[i].iov_len = vec[i - headerLength].iov_len;\n\n        if (payloadSize > LOGGER_ENTRY_MAX_PAYLOAD) {\n            newVec[i].iov_len -= payloadSize - LOGGER_ENTRY_MAX_PAYLOAD;\n            if (newVec[i].iov_len) {\n                ++i;\n            }\n            payloadSize = LOGGER_ENTRY_MAX_PAYLOAD;\n            break;\n        }\n    }\n    pmsgHeader.len += payloadSize;\n\n    ret = TEMP_FAILURE_RETRY(writev(pmsgLoggerWrite.context.fd, newVec, i));\n    if (ret < 0) {\n        ret = errno ? -errno : -ENOTCONN;\n    }\n\n    if (ret > (ssize_t)(sizeof(header) + sizeof(pmsgHeader))) {\n        ret -= sizeof(header) - sizeof(pmsgHeader);\n    }\n\n    return ret;\n}\n\n/*\n * Virtual pmsg filesystem\n *\n * Payload will comprise the string \"<basedir>:<basefile>\\0<content>\" to a\n * maximum of LOGGER_ENTRY_MAX_PAYLOAD, but scaled to the last newline in the\n * file.\n *\n * Will hijack the header.realtime.tv_nsec field for a sequence number in usec.\n */\n\nstatic inline const char *strnrchr(const char *buf, size_t len, char c) {\n    const char *cp = buf + len;\n    while ((--cp > buf) && (*cp != c));\n    if (cp <= buf) {\n        return buf + len;\n    }\n    return cp;\n}\n\n/* Write a buffer as filename references (tag = <basedir>:<basename>) */\nLIBLOG_ABI_PRIVATE ssize_t __android_log_pmsg_file_write(\n        log_id_t logId,\n        char prio,\n        const char *filename,\n        const char *buf, size_t len) {\n    int fd;\n    size_t length, packet_len;\n    const char *tag;\n    char *cp, *slash;\n    struct timespec ts;\n    struct iovec vec[3];\n\n    /* Make sure the logId value is not a bad idea */\n    if ((logId == LOG_ID_KERNEL) ||       /* Verbotten */\n            (logId == LOG_ID_EVENTS) ||   /* Do not support binary content */\n            (logId == LOG_ID_SECURITY) || /* Bad idea to allow */\n            ((unsigned)logId >= 32)) {    /* fit within logMask on arch32 */\n        return -EINVAL;\n    }\n\n    clock_gettime(android_log_clockid(), &ts);\n\n    cp = strdup(filename);\n    if (!cp) {\n        return -ENOMEM;\n    }\n\n    fd = pmsgLoggerWrite.context.fd;\n    if (fd < 0) {\n        __android_log_lock();\n        fd = pmsgOpen();\n        __android_log_unlock();\n        if (fd < 0) {\n            return -EBADF;\n        }\n    }\n\n    tag = cp;\n    slash = strrchr(cp, '/');\n    if (slash) {\n        *slash = ':';\n        slash = strrchr(cp, '/');\n        if (slash) {\n            tag = slash + 1;\n        }\n    }\n\n    length = strlen(tag) + 1;\n    packet_len = LOGGER_ENTRY_MAX_PAYLOAD - sizeof(char) - length;\n\n    vec[0].iov_base = &prio;\n    vec[0].iov_len  = sizeof(char);\n    vec[1].iov_base = (unsigned char *)tag;\n    vec[1].iov_len  = length;\n\n    for (ts.tv_nsec = 0, length = len;\n            length;\n            ts.tv_nsec += ANDROID_LOG_PMSG_FILE_SEQUENCE) {\n        ssize_t ret;\n        size_t transfer;\n\n        if ((ts.tv_nsec / ANDROID_LOG_PMSG_FILE_SEQUENCE) >=\n                ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE) {\n            len -= length;\n            break;\n        }\n\n        transfer = length;\n        if (transfer > packet_len) {\n            transfer = strnrchr(buf, packet_len - 1, '\\n') - buf;\n            if ((transfer < length) && (buf[transfer] == '\\n')) {\n                ++transfer;\n            }\n        }\n\n        vec[2].iov_base = (unsigned char *)buf;\n        vec[2].iov_len  = transfer;\n\n        ret = pmsgWrite(logId, &ts, vec, sizeof(vec) / sizeof(vec[0]));\n\n        if (ret <= 0) {\n            free(cp);\n            return ret;\n        }\n        length -= transfer;\n        buf += transfer;\n    }\n    free(cp);\n    return len;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/tests/Android.mk",
    "content": "#\n# Copyright (C) 2013-2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\nLOCAL_PATH := $(call my-dir)\n\n# -----------------------------------------------------------------------------\n# Benchmarks.\n# -----------------------------------------------------------------------------\n\ntest_module_prefix := liblog-\ntest_tags := tests\n\nbenchmark_c_flags := \\\n    -Ibionic/tests \\\n    -Wall -Wextra \\\n    -Werror \\\n    -fno-builtin \\\n    -std=gnu++11\n\nbenchmark_src_files := \\\n    benchmark_main.cpp \\\n    liblog_benchmark.cpp\n\n# Build benchmarks for the device. Run with:\n#   adb shell liblog-benchmarks\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := $(test_module_prefix)benchmarks\nLOCAL_MODULE_TAGS := $(test_tags)\nLOCAL_CFLAGS += $(benchmark_c_flags)\nLOCAL_SHARED_LIBRARIES += liblog libm\nLOCAL_SRC_FILES := $(benchmark_src_files)\ninclude $(BUILD_NATIVE_TEST)\n\n# -----------------------------------------------------------------------------\n# Unit tests.\n# -----------------------------------------------------------------------------\n\ntest_c_flags := \\\n    -fstack-protector-all \\\n    -g \\\n    -Wall -Wextra \\\n    -Werror \\\n    -fno-builtin \\\n    -std=gnu++11\n\ntest_src_files := \\\n    liblog_test.cpp\n\n# to prevent breaking the build if bionic not relatively visible to us\nifneq ($(wildcard $(LOCAL_PATH)/../../../../bionic/libc/bionic/libc_logging.cpp),)\n\ntest_src_files += \\\n    libc_test.cpp\n\nendif\n\n# Build tests for the device (with .so). Run with:\n#   adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := $(test_module_prefix)unit-tests\nLOCAL_MODULE_TAGS := $(test_tags)\nLOCAL_CFLAGS += $(test_c_flags)\nLOCAL_SHARED_LIBRARIES := liblog libcutils\nLOCAL_SRC_FILES := $(test_src_files)\ninclude $(BUILD_NATIVE_TEST)\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/tests/benchmark.h",
    "content": "/*\n * Copyright (C) 2012-2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <vector>\n\n#ifndef BIONIC_BENCHMARK_H_\n#define BIONIC_BENCHMARK_H_\n\nnamespace testing {\n\nclass Benchmark;\ntemplate <typename T> class BenchmarkWantsArg;\ntemplate <typename T> class BenchmarkWithArg;\n\nvoid BenchmarkRegister(Benchmark* bm);\nint PrettyPrintInt(char* str, int len, unsigned int arg);\n\nclass Benchmark {\n public:\n  Benchmark(const char* name, void (*fn)(int)) : name_(strdup(name)), fn_(fn) {\n    BenchmarkRegister(this);\n  }\n  Benchmark(const char* name) : name_(strdup(name)), fn_(NULL) {}\n\n  virtual ~Benchmark() {\n    free(name_);\n  }\n\n  const char* Name() { return name_; }\n  virtual const char* ArgName() { return NULL; }\n  virtual void RunFn(int iterations) { fn_(iterations); }\n\n protected:\n  char* name_;\n\n private:\n  void (*fn_)(int);\n};\n\ntemplate <typename T>\nclass BenchmarkWantsArgBase : public Benchmark {\n public:\n  BenchmarkWantsArgBase(const char* name, void (*fn)(int, T)) : Benchmark(name) {\n    fn_arg_ = fn;\n  }\n\n  BenchmarkWantsArgBase<T>* Arg(const char* arg_name, T arg) {\n    BenchmarkRegister(new BenchmarkWithArg<T>(name_, fn_arg_, arg_name, arg));\n    return this;\n  }\n\n protected:\n  virtual void RunFn(int) { printf(\"can't run arg benchmark %s without arg\\n\", Name()); }\n  void (*fn_arg_)(int, T);\n};\n\ntemplate <typename T>\nclass BenchmarkWithArg : public BenchmarkWantsArg<T> {\n public:\n  BenchmarkWithArg(const char* name, void (*fn)(int, T), const char* arg_name, T arg) :\n      BenchmarkWantsArg<T>(name, fn), arg_(arg) {\n    arg_name_ = strdup(arg_name);\n  }\n\n  virtual ~BenchmarkWithArg() {\n    free(arg_name_);\n  }\n\n  virtual const char* ArgName() { return arg_name_; }\n\n protected:\n  virtual void RunFn(int iterations) { BenchmarkWantsArg<T>::fn_arg_(iterations, arg_); }\n\n private:\n  T arg_;\n  char* arg_name_;\n};\n\ntemplate <typename T>\nclass BenchmarkWantsArg : public BenchmarkWantsArgBase<T> {\n public:\n  BenchmarkWantsArg<T>(const char* name, void (*fn)(int, T)) :\n    BenchmarkWantsArgBase<T>(name, fn) { }\n};\n\ntemplate <>\nclass BenchmarkWantsArg<int> : public BenchmarkWantsArgBase<int> {\n public:\n  BenchmarkWantsArg<int>(const char* name, void (*fn)(int, int)) :\n    BenchmarkWantsArgBase<int>(name, fn) { }\n\n  BenchmarkWantsArg<int>* Arg(int arg) {\n    char arg_name[100];\n    PrettyPrintInt(arg_name, sizeof(arg_name), arg);\n    BenchmarkRegister(new BenchmarkWithArg<int>(name_, fn_arg_, arg_name, arg));\n    return this;\n  }\n};\n\nstatic inline Benchmark* BenchmarkFactory(const char* name, void (*fn)(int)) {\n  return new Benchmark(name, fn);\n}\n\ntemplate <typename T>\nstatic inline BenchmarkWantsArg<T>* BenchmarkFactory(const char* name, void (*fn)(int, T)) {\n  return new BenchmarkWantsArg<T>(name, fn);\n}\n\n}  // namespace testing\n\ntemplate <typename T>\nstatic inline void BenchmarkAddArg(::testing::Benchmark* b, const char* name, T arg) {\n  ::testing::BenchmarkWantsArg<T>* ba;\n  ba = static_cast< ::testing::BenchmarkWantsArg<T>* >(b);\n  ba->Arg(name, arg);\n}\n\nvoid SetBenchmarkBytesProcessed(uint64_t);\nvoid ResetBenchmarkTiming(void);\nvoid StopBenchmarkTiming(void);\nvoid StartBenchmarkTiming(void);\nvoid StartBenchmarkTiming(uint64_t);\nvoid StopBenchmarkTiming(uint64_t);\n\n#define BENCHMARK(f) \\\n    static ::testing::Benchmark* _benchmark_##f __attribute__((unused)) = \\\n        (::testing::Benchmark*)::testing::BenchmarkFactory(#f, f)\n\n#endif // BIONIC_BENCHMARK_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/tests/benchmark_main.cpp",
    "content": "/*\n * Copyright (C) 2012-2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <benchmark.h>\n\n#include <inttypes.h>\n#include <math.h>\n#include <regex.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#include <string>\n#include <map>\n#include <vector>\n\nstatic uint64_t gBytesProcessed;\nstatic uint64_t gBenchmarkTotalTimeNs;\nstatic uint64_t gBenchmarkTotalTimeNsSquared;\nstatic uint64_t gBenchmarkNum;\nstatic uint64_t gBenchmarkStartTimeNs;\n\ntypedef std::vector< ::testing::Benchmark* > BenchmarkList;\nstatic BenchmarkList* gBenchmarks;\n\nstatic int Round(int n) {\n  int base = 1;\n  while (base*10 < n) {\n    base *= 10;\n  }\n  if (n < 2*base) {\n    return 2*base;\n  }\n  if (n < 5*base) {\n    return 5*base;\n  }\n  return 10*base;\n}\n\nstatic uint64_t NanoTime() {\n  struct timespec t;\n  t.tv_sec = t.tv_nsec = 0;\n  clock_gettime(CLOCK_MONOTONIC, &t);\n  return static_cast<uint64_t>(t.tv_sec) * 1000000000ULL + t.tv_nsec;\n}\n\nnamespace testing {\n\nint PrettyPrintInt(char* str, int len, unsigned int arg)\n{\n  if (arg >= (1<<30) && arg % (1<<30) == 0) {\n    return snprintf(str, len, \"%uGi\", arg/(1<<30));\n  } else if (arg >= (1<<20) && arg % (1<<20) == 0) {\n    return snprintf(str, len, \"%uMi\", arg/(1<<20));\n  } else if (arg >= (1<<10) && arg % (1<<10) == 0) {\n    return snprintf(str, len, \"%uKi\", arg/(1<<10));\n  } else if (arg >= 1000000000 && arg % 1000000000 == 0) {\n    return snprintf(str, len, \"%uG\", arg/1000000000);\n  } else if (arg >= 1000000 && arg % 1000000 == 0) {\n    return snprintf(str, len, \"%uM\", arg/1000000);\n  } else if (arg >= 1000 && arg % 1000 == 0) {\n    return snprintf(str, len, \"%uK\", arg/1000);\n  } else {\n    return snprintf(str, len, \"%u\", arg);\n  }\n}\n\nbool ShouldRun(Benchmark* b, int argc, char* argv[]) {\n  if (argc == 1) {\n    return true;  // With no arguments, we run all benchmarks.\n  }\n  // Otherwise, we interpret each argument as a regular expression and\n  // see if any of our benchmarks match.\n  for (int i = 1; i < argc; i++) {\n    regex_t re;\n    if (regcomp(&re, argv[i], 0) != 0) {\n      fprintf(stderr, \"couldn't compile \\\"%s\\\" as a regular expression!\\n\", argv[i]);\n      exit(EXIT_FAILURE);\n    }\n    int match = regexec(&re, b->Name(), 0, NULL, 0);\n    regfree(&re);\n    if (match != REG_NOMATCH) {\n      return true;\n    }\n  }\n  return false;\n}\n\nvoid BenchmarkRegister(Benchmark* b) {\n  if (gBenchmarks == NULL) {\n    gBenchmarks = new BenchmarkList;\n  }\n  gBenchmarks->push_back(b);\n}\n\nvoid RunRepeatedly(Benchmark* b, int iterations) {\n  gBytesProcessed = 0;\n  ResetBenchmarkTiming();\n  uint64_t StartTimeNs = NanoTime();\n  b->RunFn(iterations);\n  // Catch us if we fail to log anything.\n  if ((gBenchmarkTotalTimeNs == 0)\n   && (StartTimeNs != 0)\n   && (gBenchmarkStartTimeNs == 0)) {\n    gBenchmarkTotalTimeNs = NanoTime() - StartTimeNs;\n  }\n}\n\nvoid Run(Benchmark* b) {\n  // run once in case it's expensive\n  unsigned iterations = 1;\n  uint64_t s = NanoTime();\n  RunRepeatedly(b, iterations);\n  s = NanoTime() - s;\n  while (s < 2e9 && gBenchmarkTotalTimeNs < 1e9 && iterations < 1e9) {\n    unsigned last = iterations;\n    if (gBenchmarkTotalTimeNs/iterations == 0) {\n      iterations = 1e9;\n    } else {\n      iterations = 1e9 / (gBenchmarkTotalTimeNs/iterations);\n    }\n    iterations = std::max(last + 1, std::min(iterations + iterations/2, 100*last));\n    iterations = Round(iterations);\n    s = NanoTime();\n    RunRepeatedly(b, iterations);\n    s = NanoTime() - s;\n  }\n\n  char throughput[100];\n  throughput[0] = '\\0';\n  if (gBenchmarkTotalTimeNs > 0 && gBytesProcessed > 0) {\n    double mib_processed = static_cast<double>(gBytesProcessed)/1e6;\n    double seconds = static_cast<double>(gBenchmarkTotalTimeNs)/1e9;\n    snprintf(throughput, sizeof(throughput), \" %8.2f MiB/s\", mib_processed/seconds);\n  }\n\n  char full_name[100];\n  snprintf(full_name, sizeof(full_name), \"%s%s%s\", b->Name(),\n           b->ArgName() ? \"/\" : \"\",\n           b->ArgName() ? b->ArgName() : \"\");\n\n  uint64_t mean = gBenchmarkTotalTimeNs / iterations;\n  uint64_t sdev = 0;\n  if (gBenchmarkNum == iterations) {\n    mean = gBenchmarkTotalTimeNs / gBenchmarkNum;\n    uint64_t nXvariance = gBenchmarkTotalTimeNsSquared * gBenchmarkNum\n                        - (gBenchmarkTotalTimeNs * gBenchmarkTotalTimeNs);\n    sdev = (sqrt((double)nXvariance) / gBenchmarkNum / gBenchmarkNum) + 0.5;\n  }\n  if (mean > (10000 * sdev)) {\n    printf(\"%-25s %10\" PRIu64 \" %10\" PRIu64 \"%s\\n\", full_name,\n            static_cast<uint64_t>(iterations), mean, throughput);\n  } else {\n    printf(\"%-25s %10\" PRIu64 \" %10\" PRIu64 \"(\\317\\203%\" PRIu64 \")%s\\n\", full_name,\n           static_cast<uint64_t>(iterations), mean, sdev, throughput);\n  }\n  fflush(stdout);\n}\n\n}  // namespace testing\n\nvoid SetBenchmarkBytesProcessed(uint64_t x) {\n  gBytesProcessed = x;\n}\n\nvoid ResetBenchmarkTiming() {\n  gBenchmarkStartTimeNs = 0;\n  gBenchmarkTotalTimeNs = 0;\n  gBenchmarkTotalTimeNsSquared = 0;\n  gBenchmarkNum = 0;\n}\n\nvoid StopBenchmarkTiming(void) {\n  if (gBenchmarkStartTimeNs != 0) {\n    int64_t diff = NanoTime() - gBenchmarkStartTimeNs;\n    gBenchmarkTotalTimeNs += diff;\n    gBenchmarkTotalTimeNsSquared += diff * diff;\n    ++gBenchmarkNum;\n  }\n  gBenchmarkStartTimeNs = 0;\n}\n\nvoid StartBenchmarkTiming(void) {\n  if (gBenchmarkStartTimeNs == 0) {\n    gBenchmarkStartTimeNs = NanoTime();\n  }\n}\n\nvoid StopBenchmarkTiming(uint64_t NanoTime) {\n  if (gBenchmarkStartTimeNs != 0) {\n    int64_t diff = NanoTime - gBenchmarkStartTimeNs;\n    gBenchmarkTotalTimeNs += diff;\n    gBenchmarkTotalTimeNsSquared += diff * diff;\n    if (NanoTime != 0) {\n      ++gBenchmarkNum;\n    }\n  }\n  gBenchmarkStartTimeNs = 0;\n}\n\nvoid StartBenchmarkTiming(uint64_t NanoTime) {\n  if (gBenchmarkStartTimeNs == 0) {\n    gBenchmarkStartTimeNs = NanoTime;\n  }\n}\n\nint main(int argc, char* argv[]) {\n  if (gBenchmarks->empty()) {\n    fprintf(stderr, \"No benchmarks registered!\\n\");\n    exit(EXIT_FAILURE);\n  }\n\n  bool need_header = true;\n  for (auto b : *gBenchmarks) {\n    if (ShouldRun(b, argc, argv)) {\n      if (need_header) {\n        printf(\"%-25s %10s %10s\\n\", \"\", \"iterations\", \"ns/op\");\n        fflush(stdout);\n        need_header = false;\n      }\n      Run(b);\n    }\n  }\n\n  if (need_header) {\n    fprintf(stderr, \"No matching benchmarks!\\n\");\n    fprintf(stderr, \"Available benchmarks:\\n\");\n    for (auto b : *gBenchmarks) {\n      fprintf(stderr, \"  %s\\n\", b->Name());\n    }\n    exit(EXIT_FAILURE);\n  }\n\n  return 0;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/tests/libc_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <fcntl.h>\n#include <sys/cdefs.h>\n\n#include <gtest/gtest.h>\n\n// Should be in bionic test suite, *but* we are using liblog to confirm\n// end-to-end logging, so let the overly cute oedipus complex begin ...\n#include \"../../../../bionic/libc/bionic/libc_logging.cpp\" // not Standalone\n#define _ANDROID_LOG_H // Priorities redefined\n#define _LIBS_LOG_LOG_H // log ids redefined\ntypedef unsigned char log_id_t; // log_id_t missing as a result\n#define _LIBS_LOG_LOG_READ_H // log_time redefined\n\n#include <log/log.h>\n#include <log/logger.h>\n#include <log/log_read.h>\n\nTEST(libc, __libc_android_log_event_int) {\n    struct logger_list *logger_list;\n\n    pid_t pid = getpid();\n\n    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(\n        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));\n\n    struct timespec ts;\n    clock_gettime(CLOCK_MONOTONIC, &ts);\n    int value = ts.tv_nsec;\n\n    __libc_android_log_event_int(0, value);\n    usleep(1000000);\n\n    int count = 0;\n\n    for (;;) {\n        log_msg log_msg;\n        if (android_logger_list_read(logger_list, &log_msg) <= 0) {\n            break;\n        }\n\n        ASSERT_EQ(log_msg.entry.pid, pid);\n\n        if ((log_msg.entry.len != (4 + 1 + 4))\n         || ((int)log_msg.id() != LOG_ID_EVENTS)) {\n            continue;\n        }\n\n        char *eventData = log_msg.msg();\n\n        int incoming = (eventData[0] & 0xFF) |\n                      ((eventData[1] & 0xFF) << 8) |\n                      ((eventData[2] & 0xFF) << 16) |\n                      ((eventData[3] & 0xFF) << 24);\n\n        if (incoming != 0) {\n            continue;\n        }\n\n        if (eventData[4] != EVENT_TYPE_INT) {\n            continue;\n        }\n\n        incoming = (eventData[4 + 1 + 0] & 0xFF) |\n                  ((eventData[4 + 1 + 1] & 0xFF) << 8) |\n                  ((eventData[4 + 1 + 2] & 0xFF) << 16) |\n                  ((eventData[4 + 1 + 3] & 0xFF) << 24);\n\n        if (incoming == value) {\n            ++count;\n        }\n    }\n\n    EXPECT_EQ(1, count);\n\n    android_logger_list_close(logger_list);\n}\n\nTEST(libc, __libc_fatal_no_abort) {\n    struct logger_list *logger_list;\n\n    pid_t pid = getpid();\n\n    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(\n        (log_id_t)LOG_ID_CRASH, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));\n\n    char b[80];\n    struct timespec ts;\n    clock_gettime(CLOCK_MONOTONIC, &ts);\n\n    __libc_fatal_no_abort(\"%u.%09u\", (unsigned)ts.tv_sec, (unsigned)ts.tv_nsec);\n    snprintf(b, sizeof(b),\"%u.%09u\", (unsigned)ts.tv_sec, (unsigned)ts.tv_nsec);\n    usleep(1000000);\n\n    int count = 0;\n\n    for (;;) {\n        log_msg log_msg;\n        if (android_logger_list_read(logger_list, &log_msg) <= 0) {\n            break;\n        }\n\n        ASSERT_EQ(log_msg.entry.pid, pid);\n\n        if ((int)log_msg.id() != LOG_ID_CRASH) {\n            continue;\n        }\n\n        char *data = log_msg.msg();\n\n        if ((*data == ANDROID_LOG_FATAL)\n                && !strcmp(data + 1, \"libc\")\n                && !strcmp(data + 1 + strlen(data + 1) + 1, b)) {\n            ++count;\n        }\n    }\n\n    EXPECT_EQ(1, count);\n\n    android_logger_list_close(logger_list);\n}\n\nTEST(libc, __pstore_append) {\n    FILE *fp;\n    ASSERT_TRUE(NULL != (fp = fopen(\"/dev/pmsg0\", \"a\")));\n    static const char message[] = \"libc.__pstore_append\\n\";\n    ASSERT_EQ((size_t)1, fwrite(message, sizeof(message), 1, fp));\n    ASSERT_EQ(0, fclose(fp));\n    fprintf(stderr, \"Reboot, ensure string libc.__pstore_append is in /sys/fs/pstore/pmsg-ramoops-0\\n\");\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/tests/liblog_benchmark.cpp",
    "content": "/*\n * Copyright (C) 2013-2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <sys/socket.h>\n#include <cutils/sockets.h>\n#include <log/log.h>\n#include <log/logger.h>\n#include <log/log_read.h>\n\n#include \"benchmark.h\"\n\n// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and\n// non-syscall libs. Since we are benchmarking, or using this in the emergency\n// signal to stuff a terminating code, we do NOT want to introduce\n// a syscall or usleep on EAGAIN retry.\n#define LOG_FAILURE_RETRY(exp) ({  \\\n    typeof (exp) _rc;              \\\n    do {                           \\\n        _rc = (exp);               \\\n    } while (((_rc == -1)          \\\n           && ((errno == EINTR)    \\\n            || (errno == EAGAIN))) \\\n          || (_rc == -EINTR)       \\\n          || (_rc == -EAGAIN));    \\\n    _rc; })\n\n/*\n *\tMeasure the fastest rate we can reliabley stuff print messages into\n * the log at high pressure. Expect this to be less than double the process\n * wakeup time (2ms?)\n */\nstatic void BM_log_maximum_retry(int iters) {\n    StartBenchmarkTiming();\n\n    for (int i = 0; i < iters; ++i) {\n        LOG_FAILURE_RETRY(\n            __android_log_print(ANDROID_LOG_INFO,\n                                \"BM_log_maximum_retry\", \"%d\", i));\n    }\n\n    StopBenchmarkTiming();\n}\nBENCHMARK(BM_log_maximum_retry);\n\n/*\n *\tMeasure the fastest rate we can stuff print messages into the log\n * at high pressure. Expect this to be less than double the process wakeup\n * time (2ms?)\n */\nstatic void BM_log_maximum(int iters) {\n    StartBenchmarkTiming();\n\n    for (int i = 0; i < iters; ++i) {\n        __android_log_print(ANDROID_LOG_INFO, \"BM_log_maximum\", \"%d\", i);\n    }\n\n    StopBenchmarkTiming();\n}\nBENCHMARK(BM_log_maximum);\n\n/*\n *\tMeasure the time it takes to submit the android logging call using\n * discrete acquisition under light load. Expect this to be a pair of\n * syscall periods (2us).\n */\nstatic void BM_clock_overhead(int iters) {\n    for (int i = 0; i < iters; ++i) {\n       StartBenchmarkTiming();\n       StopBenchmarkTiming();\n    }\n}\nBENCHMARK(BM_clock_overhead);\n\n/*\n *\tMeasure the time it takes to submit the android logging call using\n * discrete acquisition under light load. Expect this to be a dozen or so\n * syscall periods (40us).\n */\nstatic void BM_log_overhead(int iters) {\n    for (int i = 0; i < iters; ++i) {\n       StartBenchmarkTiming();\n       __android_log_print(ANDROID_LOG_INFO, \"BM_log_overhead\", \"%d\", i);\n       StopBenchmarkTiming();\n       usleep(1000);\n    }\n}\nBENCHMARK(BM_log_overhead);\n\nstatic void caught_latency(int /*signum*/)\n{\n    unsigned long long v = 0xDEADBEEFA55A5AA5ULL;\n\n    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));\n}\n\nstatic unsigned long long caught_convert(char *cp)\n{\n    unsigned long long l = cp[0] & 0xFF;\n    l |= (unsigned long long) (cp[1] & 0xFF) << 8;\n    l |= (unsigned long long) (cp[2] & 0xFF) << 16;\n    l |= (unsigned long long) (cp[3] & 0xFF) << 24;\n    l |= (unsigned long long) (cp[4] & 0xFF) << 32;\n    l |= (unsigned long long) (cp[5] & 0xFF) << 40;\n    l |= (unsigned long long) (cp[6] & 0xFF) << 48;\n    l |= (unsigned long long) (cp[7] & 0xFF) << 56;\n    return l;\n}\n\nstatic const int alarm_time = 3;\n\n/*\n *\tMeasure the time it takes for the logd posting call to acquire the\n * timestamp to place into the internal record. Expect this to be less than\n * 4 syscalls (3us).\n */\nstatic void BM_log_latency(int iters) {\n    pid_t pid = getpid();\n\n    struct logger_list * logger_list = android_logger_list_open(LOG_ID_EVENTS,\n        ANDROID_LOG_RDONLY, 0, pid);\n\n    if (!logger_list) {\n        fprintf(stderr, \"Unable to open events log: %s\\n\", strerror(errno));\n        exit(EXIT_FAILURE);\n    }\n\n    signal(SIGALRM, caught_latency);\n    alarm(alarm_time);\n\n    for (int j = 0, i = 0; i < iters && j < 10*iters; ++i, ++j) {\n        log_time ts;\n        LOG_FAILURE_RETRY((\n            ts = log_time(CLOCK_REALTIME),\n            android_btWriteLog(0, EVENT_TYPE_LONG, &ts, sizeof(ts))));\n\n        for (;;) {\n            log_msg log_msg;\n            int ret = android_logger_list_read(logger_list, &log_msg);\n            alarm(alarm_time);\n\n            if (ret <= 0) {\n                iters = i;\n                break;\n            }\n            if ((log_msg.entry.len != (4 + 1 + 8))\n             || (log_msg.id() != LOG_ID_EVENTS)) {\n                continue;\n            }\n\n            char* eventData = log_msg.msg();\n\n            if (eventData[4] != EVENT_TYPE_LONG) {\n                continue;\n            }\n            log_time tx(eventData + 4 + 1);\n            if (ts != tx) {\n                if (0xDEADBEEFA55A5AA5ULL == caught_convert(eventData + 4 + 1)) {\n                    iters = i;\n                    break;\n                }\n                continue;\n            }\n\n            uint64_t start = ts.nsec();\n            uint64_t end = log_msg.nsec();\n            if (end >= start) {\n                StartBenchmarkTiming(start);\n                StopBenchmarkTiming(end);\n            } else {\n                --i;\n            }\n            break;\n        }\n    }\n\n    signal(SIGALRM, SIG_DFL);\n    alarm(0);\n\n    android_logger_list_free(logger_list);\n}\nBENCHMARK(BM_log_latency);\n\nstatic void caught_delay(int /*signum*/)\n{\n    unsigned long long v = 0xDEADBEEFA55A5AA6ULL;\n\n    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));\n}\n\n/*\n *\tMeasure the time it takes for the logd posting call to make it into\n * the logs. Expect this to be less than double the process wakeup time (2ms).\n */\nstatic void BM_log_delay(int iters) {\n    pid_t pid = getpid();\n\n    struct logger_list * logger_list = android_logger_list_open(LOG_ID_EVENTS,\n        ANDROID_LOG_RDONLY, 0, pid);\n\n    if (!logger_list) {\n        fprintf(stderr, \"Unable to open events log: %s\\n\", strerror(errno));\n        exit(EXIT_FAILURE);\n    }\n\n    signal(SIGALRM, caught_delay);\n    alarm(alarm_time);\n\n    StartBenchmarkTiming();\n\n    for (int i = 0; i < iters; ++i) {\n        log_time ts(CLOCK_REALTIME);\n\n        LOG_FAILURE_RETRY(\n            android_btWriteLog(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));\n\n        for (;;) {\n            log_msg log_msg;\n            int ret = android_logger_list_read(logger_list, &log_msg);\n            alarm(alarm_time);\n\n            if (ret <= 0) {\n                iters = i;\n                break;\n            }\n            if ((log_msg.entry.len != (4 + 1 + 8))\n             || (log_msg.id() != LOG_ID_EVENTS)) {\n                continue;\n            }\n\n            char* eventData = log_msg.msg();\n\n            if (eventData[4] != EVENT_TYPE_LONG) {\n                continue;\n            }\n            log_time tx(eventData + 4 + 1);\n            if (ts != tx) {\n                if (0xDEADBEEFA55A5AA6ULL == caught_convert(eventData + 4 + 1)) {\n                    iters = i;\n                    break;\n                }\n                continue;\n            }\n\n            break;\n        }\n    }\n\n    signal(SIGALRM, SIG_DFL);\n    alarm(0);\n\n    StopBenchmarkTiming();\n\n    android_logger_list_free(logger_list);\n}\nBENCHMARK(BM_log_delay);\n\n/*\n *\tMeasure the time it takes for __android_log_is_loggable.\n */\nstatic void BM_is_loggable(int iters) {\n    StartBenchmarkTiming();\n\n    for (int i = 0; i < iters; ++i) {\n        __android_log_is_loggable(ANDROID_LOG_WARN, \"logd\", ANDROID_LOG_VERBOSE);\n    }\n\n    StopBenchmarkTiming();\n}\nBENCHMARK(BM_is_loggable);\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/tests/liblog_test.cpp",
    "content": "/*\n * Copyright (C) 2013-2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <fcntl.h>\n#include <inttypes.h>\n#include <signal.h>\n#include <string.h>\n\n#include <cutils/properties.h>\n#include <gtest/gtest.h>\n#include <log/log.h>\n#include <log/logger.h>\n#include <log/log_read.h>\n#include <log/logprint.h>\n\n// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and\n// non-syscall libs. Since we are only using this in the emergency of\n// a signal to stuff a terminating code into the logs, we will spin rather\n// than try a usleep.\n#define LOG_FAILURE_RETRY(exp) ({  \\\n    typeof (exp) _rc;              \\\n    do {                           \\\n        _rc = (exp);               \\\n    } while (((_rc == -1)          \\\n           && ((errno == EINTR)    \\\n            || (errno == EAGAIN))) \\\n          || (_rc == -EINTR)       \\\n          || (_rc == -EAGAIN));    \\\n    _rc; })\n\nTEST(liblog, __android_log_buf_print) {\n    EXPECT_LT(0, __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO,\n                                         \"TEST__android_log_buf_print\",\n                                         \"radio\"));\n    usleep(1000);\n    EXPECT_LT(0, __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO,\n                                         \"TEST__android_log_buf_print\",\n                                         \"system\"));\n    usleep(1000);\n    EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,\n                                         \"TEST__android_log_buf_print\",\n                                         \"main\"));\n    usleep(1000);\n}\n\nTEST(liblog, __android_log_buf_write) {\n    EXPECT_LT(0, __android_log_buf_write(LOG_ID_RADIO, ANDROID_LOG_INFO,\n                                         \"TEST__android_log_buf_write\",\n                                         \"radio\"));\n    usleep(1000);\n    EXPECT_LT(0, __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,\n                                         \"TEST__android_log_buf_write\",\n                                         \"system\"));\n    usleep(1000);\n    EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,\n                                         \"TEST__android_log_buf_write\",\n                                         \"main\"));\n    usleep(1000);\n}\n\nTEST(liblog, __android_log_btwrite) {\n    int intBuf = 0xDEADBEEF;\n    EXPECT_LT(0, __android_log_btwrite(0,\n                                      EVENT_TYPE_INT,\n                                      &intBuf, sizeof(intBuf)));\n    long long longBuf = 0xDEADBEEFA55A5AA5;\n    EXPECT_LT(0, __android_log_btwrite(0,\n                                      EVENT_TYPE_LONG,\n                                      &longBuf, sizeof(longBuf)));\n    usleep(1000);\n    char Buf[] = \"\\20\\0\\0\\0DeAdBeEfA55a5aA5\";\n    EXPECT_LT(0, __android_log_btwrite(0,\n                                      EVENT_TYPE_STRING,\n                                      Buf, sizeof(Buf) - 1));\n    usleep(1000);\n}\n\nstatic void* ConcurrentPrintFn(void *arg) {\n    int ret = __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,\n                                  \"TEST__android_log_print\", \"Concurrent %\" PRIuPTR,\n                                  reinterpret_cast<uintptr_t>(arg));\n    return reinterpret_cast<void*>(ret);\n}\n\n#define NUM_CONCURRENT 64\n#define _concurrent_name(a,n) a##__concurrent##n\n#define concurrent_name(a,n) _concurrent_name(a,n)\n\nTEST(liblog, concurrent_name(__android_log_buf_print, NUM_CONCURRENT)) {\n    pthread_t t[NUM_CONCURRENT];\n    int i;\n    for (i=0; i < NUM_CONCURRENT; i++) {\n        ASSERT_EQ(0, pthread_create(&t[i], NULL,\n                                    ConcurrentPrintFn,\n                                    reinterpret_cast<void *>(i)));\n    }\n    int ret = 0;\n    for (i=0; i < NUM_CONCURRENT; i++) {\n        void* result;\n        ASSERT_EQ(0, pthread_join(t[i], &result));\n        int this_result = reinterpret_cast<uintptr_t>(result);\n        if ((0 == ret) && (0 != this_result)) {\n            ret = this_result;\n        }\n    }\n    ASSERT_LT(0, ret);\n}\n\nTEST(liblog, __android_log_btwrite__android_logger_list_read) {\n    struct logger_list *logger_list;\n\n    pid_t pid = getpid();\n\n    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(\n        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));\n\n    log_time ts(CLOCK_MONOTONIC);\n\n    ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));\n    usleep(1000000);\n\n    int count = 0;\n\n    for (;;) {\n        log_msg log_msg;\n        if (android_logger_list_read(logger_list, &log_msg) <= 0) {\n            break;\n        }\n\n        ASSERT_EQ(log_msg.entry.pid, pid);\n\n        if ((log_msg.entry.len != (4 + 1 + 8))\n         || (log_msg.id() != LOG_ID_EVENTS)) {\n            continue;\n        }\n\n        char *eventData = log_msg.msg();\n\n        if (eventData[4] != EVENT_TYPE_LONG) {\n            continue;\n        }\n\n        log_time tx(eventData + 4 + 1);\n        if (ts == tx) {\n            ++count;\n        }\n    }\n\n    EXPECT_EQ(1, count);\n\n    android_logger_list_close(logger_list);\n}\n\nstatic unsigned signaled;\nlog_time signal_time;\n\nstatic void caught_blocking(int /*signum*/)\n{\n    unsigned long long v = 0xDEADBEEFA55A0000ULL;\n\n    v += getpid() & 0xFFFF;\n\n    ++signaled;\n    if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) {\n        signal_time = log_time(CLOCK_MONOTONIC);\n        signal_time.tv_sec += 2;\n    }\n\n    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));\n}\n\n// Fill in current process user and system time in 10ms increments\nstatic void get_ticks(unsigned long long *uticks, unsigned long long *sticks)\n{\n    *uticks = *sticks = 0;\n\n    pid_t pid = getpid();\n\n    char buffer[512];\n    snprintf(buffer, sizeof(buffer), \"/proc/%u/stat\", pid);\n\n    FILE *fp = fopen(buffer, \"r\");\n    if (!fp) {\n        return;\n    }\n\n    char *cp = fgets(buffer, sizeof(buffer), fp);\n    fclose(fp);\n    if (!cp) {\n        return;\n    }\n\n    pid_t d;\n    char s[sizeof(buffer)];\n    char c;\n    long long ll;\n    unsigned long long ull;\n\n    if (15 != sscanf(buffer,\n      \"%d %s %c %lld %lld %lld %lld %lld %llu %llu %llu %llu %llu %llu %llu \",\n      &d, s, &c, &ll, &ll, &ll, &ll, &ll, &ull, &ull, &ull, &ull, &ull,\n      uticks, sticks)) {\n        *uticks = *sticks = 0;\n    }\n}\n\nTEST(liblog, android_logger_list_read__cpu) {\n    struct logger_list *logger_list;\n    unsigned long long v = 0xDEADBEEFA55A0000ULL;\n\n    pid_t pid = getpid();\n\n    v += pid & 0xFFFF;\n\n    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(\n        LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 1000, pid)));\n\n    int count = 0;\n\n    int signals = 0;\n\n    unsigned long long uticks_start;\n    unsigned long long sticks_start;\n    get_ticks(&uticks_start, &sticks_start);\n\n    const unsigned alarm_time = 10;\n\n    memset(&signal_time, 0, sizeof(signal_time));\n\n    signal(SIGALRM, caught_blocking);\n    alarm(alarm_time);\n\n    signaled = 0;\n\n    do {\n        log_msg log_msg;\n        if (android_logger_list_read(logger_list, &log_msg) <= 0) {\n            break;\n        }\n\n        alarm(alarm_time);\n\n        ++count;\n\n        ASSERT_EQ(log_msg.entry.pid, pid);\n\n        if ((log_msg.entry.len != (4 + 1 + 8))\n         || (log_msg.id() != LOG_ID_EVENTS)) {\n            continue;\n        }\n\n        char *eventData = log_msg.msg();\n\n        if (eventData[4] != EVENT_TYPE_LONG) {\n            continue;\n        }\n\n        unsigned long long l = eventData[4 + 1 + 0] & 0xFF;\n        l |= (unsigned long long) (eventData[4 + 1 + 1] & 0xFF) << 8;\n        l |= (unsigned long long) (eventData[4 + 1 + 2] & 0xFF) << 16;\n        l |= (unsigned long long) (eventData[4 + 1 + 3] & 0xFF) << 24;\n        l |= (unsigned long long) (eventData[4 + 1 + 4] & 0xFF) << 32;\n        l |= (unsigned long long) (eventData[4 + 1 + 5] & 0xFF) << 40;\n        l |= (unsigned long long) (eventData[4 + 1 + 6] & 0xFF) << 48;\n        l |= (unsigned long long) (eventData[4 + 1 + 7] & 0xFF) << 56;\n\n        if (l == v) {\n            ++signals;\n            break;\n        }\n    } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time));\n    alarm(0);\n    signal(SIGALRM, SIG_DFL);\n\n    EXPECT_LT(1, count);\n\n    EXPECT_EQ(1, signals);\n\n    android_logger_list_close(logger_list);\n\n    unsigned long long uticks_end;\n    unsigned long long sticks_end;\n    get_ticks(&uticks_end, &sticks_end);\n\n    // Less than 1% in either user or system time, or both\n    const unsigned long long one_percent_ticks = alarm_time;\n    unsigned long long user_ticks = uticks_end - uticks_start;\n    unsigned long long system_ticks = sticks_end - sticks_start;\n    EXPECT_GT(one_percent_ticks, user_ticks);\n    EXPECT_GT(one_percent_ticks, system_ticks);\n    EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);\n}\n\nstatic const char max_payload_tag[] = \"TEST_max_payload_XXXX\";\nstatic const char max_payload_buf[LOGGER_ENTRY_MAX_PAYLOAD\n    - sizeof(max_payload_tag) - 1] = \"LEONATO\\n\\\nI learn in this letter that Don Peter of Arragon\\n\\\ncomes this night to Messina\\n\\\nMESSENGER\\n\\\nHe is very near by this: he was not three leagues off\\n\\\nwhen I left him\\n\\\nLEONATO\\n\\\nHow many gentlemen have you lost in this action?\\n\\\nMESSENGER\\n\\\nBut few of any sort, and none of name\\n\\\nLEONATO\\n\\\nA victory is twice itself when the achiever brings\\n\\\nhome full numbers. I find here that Don Peter hath\\n\\\nbestowed much honour on a young Florentine called Claudio\\n\\\nMESSENGER\\n\\\nMuch deserved on his part and equally remembered by\\n\\\nDon Pedro: he hath borne himself beyond the\\n\\\npromise of his age, doing, in the figure of a lamb,\\n\\\nthe feats of a lion: he hath indeed better\\n\\\nbettered expectation than you must expect of me to\\n\\\ntell you how\\n\\\nLEONATO\\n\\\nHe hath an uncle here in Messina will be very much\\n\\\nglad of it.\\n\\\nMESSENGER\\n\\\nI have already delivered him letters, and there\\n\\\nappears much joy in him; even so much that joy could\\n\\\nnot show itself modest enough without a badge of\\n\\\nbitterness.\\n\\\nLEONATO\\n\\\nDid he break out into tears?\\n\\\nMESSENGER\\n\\\nIn great measure.\\n\\\nLEONATO\\n\\\nA kind overflow of kindness: there are no faces\\n\\\ntruer than those that are so washed. How much\\n\\\nbetter is it to weep at joy than to joy at weeping!\\n\\\nBEATRICE\\n\\\nI pray you, is Signior Mountanto returned from the\\n\\\nwars or no?\\n\\\nMESSENGER\\n\\\nI know none of that name, lady: there was none such\\n\\\nin the army of any sort.\\n\\\nLEONATO\\n\\\nWhat is he that you ask for, niece?\\n\\\nHERO\\n\\\nMy cousin means Signior Benedick of Padua.\\n\\\nMESSENGER\\n\\\nO, he's returned; and as pleasant as ever he was.\\n\\\nBEATRICE\\n\\\nHe set up his bills here in Messina and challenged\\n\\\nCupid at the flight; and my uncle's fool, reading\\n\\\nthe challenge, subscribed for Cupid, and challenged\\n\\\nhim at the bird-bolt. I pray you, how many hath he\\n\\\nkilled and eaten in these wars? But how many hath\\n\\\nhe killed? for indeed I promised to eat all of his killing.\\n\\\nLEONATO\\n\\\nFaith, niece, you tax Signior Benedick too much;\\n\\\nbut he'll be meet with you, I doubt it not.\\n\\\nMESSENGER\\n\\\nHe hath done good service, lady, in these wars.\\n\\\nBEATRICE\\n\\\nYou had musty victual, and he hath holp to eat it:\\n\\\nhe is a very valiant trencherman; he hath an\\n\\\nexcellent stomach.\\n\\\nMESSENGER\\n\\\nAnd a good soldier too, lady.\\n\\\nBEATRICE\\n\\\nAnd a good soldier to a lady: but what is he to a lord?\\n\\\nMESSENGER\\n\\\nA lord to a lord, a man to a man; stuffed with all\\n\\\nhonourable virtues.\\n\\\nBEATRICE\\n\\\nIt is so, indeed; he is no less than a stuffed man:\\n\\\nbut for the stuffing,--well, we are all mortal.\\n\\\nLEONATO\\n\\\nYou must not, sir, mistake my niece. There is a\\n\\\nkind of merry war betwixt Signior Benedick and her:\\n\\\nthey never meet but there's a skirmish of wit\\n\\\nbetween them.\\n\\\nBEATRICE\\n\\\nAlas! he gets nothing by that. In our last\\n\\\nconflict four of his five wits went halting off, and\\n\\\nnow is the whole man governed with one: so that if\\n\\\nhe have wit enough to keep himself warm, let him\\n\\\nbear it for a difference between himself and his\\n\\\nhorse; for it is all the wealth that he hath left,\\n\\\nto be known a reasonable creature. Who is his\\n\\\ncompanion now? He hath every month a new sworn brother.\\n\\\nMESSENGER\\n\\\nIs't possible?\\n\\\nBEATRICE\\n\\\nVery easily possible: he wears his faith but as\\n\\\nthe fashion of his hat; it ever changes with the\\n\\\nnext block.\\n\\\nMESSENGER\\n\\\nI see, lady, the gentleman is not in your books.\\n\\\nBEATRICE\\n\\\nNo; an he were, I would burn my study. But, I pray\\n\\\nyou, who is his companion? Is there no young\\n\\\nsquarer now that will make a voyage with him to the devil?\\n\\\nMESSENGER\\n\\\nHe is most in the company of the right noble Claudio.\\n\\\nBEATRICE\\n\\\nO Lord, he will hang upon him like a disease: he\\n\\\nis sooner caught than the pestilence, and the taker\\n\\\nruns presently mad. God help the noble Claudio! if\\n\\\nhe have caught the Benedick, it will cost him a\\n\\\nthousand pound ere a' be cured.\\n\\\nMESSENGER\\n\\\nI will hold friends with you, lady.\\n\\\nBEATRICE\\n\\\nDo, good friend.\\n\\\nLEONATO\\n\\\nYou will never run mad, niece.\\n\\\nBEATRICE\\n\\\nNo, not till a hot January.\\n\\\nMESSENGER\\n\\\nDon Pedro is approached.\\n\\\nEnter DON PEDRO, DON JOHN, CLAUDIO, BENEDICK, and BALTHASAR\\n\\\n\\n\\\nDON PEDRO\\n\\\nGood Signior Leonato, you are come to meet your\\n\\\ntrouble: the fashion of the world is to avoid\\n\\\ncost, and you encounter it\\n\\\nLEONATO\\n\\\nNever came trouble to my house in the likeness\";\n\nTEST(liblog, max_payload) {\n    pid_t pid = getpid();\n    char tag[sizeof(max_payload_tag)];\n    memcpy(tag, max_payload_tag, sizeof(tag));\n    snprintf(tag + sizeof(tag) - 5, 5, \"%04X\", pid & 0xFFFF);\n\n    LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,\n                                              tag, max_payload_buf));\n    sleep(2);\n\n    struct logger_list *logger_list;\n\n    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(\n        LOG_ID_SYSTEM, ANDROID_LOG_RDONLY, 100, 0)));\n\n    bool matches = false;\n    ssize_t max_len = 0;\n\n    for(;;) {\n        log_msg log_msg;\n        if (android_logger_list_read(logger_list, &log_msg) <= 0) {\n            break;\n        }\n\n        if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {\n            continue;\n        }\n\n        char *data = log_msg.msg() + 1;\n\n        if (strcmp(data, tag)) {\n            continue;\n        }\n\n        data += strlen(data) + 1;\n\n        const char *left = data;\n        const char *right = max_payload_buf;\n        while (*left && *right && (*left == *right)) {\n            ++left;\n            ++right;\n        }\n\n        if (max_len <= (left - data)) {\n            max_len = left - data + 1;\n        }\n\n        if (max_len > 512) {\n            matches = true;\n            break;\n        }\n    }\n\n    android_logger_list_close(logger_list);\n\n    EXPECT_EQ(true, matches);\n\n    EXPECT_LE(sizeof(max_payload_buf), static_cast<size_t>(max_len));\n}\n\nTEST(liblog, too_big_payload) {\n    pid_t pid = getpid();\n    static const char big_payload_tag[] = \"TEST_big_payload_XXXX\";\n    char tag[sizeof(big_payload_tag)];\n    memcpy(tag, big_payload_tag, sizeof(tag));\n    snprintf(tag + sizeof(tag) - 5, 5, \"%04X\", pid & 0xFFFF);\n\n    std::string longString(3266519, 'x');\n\n    ssize_t ret = LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM,\n                                    ANDROID_LOG_INFO, tag, longString.c_str()));\n\n    struct logger_list *logger_list;\n\n    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(\n        LOG_ID_SYSTEM, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 100, 0)));\n\n    ssize_t max_len = 0;\n\n    for(;;) {\n        log_msg log_msg;\n        if (android_logger_list_read(logger_list, &log_msg) <= 0) {\n            break;\n        }\n\n        if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {\n            continue;\n        }\n\n        char *data = log_msg.msg() + 1;\n\n        if (strcmp(data, tag)) {\n            continue;\n        }\n\n        data += strlen(data) + 1;\n\n        const char *left = data;\n        const char *right = longString.c_str();\n        while (*left && *right && (*left == *right)) {\n            ++left;\n            ++right;\n        }\n\n        if (max_len <= (left - data)) {\n            max_len = left - data + 1;\n        }\n    }\n\n    android_logger_list_close(logger_list);\n\n    EXPECT_LE(LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag),\n              static_cast<size_t>(max_len));\n\n    EXPECT_EQ(ret, max_len + static_cast<ssize_t>(sizeof(big_payload_tag)));\n}\n\nTEST(liblog, dual_reader) {\n    struct logger_list *logger_list1;\n\n    // >25 messages due to liblog.__android_log_buf_print__concurrentXX above.\n    ASSERT_TRUE(NULL != (logger_list1 = android_logger_list_open(\n        LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 25, 0)));\n\n    struct logger_list *logger_list2;\n\n    if (NULL == (logger_list2 = android_logger_list_open(\n            LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 15, 0))) {\n        android_logger_list_close(logger_list1);\n        ASSERT_TRUE(NULL != logger_list2);\n    }\n\n    int count1 = 0;\n    bool done1 = false;\n    int count2 = 0;\n    bool done2 = false;\n\n    do {\n        log_msg log_msg;\n\n        if (!done1) {\n            if (android_logger_list_read(logger_list1, &log_msg) <= 0) {\n                done1 = true;\n            } else {\n                ++count1;\n            }\n        }\n\n        if (!done2) {\n            if (android_logger_list_read(logger_list2, &log_msg) <= 0) {\n                done2 = true;\n            } else {\n                ++count2;\n            }\n        }\n    } while ((!done1) || (!done2));\n\n    android_logger_list_close(logger_list1);\n    android_logger_list_close(logger_list2);\n\n    EXPECT_EQ(25, count1);\n    EXPECT_EQ(15, count2);\n}\n\nTEST(liblog, android_logger_get_) {\n    struct logger_list * logger_list = android_logger_list_alloc(ANDROID_LOG_WRONLY, 0, 0);\n\n    for(int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {\n        log_id_t id = static_cast<log_id_t>(i);\n        const char *name = android_log_id_to_name(id);\n        if (id != android_name_to_log_id(name)) {\n            continue;\n        }\n        fprintf(stderr, \"log buffer %s\\r\", name);\n        struct logger * logger;\n        EXPECT_TRUE(NULL != (logger = android_logger_open(logger_list, id)));\n        EXPECT_EQ(id, android_logger_get_id(logger));\n        /* crash buffer is allowed to be empty, that is actually healthy! */\n        if (android_logger_get_log_size(logger) || strcmp(\"crash\", name)) {\n            EXPECT_LT(0, android_logger_get_log_size(logger));\n        }\n        EXPECT_LT(0, android_logger_get_log_readable_size(logger));\n        EXPECT_LT(0, android_logger_get_log_version(logger));\n    }\n\n    android_logger_list_close(logger_list);\n}\n\nstatic bool checkPriForTag(AndroidLogFormat *p_format, const char *tag, android_LogPriority pri) {\n    return android_log_shouldPrintLine(p_format, tag, pri)\n        && !android_log_shouldPrintLine(p_format, tag, (android_LogPriority)(pri - 1));\n}\n\nTEST(liblog, filterRule) {\n    static const char tag[] = \"random\";\n\n    AndroidLogFormat *p_format = android_log_format_new();\n\n    android_log_addFilterRule(p_format,\"*:i\");\n\n    EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO));\n    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);\n    android_log_addFilterRule(p_format, \"*\");\n    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));\n    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);\n    android_log_addFilterRule(p_format, \"*:v\");\n    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));\n    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);\n    android_log_addFilterRule(p_format, \"*:i\");\n    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_INFO));\n    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);\n\n    android_log_addFilterRule(p_format, tag);\n    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));\n    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);\n    android_log_addFilterRule(p_format, \"random:v\");\n    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));\n    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);\n    android_log_addFilterRule(p_format, \"random:d\");\n    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));\n    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);\n    android_log_addFilterRule(p_format, \"random:w\");\n    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));\n    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);\n\n    android_log_addFilterRule(p_format, \"crap:*\");\n    EXPECT_TRUE (checkPriForTag(p_format, \"crap\", ANDROID_LOG_VERBOSE));\n    EXPECT_TRUE(android_log_shouldPrintLine(p_format, \"crap\", ANDROID_LOG_VERBOSE) > 0);\n\n    // invalid expression\n    EXPECT_TRUE (android_log_addFilterRule(p_format, \"random:z\") < 0);\n    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));\n    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);\n\n    // Issue #550946\n    EXPECT_TRUE(android_log_addFilterString(p_format, \" \") == 0);\n    EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN));\n\n    // note trailing space\n    EXPECT_TRUE(android_log_addFilterString(p_format, \"*:s random:d \") == 0);\n    EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));\n\n    EXPECT_TRUE(android_log_addFilterString(p_format, \"*:s random:z\") < 0);\n\n#if 0 // bitrot, seek update\n    char defaultBuffer[512];\n\n    android_log_formatLogLine(p_format,\n        defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123,\n        123, 123, tag, \"nofile\", strlen(\"Hello\"), \"Hello\", NULL);\n\n    fprintf(stderr, \"%s\\n\", defaultBuffer);\n#endif\n\n    android_log_format_free(p_format);\n}\n\nTEST(liblog, is_loggable) {\n    static const char tag[] = \"is_loggable\";\n    static const char log_namespace[] = \"persist.log.tag.\";\n    static const size_t base_offset = 8; /* skip \"persist.\" */\n    // sizeof(\"string\") = strlen(\"string\") + 1\n    char key[sizeof(log_namespace) + sizeof(tag) - 1];\n    char hold[4][PROP_VALUE_MAX];\n    static const struct {\n        int level;\n        char type;\n    } levels[] = {\n        { ANDROID_LOG_VERBOSE, 'v' },\n        { ANDROID_LOG_DEBUG  , 'd' },\n        { ANDROID_LOG_INFO   , 'i' },\n        { ANDROID_LOG_WARN   , 'w' },\n        { ANDROID_LOG_ERROR  , 'e' },\n        { ANDROID_LOG_FATAL  , 'a' },\n        { -1                 , 's' },\n        { -2                 , 'g' }, // Illegal value, resort to default\n    };\n\n    // Set up initial test condition\n    memset(hold, 0, sizeof(hold));\n    snprintf(key, sizeof(key), \"%s%s\", log_namespace, tag);\n    property_get(key, hold[0], \"\");\n    property_set(key, \"\");\n    property_get(key + base_offset, hold[1], \"\");\n    property_set(key + base_offset, \"\");\n    strcpy(key, log_namespace);\n    key[sizeof(log_namespace) - 2] = '\\0';\n    property_get(key, hold[2], \"\");\n    property_set(key, \"\");\n    property_get(key, hold[3], \"\");\n    property_set(key + base_offset, \"\");\n\n    // All combinations of level and defaults\n    for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {\n        if (levels[i].level == -2) {\n            continue;\n        }\n        for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {\n            if (levels[j].level == -2) {\n                continue;\n            }\n            fprintf(stderr, \"i=%zu j=%zu\\r\", i, j);\n            if ((levels[i].level < levels[j].level)\n                    || (levels[j].level == -1)) {\n                EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,\n                                                       levels[j].level));\n            } else {\n                EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,\n                                                      levels[j].level));\n            }\n        }\n    }\n\n    // All combinations of level and tag and global properties\n    for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {\n        if (levels[i].level == -2) {\n            continue;\n        }\n        for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {\n            char buf[2];\n            buf[0] = levels[j].type;\n            buf[1] = '\\0';\n\n            snprintf(key, sizeof(key), \"%s%s\", log_namespace, tag);\n            fprintf(stderr, \"i=%zu j=%zu property_set(\\\"%s\\\",\\\"%s\\\")\\r\",\n                    i, j, key, buf);\n            property_set(key, buf);\n            if ((levels[i].level < levels[j].level)\n                    || (levels[j].level == -1)\n                    || ((levels[i].level < ANDROID_LOG_DEBUG)\n                        && (levels[j].level == -2))) {\n                EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,\n                                                       ANDROID_LOG_DEBUG));\n            } else {\n                EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,\n                                                      ANDROID_LOG_DEBUG));\n            }\n            property_set(key, \"\");\n\n            fprintf(stderr, \"i=%zu j=%zu property_set(\\\"%s\\\",\\\"%s\\\")\\r\",\n                    i, j, key + base_offset, buf);\n            property_set(key + base_offset, buf);\n            if ((levels[i].level < levels[j].level)\n                    || (levels[j].level == -1)\n                    || ((levels[i].level < ANDROID_LOG_DEBUG)\n                        && (levels[j].level == -2))) {\n                EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,\n                                                       ANDROID_LOG_DEBUG));\n            } else {\n                EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,\n                                                      ANDROID_LOG_DEBUG));\n            }\n            property_set(key + base_offset, \"\");\n\n            strcpy(key, log_namespace);\n            key[sizeof(log_namespace) - 2] = '\\0';\n            fprintf(stderr, \"i=%zu j=%zu property_set(\\\"%s\\\",\\\"%s\\\")\\r\",\n                    i, j, key, buf);\n            property_set(key, buf);\n            if ((levels[i].level < levels[j].level)\n                    || (levels[j].level == -1)\n                    || ((levels[i].level < ANDROID_LOG_DEBUG)\n                        && (levels[j].level == -2))) {\n                EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,\n                                                       ANDROID_LOG_DEBUG));\n            } else {\n                EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,\n                                                      ANDROID_LOG_DEBUG));\n            }\n            property_set(key, \"\");\n\n            fprintf(stderr, \"i=%zu j=%zu property_set(\\\"%s\\\",\\\"%s\\\")\\r\",\n                    i, j, key + base_offset, buf);\n            property_set(key + base_offset, buf);\n            if ((levels[i].level < levels[j].level)\n                    || (levels[j].level == -1)\n                    || ((levels[i].level < ANDROID_LOG_DEBUG)\n                        && (levels[j].level == -2))) {\n                EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,\n                                                       ANDROID_LOG_DEBUG));\n            } else {\n                EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,\n                                                      ANDROID_LOG_DEBUG));\n            }\n            property_set(key + base_offset, \"\");\n        }\n    }\n\n    // All combinations of level and tag properties, but with global set to INFO\n    strcpy(key, log_namespace);\n    key[sizeof(log_namespace) - 2] = '\\0';\n    property_set(key, \"I\");\n    snprintf(key, sizeof(key), \"%s%s\", log_namespace, tag);\n    for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {\n        if (levels[i].level == -2) {\n            continue;\n        }\n        for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {\n            char buf[2];\n            buf[0] = levels[j].type;\n            buf[1] = '\\0';\n\n            fprintf(stderr, \"i=%zu j=%zu property_set(\\\"%s\\\",\\\"%s\\\")\\r\",\n                    i, j, key, buf);\n            property_set(key, buf);\n            if ((levels[i].level < levels[j].level)\n                    || (levels[j].level == -1)\n                    || ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO\n                        && (levels[j].level == -2))) {\n                EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,\n                                                       ANDROID_LOG_DEBUG));\n            } else {\n                EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,\n                                                      ANDROID_LOG_DEBUG));\n            }\n            property_set(key, \"\");\n\n            fprintf(stderr, \"i=%zu j=%zu property_set(\\\"%s\\\",\\\"%s\\\")\\r\",\n                    i, j, key + base_offset, buf);\n            property_set(key + base_offset, buf);\n            if ((levels[i].level < levels[j].level)\n                    || (levels[j].level == -1)\n                    || ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO\n                        && (levels[j].level == -2))) {\n                EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,\n                                                       ANDROID_LOG_DEBUG));\n            } else {\n                EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,\n                                                      ANDROID_LOG_DEBUG));\n            }\n            property_set(key + base_offset, \"\");\n        }\n    }\n\n    // reset parms\n    snprintf(key, sizeof(key), \"%s%s\", log_namespace, tag);\n    property_set(key, hold[0]);\n    property_set(key + base_offset, hold[1]);\n    strcpy(key, log_namespace);\n    key[sizeof(log_namespace) - 2] = '\\0';\n    property_set(key, hold[2]);\n    property_set(key + base_offset, hold[3]);\n}\n\nstatic inline int32_t get4LE(const char* src)\n{\n    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);\n}\n\nTEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__typical) {\n    const int TAG = 123456781;\n    const char SUBTAG[] = \"test-subtag\";\n    const int UID = -1;\n    const int DATA_LEN = 200;\n    struct logger_list *logger_list;\n\n    pid_t pid = getpid();\n\n    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(\n        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));\n\n    ASSERT_LT(0, android_errorWriteWithInfoLog(\n            TAG, SUBTAG, UID, max_payload_buf, DATA_LEN));\n\n    sleep(2);\n\n    int count = 0;\n\n    for (;;) {\n        log_msg log_msg;\n        if (android_logger_list_read(logger_list, &log_msg) <= 0) {\n            break;\n        }\n\n        char *eventData = log_msg.msg();\n\n        // Tag\n        int tag = get4LE(eventData);\n        eventData += 4;\n\n        if (tag != TAG) {\n            continue;\n        }\n\n        // List type\n        ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);\n        eventData++;\n\n        // Number of elements in list\n        ASSERT_EQ(3, eventData[0]);\n        eventData++;\n\n        // Element #1: string type for subtag\n        ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);\n        eventData++;\n\n        ASSERT_EQ((int) strlen(SUBTAG), get4LE(eventData));\n        eventData +=4;\n\n        if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) {\n            continue;\n        }\n        eventData += strlen(SUBTAG);\n\n        // Element #2: int type for uid\n        ASSERT_EQ(EVENT_TYPE_INT, eventData[0]);\n        eventData++;\n\n        ASSERT_EQ(UID, get4LE(eventData));\n        eventData += 4;\n\n        // Element #3: string type for data\n        ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);\n        eventData++;\n\n        ASSERT_EQ(DATA_LEN, get4LE(eventData));\n        eventData += 4;\n\n        if (memcmp(max_payload_buf, eventData, DATA_LEN)) {\n            continue;\n        }\n\n        ++count;\n    }\n\n    EXPECT_EQ(1, count);\n\n    android_logger_list_close(logger_list);\n}\n\nTEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__data_too_large) {\n    const int TAG = 123456782;\n    const char SUBTAG[] = \"test-subtag\";\n    const int UID = -1;\n    const int DATA_LEN = sizeof(max_payload_buf);\n    struct logger_list *logger_list;\n\n    pid_t pid = getpid();\n\n    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(\n        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));\n\n    ASSERT_LT(0, android_errorWriteWithInfoLog(\n            TAG, SUBTAG, UID, max_payload_buf, DATA_LEN));\n\n    sleep(2);\n\n    int count = 0;\n\n    for (;;) {\n        log_msg log_msg;\n        if (android_logger_list_read(logger_list, &log_msg) <= 0) {\n            break;\n        }\n\n        char *eventData = log_msg.msg();\n        char *original = eventData;\n\n        // Tag\n        int tag = get4LE(eventData);\n        eventData += 4;\n\n        if (tag != TAG) {\n            continue;\n        }\n\n        // List type\n        ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);\n        eventData++;\n\n        // Number of elements in list\n        ASSERT_EQ(3, eventData[0]);\n        eventData++;\n\n        // Element #1: string type for subtag\n        ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);\n        eventData++;\n\n        ASSERT_EQ((int) strlen(SUBTAG), get4LE(eventData));\n        eventData +=4;\n\n        if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) {\n            continue;\n        }\n        eventData += strlen(SUBTAG);\n\n        // Element #2: int type for uid\n        ASSERT_EQ(EVENT_TYPE_INT, eventData[0]);\n        eventData++;\n\n        ASSERT_EQ(UID, get4LE(eventData));\n        eventData += 4;\n\n        // Element #3: string type for data\n        ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);\n        eventData++;\n\n        size_t dataLen = get4LE(eventData);\n        eventData += 4;\n\n        if (memcmp(max_payload_buf, eventData, dataLen)) {\n            continue;\n        }\n        eventData += dataLen;\n\n        // 4 bytes for the tag, and 512 bytes for the log since the max_payload_buf should be\n        // truncated.\n        ASSERT_EQ(4 + 512, eventData - original);\n\n        ++count;\n    }\n\n    EXPECT_EQ(1, count);\n\n    android_logger_list_close(logger_list);\n}\n\nTEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__null_data) {\n    const int TAG = 123456783;\n    const char SUBTAG[] = \"test-subtag\";\n    const int UID = -1;\n    const int DATA_LEN = 200;\n    struct logger_list *logger_list;\n\n    pid_t pid = getpid();\n\n    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(\n        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));\n\n    ASSERT_GT(0, android_errorWriteWithInfoLog(\n            TAG, SUBTAG, UID, NULL, DATA_LEN));\n\n    sleep(2);\n\n    int count = 0;\n\n    for (;;) {\n        log_msg log_msg;\n        if (android_logger_list_read(logger_list, &log_msg) <= 0) {\n            break;\n        }\n\n        char *eventData = log_msg.msg();\n\n        // Tag\n        int tag = get4LE(eventData);\n        eventData += 4;\n\n        if (tag == TAG) {\n            // This tag should not have been written because the data was null\n            count++;\n            break;\n        }\n    }\n\n    EXPECT_EQ(0, count);\n\n    android_logger_list_close(logger_list);\n}\n\nTEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__subtag_too_long) {\n    const int TAG = 123456784;\n    const char SUBTAG[] = \"abcdefghijklmnopqrstuvwxyz now i know my abc\";\n    const int UID = -1;\n    const int DATA_LEN = 200;\n    struct logger_list *logger_list;\n\n    pid_t pid = getpid();\n\n    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(\n        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));\n\n    ASSERT_LT(0, android_errorWriteWithInfoLog(\n            TAG, SUBTAG, UID, max_payload_buf, DATA_LEN));\n\n    sleep(2);\n\n    int count = 0;\n\n    for (;;) {\n        log_msg log_msg;\n        if (android_logger_list_read(logger_list, &log_msg) <= 0) {\n            break;\n        }\n\n        char *eventData = log_msg.msg();\n\n        // Tag\n        int tag = get4LE(eventData);\n        eventData += 4;\n\n        if (tag != TAG) {\n            continue;\n        }\n\n        // List type\n        ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);\n        eventData++;\n\n        // Number of elements in list\n        ASSERT_EQ(3, eventData[0]);\n        eventData++;\n\n        // Element #1: string type for subtag\n        ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);\n        eventData++;\n\n        // The subtag is longer than 32 and should be truncated to that.\n        ASSERT_EQ(32, get4LE(eventData));\n        eventData +=4;\n\n        if (memcmp(SUBTAG, eventData, 32)) {\n            continue;\n        }\n        eventData += 32;\n\n        // Element #2: int type for uid\n        ASSERT_EQ(EVENT_TYPE_INT, eventData[0]);\n        eventData++;\n\n        ASSERT_EQ(UID, get4LE(eventData));\n        eventData += 4;\n\n        // Element #3: string type for data\n        ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);\n        eventData++;\n\n        ASSERT_EQ(DATA_LEN, get4LE(eventData));\n        eventData += 4;\n\n        if (memcmp(max_payload_buf, eventData, DATA_LEN)) {\n            continue;\n        }\n\n        ++count;\n    }\n\n    EXPECT_EQ(1, count);\n\n    android_logger_list_close(logger_list);\n}\n\nTEST(liblog, android_errorWriteLog__android_logger_list_read__success) {\n    const int TAG = 123456785;\n    const char SUBTAG[] = \"test-subtag\";\n    struct logger_list *logger_list;\n\n    pid_t pid = getpid();\n\n    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(\n        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));\n\n    ASSERT_LT(0, android_errorWriteLog(TAG, SUBTAG));\n\n    sleep(2);\n\n    int count = 0;\n\n    for (;;) {\n        log_msg log_msg;\n        if (android_logger_list_read(logger_list, &log_msg) <= 0) {\n            break;\n        }\n\n        char *eventData = log_msg.msg();\n\n        // Tag\n        int tag = get4LE(eventData);\n        eventData += 4;\n\n        if (tag != TAG) {\n            continue;\n        }\n\n        // List type\n        ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);\n        eventData++;\n\n        // Number of elements in list\n        ASSERT_EQ(3, eventData[0]);\n        eventData++;\n\n        // Element #1: string type for subtag\n        ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);\n        eventData++;\n\n        ASSERT_EQ((int) strlen(SUBTAG), get4LE(eventData));\n        eventData +=4;\n\n        if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) {\n            continue;\n        }\n        ++count;\n    }\n\n    EXPECT_EQ(1, count);\n\n    android_logger_list_close(logger_list);\n}\n\nTEST(liblog, android_errorWriteLog__android_logger_list_read__null_subtag) {\n    const int TAG = 123456786;\n    struct logger_list *logger_list;\n\n    pid_t pid = getpid();\n\n    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(\n        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));\n\n    ASSERT_GT(0, android_errorWriteLog(TAG, NULL));\n\n    sleep(2);\n\n    int count = 0;\n\n    for (;;) {\n        log_msg log_msg;\n        if (android_logger_list_read(logger_list, &log_msg) <= 0) {\n            break;\n        }\n\n        char *eventData = log_msg.msg();\n\n        // Tag\n        int tag = get4LE(eventData);\n        eventData += 4;\n\n        if (tag == TAG) {\n            // This tag should not have been written because the data was null\n            count++;\n            break;\n        }\n    }\n\n    EXPECT_EQ(0, count);\n\n    android_logger_list_close(logger_list);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/liblog/uio.c",
    "content": "/*\n * Copyright (C) 2007-2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#if defined(_WIN32)\n\n#include <unistd.h>\n\n#include <log/uio.h>\n\n#include \"log_portability.h\"\n\nLIBLOG_ABI_PUBLIC int readv(int fd, struct iovec *vecs, int count)\n{\n    int   total = 0;\n\n    for ( ; count > 0; count--, vecs++ ) {\n        char*  buf = vecs->iov_base;\n        int    len = vecs->iov_len;\n\n        while (len > 0) {\n            int  ret = read( fd, buf, len );\n            if (ret < 0) {\n                if (total == 0)\n                    total = -1;\n                goto Exit;\n            }\n            if (ret == 0)\n                goto Exit;\n\n            total += ret;\n            buf   += ret;\n            len   -= ret;\n        }\n    }\nExit:\n    return total;\n}\n\nLIBLOG_ABI_PUBLIC int writev(int fd, const struct iovec *vecs, int count)\n{\n    int   total = 0;\n\n    for ( ; count > 0; count--, vecs++ ) {\n        const char*  buf = vecs->iov_base;\n        int          len = vecs->iov_len;\n\n        while (len > 0) {\n            int  ret = write( fd, buf, len );\n            if (ret < 0) {\n                if (total == 0)\n                    total = -1;\n                goto Exit;\n            }\n            if (ret == 0)\n                goto Exit;\n\n            total += ret;\n            buf   += ret;\n            len   -= ret;\n        }\n    }\nExit:\n    return total;\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/Android.mk",
    "content": "# Copyright (C) 2008 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nLOCAL_PATH:= $(call my-dir)\n\ncommonSources:= \\\n\tCallStack.cpp \\\n\tFileMap.cpp \\\n\tJenkinsHash.cpp \\\n\tLinearTransform.cpp \\\n\tLog.cpp \\\n\tNativeHandle.cpp \\\n\tPrinter.cpp \\\n\tPropertyMap.cpp \\\n\tRefBase.cpp \\\n\tSharedBuffer.cpp \\\n\tStatic.cpp \\\n\tStopWatch.cpp \\\n\tString8.cpp \\\n\tString16.cpp \\\n\tSystemClock.cpp \\\n\tThreads.cpp \\\n\tTimers.cpp \\\n\tTokenizer.cpp \\\n\tUnicode.cpp \\\n\tVectorImpl.cpp \\\n\tmisc.cpp \\\n\nhost_commonCflags := -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS) -Werror\n\n# For the host\n# =====================================================\ninclude $(CLEAR_VARS)\nLOCAL_SRC_FILES:= $(commonSources)\nLOCAL_SRC_FILES_linux := Looper.cpp ProcessCallStack.cpp\nLOCAL_CFLAGS_darwin := -Wno-unused-parameter\nLOCAL_MODULE:= libutils\nLOCAL_STATIC_LIBRARIES := liblog\nLOCAL_CFLAGS += $(host_commonCflags)\n# Under MinGW, ctype.h doesn't need multi-byte support\nLOCAL_CFLAGS_windows := -DMB_CUR_MAX=1\nLOCAL_MULTILIB := both\nLOCAL_MODULE_HOST_OS := darwin linux windows\nLOCAL_C_INCLUDES += external/safe-iop/include\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\n\n# For the device, static\n# =====================================================\ninclude $(CLEAR_VARS)\n\n\n# we have the common sources, plus some device-specific stuff\nLOCAL_SRC_FILES:= \\\n\t$(commonSources) \\\n\tBlobCache.cpp \\\n\tLooper.cpp \\\n\tProcessCallStack.cpp \\\n\tTrace.cpp\n\nifeq ($(TARGET_ARCH),mips)\nLOCAL_CFLAGS += -DALIGN_DOUBLE\nendif\nLOCAL_CFLAGS += -Werror -fvisibility=protected\n\nLOCAL_STATIC_LIBRARIES := \\\n\tlibcutils \\\n\tlibc\n\nLOCAL_SHARED_LIBRARIES := \\\n        libbacktrace \\\n        liblog \\\n        libdl\n\nLOCAL_MODULE := libutils\nLOCAL_CLANG := true\nLOCAL_SANITIZE := integer\nLOCAL_C_INCLUDES += external/safe-iop/include\ninclude $(BUILD_STATIC_LIBRARY)\n\n# For the device, shared\n# =====================================================\ninclude $(CLEAR_VARS)\nLOCAL_MODULE:= libutils\nLOCAL_WHOLE_STATIC_LIBRARIES := libutils\nLOCAL_SHARED_LIBRARIES := \\\n        libbacktrace \\\n        libcutils \\\n        libdl \\\n        liblog\nLOCAL_CFLAGS := -Werror\nLOCAL_C_INCLUDES += external/safe-iop/include\n\nLOCAL_CLANG := true\nLOCAL_SANITIZE := integer\ninclude $(BUILD_SHARED_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := SharedBufferTest\nLOCAL_STATIC_LIBRARIES := libutils\nLOCAL_SHARED_LIBRARIES := liblog\nLOCAL_SRC_FILES := SharedBufferTest.cpp\ninclude $(BUILD_NATIVE_TEST)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := SharedBufferTest\nLOCAL_STATIC_LIBRARIES := libutils\nLOCAL_SHARED_LIBRARIES := liblog\nLOCAL_SRC_FILES := SharedBufferTest.cpp\ninclude $(BUILD_HOST_NATIVE_TEST)\n\n# Build the tests in the tests/ subdirectory.\ninclude $(call first-makefiles-under,$(LOCAL_PATH))\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/BlobCache.cpp",
    "content": "/*\n ** Copyright 2011, The Android Open Source Project\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n\n#define LOG_TAG \"BlobCache\"\n//#define LOG_NDEBUG 0\n\n#include <inttypes.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <utils/BlobCache.h>\n#include <utils/Errors.h>\n#include <utils/Log.h>\n\n#include <cutils/properties.h>\n\nnamespace android {\n\n// BlobCache::Header::mMagicNumber value\nstatic const uint32_t blobCacheMagic = ('_' << 24) + ('B' << 16) + ('b' << 8) + '$';\n\n// BlobCache::Header::mBlobCacheVersion value\nstatic const uint32_t blobCacheVersion = 3;\n\n// BlobCache::Header::mDeviceVersion value\nstatic const uint32_t blobCacheDeviceVersion = 1;\n\nBlobCache::BlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize):\n        mMaxKeySize(maxKeySize),\n        mMaxValueSize(maxValueSize),\n        mMaxTotalSize(maxTotalSize),\n        mTotalSize(0) {\n    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);\n#ifdef _WIN32\n    srand(now);\n#else\n    mRandState[0] = (now >> 0) & 0xFFFF;\n    mRandState[1] = (now >> 16) & 0xFFFF;\n    mRandState[2] = (now >> 32) & 0xFFFF;\n#endif\n    ALOGV(\"initializing random seed using %lld\", (unsigned long long)now);\n}\n\nvoid BlobCache::set(const void* key, size_t keySize, const void* value,\n        size_t valueSize) {\n    if (mMaxKeySize < keySize) {\n        ALOGV(\"set: not caching because the key is too large: %zu (limit: %zu)\",\n                keySize, mMaxKeySize);\n        return;\n    }\n    if (mMaxValueSize < valueSize) {\n        ALOGV(\"set: not caching because the value is too large: %zu (limit: %zu)\",\n                valueSize, mMaxValueSize);\n        return;\n    }\n    if (mMaxTotalSize < keySize + valueSize) {\n        ALOGV(\"set: not caching because the combined key/value size is too \"\n                \"large: %zu (limit: %zu)\", keySize + valueSize, mMaxTotalSize);\n        return;\n    }\n    if (keySize == 0) {\n        ALOGW(\"set: not caching because keySize is 0\");\n        return;\n    }\n    if (valueSize <= 0) {\n        ALOGW(\"set: not caching because valueSize is 0\");\n        return;\n    }\n\n    sp<Blob> dummyKey(new Blob(key, keySize, false));\n    CacheEntry dummyEntry(dummyKey, NULL);\n\n    while (true) {\n        ssize_t index = mCacheEntries.indexOf(dummyEntry);\n        if (index < 0) {\n            // Create a new cache entry.\n            sp<Blob> keyBlob(new Blob(key, keySize, true));\n            sp<Blob> valueBlob(new Blob(value, valueSize, true));\n            size_t newTotalSize = mTotalSize + keySize + valueSize;\n            if (mMaxTotalSize < newTotalSize) {\n                if (isCleanable()) {\n                    // Clean the cache and try again.\n                    clean();\n                    continue;\n                } else {\n                    ALOGV(\"set: not caching new key/value pair because the \"\n                            \"total cache size limit would be exceeded: %zu \"\n                            \"(limit: %zu)\",\n                            keySize + valueSize, mMaxTotalSize);\n                    break;\n                }\n            }\n            mCacheEntries.add(CacheEntry(keyBlob, valueBlob));\n            mTotalSize = newTotalSize;\n            ALOGV(\"set: created new cache entry with %zu byte key and %zu byte value\",\n                    keySize, valueSize);\n        } else {\n            // Update the existing cache entry.\n            sp<Blob> valueBlob(new Blob(value, valueSize, true));\n            sp<Blob> oldValueBlob(mCacheEntries[index].getValue());\n            size_t newTotalSize = mTotalSize + valueSize - oldValueBlob->getSize();\n            if (mMaxTotalSize < newTotalSize) {\n                if (isCleanable()) {\n                    // Clean the cache and try again.\n                    clean();\n                    continue;\n                } else {\n                    ALOGV(\"set: not caching new value because the total cache \"\n                            \"size limit would be exceeded: %zu (limit: %zu)\",\n                            keySize + valueSize, mMaxTotalSize);\n                    break;\n                }\n            }\n            mCacheEntries.editItemAt(index).setValue(valueBlob);\n            mTotalSize = newTotalSize;\n            ALOGV(\"set: updated existing cache entry with %zu byte key and %zu byte \"\n                    \"value\", keySize, valueSize);\n        }\n        break;\n    }\n}\n\nsize_t BlobCache::get(const void* key, size_t keySize, void* value,\n        size_t valueSize) {\n    if (mMaxKeySize < keySize) {\n        ALOGV(\"get: not searching because the key is too large: %zu (limit %zu)\",\n                keySize, mMaxKeySize);\n        return 0;\n    }\n    sp<Blob> dummyKey(new Blob(key, keySize, false));\n    CacheEntry dummyEntry(dummyKey, NULL);\n    ssize_t index = mCacheEntries.indexOf(dummyEntry);\n    if (index < 0) {\n        ALOGV(\"get: no cache entry found for key of size %zu\", keySize);\n        return 0;\n    }\n\n    // The key was found. Return the value if the caller's buffer is large\n    // enough.\n    sp<Blob> valueBlob(mCacheEntries[index].getValue());\n    size_t valueBlobSize = valueBlob->getSize();\n    if (valueBlobSize <= valueSize) {\n        ALOGV(\"get: copying %zu bytes to caller's buffer\", valueBlobSize);\n        memcpy(value, valueBlob->getData(), valueBlobSize);\n    } else {\n        ALOGV(\"get: caller's buffer is too small for value: %zu (needs %zu)\",\n                valueSize, valueBlobSize);\n    }\n    return valueBlobSize;\n}\n\nstatic inline size_t align4(size_t size) {\n    return (size + 3) & ~3;\n}\n\nsize_t BlobCache::getFlattenedSize() const {\n    size_t size = align4(sizeof(Header) + PROPERTY_VALUE_MAX);\n    for (size_t i = 0; i < mCacheEntries.size(); i++) {\n        const CacheEntry& e(mCacheEntries[i]);\n        sp<Blob> keyBlob = e.getKey();\n        sp<Blob> valueBlob = e.getValue();\n        size += align4(sizeof(EntryHeader) + keyBlob->getSize() +\n                       valueBlob->getSize());\n    }\n    return size;\n}\n\nstatus_t BlobCache::flatten(void* buffer, size_t size) const {\n    // Write the cache header\n    if (size < sizeof(Header)) {\n        ALOGE(\"flatten: not enough room for cache header\");\n        return BAD_VALUE;\n    }\n    Header* header = reinterpret_cast<Header*>(buffer);\n    header->mMagicNumber = blobCacheMagic;\n    header->mBlobCacheVersion = blobCacheVersion;\n    header->mDeviceVersion = blobCacheDeviceVersion;\n    header->mNumEntries = mCacheEntries.size();\n    char buildId[PROPERTY_VALUE_MAX];\n    header->mBuildIdLength = property_get(\"ro.build.id\", buildId, \"\");\n    memcpy(header->mBuildId, buildId, header->mBuildIdLength);\n\n    // Write cache entries\n    uint8_t* byteBuffer = reinterpret_cast<uint8_t*>(buffer);\n    off_t byteOffset = align4(sizeof(Header) + header->mBuildIdLength);\n    for (size_t i = 0; i < mCacheEntries.size(); i++) {\n        const CacheEntry& e(mCacheEntries[i]);\n        sp<Blob> keyBlob = e.getKey();\n        sp<Blob> valueBlob = e.getValue();\n        size_t keySize = keyBlob->getSize();\n        size_t valueSize = valueBlob->getSize();\n\n        size_t entrySize = sizeof(EntryHeader) + keySize + valueSize;\n        size_t totalSize = align4(entrySize);\n        if (byteOffset + totalSize > size) {\n            ALOGE(\"flatten: not enough room for cache entries\");\n            return BAD_VALUE;\n        }\n\n        EntryHeader* eheader = reinterpret_cast<EntryHeader*>(\n            &byteBuffer[byteOffset]);\n        eheader->mKeySize = keySize;\n        eheader->mValueSize = valueSize;\n\n        memcpy(eheader->mData, keyBlob->getData(), keySize);\n        memcpy(eheader->mData + keySize, valueBlob->getData(), valueSize);\n\n        if (totalSize > entrySize) {\n            // We have padding bytes. Those will get written to storage, and contribute to the CRC,\n            // so make sure we zero-them to have reproducible results.\n            memset(eheader->mData + keySize + valueSize, 0, totalSize - entrySize);\n        }\n\n        byteOffset += totalSize;\n    }\n\n    return OK;\n}\n\nstatus_t BlobCache::unflatten(void const* buffer, size_t size) {\n    // All errors should result in the BlobCache being in an empty state.\n    mCacheEntries.clear();\n\n    // Read the cache header\n    if (size < sizeof(Header)) {\n        ALOGE(\"unflatten: not enough room for cache header\");\n        return BAD_VALUE;\n    }\n    const Header* header = reinterpret_cast<const Header*>(buffer);\n    if (header->mMagicNumber != blobCacheMagic) {\n        ALOGE(\"unflatten: bad magic number: %\" PRIu32, header->mMagicNumber);\n        return BAD_VALUE;\n    }\n    char buildId[PROPERTY_VALUE_MAX];\n    int len = property_get(\"ro.build.id\", buildId, \"\");\n    if (header->mBlobCacheVersion != blobCacheVersion ||\n            header->mDeviceVersion != blobCacheDeviceVersion ||\n            len != header->mBuildIdLength ||\n            strncmp(buildId, header->mBuildId, len)) {\n        // We treat version mismatches as an empty cache.\n        return OK;\n    }\n\n    // Read cache entries\n    const uint8_t* byteBuffer = reinterpret_cast<const uint8_t*>(buffer);\n    off_t byteOffset = align4(sizeof(Header) + header->mBuildIdLength);\n    size_t numEntries = header->mNumEntries;\n    for (size_t i = 0; i < numEntries; i++) {\n        if (byteOffset + sizeof(EntryHeader) > size) {\n            mCacheEntries.clear();\n            ALOGE(\"unflatten: not enough room for cache entry headers\");\n            return BAD_VALUE;\n        }\n\n        const EntryHeader* eheader = reinterpret_cast<const EntryHeader*>(\n                &byteBuffer[byteOffset]);\n        size_t keySize = eheader->mKeySize;\n        size_t valueSize = eheader->mValueSize;\n        size_t entrySize = sizeof(EntryHeader) + keySize + valueSize;\n\n        size_t totalSize = align4(entrySize);\n        if (byteOffset + totalSize > size) {\n            mCacheEntries.clear();\n            ALOGE(\"unflatten: not enough room for cache entry headers\");\n            return BAD_VALUE;\n        }\n\n        const uint8_t* data = eheader->mData;\n        set(data, keySize, data + keySize, valueSize);\n\n        byteOffset += totalSize;\n    }\n\n    return OK;\n}\n\nlong int BlobCache::blob_random() {\n#ifdef _WIN32\n    return rand();\n#else\n    return nrand48(mRandState);\n#endif\n}\n\nvoid BlobCache::clean() {\n    // Remove a random cache entry until the total cache size gets below half\n    // the maximum total cache size.\n    while (mTotalSize > mMaxTotalSize / 2) {\n        size_t i = size_t(blob_random() % (mCacheEntries.size()));\n        const CacheEntry& entry(mCacheEntries[i]);\n        mTotalSize -= entry.getKey()->getSize() + entry.getValue()->getSize();\n        mCacheEntries.removeAt(i);\n    }\n}\n\nbool BlobCache::isCleanable() const {\n    return mTotalSize > mMaxTotalSize / 2;\n}\n\nBlobCache::Blob::Blob(const void* data, size_t size, bool copyData):\n        mData(copyData ? malloc(size) : data),\n        mSize(size),\n        mOwnsData(copyData) {\n    if (data != NULL && copyData) {\n        memcpy(const_cast<void*>(mData), data, size);\n    }\n}\n\nBlobCache::Blob::~Blob() {\n    if (mOwnsData) {\n        free(const_cast<void*>(mData));\n    }\n}\n\nbool BlobCache::Blob::operator<(const Blob& rhs) const {\n    if (mSize == rhs.mSize) {\n        return memcmp(mData, rhs.mData, mSize) < 0;\n    } else {\n        return mSize < rhs.mSize;\n    }\n}\n\nconst void* BlobCache::Blob::getData() const {\n    return mData;\n}\n\nsize_t BlobCache::Blob::getSize() const {\n    return mSize;\n}\n\nBlobCache::CacheEntry::CacheEntry() {\n}\n\nBlobCache::CacheEntry::CacheEntry(const sp<Blob>& key, const sp<Blob>& value):\n        mKey(key),\n        mValue(value) {\n}\n\nBlobCache::CacheEntry::CacheEntry(const CacheEntry& ce):\n        mKey(ce.mKey),\n        mValue(ce.mValue) {\n}\n\nbool BlobCache::CacheEntry::operator<(const CacheEntry& rhs) const {\n    return *mKey < *rhs.mKey;\n}\n\nconst BlobCache::CacheEntry& BlobCache::CacheEntry::operator=(const CacheEntry& rhs) {\n    mKey = rhs.mKey;\n    mValue = rhs.mValue;\n    return *this;\n}\n\nsp<BlobCache::Blob> BlobCache::CacheEntry::getKey() const {\n    return mKey;\n}\n\nsp<BlobCache::Blob> BlobCache::CacheEntry::getValue() const {\n    return mValue;\n}\n\nvoid BlobCache::CacheEntry::setValue(const sp<Blob>& value) {\n    mValue = value;\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/CallStack.cpp",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"CallStack\"\n\n#include <memory>\n\n#include <utils/CallStack.h>\n#include <utils/Printer.h>\n#include <utils/Errors.h>\n#include <utils/Log.h>\n\n#include <backtrace/Backtrace.h>\n\nnamespace android {\n\nCallStack::CallStack() {\n}\n\nCallStack::CallStack(const char* logtag, int32_t ignoreDepth) {\n    this->update(ignoreDepth+1);\n    this->log(logtag);\n}\n\nCallStack::~CallStack() {\n}\n\nvoid CallStack::update(int32_t ignoreDepth, pid_t tid) {\n    mFrameLines.clear();\n\n    std::unique_ptr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, tid));\n    if (!backtrace->Unwind(ignoreDepth)) {\n        ALOGW(\"%s: Failed to unwind callstack.\", __FUNCTION__);\n    }\n    for (size_t i = 0; i < backtrace->NumFrames(); i++) {\n      mFrameLines.push_back(String8(backtrace->FormatFrameData(i).c_str()));\n    }\n}\n\nvoid CallStack::log(const char* logtag, android_LogPriority priority, const char* prefix) const {\n    LogPrinter printer(logtag, priority, prefix, /*ignoreBlankLines*/false);\n    print(printer);\n}\n\nvoid CallStack::dump(int fd, int indent, const char* prefix) const {\n    FdPrinter printer(fd, indent, prefix);\n    print(printer);\n}\n\nString8 CallStack::toString(const char* prefix) const {\n    String8 str;\n\n    String8Printer printer(&str, prefix);\n    print(printer);\n\n    return str;\n}\n\nvoid CallStack::print(Printer& printer) const {\n    for (size_t i = 0; i < mFrameLines.size(); i++) {\n        printer.printLine(mFrameLines[i]);\n    }\n}\n\n}; // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/CleanSpec.mk",
    "content": "# Copyright (C) 2012 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n# If you don't need to do a full clean build but would like to touch\n# a file or delete some intermediate files, add a clean step to the end\n# of the list.  These steps will only be run once, if they haven't been\n# run before.\n#\n# E.g.:\n#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)\n#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)\n#\n# Always use \"touch -c\" and \"rm -f\" or \"rm -rf\" to gracefully deal with\n# files that are missing or have been moved.\n#\n# Use $(PRODUCT_OUT) to get to the \"out/target/product/blah/\" directory.\n# Use $(OUT_DIR) to refer to the \"out\" directory.\n#\n# If you need to re-do something that's already mentioned, just copy\n# the command and add it to the bottom of the list.  E.g., if a change\n# that you made last week required touching a file and a change you\n# made today requires touching the same file, just copy the old\n# touch step and add it to the end of the list.\n#\n# ************************************************\n# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST\n# ************************************************\n\n# For example:\n#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)\n#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)\n#$(call add-clean-step, find $(OUT_DIR) -type f -name \"IGTalkSession*\" -print0 | xargs -0 rm -f)\n#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)\n\n# ************************************************\n# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST\n# ************************************************\n$(call add-clean-step, rm -rf $(HOST_OUT)/obj/STATIC_LIBRARIES/libutils_intermediates/import_includes)\n$(call add-clean-step, rm -rf $(HOST_OUT)/obj/STATIC_LIBRARIES/lib64utils_intermediates/import_includes)\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/FileMap.cpp",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Shared file mapping class.\n//\n\n#define LOG_TAG \"filemap\"\n\n#include <utils/FileMap.h>\n#include <utils/Log.h>\n\n#if defined(__MINGW32__) && !defined(__USE_MINGW_ANSI_STDIO)\n# define PRId32 \"I32d\"\n# define PRIx32 \"I32x\"\n# define PRId64 \"I64d\"\n#else\n#include <inttypes.h>\n#endif\n#include <stdio.h>\n#include <stdlib.h>\n\n#if !defined(__MINGW32__)\n#include <sys/mman.h>\n#endif\n\n#include <string.h>\n#include <memory.h>\n#include <errno.h>\n#include <assert.h>\n\nusing namespace android;\n\n/*static*/ long FileMap::mPageSize = -1;\n\n// Constructor.  Create an empty object.\nFileMap::FileMap(void)\n    : mFileName(NULL), mBasePtr(NULL), mBaseLength(0),\n      mDataPtr(NULL), mDataLength(0)\n{\n}\n\n// Move Constructor.\nFileMap::FileMap(FileMap&& other)\n    : mFileName(other.mFileName), mBasePtr(other.mBasePtr), mBaseLength(other.mBaseLength),\n      mDataOffset(other.mDataOffset), mDataPtr(other.mDataPtr), mDataLength(other.mDataLength)\n#if defined(__MINGW32__)\n      , mFileHandle(other.mFileHandle), mFileMapping(other.mFileMapping)\n#endif\n{\n    other.mFileName = NULL;\n    other.mBasePtr = NULL;\n    other.mDataPtr = NULL;\n#if defined(__MINGW32__)\n    other.mFileHandle = 0;\n    other.mFileMapping = 0;\n#endif\n}\n\n// Move assign operator.\nFileMap& FileMap::operator=(FileMap&& other) {\n    mFileName = other.mFileName;\n    mBasePtr = other.mBasePtr;\n    mBaseLength = other.mBaseLength;\n    mDataOffset = other.mDataOffset;\n    mDataPtr = other.mDataPtr;\n    mDataLength = other.mDataLength;\n    other.mFileName = NULL;\n    other.mBasePtr = NULL;\n    other.mDataPtr = NULL;\n#if defined(__MINGW32__)\n    mFileHandle = other.mFileHandle;\n    mFileMapping = other.mFileMapping;\n    other.mFileHandle = 0;\n    other.mFileMapping = 0;\n#endif\n    return *this;\n}\n\n// Destructor.\nFileMap::~FileMap(void)\n{\n    if (mFileName != NULL) {\n        free(mFileName);\n    }\n#if defined(__MINGW32__)\n    if (mBasePtr && UnmapViewOfFile(mBasePtr) == 0) {\n        ALOGD(\"UnmapViewOfFile(%p) failed, error = %\" PRId32 \"\\n\", mBasePtr,\n              GetLastError() );\n    }\n    if (mFileMapping != INVALID_HANDLE_VALUE) {\n        CloseHandle(mFileMapping);\n    }\n#else\n    if (mBasePtr && munmap(mBasePtr, mBaseLength) != 0) {\n        ALOGD(\"munmap(%p, %zu) failed\\n\", mBasePtr, mBaseLength);\n    }\n#endif\n}\n\n\n// Create a new mapping on an open file.\n//\n// Closing the file descriptor does not unmap the pages, so we don't\n// claim ownership of the fd.\n//\n// Returns \"false\" on failure.\nbool FileMap::create(const char* origFileName, int fd, off64_t offset, size_t length,\n        bool readOnly)\n{\n#if defined(__MINGW32__)\n    int     adjust;\n    off64_t adjOffset;\n    size_t  adjLength;\n\n    if (mPageSize == -1) {\n        SYSTEM_INFO  si;\n\n        GetSystemInfo( &si );\n        mPageSize = si.dwAllocationGranularity;\n    }\n\n    DWORD  protect = readOnly ? PAGE_READONLY : PAGE_READWRITE;\n\n    mFileHandle  = (HANDLE) _get_osfhandle(fd);\n    mFileMapping = CreateFileMapping( mFileHandle, NULL, protect, 0, 0, NULL);\n    if (mFileMapping == NULL) {\n        ALOGE(\"CreateFileMapping(%p, %\" PRIx32 \") failed with error %\" PRId32 \"\\n\",\n              mFileHandle, protect, GetLastError() );\n        return false;\n    }\n\n    adjust    = offset % mPageSize;\n    adjOffset = offset - adjust;\n    adjLength = length + adjust;\n\n    mBasePtr = MapViewOfFile( mFileMapping,\n                              readOnly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS,\n                              0,\n                              (DWORD)(adjOffset),\n                              adjLength );\n    if (mBasePtr == NULL) {\n        ALOGE(\"MapViewOfFile(%\" PRId64 \", %zu) failed with error %\" PRId32 \"\\n\",\n              adjOffset, adjLength, GetLastError() );\n        CloseHandle(mFileMapping);\n        mFileMapping = INVALID_HANDLE_VALUE;\n        return false;\n    }\n#else // !defined(__MINGW32__)\n    int     prot, flags, adjust;\n    off64_t adjOffset;\n    size_t  adjLength;\n\n    void* ptr;\n\n    assert(fd >= 0);\n    assert(offset >= 0);\n    assert(length > 0);\n\n    // init on first use\n    if (mPageSize == -1) {\n        mPageSize = sysconf(_SC_PAGESIZE);\n        if (mPageSize == -1) {\n            ALOGE(\"could not get _SC_PAGESIZE\\n\");\n            return false;\n        }\n    }\n\n    adjust = offset % mPageSize;\n    adjOffset = offset - adjust;\n    adjLength = length + adjust;\n\n    flags = MAP_SHARED;\n    prot = PROT_READ;\n    if (!readOnly)\n        prot |= PROT_WRITE;\n\n    ptr = mmap(NULL, adjLength, prot, flags, fd, adjOffset);\n    if (ptr == MAP_FAILED) {\n        ALOGE(\"mmap(%lld,%zu) failed: %s\\n\",\n            (long long)adjOffset, adjLength, strerror(errno));\n        return false;\n    }\n    mBasePtr = ptr;\n#endif // !defined(__MINGW32__)\n\n    mFileName = origFileName != NULL ? strdup(origFileName) : NULL;\n    mBaseLength = adjLength;\n    mDataOffset = offset;\n    mDataPtr = (char*) mBasePtr + adjust;\n    mDataLength = length;\n\n    assert(mBasePtr != NULL);\n\n    ALOGV(\"MAP: base %p/%zu data %p/%zu\\n\",\n        mBasePtr, mBaseLength, mDataPtr, mDataLength);\n\n    return true;\n}\n\n// Provide guidance to the system.\n#if !defined(_WIN32)\nint FileMap::advise(MapAdvice advice)\n{\n    int cc, sysAdvice;\n\n    switch (advice) {\n        case NORMAL:        sysAdvice = MADV_NORMAL;        break;\n        case RANDOM:        sysAdvice = MADV_RANDOM;        break;\n        case SEQUENTIAL:    sysAdvice = MADV_SEQUENTIAL;    break;\n        case WILLNEED:      sysAdvice = MADV_WILLNEED;      break;\n        case DONTNEED:      sysAdvice = MADV_DONTNEED;      break;\n        default:\n                            assert(false);\n                            return -1;\n    }\n\n    cc = madvise(mBasePtr, mBaseLength, sysAdvice);\n    if (cc != 0)\n        ALOGW(\"madvise(%d) failed: %s\\n\", sysAdvice, strerror(errno));\n    return cc;\n}\n\n#else\nint FileMap::advise(MapAdvice /* advice */)\n{\n    return -1;\n}\n#endif\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/JenkinsHash.cpp",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* Implementation of Jenkins one-at-a-time hash function. These choices are\n * optimized for code size and portability, rather than raw speed. But speed\n * should still be quite good.\n **/\n\n#include <stdlib.h>\n#include <utils/JenkinsHash.h>\n\nnamespace android {\n\n#ifdef __clang__\n__attribute__((no_sanitize(\"integer\")))\n#endif\nhash_t JenkinsHashWhiten(uint32_t hash) {\n    hash += (hash << 3);\n    hash ^= (hash >> 11);\n    hash += (hash << 15);\n    return hash;\n}\n\nuint32_t JenkinsHashMixBytes(uint32_t hash, const uint8_t* bytes, size_t size) {\n    if (size > UINT32_MAX) {\n        abort();\n    }\n    hash = JenkinsHashMix(hash, (uint32_t)size);\n    size_t i;\n    for (i = 0; i < (size & -4); i += 4) {\n        uint32_t data = bytes[i] | (bytes[i+1] << 8) | (bytes[i+2] << 16) | (bytes[i+3] << 24);\n        hash = JenkinsHashMix(hash, data);\n    }\n    if (size & 3) {\n        uint32_t data = bytes[i];\n        data |= ((size & 3) > 1) ? (bytes[i+1] << 8) : 0;\n        data |= ((size & 3) > 2) ? (bytes[i+2] << 16) : 0;\n        hash = JenkinsHashMix(hash, data);\n    }\n    return hash;\n}\n\nuint32_t JenkinsHashMixShorts(uint32_t hash, const uint16_t* shorts, size_t size) {\n    if (size > UINT32_MAX) {\n        abort();\n    }\n    hash = JenkinsHashMix(hash, (uint32_t)size);\n    size_t i;\n    for (i = 0; i < (size & -2); i += 2) {\n        uint32_t data = shorts[i] | (shorts[i+1] << 16);\n        hash = JenkinsHashMix(hash, data);\n    }\n    if (size & 1) {\n        uint32_t data = shorts[i];\n        hash = JenkinsHashMix(hash, data);\n    }\n    return hash;\n}\n\n}\n\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/LinearTransform.cpp",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define __STDC_LIMIT_MACROS\n\n#include <assert.h>\n#include <stdint.h>\n\n#include <utils/LinearTransform.h>\n\n// disable sanitize as these functions may intentionally overflow (see comments below).\n// the ifdef can be removed when host builds use clang.\n#if defined(__clang__)\n#define ATTRIBUTE_NO_SANITIZE_INTEGER __attribute__((no_sanitize(\"integer\")))\n#else\n#define ATTRIBUTE_NO_SANITIZE_INTEGER\n#endif\n\nnamespace android {\n\n// sanitize failure with T = int32_t and x = 0x80000000\ntemplate<class T>\nATTRIBUTE_NO_SANITIZE_INTEGER\nstatic inline T ABS(T x) { return (x < 0) ? -x : x; }\n\n// Static math methods involving linear transformations\n// remote sanitize failure on overflow case.\nATTRIBUTE_NO_SANITIZE_INTEGER\nstatic bool scale_u64_to_u64(\n        uint64_t val,\n        uint32_t N,\n        uint32_t D,\n        uint64_t* res,\n        bool round_up_not_down) {\n    uint64_t tmp1, tmp2;\n    uint32_t r;\n\n    assert(res);\n    assert(D);\n\n    // Let U32(X) denote a uint32_t containing the upper 32 bits of a 64 bit\n    // integer X.\n    // Let L32(X) denote a uint32_t containing the lower 32 bits of a 64 bit\n    // integer X.\n    // Let X[A, B] with A <= B denote bits A through B of the integer X.\n    // Let (A | B) denote the concatination of two 32 bit ints, A and B.\n    // IOW X = (A | B) => U32(X) == A && L32(X) == B\n    //\n    // compute M = val * N (a 96 bit int)\n    // ---------------------------------\n    // tmp2 = U32(val) * N (a 64 bit int)\n    // tmp1 = L32(val) * N (a 64 bit int)\n    // which means\n    // M = val * N = (tmp2 << 32) + tmp1\n    tmp2 = (val >> 32) * N;\n    tmp1 = (val & UINT32_MAX) * N;\n\n    // compute M[32, 95]\n    // tmp2 = tmp2 + U32(tmp1)\n    //      = (U32(val) * N) + U32(L32(val) * N)\n    //      = M[32, 95]\n    tmp2 += tmp1 >> 32;\n\n    // if M[64, 95] >= D, then M/D has bits > 63 set and we have\n    // an overflow.\n    if ((tmp2 >> 32) >= D) {\n        *res = UINT64_MAX;\n        return false;\n    }\n\n    // Divide.  Going in we know\n    // tmp2 = M[32, 95]\n    // U32(tmp2) < D\n    r = tmp2 % D;\n    tmp2 /= D;\n\n    // At this point\n    // tmp1      = L32(val) * N\n    // tmp2      = M[32, 95] / D\n    //           = (M / D)[32, 95]\n    // r         = M[32, 95] % D\n    // U32(tmp2) = 0\n    //\n    // compute tmp1 = (r | M[0, 31])\n    tmp1 = (tmp1 & UINT32_MAX) | ((uint64_t)r << 32);\n\n    // Divide again.  Keep the remainder around in order to round properly.\n    r = tmp1 % D;\n    tmp1 /= D;\n\n    // At this point\n    // tmp2      = (M / D)[32, 95]\n    // tmp1      = (M / D)[ 0, 31]\n    // r         =  M % D\n    // U32(tmp1) = 0\n    // U32(tmp2) = 0\n\n    // Pack the result and deal with the round-up case (As well as the\n    // remote possiblility over overflow in such a case).\n    *res = (tmp2 << 32) | tmp1;\n    if (r && round_up_not_down) {\n        ++(*res);\n        if (!(*res)) {\n            *res = UINT64_MAX;\n            return false;\n        }\n    }\n\n    return true;\n}\n\n// at least one known sanitize failure (see comment below)\nATTRIBUTE_NO_SANITIZE_INTEGER\nstatic bool linear_transform_s64_to_s64(\n        int64_t  val,\n        int64_t  basis1,\n        int32_t  N,\n        uint32_t D,\n        bool     invert_frac,\n        int64_t  basis2,\n        int64_t* out) {\n    uint64_t scaled, res;\n    uint64_t abs_val;\n    bool is_neg;\n\n    if (!out)\n        return false;\n\n    // Compute abs(val - basis_64). Keep track of whether or not this delta\n    // will be negative after the scale opertaion.\n    if (val < basis1) {\n        is_neg = true;\n        abs_val = basis1 - val;\n    } else {\n        is_neg = false;\n        abs_val = val - basis1;\n    }\n\n    if (N < 0)\n        is_neg = !is_neg;\n\n    if (!scale_u64_to_u64(abs_val,\n                          invert_frac ? D : ABS(N),\n                          invert_frac ? ABS(N) : D,\n                          &scaled,\n                          is_neg))\n        return false; // overflow/undeflow\n\n    // if scaled is >= 0x8000<etc>, then we are going to overflow or\n    // underflow unless ABS(basis2) is large enough to pull us back into the\n    // non-overflow/underflow region.\n    if (scaled & INT64_MIN) {\n        if (is_neg && (basis2 < 0))\n            return false; // certain underflow\n\n        if (!is_neg && (basis2 >= 0))\n            return false; // certain overflow\n\n        if (ABS(basis2) <= static_cast<int64_t>(scaled & INT64_MAX))\n            return false; // not enough\n\n        // Looks like we are OK\n        *out = (is_neg ? (-scaled) : scaled) + basis2;\n    } else {\n        // Scaled fits within signed bounds, so we just need to check for\n        // over/underflow for two signed integers.  Basically, if both scaled\n        // and basis2 have the same sign bit, and the result has a different\n        // sign bit, then we have under/overflow.  An easy way to compute this\n        // is\n        // (scaled_signbit XNOR basis_signbit) &&\n        // (scaled_signbit XOR res_signbit)\n        // ==\n        // (scaled_signbit XOR basis_signbit XOR 1) &&\n        // (scaled_signbit XOR res_signbit)\n\n        if (is_neg)\n            scaled = -scaled; // known sanitize failure\n        res = scaled + basis2;\n\n        if ((scaled ^ basis2 ^ INT64_MIN) & (scaled ^ res) & INT64_MIN)\n            return false;\n\n        *out = res;\n    }\n\n    return true;\n}\n\nbool LinearTransform::doForwardTransform(int64_t a_in, int64_t* b_out) const {\n    if (0 == a_to_b_denom)\n        return false;\n\n    return linear_transform_s64_to_s64(a_in,\n                                       a_zero,\n                                       a_to_b_numer,\n                                       a_to_b_denom,\n                                       false,\n                                       b_zero,\n                                       b_out);\n}\n\nbool LinearTransform::doReverseTransform(int64_t b_in, int64_t* a_out) const {\n    if (0 == a_to_b_numer)\n        return false;\n\n    return linear_transform_s64_to_s64(b_in,\n                                       b_zero,\n                                       a_to_b_numer,\n                                       a_to_b_denom,\n                                       true,\n                                       a_zero,\n                                       a_out);\n}\n\ntemplate <class T> void LinearTransform::reduce(T* N, T* D) {\n    T a, b;\n    if (!N || !D || !(*D)) {\n        assert(false);\n        return;\n    }\n\n    a = *N;\n    b = *D;\n\n    if (a == 0) {\n        *D = 1;\n        return;\n    }\n\n    // This implements Euclid's method to find GCD.\n    if (a < b) {\n        T tmp = a;\n        a = b;\n        b = tmp;\n    }\n\n    while (1) {\n        // a is now the greater of the two.\n        const T remainder = a % b;\n        if (remainder == 0) {\n            *N /= b;\n            *D /= b;\n            return;\n        }\n        // by swapping remainder and b, we are guaranteeing that a is\n        // still the greater of the two upon entrance to the loop.\n        a = b;\n        b = remainder;\n    }\n};\n\ntemplate void LinearTransform::reduce<uint64_t>(uint64_t* N, uint64_t* D);\ntemplate void LinearTransform::reduce<uint32_t>(uint32_t* N, uint32_t* D);\n\n// sanitize failure if *N = 0x80000000\nATTRIBUTE_NO_SANITIZE_INTEGER\nvoid LinearTransform::reduce(int32_t* N, uint32_t* D) {\n    if (N && D && *D) {\n        if (*N < 0) {\n            *N = -(*N);\n            reduce(reinterpret_cast<uint32_t*>(N), D);\n            *N = -(*N);\n        } else {\n            reduce(reinterpret_cast<uint32_t*>(N), D);\n        }\n    }\n}\n\n}  // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/Log.cpp",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"Log\"\n\n#include <utils/Log.h>\n#include <utils/Timers.h>\n\nnamespace android {\n\nLogIfSlow::LogIfSlow(const char* tag, android_LogPriority priority,\n        int timeoutMillis, const char* message) :\n        mTag(tag), mPriority(priority), mTimeoutMillis(timeoutMillis), mMessage(message),\n        mStart(systemTime(SYSTEM_TIME_BOOTTIME)) {\n}\n\nLogIfSlow::~LogIfSlow() {\n    int durationMillis = nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_BOOTTIME) - mStart);\n    if (durationMillis > mTimeoutMillis) {\n        LOG_PRI(mPriority, mTag, \"%s: %dms\", mMessage, durationMillis);\n    }\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/Looper.cpp",
    "content": "//\n// Copyright 2010 The Android Open Source Project\n//\n// A looper implementation based on epoll().\n//\n#define LOG_TAG \"Looper\"\n\n//#define LOG_NDEBUG 0\n\n// Debugs poll and wake interactions.\n#define DEBUG_POLL_AND_WAKE 0\n\n// Debugs callback registration and invocation.\n#define DEBUG_CALLBACKS 0\n\n#include <cutils/log.h>\n#include <utils/Looper.h>\n#include <utils/Timers.h>\n\n#include <errno.h>\n#include <fcntl.h>\n#include <limits.h>\n#include <inttypes.h>\n#include <string.h>\n#include <sys/eventfd.h>\n#include <unistd.h>\n\n\nnamespace android {\n\n// --- WeakMessageHandler ---\n\nWeakMessageHandler::WeakMessageHandler(const wp<MessageHandler>& handler) :\n        mHandler(handler) {\n}\n\nWeakMessageHandler::~WeakMessageHandler() {\n}\n\nvoid WeakMessageHandler::handleMessage(const Message& message) {\n    sp<MessageHandler> handler = mHandler.promote();\n    if (handler != NULL) {\n        handler->handleMessage(message);\n    }\n}\n\n\n// --- SimpleLooperCallback ---\n\nSimpleLooperCallback::SimpleLooperCallback(Looper_callbackFunc callback) :\n        mCallback(callback) {\n}\n\nSimpleLooperCallback::~SimpleLooperCallback() {\n}\n\nint SimpleLooperCallback::handleEvent(int fd, int events, void* data) {\n    return mCallback(fd, events, data);\n}\n\n\n// --- Looper ---\n\n// Hint for number of file descriptors to be associated with the epoll instance.\nstatic const int EPOLL_SIZE_HINT = 8;\n\n// Maximum number of file descriptors for which to retrieve poll events each iteration.\nstatic const int EPOLL_MAX_EVENTS = 16;\n\nstatic pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT;\nstatic pthread_key_t gTLSKey = 0;\n\nLooper::Looper(bool allowNonCallbacks) :\n        mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),\n        mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false),\n        mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {\n    mWakeEventFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);\n    LOG_ALWAYS_FATAL_IF(mWakeEventFd < 0, \"Could not make wake event fd: %s\",\n                        strerror(errno));\n\n    AutoMutex _l(mLock);\n    rebuildEpollLocked();\n}\n\nLooper::~Looper() {\n    close(mWakeEventFd);\n    if (mEpollFd >= 0) {\n        close(mEpollFd);\n    }\n}\n\nvoid Looper::initTLSKey() {\n    int result = pthread_key_create(& gTLSKey, threadDestructor);\n    LOG_ALWAYS_FATAL_IF(result != 0, \"Could not allocate TLS key.\");\n}\n\nvoid Looper::threadDestructor(void *st) {\n    Looper* const self = static_cast<Looper*>(st);\n    if (self != NULL) {\n        self->decStrong((void*)threadDestructor);\n    }\n}\n\nvoid Looper::setForThread(const sp<Looper>& looper) {\n    sp<Looper> old = getForThread(); // also has side-effect of initializing TLS\n\n    if (looper != NULL) {\n        looper->incStrong((void*)threadDestructor);\n    }\n\n    pthread_setspecific(gTLSKey, looper.get());\n\n    if (old != NULL) {\n        old->decStrong((void*)threadDestructor);\n    }\n}\n\nsp<Looper> Looper::getForThread() {\n    int result = pthread_once(& gTLSOnce, initTLSKey);\n    LOG_ALWAYS_FATAL_IF(result != 0, \"pthread_once failed\");\n\n    return (Looper*)pthread_getspecific(gTLSKey);\n}\n\nsp<Looper> Looper::prepare(int opts) {\n    bool allowNonCallbacks = opts & PREPARE_ALLOW_NON_CALLBACKS;\n    sp<Looper> looper = Looper::getForThread();\n    if (looper == NULL) {\n        looper = new Looper(allowNonCallbacks);\n        Looper::setForThread(looper);\n    }\n    if (looper->getAllowNonCallbacks() != allowNonCallbacks) {\n        ALOGW(\"Looper already prepared for this thread with a different value for the \"\n                \"LOOPER_PREPARE_ALLOW_NON_CALLBACKS option.\");\n    }\n    return looper;\n}\n\nbool Looper::getAllowNonCallbacks() const {\n    return mAllowNonCallbacks;\n}\n\nvoid Looper::rebuildEpollLocked() {\n    // Close old epoll instance if we have one.\n    if (mEpollFd >= 0) {\n#if DEBUG_CALLBACKS\n        ALOGD(\"%p ~ rebuildEpollLocked - rebuilding epoll set\", this);\n#endif\n        close(mEpollFd);\n    }\n\n    // Allocate the new epoll instance and register the wake pipe.\n    mEpollFd = epoll_create(EPOLL_SIZE_HINT);\n    LOG_ALWAYS_FATAL_IF(mEpollFd < 0, \"Could not create epoll instance: %s\", strerror(errno));\n\n    struct epoll_event eventItem;\n    memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union\n    eventItem.events = EPOLLIN;\n    eventItem.data.fd = mWakeEventFd;\n    int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, & eventItem);\n    LOG_ALWAYS_FATAL_IF(result != 0, \"Could not add wake event fd to epoll instance: %s\",\n                        strerror(errno));\n\n    for (size_t i = 0; i < mRequests.size(); i++) {\n        const Request& request = mRequests.valueAt(i);\n        struct epoll_event eventItem;\n        request.initEventItem(&eventItem);\n\n        int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, request.fd, & eventItem);\n        if (epollResult < 0) {\n            ALOGE(\"Error adding epoll events for fd %d while rebuilding epoll set: %s\",\n                  request.fd, strerror(errno));\n        }\n    }\n}\n\nvoid Looper::scheduleEpollRebuildLocked() {\n    if (!mEpollRebuildRequired) {\n#if DEBUG_CALLBACKS\n        ALOGD(\"%p ~ scheduleEpollRebuildLocked - scheduling epoll set rebuild\", this);\n#endif\n        mEpollRebuildRequired = true;\n        wake();\n    }\n}\n\nint Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {\n    int result = 0;\n    for (;;) {\n        while (mResponseIndex < mResponses.size()) {\n            const Response& response = mResponses.itemAt(mResponseIndex++);\n            int ident = response.request.ident;\n            if (ident >= 0) {\n                int fd = response.request.fd;\n                int events = response.events;\n                void* data = response.request.data;\n#if DEBUG_POLL_AND_WAKE\n                ALOGD(\"%p ~ pollOnce - returning signalled identifier %d: \"\n                        \"fd=%d, events=0x%x, data=%p\",\n                        this, ident, fd, events, data);\n#endif\n                if (outFd != NULL) *outFd = fd;\n                if (outEvents != NULL) *outEvents = events;\n                if (outData != NULL) *outData = data;\n                return ident;\n            }\n        }\n\n        if (result != 0) {\n#if DEBUG_POLL_AND_WAKE\n            ALOGD(\"%p ~ pollOnce - returning result %d\", this, result);\n#endif\n            if (outFd != NULL) *outFd = 0;\n            if (outEvents != NULL) *outEvents = 0;\n            if (outData != NULL) *outData = NULL;\n            return result;\n        }\n\n        result = pollInner(timeoutMillis);\n    }\n}\n\nint Looper::pollInner(int timeoutMillis) {\n#if DEBUG_POLL_AND_WAKE\n    ALOGD(\"%p ~ pollOnce - waiting: timeoutMillis=%d\", this, timeoutMillis);\n#endif\n\n    // Adjust the timeout based on when the next message is due.\n    if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {\n        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);\n        int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);\n        if (messageTimeoutMillis >= 0\n                && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {\n            timeoutMillis = messageTimeoutMillis;\n        }\n#if DEBUG_POLL_AND_WAKE\n        ALOGD(\"%p ~ pollOnce - next message in %\" PRId64 \"ns, adjusted timeout: timeoutMillis=%d\",\n                this, mNextMessageUptime - now, timeoutMillis);\n#endif\n    }\n\n    // Poll.\n    int result = POLL_WAKE;\n    mResponses.clear();\n    mResponseIndex = 0;\n\n    // We are about to idle.\n    mPolling = true;\n\n    struct epoll_event eventItems[EPOLL_MAX_EVENTS];\n    int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);\n\n    // No longer idling.\n    mPolling = false;\n\n    // Acquire lock.\n    mLock.lock();\n\n    // Rebuild epoll set if needed.\n    if (mEpollRebuildRequired) {\n        mEpollRebuildRequired = false;\n        rebuildEpollLocked();\n        goto Done;\n    }\n\n    // Check for poll error.\n    if (eventCount < 0) {\n        if (errno == EINTR) {\n            goto Done;\n        }\n        ALOGW(\"Poll failed with an unexpected error: %s\", strerror(errno));\n        result = POLL_ERROR;\n        goto Done;\n    }\n\n    // Check for poll timeout.\n    if (eventCount == 0) {\n#if DEBUG_POLL_AND_WAKE\n        ALOGD(\"%p ~ pollOnce - timeout\", this);\n#endif\n        result = POLL_TIMEOUT;\n        goto Done;\n    }\n\n    // Handle all events.\n#if DEBUG_POLL_AND_WAKE\n    ALOGD(\"%p ~ pollOnce - handling events from %d fds\", this, eventCount);\n#endif\n\n    for (int i = 0; i < eventCount; i++) {\n        int fd = eventItems[i].data.fd;\n        uint32_t epollEvents = eventItems[i].events;\n        if (fd == mWakeEventFd) {\n            if (epollEvents & EPOLLIN) {\n                awoken();\n            } else {\n                ALOGW(\"Ignoring unexpected epoll events 0x%x on wake event fd.\", epollEvents);\n            }\n        } else {\n            ssize_t requestIndex = mRequests.indexOfKey(fd);\n            if (requestIndex >= 0) {\n                int events = 0;\n                if (epollEvents & EPOLLIN) events |= EVENT_INPUT;\n                if (epollEvents & EPOLLOUT) events |= EVENT_OUTPUT;\n                if (epollEvents & EPOLLERR) events |= EVENT_ERROR;\n                if (epollEvents & EPOLLHUP) events |= EVENT_HANGUP;\n                pushResponse(events, mRequests.valueAt(requestIndex));\n            } else {\n                ALOGW(\"Ignoring unexpected epoll events 0x%x on fd %d that is \"\n                        \"no longer registered.\", epollEvents, fd);\n            }\n        }\n    }\nDone: ;\n\n    // Invoke pending message callbacks.\n    mNextMessageUptime = LLONG_MAX;\n    while (mMessageEnvelopes.size() != 0) {\n        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);\n        const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);\n        if (messageEnvelope.uptime <= now) {\n            // Remove the envelope from the list.\n            // We keep a strong reference to the handler until the call to handleMessage\n            // finishes.  Then we drop it so that the handler can be deleted *before*\n            // we reacquire our lock.\n            { // obtain handler\n                sp<MessageHandler> handler = messageEnvelope.handler;\n                Message message = messageEnvelope.message;\n                mMessageEnvelopes.removeAt(0);\n                mSendingMessage = true;\n                mLock.unlock();\n\n#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS\n                ALOGD(\"%p ~ pollOnce - sending message: handler=%p, what=%d\",\n                        this, handler.get(), message.what);\n#endif\n                handler->handleMessage(message);\n            } // release handler\n\n            mLock.lock();\n            mSendingMessage = false;\n            result = POLL_CALLBACK;\n        } else {\n            // The last message left at the head of the queue determines the next wakeup time.\n            mNextMessageUptime = messageEnvelope.uptime;\n            break;\n        }\n    }\n\n    // Release lock.\n    mLock.unlock();\n\n    // Invoke all response callbacks.\n    for (size_t i = 0; i < mResponses.size(); i++) {\n        Response& response = mResponses.editItemAt(i);\n        if (response.request.ident == POLL_CALLBACK) {\n            int fd = response.request.fd;\n            int events = response.events;\n            void* data = response.request.data;\n#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS\n            ALOGD(\"%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p\",\n                    this, response.request.callback.get(), fd, events, data);\n#endif\n            // Invoke the callback.  Note that the file descriptor may be closed by\n            // the callback (and potentially even reused) before the function returns so\n            // we need to be a little careful when removing the file descriptor afterwards.\n            int callbackResult = response.request.callback->handleEvent(fd, events, data);\n            if (callbackResult == 0) {\n                removeFd(fd, response.request.seq);\n            }\n\n            // Clear the callback reference in the response structure promptly because we\n            // will not clear the response vector itself until the next poll.\n            response.request.callback.clear();\n            result = POLL_CALLBACK;\n        }\n    }\n    return result;\n}\n\nint Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) {\n    if (timeoutMillis <= 0) {\n        int result;\n        do {\n            result = pollOnce(timeoutMillis, outFd, outEvents, outData);\n        } while (result == POLL_CALLBACK);\n        return result;\n    } else {\n        nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC)\n                + milliseconds_to_nanoseconds(timeoutMillis);\n\n        for (;;) {\n            int result = pollOnce(timeoutMillis, outFd, outEvents, outData);\n            if (result != POLL_CALLBACK) {\n                return result;\n            }\n\n            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);\n            timeoutMillis = toMillisecondTimeoutDelay(now, endTime);\n            if (timeoutMillis == 0) {\n                return POLL_TIMEOUT;\n            }\n        }\n    }\n}\n\nvoid Looper::wake() {\n#if DEBUG_POLL_AND_WAKE\n    ALOGD(\"%p ~ wake\", this);\n#endif\n\n    uint64_t inc = 1;\n    ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &inc, sizeof(uint64_t)));\n    if (nWrite != sizeof(uint64_t)) {\n        if (errno != EAGAIN) {\n            ALOGW(\"Could not write wake signal: %s\", strerror(errno));\n        }\n    }\n}\n\nvoid Looper::awoken() {\n#if DEBUG_POLL_AND_WAKE\n    ALOGD(\"%p ~ awoken\", this);\n#endif\n\n    uint64_t counter;\n    TEMP_FAILURE_RETRY(read(mWakeEventFd, &counter, sizeof(uint64_t)));\n}\n\nvoid Looper::pushResponse(int events, const Request& request) {\n    Response response;\n    response.events = events;\n    response.request = request;\n    mResponses.push(response);\n}\n\nint Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) {\n    return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data);\n}\n\nint Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) {\n#if DEBUG_CALLBACKS\n    ALOGD(\"%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p\", this, fd, ident,\n            events, callback.get(), data);\n#endif\n\n    if (!callback.get()) {\n        if (! mAllowNonCallbacks) {\n            ALOGE(\"Invalid attempt to set NULL callback but not allowed for this looper.\");\n            return -1;\n        }\n\n        if (ident < 0) {\n            ALOGE(\"Invalid attempt to set NULL callback with ident < 0.\");\n            return -1;\n        }\n    } else {\n        ident = POLL_CALLBACK;\n    }\n\n    { // acquire lock\n        AutoMutex _l(mLock);\n\n        Request request;\n        request.fd = fd;\n        request.ident = ident;\n        request.events = events;\n        request.seq = mNextRequestSeq++;\n        request.callback = callback;\n        request.data = data;\n        if (mNextRequestSeq == -1) mNextRequestSeq = 0; // reserve sequence number -1\n\n        struct epoll_event eventItem;\n        request.initEventItem(&eventItem);\n\n        ssize_t requestIndex = mRequests.indexOfKey(fd);\n        if (requestIndex < 0) {\n            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);\n            if (epollResult < 0) {\n                ALOGE(\"Error adding epoll events for fd %d: %s\", fd, strerror(errno));\n                return -1;\n            }\n            mRequests.add(fd, request);\n        } else {\n            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem);\n            if (epollResult < 0) {\n                if (errno == ENOENT) {\n                    // Tolerate ENOENT because it means that an older file descriptor was\n                    // closed before its callback was unregistered and meanwhile a new\n                    // file descriptor with the same number has been created and is now\n                    // being registered for the first time.  This error may occur naturally\n                    // when a callback has the side-effect of closing the file descriptor\n                    // before returning and unregistering itself.  Callback sequence number\n                    // checks further ensure that the race is benign.\n                    //\n                    // Unfortunately due to kernel limitations we need to rebuild the epoll\n                    // set from scratch because it may contain an old file handle that we are\n                    // now unable to remove since its file descriptor is no longer valid.\n                    // No such problem would have occurred if we were using the poll system\n                    // call instead, but that approach carries others disadvantages.\n#if DEBUG_CALLBACKS\n                    ALOGD(\"%p ~ addFd - EPOLL_CTL_MOD failed due to file descriptor \"\n                            \"being recycled, falling back on EPOLL_CTL_ADD: %s\",\n                            this, strerror(errno));\n#endif\n                    epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);\n                    if (epollResult < 0) {\n                        ALOGE(\"Error modifying or adding epoll events for fd %d: %s\",\n                                fd, strerror(errno));\n                        return -1;\n                    }\n                    scheduleEpollRebuildLocked();\n                } else {\n                    ALOGE(\"Error modifying epoll events for fd %d: %s\", fd, strerror(errno));\n                    return -1;\n                }\n            }\n            mRequests.replaceValueAt(requestIndex, request);\n        }\n    } // release lock\n    return 1;\n}\n\nint Looper::removeFd(int fd) {\n    return removeFd(fd, -1);\n}\n\nint Looper::removeFd(int fd, int seq) {\n#if DEBUG_CALLBACKS\n    ALOGD(\"%p ~ removeFd - fd=%d, seq=%d\", this, fd, seq);\n#endif\n\n    { // acquire lock\n        AutoMutex _l(mLock);\n        ssize_t requestIndex = mRequests.indexOfKey(fd);\n        if (requestIndex < 0) {\n            return 0;\n        }\n\n        // Check the sequence number if one was given.\n        if (seq != -1 && mRequests.valueAt(requestIndex).seq != seq) {\n#if DEBUG_CALLBACKS\n            ALOGD(\"%p ~ removeFd - sequence number mismatch, oldSeq=%d\",\n                    this, mRequests.valueAt(requestIndex).seq);\n#endif\n            return 0;\n        }\n\n        // Always remove the FD from the request map even if an error occurs while\n        // updating the epoll set so that we avoid accidentally leaking callbacks.\n        mRequests.removeItemsAt(requestIndex);\n\n        int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL);\n        if (epollResult < 0) {\n            if (seq != -1 && (errno == EBADF || errno == ENOENT)) {\n                // Tolerate EBADF or ENOENT when the sequence number is known because it\n                // means that the file descriptor was closed before its callback was\n                // unregistered.  This error may occur naturally when a callback has the\n                // side-effect of closing the file descriptor before returning and\n                // unregistering itself.\n                //\n                // Unfortunately due to kernel limitations we need to rebuild the epoll\n                // set from scratch because it may contain an old file handle that we are\n                // now unable to remove since its file descriptor is no longer valid.\n                // No such problem would have occurred if we were using the poll system\n                // call instead, but that approach carries others disadvantages.\n#if DEBUG_CALLBACKS\n                ALOGD(\"%p ~ removeFd - EPOLL_CTL_DEL failed due to file descriptor \"\n                        \"being closed: %s\", this, strerror(errno));\n#endif\n                scheduleEpollRebuildLocked();\n            } else {\n                // Some other error occurred.  This is really weird because it means\n                // our list of callbacks got out of sync with the epoll set somehow.\n                // We defensively rebuild the epoll set to avoid getting spurious\n                // notifications with nowhere to go.\n                ALOGE(\"Error removing epoll events for fd %d: %s\", fd, strerror(errno));\n                scheduleEpollRebuildLocked();\n                return -1;\n            }\n        }\n    } // release lock\n    return 1;\n}\n\nvoid Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) {\n    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);\n    sendMessageAtTime(now, handler, message);\n}\n\nvoid Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,\n        const Message& message) {\n    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);\n    sendMessageAtTime(now + uptimeDelay, handler, message);\n}\n\nvoid Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,\n        const Message& message) {\n#if DEBUG_CALLBACKS\n    ALOGD(\"%p ~ sendMessageAtTime - uptime=%\" PRId64 \", handler=%p, what=%d\",\n            this, uptime, handler.get(), message.what);\n#endif\n\n    size_t i = 0;\n    { // acquire lock\n        AutoMutex _l(mLock);\n\n        size_t messageCount = mMessageEnvelopes.size();\n        while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) {\n            i += 1;\n        }\n\n        MessageEnvelope messageEnvelope(uptime, handler, message);\n        mMessageEnvelopes.insertAt(messageEnvelope, i, 1);\n\n        // Optimization: If the Looper is currently sending a message, then we can skip\n        // the call to wake() because the next thing the Looper will do after processing\n        // messages is to decide when the next wakeup time should be.  In fact, it does\n        // not even matter whether this code is running on the Looper thread.\n        if (mSendingMessage) {\n            return;\n        }\n    } // release lock\n\n    // Wake the poll loop only when we enqueue a new message at the head.\n    if (i == 0) {\n        wake();\n    }\n}\n\nvoid Looper::removeMessages(const sp<MessageHandler>& handler) {\n#if DEBUG_CALLBACKS\n    ALOGD(\"%p ~ removeMessages - handler=%p\", this, handler.get());\n#endif\n\n    { // acquire lock\n        AutoMutex _l(mLock);\n\n        for (size_t i = mMessageEnvelopes.size(); i != 0; ) {\n            const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i);\n            if (messageEnvelope.handler == handler) {\n                mMessageEnvelopes.removeAt(i);\n            }\n        }\n    } // release lock\n}\n\nvoid Looper::removeMessages(const sp<MessageHandler>& handler, int what) {\n#if DEBUG_CALLBACKS\n    ALOGD(\"%p ~ removeMessages - handler=%p, what=%d\", this, handler.get(), what);\n#endif\n\n    { // acquire lock\n        AutoMutex _l(mLock);\n\n        for (size_t i = mMessageEnvelopes.size(); i != 0; ) {\n            const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i);\n            if (messageEnvelope.handler == handler\n                    && messageEnvelope.message.what == what) {\n                mMessageEnvelopes.removeAt(i);\n            }\n        }\n    } // release lock\n}\n\nbool Looper::isPolling() const {\n    return mPolling;\n}\n\nvoid Looper::Request::initEventItem(struct epoll_event* eventItem) const {\n    int epollEvents = 0;\n    if (events & EVENT_INPUT) epollEvents |= EPOLLIN;\n    if (events & EVENT_OUTPUT) epollEvents |= EPOLLOUT;\n\n    memset(eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union\n    eventItem->events = epollEvents;\n    eventItem->data.fd = fd;\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/MODULE_LICENSE_APACHE2",
    "content": ""
  },
  {
    "path": "atlas-aapt/system/core/libutils/NOTICE",
    "content": "\n   Copyright (c) 2005-2008, The Android Open Source Project\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/NativeHandle.cpp",
    "content": "/*\n * Copyright 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <utils/NativeHandle.h>\n#include <cutils/native_handle.h>\n\nnamespace android {\n\nsp<NativeHandle> NativeHandle::create(\n        native_handle_t* handle, bool ownsHandle) {\n    return handle ? new NativeHandle(handle, ownsHandle) : NULL;\n}\n\nNativeHandle::NativeHandle(native_handle_t* handle, bool ownsHandle)\n:   mHandle(handle), mOwnsHandle(ownsHandle)\n{}\n\nNativeHandle::~NativeHandle() {\n    if (mOwnsHandle) {\n        native_handle_close(mHandle);\n        native_handle_delete(mHandle);\n    }\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/Printer.cpp",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"Printer\"\n// #define LOG_NDEBUG 0\n\n#include <utils/Printer.h>\n#include <utils/String8.h>\n#include <utils/Log.h>\n\n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n\nnamespace android {\n\n/*\n * Implementation of Printer\n */\nPrinter::Printer() {\n    // Intentionally left empty\n}\n\nPrinter::~Printer() {\n    // Intentionally left empty\n}\n\nvoid Printer::printFormatLine(const char* format, ...) {\n    va_list arglist;\n    va_start(arglist, format);\n\n    char* formattedString;\n\n#ifndef USE_MINGW\n    if (vasprintf(&formattedString, format, arglist) < 0) { // returns -1 on error\n        ALOGE(\"%s: Failed to format string\", __FUNCTION__);\n        return;\n    }\n#else\n    return;\n#endif\n\n    va_end(arglist);\n\n    printLine(formattedString);\n    free(formattedString);\n}\n\n/*\n * Implementation of LogPrinter\n */\nLogPrinter::LogPrinter(const char* logtag,\n                       android_LogPriority priority,\n                       const char* prefix,\n                       bool ignoreBlankLines) :\n        mLogTag(logtag),\n        mPriority(priority),\n        mPrefix(prefix ?: \"\"),\n        mIgnoreBlankLines(ignoreBlankLines) {\n}\n\nvoid LogPrinter::printLine(const char* string) {\n    if (string == NULL) {\n        ALOGW(\"%s: NULL string passed in\", __FUNCTION__);\n        return;\n    }\n\n    if (mIgnoreBlankLines || (*string)) {\n        // Simple case: Line is not blank, or we don't care about printing blank lines\n        printRaw(string);\n    } else {\n        // Force logcat to print empty lines by adding prefixing with a space\n        printRaw(\" \");\n    }\n}\n\nvoid LogPrinter::printRaw(const char* string) {\n    __android_log_print(mPriority, mLogTag, \"%s%s\", mPrefix, string);\n}\n\n\n/*\n * Implementation of FdPrinter\n */\nFdPrinter::FdPrinter(int fd, unsigned int indent, const char* prefix) :\n        mFd(fd), mIndent(indent), mPrefix(prefix ?: \"\") {\n\n    if (fd < 0) {\n        ALOGW(\"%s: File descriptor out of range (%d)\", __FUNCTION__, fd);\n    }\n\n    // <indent><prefix><line> -- e.g. '%-4s%s\\n' for indent=4\n    snprintf(mFormatString, sizeof(mFormatString), \"%%-%us%%s\\n\", mIndent);\n}\n\nvoid FdPrinter::printLine(const char* string) {\n    if (string == NULL) {\n        ALOGW(\"%s: NULL string passed in\", __FUNCTION__);\n        return;\n    } else if (mFd < 0) {\n        ALOGW(\"%s: File descriptor out of range (%d)\", __FUNCTION__, mFd);\n        return;\n    }\n\n#ifndef USE_MINGW\n    dprintf(mFd, mFormatString, mPrefix, string);\n#endif\n}\n\n/*\n * Implementation of String8Printer\n */\nString8Printer::String8Printer(String8* target, const char* prefix) :\n        mTarget(target),\n        mPrefix(prefix ?: \"\") {\n\n    if (target == NULL) {\n        ALOGW(\"%s: Target string was NULL\", __FUNCTION__);\n    }\n}\n\nvoid String8Printer::printLine(const char* string) {\n    if (string == NULL) {\n        ALOGW(\"%s: NULL string passed in\", __FUNCTION__);\n        return;\n    } else if (mTarget == NULL) {\n        ALOGW(\"%s: Target string was NULL\", __FUNCTION__);\n        return;\n    }\n\n    mTarget->append(mPrefix);\n    mTarget->append(string);\n    mTarget->append(\"\\n\");\n}\n\n/*\n * Implementation of PrefixPrinter\n */\nPrefixPrinter::PrefixPrinter(Printer& printer, const char* prefix) :\n        mPrinter(printer), mPrefix(prefix ?: \"\") {\n}\n\nvoid PrefixPrinter::printLine(const char* string) {\n    mPrinter.printFormatLine(\"%s%s\", mPrefix, string);\n}\n\n}; //namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/ProcessCallStack.cpp",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"ProcessCallStack\"\n// #define LOG_NDEBUG 0\n\n#include <dirent.h>\n#include <errno.h>\n#include <stdio.h>\n#include <string.h>\n\n#include <utils/Log.h>\n#include <utils/Errors.h>\n#include <utils/ProcessCallStack.h>\n#include <utils/Printer.h>\n\n#include <limits.h>\n\nnamespace android {\n\nenum {\n    // Max sizes for various dynamically generated strings\n    MAX_TIME_STRING = 64,\n    MAX_PROC_PATH = 1024,\n\n    // Dump related prettiness constants\n    IGNORE_DEPTH_CURRENT_THREAD = 2,\n};\n\nstatic const char* CALL_STACK_PREFIX = \"  \";\nstatic const char* PATH_THREAD_NAME = \"/proc/self/task/%d/comm\";\nstatic const char* PATH_SELF_TASK = \"/proc/self/task\";\n\nstatic void dumpProcessHeader(Printer& printer, pid_t pid, const char* timeStr) {\n    if (timeStr == NULL) {\n        ALOGW(\"%s: timeStr was NULL\", __FUNCTION__);\n        return;\n    }\n\n    char path[PATH_MAX];\n    char procNameBuf[MAX_PROC_PATH];\n    char* procName = NULL;\n    FILE* fp;\n\n    snprintf(path, sizeof(path), \"/proc/%d/cmdline\", pid);\n    if ((fp = fopen(path, \"r\"))) {\n        procName = fgets(procNameBuf, sizeof(procNameBuf), fp);\n        fclose(fp);\n    }\n\n    if (!procName) {\n        procName = const_cast<char*>(\"<unknown>\");\n    }\n\n    printer.printLine();\n    printer.printLine();\n    printer.printFormatLine(\"----- pid %d at %s -----\", pid, timeStr);\n    printer.printFormatLine(\"Cmd line: %s\", procName);\n}\n\nstatic void dumpProcessFooter(Printer& printer, pid_t pid) {\n    printer.printLine();\n    printer.printFormatLine(\"----- end %d -----\", pid);\n    printer.printLine();\n}\n\nstatic String8 getThreadName(pid_t tid) {\n    char path[PATH_MAX];\n    char* procName = NULL;\n    char procNameBuf[MAX_PROC_PATH];\n    FILE* fp;\n\n    snprintf(path, sizeof(path), PATH_THREAD_NAME, tid);\n    if ((fp = fopen(path, \"r\"))) {\n        procName = fgets(procNameBuf, sizeof(procNameBuf), fp);\n        fclose(fp);\n    } else {\n        ALOGE(\"%s: Failed to open %s\", __FUNCTION__, path);\n    }\n\n    if (procName == NULL) {\n        // Reading /proc/self/task/%d/comm failed due to a race\n        return String8::format(\"[err-unknown-tid-%d]\", tid);\n    }\n\n    // Strip ending newline\n    strtok(procName, \"\\n\");\n\n    return String8(procName);\n}\n\nstatic String8 getTimeString(struct tm tm) {\n    char timestr[MAX_TIME_STRING];\n    // i.e. '2013-10-22 14:42:05'\n    strftime(timestr, sizeof(timestr), \"%F %T\", &tm);\n\n    return String8(timestr);\n}\n\n/*\n * Implementation of ProcessCallStack\n */\nProcessCallStack::ProcessCallStack() {\n}\n\nProcessCallStack::ProcessCallStack(const ProcessCallStack& rhs) :\n        mThreadMap(rhs.mThreadMap),\n        mTimeUpdated(rhs.mTimeUpdated) {\n}\n\nProcessCallStack::~ProcessCallStack() {\n}\n\nvoid ProcessCallStack::clear() {\n    mThreadMap.clear();\n    mTimeUpdated = tm();\n}\n\nvoid ProcessCallStack::update() {\n    DIR *dp;\n    struct dirent *ep;\n    struct dirent entry;\n\n    dp = opendir(PATH_SELF_TASK);\n    if (dp == NULL) {\n        ALOGE(\"%s: Failed to update the process's call stacks: %s\",\n              __FUNCTION__, strerror(errno));\n        return;\n    }\n\n    pid_t selfPid = getpid();\n\n    clear();\n\n    // Get current time.\n    {\n        time_t t = time(NULL);\n        struct tm tm;\n        localtime_r(&t, &tm);\n\n        mTimeUpdated = tm;\n    }\n\n    /*\n     * Each tid is a directory inside of /proc/self/task\n     * - Read every file in directory => get every tid\n     */\n    int code;\n    while ((code = readdir_r(dp, &entry, &ep)) == 0 && ep != NULL) {\n        pid_t tid = -1;\n        sscanf(ep->d_name, \"%d\", &tid);\n\n        if (tid < 0) {\n            // Ignore '.' and '..'\n            ALOGV(\"%s: Failed to read tid from %s/%s\",\n                  __FUNCTION__, PATH_SELF_TASK, ep->d_name);\n            continue;\n        }\n\n        ssize_t idx = mThreadMap.add(tid, ThreadInfo());\n        if (idx < 0) { // returns negative error value on error\n            ALOGE(\"%s: Failed to add new ThreadInfo: %s\",\n                  __FUNCTION__, strerror(-idx));\n            continue;\n        }\n\n        ThreadInfo& threadInfo = mThreadMap.editValueAt(static_cast<size_t>(idx));\n\n        /*\n         * Ignore CallStack::update and ProcessCallStack::update for current thread\n         * - Every other thread doesn't need this since we call update off-thread\n         */\n        int ignoreDepth = (selfPid == tid) ? IGNORE_DEPTH_CURRENT_THREAD : 0;\n\n        // Update thread's call stacks\n        threadInfo.callStack.update(ignoreDepth, tid);\n\n        // Read/save thread name\n        threadInfo.threadName = getThreadName(tid);\n\n        ALOGV(\"%s: Got call stack for tid %d (size %zu)\",\n              __FUNCTION__, tid, threadInfo.callStack.size());\n    }\n    if (code != 0) { // returns positive error value on error\n        ALOGE(\"%s: Failed to readdir from %s: %s\",\n              __FUNCTION__, PATH_SELF_TASK, strerror(code));\n    }\n\n    closedir(dp);\n}\n\nvoid ProcessCallStack::log(const char* logtag, android_LogPriority priority,\n                           const char* prefix) const {\n    LogPrinter printer(logtag, priority, prefix, /*ignoreBlankLines*/false);\n    print(printer);\n}\n\nvoid ProcessCallStack::print(Printer& printer) const {\n    /*\n     * Print the header/footer with the regular printer.\n     * Print the callstack with an additional two spaces as the prefix for legibility.\n     */\n    PrefixPrinter csPrinter(printer, CALL_STACK_PREFIX);\n    printInternal(printer, csPrinter);\n}\n\nvoid ProcessCallStack::printInternal(Printer& printer, Printer& csPrinter) const {\n    dumpProcessHeader(printer, getpid(),\n                      getTimeString(mTimeUpdated).string());\n\n    for (size_t i = 0; i < mThreadMap.size(); ++i) {\n        pid_t tid = mThreadMap.keyAt(i);\n        const ThreadInfo& threadInfo = mThreadMap.valueAt(i);\n        const String8& threadName = threadInfo.threadName;\n\n        printer.printLine(\"\");\n        printer.printFormatLine(\"\\\"%s\\\" sysTid=%d\", threadName.string(), tid);\n\n        threadInfo.callStack.print(csPrinter);\n    }\n\n    dumpProcessFooter(printer, getpid());\n}\n\nvoid ProcessCallStack::dump(int fd, int indent, const char* prefix) const {\n\n    if (indent < 0) {\n        ALOGW(\"%s: Bad indent (%d)\", __FUNCTION__, indent);\n        return;\n    }\n\n    FdPrinter printer(fd, static_cast<unsigned int>(indent), prefix);\n    print(printer);\n}\n\nString8 ProcessCallStack::toString(const char* prefix) const {\n\n    String8 dest;\n    String8Printer printer(&dest, prefix);\n    print(printer);\n\n    return dest;\n}\n\nsize_t ProcessCallStack::size() const {\n    return mThreadMap.size();\n}\n\n}; //namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/PropertyMap.cpp",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"PropertyMap\"\n\n#include <stdlib.h>\n#include <string.h>\n\n#include <utils/PropertyMap.h>\n#include <utils/Log.h>\n\n// Enables debug output for the parser.\n#define DEBUG_PARSER 0\n\n// Enables debug output for parser performance.\n#define DEBUG_PARSER_PERFORMANCE 0\n\n\nnamespace android {\n\nstatic const char* WHITESPACE = \" \\t\\r\";\nstatic const char* WHITESPACE_OR_PROPERTY_DELIMITER = \" \\t\\r=\";\n\n\n// --- PropertyMap ---\n\nPropertyMap::PropertyMap() {\n}\n\nPropertyMap::~PropertyMap() {\n}\n\nvoid PropertyMap::clear() {\n    mProperties.clear();\n}\n\nvoid PropertyMap::addProperty(const String8& key, const String8& value) {\n    mProperties.add(key, value);\n}\n\nbool PropertyMap::hasProperty(const String8& key) const {\n    return mProperties.indexOfKey(key) >= 0;\n}\n\nbool PropertyMap::tryGetProperty(const String8& key, String8& outValue) const {\n    ssize_t index = mProperties.indexOfKey(key);\n    if (index < 0) {\n        return false;\n    }\n\n    outValue = mProperties.valueAt(index);\n    return true;\n}\n\nbool PropertyMap::tryGetProperty(const String8& key, bool& outValue) const {\n    int32_t intValue;\n    if (!tryGetProperty(key, intValue)) {\n        return false;\n    }\n\n    outValue = intValue;\n    return true;\n}\n\nbool PropertyMap::tryGetProperty(const String8& key, int32_t& outValue) const {\n    String8 stringValue;\n    if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {\n        return false;\n    }\n\n    char* end;\n    int value = strtol(stringValue.string(), & end, 10);\n    if (*end != '\\0') {\n        ALOGW(\"Property key '%s' has invalid value '%s'.  Expected an integer.\",\n                key.string(), stringValue.string());\n        return false;\n    }\n    outValue = value;\n    return true;\n}\n\nbool PropertyMap::tryGetProperty(const String8& key, float& outValue) const {\n    String8 stringValue;\n    if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {\n        return false;\n    }\n\n    char* end;\n    float value = strtof(stringValue.string(), & end);\n    if (*end != '\\0') {\n        ALOGW(\"Property key '%s' has invalid value '%s'.  Expected a float.\",\n                key.string(), stringValue.string());\n        return false;\n    }\n    outValue = value;\n    return true;\n}\n\nvoid PropertyMap::addAll(const PropertyMap* map) {\n    for (size_t i = 0; i < map->mProperties.size(); i++) {\n        mProperties.add(map->mProperties.keyAt(i), map->mProperties.valueAt(i));\n    }\n}\n\nstatus_t PropertyMap::load(const String8& filename, PropertyMap** outMap) {\n    *outMap = NULL;\n\n    Tokenizer* tokenizer;\n    status_t status = Tokenizer::open(filename, &tokenizer);\n    if (status) {\n        ALOGE(\"Error %d opening property file %s.\", status, filename.string());\n    } else {\n        PropertyMap* map = new PropertyMap();\n        if (!map) {\n            ALOGE(\"Error allocating property map.\");\n            status = NO_MEMORY;\n        } else {\n#if DEBUG_PARSER_PERFORMANCE\n            nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);\n#endif\n            Parser parser(map, tokenizer);\n            status = parser.parse();\n#if DEBUG_PARSER_PERFORMANCE\n            nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;\n            ALOGD(\"Parsed property file '%s' %d lines in %0.3fms.\",\n                    tokenizer->getFilename().string(), tokenizer->getLineNumber(),\n                    elapsedTime / 1000000.0);\n#endif\n            if (status) {\n                delete map;\n            } else {\n                *outMap = map;\n            }\n        }\n        delete tokenizer;\n    }\n    return status;\n}\n\n\n// --- PropertyMap::Parser ---\n\nPropertyMap::Parser::Parser(PropertyMap* map, Tokenizer* tokenizer) :\n        mMap(map), mTokenizer(tokenizer) {\n}\n\nPropertyMap::Parser::~Parser() {\n}\n\nstatus_t PropertyMap::Parser::parse() {\n    while (!mTokenizer->isEof()) {\n#if DEBUG_PARSER\n        ALOGD(\"Parsing %s: '%s'.\", mTokenizer->getLocation().string(),\n                mTokenizer->peekRemainderOfLine().string());\n#endif\n\n        mTokenizer->skipDelimiters(WHITESPACE);\n\n        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {\n            String8 keyToken = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);\n            if (keyToken.isEmpty()) {\n                ALOGE(\"%s: Expected non-empty property key.\", mTokenizer->getLocation().string());\n                return BAD_VALUE;\n            }\n\n            mTokenizer->skipDelimiters(WHITESPACE);\n\n            if (mTokenizer->nextChar() != '=') {\n                ALOGE(\"%s: Expected '=' between property key and value.\",\n                        mTokenizer->getLocation().string());\n                return BAD_VALUE;\n            }\n\n            mTokenizer->skipDelimiters(WHITESPACE);\n\n            String8 valueToken = mTokenizer->nextToken(WHITESPACE);\n            if (valueToken.find(\"\\\\\", 0) >= 0 || valueToken.find(\"\\\"\", 0) >= 0) {\n                ALOGE(\"%s: Found reserved character '\\\\' or '\\\"' in property value.\",\n                        mTokenizer->getLocation().string());\n                return BAD_VALUE;\n            }\n\n            mTokenizer->skipDelimiters(WHITESPACE);\n            if (!mTokenizer->isEol()) {\n                ALOGE(\"%s: Expected end of line, got '%s'.\",\n                        mTokenizer->getLocation().string(),\n                        mTokenizer->peekRemainderOfLine().string());\n                return BAD_VALUE;\n            }\n\n            if (mMap->hasProperty(keyToken)) {\n                ALOGE(\"%s: Duplicate property value for key '%s'.\",\n                        mTokenizer->getLocation().string(), keyToken.string());\n                return BAD_VALUE;\n            }\n\n            mMap->addProperty(keyToken, valueToken);\n        }\n\n        mTokenizer->nextLine();\n    }\n    return NO_ERROR;\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/README",
    "content": "Android Utility Function Library\n================================\n\n\nIf you need a feature that is native to Linux but not present on other\nplatforms, construct a platform-dependent implementation that shares\nthe Linux interface.  That way the actual device runs as \"light\" as\npossible.\n\nIf that isn't feasible, create a system-independent interface and hide\nthe details.\n\nThe ultimate goal is *not* to create a super-duper platform abstraction\nlayer.  The goal is to provide an optimized solution for Linux with\nreasonable implementations for other platforms.\n\n\n\nResource overlay\n================\n\n\nIntroduction\n------------\n\nOverlay packages are special .apk files which provide no code but\nadditional resource values (and possibly new configurations) for\nresources in other packages. When an application requests resources,\nthe system will return values from either the application's original\npackage or any associated overlay package. Any redirection is completely\ntransparent to the calling application.\n\nResource values have the following precedence table, listed in\ndescending precedence.\n\n * overlay package, matching config (eg res/values-en-land)\n\n * original package, matching config\n\n * overlay package, no config (eg res/values)\n\n * original package, no config\n\nDuring compilation, overlay packages are differentiated from regular\npackages by passing the -o flag to aapt.\n\n\nBackground\n----------\n\nThis section provides generic background material on resources in\nAndroid.\n\n\nHow resources are bundled in .apk files\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nAndroid .apk files are .zip files, usually housing .dex code,\ncertificates and resources, though packages containing resources but\nno code are possible. Resources can be divided into the following\ncategories; a `configuration' indicates a set of phone language, display\ndensity, network operator, etc.\n\n * assets: uncompressed, raw files packaged as part of an .apk and\n           explicitly referenced by filename. These files are\n           independent of configuration.\n\n * res/drawable: bitmap or xml graphics. Each file may have different\n                 values depending on configuration.\n\n * res/values: integers, strings, etc. Each resource may have different\n               values depending on configuration.\n\nResource meta information and information proper is stored in a binary\nformat in a named file resources.arsc, bundled as part of the .apk.\n\nResource IDs and lookup\n~~~~~~~~~~~~~~~~~~~~~~~\nDuring compilation, the aapt tool gathers application resources and\ngenerates a resources.arsc file. Each resource name is assigned an\ninteger ID 0xppttiii (translated to a symbolic name via R.java), where\n\n * pp: corresponds to the package namespace (details below).\n\n * tt: corresponds to the resource type (string, int, etc). Every\n       resource of the same type within the same package has the same\n       tt value, but depending on available types, the actual numerical\n       value may be different between packages.\n\n * iiii: sequential number, assigned in the order resources are found.\n\nResource values are specified paired with a set of configuration\nconstraints (the default being the empty set), eg res/values-sv-port\nwhich imposes restrictions on language (Swedish) and display orientation\n(portrait). During lookup, every constraint set is matched against the\ncurrent configuration, and the value corresponding to the best matching\nconstraint set is returned (ResourceTypes.{h,cpp}).\n\nParsing of resources.arsc is handled by ResourceTypes.cpp; this utility\nis governed by AssetManager.cpp, which tracks loaded resources per\nprocess.\n\nAssets are looked up by path and filename in AssetManager.cpp. The path\nto resources in res/drawable are located by ResourceTypes.cpp and then\nhandled like assets by AssetManager.cpp. Other resources are handled\nsolely by ResourceTypes.cpp.\n\nPackage ID as namespace\n~~~~~~~~~~~~~~~~~~~~~~~\nThe pp part of a resource ID defines a namespace. Android currently\ndefines two namespaces:\n\n * 0x01: system resources (pre-installed in framework-res.apk)\n\n * 0x7f: application resources (bundled in the application .apk)\n\nResourceTypes.cpp supports package IDs between 0x01 and 0x7f\n(inclusive); values outside this range are invalid.\n\nEach running (Dalvik) process is assigned a unique instance of\nAssetManager, which in turn keeps a forest structure of loaded\nresource.arsc files. Normally, this forest is structured as follows,\nwhere mPackageMap is the internal vector employed in ResourceTypes.cpp.\n\nmPackageMap[0x00] -> system package\nmPackageMap[0x01] -> NULL\nmPackageMap[0x02] -> NULL\n...\nmPackageMap[0x7f - 2] -> NULL\nmPackageMap[0x7f - 1] -> application package\n\n\n\nThe resource overlay extension\n------------------------------\n\nThe resource overlay mechanism aims to (partly) shadow and extend\nexisting resources with new values for defined and new configurations.\nTechnically, this is achieved by adding resource-only packages (called\noverlay packages) to existing resource namespaces, like so:\n\nmPackageMap[0x00] -> system package -> system overlay package\nmPackageMap[0x01] -> NULL\nmPackageMap[0x02] -> NULL\n...\nmPackageMap[0x7f - 2] -> NULL\nmPackageMap[0x7f - 1] -> application package -> overlay 1 -> overlay 2\n\nThe use of overlay resources is completely transparent to\napplications; no additional resource identifiers are introduced, only\nconfiguration/value pairs. Any number of overlay packages may be loaded\nat a time; overlay packages are agnostic to what they target -- both\nsystem and application resources are fair game.\n\nThe package targeted by an overlay package is called the target or\noriginal package.\n\nResource overlay operates on symbolic resources names. Hence, to\noverride the string/str1 resources in a package, the overlay package\nwould include a resource also named string/str1. The end user does not\nhave to worry about the numeric resources IDs assigned by aapt, as this\nis resolved automatically by the system.\n\nAs of this writing, the use of resource overlay has not been fully\nexplored. Until it has, only OEMs are trusted to use resource overlay.\nFor this reason, overlay packages must reside in /system/overlay.\n\n\nResource ID mapping\n~~~~~~~~~~~~~~~~~~~\nResource identifiers must be coherent within the same namespace (ie\nPackageGroup in ResourceTypes.cpp). Calling applications will refer to\nresources using the IDs defined in the original package, but there is no\nguarantee aapt has assigned the same ID to the corresponding resource in\nan overlay package. To translate between the two, a resource ID mapping\n{original ID -> overlay ID} is created during package installation\n(PackageManagerService.java) and used during resource lookup. The\nmapping is stored in /data/resource-cache, with a @idmap file name\nsuffix.\n\nThe idmap file format is documented in a separate section, below.\n\n\nPackage management\n~~~~~~~~~~~~~~~~~~\nPackages are managed by the PackageManagerService. Addition and removal\nof packages are monitored via the inotify framework, exposed via\nandroid.os.FileObserver.\n\nDuring initialization of a Dalvik process, ActivityThread.java requests\nthe process' AssetManager (by proxy, via AssetManager.java and JNI)\nto load a list of packages. This list includes overlay packages, if\npresent.\n\nWhen a target package or a corresponding overlay package is installed,\nthe target package's process is stopped and a new idmap is generated.\nThis is similar to how applications are stopped when their packages are\nupgraded.\n\n\nCreating overlay packages\n-------------------------\n\nOverlay packages should contain no code, define (some) resources with\nthe same type and name as in the original package, and be compiled with\nthe -o flag passed to aapt.\n\nThe aapt -o flag instructs aapt to create an overlay package.\nTechnically, this means the package will be assigned package id 0x00.\n\nThere are no restrictions on overlay packages names, though the naming\nconvention <original.package.name>.overlay.<name> is recommended.\n\n\nExample overlay package\n~~~~~~~~~~~~~~~~~~~~~~~\n\nTo overlay the resource bool/b in package com.foo.bar, to be applied\nwhen the display is in landscape mode, create a new package with\nno source code and a single .xml file under res/values-land, with\nan entry for bool/b. Compile with aapt -o and place the results in\n/system/overlay by adding the following to Android.mk:\n\nLOCAL_AAPT_FLAGS := -o com.foo.bar\nLOCAL_MODULE_PATH := $(TARGET_OUT)/overlay\n\n\nThe ID map (idmap) file format\n------------------------------\n\nThe idmap format is designed for lookup performance. However, leading\nand trailing undefined overlay values are discarded to reduce the memory\nfootprint.\n\n\nidmap grammar\n~~~~~~~~~~~~~\nAll atoms (names in square brackets) are uint32_t integers. The\nidmap-magic constant spells \"idmp\" in ASCII. Offsets are given relative\nto the data_header, not to the beginning of the file.\n\nmap          := header data\nheader       := idmap-magic <crc32-original-pkg> <crc32-overlay-pkg>\nidmap-magic  := <0x706d6469>\ndata         := data_header type_block+\ndata_header  := <m> header_block{m}\nheader_block := <0> | <type_block_offset>\ntype_block   := <n> <id_offset> entry{n}\nentry        := <resource_id_in_target_package>\n\n\nidmap example\n~~~~~~~~~~~~~\nGiven a pair of target and overlay packages with CRC sums 0x216a8fe2\nand 0x6b9beaec, each defining the following resources\n\nName          Target package  Overlay package\nstring/str0   0x7f010000      -\nstring/str1   0x7f010001      0x7f010000\nstring/str2   0x7f010002      -\nstring/str3   0x7f010003      0x7f010001\nstring/str4   0x7f010004      -\nbool/bool0    0x7f020000      -\ninteger/int0  0x7f030000      0x7f020000\ninteger/int1  0x7f030001      -\n\nthe corresponding resource map is\n\n0x706d6469 0x216a8fe2 0x6b9beaec 0x00000003 \\\n0x00000004 0x00000000 0x00000009 0x00000003 \\\n0x00000001 0x7f010000 0x00000000 0x7f010001 \\\n0x00000001 0x00000000 0x7f020000\n\nor, formatted differently\n\n0x706d6469  # magic: all idmap files begin with this constant\n0x216a8fe2  # CRC32 of the resources.arsc file in the original package\n0x6b9beaec  # CRC32 of the resources.arsc file in the overlay package\n0x00000003  # header; three types (string, bool, integer) in the target package\n0x00000004  #   header_block for type 0 (string) is located at offset 4\n0x00000000  #   no bool type exists in overlay package -> no header_block\n0x00000009  #   header_block for type 2 (integer) is located at offset 9\n0x00000003  # header_block for string; overlay IDs span 3 elements\n0x00000001  #   the first string in target package is entry 1 == offset\n0x7f010000  #   target 0x7f01001 -> overlay 0x7f010000\n0x00000000  #   str2 not defined in overlay package\n0x7f010001  #   target 0x7f010003 -> overlay 0x7f010001\n0x00000001  # header_block for integer; overlay IDs span 1 element\n0x00000000  #   offset == 0\n0x7f020000  #   target 0x7f030000 -> overlay 0x7f020000\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/RefBase.cpp",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"RefBase\"\n// #define LOG_NDEBUG 0\n\n#include <fcntl.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <typeinfo>\n#include <unistd.h>\n\n#include <utils/RefBase.h>\n\n#include <utils/CallStack.h>\n#include <utils/Log.h>\n#include <utils/threads.h>\n\n#ifndef __unused\n#define __unused __attribute__((__unused__))\n#endif\n\n// compile with refcounting debugging enabled\n#define DEBUG_REFS                      0\n\n// whether ref-tracking is enabled by default, if not, trackMe(true, false)\n// needs to be called explicitly\n#define DEBUG_REFS_ENABLED_BY_DEFAULT   0\n\n// whether callstack are collected (significantly slows things down)\n#define DEBUG_REFS_CALLSTACK_ENABLED    1\n\n// folder where stack traces are saved when DEBUG_REFS is enabled\n// this folder needs to exist and be writable\n#define DEBUG_REFS_CALLSTACK_PATH       \"/data/debug\"\n\n// log all reference counting operations\n#define PRINT_REFS                      0\n\n// ---------------------------------------------------------------------------\n\nnamespace android {\n\n// Usage, invariants, etc:\n\n// It is normally OK just to keep weak pointers to an object.  The object will\n// be deallocated by decWeak when the last weak reference disappears.\n// Once a a strong reference has been created, the object will disappear once\n// the last strong reference does (decStrong).\n// AttemptIncStrong will succeed if the object has a strong reference, or if it\n// has a weak reference and has never had a strong reference.\n// AttemptIncWeak really does succeed only if there is already a WEAK\n// reference, and thus may fail when attemptIncStrong would succeed.\n// OBJECT_LIFETIME_WEAK changes this behavior to retain the object\n// unconditionally until the last reference of either kind disappears.  The\n// client ensures that the extendObjectLifetime call happens before the dec\n// call that would otherwise have deallocated the object, or before an\n// attemptIncStrong call that might rely on it.  We do not worry about\n// concurrent changes to the object lifetime.\n// mStrong is the strong reference count.  mWeak is the weak reference count.\n// Between calls, and ignoring memory ordering effects, mWeak includes strong\n// references, and is thus >= mStrong.\n//\n// A weakref_impl is allocated as the value of mRefs in a RefBase object on\n// construction.\n// In the OBJECT_LIFETIME_STRONG case, it is deallocated in the RefBase\n// destructor iff the strong reference count was never incremented. The\n// destructor can be invoked either from decStrong, or from decWeak if there\n// was never a strong reference. If the reference count had been incremented,\n// it is deallocated directly in decWeak, and hence still lives as long as\n// the last weak reference.\n// In the OBJECT_LIFETIME_WEAK case, it is always deallocated from the RefBase\n// destructor, which is always invoked by decWeak. DecStrong explicitly avoids\n// the deletion in this case.\n//\n// Memory ordering:\n// The client must ensure that every inc() call, together with all other\n// accesses to the object, happens before the corresponding dec() call.\n//\n// We try to keep memory ordering constraints on atomics as weak as possible,\n// since memory fences or ordered memory accesses are likely to be a major\n// performance cost for this code. All accesses to mStrong, mWeak, and mFlags\n// explicitly relax memory ordering in some way.\n//\n// The only operations that are not memory_order_relaxed are reference count\n// decrements. All reference count decrements are release operations.  In\n// addition, the final decrement leading the deallocation is followed by an\n// acquire fence, which we can view informally as also turning it into an\n// acquire operation.  (See 29.8p4 [atomics.fences] for details. We could\n// alternatively use acq_rel operations for all decrements. This is probably\n// slower on most current (2016) hardware, especially on ARMv7, but that may\n// not be true indefinitely.)\n//\n// This convention ensures that the second-to-last decrement synchronizes with\n// (in the language of 1.10 in the C++ standard) the final decrement of a\n// reference count. Since reference counts are only updated using atomic\n// read-modify-write operations, this also extends to any earlier decrements.\n// (See \"release sequence\" in 1.10.)\n//\n// Since all operations on an object happen before the corresponding reference\n// count decrement, and all reference count decrements happen before the final\n// one, we are guaranteed that all other object accesses happen before the\n// object is destroyed.\n\n\n#define INITIAL_STRONG_VALUE (1<<28)\n\n// ---------------------------------------------------------------------------\n\nclass RefBase::weakref_impl : public RefBase::weakref_type\n{\npublic:\n    std::atomic<int32_t>    mStrong;\n    std::atomic<int32_t>    mWeak;\n    RefBase* const          mBase;\n    std::atomic<int32_t>    mFlags;\n\n#if !DEBUG_REFS\n\n    weakref_impl(RefBase* base)\n        : mStrong(INITIAL_STRONG_VALUE)\n        , mWeak(0)\n        , mBase(base)\n        , mFlags(0)\n    {\n    }\n\n    void addStrongRef(const void* /*id*/) { }\n    void removeStrongRef(const void* /*id*/) { }\n    void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { }\n    void addWeakRef(const void* /*id*/) { }\n    void removeWeakRef(const void* /*id*/) { }\n    void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { }\n    void printRefs() const { }\n    void trackMe(bool, bool) { }\n\n#else\n\n    weakref_impl(RefBase* base)\n        : mStrong(INITIAL_STRONG_VALUE)\n        , mWeak(0)\n        , mBase(base)\n        , mFlags(0)\n        , mStrongRefs(NULL)\n        , mWeakRefs(NULL)\n        , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)\n        , mRetain(false)\n    {\n    }\n    \n    ~weakref_impl()\n    {\n        bool dumpStack = false;\n        if (!mRetain && mStrongRefs != NULL) {\n            dumpStack = true;\n            ALOGE(\"Strong references remain:\");\n            ref_entry* refs = mStrongRefs;\n            while (refs) {\n                char inc = refs->ref >= 0 ? '+' : '-';\n                ALOGD(\"\\t%c ID %p (ref %d):\", inc, refs->id, refs->ref);\n#if DEBUG_REFS_CALLSTACK_ENABLED\n                refs->stack.log(LOG_TAG);\n#endif\n                refs = refs->next;\n            }\n        }\n\n        if (!mRetain && mWeakRefs != NULL) {\n            dumpStack = true;\n            ALOGE(\"Weak references remain!\");\n            ref_entry* refs = mWeakRefs;\n            while (refs) {\n                char inc = refs->ref >= 0 ? '+' : '-';\n                ALOGD(\"\\t%c ID %p (ref %d):\", inc, refs->id, refs->ref);\n#if DEBUG_REFS_CALLSTACK_ENABLED\n                refs->stack.log(LOG_TAG);\n#endif\n                refs = refs->next;\n            }\n        }\n        if (dumpStack) {\n            ALOGE(\"above errors at:\");\n            CallStack stack(LOG_TAG);\n        }\n    }\n\n    void addStrongRef(const void* id) {\n        //ALOGD_IF(mTrackEnabled,\n        //        \"addStrongRef: RefBase=%p, id=%p\", mBase, id);\n        addRef(&mStrongRefs, id, mStrong.load(std::memory_order_relaxed));\n    }\n\n    void removeStrongRef(const void* id) {\n        //ALOGD_IF(mTrackEnabled,\n        //        \"removeStrongRef: RefBase=%p, id=%p\", mBase, id);\n        if (!mRetain) {\n            removeRef(&mStrongRefs, id);\n        } else {\n            addRef(&mStrongRefs, id, -mStrong.load(std::memory_order_relaxed));\n        }\n    }\n\n    void renameStrongRefId(const void* old_id, const void* new_id) {\n        //ALOGD_IF(mTrackEnabled,\n        //        \"renameStrongRefId: RefBase=%p, oid=%p, nid=%p\",\n        //        mBase, old_id, new_id);\n        renameRefsId(mStrongRefs, old_id, new_id);\n    }\n\n    void addWeakRef(const void* id) {\n        addRef(&mWeakRefs, id, mWeak.load(std::memory_order_relaxed));\n    }\n\n    void removeWeakRef(const void* id) {\n        if (!mRetain) {\n            removeRef(&mWeakRefs, id);\n        } else {\n            addRef(&mWeakRefs, id, -mWeak.load(std::memory_order_relaxed));\n        }\n    }\n\n    void renameWeakRefId(const void* old_id, const void* new_id) {\n        renameRefsId(mWeakRefs, old_id, new_id);\n    }\n\n    void trackMe(bool track, bool retain)\n    { \n        mTrackEnabled = track;\n        mRetain = retain;\n    }\n\n    void printRefs() const\n    {\n        String8 text;\n\n        {\n            Mutex::Autolock _l(mMutex);\n            char buf[128];\n            sprintf(buf, \"Strong references on RefBase %p (weakref_type %p):\\n\", mBase, this);\n            text.append(buf);\n            printRefsLocked(&text, mStrongRefs);\n            sprintf(buf, \"Weak references on RefBase %p (weakref_type %p):\\n\", mBase, this);\n            text.append(buf);\n            printRefsLocked(&text, mWeakRefs);\n        }\n\n        {\n            char name[100];\n            snprintf(name, 100, DEBUG_REFS_CALLSTACK_PATH \"/%p.stack\", this);\n            int rc = open(name, O_RDWR | O_CREAT | O_APPEND, 644);\n            if (rc >= 0) {\n                write(rc, text.string(), text.length());\n                close(rc);\n                ALOGD(\"STACK TRACE for %p saved in %s\", this, name);\n            }\n            else ALOGE(\"FAILED TO PRINT STACK TRACE for %p in %s: %s\", this,\n                      name, strerror(errno));\n        }\n    }\n\nprivate:\n    struct ref_entry\n    {\n        ref_entry* next;\n        const void* id;\n#if DEBUG_REFS_CALLSTACK_ENABLED\n        CallStack stack;\n#endif\n        int32_t ref;\n    };\n\n    void addRef(ref_entry** refs, const void* id, int32_t mRef)\n    {\n        if (mTrackEnabled) {\n            AutoMutex _l(mMutex);\n\n            ref_entry* ref = new ref_entry;\n            // Reference count at the time of the snapshot, but before the\n            // update.  Positive value means we increment, negative--we\n            // decrement the reference count.\n            ref->ref = mRef;\n            ref->id = id;\n#if DEBUG_REFS_CALLSTACK_ENABLED\n            ref->stack.update(2);\n#endif\n            ref->next = *refs;\n            *refs = ref;\n        }\n    }\n\n    void removeRef(ref_entry** refs, const void* id)\n    {\n        if (mTrackEnabled) {\n            AutoMutex _l(mMutex);\n            \n            ref_entry* const head = *refs;\n            ref_entry* ref = head;\n            while (ref != NULL) {\n                if (ref->id == id) {\n                    *refs = ref->next;\n                    delete ref;\n                    return;\n                }\n                refs = &ref->next;\n                ref = *refs;\n            }\n\n            ALOGE(\"RefBase: removing id %p on RefBase %p\"\n                    \"(weakref_type %p) that doesn't exist!\",\n                    id, mBase, this);\n\n            ref = head;\n            while (ref) {\n                char inc = ref->ref >= 0 ? '+' : '-';\n                ALOGD(\"\\t%c ID %p (ref %d):\", inc, ref->id, ref->ref);\n                ref = ref->next;\n            }\n\n            CallStack stack(LOG_TAG);\n        }\n    }\n\n    void renameRefsId(ref_entry* r, const void* old_id, const void* new_id)\n    {\n        if (mTrackEnabled) {\n            AutoMutex _l(mMutex);\n            ref_entry* ref = r;\n            while (ref != NULL) {\n                if (ref->id == old_id) {\n                    ref->id = new_id;\n                }\n                ref = ref->next;\n            }\n        }\n    }\n\n    void printRefsLocked(String8* out, const ref_entry* refs) const\n    {\n        char buf[128];\n        while (refs) {\n            char inc = refs->ref >= 0 ? '+' : '-';\n            sprintf(buf, \"\\t%c ID %p (ref %d):\\n\", \n                    inc, refs->id, refs->ref);\n            out->append(buf);\n#if DEBUG_REFS_CALLSTACK_ENABLED\n            out->append(refs->stack.toString(\"\\t\\t\"));\n#else\n            out->append(\"\\t\\t(call stacks disabled)\");\n#endif\n            refs = refs->next;\n        }\n    }\n\n    mutable Mutex mMutex;\n    ref_entry* mStrongRefs;\n    ref_entry* mWeakRefs;\n\n    bool mTrackEnabled;\n    // Collect stack traces on addref and removeref, instead of deleting the stack references\n    // on removeref that match the address ones.\n    bool mRetain;\n\n#endif\n};\n\n// ---------------------------------------------------------------------------\n\nvoid RefBase::incStrong(const void* id) const\n{\n    weakref_impl* const refs = mRefs;\n    refs->incWeak(id);\n    \n    refs->addStrongRef(id);\n    const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed);\n    ALOG_ASSERT(c > 0, \"incStrong() called on %p after last strong ref\", refs);\n#if PRINT_REFS\n    ALOGD(\"incStrong of %p from %p: cnt=%d\\n\", this, id, c);\n#endif\n    if (c != INITIAL_STRONG_VALUE)  {\n        return;\n    }\n\n    int32_t old = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE,\n            std::memory_order_relaxed);\n    // A decStrong() must still happen after us.\n    ALOG_ASSERT(old > INITIAL_STRONG_VALUE, \"0x%x too small\", old);\n    refs->mBase->onFirstRef();\n}\n\nvoid RefBase::decStrong(const void* id) const\n{\n    weakref_impl* const refs = mRefs;\n    refs->removeStrongRef(id);\n    const int32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release);\n#if PRINT_REFS\n    ALOGD(\"decStrong of %p from %p: cnt=%d\\n\", this, id, c);\n#endif\n    ALOG_ASSERT(c >= 1, \"decStrong() called on %p too many times\", refs);\n    if (c == 1) {\n        std::atomic_thread_fence(std::memory_order_acquire);\n        refs->mBase->onLastStrongRef(id);\n        int32_t flags = refs->mFlags.load(std::memory_order_relaxed);\n        if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {\n            delete this;\n            // Since mStrong had been incremented, the destructor did not\n            // delete refs.\n        }\n    }\n    // Note that even with only strong reference operations, the thread\n    // deallocating this may not be the same as the thread deallocating refs.\n    // That's OK: all accesses to this happen before its deletion here,\n    // and all accesses to refs happen before its deletion in the final decWeak.\n    // The destructor can safely access mRefs because either it's deleting\n    // mRefs itself, or it's running entirely before the final mWeak decrement.\n    refs->decWeak(id);\n}\n\nvoid RefBase::forceIncStrong(const void* id) const\n{\n    // Allows initial mStrong of 0 in addition to INITIAL_STRONG_VALUE.\n    // TODO: Better document assumptions.\n    weakref_impl* const refs = mRefs;\n    refs->incWeak(id);\n    \n    refs->addStrongRef(id);\n    const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed);\n    ALOG_ASSERT(c >= 0, \"forceIncStrong called on %p after ref count underflow\",\n               refs);\n#if PRINT_REFS\n    ALOGD(\"forceIncStrong of %p from %p: cnt=%d\\n\", this, id, c);\n#endif\n\n    switch (c) {\n    case INITIAL_STRONG_VALUE:\n        refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE,\n                std::memory_order_relaxed);\n        // fall through...\n    case 0:\n        refs->mBase->onFirstRef();\n    }\n}\n\nint32_t RefBase::getStrongCount() const\n{\n    // Debugging only; No memory ordering guarantees.\n    return mRefs->mStrong.load(std::memory_order_relaxed);\n}\n\nRefBase* RefBase::weakref_type::refBase() const\n{\n    return static_cast<const weakref_impl*>(this)->mBase;\n}\n\nvoid RefBase::weakref_type::incWeak(const void* id)\n{\n    weakref_impl* const impl = static_cast<weakref_impl*>(this);\n    impl->addWeakRef(id);\n    const int32_t c __unused = impl->mWeak.fetch_add(1,\n            std::memory_order_relaxed);\n    ALOG_ASSERT(c >= 0, \"incWeak called on %p after last weak ref\", this);\n}\n\n\nvoid RefBase::weakref_type::decWeak(const void* id)\n{\n    weakref_impl* const impl = static_cast<weakref_impl*>(this);\n    impl->removeWeakRef(id);\n    const int32_t c = impl->mWeak.fetch_sub(1, std::memory_order_release);\n    ALOG_ASSERT(c >= 1, \"decWeak called on %p too many times\", this);\n    if (c != 1) return;\n    atomic_thread_fence(std::memory_order_acquire);\n\n    int32_t flags = impl->mFlags.load(std::memory_order_relaxed);\n    if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {\n        // This is the regular lifetime case. The object is destroyed\n        // when the last strong reference goes away. Since weakref_impl\n        // outlive the object, it is not destroyed in the dtor, and\n        // we'll have to do it here.\n        if (impl->mStrong.load(std::memory_order_relaxed)\n                == INITIAL_STRONG_VALUE) {\n            // Special case: we never had a strong reference, so we need to\n            // destroy the object now.\n            delete impl->mBase;\n        } else {\n            // ALOGV(\"Freeing refs %p of old RefBase %p\\n\", this, impl->mBase);\n            delete impl;\n        }\n    } else {\n        // This is the OBJECT_LIFETIME_WEAK case. The last weak-reference\n        // is gone, we can destroy the object.\n        impl->mBase->onLastWeakRef(id);\n        delete impl->mBase;\n    }\n}\n\nbool RefBase::weakref_type::attemptIncStrong(const void* id)\n{\n    incWeak(id);\n    \n    weakref_impl* const impl = static_cast<weakref_impl*>(this);\n    int32_t curCount = impl->mStrong.load(std::memory_order_relaxed);\n\n    ALOG_ASSERT(curCount >= 0,\n            \"attemptIncStrong called on %p after underflow\", this);\n\n    while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {\n        // we're in the easy/common case of promoting a weak-reference\n        // from an existing strong reference.\n        if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,\n                std::memory_order_relaxed)) {\n            break;\n        }\n        // the strong count has changed on us, we need to re-assert our\n        // situation. curCount was updated by compare_exchange_weak.\n    }\n    \n    if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {\n        // we're now in the harder case of either:\n        // - there never was a strong reference on us\n        // - or, all strong references have been released\n        int32_t flags = impl->mFlags.load(std::memory_order_relaxed);\n        if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {\n            // this object has a \"normal\" life-time, i.e.: it gets destroyed\n            // when the last strong reference goes away\n            if (curCount <= 0) {\n                // the last strong-reference got released, the object cannot\n                // be revived.\n                decWeak(id);\n                return false;\n            }\n\n            // here, curCount == INITIAL_STRONG_VALUE, which means\n            // there never was a strong-reference, so we can try to\n            // promote this object; we need to do that atomically.\n            while (curCount > 0) {\n                if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,\n                        std::memory_order_relaxed)) {\n                    break;\n                }\n                // the strong count has changed on us, we need to re-assert our\n                // situation (e.g.: another thread has inc/decStrong'ed us)\n                // curCount has been updated.\n            }\n\n            if (curCount <= 0) {\n                // promote() failed, some other thread destroyed us in the\n                // meantime (i.e.: strong count reached zero).\n                decWeak(id);\n                return false;\n            }\n        } else {\n            // this object has an \"extended\" life-time, i.e.: it can be\n            // revived from a weak-reference only.\n            // Ask the object's implementation if it agrees to be revived\n            if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) {\n                // it didn't so give-up.\n                decWeak(id);\n                return false;\n            }\n            // grab a strong-reference, which is always safe due to the\n            // extended life-time.\n            curCount = impl->mStrong.fetch_add(1, std::memory_order_relaxed);\n        }\n\n        // If the strong reference count has already been incremented by\n        // someone else, the implementor of onIncStrongAttempted() is holding\n        // an unneeded reference.  So call onLastStrongRef() here to remove it.\n        // (No, this is not pretty.)  Note that we MUST NOT do this if we\n        // are in fact acquiring the first reference.\n        if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {\n            impl->mBase->onLastStrongRef(id);\n        }\n    }\n    \n    impl->addStrongRef(id);\n\n#if PRINT_REFS\n    ALOGD(\"attemptIncStrong of %p from %p: cnt=%d\\n\", this, id, curCount);\n#endif\n\n    // curCount is the value of mStrong before we increment ed it.\n    // Now we need to fix-up the count if it was INITIAL_STRONG_VALUE.\n    // This must be done safely, i.e.: handle the case where several threads\n    // were here in attemptIncStrong().\n    // curCount > INITIAL_STRONG_VALUE is OK, and can happen if we're doing\n    // this in the middle of another incStrong.  The subtraction is handled\n    // by the thread that started with INITIAL_STRONG_VALUE.\n    if (curCount == INITIAL_STRONG_VALUE) {\n        impl->mStrong.fetch_sub(INITIAL_STRONG_VALUE,\n                std::memory_order_relaxed);\n    }\n\n    return true;\n}\n\nbool RefBase::weakref_type::attemptIncWeak(const void* id)\n{\n    weakref_impl* const impl = static_cast<weakref_impl*>(this);\n\n    int32_t curCount = impl->mWeak.load(std::memory_order_relaxed);\n    ALOG_ASSERT(curCount >= 0, \"attemptIncWeak called on %p after underflow\",\n               this);\n    while (curCount > 0) {\n        if (impl->mWeak.compare_exchange_weak(curCount, curCount+1,\n                std::memory_order_relaxed)) {\n            break;\n        }\n        // curCount has been updated.\n    }\n\n    if (curCount > 0) {\n        impl->addWeakRef(id);\n    }\n\n    return curCount > 0;\n}\n\nint32_t RefBase::weakref_type::getWeakCount() const\n{\n    // Debug only!\n    return static_cast<const weakref_impl*>(this)->mWeak\n            .load(std::memory_order_relaxed);\n}\n\nvoid RefBase::weakref_type::printRefs() const\n{\n    static_cast<const weakref_impl*>(this)->printRefs();\n}\n\nvoid RefBase::weakref_type::trackMe(bool enable, bool retain)\n{\n    static_cast<weakref_impl*>(this)->trackMe(enable, retain);\n}\n\nRefBase::weakref_type* RefBase::createWeak(const void* id) const\n{\n    mRefs->incWeak(id);\n    return mRefs;\n}\n\nRefBase::weakref_type* RefBase::getWeakRefs() const\n{\n    return mRefs;\n}\n\nRefBase::RefBase()\n    : mRefs(new weakref_impl(this))\n{\n}\n\nRefBase::~RefBase()\n{\n    if (mRefs->mStrong.load(std::memory_order_relaxed)\n            == INITIAL_STRONG_VALUE) {\n        // we never acquired a strong (and/or weak) reference on this object.\n        delete mRefs;\n    } else {\n        // life-time of this object is extended to WEAK, in\n        // which case weakref_impl doesn't out-live the object and we\n        // can free it now.\n        int32_t flags = mRefs->mFlags.load(std::memory_order_relaxed);\n        if ((flags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) {\n            // It's possible that the weak count is not 0 if the object\n            // re-acquired a weak reference in its destructor\n            if (mRefs->mWeak.load(std::memory_order_relaxed) == 0) {\n                delete mRefs;\n            }\n        }\n    }\n    // for debugging purposes, clear this.\n    const_cast<weakref_impl*&>(mRefs) = NULL;\n}\n\nvoid RefBase::extendObjectLifetime(int32_t mode)\n{\n    // Must be happens-before ordered with respect to construction or any\n    // operation that could destroy the object.\n    mRefs->mFlags.fetch_or(mode, std::memory_order_relaxed);\n}\n\nvoid RefBase::onFirstRef()\n{\n}\n\nvoid RefBase::onLastStrongRef(const void* /*id*/)\n{\n}\n\nbool RefBase::onIncStrongAttempted(uint32_t flags, const void* /*id*/)\n{\n    return (flags&FIRST_INC_STRONG) ? true : false;\n}\n\nvoid RefBase::onLastWeakRef(const void* /*id*/)\n{\n}\n\n// ---------------------------------------------------------------------------\n\n#if DEBUG_REFS\nvoid RefBase::renameRefs(size_t n, const ReferenceRenamer& renamer) {\n    for (size_t i=0 ; i<n ; i++) {\n        renamer(i);\n    }\n}\n#else\nvoid RefBase::renameRefs(size_t /*n*/, const ReferenceRenamer& /*renamer*/) { }\n#endif\n\nvoid RefBase::renameRefId(weakref_type* ref,\n        const void* old_id, const void* new_id) {\n    weakref_impl* const impl = static_cast<weakref_impl*>(ref);\n    impl->renameStrongRefId(old_id, new_id);\n    impl->renameWeakRefId(old_id, new_id);\n}\n\nvoid RefBase::renameRefId(RefBase* ref,\n        const void* old_id, const void* new_id) {\n    ref->mRefs->renameStrongRefId(old_id, new_id);\n    ref->mRefs->renameWeakRefId(old_id, new_id);\n}\n\n}; // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/SharedBuffer.cpp",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <stdlib.h>\n#include <string.h>\n\n#include <log/log.h>\n\n#include \"SharedBuffer.h\"\n\n// ---------------------------------------------------------------------------\n\nnamespace android {\n\nSharedBuffer* SharedBuffer::alloc(size_t size)\n{\n    // Don't overflow if the combined size of the buffer / header is larger than\n    // size_max.\n    LOG_ALWAYS_FATAL_IF((size >= (SIZE_MAX - sizeof(SharedBuffer))),\n                        \"Invalid buffer size %zu\", size);\n\n    SharedBuffer* sb = static_cast<SharedBuffer *>(malloc(sizeof(SharedBuffer) + size));\n    if (sb) {\n        // Should be std::atomic_init(&sb->mRefs, 1);\n        // But that generates a warning with some compilers.\n        // The following is OK on Android-supported platforms.\n        sb->mRefs.store(1, std::memory_order_relaxed);\n        sb->mSize = size;\n    }\n    return sb;\n}\n\n\nvoid SharedBuffer::dealloc(const SharedBuffer* released)\n{\n    free(const_cast<SharedBuffer*>(released));\n}\n\nSharedBuffer* SharedBuffer::edit() const\n{\n    if (onlyOwner()) {\n        return const_cast<SharedBuffer*>(this);\n    }\n    SharedBuffer* sb = alloc(mSize);\n    if (sb) {\n        memcpy(sb->data(), data(), size());\n        release();\n    }\n    return sb;\n}\n\nSharedBuffer* SharedBuffer::editResize(size_t newSize) const\n{\n    if (onlyOwner()) {\n        SharedBuffer* buf = const_cast<SharedBuffer*>(this);\n        if (buf->mSize == newSize) return buf;\n        // Don't overflow if the combined size of the new buffer / header is larger than\n        // size_max.\n        LOG_ALWAYS_FATAL_IF((newSize >= (SIZE_MAX - sizeof(SharedBuffer))),\n                            \"Invalid buffer size %zu\", newSize);\n\n        buf = (SharedBuffer*)realloc(buf, sizeof(SharedBuffer) + newSize);\n        if (buf != NULL) {\n            buf->mSize = newSize;\n            return buf;\n        }\n    }\n    SharedBuffer* sb = alloc(newSize);\n    if (sb) {\n        const size_t mySize = mSize;\n        memcpy(sb->data(), data(), newSize < mySize ? newSize : mySize);\n        release();\n    }\n    return sb;    \n}\n\nSharedBuffer* SharedBuffer::attemptEdit() const\n{\n    if (onlyOwner()) {\n        return const_cast<SharedBuffer*>(this);\n    }\n    return 0;\n}\n\nSharedBuffer* SharedBuffer::reset(size_t new_size) const\n{\n    // cheap-o-reset.\n    SharedBuffer* sb = alloc(new_size);\n    if (sb) {\n        release();\n    }\n    return sb;\n}\n\nvoid SharedBuffer::acquire() const {\n    mRefs.fetch_add(1, std::memory_order_relaxed);\n}\n\nint32_t SharedBuffer::release(uint32_t flags) const\n{\n    int32_t prev = 1;\n    if (onlyOwner() || ((prev = mRefs.fetch_sub(1, std::memory_order_release) == 1)\n            && (atomic_thread_fence(std::memory_order_acquire), true))) {\n        mRefs.store(0, std::memory_order_relaxed);\n        if ((flags & eKeepStorage) == 0) {\n            free(const_cast<SharedBuffer*>(this));\n        }\n    }\n    return prev;\n}\n\n\n}; // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/SharedBuffer.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * DEPRECATED.  DO NOT USE FOR NEW CODE.\n */\n\n#ifndef ANDROID_SHARED_BUFFER_H\n#define ANDROID_SHARED_BUFFER_H\n\n#include <atomic>\n#include <stdint.h>\n#include <sys/types.h>\n\n// ---------------------------------------------------------------------------\n\nnamespace android {\n\nclass SharedBuffer\n{\npublic:\n\n    /* flags to use with release() */\n    enum {\n        eKeepStorage = 0x00000001\n    };\n\n    /*! allocate a buffer of size 'size' and acquire() it.\n     *  call release() to free it.\n     */\n    static          SharedBuffer*           alloc(size_t size);\n    \n    /*! free the memory associated with the SharedBuffer.\n     * Fails if there are any users associated with this SharedBuffer.\n     * In other words, the buffer must have been release by all its\n     * users.\n     */\n    static          void                    dealloc(const SharedBuffer* released);\n\n    //! access the data for read\n    inline          const void*             data() const;\n    \n    //! access the data for read/write\n    inline          void*                   data();\n\n    //! get size of the buffer\n    inline          size_t                  size() const;\n \n    //! get back a SharedBuffer object from its data\n    static  inline  SharedBuffer*           bufferFromData(void* data);\n    \n    //! get back a SharedBuffer object from its data\n    static  inline  const SharedBuffer*     bufferFromData(const void* data);\n\n    //! get the size of a SharedBuffer object from its data\n    static  inline  size_t                  sizeFromData(const void* data);\n    \n    //! edit the buffer (get a writtable, or non-const, version of it)\n                    SharedBuffer*           edit() const;\n\n    //! edit the buffer, resizing if needed\n                    SharedBuffer*           editResize(size_t size) const;\n\n    //! like edit() but fails if a copy is required\n                    SharedBuffer*           attemptEdit() const;\n    \n    //! resize and edit the buffer, loose it's content.\n                    SharedBuffer*           reset(size_t size) const;\n\n    //! acquire/release a reference on this buffer\n                    void                    acquire() const;\n                    \n    /*! release a reference on this buffer, with the option of not\n     * freeing the memory associated with it if it was the last reference\n     * returns the previous reference count\n     */     \n                    int32_t                 release(uint32_t flags = 0) const;\n    \n    //! returns wether or not we're the only owner\n    inline          bool                    onlyOwner() const;\n    \n\nprivate:\n        inline SharedBuffer() { }\n        inline ~SharedBuffer() { }\n        SharedBuffer(const SharedBuffer&);\n        SharedBuffer& operator = (const SharedBuffer&);\n \n        // Must be sized to preserve correct alignment.\n        mutable std::atomic<int32_t>        mRefs;\n                size_t                      mSize;\n                uint32_t                    mReserved[2];\n};\n\nstatic_assert(sizeof(SharedBuffer) % 8 == 0\n        && (sizeof(size_t) > 4 || sizeof(SharedBuffer) == 16),\n        \"SharedBuffer has unexpected size\");\n\n// ---------------------------------------------------------------------------\n\nconst void* SharedBuffer::data() const {\n    return this + 1;\n}\n\nvoid* SharedBuffer::data() {\n    return this + 1;\n}\n\nsize_t SharedBuffer::size() const {\n    return mSize;\n}\n\nSharedBuffer* SharedBuffer::bufferFromData(void* data) {\n    return data ? static_cast<SharedBuffer *>(data)-1 : 0;\n}\n    \nconst SharedBuffer* SharedBuffer::bufferFromData(const void* data) {\n    return data ? static_cast<const SharedBuffer *>(data)-1 : 0;\n}\n\nsize_t SharedBuffer::sizeFromData(const void* data) {\n    return data ? bufferFromData(data)->mSize : 0;\n}\n\nbool SharedBuffer::onlyOwner() const {\n    return (mRefs.load(std::memory_order_acquire) == 1);\n}\n\n}; // namespace android\n\n// ---------------------------------------------------------------------------\n\n#endif // ANDROID_VECTOR_H\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/SharedBufferTest.cpp",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define __STDC_LIMIT_MACROS\n\n#include <gtest/gtest.h>\n\n#include <memory>\n#include <stdint.h>\n\n#include \"SharedBuffer.h\"\n\nTEST(SharedBufferTest, TestAlloc) {\n  EXPECT_DEATH(android::SharedBuffer::alloc(SIZE_MAX), \"\");\n  EXPECT_DEATH(android::SharedBuffer::alloc(SIZE_MAX - sizeof(android::SharedBuffer)), \"\");\n\n  // Make sure we don't die here.\n  // Check that null is returned, as we are asking for the whole address space.\n  android::SharedBuffer* buf =\n      android::SharedBuffer::alloc(SIZE_MAX - sizeof(android::SharedBuffer) - 1);\n  ASSERT_EQ(nullptr, buf);\n\n  buf = android::SharedBuffer::alloc(0);\n  ASSERT_NE(nullptr, buf);\n  ASSERT_EQ(0U, buf->size());\n  buf->release();\n}\n\nTEST(SharedBufferTest, TestEditResize) {\n  android::SharedBuffer* buf = android::SharedBuffer::alloc(10);\n  EXPECT_DEATH(buf->editResize(SIZE_MAX - sizeof(android::SharedBuffer)), \"\");\n  buf = android::SharedBuffer::alloc(10);\n  EXPECT_DEATH(buf->editResize(SIZE_MAX), \"\");\n\n  buf = android::SharedBuffer::alloc(10);\n  // Make sure we don't die here.\n  // Check that null is returned, as we are asking for the whole address space.\n  buf = buf->editResize(SIZE_MAX - sizeof(android::SharedBuffer) - 1);\n  ASSERT_EQ(nullptr, buf);\n\n  buf = android::SharedBuffer::alloc(10);\n  buf = buf->editResize(0);\n  ASSERT_EQ(0U, buf->size());\n  buf->release();\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/Static.cpp",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// All static variables go here, to control initialization and\n// destruction order in the library.\n\nnamespace android {\n\n// For String8.cpp\nextern void initialize_string8();\nextern void terminate_string8();\n\n// For String16.cpp\nextern void initialize_string16();\nextern void terminate_string16();\n\nclass LibUtilsFirstStatics\n{\npublic:\n    LibUtilsFirstStatics()\n    {\n        initialize_string8();\n        initialize_string16();\n    }\n    \n    ~LibUtilsFirstStatics()\n    {\n        terminate_string16();\n        terminate_string8();\n    }\n};\n\nstatic LibUtilsFirstStatics gFirstStatics;\nint gDarwinCantLoadAllObjects = 1;\n\n}   // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/StopWatch.cpp",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"StopWatch\"\n\n#include <string.h>\n#include <stdlib.h>\n#include <stdio.h>\n\n/* for PRId64 */\n#ifndef __STDC_FORMAT_MACROS\n#define __STDC_FORMAT_MACROS 1\n#endif\n#include <inttypes.h>\n\n#include <utils/Log.h>\n#include <utils/Errors.h>\n#include <utils/StopWatch.h>\n\n/*****************************************************************************/\n\nnamespace android {\n\n\nStopWatch::StopWatch(const char *name, int clock, uint32_t flags)\n    :   mName(name), mClock(clock), mFlags(flags)\n{\n    reset();\n}\n\nStopWatch::~StopWatch()\n{\n    nsecs_t elapsed = elapsedTime();\n    const int n = mNumLaps;\n    ALOGD(\"StopWatch %s (us): %\" PRId64 \" \", mName, ns2us(elapsed));\n    for (int i=0 ; i<n ; i++) {\n        const nsecs_t soFar = mLaps[i].soFar;\n        const nsecs_t thisLap = mLaps[i].thisLap;\n        ALOGD(\" [%d: %\" PRId64 \", %\" PRId64, i, ns2us(soFar), ns2us(thisLap));\n    }\n}\n\nconst char* StopWatch::name() const\n{\n    return mName;\n}\n\nnsecs_t StopWatch::lap()\n{\n    nsecs_t elapsed = elapsedTime();\n    if (mNumLaps >= 8) {\n        elapsed = 0;\n    } else {\n        const int n = mNumLaps;\n        mLaps[n].soFar   = elapsed;\n        mLaps[n].thisLap = n ? (elapsed - mLaps[n-1].soFar) : elapsed;\n        mNumLaps = n+1;\n    }\n    return elapsed;\n}\n\nnsecs_t StopWatch::elapsedTime() const\n{\n    return systemTime(mClock) - mStartTime;\n}\n\nvoid StopWatch::reset()\n{\n    mNumLaps = 0;\n    mStartTime = systemTime(mClock);\n}\n\n\n/*****************************************************************************/\n\n}; // namespace android\n\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/String16.cpp",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <utils/String16.h>\n\n#include <utils/Log.h>\n#include <utils/Unicode.h>\n#include <utils/String8.h>\n#include <utils/threads.h>\n\n#include <memory.h>\n#include <stdio.h>\n#include <ctype.h>\n\n#include \"SharedBuffer.h\"\n\nnamespace android {\n\nstatic SharedBuffer* gEmptyStringBuf = NULL;\nstatic char16_t* gEmptyString = NULL;\n\nstatic inline char16_t* getEmptyString()\n{\n    gEmptyStringBuf->acquire();\n   return gEmptyString;\n}\n\nvoid initialize_string16()\n{\n    SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t));\n    char16_t* str = (char16_t*)buf->data();\n    *str = 0;\n    gEmptyStringBuf = buf;\n    gEmptyString = str;\n}\n\nvoid terminate_string16()\n{\n    SharedBuffer::bufferFromData(gEmptyString)->release();\n    gEmptyStringBuf = NULL;\n    gEmptyString = NULL;\n}\n\n// ---------------------------------------------------------------------------\n\nstatic char16_t* allocFromUTF8(const char* u8str, size_t u8len)\n{\n    if (u8len == 0) return getEmptyString();\n\n    const uint8_t* u8cur = (const uint8_t*) u8str;\n\n    const ssize_t u16len = utf8_to_utf16_length(u8cur, u8len);\n    if (u16len < 0) {\n        return getEmptyString();\n    }\n\n    SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t)*(u16len+1));\n    if (buf) {\n        u8cur = (const uint8_t*) u8str;\n        char16_t* u16str = (char16_t*)buf->data();\n\n        utf8_to_utf16(u8cur, u8len, u16str);\n\n        //printf(\"Created UTF-16 string from UTF-8 \\\"%s\\\":\", in);\n        //printHexData(1, str, buf->size(), 16, 1);\n        //printf(\"\\n\");\n        \n        return u16str;\n    }\n\n    return getEmptyString();\n}\n\n// ---------------------------------------------------------------------------\n\nString16::String16()\n    : mString(getEmptyString())\n{\n}\n\nString16::String16(StaticLinkage)\n    : mString(0)\n{\n    // this constructor is used when we can't rely on the static-initializers\n    // having run. In this case we always allocate an empty string. It's less\n    // efficient than using getEmptyString(), but we assume it's uncommon.\n\n    char16_t* data = static_cast<char16_t*>(\n            SharedBuffer::alloc(sizeof(char16_t))->data());\n    data[0] = 0;\n    mString = data;\n}\n\nString16::String16(const String16& o)\n    : mString(o.mString)\n{\n    SharedBuffer::bufferFromData(mString)->acquire();\n}\n\nString16::String16(const String16& o, size_t len, size_t begin)\n    : mString(getEmptyString())\n{\n    setTo(o, len, begin);\n}\n\nString16::String16(const char16_t* o)\n{\n    size_t len = strlen16(o);\n    SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));\n    ALOG_ASSERT(buf, \"Unable to allocate shared buffer\");\n    if (buf) {\n        char16_t* str = (char16_t*)buf->data();\n        strcpy16(str, o);\n        mString = str;\n        return;\n    }\n    \n    mString = getEmptyString();\n}\n\nString16::String16(const char16_t* o, size_t len)\n{\n    SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));\n    ALOG_ASSERT(buf, \"Unable to allocate shared buffer\");\n    if (buf) {\n        char16_t* str = (char16_t*)buf->data();\n        memcpy(str, o, len*sizeof(char16_t));\n        str[len] = 0;\n        mString = str;\n        return;\n    }\n    \n    mString = getEmptyString();\n}\n\nString16::String16(const String8& o)\n    : mString(allocFromUTF8(o.string(), o.size()))\n{\n}\n\nString16::String16(const char* o)\n    : mString(allocFromUTF8(o, strlen(o)))\n{\n}\n\nString16::String16(const char* o, size_t len)\n    : mString(allocFromUTF8(o, len))\n{\n}\n\nString16::~String16()\n{\n    SharedBuffer::bufferFromData(mString)->release();\n}\n\nsize_t String16::size() const\n{\n    return SharedBuffer::sizeFromData(mString)/sizeof(char16_t)-1;\n}\n\nvoid String16::setTo(const String16& other)\n{\n    SharedBuffer::bufferFromData(other.mString)->acquire();\n    SharedBuffer::bufferFromData(mString)->release();\n    mString = other.mString;\n}\n\nstatus_t String16::setTo(const String16& other, size_t len, size_t begin)\n{\n    const size_t N = other.size();\n    if (begin >= N) {\n        SharedBuffer::bufferFromData(mString)->release();\n        mString = getEmptyString();\n        return NO_ERROR;\n    }\n    if ((begin+len) > N) len = N-begin;\n    if (begin == 0 && len == N) {\n        setTo(other);\n        return NO_ERROR;\n    }\n\n    if (&other == this) {\n        LOG_ALWAYS_FATAL(\"Not implemented\");\n    }\n\n    return setTo(other.string()+begin, len);\n}\n\nstatus_t String16::setTo(const char16_t* other)\n{\n    return setTo(other, strlen16(other));\n}\n\nstatus_t String16::setTo(const char16_t* other, size_t len)\n{\n    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)\n        ->editResize((len+1)*sizeof(char16_t));\n    if (buf) {\n        char16_t* str = (char16_t*)buf->data();\n        memmove(str, other, len*sizeof(char16_t));\n        str[len] = 0;\n        mString = str;\n        return NO_ERROR;\n    }\n    return NO_MEMORY;\n}\n\nstatus_t String16::append(const String16& other)\n{\n    const size_t myLen = size();\n    const size_t otherLen = other.size();\n    if (myLen == 0) {\n        setTo(other);\n        return NO_ERROR;\n    } else if (otherLen == 0) {\n        return NO_ERROR;\n    }\n    \n    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)\n        ->editResize((myLen+otherLen+1)*sizeof(char16_t));\n    if (buf) {\n        char16_t* str = (char16_t*)buf->data();\n        memcpy(str+myLen, other, (otherLen+1)*sizeof(char16_t));\n        mString = str;\n        return NO_ERROR;\n    }\n    return NO_MEMORY;\n}\n\nstatus_t String16::append(const char16_t* chrs, size_t otherLen)\n{\n    const size_t myLen = size();\n    if (myLen == 0) {\n        setTo(chrs, otherLen);\n        return NO_ERROR;\n    } else if (otherLen == 0) {\n        return NO_ERROR;\n    }\n    \n    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)\n        ->editResize((myLen+otherLen+1)*sizeof(char16_t));\n    if (buf) {\n        char16_t* str = (char16_t*)buf->data();\n        memcpy(str+myLen, chrs, otherLen*sizeof(char16_t));\n        str[myLen+otherLen] = 0;\n        mString = str;\n        return NO_ERROR;\n    }\n    return NO_MEMORY;\n}\n\nstatus_t String16::insert(size_t pos, const char16_t* chrs)\n{\n    return insert(pos, chrs, strlen16(chrs));\n}\n\nstatus_t String16::insert(size_t pos, const char16_t* chrs, size_t len)\n{\n    const size_t myLen = size();\n    if (myLen == 0) {\n        return setTo(chrs, len);\n        return NO_ERROR;\n    } else if (len == 0) {\n        return NO_ERROR;\n    }\n\n    if (pos > myLen) pos = myLen;\n\n    #if 0\n    printf(\"Insert in to %s: pos=%d, len=%d, myLen=%d, chrs=%s\\n\",\n           String8(*this).string(), pos,\n           len, myLen, String8(chrs, len).string());\n    #endif\n\n    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)\n        ->editResize((myLen+len+1)*sizeof(char16_t));\n    if (buf) {\n        char16_t* str = (char16_t*)buf->data();\n        if (pos < myLen) {\n            memmove(str+pos+len, str+pos, (myLen-pos)*sizeof(char16_t));\n        }\n        memcpy(str+pos, chrs, len*sizeof(char16_t));\n        str[myLen+len] = 0;\n        mString = str;\n        #if 0\n        printf(\"Result (%d chrs): %s\\n\", size(), String8(*this).string());\n        #endif\n        return NO_ERROR;\n    }\n    return NO_MEMORY;\n}\n\nssize_t String16::findFirst(char16_t c) const\n{\n    const char16_t* str = string();\n    const char16_t* p = str;\n    const char16_t* e = p + size();\n    while (p < e) {\n        if (*p == c) {\n            return p-str;\n        }\n        p++;\n    }\n    return -1;\n}\n\nssize_t String16::findLast(char16_t c) const\n{\n    const char16_t* str = string();\n    const char16_t* p = str;\n    const char16_t* e = p + size();\n    while (p < e) {\n        e--;\n        if (*e == c) {\n            return e-str;\n        }\n    }\n    return -1;\n}\n\nbool String16::startsWith(const String16& prefix) const\n{\n    const size_t ps = prefix.size();\n    if (ps > size()) return false;\n    return strzcmp16(mString, ps, prefix.string(), ps) == 0;\n}\n\nbool String16::startsWith(const char16_t* prefix) const\n{\n    const size_t ps = strlen16(prefix);\n    if (ps > size()) return false;\n    return strncmp16(mString, prefix, ps) == 0;\n}\n\nbool String16::contains(const char16_t* chrs) const\n{\n    return strstr16(mString, chrs) != nullptr;\n}\n\nstatus_t String16::makeLower()\n{\n    const size_t N = size();\n    const char16_t* str = string();\n    char16_t* edit = NULL;\n    for (size_t i=0; i<N; i++) {\n        const char16_t v = str[i];\n        if (v >= 'A' && v <= 'Z') {\n            if (!edit) {\n                SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();\n                if (!buf) {\n                    return NO_MEMORY;\n                }\n                edit = (char16_t*)buf->data();\n                mString = str = edit;\n            }\n            edit[i] = tolower((char)v);\n        }\n    }\n    return NO_ERROR;\n}\n\nstatus_t String16::replaceAll(char16_t replaceThis, char16_t withThis)\n{\n    const size_t N = size();\n    const char16_t* str = string();\n    char16_t* edit = NULL;\n    for (size_t i=0; i<N; i++) {\n        if (str[i] == replaceThis) {\n            if (!edit) {\n                SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();\n                if (!buf) {\n                    return NO_MEMORY;\n                }\n                edit = (char16_t*)buf->data();\n                mString = str = edit;\n            }\n            edit[i] = withThis;\n        }\n    }\n    return NO_ERROR;\n}\n\nstatus_t String16::remove(size_t len, size_t begin)\n{\n    const size_t N = size();\n    if (begin >= N) {\n        SharedBuffer::bufferFromData(mString)->release();\n        mString = getEmptyString();\n        return NO_ERROR;\n    }\n    if ((begin+len) > N) len = N-begin;\n    if (begin == 0 && len == N) {\n        return NO_ERROR;\n    }\n\n    if (begin > 0) {\n        SharedBuffer* buf = SharedBuffer::bufferFromData(mString)\n            ->editResize((N+1)*sizeof(char16_t));\n        if (!buf) {\n            return NO_MEMORY;\n        }\n        char16_t* str = (char16_t*)buf->data();\n        memmove(str, str+begin, (N-begin+1)*sizeof(char16_t));\n        mString = str;\n    }\n    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)\n        ->editResize((len+1)*sizeof(char16_t));\n    if (buf) {\n        char16_t* str = (char16_t*)buf->data();\n        str[len] = 0;\n        mString = str;\n        return NO_ERROR;\n    }\n    return NO_MEMORY;\n}\n\n}; // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/String8.cpp",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define __STDC_LIMIT_MACROS\n#include <stdint.h>\n\n#include <utils/String8.h>\n\n#include <utils/Compat.h>\n#include <utils/Log.h>\n#include <utils/Unicode.h>\n#include <utils/String16.h>\n#include <utils/threads.h>\n\n#include <ctype.h>\n\n#include \"SharedBuffer.h\"\n\n/*\n * Functions outside android is below the namespace android, since they use\n * functions and constants in android namespace.\n */\n\n// ---------------------------------------------------------------------------\n\nnamespace android {\n\n// Separator used by resource paths. This is not platform dependent contrary\n// to OS_PATH_SEPARATOR.\n#define RES_PATH_SEPARATOR '/'\n\nstatic SharedBuffer* gEmptyStringBuf = NULL;\nstatic char* gEmptyString = NULL;\n\nextern int gDarwinCantLoadAllObjects;\nint gDarwinIsReallyAnnoying;\n\nvoid initialize_string8();\n\nstatic inline char* getEmptyString()\n{\n    gEmptyStringBuf->acquire();\n    return gEmptyString;\n}\n\nvoid initialize_string8()\n{\n    // HACK: This dummy dependency forces linking libutils Static.cpp,\n    // which is needed to initialize String8/String16 classes.\n    // These variables are named for Darwin, but are needed elsewhere too,\n    // including static linking on any platform.\n    gDarwinIsReallyAnnoying = gDarwinCantLoadAllObjects;\n\n    SharedBuffer* buf = SharedBuffer::alloc(1);\n    char* str = (char*)buf->data();\n    *str = 0;\n    gEmptyStringBuf = buf;\n    gEmptyString = str;\n}\n\nvoid terminate_string8()\n{\n    SharedBuffer::bufferFromData(gEmptyString)->release();\n    gEmptyStringBuf = NULL;\n    gEmptyString = NULL;\n}\n\n// ---------------------------------------------------------------------------\n\nstatic char* allocFromUTF8(const char* in, size_t len)\n{\n    if (len > 0) {\n        if (len == SIZE_MAX) {\n            return NULL;\n        }\n        SharedBuffer* buf = SharedBuffer::alloc(len+1);\n        ALOG_ASSERT(buf, \"Unable to allocate shared buffer\");\n        if (buf) {\n            char* str = (char*)buf->data();\n            memcpy(str, in, len);\n            str[len] = 0;\n            return str;\n        }\n        return NULL;\n    }\n\n    return getEmptyString();\n}\n\nstatic char* allocFromUTF16(const char16_t* in, size_t len)\n{\n    if (len == 0) return getEmptyString();\n\n     // Allow for closing '\\0'\n    const ssize_t resultStrLen = utf16_to_utf8_length(in, len) + 1;\n    if (resultStrLen < 1) {\n        return getEmptyString();\n    }\n\n    SharedBuffer* buf = SharedBuffer::alloc(resultStrLen);\n    ALOG_ASSERT(buf, \"Unable to allocate shared buffer\");\n    if (!buf) {\n        return getEmptyString();\n    }\n\n    char* resultStr = (char*)buf->data();\n    utf16_to_utf8(in, len, resultStr, resultStrLen);\n    return resultStr;\n}\n\nstatic char* allocFromUTF32(const char32_t* in, size_t len)\n{\n    if (len == 0) {\n        return getEmptyString();\n    }\n\n    const ssize_t resultStrLen = utf32_to_utf8_length(in, len) + 1;\n    if (resultStrLen < 1) {\n        return getEmptyString();\n    }\n\n    SharedBuffer* buf = SharedBuffer::alloc(resultStrLen);\n    ALOG_ASSERT(buf, \"Unable to allocate shared buffer\");\n    if (!buf) {\n        return getEmptyString();\n    }\n\n    char* resultStr = (char*) buf->data();\n    utf32_to_utf8(in, len, resultStr, resultStrLen);\n\n    return resultStr;\n}\n\n// ---------------------------------------------------------------------------\n\nString8::String8()\n    : mString(getEmptyString())\n{\n}\n\nString8::String8(StaticLinkage)\n    : mString(0)\n{\n    // this constructor is used when we can't rely on the static-initializers\n    // having run. In this case we always allocate an empty string. It's less\n    // efficient than using getEmptyString(), but we assume it's uncommon.\n\n    char* data = static_cast<char*>(\n            SharedBuffer::alloc(sizeof(char))->data());\n    data[0] = 0;\n    mString = data;\n}\n\nString8::String8(const String8& o)\n    : mString(o.mString)\n{\n    SharedBuffer::bufferFromData(mString)->acquire();\n}\n\nString8::String8(const char* o)\n    : mString(allocFromUTF8(o, strlen(o)))\n{\n    if (mString == NULL) {\n        mString = getEmptyString();\n    }\n}\n\nString8::String8(const char* o, size_t len)\n    : mString(allocFromUTF8(o, len))\n{\n    if (mString == NULL) {\n        mString = getEmptyString();\n    }\n}\n\nString8::String8(const String16& o)\n    : mString(allocFromUTF16(o.string(), o.size()))\n{\n}\n\nString8::String8(const char16_t* o)\n    : mString(allocFromUTF16(o, strlen16(o)))\n{\n}\n\nString8::String8(const char16_t* o, size_t len)\n    : mString(allocFromUTF16(o, len))\n{\n}\n\nString8::String8(const char32_t* o)\n    : mString(allocFromUTF32(o, strlen32(o)))\n{\n}\n\nString8::String8(const char32_t* o, size_t len)\n    : mString(allocFromUTF32(o, len))\n{\n}\n\nString8::~String8()\n{\n    SharedBuffer::bufferFromData(mString)->release();\n}\n\nsize_t String8::length() const\n{\n    return SharedBuffer::sizeFromData(mString)-1;\n}\n\nString8 String8::format(const char* fmt, ...)\n{\n    va_list args;\n    va_start(args, fmt);\n\n    String8 result(formatV(fmt, args));\n\n    va_end(args);\n    return result;\n}\n\nString8 String8::formatV(const char* fmt, va_list args)\n{\n    String8 result;\n    result.appendFormatV(fmt, args);\n    return result;\n}\n\nvoid String8::clear() {\n    SharedBuffer::bufferFromData(mString)->release();\n    mString = getEmptyString();\n}\n\nvoid String8::setTo(const String8& other)\n{\n    SharedBuffer::bufferFromData(other.mString)->acquire();\n    SharedBuffer::bufferFromData(mString)->release();\n    mString = other.mString;\n}\n\nstatus_t String8::setTo(const char* other)\n{\n    const char *newString = allocFromUTF8(other, strlen(other));\n    SharedBuffer::bufferFromData(mString)->release();\n    mString = newString;\n    if (mString) return NO_ERROR;\n\n    mString = getEmptyString();\n    return NO_MEMORY;\n}\n\nstatus_t String8::setTo(const char* other, size_t len)\n{\n    const char *newString = allocFromUTF8(other, len);\n    SharedBuffer::bufferFromData(mString)->release();\n    mString = newString;\n    if (mString) return NO_ERROR;\n\n    mString = getEmptyString();\n    return NO_MEMORY;\n}\n\nstatus_t String8::setTo(const char16_t* other, size_t len)\n{\n    const char *newString = allocFromUTF16(other, len);\n    SharedBuffer::bufferFromData(mString)->release();\n    mString = newString;\n    if (mString) return NO_ERROR;\n\n    mString = getEmptyString();\n    return NO_MEMORY;\n}\n\nstatus_t String8::setTo(const char32_t* other, size_t len)\n{\n    const char *newString = allocFromUTF32(other, len);\n    SharedBuffer::bufferFromData(mString)->release();\n    mString = newString;\n    if (mString) return NO_ERROR;\n\n    mString = getEmptyString();\n    return NO_MEMORY;\n}\n\nstatus_t String8::append(const String8& other)\n{\n    const size_t otherLen = other.bytes();\n    if (bytes() == 0) {\n        setTo(other);\n        return NO_ERROR;\n    } else if (otherLen == 0) {\n        return NO_ERROR;\n    }\n\n    return real_append(other.string(), otherLen);\n}\n\nstatus_t String8::append(const char* other)\n{\n    return append(other, strlen(other));\n}\n\nstatus_t String8::append(const char* other, size_t otherLen)\n{\n    if (bytes() == 0) {\n        return setTo(other, otherLen);\n    } else if (otherLen == 0) {\n        return NO_ERROR;\n    }\n\n    return real_append(other, otherLen);\n}\n\nstatus_t String8::appendFormat(const char* fmt, ...)\n{\n    va_list args;\n    va_start(args, fmt);\n\n    status_t result = appendFormatV(fmt, args);\n\n    va_end(args);\n    return result;\n}\n\nstatus_t String8::appendFormatV(const char* fmt, va_list args)\n{\n    int n, result = NO_ERROR;\n    va_list tmp_args;\n\n    /* args is undefined after vsnprintf.\n     * So we need a copy here to avoid the\n     * second vsnprintf access undefined args.\n     */\n    va_copy(tmp_args, args);\n    n = vsnprintf(NULL, 0, fmt, tmp_args);\n    va_end(tmp_args);\n\n    if (n != 0) {\n        size_t oldLength = length();\n        char* buf = lockBuffer(oldLength + n);\n        if (buf) {\n            vsnprintf(buf + oldLength, n + 1, fmt, args);\n        } else {\n            result = NO_MEMORY;\n        }\n    }\n    return result;\n}\n\nstatus_t String8::real_append(const char* other, size_t otherLen)\n{\n    const size_t myLen = bytes();\n    \n    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)\n        ->editResize(myLen+otherLen+1);\n    if (buf) {\n        char* str = (char*)buf->data();\n        mString = str;\n        str += myLen;\n        memcpy(str, other, otherLen);\n        str[otherLen] = '\\0';\n        return NO_ERROR;\n    }\n    return NO_MEMORY;\n}\n\nchar* String8::lockBuffer(size_t size)\n{\n    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)\n        ->editResize(size+1);\n    if (buf) {\n        char* str = (char*)buf->data();\n        mString = str;\n        return str;\n    }\n    return NULL;\n}\n\nvoid String8::unlockBuffer()\n{\n    unlockBuffer(strlen(mString));\n}\n\nstatus_t String8::unlockBuffer(size_t size)\n{\n    if (size != this->size()) {\n        SharedBuffer* buf = SharedBuffer::bufferFromData(mString)\n            ->editResize(size+1);\n        if (! buf) {\n            return NO_MEMORY;\n        }\n\n        char* str = (char*)buf->data();\n        str[size] = 0;\n        mString = str;\n    }\n\n    return NO_ERROR;\n}\n\nssize_t String8::find(const char* other, size_t start) const\n{\n    size_t len = size();\n    if (start >= len) {\n        return -1;\n    }\n    const char* s = mString+start;\n    const char* p = strstr(s, other);\n    return p ? p-mString : -1;\n}\n\nbool String8::removeAll(const char* other) {\n    ssize_t index = find(other);\n    if (index < 0) return false;\n\n    char* buf = lockBuffer(size());\n    if (!buf) return false; // out of memory\n\n    size_t skip = strlen(other);\n    size_t len = size();\n    size_t tail = index;\n    while (size_t(index) < len) {\n        ssize_t next = find(other, index + skip);\n        if (next < 0) {\n            next = len;\n        }\n\n        memmove(buf + tail, buf + index + skip, next - index - skip);\n        tail += next - index - skip;\n        index = next;\n    }\n    unlockBuffer(tail);\n    return true;\n}\n\nvoid String8::toLower()\n{\n    toLower(0, size());\n}\n\nvoid String8::toLower(size_t start, size_t length)\n{\n    const size_t len = size();\n    if (start >= len) {\n        return;\n    }\n    if (start+length > len) {\n        length = len-start;\n    }\n    char* buf = lockBuffer(len);\n    buf += start;\n    while (length > 0) {\n        *buf = tolower(*buf);\n        buf++;\n        length--;\n    }\n    unlockBuffer(len);\n}\n\nvoid String8::toUpper()\n{\n    toUpper(0, size());\n}\n\nvoid String8::toUpper(size_t start, size_t length)\n{\n    const size_t len = size();\n    if (start >= len) {\n        return;\n    }\n    if (start+length > len) {\n        length = len-start;\n    }\n    char* buf = lockBuffer(len);\n    buf += start;\n    while (length > 0) {\n        *buf = toupper(*buf);\n        buf++;\n        length--;\n    }\n    unlockBuffer(len);\n}\n\nsize_t String8::getUtf32Length() const\n{\n    return utf8_to_utf32_length(mString, length());\n}\n\nint32_t String8::getUtf32At(size_t index, size_t *next_index) const\n{\n    return utf32_from_utf8_at(mString, length(), index, next_index);\n}\n\nvoid String8::getUtf32(char32_t* dst) const\n{\n    utf8_to_utf32(mString, length(), dst);\n}\n\n// ---------------------------------------------------------------------------\n// Path functions\n\nvoid String8::setPathName(const char* name)\n{\n    setPathName(name, strlen(name));\n}\n\nvoid String8::setPathName(const char* name, size_t len)\n{\n    char* buf = lockBuffer(len);\n\n    memcpy(buf, name, len);\n\n    // remove trailing path separator, if present\n    if (len > 0 && buf[len-1] == OS_PATH_SEPARATOR)\n        len--;\n\n    buf[len] = '\\0';\n\n    unlockBuffer(len);\n}\n\nString8 String8::getPathLeaf(void) const\n{\n    const char* cp;\n    const char*const buf = mString;\n\n    cp = strrchr(buf, OS_PATH_SEPARATOR);\n    if (cp == NULL)\n        return String8(*this);\n    else\n        return String8(cp+1);\n}\n\nString8 String8::getPathDir(void) const\n{\n    const char* cp;\n    const char*const str = mString;\n\n    cp = strrchr(str, OS_PATH_SEPARATOR);\n    if (cp == NULL)\n        return String8(\"\");\n    else\n        return String8(str, cp - str);\n}\n\nString8 String8::walkPath(String8* outRemains) const\n{\n    const char* cp;\n    const char*const str = mString;\n    const char* buf = str;\n\n    cp = strchr(buf, OS_PATH_SEPARATOR);\n    if (cp == buf) {\n        // don't include a leading '/'.\n        buf = buf+1;\n        cp = strchr(buf, OS_PATH_SEPARATOR);\n    }\n\n    if (cp == NULL) {\n        String8 res = buf != str ? String8(buf) : *this;\n        if (outRemains) *outRemains = String8(\"\");\n        return res;\n    }\n\n    String8 res(buf, cp-buf);\n    if (outRemains) *outRemains = String8(cp+1);\n    return res;\n}\n\n/*\n * Helper function for finding the start of an extension in a pathname.\n *\n * Returns a pointer inside mString, or NULL if no extension was found.\n */\nchar* String8::find_extension(void) const\n{\n    const char* lastSlash;\n    const char* lastDot;\n    const char* const str = mString;\n\n    // only look at the filename\n    lastSlash = strrchr(str, OS_PATH_SEPARATOR);\n    if (lastSlash == NULL)\n        lastSlash = str;\n    else\n        lastSlash++;\n\n    // find the last dot\n    lastDot = strrchr(lastSlash, '.');\n    if (lastDot == NULL)\n        return NULL;\n\n    // looks good, ship it\n    return const_cast<char*>(lastDot);\n}\n\nString8 String8::getPathExtension(void) const\n{\n    char* ext;\n\n    ext = find_extension();\n    if (ext != NULL)\n        return String8(ext);\n    else\n        return String8(\"\");\n}\n\nString8 String8::getBasePath(void) const\n{\n    char* ext;\n    const char* const str = mString;\n\n    ext = find_extension();\n    if (ext == NULL)\n        return String8(*this);\n    else\n        return String8(str, ext - str);\n}\n\nString8& String8::appendPath(const char* name)\n{\n    // TODO: The test below will fail for Win32 paths. Fix later or ignore.\n    if (name[0] != OS_PATH_SEPARATOR) {\n        if (*name == '\\0') {\n            // nothing to do\n            return *this;\n        }\n\n        size_t len = length();\n        if (len == 0) {\n            // no existing filename, just use the new one\n            setPathName(name);\n            return *this;\n        }\n\n        // make room for oldPath + '/' + newPath\n        int newlen = strlen(name);\n\n        char* buf = lockBuffer(len+1+newlen);\n\n        // insert a '/' if needed\n        if (buf[len-1] != OS_PATH_SEPARATOR)\n            buf[len++] = OS_PATH_SEPARATOR;\n\n        memcpy(buf+len, name, newlen+1);\n        len += newlen;\n\n        unlockBuffer(len);\n\n        return *this;\n    } else {\n        setPathName(name);\n        return *this;\n    }\n}\n\nString8& String8::convertToResPath()\n{\n#if OS_PATH_SEPARATOR != RES_PATH_SEPARATOR\n    size_t len = length();\n    if (len > 0) {\n        char * buf = lockBuffer(len);\n        for (char * end = buf + len; buf < end; ++buf) {\n            if (*buf == OS_PATH_SEPARATOR)\n                *buf = RES_PATH_SEPARATOR;\n        }\n        unlockBuffer(len);\n    }\n#endif\n    return *this;\n}\n\n}; // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/SystemClock.cpp",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/*\n * System clock functions.\n */\n\n#if defined(__ANDROID__)\n#include <linux/ioctl.h>\n#include <linux/rtc.h>\n#include <utils/Atomic.h>\n#include <linux/android_alarm.h>\n#endif\n\n#include <sys/time.h>\n#include <limits.h>\n#include <fcntl.h>\n#include <string.h>\n\n#include <utils/SystemClock.h>\n#include <utils/Timers.h>\n\n#define LOG_TAG \"SystemClock\"\n#include <utils/Log.h>\n\nnamespace android {\n\n/*\n * native public static long uptimeMillis();\n */\nint64_t uptimeMillis()\n{\n    int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);\n    return (int64_t) nanoseconds_to_milliseconds(when);\n}\n\n/*\n * native public static long elapsedRealtime();\n */\nint64_t elapsedRealtime()\n{\n\treturn nanoseconds_to_milliseconds(elapsedRealtimeNano());\n}\n\n#define METHOD_CLOCK_GETTIME    0\n#define METHOD_IOCTL            1\n#define METHOD_SYSTEMTIME       2\n\n/*\n * To debug/verify the timestamps returned by the kernel, change\n * DEBUG_TIMESTAMP to 1 and call the timestamp routine from a single thread\n * in the test program. b/10899829\n */\n#define DEBUG_TIMESTAMP         0\n\n#if DEBUG_TIMESTAMP && defined(__arm__)\nstatic inline void checkTimeStamps(int64_t timestamp,\n                                   int64_t volatile *prevTimestampPtr,\n                                   int volatile *prevMethodPtr,\n                                   int curMethod)\n{\n    /*\n     * Disable the check for SDK since the prebuilt toolchain doesn't contain\n     * gettid, and int64_t is different on the ARM platform\n     * (ie long vs long long).\n     */\n    int64_t prevTimestamp = *prevTimestampPtr;\n    int prevMethod = *prevMethodPtr;\n\n    if (timestamp < prevTimestamp) {\n        static const char *gettime_method_names[] = {\n            \"clock_gettime\",\n            \"ioctl\",\n            \"systemTime\",\n        };\n\n        ALOGW(\"time going backwards: prev %lld(%s) vs now %lld(%s), tid=%d\",\n              prevTimestamp, gettime_method_names[prevMethod],\n              timestamp, gettime_method_names[curMethod],\n              gettid());\n    }\n    // NOTE - not atomic and may generate spurious warnings if the 64-bit\n    // write is interrupted or not observed as a whole.\n    *prevTimestampPtr = timestamp;\n    *prevMethodPtr = curMethod;\n}\n#else\n#define checkTimeStamps(timestamp, prevTimestampPtr, prevMethodPtr, curMethod)\n#endif\n\n/*\n * native public static long elapsedRealtimeNano();\n */\nint64_t elapsedRealtimeNano()\n{\n#if defined(__ANDROID__)\n    struct timespec ts;\n    int result;\n    int64_t timestamp;\n#if DEBUG_TIMESTAMP\n    static volatile int64_t prevTimestamp;\n    static volatile int prevMethod;\n#endif\n\n    static int s_fd = -1;\n\n    if (s_fd == -1) {\n        int fd = open(\"/dev/alarm\", O_RDONLY);\n        if (android_atomic_cmpxchg(-1, fd, &s_fd)) {\n            close(fd);\n        }\n    }\n\n    result = ioctl(s_fd,\n            ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);\n\n    if (result == 0) {\n        timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;\n        checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_IOCTL);\n        return timestamp;\n    }\n\n    // /dev/alarm doesn't exist, fallback to CLOCK_BOOTTIME\n    result = clock_gettime(CLOCK_BOOTTIME, &ts);\n    if (result == 0) {\n        timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;\n        checkTimeStamps(timestamp, &prevTimestamp, &prevMethod,\n                        METHOD_CLOCK_GETTIME);\n        return timestamp;\n    }\n\n    // XXX: there was an error, probably because the driver didn't\n    // exist ... this should return\n    // a real error, like an exception!\n    timestamp = systemTime(SYSTEM_TIME_MONOTONIC);\n    checkTimeStamps(timestamp, &prevTimestamp, &prevMethod,\n                    METHOD_SYSTEMTIME);\n    return timestamp;\n#else\n    return systemTime(SYSTEM_TIME_MONOTONIC);\n#endif\n}\n\n}; // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/Threads.cpp",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #define LOG_NDEBUG 0\n#define LOG_TAG \"libutils.threads\"\n\n#include <assert.h>\n#include <errno.h>\n#include <memory.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#if !defined(_WIN32)\n# include <pthread.h>\n# include <sched.h>\n# include <sys/resource.h>\n#else\n# include <windows.h>\n# include <stdint.h>\n# include <process.h>\n# define HAVE_CREATETHREAD  // Cygwin, vs. HAVE__BEGINTHREADEX for MinGW\n#endif\n\n#if defined(__linux__)\n#include <sys/prctl.h>\n#endif\n\n#include <utils/threads.h>\n#include <utils/Log.h>\n\n#include <cutils/sched_policy.h>\n\n#if defined(__ANDROID__)\n# define __android_unused\n#else\n# define __android_unused __attribute__((__unused__))\n#endif\n\n/*\n * ===========================================================================\n *      Thread wrappers\n * ===========================================================================\n */\n\nusing namespace android;\n\n// ----------------------------------------------------------------------------\n#if !defined(_WIN32)\n// ----------------------------------------------------------------------------\n\n/*\n * Create and run a new thread.\n *\n * We create it \"detached\", so it cleans up after itself.\n */\n\ntypedef void* (*android_pthread_entry)(void*);\n\nstruct thread_data_t {\n    thread_func_t   entryFunction;\n    void*           userData;\n    int             priority;\n    char *          threadName;\n\n    // we use this trampoline when we need to set the priority with\n    // nice/setpriority, and name with prctl.\n    static int trampoline(const thread_data_t* t) {\n        thread_func_t f = t->entryFunction;\n        void* u = t->userData;\n        int prio = t->priority;\n        char * name = t->threadName;\n        delete t;\n        setpriority(PRIO_PROCESS, 0, prio);\n        if (prio >= ANDROID_PRIORITY_BACKGROUND) {\n            set_sched_policy(0, SP_BACKGROUND);\n        } else {\n            set_sched_policy(0, SP_FOREGROUND);\n        }\n\n        if (name) {\n            androidSetThreadName(name);\n            free(name);\n        }\n        return f(u);\n    }\n};\n\nvoid androidSetThreadName(const char* name) {\n#if defined(__linux__)\n    // Mac OS doesn't have this, and we build libutil for the host too\n    int hasAt = 0;\n    int hasDot = 0;\n    const char *s = name;\n    while (*s) {\n        if (*s == '.') hasDot = 1;\n        else if (*s == '@') hasAt = 1;\n        s++;\n    }\n    int len = s - name;\n    if (len < 15 || hasAt || !hasDot) {\n        s = name;\n    } else {\n        s = name + len - 15;\n    }\n    prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);\n#endif\n}\n\nint androidCreateRawThreadEtc(android_thread_func_t entryFunction,\n                               void *userData,\n                               const char* threadName __android_unused,\n                               int32_t threadPriority,\n                               size_t threadStackSize,\n                               android_thread_id_t *threadId)\n{\n    pthread_attr_t attr;\n    pthread_attr_init(&attr);\n    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);\n\n#if defined(__ANDROID__)  /* valgrind is rejecting RT-priority create reqs */\n    if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {\n        // Now that the pthread_t has a method to find the associated\n        // android_thread_id_t (pid) from pthread_t, it would be possible to avoid\n        // this trampoline in some cases as the parent could set the properties\n        // for the child.  However, there would be a race condition because the\n        // child becomes ready immediately, and it doesn't work for the name.\n        // prctl(PR_SET_NAME) only works for self; prctl(PR_SET_THREAD_NAME) was\n        // proposed but not yet accepted.\n        thread_data_t* t = new thread_data_t;\n        t->priority = threadPriority;\n        t->threadName = threadName ? strdup(threadName) : NULL;\n        t->entryFunction = entryFunction;\n        t->userData = userData;\n        entryFunction = (android_thread_func_t)&thread_data_t::trampoline;\n        userData = t;\n    }\n#endif\n\n    if (threadStackSize) {\n        pthread_attr_setstacksize(&attr, threadStackSize);\n    }\n\n    errno = 0;\n    pthread_t thread;\n    int result = pthread_create(&thread, &attr,\n                    (android_pthread_entry)entryFunction, userData);\n    pthread_attr_destroy(&attr);\n    if (result != 0) {\n        ALOGE(\"androidCreateRawThreadEtc failed (entry=%p, res=%d, %s)\\n\"\n             \"(android threadPriority=%d)\",\n            entryFunction, result, strerror(errno), threadPriority);\n        return 0;\n    }\n\n    // Note that *threadID is directly available to the parent only, as it is\n    // assigned after the child starts.  Use memory barrier / lock if the child\n    // or other threads also need access.\n    if (threadId != NULL) {\n        *threadId = (android_thread_id_t)thread; // XXX: this is not portable\n    }\n    return 1;\n}\n\n#if defined(__ANDROID__)\nstatic pthread_t android_thread_id_t_to_pthread(android_thread_id_t thread)\n{\n    return (pthread_t) thread;\n}\n#endif\n\nandroid_thread_id_t androidGetThreadId()\n{\n    return (android_thread_id_t)pthread_self();\n}\n\n// ----------------------------------------------------------------------------\n#else // !defined(_WIN32)\n// ----------------------------------------------------------------------------\n\n/*\n * Trampoline to make us __stdcall-compliant.\n *\n * We're expected to delete \"vDetails\" when we're done.\n */\nstruct threadDetails {\n    int (*func)(void*);\n    void* arg;\n};\nstatic __stdcall unsigned int threadIntermediary(void* vDetails)\n{\n    struct threadDetails* pDetails = (struct threadDetails*) vDetails;\n    int result;\n\n    result = (*(pDetails->func))(pDetails->arg);\n\n    delete pDetails;\n\n    ALOG(LOG_VERBOSE, \"thread\", \"thread exiting\\n\");\n    return (unsigned int) result;\n}\n\n/*\n * Create and run a new thread.\n */\nstatic bool doCreateThread(android_thread_func_t fn, void* arg, android_thread_id_t *id)\n{\n    HANDLE hThread;\n    struct threadDetails* pDetails = new threadDetails; // must be on heap\n    unsigned int thrdaddr;\n\n    pDetails->func = fn;\n    pDetails->arg = arg;\n\n#if defined(HAVE__BEGINTHREADEX)\n    hThread = (HANDLE) _beginthreadex(NULL, 0, threadIntermediary, pDetails, 0,\n                    &thrdaddr);\n    if (hThread == 0)\n#elif defined(HAVE_CREATETHREAD)\n    hThread = CreateThread(NULL, 0,\n                    (LPTHREAD_START_ROUTINE) threadIntermediary,\n                    (void*) pDetails, 0, (DWORD*) &thrdaddr);\n    if (hThread == NULL)\n#endif\n    {\n        ALOG(LOG_WARN, \"thread\", \"WARNING: thread create failed\\n\");\n        return false;\n    }\n\n#if defined(HAVE_CREATETHREAD)\n    /* close the management handle */\n    CloseHandle(hThread);\n#endif\n\n    if (id != NULL) {\n      \t*id = (android_thread_id_t)thrdaddr;\n    }\n\n    return true;\n}\n\nint androidCreateRawThreadEtc(android_thread_func_t fn,\n                               void *userData,\n                               const char* /*threadName*/,\n                               int32_t /*threadPriority*/,\n                               size_t /*threadStackSize*/,\n                               android_thread_id_t *threadId)\n{\n    return doCreateThread(  fn, userData, threadId);\n}\n\nandroid_thread_id_t androidGetThreadId()\n{\n    return (android_thread_id_t)GetCurrentThreadId();\n}\n\n// ----------------------------------------------------------------------------\n#endif // !defined(_WIN32)\n\n// ----------------------------------------------------------------------------\n\nint androidCreateThread(android_thread_func_t fn, void* arg)\n{\n    return createThreadEtc(fn, arg);\n}\n\nint androidCreateThreadGetID(android_thread_func_t fn, void *arg, android_thread_id_t *id)\n{\n    return createThreadEtc(fn, arg, \"android:unnamed_thread\",\n                           PRIORITY_DEFAULT, 0, id);\n}\n\nstatic android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc;\n\nint androidCreateThreadEtc(android_thread_func_t entryFunction,\n                            void *userData,\n                            const char* threadName,\n                            int32_t threadPriority,\n                            size_t threadStackSize,\n                            android_thread_id_t *threadId)\n{\n    return gCreateThreadFn(entryFunction, userData, threadName,\n        threadPriority, threadStackSize, threadId);\n}\n\nvoid androidSetCreateThreadFunc(android_create_thread_fn func)\n{\n    gCreateThreadFn = func;\n}\n\n#if defined(__ANDROID__)\nint androidSetThreadPriority(pid_t tid, int pri)\n{\n    int rc = 0;\n    int lasterr = 0;\n\n    if (pri >= ANDROID_PRIORITY_BACKGROUND) {\n        rc = set_sched_policy(tid, SP_BACKGROUND);\n    } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {\n        rc = set_sched_policy(tid, SP_FOREGROUND);\n    }\n\n    if (rc) {\n        lasterr = errno;\n    }\n\n    if (setpriority(PRIO_PROCESS, tid, pri) < 0) {\n        rc = INVALID_OPERATION;\n    } else {\n        errno = lasterr;\n    }\n\n    return rc;\n}\n\nint androidGetThreadPriority(pid_t tid) {\n    return getpriority(PRIO_PROCESS, tid);\n}\n\n#endif\n\nnamespace android {\n\n/*\n * ===========================================================================\n *      Mutex class\n * ===========================================================================\n */\n\n#if !defined(_WIN32)\n// implemented as inlines in threads.h\n#else\n\nMutex::Mutex()\n{\n    HANDLE hMutex;\n\n    assert(sizeof(hMutex) == sizeof(mState));\n\n    hMutex = CreateMutex(NULL, FALSE, NULL);\n    mState = (void*) hMutex;\n}\n\nMutex::Mutex(const char* name)\n{\n    // XXX: name not used for now\n    HANDLE hMutex;\n\n    assert(sizeof(hMutex) == sizeof(mState));\n\n    hMutex = CreateMutex(NULL, FALSE, NULL);\n    mState = (void*) hMutex;\n}\n\nMutex::Mutex(int type, const char* name)\n{\n    // XXX: type and name not used for now\n    HANDLE hMutex;\n\n    assert(sizeof(hMutex) == sizeof(mState));\n\n    hMutex = CreateMutex(NULL, FALSE, NULL);\n    mState = (void*) hMutex;\n}\n\nMutex::~Mutex()\n{\n    CloseHandle((HANDLE) mState);\n}\n\nstatus_t Mutex::lock()\n{\n    DWORD dwWaitResult;\n    dwWaitResult = WaitForSingleObject((HANDLE) mState, INFINITE);\n    return dwWaitResult != WAIT_OBJECT_0 ? -1 : NO_ERROR;\n}\n\nvoid Mutex::unlock()\n{\n    if (!ReleaseMutex((HANDLE) mState))\n        ALOG(LOG_WARN, \"thread\", \"WARNING: bad result from unlocking mutex\\n\");\n}\n\nstatus_t Mutex::tryLock()\n{\n    DWORD dwWaitResult;\n\n    dwWaitResult = WaitForSingleObject((HANDLE) mState, 0);\n    if (dwWaitResult != WAIT_OBJECT_0 && dwWaitResult != WAIT_TIMEOUT)\n        ALOG(LOG_WARN, \"thread\", \"WARNING: bad result from try-locking mutex\\n\");\n    return (dwWaitResult == WAIT_OBJECT_0) ? 0 : -1;\n}\n\n#endif // !defined(_WIN32)\n\n\n/*\n * ===========================================================================\n *      Condition class\n * ===========================================================================\n */\n\n#if !defined(_WIN32)\n// implemented as inlines in threads.h\n#else\n\n/*\n * Windows doesn't have a condition variable solution.  It's possible\n * to create one, but it's easy to get it wrong.  For a discussion, and\n * the origin of this implementation, see:\n *\n *  http://www.cs.wustl.edu/~schmidt/win32-cv-1.html\n *\n * The implementation shown on the page does NOT follow POSIX semantics.\n * As an optimization they require acquiring the external mutex before\n * calling signal() and broadcast(), whereas POSIX only requires grabbing\n * it before calling wait().  The implementation here has been un-optimized\n * to have the correct behavior.\n */\ntypedef struct WinCondition {\n    // Number of waiting threads.\n    int                 waitersCount;\n\n    // Serialize access to waitersCount.\n    CRITICAL_SECTION    waitersCountLock;\n\n    // Semaphore used to queue up threads waiting for the condition to\n    // become signaled.\n    HANDLE              sema;\n\n    // An auto-reset event used by the broadcast/signal thread to wait\n    // for all the waiting thread(s) to wake up and be released from\n    // the semaphore.\n    HANDLE              waitersDone;\n\n    // This mutex wouldn't be necessary if we required that the caller\n    // lock the external mutex before calling signal() and broadcast().\n    // I'm trying to mimic pthread semantics though.\n    HANDLE              internalMutex;\n\n    // Keeps track of whether we were broadcasting or signaling.  This\n    // allows us to optimize the code if we're just signaling.\n    bool                wasBroadcast;\n\n    status_t wait(WinCondition* condState, HANDLE hMutex, nsecs_t* abstime)\n    {\n        // Increment the wait count, avoiding race conditions.\n        EnterCriticalSection(&condState->waitersCountLock);\n        condState->waitersCount++;\n        //printf(\"+++ wait: incr waitersCount to %d (tid=%ld)\\n\",\n        //    condState->waitersCount, getThreadId());\n        LeaveCriticalSection(&condState->waitersCountLock);\n\n        DWORD timeout = INFINITE;\n        if (abstime) {\n            nsecs_t reltime = *abstime - systemTime();\n            if (reltime < 0)\n                reltime = 0;\n            timeout = reltime/1000000;\n        }\n\n        // Atomically release the external mutex and wait on the semaphore.\n        DWORD res =\n            SignalObjectAndWait(hMutex, condState->sema, timeout, FALSE);\n\n        //printf(\"+++ wait: awake (tid=%ld)\\n\", getThreadId());\n\n        // Reacquire lock to avoid race conditions.\n        EnterCriticalSection(&condState->waitersCountLock);\n\n        // No longer waiting.\n        condState->waitersCount--;\n\n        // Check to see if we're the last waiter after a broadcast.\n        bool lastWaiter = (condState->wasBroadcast && condState->waitersCount == 0);\n\n        //printf(\"+++ wait: lastWaiter=%d (wasBc=%d wc=%d)\\n\",\n        //    lastWaiter, condState->wasBroadcast, condState->waitersCount);\n\n        LeaveCriticalSection(&condState->waitersCountLock);\n\n        // If we're the last waiter thread during this particular broadcast\n        // then signal broadcast() that we're all awake.  It'll drop the\n        // internal mutex.\n        if (lastWaiter) {\n            // Atomically signal the \"waitersDone\" event and wait until we\n            // can acquire the internal mutex.  We want to do this in one step\n            // because it ensures that everybody is in the mutex FIFO before\n            // any thread has a chance to run.  Without it, another thread\n            // could wake up, do work, and hop back in ahead of us.\n            SignalObjectAndWait(condState->waitersDone, condState->internalMutex,\n                INFINITE, FALSE);\n        } else {\n            // Grab the internal mutex.\n            WaitForSingleObject(condState->internalMutex, INFINITE);\n        }\n\n        // Release the internal and grab the external.\n        ReleaseMutex(condState->internalMutex);\n        WaitForSingleObject(hMutex, INFINITE);\n\n        return res == WAIT_OBJECT_0 ? NO_ERROR : -1;\n    }\n} WinCondition;\n\n/*\n * Constructor.  Set up the WinCondition stuff.\n */\nCondition::Condition()\n{\n    WinCondition* condState = new WinCondition;\n\n    condState->waitersCount = 0;\n    condState->wasBroadcast = false;\n    // semaphore: no security, initial value of 0\n    condState->sema = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);\n    InitializeCriticalSection(&condState->waitersCountLock);\n    // auto-reset event, not signaled initially\n    condState->waitersDone = CreateEvent(NULL, FALSE, FALSE, NULL);\n    // used so we don't have to lock external mutex on signal/broadcast\n    condState->internalMutex = CreateMutex(NULL, FALSE, NULL);\n\n    mState = condState;\n}\n\n/*\n * Destructor.  Free Windows resources as well as our allocated storage.\n */\nCondition::~Condition()\n{\n    WinCondition* condState = (WinCondition*) mState;\n    if (condState != NULL) {\n        CloseHandle(condState->sema);\n        CloseHandle(condState->waitersDone);\n        delete condState;\n    }\n}\n\n\nstatus_t Condition::wait(Mutex& mutex)\n{\n    WinCondition* condState = (WinCondition*) mState;\n    HANDLE hMutex = (HANDLE) mutex.mState;\n\n    return ((WinCondition*)mState)->wait(condState, hMutex, NULL);\n}\n\nstatus_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)\n{\n    WinCondition* condState = (WinCondition*) mState;\n    HANDLE hMutex = (HANDLE) mutex.mState;\n    nsecs_t absTime = systemTime()+reltime;\n\n    return ((WinCondition*)mState)->wait(condState, hMutex, &absTime);\n}\n\n/*\n * Signal the condition variable, allowing one thread to continue.\n */\nvoid Condition::signal()\n{\n    WinCondition* condState = (WinCondition*) mState;\n\n    // Lock the internal mutex.  This ensures that we don't clash with\n    // broadcast().\n    WaitForSingleObject(condState->internalMutex, INFINITE);\n\n    EnterCriticalSection(&condState->waitersCountLock);\n    bool haveWaiters = (condState->waitersCount > 0);\n    LeaveCriticalSection(&condState->waitersCountLock);\n\n    // If no waiters, then this is a no-op.  Otherwise, knock the semaphore\n    // down a notch.\n    if (haveWaiters)\n        ReleaseSemaphore(condState->sema, 1, 0);\n\n    // Release internal mutex.\n    ReleaseMutex(condState->internalMutex);\n}\n\n/*\n * Signal the condition variable, allowing all threads to continue.\n *\n * First we have to wake up all threads waiting on the semaphore, then\n * we wait until all of the threads have actually been woken before\n * releasing the internal mutex.  This ensures that all threads are woken.\n */\nvoid Condition::broadcast()\n{\n    WinCondition* condState = (WinCondition*) mState;\n\n    // Lock the internal mutex.  This keeps the guys we're waking up\n    // from getting too far.\n    WaitForSingleObject(condState->internalMutex, INFINITE);\n\n    EnterCriticalSection(&condState->waitersCountLock);\n    bool haveWaiters = false;\n\n    if (condState->waitersCount > 0) {\n        haveWaiters = true;\n        condState->wasBroadcast = true;\n    }\n\n    if (haveWaiters) {\n        // Wake up all the waiters.\n        ReleaseSemaphore(condState->sema, condState->waitersCount, 0);\n\n        LeaveCriticalSection(&condState->waitersCountLock);\n\n        // Wait for all awakened threads to acquire the counting semaphore.\n        // The last guy who was waiting sets this.\n        WaitForSingleObject(condState->waitersDone, INFINITE);\n\n        // Reset wasBroadcast.  (No crit section needed because nobody\n        // else can wake up to poke at it.)\n        condState->wasBroadcast = 0;\n    } else {\n        // nothing to do\n        LeaveCriticalSection(&condState->waitersCountLock);\n    }\n\n    // Release internal mutex.\n    ReleaseMutex(condState->internalMutex);\n}\n\n#endif // !defined(_WIN32)\n\n// ----------------------------------------------------------------------------\n\n/*\n * This is our thread object!\n */\n\nThread::Thread(bool canCallJava)\n    :   mCanCallJava(canCallJava),\n        mThread(thread_id_t(-1)),\n        mLock(\"Thread::mLock\"),\n        mStatus(NO_ERROR),\n        mExitPending(false), mRunning(false)\n#if defined(__ANDROID__)\n        , mTid(-1)\n#endif\n{\n}\n\nThread::~Thread()\n{\n}\n\nstatus_t Thread::readyToRun()\n{\n    return NO_ERROR;\n}\n\nstatus_t Thread::run(const char* name, int32_t priority, size_t stack)\n{\n    LOG_ALWAYS_FATAL_IF(name == nullptr, \"thread name not provided to Thread::run\");\n\n    Mutex::Autolock _l(mLock);\n\n    if (mRunning) {\n        // thread already started\n        return INVALID_OPERATION;\n    }\n\n    // reset status and exitPending to their default value, so we can\n    // try again after an error happened (either below, or in readyToRun())\n    mStatus = NO_ERROR;\n    mExitPending = false;\n    mThread = thread_id_t(-1);\n\n    // hold a strong reference on ourself\n    mHoldSelf = this;\n\n    mRunning = true;\n\n    bool res;\n    if (mCanCallJava) {\n        res = createThreadEtc(_threadLoop,\n                this, name, priority, stack, &mThread);\n    } else {\n        res = androidCreateRawThreadEtc(_threadLoop,\n                this, name, priority, stack, &mThread);\n    }\n\n    if (res == false) {\n        mStatus = UNKNOWN_ERROR;   // something happened!\n        mRunning = false;\n        mThread = thread_id_t(-1);\n        mHoldSelf.clear();  // \"this\" may have gone away after this.\n\n        return UNKNOWN_ERROR;\n    }\n\n    // Do not refer to mStatus here: The thread is already running (may, in fact\n    // already have exited with a valid mStatus result). The NO_ERROR indication\n    // here merely indicates successfully starting the thread and does not\n    // imply successful termination/execution.\n    return NO_ERROR;\n\n    // Exiting scope of mLock is a memory barrier and allows new thread to run\n}\n\nint Thread::_threadLoop(void* user)\n{\n    Thread* const self = static_cast<Thread*>(user);\n\n    sp<Thread> strong(self->mHoldSelf);\n    wp<Thread> weak(strong);\n    self->mHoldSelf.clear();\n\n#if defined(__ANDROID__)\n    // this is very useful for debugging with gdb\n    self->mTid = gettid();\n#endif\n\n    bool first = true;\n\n    do {\n        bool result;\n        if (first) {\n            first = false;\n            self->mStatus = self->readyToRun();\n            result = (self->mStatus == NO_ERROR);\n\n            if (result && !self->exitPending()) {\n                // Binder threads (and maybe others) rely on threadLoop\n                // running at least once after a successful ::readyToRun()\n                // (unless, of course, the thread has already been asked to exit\n                // at that point).\n                // This is because threads are essentially used like this:\n                //   (new ThreadSubclass())->run();\n                // The caller therefore does not retain a strong reference to\n                // the thread and the thread would simply disappear after the\n                // successful ::readyToRun() call instead of entering the\n                // threadLoop at least once.\n                result = self->threadLoop();\n            }\n        } else {\n            result = self->threadLoop();\n        }\n\n        // establish a scope for mLock\n        {\n        Mutex::Autolock _l(self->mLock);\n        if (result == false || self->mExitPending) {\n            self->mExitPending = true;\n            self->mRunning = false;\n            // clear thread ID so that requestExitAndWait() does not exit if\n            // called by a new thread using the same thread ID as this one.\n            self->mThread = thread_id_t(-1);\n            // note that interested observers blocked in requestExitAndWait are\n            // awoken by broadcast, but blocked on mLock until break exits scope\n            self->mThreadExitedCondition.broadcast();\n            break;\n        }\n        }\n\n        // Release our strong reference, to let a chance to the thread\n        // to die a peaceful death.\n        strong.clear();\n        // And immediately, re-acquire a strong reference for the next loop\n        strong = weak.promote();\n    } while(strong != 0);\n\n    return 0;\n}\n\nvoid Thread::requestExit()\n{\n    Mutex::Autolock _l(mLock);\n    mExitPending = true;\n}\n\nstatus_t Thread::requestExitAndWait()\n{\n    Mutex::Autolock _l(mLock);\n    if (mThread == getThreadId()) {\n        ALOGW(\n        \"Thread (this=%p): don't call waitForExit() from this \"\n        \"Thread object's thread. It's a guaranteed deadlock!\",\n        this);\n\n        return WOULD_BLOCK;\n    }\n\n    mExitPending = true;\n\n    while (mRunning == true) {\n        mThreadExitedCondition.wait(mLock);\n    }\n    // This next line is probably not needed any more, but is being left for\n    // historical reference. Note that each interested party will clear flag.\n    mExitPending = false;\n\n    return mStatus;\n}\n\nstatus_t Thread::join()\n{\n    Mutex::Autolock _l(mLock);\n    if (mThread == getThreadId()) {\n        ALOGW(\n        \"Thread (this=%p): don't call join() from this \"\n        \"Thread object's thread. It's a guaranteed deadlock!\",\n        this);\n\n        return WOULD_BLOCK;\n    }\n\n    while (mRunning == true) {\n        mThreadExitedCondition.wait(mLock);\n    }\n\n    return mStatus;\n}\n\nbool Thread::isRunning() const {\n    Mutex::Autolock _l(mLock);\n    return mRunning;\n}\n\n#if defined(__ANDROID__)\npid_t Thread::getTid() const\n{\n    // mTid is not defined until the child initializes it, and the caller may need it earlier\n    Mutex::Autolock _l(mLock);\n    pid_t tid;\n    if (mRunning) {\n        pthread_t pthread = android_thread_id_t_to_pthread(mThread);\n        tid = pthread_gettid_np(pthread);\n    } else {\n        ALOGW(\"Thread (this=%p): getTid() is undefined before run()\", this);\n        tid = -1;\n    }\n    return tid;\n}\n#endif\n\nbool Thread::exitPending() const\n{\n    Mutex::Autolock _l(mLock);\n    return mExitPending;\n}\n\n\n\n};  // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/Timers.cpp",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Timer functions.\n//\n#include <utils/Timers.h>\n\n#include <limits.h>\n#include <sys/time.h>\n#include <time.h>\n\n#if defined(__ANDROID__)\nnsecs_t systemTime(int clock)\n{\n    static const clockid_t clocks[] = {\n            CLOCK_REALTIME,\n            CLOCK_MONOTONIC,\n            CLOCK_PROCESS_CPUTIME_ID,\n            CLOCK_THREAD_CPUTIME_ID,\n            CLOCK_BOOTTIME\n    };\n    struct timespec t;\n    t.tv_sec = t.tv_nsec = 0;\n    clock_gettime(clocks[clock], &t);\n    return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;\n}\n#else\nnsecs_t systemTime(int /*clock*/)\n{\n    // Clock support varies widely across hosts. Mac OS doesn't support\n    // posix clocks, older glibcs don't support CLOCK_BOOTTIME and Windows\n    // is windows.\n    struct timeval t;\n    t.tv_sec = t.tv_usec = 0;\n    gettimeofday(&t, NULL);\n    return nsecs_t(t.tv_sec)*1000000000LL + nsecs_t(t.tv_usec)*1000LL;\n}\n#endif\n\nint toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime)\n{\n    int timeoutDelayMillis;\n    if (timeoutTime > referenceTime) {\n        uint64_t timeoutDelay = uint64_t(timeoutTime - referenceTime);\n        if (timeoutDelay > uint64_t((INT_MAX - 1) * 1000000LL)) {\n            timeoutDelayMillis = -1;\n        } else {\n            timeoutDelayMillis = (timeoutDelay + 999999LL) / 1000000LL;\n        }\n    } else {\n        timeoutDelayMillis = 0;\n    }\n    return timeoutDelayMillis;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/Tokenizer.cpp",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"Tokenizer\"\n\n#include <stdlib.h>\n#include <unistd.h>\n#include <fcntl.h>\n#include <errno.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <utils/Log.h>\n#include <utils/Tokenizer.h>\n\n// Enables debug output for the tokenizer.\n#define DEBUG_TOKENIZER 0\n\n\nnamespace android {\n\nstatic inline bool isDelimiter(char ch, const char* delimiters) {\n    return strchr(delimiters, ch) != NULL;\n}\n\nTokenizer::Tokenizer(const String8& filename, FileMap* fileMap, char* buffer,\n        bool ownBuffer, size_t length) :\n        mFilename(filename), mFileMap(fileMap),\n        mBuffer(buffer), mOwnBuffer(ownBuffer), mLength(length),\n        mCurrent(buffer), mLineNumber(1) {\n}\n\nTokenizer::~Tokenizer() {\n    delete mFileMap;\n    if (mOwnBuffer) {\n        delete[] mBuffer;\n    }\n}\n\nstatus_t Tokenizer::open(const String8& filename, Tokenizer** outTokenizer) {\n    *outTokenizer = NULL;\n\n    int result = NO_ERROR;\n    int fd = ::open(filename.string(), O_RDONLY);\n    if (fd < 0) {\n        result = -errno;\n        ALOGE(\"Error opening file '%s': %s\", filename.string(), strerror(errno));\n    } else {\n        struct stat stat;\n        if (fstat(fd, &stat)) {\n            result = -errno;\n            ALOGE(\"Error getting size of file '%s': %s\", filename.string(), strerror(errno));\n        } else {\n            size_t length = size_t(stat.st_size);\n\n            FileMap* fileMap = new FileMap();\n            bool ownBuffer = false;\n            char* buffer;\n            if (fileMap->create(NULL, fd, 0, length, true)) {\n                fileMap->advise(FileMap::SEQUENTIAL);\n                buffer = static_cast<char*>(fileMap->getDataPtr());\n            } else {\n                delete fileMap;\n                fileMap = NULL;\n\n                // Fall back to reading into a buffer since we can't mmap files in sysfs.\n                // The length we obtained from stat is wrong too (it will always be 4096)\n                // so we must trust that read will read the entire file.\n                buffer = new char[length];\n                ownBuffer = true;\n                ssize_t nrd = read(fd, buffer, length);\n                if (nrd < 0) {\n                    result = -errno;\n                    ALOGE(\"Error reading file '%s': %s\", filename.string(), strerror(errno));\n                    delete[] buffer;\n                    buffer = NULL;\n                } else {\n                    length = size_t(nrd);\n                }\n            }\n\n            if (!result) {\n                *outTokenizer = new Tokenizer(filename, fileMap, buffer, ownBuffer, length);\n            }\n        }\n        close(fd);\n    }\n    return result;\n}\n\nstatus_t Tokenizer::fromContents(const String8& filename,\n        const char* contents, Tokenizer** outTokenizer) {\n    *outTokenizer = new Tokenizer(filename, NULL,\n            const_cast<char*>(contents), false, strlen(contents));\n    return OK;\n}\n\nString8 Tokenizer::getLocation() const {\n    String8 result;\n    result.appendFormat(\"%s:%d\", mFilename.string(), mLineNumber);\n    return result;\n}\n\nString8 Tokenizer::peekRemainderOfLine() const {\n    const char* end = getEnd();\n    const char* eol = mCurrent;\n    while (eol != end) {\n        char ch = *eol;\n        if (ch == '\\n') {\n            break;\n        }\n        eol += 1;\n    }\n    return String8(mCurrent, eol - mCurrent);\n}\n\nString8 Tokenizer::nextToken(const char* delimiters) {\n#if DEBUG_TOKENIZER\n    ALOGD(\"nextToken\");\n#endif\n    const char* end = getEnd();\n    const char* tokenStart = mCurrent;\n    while (mCurrent != end) {\n        char ch = *mCurrent;\n        if (ch == '\\n' || isDelimiter(ch, delimiters)) {\n            break;\n        }\n        mCurrent += 1;\n    }\n    return String8(tokenStart, mCurrent - tokenStart);\n}\n\nvoid Tokenizer::nextLine() {\n#if DEBUG_TOKENIZER\n    ALOGD(\"nextLine\");\n#endif\n    const char* end = getEnd();\n    while (mCurrent != end) {\n        char ch = *(mCurrent++);\n        if (ch == '\\n') {\n            mLineNumber += 1;\n            break;\n        }\n    }\n}\n\nvoid Tokenizer::skipDelimiters(const char* delimiters) {\n#if DEBUG_TOKENIZER\n    ALOGD(\"skipDelimiters\");\n#endif\n    const char* end = getEnd();\n    while (mCurrent != end) {\n        char ch = *mCurrent;\n        if (ch == '\\n' || !isDelimiter(ch, delimiters)) {\n            break;\n        }\n        mCurrent += 1;\n    }\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/Trace.cpp",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <utils/misc.h>\n#include <utils/Trace.h>\n\nstatic void traceInit() __attribute__((constructor));\n\nstatic void traceInit()\n{\n    ::android::add_sysprop_change_callback(atrace_update_tags, 0);\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/Unicode.cpp",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <log/log.h>\n#include <utils/Unicode.h>\n\n#include <stddef.h>\n\n#if defined(_WIN32)\n# undef  nhtol\n# undef  htonl\n# undef  nhtos\n# undef  htons\n\n# define ntohl(x)    ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )\n# define htonl(x)    ntohl(x)\n# define ntohs(x)    ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )\n# define htons(x)    ntohs(x)\n#else\n# include <netinet/in.h>\n#endif\n\nextern \"C\" {\n\nstatic const char32_t kByteMask = 0x000000BF;\nstatic const char32_t kByteMark = 0x00000080;\n\n// Surrogates aren't valid for UTF-32 characters, so define some\n// constants that will let us screen them out.\nstatic const char32_t kUnicodeSurrogateHighStart  = 0x0000D800;\n// Unused, here for completeness:\n// static const char32_t kUnicodeSurrogateHighEnd = 0x0000DBFF;\n// static const char32_t kUnicodeSurrogateLowStart = 0x0000DC00;\nstatic const char32_t kUnicodeSurrogateLowEnd     = 0x0000DFFF;\nstatic const char32_t kUnicodeSurrogateStart      = kUnicodeSurrogateHighStart;\nstatic const char32_t kUnicodeSurrogateEnd        = kUnicodeSurrogateLowEnd;\nstatic const char32_t kUnicodeMaxCodepoint        = 0x0010FFFF;\n\n// Mask used to set appropriate bits in first byte of UTF-8 sequence,\n// indexed by number of bytes in the sequence.\n// 0xxxxxxx\n// -> (00-7f) 7bit. Bit mask for the first byte is 0x00000000\n// 110yyyyx 10xxxxxx\n// -> (c0-df)(80-bf) 11bit. Bit mask is 0x000000C0\n// 1110yyyy 10yxxxxx 10xxxxxx\n// -> (e0-ef)(80-bf)(80-bf) 16bit. Bit mask is 0x000000E0\n// 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx\n// -> (f0-f7)(80-bf)(80-bf)(80-bf) 21bit. Bit mask is 0x000000F0\nstatic const char32_t kFirstByteMark[] = {\n    0x00000000, 0x00000000, 0x000000C0, 0x000000E0, 0x000000F0\n};\n\n// --------------------------------------------------------------------------\n// UTF-32\n// --------------------------------------------------------------------------\n\n/**\n * Return number of UTF-8 bytes required for the character. If the character\n * is invalid, return size of 0.\n */\nstatic inline size_t utf32_codepoint_utf8_length(char32_t srcChar)\n{\n    // Figure out how many bytes the result will require.\n    if (srcChar < 0x00000080) {\n        return 1;\n    } else if (srcChar < 0x00000800) {\n        return 2;\n    } else if (srcChar < 0x00010000) {\n        if ((srcChar < kUnicodeSurrogateStart) || (srcChar > kUnicodeSurrogateEnd)) {\n            return 3;\n        } else {\n            // Surrogates are invalid UTF-32 characters.\n            return 0;\n        }\n    }\n    // Max code point for Unicode is 0x0010FFFF.\n    else if (srcChar <= kUnicodeMaxCodepoint) {\n        return 4;\n    } else {\n        // Invalid UTF-32 character.\n        return 0;\n    }\n}\n\n// Write out the source character to <dstP>.\n\nstatic inline void utf32_codepoint_to_utf8(uint8_t* dstP, char32_t srcChar, size_t bytes)\n{\n    dstP += bytes;\n    switch (bytes)\n    {   /* note: everything falls through. */\n        case 4: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;\n        case 3: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;\n        case 2: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;\n        case 1: *--dstP = (uint8_t)(srcChar | kFirstByteMark[bytes]);\n    }\n}\n\nsize_t strlen32(const char32_t *s)\n{\n  const char32_t *ss = s;\n  while ( *ss )\n    ss++;\n  return ss-s;\n}\n\nsize_t strnlen32(const char32_t *s, size_t maxlen)\n{\n  const char32_t *ss = s;\n  while ((maxlen > 0) && *ss) {\n    ss++;\n    maxlen--;\n  }\n  return ss-s;\n}\n\nstatic inline int32_t utf32_at_internal(const char* cur, size_t *num_read)\n{\n    const char first_char = *cur;\n    if ((first_char & 0x80) == 0) { // ASCII\n        *num_read = 1;\n        return *cur;\n    }\n    cur++;\n    char32_t mask, to_ignore_mask;\n    size_t num_to_read = 0;\n    char32_t utf32 = first_char;\n    for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0xFFFFFF80;\n         (first_char & mask);\n         num_to_read++, to_ignore_mask |= mask, mask >>= 1) {\n        // 0x3F == 00111111\n        utf32 = (utf32 << 6) + (*cur++ & 0x3F);\n    }\n    to_ignore_mask |= mask;\n    utf32 &= ~(to_ignore_mask << (6 * (num_to_read - 1)));\n\n    *num_read = num_to_read;\n    return static_cast<int32_t>(utf32);\n}\n\nint32_t utf32_from_utf8_at(const char *src, size_t src_len, size_t index, size_t *next_index)\n{\n    if (index >= src_len) {\n        return -1;\n    }\n    size_t dummy_index;\n    if (next_index == NULL) {\n        next_index = &dummy_index;\n    }\n    size_t num_read;\n    int32_t ret = utf32_at_internal(src + index, &num_read);\n    if (ret >= 0) {\n        *next_index = index + num_read;\n    }\n\n    return ret;\n}\n\nssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len)\n{\n    if (src == NULL || src_len == 0) {\n        return -1;\n    }\n\n    size_t ret = 0;\n    const char32_t *end = src + src_len;\n    while (src < end) {\n        ret += utf32_codepoint_utf8_length(*src++);\n    }\n    return ret;\n}\n\nvoid utf32_to_utf8(const char32_t* src, size_t src_len, char* dst, size_t dst_len)\n{\n    if (src == NULL || src_len == 0 || dst == NULL) {\n        return;\n    }\n\n    const char32_t *cur_utf32 = src;\n    const char32_t *end_utf32 = src + src_len;\n    char *cur = dst;\n    while (cur_utf32 < end_utf32) {\n        size_t len = utf32_codepoint_utf8_length(*cur_utf32);\n        LOG_ALWAYS_FATAL_IF(dst_len < len, \"%zu < %zu\", dst_len, len);\n        utf32_codepoint_to_utf8((uint8_t *)cur, *cur_utf32++, len);\n        cur += len;\n        dst_len -= len;\n    }\n    LOG_ALWAYS_FATAL_IF(dst_len < 1, \"dst_len < 1: %zu < 1\", dst_len);\n    *cur = '\\0';\n}\n\n// --------------------------------------------------------------------------\n// UTF-16\n// --------------------------------------------------------------------------\n\nint strcmp16(const char16_t *s1, const char16_t *s2)\n{\n  char16_t ch;\n  int d = 0;\n\n  while ( 1 ) {\n    d = (int)(ch = *s1++) - (int)*s2++;\n    if ( d || !ch )\n      break;\n  }\n\n  return d;\n}\n\nint strncmp16(const char16_t *s1, const char16_t *s2, size_t n)\n{\n  char16_t ch;\n  int d = 0;\n\n  if (n == 0) {\n    return 0;\n  }\n\n  do {\n    d = (int)(ch = *s1++) - (int)*s2++;\n    if ( d || !ch ) {\n      break;\n    }\n  } while (--n);\n\n  return d;\n}\n\nchar16_t *strcpy16(char16_t *dst, const char16_t *src)\n{\n  char16_t *q = dst;\n  const char16_t *p = src;\n  char16_t ch;\n\n  do {\n    *q++ = ch = *p++;\n  } while ( ch );\n\n  return dst;\n}\n\nsize_t strlen16(const char16_t *s)\n{\n  const char16_t *ss = s;\n  while ( *ss )\n    ss++;\n  return ss-s;\n}\n\n\nchar16_t *strncpy16(char16_t *dst, const char16_t *src, size_t n)\n{\n  char16_t *q = dst;\n  const char16_t *p = src;\n  char ch;\n\n  while (n) {\n    n--;\n    *q++ = ch = *p++;\n    if ( !ch )\n      break;\n  }\n\n  *q = 0;\n\n  return dst;\n}\n\nsize_t strnlen16(const char16_t *s, size_t maxlen)\n{\n  const char16_t *ss = s;\n\n  /* Important: the maxlen test must precede the reference through ss;\n     since the byte beyond the maximum may segfault */\n  while ((maxlen > 0) && *ss) {\n    ss++;\n    maxlen--;\n  }\n  return ss-s;\n}\n\nchar16_t* strstr16(const char16_t* src, const char16_t* target)\n{\n    const char16_t needle = *target++;\n    const size_t target_len = strlen16(target);\n    if (needle != '\\0') {\n      do {\n        do {\n          if (*src == '\\0') {\n            return nullptr;\n          }\n        } while (*src++ != needle);\n      } while (strncmp16(src, target, target_len) != 0);\n      src--;\n    }\n\n    return (char16_t*)src;\n}\n\n\nint strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2)\n{\n    const char16_t* e1 = s1+n1;\n    const char16_t* e2 = s2+n2;\n\n    while (s1 < e1 && s2 < e2) {\n        const int d = (int)*s1++ - (int)*s2++;\n        if (d) {\n            return d;\n        }\n    }\n\n    return n1 < n2\n        ? (0 - (int)*s2)\n        : (n1 > n2\n           ? ((int)*s1 - 0)\n           : 0);\n}\n\nint strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2)\n{\n    const char16_t* e1 = s1H+n1;\n    const char16_t* e2 = s2N+n2;\n\n    while (s1H < e1 && s2N < e2) {\n        const char16_t c2 = ntohs(*s2N);\n        const int d = (int)*s1H++ - (int)c2;\n        s2N++;\n        if (d) {\n            return d;\n        }\n    }\n\n    return n1 < n2\n        ? (0 - (int)ntohs(*s2N))\n        : (n1 > n2\n           ? ((int)*s1H - 0)\n           : 0);\n}\n\nvoid utf16_to_utf8(const char16_t* src, size_t src_len, char* dst, size_t dst_len)\n{\n    if (src == NULL || src_len == 0 || dst == NULL) {\n        return;\n    }\n\n    const char16_t* cur_utf16 = src;\n    const char16_t* const end_utf16 = src + src_len;\n    char *cur = dst;\n    while (cur_utf16 < end_utf16) {\n        char32_t utf32;\n        // surrogate pairs\n        if((*cur_utf16 & 0xFC00) == 0xD800 && (cur_utf16 + 1) < end_utf16\n                && (*(cur_utf16 + 1) & 0xFC00) == 0xDC00) {\n            utf32 = (*cur_utf16++ - 0xD800) << 10;\n            utf32 |= *cur_utf16++ - 0xDC00;\n            utf32 += 0x10000;\n        } else {\n            utf32 = (char32_t) *cur_utf16++;\n        }\n        const size_t len = utf32_codepoint_utf8_length(utf32);\n        LOG_ALWAYS_FATAL_IF(dst_len < len, \"%zu < %zu\", dst_len, len);\n        utf32_codepoint_to_utf8((uint8_t*)cur, utf32, len);\n        cur += len;\n        dst_len -= len;\n    }\n    LOG_ALWAYS_FATAL_IF(dst_len < 1, \"%zu < 1\", dst_len);\n    *cur = '\\0';\n}\n\n// --------------------------------------------------------------------------\n// UTF-8\n// --------------------------------------------------------------------------\n\nssize_t utf8_length(const char *src)\n{\n    const char *cur = src;\n    size_t ret = 0;\n    while (*cur != '\\0') {\n        const char first_char = *cur++;\n        if ((first_char & 0x80) == 0) { // ASCII\n            ret += 1;\n            continue;\n        }\n        // (UTF-8's character must not be like 10xxxxxx,\n        //  but 110xxxxx, 1110xxxx, ... or 1111110x)\n        if ((first_char & 0x40) == 0) {\n            return -1;\n        }\n\n        int32_t mask, to_ignore_mask;\n        size_t num_to_read = 0;\n        char32_t utf32 = 0;\n        for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0x80;\n             num_to_read < 5 && (first_char & mask);\n             num_to_read++, to_ignore_mask |= mask, mask >>= 1) {\n            if ((*cur & 0xC0) != 0x80) { // must be 10xxxxxx\n                return -1;\n            }\n            // 0x3F == 00111111\n            utf32 = (utf32 << 6) + (*cur++ & 0x3F);\n        }\n        // \"first_char\" must be (110xxxxx - 11110xxx)\n        if (num_to_read == 5) {\n            return -1;\n        }\n        to_ignore_mask |= mask;\n        utf32 |= ((~to_ignore_mask) & first_char) << (6 * (num_to_read - 1));\n        if (utf32 > kUnicodeMaxCodepoint) {\n            return -1;\n        }\n\n        ret += num_to_read;\n    }\n    return ret;\n}\n\nssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len)\n{\n    if (src == NULL || src_len == 0) {\n        return -1;\n    }\n\n    size_t ret = 0;\n    const char16_t* const end = src + src_len;\n    while (src < end) {\n        if ((*src & 0xFC00) == 0xD800 && (src + 1) < end\n                && (*(src + 1) & 0xFC00) == 0xDC00) {\n            // surrogate pairs are always 4 bytes.\n            ret += 4;\n            src += 2;\n        } else {\n            ret += utf32_codepoint_utf8_length((char32_t) *src++);\n        }\n    }\n    return ret;\n}\n\n/**\n * Returns 1-4 based on the number of leading bits.\n *\n * 1111 -> 4\n * 1110 -> 3\n * 110x -> 2\n * 10xx -> 1\n * 0xxx -> 1\n */\nstatic inline size_t utf8_codepoint_len(uint8_t ch)\n{\n    return ((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1;\n}\n\nstatic inline void utf8_shift_and_mask(uint32_t* codePoint, const uint8_t byte)\n{\n    *codePoint <<= 6;\n    *codePoint |= 0x3F & byte;\n}\n\nsize_t utf8_to_utf32_length(const char *src, size_t src_len)\n{\n    if (src == NULL || src_len == 0) {\n        return 0;\n    }\n    size_t ret = 0;\n    const char* cur;\n    const char* end;\n    size_t num_to_skip;\n    for (cur = src, end = src + src_len, num_to_skip = 1;\n         cur < end;\n         cur += num_to_skip, ret++) {\n        const char first_char = *cur;\n        num_to_skip = 1;\n        if ((first_char & 0x80) == 0) {  // ASCII\n            continue;\n        }\n        int32_t mask;\n\n        for (mask = 0x40; (first_char & mask); num_to_skip++, mask >>= 1) {\n        }\n    }\n    return ret;\n}\n\nvoid utf8_to_utf32(const char* src, size_t src_len, char32_t* dst)\n{\n    if (src == NULL || src_len == 0 || dst == NULL) {\n        return;\n    }\n\n    const char* cur = src;\n    const char* const end = src + src_len;\n    char32_t* cur_utf32 = dst;\n    while (cur < end) {\n        size_t num_read;\n        *cur_utf32++ = static_cast<char32_t>(utf32_at_internal(cur, &num_read));\n        cur += num_read;\n    }\n    *cur_utf32 = 0;\n}\n\nstatic inline uint32_t utf8_to_utf32_codepoint(const uint8_t *src, size_t length)\n{\n    uint32_t unicode;\n\n    switch (length)\n    {\n        case 1:\n            return src[0];\n        case 2:\n            unicode = src[0] & 0x1f;\n            utf8_shift_and_mask(&unicode, src[1]);\n            return unicode;\n        case 3:\n            unicode = src[0] & 0x0f;\n            utf8_shift_and_mask(&unicode, src[1]);\n            utf8_shift_and_mask(&unicode, src[2]);\n            return unicode;\n        case 4:\n            unicode = src[0] & 0x07;\n            utf8_shift_and_mask(&unicode, src[1]);\n            utf8_shift_and_mask(&unicode, src[2]);\n            utf8_shift_and_mask(&unicode, src[3]);\n            return unicode;\n        default:\n            return 0xffff;\n    }\n\n    //printf(\"Char at %p: len=%d, utf-16=%p\\n\", src, length, (void*)result);\n}\n\nssize_t utf8_to_utf16_length(const uint8_t* u8str, size_t u8len)\n{\n    const uint8_t* const u8end = u8str + u8len;\n    const uint8_t* u8cur = u8str;\n\n    /* Validate that the UTF-8 is the correct len */\n    size_t u16measuredLen = 0;\n    while (u8cur < u8end) {\n        u16measuredLen++;\n        int u8charLen = utf8_codepoint_len(*u8cur);\n        uint32_t codepoint = utf8_to_utf32_codepoint(u8cur, u8charLen);\n        if (codepoint > 0xFFFF) u16measuredLen++; // this will be a surrogate pair in utf16\n        u8cur += u8charLen;\n    }\n\n    /**\n     * Make sure that we ended where we thought we would and the output UTF-16\n     * will be exactly how long we were told it would be.\n     */\n    if (u8cur != u8end) {\n        return -1;\n    }\n\n    return u16measuredLen;\n}\n\nchar16_t* utf8_to_utf16_no_null_terminator(const uint8_t* u8str, size_t u8len, char16_t* u16str)\n{\n    const uint8_t* const u8end = u8str + u8len;\n    const uint8_t* u8cur = u8str;\n    char16_t* u16cur = u16str;\n\n    while (u8cur < u8end) {\n        size_t u8len = utf8_codepoint_len(*u8cur);\n        uint32_t codepoint = utf8_to_utf32_codepoint(u8cur, u8len);\n\n        // Convert the UTF32 codepoint to one or more UTF16 codepoints\n        if (codepoint <= 0xFFFF) {\n            // Single UTF16 character\n            *u16cur++ = (char16_t) codepoint;\n        } else {\n            // Multiple UTF16 characters with surrogates\n            codepoint = codepoint - 0x10000;\n            *u16cur++ = (char16_t) ((codepoint >> 10) + 0xD800);\n            *u16cur++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);\n        }\n\n        u8cur += u8len;\n    }\n    return u16cur;\n}\n\nvoid utf8_to_utf16(const uint8_t* u8str, size_t u8len, char16_t* u16str) {\n    char16_t* end = utf8_to_utf16_no_null_terminator(u8str, u8len, u16str);\n    *end = 0;\n}\n\nchar16_t* utf8_to_utf16_n(const uint8_t* src, size_t srcLen, char16_t* dst, size_t dstLen) {\n    const uint8_t* const u8end = src + srcLen;\n    const uint8_t* u8cur = src;\n    const char16_t* const u16end = dst + dstLen;\n    char16_t* u16cur = dst;\n\n    while (u8cur < u8end && u16cur < u16end) {\n        size_t u8len = utf8_codepoint_len(*u8cur);\n        uint32_t codepoint = utf8_to_utf32_codepoint(u8cur, u8len);\n\n        // Convert the UTF32 codepoint to one or more UTF16 codepoints\n        if (codepoint <= 0xFFFF) {\n            // Single UTF16 character\n            *u16cur++ = (char16_t) codepoint;\n        } else {\n            // Multiple UTF16 characters with surrogates\n            codepoint = codepoint - 0x10000;\n            *u16cur++ = (char16_t) ((codepoint >> 10) + 0xD800);\n            if (u16cur >= u16end) {\n                // Ooops...  not enough room for this surrogate pair.\n                return u16cur-1;\n            }\n            *u16cur++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);\n        }\n\n        u8cur += u8len;\n    }\n    return u16cur;\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/VectorImpl.cpp",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"Vector\"\n\n#include <string.h>\n#include <stdlib.h>\n#include <stdio.h>\n\n#include <cutils/log.h>\n#include <safe_iop.h>\n\n#include <utils/Errors.h>\n#include <utils/VectorImpl.h>\n\n#include \"SharedBuffer.h\"\n\n/*****************************************************************************/\n\n\nnamespace android {\n\n// ----------------------------------------------------------------------------\n\nconst size_t kMinVectorCapacity = 4;\n\nstatic inline size_t max(size_t a, size_t b) {\n    return a>b ? a : b;\n}\n\n// ----------------------------------------------------------------------------\n\nVectorImpl::VectorImpl(size_t itemSize, uint32_t flags)\n    : mStorage(0), mCount(0), mFlags(flags), mItemSize(itemSize)\n{\n}\n\nVectorImpl::VectorImpl(const VectorImpl& rhs)\n    :   mStorage(rhs.mStorage), mCount(rhs.mCount),\n        mFlags(rhs.mFlags), mItemSize(rhs.mItemSize)\n{\n    if (mStorage) {\n        SharedBuffer::bufferFromData(mStorage)->acquire();\n    }\n}\n\nVectorImpl::~VectorImpl()\n{\n    ALOGW_IF(mCount,\n        \"[%p] subclasses of VectorImpl must call finish_vector()\"\n        \" in their destructor. Leaking %d bytes.\",\n        this, (int)(mCount*mItemSize));\n    // We can't call _do_destroy() here because the vtable is already gone. \n}\n\nVectorImpl& VectorImpl::operator = (const VectorImpl& rhs)\n{\n    LOG_ALWAYS_FATAL_IF(mItemSize != rhs.mItemSize,\n        \"Vector<> have different types (this=%p, rhs=%p)\", this, &rhs);\n    if (this != &rhs) {\n        release_storage();\n        if (rhs.mCount) {\n            mStorage = rhs.mStorage;\n            mCount = rhs.mCount;\n            SharedBuffer::bufferFromData(mStorage)->acquire();\n        } else {\n            mStorage = 0;\n            mCount = 0;\n        }\n    }\n    return *this;\n}\n\nvoid* VectorImpl::editArrayImpl()\n{\n    if (mStorage) {\n        const SharedBuffer* sb = SharedBuffer::bufferFromData(mStorage);\n        SharedBuffer* editable = sb->attemptEdit();\n        if (editable == 0) {\n            // If we're here, we're not the only owner of the buffer.\n            // We must make a copy of it.\n            editable = SharedBuffer::alloc(sb->size());\n            // Fail instead of returning a pointer to storage that's not\n            // editable. Otherwise we'd be editing the contents of a buffer\n            // for which we're not the only owner, which is undefined behaviour.\n            LOG_ALWAYS_FATAL_IF(editable == NULL);\n            _do_copy(editable->data(), mStorage, mCount);\n            release_storage();\n            mStorage = editable->data();\n        }\n    }\n    return mStorage;\n}\n\nsize_t VectorImpl::capacity() const\n{\n    if (mStorage) {\n        return SharedBuffer::bufferFromData(mStorage)->size() / mItemSize;\n    }\n    return 0;\n}\n\nssize_t VectorImpl::insertVectorAt(const VectorImpl& vector, size_t index)\n{\n    return insertArrayAt(vector.arrayImpl(), index, vector.size());\n}\n\nssize_t VectorImpl::appendVector(const VectorImpl& vector)\n{\n    return insertVectorAt(vector, size());\n}\n\nssize_t VectorImpl::insertArrayAt(const void* array, size_t index, size_t length)\n{\n    if (index > size())\n        return BAD_INDEX;\n    void* where = _grow(index, length);\n    if (where) {\n        _do_copy(where, array, length);\n    }\n    return where ? index : (ssize_t)NO_MEMORY;\n}\n\nssize_t VectorImpl::appendArray(const void* array, size_t length)\n{\n    return insertArrayAt(array, size(), length);\n}\n\nssize_t VectorImpl::insertAt(size_t index, size_t numItems)\n{\n    return insertAt(0, index, numItems);\n}\n\nssize_t VectorImpl::insertAt(const void* item, size_t index, size_t numItems)\n{\n    if (index > size())\n        return BAD_INDEX;\n    void* where = _grow(index, numItems);\n    if (where) {\n        if (item) {\n            _do_splat(where, item, numItems);\n        } else {\n            _do_construct(where, numItems);\n        }\n    }\n    return where ? index : (ssize_t)NO_MEMORY;\n}\n\nstatic int sortProxy(const void* lhs, const void* rhs, void* func)\n{\n    return (*(VectorImpl::compar_t)func)(lhs, rhs);\n}\n\nstatus_t VectorImpl::sort(VectorImpl::compar_t cmp)\n{\n    return sort(sortProxy, (void*)cmp);\n}\n\nstatus_t VectorImpl::sort(VectorImpl::compar_r_t cmp, void* state)\n{\n    // the sort must be stable. we're using insertion sort which\n    // is well suited for small and already sorted arrays\n    // for big arrays, it could be better to use mergesort\n    const ssize_t count = size();\n    if (count > 1) {\n        void* array = const_cast<void*>(arrayImpl());\n        void* temp = 0;\n        ssize_t i = 1;\n        while (i < count) {\n            void* item = reinterpret_cast<char*>(array) + mItemSize*(i);\n            void* curr = reinterpret_cast<char*>(array) + mItemSize*(i-1);\n            if (cmp(curr, item, state) > 0) {\n\n                if (!temp) {\n                    // we're going to have to modify the array...\n                    array = editArrayImpl();\n                    if (!array) return NO_MEMORY;\n                    temp = malloc(mItemSize);\n                    if (!temp) return NO_MEMORY;\n                    item = reinterpret_cast<char*>(array) + mItemSize*(i);\n                    curr = reinterpret_cast<char*>(array) + mItemSize*(i-1);\n                } else {\n                    _do_destroy(temp, 1);\n                }\n\n                _do_copy(temp, item, 1);\n\n                ssize_t j = i-1;\n                void* next = reinterpret_cast<char*>(array) + mItemSize*(i);                    \n                do {\n                    _do_destroy(next, 1);\n                    _do_copy(next, curr, 1);\n                    next = curr;\n                    --j;\n                    curr = NULL;\n                    if (j >= 0) {\n                        curr = reinterpret_cast<char*>(array) + mItemSize*(j);\n                    }\n                } while (j>=0 && (cmp(curr, temp, state) > 0));\n\n                _do_destroy(next, 1);\n                _do_copy(next, temp, 1);\n            }\n            i++;\n        }\n        \n        if (temp) {\n            _do_destroy(temp, 1);\n            free(temp);\n        }\n    }\n    return NO_ERROR;\n}\n\nvoid VectorImpl::pop()\n{\n    if (size())\n        removeItemsAt(size()-1, 1);\n}\n\nvoid VectorImpl::push()\n{\n    push(0);\n}\n\nvoid VectorImpl::push(const void* item)\n{\n    insertAt(item, size());\n}\n\nssize_t VectorImpl::add()\n{\n    return add(0);\n}\n\nssize_t VectorImpl::add(const void* item)\n{\n    return insertAt(item, size());\n}\n\nssize_t VectorImpl::replaceAt(size_t index)\n{\n    return replaceAt(0, index);\n}\n\nssize_t VectorImpl::replaceAt(const void* prototype, size_t index)\n{\n    ALOG_ASSERT(index<size(),\n        \"[%p] replace: index=%d, size=%d\", this, (int)index, (int)size());\n\n    if (index >= size()) {\n        return BAD_INDEX;\n    }\n\n    void* item = editItemLocation(index);\n    if (item != prototype) {\n        if (item == 0)\n            return NO_MEMORY;\n        _do_destroy(item, 1);\n        if (prototype == 0) {\n            _do_construct(item, 1);\n        } else {\n            _do_copy(item, prototype, 1);\n        }\n    }\n    return ssize_t(index);\n}\n\nssize_t VectorImpl::removeItemsAt(size_t index, size_t count)\n{\n    ALOG_ASSERT((index+count)<=size(),\n        \"[%p] remove: index=%d, count=%d, size=%d\",\n               this, (int)index, (int)count, (int)size());\n\n    if ((index+count) > size())\n        return BAD_VALUE;\n   _shrink(index, count);\n   return index;\n}\n\nvoid VectorImpl::finish_vector()\n{\n    release_storage();\n    mStorage = 0;\n    mCount = 0;\n}\n\nvoid VectorImpl::clear()\n{\n    _shrink(0, mCount);\n}\n\nvoid* VectorImpl::editItemLocation(size_t index)\n{\n    ALOG_ASSERT(index<capacity(),\n        \"[%p] editItemLocation: index=%d, capacity=%d, count=%d\",\n        this, (int)index, (int)capacity(), (int)mCount);\n\n    if (index < capacity()) {\n        void* buffer = editArrayImpl();\n        if (buffer) {\n            return reinterpret_cast<char*>(buffer) + index*mItemSize;\n        }\n    }\n    return 0;\n}\n\nconst void* VectorImpl::itemLocation(size_t index) const\n{\n    ALOG_ASSERT(index<capacity(),\n        \"[%p] itemLocation: index=%d, capacity=%d, count=%d\",\n        this, (int)index, (int)capacity(), (int)mCount);\n\n    if (index < capacity()) {\n        const  void* buffer = arrayImpl();\n        if (buffer) {\n            return reinterpret_cast<const char*>(buffer) + index*mItemSize;\n        }\n    }\n    return 0;\n}\n\nssize_t VectorImpl::setCapacity(size_t new_capacity)\n{\n    // The capacity must always be greater than or equal to the size\n    // of this vector.\n    if (new_capacity <= size()) {\n        return capacity();\n    }\n\n    size_t new_allocation_size = 0;\n    LOG_ALWAYS_FATAL_IF(!safe_mul(&new_allocation_size, new_capacity, mItemSize));\n    SharedBuffer* sb = SharedBuffer::alloc(new_allocation_size);\n    if (sb) {\n        void* array = sb->data();\n        _do_copy(array, mStorage, size());\n        release_storage();\n        mStorage = const_cast<void*>(array);\n    } else {\n        return NO_MEMORY;\n    }\n    return new_capacity;\n}\n\nssize_t VectorImpl::resize(size_t size) {\n    ssize_t result = NO_ERROR;\n    if (size > mCount) {\n        result = insertAt(mCount, size - mCount);\n    } else if (size < mCount) {\n        result = removeItemsAt(size, mCount - size);\n    }\n    return result < 0 ? result : size;\n}\n\nvoid VectorImpl::release_storage()\n{\n    if (mStorage) {\n        const SharedBuffer* sb = SharedBuffer::bufferFromData(mStorage);\n        if (sb->release(SharedBuffer::eKeepStorage) == 1) {\n            _do_destroy(mStorage, mCount);\n            SharedBuffer::dealloc(sb);\n        } \n    }\n}\n\nvoid* VectorImpl::_grow(size_t where, size_t amount)\n{\n//    ALOGV(\"_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d\",\n//        this, (int)where, (int)amount, (int)mCount, (int)capacity());\n\n    ALOG_ASSERT(where <= mCount,\n            \"[%p] _grow: where=%d, amount=%d, count=%d\",\n            this, (int)where, (int)amount, (int)mCount); // caller already checked\n\n    size_t new_size;\n    LOG_ALWAYS_FATAL_IF(!safe_add(&new_size, mCount, amount), \"new_size overflow\");\n\n    if (capacity() < new_size) {\n        // NOTE: This implementation used to resize vectors as per ((3*x + 1) / 2)\n        // (sigh..). Also note, the \" + 1\" was necessary to handle the special case\n        // where x == 1, where the resized_capacity will be equal to the old\n        // capacity without the +1. The old calculation wouldn't work properly\n        // if x was zero.\n        //\n        // This approximates the old calculation, using (x + (x/2) + 1) instead.\n        size_t new_capacity = 0;\n        LOG_ALWAYS_FATAL_IF(!safe_add(&new_capacity, new_size, (new_size / 2)),\n                            \"new_capacity overflow\");\n        LOG_ALWAYS_FATAL_IF(!safe_add(&new_capacity, new_capacity, static_cast<size_t>(1u)),\n                            \"new_capacity overflow\");\n        new_capacity = max(kMinVectorCapacity, new_capacity);\n\n        size_t new_alloc_size = 0;\n        LOG_ALWAYS_FATAL_IF(!safe_mul(&new_alloc_size, new_capacity, mItemSize),\n                            \"new_alloc_size overflow\");\n\n//        ALOGV(\"grow vector %p, new_capacity=%d\", this, (int)new_capacity);\n        if ((mStorage) &&\n            (mCount==where) &&\n            (mFlags & HAS_TRIVIAL_COPY) &&\n            (mFlags & HAS_TRIVIAL_DTOR))\n        {\n            const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage);\n            SharedBuffer* sb = cur_sb->editResize(new_alloc_size);\n            if (sb) {\n                mStorage = sb->data();\n            } else {\n                return NULL;\n            }\n        } else {\n            SharedBuffer* sb = SharedBuffer::alloc(new_alloc_size);\n            if (sb) {\n                void* array = sb->data();\n                if (where != 0) {\n                    _do_copy(array, mStorage, where);\n                }\n                if (where != mCount) {\n                    const void* from = reinterpret_cast<const uint8_t *>(mStorage) + where*mItemSize;\n                    void* dest = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;\n                    _do_copy(dest, from, mCount-where);\n                }\n                release_storage();\n                mStorage = const_cast<void*>(array);\n            } else {\n                return NULL;\n            }\n        }\n    } else {\n        void* array = editArrayImpl();\n        if (where != mCount) {\n            const void* from = reinterpret_cast<const uint8_t *>(array) + where*mItemSize;\n            void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;\n            _do_move_forward(to, from, mCount - where);\n        }\n    }\n    mCount = new_size;\n    void* free_space = const_cast<void*>(itemLocation(where));\n    return free_space;\n}\n\nvoid VectorImpl::_shrink(size_t where, size_t amount)\n{\n    if (!mStorage)\n        return;\n\n//    ALOGV(\"_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d\",\n//        this, (int)where, (int)amount, (int)mCount, (int)capacity());\n\n    ALOG_ASSERT(where + amount <= mCount,\n            \"[%p] _shrink: where=%d, amount=%d, count=%d\",\n            this, (int)where, (int)amount, (int)mCount); // caller already checked\n\n    size_t new_size;\n    LOG_ALWAYS_FATAL_IF(!safe_sub(&new_size, mCount, amount));\n\n    if (new_size < (capacity() / 2)) {\n        // NOTE: (new_size * 2) is safe because capacity didn't overflow and\n        // new_size < (capacity / 2)).\n        const size_t new_capacity = max(kMinVectorCapacity, new_size * 2);\n\n        // NOTE: (new_capacity * mItemSize), (where * mItemSize) and\n        // ((where + amount) * mItemSize) beyond this point are safe because\n        // we are always reducing the capacity of the underlying SharedBuffer.\n        // In other words, (old_capacity * mItemSize) did not overflow, and\n        // where < (where + amount) < new_capacity < old_capacity.\n        if ((where == new_size) &&\n            (mFlags & HAS_TRIVIAL_COPY) &&\n            (mFlags & HAS_TRIVIAL_DTOR))\n        {\n            const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage);\n            SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);\n            if (sb) {\n                mStorage = sb->data();\n            } else {\n                return;\n            }\n        } else {\n            SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);\n            if (sb) {\n                void* array = sb->data();\n                if (where != 0) {\n                    _do_copy(array, mStorage, where);\n                }\n                if (where != new_size) {\n                    const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize;\n                    void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize;\n                    _do_copy(dest, from, new_size - where);\n                }\n                release_storage();\n                mStorage = const_cast<void*>(array);\n            } else{\n                return;\n            }\n        }\n    } else {\n        void* array = editArrayImpl();\n        void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize;\n        _do_destroy(to, amount);\n        if (where != new_size) {\n            const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;\n            _do_move_backward(to, from, new_size - where);\n        }\n    }\n    mCount = new_size;\n}\n\nsize_t VectorImpl::itemSize() const {\n    return mItemSize;\n}\n\nvoid VectorImpl::_do_construct(void* storage, size_t num) const\n{\n    if (!(mFlags & HAS_TRIVIAL_CTOR)) {\n        do_construct(storage, num);\n    }\n}\n\nvoid VectorImpl::_do_destroy(void* storage, size_t num) const\n{\n    if (!(mFlags & HAS_TRIVIAL_DTOR)) {\n        do_destroy(storage, num);\n    }\n}\n\nvoid VectorImpl::_do_copy(void* dest, const void* from, size_t num) const\n{\n    if (!(mFlags & HAS_TRIVIAL_COPY)) {\n        do_copy(dest, from, num);\n    } else {\n        memcpy(dest, from, num*itemSize());\n    }\n}\n\nvoid VectorImpl::_do_splat(void* dest, const void* item, size_t num) const {\n    do_splat(dest, item, num);\n}\n\nvoid VectorImpl::_do_move_forward(void* dest, const void* from, size_t num) const {\n    do_move_forward(dest, from, num);\n}\n\nvoid VectorImpl::_do_move_backward(void* dest, const void* from, size_t num) const {\n    do_move_backward(dest, from, num);\n}\n\n/*****************************************************************************/\n\nSortedVectorImpl::SortedVectorImpl(size_t itemSize, uint32_t flags)\n    : VectorImpl(itemSize, flags)\n{\n}\n\nSortedVectorImpl::SortedVectorImpl(const VectorImpl& rhs)\n: VectorImpl(rhs)\n{\n}\n\nSortedVectorImpl::~SortedVectorImpl()\n{\n}\n\nSortedVectorImpl& SortedVectorImpl::operator = (const SortedVectorImpl& rhs)\n{\n    return static_cast<SortedVectorImpl&>( VectorImpl::operator = (static_cast<const VectorImpl&>(rhs)) );\n}\n\nssize_t SortedVectorImpl::indexOf(const void* item) const\n{\n    return _indexOrderOf(item);\n}\n\nsize_t SortedVectorImpl::orderOf(const void* item) const\n{\n    size_t o;\n    _indexOrderOf(item, &o);\n    return o;\n}\n\nssize_t SortedVectorImpl::_indexOrderOf(const void* item, size_t* order) const\n{\n    if (order) *order = 0;\n    if (isEmpty()) {\n        return NAME_NOT_FOUND;\n    }\n    // binary search\n    ssize_t err = NAME_NOT_FOUND;\n    ssize_t l = 0;\n    ssize_t h = size()-1;\n    ssize_t mid;\n    const void* a = arrayImpl();\n    const size_t s = itemSize();\n    while (l <= h) {\n        mid = l + (h - l)/2;\n        const void* const curr = reinterpret_cast<const char *>(a) + (mid*s);\n        const int c = do_compare(curr, item);\n        if (c == 0) {\n            err = l = mid;\n            break;\n        } else if (c < 0) {\n            l = mid + 1;\n        } else {\n            h = mid - 1;\n        }\n    }\n    if (order) *order = l;\n    return err;\n}\n\nssize_t SortedVectorImpl::add(const void* item)\n{\n    size_t order;\n    ssize_t index = _indexOrderOf(item, &order);\n    if (index < 0) {\n        index = VectorImpl::insertAt(item, order, 1);\n    } else {\n        index = VectorImpl::replaceAt(item, index);\n    }\n    return index;\n}\n\nssize_t SortedVectorImpl::merge(const VectorImpl& vector)\n{\n    // naive merge...\n    if (!vector.isEmpty()) {\n        const void* buffer = vector.arrayImpl();\n        const size_t is = itemSize();\n        size_t s = vector.size();\n        for (size_t i=0 ; i<s ; i++) {\n            ssize_t err = add( reinterpret_cast<const char*>(buffer) + i*is );\n            if (err<0) {\n                return err;\n            }\n        }\n    }\n    return NO_ERROR;\n}\n\nssize_t SortedVectorImpl::merge(const SortedVectorImpl& vector)\n{\n    // we've merging a sorted vector... nice!\n    ssize_t err = NO_ERROR;\n    if (!vector.isEmpty()) {\n        // first take care of the case where the vectors are sorted together\n        if (do_compare(vector.itemLocation(vector.size()-1), arrayImpl()) <= 0) {\n            err = VectorImpl::insertVectorAt(static_cast<const VectorImpl&>(vector), 0);\n        } else if (do_compare(vector.arrayImpl(), itemLocation(size()-1)) >= 0) {\n            err = VectorImpl::appendVector(static_cast<const VectorImpl&>(vector));\n        } else {\n            // this could be made a little better\n            err = merge(static_cast<const VectorImpl&>(vector));\n        }\n    }\n    return err;\n}\n\nssize_t SortedVectorImpl::remove(const void* item)\n{\n    ssize_t i = indexOf(item);\n    if (i>=0) {\n        VectorImpl::removeItemsAt(i, 1);\n    }\n    return i;\n}\n\n/*****************************************************************************/\n\n}; // namespace android\n\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/misc.cpp",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"misc\"\n\n//\n// Miscellaneous utility functions.\n//\n#include <utils/misc.h>\n#include <utils/Log.h>\n\n#include <sys/stat.h>\n#include <string.h>\n#include <stdio.h>\n\n#if !defined(_WIN32)\n# include <pthread.h>\n#endif\n\n#include <utils/Vector.h>\n\nusing namespace android;\n\nnamespace android {\n\nstruct sysprop_change_callback_info {\n    sysprop_change_callback callback;\n    int priority;\n};\n\n#if !defined(_WIN32)\nstatic pthread_mutex_t gSyspropMutex = PTHREAD_MUTEX_INITIALIZER;\nstatic Vector<sysprop_change_callback_info>* gSyspropList = NULL;\n#endif\n\nvoid add_sysprop_change_callback(sysprop_change_callback cb, int priority) {\n#if !defined(_WIN32)\n    pthread_mutex_lock(&gSyspropMutex);\n    if (gSyspropList == NULL) {\n        gSyspropList = new Vector<sysprop_change_callback_info>();\n    }\n    sysprop_change_callback_info info;\n    info.callback = cb;\n    info.priority = priority;\n    bool added = false;\n    for (size_t i=0; i<gSyspropList->size(); i++) {\n        if (priority >= gSyspropList->itemAt(i).priority) {\n            gSyspropList->insertAt(info, i);\n            added = true;\n            break;\n        }\n    }\n    if (!added) {\n        gSyspropList->add(info);\n    }\n    pthread_mutex_unlock(&gSyspropMutex);\n#endif\n}\n\nvoid report_sysprop_change() {\n#if !defined(_WIN32)\n    pthread_mutex_lock(&gSyspropMutex);\n    Vector<sysprop_change_callback_info> listeners;\n    if (gSyspropList != NULL) {\n        listeners = *gSyspropList;\n    }\n    pthread_mutex_unlock(&gSyspropMutex);\n\n    //ALOGI(\"Reporting sysprop change to %d listeners\", listeners.size());\n    for (size_t i=0; i<listeners.size(); i++) {\n        listeners[i].callback();\n    }\n#endif\n}\n\n}; // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/primes.py",
    "content": "#!/usr/bin/env python2.6\n#\n# Copyright (C) 2011 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n#\n# Generates a table of prime numbers for use in BasicHashtable.cpp.\n#\n# Each prime is chosen such that it is a little more than twice as large as\n# the previous prime in the table.  This makes it easier to choose a new\n# hashtable size when the underlying array is grown by as nominal factor\n# of two each time.\n#\n\ndef is_odd_prime(n):\n  limit = (n - 1) / 2\n  d = 3\n  while d <= limit:\n    if n % d == 0:\n      return False\n    d += 2\n  return True\n\nprint \"static size_t PRIMES[] = {\"\n\nn = 5\nmax = 2**31 - 1\nwhile n < max:\n  print \"    %d,\" % (n)\n  n = n * 2 + 1\n  while not is_odd_prime(n):\n    n += 2\n\nprint \"    0,\"\nprint \"};\"\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/tests/Android.mk",
    "content": "#\n# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n# Build the unit tests.\nLOCAL_PATH := $(call my-dir)\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libutils_tests\n\nLOCAL_SRC_FILES := \\\n    BlobCache_test.cpp \\\n    BitSet_test.cpp \\\n    Looper_test.cpp \\\n    LruCache_test.cpp \\\n    String8_test.cpp \\\n    StrongPointer_test.cpp \\\n    Unicode_test.cpp \\\n    Vector_test.cpp \\\n\nLOCAL_SHARED_LIBRARIES := \\\n    libz \\\n    liblog \\\n    libcutils \\\n    libutils \\\n\ninclude $(BUILD_NATIVE_TEST)\n\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libutils_tests_host\nLOCAL_SRC_FILES := Vector_test.cpp\nLOCAL_STATIC_LIBRARIES := libutils liblog\n\ninclude $(BUILD_HOST_NATIVE_TEST)\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/tests/BitSet_test.cpp",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"BitSet_test\"\n\n#include <utils/BitSet.h>\n#include <cutils/log.h>\n#include <gtest/gtest.h>\n#include <unistd.h>\n\nnamespace android {\n\nclass BitSet32Test : public testing::Test {\nprotected:\n    BitSet32 b1;\n    BitSet32 b2;\n    virtual void TearDown() {\n        b1.clear();\n        b2.clear();\n    }\n};\n\n\nTEST_F(BitSet32Test, BitWiseOr) {\n    b1.markBit(2);\n    b2.markBit(4);\n\n    BitSet32 tmp = b1 | b2;\n    EXPECT_EQ(tmp.count(), 2u);\n    EXPECT_TRUE(tmp.hasBit(2) && tmp.hasBit(4));\n    // Check that the operator is symmetric\n    EXPECT_TRUE((b2 | b1) == (b1 | b2));\n\n    b1 |= b2;\n    EXPECT_EQ(b1.count(), 2u);\n    EXPECT_TRUE(b1.hasBit(2) && b1.hasBit(4));\n    EXPECT_TRUE(b2.hasBit(4) && b2.count() == 1u);\n}\nTEST_F(BitSet32Test, BitWiseAnd_Disjoint) {\n    b1.markBit(2);\n    b1.markBit(4);\n    b1.markBit(6);\n\n    BitSet32 tmp = b1 & b2;\n    EXPECT_TRUE(tmp.isEmpty());\n    // Check that the operator is symmetric\n    EXPECT_TRUE((b2 & b1) == (b1 & b2));\n\n    b2 &= b1;\n    EXPECT_TRUE(b2.isEmpty());\n    EXPECT_EQ(b1.count(), 3u);\n    EXPECT_TRUE(b1.hasBit(2) && b1.hasBit(4) && b1.hasBit(6));\n}\n\nTEST_F(BitSet32Test, BitWiseAnd_NonDisjoint) {\n    b1.markBit(2);\n    b1.markBit(4);\n    b1.markBit(6);\n    b2.markBit(3);\n    b2.markBit(6);\n    b2.markBit(9);\n\n    BitSet32 tmp = b1 & b2;\n    EXPECT_EQ(tmp.count(), 1u);\n    EXPECT_TRUE(tmp.hasBit(6));\n    // Check that the operator is symmetric\n    EXPECT_TRUE((b2 & b1) == (b1 & b2));\n\n    b1 &= b2;\n    EXPECT_EQ(b1.count(), 1u);\n    EXPECT_EQ(b2.count(), 3u);\n    EXPECT_TRUE(b2.hasBit(3) && b2.hasBit(6) && b2.hasBit(9));\n}\n\nTEST_F(BitSet32Test, MarkFirstUnmarkedBit) {\n    b1.markBit(1);\n\n    b1.markFirstUnmarkedBit();\n    EXPECT_EQ(b1.count(), 2u);\n    EXPECT_TRUE(b1.hasBit(0) && b1.hasBit(1));\n\n    b1.markFirstUnmarkedBit();\n    EXPECT_EQ(b1.count(), 3u);\n    EXPECT_TRUE(b1.hasBit(0) && b1.hasBit(1) && b1.hasBit(2));\n}\n\nTEST_F(BitSet32Test, ClearFirstMarkedBit) {\n    b1.markBit(0);\n    b1.markBit(10);\n\n    b1.clearFirstMarkedBit();\n    EXPECT_EQ(b1.count(), 1u);\n    EXPECT_TRUE(b1.hasBit(10));\n\n    b1.markBit(30);\n    b1.clearFirstMarkedBit();\n    EXPECT_EQ(b1.count(), 1u);\n    EXPECT_TRUE(b1.hasBit(30));\n}\n\nTEST_F(BitSet32Test, ClearLastMarkedBit) {\n    b1.markBit(10);\n    b1.markBit(31);\n\n    b1.clearLastMarkedBit();\n    EXPECT_EQ(b1.count(), 1u);\n    EXPECT_TRUE(b1.hasBit(10));\n\n    b1.markBit(5);\n    b1.clearLastMarkedBit();\n    EXPECT_EQ(b1.count(), 1u);\n    EXPECT_TRUE(b1.hasBit(5));\n}\n\nTEST_F(BitSet32Test, FillAndClear) {\n    EXPECT_TRUE(b1.isEmpty());\n    for (size_t i = 0; i < 32; i++) {\n        b1.markFirstUnmarkedBit();\n    }\n    EXPECT_TRUE(b1.isFull());\n    b1.clear();\n    EXPECT_TRUE(b1.isEmpty());\n}\n\nTEST_F(BitSet32Test, GetIndexOfBit) {\n    b1.markBit(1);\n    b1.markBit(4);\n    EXPECT_EQ(0U, b1.getIndexOfBit(1));\n    EXPECT_EQ(1U, b1.getIndexOfBit(4));\n    b1.markFirstUnmarkedBit();\n    EXPECT_EQ(1U, b1.getIndexOfBit(1));\n    EXPECT_EQ(2U, b1.getIndexOfBit(4));\n}\n\nclass BitSet64Test : public testing::Test {\nprotected:\n    BitSet64 b1;\n    BitSet64 b2;\n    virtual void TearDown() {\n        b1.clear();\n        b2.clear();\n    }\n};\n\n\nTEST_F(BitSet64Test, BitWiseOr) {\n    b1.markBit(20);\n    b2.markBit(40);\n\n    BitSet64 tmp = b1 | b2;\n    EXPECT_EQ(tmp.count(), 2u);\n    EXPECT_TRUE(tmp.hasBit(20) && tmp.hasBit(40));\n    // Check that the operator is symmetric\n    EXPECT_TRUE((b2 | b1) == (b1 | b2));\n\n    b1 |= b2;\n    EXPECT_EQ(b1.count(), 2u);\n    EXPECT_TRUE(b1.hasBit(20) && b1.hasBit(40));\n    EXPECT_TRUE(b2.hasBit(40) && b2.count() == 1u);\n}\nTEST_F(BitSet64Test, BitWiseAnd_Disjoint) {\n    b1.markBit(20);\n    b1.markBit(40);\n    b1.markBit(60);\n\n    BitSet64 tmp = b1 & b2;\n    EXPECT_TRUE(tmp.isEmpty());\n    // Check that the operator is symmetric\n    EXPECT_TRUE((b2 & b1) == (b1 & b2));\n\n    b2 &= b1;\n    EXPECT_TRUE(b2.isEmpty());\n    EXPECT_EQ(b1.count(), 3u);\n    EXPECT_TRUE(b1.hasBit(20) && b1.hasBit(40) && b1.hasBit(60));\n}\n\nTEST_F(BitSet64Test, BitWiseAnd_NonDisjoint) {\n    b1.markBit(20);\n    b1.markBit(40);\n    b1.markBit(60);\n    b2.markBit(30);\n    b2.markBit(60);\n    b2.markBit(63);\n\n    BitSet64 tmp = b1 & b2;\n    EXPECT_EQ(tmp.count(), 1u);\n    EXPECT_TRUE(tmp.hasBit(60));\n    // Check that the operator is symmetric\n    EXPECT_TRUE((b2 & b1) == (b1 & b2));\n\n    b1 &= b2;\n    EXPECT_EQ(b1.count(), 1u);\n    EXPECT_EQ(b2.count(), 3u);\n    EXPECT_TRUE(b2.hasBit(30) && b2.hasBit(60) && b2.hasBit(63));\n}\n\nTEST_F(BitSet64Test, MarkFirstUnmarkedBit) {\n    b1.markBit(1);\n\n    b1.markFirstUnmarkedBit();\n    EXPECT_EQ(b1.count(), 2u);\n    EXPECT_TRUE(b1.hasBit(0) && b1.hasBit(1));\n\n    b1.markFirstUnmarkedBit();\n    EXPECT_EQ(b1.count(), 3u);\n    EXPECT_TRUE(b1.hasBit(0) && b1.hasBit(1) && b1.hasBit(2));\n}\n\nTEST_F(BitSet64Test, ClearFirstMarkedBit) {\n    b1.markBit(0);\n    b1.markBit(10);\n\n    b1.clearFirstMarkedBit();\n    EXPECT_EQ(b1.count(), 1u);\n    EXPECT_TRUE(b1.hasBit(10));\n\n    b1.markBit(50);\n    b1.clearFirstMarkedBit();\n    EXPECT_EQ(b1.count(), 1u);\n    EXPECT_TRUE(b1.hasBit(50));\n}\n\nTEST_F(BitSet64Test, ClearLastMarkedBit) {\n    b1.markBit(10);\n    b1.markBit(63);\n\n    b1.clearLastMarkedBit();\n    EXPECT_EQ(b1.count(), 1u);\n    EXPECT_TRUE(b1.hasBit(10));\n\n    b1.markBit(5);\n    b1.clearLastMarkedBit();\n    EXPECT_EQ(b1.count(), 1u);\n    EXPECT_TRUE(b1.hasBit(5));\n}\n\nTEST_F(BitSet64Test, FillAndClear) {\n    EXPECT_TRUE(b1.isEmpty());\n    for (size_t i = 0; i < 64; i++) {\n        b1.markFirstUnmarkedBit();\n    }\n    EXPECT_TRUE(b1.isFull());\n    b1.clear();\n    EXPECT_TRUE(b1.isEmpty());\n}\n\nTEST_F(BitSet64Test, GetIndexOfBit) {\n    b1.markBit(10);\n    b1.markBit(40);\n    EXPECT_EQ(0U, b1.getIndexOfBit(10));\n    EXPECT_EQ(1U, b1.getIndexOfBit(40));\n    b1.markFirstUnmarkedBit();\n    EXPECT_EQ(1U, b1.getIndexOfBit(10));\n    EXPECT_EQ(2U, b1.getIndexOfBit(40));\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/tests/BlobCache_test.cpp",
    "content": "/*\n ** Copyright 2011, The Android Open Source Project\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n\n#include <fcntl.h>\n#include <stdio.h>\n\n#include <gtest/gtest.h>\n\n#include <utils/BlobCache.h>\n#include <utils/Errors.h>\n\nnamespace android {\n\nclass BlobCacheTest : public ::testing::Test {\nprotected:\n    enum {\n        MAX_KEY_SIZE = 6,\n        MAX_VALUE_SIZE = 8,\n        MAX_TOTAL_SIZE = 13,\n    };\n\n    virtual void SetUp() {\n        mBC = new BlobCache(MAX_KEY_SIZE, MAX_VALUE_SIZE, MAX_TOTAL_SIZE);\n    }\n\n    virtual void TearDown() {\n        mBC.clear();\n    }\n\n    sp<BlobCache> mBC;\n};\n\nTEST_F(BlobCacheTest, CacheSingleValueSucceeds) {\n    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };\n    mBC->set(\"abcd\", 4, \"efgh\", 4);\n    ASSERT_EQ(size_t(4), mBC->get(\"abcd\", 4, buf, 4));\n    ASSERT_EQ('e', buf[0]);\n    ASSERT_EQ('f', buf[1]);\n    ASSERT_EQ('g', buf[2]);\n    ASSERT_EQ('h', buf[3]);\n}\n\nTEST_F(BlobCacheTest, CacheTwoValuesSucceeds) {\n    unsigned char buf[2] = { 0xee, 0xee };\n    mBC->set(\"ab\", 2, \"cd\", 2);\n    mBC->set(\"ef\", 2, \"gh\", 2);\n    ASSERT_EQ(size_t(2), mBC->get(\"ab\", 2, buf, 2));\n    ASSERT_EQ('c', buf[0]);\n    ASSERT_EQ('d', buf[1]);\n    ASSERT_EQ(size_t(2), mBC->get(\"ef\", 2, buf, 2));\n    ASSERT_EQ('g', buf[0]);\n    ASSERT_EQ('h', buf[1]);\n}\n\nTEST_F(BlobCacheTest, GetOnlyWritesInsideBounds) {\n    unsigned char buf[6] = { 0xee, 0xee, 0xee, 0xee, 0xee, 0xee };\n    mBC->set(\"abcd\", 4, \"efgh\", 4);\n    ASSERT_EQ(size_t(4), mBC->get(\"abcd\", 4, buf+1, 4));\n    ASSERT_EQ(0xee, buf[0]);\n    ASSERT_EQ('e', buf[1]);\n    ASSERT_EQ('f', buf[2]);\n    ASSERT_EQ('g', buf[3]);\n    ASSERT_EQ('h', buf[4]);\n    ASSERT_EQ(0xee, buf[5]);\n}\n\nTEST_F(BlobCacheTest, GetOnlyWritesIfBufferIsLargeEnough) {\n    unsigned char buf[3] = { 0xee, 0xee, 0xee };\n    mBC->set(\"abcd\", 4, \"efgh\", 4);\n    ASSERT_EQ(size_t(4), mBC->get(\"abcd\", 4, buf, 3));\n    ASSERT_EQ(0xee, buf[0]);\n    ASSERT_EQ(0xee, buf[1]);\n    ASSERT_EQ(0xee, buf[2]);\n}\n\nTEST_F(BlobCacheTest, GetDoesntAccessNullBuffer) {\n    mBC->set(\"abcd\", 4, \"efgh\", 4);\n    ASSERT_EQ(size_t(4), mBC->get(\"abcd\", 4, NULL, 0));\n}\n\nTEST_F(BlobCacheTest, MultipleSetsCacheLatestValue) {\n    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };\n    mBC->set(\"abcd\", 4, \"efgh\", 4);\n    mBC->set(\"abcd\", 4, \"ijkl\", 4);\n    ASSERT_EQ(size_t(4), mBC->get(\"abcd\", 4, buf, 4));\n    ASSERT_EQ('i', buf[0]);\n    ASSERT_EQ('j', buf[1]);\n    ASSERT_EQ('k', buf[2]);\n    ASSERT_EQ('l', buf[3]);\n}\n\nTEST_F(BlobCacheTest, SecondSetKeepsFirstValueIfTooLarge) {\n    unsigned char buf[MAX_VALUE_SIZE+1] = { 0xee, 0xee, 0xee, 0xee };\n    mBC->set(\"abcd\", 4, \"efgh\", 4);\n    mBC->set(\"abcd\", 4, buf, MAX_VALUE_SIZE+1);\n    ASSERT_EQ(size_t(4), mBC->get(\"abcd\", 4, buf, 4));\n    ASSERT_EQ('e', buf[0]);\n    ASSERT_EQ('f', buf[1]);\n    ASSERT_EQ('g', buf[2]);\n    ASSERT_EQ('h', buf[3]);\n}\n\nTEST_F(BlobCacheTest, DoesntCacheIfKeyIsTooBig) {\n    char key[MAX_KEY_SIZE+1];\n    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };\n    for (int i = 0; i < MAX_KEY_SIZE+1; i++) {\n        key[i] = 'a';\n    }\n    mBC->set(key, MAX_KEY_SIZE+1, \"bbbb\", 4);\n    ASSERT_EQ(size_t(0), mBC->get(key, MAX_KEY_SIZE+1, buf, 4));\n    ASSERT_EQ(0xee, buf[0]);\n    ASSERT_EQ(0xee, buf[1]);\n    ASSERT_EQ(0xee, buf[2]);\n    ASSERT_EQ(0xee, buf[3]);\n}\n\nTEST_F(BlobCacheTest, DoesntCacheIfValueIsTooBig) {\n    char buf[MAX_VALUE_SIZE+1];\n    for (int i = 0; i < MAX_VALUE_SIZE+1; i++) {\n        buf[i] = 'b';\n    }\n    mBC->set(\"abcd\", 4, buf, MAX_VALUE_SIZE+1);\n    for (int i = 0; i < MAX_VALUE_SIZE+1; i++) {\n        buf[i] = 0xee;\n    }\n    ASSERT_EQ(size_t(0), mBC->get(\"abcd\", 4, buf, MAX_VALUE_SIZE+1));\n    for (int i = 0; i < MAX_VALUE_SIZE+1; i++) {\n        SCOPED_TRACE(i);\n        ASSERT_EQ(0xee, buf[i]);\n    }\n}\n\nTEST_F(BlobCacheTest, DoesntCacheIfKeyValuePairIsTooBig) {\n    // Check a testing assumptions\n    ASSERT_TRUE(MAX_TOTAL_SIZE < MAX_KEY_SIZE + MAX_VALUE_SIZE);\n    ASSERT_TRUE(MAX_KEY_SIZE < MAX_TOTAL_SIZE);\n\n    enum { bufSize = MAX_TOTAL_SIZE - MAX_KEY_SIZE + 1 };\n\n    char key[MAX_KEY_SIZE];\n    char buf[bufSize];\n    for (int i = 0; i < MAX_KEY_SIZE; i++) {\n        key[i] = 'a';\n    }\n    for (int i = 0; i < bufSize; i++) {\n        buf[i] = 'b';\n    }\n\n    mBC->set(key, MAX_KEY_SIZE, buf, MAX_VALUE_SIZE);\n    ASSERT_EQ(size_t(0), mBC->get(key, MAX_KEY_SIZE, NULL, 0));\n}\n\nTEST_F(BlobCacheTest, CacheMaxKeySizeSucceeds) {\n    char key[MAX_KEY_SIZE];\n    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };\n    for (int i = 0; i < MAX_KEY_SIZE; i++) {\n        key[i] = 'a';\n    }\n    mBC->set(key, MAX_KEY_SIZE, \"wxyz\", 4);\n    ASSERT_EQ(size_t(4), mBC->get(key, MAX_KEY_SIZE, buf, 4));\n    ASSERT_EQ('w', buf[0]);\n    ASSERT_EQ('x', buf[1]);\n    ASSERT_EQ('y', buf[2]);\n    ASSERT_EQ('z', buf[3]);\n}\n\nTEST_F(BlobCacheTest, CacheMaxValueSizeSucceeds) {\n    char buf[MAX_VALUE_SIZE];\n    for (int i = 0; i < MAX_VALUE_SIZE; i++) {\n        buf[i] = 'b';\n    }\n    mBC->set(\"abcd\", 4, buf, MAX_VALUE_SIZE);\n    for (int i = 0; i < MAX_VALUE_SIZE; i++) {\n        buf[i] = 0xee;\n    }\n    ASSERT_EQ(size_t(MAX_VALUE_SIZE), mBC->get(\"abcd\", 4, buf,\n            MAX_VALUE_SIZE));\n    for (int i = 0; i < MAX_VALUE_SIZE; i++) {\n        SCOPED_TRACE(i);\n        ASSERT_EQ('b', buf[i]);\n    }\n}\n\nTEST_F(BlobCacheTest, CacheMaxKeyValuePairSizeSucceeds) {\n    // Check a testing assumption\n    ASSERT_TRUE(MAX_KEY_SIZE < MAX_TOTAL_SIZE);\n\n    enum { bufSize = MAX_TOTAL_SIZE - MAX_KEY_SIZE };\n\n    char key[MAX_KEY_SIZE];\n    char buf[bufSize];\n    for (int i = 0; i < MAX_KEY_SIZE; i++) {\n        key[i] = 'a';\n    }\n    for (int i = 0; i < bufSize; i++) {\n        buf[i] = 'b';\n    }\n\n    mBC->set(key, MAX_KEY_SIZE, buf, bufSize);\n    ASSERT_EQ(size_t(bufSize), mBC->get(key, MAX_KEY_SIZE, NULL, 0));\n}\n\nTEST_F(BlobCacheTest, CacheMinKeyAndValueSizeSucceeds) {\n    unsigned char buf[1] = { 0xee };\n    mBC->set(\"x\", 1, \"y\", 1);\n    ASSERT_EQ(size_t(1), mBC->get(\"x\", 1, buf, 1));\n    ASSERT_EQ('y', buf[0]);\n}\n\nTEST_F(BlobCacheTest, CacheSizeDoesntExceedTotalLimit) {\n    for (int i = 0; i < 256; i++) {\n        uint8_t k = i;\n        mBC->set(&k, 1, \"x\", 1);\n    }\n    int numCached = 0;\n    for (int i = 0; i < 256; i++) {\n        uint8_t k = i;\n        if (mBC->get(&k, 1, NULL, 0) == 1) {\n            numCached++;\n        }\n    }\n    ASSERT_GE(MAX_TOTAL_SIZE / 2, numCached);\n}\n\nTEST_F(BlobCacheTest, ExceedingTotalLimitHalvesCacheSize) {\n    // Fill up the entire cache with 1 char key/value pairs.\n    const int maxEntries = MAX_TOTAL_SIZE / 2;\n    for (int i = 0; i < maxEntries; i++) {\n        uint8_t k = i;\n        mBC->set(&k, 1, \"x\", 1);\n    }\n    // Insert one more entry, causing a cache overflow.\n    {\n        uint8_t k = maxEntries;\n        mBC->set(&k, 1, \"x\", 1);\n    }\n    // Count the number of entries in the cache.\n    int numCached = 0;\n    for (int i = 0; i < maxEntries+1; i++) {\n        uint8_t k = i;\n        if (mBC->get(&k, 1, NULL, 0) == 1) {\n            numCached++;\n        }\n    }\n    ASSERT_EQ(maxEntries/2 + 1, numCached);\n}\n\nclass BlobCacheFlattenTest : public BlobCacheTest {\nprotected:\n    virtual void SetUp() {\n        BlobCacheTest::SetUp();\n        mBC2 = new BlobCache(MAX_KEY_SIZE, MAX_VALUE_SIZE, MAX_TOTAL_SIZE);\n    }\n\n    virtual void TearDown() {\n        mBC2.clear();\n        BlobCacheTest::TearDown();\n    }\n\n    void roundTrip() {\n        size_t size = mBC->getFlattenedSize();\n        uint8_t* flat = new uint8_t[size];\n        ASSERT_EQ(OK, mBC->flatten(flat, size));\n        ASSERT_EQ(OK, mBC2->unflatten(flat, size));\n        delete[] flat;\n    }\n\n    sp<BlobCache> mBC2;\n};\n\nTEST_F(BlobCacheFlattenTest, FlattenOneValue) {\n    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };\n    mBC->set(\"abcd\", 4, \"efgh\", 4);\n    roundTrip();\n    ASSERT_EQ(size_t(4), mBC2->get(\"abcd\", 4, buf, 4));\n    ASSERT_EQ('e', buf[0]);\n    ASSERT_EQ('f', buf[1]);\n    ASSERT_EQ('g', buf[2]);\n    ASSERT_EQ('h', buf[3]);\n}\n\nTEST_F(BlobCacheFlattenTest, FlattenFullCache) {\n    // Fill up the entire cache with 1 char key/value pairs.\n    const int maxEntries = MAX_TOTAL_SIZE / 2;\n    for (int i = 0; i < maxEntries; i++) {\n        uint8_t k = i;\n        mBC->set(&k, 1, &k, 1);\n    }\n\n    roundTrip();\n\n    // Verify the deserialized cache\n    for (int i = 0; i < maxEntries; i++) {\n        uint8_t k = i;\n        uint8_t v = 0xee;\n        ASSERT_EQ(size_t(1), mBC2->get(&k, 1, &v, 1));\n        ASSERT_EQ(k, v);\n    }\n}\n\nTEST_F(BlobCacheFlattenTest, FlattenDoesntChangeCache) {\n    // Fill up the entire cache with 1 char key/value pairs.\n    const int maxEntries = MAX_TOTAL_SIZE / 2;\n    for (int i = 0; i < maxEntries; i++) {\n        uint8_t k = i;\n        mBC->set(&k, 1, &k, 1);\n    }\n\n    size_t size = mBC->getFlattenedSize();\n    uint8_t* flat = new uint8_t[size];\n    ASSERT_EQ(OK, mBC->flatten(flat, size));\n    delete[] flat;\n\n    // Verify the cache that we just serialized\n    for (int i = 0; i < maxEntries; i++) {\n        uint8_t k = i;\n        uint8_t v = 0xee;\n        ASSERT_EQ(size_t(1), mBC->get(&k, 1, &v, 1));\n        ASSERT_EQ(k, v);\n    }\n}\n\nTEST_F(BlobCacheFlattenTest, FlattenCatchesBufferTooSmall) {\n    // Fill up the entire cache with 1 char key/value pairs.\n    const int maxEntries = MAX_TOTAL_SIZE / 2;\n    for (int i = 0; i < maxEntries; i++) {\n        uint8_t k = i;\n        mBC->set(&k, 1, &k, 1);\n    }\n\n    size_t size = mBC->getFlattenedSize() - 1;\n    uint8_t* flat = new uint8_t[size];\n    ASSERT_EQ(BAD_VALUE, mBC->flatten(flat, size));\n    delete[] flat;\n}\n\nTEST_F(BlobCacheFlattenTest, UnflattenCatchesBadMagic) {\n    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };\n    mBC->set(\"abcd\", 4, \"efgh\", 4);\n\n    size_t size = mBC->getFlattenedSize();\n    uint8_t* flat = new uint8_t[size];\n    ASSERT_EQ(OK, mBC->flatten(flat, size));\n    flat[1] = ~flat[1];\n\n    // Bad magic should cause an error.\n    ASSERT_EQ(BAD_VALUE, mBC2->unflatten(flat, size));\n    delete[] flat;\n\n    // The error should cause the unflatten to result in an empty cache\n    ASSERT_EQ(size_t(0), mBC2->get(\"abcd\", 4, buf, 4));\n}\n\nTEST_F(BlobCacheFlattenTest, UnflattenCatchesBadBlobCacheVersion) {\n    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };\n    mBC->set(\"abcd\", 4, \"efgh\", 4);\n\n    size_t size = mBC->getFlattenedSize();\n    uint8_t* flat = new uint8_t[size];\n    ASSERT_EQ(OK, mBC->flatten(flat, size));\n    flat[5] = ~flat[5];\n\n    // Version mismatches shouldn't cause errors, but should not use the\n    // serialized entries\n    ASSERT_EQ(OK, mBC2->unflatten(flat, size));\n    delete[] flat;\n\n    // The version mismatch should cause the unflatten to result in an empty\n    // cache\n    ASSERT_EQ(size_t(0), mBC2->get(\"abcd\", 4, buf, 4));\n}\n\nTEST_F(BlobCacheFlattenTest, UnflattenCatchesBadBlobCacheDeviceVersion) {\n    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };\n    mBC->set(\"abcd\", 4, \"efgh\", 4);\n\n    size_t size = mBC->getFlattenedSize();\n    uint8_t* flat = new uint8_t[size];\n    ASSERT_EQ(OK, mBC->flatten(flat, size));\n    flat[10] = ~flat[10];\n\n    // Version mismatches shouldn't cause errors, but should not use the\n    // serialized entries\n    ASSERT_EQ(OK, mBC2->unflatten(flat, size));\n    delete[] flat;\n\n    // The version mismatch should cause the unflatten to result in an empty\n    // cache\n    ASSERT_EQ(size_t(0), mBC2->get(\"abcd\", 4, buf, 4));\n}\n\nTEST_F(BlobCacheFlattenTest, UnflattenCatchesBufferTooSmall) {\n    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };\n    mBC->set(\"abcd\", 4, \"efgh\", 4);\n\n    size_t size = mBC->getFlattenedSize();\n    uint8_t* flat = new uint8_t[size];\n    ASSERT_EQ(OK, mBC->flatten(flat, size));\n\n    // A buffer truncation shouldt cause an error\n    ASSERT_EQ(BAD_VALUE, mBC2->unflatten(flat, size-1));\n    delete[] flat;\n\n    // The error should cause the unflatten to result in an empty cache\n    ASSERT_EQ(size_t(0), mBC2->get(\"abcd\", 4, buf, 4));\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/tests/Looper_test.cpp",
    "content": "//\n// Copyright 2010 The Android Open Source Project\n//\n\n#include <utils/Looper.h>\n#include <utils/Timers.h>\n#include <utils/StopWatch.h>\n#include <gtest/gtest.h>\n#include <unistd.h>\n#include <time.h>\n\n#include \"TestHelpers.h\"\n\n// # of milliseconds to fudge stopwatch measurements\n#define TIMING_TOLERANCE_MS 25\n\nnamespace android {\n\nenum {\n    MSG_TEST1 = 1,\n    MSG_TEST2 = 2,\n    MSG_TEST3 = 3,\n    MSG_TEST4 = 4,\n};\n\nclass DelayedWake : public DelayedTask {\n    sp<Looper> mLooper;\n\npublic:\n    DelayedWake(int delayMillis, const sp<Looper> looper) :\n        DelayedTask(delayMillis), mLooper(looper) {\n    }\n\nprotected:\n    virtual void doTask() {\n        mLooper->wake();\n    }\n};\n\nclass DelayedWriteSignal : public DelayedTask {\n    Pipe* mPipe;\n\npublic:\n    DelayedWriteSignal(int delayMillis, Pipe* pipe) :\n        DelayedTask(delayMillis), mPipe(pipe) {\n    }\n\nprotected:\n    virtual void doTask() {\n        mPipe->writeSignal();\n    }\n};\n\nclass CallbackHandler {\npublic:\n    void setCallback(const sp<Looper>& looper, int fd, int events) {\n        looper->addFd(fd, 0, events, staticHandler, this);\n    }\n\nprotected:\n    virtual ~CallbackHandler() { }\n\n    virtual int handler(int fd, int events) = 0;\n\nprivate:\n    static int staticHandler(int fd, int events, void* data) {\n        return static_cast<CallbackHandler*>(data)->handler(fd, events);\n    }\n};\n\nclass StubCallbackHandler : public CallbackHandler {\npublic:\n    int nextResult;\n    int callbackCount;\n\n    int fd;\n    int events;\n\n    StubCallbackHandler(int nextResult) : nextResult(nextResult),\n            callbackCount(0), fd(-1), events(-1) {\n    }\n\nprotected:\n    virtual int handler(int fd, int events) {\n        callbackCount += 1;\n        this->fd = fd;\n        this->events = events;\n        return nextResult;\n    }\n};\n\nclass StubMessageHandler : public MessageHandler {\npublic:\n    Vector<Message> messages;\n\n    virtual void handleMessage(const Message& message) {\n        messages.push(message);\n    }\n};\n\nclass LooperTest : public testing::Test {\nprotected:\n    sp<Looper> mLooper;\n\n    virtual void SetUp() {\n        mLooper = new Looper(true);\n    }\n\n    virtual void TearDown() {\n        mLooper.clear();\n    }\n};\n\n\nTEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndNotAwoken_WaitsForTimeout) {\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(100);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. equal timeout\";\n    EXPECT_EQ(Looper::POLL_TIMEOUT, result)\n            << \"pollOnce result should be LOOPER_POLL_TIMEOUT\";\n}\n\nTEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndAwokenBeforeWaiting_ImmediatelyReturns) {\n    mLooper->wake();\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(1000);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. zero because wake() was called before waiting\";\n    EXPECT_EQ(Looper::POLL_WAKE, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because loop was awoken\";\n}\n\nTEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndAwokenWhileWaiting_PromptlyReturns) {\n    sp<DelayedWake> delayedWake = new DelayedWake(100, mLooper);\n    delayedWake->run();\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(1000);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. equal wake delay\";\n    EXPECT_EQ(Looper::POLL_WAKE, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because loop was awoken\";\n}\n\nTEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndNoRegisteredFDs_ImmediatelyReturns) {\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(0);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should be approx. zero\";\n    EXPECT_EQ(Looper::POLL_TIMEOUT, result)\n            << \"pollOnce result should be Looper::POLL_TIMEOUT\";\n}\n\nTEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndNoSignalledFDs_ImmediatelyReturns) {\n    Pipe pipe;\n    StubCallbackHandler handler(true);\n\n    handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(0);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should be approx. zero\";\n    EXPECT_EQ(Looper::POLL_TIMEOUT, result)\n            << \"pollOnce result should be Looper::POLL_TIMEOUT\";\n    EXPECT_EQ(0, handler.callbackCount)\n            << \"callback should not have been invoked because FD was not signalled\";\n}\n\nTEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndSignalledFD_ImmediatelyInvokesCallbackAndReturns) {\n    Pipe pipe;\n    StubCallbackHandler handler(true);\n\n    ASSERT_EQ(OK, pipe.writeSignal());\n    handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(0);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should be approx. zero\";\n    EXPECT_EQ(Looper::POLL_CALLBACK, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because FD was signalled\";\n    EXPECT_EQ(1, handler.callbackCount)\n            << \"callback should be invoked exactly once\";\n    EXPECT_EQ(pipe.receiveFd, handler.fd)\n            << \"callback should have received pipe fd as parameter\";\n    EXPECT_EQ(Looper::EVENT_INPUT, handler.events)\n            << \"callback should have received Looper::EVENT_INPUT as events\";\n}\n\nTEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndNoSignalledFDs_WaitsForTimeoutAndReturns) {\n    Pipe pipe;\n    StubCallbackHandler handler(true);\n\n    handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(100);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. equal timeout\";\n    EXPECT_EQ(Looper::POLL_TIMEOUT, result)\n            << \"pollOnce result should be Looper::POLL_TIMEOUT\";\n    EXPECT_EQ(0, handler.callbackCount)\n            << \"callback should not have been invoked because FD was not signalled\";\n}\n\nTEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDBeforeWaiting_ImmediatelyInvokesCallbackAndReturns) {\n    Pipe pipe;\n    StubCallbackHandler handler(true);\n\n    pipe.writeSignal();\n    handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(100);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    ASSERT_EQ(OK, pipe.readSignal())\n            << \"signal should actually have been written\";\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should be approx. zero\";\n    EXPECT_EQ(Looper::POLL_CALLBACK, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because FD was signalled\";\n    EXPECT_EQ(1, handler.callbackCount)\n            << \"callback should be invoked exactly once\";\n    EXPECT_EQ(pipe.receiveFd, handler.fd)\n            << \"callback should have received pipe fd as parameter\";\n    EXPECT_EQ(Looper::EVENT_INPUT, handler.events)\n            << \"callback should have received Looper::EVENT_INPUT as events\";\n}\n\nTEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDWhileWaiting_PromptlyInvokesCallbackAndReturns) {\n    Pipe pipe;\n    StubCallbackHandler handler(true);\n    sp<DelayedWriteSignal> delayedWriteSignal = new DelayedWriteSignal(100, & pipe);\n\n    handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);\n    delayedWriteSignal->run();\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(1000);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    ASSERT_EQ(OK, pipe.readSignal())\n            << \"signal should actually have been written\";\n    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. equal signal delay\";\n    EXPECT_EQ(Looper::POLL_CALLBACK, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because FD was signalled\";\n    EXPECT_EQ(1, handler.callbackCount)\n            << \"callback should be invoked exactly once\";\n    EXPECT_EQ(pipe.receiveFd, handler.fd)\n            << \"callback should have received pipe fd as parameter\";\n    EXPECT_EQ(Looper::EVENT_INPUT, handler.events)\n            << \"callback should have received Looper::EVENT_INPUT as events\";\n}\n\nTEST_F(LooperTest, PollOnce_WhenCallbackAddedThenRemoved_CallbackShouldNotBeInvoked) {\n    Pipe pipe;\n    StubCallbackHandler handler(true);\n\n    handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);\n    pipe.writeSignal(); // would cause FD to be considered signalled\n    mLooper->removeFd(pipe.receiveFd);\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(100);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    ASSERT_EQ(OK, pipe.readSignal())\n            << \"signal should actually have been written\";\n    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. equal timeout because FD was no longer registered\";\n    EXPECT_EQ(Looper::POLL_TIMEOUT, result)\n            << \"pollOnce result should be Looper::POLL_TIMEOUT\";\n    EXPECT_EQ(0, handler.callbackCount)\n            << \"callback should not be invoked\";\n}\n\nTEST_F(LooperTest, PollOnce_WhenCallbackReturnsFalse_CallbackShouldNotBeInvokedAgainLater) {\n    Pipe pipe;\n    StubCallbackHandler handler(false);\n\n    handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);\n\n    // First loop: Callback is registered and FD is signalled.\n    pipe.writeSignal();\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(0);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    ASSERT_EQ(OK, pipe.readSignal())\n            << \"signal should actually have been written\";\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. equal zero because FD was already signalled\";\n    EXPECT_EQ(Looper::POLL_CALLBACK, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because FD was signalled\";\n    EXPECT_EQ(1, handler.callbackCount)\n            << \"callback should be invoked\";\n\n    // Second loop: Callback is no longer registered and FD is signalled.\n    pipe.writeSignal();\n\n    stopWatch.reset();\n    result = mLooper->pollOnce(0);\n    elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    ASSERT_EQ(OK, pipe.readSignal())\n            << \"signal should actually have been written\";\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. equal zero because timeout was zero\";\n    EXPECT_EQ(Looper::POLL_TIMEOUT, result)\n            << \"pollOnce result should be Looper::POLL_TIMEOUT\";\n    EXPECT_EQ(1, handler.callbackCount)\n            << \"callback should not be invoked this time\";\n}\n\nTEST_F(LooperTest, PollOnce_WhenNonCallbackFdIsSignalled_ReturnsIdent) {\n    const int expectedIdent = 5;\n    void* expectedData = this;\n\n    Pipe pipe;\n\n    pipe.writeSignal();\n    mLooper->addFd(pipe.receiveFd, expectedIdent, Looper::EVENT_INPUT, NULL, expectedData);\n\n    StopWatch stopWatch(\"pollOnce\");\n    int fd;\n    int events;\n    void* data;\n    int result = mLooper->pollOnce(100, &fd, &events, &data);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    ASSERT_EQ(OK, pipe.readSignal())\n            << \"signal should actually have been written\";\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should be approx. zero\";\n    EXPECT_EQ(expectedIdent, result)\n            << \"pollOnce result should be the ident of the FD that was signalled\";\n    EXPECT_EQ(pipe.receiveFd, fd)\n            << \"pollOnce should have returned the received pipe fd\";\n    EXPECT_EQ(Looper::EVENT_INPUT, events)\n            << \"pollOnce should have returned Looper::EVENT_INPUT as events\";\n    EXPECT_EQ(expectedData, data)\n            << \"pollOnce should have returned the data\";\n}\n\nTEST_F(LooperTest, AddFd_WhenCallbackAdded_ReturnsOne) {\n    Pipe pipe;\n    int result = mLooper->addFd(pipe.receiveFd, 0, Looper::EVENT_INPUT, NULL, NULL);\n\n    EXPECT_EQ(1, result)\n            << \"addFd should return 1 because FD was added\";\n}\n\nTEST_F(LooperTest, AddFd_WhenIdentIsNegativeAndCallbackIsNull_ReturnsError) {\n    Pipe pipe;\n    int result = mLooper->addFd(pipe.receiveFd, -1, Looper::EVENT_INPUT, NULL, NULL);\n\n    EXPECT_EQ(-1, result)\n            << \"addFd should return -1 because arguments were invalid\";\n}\n\nTEST_F(LooperTest, AddFd_WhenNoCallbackAndAllowNonCallbacksIsFalse_ReturnsError) {\n    Pipe pipe;\n    sp<Looper> looper = new Looper(false /*allowNonCallbacks*/);\n    int result = looper->addFd(pipe.receiveFd, 0, 0, NULL, NULL);\n\n    EXPECT_EQ(-1, result)\n            << \"addFd should return -1 because arguments were invalid\";\n}\n\nTEST_F(LooperTest, RemoveFd_WhenCallbackNotAdded_ReturnsZero) {\n    int result = mLooper->removeFd(1);\n\n    EXPECT_EQ(0, result)\n            << \"removeFd should return 0 because FD not registered\";\n}\n\nTEST_F(LooperTest, RemoveFd_WhenCallbackAddedThenRemovedTwice_ReturnsOnceFirstTimeAndReturnsZeroSecondTime) {\n    Pipe pipe;\n    StubCallbackHandler handler(false);\n    handler.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);\n\n    // First time.\n    int result = mLooper->removeFd(pipe.receiveFd);\n\n    EXPECT_EQ(1, result)\n            << \"removeFd should return 1 first time because FD was registered\";\n\n    // Second time.\n    result = mLooper->removeFd(pipe.receiveFd);\n\n    EXPECT_EQ(0, result)\n            << \"removeFd should return 0 second time because FD was no longer registered\";\n}\n\nTEST_F(LooperTest, PollOnce_WhenCallbackAddedTwice_OnlySecondCallbackShouldBeInvoked) {\n    Pipe pipe;\n    StubCallbackHandler handler1(true);\n    StubCallbackHandler handler2(true);\n\n    handler1.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT);\n    handler2.setCallback(mLooper, pipe.receiveFd, Looper::EVENT_INPUT); // replace it\n    pipe.writeSignal(); // would cause FD to be considered signalled\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(100);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    ASSERT_EQ(OK, pipe.readSignal())\n            << \"signal should actually have been written\";\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. zero because FD was already signalled\";\n    EXPECT_EQ(Looper::POLL_CALLBACK, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because FD was signalled\";\n    EXPECT_EQ(0, handler1.callbackCount)\n            << \"original handler callback should not be invoked because it was replaced\";\n    EXPECT_EQ(1, handler2.callbackCount)\n            << \"replacement handler callback should be invoked\";\n}\n\nTEST_F(LooperTest, SendMessage_WhenOneMessageIsEnqueue_ShouldInvokeHandlerDuringNextPoll) {\n    sp<StubMessageHandler> handler = new StubMessageHandler();\n    mLooper->sendMessage(handler, Message(MSG_TEST1));\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(100);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. zero because message was already sent\";\n    EXPECT_EQ(Looper::POLL_CALLBACK, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because message was sent\";\n    EXPECT_EQ(size_t(1), handler->messages.size())\n            << \"handled message\";\n    EXPECT_EQ(MSG_TEST1, handler->messages[0].what)\n            << \"handled message\";\n}\n\nTEST_F(LooperTest, SendMessage_WhenMultipleMessagesAreEnqueued_ShouldInvokeHandlersInOrderDuringNextPoll) {\n    sp<StubMessageHandler> handler1 = new StubMessageHandler();\n    sp<StubMessageHandler> handler2 = new StubMessageHandler();\n    mLooper->sendMessage(handler1, Message(MSG_TEST1));\n    mLooper->sendMessage(handler2, Message(MSG_TEST2));\n    mLooper->sendMessage(handler1, Message(MSG_TEST3));\n    mLooper->sendMessage(handler1, Message(MSG_TEST4));\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(1000);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. zero because message was already sent\";\n    EXPECT_EQ(Looper::POLL_CALLBACK, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because message was sent\";\n    EXPECT_EQ(size_t(3), handler1->messages.size())\n            << \"handled message\";\n    EXPECT_EQ(MSG_TEST1, handler1->messages[0].what)\n            << \"handled message\";\n    EXPECT_EQ(MSG_TEST3, handler1->messages[1].what)\n            << \"handled message\";\n    EXPECT_EQ(MSG_TEST4, handler1->messages[2].what)\n            << \"handled message\";\n    EXPECT_EQ(size_t(1), handler2->messages.size())\n            << \"handled message\";\n    EXPECT_EQ(MSG_TEST2, handler2->messages[0].what)\n            << \"handled message\";\n}\n\nTEST_F(LooperTest, SendMessageDelayed_WhenSentToTheFuture_ShouldInvokeHandlerAfterDelayTime) {\n    sp<StubMessageHandler> handler = new StubMessageHandler();\n    mLooper->sendMessageDelayed(ms2ns(100), handler, Message(MSG_TEST1));\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(1000);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"first poll should end quickly because next message timeout was computed\";\n    EXPECT_EQ(Looper::POLL_WAKE, result)\n            << \"pollOnce result should be Looper::POLL_WAKE due to wakeup\";\n    EXPECT_EQ(size_t(0), handler->messages.size())\n            << \"no message handled yet\";\n\n    result = mLooper->pollOnce(1000);\n    elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_EQ(size_t(1), handler->messages.size())\n            << \"handled message\";\n    EXPECT_EQ(MSG_TEST1, handler->messages[0].what)\n            << \"handled message\";\n    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"second poll should end around the time of the delayed message dispatch\";\n    EXPECT_EQ(Looper::POLL_CALLBACK, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because message was sent\";\n\n    result = mLooper->pollOnce(100);\n    elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(100 + 100, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"third poll should timeout\";\n    EXPECT_EQ(Looper::POLL_TIMEOUT, result)\n            << \"pollOnce result should be Looper::POLL_TIMEOUT because there were no messages left\";\n}\n\nTEST_F(LooperTest, SendMessageDelayed_WhenSentToThePast_ShouldInvokeHandlerDuringNextPoll) {\n    sp<StubMessageHandler> handler = new StubMessageHandler();\n    mLooper->sendMessageDelayed(ms2ns(-1000), handler, Message(MSG_TEST1));\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(100);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. zero because message was already sent\";\n    EXPECT_EQ(Looper::POLL_CALLBACK, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because message was sent\";\n    EXPECT_EQ(size_t(1), handler->messages.size())\n            << \"handled message\";\n    EXPECT_EQ(MSG_TEST1, handler->messages[0].what)\n            << \"handled message\";\n}\n\nTEST_F(LooperTest, SendMessageDelayed_WhenSentToThePresent_ShouldInvokeHandlerDuringNextPoll) {\n    sp<StubMessageHandler> handler = new StubMessageHandler();\n    mLooper->sendMessageDelayed(0, handler, Message(MSG_TEST1));\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(100);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. zero because message was already sent\";\n    EXPECT_EQ(Looper::POLL_CALLBACK, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because message was sent\";\n    EXPECT_EQ(size_t(1), handler->messages.size())\n            << \"handled message\";\n    EXPECT_EQ(MSG_TEST1, handler->messages[0].what)\n            << \"handled message\";\n}\n\nTEST_F(LooperTest, SendMessageAtTime_WhenSentToTheFuture_ShouldInvokeHandlerAfterDelayTime) {\n    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);\n    sp<StubMessageHandler> handler = new StubMessageHandler();\n    mLooper->sendMessageAtTime(now + ms2ns(100), handler, Message(MSG_TEST1));\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(1000);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"first poll should end quickly because next message timeout was computed\";\n    EXPECT_EQ(Looper::POLL_WAKE, result)\n            << \"pollOnce result should be Looper::POLL_WAKE due to wakeup\";\n    EXPECT_EQ(size_t(0), handler->messages.size())\n            << \"no message handled yet\";\n\n    result = mLooper->pollOnce(1000);\n    elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_EQ(size_t(1), handler->messages.size())\n            << \"handled message\";\n    EXPECT_EQ(MSG_TEST1, handler->messages[0].what)\n            << \"handled message\";\n    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"second poll should end around the time of the delayed message dispatch\";\n    EXPECT_EQ(Looper::POLL_CALLBACK, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because message was sent\";\n\n    result = mLooper->pollOnce(100);\n    elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(100 + 100, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"third poll should timeout\";\n    EXPECT_EQ(Looper::POLL_TIMEOUT, result)\n            << \"pollOnce result should be Looper::POLL_TIMEOUT because there were no messages left\";\n}\n\nTEST_F(LooperTest, SendMessageAtTime_WhenSentToThePast_ShouldInvokeHandlerDuringNextPoll) {\n    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);\n    sp<StubMessageHandler> handler = new StubMessageHandler();\n    mLooper->sendMessageAtTime(now - ms2ns(1000), handler, Message(MSG_TEST1));\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(100);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. zero because message was already sent\";\n    EXPECT_EQ(Looper::POLL_CALLBACK, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because message was sent\";\n    EXPECT_EQ(size_t(1), handler->messages.size())\n            << \"handled message\";\n    EXPECT_EQ(MSG_TEST1, handler->messages[0].what)\n            << \"handled message\";\n}\n\nTEST_F(LooperTest, SendMessageAtTime_WhenSentToThePresent_ShouldInvokeHandlerDuringNextPoll) {\n    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);\n    sp<StubMessageHandler> handler = new StubMessageHandler();\n    mLooper->sendMessageAtTime(now, handler, Message(MSG_TEST1));\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(100);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. zero because message was already sent\";\n    EXPECT_EQ(Looper::POLL_CALLBACK, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because message was sent\";\n    EXPECT_EQ(size_t(1), handler->messages.size())\n            << \"handled message\";\n    EXPECT_EQ(MSG_TEST1, handler->messages[0].what)\n            << \"handled message\";\n}\n\nTEST_F(LooperTest, RemoveMessage_WhenRemovingAllMessagesForHandler_ShouldRemoveThoseMessage) {\n    sp<StubMessageHandler> handler = new StubMessageHandler();\n    mLooper->sendMessage(handler, Message(MSG_TEST1));\n    mLooper->sendMessage(handler, Message(MSG_TEST2));\n    mLooper->sendMessage(handler, Message(MSG_TEST3));\n    mLooper->removeMessages(handler);\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(0);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. zero because message was sent so looper was awoken\";\n    EXPECT_EQ(Looper::POLL_WAKE, result)\n            << \"pollOnce result should be Looper::POLL_WAKE because looper was awoken\";\n    EXPECT_EQ(size_t(0), handler->messages.size())\n            << \"no messages to handle\";\n\n    result = mLooper->pollOnce(0);\n\n    EXPECT_EQ(Looper::POLL_TIMEOUT, result)\n            << \"pollOnce result should be Looper::POLL_TIMEOUT because there was nothing to do\";\n    EXPECT_EQ(size_t(0), handler->messages.size())\n            << \"no messages to handle\";\n}\n\nTEST_F(LooperTest, RemoveMessage_WhenRemovingSomeMessagesForHandler_ShouldRemoveThoseMessage) {\n    sp<StubMessageHandler> handler = new StubMessageHandler();\n    mLooper->sendMessage(handler, Message(MSG_TEST1));\n    mLooper->sendMessage(handler, Message(MSG_TEST2));\n    mLooper->sendMessage(handler, Message(MSG_TEST3));\n    mLooper->sendMessage(handler, Message(MSG_TEST4));\n    mLooper->removeMessages(handler, MSG_TEST3);\n    mLooper->removeMessages(handler, MSG_TEST1);\n\n    StopWatch stopWatch(\"pollOnce\");\n    int result = mLooper->pollOnce(0);\n    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());\n\n    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)\n            << \"elapsed time should approx. zero because message was sent so looper was awoken\";\n    EXPECT_EQ(Looper::POLL_CALLBACK, result)\n            << \"pollOnce result should be Looper::POLL_CALLBACK because two messages were sent\";\n    EXPECT_EQ(size_t(2), handler->messages.size())\n            << \"no messages to handle\";\n    EXPECT_EQ(MSG_TEST2, handler->messages[0].what)\n            << \"handled message\";\n    EXPECT_EQ(MSG_TEST4, handler->messages[1].what)\n            << \"handled message\";\n\n    result = mLooper->pollOnce(0);\n\n    EXPECT_EQ(Looper::POLL_TIMEOUT, result)\n            << \"pollOnce result should be Looper::POLL_TIMEOUT because there was nothing to do\";\n    EXPECT_EQ(size_t(2), handler->messages.size())\n            << \"no more messages to handle\";\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/tests/LruCache_test.cpp",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <stdlib.h>\n#include <utils/JenkinsHash.h>\n#include <utils/LruCache.h>\n#include <cutils/log.h>\n#include <gtest/gtest.h>\n\nnamespace {\n\ntypedef int SimpleKey;\ntypedef const char* StringValue;\n\nstruct ComplexKey {\n    int k;\n\n    explicit ComplexKey(int k) : k(k) {\n        instanceCount += 1;\n    }\n\n    ComplexKey(const ComplexKey& other) : k(other.k) {\n        instanceCount += 1;\n    }\n\n    ~ComplexKey() {\n        instanceCount -= 1;\n    }\n\n    bool operator ==(const ComplexKey& other) const {\n        return k == other.k;\n    }\n\n    bool operator !=(const ComplexKey& other) const {\n        return k != other.k;\n    }\n\n    static ssize_t instanceCount;\n};\n\nssize_t ComplexKey::instanceCount = 0;\n\nstruct ComplexValue {\n    int v;\n\n    explicit ComplexValue(int v) : v(v) {\n        instanceCount += 1;\n    }\n\n    ComplexValue(const ComplexValue& other) : v(other.v) {\n        instanceCount += 1;\n    }\n\n    ~ComplexValue() {\n        instanceCount -= 1;\n    }\n\n    static ssize_t instanceCount;\n};\n\nssize_t ComplexValue::instanceCount = 0;\n\n} // namespace\n\n\nnamespace android {\n\ntypedef LruCache<ComplexKey, ComplexValue> ComplexCache;\n\ntemplate<> inline android::hash_t hash_type(const ComplexKey& value) {\n    return hash_type(value.k);\n}\n\nclass EntryRemovedCallback : public OnEntryRemoved<SimpleKey, StringValue> {\npublic:\n    EntryRemovedCallback() : callbackCount(0), lastKey(-1), lastValue(NULL) { }\n    ~EntryRemovedCallback() {}\n    void operator()(SimpleKey& k, StringValue& v) {\n        callbackCount += 1;\n        lastKey = k;\n        lastValue = v;\n    }\n    ssize_t callbackCount;\n    SimpleKey lastKey;\n    StringValue lastValue;\n};\n\nclass LruCacheTest : public testing::Test {\nprotected:\n    virtual void SetUp() {\n        ComplexKey::instanceCount = 0;\n        ComplexValue::instanceCount = 0;\n    }\n\n    virtual void TearDown() {\n        ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));\n    }\n\n    void assertInstanceCount(ssize_t keys, ssize_t values) {\n        if (keys != ComplexKey::instanceCount || values != ComplexValue::instanceCount) {\n            FAIL() << \"Expected \" << keys << \" keys and \" << values << \" values \"\n                    \"but there were actually \" << ComplexKey::instanceCount << \" keys and \"\n                    << ComplexValue::instanceCount << \" values\";\n        }\n    }\n};\n\nTEST_F(LruCacheTest, Empty) {\n    LruCache<SimpleKey, StringValue> cache(100);\n\n    EXPECT_EQ(NULL, cache.get(0));\n    EXPECT_EQ(0u, cache.size());\n}\n\nTEST_F(LruCacheTest, Simple) {\n    LruCache<SimpleKey, StringValue> cache(100);\n\n    cache.put(1, \"one\");\n    cache.put(2, \"two\");\n    cache.put(3, \"three\");\n    EXPECT_STREQ(\"one\", cache.get(1));\n    EXPECT_STREQ(\"two\", cache.get(2));\n    EXPECT_STREQ(\"three\", cache.get(3));\n    EXPECT_EQ(3u, cache.size());\n}\n\nTEST_F(LruCacheTest, MaxCapacity) {\n    LruCache<SimpleKey, StringValue> cache(2);\n\n    cache.put(1, \"one\");\n    cache.put(2, \"two\");\n    cache.put(3, \"three\");\n    EXPECT_EQ(NULL, cache.get(1));\n    EXPECT_STREQ(\"two\", cache.get(2));\n    EXPECT_STREQ(\"three\", cache.get(3));\n    EXPECT_EQ(2u, cache.size());\n}\n\nTEST_F(LruCacheTest, RemoveLru) {\n    LruCache<SimpleKey, StringValue> cache(100);\n\n    cache.put(1, \"one\");\n    cache.put(2, \"two\");\n    cache.put(3, \"three\");\n    cache.removeOldest();\n    EXPECT_EQ(NULL, cache.get(1));\n    EXPECT_STREQ(\"two\", cache.get(2));\n    EXPECT_STREQ(\"three\", cache.get(3));\n    EXPECT_EQ(2u, cache.size());\n}\n\nTEST_F(LruCacheTest, GetUpdatesLru) {\n    LruCache<SimpleKey, StringValue> cache(100);\n\n    cache.put(1, \"one\");\n    cache.put(2, \"two\");\n    cache.put(3, \"three\");\n    EXPECT_STREQ(\"one\", cache.get(1));\n    cache.removeOldest();\n    EXPECT_STREQ(\"one\", cache.get(1));\n    EXPECT_EQ(NULL, cache.get(2));\n    EXPECT_STREQ(\"three\", cache.get(3));\n    EXPECT_EQ(2u, cache.size());\n}\n\nuint32_t hash_int(int x) {\n    return JenkinsHashWhiten(JenkinsHashMix(0, x));\n}\n\nTEST_F(LruCacheTest, StressTest) {\n    const size_t kCacheSize = 512;\n    LruCache<SimpleKey, StringValue> cache(512);\n    const size_t kNumKeys = 16 * 1024;\n    const size_t kNumIters = 100000;\n    char* strings[kNumKeys];\n\n    for (size_t i = 0; i < kNumKeys; i++) {\n        strings[i] = (char *)malloc(16);\n        sprintf(strings[i], \"%zu\", i);\n    }\n\n    srandom(12345);\n    int hitCount = 0;\n    for (size_t i = 0; i < kNumIters; i++) {\n        int index = random() % kNumKeys;\n        uint32_t key = hash_int(index);\n        const char *val = cache.get(key);\n        if (val != NULL) {\n            EXPECT_EQ(strings[index], val);\n            hitCount++;\n        } else {\n            cache.put(key, strings[index]);\n        }\n    }\n    size_t expectedHitCount = kNumIters * kCacheSize / kNumKeys;\n    EXPECT_LT(int(expectedHitCount * 0.9), hitCount);\n    EXPECT_GT(int(expectedHitCount * 1.1), hitCount);\n    EXPECT_EQ(kCacheSize, cache.size());\n\n    for (size_t i = 0; i < kNumKeys; i++) {\n        free((void *)strings[i]);\n    }\n}\n\nTEST_F(LruCacheTest, NoLeak) {\n    ComplexCache cache(100);\n\n    cache.put(ComplexKey(0), ComplexValue(0));\n    cache.put(ComplexKey(1), ComplexValue(1));\n    EXPECT_EQ(2U, cache.size());\n    assertInstanceCount(2, 3);  // the member mNullValue counts as an instance\n}\n\nTEST_F(LruCacheTest, Clear) {\n    ComplexCache cache(100);\n\n    cache.put(ComplexKey(0), ComplexValue(0));\n    cache.put(ComplexKey(1), ComplexValue(1));\n    EXPECT_EQ(2U, cache.size());\n    assertInstanceCount(2, 3);\n    cache.clear();\n    assertInstanceCount(0, 1);\n}\n\nTEST_F(LruCacheTest, ClearNoDoubleFree) {\n    {\n        ComplexCache cache(100);\n\n        cache.put(ComplexKey(0), ComplexValue(0));\n        cache.put(ComplexKey(1), ComplexValue(1));\n        EXPECT_EQ(2U, cache.size());\n        assertInstanceCount(2, 3);\n        cache.removeOldest();\n        cache.clear();\n        assertInstanceCount(0, 1);\n    }\n    assertInstanceCount(0, 0);\n}\n\nTEST_F(LruCacheTest, ClearReuseOk) {\n    ComplexCache cache(100);\n\n    cache.put(ComplexKey(0), ComplexValue(0));\n    cache.put(ComplexKey(1), ComplexValue(1));\n    EXPECT_EQ(2U, cache.size());\n    assertInstanceCount(2, 3);\n    cache.clear();\n    assertInstanceCount(0, 1);\n    cache.put(ComplexKey(0), ComplexValue(0));\n    cache.put(ComplexKey(1), ComplexValue(1));\n    EXPECT_EQ(2U, cache.size());\n    assertInstanceCount(2, 3);\n}\n\nTEST_F(LruCacheTest, Callback) {\n    LruCache<SimpleKey, StringValue> cache(100);\n    EntryRemovedCallback callback;\n    cache.setOnEntryRemovedListener(&callback);\n\n    cache.put(1, \"one\");\n    cache.put(2, \"two\");\n    cache.put(3, \"three\");\n    EXPECT_EQ(3U, cache.size());\n    cache.removeOldest();\n    EXPECT_EQ(1, callback.callbackCount);\n    EXPECT_EQ(1, callback.lastKey);\n    EXPECT_STREQ(\"one\", callback.lastValue);\n}\n\nTEST_F(LruCacheTest, CallbackOnClear) {\n    LruCache<SimpleKey, StringValue> cache(100);\n    EntryRemovedCallback callback;\n    cache.setOnEntryRemovedListener(&callback);\n\n    cache.put(1, \"one\");\n    cache.put(2, \"two\");\n    cache.put(3, \"three\");\n    EXPECT_EQ(3U, cache.size());\n    cache.clear();\n    EXPECT_EQ(3, callback.callbackCount);\n}\n\nTEST_F(LruCacheTest, IteratorCheck) {\n    LruCache<int, int> cache(100);\n\n    cache.put(1, 4);\n    cache.put(2, 5);\n    cache.put(3, 6);\n    EXPECT_EQ(3U, cache.size());\n\n    LruCache<int, int>::Iterator it(cache);\n    std::unordered_set<int> returnedValues;\n    while (it.next()) {\n        int v = it.value();\n        // Check we haven't seen the value before.\n        EXPECT_TRUE(returnedValues.find(v) == returnedValues.end());\n        returnedValues.insert(v);\n    }\n    EXPECT_EQ(std::unordered_set<int>({4, 5, 6}), returnedValues);\n}\n\nTEST_F(LruCacheTest, EmptyCacheIterator) {\n    // Check that nothing crashes...\n    LruCache<int, int> cache(100);\n\n    LruCache<int, int>::Iterator it(cache);\n    std::unordered_set<int> returnedValues;\n    while (it.next()) {\n        returnedValues.insert(it.value());\n    }\n    EXPECT_EQ(std::unordered_set<int>(), returnedValues);\n}\n\nTEST_F(LruCacheTest, OneElementCacheIterator) {\n    // Check that nothing crashes...\n    LruCache<int, int> cache(100);\n    cache.put(1, 2);\n\n    LruCache<int, int>::Iterator it(cache);\n    std::unordered_set<int> returnedValues;\n    while (it.next()) {\n        returnedValues.insert(it.value());\n    }\n    EXPECT_EQ(std::unordered_set<int>({ 2 }), returnedValues);\n}\n\nTEST_F(LruCacheTest, OneElementCacheRemove) {\n    LruCache<int, int> cache(100);\n    cache.put(1, 2);\n\n    cache.remove(1);\n\n    LruCache<int, int>::Iterator it(cache);\n    std::unordered_set<int> returnedValues;\n    while (it.next()) {\n        returnedValues.insert(it.value());\n    }\n    EXPECT_EQ(std::unordered_set<int>({ }), returnedValues);\n}\n\nTEST_F(LruCacheTest, Remove) {\n    LruCache<int, int> cache(100);\n    cache.put(1, 4);\n    cache.put(2, 5);\n    cache.put(3, 6);\n\n    cache.remove(2);\n\n    LruCache<int, int>::Iterator it(cache);\n    std::unordered_set<int> returnedValues;\n    while (it.next()) {\n        returnedValues.insert(it.value());\n    }\n    EXPECT_EQ(std::unordered_set<int>({ 4, 6 }), returnedValues);\n}\n\nTEST_F(LruCacheTest, RemoveYoungest) {\n    LruCache<int, int> cache(100);\n    cache.put(1, 4);\n    cache.put(2, 5);\n    cache.put(3, 6);\n\n    cache.remove(3);\n\n    LruCache<int, int>::Iterator it(cache);\n    std::unordered_set<int> returnedValues;\n    while (it.next()) {\n        returnedValues.insert(it.value());\n    }\n    EXPECT_EQ(std::unordered_set<int>({ 4, 5 }), returnedValues);\n}\n\nTEST_F(LruCacheTest, RemoveNonMember) {\n    LruCache<int, int> cache(100);\n    cache.put(1, 4);\n    cache.put(2, 5);\n    cache.put(3, 6);\n\n    cache.remove(7);\n\n    LruCache<int, int>::Iterator it(cache);\n    std::unordered_set<int> returnedValues;\n    while (it.next()) {\n        returnedValues.insert(it.value());\n    }\n    EXPECT_EQ(std::unordered_set<int>({ 4, 5, 6 }), returnedValues);\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/tests/String8_test.cpp",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"String8_test\"\n#include <utils/Log.h>\n#include <utils/String8.h>\n\n#include <gtest/gtest.h>\n\nnamespace android {\n\nclass String8Test : public testing::Test {\nprotected:\n    virtual void SetUp() {\n    }\n\n    virtual void TearDown() {\n    }\n};\n\nTEST_F(String8Test, Cstr) {\n    String8 tmp(\"Hello, world!\");\n\n    EXPECT_STREQ(tmp.string(), \"Hello, world!\");\n}\n\nTEST_F(String8Test, OperatorPlus) {\n    String8 src1(\"Hello, \");\n\n    // Test adding String8 + const char*\n    const char* ccsrc2 = \"world!\";\n    String8 dst1 = src1 + ccsrc2;\n    EXPECT_STREQ(dst1.string(), \"Hello, world!\");\n    EXPECT_STREQ(src1.string(), \"Hello, \");\n    EXPECT_STREQ(ccsrc2, \"world!\");\n\n    // Test adding String8 + String8\n    String8 ssrc2(\"world!\");\n    String8 dst2 = src1 + ssrc2;\n    EXPECT_STREQ(dst2.string(), \"Hello, world!\");\n    EXPECT_STREQ(src1.string(), \"Hello, \");\n    EXPECT_STREQ(ssrc2.string(), \"world!\");\n}\n\nTEST_F(String8Test, OperatorPlusEquals) {\n    String8 src1(\"My voice\");\n\n    // Testing String8 += String8\n    String8 src2(\" is my passport.\");\n    src1 += src2;\n    EXPECT_STREQ(src1.string(), \"My voice is my passport.\");\n    EXPECT_STREQ(src2.string(), \" is my passport.\");\n\n    // Adding const char* to the previous string.\n    const char* src3 = \" Verify me.\";\n    src1 += src3;\n    EXPECT_STREQ(src1.string(), \"My voice is my passport. Verify me.\");\n    EXPECT_STREQ(src2.string(), \" is my passport.\");\n    EXPECT_STREQ(src3, \" Verify me.\");\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/tests/StrongPointer_test.cpp",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <gtest/gtest.h>\n\n#include <utils/StrongPointer.h>\n#include <utils/RefBase.h>\n\nusing namespace android;\n\nclass Foo : public LightRefBase<Foo> {\npublic:\n    Foo(bool* deleted_check) : mDeleted(deleted_check) {\n        *mDeleted = false;\n    }\n\n    ~Foo() {\n        *mDeleted = true;\n    }\nprivate:\n    bool* mDeleted;\n};\n\nTEST(StrongPointer, move) {\n    bool isDeleted;\n    Foo* foo = new Foo(&isDeleted);\n    ASSERT_EQ(0, foo->getStrongCount());\n    ASSERT_FALSE(isDeleted) << \"Already deleted...?\";\n    sp<Foo> sp1(foo);\n    ASSERT_EQ(1, foo->getStrongCount());\n    {\n        sp<Foo> sp2 = std::move(sp1);\n        ASSERT_EQ(1, foo->getStrongCount()) << \"std::move failed, incremented refcnt\";\n        ASSERT_EQ(nullptr, sp1.get()) << \"std::move failed, sp1 is still valid\";\n        // The strong count isn't increasing, let's double check the old object\n        // is properly reset and doesn't early delete\n        sp1 = std::move(sp2);\n    }\n    ASSERT_FALSE(isDeleted) << \"deleted too early! still has a reference!\";\n    {\n        // Now let's double check it deletes on time\n        sp<Foo> sp2 = std::move(sp1);\n    }\n    ASSERT_TRUE(isDeleted) << \"foo was leaked!\";\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/tests/TestHelpers.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef TESTHELPERS_H\n#define TESTHELPERS_H\n\n#include <utils/threads.h>\n\nnamespace android {\n\nclass Pipe {\npublic:\n    int sendFd;\n    int receiveFd;\n\n    Pipe() {\n        int fds[2];\n        ::pipe(fds);\n\n        receiveFd = fds[0];\n        sendFd = fds[1];\n    }\n\n    ~Pipe() {\n        if (sendFd != -1) {\n            ::close(sendFd);\n        }\n\n        if (receiveFd != -1) {\n            ::close(receiveFd);\n        }\n    }\n\n    status_t writeSignal() {\n        ssize_t nWritten = ::write(sendFd, \"*\", 1);\n        return nWritten == 1 ? 0 : -errno;\n    }\n\n    status_t readSignal() {\n        char buf[1];\n        ssize_t nRead = ::read(receiveFd, buf, 1);\n        return nRead == 1 ? 0 : nRead == 0 ? -EPIPE : -errno;\n    }\n};\n\nclass DelayedTask : public Thread {\n    int mDelayMillis;\n\npublic:\n    DelayedTask(int delayMillis) : mDelayMillis(delayMillis) { }\n\nprotected:\n    virtual ~DelayedTask() { }\n\n    virtual void doTask() = 0;\n\n    virtual bool threadLoop() {\n        usleep(mDelayMillis * 1000);\n        doTask();\n        return false;\n    }\n};\n\n} // namespace android\n\n#endif // TESTHELPERS_H\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/tests/Unicode_test.cpp",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"Unicode_test\"\n#include <utils/Log.h>\n#include <utils/Unicode.h>\n\n#include <gtest/gtest.h>\n\nnamespace android {\n\nclass UnicodeTest : public testing::Test {\nprotected:\n    virtual void SetUp() {\n    }\n\n    virtual void TearDown() {\n    }\n};\n\nTEST_F(UnicodeTest, UTF8toUTF16ZeroLength) {\n    ssize_t measured;\n\n    const uint8_t str[] = { };\n\n    measured = utf8_to_utf16_length(str, 0);\n    EXPECT_EQ(0, measured)\n            << \"Zero length input should return zero length output.\";\n}\n\nTEST_F(UnicodeTest, UTF8toUTF16ASCIILength) {\n    ssize_t measured;\n\n    // U+0030 or ASCII '0'\n    const uint8_t str[] = { 0x30 };\n\n    measured = utf8_to_utf16_length(str, sizeof(str));\n    EXPECT_EQ(1, measured)\n            << \"ASCII glyphs should have a length of 1 char16_t\";\n}\n\nTEST_F(UnicodeTest, UTF8toUTF16Plane1Length) {\n    ssize_t measured;\n\n    // U+2323 SMILE\n    const uint8_t str[] = { 0xE2, 0x8C, 0xA3 };\n\n    measured = utf8_to_utf16_length(str, sizeof(str));\n    EXPECT_EQ(1, measured)\n            << \"Plane 1 glyphs should have a length of 1 char16_t\";\n}\n\nTEST_F(UnicodeTest, UTF8toUTF16SurrogateLength) {\n    ssize_t measured;\n\n    // U+10000\n    const uint8_t str[] = { 0xF0, 0x90, 0x80, 0x80 };\n\n    measured = utf8_to_utf16_length(str, sizeof(str));\n    EXPECT_EQ(2, measured)\n            << \"Surrogate pairs should have a length of 2 char16_t\";\n}\n\nTEST_F(UnicodeTest, UTF8toUTF16TruncatedUTF8) {\n    ssize_t measured;\n\n    // Truncated U+2323 SMILE\n    // U+2323 SMILE\n    const uint8_t str[] = { 0xE2, 0x8C };\n\n    measured = utf8_to_utf16_length(str, sizeof(str));\n    EXPECT_EQ(-1, measured)\n            << \"Truncated UTF-8 should return -1 to indicate invalid\";\n}\n\nTEST_F(UnicodeTest, UTF8toUTF16Normal) {\n    const uint8_t str[] = {\n        0x30, // U+0030, 1 UTF-16 character\n        0xC4, 0x80, // U+0100, 1 UTF-16 character\n        0xE2, 0x8C, 0xA3, // U+2323, 1 UTF-16 character\n        0xF0, 0x90, 0x80, 0x80, // U+10000, 2 UTF-16 character\n    };\n\n    char16_t output[1 + 1 + 1 + 2 + 1]; // Room for NULL\n\n    utf8_to_utf16(str, sizeof(str), output);\n\n    EXPECT_EQ(0x0030, output[0])\n            << \"should be U+0030\";\n    EXPECT_EQ(0x0100, output[1])\n            << \"should be U+0100\";\n    EXPECT_EQ(0x2323, output[2])\n            << \"should be U+2323\";\n    EXPECT_EQ(0xD800, output[3])\n            << \"should be first half of surrogate U+10000\";\n    EXPECT_EQ(0xDC00, output[4])\n            << \"should be second half of surrogate U+10000\";\n    EXPECT_EQ(NULL, output[5])\n            << \"should be NULL terminated\";\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libutils/tests/Vector_test.cpp",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"Vector_test\"\n\n#define __STDC_LIMIT_MACROS\n#include <stdint.h>\n#include <utils/Vector.h>\n#include <cutils/log.h>\n#include <gtest/gtest.h>\n#include <unistd.h>\n\nnamespace android {\n\nclass VectorTest : public testing::Test {\nprotected:\n    virtual void SetUp() {\n    }\n\n    virtual void TearDown() {\n    }\n\npublic:\n};\n\n\nTEST_F(VectorTest, CopyOnWrite_CopyAndAddElements) {\n\n    Vector<int> vector;\n    Vector<int> other;\n    vector.setCapacity(8);\n\n    vector.add(1);\n    vector.add(2);\n    vector.add(3);\n\n    EXPECT_EQ(3U, vector.size());\n\n    // copy the vector\n    other = vector;\n\n    EXPECT_EQ(3U, other.size());\n\n    // add an element to the first vector\n    vector.add(4);\n\n    // make sure the sizes are correct\n    EXPECT_EQ(4U, vector.size());\n    EXPECT_EQ(3U, other.size());\n\n    // add an element to the copy\n    other.add(5);\n\n    // make sure the sizes are correct\n    EXPECT_EQ(4U, vector.size());\n    EXPECT_EQ(4U, other.size());\n\n    // make sure the content of both vectors are correct\n    EXPECT_EQ(vector[3], 4);\n    EXPECT_EQ(other[3], 5);\n}\n\n// TODO: gtest isn't capable of parsing Abort messages formatted by\n// Android (fails differently on host and target), so we always need to\n// use an empty error message for death tests.\nTEST_F(VectorTest, SetCapacity_Overflow) {\n  Vector<int> vector;\n  EXPECT_DEATH(vector.setCapacity(SIZE_MAX / sizeof(int) + 1), \"\");\n}\n\nTEST_F(VectorTest, SetCapacity_ShrinkBelowSize) {\n  Vector<int> vector;\n  vector.add(1);\n  vector.add(2);\n  vector.add(3);\n  vector.add(4);\n\n  vector.setCapacity(8);\n  ASSERT_EQ(8, vector.capacity());\n  vector.setCapacity(2);\n  ASSERT_EQ(8, vector.capacity());\n}\n\n// NOTE: All of the tests below are useless because of the \"TODO\" above.\n// We have no way of knowing *why* the process crashed. Given that we're\n// inserting a NULL array, we'll fail with a SIGSEGV eventually. We need\n// the ability to make assertions on the abort message to make sure we're\n// failing for the right reasons.\nTEST_F(VectorTest, _grow_OverflowSize) {\n  Vector<int> vector;\n  vector.add(1);\n\n  // Checks that the size calculation (not the capacity calculation) doesn't\n  // overflow : the size here will be (1 + SIZE_MAX).\n  //\n  // EXPECT_DEATH(vector.insertArrayAt(NULL, 0, SIZE_MAX), \"new_size_overflow\");\n  EXPECT_DEATH(vector.insertArrayAt(NULL, 0, SIZE_MAX), \"\");\n}\n\nTEST_F(VectorTest, _grow_OverflowCapacityDoubling) {\n  Vector<int> vector;\n\n  // This should fail because the calculated capacity will overflow even though\n  // the size of the vector doesn't.\n  //\n  // EXPECT_DEATH(vector.insertArrayAt(NULL, 0, (SIZE_MAX - 1)), \"new_capacity_overflow\");\n  EXPECT_DEATH(vector.insertArrayAt(NULL, 0, (SIZE_MAX - 1)), \"\");\n}\n\nTEST_F(VectorTest, _grow_OverflowBufferAlloc) {\n  Vector<int> vector;\n  // This should fail because the capacity * sizeof(int) overflows, even\n  // though the capacity itself doesn't.\n  //\n  // EXPECT_DEATH(vector.insertArrayAt(NULL, 0, (SIZE_MAX / 2)), \"new_alloc_size overflow\");\n  EXPECT_DEATH(vector.insertArrayAt(NULL, 0, (SIZE_MAX / 2)), \"\");\n}\n\nTEST_F(VectorTest, editArray_Shared) {\n  Vector<int> vector1;\n  vector1.add(1);\n  vector1.add(2);\n  vector1.add(3);\n  vector1.add(4);\n\n  Vector<int> vector2 = vector1;\n  ASSERT_EQ(vector1.array(), vector2.array());\n  // We must make a copy here, since we're not the exclusive owners\n  // of this array.\n  ASSERT_NE(vector1.editArray(), vector2.editArray());\n\n  // Vector doesn't implement operator ==.\n  ASSERT_EQ(vector1.size(), vector2.size());\n  for (size_t i = 0; i < vector1.size(); ++i) {\n    EXPECT_EQ(vector1[i], vector2[i]);\n  }\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt/system/core/libziparchive/Android.mk",
    "content": "#\n# Copyright (C) 2013 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nLOCAL_PATH := $(call my-dir)\n\nlibziparchive_source_files := \\\n    zip_archive.cc \\\n    zip_archive_stream_entry.cc \\\n    zip_writer.cc \\\n\nlibziparchive_test_files := \\\n    entry_name_utils_test.cc \\\n    zip_archive_test.cc \\\n    zip_writer_test.cc \\\n\n# ZLIB_CONST turns on const for input buffers, which is pretty standard.\nlibziparchive_common_c_flags := \\\n    -DZLIB_CONST \\\n    -Werror \\\n    -Wall \\\n\n# Incorrectly warns when C++11 empty brace {} initializer is used.\n# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61489\nlibziparchive_common_cpp_flags := \\\n    -Wold-style-cast \\\n    -Wno-missing-field-initializers \\\n\ninclude $(CLEAR_VARS)\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_SRC_FILES := $(libziparchive_source_files)\nLOCAL_STATIC_LIBRARIES := libz\nLOCAL_SHARED_LIBRARIES := libutils libbase\nLOCAL_MODULE:= libziparchive\nLOCAL_CFLAGS := $(libziparchive_common_c_flags)\nLOCAL_CPPFLAGS := $(libziparchive_common_cpp_flags)\ninclude $(BUILD_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_SRC_FILES := $(libziparchive_source_files)\nLOCAL_STATIC_LIBRARIES := libz libutils libbase\nLOCAL_MODULE:= libziparchive-host\nLOCAL_CFLAGS := $(libziparchive_common_c_flags)\nLOCAL_CFLAGS_windows := -mno-ms-bitfields\nLOCAL_CPPFLAGS := $(libziparchive_common_cpp_flags)\n\nLOCAL_MULTILIB := both\nLOCAL_MODULE_HOST_OS := darwin linux windows\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\ninclude $(CLEAR_VARS)\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_SRC_FILES := $(libziparchive_source_files)\nLOCAL_STATIC_LIBRARIES := libutils\nLOCAL_SHARED_LIBRARIES := libz-host liblog libbase\nLOCAL_MODULE:= libziparchive-host\nLOCAL_CFLAGS := $(libziparchive_common_c_flags)\nLOCAL_CPPFLAGS := $(libziparchive_common_cpp_flags)\nLOCAL_MULTILIB := both\ninclude $(BUILD_HOST_SHARED_LIBRARY)\n\n# Tests.\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := ziparchive-tests\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_CFLAGS := $(libziparchive_common_c_flags)\nLOCAL_CPPFLAGS := $(libziparchive_common_cpp_flags)\nLOCAL_SRC_FILES := $(libziparchive_test_files)\nLOCAL_SHARED_LIBRARIES := \\\n    libbase \\\n    liblog \\\n\nLOCAL_STATIC_LIBRARIES := \\\n    libziparchive \\\n    libz \\\n    libutils \\\n\ninclude $(BUILD_NATIVE_TEST)\n\ninclude $(CLEAR_VARS)\nLOCAL_MODULE := ziparchive-tests-host\nLOCAL_CPP_EXTENSION := .cc\nLOCAL_CFLAGS := $(libziparchive_common_c_flags)\nLOCAL_CPPFLAGS := -Wno-unnamed-type-template-args $(libziparchive_common_cpp_flags)\nLOCAL_SRC_FILES := $(libziparchive_test_files)\nLOCAL_STATIC_LIBRARIES := \\\n    libziparchive-host \\\n    libz \\\n    libbase \\\n    libutils \\\n    liblog \\\n\nLOCAL_MODULE_HOST_OS := darwin linux windows\ninclude $(BUILD_HOST_NATIVE_TEST)\n"
  },
  {
    "path": "atlas-aapt/system/core/libziparchive/entry_name_utils-inl.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef LIBZIPARCHIVE_ENTRY_NAME_UTILS_INL_H_\n#define LIBZIPARCHIVE_ENTRY_NAME_UTILS_INL_H_\n\n#include <stddef.h>\n#include <stdint.h>\n\n// Check if |length| bytes at |entry_name| constitute a valid entry name.\n// Entry names must be valid UTF-8 and must not contain '0'.\ninline bool IsValidEntryName(const uint8_t* entry_name, const size_t length) {\n  for (size_t i = 0; i < length; ++i) {\n    const uint8_t byte = entry_name[i];\n    if (byte == 0) {\n      return false;\n    } else if ((byte & 0x80) == 0) {\n      // Single byte sequence.\n      continue;\n    } else if ((byte & 0xc0) == 0x80 || (byte & 0xfe) == 0xfe) {\n      // Invalid sequence.\n      return false;\n    } else {\n      // 2-5 byte sequences.\n      for (uint8_t first = byte << 1; first & 0x80; first <<= 1) {\n        ++i;\n\n        // Missing continuation byte..\n        if (i == length) {\n          return false;\n        }\n\n        // Invalid continuation byte.\n        const uint8_t continuation_byte = entry_name[i];\n        if ((continuation_byte & 0xc0) != 0x80) {\n          return false;\n        }\n      }\n    }\n  }\n\n  return true;\n}\n\n\n#endif  // LIBZIPARCHIVE_ENTRY_NAME_UTILS_INL_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/libziparchive/entry_name_utils_test.cc",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"entry_name_utils-inl.h\"\n\n#include <gtest/gtest.h>\n\nTEST(entry_name_utils, NullChars) {\n  // 'A', 'R', '\\0', 'S', 'E'\n  const uint8_t zeroes[] = { 0x41, 0x52, 0x00, 0x53, 0x45 };\n  ASSERT_FALSE(IsValidEntryName(zeroes, sizeof(zeroes)));\n\n  const uint8_t zeroes_continuation_chars[] = { 0xc2, 0xa1, 0xc2, 0x00 };\n  ASSERT_FALSE(IsValidEntryName(zeroes_continuation_chars,\n                                sizeof(zeroes_continuation_chars)));\n}\n\nTEST(entry_name_utils, InvalidSequence) {\n  // 0xfe is an invalid start byte\n  const uint8_t invalid[] = { 0x41, 0xfe };\n  ASSERT_FALSE(IsValidEntryName(invalid, sizeof(invalid)));\n\n  // 0x91 is an invalid start byte (it's a valid continuation byte).\n  const uint8_t invalid2[] = { 0x41, 0x91 };\n  ASSERT_FALSE(IsValidEntryName(invalid2, sizeof(invalid2)));\n}\n\nTEST(entry_name_utils, TruncatedContinuation) {\n  // Malayalam script with truncated bytes. There should be 2 bytes\n  // after 0xe0\n  const uint8_t truncated[] = { 0xe0, 0xb4, 0x85, 0xe0, 0xb4 };\n  ASSERT_FALSE(IsValidEntryName(truncated, sizeof(truncated)));\n\n  // 0xc2 is the start of a 2 byte sequence that we've subsequently\n  // dropped.\n  const uint8_t truncated2[] = { 0xc2, 0xc2, 0xa1 };\n  ASSERT_FALSE(IsValidEntryName(truncated2, sizeof(truncated2)));\n}\n\nTEST(entry_name_utils, BadContinuation) {\n  // 0x41 is an invalid continuation char, since it's MSBs\n  // aren't \"10...\" (are 01).\n  const uint8_t bad[] = { 0xc2, 0xa1, 0xc2, 0x41 };\n  ASSERT_FALSE(IsValidEntryName(bad, sizeof(bad)));\n\n  // 0x41 is an invalid continuation char, since it's MSBs\n  // aren't \"10...\" (are 11).\n  const uint8_t bad2[] = { 0xc2, 0xa1, 0xc2, 0xfe };\n  ASSERT_FALSE(IsValidEntryName(bad2, sizeof(bad2)));\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libziparchive/zip_archive.cc",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * Read-only access to Zip archives, with minimal heap allocation.\n */\n\n#include <assert.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <inttypes.h>\n#include <limits.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include <memory>\n#include <vector>\n\n#include \"android-base/file.h\"\n#include \"android-base/macros.h\"  // TEMP_FAILURE_RETRY may or may not be in unistd\n#include \"android-base/memory.h\"\n#include \"log/log.h\"\n#include \"utils/Compat.h\"\n#include \"utils/FileMap.h\"\n#include \"ziparchive/zip_archive.h\"\n#include \"zlib.h\"\n\n#include \"entry_name_utils-inl.h\"\n#include \"zip_archive_common.h\"\n#include \"zip_archive_private.h\"\n\nusing android::base::get_unaligned;\n\n// This is for windows. If we don't open a file in binary mode, weird\n// things will happen.\n#ifndef O_BINARY\n#define O_BINARY 0\n#endif\n\n// The maximum number of bytes to scan backwards for the EOCD start.\nstatic const uint32_t kMaxEOCDSearch = kMaxCommentLen + sizeof(EocdRecord);\n\nstatic const char* kErrorMessages[] = {\n  \"Unknown return code.\",\n  \"Iteration ended\",\n  \"Zlib error\",\n  \"Invalid file\",\n  \"Invalid handle\",\n  \"Duplicate entries in archive\",\n  \"Empty archive\",\n  \"Entry not found\",\n  \"Invalid offset\",\n  \"Inconsistent information\",\n  \"Invalid entry name\",\n  \"I/O Error\",\n  \"File mapping failed\"\n};\n\nstatic const int32_t kErrorMessageUpperBound = 0;\n\nstatic const int32_t kIterationEnd = -1;\n\n// We encountered a Zlib error when inflating a stream from this file.\n// Usually indicates file corruption.\nstatic const int32_t kZlibError = -2;\n\n// The input file cannot be processed as a zip archive. Usually because\n// it's too small, too large or does not have a valid signature.\nstatic const int32_t kInvalidFile = -3;\n\n// An invalid iteration / ziparchive handle was passed in as an input\n// argument.\nstatic const int32_t kInvalidHandle = -4;\n\n// The zip archive contained two (or possibly more) entries with the same\n// name.\nstatic const int32_t kDuplicateEntry = -5;\n\n// The zip archive contains no entries.\nstatic const int32_t kEmptyArchive = -6;\n\n// The specified entry was not found in the archive.\nstatic const int32_t kEntryNotFound = -7;\n\n// The zip archive contained an invalid local file header pointer.\nstatic const int32_t kInvalidOffset = -8;\n\n// The zip archive contained inconsistent entry information. This could\n// be because the central directory & local file header did not agree, or\n// if the actual uncompressed length or crc32 do not match their declared\n// values.\nstatic const int32_t kInconsistentInformation = -9;\n\n// An invalid entry name was encountered.\nstatic const int32_t kInvalidEntryName = -10;\n\n// An I/O related system call (read, lseek, ftruncate, map) failed.\nstatic const int32_t kIoError = -11;\n\n// We were not able to mmap the central directory or entry contents.\nstatic const int32_t kMmapFailed = -12;\n\nstatic const int32_t kErrorMessageLowerBound = -13;\n\n/*\n * A Read-only Zip archive.\n *\n * We want \"open\" and \"find entry by name\" to be fast operations, and\n * we want to use as little memory as possible.  We memory-map the zip\n * central directory, and load a hash table with pointers to the filenames\n * (which aren't null-terminated).  The other fields are at a fixed offset\n * from the filename, so we don't need to extract those (but we do need\n * to byte-read and endian-swap them every time we want them).\n *\n * It's possible that somebody has handed us a massive (~1GB) zip archive,\n * so we can't expect to mmap the entire file.\n *\n * To speed comparisons when doing a lookup by name, we could make the mapping\n * \"private\" (copy-on-write) and null-terminate the filenames after verifying\n * the record structure.  However, this requires a private mapping of\n * every page that the Central Directory touches.  Easier to tuck a copy\n * of the string length into the hash table entry.\n */\n\n/*\n * Round up to the next highest power of 2.\n *\n * Found on http://graphics.stanford.edu/~seander/bithacks.html.\n */\nstatic uint32_t RoundUpPower2(uint32_t val) {\n  val--;\n  val |= val >> 1;\n  val |= val >> 2;\n  val |= val >> 4;\n  val |= val >> 8;\n  val |= val >> 16;\n  val++;\n\n  return val;\n}\n\nstatic uint32_t ComputeHash(const ZipString& name) {\n  uint32_t hash = 0;\n  uint16_t len = name.name_length;\n  const uint8_t* str = name.name;\n\n  while (len--) {\n    hash = hash * 31 + *str++;\n  }\n\n  return hash;\n}\n\n/*\n * Convert a ZipEntry to a hash table index, verifying that it's in a\n * valid range.\n */\nstatic int64_t EntryToIndex(const ZipString* hash_table,\n                            const uint32_t hash_table_size,\n                            const ZipString& name) {\n  const uint32_t hash = ComputeHash(name);\n\n  // NOTE: (hash_table_size - 1) is guaranteed to be non-negative.\n  uint32_t ent = hash & (hash_table_size - 1);\n  while (hash_table[ent].name != NULL) {\n    if (hash_table[ent] == name) {\n      return ent;\n    }\n\n    ent = (ent + 1) & (hash_table_size - 1);\n  }\n\n  ALOGV(\"Zip: Unable to find entry %.*s\", name.name_length, name.name);\n  return kEntryNotFound;\n}\n\n/*\n * Add a new entry to the hash table.\n */\nstatic int32_t AddToHash(ZipString *hash_table, const uint64_t hash_table_size,\n                         const ZipString& name) {\n  const uint64_t hash = ComputeHash(name);\n  uint32_t ent = hash & (hash_table_size - 1);\n\n  /*\n   * We over-allocated the table, so we're guaranteed to find an empty slot.\n   * Further, we guarantee that the hashtable size is not 0.\n   */\n  while (hash_table[ent].name != NULL) {\n    if (hash_table[ent] == name) {\n      // We've found a duplicate entry. We don't accept it\n      ALOGW(\"Zip: Found duplicate entry %.*s\", name.name_length, name.name);\n      return kDuplicateEntry;\n    }\n    ent = (ent + 1) & (hash_table_size - 1);\n  }\n\n  hash_table[ent].name = name.name;\n  hash_table[ent].name_length = name.name_length;\n  return 0;\n}\n\nstatic int32_t MapCentralDirectory0(int fd, const char* debug_file_name,\n                                    ZipArchive* archive, off64_t file_length,\n                                    off64_t read_amount, uint8_t* scan_buffer) {\n  const off64_t search_start = file_length - read_amount;\n\n  if (lseek64(fd, search_start, SEEK_SET) != search_start) {\n    ALOGW(\"Zip: seek %\" PRId64 \" failed: %s\", static_cast<int64_t>(search_start),\n          strerror(errno));\n    return kIoError;\n  }\n  if (!android::base::ReadFully(fd, scan_buffer, static_cast<size_t>(read_amount))) {\n    ALOGW(\"Zip: read %\" PRId64 \" failed: %s\", static_cast<int64_t>(read_amount),\n          strerror(errno));\n    return kIoError;\n  }\n\n  /*\n   * Scan backward for the EOCD magic.  In an archive without a trailing\n   * comment, we'll find it on the first try.  (We may want to consider\n   * doing an initial minimal read; if we don't find it, retry with a\n   * second read as above.)\n   */\n  int i = read_amount - sizeof(EocdRecord);\n  for (; i >= 0; i--) {\n    if (scan_buffer[i] == 0x50) {\n      uint32_t* sig_addr = reinterpret_cast<uint32_t*>(&scan_buffer[i]);\n      if (get_unaligned<uint32_t>(sig_addr) == EocdRecord::kSignature) {\n        ALOGV(\"+++ Found EOCD at buf+%d\", i);\n        break;\n      }\n    }\n  }\n  if (i < 0) {\n    ALOGD(\"Zip: EOCD not found, %s is not zip\", debug_file_name);\n    return kInvalidFile;\n  }\n\n  const off64_t eocd_offset = search_start + i;\n  const EocdRecord* eocd = reinterpret_cast<const EocdRecord*>(scan_buffer + i);\n  /*\n   * Verify that there's no trailing space at the end of the central directory\n   * and its comment.\n   */\n  const off64_t calculated_length = eocd_offset + sizeof(EocdRecord)\n      + eocd->comment_length;\n  if (calculated_length != file_length) {\n    ALOGW(\"Zip: %\" PRId64 \" extraneous bytes at the end of the central directory\",\n          static_cast<int64_t>(file_length - calculated_length));\n    return kInvalidFile;\n  }\n\n  /*\n   * Grab the CD offset and size, and the number of entries in the\n   * archive and verify that they look reasonable.\n   */\n  if (eocd->cd_start_offset + eocd->cd_size > eocd_offset) {\n    ALOGW(\"Zip: bad offsets (dir %\" PRIu32 \", size %\" PRIu32 \", eocd %\" PRId64 \")\",\n        eocd->cd_start_offset, eocd->cd_size, static_cast<int64_t>(eocd_offset));\n    return kInvalidOffset;\n  }\n  if (eocd->num_records == 0) {\n    ALOGW(\"Zip: empty archive?\");\n    return kEmptyArchive;\n  }\n\n  ALOGV(\"+++ num_entries=%\" PRIu32 \" dir_size=%\" PRIu32 \" dir_offset=%\" PRIu32,\n        eocd->num_records, eocd->cd_size, eocd->cd_start_offset);\n\n  /*\n   * It all looks good.  Create a mapping for the CD, and set the fields\n   * in archive.\n   */\n  if (!archive->directory_map.create(debug_file_name, fd,\n          static_cast<off64_t>(eocd->cd_start_offset),\n          static_cast<size_t>(eocd->cd_size), true /* read only */) ) {\n    return kMmapFailed;\n  }\n\n  archive->num_entries = eocd->num_records;\n  archive->directory_offset = eocd->cd_start_offset;\n\n  return 0;\n}\n\n/*\n * Find the zip Central Directory and memory-map it.\n *\n * On success, returns 0 after populating fields from the EOCD area:\n *   directory_offset\n *   directory_map\n *   num_entries\n */\nstatic int32_t MapCentralDirectory(int fd, const char* debug_file_name,\n                                   ZipArchive* archive) {\n\n  // Test file length. We use lseek64 to make sure the file\n  // is small enough to be a zip file (Its size must be less than\n  // 0xffffffff bytes).\n  off64_t file_length = lseek64(fd, 0, SEEK_END);\n  if (file_length == -1) {\n    ALOGV(\"Zip: lseek on fd %d failed\", fd);\n    return kInvalidFile;\n  }\n\n  if (file_length > static_cast<off64_t>(0xffffffff)) {\n    ALOGV(\"Zip: zip file too long %\" PRId64, static_cast<int64_t>(file_length));\n    return kInvalidFile;\n  }\n\n  if (file_length < static_cast<off64_t>(sizeof(EocdRecord))) {\n    ALOGV(\"Zip: length %\" PRId64 \" is too small to be zip\", static_cast<int64_t>(file_length));\n    return kInvalidFile;\n  }\n\n  /*\n   * Perform the traditional EOCD snipe hunt.\n   *\n   * We're searching for the End of Central Directory magic number,\n   * which appears at the start of the EOCD block.  It's followed by\n   * 18 bytes of EOCD stuff and up to 64KB of archive comment.  We\n   * need to read the last part of the file into a buffer, dig through\n   * it to find the magic number, parse some values out, and use those\n   * to determine the extent of the CD.\n   *\n   * We start by pulling in the last part of the file.\n   */\n  off64_t read_amount = kMaxEOCDSearch;\n  if (file_length < read_amount) {\n    read_amount = file_length;\n  }\n\n  uint8_t* scan_buffer = reinterpret_cast<uint8_t*>(malloc(read_amount));\n  int32_t result = MapCentralDirectory0(fd, debug_file_name, archive,\n                                        file_length, read_amount, scan_buffer);\n\n  free(scan_buffer);\n  return result;\n}\n\n/*\n * Parses the Zip archive's Central Directory.  Allocates and populates the\n * hash table.\n *\n * Returns 0 on success.\n */\nstatic int32_t ParseZipArchive(ZipArchive* archive) {\n  const uint8_t* const cd_ptr =\n      reinterpret_cast<const uint8_t*>(archive->directory_map.getDataPtr());\n  const size_t cd_length = archive->directory_map.getDataLength();\n  const uint16_t num_entries = archive->num_entries;\n\n  /*\n   * Create hash table.  We have a minimum 75% load factor, possibly as\n   * low as 50% after we round off to a power of 2.  There must be at\n   * least one unused entry to avoid an infinite loop during creation.\n   */\n  archive->hash_table_size = RoundUpPower2(1 + (num_entries * 4) / 3);\n  archive->hash_table = reinterpret_cast<ZipString*>(calloc(archive->hash_table_size,\n      sizeof(ZipString)));\n\n  /*\n   * Walk through the central directory, adding entries to the hash\n   * table and verifying values.\n   */\n  const uint8_t* const cd_end = cd_ptr + cd_length;\n  const uint8_t* ptr = cd_ptr;\n  for (uint16_t i = 0; i < num_entries; i++) {\n    const CentralDirectoryRecord* cdr =\n        reinterpret_cast<const CentralDirectoryRecord*>(ptr);\n    if (cdr->record_signature != CentralDirectoryRecord::kSignature) {\n      ALOGW(\"Zip: missed a central dir sig (at %\" PRIu16 \")\", i);\n      return -1;\n    }\n\n    if (ptr + sizeof(CentralDirectoryRecord) > cd_end) {\n      ALOGW(\"Zip: ran off the end (at %\" PRIu16 \")\", i);\n      return -1;\n    }\n\n    const off64_t local_header_offset = cdr->local_file_header_offset;\n    if (local_header_offset >= archive->directory_offset) {\n      ALOGW(\"Zip: bad LFH offset %\" PRId64 \" at entry %\" PRIu16,\n          static_cast<int64_t>(local_header_offset), i);\n      return -1;\n    }\n\n    const uint16_t file_name_length = cdr->file_name_length;\n    const uint16_t extra_length = cdr->extra_field_length;\n    const uint16_t comment_length = cdr->comment_length;\n    const uint8_t* file_name = ptr + sizeof(CentralDirectoryRecord);\n\n    /* check that file name is valid UTF-8 and doesn't contain NUL (U+0000) characters */\n    if (!IsValidEntryName(file_name, file_name_length)) {\n      return -1;\n    }\n\n    /* add the CDE filename to the hash table */\n    ZipString entry_name;\n    entry_name.name = file_name;\n    entry_name.name_length = file_name_length;\n    const int add_result = AddToHash(archive->hash_table,\n        archive->hash_table_size, entry_name);\n    if (add_result != 0) {\n      ALOGW(\"Zip: Error adding entry to hash table %d\", add_result);\n      return add_result;\n    }\n\n    ptr += sizeof(CentralDirectoryRecord) + file_name_length + extra_length + comment_length;\n    if ((ptr - cd_ptr) > static_cast<int64_t>(cd_length)) {\n      ALOGW(\"Zip: bad CD advance (%tu vs %zu) at entry %\" PRIu16,\n          ptr - cd_ptr, cd_length, i);\n      return -1;\n    }\n  }\n  ALOGV(\"+++ zip good scan %\" PRIu16 \" entries\", num_entries);\n\n  return 0;\n}\n\nstatic int32_t OpenArchiveInternal(ZipArchive* archive,\n                                   const char* debug_file_name) {\n  int32_t result = -1;\n  if ((result = MapCentralDirectory(archive->fd, debug_file_name, archive))) {\n    return result;\n  }\n\n  if ((result = ParseZipArchive(archive))) {\n    return result;\n  }\n\n  return 0;\n}\n\nint32_t OpenArchiveFd(int fd, const char* debug_file_name,\n                      ZipArchiveHandle* handle, bool assume_ownership) {\n  ZipArchive* archive = new ZipArchive(fd, assume_ownership);\n  *handle = archive;\n  return OpenArchiveInternal(archive, debug_file_name);\n}\n\nint32_t OpenArchive(const char* fileName, ZipArchiveHandle* handle) {\n  const int fd = open(fileName, O_RDONLY | O_BINARY, 0);\n  ZipArchive* archive = new ZipArchive(fd, true);\n  *handle = archive;\n\n  if (fd < 0) {\n    ALOGW(\"Unable to open '%s': %s\", fileName, strerror(errno));\n    return kIoError;\n  }\n\n  return OpenArchiveInternal(archive, fileName);\n}\n\n/*\n * Close a ZipArchive, closing the file and freeing the contents.\n */\nvoid CloseArchive(ZipArchiveHandle handle) {\n  ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);\n  ALOGV(\"Closing archive %p\", archive);\n  delete archive;\n}\n\nstatic int32_t UpdateEntryFromDataDescriptor(int fd,\n                                             ZipEntry *entry) {\n  uint8_t ddBuf[sizeof(DataDescriptor) + sizeof(DataDescriptor::kOptSignature)];\n  if (!android::base::ReadFully(fd, ddBuf, sizeof(ddBuf))) {\n    return kIoError;\n  }\n\n  const uint32_t ddSignature = *(reinterpret_cast<const uint32_t*>(ddBuf));\n  const uint16_t offset = (ddSignature == DataDescriptor::kOptSignature) ? 4 : 0;\n  const DataDescriptor* descriptor = reinterpret_cast<const DataDescriptor*>(ddBuf + offset);\n\n  entry->crc32 = descriptor->crc32;\n  entry->compressed_length = descriptor->compressed_size;\n  entry->uncompressed_length = descriptor->uncompressed_size;\n\n  return 0;\n}\n\n// Attempts to read |len| bytes into |buf| at offset |off|.\n// On non-Windows platforms, callers are guaranteed that the |fd|\n// offset is unchanged and there is no side effect to this call.\n//\n// On Windows platforms this is not thread-safe.\nstatic inline bool ReadAtOffset(int fd, uint8_t* buf, size_t len, off64_t off) {\n#if !defined(_WIN32)\n  return TEMP_FAILURE_RETRY(pread64(fd, buf, len, off));\n#else\n  if (lseek64(fd, off, SEEK_SET) != off) {\n    ALOGW(\"Zip: failed seek to offset %\" PRId64, off);\n    return false;\n  }\n  return android::base::ReadFully(fd, buf, len);\n#endif\n}\n\nstatic int32_t FindEntry(const ZipArchive* archive, const int ent,\n                         ZipEntry* data) {\n  const uint16_t nameLen = archive->hash_table[ent].name_length;\n\n  // Recover the start of the central directory entry from the filename\n  // pointer.  The filename is the first entry past the fixed-size data,\n  // so we can just subtract back from that.\n  const uint8_t* ptr = archive->hash_table[ent].name;\n  ptr -= sizeof(CentralDirectoryRecord);\n\n  // This is the base of our mmapped region, we have to sanity check that\n  // the name that's in the hash table is a pointer to a location within\n  // this mapped region.\n  const uint8_t* base_ptr = reinterpret_cast<const uint8_t*>(\n    archive->directory_map.getDataPtr());\n  if (ptr < base_ptr || ptr > base_ptr + archive->directory_map.getDataLength()) {\n    ALOGW(\"Zip: Invalid entry pointer\");\n    return kInvalidOffset;\n  }\n\n  const CentralDirectoryRecord *cdr =\n      reinterpret_cast<const CentralDirectoryRecord*>(ptr);\n\n  // The offset of the start of the central directory in the zipfile.\n  // We keep this lying around so that we can sanity check all our lengths\n  // and our per-file structures.\n  const off64_t cd_offset = archive->directory_offset;\n\n  // Fill out the compression method, modification time, crc32\n  // and other interesting attributes from the central directory. These\n  // will later be compared against values from the local file header.\n  data->method = cdr->compression_method;\n  data->mod_time = cdr->last_mod_date << 16 | cdr->last_mod_time;\n  data->crc32 = cdr->crc32;\n  data->compressed_length = cdr->compressed_size;\n  data->uncompressed_length = cdr->uncompressed_size;\n\n  // Figure out the local header offset from the central directory. The\n  // actual file data will begin after the local header and the name /\n  // extra comments.\n  const off64_t local_header_offset = cdr->local_file_header_offset;\n  if (local_header_offset + static_cast<off64_t>(sizeof(LocalFileHeader)) >= cd_offset) {\n    ALOGW(\"Zip: bad local hdr offset in zip\");\n    return kInvalidOffset;\n  }\n\n  uint8_t lfh_buf[sizeof(LocalFileHeader)];\n  if (!ReadAtOffset(archive->fd, lfh_buf, sizeof(lfh_buf), local_header_offset)) {\n    ALOGW(\"Zip: failed reading lfh name from offset %\" PRId64,\n        static_cast<int64_t>(local_header_offset));\n    return kIoError;\n  }\n\n  const LocalFileHeader *lfh = reinterpret_cast<const LocalFileHeader*>(lfh_buf);\n\n  if (lfh->lfh_signature != LocalFileHeader::kSignature) {\n    ALOGW(\"Zip: didn't find signature at start of lfh, offset=%\" PRId64,\n        static_cast<int64_t>(local_header_offset));\n    return kInvalidOffset;\n  }\n\n  // Paranoia: Match the values specified in the local file header\n  // to those specified in the central directory.\n  if ((lfh->gpb_flags & kGPBDDFlagMask) == 0) {\n    data->has_data_descriptor = 0;\n    if (data->compressed_length != lfh->compressed_size\n        || data->uncompressed_length != lfh->uncompressed_size\n        || data->crc32 != lfh->crc32) {\n      ALOGW(\"Zip: size/crc32 mismatch. expected {%\" PRIu32 \", %\" PRIu32\n        \", %\" PRIx32 \"}, was {%\" PRIu32 \", %\" PRIu32 \", %\" PRIx32 \"}\",\n        data->compressed_length, data->uncompressed_length, data->crc32,\n        lfh->compressed_size, lfh->uncompressed_size, lfh->crc32);\n      return kInconsistentInformation;\n    }\n  } else {\n    data->has_data_descriptor = 1;\n  }\n\n  // Check that the local file header name matches the declared\n  // name in the central directory.\n  if (lfh->file_name_length == nameLen) {\n    const off64_t name_offset = local_header_offset + sizeof(LocalFileHeader);\n    if (name_offset + lfh->file_name_length > cd_offset) {\n      ALOGW(\"Zip: Invalid declared length\");\n      return kInvalidOffset;\n    }\n\n    uint8_t* name_buf = reinterpret_cast<uint8_t*>(malloc(nameLen));\n    if (!ReadAtOffset(archive->fd, name_buf, nameLen, name_offset)) {\n      ALOGW(\"Zip: failed reading lfh name from offset %\" PRId64, static_cast<int64_t>(name_offset));\n      free(name_buf);\n      return kIoError;\n    }\n\n    if (memcmp(archive->hash_table[ent].name, name_buf, nameLen)) {\n      free(name_buf);\n      return kInconsistentInformation;\n    }\n\n    free(name_buf);\n  } else {\n    ALOGW(\"Zip: lfh name did not match central directory.\");\n    return kInconsistentInformation;\n  }\n\n  const off64_t data_offset = local_header_offset + sizeof(LocalFileHeader)\n      + lfh->file_name_length + lfh->extra_field_length;\n  if (data_offset > cd_offset) {\n    ALOGW(\"Zip: bad data offset %\" PRId64 \" in zip\", static_cast<int64_t>(data_offset));\n    return kInvalidOffset;\n  }\n\n  if (static_cast<off64_t>(data_offset + data->compressed_length) > cd_offset) {\n    ALOGW(\"Zip: bad compressed length in zip (%\" PRId64 \" + %\" PRIu32 \" > %\" PRId64 \")\",\n      static_cast<int64_t>(data_offset), data->compressed_length, static_cast<int64_t>(cd_offset));\n    return kInvalidOffset;\n  }\n\n  if (data->method == kCompressStored &&\n    static_cast<off64_t>(data_offset + data->uncompressed_length) > cd_offset) {\n     ALOGW(\"Zip: bad uncompressed length in zip (%\" PRId64 \" + %\" PRIu32 \" > %\" PRId64 \")\",\n       static_cast<int64_t>(data_offset), data->uncompressed_length,\n       static_cast<int64_t>(cd_offset));\n     return kInvalidOffset;\n  }\n\n  data->offset = data_offset;\n  return 0;\n}\n\nstruct IterationHandle {\n  uint32_t position;\n  // We're not using vector here because this code is used in the Windows SDK\n  // where the STL is not available.\n  ZipString prefix;\n  ZipString suffix;\n  ZipArchive* archive;\n\n  IterationHandle(const ZipString* in_prefix,\n                  const ZipString* in_suffix) {\n    if (in_prefix) {\n      uint8_t* name_copy = new uint8_t[in_prefix->name_length];\n      memcpy(name_copy, in_prefix->name, in_prefix->name_length);\n      prefix.name = name_copy;\n      prefix.name_length = in_prefix->name_length;\n    } else {\n      prefix.name = NULL;\n      prefix.name_length = 0;\n    }\n    if (in_suffix) {\n      uint8_t* name_copy = new uint8_t[in_suffix->name_length];\n      memcpy(name_copy, in_suffix->name, in_suffix->name_length);\n      suffix.name = name_copy;\n      suffix.name_length = in_suffix->name_length;\n    } else {\n      suffix.name = NULL;\n      suffix.name_length = 0;\n    }\n  }\n\n  ~IterationHandle() {\n    delete[] prefix.name;\n    delete[] suffix.name;\n  }\n};\n\nint32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr,\n                       const ZipString* optional_prefix,\n                       const ZipString* optional_suffix) {\n  ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);\n\n  if (archive == NULL || archive->hash_table == NULL) {\n    ALOGW(\"Zip: Invalid ZipArchiveHandle\");\n    return kInvalidHandle;\n  }\n\n  IterationHandle* cookie = new IterationHandle(optional_prefix, optional_suffix);\n  cookie->position = 0;\n  cookie->archive = archive;\n\n  *cookie_ptr = cookie ;\n  return 0;\n}\n\nvoid EndIteration(void* cookie) {\n  delete reinterpret_cast<IterationHandle*>(cookie);\n}\n\nint32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName,\n                  ZipEntry* data) {\n  const ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);\n  if (entryName.name_length == 0) {\n    ALOGW(\"Zip: Invalid filename %.*s\", entryName.name_length, entryName.name);\n    return kInvalidEntryName;\n  }\n\n  const int64_t ent = EntryToIndex(archive->hash_table,\n    archive->hash_table_size, entryName);\n\n  if (ent < 0) {\n    ALOGV(\"Zip: Could not find entry %.*s\", entryName.name_length, entryName.name);\n    return ent;\n  }\n\n  return FindEntry(archive, ent, data);\n}\n\nint32_t Next(void* cookie, ZipEntry* data, ZipString* name) {\n  IterationHandle* handle = reinterpret_cast<IterationHandle*>(cookie);\n  if (handle == NULL) {\n    return kInvalidHandle;\n  }\n\n  ZipArchive* archive = handle->archive;\n  if (archive == NULL || archive->hash_table == NULL) {\n    ALOGW(\"Zip: Invalid ZipArchiveHandle\");\n    return kInvalidHandle;\n  }\n\n  const uint32_t currentOffset = handle->position;\n  const uint32_t hash_table_length = archive->hash_table_size;\n  const ZipString* hash_table = archive->hash_table;\n\n  for (uint32_t i = currentOffset; i < hash_table_length; ++i) {\n    if (hash_table[i].name != NULL &&\n        (handle->prefix.name_length == 0 ||\n         hash_table[i].StartsWith(handle->prefix)) &&\n        (handle->suffix.name_length == 0 ||\n         hash_table[i].EndsWith(handle->suffix))) {\n      handle->position = (i + 1);\n      const int error = FindEntry(archive, i, data);\n      if (!error) {\n        name->name = hash_table[i].name;\n        name->name_length = hash_table[i].name_length;\n      }\n\n      return error;\n    }\n  }\n\n  handle->position = 0;\n  return kIterationEnd;\n}\n\nclass Writer {\n public:\n  virtual bool Append(uint8_t* buf, size_t buf_size) = 0;\n  virtual ~Writer() {}\n protected:\n  Writer() = default;\n private:\n  DISALLOW_COPY_AND_ASSIGN(Writer);\n};\n\n// A Writer that writes data to a fixed size memory region.\n// The size of the memory region must be equal to the total size of\n// the data appended to it.\nclass MemoryWriter : public Writer {\n public:\n  MemoryWriter(uint8_t* buf, size_t size) : Writer(),\n      buf_(buf), size_(size), bytes_written_(0) {\n  }\n\n  virtual bool Append(uint8_t* buf, size_t buf_size) override {\n    if (bytes_written_ + buf_size > size_) {\n      ALOGW(\"Zip: Unexpected size \" ZD \" (declared) vs \" ZD \" (actual)\",\n            size_, bytes_written_ + buf_size);\n      return false;\n    }\n\n    memcpy(buf_ + bytes_written_, buf, buf_size);\n    bytes_written_ += buf_size;\n    return true;\n  }\n\n private:\n  uint8_t* const buf_;\n  const size_t size_;\n  size_t bytes_written_;\n};\n\n// A Writer that appends data to a file |fd| at its current position.\n// The file will be truncated to the end of the written data.\nclass FileWriter : public Writer {\n public:\n\n  // Creates a FileWriter for |fd| and prepare to write |entry| to it,\n  // guaranteeing that the file descriptor is valid and that there's enough\n  // space on the volume to write out the entry completely and that the file\n  // is truncated to the correct length.\n  //\n  // Returns a valid FileWriter on success, |nullptr| if an error occurred.\n  static std::unique_ptr<FileWriter> Create(int fd, const ZipEntry* entry) {\n    const uint32_t declared_length = entry->uncompressed_length;\n    const off64_t current_offset = lseek64(fd, 0, SEEK_CUR);\n    if (current_offset == -1) {\n      ALOGW(\"Zip: unable to seek to current location on fd %d: %s\", fd, strerror(errno));\n      return nullptr;\n    }\n\n    int result = 0;\n#if defined(__linux__)\n    if (declared_length > 0) {\n      // Make sure we have enough space on the volume to extract the compressed\n      // entry. Note that the call to ftruncate below will change the file size but\n      // will not allocate space on disk and this call to fallocate will not\n      // change the file size.\n      // Note: fallocate is only supported by the following filesystems -\n      // btrfs, ext4, ocfs2, and xfs. Therefore fallocate might fail with\n      // EOPNOTSUPP error when issued in other filesystems.\n      // Hence, check for the return error code before concluding that the\n      // disk does not have enough space.\n      result = TEMP_FAILURE_RETRY(fallocate(fd, 0, current_offset, declared_length));\n      if (result == -1 && errno == ENOSPC) {\n        ALOGW(\"Zip: unable to allocate space for file to %\" PRId64 \": %s\",\n              static_cast<int64_t>(declared_length + current_offset), strerror(errno));\n        return std::unique_ptr<FileWriter>(nullptr);\n      }\n    }\n#endif  // __linux__\n\n    result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));\n    if (result == -1) {\n      ALOGW(\"Zip: unable to truncate file to %\" PRId64 \": %s\",\n            static_cast<int64_t>(declared_length + current_offset), strerror(errno));\n      return std::unique_ptr<FileWriter>(nullptr);\n    }\n\n    return std::unique_ptr<FileWriter>(new FileWriter(fd, declared_length));\n  }\n\n  virtual bool Append(uint8_t* buf, size_t buf_size) override {\n    if (total_bytes_written_ + buf_size > declared_length_) {\n      ALOGW(\"Zip: Unexpected size \" ZD \" (declared) vs \" ZD \" (actual)\",\n            declared_length_, total_bytes_written_ + buf_size);\n      return false;\n    }\n\n    const bool result = android::base::WriteFully(fd_, buf, buf_size);\n    if (result) {\n      total_bytes_written_ += buf_size;\n    } else {\n      ALOGW(\"Zip: unable to write \" ZD \" bytes to file; %s\", buf_size, strerror(errno));\n    }\n\n    return result;\n  }\n private:\n  FileWriter(const int fd, const size_t declared_length) :\n      Writer(),\n      fd_(fd),\n      declared_length_(declared_length),\n      total_bytes_written_(0) {\n  }\n\n  const int fd_;\n  const size_t declared_length_;\n  size_t total_bytes_written_;\n};\n\n// This method is using libz macros with old-style-casts\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wold-style-cast\"\nstatic inline int zlib_inflateInit2(z_stream* stream, int window_bits) {\n  return inflateInit2(stream, window_bits);\n}\n#pragma GCC diagnostic pop\n\nstatic int32_t InflateEntryToWriter(int fd, const ZipEntry* entry,\n                                    Writer* writer, uint64_t* crc_out) {\n  const size_t kBufSize = 32768;\n  std::vector<uint8_t> read_buf(kBufSize);\n  std::vector<uint8_t> write_buf(kBufSize);\n  z_stream zstream;\n  int zerr;\n\n  /*\n   * Initialize the zlib stream struct.\n   */\n  memset(&zstream, 0, sizeof(zstream));\n  zstream.zalloc = Z_NULL;\n  zstream.zfree = Z_NULL;\n  zstream.opaque = Z_NULL;\n  zstream.next_in = NULL;\n  zstream.avail_in = 0;\n  zstream.next_out = &write_buf[0];\n  zstream.avail_out = kBufSize;\n  zstream.data_type = Z_UNKNOWN;\n\n  /*\n   * Use the undocumented \"negative window bits\" feature to tell zlib\n   * that there's no zlib header waiting for it.\n   */\n  zerr = zlib_inflateInit2(&zstream, -MAX_WBITS);\n  if (zerr != Z_OK) {\n    if (zerr == Z_VERSION_ERROR) {\n      ALOGE(\"Installed zlib is not compatible with linked version (%s)\",\n        ZLIB_VERSION);\n    } else {\n      ALOGW(\"Call to inflateInit2 failed (zerr=%d)\", zerr);\n    }\n\n    return kZlibError;\n  }\n\n  auto zstream_deleter = [](z_stream* stream) {\n    inflateEnd(stream);  /* free up any allocated structures */\n  };\n\n  std::unique_ptr<z_stream, decltype(zstream_deleter)> zstream_guard(&zstream, zstream_deleter);\n\n  const uint32_t uncompressed_length = entry->uncompressed_length;\n\n  uint32_t compressed_length = entry->compressed_length;\n  do {\n    /* read as much as we can */\n    if (zstream.avail_in == 0) {\n      const size_t getSize = (compressed_length > kBufSize) ? kBufSize : compressed_length;\n      if (!android::base::ReadFully(fd, read_buf.data(), getSize)) {\n        ALOGW(\"Zip: inflate read failed, getSize = %zu: %s\", getSize, strerror(errno));\n        return kIoError;\n      }\n\n      compressed_length -= getSize;\n\n      zstream.next_in = &read_buf[0];\n      zstream.avail_in = getSize;\n    }\n\n    /* uncompress the data */\n    zerr = inflate(&zstream, Z_NO_FLUSH);\n    if (zerr != Z_OK && zerr != Z_STREAM_END) {\n      ALOGW(\"Zip: inflate zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\",\n          zerr, zstream.next_in, zstream.avail_in,\n          zstream.next_out, zstream.avail_out);\n      return kZlibError;\n    }\n\n    /* write when we're full or when we're done */\n    if (zstream.avail_out == 0 ||\n      (zerr == Z_STREAM_END && zstream.avail_out != kBufSize)) {\n      const size_t write_size = zstream.next_out - &write_buf[0];\n      if (!writer->Append(&write_buf[0], write_size)) {\n        // The file might have declared a bogus length.\n        return kInconsistentInformation;\n      }\n\n      zstream.next_out = &write_buf[0];\n      zstream.avail_out = kBufSize;\n    }\n  } while (zerr == Z_OK);\n\n  assert(zerr == Z_STREAM_END);     /* other errors should've been caught */\n\n  // stream.adler holds the crc32 value for such streams.\n  *crc_out = zstream.adler;\n\n  if (zstream.total_out != uncompressed_length || compressed_length != 0) {\n    ALOGW(\"Zip: size mismatch on inflated file (%lu vs %\" PRIu32 \")\",\n        zstream.total_out, uncompressed_length);\n    return kInconsistentInformation;\n  }\n\n  return 0;\n}\n\nstatic int32_t CopyEntryToWriter(int fd, const ZipEntry* entry, Writer* writer,\n                                 uint64_t *crc_out) {\n  static const uint32_t kBufSize = 32768;\n  std::vector<uint8_t> buf(kBufSize);\n\n  const uint32_t length = entry->uncompressed_length;\n  uint32_t count = 0;\n  uint64_t crc = 0;\n  while (count < length) {\n    uint32_t remaining = length - count;\n\n    // Safe conversion because kBufSize is narrow enough for a 32 bit signed\n    // value.\n    const size_t block_size = (remaining > kBufSize) ? kBufSize : remaining;\n    if (!android::base::ReadFully(fd, buf.data(), block_size)) {\n      ALOGW(\"CopyFileToFile: copy read failed, block_size = %zu: %s\", block_size, strerror(errno));\n      return kIoError;\n    }\n\n    if (!writer->Append(&buf[0], block_size)) {\n      return kIoError;\n    }\n    crc = crc32(crc, &buf[0], block_size);\n    count += block_size;\n  }\n\n  *crc_out = crc;\n\n  return 0;\n}\n\nint32_t ExtractToWriter(ZipArchiveHandle handle,\n                        ZipEntry* entry, Writer* writer) {\n  ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);\n  const uint16_t method = entry->method;\n  off64_t data_offset = entry->offset;\n\n  if (lseek64(archive->fd, data_offset, SEEK_SET) != data_offset) {\n    ALOGW(\"Zip: lseek to data at %\" PRId64 \" failed\", static_cast<int64_t>(data_offset));\n    return kIoError;\n  }\n\n  // this should default to kUnknownCompressionMethod.\n  int32_t return_value = -1;\n  uint64_t crc = 0;\n  if (method == kCompressStored) {\n    return_value = CopyEntryToWriter(archive->fd, entry, writer, &crc);\n  } else if (method == kCompressDeflated) {\n    return_value = InflateEntryToWriter(archive->fd, entry, writer, &crc);\n  }\n\n  if (!return_value && entry->has_data_descriptor) {\n    return_value = UpdateEntryFromDataDescriptor(archive->fd, entry);\n    if (return_value) {\n      return return_value;\n    }\n  }\n\n  // TODO: Fix this check by passing the right flags to inflate2 so that\n  // it calculates the CRC for us.\n  if (entry->crc32 != crc && false) {\n    ALOGW(\"Zip: crc mismatch: expected %\" PRIu32 \", was %\" PRIu64, entry->crc32, crc);\n    return kInconsistentInformation;\n  }\n\n  return return_value;\n}\n\nint32_t ExtractToMemory(ZipArchiveHandle handle, ZipEntry* entry,\n                        uint8_t* begin, uint32_t size) {\n  std::unique_ptr<Writer> writer(new MemoryWriter(begin, size));\n  return ExtractToWriter(handle, entry, writer.get());\n}\n\nint32_t ExtractEntryToFile(ZipArchiveHandle handle,\n                           ZipEntry* entry, int fd) {\n  std::unique_ptr<Writer> writer(FileWriter::Create(fd, entry));\n  if (writer.get() == nullptr) {\n    return kIoError;\n  }\n\n  return ExtractToWriter(handle, entry, writer.get());\n}\n\nconst char* ErrorCodeString(int32_t error_code) {\n  if (error_code > kErrorMessageLowerBound && error_code < kErrorMessageUpperBound) {\n    return kErrorMessages[error_code * -1];\n  }\n\n  return kErrorMessages[0];\n}\n\nint GetFileDescriptor(const ZipArchiveHandle handle) {\n  return reinterpret_cast<ZipArchive*>(handle)->fd;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libziparchive/zip_archive_common.h",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef LIBZIPARCHIVE_ZIPARCHIVECOMMON_H_\n#define LIBZIPARCHIVE_ZIPARCHIVECOMMON_H_\n\n#include \"android-base/macros.h\"\n\n#include <inttypes.h>\n\n// The \"end of central directory\" (EOCD) record. Each archive\n// contains exactly once such record which appears at the end of\n// the archive. It contains archive wide information like the\n// number of entries in the archive and the offset to the central\n// directory of the offset.\nstruct EocdRecord {\n  static const uint32_t kSignature = 0x06054b50;\n\n  // End of central directory signature, should always be\n  // |kSignature|.\n  uint32_t eocd_signature;\n  // The number of the current \"disk\", i.e, the \"disk\" that this\n  // central directory is on.\n  //\n  // This implementation assumes that each archive spans a single\n  // disk only. i.e, that disk_num == 1.\n  uint16_t disk_num;\n  // The disk where the central directory starts.\n  //\n  // This implementation assumes that each archive spans a single\n  // disk only. i.e, that cd_start_disk == 1.\n  uint16_t cd_start_disk;\n  // The number of central directory records on this disk.\n  //\n  // This implementation assumes that each archive spans a single\n  // disk only. i.e, that num_records_on_disk == num_records.\n  uint16_t num_records_on_disk;\n  // The total number of central directory records.\n  uint16_t num_records;\n  // The size of the central directory (in bytes).\n  uint32_t cd_size;\n  // The offset of the start of the central directory, relative\n  // to the start of the file.\n  uint32_t cd_start_offset;\n  // Length of the central directory comment.\n  uint16_t comment_length;\n private:\n  EocdRecord() = default;\n  DISALLOW_COPY_AND_ASSIGN(EocdRecord);\n} __attribute__((packed));\n\n// A structure representing the fixed length fields for a single\n// record in the central directory of the archive. In addition to\n// the fixed length fields listed here, each central directory\n// record contains a variable length \"file_name\" and \"extra_field\"\n// whose lengths are given by |file_name_length| and |extra_field_length|\n// respectively.\nstruct CentralDirectoryRecord {\n  static const uint32_t kSignature = 0x02014b50;\n\n  // The start of record signature. Must be |kSignature|.\n  uint32_t record_signature;\n  // Tool version. Ignored by this implementation.\n  uint16_t version_made_by;\n  // Tool version. Ignored by this implementation.\n  uint16_t version_needed;\n  // The \"general purpose bit flags\" for this entry. The only\n  // flag value that we currently check for is the \"data descriptor\"\n  // flag.\n  uint16_t gpb_flags;\n  // The compression method for this entry, one of |kCompressStored|\n  // and |kCompressDeflated|.\n  uint16_t compression_method;\n  // The file modification time and date for this entry.\n  uint16_t last_mod_time;\n  uint16_t last_mod_date;\n  // The CRC-32 checksum for this entry.\n  uint32_t crc32;\n  // The compressed size (in bytes) of this entry.\n  uint32_t compressed_size;\n  // The uncompressed size (in bytes) of this entry.\n  uint32_t uncompressed_size;\n  // The length of the entry file name in bytes. The file name\n  // will appear immediately after this record.\n  uint16_t file_name_length;\n  // The length of the extra field info (in bytes). This data\n  // will appear immediately after the entry file name.\n  uint16_t extra_field_length;\n  // The length of the entry comment (in bytes). This data will\n  // appear immediately after the extra field.\n  uint16_t comment_length;\n  // The start disk for this entry. Ignored by this implementation).\n  uint16_t file_start_disk;\n  // File attributes. Ignored by this implementation.\n  uint16_t internal_file_attributes;\n  // File attributes. Ignored by this implementation.\n  uint32_t external_file_attributes;\n  // The offset to the local file header for this entry, from the\n  // beginning of this archive.\n  uint32_t local_file_header_offset;\n private:\n  CentralDirectoryRecord() = default;\n  DISALLOW_COPY_AND_ASSIGN(CentralDirectoryRecord);\n} __attribute__((packed));\n\n// The local file header for a given entry. This duplicates information\n// present in the central directory of the archive. It is an error for\n// the information here to be different from the central directory\n// information for a given entry.\nstruct LocalFileHeader {\n  static const uint32_t kSignature = 0x04034b50;\n\n  // The local file header signature, must be |kSignature|.\n  uint32_t lfh_signature;\n  // Tool version. Ignored by this implementation.\n  uint16_t version_needed;\n  // The \"general purpose bit flags\" for this entry. The only\n  // flag value that we currently check for is the \"data descriptor\"\n  // flag.\n  uint16_t gpb_flags;\n  // The compression method for this entry, one of |kCompressStored|\n  // and |kCompressDeflated|.\n  uint16_t compression_method;\n  // The file modification time and date for this entry.\n  uint16_t last_mod_time;\n  uint16_t last_mod_date;\n  // The CRC-32 checksum for this entry.\n  uint32_t crc32;\n  // The compressed size (in bytes) of this entry.\n  uint32_t compressed_size;\n  // The uncompressed size (in bytes) of this entry.\n  uint32_t uncompressed_size;\n  // The length of the entry file name in bytes. The file name\n  // will appear immediately after this record.\n  uint16_t file_name_length;\n  // The length of the extra field info (in bytes). This data\n  // will appear immediately after the entry file name.\n  uint16_t extra_field_length;\n private:\n  LocalFileHeader() = default;\n  DISALLOW_COPY_AND_ASSIGN(LocalFileHeader);\n} __attribute__((packed));\n\nstruct DataDescriptor {\n  // The *optional* data descriptor start signature.\n  static const uint32_t kOptSignature = 0x08074b50;\n\n  // CRC-32 checksum of the entry.\n  uint32_t crc32;\n  // Compressed size of the entry.\n  uint32_t compressed_size;\n  // Uncompressed size of the entry.\n  uint32_t uncompressed_size;\n private:\n  DataDescriptor() = default;\n  DISALLOW_COPY_AND_ASSIGN(DataDescriptor);\n} __attribute__((packed));\n\n// mask value that signifies that the entry has a DD\nstatic const uint32_t kGPBDDFlagMask = 0x0008;\n\n// The maximum size of a central directory or a file\n// comment in bytes.\nstatic const uint32_t kMaxCommentLen = 65535;\n\n#endif /* LIBZIPARCHIVE_ZIPARCHIVECOMMON_H_ */\n"
  },
  {
    "path": "atlas-aapt/system/core/libziparchive/zip_archive_private.h",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef LIBZIPARCHIVE_ZIPARCHIVE_PRIVATE_H_\n#define LIBZIPARCHIVE_ZIPARCHIVE_PRIVATE_H_\n\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <utils/FileMap.h>\n#include <ziparchive/zip_archive.h>\n\nstruct ZipArchive {\n  // open Zip archive\n  const int fd;\n  const bool close_file;\n\n  // mapped central directory area\n  off64_t directory_offset;\n  android::FileMap directory_map;\n\n  // number of entries in the Zip archive\n  uint16_t num_entries;\n\n  // We know how many entries are in the Zip archive, so we can have a\n  // fixed-size hash table. We define a load factor of 0.75 and over\n  // allocate so the maximum number entries can never be higher than\n  // ((4 * UINT16_MAX) / 3 + 1) which can safely fit into a uint32_t.\n  uint32_t hash_table_size;\n  ZipString* hash_table;\n\n  ZipArchive(const int fd, bool assume_ownership) :\n      fd(fd),\n      close_file(assume_ownership),\n      directory_offset(0),\n      num_entries(0),\n      hash_table_size(0),\n      hash_table(NULL) {}\n\n  ~ZipArchive() {\n    if (close_file && fd >= 0) {\n      close(fd);\n    }\n\n    free(hash_table);\n  }\n};\n\n#endif  // LIBZIPARCHIVE_ZIPARCHIVE_PRIVATE_H_\n"
  },
  {
    "path": "atlas-aapt/system/core/libziparchive/zip_archive_stream_entry.cc",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Read-only stream access to Zip Archive entries.\n#include <errno.h>\n#include <inttypes.h>\n#include <string.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#include <memory>\n#include <vector>\n\n#define LOG_TAG \"ZIPARCHIVE\"\n#include <android-base/file.h>\n#include <log/log.h>\n#include <ziparchive/zip_archive.h>\n#include <ziparchive/zip_archive_stream_entry.h>\n#include <zlib.h>\n\n#include \"zip_archive_private.h\"\n\nstatic constexpr size_t kBufSize = 65535;\n\nbool ZipArchiveStreamEntry::Init(const ZipEntry& entry) {\n  ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle_);\n  off64_t data_offset = entry.offset;\n  if (lseek64(archive->fd, data_offset, SEEK_SET) != data_offset) {\n    ALOGW(\"lseek to data at %\" PRId64 \" failed: %s\", data_offset, strerror(errno));\n    return false;\n  }\n  crc32_ = entry.crc32;\n  return true;\n}\n\nclass ZipArchiveStreamEntryUncompressed : public ZipArchiveStreamEntry {\n public:\n  ZipArchiveStreamEntryUncompressed(ZipArchiveHandle handle) : ZipArchiveStreamEntry(handle) {}\n  virtual ~ZipArchiveStreamEntryUncompressed() {}\n\n  const std::vector<uint8_t>* Read() override;\n\n  bool Verify() override;\n\n protected:\n  bool Init(const ZipEntry& entry) override;\n\n  uint32_t length_;\n\n private:\n  std::vector<uint8_t> data_;\n  uint32_t computed_crc32_;\n};\n\nbool ZipArchiveStreamEntryUncompressed::Init(const ZipEntry& entry) {\n  if (!ZipArchiveStreamEntry::Init(entry)) {\n    return false;\n  }\n\n  length_ = entry.uncompressed_length;\n\n  data_.resize(kBufSize);\n  computed_crc32_ = 0;\n\n  return true;\n}\n\nconst std::vector<uint8_t>* ZipArchiveStreamEntryUncompressed::Read() {\n  if (length_ == 0) {\n    return nullptr;\n  }\n\n  size_t bytes = (length_ > data_.size()) ? data_.size() : length_;\n  ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle_);\n  errno = 0;\n  if (!android::base::ReadFully(archive->fd, data_.data(), bytes)) {\n    if (errno != 0) {\n      ALOGE(\"Error reading from archive fd: %s\", strerror(errno));\n    } else {\n      ALOGE(\"Short read of zip file, possibly corrupted zip?\");\n    }\n    length_ = 0;\n    return nullptr;\n  }\n\n  if (bytes < data_.size()) {\n    data_.resize(bytes);\n  }\n  computed_crc32_ = crc32(computed_crc32_, data_.data(), data_.size());\n  length_ -= bytes;\n  return &data_;\n}\n\nbool ZipArchiveStreamEntryUncompressed::Verify() {\n  return length_ == 0 && crc32_ == computed_crc32_;\n}\n\nclass ZipArchiveStreamEntryCompressed : public ZipArchiveStreamEntry {\n public:\n  ZipArchiveStreamEntryCompressed(ZipArchiveHandle handle) : ZipArchiveStreamEntry(handle) {}\n  virtual ~ZipArchiveStreamEntryCompressed();\n\n  const std::vector<uint8_t>* Read() override;\n\n  bool Verify() override;\n\n protected:\n  bool Init(const ZipEntry& entry) override;\n\n private:\n  bool z_stream_init_ = false;\n  z_stream z_stream_;\n  std::vector<uint8_t> in_;\n  std::vector<uint8_t> out_;\n  uint32_t uncompressed_length_;\n  uint32_t compressed_length_;\n  uint32_t computed_crc32_;\n};\n\n// This method is using libz macros with old-style-casts\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wold-style-cast\"\nstatic inline int zlib_inflateInit2(z_stream* stream, int window_bits) {\n  return inflateInit2(stream, window_bits);\n}\n#pragma GCC diagnostic pop\n\nbool ZipArchiveStreamEntryCompressed::Init(const ZipEntry& entry) {\n  if (!ZipArchiveStreamEntry::Init(entry)) {\n    return false;\n  }\n\n  // Initialize the zlib stream struct.\n  memset(&z_stream_, 0, sizeof(z_stream_));\n  z_stream_.zalloc = Z_NULL;\n  z_stream_.zfree = Z_NULL;\n  z_stream_.opaque = Z_NULL;\n  z_stream_.next_in = nullptr;\n  z_stream_.avail_in = 0;\n  z_stream_.avail_out = 0;\n  z_stream_.data_type = Z_UNKNOWN;\n\n  // Use the undocumented \"negative window bits\" feature to tell zlib\n  // that there's no zlib header waiting for it.\n  int zerr = zlib_inflateInit2(&z_stream_, -MAX_WBITS);\n  if (zerr != Z_OK) {\n    if (zerr == Z_VERSION_ERROR) {\n      ALOGE(\"Installed zlib is not compatible with linked version (%s)\",\n        ZLIB_VERSION);\n    } else {\n      ALOGE(\"Call to inflateInit2 failed (zerr=%d)\", zerr);\n    }\n\n    return false;\n  }\n\n  z_stream_init_ = true;\n\n  uncompressed_length_ = entry.uncompressed_length;\n  compressed_length_ = entry.compressed_length;\n\n  out_.resize(kBufSize);\n  in_.resize(kBufSize);\n\n  computed_crc32_ = 0;\n\n  return true;\n}\n\nZipArchiveStreamEntryCompressed::~ZipArchiveStreamEntryCompressed() {\n  if (z_stream_init_) {\n    inflateEnd(&z_stream_);\n    z_stream_init_ = false;\n  }\n}\n\nbool ZipArchiveStreamEntryCompressed::Verify() {\n  return z_stream_init_ && uncompressed_length_ == 0 && compressed_length_ == 0 &&\n      crc32_ == computed_crc32_;\n}\n\nconst std::vector<uint8_t>* ZipArchiveStreamEntryCompressed::Read() {\n  if (z_stream_.avail_out == 0) {\n    z_stream_.next_out = out_.data();\n    z_stream_.avail_out = out_.size();;\n  }\n\n  while (true) {\n    if (z_stream_.avail_in == 0) {\n      if (compressed_length_ == 0) {\n        return nullptr;\n      }\n      size_t bytes = (compressed_length_ > in_.size()) ? in_.size() : compressed_length_;\n      ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle_);\n      errno = 0;\n      if (!android::base::ReadFully(archive->fd, in_.data(), bytes)) {\n        if (errno != 0) {\n          ALOGE(\"Error reading from archive fd: %s\", strerror(errno));\n        } else {\n          ALOGE(\"Short read of zip file, possibly corrupted zip?\");\n        }\n        return nullptr;\n      }\n\n      compressed_length_ -= bytes;\n      z_stream_.next_in = in_.data();\n      z_stream_.avail_in = bytes;\n    }\n\n    int zerr = inflate(&z_stream_, Z_NO_FLUSH);\n    if (zerr != Z_OK && zerr != Z_STREAM_END) {\n      ALOGE(\"inflate zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\",\n          zerr, z_stream_.next_in, z_stream_.avail_in,\n          z_stream_.next_out, z_stream_.avail_out);\n      return nullptr;\n    }\n\n    if (z_stream_.avail_out == 0) {\n      uncompressed_length_ -= out_.size();\n      computed_crc32_ = crc32(computed_crc32_, out_.data(), out_.size());\n      return &out_;\n    }\n    if (zerr == Z_STREAM_END) {\n      if (z_stream_.avail_out != 0) {\n        // Resize the vector down to the actual size of the data.\n        out_.resize(out_.size() - z_stream_.avail_out);\n        computed_crc32_ = crc32(computed_crc32_, out_.data(), out_.size());\n        uncompressed_length_ -= out_.size();\n        return &out_;\n      }\n      return nullptr;\n    }\n  }\n  return nullptr;\n}\n\nclass ZipArchiveStreamEntryRawCompressed : public ZipArchiveStreamEntryUncompressed {\n public:\n  ZipArchiveStreamEntryRawCompressed(ZipArchiveHandle handle)\n      : ZipArchiveStreamEntryUncompressed(handle) {}\n  virtual ~ZipArchiveStreamEntryRawCompressed() {}\n\n  bool Verify() override;\n\n protected:\n  bool Init(const ZipEntry& entry) override;\n};\n\nbool ZipArchiveStreamEntryRawCompressed::Init(const ZipEntry& entry) {\n  if (!ZipArchiveStreamEntryUncompressed::Init(entry)) {\n    return false;\n  }\n  length_ = entry.compressed_length;\n\n  return true;\n}\n\nbool ZipArchiveStreamEntryRawCompressed::Verify() {\n  return length_ == 0;\n}\n\nZipArchiveStreamEntry* ZipArchiveStreamEntry::Create(\n    ZipArchiveHandle handle, const ZipEntry& entry) {\n  ZipArchiveStreamEntry* stream = nullptr;\n  if (entry.method != kCompressStored) {\n    stream = new ZipArchiveStreamEntryCompressed(handle);\n  } else {\n    stream = new ZipArchiveStreamEntryUncompressed(handle);\n  }\n  if (stream && !stream->Init(entry)) {\n    delete stream;\n    stream = nullptr;\n  }\n\n  return stream;\n}\n\nZipArchiveStreamEntry* ZipArchiveStreamEntry::CreateRaw(\n    ZipArchiveHandle handle, const ZipEntry& entry) {\n  ZipArchiveStreamEntry* stream = nullptr;\n  if (entry.method == kCompressStored) {\n    // Not compressed, don't need to do anything special.\n    stream = new ZipArchiveStreamEntryUncompressed(handle);\n  } else {\n    stream = new ZipArchiveStreamEntryRawCompressed(handle);\n  }\n  if (stream && !stream->Init(entry)) {\n    delete stream;\n    stream = nullptr;\n  }\n  return stream;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libziparchive/zip_archive_test.cc",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <errno.h>\n#include <fcntl.h>\n#include <getopt.h>\n#include <stdio.h>\n#include <string.h>\n#include <unistd.h>\n\n#include <memory>\n#include <vector>\n\n#include <android-base/file.h>\n#include <android-base/test_utils.h>\n#include <gtest/gtest.h>\n#include <ziparchive/zip_archive.h>\n#include <ziparchive/zip_archive_stream_entry.h>\n\nstatic std::string test_data_dir;\n\nstatic const std::string kMissingZip = \"missing.zip\";\nstatic const std::string kValidZip = \"valid.zip\";\nstatic const std::string kLargeZip = \"large.zip\";\nstatic const std::string kBadCrcZip = \"bad_crc.zip\";\n\nstatic const std::vector<uint8_t> kATxtContents {\n  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',\n  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',\n  '\\n'\n};\n\nstatic const std::vector<uint8_t> kATxtContentsCompressed {\n  'K', 'L', 'J', 'N', 'I', 'M', 'K', 207, 'H',\n  132, 210, '\\\\', '\\0'\n};\n\nstatic const std::vector<uint8_t> kBTxtContents {\n  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',\n  '\\n'\n};\n\nstatic const std::string kATxtName(\"a.txt\");\nstatic const std::string kBTxtName(\"b.txt\");\nstatic const std::string kNonexistentTxtName(\"nonexistent.txt\");\nstatic const std::string kEmptyTxtName(\"empty.txt\");\nstatic const std::string kLargeCompressTxtName(\"compress.txt\");\nstatic const std::string kLargeUncompressTxtName(\"uncompress.txt\");\n\nstatic int32_t OpenArchiveWrapper(const std::string& name,\n                                  ZipArchiveHandle* handle) {\n  const std::string abs_path = test_data_dir + \"/\" + name;\n  return OpenArchive(abs_path.c_str(), handle);\n}\n\nstatic void AssertNameEquals(const std::string& name_str,\n                             const ZipString& name) {\n  ASSERT_EQ(name_str.size(), name.name_length);\n  ASSERT_EQ(0, memcmp(name_str.c_str(), name.name, name.name_length));\n}\n\nstatic void SetZipString(ZipString* zip_str, const std::string& str) {\n  zip_str->name = reinterpret_cast<const uint8_t*>(str.c_str());\n  zip_str->name_length = str.size();\n}\n\nTEST(ziparchive, Open) {\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));\n\n  CloseArchive(handle);\n}\n\nTEST(ziparchive, OpenMissing) {\n  ZipArchiveHandle handle;\n  ASSERT_NE(0, OpenArchiveWrapper(kMissingZip, &handle));\n\n  // Confirm the file descriptor is not going to be mistaken for a valid one.\n  ASSERT_EQ(-1, GetFileDescriptor(handle));\n}\n\nTEST(ziparchive, OpenAssumeFdOwnership) {\n  int fd = open((test_data_dir + \"/\" + kValidZip).c_str(), O_RDONLY | O_BINARY);\n  ASSERT_NE(-1, fd);\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveFd(fd, \"OpenWithAssumeFdOwnership\", &handle));\n  CloseArchive(handle);\n  ASSERT_EQ(-1, lseek(fd, 0, SEEK_SET));\n  ASSERT_EQ(EBADF, errno);\n}\n\nTEST(ziparchive, OpenDoNotAssumeFdOwnership) {\n  int fd = open((test_data_dir + \"/\" + kValidZip).c_str(), O_RDONLY | O_BINARY);\n  ASSERT_NE(-1, fd);\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveFd(fd, \"OpenWithAssumeFdOwnership\", &handle, false));\n  CloseArchive(handle);\n  ASSERT_EQ(0, lseek(fd, 0, SEEK_SET));\n  close(fd);\n}\n\nTEST(ziparchive, Iteration) {\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));\n\n  void* iteration_cookie;\n  ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, nullptr, nullptr));\n\n  ZipEntry data;\n  ZipString name;\n\n  // b/c.txt\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"b/c.txt\", name);\n\n  // b/d.txt\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"b/d.txt\", name);\n\n  // a.txt\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"a.txt\", name);\n\n  // b.txt\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"b.txt\", name);\n\n  // b/\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"b/\", name);\n\n  // End of iteration.\n  ASSERT_EQ(-1, Next(iteration_cookie, &data, &name));\n\n  CloseArchive(handle);\n}\n\nTEST(ziparchive, IterationWithPrefix) {\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));\n\n  void* iteration_cookie;\n  ZipString prefix(\"b/\");\n  ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, &prefix, nullptr));\n\n  ZipEntry data;\n  ZipString name;\n\n  // b/c.txt\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"b/c.txt\", name);\n\n  // b/d.txt\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"b/d.txt\", name);\n\n  // b/\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"b/\", name);\n\n  // End of iteration.\n  ASSERT_EQ(-1, Next(iteration_cookie, &data, &name));\n\n  CloseArchive(handle);\n}\n\nTEST(ziparchive, IterationWithSuffix) {\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));\n\n  void* iteration_cookie;\n  ZipString suffix(\".txt\");\n  ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, nullptr, &suffix));\n\n  ZipEntry data;\n  ZipString name;\n\n  // b/c.txt\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"b/c.txt\", name);\n\n  // b/d.txt\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"b/d.txt\", name);\n\n  // a.txt\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"a.txt\", name);\n\n  // b.txt\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"b.txt\", name);\n\n  // End of iteration.\n  ASSERT_EQ(-1, Next(iteration_cookie, &data, &name));\n\n  CloseArchive(handle);\n}\n\nTEST(ziparchive, IterationWithPrefixAndSuffix) {\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));\n\n  void* iteration_cookie;\n  ZipString prefix(\"b\");\n  ZipString suffix(\".txt\");\n  ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, &prefix, &suffix));\n\n  ZipEntry data;\n  ZipString name;\n\n  // b/c.txt\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"b/c.txt\", name);\n\n  // b/d.txt\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"b/d.txt\", name);\n\n  // b.txt\n  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));\n  AssertNameEquals(\"b.txt\", name);\n\n  // End of iteration.\n  ASSERT_EQ(-1, Next(iteration_cookie, &data, &name));\n\n  CloseArchive(handle);\n}\n\nTEST(ziparchive, IterationWithBadPrefixAndSuffix) {\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));\n\n  void* iteration_cookie;\n  ZipString prefix(\"x\");\n  ZipString suffix(\"y\");\n  ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, &prefix, &suffix));\n\n  ZipEntry data;\n  ZipString name;\n\n  // End of iteration.\n  ASSERT_EQ(-1, Next(iteration_cookie, &data, &name));\n\n  CloseArchive(handle);\n}\n\nTEST(ziparchive, FindEntry) {\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));\n\n  ZipEntry data;\n  ZipString name;\n  SetZipString(&name, kATxtName);\n  ASSERT_EQ(0, FindEntry(handle, name, &data));\n\n  // Known facts about a.txt, from zipinfo -v.\n  ASSERT_EQ(63, data.offset);\n  ASSERT_EQ(kCompressDeflated, data.method);\n  ASSERT_EQ(static_cast<uint32_t>(17), data.uncompressed_length);\n  ASSERT_EQ(static_cast<uint32_t>(13), data.compressed_length);\n  ASSERT_EQ(0x950821c5, data.crc32);\n  ASSERT_EQ(static_cast<uint32_t>(0x438a8005), data.mod_time);\n\n  // An entry that doesn't exist. Should be a negative return code.\n  ZipString absent_name;\n  SetZipString(&absent_name, kNonexistentTxtName);\n  ASSERT_LT(FindEntry(handle, absent_name, &data), 0);\n\n  CloseArchive(handle);\n}\n\nTEST(ziparchive, TestInvalidDeclaredLength) {\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveWrapper(\"declaredlength.zip\", &handle));\n\n  void* iteration_cookie;\n  ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, nullptr, nullptr));\n\n  ZipString name;\n  ZipEntry data;\n\n  ASSERT_EQ(Next(iteration_cookie, &data, &name), 0);\n  ASSERT_EQ(Next(iteration_cookie, &data, &name), 0);\n\n  CloseArchive(handle);\n}\n\nTEST(ziparchive, ExtractToMemory) {\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));\n\n  // An entry that's deflated.\n  ZipEntry data;\n  ZipString a_name;\n  SetZipString(&a_name, kATxtName);\n  ASSERT_EQ(0, FindEntry(handle, a_name, &data));\n  const uint32_t a_size = data.uncompressed_length;\n  ASSERT_EQ(a_size, kATxtContents.size());\n  uint8_t* buffer = new uint8_t[a_size];\n  ASSERT_EQ(0, ExtractToMemory(handle, &data, buffer, a_size));\n  ASSERT_EQ(0, memcmp(buffer, kATxtContents.data(), a_size));\n  delete[] buffer;\n\n  // An entry that's stored.\n  ZipString b_name;\n  SetZipString(&b_name, kBTxtName);\n  ASSERT_EQ(0, FindEntry(handle, b_name, &data));\n  const uint32_t b_size = data.uncompressed_length;\n  ASSERT_EQ(b_size, kBTxtContents.size());\n  buffer = new uint8_t[b_size];\n  ASSERT_EQ(0, ExtractToMemory(handle, &data, buffer, b_size));\n  ASSERT_EQ(0, memcmp(buffer, kBTxtContents.data(), b_size));\n  delete[] buffer;\n\n  CloseArchive(handle);\n}\n\nstatic const uint32_t kEmptyEntriesZip[] = {\n      0x04034b50, 0x0000000a, 0x63600000, 0x00004438, 0x00000000, 0x00000000,\n      0x00090000, 0x6d65001c, 0x2e797470, 0x55747874, 0x03000954, 0x52e25c13,\n      0x52e25c24, 0x000b7875, 0x42890401, 0x88040000, 0x50000013, 0x1e02014b,\n      0x00000a03, 0x60000000, 0x00443863, 0x00000000, 0x00000000, 0x09000000,\n      0x00001800, 0x00000000, 0xa0000000, 0x00000081, 0x706d6500, 0x742e7974,\n      0x54557478, 0x13030005, 0x7552e25c, 0x01000b78, 0x00428904, 0x13880400,\n      0x4b500000, 0x00000605, 0x00010000, 0x004f0001, 0x00430000, 0x00000000 };\n\n// This is a zip file containing a single entry (ab.txt) that contains\n// 90072 repetitions of the string \"ab\\n\" and has an uncompressed length\n// of 270216 bytes.\nstatic const uint16_t kAbZip[] = {\n  0x4b50, 0x0403, 0x0014, 0x0000, 0x0008, 0x51d2, 0x4698, 0xc4b0,\n  0x2cda, 0x011b, 0x0000, 0x1f88, 0x0004, 0x0006, 0x001c, 0x6261,\n  0x742e, 0x7478, 0x5455, 0x0009, 0x7c03, 0x3a09, 0x7c55, 0x3a09,\n  0x7555, 0x0b78, 0x0100, 0x8904, 0x0042, 0x0400, 0x1388, 0x0000,\n  0xc2ed, 0x0d31, 0x0000, 0x030c, 0x7fa0, 0x3b2e, 0x22ff, 0xa2aa,\n  0x841f, 0x45fc, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,\n  0x5555, 0x5555, 0x5555, 0x5555, 0xdd55, 0x502c, 0x014b, 0x1e02,\n  0x1403, 0x0000, 0x0800, 0xd200, 0x9851, 0xb046, 0xdac4, 0x1b2c,\n  0x0001, 0x8800, 0x041f, 0x0600, 0x1800, 0x0000, 0x0000, 0x0100,\n  0x0000, 0xa000, 0x0081, 0x0000, 0x6100, 0x2e62, 0x7874, 0x5574,\n  0x0554, 0x0300, 0x097c, 0x553a, 0x7875, 0x000b, 0x0401, 0x4289,\n  0x0000, 0x8804, 0x0013, 0x5000, 0x054b, 0x0006, 0x0000, 0x0100,\n  0x0100, 0x4c00, 0x0000, 0x5b00, 0x0001, 0x0000, 0x0000\n};\n\nstatic const std::string kAbTxtName(\"ab.txt\");\nstatic const size_t kAbUncompressedSize = 270216;\n\nTEST(ziparchive, EmptyEntries) {\n  TemporaryFile tmp_file;\n  ASSERT_NE(-1, tmp_file.fd);\n  ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, kEmptyEntriesZip, sizeof(kEmptyEntriesZip)));\n\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveFd(tmp_file.fd, \"EmptyEntriesTest\", &handle));\n\n  ZipEntry entry;\n  ZipString empty_name;\n  SetZipString(&empty_name, kEmptyTxtName);\n  ASSERT_EQ(0, FindEntry(handle, empty_name, &entry));\n  ASSERT_EQ(static_cast<uint32_t>(0), entry.uncompressed_length);\n  uint8_t buffer[1];\n  ASSERT_EQ(0, ExtractToMemory(handle, &entry, buffer, 1));\n\n\n  TemporaryFile tmp_output_file;\n  ASSERT_NE(-1, tmp_output_file.fd);\n  ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, tmp_output_file.fd));\n\n  struct stat stat_buf;\n  ASSERT_EQ(0, fstat(tmp_output_file.fd, &stat_buf));\n  ASSERT_EQ(0, stat_buf.st_size);\n}\n\nTEST(ziparchive, EntryLargerThan32K) {\n  TemporaryFile tmp_file;\n  ASSERT_NE(-1, tmp_file.fd);\n  ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, reinterpret_cast<const uint8_t*>(kAbZip),\n                         sizeof(kAbZip) - 1));\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveFd(tmp_file.fd, \"EntryLargerThan32KTest\", &handle));\n\n  ZipEntry entry;\n  ZipString ab_name;\n  SetZipString(&ab_name, kAbTxtName);\n  ASSERT_EQ(0, FindEntry(handle, ab_name, &entry));\n  ASSERT_EQ(kAbUncompressedSize, entry.uncompressed_length);\n\n  // Extract the entry to memory.\n  std::vector<uint8_t> buffer(kAbUncompressedSize);\n  ASSERT_EQ(0, ExtractToMemory(handle, &entry, &buffer[0], buffer.size()));\n\n  // Extract the entry to a file.\n  TemporaryFile tmp_output_file;\n  ASSERT_NE(-1, tmp_output_file.fd);\n  ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, tmp_output_file.fd));\n\n  // Make sure the extracted file size is as expected.\n  struct stat stat_buf;\n  ASSERT_EQ(0, fstat(tmp_output_file.fd, &stat_buf));\n  ASSERT_EQ(kAbUncompressedSize, static_cast<size_t>(stat_buf.st_size));\n\n  // Read the file back to a buffer and make sure the contents are\n  // the same as the memory buffer we extracted directly to.\n  std::vector<uint8_t> file_contents(kAbUncompressedSize);\n  ASSERT_EQ(0, lseek64(tmp_output_file.fd, 0, SEEK_SET));\n  ASSERT_TRUE(android::base::ReadFully(tmp_output_file.fd, &file_contents[0],\n                                       file_contents.size()));\n  ASSERT_EQ(file_contents, buffer);\n\n  for (int i = 0; i < 90072; ++i) {\n    const uint8_t* line = &file_contents[0] + (3 * i);\n    ASSERT_EQ('a', line[0]);\n    ASSERT_EQ('b', line[1]);\n    ASSERT_EQ('\\n', line[2]);\n  }\n}\n\nTEST(ziparchive, TrailerAfterEOCD) {\n  TemporaryFile tmp_file;\n  ASSERT_NE(-1, tmp_file.fd);\n\n  // Create a file with 8 bytes of random garbage.\n  static const uint8_t trailer[] = { 'A' ,'n', 'd', 'r', 'o', 'i', 'd', 'z' };\n  ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, kEmptyEntriesZip, sizeof(kEmptyEntriesZip)));\n  ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, trailer, sizeof(trailer)));\n\n  ZipArchiveHandle handle;\n  ASSERT_GT(0, OpenArchiveFd(tmp_file.fd, \"EmptyEntriesTest\", &handle));\n}\n\nTEST(ziparchive, ExtractToFile) {\n  TemporaryFile tmp_file;\n  ASSERT_NE(-1, tmp_file.fd);\n  const uint8_t data[8] = { '1', '2', '3', '4', '5', '6', '7', '8' };\n  const size_t data_size = sizeof(data);\n\n  ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, data, data_size));\n\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));\n\n  ZipEntry entry;\n  ZipString name;\n  SetZipString(&name, kATxtName);\n  ASSERT_EQ(0, FindEntry(handle, name, &entry));\n  ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, tmp_file.fd));\n\n\n  // Assert that the first 8 bytes of the file haven't been clobbered.\n  uint8_t read_buffer[data_size];\n  ASSERT_EQ(0, lseek64(tmp_file.fd, 0, SEEK_SET));\n  ASSERT_TRUE(android::base::ReadFully(tmp_file.fd, read_buffer, data_size));\n  ASSERT_EQ(0, memcmp(read_buffer, data, data_size));\n\n  // Assert that the remainder of the file contains the incompressed data.\n  std::vector<uint8_t> uncompressed_data(entry.uncompressed_length);\n  ASSERT_TRUE(android::base::ReadFully(tmp_file.fd, uncompressed_data.data(),\n                                       entry.uncompressed_length));\n  ASSERT_EQ(0, memcmp(&uncompressed_data[0], kATxtContents.data(),\n                      kATxtContents.size()));\n\n  // Assert that the total length of the file is sane\n  ASSERT_EQ(static_cast<ssize_t>(data_size + kATxtContents.size()),\n            lseek64(tmp_file.fd, 0, SEEK_END));\n}\n\nstatic void ZipArchiveStreamTest(\n    ZipArchiveHandle& handle, const std::string& entry_name, bool raw,\n    bool verified, ZipEntry* entry, std::vector<uint8_t>* read_data) {\n  ZipString name;\n  SetZipString(&name, entry_name);\n  ASSERT_EQ(0, FindEntry(handle, name, entry));\n  std::unique_ptr<ZipArchiveStreamEntry> stream;\n  if (raw) {\n    stream.reset(ZipArchiveStreamEntry::CreateRaw(handle, *entry));\n    if (entry->method == kCompressStored) {\n      read_data->resize(entry->uncompressed_length);\n    } else {\n      read_data->resize(entry->compressed_length);\n    }\n  } else {\n    stream.reset(ZipArchiveStreamEntry::Create(handle, *entry));\n    read_data->resize(entry->uncompressed_length);\n  }\n  uint8_t* read_data_ptr = read_data->data();\n  ASSERT_TRUE(stream.get() != nullptr);\n  const std::vector<uint8_t>* data;\n  uint64_t total_size = 0;\n  while ((data = stream->Read()) != nullptr) {\n    total_size += data->size();\n    memcpy(read_data_ptr, data->data(), data->size());\n    read_data_ptr += data->size();\n  }\n  ASSERT_EQ(verified, stream->Verify());\n  ASSERT_EQ(total_size, read_data->size());\n}\n\nstatic void ZipArchiveStreamTestUsingContents(\n    const std::string& zip_file, const std::string& entry_name,\n    const std::vector<uint8_t>& contents, bool raw) {\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveWrapper(zip_file, &handle));\n\n  ZipEntry entry;\n  std::vector<uint8_t> read_data;\n  ZipArchiveStreamTest(handle, entry_name, raw, true, &entry, &read_data);\n\n  ASSERT_EQ(contents.size(), read_data.size());\n  ASSERT_TRUE(memcmp(read_data.data(), contents.data(), read_data.size()) == 0);\n\n  CloseArchive(handle);\n}\n\nstatic void ZipArchiveStreamTestUsingMemory(const std::string& zip_file, const std::string& entry_name) {\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveWrapper(zip_file, &handle));\n\n  ZipEntry entry;\n  std::vector<uint8_t> read_data;\n  ZipArchiveStreamTest(handle, entry_name, false, true, &entry, &read_data);\n\n  std::vector<uint8_t> cmp_data(entry.uncompressed_length);\n  ASSERT_EQ(entry.uncompressed_length, read_data.size());\n  ASSERT_EQ(0, ExtractToMemory(handle, &entry, cmp_data.data(), cmp_data.size()));\n  ASSERT_TRUE(memcmp(read_data.data(), cmp_data.data(), read_data.size()) == 0);\n\n  CloseArchive(handle);\n}\n\nTEST(ziparchive, StreamCompressed) {\n  ZipArchiveStreamTestUsingContents(kValidZip, kATxtName, kATxtContents, false);\n}\n\nTEST(ziparchive, StreamUncompressed) {\n  ZipArchiveStreamTestUsingContents(kValidZip, kBTxtName, kBTxtContents, false);\n}\n\nTEST(ziparchive, StreamRawCompressed) {\n  ZipArchiveStreamTestUsingContents(kValidZip, kATxtName, kATxtContentsCompressed, true);\n}\n\nTEST(ziparchive, StreamRawUncompressed) {\n  ZipArchiveStreamTestUsingContents(kValidZip, kBTxtName, kBTxtContents, true);\n}\n\nTEST(ziparchive, StreamLargeCompressed) {\n  ZipArchiveStreamTestUsingMemory(kLargeZip, kLargeCompressTxtName);\n}\n\nTEST(ziparchive, StreamLargeUncompressed) {\n  ZipArchiveStreamTestUsingMemory(kLargeZip, kLargeUncompressTxtName);\n}\n\nTEST(ziparchive, StreamCompressedBadCrc) {\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveWrapper(kBadCrcZip, &handle));\n\n  ZipEntry entry;\n  std::vector<uint8_t> read_data;\n  ZipArchiveStreamTest(handle, kATxtName, false, false, &entry, &read_data);\n\n  CloseArchive(handle);\n}\n\nTEST(ziparchive, StreamUncompressedBadCrc) {\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveWrapper(kBadCrcZip, &handle));\n\n  ZipEntry entry;\n  std::vector<uint8_t> read_data;\n  ZipArchiveStreamTest(handle, kBTxtName, false, false, &entry, &read_data);\n\n  CloseArchive(handle);\n}\n\nint main(int argc, char** argv) {\n  ::testing::InitGoogleTest(&argc, argv);\n\n  static struct option options[] = {\n    { \"test_data_dir\", required_argument, nullptr, 't' },\n    { nullptr, 0, nullptr, 0 }\n  };\n\n  while (true) {\n    int option_index;\n    const int c = getopt_long_only(argc, argv, \"\", options, &option_index);\n    if (c == -1) {\n      break;\n    }\n\n    if (c == 't') {\n      test_data_dir = optarg;\n    }\n  }\n\n  if (test_data_dir.size() == 0) {\n    printf(\"Test data flag (--test_data_dir) required\\n\\n\");\n    return -1;\n  }\n\n  if (test_data_dir[0] != '/') {\n    std::vector<char> cwd_buffer(1024);\n    const char* cwd = getcwd(cwd_buffer.data(), cwd_buffer.size() - 1);\n    if (cwd == nullptr) {\n      printf(\"Cannot get current working directory, use an absolute path instead, was %s\\n\\n\",\n             test_data_dir.c_str());\n      return -2;\n    }\n    test_data_dir = '/' + test_data_dir;\n    test_data_dir = cwd + test_data_dir;\n  }\n\n  return RUN_ALL_TESTS();\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libziparchive/zip_writer.cc",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"entry_name_utils-inl.h\"\n#include \"zip_archive_common.h\"\n#include \"ziparchive/zip_writer.h\"\n\n#include <utils/Log.h>\n\n#include <sys/param.h>\n\n#include <cassert>\n#include <cstdio>\n#include <memory>\n#include <vector>\n#include <zlib.h>\n#define DEF_MEM_LEVEL 8                // normally in zutil.h?\n\n#if !defined(powerof2)\n#define powerof2(x) ((((x)-1)&(x))==0)\n#endif\n\n/* Zip compression methods we support */\nenum {\n  kCompressStored     = 0,        // no compression\n  kCompressDeflated   = 8,        // standard deflate\n};\n\n// Size of the output buffer used for compression.\nstatic const size_t kBufSize = 32768u;\n\n// No error, operation completed successfully.\nstatic const int32_t kNoError = 0;\n\n// The ZipWriter is in a bad state.\nstatic const int32_t kInvalidState = -1;\n\n// There was an IO error while writing to disk.\nstatic const int32_t kIoError = -2;\n\n// The zip entry name was invalid.\nstatic const int32_t kInvalidEntryName = -3;\n\n// An error occurred in zlib.\nstatic const int32_t kZlibError = -4;\n\n// The start aligned function was called with the aligned flag.\nstatic const int32_t kInvalidAlign32Flag = -5;\n\n// The alignment parameter is not a power of 2.\nstatic const int32_t kInvalidAlignment = -6;\n\nstatic const char* sErrorCodes[] = {\n    \"Invalid state\",\n    \"IO error\",\n    \"Invalid entry name\",\n    \"Zlib error\",\n};\n\nconst char* ZipWriter::ErrorCodeString(int32_t error_code) {\n  if (error_code < 0 && (-error_code) < static_cast<int32_t>(arraysize(sErrorCodes))) {\n    return sErrorCodes[-error_code];\n  }\n  return nullptr;\n}\n\nstatic void DeleteZStream(z_stream* stream) {\n  deflateEnd(stream);\n  delete stream;\n}\n\nZipWriter::ZipWriter(FILE* f) : file_(f), current_offset_(0), state_(State::kWritingZip),\n                                z_stream_(nullptr, DeleteZStream), buffer_(kBufSize) {\n}\n\nZipWriter::ZipWriter(ZipWriter&& writer) : file_(writer.file_),\n                                           current_offset_(writer.current_offset_),\n                                           state_(writer.state_),\n                                           files_(std::move(writer.files_)),\n                                           z_stream_(std::move(writer.z_stream_)),\n                                           buffer_(std::move(writer.buffer_)){\n  writer.file_ = nullptr;\n  writer.state_ = State::kError;\n}\n\nZipWriter& ZipWriter::operator=(ZipWriter&& writer) {\n  file_ = writer.file_;\n  current_offset_ = writer.current_offset_;\n  state_ = writer.state_;\n  files_ = std::move(writer.files_);\n  z_stream_ = std::move(writer.z_stream_);\n  buffer_ = std::move(writer.buffer_);\n  writer.file_ = nullptr;\n  writer.state_ = State::kError;\n  return *this;\n}\n\nint32_t ZipWriter::HandleError(int32_t error_code) {\n  state_ = State::kError;\n  z_stream_.reset();\n  return error_code;\n}\n\nint32_t ZipWriter::StartEntry(const char* path, size_t flags) {\n  uint32_t alignment = 0;\n  if (flags & kAlign32) {\n    flags &= ~kAlign32;\n    alignment = 4;\n  }\n  return StartAlignedEntryWithTime(path, flags, time_t(), alignment);\n}\n\nint32_t ZipWriter::StartAlignedEntry(const char* path, size_t flags, uint32_t alignment) {\n  return StartAlignedEntryWithTime(path, flags, time_t(), alignment);\n}\n\nint32_t ZipWriter::StartEntryWithTime(const char* path, size_t flags, time_t time) {\n  uint32_t alignment = 0;\n  if (flags & kAlign32) {\n    flags &= ~kAlign32;\n    alignment = 4;\n  }\n  return StartAlignedEntryWithTime(path, flags, time, alignment);\n}\n\nstatic void ExtractTimeAndDate(time_t when, uint16_t* out_time, uint16_t* out_date) {\n  /* round up to an even number of seconds */\n  when = static_cast<time_t>((static_cast<unsigned long>(when) + 1) & (~1));\n\n  struct tm* ptm;\n#if !defined(_WIN32)\n    struct tm tm_result;\n    ptm = localtime_r(&when, &tm_result);\n#else\n    ptm = localtime(&when);\n#endif\n\n  int year = ptm->tm_year;\n  if (year < 80) {\n    year = 80;\n  }\n\n  *out_date = (year - 80) << 9 | (ptm->tm_mon + 1) << 5 | ptm->tm_mday;\n  *out_time = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;\n}\n\nint32_t ZipWriter::StartAlignedEntryWithTime(const char* path, size_t flags,\n                                             time_t time, uint32_t alignment) {\n  if (state_ != State::kWritingZip) {\n    return kInvalidState;\n  }\n\n  if (flags & kAlign32) {\n    return kInvalidAlign32Flag;\n  }\n\n  if (powerof2(alignment) == 0) {\n    return kInvalidAlignment;\n  }\n\n  FileInfo fileInfo = {};\n  fileInfo.path = std::string(path);\n  fileInfo.local_file_header_offset = current_offset_;\n\n  if (!IsValidEntryName(reinterpret_cast<const uint8_t*>(fileInfo.path.data()),\n                       fileInfo.path.size())) {\n    return kInvalidEntryName;\n  }\n\n  LocalFileHeader header = {};\n  header.lfh_signature = LocalFileHeader::kSignature;\n\n  // Set this flag to denote that a DataDescriptor struct will appear after the data,\n  // containing the crc and size fields.\n  header.gpb_flags |= kGPBDDFlagMask;\n\n  if (flags & ZipWriter::kCompress) {\n    fileInfo.compression_method = kCompressDeflated;\n\n    int32_t result = PrepareDeflate();\n    if (result != kNoError) {\n      return result;\n    }\n  } else {\n    fileInfo.compression_method = kCompressStored;\n  }\n  header.compression_method = fileInfo.compression_method;\n\n  ExtractTimeAndDate(time, &fileInfo.last_mod_time, &fileInfo.last_mod_date);\n  header.last_mod_time = fileInfo.last_mod_time;\n  header.last_mod_date = fileInfo.last_mod_date;\n\n  header.file_name_length = fileInfo.path.size();\n\n  off64_t offset = current_offset_ + sizeof(header) + fileInfo.path.size();\n  std::vector<char> zero_padding;\n  if (alignment != 0 && (offset & (alignment - 1))) {\n    // Pad the extra field so the data will be aligned.\n    uint16_t padding = alignment - (offset % alignment);\n    header.extra_field_length = padding;\n    offset += padding;\n    zero_padding.resize(padding);\n    memset(zero_padding.data(), 0, zero_padding.size());\n  }\n\n  if (fwrite(&header, sizeof(header), 1, file_) != 1) {\n    return HandleError(kIoError);\n  }\n\n  if (fwrite(path, sizeof(*path), fileInfo.path.size(), file_) != fileInfo.path.size()) {\n    return HandleError(kIoError);\n  }\n\n  if (header.extra_field_length != 0 &&\n      fwrite(zero_padding.data(), 1, header.extra_field_length, file_)\n      != header.extra_field_length) {\n    return HandleError(kIoError);\n  }\n\n  files_.emplace_back(std::move(fileInfo));\n\n  current_offset_ = offset;\n  state_ = State::kWritingEntry;\n  return kNoError;\n}\n\nint32_t ZipWriter::PrepareDeflate() {\n  assert(state_ == State::kWritingZip);\n\n  // Initialize the z_stream for compression.\n  z_stream_ = std::unique_ptr<z_stream, void(*)(z_stream*)>(new z_stream(), DeleteZStream);\n\n  int zerr = deflateInit2(z_stream_.get(), Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS,\n                          DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);\n  if (zerr != Z_OK) {\n    if (zerr == Z_VERSION_ERROR) {\n      ALOGE(\"Installed zlib is not compatible with linked version (%s)\", ZLIB_VERSION);\n      return HandleError(kZlibError);\n    } else {\n      ALOGE(\"deflateInit2 failed (zerr=%d)\", zerr);\n      return HandleError(kZlibError);\n    }\n  }\n\n  z_stream_->next_out = buffer_.data();\n  z_stream_->avail_out = buffer_.size();\n  return kNoError;\n}\n\nint32_t ZipWriter::WriteBytes(const void* data, size_t len) {\n  if (state_ != State::kWritingEntry) {\n    return HandleError(kInvalidState);\n  }\n\n  FileInfo& currentFile = files_.back();\n  int32_t result = kNoError;\n  if (currentFile.compression_method & kCompressDeflated) {\n    result = CompressBytes(&currentFile, data, len);\n  } else {\n    result = StoreBytes(&currentFile, data, len);\n  }\n\n  if (result != kNoError) {\n    return result;\n  }\n\n  currentFile.crc32 = crc32(currentFile.crc32, reinterpret_cast<const Bytef*>(data), len);\n  currentFile.uncompressed_size += len;\n  return kNoError;\n}\n\nint32_t ZipWriter::StoreBytes(FileInfo* file, const void* data, size_t len) {\n  assert(state_ == State::kWritingEntry);\n\n  if (fwrite(data, 1, len, file_) != len) {\n    return HandleError(kIoError);\n  }\n  file->compressed_size += len;\n  current_offset_ += len;\n  return kNoError;\n}\n\nint32_t ZipWriter::CompressBytes(FileInfo* file, const void* data, size_t len) {\n  assert(state_ == State::kWritingEntry);\n  assert(z_stream_);\n  assert(z_stream_->next_out != nullptr);\n  assert(z_stream_->avail_out != 0);\n\n  // Prepare the input.\n  z_stream_->next_in = reinterpret_cast<const uint8_t*>(data);\n  z_stream_->avail_in = len;\n\n  while (z_stream_->avail_in > 0) {\n    // We have more data to compress.\n    int zerr = deflate(z_stream_.get(), Z_NO_FLUSH);\n    if (zerr != Z_OK) {\n      return HandleError(kZlibError);\n    }\n\n    if (z_stream_->avail_out == 0) {\n      // The output is full, let's write it to disk.\n      size_t write_bytes = z_stream_->next_out - buffer_.data();\n      if (fwrite(buffer_.data(), 1, write_bytes, file_) != write_bytes) {\n        return HandleError(kIoError);\n      }\n      file->compressed_size += write_bytes;\n      current_offset_ += write_bytes;\n\n      // Reset the output buffer for the next input.\n      z_stream_->next_out = buffer_.data();\n      z_stream_->avail_out = buffer_.size();\n    }\n  }\n  return kNoError;\n}\n\nint32_t ZipWriter::FlushCompressedBytes(FileInfo* file) {\n  assert(state_ == State::kWritingEntry);\n  assert(z_stream_);\n  assert(z_stream_->next_out != nullptr);\n  assert(z_stream_->avail_out != 0);\n\n  // Keep deflating while there isn't enough space in the buffer to\n  // to complete the compress.\n  int zerr;\n  while ((zerr = deflate(z_stream_.get(), Z_FINISH)) == Z_OK) {\n    assert(z_stream_->avail_out == 0);\n    size_t write_bytes = z_stream_->next_out - buffer_.data();\n    if (fwrite(buffer_.data(), 1, write_bytes, file_) != write_bytes) {\n      return HandleError(kIoError);\n    }\n    file->compressed_size += write_bytes;\n    current_offset_ += write_bytes;\n\n    z_stream_->next_out = buffer_.data();\n    z_stream_->avail_out = buffer_.size();\n  }\n  if (zerr != Z_STREAM_END) {\n    return HandleError(kZlibError);\n  }\n\n  size_t write_bytes = z_stream_->next_out - buffer_.data();\n  if (write_bytes != 0) {\n    if (fwrite(buffer_.data(), 1, write_bytes, file_) != write_bytes) {\n      return HandleError(kIoError);\n    }\n    file->compressed_size += write_bytes;\n    current_offset_ += write_bytes;\n  }\n  z_stream_.reset();\n  return kNoError;\n}\n\nint32_t ZipWriter::FinishEntry() {\n  if (state_ != State::kWritingEntry) {\n    return kInvalidState;\n  }\n\n  FileInfo& currentFile = files_.back();\n  if (currentFile.compression_method & kCompressDeflated) {\n    int32_t result = FlushCompressedBytes(&currentFile);\n    if (result != kNoError) {\n      return result;\n    }\n  }\n\n  const uint32_t sig = DataDescriptor::kOptSignature;\n  if (fwrite(&sig, sizeof(sig), 1, file_) != 1) {\n    state_ = State::kError;\n    return kIoError;\n  }\n\n  DataDescriptor dd = {};\n  dd.crc32 = currentFile.crc32;\n  dd.compressed_size = currentFile.compressed_size;\n  dd.uncompressed_size = currentFile.uncompressed_size;\n  if (fwrite(&dd, sizeof(dd), 1, file_) != 1) {\n    return HandleError(kIoError);\n  }\n\n  current_offset_ += sizeof(DataDescriptor::kOptSignature) + sizeof(dd);\n  state_ = State::kWritingZip;\n  return kNoError;\n}\n\nint32_t ZipWriter::Finish() {\n  if (state_ != State::kWritingZip) {\n    return kInvalidState;\n  }\n\n  off64_t startOfCdr = current_offset_;\n  for (FileInfo& file : files_) {\n    CentralDirectoryRecord cdr = {};\n    cdr.record_signature = CentralDirectoryRecord::kSignature;\n    cdr.gpb_flags |= kGPBDDFlagMask;\n    cdr.compression_method = file.compression_method;\n    cdr.last_mod_time = file.last_mod_time;\n    cdr.last_mod_date = file.last_mod_date;\n    cdr.crc32 = file.crc32;\n    cdr.compressed_size = file.compressed_size;\n    cdr.uncompressed_size = file.uncompressed_size;\n    cdr.file_name_length = file.path.size();\n    cdr.local_file_header_offset = file.local_file_header_offset;\n    if (fwrite(&cdr, sizeof(cdr), 1, file_) != 1) {\n      return HandleError(kIoError);\n    }\n\n    if (fwrite(file.path.data(), 1, file.path.size(), file_) != file.path.size()) {\n      return HandleError(kIoError);\n    }\n\n    current_offset_ += sizeof(cdr) + file.path.size();\n  }\n\n  EocdRecord er = {};\n  er.eocd_signature = EocdRecord::kSignature;\n  er.disk_num = 0;\n  er.cd_start_disk = 0;\n  er.num_records_on_disk = files_.size();\n  er.num_records = files_.size();\n  er.cd_size = current_offset_ - startOfCdr;\n  er.cd_start_offset = startOfCdr;\n\n  if (fwrite(&er, sizeof(er), 1, file_) != 1) {\n    return HandleError(kIoError);\n  }\n\n  if (fflush(file_) != 0) {\n    return HandleError(kIoError);\n  }\n\n  current_offset_ += sizeof(er);\n  state_ = State::kDone;\n  return kNoError;\n}\n"
  },
  {
    "path": "atlas-aapt/system/core/libziparchive/zip_writer_test.cc",
    "content": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"ziparchive/zip_archive.h\"\n#include \"ziparchive/zip_writer.h\"\n\n#include <android-base/test_utils.h>\n#include <gtest/gtest.h>\n#include <time.h>\n#include <memory>\n#include <vector>\n\nstruct zipwriter : public ::testing::Test {\n  TemporaryFile* temp_file_;\n  int fd_;\n  FILE* file_;\n\n  void SetUp() override {\n    temp_file_ = new TemporaryFile();\n    fd_ = temp_file_->fd;\n    file_ = fdopen(fd_, \"w\");\n    ASSERT_NE(file_, nullptr);\n  }\n\n  void TearDown() override {\n    fclose(file_);\n    delete temp_file_;\n  }\n};\n\nTEST_F(zipwriter, WriteUncompressedZipWithOneFile) {\n  ZipWriter writer(file_);\n\n  const char* expected = \"hello\";\n\n  ASSERT_EQ(0, writer.StartEntry(\"file.txt\", 0));\n  ASSERT_EQ(0, writer.WriteBytes(\"he\", 2));\n  ASSERT_EQ(0, writer.WriteBytes(\"llo\", 3));\n  ASSERT_EQ(0, writer.FinishEntry());\n  ASSERT_EQ(0, writer.Finish());\n\n  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));\n\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveFd(fd_, \"temp\", &handle, false));\n\n  ZipEntry data;\n  ASSERT_EQ(0, FindEntry(handle, ZipString(\"file.txt\"), &data));\n  EXPECT_EQ(strlen(expected), data.compressed_length);\n  EXPECT_EQ(strlen(expected), data.uncompressed_length);\n  EXPECT_EQ(kCompressStored, data.method);\n\n  char buffer[6];\n  EXPECT_EQ(0,\n            ExtractToMemory(handle, &data, reinterpret_cast<uint8_t*>(&buffer), sizeof(buffer)));\n  buffer[5] = 0;\n\n  EXPECT_STREQ(expected, buffer);\n\n  CloseArchive(handle);\n}\n\nTEST_F(zipwriter, WriteUncompressedZipWithMultipleFiles) {\n  ZipWriter writer(file_);\n\n  ASSERT_EQ(0, writer.StartEntry(\"file.txt\", 0));\n  ASSERT_EQ(0, writer.WriteBytes(\"he\", 2));\n  ASSERT_EQ(0, writer.FinishEntry());\n\n  ASSERT_EQ(0, writer.StartEntry(\"file/file.txt\", 0));\n  ASSERT_EQ(0, writer.WriteBytes(\"llo\", 3));\n  ASSERT_EQ(0, writer.FinishEntry());\n\n  ASSERT_EQ(0, writer.StartEntry(\"file/file2.txt\", 0));\n  ASSERT_EQ(0, writer.FinishEntry());\n\n  ASSERT_EQ(0, writer.Finish());\n\n  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));\n\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveFd(fd_, \"temp\", &handle, false));\n\n  char buffer[4];\n  ZipEntry data;\n\n  ASSERT_EQ(0, FindEntry(handle, ZipString(\"file.txt\"), &data));\n  EXPECT_EQ(kCompressStored, data.method);\n  EXPECT_EQ(2u, data.compressed_length);\n  EXPECT_EQ(2u, data.uncompressed_length);\n  ASSERT_EQ(0,\n            ExtractToMemory(handle, &data, reinterpret_cast<uint8_t*>(buffer), arraysize(buffer)));\n  buffer[2] = 0;\n  EXPECT_STREQ(\"he\", buffer);\n\n  ASSERT_EQ(0, FindEntry(handle, ZipString(\"file/file.txt\"), &data));\n  EXPECT_EQ(kCompressStored, data.method);\n  EXPECT_EQ(3u, data.compressed_length);\n  EXPECT_EQ(3u, data.uncompressed_length);\n  ASSERT_EQ(0,\n            ExtractToMemory(handle, &data, reinterpret_cast<uint8_t*>(buffer), arraysize(buffer)));\n  buffer[3] = 0;\n  EXPECT_STREQ(\"llo\", buffer);\n\n  ASSERT_EQ(0, FindEntry(handle, ZipString(\"file/file2.txt\"), &data));\n  EXPECT_EQ(kCompressStored, data.method);\n  EXPECT_EQ(0u, data.compressed_length);\n  EXPECT_EQ(0u, data.uncompressed_length);\n\n  CloseArchive(handle);\n}\n\nTEST_F(zipwriter, WriteUncompressedZipFileWithAlignedFlag) {\n  ZipWriter writer(file_);\n\n  ASSERT_EQ(0, writer.StartEntry(\"align.txt\", ZipWriter::kAlign32));\n  ASSERT_EQ(0, writer.WriteBytes(\"he\", 2));\n  ASSERT_EQ(0, writer.FinishEntry());\n  ASSERT_EQ(0, writer.Finish());\n\n  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));\n\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveFd(fd_, \"temp\", &handle, false));\n\n  ZipEntry data;\n  ASSERT_EQ(0, FindEntry(handle, ZipString(\"align.txt\"), &data));\n  EXPECT_EQ(0, data.offset & 0x03);\n\n  CloseArchive(handle);\n}\n\nvoid ConvertZipTimeToTm(uint32_t& zip_time, struct tm* tm) {\n  memset(tm, 0, sizeof(struct tm));\n  tm->tm_hour = (zip_time >> 11) & 0x1f;\n  tm->tm_min = (zip_time >> 5) & 0x3f;\n  tm->tm_sec = (zip_time & 0x1f) << 1;\n\n  tm->tm_year = ((zip_time >> 25) & 0x7f) + 80;\n  tm->tm_mon = ((zip_time >> 21) & 0xf) - 1;\n  tm->tm_mday = (zip_time >> 16) & 0x1f;\n}\n\nstatic struct tm MakeTm() {\n  struct tm tm;\n  memset(&tm, 0, sizeof(struct tm));\n  tm.tm_year = 2001 - 1900;\n  tm.tm_mon = 1;\n  tm.tm_mday = 12;\n  tm.tm_hour = 18;\n  tm.tm_min = 30;\n  tm.tm_sec = 20;\n  return tm;\n}\n\nTEST_F(zipwriter, WriteUncompressedZipFileWithAlignedFlagAndTime) {\n  ZipWriter writer(file_);\n\n  struct tm tm = MakeTm();\n  time_t time = mktime(&tm);\n  ASSERT_EQ(0, writer.StartEntryWithTime(\"align.txt\", ZipWriter::kAlign32, time));\n  ASSERT_EQ(0, writer.WriteBytes(\"he\", 2));\n  ASSERT_EQ(0, writer.FinishEntry());\n  ASSERT_EQ(0, writer.Finish());\n\n  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));\n\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveFd(fd_, \"temp\", &handle, false));\n\n  ZipEntry data;\n  ASSERT_EQ(0, FindEntry(handle, ZipString(\"align.txt\"), &data));\n  EXPECT_EQ(0, data.offset & 0x03);\n\n  struct tm mod;\n  ConvertZipTimeToTm(data.mod_time, &mod);\n  EXPECT_EQ(tm.tm_sec, mod.tm_sec);\n  EXPECT_EQ(tm.tm_min, mod.tm_min);\n  EXPECT_EQ(tm.tm_hour, mod.tm_hour);\n  EXPECT_EQ(tm.tm_mday, mod.tm_mday);\n  EXPECT_EQ(tm.tm_mon, mod.tm_mon);\n  EXPECT_EQ(tm.tm_year, mod.tm_year);\n\n  CloseArchive(handle);\n}\n\nTEST_F(zipwriter, WriteUncompressedZipFileWithAlignedValue) {\n  ZipWriter writer(file_);\n\n  ASSERT_EQ(0, writer.StartAlignedEntry(\"align.txt\", 0, 4096));\n  ASSERT_EQ(0, writer.WriteBytes(\"he\", 2));\n  ASSERT_EQ(0, writer.FinishEntry());\n  ASSERT_EQ(0, writer.Finish());\n\n  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));\n\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveFd(fd_, \"temp\", &handle, false));\n\n  ZipEntry data;\n  ASSERT_EQ(0, FindEntry(handle, ZipString(\"align.txt\"), &data));\n  EXPECT_EQ(0, data.offset & 0xfff);\n\n  CloseArchive(handle);\n}\n\nTEST_F(zipwriter, WriteUncompressedZipFileWithAlignedValueAndTime) {\n  ZipWriter writer(file_);\n\n  struct tm tm = MakeTm();\n  time_t time = mktime(&tm);\n  ASSERT_EQ(0, writer.StartAlignedEntryWithTime(\"align.txt\", 0, time, 4096));\n  ASSERT_EQ(0, writer.WriteBytes(\"he\", 2));\n  ASSERT_EQ(0, writer.FinishEntry());\n  ASSERT_EQ(0, writer.Finish());\n\n  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));\n\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveFd(fd_, \"temp\", &handle, false));\n\n  ZipEntry data;\n  ASSERT_EQ(0, FindEntry(handle, ZipString(\"align.txt\"), &data));\n  EXPECT_EQ(0, data.offset & 0xfff);\n\n  struct tm mod;\n  ConvertZipTimeToTm(data.mod_time, &mod);\n  EXPECT_EQ(tm.tm_sec, mod.tm_sec);\n  EXPECT_EQ(tm.tm_min, mod.tm_min);\n  EXPECT_EQ(tm.tm_hour, mod.tm_hour);\n  EXPECT_EQ(tm.tm_mday, mod.tm_mday);\n  EXPECT_EQ(tm.tm_mon, mod.tm_mon);\n  EXPECT_EQ(tm.tm_year, mod.tm_year);\n\n  CloseArchive(handle);\n}\n\nTEST_F(zipwriter, WriteCompressedZipWithOneFile) {\n  ZipWriter writer(file_);\n\n  ASSERT_EQ(0, writer.StartEntry(\"file.txt\", ZipWriter::kCompress));\n  ASSERT_EQ(0, writer.WriteBytes(\"helo\", 4));\n  ASSERT_EQ(0, writer.FinishEntry());\n  ASSERT_EQ(0, writer.Finish());\n\n  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));\n\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveFd(fd_, \"temp\", &handle, false));\n\n  ZipEntry data;\n  ASSERT_EQ(0, FindEntry(handle, ZipString(\"file.txt\"), &data));\n  EXPECT_EQ(kCompressDeflated, data.method);\n  EXPECT_EQ(4u, data.uncompressed_length);\n\n  char buffer[5];\n  ASSERT_EQ(0,\n            ExtractToMemory(handle, &data, reinterpret_cast<uint8_t*>(buffer), arraysize(buffer)));\n  buffer[4] = 0;\n\n  EXPECT_STREQ(\"helo\", buffer);\n\n  CloseArchive(handle);\n}\n\nTEST_F(zipwriter, WriteCompressedZipFlushFull) {\n  // This exact data will cause the Finish() to require multiple calls\n  // to deflate() because the ZipWriter buffer isn't big enough to hold\n  // the entire compressed data buffer.\n  constexpr size_t kBufSize = 10000000;\n  std::vector<uint8_t> buffer(kBufSize);\n  size_t prev = 1;\n  for (size_t i = 0; i < kBufSize; i++) {\n    buffer[i] = i + prev;\n    prev = i;\n  }\n\n  ZipWriter writer(file_);\n  ASSERT_EQ(0, writer.StartEntry(\"file.txt\", ZipWriter::kCompress));\n  ASSERT_EQ(0, writer.WriteBytes(buffer.data(), buffer.size()));\n  ASSERT_EQ(0, writer.FinishEntry());\n  ASSERT_EQ(0, writer.Finish());\n\n  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));\n\n  ZipArchiveHandle handle;\n  ASSERT_EQ(0, OpenArchiveFd(fd_, \"temp\", &handle, false));\n\n  ZipEntry data;\n  ASSERT_EQ(0, FindEntry(handle, ZipString(\"file.txt\"), &data));\n  EXPECT_EQ(kCompressDeflated, data.method);\n  EXPECT_EQ(kBufSize, data.uncompressed_length);\n\n  std::vector<uint8_t> decompress(kBufSize);\n  memset(decompress.data(), 0, kBufSize);\n  ASSERT_EQ(0, ExtractToMemory(handle, &data, decompress.data(), decompress.size()));\n  EXPECT_EQ(0, memcmp(decompress.data(), buffer.data(), kBufSize))\n      << \"Input buffer and output buffer are different.\";\n\n  CloseArchive(handle);\n}\n\nTEST_F(zipwriter, CheckStartEntryErrors) {\n  ZipWriter writer(file_);\n\n  ASSERT_EQ(-5, writer.StartAlignedEntry(\"align.txt\", ZipWriter::kAlign32, 4096));\n  ASSERT_EQ(-6, writer.StartAlignedEntry(\"align.txt\", 0, 3));\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/include/androidfw/Asset.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Class providing access to a read-only asset.  Asset objects are NOT\n// thread-safe, and should not be shared across threads.\n//\n#ifndef __LIBS_ASSET_H\n#define __LIBS_ASSET_H\n\n#include <stdio.h>\n#include <sys/types.h>\n\n#include <utils/Compat.h>\n#include <utils/Errors.h>\n#include <utils/FileMap.h>\n#include <utils/String8.h>\n\nnamespace android {\n\n/*\n * Instances of this class provide read-only operations on a byte stream.\n *\n * Access may be optimized for streaming, random, or whole buffer modes.  All\n * operations are supported regardless of how the file was opened, but some\n * things will be less efficient.  [pass that in??]\n *\n * \"Asset\" is the base class for all types of assets.  The classes below\n * provide most of the implementation.  The AssetManager uses one of the\n * static \"create\" functions defined here to create a new instance.\n */\nclass Asset {\npublic:\n    virtual ~Asset(void);\n\n    static int32_t getGlobalCount();\n    static String8 getAssetAllocations();\n    \n    /* used when opening an asset */\n    typedef enum AccessMode {\n        ACCESS_UNKNOWN = 0,\n\n        /* read chunks, and seek forward and backward */\n        ACCESS_RANDOM,\n\n        /* read sequentially, with an occasional forward seek */\n        ACCESS_STREAMING,\n\n        /* caller plans to ask for a read-only buffer with all data */\n        ACCESS_BUFFER,\n    } AccessMode;\n\n    /*\n     * Read data from the current offset.  Returns the actual number of\n     * bytes read, 0 on EOF, or -1 on error.\n     */\n    virtual ssize_t read(void* buf, size_t count) = 0;\n\n    /*\n     * Seek to the specified offset.  \"whence\" uses the same values as\n     * lseek/fseek.  Returns the new position on success, or (off64_t) -1\n     * on failure.\n     */\n    virtual off64_t seek(off64_t offset, int whence) = 0;\n\n    /*\n     * Close the asset, freeing all associated resources.\n     */\n    virtual void close(void) = 0;\n\n    /*\n     * Get a pointer to a buffer with the entire contents of the file.\n     */\n    virtual const void* getBuffer(bool wordAligned) = 0;\n\n    /*\n     * Get the total amount of data that can be read.\n     */\n    virtual off64_t getLength(void) const = 0;\n\n    /*\n     * Get the total amount of data that can be read from the current position.\n     */\n    virtual off64_t getRemainingLength(void) const = 0;\n\n    /*\n     * Open a new file descriptor that can be used to read this asset.\n     * Returns -1 if you can not use the file descriptor (for example if the\n     * asset is compressed).\n     */\n    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const = 0;\n\n    /*\n     * Return whether this asset's buffer is allocated in RAM (not mmapped).\n     * Note: not virtual so it is safe to call even when being destroyed.\n     */\n    virtual bool isAllocated(void) const { return false; }\n\n    /*\n     * Get a string identifying the asset's source.  This might be a full\n     * path, it might be a colon-separated list of identifiers.\n     *\n     * This is NOT intended to be used for anything except debug output.\n     * DO NOT try to parse this or use it to open a file.\n     */\n    const char* getAssetSource(void) const { return mAssetSource.string(); }\n\nprotected:\n    Asset(void);        // constructor; only invoked indirectly\n\n    /* handle common seek() housekeeping */\n    off64_t handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn);\n\n    /* set the asset source string */\n    void setAssetSource(const String8& path) { mAssetSource = path; }\n\n    AccessMode getAccessMode(void) const { return mAccessMode; }\n\nprivate:\n    /* these operations are not implemented */\n    Asset(const Asset& src);\n    Asset& operator=(const Asset& src);\n\n    /* AssetManager needs access to our \"create\" functions */\n    friend class AssetManager;\n\n    /*\n     * Create the asset from a named file on disk.\n     */\n    static Asset* createFromFile(const char* fileName, AccessMode mode);\n\n    /*\n     * Create the asset from a named, compressed file on disk (e.g. \".gz\").\n     */\n    static Asset* createFromCompressedFile(const char* fileName,\n        AccessMode mode);\n\n#if 0\n    /*\n     * Create the asset from a segment of an open file.  This will fail\n     * if \"offset\" and \"length\" don't fit within the bounds of the file.\n     *\n     * The asset takes ownership of the file descriptor.\n     */\n    static Asset* createFromFileSegment(int fd, off64_t offset, size_t length,\n        AccessMode mode);\n\n    /*\n     * Create from compressed data.  \"fd\" should be seeked to the start of\n     * the compressed data.  This could be inside a gzip file or part of a\n     * Zip archive.\n     *\n     * The asset takes ownership of the file descriptor.\n     *\n     * This may not verify the validity of the compressed data until first\n     * use.\n     */\n    static Asset* createFromCompressedData(int fd, off64_t offset,\n        int compressionMethod, size_t compressedLength,\n        size_t uncompressedLength, AccessMode mode);\n#endif\n\n    /*\n     * Create the asset from a memory-mapped file segment.\n     *\n     * The asset takes ownership of the FileMap.\n     */\n    static Asset* createFromUncompressedMap(FileMap* dataMap, AccessMode mode);\n\n    /*\n     * Create the asset from a memory-mapped file segment with compressed\n     * data.  \"method\" is a Zip archive compression method constant.\n     *\n     * The asset takes ownership of the FileMap.\n     */\n    static Asset* createFromCompressedMap(FileMap* dataMap, int method,\n        size_t uncompressedLen, AccessMode mode);\n\n\n    /*\n     * Create from a reference-counted chunk of shared memory.\n     */\n    // TODO\n\n    AccessMode  mAccessMode;        // how the asset was opened\n    String8    mAssetSource;       // debug string\n    \n    Asset*\t\tmNext;\t\t\t\t// linked list.\n    Asset*\t\tmPrev;\n};\n\n\n/*\n * ===========================================================================\n *\n * Innards follow.  Do not use these classes directly.\n */\n\n/*\n * An asset based on an uncompressed file on disk.  It may encompass the\n * entire file or just a piece of it.  Access is through fread/fseek.\n */\nclass _FileAsset : public Asset {\npublic:\n    _FileAsset(void);\n    virtual ~_FileAsset(void);\n\n    /*\n     * Use a piece of an already-open file.\n     *\n     * On success, the object takes ownership of \"fd\".\n     */\n    status_t openChunk(const char* fileName, int fd, off64_t offset, size_t length);\n\n    /*\n     * Use a memory-mapped region.\n     *\n     * On success, the object takes ownership of \"dataMap\".\n     */\n    status_t openChunk(FileMap* dataMap);\n\n    /*\n     * Standard Asset interfaces.\n     */\n    virtual ssize_t read(void* buf, size_t count);\n    virtual off64_t seek(off64_t offset, int whence);\n    virtual void close(void);\n    virtual const void* getBuffer(bool wordAligned);\n    virtual off64_t getLength(void) const { return mLength; }\n    virtual off64_t getRemainingLength(void) const { return mLength-mOffset; }\n    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const;\n    virtual bool isAllocated(void) const { return mBuf != NULL; }\n\nprivate:\n    off64_t     mStart;         // absolute file offset of start of chunk\n    off64_t     mLength;        // length of the chunk\n    off64_t     mOffset;        // current local offset, 0 == mStart\n    FILE*       mFp;            // for read/seek\n    char*       mFileName;      // for opening\n\n    /*\n     * To support getBuffer() we either need to read the entire thing into\n     * a buffer or memory-map it.  For small files it's probably best to\n     * just read them in.\n     */\n    enum { kReadVsMapThreshold = 4096 };\n\n    FileMap*    mMap;           // for memory map\n    unsigned char* mBuf;        // for read\n    \n    const void* ensureAlignment(FileMap* map);\n};\n\n\n/*\n * An asset based on compressed data in a file.\n */\nclass _CompressedAsset : public Asset {\npublic:\n    _CompressedAsset(void);\n    virtual ~_CompressedAsset(void);\n\n    /*\n     * Use a piece of an already-open file.\n     *\n     * On success, the object takes ownership of \"fd\".\n     */\n    status_t openChunk(int fd, off64_t offset, int compressionMethod,\n        size_t uncompressedLen, size_t compressedLen);\n\n    /*\n     * Use a memory-mapped region.\n     *\n     * On success, the object takes ownership of \"fd\".\n     */\n    status_t openChunk(FileMap* dataMap, int compressionMethod,\n        size_t uncompressedLen);\n\n    /*\n     * Standard Asset interfaces.\n     */\n    virtual ssize_t read(void* buf, size_t count);\n    virtual off64_t seek(off64_t offset, int whence);\n    virtual void close(void);\n    virtual const void* getBuffer(bool wordAligned);\n    virtual off64_t getLength(void) const { return mUncompressedLen; }\n    virtual off64_t getRemainingLength(void) const { return mUncompressedLen-mOffset; }\n    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const { return -1; }\n    virtual bool isAllocated(void) const { return mBuf != NULL; }\n\nprivate:\n    off64_t     mStart;         // offset to start of compressed data\n    off64_t     mCompressedLen; // length of the compressed data\n    off64_t     mUncompressedLen; // length of the uncompressed data\n    off64_t     mOffset;        // current offset, 0 == start of uncomp data\n\n    FileMap*    mMap;           // for memory-mapped input\n    int         mFd;            // for file input\n\n    class StreamingZipInflater* mZipInflater;  // for streaming large compressed assets\n\n    unsigned char*  mBuf;       // for getBuffer()\n};\n\n// need: shared mmap version?\n\n}; // namespace android\n\n#endif // __LIBS_ASSET_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/include/androidfw/AssetDir.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Access a chunk of the asset hierarchy as if it were a single directory.\n//\n#ifndef __LIBS_ASSETDIR_H\n#define __LIBS_ASSETDIR_H\n\n#include <androidfw/misc.h>\n#include <utils/String8.h>\n#include <utils/Vector.h>\n#include <utils/SortedVector.h>\n#include <sys/types.h>\n\nnamespace android {\n\n/*\n * This provides vector-style access to a directory.  We do this rather\n * than modeling opendir/readdir access because it's simpler and the\n * nature of the operation requires us to have all data on hand anyway.\n *\n * The list of files will be sorted in ascending order by ASCII value.\n *\n * The contents are populated by our friend, the AssetManager.\n */\nclass AssetDir {\npublic:\n    AssetDir(void)\n        : mFileInfo(NULL)\n        {}\n    virtual ~AssetDir(void) {\n        delete mFileInfo;\n    }\n\n    /*\n     * Vector-style access.\n     */\n    size_t getFileCount(void) { return mFileInfo->size(); }\n    const String8& getFileName(int idx) {\n        return mFileInfo->itemAt(idx).getFileName();\n    }\n    const String8& getSourceName(int idx) {\n        return mFileInfo->itemAt(idx).getSourceName();\n    }\n\n    /*\n     * Get the type of a file (usually regular or directory).\n     */\n    FileType getFileType(int idx) {\n        return mFileInfo->itemAt(idx).getFileType();\n    }\n\nprivate:\n    /* these operations are not implemented */\n    AssetDir(const AssetDir& src);\n    const AssetDir& operator=(const AssetDir& src);\n\n    friend class AssetManager;\n\n    /*\n     * This holds information about files in the asset hierarchy.\n     */\n    class FileInfo {\n    public:\n        FileInfo(void) {}\n        FileInfo(const String8& path)      // useful for e.g. svect.indexOf\n            : mFileName(path), mFileType(kFileTypeUnknown)\n            {}\n        ~FileInfo(void) {}\n        FileInfo(const FileInfo& src) {\n            copyMembers(src);\n        }\n        const FileInfo& operator= (const FileInfo& src) {\n            if (this != &src)\n                copyMembers(src);\n            return *this;\n        }\n\n        void copyMembers(const FileInfo& src) {\n            mFileName = src.mFileName;\n            mFileType = src.mFileType;\n            mSourceName = src.mSourceName;\n        }\n\n        /* need this for SortedVector; must compare only on file name */\n        bool operator< (const FileInfo& rhs) const {\n            return mFileName < rhs.mFileName;\n        }\n\n        /* used by AssetManager */\n        bool operator== (const FileInfo& rhs) const {\n            return mFileName == rhs.mFileName;\n        }\n\n        void set(const String8& path, FileType type) {\n            mFileName = path;\n            mFileType = type;\n        }\n\n        const String8& getFileName(void) const { return mFileName; }\n        void setFileName(const String8& path) { mFileName = path; }\n\n        FileType getFileType(void) const { return mFileType; }\n        void setFileType(FileType type) { mFileType = type; }\n\n        const String8& getSourceName(void) const { return mSourceName; }\n        void setSourceName(const String8& path) { mSourceName = path; }\n\n        /*\n         * Handy utility for finding an entry in a sorted vector of FileInfo.\n         * Returns the index of the matching entry, or -1 if none found.\n         */\n        static int findEntry(const SortedVector<FileInfo>* pVector,\n            const String8& fileName);\n\n    private:\n        String8    mFileName;      // filename only\n        FileType    mFileType;      // regular, directory, etc\n\n        String8    mSourceName;    // currently debug-only\n    };\n\n    /* AssetManager uses this to initialize us */\n    void setFileList(SortedVector<FileInfo>* list) { mFileInfo = list; }\n\n    SortedVector<FileInfo>* mFileInfo;\n};\n\n}; // namespace android\n\n#endif // __LIBS_ASSETDIR_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/include/androidfw/AssetManager.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Asset management class.  AssetManager objects are thread-safe.\n//\n#ifndef __LIBS_ASSETMANAGER_H\n#define __LIBS_ASSETMANAGER_H\n\n#include <androidfw/Asset.h>\n#include <androidfw/AssetDir.h>\n#include <androidfw/ZipFileRO.h>\n#include <utils/KeyedVector.h>\n#include <utils/SortedVector.h>\n#include <utils/String16.h>\n#include <utils/String8.h>\n#include <utils/threads.h>\n#include <utils/Vector.h>\n\n/*\n * Native-app access is via the opaque typedef struct AAssetManager in the C namespace.\n */\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct AAssetManager { };\n\n#ifdef __cplusplus\n};\n#endif\n\n\n/*\n * Now the proper C++ android-namespace definitions\n */\n\nnamespace android {\n\nclass Asset;        // fwd decl for things that include Asset.h first\nclass ResTable;\nstruct ResTable_config;\n\n/*\n * Every application that uses assets needs one instance of this.  A\n * single instance may be shared across multiple threads, and a single\n * thread may have more than one instance (the latter is discouraged).\n *\n * The purpose of the AssetManager is to create Asset objects.  To do\n * this efficiently it may cache information about the locations of\n * files it has seen.  This can be controlled with the \"cacheMode\"\n * argument.\n *\n * The asset hierarchy may be examined like a filesystem, using\n * AssetDir objects to peruse a single directory.\n */\nclass AssetManager : public AAssetManager {\npublic:\n    static const char* RESOURCES_FILENAME;\n    static const char* IDMAP_BIN;\n    static const char* OVERLAY_DIR;\n    static const char* TARGET_PACKAGE_NAME;\n    static const char* TARGET_APK_PATH;\n    static const char* IDMAP_DIR;\n\n    typedef enum CacheMode {\n        CACHE_UNKNOWN = 0,\n        CACHE_OFF,          // don't try to cache file locations\n        CACHE_DEFER,        // construct cache as pieces are needed\n        //CACHE_SCAN,         // scan full(!) asset hierarchy at init() time\n    } CacheMode;\n\n    AssetManager(CacheMode cacheMode = CACHE_OFF);\n    virtual ~AssetManager(void);\n\n    static int32_t getGlobalCount();\n    \n    /*                                                                       \n     * Add a new source for assets.  This can be called multiple times to\n     * look in multiple places for assets.  It can be either a directory (for\n     * finding assets as raw files on the disk) or a ZIP file.  This newly\n     * added asset path will be examined first when searching for assets,\n     * before any that were previously added.\n     *\n     * Returns \"true\" on success, \"false\" on failure.  If 'cookie' is non-NULL,\n     * then on success, *cookie is set to the value corresponding to the\n     * newly-added asset source.\n     */\n    bool addAssetPath(const String8& path, int32_t* cookie);\n    bool addOverlayPath(const String8& path, int32_t* cookie);\n\n    /*                                                                       \n     * Convenience for adding the standard system assets.  Uses the\n     * ANDROID_ROOT environment variable to find them.\n     */\n    bool addDefaultAssets();\n\n    /*                                                                       \n     * Iterate over the asset paths in this manager.  (Previously\n     * added via addAssetPath() and addDefaultAssets().)  On first call,\n     * 'cookie' must be 0, resulting in the first cookie being returned.\n     * Each next cookie will be returned there-after, until -1 indicating\n     * the end has been reached.\n     */\n    int32_t nextAssetPath(const int32_t cookie) const;\n\n    /*                                                                       \n     * Return an asset path in the manager.  'which' must be between 0 and\n     * countAssetPaths().\n     */\n    String8 getAssetPath(const int32_t cookie) const;\n\n    /*\n     * Set the current locale and vendor.  The locale can change during\n     * the lifetime of an AssetManager if the user updates the device's\n     * language setting.  The vendor is less likely to change.\n     *\n     * Pass in NULL to indicate no preference.\n     */\n    void setLocale(const char* locale);\n    void setVendor(const char* vendor);\n\n    /*\n     * Choose screen orientation for resources values returned.\n     */\n    void setConfiguration(const ResTable_config& config, const char* locale = NULL);\n\n    void getConfiguration(ResTable_config* outConfig) const;\n\n    typedef Asset::AccessMode AccessMode;       // typing shortcut\n\n    /*\n     * Open an asset.\n     *\n     * This will search through locale-specific and vendor-specific\n     * directories and packages to find the file.\n     *\n     * The object returned does not depend on the AssetManager.  It should\n     * be freed by calling Asset::close().\n     */\n    Asset* open(const char* fileName, AccessMode mode);\n\n    /*\n     * Open a non-asset file as an asset.\n     *\n     * This is for opening files that are included in an asset package\n     * but aren't assets.  These sit outside the usual \"locale/vendor\"\n     * path hierarchy, and will not be seen by \"AssetDir\" or included\n     * in our filename cache.\n     */\n    Asset* openNonAsset(const char* fileName, AccessMode mode, int32_t* outCookie = NULL);\n\n    /*\n     * Explicit non-asset file.  The file explicitly named by the cookie (the\n     * resource set to look in) and fileName will be opened and returned.\n     */\n    Asset* openNonAsset(const int32_t cookie, const char* fileName, AccessMode mode);\n\n    /*\n     * Open a directory within the asset hierarchy.\n     *\n     * The contents of the directory are an amalgam of vendor-specific,\n     * locale-specific, and generic assets stored loosely or in asset\n     * packages.  Depending on the cache setting and previous accesses,\n     * this call may incur significant disk overhead.\n     *\n     * To open the top-level directory, pass in \"\".\n     */\n    AssetDir* openDir(const char* dirName);\n\n    /*\n     * Open a directory within a particular path of the asset manager.\n     *\n     * The contents of the directory are an amalgam of vendor-specific,\n     * locale-specific, and generic assets stored loosely or in asset\n     * packages.  Depending on the cache setting and previous accesses,\n     * this call may incur significant disk overhead.\n     *\n     * To open the top-level directory, pass in \"\".\n     */\n    AssetDir* openNonAssetDir(const int32_t cookie, const char* dirName);\n\n    /*\n     * Get the type of a file in the asset hierarchy.  They will either\n     * be \"regular\" or \"directory\".  [Currently only works for \"regular\".]\n     *\n     * Can also be used as a quick test for existence of a file.\n     */\n    FileType getFileType(const char* fileName);\n\n    /*                                                                       \n     * Return the complete resource table to find things in the package.\n     */\n    const ResTable& getResources(bool required = true) const;\n\n    /*\n     * Discard cached filename information.  This only needs to be called\n     * if somebody has updated the set of \"loose\" files, and we want to\n     * discard our cached notion of what's where.\n     */\n    void purge(void) { purgeFileNameCacheLocked(); }\n\n    /*\n     * Return true if the files this AssetManager references are all\n     * up-to-date (have not been changed since it was created).  If false\n     * is returned, you will need to create a new AssetManager to get\n     * the current data.\n     */\n    bool isUpToDate();\n    \n    /**\n     * Get the known locales for this asset manager object.\n     */\n    void getLocales(Vector<String8>* locales) const;\n\n    /**\n     * Generate idmap data to translate resources IDs between a package and a\n     * corresponding overlay package.\n     */\n    bool createIdmap(const char* targetApkPath, const char* overlayApkPath,\n        uint32_t targetCrc, uint32_t overlayCrc, uint32_t** outData, size_t* outSize);\n\nprivate:\n    struct asset_path\n    {\n        String8 path;\n        FileType type;\n        String8 idmap;\n    };\n\n    Asset* openInPathLocked(const char* fileName, AccessMode mode,\n        const asset_path& path);\n    Asset* openNonAssetInPathLocked(const char* fileName, AccessMode mode,\n        const asset_path& path);\n    Asset* openInLocaleVendorLocked(const char* fileName, AccessMode mode,\n        const asset_path& path, const char* locale, const char* vendor);\n    String8 createPathNameLocked(const asset_path& path, const char* locale,\n        const char* vendor);\n    String8 createPathNameLocked(const asset_path& path, const char* rootDir);\n    String8 createZipSourceNameLocked(const String8& zipFileName,\n        const String8& dirName, const String8& fileName);\n\n    ZipFileRO* getZipFileLocked(const asset_path& path);\n    Asset* openAssetFromFileLocked(const String8& fileName, AccessMode mode);\n    Asset* openAssetFromZipLocked(const ZipFileRO* pZipFile,\n        const ZipEntryRO entry, AccessMode mode, const String8& entryName);\n\n    bool scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n        const asset_path& path, const char* rootDir, const char* dirName);\n    SortedVector<AssetDir::FileInfo>* scanDirLocked(const String8& path);\n    bool scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n        const asset_path& path, const char* rootDir, const char* dirName);\n    void mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n        const SortedVector<AssetDir::FileInfo>* pContents);\n\n    void loadFileNameCacheLocked(void);\n    void fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n        const char* dirName);\n    bool fncScanAndMergeDirLocked(\n        SortedVector<AssetDir::FileInfo>* pMergedInfo,\n        const asset_path& path, const char* locale, const char* vendor,\n        const char* dirName);\n    void purgeFileNameCacheLocked(void);\n\n    const ResTable* getResTable(bool required = true) const;\n    void setLocaleLocked(const char* locale);\n    void updateResourceParamsLocked() const;\n    bool appendPathToResTable(const asset_path& ap) const;\n\n    Asset* openIdmapLocked(const struct asset_path& ap) const;\n\n    void addSystemOverlays(const char* pathOverlaysList, const String8& targetPackagePath,\n            ResTable* sharedRes, size_t offset) const;\n\n    class SharedZip : public RefBase {\n    public:\n        static sp<SharedZip> get(const String8& path, bool createIfNotPresent = true);\n\n        ZipFileRO* getZip();\n\n        Asset* getResourceTableAsset();\n        Asset* setResourceTableAsset(Asset* asset);\n\n        ResTable* getResourceTable();\n        ResTable* setResourceTable(ResTable* res);\n        \n        bool isUpToDate();\n\n        void addOverlay(const asset_path& ap);\n        bool getOverlay(size_t idx, asset_path* out) const;\n        \n    protected:\n        ~SharedZip();\n\n    private:\n        SharedZip(const String8& path, time_t modWhen);\n        SharedZip(); // <-- not implemented\n\n        String8 mPath;\n        ZipFileRO* mZipFile;\n        time_t mModWhen;\n\n        Asset* mResourceTableAsset;\n        ResTable* mResourceTable;\n\n        Vector<asset_path> mOverlays;\n\n        static Mutex gLock;\n        static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;\n    };\n\n    /*\n     * Manage a set of Zip files.  For each file we need a pointer to the\n     * ZipFile and a time_t with the file's modification date.\n     *\n     * We currently only have two zip files (current app, \"common\" app).\n     * (This was originally written for 8, based on app/locale/vendor.)\n     */\n    class ZipSet {\n    public:\n        ZipSet(void);\n        ~ZipSet(void);\n\n        /*\n         * Return a ZipFileRO structure for a ZipFileRO with the specified\n         * parameters.\n         */\n        ZipFileRO* getZip(const String8& path);\n\n        Asset* getZipResourceTableAsset(const String8& path);\n        Asset* setZipResourceTableAsset(const String8& path, Asset* asset);\n\n        ResTable* getZipResourceTable(const String8& path);\n        ResTable* setZipResourceTable(const String8& path, ResTable* res);\n\n        // generate path, e.g. \"common/en-US-noogle.zip\"\n        static String8 getPathName(const char* path);\n\n        bool isUpToDate();\n\n        void addOverlay(const String8& path, const asset_path& overlay);\n        bool getOverlay(const String8& path, size_t idx, asset_path* out) const;\n        \n    private:\n        void closeZip(int idx);\n\n        int getIndex(const String8& zip) const;\n        mutable Vector<String8> mZipPath;\n        mutable Vector<sp<SharedZip> > mZipFile;\n    };\n\n    // Protect all internal state.\n    mutable Mutex   mLock;\n\n    ZipSet          mZipSet;\n\n    Vector<asset_path> mAssetPaths;\n    char*           mLocale;\n    char*           mVendor;\n\n    mutable ResTable* mResources;\n    ResTable_config* mConfig;\n\n    /*\n     * Cached data for \"loose\" files.  This lets us avoid poking at the\n     * filesystem when searching for loose assets.  Each entry is the\n     * \"extended partial\" path, e.g. \"default/default/foo/bar.txt\".  The\n     * full set of files is present, including \".EXCLUDE\" entries.\n     *\n     * We do not cache directory names.  We don't retain the \".gz\",\n     * because to our clients \"foo\" and \"foo.gz\" both look like \"foo\".\n     */\n    CacheMode       mCacheMode;         // is the cache enabled?\n    bool            mCacheValid;        // clear when locale or vendor changes\n    SortedVector<AssetDir::FileInfo> mCache;\n};\n\n}; // namespace android\n\n#endif // __LIBS_ASSETMANAGER_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/include/androidfw/BackupHelpers.h",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _UTILS_BACKUP_HELPERS_H\n#define _UTILS_BACKUP_HELPERS_H\n\n#include <utils/Errors.h>\n#include <utils/String8.h>\n#include <utils/KeyedVector.h>\n\nnamespace android {\n\nenum {\n    BACKUP_HEADER_ENTITY_V1 = 0x61746144, // Data (little endian)\n};\n\ntypedef struct {\n    int type; // BACKUP_HEADER_ENTITY_V1\n    int keyLen; // length of the key name, not including the null terminator\n    int dataSize; // size of the data, not including the padding, -1 means delete\n} entity_header_v1;\n\nstruct SnapshotHeader {\n    int magic0;\n    int fileCount;\n    int magic1;\n    int totalSize;\n};\n\nstruct FileState {\n    int modTime_sec;\n    int modTime_nsec;\n    int mode;\n    int size;\n    int crc32;\n    int nameLen;\n};\n\nstruct FileRec {\n    String8 file;\n    bool deleted;\n    FileState s;\n};\n\n\n/**\n * Writes the data.\n *\n * If an error occurs, it poisons this object and all write calls will fail\n * with the error that occurred.\n */\nclass BackupDataWriter\n{\npublic:\n    BackupDataWriter(int fd);\n    // does not close fd\n    ~BackupDataWriter();\n\n    status_t WriteEntityHeader(const String8& key, size_t dataSize);\n\n    /* Note: WriteEntityData will write arbitrary data into the file without\n     * validation or a previously-supplied header.  The full backup implementation\n     * uses it this way to generate a controlled binary stream that is not\n     * entity-structured.  If the implementation here is changed, either this\n     * use case must remain valid, or the full backup implementation should be\n     * adjusted to use some other appropriate mechanism.\n     */\n    status_t WriteEntityData(const void* data, size_t size);\n\n    void SetKeyPrefix(const String8& keyPrefix);\n\nprivate:\n    explicit BackupDataWriter();\n    status_t write_padding_for(int n);\n    \n    int m_fd;\n    status_t m_status;\n    ssize_t m_pos;\n    int m_entityCount;\n    String8 m_keyPrefix;\n};\n\n/**\n * Reads the data.\n *\n * If an error occurs, it poisons this object and all write calls will fail\n * with the error that occurred.\n */\nclass BackupDataReader\n{\npublic:\n    BackupDataReader(int fd);\n    // does not close fd\n    ~BackupDataReader();\n\n    status_t Status();\n    status_t ReadNextHeader(bool* done, int* type);\n\n    bool HasEntities();\n    status_t ReadEntityHeader(String8* key, size_t* dataSize);\n    status_t SkipEntityData(); // must be called with the pointer at the beginning of the data.\n    ssize_t ReadEntityData(void* data, size_t size);\n\nprivate:\n    explicit BackupDataReader();\n    status_t skip_padding();\n    \n    int m_fd;\n    bool m_done;\n    status_t m_status;\n    ssize_t m_pos;\n    ssize_t m_dataEndPos;\n    int m_entityCount;\n    union {\n        int type;\n        entity_header_v1 entity;\n    } m_header;\n    String8 m_key;\n};\n\nint back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,\n        char const* const* files, char const* const *keys, int fileCount);\n\nint write_tarfile(const String8& packageName, const String8& domain,\n        const String8& rootPath, const String8& filePath, BackupDataWriter* outputStream);\n\nclass RestoreHelperBase\n{\npublic:\n    RestoreHelperBase();\n    ~RestoreHelperBase();\n\n    status_t WriteFile(const String8& filename, BackupDataReader* in);\n    status_t WriteSnapshot(int fd);\n\nprivate:\n    void* m_buf;\n    bool m_loggedUnknownMetadata;\n    KeyedVector<String8,FileRec> m_files;\n};\n\n#define TEST_BACKUP_HELPERS 1\n\n#if TEST_BACKUP_HELPERS\nint backup_helper_test_empty();\nint backup_helper_test_four();\nint backup_helper_test_files();\nint backup_helper_test_null_base();\nint backup_helper_test_missing_file();\nint backup_helper_test_data_writer();\nint backup_helper_test_data_reader();\n#endif\n\n} // namespace android\n\n#endif // _UTILS_BACKUP_HELPERS_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/include/androidfw/ByteBucketArray.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __BYTE_BUCKET_ARRAY_H\n#define __BYTE_BUCKET_ARRAY_H\n\n#include <utils/Log.h>\n#include <stdint.h>\n#include <string.h>\n\nnamespace android {\n\n/**\n * Stores a sparsely populated array. Has a fixed size of 256\n * (number of entries that a byte can represent).\n */\ntemplate<typename T>\nclass ByteBucketArray {\npublic:\n    ByteBucketArray() : mDefault() {\n        memset(mBuckets, 0, sizeof(mBuckets));\n    }\n\n    ~ByteBucketArray() {\n        for (size_t i = 0; i < NUM_BUCKETS; i++) {\n            if (mBuckets[i] != NULL) {\n                delete [] mBuckets[i];\n            }\n        }\n        memset(mBuckets, 0, sizeof(mBuckets));\n    }\n\n    inline size_t size() const {\n        return NUM_BUCKETS * BUCKET_SIZE;\n    }\n\n    inline const T& get(size_t index) const {\n        return (*this)[index];\n    }\n\n    const T& operator[](size_t index) const {\n        if (index >= size()) {\n            return mDefault;\n        }\n\n        uint8_t bucketIndex = static_cast<uint8_t>(index) >> 4;\n        T* bucket = mBuckets[bucketIndex];\n        if (bucket == NULL) {\n            return mDefault;\n        }\n        return bucket[0x0f & static_cast<uint8_t>(index)];\n    }\n\n    T& editItemAt(size_t index) {\n        ALOG_ASSERT(index < size(), \"ByteBucketArray.getOrCreate(index=%u) with size=%u\",\n                (uint32_t) index, (uint32_t) size());\n\n        uint8_t bucketIndex = static_cast<uint8_t>(index) >> 4;\n        T* bucket = mBuckets[bucketIndex];\n        if (bucket == NULL) {\n            bucket = mBuckets[bucketIndex] = new T[BUCKET_SIZE]();\n        }\n        return bucket[0x0f & static_cast<uint8_t>(index)];\n    }\n\n    bool set(size_t index, const T& value) {\n        if (index >= size()) {\n            return false;\n        }\n\n        editItemAt(index) = value;\n        return true;\n    }\n\nprivate:\n    enum { NUM_BUCKETS = 16, BUCKET_SIZE = 16 };\n\n    T*  mBuckets[NUM_BUCKETS];\n    T   mDefault;\n};\n\n} // namespace android\n\n#endif // __BYTE_BUCKET_ARRAY_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/include/androidfw/CursorWindow.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef _ANDROID__DATABASE_WINDOW_H\n#define _ANDROID__DATABASE_WINDOW_H\n\n#include <cutils/log.h>\n#include <stddef.h>\n#include <stdint.h>\n\n#include <binder/Parcel.h>\n#include <utils/String8.h>\n\n#if LOG_NDEBUG\n\n#define IF_LOG_WINDOW() if (false)\n#define LOG_WINDOW(...)\n\n#else\n\n#define IF_LOG_WINDOW() IF_ALOG(LOG_DEBUG, \"CursorWindow\")\n#define LOG_WINDOW(...) ALOG(LOG_DEBUG, \"CursorWindow\", __VA_ARGS__)\n\n#endif\n\nnamespace android {\n\n/**\n * This class stores a set of rows from a database in a buffer. The begining of the\n * window has first chunk of RowSlots, which are offsets to the row directory, followed by\n * an offset to the next chunk in a linked-list of additional chunk of RowSlots in case\n * the pre-allocated chunk isn't big enough to refer to all rows. Each row directory has a\n * FieldSlot per column, which has the size, offset, and type of the data for that field.\n * Note that the data types come from sqlite3.h.\n *\n * Strings are stored in UTF-8.\n */\nclass CursorWindow {\n    CursorWindow(const String8& name, int ashmemFd,\n            void* data, size_t size, bool readOnly);\n\npublic:\n    /* Field types. */\n    enum {\n        FIELD_TYPE_NULL = 0,\n        FIELD_TYPE_INTEGER = 1,\n        FIELD_TYPE_FLOAT = 2,\n        FIELD_TYPE_STRING = 3,\n        FIELD_TYPE_BLOB = 4,\n    };\n\n    /* Opaque type that describes a field slot. */\n    struct FieldSlot {\n    private:\n        int32_t type;\n        union {\n            double d;\n            int64_t l;\n            struct {\n                uint32_t offset;\n                uint32_t size;\n            } buffer;\n        } data;\n\n        friend class CursorWindow;\n    } __attribute((packed));\n\n    ~CursorWindow();\n\n    static status_t create(const String8& name, size_t size, CursorWindow** outCursorWindow);\n    static status_t createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow);\n\n    status_t writeToParcel(Parcel* parcel);\n\n    inline String8 name() { return mName; }\n    inline size_t size() { return mSize; }\n    inline size_t freeSpace() { return mSize - mHeader->freeOffset; }\n    inline uint32_t getNumRows() { return mHeader->numRows; }\n    inline uint32_t getNumColumns() { return mHeader->numColumns; }\n\n    status_t clear();\n    status_t setNumColumns(uint32_t numColumns);\n\n    /**\n     * Allocate a row slot and its directory.\n     * The row is initialized will null entries for each field.\n     */\n    status_t allocRow();\n    status_t freeLastRow();\n\n    status_t putBlob(uint32_t row, uint32_t column, const void* value, size_t size);\n    status_t putString(uint32_t row, uint32_t column, const char* value, size_t sizeIncludingNull);\n    status_t putLong(uint32_t row, uint32_t column, int64_t value);\n    status_t putDouble(uint32_t row, uint32_t column, double value);\n    status_t putNull(uint32_t row, uint32_t column);\n\n    /**\n     * Gets the field slot at the specified row and column.\n     * Returns null if the requested row or column is not in the window.\n     */\n    FieldSlot* getFieldSlot(uint32_t row, uint32_t column);\n\n    inline int32_t getFieldSlotType(FieldSlot* fieldSlot) {\n        return fieldSlot->type;\n    }\n\n    inline int64_t getFieldSlotValueLong(FieldSlot* fieldSlot) {\n        return fieldSlot->data.l;\n    }\n\n    inline double getFieldSlotValueDouble(FieldSlot* fieldSlot) {\n        return fieldSlot->data.d;\n    }\n\n    inline const char* getFieldSlotValueString(FieldSlot* fieldSlot,\n            size_t* outSizeIncludingNull) {\n        *outSizeIncludingNull = fieldSlot->data.buffer.size;\n        return static_cast<char*>(offsetToPtr(fieldSlot->data.buffer.offset));\n    }\n\n    inline const void* getFieldSlotValueBlob(FieldSlot* fieldSlot, size_t* outSize) {\n        *outSize = fieldSlot->data.buffer.size;\n        return offsetToPtr(fieldSlot->data.buffer.offset);\n    }\n\nprivate:\n    static const size_t ROW_SLOT_CHUNK_NUM_ROWS = 100;\n\n    struct Header {\n        // Offset of the lowest unused byte in the window.\n        uint32_t freeOffset;\n\n        // Offset of the first row slot chunk.\n        uint32_t firstChunkOffset;\n\n        uint32_t numRows;\n        uint32_t numColumns;\n    };\n\n    struct RowSlot {\n        uint32_t offset;\n    };\n\n    struct RowSlotChunk {\n        RowSlot slots[ROW_SLOT_CHUNK_NUM_ROWS];\n        uint32_t nextChunkOffset;\n    };\n\n    String8 mName;\n    int mAshmemFd;\n    void* mData;\n    size_t mSize;\n    bool mReadOnly;\n    Header* mHeader;\n\n    inline void* offsetToPtr(uint32_t offset) {\n        return static_cast<uint8_t*>(mData) + offset;\n    }\n\n    inline uint32_t offsetFromPtr(void* ptr) {\n        return static_cast<uint8_t*>(ptr) - static_cast<uint8_t*>(mData);\n    }\n\n    /**\n     * Allocate a portion of the window. Returns the offset\n     * of the allocation, or 0 if there isn't enough space.\n     * If aligned is true, the allocation gets 4 byte alignment.\n     */\n    uint32_t alloc(size_t size, bool aligned = false);\n\n    RowSlot* getRowSlot(uint32_t row);\n    RowSlot* allocRowSlot();\n\n    status_t putBlobOrString(uint32_t row, uint32_t column,\n            const void* value, size_t size, int32_t type);\n};\n\n}; // namespace android\n\n#endif\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/include/androidfw/ObbFile.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef OBBFILE_H_\n#define OBBFILE_H_\n\n#include <stdint.h>\n#include <strings.h>\n\n#include <utils/RefBase.h>\n#include <utils/String8.h>\n\nnamespace android {\n\n// OBB flags (bit 0)\n#define OBB_OVERLAY         (1 << 0)\n#define OBB_SALTED          (1 << 1)\n\nclass ObbFile : public RefBase {\nprotected:\n    virtual ~ObbFile();\n\npublic:\n    ObbFile();\n\n    bool readFrom(const char* filename);\n    bool readFrom(int fd);\n    bool writeTo(const char* filename);\n    bool writeTo(int fd);\n    bool removeFrom(const char* filename);\n    bool removeFrom(int fd);\n\n    const char* getFileName() const {\n        return mFileName;\n    }\n\n    const String8 getPackageName() const {\n        return mPackageName;\n    }\n\n    void setPackageName(String8 packageName) {\n        mPackageName = packageName;\n    }\n\n    int32_t getVersion() const {\n        return mVersion;\n    }\n\n    void setVersion(int32_t version) {\n        mVersion = version;\n    }\n\n    int32_t getFlags() const {\n        return mFlags;\n    }\n\n    void setFlags(int32_t flags) {\n        mFlags = flags;\n    }\n\n    const unsigned char* getSalt(size_t* length) const {\n        if ((mFlags & OBB_SALTED) == 0) {\n            *length = 0;\n            return NULL;\n        }\n\n        *length = sizeof(mSalt);\n        return mSalt;\n    }\n\n    bool setSalt(const unsigned char* salt, size_t length) {\n        if (length != sizeof(mSalt)) {\n            return false;\n        }\n\n        memcpy(mSalt, salt, sizeof(mSalt));\n        mFlags |= OBB_SALTED;\n        return true;\n    }\n\n    bool isOverlay() {\n        return (mFlags & OBB_OVERLAY) == OBB_OVERLAY;\n    }\n\n    void setOverlay(bool overlay) {\n        if (overlay) {\n            mFlags |= OBB_OVERLAY;\n        } else {\n            mFlags &= ~OBB_OVERLAY;\n        }\n    }\n\n    static inline uint32_t get4LE(const unsigned char* buf) {\n        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);\n    }\n\n    static inline void put4LE(unsigned char* buf, uint32_t val) {\n        buf[0] = val & 0xFF;\n        buf[1] = (val >> 8) & 0xFF;\n        buf[2] = (val >> 16) & 0xFF;\n        buf[3] = (val >> 24) & 0xFF;\n    }\n\nprivate:\n    /* Package name this ObbFile is associated with */\n    String8 mPackageName;\n\n    /* Package version this ObbFile is associated with */\n    int32_t mVersion;\n\n    /* Flags for this OBB type. */\n    int32_t mFlags;\n\n    /* Whether the file is salted. */\n    bool mSalted;\n\n    /* The encryption salt. */\n    unsigned char mSalt[8];\n\n    const char* mFileName;\n\n    size_t mFileSize;\n\n    size_t mFooterStart;\n\n    unsigned char* mReadBuf;\n\n    bool parseObbFile(int fd);\n};\n\n}\n#endif /* OBBFILE_H_ */\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/include/androidfw/ResourcePackageId.h",
    "content": "#ifndef __ResourcePackageId__\n#define __ResourcePackageId__\nextern int customePackageId;\nextern char* sktPackageName;\n#endif\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/include/androidfw/ResourceTypes.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Definitions of resource data structures.\n//\n#ifndef _LIBS_UTILS_RESOURCE_TYPES_H\n#define _LIBS_UTILS_RESOURCE_TYPES_H\n\n#include <androidfw/Asset.h>\n#include <utils/ByteOrder.h>\n#include <utils/Errors.h>\n#include <utils/String16.h>\n#include <utils/Vector.h>\n#include <utils/KeyedVector.h>\n\n#include <utils/threads.h>\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#include <android/configuration.h>\n\nnamespace android {\n\n/** ********************************************************************\n *  PNG Extensions\n *\n *  New private chunks that may be placed in PNG images.\n *\n *********************************************************************** */\n\n/**\n * This chunk specifies how to split an image into segments for\n * scaling.\n *\n * There are J horizontal and K vertical segments.  These segments divide\n * the image into J*K regions as follows (where J=4 and K=3):\n *\n *      F0   S0    F1     S1\n *   +-----+----+------+-------+\n * S2|  0  |  1 |  2   |   3   |\n *   +-----+----+------+-------+\n *   |     |    |      |       |\n *   |     |    |      |       |\n * F2|  4  |  5 |  6   |   7   |\n *   |     |    |      |       |\n *   |     |    |      |       |\n *   +-----+----+------+-------+\n * S3|  8  |  9 |  10  |   11  |\n *   +-----+----+------+-------+\n *\n * Each horizontal and vertical segment is considered to by either\n * stretchable (marked by the Sx labels) or fixed (marked by the Fy\n * labels), in the horizontal or vertical axis, respectively. In the\n * above example, the first is horizontal segment (F0) is fixed, the\n * next is stretchable and then they continue to alternate. Note that\n * the segment list for each axis can begin or end with a stretchable\n * or fixed segment.\n *\n * The relative sizes of the stretchy segments indicates the relative\n * amount of stretchiness of the regions bordered by the segments.  For\n * example, regions 3, 7 and 11 above will take up more horizontal space\n * than regions 1, 5 and 9 since the horizontal segment associated with\n * the first set of regions is larger than the other set of regions.  The\n * ratios of the amount of horizontal (or vertical) space taken by any\n * two stretchable slices is exactly the ratio of their corresponding\n * segment lengths.\n *\n * xDivs and yDivs are arrays of horizontal and vertical pixel\n * indices.  The first pair of Divs (in either array) indicate the\n * starting and ending points of the first stretchable segment in that\n * axis. The next pair specifies the next stretchable segment, etc. So\n * in the above example xDiv[0] and xDiv[1] specify the horizontal\n * coordinates for the regions labeled 1, 5 and 9.  xDiv[2] and\n * xDiv[3] specify the coordinates for regions 3, 7 and 11. Note that\n * the leftmost slices always start at x=0 and the rightmost slices\n * always end at the end of the image. So, for example, the regions 0,\n * 4 and 8 (which are fixed along the X axis) start at x value 0 and\n * go to xDiv[0] and slices 2, 6 and 10 start at xDiv[1] and end at\n * xDiv[2].\n *\n * The colors array contains hints for each of the regions. They are\n * ordered according left-to-right and top-to-bottom as indicated above.\n * For each segment that is a solid color the array entry will contain\n * that color value; otherwise it will contain NO_COLOR. Segments that\n * are completely transparent will always have the value TRANSPARENT_COLOR.\n *\n * The PNG chunk type is \"npTc\".\n */\nstruct Res_png_9patch\n{\n    Res_png_9patch() : wasDeserialized(false), xDivsOffset(0),\n                       yDivsOffset(0), colorsOffset(0) { }\n\n    int8_t wasDeserialized;\n    int8_t numXDivs;\n    int8_t numYDivs;\n    int8_t numColors;\n\n    // The offset (from the start of this structure) to the xDivs & yDivs\n    // array for this 9patch. To get a pointer to this array, call\n    // getXDivs or getYDivs. Note that the serialized form for 9patches places\n    // the xDivs, yDivs and colors arrays immediately after the location\n    // of the Res_png_9patch struct.\n    uint32_t xDivsOffset;\n    uint32_t yDivsOffset;\n\n    int32_t paddingLeft, paddingRight;\n    int32_t paddingTop, paddingBottom;\n\n    enum {\n        // The 9 patch segment is not a solid color.\n        NO_COLOR = 0x00000001,\n\n        // The 9 patch segment is completely transparent.\n        TRANSPARENT_COLOR = 0x00000000\n    };\n\n    // The offset (from the start of this structure) to the colors array\n    // for this 9patch.\n    uint32_t colorsOffset;\n\n    // Convert data from device representation to PNG file representation.\n    void deviceToFile();\n    // Convert data from PNG file representation to device representation.\n    void fileToDevice();\n\n    // Serialize/Marshall the patch data into a newly malloc-ed block.\n    static void* serialize(const Res_png_9patch& patchHeader, const int32_t* xDivs,\n                           const int32_t* yDivs, const uint32_t* colors);\n    // Serialize/Marshall the patch data into |outData|.\n    static void serialize(const Res_png_9patch& patchHeader, const int32_t* xDivs,\n                           const int32_t* yDivs, const uint32_t* colors, void* outData);\n    // Deserialize/Unmarshall the patch data\n    static Res_png_9patch* deserialize(void* data);\n    // Compute the size of the serialized data structure\n    size_t serializedSize() const;\n\n    // These tell where the next section of a patch starts.\n    // For example, the first patch includes the pixels from\n    // 0 to xDivs[0]-1 and the second patch includes the pixels\n    // from xDivs[0] to xDivs[1]-1.\n    inline int32_t* getXDivs() const {\n        return reinterpret_cast<int32_t*>(reinterpret_cast<uintptr_t>(this) + xDivsOffset);\n    }\n    inline int32_t* getYDivs() const {\n        return reinterpret_cast<int32_t*>(reinterpret_cast<uintptr_t>(this) + yDivsOffset);\n    }\n    inline uint32_t* getColors() const {\n        return reinterpret_cast<uint32_t*>(reinterpret_cast<uintptr_t>(this) + colorsOffset);\n    }\n\n} __attribute__((packed));\n\n/** ********************************************************************\n *  Base Types\n *\n *  These are standard types that are shared between multiple specific\n *  resource types.\n *\n *********************************************************************** */\n\n/**\n * Header that appears at the front of every data chunk in a resource.\n */\nstruct ResChunk_header\n{\n    // Type identifier for this chunk.  The meaning of this value depends\n    // on the containing chunk.\n    uint16_t type;\n\n    // Size of the chunk header (in bytes).  Adding this value to\n    // the address of the chunk allows you to find its associated data\n    // (if any).\n    uint16_t headerSize;\n\n    // Total size of this chunk (in bytes).  This is the chunkSize plus\n    // the size of any data associated with the chunk.  Adding this value\n    // to the chunk allows you to completely skip its contents (including\n    // any child chunks).  If this value is the same as chunkSize, there is\n    // no data associated with the chunk.\n    uint32_t size;\n};\n\nenum {\n    RES_NULL_TYPE               = 0x0000,\n    RES_STRING_POOL_TYPE        = 0x0001,\n    RES_TABLE_TYPE              = 0x0002,\n    RES_XML_TYPE                = 0x0003,\n\n    // Chunk types in RES_XML_TYPE\n    RES_XML_FIRST_CHUNK_TYPE    = 0x0100,\n    RES_XML_START_NAMESPACE_TYPE= 0x0100,\n    RES_XML_END_NAMESPACE_TYPE  = 0x0101,\n    RES_XML_START_ELEMENT_TYPE  = 0x0102,\n    RES_XML_END_ELEMENT_TYPE    = 0x0103,\n    RES_XML_CDATA_TYPE          = 0x0104,\n    RES_XML_LAST_CHUNK_TYPE     = 0x017f,\n    // This contains a uint32_t array mapping strings in the string\n    // pool back to resource identifiers.  It is optional.\n    RES_XML_RESOURCE_MAP_TYPE   = 0x0180,\n\n    // Chunk types in RES_TABLE_TYPE\n    RES_TABLE_PACKAGE_TYPE      = 0x0200,\n    RES_TABLE_TYPE_TYPE         = 0x0201,\n    RES_TABLE_TYPE_SPEC_TYPE    = 0x0202,\n    RES_TABLE_LIBRARY_TYPE      = 0x0203\n};\n\n/**\n * Macros for building/splitting resource identifiers.\n */\n#define Res_VALIDID(resid) (resid != 0)\n#define Res_CHECKID(resid) ((resid&0xFFFF0000) != 0)\n#define Res_MAKEID(package, type, entry) \\\n    (((package+1)<<24) | (((type+1)&0xFF)<<16) | (entry&0xFFFF))\n#define Res_GETPACKAGE(id) ((id>>24)-1)\n#define Res_GETTYPE(id) (((id>>16)&0xFF)-1)\n#define Res_GETENTRY(id) (id&0xFFFF)\n\n#define Res_INTERNALID(resid) ((resid&0xFFFF0000) != 0 && (resid&0xFF0000) == 0)\n#define Res_MAKEINTERNAL(entry) (0x01000000 | (entry&0xFFFF))\n#define Res_MAKEARRAY(entry) (0x02000000 | (entry&0xFFFF))\n\n#define Res_MAXPACKAGE 255\n#define Res_MAXTYPE 255\n\n/**\n * Representation of a value in a resource, supplying type\n * information.\n */\nstruct Res_value\n{\n    // Number of bytes in this structure.\n    uint16_t size;\n\n    // Always set to 0.\n    uint8_t res0;\n        \n    // Type of the data value.\n    enum {\n        // Contains no data.\n        TYPE_NULL = 0x00,\n        // The 'data' holds a ResTable_ref, a reference to another resource\n        // table entry.\n        TYPE_REFERENCE = 0x01,\n        // The 'data' holds an attribute resource identifier.\n        TYPE_ATTRIBUTE = 0x02,\n        // The 'data' holds an index into the containing resource table's\n        // global value string pool.\n        TYPE_STRING = 0x03,\n        // The 'data' holds a single-precision floating point number.\n        TYPE_FLOAT = 0x04,\n        // The 'data' holds a complex number encoding a dimension value,\n        // such as \"100in\".\n        TYPE_DIMENSION = 0x05,\n        // The 'data' holds a complex number encoding a fraction of a\n        // container.\n        TYPE_FRACTION = 0x06,\n        // The 'data' holds a dynamic ResTable_ref, which needs to be\n        // resolved before it can be used like a TYPE_REFERENCE.\n        TYPE_DYNAMIC_REFERENCE = 0x07,\n\n        // Beginning of integer flavors...\n        TYPE_FIRST_INT = 0x10,\n\n        // The 'data' is a raw integer value of the form n..n.\n        TYPE_INT_DEC = 0x10,\n        // The 'data' is a raw integer value of the form 0xn..n.\n        TYPE_INT_HEX = 0x11,\n        // The 'data' is either 0 or 1, for input \"false\" or \"true\" respectively.\n        TYPE_INT_BOOLEAN = 0x12,\n\n        // Beginning of color integer flavors...\n        TYPE_FIRST_COLOR_INT = 0x1c,\n\n        // The 'data' is a raw integer value of the form #aarrggbb.\n        TYPE_INT_COLOR_ARGB8 = 0x1c,\n        // The 'data' is a raw integer value of the form #rrggbb.\n        TYPE_INT_COLOR_RGB8 = 0x1d,\n        // The 'data' is a raw integer value of the form #argb.\n        TYPE_INT_COLOR_ARGB4 = 0x1e,\n        // The 'data' is a raw integer value of the form #rgb.\n        TYPE_INT_COLOR_RGB4 = 0x1f,\n\n        // ...end of integer flavors.\n        TYPE_LAST_COLOR_INT = 0x1f,\n\n        // ...end of integer flavors.\n        TYPE_LAST_INT = 0x1f\n    };\n    uint8_t dataType;\n\n    // Structure of complex data values (TYPE_UNIT and TYPE_FRACTION)\n    enum {\n        // Where the unit type information is.  This gives us 16 possible\n        // types, as defined below.\n        COMPLEX_UNIT_SHIFT = 0,\n        COMPLEX_UNIT_MASK = 0xf,\n\n        // TYPE_DIMENSION: Value is raw pixels.\n        COMPLEX_UNIT_PX = 0,\n        // TYPE_DIMENSION: Value is Device Independent Pixels.\n        COMPLEX_UNIT_DIP = 1,\n        // TYPE_DIMENSION: Value is a Scaled device independent Pixels.\n        COMPLEX_UNIT_SP = 2,\n        // TYPE_DIMENSION: Value is in points.\n        COMPLEX_UNIT_PT = 3,\n        // TYPE_DIMENSION: Value is in inches.\n        COMPLEX_UNIT_IN = 4,\n        // TYPE_DIMENSION: Value is in millimeters.\n        COMPLEX_UNIT_MM = 5,\n\n        // TYPE_FRACTION: A basic fraction of the overall size.\n        COMPLEX_UNIT_FRACTION = 0,\n        // TYPE_FRACTION: A fraction of the parent size.\n        COMPLEX_UNIT_FRACTION_PARENT = 1,\n\n        // Where the radix information is, telling where the decimal place\n        // appears in the mantissa.  This give us 4 possible fixed point\n        // representations as defined below.\n        COMPLEX_RADIX_SHIFT = 4,\n        COMPLEX_RADIX_MASK = 0x3,\n\n        // The mantissa is an integral number -- i.e., 0xnnnnnn.0\n        COMPLEX_RADIX_23p0 = 0,\n        // The mantissa magnitude is 16 bits -- i.e, 0xnnnn.nn\n        COMPLEX_RADIX_16p7 = 1,\n        // The mantissa magnitude is 8 bits -- i.e, 0xnn.nnnn\n        COMPLEX_RADIX_8p15 = 2,\n        // The mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn\n        COMPLEX_RADIX_0p23 = 3,\n\n        // Where the actual value is.  This gives us 23 bits of\n        // precision.  The top bit is the sign.\n        COMPLEX_MANTISSA_SHIFT = 8,\n        COMPLEX_MANTISSA_MASK = 0xffffff\n    };\n\n    // The data for this item, as interpreted according to dataType.\n    uint32_t data;\n\n    void copyFrom_dtoh(const Res_value& src);\n};\n\n/**\n *  This is a reference to a unique entry (a ResTable_entry structure)\n *  in a resource table.  The value is structured as: 0xpptteeee,\n *  where pp is the package index, tt is the type index in that\n *  package, and eeee is the entry index in that type.  The package\n *  and type values start at 1 for the first item, to help catch cases\n *  where they have not been supplied.\n */\nstruct ResTable_ref\n{\n    uint32_t ident;\n};\n\n/**\n * Reference to a string in a string pool.\n */\nstruct ResStringPool_ref\n{\n    // Index into the string pool table (uint32_t-offset from the indices\n    // immediately after ResStringPool_header) at which to find the location\n    // of the string data in the pool.\n    uint32_t index;\n};\n\n/** ********************************************************************\n *  String Pool\n *\n *  A set of strings that can be references by others through a\n *  ResStringPool_ref.\n *\n *********************************************************************** */\n\n/**\n * Definition for a pool of strings.  The data of this chunk is an\n * array of uint32_t providing indices into the pool, relative to\n * stringsStart.  At stringsStart are all of the UTF-16 strings\n * concatenated together; each starts with a uint16_t of the string's\n * length and each ends with a 0x0000 terminator.  If a string is >\n * 32767 characters, the high bit of the length is set meaning to take\n * those 15 bits as a high word and it will be followed by another\n * uint16_t containing the low word.\n *\n * If styleCount is not zero, then immediately following the array of\n * uint32_t indices into the string table is another array of indices\n * into a style table starting at stylesStart.  Each entry in the\n * style table is an array of ResStringPool_span structures.\n */\nstruct ResStringPool_header\n{\n    struct ResChunk_header header;\n\n    // Number of strings in this pool (number of uint32_t indices that follow\n    // in the data).\n    uint32_t stringCount;\n\n    // Number of style span arrays in the pool (number of uint32_t indices\n    // follow the string indices).\n    uint32_t styleCount;\n\n    // Flags.\n    enum {\n        // If set, the string index is sorted by the string values (based\n        // on strcmp16()).\n        SORTED_FLAG = 1<<0,\n\n        // String pool is encoded in UTF-8\n        UTF8_FLAG = 1<<8\n    };\n    uint32_t flags;\n\n    // Index from header of the string data.\n    uint32_t stringsStart;\n\n    // Index from header of the style data.\n    uint32_t stylesStart;\n};\n\n/**\n * This structure defines a span of style information associated with\n * a string in the pool.\n */\nstruct ResStringPool_span\n{\n    enum {\n        END = 0xFFFFFFFF\n    };\n\n    // This is the name of the span -- that is, the name of the XML\n    // tag that defined it.  The special value END (0xFFFFFFFF) indicates\n    // the end of an array of spans.\n    ResStringPool_ref name;\n\n    // The range of characters in the string that this span applies to.\n    uint32_t firstChar, lastChar;\n};\n\n/**\n * Convenience class for accessing data in a ResStringPool resource.\n */\nclass ResStringPool\n{\npublic:\n    ResStringPool();\n    ResStringPool(const void* data, size_t size, bool copyData=false);\n    ~ResStringPool();\n\n    void setToEmpty();\n    status_t setTo(const void* data, size_t size, bool copyData=false);\n\n    status_t getError() const;\n\n    void uninit();\n\n    // Return string entry as UTF16; if the pool is UTF8, the string will\n    // be converted before returning.\n    inline const char16_t* stringAt(const ResStringPool_ref& ref, size_t* outLen) const {\n        return stringAt(ref.index, outLen);\n    }\n    const char16_t* stringAt(size_t idx, size_t* outLen) const;\n\n    // Note: returns null if the string pool is not UTF8.\n    const char* string8At(size_t idx, size_t* outLen) const;\n\n    // Return string whether the pool is UTF8 or UTF16.  Does not allow you\n    // to distinguish null.\n    const String8 string8ObjectAt(size_t idx) const;\n\n    const ResStringPool_span* styleAt(const ResStringPool_ref& ref) const;\n    const ResStringPool_span* styleAt(size_t idx) const;\n\n    ssize_t indexOfString(const char16_t* str, size_t strLen) const;\n\n    size_t size() const;\n    size_t styleCount() const;\n    size_t bytes() const;\n\n    bool isSorted() const;\n    bool isUTF8() const;\n\nprivate:\n    status_t                    mError;\n    void*                       mOwnedData;\n    const ResStringPool_header* mHeader;\n    size_t                      mSize;\n    mutable Mutex               mDecodeLock;\n    const uint32_t*             mEntries;\n    const uint32_t*             mEntryStyles;\n    const void*                 mStrings;\n    char16_t mutable**          mCache;\n    uint32_t                    mStringPoolSize;    // number of uint16_t\n    const uint32_t*             mStyles;\n    uint32_t                    mStylePoolSize;    // number of uint32_t\n};\n\n/**\n * Wrapper class that allows the caller to retrieve a string from\n * a string pool without knowing which string pool to look.\n */\nclass StringPoolRef {\npublic:\n    StringPoolRef();\n    StringPoolRef(const ResStringPool* pool, uint32_t index);\n\n    const char* string8(size_t* outLen) const;\n    const char16_t* string16(size_t* outLen) const;\n\nprivate:\n    const ResStringPool*        mPool;\n    uint32_t                    mIndex;\n};\n\n/** ********************************************************************\n *  XML Tree\n *\n *  Binary representation of an XML document.  This is designed to\n *  express everything in an XML document, in a form that is much\n *  easier to parse on the device.\n *\n *********************************************************************** */\n\n/**\n * XML tree header.  This appears at the front of an XML tree,\n * describing its content.  It is followed by a flat array of\n * ResXMLTree_node structures; the hierarchy of the XML document\n * is described by the occurrance of RES_XML_START_ELEMENT_TYPE\n * and corresponding RES_XML_END_ELEMENT_TYPE nodes in the array.\n */\nstruct ResXMLTree_header\n{\n    struct ResChunk_header header;\n};\n\n/**\n * Basic XML tree node.  A single item in the XML document.  Extended info\n * about the node can be found after header.headerSize.\n */\nstruct ResXMLTree_node\n{\n    struct ResChunk_header header;\n\n    // Line number in original source file at which this element appeared.\n    uint32_t lineNumber;\n\n    // Optional XML comment that was associated with this element; -1 if none.\n    struct ResStringPool_ref comment;\n};\n\n/**\n * Extended XML tree node for CDATA tags -- includes the CDATA string.\n * Appears header.headerSize bytes after a ResXMLTree_node.\n */\nstruct ResXMLTree_cdataExt\n{\n    // The raw CDATA character data.\n    struct ResStringPool_ref data;\n    \n    // The typed value of the character data if this is a CDATA node.\n    struct Res_value typedData;\n};\n\n/**\n * Extended XML tree node for namespace start/end nodes.\n * Appears header.headerSize bytes after a ResXMLTree_node.\n */\nstruct ResXMLTree_namespaceExt\n{\n    // The prefix of the namespace.\n    struct ResStringPool_ref prefix;\n    \n    // The URI of the namespace.\n    struct ResStringPool_ref uri;\n};\n\n/**\n * Extended XML tree node for element start/end nodes.\n * Appears header.headerSize bytes after a ResXMLTree_node.\n */\nstruct ResXMLTree_endElementExt\n{\n    // String of the full namespace of this element.\n    struct ResStringPool_ref ns;\n    \n    // String name of this node if it is an ELEMENT; the raw\n    // character data if this is a CDATA node.\n    struct ResStringPool_ref name;\n};\n\n/**\n * Extended XML tree node for start tags -- includes attribute\n * information.\n * Appears header.headerSize bytes after a ResXMLTree_node.\n */\nstruct ResXMLTree_attrExt\n{\n    // String of the full namespace of this element.\n    struct ResStringPool_ref ns;\n    \n    // String name of this node if it is an ELEMENT; the raw\n    // character data if this is a CDATA node.\n    struct ResStringPool_ref name;\n    \n    // Byte offset from the start of this structure where the attributes start.\n    uint16_t attributeStart;\n    \n    // Size of the ResXMLTree_attribute structures that follow.\n    uint16_t attributeSize;\n    \n    // Number of attributes associated with an ELEMENT.  These are\n    // available as an array of ResXMLTree_attribute structures\n    // immediately following this node.\n    uint16_t attributeCount;\n    \n    // Index (1-based) of the \"id\" attribute. 0 if none.\n    uint16_t idIndex;\n    \n    // Index (1-based) of the \"class\" attribute. 0 if none.\n    uint16_t classIndex;\n    \n    // Index (1-based) of the \"style\" attribute. 0 if none.\n    uint16_t styleIndex;\n};\n\nstruct ResXMLTree_attribute\n{\n    // Namespace of this attribute.\n    struct ResStringPool_ref ns;\n    \n    // Name of this attribute.\n    struct ResStringPool_ref name;\n\n    // The original raw string value of this attribute.\n    struct ResStringPool_ref rawValue;\n    \n    // Processesd typed value of this attribute.\n    struct Res_value typedValue;\n};\n\nclass ResXMLTree;\n\nclass ResXMLParser\n{\npublic:\n    ResXMLParser(const ResXMLTree& tree);\n\n    enum event_code_t {\n        BAD_DOCUMENT = -1,\n        START_DOCUMENT = 0,\n        END_DOCUMENT = 1,\n        \n        FIRST_CHUNK_CODE = RES_XML_FIRST_CHUNK_TYPE, \n        \n        START_NAMESPACE = RES_XML_START_NAMESPACE_TYPE,\n        END_NAMESPACE = RES_XML_END_NAMESPACE_TYPE,\n        START_TAG = RES_XML_START_ELEMENT_TYPE,\n        END_TAG = RES_XML_END_ELEMENT_TYPE,\n        TEXT = RES_XML_CDATA_TYPE\n    };\n\n    struct ResXMLPosition\n    {\n        event_code_t                eventCode;\n        const ResXMLTree_node*      curNode;\n        const void*                 curExt;\n    };\n\n    void restart();\n\n    const ResStringPool& getStrings() const;\n\n    event_code_t getEventType() const;\n    // Note, unlike XmlPullParser, the first call to next() will return\n    // START_TAG of the first element.\n    event_code_t next();\n\n    // These are available for all nodes:\n    int32_t getCommentID() const;\n    const uint16_t* getComment(size_t* outLen) const;\n    uint32_t getLineNumber() const;\n    \n    // This is available for TEXT:\n    int32_t getTextID() const;\n    const uint16_t* getText(size_t* outLen) const;\n    ssize_t getTextValue(Res_value* outValue) const;\n    \n    // These are available for START_NAMESPACE and END_NAMESPACE:\n    int32_t getNamespacePrefixID() const;\n    const uint16_t* getNamespacePrefix(size_t* outLen) const;\n    int32_t getNamespaceUriID() const;\n    const uint16_t* getNamespaceUri(size_t* outLen) const;\n    \n    // These are available for START_TAG and END_TAG:\n    int32_t getElementNamespaceID() const;\n    const uint16_t* getElementNamespace(size_t* outLen) const;\n    int32_t getElementNameID() const;\n    const uint16_t* getElementName(size_t* outLen) const;\n    \n    // Remaining methods are for retrieving information about attributes\n    // associated with a START_TAG:\n    \n    size_t getAttributeCount() const;\n    \n    // Returns -1 if no namespace, -2 if idx out of range.\n    int32_t getAttributeNamespaceID(size_t idx) const;\n    const uint16_t* getAttributeNamespace(size_t idx, size_t* outLen) const;\n\n    int32_t getAttributeNameID(size_t idx) const;\n    const uint16_t* getAttributeName(size_t idx, size_t* outLen) const;\n    uint32_t getAttributeNameResID(size_t idx) const;\n\n    // These will work only if the underlying string pool is UTF-8.\n    const char* getAttributeNamespace8(size_t idx, size_t* outLen) const;\n    const char* getAttributeName8(size_t idx, size_t* outLen) const;\n\n    int32_t getAttributeValueStringID(size_t idx) const;\n    const uint16_t* getAttributeStringValue(size_t idx, size_t* outLen) const;\n    \n    int32_t getAttributeDataType(size_t idx) const;\n    int32_t getAttributeData(size_t idx) const;\n    ssize_t getAttributeValue(size_t idx, Res_value* outValue) const;\n\n    ssize_t indexOfAttribute(const char* ns, const char* attr) const;\n    ssize_t indexOfAttribute(const char16_t* ns, size_t nsLen,\n                             const char16_t* attr, size_t attrLen) const;\n\n    ssize_t indexOfID() const;\n    ssize_t indexOfClass() const;\n    ssize_t indexOfStyle() const;\n\n    void getPosition(ResXMLPosition* pos) const;\n    void setPosition(const ResXMLPosition& pos);\n\nprivate:\n    friend class ResXMLTree;\n    \n    event_code_t nextNode();\n\n    const ResXMLTree&           mTree;\n    event_code_t                mEventCode;\n    const ResXMLTree_node*      mCurNode;\n    const void*                 mCurExt;\n};\n\nclass DynamicRefTable;\n\n/**\n * Convenience class for accessing data in a ResXMLTree resource.\n */\nclass ResXMLTree : public ResXMLParser\n{\npublic:\n    ResXMLTree(const DynamicRefTable* dynamicRefTable);\n    ResXMLTree();\n    ~ResXMLTree();\n\n    status_t setTo(const void* data, size_t size, bool copyData=false);\n\n    status_t getError() const;\n\n    void uninit();\n\nprivate:\n    friend class ResXMLParser;\n\n    status_t validateNode(const ResXMLTree_node* node) const;\n\n    const DynamicRefTable* const mDynamicRefTable;\n\n    status_t                    mError;\n    void*                       mOwnedData;\n    const ResXMLTree_header*    mHeader;\n    size_t                      mSize;\n    const uint8_t*              mDataEnd;\n    ResStringPool               mStrings;\n    const uint32_t*             mResIds;\n    size_t                      mNumResIds;\n    const ResXMLTree_node*      mRootNode;\n    const void*                 mRootExt;\n    event_code_t                mRootCode;\n};\n\n/** ********************************************************************\n *  RESOURCE TABLE\n *\n *********************************************************************** */\n\n/**\n * Header for a resource table.  Its data contains a series of\n * additional chunks:\n *   * A ResStringPool_header containing all table values.  This string pool\n *     contains all of the string values in the entire resource table (not\n *     the names of entries or type identifiers however).\n *   * One or more ResTable_package chunks.\n *\n * Specific entries within a resource table can be uniquely identified\n * with a single integer as defined by the ResTable_ref structure.\n */\nstruct ResTable_header\n{\n    struct ResChunk_header header;\n\n    // The number of ResTable_package structures.\n    uint32_t packageCount;\n};\n\n/**\n * A collection of resource data types within a package.  Followed by\n * one or more ResTable_type and ResTable_typeSpec structures containing the\n * entry values for each resource type.\n */\nstruct ResTable_package\n{\n    struct ResChunk_header header;\n\n    // If this is a base package, its ID.  Package IDs start\n    // at 1 (corresponding to the value of the package bits in a\n    // resource identifier).  0 means this is not a base package.\n    uint32_t id;\n\n    // Actual name of this package, \\0-terminated.\n    char16_t name[128];\n\n    // Offset to a ResStringPool_header defining the resource\n    // type symbol table.  If zero, this package is inheriting from\n    // another base package (overriding specific values in it).\n    uint32_t typeStrings;\n\n    // Last index into typeStrings that is for public use by others.\n    uint32_t lastPublicType;\n\n    // Offset to a ResStringPool_header defining the resource\n    // key symbol table.  If zero, this package is inheriting from\n    // another base package (overriding specific values in it).\n    uint32_t keyStrings;\n\n    // Last index into keyStrings that is for public use by others.\n    uint32_t lastPublicKey;\n\n    uint32_t typeIdOffset;\n};\n\n// The most specific locale can consist of:\n//\n// - a 3 char language code\n// - a 3 char region code prefixed by a 'r'\n// - a 4 char script code prefixed by a 's'\n// - a 8 char variant code prefixed by a 'v'\n//\n// each separated by a single char separator, which sums up to a total of 24\n// chars, (25 include the string terminator) rounded up to 28 to be 4 byte\n// aligned.\n#define RESTABLE_MAX_LOCALE_LEN 28\n\n\n/**\n * Describes a particular resource configuration.\n */\nstruct ResTable_config\n{\n    // Number of bytes in this structure.\n    uint32_t size;\n    \n    union {\n        struct {\n            // Mobile country code (from SIM).  0 means \"any\".\n            uint16_t mcc;\n            // Mobile network code (from SIM).  0 means \"any\".\n            uint16_t mnc;\n        };\n        uint32_t imsi;\n    };\n    \n    union {\n        struct {\n            // This field can take three different forms:\n            // - \\0\\0 means \"any\".\n            //\n            // - Two 7 bit ascii values interpreted as ISO-639-1 language\n            //   codes ('fr', 'en' etc. etc.). The high bit for both bytes is\n            //   zero.\n            //\n            // - A single 16 bit little endian packed value representing an\n            //   ISO-639-2 3 letter language code. This will be of the form:\n            //\n            //   {1, t, t, t, t, t, s, s, s, s, s, f, f, f, f, f}\n            //\n            //   bit[0, 4] = first letter of the language code\n            //   bit[5, 9] = second letter of the language code\n            //   bit[10, 14] = third letter of the language code.\n            //   bit[15] = 1 always\n            //\n            // For backwards compatibility, languages that have unambiguous\n            // two letter codes are represented in that format.\n            //\n            // The layout is always bigendian irrespective of the runtime\n            // architecture.\n            char language[2];\n            \n            // This field can take three different forms:\n            // - \\0\\0 means \"any\".\n            //\n            // - Two 7 bit ascii values interpreted as 2 letter region\n            //   codes ('US', 'GB' etc.). The high bit for both bytes is zero.\n            //\n            // - An UN M.49 3 digit region code. For simplicity, these are packed\n            //   in the same manner as the language codes, though we should need\n            //   only 10 bits to represent them, instead of the 15.\n            //\n            // The layout is always bigendian irrespective of the runtime\n            // architecture.\n            char country[2];\n        };\n        uint32_t locale;\n    };\n    \n    enum {\n        ORIENTATION_ANY  = ACONFIGURATION_ORIENTATION_ANY,\n        ORIENTATION_PORT = ACONFIGURATION_ORIENTATION_PORT,\n        ORIENTATION_LAND = ACONFIGURATION_ORIENTATION_LAND,\n        ORIENTATION_SQUARE = ACONFIGURATION_ORIENTATION_SQUARE,\n    };\n    \n    enum {\n        TOUCHSCREEN_ANY  = ACONFIGURATION_TOUCHSCREEN_ANY,\n        TOUCHSCREEN_NOTOUCH  = ACONFIGURATION_TOUCHSCREEN_NOTOUCH,\n        TOUCHSCREEN_STYLUS  = ACONFIGURATION_TOUCHSCREEN_STYLUS,\n        TOUCHSCREEN_FINGER  = ACONFIGURATION_TOUCHSCREEN_FINGER,\n    };\n    \n    enum {\n        DENSITY_DEFAULT = ACONFIGURATION_DENSITY_DEFAULT,\n        DENSITY_LOW = ACONFIGURATION_DENSITY_LOW,\n        DENSITY_MEDIUM = ACONFIGURATION_DENSITY_MEDIUM,\n        DENSITY_TV = ACONFIGURATION_DENSITY_TV,\n        DENSITY_HIGH = ACONFIGURATION_DENSITY_HIGH,\n        DENSITY_XHIGH = ACONFIGURATION_DENSITY_XHIGH,\n        DENSITY_XXHIGH = ACONFIGURATION_DENSITY_XXHIGH,\n        DENSITY_XXXHIGH = ACONFIGURATION_DENSITY_XXXHIGH,\n        DENSITY_ANY = ACONFIGURATION_DENSITY_ANY,\n        DENSITY_NONE = ACONFIGURATION_DENSITY_NONE\n    };\n    \n    union {\n        struct {\n            uint8_t orientation;\n            uint8_t touchscreen;\n            uint16_t density;\n        };\n        uint32_t screenType;\n    };\n    \n    enum {\n        KEYBOARD_ANY  = ACONFIGURATION_KEYBOARD_ANY,\n        KEYBOARD_NOKEYS  = ACONFIGURATION_KEYBOARD_NOKEYS,\n        KEYBOARD_QWERTY  = ACONFIGURATION_KEYBOARD_QWERTY,\n        KEYBOARD_12KEY  = ACONFIGURATION_KEYBOARD_12KEY,\n    };\n    \n    enum {\n        NAVIGATION_ANY  = ACONFIGURATION_NAVIGATION_ANY,\n        NAVIGATION_NONAV  = ACONFIGURATION_NAVIGATION_NONAV,\n        NAVIGATION_DPAD  = ACONFIGURATION_NAVIGATION_DPAD,\n        NAVIGATION_TRACKBALL  = ACONFIGURATION_NAVIGATION_TRACKBALL,\n        NAVIGATION_WHEEL  = ACONFIGURATION_NAVIGATION_WHEEL,\n    };\n    \n    enum {\n        MASK_KEYSHIDDEN = 0x0003,\n        KEYSHIDDEN_ANY = ACONFIGURATION_KEYSHIDDEN_ANY,\n        KEYSHIDDEN_NO = ACONFIGURATION_KEYSHIDDEN_NO,\n        KEYSHIDDEN_YES = ACONFIGURATION_KEYSHIDDEN_YES,\n        KEYSHIDDEN_SOFT = ACONFIGURATION_KEYSHIDDEN_SOFT,\n    };\n    \n    enum {\n        MASK_NAVHIDDEN = 0x000c,\n        SHIFT_NAVHIDDEN = 2,\n        NAVHIDDEN_ANY = ACONFIGURATION_NAVHIDDEN_ANY << SHIFT_NAVHIDDEN,\n        NAVHIDDEN_NO = ACONFIGURATION_NAVHIDDEN_NO << SHIFT_NAVHIDDEN,\n        NAVHIDDEN_YES = ACONFIGURATION_NAVHIDDEN_YES << SHIFT_NAVHIDDEN,\n    };\n    \n    union {\n        struct {\n            uint8_t keyboard;\n            uint8_t navigation;\n            uint8_t inputFlags;\n            uint8_t inputPad0;\n        };\n        uint32_t input;\n    };\n    \n    enum {\n        SCREENWIDTH_ANY = 0\n    };\n    \n    enum {\n        SCREENHEIGHT_ANY = 0\n    };\n    \n    union {\n        struct {\n            uint16_t screenWidth;\n            uint16_t screenHeight;\n        };\n        uint32_t screenSize;\n    };\n    \n    enum {\n        SDKVERSION_ANY = 0\n    };\n    \n  enum {\n        MINORVERSION_ANY = 0\n    };\n    \n    union {\n        struct {\n            uint16_t sdkVersion;\n            // For now minorVersion must always be 0!!!  Its meaning\n            // is currently undefined.\n            uint16_t minorVersion;\n        };\n        uint32_t version;\n    };\n    \n    enum {\n        // screenLayout bits for screen size class.\n        MASK_SCREENSIZE = 0x0f,\n        SCREENSIZE_ANY = ACONFIGURATION_SCREENSIZE_ANY,\n        SCREENSIZE_SMALL = ACONFIGURATION_SCREENSIZE_SMALL,\n        SCREENSIZE_NORMAL = ACONFIGURATION_SCREENSIZE_NORMAL,\n        SCREENSIZE_LARGE = ACONFIGURATION_SCREENSIZE_LARGE,\n        SCREENSIZE_XLARGE = ACONFIGURATION_SCREENSIZE_XLARGE,\n        \n        // screenLayout bits for wide/long screen variation.\n        MASK_SCREENLONG = 0x30,\n        SHIFT_SCREENLONG = 4,\n        SCREENLONG_ANY = ACONFIGURATION_SCREENLONG_ANY << SHIFT_SCREENLONG,\n        SCREENLONG_NO = ACONFIGURATION_SCREENLONG_NO << SHIFT_SCREENLONG,\n        SCREENLONG_YES = ACONFIGURATION_SCREENLONG_YES << SHIFT_SCREENLONG,\n\n        // screenLayout bits for layout direction.\n        MASK_LAYOUTDIR = 0xC0,\n        SHIFT_LAYOUTDIR = 6,\n        LAYOUTDIR_ANY = ACONFIGURATION_LAYOUTDIR_ANY << SHIFT_LAYOUTDIR,\n        LAYOUTDIR_LTR = ACONFIGURATION_LAYOUTDIR_LTR << SHIFT_LAYOUTDIR,\n        LAYOUTDIR_RTL = ACONFIGURATION_LAYOUTDIR_RTL << SHIFT_LAYOUTDIR,\n    };\n    \n    enum {\n        // uiMode bits for the mode type.\n        MASK_UI_MODE_TYPE = 0x0f,\n        UI_MODE_TYPE_ANY = ACONFIGURATION_UI_MODE_TYPE_ANY,\n        UI_MODE_TYPE_NORMAL = ACONFIGURATION_UI_MODE_TYPE_NORMAL,\n        UI_MODE_TYPE_DESK = ACONFIGURATION_UI_MODE_TYPE_DESK,\n        UI_MODE_TYPE_CAR = ACONFIGURATION_UI_MODE_TYPE_CAR,\n        UI_MODE_TYPE_TELEVISION = ACONFIGURATION_UI_MODE_TYPE_TELEVISION,\n        UI_MODE_TYPE_APPLIANCE = ACONFIGURATION_UI_MODE_TYPE_APPLIANCE,\n        UI_MODE_TYPE_WATCH = ACONFIGURATION_UI_MODE_TYPE_WATCH,\n\n        // uiMode bits for the night switch.\n        MASK_UI_MODE_NIGHT = 0x30,\n        SHIFT_UI_MODE_NIGHT = 4,\n        UI_MODE_NIGHT_ANY = ACONFIGURATION_UI_MODE_NIGHT_ANY << SHIFT_UI_MODE_NIGHT,\n        UI_MODE_NIGHT_NO = ACONFIGURATION_UI_MODE_NIGHT_NO << SHIFT_UI_MODE_NIGHT,\n        UI_MODE_NIGHT_YES = ACONFIGURATION_UI_MODE_NIGHT_YES << SHIFT_UI_MODE_NIGHT,\n    };\n\n    union {\n        struct {\n            uint8_t screenLayout;\n            uint8_t uiMode;\n            uint16_t smallestScreenWidthDp;\n        };\n        uint32_t screenConfig;\n    };\n    \n    union {\n        struct {\n            uint16_t screenWidthDp;\n            uint16_t screenHeightDp;\n        };\n        uint32_t screenSizeDp;\n    };\n\n    // The ISO-15924 short name for the script corresponding to this\n    // configuration. (eg. Hant, Latn, etc.). Interpreted in conjunction with\n    // the locale field.\n    char localeScript[4];\n\n    // A single BCP-47 variant subtag. Will vary in length between 5 and 8\n    // chars. Interpreted in conjunction with the locale field.\n    char localeVariant[8];\n\n    void copyFromDeviceNoSwap(const ResTable_config& o);\n    \n    void copyFromDtoH(const ResTable_config& o);\n    \n    void swapHtoD();\n\n    int compare(const ResTable_config& o) const;\n    int compareLogical(const ResTable_config& o) const;\n\n    // Flags indicating a set of config values.  These flag constants must\n    // match the corresponding ones in android.content.pm.ActivityInfo and\n    // attrs_manifest.xml.\n    enum {\n        CONFIG_MCC = ACONFIGURATION_MCC,\n        CONFIG_MNC = ACONFIGURATION_MNC,\n        CONFIG_LOCALE = ACONFIGURATION_LOCALE,\n        CONFIG_TOUCHSCREEN = ACONFIGURATION_TOUCHSCREEN,\n        CONFIG_KEYBOARD = ACONFIGURATION_KEYBOARD,\n        CONFIG_KEYBOARD_HIDDEN = ACONFIGURATION_KEYBOARD_HIDDEN,\n        CONFIG_NAVIGATION = ACONFIGURATION_NAVIGATION,\n        CONFIG_ORIENTATION = ACONFIGURATION_ORIENTATION,\n        CONFIG_DENSITY = ACONFIGURATION_DENSITY,\n        CONFIG_SCREEN_SIZE = ACONFIGURATION_SCREEN_SIZE,\n        CONFIG_SMALLEST_SCREEN_SIZE = ACONFIGURATION_SMALLEST_SCREEN_SIZE,\n        CONFIG_VERSION = ACONFIGURATION_VERSION,\n        CONFIG_SCREEN_LAYOUT = ACONFIGURATION_SCREEN_LAYOUT,\n        CONFIG_UI_MODE = ACONFIGURATION_UI_MODE,\n        CONFIG_LAYOUTDIR = ACONFIGURATION_LAYOUTDIR,\n    };\n    \n    // Compare two configuration, returning CONFIG_* flags set for each value\n    // that is different.\n    int diff(const ResTable_config& o) const;\n    \n    // Return true if 'this' is more specific than 'o'.\n    bool isMoreSpecificThan(const ResTable_config& o) const;\n\n    // Return true if 'this' is a better match than 'o' for the 'requested'\n    // configuration.  This assumes that match() has already been used to\n    // remove any configurations that don't match the requested configuration\n    // at all; if they are not first filtered, non-matching results can be\n    // considered better than matching ones.\n    // The general rule per attribute: if the request cares about an attribute\n    // (it normally does), if the two (this and o) are equal it's a tie.  If\n    // they are not equal then one must be generic because only generic and\n    // '==requested' will pass the match() call.  So if this is not generic,\n    // it wins.  If this IS generic, o wins (return false).\n    bool isBetterThan(const ResTable_config& o, const ResTable_config* requested) const;\n\n    // Return true if 'this' can be considered a match for the parameters in \n    // 'settings'.\n    // Note this is asymetric.  A default piece of data will match every request\n    // but a request for the default should not match odd specifics\n    // (ie, request with no mcc should not match a particular mcc's data)\n    // settings is the requested settings\n    bool match(const ResTable_config& settings) const;\n\n    // Get the string representation of the locale component of this\n    // Config. The maximum size of this representation will be\n    // |RESTABLE_MAX_LOCALE_LEN| (including a terminating '\\0').\n    //\n    // Example: en-US, en-Latn-US, en-POSIX.\n    void getBcp47Locale(char* out) const;\n\n    // Sets the values of language, region, script and variant to the\n    // well formed BCP-47 locale contained in |in|. The input locale is\n    // assumed to be valid and no validation is performed.\n    void setBcp47Locale(const char* in);\n\n    inline void clearLocale() {\n        locale = 0;\n        memset(localeScript, 0, sizeof(localeScript));\n        memset(localeVariant, 0, sizeof(localeVariant));\n    }\n\n    // Get the 2 or 3 letter language code of this configuration. Trailing\n    // bytes are set to '\\0'.\n    size_t unpackLanguage(char language[4]) const;\n    // Get the 2 or 3 letter language code of this configuration. Trailing\n    // bytes are set to '\\0'.\n    size_t unpackRegion(char region[4]) const;\n\n    // Sets the language code of this configuration to the first three\n    // chars at |language|.\n    //\n    // If |language| is a 2 letter code, the trailing byte must be '\\0' or\n    // the BCP-47 separator '-'.\n    void packLanguage(const char* language);\n    // Sets the region code of this configuration to the first three bytes\n    // at |region|. If |region| is a 2 letter code, the trailing byte must be '\\0'\n    // or the BCP-47 separator '-'.\n    void packRegion(const char* region);\n\n    // Returns a positive integer if this config is more specific than |o|\n    // with respect to their locales, a negative integer if |o| is more specific\n    // and 0 if they're equally specific.\n    int isLocaleMoreSpecificThan(const ResTable_config &o) const;\n\n    String8 toString() const;\n};\n\n/**\n * A specification of the resources defined by a particular type.\n *\n * There should be one of these chunks for each resource type.\n *\n * This structure is followed by an array of integers providing the set of\n * configuration change flags (ResTable_config::CONFIG_*) that have multiple\n * resources for that configuration.  In addition, the high bit is set if that\n * resource has been made public.\n */\nstruct ResTable_typeSpec\n{\n    struct ResChunk_header header;\n\n    // The type identifier this chunk is holding.  Type IDs start\n    // at 1 (corresponding to the value of the type bits in a\n    // resource identifier).  0 is invalid.\n    uint8_t id;\n    \n    // Must be 0.\n    uint8_t res0;\n    // Must be 0.\n    uint16_t res1;\n    \n    // Number of uint32_t entry configuration masks that follow.\n    uint32_t entryCount;\n\n    enum {\n        // Additional flag indicating an entry is public.\n        SPEC_PUBLIC = 0x40000000\n    };\n};\n\n/**\n * A collection of resource entries for a particular resource data\n * type. Followed by an array of uint32_t defining the resource\n * values, corresponding to the array of type strings in the\n * ResTable_package::typeStrings string block. Each of these hold an\n * index from entriesStart; a value of NO_ENTRY means that entry is\n * not defined.\n *\n * There may be multiple of these chunks for a particular resource type,\n * supply different configuration variations for the resource values of\n * that type.\n *\n * It would be nice to have an additional ordered index of entries, so\n * we can do a binary search if trying to find a resource by string name.\n */\nstruct ResTable_type\n{\n    struct ResChunk_header header;\n\n    enum {\n        NO_ENTRY = 0xFFFFFFFF\n    };\n    \n    // The type identifier this chunk is holding.  Type IDs start\n    // at 1 (corresponding to the value of the type bits in a\n    // resource identifier).  0 is invalid.\n    uint8_t id;\n    \n    // Must be 0.\n    uint8_t res0;\n    // Must be 0.\n    uint16_t res1;\n    \n    // Number of uint32_t entry indices that follow.\n    uint32_t entryCount;\n\n    // Offset from header where ResTable_entry data starts.\n    uint32_t entriesStart;\n    \n    // Configuration this collection of entries is designed for.\n    ResTable_config config;\n};\n\n/**\n * This is the beginning of information about an entry in the resource\n * table.  It holds the reference to the name of this entry, and is\n * immediately followed by one of:\n *   * A Res_value structure, if FLAG_COMPLEX is -not- set.\n *   * An array of ResTable_map structures, if FLAG_COMPLEX is set.\n *     These supply a set of name/value mappings of data.\n */\nstruct ResTable_entry\n{\n    // Number of bytes in this structure.\n    uint16_t size;\n\n    enum {\n        // If set, this is a complex entry, holding a set of name/value\n        // mappings.  It is followed by an array of ResTable_map structures.\n        FLAG_COMPLEX = 0x0001,\n        // If set, this resource has been declared public, so libraries\n        // are allowed to reference it.\n        FLAG_PUBLIC = 0x0002\n    };\n    uint16_t flags;\n    \n    // Reference into ResTable_package::keyStrings identifying this entry.\n    struct ResStringPool_ref key;\n};\n\n/**\n * Extended form of a ResTable_entry for map entries, defining a parent map\n * resource from which to inherit values.\n */\nstruct ResTable_map_entry : public ResTable_entry\n{\n    // Resource identifier of the parent mapping, or 0 if there is none.\n    // This is always treated as a TYPE_DYNAMIC_REFERENCE.\n    ResTable_ref parent;\n    // Number of name/value pairs that follow for FLAG_COMPLEX.\n    uint32_t count;\n};\n\n/**\n * A single name/value mapping that is part of a complex resource\n * entry.\n */\nstruct ResTable_map\n{\n    // The resource identifier defining this mapping's name.  For attribute\n    // resources, 'name' can be one of the following special resource types\n    // to supply meta-data about the attribute; for all other resource types\n    // it must be an attribute resource.\n    ResTable_ref name;\n\n    // Special values for 'name' when defining attribute resources.\n    enum {\n        // This entry holds the attribute's type code.\n        ATTR_TYPE = Res_MAKEINTERNAL(0),\n\n        // For integral attributes, this is the minimum value it can hold.\n        ATTR_MIN = Res_MAKEINTERNAL(1),\n\n        // For integral attributes, this is the maximum value it can hold.\n        ATTR_MAX = Res_MAKEINTERNAL(2),\n\n        // Localization of this resource is can be encouraged or required with\n        // an aapt flag if this is set\n        ATTR_L10N = Res_MAKEINTERNAL(3),\n\n        // for plural support, see android.content.res.PluralRules#attrForQuantity(int)\n        ATTR_OTHER = Res_MAKEINTERNAL(4),\n        ATTR_ZERO = Res_MAKEINTERNAL(5),\n        ATTR_ONE = Res_MAKEINTERNAL(6),\n        ATTR_TWO = Res_MAKEINTERNAL(7),\n        ATTR_FEW = Res_MAKEINTERNAL(8),\n        ATTR_MANY = Res_MAKEINTERNAL(9)\n        \n    };\n\n    // Bit mask of allowed types, for use with ATTR_TYPE.\n    enum {\n        // No type has been defined for this attribute, use generic\n        // type handling.  The low 16 bits are for types that can be\n        // handled generically; the upper 16 require additional information\n        // in the bag so can not be handled generically for TYPE_ANY.\n        TYPE_ANY = 0x0000FFFF,\n\n        // Attribute holds a references to another resource.\n        TYPE_REFERENCE = 1<<0,\n\n        // Attribute holds a generic string.\n        TYPE_STRING = 1<<1,\n\n        // Attribute holds an integer value.  ATTR_MIN and ATTR_MIN can\n        // optionally specify a constrained range of possible integer values.\n        TYPE_INTEGER = 1<<2,\n\n        // Attribute holds a boolean integer.\n        TYPE_BOOLEAN = 1<<3,\n\n        // Attribute holds a color value.\n        TYPE_COLOR = 1<<4,\n\n        // Attribute holds a floating point value.\n        TYPE_FLOAT = 1<<5,\n\n        // Attribute holds a dimension value, such as \"20px\".\n        TYPE_DIMENSION = 1<<6,\n\n        // Attribute holds a fraction value, such as \"20%\".\n        TYPE_FRACTION = 1<<7,\n\n        // Attribute holds an enumeration.  The enumeration values are\n        // supplied as additional entries in the map.\n        TYPE_ENUM = 1<<16,\n\n        // Attribute holds a bitmaks of flags.  The flag bit values are\n        // supplied as additional entries in the map.\n        TYPE_FLAGS = 1<<17\n    };\n\n    // Enum of localization modes, for use with ATTR_L10N.\n    enum {\n        L10N_NOT_REQUIRED = 0,\n        L10N_SUGGESTED    = 1\n    };\n    \n    // This mapping's value.\n    Res_value value;\n};\n\n/**\n * A package-id to package name mapping for any shared libraries used\n * in this resource table. The package-id's encoded in this resource\n * table may be different than the id's assigned at runtime. We must\n * be able to translate the package-id's based on the package name.\n */\nstruct ResTable_lib_header\n{\n    struct ResChunk_header header;\n\n    // The number of shared libraries linked in this resource table.\n    uint32_t count;\n};\n\n/**\n * A shared library package-id to package name entry.\n */\nstruct ResTable_lib_entry\n{\n    // The package-id this shared library was assigned at build time.\n    // We use a uint32 to keep the structure aligned on a uint32 boundary.\n    uint32_t packageId;\n\n    // The package name of the shared library. \\0 terminated.\n    char16_t packageName[128];\n};\n\n/**\n * Holds the shared library ID table. Shared libraries are assigned package IDs at\n * build time, but they may be loaded in a different order, so we need to maintain\n * a mapping of build-time package ID to run-time assigned package ID.\n *\n * Dynamic references are not currently supported in overlays. Only the base package\n * may have dynamic references.\n */\nclass DynamicRefTable\n{\npublic:\n    DynamicRefTable(uint8_t packageId);\n\n    // Loads an unmapped reference table from the package.\n    status_t load(const ResTable_lib_header* const header);\n\n    // Adds mappings from the other DynamicRefTable\n    status_t addMappings(const DynamicRefTable& other);\n\n    // Creates a mapping from build-time package ID to run-time package ID for\n    // the given package.\n    status_t addMapping(const String16& packageName, uint8_t packageId);\n\n    // Performs the actual conversion of build-time resource ID to run-time\n    // resource ID.\n    inline status_t lookupResourceId(uint32_t* resId) const;\n    inline status_t lookupResourceValue(Res_value* value) const;\n\n    inline const KeyedVector<String16, uint8_t>& entries() const {\n        return mEntries;\n    }\n\nprivate:\n    const uint8_t                   mAssignedPackageId;\n    uint8_t                         mLookupTable[256];\n    KeyedVector<String16, uint8_t>  mEntries;\n};\n\n/**\n * Convenience class for accessing data in a ResTable resource.\n */\nclass ResTable\n{\npublic:\n    ResTable();\n    ResTable(const void* data, size_t size, const int32_t cookie,\n             bool copyData=false);\n    ~ResTable();\n\n    status_t add(const void* data, size_t size, const int32_t cookie=-1, bool copyData=false);\n    status_t add(const void* data, size_t size, const void* idmapData, size_t idmapDataSize,\n            const int32_t cookie=-1, bool copyData=false);\n\n    status_t add(Asset* asset, const int32_t cookie=-1, bool copyData=false);\n    status_t add(Asset* asset, Asset* idmapAsset, const int32_t cookie=-1, bool copyData=false);\n\n    status_t add(ResTable* src);\n    status_t addEmpty(const int32_t cookie);\n\n    status_t getError() const;\n\n    void uninit();\n\n    struct resource_name\n    {\n        const char16_t* package;\n        size_t packageLen;\n        const char16_t* type;\n        const char* type8;\n        size_t typeLen;\n        const char16_t* name;\n        const char* name8;\n        size_t nameLen;\n    };\n\n    bool getResourceName(uint32_t resID, bool allowUtf8, resource_name* outName) const;\n\n    bool getResourceFlags(uint32_t resID, uint32_t* outFlags) const;\n\n    /**\n     * Retrieve the value of a resource.  If the resource is found, returns a\n     * value >= 0 indicating the table it is in (for use with\n     * getTableStringBlock() and getTableCookie()) and fills in 'outValue'.  If\n     * not found, returns a negative error code.\n     *\n     * Note that this function does not do reference traversal.  If you want\n     * to follow references to other resources to get the \"real\" value to\n     * use, you need to call resolveReference() after this function.\n     *\n     * @param resID The desired resoruce identifier.\n     * @param outValue Filled in with the resource data that was found.\n     *\n     * @return ssize_t Either a >= 0 table index or a negative error code.\n     */\n    ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag = false,\n                    uint16_t density = 0,\n                    uint32_t* outSpecFlags = NULL,\n                    ResTable_config* outConfig = NULL) const;\n\n    inline ssize_t getResource(const ResTable_ref& res, Res_value* outValue,\n            uint32_t* outSpecFlags=NULL) const {\n        return getResource(res.ident, outValue, false, 0, outSpecFlags, NULL);\n    }\n\n    ssize_t resolveReference(Res_value* inOutValue,\n                             ssize_t blockIndex,\n                             uint32_t* outLastRef = NULL,\n                             uint32_t* inoutTypeSpecFlags = NULL,\n                             ResTable_config* outConfig = NULL) const;\n\n    enum {\n        TMP_BUFFER_SIZE = 16\n    };\n    const char16_t* valueToString(const Res_value* value, size_t stringBlock,\n                                  char16_t tmpBuffer[TMP_BUFFER_SIZE],\n                                  size_t* outLen) const;\n\n    struct bag_entry {\n        ssize_t stringBlock;\n        ResTable_map map;\n    };\n\n    /**\n     * Retrieve the bag of a resource.  If the resoruce is found, returns the\n     * number of bags it contains and 'outBag' points to an array of their\n     * values.  If not found, a negative error code is returned.\n     *\n     * Note that this function -does- do reference traversal of the bag data.\n     *\n     * @param resID The desired resource identifier.\n     * @param outBag Filled inm with a pointer to the bag mappings.\n     *\n     * @return ssize_t Either a >= 0 bag count of negative error code.\n     */\n    ssize_t lockBag(uint32_t resID, const bag_entry** outBag) const;\n\n    void unlockBag(const bag_entry* bag) const;\n\n    void lock() const;\n\n    ssize_t getBagLocked(uint32_t resID, const bag_entry** outBag,\n            uint32_t* outTypeSpecFlags=NULL) const;\n\n    void unlock() const;\n\n    class Theme {\n    public:\n        Theme(const ResTable& table);\n        ~Theme();\n\n        inline const ResTable& getResTable() const { return mTable; }\n\n        status_t applyStyle(uint32_t resID, bool force=false);\n        status_t setTo(const Theme& other);\n\n        /**\n         * Retrieve a value in the theme.  If the theme defines this\n         * value, returns a value >= 0 indicating the table it is in\n         * (for use with getTableStringBlock() and getTableCookie) and\n         * fills in 'outValue'.  If not found, returns a negative error\n         * code.\n         *\n         * Note that this function does not do reference traversal.  If you want\n         * to follow references to other resources to get the \"real\" value to\n         * use, you need to call resolveReference() after this function.\n         *\n         * @param resID A resource identifier naming the desired theme\n         *              attribute.\n         * @param outValue Filled in with the theme value that was\n         *                 found.\n         *\n         * @return ssize_t Either a >= 0 table index or a negative error code.\n         */\n        ssize_t getAttribute(uint32_t resID, Res_value* outValue,\n                uint32_t* outTypeSpecFlags = NULL) const;\n\n        /**\n         * This is like ResTable::resolveReference(), but also takes\n         * care of resolving attribute references to the theme.\n         */\n        ssize_t resolveAttributeReference(Res_value* inOutValue,\n                ssize_t blockIndex, uint32_t* outLastRef = NULL,\n                uint32_t* inoutTypeSpecFlags = NULL,\n                ResTable_config* inoutConfig = NULL) const;\n\n        void dumpToLog() const;\n        \n    private:\n        Theme(const Theme&);\n        Theme& operator=(const Theme&);\n\n        struct theme_entry {\n            ssize_t stringBlock;\n            uint32_t typeSpecFlags;\n            Res_value value;\n        };\n\n        struct type_info {\n            size_t numEntries;\n            theme_entry* entries;\n        };\n\n        struct package_info {\n            type_info types[Res_MAXTYPE + 1];\n        };\n\n        void free_package(package_info* pi);\n        package_info* copy_package(package_info* pi);\n\n        const ResTable& mTable;\n        package_info*   mPackages[Res_MAXPACKAGE];\n    };\n\n    void setParameters(const ResTable_config* params);\n    void getParameters(ResTable_config* params) const;\n\n    // Retrieve an identifier (which can be passed to getResource)\n    // for a given resource name.  The 'name' can be fully qualified\n    // (<package>:<type>.<basename>) or the package or type components\n    // can be dropped if default values are supplied here.\n    //\n    // Returns 0 if no such resource was found, else a valid resource ID.\n    uint32_t identifierForName(const char16_t* name, size_t nameLen,\n                               const char16_t* type = 0, size_t typeLen = 0,\n                               const char16_t* defPackage = 0,\n                               size_t defPackageLen = 0,\n                               uint32_t* outTypeSpecFlags = NULL) const;\n\n    static bool expandResourceRef(const uint16_t* refStr, size_t refLen,\n                                  String16* outPackage,\n                                  String16* outType,\n                                  String16* outName,\n                                  const String16* defType = NULL,\n                                  const String16* defPackage = NULL,\n                                  const char** outErrorMsg = NULL,\n                                  bool* outPublicOnly = NULL);\n\n    static bool stringToInt(const char16_t* s, size_t len, Res_value* outValue);\n    static bool stringToFloat(const char16_t* s, size_t len, Res_value* outValue);\n\n    // Used with stringToValue.\n    class Accessor\n    {\n    public:\n        inline virtual ~Accessor() { }\n\n        virtual const String16& getAssetsPackage() const = 0;\n\n        virtual uint32_t getCustomResource(const String16& package,\n                                           const String16& type,\n                                           const String16& name) const = 0;\n        virtual uint32_t getCustomResourceWithCreation(const String16& package,\n                                                       const String16& type,\n                                                       const String16& name,\n                                                       const bool createIfNeeded = false) = 0;\n        virtual uint32_t getRemappedPackage(uint32_t origPackage) const = 0;\n        virtual bool getAttributeType(uint32_t attrID, uint32_t* outType) = 0;\n        virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin) = 0;\n        virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax) = 0;\n        virtual bool getAttributeEnum(uint32_t attrID,\n                                      const char16_t* name, size_t nameLen,\n                                      Res_value* outValue) = 0;\n        virtual bool getAttributeFlags(uint32_t attrID,\n                                       const char16_t* name, size_t nameLen,\n                                       Res_value* outValue) = 0;\n        virtual uint32_t getAttributeL10N(uint32_t attrID) = 0;\n        virtual bool getLocalizationSetting() = 0;\n        virtual void reportError(void* accessorCookie, const char* fmt, ...) = 0;\n    };\n\n    // Convert a string to a resource value.  Handles standard \"@res\",\n    // \"#color\", \"123\", and \"0x1bd\" types; performs escaping of strings.\n    // The resulting value is placed in 'outValue'; if it is a string type,\n    // 'outString' receives the string.  If 'attrID' is supplied, the value is\n    // type checked against this attribute and it is used to perform enum\n    // evaluation.  If 'acccessor' is supplied, it will be used to attempt to\n    // resolve resources that do not exist in this ResTable.  If 'attrType' is\n    // supplied, the value will be type checked for this format if 'attrID'\n    // is not supplied or found.\n    bool stringToValue(Res_value* outValue, String16* outString,\n                       const char16_t* s, size_t len,\n                       bool preserveSpaces, bool coerceType,\n                       uint32_t attrID = 0,\n                       const String16* defType = NULL,\n                       const String16* defPackage = NULL,\n                       Accessor* accessor = NULL,\n                       void* accessorCookie = NULL,\n                       uint32_t attrType = ResTable_map::TYPE_ANY,\n                       bool enforcePrivate = true,\n                       bool printError = true) const;\n\n    // Perform processing of escapes and quotes in a string.\n    static bool collectString(String16* outString,\n                              const char16_t* s, size_t len,\n                              bool preserveSpaces,\n                              const char** outErrorMsg = NULL,\n                              bool append = false);\n\n    size_t getBasePackageCount() const;\n    const String16 getBasePackageName(size_t idx) const;\n    uint32_t getBasePackageId(size_t idx) const;\n    uint32_t getLastTypeIdForPackage(size_t idx) const;\n\n    // Return the number of resource tables that the object contains.\n    size_t getTableCount() const;\n    // Return the values string pool for the resource table at the given\n    // index.  This string pool contains all of the strings for values\n    // contained in the resource table -- that is the item values themselves,\n    // but not the names their entries or types.\n    const ResStringPool* getTableStringBlock(size_t index) const;\n    // Return unique cookie identifier for the given resource table.\n    int32_t getTableCookie(size_t index) const;\n\n    const DynamicRefTable* getDynamicRefTableForCookie(int32_t cookie) const;\n\n    // Return the configurations (ResTable_config) that we know about\n    void getConfigurations(Vector<ResTable_config>* configs) const;\n\n    void getLocales(Vector<String8>* locales) const;\n\n    // Generate an idmap.\n    //\n    // Return value: on success: NO_ERROR; caller is responsible for free-ing\n    // outData (using free(3)). On failure, any status_t value other than\n    // NO_ERROR; the caller should not free outData.\n    status_t createIdmap(const ResTable& overlay,\n            uint32_t targetCrc, uint32_t overlayCrc,\n            const char* targetPath, const char* overlayPath,\n            void** outData, size_t* outSize) const;\n\n    enum {\n        IDMAP_HEADER_SIZE_BYTES = 4 * sizeof(uint32_t) + 2 * 256,\n    };\n\n    // Retrieve idmap meta-data.\n    //\n    // This function only requires the idmap header (the first\n    // IDMAP_HEADER_SIZE_BYTES) bytes of an idmap file.\n    static bool getIdmapInfo(const void* idmap, size_t size,\n            uint32_t* pVersion,\n            uint32_t* pTargetCrc, uint32_t* pOverlayCrc,\n            String8* pTargetPath, String8* pOverlayPath);\n\n    void print(bool inclValues) const;\n    static String8 normalizeForOutput(const char* input);\n    KeyedVector<uint32_t, ResTable::resource_name> getResourceEntries() const;\n\nprivate:\n    struct Header;\n    struct Type;\n    struct Entry;\n    struct Package;\n    struct PackageGroup;\n    struct bag_set;\n    typedef Vector<Type*> TypeList;\n\n    status_t addInternal(const void* data, size_t size, const void* idmapData, size_t idmapDataSize,\n            const int32_t cookie, bool copyData);\n\n    ssize_t getResourcePackageIndex(uint32_t resID) const;\n\n    status_t getEntry(\n        const PackageGroup* packageGroup, int typeIndex, int entryIndex,\n        const ResTable_config* config,\n        Entry* outEntry) const;\n\n    status_t parsePackage(\n        const ResTable_package* const pkg, const Header* const header);\n\n    void print_value(const Package* pkg, const Res_value& value) const;\n    \n    mutable Mutex               mLock;\n\n    status_t                    mError;\n\n    ResTable_config             mParams;\n\n    // Array of all resource tables.\n    Vector<Header*>             mHeaders;\n\n    // Array of packages in all resource tables.\n    Vector<PackageGroup*>       mPackageGroups;\n\n    // Mapping from resource package IDs to indices into the internal\n    // package array.\n    uint8_t                     mPackageMap[256];\n\n    uint8_t                     mNextPackageId;\n};\n\n}   // namespace android\n\n#endif // _LIBS_UTILS_RESOURCE_TYPES_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/include/androidfw/StreamingZipInflater.h",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __LIBS_STREAMINGZIPINFLATER_H\n#define __LIBS_STREAMINGZIPINFLATER_H\n\n#include <unistd.h>\n#include <inttypes.h>\n#include <zlib.h>\n\n#include <utils/Compat.h>\n\nnamespace android {\n\nclass StreamingZipInflater {\npublic:\n    static const size_t INPUT_CHUNK_SIZE = 64 * 1024;\n    static const size_t OUTPUT_CHUNK_SIZE = 64 * 1024;\n\n    // Flavor that pages in the compressed data from a fd\n    StreamingZipInflater(int fd, off64_t compDataStart, size_t uncompSize, size_t compSize);\n\n    // Flavor that gets the compressed data from an in-memory buffer\n    StreamingZipInflater(class FileMap* dataMap, size_t uncompSize);\n\n    ~StreamingZipInflater();\n\n    // read 'count' bytes of uncompressed data from the current position.  outBuf may\n    // be NULL, in which case the data is consumed and discarded.\n    ssize_t read(void* outBuf, size_t count);\n\n    // seeking backwards requires uncompressing fom the beginning, so is very\n    // expensive.  seeking forwards only requires uncompressing from the current\n    // position to the destination.\n    off64_t seekAbsolute(off64_t absoluteInputPosition);\n\nprivate:\n    void initInflateState();\n    int readNextChunk();\n\n    // where to find the uncompressed data\n    int mFd;\n    off64_t mInFileStart;         // where the compressed data lives in the file\n    class FileMap* mDataMap;\n\n    z_stream mInflateState;\n    bool mStreamNeedsInit;\n\n    // output invariants for this asset\n    uint8_t* mOutBuf;           // output buf for decompressed bytes\n    size_t mOutBufSize;         // allocated size of mOutBuf\n    size_t mOutTotalSize;       // total uncompressed size of the blob\n\n    // current output state bookkeeping\n    off64_t mOutCurPosition;      // current position in total offset\n    size_t mOutLastDecoded;     // last decoded byte + 1 in mOutbuf\n    size_t mOutDeliverable;     // next undelivered byte of decoded output in mOutBuf\n\n    // input invariants\n    uint8_t* mInBuf;\n    size_t mInBufSize;          // allocated size of mInBuf;\n    size_t mInTotalSize;        // total size of compressed data for this blob\n\n    // input state bookkeeping\n    size_t mInNextChunkOffset;  // offset from start of blob at which the next input chunk lies\n    // the z_stream contains state about input block consumption\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/include/androidfw/TypeWrappers.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __TYPE_WRAPPERS_H\n#define __TYPE_WRAPPERS_H\n\n#include <androidfw/ResourceTypes.h>\n\nnamespace android {\n\nstruct TypeVariant {\n    TypeVariant(const ResTable_type* data)\n        : data(data) {}\n\n    class iterator {\n    public:\n        iterator& operator=(const iterator& rhs) {\n            mTypeVariant = rhs.mTypeVariant;\n            mIndex = rhs.mIndex;\n        }\n\n        bool operator==(const iterator& rhs) const {\n            return mTypeVariant == rhs.mTypeVariant && mIndex == rhs.mIndex;\n        }\n\n        bool operator!=(const iterator& rhs) const {\n            return mTypeVariant != rhs.mTypeVariant || mIndex != rhs.mIndex;\n        }\n\n        iterator operator++(int) {\n            uint32_t prevIndex = mIndex;\n            operator++();\n            return iterator(mTypeVariant, prevIndex);\n        }\n\n        const ResTable_entry* operator->() const {\n            return operator*();\n        }\n\n        uint32_t index() const {\n            return mIndex;\n        }\n\n        iterator& operator++();\n        const ResTable_entry* operator*() const;\n\n    private:\n        friend struct TypeVariant;\n        iterator(const TypeVariant* tv, uint32_t index)\n            : mTypeVariant(tv), mIndex(index) {}\n        const TypeVariant* mTypeVariant;\n        uint32_t mIndex;\n    };\n\n    iterator beginEntries() const {\n        return iterator(this, 0);\n    }\n\n    iterator endEntries() const {\n        return iterator(this, dtohl(data->entryCount));\n    }\n\n    const ResTable_type* data;\n};\n\n} // namespace android\n\n#endif // __TYPE_WRAPPERS_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/include/androidfw/ZipFileRO.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * Read-only access to Zip archives, with minimal heap allocation.\n *\n * This is similar to the more-complete ZipFile class, but no attempt\n * has been made to make them interchangeable.  This class operates under\n * a very different set of assumptions and constraints.\n *\n * One such assumption is that if you're getting file descriptors for\n * use with this class as a child of a fork() operation, you must be on\n * a pread() to guarantee correct operation. This is because pread() can\n * atomically read at a file offset without worrying about a lock around an\n * lseek() + read() pair.\n */\n#ifndef __LIBS_ZIPFILERO_H\n#define __LIBS_ZIPFILERO_H\n\n#include <utils/Compat.h>\n#include <utils/Errors.h>\n#include <utils/FileMap.h>\n#include <utils/threads.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <time.h>\n\ntypedef void* ZipArchiveHandle;\n\nnamespace android {\n\n/*\n * Trivial typedef to ensure that ZipEntryRO is not treated as a simple\n * integer.  We use NULL to indicate an invalid value.\n */\ntypedef void* ZipEntryRO;\n\n/*\n * Open a Zip archive for reading.\n *\n * Implemented as a thin wrapper over system/core/libziparchive.\n *\n * \"open\" and \"find entry by name\" are fast operations and use as little\n * memory as possible.\n *\n * We also support fast iteration over all entries in the file (with a\n * stable, but unspecified iteration order).\n *\n * NOTE: If this is used on file descriptors inherited from a fork() operation,\n * you must be on a platform that implements pread() to guarantee correctness\n * on the shared file descriptors.\n */\nclass ZipFileRO {\npublic:\n    /* Zip compression methods we support */\n    enum {\n        kCompressStored     = 0,        // no compression\n        kCompressDeflated   = 8,        // standard deflate\n    };\n\n    /*\n     * Open an archive.\n     */\n    static ZipFileRO* open(const char* zipFileName);\n\n    /*\n     * Find an entry, by name.  Returns the entry identifier, or NULL if\n     * not found.\n     */\n    ZipEntryRO findEntryByName(const char* entryName) const;\n\n\n    /*\n     * Start iterating over the list of entries in the zip file. Requires\n     * a matching call to endIteration with the same cookie.\n     */\n    bool startIteration(void** cookie);\n\n    /**\n     * Return the next entry in iteration order, or NULL if there are no more\n     * entries in this archive.\n     */\n    ZipEntryRO nextEntry(void* cookie);\n\n    void endIteration(void* cookie);\n\n    void releaseEntry(ZipEntryRO entry) const;\n\n    /*\n     * Return the #of entries in the Zip archive.\n     */\n    int getNumEntries();\n\n    /*\n     * Copy the filename into the supplied buffer.  Returns 0 on success,\n     * -1 if \"entry\" is invalid, or the filename length if it didn't fit.  The\n     * length, and the returned string, include the null-termination.\n     */\n    int getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen) const;\n\n    /*\n     * Get the vital stats for an entry.  Pass in NULL pointers for anything\n     * you don't need.\n     *\n     * \"*pOffset\" holds the Zip file offset of the entry's data.\n     *\n     * Returns \"false\" if \"entry\" is bogus or if the data in the Zip file\n     * appears to be bad.\n     */\n    bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,\n        size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const;\n\n    /*\n     * Create a new FileMap object that maps a subset of the archive.  For\n     * an uncompressed entry this effectively provides a pointer to the\n     * actual data, for a compressed entry this provides the input buffer\n     * for inflate().\n     */\n    FileMap* createEntryFileMap(ZipEntryRO entry) const;\n\n    /*\n     * Uncompress the data into a buffer.  Depending on the compression\n     * format, this is either an \"inflate\" operation or a memcpy.\n     *\n     * Use \"uncompLen\" from getEntryInfo() to determine the required\n     * buffer size.\n     *\n     * Returns \"true\" on success.\n     */\n    bool uncompressEntry(ZipEntryRO entry, void* buffer, size_t size) const;\n\n    /*\n     * Uncompress the data to an open file descriptor.\n     */\n    bool uncompressEntry(ZipEntryRO entry, int fd) const;\n\n    ~ZipFileRO();\n\nprivate:\n    /* these are private and not defined */\n    ZipFileRO(const ZipFileRO& src);\n    ZipFileRO& operator=(const ZipFileRO& src);\n\n    ZipFileRO(ZipArchiveHandle handle, char* fileName) : mHandle(handle),\n        mFileName(fileName)\n    {\n    }\n\n    const ZipArchiveHandle mHandle;\n    char* mFileName;\n};\n\n}; // namespace android\n\n#endif /*__LIBS_ZIPFILERO_H*/\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/include/androidfw/ZipUtils.h",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Miscellaneous zip/gzip utility functions.\n//\n#ifndef __LIBS_ZIPUTILS_H\n#define __LIBS_ZIPUTILS_H\n\n#include <stdio.h>\n#include <time.h>\n\nnamespace android {\n\n/*\n * Container class for utility functions, primarily for namespace reasons.\n */\nclass ZipUtils {\npublic:\n    /*\n     * General utility function for uncompressing \"deflate\" data from a file\n     * to a buffer.\n     */\n    static bool inflateToBuffer(FILE* fp, void* buf, long uncompressedLen,\n        long compressedLen);\n    static bool inflateToBuffer(int fd, void* buf, long uncompressedLen,\n        long compressedLen);\n    static bool inflateToBuffer(void *in, void* buf, long uncompressedLen,\n        long compressedLen);\n\n    /*\n     * Someday we might want to make this generic and handle bzip2 \".bz2\"\n     * files too.\n     *\n     * We could declare gzip to be a sub-class of zip that has exactly\n     * one always-compressed entry, but we currently want to treat Zip\n     * and gzip as distinct, so there's no value.\n     *\n     * The zlib library has some gzip utilities, but it has no interface\n     * for extracting the uncompressed length of the file (you do *not*\n     * want to gzseek to the end).\n     *\n     * Pass in a seeked file pointer for the gzip file.  If this is a gzip\n     * file, we set our return values appropriately and return \"true\" with\n     * the file seeked to the start of the compressed data.\n     */\n    static bool examineGzip(FILE* fp, int* pCompressionMethod,\n        long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32);\n\n    /*\n     * Utility function to convert ZIP's time format to a timespec struct.\n     */\n    static inline void zipTimeToTimespec(long when, struct tm* timespec) {\n        const long date = when >> 16;\n        timespec->tm_year = ((date >> 9) & 0x7F) + 80; // Zip is years since 1980\n        timespec->tm_mon = (date >> 5) & 0x0F;\n        timespec->tm_mday = date & 0x1F;\n\n        timespec->tm_hour = (when >> 11) & 0x1F;\n        timespec->tm_min = (when >> 5) & 0x3F;\n        timespec->tm_sec = (when & 0x1F) << 1;\n    }\nprivate:\n    ZipUtils() {}\n    ~ZipUtils() {}\n};\n\n}; // namespace android\n\n#endif /*__LIBS_ZIPUTILS_H*/\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/include/androidfw/misc.h",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <sys/types.h>\n\n//\n// Handy utility functions and portability code.\n//\n#ifndef _LIBS_ANDROID_FW_MISC_H\n#define _LIBS_ANDROID_FW_MISC_H\n\nnamespace android {\n\n/*\n * Some utility functions for working with files.  These could be made\n * part of a \"File\" class.\n */\ntypedef enum FileType {\n    kFileTypeUnknown = 0,\n    kFileTypeNonexistent,       // i.e. ENOENT\n    kFileTypeRegular,\n    kFileTypeDirectory,\n    kFileTypeCharDev,\n    kFileTypeBlockDev,\n    kFileTypeFifo,\n    kFileTypeSymlink,\n    kFileTypeSocket,\n} FileType;\n/* get the file's type; follows symlinks */\nFileType getFileType(const char* fileName);\n/* get the file's modification date; returns -1 w/errno set on failure */\ntime_t getFileModDate(const char* fileName);\n\n}; // namespace android\n\n#endif // _LIBS_ANDROID_FW_MISC_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/Android.mk",
    "content": "# Copyright (C) 2010 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nLOCAL_PATH:= $(call my-dir)\n\n# libandroidfw is partially built for the host (used by obbtool and others)\n# These files are common to host and target builds.\n\ncommonSources := \\\n    Asset.cpp \\\n    AssetDir.cpp \\\n    AssetManager.cpp \\\n    misc.cpp \\\n    ObbFile.cpp \\\n    ResourceTypes.cpp \\\n    StreamingZipInflater.cpp \\\n    TypeWrappers.cpp \\\n    ZipFileRO.cpp \\\n    ZipUtils.cpp\n\ndeviceSources := \\\n    $(commonSources) \\\n    BackupData.cpp \\\n    BackupHelpers.cpp \\\n    CursorWindow.cpp\n\nhostSources := \\\n    $(commonSources)\n\n# For the host\n# =====================================================\n\ninclude $(CLEAR_VARS)\n\nLOCAL_SRC_FILES:= $(hostSources)\n\nLOCAL_MODULE:= libandroidfw\n\nLOCAL_MODULE_TAGS := optional\n\nLOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS\nLOCAL_CFLAGS += -O0\n\nLOCAL_C_INCLUDES := \\\n\texternal/zlib\n\nLOCAL_STATIC_LIBRARIES := liblog libziparchive-host libutils\n\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\n\n# For the device\n# =====================================================\n\ninclude $(CLEAR_VARS)\n\nLOCAL_SRC_FILES:= $(deviceSources)\n\nLOCAL_SHARED_LIBRARIES := \\\n\tlibbinder \\\n\tliblog \\\n\tlibcutils \\\n\tlibutils \\\n\tlibz\n\nLOCAL_STATIC_LIBRARIES := libziparchive\nLOCAL_CFLAGS += -O0\n\nLOCAL_C_INCLUDES := \\\n    external/zlib \\\n    system/core/include\n\nLOCAL_MODULE:= libandroidfw\n\nLOCAL_MODULE_TAGS := optional\n\ninclude $(BUILD_SHARED_LIBRARY)\n\n\n# Include subdirectory makefiles\n# ============================================================\n\n# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework\n# team really wants is to build the stuff defined by this makefile.\nifeq (,$(ONE_SHOT_MAKEFILE))\ninclude $(call first-makefiles-under,$(LOCAL_PATH))\nendif\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/Asset.cpp",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Provide access to a read-only asset.\n//\n\n#define LOG_TAG \"asset\"\n//#define NDEBUG 0\n\n#include <androidfw/Asset.h>\n#include <androidfw/StreamingZipInflater.h>\n#include <androidfw/ZipFileRO.h>\n#include <androidfw/ZipUtils.h>\n#include <utils/Atomic.h>\n#include <utils/FileMap.h>\n#include <utils/Log.h>\n#include <utils/threads.h>\n\n#include <assert.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <memory.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <unistd.h>\n\nusing namespace android;\n\n#ifndef O_BINARY\n# define O_BINARY 0\n#endif\n\nstatic Mutex gAssetLock;\nstatic int32_t gCount = 0;\nstatic Asset* gHead = NULL;\nstatic Asset* gTail = NULL;\n\nint32_t Asset::getGlobalCount()\n{\n    AutoMutex _l(gAssetLock);\n    return gCount;\n}\n\nString8 Asset::getAssetAllocations()\n{\n    AutoMutex _l(gAssetLock);\n    String8 res;\n    Asset* cur = gHead;\n    while (cur != NULL) {\n        if (cur->isAllocated()) {\n            res.append(\"    \");\n            res.append(cur->getAssetSource());\n            off64_t size = (cur->getLength()+512)/1024;\n            char buf[64];\n            sprintf(buf, \": %dK\\n\", (int)size);\n            res.append(buf);\n        }\n        cur = cur->mNext;\n    }\n\n    return res;\n}\n\nAsset::Asset(void)\n    : mAccessMode(ACCESS_UNKNOWN)\n{\n    AutoMutex _l(gAssetLock);\n    gCount++;\n    mNext = mPrev = NULL;\n    if (gTail == NULL) {\n        gHead = gTail = this;\n    } else {\n        mPrev = gTail;\n        gTail->mNext = this;\n        gTail = this;\n    }\n    //ALOGI(\"Creating Asset %p #%d\\n\", this, gCount);\n}\n\nAsset::~Asset(void)\n{\n    AutoMutex _l(gAssetLock);\n    gCount--;\n    if (gHead == this) {\n        gHead = mNext;\n    }\n    if (gTail == this) {\n        gTail = mPrev;\n    }\n    if (mNext != NULL) {\n        mNext->mPrev = mPrev;\n    }\n    if (mPrev != NULL) {\n        mPrev->mNext = mNext;\n    }\n    mNext = mPrev = NULL;\n    //ALOGI(\"Destroying Asset in %p #%d\\n\", this, gCount);\n}\n\n/*\n * Create a new Asset from a file on disk.  There is a fair chance that\n * the file doesn't actually exist.\n *\n * We can use \"mode\" to decide how we want to go about it.\n */\n/*static*/ Asset* Asset::createFromFile(const char* fileName, AccessMode mode)\n{\n    _FileAsset* pAsset;\n    status_t result;\n    off64_t length;\n    int fd;\n\n    fd = open(fileName, O_RDONLY | O_BINARY);\n    if (fd < 0)\n        return NULL;\n\n    /*\n     * Under Linux, the lseek fails if we actually opened a directory.  To\n     * be correct we should test the file type explicitly, but since we\n     * always open things read-only it doesn't really matter, so there's\n     * no value in incurring the extra overhead of an fstat() call.\n     */\n    // TODO(kroot): replace this with fstat despite the plea above.\n#if 1\n    length = lseek64(fd, 0, SEEK_END);\n    if (length < 0) {\n        ::close(fd);\n        return NULL;\n    }\n    (void) lseek64(fd, 0, SEEK_SET);\n#else\n    struct stat st;\n    if (fstat(fd, &st) < 0) {\n        ::close(fd);\n        return NULL;\n    }\n\n    if (!S_ISREG(st.st_mode)) {\n        ::close(fd);\n        return NULL;\n    }\n#endif\n\n    pAsset = new _FileAsset;\n    result = pAsset->openChunk(fileName, fd, 0, length);\n    if (result != NO_ERROR) {\n        delete pAsset;\n        return NULL;\n    }\n\n    pAsset->mAccessMode = mode;\n    return pAsset;\n}\n\n\n/*\n * Create a new Asset from a compressed file on disk.  There is a fair chance\n * that the file doesn't actually exist.\n *\n * We currently support gzip files.  We might want to handle .bz2 someday.\n */\n/*static*/ Asset* Asset::createFromCompressedFile(const char* fileName,\n    AccessMode mode)\n{\n    _CompressedAsset* pAsset;\n    status_t result;\n    off64_t fileLen;\n    bool scanResult;\n    long offset;\n    int method;\n    long uncompressedLen, compressedLen;\n    int fd;\n\n    fd = open(fileName, O_RDONLY | O_BINARY);\n    if (fd < 0)\n        return NULL;\n\n    fileLen = lseek(fd, 0, SEEK_END);\n    if (fileLen < 0) {\n        ::close(fd);\n        return NULL;\n    }\n    (void) lseek(fd, 0, SEEK_SET);\n\n    /* want buffered I/O for the file scan; must dup so fclose() is safe */\n    FILE* fp = fdopen(dup(fd), \"rb\");\n    if (fp == NULL) {\n        ::close(fd);\n        return NULL;\n    }\n\n    unsigned long crc32;\n    scanResult = ZipUtils::examineGzip(fp, &method, &uncompressedLen,\n                    &compressedLen, &crc32);\n    offset = ftell(fp);\n    fclose(fp);\n    if (!scanResult) {\n        ALOGD(\"File '%s' is not in gzip format\\n\", fileName);\n        ::close(fd);\n        return NULL;\n    }\n\n    pAsset = new _CompressedAsset;\n    result = pAsset->openChunk(fd, offset, method, uncompressedLen,\n                compressedLen);\n    if (result != NO_ERROR) {\n        delete pAsset;\n        return NULL;\n    }\n\n    pAsset->mAccessMode = mode;\n    return pAsset;\n}\n\n\n#if 0\n/*\n * Create a new Asset from part of an open file.\n */\n/*static*/ Asset* Asset::createFromFileSegment(int fd, off64_t offset,\n    size_t length, AccessMode mode)\n{\n    _FileAsset* pAsset;\n    status_t result;\n\n    pAsset = new _FileAsset;\n    result = pAsset->openChunk(NULL, fd, offset, length);\n    if (result != NO_ERROR)\n        return NULL;\n\n    pAsset->mAccessMode = mode;\n    return pAsset;\n}\n\n/*\n * Create a new Asset from compressed data in an open file.\n */\n/*static*/ Asset* Asset::createFromCompressedData(int fd, off64_t offset,\n    int compressionMethod, size_t uncompressedLen, size_t compressedLen,\n    AccessMode mode)\n{\n    _CompressedAsset* pAsset;\n    status_t result;\n\n    pAsset = new _CompressedAsset;\n    result = pAsset->openChunk(fd, offset, compressionMethod,\n                uncompressedLen, compressedLen);\n    if (result != NO_ERROR)\n        return NULL;\n\n    pAsset->mAccessMode = mode;\n    return pAsset;\n}\n#endif\n\n/*\n * Create a new Asset from a memory mapping.\n */\n/*static*/ Asset* Asset::createFromUncompressedMap(FileMap* dataMap,\n    AccessMode mode)\n{\n    _FileAsset* pAsset;\n    status_t result;\n\n    pAsset = new _FileAsset;\n    result = pAsset->openChunk(dataMap);\n    if (result != NO_ERROR)\n        return NULL;\n\n    pAsset->mAccessMode = mode;\n    return pAsset;\n}\n\n/*\n * Create a new Asset from compressed data in a memory mapping.\n */\n/*static*/ Asset* Asset::createFromCompressedMap(FileMap* dataMap,\n    int method, size_t uncompressedLen, AccessMode mode)\n{\n    _CompressedAsset* pAsset;\n    status_t result;\n\n    pAsset = new _CompressedAsset;\n    result = pAsset->openChunk(dataMap, method, uncompressedLen);\n    if (result != NO_ERROR)\n        return NULL;\n\n    pAsset->mAccessMode = mode;\n    return pAsset;\n}\n\n\n/*\n * Do generic seek() housekeeping.  Pass in the offset/whence values from\n * the seek request, along with the current chunk offset and the chunk\n * length.\n *\n * Returns the new chunk offset, or -1 if the seek is illegal.\n */\noff64_t Asset::handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn)\n{\n    off64_t newOffset;\n\n    switch (whence) {\n    case SEEK_SET:\n        newOffset = offset;\n        break;\n    case SEEK_CUR:\n        newOffset = curPosn + offset;\n        break;\n    case SEEK_END:\n        newOffset = maxPosn + offset;\n        break;\n    default:\n        ALOGW(\"unexpected whence %d\\n\", whence);\n        // this was happening due to an off64_t size mismatch\n        assert(false);\n        return (off64_t) -1;\n    }\n\n    if (newOffset < 0 || newOffset > maxPosn) {\n        ALOGW(\"seek out of range: want %ld, end=%ld\\n\",\n            (long) newOffset, (long) maxPosn);\n        return (off64_t) -1;\n    }\n\n    return newOffset;\n}\n\n\n/*\n * ===========================================================================\n *      _FileAsset\n * ===========================================================================\n */\n\n/*\n * Constructor.\n */\n_FileAsset::_FileAsset(void)\n    : mStart(0), mLength(0), mOffset(0), mFp(NULL), mFileName(NULL), mMap(NULL), mBuf(NULL)\n{\n}\n\n/*\n * Destructor.  Release resources.\n */\n_FileAsset::~_FileAsset(void)\n{\n    close();\n}\n\n/*\n * Operate on a chunk of an uncompressed file.\n *\n * Zero-length chunks are allowed.\n */\nstatus_t _FileAsset::openChunk(const char* fileName, int fd, off64_t offset, size_t length)\n{\n    assert(mFp == NULL);    // no reopen\n    assert(mMap == NULL);\n    assert(fd >= 0);\n    assert(offset >= 0);\n\n    /*\n     * Seek to end to get file length.\n     */\n    off64_t fileLength;\n    fileLength = lseek64(fd, 0, SEEK_END);\n    if (fileLength == (off64_t) -1) {\n        // probably a bad file descriptor\n        ALOGD(\"failed lseek (errno=%d)\\n\", errno);\n        return UNKNOWN_ERROR;\n    }\n\n    if ((off64_t) (offset + length) > fileLength) {\n        ALOGD(\"start (%ld) + len (%ld) > end (%ld)\\n\",\n            (long) offset, (long) length, (long) fileLength);\n        return BAD_INDEX;\n    }\n\n    /* after fdopen, the fd will be closed on fclose() */\n    mFp = fdopen(fd, \"rb\");\n    if (mFp == NULL)\n        return UNKNOWN_ERROR;\n\n    mStart = offset;\n    mLength = length;\n    assert(mOffset == 0);\n\n    /* seek the FILE* to the start of chunk */\n    if (fseek(mFp, mStart, SEEK_SET) != 0) {\n        assert(false);\n    }\n\n    mFileName = fileName != NULL ? strdup(fileName) : NULL;\n\n    return NO_ERROR;\n}\n\n/*\n * Create the chunk from the map.\n */\nstatus_t _FileAsset::openChunk(FileMap* dataMap)\n{\n    assert(mFp == NULL);    // no reopen\n    assert(mMap == NULL);\n    assert(dataMap != NULL);\n\n    mMap = dataMap;\n    mStart = -1;            // not used\n    mLength = dataMap->getDataLength();\n    assert(mOffset == 0);\n\n    return NO_ERROR;\n}\n\n/*\n * Read a chunk of data.\n */\nssize_t _FileAsset::read(void* buf, size_t count)\n{\n    size_t maxLen;\n    size_t actual;\n\n    assert(mOffset >= 0 && mOffset <= mLength);\n\n    if (getAccessMode() == ACCESS_BUFFER) {\n        /*\n         * On first access, read or map the entire file.  The caller has\n         * requested buffer access, either because they're going to be\n         * using the buffer or because what they're doing has appropriate\n         * performance needs and access patterns.\n         */\n        if (mBuf == NULL)\n            getBuffer(false);\n    }\n\n    /* adjust count if we're near EOF */\n    maxLen = mLength - mOffset;\n    if (count > maxLen)\n        count = maxLen;\n\n    if (!count)\n        return 0;\n\n    if (mMap != NULL) {\n        /* copy from mapped area */\n        //printf(\"map read\\n\");\n        memcpy(buf, (char*)mMap->getDataPtr() + mOffset, count);\n        actual = count;\n    } else if (mBuf != NULL) {\n        /* copy from buffer */\n        //printf(\"buf read\\n\");\n        memcpy(buf, (char*)mBuf + mOffset, count);\n        actual = count;\n    } else {\n        /* read from the file */\n        //printf(\"file read\\n\");\n        if (ftell(mFp) != mStart + mOffset) {\n            ALOGE(\"Hosed: %ld != %ld+%ld\\n\",\n                ftell(mFp), (long) mStart, (long) mOffset);\n            assert(false);\n        }\n\n        /*\n         * This returns 0 on error or eof.  We need to use ferror() or feof()\n         * to tell the difference, but we don't currently have those on the\n         * device.  However, we know how much data is *supposed* to be in the\n         * file, so if we don't read the full amount we know something is\n         * hosed.\n         */\n        actual = fread(buf, 1, count, mFp);\n        if (actual == 0)        // something failed -- I/O error?\n            return -1;\n\n        assert(actual == count);\n    }\n\n    mOffset += actual;\n    return actual;\n}\n\n/*\n * Seek to a new position.\n */\noff64_t _FileAsset::seek(off64_t offset, int whence)\n{\n    off64_t newPosn;\n    off64_t actualOffset;\n\n    // compute new position within chunk\n    newPosn = handleSeek(offset, whence, mOffset, mLength);\n    if (newPosn == (off64_t) -1)\n        return newPosn;\n\n    actualOffset = mStart + newPosn;\n\n    if (mFp != NULL) {\n        if (fseek(mFp, (long) actualOffset, SEEK_SET) != 0)\n            return (off64_t) -1;\n    }\n\n    mOffset = actualOffset - mStart;\n    return mOffset;\n}\n\n/*\n * Close the asset.\n */\nvoid _FileAsset::close(void)\n{\n    if (mMap != NULL) {\n        mMap->release();\n        mMap = NULL;\n    }\n    if (mBuf != NULL) {\n        delete[] mBuf;\n        mBuf = NULL;\n    }\n\n    if (mFileName != NULL) {\n        free(mFileName);\n        mFileName = NULL;\n    }\n\n    if (mFp != NULL) {\n        // can only be NULL when called from destructor\n        // (otherwise we would never return this object)\n        fclose(mFp);\n        mFp = NULL;\n    }\n}\n\n/*\n * Return a read-only pointer to a buffer.\n *\n * We can either read the whole thing in or map the relevant piece of\n * the source file.  Ideally a map would be established at a higher\n * level and we'd be using a different object, but we didn't, so we\n * deal with it here.\n */\nconst void* _FileAsset::getBuffer(bool wordAligned)\n{\n    /* subsequent requests just use what we did previously */\n    if (mBuf != NULL)\n        return mBuf;\n    if (mMap != NULL) {\n        if (!wordAligned) {\n            return  mMap->getDataPtr();\n        }\n        return ensureAlignment(mMap);\n    }\n\n    assert(mFp != NULL);\n\n    if (mLength < kReadVsMapThreshold) {\n        unsigned char* buf;\n        long allocLen;\n\n        /* zero-length files are allowed; not sure about zero-len allocs */\n        /* (works fine with gcc + x86linux) */\n        allocLen = mLength;\n        if (mLength == 0)\n            allocLen = 1;\n\n        buf = new unsigned char[allocLen];\n        if (buf == NULL) {\n            ALOGE(\"alloc of %ld bytes failed\\n\", (long) allocLen);\n            return NULL;\n        }\n\n        ALOGV(\"Asset %p allocating buffer size %d (smaller than threshold)\", this, (int)allocLen);\n        if (mLength > 0) {\n            long oldPosn = ftell(mFp);\n            fseek(mFp, mStart, SEEK_SET);\n            if (fread(buf, 1, mLength, mFp) != (size_t) mLength) {\n                ALOGE(\"failed reading %ld bytes\\n\", (long) mLength);\n                delete[] buf;\n                return NULL;\n            }\n            fseek(mFp, oldPosn, SEEK_SET);\n        }\n\n        ALOGV(\" getBuffer: loaded into buffer\\n\");\n\n        mBuf = buf;\n        return mBuf;\n    } else {\n        FileMap* map;\n\n        map = new FileMap;\n        if (!map->create(NULL, fileno(mFp), mStart, mLength, true)) {\n            map->release();\n            return NULL;\n        }\n\n        ALOGV(\" getBuffer: mapped\\n\");\n\n        mMap = map;\n        if (!wordAligned) {\n            return  mMap->getDataPtr();\n        }\n        return ensureAlignment(mMap);\n    }\n}\n\nint _FileAsset::openFileDescriptor(off64_t* outStart, off64_t* outLength) const\n{\n    if (mMap != NULL) {\n        const char* fname = mMap->getFileName();\n        if (fname == NULL) {\n            fname = mFileName;\n        }\n        if (fname == NULL) {\n            return -1;\n        }\n        *outStart = mMap->getDataOffset();\n        *outLength = mMap->getDataLength();\n        return open(fname, O_RDONLY | O_BINARY);\n    }\n    if (mFileName == NULL) {\n        return -1;\n    }\n    *outStart = mStart;\n    *outLength = mLength;\n    return open(mFileName, O_RDONLY | O_BINARY);\n}\n\nconst void* _FileAsset::ensureAlignment(FileMap* map)\n{\n    void* data = map->getDataPtr();\n    if ((((size_t)data)&0x3) == 0) {\n        // We can return this directly if it is aligned on a word\n        // boundary.\n        ALOGV(\"Returning aligned FileAsset %p (%s).\", this,\n                getAssetSource());\n        return data;\n    }\n    // If not aligned on a word boundary, then we need to copy it into\n    // our own buffer.\n    ALOGV(\"Copying FileAsset %p (%s) to buffer size %d to make it aligned.\", this,\n            getAssetSource(), (int)mLength);\n    unsigned char* buf = new unsigned char[mLength];\n    if (buf == NULL) {\n        ALOGE(\"alloc of %ld bytes failed\\n\", (long) mLength);\n        return NULL;\n    }\n    memcpy(buf, data, mLength);\n    mBuf = buf;\n    return buf;\n}\n\n/*\n * ===========================================================================\n *      _CompressedAsset\n * ===========================================================================\n */\n\n/*\n * Constructor.\n */\n_CompressedAsset::_CompressedAsset(void)\n    : mStart(0), mCompressedLen(0), mUncompressedLen(0), mOffset(0),\n      mMap(NULL), mFd(-1), mZipInflater(NULL), mBuf(NULL)\n{\n}\n\n/*\n * Destructor.  Release resources.\n */\n_CompressedAsset::~_CompressedAsset(void)\n{\n    close();\n}\n\n/*\n * Open a chunk of compressed data inside a file.\n *\n * This currently just sets up some values and returns.  On the first\n * read, we expand the entire file into a buffer and return data from it.\n */\nstatus_t _CompressedAsset::openChunk(int fd, off64_t offset,\n    int compressionMethod, size_t uncompressedLen, size_t compressedLen)\n{\n    assert(mFd < 0);        // no re-open\n    assert(mMap == NULL);\n    assert(fd >= 0);\n    assert(offset >= 0);\n    assert(compressedLen > 0);\n\n    if (compressionMethod != ZipFileRO::kCompressDeflated) {\n        assert(false);\n        return UNKNOWN_ERROR;\n    }\n\n    mStart = offset;\n    mCompressedLen = compressedLen;\n    mUncompressedLen = uncompressedLen;\n    assert(mOffset == 0);\n    mFd = fd;\n    assert(mBuf == NULL);\n\n    if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) {\n        mZipInflater = new StreamingZipInflater(mFd, offset, uncompressedLen, compressedLen);\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Open a chunk of compressed data in a mapped region.\n *\n * Nothing is expanded until the first read call.\n */\nstatus_t _CompressedAsset::openChunk(FileMap* dataMap, int compressionMethod,\n    size_t uncompressedLen)\n{\n    assert(mFd < 0);        // no re-open\n    assert(mMap == NULL);\n    assert(dataMap != NULL);\n\n    if (compressionMethod != ZipFileRO::kCompressDeflated) {\n        assert(false);\n        return UNKNOWN_ERROR;\n    }\n\n    mMap = dataMap;\n    mStart = -1;        // not used\n    mCompressedLen = dataMap->getDataLength();\n    mUncompressedLen = uncompressedLen;\n    assert(mOffset == 0);\n\n    if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) {\n        mZipInflater = new StreamingZipInflater(dataMap, uncompressedLen);\n    }\n    return NO_ERROR;\n}\n\n/*\n * Read data from a chunk of compressed data.\n *\n * [For now, that's just copying data out of a buffer.]\n */\nssize_t _CompressedAsset::read(void* buf, size_t count)\n{\n    size_t maxLen;\n    size_t actual;\n\n    assert(mOffset >= 0 && mOffset <= mUncompressedLen);\n\n    /* If we're relying on a streaming inflater, go through that */\n    if (mZipInflater) {\n        actual = mZipInflater->read(buf, count);\n    } else {\n        if (mBuf == NULL) {\n            if (getBuffer(false) == NULL)\n                return -1;\n        }\n        assert(mBuf != NULL);\n\n        /* adjust count if we're near EOF */\n        maxLen = mUncompressedLen - mOffset;\n        if (count > maxLen)\n            count = maxLen;\n\n        if (!count)\n            return 0;\n\n        /* copy from buffer */\n        //printf(\"comp buf read\\n\");\n        memcpy(buf, (char*)mBuf + mOffset, count);\n        actual = count;\n    }\n\n    mOffset += actual;\n    return actual;\n}\n\n/*\n * Handle a seek request.\n *\n * If we're working in a streaming mode, this is going to be fairly\n * expensive, because it requires plowing through a bunch of compressed\n * data.\n */\noff64_t _CompressedAsset::seek(off64_t offset, int whence)\n{\n    off64_t newPosn;\n\n    // compute new position within chunk\n    newPosn = handleSeek(offset, whence, mOffset, mUncompressedLen);\n    if (newPosn == (off64_t) -1)\n        return newPosn;\n\n    if (mZipInflater) {\n        mZipInflater->seekAbsolute(newPosn);\n    }\n    mOffset = newPosn;\n    return mOffset;\n}\n\n/*\n * Close the asset.\n */\nvoid _CompressedAsset::close(void)\n{\n    if (mMap != NULL) {\n        mMap->release();\n        mMap = NULL;\n    }\n\n    delete[] mBuf;\n    mBuf = NULL;\n\n    delete mZipInflater;\n    mZipInflater = NULL;\n\n    if (mFd > 0) {\n        ::close(mFd);\n        mFd = -1;\n    }\n}\n\n/*\n * Get a pointer to a read-only buffer of data.\n *\n * The first time this is called, we expand the compressed data into a\n * buffer.\n */\nconst void* _CompressedAsset::getBuffer(bool)\n{\n    unsigned char* buf = NULL;\n\n    if (mBuf != NULL)\n        return mBuf;\n\n    /*\n     * Allocate a buffer and read the file into it.\n     */\n    buf = new unsigned char[mUncompressedLen];\n    if (buf == NULL) {\n        ALOGW(\"alloc %ld bytes failed\\n\", (long) mUncompressedLen);\n        goto bail;\n    }\n\n    if (mMap != NULL) {\n        if (!ZipUtils::inflateToBuffer(mMap->getDataPtr(), buf,\n                mUncompressedLen, mCompressedLen))\n            goto bail;\n    } else {\n        assert(mFd >= 0);\n\n        /*\n         * Seek to the start of the compressed data.\n         */\n        if (lseek(mFd, mStart, SEEK_SET) != mStart)\n            goto bail;\n\n        /*\n         * Expand the data into it.\n         */\n        if (!ZipUtils::inflateToBuffer(mFd, buf, mUncompressedLen,\n                mCompressedLen))\n            goto bail;\n    }\n\n    /*\n     * Success - now that we have the full asset in RAM we\n     * no longer need the streaming inflater\n     */\n    delete mZipInflater;\n    mZipInflater = NULL;\n\n    mBuf = buf;\n    buf = NULL;\n\nbail:\n    delete[] buf;\n    return mBuf;\n}\n\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/AssetDir.cpp",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Provide access to a virtual directory in \"asset space\".  Most of the\n// implementation is in the header file or in friend functions in\n// AssetManager.\n//\n#include <androidfw/AssetDir.h>\n\nusing namespace android;\n\n\n/*\n * Find a matching entry in a vector of FileInfo.  Because it's sorted, we\n * can use a binary search.\n *\n * Assumes the vector is sorted in ascending order.\n */\n/*static*/ int AssetDir::FileInfo::findEntry(const SortedVector<FileInfo>* pVector,\n    const String8& fileName)\n{\n    FileInfo tmpInfo;\n\n    tmpInfo.setFileName(fileName);\n    return pVector->indexOf(tmpInfo);\n\n#if 0  // don't need this after all (uses 1/2 compares of SortedVector though)\n    int lo, hi, cur;\n\n    lo = 0;\n    hi = pVector->size() -1;\n    while (lo <= hi) {\n        int cmp;\n\n        cur = (hi + lo) / 2;\n        cmp = strcmp(pVector->itemAt(cur).getFileName(), fileName);\n        if (cmp == 0) {\n            /* match, bail */\n            return cur;\n        } else if (cmp < 0) {\n            /* too low */\n            lo = cur + 1;\n        } else {\n            /* too high */\n            hi = cur -1;\n        }\n    }\n\n    return -1;\n#endif\n}\n\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/AssetManager.cpp",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Provide access to read-only assets.\n//\n\n#define LOG_TAG \"asset\"\n#define ATRACE_TAG ATRACE_TAG_RESOURCES\n//#define LOG_NDEBUG 0\n\n#include <androidfw/Asset.h>\n#include <androidfw/AssetDir.h>\n#include <androidfw/AssetManager.h>\n#include <androidfw/misc.h>\n#include <androidfw/ResourceTypes.h>\n#include <androidfw/ZipFileRO.h>\n#include <utils/Atomic.h>\n#include <utils/Log.h>\n#include <utils/String8.h>\n#include <utils/String8.h>\n#include <utils/threads.h>\n#include <utils/Timers.h>\n#ifdef HAVE_ANDROID_OS\n#include <cutils/trace.h>\n#endif\n\n#include <assert.h>\n#include <dirent.h>\n#include <errno.h>\n#include <string.h> // strerror\n#include <strings.h>\n\n#ifndef TEMP_FAILURE_RETRY\n/* Used to retry syscalls that can return EINTR. */\n#define TEMP_FAILURE_RETRY(exp) ({         \\\n    typeof (exp) _rc;                      \\\n    do {                                   \\\n        _rc = (exp);                       \\\n    } while (_rc == -1 && errno == EINTR); \\\n    _rc; })\n#endif\n\n#ifdef HAVE_ANDROID_OS\n#define MY_TRACE_BEGIN(x) ATRACE_BEGIN(x)\n#define MY_TRACE_END() ATRACE_END()\n#else\n#define MY_TRACE_BEGIN(x)\n#define MY_TRACE_END()\n#endif\n\nusing namespace android;\n\n/*\n * Names for default app, locale, and vendor.  We might want to change\n * these to be an actual locale, e.g. always use en-US as the default.\n */\nstatic const char* kDefaultLocale = \"default\";\nstatic const char* kDefaultVendor = \"default\";\nstatic const char* kAssetsRoot = \"assets\";\nstatic const char* kAppZipName = NULL; //\"classes.jar\";\nstatic const char* kSystemAssets = \"framework/framework-res.apk\";\nstatic const char* kResourceCache = \"resource-cache\";\nstatic const char* kAndroidManifest = \"AndroidManifest.xml\";\n\nstatic const char* kExcludeExtension = \".EXCLUDE\";\n\nstatic Asset* const kExcludedAsset = (Asset*) 0xd000000d;\n\nstatic volatile int32_t gCount = 0;\n\nconst char* AssetManager::RESOURCES_FILENAME = \"resources.arsc\";\nconst char* AssetManager::IDMAP_BIN = \"/system/bin/idmap\";\nconst char* AssetManager::OVERLAY_DIR = \"/vendor/overlay\";\nconst char* AssetManager::TARGET_PACKAGE_NAME = \"android\";\nconst char* AssetManager::TARGET_APK_PATH = \"/system/framework/framework-res.apk\";\nconst char* AssetManager::IDMAP_DIR = \"/data/resource-cache\";\n\nnamespace {\n    String8 idmapPathForPackagePath(const String8& pkgPath)\n    {\n        const char* root = getenv(\"ANDROID_DATA\");\n        LOG_ALWAYS_FATAL_IF(root == NULL, \"ANDROID_DATA not set\");\n        String8 path(root);\n        path.appendPath(kResourceCache);\n\n        char buf[256]; // 256 chars should be enough for anyone...\n        strncpy(buf, pkgPath.string(), 255);\n        buf[255] = '\\0';\n        char* filename = buf;\n        while (*filename && *filename == '/') {\n            ++filename;\n        }\n        char* p = filename;\n        while (*p) {\n            if (*p == '/') {\n                *p = '@';\n            }\n            ++p;\n        }\n        path.appendPath(filename);\n        path.append(\"@idmap\");\n\n        return path;\n    }\n\n    /*\n     * Like strdup(), but uses C++ \"new\" operator instead of malloc.\n     */\n    static char* strdupNew(const char* str)\n    {\n        char* newStr;\n        int len;\n\n        if (str == NULL)\n            return NULL;\n\n        len = strlen(str);\n        newStr = new char[len+1];\n        memcpy(newStr, str, len+1);\n\n        return newStr;\n    }\n}\n\n/*\n * ===========================================================================\n *      AssetManager\n * ===========================================================================\n */\n\nint32_t AssetManager::getGlobalCount()\n{\n    return gCount;\n}\n\nAssetManager::AssetManager(CacheMode cacheMode)\n    : mLocale(NULL), mVendor(NULL),\n      mResources(NULL), mConfig(new ResTable_config),\n      mCacheMode(cacheMode), mCacheValid(false)\n{\n    int count = android_atomic_inc(&gCount)+1;\n    //ALOGI(\"Creating AssetManager %p #%d\\n\", this, count);\n    memset(mConfig, 0, sizeof(ResTable_config));\n}\n\nAssetManager::~AssetManager(void)\n{\n    int count = android_atomic_dec(&gCount);\n    //ALOGI(\"Destroying AssetManager in %p #%d\\n\", this, count);\n\n    delete mConfig;\n    delete mResources;\n\n    // don't have a String class yet, so make sure we clean up\n    delete[] mLocale;\n    delete[] mVendor;\n}\n\nbool AssetManager::addAssetPath(const String8& path, int32_t* cookie)\n{\n    AutoMutex _l(mLock);\n\n    asset_path ap;\n\n    String8 realPath(path);\n    if (kAppZipName) {\n        realPath.appendPath(kAppZipName);\n    }\n    ap.type = ::getFileType(realPath.string());\n    if (ap.type == kFileTypeRegular) {\n        ap.path = realPath;\n    } else {\n        ap.path = path;\n        ap.type = ::getFileType(path.string());\n        if (ap.type != kFileTypeDirectory && ap.type != kFileTypeRegular) {\n            ALOGW(\"Asset path %s is neither a directory nor file (type=%d).\",\n                 path.string(), (int)ap.type);\n            return false;\n        }\n    }\n\n    // Skip if we have it already.\n    for (size_t i=0; i<mAssetPaths.size(); i++) {\n        if (mAssetPaths[i].path == ap.path) {\n            if (cookie) {\n                *cookie = static_cast<int32_t>(i+1);\n            }\n            return true;\n        }\n    }\n\n    ALOGV(\"In %p Asset %s path: %s\", this,\n         ap.type == kFileTypeDirectory ? \"dir\" : \"zip\", ap.path.string());\n\n    // Check that the path has an AndroidManifest.xml\n    Asset* manifestAsset = const_cast<AssetManager*>(this)->openNonAssetInPathLocked(\n            kAndroidManifest, Asset::ACCESS_BUFFER, ap);\n    if (manifestAsset == NULL) {\n        // This asset path does not contain any resources.\n        delete manifestAsset;\n        return false;\n    }\n    delete manifestAsset;\n\n    mAssetPaths.add(ap);\n\n    // new paths are always added at the end\n    if (cookie) {\n        *cookie = static_cast<int32_t>(mAssetPaths.size());\n    }\n\n#ifdef HAVE_ANDROID_OS\n    // Load overlays, if any\n    asset_path oap;\n    for (size_t idx = 0; mZipSet.getOverlay(ap.path, idx, &oap); idx++) {\n        mAssetPaths.add(oap);\n    }\n#endif\n\n    if (mResources != NULL) {\n        appendPathToResTable(ap);\n    }\n\n    return true;\n}\n\nbool AssetManager::addOverlayPath(const String8& packagePath, int32_t* cookie)\n{\n    const String8 idmapPath = idmapPathForPackagePath(packagePath);\n\n    AutoMutex _l(mLock);\n\n    for (size_t i = 0; i < mAssetPaths.size(); ++i) {\n        if (mAssetPaths[i].idmap == idmapPath) {\n           *cookie = static_cast<int32_t>(i + 1);\n            return true;\n         }\n     }\n\n    Asset* idmap = NULL;\n    if ((idmap = openAssetFromFileLocked(idmapPath, Asset::ACCESS_BUFFER)) == NULL) {\n        ALOGW(\"failed to open idmap file %s\\n\", idmapPath.string());\n        return false;\n    }\n\n    String8 targetPath;\n    String8 overlayPath;\n    if (!ResTable::getIdmapInfo(idmap->getBuffer(false), idmap->getLength(),\n                NULL, NULL, NULL, &targetPath, &overlayPath)) {\n        ALOGW(\"failed to read idmap file %s\\n\", idmapPath.string());\n        delete idmap;\n        return false;\n    }\n    delete idmap;\n\n    if (overlayPath != packagePath) {\n        ALOGW(\"idmap file %s inconcistent: expected path %s does not match actual path %s\\n\",\n                idmapPath.string(), packagePath.string(), overlayPath.string());\n        return false;\n    }\n    if (access(targetPath.string(), R_OK) != 0) {\n        ALOGW(\"failed to access file %s: %s\\n\", targetPath.string(), strerror(errno));\n        return false;\n    }\n    if (access(idmapPath.string(), R_OK) != 0) {\n        ALOGW(\"failed to access file %s: %s\\n\", idmapPath.string(), strerror(errno));\n        return false;\n    }\n    if (access(overlayPath.string(), R_OK) != 0) {\n        ALOGW(\"failed to access file %s: %s\\n\", overlayPath.string(), strerror(errno));\n        return false;\n    }\n\n    asset_path oap;\n    oap.path = overlayPath;\n    oap.type = ::getFileType(overlayPath.string());\n    oap.idmap = idmapPath;\n#if 0\n    ALOGD(\"Overlay added: targetPath=%s overlayPath=%s idmapPath=%s\\n\",\n            targetPath.string(), overlayPath.string(), idmapPath.string());\n#endif\n    mAssetPaths.add(oap);\n    *cookie = static_cast<int32_t>(mAssetPaths.size());\n\n    return true;\n }\n\nbool AssetManager::createIdmap(const char* targetApkPath, const char* overlayApkPath,\n        uint32_t targetCrc, uint32_t overlayCrc, uint32_t** outData, size_t* outSize)\n{\n    AutoMutex _l(mLock);\n    const String8 paths[2] = { String8(targetApkPath), String8(overlayApkPath) };\n    ResTable tables[2];\n\n    for (int i = 0; i < 2; ++i) {\n        asset_path ap;\n        ap.type = kFileTypeRegular;\n        ap.path = paths[i];\n        Asset* ass = openNonAssetInPathLocked(\"resources.arsc\", Asset::ACCESS_BUFFER, ap);\n        if (ass == NULL) {\n            ALOGW(\"failed to find resources.arsc in %s\\n\", ap.path.string());\n            return false;\n        }\n        tables[i].add(ass);\n    }\n\n    return tables[0].createIdmap(tables[1], targetCrc, overlayCrc,\n            targetApkPath, overlayApkPath, (void**)outData, outSize) == NO_ERROR;\n}\n\nbool AssetManager::addDefaultAssets()\n{\n    const char* root = getenv(\"ANDROID_ROOT\");\n    LOG_ALWAYS_FATAL_IF(root == NULL, \"ANDROID_ROOT not set\");\n\n    String8 path(root);\n    path.appendPath(kSystemAssets);\n\n    return addAssetPath(path, NULL);\n}\n\nint32_t AssetManager::nextAssetPath(const int32_t cookie) const\n{\n    AutoMutex _l(mLock);\n    const size_t next = static_cast<size_t>(cookie) + 1;\n    return next > mAssetPaths.size() ? -1 : next;\n}\n\nString8 AssetManager::getAssetPath(const int32_t cookie) const\n{\n    AutoMutex _l(mLock);\n    const size_t which = static_cast<size_t>(cookie) - 1;\n    if (which < mAssetPaths.size()) {\n        return mAssetPaths[which].path;\n    }\n    return String8();\n}\n\n/*\n * Set the current locale.  Use NULL to indicate no locale.\n *\n * Close and reopen Zip archives as appropriate, and reset cached\n * information in the locale-specific sections of the tree.\n */\nvoid AssetManager::setLocale(const char* locale)\n{\n    AutoMutex _l(mLock);\n    setLocaleLocked(locale);\n}\n\n\nstatic const char kFilPrefix[] = \"fil\";\nstatic const char kTlPrefix[] = \"tl\";\n\n// The sizes of the prefixes, excluding the 0 suffix.\n// char.\nstatic const int kFilPrefixLen = sizeof(kFilPrefix) - 1;\nstatic const int kTlPrefixLen = sizeof(kTlPrefix) - 1;\n\nvoid AssetManager::setLocaleLocked(const char* locale)\n{\n    if (mLocale != NULL) {\n        /* previously set, purge cached data */\n        purgeFileNameCacheLocked();\n        //mZipSet.purgeLocale();\n        delete[] mLocale;\n    }\n\n    // If we're attempting to set a locale that starts with \"fil\",\n    // we should convert it to \"tl\" for backwards compatibility since\n    // we've been using \"tl\" instead of \"fil\" prior to L.\n    //\n    // If the resource table already has entries for \"fil\", we use that\n    // instead of attempting a fallback.\n    if (strncmp(locale, kFilPrefix, kFilPrefixLen) == 0) {\n        Vector<String8> locales;\n        ResTable* res = mResources;\n        if (res != NULL) {\n            res->getLocales(&locales);\n        }\n        const size_t localesSize = locales.size();\n        bool hasFil = false;\n        for (size_t i = 0; i < localesSize; ++i) {\n            if (locales[i].find(kFilPrefix) == 0) {\n                hasFil = true;\n                break;\n            }\n        }\n\n\n        if (!hasFil) {\n            const size_t newLocaleLen = strlen(locale);\n            // This isn't a bug. We really do want mLocale to be 1 byte\n            // shorter than locale, because we're replacing \"fil-\" with\n            // \"tl-\".\n            mLocale = new char[newLocaleLen];\n            // Copy over \"tl\".\n            memcpy(mLocale, kTlPrefix, kTlPrefixLen);\n            // Copy the rest of |locale|, including the terminating '\\0'.\n            memcpy(mLocale + kTlPrefixLen, locale + kFilPrefixLen,\n                   newLocaleLen - kFilPrefixLen + 1);\n            updateResourceParamsLocked();\n            return;\n        }\n    }\n\n    mLocale = strdupNew(locale);\n    updateResourceParamsLocked();\n}\n\n/*\n * Set the current vendor.  Use NULL to indicate no vendor.\n *\n * Close and reopen Zip archives as appropriate, and reset cached\n * information in the vendor-specific sections of the tree.\n */\nvoid AssetManager::setVendor(const char* vendor)\n{\n    AutoMutex _l(mLock);\n\n    if (mVendor != NULL) {\n        /* previously set, purge cached data */\n        purgeFileNameCacheLocked();\n        //mZipSet.purgeVendor();\n        delete[] mVendor;\n    }\n    mVendor = strdupNew(vendor);\n}\n\nvoid AssetManager::setConfiguration(const ResTable_config& config, const char* locale)\n{\n    AutoMutex _l(mLock);\n    *mConfig = config;\n    if (locale) {\n        setLocaleLocked(locale);\n    } else if (config.language[0] != 0) {\n        char spec[RESTABLE_MAX_LOCALE_LEN];\n        config.getBcp47Locale(spec);\n        setLocaleLocked(spec);\n    } else {\n        updateResourceParamsLocked();\n    }\n}\n\nvoid AssetManager::getConfiguration(ResTable_config* outConfig) const\n{\n    AutoMutex _l(mLock);\n    *outConfig = *mConfig;\n}\n\n/*\n * Open an asset.\n *\n * The data could be;\n *  - In a file on disk (assetBase + fileName).\n *  - In a compressed file on disk (assetBase + fileName.gz).\n *  - In a Zip archive, uncompressed or compressed.\n *\n * It can be in a number of different directories and Zip archives.\n * The search order is:\n *  - [appname]\n *    - locale + vendor\n *    - \"default\" + vendor\n *    - locale + \"default\"\n *    - \"default + \"default\"\n *  - \"common\"\n *    - (same as above)\n *\n * To find a particular file, we have to try up to eight paths with\n * all three forms of data.\n *\n * We should probably reject requests for \"illegal\" filenames, e.g. those\n * with illegal characters or \"../\" backward relative paths.\n */\nAsset* AssetManager::open(const char* fileName, AccessMode mode)\n{\n    AutoMutex _l(mLock);\n\n    LOG_FATAL_IF(mAssetPaths.size() == 0, \"No assets added to AssetManager\");\n\n\n    if (mCacheMode != CACHE_OFF && !mCacheValid)\n        loadFileNameCacheLocked();\n\n    String8 assetName(kAssetsRoot);\n    assetName.appendPath(fileName);\n\n    /*\n     * For each top-level asset path, search for the asset.\n     */\n\n    size_t i = mAssetPaths.size();\n    while (i > 0) {\n        i--;\n        ALOGV(\"Looking for asset '%s' in '%s'\\n\",\n                assetName.string(), mAssetPaths.itemAt(i).path.string());\n        Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, mAssetPaths.itemAt(i));\n        if (pAsset != NULL) {\n            return pAsset != kExcludedAsset ? pAsset : NULL;\n        }\n    }\n\n    return NULL;\n}\n\n/*\n * Open a non-asset file as if it were an asset.\n *\n * The \"fileName\" is the partial path starting from the application\n * name.\n */\nAsset* AssetManager::openNonAsset(const char* fileName, AccessMode mode, int32_t* outCookie)\n{\n    AutoMutex _l(mLock);\n\n    LOG_FATAL_IF(mAssetPaths.size() == 0, \"No assets added to AssetManager\");\n\n\n    if (mCacheMode != CACHE_OFF && !mCacheValid)\n        loadFileNameCacheLocked();\n\n    /*\n     * For each top-level asset path, search for the asset.\n     */\n\n    size_t i = mAssetPaths.size();\n    while (i > 0) {\n        i--;\n        ALOGV(\"Looking for non-asset '%s' in '%s'\\n\", fileName, mAssetPaths.itemAt(i).path.string());\n        Asset* pAsset = openNonAssetInPathLocked(\n            fileName, mode, mAssetPaths.itemAt(i));\n        if (pAsset != NULL) {\n            if (outCookie != NULL) *outCookie = static_cast<int32_t>(i + 1);\n            return pAsset != kExcludedAsset ? pAsset : NULL;\n        }\n    }\n\n    return NULL;\n}\n\nAsset* AssetManager::openNonAsset(const int32_t cookie, const char* fileName, AccessMode mode)\n{\n    const size_t which = static_cast<size_t>(cookie) - 1;\n\n    AutoMutex _l(mLock);\n\n    LOG_FATAL_IF(mAssetPaths.size() == 0, \"No assets added to AssetManager\");\n\n    if (mCacheMode != CACHE_OFF && !mCacheValid)\n        loadFileNameCacheLocked();\n\n    if (which < mAssetPaths.size()) {\n        ALOGV(\"Looking for non-asset '%s' in '%s'\\n\", fileName,\n                mAssetPaths.itemAt(which).path.string());\n        Asset* pAsset = openNonAssetInPathLocked(\n            fileName, mode, mAssetPaths.itemAt(which));\n        if (pAsset != NULL) {\n            return pAsset != kExcludedAsset ? pAsset : NULL;\n        }\n    }\n\n    return NULL;\n}\n\n/*\n * Get the type of a file in the asset namespace.\n *\n * This currently only works for regular files.  All others (including\n * directories) will return kFileTypeNonexistent.\n */\nFileType AssetManager::getFileType(const char* fileName)\n{\n    Asset* pAsset = NULL;\n\n    /*\n     * Open the asset.  This is less efficient than simply finding the\n     * file, but it's not too bad (we don't uncompress or mmap data until\n     * the first read() call).\n     */\n    pAsset = open(fileName, Asset::ACCESS_STREAMING);\n    delete pAsset;\n\n    if (pAsset == NULL)\n        return kFileTypeNonexistent;\n    else\n        return kFileTypeRegular;\n}\n\nbool AssetManager::appendPathToResTable(const asset_path& ap) const {\n    Asset* ass = NULL;\n    ResTable* sharedRes = NULL;\n    bool shared = true;\n    bool onlyEmptyResources = true;\n    MY_TRACE_BEGIN(ap.path.string());\n    Asset* idmap = openIdmapLocked(ap);\n    size_t nextEntryIdx = mResources->getTableCount();\n    ALOGV(\"Looking for resource asset in '%s'\\n\", ap.path.string());\n    if (ap.type != kFileTypeDirectory) {\n        if (nextEntryIdx == 0) {\n            // The first item is typically the framework resources,\n            // which we want to avoid parsing every time.\n            sharedRes = const_cast<AssetManager*>(this)->\n                mZipSet.getZipResourceTable(ap.path);\n            if (sharedRes != NULL) {\n                // skip ahead the number of system overlay packages preloaded\n                nextEntryIdx = sharedRes->getTableCount();\n            }\n        }\n        if (sharedRes == NULL) {\n            ass = const_cast<AssetManager*>(this)->\n                mZipSet.getZipResourceTableAsset(ap.path);\n            if (ass == NULL) {\n                ALOGV(\"loading resource table %s\\n\", ap.path.string());\n                ass = const_cast<AssetManager*>(this)->\n                    openNonAssetInPathLocked(\"resources.arsc\",\n                                             Asset::ACCESS_BUFFER,\n                                             ap);\n                if (ass != NULL && ass != kExcludedAsset) {\n                    ass = const_cast<AssetManager*>(this)->\n                        mZipSet.setZipResourceTableAsset(ap.path, ass);\n                }\n            }\n            \n            if (nextEntryIdx == 0 && ass != NULL) {\n                // If this is the first resource table in the asset\n                // manager, then we are going to cache it so that we\n                // can quickly copy it out for others.\n                ALOGV(\"Creating shared resources for %s\", ap.path.string());\n                sharedRes = new ResTable();\n                sharedRes->add(ass, idmap, nextEntryIdx + 1, false);\n#ifdef HAVE_ANDROID_OS\n                const char* data = getenv(\"ANDROID_DATA\");\n                LOG_ALWAYS_FATAL_IF(data == NULL, \"ANDROID_DATA not set\");\n                String8 overlaysListPath(data);\n                overlaysListPath.appendPath(kResourceCache);\n                overlaysListPath.appendPath(\"overlays.list\");\n                addSystemOverlays(overlaysListPath.string(), ap.path, sharedRes, nextEntryIdx);\n#endif\n                sharedRes = const_cast<AssetManager*>(this)->\n                    mZipSet.setZipResourceTable(ap.path, sharedRes);\n            }\n        }\n    } else {\n        ALOGV(\"loading resource table %s\\n\", ap.path.string());\n        ass = const_cast<AssetManager*>(this)->\n            openNonAssetInPathLocked(\"resources.arsc\",\n                                     Asset::ACCESS_BUFFER,\n                                     ap);\n        shared = false;\n    }\n\n    if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) {\n        ALOGV(\"Installing resource asset %p in to table %p\\n\", ass, mResources);\n        if (sharedRes != NULL) {\n            ALOGV(\"Copying existing resources for %s\", ap.path.string());\n            mResources->add(sharedRes);\n        } else {\n            ALOGV(\"Parsing resources for %s\", ap.path.string());\n            mResources->add(ass, idmap, nextEntryIdx + 1, !shared);\n        }\n        onlyEmptyResources = false;\n\n        if (!shared) {\n            delete ass;\n        }\n    } else {\n        ALOGV(\"Installing empty resources in to table %p\\n\", mResources);\n        mResources->addEmpty(nextEntryIdx + 1);\n    }\n\n    if (idmap != NULL) {\n        delete idmap;\n    }\n    MY_TRACE_END();\n\n    return onlyEmptyResources;\n}\n\nconst ResTable* AssetManager::getResTable(bool required) const\n{\n    ResTable* rt = mResources;\n    if (rt) {\n        return rt;\n    }\n\n    // Iterate through all asset packages, collecting resources from each.\n\n    AutoMutex _l(mLock);\n\n    if (mResources != NULL) {\n        return mResources;\n    }\n\n    if (required) {\n        LOG_FATAL_IF(mAssetPaths.size() == 0, \"No assets added to AssetManager\");\n    }\n\n    if (mCacheMode != CACHE_OFF && !mCacheValid) {\n        const_cast<AssetManager*>(this)->loadFileNameCacheLocked();\n    }\n\n    mResources = new ResTable();\n    updateResourceParamsLocked();\n\n    bool onlyEmptyResources = true;\n    const size_t N = mAssetPaths.size();\n    for (size_t i=0; i<N; i++) {\n        bool empty = appendPathToResTable(mAssetPaths.itemAt(i));\n        onlyEmptyResources = onlyEmptyResources && empty;\n    }\n\n    if (required && onlyEmptyResources) {\n        ALOGW(\"Unable to find resources file resources.arsc\");\n        delete mResources;\n        mResources = NULL;\n    }\n\n    return mResources;\n}\n\nvoid AssetManager::updateResourceParamsLocked() const\n{\n    ResTable* res = mResources;\n    if (!res) {\n        return;\n    }\n\n    if (mLocale) {\n        mConfig->setBcp47Locale(mLocale);\n    } else {\n        mConfig->clearLocale();\n    }\n\n    res->setParameters(mConfig);\n}\n\nAsset* AssetManager::openIdmapLocked(const struct asset_path& ap) const\n{\n    Asset* ass = NULL;\n    if (ap.idmap.size() != 0) {\n        ass = const_cast<AssetManager*>(this)->\n            openAssetFromFileLocked(ap.idmap, Asset::ACCESS_BUFFER);\n        if (ass) {\n            ALOGV(\"loading idmap %s\\n\", ap.idmap.string());\n        } else {\n            ALOGW(\"failed to load idmap %s\\n\", ap.idmap.string());\n        }\n    }\n    return ass;\n}\n\nvoid AssetManager::addSystemOverlays(const char* pathOverlaysList,\n        const String8& targetPackagePath, ResTable* sharedRes, size_t offset) const\n{\n    FILE* fin = fopen(pathOverlaysList, \"r\");\n    if (fin == NULL) {\n        return;\n    }\n\n    char buf[1024];\n    while (fgets(buf, sizeof(buf), fin)) {\n        // format of each line:\n        //   <path to apk><space><path to idmap><newline>\n        char* space = strchr(buf, ' ');\n        char* newline = strchr(buf, '\\n');\n        asset_path oap;\n\n        if (space == NULL || newline == NULL || newline < space) {\n            continue;\n        }\n\n        oap.path = String8(buf, space - buf);\n        oap.type = kFileTypeRegular;\n        oap.idmap = String8(space + 1, newline - space - 1);\n\n        Asset* oass = const_cast<AssetManager*>(this)->\n            openNonAssetInPathLocked(\"resources.arsc\",\n                    Asset::ACCESS_BUFFER,\n                    oap);\n\n        if (oass != NULL) {\n            Asset* oidmap = openIdmapLocked(oap);\n            offset++;\n            sharedRes->add(oass, oidmap, offset + 1, false);\n            const_cast<AssetManager*>(this)->mAssetPaths.add(oap);\n            const_cast<AssetManager*>(this)->mZipSet.addOverlay(targetPackagePath, oap);\n        }\n    }\n    fclose(fin);\n}\n\nconst ResTable& AssetManager::getResources(bool required) const\n{\n    const ResTable* rt = getResTable(required);\n    return *rt;\n}\n\nbool AssetManager::isUpToDate()\n{\n    AutoMutex _l(mLock);\n    return mZipSet.isUpToDate();\n}\n\nvoid AssetManager::getLocales(Vector<String8>* locales) const\n{\n    ResTable* res = mResources;\n    if (res != NULL) {\n        res->getLocales(locales);\n    }\n\n    const size_t numLocales = locales->size();\n    for (size_t i = 0; i < numLocales; ++i) {\n        const String8& localeStr = locales->itemAt(i);\n        if (localeStr.find(kTlPrefix) == 0) {\n            String8 replaced(\"fil\");\n            replaced += (localeStr.string() + kTlPrefixLen);\n            locales->editItemAt(i) = replaced;\n        }\n    }\n}\n\n/*\n * Open a non-asset file as if it were an asset, searching for it in the\n * specified app.\n *\n * Pass in a NULL values for \"appName\" if the common app directory should\n * be used.\n */\nAsset* AssetManager::openNonAssetInPathLocked(const char* fileName, AccessMode mode,\n    const asset_path& ap)\n{\n    Asset* pAsset = NULL;\n\n    /* look at the filesystem on disk */\n    if (ap.type == kFileTypeDirectory) {\n        String8 path(ap.path);\n        path.appendPath(fileName);\n\n        pAsset = openAssetFromFileLocked(path, mode);\n\n        if (pAsset == NULL) {\n            /* try again, this time with \".gz\" */\n            path.append(\".gz\");\n            pAsset = openAssetFromFileLocked(path, mode);\n        }\n\n        if (pAsset != NULL) {\n            //printf(\"FOUND NA '%s' on disk\\n\", fileName);\n            pAsset->setAssetSource(path);\n        }\n\n    /* look inside the zip file */\n    } else {\n        String8 path(fileName);\n\n        /* check the appropriate Zip file */\n        ZipFileRO* pZip = getZipFileLocked(ap);\n        if (pZip != NULL) {\n            //printf(\"GOT zip, checking NA '%s'\\n\", (const char*) path);\n            ZipEntryRO entry = pZip->findEntryByName(path.string());\n            if (entry != NULL) {\n                //printf(\"FOUND NA in Zip file for %s\\n\", appName ? appName : kAppCommon);\n                pAsset = openAssetFromZipLocked(pZip, entry, mode, path);\n                pZip->releaseEntry(entry);\n            }\n        }\n\n        if (pAsset != NULL) {\n            /* create a \"source\" name, for debug/display */\n            pAsset->setAssetSource(\n                    createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()), String8(\"\"),\n                                                String8(fileName)));\n        }\n    }\n\n    return pAsset;\n}\n\n/*\n * Open an asset, searching for it in the directory hierarchy for the\n * specified app.\n *\n * Pass in a NULL values for \"appName\" if the common app directory should\n * be used.\n */\nAsset* AssetManager::openInPathLocked(const char* fileName, AccessMode mode,\n    const asset_path& ap)\n{\n    Asset* pAsset = NULL;\n\n    /*\n     * Try various combinations of locale and vendor.\n     */\n    if (mLocale != NULL && mVendor != NULL)\n        pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, mVendor);\n    if (pAsset == NULL && mVendor != NULL)\n        pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, mVendor);\n    if (pAsset == NULL && mLocale != NULL)\n        pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, NULL);\n    if (pAsset == NULL)\n        pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, NULL);\n\n    return pAsset;\n}\n\n/*\n * Open an asset, searching for it in the directory hierarchy for the\n * specified locale and vendor.\n *\n * We also search in \"app.jar\".\n *\n * Pass in NULL values for \"appName\", \"locale\", and \"vendor\" if the\n * defaults should be used.\n */\nAsset* AssetManager::openInLocaleVendorLocked(const char* fileName, AccessMode mode,\n    const asset_path& ap, const char* locale, const char* vendor)\n{\n    Asset* pAsset = NULL;\n\n    if (ap.type == kFileTypeDirectory) {\n        if (mCacheMode == CACHE_OFF) {\n            /* look at the filesystem on disk */\n            String8 path(createPathNameLocked(ap, locale, vendor));\n            path.appendPath(fileName);\n    \n            String8 excludeName(path);\n            excludeName.append(kExcludeExtension);\n            if (::getFileType(excludeName.string()) != kFileTypeNonexistent) {\n                /* say no more */\n                //printf(\"+++ excluding '%s'\\n\", (const char*) excludeName);\n                return kExcludedAsset;\n            }\n    \n            pAsset = openAssetFromFileLocked(path, mode);\n    \n            if (pAsset == NULL) {\n                /* try again, this time with \".gz\" */\n                path.append(\".gz\");\n                pAsset = openAssetFromFileLocked(path, mode);\n            }\n    \n            if (pAsset != NULL)\n                pAsset->setAssetSource(path);\n        } else {\n            /* find in cache */\n            String8 path(createPathNameLocked(ap, locale, vendor));\n            path.appendPath(fileName);\n    \n            AssetDir::FileInfo tmpInfo;\n            bool found = false;\n    \n            String8 excludeName(path);\n            excludeName.append(kExcludeExtension);\n    \n            if (mCache.indexOf(excludeName) != NAME_NOT_FOUND) {\n                /* go no farther */\n                //printf(\"+++ Excluding '%s'\\n\", (const char*) excludeName);\n                return kExcludedAsset;\n            }\n\n            /*\n             * File compression extensions (\".gz\") don't get stored in the\n             * name cache, so we have to try both here.\n             */\n            if (mCache.indexOf(path) != NAME_NOT_FOUND) {\n                found = true;\n                pAsset = openAssetFromFileLocked(path, mode);\n                if (pAsset == NULL) {\n                    /* try again, this time with \".gz\" */\n                    path.append(\".gz\");\n                    pAsset = openAssetFromFileLocked(path, mode);\n                }\n            }\n\n            if (pAsset != NULL)\n                pAsset->setAssetSource(path);\n\n            /*\n             * Don't continue the search into the Zip files.  Our cached info\n             * said it was a file on disk; to be consistent with openDir()\n             * we want to return the loose asset.  If the cached file gets\n             * removed, we fail.\n             *\n             * The alternative is to update our cache when files get deleted,\n             * or make some sort of \"best effort\" promise, but for now I'm\n             * taking the hard line.\n             */\n            if (found) {\n                if (pAsset == NULL)\n                    ALOGD(\"Expected file not found: '%s'\\n\", path.string());\n                return pAsset;\n            }\n        }\n    }\n\n    /*\n     * Either it wasn't found on disk or on the cached view of the disk.\n     * Dig through the currently-opened set of Zip files.  If caching\n     * is disabled, the Zip file may get reopened.\n     */\n    if (pAsset == NULL && ap.type == kFileTypeRegular) {\n        String8 path;\n\n        path.appendPath((locale != NULL) ? locale : kDefaultLocale);\n        path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);\n        path.appendPath(fileName);\n\n        /* check the appropriate Zip file */\n        ZipFileRO* pZip = getZipFileLocked(ap);\n        if (pZip != NULL) {\n            //printf(\"GOT zip, checking '%s'\\n\", (const char*) path);\n            ZipEntryRO entry = pZip->findEntryByName(path.string());\n            if (entry != NULL) {\n                //printf(\"FOUND in Zip file for %s/%s-%s\\n\",\n                //    appName, locale, vendor);\n                pAsset = openAssetFromZipLocked(pZip, entry, mode, path);\n                pZip->releaseEntry(entry);\n            }\n        }\n\n        if (pAsset != NULL) {\n            /* create a \"source\" name, for debug/display */\n            pAsset->setAssetSource(createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()),\n                                                             String8(\"\"), String8(fileName)));\n        }\n    }\n\n    return pAsset;\n}\n\n/*\n * Create a \"source name\" for a file from a Zip archive.\n */\nString8 AssetManager::createZipSourceNameLocked(const String8& zipFileName,\n    const String8& dirName, const String8& fileName)\n{\n    String8 sourceName(\"zip:\");\n    sourceName.append(zipFileName);\n    sourceName.append(\":\");\n    if (dirName.length() > 0) {\n        sourceName.appendPath(dirName);\n    }\n    sourceName.appendPath(fileName);\n    return sourceName;\n}\n\n/*\n * Create a path to a loose asset (asset-base/app/locale/vendor).\n */\nString8 AssetManager::createPathNameLocked(const asset_path& ap, const char* locale,\n    const char* vendor)\n{\n    String8 path(ap.path);\n    path.appendPath((locale != NULL) ? locale : kDefaultLocale);\n    path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);\n    return path;\n}\n\n/*\n * Create a path to a loose asset (asset-base/app/rootDir).\n */\nString8 AssetManager::createPathNameLocked(const asset_path& ap, const char* rootDir)\n{\n    String8 path(ap.path);\n    if (rootDir != NULL) path.appendPath(rootDir);\n    return path;\n}\n\n/*\n * Return a pointer to one of our open Zip archives.  Returns NULL if no\n * matching Zip file exists.\n *\n * Right now we have 2 possible Zip files (1 each in app/\"common\").\n *\n * If caching is set to CACHE_OFF, to get the expected behavior we\n * need to reopen the Zip file on every request.  That would be silly\n * and expensive, so instead we just check the file modification date.\n *\n * Pass in NULL values for \"appName\", \"locale\", and \"vendor\" if the\n * generics should be used.\n */\nZipFileRO* AssetManager::getZipFileLocked(const asset_path& ap)\n{\n    ALOGV(\"getZipFileLocked() in %p\\n\", this);\n\n    return mZipSet.getZip(ap.path);\n}\n\n/*\n * Try to open an asset from a file on disk.\n *\n * If the file is compressed with gzip, we seek to the start of the\n * deflated data and pass that in (just like we would for a Zip archive).\n *\n * For uncompressed data, we may already have an mmap()ed version sitting\n * around.  If so, we want to hand that to the Asset instead.\n *\n * This returns NULL if the file doesn't exist, couldn't be opened, or\n * claims to be a \".gz\" but isn't.\n */\nAsset* AssetManager::openAssetFromFileLocked(const String8& pathName,\n    AccessMode mode)\n{\n    Asset* pAsset = NULL;\n\n    if (strcasecmp(pathName.getPathExtension().string(), \".gz\") == 0) {\n        //printf(\"TRYING '%s'\\n\", (const char*) pathName);\n        pAsset = Asset::createFromCompressedFile(pathName.string(), mode);\n    } else {\n        //printf(\"TRYING '%s'\\n\", (const char*) pathName);\n        pAsset = Asset::createFromFile(pathName.string(), mode);\n    }\n\n    return pAsset;\n}\n\n/*\n * Given an entry in a Zip archive, create a new Asset object.\n *\n * If the entry is uncompressed, we may want to create or share a\n * slice of shared memory.\n */\nAsset* AssetManager::openAssetFromZipLocked(const ZipFileRO* pZipFile,\n    const ZipEntryRO entry, AccessMode mode, const String8& entryName)\n{\n    Asset* pAsset = NULL;\n\n    // TODO: look for previously-created shared memory slice?\n    int method;\n    size_t uncompressedLen;\n\n    //printf(\"USING Zip '%s'\\n\", pEntry->getFileName());\n\n    //pZipFile->getEntryInfo(entry, &method, &uncompressedLen, &compressedLen,\n    //    &offset);\n    if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, NULL, NULL,\n            NULL, NULL))\n    {\n        ALOGW(\"getEntryInfo failed\\n\");\n        return NULL;\n    }\n\n    FileMap* dataMap = pZipFile->createEntryFileMap(entry);\n    if (dataMap == NULL) {\n        ALOGW(\"create map from entry failed\\n\");\n        return NULL;\n    }\n\n    if (method == ZipFileRO::kCompressStored) {\n        pAsset = Asset::createFromUncompressedMap(dataMap, mode);\n        ALOGV(\"Opened uncompressed entry %s in zip %s mode %d: %p\", entryName.string(),\n                dataMap->getFileName(), mode, pAsset);\n    } else {\n        pAsset = Asset::createFromCompressedMap(dataMap, method,\n            uncompressedLen, mode);\n        ALOGV(\"Opened compressed entry %s in zip %s mode %d: %p\", entryName.string(),\n                dataMap->getFileName(), mode, pAsset);\n    }\n    if (pAsset == NULL) {\n        /* unexpected */\n        ALOGW(\"create from segment failed\\n\");\n    }\n\n    return pAsset;\n}\n\n\n\n/*\n * Open a directory in the asset namespace.\n *\n * An \"asset directory\" is simply the combination of all files in all\n * locations, with \".gz\" stripped for loose files.  With app, locale, and\n * vendor defined, we have 8 directories and 2 Zip archives to scan.\n *\n * Pass in \"\" for the root dir.\n */\nAssetDir* AssetManager::openDir(const char* dirName)\n{\n    AutoMutex _l(mLock);\n\n    AssetDir* pDir = NULL;\n    SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL;\n\n    LOG_FATAL_IF(mAssetPaths.size() == 0, \"No assets added to AssetManager\");\n    assert(dirName != NULL);\n\n    //printf(\"+++ openDir(%s) in '%s'\\n\", dirName, (const char*) mAssetBase);\n\n    if (mCacheMode != CACHE_OFF && !mCacheValid)\n        loadFileNameCacheLocked();\n\n    pDir = new AssetDir;\n\n    /*\n     * Scan the various directories, merging what we find into a single\n     * vector.  We want to scan them in reverse priority order so that\n     * the \".EXCLUDE\" processing works correctly.  Also, if we decide we\n     * want to remember where the file is coming from, we'll get the right\n     * version.\n     *\n     * We start with Zip archives, then do loose files.\n     */\n    pMergedInfo = new SortedVector<AssetDir::FileInfo>;\n\n    size_t i = mAssetPaths.size();\n    while (i > 0) {\n        i--;\n        const asset_path& ap = mAssetPaths.itemAt(i);\n        if (ap.type == kFileTypeRegular) {\n            ALOGV(\"Adding directory %s from zip %s\", dirName, ap.path.string());\n            scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName);\n        } else {\n            ALOGV(\"Adding directory %s from dir %s\", dirName, ap.path.string());\n            scanAndMergeDirLocked(pMergedInfo, ap, kAssetsRoot, dirName);\n        }\n    }\n\n#if 0\n    printf(\"FILE LIST:\\n\");\n    for (i = 0; i < (size_t) pMergedInfo->size(); i++) {\n        printf(\" %d: (%d) '%s'\\n\", i,\n            pMergedInfo->itemAt(i).getFileType(),\n            (const char*) pMergedInfo->itemAt(i).getFileName());\n    }\n#endif\n\n    pDir->setFileList(pMergedInfo);\n    return pDir;\n}\n\n/*\n * Open a directory in the non-asset namespace.\n *\n * An \"asset directory\" is simply the combination of all files in all\n * locations, with \".gz\" stripped for loose files.  With app, locale, and\n * vendor defined, we have 8 directories and 2 Zip archives to scan.\n *\n * Pass in \"\" for the root dir.\n */\nAssetDir* AssetManager::openNonAssetDir(const int32_t cookie, const char* dirName)\n{\n    AutoMutex _l(mLock);\n\n    AssetDir* pDir = NULL;\n    SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL;\n\n    LOG_FATAL_IF(mAssetPaths.size() == 0, \"No assets added to AssetManager\");\n    assert(dirName != NULL);\n\n    //printf(\"+++ openDir(%s) in '%s'\\n\", dirName, (const char*) mAssetBase);\n\n    if (mCacheMode != CACHE_OFF && !mCacheValid)\n        loadFileNameCacheLocked();\n\n    pDir = new AssetDir;\n\n    pMergedInfo = new SortedVector<AssetDir::FileInfo>;\n\n    const size_t which = static_cast<size_t>(cookie) - 1;\n\n    if (which < mAssetPaths.size()) {\n        const asset_path& ap = mAssetPaths.itemAt(which);\n        if (ap.type == kFileTypeRegular) {\n            ALOGV(\"Adding directory %s from zip %s\", dirName, ap.path.string());\n            scanAndMergeZipLocked(pMergedInfo, ap, NULL, dirName);\n        } else {\n            ALOGV(\"Adding directory %s from dir %s\", dirName, ap.path.string());\n            scanAndMergeDirLocked(pMergedInfo, ap, NULL, dirName);\n        }\n    }\n\n#if 0\n    printf(\"FILE LIST:\\n\");\n    for (i = 0; i < (size_t) pMergedInfo->size(); i++) {\n        printf(\" %d: (%d) '%s'\\n\", i,\n            pMergedInfo->itemAt(i).getFileType(),\n            (const char*) pMergedInfo->itemAt(i).getFileName());\n    }\n#endif\n\n    pDir->setFileList(pMergedInfo);\n    return pDir;\n}\n\n/*\n * Scan the contents of the specified directory and merge them into the\n * \"pMergedInfo\" vector, removing previous entries if we find \"exclude\"\n * directives.\n *\n * Returns \"false\" if we found nothing to contribute.\n */\nbool AssetManager::scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n    const asset_path& ap, const char* rootDir, const char* dirName)\n{\n    SortedVector<AssetDir::FileInfo>* pContents;\n    String8 path;\n\n    assert(pMergedInfo != NULL);\n\n    //printf(\"scanAndMergeDir: %s %s %s %s\\n\", appName, locale, vendor,dirName);\n\n    if (mCacheValid) {\n        int i, start, count;\n\n        pContents = new SortedVector<AssetDir::FileInfo>;\n\n        /*\n         * Get the basic partial path and find it in the cache.  That's\n         * the start point for the search.\n         */\n        path = createPathNameLocked(ap, rootDir);\n        if (dirName[0] != '\\0')\n            path.appendPath(dirName);\n\n        start = mCache.indexOf(path);\n        if (start == NAME_NOT_FOUND) {\n            //printf(\"+++ not found in cache: dir '%s'\\n\", (const char*) path);\n            delete pContents;\n            return false;\n        }\n\n        /*\n         * The match string looks like \"common/default/default/foo/bar/\".\n         * The '/' on the end ensures that we don't match on the directory\n         * itself or on \".../foo/barfy/\".\n         */\n        path.append(\"/\");\n\n        count = mCache.size();\n\n        /*\n         * Pick out the stuff in the current dir by examining the pathname.\n         * It needs to match the partial pathname prefix, and not have a '/'\n         * (fssep) anywhere after the prefix.\n         */\n        for (i = start+1; i < count; i++) {\n            if (mCache[i].getFileName().length() > path.length() &&\n                strncmp(mCache[i].getFileName().string(), path.string(), path.length()) == 0)\n            {\n                const char* name = mCache[i].getFileName().string();\n                // XXX THIS IS BROKEN!  Looks like we need to store the full\n                // path prefix separately from the file path.\n                if (strchr(name + path.length(), '/') == NULL) {\n                    /* grab it, reducing path to just the filename component */\n                    AssetDir::FileInfo tmp = mCache[i];\n                    tmp.setFileName(tmp.getFileName().getPathLeaf());\n                    pContents->add(tmp);\n                }\n            } else {\n                /* no longer in the dir or its subdirs */\n                break;\n            }\n\n        }\n    } else {\n        path = createPathNameLocked(ap, rootDir);\n        if (dirName[0] != '\\0')\n            path.appendPath(dirName);\n        pContents = scanDirLocked(path);\n        if (pContents == NULL)\n            return false;\n    }\n\n    // if we wanted to do an incremental cache fill, we would do it here\n\n    /*\n     * Process \"exclude\" directives.  If we find a filename that ends with\n     * \".EXCLUDE\", we look for a matching entry in the \"merged\" set, and\n     * remove it if we find it.  We also delete the \"exclude\" entry.\n     */\n    int i, count, exclExtLen;\n\n    count = pContents->size();\n    exclExtLen = strlen(kExcludeExtension);\n    for (i = 0; i < count; i++) {\n        const char* name;\n        int nameLen;\n\n        name = pContents->itemAt(i).getFileName().string();\n        nameLen = strlen(name);\n        if (nameLen > exclExtLen &&\n            strcmp(name + (nameLen - exclExtLen), kExcludeExtension) == 0)\n        {\n            String8 match(name, nameLen - exclExtLen);\n            int matchIdx;\n\n            matchIdx = AssetDir::FileInfo::findEntry(pMergedInfo, match);\n            if (matchIdx > 0) {\n                ALOGV(\"Excluding '%s' [%s]\\n\",\n                    pMergedInfo->itemAt(matchIdx).getFileName().string(),\n                    pMergedInfo->itemAt(matchIdx).getSourceName().string());\n                pMergedInfo->removeAt(matchIdx);\n            } else {\n                //printf(\"+++ no match on '%s'\\n\", (const char*) match);\n            }\n\n            ALOGD(\"HEY: size=%d removing %d\\n\", (int)pContents->size(), i);\n            pContents->removeAt(i);\n            i--;        // adjust \"for\" loop\n            count--;    //  and loop limit\n        }\n    }\n\n    mergeInfoLocked(pMergedInfo, pContents);\n\n    delete pContents;\n\n    return true;\n}\n\n/*\n * Scan the contents of the specified directory, and stuff what we find\n * into a newly-allocated vector.\n *\n * Files ending in \".gz\" will have their extensions removed.\n *\n * We should probably think about skipping files with \"illegal\" names,\n * e.g. illegal characters (/\\:) or excessive length.\n *\n * Returns NULL if the specified directory doesn't exist.\n */\nSortedVector<AssetDir::FileInfo>* AssetManager::scanDirLocked(const String8& path)\n{\n    SortedVector<AssetDir::FileInfo>* pContents = NULL;\n    DIR* dir;\n    struct dirent* entry;\n    FileType fileType;\n\n    ALOGV(\"Scanning dir '%s'\\n\", path.string());\n\n    dir = opendir(path.string());\n    if (dir == NULL)\n        return NULL;\n\n    pContents = new SortedVector<AssetDir::FileInfo>;\n\n    while (1) {\n        entry = readdir(dir);\n        if (entry == NULL)\n            break;\n\n        if (strcmp(entry->d_name, \".\") == 0 ||\n            strcmp(entry->d_name, \"..\") == 0)\n            continue;\n\n#ifdef _DIRENT_HAVE_D_TYPE\n        if (entry->d_type == DT_REG)\n            fileType = kFileTypeRegular;\n        else if (entry->d_type == DT_DIR)\n            fileType = kFileTypeDirectory;\n        else\n            fileType = kFileTypeUnknown;\n#else\n        // stat the file\n        fileType = ::getFileType(path.appendPathCopy(entry->d_name).string());\n#endif\n\n        if (fileType != kFileTypeRegular && fileType != kFileTypeDirectory)\n            continue;\n\n        AssetDir::FileInfo info;\n        info.set(String8(entry->d_name), fileType);\n        if (strcasecmp(info.getFileName().getPathExtension().string(), \".gz\") == 0)\n            info.setFileName(info.getFileName().getBasePath());\n        info.setSourceName(path.appendPathCopy(info.getFileName()));\n        pContents->add(info);\n    }\n\n    closedir(dir);\n    return pContents;\n}\n\n/*\n * Scan the contents out of the specified Zip archive, and merge what we\n * find into \"pMergedInfo\".  If the Zip archive in question doesn't exist,\n * we return immediately.\n *\n * Returns \"false\" if we found nothing to contribute.\n */\nbool AssetManager::scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n    const asset_path& ap, const char* rootDir, const char* baseDirName)\n{\n    ZipFileRO* pZip;\n    Vector<String8> dirs;\n    AssetDir::FileInfo info;\n    SortedVector<AssetDir::FileInfo> contents;\n    String8 sourceName, zipName, dirName;\n\n    pZip = mZipSet.getZip(ap.path);\n    if (pZip == NULL) {\n        ALOGW(\"Failure opening zip %s\\n\", ap.path.string());\n        return false;\n    }\n\n    zipName = ZipSet::getPathName(ap.path.string());\n\n    /* convert \"sounds\" to \"rootDir/sounds\" */\n    if (rootDir != NULL) dirName = rootDir;\n    dirName.appendPath(baseDirName);\n\n    /*\n     * Scan through the list of files, looking for a match.  The files in\n     * the Zip table of contents are not in sorted order, so we have to\n     * process the entire list.  We're looking for a string that begins\n     * with the characters in \"dirName\", is followed by a '/', and has no\n     * subsequent '/' in the stuff that follows.\n     *\n     * What makes this especially fun is that directories are not stored\n     * explicitly in Zip archives, so we have to infer them from context.\n     * When we see \"sounds/foo.wav\" we have to leave a note to ourselves\n     * to insert a directory called \"sounds\" into the list.  We store\n     * these in temporary vector so that we only return each one once.\n     *\n     * Name comparisons are case-sensitive to match UNIX filesystem\n     * semantics.\n     */\n    int dirNameLen = dirName.length();\n    void *iterationCookie;\n    if (!pZip->startIteration(&iterationCookie)) {\n        ALOGW(\"ZipFileRO::startIteration returned false\");\n        return false;\n    }\n\n    ZipEntryRO entry;\n    while ((entry = pZip->nextEntry(iterationCookie)) != NULL) {\n        char nameBuf[256];\n\n        if (pZip->getEntryFileName(entry, nameBuf, sizeof(nameBuf)) != 0) {\n            // TODO: fix this if we expect to have long names\n            ALOGE(\"ARGH: name too long?\\n\");\n            continue;\n        }\n        //printf(\"Comparing %s in %s?\\n\", nameBuf, dirName.string());\n        if (dirNameLen == 0 ||\n            (strncmp(nameBuf, dirName.string(), dirNameLen) == 0 &&\n             nameBuf[dirNameLen] == '/'))\n        {\n            const char* cp;\n            const char* nextSlash;\n\n            cp = nameBuf + dirNameLen;\n            if (dirNameLen != 0)\n                cp++;       // advance past the '/'\n\n            nextSlash = strchr(cp, '/');\n//xxx this may break if there are bare directory entries\n            if (nextSlash == NULL) {\n                /* this is a file in the requested directory */\n\n                info.set(String8(nameBuf).getPathLeaf(), kFileTypeRegular);\n\n                info.setSourceName(\n                    createZipSourceNameLocked(zipName, dirName, info.getFileName()));\n\n                contents.add(info);\n                //printf(\"FOUND: file '%s'\\n\", info.getFileName().string());\n            } else {\n                /* this is a subdir; add it if we don't already have it*/\n                String8 subdirName(cp, nextSlash - cp);\n                size_t j;\n                size_t N = dirs.size();\n\n                for (j = 0; j < N; j++) {\n                    if (subdirName == dirs[j]) {\n                        break;\n                    }\n                }\n                if (j == N) {\n                    dirs.add(subdirName);\n                }\n\n                //printf(\"FOUND: dir '%s'\\n\", subdirName.string());\n            }\n        }\n    }\n\n    pZip->endIteration(iterationCookie);\n\n    /*\n     * Add the set of unique directories.\n     */\n    for (int i = 0; i < (int) dirs.size(); i++) {\n        info.set(dirs[i], kFileTypeDirectory);\n        info.setSourceName(\n            createZipSourceNameLocked(zipName, dirName, info.getFileName()));\n        contents.add(info);\n    }\n\n    mergeInfoLocked(pMergedInfo, &contents);\n\n    return true;\n}\n\n\n/*\n * Merge two vectors of FileInfo.\n *\n * The merged contents will be stuffed into *pMergedInfo.\n *\n * If an entry for a file exists in both \"pMergedInfo\" and \"pContents\",\n * we use the newer \"pContents\" entry.\n */\nvoid AssetManager::mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n    const SortedVector<AssetDir::FileInfo>* pContents)\n{\n    /*\n     * Merge what we found in this directory with what we found in\n     * other places.\n     *\n     * Two basic approaches:\n     * (1) Create a new array that holds the unique values of the two\n     *     arrays.\n     * (2) Take the elements from pContents and shove them into pMergedInfo.\n     *\n     * Because these are vectors of complex objects, moving elements around\n     * inside the vector requires constructing new objects and allocating\n     * storage for members.  With approach #1, we're always adding to the\n     * end, whereas with #2 we could be inserting multiple elements at the\n     * front of the vector.  Approach #1 requires a full copy of the\n     * contents of pMergedInfo, but approach #2 requires the same copy for\n     * every insertion at the front of pMergedInfo.\n     *\n     * (We should probably use a SortedVector interface that allows us to\n     * just stuff items in, trusting us to maintain the sort order.)\n     */\n    SortedVector<AssetDir::FileInfo>* pNewSorted;\n    int mergeMax, contMax;\n    int mergeIdx, contIdx;\n\n    pNewSorted = new SortedVector<AssetDir::FileInfo>;\n    mergeMax = pMergedInfo->size();\n    contMax = pContents->size();\n    mergeIdx = contIdx = 0;\n\n    while (mergeIdx < mergeMax || contIdx < contMax) {\n        if (mergeIdx == mergeMax) {\n            /* hit end of \"merge\" list, copy rest of \"contents\" */\n            pNewSorted->add(pContents->itemAt(contIdx));\n            contIdx++;\n        } else if (contIdx == contMax) {\n            /* hit end of \"cont\" list, copy rest of \"merge\" */\n            pNewSorted->add(pMergedInfo->itemAt(mergeIdx));\n            mergeIdx++;\n        } else if (pMergedInfo->itemAt(mergeIdx) == pContents->itemAt(contIdx))\n        {\n            /* items are identical, add newer and advance both indices */\n            pNewSorted->add(pContents->itemAt(contIdx));\n            mergeIdx++;\n            contIdx++;\n        } else if (pMergedInfo->itemAt(mergeIdx) < pContents->itemAt(contIdx))\n        {\n            /* \"merge\" is lower, add that one */\n            pNewSorted->add(pMergedInfo->itemAt(mergeIdx));\n            mergeIdx++;\n        } else {\n            /* \"cont\" is lower, add that one */\n            assert(pContents->itemAt(contIdx) < pMergedInfo->itemAt(mergeIdx));\n            pNewSorted->add(pContents->itemAt(contIdx));\n            contIdx++;\n        }\n    }\n\n    /*\n     * Overwrite the \"merged\" list with the new stuff.\n     */\n    *pMergedInfo = *pNewSorted;\n    delete pNewSorted;\n\n#if 0       // for Vector, rather than SortedVector\n    int i, j;\n    for (i = pContents->size() -1; i >= 0; i--) {\n        bool add = true;\n\n        for (j = pMergedInfo->size() -1; j >= 0; j--) {\n            /* case-sensitive comparisons, to behave like UNIX fs */\n            if (strcmp(pContents->itemAt(i).mFileName,\n                       pMergedInfo->itemAt(j).mFileName) == 0)\n            {\n                /* match, don't add this entry */\n                add = false;\n                break;\n            }\n        }\n\n        if (add)\n            pMergedInfo->add(pContents->itemAt(i));\n    }\n#endif\n}\n\n\n/*\n * Load all files into the file name cache.  We want to do this across\n * all combinations of { appname, locale, vendor }, performing a recursive\n * directory traversal.\n *\n * This is not the most efficient data structure.  Also, gathering the\n * information as we needed it (file-by-file or directory-by-directory)\n * would be faster.  However, on the actual device, 99% of the files will\n * live in Zip archives, so this list will be very small.  The trouble\n * is that we have to check the \"loose\" files first, so it's important\n * that we don't beat the filesystem silly looking for files that aren't\n * there.\n *\n * Note on thread safety: this is the only function that causes updates\n * to mCache, and anybody who tries to use it will call here if !mCacheValid,\n * so we need to employ a mutex here.\n */\nvoid AssetManager::loadFileNameCacheLocked(void)\n{\n    assert(!mCacheValid);\n    assert(mCache.size() == 0);\n\n#ifdef DO_TIMINGS   // need to link against -lrt for this now\n    DurationTimer timer;\n    timer.start();\n#endif\n\n    fncScanLocked(&mCache, \"\");\n\n#ifdef DO_TIMINGS\n    timer.stop();\n    ALOGD(\"Cache scan took %.3fms\\n\",\n        timer.durationUsecs() / 1000.0);\n#endif\n\n#if 0\n    int i;\n    printf(\"CACHED FILE LIST (%d entries):\\n\", mCache.size());\n    for (i = 0; i < (int) mCache.size(); i++) {\n        printf(\" %d: (%d) '%s'\\n\", i,\n            mCache.itemAt(i).getFileType(),\n            (const char*) mCache.itemAt(i).getFileName());\n    }\n#endif\n\n    mCacheValid = true;\n}\n\n/*\n * Scan up to 8 versions of the specified directory.\n */\nvoid AssetManager::fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,\n    const char* dirName)\n{\n    size_t i = mAssetPaths.size();\n    while (i > 0) {\n        i--;\n        const asset_path& ap = mAssetPaths.itemAt(i);\n        fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, NULL, dirName);\n        if (mLocale != NULL)\n            fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, NULL, dirName);\n        if (mVendor != NULL)\n            fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, mVendor, dirName);\n        if (mLocale != NULL && mVendor != NULL)\n            fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, mVendor, dirName);\n    }\n}\n\n/*\n * Recursively scan this directory and all subdirs.\n *\n * This is similar to scanAndMergeDir, but we don't remove the .EXCLUDE\n * files, and we prepend the extended partial path to the filenames.\n */\nbool AssetManager::fncScanAndMergeDirLocked(\n    SortedVector<AssetDir::FileInfo>* pMergedInfo,\n    const asset_path& ap, const char* locale, const char* vendor,\n    const char* dirName)\n{\n    SortedVector<AssetDir::FileInfo>* pContents;\n    String8 partialPath;\n    String8 fullPath;\n\n    // XXX This is broken -- the filename cache needs to hold the base\n    // asset path separately from its filename.\n    \n    partialPath = createPathNameLocked(ap, locale, vendor);\n    if (dirName[0] != '\\0') {\n        partialPath.appendPath(dirName);\n    }\n\n    fullPath = partialPath;\n    pContents = scanDirLocked(fullPath);\n    if (pContents == NULL) {\n        return false;       // directory did not exist\n    }\n\n    /*\n     * Scan all subdirectories of the current dir, merging what we find\n     * into \"pMergedInfo\".\n     */\n    for (int i = 0; i < (int) pContents->size(); i++) {\n        if (pContents->itemAt(i).getFileType() == kFileTypeDirectory) {\n            String8 subdir(dirName);\n            subdir.appendPath(pContents->itemAt(i).getFileName());\n\n            fncScanAndMergeDirLocked(pMergedInfo, ap, locale, vendor, subdir.string());\n        }\n    }\n\n    /*\n     * To be consistent, we want entries for the root directory.  If\n     * we're the root, add one now.\n     */\n    if (dirName[0] == '\\0') {\n        AssetDir::FileInfo tmpInfo;\n\n        tmpInfo.set(String8(\"\"), kFileTypeDirectory);\n        tmpInfo.setSourceName(createPathNameLocked(ap, locale, vendor));\n        pContents->add(tmpInfo);\n    }\n\n    /*\n     * We want to prepend the extended partial path to every entry in\n     * \"pContents\".  It's the same value for each entry, so this will\n     * not change the sorting order of the vector contents.\n     */\n    for (int i = 0; i < (int) pContents->size(); i++) {\n        const AssetDir::FileInfo& info = pContents->itemAt(i);\n        pContents->editItemAt(i).setFileName(partialPath.appendPathCopy(info.getFileName()));\n    }\n\n    mergeInfoLocked(pMergedInfo, pContents);\n    delete pContents;\n    return true;\n}\n\n/*\n * Trash the cache.\n */\nvoid AssetManager::purgeFileNameCacheLocked(void)\n{\n    mCacheValid = false;\n    mCache.clear();\n}\n\n/*\n * ===========================================================================\n *      AssetManager::SharedZip\n * ===========================================================================\n */\n\n\nMutex AssetManager::SharedZip::gLock;\nDefaultKeyedVector<String8, wp<AssetManager::SharedZip> > AssetManager::SharedZip::gOpen;\n\nAssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen)\n    : mPath(path), mZipFile(NULL), mModWhen(modWhen),\n      mResourceTableAsset(NULL), mResourceTable(NULL)\n{\n    //ALOGI(\"Creating SharedZip %p %s\\n\", this, (const char*)mPath);\n    ALOGV(\"+++ opening zip '%s'\\n\", mPath.string());\n    mZipFile = ZipFileRO::open(mPath.string());\n    if (mZipFile == NULL) {\n        ALOGD(\"failed to open Zip archive '%s'\\n\", mPath.string());\n    }\n}\n\nsp<AssetManager::SharedZip> AssetManager::SharedZip::get(const String8& path,\n        bool createIfNotPresent)\n{\n    AutoMutex _l(gLock);\n    time_t modWhen = getFileModDate(path);\n    sp<SharedZip> zip = gOpen.valueFor(path).promote();\n    if (zip != NULL && zip->mModWhen == modWhen) {\n        return zip;\n    }\n    if (zip == NULL && !createIfNotPresent) {\n        return NULL;\n    }\n    zip = new SharedZip(path, modWhen);\n    gOpen.add(path, zip);\n    return zip;\n\n}\n\nZipFileRO* AssetManager::SharedZip::getZip()\n{\n    return mZipFile;\n}\n\nAsset* AssetManager::SharedZip::getResourceTableAsset()\n{\n    ALOGV(\"Getting from SharedZip %p resource asset %p\\n\", this, mResourceTableAsset);\n    return mResourceTableAsset;\n}\n\nAsset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset)\n{\n    {\n        AutoMutex _l(gLock);\n        if (mResourceTableAsset == NULL) {\n            mResourceTableAsset = asset;\n            // This is not thread safe the first time it is called, so\n            // do it here with the global lock held.\n            asset->getBuffer(true);\n            return asset;\n        }\n    }\n    delete asset;\n    return mResourceTableAsset;\n}\n\nResTable* AssetManager::SharedZip::getResourceTable()\n{\n    ALOGV(\"Getting from SharedZip %p resource table %p\\n\", this, mResourceTable);\n    return mResourceTable;\n}\n\nResTable* AssetManager::SharedZip::setResourceTable(ResTable* res)\n{\n    {\n        AutoMutex _l(gLock);\n        if (mResourceTable == NULL) {\n            mResourceTable = res;\n            return res;\n        }\n    }\n    delete res;\n    return mResourceTable;\n}\n\nbool AssetManager::SharedZip::isUpToDate()\n{\n    time_t modWhen = getFileModDate(mPath.string());\n    return mModWhen == modWhen;\n}\n\nvoid AssetManager::SharedZip::addOverlay(const asset_path& ap)\n{\n    mOverlays.add(ap);\n}\n\nbool AssetManager::SharedZip::getOverlay(size_t idx, asset_path* out) const\n{\n    if (idx >= mOverlays.size()) {\n        return false;\n    }\n    *out = mOverlays[idx];\n    return true;\n}\n\nAssetManager::SharedZip::~SharedZip()\n{\n    //ALOGI(\"Destroying SharedZip %p %s\\n\", this, (const char*)mPath);\n    if (mResourceTable != NULL) {\n        delete mResourceTable;\n    }\n    if (mResourceTableAsset != NULL) {\n        delete mResourceTableAsset;\n    }\n    if (mZipFile != NULL) {\n        delete mZipFile;\n        ALOGV(\"Closed '%s'\\n\", mPath.string());\n    }\n}\n\n/*\n * ===========================================================================\n *      AssetManager::ZipSet\n * ===========================================================================\n */\n\n/*\n * Constructor.\n */\nAssetManager::ZipSet::ZipSet(void)\n{\n}\n\n/*\n * Destructor.  Close any open archives.\n */\nAssetManager::ZipSet::~ZipSet(void)\n{\n    size_t N = mZipFile.size();\n    for (size_t i = 0; i < N; i++)\n        closeZip(i);\n}\n\n/*\n * Close a Zip file and reset the entry.\n */\nvoid AssetManager::ZipSet::closeZip(int idx)\n{\n    mZipFile.editItemAt(idx) = NULL;\n}\n\n\n/*\n * Retrieve the appropriate Zip file from the set.\n */\nZipFileRO* AssetManager::ZipSet::getZip(const String8& path)\n{\n    int idx = getIndex(path);\n    sp<SharedZip> zip = mZipFile[idx];\n    if (zip == NULL) {\n        zip = SharedZip::get(path);\n        mZipFile.editItemAt(idx) = zip;\n    }\n    return zip->getZip();\n}\n\nAsset* AssetManager::ZipSet::getZipResourceTableAsset(const String8& path)\n{\n    int idx = getIndex(path);\n    sp<SharedZip> zip = mZipFile[idx];\n    if (zip == NULL) {\n        zip = SharedZip::get(path);\n        mZipFile.editItemAt(idx) = zip;\n    }\n    return zip->getResourceTableAsset();\n}\n\nAsset* AssetManager::ZipSet::setZipResourceTableAsset(const String8& path,\n                                                 Asset* asset)\n{\n    int idx = getIndex(path);\n    sp<SharedZip> zip = mZipFile[idx];\n    // doesn't make sense to call before previously accessing.\n    return zip->setResourceTableAsset(asset);\n}\n\nResTable* AssetManager::ZipSet::getZipResourceTable(const String8& path)\n{\n    int idx = getIndex(path);\n    sp<SharedZip> zip = mZipFile[idx];\n    if (zip == NULL) {\n        zip = SharedZip::get(path);\n        mZipFile.editItemAt(idx) = zip;\n    }\n    return zip->getResourceTable();\n}\n\nResTable* AssetManager::ZipSet::setZipResourceTable(const String8& path,\n                                                    ResTable* res)\n{\n    int idx = getIndex(path);\n    sp<SharedZip> zip = mZipFile[idx];\n    // doesn't make sense to call before previously accessing.\n    return zip->setResourceTable(res);\n}\n\n/*\n * Generate the partial pathname for the specified archive.  The caller\n * gets to prepend the asset root directory.\n *\n * Returns something like \"common/en-US-noogle.jar\".\n */\n/*static*/ String8 AssetManager::ZipSet::getPathName(const char* zipPath)\n{\n    return String8(zipPath);\n}\n\nbool AssetManager::ZipSet::isUpToDate()\n{\n    const size_t N = mZipFile.size();\n    for (size_t i=0; i<N; i++) {\n        if (mZipFile[i] != NULL && !mZipFile[i]->isUpToDate()) {\n            return false;\n        }\n    }\n    return true;\n}\n\nvoid AssetManager::ZipSet::addOverlay(const String8& path, const asset_path& overlay)\n{\n    int idx = getIndex(path);\n    sp<SharedZip> zip = mZipFile[idx];\n    zip->addOverlay(overlay);\n}\n\nbool AssetManager::ZipSet::getOverlay(const String8& path, size_t idx, asset_path* out) const\n{\n    sp<SharedZip> zip = SharedZip::get(path, false);\n    if (zip == NULL) {\n        return false;\n    }\n    return zip->getOverlay(idx, out);\n}\n\n/*\n * Compute the zip file's index.\n *\n * \"appName\", \"locale\", and \"vendor\" should be set to NULL to indicate the\n * default directory.\n */\nint AssetManager::ZipSet::getIndex(const String8& zip) const\n{\n    const size_t N = mZipPath.size();\n    for (size_t i=0; i<N; i++) {\n        if (mZipPath[i] == zip) {\n            return i;\n        }\n    }\n\n    mZipPath.add(zip);\n    mZipFile.add(NULL);\n\n    return mZipPath.size()-1;\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/BackupData.cpp",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"backup_data\"\n\n#include <androidfw/BackupHelpers.h>\n#include <utils/ByteOrder.h>\n\n#include <stdio.h>\n#include <string.h>\n#include <unistd.h>\n\n#include <cutils/log.h>\n\nnamespace android {\n\nstatic const bool DEBUG = false;\n\n/*\n * File Format (v1):\n *\n * All ints are stored little-endian.\n *\n *  - An app_header_v1 struct.\n *  - The name of the package, utf-8, null terminated, padded to 4-byte boundary.\n *  - A sequence of zero or more key/value paires (entities), each with\n *      - A entity_header_v1 struct\n *      - The key, utf-8, null terminated, padded to 4-byte boundary.\n *      - The value, padded to 4 byte boundary\n */\n\nconst static int ROUND_UP[4] = { 0, 3, 2, 1 };\n\nstatic inline size_t\nround_up(size_t n)\n{\n    return n + ROUND_UP[n % 4];\n}\n\nstatic inline size_t\npadding_extra(size_t n)\n{\n    return ROUND_UP[n % 4];\n}\n\nBackupDataWriter::BackupDataWriter(int fd)\n    :m_fd(fd),\n     m_status(NO_ERROR),\n     m_entityCount(0)\n{\n    m_pos = (ssize_t) lseek(fd, 0, SEEK_CUR);\n    if (DEBUG) ALOGI(\"BackupDataWriter(%d) @ %ld\", fd, (long)m_pos);\n}\n\nBackupDataWriter::~BackupDataWriter()\n{\n}\n\n// Pad out anything they've previously written to the next 4 byte boundary.\nstatus_t\nBackupDataWriter::write_padding_for(int n)\n{\n    ssize_t amt;\n    ssize_t paddingSize;\n\n    paddingSize = padding_extra(n);\n    if (paddingSize > 0) {\n        uint32_t padding = 0xbcbcbcbc;\n        if (DEBUG) ALOGI(\"writing %zd padding bytes for %d\", paddingSize, n);\n        amt = write(m_fd, &padding, paddingSize);\n        if (amt != paddingSize) {\n            m_status = errno;\n            return m_status;\n        }\n        m_pos += amt;\n    }\n    return NO_ERROR;\n}\n\nstatus_t\nBackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize)\n{\n    if (m_status != NO_ERROR) {\n        return m_status;\n    }\n\n    ssize_t amt;\n\n    amt = write_padding_for(m_pos);\n    if (amt != 0) {\n        return amt;\n    }\n\n    String8 k;\n    if (m_keyPrefix.length() > 0) {\n        k = m_keyPrefix;\n        k += \":\";\n        k += key;\n    } else {\n        k = key;\n    }\n    if (DEBUG) {\n        ALOGD(\"Writing header: prefix='%s' key='%s' dataSize=%zu\", m_keyPrefix.string(),\n                key.string(), dataSize);\n    }\n\n    entity_header_v1 header;\n    ssize_t keyLen;\n\n    keyLen = k.length();\n\n    header.type = tolel(BACKUP_HEADER_ENTITY_V1);\n    header.keyLen = tolel(keyLen);\n    header.dataSize = tolel(dataSize);\n\n    if (DEBUG) ALOGI(\"writing entity header, %zu bytes\", sizeof(entity_header_v1));\n    amt = write(m_fd, &header, sizeof(entity_header_v1));\n    if (amt != sizeof(entity_header_v1)) {\n        m_status = errno;\n        return m_status;\n    }\n    m_pos += amt;\n\n    if (DEBUG) ALOGI(\"writing entity header key, %zd bytes\", keyLen+1);\n    amt = write(m_fd, k.string(), keyLen+1);\n    if (amt != keyLen+1) {\n        m_status = errno;\n        return m_status;\n    }\n    m_pos += amt;\n\n    amt = write_padding_for(keyLen+1);\n\n    m_entityCount++;\n\n    return amt;\n}\n\nstatus_t\nBackupDataWriter::WriteEntityData(const void* data, size_t size)\n{\n    if (DEBUG) ALOGD(\"Writing data: size=%lu\", (unsigned long) size);\n\n    if (m_status != NO_ERROR) {\n        if (DEBUG) {\n            ALOGD(\"Not writing data - stream in error state %d (%s)\", m_status, strerror(m_status));\n        }\n        return m_status;\n    }\n\n    // We don't write padding here, because they're allowed to call this several\n    // times with smaller buffers.  We write it at the end of WriteEntityHeader\n    // instead.\n    ssize_t amt = write(m_fd, data, size);\n    if (amt != (ssize_t)size) {\n        m_status = errno;\n        if (DEBUG) ALOGD(\"write returned error %d (%s)\", m_status, strerror(m_status));\n        return m_status;\n    }\n    m_pos += amt;\n    return NO_ERROR;\n}\n\nvoid\nBackupDataWriter::SetKeyPrefix(const String8& keyPrefix)\n{\n    m_keyPrefix = keyPrefix;\n}\n\n\nBackupDataReader::BackupDataReader(int fd)\n    :m_fd(fd),\n     m_done(false),\n     m_status(NO_ERROR),\n     m_entityCount(0)\n{\n    memset(&m_header, 0, sizeof(m_header));\n    m_pos = (ssize_t) lseek(fd, 0, SEEK_CUR);\n    if (DEBUG) ALOGI(\"BackupDataReader(%d) @ %ld\", fd, (long)m_pos);\n}\n\nBackupDataReader::~BackupDataReader()\n{\n}\n\nstatus_t\nBackupDataReader::Status()\n{\n    return m_status;\n}\n\n#define CHECK_SIZE(actual, expected) \\\n    do { \\\n        if ((actual) != (expected)) { \\\n            if ((actual) == 0) { \\\n                m_status = EIO; \\\n                m_done = true; \\\n            } else { \\\n                m_status = errno; \\\n                ALOGD(\"CHECK_SIZE(a=%ld e=%ld) failed at line %d m_status='%s'\", \\\n                    long(actual), long(expected), __LINE__, strerror(m_status)); \\\n            } \\\n            return m_status; \\\n        } \\\n    } while(0)\n#define SKIP_PADDING() \\\n    do { \\\n        status_t err = skip_padding(); \\\n        if (err != NO_ERROR) { \\\n            ALOGD(\"SKIP_PADDING FAILED at line %d\", __LINE__); \\\n            m_status = err; \\\n            return err; \\\n        } \\\n    } while(0)\n\nstatus_t\nBackupDataReader::ReadNextHeader(bool* done, int* type)\n{\n    *done = m_done;\n    if (m_status != NO_ERROR) {\n        return m_status;\n    }\n\n    int amt;\n\n    amt = skip_padding();\n    if (amt == EIO) {\n        *done = m_done = true;\n        return NO_ERROR;\n    }\n    else if (amt != NO_ERROR) {\n        return amt;\n    }\n    amt = read(m_fd, &m_header, sizeof(m_header));\n    *done = m_done = (amt == 0);\n    if (*done) {\n        return NO_ERROR;\n    }\n    CHECK_SIZE(amt, sizeof(m_header));\n    m_pos += sizeof(m_header);\n    if (type) {\n        *type = m_header.type;\n    }\n\n    // validate and fix up the fields.\n    m_header.type = fromlel(m_header.type);\n    switch (m_header.type)\n    {\n        case BACKUP_HEADER_ENTITY_V1:\n        {\n            m_header.entity.keyLen = fromlel(m_header.entity.keyLen);\n            if (m_header.entity.keyLen <= 0) {\n                ALOGD(\"Entity header at %d has keyLen<=0: 0x%08x\\n\", (int)m_pos,\n                        (int)m_header.entity.keyLen);\n                m_status = EINVAL;\n            }\n            m_header.entity.dataSize = fromlel(m_header.entity.dataSize);\n            m_entityCount++;\n\n            // read the rest of the header (filename)\n            size_t size = m_header.entity.keyLen;\n            char* buf = m_key.lockBuffer(size);\n            if (buf == NULL) {\n                m_status = ENOMEM;\n                return m_status;\n            }\n            int amt = read(m_fd, buf, size+1);\n            CHECK_SIZE(amt, (int)size+1);\n            m_key.unlockBuffer(size);\n            m_pos += size+1;\n            SKIP_PADDING();\n            m_dataEndPos = m_pos + m_header.entity.dataSize;\n\n            break;\n        }\n        default:\n            ALOGD(\"Chunk header at %d has invalid type: 0x%08x\",\n                    (int)(m_pos - sizeof(m_header)), (int)m_header.type);\n            m_status = EINVAL;\n    }\n\n    return m_status;\n}\n\nbool\nBackupDataReader::HasEntities()\n{\n    return m_status == NO_ERROR && m_header.type == BACKUP_HEADER_ENTITY_V1;\n}\n\nstatus_t\nBackupDataReader::ReadEntityHeader(String8* key, size_t* dataSize)\n{\n    if (m_status != NO_ERROR) {\n        return m_status;\n    }\n    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {\n        return EINVAL;\n    }\n    *key = m_key;\n    *dataSize = m_header.entity.dataSize;\n    return NO_ERROR;\n}\n\nstatus_t\nBackupDataReader::SkipEntityData()\n{\n    if (m_status != NO_ERROR) {\n        return m_status;\n    }\n    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {\n        return EINVAL;\n    }\n    if (m_header.entity.dataSize > 0) {\n        int pos = lseek(m_fd, m_dataEndPos, SEEK_SET);\n        if (pos == -1) {\n            return errno;\n        }\n        m_pos = pos;\n    }\n    SKIP_PADDING();\n    return NO_ERROR;\n}\n\nssize_t\nBackupDataReader::ReadEntityData(void* data, size_t size)\n{\n    if (m_status != NO_ERROR) {\n        return -1;\n    }\n    int remaining = m_dataEndPos - m_pos;\n    //ALOGD(\"ReadEntityData size=%d m_pos=0x%x m_dataEndPos=0x%x remaining=%d\\n\",\n    //        size, m_pos, m_dataEndPos, remaining);\n    if (remaining <= 0) {\n        return 0;\n    }\n    if (((int)size) > remaining) {\n        size = remaining;\n    }\n    //ALOGD(\"   reading %d bytes\", size);\n    int amt = read(m_fd, data, size);\n    if (amt < 0) {\n        m_status = errno;\n        return -1;\n    }\n    if (amt == 0) {\n        m_status = EIO;\n        m_done = true;\n    }\n    m_pos += amt;\n    return amt;\n}\n\nstatus_t\nBackupDataReader::skip_padding()\n{\n    ssize_t amt;\n    ssize_t paddingSize;\n\n    paddingSize = padding_extra(m_pos);\n    if (paddingSize > 0) {\n        uint32_t padding;\n        amt = read(m_fd, &padding, paddingSize);\n        CHECK_SIZE(amt, paddingSize);\n        m_pos += amt;\n    }\n    return NO_ERROR;\n}\n\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/BackupHelpers.cpp",
    "content": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"file_backup_helper\"\n\n#include <androidfw/BackupHelpers.h>\n\n#include <utils/KeyedVector.h>\n#include <utils/ByteOrder.h>\n#include <utils/String8.h>\n\n#include <errno.h>\n#include <sys/types.h>\n#include <sys/uio.h>\n#include <sys/stat.h>\n#include <sys/time.h>  // for utimes\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <utime.h>\n#include <fcntl.h>\n#include <zlib.h>\n\n#include <cutils/log.h>\n\nnamespace android {\n\n#define MAGIC0 0x70616e53 // Snap\n#define MAGIC1 0x656c6946 // File\n\n/*\n * File entity data format (v1):\n *\n *   - 4-byte version number of the metadata, little endian (0x00000001 for v1)\n *   - 12 bytes of metadata\n *   - the file data itself\n *\n * i.e. a 16-byte metadata header followed by the raw file data.  If the\n * restore code does not recognize the metadata version, it can still\n * interpret the file data itself correctly.\n *\n * file_metadata_v1:\n *\n *   - 4 byte version number === 0x00000001 (little endian)\n *   - 4-byte access mode (little-endian)\n *   - undefined (8 bytes)\n */\n\nstruct file_metadata_v1 {\n    int version;\n    int mode;\n    int undefined_1;\n    int undefined_2;\n};\n\nconst static int CURRENT_METADATA_VERSION = 1;\n\n#if 1\n#define LOGP(f, x...)\n#else\n#if TEST_BACKUP_HELPERS\n#define LOGP(f, x...) printf(f \"\\n\", x)\n#else\n#define LOGP(x...) ALOGD(x)\n#endif\n#endif\n\nconst static int ROUND_UP[4] = { 0, 3, 2, 1 };\n\nstatic inline int\nround_up(int n)\n{\n    return n + ROUND_UP[n % 4];\n}\n\nstatic int\nread_snapshot_file(int fd, KeyedVector<String8,FileState>* snapshot)\n{\n    int bytesRead = 0;\n    int amt;\n    SnapshotHeader header;\n\n    amt = read(fd, &header, sizeof(header));\n    if (amt != sizeof(header)) {\n        return errno;\n    }\n    bytesRead += amt;\n\n    if (header.magic0 != MAGIC0 || header.magic1 != MAGIC1) {\n        ALOGW(\"read_snapshot_file header.magic0=0x%08x magic1=0x%08x\", header.magic0, header.magic1);\n        return 1;\n    }\n\n    for (int i=0; i<header.fileCount; i++) {\n        FileState file;\n        char filenameBuf[128];\n\n        amt = read(fd, &file, sizeof(FileState));\n        if (amt != sizeof(FileState)) {\n            ALOGW(\"read_snapshot_file FileState truncated/error with read at %d bytes\\n\", bytesRead);\n            return 1;\n        }\n        bytesRead += amt;\n\n        // filename is not NULL terminated, but it is padded\n        int nameBufSize = round_up(file.nameLen);\n        char* filename = nameBufSize <= (int)sizeof(filenameBuf)\n                ? filenameBuf\n                : (char*)malloc(nameBufSize);\n        amt = read(fd, filename, nameBufSize);\n        if (amt == nameBufSize) {\n            snapshot->add(String8(filename, file.nameLen), file);\n        }\n        bytesRead += amt;\n        if (filename != filenameBuf) {\n            free(filename);\n        }\n        if (amt != nameBufSize) {\n            ALOGW(\"read_snapshot_file filename truncated/error with read at %d bytes\\n\", bytesRead);\n            return 1;\n        }\n    }\n\n    if (header.totalSize != bytesRead) {\n        ALOGW(\"read_snapshot_file length mismatch: header.totalSize=%d bytesRead=%d\\n\",\n                header.totalSize, bytesRead);\n        return 1;\n    }\n\n    return 0;\n}\n\nstatic int\nwrite_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot)\n{\n    int fileCount = 0;\n    int bytesWritten = sizeof(SnapshotHeader);\n    // preflight size\n    const int N = snapshot.size();\n    for (int i=0; i<N; i++) {\n        const FileRec& g = snapshot.valueAt(i);\n        if (!g.deleted) {\n            const String8& name = snapshot.keyAt(i);\n            bytesWritten += sizeof(FileState) + round_up(name.length());\n            fileCount++;\n        }\n    }\n\n    LOGP(\"write_snapshot_file fd=%d\\n\", fd);\n\n    int amt;\n    SnapshotHeader header = { MAGIC0, fileCount, MAGIC1, bytesWritten };\n\n    amt = write(fd, &header, sizeof(header));\n    if (amt != sizeof(header)) {\n        ALOGW(\"write_snapshot_file error writing header %s\", strerror(errno));\n        return errno;\n    }\n\n    for (int i=0; i<N; i++) {\n        FileRec r = snapshot.valueAt(i);\n        if (!r.deleted) {\n            const String8& name = snapshot.keyAt(i);\n            int nameLen = r.s.nameLen = name.length();\n\n            amt = write(fd, &r.s, sizeof(FileState));\n            if (amt != sizeof(FileState)) {\n                ALOGW(\"write_snapshot_file error writing header %s\", strerror(errno));\n                return 1;\n            }\n\n            // filename is not NULL terminated, but it is padded\n            amt = write(fd, name.string(), nameLen);\n            if (amt != nameLen) {\n                ALOGW(\"write_snapshot_file error writing filename %s\", strerror(errno));\n                return 1;\n            }\n            int paddingLen = ROUND_UP[nameLen % 4];\n            if (paddingLen != 0) {\n                int padding = 0xabababab;\n                amt = write(fd, &padding, paddingLen);\n                if (amt != paddingLen) {\n                    ALOGW(\"write_snapshot_file error writing %d bytes of filename padding %s\",\n                            paddingLen, strerror(errno));\n                    return 1;\n                }\n            }\n        }\n    }\n\n    return 0;\n}\n\nstatic int\nwrite_delete_file(BackupDataWriter* dataStream, const String8& key)\n{\n    LOGP(\"write_delete_file %s\\n\", key.string());\n    return dataStream->WriteEntityHeader(key, -1);\n}\n\nstatic int\nwrite_update_file(BackupDataWriter* dataStream, int fd, int mode, const String8& key,\n        char const* realFilename)\n{\n    LOGP(\"write_update_file %s (%s) : mode 0%o\\n\", realFilename, key.string(), mode);\n\n    const int bufsize = 4*1024;\n    int err;\n    int amt;\n    int fileSize;\n    int bytesLeft;\n    file_metadata_v1 metadata;\n\n    char* buf = (char*)malloc(bufsize);\n    int crc = crc32(0L, Z_NULL, 0);\n\n\n    fileSize = lseek(fd, 0, SEEK_END);\n    lseek(fd, 0, SEEK_SET);\n\n    if (sizeof(metadata) != 16) {\n        ALOGE(\"ERROR: metadata block is the wrong size!\");\n    }\n\n    bytesLeft = fileSize + sizeof(metadata);\n    err = dataStream->WriteEntityHeader(key, bytesLeft);\n    if (err != 0) {\n        free(buf);\n        return err;\n    }\n\n    // store the file metadata first\n    metadata.version = tolel(CURRENT_METADATA_VERSION);\n    metadata.mode = tolel(mode);\n    metadata.undefined_1 = metadata.undefined_2 = 0;\n    err = dataStream->WriteEntityData(&metadata, sizeof(metadata));\n    if (err != 0) {\n        free(buf);\n        return err;\n    }\n    bytesLeft -= sizeof(metadata); // bytesLeft should == fileSize now\n\n    // now store the file content\n    while ((amt = read(fd, buf, bufsize)) != 0 && bytesLeft > 0) {\n        bytesLeft -= amt;\n        if (bytesLeft < 0) {\n            amt += bytesLeft; // Plus a negative is minus.  Don't write more than we promised.\n        }\n        err = dataStream->WriteEntityData(buf, amt);\n        if (err != 0) {\n            free(buf);\n            return err;\n        }\n    }\n    if (bytesLeft != 0) {\n        if (bytesLeft > 0) {\n            // Pad out the space we promised in the buffer.  We can't corrupt the buffer,\n            // even though the data we're sending is probably bad.\n            memset(buf, 0, bufsize);\n            while (bytesLeft > 0) {\n                amt = bytesLeft < bufsize ? bytesLeft : bufsize;\n                bytesLeft -= amt;\n                err = dataStream->WriteEntityData(buf, amt);\n                if (err != 0) {\n                    free(buf);\n                    return err;\n                }\n            }\n        }\n        ALOGE(\"write_update_file size mismatch for %s. expected=%d actual=%d.\"\n                \" You aren't doing proper locking!\", realFilename, fileSize, fileSize-bytesLeft);\n    }\n\n    free(buf);\n    return NO_ERROR;\n}\n\nstatic int\nwrite_update_file(BackupDataWriter* dataStream, const String8& key, char const* realFilename)\n{\n    int err;\n    struct stat st;\n\n    err = stat(realFilename, &st);\n    if (err < 0) {\n        return errno;\n    }\n\n    int fd = open(realFilename, O_RDONLY);\n    if (fd == -1) {\n        return errno;\n    }\n\n    err = write_update_file(dataStream, fd, st.st_mode, key, realFilename);\n    close(fd);\n    return err;\n}\n\nstatic int\ncompute_crc32(int fd)\n{\n    const int bufsize = 4*1024;\n    int amt;\n\n    char* buf = (char*)malloc(bufsize);\n    int crc = crc32(0L, Z_NULL, 0);\n\n    lseek(fd, 0, SEEK_SET);\n\n    while ((amt = read(fd, buf, bufsize)) != 0) {\n        crc = crc32(crc, (Bytef*)buf, amt);\n    }\n\n    free(buf);\n    return crc;\n}\n\nint\nback_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,\n        char const* const* files, char const* const* keys, int fileCount)\n{\n    int err;\n    KeyedVector<String8,FileState> oldSnapshot;\n    KeyedVector<String8,FileRec> newSnapshot;\n\n    if (oldSnapshotFD != -1) {\n        err = read_snapshot_file(oldSnapshotFD, &oldSnapshot);\n        if (err != 0) {\n            // On an error, treat this as a full backup.\n            oldSnapshot.clear();\n        }\n    }\n\n    for (int i=0; i<fileCount; i++) {\n        String8 key(keys[i]);\n        FileRec r;\n        char const* file = files[i];\n        r.file = file;\n        struct stat st;\n\n        err = stat(file, &st);\n        if (err != 0) {\n            r.deleted = true;\n        } else {\n            r.deleted = false;\n            r.s.modTime_sec = st.st_mtime;\n            r.s.modTime_nsec = 0; // workaround sim breakage\n            //r.s.modTime_nsec = st.st_mtime_nsec;\n            r.s.mode = st.st_mode;\n            r.s.size = st.st_size;\n            // we compute the crc32 later down below, when we already have the file open.\n\n            if (newSnapshot.indexOfKey(key) >= 0) {\n                LOGP(\"back_up_files key already in use '%s'\", key.string());\n                return -1;\n            }\n        }\n        newSnapshot.add(key, r);\n    }\n\n    int n = 0;\n    int N = oldSnapshot.size();\n    int m = 0;\n\n    while (n<N && m<fileCount) {\n        const String8& p = oldSnapshot.keyAt(n);\n        const String8& q = newSnapshot.keyAt(m);\n        FileRec& g = newSnapshot.editValueAt(m);\n        int cmp = p.compare(q);\n        if (g.deleted || cmp < 0) {\n            // file removed\n            LOGP(\"file removed: %s\", p.string());\n            g.deleted = true; // They didn't mention the file, but we noticed that it's gone.\n            dataStream->WriteEntityHeader(p, -1);\n            n++;\n        }\n        else if (cmp > 0) {\n            // file added\n            LOGP(\"file added: %s\", g.file.string());\n            write_update_file(dataStream, q, g.file.string());\n            m++;\n        }\n        else {\n            // both files exist, check them\n            const FileState& f = oldSnapshot.valueAt(n);\n\n            int fd = open(g.file.string(), O_RDONLY);\n            if (fd < 0) {\n                // We can't open the file.  Don't report it as a delete either.  Let the\n                // server keep the old version.  Maybe they'll be able to deal with it\n                // on restore.\n                LOGP(\"Unable to open file %s - skipping\", g.file.string());\n            } else {\n                g.s.crc32 = compute_crc32(fd);\n\n                LOGP(\"%s\", q.string());\n                LOGP(\"  new: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x\",\n                        f.modTime_sec, f.modTime_nsec, f.mode, f.size, f.crc32);\n                LOGP(\"  old: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x\",\n                        g.s.modTime_sec, g.s.modTime_nsec, g.s.mode, g.s.size, g.s.crc32);\n                if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec\n                        || f.mode != g.s.mode || f.size != g.s.size || f.crc32 != g.s.crc32) {\n                    write_update_file(dataStream, fd, g.s.mode, p, g.file.string());\n                }\n\n                close(fd);\n            }\n            n++;\n            m++;\n        }\n    }\n\n    // these were deleted\n    while (n<N) {\n        dataStream->WriteEntityHeader(oldSnapshot.keyAt(n), -1);\n        n++;\n    }\n\n    // these were added\n    while (m<fileCount) {\n        const String8& q = newSnapshot.keyAt(m);\n        FileRec& g = newSnapshot.editValueAt(m);\n        write_update_file(dataStream, q, g.file.string());\n        m++;\n    }\n\n    err = write_snapshot_file(newSnapshotFD, newSnapshot);\n\n    return 0;\n}\n\n// Utility function, equivalent to stpcpy(): perform a strcpy, but instead of\n// returning the initial dest, return a pointer to the trailing NUL.\nstatic char* strcpy_ptr(char* dest, const char* str) {\n    if (dest && str) {\n        while ((*dest = *str) != 0) {\n            dest++;\n            str++;\n        }\n    }\n    return dest;\n}\n\nstatic void calc_tar_checksum(char* buf) {\n    // [ 148 :   8 ] checksum -- to be calculated with this field as space chars\n    memset(buf + 148, ' ', 8);\n\n    uint16_t sum = 0;\n    for (uint8_t* p = (uint8_t*) buf; p < ((uint8_t*)buf) + 512; p++) {\n        sum += *p;\n    }\n\n    // Now write the real checksum value:\n    // [ 148 :   8 ]  checksum: 6 octal digits [leading zeroes], NUL, SPC\n    sprintf(buf + 148, \"%06o\", sum); // the trailing space is already in place\n}\n\n// Returns number of bytes written\nstatic int write_pax_header_entry(char* buf, const char* key, const char* value) {\n    // start with the size of \"1 key=value\\n\"\n    int len = strlen(key) + strlen(value) + 4;\n    if (len > 9) len++;\n    if (len > 99) len++;\n    if (len > 999) len++;\n    // since PATH_MAX is 4096 we don't expect to have to generate any single\n    // header entry longer than 9999 characters\n\n    return sprintf(buf, \"%d %s=%s\\n\", len, key, value);\n}\n\n// Wire format to the backup manager service is chunked:  each chunk is prefixed by\n// a 4-byte count of its size.  A chunk size of zero (four zero bytes) indicates EOD.\nvoid send_tarfile_chunk(BackupDataWriter* writer, const char* buffer, size_t size) {\n    uint32_t chunk_size_no = htonl(size);\n    writer->WriteEntityData(&chunk_size_no, 4);\n    if (size != 0) writer->WriteEntityData(buffer, size);\n}\n\nint write_tarfile(const String8& packageName, const String8& domain,\n        const String8& rootpath, const String8& filepath, BackupDataWriter* writer)\n{\n    // In the output stream everything is stored relative to the root\n    const char* relstart = filepath.string() + rootpath.length();\n    if (*relstart == '/') relstart++;     // won't be true when path == rootpath\n    String8 relpath(relstart);\n\n    // If relpath is empty, it means this is the top of one of the standard named\n    // domain directories, so we should just skip it\n    if (relpath.length() == 0) {\n        return 0;\n    }\n\n    // Too long a name for the ustar format?\n    //    \"apps/\" + packagename + '/' + domainpath < 155 chars\n    //    relpath < 100 chars\n    bool needExtended = false;\n    if ((5 + packageName.length() + 1 + domain.length() >= 155) || (relpath.length() >= 100)) {\n        needExtended = true;\n    }\n\n    // Non-7bit-clean path also means needing pax extended format\n    if (!needExtended) {\n        for (size_t i = 0; i < filepath.length(); i++) {\n            if ((filepath[i] & 0x80) != 0) {\n                needExtended = true;\n                break;\n            }\n        }\n    }\n\n    int err = 0;\n    struct stat64 s;\n    if (lstat64(filepath.string(), &s) != 0) {\n        err = errno;\n        ALOGE(\"Error %d (%s) from lstat64(%s)\", err, strerror(err), filepath.string());\n        return err;\n    }\n\n    String8 fullname;   // for pax later on\n    String8 prefix;\n\n    const int isdir = S_ISDIR(s.st_mode);\n    if (isdir) s.st_size = 0;   // directories get no actual data in the tar stream\n\n    // !!! TODO: use mmap when possible to avoid churning the buffer cache\n    // !!! TODO: this will break with symlinks; need to use readlink(2)\n    int fd = open(filepath.string(), O_RDONLY);\n    if (fd < 0) {\n        err = errno;\n        ALOGE(\"Error %d (%s) from open(%s)\", err, strerror(err), filepath.string());\n        return err;\n    }\n\n    // read/write up to this much at a time.\n    const size_t BUFSIZE = 32 * 1024;\n    char* buf = (char *)calloc(1,BUFSIZE);\n    char* paxHeader = buf + 512;    // use a different chunk of it as separate scratch\n    char* paxData = buf + 1024;\n\n    if (buf == NULL) {\n        ALOGE(\"Out of mem allocating transfer buffer\");\n        err = ENOMEM;\n        goto done;\n    }\n\n    // Magic fields for the ustar file format\n    strcat(buf + 257, \"ustar\");\n    strcat(buf + 263, \"00\");\n\n    // [ 265 : 32 ] user name, ignored on restore\n    // [ 297 : 32 ] group name, ignored on restore\n\n    // [ 100 :   8 ] file mode\n    snprintf(buf + 100, 8, \"%06o \", s.st_mode & ~S_IFMT);\n\n    // [ 108 :   8 ] uid -- ignored in Android format; uids are remapped at restore time\n    // [ 116 :   8 ] gid -- ignored in Android format\n    snprintf(buf + 108, 8, \"0%lo\", (unsigned long)s.st_uid);\n    snprintf(buf + 116, 8, \"0%lo\", (unsigned long)s.st_gid);\n\n    // [ 124 :  12 ] file size in bytes\n    if (s.st_size > 077777777777LL) {\n        // very large files need a pax extended size header\n        needExtended = true;\n    }\n    snprintf(buf + 124, 12, \"%011llo\", (isdir) ? 0LL : s.st_size);\n\n    // [ 136 :  12 ] last mod time as a UTC time_t\n    snprintf(buf + 136, 12, \"%0lo\", s.st_mtime);\n\n    // [ 156 :   1 ] link/file type\n    uint8_t type;\n    if (isdir) {\n        type = '5';     // tar magic: '5' == directory\n    } else if (S_ISREG(s.st_mode)) {\n        type = '0';     // tar magic: '0' == normal file\n    } else {\n        ALOGW(\"Error: unknown file mode 0%o [%s]\", s.st_mode, filepath.string());\n        goto cleanup;\n    }\n    buf[156] = type;\n\n    // [ 157 : 100 ] name of linked file [not implemented]\n\n    {\n        // Prefix and main relative path.  Path lengths have been preflighted.\n        if (packageName.length() > 0) {\n            prefix = \"apps/\";\n            prefix += packageName;\n        }\n        if (domain.length() > 0) {\n            prefix.appendPath(domain);\n        }\n\n        // pax extended means we don't put in a prefix field, and put a different\n        // string in the basic name field.  We can also construct the full path name\n        // out of the substrings we've now built.\n        fullname = prefix;\n        fullname.appendPath(relpath);\n\n        // ustar:\n        //    [   0 : 100 ]; file name/path\n        //    [ 345 : 155 ] filename path prefix\n        // We only use the prefix area if fullname won't fit in the path\n        if (fullname.length() > 100) {\n            strncpy(buf, relpath.string(), 100);\n            strncpy(buf + 345, prefix.string(), 155);\n        } else {\n            strncpy(buf, fullname.string(), 100);\n        }\n    }\n\n    // [ 329 : 8 ] and [ 337 : 8 ] devmajor/devminor, not used\n\n    ALOGI(\"   Name: %s\", fullname.string());\n\n    // If we're using a pax extended header, build & write that here; lengths are\n    // already preflighted\n    if (needExtended) {\n        char sizeStr[32];   // big enough for a 64-bit unsigned value in decimal\n        char* p = paxData;\n\n        // construct the pax extended header data block\n        memset(paxData, 0, BUFSIZE - (paxData - buf));\n        int len;\n\n        // size header -- calc len in digits by actually rendering the number\n        // to a string - brute force but simple\n        snprintf(sizeStr, sizeof(sizeStr), \"%lld\", (long long)s.st_size);\n        p += write_pax_header_entry(p, \"size\", sizeStr);\n\n        // fullname was generated above with the ustar paths\n        p += write_pax_header_entry(p, \"path\", fullname.string());\n\n        // Now we know how big the pax data is\n        int paxLen = p - paxData;\n\n        // Now build the pax *header* templated on the ustar header\n        memcpy(paxHeader, buf, 512);\n\n        String8 leaf = fullname.getPathLeaf();\n        memset(paxHeader, 0, 100);                  // rewrite the name area\n        snprintf(paxHeader, 100, \"PaxHeader/%s\", leaf.string());\n        memset(paxHeader + 345, 0, 155);            // rewrite the prefix area\n        strncpy(paxHeader + 345, prefix.string(), 155);\n\n        paxHeader[156] = 'x';                       // mark it as a pax extended header\n\n        // [ 124 :  12 ] size of pax extended header data\n        memset(paxHeader + 124, 0, 12);\n        snprintf(paxHeader + 124, 12, \"%011o\", (unsigned int)(p - paxData));\n\n        // Checksum and write the pax block header\n        calc_tar_checksum(paxHeader);\n        send_tarfile_chunk(writer, paxHeader, 512);\n\n        // Now write the pax data itself\n        int paxblocks = (paxLen + 511) / 512;\n        send_tarfile_chunk(writer, paxData, 512 * paxblocks);\n    }\n\n    // Checksum and write the 512-byte ustar file header block to the output\n    calc_tar_checksum(buf);\n    send_tarfile_chunk(writer, buf, 512);\n\n    // Now write the file data itself, for real files.  We honor tar's convention that\n    // only full 512-byte blocks are sent to write().\n    if (!isdir) {\n        off64_t toWrite = s.st_size;\n        while (toWrite > 0) {\n            size_t toRead = toWrite;\n            if (toRead > BUFSIZE) {\n                toRead = BUFSIZE;\n            }\n            ssize_t nRead = read(fd, buf, toRead);\n            if (nRead < 0) {\n                err = errno;\n                ALOGE(\"Unable to read file [%s], err=%d (%s)\", filepath.string(),\n                        err, strerror(err));\n                break;\n            } else if (nRead == 0) {\n                ALOGE(\"EOF but expect %lld more bytes in [%s]\", (long long) toWrite,\n                        filepath.string());\n                err = EIO;\n                break;\n            }\n\n            // At EOF we might have a short block; NUL-pad that to a 512-byte multiple.  This\n            // depends on the OS guarantee that for ordinary files, read() will never return\n            // less than the number of bytes requested.\n            ssize_t partial = (nRead+512) % 512;\n            if (partial > 0) {\n                ssize_t remainder = 512 - partial;\n                memset(buf + nRead, 0, remainder);\n                nRead += remainder;\n            }\n            send_tarfile_chunk(writer, buf, nRead);\n            toWrite -= nRead;\n        }\n    }\n\ncleanup:\n    free(buf);\ndone:\n    close(fd);\n    return err;\n}\n// end tarfile\n\n\n\n#define RESTORE_BUF_SIZE (8*1024)\n\nRestoreHelperBase::RestoreHelperBase()\n{\n    m_buf = malloc(RESTORE_BUF_SIZE);\n    m_loggedUnknownMetadata = false;\n}\n\nRestoreHelperBase::~RestoreHelperBase()\n{\n    free(m_buf);\n}\n\nstatus_t\nRestoreHelperBase::WriteFile(const String8& filename, BackupDataReader* in)\n{\n    ssize_t err;\n    size_t dataSize;\n    String8 key;\n    int fd;\n    void* buf = m_buf;\n    ssize_t amt;\n    int mode;\n    int crc;\n    struct stat st;\n    FileRec r;\n\n    err = in->ReadEntityHeader(&key, &dataSize);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    // Get the metadata block off the head of the file entity and use that to\n    // set up the output file\n    file_metadata_v1 metadata;\n    amt = in->ReadEntityData(&metadata, sizeof(metadata));\n    if (amt != sizeof(metadata)) {\n        ALOGW(\"Could not read metadata for %s -- %ld / %s\", filename.string(),\n                (long)amt, strerror(errno));\n        return EIO;\n    }\n    metadata.version = fromlel(metadata.version);\n    metadata.mode = fromlel(metadata.mode);\n    if (metadata.version > CURRENT_METADATA_VERSION) {\n        if (!m_loggedUnknownMetadata) {\n            m_loggedUnknownMetadata = true;\n            ALOGW(\"Restoring file with unsupported metadata version %d (currently %d)\",\n                    metadata.version, CURRENT_METADATA_VERSION);\n        }\n    }\n    mode = metadata.mode;\n\n    // Write the file and compute the crc\n    crc = crc32(0L, Z_NULL, 0);\n    fd = open(filename.string(), O_CREAT|O_RDWR|O_TRUNC, mode);\n    if (fd == -1) {\n        ALOGW(\"Could not open file %s -- %s\", filename.string(), strerror(errno));\n        return errno;\n    }\n\n    while ((amt = in->ReadEntityData(buf, RESTORE_BUF_SIZE)) > 0) {\n        err = write(fd, buf, amt);\n        if (err != amt) {\n            close(fd);\n            ALOGW(\"Error '%s' writing '%s'\", strerror(errno), filename.string());\n            return errno;\n        }\n        crc = crc32(crc, (Bytef*)buf, amt);\n    }\n\n    close(fd);\n\n    // Record for the snapshot\n    err = stat(filename.string(), &st);\n    if (err != 0) {\n        ALOGW(\"Error stating file that we just created %s\", filename.string());\n        return errno;\n    }\n\n    r.file = filename;\n    r.deleted = false;\n    r.s.modTime_sec = st.st_mtime;\n    r.s.modTime_nsec = 0; // workaround sim breakage\n    //r.s.modTime_nsec = st.st_mtime_nsec;\n    r.s.mode = st.st_mode;\n    r.s.size = st.st_size;\n    r.s.crc32 = crc;\n\n    m_files.add(key, r);\n\n    return NO_ERROR;\n}\n\nstatus_t\nRestoreHelperBase::WriteSnapshot(int fd)\n{\n    return write_snapshot_file(fd, m_files);;\n}\n\n#if TEST_BACKUP_HELPERS\n\n#define SCRATCH_DIR \"/data/backup_helper_test/\"\n\nstatic int\nwrite_text_file(const char* path, const char* data)\n{\n    int amt;\n    int fd;\n    int len;\n\n    fd = creat(path, 0666);\n    if (fd == -1) {\n        fprintf(stderr, \"creat %s failed\\n\", path);\n        return errno;\n    }\n\n    len = strlen(data);\n    amt = write(fd, data, len);\n    if (amt != len) {\n        fprintf(stderr, \"error (%s) writing to file %s\\n\", strerror(errno), path);\n        return errno;\n    }\n\n    close(fd);\n\n    return 0;\n}\n\nstatic int\ncompare_file(const char* path, const unsigned char* data, int len)\n{\n    int fd;\n    int amt;\n\n    fd = open(path, O_RDONLY);\n    if (fd == -1) {\n        fprintf(stderr, \"compare_file error (%s) opening %s\\n\", strerror(errno), path);\n        return errno;\n    }\n\n    unsigned char* contents = (unsigned char*)malloc(len);\n    if (contents == NULL) {\n        fprintf(stderr, \"malloc(%d) failed\\n\", len);\n        return ENOMEM;\n    }\n\n    bool sizesMatch = true;\n    amt = lseek(fd, 0, SEEK_END);\n    if (amt != len) {\n        fprintf(stderr, \"compare_file file length should be %d, was %d\\n\", len, amt);\n        sizesMatch = false;\n    }\n    lseek(fd, 0, SEEK_SET);\n\n    int readLen = amt < len ? amt : len;\n    amt = read(fd, contents, readLen);\n    if (amt != readLen) {\n        fprintf(stderr, \"compare_file read expected %d bytes but got %d\\n\", len, amt);\n    }\n\n    bool contentsMatch = true;\n    for (int i=0; i<readLen; i++) {\n        if (data[i] != contents[i]) {\n            if (contentsMatch) {\n                fprintf(stderr, \"compare_file contents are different: (index, expected, actual)\\n\");\n                contentsMatch = false;\n            }\n            fprintf(stderr, \"  [%-2d] %02x %02x\\n\", i, data[i], contents[i]);\n        }\n    }\n\n    free(contents);\n    return contentsMatch && sizesMatch ? 0 : 1;\n}\n\nint\nbackup_helper_test_empty()\n{\n    int err;\n    int fd;\n    KeyedVector<String8,FileRec> snapshot;\n    const char* filename = SCRATCH_DIR \"backup_helper_test_empty.snap\";\n\n    system(\"rm -r \" SCRATCH_DIR);\n    mkdir(SCRATCH_DIR, 0777);\n\n    // write\n    fd = creat(filename, 0666);\n    if (fd == -1) {\n        fprintf(stderr, \"error creating %s\\n\", filename);\n        return 1;\n    }\n\n    err = write_snapshot_file(fd, snapshot);\n\n    close(fd);\n\n    if (err != 0) {\n        fprintf(stderr, \"write_snapshot_file reported error %d (%s)\\n\", err, strerror(err));\n        return err;\n    }\n\n    static const unsigned char correct_data[] = {\n        0x53, 0x6e, 0x61, 0x70,  0x00, 0x00, 0x00, 0x00,\n        0x46, 0x69, 0x6c, 0x65,  0x10, 0x00, 0x00, 0x00\n    };\n\n    err = compare_file(filename, correct_data, sizeof(correct_data));\n    if (err != 0) {\n        return err;\n    }\n\n    // read\n    fd = open(filename, O_RDONLY);\n    if (fd == -1) {\n        fprintf(stderr, \"error opening for read %s\\n\", filename);\n        return 1;\n    }\n\n    KeyedVector<String8,FileState> readSnapshot;\n    err = read_snapshot_file(fd, &readSnapshot);\n    if (err != 0) {\n        fprintf(stderr, \"read_snapshot_file failed %d\\n\", err);\n        return err;\n    }\n\n    if (readSnapshot.size() != 0) {\n        fprintf(stderr, \"readSnapshot should be length 0\\n\");\n        return 1;\n    }\n\n    return 0;\n}\n\nint\nbackup_helper_test_four()\n{\n    int err;\n    int fd;\n    KeyedVector<String8,FileRec> snapshot;\n    const char* filename = SCRATCH_DIR \"backup_helper_test_four.snap\";\n\n    system(\"rm -r \" SCRATCH_DIR);\n    mkdir(SCRATCH_DIR, 0777);\n\n    // write\n    fd = creat(filename, 0666);\n    if (fd == -1) {\n        fprintf(stderr, \"error opening %s\\n\", filename);\n        return 1;\n    }\n\n    String8 filenames[4];\n    FileState states[4];\n    FileRec r;\n    r.deleted = false;\n\n    states[0].modTime_sec = 0xfedcba98;\n    states[0].modTime_nsec = 0xdeadbeef;\n    states[0].mode = 0777; // decimal 511, hex 0x000001ff\n    states[0].size = 0xababbcbc;\n    states[0].crc32 = 0x12345678;\n    states[0].nameLen = -12;\n    r.s = states[0];\n    filenames[0] = String8(\"bytes_of_padding\");\n    snapshot.add(filenames[0], r);\n\n    states[1].modTime_sec = 0x93400031;\n    states[1].modTime_nsec = 0xdeadbeef;\n    states[1].mode = 0666; // decimal 438, hex 0x000001b6\n    states[1].size = 0x88557766;\n    states[1].crc32 = 0x22334422;\n    states[1].nameLen = -1;\n    r.s = states[1];\n    filenames[1] = String8(\"bytes_of_padding3\");\n    snapshot.add(filenames[1], r);\n\n    states[2].modTime_sec = 0x33221144;\n    states[2].modTime_nsec = 0xdeadbeef;\n    states[2].mode = 0744; // decimal 484, hex 0x000001e4\n    states[2].size = 0x11223344;\n    states[2].crc32 = 0x01122334;\n    states[2].nameLen = 0;\n    r.s = states[2];\n    filenames[2] = String8(\"bytes_of_padding_2\");\n    snapshot.add(filenames[2], r);\n\n    states[3].modTime_sec = 0x33221144;\n    states[3].modTime_nsec = 0xdeadbeef;\n    states[3].mode = 0755; // decimal 493, hex 0x000001ed\n    states[3].size = 0x11223344;\n    states[3].crc32 = 0x01122334;\n    states[3].nameLen = 0;\n    r.s = states[3];\n    filenames[3] = String8(\"bytes_of_padding__1\");\n    snapshot.add(filenames[3], r);\n\n    err = write_snapshot_file(fd, snapshot);\n\n    close(fd);\n\n    if (err != 0) {\n        fprintf(stderr, \"write_snapshot_file reported error %d (%s)\\n\", err, strerror(err));\n        return err;\n    }\n\n    static const unsigned char correct_data[] = {\n        // header\n        0x53, 0x6e, 0x61, 0x70,  0x04, 0x00, 0x00, 0x00,\n        0x46, 0x69, 0x6c, 0x65,  0xbc, 0x00, 0x00, 0x00,\n\n        // bytes_of_padding\n        0x98, 0xba, 0xdc, 0xfe,  0xef, 0xbe, 0xad, 0xde,\n        0xff, 0x01, 0x00, 0x00,  0xbc, 0xbc, 0xab, 0xab,\n        0x78, 0x56, 0x34, 0x12,  0x10, 0x00, 0x00, 0x00,\n        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,\n        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,\n\n        // bytes_of_padding3\n        0x31, 0x00, 0x40, 0x93,  0xef, 0xbe, 0xad, 0xde,\n        0xb6, 0x01, 0x00, 0x00,  0x66, 0x77, 0x55, 0x88,\n        0x22, 0x44, 0x33, 0x22,  0x11, 0x00, 0x00, 0x00,\n        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,\n        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,\n        0x33, 0xab, 0xab, 0xab,\n\n        // bytes of padding2\n        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,\n        0xe4, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,\n        0x34, 0x23, 0x12, 0x01,  0x12, 0x00, 0x00, 0x00,\n        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,\n        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,\n        0x5f, 0x32, 0xab, 0xab,\n\n        // bytes of padding3\n        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,\n        0xed, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,\n        0x34, 0x23, 0x12, 0x01,  0x13, 0x00, 0x00, 0x00,\n        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,\n        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,\n        0x5f, 0x5f, 0x31, 0xab\n    };\n\n    err = compare_file(filename, correct_data, sizeof(correct_data));\n    if (err != 0) {\n        return err;\n    }\n\n    // read\n    fd = open(filename, O_RDONLY);\n    if (fd == -1) {\n        fprintf(stderr, \"error opening for read %s\\n\", filename);\n        return 1;\n    }\n\n\n    KeyedVector<String8,FileState> readSnapshot;\n    err = read_snapshot_file(fd, &readSnapshot);\n    if (err != 0) {\n        fprintf(stderr, \"read_snapshot_file failed %d\\n\", err);\n        return err;\n    }\n\n    if (readSnapshot.size() != 4) {\n        fprintf(stderr, \"readSnapshot should be length 4 is %zu\\n\", readSnapshot.size());\n        return 1;\n    }\n\n    bool matched = true;\n    for (size_t i=0; i<readSnapshot.size(); i++) {\n        const String8& name = readSnapshot.keyAt(i);\n        const FileState state = readSnapshot.valueAt(i);\n\n        if (name != filenames[i] || states[i].modTime_sec != state.modTime_sec\n                || states[i].modTime_nsec != state.modTime_nsec || states[i].mode != state.mode\n                || states[i].size != state.size || states[i].crc32 != states[i].crc32) {\n            fprintf(stderr, \"state %zu expected={%d/%d, %04o, 0x%08x, 0x%08x, %3zu} '%s'\\n\"\n                            \"          actual={%d/%d, %04o, 0x%08x, 0x%08x, %3d} '%s'\\n\", i,\n                    states[i].modTime_sec, states[i].modTime_nsec, states[i].mode, states[i].size,\n                    states[i].crc32, name.length(), filenames[i].string(),\n                    state.modTime_sec, state.modTime_nsec, state.mode, state.size, state.crc32,\n                    state.nameLen, name.string());\n            matched = false;\n        }\n    }\n\n    return matched ? 0 : 1;\n}\n\n// hexdump -v -e '\"    \" 8/1 \" 0x%02x,\" \"\\n\"' data_writer.data\nconst unsigned char DATA_GOLDEN_FILE[] = {\n     0x44, 0x61, 0x74, 0x61, 0x0b, 0x00, 0x00, 0x00,\n     0x0c, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x5f, 0x70,\n     0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,\n     0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,\n     0x6e, 0x67, 0x5f, 0x00, 0x44, 0x61, 0x74, 0x61,\n     0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,\n     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,\n     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,\n     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,\n     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,\n     0x44, 0x61, 0x74, 0x61, 0x0d, 0x00, 0x00, 0x00,\n     0x0e, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,\n     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,\n     0x5f, 0x00, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,\n     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,\n     0x5f, 0x00, 0xbc, 0xbc, 0x44, 0x61, 0x74, 0x61,\n     0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,\n     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,\n     0x6f, 0x31, 0x00, 0xbc, 0x70, 0x61, 0x64, 0x64,\n     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00\n\n};\nconst int DATA_GOLDEN_FILE_SIZE = sizeof(DATA_GOLDEN_FILE);\n\nstatic int\ntest_write_header_and_entity(BackupDataWriter& writer, const char* str)\n{\n    int err;\n    String8 text(str);\n\n    err = writer.WriteEntityHeader(text, text.length()+1);\n    if (err != 0) {\n        fprintf(stderr, \"WriteEntityHeader failed with %s\\n\", strerror(err));\n        return err;\n    }\n\n    err = writer.WriteEntityData(text.string(), text.length()+1);\n    if (err != 0) {\n        fprintf(stderr, \"write failed for data '%s'\\n\", text.string());\n        return errno;\n    }\n\n    return err;\n}\n\nint\nbackup_helper_test_data_writer()\n{\n    int err;\n    int fd;\n    const char* filename = SCRATCH_DIR \"data_writer.data\";\n\n    system(\"rm -r \" SCRATCH_DIR);\n    mkdir(SCRATCH_DIR, 0777);\n    mkdir(SCRATCH_DIR \"data\", 0777);\n\n    fd = creat(filename, 0666);\n    if (fd == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    BackupDataWriter writer(fd);\n\n    err = 0;\n    err |= test_write_header_and_entity(writer, \"no_padding_\");\n    err |= test_write_header_and_entity(writer, \"padded_to__3\");\n    err |= test_write_header_and_entity(writer, \"padded_to_2__\");\n    err |= test_write_header_and_entity(writer, \"padded_to1\");\n\n    close(fd);\n\n    err = compare_file(filename, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);\n    if (err != 0) {\n        return err;\n    }\n\n    return err;\n}\n\nint\ntest_read_header_and_entity(BackupDataReader& reader, const char* str)\n{\n    int err;\n    size_t bufSize = strlen(str)+1;\n    char* buf = (char*)malloc(bufSize);\n    String8 string;\n    int cookie = 0x11111111;\n    size_t actualSize;\n    bool done;\n    int type;\n    ssize_t nRead;\n\n    // printf(\"\\n\\n---------- test_read_header_and_entity -- %s\\n\\n\", str);\n\n    err = reader.ReadNextHeader(&done, &type);\n    if (done) {\n        fprintf(stderr, \"should not be done yet\\n\");\n        goto finished;\n    }\n    if (err != 0) {\n        fprintf(stderr, \"ReadNextHeader (for app header) failed with %s\\n\", strerror(err));\n        goto finished;\n    }\n    if (type != BACKUP_HEADER_ENTITY_V1) {\n        err = EINVAL;\n        fprintf(stderr, \"type=0x%08x expected 0x%08x\\n\", type, BACKUP_HEADER_ENTITY_V1);\n    }\n\n    err = reader.ReadEntityHeader(&string, &actualSize);\n    if (err != 0) {\n        fprintf(stderr, \"ReadEntityHeader failed with %s\\n\", strerror(err));\n        goto finished;\n    }\n    if (string != str) {\n        fprintf(stderr, \"ReadEntityHeader expected key '%s' got '%s'\\n\", str, string.string());\n        err = EINVAL;\n        goto finished;\n    }\n    if (actualSize != bufSize) {\n        fprintf(stderr, \"ReadEntityHeader expected dataSize %zu got %zu\\n\",\n                bufSize, actualSize);\n        err = EINVAL;\n        goto finished;\n    }\n\n    nRead = reader.ReadEntityData(buf, bufSize);\n    if (nRead < 0) {\n        err = reader.Status();\n        fprintf(stderr, \"ReadEntityData failed with %s\\n\", strerror(err));\n        goto finished;\n    }\n\n    if (0 != memcmp(buf, str, bufSize)) {\n        fprintf(stderr, \"ReadEntityData expected '%s' but got something starting with \"\n                \"%02x %02x %02x %02x  '%c%c%c%c'\\n\", str, buf[0], buf[1], buf[2], buf[3],\n                buf[0], buf[1], buf[2], buf[3]);\n        err = EINVAL;\n        goto finished;\n    }\n\n    // The next read will confirm whether it got the right amount of data.\n\nfinished:\n    if (err != NO_ERROR) {\n        fprintf(stderr, \"test_read_header_and_entity failed with %s\\n\", strerror(err));\n    }\n    free(buf);\n    return err;\n}\n\nint\nbackup_helper_test_data_reader()\n{\n    int err;\n    int fd;\n    const char* filename = SCRATCH_DIR \"data_reader.data\";\n\n    system(\"rm -r \" SCRATCH_DIR);\n    mkdir(SCRATCH_DIR, 0777);\n    mkdir(SCRATCH_DIR \"data\", 0777);\n\n    fd = creat(filename, 0666);\n    if (fd == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    err = write(fd, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);\n    if (err != DATA_GOLDEN_FILE_SIZE) {\n        fprintf(stderr, \"Error \\\"%s\\\" writing golden file %s\\n\", strerror(errno), filename);\n        return errno;\n    }\n\n    close(fd);\n\n    fd = open(filename, O_RDONLY);\n    if (fd == -1) {\n        fprintf(stderr, \"Error \\\"%s\\\" opening golden file %s for read\\n\", strerror(errno),\n                filename);\n        return errno;\n    }\n\n    {\n        BackupDataReader reader(fd);\n\n        err = 0;\n\n        if (err == NO_ERROR) {\n            err = test_read_header_and_entity(reader, \"no_padding_\");\n        }\n\n        if (err == NO_ERROR) {\n            err = test_read_header_and_entity(reader, \"padded_to__3\");\n        }\n\n        if (err == NO_ERROR) {\n            err = test_read_header_and_entity(reader, \"padded_to_2__\");\n        }\n\n        if (err == NO_ERROR) {\n            err = test_read_header_and_entity(reader, \"padded_to1\");\n        }\n    }\n\n    close(fd);\n\n    return err;\n}\n\nstatic int\nget_mod_time(const char* filename, struct timeval times[2])\n{\n    int err;\n    struct stat64 st;\n    err = stat64(filename, &st);\n    if (err != 0) {\n        fprintf(stderr, \"stat '%s' failed: %s\\n\", filename, strerror(errno));\n        return errno;\n    }\n    times[0].tv_sec = st.st_atime;\n    times[1].tv_sec = st.st_mtime;\n\n    // If st_atime is a macro then struct stat64 uses struct timespec\n    // to store the access and modif time values and typically\n    // st_*time_nsec is not defined. In glibc, this is controlled by\n    // __USE_MISC.\n#ifdef __USE_MISC\n#if !defined(st_atime) || defined(st_atime_nsec)\n#error \"Check if this __USE_MISC conditional is still needed.\"\n#endif\n    times[0].tv_usec = st.st_atim.tv_nsec / 1000;\n    times[1].tv_usec = st.st_mtim.tv_nsec / 1000;\n#else\n    times[0].tv_usec = st.st_atime_nsec / 1000;\n    times[1].tv_usec = st.st_mtime_nsec / 1000;\n#endif\n\n    return 0;\n}\n\nint\nbackup_helper_test_files()\n{\n    int err;\n    int oldSnapshotFD;\n    int dataStreamFD;\n    int newSnapshotFD;\n\n    system(\"rm -r \" SCRATCH_DIR);\n    mkdir(SCRATCH_DIR, 0777);\n    mkdir(SCRATCH_DIR \"data\", 0777);\n\n    write_text_file(SCRATCH_DIR \"data/b\", \"b\\nbb\\n\");\n    write_text_file(SCRATCH_DIR \"data/c\", \"c\\ncc\\n\");\n    write_text_file(SCRATCH_DIR \"data/d\", \"d\\ndd\\n\");\n    write_text_file(SCRATCH_DIR \"data/e\", \"e\\nee\\n\");\n    write_text_file(SCRATCH_DIR \"data/f\", \"f\\nff\\n\");\n    write_text_file(SCRATCH_DIR \"data/h\", \"h\\nhh\\n\");\n\n    char const* files_before[] = {\n        SCRATCH_DIR \"data/b\",\n        SCRATCH_DIR \"data/c\",\n        SCRATCH_DIR \"data/d\",\n        SCRATCH_DIR \"data/e\",\n        SCRATCH_DIR \"data/f\"\n    };\n\n    char const* keys_before[] = {\n        \"data/b\",\n        \"data/c\",\n        \"data/d\",\n        \"data/e\",\n        \"data/f\"\n    };\n\n    dataStreamFD = creat(SCRATCH_DIR \"1.data\", 0666);\n    if (dataStreamFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    newSnapshotFD = creat(SCRATCH_DIR \"before.snap\", 0666);\n    if (newSnapshotFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    {\n        BackupDataWriter dataStream(dataStreamFD);\n\n        err = back_up_files(-1, &dataStream, newSnapshotFD, files_before, keys_before, 5);\n        if (err != 0) {\n            return err;\n        }\n    }\n\n    close(dataStreamFD);\n    close(newSnapshotFD);\n\n    sleep(3);\n\n    struct timeval d_times[2];\n    struct timeval e_times[2];\n\n    err = get_mod_time(SCRATCH_DIR \"data/d\", d_times);\n    err |= get_mod_time(SCRATCH_DIR \"data/e\", e_times);\n    if (err != 0) {\n        return err;\n    }\n\n    write_text_file(SCRATCH_DIR \"data/a\", \"a\\naa\\n\");\n    unlink(SCRATCH_DIR \"data/c\");\n    write_text_file(SCRATCH_DIR \"data/c\", \"c\\ncc\\n\");\n    write_text_file(SCRATCH_DIR \"data/d\", \"dd\\ndd\\n\");\n    utimes(SCRATCH_DIR \"data/d\", d_times);\n    write_text_file(SCRATCH_DIR \"data/e\", \"z\\nzz\\n\");\n    utimes(SCRATCH_DIR \"data/e\", e_times);\n    write_text_file(SCRATCH_DIR \"data/g\", \"g\\ngg\\n\");\n    unlink(SCRATCH_DIR \"data/f\");\n\n    char const* files_after[] = {\n        SCRATCH_DIR \"data/a\", // added\n        SCRATCH_DIR \"data/b\", // same\n        SCRATCH_DIR \"data/c\", // different mod time\n        SCRATCH_DIR \"data/d\", // different size (same mod time)\n        SCRATCH_DIR \"data/e\", // different contents (same mod time, same size)\n        SCRATCH_DIR \"data/g\"  // added\n    };\n\n    char const* keys_after[] = {\n        \"data/a\", // added\n        \"data/b\", // same\n        \"data/c\", // different mod time\n        \"data/d\", // different size (same mod time)\n        \"data/e\", // different contents (same mod time, same size)\n        \"data/g\"  // added\n    };\n\n    oldSnapshotFD = open(SCRATCH_DIR \"before.snap\", O_RDONLY);\n    if (oldSnapshotFD == -1) {\n        fprintf(stderr, \"error opening: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    dataStreamFD = creat(SCRATCH_DIR \"2.data\", 0666);\n    if (dataStreamFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    newSnapshotFD = creat(SCRATCH_DIR \"after.snap\", 0666);\n    if (newSnapshotFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    {\n        BackupDataWriter dataStream(dataStreamFD);\n\n        err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, files_after, keys_after, 6);\n        if (err != 0) {\n            return err;\n        }\n}\n\n    close(oldSnapshotFD);\n    close(dataStreamFD);\n    close(newSnapshotFD);\n\n    return 0;\n}\n\nint\nbackup_helper_test_null_base()\n{\n    int err;\n    int oldSnapshotFD;\n    int dataStreamFD;\n    int newSnapshotFD;\n\n    system(\"rm -r \" SCRATCH_DIR);\n    mkdir(SCRATCH_DIR, 0777);\n    mkdir(SCRATCH_DIR \"data\", 0777);\n\n    write_text_file(SCRATCH_DIR \"data/a\", \"a\\naa\\n\");\n\n    char const* files[] = {\n        SCRATCH_DIR \"data/a\",\n    };\n\n    char const* keys[] = {\n        \"a\",\n    };\n\n    dataStreamFD = creat(SCRATCH_DIR \"null_base.data\", 0666);\n    if (dataStreamFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    newSnapshotFD = creat(SCRATCH_DIR \"null_base.snap\", 0666);\n    if (newSnapshotFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    {\n        BackupDataWriter dataStream(dataStreamFD);\n\n        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);\n        if (err != 0) {\n            return err;\n        }\n    }\n\n    close(dataStreamFD);\n    close(newSnapshotFD);\n\n    return 0;\n}\n\nint\nbackup_helper_test_missing_file()\n{\n    int err;\n    int oldSnapshotFD;\n    int dataStreamFD;\n    int newSnapshotFD;\n\n    system(\"rm -r \" SCRATCH_DIR);\n    mkdir(SCRATCH_DIR, 0777);\n    mkdir(SCRATCH_DIR \"data\", 0777);\n\n    write_text_file(SCRATCH_DIR \"data/b\", \"b\\nbb\\n\");\n\n    char const* files[] = {\n        SCRATCH_DIR \"data/a\",\n        SCRATCH_DIR \"data/b\",\n        SCRATCH_DIR \"data/c\",\n    };\n\n    char const* keys[] = {\n        \"a\",\n        \"b\",\n        \"c\",\n    };\n\n    dataStreamFD = creat(SCRATCH_DIR \"null_base.data\", 0666);\n    if (dataStreamFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    newSnapshotFD = creat(SCRATCH_DIR \"null_base.snap\", 0666);\n    if (newSnapshotFD == -1) {\n        fprintf(stderr, \"error creating: %s\\n\", strerror(errno));\n        return errno;\n    }\n\n    {\n        BackupDataWriter dataStream(dataStreamFD);\n\n        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);\n        if (err != 0) {\n            return err;\n        }\n    }\n\n    close(dataStreamFD);\n    close(newSnapshotFD);\n\n    return 0;\n}\n\n\n#endif // TEST_BACKUP_HELPERS\n\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/CursorWindow.cpp",
    "content": "/*\n * Copyright (C) 2006-2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#undef LOG_TAG\n#define LOG_TAG \"CursorWindow\"\n\n#include <androidfw/CursorWindow.h>\n#include <binder/Parcel.h>\n#include <utils/Log.h>\n\n#include <cutils/ashmem.h>\n#include <sys/mman.h>\n\n#include <assert.h>\n#include <string.h>\n#include <stdlib.h>\n\nnamespace android {\n\nCursorWindow::CursorWindow(const String8& name, int ashmemFd,\n        void* data, size_t size, bool readOnly) :\n        mName(name), mAshmemFd(ashmemFd), mData(data), mSize(size), mReadOnly(readOnly) {\n    mHeader = static_cast<Header*>(mData);\n}\n\nCursorWindow::~CursorWindow() {\n    ::munmap(mData, mSize);\n    ::close(mAshmemFd);\n}\n\nstatus_t CursorWindow::create(const String8& name, size_t size, CursorWindow** outCursorWindow) {\n    String8 ashmemName(\"CursorWindow: \");\n    ashmemName.append(name);\n\n    status_t result;\n    int ashmemFd = ashmem_create_region(ashmemName.string(), size);\n    if (ashmemFd < 0) {\n        result = -errno;\n    } else {\n        result = ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);\n        if (result >= 0) {\n            void* data = ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);\n            if (data == MAP_FAILED) {\n                result = -errno;\n            } else {\n                result = ashmem_set_prot_region(ashmemFd, PROT_READ);\n                if (result >= 0) {\n                    CursorWindow* window = new CursorWindow(name, ashmemFd,\n                            data, size, false /*readOnly*/);\n                    result = window->clear();\n                    if (!result) {\n                        LOG_WINDOW(\"Created new CursorWindow: freeOffset=%d, \"\n                                \"numRows=%d, numColumns=%d, mSize=%d, mData=%p\",\n                                window->mHeader->freeOffset,\n                                window->mHeader->numRows,\n                                window->mHeader->numColumns,\n                                window->mSize, window->mData);\n                        *outCursorWindow = window;\n                        return OK;\n                    }\n                    delete window;\n                }\n            }\n            ::munmap(data, size);\n        }\n        ::close(ashmemFd);\n    }\n    *outCursorWindow = NULL;\n    return result;\n}\n\nstatus_t CursorWindow::createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow) {\n    String8 name = parcel->readString8();\n\n    status_t result;\n    int ashmemFd = parcel->readFileDescriptor();\n    if (ashmemFd == int(BAD_TYPE)) {\n        result = BAD_TYPE;\n    } else {\n        ssize_t size = ashmem_get_size_region(ashmemFd);\n        if (size < 0) {\n            result = UNKNOWN_ERROR;\n        } else {\n            int dupAshmemFd = ::dup(ashmemFd);\n            if (dupAshmemFd < 0) {\n                result = -errno;\n            } else {\n                void* data = ::mmap(NULL, size, PROT_READ, MAP_SHARED, dupAshmemFd, 0);\n                if (data == MAP_FAILED) {\n                    result = -errno;\n                } else {\n                    CursorWindow* window = new CursorWindow(name, dupAshmemFd,\n                            data, size, true /*readOnly*/);\n                    LOG_WINDOW(\"Created CursorWindow from parcel: freeOffset=%d, \"\n                            \"numRows=%d, numColumns=%d, mSize=%d, mData=%p\",\n                            window->mHeader->freeOffset,\n                            window->mHeader->numRows,\n                            window->mHeader->numColumns,\n                            window->mSize, window->mData);\n                    *outCursorWindow = window;\n                    return OK;\n                }\n                ::close(dupAshmemFd);\n            }\n        }\n    }\n    *outCursorWindow = NULL;\n    return result;\n}\n\nstatus_t CursorWindow::writeToParcel(Parcel* parcel) {\n    status_t status = parcel->writeString8(mName);\n    if (!status) {\n        status = parcel->writeDupFileDescriptor(mAshmemFd);\n    }\n    return status;\n}\n\nstatus_t CursorWindow::clear() {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    mHeader->freeOffset = sizeof(Header) + sizeof(RowSlotChunk);\n    mHeader->firstChunkOffset = sizeof(Header);\n    mHeader->numRows = 0;\n    mHeader->numColumns = 0;\n\n    RowSlotChunk* firstChunk = static_cast<RowSlotChunk*>(offsetToPtr(mHeader->firstChunkOffset));\n    firstChunk->nextChunkOffset = 0;\n    return OK;\n}\n\nstatus_t CursorWindow::setNumColumns(uint32_t numColumns) {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    uint32_t cur = mHeader->numColumns;\n    if ((cur > 0 || mHeader->numRows > 0) && cur != numColumns) {\n        ALOGE(\"Trying to go from %d columns to %d\", cur, numColumns);\n        return INVALID_OPERATION;\n    }\n    mHeader->numColumns = numColumns;\n    return OK;\n}\n\nstatus_t CursorWindow::allocRow() {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    // Fill in the row slot\n    RowSlot* rowSlot = allocRowSlot();\n    if (rowSlot == NULL) {\n        return NO_MEMORY;\n    }\n\n    // Allocate the slots for the field directory\n    size_t fieldDirSize = mHeader->numColumns * sizeof(FieldSlot);\n    uint32_t fieldDirOffset = alloc(fieldDirSize, true /*aligned*/);\n    if (!fieldDirOffset) {\n        mHeader->numRows--;\n        LOG_WINDOW(\"The row failed, so back out the new row accounting \"\n                \"from allocRowSlot %d\", mHeader->numRows);\n        return NO_MEMORY;\n    }\n    FieldSlot* fieldDir = static_cast<FieldSlot*>(offsetToPtr(fieldDirOffset));\n    memset(fieldDir, 0, fieldDirSize);\n\n    LOG_WINDOW(\"Allocated row %u, rowSlot is at offset %u, fieldDir is %d bytes at offset %u\\n\",\n            mHeader->numRows - 1, offsetFromPtr(rowSlot), fieldDirSize, fieldDirOffset);\n    rowSlot->offset = fieldDirOffset;\n    return OK;\n}\n\nstatus_t CursorWindow::freeLastRow() {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    if (mHeader->numRows > 0) {\n        mHeader->numRows--;\n    }\n    return OK;\n}\n\nuint32_t CursorWindow::alloc(size_t size, bool aligned) {\n    uint32_t padding;\n    if (aligned) {\n        // 4 byte alignment\n        padding = (~mHeader->freeOffset + 1) & 3;\n    } else {\n        padding = 0;\n    }\n\n    uint32_t offset = mHeader->freeOffset + padding;\n    uint32_t nextFreeOffset = offset + size;\n    if (nextFreeOffset > mSize) {\n        ALOGW(\"Window is full: requested allocation %zu bytes, \"\n                \"free space %zu bytes, window size %zu bytes\",\n                size, freeSpace(), mSize);\n        return 0;\n    }\n\n    mHeader->freeOffset = nextFreeOffset;\n    return offset;\n}\n\nCursorWindow::RowSlot* CursorWindow::getRowSlot(uint32_t row) {\n    uint32_t chunkPos = row;\n    RowSlotChunk* chunk = static_cast<RowSlotChunk*>(\n            offsetToPtr(mHeader->firstChunkOffset));\n    while (chunkPos >= ROW_SLOT_CHUNK_NUM_ROWS) {\n        chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));\n        chunkPos -= ROW_SLOT_CHUNK_NUM_ROWS;\n    }\n    return &chunk->slots[chunkPos];\n}\n\nCursorWindow::RowSlot* CursorWindow::allocRowSlot() {\n    uint32_t chunkPos = mHeader->numRows;\n    RowSlotChunk* chunk = static_cast<RowSlotChunk*>(\n            offsetToPtr(mHeader->firstChunkOffset));\n    while (chunkPos > ROW_SLOT_CHUNK_NUM_ROWS) {\n        chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));\n        chunkPos -= ROW_SLOT_CHUNK_NUM_ROWS;\n    }\n    if (chunkPos == ROW_SLOT_CHUNK_NUM_ROWS) {\n        if (!chunk->nextChunkOffset) {\n            chunk->nextChunkOffset = alloc(sizeof(RowSlotChunk), true /*aligned*/);\n            if (!chunk->nextChunkOffset) {\n                return NULL;\n            }\n        }\n        chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));\n        chunk->nextChunkOffset = 0;\n        chunkPos = 0;\n    }\n    mHeader->numRows += 1;\n    return &chunk->slots[chunkPos];\n}\n\nCursorWindow::FieldSlot* CursorWindow::getFieldSlot(uint32_t row, uint32_t column) {\n    if (row >= mHeader->numRows || column >= mHeader->numColumns) {\n        ALOGE(\"Failed to read row %d, column %d from a CursorWindow which \"\n                \"has %d rows, %d columns.\",\n                row, column, mHeader->numRows, mHeader->numColumns);\n        return NULL;\n    }\n    RowSlot* rowSlot = getRowSlot(row);\n    if (!rowSlot) {\n        ALOGE(\"Failed to find rowSlot for row %d.\", row);\n        return NULL;\n    }\n    FieldSlot* fieldDir = static_cast<FieldSlot*>(offsetToPtr(rowSlot->offset));\n    return &fieldDir[column];\n}\n\nstatus_t CursorWindow::putBlob(uint32_t row, uint32_t column, const void* value, size_t size) {\n    return putBlobOrString(row, column, value, size, FIELD_TYPE_BLOB);\n}\n\nstatus_t CursorWindow::putString(uint32_t row, uint32_t column, const char* value,\n        size_t sizeIncludingNull) {\n    return putBlobOrString(row, column, value, sizeIncludingNull, FIELD_TYPE_STRING);\n}\n\nstatus_t CursorWindow::putBlobOrString(uint32_t row, uint32_t column,\n        const void* value, size_t size, int32_t type) {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    FieldSlot* fieldSlot = getFieldSlot(row, column);\n    if (!fieldSlot) {\n        return BAD_VALUE;\n    }\n\n    uint32_t offset = alloc(size);\n    if (!offset) {\n        return NO_MEMORY;\n    }\n\n    memcpy(offsetToPtr(offset), value, size);\n\n    fieldSlot->type = type;\n    fieldSlot->data.buffer.offset = offset;\n    fieldSlot->data.buffer.size = size;\n    return OK;\n}\n\nstatus_t CursorWindow::putLong(uint32_t row, uint32_t column, int64_t value) {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    FieldSlot* fieldSlot = getFieldSlot(row, column);\n    if (!fieldSlot) {\n        return BAD_VALUE;\n    }\n\n    fieldSlot->type = FIELD_TYPE_INTEGER;\n    fieldSlot->data.l = value;\n    return OK;\n}\n\nstatus_t CursorWindow::putDouble(uint32_t row, uint32_t column, double value) {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    FieldSlot* fieldSlot = getFieldSlot(row, column);\n    if (!fieldSlot) {\n        return BAD_VALUE;\n    }\n\n    fieldSlot->type = FIELD_TYPE_FLOAT;\n    fieldSlot->data.d = value;\n    return OK;\n}\n\nstatus_t CursorWindow::putNull(uint32_t row, uint32_t column) {\n    if (mReadOnly) {\n        return INVALID_OPERATION;\n    }\n\n    FieldSlot* fieldSlot = getFieldSlot(row, column);\n    if (!fieldSlot) {\n        return BAD_VALUE;\n    }\n\n    fieldSlot->type = FIELD_TYPE_NULL;\n    fieldSlot->data.buffer.offset = 0;\n    fieldSlot->data.buffer.size = 0;\n    return OK;\n}\n\n}; // namespace android\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/MODULE_LICENSE_APACHE2",
    "content": ""
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/NOTICE",
    "content": "\n   Copyright (c) 2005-2008, The Android Open Source Project\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/ObbFile.cpp",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <errno.h>\n#include <fcntl.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#define LOG_TAG \"ObbFile\"\n\n#include <androidfw/ObbFile.h>\n#include <utils/Compat.h>\n#include <utils/Log.h>\n\n//#define DEBUG 1\n\n#define kFooterTagSize 8  /* last two 32-bit integers */\n\n#define kFooterMinSize 33 /* 32-bit signature version (4 bytes)\n                           * 32-bit package version (4 bytes)\n                           * 32-bit flags (4 bytes)\n                           * 64-bit salt (8 bytes)\n                           * 32-bit package name size (4 bytes)\n                           * >=1-character package name (1 byte)\n                           * 32-bit footer size (4 bytes)\n                           * 32-bit footer marker (4 bytes)\n                           */\n\n#define kMaxBufSize    32768 /* Maximum file read buffer */\n\n#define kSignature     0x01059983U /* ObbFile signature */\n\n#define kSigVersion    1 /* We only know about signature version 1 */\n\n/* offsets in version 1 of the header */\n#define kPackageVersionOffset 4\n#define kFlagsOffset          8\n#define kSaltOffset           12\n#define kPackageNameLenOffset 20\n#define kPackageNameOffset    24\n\n/*\n * TEMP_FAILURE_RETRY is defined by some, but not all, versions of\n * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's\n * not already defined, then define it here.\n */\n#ifndef TEMP_FAILURE_RETRY\n/* Used to retry syscalls that can return EINTR. */\n#define TEMP_FAILURE_RETRY(exp) ({         \\\n    typeof (exp) _rc;                      \\\n    do {                                   \\\n        _rc = (exp);                       \\\n    } while (_rc == -1 && errno == EINTR); \\\n    _rc; })\n#endif\n\n\nnamespace android {\n\nObbFile::ObbFile()\n        : mPackageName(\"\")\n        , mVersion(-1)\n        , mFlags(0)\n{\n    memset(mSalt, 0, sizeof(mSalt));\n}\n\nObbFile::~ObbFile() {\n}\n\nbool ObbFile::readFrom(const char* filename)\n{\n    int fd;\n    bool success = false;\n\n    fd = ::open(filename, O_RDONLY);\n    if (fd < 0) {\n        ALOGW(\"couldn't open file %s: %s\", filename, strerror(errno));\n        goto out;\n    }\n    success = readFrom(fd);\n    close(fd);\n\n    if (!success) {\n        ALOGW(\"failed to read from %s (fd=%d)\\n\", filename, fd);\n    }\n\nout:\n    return success;\n}\n\nbool ObbFile::readFrom(int fd)\n{\n    if (fd < 0) {\n        ALOGW(\"attempt to read from invalid fd\\n\");\n        return false;\n    }\n\n    return parseObbFile(fd);\n}\n\nbool ObbFile::parseObbFile(int fd)\n{\n    off64_t fileLength = lseek64(fd, 0, SEEK_END);\n\n    if (fileLength < kFooterMinSize) {\n        if (fileLength < 0) {\n            ALOGW(\"error seeking in ObbFile: %s\\n\", strerror(errno));\n        } else {\n            ALOGW(\"file is only %lld (less than %d minimum)\\n\", fileLength, kFooterMinSize);\n        }\n        return false;\n    }\n\n    ssize_t actual;\n    size_t footerSize;\n\n    {\n        lseek64(fd, fileLength - kFooterTagSize, SEEK_SET);\n\n        char footer[kFooterTagSize];\n        actual = TEMP_FAILURE_RETRY(read(fd, footer, kFooterTagSize));\n        if (actual != kFooterTagSize) {\n            ALOGW(\"couldn't read footer signature: %s\\n\", strerror(errno));\n            return false;\n        }\n\n        unsigned int fileSig = get4LE((unsigned char*)footer + sizeof(int32_t));\n        if (fileSig != kSignature) {\n            ALOGW(\"footer didn't match magic string (expected 0x%08x; got 0x%08x)\\n\",\n                    kSignature, fileSig);\n            return false;\n        }\n\n        footerSize = get4LE((unsigned char*)footer);\n        if (footerSize > (size_t)fileLength - kFooterTagSize\n                || footerSize > kMaxBufSize) {\n            ALOGW(\"claimed footer size is too large (0x%08zx; file size is 0x%08llx)\\n\",\n                    footerSize, fileLength);\n            return false;\n        }\n\n        if (footerSize < (kFooterMinSize - kFooterTagSize)) {\n            ALOGW(\"claimed footer size is too small (0x%zx; minimum size is 0x%x)\\n\",\n                    footerSize, kFooterMinSize - kFooterTagSize);\n            return false;\n        }\n    }\n\n    off64_t fileOffset = fileLength - footerSize - kFooterTagSize;\n    if (lseek64(fd, fileOffset, SEEK_SET) != fileOffset) {\n        ALOGW(\"seek %lld failed: %s\\n\", fileOffset, strerror(errno));\n        return false;\n    }\n\n    mFooterStart = fileOffset;\n\n    char* scanBuf = (char*)malloc(footerSize);\n    if (scanBuf == NULL) {\n        ALOGW(\"couldn't allocate scanBuf: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    actual = TEMP_FAILURE_RETRY(read(fd, scanBuf, footerSize));\n    // readAmount is guaranteed to be less than kMaxBufSize\n    if (actual != (ssize_t)footerSize) {\n        ALOGI(\"couldn't read ObbFile footer: %s\\n\", strerror(errno));\n        free(scanBuf);\n        return false;\n    }\n\n#ifdef DEBUG\n    for (int i = 0; i < footerSize; ++i) {\n        ALOGI(\"char: 0x%02x\\n\", scanBuf[i]);\n    }\n#endif\n\n    uint32_t sigVersion = get4LE((unsigned char*)scanBuf);\n    if (sigVersion != kSigVersion) {\n        ALOGW(\"Unsupported ObbFile version %d\\n\", sigVersion);\n        free(scanBuf);\n        return false;\n    }\n\n    mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset);\n    mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset);\n\n    memcpy(&mSalt, (unsigned char*)scanBuf + kSaltOffset, sizeof(mSalt));\n\n    size_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);\n    if (packageNameLen == 0\n            || packageNameLen > (footerSize - kPackageNameOffset)) {\n        ALOGW(\"bad ObbFile package name length (0x%04zx; 0x%04zx possible)\\n\",\n                packageNameLen, footerSize - kPackageNameOffset);\n        free(scanBuf);\n        return false;\n    }\n\n    char* packageName = reinterpret_cast<char*>(scanBuf + kPackageNameOffset);\n    mPackageName = String8(const_cast<char*>(packageName), packageNameLen);\n\n    free(scanBuf);\n\n#ifdef DEBUG\n    ALOGI(\"Obb scan succeeded: packageName=%s, version=%d\\n\", mPackageName.string(), mVersion);\n#endif\n\n    return true;\n}\n\nbool ObbFile::writeTo(const char* filename)\n{\n    int fd;\n    bool success = false;\n\n    fd = ::open(filename, O_WRONLY);\n    if (fd < 0) {\n        goto out;\n    }\n    success = writeTo(fd);\n    close(fd);\n\nout:\n    if (!success) {\n        ALOGW(\"failed to write to %s: %s\\n\", filename, strerror(errno));\n    }\n    return success;\n}\n\nbool ObbFile::writeTo(int fd)\n{\n    if (fd < 0) {\n        return false;\n    }\n\n    lseek64(fd, 0, SEEK_END);\n\n    if (mPackageName.size() == 0 || mVersion == -1) {\n        ALOGW(\"tried to write uninitialized ObbFile data\\n\");\n        return false;\n    }\n\n    unsigned char intBuf[sizeof(uint32_t)+1];\n    memset(&intBuf, 0, sizeof(intBuf));\n\n    put4LE(intBuf, kSigVersion);\n    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {\n        ALOGW(\"couldn't write signature version: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    put4LE(intBuf, mVersion);\n    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {\n        ALOGW(\"couldn't write package version\\n\");\n        return false;\n    }\n\n    put4LE(intBuf, mFlags);\n    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {\n        ALOGW(\"couldn't write package version\\n\");\n        return false;\n    }\n\n    if (write(fd, mSalt, sizeof(mSalt)) != (ssize_t)sizeof(mSalt)) {\n        ALOGW(\"couldn't write salt: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    size_t packageNameLen = mPackageName.size();\n    put4LE(intBuf, packageNameLen);\n    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {\n        ALOGW(\"couldn't write package name length: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) {\n        ALOGW(\"couldn't write package name: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    put4LE(intBuf, kPackageNameOffset + packageNameLen);\n    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {\n        ALOGW(\"couldn't write footer size: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    put4LE(intBuf, kSignature);\n    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {\n        ALOGW(\"couldn't write footer magic signature: %s\\n\", strerror(errno));\n        return false;\n    }\n\n    return true;\n}\n\nbool ObbFile::removeFrom(const char* filename)\n{\n    int fd;\n    bool success = false;\n\n    fd = ::open(filename, O_RDWR);\n    if (fd < 0) {\n        goto out;\n    }\n    success = removeFrom(fd);\n    close(fd);\n\nout:\n    if (!success) {\n        ALOGW(\"failed to remove signature from %s: %s\\n\", filename, strerror(errno));\n    }\n    return success;\n}\n\nbool ObbFile::removeFrom(int fd)\n{\n    if (fd < 0) {\n        return false;\n    }\n\n    if (!readFrom(fd)) {\n        return false;\n    }\n\n    ftruncate(fd, mFooterStart);\n\n    return true;\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/ResourceTypes.cpp",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"ResourceType\"\n//#define LOG_NDEBUG 0\n\n#include <androidfw/ByteBucketArray.h>\n#include <androidfw/ResourceTypes.h>\n#include <androidfw/TypeWrappers.h>\n#include <utils/Atomic.h>\n#include <utils/ByteOrder.h>\n#include <utils/Debug.h>\n#include <utils/Log.h>\n#include <utils/String16.h>\n#include <utils/String8.h>\n#include <androidfw/ResourcePackageId.h>\n\n#include <stdlib.h>\n#include <string.h>\n#include <memory.h>\n#include <ctype.h>\n#include <stdint.h>\n#include <stddef.h>\n\n#ifndef INT32_MAX\n#define INT32_MAX ((int32_t)(2147483647))\n#endif\n\n#define STRING_POOL_NOISY(x) //x\n#define XML_NOISY(x) //x\n#define TABLE_NOISY(x) //x\n#define TABLE_GETENTRY(x) //x\n#define TABLE_SUPER_NOISY(x) //x\n#define LOAD_TABLE_NOISY(x) //x\n#define TABLE_THEME(x) //x\n#define LIB_NOISY(x) //x\n\nint customePackageId = 0x7f;\nchar* sktPackageName;\n\nnamespace android {\n\n#ifdef HAVE_WINSOCK\n#undef  nhtol\n#undef  htonl\n\n#ifdef HAVE_LITTLE_ENDIAN\n#define ntohl(x)    ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )\n#define htonl(x)    ntohl(x)\n#define ntohs(x)    ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )\n#define htons(x)    ntohs(x)\n#else\n#define ntohl(x)    (x)\n#define htonl(x)    (x)\n#define ntohs(x)    (x)\n#define htons(x)    (x)\n#endif\n#endif\n\n#define IDMAP_MAGIC             0x504D4449\n#define IDMAP_CURRENT_VERSION   0x00000001\n\n#define APP_PACKAGE_ID      0x7f\n#define SYS_PACKAGE_ID      0x01\n\n// Standard C isspace() is only required to look at the low byte of its input, so\n// produces incorrect results for UTF-16 characters.  For safety's sake, assume that\n// any high-byte UTF-16 code point is not whitespace.\ninline int isspace16(char16_t c) {\n    return (c < 0x0080 && isspace(c));\n}\n\ntemplate<typename T>\ninline static T max(T a, T b) {\n    return a > b ? a : b;\n}\n\n// range checked; guaranteed to NUL-terminate within the stated number of available slots\n// NOTE: if this truncates the dst string due to running out of space, no attempt is\n// made to avoid splitting surrogate pairs.\nstatic void strcpy16_dtoh(uint16_t* dst, const uint16_t* src, size_t avail)\n{\n    uint16_t* last = dst + avail - 1;\n    while (*src && (dst < last)) {\n        char16_t s = dtohs(*src);\n        *dst++ = s;\n        src++;\n    }\n    *dst = 0;\n}\n\nstatic status_t validate_chunk(const ResChunk_header* chunk,\n                               size_t minSize,\n                               const uint8_t* dataEnd,\n                               const char* name)\n{\n    const uint16_t headerSize = dtohs(chunk->headerSize);\n    const uint32_t size = dtohl(chunk->size);\n\n    if (headerSize >= minSize) {\n        if (headerSize <= size) {\n            if (((headerSize|size)&0x3) == 0) {\n                if ((size_t)size <= (size_t)(dataEnd-((const uint8_t*)chunk))) {\n                    return NO_ERROR;\n                }\n                ALOGW(\"%s data size 0x%x extends beyond resource end %p.\",\n                     name, size, (void*)(dataEnd-((const uint8_t*)chunk)));\n                return BAD_TYPE;\n            }\n            ALOGW(\"%s size 0x%x or headerSize 0x%x is not on an integer boundary.\",\n                 name, (int)size, (int)headerSize);\n            return BAD_TYPE;\n        }\n        ALOGW(\"%s size 0x%x is smaller than header size 0x%x.\",\n             name, size, headerSize);\n        return BAD_TYPE;\n    }\n    ALOGW(\"%s header size 0x%04x is too small.\",\n         name, headerSize);\n    return BAD_TYPE;\n}\n\nstatic void fill9patchOffsets(Res_png_9patch* patch) {\n    patch->xDivsOffset = sizeof(Res_png_9patch);\n    patch->yDivsOffset = patch->xDivsOffset + (patch->numXDivs * sizeof(int32_t));\n    patch->colorsOffset = patch->yDivsOffset + (patch->numYDivs * sizeof(int32_t));\n}\n\ninline void Res_value::copyFrom_dtoh(const Res_value& src)\n{\n    size = dtohs(src.size);\n    res0 = src.res0;\n    dataType = src.dataType;\n    data = dtohl(src.data);\n}\n\nvoid Res_png_9patch::deviceToFile()\n{\n    int32_t* xDivs = getXDivs();\n    for (int i = 0; i < numXDivs; i++) {\n        xDivs[i] = htonl(xDivs[i]);\n    }\n    int32_t* yDivs = getYDivs();\n    for (int i = 0; i < numYDivs; i++) {\n        yDivs[i] = htonl(yDivs[i]);\n    }\n    paddingLeft = htonl(paddingLeft);\n    paddingRight = htonl(paddingRight);\n    paddingTop = htonl(paddingTop);\n    paddingBottom = htonl(paddingBottom);\n    uint32_t* colors = getColors();\n    for (int i=0; i<numColors; i++) {\n        colors[i] = htonl(colors[i]);\n    }\n}\n\nvoid Res_png_9patch::fileToDevice()\n{\n    int32_t* xDivs = getXDivs();\n    for (int i = 0; i < numXDivs; i++) {\n        xDivs[i] = ntohl(xDivs[i]);\n    }\n    int32_t* yDivs = getYDivs();\n    for (int i = 0; i < numYDivs; i++) {\n        yDivs[i] = ntohl(yDivs[i]);\n    }\n    paddingLeft = ntohl(paddingLeft);\n    paddingRight = ntohl(paddingRight);\n    paddingTop = ntohl(paddingTop);\n    paddingBottom = ntohl(paddingBottom);\n    uint32_t* colors = getColors();\n    for (int i=0; i<numColors; i++) {\n        colors[i] = ntohl(colors[i]);\n    }\n}\n\nsize_t Res_png_9patch::serializedSize() const\n{\n    // The size of this struct is 32 bytes on the 32-bit target system\n    // 4 * int8_t\n    // 4 * int32_t\n    // 3 * uint32_t\n    return 32\n            + numXDivs * sizeof(int32_t)\n            + numYDivs * sizeof(int32_t)\n            + numColors * sizeof(uint32_t);\n}\n\nvoid* Res_png_9patch::serialize(const Res_png_9patch& patch, const int32_t* xDivs,\n                                const int32_t* yDivs, const uint32_t* colors)\n{\n    // Use calloc since we're going to leave a few holes in the data\n    // and want this to run cleanly under valgrind\n    void* newData = calloc(1, patch.serializedSize());\n    serialize(patch, xDivs, yDivs, colors, newData);\n    return newData;\n}\n\nvoid Res_png_9patch::serialize(const Res_png_9patch& patch, const int32_t* xDivs,\n                               const int32_t* yDivs, const uint32_t* colors, void* outData)\n{\n    uint8_t* data = (uint8_t*) outData;\n    memcpy(data, &patch.wasDeserialized, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors\n    memcpy(data + 12, &patch.paddingLeft, 16);   // copy paddingXXXX\n    data += 32;\n\n    memcpy(data, xDivs, patch.numXDivs * sizeof(int32_t));\n    data +=  patch.numXDivs * sizeof(int32_t);\n    memcpy(data, yDivs, patch.numYDivs * sizeof(int32_t));\n    data +=  patch.numYDivs * sizeof(int32_t);\n    memcpy(data, colors, patch.numColors * sizeof(uint32_t));\n\n    fill9patchOffsets(reinterpret_cast<Res_png_9patch*>(outData));\n}\n\nstatic bool assertIdmapHeader(const void* idmap, size_t size) {\n    if (reinterpret_cast<uintptr_t>(idmap) & 0x03) {\n        ALOGE(\"idmap: header is not word aligned\");\n        return false;\n    }\n\n    if (size < ResTable::IDMAP_HEADER_SIZE_BYTES) {\n        ALOGW(\"idmap: header too small (%d bytes)\", (uint32_t) size);\n        return false;\n    }\n\n    const uint32_t magic = htodl(*reinterpret_cast<const uint32_t*>(idmap));\n    if (magic != IDMAP_MAGIC) {\n        ALOGW(\"idmap: no magic found in header (is 0x%08x, expected 0x%08x)\",\n             magic, IDMAP_MAGIC);\n        return false;\n    }\n\n    const uint32_t version = htodl(*(reinterpret_cast<const uint32_t*>(idmap) + 1));\n    if (version != IDMAP_CURRENT_VERSION) {\n        // We are strict about versions because files with this format are\n        // auto-generated and don't need backwards compatibility.\n        ALOGW(\"idmap: version mismatch in header (is 0x%08x, expected 0x%08x)\",\n                version, IDMAP_CURRENT_VERSION);\n        return false;\n    }\n    return true;\n}\n\nclass IdmapEntries {\npublic:\n    IdmapEntries() : mData(NULL) {}\n\n    bool hasEntries() const {\n        if (mData == NULL) {\n            return false;\n        }\n\n        return (dtohs(*mData) > 0);\n    }\n\n    size_t byteSize() const {\n        if (mData == NULL) {\n            return 0;\n        }\n        uint16_t entryCount = dtohs(mData[2]);\n        return (sizeof(uint16_t) * 4) + (sizeof(uint32_t) * static_cast<size_t>(entryCount));\n    }\n\n    uint8_t targetTypeId() const {\n        if (mData == NULL) {\n            return 0;\n        }\n        return dtohs(mData[0]);\n    }\n\n    uint8_t overlayTypeId() const {\n        if (mData == NULL) {\n            return 0;\n        }\n        return dtohs(mData[1]);\n    }\n\n    status_t setTo(const void* entryHeader, size_t size) {\n        if (reinterpret_cast<uintptr_t>(entryHeader) & 0x03) {\n            ALOGE(\"idmap: entry header is not word aligned\");\n            return UNKNOWN_ERROR;\n        }\n\n        if (size < sizeof(uint16_t) * 4) {\n            ALOGE(\"idmap: entry header is too small (%u bytes)\", (uint32_t) size);\n            return UNKNOWN_ERROR;\n        }\n\n        const uint16_t* header = reinterpret_cast<const uint16_t*>(entryHeader);\n        const uint16_t targetTypeId = dtohs(header[0]);\n        const uint16_t overlayTypeId = dtohs(header[1]);\n        if (targetTypeId == 0 || overlayTypeId == 0 || targetTypeId > 255 || overlayTypeId > 255) {\n            ALOGE(\"idmap: invalid type map (%u -> %u)\", targetTypeId, overlayTypeId);\n            return UNKNOWN_ERROR;\n        }\n\n        uint16_t entryCount = dtohs(header[2]);\n        if (size < sizeof(uint32_t) * (entryCount + 2)) {\n            ALOGE(\"idmap: too small (%u bytes) for the number of entries (%u)\",\n                    (uint32_t) size, (uint32_t) entryCount);\n            return UNKNOWN_ERROR;\n        }\n        mData = header;\n        return NO_ERROR;\n    }\n\n    status_t lookup(uint16_t entryId, uint16_t* outEntryId) const {\n        uint16_t entryCount = dtohs(mData[2]);\n        uint16_t offset = dtohs(mData[3]);\n\n        if (entryId < offset) {\n            // The entry is not present in this idmap\n            return BAD_INDEX;\n        }\n\n        entryId -= offset;\n\n        if (entryId >= entryCount) {\n            // The entry is not present in this idmap\n            return BAD_INDEX;\n        }\n\n        // It is safe to access the type here without checking the size because\n        // we have checked this when it was first loaded.\n        const uint32_t* entries = reinterpret_cast<const uint32_t*>(mData) + 2;\n        uint32_t mappedEntry = dtohl(entries[entryId]);\n        if (mappedEntry == 0xffffffff) {\n            // This entry is not present in this idmap\n            return BAD_INDEX;\n        }\n        *outEntryId = static_cast<uint16_t>(mappedEntry);\n        return NO_ERROR;\n    }\n\nprivate:\n    const uint16_t* mData;\n};\n\nstatus_t parseIdmap(const void* idmap, size_t size, uint8_t* outPackageId, KeyedVector<uint8_t, IdmapEntries>* outMap) {\n    if (!assertIdmapHeader(idmap, size)) {\n        return UNKNOWN_ERROR;\n    }\n\n    size -= ResTable::IDMAP_HEADER_SIZE_BYTES;\n    if (size < sizeof(uint16_t) * 2) {\n        ALOGE(\"idmap: too small to contain any mapping\");\n        return UNKNOWN_ERROR;\n    }\n\n    const uint16_t* data = reinterpret_cast<const uint16_t*>(\n            reinterpret_cast<const uint8_t*>(idmap) + ResTable::IDMAP_HEADER_SIZE_BYTES);\n\n    uint16_t targetPackageId = dtohs(*(data++));\n    if (targetPackageId == 0 || targetPackageId > 255) {\n        ALOGE(\"idmap: target package ID is invalid (%02x)\", targetPackageId);\n        return UNKNOWN_ERROR;\n    }\n\n    uint16_t mapCount = dtohs(*(data++));\n    if (mapCount == 0) {\n        ALOGE(\"idmap: no mappings\");\n        return UNKNOWN_ERROR;\n    }\n\n    if (mapCount > 255) {\n        ALOGW(\"idmap: too many mappings. Only 255 are possible but %u are present\", (uint32_t) mapCount);\n    }\n\n    while (size > sizeof(uint16_t) * 4) {\n        IdmapEntries entries;\n        status_t err = entries.setTo(data, size);\n        if (err != NO_ERROR) {\n            return err;\n        }\n\n        ssize_t index = outMap->add(entries.overlayTypeId(), entries);\n        if (index < 0) {\n            return NO_MEMORY;\n        }\n\n        data += entries.byteSize() / sizeof(uint16_t);\n        size -= entries.byteSize();\n    }\n\n    if (outPackageId != NULL) {\n        *outPackageId = static_cast<uint8_t>(targetPackageId);\n    }\n    return NO_ERROR;\n}\n\nRes_png_9patch* Res_png_9patch::deserialize(void* inData)\n{\n\n    Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(inData);\n    patch->wasDeserialized = true;\n    fill9patchOffsets(patch);\n\n    return patch;\n}\n\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n\nResStringPool::ResStringPool()\n    : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL)\n{\n}\n\nResStringPool::ResStringPool(const void* data, size_t size, bool copyData)\n    : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL)\n{\n    setTo(data, size, copyData);\n}\n\nResStringPool::~ResStringPool()\n{\n    uninit();\n}\n\nvoid ResStringPool::setToEmpty()\n{\n    uninit();\n\n    mOwnedData = calloc(1, sizeof(ResStringPool_header));\n    ResStringPool_header* header = (ResStringPool_header*) mOwnedData;\n    mSize = 0;\n    mEntries = NULL;\n    mStrings = NULL;\n    mStringPoolSize = 0;\n    mEntryStyles = NULL;\n    mStyles = NULL;\n    mStylePoolSize = 0;\n    mHeader = (const ResStringPool_header*) header;\n}\n\nstatus_t ResStringPool::setTo(const void* data, size_t size, bool copyData)\n{\n    if (!data || !size) {\n        return (mError=BAD_TYPE);\n    }\n\n    uninit();\n\n    const bool notDeviceEndian = htods(0xf0) != 0xf0;\n\n    if (copyData || notDeviceEndian) {\n        mOwnedData = malloc(size);\n        if (mOwnedData == NULL) {\n            return (mError=NO_MEMORY);\n        }\n        memcpy(mOwnedData, data, size);\n        data = mOwnedData;\n    }\n\n    mHeader = (const ResStringPool_header*)data;\n\n    if (notDeviceEndian) {\n        ResStringPool_header* h = const_cast<ResStringPool_header*>(mHeader);\n        h->header.headerSize = dtohs(mHeader->header.headerSize);\n        h->header.type = dtohs(mHeader->header.type);\n        h->header.size = dtohl(mHeader->header.size);\n        h->stringCount = dtohl(mHeader->stringCount);\n        h->styleCount = dtohl(mHeader->styleCount);\n        h->flags = dtohl(mHeader->flags);\n        h->stringsStart = dtohl(mHeader->stringsStart);\n        h->stylesStart = dtohl(mHeader->stylesStart);\n    }\n\n    if (mHeader->header.headerSize > mHeader->header.size\n            || mHeader->header.size > size) {\n        ALOGW(\"Bad string block: header size %d or total size %d is larger than data size %d\\n\",\n                (int)mHeader->header.headerSize, (int)mHeader->header.size, (int)size);\n        return (mError=BAD_TYPE);\n    }\n    mSize = mHeader->header.size;\n    mEntries = (const uint32_t*)\n        (((const uint8_t*)data)+mHeader->header.headerSize);\n\n    if (mHeader->stringCount > 0) {\n        if ((mHeader->stringCount*sizeof(uint32_t) < mHeader->stringCount)  // uint32 overflow?\n            || (mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t)))\n                > size) {\n            ALOGW(\"Bad string block: entry of %d items extends past data size %d\\n\",\n                    (int)(mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t))),\n                    (int)size);\n            return (mError=BAD_TYPE);\n        }\n\n        size_t charSize;\n        if (mHeader->flags&ResStringPool_header::UTF8_FLAG) {\n            charSize = sizeof(uint8_t);\n        } else {\n            charSize = sizeof(char16_t);\n        }\n\n        // There should be at least space for the smallest string\n        // (2 bytes length, null terminator).\n        if (mHeader->stringsStart >= (mSize - sizeof(uint16_t))) {\n            ALOGW(\"Bad string block: string pool starts at %d, after total size %d\\n\",\n                    (int)mHeader->stringsStart, (int)mHeader->header.size);\n            return (mError=BAD_TYPE);\n        }\n\n        mStrings = (const void*)\n            (((const uint8_t*)data) + mHeader->stringsStart);\n\n        if (mHeader->styleCount == 0) {\n            mStringPoolSize = (mSize - mHeader->stringsStart) / charSize;\n        } else {\n            // check invariant: styles starts before end of data\n            if (mHeader->stylesStart >= (mSize - sizeof(uint16_t))) {\n                ALOGW(\"Bad style block: style block starts at %d past data size of %d\\n\",\n                    (int)mHeader->stylesStart, (int)mHeader->header.size);\n                return (mError=BAD_TYPE);\n            }\n            // check invariant: styles follow the strings\n            if (mHeader->stylesStart <= mHeader->stringsStart) {\n                ALOGW(\"Bad style block: style block starts at %d, before strings at %d\\n\",\n                    (int)mHeader->stylesStart, (int)mHeader->stringsStart);\n                return (mError=BAD_TYPE);\n            }\n            mStringPoolSize =\n                (mHeader->stylesStart-mHeader->stringsStart)/charSize;\n        }\n\n        // check invariant: stringCount > 0 requires a string pool to exist\n        if (mStringPoolSize == 0) {\n            ALOGW(\"Bad string block: stringCount is %d but pool size is 0\\n\", (int)mHeader->stringCount);\n            return (mError=BAD_TYPE);\n        }\n\n        if (notDeviceEndian) {\n            size_t i;\n            uint32_t* e = const_cast<uint32_t*>(mEntries);\n            for (i=0; i<mHeader->stringCount; i++) {\n                e[i] = dtohl(mEntries[i]);\n            }\n            if (!(mHeader->flags&ResStringPool_header::UTF8_FLAG)) {\n                const char16_t* strings = (const char16_t*)mStrings;\n                char16_t* s = const_cast<char16_t*>(strings);\n                for (i=0; i<mStringPoolSize; i++) {\n                    s[i] = dtohs(strings[i]);\n                }\n            }\n        }\n\n        if ((mHeader->flags&ResStringPool_header::UTF8_FLAG &&\n                ((uint8_t*)mStrings)[mStringPoolSize-1] != 0) ||\n                (!mHeader->flags&ResStringPool_header::UTF8_FLAG &&\n                ((char16_t*)mStrings)[mStringPoolSize-1] != 0)) {\n            ALOGW(\"Bad string block: last string is not 0-terminated\\n\");\n            return (mError=BAD_TYPE);\n        }\n    } else {\n        mStrings = NULL;\n        mStringPoolSize = 0;\n    }\n\n    if (mHeader->styleCount > 0) {\n        mEntryStyles = mEntries + mHeader->stringCount;\n        // invariant: integer overflow in calculating mEntryStyles\n        if (mEntryStyles < mEntries) {\n            ALOGW(\"Bad string block: integer overflow finding styles\\n\");\n            return (mError=BAD_TYPE);\n        }\n\n        if (((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader) > (int)size) {\n            ALOGW(\"Bad string block: entry of %d styles extends past data size %d\\n\",\n                    (int)((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader),\n                    (int)size);\n            return (mError=BAD_TYPE);\n        }\n        mStyles = (const uint32_t*)\n            (((const uint8_t*)data)+mHeader->stylesStart);\n        if (mHeader->stylesStart >= mHeader->header.size) {\n            ALOGW(\"Bad string block: style pool starts %d, after total size %d\\n\",\n                    (int)mHeader->stylesStart, (int)mHeader->header.size);\n            return (mError=BAD_TYPE);\n        }\n        mStylePoolSize =\n            (mHeader->header.size-mHeader->stylesStart)/sizeof(uint32_t);\n\n        if (notDeviceEndian) {\n            size_t i;\n            uint32_t* e = const_cast<uint32_t*>(mEntryStyles);\n            for (i=0; i<mHeader->styleCount; i++) {\n                e[i] = dtohl(mEntryStyles[i]);\n            }\n            uint32_t* s = const_cast<uint32_t*>(mStyles);\n            for (i=0; i<mStylePoolSize; i++) {\n                s[i] = dtohl(mStyles[i]);\n            }\n        }\n\n        const ResStringPool_span endSpan = {\n            { htodl(ResStringPool_span::END) },\n            htodl(ResStringPool_span::END), htodl(ResStringPool_span::END)\n        };\n        if (memcmp(&mStyles[mStylePoolSize-(sizeof(endSpan)/sizeof(uint32_t))],\n                   &endSpan, sizeof(endSpan)) != 0) {\n            ALOGW(\"Bad string block: last style is not 0xFFFFFFFF-terminated\\n\");\n            return (mError=BAD_TYPE);\n        }\n    } else {\n        mEntryStyles = NULL;\n        mStyles = NULL;\n        mStylePoolSize = 0;\n    }\n\n    return (mError=NO_ERROR);\n}\n\nstatus_t ResStringPool::getError() const\n{\n    return mError;\n}\n\nvoid ResStringPool::uninit()\n{\n    mError = NO_INIT;\n    if (mHeader != NULL && mCache != NULL) {\n        for (size_t x = 0; x < mHeader->stringCount; x++) {\n            if (mCache[x] != NULL) {\n                free(mCache[x]);\n                mCache[x] = NULL;\n            }\n        }\n        free(mCache);\n        mCache = NULL;\n    }\n    if (mOwnedData) {\n        free(mOwnedData);\n        mOwnedData = NULL;\n    }\n}\n\n/**\n * Strings in UTF-16 format have length indicated by a length encoded in the\n * stored data. It is either 1 or 2 characters of length data. This allows a\n * maximum length of 0x7FFFFFF (2147483647 bytes), but if you're storing that\n * much data in a string, you're abusing them.\n *\n * If the high bit is set, then there are two characters or 4 bytes of length\n * data encoded. In that case, drop the high bit of the first character and\n * add it together with the next character.\n */\nstatic inline size_t\ndecodeLength(const char16_t** str)\n{\n    size_t len = **str;\n    if ((len & 0x8000) != 0) {\n        (*str)++;\n        len = ((len & 0x7FFF) << 16) | **str;\n    }\n    (*str)++;\n    return len;\n}\n\n/**\n * Strings in UTF-8 format have length indicated by a length encoded in the\n * stored data. It is either 1 or 2 characters of length data. This allows a\n * maximum length of 0x7FFF (32767 bytes), but you should consider storing\n * text in another way if you're using that much data in a single string.\n *\n * If the high bit is set, then there are two characters or 2 bytes of length\n * data encoded. In that case, drop the high bit of the first character and\n * add it together with the next character.\n */\nstatic inline size_t\ndecodeLength(const uint8_t** str)\n{\n    size_t len = **str;\n    if ((len & 0x80) != 0) {\n        (*str)++;\n        len = ((len & 0x7F) << 8) | **str;\n    }\n    (*str)++;\n    return len;\n}\n\nconst uint16_t* ResStringPool::stringAt(size_t idx, size_t* u16len) const\n{\n    if (mError == NO_ERROR && idx < mHeader->stringCount) {\n        const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0;\n        const uint32_t off = mEntries[idx]/(isUTF8?sizeof(char):sizeof(char16_t));\n        if (off < (mStringPoolSize-1)) {\n            if (!isUTF8) {\n                const char16_t* strings = (char16_t*)mStrings;\n                const char16_t* str = strings+off;\n\n                *u16len = decodeLength(&str);\n                if ((uint32_t)(str+*u16len-strings) < mStringPoolSize) {\n                    return str;\n                } else {\n                    ALOGW(\"Bad string block: string #%d extends to %d, past end at %d\\n\",\n                            (int)idx, (int)(str+*u16len-strings), (int)mStringPoolSize);\n                }\n            } else {\n                const uint8_t* strings = (uint8_t*)mStrings;\n                const uint8_t* u8str = strings+off;\n\n                *u16len = decodeLength(&u8str);\n                size_t u8len = decodeLength(&u8str);\n\n                // encLen must be less than 0x7FFF due to encoding.\n                if ((uint32_t)(u8str+u8len-strings) < mStringPoolSize) {\n                    AutoMutex lock(mDecodeLock);\n\n                    if (mCache == NULL) {\n#ifndef HAVE_ANDROID_OS\n                        STRING_POOL_NOISY(ALOGI(\"CREATING STRING CACHE OF %d bytes\",\n                                mHeader->stringCount*sizeof(char16_t**)));\n#else\n                        // We do not want to be in this case when actually running Android.\n                        ALOGW(\"CREATING STRING CACHE OF %d bytes\",\n                                mHeader->stringCount*sizeof(char16_t**));\n#endif\n                        mCache = (char16_t**)calloc(mHeader->stringCount, sizeof(char16_t**));\n                        if (mCache == NULL) {\n                            ALOGW(\"No memory trying to allocate decode cache table of %d bytes\\n\",\n                                    (int)(mHeader->stringCount*sizeof(char16_t**)));\n                            return NULL;\n                        }\n                    }\n\n                    if (mCache[idx] != NULL) {\n                        return mCache[idx];\n                    }\n\n                    ssize_t actualLen = utf8_to_utf16_length(u8str, u8len);\n                    if (actualLen < 0 || (size_t)actualLen != *u16len) {\n                        ALOGW(\"Bad string block: string #%lld decoded length is not correct \"\n                                \"%lld vs %llu\\n\",\n                                (long long)idx, (long long)actualLen, (long long)*u16len);\n                        return NULL;\n                    }\n\n                    char16_t *u16str = (char16_t *)calloc(*u16len+1, sizeof(char16_t));\n                    if (!u16str) {\n                        ALOGW(\"No memory when trying to allocate decode cache for string #%d\\n\",\n                                (int)idx);\n                        return NULL;\n                    }\n\n                    STRING_POOL_NOISY(ALOGI(\"Caching UTF8 string: %s\", u8str));\n                    utf8_to_utf16(u8str, u8len, u16str);\n                    mCache[idx] = u16str;\n                    return u16str;\n                } else {\n                    ALOGW(\"Bad string block: string #%lld extends to %lld, past end at %lld\\n\",\n                            (long long)idx, (long long)(u8str+u8len-strings),\n                            (long long)mStringPoolSize);\n                }\n            }\n        } else {\n            ALOGW(\"Bad string block: string #%d entry is at %d, past end at %d\\n\",\n                    (int)idx, (int)(off*sizeof(uint16_t)),\n                    (int)(mStringPoolSize*sizeof(uint16_t)));\n        }\n    }\n    return NULL;\n}\n\nconst char* ResStringPool::string8At(size_t idx, size_t* outLen) const\n{\n    if (mError == NO_ERROR && idx < mHeader->stringCount) {\n        if ((mHeader->flags&ResStringPool_header::UTF8_FLAG) == 0) {\n            return NULL;\n        }\n        const uint32_t off = mEntries[idx]/sizeof(char);\n        if (off < (mStringPoolSize-1)) {\n            const uint8_t* strings = (uint8_t*)mStrings;\n            const uint8_t* str = strings+off;\n            *outLen = decodeLength(&str);\n            size_t encLen = decodeLength(&str);\n            if ((uint32_t)(str+encLen-strings) < mStringPoolSize) {\n                return (const char*)str;\n            } else {\n                ALOGW(\"Bad string block: string #%d extends to %d, past end at %d\\n\",\n                        (int)idx, (int)(str+encLen-strings), (int)mStringPoolSize);\n            }\n        } else {\n            ALOGW(\"Bad string block: string #%d entry is at %d, past end at %d\\n\",\n                    (int)idx, (int)(off*sizeof(uint16_t)),\n                    (int)(mStringPoolSize*sizeof(uint16_t)));\n        }\n    }\n    return NULL;\n}\n\nconst String8 ResStringPool::string8ObjectAt(size_t idx) const\n{\n    size_t len;\n    const char *str = string8At(idx, &len);\n    if (str != NULL) {\n        return String8(str, len);\n    }\n\n    const char16_t *str16 = stringAt(idx, &len);\n    if (str16 != NULL) {\n        return String8(str16, len);\n    }\n    return String8();\n}\n\nconst ResStringPool_span* ResStringPool::styleAt(const ResStringPool_ref& ref) const\n{\n    return styleAt(ref.index);\n}\n\nconst ResStringPool_span* ResStringPool::styleAt(size_t idx) const\n{\n    if (mError == NO_ERROR && idx < mHeader->styleCount) {\n        const uint32_t off = (mEntryStyles[idx]/sizeof(uint32_t));\n        if (off < mStylePoolSize) {\n            return (const ResStringPool_span*)(mStyles+off);\n        } else {\n            ALOGW(\"Bad string block: style #%d entry is at %d, past end at %d\\n\",\n                    (int)idx, (int)(off*sizeof(uint32_t)),\n                    (int)(mStylePoolSize*sizeof(uint32_t)));\n        }\n    }\n    return NULL;\n}\n\nssize_t ResStringPool::indexOfString(const char16_t* str, size_t strLen) const\n{\n    if (mError != NO_ERROR) {\n        return mError;\n    }\n\n    size_t len;\n\n    if ((mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0) {\n        STRING_POOL_NOISY(ALOGI(\"indexOfString UTF-8: %s\", String8(str, strLen).string()));\n\n        // The string pool contains UTF 8 strings; we don't want to cause\n        // temporary UTF-16 strings to be created as we search.\n        if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {\n            // Do a binary search for the string...  this is a little tricky,\n            // because the strings are sorted with strzcmp16().  So to match\n            // the ordering, we need to convert strings in the pool to UTF-16.\n            // But we don't want to hit the cache, so instead we will have a\n            // local temporary allocation for the conversions.\n            char16_t* convBuffer = (char16_t*)malloc(strLen+4);\n            ssize_t l = 0;\n            ssize_t h = mHeader->stringCount-1;\n\n            ssize_t mid;\n            while (l <= h) {\n                mid = l + (h - l)/2;\n                const uint8_t* s = (const uint8_t*)string8At(mid, &len);\n                int c;\n                if (s != NULL) {\n                    char16_t* end = utf8_to_utf16_n(s, len, convBuffer, strLen+3);\n                    *end = 0;\n                    c = strzcmp16(convBuffer, end-convBuffer, str, strLen);\n                } else {\n                    c = -1;\n                }\n                STRING_POOL_NOISY(ALOGI(\"Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\\n\",\n                             (const char*)s, c, (int)l, (int)mid, (int)h));\n                if (c == 0) {\n                    STRING_POOL_NOISY(ALOGI(\"MATCH!\"));\n                    free(convBuffer);\n                    return mid;\n                } else if (c < 0) {\n                    l = mid + 1;\n                } else {\n                    h = mid - 1;\n                }\n            }\n            free(convBuffer);\n        } else {\n            // It is unusual to get the ID from an unsorted string block...\n            // most often this happens because we want to get IDs for style\n            // span tags; since those always appear at the end of the string\n            // block, start searching at the back.\n            String8 str8(str, strLen);\n            const size_t str8Len = str8.size();\n            for (int i=mHeader->stringCount-1; i>=0; i--) {\n                const char* s = string8At(i, &len);\n                STRING_POOL_NOISY(ALOGI(\"Looking at %s, i=%d\\n\",\n                             String8(s).string(),\n                             i));\n                if (s && str8Len == len && memcmp(s, str8.string(), str8Len) == 0) {\n                    STRING_POOL_NOISY(ALOGI(\"MATCH!\"));\n                    return i;\n                }\n            }\n        }\n\n    } else {\n        STRING_POOL_NOISY(ALOGI(\"indexOfString UTF-16: %s\", String8(str, strLen).string()));\n\n        if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {\n            // Do a binary search for the string...\n            ssize_t l = 0;\n            ssize_t h = mHeader->stringCount-1;\n\n            ssize_t mid;\n            while (l <= h) {\n                mid = l + (h - l)/2;\n                const char16_t* s = stringAt(mid, &len);\n                int c = s ? strzcmp16(s, len, str, strLen) : -1;\n                STRING_POOL_NOISY(ALOGI(\"Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\\n\",\n                             String8(s).string(),\n                             c, (int)l, (int)mid, (int)h));\n                if (c == 0) {\n                    STRING_POOL_NOISY(ALOGI(\"MATCH!\"));\n                    return mid;\n                } else if (c < 0) {\n                    l = mid + 1;\n                } else {\n                    h = mid - 1;\n                }\n            }\n        } else {\n            // It is unusual to get the ID from an unsorted string block...\n            // most often this happens because we want to get IDs for style\n            // span tags; since those always appear at the end of the string\n            // block, start searching at the back.\n            for (int i=mHeader->stringCount-1; i>=0; i--) {\n                const char16_t* s = stringAt(i, &len);\n                STRING_POOL_NOISY(ALOGI(\"Looking at %s, i=%d\\n\",\n                             String8(s).string(),\n                             i));\n                if (s && strLen == len && strzcmp16(s, len, str, strLen) == 0) {\n                    STRING_POOL_NOISY(ALOGI(\"MATCH!\"));\n                    return i;\n                }\n            }\n        }\n    }\n\n    return NAME_NOT_FOUND;\n}\n\nsize_t ResStringPool::size() const\n{\n    return (mError == NO_ERROR) ? mHeader->stringCount : 0;\n}\n\nsize_t ResStringPool::styleCount() const\n{\n    return (mError == NO_ERROR) ? mHeader->styleCount : 0;\n}\n\nsize_t ResStringPool::bytes() const\n{\n    return (mError == NO_ERROR) ? mHeader->header.size : 0;\n}\n\nbool ResStringPool::isSorted() const\n{\n    return (mHeader->flags&ResStringPool_header::SORTED_FLAG)!=0;\n}\n\nbool ResStringPool::isUTF8() const\n{\n    return (mHeader->flags&ResStringPool_header::UTF8_FLAG)!=0;\n}\n\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n\nResXMLParser::ResXMLParser(const ResXMLTree& tree)\n    : mTree(tree), mEventCode(BAD_DOCUMENT)\n{\n}\n\nvoid ResXMLParser::restart()\n{\n    mCurNode = NULL;\n    mEventCode = mTree.mError == NO_ERROR ? START_DOCUMENT : BAD_DOCUMENT;\n}\nconst ResStringPool& ResXMLParser::getStrings() const\n{\n    return mTree.mStrings;\n}\n\nResXMLParser::event_code_t ResXMLParser::getEventType() const\n{\n    return mEventCode;\n}\n\nResXMLParser::event_code_t ResXMLParser::next()\n{\n    if (mEventCode == START_DOCUMENT) {\n        mCurNode = mTree.mRootNode;\n        mCurExt = mTree.mRootExt;\n        return (mEventCode=mTree.mRootCode);\n    } else if (mEventCode >= FIRST_CHUNK_CODE) {\n        return nextNode();\n    }\n    return mEventCode;\n}\n\nint32_t ResXMLParser::getCommentID() const\n{\n    return mCurNode != NULL ? dtohl(mCurNode->comment.index) : -1;\n}\n\nconst uint16_t* ResXMLParser::getComment(size_t* outLen) const\n{\n    int32_t id = getCommentID();\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nuint32_t ResXMLParser::getLineNumber() const\n{\n    return mCurNode != NULL ? dtohl(mCurNode->lineNumber) : -1;\n}\n\nint32_t ResXMLParser::getTextID() const\n{\n    if (mEventCode == TEXT) {\n        return dtohl(((const ResXMLTree_cdataExt*)mCurExt)->data.index);\n    }\n    return -1;\n}\n\nconst uint16_t* ResXMLParser::getText(size_t* outLen) const\n{\n    int32_t id = getTextID();\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nssize_t ResXMLParser::getTextValue(Res_value* outValue) const\n{\n    if (mEventCode == TEXT) {\n        outValue->copyFrom_dtoh(((const ResXMLTree_cdataExt*)mCurExt)->typedData);\n        return sizeof(Res_value);\n    }\n    return BAD_TYPE;\n}\n\nint32_t ResXMLParser::getNamespacePrefixID() const\n{\n    if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {\n        return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->prefix.index);\n    }\n    return -1;\n}\n\nconst uint16_t* ResXMLParser::getNamespacePrefix(size_t* outLen) const\n{\n    int32_t id = getNamespacePrefixID();\n    //printf(\"prefix=%d  event=%p\\n\", id, mEventCode);\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nint32_t ResXMLParser::getNamespaceUriID() const\n{\n    if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {\n        return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->uri.index);\n    }\n    return -1;\n}\n\nconst uint16_t* ResXMLParser::getNamespaceUri(size_t* outLen) const\n{\n    int32_t id = getNamespaceUriID();\n    //printf(\"uri=%d  event=%p\\n\", id, mEventCode);\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nint32_t ResXMLParser::getElementNamespaceID() const\n{\n    if (mEventCode == START_TAG) {\n        return dtohl(((const ResXMLTree_attrExt*)mCurExt)->ns.index);\n    }\n    if (mEventCode == END_TAG) {\n        return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->ns.index);\n    }\n    return -1;\n}\n\nconst uint16_t* ResXMLParser::getElementNamespace(size_t* outLen) const\n{\n    int32_t id = getElementNamespaceID();\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nint32_t ResXMLParser::getElementNameID() const\n{\n    if (mEventCode == START_TAG) {\n        return dtohl(((const ResXMLTree_attrExt*)mCurExt)->name.index);\n    }\n    if (mEventCode == END_TAG) {\n        return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->name.index);\n    }\n    return -1;\n}\n\nconst uint16_t* ResXMLParser::getElementName(size_t* outLen) const\n{\n    int32_t id = getElementNameID();\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nsize_t ResXMLParser::getAttributeCount() const\n{\n    if (mEventCode == START_TAG) {\n        return dtohs(((const ResXMLTree_attrExt*)mCurExt)->attributeCount);\n    }\n    return 0;\n}\n\nint32_t ResXMLParser::getAttributeNamespaceID(size_t idx) const\n{\n    if (mEventCode == START_TAG) {\n        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;\n        if (idx < dtohs(tag->attributeCount)) {\n            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)\n                (((const uint8_t*)tag)\n                 + dtohs(tag->attributeStart)\n                 + (dtohs(tag->attributeSize)*idx));\n            return dtohl(attr->ns.index);\n        }\n    }\n    return -2;\n}\n\nconst uint16_t* ResXMLParser::getAttributeNamespace(size_t idx, size_t* outLen) const\n{\n    int32_t id = getAttributeNamespaceID(idx);\n    //printf(\"attribute namespace=%d  idx=%d  event=%p\\n\", id, idx, mEventCode);\n    //XML_NOISY(printf(\"getAttributeNamespace 0x%x=0x%x\\n\", idx, id));\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nconst char* ResXMLParser::getAttributeNamespace8(size_t idx, size_t* outLen) const\n{\n    int32_t id = getAttributeNamespaceID(idx);\n    //printf(\"attribute namespace=%d  idx=%d  event=%p\\n\", id, idx, mEventCode);\n    //XML_NOISY(printf(\"getAttributeNamespace 0x%x=0x%x\\n\", idx, id));\n    return id >= 0 ? mTree.mStrings.string8At(id, outLen) : NULL;\n}\n\nint32_t ResXMLParser::getAttributeNameID(size_t idx) const\n{\n    if (mEventCode == START_TAG) {\n        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;\n        if (idx < dtohs(tag->attributeCount)) {\n            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)\n                (((const uint8_t*)tag)\n                 + dtohs(tag->attributeStart)\n                 + (dtohs(tag->attributeSize)*idx));\n            return dtohl(attr->name.index);\n        }\n    }\n    return -1;\n}\n\nconst uint16_t* ResXMLParser::getAttributeName(size_t idx, size_t* outLen) const\n{\n    int32_t id = getAttributeNameID(idx);\n    //printf(\"attribute name=%d  idx=%d  event=%p\\n\", id, idx, mEventCode);\n    //XML_NOISY(printf(\"getAttributeName 0x%x=0x%x\\n\", idx, id));\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nconst char* ResXMLParser::getAttributeName8(size_t idx, size_t* outLen) const\n{\n    int32_t id = getAttributeNameID(idx);\n    //printf(\"attribute name=%d  idx=%d  event=%p\\n\", id, idx, mEventCode);\n    //XML_NOISY(printf(\"getAttributeName 0x%x=0x%x\\n\", idx, id));\n    return id >= 0 ? mTree.mStrings.string8At(id, outLen) : NULL;\n}\n\nuint32_t ResXMLParser::getAttributeNameResID(size_t idx) const\n{\n    int32_t id = getAttributeNameID(idx);\n    if (id >= 0 && (size_t)id < mTree.mNumResIds) {\n        return dtohl(mTree.mResIds[id]);\n    }\n    return 0;\n}\n\nint32_t ResXMLParser::getAttributeValueStringID(size_t idx) const\n{\n    if (mEventCode == START_TAG) {\n        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;\n        if (idx < dtohs(tag->attributeCount)) {\n            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)\n                (((const uint8_t*)tag)\n                 + dtohs(tag->attributeStart)\n                 + (dtohs(tag->attributeSize)*idx));\n            return dtohl(attr->rawValue.index);\n        }\n    }\n    return -1;\n}\n\nconst uint16_t* ResXMLParser::getAttributeStringValue(size_t idx, size_t* outLen) const\n{\n    int32_t id = getAttributeValueStringID(idx);\n    //XML_NOISY(printf(\"getAttributeValue 0x%x=0x%x\\n\", idx, id));\n    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;\n}\n\nint32_t ResXMLParser::getAttributeDataType(size_t idx) const\n{\n    if (mEventCode == START_TAG) {\n        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;\n        if (idx < dtohs(tag->attributeCount)) {\n            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)\n                (((const uint8_t*)tag)\n                 + dtohs(tag->attributeStart)\n                 + (dtohs(tag->attributeSize)*idx));\n            uint8_t type = attr->typedValue.dataType;\n            if (type != Res_value::TYPE_DYNAMIC_REFERENCE) {\n                return type;\n            }\n\n            // This is a dynamic reference. We adjust those references\n            // to regular references at this level, so lie to the caller.\n            return Res_value::TYPE_REFERENCE;\n        }\n    }\n    return Res_value::TYPE_NULL;\n}\n\nint32_t ResXMLParser::getAttributeData(size_t idx) const\n{\n    if (mEventCode == START_TAG) {\n        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;\n        if (idx < dtohs(tag->attributeCount)) {\n            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)\n                (((const uint8_t*)tag)\n                 + dtohs(tag->attributeStart)\n                 + (dtohs(tag->attributeSize)*idx));\n            if (attr->typedValue.dataType != Res_value::TYPE_DYNAMIC_REFERENCE ||\n                    mTree.mDynamicRefTable == NULL) {\n                return dtohl(attr->typedValue.data);\n            }\n\n            uint32_t data = dtohl(attr->typedValue.data);\n            if (mTree.mDynamicRefTable->lookupResourceId(&data) == NO_ERROR) {\n                return data;\n            }\n        }\n    }\n    return 0;\n}\n\nssize_t ResXMLParser::getAttributeValue(size_t idx, Res_value* outValue) const\n{\n    if (mEventCode == START_TAG) {\n        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;\n        if (idx < dtohs(tag->attributeCount)) {\n            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)\n                (((const uint8_t*)tag)\n                 + dtohs(tag->attributeStart)\n                 + (dtohs(tag->attributeSize)*idx));\n            outValue->copyFrom_dtoh(attr->typedValue);\n            if (mTree.mDynamicRefTable != NULL &&\n                    mTree.mDynamicRefTable->lookupResourceValue(outValue) != NO_ERROR) {\n                return BAD_TYPE;\n            }\n            return sizeof(Res_value);\n        }\n    }\n    return BAD_TYPE;\n}\n\nssize_t ResXMLParser::indexOfAttribute(const char* ns, const char* attr) const\n{\n    String16 nsStr(ns != NULL ? ns : \"\");\n    String16 attrStr(attr);\n    return indexOfAttribute(ns ? nsStr.string() : NULL, ns ? nsStr.size() : 0,\n                            attrStr.string(), attrStr.size());\n}\n\nssize_t ResXMLParser::indexOfAttribute(const char16_t* ns, size_t nsLen,\n                                       const char16_t* attr, size_t attrLen) const\n{\n    if (mEventCode == START_TAG) {\n        if (attr == NULL) {\n            return NAME_NOT_FOUND;\n        }\n        const size_t N = getAttributeCount();\n        if (mTree.mStrings.isUTF8()) {\n            String8 ns8, attr8;\n            if (ns != NULL) {\n                ns8 = String8(ns, nsLen);\n            }\n            attr8 = String8(attr, attrLen);\n            STRING_POOL_NOISY(ALOGI(\"indexOfAttribute UTF8 %s (%d) / %s (%d)\", ns8.string(), nsLen,\n                    attr8.string(), attrLen));\n            for (size_t i=0; i<N; i++) {\n                size_t curNsLen = 0, curAttrLen = 0;\n                const char* curNs = getAttributeNamespace8(i, &curNsLen);\n                const char* curAttr = getAttributeName8(i, &curAttrLen);\n                STRING_POOL_NOISY(ALOGI(\"  curNs=%s (%d), curAttr=%s (%d)\", curNs, curNsLen,\n                        curAttr, curAttrLen));\n                if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen\n                        && memcmp(attr8.string(), curAttr, attrLen) == 0) {\n                    if (ns == NULL) {\n                        if (curNs == NULL) {\n                            STRING_POOL_NOISY(ALOGI(\"  FOUND!\"));\n                            return i;\n                        }\n                    } else if (curNs != NULL) {\n                        //printf(\" --> ns=%s, curNs=%s\\n\",\n                        //       String8(ns).string(), String8(curNs).string());\n                        if (memcmp(ns8.string(), curNs, nsLen) == 0) {\n                            STRING_POOL_NOISY(ALOGI(\"  FOUND!\"));\n                            return i;\n                        }\n                    }\n                }\n            }\n        } else {\n            STRING_POOL_NOISY(ALOGI(\"indexOfAttribute UTF16 %s (%d) / %s (%d)\",\n                    String8(ns, nsLen).string(), nsLen,\n                    String8(attr, attrLen).string(), attrLen));\n            for (size_t i=0; i<N; i++) {\n                size_t curNsLen = 0, curAttrLen = 0;\n                const char16_t* curNs = getAttributeNamespace(i, &curNsLen);\n                const char16_t* curAttr = getAttributeName(i, &curAttrLen);\n                STRING_POOL_NOISY(ALOGI(\"  curNs=%s (%d), curAttr=%s (%d)\",\n                        String8(curNs, curNsLen).string(), curNsLen,\n                        String8(curAttr, curAttrLen).string(), curAttrLen));\n                if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen\n                        && (memcmp(attr, curAttr, attrLen*sizeof(char16_t)) == 0)) {\n                    if (ns == NULL) {\n                        if (curNs == NULL) {\n                            STRING_POOL_NOISY(ALOGI(\"  FOUND!\"));\n                            return i;\n                        }\n                    } else if (curNs != NULL) {\n                        //printf(\" --> ns=%s, curNs=%s\\n\",\n                        //       String8(ns).string(), String8(curNs).string());\n                        if (memcmp(ns, curNs, nsLen*sizeof(char16_t)) == 0) {\n                            STRING_POOL_NOISY(ALOGI(\"  FOUND!\"));\n                            return i;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    return NAME_NOT_FOUND;\n}\n\nssize_t ResXMLParser::indexOfID() const\n{\n    if (mEventCode == START_TAG) {\n        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->idIndex);\n        if (idx > 0) return (idx-1);\n    }\n    return NAME_NOT_FOUND;\n}\n\nssize_t ResXMLParser::indexOfClass() const\n{\n    if (mEventCode == START_TAG) {\n        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->classIndex);\n        if (idx > 0) return (idx-1);\n    }\n    return NAME_NOT_FOUND;\n}\n\nssize_t ResXMLParser::indexOfStyle() const\n{\n    if (mEventCode == START_TAG) {\n        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->styleIndex);\n        if (idx > 0) return (idx-1);\n    }\n    return NAME_NOT_FOUND;\n}\n\nResXMLParser::event_code_t ResXMLParser::nextNode()\n{\n    if (mEventCode < 0) {\n        return mEventCode;\n    }\n\n    do {\n        const ResXMLTree_node* next = (const ResXMLTree_node*)\n            (((const uint8_t*)mCurNode) + dtohl(mCurNode->header.size));\n        //ALOGW(\"Next node: prev=%p, next=%p\\n\", mCurNode, next);\n\n        if (((const uint8_t*)next) >= mTree.mDataEnd) {\n            mCurNode = NULL;\n            return (mEventCode=END_DOCUMENT);\n        }\n\n        if (mTree.validateNode(next) != NO_ERROR) {\n            mCurNode = NULL;\n            return (mEventCode=BAD_DOCUMENT);\n        }\n\n        mCurNode = next;\n        const uint16_t headerSize = dtohs(next->header.headerSize);\n        const uint32_t totalSize = dtohl(next->header.size);\n        mCurExt = ((const uint8_t*)next) + headerSize;\n        size_t minExtSize = 0;\n        event_code_t eventCode = (event_code_t)dtohs(next->header.type);\n        switch ((mEventCode=eventCode)) {\n            case RES_XML_START_NAMESPACE_TYPE:\n            case RES_XML_END_NAMESPACE_TYPE:\n                minExtSize = sizeof(ResXMLTree_namespaceExt);\n                break;\n            case RES_XML_START_ELEMENT_TYPE:\n                minExtSize = sizeof(ResXMLTree_attrExt);\n                break;\n            case RES_XML_END_ELEMENT_TYPE:\n                minExtSize = sizeof(ResXMLTree_endElementExt);\n                break;\n            case RES_XML_CDATA_TYPE:\n                minExtSize = sizeof(ResXMLTree_cdataExt);\n                break;\n            default:\n                ALOGW(\"Unknown XML block: header type %d in node at %d\\n\",\n                     (int)dtohs(next->header.type),\n                     (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)));\n                continue;\n        }\n\n        if ((totalSize-headerSize) < minExtSize) {\n            ALOGW(\"Bad XML block: header type 0x%x in node at 0x%x has size %d, need %d\\n\",\n                 (int)dtohs(next->header.type),\n                 (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)),\n                 (int)(totalSize-headerSize), (int)minExtSize);\n            return (mEventCode=BAD_DOCUMENT);\n        }\n\n        //printf(\"CurNode=%p, CurExt=%p, headerSize=%d, minExtSize=%d\\n\",\n        //       mCurNode, mCurExt, headerSize, minExtSize);\n\n        return eventCode;\n    } while (true);\n}\n\nvoid ResXMLParser::getPosition(ResXMLParser::ResXMLPosition* pos) const\n{\n    pos->eventCode = mEventCode;\n    pos->curNode = mCurNode;\n    pos->curExt = mCurExt;\n}\n\nvoid ResXMLParser::setPosition(const ResXMLParser::ResXMLPosition& pos)\n{\n    mEventCode = pos.eventCode;\n    mCurNode = pos.curNode;\n    mCurExt = pos.curExt;\n}\n\n// --------------------------------------------------------------------\n\nstatic volatile int32_t gCount = 0;\n\nResXMLTree::ResXMLTree(const DynamicRefTable* dynamicRefTable)\n    : ResXMLParser(*this)\n    , mDynamicRefTable(dynamicRefTable)\n    , mError(NO_INIT), mOwnedData(NULL)\n{\n    //ALOGI(\"Creating ResXMLTree %p #%d\\n\", this, android_atomic_inc(&gCount)+1);\n    restart();\n}\n\nResXMLTree::ResXMLTree()\n    : ResXMLParser(*this)\n    , mDynamicRefTable(NULL)\n    , mError(NO_INIT), mOwnedData(NULL)\n{\n    //ALOGI(\"Creating ResXMLTree %p #%d\\n\", this, android_atomic_inc(&gCount)+1);\n    restart();\n}\n\nResXMLTree::~ResXMLTree()\n{\n    //ALOGI(\"Destroying ResXMLTree in %p #%d\\n\", this, android_atomic_dec(&gCount)-1);\n    uninit();\n}\n\nstatus_t ResXMLTree::setTo(const void* data, size_t size, bool copyData)\n{\n    uninit();\n    mEventCode = START_DOCUMENT;\n\n    if (!data || !size) {\n        return (mError=BAD_TYPE);\n    }\n\n    if (copyData) {\n        mOwnedData = malloc(size);\n        if (mOwnedData == NULL) {\n            return (mError=NO_MEMORY);\n        }\n        memcpy(mOwnedData, data, size);\n        data = mOwnedData;\n    }\n\n    mHeader = (const ResXMLTree_header*)data;\n    mSize = dtohl(mHeader->header.size);\n    if (dtohs(mHeader->header.headerSize) > mSize || mSize > size) {\n        ALOGW(\"Bad XML block: header size %d or total size %d is larger than data size %d\\n\",\n             (int)dtohs(mHeader->header.headerSize),\n             (int)dtohl(mHeader->header.size), (int)size);\n        mError = BAD_TYPE;\n        restart();\n        return mError;\n    }\n    mDataEnd = ((const uint8_t*)mHeader) + mSize;\n\n    mStrings.uninit();\n    mRootNode = NULL;\n    mResIds = NULL;\n    mNumResIds = 0;\n\n    // First look for a couple interesting chunks: the string block\n    // and first XML node.\n    const ResChunk_header* chunk =\n        (const ResChunk_header*)(((const uint8_t*)mHeader) + dtohs(mHeader->header.headerSize));\n    const ResChunk_header* lastChunk = chunk;\n    while (((const uint8_t*)chunk) < (mDataEnd-sizeof(ResChunk_header)) &&\n           ((const uint8_t*)chunk) < (mDataEnd-dtohl(chunk->size))) {\n        status_t err = validate_chunk(chunk, sizeof(ResChunk_header), mDataEnd, \"XML\");\n        if (err != NO_ERROR) {\n            mError = err;\n            goto done;\n        }\n        const uint16_t type = dtohs(chunk->type);\n        const size_t size = dtohl(chunk->size);\n        XML_NOISY(printf(\"Scanning @ %p: type=0x%x, size=0x%x\\n\",\n                     (void*)(((uint32_t)chunk)-((uint32_t)mHeader)), type, size));\n        if (type == RES_STRING_POOL_TYPE) {\n            mStrings.setTo(chunk, size);\n        } else if (type == RES_XML_RESOURCE_MAP_TYPE) {\n            mResIds = (const uint32_t*)\n                (((const uint8_t*)chunk)+dtohs(chunk->headerSize));\n            mNumResIds = (dtohl(chunk->size)-dtohs(chunk->headerSize))/sizeof(uint32_t);\n        } else if (type >= RES_XML_FIRST_CHUNK_TYPE\n                   && type <= RES_XML_LAST_CHUNK_TYPE) {\n            if (validateNode((const ResXMLTree_node*)chunk) != NO_ERROR) {\n                mError = BAD_TYPE;\n                goto done;\n            }\n            mCurNode = (const ResXMLTree_node*)lastChunk;\n            if (nextNode() == BAD_DOCUMENT) {\n                mError = BAD_TYPE;\n                goto done;\n            }\n            mRootNode = mCurNode;\n            mRootExt = mCurExt;\n            mRootCode = mEventCode;\n            break;\n        } else {\n            XML_NOISY(printf(\"Skipping unknown chunk!\\n\"));\n        }\n        lastChunk = chunk;\n        chunk = (const ResChunk_header*)\n            (((const uint8_t*)chunk) + size);\n    }\n\n    if (mRootNode == NULL) {\n        ALOGW(\"Bad XML block: no root element node found\\n\");\n        mError = BAD_TYPE;\n        goto done;\n    }\n\n    mError = mStrings.getError();\n\ndone:\n    restart();\n    return mError;\n}\n\nstatus_t ResXMLTree::getError() const\n{\n    return mError;\n}\n\nvoid ResXMLTree::uninit()\n{\n    mError = NO_INIT;\n    mStrings.uninit();\n    if (mOwnedData) {\n        free(mOwnedData);\n        mOwnedData = NULL;\n    }\n    restart();\n}\n\nstatus_t ResXMLTree::validateNode(const ResXMLTree_node* node) const\n{\n    const uint16_t eventCode = dtohs(node->header.type);\n\n    status_t err = validate_chunk(\n        &node->header, sizeof(ResXMLTree_node),\n        mDataEnd, \"ResXMLTree_node\");\n\n    if (err >= NO_ERROR) {\n        // Only perform additional validation on START nodes\n        if (eventCode != RES_XML_START_ELEMENT_TYPE) {\n            return NO_ERROR;\n        }\n\n        const uint16_t headerSize = dtohs(node->header.headerSize);\n        const uint32_t size = dtohl(node->header.size);\n        const ResXMLTree_attrExt* attrExt = (const ResXMLTree_attrExt*)\n            (((const uint8_t*)node) + headerSize);\n        // check for sensical values pulled out of the stream so far...\n        if ((size >= headerSize + sizeof(ResXMLTree_attrExt))\n                && ((void*)attrExt > (void*)node)) {\n            const size_t attrSize = ((size_t)dtohs(attrExt->attributeSize))\n                * dtohs(attrExt->attributeCount);\n            if ((dtohs(attrExt->attributeStart)+attrSize) <= (size-headerSize)) {\n                return NO_ERROR;\n            }\n            ALOGW(\"Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\\n\",\n                    (unsigned int)(dtohs(attrExt->attributeStart)+attrSize),\n                    (unsigned int)(size-headerSize));\n        }\n        else {\n            ALOGW(\"Bad XML start block: node header size 0x%x, size 0x%x\\n\",\n                (unsigned int)headerSize, (unsigned int)size);\n        }\n        return BAD_TYPE;\n    }\n\n    return err;\n\n#if 0\n    const bool isStart = dtohs(node->header.type) == RES_XML_START_ELEMENT_TYPE;\n\n    const uint16_t headerSize = dtohs(node->header.headerSize);\n    const uint32_t size = dtohl(node->header.size);\n\n    if (headerSize >= (isStart ? sizeof(ResXMLTree_attrNode) : sizeof(ResXMLTree_node))) {\n        if (size >= headerSize) {\n            if (((const uint8_t*)node) <= (mDataEnd-size)) {\n                if (!isStart) {\n                    return NO_ERROR;\n                }\n                if ((((size_t)dtohs(node->attributeSize))*dtohs(node->attributeCount))\n                        <= (size-headerSize)) {\n                    return NO_ERROR;\n                }\n                ALOGW(\"Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\\n\",\n                        ((int)dtohs(node->attributeSize))*dtohs(node->attributeCount),\n                        (int)(size-headerSize));\n                return BAD_TYPE;\n            }\n            ALOGW(\"Bad XML block: node at 0x%x extends beyond data end 0x%x\\n\",\n                    (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)), (int)mSize);\n            return BAD_TYPE;\n        }\n        ALOGW(\"Bad XML block: node at 0x%x header size 0x%x smaller than total size 0x%x\\n\",\n                (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),\n                (int)headerSize, (int)size);\n        return BAD_TYPE;\n    }\n    ALOGW(\"Bad XML block: node at 0x%x header size 0x%x too small\\n\",\n            (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),\n            (int)headerSize);\n    return BAD_TYPE;\n#endif\n}\n\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n\nvoid ResTable_config::copyFromDeviceNoSwap(const ResTable_config& o) {\n    const size_t size = dtohl(o.size);\n    if (size >= sizeof(ResTable_config)) {\n        *this = o;\n    } else {\n        memcpy(this, &o, size);\n        memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size);\n    }\n}\n\n/* static */ size_t unpackLanguageOrRegion(const char in[2], const char base,\n        char out[4]) {\n  if (in[0] & 0x80) {\n      // The high bit is \"1\", which means this is a packed three letter\n      // language code.\n\n      // The smallest 5 bits of the second char are the first alphabet.\n      const uint8_t first = in[1] & 0x1f;\n      // The last three bits of the second char and the first two bits\n      // of the first char are the second alphabet.\n      const uint8_t second = ((in[1] & 0xe0) >> 5) + ((in[0] & 0x03) << 3);\n      // Bits 3 to 7 (inclusive) of the first char are the third alphabet.\n      const uint8_t third = (in[0] & 0x7c) >> 2;\n\n      out[0] = first + base;\n      out[1] = second + base;\n      out[2] = third + base;\n      out[3] = 0;\n\n      return 3;\n  }\n\n  if (in[0]) {\n      memcpy(out, in, 2);\n      memset(out + 2, 0, 2);\n      return 2;\n  }\n\n  memset(out, 0, 4);\n  return 0;\n}\n\n/* static */ void packLanguageOrRegion(const char* in, const char base,\n        char out[2]) {\n  if (in[2] == 0 || in[2] == '-') {\n      out[0] = in[0];\n      out[1] = in[1];\n  } else {\n      uint8_t first = (in[0] - base) & 0x007f;\n      uint8_t second = (in[1] - base) & 0x007f;\n      uint8_t third = (in[2] - base) & 0x007f;\n\n      out[0] = (0x80 | (third << 2) | (second >> 3));\n      out[1] = ((second << 5) | first);\n  }\n}\n\n\nvoid ResTable_config::packLanguage(const char* language) {\n    packLanguageOrRegion(language, 'a', this->language);\n}\n\nvoid ResTable_config::packRegion(const char* region) {\n    packLanguageOrRegion(region, '0', this->country);\n}\n\nsize_t ResTable_config::unpackLanguage(char language[4]) const {\n    return unpackLanguageOrRegion(this->language, 'a', language);\n}\n\nsize_t ResTable_config::unpackRegion(char region[4]) const {\n    return unpackLanguageOrRegion(this->country, '0', region);\n}\n\n\nvoid ResTable_config::copyFromDtoH(const ResTable_config& o) {\n    copyFromDeviceNoSwap(o);\n    size = sizeof(ResTable_config);\n    mcc = dtohs(mcc);\n    mnc = dtohs(mnc);\n    density = dtohs(density);\n    screenWidth = dtohs(screenWidth);\n    screenHeight = dtohs(screenHeight);\n    sdkVersion = dtohs(sdkVersion);\n    minorVersion = dtohs(minorVersion);\n    smallestScreenWidthDp = dtohs(smallestScreenWidthDp);\n    screenWidthDp = dtohs(screenWidthDp);\n    screenHeightDp = dtohs(screenHeightDp);\n}\n\nvoid ResTable_config::swapHtoD() {\n    size = htodl(size);\n    mcc = htods(mcc);\n    mnc = htods(mnc);\n    density = htods(density);\n    screenWidth = htods(screenWidth);\n    screenHeight = htods(screenHeight);\n    sdkVersion = htods(sdkVersion);\n    minorVersion = htods(minorVersion);\n    smallestScreenWidthDp = htods(smallestScreenWidthDp);\n    screenWidthDp = htods(screenWidthDp);\n    screenHeightDp = htods(screenHeightDp);\n}\n\n/* static */ inline int compareLocales(const ResTable_config &l, const ResTable_config &r) {\n    if (l.locale != r.locale) {\n        // NOTE: This is the old behaviour with respect to comparison orders.\n        // The diff value here doesn't make much sense (given our bit packing scheme)\n        // but it's stable, and that's all we need.\n        return l.locale - r.locale;\n    }\n\n    // The language & region are equal, so compare the scripts and variants.\n    int script = memcmp(l.localeScript, r.localeScript, sizeof(l.localeScript));\n    if (script) {\n        return script;\n    }\n\n    // The language, region and script are equal, so compare variants.\n    //\n    // This should happen very infrequently (if at all.)\n    return memcmp(l.localeVariant, r.localeVariant, sizeof(l.localeVariant));\n}\n\nint ResTable_config::compare(const ResTable_config& o) const {\n    int32_t diff = (int32_t)(imsi - o.imsi);\n    if (diff != 0) return diff;\n    diff = compareLocales(*this, o);\n    if (diff != 0) return diff;\n    diff = (int32_t)(screenType - o.screenType);\n    if (diff != 0) return diff;\n    diff = (int32_t)(input - o.input);\n    if (diff != 0) return diff;\n    diff = (int32_t)(screenSize - o.screenSize);\n    if (diff != 0) return diff;\n    diff = (int32_t)(version - o.version);\n    if (diff != 0) return diff;\n    diff = (int32_t)(screenLayout - o.screenLayout);\n    if (diff != 0) return diff;\n    diff = (int32_t)(uiMode - o.uiMode);\n    if (diff != 0) return diff;\n    diff = (int32_t)(smallestScreenWidthDp - o.smallestScreenWidthDp);\n    if (diff != 0) return diff;\n    diff = (int32_t)(screenSizeDp - o.screenSizeDp);\n    return (int)diff;\n}\n\nint ResTable_config::compareLogical(const ResTable_config& o) const {\n    if (mcc != o.mcc) {\n        return mcc < o.mcc ? -1 : 1;\n    }\n    if (mnc != o.mnc) {\n        return mnc < o.mnc ? -1 : 1;\n    }\n\n    int diff = compareLocales(*this, o);\n    if (diff < 0) {\n        return -1;\n    }\n    if (diff > 0) {\n        return 1;\n    }\n\n    if ((screenLayout & MASK_LAYOUTDIR) != (o.screenLayout & MASK_LAYOUTDIR)) {\n        return (screenLayout & MASK_LAYOUTDIR) < (o.screenLayout & MASK_LAYOUTDIR) ? -1 : 1;\n    }\n    if (smallestScreenWidthDp != o.smallestScreenWidthDp) {\n        return smallestScreenWidthDp < o.smallestScreenWidthDp ? -1 : 1;\n    }\n    if (screenWidthDp != o.screenWidthDp) {\n        return screenWidthDp < o.screenWidthDp ? -1 : 1;\n    }\n    if (screenHeightDp != o.screenHeightDp) {\n        return screenHeightDp < o.screenHeightDp ? -1 : 1;\n    }\n    if (screenWidth != o.screenWidth) {\n        return screenWidth < o.screenWidth ? -1 : 1;\n    }\n    if (screenHeight != o.screenHeight) {\n        return screenHeight < o.screenHeight ? -1 : 1;\n    }\n    if (density != o.density) {\n        return density < o.density ? -1 : 1;\n    }\n    if (orientation != o.orientation) {\n        return orientation < o.orientation ? -1 : 1;\n    }\n    if (touchscreen != o.touchscreen) {\n        return touchscreen < o.touchscreen ? -1 : 1;\n    }\n    if (input != o.input) {\n        return input < o.input ? -1 : 1;\n    }\n    if (screenLayout != o.screenLayout) {\n        return screenLayout < o.screenLayout ? -1 : 1;\n    }\n    if (uiMode != o.uiMode) {\n        return uiMode < o.uiMode ? -1 : 1;\n    }\n    if (version != o.version) {\n        return version < o.version ? -1 : 1;\n    }\n    return 0;\n}\n\nint ResTable_config::diff(const ResTable_config& o) const {\n    int diffs = 0;\n    if (mcc != o.mcc) diffs |= CONFIG_MCC;\n    if (mnc != o.mnc) diffs |= CONFIG_MNC;\n    if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION;\n    if (density != o.density) diffs |= CONFIG_DENSITY;\n    if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN;\n    if (((inputFlags^o.inputFlags)&(MASK_KEYSHIDDEN|MASK_NAVHIDDEN)) != 0)\n            diffs |= CONFIG_KEYBOARD_HIDDEN;\n    if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD;\n    if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;\n    if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;\n    if (version != o.version) diffs |= CONFIG_VERSION;\n    if ((screenLayout & MASK_LAYOUTDIR) != (o.screenLayout & MASK_LAYOUTDIR)) diffs |= CONFIG_LAYOUTDIR;\n    if ((screenLayout & ~MASK_LAYOUTDIR) != (o.screenLayout & ~MASK_LAYOUTDIR)) diffs |= CONFIG_SCREEN_LAYOUT;\n    if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE;\n    if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE;\n    if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE;\n\n    const int diff = compareLocales(*this, o);\n    if (diff) diffs |= CONFIG_LOCALE;\n\n    return diffs;\n}\n\nint ResTable_config::isLocaleMoreSpecificThan(const ResTable_config& o) const {\n    if (locale || o.locale) {\n        if (language[0] != o.language[0]) {\n            if (!language[0]) return -1;\n            if (!o.language[0]) return 1;\n        }\n\n        if (country[0] != o.country[0]) {\n            if (!country[0]) return -1;\n            if (!o.country[0]) return 1;\n        }\n    }\n\n    // There isn't a well specified \"importance\" order between variants and\n    // scripts. We can't easily tell whether, say \"en-Latn-US\" is more or less\n    // specific than \"en-US-POSIX\".\n    //\n    // We therefore arbitrarily decide to give priority to variants over\n    // scripts since it seems more useful to do so. We will consider\n    // \"en-US-POSIX\" to be more specific than \"en-Latn-US\".\n\n    const int score = ((localeScript[0] != 0) ? 1 : 0) +\n        ((localeVariant[0] != 0) ? 2 : 0);\n\n    const int oScore = ((o.localeScript[0] != 0) ? 1 : 0) +\n        ((o.localeVariant[0] != 0) ? 2 : 0);\n\n    return score - oScore;\n\n}\n\nbool ResTable_config::isMoreSpecificThan(const ResTable_config& o) const {\n    // The order of the following tests defines the importance of one\n    // configuration parameter over another.  Those tests first are more\n    // important, trumping any values in those following them.\n    if (imsi || o.imsi) {\n        if (mcc != o.mcc) {\n            if (!mcc) return false;\n            if (!o.mcc) return true;\n        }\n\n        if (mnc != o.mnc) {\n            if (!mnc) return false;\n            if (!o.mnc) return true;\n        }\n    }\n\n    if (locale || o.locale) {\n        const int diff = isLocaleMoreSpecificThan(o);\n        if (diff < 0) {\n            return false;\n        }\n\n        if (diff > 0) {\n            return true;\n        }\n    }\n\n    if (screenLayout || o.screenLayout) {\n        if (((screenLayout^o.screenLayout) & MASK_LAYOUTDIR) != 0) {\n            if (!(screenLayout & MASK_LAYOUTDIR)) return false;\n            if (!(o.screenLayout & MASK_LAYOUTDIR)) return true;\n        }\n    }\n\n    if (smallestScreenWidthDp || o.smallestScreenWidthDp) {\n        if (smallestScreenWidthDp != o.smallestScreenWidthDp) {\n            if (!smallestScreenWidthDp) return false;\n            if (!o.smallestScreenWidthDp) return true;\n        }\n    }\n\n    if (screenSizeDp || o.screenSizeDp) {\n        if (screenWidthDp != o.screenWidthDp) {\n            if (!screenWidthDp) return false;\n            if (!o.screenWidthDp) return true;\n        }\n\n        if (screenHeightDp != o.screenHeightDp) {\n            if (!screenHeightDp) return false;\n            if (!o.screenHeightDp) return true;\n        }\n    }\n\n    if (screenLayout || o.screenLayout) {\n        if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) {\n            if (!(screenLayout & MASK_SCREENSIZE)) return false;\n            if (!(o.screenLayout & MASK_SCREENSIZE)) return true;\n        }\n        if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) {\n            if (!(screenLayout & MASK_SCREENLONG)) return false;\n            if (!(o.screenLayout & MASK_SCREENLONG)) return true;\n        }\n    }\n\n    if (orientation != o.orientation) {\n        if (!orientation) return false;\n        if (!o.orientation) return true;\n    }\n\n    if (uiMode || o.uiMode) {\n        if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0) {\n            if (!(uiMode & MASK_UI_MODE_TYPE)) return false;\n            if (!(o.uiMode & MASK_UI_MODE_TYPE)) return true;\n        }\n        if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0) {\n            if (!(uiMode & MASK_UI_MODE_NIGHT)) return false;\n            if (!(o.uiMode & MASK_UI_MODE_NIGHT)) return true;\n        }\n    }\n\n    // density is never 'more specific'\n    // as the default just equals 160\n\n    if (touchscreen != o.touchscreen) {\n        if (!touchscreen) return false;\n        if (!o.touchscreen) return true;\n    }\n\n    if (input || o.input) {\n        if (((inputFlags^o.inputFlags) & MASK_KEYSHIDDEN) != 0) {\n            if (!(inputFlags & MASK_KEYSHIDDEN)) return false;\n            if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true;\n        }\n\n        if (((inputFlags^o.inputFlags) & MASK_NAVHIDDEN) != 0) {\n            if (!(inputFlags & MASK_NAVHIDDEN)) return false;\n            if (!(o.inputFlags & MASK_NAVHIDDEN)) return true;\n        }\n\n        if (keyboard != o.keyboard) {\n            if (!keyboard) return false;\n            if (!o.keyboard) return true;\n        }\n\n        if (navigation != o.navigation) {\n            if (!navigation) return false;\n            if (!o.navigation) return true;\n        }\n    }\n\n    if (screenSize || o.screenSize) {\n        if (screenWidth != o.screenWidth) {\n            if (!screenWidth) return false;\n            if (!o.screenWidth) return true;\n        }\n\n        if (screenHeight != o.screenHeight) {\n            if (!screenHeight) return false;\n            if (!o.screenHeight) return true;\n        }\n    }\n\n    if (version || o.version) {\n        if (sdkVersion != o.sdkVersion) {\n            if (!sdkVersion) return false;\n            if (!o.sdkVersion) return true;\n        }\n\n        if (minorVersion != o.minorVersion) {\n            if (!minorVersion) return false;\n            if (!o.minorVersion) return true;\n        }\n    }\n    return false;\n}\n\nbool ResTable_config::isBetterThan(const ResTable_config& o,\n        const ResTable_config* requested) const {\n    if (requested) {\n        if (imsi || o.imsi) {\n            if ((mcc != o.mcc) && requested->mcc) {\n                return (mcc);\n            }\n\n            if ((mnc != o.mnc) && requested->mnc) {\n                return (mnc);\n            }\n        }\n\n        if (locale || o.locale) {\n            if ((language[0] != o.language[0]) && requested->language[0]) {\n                return (language[0]);\n            }\n\n            if ((country[0] != o.country[0]) && requested->country[0]) {\n                return (country[0]);\n            }\n        }\n\n        if (localeScript[0] || o.localeScript[0]) {\n            if (localeScript[0] != o.localeScript[0] && requested->localeScript[0]) {\n                return localeScript[0];\n            }\n        }\n\n        if (localeVariant[0] || o.localeVariant[0]) {\n            if (localeVariant[0] != o.localeVariant[0] && requested->localeVariant[0]) {\n                return localeVariant[0];\n            }\n        }\n\n        if (screenLayout || o.screenLayout) {\n            if (((screenLayout^o.screenLayout) & MASK_LAYOUTDIR) != 0\n                    && (requested->screenLayout & MASK_LAYOUTDIR)) {\n                int myLayoutDir = screenLayout & MASK_LAYOUTDIR;\n                int oLayoutDir = o.screenLayout & MASK_LAYOUTDIR;\n                return (myLayoutDir > oLayoutDir);\n            }\n        }\n\n        if (smallestScreenWidthDp || o.smallestScreenWidthDp) {\n            // The configuration closest to the actual size is best.\n            // We assume that larger configs have already been filtered\n            // out at this point.  That means we just want the largest one.\n            if (smallestScreenWidthDp != o.smallestScreenWidthDp) {\n                return smallestScreenWidthDp > o.smallestScreenWidthDp;\n            }\n        }\n\n        if (screenSizeDp || o.screenSizeDp) {\n            // \"Better\" is based on the sum of the difference between both\n            // width and height from the requested dimensions.  We are\n            // assuming the invalid configs (with smaller dimens) have\n            // already been filtered.  Note that if a particular dimension\n            // is unspecified, we will end up with a large value (the\n            // difference between 0 and the requested dimension), which is\n            // good since we will prefer a config that has specified a\n            // dimension value.\n            int myDelta = 0, otherDelta = 0;\n            if (requested->screenWidthDp) {\n                myDelta += requested->screenWidthDp - screenWidthDp;\n                otherDelta += requested->screenWidthDp - o.screenWidthDp;\n            }\n            if (requested->screenHeightDp) {\n                myDelta += requested->screenHeightDp - screenHeightDp;\n                otherDelta += requested->screenHeightDp - o.screenHeightDp;\n            }\n            //ALOGI(\"Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d\",\n            //    screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,\n            //    requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);\n            if (myDelta != otherDelta) {\n                return myDelta < otherDelta;\n            }\n        }\n\n        if (screenLayout || o.screenLayout) {\n            if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0\n                    && (requested->screenLayout & MASK_SCREENSIZE)) {\n                // A little backwards compatibility here: undefined is\n                // considered equivalent to normal.  But only if the\n                // requested size is at least normal; otherwise, small\n                // is better than the default.\n                int mySL = (screenLayout & MASK_SCREENSIZE);\n                int oSL = (o.screenLayout & MASK_SCREENSIZE);\n                int fixedMySL = mySL;\n                int fixedOSL = oSL;\n                if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) {\n                    if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL;\n                    if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL;\n                }\n                // For screen size, the best match is the one that is\n                // closest to the requested screen size, but not over\n                // (the not over part is dealt with in match() below).\n                if (fixedMySL == fixedOSL) {\n                    // If the two are the same, but 'this' is actually\n                    // undefined, then the other is really a better match.\n                    if (mySL == 0) return false;\n                    return true;\n                }\n                if (fixedMySL != fixedOSL) {\n                    return fixedMySL > fixedOSL;\n                }\n            }\n            if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0\n                    && (requested->screenLayout & MASK_SCREENLONG)) {\n                return (screenLayout & MASK_SCREENLONG);\n            }\n        }\n\n        if ((orientation != o.orientation) && requested->orientation) {\n            return (orientation);\n        }\n\n        if (uiMode || o.uiMode) {\n            if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0\n                    && (requested->uiMode & MASK_UI_MODE_TYPE)) {\n                return (uiMode & MASK_UI_MODE_TYPE);\n            }\n            if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0\n                    && (requested->uiMode & MASK_UI_MODE_NIGHT)) {\n                return (uiMode & MASK_UI_MODE_NIGHT);\n            }\n        }\n\n        if (screenType || o.screenType) {\n            if (density != o.density) {\n                // Use the system default density (DENSITY_MEDIUM, 160dpi) if none specified.\n                const int thisDensity = density ? density : int(ResTable_config::DENSITY_MEDIUM);\n                const int otherDensity = o.density ? o.density : int(ResTable_config::DENSITY_MEDIUM);\n\n                // We always prefer DENSITY_ANY over scaling a density bucket.\n                if (thisDensity == ResTable_config::DENSITY_ANY) {\n                    return true;\n                } else if (otherDensity == ResTable_config::DENSITY_ANY) {\n                    return false;\n                }\n\n                int requestedDensity = requested->density;\n                if (requested->density == 0 ||\n                        requested->density == ResTable_config::DENSITY_ANY) {\n                    requestedDensity = ResTable_config::DENSITY_MEDIUM;\n                }\n\n                // DENSITY_ANY is now dealt with. We should look to\n                // pick a density bucket and potentially scale it.\n                // Any density is potentially useful\n                // because the system will scale it.  Scaling down\n                // is generally better than scaling up.\n                int h = thisDensity;\n                int l = otherDensity;\n                bool bImBigger = true;\n                if (l > h) {\n                    int t = h;\n                    h = l;\n                    l = t;\n                    bImBigger = false;\n                }\n\n                if (requestedDensity >= h) {\n                    // requested value higher than both l and h, give h\n                    return bImBigger;\n                }\n                if (l >= requestedDensity) {\n                    // requested value lower than both l and h, give l\n                    return !bImBigger;\n                }\n                // saying that scaling down is 2x better than up\n                if (((2 * l) - requestedDensity) * h > requestedDensity * requestedDensity) {\n                    return !bImBigger;\n                } else {\n                    return bImBigger;\n                }\n            }\n\n            if ((touchscreen != o.touchscreen) && requested->touchscreen) {\n                return (touchscreen);\n            }\n        }\n\n        if (input || o.input) {\n            const int keysHidden = inputFlags & MASK_KEYSHIDDEN;\n            const int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN;\n            if (keysHidden != oKeysHidden) {\n                const int reqKeysHidden =\n                        requested->inputFlags & MASK_KEYSHIDDEN;\n                if (reqKeysHidden) {\n\n                    if (!keysHidden) return false;\n                    if (!oKeysHidden) return true;\n                    // For compatibility, we count KEYSHIDDEN_NO as being\n                    // the same as KEYSHIDDEN_SOFT.  Here we disambiguate\n                    // these by making an exact match more specific.\n                    if (reqKeysHidden == keysHidden) return true;\n                    if (reqKeysHidden == oKeysHidden) return false;\n                }\n            }\n\n            const int navHidden = inputFlags & MASK_NAVHIDDEN;\n            const int oNavHidden = o.inputFlags & MASK_NAVHIDDEN;\n            if (navHidden != oNavHidden) {\n                const int reqNavHidden =\n                        requested->inputFlags & MASK_NAVHIDDEN;\n                if (reqNavHidden) {\n\n                    if (!navHidden) return false;\n                    if (!oNavHidden) return true;\n                }\n            }\n\n            if ((keyboard != o.keyboard) && requested->keyboard) {\n                return (keyboard);\n            }\n\n            if ((navigation != o.navigation) && requested->navigation) {\n                return (navigation);\n            }\n        }\n\n        if (screenSize || o.screenSize) {\n            // \"Better\" is based on the sum of the difference between both\n            // width and height from the requested dimensions.  We are\n            // assuming the invalid configs (with smaller sizes) have\n            // already been filtered.  Note that if a particular dimension\n            // is unspecified, we will end up with a large value (the\n            // difference between 0 and the requested dimension), which is\n            // good since we will prefer a config that has specified a\n            // size value.\n            int myDelta = 0, otherDelta = 0;\n            if (requested->screenWidth) {\n                myDelta += requested->screenWidth - screenWidth;\n                otherDelta += requested->screenWidth - o.screenWidth;\n            }\n            if (requested->screenHeight) {\n                myDelta += requested->screenHeight - screenHeight;\n                otherDelta += requested->screenHeight - o.screenHeight;\n            }\n            if (myDelta != otherDelta) {\n                return myDelta < otherDelta;\n            }\n        }\n\n        if (version || o.version) {\n            if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {\n                return (sdkVersion > o.sdkVersion);\n            }\n\n            if ((minorVersion != o.minorVersion) &&\n                    requested->minorVersion) {\n                return (minorVersion);\n            }\n        }\n\n        return false;\n    }\n    return isMoreSpecificThan(o);\n}\n\nbool ResTable_config::match(const ResTable_config& settings) const {\n    if (imsi != 0) {\n        if (mcc != 0 && mcc != settings.mcc) {\n            return false;\n        }\n        if (mnc != 0 && mnc != settings.mnc) {\n            return false;\n        }\n    }\n    if (locale != 0) {\n        // Don't consider the script & variants when deciding matches.\n        //\n        // If we two configs differ only in their script or language, they\n        // can be weeded out in the isMoreSpecificThan test.\n        if (language[0] != 0\n            && (language[0] != settings.language[0]\n                || language[1] != settings.language[1])) {\n            return false;\n        }\n\n        if (country[0] != 0\n            && (country[0] != settings.country[0]\n                || country[1] != settings.country[1])) {\n            return false;\n        }\n    }\n\n    if (screenConfig != 0) {\n        const int layoutDir = screenLayout&MASK_LAYOUTDIR;\n        const int setLayoutDir = settings.screenLayout&MASK_LAYOUTDIR;\n        if (layoutDir != 0 && layoutDir != setLayoutDir) {\n            return false;\n        }\n\n        const int screenSize = screenLayout&MASK_SCREENSIZE;\n        const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;\n        // Any screen sizes for larger screens than the setting do not\n        // match.\n        if (screenSize != 0 && screenSize > setScreenSize) {\n            return false;\n        }\n\n        const int screenLong = screenLayout&MASK_SCREENLONG;\n        const int setScreenLong = settings.screenLayout&MASK_SCREENLONG;\n        if (screenLong != 0 && screenLong != setScreenLong) {\n            return false;\n        }\n\n        const int uiModeType = uiMode&MASK_UI_MODE_TYPE;\n        const int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE;\n        if (uiModeType != 0 && uiModeType != setUiModeType) {\n            return false;\n        }\n\n        const int uiModeNight = uiMode&MASK_UI_MODE_NIGHT;\n        const int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT;\n        if (uiModeNight != 0 && uiModeNight != setUiModeNight) {\n            return false;\n        }\n\n        if (smallestScreenWidthDp != 0\n                && smallestScreenWidthDp > settings.smallestScreenWidthDp) {\n            return false;\n        }\n    }\n    if (screenSizeDp != 0) {\n        if (screenWidthDp != 0 && screenWidthDp > settings.screenWidthDp) {\n            //ALOGI(\"Filtering out width %d in requested %d\", screenWidthDp, settings.screenWidthDp);\n            return false;\n        }\n        if (screenHeightDp != 0 && screenHeightDp > settings.screenHeightDp) {\n            //ALOGI(\"Filtering out height %d in requested %d\", screenHeightDp, settings.screenHeightDp);\n            return false;\n        }\n    }\n    if (screenType != 0) {\n        if (orientation != 0 && orientation != settings.orientation) {\n            return false;\n        }\n        // density always matches - we can scale it.  See isBetterThan\n        if (touchscreen != 0 && touchscreen != settings.touchscreen) {\n            return false;\n        }\n    }\n    if (input != 0) {\n        const int keysHidden = inputFlags&MASK_KEYSHIDDEN;\n        const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;\n        if (keysHidden != 0 && keysHidden != setKeysHidden) {\n            // For compatibility, we count a request for KEYSHIDDEN_NO as also\n            // matching the more recent KEYSHIDDEN_SOFT.  Basically\n            // KEYSHIDDEN_NO means there is some kind of keyboard available.\n            //ALOGI(\"Matching keysHidden: have=%d, config=%d\\n\", keysHidden, setKeysHidden);\n            if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) {\n                //ALOGI(\"No match!\");\n                return false;\n            }\n        }\n        const int navHidden = inputFlags&MASK_NAVHIDDEN;\n        const int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN;\n        if (navHidden != 0 && navHidden != setNavHidden) {\n            return false;\n        }\n        if (keyboard != 0 && keyboard != settings.keyboard) {\n            return false;\n        }\n        if (navigation != 0 && navigation != settings.navigation) {\n            return false;\n        }\n    }\n    if (screenSize != 0) {\n        if (screenWidth != 0 && screenWidth > settings.screenWidth) {\n            return false;\n        }\n        if (screenHeight != 0 && screenHeight > settings.screenHeight) {\n            return false;\n        }\n    }\n    if (version != 0) {\n        if (sdkVersion != 0 && sdkVersion > settings.sdkVersion) {\n            return false;\n        }\n        if (minorVersion != 0 && minorVersion != settings.minorVersion) {\n            return false;\n        }\n    }\n    return true;\n}\n\nvoid ResTable_config::getBcp47Locale(char str[RESTABLE_MAX_LOCALE_LEN]) const {\n    memset(str, 0, RESTABLE_MAX_LOCALE_LEN);\n\n    // This represents the \"any\" locale value, which has traditionally been\n    // represented by the empty string.\n    if (!language[0] && !country[0]) {\n        return;\n    }\n\n    size_t charsWritten = 0;\n    if (language[0]) {\n        charsWritten += unpackLanguage(str);\n    }\n\n    if (localeScript[0]) {\n        if (charsWritten) {\n            str[charsWritten++] = '-';\n        }\n        memcpy(str + charsWritten, localeScript, sizeof(localeScript));\n        charsWritten += sizeof(localeScript);\n    }\n\n    if (country[0]) {\n        if (charsWritten) {\n            str[charsWritten++] = '-';\n        }\n        charsWritten += unpackRegion(str + charsWritten);\n    }\n\n    if (localeVariant[0]) {\n        if (charsWritten) {\n            str[charsWritten++] = '-';\n        }\n        memcpy(str + charsWritten, localeVariant, sizeof(localeVariant));\n    }\n}\n\n/* static */ inline bool assignLocaleComponent(ResTable_config* config,\n        const char* start, size_t size) {\n\n  switch (size) {\n       case 0:\n           return false;\n       case 2:\n       case 3:\n           config->language[0] ? config->packRegion(start) : config->packLanguage(start);\n           break;\n       case 4:\n           config->localeScript[0] = toupper(start[0]);\n           for (size_t i = 1; i < 4; ++i) {\n               config->localeScript[i] = tolower(start[i]);\n           }\n           break;\n       case 5:\n       case 6:\n       case 7:\n       case 8:\n           for (size_t i = 0; i < size; ++i) {\n               config->localeVariant[i] = tolower(start[i]);\n           }\n           break;\n       default:\n           return false;\n  }\n\n  return true;\n}\n\nvoid ResTable_config::setBcp47Locale(const char* in) {\n    locale = 0;\n    memset(localeScript, 0, sizeof(localeScript));\n    memset(localeVariant, 0, sizeof(localeVariant));\n\n    const char* separator = in;\n    const char* start = in;\n    while ((separator = strchr(start, '-')) != NULL) {\n        const size_t size = separator - start;\n        if (!assignLocaleComponent(this, start, size)) {\n            fprintf(stderr, \"Invalid BCP-47 locale string: %s\", in);\n        }\n\n        start = (separator + 1);\n    }\n\n    const size_t size = in + strlen(in) - start;\n    assignLocaleComponent(this, start, size);\n}\n\nString8 ResTable_config::toString() const {\n    String8 res;\n\n    if (mcc != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.appendFormat(\"mcc%d\", dtohs(mcc));\n    }\n    if (mnc != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.appendFormat(\"mnc%d\", dtohs(mnc));\n    }\n\n    char localeStr[RESTABLE_MAX_LOCALE_LEN];\n    getBcp47Locale(localeStr);\n    if (strlen(localeStr) > 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.append(localeStr);\n    }\n\n    if ((screenLayout&MASK_LAYOUTDIR) != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (screenLayout&ResTable_config::MASK_LAYOUTDIR) {\n            case ResTable_config::LAYOUTDIR_LTR:\n                res.append(\"ldltr\");\n                break;\n            case ResTable_config::LAYOUTDIR_RTL:\n                res.append(\"ldrtl\");\n                break;\n            default:\n                res.appendFormat(\"layoutDir=%d\",\n                        dtohs(screenLayout&ResTable_config::MASK_LAYOUTDIR));\n                break;\n        }\n    }\n    if (smallestScreenWidthDp != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.appendFormat(\"sw%ddp\", dtohs(smallestScreenWidthDp));\n    }\n    if (screenWidthDp != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.appendFormat(\"w%ddp\", dtohs(screenWidthDp));\n    }\n    if (screenHeightDp != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.appendFormat(\"h%ddp\", dtohs(screenHeightDp));\n    }\n    if ((screenLayout&MASK_SCREENSIZE) != SCREENSIZE_ANY) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (screenLayout&ResTable_config::MASK_SCREENSIZE) {\n            case ResTable_config::SCREENSIZE_SMALL:\n                res.append(\"small\");\n                break;\n            case ResTable_config::SCREENSIZE_NORMAL:\n                res.append(\"normal\");\n                break;\n            case ResTable_config::SCREENSIZE_LARGE:\n                res.append(\"large\");\n                break;\n            case ResTable_config::SCREENSIZE_XLARGE:\n                res.append(\"xlarge\");\n                break;\n            default:\n                res.appendFormat(\"screenLayoutSize=%d\",\n                        dtohs(screenLayout&ResTable_config::MASK_SCREENSIZE));\n                break;\n        }\n    }\n    if ((screenLayout&MASK_SCREENLONG) != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (screenLayout&ResTable_config::MASK_SCREENLONG) {\n            case ResTable_config::SCREENLONG_NO:\n                res.append(\"notlong\");\n                break;\n            case ResTable_config::SCREENLONG_YES:\n                res.append(\"long\");\n                break;\n            default:\n                res.appendFormat(\"screenLayoutLong=%d\",\n                        dtohs(screenLayout&ResTable_config::MASK_SCREENLONG));\n                break;\n        }\n    }\n    if (orientation != ORIENTATION_ANY) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (orientation) {\n            case ResTable_config::ORIENTATION_PORT:\n                res.append(\"port\");\n                break;\n            case ResTable_config::ORIENTATION_LAND:\n                res.append(\"land\");\n                break;\n            case ResTable_config::ORIENTATION_SQUARE:\n                res.append(\"square\");\n                break;\n            default:\n                res.appendFormat(\"orientation=%d\", dtohs(orientation));\n                break;\n        }\n    }\n    if ((uiMode&MASK_UI_MODE_TYPE) != UI_MODE_TYPE_ANY) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (uiMode&ResTable_config::MASK_UI_MODE_TYPE) {\n            case ResTable_config::UI_MODE_TYPE_DESK:\n                res.append(\"desk\");\n                break;\n            case ResTable_config::UI_MODE_TYPE_CAR:\n                res.append(\"car\");\n                break;\n            case ResTable_config::UI_MODE_TYPE_TELEVISION:\n                res.append(\"television\");\n                break;\n            case ResTable_config::UI_MODE_TYPE_APPLIANCE:\n                res.append(\"appliance\");\n                break;\n            case ResTable_config::UI_MODE_TYPE_WATCH:\n                res.append(\"watch\");\n                break;\n            default:\n                res.appendFormat(\"uiModeType=%d\",\n                        dtohs(screenLayout&ResTable_config::MASK_UI_MODE_TYPE));\n                break;\n        }\n    }\n    if ((uiMode&MASK_UI_MODE_NIGHT) != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (uiMode&ResTable_config::MASK_UI_MODE_NIGHT) {\n            case ResTable_config::UI_MODE_NIGHT_NO:\n                res.append(\"notnight\");\n                break;\n            case ResTable_config::UI_MODE_NIGHT_YES:\n                res.append(\"night\");\n                break;\n            default:\n                res.appendFormat(\"uiModeNight=%d\",\n                        dtohs(uiMode&MASK_UI_MODE_NIGHT));\n                break;\n        }\n    }\n    if (density != DENSITY_DEFAULT) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (density) {\n            case ResTable_config::DENSITY_LOW:\n                res.append(\"ldpi\");\n                break;\n            case ResTable_config::DENSITY_MEDIUM:\n                res.append(\"mdpi\");\n                break;\n            case ResTable_config::DENSITY_TV:\n                res.append(\"tvdpi\");\n                break;\n            case ResTable_config::DENSITY_HIGH:\n                res.append(\"hdpi\");\n                break;\n            case ResTable_config::DENSITY_XHIGH:\n                res.append(\"xhdpi\");\n                break;\n            case ResTable_config::DENSITY_XXHIGH:\n                res.append(\"xxhdpi\");\n                break;\n            case ResTable_config::DENSITY_XXXHIGH:\n                res.append(\"xxxhdpi\");\n                break;\n            case ResTable_config::DENSITY_NONE:\n                res.append(\"nodpi\");\n                break;\n            case ResTable_config::DENSITY_ANY:\n                res.append(\"anydpi\");\n                break;\n            default:\n                res.appendFormat(\"%ddpi\", dtohs(density));\n                break;\n        }\n    }\n    if (touchscreen != TOUCHSCREEN_ANY) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (touchscreen) {\n            case ResTable_config::TOUCHSCREEN_NOTOUCH:\n                res.append(\"notouch\");\n                break;\n            case ResTable_config::TOUCHSCREEN_FINGER:\n                res.append(\"finger\");\n                break;\n            case ResTable_config::TOUCHSCREEN_STYLUS:\n                res.append(\"stylus\");\n                break;\n            default:\n                res.appendFormat(\"touchscreen=%d\", dtohs(touchscreen));\n                break;\n        }\n    }\n    if ((inputFlags&MASK_KEYSHIDDEN) != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (inputFlags&MASK_KEYSHIDDEN) {\n            case ResTable_config::KEYSHIDDEN_NO:\n                res.append(\"keysexposed\");\n                break;\n            case ResTable_config::KEYSHIDDEN_YES:\n                res.append(\"keyshidden\");\n                break;\n            case ResTable_config::KEYSHIDDEN_SOFT:\n                res.append(\"keyssoft\");\n                break;\n        }\n    }\n    if (keyboard != KEYBOARD_ANY) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (keyboard) {\n            case ResTable_config::KEYBOARD_NOKEYS:\n                res.append(\"nokeys\");\n                break;\n            case ResTable_config::KEYBOARD_QWERTY:\n                res.append(\"qwerty\");\n                break;\n            case ResTable_config::KEYBOARD_12KEY:\n                res.append(\"12key\");\n                break;\n            default:\n                res.appendFormat(\"keyboard=%d\", dtohs(keyboard));\n                break;\n        }\n    }\n    if ((inputFlags&MASK_NAVHIDDEN) != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (inputFlags&MASK_NAVHIDDEN) {\n            case ResTable_config::NAVHIDDEN_NO:\n                res.append(\"navexposed\");\n                break;\n            case ResTable_config::NAVHIDDEN_YES:\n                res.append(\"navhidden\");\n                break;\n            default:\n                res.appendFormat(\"inputFlagsNavHidden=%d\",\n                        dtohs(inputFlags&MASK_NAVHIDDEN));\n                break;\n        }\n    }\n    if (navigation != NAVIGATION_ANY) {\n        if (res.size() > 0) res.append(\"-\");\n        switch (navigation) {\n            case ResTable_config::NAVIGATION_NONAV:\n                res.append(\"nonav\");\n                break;\n            case ResTable_config::NAVIGATION_DPAD:\n                res.append(\"dpad\");\n                break;\n            case ResTable_config::NAVIGATION_TRACKBALL:\n                res.append(\"trackball\");\n                break;\n            case ResTable_config::NAVIGATION_WHEEL:\n                res.append(\"wheel\");\n                break;\n            default:\n                res.appendFormat(\"navigation=%d\", dtohs(navigation));\n                break;\n        }\n    }\n    if (screenSize != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.appendFormat(\"%dx%d\", dtohs(screenWidth), dtohs(screenHeight));\n    }\n    if (version != 0) {\n        if (res.size() > 0) res.append(\"-\");\n        res.appendFormat(\"v%d\", dtohs(sdkVersion));\n        if (minorVersion != 0) {\n            res.appendFormat(\".%d\", dtohs(minorVersion));\n        }\n    }\n\n    return res;\n}\n\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n// --------------------------------------------------------------------\n\nstruct ResTable::Header\n{\n    Header(ResTable* _owner) : owner(_owner), ownedData(NULL), header(NULL),\n        resourceIDMap(NULL), resourceIDMapSize(0) { }\n\n    ~Header()\n    {\n        free(resourceIDMap);\n    }\n\n    const ResTable* const           owner;\n    void*                           ownedData;\n    const ResTable_header*          header;\n    size_t                          size;\n    const uint8_t*                  dataEnd;\n    size_t                          index;\n    int32_t                         cookie;\n\n    ResStringPool                   values;\n    uint32_t*                       resourceIDMap;\n    size_t                          resourceIDMapSize;\n};\n\nstruct ResTable::Entry {\n    ResTable_config config;\n    const ResTable_entry* entry;\n    const ResTable_type* type;\n    uint32_t specFlags;\n    const Package* package;\n\n    StringPoolRef typeStr;\n    StringPoolRef keyStr;\n};\n\nstruct ResTable::Type\n{\n    Type(const Header* _header, const Package* _package, size_t count)\n        : header(_header), package(_package), entryCount(count),\n          typeSpec(NULL), typeSpecFlags(NULL) { }\n    const Header* const             header;\n    const Package* const            package;\n    const size_t                    entryCount;\n    const ResTable_typeSpec*        typeSpec;\n    const uint32_t*                 typeSpecFlags;\n    IdmapEntries                    idmapEntries;\n    Vector<const ResTable_type*>    configs;\n};\n\nstruct ResTable::Package\n{\n    Package(ResTable* _owner, const Header* _header, const ResTable_package* _package)\n        : owner(_owner), header(_header), package(_package), typeIdOffset(0) {\n        if (dtohs(package->header.headerSize) == sizeof(package)) {\n            // The package structure is the same size as the definition.\n            // This means it contains the typeIdOffset field.\n            typeIdOffset = package->typeIdOffset;\n        }\n    }\n\n    const ResTable* const           owner;\n    const Header* const             header;\n    const ResTable_package* const   package;\n\n    ResStringPool                   typeStrings;\n    ResStringPool                   keyStrings;\n\n    size_t                          typeIdOffset;\n};\n\n// A group of objects describing a particular resource package.\n// The first in 'package' is always the root object (from the resource\n// table that defined the package); the ones after are skins on top of it.\nstruct ResTable::PackageGroup\n{\n    PackageGroup(ResTable* _owner, const String16& _name, uint32_t _id)\n        : owner(_owner)\n        , name(_name)\n        , id(_id)\n        , largestTypeId(0)\n        , bags(NULL)\n        , dynamicRefTable(static_cast<uint8_t>(_id))\n    { }\n\n    ~PackageGroup() {\n        clearBagCache();\n        const size_t numTypes = types.size();\n        for (size_t i = 0; i < numTypes; i++) {\n            const TypeList& typeList = types[i];\n            const size_t numInnerTypes = typeList.size();\n            for (size_t j = 0; j < numInnerTypes; j++) {\n                if (typeList[j]->package->owner == owner) {\n                    delete typeList[j];\n                }\n            }\n        }\n\n        const size_t N = packages.size();\n        for (size_t i=0; i<N; i++) {\n            Package* pkg = packages[i];\n            if (pkg->owner == owner) {\n                delete pkg;\n            }\n        }\n    }\n\n    void clearBagCache() {\n        if (bags) {\n            TABLE_NOISY(printf(\"bags=%p\\n\", bags));\n            for (size_t i = 0; i < bags->size(); i++) {\n                TABLE_NOISY(printf(\"type=%d\\n\", i));\n                const TypeList& typeList = types[i];\n                if (!typeList.isEmpty()) {\n                    bag_set** typeBags = bags->get(i);\n                    TABLE_NOISY(printf(\"typeBags=%p\\n\", typeBags));\n                    if (typeBags) {\n                        const size_t N = typeList[0]->entryCount;\n                        TABLE_NOISY(printf(\"type->entryCount=%x\\n\", N));\n                        for (size_t j=0; j<N; j++) {\n                            if (typeBags[j] && typeBags[j] != (bag_set*)0xFFFFFFFF)\n                                free(typeBags[j]);\n                        }\n                        free(typeBags);\n                    }\n                }\n            }\n            delete bags;\n            bags = NULL;\n        }\n    }\n\n    ssize_t findType16(const char16_t* type, size_t len) const {\n        const size_t N = packages.size();\n        for (size_t i = 0; i < N; i++) {\n            ssize_t index = packages[i]->typeStrings.indexOfString(type, len);\n            if (index >= 0) {\n                return index + packages[i]->typeIdOffset;\n            }\n        }\n        return -1;\n    }\n\n    const ResTable* const           owner;\n    String16 const                  name;\n    uint32_t const                  id;\n\n    // This is mainly used to keep track of the loaded packages\n    // and to clean them up properly. Accessing resources happens from\n    // the 'types' array.\n    Vector<Package*>                packages;\n\n    ByteBucketArray<TypeList>       types;\n\n    uint8_t                         largestTypeId;\n\n    // Computed attribute bags, first indexed by the type and second\n    // by the entry in that type.\n    ByteBucketArray<bag_set**>*     bags;\n\n    // The table mapping dynamic references to resolved references for\n    // this package group.\n    // TODO: We may be able to support dynamic references in overlays\n    // by having these tables in a per-package scope rather than\n    // per-package-group.\n    DynamicRefTable                 dynamicRefTable;\n};\n\nstruct ResTable::bag_set\n{\n    size_t numAttrs;    // number in array\n    size_t availAttrs;  // total space in array\n    uint32_t typeSpecFlags;\n    // Followed by 'numAttr' bag_entry structures.\n};\n\nResTable::Theme::Theme(const ResTable& table)\n    : mTable(table)\n{\n    memset(mPackages, 0, sizeof(mPackages));\n}\n\nResTable::Theme::~Theme()\n{\n    for (size_t i=0; i<Res_MAXPACKAGE; i++) {\n        package_info* pi = mPackages[i];\n        if (pi != NULL) {\n            free_package(pi);\n        }\n    }\n}\n\nvoid ResTable::Theme::free_package(package_info* pi)\n{\n    for (size_t j = 0; j <= Res_MAXTYPE; j++) {\n        theme_entry* te = pi->types[j].entries;\n        if (te != NULL) {\n            free(te);\n        }\n    }\n    free(pi);\n}\n\nResTable::Theme::package_info* ResTable::Theme::copy_package(package_info* pi)\n{\n    package_info* newpi = (package_info*)malloc(sizeof(package_info));\n    for (size_t j = 0; j <= Res_MAXTYPE; j++) {\n        size_t cnt = pi->types[j].numEntries;\n        newpi->types[j].numEntries = cnt;\n        theme_entry* te = pi->types[j].entries;\n        if (te != NULL) {\n            theme_entry* newte = (theme_entry*)malloc(cnt*sizeof(theme_entry));\n            newpi->types[j].entries = newte;\n            memcpy(newte, te, cnt*sizeof(theme_entry));\n        } else {\n            newpi->types[j].entries = NULL;\n        }\n    }\n    return newpi;\n}\n\nstatus_t ResTable::Theme::applyStyle(uint32_t resID, bool force)\n{\n    const bag_entry* bag;\n    uint32_t bagTypeSpecFlags = 0;\n    mTable.lock();\n    const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags);\n    TABLE_NOISY(ALOGV(\"Applying style 0x%08x to theme %p, count=%d\", resID, this, N));\n    if (N < 0) {\n        mTable.unlock();\n        return N;\n    }\n\n    uint32_t curPackage = 0xffffffff;\n    ssize_t curPackageIndex = 0;\n    package_info* curPI = NULL;\n    uint32_t curType = 0xffffffff;\n    size_t numEntries = 0;\n    theme_entry* curEntries = NULL;\n\n    const bag_entry* end = bag + N;\n    while (bag < end) {\n        const uint32_t attrRes = bag->map.name.ident;\n        const uint32_t p = Res_GETPACKAGE(attrRes);\n        const uint32_t t = Res_GETTYPE(attrRes);\n        const uint32_t e = Res_GETENTRY(attrRes);\n\n        if (curPackage != p) {\n            const ssize_t pidx = mTable.getResourcePackageIndex(attrRes);\n            if (pidx < 0) {\n                ALOGE(\"Style contains key with bad package: 0x%08x\\n\", attrRes);\n                bag++;\n                continue;\n            }\n            curPackage = p;\n            curPackageIndex = pidx;\n            curPI = mPackages[pidx];\n            if (curPI == NULL) {\n                PackageGroup* const grp = mTable.mPackageGroups[pidx];\n                curPI = (package_info*)malloc(sizeof(package_info));\n                memset(curPI, 0, sizeof(*curPI));\n                mPackages[pidx] = curPI;\n            }\n            curType = 0xffffffff;\n        }\n        if (curType != t) {\n            if (t > Res_MAXTYPE) {\n                ALOGE(\"Style contains key with bad type: 0x%08x\\n\", attrRes);\n                bag++;\n                continue;\n            }\n            curType = t;\n            curEntries = curPI->types[t].entries;\n            if (curEntries == NULL) {\n                PackageGroup* const grp = mTable.mPackageGroups[curPackageIndex];\n                const TypeList& typeList = grp->types[t];\n                int cnt = typeList.isEmpty() ? 0 : typeList[0]->entryCount;\n                curEntries = (theme_entry*)malloc(cnt*sizeof(theme_entry));\n                memset(curEntries, Res_value::TYPE_NULL, cnt*sizeof(theme_entry));\n                curPI->types[t].numEntries = cnt;\n                curPI->types[t].entries = curEntries;\n            }\n            numEntries = curPI->types[t].numEntries;\n        }\n        if (e >= numEntries) {\n            ALOGE(\"Style contains key with bad entry: 0x%08x\\n\", attrRes);\n            bag++;\n            continue;\n        }\n        theme_entry* curEntry = curEntries + e;\n        TABLE_NOISY(ALOGV(\"Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x\",\n                attrRes, bag->map.value.dataType, bag->map.value.data,\n                curEntry->value.dataType));\n        if (force || curEntry->value.dataType == Res_value::TYPE_NULL) {\n            curEntry->stringBlock = bag->stringBlock;\n            curEntry->typeSpecFlags |= bagTypeSpecFlags;\n            curEntry->value = bag->map.value;\n        }\n\n        bag++;\n    }\n\n    mTable.unlock();\n\n    //ALOGI(\"Applying style 0x%08x (force=%d)  theme %p...\\n\", resID, force, this);\n    //dumpToLog();\n\n    return NO_ERROR;\n}\n\nstatus_t ResTable::Theme::setTo(const Theme& other)\n{\n    //ALOGI(\"Setting theme %p from theme %p...\\n\", this, &other);\n    //dumpToLog();\n    //other.dumpToLog();\n\n    if (&mTable == &other.mTable) {\n        for (size_t i=0; i<Res_MAXPACKAGE; i++) {\n            if (mPackages[i] != NULL) {\n                free_package(mPackages[i]);\n            }\n            if (other.mPackages[i] != NULL) {\n                mPackages[i] = copy_package(other.mPackages[i]);\n            } else {\n                mPackages[i] = NULL;\n            }\n        }\n    } else {\n        // @todo: need to really implement this, not just copy\n        // the system package (which is still wrong because it isn't\n        // fixing up resource references).\n        for (size_t i=0; i<Res_MAXPACKAGE; i++) {\n            if (mPackages[i] != NULL) {\n                free_package(mPackages[i]);\n            }\n            if (i == 0 && other.mPackages[i] != NULL) {\n                mPackages[i] = copy_package(other.mPackages[i]);\n            } else {\n                mPackages[i] = NULL;\n            }\n        }\n    }\n\n    //ALOGI(\"Final theme:\");\n    //dumpToLog();\n\n    return NO_ERROR;\n}\n\nssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue,\n        uint32_t* outTypeSpecFlags) const\n{\n    int cnt = 20;\n\n    if (outTypeSpecFlags != NULL) *outTypeSpecFlags = 0;\n\n    do {\n        const ssize_t p = mTable.getResourcePackageIndex(resID);\n        const uint32_t t = Res_GETTYPE(resID);\n        const uint32_t e = Res_GETENTRY(resID);\n\n        TABLE_THEME(ALOGI(\"Looking up attr 0x%08x in theme %p\", resID, this));\n\n        if (p >= 0) {\n            const package_info* const pi = mPackages[p];\n            TABLE_THEME(ALOGI(\"Found package: %p\", pi));\n            if (pi != NULL) {\n                TABLE_THEME(ALOGI(\"Desired type index is %ld in avail %d\", t, Res_MAXTYPE + 1));\n                if (t <= Res_MAXTYPE) {\n                    const type_info& ti = pi->types[t];\n                    TABLE_THEME(ALOGI(\"Desired entry index is %ld in avail %d\", e, ti.numEntries));\n                    if (e < ti.numEntries) {\n                        const theme_entry& te = ti.entries[e];\n                        if (outTypeSpecFlags != NULL) {\n                            *outTypeSpecFlags |= te.typeSpecFlags;\n                        }\n                        TABLE_THEME(ALOGI(\"Theme value: type=0x%x, data=0x%08x\",\n                                te.value.dataType, te.value.data));\n                        const uint8_t type = te.value.dataType;\n                        if (type == Res_value::TYPE_ATTRIBUTE) {\n                            if (cnt > 0) {\n                                cnt--;\n                                resID = te.value.data;\n                                continue;\n                            }\n                            ALOGW(\"Too many attribute references, stopped at: 0x%08x\\n\", resID);\n                            return BAD_INDEX;\n                        } else if (type != Res_value::TYPE_NULL) {\n                            *outValue = te.value;\n                            return te.stringBlock;\n                        }\n                        return BAD_INDEX;\n                    }\n                }\n            }\n        }\n        break;\n\n    } while (true);\n\n    return BAD_INDEX;\n}\n\nssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue,\n        ssize_t blockIndex, uint32_t* outLastRef,\n        uint32_t* inoutTypeSpecFlags, ResTable_config* inoutConfig) const\n{\n    //printf(\"Resolving type=0x%x\\n\", inOutValue->dataType);\n    if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {\n        uint32_t newTypeSpecFlags;\n        blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags);\n        TABLE_THEME(ALOGI(\"Resolving attr reference: blockIndex=%d, type=0x%x, data=%p\\n\",\n             (int)blockIndex, (int)inOutValue->dataType, (void*)inOutValue->data));\n        if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags;\n        //printf(\"Retrieved attribute new type=0x%x\\n\", inOutValue->dataType);\n        if (blockIndex < 0) {\n            return blockIndex;\n        }\n    }\n    return mTable.resolveReference(inOutValue, blockIndex, outLastRef,\n            inoutTypeSpecFlags, inoutConfig);\n}\n\nvoid ResTable::Theme::dumpToLog() const\n{\n    ALOGI(\"Theme %p:\\n\", this);\n    for (size_t i=0; i<Res_MAXPACKAGE; i++) {\n        package_info* pi = mPackages[i];\n        if (pi == NULL) continue;\n\n        ALOGI(\"  Package #0x%02x:\\n\", (int)(i + 1));\n        for (size_t j = 0; j <= Res_MAXTYPE; j++) {\n            type_info& ti = pi->types[j];\n            if (ti.numEntries == 0) continue;\n            ALOGI(\"    Type #0x%02x:\\n\", (int)(j + 1));\n            for (size_t k = 0; k < ti.numEntries; k++) {\n                const theme_entry& te = ti.entries[k];\n                if (te.value.dataType == Res_value::TYPE_NULL) continue;\n                ALOGI(\"      0x%08x: t=0x%x, d=0x%08x (block=%d)\\n\",\n                     (int)Res_MAKEID(i, j, k),\n                     te.value.dataType, (int)te.value.data, (int)te.stringBlock);\n            }\n        }\n    }\n}\n\nResTable::ResTable()\n    : mError(NO_INIT), mNextPackageId(2)\n{\n    memset(&mParams, 0, sizeof(mParams));\n    memset(mPackageMap, 0, sizeof(mPackageMap));\n    //ALOGI(\"Creating ResTable %p\\n\", this);\n}\n\nResTable::ResTable(const void* data, size_t size, const int32_t cookie, bool copyData)\n    : mError(NO_INIT), mNextPackageId(2)\n{\n    memset(&mParams, 0, sizeof(mParams));\n    memset(mPackageMap, 0, sizeof(mPackageMap));\n    addInternal(data, size, NULL, 0, cookie, copyData);\n    LOG_FATAL_IF(mError != NO_ERROR, \"Error parsing resource table\");\n    //ALOGI(\"Creating ResTable %p\\n\", this);\n}\n\nResTable::~ResTable()\n{\n    //ALOGI(\"Destroying ResTable in %p\\n\", this);\n    uninit();\n}\n\ninline ssize_t ResTable::getResourcePackageIndex(uint32_t resID) const\n{\n    return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1;\n}\n\nstatus_t ResTable::add(const void* data, size_t size, const int32_t cookie, bool copyData) {\n    return addInternal(data, size, NULL, 0, cookie, copyData);\n}\n\nstatus_t ResTable::add(const void* data, size_t size, const void* idmapData, size_t idmapDataSize,\n        const int32_t cookie, bool copyData) {\n    return addInternal(data, size, idmapData, idmapDataSize, cookie, copyData);\n}\n\nstatus_t ResTable::add(Asset* asset, const int32_t cookie, bool copyData) {\n    const void* data = asset->getBuffer(true);\n    if (data == NULL) {\n        ALOGW(\"Unable to get buffer of resource asset file\");\n        return UNKNOWN_ERROR;\n    }\n\n    return addInternal(data, static_cast<size_t>(asset->getLength()), NULL, 0, cookie, copyData);\n}\n\nstatus_t ResTable::add(Asset* asset, Asset* idmapAsset, const int32_t cookie, bool copyData) {\n    const void* data = asset->getBuffer(true);\n    if (data == NULL) {\n        ALOGW(\"Unable to get buffer of resource asset file\");\n        return UNKNOWN_ERROR;\n    }\n\n    size_t idmapSize = 0;\n    const void* idmapData = NULL;\n    if (idmapAsset != NULL) {\n        idmapData = idmapAsset->getBuffer(true);\n        if (idmapData == NULL) {\n            ALOGW(\"Unable to get buffer of idmap asset file\");\n            return UNKNOWN_ERROR;\n        }\n        idmapSize = static_cast<size_t>(idmapAsset->getLength());\n    }\n\n    return addInternal(data, static_cast<size_t>(asset->getLength()),\n            idmapData, idmapSize, cookie, copyData);\n}\n\nstatus_t ResTable::add(ResTable* src)\n{\n    mError = src->mError;\n\n    for (size_t i=0; i<src->mHeaders.size(); i++) {\n        mHeaders.add(src->mHeaders[i]);\n    }\n\n    for (size_t i=0; i<src->mPackageGroups.size(); i++) {\n        PackageGroup* srcPg = src->mPackageGroups[i];\n        PackageGroup* pg = new PackageGroup(this, srcPg->name, srcPg->id);\n        for (size_t j=0; j<srcPg->packages.size(); j++) {\n            pg->packages.add(srcPg->packages[j]);\n        }\n\n        for (size_t j = 0; j < srcPg->types.size(); j++) {\n            if (srcPg->types[j].isEmpty()) {\n                continue;\n            }\n\n            TypeList& typeList = pg->types.editItemAt(j);\n            typeList.appendVector(srcPg->types[j]);\n        }\n        pg->dynamicRefTable.addMappings(srcPg->dynamicRefTable);\n        pg->largestTypeId = max(pg->largestTypeId, srcPg->largestTypeId);\n        mPackageGroups.add(pg);\n    }\n\n    memcpy(mPackageMap, src->mPackageMap, sizeof(mPackageMap));\n\n    return mError;\n}\n\nstatus_t ResTable::addEmpty(const int32_t cookie) {\n    Header* header = new Header(this);\n    header->index = mHeaders.size();\n    header->cookie = cookie;\n    header->values.setToEmpty();\n    header->ownedData = calloc(1, sizeof(ResTable_header));\n\n    ResTable_header* resHeader = (ResTable_header*) header->ownedData;\n    resHeader->header.type = RES_TABLE_TYPE;\n    resHeader->header.headerSize = sizeof(ResTable_header);\n    resHeader->header.size = sizeof(ResTable_header);\n\n    header->header = (const ResTable_header*) resHeader;\n    mHeaders.add(header);\n    return (mError=NO_ERROR);\n}\n\nstatus_t ResTable::addInternal(const void* data, size_t dataSize, const void* idmapData, size_t idmapDataSize,\n        const int32_t cookie, bool copyData)\n{\n    if (!data) {\n        return NO_ERROR;\n    }\n\n    if (dataSize < sizeof(ResTable_header)) {\n        ALOGE(\"Invalid data. Size(%d) is smaller than a ResTable_header(%d).\",\n                (int) dataSize, (int) sizeof(ResTable_header));\n        return UNKNOWN_ERROR;\n    }\n\n    Header* header = new Header(this);\n    header->index = mHeaders.size();\n    header->cookie = cookie;\n    if (idmapData != NULL) {\n        header->resourceIDMap = (uint32_t*) malloc(idmapDataSize);\n        if (header->resourceIDMap == NULL) {\n            delete header;\n            return (mError = NO_MEMORY);\n        }\n        memcpy(header->resourceIDMap, idmapData, idmapDataSize);\n        header->resourceIDMapSize = idmapDataSize;\n    }\n    mHeaders.add(header);\n\n    const bool notDeviceEndian = htods(0xf0) != 0xf0;\n\n    LOAD_TABLE_NOISY(\n        ALOGV(\"Adding resources to ResTable: data=%p, size=0x%x, cookie=%d, copy=%d \"\n             \"idmap=%p\\n\", data, dataSize, cookie, copyData, idmap));\n\n    if (copyData || notDeviceEndian) {\n        header->ownedData = malloc(dataSize);\n        if (header->ownedData == NULL) {\n            return (mError=NO_MEMORY);\n        }\n        memcpy(header->ownedData, data, dataSize);\n        data = header->ownedData;\n    }\n\n    header->header = (const ResTable_header*)data;\n    header->size = dtohl(header->header->header.size);\n    //ALOGI(\"Got size 0x%x, again size 0x%x, raw size 0x%x\\n\", header->size,\n    //     dtohl(header->header->header.size), header->header->header.size);\n    LOAD_TABLE_NOISY(ALOGV(\"Loading ResTable @%p:\\n\", header->header));\n    if (dtohs(header->header->header.headerSize) > header->size\n            || header->size > dataSize) {\n        ALOGW(\"Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\\n\",\n             (int)dtohs(header->header->header.headerSize),\n             (int)header->size, (int)dataSize);\n        return (mError=BAD_TYPE);\n    }\n    if (((dtohs(header->header->header.headerSize)|header->size)&0x3) != 0) {\n        ALOGW(\"Bad resource table: header size 0x%x or total size 0x%x is not on an integer boundary\\n\",\n             (int)dtohs(header->header->header.headerSize),\n             (int)header->size);\n        return (mError=BAD_TYPE);\n    }\n    header->dataEnd = ((const uint8_t*)header->header) + header->size;\n\n    // Iterate through all chunks.\n    size_t curPackage = 0;\n\n    const ResChunk_header* chunk =\n        (const ResChunk_header*)(((const uint8_t*)header->header)\n                                 + dtohs(header->header->header.headerSize));\n    while (((const uint8_t*)chunk) <= (header->dataEnd-sizeof(ResChunk_header)) &&\n           ((const uint8_t*)chunk) <= (header->dataEnd-dtohl(chunk->size))) {\n        status_t err = validate_chunk(chunk, sizeof(ResChunk_header), header->dataEnd, \"ResTable\");\n        if (err != NO_ERROR) {\n            return (mError=err);\n        }\n        TABLE_NOISY(ALOGV(\"Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\\n\",\n                     dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),\n                     (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));\n        const size_t csize = dtohl(chunk->size);\n        const uint16_t ctype = dtohs(chunk->type);\n        if (ctype == RES_STRING_POOL_TYPE) {\n            if (header->values.getError() != NO_ERROR) {\n                // Only use the first string chunk; ignore any others that\n                // may appear.\n                status_t err = header->values.setTo(chunk, csize);\n                if (err != NO_ERROR) {\n                    return (mError=err);\n                }\n            } else {\n                ALOGW(\"Multiple string chunks found in resource table.\");\n            }\n        } else if (ctype == RES_TABLE_PACKAGE_TYPE) {\n            if (curPackage >= dtohl(header->header->packageCount)) {\n                ALOGW(\"More package chunks were found than the %d declared in the header.\",\n                     dtohl(header->header->packageCount));\n                return (mError=BAD_TYPE);\n            }\n\n            if (parsePackage((ResTable_package*)chunk, header) != NO_ERROR) {\n                return mError;\n            }\n            curPackage++;\n        } else {\n            ALOGW(\"Unknown chunk type 0x%x in table at %p.\\n\",\n                 ctype,\n                 (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)));\n        }\n        chunk = (const ResChunk_header*)\n            (((const uint8_t*)chunk) + csize);\n    }\n\n    if (curPackage < dtohl(header->header->packageCount)) {\n        ALOGW(\"Fewer package chunks (%d) were found than the %d declared in the header.\",\n             (int)curPackage, dtohl(header->header->packageCount));\n        return (mError=BAD_TYPE);\n    }\n    mError = header->values.getError();\n    if (mError != NO_ERROR) {\n        ALOGW(\"No string values found in resource table!\");\n    }\n\n    TABLE_NOISY(ALOGV(\"Returning from add with mError=%d\\n\", mError));\n    return mError;\n}\n\nstatus_t ResTable::getError() const\n{\n    return mError;\n}\n\nvoid ResTable::uninit()\n{\n    mError = NO_INIT;\n    size_t N = mPackageGroups.size();\n    for (size_t i=0; i<N; i++) {\n        PackageGroup* g = mPackageGroups[i];\n        delete g;\n    }\n    N = mHeaders.size();\n    for (size_t i=0; i<N; i++) {\n        Header* header = mHeaders[i];\n        if (header->owner == this) {\n            if (header->ownedData) {\n                free(header->ownedData);\n            }\n            delete header;\n        }\n    }\n\n    mPackageGroups.clear();\n    mHeaders.clear();\n}\n\nbool ResTable::getResourceName(uint32_t resID, bool allowUtf8, resource_name* outName) const\n{\n    if (mError != NO_ERROR) {\n        return false;\n    }\n\n    const ssize_t p = getResourcePackageIndex(resID);\n    const int t = Res_GETTYPE(resID);\n    const int e = Res_GETENTRY(resID);\n\n    if (p < 0) {\n        if (Res_GETPACKAGE(resID)+1 == 0) {\n            ALOGW(\"No package identifier when getting name for resource number 0x%08x\", resID);\n        } else {\n            ALOGW(\"No known package when getting name for resource number 0x%08x\", resID);\n        }\n        return false;\n    }\n    if (t < 0) {\n        ALOGW(\"No type identifier when getting name for resource number 0x%08x\", resID);\n        return false;\n    }\n\n    const PackageGroup* const grp = mPackageGroups[p];\n    if (grp == NULL) {\n        ALOGW(\"Bad identifier when getting name for resource number 0x%08x\", resID);\n        return false;\n    }\n\n    Entry entry;\n    status_t err = getEntry(grp, t, e, NULL, &entry);\n    if (err != NO_ERROR) {\n        return false;\n    }\n\n    outName->package = grp->name.string();\n    outName->packageLen = grp->name.size();\n    if (allowUtf8) {\n        outName->type8 = entry.typeStr.string8(&outName->typeLen);\n        outName->name8 = entry.keyStr.string8(&outName->nameLen);\n    } else {\n        outName->type8 = NULL;\n        outName->name8 = NULL;\n    }\n    if (outName->type8 == NULL) {\n        outName->type = entry.typeStr.string16(&outName->typeLen);\n        // If we have a bad index for some reason, we should abort.\n        if (outName->type == NULL) {\n            return false;\n        }\n    }\n    if (outName->name8 == NULL) {\n        outName->name = entry.keyStr.string16(&outName->nameLen);\n        // If we have a bad index for some reason, we should abort.\n        if (outName->name == NULL) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\nssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag, uint16_t density,\n        uint32_t* outSpecFlags, ResTable_config* outConfig) const\n{\n    if (mError != NO_ERROR) {\n        return mError;\n    }\n\n    const ssize_t p = getResourcePackageIndex(resID);\n    const int t = Res_GETTYPE(resID);\n    const int e = Res_GETENTRY(resID);\n\n    if (p < 0) {\n        if (Res_GETPACKAGE(resID)+1 == 0) {\n            ALOGW(\"No package identifier when getting value for resource number 0x%08x\", resID);\n        } else {\n            ALOGW(\"No known package when getting value for resource number 0x%08x\", resID);\n        }\n        return BAD_INDEX;\n    }\n    if (t < 0) {\n        ALOGW(\"No type identifier when getting value for resource number 0x%08x\", resID);\n        return BAD_INDEX;\n    }\n\n    const PackageGroup* const grp = mPackageGroups[p];\n    if (grp == NULL) {\n        ALOGW(\"Bad identifier when getting value for resource number 0x%08x\", resID);\n        return BAD_INDEX;\n    }\n\n    // Allow overriding density\n    ResTable_config desiredConfig = mParams;\n    if (density > 0) {\n        desiredConfig.density = density;\n    }\n\n    Entry entry;\n    status_t err = getEntry(grp, t, e, &desiredConfig, &entry);\n    if (err != NO_ERROR) {\n        ALOGW(\"Failure getting entry for 0x%08x (t=%d e=%d) (error %d)\\n\",\n                resID, t, e, err);\n        return err;\n    }\n\n    if ((dtohs(entry.entry->flags) & ResTable_entry::FLAG_COMPLEX) != 0) {\n        if (!mayBeBag) {\n            ALOGW(\"Requesting resource 0x%08x failed because it is complex\\n\", resID);\n        }\n        return BAD_VALUE;\n    }\n\n    const Res_value* value = reinterpret_cast<const Res_value*>(\n            reinterpret_cast<const uint8_t*>(entry.entry) + entry.entry->size);\n\n    outValue->size = dtohs(value->size);\n    outValue->res0 = value->res0;\n    outValue->dataType = value->dataType;\n    outValue->data = dtohl(value->data);\n\n    // The reference may be pointing to a resource in a shared library. These\n    // references have build-time generated package IDs. These ids may not match\n    // the actual package IDs of the corresponding packages in this ResTable.\n    // We need to fix the package ID based on a mapping.\n    if (grp->dynamicRefTable.lookupResourceValue(outValue) != NO_ERROR) {\n        ALOGW(\"Failed to resolve referenced package: 0x%08x\", outValue->data);\n        return BAD_VALUE;\n    }\n\n    TABLE_NOISY(size_t len;\n          printf(\"Found value: pkg=%d, type=%d, str=%s, int=%d\\n\",\n                 entry.package->header->index,\n                 outValue->dataType,\n                 outValue->dataType == Res_value::TYPE_STRING\n                 ? String8(entry.package->header->values.stringAt(\n                     outValue->data, &len)).string()\n                 : \"\",\n                 outValue->data));\n\n    if (outSpecFlags != NULL) {\n        *outSpecFlags = entry.specFlags;\n    }\n\n    if (outConfig != NULL) {\n        *outConfig = entry.config;\n    }\n\n    return entry.package->header->index;\n}\n\nssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,\n        uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags,\n        ResTable_config* outConfig) const\n{\n    int count=0;\n    while (blockIndex >= 0 && value->dataType == Res_value::TYPE_REFERENCE\n            && value->data != 0 && count < 20) {\n        if (outLastRef) *outLastRef = value->data;\n        uint32_t lastRef = value->data;\n        uint32_t newFlags = 0;\n        const ssize_t newIndex = getResource(value->data, value, true, 0, &newFlags,\n                outConfig);\n        if (newIndex == BAD_INDEX) {\n            return BAD_INDEX;\n        }\n        TABLE_THEME(ALOGI(\"Resolving reference %p: newIndex=%d, type=0x%x, data=%p\\n\",\n             (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data));\n        //printf(\"Getting reference 0x%08x: newIndex=%d\\n\", value->data, newIndex);\n        if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags;\n        if (newIndex < 0) {\n            // This can fail if the resource being referenced is a style...\n            // in this case, just return the reference, and expect the\n            // caller to deal with.\n            return blockIndex;\n        }\n        blockIndex = newIndex;\n        count++;\n    }\n    return blockIndex;\n}\n\nconst char16_t* ResTable::valueToString(\n    const Res_value* value, size_t stringBlock,\n    char16_t /*tmpBuffer*/ [TMP_BUFFER_SIZE], size_t* outLen) const\n{\n    if (!value) {\n        return NULL;\n    }\n    if (value->dataType == value->TYPE_STRING) {\n        return getTableStringBlock(stringBlock)->stringAt(value->data, outLen);\n    }\n    // XXX do int to string conversions.\n    return NULL;\n}\n\nssize_t ResTable::lockBag(uint32_t resID, const bag_entry** outBag) const\n{\n    mLock.lock();\n    ssize_t err = getBagLocked(resID, outBag);\n    if (err < NO_ERROR) {\n        //printf(\"*** get failed!  unlocking\\n\");\n        mLock.unlock();\n    }\n    return err;\n}\n\nvoid ResTable::unlockBag(const bag_entry* /*bag*/) const\n{\n    //printf(\"<<< unlockBag %p\\n\", this);\n    mLock.unlock();\n}\n\nvoid ResTable::lock() const\n{\n    mLock.lock();\n}\n\nvoid ResTable::unlock() const\n{\n    mLock.unlock();\n}\n\nssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,\n        uint32_t* outTypeSpecFlags) const\n{\n    if (mError != NO_ERROR) {\n        return mError;\n    }\n\n    const ssize_t p = getResourcePackageIndex(resID);\n    const int t = Res_GETTYPE(resID);\n    const int e = Res_GETENTRY(resID);\n\n    if (p < 0) {\n        ALOGW(\"Invalid package identifier when getting bag for resource number 0x%08x\", resID);\n        return BAD_INDEX;\n    }\n    if (t < 0) {\n        ALOGW(\"No type identifier when getting bag for resource number 0x%08x\", resID);\n        return BAD_INDEX;\n    }\n\n    //printf(\"Get bag: id=0x%08x, p=%d, t=%d\\n\", resID, p, t);\n    PackageGroup* const grp = mPackageGroups[p];\n    if (grp == NULL) {\n        ALOGW(\"Bad identifier when getting bag for resource number 0x%08x\", resID);\n        return BAD_INDEX;\n    }\n\n    const TypeList& typeConfigs = grp->types[t];\n    if (typeConfigs.isEmpty()) {\n        ALOGW(\"Type identifier 0x%x does not exist.\", t+1);\n        return BAD_INDEX;\n    }\n\n    const size_t NENTRY = typeConfigs[0]->entryCount;\n    if (e >= (int)NENTRY) {\n        ALOGW(\"Entry identifier 0x%x is larger than entry count 0x%x\",\n             e, (int)typeConfigs[0]->entryCount);\n        return BAD_INDEX;\n    }\n\n    // First see if we've already computed this bag...\n    if (grp->bags) {\n        bag_set** typeSet = grp->bags->get(t);\n        if (typeSet) {\n            bag_set* set = typeSet[e];\n            if (set) {\n                if (set != (bag_set*)0xFFFFFFFF) {\n                    if (outTypeSpecFlags != NULL) {\n                        *outTypeSpecFlags = set->typeSpecFlags;\n                    }\n                    *outBag = (bag_entry*)(set+1);\n                    //ALOGI(\"Found existing bag for: %p\\n\", (void*)resID);\n                    return set->numAttrs;\n                }\n                ALOGW(\"Attempt to retrieve bag 0x%08x which is invalid or in a cycle.\",\n                     resID);\n                return BAD_INDEX;\n            }\n        }\n    }\n\n    // Bag not found, we need to compute it!\n    if (!grp->bags) {\n        grp->bags = new ByteBucketArray<bag_set**>();\n        if (!grp->bags) return NO_MEMORY;\n    }\n\n    bag_set** typeSet = grp->bags->get(t);\n    if (!typeSet) {\n        typeSet = (bag_set**)calloc(NENTRY, sizeof(bag_set*));\n        if (!typeSet) return NO_MEMORY;\n        grp->bags->set(t, typeSet);\n    }\n\n    // Mark that we are currently working on this one.\n    typeSet[e] = (bag_set*)0xFFFFFFFF;\n\n    TABLE_NOISY(ALOGI(\"Building bag: %p\\n\", (void*)resID));\n\n    // Now collect all bag attributes\n    Entry entry;\n    status_t err = getEntry(grp, t, e, &mParams, &entry);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    const uint16_t entrySize = dtohs(entry.entry->size);\n    const uint32_t parent = entrySize >= sizeof(ResTable_map_entry)\n        ? dtohl(((const ResTable_map_entry*)entry.entry)->parent.ident) : 0;\n    const uint32_t count = entrySize >= sizeof(ResTable_map_entry)\n        ? dtohl(((const ResTable_map_entry*)entry.entry)->count) : 0;\n\n    size_t N = count;\n\n    TABLE_NOISY(ALOGI(\"Found map: size=%p parent=%p count=%d\\n\",\n                     entrySize, parent, count));\n\n    // If this map inherits from another, we need to start\n    // with its parent's values.  Otherwise start out empty.\n    TABLE_NOISY(printf(\"Creating new bag, entrySize=0x%08x, parent=0x%08x\\n\",\n                       entrySize, parent));\n\n    // This is what we are building.\n    bag_set* set = NULL;\n\n    if (parent) {\n        uint32_t resolvedParent = parent;\n\n        // Bags encode a parent reference without using the standard\n        // Res_value structure. That means we must always try to\n        // resolve a parent reference in case it is actually a\n        // TYPE_DYNAMIC_REFERENCE.\n        status_t err = grp->dynamicRefTable.lookupResourceId(&resolvedParent);\n        if (err != NO_ERROR) {\n            ALOGE(\"Failed resolving bag parent id 0x%08x\", parent);\n            return UNKNOWN_ERROR;\n        }\n\n        const bag_entry* parentBag;\n        uint32_t parentTypeSpecFlags = 0;\n        const ssize_t NP = getBagLocked(resolvedParent, &parentBag, &parentTypeSpecFlags);\n        const size_t NT = ((NP >= 0) ? NP : 0) + N;\n        set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*NT);\n        if (set == NULL) {\n            return NO_MEMORY;\n        }\n        if (NP > 0) {\n            memcpy(set+1, parentBag, NP*sizeof(bag_entry));\n            set->numAttrs = NP;\n            TABLE_NOISY(ALOGI(\"Initialized new bag with %d inherited attributes.\\n\", NP));\n        } else {\n            TABLE_NOISY(ALOGI(\"Initialized new bag with no inherited attributes.\\n\"));\n            set->numAttrs = 0;\n        }\n        set->availAttrs = NT;\n        set->typeSpecFlags = parentTypeSpecFlags;\n    } else {\n        set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*N);\n        if (set == NULL) {\n            return NO_MEMORY;\n        }\n        set->numAttrs = 0;\n        set->availAttrs = N;\n        set->typeSpecFlags = 0;\n    }\n\n    set->typeSpecFlags |= entry.specFlags;\n\n    // Now merge in the new attributes...\n    size_t curOff = (reinterpret_cast<uintptr_t>(entry.entry) - reinterpret_cast<uintptr_t>(entry.type))\n        + dtohs(entry.entry->size);\n    const ResTable_map* map;\n    bag_entry* entries = (bag_entry*)(set+1);\n    size_t curEntry = 0;\n    uint32_t pos = 0;\n    TABLE_NOISY(ALOGI(\"Starting with set %p, entries=%p, avail=%d\\n\",\n                 set, entries, set->availAttrs));\n    while (pos < count) {\n        TABLE_NOISY(printf(\"Now at %p\\n\", (void*)curOff));\n\n        if (curOff > (dtohl(entry.type->header.size)-sizeof(ResTable_map))) {\n            ALOGW(\"ResTable_map at %d is beyond type chunk data %d\",\n                 (int)curOff, dtohl(entry.type->header.size));\n            return BAD_TYPE;\n        }\n        map = (const ResTable_map*)(((const uint8_t*)entry.type) + curOff);\n        N++;\n\n        uint32_t newName = htodl(map->name.ident);\n        if (!Res_INTERNALID(newName)) {\n            // Attributes don't have a resource id as the name. They specify\n            // other data, which would be wrong to change via a lookup.\n            if (grp->dynamicRefTable.lookupResourceId(&newName) != NO_ERROR) {\n                ALOGE(\"Failed resolving ResTable_map name at %d with ident 0x%08x\",\n                        (int) curOff, (int) newName);\n                return UNKNOWN_ERROR;\n            }\n        }\n\n        bool isInside;\n        uint32_t oldName = 0;\n        while ((isInside=(curEntry < set->numAttrs))\n                && (oldName=entries[curEntry].map.name.ident) < newName) {\n            TABLE_NOISY(printf(\"#%d: Keeping existing attribute: 0x%08x\\n\",\n                         curEntry, entries[curEntry].map.name.ident));\n            curEntry++;\n        }\n\n        if ((!isInside) || oldName != newName) {\n            // This is a new attribute...  figure out what to do with it.\n            if (set->numAttrs >= set->availAttrs) {\n                // Need to alloc more memory...\n                const size_t newAvail = set->availAttrs+N;\n                set = (bag_set*)realloc(set,\n                                        sizeof(bag_set)\n                                        + sizeof(bag_entry)*newAvail);\n                if (set == NULL) {\n                    return NO_MEMORY;\n                }\n                set->availAttrs = newAvail;\n                entries = (bag_entry*)(set+1);\n                TABLE_NOISY(printf(\"Reallocated set %p, entries=%p, avail=%d\\n\",\n                             set, entries, set->availAttrs));\n            }\n            if (isInside) {\n                // Going in the middle, need to make space.\n                memmove(entries+curEntry+1, entries+curEntry,\n                        sizeof(bag_entry)*(set->numAttrs-curEntry));\n                set->numAttrs++;\n            }\n            TABLE_NOISY(printf(\"#%d: Inserting new attribute: 0x%08x\\n\",\n                         curEntry, newName));\n        } else {\n            TABLE_NOISY(printf(\"#%d: Replacing existing attribute: 0x%08x\\n\",\n                         curEntry, oldName));\n        }\n\n        bag_entry* cur = entries+curEntry;\n\n        cur->stringBlock = entry.package->header->index;\n        cur->map.name.ident = newName;\n        cur->map.value.copyFrom_dtoh(map->value);\n        status_t err = grp->dynamicRefTable.lookupResourceValue(&cur->map.value);\n        if (err != NO_ERROR) {\n            ALOGE(\"Reference item(0x%08x) in bag could not be resolved.\", cur->map.value.data);\n            return UNKNOWN_ERROR;\n        }\n\n        TABLE_NOISY(printf(\"Setting entry #%d %p: block=%d, name=0x%08x, type=%d, data=0x%08x\\n\",\n                     curEntry, cur, cur->stringBlock, cur->map.name.ident,\n                     cur->map.value.dataType, cur->map.value.data));\n\n        // On to the next!\n        curEntry++;\n        pos++;\n        const size_t size = dtohs(map->value.size);\n        curOff += size + sizeof(*map)-sizeof(map->value);\n    };\n\n    if (curEntry > set->numAttrs) {\n        set->numAttrs = curEntry;\n    }\n\n    // And this is it...\n    typeSet[e] = set;\n    if (set) {\n        if (outTypeSpecFlags != NULL) {\n            *outTypeSpecFlags = set->typeSpecFlags;\n        }\n        *outBag = (bag_entry*)(set+1);\n        TABLE_NOISY(ALOGI(\"Returning %d attrs\\n\", set->numAttrs));\n        return set->numAttrs;\n    }\n    return BAD_INDEX;\n}\n\nvoid ResTable::setParameters(const ResTable_config* params)\n{\n    mLock.lock();\n    TABLE_GETENTRY(ALOGI(\"Setting parameters: %s\\n\", params->toString().string()));\n    mParams = *params;\n    for (size_t i=0; i<mPackageGroups.size(); i++) {\n        TABLE_NOISY(ALOGI(\"CLEARING BAGS FOR GROUP %d!\", i));\n        mPackageGroups[i]->clearBagCache();\n    }\n    mLock.unlock();\n}\n\nvoid ResTable::getParameters(ResTable_config* params) const\n{\n    mLock.lock();\n    *params = mParams;\n    mLock.unlock();\n}\n\nstruct id_name_map {\n    uint32_t id;\n    size_t len;\n    char16_t name[6];\n};\n\nconst static id_name_map ID_NAMES[] = {\n    { ResTable_map::ATTR_TYPE,  5, { '^', 't', 'y', 'p', 'e' } },\n    { ResTable_map::ATTR_L10N,  5, { '^', 'l', '1', '0', 'n' } },\n    { ResTable_map::ATTR_MIN,   4, { '^', 'm', 'i', 'n' } },\n    { ResTable_map::ATTR_MAX,   4, { '^', 'm', 'a', 'x' } },\n    { ResTable_map::ATTR_OTHER, 6, { '^', 'o', 't', 'h', 'e', 'r' } },\n    { ResTable_map::ATTR_ZERO,  5, { '^', 'z', 'e', 'r', 'o' } },\n    { ResTable_map::ATTR_ONE,   4, { '^', 'o', 'n', 'e' } },\n    { ResTable_map::ATTR_TWO,   4, { '^', 't', 'w', 'o' } },\n    { ResTable_map::ATTR_FEW,   4, { '^', 'f', 'e', 'w' } },\n    { ResTable_map::ATTR_MANY,  5, { '^', 'm', 'a', 'n', 'y' } },\n};\n\nuint32_t ResTable::identifierForName(const char16_t* name, size_t nameLen,\n                                     const char16_t* type, size_t typeLen,\n                                     const char16_t* package,\n                                     size_t packageLen,\n                                     uint32_t* outTypeSpecFlags) const\n{\n    TABLE_SUPER_NOISY(printf(\"Identifier for name: error=%d\\n\", mError));\n\n    // Check for internal resource identifier as the very first thing, so\n    // that we will always find them even when there are no resources.\n    if (name[0] == '^') {\n        const int N = (sizeof(ID_NAMES)/sizeof(ID_NAMES[0]));\n        size_t len;\n        for (int i=0; i<N; i++) {\n            const id_name_map* m = ID_NAMES + i;\n            len = m->len;\n            if (len != nameLen) {\n                continue;\n            }\n            for (size_t j=1; j<len; j++) {\n                if (m->name[j] != name[j]) {\n                    goto nope;\n                }\n            }\n            if (outTypeSpecFlags) {\n                *outTypeSpecFlags = ResTable_typeSpec::SPEC_PUBLIC;\n            }\n            return m->id;\nnope:\n            ;\n        }\n        if (nameLen > 7) {\n            if (name[1] == 'i' && name[2] == 'n'\n                && name[3] == 'd' && name[4] == 'e' && name[5] == 'x'\n                && name[6] == '_') {\n                int index = atoi(String8(name + 7, nameLen - 7).string());\n                if (Res_CHECKID(index)) {\n                    ALOGW(\"Array resource index: %d is too large.\",\n                         index);\n                    return 0;\n                }\n                if (outTypeSpecFlags) {\n                    *outTypeSpecFlags = ResTable_typeSpec::SPEC_PUBLIC;\n                }\n                return  Res_MAKEARRAY(index);\n            }\n        }\n        return 0;\n    }\n\n    if (mError != NO_ERROR) {\n        return 0;\n    }\n\n    bool fakePublic = false;\n\n    // Figure out the package and type we are looking in...\n\n    const char16_t* packageEnd = NULL;\n    const char16_t* typeEnd = NULL;\n    const char16_t* const nameEnd = name+nameLen;\n    const char16_t* p = name;\n    while (p < nameEnd) {\n        if (*p == ':') packageEnd = p;\n        else if (*p == '/') typeEnd = p;\n        p++;\n    }\n    if (*name == '@') {\n        name++;\n        if (*name == '*') {\n            fakePublic = true;\n            name++;\n        }\n    }\n    if (name >= nameEnd) {\n        return 0;\n    }\n\n    if (packageEnd) {\n        package = name;\n        packageLen = packageEnd-name;\n        name = packageEnd+1;\n    } else if (!package) {\n        return 0;\n    }\n\n    if (typeEnd) {\n        type = name;\n        typeLen = typeEnd-name;\n        name = typeEnd+1;\n    } else if (!type) {\n        return 0;\n    }\n\n    if (name >= nameEnd) {\n        return 0;\n    }\n    nameLen = nameEnd-name;\n\n    TABLE_NOISY(printf(\"Looking for identifier: type=%s, name=%s, package=%s\\n\",\n                 String8(type, typeLen).string(),\n                 String8(name, nameLen).string(),\n                 String8(package, packageLen).string()));\n\n    const size_t NG = mPackageGroups.size();\n    for (size_t ig=0; ig<NG; ig++) {\n        const PackageGroup* group = mPackageGroups[ig];\n\n        if (strzcmp16(package, packageLen,\n                      group->name.string(), group->name.size())) {\n            TABLE_NOISY(printf(\"Skipping package group: %s\\n\", String8(group->name).string()));\n            continue;\n        }\n\n        const size_t packageCount = group->packages.size();\n        for (size_t pi = 0; pi < packageCount; pi++) {\n            ssize_t ti = group->packages[pi]->typeStrings.indexOfString(type, typeLen);\n            if (ti < 0) {\n                continue;\n            }\n\n            ti += group->packages[pi]->typeIdOffset;\n\n            const TypeList& typeList = group->types[ti];\n            if (typeList.isEmpty()) {\n                TABLE_NOISY(printf(\"Expected type structure not found in package %s for index %d\\n\",\n                                   String8(group->name).string(), ti));\n                continue;\n            }\n\n            const size_t typeCount = typeList.size();\n            for (size_t i = 0; i < typeCount; i++) {\n                const Type* t = typeList[i];\n                const ssize_t ei = t->package->keyStrings.indexOfString(name, nameLen);\n                if (ei < 0) {\n                    continue;\n                }\n\n                const size_t configCount = t->configs.size();\n                for (size_t j = 0; j < configCount; j++) {\n                    const TypeVariant tv(t->configs[j]);\n                    for (TypeVariant::iterator iter = tv.beginEntries();\n                         iter != tv.endEntries();\n                         iter++) {\n                        const ResTable_entry* entry = *iter;\n                        if (entry == NULL) {\n                            continue;\n                        }\n\n                        if (dtohl(entry->key.index) == (size_t) ei) {\n                            uint32_t resId = Res_MAKEID(group->id - 1, ti, iter.index());\n                            if (outTypeSpecFlags) {\n                                Entry result;\n                                if (getEntry(group, ti, iter.index(), NULL, &result) != NO_ERROR) {\n                                    ALOGW(\"Failed to find spec flags for %s:%s/%s (0x%08x)\",\n                                            String8(group->name).string(),\n                                            String8(String16(type, typeLen)).string(),\n                                            String8(String16(name, nameLen)).string(),\n                                            resId);\n                                    return 0;\n                                }\n                                *outTypeSpecFlags = result.specFlags;\n\n                                if (fakePublic) {\n                                    *outTypeSpecFlags |= ResTable_typeSpec::SPEC_PUBLIC;\n                                }\n                            }\n                            return resId;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    return 0;\n}\n\nbool ResTable::expandResourceRef(const uint16_t* refStr, size_t refLen,\n                                 String16* outPackage,\n                                 String16* outType,\n                                 String16* outName,\n                                 const String16* defType,\n                                 const String16* defPackage,\n                                 const char** outErrorMsg,\n                                 bool* outPublicOnly)\n{\n    const char16_t* packageEnd = NULL;\n    const char16_t* typeEnd = NULL;\n    const char16_t* p = refStr;\n    const char16_t* const end = p + refLen;\n    while (p < end) {\n        if (*p == ':') packageEnd = p;\n        else if (*p == '/') {\n            typeEnd = p;\n            break;\n        }\n        p++;\n    }\n    p = refStr;\n    if (*p == '@') p++;\n\n    if (outPublicOnly != NULL) {\n        *outPublicOnly = true;\n    }\n    if (*p == '*') {\n        p++;\n        if (outPublicOnly != NULL) {\n            *outPublicOnly = false;\n        }\n    }\n\n    if (packageEnd) {\n        *outPackage = String16(p, packageEnd-p);\n        p = packageEnd+1;\n    } else {\n        if (!defPackage) {\n            if (outErrorMsg) {\n                *outErrorMsg = \"No resource package specified\";\n            }\n            return false;\n        }\n        *outPackage = *defPackage;\n    }\n    if (typeEnd) {\n        *outType = String16(p, typeEnd-p);\n        p = typeEnd+1;\n    } else {\n        if (!defType) {\n            if (outErrorMsg) {\n                *outErrorMsg = \"No resource type specified\";\n            }\n            return false;\n        }\n        *outType = *defType;\n    }\n    *outName = String16(p, end-p);\n    if(**outPackage == 0) {\n        if(outErrorMsg) {\n            *outErrorMsg = \"Resource package cannot be an empty string\";\n        }\n        return false;\n    }\n    if(**outType == 0) {\n        if(outErrorMsg) {\n            *outErrorMsg = \"Resource type cannot be an empty string\";\n        }\n        return false;\n    }\n    if(**outName == 0) {\n        if(outErrorMsg) {\n            *outErrorMsg = \"Resource id cannot be an empty string\";\n        }\n        return false;\n    }\n    return true;\n}\n\nstatic uint32_t get_hex(char c, bool* outError)\n{\n    if (c >= '0' && c <= '9') {\n        return c - '0';\n    } else if (c >= 'a' && c <= 'f') {\n        return c - 'a' + 0xa;\n    } else if (c >= 'A' && c <= 'F') {\n        return c - 'A' + 0xa;\n    }\n    *outError = true;\n    return 0;\n}\n\nstruct unit_entry\n{\n    const char* name;\n    size_t len;\n    uint8_t type;\n    uint32_t unit;\n    float scale;\n};\n\nstatic const unit_entry unitNames[] = {\n    { \"px\", strlen(\"px\"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PX, 1.0f },\n    { \"dip\", strlen(\"dip\"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },\n    { \"dp\", strlen(\"dp\"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },\n    { \"sp\", strlen(\"sp\"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_SP, 1.0f },\n    { \"pt\", strlen(\"pt\"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PT, 1.0f },\n    { \"in\", strlen(\"in\"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_IN, 1.0f },\n    { \"mm\", strlen(\"mm\"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_MM, 1.0f },\n    { \"%\", strlen(\"%\"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION, 1.0f/100 },\n    { \"%p\", strlen(\"%p\"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100 },\n    { NULL, 0, 0, 0, 0 }\n};\n\nstatic bool parse_unit(const char* str, Res_value* outValue,\n                       float* outScale, const char** outEnd)\n{\n    const char* end = str;\n    while (*end != 0 && !isspace((unsigned char)*end)) {\n        end++;\n    }\n    const size_t len = end-str;\n\n    const char* realEnd = end;\n    while (*realEnd != 0 && isspace((unsigned char)*realEnd)) {\n        realEnd++;\n    }\n    if (*realEnd != 0) {\n        return false;\n    }\n\n    const unit_entry* cur = unitNames;\n    while (cur->name) {\n        if (len == cur->len && strncmp(cur->name, str, len) == 0) {\n            outValue->dataType = cur->type;\n            outValue->data = cur->unit << Res_value::COMPLEX_UNIT_SHIFT;\n            *outScale = cur->scale;\n            *outEnd = end;\n            //printf(\"Found unit %s for %s\\n\", cur->name, str);\n            return true;\n        }\n        cur++;\n    }\n\n    return false;\n}\n\n\nbool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue)\n{\n    while (len > 0 && isspace16(*s)) {\n        s++;\n        len--;\n    }\n\n    if (len <= 0) {\n        return false;\n    }\n\n    size_t i = 0;\n    int32_t val = 0;\n    bool neg = false;\n\n    if (*s == '-') {\n        neg = true;\n        i++;\n    }\n\n    if (s[i] < '0' || s[i] > '9') {\n        return false;\n    }\n\n    // Decimal or hex?\n    if (s[i] == '0' && s[i+1] == 'x') {\n        if (outValue)\n            outValue->dataType = outValue->TYPE_INT_HEX;\n        i += 2;\n        bool error = false;\n        while (i < len && !error) {\n            val = (val*16) + get_hex(s[i], &error);\n            i++;\n        }\n        if (error) {\n            return false;\n        }\n    } else {\n        if (outValue)\n            outValue->dataType = outValue->TYPE_INT_DEC;\n        while (i < len) {\n            if (s[i] < '0' || s[i] > '9') {\n                return false;\n            }\n            val = (val*10) + s[i]-'0';\n            i++;\n        }\n    }\n\n    if (neg) val = -val;\n\n    while (i < len && isspace16(s[i])) {\n        i++;\n    }\n\n    if (i == len) {\n        if (outValue)\n            outValue->data = val;\n        return true;\n    }\n\n    return false;\n}\n\nbool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue)\n{\n    while (len > 0 && isspace16(*s)) {\n        s++;\n        len--;\n    }\n\n    if (len <= 0) {\n        return false;\n    }\n\n    char buf[128];\n    int i=0;\n    while (len > 0 && *s != 0 && i < 126) {\n        if (*s > 255) {\n            return false;\n        }\n        buf[i++] = *s++;\n        len--;\n    }\n\n    if (len > 0) {\n        return false;\n    }\n    if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') {\n        return false;\n    }\n\n    buf[i] = 0;\n    const char* end;\n    float f = strtof(buf, (char**)&end);\n\n    if (*end != 0 && !isspace((unsigned char)*end)) {\n        // Might be a unit...\n        float scale;\n        if (parse_unit(end, outValue, &scale, &end)) {\n            f *= scale;\n            const bool neg = f < 0;\n            if (neg) f = -f;\n            uint64_t bits = (uint64_t)(f*(1<<23)+.5f);\n            uint32_t radix;\n            uint32_t shift;\n            if ((bits&0x7fffff) == 0) {\n                // Always use 23p0 if there is no fraction, just to make\n                // things easier to read.\n                radix = Res_value::COMPLEX_RADIX_23p0;\n                shift = 23;\n            } else if ((bits&0xffffffffff800000LL) == 0) {\n                // Magnitude is zero -- can fit in 0 bits of precision.\n                radix = Res_value::COMPLEX_RADIX_0p23;\n                shift = 0;\n            } else if ((bits&0xffffffff80000000LL) == 0) {\n                // Magnitude can fit in 8 bits of precision.\n                radix = Res_value::COMPLEX_RADIX_8p15;\n                shift = 8;\n            } else if ((bits&0xffffff8000000000LL) == 0) {\n                // Magnitude can fit in 16 bits of precision.\n                radix = Res_value::COMPLEX_RADIX_16p7;\n                shift = 16;\n            } else {\n                // Magnitude needs entire range, so no fractional part.\n                radix = Res_value::COMPLEX_RADIX_23p0;\n                shift = 23;\n            }\n            int32_t mantissa = (int32_t)(\n                (bits>>shift) & Res_value::COMPLEX_MANTISSA_MASK);\n            if (neg) {\n                mantissa = (-mantissa) & Res_value::COMPLEX_MANTISSA_MASK;\n            }\n            outValue->data |=\n                (radix<<Res_value::COMPLEX_RADIX_SHIFT)\n                | (mantissa<<Res_value::COMPLEX_MANTISSA_SHIFT);\n            //printf(\"Input value: %f 0x%016Lx, mult: %f, radix: %d, shift: %d, final: 0x%08x\\n\",\n            //       f * (neg ? -1 : 1), bits, f*(1<<23),\n            //       radix, shift, outValue->data);\n            return true;\n        }\n        return false;\n    }\n\n    while (*end != 0 && isspace((unsigned char)*end)) {\n        end++;\n    }\n\n    if (*end == 0) {\n        if (outValue) {\n            outValue->dataType = outValue->TYPE_FLOAT;\n            *(float*)(&outValue->data) = f;\n            return true;\n        }\n    }\n\n    return false;\n}\n\nbool ResTable::stringToValue(Res_value* outValue, String16* outString,\n                             const char16_t* s, size_t len,\n                             bool preserveSpaces, bool coerceType,\n                             uint32_t attrID,\n                             const String16* defType,\n                             const String16* defPackage,\n                             Accessor* accessor,\n                             void* accessorCookie,\n                             uint32_t attrType,\n                             bool enforcePrivate,\n                             bool printError) const\n{\n    bool localizationSetting = accessor != NULL && accessor->getLocalizationSetting();\n    const char* errorMsg = NULL;\n\n    outValue->size = sizeof(Res_value);\n    outValue->res0 = 0;\n\n    // First strip leading/trailing whitespace.  Do this before handling\n    // escapes, so they can be used to force whitespace into the string.\n    if (!preserveSpaces) {\n        while (len > 0 && isspace16(*s)) {\n            s++;\n            len--;\n        }\n        while (len > 0 && isspace16(s[len-1])) {\n            len--;\n        }\n        // If the string ends with '\\', then we keep the space after it.\n        if (len > 0 && s[len-1] == '\\\\' && s[len] != 0) {\n            len++;\n        }\n    }\n\n    //printf(\"Value for: %s\\n\", String8(s, len).string());\n\n    uint32_t l10nReq = ResTable_map::L10N_NOT_REQUIRED;\n    uint32_t attrMin = 0x80000000, attrMax = 0x7fffffff;\n    bool fromAccessor = false;\n    if (attrID != 0 && !Res_INTERNALID(attrID)) {\n        const ssize_t p = getResourcePackageIndex(attrID);\n        const bag_entry* bag;\n        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;\n        //printf(\"For attr 0x%08x got bag of %d\\n\", attrID, cnt);\n        if (cnt >= 0) {\n            while (cnt > 0) {\n                //printf(\"Entry 0x%08x = 0x%08x\\n\", bag->map.name.ident, bag->map.value.data);\n                switch (bag->map.name.ident) {\n                case ResTable_map::ATTR_TYPE:\n                    attrType = bag->map.value.data;\n                    break;\n                case ResTable_map::ATTR_MIN:\n                    attrMin = bag->map.value.data;\n                    break;\n                case ResTable_map::ATTR_MAX:\n                    attrMax = bag->map.value.data;\n                    break;\n                case ResTable_map::ATTR_L10N:\n                    l10nReq = bag->map.value.data;\n                    break;\n                }\n                bag++;\n                cnt--;\n            }\n            unlockBag(bag);\n        } else if (accessor && accessor->getAttributeType(attrID, &attrType)) {\n            fromAccessor = true;\n            if (attrType == ResTable_map::TYPE_ENUM\n                    || attrType == ResTable_map::TYPE_FLAGS\n                    || attrType == ResTable_map::TYPE_INTEGER) {\n                accessor->getAttributeMin(attrID, &attrMin);\n                accessor->getAttributeMax(attrID, &attrMax);\n            }\n            if (localizationSetting) {\n                l10nReq = accessor->getAttributeL10N(attrID);\n            }\n        }\n    }\n\n    const bool canStringCoerce =\n        coerceType && (attrType&ResTable_map::TYPE_STRING) != 0;\n\n    if (*s == '@') {\n        outValue->dataType = outValue->TYPE_REFERENCE;\n\n        // Note: we don't check attrType here because the reference can\n        // be to any other type; we just need to count on the client making\n        // sure the referenced type is correct.\n\n        //printf(\"Looking up ref: %s\\n\", String8(s, len).string());\n\n        // It's a reference!\n        if (len == 5 && s[1]=='n' && s[2]=='u' && s[3]=='l' && s[4]=='l') {\n            outValue->data = 0;\n            return true;\n        } else {\n            bool createIfNotFound = false;\n            const char16_t* resourceRefName;\n            int resourceNameLen;\n            if (len > 2 && s[1] == '+') {\n                createIfNotFound = true;\n                resourceRefName = s + 2;\n                resourceNameLen = len - 2;\n            } else if (len > 2 && s[1] == '*') {\n                enforcePrivate = false;\n                resourceRefName = s + 2;\n                resourceNameLen = len - 2;\n            } else {\n                createIfNotFound = false;\n                resourceRefName = s + 1;\n                resourceNameLen = len - 1;\n            }\n            String16 package, type, name;\n            if (!expandResourceRef(resourceRefName,resourceNameLen, &package, &type, &name,\n                                   defType, defPackage, &errorMsg)) {\n                if (accessor != NULL&& printError) {\n                    accessor->reportError(accessorCookie, errorMsg);\n                }\n                return false;\n            }\n\n            uint32_t specFlags = 0;\n            // 首先include中查找\n            uint32_t rid = identifierForName(name.string(), name.size(), type.string(),\n                    type.size(), package.string(), package.size(), &specFlags);\n\n            if (rid != 0) {\n                if (enforcePrivate) {\n                    if (accessor == NULL) {\n                        if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {\n                            if (accessor != NULL&& printError) {\n                                accessor->reportError(accessorCookie, \"Resource is not public.\");\n                            }\n                            return false;\n                        }\n                    }\n                }\n\n                if (accessor) {\n                    rid = Res_MAKEID(\n                        accessor->getRemappedPackage(Res_GETPACKAGE(rid)),\n                        Res_GETTYPE(rid), Res_GETENTRY(rid));\n                    TABLE_NOISY(printf(\"Incl %s:%s/%s: 0x%08x\\n\",\n                           String8(package).string(), String8(type).string(),\n                           String8(name).string(), rid));\n                }\n\n                uint32_t packageId = Res_GETPACKAGE(rid) + 1;\n                if (packageId != customePackageId && packageId != SYS_PACKAGE_ID &&packageId != 0x7f) {\n                    outValue->dataType = Res_value::TYPE_DYNAMIC_REFERENCE;\n                }\n                outValue->data = rid;\n                return true;\n            }\n\n            if (accessor) {\n                // For fragment case, that Host bundle's xml could has same @+id\n                // in Fragment, here we do a very trick thing is that search\n                // Host bundle for rid so that the rid could be unique.\n                uint32_t rid = 0;    \t\n                if (sktPackageName != NULL){\n                    rid = identifierForName(name.string(), name.size(), type.string(),\n                            type.size(), String16(sktPackageName).string(), String16(sktPackageName).size(), &specFlags);\n                }\n                if (rid == 0){\n                    // include中找不到\n                    // 从自身查找\n                     rid = accessor->getCustomResourceWithCreation(package, type, name,\n                                                                       createIfNotFound);\n                }\n                if (rid != 0) {\n                    TABLE_NOISY(printf(\"Pckg %s:%s/%s: 0x%08x\\n\",\n                           String8(package).string(), String8(type).string(),\n                           String8(name).string(), rid));\n                    uint32_t packageId = Res_GETPACKAGE(rid) + 1;\n                    if (packageId == 0x00) {\n                        outValue->data = rid;\n                        outValue->dataType = Res_value::TYPE_DYNAMIC_REFERENCE;\n                        return true;\n                    } else if (packageId == customePackageId || packageId == SYS_PACKAGE_ID || packageId == 0x7f) {\n                        // We accept packageId's generated as 0x01 in order to support\n                        // building the android system resources\n                        outValue->data = rid;\n                        return true;\n                    }\n                }\n            }\n        }\n\n        if (accessor != NULL && printError) {\n            accessor->reportError(accessorCookie, \"No resource found that matches the given name\");\n        }\n        return false;\n    }\n\n    // if we got to here, and localization is required and it's not a reference,\n    // complain and bail.\n    if (l10nReq == ResTable_map::L10N_SUGGESTED) {\n        if (localizationSetting) {\n            if (accessor != NULL && printError) {\n                accessor->reportError(accessorCookie, \"This attribute must be localized.\");\n            }\n        }\n    }\n\n    if (*s == '#') {\n        // It's a color!  Convert to an integer of the form 0xaarrggbb.\n        uint32_t color = 0;\n        bool error = false;\n        if (len == 4) {\n            outValue->dataType = outValue->TYPE_INT_COLOR_RGB4;\n            color |= 0xFF000000;\n            color |= get_hex(s[1], &error) << 20;\n            color |= get_hex(s[1], &error) << 16;\n            color |= get_hex(s[2], &error) << 12;\n            color |= get_hex(s[2], &error) << 8;\n            color |= get_hex(s[3], &error) << 4;\n            color |= get_hex(s[3], &error);\n        } else if (len == 5) {\n            outValue->dataType = outValue->TYPE_INT_COLOR_ARGB4;\n            color |= get_hex(s[1], &error) << 28;\n            color |= get_hex(s[1], &error) << 24;\n            color |= get_hex(s[2], &error) << 20;\n            color |= get_hex(s[2], &error) << 16;\n            color |= get_hex(s[3], &error) << 12;\n            color |= get_hex(s[3], &error) << 8;\n            color |= get_hex(s[4], &error) << 4;\n            color |= get_hex(s[4], &error);\n        } else if (len == 7) {\n            outValue->dataType = outValue->TYPE_INT_COLOR_RGB8;\n            color |= 0xFF000000;\n            color |= get_hex(s[1], &error) << 20;\n            color |= get_hex(s[2], &error) << 16;\n            color |= get_hex(s[3], &error) << 12;\n            color |= get_hex(s[4], &error) << 8;\n            color |= get_hex(s[5], &error) << 4;\n            color |= get_hex(s[6], &error);\n        } else if (len == 9) {\n            outValue->dataType = outValue->TYPE_INT_COLOR_ARGB8;\n            color |= get_hex(s[1], &error) << 28;\n            color |= get_hex(s[2], &error) << 24;\n            color |= get_hex(s[3], &error) << 20;\n            color |= get_hex(s[4], &error) << 16;\n            color |= get_hex(s[5], &error) << 12;\n            color |= get_hex(s[6], &error) << 8;\n            color |= get_hex(s[7], &error) << 4;\n            color |= get_hex(s[8], &error);\n        } else {\n            error = true;\n        }\n        if (!error) {\n            if ((attrType&ResTable_map::TYPE_COLOR) == 0) {\n                if (!canStringCoerce) {\n                    if (accessor != NULL && printError) {\n                        accessor->reportError(accessorCookie,\n                                \"Color types not allowed\");\n                    }\n                    return false;\n                }\n            } else {\n                outValue->data = color;\n                //printf(\"Color input=%s, output=0x%x\\n\", String8(s, len).string(), color);\n                return true;\n            }\n        } else {\n            if ((attrType&ResTable_map::TYPE_COLOR) != 0) {\n                if (accessor != NULL && printError) {\n                    accessor->reportError(accessorCookie, \"Color value not valid --\"\n                            \" must be #rgb, #argb, #rrggbb, or #aarrggbb\");\n                }\n                #if 0\n                fprintf(stderr, \"%s: Color ID %s value %s is not valid\\n\",\n                        \"Resource File\", //(const char*)in->getPrintableSource(),\n                        String8(*curTag).string(),\n                        String8(s, len).string());\n                #endif\n                return false;\n            }\n        }\n    }\n\n    if (*s == '?') {\n        outValue->dataType = outValue->TYPE_ATTRIBUTE;\n\n        // Note: we don't check attrType here because the reference can\n        // be to any other type; we just need to count on the client making\n        // sure the referenced type is correct.\n\n        //printf(\"Looking up attr: %s\\n\", String8(s, len).string());\n\n        static const String16 attr16(\"attr\");\n        String16 package, type, name;\n        if (!expandResourceRef(s+1, len-1, &package, &type, &name,\n                               &attr16, defPackage, &errorMsg)) {\n            if (accessor != NULL && printError) {\n                accessor->reportError(accessorCookie, errorMsg);\n            }\n            return false;\n        }\n\n        //printf(\"Pkg: %s, Type: %s, Name: %s\\n\",\n        //       String8(package).string(), String8(type).string(),\n        //       String8(name).string());\n        uint32_t specFlags = 0;\n        uint32_t rid =\n            identifierForName(name.string(), name.size(),\n                              type.string(), type.size(),\n                              package.string(), package.size(), &specFlags);\n        if (rid != 0) {\n            // if (enforcePrivate) {\n            //     if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {\n            //         if (accessor != NULL && printError) {\n            //             accessor->reportError(accessorCookie, \"Attribute is not public.\");\n            //         }\n            //         return false;\n            //     }\n            // }\n            if (!accessor) {\n                outValue->data = rid;\n                return true;\n            }\n            rid = Res_MAKEID(\n                accessor->getRemappedPackage(Res_GETPACKAGE(rid)),\n                Res_GETTYPE(rid), Res_GETENTRY(rid));\n            //printf(\"Incl %s:%s/%s: 0x%08x\\n\",\n            //       String8(package).string(), String8(type).string(),\n            //       String8(name).string(), rid);\n            outValue->data = rid;\n            return true;\n        }\n\n        if (accessor) {\n            uint32_t rid = accessor->getCustomResource(package, type, name);\n            if (rid != 0) {\n                //printf(\"Mine %s:%s/%s: 0x%08x\\n\",\n                //       String8(package).string(), String8(type).string(),\n                //       String8(name).string(), rid);\n                outValue->data = rid;\n                return true;\n            }\n        }\n\n        if (accessor != NULL && printError) {\n            accessor->reportError(accessorCookie, \"No resource found that matches the given name\");\n        }\n        return false;\n    }\n\n    if (stringToInt(s, len, outValue)) {\n        if ((attrType&ResTable_map::TYPE_INTEGER) == 0) {\n            // If this type does not allow integers, but does allow floats,\n            // fall through on this error case because the float type should\n            // be able to accept any integer value.\n            if (!canStringCoerce && (attrType&ResTable_map::TYPE_FLOAT) == 0) {\n                if (accessor != NULL && printError) {\n                    accessor->reportError(accessorCookie, \"Integer types not allowed\");\n                }\n                return false;\n            }\n        } else {\n            if (((int32_t)outValue->data) < ((int32_t)attrMin)\n                    || ((int32_t)outValue->data) > ((int32_t)attrMax)) {\n                if (accessor != NULL && printError) {\n                    accessor->reportError(accessorCookie, \"Integer value out of range\");\n                }\n                return false;\n            }\n            return true;\n        }\n    }\n\n    if (stringToFloat(s, len, outValue)) {\n        if (outValue->dataType == Res_value::TYPE_DIMENSION) {\n            if ((attrType&ResTable_map::TYPE_DIMENSION) != 0) {\n                return true;\n            }\n            if (!canStringCoerce) {\n                if (accessor != NULL&& printError) {\n                    accessor->reportError(accessorCookie, \"Dimension types not allowed\");\n                }\n                return false;\n            }\n        } else if (outValue->dataType == Res_value::TYPE_FRACTION) {\n            if ((attrType&ResTable_map::TYPE_FRACTION) != 0) {\n                return true;\n            }\n            if (!canStringCoerce) {\n                if (accessor != NULL&& printError) {\n                    accessor->reportError(accessorCookie, \"Fraction types not allowed\");\n                }\n                return false;\n            }\n        } else if ((attrType&ResTable_map::TYPE_FLOAT) == 0) {\n            if (!canStringCoerce) {\n                if (accessor != NULL&& printError) {\n                    accessor->reportError(accessorCookie, \"Float types not allowed\");\n                }\n                return false;\n            }\n        } else {\n            return true;\n        }\n    }\n\n    if (len == 4) {\n        if ((s[0] == 't' || s[0] == 'T') &&\n            (s[1] == 'r' || s[1] == 'R') &&\n            (s[2] == 'u' || s[2] == 'U') &&\n            (s[3] == 'e' || s[3] == 'E')) {\n            if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {\n                if (!canStringCoerce) {\n                    if (accessor != NULL&& printError) {\n                        accessor->reportError(accessorCookie, \"Boolean types not allowed\");\n                    }\n                    return false;\n                }\n            } else {\n                outValue->dataType = outValue->TYPE_INT_BOOLEAN;\n                outValue->data = (uint32_t)-1;\n                return true;\n            }\n        }\n    }\n\n    if (len == 5) {\n        if ((s[0] == 'f' || s[0] == 'F') &&\n            (s[1] == 'a' || s[1] == 'A') &&\n            (s[2] == 'l' || s[2] == 'L') &&\n            (s[3] == 's' || s[3] == 'S') &&\n            (s[4] == 'e' || s[4] == 'E')) {\n            if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {\n                if (!canStringCoerce) {\n                    if (accessor != NULL&& printError) {\n                        accessor->reportError(accessorCookie, \"Boolean types not allowed\");\n                    }\n                    return false;\n                }\n            } else {\n                outValue->dataType = outValue->TYPE_INT_BOOLEAN;\n                outValue->data = 0;\n                return true;\n            }\n        }\n    }\n\n    if ((attrType&ResTable_map::TYPE_ENUM) != 0) {\n        const ssize_t p = getResourcePackageIndex(attrID);\n        const bag_entry* bag;\n        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;\n        //printf(\"Got %d for enum\\n\", cnt);\n        if (cnt >= 0) {\n            resource_name rname;\n            while (cnt > 0) {\n                if (!Res_INTERNALID(bag->map.name.ident)) {\n                    //printf(\"Trying attr #%08x\\n\", bag->map.name.ident);\n                    if (getResourceName(bag->map.name.ident, false, &rname)) {\n                        #if 0\n                        printf(\"Matching %s against %s (0x%08x)\\n\",\n                               String8(s, len).string(),\n                               String8(rname.name, rname.nameLen).string(),\n                               bag->map.name.ident);\n                        #endif\n                        if (strzcmp16(s, len, rname.name, rname.nameLen) == 0) {\n                            outValue->dataType = bag->map.value.dataType;\n                            outValue->data = bag->map.value.data;\n                            unlockBag(bag);\n                            return true;\n                        }\n                    }\n\n                }\n                bag++;\n                cnt--;\n            }\n            unlockBag(bag);\n        }\n\n        if (fromAccessor) {\n            if (accessor->getAttributeEnum(attrID, s, len, outValue)) {\n                return true;\n            }\n        }\n    }\n\n    if ((attrType&ResTable_map::TYPE_FLAGS) != 0) {\n        const ssize_t p = getResourcePackageIndex(attrID);\n        const bag_entry* bag;\n        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;\n        //printf(\"Got %d for flags\\n\", cnt);\n        if (cnt >= 0) {\n            bool failed = false;\n            resource_name rname;\n            outValue->dataType = Res_value::TYPE_INT_HEX;\n            outValue->data = 0;\n            const char16_t* end = s + len;\n            const char16_t* pos = s;\n            while (pos < end && !failed) {\n                const char16_t* start = pos;\n                pos++;\n                while (pos < end && *pos != '|') {\n                    pos++;\n                }\n                //printf(\"Looking for: %s\\n\", String8(start, pos-start).string());\n                const bag_entry* bagi = bag;\n                ssize_t i;\n                for (i=0; i<cnt; i++, bagi++) {\n                    if (!Res_INTERNALID(bagi->map.name.ident)) {\n                        //printf(\"Trying attr #%08x\\n\", bagi->map.name.ident);\n                        if (getResourceName(bagi->map.name.ident, false, &rname)) {\n                            #if 0\n                            printf(\"Matching %s against %s (0x%08x)\\n\",\n                                   String8(start,pos-start).string(),\n                                   String8(rname.name, rname.nameLen).string(),\n                                   bagi->map.name.ident);\n                            #endif\n                            if (strzcmp16(start, pos-start, rname.name, rname.nameLen) == 0) {\n                                outValue->data |= bagi->map.value.data;\n                                break;\n                            }\n                        }\n                    }\n                }\n                if (i >= cnt) {\n                    // Didn't find this flag identifier.\n                    failed = true;\n                }\n                if (pos < end) {\n                    pos++;\n                }\n            }\n            unlockBag(bag);\n            if (!failed) {\n                //printf(\"Final flag value: 0x%lx\\n\", outValue->data);\n                return true;\n            }\n        }\n\n\n        if (fromAccessor) {\n            if (accessor->getAttributeFlags(attrID, s, len, outValue)) {\n                //printf(\"Final flag value: 0x%lx\\n\", outValue->data);\n                return true;\n            }\n        }\n    }\n\n    if ((attrType&ResTable_map::TYPE_STRING) == 0) {\n        if (accessor != NULL&& printError) {\n            accessor->reportError(accessorCookie, \"String types not allowed\");\n        }\n        return false;\n    }\n\n    // Generic string handling...\n    outValue->dataType = outValue->TYPE_STRING;\n    if (outString) {\n        bool failed = collectString(outString, s, len, preserveSpaces, &errorMsg);\n        if (accessor != NULL&& printError) {\n            accessor->reportError(accessorCookie, errorMsg);\n        }\n        return failed;\n    }\n\n    return true;\n}\n\nbool ResTable::collectString(String16* outString,\n                             const char16_t* s, size_t len,\n                             bool preserveSpaces,\n                             const char** outErrorMsg,\n                             bool append)\n{\n    String16 tmp;\n\n    char quoted = 0;\n    const char16_t* p = s;\n    while (p < (s+len)) {\n        while (p < (s+len)) {\n            const char16_t c = *p;\n            if (c == '\\\\') {\n                break;\n            }\n            if (!preserveSpaces) {\n                if (quoted == 0 && isspace16(c)\n                    && (c != ' ' || isspace16(*(p+1)))) {\n                    break;\n                }\n                if (c == '\"' && (quoted == 0 || quoted == '\"')) {\n                    break;\n                }\n                if (c == '\\'' && (quoted == 0 || quoted == '\\'')) {\n                    /*\n                     * In practice, when people write ' instead of \\'\n                     * in a string, they are doing it by accident\n                     * instead of really meaning to use ' as a quoting\n                     * character.  Warn them so they don't lose it.\n                     */\n                    if (outErrorMsg) {\n                        *outErrorMsg = \"Apostrophe not preceded by \\\\\";\n                    }\n                    return false;\n                }\n            }\n            p++;\n        }\n        if (p < (s+len)) {\n            if (p > s) {\n                tmp.append(String16(s, p-s));\n            }\n            if (!preserveSpaces && (*p == '\"' || *p == '\\'')) {\n                if (quoted == 0) {\n                    quoted = *p;\n                } else {\n                    quoted = 0;\n                }\n                p++;\n            } else if (!preserveSpaces && isspace16(*p)) {\n                // Space outside of a quote -- consume all spaces and\n                // leave a single plain space char.\n                tmp.append(String16(\" \"));\n                p++;\n                while (p < (s+len) && isspace16(*p)) {\n                    p++;\n                }\n            } else if (*p == '\\\\') {\n                p++;\n                if (p < (s+len)) {\n                    switch (*p) {\n                    case 't':\n                        tmp.append(String16(\"\\t\"));\n                        break;\n                    case 'n':\n                        tmp.append(String16(\"\\n\"));\n                        break;\n                    case '#':\n                        tmp.append(String16(\"#\"));\n                        break;\n                    case '@':\n                        tmp.append(String16(\"@\"));\n                        break;\n                    case '?':\n                        tmp.append(String16(\"?\"));\n                        break;\n                    case '\"':\n                        tmp.append(String16(\"\\\"\"));\n                        break;\n                    case '\\'':\n                        tmp.append(String16(\"'\"));\n                        break;\n                    case '\\\\':\n                        tmp.append(String16(\"\\\\\"));\n                        break;\n                    case 'u':\n                    {\n                        char16_t chr = 0;\n                        int i = 0;\n                        while (i < 4 && p[1] != 0) {\n                            p++;\n                            i++;\n                            int c;\n                            if (*p >= '0' && *p <= '9') {\n                                c = *p - '0';\n                            } else if (*p >= 'a' && *p <= 'f') {\n                                c = *p - 'a' + 10;\n                            } else if (*p >= 'A' && *p <= 'F') {\n                                c = *p - 'A' + 10;\n                            } else {\n                                if (outErrorMsg) {\n                                    *outErrorMsg = \"Bad character in \\\\u unicode escape sequence\";\n                                }\n                                return false;\n                            }\n                            chr = (chr<<4) | c;\n                        }\n                        tmp.append(String16(&chr, 1));\n                    } break;\n                    default:\n                        // ignore unknown escape chars.\n                        break;\n                    }\n                    p++;\n                }\n            }\n            len -= (p-s);\n            s = p;\n        }\n    }\n\n    if (tmp.size() != 0) {\n        if (len > 0) {\n            tmp.append(String16(s, len));\n        }\n        if (append) {\n            outString->append(tmp);\n        } else {\n            outString->setTo(tmp);\n        }\n    } else {\n        if (append) {\n            outString->append(String16(s, len));\n        } else {\n            outString->setTo(s, len);\n        }\n    }\n\n    return true;\n}\n\nsize_t ResTable::getBasePackageCount() const\n{\n    if (mError != NO_ERROR) {\n        return 0;\n    }\n    return mPackageGroups.size();\n}\n\nconst String16 ResTable::getBasePackageName(size_t idx) const\n{\n    if (mError != NO_ERROR) {\n        return String16();\n    }\n    LOG_FATAL_IF(idx >= mPackageGroups.size(),\n                 \"Requested package index %d past package count %d\",\n                 (int)idx, (int)mPackageGroups.size());\n    return mPackageGroups[idx]->name;\n}\n\nuint32_t ResTable::getBasePackageId(size_t idx) const\n{\n    if (mError != NO_ERROR) {\n        return 0;\n    }\n    LOG_FATAL_IF(idx >= mPackageGroups.size(),\n                 \"Requested package index %d past package count %d\",\n                 (int)idx, (int)mPackageGroups.size());\n    return mPackageGroups[idx]->id;\n}\n\nuint32_t ResTable::getLastTypeIdForPackage(size_t idx) const\n{\n    if (mError != NO_ERROR) {\n        return 0;\n    }\n    LOG_FATAL_IF(idx >= mPackageGroups.size(),\n            \"Requested package index %d past package count %d\",\n            (int)idx, (int)mPackageGroups.size());\n    const PackageGroup* const group = mPackageGroups[idx];\n    return group->largestTypeId;\n}\n\nsize_t ResTable::getTableCount() const\n{\n    return mHeaders.size();\n}\n\nconst ResStringPool* ResTable::getTableStringBlock(size_t index) const\n{\n    return &mHeaders[index]->values;\n}\n\nint32_t ResTable::getTableCookie(size_t index) const\n{\n    return mHeaders[index]->cookie;\n}\n\nconst DynamicRefTable* ResTable::getDynamicRefTableForCookie(int32_t cookie) const\n{\n    const size_t N = mPackageGroups.size();\n    for (size_t i = 0; i < N; i++) {\n        const PackageGroup* pg = mPackageGroups[i];\n        size_t M = pg->packages.size();\n        for (size_t j = 0; j < M; j++) {\n            if (pg->packages[j]->header->cookie == cookie) {\n                return &pg->dynamicRefTable;\n            }\n        }\n    }\n    return NULL;\n}\n\nvoid ResTable::getConfigurations(Vector<ResTable_config>* configs) const\n{\n    const size_t packageCount = mPackageGroups.size();\n    for (size_t i = 0; i < packageCount; i++) {\n        const PackageGroup* packageGroup = mPackageGroups[i];\n        const size_t typeCount = packageGroup->types.size();\n        for (size_t j = 0; j < typeCount; j++) {\n            const TypeList& typeList = packageGroup->types[j];\n            const size_t numTypes = typeList.size();\n            for (size_t k = 0; k < numTypes; k++) {\n                const Type* type = typeList[k];\n                const size_t numConfigs = type->configs.size();\n                for (size_t m = 0; m < numConfigs; m++) {\n                    const ResTable_type* config = type->configs[m];\n                    ResTable_config cfg;\n                    memset(&cfg, 0, sizeof(ResTable_config));\n                    cfg.copyFromDtoH(config->config);\n                    // only insert unique\n                    const size_t N = configs->size();\n                    size_t n;\n                    for (n = 0; n < N; n++) {\n                        if (0 == (*configs)[n].compare(cfg)) {\n                            break;\n                        }\n                    }\n                    // if we didn't find it\n                    if (n == N) {\n                        configs->add(cfg);\n                    }\n                }\n            }\n        }\n    }\n}\n\nvoid ResTable::getLocales(Vector<String8>* locales) const\n{\n    Vector<ResTable_config> configs;\n    ALOGV(\"calling getConfigurations\");\n    getConfigurations(&configs);\n    ALOGV(\"called getConfigurations size=%d\", (int)configs.size());\n    const size_t I = configs.size();\n\n    char locale[RESTABLE_MAX_LOCALE_LEN];\n    for (size_t i=0; i<I; i++) {\n        configs[i].getBcp47Locale(locale);\n        const size_t J = locales->size();\n        size_t j;\n        for (j=0; j<J; j++) {\n            if (0 == strcmp(locale, (*locales)[j].string())) {\n                break;\n            }\n        }\n        if (j == J) {\n            locales->add(String8(locale));\n        }\n    }\n}\n\nStringPoolRef::StringPoolRef(const ResStringPool* pool, uint32_t index)\n    : mPool(pool), mIndex(index) {}\n\nStringPoolRef::StringPoolRef()\n    : mPool(NULL), mIndex(0) {}\n\nconst char* StringPoolRef::string8(size_t* outLen) const {\n    if (mPool != NULL) {\n        return mPool->string8At(mIndex, outLen);\n    }\n    if (outLen != NULL) {\n        *outLen = 0;\n    }\n    return NULL;\n}\n\nconst char16_t* StringPoolRef::string16(size_t* outLen) const {\n    if (mPool != NULL) {\n        return mPool->stringAt(mIndex, outLen);\n    }\n    if (outLen != NULL) {\n        *outLen = 0;\n    }\n    return NULL;\n}\n\nbool ResTable::getResourceFlags(uint32_t resID, uint32_t* outFlags) const {\n    if (mError != NO_ERROR) {\n        return false;\n    }\n\n    const ssize_t p = getResourcePackageIndex(resID);\n    const int t = Res_GETTYPE(resID);\n    const int e = Res_GETENTRY(resID);\n\n    if (p < 0) {\n        if (Res_GETPACKAGE(resID)+1 == 0) {\n            ALOGW(\"No package identifier when getting flags for resource number 0x%08x\", resID);\n        } else {\n            ALOGW(\"No known package when getting flags for resource number 0x%08x\", resID);\n        }\n        return false;\n    }\n    if (t < 0) {\n        ALOGW(\"No type identifier when getting flags for resource number 0x%08x\", resID);\n        return false;\n    }\n\n    const PackageGroup* const grp = mPackageGroups[p];\n    if (grp == NULL) {\n        ALOGW(\"Bad identifier when getting flags for resource number 0x%08x\", resID);\n        return false;\n    }\n\n    Entry entry;\n    status_t err = getEntry(grp, t, e, NULL, &entry);\n    if (err != NO_ERROR) {\n        return false;\n    }\n\n    *outFlags = entry.specFlags;\n    return true;\n}\n\nstatus_t ResTable::getEntry(\n        const PackageGroup* packageGroup, int typeIndex, int entryIndex,\n        const ResTable_config* config,\n        Entry* outEntry) const\n{\n    const TypeList& typeList = packageGroup->types[typeIndex];\n    if (typeList.isEmpty()) {\n        ALOGV(\"Skipping entry type index 0x%02x because type is NULL!\\n\", typeIndex);\n        return BAD_TYPE;\n    }\n\n    const ResTable_type* bestType = NULL;\n    uint32_t bestOffset = ResTable_type::NO_ENTRY;\n    const Package* bestPackage = NULL;\n    uint32_t specFlags = 0;\n    uint8_t actualTypeIndex = typeIndex;\n    ResTable_config bestConfig;\n    memset(&bestConfig, 0, sizeof(bestConfig));\n\n    // Iterate over the Types of each package.\n    const size_t typeCount = typeList.size();\n    for (size_t i = 0; i < typeCount; i++) {\n        const Type* const typeSpec = typeList[i];\n\n        int realEntryIndex = entryIndex;\n        int realTypeIndex = typeIndex;\n        bool currentTypeIsOverlay = false;\n\n        // Runtime overlay packages provide a mapping of app resource\n        // ID to package resource ID.\n        if (typeSpec->idmapEntries.hasEntries()) {\n            uint16_t overlayEntryIndex;\n            if (typeSpec->idmapEntries.lookup(entryIndex, &overlayEntryIndex) != NO_ERROR) {\n                // No such mapping exists\n                continue;\n            }\n            realEntryIndex = overlayEntryIndex;\n            realTypeIndex = typeSpec->idmapEntries.overlayTypeId() - 1;\n            currentTypeIsOverlay = true;\n        }\n\n        if (static_cast<size_t>(realEntryIndex) >= typeSpec->entryCount) {\n            ALOGW(\"For resource 0x%08x, entry index(%d) is beyond type entryCount(%d)\",\n                    Res_MAKEID(packageGroup->id - 1, typeIndex, entryIndex),\n                    entryIndex, static_cast<int>(typeSpec->entryCount));\n            // We should normally abort here, but some legacy apps declare\n            // resources in the 'android' package (old bug in AAPT).\n            continue;\n        }\n\n        // Aggregate all the flags for each package that defines this entry.\n        if (typeSpec->typeSpecFlags != NULL) {\n            specFlags |= dtohl(typeSpec->typeSpecFlags[realEntryIndex]);\n        } else {\n            specFlags = -1;\n        }\n\n        const size_t numConfigs = typeSpec->configs.size();\n        for (size_t c = 0; c < numConfigs; c++) {\n            const ResTable_type* const thisType = typeSpec->configs[c];\n            if (thisType == NULL) {\n                continue;\n            }\n\n            ResTable_config thisConfig;\n            thisConfig.copyFromDtoH(thisType->config);\n\n            // Check to make sure this one is valid for the current parameters.\n            if (config != NULL && !thisConfig.match(*config)) {\n                continue;\n            }\n\n            // Check if there is the desired entry in this type.\n            const uint8_t* const end = reinterpret_cast<const uint8_t*>(thisType)\n                    + dtohl(thisType->header.size);\n            const uint32_t* const eindex = reinterpret_cast<const uint32_t*>(\n                    reinterpret_cast<const uint8_t*>(thisType) + dtohs(thisType->header.headerSize));\n\n            uint32_t thisOffset = dtohl(eindex[realEntryIndex]);\n            if (thisOffset == ResTable_type::NO_ENTRY) {\n                // There is no entry for this index and configuration.\n                continue;\n            }\n\n            if (bestType != NULL) {\n                // Check if this one is less specific than the last found.  If so,\n                // we will skip it.  We check starting with things we most care\n                // about to those we least care about.\n                if (!thisConfig.isBetterThan(bestConfig, config)) {\n                    if (!currentTypeIsOverlay || thisConfig.compare(bestConfig) != 0) {\n                        continue;\n                    }\n                }\n            }\n\n            bestType = thisType;\n            bestOffset = thisOffset;\n            bestConfig = thisConfig;\n            bestPackage = typeSpec->package;\n            actualTypeIndex = realTypeIndex;\n\n            // If no config was specified, any type will do, so skip\n            if (config == NULL) {\n                break;\n            }\n        }\n    }\n\n    if (bestType == NULL) {\n        return BAD_INDEX;\n    }\n\n    bestOffset += dtohl(bestType->entriesStart);\n\n    if (bestOffset > (dtohl(bestType->header.size)-sizeof(ResTable_entry))) {\n        ALOGW(\"ResTable_entry at 0x%x is beyond type chunk data 0x%x\",\n                bestOffset, dtohl(bestType->header.size));\n        return BAD_TYPE;\n    }\n    if ((bestOffset & 0x3) != 0) {\n        ALOGW(\"ResTable_entry at 0x%x is not on an integer boundary\", bestOffset);\n        return BAD_TYPE;\n    }\n\n    const ResTable_entry* const entry = reinterpret_cast<const ResTable_entry*>(\n            reinterpret_cast<const uint8_t*>(bestType) + bestOffset);\n    if (dtohs(entry->size) < sizeof(*entry)) {\n        ALOGW(\"ResTable_entry size 0x%x is too small\", dtohs(entry->size));\n        return BAD_TYPE;\n    }\n\n    if (outEntry != NULL) {\n        outEntry->entry = entry;\n        outEntry->config = bestConfig;\n        outEntry->type = bestType;\n        outEntry->specFlags = specFlags;\n        outEntry->package = bestPackage;\n        outEntry->typeStr = StringPoolRef(&bestPackage->typeStrings, actualTypeIndex - bestPackage->typeIdOffset);\n        outEntry->keyStr = StringPoolRef(&bestPackage->keyStrings, dtohl(entry->key.index));\n    }\n    return NO_ERROR;\n}\n\nstatus_t ResTable::parsePackage(const ResTable_package* const pkg,\n                                const Header* const header)\n{\n    const uint8_t* base = (const uint8_t*)pkg;\n    status_t err = validate_chunk(&pkg->header, sizeof(*pkg) - sizeof(pkg->typeIdOffset),\n                                  header->dataEnd, \"ResTable_package\");\n    if (err != NO_ERROR) {\n        return (mError=err);\n    }\n\n    const uint32_t pkgSize = dtohl(pkg->header.size);\n\n    if (dtohl(pkg->typeStrings) >= pkgSize) {\n        ALOGW(\"ResTable_package type strings at 0x%x are past chunk size 0x%x.\",\n             dtohl(pkg->typeStrings), pkgSize);\n        return (mError=BAD_TYPE);\n    }\n    if ((dtohl(pkg->typeStrings)&0x3) != 0) {\n        ALOGW(\"ResTable_package type strings at 0x%x is not on an integer boundary.\",\n             dtohl(pkg->typeStrings));\n        return (mError=BAD_TYPE);\n    }\n    if (dtohl(pkg->keyStrings) >= pkgSize) {\n        ALOGW(\"ResTable_package key strings at 0x%x are past chunk size 0x%x.\",\n             dtohl(pkg->keyStrings), pkgSize);\n        return (mError=BAD_TYPE);\n    }\n    if ((dtohl(pkg->keyStrings)&0x3) != 0) {\n        ALOGW(\"ResTable_package key strings at 0x%x is not on an integer boundary.\",\n             dtohl(pkg->keyStrings));\n        return (mError=BAD_TYPE);\n    }\n\n    uint32_t id = dtohl(pkg->id);\n    KeyedVector<uint8_t, IdmapEntries> idmapEntries;\n\n    if (header->resourceIDMap != NULL) {\n        uint8_t targetPackageId = 0;\n        status_t err = parseIdmap(header->resourceIDMap, header->resourceIDMapSize, &targetPackageId, &idmapEntries);\n        if (err != NO_ERROR) {\n            ALOGW(\"Overlay is broken\");\n            return (mError=err);\n        }\n        id = targetPackageId;\n    }\n\n    if (id >= 256) {\n        LOG_ALWAYS_FATAL(\"Package id out of range\");\n        return NO_ERROR;\n    } else if (id == 0) {\n        // This is a library so assign an ID\n        id = mNextPackageId++;\n    }\n\n    PackageGroup* group = NULL;\n    Package* package = new Package(this, header, pkg);\n    if (package == NULL) {\n        return (mError=NO_MEMORY);\n    }\n\n    err = package->typeStrings.setTo(base+dtohl(pkg->typeStrings),\n                                   header->dataEnd-(base+dtohl(pkg->typeStrings)));\n    if (err != NO_ERROR) {\n        delete group;\n        delete package;\n        return (mError=err);\n    }\n\n    err = package->keyStrings.setTo(base+dtohl(pkg->keyStrings),\n                                  header->dataEnd-(base+dtohl(pkg->keyStrings)));\n    if (err != NO_ERROR) {\n        delete group;\n        delete package;\n        return (mError=err);\n    }\n\n    size_t idx = mPackageMap[id];\n    if (idx == 0) {\n        idx = mPackageGroups.size() + 1;\n\n        char16_t tmpName[sizeof(pkg->name)/sizeof(char16_t)];\n        strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(char16_t));\n        group = new PackageGroup(this, String16(tmpName), id);\n        if (group == NULL) {\n            delete package;\n            return (mError=NO_MEMORY);\n        }\n\n        err = mPackageGroups.add(group);\n        if (err < NO_ERROR) {\n            return (mError=err);\n        }\n\n        mPackageMap[id] = static_cast<uint8_t>(idx);\n\n        // Find all packages that reference this package\n        size_t N = mPackageGroups.size();\n        for (size_t i = 0; i < N; i++) {\n            mPackageGroups[i]->dynamicRefTable.addMapping(\n                    group->name, static_cast<uint8_t>(group->id));\n        }\n    } else {\n        group = mPackageGroups.itemAt(idx - 1);\n        if (group == NULL) {\n            return (mError=UNKNOWN_ERROR);\n        }\n    }\n\n    err = group->packages.add(package);\n    if (err < NO_ERROR) {\n        return (mError=err);\n    }\n\n    // Iterate through all chunks.\n    const ResChunk_header* chunk =\n        (const ResChunk_header*)(((const uint8_t*)pkg)\n                                 + dtohs(pkg->header.headerSize));\n    const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size);\n    while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) &&\n           ((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) {\n        TABLE_NOISY(ALOGV(\"PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\\n\",\n                         dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),\n                         (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));\n        const size_t csize = dtohl(chunk->size);\n        const uint16_t ctype = dtohs(chunk->type);\n        if (ctype == RES_TABLE_TYPE_SPEC_TYPE) {\n            const ResTable_typeSpec* typeSpec = (const ResTable_typeSpec*)(chunk);\n            err = validate_chunk(&typeSpec->header, sizeof(*typeSpec),\n                                 endPos, \"ResTable_typeSpec\");\n            if (err != NO_ERROR) {\n                return (mError=err);\n            }\n\n            const size_t typeSpecSize = dtohl(typeSpec->header.size);\n            const size_t newEntryCount = dtohl(typeSpec->entryCount);\n\n            LOAD_TABLE_NOISY(printf(\"TypeSpec off %p: type=0x%x, headerSize=0x%x, size=%p\\n\",\n                                    (void*)(base-(const uint8_t*)chunk),\n                                    dtohs(typeSpec->header.type),\n                                    dtohs(typeSpec->header.headerSize),\n                                    (void*)typeSpecSize));\n            // look for block overrun or int overflow when multiplying by 4\n            if ((dtohl(typeSpec->entryCount) > (INT32_MAX/sizeof(uint32_t))\n                    || dtohs(typeSpec->header.headerSize)+(sizeof(uint32_t)*newEntryCount)\n                    > typeSpecSize)) {\n                ALOGW(\"ResTable_typeSpec entry index to %p extends beyond chunk end %p.\",\n                        (void*)(dtohs(typeSpec->header.headerSize) + (sizeof(uint32_t)*newEntryCount)),\n                        (void*)typeSpecSize);\n                return (mError=BAD_TYPE);\n            }\n\n            if (typeSpec->id == 0) {\n                ALOGW(\"ResTable_type has an id of 0.\");\n                return (mError=BAD_TYPE);\n            }\n\n            if (newEntryCount > 0) {\n                uint8_t typeIndex = typeSpec->id - 1;\n                ssize_t idmapIndex = idmapEntries.indexOfKey(typeSpec->id);\n                if (idmapIndex >= 0) {\n                    typeIndex = idmapEntries[idmapIndex].targetTypeId() - 1;\n                }\n\n                TypeList& typeList = group->types.editItemAt(typeIndex);\n                if (!typeList.isEmpty()) {\n                    const Type* existingType = typeList[0];\n                    if (existingType->entryCount != newEntryCount && idmapIndex < 0) {\n                        ALOGW(\"ResTable_typeSpec entry count inconsistent: given %d, previously %d\",\n                                (int) newEntryCount, (int) existingType->entryCount);\n                        // We should normally abort here, but some legacy apps declare\n                        // resources in the 'android' package (old bug in AAPT).\n                    }\n                }\n\n                Type* t = new Type(header, package, newEntryCount);\n                t->typeSpec = typeSpec;\n                t->typeSpecFlags = (const uint32_t*)(\n                        ((const uint8_t*)typeSpec) + dtohs(typeSpec->header.headerSize));\n                if (idmapIndex >= 0) {\n                    t->idmapEntries = idmapEntries[idmapIndex];\n                }\n                typeList.add(t);\n                group->largestTypeId = max(group->largestTypeId, typeSpec->id);\n            } else {\n                ALOGV(\"Skipping empty ResTable_typeSpec for type %d\", typeSpec->id);\n            }\n\n        } else if (ctype == RES_TABLE_TYPE_TYPE) {\n            const ResTable_type* type = (const ResTable_type*)(chunk);\n            err = validate_chunk(&type->header, sizeof(*type)-sizeof(ResTable_config)+4,\n                                 endPos, \"ResTable_type\");\n            if (err != NO_ERROR) {\n                return (mError=err);\n            }\n\n            const uint32_t typeSize = dtohl(type->header.size);\n            const size_t newEntryCount = dtohl(type->entryCount);\n\n            LOAD_TABLE_NOISY(printf(\"Type off %p: type=0x%x, headerSize=0x%x, size=%p\\n\",\n                                    (void*)(base-(const uint8_t*)chunk),\n                                    dtohs(type->header.type),\n                                    dtohs(type->header.headerSize),\n                                    (void*)typeSize));\n            if (dtohs(type->header.headerSize)+(sizeof(uint32_t)*newEntryCount)\n                    > typeSize) {\n                ALOGW(\"ResTable_type entry index to %p extends beyond chunk end 0x%x.\",\n                        (void*)(dtohs(type->header.headerSize) + (sizeof(uint32_t)*newEntryCount)),\n                        typeSize);\n                return (mError=BAD_TYPE);\n            }\n\n            if (newEntryCount != 0\n                && dtohl(type->entriesStart) > (typeSize-sizeof(ResTable_entry))) {\n                ALOGW(\"ResTable_type entriesStart at 0x%x extends beyond chunk end 0x%x. newEntryCount = %d\",\n                     dtohl(type->entriesStart), typeSize, newEntryCount);\n                return (mError=BAD_TYPE);\n            }\n\n            if (type->id == 0) {\n                ALOGW(\"ResTable_type has an id of 0.\");\n                return (mError=BAD_TYPE);\n            }\n\n            if (newEntryCount > 0) {\n                uint8_t typeIndex = type->id - 1;\n                ssize_t idmapIndex = idmapEntries.indexOfKey(type->id);\n                if (idmapIndex >= 0) {\n                    typeIndex = idmapEntries[idmapIndex].targetTypeId() - 1;\n                }\n\n                TypeList& typeList = group->types.editItemAt(typeIndex);\n                if (typeList.isEmpty()) {\n                    ALOGE(\"No TypeSpec for type %d\", type->id);\n                    return (mError=BAD_TYPE);\n                }\n\n                Type* t = typeList.editItemAt(typeList.size() - 1);\n                if (newEntryCount != t->entryCount) {\n                    ALOGE(\"ResTable_type entry count inconsistent: given %d, previously %d\",\n                        (int)newEntryCount, (int)t->entryCount);\n                    return (mError=BAD_TYPE);\n                }\n\n                if (t->package != package) {\n                    ALOGE(\"No TypeSpec for type %d\", type->id);\n                    return (mError=BAD_TYPE);\n                }\n\n                t->configs.add(type);\n\n                TABLE_GETENTRY(\n                    ResTable_config thisConfig;\n                    thisConfig.copyFromDtoH(type->config);\n                    ALOGI(\"Adding config to type %d: %s\\n\",\n                          type->id, thisConfig.toString().string()));\n            } else {\n                ALOGV(\"Skipping empty ResTable_type for type %d\", type->id);\n            }\n\n        } else if (ctype == RES_TABLE_LIBRARY_TYPE) {\n            if (group->dynamicRefTable.entries().size() == 0) {\n                status_t err = group->dynamicRefTable.load((const ResTable_lib_header*) chunk);\n                if (err != NO_ERROR) {\n                    return (mError=err);\n                }\n\n                // Fill in the reference table with the entries we already know about.\n                size_t N = mPackageGroups.size();\n                for (size_t i = 0; i < N; i++) {\n                    group->dynamicRefTable.addMapping(mPackageGroups[i]->name, mPackageGroups[i]->id);\n                }\n            } else {\n                ALOGW(\"Found multiple library tables, ignoring...\");\n            }\n        } else {\n            status_t err = validate_chunk(chunk, sizeof(ResChunk_header),\n                                          endPos, \"ResTable_package:unknown\");\n            if (err != NO_ERROR) {\n                return (mError=err);\n            }\n        }\n        chunk = (const ResChunk_header*)\n            (((const uint8_t*)chunk) + csize);\n    }\n\n    return NO_ERROR;\n}\n\nDynamicRefTable::DynamicRefTable(uint8_t packageId)\n    : mAssignedPackageId(packageId)\n{\n    memset(mLookupTable, 0, sizeof(mLookupTable));\n\n    // Reserved package ids\n    mLookupTable[customePackageId] = customePackageId;\n    mLookupTable[SYS_PACKAGE_ID] = SYS_PACKAGE_ID;\n    mLookupTable[APP_PACKAGE_ID] = APP_PACKAGE_ID;\n}\n\nstatus_t DynamicRefTable::load(const ResTable_lib_header* const header)\n{\n    const uint32_t entryCount = dtohl(header->count);\n    const uint32_t sizeOfEntries = sizeof(ResTable_lib_entry) * entryCount;\n    const uint32_t expectedSize = dtohl(header->header.size) - dtohl(header->header.headerSize);\n    if (sizeOfEntries > expectedSize) {\n        ALOGE(\"ResTable_lib_header size %u is too small to fit %u entries (x %u).\",\n                expectedSize, entryCount, (uint32_t)sizeof(ResTable_lib_entry));\n        return UNKNOWN_ERROR;\n    }\n\n    const ResTable_lib_entry* entry = (const ResTable_lib_entry*)(((uint8_t*) header) +\n            dtohl(header->header.headerSize));\n    for (uint32_t entryIndex = 0; entryIndex < entryCount; entryIndex++) {\n        uint32_t packageId = dtohl(entry->packageId);\n        char16_t tmpName[sizeof(entry->packageName) / sizeof(char16_t)];\n        strcpy16_dtoh(tmpName, entry->packageName, sizeof(entry->packageName) / sizeof(char16_t));\n        LIB_NOISY(ALOGV(\"Found lib entry %s with id %d\\n\", String8(tmpName).string(),\n                dtohl(entry->packageId)));\n        if (packageId >= 256) {\n            ALOGE(\"Bad package id 0x%08x\", packageId);\n            return UNKNOWN_ERROR;\n        }\n        mEntries.replaceValueFor(String16(tmpName), (uint8_t) packageId);\n        entry = entry + 1;\n    }\n    return NO_ERROR;\n}\n\nstatus_t DynamicRefTable::addMappings(const DynamicRefTable& other) {\n    if (mAssignedPackageId != other.mAssignedPackageId) {\n        return UNKNOWN_ERROR;\n    }\n\n    const size_t entryCount = other.mEntries.size();\n    for (size_t i = 0; i < entryCount; i++) {\n        ssize_t index = mEntries.indexOfKey(other.mEntries.keyAt(i));\n        if (index < 0) {\n            mEntries.add(other.mEntries.keyAt(i), other.mEntries[i]);\n        } else {\n            if (other.mEntries[i] != mEntries[index]) {\n                return UNKNOWN_ERROR;\n            }\n        }\n    }\n\n    // Merge the lookup table. No entry can conflict\n    // (value of 0 means not set).\n    for (size_t i = 0; i < 256; i++) {\n        if (mLookupTable[i] != other.mLookupTable[i]) {\n            if (mLookupTable[i] == 0) {\n                mLookupTable[i] = other.mLookupTable[i];\n            } else if (other.mLookupTable[i] != 0) {\n                return UNKNOWN_ERROR;\n            }\n        }\n    }\n    return NO_ERROR;\n}\n\nstatus_t DynamicRefTable::addMapping(const String16& packageName, uint8_t packageId)\n{\n    ssize_t index = mEntries.indexOfKey(packageName);\n    if (index < 0) {\n        return UNKNOWN_ERROR;\n    }\n    mLookupTable[mEntries.valueAt(index)] = packageId;\n    return NO_ERROR;\n}\n\nstatus_t DynamicRefTable::lookupResourceId(uint32_t* resId) const {\n    uint32_t res = *resId;\n    size_t packageId = Res_GETPACKAGE(res) + 1;\n\n    if (packageId == customePackageId || packageId == 0x7f) {\n        // No lookup needs to be done, app package IDs are absolute.\n        return NO_ERROR;\n    }\n\n    if (packageId == 0) {\n        // The package ID is 0x00. That means that a shared library is accessing\n        // its own local resource, so we fix up the resource with the calling\n        // package ID.\n        *resId |= ((uint32_t) mAssignedPackageId) << 24;\n        return NO_ERROR;\n    }\n\n    // Do a proper lookup.\n    uint8_t translatedId = mLookupTable[packageId];\n    if (translatedId == 0) {\n        ALOGE(\"DynamicRefTable(0x%02x): No mapping for build-time package ID 0x%02x.\",\n                (uint8_t)mAssignedPackageId, (uint8_t)packageId);\n        for (size_t i = 0; i < 256; i++) {\n            if (mLookupTable[i] != 0) {\n                ALOGE(\"e[0x%02x] -> 0x%02x\", (uint8_t)i, mLookupTable[i]);\n            }\n        }\n        return UNKNOWN_ERROR;\n    }\n\n    *resId = (res & 0x00ffffff) | (((uint32_t) translatedId) << 24);\n    return NO_ERROR;\n}\n\nstatus_t DynamicRefTable::lookupResourceValue(Res_value* value) const {\n    if (value->dataType != Res_value::TYPE_DYNAMIC_REFERENCE) {\n        return NO_ERROR;\n    }\n\n    status_t err = lookupResourceId(&value->data);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    value->dataType = Res_value::TYPE_REFERENCE;\n    return NO_ERROR;\n}\n\nstruct IdmapTypeMap {\n    ssize_t overlayTypeId;\n    size_t entryOffset;\n    Vector<uint32_t> entryMap;\n};\n\nstatus_t ResTable::createIdmap(const ResTable& overlay,\n        uint32_t targetCrc, uint32_t overlayCrc,\n        const char* targetPath, const char* overlayPath,\n        void** outData, size_t* outSize) const\n{\n    // see README for details on the format of map\n    if (mPackageGroups.size() == 0) {\n        ALOGW(\"idmap: target package has no package groups, cannot create idmap\\n\");\n        return UNKNOWN_ERROR;\n    }\n\n    if (mPackageGroups[0]->packages.size() == 0) {\n        ALOGW(\"idmap: target package has no packages in its first package group, \"\n                \"cannot create idmap\\n\");\n        return UNKNOWN_ERROR;\n    }\n\n    KeyedVector<uint8_t, IdmapTypeMap> map;\n\n    // overlaid packages are assumed to contain only one package group\n    const PackageGroup* pg = mPackageGroups[0];\n\n    // starting size is header\n    *outSize = ResTable::IDMAP_HEADER_SIZE_BYTES;\n\n    // target package id and number of types in map\n    *outSize += 2 * sizeof(uint16_t);\n\n    // overlay packages are assumed to contain only one package group\n    const String16 overlayPackage(overlay.mPackageGroups[0]->packages[0]->package->name);\n\n    for (size_t typeIndex = 0; typeIndex < pg->types.size(); ++typeIndex) {\n        const TypeList& typeList = pg->types[typeIndex];\n        if (typeList.isEmpty()) {\n            continue;\n        }\n\n        const Type* typeConfigs = typeList[0];\n\n        IdmapTypeMap typeMap;\n        typeMap.overlayTypeId = -1;\n        typeMap.entryOffset = 0;\n\n        for (size_t entryIndex = 0; entryIndex < typeConfigs->entryCount; ++entryIndex) {\n            uint32_t resID = Res_MAKEID(pg->id - 1, typeIndex, entryIndex);\n            resource_name resName;\n            if (!this->getResourceName(resID, false, &resName)) {\n                if (typeMap.entryMap.isEmpty()) {\n                    typeMap.entryOffset++;\n                }\n                continue;\n            }\n\n            const String16 overlayType(resName.type, resName.typeLen);\n            const String16 overlayName(resName.name, resName.nameLen);\n            uint32_t overlayResID = overlay.identifierForName(overlayName.string(),\n                                                              overlayName.size(),\n                                                              overlayType.string(),\n                                                              overlayType.size(),\n                                                              overlayPackage.string(),\n                                                              overlayPackage.size());\n            if (overlayResID == 0) {\n                if (typeMap.entryMap.isEmpty()) {\n                    typeMap.entryOffset++;\n                }\n                continue;\n            }\n\n            if (typeMap.overlayTypeId == -1) {\n                typeMap.overlayTypeId = Res_GETTYPE(overlayResID) + 1;\n            }\n\n            if (Res_GETTYPE(overlayResID) + 1 != static_cast<size_t>(typeMap.overlayTypeId)) {\n                ALOGE(\"idmap: can't mix type ids in entry map. Resource 0x%08x maps to 0x%08x\"\n                        \" but entries should map to resources of type %02x\",\n                        resID, overlayResID, typeMap.overlayTypeId);\n                return BAD_TYPE;\n            }\n\n            if (typeMap.entryOffset + typeMap.entryMap.size() < entryIndex) {\n                // Resize to accomodate this entry and the 0's in between.\n                if (typeMap.entryMap.resize((entryIndex - typeMap.entryOffset) + 1) < 0) {\n                    return NO_MEMORY;\n                }\n                typeMap.entryMap.editTop() = Res_GETENTRY(overlayResID);\n            } else {\n                typeMap.entryMap.add(Res_GETENTRY(overlayResID));\n            }\n        }\n\n        if (!typeMap.entryMap.isEmpty()) {\n            if (map.add(static_cast<uint8_t>(typeIndex), typeMap) < 0) {\n                return NO_MEMORY;\n            }\n            *outSize += (4 * sizeof(uint16_t)) + (typeMap.entryMap.size() * sizeof(uint32_t));\n        }\n    }\n\n    if (map.isEmpty()) {\n        ALOGW(\"idmap: no resources in overlay package present in base package\");\n        return UNKNOWN_ERROR;\n    }\n\n    if ((*outData = malloc(*outSize)) == NULL) {\n        return NO_MEMORY;\n    }\n\n    uint32_t* data = (uint32_t*)*outData;\n    *data++ = htodl(IDMAP_MAGIC);\n    *data++ = htodl(IDMAP_CURRENT_VERSION);\n    *data++ = htodl(targetCrc);\n    *data++ = htodl(overlayCrc);\n    const char* paths[] = { targetPath, overlayPath };\n    for (int j = 0; j < 2; ++j) {\n        char* p = (char*)data;\n        const char* path = paths[j];\n        const size_t I = strlen(path);\n        if (I > 255) {\n            ALOGV(\"path exceeds expected 255 characters: %s\\n\", path);\n            return UNKNOWN_ERROR;\n        }\n        for (size_t i = 0; i < 256; ++i) {\n            *p++ = i < I ? path[i] : '\\0';\n        }\n        data += 256 / sizeof(uint32_t);\n    }\n    const size_t mapSize = map.size();\n    uint16_t* typeData = reinterpret_cast<uint16_t*>(data);\n    *typeData++ = htods(pg->id);\n    *typeData++ = htods(mapSize);\n    for (size_t i = 0; i < mapSize; ++i) {\n        uint8_t targetTypeId = map.keyAt(i);\n        const IdmapTypeMap& typeMap = map[i];\n        *typeData++ = htods(targetTypeId + 1);\n        *typeData++ = htods(typeMap.overlayTypeId);\n        *typeData++ = htods(typeMap.entryMap.size());\n        *typeData++ = htods(typeMap.entryOffset);\n\n        const size_t entryCount = typeMap.entryMap.size();\n        uint32_t* entries = reinterpret_cast<uint32_t*>(typeData);\n        for (size_t j = 0; j < entryCount; j++) {\n            entries[j] = htodl(typeMap.entryMap[j]);\n        }\n        typeData += entryCount * 2;\n    }\n\n    return NO_ERROR;\n}\n\nbool ResTable::getIdmapInfo(const void* idmap, size_t sizeBytes,\n                            uint32_t* pVersion,\n                            uint32_t* pTargetCrc, uint32_t* pOverlayCrc,\n                            String8* pTargetPath, String8* pOverlayPath)\n{\n    const uint32_t* map = (const uint32_t*)idmap;\n    if (!assertIdmapHeader(map, sizeBytes)) {\n        return false;\n    }\n    if (pVersion) {\n        *pVersion = dtohl(map[1]);\n    }\n    if (pTargetCrc) {\n        *pTargetCrc = dtohl(map[2]);\n    }\n    if (pOverlayCrc) {\n        *pOverlayCrc = dtohl(map[3]);\n    }\n    if (pTargetPath) {\n        pTargetPath->setTo(reinterpret_cast<const char*>(map + 4));\n    }\n    if (pOverlayPath) {\n        pOverlayPath->setTo(reinterpret_cast<const char*>(map + 4 + 256 / sizeof(uint32_t)));\n    }\n    return true;\n}\n\n\n#define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string())\n\n#define CHAR16_ARRAY_EQ(constant, var, len) \\\n        ((len == (sizeof(constant)/sizeof(constant[0]))) && (0 == memcmp((var), (constant), (len))))\n\nstatic void print_complex(uint32_t complex, bool isFraction)\n{\n    const float MANTISSA_MULT =\n        1.0f / (1<<Res_value::COMPLEX_MANTISSA_SHIFT);\n    const float RADIX_MULTS[] = {\n        1.0f*MANTISSA_MULT, 1.0f/(1<<7)*MANTISSA_MULT,\n        1.0f/(1<<15)*MANTISSA_MULT, 1.0f/(1<<23)*MANTISSA_MULT\n    };\n\n    float value = (complex&(Res_value::COMPLEX_MANTISSA_MASK\n                   <<Res_value::COMPLEX_MANTISSA_SHIFT))\n            * RADIX_MULTS[(complex>>Res_value::COMPLEX_RADIX_SHIFT)\n                            & Res_value::COMPLEX_RADIX_MASK];\n    printf(\"%f\", value);\n\n    if (!isFraction) {\n        switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) {\n            case Res_value::COMPLEX_UNIT_PX: printf(\"px\"); break;\n            case Res_value::COMPLEX_UNIT_DIP: printf(\"dp\"); break;\n            case Res_value::COMPLEX_UNIT_SP: printf(\"sp\"); break;\n            case Res_value::COMPLEX_UNIT_PT: printf(\"pt\"); break;\n            case Res_value::COMPLEX_UNIT_IN: printf(\"in\"); break;\n            case Res_value::COMPLEX_UNIT_MM: printf(\"mm\"); break;\n            default: printf(\" (unknown unit)\"); break;\n        }\n    } else {\n        switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) {\n            case Res_value::COMPLEX_UNIT_FRACTION: printf(\"%%\"); break;\n            case Res_value::COMPLEX_UNIT_FRACTION_PARENT: printf(\"%%p\"); break;\n            default: printf(\" (unknown unit)\"); break;\n        }\n    }\n}\n\n// Normalize a string for output\nString8 ResTable::normalizeForOutput( const char *input )\n{\n    String8 ret;\n    char buff[2];\n    buff[1] = '\\0';\n\n    while (*input != '\\0') {\n        switch (*input) {\n            // All interesting characters are in the ASCII zone, so we are making our own lives\n            // easier by scanning the string one byte at a time.\n        case '\\\\':\n            ret += \"\\\\\\\\\";\n            break;\n        case '\\n':\n            ret += \"\\\\n\";\n            break;\n        case '\"':\n            ret += \"\\\\\\\"\";\n            break;\n        default:\n            buff[0] = *input;\n            ret += buff;\n            break;\n        }\n\n        input++;\n    }\n\n    return ret;\n}\n\nvoid ResTable::print_value(const Package* pkg, const Res_value& value) const\n{\n    if (value.dataType == Res_value::TYPE_NULL) {\n        printf(\"(null)\\n\");\n    } else if (value.dataType == Res_value::TYPE_REFERENCE) {\n        printf(\"(reference) 0x%08x\\n\", value.data);\n    } else if (value.dataType == Res_value::TYPE_DYNAMIC_REFERENCE) {\n        printf(\"(dynamic reference) 0x%08x\\n\", value.data);\n    } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) {\n        printf(\"(attribute) 0x%08x\\n\", value.data);\n    } else if (value.dataType == Res_value::TYPE_STRING) {\n        size_t len;\n        const char* str8 = pkg->header->values.string8At(\n                value.data, &len);\n        if (str8 != NULL) {\n            printf(\"(string8) \\\"%s\\\"\\n\", normalizeForOutput(str8).string());\n        } else {\n            const char16_t* str16 = pkg->header->values.stringAt(\n                    value.data, &len);\n            if (str16 != NULL) {\n                printf(\"(string16) \\\"%s\\\"\\n\",\n                    normalizeForOutput(String8(str16, len).string()).string());\n            } else {\n                printf(\"(string) null\\n\");\n            }\n        }\n    } else if (value.dataType == Res_value::TYPE_FLOAT) {\n        printf(\"(float) %g\\n\", *(const float*)&value.data);\n    } else if (value.dataType == Res_value::TYPE_DIMENSION) {\n        printf(\"(dimension) \");\n        print_complex(value.data, false);\n        printf(\"\\n\");\n    } else if (value.dataType == Res_value::TYPE_FRACTION) {\n        printf(\"(fraction) \");\n        print_complex(value.data, true);\n        printf(\"\\n\");\n    } else if (value.dataType >= Res_value::TYPE_FIRST_COLOR_INT\n            || value.dataType <= Res_value::TYPE_LAST_COLOR_INT) {\n        printf(\"(color) #%08x\\n\", value.data);\n    } else if (value.dataType == Res_value::TYPE_INT_BOOLEAN) {\n        printf(\"(boolean) %s\\n\", value.data ? \"true\" : \"false\");\n    } else if (value.dataType >= Res_value::TYPE_FIRST_INT\n            || value.dataType <= Res_value::TYPE_LAST_INT) {\n        printf(\"(int) 0x%08x or %d\\n\", value.data, value.data);\n    } else {\n        printf(\"(unknown type) t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)\\n\",\n               (int)value.dataType, (int)value.data,\n               (int)value.size, (int)value.res0);\n    }\n}\n\nvoid ResTable::print(bool inclValues) const\n{\n    if (mError != 0) {\n        printf(\"mError=0x%x (%s)\\n\", mError, strerror(mError));\n    }\n    size_t pgCount = mPackageGroups.size();\n    printf(\"Package Groups (%d)\\n\", (int)pgCount);\n    for (size_t pgIndex=0; pgIndex<pgCount; pgIndex++) {\n        const PackageGroup* pg = mPackageGroups[pgIndex];\n        printf(\"Package Group %d id=0x%02x packageCount=%d name=%s\\n\",\n                (int)pgIndex, pg->id, (int)pg->packages.size(),\n                String8(pg->name).string());\n\n        const KeyedVector<String16, uint8_t>& refEntries = pg->dynamicRefTable.entries();\n        const size_t refEntryCount = refEntries.size();\n        if (refEntryCount > 0) {\n            printf(\"  DynamicRefTable entryCount=%d:\\n\", (int) refEntryCount);\n            for (size_t refIndex = 0; refIndex < refEntryCount; refIndex++) {\n                printf(\"    0x%02x -> %s\\n\",\n                        refEntries.valueAt(refIndex),\n                        String8(refEntries.keyAt(refIndex)).string());\n            }\n            printf(\"\\n\");\n        }\n\n        int packageId = pg->id;\n        size_t pkgCount = pg->packages.size();\n        for (size_t pkgIndex=0; pkgIndex<pkgCount; pkgIndex++) {\n            const Package* pkg = pg->packages[pkgIndex];\n            // Use a package's real ID, since the ID may have been assigned\n            // if this package is a shared library.\n            packageId = pkg->package->id;\n            printf(\"  Package %d id=0x%02x name=%s\\n\", (int)pkgIndex,\n                    pkg->package->id, String8(String16(pkg->package->name)).string());\n        }\n\n        for (size_t typeIndex=0; typeIndex < pg->types.size(); typeIndex++) {\n            const TypeList& typeList = pg->types[typeIndex];\n            if (typeList.isEmpty()) {\n                continue;\n            }\n            const Type* typeConfigs = typeList[0];\n            const size_t NTC = typeConfigs->configs.size();\n            printf(\"    type %d configCount=%d entryCount=%d\\n\",\n                   (int)typeIndex, (int)NTC, (int)typeConfigs->entryCount);\n            if (typeConfigs->typeSpecFlags != NULL) {\n                for (size_t entryIndex=0; entryIndex<typeConfigs->entryCount; entryIndex++) {\n                    uint32_t resID = (0xff000000 & ((packageId)<<24))\n                                | (0x00ff0000 & ((typeIndex+1)<<16))\n                                | (0x0000ffff & (entryIndex));\n                    // Since we are creating resID without actually\n                    // iterating over them, we have no idea which is a\n                    // dynamic reference. We must check.\n                    if (packageId == 0) {\n                        pg->dynamicRefTable.lookupResourceId(&resID);\n                    }\n\n                    resource_name resName;\n                    if (this->getResourceName(resID, true, &resName)) {\n                        String8 type8;\n                        String8 name8;\n                        if (resName.type8 != NULL) {\n                            type8 = String8(resName.type8, resName.typeLen);\n                        } else {\n                            type8 = String8(resName.type, resName.typeLen);\n                        }\n                        if (resName.name8 != NULL) {\n                            name8 = String8(resName.name8, resName.nameLen);\n                        } else {\n                            name8 = String8(resName.name, resName.nameLen);\n                        }\n                        printf(\"      spec resource 0x%08x %s:%s/%s: flags=0x%08x\\n\",\n                            resID,\n                            CHAR16_TO_CSTR(resName.package, resName.packageLen),\n                            type8.string(), name8.string(),\n                            dtohl(typeConfigs->typeSpecFlags[entryIndex]));\n                    } else {\n                        printf(\"      INVALID TYPE CONFIG FOR RESOURCE 0x%08x\\n\", resID);\n                    }\n                }\n            }\n            for (size_t configIndex=0; configIndex<NTC; configIndex++) {\n                const ResTable_type* type = typeConfigs->configs[configIndex];\n                if ((((uint64_t)type)&0x3) != 0) {\n                    printf(\"      NON-INTEGER ResTable_type ADDRESS: %p\\n\", type);\n                    continue;\n                }\n                String8 configStr = type->config.toString();\n                printf(\"      config %s:\\n\", configStr.size() > 0\n                        ? configStr.string() : \"(default)\");\n                size_t entryCount = dtohl(type->entryCount);\n                uint32_t entriesStart = dtohl(type->entriesStart);\n                if ((entriesStart&0x3) != 0) {\n                    printf(\"      NON-INTEGER ResTable_type entriesStart OFFSET: 0x%x\\n\", entriesStart);\n                    continue;\n                }\n                uint32_t typeSize = dtohl(type->header.size);\n                if ((typeSize&0x3) != 0) {\n                    printf(\"      NON-INTEGER ResTable_type header.size: 0x%x\\n\", typeSize);\n                    continue;\n                }\n                for (size_t entryIndex=0; entryIndex<entryCount; entryIndex++) {\n\n                    const uint8_t* const end = ((const uint8_t*)type)\n                        + dtohl(type->header.size);\n                    const uint32_t* const eindex = (const uint32_t*)\n                        (((const uint8_t*)type) + dtohs(type->header.headerSize));\n\n                    uint32_t thisOffset = dtohl(eindex[entryIndex]);\n                    if (thisOffset == ResTable_type::NO_ENTRY) {\n                        continue;\n                    }\n\n                    uint32_t resID = (0xff000000 & ((packageId)<<24))\n                                | (0x00ff0000 & ((typeIndex+1)<<16))\n                                | (0x0000ffff & (entryIndex));\n                    if (packageId == 0) {\n                        pg->dynamicRefTable.lookupResourceId(&resID);\n                    }\n                    resource_name resName;\n                    if (this->getResourceName(resID, true, &resName)) {\n                        String8 type8;\n                        String8 name8;\n                        if (resName.type8 != NULL) {\n                            type8 = String8(resName.type8, resName.typeLen);\n                        } else {\n                            type8 = String8(resName.type, resName.typeLen);\n                        }\n                        if (resName.name8 != NULL) {\n                            name8 = String8(resName.name8, resName.nameLen);\n                        } else {\n                            name8 = String8(resName.name, resName.nameLen);\n                        }\n                        printf(\"        resource 0x%08x %s:%s/%s: \", resID,\n                                CHAR16_TO_CSTR(resName.package, resName.packageLen),\n                                type8.string(), name8.string());\n                    } else {\n                        printf(\"        INVALID RESOURCE 0x%08x: \", resID);\n                    }\n                    if ((thisOffset&0x3) != 0) {\n                        printf(\"NON-INTEGER OFFSET: 0x%x\\n\", thisOffset);\n                        continue;\n                    }\n                    if ((thisOffset+sizeof(ResTable_entry)) > typeSize) {\n                        printf(\"OFFSET OUT OF BOUNDS: 0x%x+0x%x (size is 0x%x)\\n\",\n                               entriesStart, thisOffset, typeSize);\n                        continue;\n                    }\n\n                    const ResTable_entry* ent = (const ResTable_entry*)\n                        (((const uint8_t*)type) + entriesStart + thisOffset);\n                    if (((entriesStart + thisOffset)&0x3) != 0) {\n                        printf(\"NON-INTEGER ResTable_entry OFFSET: 0x%x\\n\",\n                             (entriesStart + thisOffset));\n                        continue;\n                    }\n\n                    uintptr_t esize = dtohs(ent->size);\n                    if ((esize&0x3) != 0) {\n                        printf(\"NON-INTEGER ResTable_entry SIZE: %p\\n\", (void *)esize);\n                        continue;\n                    }\n                    if ((thisOffset+esize) > typeSize) {\n                        printf(\"ResTable_entry OUT OF BOUNDS: 0x%x+0x%x+%p (size is 0x%x)\\n\",\n                               entriesStart, thisOffset, (void *)esize, typeSize);\n                        continue;\n                    }\n\n                    const Res_value* valuePtr = NULL;\n                    const ResTable_map_entry* bagPtr = NULL;\n                    Res_value value;\n                    if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) {\n                        printf(\"<bag>\");\n                        bagPtr = (const ResTable_map_entry*)ent;\n                    } else {\n                        valuePtr = (const Res_value*)\n                            (((const uint8_t*)ent) + esize);\n                        value.copyFrom_dtoh(*valuePtr);\n                        printf(\"t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)\",\n                               (int)value.dataType, (int)value.data,\n                               (int)value.size, (int)value.res0);\n                    }\n\n                    if ((dtohs(ent->flags)&ResTable_entry::FLAG_PUBLIC) != 0) {\n                        printf(\" (PUBLIC)\");\n                    }\n                    printf(\"\\n\");\n\n                    if (inclValues) {\n                        if (valuePtr != NULL) {\n                            printf(\"          \");\n                            print_value(typeConfigs->package, value);\n                        } else if (bagPtr != NULL) {\n                            const int N = dtohl(bagPtr->count);\n                            const uint8_t* baseMapPtr = (const uint8_t*)ent;\n                            size_t mapOffset = esize;\n                            const ResTable_map* mapPtr = (ResTable_map*)(baseMapPtr+mapOffset);\n                            const uint32_t parent = dtohl(bagPtr->parent.ident);\n                            uint32_t resolvedParent = parent;\n                            if (Res_GETPACKAGE(resolvedParent) + 1 == 0) {\n                                status_t err = pg->dynamicRefTable.lookupResourceId(&resolvedParent);\n                                if (err != NO_ERROR) {\n                                    resolvedParent = 0;\n                                }\n                            }\n                            printf(\"          Parent=0x%08x(Resolved=0x%08x), Count=%d\\n\",\n                                    parent, resolvedParent, N);\n                            for (int i=0; i<N && mapOffset < (typeSize-sizeof(ResTable_map)); i++) {\n                                printf(\"          #%i (Key=0x%08x): \",\n                                    i, dtohl(mapPtr->name.ident));\n                                value.copyFrom_dtoh(mapPtr->value);\n                                print_value(typeConfigs->package, value);\n                                const size_t size = dtohs(mapPtr->value.size);\n                                mapOffset += size + sizeof(*mapPtr)-sizeof(mapPtr->value);\n                                mapPtr = (ResTable_map*)(baseMapPtr+mapOffset);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nKeyedVector<uint32_t, ResTable::resource_name> ResTable::getResourceEntries() const\n{\n    /* if (mError != 0) {\n        printf(\"mError=0x%x (%s)\\n\", mError, strerror(mError));\n    } */\n    KeyedVector<uint32_t, resource_name> resourceEntries;\n    size_t pgCount = mPackageGroups.size();\n    // printf(\"Package Groups (%d)\\n\", (int)pgCount);\n    for (size_t pgIndex=0; pgIndex<pgCount; pgIndex++) {\n        const PackageGroup* pg = mPackageGroups[pgIndex];\n        /* printf(\"Package Group %d id=0x%02x packageCount=%d name=%s\\n\",\n                (int)pgIndex, pg->id, (int)pg->packages.size(),\n                String8(pg->name).string()); */\n\n        /* const KeyedVector<String16, uint8_t>& refEntries = pg->dynamicRefTable.entries();\n        const size_t refEntryCount = refEntries.size();\n        if (refEntryCount > 0) {\n            printf(\"  DynamicRefTable entryCount=%d:\\n\", (int) refEntryCount);\n            for (size_t refIndex = 0; refIndex < refEntryCount; refIndex++) {\n                printf(\"    0x%02x -> %s\\n\",\n                        refEntries.valueAt(refIndex),\n                        String8(refEntries.keyAt(refIndex)).string());\n            }\n            printf(\"\\n\");\n        } */\n\n        int packageId = pg->id;\n        size_t pkgCount = pg->packages.size();\n        for (size_t pkgIndex=0; pkgIndex<pkgCount; pkgIndex++) {\n            const Package* pkg = pg->packages[pkgIndex];\n            // Use a package's real ID, since the ID may have been assigned\n            // if this package is a shared library.\n            packageId = pkg->package->id;\n            /* printf(\"  Package %d id=0x%02x name=%s\\n\", (int)pkgIndex,\n                    pkg->package->id, String8(String16(pkg->package->name)).string()); */\n        }\n\n        for (size_t typeIndex=0; typeIndex < pg->types.size(); typeIndex++) {\n            const TypeList& typeList = pg->types[typeIndex];\n            if (typeList.isEmpty()) {\n                continue;\n            }\n            const Type* typeConfigs = typeList[0];\n            const size_t NTC = typeConfigs->configs.size();\n            /* printf(\"    type %d configCount=%d entryCount=%d\\n\",\n                   (int)typeIndex, (int)NTC, (int)typeConfigs->entryCount); */\n            if (typeConfigs->typeSpecFlags != NULL) {\n                for (size_t entryIndex=0; entryIndex<typeConfigs->entryCount; entryIndex++) {\n                    uint32_t resID = (0xff000000 & ((packageId)<<24))\n                                | (0x00ff0000 & ((typeIndex+1)<<16))\n                                | (0x0000ffff & (entryIndex));\n                    // Since we are creating resID without actually\n                    // iterating over them, we have no idea which is a\n                    // dynamic reference. We must check.\n                    if (packageId == 0) {\n                        pg->dynamicRefTable.lookupResourceId(&resID);\n                    }\n\n                    resource_name resName;\n                    if (this->getResourceName(resID, true, &resName)) {\n                        resourceEntries.add(resID, resName);\n                        /* String8 type8;\n                        String8 name8;\n                        if (resName.type8 != NULL) {\n                            type8 = String8(resName.type8, resName.typeLen);\n                        } else {\n                            type8 = String8(resName.type, resName.typeLen);\n                        }\n                        if (resName.name8 != NULL) {\n                            name8 = String8(resName.name8, resName.nameLen);\n                        } else {\n                            name8 = String8(resName.name, resName.nameLen);\n                        }\n                        printf(\"      spec resource 0x%08x %s:%s/%s: flags=0x%08x\\n\",\n                            resID,\n                            CHAR16_TO_CSTR(resName.package, resName.packageLen),\n                            type8.string(), name8.string(),\n                            dtohl(typeConfigs->typeSpecFlags[entryIndex]));  */\n                    } else {\n                        printf(\"      INVALID TYPE CONFIG FOR RESOURCE 0x%08x\\n\", resID);\n                    }\n                }\n            }\n            /* for (size_t configIndex=0; configIndex<NTC; configIndex++) {\n                const ResTable_type* type = typeConfigs->configs[configIndex];\n                if ((((uint64_t)type)&0x3) != 0) {\n                    printf(\"      NON-INTEGER ResTable_type ADDRESS: %p\\n\", type);\n                    continue;\n                }\n                String8 configStr = type->config.toString();\n                printf(\"      config %s:\\n\", configStr.size() > 0\n                        ? configStr.string() : \"(default)\");\n                size_t entryCount = dtohl(type->entryCount);\n                uint32_t entriesStart = dtohl(type->entriesStart);\n                if ((entriesStart&0x3) != 0) {\n                    printf(\"      NON-INTEGER ResTable_type entriesStart OFFSET: 0x%x\\n\", entriesStart);\n                    continue;\n                }\n                uint32_t typeSize = dtohl(type->header.size);\n                if ((typeSize&0x3) != 0) {\n                    printf(\"      NON-INTEGER ResTable_type header.size: 0x%x\\n\", typeSize);\n                    continue;\n                }\n                for (size_t entryIndex=0; entryIndex<entryCount; entryIndex++) {\n\n                    const uint8_t* const end = ((const uint8_t*)type)\n                        + dtohl(type->header.size);\n                    const uint32_t* const eindex = (const uint32_t*)\n                        (((const uint8_t*)type) + dtohs(type->header.headerSize));\n\n                    uint32_t thisOffset = dtohl(eindex[entryIndex]);\n                    if (thisOffset == ResTable_type::NO_ENTRY) {\n                        continue;\n                    }\n\n                    uint32_t resID = (0xff000000 & ((packageId)<<24))\n                                | (0x00ff0000 & ((typeIndex+1)<<16))\n                                | (0x0000ffff & (entryIndex));\n                    if (packageId == 0) {\n                        pg->dynamicRefTable.lookupResourceId(&resID);\n                    }\n                    resource_name resName;\n                    if (this->getResourceName(resID, true, &resName)) {\n                        String8 type8;\n                        String8 name8;\n                        if (resName.type8 != NULL) {\n                            type8 = String8(resName.type8, resName.typeLen);\n                        } else {\n                            type8 = String8(resName.type, resName.typeLen);\n                        }\n                        if (resName.name8 != NULL) {\n                            name8 = String8(resName.name8, resName.nameLen);\n                        } else {\n                            name8 = String8(resName.name, resName.nameLen);\n                        }\n                        printf(\"        resource 0x%08x %s:%s/%s: \", resID,\n                                CHAR16_TO_CSTR(resName.package, resName.packageLen),\n                                type8.string(), name8.string());\n                    } else {\n                        printf(\"        INVALID RESOURCE 0x%08x: \", resID);\n                    }\n                    if ((thisOffset&0x3) != 0) {\n                        printf(\"NON-INTEGER OFFSET: 0x%x\\n\", thisOffset);\n                        continue;\n                    }\n                    if ((thisOffset+sizeof(ResTable_entry)) > typeSize) {\n                        printf(\"OFFSET OUT OF BOUNDS: 0x%x+0x%x (size is 0x%x)\\n\",\n                               entriesStart, thisOffset, typeSize);\n                        continue;\n                    }\n\n                    const ResTable_entry* ent = (const ResTable_entry*)\n                        (((const uint8_t*)type) + entriesStart + thisOffset);\n                    if (((entriesStart + thisOffset)&0x3) != 0) {\n                        printf(\"NON-INTEGER ResTable_entry OFFSET: 0x%x\\n\",\n                             (entriesStart + thisOffset));\n                        continue;\n                    }\n\n                    uintptr_t esize = dtohs(ent->size);\n                    if ((esize&0x3) != 0) {\n                        printf(\"NON-INTEGER ResTable_entry SIZE: %p\\n\", (void *)esize);\n                        continue;\n                    }\n                    if ((thisOffset+esize) > typeSize) {\n                        printf(\"ResTable_entry OUT OF BOUNDS: 0x%x+0x%x+%p (size is 0x%x)\\n\",\n                               entriesStart, thisOffset, (void *)esize, typeSize);\n                        continue;\n                    }\n\n                    const Res_value* valuePtr = NULL;\n                    const ResTable_map_entry* bagPtr = NULL;\n                    Res_value value;\n                    if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) {\n                        printf(\"<bag>\");\n                        bagPtr = (const ResTable_map_entry*)ent;\n                    } else {\n                        valuePtr = (const Res_value*)\n                            (((const uint8_t*)ent) + esize);\n                        value.copyFrom_dtoh(*valuePtr);\n                        printf(\"t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)\",\n                               (int)value.dataType, (int)value.data,\n                               (int)value.size, (int)value.res0);\n                    }\n\n                    if ((dtohs(ent->flags)&ResTable_entry::FLAG_PUBLIC) != 0) {\n                        printf(\" (PUBLIC)\");\n                    }\n                    printf(\"\\n\");\n\n                    if (inclValues) {\n                        if (valuePtr != NULL) {\n                            printf(\"          \");\n                            print_value(typeConfigs->package, value);\n                        } else if (bagPtr != NULL) {\n                            const int N = dtohl(bagPtr->count);\n                            const uint8_t* baseMapPtr = (const uint8_t*)ent;\n                            size_t mapOffset = esize;\n                            const ResTable_map* mapPtr = (ResTable_map*)(baseMapPtr+mapOffset);\n                            const uint32_t parent = dtohl(bagPtr->parent.ident);\n                            uint32_t resolvedParent = parent;\n                            if (Res_GETPACKAGE(resolvedParent) + 1 == 0) {\n                                status_t err = pg->dynamicRefTable.lookupResourceId(&resolvedParent);\n                                if (err != NO_ERROR) {\n                                    resolvedParent = 0;\n                                }\n                            }\n                            printf(\"          Parent=0x%08x(Resolved=0x%08x), Count=%d\\n\",\n                                    parent, resolvedParent, N);\n                            for (int i=0; i<N && mapOffset < (typeSize-sizeof(ResTable_map)); i++) {\n                                printf(\"          #%i (Key=0x%08x): \",\n                                    i, dtohl(mapPtr->name.ident));\n                                value.copyFrom_dtoh(mapPtr->value);\n                                print_value(typeConfigs->package, value);\n                                const size_t size = dtohs(mapPtr->value.size);\n                                mapOffset += size + sizeof(*mapPtr)-sizeof(mapPtr->value);\n                                mapPtr = (ResTable_map*)(baseMapPtr+mapOffset);\n                            }\n                        }\n                    }\n                }\n            } */\n        }\n    }\n    return resourceEntries;\n}\n\n}   // namespace android\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/StreamingZipInflater.cpp",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//#define LOG_NDEBUG 0\n#define LOG_TAG \"szipinf\"\n#include <utils/Log.h>\n\n#include <androidfw/StreamingZipInflater.h>\n#include <utils/FileMap.h>\n#include <string.h>\n#include <stddef.h>\n#include <assert.h>\n#include <unistd.h>\n#include <errno.h>\n\n/*\n * TEMP_FAILURE_RETRY is defined by some, but not all, versions of\n * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's\n * not already defined, then define it here.\n */\n#ifndef TEMP_FAILURE_RETRY\n/* Used to retry syscalls that can return EINTR. */\n#define TEMP_FAILURE_RETRY(exp) ({         \\\n    typeof (exp) _rc;                      \\\n    do {                                   \\\n        _rc = (exp);                       \\\n    } while (_rc == -1 && errno == EINTR); \\\n    _rc; })\n#endif\n\nstatic inline size_t min_of(size_t a, size_t b) { return (a < b) ? a : b; }\n\nusing namespace android;\n\n/*\n * Streaming access to compressed asset data in an open fd\n */\nStreamingZipInflater::StreamingZipInflater(int fd, off64_t compDataStart,\n        size_t uncompSize, size_t compSize) {\n    mFd = fd;\n    mDataMap = NULL;\n    mInFileStart = compDataStart;\n    mOutTotalSize = uncompSize;\n    mInTotalSize = compSize;\n\n    mInBufSize = StreamingZipInflater::INPUT_CHUNK_SIZE;\n    mInBuf = new uint8_t[mInBufSize];\n\n    mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;\n    mOutBuf = new uint8_t[mOutBufSize];\n\n    initInflateState();\n}\n\n/*\n * Streaming access to compressed data held in an mmapped region of memory\n */\nStreamingZipInflater::StreamingZipInflater(FileMap* dataMap, size_t uncompSize) {\n    mFd = -1;\n    mDataMap = dataMap;\n    mOutTotalSize = uncompSize;\n    mInTotalSize = dataMap->getDataLength();\n\n    mInBuf = (uint8_t*) dataMap->getDataPtr();\n    mInBufSize = mInTotalSize;\n\n    mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;\n    mOutBuf = new uint8_t[mOutBufSize];\n\n    initInflateState();\n}\n\nStreamingZipInflater::~StreamingZipInflater() {\n    // tear down the in-flight zip state just in case\n    ::inflateEnd(&mInflateState);\n\n    if (mDataMap == NULL) {\n        delete [] mInBuf;\n    }\n    delete [] mOutBuf;\n}\n\nvoid StreamingZipInflater::initInflateState() {\n    ALOGV(\"Initializing inflate state\");\n\n    memset(&mInflateState, 0, sizeof(mInflateState));\n    mInflateState.zalloc = Z_NULL;\n    mInflateState.zfree = Z_NULL;\n    mInflateState.opaque = Z_NULL;\n    mInflateState.next_in = (Bytef*)mInBuf;\n    mInflateState.next_out = (Bytef*) mOutBuf;\n    mInflateState.avail_out = mOutBufSize;\n    mInflateState.data_type = Z_UNKNOWN;\n\n    mOutLastDecoded = mOutDeliverable = mOutCurPosition = 0;\n    mInNextChunkOffset = 0;\n    mStreamNeedsInit = true;\n\n    if (mDataMap == NULL) {\n        ::lseek(mFd, mInFileStart, SEEK_SET);\n        mInflateState.avail_in = 0; // set when a chunk is read in\n    } else {\n        mInflateState.avail_in = mInBufSize;\n    }\n}\n\n/*\n * Basic approach:\n *\n * 1. If we have undelivered uncompressed data, send it.  At this point\n *    either we've satisfied the request, or we've exhausted the available\n *    output data in mOutBuf.\n *\n * 2. While we haven't sent enough data to satisfy the request:\n *    0. if the request is for more data than exists, bail.\n *    a. if there is no input data to decode, read some into the input buffer\n *       and readjust the z_stream input pointers\n *    b. point the output to the start of the output buffer and decode what we can\n *    c. deliver whatever output data we can\n */\nssize_t StreamingZipInflater::read(void* outBuf, size_t count) {\n    uint8_t* dest = (uint8_t*) outBuf;\n    size_t bytesRead = 0;\n    size_t toRead = min_of(count, size_t(mOutTotalSize - mOutCurPosition));\n    while (toRead > 0) {\n        // First, write from whatever we already have decoded and ready to go\n        size_t deliverable = min_of(toRead, mOutLastDecoded - mOutDeliverable);\n        if (deliverable > 0) {\n            if (outBuf != NULL) memcpy(dest, mOutBuf + mOutDeliverable, deliverable);\n            mOutDeliverable += deliverable;\n            mOutCurPosition += deliverable;\n            dest += deliverable;\n            bytesRead += deliverable;\n            toRead -= deliverable;\n        }\n\n        // need more data?  time to decode some.\n        if (toRead > 0) {\n            // if we don't have any data to decode, read some in.  If we're working\n            // from mmapped data this won't happen, because the clipping to total size\n            // will prevent reading off the end of the mapped input chunk.\n            if ((mInflateState.avail_in == 0) && (mDataMap == NULL)) {\n                int err = readNextChunk();\n                if (err < 0) {\n                    ALOGE(\"Unable to access asset data: %d\", err);\n                    if (!mStreamNeedsInit) {\n                        ::inflateEnd(&mInflateState);\n                        initInflateState();\n                    }\n                    return -1;\n                }\n            }\n            // we know we've drained whatever is in the out buffer now, so just\n            // start from scratch there, reading all the input we have at present.\n            mInflateState.next_out = (Bytef*) mOutBuf;\n            mInflateState.avail_out = mOutBufSize;\n\n            /*\n            ALOGV(\"Inflating to outbuf: avail_in=%u avail_out=%u next_in=%p next_out=%p\",\n                    mInflateState.avail_in, mInflateState.avail_out,\n                    mInflateState.next_in, mInflateState.next_out);\n            */\n            int result = Z_OK;\n            if (mStreamNeedsInit) {\n                ALOGV(\"Initializing zlib to inflate\");\n                result = inflateInit2(&mInflateState, -MAX_WBITS);\n                mStreamNeedsInit = false;\n            }\n            if (result == Z_OK) result = ::inflate(&mInflateState, Z_SYNC_FLUSH);\n            if (result < 0) {\n                // Whoops, inflation failed\n                ALOGE(\"Error inflating asset: %d\", result);\n                ::inflateEnd(&mInflateState);\n                initInflateState();\n                return -1;\n            } else {\n                if (result == Z_STREAM_END) {\n                    // we know we have to have reached the target size here and will\n                    // not try to read any further, so just wind things up.\n                    ::inflateEnd(&mInflateState);\n                }\n\n                // Note how much data we got, and off we go\n                mOutDeliverable = 0;\n                mOutLastDecoded = mOutBufSize - mInflateState.avail_out;\n            }\n        }\n    }\n    return bytesRead;\n}\n\nint StreamingZipInflater::readNextChunk() {\n    assert(mDataMap == NULL);\n\n    if (mInNextChunkOffset < mInTotalSize) {\n        size_t toRead = min_of(mInBufSize, mInTotalSize - mInNextChunkOffset);\n        if (toRead > 0) {\n            ssize_t didRead = TEMP_FAILURE_RETRY(::read(mFd, mInBuf, toRead));\n            //ALOGV(\"Reading input chunk, size %08x didread %08x\", toRead, didRead);\n            if (didRead < 0) {\n                ALOGE(\"Error reading asset data: %s\", strerror(errno));\n                return didRead;\n            } else {\n                mInNextChunkOffset += didRead;\n                mInflateState.next_in = (Bytef*) mInBuf;\n                mInflateState.avail_in = didRead;\n            }\n        }\n    }\n    return 0;\n}\n\n// seeking backwards requires uncompressing fom the beginning, so is very\n// expensive.  seeking forwards only requires uncompressing from the current\n// position to the destination.\noff64_t StreamingZipInflater::seekAbsolute(off64_t absoluteInputPosition) {\n    if (absoluteInputPosition < mOutCurPosition) {\n        // rewind and reprocess the data from the beginning\n        if (!mStreamNeedsInit) {\n            ::inflateEnd(&mInflateState);\n        }\n        initInflateState();\n        read(NULL, absoluteInputPosition);\n    } else if (absoluteInputPosition > mOutCurPosition) {\n        read(NULL, absoluteInputPosition - mOutCurPosition);\n    }\n    // else if the target position *is* our current position, do nothing\n    return absoluteInputPosition;\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/TypeWrappers.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/TypeWrappers.h>\n\nnamespace android {\n\nTypeVariant::iterator& TypeVariant::iterator::operator++() {\n    mIndex++;\n    if (mIndex > dtohl(mTypeVariant->data->entryCount)) {\n        mIndex = dtohl(mTypeVariant->data->entryCount);\n    }\n    return *this;\n}\n\nconst ResTable_entry* TypeVariant::iterator::operator*() const {\n    const ResTable_type* type = mTypeVariant->data;\n    const uint32_t entryCount = dtohl(type->entryCount);\n    if (mIndex >= entryCount) {\n        return NULL;\n    }\n\n    const uintptr_t containerEnd = reinterpret_cast<uintptr_t>(type)\n            + dtohl(type->header.size);\n    const uint32_t* const entryIndices = reinterpret_cast<const uint32_t*>(\n            reinterpret_cast<uintptr_t>(type) + dtohs(type->header.headerSize));\n    if (reinterpret_cast<uintptr_t>(entryIndices) + (sizeof(uint32_t) * entryCount) > containerEnd) {\n        ALOGE(\"Type's entry indices extend beyond its boundaries\");\n        return NULL;\n    }\n\n    const uint32_t entryOffset = dtohl(entryIndices[mIndex]);\n    if (entryOffset == ResTable_type::NO_ENTRY) {\n        return NULL;\n    }\n\n    if ((entryOffset & 0x3) != 0) {\n        ALOGE(\"Index %u points to entry with unaligned offset 0x%08x\", mIndex, entryOffset);\n        return NULL;\n    }\n\n    const ResTable_entry* entry = reinterpret_cast<const ResTable_entry*>(\n            reinterpret_cast<uintptr_t>(type) + dtohl(type->entriesStart) + entryOffset);\n    if (reinterpret_cast<uintptr_t>(entry) > containerEnd - sizeof(*entry)) {\n        ALOGE(\"Entry offset at index %u points outside the Type's boundaries\", mIndex);\n        return NULL;\n    } else if (reinterpret_cast<uintptr_t>(entry) + dtohs(entry->size) > containerEnd) {\n        ALOGE(\"Entry at index %u extends beyond Type's boundaries\", mIndex);\n        return NULL;\n    } else if (dtohs(entry->size) < sizeof(*entry)) {\n        ALOGE(\"Entry at index %u is too small (%u)\", mIndex, dtohs(entry->size));\n        return NULL;\n    }\n    return entry;\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/ZipFileRO.cpp",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Read-only access to Zip archives, with minimal heap allocation.\n//\n#define LOG_TAG \"zipro\"\n//#define LOG_NDEBUG 0\n#include <androidfw/ZipFileRO.h>\n#include <utils/Log.h>\n#include <utils/Compat.h>\n#include <utils/misc.h>\n#include <utils/threads.h>\n#include <ziparchive/zip_archive.h>\n\n#include <zlib.h>\n\n#include <string.h>\n#include <fcntl.h>\n#include <errno.h>\n#include <assert.h>\n#include <unistd.h>\n\n/*\n * We must open binary files using open(path, ... | O_BINARY) under Windows.\n * Otherwise strange read errors will happen.\n */\n#ifndef O_BINARY\n#  define O_BINARY  0\n#endif\n\nusing namespace android;\n\nclass _ZipEntryRO {\npublic:\n    ZipEntry entry;\n    ZipEntryName name;\n    void *cookie;\n\n    _ZipEntryRO() : cookie(NULL) {\n    }\n\nprivate:\n    _ZipEntryRO(const _ZipEntryRO& other);\n    _ZipEntryRO& operator=(const _ZipEntryRO& other);\n};\n\nZipFileRO::~ZipFileRO() {\n    CloseArchive(mHandle);\n    free(mFileName);\n}\n\n/*\n * Open the specified file read-only.  We memory-map the entire thing and\n * close the file before returning.\n */\n/* static */ ZipFileRO* ZipFileRO::open(const char* zipFileName)\n{\n    ZipArchiveHandle handle;\n    const int32_t error = OpenArchive(zipFileName, &handle);\n    if (error) {\n        ALOGW(\"Error opening archive %s: %s\", zipFileName, ErrorCodeString(error));\n        return NULL;\n    }\n\n    return new ZipFileRO(handle, strdup(zipFileName));\n}\n\n\nZipEntryRO ZipFileRO::findEntryByName(const char* entryName) const\n{\n    _ZipEntryRO* data = new _ZipEntryRO;\n    const int32_t error = FindEntry(mHandle, entryName, &(data->entry));\n    if (error) {\n        delete data;\n        return NULL;\n    }\n\n    data->name.name = entryName;\n    data->name.name_length = strlen(entryName);\n\n    return (ZipEntryRO) data;\n}\n\n/*\n * Get the useful fields from the zip entry.\n *\n * Returns \"false\" if the offsets to the fields or the contents of the fields\n * appear to be bogus.\n */\nbool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,\n    size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const\n{\n    const _ZipEntryRO* zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);\n    const ZipEntry& ze = zipEntry->entry;\n\n    if (pMethod != NULL) {\n        *pMethod = ze.method;\n    }\n    if (pUncompLen != NULL) {\n        *pUncompLen = ze.uncompressed_length;\n    }\n    if (pCompLen != NULL) {\n        *pCompLen = ze.compressed_length;\n    }\n    if (pOffset != NULL) {\n        *pOffset = ze.offset;\n    }\n    if (pModWhen != NULL) {\n        *pModWhen = ze.mod_time;\n    }\n    if (pCrc32 != NULL) {\n        *pCrc32 = ze.crc32;\n    }\n\n    return true;\n}\n\nbool ZipFileRO::startIteration(void** cookie)\n{\n    _ZipEntryRO* ze = new _ZipEntryRO;\n    int32_t error = StartIteration(mHandle, &(ze->cookie), NULL /* prefix */);\n    if (error) {\n        ALOGW(\"Could not start iteration over %s: %s\", mFileName, ErrorCodeString(error));\n        delete ze;\n        return false;\n    }\n\n    *cookie = ze;\n    return true;\n}\n\nZipEntryRO ZipFileRO::nextEntry(void* cookie)\n{\n    _ZipEntryRO* ze = reinterpret_cast<_ZipEntryRO*>(cookie);\n    int32_t error = Next(ze->cookie, &(ze->entry), &(ze->name));\n    if (error) {\n        if (error != -1) {\n            ALOGW(\"Error iteration over %s: %s\", mFileName, ErrorCodeString(error));\n        }\n        return NULL;\n    }\n\n    return &(ze->entry);\n}\n\nvoid ZipFileRO::endIteration(void* cookie)\n{\n    delete reinterpret_cast<_ZipEntryRO*>(cookie);\n}\n\nvoid ZipFileRO::releaseEntry(ZipEntryRO entry) const\n{\n    delete reinterpret_cast<_ZipEntryRO*>(entry);\n}\n\n/*\n * Copy the entry's filename to the buffer.\n */\nint ZipFileRO::getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen)\n    const\n{\n    const _ZipEntryRO* zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);\n    const uint16_t requiredSize = zipEntry->name.name_length + 1;\n\n    if (bufLen < requiredSize) {\n        ALOGW(\"Buffer too short, requires %d bytes for entry name\", requiredSize);\n        return requiredSize;\n    }\n\n    memcpy(buffer, zipEntry->name.name, requiredSize - 1);\n    buffer[requiredSize - 1] = '\\0';\n\n    return 0;\n}\n\n/*\n * Create a new FileMap object that spans the data in \"entry\".\n */\nFileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const\n{\n    const _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);\n    const ZipEntry& ze = zipEntry->entry;\n    int fd = GetFileDescriptor(mHandle);\n    size_t actualLen = 0;\n\n    if (ze.method == kCompressStored) {\n        actualLen = ze.uncompressed_length;\n    } else {\n        actualLen = ze.compressed_length;\n    }\n\n    FileMap* newMap = new FileMap();\n    if (!newMap->create(mFileName, fd, ze.offset, actualLen, true)) {\n        newMap->release();\n        return NULL;\n    }\n\n    return newMap;\n}\n\n/*\n * Uncompress an entry, in its entirety, into the provided output buffer.\n *\n * This doesn't verify the data's CRC, which might be useful for\n * uncompressed data.  The caller should be able to manage it.\n */\nbool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer, size_t size) const\n{\n    _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);\n    const int32_t error = ExtractToMemory(mHandle, &(zipEntry->entry),\n        (uint8_t*) buffer, size);\n    if (error) {\n        ALOGW(\"ExtractToMemory failed with %s\", ErrorCodeString(error));\n        return false;\n    }\n\n    return true;\n}\n\n/*\n * Uncompress an entry, in its entirety, to an open file descriptor.\n *\n * This doesn't verify the data's CRC, but probably should.\n */\nbool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const\n{\n    _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);\n    const int32_t error = ExtractEntryToFile(mHandle, &(zipEntry->entry), fd);\n    if (error) {\n        ALOGW(\"ExtractToMemory failed with %s\", ErrorCodeString(error));\n        return false;\n    }\n\n    return true;\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/ZipUtils.cpp",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Misc zip/gzip utility functions.\n//\n\n#define LOG_TAG \"ziputil\"\n\n#include <androidfw/ZipUtils.h>\n#include <androidfw/ZipFileRO.h>\n#include <utils/Log.h>\n#include <utils/Compat.h>\n\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n\n#include <zlib.h>\n\nusing namespace android;\n\nstatic inline unsigned long get4LE(const unsigned char* buf) {\n    return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);\n}\n\n\nstatic const unsigned long kReadBufSize = 32768;\n\n/*\n * Utility function that expands zip/gzip \"deflate\" compressed data\n * into a buffer.\n *\n * (This is a clone of the previous function, but it takes a FILE* instead\n * of an fd.  We could pass fileno(fd) to the above, but we can run into\n * trouble when \"fp\" has a different notion of what fd's file position is.)\n *\n * \"fp\" is an open file positioned at the start of the \"deflate\" data\n * \"buf\" must hold at least \"uncompressedLen\" bytes.\n */\n/*static*/ template<typename T> bool inflateToBuffer(T& reader, void* buf,\n    long uncompressedLen, long compressedLen)\n{\n    bool result = false;\n\n    z_stream zstream;\n    int zerr;\n    unsigned long compRemaining;\n\n    assert(uncompressedLen >= 0);\n    assert(compressedLen >= 0);\n\n    compRemaining = compressedLen;\n\n    /*\n     * Initialize the zlib stream.\n     */\n    memset(&zstream, 0, sizeof(zstream));\n    zstream.zalloc = Z_NULL;\n    zstream.zfree = Z_NULL;\n    zstream.opaque = Z_NULL;\n    zstream.next_in = NULL;\n    zstream.avail_in = 0;\n    zstream.next_out = (Bytef*) buf;\n    zstream.avail_out = uncompressedLen;\n    zstream.data_type = Z_UNKNOWN;\n\n    /*\n     * Use the undocumented \"negative window bits\" feature to tell zlib\n     * that there's no zlib header waiting for it.\n     */\n    zerr = inflateInit2(&zstream, -MAX_WBITS);\n    if (zerr != Z_OK) {\n        if (zerr == Z_VERSION_ERROR) {\n            ALOGE(\"Installed zlib is not compatible with linked version (%s)\\n\",\n                ZLIB_VERSION);\n        } else {\n            ALOGE(\"Call to inflateInit2 failed (zerr=%d)\\n\", zerr);\n        }\n        goto bail;\n    }\n\n    /*\n     * Loop while we have data.\n     */\n    do {\n        unsigned long getSize;\n\n        /* read as much as we can */\n        if (zstream.avail_in == 0) {\n            getSize = (compRemaining > kReadBufSize) ?\n                        kReadBufSize : compRemaining;\n            ALOGV(\"+++ reading %ld bytes (%ld left)\\n\",\n                getSize, compRemaining);\n\n            unsigned char* nextBuffer = NULL;\n            const unsigned long nextSize = reader.read(&nextBuffer, getSize);\n\n            if (nextSize < getSize || nextBuffer == NULL) {\n                ALOGD(\"inflate read failed (%ld vs %ld)\\n\", nextSize, getSize);\n                goto z_bail;\n            }\n\n            compRemaining -= nextSize;\n\n            zstream.next_in = nextBuffer;\n            zstream.avail_in = nextSize;\n        }\n\n        /* uncompress the data */\n        zerr = inflate(&zstream, Z_NO_FLUSH);\n        if (zerr != Z_OK && zerr != Z_STREAM_END) {\n            ALOGD(\"zlib inflate call failed (zerr=%d)\\n\", zerr);\n            goto z_bail;\n        }\n\n        /* output buffer holds all, so no need to write the output */\n    } while (zerr == Z_OK);\n\n    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */\n\n    if ((long) zstream.total_out != uncompressedLen) {\n        ALOGW(\"Size mismatch on inflated file (%ld vs %ld)\\n\",\n            zstream.total_out, uncompressedLen);\n        goto z_bail;\n    }\n\n    // success!\n    result = true;\n\nz_bail:\n    inflateEnd(&zstream);        /* free up any allocated structures */\n\nbail:\n    return result;\n}\n\nclass FileReader {\npublic:\n   FileReader(FILE* fp) :\n       mFp(fp), mReadBuf(new unsigned char[kReadBufSize])\n   {\n   }\n\n   ~FileReader() {\n       delete[] mReadBuf;\n   }\n\n   long read(unsigned char** nextBuffer, long readSize) const {\n       *nextBuffer = mReadBuf;\n       return fread(mReadBuf, 1, readSize, mFp);\n   }\n\n   FILE* mFp;\n   unsigned char* mReadBuf;\n};\n\nclass FdReader {\npublic:\n   FdReader(int fd) :\n       mFd(fd), mReadBuf(new unsigned char[kReadBufSize])\n   {\n   }\n\n   ~FdReader() {\n       delete[] mReadBuf;\n   }\n\n   long read(unsigned char** nextBuffer, long readSize) const {\n       *nextBuffer = mReadBuf;\n       return TEMP_FAILURE_RETRY(::read(mFd, mReadBuf, readSize));\n   }\n\n   int mFd;\n   unsigned char* mReadBuf;\n};\n\nclass BufferReader {\npublic:\n    BufferReader(void* input, size_t inputSize) :\n        mInput(reinterpret_cast<unsigned char*>(input)),\n        mInputSize(inputSize),\n        mBufferReturned(false)\n    {\n    }\n\n    long read(unsigned char** nextBuffer, long /*readSize*/) {\n        if (!mBufferReturned) {\n            mBufferReturned = true;\n            *nextBuffer = mInput;\n            return mInputSize;\n        }\n\n        *nextBuffer = NULL;\n        return 0;\n    }\n\n    unsigned char* mInput;\n    const size_t mInputSize;\n    bool mBufferReturned;\n};\n\n/*static*/ bool ZipUtils::inflateToBuffer(FILE* fp, void* buf,\n    long uncompressedLen, long compressedLen)\n{\n    FileReader reader(fp);\n    return ::inflateToBuffer<FileReader>(reader, buf,\n        uncompressedLen, compressedLen);\n}\n\n/*static*/ bool ZipUtils::inflateToBuffer(int fd, void* buf,\n    long uncompressedLen, long compressedLen)\n{\n    FdReader reader(fd);\n    return ::inflateToBuffer<FdReader>(reader, buf,\n        uncompressedLen, compressedLen);\n}\n\n/*static*/ bool ZipUtils::inflateToBuffer(void* in, void* buf,\n    long uncompressedLen, long compressedLen)\n{\n    BufferReader reader(in, compressedLen);\n    return ::inflateToBuffer<BufferReader>(reader, buf,\n        uncompressedLen, compressedLen);\n}\n\n\n\n/*\n * Look at the contents of a gzip archive.  We want to know where the\n * data starts, and how long it will be after it is uncompressed.\n *\n * We expect to find the CRC and length as the last 8 bytes on the file.\n * This is a pretty reasonable thing to expect for locally-compressed\n * files, but there's a small chance that some extra padding got thrown\n * on (the man page talks about compressed data written to tape).  We\n * don't currently deal with that here.  If \"gzip -l\" whines, we're going\n * to fail too.\n *\n * On exit, \"fp\" is pointing at the start of the compressed data.\n */\n/*static*/ bool ZipUtils::examineGzip(FILE* fp, int* pCompressionMethod,\n    long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32)\n{\n    enum {  // flags\n        FTEXT       = 0x01,\n        FHCRC       = 0x02,\n        FEXTRA      = 0x04,\n        FNAME       = 0x08,\n        FCOMMENT    = 0x10,\n    };\n    int ic;\n    int method, flags;\n    int i;\n\n    ic = getc(fp);\n    if (ic != 0x1f || getc(fp) != 0x8b)\n        return false;       // not gzip\n    method = getc(fp);\n    flags = getc(fp);\n\n    /* quick sanity checks */\n    if (method == EOF || flags == EOF)\n        return false;\n    if (method != ZipFileRO::kCompressDeflated)\n        return false;\n\n    /* skip over 4 bytes of mod time, 1 byte XFL, 1 byte OS */\n    for (i = 0; i < 6; i++)\n        (void) getc(fp);\n    /* consume \"extra\" field, if present */\n    if ((flags & FEXTRA) != 0) {\n        int len;\n\n        len = getc(fp);\n        len |= getc(fp) << 8;\n        while (len-- && getc(fp) != EOF)\n            ;\n    }\n    /* consume filename, if present */\n    if ((flags & FNAME) != 0) {\n        do {\n            ic = getc(fp);\n        } while (ic != 0 && ic != EOF);\n    }\n    /* consume comment, if present */\n    if ((flags & FCOMMENT) != 0) {\n        do {\n            ic = getc(fp);\n        } while (ic != 0 && ic != EOF);\n    }\n    /* consume 16-bit header CRC, if present */\n    if ((flags & FHCRC) != 0) {\n        (void) getc(fp);\n        (void) getc(fp);\n    }\n\n    if (feof(fp) || ferror(fp))\n        return false;\n\n    /* seek to the end; CRC and length are in the last 8 bytes */\n    long curPosn = ftell(fp);\n    unsigned char buf[8];\n    fseek(fp, -8, SEEK_END);\n    *pCompressedLen = ftell(fp) - curPosn;\n\n    if (fread(buf, 1, 8, fp) != 8)\n        return false;\n    /* seek back to start of compressed data */\n    fseek(fp, curPosn, SEEK_SET);\n\n    *pCompressionMethod = method;\n    *pCRC32 = get4LE(&buf[0]);\n    *pUncompressedLen = get4LE(&buf[4]);\n\n    return true;\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/misc.cpp",
    "content": "/*\n * Copyright (C) 2005 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"misc\"\n\n//\n// Miscellaneous utility functions.\n//\n#include <androidfw/misc.h>\n\n#include <sys/stat.h>\n#include <string.h>\n#include <errno.h>\n#include <stdio.h>\n\nusing namespace android;\n\nnamespace android {\n\n/*\n * Get a file's type.\n */\nFileType getFileType(const char* fileName)\n{\n    struct stat sb;\n\n    if (stat(fileName, &sb) < 0) {\n        if (errno == ENOENT || errno == ENOTDIR)\n            return kFileTypeNonexistent;\n        else {\n            fprintf(stderr, \"getFileType got errno=%d on '%s'\\n\",\n                errno, fileName);\n            return kFileTypeUnknown;\n        }\n    } else {\n        if (S_ISREG(sb.st_mode))\n            return kFileTypeRegular;\n        else if (S_ISDIR(sb.st_mode))\n            return kFileTypeDirectory;\n        else if (S_ISCHR(sb.st_mode))\n            return kFileTypeCharDev;\n        else if (S_ISBLK(sb.st_mode))\n            return kFileTypeBlockDev;\n        else if (S_ISFIFO(sb.st_mode))\n            return kFileTypeFifo;\n#ifdef HAVE_SYMLINKS\n        else if (S_ISLNK(sb.st_mode))\n            return kFileTypeSymlink;\n        else if (S_ISSOCK(sb.st_mode))\n            return kFileTypeSocket;\n#endif\n        else\n            return kFileTypeUnknown;\n    }\n}\n\n/*\n * Get a file's modification date.\n */\ntime_t getFileModDate(const char* fileName)\n{\n    struct stat sb;\n\n    if (stat(fileName, &sb) < 0)\n        return (time_t) -1;\n\n    return sb.st_mtime;\n}\n\n}; // namespace android\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/Android.mk",
    "content": "#\n# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n# ==========================================================\n# Setup some common variables for the different build\n# targets here.\n# ==========================================================\nLOCAL_PATH:= $(call my-dir)\ntestFiles := \\\n    ByteBucketArray_test.cpp \\\n    Config_test.cpp \\\n    ConfigLocale_test.cpp \\\n    Idmap_test.cpp \\\n    ResTable_test.cpp \\\n    Split_test.cpp \\\n    Theme_test.cpp \\\n    TypeWrappers_test.cpp \\\n    ZipUtils_test.cpp\n\n# ==========================================================\n# Build the host tests: libandroidfw_tests\n# ==========================================================\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libandroidfw_tests\n\nLOCAL_SRC_FILES := $(testFiles)\nLOCAL_STATIC_LIBRARIES := \\\n    libandroidfw \\\n    libutils \\\n    libcutils \\\n\tliblog\n\ninclude $(BUILD_HOST_NATIVE_TEST)\n\n\n# ==========================================================\n# Build the device tests: libandroidfw_tests\n# ==========================================================\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libandroidfw_tests\n\nLOCAL_SRC_FILES := $(testFiles) \\\n    BackupData_test.cpp \\\n    ObbFile_test.cpp\n\nLOCAL_SHARED_LIBRARIES := \\\n    libandroidfw \\\n    libcutils \\\n    libutils \\\n    libui \\\n    libstlport\n\ninclude $(BUILD_NATIVE_TEST)\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/BackupData_test.cpp",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"ObbFile_test\"\n#include <androidfw/BackupHelpers.h>\n#include <utils/Log.h>\n#include <utils/String8.h>\n\n#include <gtest/gtest.h>\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <string.h>\n\nnamespace android {\n\n#define TEST_FILENAME \"/test.bd\"\n\n// keys of different lengths to test padding\n#define KEY1 \"key1\"\n#define KEY2 \"key2a\"\n#define KEY3 \"key3bc\"\n#define KEY4 \"key4def\"\n\n// payloads of different lengths to test padding\n#define DATA1 \"abcdefg\"\n#define DATA2 \"hijklmnopq\"\n#define DATA3 \"rstuvwxyz\"\n// KEY4 is only ever deleted\n\nclass BackupDataTest : public testing::Test {\nprotected:\n    char* m_external_storage;\n    String8 mFilename;\n    String8 mKey1;\n    String8 mKey2;\n    String8 mKey3;\n    String8 mKey4;\n\n    virtual void SetUp() {\n        m_external_storage = getenv(\"EXTERNAL_STORAGE\");\n        mFilename.append(m_external_storage);\n        mFilename.append(TEST_FILENAME);\n\n        ::unlink(mFilename.string());\n        int fd = ::open(mFilename.string(), O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);\n        if (fd < 0) {\n            FAIL() << \"Couldn't create \" << mFilename.string() << \" for writing\";\n        }\n        mKey1 = String8(KEY1);\n        mKey2 = String8(KEY2);\n        mKey3 = String8(KEY3);\n        mKey4 = String8(KEY4);\n   }\n\n    virtual void TearDown() {\n    }\n};\n\nTEST_F(BackupDataTest, WriteAndReadSingle) {\n  int fd = ::open(mFilename.string(), O_WRONLY);\n  BackupDataWriter* writer = new BackupDataWriter(fd);\n\n  EXPECT_EQ(NO_ERROR, writer->WriteEntityHeader(mKey1, sizeof(DATA1)))\n          << \"WriteEntityHeader returned an error\";\n  EXPECT_EQ(NO_ERROR, writer->WriteEntityData(DATA1, sizeof(DATA1)))\n          << \"WriteEntityData returned an error\";\n\n  ::close(fd);\n  fd = ::open(mFilename.string(), O_RDONLY);\n  BackupDataReader* reader = new BackupDataReader(fd);\n  EXPECT_EQ(NO_ERROR, reader->Status())\n          << \"Reader ctor failed\";\n\n  bool done;\n  int type;\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader\";\n\n  String8 key;\n  size_t dataSize;\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error\";\n  EXPECT_EQ(mKey1, key)\n          << \"wrong key from ReadEntityHeader\";\n  EXPECT_EQ(sizeof(DATA1), dataSize)\n          << \"wrong size from ReadEntityHeader\";\n\n  char* dataBytes = new char[dataSize];\n  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))\n          << \"ReadEntityData returned an error\";\n  for (unsigned int i = 0; i < sizeof(DATA1); i++) {\n    EXPECT_EQ(DATA1[i], dataBytes[i])\n             << \"data character \" << i << \" should be equal\";\n  }\n  delete dataBytes;\n  delete writer;\n  delete reader;\n}\n\nTEST_F(BackupDataTest, WriteAndReadMultiple) {\n  int fd = ::open(mFilename.string(), O_WRONLY);\n  BackupDataWriter* writer = new BackupDataWriter(fd);\n  writer->WriteEntityHeader(mKey1, sizeof(DATA1));\n  writer->WriteEntityData(DATA1, sizeof(DATA1));\n  writer->WriteEntityHeader(mKey2, sizeof(DATA2));\n  writer->WriteEntityData(DATA2, sizeof(DATA2));\n\n  ::close(fd);\n  fd = ::open(mFilename.string(), O_RDONLY);\n  BackupDataReader* reader = new BackupDataReader(fd);\n\n  bool done;\n  int type;\n  String8 key;\n  size_t dataSize;\n  char* dataBytes;\n  // read first entity\n  reader->ReadNextHeader(&done, &type);\n  reader->ReadEntityHeader(&key, &dataSize);\n  dataBytes = new char[dataSize];\n  reader->ReadEntityData(dataBytes, dataSize);\n  delete dataBytes;\n\n  // read and verify second entity\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on second entity\";\n  EXPECT_EQ(mKey2, key)\n          << \"wrong key from ReadEntityHeader on second entity\";\n  EXPECT_EQ(sizeof(DATA2), dataSize)\n          << \"wrong size from ReadEntityHeader on second entity\";\n\n  dataBytes = new char[dataSize];\n  EXPECT_EQ((int)dataSize, reader->ReadEntityData(dataBytes, dataSize))\n          << \"ReadEntityData returned an error on second entity\";\n  for (unsigned int i = 0; i < sizeof(DATA2); i++) {\n    EXPECT_EQ(DATA2[i], dataBytes[i])\n             << \"data character \" << i << \" should be equal\";\n  }\n  delete dataBytes;\n  delete writer;\n  delete reader;\n}\n\nTEST_F(BackupDataTest, SkipEntity) {\n  int fd = ::open(mFilename.string(), O_WRONLY);\n  BackupDataWriter* writer = new BackupDataWriter(fd);\n  writer->WriteEntityHeader(mKey1, sizeof(DATA1));\n  writer->WriteEntityData(DATA1, sizeof(DATA1));\n  writer->WriteEntityHeader(mKey2, sizeof(DATA2));\n  writer->WriteEntityData(DATA2, sizeof(DATA2));\n  writer->WriteEntityHeader(mKey3, sizeof(DATA3));\n  writer->WriteEntityData(DATA3, sizeof(DATA3));\n\n  ::close(fd);\n  fd = ::open(mFilename.string(), O_RDONLY);\n  BackupDataReader* reader = new BackupDataReader(fd);\n\n  bool done;\n  int type;\n  String8 key;\n  size_t dataSize;\n  char* dataBytes;\n  // read first entity\n  reader->ReadNextHeader(&done, &type);\n  reader->ReadEntityHeader(&key, &dataSize);\n  dataBytes = new char[dataSize];\n  reader->ReadEntityData(dataBytes, dataSize);\n  delete dataBytes;\n\n  // skip second entity\n  reader->ReadNextHeader(&done, &type);\n  reader->ReadEntityHeader(&key, &dataSize);\n  reader->SkipEntityData();\n\n  // read and verify third entity\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader after skip\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on third entity\";\n  EXPECT_EQ(mKey3, key)\n          << \"wrong key from ReadEntityHeader on third entity\";\n  EXPECT_EQ(sizeof(DATA3), dataSize)\n          << \"wrong size from ReadEntityHeader on third entity\";\n\n  dataBytes = new char[dataSize];\n  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))\n          << \"ReadEntityData returned an error on third entity\";\n  for (unsigned int i = 0; i < sizeof(DATA3); i++) {\n    EXPECT_EQ(DATA3[i], dataBytes[i])\n             << \"data character \" << i << \" should be equal\";\n  }\n  delete dataBytes;\n  delete writer;\n  delete reader;\n}\n\nTEST_F(BackupDataTest, DeleteEntity) {\n  int fd = ::open(mFilename.string(), O_WRONLY);\n  BackupDataWriter* writer = new BackupDataWriter(fd);\n  writer->WriteEntityHeader(mKey1, sizeof(DATA1));\n  writer->WriteEntityData(DATA1, sizeof(DATA1));\n  writer->WriteEntityHeader(mKey2, -1);\n\n  ::close(fd);\n  fd = ::open(mFilename.string(), O_RDONLY);\n  BackupDataReader* reader = new BackupDataReader(fd);\n\n  bool done;\n  int type;\n  String8 key;\n  size_t dataSize;\n  char* dataBytes;\n  // read first entity\n  reader->ReadNextHeader(&done, &type);\n  reader->ReadEntityHeader(&key, &dataSize);\n  dataBytes = new char[dataSize];\n  reader->ReadEntityData(dataBytes, dataSize);\n  delete dataBytes;\n\n  // read and verify deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader on deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on second entity\";\n  EXPECT_EQ(mKey2, key)\n          << \"wrong key from ReadEntityHeader on second entity\";\n  EXPECT_EQ(-1, (int) dataSize)\n          << \"not recognizing deletion on second entity\";\n\n  delete writer;\n  delete reader;\n}\n\nTEST_F(BackupDataTest, EneityAfterDelete) {\n  int fd = ::open(mFilename.string(), O_WRONLY);\n  BackupDataWriter* writer = new BackupDataWriter(fd);\n  writer->WriteEntityHeader(mKey1, sizeof(DATA1));\n  writer->WriteEntityData(DATA1, sizeof(DATA1));\n  writer->WriteEntityHeader(mKey2, -1);\n  writer->WriteEntityHeader(mKey3, sizeof(DATA3));\n  writer->WriteEntityData(DATA3, sizeof(DATA3));\n\n  ::close(fd);\n  fd = ::open(mFilename.string(), O_RDONLY);\n  BackupDataReader* reader = new BackupDataReader(fd);\n\n  bool done;\n  int type;\n  String8 key;\n  size_t dataSize;\n  char* dataBytes;\n  // read first entity\n  reader->ReadNextHeader(&done, &type);\n  reader->ReadEntityHeader(&key, &dataSize);\n  dataBytes = new char[dataSize];\n  reader->ReadEntityData(dataBytes, dataSize);\n  delete dataBytes;\n\n  // read and verify deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader on deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on second entity\";\n  EXPECT_EQ(mKey2, key)\n          << \"wrong key from ReadEntityHeader on second entity\";\n  EXPECT_EQ(-1, (int)dataSize)\n          << \"not recognizing deletion on second entity\";\n\n  // read and verify third entity\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader after deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on third entity\";\n  EXPECT_EQ(mKey3, key)\n          << \"wrong key from ReadEntityHeader on third entity\";\n  EXPECT_EQ(sizeof(DATA3), dataSize)\n          << \"wrong size from ReadEntityHeader on third entity\";\n\n  dataBytes = new char[dataSize];\n  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))\n          << \"ReadEntityData returned an error on third entity\";\n  for (unsigned int i = 0; i < sizeof(DATA3); i++) {\n    EXPECT_EQ(DATA3[i], dataBytes[i])\n             << \"data character \" << i << \" should be equal\";\n  }\n  delete dataBytes;\n  delete writer;\n  delete reader;\n}\n\nTEST_F(BackupDataTest, OnlyDeleteEntities) {\n  int fd = ::open(mFilename.string(), O_WRONLY);\n  BackupDataWriter* writer = new BackupDataWriter(fd);\n  writer->WriteEntityHeader(mKey1, -1);\n  writer->WriteEntityHeader(mKey2, -1);\n  writer->WriteEntityHeader(mKey3, -1);\n  writer->WriteEntityHeader(mKey4, -1);\n\n  ::close(fd);\n  fd = ::open(mFilename.string(), O_RDONLY);\n  BackupDataReader* reader = new BackupDataReader(fd);\n\n  bool done;\n  int type;\n  String8 key;\n  size_t dataSize;\n  // read and verify first deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader first deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on first entity\";\n  EXPECT_EQ(mKey1, key)\n          << \"wrong key from ReadEntityHeader on first entity\";\n  EXPECT_EQ(-1, (int) dataSize)\n          << \"not recognizing deletion on first entity\";\n\n  // read and verify second deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader second deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on second entity\";\n  EXPECT_EQ(mKey2, key)\n          << \"wrong key from ReadEntityHeader on second entity\";\n  EXPECT_EQ(-1, (int) dataSize)\n          << \"not recognizing deletion on second entity\";\n\n  // read and verify third deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader third deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on third entity\";\n  EXPECT_EQ(mKey3, key)\n          << \"wrong key from ReadEntityHeader on third entity\";\n  EXPECT_EQ(-1, (int) dataSize)\n          << \"not recognizing deletion on third entity\";\n\n  // read and verify fourth deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader fourth deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on fourth entity\";\n  EXPECT_EQ(mKey4, key)\n          << \"wrong key from ReadEntityHeader on fourth entity\";\n  EXPECT_EQ(-1, (int) dataSize)\n          << \"not recognizing deletion on fourth entity\";\n\n  delete writer;\n  delete reader;\n}\n\nTEST_F(BackupDataTest, ReadDeletedEntityData) {\n  int fd = ::open(mFilename.string(), O_WRONLY);\n  BackupDataWriter* writer = new BackupDataWriter(fd);\n  writer->WriteEntityHeader(mKey1, -1);\n  writer->WriteEntityHeader(mKey2, -1);\n\n  ::close(fd);\n  fd = ::open(mFilename.string(), O_RDONLY);\n  BackupDataReader* reader = new BackupDataReader(fd);\n\n  bool done;\n  int type;\n  String8 key;\n  size_t dataSize;\n  // read and verify first deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader first deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on first entity\";\n  EXPECT_EQ(mKey1, key)\n          << \"wrong key from ReadEntityHeader on first entity\";\n  EXPECT_EQ(-1, (int) dataSize)\n          << \"not recognizing deletion on first entity\";\n\n  // erroneously try to read first entity data\n  char* dataBytes = new char[10];\n  dataBytes[0] = 'A';\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityData(dataBytes, dataSize));\n  // expect dataBytes to be unmodofied\n  EXPECT_EQ('A', dataBytes[0]);\n\n  // read and verify second deletion\n  reader->ReadNextHeader(&done, &type);\n  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)\n          << \"wrong type from ReadNextHeader second deletion\";\n\n  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))\n          << \"ReadEntityHeader returned an error on second entity\";\n  EXPECT_EQ(mKey2, key)\n          << \"wrong key from ReadEntityHeader on second entity\";\n  EXPECT_EQ(-1, (int) dataSize)\n          << \"not recognizing deletion on second entity\";\n\n  delete[] dataBytes;\n  delete writer;\n  delete reader;\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/ByteBucketArray_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ByteBucketArray.h>\n\n#include <gtest/gtest.h>\n\nusing android::ByteBucketArray;\n\nTEST(ByteBucketArrayTest, TestSparseInsertion) {\n    ByteBucketArray<int> bba;\n    ASSERT_TRUE(bba.set(0, 1));\n    ASSERT_TRUE(bba.set(10, 2));\n    ASSERT_TRUE(bba.set(26, 3));\n    ASSERT_TRUE(bba.set(129, 4));\n    ASSERT_TRUE(bba.set(234, 5));\n\n    for (size_t i = 0; i < bba.size(); i++) {\n        switch (i) {\n            case 0: EXPECT_EQ(1, bba[i]); break;\n            case 10: EXPECT_EQ(2, bba[i]); break;\n            case 26: EXPECT_EQ(3, bba[i]); break;\n            case 129: EXPECT_EQ(4, bba[i]); break;\n            case 234: EXPECT_EQ(5, bba[i]); break;\n            default: EXPECT_EQ(0, bba[i]); break;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/ConfigLocale_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/Log.h>\n#include <utils/String8.h>\n\n#include <gtest/gtest.h>\nnamespace android {\n\nTEST(ConfigLocaleTest, packAndUnpack2LetterLanguage) {\n     ResTable_config config;\n     config.packLanguage(\"en\");\n\n     EXPECT_EQ('e', config.language[0]);\n     EXPECT_EQ('n', config.language[1]);\n\n     char out[4] = { 1, 1, 1, 1};\n     config.unpackLanguage(out);\n     EXPECT_EQ('e', out[0]);\n     EXPECT_EQ('n', out[1]);\n     EXPECT_EQ(0, out[2]);\n     EXPECT_EQ(0, out[3]);\n\n     memset(out, 1, sizeof(out));\n     config.locale = 0;\n     config.unpackLanguage(out);\n     EXPECT_EQ(0, out[0]);\n     EXPECT_EQ(0, out[1]);\n     EXPECT_EQ(0, out[2]);\n     EXPECT_EQ(0, out[3]);\n}\n\nTEST(ConfigLocaleTest, packAndUnpack2LetterRegion) {\n     ResTable_config config;\n     config.packRegion(\"US\");\n\n     EXPECT_EQ('U', config.country[0]);\n     EXPECT_EQ('S', config.country[1]);\n\n     char out[4] = { 1, 1, 1, 1};\n     config.unpackRegion(out);\n     EXPECT_EQ('U', out[0]);\n     EXPECT_EQ('S', out[1]);\n     EXPECT_EQ(0, out[2]);\n     EXPECT_EQ(0, out[3]);\n}\n\nTEST(ConfigLocaleTest, packAndUnpack3LetterLanguage) {\n     ResTable_config config;\n     config.packLanguage(\"eng\");\n\n     // 1-00110-01 101-00100\n     EXPECT_EQ('\\x99', config.language[0]);\n     EXPECT_EQ('\\xA4', config.language[1]);\n\n     char out[4] = { 1, 1, 1, 1};\n     config.unpackLanguage(out);\n     EXPECT_EQ('e', out[0]);\n     EXPECT_EQ('n', out[1]);\n     EXPECT_EQ('g', out[2]);\n     EXPECT_EQ(0, out[3]);\n}\n\nTEST(ConfigLocaleTest, packAndUnpack3LetterLanguageAtOffset16) {\n     ResTable_config config;\n     config.packLanguage(\"tgp\");\n\n     // We had a bug where we would accidentally mask\n     // the 5th bit of both bytes\n     //\n     // packed[0] = 1011 1100\n     // packed[1] = 1101 0011\n     //\n     // which is equivalent to:\n     // 1  [0]   [1]   [2]\n     // 1-01111-00110-10011\n     EXPECT_EQ(char(0xbc), config.language[0]);\n     EXPECT_EQ(char(0xd3), config.language[1]);\n\n     char out[4] = { 1, 1, 1, 1};\n     config.unpackLanguage(out);\n     EXPECT_EQ('t', out[0]);\n     EXPECT_EQ('g', out[1]);\n     EXPECT_EQ('p', out[2]);\n     EXPECT_EQ(0, out[3]);\n}\n\nTEST(ConfigLocaleTest, packAndUnpack3LetterRegion) {\n     ResTable_config config;\n     config.packRegion(\"419\");\n\n     char out[4] = { 1, 1, 1, 1};\n     config.unpackRegion(out);\n\n     EXPECT_EQ('4', out[0]);\n     EXPECT_EQ('1', out[1]);\n     EXPECT_EQ('9', out[2]);\n}\n\n/* static */ void fillIn(const char* lang, const char* country,\n        const char* script, const char* variant, ResTable_config* out) {\n     memset(out, 0, sizeof(ResTable_config));\n     if (lang != NULL) {\n         out->packLanguage(lang);\n     }\n\n     if (country != NULL) {\n         out->packRegion(country);\n     }\n\n     if (script != NULL) {\n         memcpy(out->localeScript, script, 4);\n     }\n\n     if (variant != NULL) {\n         memcpy(out->localeVariant, variant, strlen(variant));\n     }\n}\n\nTEST(ConfigLocaleTest, IsMoreSpecificThan) {\n    ResTable_config l;\n    ResTable_config r;\n\n    fillIn(\"en\", NULL, NULL, NULL, &l);\n    fillIn(NULL, NULL, NULL, NULL, &r);\n\n    EXPECT_TRUE(l.isMoreSpecificThan(r));\n    EXPECT_FALSE(r.isMoreSpecificThan(l));\n\n    fillIn(\"eng\", NULL, NULL, NULL, &l);\n    EXPECT_TRUE(l.isMoreSpecificThan(r));\n    EXPECT_FALSE(r.isMoreSpecificThan(l));\n\n    fillIn(\"eng\", \"419\", NULL, NULL, &r);\n    EXPECT_FALSE(l.isMoreSpecificThan(r));\n    EXPECT_TRUE(r.isMoreSpecificThan(l));\n\n    fillIn(\"en\", NULL, NULL, NULL, &l);\n    fillIn(\"en\", \"US\", NULL, NULL, &r);\n    EXPECT_FALSE(l.isMoreSpecificThan(r));\n    EXPECT_TRUE(r.isMoreSpecificThan(l));\n\n    fillIn(\"en\", \"US\", NULL, NULL, &l);\n    fillIn(\"en\", \"US\", \"Latn\", NULL, &r);\n    EXPECT_FALSE(l.isMoreSpecificThan(r));\n    EXPECT_TRUE(r.isMoreSpecificThan(l));\n\n    fillIn(\"en\", \"US\", NULL, NULL, &l);\n    fillIn(\"en\", \"US\", NULL, \"POSIX\", &r);\n    EXPECT_FALSE(l.isMoreSpecificThan(r));\n    EXPECT_TRUE(r.isMoreSpecificThan(l));\n\n    fillIn(\"en\", \"US\", \"Latn\", NULL, &l);\n    fillIn(\"en\", \"US\", NULL, \"POSIX\", &r);\n    EXPECT_FALSE(l.isMoreSpecificThan(r));\n    EXPECT_TRUE(r.isMoreSpecificThan(l));\n}\n\nTEST(ConfigLocaleTest, setLocale) {\n    ResTable_config test;\n    test.setBcp47Locale(\"en-US\");\n    EXPECT_EQ('e', test.language[0]);\n    EXPECT_EQ('n', test.language[1]);\n    EXPECT_EQ('U', test.country[0]);\n    EXPECT_EQ('S', test.country[1]);\n    EXPECT_EQ(0, test.localeScript[0]);\n    EXPECT_EQ(0, test.localeVariant[0]);\n\n    test.setBcp47Locale(\"eng-419\");\n    char out[4] = { 1, 1, 1, 1};\n    test.unpackLanguage(out);\n    EXPECT_EQ('e', out[0]);\n    EXPECT_EQ('n', out[1]);\n    EXPECT_EQ('g', out[2]);\n    EXPECT_EQ(0, out[3]);\n    memset(out, 1, 4);\n    test.unpackRegion(out);\n    EXPECT_EQ('4', out[0]);\n    EXPECT_EQ('1', out[1]);\n    EXPECT_EQ('9', out[2]);\n\n\n    test.setBcp47Locale(\"en-Latn-419\");\n    memset(out, 1, 4);\n    EXPECT_EQ('e', test.language[0]);\n    EXPECT_EQ('n', test.language[1]);\n\n    EXPECT_EQ(0, memcmp(\"Latn\", test.localeScript, 4));\n    test.unpackRegion(out);\n    EXPECT_EQ('4', out[0]);\n    EXPECT_EQ('1', out[1]);\n    EXPECT_EQ('9', out[2]);\n}\n\n}  // namespace android.\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/Config_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/Log.h>\n#include <utils/String8.h>\n#include <utils/Vector.h>\n\n#include \"TestHelpers.h\"\n#include <gtest/gtest.h>\n\nnamespace android {\n\nstatic ResTable_config selectBest(const ResTable_config& target,\n        const Vector<ResTable_config>& configs) {\n    ResTable_config bestConfig;\n    memset(&bestConfig, 0, sizeof(bestConfig));\n    const size_t configCount = configs.size();\n    for (size_t i = 0; i < configCount; i++) {\n        const ResTable_config& thisConfig = configs[i];\n        if (!thisConfig.match(target)) {\n            continue;\n        }\n\n        if (thisConfig.isBetterThan(bestConfig, &target)) {\n            bestConfig = thisConfig;\n        }\n    }\n    return bestConfig;\n}\n\nstatic ResTable_config buildDensityConfig(int density) {\n    ResTable_config config;\n    memset(&config, 0, sizeof(config));\n    config.density = uint16_t(density);\n    config.sdkVersion = 4;\n    return config;\n}\n\nTEST(ConfigTest, shouldSelectBestDensity) {\n    ResTable_config deviceConfig;\n    memset(&deviceConfig, 0, sizeof(deviceConfig));\n    deviceConfig.density = ResTable_config::DENSITY_XHIGH;\n    deviceConfig.sdkVersion = 21;\n\n    Vector<ResTable_config> configs;\n\n    ResTable_config expectedBest = buildDensityConfig(ResTable_config::DENSITY_HIGH);\n    configs.add(expectedBest);\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n\n    expectedBest = buildDensityConfig(ResTable_config::DENSITY_XXHIGH);\n    configs.add(expectedBest);\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n\n    expectedBest = buildDensityConfig(int(ResTable_config::DENSITY_XXHIGH) - 20);\n    configs.add(expectedBest);\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n\n    configs.add(buildDensityConfig(int(ResTable_config::DENSITY_HIGH) + 20));\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n\n    expectedBest = buildDensityConfig(ResTable_config::DENSITY_XHIGH);\n    configs.add(expectedBest);\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n\n    expectedBest = buildDensityConfig(ResTable_config::DENSITY_ANY);\n    expectedBest.sdkVersion = 21;\n    configs.add(expectedBest);\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n}\n\nTEST(ConfigTest, shouldSelectBestDensityWhenNoneSpecified) {\n    ResTable_config deviceConfig;\n    memset(&deviceConfig, 0, sizeof(deviceConfig));\n    deviceConfig.sdkVersion = 21;\n\n    Vector<ResTable_config> configs;\n    configs.add(buildDensityConfig(ResTable_config::DENSITY_HIGH));\n\n    ResTable_config expectedBest = buildDensityConfig(ResTable_config::DENSITY_MEDIUM);\n    configs.add(expectedBest);\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n\n    expectedBest = buildDensityConfig(ResTable_config::DENSITY_ANY);\n    configs.add(expectedBest);\n    ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs));\n}\n\n}  // namespace android.\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/Idmap_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n\n#include <utils/String8.h>\n#include <utils/String16.h>\n#include \"TestHelpers.h\"\n#include \"data/basic/R.h\"\n\n#include <gtest/gtest.h>\n\nusing namespace android;\n\nnamespace {\n\n/**\n * Include a binary resource table.\n *\n * Package: com.android.test.basic\n */\n#include \"data/basic/basic_arsc.h\"\n\n/**\n * Include a binary resource table.\n * This table is an overlay.\n *\n * Package: com.android.test.basic\n */\n#include \"data/overlay/overlay_arsc.h\"\n\nenum { MAY_NOT_BE_BAG = false };\n\nclass IdmapTest : public ::testing::Test {\nprotected:\n    virtual void SetUp() {\n        ASSERT_EQ(NO_ERROR, mTargetTable.add(basic_arsc, basic_arsc_len));\n        ASSERT_EQ(NO_ERROR, mOverlayTable.add(overlay_arsc, overlay_arsc_len));\n        char targetName[256] = \"com.android.test.basic\";\n        ASSERT_EQ(NO_ERROR, mTargetTable.createIdmap(mOverlayTable, 0, 0,\n                    targetName, targetName, &mData, &mDataSize));\n    }\n\n    virtual void TearDown() {\n        free(mData);\n    }\n\n    ResTable mTargetTable;\n    ResTable mOverlayTable;\n    void* mData;\n    size_t mDataSize;\n};\n\nTEST_F(IdmapTest, canLoadIdmap) {\n    ASSERT_EQ(NO_ERROR, mTargetTable.add(overlay_arsc, overlay_arsc_len, mData, mDataSize));\n}\n\nTEST_F(IdmapTest, overlayOverridesResourceValue) {\n    Res_value val;\n    ssize_t block = mTargetTable.getResource(base::R::string::test2, &val, false);\n    ASSERT_GE(block, 0);\n    ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);\n    const ResStringPool* pool = mTargetTable.getTableStringBlock(block);\n    ASSERT_TRUE(pool != NULL);\n    ASSERT_LT(val.data, pool->size());\n\n    size_t strLen;\n    const char16_t* targetStr16 = pool->stringAt(val.data, &strLen);\n    ASSERT_TRUE(targetStr16 != NULL);\n    ASSERT_EQ(String16(\"test2\"), String16(targetStr16, strLen));\n\n    ASSERT_EQ(NO_ERROR, mTargetTable.add(overlay_arsc, overlay_arsc_len, mData, mDataSize));\n\n    ssize_t newBlock = mTargetTable.getResource(base::R::string::test2, &val, false);\n    ASSERT_GE(newBlock, 0);\n    ASSERT_NE(block, newBlock);\n    ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);\n    pool = mTargetTable.getTableStringBlock(newBlock);\n    ASSERT_TRUE(pool != NULL);\n    ASSERT_LT(val.data, pool->size());\n\n    targetStr16 = pool->stringAt(val.data, &strLen);\n    ASSERT_TRUE(targetStr16 != NULL);\n    ASSERT_EQ(String16(\"test2-overlay\"), String16(targetStr16, strLen));\n}\n\nTEST_F(IdmapTest, overlaidResourceHasSameName) {\n    ASSERT_EQ(NO_ERROR, mTargetTable.add(overlay_arsc, overlay_arsc_len, mData, mDataSize));\n\n    ResTable::resource_name resName;\n    ASSERT_TRUE(mTargetTable.getResourceName(base::R::array::integerArray1, false, &resName));\n\n    ASSERT_TRUE(resName.package != NULL);\n    ASSERT_TRUE(resName.type != NULL);\n    ASSERT_TRUE(resName.name != NULL);\n\n    EXPECT_EQ(String16(\"com.android.test.basic\"), String16(resName.package, resName.packageLen));\n    EXPECT_EQ(String16(\"array\"), String16(resName.type, resName.typeLen));\n    EXPECT_EQ(String16(\"integerArray1\"), String16(resName.name, resName.nameLen));\n}\n\n} // namespace\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/ObbFile_test.cpp",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"ObbFile_test\"\n#include <androidfw/ObbFile.h>\n#include <utils/Log.h>\n#include <utils/RefBase.h>\n#include <utils/String8.h>\n\n#include <gtest/gtest.h>\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <string.h>\n\nnamespace android {\n\n#define TEST_FILENAME \"/test.obb\"\n\nclass ObbFileTest : public testing::Test {\nprotected:\n    sp<ObbFile> mObbFile;\n    String8 mFileName;\n\n    virtual void SetUp() {\n        mObbFile = new ObbFile();\n        char* externalStorage = getenv(\"EXTERNAL_STORAGE\");\n\n        mFileName.append(externalStorage);\n        mFileName.append(TEST_FILENAME);\n\n        int fd = ::open(mFileName.string(), O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);\n        if (fd < 0) {\n            FAIL() << \"Couldn't create \" << mFileName.string() << \" for tests\";\n        }\n    }\n\n    virtual void TearDown() {\n    }\n};\n\nTEST_F(ObbFileTest, ReadFailure) {\n    EXPECT_FALSE(mObbFile->readFrom(-1))\n            << \"No failure on invalid file descriptor\";\n}\n\nTEST_F(ObbFileTest, WriteThenRead) {\n    const char* packageName = \"com.example.obbfile\";\n    const int32_t versionNum = 1;\n\n    mObbFile->setPackageName(String8(packageName));\n    mObbFile->setVersion(versionNum);\n#define SALT_SIZE 8\n    unsigned char salt[SALT_SIZE] = {0x01, 0x10, 0x55, 0xAA, 0xFF, 0x00, 0x5A, 0xA5};\n    EXPECT_TRUE(mObbFile->setSalt(salt, SALT_SIZE))\n            << \"Salt should be successfully set\";\n\n    EXPECT_TRUE(mObbFile->writeTo(mFileName.string()))\n            << \"couldn't write to fake .obb file\";\n\n    mObbFile = new ObbFile();\n\n    EXPECT_TRUE(mObbFile->readFrom(mFileName.string()))\n            << \"couldn't read from fake .obb file\";\n\n    EXPECT_EQ(versionNum, mObbFile->getVersion())\n            << \"version didn't come out the same as it went in\";\n    const char* currentPackageName = mObbFile->getPackageName().string();\n    EXPECT_STREQ(packageName, currentPackageName)\n            << \"package name didn't come out the same as it went in\";\n\n    size_t saltLen;\n    const unsigned char* newSalt = mObbFile->getSalt(&saltLen);\n\n    EXPECT_EQ(sizeof(salt), saltLen)\n            << \"salt sizes were not the same\";\n\n    for (size_t i = 0; i < sizeof(salt); i++) {\n        EXPECT_EQ(salt[i], newSalt[i])\n                << \"salt character \" << i << \" should be equal\";\n    }\n    EXPECT_TRUE(memcmp(newSalt, salt, sizeof(salt)) == 0)\n            << \"salts should be the same\";\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/ResTable_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n\n#include <utils/String8.h>\n#include <utils/String16.h>\n#include \"TestHelpers.h\"\n#include \"data/basic/R.h\"\n#include \"data/lib/R.h\"\n\n#include <gtest/gtest.h>\n\nusing namespace android;\n\nnamespace {\n\n/**\n * Include a binary resource table.\n *\n * Package: com.android.test.basic\n */\n#include \"data/basic/basic_arsc.h\"\n\n#include \"data/lib/lib_arsc.h\"\n\nenum { MAY_NOT_BE_BAG = false };\n\nTEST(ResTableTest, shouldLoadSuccessfully) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n}\n\nTEST(ResTableTest, simpleTypeIsRetrievedCorrectly) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    Res_value val;\n    ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG);\n\n    ASSERT_GE(block, 0);\n    ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);\n\n    const ResStringPool* pool = table.getTableStringBlock(block);\n    ASSERT_TRUE(NULL != pool);\n    ASSERT_EQ(String8(\"test1\"), pool->string8ObjectAt(val.data));\n}\n\nTEST(ResTableTest, resourceNameIsResolved) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    String16 defPackage(\"com.android.test.basic\");\n    String16 testName(\"@string/test1\");\n    uint32_t resID = table.identifierForName(testName.string(), testName.size(),\n                                             0, 0,\n                                             defPackage.string(), defPackage.size());\n    ASSERT_NE(uint32_t(0x00000000), resID);\n    ASSERT_EQ(base::R::string::test1, resID);\n}\n\nTEST(ResTableTest, noParentThemeIsAppliedCorrectly) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    ResTable::Theme theme(table);\n    ASSERT_EQ(NO_ERROR, theme.applyStyle(base::R::style::Theme1));\n\n    Res_value val;\n    uint32_t specFlags = 0;\n    ssize_t index = theme.getAttribute(base::R::attr::attr1, &val, &specFlags);\n    ASSERT_GE(index, 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n    ASSERT_EQ(uint32_t(100), val.data);\n\n    index = theme.getAttribute(base::R::attr::attr2, &val, &specFlags);\n    ASSERT_GE(index, 0);\n    ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);\n    ASSERT_EQ(base::R::integer::number1, val.data);\n}\n\nTEST(ResTableTest, parentThemeIsAppliedCorrectly) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    ResTable::Theme theme(table);\n    ASSERT_EQ(NO_ERROR, theme.applyStyle(base::R::style::Theme2));\n\n    Res_value val;\n    uint32_t specFlags = 0;\n    ssize_t index = theme.getAttribute(base::R::attr::attr1, &val, &specFlags);\n    ASSERT_GE(index, 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n    ASSERT_EQ(uint32_t(300), val.data);\n\n    index = theme.getAttribute(base::R::attr::attr2, &val, &specFlags);\n    ASSERT_GE(index, 0);\n    ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);\n    ASSERT_EQ(base::R::integer::number1, val.data);\n}\n\nTEST(ResTableTest, libraryThemeIsAppliedCorrectly) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(lib_arsc, lib_arsc_len));\n\n    ResTable::Theme theme(table);\n    ASSERT_EQ(NO_ERROR, theme.applyStyle(lib::R::style::Theme));\n\n    Res_value val;\n    uint32_t specFlags = 0;\n    ssize_t index = theme.getAttribute(lib::R::attr::attr1, &val, &specFlags);\n    ASSERT_GE(index, 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n    ASSERT_EQ(uint32_t(700), val.data);\n}\n\nTEST(ResTableTest, referenceToBagIsNotResolved) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    Res_value val;\n    ssize_t block = table.getResource(base::R::integer::number2, &val, MAY_NOT_BE_BAG);\n    ASSERT_GE(block, 0);\n    ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);\n    ASSERT_EQ(base::R::array::integerArray1, val.data);\n\n    ssize_t newBlock = table.resolveReference(&val, block);\n    EXPECT_EQ(block, newBlock);\n    EXPECT_EQ(Res_value::TYPE_REFERENCE, val.dataType);\n    EXPECT_EQ(base::R::array::integerArray1, val.data);\n}\n\nTEST(ResTableTest, resourcesStillAccessibleAfterParameterChange) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    Res_value val;\n    ssize_t block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);\n    ASSERT_GE(block, 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n\n    const ResTable::bag_entry* entry;\n    ssize_t count = table.lockBag(base::R::array::integerArray1, &entry);\n    ASSERT_GE(count, 0);\n    table.unlockBag(entry);\n\n    ResTable_config param;\n    memset(&param, 0, sizeof(param));\n    param.density = 320;\n    table.setParameters(&param);\n\n    block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);\n    ASSERT_GE(block, 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n\n    count = table.lockBag(base::R::array::integerArray1, &entry);\n    ASSERT_GE(count, 0);\n    table.unlockBag(entry);\n}\n\nTEST(ResTableTest, resourceIsOverridenWithBetterConfig) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    Res_value val;\n    ssize_t block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);\n    ASSERT_GE(block, 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n    ASSERT_EQ(uint32_t(200), val.data);\n\n    ResTable_config param;\n    memset(&param, 0, sizeof(param));\n    param.language[0] = 's';\n    param.language[1] = 'v';\n    param.country[0] = 'S';\n    param.country[1] = 'E';\n    table.setParameters(&param);\n\n    block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);\n    ASSERT_GE(block, 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n    ASSERT_EQ(uint32_t(400), val.data);\n}\n\nTEST(ResTableTest, emptyTableHasSensibleDefaults) {\n    const int32_t assetCookie = 1;\n\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.addEmpty(assetCookie));\n\n    // Adding an empty table gives us one table!\n    ASSERT_EQ(uint32_t(1), table.getTableCount());\n\n    // Adding an empty table doesn't mean we get packages.\n    ASSERT_EQ(uint32_t(0), table.getBasePackageCount());\n\n    Res_value val;\n    ASSERT_LT(table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG), 0);\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/Split_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n\n#include <utils/String8.h>\n#include <utils/String16.h>\n#include \"TestHelpers.h\"\n#include \"data/basic/R.h\"\n\n#include <gtest/gtest.h>\n\nusing namespace android;\n\nnamespace {\n\n/**\n * Include a binary resource table. This table\n * is a base table for an APK split.\n *\n * Package: com.android.test.basic\n */\n#include \"data/basic/basic_arsc.h\"\n\n/**\n * Include a binary resource table. This table\n * is a configuration split table for an APK split.\n *\n * Package: com.android.test.basic\n */\n#include \"data/basic/split_de_fr_arsc.h\"\n\n/**\n * Include a binary resource table. This table\n * is a feature split table for an APK split.\n *\n * Package: com.android.test.basic\n */\n#include \"data/feature/feature_arsc.h\"\n\nenum { MAY_NOT_BE_BAG = false };\n\nvoid makeConfigFrench(ResTable_config* config) {\n    memset(config, 0, sizeof(*config));\n    config->language[0] = 'f';\n    config->language[1] = 'r';\n}\n\nTEST(SplitTest, TestLoadBase) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n}\n\nTEST(SplitTest, TestGetResourceFromBase) {\n    ResTable_config frenchConfig;\n    makeConfigFrench(&frenchConfig);\n\n    ResTable table;\n    table.setParameters(&frenchConfig);\n\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    ResTable_config expectedConfig;\n    memset(&expectedConfig, 0, sizeof(expectedConfig));\n\n    Res_value val;\n    ResTable_config config;\n    ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, NULL, &config);\n\n    // The returned block should tell us which string pool to get the value, if it is a string.\n    EXPECT_GE(block, 0);\n\n    // We expect the default resource to be selected since it is the only resource configuration.\n    EXPECT_EQ(0, expectedConfig.compare(config));\n\n    EXPECT_EQ(Res_value::TYPE_STRING, val.dataType);\n}\n\nTEST(SplitTest, TestGetResourceFromSplit) {\n    ResTable_config expectedConfig;\n    makeConfigFrench(&expectedConfig);\n\n    ResTable table;\n    table.setParameters(&expectedConfig);\n\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n    ASSERT_EQ(NO_ERROR, table.add(split_de_fr_arsc, split_de_fr_arsc_len));\n\n    Res_value val;\n    ResTable_config config;\n    ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, NULL, &config);\n\n    EXPECT_GE(block, 0);\n\n    EXPECT_EQ(0, expectedConfig.compare(config));\n\n    EXPECT_EQ(Res_value::TYPE_STRING, val.dataType);\n}\n\nTEST(SplitTest, ResourcesFromBaseAndSplitHaveSameNames) {\n    ResTable_config expectedConfig;\n    makeConfigFrench(&expectedConfig);\n\n    ResTable table;\n    table.setParameters(&expectedConfig);\n\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    ResTable::resource_name baseName;\n    EXPECT_TRUE(table.getResourceName(base::R::string::test1, false, &baseName));\n\n    ASSERT_EQ(NO_ERROR, table.add(split_de_fr_arsc, split_de_fr_arsc_len));\n\n    ResTable::resource_name frName;\n    EXPECT_TRUE(table.getResourceName(base::R::string::test1, false, &frName));\n\n    EXPECT_EQ(\n            String16(baseName.package, baseName.packageLen),\n            String16(frName.package, frName.packageLen));\n\n    EXPECT_EQ(\n            String16(baseName.type, baseName.typeLen),\n            String16(frName.type, frName.typeLen));\n\n    EXPECT_EQ(\n            String16(baseName.name, baseName.nameLen),\n            String16(frName.name, frName.nameLen));\n}\n\nTEST(SplitTest, TypeEntrySpecFlagsAreUpdated) {\n    ResTable_config defaultConfig;\n    memset(&defaultConfig, 0, sizeof(defaultConfig));\n\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    Res_value val;\n    uint32_t specFlags = 0;\n    ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, &specFlags, NULL);\n    EXPECT_GE(block, 0);\n\n    EXPECT_EQ(static_cast<uint32_t>(0), specFlags);\n\n    ASSERT_EQ(NO_ERROR, table.add(split_de_fr_arsc, split_de_fr_arsc_len));\n\n    uint32_t frSpecFlags = 0;\n    block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, &frSpecFlags, NULL);\n    EXPECT_GE(block, 0);\n\n    EXPECT_EQ(ResTable_config::CONFIG_LOCALE, frSpecFlags);\n}\n\nTEST(SplitFeatureTest, TestNewResourceIsAccessible) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    Res_value val;\n    ssize_t block = table.getResource(base::R::string::test3, &val, MAY_NOT_BE_BAG);\n    EXPECT_LT(block, 0);\n\n    ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len));\n\n    block = table.getResource(base::R::string::test3, &val, MAY_NOT_BE_BAG);\n    EXPECT_GE(block, 0);\n\n    EXPECT_EQ(Res_value::TYPE_STRING, val.dataType);\n}\n\nTEST(SplitFeatureTest, TestNewResourceNameHasCorrectName) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n\n    ResTable::resource_name name;\n    EXPECT_FALSE(table.getResourceName(base::R::string::test3, false, &name));\n\n    ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len));\n\n    EXPECT_TRUE(table.getResourceName(base::R::string::test3, false, &name));\n\n    EXPECT_EQ(String16(\"com.android.test.basic\"),\n            String16(name.package, name.packageLen));\n\n    EXPECT_EQ(String16(\"string\"),\n            String16(name.type, name.typeLen));\n\n    EXPECT_EQ(String16(\"test3\"),\n            String16(name.name, name.nameLen));\n}\n\nTEST(SplitFeatureTest, TestNewResourceIsAccessibleByName) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));\n    ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len));\n\n    const String16 name(\"test3\");\n    const String16 type(\"string\");\n    const String16 package(\"com.android.test.basic\");\n    ASSERT_EQ(base::R::string::test3, table.identifierForName(name.string(), name.size(),\n                                                              type.string(), type.size(),\n                                                              package.string(), package.size()));\n}\n\n} // namespace\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/TestHelpers.h",
    "content": "#ifndef __TEST_HELPERS_H\n#define __TEST_HELPERS_H\n\n#include <ostream>\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/String8.h>\n#include <utils/String16.h>\n\nstatic inline ::std::ostream& operator<<(::std::ostream& out, const android::String8& str) {\n    return out << str.string();\n}\n\nstatic inline ::std::ostream& operator<<(::std::ostream& out, const android::String16& str) {\n    return out << android::String8(str).string();\n}\n\nnamespace android {\n\nstatic inline bool operator==(const android::ResTable_config& a, const android::ResTable_config& b) {\n    return memcmp(&a, &b, sizeof(a)) == 0;\n}\n\nstatic inline ::std::ostream& operator<<(::std::ostream& out, const android::ResTable_config& c) {\n    return out << c.toString().string();\n}\n\n} // namespace android\n\n#endif // __TEST_HELPERS_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/Theme_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n\n#include <utils/String8.h>\n#include <utils/String16.h>\n#include \"TestHelpers.h\"\n#include \"data/system/R.h\"\n#include \"data/app/R.h\"\n\n#include <gtest/gtest.h>\n\nusing namespace android;\n\nnamespace {\n\n#include \"data/system/system_arsc.h\"\n#include \"data/app/app_arsc.h\"\n\nenum { MAY_NOT_BE_BAG = false };\n\n/**\n * TODO(adamlesinski): Enable when fixed.\n */\nTEST(ThemeTest, DISABLED_shouldCopyThemeFromDifferentResTable) {\n    ResTable table;\n    ASSERT_EQ(NO_ERROR, table.add(system_arsc, system_arsc_len));\n    ASSERT_EQ(NO_ERROR, table.add(app_arsc, app_arsc_len));\n\n    ResTable::Theme theme1(table);\n    ASSERT_EQ(NO_ERROR, theme1.applyStyle(app::R::style::Theme_One));\n    Res_value val;\n    ASSERT_GE(theme1.getAttribute(android::R::attr::background, &val), 0);\n    ASSERT_EQ(Res_value::TYPE_INT_COLOR_RGB8, val.dataType);\n    ASSERT_EQ(uint32_t(0xffff0000), val.data);\n    ASSERT_GE(theme1.getAttribute(app::R::attr::number, &val), 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n    ASSERT_EQ(uint32_t(1), val.data);\n\n    ResTable table2;\n    ASSERT_EQ(NO_ERROR, table2.add(system_arsc, system_arsc_len));\n    ASSERT_EQ(NO_ERROR, table2.add(app_arsc, app_arsc_len));\n\n    ResTable::Theme theme2(table2);\n    ASSERT_EQ(NO_ERROR, theme2.setTo(theme1));\n    ASSERT_GE(theme2.getAttribute(android::R::attr::background, &val), 0);\n    ASSERT_EQ(Res_value::TYPE_INT_COLOR_RGB8, val.dataType);\n    ASSERT_EQ(uint32_t(0xffff0000), val.data);\n    ASSERT_GE(theme2.getAttribute(app::R::attr::number, &val), 0);\n    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);\n    ASSERT_EQ(uint32_t(1), val.data);\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/TypeWrappers_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n#include <androidfw/TypeWrappers.h>\n#include <utils/String8.h>\n\n#include <gtest/gtest.h>\n\nnamespace android {\n\nvoid* createTypeData() {\n    ResTable_type t;\n    memset(&t, 0, sizeof(t));\n    t.header.type = RES_TABLE_TYPE_TYPE;\n    t.header.headerSize = sizeof(t);\n    t.id = 1;\n    t.entryCount = 3;\n\n    uint32_t offsets[3];\n    t.entriesStart = t.header.headerSize + sizeof(offsets);\n    t.header.size = t.entriesStart;\n\n    offsets[0] = 0;\n    ResTable_entry e1;\n    memset(&e1, 0, sizeof(e1));\n    e1.size = sizeof(e1);\n    e1.key.index = 0;\n    t.header.size += sizeof(e1);\n\n    Res_value v1;\n    memset(&v1, 0, sizeof(v1));\n    t.header.size += sizeof(v1);\n\n    offsets[1] = ResTable_type::NO_ENTRY;\n\n    offsets[2] = sizeof(e1) + sizeof(v1);\n    ResTable_entry e2;\n    memset(&e2, 0, sizeof(e2));\n    e2.size = sizeof(e2);\n    e2.key.index = 1;\n    t.header.size += sizeof(e2);\n\n    Res_value v2;\n    memset(&v2, 0, sizeof(v2));\n    t.header.size += sizeof(v2);\n\n    uint8_t* data = (uint8_t*)malloc(t.header.size);\n    uint8_t* p = data;\n    memcpy(p, &t, sizeof(t));\n    p += sizeof(t);\n    memcpy(p, offsets, sizeof(offsets));\n    p += sizeof(offsets);\n    memcpy(p, &e1, sizeof(e1));\n    p += sizeof(e1);\n    memcpy(p, &v1, sizeof(v1));\n    p += sizeof(v1);\n    memcpy(p, &e2, sizeof(e2));\n    p += sizeof(e2);\n    memcpy(p, &v2, sizeof(v2));\n    p += sizeof(v2);\n    return data;\n}\n\nTEST(TypeVariantIteratorTest, shouldIterateOverTypeWithoutErrors) {\n    ResTable_type* data = (ResTable_type*) createTypeData();\n\n    TypeVariant v(data);\n\n    TypeVariant::iterator iter = v.beginEntries();\n    ASSERT_EQ(uint32_t(0), iter.index());\n    ASSERT_TRUE(NULL != *iter);\n    ASSERT_EQ(uint32_t(0), iter->key.index);\n    ASSERT_NE(v.endEntries(), iter);\n\n    iter++;\n\n    ASSERT_EQ(uint32_t(1), iter.index());\n    ASSERT_TRUE(NULL == *iter);\n    ASSERT_NE(v.endEntries(), iter);\n\n    iter++;\n\n    ASSERT_EQ(uint32_t(2), iter.index());\n    ASSERT_TRUE(NULL != *iter);\n    ASSERT_EQ(uint32_t(1), iter->key.index);\n    ASSERT_NE(v.endEntries(), iter);\n\n    iter++;\n\n    ASSERT_EQ(v.endEntries(), iter);\n\n    free(data);\n}\n\n} // namespace android\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/ZipUtils_test.cpp",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#define LOG_TAG \"ZipUtils_test\"\n#include <utils/Log.h>\n#include <androidfw/ZipUtils.h>\n\n#include <gtest/gtest.h>\n\n#include <fcntl.h>\n#include <string.h>\n\nnamespace android {\n\nclass ZipUtilsTest : public testing::Test {\nprotected:\n    virtual void SetUp() {\n    }\n\n    virtual void TearDown() {\n    }\n};\n\nTEST_F(ZipUtilsTest, ZipTimeConvertSuccess) {\n    struct tm t;\n\n    // 2011-06-29 14:40:40\n    long when = 0x3EDD7514;\n\n    ZipUtils::zipTimeToTimespec(when, &t);\n\n    EXPECT_EQ(2011, t.tm_year + 1900)\n            << \"Year was improperly converted.\";\n\n    EXPECT_EQ(6, t.tm_mon)\n            << \"Month was improperly converted.\";\n\n    EXPECT_EQ(29, t.tm_mday)\n            << \"Day was improperly converted.\";\n\n    EXPECT_EQ(14, t.tm_hour)\n            << \"Hour was improperly converted.\";\n\n    EXPECT_EQ(40, t.tm_min)\n            << \"Minute was improperly converted.\";\n\n    EXPECT_EQ(40, t.tm_sec)\n            << \"Second was improperly converted.\";\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/.gitignore",
    "content": "*.apk\n*.arsc\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/app/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.android.app\">\n</manifest>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/app/R.h",
    "content": "#ifndef __APP_R_H\n#define __APP_R_H\n\nnamespace app {\nnamespace R {\n\nnamespace attr {\n    enum {\n        number         = 0x7f010000,   // default\n    };\n}\n\nnamespace style {\n    enum {\n        Theme_One      = 0x7f020000,   // default\n    };\n}\n\n} // namespace R\n} // namespace app\n\n#endif // __APP_R_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/app/app_arsc.h",
    "content": "unsigned char app_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0xc4, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x9c, 0x02, 0x00, 0x00,\n  0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,\n  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,\n  0x64, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x70, 0x00, 0x70, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00,\n  0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00,\n  0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,\n  0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x6e, 0x00,\n  0x75, 0x00, 0x6d, 0x00, 0x62, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00,\n  0x09, 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00,\n  0x2e, 0x00, 0x4f, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00,\n  0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00,\n  0x64, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x01, 0x7f, 0x08, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00\n};\nunsigned int app_arsc_len = 708;\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/app/res/values/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <attr name=\"number\" format=\"integer\"/>\n    <style name=\"Theme.One\" parent=\"@android:style/Theme.One\">\n        <item name=\"number\">1</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/basic/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.android.test.basic\">\n    <application>\n    </application>\n</manifest>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/basic/R.h",
    "content": "#ifndef __BASE_R_H\n#define __BASE_R_H\n\nnamespace base {\nnamespace R {\n\nnamespace attr {\n    enum {\n        attr1       = 0x7f010000, // default\n        attr2       = 0x7f010001, // default\n    };\n}\n\nnamespace layout {\n    enum {\n        main        = 0x7f020000,  // default, fr-sw600dp-v13\n    };\n}\n\nnamespace string {\n    enum {\n        test1       = 0x7f030000,   // default\n        test2       = 0x7f030001,   // default\n\n        test3       = 0x7f070000,   // default (in feature)\n        test4       = 0x7f070001,   // default (in feature)\n    };\n}\n\nnamespace integer {\n    enum {\n        number1     = 0x7f040000,   // default, sv\n        number2     = 0x7f040001,   // default\n\n        test3       = 0x7f080000,   // default (in feature)\n    };\n}\n\nnamespace style {\n    enum {\n        Theme1      = 0x7f050000,   // default\n        Theme2      = 0x7f050001,   // default\n    };\n}\n\nnamespace array {\n    enum {\n        integerArray1 = 0x7f060000,   // default\n    };\n}\n\n} // namespace R\n} // namespace base\n\n#endif // __BASE_R_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/basic/basic_arsc.h",
    "content": "unsigned char basic_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0x60, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,\n  0x72, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x13, 0x00, 0x72, 0x00,\n  0x65, 0x00, 0x73, 0x00, 0x2f, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00,\n  0x6f, 0x00, 0x75, 0x00, 0x74, 0x00, 0x2f, 0x00, 0x6d, 0x00, 0x61, 0x00,\n  0x69, 0x00, 0x6e, 0x00, 0x2e, 0x00, 0x78, 0x00, 0x6d, 0x00, 0x6c, 0x00,\n  0x00, 0x00, 0x22, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2f, 0x00,\n  0x6c, 0x00, 0x61, 0x00, 0x79, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x74, 0x00,\n  0x2d, 0x00, 0x66, 0x00, 0x72, 0x00, 0x2d, 0x00, 0x73, 0x00, 0x77, 0x00,\n  0x36, 0x00, 0x30, 0x00, 0x30, 0x00, 0x64, 0x00, 0x70, 0x00, 0x2d, 0x00,\n  0x76, 0x00, 0x31, 0x00, 0x33, 0x00, 0x2f, 0x00, 0x6d, 0x00, 0x61, 0x00,\n  0x69, 0x00, 0x6e, 0x00, 0x2e, 0x00, 0x78, 0x00, 0x6d, 0x00, 0x6c, 0x00,\n  0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x31, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00,\n  0x74, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01,\n  0x98, 0x06, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00,\n  0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00,\n  0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00,\n  0x73, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00,\n  0x69, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x20, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00,\n  0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,\n  0x90, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,\n  0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x00, 0x00,\n  0x06, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00, 0x6f, 0x00, 0x75, 0x00,\n  0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00,\n  0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x00, 0x00, 0x07, 0x00, 0x69, 0x00,\n  0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00,\n  0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00, 0x6c, 0x00,\n  0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00, 0x72, 0x00, 0x72, 0x00,\n  0x61, 0x00, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,\n  0xec, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,\n  0x28, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,\n  0x56, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,\n  0x88, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00,\n  0x72, 0x00, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00, 0x74, 0x00,\n  0x74, 0x00, 0x72, 0x00, 0x32, 0x00, 0x00, 0x00, 0x04, 0x00, 0x6d, 0x00,\n  0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00,\n  0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00,\n  0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x32, 0x00, 0x00, 0x00,\n  0x07, 0x00, 0x6e, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x62, 0x00, 0x65, 0x00,\n  0x72, 0x00, 0x31, 0x00, 0x00, 0x00, 0x07, 0x00, 0x6e, 0x00, 0x75, 0x00,\n  0x6d, 0x00, 0x62, 0x00, 0x65, 0x00, 0x72, 0x00, 0x32, 0x00, 0x00, 0x00,\n  0x06, 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00,\n  0x31, 0x00, 0x00, 0x00, 0x06, 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 0x00,\n  0x6d, 0x00, 0x65, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x69, 0x00,\n  0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00,\n  0x41, 0x00, 0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00, 0x31, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x84, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00,\n  0x10, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10,\n  0x05, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x24, 0x00, 0x00,\n  0x01, 0x02, 0x44, 0x00, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x58, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x72, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\n  0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00,\n  0x6c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,\n  0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\n  0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00,\n  0x6c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10,\n  0xc8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x06, 0x7f, 0x01, 0x02, 0x44, 0x00,\n  0x5c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x73, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\n  0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10,\n  0x90, 0x01, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x90, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\n  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x01, 0x7f, 0x08, 0x00, 0x00, 0x10, 0x64, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x01, 0x7f, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x7f,\n  0x10, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x7f,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f, 0x08, 0x00, 0x00, 0x10,\n  0x2c, 0x01, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00,\n  0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x02, 0x44, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x10, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10,\n  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10,\n  0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10,\n  0x03, 0x00, 0x00, 0x00\n};\nunsigned int basic_arsc_len = 1888;\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/basic/res/layout/main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<merge>\n</merge>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/basic/res/layout-fr-sw600dp/main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<merge>\n</merge>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/basic/res/values/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <attr name=\"attr1\" format=\"reference|integer\" />\n    <attr name=\"attr2\" format=\"reference|integer\" />\n\n    <string name=\"test1\">test1</string>\n    <string name=\"test2\">test2</string>\n\n    <integer name=\"number1\">200</integer>\n    <integer name=\"number2\">@array/integerArray1</integer>\n\n    <style name=\"Theme1\">\n        <item name=\"com.android.test.basic:attr1\">100</item>\n        <item name=\"com.android.test.basic:attr2\">@integer/number1</item>\n    </style>\n\n    <style name=\"Theme2\" parent=\"@com.android.test.basic:style/Theme1\">\n        <item name=\"com.android.test.basic:attr1\">300</item>\n    </style>\n\n    <integer-array name=\"integerArray1\">\n        <item>1</item>\n        <item>2</item>\n        <item>3</item>\n    </integer-array>\n</resources>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/basic/res/values-de/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"test1\">versuch 1</string>\n    <string name=\"test2\">versuch 2</string>\n</resources>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/basic/res/values-fr/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"test1\">essai 1</string>\n    <string name=\"test2\">essai 2</string>\n</resources>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/basic/res/values-sv/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <integer name=\"number1\">400</integer>\n</resources>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/basic/split_de_fr_arsc.h",
    "content": "unsigned char split_de_fr_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0xd8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n  0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x09, 0x00, 0x76, 0x00,\n  0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x75, 0x00, 0x63, 0x00, 0x68, 0x00,\n  0x20, 0x00, 0x31, 0x00, 0x00, 0x00, 0x09, 0x00, 0x76, 0x00, 0x65, 0x00,\n  0x72, 0x00, 0x73, 0x00, 0x75, 0x00, 0x63, 0x00, 0x68, 0x00, 0x20, 0x00,\n  0x32, 0x00, 0x00, 0x00, 0x07, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00,\n  0x61, 0x00, 0x69, 0x00, 0x20, 0x00, 0x31, 0x00, 0x00, 0x00, 0x07, 0x00,\n  0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x61, 0x00, 0x69, 0x00, 0x20, 0x00,\n  0x32, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x50, 0x03, 0x00, 0x00,\n  0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,\n  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,\n  0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,\n  0x06, 0x00, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x90, 0x00, 0x00, 0x00,\n  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,\n  0x3e, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00,\n  0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x00, 0x00, 0x06, 0x00, 0x6c, 0x00,\n  0x61, 0x00, 0x79, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x74, 0x00, 0x00, 0x00,\n  0x06, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00,\n  0x67, 0x00, 0x00, 0x00, 0x07, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00,\n  0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00,\n  0x73, 0x00, 0x74, 0x00, 0x79, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x61, 0x00, 0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00,\n  0x74, 0x00, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00,\n  0x73, 0x00, 0x74, 0x00, 0x32, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\n  0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\n  0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x6c, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,\n  0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x6c, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x72, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,\n  0x03, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00,\n  0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\nunsigned int split_de_fr_arsc_len = 984;\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/feature/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.android.test.basic\">\n</manifest>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/feature/feature_arsc.h",
    "content": "unsigned char feature_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0x40, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x33, 0x00,\n  0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x34, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xf4, 0x02, 0x00, 0x00,\n  0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,\n  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,\n  0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x9c, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x7c, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,\n  0x2e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x3c, 0x00, 0x65, 0x00, 0x6d, 0x00,\n  0x70, 0x00, 0x74, 0x00, 0x79, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x04, 0x00,\n  0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x00, 0x00, 0x06, 0x00,\n  0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00,\n  0x00, 0x00, 0x07, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00,\n  0x67, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,\n  0x58, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x33, 0x00,\n  0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x34, 0x00, 0x00, 0x00, 0x07, 0x00, 0x6e, 0x00, 0x75, 0x00, 0x6d, 0x00,\n  0x62, 0x00, 0x65, 0x00, 0x72, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,\n  0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x6c, 0x00, 0x00, 0x00,\n  0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,\n  0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x02, 0x44, 0x00, 0x58, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10,\n  0xc8, 0x00, 0x00, 0x00\n};\nunsigned int feature_arsc_len = 832;\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/feature/res/values/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"test3\">test3</string>\n    <string name=\"test4\">test4</string>\n\n    <integer name=\"number3\">200</integer>\n</resources>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/lib/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.android.test.basic\">\n    <application>\n    </application>\n</manifest>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/lib/R.h",
    "content": "#ifndef __LIB_R_H\n#define __LIB_R_H\n\nnamespace lib {\nnamespace R {\n\nnamespace attr {\n    enum {\n        attr1       = 0x02010000, // default\n    };\n}\n\nnamespace style {\n    enum {\n        Theme        = 0x02020000,  // default\n    };\n}\n\n} // namespace R\n} // namespace lib\n\n#endif // __LIB_R_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/lib/lib_arsc.h",
    "content": "unsigned char lib_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0xc8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xa0, 0x03, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,\n  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,\n  0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00,\n  0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00,\n  0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,\n  0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00,\n  0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00,\n  0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00,\n  0x03, 0x02, 0x0c, 0x00, 0x10, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,\n  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,\n  0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\n  0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x64, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\n  0x08, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\n  0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x64, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,\n  0x08, 0x00, 0x00, 0x10, 0xbc, 0x02, 0x00, 0x00\n};\nunsigned int lib_arsc_len = 968;\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/lib/res/values/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <attr name=\"attr1\" format=\"integer\" />\n\n    <style name=\"Theme\">\n        <item name=\"com.android.test.basic:attr1\">700</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/overlay/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.android.test.basic\">\n    <application>\n    </application>\n</manifest>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/overlay/overlay_arsc.h",
    "content": "unsigned char overlay_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0x10, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x74, 0x00,\n  0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x32, 0x00, 0x2d, 0x00, 0x6f, 0x00,\n  0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xc4, 0x02, 0x00, 0x00,\n  0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,\n  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,\n  0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,\n  0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x54, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00,\n  0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x00, 0x00, 0x06, 0x00, 0x73, 0x00,\n  0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x00, 0x00,\n  0x05, 0x00, 0x61, 0x00, 0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x50, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00,\n  0x74, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x69, 0x00, 0x6e, 0x00,\n  0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00, 0x41, 0x00,\n  0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00, 0x31, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x02, 0x44, 0x00, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x01, 0x02, 0x44, 0x00, 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x10, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10,\n  0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10,\n  0x0b, 0x00, 0x00, 0x00\n};\nunsigned int overlay_arsc_len = 784;\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/overlay/res/values/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"test2\">test2-overlay</string>\n    <integer-array name=\"integerArray1\">\n        <item>10</item>\n        <item>11</item>\n    </integer-array>\n</resources>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/system/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the Apache License, Version 2.0 (the \"License\");\n     you may not use this file except in compliance with the License.\n     You may obtain a copy of the License at\n\n          http://www.apache.org/licenses/LICENSE-2.0\n\n     Unless required by applicable law or agreed to in writing, software\n     distributed under the License is distributed on an \"AS IS\" BASIS,\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n     See the License for the specific language governing permissions and\n     limitations under the License.\n-->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"android\">\n</manifest>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/system/R.h",
    "content": "#ifndef __ANDROID_R_H\n#define __ANDROID_R_H\n\nnamespace android {\nnamespace R {\n\nnamespace attr {\n    enum {\n        background  = 0x01010000, // default\n        foreground  = 0x01010001, // default\n    };\n}\n\nnamespace style {\n    enum {\n        Theme_One      = 0x01020000,   // default\n    };\n}\n\n} // namespace R\n} // namespace android\n\n#endif // __ANDROID_R_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/system/res/values/themes.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <public name=\"background\" type=\"attr\" id=\"0x01010000\"/>\n    <public name=\"foreground\" type=\"attr\" id=\"0x01010001\"/>\n    <public name=\"Theme.One\" type=\"style\" id=\"0x01020000\"/>\n\n    <attr name=\"background\" format=\"color|reference\"/>\n    <attr name=\"foreground\" format=\"color|reference\"/>\n    <style name=\"Theme.One\" parent=\"\">\n        <item name=\"android:background\">#ff0000</item>\n        <item name=\"android:foreground\">#000000</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/libs/androidfw/tests/data/system/system_arsc.h",
    "content": "unsigned char system_arsc[] = {\n  0x02, 0x00, 0x0c, 0x00, 0x18, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xf0, 0x02, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00,\n  0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00,\n  0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00,\n  0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,\n  0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x0a, 0x00, 0x62, 0x00, 0x61, 0x00, 0x63, 0x00, 0x6b, 0x00, 0x67, 0x00,\n  0x72, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x00, 0x00,\n  0x0a, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x67, 0x00,\n  0x72, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x00, 0x00,\n  0x09, 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00,\n  0x2e, 0x00, 0x4f, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40,\n  0x01, 0x02, 0x44, 0x00, 0x84, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x1c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\n  0x08, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00,\n  0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x02, 0x44, 0x00,\n  0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n  0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00,\n  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x01, 0x01, 0x08, 0x00, 0x00, 0x1d, 0x00, 0x00, 0xff, 0xff,\n  0x01, 0x00, 0x01, 0x01, 0x08, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xff\n};\nunsigned int system_arsc_len = 792;\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/AaptAssets.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n\n#include \"AaptAssets.h\"\n#include \"AaptConfig.h\"\n#include \"AaptUtil.h\"\n#include \"Main.h\"\n#include \"ResourceFilter.h\"\n\n#include <utils/misc.h>\n#include <utils/SortedVector.h>\n\n#include <ctype.h>\n#include <dirent.h>\n#include <errno.h>\n\nstatic const char* kDefaultLocale = \"default\";\nstatic const char* kAssetDir = \"assets\";\nstatic const char* kResourceDir = \"res\";\nstatic const char* kValuesDir = \"values\";\nstatic const char* kMipmapDir = \"mipmap\";\nstatic const char* kInvalidChars = \"/\\\\:\";\nstatic const size_t kMaxAssetFileName = 100;\n\nstatic const String8 kResString(kResourceDir);\n\n/*\n * Names of asset files must meet the following criteria:\n *\n *  - the filename length must be less than kMaxAssetFileName bytes long\n *    (and can't be empty)\n *  - all characters must be 7-bit printable ASCII\n *  - none of { '/' '\\\\' ':' }\n *\n * Pass in just the filename, not the full path.\n */\nstatic bool validateFileName(const char* fileName)\n{\n    const char* cp = fileName;\n    size_t len = 0;\n\n    while (*cp != '\\0') {\n        if ((*cp & 0x80) != 0)\n            return false;           // reject high ASCII\n        if (*cp < 0x20 || *cp >= 0x7f)\n            return false;           // reject control chars and 0x7f\n        if (strchr(kInvalidChars, *cp) != NULL)\n            return false;           // reject path sep chars\n        cp++;\n        len++;\n    }\n\n    if (len < 1 || len > kMaxAssetFileName)\n        return false;               // reject empty or too long\n\n    return true;\n}\n\n// The default to use if no other ignore pattern is defined.\nconst char * const gDefaultIgnoreAssets =\n    \"!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~\";\n// The ignore pattern that can be passed via --ignore-assets in Main.cpp\nconst char * gUserIgnoreAssets = NULL;\n\nstatic bool isHidden(const char *root, const char *path)\n{\n    // Patterns syntax:\n    // - Delimiter is :\n    // - Entry can start with the flag ! to avoid printing a warning\n    //   about the file being ignored.\n    // - Entry can have the flag \"<dir>\" to match only directories\n    //   or <file> to match only files. Default is to match both.\n    // - Entry can be a simplified glob \"<prefix>*\" or \"*<suffix>\"\n    //   where prefix/suffix must have at least 1 character (so that\n    //   we don't match a '*' catch-all pattern.)\n    // - The special filenames \".\" and \"..\" are always ignored.\n    // - Otherwise the full string is matched.\n    // - match is not case-sensitive.\n\n    if (strcmp(path, \".\") == 0 || strcmp(path, \"..\") == 0) {\n        return true;\n    }\n\n    const char *delim = \":\";\n    const char *p = gUserIgnoreAssets;\n    if (!p || !p[0]) {\n        p = getenv(\"ANDROID_AAPT_IGNORE\");\n    }\n    if (!p || !p[0]) {\n        p = gDefaultIgnoreAssets;\n    }\n    char *patterns = strdup(p);\n\n    bool ignore = false;\n    bool chatty = true;\n    char *matchedPattern = NULL;\n\n    String8 fullPath(root);\n    fullPath.appendPath(path);\n    FileType type = getFileType(fullPath);\n\n    int plen = strlen(path);\n\n    // Note: we don't have strtok_r under mingw.\n    for(char *token = strtok(patterns, delim);\n            !ignore && token != NULL;\n            token = strtok(NULL, delim)) {\n        chatty = token[0] != '!';\n        if (!chatty) token++; // skip !\n        if (strncasecmp(token, \"<dir>\" , 5) == 0) {\n            if (type != kFileTypeDirectory) continue;\n            token += 5;\n        }\n        if (strncasecmp(token, \"<file>\", 6) == 0) {\n            if (type != kFileTypeRegular) continue;\n            token += 6;\n        }\n\n        matchedPattern = token;\n        int n = strlen(token);\n\n        if (token[0] == '*') {\n            // Match *suffix\n            token++;\n            n--;\n            if (n <= plen) {\n                ignore = strncasecmp(token, path + plen - n, n) == 0;\n            }\n        } else if (n > 1 && token[n - 1] == '*') {\n            // Match prefix*\n            ignore = strncasecmp(token, path, n - 1) == 0;\n        } else {\n            ignore = strcasecmp(token, path) == 0;\n        }\n    }\n\n    if (ignore && chatty) {\n        fprintf(stderr, \"    (skipping %s '%s' due to ANDROID_AAPT_IGNORE pattern '%s')\\n\",\n                type == kFileTypeDirectory ? \"dir\" : \"file\",\n                path,\n                matchedPattern ? matchedPattern : \"\");\n    }\n\n    free(patterns);\n    return ignore;\n}\n\n// =========================================================================\n// =========================================================================\n// =========================================================================\n\n/* static */\ninline bool isAlpha(const String8& string) {\n     const size_t length = string.length();\n     for (size_t i = 0; i < length; ++i) {\n          if (!isalpha(string[i])) {\n              return false;\n          }\n     }\n\n     return true;\n}\n\n/* static */\ninline bool isNumber(const String8& string) {\n     const size_t length = string.length();\n     for (size_t i = 0; i < length; ++i) {\n          if (!isdigit(string[i])) {\n              return false;\n          }\n     }\n\n     return true;\n}\n\nvoid AaptLocaleValue::setLanguage(const char* languageChars) {\n     size_t i = 0;\n     while ((*languageChars) != '\\0') {\n          language[i++] = tolower(*languageChars);\n          languageChars++;\n     }\n}\n\nvoid AaptLocaleValue::setRegion(const char* regionChars) {\n    size_t i = 0;\n    while ((*regionChars) != '\\0') {\n         region[i++] = toupper(*regionChars);\n         regionChars++;\n    }\n}\n\nvoid AaptLocaleValue::setScript(const char* scriptChars) {\n    size_t i = 0;\n    while ((*scriptChars) != '\\0') {\n         if (i == 0) {\n             script[i++] = toupper(*scriptChars);\n         } else {\n             script[i++] = tolower(*scriptChars);\n         }\n         scriptChars++;\n    }\n}\n\nvoid AaptLocaleValue::setVariant(const char* variantChars) {\n     size_t i = 0;\n     while ((*variantChars) != '\\0') {\n          variant[i++] = *variantChars;\n          variantChars++;\n     }\n}\n\nbool AaptLocaleValue::initFromFilterString(const String8& str) {\n     // A locale (as specified in the filter) is an underscore separated name such\n     // as \"en_US\", \"en_Latn_US\", or \"en_US_POSIX\".\n     Vector<String8> parts = AaptUtil::splitAndLowerCase(str, '_');\n\n     const int numTags = parts.size();\n     bool valid = false;\n     if (numTags >= 1) {\n         const String8& lang = parts[0];\n         if (isAlpha(lang) && (lang.length() == 2 || lang.length() == 3)) {\n             setLanguage(lang.string());\n             valid = true;\n         }\n     }\n\n     if (!valid || numTags == 1) {\n         return valid;\n     }\n\n     // At this point, valid == true && numTags > 1.\n     const String8& part2 = parts[1];\n     if ((part2.length() == 2 && isAlpha(part2)) ||\n         (part2.length() == 3 && isNumber(part2))) {\n         setRegion(part2.string());\n     } else if (part2.length() == 4 && isAlpha(part2)) {\n         setScript(part2.string());\n     } else if (part2.length() >= 5 && part2.length() <= 8) {\n         setVariant(part2.string());\n     } else {\n         valid = false;\n     }\n\n     if (!valid || numTags == 2) {\n         return valid;\n     }\n\n     // At this point, valid == true && numTags > 1.\n     const String8& part3 = parts[2];\n     if (((part3.length() == 2 && isAlpha(part3)) ||\n         (part3.length() == 3 && isNumber(part3))) && script[0]) {\n         setRegion(part3.string());\n     } else if (part3.length() >= 5 && part3.length() <= 8) {\n         setVariant(part3.string());\n     } else {\n         valid = false;\n     }\n\n     if (!valid || numTags == 3) {\n         return valid;\n     }\n\n     const String8& part4 = parts[3];\n     if (part4.length() >= 5 && part4.length() <= 8) {\n         setVariant(part4.string());\n     } else {\n         valid = false;\n     }\n\n     if (!valid || numTags > 4) {\n         return false;\n     }\n\n     return true;\n}\n\nint AaptLocaleValue::initFromDirName(const Vector<String8>& parts, const int startIndex) {\n    const int size = parts.size();\n    int currentIndex = startIndex;\n\n    String8 part = parts[currentIndex];\n    if (part[0] == 'b' && part[1] == '+') {\n        // This is a \"modified\" BCP-47 language tag. Same semantics as BCP-47 tags,\n        // except that the separator is \"+\" and not \"-\".\n        Vector<String8> subtags = AaptUtil::splitAndLowerCase(part, '+');\n        subtags.removeItemsAt(0);\n        if (subtags.size() == 1) {\n            setLanguage(subtags[0]);\n        } else if (subtags.size() == 2) {\n            setLanguage(subtags[0]);\n\n            // The second tag can either be a region, a variant or a script.\n            switch (subtags[1].size()) {\n                case 2:\n                case 3:\n                    setRegion(subtags[1]);\n                    break;\n                case 4:\n                    setScript(subtags[1]);\n                    break;\n                case 5:\n                case 6:\n                case 7:\n                case 8:\n                    setVariant(subtags[1]);\n                    break;\n                default:\n                    fprintf(stderr, \"ERROR: Invalid BCP-47 tag in directory name %s\\n\",\n                            part.string());\n                    return -1;\n            }\n        } else if (subtags.size() == 3) {\n            // The language is always the first subtag.\n            setLanguage(subtags[0]);\n\n            // The second subtag can either be a script or a region code.\n            // If its size is 4, it's a script code, else it's a region code.\n            bool hasRegion = false;\n            if (subtags[1].size() == 4) {\n                setScript(subtags[1]);\n            } else if (subtags[1].size() == 2 || subtags[1].size() == 3) {\n                setRegion(subtags[1]);\n                hasRegion = true;\n            } else {\n                fprintf(stderr, \"ERROR: Invalid BCP-47 tag in directory name %s\\n\", part.string());\n                return -1;\n            }\n\n            // The third tag can either be a region code (if the second tag was\n            // a script), else a variant code.\n            if (subtags[2].size() > 4) {\n                setVariant(subtags[2]);\n            } else {\n                setRegion(subtags[2]);\n            }\n        } else if (subtags.size() == 4) {\n            setLanguage(subtags[0]);\n            setScript(subtags[1]);\n            setRegion(subtags[2]);\n            setVariant(subtags[3]);\n        } else {\n            fprintf(stderr, \"ERROR: Invalid BCP-47 tag in directory name: %s\\n\", part.string());\n            return -1;\n        }\n\n        return ++currentIndex;\n    } else {\n        if ((part.length() == 2 || part.length() == 3) && isAlpha(part)) {\n            setLanguage(part);\n            if (++currentIndex == size) {\n                return size;\n            }\n        } else {\n            return currentIndex;\n        }\n\n        part = parts[currentIndex];\n        if (part.string()[0] == 'r' && part.length() == 3) {\n            setRegion(part.string() + 1);\n            if (++currentIndex == size) {\n                return size;\n            }\n        }\n    }\n\n    return currentIndex;\n}\n\n\nString8 AaptLocaleValue::toDirName() const {\n    String8 dirName(\"\");\n    if (language[0]) {\n        dirName += language;\n    } else {\n        return dirName;\n    }\n\n    if (script[0]) {\n        dirName += \"-s\";\n        dirName += script;\n    }\n\n    if (region[0]) {\n        dirName += \"-r\";\n        dirName += region;\n    }\n\n    if (variant[0]) {\n        dirName += \"-v\";\n        dirName += variant;\n    }\n\n    return dirName;\n}\n\nvoid AaptLocaleValue::initFromResTable(const ResTable_config& config) {\n    config.unpackLanguage(language);\n    config.unpackRegion(region);\n    if (config.localeScript[0]) {\n        memcpy(script, config.localeScript, sizeof(config.localeScript));\n    }\n\n    if (config.localeVariant[0]) {\n        memcpy(variant, config.localeVariant, sizeof(config.localeVariant));\n    }\n}\n\nvoid AaptLocaleValue::writeTo(ResTable_config* out) const {\n    out->packLanguage(language);\n    out->packRegion(region);\n\n    if (script[0]) {\n        memcpy(out->localeScript, script, sizeof(out->localeScript));\n    }\n\n    if (variant[0]) {\n        memcpy(out->localeVariant, variant, sizeof(out->localeVariant));\n    }\n}\n\nbool\nAaptGroupEntry::initFromDirName(const char* dir, String8* resType)\n{\n    const char* q = strchr(dir, '-');\n    size_t typeLen;\n    if (q != NULL) {\n        typeLen = q - dir;\n    } else {\n        typeLen = strlen(dir);\n    }\n\n    String8 type(dir, typeLen);\n    if (!isValidResourceType(type)) {\n        return false;\n    }\n\n    if (q != NULL) {\n        if (!AaptConfig::parse(String8(q + 1), &mParams)) {\n            return false;\n        }\n    }\n\n    *resType = type;\n    return true;\n}\n\nString8\nAaptGroupEntry::toDirName(const String8& resType) const\n{\n    String8 s = resType;\n    String8 params = mParams.toString();\n    if (params.length() > 0) {\n        if (s.length() > 0) {\n            s += \"-\";\n        }\n        s += params;\n    }\n    return s;\n}\n\n\n// =========================================================================\n// =========================================================================\n// =========================================================================\n\nvoid* AaptFile::editData(size_t size)\n{\n    if (size <= mBufferSize) {\n        mDataSize = size;\n        return mData;\n    }\n    size_t allocSize = (size*3)/2;\n    void* buf = realloc(mData, allocSize);\n    if (buf == NULL) {\n        return NULL;\n    }\n    mData = buf;\n    mDataSize = size;\n    mBufferSize = allocSize;\n    return buf;\n}\n\nvoid* AaptFile::editDataInRange(size_t offset, size_t size)\n{\n    return (void*)(((uint8_t*) editData(offset + size)) + offset);\n}\n\nvoid* AaptFile::editData(size_t* outSize)\n{\n    if (outSize) {\n        *outSize = mDataSize;\n    }\n    return mData;\n}\n\nvoid* AaptFile::padData(size_t wordSize)\n{\n    const size_t extra = mDataSize%wordSize;\n    if (extra == 0) {\n        return mData;\n    }\n\n    size_t initial = mDataSize;\n    void* data = editData(initial+(wordSize-extra));\n    if (data != NULL) {\n        memset(((uint8_t*)data) + initial, 0, wordSize-extra);\n    }\n    return data;\n}\n\nstatus_t AaptFile::writeData(const void* data, size_t size)\n{\n    size_t end = mDataSize;\n    size_t total = size + end;\n    void* buf = editData(total);\n    if (buf == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    memcpy(((char*)buf)+end, data, size);\n    return NO_ERROR;\n}\n\nvoid AaptFile::clearData()\n{\n    if (mData != NULL) free(mData);\n    mData = NULL;\n    mDataSize = 0;\n    mBufferSize = 0;\n}\n\nString8 AaptFile::getPrintableSource() const\n{\n    if (hasData()) {\n        String8 name(mGroupEntry.toDirName(String8()));\n        name.appendPath(mPath);\n        name.append(\" #generated\");\n        return name;\n    }\n    return mSourceFile;\n}\n\n// =========================================================================\n// =========================================================================\n// =========================================================================\n\nstatus_t AaptGroup::addFile(const sp<AaptFile>& file, const bool overwriteDuplicate)\n{\n    ssize_t index = mFiles.indexOfKey(file->getGroupEntry());\n    if (index >= 0 && overwriteDuplicate) {\n        fprintf(stderr, \"warning: overwriting '%s' with '%s'\\n\",\n                mFiles[index]->getSourceFile().string(),\n                file->getSourceFile().string());\n        removeFile(index);\n        index = -1;\n    }\n\n    if (index < 0) {\n        file->mPath = mPath;\n        mFiles.add(file->getGroupEntry(), file);\n        return NO_ERROR;\n    }\n\n    // Check if the version is automatically applied. This is a common source of\n    // error.\n    ConfigDescription withoutVersion = file->getGroupEntry().toParams();\n    withoutVersion.version = 0;\n    AaptConfig::applyVersionForCompatibility(&withoutVersion);\n\n    const sp<AaptFile>& originalFile = mFiles.valueAt(index);\n    SourcePos(file->getSourceFile(), -1)\n            .error(\"Duplicate file.\\n%s: Original is here. %s\",\n                   originalFile->getPrintableSource().string(),\n                   (withoutVersion.version != 0) ? \"The version qualifier may be implied.\" : \"\");\n    return UNKNOWN_ERROR;\n}\n\nvoid AaptGroup::removeFile(size_t index)\n{\n\tmFiles.removeItemsAt(index);\n}\n\nvoid AaptGroup::print(const String8& prefix) const\n{\n    printf(\"%s%s\\n\", prefix.string(), getPath().string());\n    const size_t N=mFiles.size();\n    size_t i;\n    for (i=0; i<N; i++) {\n        sp<AaptFile> file = mFiles.valueAt(i);\n        const AaptGroupEntry& e = file->getGroupEntry();\n        if (file->hasData()) {\n            printf(\"%s  Gen: (%s) %d bytes\\n\", prefix.string(), e.toDirName(String8()).string(),\n                    (int)file->getSize());\n        } else {\n            printf(\"%s  Src: (%s) %s\\n\", prefix.string(), e.toDirName(String8()).string(),\n                    file->getPrintableSource().string());\n        }\n        //printf(\"%s  File Group Entry: %s\\n\", prefix.string(),\n        //        file->getGroupEntry().toDirName(String8()).string());\n    }\n}\n\nString8 AaptGroup::getPrintableSource() const\n{\n    if (mFiles.size() > 0) {\n        // Arbitrarily pull the first source file out of the list.\n        return mFiles.valueAt(0)->getPrintableSource();\n    }\n\n    // Should never hit this case, but to be safe...\n    return getPath();\n\n}\n\n// =========================================================================\n// =========================================================================\n// =========================================================================\n\nstatus_t AaptDir::addFile(const String8& name, const sp<AaptGroup>& file)\n{\n    if (mFiles.indexOfKey(name) >= 0) {\n        return ALREADY_EXISTS;\n    }\n    mFiles.add(name, file);\n    return NO_ERROR;\n}\n\nstatus_t AaptDir::addDir(const String8& name, const sp<AaptDir>& dir)\n{\n    if (mDirs.indexOfKey(name) >= 0) {\n        return ALREADY_EXISTS;\n    }\n    mDirs.add(name, dir);\n    return NO_ERROR;\n}\n\nsp<AaptDir> AaptDir::makeDir(const String8& path)\n{\n    String8 name;\n    String8 remain = path;\n\n    sp<AaptDir> subdir = this;\n    while (name = remain.walkPath(&remain), remain != \"\") {\n        subdir = subdir->makeDir(name);\n    }\n\n    ssize_t i = subdir->mDirs.indexOfKey(name);\n    if (i >= 0) {\n        return subdir->mDirs.valueAt(i);\n    }\n    sp<AaptDir> dir = new AaptDir(name, subdir->mPath.appendPathCopy(name));\n    subdir->mDirs.add(name, dir);\n    return dir;\n}\n\nvoid AaptDir::removeFile(const String8& name)\n{\n    mFiles.removeItem(name);\n}\n\nvoid AaptDir::removeDir(const String8& name)\n{\n    mDirs.removeItem(name);\n}\n\nstatus_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file,\n        const bool overwrite)\n{\n    sp<AaptGroup> group;\n    if (mFiles.indexOfKey(leafName) >= 0) {\n        group = mFiles.valueFor(leafName);\n    } else {\n        group = new AaptGroup(leafName, mPath.appendPathCopy(leafName));\n        mFiles.add(leafName, group);\n    }\n\n    return group->addFile(file, overwrite);\n}\n\nssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir,\n                            const AaptGroupEntry& kind, const String8& resType,\n                            sp<FilePathStore>& fullResPaths, const bool overwrite)\n{\n    Vector<String8> fileNames;\n    {\n        DIR* dir = NULL;\n\n        dir = opendir(srcDir.string());\n        if (dir == NULL) {\n            fprintf(stderr, \"ERROR: opendir(%s): %s\\n\", srcDir.string(), strerror(errno));\n            return UNKNOWN_ERROR;\n        }\n\n        /*\n         * Slurp the filenames out of the directory.\n         */\n        while (1) {\n            struct dirent* entry;\n\n            entry = readdir(dir);\n            if (entry == NULL)\n                break;\n\n            if (isHidden(srcDir.string(), entry->d_name))\n                continue;\n\n            String8 name(entry->d_name);\n            fileNames.add(name);\n            // Add fully qualified path for dependency purposes\n            // if we're collecting them\n            if (fullResPaths != NULL) {\n                fullResPaths->add(srcDir.appendPathCopy(name));\n            }\n        }\n        closedir(dir);\n    }\n\n    ssize_t count = 0;\n\n    /*\n     * Stash away the files and recursively descend into subdirectories.\n     */\n    const size_t N = fileNames.size();\n    size_t i;\n    for (i = 0; i < N; i++) {\n        String8 pathName(srcDir);\n        FileType type;\n\n        pathName.appendPath(fileNames[i].string());\n        type = getFileType(pathName.string());\n        if (type == kFileTypeDirectory) {\n            sp<AaptDir> subdir;\n            bool notAdded = false;\n            if (mDirs.indexOfKey(fileNames[i]) >= 0) {\n                subdir = mDirs.valueFor(fileNames[i]);\n            } else {\n                subdir = new AaptDir(fileNames[i], mPath.appendPathCopy(fileNames[i]));\n                notAdded = true;\n            }\n            ssize_t res = subdir->slurpFullTree(bundle, pathName, kind,\n                                                resType, fullResPaths, overwrite);\n            if (res < NO_ERROR) {\n                return res;\n            }\n            if (res > 0 && notAdded) {\n                mDirs.add(fileNames[i], subdir);\n            }\n            count += res;\n        } else if (type == kFileTypeRegular) {\n            sp<AaptFile> file = new AaptFile(pathName, kind, resType);\n            status_t err = addLeafFile(fileNames[i], file, overwrite);\n            if (err != NO_ERROR) {\n                return err;\n            }\n\n            count++;\n\n        } else {\n            if (bundle->getVerbose())\n                printf(\"   (ignoring non-file/dir '%s')\\n\", pathName.string());\n        }\n    }\n\n    return count;\n}\n\nstatus_t AaptDir::validate() const\n{\n    const size_t NF = mFiles.size();\n    const size_t ND = mDirs.size();\n    size_t i;\n    for (i = 0; i < NF; i++) {\n        if (!validateFileName(mFiles.valueAt(i)->getLeaf().string())) {\n            SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error(\n                    \"Invalid filename.  Unable to add.\");\n            return UNKNOWN_ERROR;\n        }\n\n        size_t j;\n        for (j = i+1; j < NF; j++) {\n            if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(),\n                           mFiles.valueAt(j)->getLeaf().string()) == 0) {\n                SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error(\n                        \"File is case-insensitive equivalent to: %s\",\n                        mFiles.valueAt(j)->getPrintableSource().string());\n                return UNKNOWN_ERROR;\n            }\n\n            // TODO: if \".gz\", check for non-.gz; if non-, check for \".gz\"\n            // (this is mostly caught by the \"marked\" stuff, below)\n        }\n\n        for (j = 0; j < ND; j++) {\n            if (strcasecmp(mFiles.valueAt(i)->getLeaf().string(),\n                           mDirs.valueAt(j)->getLeaf().string()) == 0) {\n                SourcePos(mFiles.valueAt(i)->getPrintableSource(), -1).error(\n                        \"File conflicts with dir from: %s\",\n                        mDirs.valueAt(j)->getPrintableSource().string());\n                return UNKNOWN_ERROR;\n            }\n        }\n    }\n\n    for (i = 0; i < ND; i++) {\n        if (!validateFileName(mDirs.valueAt(i)->getLeaf().string())) {\n            SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error(\n                    \"Invalid directory name, unable to add.\");\n            return UNKNOWN_ERROR;\n        }\n\n        size_t j;\n        for (j = i+1; j < ND; j++) {\n            if (strcasecmp(mDirs.valueAt(i)->getLeaf().string(),\n                           mDirs.valueAt(j)->getLeaf().string()) == 0) {\n                SourcePos(mDirs.valueAt(i)->getPrintableSource(), -1).error(\n                        \"Directory is case-insensitive equivalent to: %s\",\n                        mDirs.valueAt(j)->getPrintableSource().string());\n                return UNKNOWN_ERROR;\n            }\n        }\n\n        status_t err = mDirs.valueAt(i)->validate();\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    return NO_ERROR;\n}\n\nvoid AaptDir::print(const String8& prefix) const\n{\n    const size_t ND=getDirs().size();\n    size_t i;\n    for (i=0; i<ND; i++) {\n        getDirs().valueAt(i)->print(prefix);\n    }\n\n    const size_t NF=getFiles().size();\n    for (i=0; i<NF; i++) {\n        getFiles().valueAt(i)->print(prefix);\n    }\n}\n\nString8 AaptDir::getPrintableSource() const\n{\n    if (mFiles.size() > 0) {\n        // Arbitrarily pull the first file out of the list as the source dir.\n        return mFiles.valueAt(0)->getPrintableSource().getPathDir();\n    }\n    if (mDirs.size() > 0) {\n        // Or arbitrarily pull the first dir out of the list as the source dir.\n        return mDirs.valueAt(0)->getPrintableSource().getPathDir();\n    }\n\n    // Should never hit this case, but to be safe...\n    return mPath;\n\n}\n\n// =========================================================================\n// =========================================================================\n// =========================================================================\n\nstatus_t AaptSymbols::applyJavaSymbols(const sp<AaptSymbols>& javaSymbols)\n{\n    status_t err = NO_ERROR;\n    size_t N = javaSymbols->mSymbols.size();\n    for (size_t i=0; i<N; i++) {\n        const String8& name = javaSymbols->mSymbols.keyAt(i);\n        const AaptSymbolEntry& entry = javaSymbols->mSymbols.valueAt(i);\n        ssize_t pos = mSymbols.indexOfKey(name);\n        if (pos < 0) {\n            entry.sourcePos.error(\"Symbol '%s' declared with <java-symbol> not defined\\n\", name.string());\n            err = UNKNOWN_ERROR;\n            continue;\n        }\n        //printf(\"**** setting symbol #%d/%d %s to isJavaSymbol=%d\\n\",\n        //        i, N, name.string(), entry.isJavaSymbol ? 1 : 0);\n        mSymbols.editValueAt(pos).isJavaSymbol = entry.isJavaSymbol;\n    }\n\n    N = javaSymbols->mNestedSymbols.size();\n    for (size_t i=0; i<N; i++) {\n        const String8& name = javaSymbols->mNestedSymbols.keyAt(i);\n        const sp<AaptSymbols>& symbols = javaSymbols->mNestedSymbols.valueAt(i);\n        ssize_t pos = mNestedSymbols.indexOfKey(name);\n        if (pos < 0) {\n            SourcePos pos;\n            pos.error(\"Java symbol dir %s not defined\\n\", name.string());\n            err = UNKNOWN_ERROR;\n            continue;\n        }\n        //printf(\"**** applying java symbols in dir %s\\n\", name.string());\n        status_t myerr = mNestedSymbols.valueAt(pos)->applyJavaSymbols(symbols);\n        if (myerr != NO_ERROR) {\n            err = myerr;\n        }\n    }\n\n    return err;\n}\n\n// =========================================================================\n// =========================================================================\n// =========================================================================\n\nAaptAssets::AaptAssets()\n    : AaptDir(String8(), String8()),\n      mHavePrivateSymbols(false),\n      mChanged(false), mHaveIncludedAssets(false),\n      mRes(NULL) {}\n\nconst SortedVector<AaptGroupEntry>& AaptAssets::getGroupEntries() const {\n    if (mChanged) {\n    }\n    return mGroupEntries;\n}\n\nstatus_t AaptAssets::addFile(const String8& name, const sp<AaptGroup>& file)\n{\n    mChanged = true;\n    return AaptDir::addFile(name, file);\n}\n\nsp<AaptFile> AaptAssets::addFile(\n        const String8& filePath, const AaptGroupEntry& entry,\n        const String8& srcDir, sp<AaptGroup>* outGroup,\n        const String8& resType)\n{\n    sp<AaptDir> dir = this;\n    sp<AaptGroup> group;\n    sp<AaptFile> file;\n    String8 root, remain(filePath), partialPath;\n    while (remain.length() > 0) {\n        root = remain.walkPath(&remain);\n        partialPath.appendPath(root);\n\n        const String8 rootStr(root);\n\n        if (remain.length() == 0) {\n            ssize_t i = dir->getFiles().indexOfKey(rootStr);\n            if (i >= 0) {\n                group = dir->getFiles().valueAt(i);\n            } else {\n                group = new AaptGroup(rootStr, filePath);\n                status_t res = dir->addFile(rootStr, group);\n                if (res != NO_ERROR) {\n                    return NULL;\n                }\n            }\n            file = new AaptFile(srcDir.appendPathCopy(filePath), entry, resType);\n            status_t res = group->addFile(file);\n            if (res != NO_ERROR) {\n                return NULL;\n            }\n            break;\n\n        } else {\n            ssize_t i = dir->getDirs().indexOfKey(rootStr);\n            if (i >= 0) {\n                dir = dir->getDirs().valueAt(i);\n            } else {\n                sp<AaptDir> subdir = new AaptDir(rootStr, partialPath);\n                status_t res = dir->addDir(rootStr, subdir);\n                if (res != NO_ERROR) {\n                    return NULL;\n                }\n                dir = subdir;\n            }\n        }\n    }\n\n    mGroupEntries.add(entry);\n    if (outGroup) *outGroup = group;\n    return file;\n}\n\nvoid AaptAssets::addResource(const String8& leafName, const String8& path,\n                const sp<AaptFile>& file, const String8& resType)\n{\n    sp<AaptDir> res = AaptDir::makeDir(kResString);\n    String8 dirname = file->getGroupEntry().toDirName(resType);\n    sp<AaptDir> subdir = res->makeDir(dirname);\n    sp<AaptGroup> grr = new AaptGroup(leafName, path);\n    grr->addFile(file);\n\n    subdir->addFile(leafName, grr);\n}\n\n\nssize_t AaptAssets::slurpFromArgs(Bundle* bundle)\n{\n    int count;\n    int totalCount = 0;\n    FileType type;\n    const Vector<const char *>& resDirs = bundle->getResourceSourceDirs();\n    const size_t dirCount =resDirs.size();\n    sp<AaptAssets> current = this;\n\n    const int N = bundle->getFileSpecCount();\n\n    /*\n     * If a package manifest was specified, include that first.\n     */\n    if (bundle->getAndroidManifestFile() != NULL) {\n        // place at root of zip.\n        String8 srcFile(bundle->getAndroidManifestFile());\n        addFile(srcFile.getPathLeaf(), AaptGroupEntry(), srcFile.getPathDir(),\n                NULL, String8());\n        totalCount++;\n    }\n\n    /*\n     * If a directory of custom assets was supplied, slurp 'em up.\n     */\n    const Vector<const char*>& assetDirs = bundle->getAssetSourceDirs();\n    const int AN = assetDirs.size();\n    for (int i = 0; i < AN; i++) {\n        FileType type = getFileType(assetDirs[i]);\n        if (type == kFileTypeNonexistent) {\n            fprintf(stderr, \"ERROR: asset directory '%s' does not exist\\n\", assetDirs[i]);\n            return UNKNOWN_ERROR;\n        }\n        if (type != kFileTypeDirectory) {\n            fprintf(stderr, \"ERROR: '%s' is not a directory\\n\", assetDirs[i]);\n            return UNKNOWN_ERROR;\n        }\n\n        String8 assetRoot(assetDirs[i]);\n        sp<AaptDir> assetAaptDir = makeDir(String8(kAssetDir));\n        AaptGroupEntry group;\n        count = assetAaptDir->slurpFullTree(bundle, assetRoot, group,\n                                            String8(), mFullAssetPaths, true);\n        if (count < 0) {\n            totalCount = count;\n            goto bail;\n        }\n        if (count > 0) {\n            mGroupEntries.add(group);\n        }\n        totalCount += count;\n\n        if (bundle->getVerbose()) {\n            printf(\"Found %d custom asset file%s in %s\\n\",\n                   count, (count==1) ? \"\" : \"s\", assetDirs[i]);\n        }\n    }\n\n    /*\n     * If a directory of resource-specific assets was supplied, slurp 'em up.\n     */\n    for (size_t i=0; i<dirCount; i++) {\n        const char *res = resDirs[i];\n        if (res) {\n            type = getFileType(res);\n            if (type == kFileTypeNonexistent) {\n                fprintf(stderr, \"ERROR: resource directory '%s' does not exist\\n\", res);\n                return UNKNOWN_ERROR;\n            }\n            if (type == kFileTypeDirectory) {\n                if (i>0) {\n                    sp<AaptAssets> nextOverlay = new AaptAssets();\n                    current->setOverlay(nextOverlay);\n                    current = nextOverlay;\n                    current->setFullResPaths(mFullResPaths);\n                }\n                count = current->slurpResourceTree(bundle, String8(res));\n                if (i > 0 && count > 0) {\n                  count = current->filter(bundle);\n                }\n\n                if (count < 0) {\n                    totalCount = count;\n                    goto bail;\n                }\n                totalCount += count;\n            }\n            else {\n                fprintf(stderr, \"ERROR: '%s' is not a directory\\n\", res);\n                return UNKNOWN_ERROR;\n            }\n        }\n        \n    }\n    /*\n     * Now do any additional raw files.\n     */\n    for (int arg=0; arg<N; arg++) {\n        const char* assetDir = bundle->getFileSpecEntry(arg);\n\n        FileType type = getFileType(assetDir);\n        if (type == kFileTypeNonexistent) {\n            fprintf(stderr, \"ERROR: input directory '%s' does not exist\\n\", assetDir);\n            return UNKNOWN_ERROR;\n        }\n        if (type != kFileTypeDirectory) {\n            fprintf(stderr, \"ERROR: '%s' is not a directory\\n\", assetDir);\n            return UNKNOWN_ERROR;\n        }\n\n        String8 assetRoot(assetDir);\n\n        if (bundle->getVerbose())\n            printf(\"Processing raw dir '%s'\\n\", (const char*) assetDir);\n\n        /*\n         * Do a recursive traversal of subdir tree.  We don't make any\n         * guarantees about ordering, so we're okay with an inorder search\n         * using whatever order the OS happens to hand back to us.\n         */\n        count = slurpFullTree(bundle, assetRoot, AaptGroupEntry(), String8(), mFullAssetPaths);\n        if (count < 0) {\n            /* failure; report error and remove archive */\n            totalCount = count;\n            goto bail;\n        }\n        totalCount += count;\n\n        if (bundle->getVerbose())\n            printf(\"Found %d asset file%s in %s\\n\",\n                   count, (count==1) ? \"\" : \"s\", assetDir);\n    }\n\n    count = validate();\n    if (count != NO_ERROR) {\n        totalCount = count;\n        goto bail;\n    }\n\n    count = filter(bundle);\n    if (count != NO_ERROR) {\n        totalCount = count;\n        goto bail;\n    }\n\nbail:\n    return totalCount;\n}\n\nssize_t AaptAssets::slurpFullTree(Bundle* bundle, const String8& srcDir,\n                                    const AaptGroupEntry& kind,\n                                    const String8& resType,\n                                    sp<FilePathStore>& fullResPaths)\n{\n    ssize_t res = AaptDir::slurpFullTree(bundle, srcDir, kind, resType, fullResPaths);\n    if (res > 0) {\n        mGroupEntries.add(kind);\n    }\n\n    return res;\n}\n\nssize_t AaptAssets::slurpResourceTree(Bundle* bundle, const String8& srcDir)\n{\n    ssize_t err = 0;\n\n    DIR* dir = opendir(srcDir.string());\n    if (dir == NULL) {\n        fprintf(stderr, \"ERROR: opendir(%s): %s\\n\", srcDir.string(), strerror(errno));\n        return UNKNOWN_ERROR;\n    }\n\n    status_t count = 0;\n\n    /*\n     * Run through the directory, looking for dirs that match the\n     * expected pattern.\n     */\n    while (1) {\n        struct dirent* entry = readdir(dir);\n        if (entry == NULL) {\n            break;\n        }\n\n        if (isHidden(srcDir.string(), entry->d_name)) {\n            continue;\n        }\n\n        String8 subdirName(srcDir);\n        subdirName.appendPath(entry->d_name);\n\n        AaptGroupEntry group;\n        String8 resType;\n        bool b = group.initFromDirName(entry->d_name, &resType);\n        // printf(\"resource directory name: %s %s %s\\n\", srcDir.string(),\n        //         entry->d_name, group.getVersionString().string());\n        if (!b) {\n            fprintf(stderr, \"invalid resource directory name: %s %s\\n\", srcDir.string(),\n                    entry->d_name);\n            err = -1;\n            continue;\n        }\n\n        if (bundle->getMaxResVersion() != NULL && group.getVersionString().length() != 0) {\n            int maxResInt = atoi(bundle->getMaxResVersion());\n            const char *verString = group.getVersionString().string();\n            int dirVersionInt = atoi(verString + 1); // skip 'v' in version name\n            if (dirVersionInt > maxResInt) {\n              fprintf(stderr, \"max res %d, skipping %s\\n\", maxResInt, entry->d_name);\n              continue;\n            }\n        }\n\n        FileType type = getFileType(subdirName.string());\n\n        if (type == kFileTypeDirectory) {\n            sp<AaptDir> dir = makeDir(resType);\n            ssize_t res = dir->slurpFullTree(bundle, subdirName, group,\n                                                resType, mFullResPaths);\n            if (res < 0) {\n                count = res;\n                goto bail;\n            }\n            if (res > 0) {\n                mGroupEntries.add(group);\n                count += res;\n            }\n\n            // Only add this directory if we don't already have a resource dir\n            // for the current type.  This ensures that we only add the dir once\n            // for all configs.\n            sp<AaptDir> rdir = resDir(resType);\n            if (rdir == NULL) {\n                mResDirs.add(dir);\n            }\n        } else {\n            if (bundle->getVerbose()) {\n                fprintf(stderr, \"   (ignoring file '%s')\\n\", subdirName.string());\n            }\n        }\n    }\n\nbail:\n    closedir(dir);\n    dir = NULL;\n\n    if (err != 0) {\n        return err;\n    }\n    return count;\n}\n\nssize_t\nAaptAssets::slurpResourceZip(Bundle* bundle, const char* filename)\n{\n    int count = 0;\n    SortedVector<AaptGroupEntry> entries;\n\n    ZipFile* zip = new ZipFile;\n    status_t err = zip->open(filename, ZipFile::kOpenReadOnly);\n    if (err != NO_ERROR) {\n        fprintf(stderr, \"error opening zip file %s\\n\", filename);\n        count = err;\n        delete zip;\n        return -1;\n    }\n\n    const int N = zip->getNumEntries();\n    for (int i=0; i<N; i++) {\n        ZipEntry* entry = zip->getEntryByIndex(i);\n        if (entry->getDeleted()) {\n            continue;\n        }\n\n        String8 entryName(entry->getFileName());\n\n        String8 dirName = entryName.getPathDir();\n        sp<AaptDir> dir = dirName == \"\" ? this : makeDir(dirName);\n\n        String8 resType;\n        AaptGroupEntry kind;\n\n        String8 remain;\n        if (entryName.walkPath(&remain) == kResourceDir) {\n            // these are the resources, pull their type out of the directory name\n            kind.initFromDirName(remain.walkPath().string(), &resType);\n        } else {\n            // these are untyped and don't have an AaptGroupEntry\n        }\n        if (entries.indexOf(kind) < 0) {\n            entries.add(kind);\n            mGroupEntries.add(kind);\n        }\n\n        // use the one from the zip file if they both exist.\n        dir->removeFile(entryName.getPathLeaf());\n\n        sp<AaptFile> file = new AaptFile(entryName, kind, resType);\n        status_t err = dir->addLeafFile(entryName.getPathLeaf(), file);\n        if (err != NO_ERROR) {\n            fprintf(stderr, \"err=%s entryName=%s\\n\", strerror(err), entryName.string());\n            count = err;\n            goto bail;\n        }\n        file->setCompressionMethod(entry->getCompressionMethod());\n\n#if 0\n        if (entryName == \"AndroidManifest.xml\") {\n            printf(\"AndroidManifest.xml\\n\");\n        }\n        printf(\"\\n\\nfile: %s\\n\", entryName.string());\n#endif\n\n        size_t len = entry->getUncompressedLen();\n        void* data = zip->uncompress(entry);\n        void* buf = file->editData(len);\n        memcpy(buf, data, len);\n\n#if 0\n        const int OFF = 0;\n        const unsigned char* p = (unsigned char*)data;\n        const unsigned char* end = p+len;\n        p += OFF;\n        for (int i=0; i<32 && p < end; i++) {\n            printf(\"0x%03x \", i*0x10 + OFF);\n            for (int j=0; j<0x10 && p < end; j++) {\n                printf(\" %02x\", *p);\n                p++;\n            }\n            printf(\"\\n\");\n        }\n#endif\n\n        free(data);\n\n        count++;\n    }\n\nbail:\n    delete zip;\n    return count;\n}\n\nstatus_t AaptAssets::filter(Bundle* bundle)\n{\n    WeakResourceFilter reqFilter;\n    status_t err = reqFilter.parse(bundle->getConfigurations());\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    uint32_t preferredDensity = 0;\n    if (bundle->getPreferredDensity().size() > 0) {\n        ResTable_config preferredConfig;\n        if (!AaptConfig::parseDensity(bundle->getPreferredDensity().string(), &preferredConfig)) {\n            fprintf(stderr, \"Error parsing preferred density: %s\\n\",\n                    bundle->getPreferredDensity().string());\n            return UNKNOWN_ERROR;\n        }\n        preferredDensity = preferredConfig.density;\n    }\n\n    if (reqFilter.isEmpty() && preferredDensity == 0) {\n        return NO_ERROR;\n    }\n\n    if (bundle->getVerbose()) {\n        if (!reqFilter.isEmpty()) {\n            printf(\"Applying required filter: %s\\n\",\n                    bundle->getConfigurations().string());\n        }\n        if (preferredDensity > 0) {\n            printf(\"Applying preferred density filter: %s\\n\",\n                    bundle->getPreferredDensity().string());\n        }\n    }\n\n    const Vector<sp<AaptDir> >& resdirs = mResDirs;\n    const size_t ND = resdirs.size();\n    for (size_t i=0; i<ND; i++) {\n        const sp<AaptDir>& dir = resdirs.itemAt(i);\n        if (dir->getLeaf() == kValuesDir) {\n            // The \"value\" dir is special since a single file defines\n            // multiple resources, so we can not do filtering on the\n            // files themselves.\n            continue;\n        }\n        if (dir->getLeaf() == kMipmapDir) {\n            // We also skip the \"mipmap\" directory, since the point of this\n            // is to include all densities without stripping.  If you put\n            // other configurations in here as well they won't be stripped\n            // either...  So don't do that.  Seriously.  What is wrong with you?\n            continue;\n        }\n\n        const size_t NG = dir->getFiles().size();\n        for (size_t j=0; j<NG; j++) {\n            sp<AaptGroup> grp = dir->getFiles().valueAt(j);\n\n            // First remove any configurations we know we don't need.\n            for (size_t k=0; k<grp->getFiles().size(); k++) {\n                sp<AaptFile> file = grp->getFiles().valueAt(k);\n                if (k == 0 && grp->getFiles().size() == 1) {\n                    // If this is the only file left, we need to keep it.\n                    // Otherwise the resource IDs we are using will be inconsistent\n                    // with what we get when not stripping.  Sucky, but at least\n                    // for now we can rely on the back-end doing another filtering\n                    // pass to take this out and leave us with this resource name\n                    // containing no entries.\n                    continue;\n                }\n                if (file->getPath().getPathExtension() == \".xml\") {\n                    // We can't remove .xml files at this point, because when\n                    // we parse them they may add identifier resources, so\n                    // removing them can cause our resource identifiers to\n                    // become inconsistent.\n                    continue;\n                }\n                const ResTable_config& config(file->getGroupEntry().toParams());\n                if (!reqFilter.match(config)) {\n                    if (bundle->getVerbose()) {\n                        printf(\"Pruning unneeded resource: %s\\n\",\n                                file->getPrintableSource().string());\n                    }\n                    grp->removeFile(k);\n                    k--;\n                }\n            }\n\n            // Quick check: no preferred filters, nothing more to do.\n            if (preferredDensity == 0) {\n                continue;\n            }\n\n            // Get the preferred density if there is one. We do not match exactly for density.\n            // If our preferred density is hdpi but we only have mdpi and xhdpi resources, we\n            // pick xhdpi.\n            for (size_t k=0; k<grp->getFiles().size(); k++) {\n                sp<AaptFile> file = grp->getFiles().valueAt(k);\n                if (k == 0 && grp->getFiles().size() == 1) {\n                    // If this is the only file left, we need to keep it.\n                    // Otherwise the resource IDs we are using will be inconsistent\n                    // with what we get when not stripping.  Sucky, but at least\n                    // for now we can rely on the back-end doing another filtering\n                    // pass to take this out and leave us with this resource name\n                    // containing no entries.\n                    continue;\n                }\n                if (file->getPath().getPathExtension() == \".xml\") {\n                    // We can't remove .xml files at this point, because when\n                    // we parse them they may add identifier resources, so\n                    // removing them can cause our resource identifiers to\n                    // become inconsistent.\n                    continue;\n                }\n                const ResTable_config& config(file->getGroupEntry().toParams());\n                if (config.density != 0 && config.density != preferredDensity) {\n                    // This is a resource we would prefer not to have.  Check\n                    // to see if have a similar variation that we would like\n                    // to have and, if so, we can drop it.\n                    uint32_t bestDensity = config.density;\n\n                    for (size_t m=0; m<grp->getFiles().size(); m++) {\n                        if (m == k) {\n                            continue;\n                        }\n\n                        sp<AaptFile> mfile = grp->getFiles().valueAt(m);\n                        const ResTable_config& mconfig(mfile->getGroupEntry().toParams());\n                        if (AaptConfig::isSameExcept(config, mconfig, ResTable_config::CONFIG_DENSITY)) {\n                            // See if there is a better density resource\n                            if (mconfig.density < bestDensity &&\n                                    mconfig.density >= preferredDensity &&\n                                    bestDensity > preferredDensity) {\n                                // This density is our preferred density, or between our best density and\n                                // the preferred density, therefore it is better.\n                                bestDensity = mconfig.density;\n                            } else if (mconfig.density > bestDensity &&\n                                    bestDensity < preferredDensity) {\n                                // This density is better than our best density and\n                                // our best density was smaller than our preferred\n                                // density, so it is better.\n                                bestDensity = mconfig.density;\n                            }\n                        }\n                    }\n\n                    if (bestDensity != config.density) {\n                        if (bundle->getVerbose()) {\n                            printf(\"Pruning unneeded resource: %s\\n\",\n                                    file->getPrintableSource().string());\n                        }\n                        grp->removeFile(k);\n                        k--;\n                    }\n                }\n            }\n        }\n    }\n\n    return NO_ERROR;\n}\n\nsp<AaptSymbols> AaptAssets::getSymbolsFor(const String8& name)\n{\n    sp<AaptSymbols> sym = mSymbols.valueFor(name);\n    if (sym == NULL) {\n        sym = new AaptSymbols();\n        mSymbols.add(name, sym);\n    }\n    return sym;\n}\n\nsp<AaptSymbols> AaptAssets::getJavaSymbolsFor(const String8& name)\n{\n    sp<AaptSymbols> sym = mJavaSymbols.valueFor(name);\n    if (sym == NULL) {\n        sym = new AaptSymbols();\n        mJavaSymbols.add(name, sym);\n    }\n    return sym;\n}\n\nstatus_t AaptAssets::applyJavaSymbols()\n{\n    size_t N = mJavaSymbols.size();\n    for (size_t i=0; i<N; i++) {\n        const String8& name = mJavaSymbols.keyAt(i);\n        const sp<AaptSymbols>& symbols = mJavaSymbols.valueAt(i);\n        ssize_t pos = mSymbols.indexOfKey(name);\n        if (pos < 0) {\n            SourcePos pos;\n            pos.error(\"Java symbol dir %s not defined\\n\", name.string());\n            return UNKNOWN_ERROR;\n        }\n        //printf(\"**** applying java symbols in dir %s\\n\", name.string());\n        status_t err = mSymbols.valueAt(pos)->applyJavaSymbols(symbols);\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    return NO_ERROR;\n}\n\nbool AaptAssets::isJavaSymbol(const AaptSymbolEntry& sym, bool includePrivate) const {\n    //printf(\"isJavaSymbol %s: public=%d, includePrivate=%d, isJavaSymbol=%d\\n\",\n    //        sym.name.string(), sym.isPublic ? 1 : 0, includePrivate ? 1 : 0,\n    //        sym.isJavaSymbol ? 1 : 0);\n    if (!mHavePrivateSymbols) return true;\n    if (sym.isPublic) return true;\n    if (includePrivate && sym.isJavaSymbol) return true;\n    return false;\n}\n\nstatus_t AaptAssets::buildIncludedResources(Bundle* bundle)\n{\n    if (mHaveIncludedAssets) {\n        return NO_ERROR;\n    }\n\n    // Add in all includes.\n    const Vector<String8>& includes = bundle->getPackageIncludes();\n    const size_t packageIncludeCount = includes.size();\n    for (size_t i = 0; i < packageIncludeCount; i++) {\n        if (bundle->getVerbose()) {\n            printf(\"Including resources from package: %s\\n\", includes[i].string());\n        }\n\n        if (!mIncludedAssets.addAssetPath(includes[i], NULL)) {\n            fprintf(stderr, \"ERROR: Asset package include '%s' not found.\\n\",\n                    includes[i].string());\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    const String8& featureOfBase = bundle->getFeatureOfPackage();\n    if (!featureOfBase.isEmpty()) {\n        if (bundle->getVerbose()) {\n            printf(\"Including base feature resources from package: %s\\n\",\n                    featureOfBase.string());\n        }\n\n        if (!mIncludedAssets.addAssetPath(featureOfBase, NULL)) {\n            fprintf(stderr, \"ERROR: base feature package '%s' not found.\\n\",\n                    featureOfBase.string());\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    if (bundle->getFeatureAfterPackage().size() > 0){\n        const Vector<String8>& featureStrs = bundle->getFeatureAfterPackage();\n        const size_t numFeatures = featureStrs.size();\n        for (size_t i = 0; i < numFeatures; i++){\n            String8 featureAfter = featureStrs[i];\n            if (!featureAfter.isEmpty()) {\n                if (bundle->getVerbose()) {\n                    printf(\"Including after feature resources from package: %s\\n\",\n                            featureAfter.string());\n                }\n    \n                if (!mIncludedAssets.addAssetPath(featureAfter, NULL)) {\n                    fprintf(stderr, \"ERROR: after feature package '%s' not found.\\n\",\n                            featureAfter.string());\n                    return UNKNOWN_ERROR;\n                }\n            }\n        }\n\n    }\n\n    if (bundle->getFeatureOfPackage().size() > 0){\n        String8 featureOf = bundle->getFeatureOfPackage();\n        if (!featureOf.isEmpty()) {\n            if (bundle->getVerbose()) {\n                printf(\"Including after feature resources from package: %s\\n\",\n                        featureOf.string());\n            }\n    \n            if (!mIncludedAssets.addAssetPath(featureOf, NULL)) {\n                fprintf(stderr, \"ERROR: after feature package '%s' not found.\\n\",\n                        featureOf.string());\n                return UNKNOWN_ERROR;\n            }\n        }\n    }\n\n    if (bundle->getBaselinePackage().size() > 0){\n        String8 baseline = bundle->getBaselinePackage();\n        if (!baseline.isEmpty()) {\n            if (bundle->getVerbose()) {\n                printf(\"Including baseline resources from package: %s\\n\",\n                        baseline.string());\n            }\n    \n            /* if (!mIncludedAssets.addAssetPath(featureOf, NULL)) {\n                fprintf(stderr, \"ERROR: after feature package '%s' not found.\\n\",\n                        featureOf.string());\n                return UNKNOWN_ERROR;\n            } */\n    \n            if (!mBaselineAssets.addAssetPath(baseline, NULL)) {\n                fprintf(stderr, \"ERROR: baseline package '%s' not found.\\n\",\n                        baseline.string());\n                return UNKNOWN_ERROR;\n            }\n        }\n    }\n\n    mHaveIncludedAssets = true;\n\n    return NO_ERROR;\n}\n\nstatus_t AaptAssets::addIncludedResources(const sp<AaptFile>& file)\n{\n    const ResTable& res = getIncludedResources();\n    // XXX dirty!\n    return const_cast<ResTable&>(res).add(file->getData(), file->getSize());\n}\n\nconst ResTable& AaptAssets::getIncludedResources() const\n{\n    return mIncludedAssets.getResources(false);\n}\n\nAssetManager& AaptAssets::getAssetManager()\n{\n    return mIncludedAssets;\n}\n\nconst ResTable& AaptAssets::getBaselineResources() const\n{\n    return mBaselineAssets.getResources(false);\n}\n\nAssetManager& AaptAssets::getBaselineAssetManager()\n{\n    return mBaselineAssets;\n}\n\nvoid AaptAssets::print(const String8& prefix) const\n{\n    String8 innerPrefix(prefix);\n    innerPrefix.append(\"  \");\n    String8 innerInnerPrefix(innerPrefix);\n    innerInnerPrefix.append(\"  \");\n    printf(\"%sConfigurations:\\n\", prefix.string());\n    const size_t N=mGroupEntries.size();\n    for (size_t i=0; i<N; i++) {\n        String8 cname = mGroupEntries.itemAt(i).toDirName(String8());\n        printf(\"%s %s\\n\", prefix.string(),\n                cname != \"\" ? cname.string() : \"(default)\");\n    }\n\n    printf(\"\\n%sFiles:\\n\", prefix.string());\n    AaptDir::print(innerPrefix);\n\n    printf(\"\\n%sResource Dirs:\\n\", prefix.string());\n    const Vector<sp<AaptDir> >& resdirs = mResDirs;\n    const size_t NR = resdirs.size();\n    for (size_t i=0; i<NR; i++) {\n        const sp<AaptDir>& d = resdirs.itemAt(i);\n        printf(\"%s  Type %s\\n\", prefix.string(), d->getLeaf().string());\n        d->print(innerInnerPrefix);\n    }\n}\n\nsp<AaptDir> AaptAssets::resDir(const String8& name) const\n{\n    const Vector<sp<AaptDir> >& resdirs = mResDirs;\n    const size_t N = resdirs.size();\n    for (size_t i=0; i<N; i++) {\n        const sp<AaptDir>& d = resdirs.itemAt(i);\n        if (d->getLeaf() == name) {\n            return d;\n        }\n    }\n    return NULL;\n}\n\nbool\nvalid_symbol_name(const String8& symbol)\n{\n    static char const * const KEYWORDS[] = {\n        \"abstract\", \"assert\", \"boolean\", \"break\",\n        \"byte\", \"case\", \"catch\", \"char\", \"class\", \"const\", \"continue\",\n        \"default\", \"do\", \"double\", \"else\", \"enum\", \"extends\", \"final\",\n        \"finally\", \"float\", \"for\", \"goto\", \"if\", \"implements\", \"import\",\n        \"instanceof\", \"int\", \"interface\", \"long\", \"native\", \"new\", \"package\",\n        \"private\", \"protected\", \"public\", \"return\", \"short\", \"static\",\n        \"strictfp\", \"super\", \"switch\", \"synchronized\", \"this\", \"throw\",\n        \"throws\", \"transient\", \"try\", \"void\", \"volatile\", \"while\",\n        \"true\", \"false\", \"null\",\n        NULL\n    };\n    const char*const* k = KEYWORDS;\n    const char*const s = symbol.string();\n    while (*k) {\n        if (0 == strcmp(s, *k)) {\n            return false;\n        }\n        k++;\n    }\n    return true;\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/AaptAssets.h",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Information about assets being operated on.\n//\n#ifndef __AAPT_ASSETS_H\n#define __AAPT_ASSETS_H\n\n#include <androidfw/AssetManager.h>\n#include <androidfw/ResourceTypes.h>\n#include <stdlib.h>\n#include <set>\n#include <utils/KeyedVector.h>\n#include <utils/RefBase.h>\n#include <utils/SortedVector.h>\n#include <utils/String8.h>\n#include <utils/Vector.h>\n\n#include \"AaptConfig.h\"\n#include \"Bundle.h\"\n#include \"ConfigDescription.h\"\n#include \"SourcePos.h\"\n#include \"ZipFile.h\"\n\nusing namespace android;\n\nextern const char * const gDefaultIgnoreAssets;\nextern const char * gUserIgnoreAssets;\n\nbool valid_symbol_name(const String8& str);\n\nclass AaptAssets;\n\nenum {\n    AXIS_NONE = 0,\n    AXIS_MCC = 1,\n    AXIS_MNC,\n    AXIS_LOCALE,\n    AXIS_SCREENLAYOUTSIZE,\n    AXIS_SCREENLAYOUTLONG,\n    AXIS_ORIENTATION,\n    AXIS_UIMODETYPE,\n    AXIS_UIMODENIGHT,\n    AXIS_DENSITY,\n    AXIS_TOUCHSCREEN,\n    AXIS_KEYSHIDDEN,\n    AXIS_KEYBOARD,\n    AXIS_NAVHIDDEN,\n    AXIS_NAVIGATION,\n    AXIS_SCREENSIZE,\n    AXIS_SMALLESTSCREENWIDTHDP,\n    AXIS_SCREENWIDTHDP,\n    AXIS_SCREENHEIGHTDP,\n    AXIS_LAYOUTDIR,\n    AXIS_VERSION,\n\n    AXIS_START = AXIS_MCC,\n    AXIS_END = AXIS_VERSION,\n};\n\nstruct AaptLocaleValue {\n     char language[4];\n     char region[4];\n     char script[4];\n     char variant[8];\n\n     AaptLocaleValue() {\n         memset(this, 0, sizeof(AaptLocaleValue));\n     }\n\n     // Initialize this AaptLocaleValue from a config string.\n     bool initFromFilterString(const String8& config);\n\n     int initFromDirName(const Vector<String8>& parts, const int startIndex);\n\n     // Initialize this AaptLocaleValue from a ResTable_config.\n     void initFromResTable(const ResTable_config& config);\n\n     void writeTo(ResTable_config* out) const;\n\n     String8 toDirName() const;\n\n     int compare(const AaptLocaleValue& other) const {\n         return memcmp(this, &other, sizeof(AaptLocaleValue));\n     }\n\n     inline bool operator<(const AaptLocaleValue& o) const { return compare(o) < 0; }\n     inline bool operator<=(const AaptLocaleValue& o) const { return compare(o) <= 0; }\n     inline bool operator==(const AaptLocaleValue& o) const { return compare(o) == 0; }\n     inline bool operator!=(const AaptLocaleValue& o) const { return compare(o) != 0; }\n     inline bool operator>=(const AaptLocaleValue& o) const { return compare(o) >= 0; }\n     inline bool operator>(const AaptLocaleValue& o) const { return compare(o) > 0; }\nprivate:\n     void setLanguage(const char* language);\n     void setRegion(const char* language);\n     void setScript(const char* script);\n     void setVariant(const char* variant);\n};\n\n/**\n * This structure contains a specific variation of a single file out\n * of all the variations it can have that we can have.\n */\nstruct AaptGroupEntry\n{\npublic:\n    AaptGroupEntry() {}\n    AaptGroupEntry(const ConfigDescription& config) : mParams(config) {}\n\n    bool initFromDirName(const char* dir, String8* resType);\n\n    inline const ConfigDescription& toParams() const { return mParams; }\n\n    inline int compare(const AaptGroupEntry& o) const { return mParams.compareLogical(o.mParams); }\n    inline bool operator<(const AaptGroupEntry& o) const { return compare(o) < 0; }\n    inline bool operator<=(const AaptGroupEntry& o) const { return compare(o) <= 0; }\n    inline bool operator==(const AaptGroupEntry& o) const { return compare(o) == 0; }\n    inline bool operator!=(const AaptGroupEntry& o) const { return compare(o) != 0; }\n    inline bool operator>=(const AaptGroupEntry& o) const { return compare(o) >= 0; }\n    inline bool operator>(const AaptGroupEntry& o) const { return compare(o) > 0; }\n\n    String8 toString() const { return mParams.toString(); }\n    String8 toDirName(const String8& resType) const;\n\n    const String8 getVersionString() const { return AaptConfig::getVersion(mParams); }\n\nprivate:\n    ConfigDescription mParams;\n};\n\ninline int compare_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs)\n{\n    return lhs.compare(rhs);\n}\n\ninline int strictly_order_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs)\n{\n    return compare_type(lhs, rhs) < 0;\n}\n\nclass AaptGroup;\nclass FilePathStore;\n\n/**\n * A single asset file we know about.\n */\nclass AaptFile : public RefBase\n{\npublic:\n    AaptFile(const String8& sourceFile, const AaptGroupEntry& groupEntry,\n             const String8& resType)\n        : mGroupEntry(groupEntry)\n        , mResourceType(resType)\n        , mSourceFile(sourceFile)\n        , mData(NULL)\n        , mDataSize(0)\n        , mBufferSize(0)\n        , mCompression(ZipEntry::kCompressStored)\n        {\n            //printf(\"new AaptFile created %s\\n\", (const char*)sourceFile);\n        }\n    virtual ~AaptFile() {\n        free(mData);\n    }\n\n    const String8& getPath() const { return mPath; }\n    const AaptGroupEntry& getGroupEntry() const { return mGroupEntry; }\n\n    // Data API.  If there is data attached to the file,\n    // getSourceFile() is not used.\n    bool hasData() const { return mData != NULL; }\n    const void* getData() const { return mData; }\n    size_t getSize() const { return mDataSize; }\n    void* editData(size_t size);\n    void* editData(size_t* outSize = NULL);\n    void* editDataInRange(size_t offset, size_t size);\n    void* padData(size_t wordSize);\n    status_t writeData(const void* data, size_t size);\n    void clearData();\n\n    const String8& getResourceType() const { return mResourceType; }\n\n    // File API.  If the file does not hold raw data, this is\n    // a full path to a file on the filesystem that holds its data.\n    const String8& getSourceFile() const { return mSourceFile; }\n\n    String8 getPrintableSource() const;\n\n    // Desired compression method, as per utils/ZipEntry.h.  For example,\n    // no compression is ZipEntry::kCompressStored.\n    int getCompressionMethod() const { return mCompression; }\n    void setCompressionMethod(int c) { mCompression = c; }\nprivate:\n    friend class AaptGroup;\n\n    String8 mPath;\n    AaptGroupEntry mGroupEntry;\n    String8 mResourceType;\n    String8 mSourceFile;\n    void* mData;\n    size_t mDataSize;\n    size_t mBufferSize;\n    int mCompression;\n};\n\n/**\n * A group of related files (the same file, with different\n * vendor/locale variations).\n */\nclass AaptGroup : public RefBase\n{\npublic:\n    AaptGroup(const String8& leaf, const String8& path)\n        : mLeaf(leaf), mPath(path) { }\n    virtual ~AaptGroup() { }\n\n    const String8& getLeaf() const { return mLeaf; }\n\n    // Returns the relative path after the AaptGroupEntry dirs.\n    const String8& getPath() const { return mPath; }\n\n    const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& getFiles() const\n        { return mFiles; }\n\n    status_t addFile(const sp<AaptFile>& file, const bool overwriteDuplicate=false);\n    void removeFile(size_t index);\n\n    void print(const String8& prefix) const;\n\n    String8 getPrintableSource() const;\n\nprivate:\n    String8 mLeaf;\n    String8 mPath;\n\n    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > mFiles;\n};\n\n/**\n * A single directory of assets, which can contain files and other\n * sub-directories.\n */\nclass AaptDir : public RefBase\n{\npublic:\n    AaptDir(const String8& leaf, const String8& path)\n        : mLeaf(leaf), mPath(path) { }\n    virtual ~AaptDir() { }\n\n    const String8& getLeaf() const { return mLeaf; }\n\n    const String8& getPath() const { return mPath; }\n\n    const DefaultKeyedVector<String8, sp<AaptGroup> >& getFiles() const { return mFiles; }\n    const DefaultKeyedVector<String8, sp<AaptDir> >& getDirs() const { return mDirs; }\n\n    virtual status_t addFile(const String8& name, const sp<AaptGroup>& file);\n\n    void removeFile(const String8& name);\n    void removeDir(const String8& name);\n\n    /*\n     * Perform some sanity checks on the names of files and directories here.\n     * In particular:\n     *  - Check for illegal chars in filenames.\n     *  - Check filename length.\n     *  - Check for presence of \".gz\" and non-\".gz\" copies of same file.\n     *  - Check for multiple files whose names match in a case-insensitive\n     *    fashion (problematic for some systems).\n     *\n     * Comparing names against all other names is O(n^2).  We could speed\n     * it up some by sorting the entries and being smarter about what we\n     * compare against, but I'm not expecting to have enough files in a\n     * single directory to make a noticeable difference in speed.\n     *\n     * Note that sorting here is not enough to guarantee that the package\n     * contents are sorted -- subsequent updates can rearrange things.\n     */\n    status_t validate() const;\n\n    void print(const String8& prefix) const;\n\n    String8 getPrintableSource() const;\n\nprivate:\n    friend class AaptAssets;\n\n    status_t addDir(const String8& name, const sp<AaptDir>& dir);\n    sp<AaptDir> makeDir(const String8& name);\n    status_t addLeafFile(const String8& leafName,\n                         const sp<AaptFile>& file,\n                         const bool overwrite=false);\n    virtual ssize_t slurpFullTree(Bundle* bundle,\n                                  const String8& srcDir,\n                                  const AaptGroupEntry& kind,\n                                  const String8& resType,\n                                  sp<FilePathStore>& fullResPaths,\n                                  const bool overwrite=false);\n\n    String8 mLeaf;\n    String8 mPath;\n\n    DefaultKeyedVector<String8, sp<AaptGroup> > mFiles;\n    DefaultKeyedVector<String8, sp<AaptDir> > mDirs;\n};\n\n/**\n * All information we know about a particular symbol.\n */\nclass AaptSymbolEntry\n{\npublic:\n    AaptSymbolEntry()\n        : isPublic(false), isJavaSymbol(false), typeCode(TYPE_UNKNOWN)\n    {\n    }\n    AaptSymbolEntry(const String8& _name)\n        : name(_name), isPublic(false), isJavaSymbol(false), typeCode(TYPE_UNKNOWN)\n    {\n    }\n    AaptSymbolEntry(const AaptSymbolEntry& o)\n        : name(o.name), sourcePos(o.sourcePos), isPublic(o.isPublic)\n        , isJavaSymbol(o.isJavaSymbol), comment(o.comment), typeComment(o.typeComment)\n        , typeCode(o.typeCode), int32Val(o.int32Val), stringVal(o.stringVal)\n    {\n    }\n    AaptSymbolEntry operator=(const AaptSymbolEntry& o)\n    {\n        sourcePos = o.sourcePos;\n        isPublic = o.isPublic;\n        isJavaSymbol = o.isJavaSymbol;\n        comment = o.comment;\n        typeComment = o.typeComment;\n        typeCode = o.typeCode;\n        int32Val = o.int32Val;\n        stringVal = o.stringVal;\n        return *this;\n    }\n    \n    const String8 name;\n    \n    SourcePos sourcePos;\n    bool isPublic;\n    bool isJavaSymbol;\n    \n    String16 comment;\n    String16 typeComment;\n    \n    enum {\n        TYPE_UNKNOWN = 0,\n        TYPE_INT32,\n        TYPE_STRING\n    };\n    \n    int typeCode;\n    \n    // Value.  May be one of these.\n    int32_t int32Val;\n    String8 stringVal;\n};\n\n/**\n * A group of related symbols (such as indices into a string block)\n * that have been generated from the assets.\n */\nclass AaptSymbols : public RefBase\n{\npublic:\n    AaptSymbols() { }\n    virtual ~AaptSymbols() { }\n\n    status_t addSymbol(const String8& name, int32_t value, const SourcePos& pos) {\n        if (!check_valid_symbol_name(name, pos, \"symbol\")) {\n            return BAD_VALUE;\n        }\n        AaptSymbolEntry& sym = edit_symbol(name, &pos);\n        sym.typeCode = AaptSymbolEntry::TYPE_INT32;\n        sym.int32Val = value;\n        return NO_ERROR;\n    }\n\n    status_t addStringSymbol(const String8& name, const String8& value,\n            const SourcePos& pos) {\n        if (!check_valid_symbol_name(name, pos, \"symbol\")) {\n            return BAD_VALUE;\n        }\n        AaptSymbolEntry& sym = edit_symbol(name, &pos);\n        sym.typeCode = AaptSymbolEntry::TYPE_STRING;\n        sym.stringVal = value;\n        return NO_ERROR;\n    }\n\n    status_t makeSymbolPublic(const String8& name, const SourcePos& pos) {\n        if (!check_valid_symbol_name(name, pos, \"symbol\")) {\n            return BAD_VALUE;\n        }\n        AaptSymbolEntry& sym = edit_symbol(name, &pos);\n        sym.isPublic = true;\n        return NO_ERROR;\n    }\n\n    status_t makeSymbolJavaSymbol(const String8& name, const SourcePos& pos) {\n        if (!check_valid_symbol_name(name, pos, \"symbol\")) {\n            return BAD_VALUE;\n        }\n        AaptSymbolEntry& sym = edit_symbol(name, &pos);\n        sym.isJavaSymbol = true;\n        return NO_ERROR;\n    }\n\n    void appendComment(const String8& name, const String16& comment, const SourcePos& pos) {\n        if (comment.size() <= 0) {\n            return;\n        }\n        AaptSymbolEntry& sym = edit_symbol(name, &pos);\n        if (sym.comment.size() == 0) {\n            sym.comment = comment;\n        } else {\n            sym.comment.append(String16(\"\\n\"));\n            sym.comment.append(comment);\n        }\n    }\n\n    void appendTypeComment(const String8& name, const String16& comment) {\n        if (comment.size() <= 0) {\n            return;\n        }\n        AaptSymbolEntry& sym = edit_symbol(name, NULL);\n        if (sym.typeComment.size() == 0) {\n            sym.typeComment = comment;\n        } else {\n            sym.typeComment.append(String16(\"\\n\"));\n            sym.typeComment.append(comment);\n        }\n    }\n    \n    sp<AaptSymbols> addNestedSymbol(const String8& name, const SourcePos& pos) {\n        if (!check_valid_symbol_name(name, pos, \"nested symbol\")) {\n            return NULL;\n        }\n        \n        sp<AaptSymbols> sym = mNestedSymbols.valueFor(name);\n        if (sym == NULL) {\n            sym = new AaptSymbols();\n            mNestedSymbols.add(name, sym);\n        }\n\n        return sym;\n    }\n\n    status_t applyJavaSymbols(const sp<AaptSymbols>& javaSymbols);\n\n    const KeyedVector<String8, AaptSymbolEntry>& getSymbols() const\n        { return mSymbols; }\n    const DefaultKeyedVector<String8, sp<AaptSymbols> >& getNestedSymbols() const\n        { return mNestedSymbols; }\n\n    const String16& getComment(const String8& name) const\n        { return get_symbol(name).comment; }\n    const String16& getTypeComment(const String8& name) const\n        { return get_symbol(name).typeComment; }\n\nprivate:\n    bool check_valid_symbol_name(const String8& symbol, const SourcePos& pos, const char* label) {\n        if (valid_symbol_name(symbol)) {\n            return true;\n        }\n        pos.error(\"invalid %s: '%s'\\n\", label, symbol.string());\n        return false;\n    }\n    AaptSymbolEntry& edit_symbol(const String8& symbol, const SourcePos* pos) {\n        ssize_t i = mSymbols.indexOfKey(symbol);\n        if (i < 0) {\n            i = mSymbols.add(symbol, AaptSymbolEntry(symbol));\n        }\n        AaptSymbolEntry& sym = mSymbols.editValueAt(i);\n        if (pos != NULL && sym.sourcePos.line < 0) {\n            sym.sourcePos = *pos;\n        }\n        return sym;\n    }\n    const AaptSymbolEntry& get_symbol(const String8& symbol) const {\n        ssize_t i = mSymbols.indexOfKey(symbol);\n        if (i >= 0) {\n            return mSymbols.valueAt(i);\n        }\n        return mDefSymbol;\n    }\n\n    KeyedVector<String8, AaptSymbolEntry>           mSymbols;\n    DefaultKeyedVector<String8, sp<AaptSymbols> >   mNestedSymbols;\n    AaptSymbolEntry                                 mDefSymbol;\n};\n\nclass ResourceTypeSet : public RefBase,\n                        public KeyedVector<String8,sp<AaptGroup> >\n{\npublic:\n    ResourceTypeSet();\n};\n\n// Storage for lists of fully qualified paths for\n// resources encountered during slurping.\nclass FilePathStore : public RefBase,\n                      public Vector<String8>\n{\npublic:\n    FilePathStore();\n};\n\n/**\n * Asset hierarchy being operated on.\n */\nclass AaptAssets : public AaptDir\n{\npublic:\n    AaptAssets();\n    virtual ~AaptAssets() { delete mRes; }\n\n    const String8& getPackage() const { return mPackage; }\n    void setPackage(const String8& package) {\n        mPackage = package;\n        mSymbolsPrivatePackage = package;\n        mHavePrivateSymbols = false;\n    }\n\n    const SortedVector<AaptGroupEntry>& getGroupEntries() const;\n\n    virtual status_t addFile(const String8& name, const sp<AaptGroup>& file);\n\n    sp<AaptFile> addFile(const String8& filePath,\n                         const AaptGroupEntry& entry,\n                         const String8& srcDir,\n                         sp<AaptGroup>* outGroup,\n                         const String8& resType);\n\n    void addResource(const String8& leafName,\n                     const String8& path,\n                     const sp<AaptFile>& file,\n                     const String8& resType);\n\n    void addGroupEntry(const AaptGroupEntry& entry) { mGroupEntries.add(entry); }\n    \n    ssize_t slurpFromArgs(Bundle* bundle);\n\n    sp<AaptSymbols> getSymbolsFor(const String8& name);\n\n    sp<AaptSymbols> getJavaSymbolsFor(const String8& name);\n\n    status_t applyJavaSymbols();\n\n    const DefaultKeyedVector<String8, sp<AaptSymbols> >& getSymbols() const { return mSymbols; }\n\n    String8 getSymbolsPrivatePackage() const { return mSymbolsPrivatePackage; }\n    void setSymbolsPrivatePackage(const String8& pkg) {\n        mSymbolsPrivatePackage = pkg;\n        mHavePrivateSymbols = mSymbolsPrivatePackage != mPackage;\n    }\n\n    bool havePrivateSymbols() const { return mHavePrivateSymbols; }\n\n    bool isJavaSymbol(const AaptSymbolEntry& sym, bool includePrivate) const;\n\n    status_t buildIncludedResources(Bundle* bundle);\n    status_t addIncludedResources(const sp<AaptFile>& file);\n    const ResTable& getIncludedResources() const;\n    AssetManager& getAssetManager();\n    const ResTable& getBaselineResources() const;\n    AssetManager& getBaselineAssetManager();\n\n    void print(const String8& prefix) const;\n\n    inline const Vector<sp<AaptDir> >& resDirs() const { return mResDirs; }\n    sp<AaptDir> resDir(const String8& name) const;\n\n    inline sp<AaptAssets> getOverlay() { return mOverlay; }\n    inline void setOverlay(sp<AaptAssets>& overlay) { mOverlay = overlay; }\n    \n    inline KeyedVector<String8, sp<ResourceTypeSet> >* getResources() { return mRes; }\n    inline void \n        setResources(KeyedVector<String8, sp<ResourceTypeSet> >* res) { delete mRes; mRes = res; }\n\n    inline sp<FilePathStore>& getFullResPaths() { return mFullResPaths; }\n    inline void\n        setFullResPaths(sp<FilePathStore>& res) { mFullResPaths = res; }\n\n    inline sp<FilePathStore>& getFullAssetPaths() { return mFullAssetPaths; }\n    inline void\n        setFullAssetPaths(sp<FilePathStore>& res) { mFullAssetPaths = res; }\n\nprivate:\n    virtual ssize_t slurpFullTree(Bundle* bundle,\n                                  const String8& srcDir,\n                                  const AaptGroupEntry& kind,\n                                  const String8& resType,\n                                  sp<FilePathStore>& fullResPaths);\n\n    ssize_t slurpResourceTree(Bundle* bundle, const String8& srcDir);\n    ssize_t slurpResourceZip(Bundle* bundle, const char* filename);\n\n    status_t filter(Bundle* bundle);\n\n    String8 mPackage;\n    SortedVector<AaptGroupEntry> mGroupEntries;\n    DefaultKeyedVector<String8, sp<AaptSymbols> > mSymbols;\n    DefaultKeyedVector<String8, sp<AaptSymbols> > mJavaSymbols;\n    String8 mSymbolsPrivatePackage;\n    bool mHavePrivateSymbols;\n\n    Vector<sp<AaptDir> > mResDirs;\n\n    bool mChanged;\n\n    bool mHaveIncludedAssets;\n    AssetManager mIncludedAssets;\n    AssetManager mBaselineAssets;\n\n    sp<AaptAssets> mOverlay;\n    KeyedVector<String8, sp<ResourceTypeSet> >* mRes;\n\n    sp<FilePathStore> mFullResPaths;\n    sp<FilePathStore> mFullAssetPaths;\n};\n\n#endif // __AAPT_ASSETS_H\n\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/AaptConfig.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n#include <ctype.h>\n\n#include \"AaptConfig.h\"\n#include \"AaptAssets.h\"\n#include \"AaptUtil.h\"\n#include \"ResourceFilter.h\"\n\nusing android::String8;\nusing android::Vector;\nusing android::ResTable_config;\n\nnamespace AaptConfig {\n\nstatic const char* kWildcardName = \"any\";\n\nbool parse(const String8& str, ConfigDescription* out) {\n    Vector<String8> parts = AaptUtil::splitAndLowerCase(str, '-');\n\n    ConfigDescription config;\n    AaptLocaleValue locale;\n    ssize_t index = 0;\n    ssize_t localeIndex = 0;\n    const ssize_t N = parts.size();\n    const char* part = parts[index].string();\n\n    if (str.length() == 0) {\n        goto success;\n    }\n\n    if (parseMcc(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseMnc(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    // Locale spans a few '-' separators, so we let it\n    // control the index.\n    localeIndex = locale.initFromDirName(parts, index);\n    if (localeIndex < 0) {\n        return false;\n    } else if (localeIndex > index) {\n        locale.writeTo(&config);\n        index = localeIndex;\n        if (index >= N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseLayoutDirection(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseSmallestScreenWidthDp(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseScreenWidthDp(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseScreenHeightDp(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseScreenLayoutSize(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseScreenLayoutLong(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseOrientation(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseUiModeType(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseUiModeNight(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseDensity(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseTouchscreen(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseKeysHidden(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseKeyboard(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseNavHidden(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseNavigation(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseScreenSize(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    if (parseVersion(part, &config)) {\n        index++;\n        if (index == N) {\n            goto success;\n        }\n        part = parts[index].string();\n    }\n\n    // Unrecognized.\n    return false;\n\nsuccess:\n    if (out != NULL) {\n        // applyVersionForCompatibility(&config);\n        *out = config;\n    }\n    return true;\n}\n\nbool parseCommaSeparatedList(const String8& str, std::set<ConfigDescription>* outSet) {\n    Vector<String8> parts = AaptUtil::splitAndLowerCase(str, ',');\n    const size_t N = parts.size();\n    for (size_t i = 0; i < N; i++) {\n        ConfigDescription config;\n        if (!parse(parts[i], &config)) {\n            return false;\n        }\n        outSet->insert(config);\n    }\n    return true;\n}\n\nvoid applyVersionForCompatibility(ConfigDescription* config) {\n    if (config == NULL) {\n        return;\n    }\n\n    uint16_t minSdk = 0;\n    if (config->smallestScreenWidthDp != ResTable_config::SCREENWIDTH_ANY\n            || config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY\n            || config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {\n        minSdk = SDK_HONEYCOMB_MR2;\n    } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE)\n                != ResTable_config::UI_MODE_TYPE_ANY\n            ||  (config->uiMode & ResTable_config::MASK_UI_MODE_NIGHT)\n                != ResTable_config::UI_MODE_NIGHT_ANY) {\n        minSdk = SDK_FROYO;\n    } else if ((config->screenLayout & ResTable_config::MASK_SCREENSIZE)\n                != ResTable_config::SCREENSIZE_ANY\n            ||  (config->screenLayout & ResTable_config::MASK_SCREENLONG)\n                != ResTable_config::SCREENLONG_ANY\n            || config->density != ResTable_config::DENSITY_DEFAULT) {\n        minSdk = SDK_DONUT;\n    } else if ((config->density == ResTable_config::DENSITY_ANY)) {\n        minSdk = SDK_L;\n    }\n\n    if (minSdk > config->sdkVersion) {\n        config->sdkVersion = minSdk;\n    }\n}\n\nbool parseMcc(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->mcc = 0;\n        return true;\n    }\n    const char* c = name;\n    if (tolower(*c) != 'm') return false;\n    c++;\n    if (tolower(*c) != 'c') return false;\n    c++;\n    if (tolower(*c) != 'c') return false;\n    c++;\n\n    const char* val = c;\n\n    while (*c >= '0' && *c <= '9') {\n        c++;\n    }\n    if (*c != 0) return false;\n    if (c-val != 3) return false;\n\n    int d = atoi(val);\n    if (d != 0) {\n        if (out) out->mcc = d;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseMnc(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->mcc = 0;\n        return true;\n    }\n    const char* c = name;\n    if (tolower(*c) != 'm') return false;\n    c++;\n    if (tolower(*c) != 'n') return false;\n    c++;\n    if (tolower(*c) != 'c') return false;\n    c++;\n\n    const char* val = c;\n\n    while (*c >= '0' && *c <= '9') {\n        c++;\n    }\n    if (*c != 0) return false;\n    if (c-val == 0 || c-val > 3) return false;\n\n    if (out) {\n        out->mnc = atoi(val);\n        if (out->mnc == 0) {\n            out->mnc = ACONFIGURATION_MNC_ZERO;\n        }\n    }\n\n    return true;\n}\n\nbool parseLayoutDirection(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)\n                | ResTable_config::LAYOUTDIR_ANY;\n        return true;\n    } else if (strcmp(name, \"ldltr\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)\n                | ResTable_config::LAYOUTDIR_LTR;\n        return true;\n    } else if (strcmp(name, \"ldrtl\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)\n                | ResTable_config::LAYOUTDIR_RTL;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseScreenLayoutSize(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)\n                | ResTable_config::SCREENSIZE_ANY;\n        return true;\n    } else if (strcmp(name, \"small\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)\n                | ResTable_config::SCREENSIZE_SMALL;\n        return true;\n    } else if (strcmp(name, \"normal\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)\n                | ResTable_config::SCREENSIZE_NORMAL;\n        return true;\n    } else if (strcmp(name, \"large\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)\n                | ResTable_config::SCREENSIZE_LARGE;\n        return true;\n    } else if (strcmp(name, \"xlarge\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)\n                | ResTable_config::SCREENSIZE_XLARGE;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseScreenLayoutLong(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)\n                | ResTable_config::SCREENLONG_ANY;\n        return true;\n    } else if (strcmp(name, \"long\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)\n                | ResTable_config::SCREENLONG_YES;\n        return true;\n    } else if (strcmp(name, \"notlong\") == 0) {\n        if (out) out->screenLayout =\n                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)\n                | ResTable_config::SCREENLONG_NO;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseOrientation(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->orientation = out->ORIENTATION_ANY;\n        return true;\n    } else if (strcmp(name, \"port\") == 0) {\n        if (out) out->orientation = out->ORIENTATION_PORT;\n        return true;\n    } else if (strcmp(name, \"land\") == 0) {\n        if (out) out->orientation = out->ORIENTATION_LAND;\n        return true;\n    } else if (strcmp(name, \"square\") == 0) {\n        if (out) out->orientation = out->ORIENTATION_SQUARE;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseUiModeType(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->uiMode =\n                (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n                | ResTable_config::UI_MODE_TYPE_ANY;\n        return true;\n    } else if (strcmp(name, \"desk\") == 0) {\n      if (out) out->uiMode =\n              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n              | ResTable_config::UI_MODE_TYPE_DESK;\n        return true;\n    } else if (strcmp(name, \"car\") == 0) {\n      if (out) out->uiMode =\n              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n              | ResTable_config::UI_MODE_TYPE_CAR;\n        return true;\n    } else if (strcmp(name, \"television\") == 0) {\n      if (out) out->uiMode =\n              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n              | ResTable_config::UI_MODE_TYPE_TELEVISION;\n        return true;\n    } else if (strcmp(name, \"appliance\") == 0) {\n      if (out) out->uiMode =\n              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n              | ResTable_config::UI_MODE_TYPE_APPLIANCE;\n        return true;\n    } else if (strcmp(name, \"watch\") == 0) {\n      if (out) out->uiMode =\n              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)\n              | ResTable_config::UI_MODE_TYPE_WATCH;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseUiModeNight(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->uiMode =\n                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)\n                | ResTable_config::UI_MODE_NIGHT_ANY;\n        return true;\n    } else if (strcmp(name, \"night\") == 0) {\n        if (out) out->uiMode =\n                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)\n                | ResTable_config::UI_MODE_NIGHT_YES;\n        return true;\n    } else if (strcmp(name, \"notnight\") == 0) {\n      if (out) out->uiMode =\n              (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)\n              | ResTable_config::UI_MODE_NIGHT_NO;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseDensity(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->density = ResTable_config::DENSITY_DEFAULT;\n        return true;\n    }\n\n    if (strcmp(name, \"anydpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_ANY;\n        return true;\n    }\n\n    if (strcmp(name, \"nodpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_NONE;\n        return true;\n    }\n\n    if (strcmp(name, \"ldpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_LOW;\n        return true;\n    }\n\n    if (strcmp(name, \"mdpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_MEDIUM;\n        return true;\n    }\n\n    if (strcmp(name, \"tvdpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_TV;\n        return true;\n    }\n\n    if (strcmp(name, \"hdpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_HIGH;\n        return true;\n    }\n\n    if (strcmp(name, \"xhdpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_XHIGH;\n        return true;\n    }\n\n    if (strcmp(name, \"xxhdpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_XXHIGH;\n        return true;\n    }\n\n    if (strcmp(name, \"xxxhdpi\") == 0) {\n        if (out) out->density = ResTable_config::DENSITY_XXXHIGH;\n        return true;\n    }\n\n    char* c = (char*)name;\n    while (*c >= '0' && *c <= '9') {\n        c++;\n    }\n\n    // check that we have 'dpi' after the last digit.\n    if (toupper(c[0]) != 'D' ||\n            toupper(c[1]) != 'P' ||\n            toupper(c[2]) != 'I' ||\n            c[3] != 0) {\n        return false;\n    }\n\n    // temporarily replace the first letter with \\0 to\n    // use atoi.\n    char tmp = c[0];\n    c[0] = '\\0';\n\n    int d = atoi(name);\n    c[0] = tmp;\n\n    if (d != 0) {\n        if (out) out->density = d;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseTouchscreen(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->touchscreen = out->TOUCHSCREEN_ANY;\n        return true;\n    } else if (strcmp(name, \"notouch\") == 0) {\n        if (out) out->touchscreen = out->TOUCHSCREEN_NOTOUCH;\n        return true;\n    } else if (strcmp(name, \"stylus\") == 0) {\n        if (out) out->touchscreen = out->TOUCHSCREEN_STYLUS;\n        return true;\n    } else if (strcmp(name, \"finger\") == 0) {\n        if (out) out->touchscreen = out->TOUCHSCREEN_FINGER;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseKeysHidden(const char* name, ResTable_config* out) {\n    uint8_t mask = 0;\n    uint8_t value = 0;\n    if (strcmp(name, kWildcardName) == 0) {\n        mask = ResTable_config::MASK_KEYSHIDDEN;\n        value = ResTable_config::KEYSHIDDEN_ANY;\n    } else if (strcmp(name, \"keysexposed\") == 0) {\n        mask = ResTable_config::MASK_KEYSHIDDEN;\n        value = ResTable_config::KEYSHIDDEN_NO;\n    } else if (strcmp(name, \"keyshidden\") == 0) {\n        mask = ResTable_config::MASK_KEYSHIDDEN;\n        value = ResTable_config::KEYSHIDDEN_YES;\n    } else if (strcmp(name, \"keyssoft\") == 0) {\n        mask = ResTable_config::MASK_KEYSHIDDEN;\n        value = ResTable_config::KEYSHIDDEN_SOFT;\n    }\n\n    if (mask != 0) {\n        if (out) out->inputFlags = (out->inputFlags&~mask) | value;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseKeyboard(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->keyboard = out->KEYBOARD_ANY;\n        return true;\n    } else if (strcmp(name, \"nokeys\") == 0) {\n        if (out) out->keyboard = out->KEYBOARD_NOKEYS;\n        return true;\n    } else if (strcmp(name, \"qwerty\") == 0) {\n        if (out) out->keyboard = out->KEYBOARD_QWERTY;\n        return true;\n    } else if (strcmp(name, \"12key\") == 0) {\n        if (out) out->keyboard = out->KEYBOARD_12KEY;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseNavHidden(const char* name, ResTable_config* out) {\n    uint8_t mask = 0;\n    uint8_t value = 0;\n    if (strcmp(name, kWildcardName) == 0) {\n        mask = ResTable_config::MASK_NAVHIDDEN;\n        value = ResTable_config::NAVHIDDEN_ANY;\n    } else if (strcmp(name, \"navexposed\") == 0) {\n        mask = ResTable_config::MASK_NAVHIDDEN;\n        value = ResTable_config::NAVHIDDEN_NO;\n    } else if (strcmp(name, \"navhidden\") == 0) {\n        mask = ResTable_config::MASK_NAVHIDDEN;\n        value = ResTable_config::NAVHIDDEN_YES;\n    }\n\n    if (mask != 0) {\n        if (out) out->inputFlags = (out->inputFlags&~mask) | value;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseNavigation(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) out->navigation = out->NAVIGATION_ANY;\n        return true;\n    } else if (strcmp(name, \"nonav\") == 0) {\n        if (out) out->navigation = out->NAVIGATION_NONAV;\n        return true;\n    } else if (strcmp(name, \"dpad\") == 0) {\n        if (out) out->navigation = out->NAVIGATION_DPAD;\n        return true;\n    } else if (strcmp(name, \"trackball\") == 0) {\n        if (out) out->navigation = out->NAVIGATION_TRACKBALL;\n        return true;\n    } else if (strcmp(name, \"wheel\") == 0) {\n        if (out) out->navigation = out->NAVIGATION_WHEEL;\n        return true;\n    }\n\n    return false;\n}\n\nbool parseScreenSize(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) {\n            out->screenWidth = out->SCREENWIDTH_ANY;\n            out->screenHeight = out->SCREENHEIGHT_ANY;\n        }\n        return true;\n    }\n\n    const char* x = name;\n    while (*x >= '0' && *x <= '9') x++;\n    if (x == name || *x != 'x') return false;\n    String8 xName(name, x-name);\n    x++;\n\n    const char* y = x;\n    while (*y >= '0' && *y <= '9') y++;\n    if (y == name || *y != 0) return false;\n    String8 yName(x, y-x);\n\n    uint16_t w = (uint16_t)atoi(xName.string());\n    uint16_t h = (uint16_t)atoi(yName.string());\n    if (w < h) {\n        return false;\n    }\n\n    if (out) {\n        out->screenWidth = w;\n        out->screenHeight = h;\n    }\n\n    return true;\n}\n\nbool parseSmallestScreenWidthDp(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) {\n            out->smallestScreenWidthDp = out->SCREENWIDTH_ANY;\n        }\n        return true;\n    }\n\n    if (*name != 's') return false;\n    name++;\n    if (*name != 'w') return false;\n    name++;\n    const char* x = name;\n    while (*x >= '0' && *x <= '9') x++;\n    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;\n    String8 xName(name, x-name);\n\n    if (out) {\n        out->smallestScreenWidthDp = (uint16_t)atoi(xName.string());\n    }\n\n    return true;\n}\n\nbool parseScreenWidthDp(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) {\n            out->screenWidthDp = out->SCREENWIDTH_ANY;\n        }\n        return true;\n    }\n\n    if (*name != 'w') return false;\n    name++;\n    const char* x = name;\n    while (*x >= '0' && *x <= '9') x++;\n    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;\n    String8 xName(name, x-name);\n\n    if (out) {\n        out->screenWidthDp = (uint16_t)atoi(xName.string());\n    }\n\n    return true;\n}\n\nbool parseScreenHeightDp(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) {\n            out->screenHeightDp = out->SCREENWIDTH_ANY;\n        }\n        return true;\n    }\n\n    if (*name != 'h') return false;\n    name++;\n    const char* x = name;\n    while (*x >= '0' && *x <= '9') x++;\n    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;\n    String8 xName(name, x-name);\n\n    if (out) {\n        out->screenHeightDp = (uint16_t)atoi(xName.string());\n    }\n\n    return true;\n}\n\nbool parseVersion(const char* name, ResTable_config* out) {\n    if (strcmp(name, kWildcardName) == 0) {\n        if (out) {\n            out->sdkVersion = out->SDKVERSION_ANY;\n            out->minorVersion = out->MINORVERSION_ANY;\n        }\n        return true;\n    }\n\n    if (*name != 'v') {\n        return false;\n    }\n\n    name++;\n    const char* s = name;\n    while (*s >= '0' && *s <= '9') s++;\n    if (s == name || *s != 0) return false;\n    String8 sdkName(name, s-name);\n\n    if (out) {\n        out->sdkVersion = (uint16_t)atoi(sdkName.string());\n        out->minorVersion = 0;\n    }\n\n    return true;\n}\n\nString8 getVersion(const ResTable_config& config) {\n    return String8::format(\"v%u\", config.sdkVersion);\n}\n\nbool isSameExcept(const ResTable_config& a, const ResTable_config& b, int axisMask) {\n    return a.diff(b) == axisMask;\n}\n\n} // namespace AaptConfig\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/AaptConfig.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __AAPT_CONFIG_H\n#define __AAPT_CONFIG_H\n\n#include <set>\n#include <utils/String8.h>\n\n#include \"ConfigDescription.h\"\n\n/**\n * Utility methods for dealing with configurations.\n */\nnamespace AaptConfig {\n\n/**\n * Parse a string of the form 'fr-sw600dp-land' and fill in the\n * given ResTable_config with resulting configuration parameters.\n *\n * The resulting configuration has the appropriate sdkVersion defined\n * for backwards compatibility.\n */\nbool parse(const android::String8& str, ConfigDescription* out = NULL);\n\n/**\n * Parse a comma separated list of configuration strings. Duplicate configurations\n * will be removed.\n *\n * Example input: \"fr,de-land,fr-sw600dp-land\"\n */\nbool parseCommaSeparatedList(const android::String8& str, std::set<ConfigDescription>* outSet);\n\n/**\n * If the configuration uses an axis that was added after\n * the original Android release, make sure the SDK version\n * is set accordingly.\n */\nvoid applyVersionForCompatibility(ConfigDescription* config);\n\n// Individual axis\nbool parseMcc(const char* str, android::ResTable_config* out = NULL);\nbool parseMnc(const char* str, android::ResTable_config* out = NULL);\nbool parseLayoutDirection(const char* str, android::ResTable_config* out = NULL);\nbool parseSmallestScreenWidthDp(const char* str, android::ResTable_config* out = NULL);\nbool parseScreenWidthDp(const char* str, android::ResTable_config* out = NULL);\nbool parseScreenHeightDp(const char* str, android::ResTable_config* out = NULL);\nbool parseScreenLayoutSize(const char* str, android::ResTable_config* out = NULL);\nbool parseScreenLayoutLong(const char* str, android::ResTable_config* out = NULL);\nbool parseOrientation(const char* str, android::ResTable_config* out = NULL);\nbool parseUiModeType(const char* str, android::ResTable_config* out = NULL);\nbool parseUiModeNight(const char* str, android::ResTable_config* out = NULL);\nbool parseDensity(const char* str, android::ResTable_config* out = NULL);\nbool parseTouchscreen(const char* str, android::ResTable_config* out = NULL);\nbool parseKeysHidden(const char* str, android::ResTable_config* out = NULL);\nbool parseKeyboard(const char* str, android::ResTable_config* out = NULL);\nbool parseNavHidden(const char* str, android::ResTable_config* out = NULL);\nbool parseNavigation(const char* str, android::ResTable_config* out = NULL);\nbool parseScreenSize(const char* str, android::ResTable_config* out = NULL);\nbool parseVersion(const char* str, android::ResTable_config* out = NULL);\n\nandroid::String8 getVersion(const android::ResTable_config& config);\n\n/**\n * Returns true if the two configurations only differ by the specified axis.\n * The axis mask is a bitmask of CONFIG_* constants.\n */\nbool isSameExcept(const android::ResTable_config& a, const android::ResTable_config& b, int configMask);\n\n} // namespace AaptConfig\n\n#endif // __AAPT_CONFIG_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/AaptUtil.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"AaptUtil.h\"\n\nusing android::Vector;\nusing android::String8;\n\nnamespace AaptUtil {\n\nVector<String8> split(const String8& str, const char sep) {\n    Vector<String8> parts;\n    const char* p = str.string();\n    const char* q;\n\n    while (true) {\n        q = strchr(p, sep);\n        if (q == NULL) {\n            parts.add(String8(p, strlen(p)));\n            return parts;\n        }\n\n        parts.add(String8(p, q-p));\n        p = q + 1;\n    }\n    return parts;\n}\n\nVector<String8> splitAndLowerCase(const String8& str, const char sep) {\n    Vector<String8> parts;\n    const char* p = str.string();\n    const char* q;\n\n    while (true) {\n        q = strchr(p, sep);\n        if (q == NULL) {\n            String8 val(p, strlen(p));\n            val.toLower();\n            parts.add(val);\n            return parts;\n        }\n\n        String8 val(p, q-p);\n        val.toLower();\n        parts.add(val);\n        p = q + 1;\n    }\n    return parts;\n}\n\n} // namespace AaptUtil\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/AaptUtil.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __AAPT_UTIL_H\n#define __AAPT_UTIL_H\n\n#include <utils/String8.h>\n#include <utils/Vector.h>\n\nnamespace AaptUtil {\n\nandroid::Vector<android::String8> split(const android::String8& str, const char sep);\nandroid::Vector<android::String8> splitAndLowerCase(const android::String8& str, const char sep);\n\n} // namespace AaptUtil\n\n#endif // __AAPT_UTIL_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/AaptXml.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/String8.h>\n\n#include \"AaptXml.h\"\n\nusing namespace android;\n\nnamespace AaptXml {\n\nstatic String8 getStringAttributeAtIndex(const ResXMLTree& tree, ssize_t attrIndex,\n        String8* outError) {\n    Res_value value;\n    if (tree.getAttributeValue(attrIndex, &value) < 0) {\n        if (outError != NULL) {\n            *outError = \"could not find attribute at index\";\n        }\n        return String8();\n    }\n\n    if (value.dataType != Res_value::TYPE_STRING) {\n        if (outError != NULL) {\n            *outError = \"attribute is not a string value\";\n        }\n        return String8();\n    }\n\n    size_t len;\n    const uint16_t* str = tree.getAttributeStringValue(attrIndex, &len);\n    return str ? String8(str, len) : String8();\n}\n\nstatic int32_t getIntegerAttributeAtIndex(const ResXMLTree& tree, ssize_t attrIndex,\n    int32_t defValue, String8* outError) {\n    Res_value value;\n    if (tree.getAttributeValue(attrIndex, &value) < 0) {\n        if (outError != NULL) {\n            *outError = \"could not find attribute at index\";\n        }\n        return defValue;\n    }\n\n    if (value.dataType < Res_value::TYPE_FIRST_INT\n            || value.dataType > Res_value::TYPE_LAST_INT) {\n        if (outError != NULL) {\n            *outError = \"attribute is not an integer value\";\n        }\n        return defValue;\n    }\n    return value.data;\n}\n\n\nssize_t indexOfAttribute(const ResXMLTree& tree, uint32_t attrRes) {\n    size_t attrCount = tree.getAttributeCount();\n    for (size_t i = 0; i < attrCount; i++) {\n        if (tree.getAttributeNameResID(i) == attrRes) {\n            return (ssize_t)i;\n        }\n    }\n    return -1;\n}\n\nString8 getAttribute(const ResXMLTree& tree, const char* ns,\n        const char* attr, String8* outError) {\n    ssize_t idx = tree.indexOfAttribute(ns, attr);\n    if (idx < 0) {\n        return String8();\n    }\n    return getStringAttributeAtIndex(tree, idx, outError);\n}\n\nString8 getAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* outError) {\n    ssize_t idx = indexOfAttribute(tree, attrRes);\n    if (idx < 0) {\n        return String8();\n    }\n    return getStringAttributeAtIndex(tree, idx, outError);\n}\n\nString8 getResolvedAttribute(const ResTable& resTable, const ResXMLTree& tree,\n        uint32_t attrRes, String8* outError) {\n    ssize_t idx = indexOfAttribute(tree, attrRes);\n    if (idx < 0) {\n        return String8();\n    }\n    Res_value value;\n    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {\n        if (value.dataType == Res_value::TYPE_STRING) {\n            size_t len;\n            const uint16_t* str = tree.getAttributeStringValue(idx, &len);\n            return str ? String8(str, len) : String8();\n        }\n        resTable.resolveReference(&value, 0);\n        if (value.dataType != Res_value::TYPE_STRING) {\n            if (outError != NULL) {\n                *outError = \"attribute is not a string value\";\n            }\n            return String8();\n        }\n    }\n    size_t len;\n    const Res_value* value2 = &value;\n    const char16_t* str = resTable.valueToString(value2, 0, NULL, &len);\n    return str ? String8(str, len) : String8();\n}\n\nint32_t getIntegerAttribute(const ResXMLTree& tree, const char* ns,\n        const char* attr, int32_t defValue, String8* outError) {\n    ssize_t idx = tree.indexOfAttribute(ns, attr);\n    if (idx < 0) {\n        return defValue;\n    }\n    return getIntegerAttributeAtIndex(tree, idx, defValue, outError);\n}\n\nint32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes, int32_t defValue,\n        String8* outError) {\n    ssize_t idx = indexOfAttribute(tree, attrRes);\n    if (idx < 0) {\n        return defValue;\n    }\n    return getIntegerAttributeAtIndex(tree, idx, defValue, outError);\n}\n\nint32_t getResolvedIntegerAttribute(const ResTable& resTable, const ResXMLTree& tree,\n        uint32_t attrRes, int32_t defValue, String8* outError) {\n    ssize_t idx = indexOfAttribute(tree, attrRes);\n    if (idx < 0) {\n        return defValue;\n    }\n    Res_value value;\n    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {\n        if (value.dataType == Res_value::TYPE_REFERENCE) {\n            resTable.resolveReference(&value, 0);\n        }\n        if (value.dataType < Res_value::TYPE_FIRST_INT\n                || value.dataType > Res_value::TYPE_LAST_INT) {\n            if (outError != NULL) {\n                *outError = \"attribute is not an integer value\";\n            }\n            return defValue;\n        }\n    }\n    return value.data;\n}\n\nvoid getResolvedResourceAttribute(const ResTable& resTable, const ResXMLTree& tree,\n        uint32_t attrRes, Res_value* outValue, String8* outError) {\n    ssize_t idx = indexOfAttribute(tree, attrRes);\n    if (idx < 0) {\n        if (outError != NULL) {\n            *outError = \"attribute could not be found\";\n        }\n        return;\n    }\n    if (tree.getAttributeValue(idx, outValue) != NO_ERROR) {\n        if (outValue->dataType == Res_value::TYPE_REFERENCE) {\n            resTable.resolveReference(outValue, 0);\n        }\n        // The attribute was found and was resolved if need be.\n        return;\n    }\n    if (outError != NULL) {\n        *outError = \"error getting resolved resource attribute\";\n    }\n}\n\n} // namespace AaptXml\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/AaptXml.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __AAPT_XML_H\n#define __AAPT_XML_H\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/String8.h>\n\n/**\n * Utility methods for dealing with ResXMLTree.\n */\nnamespace AaptXml {\n\n/**\n * Returns the index of the attribute, or < 0 if it was not found.\n */\nssize_t indexOfAttribute(const android::ResXMLTree& tree, uint32_t attrRes);\n\n/**\n * Returns the string value for the specified attribute.\n * The string must be present in the ResXMLTree's string pool (inline in the XML).\n */\nandroid::String8 getAttribute(const android::ResXMLTree& tree, const char* ns,\n        const char* attr, android::String8* outError = NULL);\n\n/**\n * Returns the string value for the specified attribute, or an empty string\n * if the attribute does not exist.\n * The string must be present in the ResXMLTree's string pool (inline in the XML).\n */\nandroid::String8 getAttribute(const android::ResXMLTree& tree, uint32_t attrRes,\n        android::String8* outError = NULL);\n\n/**\n * Returns the integer value for the specified attribute, or the default value\n * if the attribute does not exist.\n * The integer must be declared inline in the XML.\n */\nint32_t getIntegerAttribute(const android::ResXMLTree& tree, const char* ns,\n        const char* attr, int32_t defValue = -1, android::String8* outError = NULL);\n\n/**\n * Returns the integer value for the specified attribute, or the default value\n * if the attribute does not exist.\n * The integer must be declared inline in the XML.\n */\ninline int32_t getIntegerAttribute(const android::ResXMLTree& tree, const char* ns,\n        const char* attr, android::String8* outError) {\n    return getIntegerAttribute(tree, ns, attr, -1, outError);\n}\n\n/**\n * Returns the integer value for the specified attribute, or the default value\n * if the attribute does not exist.\n * The integer must be declared inline in the XML.\n */\nint32_t getIntegerAttribute(const android::ResXMLTree& tree, uint32_t attrRes,\n        int32_t defValue = -1, android::String8* outError = NULL);\n\n/**\n * Returns the integer value for the specified attribute, or the default value\n * if the attribute does not exist.\n * The integer must be declared inline in the XML.\n */\ninline int32_t getIntegerAttribute(const android::ResXMLTree& tree, uint32_t attrRes,\n        android::String8* outError) {\n    return getIntegerAttribute(tree, attrRes, -1, outError);\n}\n\n/**\n * Returns the integer value for the specified attribute, or the default value\n * if the attribute does not exist.\n * The integer may be a resource in the supplied ResTable.\n */\nint32_t getResolvedIntegerAttribute(const android::ResTable& resTable,\n        const android::ResXMLTree& tree, uint32_t attrRes, int32_t defValue = -1,\n        android::String8* outError = NULL);\n\n/**\n * Returns the integer value for the specified attribute, or the default value\n * if the attribute does not exist.\n * The integer may be a resource in the supplied ResTable.\n */\ninline int32_t getResolvedIntegerAttribute(const android::ResTable& resTable,\n        const android::ResXMLTree& tree, uint32_t attrRes,\n        android::String8* outError) {\n    return getResolvedIntegerAttribute(resTable, tree, attrRes, -1, outError);\n}\n\n/**\n * Returns the string value for the specified attribute, or an empty string\n * if the attribute does not exist.\n * The string may be a resource in the supplied ResTable.\n */\nandroid::String8 getResolvedAttribute(const android::ResTable& resTable,\n        const android::ResXMLTree& tree, uint32_t attrRes,\n        android::String8* outError = NULL);\n\n/**\n * Returns the resource for the specified attribute in the outValue parameter.\n * The resource may be a resource in the supplied ResTable.\n */\nvoid getResolvedResourceAttribute(const android::ResTable& resTable,\n        const android::ResXMLTree& tree, uint32_t attrRes, android::Res_value* outValue,\n        android::String8* outError = NULL);\n\n} // namespace AaptXml\n\n#endif // __AAPT_XML_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/Android.mk",
    "content": "#\n# Copyright (C) 2014 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n# This tool is prebuilt if we're doing an app-only build.\nifeq ($(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)),)\n\n# ==========================================================\n# Setup some common variables for the different build\n# targets here.\n# ==========================================================\nLOCAL_PATH:= $(call my-dir)\n\naaptMain := Main.cpp\naaptSources := \\\n    AaptAssets.cpp \\\n    AaptConfig.cpp \\\n    AaptUtil.cpp \\\n    AaptXml.cpp \\\n    ApkBuilder.cpp \\\n    Command.cpp \\\n    CrunchCache.cpp \\\n    FileFinder.cpp \\\n    Package.cpp \\\n    StringPool.cpp \\\n    XMLNode.cpp \\\n    ResourceFilter.cpp \\\n    ResourceIdCache.cpp \\\n    ResourceTable.cpp \\\n    Images.cpp \\\n    Resource.cpp \\\n    pseudolocalize.cpp \\\n    SourcePos.cpp \\\n    WorkQueue.cpp \\\n    ZipEntry.cpp \\\n    ZipFile.cpp \\\n    qsort_r_compat.c\n\naaptTests := \\\n    tests/AaptConfig_test.cpp \\\n    tests/AaptGroupEntry_test.cpp \\\n    tests/ResourceFilter_test.cpp\n\naaptCIncludes := \\\n    external/libpng \\\n    external/zlib\n\naaptHostLdLibs :=\naaptHostStaticLibs := \\\n    libandroidfw \\\n    libpng \\\n    liblog \\\n    libutils \\\n    libcutils \\\n    libexpat \\\n    libziparchive-host\n\naaptCFlags := -DAAPT_VERSION=\\\"$(BUILD_NUMBER)\\\"\n\nifeq ($(HOST_OS),linux)\n    aaptHostLdLibs += -lrt -ldl -lpthread\nendif\n\n# Statically link libz for MinGW (Win SDK under Linux),\n# and dynamically link for all others.\nifneq ($(strip $(USE_MINGW)),)\n    aaptHostStaticLibs += libz\nelse\n    aaptHostLdLibs += -lz\nendif\n\n\n# ==========================================================\n# Build the host static library: libaapt\n# ==========================================================\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libaapt\n\nLOCAL_SRC_FILES := $(aaptSources)\nLOCAL_C_INCLUDES += $(aaptCIncludes)\n\nLOCAL_CFLAGS += -Wno-format-y2k\nLOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS\nLOCAL_CFLAGS += $(aaptCFlags)\nifeq (darwin,$(HOST_OS))\nLOCAL_CFLAGS += -D_DARWIN_UNLIMITED_STREAMS\nendif\n\ninclude $(BUILD_HOST_STATIC_LIBRARY)\n\n\n# ==========================================================\n# Build the host executable: aapt\n# ==========================================================\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := aapt\n\nLOCAL_SRC_FILES := $(aaptMain)\n\nLOCAL_STATIC_LIBRARIES += \\\n    libaapt \\\n    $(aaptHostStaticLibs)\n\nLOCAL_LDLIBS += $(aaptHostLdLibs)\nLOCAL_CFLAGS += $(aaptCFlags)\n\ninclude $(BUILD_HOST_EXECUTABLE)\n\n\n# ==========================================================\n# Build the host tests: libaapt_tests\n# ==========================================================\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := libaapt_tests\n\nLOCAL_SRC_FILES += $(aaptTests)\nLOCAL_C_INCLUDES += $(LOCAL_PATH)\n\nLOCAL_STATIC_LIBRARIES += \\\n    libaapt \\\n    $(aaptHostStaticLibs)\n\nLOCAL_LDLIBS += $(aaptHostLdLibs)\nLOCAL_CFLAGS += $(aaptCFlags)\n\ninclude $(BUILD_HOST_NATIVE_TEST)\n\n\n# ==========================================================\n# Build the device executable: aapt\n# ==========================================================\nifneq ($(SDK_ONLY),true)\ninclude $(CLEAR_VARS)\n\nLOCAL_MODULE := aapt\n\nLOCAL_SRC_FILES := $(aaptSources) $(aaptMain)\nLOCAL_C_INCLUDES += \\\n    $(aaptCIncludes) \\\n    bionic \\\n    external/stlport/stlport\n\nLOCAL_SHARED_LIBRARIES := \\\n    libandroidfw \\\n    libutils \\\n    libcutils \\\n    libpng \\\n    liblog \\\n    libz\n\nLOCAL_STATIC_LIBRARIES := \\\n    libstlport_static \\\n    libexpat_static\n\nLOCAL_CFLAGS += $(aaptCFlags)\nLOCAL_CPPFLAGS += -Wno-non-virtual-dtor\n\ninclude $(BUILD_EXECUTABLE)\n\nendif # Not SDK_ONLY\n\nendif # No TARGET_BUILD_APPS or TARGET_BUILD_PDK\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/ApkBuilder.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include \"AaptAssets.h\"\n#include \"ApkBuilder.h\"\n\nusing namespace android;\n\nApkBuilder::ApkBuilder(const sp<WeakResourceFilter>& configFilter)\n    : mConfigFilter(configFilter)\n    , mDefaultFilter(new AndResourceFilter()) {\n    // Add the default split, which is present for all APKs.\n    mDefaultFilter->addFilter(mConfigFilter);\n    mSplits.add(new ApkSplit(std::set<ConfigDescription>(), mDefaultFilter, true));\n}\n\nstatus_t ApkBuilder::createSplitForConfigs(const std::set<ConfigDescription>& configs) {\n    const size_t N = mSplits.size();\n    for (size_t i = 0; i < N; i++) {\n        const std::set<ConfigDescription>& splitConfigs = mSplits[i]->getConfigs();\n        std::set<ConfigDescription>::const_iterator iter = configs.begin();\n        for (; iter != configs.end(); iter++) {\n            if (splitConfigs.count(*iter) > 0) {\n                // Can't have overlapping configurations.\n                fprintf(stderr, \"ERROR: Split configuration '%s' is already defined \"\n                        \"in another split.\\n\", iter->toString().string());\n                return ALREADY_EXISTS;\n            }\n        }\n    }\n\n    sp<StrongResourceFilter> splitFilter = new StrongResourceFilter(configs);\n\n    // Add the inverse filter of this split filter to the base apk filter so it will\n    // omit resources that belong in this split.\n    mDefaultFilter->addFilter(new InverseResourceFilter(splitFilter));\n\n    // Now add the apk-wide config filter to our split filter.\n    sp<AndResourceFilter> filter = new AndResourceFilter();\n    filter->addFilter(splitFilter);\n    filter->addFilter(mConfigFilter);\n    mSplits.add(new ApkSplit(configs, filter));\n    return NO_ERROR;\n}\n\nstatus_t ApkBuilder::addEntry(const String8& path, const sp<AaptFile>& file) {\n    const size_t N = mSplits.size();\n    for (size_t i = 0; i < N; i++) {\n        if (mSplits[i]->matches(file)) {\n            return mSplits.editItemAt(i)->addEntry(path, file);\n        }\n    }\n    // Entry can be dropped if it doesn't match any split. This will only happen\n    // if the enry doesn't mConfigFilter.\n    return NO_ERROR;\n}\n\nvoid ApkBuilder::print() const {\n    fprintf(stderr, \"APK Builder\\n\");\n    fprintf(stderr, \"-----------\\n\");\n    const size_t N = mSplits.size();\n    for (size_t i = 0; i < N; i++) {\n        mSplits[i]->print();\n        fprintf(stderr, \"\\n\");\n    }\n}\n\nApkSplit::ApkSplit(const std::set<ConfigDescription>& configs, const sp<ResourceFilter>& filter, bool isBase)\n    : mConfigs(configs), mFilter(filter), mIsBase(isBase) {\n    std::set<ConfigDescription>::const_iterator iter = configs.begin();\n    for (; iter != configs.end(); iter++) {\n        if (mName.size() > 0) {\n            mName.append(\",\");\n            mDirName.append(\"_\");\n            mPackageSafeName.append(\".\");\n        }\n\n        String8 configStr = iter->toString();\n        String8 packageConfigStr(configStr);\n        size_t len = packageConfigStr.length();\n        if (len > 0) {\n            char* buf = packageConfigStr.lockBuffer(len);\n            for (char* end = buf + len; buf < end; ++buf) {\n                if (*buf == '-') {\n                    *buf = '_';\n                }\n            }\n            packageConfigStr.unlockBuffer(len);\n        }\n        mName.append(configStr);\n        mDirName.append(configStr);\n        mPackageSafeName.append(packageConfigStr);\n    }\n}\n\nstatus_t ApkSplit::addEntry(const String8& path, const sp<AaptFile>& file) {\n    if (!mFiles.insert(OutputEntry(path, file)).second) {\n        // Duplicate file.\n        return ALREADY_EXISTS;\n    }\n    return NO_ERROR;\n}\n\nvoid ApkSplit::print() const {\n    fprintf(stderr, \"APK Split '%s'\\n\", mName.string());\n\n    std::set<OutputEntry>::const_iterator iter = mFiles.begin();\n    for (; iter != mFiles.end(); iter++) {\n        fprintf(stderr, \"  %s (%s)\\n\", iter->getPath().string(), iter->getFile()->getSourceFile().string());\n    }\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/ApkBuilder.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __APK_BUILDER_H\n#define __APK_BUILDER_H\n\n#include <set>\n#include <utils/Errors.h>\n#include <utils/String8.h>\n#include <utils/StrongPointer.h>\n#include <utils/Vector.h>\n\n#include \"ConfigDescription.h\"\n#include \"OutputSet.h\"\n#include \"ResourceFilter.h\"\n\nclass ApkSplit;\nclass AaptFile;\n\nclass ApkBuilder : public android::RefBase {\npublic:\n    ApkBuilder(const sp<WeakResourceFilter>& configFilter);\n\n    /**\n     * Tells the builder to generate a separate APK for resources that\n     * match the configurations specified. Split APKs can not have\n     * overlapping resources.\n     *\n     * NOTE: All splits should be set up before any files are added.\n     */\n    android::status_t createSplitForConfigs(const std::set<ConfigDescription>& configs);\n\n    /**\n     * Adds a file to be written to the final APK. It's name must not collide\n     * with that of any files previously added. When a Split APK is being\n     * generated, duplicates can exist as long as they are in different splits\n     * (resources.arsc, AndroidManifest.xml).\n     */\n    android::status_t addEntry(const String8& path, const android::sp<AaptFile>& file);\n\n    android::Vector<sp<ApkSplit> >& getSplits() {\n        return mSplits;\n    }\n\n    android::sp<ApkSplit> getBaseSplit() {\n        return mSplits[0];\n    }\n\n    void print() const;\n\nprivate:\n    android::sp<ResourceFilter> mConfigFilter;\n    android::sp<AndResourceFilter> mDefaultFilter;\n    android::Vector<sp<ApkSplit> > mSplits;\n};\n\nclass ApkSplit : public OutputSet {\npublic:\n    android::status_t addEntry(const String8& path, const android::sp<AaptFile>& file);\n\n    const std::set<OutputEntry>& getEntries() const {\n        return mFiles;\n    }\n\n    const std::set<ConfigDescription>& getConfigs() const {\n        return mConfigs;\n    }\n\n    bool matches(const sp<AaptFile>& file) const {\n        return mFilter->match(file->getGroupEntry().toParams());\n    }\n\n    sp<ResourceFilter> getResourceFilter() const {\n        return mFilter;\n    }\n\n    const android::String8& getPrintableName() const {\n        return mName;\n    }\n\n    const android::String8& getDirectorySafeName() const {\n        return mDirName;\n    }\n\n    const android::String8& getPackageSafeName() const {\n        return mPackageSafeName;\n    }\n\n    bool isBase() const {\n        return mIsBase;\n    }\n\n    void print() const;\n\nprivate:\n    friend class ApkBuilder;\n\n    ApkSplit(const std::set<ConfigDescription>& configs, const android::sp<ResourceFilter>& filter, bool isBase=false);\n\n    std::set<ConfigDescription> mConfigs;\n    const sp<ResourceFilter> mFilter;\n    const bool mIsBase;\n    String8 mName;\n    String8 mDirName;\n    String8 mPackageSafeName;\n    std::set<OutputEntry> mFiles;\n};\n\n#endif // __APK_BUILDER_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/Bundle.h",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// State bundle.  Used to pass around stuff like command-line args.\n//\n#ifndef __BUNDLE_H\n#define __BUNDLE_H\n\n#include <stdlib.h>\n#include <utils/Log.h>\n#include <utils/threads.h>\n#include <utils/List.h>\n#include <utils/Errors.h>\n#include <utils/String8.h>\n#include <utils/Vector.h>\n\nenum {\n    SDK_CUPCAKE = 3,\n    SDK_DONUT = 4,\n    SDK_ECLAIR = 5,\n    SDK_ECLAIR_0_1 = 6,\n    SDK_MR1 = 7,\n    SDK_FROYO = 8,\n    SDK_HONEYCOMB_MR2 = 13,\n    SDK_ICE_CREAM_SANDWICH = 14,\n    SDK_ICE_CREAM_SANDWICH_MR1 = 15,\n    SDK_L = 21,\n};\n\n/*\n * Things we can do.\n */\ntypedef enum Command {\n    kCommandUnknown = 0,\n    kCommandVersion,\n    kCommandList,\n    kCommandDump,\n    kCommandAdd,\n    kCommandRemove,\n    kCommandPackage,\n    kCommandCrunch,\n    kCommandSingleCrunch,\n    kCommandDaemon\n} Command;\n\n/*\n * Pseudolocalization methods\n */\ntypedef enum PseudolocalizationMethod {\n    NO_PSEUDOLOCALIZATION = 0,\n    PSEUDO_ACCENTED,\n    PSEUDO_BIDI,\n} PseudolocalizationMethod;\n\n/*\n * Bundle of goodies, including everything specified on the command line.\n */\nclass Bundle {\npublic:\n    Bundle(void)\n        : mCmd(kCommandUnknown), mVerbose(false), mAndroidList(false),\n          mForce(false), mGrayscaleTolerance(0), mMakePackageDirs(false),\n          mUpdate(false), mExtending(false),\n          mRequireLocalization(false), mPseudolocalize(NO_PSEUDOLOCALIZATION),\n          mWantUTF16(false), mValues(false), mIncludeMetaData(false),\n          mCompressionMethod(0), mJunkPath(false), mOutputAPKFile(NULL),\n          mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),\n          mAutoAddOverlay(false), mGenDependencies(false),\n          mCrunchedOutputDir(NULL), mProguardFile(NULL), mMainDexProguardFile(NULL),\n          mAndroidManifestFile(NULL), mPublicOutputFile(NULL),\n          mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),\n          mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),\n          mVersionCode(NULL), mVersionName(NULL), mReplaceVersion(false), mCustomPackage(NULL),\n          mExtraPackages(NULL), mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false),\n          mProduct(NULL), mUseCrunchCache(false), mErrorOnFailedInsert(false),\n          mErrorOnMissingConfigEntry(false), mOutputTextSymbols(NULL),\n          mSingleCrunchInputFile(NULL), mSingleCrunchOutputFile(NULL),\n          mBuildSharedLibrary(false), mTypeIdOffset(0), mArgc(0), mArgv(NULL)\n        {}\n    ~Bundle(void) {}\n\n    /*\n     * Set the command value.  Returns \"false\" if it was previously set.\n     */\n    Command getCommand(void) const { return mCmd; }\n    void setCommand(Command cmd) { mCmd = cmd; }\n\n    /*\n     * Command modifiers.  Not all modifiers are appropriate for all\n     * commands.\n     */\n    bool getVerbose(void) const { return mVerbose; }\n    void setVerbose(bool val) { mVerbose = val; }\n    bool getAndroidList(void) const { return mAndroidList; }\n    void setAndroidList(bool val) { mAndroidList = val; }\n    bool getForce(void) const { return mForce; }\n    void setForce(bool val) { mForce = val; }\n    void setGrayscaleTolerance(int val) { mGrayscaleTolerance = val; }\n    int  getGrayscaleTolerance() const { return mGrayscaleTolerance; }\n    bool getMakePackageDirs(void) const { return mMakePackageDirs; }\n    void setMakePackageDirs(bool val) { mMakePackageDirs = val; }\n    bool getUpdate(void) const { return mUpdate; }\n    void setUpdate(bool val) { mUpdate = val; }\n    bool getExtending(void) const { return mExtending; }\n    void setExtending(bool val) { mExtending = val; }\n    bool getRequireLocalization(void) const { return mRequireLocalization; }\n    void setRequireLocalization(bool val) { mRequireLocalization = val; }\n    short getPseudolocalize(void) const { return mPseudolocalize; }\n    void setPseudolocalize(short val) { mPseudolocalize = val; }\n    void setWantUTF16(bool val) { mWantUTF16 = val; }\n    bool getValues(void) const { return mValues; }\n    void setValues(bool val) { mValues = val; }\n    bool getIncludeMetaData(void) const { return mIncludeMetaData; }\n    void setIncludeMetaData(bool val) { mIncludeMetaData = val; }\n    int getCompressionMethod(void) const { return mCompressionMethod; }\n    void setCompressionMethod(int val) { mCompressionMethod = val; }\n    bool getJunkPath(void) const { return mJunkPath; }\n    void setJunkPath(bool val) { mJunkPath = val; }\n    const char* getOutputAPKFile() const { return mOutputAPKFile; }\n    void setOutputAPKFile(const char* val) { mOutputAPKFile = val; }\n    const char* getManifestPackageNameOverride() const { return mManifestPackageNameOverride; }\n    void setManifestPackageNameOverride(const char * val) { mManifestPackageNameOverride = val; }\n    const char* getInstrumentationPackageNameOverride() const { return mInstrumentationPackageNameOverride; }\n    void setInstrumentationPackageNameOverride(const char * val) { mInstrumentationPackageNameOverride = val; }\n    bool getAutoAddOverlay() { return mAutoAddOverlay; }\n    void setAutoAddOverlay(bool val) { mAutoAddOverlay = val; }\n    bool getGenDependencies() { return mGenDependencies; }\n    void setGenDependencies(bool val) { mGenDependencies = val; }\n    bool getErrorOnFailedInsert() { return mErrorOnFailedInsert; }\n    void setErrorOnFailedInsert(bool val) { mErrorOnFailedInsert = val; }\n    bool getErrorOnMissingConfigEntry() { return mErrorOnMissingConfigEntry; }\n    void setErrorOnMissingConfigEntry(bool val) { mErrorOnMissingConfigEntry = val; }\n    const android::String8& getPlatformBuildVersionCode() { return mPlatformVersionCode; }\n    void setPlatformBuildVersionCode(const android::String8& code) { mPlatformVersionCode = code; }\n    const android::String8& getPlatformBuildVersionName() { return mPlatformVersionName; }\n    void setPlatformBuildVersionName(const android::String8& name) { mPlatformVersionName = name; }\n\n    bool getUTF16StringsOption() {\n        return mWantUTF16 || !isMinSdkAtLeast(SDK_FROYO);\n    }\n\n    /*\n     * Input options.\n     */\n    const android::Vector<const char*>& getAssetSourceDirs() const { return mAssetSourceDirs; }\n    void addAssetSourceDir(const char* dir) { mAssetSourceDirs.insertAt(dir,0); }\n    const char* getCrunchedOutputDir() const { return mCrunchedOutputDir; }\n    void setCrunchedOutputDir(const char* dir) { mCrunchedOutputDir = dir; }\n    const char* getProguardFile() const { return mProguardFile; }\n    void setProguardFile(const char* file) { mProguardFile = file; }\n    const char* getMainDexProguardFile() const { return mMainDexProguardFile; }\n    void setMainDexProguardFile(const char* file) { mMainDexProguardFile = file; }\n    const android::Vector<const char*>& getResourceSourceDirs() const { return mResourceSourceDirs; }\n    void addResourceSourceDir(const char* dir) { mResourceSourceDirs.insertAt(dir,0); }\n    const char* getAndroidManifestFile() const { return mAndroidManifestFile; }\n    void setAndroidManifestFile(const char* file) { mAndroidManifestFile = file; }\n    const char* getPublicOutputFile() const { return mPublicOutputFile; }\n    void setPublicOutputFile(const char* file) { mPublicOutputFile = file; }\n    const char* getRClassDir() const { return mRClassDir; }\n    void setRClassDir(const char* dir) { mRClassDir = dir; }\n    const android::String8& getConfigurations() const { return mConfigurations; }\n    void addConfigurations(const char* val) { if (mConfigurations.size() > 0) { mConfigurations.append(\",\"); mConfigurations.append(val); } else { mConfigurations = val; } }\n    const android::String8& getPreferredDensity() const { return mPreferredDensity; }\n    void setPreferredDensity(const char* val) { mPreferredDensity = val; }\n    void addSplitConfigurations(const char* val) { mPartialConfigurations.add(android::String8(val)); }\n    const android::Vector<android::String8>& getSplitConfigurations() const { return mPartialConfigurations; }\n    const char* getResourceIntermediatesDir() const { return mResourceIntermediatesDir; }\n    void setResourceIntermediatesDir(const char* dir) { mResourceIntermediatesDir = dir; }\n    const android::Vector<android::String8>& getPackageIncludes() const { return mPackageIncludes; }\n    void addPackageInclude(const char* file) { mPackageIncludes.add(android::String8(file)); }\n    void setBaselinePackage(const char* str) { mBaselinePackage = str; }\n    const android::String8& getBaselinePackage() const { return mBaselinePackage; }\n    const android::Vector<const char*>& getJarFiles() const { return mJarFiles; }\n    void addJarFile(const char* file) { mJarFiles.add(file); }\n    const android::Vector<const char*>& getNoCompressExtensions() const { return mNoCompressExtensions; }\n    void addNoCompressExtension(const char* ext) { mNoCompressExtensions.add(ext); }\n    void setFeatureOfPackage(const char* str) { mFeatureOfPackage = str; }\n    const android::String8& getFeatureOfPackage() const { return mFeatureOfPackage; }\n    void setFeatureAfterPackage(const char* str) { mFeatureAfterPackage.add(android::String8(str)); }\n    const android::Vector<android::String8>& getFeatureAfterPackage() const { return mFeatureAfterPackage; }\n\n    const char*  getManifestMinSdkVersion() const { return mManifestMinSdkVersion; }\n    void setManifestMinSdkVersion(const char*  val) { mManifestMinSdkVersion = val; }\n    const char*  getMinSdkVersion() const { return mMinSdkVersion; }\n    void setMinSdkVersion(const char*  val) { mMinSdkVersion = val; }\n    const char*  getTargetSdkVersion() const { return mTargetSdkVersion; }\n    void setTargetSdkVersion(const char*  val) { mTargetSdkVersion = val; }\n    const char*  getMaxSdkVersion() const { return mMaxSdkVersion; }\n    void setMaxSdkVersion(const char*  val) { mMaxSdkVersion = val; }\n    const char*  getVersionCode() const { return mVersionCode; }\n    void setVersionCode(const char*  val) { mVersionCode = val; }\n    const char* getVersionName() const { return mVersionName; }\n    void setVersionName(const char* val) { mVersionName = val; }\n    bool getReplaceVersion() { return mReplaceVersion; }\n    void setReplaceVersion(bool val) { mReplaceVersion = val; }\n    const char* getCustomPackage() const { return mCustomPackage; }\n    void setCustomPackage(const char* val) { mCustomPackage = val; }\n    const char* getExtraPackages() const { return mExtraPackages; }\n    void setExtraPackages(const char* val) { mExtraPackages = val; }\n    const char* getMaxResVersion() const { return mMaxResVersion; }\n    void setMaxResVersion(const char * val) { mMaxResVersion = val; }\n    bool getDebugMode() const { return mDebugMode; }\n    void setDebugMode(bool val) { mDebugMode = val; }\n    bool getNonConstantId() const { return mNonConstantId; }\n    void setNonConstantId(bool val) { mNonConstantId = val; }\n    const char* getProduct() const { return mProduct; }\n    void setProduct(const char * val) { mProduct = val; }\n    void setUseCrunchCache(bool val) { mUseCrunchCache = val; }\n    bool getUseCrunchCache() const { return mUseCrunchCache; }\n    const char* getOutputTextSymbols() const { return mOutputTextSymbols; }\n    void setOutputTextSymbols(const char* val) { mOutputTextSymbols = val; }\n    const char* getSingleCrunchInputFile() const { return mSingleCrunchInputFile; }\n    void setSingleCrunchInputFile(const char* val) { mSingleCrunchInputFile = val; }\n    const char* getSingleCrunchOutputFile() const { return mSingleCrunchOutputFile; }\n    void setSingleCrunchOutputFile(const char* val) { mSingleCrunchOutputFile = val; }\n    bool getBuildSharedLibrary() const { return mBuildSharedLibrary; }\n    void setBuildSharedLibrary(bool val) { mBuildSharedLibrary = val; }\n    void setTypeIdOffset(uint32_t val) { mTypeIdOffset = val; }\n    uint32_t  getTypeIdOffset() const { return mTypeIdOffset; }\n\n    /*\n     * Set and get the file specification.\n     *\n     * Note this does NOT make a copy of argv.\n     */\n    void setFileSpec(char* const argv[], int argc) {\n        mArgc = argc;\n        mArgv = argv;\n    }\n    int getFileSpecCount(void) const { return mArgc; }\n    const char* getFileSpecEntry(int idx) const { return mArgv[idx]; }\n    void eatArgs(int n) {\n        if (n > mArgc) n = mArgc;\n        mArgv += n;\n        mArgc -= n;\n    }\n\n#if 0\n    /*\n     * Package count.  Nothing to do with anything else here; this is\n     * just a convenient place to stuff it so we don't have to pass it\n     * around everywhere.\n     */\n    int getPackageCount(void) const { return mPackageCount; }\n    void setPackageCount(int val) { mPackageCount = val; }\n#endif\n\n    /* Certain features may only be available on a specific SDK level or\n     * above. SDK levels that have a non-numeric identifier are assumed\n     * to be newer than any SDK level that has a number designated.\n     */\n    bool isMinSdkAtLeast(int desired) {\n        /* If the application specifies a minSdkVersion in the manifest\n         * then use that. Otherwise, check what the user specified on\n         * the command line. If neither, it's not available since\n         * the minimum SDK version is assumed to be 1.\n         */\n        const char *minVer;\n        if (mManifestMinSdkVersion != NULL) {\n            minVer = mManifestMinSdkVersion;\n        } else if (mMinSdkVersion != NULL) {\n            minVer = mMinSdkVersion;\n        } else {\n            return false;\n        }\n\n        char *end;\n        int minSdkNum = (int)strtol(minVer, &end, 0);\n        if (*end == '\\0') {\n            if (minSdkNum < desired) {\n                return false;\n            }\n        }\n        return true;\n    }\n\nprivate:\n    /* commands & modifiers */\n    Command     mCmd;\n    bool        mVerbose;\n    bool        mAndroidList;\n    bool        mForce;\n    int         mGrayscaleTolerance;\n    bool        mMakePackageDirs;\n    bool        mUpdate;\n    bool        mExtending;\n    bool        mRequireLocalization;\n    short       mPseudolocalize;\n    bool        mWantUTF16;\n    bool        mValues;\n    bool        mIncludeMetaData;\n    int         mCompressionMethod;\n    bool        mJunkPath;\n    const char* mOutputAPKFile;\n    const char* mManifestPackageNameOverride;\n    const char* mInstrumentationPackageNameOverride;\n    bool        mAutoAddOverlay;\n    bool        mGenDependencies;\n    const char* mCrunchedOutputDir;\n    const char* mProguardFile;\n    const char* mMainDexProguardFile;\n    const char* mAndroidManifestFile;\n    const char* mPublicOutputFile;\n    const char* mRClassDir;\n    const char* mResourceIntermediatesDir;\n\n    android::String8 mConfigurations;\n    android::String8 mPreferredDensity;\n    android::Vector<android::String8> mPartialConfigurations;\n    android::Vector<android::String8> mPackageIncludes;\n    android::String8 mBaselinePackage;\n    android::Vector<const char*> mJarFiles;\n    android::Vector<const char*> mNoCompressExtensions;\n    android::Vector<const char*> mAssetSourceDirs;\n    android::Vector<const char*> mResourceSourceDirs;\n\n    android::String8 mFeatureOfPackage;\n    android::Vector<android::String8> mFeatureAfterPackage;\n    const char* mManifestMinSdkVersion;\n    const char* mMinSdkVersion;\n    const char* mTargetSdkVersion;\n    const char* mMaxSdkVersion;\n    const char* mVersionCode;\n    const char* mVersionName;\n    bool        mReplaceVersion;\n    const char* mCustomPackage;\n    const char* mExtraPackages;\n    const char* mMaxResVersion;\n    bool        mDebugMode;\n    bool        mNonConstantId;\n    const char* mProduct;\n    bool        mUseCrunchCache;\n    bool        mErrorOnFailedInsert;\n    bool        mErrorOnMissingConfigEntry;\n    const char* mOutputTextSymbols;\n    const char* mSingleCrunchInputFile;\n    const char* mSingleCrunchOutputFile;\n    bool        mBuildSharedLibrary;\n    android::String8 mPlatformVersionCode;\n    android::String8 mPlatformVersionName;\n    uint32_t         mTypeIdOffset;\n\n    /* file specification */\n    int         mArgc;\n    char* const* mArgv;\n\n#if 0\n    /* misc stuff */\n    int         mPackageCount;\n#endif\n\n};\n\n#endif // __BUNDLE_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/CacheUpdater.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n// Abstraction of calls to system to make directories and delete files and\n// wrapper to image processing.\n\n#ifndef CACHE_UPDATER_H\n#define CACHE_UPDATER_H\n\n#include <utils/String8.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <stdio.h>\n#include \"Images.h\"\n#ifdef HAVE_MS_C_RUNTIME\n#include <direct.h>\n#endif\n\nusing namespace android;\n\n/** CacheUpdater\n *  This is a pure virtual class that declares abstractions of functions useful\n *  for managing a cache files. This manager is set up to be used in a\n *  mirror cache where the source tree is duplicated and filled with processed\n *  images. This class is abstracted to allow for dependency injection during\n *  unit testing.\n *  Usage:\n *      To update/add a file to the cache, call processImage\n *      To remove a file from the cache, call deleteFile\n */\nclass CacheUpdater {\npublic:\n    // Make sure all the directories along this path exist\n    virtual void ensureDirectoriesExist(String8 path) = 0;\n\n    // Delete a file\n    virtual void deleteFile(String8 path) = 0;\n\n    // Process an image from source out to dest\n    virtual void processImage(String8 source, String8 dest) = 0;\nprivate:\n};\n\n/** SystemCacheUpdater\n * This is an implementation of the above virtual cache updater specification.\n * This implementations hits the filesystem to manage a cache and calls out to\n * the PNG crunching in images.h to process images out to its cache components.\n */\nclass SystemCacheUpdater : public CacheUpdater {\npublic:\n    // Constructor to set bundle to pass to preProcessImage\n    SystemCacheUpdater (Bundle* b)\n        : bundle(b) { };\n\n    // Make sure all the directories along this path exist\n    virtual void ensureDirectoriesExist(String8 path)\n    {\n        // Check to see if we're dealing with a fully qualified path\n        String8 existsPath;\n        String8 toCreate;\n        String8 remains;\n        struct stat s;\n\n        // Check optomistically to see if all directories exist.\n        // If something in the path doesn't exist, then walk the path backwards\n        // and find the place to start creating directories forward.\n        if (stat(path.string(),&s) == -1) {\n            // Walk backwards to find place to start creating directories\n            existsPath = path;\n            do {\n                // As we remove the end of existsPath add it to\n                // the string of paths to create.\n                toCreate = existsPath.getPathLeaf().appendPath(toCreate);\n                existsPath = existsPath.getPathDir();\n            } while (stat(existsPath.string(),&s) == -1);\n\n            // Walk forwards and build directories as we go\n            do {\n                // Advance to the next segment of the path\n                existsPath.appendPath(toCreate.walkPath(&remains));\n                toCreate = remains;\n#ifdef HAVE_MS_C_RUNTIME\n                _mkdir(existsPath.string());\n#else\n                mkdir(existsPath.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);\n#endif\n            } while (remains.length() > 0);\n        } //if\n    };\n\n    // Delete a file\n    virtual void deleteFile(String8 path)\n    {\n        if (remove(path.string()) != 0)\n            fprintf(stderr,\"ERROR DELETING %s\\n\",path.string());\n    };\n\n    // Process an image from source out to dest\n    virtual void processImage(String8 source, String8 dest)\n    {\n        // Make sure we're trying to write to a directory that is extant\n        ensureDirectoriesExist(dest.getPathDir());\n\n        preProcessImageToCache(bundle, source, dest);\n    };\nprivate:\n    Bundle* bundle;\n};\n\n#endif // CACHE_UPDATER_H"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/Command.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Android Asset Packaging Tool main entry point.\n//\n#include \"AaptXml.h\"\n#include \"ApkBuilder.h\"\n#include \"Bundle.h\"\n#include \"Images.h\"\n#include \"Main.h\"\n#include \"ResourceFilter.h\"\n#include \"ResourceTable.h\"\n#include \"XMLNode.h\"\n\n#include <utils/Errors.h>\n#include <utils/KeyedVector.h>\n#include <utils/List.h>\n#include <utils/Log.h>\n#include <utils/SortedVector.h>\n#include <utils/threads.h>\n#include <utils/Vector.h>\n\n#include <errno.h>\n#include <fcntl.h>\n\n#include <iostream>\n#include <string>\n#include <sstream>\n#include <androidfw/ResourcePackageId.h>\n\nusing namespace android;\n\n#ifndef AAPT_VERSION\n    #define AAPT_VERSION \"\"\n#endif\n\n/*\n * Show version info.  All the cool kids do it.\n */\nint doVersion(Bundle* bundle)\n{\n    if (bundle->getFileSpecCount() != 0) {\n        printf(\"(ignoring extra arguments)\\n\");\n    }\n    printf(\"Android Asset Packaging Tool, v0.2-\" AAPT_VERSION \"\\n\");\n\n    return 0;\n}\n\n\n/*\n * Open the file read only.  The call fails if the file doesn't exist.\n *\n * Returns NULL on failure.\n */\nZipFile* openReadOnly(const char* fileName)\n{\n    ZipFile* zip;\n    status_t result;\n\n    zip = new ZipFile;\n    result = zip->open(fileName, ZipFile::kOpenReadOnly);\n    if (result != NO_ERROR) {\n        if (result == NAME_NOT_FOUND) {\n            fprintf(stderr, \"ERROR: '%s' not found\\n\", fileName);\n        } else if (result == PERMISSION_DENIED) {\n            fprintf(stderr, \"ERROR: '%s' access denied\\n\", fileName);\n        } else {\n            fprintf(stderr, \"ERROR: failed opening '%s' as Zip file\\n\",\n                fileName);\n        }\n        delete zip;\n        return NULL;\n    }\n\n    return zip;\n}\n\n/*\n * Open the file read-write.  The file will be created if it doesn't\n * already exist and \"okayToCreate\" is set.\n *\n * Returns NULL on failure.\n */\nZipFile* openReadWrite(const char* fileName, bool okayToCreate)\n{\n    ZipFile* zip = NULL;\n    status_t result;\n    int flags;\n\n    flags = ZipFile::kOpenReadWrite;\n    if (okayToCreate) {\n        flags |= ZipFile::kOpenCreate;\n    }\n\n    zip = new ZipFile;\n    result = zip->open(fileName, flags);\n    if (result != NO_ERROR) {\n        delete zip;\n        zip = NULL;\n        goto bail;\n    }\n\nbail:\n    return zip;\n}\n\n\n/*\n * Return a short string describing the compression method.\n */\nconst char* compressionName(int method)\n{\n    if (method == ZipEntry::kCompressStored) {\n        return \"Stored\";\n    } else if (method == ZipEntry::kCompressDeflated) {\n        return \"Deflated\";\n    } else {\n        return \"Unknown\";\n    }\n}\n\n/*\n * Return the percent reduction in size (0% == no compression).\n */\nint calcPercent(long uncompressedLen, long compressedLen)\n{\n    if (!uncompressedLen) {\n        return 0;\n    } else {\n        return (int) (100.0 - (compressedLen * 100.0) / uncompressedLen + 0.5);\n    }\n}\n\n/*\n * Handle the \"list\" command, which can be a simple file dump or\n * a verbose listing.\n *\n * The verbose listing closely matches the output of the Info-ZIP \"unzip\"\n * command.\n */\nint doList(Bundle* bundle)\n{\n    int result = 1;\n    ZipFile* zip = NULL;\n    const ZipEntry* entry;\n    long totalUncLen, totalCompLen;\n    const char* zipFileName;\n\n    if (bundle->getFileSpecCount() != 1) {\n        fprintf(stderr, \"ERROR: specify zip file name (only)\\n\");\n        goto bail;\n    }\n    zipFileName = bundle->getFileSpecEntry(0);\n\n    zip = openReadOnly(zipFileName);\n    if (zip == NULL) {\n        goto bail;\n    }\n\n    int count, i;\n\n    if (bundle->getVerbose()) {\n        printf(\"Archive:  %s\\n\", zipFileName);\n        printf(\n            \" Length   Method    Size  Ratio   Offset      Date  Time  CRC-32    Name\\n\");\n        printf(\n            \"--------  ------  ------- -----  -------      ----  ----  ------    ----\\n\");\n    }\n\n    totalUncLen = totalCompLen = 0;\n\n    count = zip->getNumEntries();\n    for (i = 0; i < count; i++) {\n        entry = zip->getEntryByIndex(i);\n        if (bundle->getVerbose()) {\n            char dateBuf[32];\n            time_t when;\n\n            when = entry->getModWhen();\n            strftime(dateBuf, sizeof(dateBuf), \"%m-%d-%y %H:%M\",\n                localtime(&when));\n\n            printf(\"%8ld  %-7.7s %7ld %3d%%  %8zd  %s  %08lx  %s\\n\",\n                (long) entry->getUncompressedLen(),\n                compressionName(entry->getCompressionMethod()),\n                (long) entry->getCompressedLen(),\n                calcPercent(entry->getUncompressedLen(),\n                            entry->getCompressedLen()),\n                (size_t) entry->getLFHOffset(),\n                dateBuf,\n                entry->getCRC32(),\n                entry->getFileName());\n        } else {\n            printf(\"%s\\n\", entry->getFileName());\n        }\n\n        totalUncLen += entry->getUncompressedLen();\n        totalCompLen += entry->getCompressedLen();\n    }\n\n    if (bundle->getVerbose()) {\n        printf(\n        \"--------          -------  ---                            -------\\n\");\n        printf(\"%8ld          %7ld  %2d%%                            %d files\\n\",\n            totalUncLen,\n            totalCompLen,\n            calcPercent(totalUncLen, totalCompLen),\n            zip->getNumEntries());\n    }\n\n    if (bundle->getAndroidList()) {\n        AssetManager assets;\n        if (!assets.addAssetPath(String8(zipFileName), NULL)) {\n            fprintf(stderr, \"ERROR: list -a failed because assets could not be loaded\\n\");\n            goto bail;\n        }\n        const Vector<String8>& includes = bundle->getPackageIncludes();\n        const size_t packageIncludeCount = includes.size();\n        for (size_t i = 0; i < packageIncludeCount; i++) {\n            if (bundle->getVerbose()) {\n                printf(\"Including resources from package: %s\\n\", includes[i].string());\n            }\n\n            if (!assets.addAssetPath(includes[i], NULL)) {\n                fprintf(stderr, \"ERROR: Asset package include '%s' not found.\\n\",\n                        includes[i].string());\n                goto bail;\n            }\n        }\n\n        const ResTable& res = assets.getResources(false);\n        if (&res == NULL) {\n            printf(\"\\nNo resource table found.\\n\");\n        } else {\n#ifndef HAVE_ANDROID_OS\n            printf(\"\\nResource table:\\n\");\n            res.print(false);\n#endif\n        }\n\n        Asset* manifestAsset = assets.openNonAsset(\"AndroidManifest.xml\",\n                                                   Asset::ACCESS_BUFFER);\n        if (manifestAsset == NULL) {\n            printf(\"\\nNo AndroidManifest.xml found.\\n\");\n        } else {\n            printf(\"\\nAndroid manifest:\\n\");\n            ResXMLTree tree;\n            tree.setTo(manifestAsset->getBuffer(true),\n                       manifestAsset->getLength());\n            printXMLBlock(&tree);\n        }\n        delete manifestAsset;\n    }\n\n    result = 0;\n\nbail:\n    delete zip;\n    return result;\n}\n\nstatic void printResolvedResourceAttribute(const ResTable& resTable, const ResXMLTree& tree,\n        uint32_t attrRes, String8 attrLabel, String8* outError)\n{\n    Res_value value;\n    AaptXml::getResolvedResourceAttribute(resTable, tree, attrRes, &value, outError);\n    if (*outError != \"\") {\n        *outError = \"error print resolved resource attribute\";\n        return;\n    }\n    if (value.dataType == Res_value::TYPE_STRING) {\n        String8 result = AaptXml::getResolvedAttribute(resTable, tree, attrRes, outError);\n        printf(\"%s='%s'\", attrLabel.string(),\n                ResTable::normalizeForOutput(result.string()).string());\n    } else if (Res_value::TYPE_FIRST_INT <= value.dataType &&\n            value.dataType <= Res_value::TYPE_LAST_INT) {\n        printf(\"%s='%d'\", attrLabel.string(), value.data);\n    } else {\n        printf(\"%s='0x%x'\", attrLabel.string(), (int)value.data);\n    }\n}\n\n// These are attribute resource constants for the platform, as found\n// in android.R.attr\nenum {\n    LABEL_ATTR = 0x01010001,\n    ICON_ATTR = 0x01010002,\n    NAME_ATTR = 0x01010003,\n    PERMISSION_ATTR = 0x01010006,\n    EXPORTED_ATTR = 0x01010010,\n    GRANT_URI_PERMISSIONS_ATTR = 0x0101001b,\n    RESOURCE_ATTR = 0x01010025,\n    DEBUGGABLE_ATTR = 0x0101000f,\n    VALUE_ATTR = 0x01010024,\n    VERSION_CODE_ATTR = 0x0101021b,\n    VERSION_NAME_ATTR = 0x0101021c,\n    SCREEN_ORIENTATION_ATTR = 0x0101001e,\n    MIN_SDK_VERSION_ATTR = 0x0101020c,\n    MAX_SDK_VERSION_ATTR = 0x01010271,\n    REQ_TOUCH_SCREEN_ATTR = 0x01010227,\n    REQ_KEYBOARD_TYPE_ATTR = 0x01010228,\n    REQ_HARD_KEYBOARD_ATTR = 0x01010229,\n    REQ_NAVIGATION_ATTR = 0x0101022a,\n    REQ_FIVE_WAY_NAV_ATTR = 0x01010232,\n    TARGET_SDK_VERSION_ATTR = 0x01010270,\n    TEST_ONLY_ATTR = 0x01010272,\n    ANY_DENSITY_ATTR = 0x0101026c,\n    GL_ES_VERSION_ATTR = 0x01010281,\n    SMALL_SCREEN_ATTR = 0x01010284,\n    NORMAL_SCREEN_ATTR = 0x01010285,\n    LARGE_SCREEN_ATTR = 0x01010286,\n    XLARGE_SCREEN_ATTR = 0x010102bf,\n    REQUIRED_ATTR = 0x0101028e,\n    INSTALL_LOCATION_ATTR = 0x010102b7,\n    SCREEN_SIZE_ATTR = 0x010102ca,\n    SCREEN_DENSITY_ATTR = 0x010102cb,\n    REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364,\n    COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365,\n    LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366,\n    PUBLIC_KEY_ATTR = 0x010103a6,\n    CATEGORY_ATTR = 0x010103e8,\n    BANNER_ATTR = 0x10103f2,\n};\n\nString8 getComponentName(String8 &pkgName, String8 &componentName) {\n    ssize_t idx = componentName.find(\".\");\n    String8 retStr(pkgName);\n    if (idx == 0) {\n        retStr += componentName;\n    } else if (idx < 0) {\n        retStr += \".\";\n        retStr += componentName;\n    } else {\n        return componentName;\n    }\n    return retStr;\n}\n\nstatic void printCompatibleScreens(ResXMLTree& tree, String8* outError) {\n    size_t len;\n    ResXMLTree::event_code_t code;\n    int depth = 0;\n    bool first = true;\n    printf(\"compatible-screens:\");\n    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::END_TAG) {\n            depth--;\n            if (depth < 0) {\n                break;\n            }\n            continue;\n        }\n        if (code != ResXMLTree::START_TAG) {\n            continue;\n        }\n        depth++;\n        const char16_t* ctag16 = tree.getElementName(&len);\n        if (ctag16 == NULL) {\n            *outError = \"failed to get XML element name (bad string pool)\";\n            return;\n        }\n        String8 tag(ctag16);\n        if (tag == \"screen\") {\n            int32_t screenSize = AaptXml::getIntegerAttribute(tree,\n                    SCREEN_SIZE_ATTR);\n            int32_t screenDensity = AaptXml::getIntegerAttribute(tree,\n                    SCREEN_DENSITY_ATTR);\n            if (screenSize > 0 && screenDensity > 0) {\n                if (!first) {\n                    printf(\",\");\n                }\n                first = false;\n                printf(\"'%d/%d'\", screenSize, screenDensity);\n            }\n        }\n    }\n    printf(\"\\n\");\n}\n\nstatic void printUsesPermission(const String8& name, bool optional=false, int maxSdkVersion=-1) {\n    printf(\"uses-permission: name='%s'\", ResTable::normalizeForOutput(name.string()).string());\n    if (maxSdkVersion != -1) {\n         printf(\" maxSdkVersion='%d'\", maxSdkVersion);\n    }\n    printf(\"\\n\");\n\n    if (optional) {\n        printf(\"optional-permission: name='%s'\",\n                ResTable::normalizeForOutput(name.string()).string());\n        if (maxSdkVersion != -1) {\n            printf(\" maxSdkVersion='%d'\", maxSdkVersion);\n        }\n        printf(\"\\n\");\n    }\n}\n\nstatic void printUsesImpliedPermission(const String8& name, const String8& reason) {\n    printf(\"uses-implied-permission: name='%s' reason='%s'\\n\",\n            ResTable::normalizeForOutput(name.string()).string(),\n            ResTable::normalizeForOutput(reason.string()).string());\n}\n\nVector<String8> getNfcAidCategories(AssetManager& assets, String8 xmlPath, bool offHost,\n        String8 *outError = NULL)\n{\n    Asset* aidAsset = assets.openNonAsset(xmlPath, Asset::ACCESS_BUFFER);\n    if (aidAsset == NULL) {\n        if (outError != NULL) *outError = \"xml resource does not exist\";\n        return Vector<String8>();\n    }\n\n    const String8 serviceTagName(offHost ? \"offhost-apdu-service\" : \"host-apdu-service\");\n\n    bool withinApduService = false;\n    Vector<String8> categories;\n\n    String8 error;\n    ResXMLTree tree;\n    tree.setTo(aidAsset->getBuffer(true), aidAsset->getLength());\n\n    size_t len;\n    int depth = 0;\n    ResXMLTree::event_code_t code;\n    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::END_TAG) {\n            depth--;\n            const char16_t* ctag16 = tree.getElementName(&len);\n            if (ctag16 == NULL) {\n                *outError = \"failed to get XML element name (bad string pool)\";\n                return Vector<String8>();\n            }\n            String8 tag(ctag16);\n\n            if (depth == 0 && tag == serviceTagName) {\n                withinApduService = false;\n            }\n\n        } else if (code == ResXMLTree::START_TAG) {\n            depth++;\n            const char16_t* ctag16 = tree.getElementName(&len);\n            if (ctag16 == NULL) {\n                *outError = \"failed to get XML element name (bad string pool)\";\n                return Vector<String8>();\n            }\n            String8 tag(ctag16);\n\n            if (depth == 1) {\n                if (tag == serviceTagName) {\n                    withinApduService = true;\n                }\n            } else if (depth == 2 && withinApduService) {\n                if (tag == \"aid-group\") {\n                    String8 category = AaptXml::getAttribute(tree, CATEGORY_ATTR, &error);\n                    if (error != \"\") {\n                        if (outError != NULL) *outError = error;\n                        return Vector<String8>();\n                    }\n\n                    categories.add(category);\n                }\n            }\n        }\n    }\n    aidAsset->close();\n    return categories;\n}\n\nstatic void printComponentPresence(const char* componentName) {\n    printf(\"provides-component:'%s'\\n\", componentName);\n}\n\n/**\n * Represents a feature that has been automatically added due to\n * a pre-requisite or some other reason.\n */\nstruct ImpliedFeature {\n    /**\n     * Name of the implied feature.\n     */\n    String8 name;\n\n    /**\n     * List of human-readable reasons for why this feature was implied.\n     */\n    SortedVector<String8> reasons;\n};\n\n/**\n * Represents a <feature-group> tag in the AndroidManifest.xml\n */\nstruct FeatureGroup {\n    FeatureGroup() : openGLESVersion(-1) {}\n\n    /**\n     * Human readable label\n     */\n    String8 label;\n\n    /**\n     * Explicit features defined in the group\n     */\n    KeyedVector<String8, bool> features;\n\n    /**\n     * OpenGL ES version required\n     */\n    int openGLESVersion;\n};\n\nstatic void addImpliedFeature(KeyedVector<String8, ImpliedFeature>* impliedFeatures,\n        const char* name, const char* reason) {\n    String8 name8(name);\n    ssize_t idx = impliedFeatures->indexOfKey(name8);\n    if (idx < 0) {\n        idx = impliedFeatures->add(name8, ImpliedFeature());\n        impliedFeatures->editValueAt(idx).name = name8;\n    }\n    impliedFeatures->editValueAt(idx).reasons.add(String8(reason));\n}\n\nstatic void printFeatureGroup(const FeatureGroup& grp,\n        const KeyedVector<String8, ImpliedFeature>* impliedFeatures = NULL) {\n    printf(\"feature-group: label='%s'\\n\", grp.label.string());\n\n    if (grp.openGLESVersion > 0) {\n        printf(\"  uses-gl-es: '0x%x'\\n\", grp.openGLESVersion);\n    }\n\n    const size_t numFeatures = grp.features.size();\n    for (size_t i = 0; i < numFeatures; i++) {\n        if (!grp.features[i]) {\n            continue;\n        }\n\n        const String8& featureName = grp.features.keyAt(i);\n        printf(\"  uses-feature: name='%s'\\n\",\n                ResTable::normalizeForOutput(featureName.string()).string());\n    }\n\n    const size_t numImpliedFeatures =\n        (impliedFeatures != NULL) ? impliedFeatures->size() : 0;\n    for (size_t i = 0; i < numImpliedFeatures; i++) {\n        const ImpliedFeature& impliedFeature = impliedFeatures->valueAt(i);\n        if (grp.features.indexOfKey(impliedFeature.name) >= 0) {\n            // The feature is explicitly set, no need to use implied\n            // definition.\n            continue;\n        }\n\n        String8 printableFeatureName(ResTable::normalizeForOutput(\n                    impliedFeature.name.string()));\n        printf(\"  uses-feature: name='%s'\\n\", printableFeatureName.string());\n        printf(\"  uses-implied-feature: name='%s' reason='\",\n                printableFeatureName.string());\n        const size_t numReasons = impliedFeature.reasons.size();\n        for (size_t j = 0; j < numReasons; j++) {\n            printf(\"%s\", impliedFeature.reasons[j].string());\n            if (j + 2 < numReasons) {\n                printf(\", \");\n            } else if (j + 1 < numReasons) {\n                printf(\", and \");\n            }\n        }\n        printf(\"'\\n\");\n    }\n}\n\nstatic void addParentFeatures(FeatureGroup* grp, const String8& name) {\n    if (name == \"android.hardware.camera.autofocus\" ||\n            name == \"android.hardware.camera.flash\") {\n        grp->features.add(String8(\"android.hardware.camera\"), true);\n    } else if (name == \"android.hardware.location.gps\" ||\n            name == \"android.hardware.location.network\") {\n        grp->features.add(String8(\"android.hardware.location\"), true);\n    } else if (name == \"android.hardware.touchscreen.multitouch\") {\n        grp->features.add(String8(\"android.hardware.touchscreen\"), true);\n    } else if (name == \"android.hardware.touchscreen.multitouch.distinct\") {\n        grp->features.add(String8(\"android.hardware.touchscreen.multitouch\"), true);\n        grp->features.add(String8(\"android.hardware.touchscreen\"), true);\n    } else if (name == \"android.hardware.opengles.aep\") {\n        const int openGLESVersion31 = 0x00030001;\n        if (openGLESVersion31 > grp->openGLESVersion) {\n            grp->openGLESVersion = openGLESVersion31;\n        }\n    }\n}\n\n/*\n * Handle the \"dump\" command, to extract select data from an archive.\n */\nextern char CONSOLE_DATA[2925]; // see EOF\nint doDump(Bundle* bundle)\n{\n    status_t result = UNKNOWN_ERROR;\n\n    if (bundle->getFileSpecCount() < 1) {\n        fprintf(stderr, \"ERROR: no dump option specified\\n\");\n        return 1;\n    }\n\n    if (bundle->getFileSpecCount() < 2) {\n        fprintf(stderr, \"ERROR: no dump file specified\\n\");\n        return 1;\n    }\n\n    const char* option = bundle->getFileSpecEntry(0);\n    const char* filename = bundle->getFileSpecEntry(1);\n\n    AssetManager assets;\n    int32_t assetsCookie;\n    if (!assets.addAssetPath(String8(filename), &assetsCookie)) {\n        fprintf(stderr, \"ERROR: dump failed because assets could not be loaded\\n\");\n        return 1;\n    }\n\n    // Make a dummy config for retrieving resources...  we need to supply\n    // non-default values for some configs so that we can retrieve resources\n    // in the app that don't have a default.  The most important of these is\n    // the API version because key resources like icons will have an implicit\n    // version if they are using newer config types like density.\n    ResTable_config config;\n    memset(&config, 0, sizeof(ResTable_config));\n    config.language[0] = 'e';\n    config.language[1] = 'n';\n    config.country[0] = 'U';\n    config.country[1] = 'S';\n    config.orientation = ResTable_config::ORIENTATION_PORT;\n    config.density = ResTable_config::DENSITY_MEDIUM;\n    config.sdkVersion = 10000; // Very high.\n    config.screenWidthDp = 320;\n    config.screenHeightDp = 480;\n    config.smallestScreenWidthDp = 320;\n    config.screenLayout |= ResTable_config::SCREENSIZE_NORMAL;\n    assets.setConfiguration(config);\n\n    const ResTable& res = assets.getResources(false);\n    if (&res == NULL) {\n        fprintf(stderr, \"ERROR: dump failed because no resource table was found\\n\");\n        return 1;\n    } else if (res.getError() != NO_ERROR) {\n        fprintf(stderr, \"ERROR: dump failed because the resource table is invalid/corrupt.\\n\");\n        return 1;\n    }\n\n    // The dynamicRefTable can be null if there are no resources for this asset cookie.\n    // This fine.\n    const DynamicRefTable* dynamicRefTable = res.getDynamicRefTableForCookie(assetsCookie);\n\n    Asset* asset = NULL;\n\n    if (strcmp(\"resources\", option) == 0) {\n#ifndef HAVE_ANDROID_OS\n        res.print(bundle->getValues());\n#endif\n\n    } else if (strcmp(\"strings\", option) == 0) {\n        const ResStringPool* pool = res.getTableStringBlock(0);\n        printStringPool(pool);\n\n    } else if (strcmp(\"xmltree\", option) == 0) {\n        if (bundle->getFileSpecCount() < 3) {\n            fprintf(stderr, \"ERROR: no dump xmltree resource file specified\\n\");\n            goto bail;\n        }\n\n        for (int i=2; i<bundle->getFileSpecCount(); i++) {\n            const char* resname = bundle->getFileSpecEntry(i);\n            ResXMLTree tree(dynamicRefTable);\n            asset = assets.openNonAsset(assetsCookie, resname, Asset::ACCESS_BUFFER);\n            if (asset == NULL) {\n                fprintf(stderr, \"ERROR: dump failed because resource %s found\\n\", resname);\n                goto bail;\n            }\n\n            if (tree.setTo(asset->getBuffer(true),\n                           asset->getLength()) != NO_ERROR) {\n                fprintf(stderr, \"ERROR: Resource %s is corrupt\\n\", resname);\n                goto bail;\n            }\n            tree.restart();\n            printXMLBlock(&tree);\n            tree.uninit();\n            delete asset;\n            asset = NULL;\n        }\n\n    } else if (strcmp(\"xmlstrings\", option) == 0) {\n        if (bundle->getFileSpecCount() < 3) {\n            fprintf(stderr, \"ERROR: no dump xmltree resource file specified\\n\");\n            goto bail;\n        }\n\n        for (int i=2; i<bundle->getFileSpecCount(); i++) {\n            const char* resname = bundle->getFileSpecEntry(i);\n            asset = assets.openNonAsset(assetsCookie, resname, Asset::ACCESS_BUFFER);\n            if (asset == NULL) {\n                fprintf(stderr, \"ERROR: dump failed because resource %s found\\n\", resname);\n                goto bail;\n            }\n\n            ResXMLTree tree(dynamicRefTable);\n            if (tree.setTo(asset->getBuffer(true),\n                           asset->getLength()) != NO_ERROR) {\n                fprintf(stderr, \"ERROR: Resource %s is corrupt\\n\", resname);\n                goto bail;\n            }\n            printStringPool(&tree.getStrings());\n            delete asset;\n            asset = NULL;\n        }\n\n    } else {\n        asset = assets.openNonAsset(assetsCookie, \"AndroidManifest.xml\", Asset::ACCESS_BUFFER);\n        if (asset == NULL) {\n            fprintf(stderr, \"ERROR: dump failed because no AndroidManifest.xml found\\n\");\n            goto bail;\n        }\n\n        ResXMLTree tree(dynamicRefTable);\n        if (tree.setTo(asset->getBuffer(true),\n                       asset->getLength()) != NO_ERROR) {\n            fprintf(stderr, \"ERROR: AndroidManifest.xml is corrupt\\n\");\n            goto bail;\n        }\n        tree.restart();\n\n        if (strcmp(\"permissions\", option) == 0) {\n            size_t len;\n            ResXMLTree::event_code_t code;\n            int depth = 0;\n            while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n                if (code == ResXMLTree::END_TAG) {\n                    depth--;\n                    continue;\n                }\n                if (code != ResXMLTree::START_TAG) {\n                    continue;\n                }\n                depth++;\n                const char16_t* ctag16 = tree.getElementName(&len);\n                if (ctag16 == NULL) {\n                    fprintf(stderr, \"ERROR: failed to get XML element name (bad string pool)\\n\");\n                    goto bail;\n                }\n                String8 tag(ctag16);\n                //printf(\"Depth %d tag %s\\n\", depth, tag.string());\n                if (depth == 1) {\n                    if (tag != \"manifest\") {\n                        fprintf(stderr, \"ERROR: manifest does not start with <manifest> tag\\n\");\n                        goto bail;\n                    }\n                    String8 pkg = AaptXml::getAttribute(tree, NULL, \"package\", NULL);\n                    printf(\"package: %s\\n\", ResTable::normalizeForOutput(pkg.string()).string());\n                } else if (depth == 2 && tag == \"permission\") {\n                    String8 error;\n                    String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                    if (error != \"\") {\n                        fprintf(stderr, \"ERROR: %s\\n\", error.string());\n                        goto bail;\n                    }\n                    printf(\"permission: %s\\n\",\n                            ResTable::normalizeForOutput(name.string()).string());\n                } else if (depth == 2 && tag == \"uses-permission\") {\n                    String8 error;\n                    String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                    if (error != \"\") {\n                        fprintf(stderr, \"ERROR: %s\\n\", error.string());\n                        goto bail;\n                    }\n                    printUsesPermission(name,\n                            AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1) == 0,\n                            AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR));\n                }\n            }\n        } else if (strcmp(\"badging\", option) == 0) {\n            Vector<String8> locales;\n            res.getLocales(&locales);\n\n            Vector<ResTable_config> configs;\n            res.getConfigurations(&configs);\n            SortedVector<int> densities;\n            const size_t NC = configs.size();\n            for (size_t i=0; i<NC; i++) {\n                int dens = configs[i].density;\n                if (dens == 0) {\n                    dens = 160;\n                }\n                densities.add(dens);\n            }\n\n            size_t len;\n            ResXMLTree::event_code_t code;\n            int depth = 0;\n            String8 error;\n            bool withinActivity = false;\n            bool isMainActivity = false;\n            bool isLauncherActivity = false;\n            bool isLeanbackLauncherActivity = false;\n            bool isSearchable = false;\n            bool withinApplication = false;\n            bool withinSupportsInput = false;\n            bool withinFeatureGroup = false;\n            bool withinReceiver = false;\n            bool withinService = false;\n            bool withinProvider = false;\n            bool withinIntentFilter = false;\n            bool hasMainActivity = false;\n            bool hasOtherActivities = false;\n            bool hasOtherReceivers = false;\n            bool hasOtherServices = false;\n            bool hasIntentFilter = false;\n\n            bool hasWallpaperService = false;\n            bool hasImeService = false;\n            bool hasAccessibilityService = false;\n            bool hasPrintService = false;\n            bool hasWidgetReceivers = false;\n            bool hasDeviceAdminReceiver = false;\n            bool hasPaymentService = false;\n            bool hasDocumentsProvider = false;\n            bool hasCameraActivity = false;\n            bool hasCameraSecureActivity = false;\n            bool hasLauncher = false;\n            bool hasNotificationListenerService = false;\n            bool hasDreamService = false;\n\n            bool actMainActivity = false;\n            bool actWidgetReceivers = false;\n            bool actDeviceAdminEnabled = false;\n            bool actImeService = false;\n            bool actWallpaperService = false;\n            bool actAccessibilityService = false;\n            bool actPrintService = false;\n            bool actHostApduService = false;\n            bool actOffHostApduService = false;\n            bool actDocumentsProvider = false;\n            bool actNotificationListenerService = false;\n            bool actDreamService = false;\n            bool actCamera = false;\n            bool actCameraSecure = false;\n            bool catLauncher = false;\n            bool hasMetaHostPaymentCategory = false;\n            bool hasMetaOffHostPaymentCategory = false;\n\n            // These permissions are required by services implementing services\n            // the system binds to (IME, Accessibility, PrintServices, etc.)\n            bool hasBindDeviceAdminPermission = false;\n            bool hasBindInputMethodPermission = false;\n            bool hasBindAccessibilityServicePermission = false;\n            bool hasBindPrintServicePermission = false;\n            bool hasBindNfcServicePermission = false;\n            bool hasRequiredSafAttributes = false;\n            bool hasBindNotificationListenerServicePermission = false;\n            bool hasBindDreamServicePermission = false;\n\n            // These two implement the implicit permissions that are granted\n            // to pre-1.6 applications.\n            bool hasWriteExternalStoragePermission = false;\n            bool hasReadPhoneStatePermission = false;\n\n            // If an app requests write storage, they will also get read storage.\n            bool hasReadExternalStoragePermission = false;\n\n            // Implement transition to read and write call log.\n            bool hasReadContactsPermission = false;\n            bool hasWriteContactsPermission = false;\n            bool hasReadCallLogPermission = false;\n            bool hasWriteCallLogPermission = false;\n\n            // If an app declares itself as multiArch, we report the\n            // native libraries differently.\n            bool hasMultiArch = false;\n\n            // This next group of variables is used to implement a group of\n            // backward-compatibility heuristics necessitated by the addition of\n            // some new uses-feature constants in 2.1 and 2.2. In most cases, the\n            // heuristic is \"if an app requests a permission but doesn't explicitly\n            // request the corresponding <uses-feature>, presume it's there anyway\".\n\n            // 2.2 also added some other features that apps can request, but that\n            // have no corresponding permission, so we cannot implement any\n            // back-compatibility heuristic for them. The below are thus unnecessary\n            // (but are retained here for documentary purposes.)\n            //bool specCompassFeature = false;\n            //bool specAccelerometerFeature = false;\n            //bool specProximityFeature = false;\n            //bool specAmbientLightFeature = false;\n            //bool specLiveWallpaperFeature = false;\n\n            int targetSdk = 0;\n            int smallScreen = 1;\n            int normalScreen = 1;\n            int largeScreen = 1;\n            int xlargeScreen = 1;\n            int anyDensity = 1;\n            int requiresSmallestWidthDp = 0;\n            int compatibleWidthLimitDp = 0;\n            int largestWidthLimitDp = 0;\n            String8 pkg;\n            String8 activityName;\n            String8 activityLabel;\n            String8 activityIcon;\n            String8 activityBanner;\n            String8 receiverName;\n            String8 serviceName;\n            Vector<String8> supportedInput;\n\n            FeatureGroup commonFeatures;\n            Vector<FeatureGroup> featureGroups;\n            KeyedVector<String8, ImpliedFeature> impliedFeatures;\n\n            while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n                if (code == ResXMLTree::END_TAG) {\n                    depth--;\n                    if (depth < 2) {\n                        if (withinSupportsInput && !supportedInput.isEmpty()) {\n                            printf(\"supports-input: '\");\n                            const size_t N = supportedInput.size();\n                            for (size_t i=0; i<N; i++) {\n                                printf(\"%s\", ResTable::normalizeForOutput(\n                                        supportedInput[i].string()).string());\n                                if (i != N - 1) {\n                                    printf(\"' '\");\n                                } else {\n                                    printf(\"'\\n\");\n                                }\n                            }\n                            supportedInput.clear();\n                        }\n                        withinApplication = false;\n                        withinSupportsInput = false;\n                        withinFeatureGroup = false;\n                    } else if (depth < 3) {\n                        if (withinActivity && isMainActivity) {\n                            String8 aName(getComponentName(pkg, activityName));\n                            if (isLauncherActivity) {\n                                printf(\"launchable-activity:\");\n                                if (aName.length() > 0) {\n                                    printf(\" name='%s' \",\n                                            ResTable::normalizeForOutput(aName.string()).string());\n                                }\n                                printf(\" label='%s' icon='%s'\\n\",\n                                        ResTable::normalizeForOutput(activityLabel.string()).string(),\n                                        ResTable::normalizeForOutput(activityIcon.string()).string());\n                            }\n                            if (isLeanbackLauncherActivity) {\n                                printf(\"leanback-launchable-activity:\");\n                                if (aName.length() > 0) {\n                                    printf(\" name='%s' \",\n                                            ResTable::normalizeForOutput(aName.string()).string());\n                                }\n                                printf(\" label='%s' icon='%s' banner='%s'\\n\",\n                                        ResTable::normalizeForOutput(activityLabel.string()).string(),\n                                        ResTable::normalizeForOutput(activityIcon.string()).string(),\n                                        ResTable::normalizeForOutput(activityBanner.string()).string());\n                            }\n                        }\n                        if (!hasIntentFilter) {\n                            hasOtherActivities |= withinActivity;\n                            hasOtherReceivers |= withinReceiver;\n                            hasOtherServices |= withinService;\n                        } else {\n                            if (withinService) {\n                                hasPaymentService |= (actHostApduService && hasMetaHostPaymentCategory &&\n                                        hasBindNfcServicePermission);\n                                hasPaymentService |= (actOffHostApduService && hasMetaOffHostPaymentCategory &&\n                                        hasBindNfcServicePermission);\n                            }\n                        }\n                        withinActivity = false;\n                        withinService = false;\n                        withinReceiver = false;\n                        withinProvider = false;\n                        hasIntentFilter = false;\n                        isMainActivity = isLauncherActivity = isLeanbackLauncherActivity = false;\n                    } else if (depth < 4) {\n                        if (withinIntentFilter) {\n                            if (withinActivity) {\n                                hasMainActivity |= actMainActivity;\n                                hasLauncher |= catLauncher;\n                                hasCameraActivity |= actCamera;\n                                hasCameraSecureActivity |= actCameraSecure;\n                                hasOtherActivities |= !actMainActivity && !actCamera && !actCameraSecure;\n                            } else if (withinReceiver) {\n                                hasWidgetReceivers |= actWidgetReceivers;\n                                hasDeviceAdminReceiver |= (actDeviceAdminEnabled &&\n                                        hasBindDeviceAdminPermission);\n                                hasOtherReceivers |= (!actWidgetReceivers && !actDeviceAdminEnabled);\n                            } else if (withinService) {\n                                hasImeService |= actImeService;\n                                hasWallpaperService |= actWallpaperService;\n                                hasAccessibilityService |= (actAccessibilityService &&\n                                        hasBindAccessibilityServicePermission);\n                                hasPrintService |= (actPrintService && hasBindPrintServicePermission);\n                                hasNotificationListenerService |= actNotificationListenerService &&\n                                        hasBindNotificationListenerServicePermission;\n                                hasDreamService |= actDreamService && hasBindDreamServicePermission;\n                                hasOtherServices |= (!actImeService && !actWallpaperService &&\n                                        !actAccessibilityService && !actPrintService &&\n                                        !actHostApduService && !actOffHostApduService &&\n                                        !actNotificationListenerService);\n                            } else if (withinProvider) {\n                                hasDocumentsProvider |= actDocumentsProvider && hasRequiredSafAttributes;\n                            }\n                        }\n                        withinIntentFilter = false;\n                    }\n                    continue;\n                }\n                if (code != ResXMLTree::START_TAG) {\n                    continue;\n                }\n                depth++;\n\n                const char16_t* ctag16 = tree.getElementName(&len);\n                if (ctag16 == NULL) {\n                    fprintf(stderr, \"ERROR: failed to get XML element name (bad string pool)\\n\");\n                    goto bail;\n                }\n                String8 tag(ctag16);\n                //printf(\"Depth %d,  %s\\n\", depth, tag.string());\n                if (depth == 1) {\n                    if (tag != \"manifest\") {\n                        fprintf(stderr, \"ERROR: manifest does not start with <manifest> tag\\n\");\n                        goto bail;\n                    }\n                    pkg = AaptXml::getAttribute(tree, NULL, \"package\", NULL);\n                    printf(\"package: name='%s' \",\n                            ResTable::normalizeForOutput(pkg.string()).string());\n                    int32_t versionCode = AaptXml::getIntegerAttribute(tree, VERSION_CODE_ATTR,\n                            &error);\n                    if (error != \"\") {\n                        fprintf(stderr, \"ERROR getting 'android:versionCode' attribute: %s\\n\",\n                                error.string());\n                        goto bail;\n                    }\n                    if (versionCode > 0) {\n                        printf(\"versionCode='%d' \", versionCode);\n                    } else {\n                        printf(\"versionCode='' \");\n                    }\n                    String8 versionName = AaptXml::getResolvedAttribute(res, tree,\n                            VERSION_NAME_ATTR, &error);\n                    if (error != \"\") {\n                        fprintf(stderr, \"ERROR getting 'android:versionName' attribute: %s\\n\",\n                                error.string());\n                        goto bail;\n                    }\n                    printf(\"versionName='%s'\",\n                            ResTable::normalizeForOutput(versionName.string()).string());\n\n                    String8 splitName = AaptXml::getAttribute(tree, NULL, \"split\");\n                    if (!splitName.isEmpty()) {\n                        printf(\" split='%s'\", ResTable::normalizeForOutput(\n                                    splitName.string()).string());\n                    }\n\n                    String8 platformVersionName = AaptXml::getAttribute(tree, NULL,\n                            \"platformBuildVersionName\");\n                    printf(\" platformBuildVersionName='%s'\", platformVersionName.string());\n                    printf(\"\\n\");\n\n                    int32_t installLocation = AaptXml::getResolvedIntegerAttribute(res, tree,\n                            INSTALL_LOCATION_ATTR, &error);\n                    if (error != \"\") {\n                        fprintf(stderr, \"ERROR getting 'android:installLocation' attribute: %s\\n\",\n                                error.string());\n                        goto bail;\n                    }\n\n                    if (installLocation >= 0) {\n                        printf(\"install-location:'\");\n                        switch (installLocation) {\n                            case 0:\n                                printf(\"auto\");\n                                break;\n                            case 1:\n                                printf(\"internalOnly\");\n                                break;\n                            case 2:\n                                printf(\"preferExternal\");\n                                break;\n                            default:\n                                fprintf(stderr, \"Invalid installLocation %d\\n\", installLocation);\n                                goto bail;\n                        }\n                        printf(\"'\\n\");\n                    }\n                } else if (depth == 2) {\n                    withinApplication = false;\n                    if (tag == \"application\") {\n                        withinApplication = true;\n\n                        String8 label;\n                        const size_t NL = locales.size();\n                        for (size_t i=0; i<NL; i++) {\n                            const char* localeStr =  locales[i].string();\n                            assets.setLocale(localeStr != NULL ? localeStr : \"\");\n                            String8 llabel = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR,\n                                    &error);\n                            if (llabel != \"\") {\n                                if (localeStr == NULL || strlen(localeStr) == 0) {\n                                    label = llabel;\n                                    printf(\"application-label:'%s'\\n\",\n                                            ResTable::normalizeForOutput(llabel.string()).string());\n                                } else {\n                                    if (label == \"\") {\n                                        label = llabel;\n                                    }\n                                    printf(\"application-label-%s:'%s'\\n\", localeStr,\n                                           ResTable::normalizeForOutput(llabel.string()).string());\n                                }\n                            }\n                        }\n\n                        ResTable_config tmpConfig = config;\n                        const size_t ND = densities.size();\n                        for (size_t i=0; i<ND; i++) {\n                            tmpConfig.density = densities[i];\n                            assets.setConfiguration(tmpConfig);\n                            String8 icon = AaptXml::getResolvedAttribute(res, tree, ICON_ATTR,\n                                    &error);\n                            if (icon != \"\") {\n                                printf(\"application-icon-%d:'%s'\\n\", densities[i],\n                                        ResTable::normalizeForOutput(icon.string()).string());\n                            }\n                        }\n                        assets.setConfiguration(config);\n\n                        String8 icon = AaptXml::getResolvedAttribute(res, tree, ICON_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:icon' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n                        int32_t testOnly = AaptXml::getIntegerAttribute(tree, TEST_ONLY_ATTR, 0,\n                                &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:testOnly' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n                        printf(\"application: label='%s' \",\n                                ResTable::normalizeForOutput(label.string()).string());\n                        printf(\"icon='%s'\\n\", ResTable::normalizeForOutput(icon.string()).string());\n                        if (testOnly != 0) {\n                            printf(\"testOnly='%d'\\n\", testOnly);\n                        }\n\n                        int32_t debuggable = AaptXml::getResolvedIntegerAttribute(res, tree,\n                                DEBUGGABLE_ATTR, 0, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:debuggable' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n                        if (debuggable != 0) {\n                            printf(\"application-debuggable\\n\");\n                        }\n\n                        // We must search by name because the multiArch flag hasn't been API\n                        // frozen yet.\n                        int32_t multiArchIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE,\n                                \"multiArch\");\n                        if (multiArchIndex >= 0) {\n                            Res_value value;\n                            if (tree.getAttributeValue(multiArchIndex, &value) != NO_ERROR) {\n                                if (value.dataType >= Res_value::TYPE_FIRST_INT &&\n                                        value.dataType <= Res_value::TYPE_LAST_INT) {\n                                    hasMultiArch = value.data;\n                                }\n                            }\n                        }\n                    } else if (tag == \"uses-sdk\") {\n                        int32_t code = AaptXml::getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error);\n                        if (error != \"\") {\n                            error = \"\";\n                            String8 name = AaptXml::getResolvedAttribute(res, tree,\n                                    MIN_SDK_VERSION_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:minSdkVersion' attribute: %s\\n\",\n                                        error.string());\n                                goto bail;\n                            }\n                            if (name == \"Donut\") targetSdk = 4;\n                            printf(\"sdkVersion:'%s'\\n\",\n                                    ResTable::normalizeForOutput(name.string()).string());\n                        } else if (code != -1) {\n                            targetSdk = code;\n                            printf(\"sdkVersion:'%d'\\n\", code);\n                        }\n                        code = AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR);\n                        if (code != -1) {\n                            printf(\"maxSdkVersion:'%d'\\n\", code);\n                        }\n                        code = AaptXml::getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error);\n                        if (error != \"\") {\n                            error = \"\";\n                            String8 name = AaptXml::getResolvedAttribute(res, tree,\n                                    TARGET_SDK_VERSION_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:targetSdkVersion' attribute: %s\\n\",\n                                        error.string());\n                                goto bail;\n                            }\n                            if (name == \"Donut\" && targetSdk < 4) targetSdk = 4;\n                            printf(\"targetSdkVersion:'%s'\\n\",\n                                    ResTable::normalizeForOutput(name.string()).string());\n                        } else if (code != -1) {\n                            if (targetSdk < code) {\n                                targetSdk = code;\n                            }\n                            printf(\"targetSdkVersion:'%d'\\n\", code);\n                        }\n                    } else if (tag == \"uses-configuration\") {\n                        int32_t reqTouchScreen = AaptXml::getIntegerAttribute(tree,\n                                REQ_TOUCH_SCREEN_ATTR, 0);\n                        int32_t reqKeyboardType = AaptXml::getIntegerAttribute(tree,\n                                REQ_KEYBOARD_TYPE_ATTR, 0);\n                        int32_t reqHardKeyboard = AaptXml::getIntegerAttribute(tree,\n                                REQ_HARD_KEYBOARD_ATTR, 0);\n                        int32_t reqNavigation = AaptXml::getIntegerAttribute(tree,\n                                REQ_NAVIGATION_ATTR, 0);\n                        int32_t reqFiveWayNav = AaptXml::getIntegerAttribute(tree,\n                                REQ_FIVE_WAY_NAV_ATTR, 0);\n                        printf(\"uses-configuration:\");\n                        if (reqTouchScreen != 0) {\n                            printf(\" reqTouchScreen='%d'\", reqTouchScreen);\n                        }\n                        if (reqKeyboardType != 0) {\n                            printf(\" reqKeyboardType='%d'\", reqKeyboardType);\n                        }\n                        if (reqHardKeyboard != 0) {\n                            printf(\" reqHardKeyboard='%d'\", reqHardKeyboard);\n                        }\n                        if (reqNavigation != 0) {\n                            printf(\" reqNavigation='%d'\", reqNavigation);\n                        }\n                        if (reqFiveWayNav != 0) {\n                            printf(\" reqFiveWayNav='%d'\", reqFiveWayNav);\n                        }\n                        printf(\"\\n\");\n                    } else if (tag == \"supports-input\") {\n                        withinSupportsInput = true;\n                    } else if (tag == \"supports-screens\") {\n                        smallScreen = AaptXml::getIntegerAttribute(tree,\n                                SMALL_SCREEN_ATTR, 1);\n                        normalScreen = AaptXml::getIntegerAttribute(tree,\n                                NORMAL_SCREEN_ATTR, 1);\n                        largeScreen = AaptXml::getIntegerAttribute(tree,\n                                LARGE_SCREEN_ATTR, 1);\n                        xlargeScreen = AaptXml::getIntegerAttribute(tree,\n                                XLARGE_SCREEN_ATTR, 1);\n                        anyDensity = AaptXml::getIntegerAttribute(tree,\n                                ANY_DENSITY_ATTR, 1);\n                        requiresSmallestWidthDp = AaptXml::getIntegerAttribute(tree,\n                                REQUIRES_SMALLEST_WIDTH_DP_ATTR, 0);\n                        compatibleWidthLimitDp = AaptXml::getIntegerAttribute(tree,\n                                COMPATIBLE_WIDTH_LIMIT_DP_ATTR, 0);\n                        largestWidthLimitDp = AaptXml::getIntegerAttribute(tree,\n                                LARGEST_WIDTH_LIMIT_DP_ATTR, 0);\n                    } else if (tag == \"feature-group\") {\n                        withinFeatureGroup = true;\n                        FeatureGroup group;\n                        group.label = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:label' attribute:\"\n                                    \" %s\\n\", error.string());\n                            goto bail;\n                        }\n                        featureGroups.add(group);\n\n                    } else if (tag == \"uses-feature\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (name != \"\" && error == \"\") {\n                            int req = AaptXml::getIntegerAttribute(tree,\n                                    REQUIRED_ATTR, 1);\n\n                            commonFeatures.features.add(name, req);\n                            if (req) {\n                                addParentFeatures(&commonFeatures, name);\n                            }\n                        } else {\n                            int vers = AaptXml::getIntegerAttribute(tree,\n                                    GL_ES_VERSION_ATTR, &error);\n                            if (error == \"\") {\n                                if (vers > commonFeatures.openGLESVersion) {\n                                    commonFeatures.openGLESVersion = vers;\n                                }\n                            }\n                        }\n                    } else if (tag == \"uses-permission\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (name != \"\" && error == \"\") {\n                            if (name == \"android.permission.CAMERA\") {\n                                addImpliedFeature(&impliedFeatures, \"android.hardware.camera\",\n                                        String8::format(\"requested %s permission\", name.string())\n                                        .string());\n                            } else if (name == \"android.permission.ACCESS_FINE_LOCATION\") {\n                                addImpliedFeature(&impliedFeatures, \"android.hardware.location.gps\",\n                                        String8::format(\"requested %s permission\", name.string())\n                                        .string());\n                                addImpliedFeature(&impliedFeatures, \"android.hardware.location\",\n                                        String8::format(\"requested %s permission\", name.string())\n                                        .string());\n                            } else if (name == \"android.permission.ACCESS_MOCK_LOCATION\") {\n                                addImpliedFeature(&impliedFeatures, \"android.hardware.location\",\n                                        String8::format(\"requested %s permission\", name.string())\n                                        .string());\n                            } else if (name == \"android.permission.ACCESS_COARSE_LOCATION\") {\n                                addImpliedFeature(&impliedFeatures, \"android.hardware.location.network\",\n                                        String8::format(\"requested %s permission\", name.string())\n                                        .string());\n                                addImpliedFeature(&impliedFeatures, \"android.hardware.location\",\n                                        String8::format(\"requested %s permission\", name.string())\n                                        .string());\n                            } else if (name == \"android.permission.ACCESS_LOCATION_EXTRA_COMMANDS\" ||\n                                       name == \"android.permission.INSTALL_LOCATION_PROVIDER\") {\n                                addImpliedFeature(&impliedFeatures, \"android.hardware.location\",\n                                        String8::format(\"requested %s permission\", name.string())\n                                        .string());\n                            } else if (name == \"android.permission.BLUETOOTH\" ||\n                                       name == \"android.permission.BLUETOOTH_ADMIN\") {\n                                if (targetSdk > 4) {\n                                    addImpliedFeature(&impliedFeatures, \"android.hardware.bluetooth\",\n                                            String8::format(\"requested %s permission\", name.string())\n                                            .string());\n                                    addImpliedFeature(&impliedFeatures, \"android.hardware.bluetooth\",\n                                            \"targetSdkVersion > 4\");\n                                }\n                            } else if (name == \"android.permission.RECORD_AUDIO\") {\n                                addImpliedFeature(&impliedFeatures, \"android.hardware.microphone\",\n                                        String8::format(\"requested %s permission\", name.string())\n                                        .string());\n                            } else if (name == \"android.permission.ACCESS_WIFI_STATE\" ||\n                                       name == \"android.permission.CHANGE_WIFI_STATE\" ||\n                                       name == \"android.permission.CHANGE_WIFI_MULTICAST_STATE\") {\n                                addImpliedFeature(&impliedFeatures, \"android.hardware.wifi\",\n                                        String8::format(\"requested %s permission\", name.string())\n                                        .string());\n                            } else if (name == \"android.permission.CALL_PHONE\" ||\n                                       name == \"android.permission.CALL_PRIVILEGED\" ||\n                                       name == \"android.permission.MODIFY_PHONE_STATE\" ||\n                                       name == \"android.permission.PROCESS_OUTGOING_CALLS\" ||\n                                       name == \"android.permission.READ_SMS\" ||\n                                       name == \"android.permission.RECEIVE_SMS\" ||\n                                       name == \"android.permission.RECEIVE_MMS\" ||\n                                       name == \"android.permission.RECEIVE_WAP_PUSH\" ||\n                                       name == \"android.permission.SEND_SMS\" ||\n                                       name == \"android.permission.WRITE_APN_SETTINGS\" ||\n                                       name == \"android.permission.WRITE_SMS\") {\n                                addImpliedFeature(&impliedFeatures, \"android.hardware.telephony\",\n                                        String8(\"requested a telephony permission\").string());\n                            } else if (name == \"android.permission.WRITE_EXTERNAL_STORAGE\") {\n                                hasWriteExternalStoragePermission = true;\n                            } else if (name == \"android.permission.READ_EXTERNAL_STORAGE\") {\n                                hasReadExternalStoragePermission = true;\n                            } else if (name == \"android.permission.READ_PHONE_STATE\") {\n                                hasReadPhoneStatePermission = true;\n                            } else if (name == \"android.permission.READ_CONTACTS\") {\n                                hasReadContactsPermission = true;\n                            } else if (name == \"android.permission.WRITE_CONTACTS\") {\n                                hasWriteContactsPermission = true;\n                            } else if (name == \"android.permission.READ_CALL_LOG\") {\n                                hasReadCallLogPermission = true;\n                            } else if (name == \"android.permission.WRITE_CALL_LOG\") {\n                                hasWriteCallLogPermission = true;\n                            }\n\n                            printUsesPermission(name,\n                                    AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1) == 0,\n                                    AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR));\n                       } else {\n                            fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n                    } else if (tag == \"uses-package\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (name != \"\" && error == \"\") {\n                            printf(\"uses-package:'%s'\\n\",\n                                    ResTable::normalizeForOutput(name.string()).string());\n                        } else {\n                            fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                    error.string());\n                                goto bail;\n                        }\n                    } else if (tag == \"original-package\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (name != \"\" && error == \"\") {\n                            printf(\"original-package:'%s'\\n\",\n                                    ResTable::normalizeForOutput(name.string()).string());\n                        } else {\n                            fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                    error.string());\n                                goto bail;\n                        }\n                    } else if (tag == \"supports-gl-texture\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (name != \"\" && error == \"\") {\n                            printf(\"supports-gl-texture:'%s'\\n\",\n                                    ResTable::normalizeForOutput(name.string()).string());\n                        } else {\n                            fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                    error.string());\n                                goto bail;\n                        }\n                    } else if (tag == \"compatible-screens\") {\n                        printCompatibleScreens(tree, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting compatible screens: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n                        depth--;\n                    } else if (tag == \"package-verifier\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (name != \"\" && error == \"\") {\n                            String8 publicKey = AaptXml::getAttribute(tree, PUBLIC_KEY_ATTR, &error);\n                            if (publicKey != \"\" && error == \"\") {\n                                printf(\"package-verifier: name='%s' publicKey='%s'\\n\",\n                                        ResTable::normalizeForOutput(name.string()).string(),\n                                        ResTable::normalizeForOutput(publicKey.string()).string());\n                            }\n                        }\n                    }\n                } else if (depth == 3) {\n                    withinActivity = false;\n                    withinReceiver = false;\n                    withinService = false;\n                    withinProvider = false;\n                    hasIntentFilter = false;\n                    hasMetaHostPaymentCategory = false;\n                    hasMetaOffHostPaymentCategory = false;\n                    hasBindDeviceAdminPermission = false;\n                    hasBindInputMethodPermission = false;\n                    hasBindAccessibilityServicePermission = false;\n                    hasBindPrintServicePermission = false;\n                    hasBindNfcServicePermission = false;\n                    hasRequiredSafAttributes = false;\n                    hasBindNotificationListenerServicePermission = false;\n                    hasBindDreamServicePermission = false;\n                    if (withinApplication) {\n                        if(tag == \"activity\") {\n                            withinActivity = true;\n                            activityName = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                        error.string());\n                                goto bail;\n                            }\n\n                            activityLabel = AaptXml::getResolvedAttribute(res, tree, LABEL_ATTR,\n                                    &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:label' attribute: %s\\n\",\n                                        error.string());\n                                goto bail;\n                            }\n\n                            activityIcon = AaptXml::getResolvedAttribute(res, tree, ICON_ATTR,\n                                    &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:icon' attribute: %s\\n\",\n                                        error.string());\n                                goto bail;\n                            }\n\n                            activityBanner = AaptXml::getResolvedAttribute(res, tree, BANNER_ATTR,\n                                    &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:banner' attribute: %s\\n\",\n                                        error.string());\n                                goto bail;\n                            }\n\n                            int32_t orien = AaptXml::getResolvedIntegerAttribute(res, tree,\n                                    SCREEN_ORIENTATION_ATTR, &error);\n                            if (error == \"\") {\n                                if (orien == 0 || orien == 6 || orien == 8) {\n                                    // Requests landscape, sensorLandscape, or reverseLandscape.\n                                    addImpliedFeature(&impliedFeatures, \"android.hardware.screen.landscape\",\n                                            \"one or more activities have specified a landscape orientation\");\n                                } else if (orien == 1 || orien == 7 || orien == 9) {\n                                    // Requests portrait, sensorPortrait, or reversePortrait.\n                                    addImpliedFeature(&impliedFeatures, \"android.hardware.screen.portrait\",\n                                            \"one or more activities have specified a portrait orientation\");\n                                }\n                            }\n                        } else if (tag == \"uses-library\") {\n                            String8 libraryName = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr,\n                                        \"ERROR getting 'android:name' attribute for uses-library\"\n                                        \" %s\\n\", error.string());\n                                goto bail;\n                            }\n                            int req = AaptXml::getIntegerAttribute(tree,\n                                    REQUIRED_ATTR, 1);\n                            printf(\"uses-library%s:'%s'\\n\",\n                                    req ? \"\" : \"-not-required\", ResTable::normalizeForOutput(\n                                            libraryName.string()).string());\n                        } else if (tag == \"receiver\") {\n                            withinReceiver = true;\n                            receiverName = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n\n                            if (error != \"\") {\n                                fprintf(stderr,\n                                        \"ERROR getting 'android:name' attribute for receiver:\"\n                                        \" %s\\n\", error.string());\n                                goto bail;\n                            }\n\n                            String8 permission = AaptXml::getAttribute(tree, PERMISSION_ATTR,\n                                    &error);\n                            if (error == \"\") {\n                                if (permission == \"android.permission.BIND_DEVICE_ADMIN\") {\n                                    hasBindDeviceAdminPermission = true;\n                                }\n                            } else {\n                                fprintf(stderr, \"ERROR getting 'android:permission' attribute for\"\n                                        \" receiver '%s': %s\\n\", receiverName.string(), error.string());\n                            }\n                        } else if (tag == \"service\") {\n                            withinService = true;\n                            serviceName = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:name' attribute for \"\n                                        \"service:%s\\n\", error.string());\n                                goto bail;\n                            }\n\n                            String8 permission = AaptXml::getAttribute(tree, PERMISSION_ATTR,\n                                    &error);\n                            if (error == \"\") {\n                                if (permission == \"android.permission.BIND_INPUT_METHOD\") {\n                                    hasBindInputMethodPermission = true;\n                                } else if (permission == \"android.permission.BIND_ACCESSIBILITY_SERVICE\") {\n                                    hasBindAccessibilityServicePermission = true;\n                                } else if (permission == \"android.permission.BIND_PRINT_SERVICE\") {\n                                    hasBindPrintServicePermission = true;\n                                } else if (permission == \"android.permission.BIND_NFC_SERVICE\") {\n                                    hasBindNfcServicePermission = true;\n                                } else if (permission == \"android.permission.BIND_NOTIFICATION_LISTENER_SERVICE\") {\n                                    hasBindNotificationListenerServicePermission = true;\n                                } else if (permission == \"android.permission.BIND_DREAM_SERVICE\") {\n                                    hasBindDreamServicePermission = true;\n                                }\n                            } else {\n                                fprintf(stderr, \"ERROR getting 'android:permission' attribute for\"\n                                        \" service '%s': %s\\n\", serviceName.string(), error.string());\n                            }\n                        } else if (tag == \"provider\") {\n                            withinProvider = true;\n\n                            bool exported = AaptXml::getResolvedIntegerAttribute(res, tree,\n                                    EXPORTED_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:exported' attribute for provider:\"\n                                        \" %s\\n\", error.string());\n                                goto bail;\n                            }\n\n                            bool grantUriPermissions = AaptXml::getResolvedIntegerAttribute(\n                                    res, tree, GRANT_URI_PERMISSIONS_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:grantUriPermissions' attribute for provider:\"\n                                        \" %s\\n\", error.string());\n                                goto bail;\n                            }\n\n                            String8 permission = AaptXml::getResolvedAttribute(res, tree,\n                                    PERMISSION_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:permission' attribute for provider:\"\n                                        \" %s\\n\", error.string());\n                                goto bail;\n                            }\n\n                            hasRequiredSafAttributes |= exported && grantUriPermissions &&\n                                permission == \"android.permission.MANAGE_DOCUMENTS\";\n\n                        } else if (bundle->getIncludeMetaData() && tag == \"meta-data\") {\n                            String8 metaDataName = AaptXml::getResolvedAttribute(res, tree,\n                                    NAME_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:name' attribute for \"\n                                        \"meta-data:%s\\n\", error.string());\n                                goto bail;\n                            }\n                            printf(\"meta-data: name='%s' \",\n                                    ResTable::normalizeForOutput(metaDataName.string()).string());\n                            printResolvedResourceAttribute(res, tree, VALUE_ATTR, String8(\"value\"),\n                                    &error);\n                            if (error != \"\") {\n                                // Try looking for a RESOURCE_ATTR\n                                error = \"\";\n                                printResolvedResourceAttribute(res, tree, RESOURCE_ATTR,\n                                        String8(\"resource\"), &error);\n                                if (error != \"\") {\n                                    fprintf(stderr, \"ERROR getting 'android:value' or \"\n                                            \"'android:resource' attribute for \"\n                                            \"meta-data:%s\\n\", error.string());\n                                    goto bail;\n                                }\n                            }\n                            printf(\"\\n\");\n                        } else if (withinSupportsInput && tag == \"input-type\") {\n                            String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                            if (name != \"\" && error == \"\") {\n                                supportedInput.add(name);\n                            } else {\n                                fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                        error.string());\n                                goto bail;\n                            }\n                        }\n                    } else if (withinFeatureGroup && tag == \"uses-feature\") {\n                        FeatureGroup& top = featureGroups.editTop();\n\n                        String8 name = AaptXml::getResolvedAttribute(res, tree, NAME_ATTR, &error);\n                        if (name != \"\" && error == \"\") {\n                            top.features.add(name, true);\n                            addParentFeatures(&top, name);\n                        } else {\n                            int vers = AaptXml::getIntegerAttribute(tree, GL_ES_VERSION_ATTR,\n                                    &error);\n                            if (error == \"\") {\n                                if (vers > top.openGLESVersion) {\n                                    top.openGLESVersion = vers;\n                                }\n                            }\n                        }\n                    }\n                } else if (depth == 4) {\n                    if (tag == \"intent-filter\") {\n                        hasIntentFilter = true;\n                        withinIntentFilter = true;\n                        actMainActivity = false;\n                        actWidgetReceivers = false;\n                        actImeService = false;\n                        actWallpaperService = false;\n                        actAccessibilityService = false;\n                        actPrintService = false;\n                        actDeviceAdminEnabled = false;\n                        actHostApduService = false;\n                        actOffHostApduService = false;\n                        actDocumentsProvider = false;\n                        actNotificationListenerService = false;\n                        actDreamService = false;\n                        actCamera = false;\n                        actCameraSecure = false;\n                        catLauncher = false;\n                    } else if (withinService && tag == \"meta-data\") {\n                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:name' attribute for\"\n                                    \" meta-data tag in service '%s': %s\\n\", serviceName.string(), error.string());\n                            goto bail;\n                        }\n\n                        if (name == \"android.nfc.cardemulation.host_apdu_service\" ||\n                                name == \"android.nfc.cardemulation.off_host_apdu_service\") {\n                            bool offHost = true;\n                            if (name == \"android.nfc.cardemulation.host_apdu_service\") {\n                                offHost = false;\n                            }\n\n                            String8 xmlPath = AaptXml::getResolvedAttribute(res, tree,\n                                    RESOURCE_ATTR, &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting 'android:resource' attribute for\"\n                                        \" meta-data tag in service '%s': %s\\n\", serviceName.string(), error.string());\n                                goto bail;\n                            }\n\n                            Vector<String8> categories = getNfcAidCategories(assets, xmlPath,\n                                    offHost, &error);\n                            if (error != \"\") {\n                                fprintf(stderr, \"ERROR getting AID category for service '%s'\\n\",\n                                        serviceName.string());\n                                goto bail;\n                            }\n\n                            const size_t catLen = categories.size();\n                            for (size_t i = 0; i < catLen; i++) {\n                                bool paymentCategory = (categories[i] == \"payment\");\n                                if (offHost) {\n                                    hasMetaOffHostPaymentCategory |= paymentCategory;\n                                } else {\n                                    hasMetaHostPaymentCategory |= paymentCategory;\n                                }\n                            }\n                        }\n                    }\n                } else if ((depth == 5) && withinIntentFilter) {\n                    String8 action;\n                    if (tag == \"action\") {\n                        action = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'android:name' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n\n                        if (withinActivity) {\n                            if (action == \"android.intent.action.MAIN\") {\n                                isMainActivity = true;\n                                actMainActivity = true;\n                            } else if (action == \"android.media.action.STILL_IMAGE_CAMERA\" ||\n                                    action == \"android.media.action.VIDEO_CAMERA\") {\n                                actCamera = true;\n                            } else if (action == \"android.media.action.STILL_IMAGE_CAMERA_SECURE\") {\n                                actCameraSecure = true;\n                            }\n                        } else if (withinReceiver) {\n                            if (action == \"android.appwidget.action.APPWIDGET_UPDATE\") {\n                                actWidgetReceivers = true;\n                            } else if (action == \"android.app.action.DEVICE_ADMIN_ENABLED\") {\n                                actDeviceAdminEnabled = true;\n                            }\n                        } else if (withinService) {\n                            if (action == \"android.view.InputMethod\") {\n                                actImeService = true;\n                            } else if (action == \"android.service.wallpaper.WallpaperService\") {\n                                actWallpaperService = true;\n                            } else if (action == \"android.accessibilityservice.AccessibilityService\") {\n                                actAccessibilityService = true;\n                            } else if (action == \"android.printservice.PrintService\") {\n                                actPrintService = true;\n                            } else if (action == \"android.nfc.cardemulation.action.HOST_APDU_SERVICE\") {\n                                actHostApduService = true;\n                            } else if (action == \"android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE\") {\n                                actOffHostApduService = true;\n                            } else if (action == \"android.service.notification.NotificationListenerService\") {\n                                actNotificationListenerService = true;\n                            } else if (action == \"android.service.dreams.DreamService\") {\n                                actDreamService = true;\n                            }\n                        } else if (withinProvider) {\n                            if (action == \"android.content.action.DOCUMENTS_PROVIDER\") {\n                                actDocumentsProvider = true;\n                            }\n                        }\n                        if (action == \"android.intent.action.SEARCH\") {\n                            isSearchable = true;\n                        }\n                    }\n\n                    if (tag == \"category\") {\n                        String8 category = AaptXml::getAttribute(tree, NAME_ATTR, &error);\n                        if (error != \"\") {\n                            fprintf(stderr, \"ERROR getting 'name' attribute: %s\\n\",\n                                    error.string());\n                            goto bail;\n                        }\n                        if (withinActivity) {\n                            if (category == \"android.intent.category.LAUNCHER\") {\n                                isLauncherActivity = true;\n                            } else if (category == \"android.intent.category.LEANBACK_LAUNCHER\") {\n                                isLeanbackLauncherActivity = true;\n                            } else if (category == \"android.intent.category.HOME\") {\n                                catLauncher = true;\n                            }\n                        }\n                    }\n                }\n            }\n\n            // Pre-1.6 implicitly granted permission compatibility logic\n            if (targetSdk < 4) {\n                if (!hasWriteExternalStoragePermission) {\n                    printUsesPermission(String8(\"android.permission.WRITE_EXTERNAL_STORAGE\"));\n                    printUsesImpliedPermission(String8(\"android.permission.WRITE_EXTERNAL_STORAGE\"),\n                            String8(\"targetSdkVersion < 4\"));\n                    hasWriteExternalStoragePermission = true;\n                }\n                if (!hasReadPhoneStatePermission) {\n                    printUsesPermission(String8(\"android.permission.READ_PHONE_STATE\"));\n                    printUsesImpliedPermission(String8(\"android.permission.READ_PHONE_STATE\"),\n                            String8(\"targetSdkVersion < 4\"));\n                }\n            }\n\n            // If the application has requested WRITE_EXTERNAL_STORAGE, we will\n            // force them to always take READ_EXTERNAL_STORAGE as well.  We always\n            // do this (regardless of target API version) because we can't have\n            // an app with write permission but not read permission.\n            if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) {\n                printUsesPermission(String8(\"android.permission.READ_EXTERNAL_STORAGE\"));\n                printUsesImpliedPermission(String8(\"android.permission.READ_EXTERNAL_STORAGE\"),\n                        String8(\"requested WRITE_EXTERNAL_STORAGE\"));\n            }\n\n            // Pre-JellyBean call log permission compatibility.\n            if (targetSdk < 16) {\n                if (!hasReadCallLogPermission && hasReadContactsPermission) {\n                    printUsesPermission(String8(\"android.permission.READ_CALL_LOG\"));\n                    printUsesImpliedPermission(String8(\"android.permission.READ_CALL_LOG\"),\n                            String8(\"targetSdkVersion < 16 and requested READ_CONTACTS\"));\n                }\n                if (!hasWriteCallLogPermission && hasWriteContactsPermission) {\n                    printUsesPermission(String8(\"android.permission.WRITE_CALL_LOG\"));\n                    printUsesImpliedPermission(String8(\"android.permission.WRITE_CALL_LOG\"),\n                            String8(\"targetSdkVersion < 16 and requested WRITE_CONTACTS\"));\n                }\n            }\n\n            addImpliedFeature(&impliedFeatures, \"android.hardware.touchscreen\",\n                    \"default feature for all apps\");\n\n            const size_t numFeatureGroups = featureGroups.size();\n            if (numFeatureGroups == 0) {\n                // If no <feature-group> tags were defined, apply auto-implied features.\n                printFeatureGroup(commonFeatures, &impliedFeatures);\n\n            } else {\n                // <feature-group> tags are defined, so we ignore implied features and\n                for (size_t i = 0; i < numFeatureGroups; i++) {\n                    FeatureGroup& grp = featureGroups.editItemAt(i);\n\n                    if (commonFeatures.openGLESVersion > grp.openGLESVersion) {\n                        grp.openGLESVersion = commonFeatures.openGLESVersion;\n                    }\n\n                    // Merge the features defined in the top level (not inside a <feature-group>)\n                    // with this feature group.\n                    const size_t numCommonFeatures = commonFeatures.features.size();\n                    for (size_t j = 0; j < numCommonFeatures; j++) {\n                        if (grp.features.indexOfKey(commonFeatures.features.keyAt(j)) < 0) {\n                            grp.features.add(commonFeatures.features.keyAt(j),\n                                    commonFeatures.features[j]);\n                        }\n                    }\n\n                   if (!grp.features.isEmpty()) {\n                        printFeatureGroup(grp);\n                    }\n                }\n            }\n\n\n            if (hasWidgetReceivers) {\n                printComponentPresence(\"app-widget\");\n            }\n            if (hasDeviceAdminReceiver) {\n                printComponentPresence(\"device-admin\");\n            }\n            if (hasImeService) {\n                printComponentPresence(\"ime\");\n            }\n            if (hasWallpaperService) {\n                printComponentPresence(\"wallpaper\");\n            }\n            if (hasAccessibilityService) {\n                printComponentPresence(\"accessibility\");\n            }\n            if (hasPrintService) {\n                printComponentPresence(\"print-service\");\n            }\n            if (hasPaymentService) {\n                printComponentPresence(\"payment\");\n            }\n            if (isSearchable) {\n                printComponentPresence(\"search\");\n            }\n            if (hasDocumentsProvider) {\n                printComponentPresence(\"document-provider\");\n            }\n            if (hasLauncher) {\n                printComponentPresence(\"launcher\");\n            }\n            if (hasNotificationListenerService) {\n                printComponentPresence(\"notification-listener\");\n            }\n            if (hasDreamService) {\n                printComponentPresence(\"dream\");\n            }\n            if (hasCameraActivity) {\n                printComponentPresence(\"camera\");\n            }\n            if (hasCameraSecureActivity) {\n                printComponentPresence(\"camera-secure\");\n            }\n\n            if (hasMainActivity) {\n                printf(\"main\\n\");\n            }\n            if (hasOtherActivities) {\n                printf(\"other-activities\\n\");\n            }\n             if (hasOtherReceivers) {\n                printf(\"other-receivers\\n\");\n            }\n            if (hasOtherServices) {\n                printf(\"other-services\\n\");\n            }\n\n            // For modern apps, if screen size buckets haven't been specified\n            // but the new width ranges have, then infer the buckets from them.\n            if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0\n                    && requiresSmallestWidthDp > 0) {\n                int compatWidth = compatibleWidthLimitDp;\n                if (compatWidth <= 0) {\n                    compatWidth = requiresSmallestWidthDp;\n                }\n                if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) {\n                    smallScreen = -1;\n                } else {\n                    smallScreen = 0;\n                }\n                if (requiresSmallestWidthDp <= 320 && compatWidth >= 320) {\n                    normalScreen = -1;\n                } else {\n                    normalScreen = 0;\n                }\n                if (requiresSmallestWidthDp <= 480 && compatWidth >= 480) {\n                    largeScreen = -1;\n                } else {\n                    largeScreen = 0;\n                }\n                if (requiresSmallestWidthDp <= 720 && compatWidth >= 720) {\n                    xlargeScreen = -1;\n                } else {\n                    xlargeScreen = 0;\n                }\n            }\n\n            // Determine default values for any unspecified screen sizes,\n            // based on the target SDK of the package.  As of 4 (donut)\n            // the screen size support was introduced, so all default to\n            // enabled.\n            if (smallScreen > 0) {\n                smallScreen = targetSdk >= 4 ? -1 : 0;\n            }\n            if (normalScreen > 0) {\n                normalScreen = -1;\n            }\n            if (largeScreen > 0) {\n                largeScreen = targetSdk >= 4 ? -1 : 0;\n            }\n            if (xlargeScreen > 0) {\n                // Introduced in Gingerbread.\n                xlargeScreen = targetSdk >= 9 ? -1 : 0;\n            }\n            if (anyDensity > 0) {\n                anyDensity = (targetSdk >= 4 || requiresSmallestWidthDp > 0\n                        || compatibleWidthLimitDp > 0) ? -1 : 0;\n            }\n            printf(\"supports-screens:\");\n            if (smallScreen != 0) {\n                printf(\" 'small'\");\n            }\n            if (normalScreen != 0) {\n                printf(\" 'normal'\");\n            }\n            if (largeScreen != 0) {\n                printf(\" 'large'\");\n            }\n            if (xlargeScreen != 0) {\n                printf(\" 'xlarge'\");\n            }\n            printf(\"\\n\");\n            printf(\"supports-any-density: '%s'\\n\", anyDensity ? \"true\" : \"false\");\n            if (requiresSmallestWidthDp > 0) {\n                printf(\"requires-smallest-width:'%d'\\n\", requiresSmallestWidthDp);\n            }\n            if (compatibleWidthLimitDp > 0) {\n                printf(\"compatible-width-limit:'%d'\\n\", compatibleWidthLimitDp);\n            }\n            if (largestWidthLimitDp > 0) {\n                printf(\"largest-width-limit:'%d'\\n\", largestWidthLimitDp);\n            }\n\n            printf(\"locales:\");\n            const size_t NL = locales.size();\n            for (size_t i=0; i<NL; i++) {\n                const char* localeStr =  locales[i].string();\n                if (localeStr == NULL || strlen(localeStr) == 0) {\n                    localeStr = \"--_--\";\n                }\n                printf(\" '%s'\", localeStr);\n            }\n            printf(\"\\n\");\n\n            printf(\"densities:\");\n            const size_t ND = densities.size();\n            for (size_t i=0; i<ND; i++) {\n                printf(\" '%d'\", densities[i]);\n            }\n            printf(\"\\n\");\n\n            AssetDir* dir = assets.openNonAssetDir(assetsCookie, \"lib\");\n            if (dir != NULL) {\n                if (dir->getFileCount() > 0) {\n                    SortedVector<String8> architectures;\n                    for (size_t i=0; i<dir->getFileCount(); i++) {\n                        architectures.add(ResTable::normalizeForOutput(\n                                dir->getFileName(i).string()));\n                    }\n\n                    bool outputAltNativeCode = false;\n                    // A multiArch package is one that contains 64-bit and\n                    // 32-bit versions of native code and expects 3rd-party\n                    // apps to load these native code libraries. Since most\n                    // 64-bit systems also support 32-bit apps, the apps\n                    // loading this multiArch package's code may be either\n                    // 32-bit or 64-bit.\n                    if (hasMultiArch) {\n                        // If this is a multiArch package, report the 64-bit\n                        // version only. Then as a separate entry, report the\n                        // rest.\n                        //\n                        // If we report the 32-bit architecture, this APK will\n                        // be installed on a 32-bit device, causing a large waste\n                        // of bandwidth and disk space. This assumes that\n                        // the developer of the multiArch package has also\n                        // made a version that is 32-bit only.\n                        String8 intel64(\"x86_64\");\n                        String8 arm64(\"arm64-v8a\");\n                        ssize_t index = architectures.indexOf(intel64);\n                        if (index < 0) {\n                            index = architectures.indexOf(arm64);\n                        }\n\n                        if (index >= 0) {\n                            printf(\"native-code: '%s'\\n\", architectures[index].string());\n                            architectures.removeAt(index);\n                            outputAltNativeCode = true;\n                        }\n                    }\n\n                    const size_t archCount = architectures.size();\n                    if (archCount > 0) {\n                        if (outputAltNativeCode) {\n                            printf(\"alt-\");\n                        }\n                        printf(\"native-code:\");\n                        for (size_t i = 0; i < archCount; i++) {\n                            printf(\" '%s'\", architectures[i].string());\n                        }\n                        printf(\"\\n\");\n                    }\n                }\n                delete dir;\n            }\n        } else if (strcmp(\"badger\", option) == 0) {\n            printf(\"%s\", CONSOLE_DATA);\n        } else if (strcmp(\"configurations\", option) == 0) {\n            Vector<ResTable_config> configs;\n            res.getConfigurations(&configs);\n            const size_t N = configs.size();\n            for (size_t i=0; i<N; i++) {\n                printf(\"%s\\n\", configs[i].toString().string());\n            }\n        } else {\n            fprintf(stderr, \"ERROR: unknown dump option '%s'\\n\", option);\n            goto bail;\n        }\n    }\n\n    result = NO_ERROR;\n\nbail:\n    if (asset) {\n        delete asset;\n    }\n    return (result != NO_ERROR);\n}\n\n\n/*\n * Handle the \"add\" command, which wants to add files to a new or\n * pre-existing archive.\n */\nint doAdd(Bundle* bundle)\n{\n    ZipFile* zip = NULL;\n    status_t result = UNKNOWN_ERROR;\n    const char* zipFileName;\n\n    if (bundle->getUpdate()) {\n        /* avoid confusion */\n        fprintf(stderr, \"ERROR: can't use '-u' with add\\n\");\n        goto bail;\n    }\n\n    if (bundle->getFileSpecCount() < 1) {\n        fprintf(stderr, \"ERROR: must specify zip file name\\n\");\n        goto bail;\n    }\n    zipFileName = bundle->getFileSpecEntry(0);\n\n    if (bundle->getFileSpecCount() < 2) {\n        fprintf(stderr, \"NOTE: nothing to do\\n\");\n        goto bail;\n    }\n\n    zip = openReadWrite(zipFileName, true);\n    if (zip == NULL) {\n        fprintf(stderr, \"ERROR: failed opening/creating '%s' as Zip file\\n\", zipFileName);\n        goto bail;\n    }\n\n    for (int i = 1; i < bundle->getFileSpecCount(); i++) {\n        const char* fileName = bundle->getFileSpecEntry(i);\n\n        if (strcasecmp(String8(fileName).getPathExtension().string(), \".gz\") == 0) {\n            printf(\" '%s'... (from gzip)\\n\", fileName);\n            result = zip->addGzip(fileName, String8(fileName).getBasePath().string(), NULL);\n        } else {\n            if (bundle->getJunkPath()) {\n                String8 storageName = String8(fileName).getPathLeaf();\n                printf(\" '%s' as '%s'...\\n\", fileName,\n                        ResTable::normalizeForOutput(storageName.string()).string());\n                result = zip->add(fileName, storageName.string(),\n                                  bundle->getCompressionMethod(), NULL);\n            } else {\n                printf(\" '%s'...\\n\", fileName);\n                result = zip->add(fileName, bundle->getCompressionMethod(), NULL);\n            }\n        }\n        if (result != NO_ERROR) {\n            fprintf(stderr, \"Unable to add '%s' to '%s'\", bundle->getFileSpecEntry(i), zipFileName);\n            if (result == NAME_NOT_FOUND) {\n                fprintf(stderr, \": file not found\\n\");\n            } else if (result == ALREADY_EXISTS) {\n                fprintf(stderr, \": already exists in archive\\n\");\n            } else {\n                fprintf(stderr, \"\\n\");\n            }\n            goto bail;\n        }\n    }\n\n    result = NO_ERROR;\n\nbail:\n    delete zip;\n    return (result != NO_ERROR);\n}\n\n\n/*\n * Delete files from an existing archive.\n */\nint doRemove(Bundle* bundle)\n{\n    ZipFile* zip = NULL;\n    status_t result = UNKNOWN_ERROR;\n    const char* zipFileName;\n\n    if (bundle->getFileSpecCount() < 1) {\n        fprintf(stderr, \"ERROR: must specify zip file name\\n\");\n        goto bail;\n    }\n    zipFileName = bundle->getFileSpecEntry(0);\n\n    if (bundle->getFileSpecCount() < 2) {\n        fprintf(stderr, \"NOTE: nothing to do\\n\");\n        goto bail;\n    }\n\n    zip = openReadWrite(zipFileName, false);\n    if (zip == NULL) {\n        fprintf(stderr, \"ERROR: failed opening Zip archive '%s'\\n\",\n            zipFileName);\n        goto bail;\n    }\n\n    for (int i = 1; i < bundle->getFileSpecCount(); i++) {\n        const char* fileName = bundle->getFileSpecEntry(i);\n        ZipEntry* entry;\n\n        entry = zip->getEntryByName(fileName);\n        if (entry == NULL) {\n            printf(\" '%s' NOT FOUND\\n\", fileName);\n            continue;\n        }\n\n        result = zip->remove(entry);\n\n        if (result != NO_ERROR) {\n            fprintf(stderr, \"Unable to delete '%s' from '%s'\\n\",\n                bundle->getFileSpecEntry(i), zipFileName);\n            goto bail;\n        }\n    }\n\n    /* update the archive */\n    zip->flush();\n\nbail:\n    delete zip;\n    return (result != NO_ERROR);\n}\n\nstatic status_t addResourcesToBuilder(const sp<AaptDir>& dir, const sp<ApkBuilder>& builder, bool ignoreConfig=false) {\n    const size_t numDirs = dir->getDirs().size();\n    for (size_t i = 0; i < numDirs; i++) {\n        bool ignore = ignoreConfig;\n        const sp<AaptDir>& subDir = dir->getDirs().valueAt(i);\n        const char* dirStr = subDir->getLeaf().string();\n        if (!ignore && strstr(dirStr, \"mipmap\") == dirStr) {\n            ignore = true;\n        }\n        status_t err = addResourcesToBuilder(subDir, builder, ignore);\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    const size_t numFiles = dir->getFiles().size();\n    for (size_t i = 0; i < numFiles; i++) {\n        sp<AaptGroup> gp = dir->getFiles().valueAt(i);\n        const size_t numConfigs = gp->getFiles().size();\n        for (size_t j = 0; j < numConfigs; j++) {\n            status_t err = NO_ERROR;\n            if (ignoreConfig) {\n                err = builder->getBaseSplit()->addEntry(gp->getPath(), gp->getFiles().valueAt(j));\n            } else {\n                err = builder->addEntry(gp->getPath(), gp->getFiles().valueAt(j));\n            }\n            // printf(\"add %s (%s) to builder.\\n\",\n            //         gp->getPath().string(), gp->getFiles()[j]->getPrintableSource().string());\n            if (err != NO_ERROR) {\n                fprintf(stderr, \"Failed to add %s (%s) to builder.\\n\",\n                        gp->getPath().string(), gp->getFiles()[j]->getPrintableSource().string());\n                return err;\n            }\n        }\n    }\n    return NO_ERROR;\n}\n\nstatic String8 buildApkName(const String8& original, const sp<ApkSplit>& split) {\n    if (split->isBase()) {\n        return original;\n    }\n\n    String8 ext(original.getPathExtension());\n    if (ext == String8(\".apk\")) {\n        return String8::format(\"%s_%s%s\",\n                original.getBasePath().string(),\n                split->getDirectorySafeName().string(),\n                ext.string());\n    }\n\n    return String8::format(\"%s_%s\", original.string(),\n            split->getDirectorySafeName().string());\n}\n\n/*\n * Package up an asset directory and associated application files.\n */\nint doPackage(Bundle* bundle)\n{\n    const char* outputAPKFile;\n    int retVal = 1;\n    status_t err;\n    sp<AaptAssets> assets;\n    int N;\n    FILE* fp;\n    String8 dependencyFile;\n    sp<ApkBuilder> builder;\n\n    // -c en_XA or/and ar_XB means do pseudolocalization\n    sp<WeakResourceFilter> configFilter = new WeakResourceFilter();\n    err = configFilter->parse(bundle->getConfigurations());\n    if (err != NO_ERROR) {\n        goto bail;\n    }\n    if (configFilter->containsPseudo()) {\n        bundle->setPseudolocalize(bundle->getPseudolocalize() | PSEUDO_ACCENTED);\n    }\n    if (configFilter->containsPseudoBidi()) {\n        bundle->setPseudolocalize(bundle->getPseudolocalize() | PSEUDO_BIDI);\n    }\n\n    N = bundle->getFileSpecCount();\n    if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0\n            && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDirs().size() == 0) {\n        fprintf(stderr, \"ERROR: no input files\\n\");\n        goto bail;\n    }\n\n    outputAPKFile = bundle->getOutputAPKFile();\n\n    // Make sure the filenames provided exist and are of the appropriate type.\n    if (outputAPKFile) {\n        FileType type;\n        type = getFileType(outputAPKFile);\n        if (type != kFileTypeNonexistent && type != kFileTypeRegular) {\n            fprintf(stderr,\n                \"ERROR: output file '%s' exists but is not regular file\\n\",\n                outputAPKFile);\n            goto bail;\n        }\n    }\n\n    // Load the assets.\n    assets = new AaptAssets();\n\n    // Set up the resource gathering in assets if we're going to generate\n    // dependency files. Every time we encounter a resource while slurping\n    // the tree, we'll add it to these stores so we have full resource paths\n    // to write to a dependency file.\n    if (bundle->getGenDependencies()) {\n        sp<FilePathStore> resPathStore = new FilePathStore;\n        assets->setFullResPaths(resPathStore);\n        sp<FilePathStore> assetPathStore = new FilePathStore;\n        assets->setFullAssetPaths(assetPathStore);\n    }\n\n    err = assets->slurpFromArgs(bundle);\n    if (err < 0) {\n        goto bail;\n    }\n\n    if (bundle->getVerbose()) {\n        assets->print(String8());\n    }\n\n    // Create the ApkBuilder, which will collect the compiled files\n    // to write to the final APK (or sets of APKs if we are building\n    // a Split APK.\n    builder = new ApkBuilder(configFilter);\n\n    // If we are generating a Split APK, find out which configurations to split on.\n    if (bundle->getSplitConfigurations().size() > 0) {\n        const Vector<String8>& splitStrs = bundle->getSplitConfigurations();\n        const size_t numSplits = splitStrs.size();\n        for (size_t i = 0; i < numSplits; i++) {\n            std::set<ConfigDescription> configs;\n            if (!AaptConfig::parseCommaSeparatedList(splitStrs[i], &configs)) {\n                fprintf(stderr, \"ERROR: failed to parse split configuration '%s'\\n\", splitStrs[i].string());\n                goto bail;\n            }\n\n            err = builder->createSplitForConfigs(configs);\n            if (err != NO_ERROR) {\n                goto bail;\n            }\n        }\n    }\n\n    // If they asked for any fileAs that need to be compiled, do so.\n    if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) {\n        err = buildResources(bundle, assets, builder);\n        if (err != 0) {\n            goto bail;\n        }\n    }\n\n    // At this point we've read everything and processed everything.  From here\n    // on out it's just writing output files.\n    if (SourcePos::hasErrors()) {\n        goto bail;\n    }\n\n    // Update symbols with information about which ones are needed as Java symbols.\n    assets->applyJavaSymbols();\n    if (SourcePos::hasErrors()) {\n        goto bail;\n    }\n\n    // If we've been asked to generate a dependency file, do that here\n    if (bundle->getGenDependencies()) {\n        // If this is the packaging step, generate the dependency file next to\n        // the output apk (e.g. bin/resources.ap_.d)\n        if (outputAPKFile) {\n            dependencyFile = String8(outputAPKFile);\n            // Add the .d extension to the dependency file.\n            dependencyFile.append(\".d\");\n        } else {\n            // Else if this is the R.java dependency generation step,\n            // generate the dependency file in the R.java package subdirectory\n            // e.g. gen/com/foo/app/R.java.d\n            dependencyFile = String8(bundle->getRClassDir());\n            dependencyFile.appendPath(\"R.java.d\");\n        }\n        // Make sure we have a clean dependency file to start with\n        fp = fopen(dependencyFile, \"w\");\n        fclose(fp);\n    }\n\n    // Write out R.java constants\n    if (!assets->havePrivateSymbols()) {\n        if (bundle->getCustomPackage() == NULL) {\n            // Write the R.java file into the appropriate class directory\n            // e.g. gen/com/foo/app/R.java\n            err = writeResourceSymbols(bundle, assets, assets->getPackage(), true,\n                    bundle->getBuildSharedLibrary());\n        } else {\n            const String8 customPkg(bundle->getCustomPackage());\n            err = writeResourceSymbols(bundle, assets, customPkg, true,\n                    bundle->getBuildSharedLibrary());\n        }\n        if (err < 0 && (sktPackageName != NULL)) {\n            err = writeResourceSymbols(bundle, assets, String8(sktPackageName), true,\n                    bundle->getBuildSharedLibrary());\n        }\n        if (err < 0) {\n            goto bail;\n        }\n        // If we have library files, we're going to write our R.java file into\n        // the appropriate class directory for those libraries as well.\n        // e.g. gen/com/foo/app/lib/R.java\n        if (bundle->getExtraPackages() != NULL) {\n            // Split on colon\n            String8 libs(bundle->getExtraPackages());\n            char* packageString = strtok(libs.lockBuffer(libs.length()), \":\");\n            while (packageString != NULL) {\n                // Write the R.java file out with the correct package name\n                err = writeResourceSymbols(bundle, assets, String8(packageString), true,\n                        bundle->getBuildSharedLibrary());\n                if (err < 0) {\n                    goto bail;\n                }\n                packageString = strtok(NULL, \":\");\n            }\n            libs.unlockBuffer();\n        }\n    } else {\n        err = writeResourceSymbols(bundle, assets, assets->getPackage(), false, false);\n        if (err < 0) {\n            goto bail;\n        }\n        err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true, false);\n        if (err < 0) {\n            goto bail;\n        }\n    }\n\n    // Write out the ProGuard file\n    err = writeProguardFile(bundle, assets);\n    if (err < 0) {\n        goto bail;\n    }\n\n    // Write out the Main Dex ProGuard file\n    err = writeMainDexProguardFile(bundle, assets);\n    if (err < 0) {\n        goto bail;\n    }\n\n    // Write the apk\n    if (outputAPKFile) {\n        // Gather all resources and add them to the APK Builder. The builder will then\n        // figure out which Split they belong in.\n        err = addResourcesToBuilder(assets, builder);\n        if (err != NO_ERROR) {\n            goto bail;\n        }\n\n        const Vector<sp<ApkSplit> >& splits = builder->getSplits();\n        const size_t numSplits = splits.size();\n        for (size_t i = 0; i < numSplits; i++) {\n            const sp<ApkSplit>& split = splits[i];\n            String8 outputPath = buildApkName(String8(outputAPKFile), split);\n            err = writeAPK(bundle, outputPath, split);\n            if (err != NO_ERROR) {\n                fprintf(stderr, \"ERROR: packaging of '%s' failed\\n\", outputPath.string());\n                goto bail;\n            }\n        }\n    }\n\n    // If we've been asked to generate a dependency file, we need to finish up here.\n    // the writeResourceSymbols and writeAPK functions have already written the target\n    // half of the dependency file, now we need to write the prerequisites. (files that\n    // the R.java file or .ap_ file depend on)\n    if (bundle->getGenDependencies()) {\n        // Now that writeResourceSymbols or writeAPK has taken care of writing\n        // the targets to our dependency file, we'll write the prereqs\n        fp = fopen(dependencyFile, \"a+\");\n        fprintf(fp, \" : \");\n        bool includeRaw = (outputAPKFile != NULL);\n        err = writeDependencyPreReqs(bundle, assets, fp, includeRaw);\n        // Also manually add the AndroidManifeset since it's not under res/ or assets/\n        // and therefore was not added to our pathstores during slurping\n        fprintf(fp, \"%s \\\\\\n\", bundle->getAndroidManifestFile());\n        fclose(fp);\n    }\n\n    retVal = 0;\nbail:\n    if (SourcePos::hasErrors()) {\n        SourcePos::printErrors(stderr);\n    }\n    return retVal;\n}\n\n/*\n * Do PNG Crunching\n * PRECONDITIONS\n *  -S flag points to a source directory containing drawable* folders\n *  -C flag points to destination directory. The folder structure in the\n *     source directory will be mirrored to the destination (cache) directory\n *\n * POSTCONDITIONS\n *  Destination directory will be updated to match the PNG files in\n *  the source directory.\n */\nint doCrunch(Bundle* bundle)\n{\n    fprintf(stdout, \"Crunching PNG Files in \");\n    fprintf(stdout, \"source dir: %s\\n\", bundle->getResourceSourceDirs()[0]);\n    fprintf(stdout, \"To destination dir: %s\\n\", bundle->getCrunchedOutputDir());\n\n    updatePreProcessedCache(bundle);\n\n    return NO_ERROR;\n}\n\n/*\n * Do PNG Crunching on a single flag\n *  -i points to a single png file\n *  -o points to a single png output file\n */\nint doSingleCrunch(Bundle* bundle)\n{\n    fprintf(stdout, \"Crunching single PNG file: %s\\n\", bundle->getSingleCrunchInputFile());\n    fprintf(stdout, \"\\tOutput file: %s\\n\", bundle->getSingleCrunchOutputFile());\n\n    String8 input(bundle->getSingleCrunchInputFile());\n    String8 output(bundle->getSingleCrunchOutputFile());\n\n    if (preProcessImageToCache(bundle, input, output) != NO_ERROR) {\n        // we can't return the status_t as it gets truncate to the lower 8 bits.\n        return 42;\n    }\n\n    return NO_ERROR;\n}\n\nint runInDaemonMode(Bundle* bundle) {\n    std::cout << \"Ready\" << std::endl;\n    for (std::string line; std::getline(std::cin, line);) {\n        if (line == \"quit\") {\n            return NO_ERROR;\n        }\n        std::stringstream ss;\n        ss << line;\n        std::string s;\n\n        std::string command, parameterOne, parameterTwo;\n        std::getline(ss, command, ' ');\n        std::getline(ss, parameterOne, ' ');\n        std::getline(ss, parameterTwo, ' ');\n        if (command[0] == 's') {\n            bundle->setSingleCrunchInputFile(parameterOne.c_str());\n            bundle->setSingleCrunchOutputFile(parameterTwo.c_str());\n            std::cout << \"Crunching \" << parameterOne << std::endl;\n            if (doSingleCrunch(bundle) != NO_ERROR) {\n                std::cout << \"Error\" << std::endl;\n            }\n            std::cout << \"Done\" << std::endl;\n        } else {\n            // in case of invalid command, just bail out.\n            std::cerr << \"Unknown command\" << std::endl;\n            return -1;\n        }\n    }\n    return -1;\n}\n\nchar CONSOLE_DATA[2925] = {\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63,\n    86, 35, 40, 46, 46, 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83,\n    62, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 46, 58, 59, 61, 59, 61, 81,\n    81, 81, 81, 66, 96, 61, 61, 58, 46, 46, 46, 58, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81, 81, 81, 102, 59, 61, 59,\n    59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59,\n    59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59, 46, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87,\n    58, 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46,\n    47, 61, 59, 59, 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58,\n    121, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81,\n    81, 81, 81, 109, 58, 59, 59, 59, 59, 61, 109, 81, 81, 76, 46, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81, 81, 81, 81, 81, 59, 61, 59,\n    59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 60, 81, 91, 59,\n    59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81, 81, 76, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81,\n    70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 93, 40, 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81,\n    81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 46, 46, 46, 32, 46, 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109,\n    81, 81, 81, 87, 46, 58, 61, 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,\n    32, 32, 32, 32, 32, 32, 32, 46, 46, 61, 59, 61, 61, 61, 59, 61, 61, 59,\n    59, 59, 58, 58, 46, 46, 41, 58, 59, 58, 81, 81, 81, 81, 69, 58, 59, 59,\n    60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 58, 59,\n    61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 46,\n    61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68, 96, 32, 32, 32,\n    46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59,\n    59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36, 81,\n    109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81,\n    67, 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,\n    59, 59, 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58,\n    61, 59, 59, 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59,\n    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37,\n    73, 108, 108, 62, 52, 81, 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59,\n    59, 61, 59, 61, 61, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10,\n    32, 46, 45, 57, 101, 43, 43, 61, 61, 59, 59, 59, 59, 59, 59, 61, 59, 59,\n    59, 59, 59, 59, 59, 59, 59, 58, 97, 46, 61, 108, 62, 126, 58, 106, 80, 96,\n    46, 61, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61,\n    97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 45, 46, 32,\n    46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 58, 59, 59, 59, 59, 61,\n    119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61, 58, 59, 59, 59,\n    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81, 99, 32, 32,\n    32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119,\n    119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59,\n    59, 59, 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 61, 58, 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81,\n    81, 58, 59, 59, 59, 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41,\n    87, 66, 33, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81,\n    81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58,\n    45, 32, 46, 32, 32, 32, 32, 32, 46, 32, 126, 96, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81,\n    81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58,\n    59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58,\n    59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81,\n    81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,\n    81, 81, 40, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106,\n    81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59,\n    32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 61, 58, 58, 81, 81, 81, 81, 81, 81, 81, 81,\n    81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 59,\n    61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81, 81,\n    81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81,\n    81, 102, 94, 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59,\n    59, 59, 43, 63, 36, 81, 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59,\n    59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 43, 33,\n    58, 126, 126, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46,\n    61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61, 59, 59, 59, 59, 59,\n    59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 58, 95,\n    32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59, 59,\n    61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45,\n    59, 58, 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59,\n    59, 59, 59, 59, 59, 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59,\n    59, 59, 59, 59, 59, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 45, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 58, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 61,\n    46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59,\n    59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59, 59, 59,\n    59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32,\n    32, 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61,\n    59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59,\n    59, 59, 59, 58, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 61, 59, 58, 45, 45, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10\n  };\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/ConfigDescription.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __CONFIG_DESCRIPTION_H\n#define __CONFIG_DESCRIPTION_H\n\n#include <androidfw/ResourceTypes.h>\n\n/**\n * Subclass of ResTable_config that adds convenient\n * initialization and comparison methods.\n */\nstruct ConfigDescription : public android::ResTable_config {\n    ConfigDescription() {\n        memset(this, 0, sizeof(*this));\n        size = sizeof(android::ResTable_config);\n    }\n    ConfigDescription(const android::ResTable_config&o) {\n        *static_cast<android::ResTable_config*>(this) = o;\n        size = sizeof(android::ResTable_config);\n    }\n    ConfigDescription(const ConfigDescription&o) {\n        *static_cast<android::ResTable_config*>(this) = o;\n    }\n\n    ConfigDescription& operator=(const android::ResTable_config& o) {\n        *static_cast<android::ResTable_config*>(this) = o;\n        size = sizeof(android::ResTable_config);\n        return *this;\n    }\n    ConfigDescription& operator=(const ConfigDescription& o) {\n        *static_cast<android::ResTable_config*>(this) = o;\n        return *this;\n    }\n\n    inline bool operator<(const ConfigDescription& o) const { return compare(o) < 0; }\n    inline bool operator<=(const ConfigDescription& o) const { return compare(o) <= 0; }\n    inline bool operator==(const ConfigDescription& o) const { return compare(o) == 0; }\n    inline bool operator!=(const ConfigDescription& o) const { return compare(o) != 0; }\n    inline bool operator>=(const ConfigDescription& o) const { return compare(o) >= 0; }\n    inline bool operator>(const ConfigDescription& o) const { return compare(o) > 0; }\n};\n\n#endif // __CONFIG_DESCRIPTION_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/CrunchCache.cpp",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n// Implementation file for CrunchCache\n// This file defines functions laid out and documented in\n// CrunchCache.h\n\n#include <utils/Vector.h>\n#include <utils/String8.h>\n\n#include \"DirectoryWalker.h\"\n#include \"FileFinder.h\"\n#include \"CacheUpdater.h\"\n#include \"CrunchCache.h\"\n\nusing namespace android;\n\nCrunchCache::CrunchCache(String8 sourcePath, String8 destPath, FileFinder* ff)\n    : mSourcePath(sourcePath), mDestPath(destPath), mSourceFiles(0), mDestFiles(0), mFileFinder(ff)\n{\n    // We initialize the default value to return to 0 so if a file doesn't exist\n    // then all files are automatically \"newer\" than it.\n\n    // Set file extensions to look for. Right now just pngs.\n    mExtensions.push(String8(\".png\"));\n\n    // Load files into our data members\n    loadFiles();\n}\n\nsize_t CrunchCache::crunch(CacheUpdater* cu, bool forceOverwrite)\n{\n    size_t numFilesUpdated = 0;\n\n    // Iterate through the source files and compare to cache.\n    // After processing a file, remove it from the source files and\n    // from the dest files.\n    // We're done when we're out of files in source.\n    String8 relativePath;\n    while (mSourceFiles.size() > 0) {\n        // Get the full path to the source file, then convert to a c-string\n        // and offset our beginning pointer to the length of the sourcePath\n        // This efficiently strips the source directory prefix from our path.\n        // Also, String8 doesn't have a substring method so this is what we've\n        // got to work with.\n        const char* rPathPtr = mSourceFiles.keyAt(0).string()+mSourcePath.length();\n        // Strip leading slash if present\n        int offset = 0;\n        if (rPathPtr[0] == OS_PATH_SEPARATOR)\n            offset = 1;\n        relativePath = String8(rPathPtr + offset);\n\n        if (forceOverwrite || needsUpdating(relativePath)) {\n            cu->processImage(mSourcePath.appendPathCopy(relativePath),\n                             mDestPath.appendPathCopy(relativePath));\n            numFilesUpdated++;\n            // crunchFile(relativePath);\n        }\n        // Delete this file from the source files and (if it exists) from the\n        // dest files.\n        mSourceFiles.removeItemsAt(0);\n        mDestFiles.removeItem(mDestPath.appendPathCopy(relativePath));\n    }\n\n    // Iterate through what's left of destFiles and delete leftovers\n    while (mDestFiles.size() > 0) {\n        cu->deleteFile(mDestFiles.keyAt(0));\n        mDestFiles.removeItemsAt(0);\n    }\n\n    // Update our knowledge of the files cache\n    // both source and dest should be empty by now.\n    loadFiles();\n\n    return numFilesUpdated;\n}\n\nvoid CrunchCache::loadFiles()\n{\n    // Clear out our data structures to avoid putting in duplicates\n    mSourceFiles.clear();\n    mDestFiles.clear();\n\n    // Make a directory walker that points to the system.\n    DirectoryWalker* dw = new SystemDirectoryWalker();\n\n    // Load files in the source directory\n    mFileFinder->findFiles(mSourcePath, mExtensions, mSourceFiles,dw);\n\n    // Load files in the destination directory\n    mFileFinder->findFiles(mDestPath,mExtensions,mDestFiles,dw);\n\n    delete dw;\n}\n\nbool CrunchCache::needsUpdating(String8 relativePath) const\n{\n    // Retrieve modification dates for this file entry under the source and\n    // cache directory trees. The vectors will return a modification date of 0\n    // if the file doesn't exist.\n    time_t sourceDate = mSourceFiles.valueFor(mSourcePath.appendPathCopy(relativePath));\n    time_t destDate = mDestFiles.valueFor(mDestPath.appendPathCopy(relativePath));\n    return sourceDate > destDate;\n}"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/CrunchCache.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n// Cache manager for pre-processed PNG files.\n// Contains code for managing which PNG files get processed\n// at build time.\n//\n\n#ifndef CRUNCHCACHE_H\n#define CRUNCHCACHE_H\n\n#include <utils/KeyedVector.h>\n#include <utils/String8.h>\n#include \"FileFinder.h\"\n#include \"CacheUpdater.h\"\n\nusing namespace android;\n\n/** CrunchCache\n *  This class is a cache manager which can pre-process PNG files and store\n *  them in a mirror-cache. It's capable of doing incremental updates to its\n *  cache.\n *\n *  Usage:\n *      Create an instance initialized with the root of the source tree, the\n *      root location to store the cache files, and an instance of a file finder.\n *      Then update the cache by calling crunch.\n */\nclass CrunchCache {\npublic:\n    // Constructor\n    CrunchCache(String8 sourcePath, String8 destPath, FileFinder* ff);\n\n    // Nobody should be calling the default constructor\n    // So this space is intentionally left blank\n\n    // Default Copy Constructor and Destructor are fine\n\n    /** crunch is the workhorse of this class.\n     * It goes through all the files found in the sourcePath and compares\n     * them to the cached versions in the destPath. If the optional\n     * argument forceOverwrite is set to true, then all source files are\n     * re-crunched even if they have not been modified recently. Otherwise,\n     * source files are only crunched when they needUpdating. Afterwards,\n     * we delete any leftover files in the cache that are no longer present\n     * in source.\n     *\n     * PRECONDITIONS:\n     *      No setup besides construction is needed\n     * POSTCONDITIONS:\n     *      The cache is updated to fully reflect all changes in source.\n     *      The function then returns the number of files changed in cache\n     *      (counting deletions).\n     */\n    size_t crunch(CacheUpdater* cu, bool forceOverwrite=false);\n\nprivate:\n    /** loadFiles is a wrapper to the FileFinder that places matching\n     * files into mSourceFiles and mDestFiles.\n     *\n     *  POSTCONDITIONS\n     *      mDestFiles and mSourceFiles are refreshed to reflect the current\n     *      state of the files in the source and dest directories.\n     *      Any previous contents of mSourceFiles and mDestFiles are cleared.\n     */\n    void loadFiles();\n\n    /** needsUpdating takes a file path\n     * and returns true if the file represented by this path is newer in the\n     * sourceFiles than in the cache (mDestFiles).\n     *\n     * PRECONDITIONS:\n     *      mSourceFiles and mDestFiles must be initialized and filled.\n     * POSTCONDITIONS:\n     *      returns true if and only if source file's modification time\n     *      is greater than the cached file's mod-time. Otherwise returns false.\n     *\n     * USAGE:\n     *      Should be used something like the following:\n     *      if (needsUpdating(filePath))\n     *          // Recrunch sourceFile out to destFile.\n     *\n     */\n    bool needsUpdating(String8 relativePath) const;\n\n    // DATA MEMBERS ====================================================\n\n    String8 mSourcePath;\n    String8 mDestPath;\n\n    Vector<String8> mExtensions;\n\n    // Each vector of paths contains one entry per PNG file encountered.\n    // Each entry consists of a path pointing to that PNG.\n    DefaultKeyedVector<String8,time_t> mSourceFiles;\n    DefaultKeyedVector<String8,time_t> mDestFiles;\n\n    // Pointer to a FileFinder to use\n    FileFinder* mFileFinder;\n};\n\n#endif // CRUNCHCACHE_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/DirectoryWalker.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n// Defines an abstraction for opening a directory on the filesystem and\n// iterating through it.\n\n#ifndef DIRECTORYWALKER_H\n#define DIRECTORYWALKER_H\n\n#include <dirent.h>\n#include <sys/types.h>\n#include <sys/param.h>\n#include <sys/stat.h>\n#include <unistd.h>\n#include <utils/String8.h>\n\n#include <stdio.h>\n\nusing namespace android;\n\n// Directory Walker\n// This is an abstraction for walking through a directory and getting files\n// and descriptions.\n\nclass DirectoryWalker {\npublic:\n    virtual ~DirectoryWalker() {};\n    virtual bool openDir(String8 path) = 0;\n    virtual bool openDir(const char* path) = 0;\n    // Advance to next directory entry\n    virtual struct dirent* nextEntry() = 0;\n    // Get the stats for the current entry\n    virtual struct stat*   entryStats() = 0;\n    // Clean Up\n    virtual void closeDir() = 0;\n    // This class is able to replicate itself on the heap\n    virtual DirectoryWalker* clone() = 0;\n\n    // DATA MEMBERS\n    // Current directory entry\n    struct dirent mEntry;\n    // Stats for that directory entry\n    struct stat mStats;\n    // Base path\n    String8 mBasePath;\n};\n\n// System Directory Walker\n// This is an implementation of the above abstraction that calls\n// real system calls and is fully functional.\n// functions are inlined since they're very short and simple\n\nclass SystemDirectoryWalker : public DirectoryWalker {\n\n    // Default constructor, copy constructor, and destructor are fine\npublic:\n    virtual bool openDir(String8 path) {\n        mBasePath = path;\n        dir = NULL;\n        dir = opendir(mBasePath.string() );\n\n        if (dir == NULL)\n            return false;\n\n        return true;\n    };\n    virtual bool openDir(const char* path) {\n        String8 p(path);\n        openDir(p);\n        return true;\n    };\n    // Advance to next directory entry\n    virtual struct dirent* nextEntry() {\n        struct dirent* entryPtr = readdir(dir);\n        if (entryPtr == NULL)\n            return NULL;\n\n        mEntry = *entryPtr;\n        // Get stats\n        String8 fullPath = mBasePath.appendPathCopy(mEntry.d_name);\n        stat(fullPath.string(),&mStats);\n        return &mEntry;\n    };\n    // Get the stats for the current entry\n    virtual struct stat*   entryStats() {\n        return &mStats;\n    };\n    virtual void closeDir() {\n        closedir(dir);\n    };\n    virtual DirectoryWalker* clone() {\n        return new SystemDirectoryWalker(*this);\n    };\nprivate:\n    DIR* dir;\n};\n\n#endif // DIRECTORYWALKER_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/FileFinder.cpp",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n\n// File Finder implementation.\n// Implementation for the functions declared and documented in FileFinder.h\n\n#include <utils/Vector.h>\n#include <utils/String8.h>\n#include <utils/KeyedVector.h>\n\n#include <dirent.h>\n#include <sys/stat.h>\n\n#include \"DirectoryWalker.h\"\n#include \"FileFinder.h\"\n\n//#define DEBUG\n\nusing android::String8;\n\n// Private function to check whether a file is a directory or not\nbool isDirectory(const char* filename) {\n    struct stat fileStat;\n    if (stat(filename, &fileStat) == -1) {\n        return false;\n    }\n    return(S_ISDIR(fileStat.st_mode));\n}\n\n\n// Private function to check whether a file is a regular file or not\nbool isFile(const char* filename) {\n    struct stat fileStat;\n    if (stat(filename, &fileStat) == -1) {\n        return false;\n    }\n    return(S_ISREG(fileStat.st_mode));\n}\n\nbool SystemFileFinder::findFiles(String8 basePath, Vector<String8>& extensions,\n                                 KeyedVector<String8,time_t>& fileStore,\n                                 DirectoryWalker* dw)\n{\n    // Scan the directory pointed to by basePath\n    // check files and recurse into subdirectories.\n    if (!dw->openDir(basePath)) {\n        return false;\n    }\n    /*\n     *  Go through all directory entries. Check each file using checkAndAddFile\n     *  and recurse into sub-directories.\n     */\n    struct dirent* entry;\n    while ((entry = dw->nextEntry()) != NULL) {\n        String8 entryName(entry->d_name);\n        if (entry->d_name[0] == '.') // Skip hidden files and directories\n            continue;\n\n        String8 fullPath = basePath.appendPathCopy(entryName);\n        // If this entry is a directory we'll recurse into it\n        if (isDirectory(fullPath.string()) ) {\n            DirectoryWalker* copy = dw->clone();\n            findFiles(fullPath, extensions, fileStore,copy);\n            delete copy;\n        }\n\n        // If this entry is a file, we'll pass it over to checkAndAddFile\n        if (isFile(fullPath.string()) ) {\n            checkAndAddFile(fullPath,dw->entryStats(),extensions,fileStore);\n        }\n    }\n\n    // Clean up\n    dw->closeDir();\n\n    return true;\n}\n\nvoid SystemFileFinder::checkAndAddFile(String8 path, const struct stat* stats,\n                                       Vector<String8>& extensions,\n                                       KeyedVector<String8,time_t>& fileStore)\n{\n    // Loop over the extensions, checking for a match\n    bool done = false;\n    String8 ext(path.getPathExtension());\n    ext.toLower();\n    for (size_t i = 0; i < extensions.size() && !done; ++i) {\n        String8 ext2 = extensions[i].getPathExtension();\n        ext2.toLower();\n        // Compare the extensions. If a match is found, add to storage.\n        if (ext == ext2) {\n            done = true;\n            fileStore.add(path,stats->st_mtime);\n        }\n    }\n}\n\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/FileFinder.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n\n// File Finder.\n// This is a collection of useful functions for finding paths and modification\n// times of files that match an extension pattern in a directory tree.\n// and finding files in it.\n\n#ifndef FILEFINDER_H\n#define FILEFINDER_H\n\n#include <utils/Vector.h>\n#include <utils/KeyedVector.h>\n#include <utils/String8.h>\n\n#include \"DirectoryWalker.h\"\n\nusing namespace android;\n\n// Abstraction to allow for dependency injection. See MockFileFinder.h\n// for the testing implementation.\nclass FileFinder {\npublic:\n    virtual bool findFiles(String8 basePath, Vector<String8>& extensions,\n                           KeyedVector<String8,time_t>& fileStore,\n                           DirectoryWalker* dw) = 0;\n\n    virtual ~FileFinder() {};\n};\n\nclass SystemFileFinder : public FileFinder {\npublic:\n\n    /* findFiles takes a path, a Vector of extensions, and a destination KeyedVector\n     *           and places path/modification date key/values pointing to\n     *          all files with matching extensions found into the KeyedVector\n     * PRECONDITIONS\n     *     path is a valid system path\n     *     extensions should include leading \".\"\n     *                This is not necessary, but the comparison directly\n     *                compares the end of the path string so if the \".\"\n     *                is excluded there is a small chance you could have\n     *                a false positive match. (For example: extension \"png\"\n     *                would match a file called \"blahblahpng\")\n     *\n     * POSTCONDITIONS\n     *     fileStore contains (in no guaranteed order) paths to all\n     *                matching files encountered in subdirectories of path\n     *                as keys in the KeyedVector. Each key has the modification time\n     *                of the file as its value.\n     *\n     * Calls checkAndAddFile on each file encountered in the directory tree\n     * Recursively descends into subdirectories.\n     */\n    virtual bool findFiles(String8 basePath, Vector<String8>& extensions,\n                           KeyedVector<String8,time_t>& fileStore,\n                           DirectoryWalker* dw);\n\nprivate:\n    /**\n     * checkAndAddFile looks at a single file path and stat combo\n     * to determine whether it is a matching file (by looking at\n     * the extension)\n     *\n     * PRECONDITIONS\n     *    no setup is needed\n     *\n     * POSTCONDITIONS\n     *    If the given file has a matching extension then a new entry\n     *    is added to the KeyedVector with the path as the key and the modification\n     *    time as the value.\n     *\n     */\n    static void checkAndAddFile(String8 path, const struct stat* stats,\n                                Vector<String8>& extensions,\n                                KeyedVector<String8,time_t>& fileStore);\n\n};\n#endif // FILEFINDER_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/Images.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#define PNG_INTERNAL\n\n#include \"Images.h\"\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/ByteOrder.h>\n\n#include <png.h>\n#include <zlib.h>\n\n#define NOISY(x) //x\n\nstatic void\npng_write_aapt_file(png_structp png_ptr, png_bytep data, png_size_t length)\n{\n    AaptFile* aaptfile = (AaptFile*) png_get_io_ptr(png_ptr);\n    status_t err = aaptfile->writeData(data, length);\n    if (err != NO_ERROR) {\n        png_error(png_ptr, \"Write Error\");\n    }\n}\n\n\nstatic void\npng_flush_aapt_file(png_structp png_ptr)\n{\n}\n\n// This holds an image as 8bpp RGBA.\nstruct image_info\n{\n    image_info() : rows(NULL), is9Patch(false),\n        xDivs(NULL), yDivs(NULL), colors(NULL), allocRows(NULL) { }\n\n    ~image_info() {\n        if (rows && rows != allocRows) {\n            free(rows);\n        }\n        if (allocRows) {\n            for (int i=0; i<(int)allocHeight; i++) {\n                free(allocRows[i]);\n            }\n            free(allocRows);\n        }\n        free(xDivs);\n        free(yDivs);\n        free(colors);\n    }\n\n    void* serialize9patch() {\n        void* serialized = Res_png_9patch::serialize(info9Patch, xDivs, yDivs, colors);\n        reinterpret_cast<Res_png_9patch*>(serialized)->deviceToFile();\n        return serialized;\n    }\n\n    png_uint_32 width;\n    png_uint_32 height;\n    png_bytepp rows;\n\n    // 9-patch info.\n    bool is9Patch;\n    Res_png_9patch info9Patch;\n    int32_t* xDivs;\n    int32_t* yDivs;\n    uint32_t* colors;\n\n    // Layout padding, if relevant\n    bool haveLayoutBounds;\n    int32_t layoutBoundsLeft;\n    int32_t layoutBoundsTop;\n    int32_t layoutBoundsRight;\n    int32_t layoutBoundsBottom;\n\n    // Round rect outline description\n    int32_t outlineInsetsLeft;\n    int32_t outlineInsetsTop;\n    int32_t outlineInsetsRight;\n    int32_t outlineInsetsBottom;\n    float outlineRadius;\n    uint8_t outlineAlpha;\n\n    png_uint_32 allocHeight;\n    png_bytepp allocRows;\n};\n\nstatic void log_warning(png_structp png_ptr, png_const_charp warning_message)\n{\n    const char* imageName = (const char*) png_get_error_ptr(png_ptr);\n    fprintf(stderr, \"%s: libpng warning: %s\\n\", imageName, warning_message);\n}\n\nstatic void read_png(const char* imageName,\n                     png_structp read_ptr, png_infop read_info,\n                     image_info* outImageInfo)\n{\n    int color_type;\n    int bit_depth, interlace_type, compression_type;\n    int i;\n\n    png_set_error_fn(read_ptr, const_cast<char*>(imageName),\n            NULL /* use default errorfn */, log_warning);\n    png_read_info(read_ptr, read_info);\n\n    png_get_IHDR(read_ptr, read_info, &outImageInfo->width,\n       &outImageInfo->height, &bit_depth, &color_type,\n       &interlace_type, &compression_type, NULL);\n\n    //printf(\"Image %s:\\n\", imageName);\n    //printf(\"color_type=%d, bit_depth=%d, interlace_type=%d, compression_type=%d\\n\",\n    //       color_type, bit_depth, interlace_type, compression_type);\n\n    if (color_type == PNG_COLOR_TYPE_PALETTE)\n        png_set_palette_to_rgb(read_ptr);\n\n    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)\n        png_set_expand_gray_1_2_4_to_8(read_ptr);\n\n    if (png_get_valid(read_ptr, read_info, PNG_INFO_tRNS)) {\n        //printf(\"Has PNG_INFO_tRNS!\\n\");\n        png_set_tRNS_to_alpha(read_ptr);\n    }\n\n    if (bit_depth == 16)\n        png_set_strip_16(read_ptr);\n\n    if ((color_type&PNG_COLOR_MASK_ALPHA) == 0)\n        png_set_add_alpha(read_ptr, 0xFF, PNG_FILLER_AFTER);\n\n    if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n        png_set_gray_to_rgb(read_ptr);\n\n    png_set_interlace_handling(read_ptr);\n\n    png_read_update_info(read_ptr, read_info);\n\n    outImageInfo->rows = (png_bytepp)malloc(\n        outImageInfo->height * sizeof(png_bytep));\n    outImageInfo->allocHeight = outImageInfo->height;\n    outImageInfo->allocRows = outImageInfo->rows;\n\n    png_set_rows(read_ptr, read_info, outImageInfo->rows);\n\n    for (i = 0; i < (int)outImageInfo->height; i++)\n    {\n        outImageInfo->rows[i] = (png_bytep)\n            malloc(png_get_rowbytes(read_ptr, read_info));\n    }\n\n    png_read_image(read_ptr, outImageInfo->rows);\n\n    png_read_end(read_ptr, read_info);\n\n    NOISY(printf(\"Image %s: w=%d, h=%d, d=%d, colors=%d, inter=%d, comp=%d\\n\",\n                 imageName,\n                 (int)outImageInfo->width, (int)outImageInfo->height,\n                 bit_depth, color_type,\n                 interlace_type, compression_type));\n\n    png_get_IHDR(read_ptr, read_info, &outImageInfo->width,\n       &outImageInfo->height, &bit_depth, &color_type,\n       &interlace_type, &compression_type, NULL);\n}\n\n#define COLOR_TRANSPARENT 0\n#define COLOR_WHITE 0xFFFFFFFF\n#define COLOR_TICK  0xFF000000\n#define COLOR_LAYOUT_BOUNDS_TICK 0xFF0000FF\n\nenum {\n    TICK_TYPE_NONE,\n    TICK_TYPE_TICK,\n    TICK_TYPE_LAYOUT_BOUNDS,\n    TICK_TYPE_BOTH\n};\n\nstatic int tick_type(png_bytep p, bool transparent, const char** outError)\n{\n    png_uint_32 color = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);\n\n    if (transparent) {\n        if (p[3] == 0) {\n            return TICK_TYPE_NONE;\n        }\n        if (color == COLOR_LAYOUT_BOUNDS_TICK) {\n            return TICK_TYPE_LAYOUT_BOUNDS;\n        }\n        if (color == COLOR_TICK) {\n            return TICK_TYPE_TICK;\n        }\n\n        // Error cases\n        if (p[3] != 0xff) {\n            *outError = \"Frame pixels must be either solid or transparent (not intermediate alphas)\";\n            return TICK_TYPE_NONE;\n        }\n        if (p[0] != 0 || p[1] != 0 || p[2] != 0) {\n            *outError = \"Ticks in transparent frame must be black or red\";\n        }\n        return TICK_TYPE_TICK;\n    }\n\n    if (p[3] != 0xFF) {\n        *outError = \"White frame must be a solid color (no alpha)\";\n    }\n    if (color == COLOR_WHITE) {\n        return TICK_TYPE_NONE;\n    }\n    if (color == COLOR_TICK) {\n        return TICK_TYPE_TICK;\n    }\n    if (color == COLOR_LAYOUT_BOUNDS_TICK) {\n        return TICK_TYPE_LAYOUT_BOUNDS;\n    }\n\n    if (p[0] != 0 || p[1] != 0 || p[2] != 0) {\n        *outError = \"Ticks in white frame must be black or red\";\n        return TICK_TYPE_NONE;\n    }\n    return TICK_TYPE_TICK;\n}\n\nenum {\n    TICK_START,\n    TICK_INSIDE_1,\n    TICK_OUTSIDE_1\n};\n\nstatic status_t get_horizontal_ticks(\n        png_bytep row, int width, bool transparent, bool required,\n        int32_t* outLeft, int32_t* outRight, const char** outError,\n        uint8_t* outDivs, bool multipleAllowed)\n{\n    int i;\n    *outLeft = *outRight = -1;\n    int state = TICK_START;\n    bool found = false;\n\n    for (i=1; i<width-1; i++) {\n        if (TICK_TYPE_TICK == tick_type(row+i*4, transparent, outError)) {\n            if (state == TICK_START ||\n                (state == TICK_OUTSIDE_1 && multipleAllowed)) {\n                *outLeft = i-1;\n                *outRight = width-2;\n                found = true;\n                if (outDivs != NULL) {\n                    *outDivs += 2;\n                }\n                state = TICK_INSIDE_1;\n            } else if (state == TICK_OUTSIDE_1) {\n                *outError = \"Can't have more than one marked region along edge\";\n                *outLeft = i;\n                return UNKNOWN_ERROR;\n            }\n        } else if (*outError == NULL) {\n            if (state == TICK_INSIDE_1) {\n                // We're done with this div.  Move on to the next.\n                *outRight = i-1;\n                outRight += 2;\n                outLeft += 2;\n                state = TICK_OUTSIDE_1;\n            }\n        } else {\n            *outLeft = i;\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    if (required && !found) {\n        *outError = \"No marked region found along edge\";\n        *outLeft = -1;\n        return UNKNOWN_ERROR;\n    }\n\n    return NO_ERROR;\n}\n\nstatic status_t get_vertical_ticks(\n        png_bytepp rows, int offset, int height, bool transparent, bool required,\n        int32_t* outTop, int32_t* outBottom, const char** outError,\n        uint8_t* outDivs, bool multipleAllowed)\n{\n    int i;\n    *outTop = *outBottom = -1;\n    int state = TICK_START;\n    bool found = false;\n\n    for (i=1; i<height-1; i++) {\n        if (TICK_TYPE_TICK == tick_type(rows[i]+offset, transparent, outError)) {\n            if (state == TICK_START ||\n                (state == TICK_OUTSIDE_1 && multipleAllowed)) {\n                *outTop = i-1;\n                *outBottom = height-2;\n                found = true;\n                if (outDivs != NULL) {\n                    *outDivs += 2;\n                }\n                state = TICK_INSIDE_1;\n            } else if (state == TICK_OUTSIDE_1) {\n                *outError = \"Can't have more than one marked region along edge\";\n                *outTop = i;\n                return UNKNOWN_ERROR;\n            }\n        } else if (*outError == NULL) {\n            if (state == TICK_INSIDE_1) {\n                // We're done with this div.  Move on to the next.\n                *outBottom = i-1;\n                outTop += 2;\n                outBottom += 2;\n                state = TICK_OUTSIDE_1;\n            }\n        } else {\n            *outTop = i;\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    if (required && !found) {\n        *outError = \"No marked region found along edge\";\n        *outTop = -1;\n        return UNKNOWN_ERROR;\n    }\n\n    return NO_ERROR;\n}\n\nstatic status_t get_horizontal_layout_bounds_ticks(\n        png_bytep row, int width, bool transparent, bool required,\n        int32_t* outLeft, int32_t* outRight, const char** outError)\n{\n    int i;\n    *outLeft = *outRight = 0;\n\n    // Look for left tick\n    if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(row + 4, transparent, outError)) {\n        // Starting with a layout padding tick\n        i = 1;\n        while (i < width - 1) {\n            (*outLeft)++;\n            i++;\n            int tick = tick_type(row + i * 4, transparent, outError);\n            if (tick != TICK_TYPE_LAYOUT_BOUNDS) {\n                break;\n            }\n        }\n    }\n\n    // Look for right tick\n    if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(row + (width - 2) * 4, transparent, outError)) {\n        // Ending with a layout padding tick\n        i = width - 2;\n        while (i > 1) {\n            (*outRight)++;\n            i--;\n            int tick = tick_type(row+i*4, transparent, outError);\n            if (tick != TICK_TYPE_LAYOUT_BOUNDS) {\n                break;\n            }\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatic status_t get_vertical_layout_bounds_ticks(\n        png_bytepp rows, int offset, int height, bool transparent, bool required,\n        int32_t* outTop, int32_t* outBottom, const char** outError)\n{\n    int i;\n    *outTop = *outBottom = 0;\n\n    // Look for top tick\n    if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(rows[1] + offset, transparent, outError)) {\n        // Starting with a layout padding tick\n        i = 1;\n        while (i < height - 1) {\n            (*outTop)++;\n            i++;\n            int tick = tick_type(rows[i] + offset, transparent, outError);\n            if (tick != TICK_TYPE_LAYOUT_BOUNDS) {\n                break;\n            }\n        }\n    }\n\n    // Look for bottom tick\n    if (TICK_TYPE_LAYOUT_BOUNDS == tick_type(rows[height - 2] + offset, transparent, outError)) {\n        // Ending with a layout padding tick\n        i = height - 2;\n        while (i > 1) {\n            (*outBottom)++;\n            i--;\n            int tick = tick_type(rows[i] + offset, transparent, outError);\n            if (tick != TICK_TYPE_LAYOUT_BOUNDS) {\n                break;\n            }\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatic void find_max_opacity(png_byte** rows,\n                             int startX, int startY, int endX, int endY, int dX, int dY,\n                             int* out_inset)\n{\n    bool opaque_within_inset = true;\n    uint8_t max_opacity = 0;\n    int inset = 0;\n    *out_inset = 0;\n    for (int x = startX, y = startY; x != endX && y != endY; x += dX, y += dY, inset++) {\n        png_byte* color = rows[y] + x * 4;\n        uint8_t opacity = color[3];\n        if (opacity > max_opacity) {\n            max_opacity = opacity;\n            *out_inset = inset;\n        }\n        if (opacity == 0xff) return;\n    }\n}\n\nstatic uint8_t max_alpha_over_row(png_byte* row, int startX, int endX)\n{\n    uint8_t max_alpha = 0;\n    for (int x = startX; x < endX; x++) {\n        uint8_t alpha = (row + x * 4)[3];\n        if (alpha > max_alpha) max_alpha = alpha;\n    }\n    return max_alpha;\n}\n\nstatic uint8_t max_alpha_over_col(png_byte** rows, int offsetX, int startY, int endY)\n{\n    uint8_t max_alpha = 0;\n    for (int y = startY; y < endY; y++) {\n        uint8_t alpha = (rows[y] + offsetX * 4)[3];\n        if (alpha > max_alpha) max_alpha = alpha;\n    }\n    return max_alpha;\n}\n\nstatic void get_outline(image_info* image)\n{\n    int midX = image->width / 2;\n    int midY = image->height / 2;\n    int endX = image->width - 2;\n    int endY = image->height - 2;\n\n    // find left and right extent of nine patch content on center row\n    if (image->width > 4) {\n        find_max_opacity(image->rows, 1, midY, midX, -1, 1, 0, &image->outlineInsetsLeft);\n        find_max_opacity(image->rows, endX, midY, midX, -1, -1, 0, &image->outlineInsetsRight);\n    } else {\n        image->outlineInsetsLeft = 0;\n        image->outlineInsetsRight = 0;\n    }\n\n    // find top and bottom extent of nine patch content on center column\n    if (image->height > 4) {\n        find_max_opacity(image->rows, midX, 1, -1, midY, 0, 1, &image->outlineInsetsTop);\n        find_max_opacity(image->rows, midX, endY, -1, midY, 0, -1, &image->outlineInsetsBottom);\n    } else {\n        image->outlineInsetsTop = 0;\n        image->outlineInsetsBottom = 0;\n    }\n\n    int innerStartX = 1 + image->outlineInsetsLeft;\n    int innerStartY = 1 + image->outlineInsetsTop;\n    int innerEndX = endX - image->outlineInsetsRight;\n    int innerEndY = endY - image->outlineInsetsBottom;\n    int innerMidX = (innerEndX + innerStartX) / 2;\n    int innerMidY = (innerEndY + innerStartY) / 2;\n\n    // assuming the image is a round rect, compute the radius by marching\n    // diagonally from the top left corner towards the center\n    image->outlineAlpha = max(max_alpha_over_row(image->rows[innerMidY], innerStartX, innerEndX),\n            max_alpha_over_col(image->rows, innerMidX, innerStartY, innerStartY));\n\n    int diagonalInset = 0;\n    find_max_opacity(image->rows, innerStartX, innerStartY, innerMidX, innerMidY, 1, 1,\n            &diagonalInset);\n\n    /* Determine source radius based upon inset:\n     *     sqrt(r^2 + r^2) = sqrt(i^2 + i^2) + r\n     *     sqrt(2) * r = sqrt(2) * i + r\n     *     (sqrt(2) - 1) * r = sqrt(2) * i\n     *     r = sqrt(2) / (sqrt(2) - 1) * i\n     */\n    image->outlineRadius = 3.4142f * diagonalInset;\n\n    NOISY(printf(\"outline insets %d %d %d %d, rad %f, alpha %x\\n\",\n            image->outlineInsetsLeft,\n            image->outlineInsetsTop,\n            image->outlineInsetsRight,\n            image->outlineInsetsBottom,\n            image->outlineRadius,\n            image->outlineAlpha));\n}\n\n\nstatic uint32_t get_color(\n    png_bytepp rows, int left, int top, int right, int bottom)\n{\n    png_bytep color = rows[top] + left*4;\n\n    if (left > right || top > bottom) {\n        return Res_png_9patch::TRANSPARENT_COLOR;\n    }\n\n    while (top <= bottom) {\n        for (int i = left; i <= right; i++) {\n            png_bytep p = rows[top]+i*4;\n            if (color[3] == 0) {\n                if (p[3] != 0) {\n                    return Res_png_9patch::NO_COLOR;\n                }\n            } else if (p[0] != color[0] || p[1] != color[1]\n                       || p[2] != color[2] || p[3] != color[3]) {\n                return Res_png_9patch::NO_COLOR;\n            }\n        }\n        top++;\n    }\n\n    if (color[3] == 0) {\n        return Res_png_9patch::TRANSPARENT_COLOR;\n    }\n    return (color[3]<<24) | (color[0]<<16) | (color[1]<<8) | color[2];\n}\n\nstatic void select_patch(\n    int which, int front, int back, int size, int* start, int* end)\n{\n    switch (which) {\n    case 0:\n        *start = 0;\n        *end = front-1;\n        break;\n    case 1:\n        *start = front;\n        *end = back-1;\n        break;\n    case 2:\n        *start = back;\n        *end = size-1;\n        break;\n    }\n}\n\nstatic uint32_t get_color(image_info* image, int hpatch, int vpatch)\n{\n    int left, right, top, bottom;\n    select_patch(\n        hpatch, image->xDivs[0], image->xDivs[1],\n        image->width, &left, &right);\n    select_patch(\n        vpatch, image->yDivs[0], image->yDivs[1],\n        image->height, &top, &bottom);\n    //printf(\"Selecting h=%d v=%d: (%d,%d)-(%d,%d)\\n\",\n    //       hpatch, vpatch, left, top, right, bottom);\n    const uint32_t c = get_color(image->rows, left, top, right, bottom);\n    NOISY(printf(\"Color in (%d,%d)-(%d,%d): #%08x\\n\", left, top, right, bottom, c));\n    return c;\n}\n\nstatic status_t do_9patch(const char* imageName, image_info* image)\n{\n    image->is9Patch = true;\n\n    int W = image->width;\n    int H = image->height;\n    int i, j;\n\n    int maxSizeXDivs = W * sizeof(int32_t);\n    int maxSizeYDivs = H * sizeof(int32_t);\n    int32_t* xDivs = image->xDivs = (int32_t*) malloc(maxSizeXDivs);\n    int32_t* yDivs = image->yDivs = (int32_t*) malloc(maxSizeYDivs);\n    uint8_t numXDivs = 0;\n    uint8_t numYDivs = 0;\n\n    int8_t numColors;\n    int numRows;\n    int numCols;\n    int top;\n    int left;\n    int right;\n    int bottom;\n    memset(xDivs, -1, maxSizeXDivs);\n    memset(yDivs, -1, maxSizeYDivs);\n    image->info9Patch.paddingLeft = image->info9Patch.paddingRight =\n        image->info9Patch.paddingTop = image->info9Patch.paddingBottom = -1;\n\n    image->layoutBoundsLeft = image->layoutBoundsRight =\n        image->layoutBoundsTop = image->layoutBoundsBottom = 0;\n\n    png_bytep p = image->rows[0];\n    bool transparent = p[3] == 0;\n    bool hasColor = false;\n\n    const char* errorMsg = NULL;\n    int errorPixel = -1;\n    const char* errorEdge = NULL;\n\n    int colorIndex = 0;\n\n    // Validate size...\n    if (W < 3 || H < 3) {\n        errorMsg = \"Image must be at least 3x3 (1x1 without frame) pixels\";\n        goto getout;\n    }\n\n    // Validate frame...\n    if (!transparent &&\n        (p[0] != 0xFF || p[1] != 0xFF || p[2] != 0xFF || p[3] != 0xFF)) {\n        errorMsg = \"Must have one-pixel frame that is either transparent or white\";\n        goto getout;\n    }\n\n    // Find left and right of sizing areas...\n    if (get_horizontal_ticks(p, W, transparent, true, &xDivs[0],\n                             &xDivs[1], &errorMsg, &numXDivs, true) != NO_ERROR) {\n        errorPixel = xDivs[0];\n        errorEdge = \"top\";\n        goto getout;\n    }\n\n    // Find top and bottom of sizing areas...\n    if (get_vertical_ticks(image->rows, 0, H, transparent, true, &yDivs[0],\n                           &yDivs[1], &errorMsg, &numYDivs, true) != NO_ERROR) {\n        errorPixel = yDivs[0];\n        errorEdge = \"left\";\n        goto getout;\n    }\n\n    // Copy patch size data into image...\n    image->info9Patch.numXDivs = numXDivs;\n    image->info9Patch.numYDivs = numYDivs;\n\n    // Find left and right of padding area...\n    if (get_horizontal_ticks(image->rows[H-1], W, transparent, false, &image->info9Patch.paddingLeft,\n                             &image->info9Patch.paddingRight, &errorMsg, NULL, false) != NO_ERROR) {\n        errorPixel = image->info9Patch.paddingLeft;\n        errorEdge = \"bottom\";\n        goto getout;\n    }\n\n    // Find top and bottom of padding area...\n    if (get_vertical_ticks(image->rows, (W-1)*4, H, transparent, false, &image->info9Patch.paddingTop,\n                           &image->info9Patch.paddingBottom, &errorMsg, NULL, false) != NO_ERROR) {\n        errorPixel = image->info9Patch.paddingTop;\n        errorEdge = \"right\";\n        goto getout;\n    }\n\n    // Find left and right of layout padding...\n    get_horizontal_layout_bounds_ticks(image->rows[H-1], W, transparent, false,\n                                        &image->layoutBoundsLeft,\n                                        &image->layoutBoundsRight, &errorMsg);\n\n    get_vertical_layout_bounds_ticks(image->rows, (W-1)*4, H, transparent, false,\n                                        &image->layoutBoundsTop,\n                                        &image->layoutBoundsBottom, &errorMsg);\n\n    image->haveLayoutBounds = image->layoutBoundsLeft != 0\n                               || image->layoutBoundsRight != 0\n                               || image->layoutBoundsTop != 0\n                               || image->layoutBoundsBottom != 0;\n\n    if (image->haveLayoutBounds) {\n        NOISY(printf(\"layoutBounds=%d %d %d %d\\n\", image->layoutBoundsLeft, image->layoutBoundsTop,\n                image->layoutBoundsRight, image->layoutBoundsBottom));\n    }\n\n    // use opacity of pixels to estimate the round rect outline\n    get_outline(image);\n\n    // If padding is not yet specified, take values from size.\n    if (image->info9Patch.paddingLeft < 0) {\n        image->info9Patch.paddingLeft = xDivs[0];\n        image->info9Patch.paddingRight = W - 2 - xDivs[1];\n    } else {\n        // Adjust value to be correct!\n        image->info9Patch.paddingRight = W - 2 - image->info9Patch.paddingRight;\n    }\n    if (image->info9Patch.paddingTop < 0) {\n        image->info9Patch.paddingTop = yDivs[0];\n        image->info9Patch.paddingBottom = H - 2 - yDivs[1];\n    } else {\n        // Adjust value to be correct!\n        image->info9Patch.paddingBottom = H - 2 - image->info9Patch.paddingBottom;\n    }\n\n    NOISY(printf(\"Size ticks for %s: x0=%d, x1=%d, y0=%d, y1=%d\\n\", imageName,\n                 xDivs[0], xDivs[1],\n                 yDivs[0], yDivs[1]));\n    NOISY(printf(\"padding ticks for %s: l=%d, r=%d, t=%d, b=%d\\n\", imageName,\n                 image->info9Patch.paddingLeft, image->info9Patch.paddingRight,\n                 image->info9Patch.paddingTop, image->info9Patch.paddingBottom));\n\n    // Remove frame from image.\n    image->rows = (png_bytepp)malloc((H-2) * sizeof(png_bytep));\n    for (i=0; i<(H-2); i++) {\n        image->rows[i] = image->allocRows[i+1];\n        memmove(image->rows[i], image->rows[i]+4, (W-2)*4);\n    }\n    image->width -= 2;\n    W = image->width;\n    image->height -= 2;\n    H = image->height;\n\n    // Figure out the number of rows and columns in the N-patch\n    numCols = numXDivs + 1;\n    if (xDivs[0] == 0) {  // Column 1 is strechable\n        numCols--;\n    }\n    if (xDivs[numXDivs - 1] == W) {\n        numCols--;\n    }\n    numRows = numYDivs + 1;\n    if (yDivs[0] == 0) {  // Row 1 is strechable\n        numRows--;\n    }\n    if (yDivs[numYDivs - 1] == H) {\n        numRows--;\n    }\n\n    // Make sure the amount of rows and columns will fit in the number of\n    // colors we can use in the 9-patch format.\n    if (numRows * numCols > 0x7F) {\n        errorMsg = \"Too many rows and columns in 9-patch perimeter\";\n        goto getout;\n    }\n\n    numColors = numRows * numCols;\n    image->info9Patch.numColors = numColors;\n    image->colors = (uint32_t*)malloc(numColors * sizeof(uint32_t));\n\n    // Fill in color information for each patch.\n\n    uint32_t c;\n    top = 0;\n\n    // The first row always starts with the top being at y=0 and the bottom\n    // being either yDivs[1] (if yDivs[0]=0) of yDivs[0].  In the former case\n    // the first row is stretchable along the Y axis, otherwise it is fixed.\n    // The last row always ends with the bottom being bitmap.height and the top\n    // being either yDivs[numYDivs-2] (if yDivs[numYDivs-1]=bitmap.height) or\n    // yDivs[numYDivs-1]. In the former case the last row is stretchable along\n    // the Y axis, otherwise it is fixed.\n    //\n    // The first and last columns are similarly treated with respect to the X\n    // axis.\n    //\n    // The above is to help explain some of the special casing that goes on the\n    // code below.\n\n    // The initial yDiv and whether the first row is considered stretchable or\n    // not depends on whether yDiv[0] was zero or not.\n    for (j = (yDivs[0] == 0 ? 1 : 0);\n          j <= numYDivs && top < H;\n          j++) {\n        if (j == numYDivs) {\n            bottom = H;\n        } else {\n            bottom = yDivs[j];\n        }\n        left = 0;\n        // The initial xDiv and whether the first column is considered\n        // stretchable or not depends on whether xDiv[0] was zero or not.\n        for (i = xDivs[0] == 0 ? 1 : 0;\n              i <= numXDivs && left < W;\n              i++) {\n            if (i == numXDivs) {\n                right = W;\n            } else {\n                right = xDivs[i];\n            }\n            c = get_color(image->rows, left, top, right - 1, bottom - 1);\n            image->colors[colorIndex++] = c;\n            NOISY(if (c != Res_png_9patch::NO_COLOR) hasColor = true);\n            left = right;\n        }\n        top = bottom;\n    }\n\n    assert(colorIndex == numColors);\n\n    for (i=0; i<numColors; i++) {\n        if (hasColor) {\n            if (i == 0) printf(\"Colors in %s:\\n \", imageName);\n            printf(\" #%08x\", image->colors[i]);\n            if (i == numColors - 1) printf(\"\\n\");\n        }\n    }\ngetout:\n    if (errorMsg) {\n        fprintf(stderr,\n            \"ERROR: 9-patch image %s malformed.\\n\"\n            \"       %s.\\n\", imageName, errorMsg);\n        if (errorEdge != NULL) {\n            if (errorPixel >= 0) {\n                fprintf(stderr,\n                    \"       Found at pixel #%d along %s edge.\\n\", errorPixel, errorEdge);\n            } else {\n                fprintf(stderr,\n                    \"       Found along %s edge.\\n\", errorEdge);\n            }\n        }\n        return UNKNOWN_ERROR;\n    }\n    return NO_ERROR;\n}\n\nstatic void checkNinePatchSerialization(Res_png_9patch* inPatch,  void* data)\n{\n    size_t patchSize = inPatch->serializedSize();\n    void* newData = malloc(patchSize);\n    memcpy(newData, data, patchSize);\n    Res_png_9patch* outPatch = inPatch->deserialize(newData);\n    // deserialization is done in place, so outPatch == newData\n    assert(outPatch == newData);\n    assert(outPatch->numXDivs == inPatch->numXDivs);\n    assert(outPatch->numYDivs == inPatch->numYDivs);\n    assert(outPatch->paddingLeft == inPatch->paddingLeft);\n    assert(outPatch->paddingRight == inPatch->paddingRight);\n    assert(outPatch->paddingTop == inPatch->paddingTop);\n    assert(outPatch->paddingBottom == inPatch->paddingBottom);\n    for (int i = 0; i < outPatch->numXDivs; i++) {\n        assert(outPatch->xDivs[i] == inPatch->xDivs[i]);\n    }\n    for (int i = 0; i < outPatch->numYDivs; i++) {\n        assert(outPatch->yDivs[i] == inPatch->yDivs[i]);\n    }\n    for (int i = 0; i < outPatch->numColors; i++) {\n        assert(outPatch->colors[i] == inPatch->colors[i]);\n    }\n    free(newData);\n}\n\nstatic void dump_image(int w, int h, png_bytepp rows, int color_type)\n{\n    int i, j, rr, gg, bb, aa;\n\n    int bpp;\n    if (color_type == PNG_COLOR_TYPE_PALETTE || color_type == PNG_COLOR_TYPE_GRAY) {\n        bpp = 1;\n    } else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {\n        bpp = 2;\n    } else if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) {\n        // We use a padding byte even when there is no alpha\n        bpp = 4;\n    } else {\n        printf(\"Unknown color type %d.\\n\", color_type);\n    }\n\n    for (j = 0; j < h; j++) {\n        png_bytep row = rows[j];\n        for (i = 0; i < w; i++) {\n            rr = row[0];\n            gg = row[1];\n            bb = row[2];\n            aa = row[3];\n            row += bpp;\n\n            if (i == 0) {\n                printf(\"Row %d:\", j);\n            }\n            switch (bpp) {\n            case 1:\n                printf(\" (%d)\", rr);\n                break;\n            case 2:\n                printf(\" (%d %d\", rr, gg);\n                break;\n            case 3:\n                printf(\" (%d %d %d)\", rr, gg, bb);\n                break;\n            case 4:\n                printf(\" (%d %d %d %d)\", rr, gg, bb, aa);\n                break;\n            }\n            if (i == (w - 1)) {\n                NOISY(printf(\"\\n\"));\n            }\n        }\n    }\n}\n\n#define MAX(a,b) ((a)>(b)?(a):(b))\n#define ABS(a)   ((a)<0?-(a):(a))\n\nstatic void analyze_image(const char *imageName, image_info &imageInfo, int grayscaleTolerance,\n                          png_colorp rgbPalette, png_bytep alphaPalette,\n                          int *paletteEntries, bool *hasTransparency, int *colorType,\n                          png_bytepp outRows)\n{\n    int w = imageInfo.width;\n    int h = imageInfo.height;\n    int i, j, rr, gg, bb, aa, idx;\n    uint32_t colors[256], col;\n    int num_colors = 0;\n    int maxGrayDeviation = 0;\n\n    bool isOpaque = true;\n    bool isPalette = true;\n    bool isGrayscale = true;\n\n    // Scan the entire image and determine if:\n    // 1. Every pixel has R == G == B (grayscale)\n    // 2. Every pixel has A == 255 (opaque)\n    // 3. There are no more than 256 distinct RGBA colors\n\n    // NOISY(printf(\"Initial image data:\\n\"));\n    // dump_image(w, h, imageInfo.rows, PNG_COLOR_TYPE_RGB_ALPHA);\n\n    for (j = 0; j < h; j++) {\n        png_bytep row = imageInfo.rows[j];\n        png_bytep out = outRows[j];\n        for (i = 0; i < w; i++) {\n            rr = *row++;\n            gg = *row++;\n            bb = *row++;\n            aa = *row++;\n\n            int odev = maxGrayDeviation;\n            maxGrayDeviation = MAX(ABS(rr - gg), maxGrayDeviation);\n            maxGrayDeviation = MAX(ABS(gg - bb), maxGrayDeviation);\n            maxGrayDeviation = MAX(ABS(bb - rr), maxGrayDeviation);\n            if (maxGrayDeviation > odev) {\n                NOISY(printf(\"New max dev. = %d at pixel (%d, %d) = (%d %d %d %d)\\n\",\n                             maxGrayDeviation, i, j, rr, gg, bb, aa));\n            }\n\n            // Check if image is really grayscale\n            if (isGrayscale) {\n                if (rr != gg || rr != bb) {\n                     NOISY(printf(\"Found a non-gray pixel at %d, %d = (%d %d %d %d)\\n\",\n                                  i, j, rr, gg, bb, aa));\n                    isGrayscale = false;\n                }\n            }\n\n            // Check if image is really opaque\n            if (isOpaque) {\n                if (aa != 0xff) {\n                    NOISY(printf(\"Found a non-opaque pixel at %d, %d = (%d %d %d %d)\\n\",\n                                 i, j, rr, gg, bb, aa));\n                    isOpaque = false;\n                }\n            }\n\n            // Check if image is really <= 256 colors\n            if (isPalette) {\n                col = (uint32_t) ((rr << 24) | (gg << 16) | (bb << 8) | aa);\n                bool match = false;\n                for (idx = 0; idx < num_colors; idx++) {\n                    if (colors[idx] == col) {\n                        match = true;\n                        break;\n                    }\n                }\n\n                // Write the palette index for the pixel to outRows optimistically\n                // We might overwrite it later if we decide to encode as gray or\n                // gray + alpha\n                *out++ = idx;\n                if (!match) {\n                    if (num_colors == 256) {\n                        NOISY(printf(\"Found 257th color at %d, %d\\n\", i, j));\n                        isPalette = false;\n                    } else {\n                        colors[num_colors++] = col;\n                    }\n                }\n            }\n        }\n    }\n\n    *paletteEntries = 0;\n    *hasTransparency = !isOpaque;\n    int bpp = isOpaque ? 3 : 4;\n    int paletteSize = w * h + bpp * num_colors;\n\n    NOISY(printf(\"isGrayscale = %s\\n\", isGrayscale ? \"true\" : \"false\"));\n    NOISY(printf(\"isOpaque = %s\\n\", isOpaque ? \"true\" : \"false\"));\n    NOISY(printf(\"isPalette = %s\\n\", isPalette ? \"true\" : \"false\"));\n    NOISY(printf(\"Size w/ palette = %d, gray+alpha = %d, rgb(a) = %d\\n\",\n                 paletteSize, 2 * w * h, bpp * w * h));\n    NOISY(printf(\"Max gray deviation = %d, tolerance = %d\\n\", maxGrayDeviation, grayscaleTolerance));\n\n    // Choose the best color type for the image.\n    // 1. Opaque gray - use COLOR_TYPE_GRAY at 1 byte/pixel\n    // 2. Gray + alpha - use COLOR_TYPE_PALETTE if the number of distinct combinations\n    //     is sufficiently small, otherwise use COLOR_TYPE_GRAY_ALPHA\n    // 3. RGB(A) - use COLOR_TYPE_PALETTE if the number of distinct colors is sufficiently\n    //     small, otherwise use COLOR_TYPE_RGB{_ALPHA}\n    if (isGrayscale) {\n        if (isOpaque) {\n            *colorType = PNG_COLOR_TYPE_GRAY; // 1 byte/pixel\n        } else {\n            // Use a simple heuristic to determine whether using a palette will\n            // save space versus using gray + alpha for each pixel.\n            // This doesn't take into account chunk overhead, filtering, LZ\n            // compression, etc.\n            if (isPalette && (paletteSize < 2 * w * h)) {\n                *colorType = PNG_COLOR_TYPE_PALETTE; // 1 byte/pixel + 4 bytes/color\n            } else {\n                *colorType = PNG_COLOR_TYPE_GRAY_ALPHA; // 2 bytes per pixel\n            }\n        }\n    } else if (isPalette && (paletteSize < bpp * w * h)) {\n        *colorType = PNG_COLOR_TYPE_PALETTE;\n    } else {\n        if (maxGrayDeviation <= grayscaleTolerance) {\n            printf(\"%s: forcing image to gray (max deviation = %d)\\n\", imageName, maxGrayDeviation);\n            *colorType = isOpaque ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_GRAY_ALPHA;\n        } else {\n            *colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;\n        }\n    }\n\n    // Perform postprocessing of the image or palette data based on the final\n    // color type chosen\n\n    if (*colorType == PNG_COLOR_TYPE_PALETTE) {\n        // Create separate RGB and Alpha palettes and set the number of colors\n        *paletteEntries = num_colors;\n\n        // Create the RGB and alpha palettes\n        for (int idx = 0; idx < num_colors; idx++) {\n            col = colors[idx];\n            rgbPalette[idx].red   = (png_byte) ((col >> 24) & 0xff);\n            rgbPalette[idx].green = (png_byte) ((col >> 16) & 0xff);\n            rgbPalette[idx].blue  = (png_byte) ((col >>  8) & 0xff);\n            alphaPalette[idx]     = (png_byte)  (col        & 0xff);\n        }\n    } else if (*colorType == PNG_COLOR_TYPE_GRAY || *colorType == PNG_COLOR_TYPE_GRAY_ALPHA) {\n        // If the image is gray or gray + alpha, compact the pixels into outRows\n        for (j = 0; j < h; j++) {\n            png_bytep row = imageInfo.rows[j];\n            png_bytep out = outRows[j];\n            for (i = 0; i < w; i++) {\n                rr = *row++;\n                gg = *row++;\n                bb = *row++;\n                aa = *row++;\n                \n                if (isGrayscale) {\n                    *out++ = rr;\n                } else {\n                    *out++ = (png_byte) (rr * 0.2126f + gg * 0.7152f + bb * 0.0722f);\n                }\n                if (!isOpaque) {\n                    *out++ = aa;\n                }\n           }\n        }\n    }\n}\n\n\nstatic void write_png(const char* imageName,\n                      png_structp write_ptr, png_infop write_info,\n                      image_info& imageInfo, int grayscaleTolerance)\n{\n    bool optimize = true;\n    png_uint_32 width, height;\n    int color_type;\n    int bit_depth, interlace_type, compression_type;\n    int i;\n\n    png_unknown_chunk unknowns[3];\n    unknowns[0].data = NULL;\n    unknowns[1].data = NULL;\n    unknowns[2].data = NULL;\n\n    png_bytepp outRows = (png_bytepp) malloc((int) imageInfo.height * sizeof(png_bytep));\n    if (outRows == (png_bytepp) 0) {\n        printf(\"Can't allocate output buffer!\\n\");\n        exit(1);\n    }\n    for (i = 0; i < (int) imageInfo.height; i++) {\n        outRows[i] = (png_bytep) malloc(2 * (int) imageInfo.width);\n        if (outRows[i] == (png_bytep) 0) {\n            printf(\"Can't allocate output buffer!\\n\");\n            exit(1);\n        }\n    }\n\n    png_set_compression_level(write_ptr, Z_BEST_COMPRESSION);\n\n    NOISY(printf(\"Writing image %s: w = %d, h = %d\\n\", imageName,\n          (int) imageInfo.width, (int) imageInfo.height));\n\n    png_color rgbPalette[256];\n    png_byte alphaPalette[256];\n    bool hasTransparency;\n    int paletteEntries;\n\n    analyze_image(imageName, imageInfo, grayscaleTolerance, rgbPalette, alphaPalette,\n                  &paletteEntries, &hasTransparency, &color_type, outRows);\n\n    // If the image is a 9-patch, we need to preserve it as a ARGB file to make\n    // sure the pixels will not be pre-dithered/clamped until we decide they are\n    if (imageInfo.is9Patch && (color_type == PNG_COLOR_TYPE_RGB ||\n            color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE)) {\n        color_type = PNG_COLOR_TYPE_RGB_ALPHA;\n    }\n\n    switch (color_type) {\n    case PNG_COLOR_TYPE_PALETTE:\n        NOISY(printf(\"Image %s has %d colors%s, using PNG_COLOR_TYPE_PALETTE\\n\",\n                     imageName, paletteEntries,\n                     hasTransparency ? \" (with alpha)\" : \"\"));\n        break;\n    case PNG_COLOR_TYPE_GRAY:\n        NOISY(printf(\"Image %s is opaque gray, using PNG_COLOR_TYPE_GRAY\\n\", imageName));\n        break;\n    case PNG_COLOR_TYPE_GRAY_ALPHA:\n        NOISY(printf(\"Image %s is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA\\n\", imageName));\n        break;\n    case PNG_COLOR_TYPE_RGB:\n        NOISY(printf(\"Image %s is opaque RGB, using PNG_COLOR_TYPE_RGB\\n\", imageName));\n        break;\n    case PNG_COLOR_TYPE_RGB_ALPHA:\n        NOISY(printf(\"Image %s is RGB + alpha, using PNG_COLOR_TYPE_RGB_ALPHA\\n\", imageName));\n        break;\n    }\n\n    png_set_IHDR(write_ptr, write_info, imageInfo.width, imageInfo.height,\n                 8, color_type, PNG_INTERLACE_NONE,\n                 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);\n\n    if (color_type == PNG_COLOR_TYPE_PALETTE) {\n        png_set_PLTE(write_ptr, write_info, rgbPalette, paletteEntries);\n        if (hasTransparency) {\n            png_set_tRNS(write_ptr, write_info, alphaPalette, paletteEntries, (png_color_16p) 0);\n        }\n       png_set_filter(write_ptr, 0, PNG_NO_FILTERS);\n    } else {\n       png_set_filter(write_ptr, 0, PNG_ALL_FILTERS);\n    }\n\n    if (imageInfo.is9Patch) {\n        int chunk_count = 2 + (imageInfo.haveLayoutBounds ? 1 : 0);\n        int p_index = imageInfo.haveLayoutBounds ? 2 : 1;\n        int b_index = 1;\n        int o_index = 0;\n\n        // Chunks ordered thusly because older platforms depend on the base 9 patch data being last\n        png_byte *chunk_names = imageInfo.haveLayoutBounds\n                ? (png_byte*)\"npOl\\0npLb\\0npTc\\0\"\n                : (png_byte*)\"npOl\\0npTc\";\n\n        // base 9 patch data\n        NOISY(printf(\"Adding 9-patch info...\\n\"));\n        strcpy((char*)unknowns[p_index].name, \"npTc\");\n        unknowns[p_index].data = (png_byte*)imageInfo.serialize9patch();\n        unknowns[p_index].size = imageInfo.info9Patch.serializedSize();\n        // TODO: remove the check below when everything works\n        checkNinePatchSerialization(&imageInfo.info9Patch, unknowns[p_index].data);\n\n        // automatically generated 9 patch outline data\n        int chunk_size = sizeof(png_uint_32) * 6;\n        strcpy((char*)unknowns[o_index].name, \"npOl\");\n        unknowns[o_index].data = (png_byte*) calloc(chunk_size, 1);\n        png_byte outputData[chunk_size];\n        memcpy(&outputData, &imageInfo.outlineInsetsLeft, 4 * sizeof(png_uint_32));\n        ((float*) outputData)[4] = imageInfo.outlineRadius;\n        ((png_uint_32*) outputData)[5] = imageInfo.outlineAlpha;\n        memcpy(unknowns[o_index].data, &outputData, chunk_size);\n        unknowns[o_index].size = chunk_size;\n\n        // optional optical inset / layout bounds data\n        if (imageInfo.haveLayoutBounds) {\n            int chunk_size = sizeof(png_uint_32) * 4;\n            strcpy((char*)unknowns[b_index].name, \"npLb\");\n            unknowns[b_index].data = (png_byte*) calloc(chunk_size, 1);\n            memcpy(unknowns[b_index].data, &imageInfo.layoutBoundsLeft, chunk_size);\n            unknowns[b_index].size = chunk_size;\n        }\n\n        for (int i = 0; i < chunk_count; i++) {\n            unknowns[i].location = PNG_HAVE_PLTE;\n        }\n        png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS,\n                                    chunk_names, chunk_count);\n        png_set_unknown_chunks(write_ptr, write_info, unknowns, chunk_count);\n#if PNG_LIBPNG_VER < 10600\n        /* Deal with unknown chunk location bug in 1.5.x and earlier */\n        png_set_unknown_chunk_location(write_ptr, write_info, 0, PNG_HAVE_PLTE);\n        if (imageInfo.haveLayoutBounds) {\n            png_set_unknown_chunk_location(write_ptr, write_info, 1, PNG_HAVE_PLTE);\n        }\n#endif\n    }\n\n\n    png_write_info(write_ptr, write_info);\n\n    png_bytepp rows;\n    if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) {\n        if (color_type == PNG_COLOR_TYPE_RGB) {\n            png_set_filler(write_ptr, 0, PNG_FILLER_AFTER);\n        }\n        rows = imageInfo.rows;\n    } else {\n        rows = outRows;\n    }\n    png_write_image(write_ptr, rows);\n\n//     NOISY(printf(\"Final image data:\\n\"));\n//     dump_image(imageInfo.width, imageInfo.height, rows, color_type);\n\n    png_write_end(write_ptr, write_info);\n\n    for (i = 0; i < (int) imageInfo.height; i++) {\n        free(outRows[i]);\n    }\n    free(outRows);\n    free(unknowns[0].data);\n    free(unknowns[1].data);\n    free(unknowns[2].data);\n\n    png_get_IHDR(write_ptr, write_info, &width, &height,\n       &bit_depth, &color_type, &interlace_type,\n       &compression_type, NULL);\n\n    NOISY(printf(\"Image written: w=%d, h=%d, d=%d, colors=%d, inter=%d, comp=%d\\n\",\n                 (int)width, (int)height, bit_depth, color_type, interlace_type,\n                 compression_type));\n}\n\nstatus_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,\n                         const sp<AaptFile>& file, String8* outNewLeafName)\n{\n    String8 ext(file->getPath().getPathExtension());\n\n    // We currently only process PNG images.\n    if (strcmp(ext.string(), \".png\") != 0) {\n        return NO_ERROR;\n    }\n\n    // Example of renaming a file:\n    //*outNewLeafName = file->getPath().getBasePath().getFileName();\n    //outNewLeafName->append(\".nupng\");\n\n    String8 printableName(file->getPrintableSource());\n\n    if (bundle->getVerbose()) {\n        printf(\"Processing image: %s\\n\", printableName.string());\n    }\n\n    png_structp read_ptr = NULL;\n    png_infop read_info = NULL;\n    FILE* fp;\n\n    image_info imageInfo;\n\n    png_structp write_ptr = NULL;\n    png_infop write_info = NULL;\n\n    status_t error = UNKNOWN_ERROR;\n\n    const size_t nameLen = file->getPath().length();\n\n    fp = fopen(file->getSourceFile().string(), \"rb\");\n    if (fp == NULL) {\n        fprintf(stderr, \"%s: ERROR: Unable to open PNG file\\n\", printableName.string());\n        goto bail;\n    }\n\n    read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, (png_error_ptr)NULL,\n                                        (png_error_ptr)NULL);\n    if (!read_ptr) {\n        goto bail;\n    }\n\n    read_info = png_create_info_struct(read_ptr);\n    if (!read_info) {\n        goto bail;\n    }\n\n    if (setjmp(png_jmpbuf(read_ptr))) {\n        goto bail;\n    }\n\n    png_init_io(read_ptr, fp);\n\n    read_png(printableName.string(), read_ptr, read_info, &imageInfo);\n\n    if (nameLen > 6) {\n        const char* name = file->getPath().string();\n        if (name[nameLen-5] == '9' && name[nameLen-6] == '.') {\n            if (do_9patch(printableName.string(), &imageInfo) != NO_ERROR) {\n                goto bail;\n            }\n        }\n    }\n\n    write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, (png_error_ptr)NULL,\n                                        (png_error_ptr)NULL);\n    if (!write_ptr)\n    {\n        goto bail;\n    }\n\n    write_info = png_create_info_struct(write_ptr);\n    if (!write_info)\n    {\n        goto bail;\n    }\n\n    png_set_write_fn(write_ptr, (void*)file.get(),\n                     png_write_aapt_file, png_flush_aapt_file);\n\n    if (setjmp(png_jmpbuf(write_ptr)))\n    {\n        goto bail;\n    }\n\n    write_png(printableName.string(), write_ptr, write_info, imageInfo,\n              bundle->getGrayscaleTolerance());\n\n    error = NO_ERROR;\n\n    if (bundle->getVerbose()) {\n        fseek(fp, 0, SEEK_END);\n        size_t oldSize = (size_t)ftell(fp);\n        size_t newSize = file->getSize();\n        float factor = ((float)newSize)/oldSize;\n        int percent = (int)(factor*100);\n        printf(\"    (processed image %s: %d%% size of source)\\n\", printableName.string(), percent);\n    }\n\nbail:\n    if (read_ptr) {\n        png_destroy_read_struct(&read_ptr, &read_info, (png_infopp)NULL);\n    }\n    if (fp) {\n        fclose(fp);\n    }\n    if (write_ptr) {\n        png_destroy_write_struct(&write_ptr, &write_info);\n    }\n\n    if (error != NO_ERROR) {\n        fprintf(stderr, \"ERROR: Failure processing PNG image %s\\n\",\n                file->getPrintableSource().string());\n    }\n    return error;\n}\n\nstatus_t preProcessImageToCache(const Bundle* bundle, const String8& source, const String8& dest)\n{\n    png_structp read_ptr = NULL;\n    png_infop read_info = NULL;\n\n    FILE* fp;\n\n    image_info imageInfo;\n\n    png_structp write_ptr = NULL;\n    png_infop write_info = NULL;\n\n    status_t error = UNKNOWN_ERROR;\n\n    if (bundle->getVerbose()) {\n        printf(\"Processing image to cache: %s => %s\\n\", source.string(), dest.string());\n    }\n\n    // Get a file handler to read from\n    fp = fopen(source.string(),\"rb\");\n    if (fp == NULL) {\n        fprintf(stderr, \"%s ERROR: Unable to open PNG file\\n\", source.string());\n        return error;\n    }\n\n    // Call libpng to get a struct to read image data into\n    read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);\n    if (!read_ptr) {\n        fclose(fp);\n        png_destroy_read_struct(&read_ptr, &read_info,NULL);\n        return error;\n    }\n\n    // Call libpng to get a struct to read image info into\n    read_info = png_create_info_struct(read_ptr);\n    if (!read_info) {\n        fclose(fp);\n        png_destroy_read_struct(&read_ptr, &read_info,NULL);\n        return error;\n    }\n\n    // Set a jump point for libpng to long jump back to on error\n    if (setjmp(png_jmpbuf(read_ptr))) {\n        fclose(fp);\n        png_destroy_read_struct(&read_ptr, &read_info,NULL);\n        return error;\n    }\n\n    // Set up libpng to read from our file.\n    png_init_io(read_ptr,fp);\n\n    // Actually read data from the file\n    read_png(source.string(), read_ptr, read_info, &imageInfo);\n\n    // We're done reading so we can clean up\n    // Find old file size before releasing handle\n    fseek(fp, 0, SEEK_END);\n    size_t oldSize = (size_t)ftell(fp);\n    fclose(fp);\n    png_destroy_read_struct(&read_ptr, &read_info,NULL);\n\n    // Check to see if we're dealing with a 9-patch\n    // If we are, process appropriately\n    if (source.getBasePath().getPathExtension() == \".9\")  {\n        if (do_9patch(source.string(), &imageInfo) != NO_ERROR) {\n            return error;\n        }\n    }\n\n    // Call libpng to create a structure to hold the processed image data\n    // that can be written to disk\n    write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);\n    if (!write_ptr) {\n        png_destroy_write_struct(&write_ptr, &write_info);\n        return error;\n    }\n\n    // Call libpng to create a structure to hold processed image info that can\n    // be written to disk\n    write_info = png_create_info_struct(write_ptr);\n    if (!write_info) {\n        png_destroy_write_struct(&write_ptr, &write_info);\n        return error;\n    }\n\n    // Open up our destination file for writing\n    fp = fopen(dest.string(), \"wb\");\n    if (!fp) {\n        fprintf(stderr, \"%s ERROR: Unable to open PNG file\\n\", dest.string());\n        png_destroy_write_struct(&write_ptr, &write_info);\n        return error;\n    }\n\n    // Set up libpng to write to our file\n    png_init_io(write_ptr, fp);\n\n    // Set up a jump for libpng to long jump back on on errors\n    if (setjmp(png_jmpbuf(write_ptr))) {\n        fclose(fp);\n        png_destroy_write_struct(&write_ptr, &write_info);\n        return error;\n    }\n\n    // Actually write out to the new png\n    write_png(dest.string(), write_ptr, write_info, imageInfo,\n              bundle->getGrayscaleTolerance());\n\n    if (bundle->getVerbose()) {\n        // Find the size of our new file\n        FILE* reader = fopen(dest.string(), \"rb\");\n        fseek(reader, 0, SEEK_END);\n        size_t newSize = (size_t)ftell(reader);\n        fclose(reader);\n\n        float factor = ((float)newSize)/oldSize;\n        int percent = (int)(factor*100);\n        printf(\"  (processed image to cache entry %s: %d%% size of source)\\n\",\n               dest.string(), percent);\n    }\n\n    //Clean up\n    fclose(fp);\n    png_destroy_write_struct(&write_ptr, &write_info);\n\n    return NO_ERROR;\n}\n\nstatus_t postProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,\n                          ResourceTable* table, const sp<AaptFile>& file)\n{\n    String8 ext(file->getPath().getPathExtension());\n\n    // At this point, now that we have all the resource data, all we need to\n    // do is compile XML files.\n    if (strcmp(ext.string(), \".xml\") == 0) {\n        String16 resourceName(parseResourceName(file->getSourceFile().getPathLeaf()));\n        return compileXmlFile(bundle, assets, resourceName, file, table);\n    }\n\n    return NO_ERROR;\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/Images.h",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#ifndef IMAGES_H\n#define IMAGES_H\n\n#include \"ResourceTable.h\"\n#include \"Bundle.h\"\n\n#include <utils/String8.h>\n#include <utils/RefBase.h>\n\nusing android::String8;\n\nstatus_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,\n                         const sp<AaptFile>& file, String8* outNewLeafName);\n\nstatus_t preProcessImageToCache(const Bundle* bundle, const String8& source, const String8& dest);\n\nstatus_t postProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,\n                          ResourceTable* table, const sp<AaptFile>& file);\n\n#endif\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/IndentPrinter.h",
    "content": "#ifndef __INDENT_PRINTER_H\n#define __INDENT_PRINTER_H\n\nclass IndentPrinter {\npublic:\n    IndentPrinter(FILE* stream, int indentSize=2)\n        : mStream(stream)\n        , mIndentSize(indentSize)\n        , mIndent(0)\n        , mNeedsIndent(true) {\n    }\n\n    void indent(int amount = 1) {\n        mIndent += amount;\n        if (mIndent < 0) {\n            mIndent = 0;\n        }\n    }\n\n    void print(const char* fmt, ...) {\n        doIndent();\n        va_list args;\n        va_start(args, fmt);\n        vfprintf(mStream, fmt, args);\n        va_end(args);\n    }\n\n    void println(const char* fmt, ...) {\n        doIndent();\n        va_list args;\n        va_start(args, fmt);\n        vfprintf(mStream, fmt, args);\n        va_end(args);\n        fputs(\"\\n\", mStream);\n        mNeedsIndent = true;\n    }\n\n    void println() {\n        doIndent();\n        fputs(\"\\n\", mStream);\n        mNeedsIndent = true;\n    }\n\nprivate:\n    void doIndent() {\n        if (mNeedsIndent) {\n            int numSpaces = mIndent * mIndentSize;\n            while (numSpaces > 0) {\n                fputs(\" \", mStream);\n                numSpaces--;\n            }\n            mNeedsIndent = false;\n        }\n    }\n\n    FILE* mStream;\n    const int mIndentSize;\n    int mIndent;\n    bool mNeedsIndent;\n};\n\n#endif // __INDENT_PRINTER_H\n\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/Main.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Android Asset Packaging Tool main entry point.\n//\n#include \"Main.h\"\n#include \"Bundle.h\"\n\n#include <utils/Log.h>\n#include <utils/threads.h>\n#include <utils/List.h>\n#include <utils/Errors.h>\n\n#include <stdlib.h>\n#include <getopt.h>\n#include <assert.h>\n#include <androidfw/ResourcePackageId.h>\n\nusing namespace android;\n\nstatic const char* gProgName = \"aapt\";\n\n/*\n * When running under Cygwin on Windows, this will convert slash-based\n * paths into back-slash-based ones. Otherwise the ApptAssets file comparisons\n * fail later as they use back-slash separators under Windows.\n *\n * This operates in-place on the path string.\n */\nvoid convertPath(char *path) {\n  if (path != NULL && OS_PATH_SEPARATOR != '/') {\n    for (; *path; path++) {\n      if (*path == '/') {\n        *path = OS_PATH_SEPARATOR;\n      }\n    }\n  }\n}\n\n/*\n * Print usage info.\n */\nvoid usage(void)\n{\n    fprintf(stderr, \"Android Asset Packaging Tool\\n\\n\");\n    fprintf(stderr, \"Usage:\\n\");\n    fprintf(stderr,\n        \" %s l[ist] [-v] [-a] file.{zip,jar,apk}\\n\"\n        \"   List contents of Zip-compatible archive.\\n\\n\", gProgName);\n    fprintf(stderr,\n        \" %s d[ump] [--values] [--include-meta-data] WHAT file.{apk} [asset [asset ...]]\\n\"\n        \"   strings          Print the contents of the resource table string pool in the APK.\\n\"\n        \"   badging          Print the label and icon for the app declared in APK.\\n\"\n        \"   permissions      Print the permissions from the APK.\\n\"\n        \"   resources        Print the resource table from the APK.\\n\"\n        \"   configurations   Print the configurations in the APK.\\n\"\n        \"   xmltree          Print the compiled xmls in the given assets.\\n\"\n        \"   xmlstrings       Print the strings of the given compiled xml assets.\\n\\n\", gProgName);\n    fprintf(stderr,\n        \" %s p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] \\\\\\n\"\n        \"        [-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] \\\\\\n\"\n        \"        [--debug-mode] [--min-sdk-version VAL] [--target-sdk-version VAL] \\\\\\n\"\n        \"        [--app-version VAL] [--app-version-name TEXT] [--custom-package VAL] \\\\\\n\"\n        \"        [--rename-manifest-package PACKAGE] \\\\\\n\"\n        \"        [--rename-instrumentation-target-package PACKAGE] \\\\\\n\"\n        \"        [--utf16] [--auto-add-overlay] \\\\\\n\"\n        \"        [--max-res-version VAL] \\\\\\n\"\n        \"        [-I base-package [-I base-package ...]] \\\\\\n\"\n        \"        [-A asset-source-dir]  [-G class-list-file] [-P public-definitions-file] \\\\\\n\"\n        \"        [-S resource-sources [-S resource-sources ...]] \\\\\\n\"\n        \"        [-F apk-file] [-J R-file-dir] \\\\\\n\"\n        \"        [--product product1,product2,...] \\\\\\n\"\n        \"        [-c CONFIGS] [--preferred-configurations CONFIGS] \\\\\\n\"\n        \"        [--split CONFIGS [--split CONFIGS]] \\\\\\n\"\n        \"        [--feature-of package [--feature-after package]] \\\\\\n\"\n        \"        [raw-files-dir [raw-files-dir] ...] \\\\\\n\"\n        \"        [-B apk-file] \\\\\\n\"\n        \"        [--output-text-symbols DIR]\\n\"\n        \"\\n\"\n        \"   Package the android resources.  It will read assets and resources that are\\n\"\n        \"   supplied with the -M -A -S or raw-files-dir arguments.  The -J -P -F and -R\\n\"\n        \"   options control which files are output.\\n\\n\"\n        , gProgName);\n    fprintf(stderr,\n        \" %s r[emove] [-v] file.{zip,jar,apk} file1 [file2 ...]\\n\"\n        \"   Delete specified files from Zip-compatible archive.\\n\\n\",\n        gProgName);\n    fprintf(stderr,\n        \" %s a[dd] [-v] file.{zip,jar,apk} file1 [file2 ...]\\n\"\n        \"   Add specified files to Zip-compatible archive.\\n\\n\", gProgName);\n    fprintf(stderr,\n        \" %s c[runch] [-v] -S resource-sources ... -C output-folder ...\\n\"\n        \"   Do PNG preprocessing on one or several resource folders\\n\"\n        \"   and store the results in the output folder.\\n\\n\", gProgName);\n    fprintf(stderr,\n        \" %s s[ingleCrunch] [-v] -i input-file -o outputfile\\n\"\n        \"   Do PNG preprocessing on a single file.\\n\\n\", gProgName);\n    fprintf(stderr,\n        \" %s v[ersion]\\n\"\n        \"   Print program version.\\n\\n\", gProgName);\n    fprintf(stderr,\n        \" Modifiers:\\n\"\n        \"   -a  print Android-specific data (resources, manifest) when listing\\n\"\n        \"   -c  specify which configurations to include.  The default is all\\n\"\n        \"       configurations.  The value of the parameter should be a comma\\n\"\n        \"       separated list of configuration values.  Locales should be specified\\n\"\n        \"       as either a language or language-region pair.  Some examples:\\n\"\n        \"            en\\n\"\n        \"            port,en\\n\"\n        \"            port,land,en_US\\n\"\n        \"   -d  one or more device assets to include, separated by commas\\n\"\n        \"   -f  force overwrite of existing files\\n\"\n        \"   -g  specify a pixel tolerance to force images to grayscale, default 0\\n\"\n        \"   -j  specify a jar or zip file containing classes to include\\n\"\n        \"   -k  junk path of file(s) added\\n\"\n        \"   -m  make package directories under location specified by -J\\n\"\n        \"   -u  update existing packages (add new, replace older, remove deleted files)\\n\"\n        \"   -v  verbose output\\n\"\n        \"   -x  create extending (non-application) resource IDs\\n\"\n        \"   -z  require localization of resource attributes marked with\\n\"\n        \"       localization=\\\"suggested\\\"\\n\"\n        \"   -A  additional directory in which to find raw asset files\\n\"\n        \"   -G  A file to output proguard options into.\\n\"\n        \"   -F  specify the apk file to output\\n\"\n        \"   -I  add an existing package to base include set\\n\"\n        \"   -J  specify where to output R.java resource constant definitions\\n\"\n        \"   -M  specify full path to AndroidManifest.xml to include in zip\\n\"\n        \"   -P  specify where to output public resource definitions\\n\"\n        \"   -S  directory in which to find resources.  Multiple directories will be scanned\\n\"\n        \"       and the first match found (left to right) will take precedence.\\n\"\n        \"   -0  specifies an additional extension for which such files will not\\n\"\n        \"       be stored compressed in the .apk.  An empty string means to not\\n\"\n        \"       compress any files at all.\\n\"\n        \"   -B  specify the baseline apk file for output\\n\"\n        \"   --debug-mode\\n\"\n        \"       inserts android:debuggable=\\\"true\\\" in to the application node of the\\n\"\n        \"       manifest, making the application debuggable even on production devices.\\n\"\n        \"   --include-meta-data\\n\"\n        \"       when used with \\\"dump badging\\\" also includes meta-data tags.\\n\"\n        \"   --pseudo-localize\\n\"\n        \"       generate resources for pseudo-locales (en-XA and ar-XB).\\n\"\n        \"   --min-sdk-version\\n\"\n        \"       inserts android:minSdkVersion in to manifest.  If the version is 7 or\\n\"\n        \"       higher, the default encoding for resources will be in UTF-8.\\n\"\n        \"   --target-sdk-version\\n\"\n        \"       inserts android:targetSdkVersion in to manifest.\\n\"\n        \"   --max-res-version\\n\"\n        \"       ignores versioned resource directories above the given value.\\n\"\n        \"   --values\\n\"\n        \"       when used with \\\"dump resources\\\" also includes resource values.\\n\"\n        \"   --version-code\\n\"\n        \"       inserts android:versionCode in to manifest.\\n\"\n        \"   --version-name\\n\"\n        \"       inserts android:versionName in to manifest.\\n\"\n        \"   --replace-version\\n\"\n        \"       If --version-code and/or --version-name are specified, these\\n\"\n        \"       values will replace any value already in the manifest. By\\n\"\n        \"       default, nothing is changed if the manifest already defines\\n\"\n        \"       these attributes.\\n\"\n        \"   --custom-package\\n\"\n        \"       generates R.java into a different package.\\n\"\n        \"   --extra-packages\\n\"\n        \"       generate R.java for libraries. Separate libraries with ':'.\\n\"\n        \"   --generate-dependencies\\n\"\n        \"       generate dependency files in the same directories for R.java and resource package\\n\"\n        \"   --auto-add-overlay\\n\"\n        \"       Automatically add resources that are only in overlays.\\n\"\n        \"   --preferred-density\\n\"\n        \"       Specifies a preference for a particular density. Resources that do not\\n\"\n        \"       match this density and have variants that are a closer match are removed.\\n\"\n        \"   --split\\n\"\n        \"       Builds a separate split APK for the configurations listed. This can\\n\"\n        \"       be loaded alongside the base APK at runtime.\\n\"\n        \"   --feature-of\\n\"\n        \"       Builds a split APK that is a feature of the apk specified here. Resources\\n\"\n        \"       in the base APK can be referenced from the the feature APK.\\n\"\n        \"   --feature-after\\n\"\n        \"       An app can have multiple Feature Split APKs which must be totally ordered.\\n\"\n        \"       If --feature-of is specified, this flag specifies which Feature Split APK\\n\"\n        \"       comes before this one. The first Feature Split APK should not define\\n\"\n        \"       anything here.\\n\"\n        \"   --rename-manifest-package\\n\"\n        \"       Rewrite the manifest so that its package name is the package name\\n\"\n        \"       given here.  Relative class names (for example .Foo) will be\\n\"\n        \"       changed to absolute names with the old package so that the code\\n\"\n        \"       does not need to change.\\n\"\n        \"   --rename-instrumentation-target-package\\n\"\n        \"       Rewrite the manifest so that all of its instrumentation\\n\"\n        \"       components target the given package.  Useful when used in\\n\"\n        \"       conjunction with --rename-manifest-package to fix tests against\\n\"\n        \"       a package that has been renamed.\\n\"\n        \"   --product\\n\"\n        \"       Specifies which variant to choose for strings that have\\n\"\n        \"       product variants\\n\"\n        \"   --utf16\\n\"\n        \"       changes default encoding for resources to UTF-16.  Only useful when API\\n\"\n        \"       level is set to 7 or higher where the default encoding is UTF-8.\\n\"\n        \"   --non-constant-id\\n\"\n        \"       Make the resources ID non constant. This is required to make an R java class\\n\"\n        \"       that does not contain the final value but is used to make reusable compiled\\n\"\n        \"       libraries that need to access resources.\\n\"\n        \"   --shared-lib\\n\"\n        \"       Make a shared library resource package that can be loaded by an application\\n\"\n        \"       at runtime to access the libraries resources. Implies --non-constant-id.\\n\"\n        \"   --error-on-failed-insert\\n\"\n        \"       Forces aapt to return an error if it fails to insert values into the manifest\\n\"\n        \"       with --debug-mode, --min-sdk-version, --target-sdk-version --version-code\\n\"\n        \"       and --version-name.\\n\"\n        \"       Insertion typically fails if the manifest already defines the attribute.\\n\"\n        \"   --error-on-missing-config-entry\\n\"\n        \"       Forces aapt to return an error if it fails to find an entry for a configuration.\\n\"\n        \"   --output-text-symbols\\n\"\n        \"       Generates a text file containing the resource symbols of the R class in the\\n\"\n        \"       specified folder.\\n\"\n        \"   --ignore-assets\\n\"\n        \"       Assets to be ignored. Default pattern is:\\n\"\n        \"       %s\\n\"\n        \"   --forced-package-id\\n\"\n        \"       By default, package id should be 127 in R.java of application,\\n\"\n        \"       using thie parametor would change the id to other value\\n\"\n        \"   --main-package\\n\"\n        \"       use skt package name as resource arsc package name !!\\n\",\n        \"   --type-id-offset\\n\"\n        \"       specify type id offset\\n\",\n        gDefaultIgnoreAssets);\n}\n\n/*\n * Dispatch the command.\n */\nint handleCommand(Bundle* bundle)\n{\n    //printf(\"--- command %d (verbose=%d force=%d):\\n\",\n    //    bundle->getCommand(), bundle->getVerbose(), bundle->getForce());\n    //for (int i = 0; i < bundle->getFileSpecCount(); i++)\n    //    printf(\"  %d: '%s'\\n\", i, bundle->getFileSpecEntry(i));\n\n    switch (bundle->getCommand()) {\n    case kCommandVersion:      return doVersion(bundle);\n    case kCommandList:         return doList(bundle);\n    case kCommandDump:         return doDump(bundle);\n    case kCommandAdd:          return doAdd(bundle);\n    case kCommandRemove:       return doRemove(bundle);\n    case kCommandPackage:      return doPackage(bundle);\n    case kCommandCrunch:       return doCrunch(bundle);\n    case kCommandSingleCrunch: return doSingleCrunch(bundle);\n    case kCommandDaemon:       return runInDaemonMode(bundle);\n    default:\n        fprintf(stderr, \"%s: requested command not yet supported\\n\", gProgName);\n        return 1;\n    }\n}\n\n/*\n * Parse args.\n */\nint main(int argc, char* const argv[])\n{\n    char *prog = argv[0];\n    Bundle bundle;\n    bool wantUsage = false;\n    int result = 1;    // pessimistically assume an error.\n    int tolerance = 0;\n    int typeIdOffset = 0;\n\n    /* default to compression */\n    bundle.setCompressionMethod(ZipEntry::kCompressDeflated);\n\n    if (argc < 2) {\n        wantUsage = true;\n        goto bail;\n    }\n\n    if (argv[1][0] == 'v')\n        bundle.setCommand(kCommandVersion);\n    else if (argv[1][0] == 'd')\n        bundle.setCommand(kCommandDump);\n    else if (argv[1][0] == 'l')\n        bundle.setCommand(kCommandList);\n    else if (argv[1][0] == 'a')\n        bundle.setCommand(kCommandAdd);\n    else if (argv[1][0] == 'r')\n        bundle.setCommand(kCommandRemove);\n    else if (argv[1][0] == 'p')\n        bundle.setCommand(kCommandPackage);\n    else if (argv[1][0] == 'c')\n        bundle.setCommand(kCommandCrunch);\n    else if (argv[1][0] == 's')\n        bundle.setCommand(kCommandSingleCrunch);\n    else if (argv[1][0] == 'm')\n        bundle.setCommand(kCommandDaemon);\n    else {\n        fprintf(stderr, \"ERROR: Unknown command '%s'\\n\", argv[1]);\n        wantUsage = true;\n        goto bail;\n    }\n    argc -= 2;\n    argv += 2;\n\n    /*\n     * Pull out flags.  We support \"-fv\" and \"-f -v\".\n     */\n    while (argc && argv[0][0] == '-') {\n        /* flag(s) found */\n        const char* cp = argv[0] +1;\n\n        while (*cp != '\\0') {\n            switch (*cp) {\n            case 'v':\n                bundle.setVerbose(true);\n                break;\n            case 'a':\n                bundle.setAndroidList(true);\n                break;\n            case 'c':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-c' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                bundle.addConfigurations(argv[0]);\n                break;\n            case 'f':\n                bundle.setForce(true);\n                break;\n            case 'g':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-g' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                tolerance = atoi(argv[0]);\n                bundle.setGrayscaleTolerance(tolerance);\n                printf(\"%s: Images with deviation <= %d will be forced to grayscale.\\n\", prog, tolerance);\n                break;\n            case 'k':\n                bundle.setJunkPath(true);\n                break;\n            case 'm':\n                bundle.setMakePackageDirs(true);\n                break;\n#if 0\n            case 'p':\n                bundle.setPseudolocalize(true);\n                break;\n#endif\n            case 'u':\n                bundle.setUpdate(true);\n                break;\n            case 'x':\n                bundle.setExtending(true);\n                break;\n            case 'z':\n                bundle.setRequireLocalization(true);\n                break;\n            case 'j':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-j' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.addJarFile(argv[0]);\n                break;\n            case 'A':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-A' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.addAssetSourceDir(argv[0]);\n                break;\n            case 'G':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-G' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setProguardFile(argv[0]);\n                break;\n            case 'I':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-I' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.addPackageInclude(argv[0]);\n                break;\n            case 'B':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-B' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setBaselinePackage(argv[0]);\n                break;\n            case 'F':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-F' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setOutputAPKFile(argv[0]);\n                break;\n            case 'J':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-J' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setRClassDir(argv[0]);\n                break;\n            case 'M':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-M' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setAndroidManifestFile(argv[0]);\n                break;\n            case 'P':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-P' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setPublicOutputFile(argv[0]);\n                break;\n            case 'S':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-S' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.addResourceSourceDir(argv[0]);\n                break;\n            case 'C':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-C' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setCrunchedOutputDir(argv[0]);\n                break;\n            case 'i':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-i' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setSingleCrunchInputFile(argv[0]);\n                break;\n            case 'o':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-o' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setSingleCrunchOutputFile(argv[0]);\n                break;\n            case 'D':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-D' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                convertPath(argv[0]);\n                bundle.setMainDexProguardFile(argv[0]);\n                break;\n                break;\n            case '0':\n                argc--;\n                argv++;\n                if (!argc) {\n                    fprintf(stderr, \"ERROR: No argument supplied for '-e' option\\n\");\n                    wantUsage = true;\n                    goto bail;\n                }\n                if (argv[0][0] != 0) {\n                    bundle.addNoCompressExtension(argv[0]);\n                } else {\n                    bundle.setCompressionMethod(ZipEntry::kCompressStored);\n                }\n                break;\n            case '-':\n                if (strcmp(cp, \"-debug-mode\") == 0) {\n                    bundle.setDebugMode(true);\n                } else if (strcmp(cp, \"-min-sdk-version\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--min-sdk-version' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setMinSdkVersion(argv[0]);\n                } else if (strcmp(cp, \"-target-sdk-version\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--target-sdk-version' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setTargetSdkVersion(argv[0]);\n                } else if (strcmp(cp, \"-max-sdk-version\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--max-sdk-version' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setMaxSdkVersion(argv[0]);\n                } else if (strcmp(cp, \"-max-res-version\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--max-res-version' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setMaxResVersion(argv[0]);\n                } else if (strcmp(cp, \"-version-code\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--version-code' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setVersionCode(argv[0]);\n                } else if (strcmp(cp, \"-version-name\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--version-name' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setVersionName(argv[0]);\n                } else if (strcmp(cp, \"-replace-version\") == 0) {\n                    bundle.setReplaceVersion(true);\n                } else if (strcmp(cp, \"-values\") == 0) {\n                    bundle.setValues(true);\n                } else if (strcmp(cp, \"-include-meta-data\") == 0) {\n                    bundle.setIncludeMetaData(true);\n                } else if (strcmp(cp, \"-custom-package\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--custom-package' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setCustomPackage(argv[0]);\n                } else if (strcmp(cp, \"-extra-packages\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--extra-packages' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setExtraPackages(argv[0]);\n                } else if (strcmp(cp, \"-generate-dependencies\") == 0) {\n                    bundle.setGenDependencies(true);\n                } else if (strcmp(cp, \"-utf16\") == 0) {\n                    bundle.setWantUTF16(true);\n                } else if (strcmp(cp, \"-preferred-density\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--preferred-density' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setPreferredDensity(argv[0]);\n                } else if (strcmp(cp, \"-split\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--split' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.addSplitConfigurations(argv[0]);\n                } else if (strcmp(cp, \"-feature-of\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--feature-of' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setFeatureOfPackage(argv[0]);\n                } else if (strcmp(cp, \"-feature-after\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--feature-after' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setFeatureAfterPackage(argv[0]);\n                } else if (strcmp(cp, \"-rename-manifest-package\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--rename-manifest-package' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setManifestPackageNameOverride(argv[0]);\n                } else if (strcmp(cp, \"-rename-instrumentation-target-package\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--rename-instrumentation-target-package' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setInstrumentationPackageNameOverride(argv[0]);\n                } else if (strcmp(cp, \"-auto-add-overlay\") == 0) {\n                    bundle.setAutoAddOverlay(true);\n                } else if (strcmp(cp, \"-error-on-failed-insert\") == 0) {\n                    bundle.setErrorOnFailedInsert(true);\n                } else if (strcmp(cp, \"-error-on-missing-config-entry\") == 0) {\n                    bundle.setErrorOnMissingConfigEntry(true);\n                } else if (strcmp(cp, \"-output-text-symbols\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '-output-text-symbols' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setOutputTextSymbols(argv[0]);\n                } else if (strcmp(cp, \"-product\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--product' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setProduct(argv[0]);\n                } else if (strcmp(cp, \"-non-constant-id\") == 0) {\n                    bundle.setNonConstantId(true);\n                } else if (strcmp(cp, \"-shared-lib\") == 0) {\n                    bundle.setNonConstantId(true);\n                    bundle.setBuildSharedLibrary(true);\n                } else if (strcmp(cp, \"-no-crunch\") == 0) {\n                    bundle.setUseCrunchCache(true);\n                } else if (strcmp(cp, \"-ignore-assets\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--ignore-assets' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    gUserIgnoreAssets = argv[0];\n                } else if (strcmp(cp, \"-pseudo-localize\") == 0) {\n                    bundle.setPseudolocalize(PSEUDO_ACCENTED | PSEUDO_BIDI);\n                } else if (strcmp(cp, \"-forced-package-id\") == 0 || strcmp(cp, \"-customized-package-id\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--forced-package-id' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    if(atoi(argv[0]) > 127 || atoi(argv[0]) <= 0) {\n                        fprintf(stderr, \"ERROR:  '--forced-package-id' option value should between 0 and 127\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    customePackageId = atoi(argv[0]); \n                } else if (strcmp(cp, \"-type-id-offset\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--type-id-offset' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    typeIdOffset = atoi(argv[0]);\n                    if(typeIdOffset > 127 || atoi(argv[0]) < 0) {\n                        fprintf(stderr, \"ERROR:  '--type-id-offset' option value should between 0 and 127\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    bundle.setTypeIdOffset(typeIdOffset);\n                } else if (strcmp(cp, \"-main-package\") == 0 || strcmp(cp, \"-use-skt-package-name\") == 0) {\n                    argc--;\n                    argv++;\n                    if (!argc) {\n                        fprintf(stderr, \"ERROR: No argument supplied for '--main-package' option\\n\");\n                        wantUsage = true;\n                        goto bail;\n                    }\n                    sktPackageName = (char *)malloc(128);  \n                    snprintf(sktPackageName, 127, \"%s\", argv[0]);\n                    sktPackageName[127] = '\\0';\n                } else if (strcmp(cp, \"-no-version-vectors\") == 0) {\n                } else {\n                    fprintf(stderr, \"ERROR: Unknown option '-%s'\\n\", cp);\n                    wantUsage = true;\n                    goto bail;\n                }\n                cp += strlen(cp) - 1;\n                break;\n            default:\n                fprintf(stderr, \"ERROR: Unknown flag '-%c'\\n\", *cp);\n                wantUsage = true;\n                goto bail;\n            }\n\n            cp++;\n        }\n        argc--;\n        argv++;\n    }\n\n    /*\n     * We're past the flags.  The rest all goes straight in.\n     */\n    bundle.setFileSpec(argv, argc);\n\n    result = handleCommand(&bundle);\n\nbail:\n    if (wantUsage) {\n        usage();\n        result = 2;\n    }\n\n    //printf(\"--> returning %d\\n\", result);\n    return result;\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/Main.h",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Some global defines that don't really merit their own header.\n//\n#ifndef __MAIN_H\n#define __MAIN_H\n\n#include <utils/Log.h>\n#include <utils/threads.h>\n#include <utils/List.h>\n#include <utils/Errors.h>\n#include <utils/StrongPointer.h>\n\n#include \"AaptAssets.h\"\n#include \"ApkBuilder.h\"\n#include \"Bundle.h\"\n#include \"ResourceFilter.h\"\n#include \"ZipFile.h\"\n\n\n/* Benchmarking Flag */\n//#define BENCHMARK 1\n\n#if BENCHMARK\n    #include <time.h>\n#endif /* BENCHMARK */\n\nclass OutputSet;\n\nextern int doVersion(Bundle* bundle);\nextern int doList(Bundle* bundle);\nextern int doDump(Bundle* bundle);\nextern int doAdd(Bundle* bundle);\nextern int doRemove(Bundle* bundle);\nextern int doPackage(Bundle* bundle);\nextern int doCrunch(Bundle* bundle);\nextern int doSingleCrunch(Bundle* bundle);\nextern int runInDaemonMode(Bundle* bundle);\n\nextern int calcPercent(long uncompressedLen, long compressedLen);\n\nextern android::status_t writeAPK(Bundle* bundle,\n    const android::String8& outputFile,\n    const android::sp<OutputSet>& outputSet);\n\nextern android::status_t updatePreProcessedCache(Bundle* bundle);\n\nextern android::status_t buildResources(Bundle* bundle,\n    const sp<AaptAssets>& assets, sp<ApkBuilder>& builder);\n\nextern android::status_t writeResourceSymbols(Bundle* bundle,\n        const sp<AaptAssets>& assets, const String8& pkgName,\n        bool includePrivate, bool emitCallback);\n\nextern android::status_t writeProguardFile(Bundle* bundle, const sp<AaptAssets>& assets);\nextern android::status_t writeMainDexProguardFile(Bundle* bundle, const sp<AaptAssets>& assets);\n\nextern bool isValidResourceType(const String8& type);\n\nextern status_t filterResources(Bundle* bundle, const sp<AaptAssets>& assets);\n\nint dumpResources(Bundle* bundle);\n\nstatus_t writeDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets,\n                                FILE* fp, bool includeRaw);\n\nandroid::String8 parseResourceName(const String8& pathLeaf);\n\n#endif // __MAIN_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/NOTICE",
    "content": "\n   Copyright (c) 2005-2008, The Android Open Source Project\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/OutputSet.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __OUTPUT_SET_H\n#define __OUTPUT_SET_H\n\n#include <set>\n#include <utils/Errors.h>\n#include <utils/String8.h>\n#include <utils/StrongPointer.h>\n\nclass AaptFile;\n\nclass OutputEntry {\npublic:\n    OutputEntry() {}\n    OutputEntry(const android::String8& path, const android::sp<const AaptFile>& file)\n        : mPath(path), mFile(file) {}\n\n    inline const android::sp<const AaptFile>& getFile() const {\n        return mFile;\n    }\n\n    inline const android::String8& getPath() const {\n        return mPath;\n    }\n\n    bool operator<(const OutputEntry& o) const { return getPath() < o.mPath; }\n    bool operator==(const OutputEntry& o) const { return getPath() == o.mPath; }\n\nprivate:\n    android::String8 mPath;\n    android::sp<const AaptFile> mFile;\n};\n\nclass OutputSet : public virtual android::RefBase {\npublic:\n    virtual const std::set<OutputEntry>& getEntries() const = 0;\n\n    virtual ~OutputSet() {}\n};\n\n#endif // __OUTPUT_SET_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/Package.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Package assets into Zip files.\n//\n#include \"Main.h\"\n#include \"AaptAssets.h\"\n#include \"OutputSet.h\"\n#include \"ResourceTable.h\"\n#include \"ResourceFilter.h\"\n\n#include <androidfw/misc.h>\n\n#include <utils/Log.h>\n#include <utils/threads.h>\n#include <utils/List.h>\n#include <utils/Errors.h>\n#include <utils/misc.h>\n\n#include <sys/types.h>\n#include <dirent.h>\n#include <ctype.h>\n#include <errno.h>\n\nusing namespace android;\n\nstatic const char* kExcludeExtension = \".EXCLUDE\";\n\n/* these formats are already compressed, or don't compress well */\nstatic const char* kNoCompressExt[] = {\n    \".jpg\", \".jpeg\", \".png\", \".gif\",\n    \".wav\", \".mp2\", \".mp3\", \".ogg\", \".aac\",\n    \".mpg\", \".mpeg\", \".mid\", \".midi\", \".smf\", \".jet\",\n    \".rtttl\", \".imy\", \".xmf\", \".mp4\", \".m4a\",\n    \".m4v\", \".3gp\", \".3gpp\", \".3g2\", \".3gpp2\",\n    \".amr\", \".awb\", \".wma\", \".wmv\"\n};\n\n/* fwd decls, so I can write this downward */\nssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<const OutputSet>& outputSet);\nbool processFile(Bundle* bundle, ZipFile* zip, String8 storageName, const sp<const AaptFile>& file);\nbool okayToCompress(Bundle* bundle, const String8& pathName);\nssize_t processJarFiles(Bundle* bundle, ZipFile* zip);\n\n/*\n * The directory hierarchy looks like this:\n * \"outputDir\" and \"assetRoot\" are existing directories.\n *\n * On success, \"bundle->numPackages\" will be the number of Zip packages\n * we created.\n */\nstatus_t writeAPK(Bundle* bundle, const String8& outputFile, const sp<OutputSet>& outputSet)\n{\n    #if BENCHMARK\n    fprintf(stdout, \"BENCHMARK: Starting APK Bundling \\n\");\n    long startAPKTime = clock();\n    #endif /* BENCHMARK */\n\n    status_t result = NO_ERROR;\n    ZipFile* zip = NULL;\n    int count;\n\n    //bundle->setPackageCount(0);\n\n    /*\n     * Prep the Zip archive.\n     *\n     * If the file already exists, fail unless \"update\" or \"force\" is set.\n     * If \"update\" is set, update the contents of the existing archive.\n     * Else, if \"force\" is set, remove the existing archive.\n     */\n    FileType fileType = getFileType(outputFile.string());\n    if (fileType == kFileTypeNonexistent) {\n        // okay, create it below\n    } else if (fileType == kFileTypeRegular) {\n        if (bundle->getUpdate()) {\n            // okay, open it below\n        } else if (bundle->getForce()) {\n            if (unlink(outputFile.string()) != 0) {\n                fprintf(stderr, \"ERROR: unable to remove '%s': %s\\n\", outputFile.string(),\n                        strerror(errno));\n                goto bail;\n            }\n        } else {\n            fprintf(stderr, \"ERROR: '%s' exists (use '-f' to force overwrite)\\n\",\n                    outputFile.string());\n            goto bail;\n        }\n    } else {\n        fprintf(stderr, \"ERROR: '%s' exists and is not a regular file\\n\", outputFile.string());\n        goto bail;\n    }\n\n    if (bundle->getVerbose()) {\n        printf(\"%s '%s'\\n\", (fileType == kFileTypeNonexistent) ? \"Creating\" : \"Opening\",\n                outputFile.string());\n    }\n\n    status_t status;\n    zip = new ZipFile;\n    status = zip->open(outputFile.string(), ZipFile::kOpenReadWrite | ZipFile::kOpenCreate);\n    if (status != NO_ERROR) {\n        fprintf(stderr, \"ERROR: unable to open '%s' as Zip file for writing\\n\",\n                outputFile.string());\n        goto bail;\n    }\n\n    if (bundle->getVerbose()) {\n        printf(\"Writing all files...\\n\");\n    }\n\n    count = processAssets(bundle, zip, outputSet);\n    if (count < 0) {\n        fprintf(stderr, \"ERROR: unable to process assets while packaging '%s'\\n\",\n                outputFile.string());\n        result = count;\n        goto bail;\n    }\n\n    if (bundle->getVerbose()) {\n        printf(\"Generated %d file%s\\n\", count, (count==1) ? \"\" : \"s\");\n    }\n    \n    count = processJarFiles(bundle, zip);\n    if (count < 0) {\n        fprintf(stderr, \"ERROR: unable to process jar files while packaging '%s'\\n\",\n                outputFile.string());\n        result = count;\n        goto bail;\n    }\n    \n    if (bundle->getVerbose())\n        printf(\"Included %d file%s from jar/zip files.\\n\", count, (count==1) ? \"\" : \"s\");\n    \n    result = NO_ERROR;\n\n    /*\n     * Check for cruft.  We set the \"marked\" flag on all entries we created\n     * or decided not to update.  If the entry isn't already slated for\n     * deletion, remove it now.\n     */\n    {\n        if (bundle->getVerbose())\n            printf(\"Checking for deleted files\\n\");\n        int i, removed = 0;\n        for (i = 0; i < zip->getNumEntries(); i++) {\n            ZipEntry* entry = zip->getEntryByIndex(i);\n\n            if (!entry->getMarked() && entry->getDeleted()) {\n                if (bundle->getVerbose()) {\n                    printf(\"      (removing crufty '%s')\\n\",\n                        entry->getFileName());\n                }\n                zip->remove(entry);\n                removed++;\n            }\n        }\n        if (bundle->getVerbose() && removed > 0)\n            printf(\"Removed %d file%s\\n\", removed, (removed==1) ? \"\" : \"s\");\n    }\n\n    /* tell Zip lib to process deletions and other pending changes */\n    result = zip->flush();\n    if (result != NO_ERROR) {\n        fprintf(stderr, \"ERROR: Zip flush failed, archive may be hosed\\n\");\n        goto bail;\n    }\n\n    /* anything here? */\n    if (zip->getNumEntries() == 0) {\n        if (bundle->getVerbose()) {\n            printf(\"Archive is empty -- removing %s\\n\", outputFile.getPathLeaf().string());\n        }\n        delete zip;        // close the file so we can remove it in Win32\n        zip = NULL;\n        if (unlink(outputFile.string()) != 0) {\n            fprintf(stderr, \"warning: could not unlink '%s'\\n\", outputFile.string());\n        }\n    }\n\n    // If we've been asked to generate a dependency file for the .ap_ package,\n    // do so here\n    if (bundle->getGenDependencies()) {\n        // The dependency file gets output to the same directory\n        // as the specified output file with an additional .d extension.\n        // e.g. bin/resources.ap_.d\n        String8 dependencyFile = outputFile;\n        dependencyFile.append(\".d\");\n\n        FILE* fp = fopen(dependencyFile.string(), \"a\");\n        // Add this file to the dependency file\n        fprintf(fp, \"%s \\\\\\n\", outputFile.string());\n        fclose(fp);\n    }\n\n    assert(result == NO_ERROR);\n\nbail:\n    delete zip;        // must close before remove in Win32\n    if (result != NO_ERROR) {\n        if (bundle->getVerbose()) {\n            printf(\"Removing %s due to earlier failures\\n\", outputFile.string());\n        }\n        if (unlink(outputFile.string()) != 0) {\n            fprintf(stderr, \"warning: could not unlink '%s'\\n\", outputFile.string());\n        }\n    }\n\n    if (result == NO_ERROR && bundle->getVerbose())\n        printf(\"Done!\\n\");\n\n    #if BENCHMARK\n    fprintf(stdout, \"BENCHMARK: End APK Bundling. Time Elapsed: %f ms \\n\",(clock() - startAPKTime)/1000.0);\n    #endif /* BENCHMARK */\n    return result;\n}\n\nssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<const OutputSet>& outputSet)\n{\n    ssize_t count = 0;\n    const std::set<OutputEntry>& entries = outputSet->getEntries();\n    std::set<OutputEntry>::const_iterator iter = entries.begin();\n    for (; iter != entries.end(); iter++) {\n        const OutputEntry& entry = *iter;\n        if (entry.getFile() == NULL) {\n            fprintf(stderr, \"warning: null file being processed.\\n\");\n        } else {\n            String8 storagePath(entry.getPath());\n            storagePath.convertToResPath();\n            if (!processFile(bundle, zip, storagePath, entry.getFile())) {\n                return UNKNOWN_ERROR;\n            }\n            count++;\n        }\n    }\n    return count;\n}\n\n/*\n * Process a regular file, adding it to the archive if appropriate.\n *\n * If we're in \"update\" mode, and the file already exists in the archive,\n * delete the existing entry before adding the new one.\n */\nbool processFile(Bundle* bundle, ZipFile* zip,\n                 String8 storageName, const sp<const AaptFile>& file)\n{\n    const bool hasData = file->hasData();\n\n    ZipEntry* entry;\n    bool fromGzip = false;\n    status_t result;\n\n    /*\n     * See if the filename ends in \".EXCLUDE\".  We can't use\n     * String8::getPathExtension() because the length of what it considers\n     * to be an extension is capped.\n     *\n     * The Asset Manager doesn't check for \".EXCLUDE\" in Zip archives,\n     * so there's no value in adding them (and it makes life easier on\n     * the AssetManager lib if we don't).\n     *\n     * NOTE: this restriction has been removed.  If you're in this code, you\n     * should clean this up, but I'm in here getting rid of Path Name, and I\n     * don't want to make other potentially breaking changes --joeo\n     */\n    int fileNameLen = storageName.length();\n    int excludeExtensionLen = strlen(kExcludeExtension);\n    if (fileNameLen > excludeExtensionLen\n            && (0 == strcmp(storageName.string() + (fileNameLen - excludeExtensionLen),\n                            kExcludeExtension))) {\n        fprintf(stderr, \"warning: '%s' not added to Zip\\n\", storageName.string());\n        return true;\n    }\n\n    if (strcasecmp(storageName.getPathExtension().string(), \".gz\") == 0) {\n        fromGzip = true;\n        storageName = storageName.getBasePath();\n    }\n\n    if (bundle->getUpdate()) {\n        entry = zip->getEntryByName(storageName.string());\n        if (entry != NULL) {\n            /* file already exists in archive; there can be only one */\n            if (entry->getMarked()) {\n                fprintf(stderr,\n                        \"ERROR: '%s' exists twice (check for with & w/o '.gz'?)\\n\",\n                        file->getPrintableSource().string());\n                return false;\n            }\n            if (!hasData) {\n                const String8& srcName = file->getSourceFile();\n                time_t fileModWhen;\n                fileModWhen = getFileModDate(srcName.string());\n                if (fileModWhen == (time_t) -1) { // file existence tested earlier,\n                    return false;                 //  not expecting an error here\n                }\n    \n                if (fileModWhen > entry->getModWhen()) {\n                    // mark as deleted so add() will succeed\n                    if (bundle->getVerbose()) {\n                        printf(\"      (removing old '%s')\\n\", storageName.string());\n                    }\n    \n                    zip->remove(entry);\n                } else {\n                    // version in archive is newer\n                    if (bundle->getVerbose()) {\n                        printf(\"      (not updating '%s')\\n\", storageName.string());\n                    }\n                    entry->setMarked(true);\n                    return true;\n                }\n            } else {\n                // Generated files are always replaced.\n                zip->remove(entry);\n            }\n        }\n    }\n\n    //android_setMinPriority(NULL, ANDROID_LOG_VERBOSE);\n\n    if (fromGzip) {\n        result = zip->addGzip(file->getSourceFile().string(), storageName.string(), &entry);\n    } else if (!hasData) {\n        /* don't compress certain files, e.g. PNGs */\n        int compressionMethod = bundle->getCompressionMethod();\n        if (!okayToCompress(bundle, storageName)) {\n            compressionMethod = ZipEntry::kCompressStored;\n        }\n        result = zip->add(file->getSourceFile().string(), storageName.string(), compressionMethod,\n                            &entry);\n    } else {\n        result = zip->add(file->getData(), file->getSize(), storageName.string(),\n                           file->getCompressionMethod(), &entry);\n    }\n    if (result == NO_ERROR) {\n        if (bundle->getVerbose()) {\n            printf(\"      '%s'%s\", storageName.string(), fromGzip ? \" (from .gz)\" : \"\");\n            if (entry->getCompressionMethod() == ZipEntry::kCompressStored) {\n                printf(\" (not compressed)\\n\");\n            } else {\n                printf(\" (compressed %d%%)\\n\", calcPercent(entry->getUncompressedLen(),\n                            entry->getCompressedLen()));\n            }\n        }\n        entry->setMarked(true);\n    } else {\n        if (result == ALREADY_EXISTS) {\n            fprintf(stderr, \"      Unable to add '%s': file already in archive (try '-u'?)\\n\",\n                    file->getPrintableSource().string());\n        } else {\n            fprintf(stderr, \"      Unable to add '%s': Zip add failed (%d)\\n\",\n                    file->getPrintableSource().string(), result);\n        }\n        return false;\n    }\n\n    return true;\n}\n\n/*\n * Determine whether or not we want to try to compress this file based\n * on the file extension.\n */\nbool okayToCompress(Bundle* bundle, const String8& pathName)\n{\n    String8 ext = pathName.getPathExtension();\n    int i;\n\n    if (ext.length() == 0)\n        return true;\n\n    for (i = 0; i < NELEM(kNoCompressExt); i++) {\n        if (strcasecmp(ext.string(), kNoCompressExt[i]) == 0)\n            return false;\n    }\n\n    const android::Vector<const char*>& others(bundle->getNoCompressExtensions());\n    for (i = 0; i < (int)others.size(); i++) {\n        const char* str = others[i];\n        int pos = pathName.length() - strlen(str);\n        if (pos < 0) {\n            continue;\n        }\n        const char* path = pathName.string();\n        if (strcasecmp(path + pos, str) == 0) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\nbool endsWith(const char* haystack, const char* needle)\n{\n    size_t a = strlen(haystack);\n    size_t b = strlen(needle);\n    if (a < b) return false;\n    return strcasecmp(haystack+(a-b), needle) == 0;\n}\n\nssize_t processJarFile(ZipFile* jar, ZipFile* out)\n{\n    status_t err;\n    size_t N = jar->getNumEntries();\n    size_t count = 0;\n    for (size_t i=0; i<N; i++) {\n        ZipEntry* entry = jar->getEntryByIndex(i);\n        const char* storageName = entry->getFileName();\n        if (endsWith(storageName, \".class\")) {\n            int compressionMethod = entry->getCompressionMethod();\n            size_t size = entry->getUncompressedLen();\n            const void* data = jar->uncompress(entry);\n            if (data == NULL) {\n                fprintf(stderr, \"ERROR: unable to uncompress entry '%s'\\n\",\n                    storageName);\n                return -1;\n            }\n            out->add(data, size, storageName, compressionMethod, NULL);\n            free((void*)data);\n        }\n        count++;\n    }\n    return count;\n}\n\nssize_t processJarFiles(Bundle* bundle, ZipFile* zip)\n{\n    status_t err;\n    ssize_t count = 0;\n    const android::Vector<const char*>& jars = bundle->getJarFiles();\n\n    size_t N = jars.size();\n    for (size_t i=0; i<N; i++) {\n        ZipFile jar;\n        err = jar.open(jars[i], ZipFile::kOpenReadOnly);\n        if (err != 0) {\n            fprintf(stderr, \"ERROR: unable to open '%s' as a zip file: %d\\n\",\n                jars[i], err);\n            return err;\n        }\n        err += processJarFile(&jar, zip);\n        if (err < 0) {\n            fprintf(stderr, \"ERROR: unable to process '%s'\\n\", jars[i]);\n            return err;\n        }\n        count += err;\n    }\n\n    return count;\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/Resource.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n#include \"AaptAssets.h\"\n#include \"AaptXml.h\"\n#include \"CacheUpdater.h\"\n#include \"CrunchCache.h\"\n#include \"FileFinder.h\"\n#include \"Images.h\"\n#include \"IndentPrinter.h\"\n#include \"Main.h\"\n#include \"ResourceTable.h\"\n#include \"StringPool.h\"\n#include \"WorkQueue.h\"\n#include \"XMLNode.h\"\n#include <androidfw/ResourcePackageId.h>\n\n#if HAVE_PRINTF_ZD\n#  define ZD \"%zd\"\n#  define ZD_TYPE ssize_t\n#else\n#  define ZD \"%ld\"\n#  define ZD_TYPE long\n#endif\n\n#define NOISY(x) //x\n\n// Number of threads to use for preprocessing images.\nstatic const size_t MAX_THREADS = 4;\n\n// ==========================================================================\n// ==========================================================================\n// ==========================================================================\n\nclass PackageInfo\n{\npublic:\n    PackageInfo()\n    {\n    }\n    ~PackageInfo()\n    {\n    }\n\n    status_t parsePackage(const sp<AaptGroup>& grp);\n};\n\n// ==========================================================================\n// ==========================================================================\n// ==========================================================================\n\nString8 parseResourceName(const String8& leaf)\n{\n    const char* firstDot = strchr(leaf.string(), '.');\n    const char* str = leaf.string();\n\n    if (firstDot) {\n        return String8(str, firstDot-str);\n    } else {\n        return String8(str);\n    }\n}\n\nResourceTypeSet::ResourceTypeSet()\n    :RefBase(),\n     KeyedVector<String8,sp<AaptGroup> >()\n{\n}\n\nFilePathStore::FilePathStore()\n    :RefBase(),\n     Vector<String8>()\n{\n}\n\nclass ResourceDirIterator\n{\npublic:\n    ResourceDirIterator(const sp<ResourceTypeSet>& set, const String8& resType)\n        : mResType(resType), mSet(set), mSetPos(0), mGroupPos(0)\n    {\n        memset(&mParams, 0, sizeof(ResTable_config));\n    }\n\n    inline const sp<AaptGroup>& getGroup() const { return mGroup; }\n    inline const sp<AaptFile>& getFile() const { return mFile; }\n\n    inline const String8& getBaseName() const { return mBaseName; }\n    inline const String8& getLeafName() const { return mLeafName; }\n    inline String8 getPath() const { return mPath; }\n    inline const ResTable_config& getParams() const { return mParams; }\n\n    enum {\n        EOD = 1\n    };\n\n    ssize_t next()\n    {\n        while (true) {\n            sp<AaptGroup> group;\n            sp<AaptFile> file;\n\n            // Try to get next file in this current group.\n            if (mGroup != NULL && mGroupPos < mGroup->getFiles().size()) {\n                group = mGroup;\n                file = group->getFiles().valueAt(mGroupPos++);\n\n            // Try to get the next group/file in this directory\n            } else if (mSetPos < mSet->size()) {\n                mGroup = group = mSet->valueAt(mSetPos++);\n                if (group->getFiles().size() < 1) {\n                    continue;\n                }\n                file = group->getFiles().valueAt(0);\n                mGroupPos = 1;\n\n            // All done!\n            } else {\n                return EOD;\n            }\n\n            mFile = file;\n\n            String8 leaf(group->getLeaf());\n            mLeafName = String8(leaf);\n            mParams = file->getGroupEntry().toParams();\n            NOISY(printf(\"Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d ui=%d density=%d touch=%d key=%d inp=%d nav=%d\\n\",\n                   group->getPath().string(), mParams.mcc, mParams.mnc,\n                   mParams.language[0] ? mParams.language[0] : '-',\n                   mParams.language[1] ? mParams.language[1] : '-',\n                   mParams.country[0] ? mParams.country[0] : '-',\n                   mParams.country[1] ? mParams.country[1] : '-',\n                   mParams.orientation, mParams.uiMode,\n                   mParams.density, mParams.touchscreen, mParams.keyboard,\n                   mParams.inputFlags, mParams.navigation));\n            mPath = \"res\";\n            mPath.appendPath(file->getGroupEntry().toDirName(mResType));\n            mPath.appendPath(leaf);\n            mBaseName = parseResourceName(leaf);\n            if (mBaseName == \"\") {\n                fprintf(stderr, \"Error: malformed resource filename %s\\n\",\n                        file->getPrintableSource().string());\n                return UNKNOWN_ERROR;\n            }\n\n            NOISY(printf(\"file name=%s\\n\", mBaseName.string()));\n\n            return NO_ERROR;\n        }\n    }\n\nprivate:\n    String8 mResType;\n\n    const sp<ResourceTypeSet> mSet;\n    size_t mSetPos;\n\n    sp<AaptGroup> mGroup;\n    size_t mGroupPos;\n\n    sp<AaptFile> mFile;\n    String8 mBaseName;\n    String8 mLeafName;\n    String8 mPath;\n    ResTable_config mParams;\n};\n\nclass AnnotationProcessor {\npublic:\n    AnnotationProcessor() : mDeprecated(false), mSystemApi(false) { }\n\n    void preprocessComment(String8& comment) {\n        if (comment.size() > 0) {\n            if (comment.contains(\"@deprecated\")) {\n                mDeprecated = true;\n            }\n            if (comment.removeAll(\"@SystemApi\")) {\n                mSystemApi = true;\n            }\n        }\n    }\n\n    void printAnnotations(FILE* fp, const char* indentStr) {\n        if (mDeprecated) {\n            fprintf(fp, \"%s@Deprecated\\n\", indentStr);\n        }\n        if (mSystemApi) {\n            fprintf(fp, \"%s@android.annotation.SystemApi\\n\", indentStr);\n        }\n    }\n\nprivate:\n    bool mDeprecated;\n    bool mSystemApi;\n};\n\n// ==========================================================================\n// ==========================================================================\n// ==========================================================================\n\nbool isValidResourceType(const String8& type)\n{\n    return type == \"anim\" || type == \"animator\" || type == \"interpolator\"\n        || type == \"transition\"\n        || type == \"drawable\" || type == \"layout\"\n        || type == \"values\" || type == \"xml\" || type == \"raw\"\n        || type == \"color\" || type == \"menu\" || type == \"mipmap\";\n}\n\nstatic status_t parsePackage(Bundle* bundle, const sp<AaptAssets>& assets,\n    const sp<AaptGroup>& grp)\n{\n    if (grp->getFiles().size() != 1) {\n        fprintf(stderr, \"warning: Multiple AndroidManifest.xml files found, using %s\\n\",\n                grp->getFiles().valueAt(0)->getPrintableSource().string());\n    }\n\n    sp<AaptFile> file = grp->getFiles().valueAt(0);\n\n    ResXMLTree block;\n    status_t err = parseXMLResource(file, &block);\n    if (err != NO_ERROR) {\n        return err;\n    }\n    //printXMLBlock(&block);\n\n    ResXMLTree::event_code_t code;\n    while ((code=block.next()) != ResXMLTree::START_TAG\n           && code != ResXMLTree::END_DOCUMENT\n           && code != ResXMLTree::BAD_DOCUMENT) {\n    }\n\n    size_t len;\n    if (code != ResXMLTree::START_TAG) {\n        fprintf(stderr, \"%s:%d: No start tag found\\n\",\n                file->getPrintableSource().string(), block.getLineNumber());\n        return UNKNOWN_ERROR;\n    }\n    if (strcmp16(block.getElementName(&len), String16(\"manifest\").string()) != 0) {\n        fprintf(stderr, \"%s:%d: Invalid start tag %s, expected <manifest>\\n\",\n                file->getPrintableSource().string(), block.getLineNumber(),\n                String8(block.getElementName(&len)).string());\n        return UNKNOWN_ERROR;\n    }\n\n    ssize_t nameIndex = block.indexOfAttribute(NULL, \"package\");\n    if (nameIndex < 0) {\n        fprintf(stderr, \"%s:%d: <manifest> does not have package attribute.\\n\",\n                file->getPrintableSource().string(), block.getLineNumber());\n        return UNKNOWN_ERROR;\n    }\n\n    assets->setPackage(String8(block.getAttributeStringValue(nameIndex, &len)));\n\n    String16 uses_sdk16(\"uses-sdk\");\n    while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n           && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::START_TAG) {\n            if (strcmp16(block.getElementName(&len), uses_sdk16.string()) == 0) {\n                ssize_t minSdkIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE,\n                                                             \"minSdkVersion\");\n                if (minSdkIndex >= 0) {\n                    const uint16_t* minSdk16 = block.getAttributeStringValue(minSdkIndex, &len);\n                    const char* minSdk8 = strdup(String8(minSdk16).string());\n                    bundle->setManifestMinSdkVersion(minSdk8);\n                }\n            }\n        }\n    }\n\n    return NO_ERROR;\n}\n\n// ==========================================================================\n// ==========================================================================\n// ==========================================================================\n\nstatic status_t makeFileResources(Bundle* bundle, const sp<AaptAssets>& assets,\n                                  ResourceTable* table,\n                                  const sp<ResourceTypeSet>& set,\n                                  const char* resType)\n{\n    String8 type8(resType);\n    String16 type16(resType);\n\n    bool hasErrors = false;\n\n    ResourceDirIterator it(set, String8(resType));\n    ssize_t res;\n    while ((res=it.next()) == NO_ERROR) {\n        if (bundle->getVerbose()) {\n            printf(\"    (new resource id %s from %s)\\n\",\n                   it.getBaseName().string(), it.getFile()->getPrintableSource().string());\n        }\n        String16 baseName(it.getBaseName());\n        const char16_t* str = baseName.string();\n        const char16_t* const end = str + baseName.size();\n        while (str < end) {\n            if (!((*str >= 'a' && *str <= 'z')\n                    || (*str >= '0' && *str <= '9')\n                    || *str == '_' || *str == '.')) {\n                fprintf(stderr, \"%s: Invalid file name: must contain only [a-z0-9_.]\\n\",\n                        it.getPath().string());\n                hasErrors = true;\n            }\n            str++;\n        }\n        String8 resPath = it.getPath();\n        resPath.convertToResPath();\n        table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()),\n                        type16,\n                        baseName,\n                        String16(resPath),\n                        NULL,\n                        &it.getParams());\n        assets->addResource(it.getLeafName(), resPath, it.getFile(), type8);\n    }\n\n    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;\n}\n\nclass PreProcessImageWorkUnit : public WorkQueue::WorkUnit {\npublic:\n    PreProcessImageWorkUnit(const Bundle* bundle, const sp<AaptAssets>& assets,\n            const sp<AaptFile>& file, volatile bool* hasErrors) :\n            mBundle(bundle), mAssets(assets), mFile(file), mHasErrors(hasErrors) {\n    }\n\n    virtual bool run() {\n        status_t status = preProcessImage(mBundle, mAssets, mFile, NULL);\n        if (status) {\n            *mHasErrors = true;\n        }\n        return true; // continue even if there are errors\n    }\n\nprivate:\n    const Bundle* mBundle;\n    sp<AaptAssets> mAssets;\n    sp<AaptFile> mFile;\n    volatile bool* mHasErrors;\n};\n\nstatic status_t preProcessImages(const Bundle* bundle, const sp<AaptAssets>& assets,\n                          const sp<ResourceTypeSet>& set, const char* type)\n{\n    volatile bool hasErrors = false;\n    ssize_t res = NO_ERROR;\n    if (bundle->getUseCrunchCache() == false) {\n        WorkQueue wq(MAX_THREADS, false);\n        ResourceDirIterator it(set, String8(type));\n        while ((res=it.next()) == NO_ERROR) {\n            PreProcessImageWorkUnit* w = new PreProcessImageWorkUnit(\n                    bundle, assets, it.getFile(), &hasErrors);\n            status_t status = wq.schedule(w);\n            if (status) {\n                fprintf(stderr, \"preProcessImages failed: schedule() returned %d\\n\", status);\n                hasErrors = true;\n                delete w;\n                break;\n            }\n        }\n        status_t status = wq.finish();\n        if (status) {\n            fprintf(stderr, \"preProcessImages failed: finish() returned %d\\n\", status);\n            hasErrors = true;\n        }\n    }\n    return (hasErrors || (res < NO_ERROR)) ? UNKNOWN_ERROR : NO_ERROR;\n}\n\nstatic void collect_files(const sp<AaptDir>& dir,\n        KeyedVector<String8, sp<ResourceTypeSet> >* resources)\n{\n    const DefaultKeyedVector<String8, sp<AaptGroup> >& groups = dir->getFiles();\n    int N = groups.size();\n    for (int i=0; i<N; i++) {\n        String8 leafName = groups.keyAt(i);\n        const sp<AaptGroup>& group = groups.valueAt(i);\n\n        const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files\n                = group->getFiles();\n\n        if (files.size() == 0) {\n            continue;\n        }\n\n        String8 resType = files.valueAt(0)->getResourceType();\n\n        ssize_t index = resources->indexOfKey(resType);\n\n        if (index < 0) {\n            sp<ResourceTypeSet> set = new ResourceTypeSet();\n            NOISY(printf(\"Creating new resource type set for leaf %s with group %s (%p)\\n\",\n                    leafName.string(), group->getPath().string(), group.get()));\n            set->add(leafName, group);\n            resources->add(resType, set);\n        } else {\n            sp<ResourceTypeSet> set = resources->valueAt(index);\n            index = set->indexOfKey(leafName);\n            if (index < 0) {\n                NOISY(printf(\"Adding to resource type set for leaf %s group %s (%p)\\n\",\n                        leafName.string(), group->getPath().string(), group.get()));\n                set->add(leafName, group);\n            } else {\n                sp<AaptGroup> existingGroup = set->valueAt(index);\n                NOISY(printf(\"Extending to resource type set for leaf %s group %s (%p)\\n\",\n                        leafName.string(), group->getPath().string(), group.get()));\n                for (size_t j=0; j<files.size(); j++) {\n                    NOISY(printf(\"Adding file %s in group %s resType %s\\n\",\n                        files.valueAt(j)->getSourceFile().string(),\n                        files.keyAt(j).toDirName(String8()).string(),\n                        resType.string()));\n                    status_t err = existingGroup->addFile(files.valueAt(j));\n                }\n            }\n        }\n    }\n}\n\nstatic void collect_files(const sp<AaptAssets>& ass,\n        KeyedVector<String8, sp<ResourceTypeSet> >* resources)\n{\n    const Vector<sp<AaptDir> >& dirs = ass->resDirs();\n    int N = dirs.size();\n\n    for (int i=0; i<N; i++) {\n        sp<AaptDir> d = dirs.itemAt(i);\n        NOISY(printf(\"Collecting dir #%d %p: %s, leaf %s\\n\", i, d.get(), d->getPath().string(),\n                d->getLeaf().string()));\n        collect_files(d, resources);\n\n        // don't try to include the res dir\n        NOISY(printf(\"Removing dir leaf %s\\n\", d->getLeaf().string()));\n        ass->removeDir(d->getLeaf());\n    }\n}\n\nenum {\n    ATTR_OKAY = -1,\n    ATTR_NOT_FOUND = -2,\n    ATTR_LEADING_SPACES = -3,\n    ATTR_TRAILING_SPACES = -4\n};\nstatic int validateAttr(const String8& path, const ResTable& table,\n        const ResXMLParser& parser,\n        const char* ns, const char* attr, const char* validChars, bool required)\n{\n    size_t len;\n\n    ssize_t index = parser.indexOfAttribute(ns, attr);\n    const uint16_t* str;\n    Res_value value;\n    if (index >= 0 && parser.getAttributeValue(index, &value) >= 0) {\n        const ResStringPool* pool = &parser.getStrings();\n        if (value.dataType == Res_value::TYPE_REFERENCE) {\n            uint32_t specFlags = 0;\n            int strIdx;\n            if ((strIdx=table.resolveReference(&value, 0x10000000, NULL, &specFlags)) < 0) {\n                fprintf(stderr, \"%s:%d: Tag <%s> attribute %s references unknown resid 0x%08x.\\n\",\n                        path.string(), parser.getLineNumber(),\n                        String8(parser.getElementName(&len)).string(), attr,\n                        value.data);\n                return ATTR_NOT_FOUND;\n            }\n            \n            pool = table.getTableStringBlock(strIdx);\n            #if 0\n            if (pool != NULL) {\n                str = pool->stringAt(value.data, &len);\n            }\n            printf(\"***** RES ATTR: %s specFlags=0x%x strIdx=%d: %s\\n\", attr,\n                    specFlags, strIdx, str != NULL ? String8(str).string() : \"???\");\n            #endif\n            if ((specFlags&~ResTable_typeSpec::SPEC_PUBLIC) != 0 && false) {\n                fprintf(stderr, \"%s:%d: Tag <%s> attribute %s varies by configurations 0x%x.\\n\",\n                        path.string(), parser.getLineNumber(),\n                        String8(parser.getElementName(&len)).string(), attr,\n                        specFlags);\n                return ATTR_NOT_FOUND;\n            }\n        }\n        if (value.dataType == Res_value::TYPE_STRING) {\n            if (pool == NULL) {\n                fprintf(stderr, \"%s:%d: Tag <%s> attribute %s has no string block.\\n\",\n                        path.string(), parser.getLineNumber(),\n                        String8(parser.getElementName(&len)).string(), attr);\n                return ATTR_NOT_FOUND;\n            }\n            if ((str=pool->stringAt(value.data, &len)) == NULL) {\n                fprintf(stderr, \"%s:%d: Tag <%s> attribute %s has corrupt string value.\\n\",\n                        path.string(), parser.getLineNumber(),\n                        String8(parser.getElementName(&len)).string(), attr);\n                return ATTR_NOT_FOUND;\n            }\n        } else {\n            fprintf(stderr, \"%s:%d: Tag <%s> attribute %s has invalid type %d.\\n\",\n                    path.string(), parser.getLineNumber(),\n                    String8(parser.getElementName(&len)).string(), attr,\n                    value.dataType);\n            return ATTR_NOT_FOUND;\n        }\n        if (validChars) {\n            for (size_t i=0; i<len; i++) {\n                uint16_t c = str[i];\n                const char* p = validChars;\n                bool okay = false;\n                while (*p) {\n                    if (c == *p) {\n                        okay = true;\n                        break;\n                    }\n                    p++;\n                }\n                if (!okay) {\n                    fprintf(stderr, \"%s:%d: Tag <%s> attribute %s has invalid character '%c'.\\n\",\n                            path.string(), parser.getLineNumber(),\n                            String8(parser.getElementName(&len)).string(), attr, (char)str[i]);\n                    return (int)i;\n                }\n            }\n        }\n        if (*str == ' ') {\n            fprintf(stderr, \"%s:%d: Tag <%s> attribute %s can not start with a space.\\n\",\n                    path.string(), parser.getLineNumber(),\n                    String8(parser.getElementName(&len)).string(), attr);\n            return ATTR_LEADING_SPACES;\n        }\n        if (str[len-1] == ' ') {\n            fprintf(stderr, \"%s:%d: Tag <%s> attribute %s can not end with a space.\\n\",\n                    path.string(), parser.getLineNumber(),\n                    String8(parser.getElementName(&len)).string(), attr);\n            return ATTR_TRAILING_SPACES;\n        }\n        return ATTR_OKAY;\n    }\n    if (required) {\n        fprintf(stderr, \"%s:%d: Tag <%s> missing required attribute %s.\\n\",\n                path.string(), parser.getLineNumber(),\n                String8(parser.getElementName(&len)).string(), attr);\n        return ATTR_NOT_FOUND;\n    }\n    return ATTR_OKAY;\n}\n\nstatic void checkForIds(const String8& path, ResXMLParser& parser)\n{\n    ResXMLTree::event_code_t code;\n    while ((code=parser.next()) != ResXMLTree::END_DOCUMENT\n           && code > ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::START_TAG) {\n            ssize_t index = parser.indexOfAttribute(NULL, \"id\");\n            if (index >= 0) {\n                fprintf(stderr, \"%s:%d: warning: found plain 'id' attribute; did you mean the new 'android:id' name?\\n\",\n                        path.string(), parser.getLineNumber());\n            }\n        }\n    }\n}\n\nstatic bool applyFileOverlay(Bundle *bundle,\n                             const sp<AaptAssets>& assets,\n                             sp<ResourceTypeSet> *baseSet,\n                             const char *resType)\n{\n    if (bundle->getVerbose()) {\n        printf(\"applyFileOverlay for %s\\n\", resType);\n    }\n\n    // Replace any base level files in this category with any found from the overlay\n    // Also add any found only in the overlay.\n    sp<AaptAssets> overlay = assets->getOverlay();\n    String8 resTypeString(resType);\n\n    // work through the linked list of overlays\n    while (overlay.get()) {\n        KeyedVector<String8, sp<ResourceTypeSet> >* overlayRes = overlay->getResources();\n\n        // get the overlay resources of the requested type\n        ssize_t index = overlayRes->indexOfKey(resTypeString);\n        if (index >= 0) {\n            sp<ResourceTypeSet> overlaySet = overlayRes->valueAt(index);\n\n            // for each of the resources, check for a match in the previously built\n            // non-overlay \"baseset\".\n            size_t overlayCount = overlaySet->size();\n            for (size_t overlayIndex=0; overlayIndex<overlayCount; overlayIndex++) {\n                if (bundle->getVerbose()) {\n                    printf(\"trying overlaySet Key=%s\\n\",overlaySet->keyAt(overlayIndex).string());\n                }\n                ssize_t baseIndex = -1;\n                if (baseSet->get() != NULL) {\n                    baseIndex = (*baseSet)->indexOfKey(overlaySet->keyAt(overlayIndex));\n                }\n                if (baseIndex >= 0) {\n                    // look for same flavor.  For a given file (strings.xml, for example)\n                    // there may be a locale specific or other flavors - we want to match\n                    // the same flavor.\n                    sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex);\n                    sp<AaptGroup> baseGroup = (*baseSet)->valueAt(baseIndex);\n\n                    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =\n                            overlayGroup->getFiles();\n                    if (bundle->getVerbose()) {\n                        DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > baseFiles =\n                                baseGroup->getFiles();\n                        for (size_t i=0; i < baseFiles.size(); i++) {\n                            printf(\"baseFile \" ZD \" has flavor %s\\n\", (ZD_TYPE) i,\n                                    baseFiles.keyAt(i).toString().string());\n                        }\n                        for (size_t i=0; i < overlayFiles.size(); i++) {\n                            printf(\"overlayFile \" ZD \" has flavor %s\\n\", (ZD_TYPE) i,\n                                    overlayFiles.keyAt(i).toString().string());\n                        }\n                    }\n\n                    size_t overlayGroupSize = overlayFiles.size();\n                    for (size_t overlayGroupIndex = 0;\n                            overlayGroupIndex<overlayGroupSize;\n                            overlayGroupIndex++) {\n                        ssize_t baseFileIndex =\n                                baseGroup->getFiles().indexOfKey(overlayFiles.\n                                keyAt(overlayGroupIndex));\n                        if (baseFileIndex >= 0) {\n                            if (bundle->getVerbose()) {\n                                printf(\"found a match (\" ZD \") for overlay file %s, for flavor %s\\n\",\n                                        (ZD_TYPE) baseFileIndex,\n                                        overlayGroup->getLeaf().string(),\n                                        overlayFiles.keyAt(overlayGroupIndex).toString().string());\n                            }\n                            baseGroup->removeFile(baseFileIndex);\n                        } else {\n                            // didn't find a match fall through and add it..\n                            if (true || bundle->getVerbose()) {\n                                printf(\"nothing matches overlay file %s, for flavor %s\\n\",\n                                        overlayGroup->getLeaf().string(),\n                                        overlayFiles.keyAt(overlayGroupIndex).toString().string());\n                            }\n                        }\n                        baseGroup->addFile(overlayFiles.valueAt(overlayGroupIndex));\n                        assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));\n                    }\n                } else {\n                    if (baseSet->get() == NULL) {\n                        *baseSet = new ResourceTypeSet();\n                        assets->getResources()->add(String8(resType), *baseSet);\n                    }\n                    // this group doesn't exist (a file that's only in the overlay)\n                    (*baseSet)->add(overlaySet->keyAt(overlayIndex),\n                            overlaySet->valueAt(overlayIndex));\n                    // make sure all flavors are defined in the resources.\n                    sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex);\n                    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =\n                            overlayGroup->getFiles();\n                    size_t overlayGroupSize = overlayFiles.size();\n                    for (size_t overlayGroupIndex = 0;\n                            overlayGroupIndex<overlayGroupSize;\n                            overlayGroupIndex++) {\n                        assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));\n                    }\n                }\n            }\n            // this overlay didn't have resources for this type\n        }\n        // try next overlay\n        overlay = overlay->getOverlay();\n    }\n    return true;\n}\n\n/*\n * Inserts an attribute in a given node.\n * If errorOnFailedInsert is true, and the attribute already exists, returns false.\n * If replaceExisting is true, the attribute will be updated if it already exists.\n * Returns true otherwise, even if the attribute already exists, and does not modify\n * the existing attribute's value.\n */\nbool addTagAttribute(const sp<XMLNode>& node, const char* ns8,\n        const char* attr8, const char* value, bool errorOnFailedInsert,\n        bool replaceExisting)\n{\n    if (value == NULL) {\n        return true;\n    }\n\n    const String16 ns(ns8);\n    const String16 attr(attr8);\n\n    XMLNode::attribute_entry* existingEntry = node->editAttribute(ns, attr);\n    if (existingEntry != NULL) {\n        if (replaceExisting) {\n            NOISY(printf(\"Info: AndroidManifest.xml already defines %s (in %s);\"\n                         \" overwriting existing value from manifest.\\n\",\n                         String8(attr).string(), String8(ns).string()));\n            existingEntry->string = String16(value);\n            return true;\n        }\n\n        if (errorOnFailedInsert) {\n            fprintf(stderr, \"Error: AndroidManifest.xml already defines %s (in %s);\"\n                            \" cannot insert new value %s.\\n\",\n                    String8(attr).string(), String8(ns).string(), value);\n            return false;\n        }\n\n        fprintf(stderr, \"Warning: AndroidManifest.xml already defines %s (in %s);\"\n                        \" using existing value in manifest.\\n\",\n                String8(attr).string(), String8(ns).string());\n\n        // don't stop the build.\n        return true;\n    }\n    \n    node->addAttribute(ns, attr, String16(value));\n    return true;\n}\n\n/*\n * Inserts an attribute in a given node, only if the attribute does not\n * exist.\n * If errorOnFailedInsert is true, and the attribute already exists, returns false.\n * Returns true otherwise, even if the attribute already exists.\n */\nbool addTagAttribute(const sp<XMLNode>& node, const char* ns8,\n        const char* attr8, const char* value, bool errorOnFailedInsert)\n{\n    return addTagAttribute(node, ns8, attr8, value, errorOnFailedInsert, false);\n}\n\nstatic void fullyQualifyClassName(const String8& package, sp<XMLNode> node,\n        const String16& attrName) {\n    XMLNode::attribute_entry* attr = node->editAttribute(\n            String16(\"http://schemas.android.com/apk/res/android\"), attrName);\n    if (attr != NULL) {\n        String8 name(attr->string);\n\n        // asdf     --> package.asdf\n        // .asdf  .a.b  --> package.asdf package.a.b\n        // asdf.adsf --> asdf.asdf\n        String8 className;\n        const char* p = name.string();\n        const char* q = strchr(p, '.');\n        if (p == q) {\n            className += package;\n            className += name;\n        } else if (q == NULL) {\n            className += package;\n            className += \".\";\n            className += name;\n        } else {\n            className += name;\n        }\n        NOISY(printf(\"Qualifying class '%s' to '%s'\", name.string(), className.string()));\n        attr->string.setTo(String16(className));\n    }\n}\n\nstatus_t massageManifest(Bundle* bundle, sp<XMLNode> root)\n{\n    root = root->searchElement(String16(), String16(\"manifest\"));\n    if (root == NULL) {\n        fprintf(stderr, \"No <manifest> tag.\\n\");\n        return UNKNOWN_ERROR;\n    }\n\n    bool errorOnFailedInsert = bundle->getErrorOnFailedInsert();\n    bool replaceVersion = bundle->getReplaceVersion();\n\n    if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, \"versionCode\",\n            bundle->getVersionCode(), errorOnFailedInsert, replaceVersion)) {\n        return UNKNOWN_ERROR;\n    } else {\n        const XMLNode::attribute_entry* attr = root->getAttribute(\n                String16(RESOURCES_ANDROID_NAMESPACE), String16(\"versionCode\"));\n        if (attr != NULL) {\n            bundle->setVersionCode(strdup(String8(attr->string).string()));\n        }\n    }\n\n    if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, \"versionName\",\n            bundle->getVersionName(), errorOnFailedInsert, replaceVersion)) {\n        return UNKNOWN_ERROR;\n    } else {\n        const XMLNode::attribute_entry* attr = root->getAttribute(\n                String16(RESOURCES_ANDROID_NAMESPACE), String16(\"versionName\"));\n        if (attr != NULL) {\n            bundle->setVersionName(strdup(String8(attr->string).string()));\n        }\n    }\n    \n    sp<XMLNode> vers = root->getChildElement(String16(), String16(\"uses-sdk\"));\n    if (bundle->getMinSdkVersion() != NULL\n            || bundle->getTargetSdkVersion() != NULL\n            || bundle->getMaxSdkVersion() != NULL) {\n        if (vers == NULL) {\n            vers = XMLNode::newElement(root->getFilename(), String16(), String16(\"uses-sdk\"));\n            root->insertChildAt(vers, 0);\n        }\n        \n        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, \"minSdkVersion\",\n                bundle->getMinSdkVersion(), errorOnFailedInsert)) {\n            return UNKNOWN_ERROR;\n        }\n        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, \"targetSdkVersion\",\n                bundle->getTargetSdkVersion(), errorOnFailedInsert)) {\n            return UNKNOWN_ERROR;\n        }\n        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, \"maxSdkVersion\",\n                bundle->getMaxSdkVersion(), errorOnFailedInsert)) {\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    if (vers != NULL) {\n        const XMLNode::attribute_entry* attr = vers->getAttribute(\n                String16(RESOURCES_ANDROID_NAMESPACE), String16(\"minSdkVersion\"));\n        if (attr != NULL) {\n            bundle->setMinSdkVersion(strdup(String8(attr->string).string()));\n        }\n    }\n\n    if (bundle->getPlatformBuildVersionCode() != \"\") {\n        if (!addTagAttribute(root, \"\", \"platformBuildVersionCode\",\n                    bundle->getPlatformBuildVersionCode(), errorOnFailedInsert, true)) {\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    if (bundle->getPlatformBuildVersionName() != \"\") {\n        if (!addTagAttribute(root, \"\", \"platformBuildVersionName\",\n                    bundle->getPlatformBuildVersionName(), errorOnFailedInsert, true)) {\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    if (bundle->getDebugMode()) {\n        sp<XMLNode> application = root->getChildElement(String16(), String16(\"application\"));\n        if (application != NULL) {\n            if (!addTagAttribute(application, RESOURCES_ANDROID_NAMESPACE, \"debuggable\", \"true\",\n                    errorOnFailedInsert)) {\n                return UNKNOWN_ERROR;\n            }\n        }\n    }\n\n    // Deal with manifest package name overrides\n    const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride();\n    if (manifestPackageNameOverride != NULL) {\n        // Update the actual package name\n        XMLNode::attribute_entry* attr = root->editAttribute(String16(), String16(\"package\"));\n        if (attr == NULL) {\n            fprintf(stderr, \"package name is required with --rename-manifest-package.\\n\");\n            return UNKNOWN_ERROR;\n        }\n        String8 origPackage(attr->string);\n        attr->string.setTo(String16(manifestPackageNameOverride));\n        NOISY(printf(\"Overriding package '%s' to be '%s'\\n\", origPackage.string(), manifestPackageNameOverride));\n\n        // Make class names fully qualified\n        sp<XMLNode> application = root->getChildElement(String16(), String16(\"application\"));\n        if (application != NULL) {\n            fullyQualifyClassName(origPackage, application, String16(\"name\"));\n            fullyQualifyClassName(origPackage, application, String16(\"backupAgent\"));\n\n            Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(application->getChildren());\n            for (size_t i = 0; i < children.size(); i++) {\n                sp<XMLNode> child = children.editItemAt(i);\n                String8 tag(child->getElementName());\n                if (tag == \"activity\" || tag == \"service\" || tag == \"receiver\" || tag == \"provider\") {\n                    fullyQualifyClassName(origPackage, child, String16(\"name\"));\n                } else if (tag == \"activity-alias\") {\n                    fullyQualifyClassName(origPackage, child, String16(\"name\"));\n                    fullyQualifyClassName(origPackage, child, String16(\"targetActivity\"));\n                }\n            }\n        }\n    }\n\n    // Deal with manifest package name overrides\n    const char* instrumentationPackageNameOverride = bundle->getInstrumentationPackageNameOverride();\n    if (instrumentationPackageNameOverride != NULL) {\n        // Fix up instrumentation targets.\n        Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(root->getChildren());\n        for (size_t i = 0; i < children.size(); i++) {\n            sp<XMLNode> child = children.editItemAt(i);\n            String8 tag(child->getElementName());\n            if (tag == \"instrumentation\") {\n                XMLNode::attribute_entry* attr = child->editAttribute(\n                        String16(\"http://schemas.android.com/apk/res/android\"), String16(\"targetPackage\"));\n                if (attr != NULL) {\n                    attr->string.setTo(String16(instrumentationPackageNameOverride));\n                }\n            }\n        }\n    }\n    \n    // Generate split name if feature is present.\n    const XMLNode::attribute_entry* attr = root->getAttribute(String16(), String16(\"featureName\"));\n    if (attr != NULL) {\n        String16 splitName(\"feature_\");\n        splitName.append(attr->string);\n        status_t err = root->addAttribute(String16(), String16(\"split\"), splitName);\n        if (err != NO_ERROR) {\n            ALOGE(\"Failed to insert split name into AndroidManifest.xml\");\n            return err;\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatic int32_t getPlatformAssetCookie(const AssetManager& assets) {\n    // Find the system package (0x01). AAPT always generates attributes\n    // with the type 0x01, so we're looking for the first attribute\n    // resource in the system package.\n    const ResTable& table = assets.getResources(true);\n    Res_value val;\n    ssize_t idx = table.getResource(0x01010000, &val, true);\n    if (idx != NO_ERROR) {\n        // Try as a bag.\n        const ResTable::bag_entry* entry;\n        ssize_t cnt = table.lockBag(0x01010000, &entry);\n        if (cnt >= 0) {\n            idx = entry->stringBlock;\n        }\n        table.unlockBag(entry);\n    }\n\n    if (idx < 0) {\n        return 0;\n    }\n    return table.getTableCookie(idx);\n}\n\nenum {\n    VERSION_CODE_ATTR = 0x0101021b,\n    VERSION_NAME_ATTR = 0x0101021c,\n};\n\nstatic ssize_t extractPlatformBuildVersion(ResXMLTree& tree, Bundle* bundle) {\n    size_t len;\n    ResXMLTree::event_code_t code;\n    while ((code = tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code != ResXMLTree::START_TAG) {\n            continue;\n        }\n\n        const char16_t* ctag16 = tree.getElementName(&len);\n        if (ctag16 == NULL) {\n            fprintf(stderr, \"ERROR: failed to get XML element name (bad string pool)\\n\");\n            return UNKNOWN_ERROR;\n        }\n\n        String8 tag(ctag16, len);\n        if (tag != \"manifest\") {\n            continue;\n        }\n\n        String8 error;\n        int32_t versionCode = AaptXml::getIntegerAttribute(tree, VERSION_CODE_ATTR, &error);\n        if (error != \"\") {\n            fprintf(stderr, \"ERROR: failed to get platform version code\\n\");\n            return UNKNOWN_ERROR;\n        }\n\n        if (versionCode >= 0 && bundle->getPlatformBuildVersionCode() == \"\") {\n            bundle->setPlatformBuildVersionCode(String8::format(\"%d\", versionCode));\n        }\n\n        String8 versionName = AaptXml::getAttribute(tree, VERSION_NAME_ATTR, &error);\n        if (error != \"\") {\n            fprintf(stderr, \"ERROR: failed to get platform version name\\n\");\n            return UNKNOWN_ERROR;\n        }\n\n        if (versionName != \"\" && bundle->getPlatformBuildVersionName() == \"\") {\n            bundle->setPlatformBuildVersionName(versionName);\n        }\n        return NO_ERROR;\n    }\n\n    fprintf(stderr, \"ERROR: no <manifest> tag found in platform AndroidManifest.xml\\n\");\n    return UNKNOWN_ERROR;\n}\n\nstatic ssize_t extractPlatformBuildVersion(AssetManager& assets, Bundle* bundle) {\n    int32_t cookie = getPlatformAssetCookie(assets);\n    if (cookie == 0) {\n        // No platform was loaded.\n        return NO_ERROR;\n    }\n\n    ResXMLTree tree;\n    Asset* asset = assets.openNonAsset(cookie, \"AndroidManifest.xml\", Asset::ACCESS_STREAMING);\n    if (asset == NULL) {\n        fprintf(stderr, \"ERROR: Platform AndroidManifest.xml not found\\n\");\n        return UNKNOWN_ERROR;\n    }\n\n    ssize_t result = NO_ERROR;\n    if (tree.setTo(asset->getBuffer(true), asset->getLength()) != NO_ERROR) {\n        fprintf(stderr, \"ERROR: Platform AndroidManifest.xml is corrupt\\n\");\n        result = UNKNOWN_ERROR;\n    } else {\n        result = extractPlatformBuildVersion(tree, bundle);\n    }\n\n    delete asset;\n    return result;\n}\n\n#define ASSIGN_IT(n) \\\n        do { \\\n            ssize_t index = resources->indexOfKey(String8(#n)); \\\n            if (index >= 0) { \\\n                n ## s = resources->valueAt(index); \\\n            } \\\n        } while (0)\n\nstatus_t updatePreProcessedCache(Bundle* bundle)\n{\n    #if BENCHMARK\n    fprintf(stdout, \"BENCHMARK: Starting PNG PreProcessing \\n\");\n    long startPNGTime = clock();\n    #endif /* BENCHMARK */\n\n    String8 source(bundle->getResourceSourceDirs()[0]);\n    String8 dest(bundle->getCrunchedOutputDir());\n\n    FileFinder* ff = new SystemFileFinder();\n    CrunchCache cc(source,dest,ff);\n\n    CacheUpdater* cu = new SystemCacheUpdater(bundle);\n    size_t numFiles = cc.crunch(cu);\n\n    if (bundle->getVerbose())\n        fprintf(stdout, \"Crunched %d PNG files to update cache\\n\", (int)numFiles);\n\n    delete ff;\n    delete cu;\n\n    #if BENCHMARK\n    fprintf(stdout, \"BENCHMARK: End PNG PreProcessing. Time Elapsed: %f ms \\n\"\n            ,(clock() - startPNGTime)/1000.0);\n    #endif /* BENCHMARK */\n    return 0;\n}\n\nstatus_t generateAndroidManifestForSplit(Bundle* bundle, const sp<AaptAssets>& assets,\n        const sp<ApkSplit>& split, sp<AaptFile>& outFile, ResourceTable* table) {\n    const String8 filename(\"AndroidManifest.xml\");\n    const String16 androidPrefix(\"android\");\n    const String16 androidNSUri(\"http://schemas.android.com/apk/res/android\");\n    sp<XMLNode> root = XMLNode::newNamespace(filename, androidPrefix, androidNSUri);\n\n    // Build the <manifest> tag\n    sp<XMLNode> manifest = XMLNode::newElement(filename, String16(), String16(\"manifest\"));\n\n    // Add the 'package' attribute which is set to the package name.\n    const char* packageName = assets->getPackage();\n    const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride();\n    if (manifestPackageNameOverride != NULL) {\n        packageName = manifestPackageNameOverride;\n    }\n    manifest->addAttribute(String16(), String16(\"package\"), String16(packageName));\n\n    // Add the 'versionCode' attribute which is set to the original version code.\n    if (!addTagAttribute(manifest, RESOURCES_ANDROID_NAMESPACE, \"versionCode\",\n            bundle->getVersionCode(), true, true)) {\n        return UNKNOWN_ERROR;\n    }\n\n    // Add the 'split' attribute which describes the configurations included.\n    String8 splitName(\"config.\");\n    splitName.append(split->getPackageSafeName());\n    manifest->addAttribute(String16(), String16(\"split\"), String16(splitName));\n\n    // Build an empty <application> tag (required).\n    sp<XMLNode> app = XMLNode::newElement(filename, String16(), String16(\"application\"));\n\n    // Add the 'hasCode' attribute which is never true for resource splits.\n    if (!addTagAttribute(app, RESOURCES_ANDROID_NAMESPACE, \"hasCode\",\n            \"false\", true, true)) {\n        return UNKNOWN_ERROR;\n    }\n\n    manifest->addChild(app);\n    root->addChild(manifest);\n\n    int err = compileXmlFile(bundle, assets, String16(), root, outFile, table);\n    if (err < NO_ERROR) {\n        return err;\n    }\n    outFile->setCompressionMethod(ZipEntry::kCompressDeflated);\n    return NO_ERROR;\n}\n\nstatus_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuilder>& builder)\n{\n    // First, look for a package file to parse.  This is required to\n    // be able to generate the resource information.\n    sp<AaptGroup> androidManifestFile =\n            assets->getFiles().valueFor(String8(\"AndroidManifest.xml\"));\n    if (androidManifestFile == NULL) {\n        fprintf(stderr, \"ERROR: No AndroidManifest.xml file found.\\n\");\n        return UNKNOWN_ERROR;\n    }\n\n    status_t err = parsePackage(bundle, assets, androidManifestFile);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    NOISY(printf(\"Creating resources for package %s\\n\",\n                 assets->getPackage().string()));\n\n    ResourceTable::PackageType packageType = ResourceTable::App;\n    if (bundle->getBuildSharedLibrary()) {\n        packageType = ResourceTable::SharedLibrary;\n    } else if (bundle->getExtending()) {\n        packageType = ResourceTable::System;\n    } else if (!bundle->getFeatureOfPackage().isEmpty()) {\n        packageType = ResourceTable::AppFeature;\n    }\n\n    ResourceTable table(bundle, String16(assets->getPackage()), packageType, bundle->getTypeIdOffset());\n    err = table.addIncludedResources(bundle, assets);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    NOISY(printf(\"Found %d included resource packages\\n\", (int)table.size()));\n\n    // Standard flags for compiled XML and optional UTF-8 encoding\n    int xmlFlags = XML_COMPILE_STANDARD_RESOURCE;\n\n    /* Only enable UTF-8 if the caller of aapt didn't specifically\n     * request UTF-16 encoding and the parameters of this package\n     * allow UTF-8 to be used.\n     */\n    if (!bundle->getUTF16StringsOption()) {\n        xmlFlags |= XML_COMPILE_UTF8;\n    }\n\n    // --------------------------------------------------------------\n    // First, gather all resource information.\n    // --------------------------------------------------------------\n\n    // resType -> leafName -> group\n    KeyedVector<String8, sp<ResourceTypeSet> > *resources = \n            new KeyedVector<String8, sp<ResourceTypeSet> >;\n    collect_files(assets, resources);\n\n    sp<ResourceTypeSet> drawables;\n    sp<ResourceTypeSet> layouts;\n    sp<ResourceTypeSet> anims;\n    sp<ResourceTypeSet> animators;\n    sp<ResourceTypeSet> interpolators;\n    sp<ResourceTypeSet> transitions;\n    sp<ResourceTypeSet> xmls;\n    sp<ResourceTypeSet> raws;\n    sp<ResourceTypeSet> colors;\n    sp<ResourceTypeSet> menus;\n    sp<ResourceTypeSet> mipmaps;\n\n    ASSIGN_IT(drawable);\n    ASSIGN_IT(layout);\n    ASSIGN_IT(anim);\n    ASSIGN_IT(animator);\n    ASSIGN_IT(interpolator);\n    ASSIGN_IT(transition);\n    ASSIGN_IT(xml);\n    ASSIGN_IT(raw);\n    ASSIGN_IT(color);\n    ASSIGN_IT(menu);\n    ASSIGN_IT(mipmap);\n\n    assets->setResources(resources);\n    // now go through any resource overlays and collect their files\n    sp<AaptAssets> current = assets->getOverlay();\n    while(current.get()) {\n        KeyedVector<String8, sp<ResourceTypeSet> > *resources = \n                new KeyedVector<String8, sp<ResourceTypeSet> >;\n        current->setResources(resources);\n        collect_files(current, resources);\n        current = current->getOverlay();\n    }\n    // apply the overlay files to the base set\n    if (!applyFileOverlay(bundle, assets, &drawables, \"drawable\") ||\n            !applyFileOverlay(bundle, assets, &layouts, \"layout\") ||\n            !applyFileOverlay(bundle, assets, &anims, \"anim\") ||\n            !applyFileOverlay(bundle, assets, &animators, \"animator\") ||\n            !applyFileOverlay(bundle, assets, &interpolators, \"interpolator\") ||\n            !applyFileOverlay(bundle, assets, &transitions, \"transition\") ||\n            !applyFileOverlay(bundle, assets, &xmls, \"xml\") ||\n            !applyFileOverlay(bundle, assets, &raws, \"raw\") ||\n            !applyFileOverlay(bundle, assets, &colors, \"color\") ||\n            !applyFileOverlay(bundle, assets, &menus, \"menu\") ||\n            !applyFileOverlay(bundle, assets, &mipmaps, \"mipmap\")) {\n        return UNKNOWN_ERROR;\n    }\n\n    bool hasErrors = false;\n\n    if (drawables != NULL) {\n        if (bundle->getOutputAPKFile() != NULL) {\n            err = preProcessImages(bundle, assets, drawables, \"drawable\");\n        }\n        if (err == NO_ERROR) {\n            err = makeFileResources(bundle, assets, &table, drawables, \"drawable\");\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        } else {\n            hasErrors = true;\n        }\n    }\n\n    if (mipmaps != NULL) {\n        if (bundle->getOutputAPKFile() != NULL) {\n            err = preProcessImages(bundle, assets, mipmaps, \"mipmap\");\n        }\n        if (err == NO_ERROR) {\n            err = makeFileResources(bundle, assets, &table, mipmaps, \"mipmap\");\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        } else {\n            hasErrors = true;\n        }\n    }\n\n    if (layouts != NULL) {\n        err = makeFileResources(bundle, assets, &table, layouts, \"layout\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (anims != NULL) {\n        err = makeFileResources(bundle, assets, &table, anims, \"anim\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (animators != NULL) {\n        err = makeFileResources(bundle, assets, &table, animators, \"animator\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (transitions != NULL) {\n        err = makeFileResources(bundle, assets, &table, transitions, \"transition\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (interpolators != NULL) {\n        err = makeFileResources(bundle, assets, &table, interpolators, \"interpolator\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (xmls != NULL) {\n        err = makeFileResources(bundle, assets, &table, xmls, \"xml\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (raws != NULL) {\n        err = makeFileResources(bundle, assets, &table, raws, \"raw\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    // compile resources\n    current = assets;\n    while(current.get()) {\n        KeyedVector<String8, sp<ResourceTypeSet> > *resources = \n                current->getResources();\n\n        ssize_t index = resources->indexOfKey(String8(\"values\"));\n        if (index >= 0) {\n            ResourceDirIterator it(resources->valueAt(index), String8(\"values\"));\n            ssize_t res;\n            while ((res=it.next()) == NO_ERROR) {\n                sp<AaptFile> file = it.getFile();\n                res = compileResourceFile(bundle, assets, file, it.getParams(), \n                                          (current!=assets), &table);\n                if (res != NO_ERROR) {\n                    hasErrors = true;\n                }\n            }\n        }\n        current = current->getOverlay();\n    }\n\n    if (colors != NULL) {\n        err = makeFileResources(bundle, assets, &table, colors, \"color\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    if (menus != NULL) {\n        err = makeFileResources(bundle, assets, &table, menus, \"menu\");\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    // --------------------------------------------------------------------\n    // Assignment of resource IDs and initial generation of resource table.\n    // --------------------------------------------------------------------\n\n    if (table.hasResources()) {\n        err = table.assignResourceIds(bundle);\n        if (err < NO_ERROR) {\n            return err;\n        }\n    }\n\n    // --------------------------------------------------------------\n    // Finally, we can now we can compile XML files, which may reference\n    // resources.\n    // --------------------------------------------------------------\n\n    if (layouts != NULL) {\n        ResourceDirIterator it(layouts, String8(\"layout\"));\n        while ((err=it.next()) == NO_ERROR) {\n            String8 src = it.getFile()->getPrintableSource();\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err == NO_ERROR) {\n                ResXMLTree block;\n                block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);\n                checkForIds(src, block);\n            } else {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (anims != NULL) {\n        ResourceDirIterator it(anims, String8(\"anim\"));\n        while ((err=it.next()) == NO_ERROR) {\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (animators != NULL) {\n        ResourceDirIterator it(animators, String8(\"animator\"));\n        while ((err=it.next()) == NO_ERROR) {\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (interpolators != NULL) {\n        ResourceDirIterator it(interpolators, String8(\"interpolator\"));\n        while ((err=it.next()) == NO_ERROR) {\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (transitions != NULL) {\n        ResourceDirIterator it(transitions, String8(\"transition\"));\n        while ((err=it.next()) == NO_ERROR) {\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (xmls != NULL) {\n        ResourceDirIterator it(xmls, String8(\"xml\"));\n        while ((err=it.next()) == NO_ERROR) {\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (drawables != NULL) {\n        ResourceDirIterator it(drawables, String8(\"drawable\"));\n        while ((err=it.next()) == NO_ERROR) {\n            err = postProcessImage(bundle, assets, &table, it.getFile());\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (colors != NULL) {\n        ResourceDirIterator it(colors, String8(\"color\"));\n        while ((err=it.next()) == NO_ERROR) {\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err != NO_ERROR) {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    if (menus != NULL) {\n        ResourceDirIterator it(menus, String8(\"menu\"));\n        while ((err=it.next()) == NO_ERROR) {\n            String8 src = it.getFile()->getPrintableSource();\n            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),\n                    it.getFile(), &table, xmlFlags);\n            if (err == NO_ERROR) {\n                ResXMLTree block;\n                block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);\n                checkForIds(src, block);\n            } else {\n                hasErrors = true;\n            }\n        }\n\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n        err = NO_ERROR;\n    }\n\n    // Now compile any generated resources.\n    std::queue<CompileResourceWorkItem>& workQueue = table.getWorkQueue();\n    while (!workQueue.empty()) {\n        CompileResourceWorkItem& workItem = workQueue.front();\n        err = compileXmlFile(bundle, assets, workItem.resourceName, workItem.file, &table, xmlFlags);\n        if (err == NO_ERROR) {\n            assets->addResource(workItem.resPath.getPathLeaf(),\n                    workItem.resPath,\n                    workItem.file,\n                    workItem.file->getResourceType());\n        } else {\n            hasErrors = true;\n        }\n        workQueue.pop();\n    }\n\n    if (table.validateLocalizations()) {\n        hasErrors = true;\n    }\n    \n    if (hasErrors) {\n        return UNKNOWN_ERROR;\n    }\n\n    // If we're not overriding the platform build versions,\n    // extract them from the platform APK.\n    if (packageType != ResourceTable::System &&\n            (bundle->getPlatformBuildVersionCode() == \"\" ||\n            bundle->getPlatformBuildVersionName() == \"\")) {\n        err = extractPlatformBuildVersion(assets->getAssetManager(), bundle);\n        if (err != NO_ERROR) {\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    const sp<AaptFile> manifestFile(androidManifestFile->getFiles().valueAt(0));\n    String8 manifestPath(manifestFile->getPrintableSource());\n\n    // Generate final compiled manifest file.\n    manifestFile->clearData();\n    sp<XMLNode> manifestTree = XMLNode::parse(manifestFile);\n    if (manifestTree == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    err = massageManifest(bundle, manifestTree);\n    if (err < NO_ERROR) {\n        return err;\n    }\n    err = compileXmlFile(bundle, assets, String16(), manifestTree, manifestFile, &table);\n    if (err < NO_ERROR) {\n        return err;\n    }\n\n    if (table.modifyForCompat(bundle) != NO_ERROR) {\n        return UNKNOWN_ERROR;\n    }\n\n    //block.restart();\n    //printXMLBlock(&block);\n\n    // --------------------------------------------------------------\n    // Generate the final resource table.\n    // Re-flatten because we may have added new resource IDs\n    // --------------------------------------------------------------\n\n    ResTable finalResTable;\n    sp<AaptFile> resFile;\n    \n    if (table.hasResources()) {\n        sp<AaptSymbols> symbols = assets->getSymbolsFor(String8(\"R\"));\n        err = table.addSymbols(symbols);\n        if (err < NO_ERROR) {\n            return err;\n        }\n\n        Vector<sp<ApkSplit> >& splits = builder->getSplits();\n        const size_t numSplits = splits.size();\n        for (size_t i = 0; i < numSplits; i++) {\n            sp<ApkSplit>& split = splits.editItemAt(i);\n            sp<AaptFile> flattenedTable = new AaptFile(String8(\"resources.arsc\"),\n                    AaptGroupEntry(), String8());\n            err = table.flatten(bundle, split->getResourceFilter(),\n                    flattenedTable, split->isBase());\n            if (err != NO_ERROR) {\n                fprintf(stderr, \"Failed to generate resource table for split '%s'\\n\",\n                        split->getPrintableName().string());\n                return err;\n            }\n            split->addEntry(String8(\"resources.arsc\"), flattenedTable);\n\n            if (split->isBase()) {\n                resFile = flattenedTable;\n                err = finalResTable.add(flattenedTable->getData(), flattenedTable->getSize());\n                if (err != NO_ERROR) {\n                    fprintf(stderr, \"Generated resource table is corrupt.\\n\");\n                    return err;\n                }\n            } else {\n                sp<AaptFile> generatedManifest = new AaptFile(String8(\"AndroidManifest.xml\"),\n                        AaptGroupEntry(), String8());\n                err = generateAndroidManifestForSplit(bundle, assets, split,\n                        generatedManifest, &table);\n                if (err != NO_ERROR) {\n                    fprintf(stderr, \"Failed to generate AndroidManifest.xml for split '%s'\\n\",\n                            split->getPrintableName().string());\n                    return err;\n                }\n                split->addEntry(String8(\"AndroidManifest.xml\"), generatedManifest);\n            }\n        }\n\n        if (bundle->getPublicOutputFile()) {\n            FILE* fp = fopen(bundle->getPublicOutputFile(), \"w+\");\n            if (fp == NULL) {\n                fprintf(stderr, \"ERROR: Unable to open public definitions output file %s: %s\\n\",\n                        (const char*)bundle->getPublicOutputFile(), strerror(errno));\n                return UNKNOWN_ERROR;\n            }\n            if (bundle->getVerbose()) {\n                printf(\"  Writing public definitions to %s.\\n\", bundle->getPublicOutputFile());\n            }\n            table.writePublicDefinitions(String16(assets->getPackage()), fp);\n            fclose(fp);\n        }\n\n        if (finalResTable.getTableCount() == 0 || resFile == NULL) {\n            fprintf(stderr, \"No resource table was generated.\\n\");\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    // Perform a basic validation of the manifest file.  This time we\n    // parse it with the comments intact, so that we can use them to\n    // generate java docs...  so we are not going to write this one\n    // back out to the final manifest data.\n    sp<AaptFile> outManifestFile = new AaptFile(manifestFile->getSourceFile(),\n            manifestFile->getGroupEntry(),\n            manifestFile->getResourceType());\n    err = compileXmlFile(bundle, assets, String16(), manifestFile,\n            outManifestFile, &table,\n            XML_COMPILE_ASSIGN_ATTRIBUTE_IDS\n            | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES);\n    if (err < NO_ERROR) {\n        return err;\n    }\n    ResXMLTree block;\n    block.setTo(outManifestFile->getData(), outManifestFile->getSize(), true);\n    String16 manifest16(\"manifest\");\n    String16 permission16(\"permission\");\n    String16 permission_group16(\"permission-group\");\n    String16 uses_permission16(\"uses-permission\");\n    String16 instrumentation16(\"instrumentation\");\n    String16 application16(\"application\");\n    String16 provider16(\"provider\");\n    String16 service16(\"service\");\n    String16 receiver16(\"receiver\");\n    String16 activity16(\"activity\");\n    String16 action16(\"action\");\n    String16 category16(\"category\");\n    String16 data16(\"scheme\");\n    String16 feature_group16(\"feature-group\");\n    String16 uses_feature16(\"uses-feature\");\n    const char* packageIdentChars = \"abcdefghijklmnopqrstuvwxyz\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789\";\n    const char* packageIdentCharsWithTheStupid = \"abcdefghijklmnopqrstuvwxyz\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-\";\n    const char* classIdentChars = \"abcdefghijklmnopqrstuvwxyz\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789$\";\n    const char* processIdentChars = \"abcdefghijklmnopqrstuvwxyz\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:\";\n    const char* authoritiesIdentChars = \"abcdefghijklmnopqrstuvwxyz\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-:;\";\n    const char* typeIdentChars = \"abcdefghijklmnopqrstuvwxyz\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:-/*+\";\n    const char* schemeIdentChars = \"abcdefghijklmnopqrstuvwxyz\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-\";\n    ResXMLTree::event_code_t code;\n    sp<AaptSymbols> permissionSymbols;\n    sp<AaptSymbols> permissionGroupSymbols;\n    while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n           && code > ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::START_TAG) {\n            size_t len;\n            if (block.getElementNamespace(&len) != NULL) {\n                continue;\n            }\n            if (strcmp16(block.getElementName(&len), manifest16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block, NULL, \"package\",\n                                 packageIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,\n                                 \"sharedUserId\", packageIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), permission16.string()) == 0\n                    || strcmp16(block.getElementName(&len), permission_group16.string()) == 0) {\n                const bool isGroup = strcmp16(block.getElementName(&len),\n                        permission_group16.string()) == 0;\n                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,\n                                 \"name\", isGroup ? packageIdentCharsWithTheStupid\n                                 : packageIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                SourcePos srcPos(manifestPath, block.getLineNumber());\n                sp<AaptSymbols> syms;\n                if (!isGroup) {\n                    syms = permissionSymbols;\n                    if (syms == NULL) {\n                        sp<AaptSymbols> symbols =\n                                assets->getSymbolsFor(String8(\"Manifest\"));\n                        syms = permissionSymbols = symbols->addNestedSymbol(\n                                String8(\"permission\"), srcPos);\n                    }\n                } else {\n                    syms = permissionGroupSymbols;\n                    if (syms == NULL) {\n                        sp<AaptSymbols> symbols =\n                                assets->getSymbolsFor(String8(\"Manifest\"));\n                        syms = permissionGroupSymbols = symbols->addNestedSymbol(\n                                String8(\"permission_group\"), srcPos);\n                    }\n                }\n                size_t len;\n                ssize_t index = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, \"name\");\n                const uint16_t* id = block.getAttributeStringValue(index, &len);\n                if (id == NULL) {\n                    fprintf(stderr, \"%s:%d: missing name attribute in element <%s>.\\n\", \n                            manifestPath.string(), block.getLineNumber(),\n                            String8(block.getElementName(&len)).string());\n                    hasErrors = true;\n                    break;\n                }\n                String8 idStr(id);\n                char* p = idStr.lockBuffer(idStr.size());\n                char* e = p + idStr.size();\n                bool begins_with_digit = true;  // init to true so an empty string fails\n                while (e > p) {\n                    e--;\n                    if (*e >= '0' && *e <= '9') {\n                      begins_with_digit = true;\n                      continue;\n                    }\n                    if ((*e >= 'a' && *e <= 'z') ||\n                        (*e >= 'A' && *e <= 'Z') ||\n                        (*e == '_')) {\n                      begins_with_digit = false;\n                      continue;\n                    }\n                    if (isGroup && (*e == '-')) {\n                        *e = '_';\n                        begins_with_digit = false;\n                        continue;\n                    }\n                    e++;\n                    break;\n                }\n                idStr.unlockBuffer();\n                // verify that we stopped because we hit a period or\n                // the beginning of the string, and that the\n                // identifier didn't begin with a digit.\n                if (begins_with_digit || (e != p && *(e-1) != '.')) {\n                  fprintf(stderr,\n                          \"%s:%d: Permission name <%s> is not a valid Java symbol\\n\",\n                          manifestPath.string(), block.getLineNumber(), idStr.string());\n                  hasErrors = true;\n                }\n                syms->addStringSymbol(String8(e), idStr, srcPos);\n                const uint16_t* cmt = block.getComment(&len);\n                if (cmt != NULL && *cmt != 0) {\n                    //printf(\"Comment of %s: %s\\n\", String8(e).string(),\n                    //        String8(cmt).string());\n                    syms->appendComment(String8(e), String16(cmt), srcPos);\n                } else {\n                    //printf(\"No comment for %s\\n\", String8(e).string());\n                }\n                syms->makeSymbolPublic(String8(e), srcPos);\n            } else if (strcmp16(block.getElementName(&len), uses_permission16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,\n                                 \"name\", packageIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), instrumentation16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,\n                                 \"name\", classIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"targetPackage\",\n                                 packageIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), application16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,\n                                 \"name\", classIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"permission\",\n                                 packageIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"process\",\n                                 processIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"taskAffinity\",\n                                 processIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), provider16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,\n                                 \"name\", classIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"authorities\",\n                                 authoritiesIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"permission\",\n                                 packageIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"process\",\n                                 processIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), service16.string()) == 0\n                       || strcmp16(block.getElementName(&len), receiver16.string()) == 0\n                       || strcmp16(block.getElementName(&len), activity16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,\n                                 \"name\", classIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"permission\",\n                                 packageIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"process\",\n                                 processIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"taskAffinity\",\n                                 processIdentChars, false) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), action16.string()) == 0\n                       || strcmp16(block.getElementName(&len), category16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"name\",\n                                 packageIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), data16.string()) == 0) {\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"mimeType\",\n                                 typeIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n                if (validateAttr(manifestPath, finalResTable, block,\n                                 RESOURCES_ANDROID_NAMESPACE, \"scheme\",\n                                 schemeIdentChars, true) != ATTR_OKAY) {\n                    hasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), feature_group16.string()) == 0) {\n                int depth = 1;\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n                       && code > ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::START_TAG) {\n                        depth++;\n                        if (strcmp16(block.getElementName(&len), uses_feature16.string()) == 0) {\n                            ssize_t idx = block.indexOfAttribute(\n                                    RESOURCES_ANDROID_NAMESPACE, \"required\");\n                            if (idx < 0) {\n                                continue;\n                            }\n\n                            int32_t data = block.getAttributeData(idx);\n                            if (data == 0) {\n                                fprintf(stderr, \"%s:%d: Tag <uses-feature> can not have \"\n                                        \"android:required=\\\"false\\\" when inside a \"\n                                        \"<feature-group> tag.\\n\",\n                                        manifestPath.string(), block.getLineNumber());\n                                hasErrors = true;\n                            }\n                        }\n                    } else if (code == ResXMLTree::END_TAG) {\n                        depth--;\n                        if (depth == 0) {\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    if (hasErrors) {\n        return UNKNOWN_ERROR;\n    }\n\n    if (resFile != NULL) {\n        // These resources are now considered to be a part of the included\n        // resources, for others to reference.\n        err = assets->addIncludedResources(resFile);\n        if (err < NO_ERROR) {\n            fprintf(stderr, \"ERROR: Unable to parse generated resources, aborting.\\n\");\n            return err;\n        }\n    }\n    \n    return err;\n}\n\nstatic const char* getIndentSpace(int indent)\n{\nstatic const char whitespace[] =\n\"                                                                                       \";\n\n    return whitespace + sizeof(whitespace) - 1 - indent*4;\n}\n\nstatic String8 flattenSymbol(const String8& symbol) {\n    String8 result(symbol);\n    ssize_t first;\n    if ((first = symbol.find(\":\", 0)) >= 0\n            || (first = symbol.find(\".\", 0)) >= 0) {\n        size_t size = symbol.size();\n        char* buf = result.lockBuffer(size);\n        for (size_t i = first; i < size; i++) {\n            if (buf[i] == ':' || buf[i] == '.') {\n                buf[i] = '_';\n            }\n        }\n        result.unlockBuffer(size);\n    }\n    return result;\n}\n\nstatic String8 getSymbolPackage(const String8& symbol, const sp<AaptAssets>& assets, bool pub) {\n    ssize_t colon = symbol.find(\":\", 0);\n    if (colon >= 0) {\n        return String8(symbol.string(), colon);\n    }\n    return pub ? assets->getPackage() : assets->getSymbolsPrivatePackage();\n}\n\nstatic String8 getSymbolName(const String8& symbol) {\n    ssize_t colon = symbol.find(\":\", 0);\n    if (colon >= 0) {\n        return String8(symbol.string() + colon + 1);\n    }\n    return symbol;\n}\n\nstatic String16 getAttributeComment(const sp<AaptAssets>& assets,\n                                    const String8& name,\n                                    String16* outTypeComment = NULL)\n{\n    sp<AaptSymbols> asym = assets->getSymbolsFor(String8(\"R\"));\n    if (asym != NULL) {\n        //printf(\"Got R symbols!\\n\");\n        asym = asym->getNestedSymbols().valueFor(String8(\"attr\"));\n        if (asym != NULL) {\n            //printf(\"Got attrs symbols! comment %s=%s\\n\",\n            //     name.string(), String8(asym->getComment(name)).string());\n            if (outTypeComment != NULL) {\n                *outTypeComment = asym->getTypeComment(name);\n            }\n            return asym->getComment(name);\n        }\n    }\n    return String16();\n}\n\nstatic status_t writeResourceLoadedCallbackForLayoutClasses(\n    FILE* fp, const sp<AaptAssets>& assets,\n    const sp<AaptSymbols>& symbols, int indent, bool includePrivate)\n{\n    String16 attr16(\"attr\");\n    String16 package16(assets->getPackage());\n\n    const char* indentStr = getIndentSpace(indent);\n    bool hasErrors = false;\n\n    size_t i;\n    size_t N = symbols->getNestedSymbols().size();\n    for (i=0; i<N; i++) {\n        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);\n        String8 realClassName(symbols->getNestedSymbols().keyAt(i));\n        String8 nclassName(flattenSymbol(realClassName));\n\n        fprintf(fp,\n                \"%sfor(int i = 0; i < styleable.%s.length; ++i) {\\n\"\n                \"%sstyleable.%s[i] = (styleable.%s[i] & 0x00ffffff) | (packageId << 24);\\n\"\n                \"%s}\\n\",\n                indentStr, nclassName.string(),\n                getIndentSpace(indent+1), nclassName.string(), nclassName.string(),\n                indentStr);\n    }\n\n    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;\n}\n\nstatic status_t writeResourceLoadedCallback(\n    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,\n    const sp<AaptSymbols>& symbols, const String8& className, int indent)\n{\n    size_t i;\n    status_t err = NO_ERROR;\n\n    size_t N = symbols->getSymbols().size();\n    for (i=0; i<N; i++) {\n        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);\n        if (sym.typeCode == AaptSymbolEntry::TYPE_UNKNOWN) {\n            continue;\n        }\n        if (!assets->isJavaSymbol(sym, includePrivate)) {\n            continue;\n        }\n        String8 flat_name(flattenSymbol(sym.name));\n        fprintf(fp,\n                \"%s%s.%s = (%s.%s & 0x00ffffff) | (packageId << 24);\\n\",\n                getIndentSpace(indent), className.string(), flat_name.string(),\n                className.string(), flat_name.string());\n    }\n\n    N = symbols->getNestedSymbols().size();\n    for (i=0; i<N; i++) {\n        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);\n        String8 nclassName(symbols->getNestedSymbols().keyAt(i));\n        if (nclassName == \"styleable\") {\n            err = writeResourceLoadedCallbackForLayoutClasses(\n                    fp, assets, nsymbols, indent, includePrivate);\n        } else {\n            err = writeResourceLoadedCallback(fp, assets, includePrivate, nsymbols,\n                    nclassName, indent);\n        }\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatic status_t writeLayoutClasses(\n    FILE* fp, const sp<AaptAssets>& assets,\n    const sp<AaptSymbols>& symbols, int indent, bool includePrivate, bool nonConstantId)\n{\n    const char* indentStr = getIndentSpace(indent);\n    if (!includePrivate) {\n        fprintf(fp, \"%s/** @doconly */\\n\", indentStr);\n    }\n    fprintf(fp, \"%spublic static final class styleable {\\n\", indentStr);\n    indent++;\n\n    String16 attr16(\"attr\");\n    String16 package16(assets->getPackage());\n\n    indentStr = getIndentSpace(indent);\n    bool hasErrors = false;\n\n    size_t i;\n    size_t N = symbols->getNestedSymbols().size();\n    for (i=0; i<N; i++) {\n        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);\n        String8 realClassName(symbols->getNestedSymbols().keyAt(i));\n        String8 nclassName(flattenSymbol(realClassName));\n\n        SortedVector<uint32_t> idents;\n        Vector<uint32_t> origOrder;\n        Vector<bool> publicFlags;\n\n        size_t a;\n        size_t NA = nsymbols->getSymbols().size();\n        for (a=0; a<NA; a++) {\n            const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a));\n            int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32\n                    ? sym.int32Val : 0;\n            bool isPublic = true;\n            if (code == 0) {\n                String16 name16(sym.name);\n                uint32_t typeSpecFlags;\n                code = assets->getIncludedResources().identifierForName(\n                    name16.string(), name16.size(),\n                    attr16.string(), attr16.size(),\n                    package16.string(), package16.size(), &typeSpecFlags);\n                if (code ==0) {\n                String16 package16_taobao(sktPackageName);\n                code = assets->getIncludedResources().identifierForName(\n                    name16.string(), name16.size(),\n                    attr16.string(), attr16.size(),\n                    package16_taobao.string(), package16_taobao.size(), &typeSpecFlags);\n                }\n                if (code ==0) {\n                String16 package16_taobao(sktPackageName);\n                code = assets->getIncludedResources().identifierForName(\n                    name16.string(), name16.size(),\n                    attr16.string(), attr16.size(),\n                    package16_taobao.string(), package16_taobao.size(), &typeSpecFlags);\n                }\n                if (code == 0) {\n                    fprintf(stderr, \"ERROR: In <declare-styleable> %s, unable to find attribute %s\\n\",\n                            nclassName.string(), sym.name.string());\n                    hasErrors = true;\n                }\n                isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;\n            }\n            idents.add(code);\n            origOrder.add(code);\n            publicFlags.add(isPublic);\n        }\n\n        NA = idents.size();\n\n        String16 comment = symbols->getComment(realClassName);\n        AnnotationProcessor ann;\n        fprintf(fp, \"%s/** \", indentStr);\n        if (comment.size() > 0) {\n            String8 cmt(comment);\n            ann.preprocessComment(cmt);\n            fprintf(fp, \"%s\\n\", cmt.string());\n        } else {\n            fprintf(fp, \"Attributes that can be used with a %s.\\n\", nclassName.string());\n        }\n        bool hasTable = false;\n        for (a=0; a<NA; a++) {\n            ssize_t pos = idents.indexOf(origOrder.itemAt(a));\n            if (pos >= 0) {\n                if (!hasTable) {\n                    hasTable = true;\n                    fprintf(fp,\n                            \"%s   <p>Includes the following attributes:</p>\\n\"\n                            \"%s   <table>\\n\"\n                            \"%s   <colgroup align=\\\"left\\\" />\\n\"\n                            \"%s   <colgroup align=\\\"left\\\" />\\n\"\n                            \"%s   <tr><th>Attribute</th><th>Description</th></tr>\\n\",\n                            indentStr,\n                            indentStr,\n                            indentStr,\n                            indentStr,\n                            indentStr);\n                }\n                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);\n                if (!publicFlags.itemAt(a) && !includePrivate) {\n                    continue;\n                }\n                String8 name8(sym.name);\n                String16 comment(sym.comment);\n                if (comment.size() <= 0) {\n                    comment = getAttributeComment(assets, name8);\n                }\n                if (comment.size() > 0) {\n                    const char16_t* p = comment.string();\n                    while (*p != 0 && *p != '.') {\n                        if (*p == '{') {\n                            while (*p != 0 && *p != '}') {\n                                p++;\n                            }\n                        } else {\n                            p++;\n                        }\n                    }\n                    if (*p == '.') {\n                        p++;\n                    }\n                    comment = String16(comment.string(), p-comment.string());\n                }\n                fprintf(fp, \"%s   <tr><td><code>{@link #%s_%s %s:%s}</code></td><td>%s</td></tr>\\n\",\n                        indentStr, nclassName.string(),\n                        flattenSymbol(name8).string(),\n                        getSymbolPackage(name8, assets, true).string(),\n                        getSymbolName(name8).string(),\n                        String8(comment).string());\n            }\n        }\n        if (hasTable) {\n            fprintf(fp, \"%s   </table>\\n\", indentStr);\n        }\n        for (a=0; a<NA; a++) {\n            ssize_t pos = idents.indexOf(origOrder.itemAt(a));\n            if (pos >= 0) {\n                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);\n                if (!publicFlags.itemAt(a) && !includePrivate) {\n                    continue;\n                }\n                fprintf(fp, \"%s   @see #%s_%s\\n\",\n                        indentStr, nclassName.string(),\n                        flattenSymbol(sym.name).string());\n            }\n        }\n        fprintf(fp, \"%s */\\n\", getIndentSpace(indent));\n\n        ann.printAnnotations(fp, indentStr);\n        \n        fprintf(fp,\n                \"%spublic static final int[] %s = {\\n\"\n                \"%s\",\n                indentStr, nclassName.string(),\n                getIndentSpace(indent+1));\n\n        for (a=0; a<NA; a++) {\n            if (a != 0) {\n                if ((a&3) == 0) {\n                    fprintf(fp, \",\\n%s\", getIndentSpace(indent+1));\n                } else {\n                    fprintf(fp, \", \");\n                }\n            }\n            fprintf(fp, \"0x%08x\", idents[a]);\n        }\n\n        fprintf(fp, \"\\n%s};\\n\", indentStr);\n\n        for (a=0; a<NA; a++) {\n            ssize_t pos = idents.indexOf(origOrder.itemAt(a));\n            if (pos >= 0) {\n                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);\n                if (!publicFlags.itemAt(a) && !includePrivate) {\n                    continue;\n                }\n                String8 name8(sym.name);\n                String16 comment(sym.comment);\n                String16 typeComment;\n                if (comment.size() <= 0) {\n                    comment = getAttributeComment(assets, name8, &typeComment);\n                } else {\n                    getAttributeComment(assets, name8, &typeComment);\n                }\n\n                uint32_t typeSpecFlags = 0;\n                String16 name16(sym.name);\n                assets->getIncludedResources().identifierForName(\n                    name16.string(), name16.size(),\n                    attr16.string(), attr16.size(),\n                    package16.string(), package16.size(), &typeSpecFlags);\n                //printf(\"%s:%s/%s: 0x%08x\\n\", String8(package16).string(),\n                //    String8(attr16).string(), String8(name16).string(), typeSpecFlags);\n                const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;\n\n                AnnotationProcessor ann;\n                fprintf(fp, \"%s/**\\n\", indentStr);\n                if (comment.size() > 0) {\n                    String8 cmt(comment);\n                    ann.preprocessComment(cmt);\n                    fprintf(fp, \"%s  <p>\\n%s  @attr description\\n\", indentStr, indentStr);\n                    fprintf(fp, \"%s  %s\\n\", indentStr, cmt.string());\n                } else {\n                    fprintf(fp,\n                            \"%s  <p>This symbol is the offset where the {@link %s.R.attr#%s}\\n\"\n                            \"%s  attribute's value can be found in the {@link #%s} array.\\n\",\n                            indentStr,\n                            getSymbolPackage(name8, assets, pub).string(),\n                            getSymbolName(name8).string(),\n                            indentStr, nclassName.string());\n                }\n                if (typeComment.size() > 0) {\n                    String8 cmt(typeComment);\n                    ann.preprocessComment(cmt);\n                    fprintf(fp, \"\\n\\n%s  %s\\n\", indentStr, cmt.string());\n                }\n                if (comment.size() > 0) {\n                    if (pub) {\n                        fprintf(fp,\n                                \"%s  <p>This corresponds to the global attribute\\n\"\n                                \"%s  resource symbol {@link %s.R.attr#%s}.\\n\",\n                                indentStr, indentStr,\n                                getSymbolPackage(name8, assets, true).string(),\n                                getSymbolName(name8).string());\n                    } else {\n                        fprintf(fp,\n                                \"%s  <p>This is a private symbol.\\n\", indentStr);\n                    }\n                }\n                fprintf(fp, \"%s  @attr name %s:%s\\n\", indentStr,\n                        getSymbolPackage(name8, assets, pub).string(),\n                        getSymbolName(name8).string());\n                fprintf(fp, \"%s*/\\n\", indentStr);\n                ann.printAnnotations(fp, indentStr);\n\n                const char * id_format = nonConstantId ?\n                        \"%spublic static int %s_%s = %d;\\n\" :\n                        \"%spublic static final int %s_%s = %d;\\n\";\n\n                fprintf(fp,\n                        id_format,\n                        indentStr, nclassName.string(),\n                        flattenSymbol(name8).string(), (int)pos);\n            }\n        }\n    }\n\n    indent--;\n    fprintf(fp, \"%s};\\n\", getIndentSpace(indent));\n    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;\n}\n\nstatic status_t writeTextLayoutClasses(\n    FILE* fp, const sp<AaptAssets>& assets,\n    const sp<AaptSymbols>& symbols, bool includePrivate)\n{\n    String16 attr16(\"attr\");\n    String16 package16(assets->getPackage());\n\n    bool hasErrors = false;\n\n    size_t i;\n    size_t N = symbols->getNestedSymbols().size();\n    for (i=0; i<N; i++) {\n        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);\n        String8 realClassName(symbols->getNestedSymbols().keyAt(i));\n        String8 nclassName(flattenSymbol(realClassName));\n\n        SortedVector<uint32_t> idents;\n        Vector<uint32_t> origOrder;\n        Vector<bool> publicFlags;\n\n        size_t a;\n        size_t NA = nsymbols->getSymbols().size();\n        for (a=0; a<NA; a++) {\n            const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a));\n            int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32\n                    ? sym.int32Val : 0;\n            bool isPublic = true;\n            if (code == 0) {\n                String16 name16(sym.name);\n                uint32_t typeSpecFlags;\n                code = assets->getIncludedResources().identifierForName(\n                    name16.string(), name16.size(),\n                    attr16.string(), attr16.size(),\n                    package16.string(), package16.size(), &typeSpecFlags);\n                if (code ==0) {\n                String16 package16_taobao(sktPackageName);\n                code = assets->getIncludedResources().identifierForName(\n                    name16.string(), name16.size(),\n                    attr16.string(), attr16.size(),\n                    package16_taobao.string(), package16_taobao.size(), &typeSpecFlags);\n                }\n                if (code == 0) {\n                    fprintf(stderr, \"ERROR: In <declare-styleable> %s, unable to find attribute %s\\n\",\n                            nclassName.string(), sym.name.string());\n                    hasErrors = true;\n                }\n                isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;\n            }\n            idents.add(code);\n            origOrder.add(code);\n            publicFlags.add(isPublic);\n        }\n\n        NA = idents.size();\n\n        fprintf(fp, \"int[] styleable %s {\", nclassName.string());\n\n        for (a=0; a<NA; a++) {\n            if (a != 0) {\n                fprintf(fp, \",\");\n            }\n            fprintf(fp, \" 0x%08x\", idents[a]);\n        }\n\n        fprintf(fp, \" }\\n\");\n\n        for (a=0; a<NA; a++) {\n            ssize_t pos = idents.indexOf(origOrder.itemAt(a));\n            if (pos >= 0) {\n                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);\n                if (!publicFlags.itemAt(a) && !includePrivate) {\n                    continue;\n                }\n                String8 name8(sym.name);\n                String16 comment(sym.comment);\n                String16 typeComment;\n                if (comment.size() <= 0) {\n                    comment = getAttributeComment(assets, name8, &typeComment);\n                } else {\n                    getAttributeComment(assets, name8, &typeComment);\n                }\n\n                uint32_t typeSpecFlags = 0;\n                String16 name16(sym.name);\n                assets->getIncludedResources().identifierForName(\n                    name16.string(), name16.size(),\n                    attr16.string(), attr16.size(),\n                    package16.string(), package16.size(), &typeSpecFlags);\n                //printf(\"%s:%s/%s: 0x%08x\\n\", String8(package16).string(),\n                //    String8(attr16).string(), String8(name16).string(), typeSpecFlags);\n                const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;\n\n                fprintf(fp,\n                        \"int styleable %s_%s %d\\n\",\n                        nclassName.string(),\n                        flattenSymbol(name8).string(), (int)pos);\n            }\n        }\n    }\n\n    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;\n}\n\nstatic status_t writeSymbolClass(\n    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,\n    const sp<AaptSymbols>& symbols, const String8& className, int indent,\n    bool nonConstantId, bool emitCallback)\n{\n    fprintf(fp, \"%spublic %sfinal class %s {\\n\",\n            getIndentSpace(indent),\n            indent != 0 ? \"static \" : \"\", className.string());\n    indent++;\n\n    size_t i;\n    status_t err = NO_ERROR;\n\n    const char * id_format = nonConstantId ?\n            \"%spublic static int %s=0x%08x;\\n\" :\n            \"%spublic static final int %s=0x%08x;\\n\";\n\n    size_t N = symbols->getSymbols().size();\n    for (i=0; i<N; i++) {\n        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);\n        if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) {\n            continue;\n        }\n        if (!assets->isJavaSymbol(sym, includePrivate)) {\n            continue;\n        }\n        String8 name8(sym.name);\n        String16 comment(sym.comment);\n        bool haveComment = false;\n        AnnotationProcessor ann;\n        if (comment.size() > 0) {\n            haveComment = true;\n            String8 cmt(comment);\n            ann.preprocessComment(cmt);\n            fprintf(fp,\n                    \"%s/** %s\\n\",\n                    getIndentSpace(indent), cmt.string());\n        } else if (sym.isPublic && !includePrivate) {\n            sym.sourcePos.warning(\"No comment for public symbol %s:%s/%s\",\n                assets->getPackage().string(), className.string(),\n                String8(sym.name).string());\n        }\n        String16 typeComment(sym.typeComment);\n        if (typeComment.size() > 0) {\n            String8 cmt(typeComment);\n            ann.preprocessComment(cmt);\n            if (!haveComment) {\n                haveComment = true;\n                fprintf(fp,\n                        \"%s/** %s\\n\", getIndentSpace(indent), cmt.string());\n            } else {\n                fprintf(fp,\n                        \"%s %s\\n\", getIndentSpace(indent), cmt.string());\n            }\n        }\n        if (haveComment) {\n            fprintf(fp,\"%s */\\n\", getIndentSpace(indent));\n        }\n        ann.printAnnotations(fp, getIndentSpace(indent));\n        fprintf(fp, id_format,\n                getIndentSpace(indent),\n                flattenSymbol(name8).string(), (int)sym.int32Val);\n    }\n\n    for (i=0; i<N; i++) {\n        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);\n        if (sym.typeCode != AaptSymbolEntry::TYPE_STRING) {\n            continue;\n        }\n        if (!assets->isJavaSymbol(sym, includePrivate)) {\n            continue;\n        }\n        String8 name8(sym.name);\n        String16 comment(sym.comment);\n        AnnotationProcessor ann;\n        if (comment.size() > 0) {\n            String8 cmt(comment);\n            ann.preprocessComment(cmt);\n            fprintf(fp,\n                    \"%s/** %s\\n\"\n                     \"%s */\\n\",\n                    getIndentSpace(indent), cmt.string(),\n                    getIndentSpace(indent));\n        } else if (sym.isPublic && !includePrivate) {\n            sym.sourcePos.warning(\"No comment for public symbol %s:%s/%s\",\n                assets->getPackage().string(), className.string(),\n                String8(sym.name).string());\n        }\n        ann.printAnnotations(fp, getIndentSpace(indent));\n        fprintf(fp, \"%spublic static final String %s=\\\"%s\\\";\\n\",\n                getIndentSpace(indent),\n                flattenSymbol(name8).string(), sym.stringVal.string());\n    }\n\n    sp<AaptSymbols> styleableSymbols;\n\n    N = symbols->getNestedSymbols().size();\n    for (i=0; i<N; i++) {\n        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);\n        String8 nclassName(symbols->getNestedSymbols().keyAt(i));\n        if (nclassName == \"styleable\") {\n            styleableSymbols = nsymbols;\n        } else {\n            err = writeSymbolClass(fp, assets, includePrivate, nsymbols, nclassName,\n                    indent, nonConstantId, false);\n        }\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    if (styleableSymbols != NULL) {\n        err = writeLayoutClasses(fp, assets, styleableSymbols, indent, includePrivate, nonConstantId);\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    if (emitCallback) {\n        fprintf(fp, \"%spublic static void onResourcesLoaded(int packageId) {\\n\",\n                getIndentSpace(indent));\n        writeResourceLoadedCallback(fp, assets, includePrivate, symbols, className, indent + 1);\n        fprintf(fp, \"%s}\\n\", getIndentSpace(indent));\n    }\n\n    indent--;\n    fprintf(fp, \"%s}\\n\", getIndentSpace(indent));\n    return NO_ERROR;\n}\n\nstatic status_t writeTextSymbolClass(\n    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,\n    const sp<AaptSymbols>& symbols, const String8& className)\n{\n    size_t i;\n    status_t err = NO_ERROR;\n\n    size_t N = symbols->getSymbols().size();\n    for (i=0; i<N; i++) {\n        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);\n        if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) {\n            continue;\n        }\n\n        if (!assets->isJavaSymbol(sym, includePrivate)) {\n            continue;\n        }\n\n        String8 name8(sym.name);\n        fprintf(fp, \"int %s %s 0x%08x\\n\",\n                className.string(),\n                flattenSymbol(name8).string(), (int)sym.int32Val);\n    }\n\n    N = symbols->getNestedSymbols().size();\n    for (i=0; i<N; i++) {\n        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);\n        String8 nclassName(symbols->getNestedSymbols().keyAt(i));\n        if (nclassName == \"styleable\") {\n            err = writeTextLayoutClasses(fp, assets, nsymbols, includePrivate);\n        } else {\n            err = writeTextSymbolClass(fp, assets, includePrivate, nsymbols, nclassName);\n        }\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets,\n    const String8& package, bool includePrivate, bool emitCallback)\n{\n    if (!bundle->getRClassDir()) {\n        return NO_ERROR;\n    }\n\n    const char* textSymbolsDest = bundle->getOutputTextSymbols();\n\n    String8 R(\"R\");\n    const size_t N = assets->getSymbols().size();\n    for (size_t i=0; i<N; i++) {\n        sp<AaptSymbols> symbols = assets->getSymbols().valueAt(i);\n        String8 className(assets->getSymbols().keyAt(i));\n        String8 dest(bundle->getRClassDir());\n\n        if (bundle->getMakePackageDirs()) {\n            String8 pkg(package);\n            const char* last = pkg.string();\n            const char* s = last-1;\n            do {\n                s++;\n                if (s > last && (*s == '.' || *s == 0)) {\n                    String8 part(last, s-last);\n                    dest.appendPath(part);\n#ifdef HAVE_MS_C_RUNTIME\n                    _mkdir(dest.string());\n#else\n                    mkdir(dest.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);\n#endif\n                    last = s+1;\n                }\n            } while (*s);\n        }\n        dest.appendPath(className);\n        dest.append(\".java\");\n        FILE* fp = fopen(dest.string(), \"w+\");\n        if (fp == NULL) {\n            fprintf(stderr, \"ERROR: Unable to open class file %s: %s\\n\",\n                    dest.string(), strerror(errno));\n            return UNKNOWN_ERROR;\n        }\n        if (bundle->getVerbose()) {\n            printf(\"  Writing symbols for class %s.\\n\", className.string());\n        }\n\n        fprintf(fp,\n            \"/* AUTO-GENERATED FILE.  DO NOT MODIFY.\\n\"\n            \" *\\n\"\n            \" * This class was automatically generated by the\\n\"\n            \" * aapt tool from the resource data it found.  It\\n\"\n            \" * should not be modified by hand.\\n\"\n            \" */\\n\"\n            \"\\n\"\n            \"package %s;\\n\\n\", package.string());\n\n        status_t err = writeSymbolClass(fp, assets, includePrivate, symbols,\n                className, 0, bundle->getNonConstantId(), emitCallback);\n        fclose(fp);\n        if (err != NO_ERROR) {\n            return err;\n        }\n\n        if (textSymbolsDest != NULL && R == className) {\n            String8 textDest(textSymbolsDest);\n            textDest.appendPath(className);\n            textDest.append(\".txt\");\n\n            FILE* fp = fopen(textDest.string(), \"w+\");\n            if (fp == NULL) {\n                fprintf(stderr, \"ERROR: Unable to open text symbol file %s: %s\\n\",\n                        textDest.string(), strerror(errno));\n                return UNKNOWN_ERROR;\n            }\n            if (bundle->getVerbose()) {\n                printf(\"  Writing text symbols for class %s.\\n\", className.string());\n            }\n\n            status_t err = writeTextSymbolClass(fp, assets, includePrivate, symbols,\n                    className);\n            fclose(fp);\n            if (err != NO_ERROR) {\n                return err;\n            }\n        }\n\n        // If we were asked to generate a dependency file, we'll go ahead and add this R.java\n        // as a target in the dependency file right next to it.\n        if (bundle->getGenDependencies() && R == className) {\n            // Add this R.java to the dependency file\n            String8 dependencyFile(bundle->getRClassDir());\n            dependencyFile.appendPath(\"R.java.d\");\n\n            FILE *fp = fopen(dependencyFile.string(), \"a\");\n            fprintf(fp,\"%s \\\\\\n\", dest.string());\n            fclose(fp);\n        }\n    }\n\n    return NO_ERROR;\n}\n\n\nclass ProguardKeepSet\n{\npublic:\n    // { rule --> { file locations } }\n    KeyedVector<String8, SortedVector<String8> > rules;\n\n    void add(const String8& rule, const String8& where);\n};\n\nvoid ProguardKeepSet::add(const String8& rule, const String8& where)\n{\n    ssize_t index = rules.indexOfKey(rule);\n    if (index < 0) {\n        index = rules.add(rule, SortedVector<String8>());\n    }\n    rules.editValueAt(index).add(where);\n}\n\nvoid\naddProguardKeepRule(ProguardKeepSet* keep, const String8& inClassName,\n        const char* pkg, const String8& srcName, int line)\n{\n    String8 className(inClassName);\n    if (pkg != NULL) {\n        // asdf     --> package.asdf\n        // .asdf  .a.b  --> package.asdf package.a.b\n        // asdf.adsf --> asdf.asdf\n        const char* p = className.string();\n        const char* q = strchr(p, '.');\n        if (p == q) {\n            className = pkg;\n            className.append(inClassName);\n        } else if (q == NULL) {\n            className = pkg;\n            className.append(\".\");\n            className.append(inClassName);\n        }\n    }\n\n    String8 rule(\"-keep class \");\n    rule += className;\n    rule += \" { <init>(...); }\";\n\n    String8 location(\"view \");\n    location += srcName;\n    char lineno[20];\n    sprintf(lineno, \":%d\", line);\n    location += lineno;\n\n    keep->add(rule, location);\n}\n\nvoid\naddProguardKeepMethodRule(ProguardKeepSet* keep, const String8& memberName,\n        const char* pkg, const String8& srcName, int line)\n{\n    String8 rule(\"-keepclassmembers class * { *** \");\n    rule += memberName;\n    rule += \"(...); }\";\n\n    String8 location(\"onClick \");\n    location += srcName;\n    char lineno[20];\n    sprintf(lineno, \":%d\", line);\n    location += lineno;\n\n    keep->add(rule, location);\n}\n\nstatus_t\nwriteProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& assets, bool mainDex)\n{\n    status_t err;\n    ResXMLTree tree;\n    size_t len;\n    ResXMLTree::event_code_t code;\n    int depth = 0;\n    bool inApplication = false;\n    String8 error;\n    sp<AaptGroup> assGroup;\n    sp<AaptFile> assFile;\n    String8 pkg;\n    String8 defaultProcess;\n\n    // First, look for a package file to parse.  This is required to\n    // be able to generate the resource information.\n    assGroup = assets->getFiles().valueFor(String8(\"AndroidManifest.xml\"));\n    if (assGroup == NULL) {\n        fprintf(stderr, \"ERROR: No AndroidManifest.xml file found.\\n\");\n        return -1;\n    }\n\n    if (assGroup->getFiles().size() != 1) {\n        fprintf(stderr, \"warning: Multiple AndroidManifest.xml files found, using %s\\n\",\n                assGroup->getFiles().valueAt(0)->getPrintableSource().string());\n    }\n\n    assFile = assGroup->getFiles().valueAt(0);\n\n    err = parseXMLResource(assFile, &tree);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    tree.restart();\n\n    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::END_TAG) {\n            if (/* name == \"Application\" && */ depth == 2) {\n                inApplication = false;\n            }\n            depth--;\n            continue;\n        }\n        if (code != ResXMLTree::START_TAG) {\n            continue;\n        }\n        depth++;\n        String8 tag(tree.getElementName(&len));\n        // printf(\"Depth %d tag %s\\n\", depth, tag.string());\n        bool keepTag = false;\n        if (depth == 1) {\n            if (tag != \"manifest\") {\n                fprintf(stderr, \"ERROR: manifest does not start with <manifest> tag\\n\");\n                return -1;\n            }\n            pkg = AaptXml::getAttribute(tree, NULL, \"package\");\n        } else if (depth == 2) {\n            if (tag == \"application\") {\n                inApplication = true;\n                keepTag = true;\n\n                String8 agent = AaptXml::getAttribute(tree,\n                        \"http://schemas.android.com/apk/res/android\",\n                        \"backupAgent\", &error);\n                if (agent.length() > 0) {\n                    addProguardKeepRule(keep, agent, pkg.string(),\n                            assFile->getPrintableSource(), tree.getLineNumber());\n                }\n\n                if (mainDex) {\n                    defaultProcess = AaptXml::getAttribute(tree,\n                            \"http://schemas.android.com/apk/res/android\", \"process\", &error);\n                    if (error != \"\") {\n                        fprintf(stderr, \"ERROR: %s\\n\", error.string());\n                        return -1;\n                    }\n                }\n            } else if (tag == \"instrumentation\") {\n                keepTag = true;\n            }\n        }\n        if (!keepTag && inApplication && depth == 3) {\n            if (tag == \"activity\" || tag == \"service\" || tag == \"receiver\" || tag == \"provider\") {\n                keepTag = true;\n            }\n        }\n        if (keepTag) {\n            String8 name = AaptXml::getAttribute(tree,\n                    \"http://schemas.android.com/apk/res/android\", \"name\", &error);\n            if (error != \"\") {\n                fprintf(stderr, \"ERROR: %s\\n\", error.string());\n                return -1;\n            }\n\n            keepTag = name.length() > 0;\n\n            if (keepTag && mainDex) {\n                String8 componentProcess = AaptXml::getAttribute(tree,\n                        \"http://schemas.android.com/apk/res/android\", \"process\", &error);\n                if (error != \"\") {\n                    fprintf(stderr, \"ERROR: %s\\n\", error.string());\n                    return -1;\n                }\n\n                const String8& process =\n                        componentProcess.length() > 0 ? componentProcess : defaultProcess;\n                keepTag = process.length() > 0 && process.find(\":\") != 0;\n            }\n\n            if (keepTag) {\n                addProguardKeepRule(keep, name, pkg.string(),\n                        assFile->getPrintableSource(), tree.getLineNumber());\n            }\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstruct NamespaceAttributePair {\n    const char* ns;\n    const char* attr;\n\n    NamespaceAttributePair(const char* n, const char* a) : ns(n), attr(a) {}\n    NamespaceAttributePair() : ns(NULL), attr(NULL) {}\n};\n\nstatus_t\nwriteProguardForXml(ProguardKeepSet* keep, const sp<AaptFile>& layoutFile,\n        const Vector<String8>& startTags, const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs)\n{\n    status_t err;\n    ResXMLTree tree;\n    size_t len;\n    ResXMLTree::event_code_t code;\n\n    err = parseXMLResource(layoutFile, &tree);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    tree.restart();\n\n    if (!startTags.isEmpty()) {\n        bool haveStart = false;\n        while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n            if (code != ResXMLTree::START_TAG) {\n                continue;\n            }\n            String8 tag(tree.getElementName(&len));\n            const size_t numStartTags = startTags.size();\n            for (size_t i = 0; i < numStartTags; i++) {\n                if (tag == startTags[i]) {\n                    haveStart = true;\n                }\n            }\n            break;\n        }\n        if (!haveStart) {\n            return NO_ERROR;\n        }\n    }\n\n    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code != ResXMLTree::START_TAG) {\n            continue;\n        }\n        String8 tag(tree.getElementName(&len));\n\n        // If there is no '.', we'll assume that it's one of the built in names.\n        if (strchr(tag.string(), '.')) {\n            addProguardKeepRule(keep, tag, NULL,\n                    layoutFile->getPrintableSource(), tree.getLineNumber());\n        } else if (tagAttrPairs != NULL) {\n            ssize_t tagIndex = tagAttrPairs->indexOfKey(tag);\n            if (tagIndex >= 0) {\n                const Vector<NamespaceAttributePair>& nsAttrVector = tagAttrPairs->valueAt(tagIndex);\n                for (size_t i = 0; i < nsAttrVector.size(); i++) {\n                    const NamespaceAttributePair& nsAttr = nsAttrVector[i];\n\n                    ssize_t attrIndex = tree.indexOfAttribute(nsAttr.ns, nsAttr.attr);\n                    if (attrIndex < 0) {\n                        // fprintf(stderr, \"%s:%d: <%s> does not have attribute %s:%s.\\n\",\n                        //        layoutFile->getPrintableSource().string(), tree.getLineNumber(),\n                        //        tag.string(), nsAttr.ns, nsAttr.attr);\n                    } else {\n                        size_t len;\n                        addProguardKeepRule(keep,\n                                            String8(tree.getAttributeStringValue(attrIndex, &len)), NULL,\n                                            layoutFile->getPrintableSource(), tree.getLineNumber());\n                    }\n                }\n            }\n        }\n        ssize_t attrIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, \"onClick\");\n        if (attrIndex >= 0) {\n            size_t len;\n            addProguardKeepMethodRule(keep,\n                                String8(tree.getAttributeStringValue(attrIndex, &len)), NULL,\n                                layoutFile->getPrintableSource(), tree.getLineNumber());\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatic void addTagAttrPair(KeyedVector<String8, Vector<NamespaceAttributePair> >* dest,\n        const char* tag, const char* ns, const char* attr) {\n    String8 tagStr(tag);\n    ssize_t index = dest->indexOfKey(tagStr);\n\n    if (index < 0) {\n        Vector<NamespaceAttributePair> vector;\n        vector.add(NamespaceAttributePair(ns, attr));\n        dest->add(tagStr, vector);\n    } else {\n        dest->editValueAt(index).add(NamespaceAttributePair(ns, attr));\n    }\n}\n\nstatus_t\nwriteProguardForLayouts(ProguardKeepSet* keep, const sp<AaptAssets>& assets)\n{\n    status_t err;\n\n    // tag:attribute pairs that should be checked in layout files.\n    KeyedVector<String8, Vector<NamespaceAttributePair> > kLayoutTagAttrPairs;\n    addTagAttrPair(&kLayoutTagAttrPairs, \"view\", NULL, \"class\");\n    addTagAttrPair(&kLayoutTagAttrPairs, \"fragment\", NULL, \"class\");\n    addTagAttrPair(&kLayoutTagAttrPairs, \"fragment\", RESOURCES_ANDROID_NAMESPACE, \"name\");\n\n    // tag:attribute pairs that should be checked in xml files.\n    KeyedVector<String8, Vector<NamespaceAttributePair> > kXmlTagAttrPairs;\n    addTagAttrPair(&kXmlTagAttrPairs, \"PreferenceScreen\", RESOURCES_ANDROID_NAMESPACE, \"fragment\");\n    addTagAttrPair(&kXmlTagAttrPairs, \"header\", RESOURCES_ANDROID_NAMESPACE, \"fragment\");\n\n    const Vector<sp<AaptDir> >& dirs = assets->resDirs();\n    const size_t K = dirs.size();\n    for (size_t k=0; k<K; k++) {\n        const sp<AaptDir>& d = dirs.itemAt(k);\n        const String8& dirName = d->getLeaf();\n        Vector<String8> startTags;\n        const char* startTag = NULL;\n        const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs = NULL;\n        if ((dirName == String8(\"layout\")) || (strncmp(dirName.string(), \"layout-\", 7) == 0)) {\n            tagAttrPairs = &kLayoutTagAttrPairs;\n        } else if ((dirName == String8(\"xml\")) || (strncmp(dirName.string(), \"xml-\", 4) == 0)) {\n            startTags.add(String8(\"PreferenceScreen\"));\n            startTags.add(String8(\"preference-headers\"));\n            tagAttrPairs = &kXmlTagAttrPairs;\n        } else if ((dirName == String8(\"menu\")) || (strncmp(dirName.string(), \"menu-\", 5) == 0)) {\n            startTags.add(String8(\"menu\"));\n            tagAttrPairs = NULL;\n        } else {\n            continue;\n        }\n\n        const KeyedVector<String8,sp<AaptGroup> > groups = d->getFiles();\n        const size_t N = groups.size();\n        for (size_t i=0; i<N; i++) {\n            const sp<AaptGroup>& group = groups.valueAt(i);\n            const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files = group->getFiles();\n            const size_t M = files.size();\n            for (size_t j=0; j<M; j++) {\n                err = writeProguardForXml(keep, files.valueAt(j), startTags, tagAttrPairs);\n                if (err < 0) {\n                    return err;\n                }\n            }\n        }\n    }\n    // Handle the overlays\n    sp<AaptAssets> overlay = assets->getOverlay();\n    if (overlay.get()) {\n        return writeProguardForLayouts(keep, overlay);\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t\nwriteProguardSpec(const char* filename, const ProguardKeepSet& keep, status_t err)\n{\n    FILE* fp = fopen(filename, \"w+\");\n    if (fp == NULL) {\n        fprintf(stderr, \"ERROR: Unable to open class file %s: %s\\n\",\n                filename, strerror(errno));\n        return UNKNOWN_ERROR;\n    }\n\n    const KeyedVector<String8, SortedVector<String8> >& rules = keep.rules;\n    const size_t N = rules.size();\n    for (size_t i=0; i<N; i++) {\n        const SortedVector<String8>& locations = rules.valueAt(i);\n        const size_t M = locations.size();\n        for (size_t j=0; j<M; j++) {\n            fprintf(fp, \"# %s\\n\", locations.itemAt(j).string());\n        }\n        fprintf(fp, \"%s\\n\\n\", rules.keyAt(i).string());\n    }\n    fclose(fp);\n\n    return err;\n}\n\nstatus_t\nwriteProguardFile(Bundle* bundle, const sp<AaptAssets>& assets)\n{\n    status_t err = -1;\n\n    if (!bundle->getProguardFile()) {\n        return NO_ERROR;\n    }\n\n    ProguardKeepSet keep;\n\n    err = writeProguardForAndroidManifest(&keep, assets, false);\n    if (err < 0) {\n        return err;\n    }\n\n    err = writeProguardForLayouts(&keep, assets);\n    if (err < 0) {\n        return err;\n    }\n\n    return writeProguardSpec(bundle->getProguardFile(), keep, err);\n}\n\n\nstatus_t\nwriteMainDexProguardFile(Bundle* bundle, const sp<AaptAssets>& assets)\n{\n    status_t err = -1;\n\n    if (!bundle->getMainDexProguardFile()) {\n        return NO_ERROR;\n    }\n\n    ProguardKeepSet keep;\n\n    err = writeProguardForAndroidManifest(&keep, assets, true);\n    if (err < 0) {\n        return err;\n    }\n\n    return writeProguardSpec(bundle->getMainDexProguardFile(), keep, err);\n}\n// Loops through the string paths and writes them to the file pointer\n// Each file path is written on its own line with a terminating backslash.\nstatus_t writePathsToFile(const sp<FilePathStore>& files, FILE* fp)\n{\n    status_t deps = -1;\n    for (size_t file_i = 0; file_i < files->size(); ++file_i) {\n        // Add the full file path to the dependency file\n        fprintf(fp, \"%s \\\\\\n\", files->itemAt(file_i).string());\n        deps++;\n    }\n    return deps;\n}\n\nstatus_t\nwriteDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets, FILE* fp, bool includeRaw)\n{\n    status_t deps = -1;\n    deps += writePathsToFile(assets->getFullResPaths(), fp);\n    if (includeRaw) {\n        deps += writePathsToFile(assets->getFullAssetPaths(), fp);\n    }\n    return deps;\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/ResourceFilter.cpp",
    "content": "//\n// Copyright 2014 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#include \"ResourceFilter.h\"\n#include \"AaptUtil.h\"\n#include \"AaptConfig.h\"\n\nstatus_t\nWeakResourceFilter::parse(const String8& str)\n{\n    Vector<String8> configStrs = AaptUtil::split(str, ',');\n    const size_t N = configStrs.size();\n    mConfigs.clear();\n    mConfigMask = 0;\n    mConfigs.resize(N);\n    for (size_t i = 0; i < N; i++) {\n        const String8& part = configStrs[i];\n        if (part == \"en_XA\") {\n            mContainsPseudoAccented = true;\n        } else if (part == \"ar_XB\") {\n            mContainsPseudoBidi = true;\n        }\n\n        std::pair<ConfigDescription, uint32_t>& entry = mConfigs.editItemAt(i);\n\n        AaptLocaleValue val;\n        if (val.initFromFilterString(part)) {\n            // For backwards compatibility, we accept configurations that\n            // only specify locale in the standard 'en_US' format.\n            val.writeTo(&entry.first);\n        } else if (!AaptConfig::parse(part, &entry.first)) {\n            fprintf(stderr, \"Invalid configuration: %s\\n\", part.string());\n            return UNKNOWN_ERROR;\n        }\n\n        entry.second = mDefault.diff(entry.first);\n\n        // Ignore the version\n        entry.second &= ~ResTable_config::CONFIG_VERSION;\n\n        mConfigMask |= entry.second;\n    }\n\n    return NO_ERROR;\n}\n\nbool\nWeakResourceFilter::match(const ResTable_config& config) const\n{\n    uint32_t mask = mDefault.diff(config);\n    if ((mConfigMask & mask) == 0) {\n        // The two configurations don't have any common axis.\n        return true;\n    }\n\n    uint32_t matchedAxis = 0x0;\n    const size_t N = mConfigs.size();\n    for (size_t i = 0; i < N; i++) {\n        const std::pair<ConfigDescription, uint32_t>& entry = mConfigs[i];\n        uint32_t diff = entry.first.diff(config);\n        if ((diff & entry.second) == 0) {\n            // Mark the axis that was matched.\n            matchedAxis |= entry.second;\n        } else if ((diff & entry.second) == ResTable_config::CONFIG_LOCALE) {\n            // If the locales differ, but the languages are the same and\n            // the locale we are matching only has a language specified,\n            // we match.\n            if (config.language[0] &&\n                    memcmp(config.language, entry.first.language, sizeof(config.language)) == 0) {\n                if (config.country[0] == 0) {\n                    matchedAxis |= ResTable_config::CONFIG_LOCALE;\n                }\n            }\n        } else if ((diff & entry.second) == ResTable_config::CONFIG_SMALLEST_SCREEN_SIZE) {\n            // Special case if the smallest screen width doesn't match. We check that the\n            // config being matched has a smaller screen width than the filter specified.\n            if (config.smallestScreenWidthDp != 0 &&\n                    config.smallestScreenWidthDp < entry.first.smallestScreenWidthDp) {\n                matchedAxis |= ResTable_config::CONFIG_SMALLEST_SCREEN_SIZE;\n            }\n        }\n    }\n    return matchedAxis == (mConfigMask & mask);\n}\n\nstatus_t\nStrongResourceFilter::parse(const String8& str) {\n    Vector<String8> configStrs = AaptUtil::split(str, ',');\n    ConfigDescription config;\n    mConfigs.clear();\n    for (size_t i = 0; i < configStrs.size(); i++) {\n        if (!AaptConfig::parse(configStrs[i], &config)) {\n            fprintf(stderr, \"Invalid configuration: %s\\n\", configStrs[i].string());\n            return UNKNOWN_ERROR;\n        }\n        mConfigs.insert(config);\n    }\n    return NO_ERROR;\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/ResourceFilter.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#ifndef RESOURCE_FILTER_H\n#define RESOURCE_FILTER_H\n\n#include <androidfw/ResourceTypes.h>\n#include <set>\n#include <utility>\n#include <utils/Errors.h>\n#include <utils/String8.h>\n#include <utils/StrongPointer.h>\n#include <utils/Vector.h>\n\n#include \"AaptAssets.h\"\n#include \"ConfigDescription.h\"\n\nclass ResourceFilter : public virtual android::RefBase {\npublic:\n    virtual bool match(const android::ResTable_config& config) const = 0;\n};\n\n/**\n * Implements logic for parsing and handling \"-c\" options.\n */\nclass WeakResourceFilter : public ResourceFilter {\npublic:\n    WeakResourceFilter()\n        : mContainsPseudoAccented(false)\n        , mContainsPseudoBidi(false) {}\n\n    android::status_t parse(const android::String8& str);\n\n    bool match(const android::ResTable_config& config) const;\n\n    inline bool isEmpty() const {\n        return mConfigMask == 0;\n    }\n\n    inline bool containsPseudo() const {\n        return mContainsPseudoAccented;\n    }\n\n    inline bool containsPseudoBidi() const {\n        return mContainsPseudoBidi;\n    }\n\nprivate:\n    ConfigDescription mDefault;\n    uint32_t mConfigMask;\n    android::Vector<std::pair<ConfigDescription, uint32_t> > mConfigs;\n\n    bool mContainsPseudoAccented;\n    bool mContainsPseudoBidi;\n};\n\n/**\n * Matches resources that have at least one of the configurations\n * that this filter is looking for. In order to match a configuration,\n * the resource must have the exact same configuration.\n *\n * This filter acts as a logical OR when matching resources.\n *\n * For example, if the filter is looking for resources with\n * fr-land, de-land, or sw600dp:\n *\n * (PASS) fr-land\n * (FAIL) fr\n * (PASS) de-land\n * (FAIL) de\n * (FAIL) de-sw600dp\n * (PASS) sw600dp\n * (FAIL) sw600dp-land\n */\nclass StrongResourceFilter : public ResourceFilter {\npublic:\n    StrongResourceFilter() {}\n    StrongResourceFilter(const std::set<ConfigDescription>& configs)\n        : mConfigs(configs) {}\n\n    android::status_t parse(const android::String8& str);\n\n    bool match(const android::ResTable_config& config) const {\n        std::set<ConfigDescription>::const_iterator iter = mConfigs.begin();\n        for (; iter != mConfigs.end(); iter++) {\n            if (iter->compare(config) == 0) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    inline const std::set<ConfigDescription>& getConfigs() const {\n        return mConfigs;\n    }\n\nprivate:\n    std::set<ConfigDescription> mConfigs;\n};\n\n/**\n * Negates the response of the target filter.\n */\nclass InverseResourceFilter : public ResourceFilter {\npublic:\n    InverseResourceFilter(const android::sp<ResourceFilter>& filter)\n        : mFilter(filter) {}\n\n    bool match(const android::ResTable_config& config) const {\n        return !mFilter->match(config);\n    }\n\nprivate:\n    const android::sp<ResourceFilter> mFilter;\n};\n\n/**\n * A logical AND of all the added filters.\n */\nclass AndResourceFilter : public ResourceFilter {\npublic:\n    void addFilter(const android::sp<ResourceFilter>& filter) {\n        mFilters.add(filter);\n    }\n\n    bool match(const android::ResTable_config& config) const {\n        const size_t N = mFilters.size();\n        for (size_t i = 0; i < N; i++) {\n            if (!mFilters[i]->match(config)) {\n                return false;\n            }\n        }\n        return true;\n    }\n\nprivate:\n    android::Vector<android::sp<ResourceFilter> > mFilters;\n};\n#endif\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/ResourceIdCache.cpp",
    "content": "//\n// Copyright 2012 The Android Open Source Project\n//\n// Manage a resource ID cache.\n\n#define LOG_TAG \"ResourceIdCache\"\n\n#include <utils/String16.h>\n#include <utils/Log.h>\n#include \"ResourceIdCache.h\"\n#include <map>\nusing namespace std;\n\n\nstatic size_t mHits = 0;\nstatic size_t mMisses = 0;\nstatic size_t mCollisions = 0;\n\nstatic const size_t MAX_CACHE_ENTRIES = 2048;\nstatic const android::String16 TRUE16(\"1\");\nstatic const android::String16 FALSE16(\"0\");\n\nstruct CacheEntry {\n    // concatenation of the relevant strings into a single instance\n    android::String16 hashedName;\n    uint32_t id;\n\n    CacheEntry() {}\n    CacheEntry(const android::String16& name, uint32_t resId) : hashedName(name), id(resId) { }\n};\n\nstatic map< uint32_t, CacheEntry > mIdMap;\n\n\n// djb2; reasonable choice for strings when collisions aren't particularly important\nstatic inline uint32_t hashround(uint32_t hash, int c) {\n    return ((hash << 5) + hash) + c;    /* hash * 33 + c */\n}\n\nstatic uint32_t hash(const android::String16& hashableString) {\n    uint32_t hash = 5381;\n    const char16_t* str = hashableString.string();\n    while (int c = *str++) hash = hashround(hash, c);\n    return hash;\n}\n\nnamespace android {\n\nstatic inline String16 makeHashableName(const android::String16& package,\n        const android::String16& type,\n        const android::String16& name,\n        bool onlyPublic) {\n    String16 hashable = String16(name);\n    hashable += type;\n    hashable += package;\n    hashable += (onlyPublic ? TRUE16 : FALSE16);\n    return hashable;\n}\n\nuint32_t ResourceIdCache::lookup(const android::String16& package,\n        const android::String16& type,\n        const android::String16& name,\n        bool onlyPublic) {\n    const String16 hashedName = makeHashableName(package, type, name, onlyPublic);\n    const uint32_t hashcode = hash(hashedName);\n    map<uint32_t, CacheEntry>::iterator item = mIdMap.find(hashcode);\n    if (item == mIdMap.end()) {\n        // cache miss\n        mMisses++;\n        return 0;\n    }\n\n    // legit match?\n    if (hashedName == (*item).second.hashedName) {\n        mHits++;\n        return (*item).second.id;\n    }\n\n    // collision\n    mCollisions++;\n    mIdMap.erase(hashcode);\n    return 0;\n}\n\n// returns the resource ID being stored, for callsite convenience\nuint32_t ResourceIdCache::store(const android::String16& package,\n        const android::String16& type,\n        const android::String16& name,\n        bool onlyPublic,\n        uint32_t resId) {\n    if (mIdMap.size() < MAX_CACHE_ENTRIES) {\n        const String16 hashedName = makeHashableName(package, type, name, onlyPublic);\n        const uint32_t hashcode = hash(hashedName);\n        mIdMap[hashcode] = CacheEntry(hashedName, resId);\n    }\n    return resId;\n}\n\nvoid ResourceIdCache::dump() {\n    printf(\"ResourceIdCache dump:\\n\");\n    printf(\"Size: %zd\\n\", mIdMap.size());\n    printf(\"Hits:   %zd\\n\", mHits);\n    printf(\"Misses: %zd\\n\", mMisses);\n    printf(\"(Collisions: %zd)\\n\", mCollisions);\n}\n\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/ResourceIdCache.h",
    "content": "//\n// Copyright 2012 The Android Open Source Project\n//\n// Manage a resource ID cache.\n\n#ifndef RESOURCE_ID_CACHE_H\n#define RESOURCE_ID_CACHE_H\n\n#include <utils/String16.h>\n\nnamespace android {\n\nclass ResourceIdCache {\npublic:\n    static uint32_t lookup(const String16& package,\n            const String16& type,\n            const String16& name,\n            bool onlyPublic);\n\n    static uint32_t store(const String16& package,\n            const String16& type,\n            const String16& name,\n            bool onlyPublic,\n            uint32_t resId);\n\n    static void dump(void);\n};\n\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/ResourceTable.cpp",
    "content": "// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#include \"ResourceTable.h\"\n\n#include \"XMLNode.h\"\n#include \"ResourceFilter.h\"\n#include \"ResourceIdCache.h\"\n#include <androidfw/ResourcePackageId.h>\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/ByteOrder.h>\n#include <utils/TypeHelpers.h>\n#include <utils/Log.h>\n#include <stdarg.h>\n#include <androidfw/ResourcePackageId.h>\n\n#define NOISY(x) //x\n\nstatus_t compileXmlFile(const Bundle* bundle,\n                        const sp<AaptAssets>& assets,\n                        const String16& resourceName,\n                        const sp<AaptFile>& target,\n                        ResourceTable* table,\n                        int options)\n{\n    sp<XMLNode> root = XMLNode::parse(target);\n    if (root == NULL) {\n        return UNKNOWN_ERROR;\n    }\n\n    return compileXmlFile(bundle, assets, resourceName, root, target, table, options);\n}\n\nstatus_t compileXmlFile(const Bundle* bundle,\n                        const sp<AaptAssets>& assets,\n                        const String16& resourceName,\n                        const sp<AaptFile>& target,\n                        const sp<AaptFile>& outTarget,\n                        ResourceTable* table,\n                        int options)\n{\n    sp<XMLNode> root = XMLNode::parse(target);\n    if (root == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    \n    return compileXmlFile(bundle, assets, resourceName, root, outTarget, table, options);\n}\n\nstatus_t compileXmlFile(const Bundle* bundle,\n                        const sp<AaptAssets>& assets,\n                        const String16& resourceName,\n                        const sp<XMLNode>& root,\n                        const sp<AaptFile>& target,\n                        ResourceTable* table,\n                        int options)\n{\n    if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) {\n        root->removeWhitespace(true, NULL);\n    } else  if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) {\n        root->removeWhitespace(false, NULL);\n    }\n\n    if ((options&XML_COMPILE_UTF8) != 0) {\n        root->setUTF8(true);\n    }\n\n    bool hasErrors = false;\n    \n    if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) {\n        status_t err = root->assignResourceIds(assets, table, bundle);\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    // 解析XML值\n    status_t err = root->parseValues(assets, table, bundle);\n    if (err != NO_ERROR) {\n        hasErrors = true;\n    }\n\n    if (hasErrors) {\n        return UNKNOWN_ERROR;\n    }\n\n    if (table->modifyForCompat(bundle, resourceName, target, root) != NO_ERROR) {\n        return UNKNOWN_ERROR;\n    }\n    \n    NOISY(printf(\"Input XML Resource:\\n\"));\n    NOISY(root->print());\n    err = root->flatten(target,\n            (options&XML_COMPILE_STRIP_COMMENTS) != 0,\n            (options&XML_COMPILE_STRIP_RAW_VALUES) != 0);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    NOISY(printf(\"Output XML Resource:\\n\"));\n    NOISY(ResXMLTree tree;\n        tree.setTo(target->getData(), target->getSize());\n        printXMLBlock(&tree));\n\n    target->setCompressionMethod(ZipEntry::kCompressDeflated);\n    \n    return err;\n}\n\n#undef NOISY\n#define NOISY(x) //x\n\nstruct flag_entry\n{\n    const char16_t* name;\n    size_t nameLen;\n    uint32_t value;\n    const char* description;\n};\n\nstatic const char16_t referenceArray[] =\n    { 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e' };\nstatic const char16_t stringArray[] =\n    { 's', 't', 'r', 'i', 'n', 'g' };\nstatic const char16_t integerArray[] =\n    { 'i', 'n', 't', 'e', 'g', 'e', 'r' };\nstatic const char16_t booleanArray[] =\n    { 'b', 'o', 'o', 'l', 'e', 'a', 'n' };\nstatic const char16_t colorArray[] =\n    { 'c', 'o', 'l', 'o', 'r' };\nstatic const char16_t floatArray[] =\n    { 'f', 'l', 'o', 'a', 't' };\nstatic const char16_t dimensionArray[] =\n    { 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n' };\nstatic const char16_t fractionArray[] =\n    { 'f', 'r', 'a', 'c', 't', 'i', 'o', 'n' };\nstatic const char16_t enumArray[] =\n    { 'e', 'n', 'u', 'm' };\nstatic const char16_t flagsArray[] =\n    { 'f', 'l', 'a', 'g', 's' };\n\nstatic const flag_entry gFormatFlags[] = {\n    { referenceArray, sizeof(referenceArray)/2, ResTable_map::TYPE_REFERENCE,\n      \"a reference to another resource, in the form \\\"<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>\\\"\\n\"\n      \"or to a theme attribute in the form \\\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\\\".\"},\n    { stringArray, sizeof(stringArray)/2, ResTable_map::TYPE_STRING,\n      \"a string value, using '\\\\\\\\;' to escape characters such as '\\\\\\\\n' or '\\\\\\\\uxxxx' for a unicode character.\" },\n    { integerArray, sizeof(integerArray)/2, ResTable_map::TYPE_INTEGER,\n      \"an integer value, such as \\\"<code>100</code>\\\".\" },\n    { booleanArray, sizeof(booleanArray)/2, ResTable_map::TYPE_BOOLEAN,\n      \"a boolean value, either \\\"<code>true</code>\\\" or \\\"<code>false</code>\\\".\" },\n    { colorArray, sizeof(colorArray)/2, ResTable_map::TYPE_COLOR,\n      \"a color value, in the form of \\\"<code>#<i>rgb</i></code>\\\", \\\"<code>#<i>argb</i></code>\\\",\\n\"\n      \"\\\"<code>#<i>rrggbb</i></code>\\\", or \\\"<code>#<i>aarrggbb</i></code>\\\".\" },\n    { floatArray, sizeof(floatArray)/2, ResTable_map::TYPE_FLOAT,\n      \"a floating point value, such as \\\"<code>1.2</code>\\\".\"},\n    { dimensionArray, sizeof(dimensionArray)/2, ResTable_map::TYPE_DIMENSION,\n      \"a dimension value, which is a floating point number appended with a unit such as \\\"<code>14.5sp</code>\\\".\\n\"\n      \"Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),\\n\"\n      \"in (inches), mm (millimeters).\" },\n    { fractionArray, sizeof(fractionArray)/2, ResTable_map::TYPE_FRACTION,\n      \"a fractional value, which is a floating point number appended with either % or %p, such as \\\"<code>14.5%</code>\\\".\\n\"\n      \"The % suffix always means a percentage of the base size; the optional %p suffix provides a size relative to\\n\"\n      \"some parent container.\" },\n    { enumArray, sizeof(enumArray)/2, ResTable_map::TYPE_ENUM, NULL },\n    { flagsArray, sizeof(flagsArray)/2, ResTable_map::TYPE_FLAGS, NULL },\n    { NULL, 0, 0, NULL }\n};\n\nstatic const char16_t suggestedArray[] = { 's', 'u', 'g', 'g', 'e', 's', 't', 'e', 'd' };\n\nstatic const flag_entry l10nRequiredFlags[] = {\n    { suggestedArray, sizeof(suggestedArray)/2, ResTable_map::L10N_SUGGESTED, NULL },\n    { NULL, 0, 0, NULL }\n};\n\nstatic const char16_t nulStr[] = { 0 };\n\nstatic uint32_t parse_flags(const char16_t* str, size_t len,\n                             const flag_entry* flags, bool* outError = NULL)\n{\n    while (len > 0 && isspace(*str)) {\n        str++;\n        len--;\n    }\n    while (len > 0 && isspace(str[len-1])) {\n        len--;\n    }\n\n    const char16_t* const end = str + len;\n    uint32_t value = 0;\n\n    while (str < end) {\n        const char16_t* div = str;\n        while (div < end && *div != '|') {\n            div++;\n        }\n\n        const flag_entry* cur = flags;\n        while (cur->name) {\n            if (strzcmp16(cur->name, cur->nameLen, str, div-str) == 0) {\n                value |= cur->value;\n                break;\n            }\n            cur++;\n        }\n\n        if (!cur->name) {\n            if (outError) *outError = true;\n            return 0;\n        }\n\n        str = div < end ? div+1 : div;\n    }\n\n    if (outError) *outError = false;\n    return value;\n}\n\nstatic String16 mayOrMust(int type, int flags)\n{\n    if ((type&(~flags)) == 0) {\n        return String16(\"<p>Must\");\n    }\n    \n    return String16(\"<p>May\");\n}\n\nstatic void appendTypeInfo(ResourceTable* outTable, const String16& pkg,\n        const String16& typeName, const String16& ident, int type,\n        const flag_entry* flags)\n{\n    bool hadType = false;\n    while (flags->name) {\n        if ((type&flags->value) != 0 && flags->description != NULL) {\n            String16 fullMsg(mayOrMust(type, flags->value));\n            fullMsg.append(String16(\" be \"));\n            fullMsg.append(String16(flags->description));\n            outTable->appendTypeComment(pkg, typeName, ident, fullMsg);\n            hadType = true;\n        }\n        flags++;\n    }\n    if (hadType && (type&ResTable_map::TYPE_REFERENCE) == 0) {\n        outTable->appendTypeComment(pkg, typeName, ident,\n                String16(\"<p>This may also be a reference to a resource (in the form\\n\"\n                         \"\\\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\\\") or\\n\"\n                         \"theme attribute (in the form\\n\"\n                         \"\\\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\\\")\\n\"\n                         \"containing a value of this type.\"));\n    }\n}\n\nstruct PendingAttribute\n{\n    const String16 myPackage;\n    const SourcePos sourcePos;\n    const bool appendComment;\n    int32_t type;\n    String16 ident;\n    String16 comment;\n    bool hasErrors;\n    bool added;\n    \n    PendingAttribute(String16 _package, const sp<AaptFile>& in,\n            ResXMLTree& block, bool _appendComment)\n        : myPackage(_package)\n        , sourcePos(in->getPrintableSource(), block.getLineNumber())\n        , appendComment(_appendComment)\n        , type(ResTable_map::TYPE_ANY)\n        , hasErrors(false)\n        , added(false)\n    {\n    }\n    \n    status_t createIfNeeded(ResourceTable* outTable)\n    {\n        if (added || hasErrors) {\n            return NO_ERROR;\n        }\n        added = true;\n\n        String16 attr16(\"attr\");\n        \n        if (outTable->hasBagOrEntry(myPackage, attr16, ident)) {\n            // sourcePos.error(\"Attribute \\\"%s\\\" has already been defined\\n\",\n            //         String8(ident).string());\n            // hasErrors = true;\n            // return UNKNOWN_ERROR;\n            sourcePos.warning(\"Attribute \\\"%s\\\" has already been defined\\n\",\n                    String8(ident).string());\n            return NO_ERROR;\n        }\n        \n        char numberStr[16];\n        sprintf(numberStr, \"%d\", type);\n        status_t err = outTable->addBag(sourcePos, myPackage,\n                attr16, ident, String16(\"\"),\n                String16(\"^type\"),\n                String16(numberStr), NULL, NULL);\n        if (err != NO_ERROR) {\n            hasErrors = true;\n            return err;\n        }\n        outTable->appendComment(myPackage, attr16, ident, comment, appendComment);\n        //printf(\"Attribute %s comment: %s\\n\", String8(ident).string(),\n        //     String8(comment).string());\n        return err;\n    }\n};\n\nstatic status_t compileAttribute(const sp<AaptFile>& in,\n                                 ResXMLTree& block,\n                                 const String16& myPackage,\n                                 ResourceTable* outTable,\n                                 String16* outIdent = NULL,\n                                 bool inStyleable = false)\n{\n    PendingAttribute attr(myPackage, in, block, inStyleable);\n    \n    const String16 attr16(\"attr\");\n    const String16 id16(\"id\");\n\n    // Attribute type constants.\n    const String16 enum16(\"enum\");\n    const String16 flag16(\"flag\");\n\n    ResXMLTree::event_code_t code;\n    size_t len;\n    status_t err;\n    \n    ssize_t identIdx = block.indexOfAttribute(NULL, \"name\");\n    if (identIdx >= 0) {\n        attr.ident = String16(block.getAttributeStringValue(identIdx, &len));\n        if (outIdent) {\n            *outIdent = attr.ident;\n        }\n    } else {\n        attr.sourcePos.error(\"A 'name' attribute is required for <attr>\\n\");\n        attr.hasErrors = true;\n    }\n\n    attr.comment = String16(\n            block.getComment(&len) ? block.getComment(&len) : nulStr);\n\n    ssize_t typeIdx = block.indexOfAttribute(NULL, \"format\");\n    if (typeIdx >= 0) {\n        String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len));\n        attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags);\n        if (attr.type == 0) {\n            attr.sourcePos.error(\"Tag <attr> 'format' attribute value \\\"%s\\\" not valid\\n\",\n                    String8(typeStr).string());\n            attr.hasErrors = true;\n        }\n        attr.createIfNeeded(outTable);\n    } else if (!inStyleable) {\n        // Attribute definitions outside of styleables always define the\n        // attribute as a generic value.\n        attr.createIfNeeded(outTable);\n    }\n\n    //printf(\"Attribute %s: type=0x%08x\\n\", String8(attr.ident).string(), attr.type);\n\n    ssize_t minIdx = block.indexOfAttribute(NULL, \"min\");\n    if (minIdx >= 0) {\n        String16 val = String16(block.getAttributeStringValue(minIdx, &len));\n        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {\n            attr.sourcePos.error(\"Tag <attr> 'min' attribute must be a number, not \\\"%s\\\"\\n\",\n                    String8(val).string());\n            attr.hasErrors = true;\n        }\n        attr.createIfNeeded(outTable);\n        if (!attr.hasErrors) {\n            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,\n                    String16(\"\"), String16(\"^min\"), String16(val), NULL, NULL);\n            if (err != NO_ERROR) {\n                attr.hasErrors = true;\n            }\n        }\n    }\n\n    ssize_t maxIdx = block.indexOfAttribute(NULL, \"max\");\n    if (maxIdx >= 0) {\n        String16 val = String16(block.getAttributeStringValue(maxIdx, &len));\n        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {\n            attr.sourcePos.error(\"Tag <attr> 'max' attribute must be a number, not \\\"%s\\\"\\n\",\n                    String8(val).string());\n            attr.hasErrors = true;\n        }\n        attr.createIfNeeded(outTable);\n        if (!attr.hasErrors) {\n            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,\n                    String16(\"\"), String16(\"^max\"), String16(val), NULL, NULL);\n            attr.hasErrors = true;\n        }\n    }\n\n    if ((minIdx >= 0 || maxIdx >= 0) && (attr.type&ResTable_map::TYPE_INTEGER) == 0) {\n        attr.sourcePos.error(\"Tag <attr> must have format=integer attribute if using max or min\\n\");\n        attr.hasErrors = true;\n    }\n\n    ssize_t l10nIdx = block.indexOfAttribute(NULL, \"localization\");\n    if (l10nIdx >= 0) {\n        const uint16_t* str = block.getAttributeStringValue(l10nIdx, &len);\n        bool error;\n        uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error);\n        if (error) {\n            attr.sourcePos.error(\"Tag <attr> 'localization' attribute value \\\"%s\\\" not valid\\n\",\n                    String8(str).string());\n            attr.hasErrors = true;\n        }\n        attr.createIfNeeded(outTable);\n        if (!attr.hasErrors) {\n            char buf[11];\n            sprintf(buf, \"%d\", l10n_required);\n            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,\n                    String16(\"\"), String16(\"^l10n\"), String16(buf), NULL, NULL);\n            if (err != NO_ERROR) {\n                attr.hasErrors = true;\n            }\n        }\n    }\n\n    String16 enumOrFlagsComment;\n    \n    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::START_TAG) {\n            uint32_t localType = 0;\n            if (strcmp16(block.getElementName(&len), enum16.string()) == 0) {\n                localType = ResTable_map::TYPE_ENUM;\n            } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) {\n                localType = ResTable_map::TYPE_FLAGS;\n            } else {\n                SourcePos(in->getPrintableSource(), block.getLineNumber())\n                        .error(\"Tag <%s> can not appear inside <attr>, only <enum> or <flag>\\n\",\n                        String8(block.getElementName(&len)).string());\n                return UNKNOWN_ERROR;\n            }\n\n            attr.createIfNeeded(outTable);\n            \n            if (attr.type == ResTable_map::TYPE_ANY) {\n                // No type was explicitly stated, so supplying enum tags\n                // implicitly creates an enum or flag.\n                attr.type = 0;\n            }\n\n            if ((attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) == 0) {\n                // Wasn't originally specified as an enum, so update its type.\n                attr.type |= localType;\n                if (!attr.hasErrors) {\n                    char numberStr[16];\n                    sprintf(numberStr, \"%d\", attr.type);\n                    err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),\n                            myPackage, attr16, attr.ident, String16(\"\"),\n                            String16(\"^type\"), String16(numberStr), NULL, NULL, true);\n                    if (err != NO_ERROR) {\n                        attr.hasErrors = true;\n                    }\n                }\n            } else if ((uint32_t)(attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) != localType) {\n                if (localType == ResTable_map::TYPE_ENUM) {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber())\n                            .error(\"<enum> attribute can not be used inside a flags format\\n\");\n                    attr.hasErrors = true;\n                } else {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber())\n                            .error(\"<flag> attribute can not be used inside a enum format\\n\");\n                    attr.hasErrors = true;\n                }\n            }\n\n            String16 itemIdent;\n            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, \"name\");\n            if (itemIdentIdx >= 0) {\n                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));\n            } else {\n                SourcePos(in->getPrintableSource(), block.getLineNumber())\n                        .error(\"A 'name' attribute is required for <enum> or <flag>\\n\");\n                attr.hasErrors = true;\n            }\n\n            String16 value;\n            ssize_t valueIdx = block.indexOfAttribute(NULL, \"value\");\n            if (valueIdx >= 0) {\n                value = String16(block.getAttributeStringValue(valueIdx, &len));\n            } else {\n                SourcePos(in->getPrintableSource(), block.getLineNumber())\n                        .error(\"A 'value' attribute is required for <enum> or <flag>\\n\");\n                attr.hasErrors = true;\n            }\n            if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) {\n                SourcePos(in->getPrintableSource(), block.getLineNumber())\n                        .error(\"Tag <enum> or <flag> 'value' attribute must be a number,\"\n                        \" not \\\"%s\\\"\\n\",\n                        String8(value).string());\n                attr.hasErrors = true;\n            }\n\n            if (!attr.hasErrors) {\n                if (enumOrFlagsComment.size() == 0) {\n                    enumOrFlagsComment.append(mayOrMust(attr.type,\n                            ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS));\n                    enumOrFlagsComment.append((attr.type&ResTable_map::TYPE_ENUM)\n                                       ? String16(\" be one of the following constant values.\")\n                                       : String16(\" be one or more (separated by '|') of the following constant values.\"));\n                    enumOrFlagsComment.append(String16(\"</p>\\n<table>\\n\"\n                                                \"<colgroup align=\\\"left\\\" />\\n\"\n                                                \"<colgroup align=\\\"left\\\" />\\n\"\n                                                \"<colgroup align=\\\"left\\\" />\\n\"\n                                                \"<tr><th>Constant</th><th>Value</th><th>Description</th></tr>\"));\n                }\n                \n                enumOrFlagsComment.append(String16(\"\\n<tr><td><code>\"));\n                enumOrFlagsComment.append(itemIdent);\n                enumOrFlagsComment.append(String16(\"</code></td><td>\"));\n                enumOrFlagsComment.append(value);\n                enumOrFlagsComment.append(String16(\"</td><td>\"));\n                if (block.getComment(&len)) {\n                    enumOrFlagsComment.append(String16(block.getComment(&len)));\n                }\n                enumOrFlagsComment.append(String16(\"</td></tr>\"));\n                \n                err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),\n                                       myPackage,\n                                       attr16, attr.ident, String16(\"\"),\n                                       itemIdent, value, NULL, NULL, false, true);\n                if (err != NO_ERROR) {\n                    attr.hasErrors = true;\n                }\n            }\n        } else if (code == ResXMLTree::END_TAG) {\n            if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {\n                break;\n            }\n            if ((attr.type&ResTable_map::TYPE_ENUM) != 0) {\n                if (strcmp16(block.getElementName(&len), enum16.string()) != 0) {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber())\n                            .error(\"Found tag </%s> where </enum> is expected\\n\",\n                            String8(block.getElementName(&len)).string());\n                    return UNKNOWN_ERROR;\n                }\n            } else {\n                if (strcmp16(block.getElementName(&len), flag16.string()) != 0) {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber())\n                            .error(\"Found tag </%s> where </flag> is expected\\n\",\n                            String8(block.getElementName(&len)).string());\n                    return UNKNOWN_ERROR;\n                }\n            }\n        }\n    }\n    \n    if (!attr.hasErrors && attr.added) {\n        appendTypeInfo(outTable, myPackage, attr16, attr.ident, attr.type, gFormatFlags);\n    }\n    \n    if (!attr.hasErrors && enumOrFlagsComment.size() > 0) {\n        enumOrFlagsComment.append(String16(\"\\n</table>\"));\n        outTable->appendTypeComment(myPackage, attr16, attr.ident, enumOrFlagsComment);\n    }\n\n\n    return NO_ERROR;\n}\n\nbool localeIsDefined(const ResTable_config& config)\n{\n    return config.locale == 0;\n}\n\nstatus_t parseAndAddBag(Bundle* bundle,\n                        const sp<AaptFile>& in,\n                        ResXMLTree* block,\n                        const ResTable_config& config,\n                        const String16& myPackage,\n                        const String16& curType,\n                        const String16& ident,\n                        const String16& parentIdent,\n                        const String16& itemIdent,\n                        int32_t curFormat,\n                        bool isFormatted,\n                        const String16& product,\n                        PseudolocalizationMethod pseudolocalize,\n                        const bool overwrite,\n                        ResourceTable* outTable)\n{\n    status_t err;\n    const String16 item16(\"item\");\n\n    String16 str;\n    Vector<StringPool::entry_style_span> spans;\n    err = parseStyledString(bundle, in->getPrintableSource().string(),\n                            block, item16, &str, &spans, isFormatted,\n                            pseudolocalize);\n    if (err != NO_ERROR) {\n        return err;\n    }\n    \n    NOISY(printf(\"Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d \"\n                 \" pid=%s, bag=%s, id=%s: %s\\n\",\n                 config.language[0], config.language[1],\n                 config.country[0], config.country[1],\n                 config.orientation, config.density,\n                 String8(parentIdent).string(),\n                 String8(ident).string(),\n                 String8(itemIdent).string(),\n                 String8(str).string()));\n\n    err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()),\n                           myPackage, curType, ident, parentIdent, itemIdent, str,\n                           &spans, &config, overwrite, false, curFormat);\n    return err;\n}\n\n/*\n * Returns true if needle is one of the elements in the comma-separated list\n * haystack, false otherwise.\n */\nbool isInProductList(const String16& needle, const String16& haystack) {\n    const char16_t *needle2 = needle.string();\n    const char16_t *haystack2 = haystack.string();\n    size_t needlesize = needle.size();\n\n    while (*haystack2 != '\\0') {\n        if (strncmp16(haystack2, needle2, needlesize) == 0) {\n            if (haystack2[needlesize] == '\\0' || haystack2[needlesize] == ',') {\n                return true;\n            }\n        }\n\n        while (*haystack2 != '\\0' && *haystack2 != ',') {\n            haystack2++;\n        }\n        if (*haystack2 == ',') {\n            haystack2++;\n        }\n    }\n\n    return false;\n}\n\n/*\n * A simple container that holds a resource type and name. It is ordered first by type then\n * by name.\n */\nstruct type_ident_pair_t {\n    String16 type;\n    String16 ident;\n\n    type_ident_pair_t() { };\n    type_ident_pair_t(const String16& t, const String16& i) : type(t), ident(i) { }\n    type_ident_pair_t(const type_ident_pair_t& o) : type(o.type), ident(o.ident) { }\n    inline bool operator < (const type_ident_pair_t& o) const {\n        int cmp = compare_type(type, o.type);\n        if (cmp < 0) {\n            return true;\n        } else if (cmp > 0) {\n            return false;\n        } else {\n            return strictly_order_type(ident, o.ident);\n        }\n    }\n};\n\n\nstatus_t parseAndAddEntry(Bundle* bundle,\n                        const sp<AaptFile>& in,\n                        ResXMLTree* block,\n                        const ResTable_config& config,\n                        const String16& myPackage,\n                        const String16& curType,\n                        const String16& ident,\n                        const String16& curTag,\n                        bool curIsStyled,\n                        int32_t curFormat,\n                        bool isFormatted,\n                        const String16& product,\n                        PseudolocalizationMethod pseudolocalize,\n                        const bool overwrite,\n                        KeyedVector<type_ident_pair_t, bool>* skippedResourceNames,\n                        ResourceTable* outTable)\n{\n    status_t err;\n\n    String16 str;\n    Vector<StringPool::entry_style_span> spans;\n    err = parseStyledString(bundle, in->getPrintableSource().string(), block,\n                            curTag, &str, curIsStyled ? &spans : NULL,\n                            isFormatted, pseudolocalize);\n\n    if (err < NO_ERROR) { \n        return err;\n    }\n\n    /*\n     * If a product type was specified on the command line\n     * and also in the string, and the two are not the same,\n     * return without adding the string.\n     */\n\n    const char *bundleProduct = bundle->getProduct();\n    if (bundleProduct == NULL) {\n        bundleProduct = \"\";\n    }\n\n    if (product.size() != 0) {\n        /*\n         * If the command-line-specified product is empty, only \"default\"\n         * matches.  Other variants are skipped.  This is so generation\n         * of the R.java file when the product is not known is predictable.\n         */\n\n        if (bundleProduct[0] == '\\0') {\n            if (strcmp16(String16(\"default\").string(), product.string()) != 0) {\n                /*\n                 * This string has a product other than 'default'. Do not add it,\n                 * but record it so that if we do not see the same string with\n                 * product 'default' or no product, then report an error.\n                 */\n                skippedResourceNames->replaceValueFor(\n                        type_ident_pair_t(curType, ident), true);\n                return NO_ERROR;\n            }\n        } else {\n            /*\n             * The command-line product is not empty.\n             * If the product for this string is on the command-line list,\n             * it matches.  \"default\" also matches, but only if nothing\n             * else has matched already.\n             */\n\n            if (isInProductList(product, String16(bundleProduct))) {\n                ;\n            } else if (strcmp16(String16(\"default\").string(), product.string()) == 0 &&\n                       !outTable->hasBagOrEntry(myPackage, curType, ident, config)) {\n                ;\n            } else {\n                return NO_ERROR;\n            }\n        }\n    }\n\n    NOISY(printf(\"Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\\n\",\n                 config.language[0], config.language[1],\n                 config.country[0], config.country[1],\n                 config.orientation, config.density,\n                 String8(ident).string(), String8(str).string()));\n\n    err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()),\n                             myPackage, curType, ident, str, &spans, &config,\n                             false, curFormat, overwrite);\n\n    return err;\n}\n\nstatus_t compileResourceFile(Bundle* bundle,\n                             const sp<AaptAssets>& assets,\n                             const sp<AaptFile>& in,\n                             const ResTable_config& defParams,\n                             const bool overwrite,\n                             ResourceTable* outTable)\n{\n    ResXMLTree block;\n    status_t err = parseXMLResource(in, &block, false, true);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    // Top-level tag.\n    const String16 resources16(\"resources\");\n\n    // Identifier declaration tags.\n    const String16 declare_styleable16(\"declare-styleable\");\n    const String16 attr16(\"attr\");\n\n    // Data creation organizational tags.\n    const String16 string16(\"string\");\n    const String16 drawable16(\"drawable\");\n    const String16 color16(\"color\");\n    const String16 bool16(\"bool\");\n    const String16 integer16(\"integer\");\n    const String16 dimen16(\"dimen\");\n    const String16 fraction16(\"fraction\");\n    const String16 style16(\"style\");\n    const String16 plurals16(\"plurals\");\n    const String16 array16(\"array\");\n    const String16 string_array16(\"string-array\");\n    const String16 integer_array16(\"integer-array\");\n    const String16 public16(\"public\");\n    const String16 public_padding16(\"public-padding\");\n    const String16 private_symbols16(\"private-symbols\");\n    const String16 java_symbol16(\"java-symbol\");\n    const String16 add_resource16(\"add-resource\");\n    const String16 skip16(\"skip\");\n    const String16 eat_comment16(\"eat-comment\");\n\n    // Data creation tags.\n    const String16 bag16(\"bag\");\n    const String16 item16(\"item\");\n\n    // Attribute type constants.\n    const String16 enum16(\"enum\");\n\n    // plural values\n    const String16 other16(\"other\");\n    const String16 quantityOther16(\"^other\");\n    const String16 zero16(\"zero\");\n    const String16 quantityZero16(\"^zero\");\n    const String16 one16(\"one\");\n    const String16 quantityOne16(\"^one\");\n    const String16 two16(\"two\");\n    const String16 quantityTwo16(\"^two\");\n    const String16 few16(\"few\");\n    const String16 quantityFew16(\"^few\");\n    const String16 many16(\"many\");\n    const String16 quantityMany16(\"^many\");\n\n    // useful attribute names and special values\n    const String16 name16(\"name\");\n    const String16 translatable16(\"translatable\");\n    const String16 formatted16(\"formatted\");\n    const String16 false16(\"false\");\n\n    const String16 myPackage(assets->getPackage());\n\n    bool hasErrors = false;\n\n    bool fileIsTranslatable = true;\n    if (strstr(in->getPrintableSource().string(), \"donottranslate\") != NULL) {\n        fileIsTranslatable = false;\n    }\n\n    DefaultKeyedVector<String16, uint32_t> nextPublicId(0);\n\n    // Stores the resource names that were skipped. Typically this happens when\n    // AAPT is invoked without a product specified and a resource has no\n    // 'default' product attribute.\n    KeyedVector<type_ident_pair_t, bool> skippedResourceNames;\n\n    ResXMLTree::event_code_t code;\n    do {\n        code = block.next();\n    } while (code == ResXMLTree::START_NAMESPACE);\n\n    size_t len;\n    if (code != ResXMLTree::START_TAG) {\n        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                \"No start tag found\\n\");\n        return UNKNOWN_ERROR;\n    }\n    if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {\n        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                \"Invalid start tag %s\\n\", String8(block.getElementName(&len)).string());\n        return UNKNOWN_ERROR;\n    }\n\n    ResTable_config curParams(defParams);\n\n    ResTable_config pseudoParams(curParams);\n        pseudoParams.language[0] = 'e';\n        pseudoParams.language[1] = 'n';\n        pseudoParams.country[0] = 'X';\n        pseudoParams.country[1] = 'A';\n\n    ResTable_config pseudoBidiParams(curParams);\n        pseudoBidiParams.language[0] = 'a';\n        pseudoBidiParams.language[1] = 'r';\n        pseudoBidiParams.country[0] = 'X';\n        pseudoBidiParams.country[1] = 'B';\n\n    // We should skip resources for pseudolocales if they were\n    // already added automatically. This is a fix for a transition period when\n    // manually pseudolocalized resources may be expected.\n    // TODO: remove this check after next SDK version release.\n    if ((bundle->getPseudolocalize() & PSEUDO_ACCENTED &&\n         curParams.locale == pseudoParams.locale) ||\n        (bundle->getPseudolocalize() & PSEUDO_BIDI &&\n         curParams.locale == pseudoBidiParams.locale)) {\n        SourcePos(in->getPrintableSource(), 0).warning(\n                \"Resource file %s is skipped as pseudolocalization\"\n                \" was done automatically.\",\n                in->getPrintableSource().string());\n        return NO_ERROR;\n    }\n\n    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::START_TAG) {\n            const String16* curTag = NULL;\n            String16 curType;\n            int32_t curFormat = ResTable_map::TYPE_ANY;\n            bool curIsBag = false;\n            bool curIsBagReplaceOnOverwrite = false;\n            bool curIsStyled = false;\n            bool curIsPseudolocalizable = false;\n            bool curIsFormatted = fileIsTranslatable;\n            bool localHasErrors = false;\n\n            if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n                        && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {\n                            break;\n                        }\n                    }\n                }\n                continue;\n\n            } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n                        && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {\n                            break;\n                        }\n                    }\n                }\n                continue;\n\n            } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) {\n                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());\n            \n                String16 type;\n                ssize_t typeIdx = block.indexOfAttribute(NULL, \"type\");\n                if (typeIdx < 0) {\n                    srcPos.error(\"A 'type' attribute is required for <public>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                type = String16(block.getAttributeStringValue(typeIdx, &len));\n\n                String16 name;\n                ssize_t nameIdx = block.indexOfAttribute(NULL, \"name\");\n                if (nameIdx < 0) {\n                    srcPos.error(\"A 'name' attribute is required for <public>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                name = String16(block.getAttributeStringValue(nameIdx, &len));\n\n                uint32_t ident = 0;\n                ssize_t identIdx = block.indexOfAttribute(NULL, \"id\");\n                if (identIdx >= 0) {\n                    const char16_t* identStr = block.getAttributeStringValue(identIdx, &len);\n                    Res_value identValue;\n                    if (!ResTable::stringToInt(identStr, len, &identValue)) {\n                        srcPos.error(\"Given 'id' attribute is not an integer: %s\\n\",\n                                String8(block.getAttributeStringValue(identIdx, &len)).string());\n                        hasErrors = localHasErrors = true;\n                    } else {\n                        ident = identValue.data;\n                        nextPublicId.replaceValueFor(type, ident+1);\n                    }\n                } else if (nextPublicId.indexOfKey(type) < 0) {\n                    srcPos.error(\"No 'id' attribute supplied <public>,\"\n                            \" and no previous id defined in this file.\\n\");\n                    hasErrors = localHasErrors = true;\n                } else if (!localHasErrors) {\n                    ident = nextPublicId.valueFor(type);\n                    nextPublicId.replaceValueFor(type, ident+1);\n                }\n\n                if (!localHasErrors) {\n                    err = outTable->addPublic(srcPos, myPackage, type, name, ident);\n                    if (err < NO_ERROR) {\n                        hasErrors = localHasErrors = true;\n                    }\n                }\n                if (!localHasErrors) {\n                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8(\"R\"));\n                    if (symbols != NULL) {\n                        symbols = symbols->addNestedSymbol(String8(type), srcPos);\n                    }\n                    if (symbols != NULL) {\n                        symbols->makeSymbolPublic(String8(name), srcPos);\n                        String16 comment(\n                            block.getComment(&len) ? block.getComment(&len) : nulStr);\n                        symbols->appendComment(String8(name), comment, srcPos);\n                    } else {\n                        srcPos.error(\"Unable to create symbols!\\n\");\n                        hasErrors = localHasErrors = true;\n                    }\n                }\n\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), public16.string()) == 0) {\n                            break;\n                        }\n                    }\n                }\n                continue;\n\n            } else if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {\n                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());\n            \n                String16 type;\n                ssize_t typeIdx = block.indexOfAttribute(NULL, \"type\");\n                if (typeIdx < 0) {\n                    srcPos.error(\"A 'type' attribute is required for <public-padding>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                type = String16(block.getAttributeStringValue(typeIdx, &len));\n\n                String16 name;\n                ssize_t nameIdx = block.indexOfAttribute(NULL, \"name\");\n                if (nameIdx < 0) {\n                    srcPos.error(\"A 'name' attribute is required for <public-padding>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                name = String16(block.getAttributeStringValue(nameIdx, &len));\n\n                uint32_t start = 0;\n                ssize_t startIdx = block.indexOfAttribute(NULL, \"start\");\n                if (startIdx >= 0) {\n                    const char16_t* startStr = block.getAttributeStringValue(startIdx, &len);\n                    Res_value startValue;\n                    if (!ResTable::stringToInt(startStr, len, &startValue)) {\n                        srcPos.error(\"Given 'start' attribute is not an integer: %s\\n\",\n                                String8(block.getAttributeStringValue(startIdx, &len)).string());\n                        hasErrors = localHasErrors = true;\n                    } else {\n                        start = startValue.data;\n                    }\n                } else if (nextPublicId.indexOfKey(type) < 0) {\n                    srcPos.error(\"No 'start' attribute supplied <public-padding>,\"\n                            \" and no previous id defined in this file.\\n\");\n                    hasErrors = localHasErrors = true;\n                } else if (!localHasErrors) {\n                    start = nextPublicId.valueFor(type);\n                }\n\n                uint32_t end = 0;\n                ssize_t endIdx = block.indexOfAttribute(NULL, \"end\");\n                if (endIdx >= 0) {\n                    const char16_t* endStr = block.getAttributeStringValue(endIdx, &len);\n                    Res_value endValue;\n                    if (!ResTable::stringToInt(endStr, len, &endValue)) {\n                        srcPos.error(\"Given 'end' attribute is not an integer: %s\\n\",\n                                String8(block.getAttributeStringValue(endIdx, &len)).string());\n                        hasErrors = localHasErrors = true;\n                    } else {\n                        end = endValue.data;\n                    }\n                } else {\n                    srcPos.error(\"No 'end' attribute supplied <public-padding>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n\n                if (end >= start) {\n                    nextPublicId.replaceValueFor(type, end+1);\n                } else {\n                    srcPos.error(\"Padding start '%ul' is after end '%ul'\\n\",\n                            start, end);\n                    hasErrors = localHasErrors = true;\n                }\n                \n                String16 comment(\n                    block.getComment(&len) ? block.getComment(&len) : nulStr);\n                for (uint32_t curIdent=start; curIdent<=end; curIdent++) {\n                    if (localHasErrors) {\n                        break;\n                    }\n                    String16 curName(name);\n                    char buf[64];\n                    sprintf(buf, \"%d\", (int)(end-curIdent+1));\n                    curName.append(String16(buf));\n                    \n                    err = outTable->addEntry(srcPos, myPackage, type, curName,\n                                             String16(\"padding\"), NULL, &curParams, false,\n                                             ResTable_map::TYPE_STRING, overwrite);\n                    if (err < NO_ERROR) {\n                        hasErrors = localHasErrors = true;\n                        break;\n                    }\n                    err = outTable->addPublic(srcPos, myPackage, type,\n                            curName, curIdent);\n                    if (err < NO_ERROR) {\n                        hasErrors = localHasErrors = true;\n                        break;\n                    }\n                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8(\"R\"));\n                    if (symbols != NULL) {\n                        symbols = symbols->addNestedSymbol(String8(type), srcPos);\n                    }\n                    if (symbols != NULL) {\n                        symbols->makeSymbolPublic(String8(curName), srcPos);\n                        symbols->appendComment(String8(curName), comment, srcPos);\n                    } else {\n                        srcPos.error(\"Unable to create symbols!\\n\");\n                        hasErrors = localHasErrors = true;\n                    }\n                }\n\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {\n                            break;\n                        }\n                    }\n                }\n                continue;\n\n            } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {\n                String16 pkg;\n                ssize_t pkgIdx = block.indexOfAttribute(NULL, \"package\");\n                if (pkgIdx < 0) {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                            \"A 'package' attribute is required for <private-symbols>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                pkg = String16(block.getAttributeStringValue(pkgIdx, &len));\n                if (!localHasErrors) {\n                    assets->setSymbolsPrivatePackage(String8(pkg));\n                }\n\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {\n                            break;\n                        }\n                    }\n                }\n                continue;\n\n            } else if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) {\n                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());\n            \n                String16 type;\n                ssize_t typeIdx = block.indexOfAttribute(NULL, \"type\");\n                if (typeIdx < 0) {\n                    srcPos.error(\"A 'type' attribute is required for <public>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                type = String16(block.getAttributeStringValue(typeIdx, &len));\n\n                String16 name;\n                ssize_t nameIdx = block.indexOfAttribute(NULL, \"name\");\n                if (nameIdx < 0) {\n                    srcPos.error(\"A 'name' attribute is required for <public>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                name = String16(block.getAttributeStringValue(nameIdx, &len));\n\n                sp<AaptSymbols> symbols = assets->getJavaSymbolsFor(String8(\"R\"));\n                if (symbols != NULL) {\n                    symbols = symbols->addNestedSymbol(String8(type), srcPos);\n                }\n                if (symbols != NULL) {\n                    symbols->makeSymbolJavaSymbol(String8(name), srcPos);\n                    String16 comment(\n                        block.getComment(&len) ? block.getComment(&len) : nulStr);\n                    symbols->appendComment(String8(name), comment, srcPos);\n                } else {\n                    srcPos.error(\"Unable to create symbols!\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) {\n                            break;\n                        }\n                    }\n                }\n                continue;\n\n\n            } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {\n                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());\n            \n                String16 typeName;\n                ssize_t typeIdx = block.indexOfAttribute(NULL, \"type\");\n                if (typeIdx < 0) {\n                    srcPos.error(\"A 'type' attribute is required for <add-resource>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                typeName = String16(block.getAttributeStringValue(typeIdx, &len));\n\n                String16 name;\n                ssize_t nameIdx = block.indexOfAttribute(NULL, \"name\");\n                if (nameIdx < 0) {\n                    srcPos.error(\"A 'name' attribute is required for <add-resource>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                name = String16(block.getAttributeStringValue(nameIdx, &len));\n\n                outTable->canAddEntry(srcPos, myPackage, typeName, name);\n\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {\n                            break;\n                        }\n                    }\n                }\n                continue;\n                \n            } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {\n                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());\n                                \n                String16 ident;\n                ssize_t identIdx = block.indexOfAttribute(NULL, \"name\");\n                if (identIdx < 0) {\n                    srcPos.error(\"A 'name' attribute is required for <declare-styleable>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                ident = String16(block.getAttributeStringValue(identIdx, &len));\n\n                sp<AaptSymbols> symbols = assets->getSymbolsFor(String8(\"R\"));\n                if (!localHasErrors) {\n                    if (symbols != NULL) {\n                        symbols = symbols->addNestedSymbol(String8(\"styleable\"), srcPos);\n                    }\n                    sp<AaptSymbols> styleSymbols = symbols;\n                    if (symbols != NULL) {\n                        symbols = symbols->addNestedSymbol(String8(ident), srcPos);\n                    }\n                    if (symbols == NULL) {\n                        srcPos.error(\"Unable to create symbols!\\n\");\n                        return UNKNOWN_ERROR;\n                    }\n                    \n                    String16 comment(\n                        block.getComment(&len) ? block.getComment(&len) : nulStr);\n                    styleSymbols->appendComment(String8(ident), comment, srcPos);\n                } else {\n                    symbols = NULL;\n                }\n\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n                    if (code == ResXMLTree::START_TAG) {\n                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {\n                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n                                   && code != ResXMLTree::BAD_DOCUMENT) {\n                                if (code == ResXMLTree::END_TAG) {\n                                    if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {\n                                        break;\n                                    }\n                                }\n                            }\n                            continue;\n                        } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {\n                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n                                   && code != ResXMLTree::BAD_DOCUMENT) {\n                                if (code == ResXMLTree::END_TAG) {\n                                    if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {\n                                        break;\n                                    }\n                                }\n                            }\n                            continue;\n                        } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) {\n                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                    \"Tag <%s> can not appear inside <declare-styleable>, only <attr>\\n\",\n                                    String8(block.getElementName(&len)).string());\n                            return UNKNOWN_ERROR;\n                        }\n\n                        String16 comment(\n                            block.getComment(&len) ? block.getComment(&len) : nulStr);\n                        String16 itemIdent;\n                        err = compileAttribute(in, block, myPackage, outTable, &itemIdent, true);\n                        if (err != NO_ERROR) {\n                            hasErrors = localHasErrors = true;\n                        }\n\n                        if (symbols != NULL) {\n                            SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber());\n                            symbols->addSymbol(String8(itemIdent), 0, srcPos);\n                            symbols->appendComment(String8(itemIdent), comment, srcPos);\n                            //printf(\"Attribute %s comment: %s\\n\", String8(itemIdent).string(),\n                            //     String8(comment).string());\n                        }\n                    } else if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {\n                            break;\n                        }\n\n                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                \"Found tag </%s> where </attr> is expected\\n\",\n                                String8(block.getElementName(&len)).string());\n                        return UNKNOWN_ERROR;\n                    }\n                }\n                continue;\n\n            } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {\n                err = compileAttribute(in, block, myPackage, outTable, NULL);\n                if (err != NO_ERROR) {\n                    hasErrors = true;\n                }\n                continue;\n\n            } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) {\n                curTag = &item16;\n                ssize_t attri = block.indexOfAttribute(NULL, \"type\");\n                if (attri >= 0) {\n                    curType = String16(block.getAttributeStringValue(attri, &len));\n                    ssize_t formatIdx = block.indexOfAttribute(NULL, \"format\");\n                    if (formatIdx >= 0) {\n                        String16 formatStr = String16(block.getAttributeStringValue(\n                                formatIdx, &len));\n                        curFormat = parse_flags(formatStr.string(), formatStr.size(),\n                                                gFormatFlags);\n                        if (curFormat == 0) {\n                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                    \"Tag <item> 'format' attribute value \\\"%s\\\" not valid\\n\",\n                                    String8(formatStr).string());\n                            hasErrors = localHasErrors = true;\n                        }\n                    }\n                } else {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                            \"A 'type' attribute is required for <item>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n                curIsStyled = true;\n            } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) {\n                // Note the existence and locale of every string we process\n                char rawLocale[RESTABLE_MAX_LOCALE_LEN];\n                curParams.getBcp47Locale(rawLocale);\n                String8 locale(rawLocale);\n                String16 name;\n                String16 translatable;\n                String16 formatted;\n\n                size_t n = block.getAttributeCount();\n                for (size_t i = 0; i < n; i++) {\n                    size_t length;\n                    const uint16_t* attr = block.getAttributeName(i, &length);\n                    if (strcmp16(attr, name16.string()) == 0) {\n                        name.setTo(block.getAttributeStringValue(i, &length));\n                    } else if (strcmp16(attr, translatable16.string()) == 0) {\n                        translatable.setTo(block.getAttributeStringValue(i, &length));\n                    } else if (strcmp16(attr, formatted16.string()) == 0) {\n                        formatted.setTo(block.getAttributeStringValue(i, &length));\n                    }\n                }\n                \n                if (name.size() > 0) {\n                    if (translatable == false16) {\n                        curIsFormatted = false;\n                        // Untranslatable strings must only exist in the default [empty] locale\n                        if (locale.size() > 0) {\n                            SourcePos(in->getPrintableSource(), block.getLineNumber()).warning(\n                                    \"string '%s' marked untranslatable but exists in locale '%s'\\n\",\n                                    String8(name).string(),\n                                    locale.string());\n                            // hasErrors = localHasErrors = true;\n                        } else {\n                            // Intentionally empty block:\n                            //\n                            // Don't add untranslatable strings to the localization table; that\n                            // way if we later see localizations of them, they'll be flagged as\n                            // having no default translation.\n                        }\n                    } else {\n                        outTable->addLocalization(\n                                name,\n                                locale,\n                                SourcePos(in->getPrintableSource(), block.getLineNumber()));\n                    }\n\n                    if (formatted == false16) {\n                        curIsFormatted = false;\n                    }\n                }\n\n                curTag = &string16;\n                curType = string16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;\n                curIsStyled = true;\n                curIsPseudolocalizable = fileIsTranslatable && (translatable != false16);\n            } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) {\n                curTag = &drawable16;\n                curType = drawable16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;\n            } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) {\n                curTag = &color16;\n                curType = color16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;\n            } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) {\n                curTag = &bool16;\n                curType = bool16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN;\n            } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) {\n                curTag = &integer16;\n                curType = integer16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;\n            } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) {\n                curTag = &dimen16;\n                curType = dimen16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION;\n            } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) {\n                curTag = &fraction16;\n                curType = fraction16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION;\n            } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) {\n                curTag = &bag16;\n                curIsBag = true;\n                ssize_t attri = block.indexOfAttribute(NULL, \"type\");\n                if (attri >= 0) {\n                    curType = String16(block.getAttributeStringValue(attri, &len));\n                } else {\n                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                            \"A 'type' attribute is required for <bag>\\n\");\n                    hasErrors = localHasErrors = true;\n                }\n            } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) {\n                curTag = &style16;\n                curType = style16;\n                curIsBag = true;\n            } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) {\n                curTag = &plurals16;\n                curType = plurals16;\n                curIsBag = true;\n                curIsPseudolocalizable = fileIsTranslatable;\n            } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) {\n                curTag = &array16;\n                curType = array16;\n                curIsBag = true;\n                curIsBagReplaceOnOverwrite = true;\n                ssize_t formatIdx = block.indexOfAttribute(NULL, \"format\");\n                if (formatIdx >= 0) {\n                    String16 formatStr = String16(block.getAttributeStringValue(\n                            formatIdx, &len));\n                    curFormat = parse_flags(formatStr.string(), formatStr.size(),\n                                            gFormatFlags);\n                    if (curFormat == 0) {\n                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                \"Tag <array> 'format' attribute value \\\"%s\\\" not valid\\n\",\n                                String8(formatStr).string());\n                        hasErrors = localHasErrors = true;\n                    }\n                }\n            } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) {\n                // Check whether these strings need valid formats.\n                // (simplified form of what string16 does above)\n                bool isTranslatable = false;\n                size_t n = block.getAttributeCount();\n\n                // Pseudolocalizable by default, unless this string array isn't\n                // translatable.\n                for (size_t i = 0; i < n; i++) {\n                    size_t length;\n                    const uint16_t* attr = block.getAttributeName(i, &length);\n                    if (strcmp16(attr, formatted16.string()) == 0) {\n                        const uint16_t* value = block.getAttributeStringValue(i, &length);\n                        if (strcmp16(value, false16.string()) == 0) {\n                            curIsFormatted = false;\n                        }\n                    } else if (strcmp16(attr, translatable16.string()) == 0) {\n                        const uint16_t* value = block.getAttributeStringValue(i, &length);\n                        if (strcmp16(value, false16.string()) == 0) {\n                            isTranslatable = false;\n                        }\n                    }\n                }\n\n                curTag = &string_array16;\n                curType = array16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;\n                curIsBag = true;\n                curIsBagReplaceOnOverwrite = true;\n                curIsPseudolocalizable = isTranslatable && fileIsTranslatable;\n            } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) {\n                curTag = &integer_array16;\n                curType = array16;\n                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;\n                curIsBag = true;\n                curIsBagReplaceOnOverwrite = true;\n            } else {\n                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                        \"Found tag %s where item is expected\\n\",\n                        String8(block.getElementName(&len)).string());\n                return UNKNOWN_ERROR;\n            }\n\n            String16 ident;\n            ssize_t identIdx = block.indexOfAttribute(NULL, \"name\");\n            if (identIdx >= 0) {\n                ident = String16(block.getAttributeStringValue(identIdx, &len));\n            } else {\n                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                        \"A 'name' attribute is required for <%s>\\n\",\n                        String8(*curTag).string());\n                hasErrors = localHasErrors = true;\n            }\n\n            String16 product;\n            identIdx = block.indexOfAttribute(NULL, \"product\");\n            if (identIdx >= 0) {\n                product = String16(block.getAttributeStringValue(identIdx, &len));\n            }\n\n            String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr);\n            \n            if (curIsBag) {\n                // Figure out the parent of this bag...\n                String16 parentIdent;\n                ssize_t parentIdentIdx = block.indexOfAttribute(NULL, \"parent\");\n                if (parentIdentIdx >= 0) {\n                    parentIdent = String16(block.getAttributeStringValue(parentIdentIdx, &len));\n                } else {\n                    ssize_t sep = ident.findLast('.');\n                    if (sep >= 0) {\n                        parentIdent.setTo(ident, sep);\n                    }\n                }\n\n                if (!localHasErrors) {\n                    err = outTable->startBag(SourcePos(in->getPrintableSource(),\n                            block.getLineNumber()), myPackage, curType, ident,\n                            parentIdent, &curParams,\n                            overwrite, curIsBagReplaceOnOverwrite);\n                    if (err != NO_ERROR) {\n                        hasErrors = localHasErrors = true;\n                    }\n                }\n                \n                ssize_t elmIndex = 0;\n                char elmIndexStr[14];\n                while ((code=block.next()) != ResXMLTree::END_DOCUMENT\n                        && code != ResXMLTree::BAD_DOCUMENT) {\n\n                    if (code == ResXMLTree::START_TAG) {\n                        if (strcmp16(block.getElementName(&len), item16.string()) != 0) {\n                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                    \"Tag <%s> can not appear inside <%s>, only <item>\\n\",\n                                    String8(block.getElementName(&len)).string(),\n                                    String8(*curTag).string());\n                            return UNKNOWN_ERROR;\n                        }\n\n                        String16 itemIdent;\n                        if (curType == array16) {\n                            sprintf(elmIndexStr, \"^index_%d\", (int)elmIndex++);\n                            itemIdent = String16(elmIndexStr);\n                        } else if (curType == plurals16) {\n                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, \"quantity\");\n                            if (itemIdentIdx >= 0) {\n                                String16 quantity16(block.getAttributeStringValue(itemIdentIdx, &len));\n                                if (quantity16 == other16) {\n                                    itemIdent = quantityOther16;\n                                }\n                                else if (quantity16 == zero16) {\n                                    itemIdent = quantityZero16;\n                                }\n                                else if (quantity16 == one16) {\n                                    itemIdent = quantityOne16;\n                                }\n                                else if (quantity16 == two16) {\n                                    itemIdent = quantityTwo16;\n                                }\n                                else if (quantity16 == few16) {\n                                    itemIdent = quantityFew16;\n                                }\n                                else if (quantity16 == many16) {\n                                    itemIdent = quantityMany16;\n                                }\n                                else {\n                                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                            \"Illegal 'quantity' attribute is <item> inside <plurals>\\n\");\n                                    hasErrors = localHasErrors = true;\n                                }\n                            } else {\n                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                        \"A 'quantity' attribute is required for <item> inside <plurals>\\n\");\n                                hasErrors = localHasErrors = true;\n                            }\n                        } else {\n                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, \"name\");\n                            if (itemIdentIdx >= 0) {\n                                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));\n                            } else {\n                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                        \"A 'name' attribute is required for <item>\\n\");\n                                hasErrors = localHasErrors = true;\n                            }\n                        }\n\n                        ResXMLParser::ResXMLPosition parserPosition;\n                        block.getPosition(&parserPosition);\n\n                        err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType,\n                                ident, parentIdent, itemIdent, curFormat, curIsFormatted,\n                                product, NO_PSEUDOLOCALIZATION, overwrite, outTable);\n                        if (err == NO_ERROR) {\n                            if (curIsPseudolocalizable && localeIsDefined(curParams)\n                                    && bundle->getPseudolocalize() > 0) {\n                                // pseudolocalize here\n                                if ((PSEUDO_ACCENTED & bundle->getPseudolocalize()) ==\n                                   PSEUDO_ACCENTED) {\n                                    block.setPosition(parserPosition);\n                                    err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage,\n                                            curType, ident, parentIdent, itemIdent, curFormat,\n                                            curIsFormatted, product, PSEUDO_ACCENTED,\n                                            overwrite, outTable);\n                                }\n                                if ((PSEUDO_BIDI & bundle->getPseudolocalize()) ==\n                                   PSEUDO_BIDI) {\n                                    block.setPosition(parserPosition);\n                                    err = parseAndAddBag(bundle, in, &block, pseudoBidiParams, myPackage,\n                                            curType, ident, parentIdent, itemIdent, curFormat,\n                                            curIsFormatted, product, PSEUDO_BIDI,\n                                            overwrite, outTable);\n                                }\n                            }\n                        }\n                        if (err != NO_ERROR) {\n                            hasErrors = localHasErrors = true;\n                        }\n                    } else if (code == ResXMLTree::END_TAG) {\n                        if (strcmp16(block.getElementName(&len), curTag->string()) != 0) {\n                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                                    \"Found tag </%s> where </%s> is expected\\n\",\n                                    String8(block.getElementName(&len)).string(),\n                                    String8(*curTag).string());\n                            return UNKNOWN_ERROR;\n                        }\n                        break;\n                    }\n                }\n            } else {\n                ResXMLParser::ResXMLPosition parserPosition;\n                block.getPosition(&parserPosition);\n\n                err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident,\n                        *curTag, curIsStyled, curFormat, curIsFormatted,\n                        product, NO_PSEUDOLOCALIZATION, overwrite, &skippedResourceNames, outTable);\n\n                if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR?\n                    hasErrors = localHasErrors = true;\n                }\n                else if (err == NO_ERROR) {\n                    if (curIsPseudolocalizable && localeIsDefined(curParams)\n                            && bundle->getPseudolocalize() > 0) {\n                        // pseudolocalize here\n                        if ((PSEUDO_ACCENTED & bundle->getPseudolocalize()) ==\n                           PSEUDO_ACCENTED) {\n                            block.setPosition(parserPosition);\n                            err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType,\n                                    ident, *curTag, curIsStyled, curFormat,\n                                    curIsFormatted, product,\n                                    PSEUDO_ACCENTED, overwrite, &skippedResourceNames, outTable);\n                        }\n                        if ((PSEUDO_BIDI & bundle->getPseudolocalize()) ==\n                           PSEUDO_BIDI) {\n                            block.setPosition(parserPosition);\n                            err = parseAndAddEntry(bundle, in, &block, pseudoBidiParams,\n                                    myPackage, curType, ident, *curTag, curIsStyled, curFormat,\n                                    curIsFormatted, product,\n                                    PSEUDO_BIDI, overwrite, &skippedResourceNames, outTable);\n                        }\n                        if (err != NO_ERROR) {\n                            hasErrors = localHasErrors = true;\n                        }\n                    }\n                }\n            }\n\n#if 0\n            if (comment.size() > 0) {\n                printf(\"Comment for @%s:%s/%s: %s\\n\", String8(myPackage).string(),\n                       String8(curType).string(), String8(ident).string(),\n                       String8(comment).string());\n            }\n#endif\n            if (!localHasErrors) {\n                outTable->appendComment(myPackage, curType, ident, comment, false);\n            }\n        }\n        else if (code == ResXMLTree::END_TAG) {\n            if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {\n                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                        \"Unexpected end tag %s\\n\", String8(block.getElementName(&len)).string());\n                return UNKNOWN_ERROR;\n            }\n        }\n        else if (code == ResXMLTree::START_NAMESPACE || code == ResXMLTree::END_NAMESPACE) {\n        }\n        else if (code == ResXMLTree::TEXT) {\n            if (isWhitespace(block.getText(&len))) {\n                continue;\n            }\n            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(\n                    \"Found text \\\"%s\\\" where item tag is expected\\n\",\n                    String8(block.getText(&len)).string());\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    // For every resource defined, there must be exist one variant with a product attribute\n    // set to 'default' (or no product attribute at all).\n    // We check to see that for every resource that was ignored because of a mismatched\n    // product attribute, some product variant of that resource was processed.\n    for (size_t i = 0; i < skippedResourceNames.size(); i++) {\n        if (skippedResourceNames[i]) {\n            const type_ident_pair_t& p = skippedResourceNames.keyAt(i);\n            if (!outTable->hasBagOrEntry(myPackage, p.type, p.ident)) {\n                const char* bundleProduct =\n                        (bundle->getProduct() == NULL) ? \"\" : bundle->getProduct();\n                fprintf(stderr, \"In resource file %s: %s\\n\",\n                        in->getPrintableSource().string(),\n                        curParams.toString().string());\n\n                fprintf(stderr, \"\\t%s '%s' does not match product %s.\\n\"\n                        \"\\tYou may have forgotten to include a 'default' product variant\"\n                        \" of the resource.\\n\",\n                        String8(p.type).string(), String8(p.ident).string(),\n                        bundleProduct[0] == 0 ? \"default\" : bundleProduct);\n                return UNKNOWN_ERROR;\n            }\n        }\n    }\n\n    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;\n}\n\nResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage, ResourceTable::PackageType type, uint32_t typeIdOffset)\n    : mAssetsPackage(assetsPackage)\n    , mPackageType(type)\n    , mTypeIdOffset(typeIdOffset)\n    , mNumLocal(0)\n    , mBundle(bundle)\n{\n    ssize_t packageId = -1;\n    switch (mPackageType) {\n        case App:\n        case AppFeature:\n            packageId = customePackageId;\n            break;\n\n        case System:\n            packageId = 0x01;\n            break;\n\n        case SharedLibrary:\n            packageId = 0x00;\n            break;\n\n        default:\n            assert(0);\n            break;\n    }\n    sp<Package> package = new Package(mAssetsPackage, packageId);\n    mPackages.add(assetsPackage, package);\n    mOrderedPackages.add(package);\n\n    // Every resource table always has one first entry, the bag attributes.\n    const SourcePos unknown(String8(\"????\"), 0);\n    getType(mAssetsPackage, String16(\"attr\"), unknown);\n}\n\nstatic uint32_t findLargestTypeIdForPackage(const ResTable& table, const String16& packageName) {\n    const size_t basePackageCount = table.getBasePackageCount();\n    for (size_t i = 0; i < basePackageCount; i++) {\n        if ((packageName == table.getBasePackageName(i)) || \n               (table.getBasePackageId(i) == customePackageId)) {\n            return table.getLastTypeIdForPackage(i);\n        }\n    }\n    return 0;\n}\n\nstatus_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets)\n{\n    status_t err = assets->buildIncludedResources(bundle);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    mAssets = assets;\n    if (mTypeIdOffset == 0) {\n        mTypeIdOffset = findLargestTypeIdForPackage(assets->getIncludedResources(), mAssetsPackage);\n    }\n\n    const KeyedVector<uint32_t, ResTable::resource_name> resourceEntries = mAssets->getBaselineResources().getResourceEntries();\n    const size_t N = resourceEntries.size();\n    for (size_t i=0; i<N; i++) {\n        const uint32_t resID = resourceEntries.keyAt(i);\n        const ResTable::resource_name resName = resourceEntries.valueAt(i);\n        String8 type8;\n        String8 name8;\n        if (resName.type8 != NULL) {\n            type8 = String8(resName.type8, resName.typeLen);\n        } else {\n            type8 = String8(resName.type, resName.typeLen);\n        }\n        if (resName.name8 != NULL) {\n            name8 = String8(resName.name8, resName.nameLen);\n        } else {\n            name8 = String8(resName.name, resName.nameLen);\n        }\n        /* printf(\"      spec resource 0x%08x %s:%s/%s: flags=0x%08x\\n\",\n                resID,\n                String8(String16(resName.package,resName.packageLen)).string(),\n                type8.string(), name8.string(),\n                dtohl(typeConfigs->typeSpecFlags[entryIndex]));   */\n        // 忽略null资源（用来做占位符的资源）\n        // null资源的名字是以null为开头的\n        if (strncmp(name8.string(), \"null\", strlen(\"null\")) != 0) {\n            err = addMapping(SourcePos(), assets, String16(resName.package,resName.packageLen), String16(type8), String16(name8), resID);\n        }\n    }\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n\n    if (bundle->getFeatureAfterPackage().size() > 0){\n        const Vector<String8>& featureStrs = bundle->getFeatureAfterPackage();\n        const size_t numFeatures = featureStrs.size();\n        for (size_t i = 0; i < numFeatures; i++){\n            String8 featureAfter = featureStrs[i];\n            AssetManager featureAssetManager;\n            if (!featureAssetManager.addAssetPath(featureAfter, NULL)) {\n                fprintf(stderr, \"ERROR: Feature package '%s' not found.\\n\",\n                        featureAfter.string());\n                return UNKNOWN_ERROR;\n            }\n            const ResTable& featureTable = featureAssetManager.getResources(false);\n            mTypeIdOffset = max(mTypeIdOffset,\n                    findLargestTypeIdForPackage(featureTable, mAssetsPackage));\n        }\n\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::addMapping(const SourcePos& sourcePos,\n                                 const sp<AaptAssets>& assets,\n                                  const String16& package,\n                                  const String16& type,\n                                  const String16& name,\n                                  const uint32_t ident)\n{\n    /* uint32_t rid = mAssets->getIncludedResources()\n        .identifierForName(name.string(), name.size(),\n                           type.string(), type.size(),\n                           package.string(), package.size());\n    if (rid != 0) {\n        sourcePos.error(\"Error declaring public resource %s/%s for included package %s\\n\",\n                String8(type).string(), String8(name).string(),\n                String8(package).string());\n        return UNKNOWN_ERROR;\n    } */\n\n    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8(\"R\"));\n    if (symbols != NULL) {\n        symbols = symbols->addNestedSymbol(String8(type), sourcePos);\n    }\n    sp<Type> t = getType(package, type, sourcePos);\n    if (t == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    return t->addMapping(sourcePos, symbols, name, ident);\n}\n\nstatus_t ResourceTable::addPublic(const SourcePos& sourcePos,\n                                  const String16& package,\n                                  const String16& type,\n                                  const String16& name,\n                                  const uint32_t ident)\n{\n    uint32_t rid = mAssets->getIncludedResources()\n        .identifierForName(name.string(), name.size(),\n                           type.string(), type.size(),\n                           package.string(), package.size());\n    if (rid != 0) {\n        sourcePos.error(\"Error declaring public resource %s/%s for included package %s\\n\",\n                String8(type).string(), String8(name).string(),\n                String8(package).string());\n        return UNKNOWN_ERROR;\n    }\n\n    sp<Type> t = getType(package, type, sourcePos);\n    if (t == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    return t->addPublic(sourcePos, name, ident);\n}\n\nstatus_t ResourceTable::addEntry(const SourcePos& sourcePos,\n                                 const String16& package,\n                                 const String16& type,\n                                 const String16& name,\n                                 const String16& value,\n                                 const Vector<StringPool::entry_style_span>* style,\n                                 const ResTable_config* params,\n                                 const bool doSetIndex,\n                                 const int32_t format,\n                                 const bool overwrite,\n                    int pos)\n{\n    uint32_t rid = mAssets->getIncludedResources()\n        .identifierForName(name.string(), name.size(),\n                           type.string(), type.size(),\n                           package.string(), package.size());\n    if (rid != 0) {\n        sourcePos.error(\"Resource entry %s/%s is already defined in package %s.\",\n                String8(type).string(), String8(name).string(), String8(package).string());\n        return UNKNOWN_ERROR;\n    }\n    \n    sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite,\n                           params, doSetIndex, pos);\n    if (e == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    status_t err = e->setItem(sourcePos, value, style, format, overwrite);\n    if (err == NO_ERROR) {\n        mNumLocal++;\n    }\n    return err;\n}\n\nstatus_t ResourceTable::startBag(const SourcePos& sourcePos,\n                                 const String16& package,\n                                 const String16& type,\n                                 const String16& name,\n                                 const String16& bagParent,\n                                 const ResTable_config* params,\n                                 bool overlay,\n                                 bool replace, bool isId)\n{\n    status_t result = NO_ERROR;\n\n    // Check for adding entries in other packages...  for now we do\n    // nothing.  We need to do the right thing here to support skinning.\n    uint32_t rid = mAssets->getIncludedResources()\n    .identifierForName(name.string(), name.size(),\n                       type.string(), type.size(),\n                       package.string(), package.size());\n    if (rid != 0) {\n        sourcePos.error(\"Resource entry %s/%s is already defined in package %s.\",\n                String8(type).string(), String8(name).string(), String8(package).string());\n        return UNKNOWN_ERROR;\n    }\n\n    if (overlay && !mBundle->getAutoAddOverlay() && !hasBagOrEntry(package, type, name)) {\n        bool canAdd = false;\n        sp<Package> p = mPackages.valueFor(package);\n        if (p != NULL) {\n            sp<Type> t = p->getTypes().valueFor(type);\n            if (t != NULL) {\n                if (t->getCanAddEntries().indexOf(name) >= 0) {\n                    canAdd = true;\n                }\n            }\n        }\n        if (!canAdd) {\n            sourcePos.error(\"Resource does not already exist in overlay at '%s'; use <add-resource> to add.\\n\",\n                            String8(name).string());\n            return UNKNOWN_ERROR;\n        }\n    }\n    sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params);\n    if (e == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    \n    // If a parent is explicitly specified, set it.\n    if (bagParent.size() > 0) {\n        e->setParent(bagParent);\n    }\n\n    if ((result = e->makeItABag(sourcePos)) != NO_ERROR) {\n        return result;\n    }\n\n    if (overlay && replace) { \n        return e->emptyBag(sourcePos);\n    }\n    return result;\n}\n\nstatus_t ResourceTable::addBag(const SourcePos& sourcePos,\n                               const String16& package,\n                               const String16& type,\n                               const String16& name,\n                               const String16& bagParent,\n                               const String16& bagKey,\n                               const String16& value,\n                               const Vector<StringPool::entry_style_span>* style,\n                               const ResTable_config* params,\n                               bool replace, bool isId, const int32_t format)\n{\n    // Check for adding entries in other packages...  for now we do\n    // nothing.  We need to do the right thing here to support skinning.\n    uint32_t rid = mAssets->getIncludedResources()\n        .identifierForName(name.string(), name.size(),\n                           type.string(), type.size(),\n                           package.string(), package.size());\n    if (rid != 0) {\n        return NO_ERROR;\n    }\n\n#if 0\n    if (name == String16(\"left\")) {\n        printf(\"Adding bag left: file=%s, line=%d, type=%s\\n\",\n               sourcePos.file.striing(), sourcePos.line, String8(type).string());\n    }\n#endif\n    sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params);\n    if (e == NULL) {\n        return UNKNOWN_ERROR;\n    }\n\n    // If a parent is explicitly specified, set it.\n    if (bagParent.size() > 0) {\n        e->setParent(bagParent);\n    }\n\n    const bool first = e->getBag().indexOfKey(bagKey) < 0;\n    status_t err = e->addToBag(sourcePos, bagKey, value, style, replace, isId, format);\n    if (err == NO_ERROR && first) {\n        mNumLocal++;\n    }\n    return err;\n}\n\nbool ResourceTable::hasBagOrEntry(const String16& package,\n                                  const String16& type,\n                                  const String16& name) const\n{\n    // First look for this in the included resources...\n    uint32_t rid = mAssets->getIncludedResources()\n        .identifierForName(name.string(), name.size(),\n                           type.string(), type.size(),\n                           package.string(), package.size());\n    if (rid != 0) {\n        return true;\n    }\n\n    sp<Package> p = mPackages.valueFor(package);\n    if (p != NULL) {\n        sp<Type> t = p->getTypes().valueFor(type);\n        if (t != NULL) {\n            sp<ConfigList> c =  t->getConfigs().valueFor(name);\n            if (c != NULL) return true;\n        }\n    }\n\n    return false;\n}\n\nbool ResourceTable::hasBagOrEntry(const String16& package,\n                                  const String16& type,\n                                  const String16& name,\n                                  const ResTable_config& config) const\n{\n    // First look for this in the included resources...\n    uint32_t rid = mAssets->getIncludedResources()\n        .identifierForName(name.string(), name.size(),\n                           type.string(), type.size(),\n                           package.string(), package.size());\n    if (rid != 0) {\n        return true;\n    }\n\n    sp<Package> p = mPackages.valueFor(package);\n    if (p != NULL) {\n        sp<Type> t = p->getTypes().valueFor(type);\n        if (t != NULL) {\n            sp<ConfigList> c =  t->getConfigs().valueFor(name);\n            if (c != NULL) {\n                sp<Entry> e = c->getEntries().valueFor(config);\n                if (e != NULL) {\n                    return true;\n                }\n            }\n        }\n    }\n\n    return false;\n}\n\nbool ResourceTable::hasBagOrEntry(const String16& ref,\n                                  const String16* defType,\n                                  const String16* defPackage)\n{\n    String16 package, type, name;\n    if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name,\n                defType, defPackage ? defPackage:&mAssetsPackage, NULL)) {\n        return false;\n    }\n    return hasBagOrEntry(package, type, name);\n}\n\nbool ResourceTable::appendComment(const String16& package,\n                                  const String16& type,\n                                  const String16& name,\n                                  const String16& comment,\n                                  bool onlyIfEmpty)\n{\n    if (comment.size() <= 0) {\n        return true;\n    }\n\n    sp<Package> p = mPackages.valueFor(package);\n    if (p != NULL) {\n        sp<Type> t = p->getTypes().valueFor(type);\n        if (t != NULL) {\n            sp<ConfigList> c =  t->getConfigs().valueFor(name);\n            if (c != NULL) {\n                c->appendComment(comment, onlyIfEmpty);\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nbool ResourceTable::appendTypeComment(const String16& package,\n                                      const String16& type,\n                                      const String16& name,\n                                      const String16& comment)\n{\n    if (comment.size() <= 0) {\n        return true;\n    }\n    \n    sp<Package> p = mPackages.valueFor(package);\n    if (p != NULL) {\n        sp<Type> t = p->getTypes().valueFor(type);\n        if (t != NULL) {\n            sp<ConfigList> c =  t->getConfigs().valueFor(name);\n            if (c != NULL) {\n                c->appendTypeComment(comment);\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nvoid ResourceTable::canAddEntry(const SourcePos& pos,\n        const String16& package, const String16& type, const String16& name)\n{\n    sp<Type> t = getType(package, type, pos);\n    if (t != NULL) {\n        t->canAddEntry(name);\n    }\n}\n\nsize_t ResourceTable::size() const {\n    return mPackages.size();\n}\n\nsize_t ResourceTable::numLocalResources() const {\n    return mNumLocal;\n}\n\nbool ResourceTable::hasResources() const {\n    return mNumLocal > 0;\n}\n\nsp<AaptFile> ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,\n        const bool isBase)\n{\n    sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());\n    status_t err = flatten(bundle, filter, data, isBase);\n    return err == NO_ERROR ? data : NULL;\n}\n\ninline uint32_t ResourceTable::getResId(const sp<Package>& p,\n                                        const sp<Type>& t,\n                                        uint32_t nameId)\n{\n    return makeResId(p->getAssignedId(), t->getIndex(), nameId);\n}\n\nuint32_t ResourceTable::getResId(const String16& package,\n                                 const String16& type,\n                                 const String16& name,\n                                 bool onlyPublic) const\n{\n    uint32_t id = ResourceIdCache::lookup(package, type, name, onlyPublic);\n    if (id != 0) return id;     // cache hit\n\n    /* printf(\"Lookup resource: p=%s, t=%s, n=%s, res=%d\\n\",\n                String8(package).string(), String8(type).string(),\n                String8(name).string(), id); */\n    // First look for this in the included resources...\n    uint32_t specFlags = 0;\n    uint32_t rid = mAssets->getIncludedResources()\n        .identifierForName(name.string(), name.size(),\n                           type.string(), type.size(),\n                           package.string(), package.size(),\n                           &specFlags);\n    if (rid != 0) {\n        if (onlyPublic) {\n            if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) {\n                return 0;\n            }\n        }\n        \n        return ResourceIdCache::store(package, type, name, onlyPublic, rid);\n    }\n\n    rid = mAssets->getBaselineResources()\n        .identifierForName(name.string(), name.size(),\n                type.string(), type.size(),\n                package.string(), package.size(),\n                &specFlags);\n    if (rid != 0) {\n        /* if (onlyPublic) {\n            if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) {\n                return 0;\n            }\n        } */\n\n        return ResourceIdCache::store(package, type, name, onlyPublic, rid);\n    }\n\n    sp<Package> p = mPackages.valueFor(package);\n    if (p == NULL) return 0;\n    sp<Type> t = p->getTypes().valueFor(type);\n    if (t == NULL) return 0;\n    sp<ConfigList> c =  t->getConfigs().valueFor(name);\n    if (c == NULL) return 0;\n    int32_t ei = c->getEntryIndex();\n    if (ei < 0) return 0;\n\n    return ResourceIdCache::store(package, type, name, onlyPublic,\n            getResId(p, t, ei));\n}\n\nuint32_t ResourceTable::getResId(const String16& ref,\n                                 const String16* defType,\n                                 const String16* defPackage,\n                                 const char** outErrorMsg,\n                                 bool onlyPublic) const\n{\n    String16 package, type, name;\n    bool refOnlyPublic = true;\n    if (!ResTable::expandResourceRef(\n        ref.string(), ref.size(), &package, &type, &name,\n        defType, defPackage ? defPackage:&mAssetsPackage,\n        outErrorMsg, &refOnlyPublic)) {\n        NOISY(printf(\"Expanding resource: ref=%s\\n\",\n                     String8(ref).string()));\n        NOISY(printf(\"Expanding resource: defType=%s\\n\",\n                     defType ? String8(*defType).string() : \"NULL\"));\n        NOISY(printf(\"Expanding resource: defPackage=%s\\n\",\n                     defPackage ? String8(*defPackage).string() : \"NULL\"));\n        NOISY(printf(\"Expanding resource: ref=%s\\n\", String8(ref).string()));\n        NOISY(printf(\"Expanded resource: p=%s, t=%s, n=%s, res=0\\n\",\n                     String8(package).string(), String8(type).string(),\n                     String8(name).string()));\n        return 0;\n    }\n    uint32_t res = getResId(package, type, name, onlyPublic && refOnlyPublic);\n    NOISY(printf(\"Expanded resource: p=%s, t=%s, n=%s, res=%d\\n\",\n                 String8(package).string(), String8(type).string(),\n                 String8(name).string(), res));\n    if (res == 0) {\n        //if (outErrorMsg)\n            //*outErrorMsg = \"No resource found that matches the given name\";\n    }\n    return res;\n}\n\nbool ResourceTable::isValidResourceName(const String16& s)\n{\n    const char16_t* p = s.string();\n    bool first = true;\n    while (*p) {\n        if ((*p >= 'a' && *p <= 'z')\n            || (*p >= 'A' && *p <= 'Z')\n            || *p == '_'\n            || (!first && *p >= '0' && *p <= '9')) {\n            first = false;\n            p++;\n            continue;\n        }\n        return false;\n    }\n    return true;\n}\n\nbool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool,\n                                  const String16& str,\n                                  bool preserveSpaces, bool coerceType,\n                                  uint32_t attrID,\n                                  const Vector<StringPool::entry_style_span>* style,\n                                  String16* outStr, void* accessorCookie,\n                                  uint32_t attrType, const String8* configTypeName,\n                                  const ConfigDescription* config)\n{\n    String16 finalStr;\n\n    bool res = true;\n    if (style == NULL || style->size() == 0) {\n        res = mAssets->getIncludedResources()\n            .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces,\n                            coerceType, attrID, NULL, &mAssetsPackage, this,\n                           accessorCookie, attrType, true, sktPackageName == NULL);\n        if (res == 0 && sktPackageName != NULL){\n            String16 packageName = String16(sktPackageName);\n            // Text is not styled so it can be any type...  let's figure it out.\n            res = mAssets->getIncludedResources()\n                .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces,\n                            coerceType, attrID, NULL, &packageName, this,\n                           accessorCookie, attrType, true);\n        }\n    } else {\n        // Styled text can only be a string, and while collecting the style\n        // information we have already processed that string!\n        outValue->size = sizeof(Res_value);\n        outValue->res0 = 0;\n        outValue->dataType = outValue->TYPE_STRING;\n        outValue->data = 0;\n        finalStr = str;\n    }\n\n    if (!res) {\n        return false;\n    }\n\n    if (outValue->dataType == outValue->TYPE_STRING) {\n        // Should do better merging styles.\n        if (pool) {\n            String8 configStr;\n            if (config != NULL) {\n                configStr = config->toString();\n            } else {\n                configStr = \"(null)\";\n            }\n            NOISY(printf(\"Adding to pool string style #%d config %s: %s\\n\",\n                    style != NULL ? style->size() : 0,\n                    configStr.string(), String8(finalStr).string()));\n            if (style != NULL && style->size() > 0) {\n                outValue->data = pool->add(finalStr, *style, configTypeName, config);\n            } else {\n                outValue->data = pool->add(finalStr, true, configTypeName, config);\n            }\n        } else {\n            // Caller will fill this in later.\n            outValue->data = 0;\n        }\n    \n        if (outStr) {\n            *outStr = finalStr;\n        }\n\n    }\n\n    return true;\n}\n\nuint32_t ResourceTable::getCustomResource(\n    const String16& package, const String16& type, const String16& name) const\n{\n    /* // 首先从Baseline中查找\n    uint32_t rid = mAssets->getBaselineResources()\n        .identifierForName(name.string(), name.size(),\n                           type.string(), type.size(),\n                           package.string(), package.size());\n    if (rid != 0) {\n        printf(\"getCustomResource: %s %s %s not found in baseline resources\\n\", String8(package).string(),\n                String8(type).string(), String8(name).string());\n        return rid;\n    } */\n\n    //printf(\"getCustomResource: %s %s %s\\n\", String8(package).string(),\n    //       String8(type).string(), String8(name).string());\n    sp<Package> p = mPackages.valueFor(package);\n    if (p == NULL) return 0;\n    sp<Type> t = p->getTypes().valueFor(type);\n    if (t == NULL) return 0;\n    sp<ConfigList> c =  t->getConfigs().valueFor(name);\n    if (c == NULL) return 0;\n    int32_t ei = c->getEntryIndex();\n    if (ei < 0)\n        printf(\"getCustomResource: %s %s %s=%d not found\\n\", String8(package).string(),\n                String8(type).string(), String8(name).string(), ei); \n    if (ei < 0) return 0;\n    uint32_t resId = getResId(p, t, ei);\n    // printf(\"getCustomResource: %s %s %s=%d\\n\", String8(package).string(),\n          // String8(type).string(), String8(name).string(), resId);\n    return resId;\n}\n\nuint32_t ResourceTable::getCustomResourceWithCreation(\n        const String16& package, const String16& type, const String16& name,\n        const bool createIfNotFound)\n{\n    uint32_t resId = getCustomResource(package, type, name);\n    if (resId == 0 && !createIfNotFound) {\n        // 然后从Baseline中查找\n        resId = mAssets->getBaselineResources()\n            .identifierForName(name.string(), name.size(),\n                    type.string(), type.size(),\n                    package.string(), package.size());\n        /* if (resId != 0) {\n            printf(\"getCustomResource: %s %s %s not found in baseline resources\\n\", String8(package).string(),\n                    String8(type).string(), String8(name).string());\n            return resId;\n        }  */\n    }\n\n    if (resId != 0 || !createIfNotFound) {\n        return resId;\n    }\n\n    if (mAssetsPackage != package) {\n        mCurrentXmlPos.error(\"creating resource for external package %s: %s/%s.\",\n                String8(package).string(), String8(type).string(), String8(name).string());\n        if (package == String16(\"android\")) {\n            mCurrentXmlPos.printf(\"did you mean to use @+id instead of @+android:id?\");\n        }\n        return 0;\n    }\n\n    String16 value(\"false\");\n    resId = mAssets->getBaselineResources()\n        .identifierForName(name.string(), name.size(),\n                type.string(), type.size(),\n                package.string(), package.size());\n    int pos = -1;\n    if (resId != 0) {\n        pos = Res_GETENTRY(resId);\n        /*printf(\"getCustomResource: %s %s %s=%d found in baseline resources\\n\", String8(package).string(),\n                String8(type).string(), String8(name).string(), pos);*/\n    }\n    status_t status = addEntry(mCurrentXmlPos, package, type, name, value, NULL, NULL, true,  ResTable_map::TYPE_ANY, false, pos);\n    if (status == NO_ERROR) {\n        resId = getResId(package, type, name);\n        return resId;\n    }\n    return 0;\n}\n\nuint32_t ResourceTable::getRemappedPackage(uint32_t origPackage) const\n{\n    return origPackage;\n}\n\nbool ResourceTable::getAttributeType(uint32_t attrID, uint32_t* outType)\n{\n    //printf(\"getAttributeType #%08x\\n\", attrID);\n    Res_value value;\n    if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) {\n        //printf(\"getAttributeType #%08x (%s): #%08x\\n\", attrID,\n        //       String8(getEntry(attrID)->getName()).string(), value.data);\n        *outType = value.data;\n        return true;\n    }\n    return false;\n}\n\nbool ResourceTable::getAttributeMin(uint32_t attrID, uint32_t* outMin)\n{\n    //printf(\"getAttributeMin #%08x\\n\", attrID);\n    Res_value value;\n    if (getItemValue(attrID, ResTable_map::ATTR_MIN, &value)) {\n        *outMin = value.data;\n        return true;\n    }\n    return false;\n}\n\nbool ResourceTable::getAttributeMax(uint32_t attrID, uint32_t* outMax)\n{\n    //printf(\"getAttributeMax #%08x\\n\", attrID);\n    Res_value value;\n    if (getItemValue(attrID, ResTable_map::ATTR_MAX, &value)) {\n        *outMax = value.data;\n        return true;\n    }\n    return false;\n}\n\nuint32_t ResourceTable::getAttributeL10N(uint32_t attrID)\n{\n    //printf(\"getAttributeL10N #%08x\\n\", attrID);\n    Res_value value;\n    if (getItemValue(attrID, ResTable_map::ATTR_L10N, &value)) {\n        return value.data;\n    }\n    return ResTable_map::L10N_NOT_REQUIRED;\n}\n\nbool ResourceTable::getLocalizationSetting()\n{\n    return mBundle->getRequireLocalization();\n}\n\nvoid ResourceTable::reportError(void* accessorCookie, const char* fmt, ...)\n{\n    if (accessorCookie != NULL && fmt != NULL) {\n        AccessorCookie* ac = (AccessorCookie*)accessorCookie;\n        int retval=0;\n        char buf[1024];\n        va_list ap;\n        va_start(ap, fmt);\n        retval = vsnprintf(buf, sizeof(buf), fmt, ap);\n        va_end(ap);\n        ac->sourcePos.error(\"Error: %s (at '%s' with value '%s').\\n\",\n                            buf, ac->attr.string(), ac->value.string());\n    }\n}\n\nbool ResourceTable::getAttributeKeys(\n    uint32_t attrID, Vector<String16>* outKeys)\n{\n    sp<const Entry> e = getEntry(attrID);\n    if (e != NULL) {\n        const size_t N = e->getBag().size();\n        for (size_t i=0; i<N; i++) {\n            const String16& key = e->getBag().keyAt(i);\n            if (key.size() > 0 && key.string()[0] != '^') {\n                outKeys->add(key);\n            }\n        }\n        return true;\n    }\n    return false;\n}\n\nbool ResourceTable::getAttributeEnum(\n    uint32_t attrID, const char16_t* name, size_t nameLen,\n    Res_value* outValue)\n{\n    //printf(\"getAttributeEnum #%08x %s\\n\", attrID, String8(name, nameLen).string());\n    String16 nameStr(name, nameLen);\n    sp<const Entry> e = getEntry(attrID);\n    if (e != NULL) {\n        const size_t N = e->getBag().size();\n        for (size_t i=0; i<N; i++) {\n            //printf(\"Comparing %s to %s\\n\", String8(name, nameLen).string(),\n            //       String8(e->getBag().keyAt(i)).string());\n            if (e->getBag().keyAt(i) == nameStr) {\n                return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue);\n            }\n        }\n    }\n    return false;\n}\n\nbool ResourceTable::getAttributeFlags(\n    uint32_t attrID, const char16_t* name, size_t nameLen,\n    Res_value* outValue)\n{\n    outValue->dataType = Res_value::TYPE_INT_HEX;\n    outValue->data = 0;\n\n    //printf(\"getAttributeFlags #%08x %s\\n\", attrID, String8(name, nameLen).string());\n    String16 nameStr(name, nameLen);\n    sp<const Entry> e = getEntry(attrID);\n    if (e != NULL) {\n        const size_t N = e->getBag().size();\n\n        const char16_t* end = name + nameLen;\n        const char16_t* pos = name;\n        while (pos < end) {\n            const char16_t* start = pos;\n            while (pos < end && *pos != '|') {\n                pos++;\n            }\n\n            String16 nameStr(start, pos-start);\n            size_t i;\n            for (i=0; i<N; i++) {\n                //printf(\"Comparing \\\"%s\\\" to \\\"%s\\\"\\n\", String8(nameStr).string(),\n                //       String8(e->getBag().keyAt(i)).string());\n                if (e->getBag().keyAt(i) == nameStr) {\n                    Res_value val;\n                    bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val);\n                    if (!got) {\n                        return false;\n                    }\n                    //printf(\"Got value: 0x%08x\\n\", val.data);\n                    outValue->data |= val.data;\n                    break;\n                }\n            }\n\n            if (i >= N) {\n                // Didn't find this flag identifier.\n                return false;\n            }\n            pos++;\n        }\n\n        return true;\n    }\n    return false;\n}\n\nstatus_t ResourceTable::assignResourceIds(Bundle *bundle)\n{\n    const size_t N = mOrderedPackages.size();\n    size_t pi;\n    status_t firstError = NO_ERROR;\n\n    // First generate all bag attributes and assign indices.\n    for (pi=0; pi<N; pi++) {\n        sp<Package> p = mOrderedPackages.itemAt(pi);\n        if (p == NULL || p->getTypes().size() == 0) {\n            // Empty, skip!\n            continue;\n        }\n\n        // This has no sense for packages being built as AppFeature (aka with a non-zero offset).\n        status_t err = p->applyPublicTypeOrder();\n        if (err != NO_ERROR && firstError == NO_ERROR) {\n            firstError = err;\n        }\n\n        // Generate attributes...\n        const size_t N = p->getOrderedTypes().size();\n        size_t ti;\n        for (ti=0; ti<N; ti++) {\n            sp<Type> t = p->getOrderedTypes().itemAt(ti);\n            if (t == NULL) {\n                continue;\n            }\n            const size_t N = t->getOrderedConfigs().size();\n            for (size_t ci=0; ci<N; ci++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);\n                if (c == NULL) {\n                    continue;\n                }\n                const size_t N = c->getEntries().size();\n                for (size_t ei=0; ei<N; ei++) {\n                    sp<Entry> e = c->getEntries().valueAt(ei);\n                    if (e == NULL) {\n                        continue;\n                    }\n                    status_t err = e->generateAttributes(this, p->getName());\n                    if (err != NO_ERROR && firstError == NO_ERROR) {\n                        firstError = err;\n                    }\n                }\n            }\n        }\n\n        uint32_t typeIdOffset = 0;\n        if ((mPackageType == AppFeature && p->getName() == mAssetsPackage) || mTypeIdOffset > 0) {\n            typeIdOffset = mTypeIdOffset;\n        }\n\n        const SourcePos unknown(String8(\"????\"), 0);\n        sp<Type> attr = p->getType(String16(\"attr\"), unknown, mTypeIdOffset);\n\n        // Assign indices...\n        const size_t typeCount = p->getOrderedTypes().size();\n        for (size_t ti = 0; ti < typeCount; ti++) {\n            sp<Type> t = p->getOrderedTypes().itemAt(ti);\n            if (t == NULL) {\n                continue;\n            }\n\n            err = t->applyMappingEntryOrder();\n            if (err != NO_ERROR && firstError == NO_ERROR) {\n                firstError = err;\n            } \n\n            err = t->applyPublicEntryOrder();\n            if (err != NO_ERROR && firstError == NO_ERROR) {\n                firstError = err;\n            } \n\n            const size_t N = t->getOrderedConfigs().size();\n            size_t i = ti + 1 + typeIdOffset;\n            if(i > 127) {\n                fprintf(stderr, \"ERROR:  type-id should between 0 and 127\\n\");\n                return UNKNOWN_ERROR;\n            }\n            t->setIndex(i);\n\n            LOG_ALWAYS_FATAL_IF(ti == 0 && attr != t,\n                                \"First type is not attr!\");\n\n            for (size_t ei=0; ei<N; ei++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ei);\n                if (c == NULL) {\n                    continue;\n                }\n                // printf(\"setEntryIndex #%d: \\\"%s\\\"\\n\", ei, String8(c->getName()).string());\n                c->setEntryIndex(ei);\n            }\n        }\n\n        // Assign resource IDs to keys in bags...\n        for (size_t ti = 0; ti < typeCount; ti++) {\n            sp<Type> t = p->getOrderedTypes().itemAt(ti);\n            if (t == NULL) {\n                continue;\n            }\n            const size_t N = t->getOrderedConfigs().size();\n            for (size_t ci=0; ci<N; ci++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);\n                if (c == NULL) {\n                    continue;\n                }\n                //printf(\"Ordered config #%d: %p\\n\", ci, c.get());\n                const size_t N = c->getEntries().size();\n                for (size_t ei=0; ei<N; ei++) {\n                    sp<Entry> e = c->getEntries().valueAt(ei);\n                    if (e == NULL) {\n                        continue;\n                    }\n                    status_t err = e->assignResourceIds(this, p->getName(), bundle);\n                    if (err != NO_ERROR && firstError == NO_ERROR) {\n                        firstError = err;\n                    }\n                }\n            }\n        }\n    }\n    return firstError;\n}\n\nstatus_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) {\n    const size_t N = mOrderedPackages.size();\n    size_t pi;\n\n    for (pi=0; pi<N; pi++) {\n        sp<Package> p = mOrderedPackages.itemAt(pi);\n        if (p->getTypes().size() == 0) {\n            // Empty, skip!\n            continue;\n        }\n\n        const size_t N = p->getOrderedTypes().size();\n        size_t ti;\n\n        for (ti=0; ti<N; ti++) {\n            sp<Type> t = p->getOrderedTypes().itemAt(ti);\n            if (t == NULL) {\n                continue;\n            }\n            const size_t N = t->getOrderedConfigs().size();\n            sp<AaptSymbols> typeSymbols =\n                    outSymbols->addNestedSymbol(String8(t->getName()), t->getPos());\n            if (typeSymbols == NULL) {\n                return UNKNOWN_ERROR;\n            }\n\n            for (size_t ci=0; ci<N; ci++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);\n                if (c == NULL) {\n                    continue;\n                }\n                uint32_t rid = getResId(p, t, ci);\n                if (rid == 0) {\n                    return UNKNOWN_ERROR;\n                }\n                if (Res_GETPACKAGE(rid) + 1 == p->getAssignedId()) {\n                    typeSymbols->addSymbol(String8(c->getName()), rid, c->getPos());\n                    \n                    String16 comment(c->getComment());\n                    typeSymbols->appendComment(String8(c->getName()), comment, c->getPos());\n                    //printf(\"Type symbol [%08x] %s comment: %s\\n\", rid,\n                    //        String8(c->getName()).string(), String8(comment).string());\n                    comment = c->getTypeComment();\n                    typeSymbols->appendTypeComment(String8(c->getName()), comment);\n                }\n            }\n        }\n    }\n    return NO_ERROR;\n}\n\n\nvoid\nResourceTable::addLocalization(const String16& name, const String8& locale, const SourcePos& src)\n{\n    mLocalizations[name][locale] = src;\n}\n\n\n/*!\n * Flag various sorts of localization problems.  '+' indicates checks already implemented;\n * '-' indicates checks that will be implemented in the future.\n *\n * + A localized string for which no default-locale version exists => warning\n * + A string for which no version in an explicitly-requested locale exists => warning\n * + A localized translation of an translateable=\"false\" string => warning\n * - A localized string not provided in every locale used by the table\n */\nstatus_t\nResourceTable::validateLocalizations(void)\n{\n    status_t err = NO_ERROR;\n    const String8 defaultLocale;\n\n    // For all strings...\n    for (map<String16, map<String8, SourcePos> >::iterator nameIter = mLocalizations.begin();\n         nameIter != mLocalizations.end();\n         nameIter++) {\n        const map<String8, SourcePos>& configSrcMap = nameIter->second;\n\n        // Look for strings with no default localization\n        if (configSrcMap.count(defaultLocale) == 0) {\n            SourcePos().warning(\"string '%s' has no default translation.\",\n                    String8(nameIter->first).string());\n            if (mBundle->getVerbose()) {\n                for (map<String8, SourcePos>::const_iterator locales = configSrcMap.begin();\n                    locales != configSrcMap.end();\n                    locales++) {\n                    locales->second.printf(\"locale %s found\", locales->first.string());\n                }\n            }\n            // !!! TODO: throw an error here in some circumstances\n        }\n\n        // Check that all requested localizations are present for this string\n        if (mBundle->getConfigurations().size() > 0 && mBundle->getRequireLocalization()) {\n            const char* allConfigs = mBundle->getConfigurations().string();\n            const char* start = allConfigs;\n            const char* comma;\n            \n            set<String8> missingConfigs;\n            AaptLocaleValue locale;\n            do {\n                String8 config;\n                comma = strchr(start, ',');\n                if (comma != NULL) {\n                    config.setTo(start, comma - start);\n                    start = comma + 1;\n                } else {\n                    config.setTo(start);\n                }\n\n                if (!locale.initFromFilterString(config)) {\n                    continue;\n                }\n\n                // don't bother with the pseudolocale \"en_XA\" or \"ar_XB\"\n                if (config != \"en_XA\" && config != \"ar_XB\") {\n                    if (configSrcMap.find(config) == configSrcMap.end()) {\n                        // okay, no specific localization found.  it's possible that we are\n                        // requiring a specific regional localization [e.g. de_DE] but there is an\n                        // available string in the generic language localization [e.g. de];\n                        // consider that string to have fulfilled the localization requirement.\n                        String8 region(config.string(), 2);\n                        if (configSrcMap.find(region) == configSrcMap.end() &&\n                                configSrcMap.count(defaultLocale) == 0) {\n                            missingConfigs.insert(config);\n                        }\n                    }\n                }\n            } while (comma != NULL);\n\n            if (!missingConfigs.empty()) {\n                String8 configStr;\n                for (set<String8>::iterator iter = missingConfigs.begin();\n                     iter != missingConfigs.end();\n                     iter++) {\n                    configStr.appendFormat(\" %s\", iter->string());\n                }\n                SourcePos().warning(\"string '%s' is missing %u required localizations:%s\",\n                        String8(nameIter->first).string(),\n                        (unsigned int)missingConfigs.size(),\n                        configStr.string());\n            }\n        }\n    }\n\n    return err;\n}\n\nstatus_t ResourceTable::flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,\n        const sp<AaptFile>& dest,\n        const bool isBase)\n{\n    const ConfigDescription nullConfig;\n\n    const size_t N = mOrderedPackages.size();\n    size_t pi;\n\n    const static String16 mipmap16(\"mipmap\");\n\n    bool useUTF8 = !bundle->getUTF16StringsOption();\n\n    // The libraries this table references.\n    Vector<sp<Package> > libraryPackages;\n    const ResTable& table = mAssets->getIncludedResources();\n    const size_t basePackageCount = table.getBasePackageCount();\n    for (size_t i = 0; i < basePackageCount; i++) {\n        size_t packageId = table.getBasePackageId(i);\n        String16 packageName(table.getBasePackageName(i));\n        if (packageId > 0x01 && packageId != customePackageId&&\n                packageName != String16(\"android\")) {\n            libraryPackages.add(sp<Package>(new Package(packageName, packageId)));\n        }\n    }\n\n    // Iterate through all data, collecting all values (strings,\n    // references, etc).\n    StringPool valueStrings(useUTF8);\n    Vector<sp<Entry> > allEntries;\n    for (pi=0; pi<N; pi++) {\n        sp<Package> p = mOrderedPackages.itemAt(pi);\n        if (p->getTypes().size() == 0) {\n            continue;\n        }\n\n        StringPool typeStrings(useUTF8);\n        StringPool keyStrings(useUTF8);\n\n        ssize_t stringsAdded = 0;\n        const size_t N = p->getOrderedTypes().size();\n        for (size_t ti=0; ti<N; ti++) {\n            sp<Type> t = p->getOrderedTypes().itemAt(ti);\n            if (t == NULL) {\n                typeStrings.add(String16(\"<empty>\"), false);\n                stringsAdded++;\n                continue;\n            }\n\n            while (stringsAdded < t->getIndex() - 1) {\n                typeStrings.add(String16(\"<empty>\"), false);\n                stringsAdded++;\n            }\n\n            const String16 typeName(t->getName());\n            typeStrings.add(typeName, false);\n            stringsAdded++;\n\n            // This is a hack to tweak the sorting order of the final strings,\n            // to put stuff that is generally not language-specific first.\n            String8 configTypeName(typeName);\n            if (configTypeName == \"drawable\" || configTypeName == \"layout\"\n                    || configTypeName == \"color\" || configTypeName == \"anim\"\n                    || configTypeName == \"interpolator\" || configTypeName == \"animator\"\n                    || configTypeName == \"xml\" || configTypeName == \"menu\"\n                    || configTypeName == \"mipmap\" || configTypeName == \"raw\") {\n                configTypeName = \"1complex\";\n            } else {\n                configTypeName = \"2value\";\n            }\n\n            // mipmaps don't get filtered, so they will\n            // allways end up in the base. Make sure they\n            // don't end up in a split.\n            if (typeName == mipmap16 && !isBase) {\n                continue;\n            }\n\n            const bool filterable = (typeName != mipmap16);\n\n            // 非补丁包（基础包）添加null资源进行占位，因为在5.0一下，由于不能超出基础包的范围导致不能够新增资源\n            if (mAssets->getBaselineResources().getTableCount() == 0 && customePackageId == 0x7f) {\n                for (size_t ci=0; ci<128 * 2; ci++) { // 默认最多只允许添加128个资源\n                    // 加入null资源进行占位，为了后面添加新的资源\n                    addEntry(SourcePos(), mAssetsPackage, typeName, String16(String8::format(\"null_%x\", ci)), String16(\"null\"), NULL, NULL, true);\n                }\n            }\n\n            const size_t N = t->getOrderedConfigs().size();\n            for (size_t ci=0; ci<N; ci++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);\n                if (c == NULL) {\n                    continue;\n                }\n                const size_t N = c->getEntries().size();\n                for (size_t ei=0; ei<N; ei++) {\n                    ConfigDescription config = c->getEntries().keyAt(ei);\n                    if (filterable && !filter->match(config)) {\n                        continue;\n                    }\n                    sp<Entry> e = c->getEntries().valueAt(ei);\n                    if (e == NULL) {\n                        continue;\n                    }\n                    e->setNameIndex(keyStrings.add(e->getName(), true));\n\n                    // If this entry has no values for other configs,\n                    // and is the default config, then it is special.  Otherwise\n                    // we want to add it with the config info.\n                    ConfigDescription* valueConfig = NULL;\n                    if (N != 1 || config == nullConfig) {\n                        valueConfig = &config;\n                    }\n\n                    status_t err = e->prepareFlatten(&valueStrings, this,\n                            &configTypeName, &config);\n                    if (err != NO_ERROR) {\n                        return err;\n                    }\n                    allEntries.add(e);\n                }\n            }\n        }\n\n        p->setTypeStrings(typeStrings.createStringBlock());\n        p->setKeyStrings(keyStrings.createStringBlock());\n    }\n\n    if (bundle->getOutputAPKFile() != NULL) {\n        // Now we want to sort the value strings for better locality.  This will\n        // cause the positions of the strings to change, so we need to go back\n        // through out resource entries and update them accordingly.  Only need\n        // to do this if actually writing the output file.\n        valueStrings.sortByConfig();\n        for (pi=0; pi<allEntries.size(); pi++) {\n            allEntries[pi]->remapStringValue(&valueStrings);\n        }\n    }\n\n    ssize_t strAmt = 0;\n\n    // Now build the array of package chunks.\n    Vector<sp<AaptFile> > flatPackages;\n    for (pi=0; pi<N; pi++) {\n        sp<Package> p = mOrderedPackages.itemAt(pi);\n        if (p->getTypes().size() == 0) {\n            // Empty, skip!\n            continue;\n        }\n\n        const size_t N = p->getTypeStrings().size();\n\n        const size_t baseSize = sizeof(ResTable_package);\n\n        // Start the package data.\n        sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());\n        ResTable_package* header = (ResTable_package*)data->editData(baseSize);\n        if (header == NULL) {\n            fprintf(stderr, \"ERROR: out of memory creating ResTable_package\\n\");\n            return NO_MEMORY;\n        }\n        memset(header, 0, sizeof(*header));\n        header->header.type = htods(RES_TABLE_PACKAGE_TYPE);\n        header->header.headerSize = htods(sizeof(*header));\n        header->id = htodl(static_cast<uint32_t>(p->getAssignedId()));\n        strcpy16_htod(header->name, sktPackageName? \n                                    String16(sktPackageName):\n                                    p->getName().string());\n\n        // Write the string blocks.\n        const size_t typeStringsStart = data->getSize();\n        sp<AaptFile> strFile = p->getTypeStringsData();\n        ssize_t amt = data->writeData(strFile->getData(), strFile->getSize());\n        #if PRINT_STRING_METRICS\n        fprintf(stderr, \"**** type strings: %d\\n\", amt);\n        #endif\n        strAmt += amt;\n        if (amt < 0) {\n            return amt;\n        }\n        const size_t keyStringsStart = data->getSize();\n        strFile = p->getKeyStringsData();\n        amt = data->writeData(strFile->getData(), strFile->getSize());\n        #if PRINT_STRING_METRICS\n        fprintf(stderr, \"**** key strings: %d\\n\", amt);\n        #endif\n        strAmt += amt;\n        if (amt < 0) {\n            return amt;\n        }\n\n        if (isBase) {\n            status_t err = flattenLibraryTable(data, libraryPackages);\n            if (err != NO_ERROR) {\n                fprintf(stderr, \"ERROR: failed to write library table\\n\");\n                return err;\n            }\n        }\n\n        // Build the type chunks inside of this package.\n        for (size_t ti=0; ti<N; ti++) {\n            // Retrieve them in the same order as the type string block.\n            size_t len;\n            String16 typeName(p->getTypeStrings().stringAt(ti, &len));\n            sp<Type> t = p->getTypes().valueFor(typeName);\n            LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16(\"<empty>\"),\n                                \"Type name %s not found\",\n                                String8(typeName).string());\n            if (t == NULL) {\n                continue;\n            }\n            const bool filterable = (typeName != mipmap16);\n            const bool skipEntireType = (typeName == mipmap16 && !isBase);\n\n            /* // 无效代码\n            size_t validResources = 0;\n            const size_t configCount = t->getOrderedConfigs().size();\n            for (size_t ci = 0; ci < configCount; ci++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);\n                if (c != NULL) {\n                    validResources++;\n                }\n            }  */\n\n            // 读取不同type下的资源.\n            const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0;\n\n            // Until a non-NO_ENTRY value has been written for a resource,\n            // that resource is invalid; validResources[i] represents\n            // the item at t->getOrderedConfigs().itemAt(i).\n            Vector<bool> validResources;\n            validResources.insertAt(false, 0, N);\n            \n            // First write the typeSpec chunk, containing information about\n            // each resource entry in this type.\n            {\n                const size_t typeSpecSize = sizeof(ResTable_typeSpec) + sizeof(uint32_t)*N;\n                const size_t typeSpecStart = data->getSize();\n                ResTable_typeSpec* tsHeader = (ResTable_typeSpec*)\n                    (((uint8_t*)data->editData(typeSpecStart+typeSpecSize)) + typeSpecStart);\n                if (tsHeader == NULL) {\n                    fprintf(stderr, \"ERROR: out of memory creating ResTable_typeSpec\\n\");\n                    return NO_MEMORY;\n                }\n                memset(tsHeader, 0, sizeof(*tsHeader));\n                tsHeader->header.type = htods(RES_TABLE_TYPE_SPEC_TYPE);\n                tsHeader->header.headerSize = htods(sizeof(*tsHeader));\n                tsHeader->header.size = htodl(typeSpecSize);\n                tsHeader->id = ti+1;\n                tsHeader->entryCount = htodl(N);\n                \n                uint32_t* typeSpecFlags = (uint32_t*)\n                    (((uint8_t*)data->editData())\n                        + typeSpecStart + sizeof(ResTable_typeSpec));\n                memset(typeSpecFlags, 0, sizeof(uint32_t)*N);\n\n                for (size_t ei=0; ei<N; ei++) {\n                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);\n                    if (cl == NULL) {\n                        continue;\n                    }\n                    if (cl->getPublic()) {\n                        typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC);\n                    }\n\n                    if (skipEntireType) {\n                        continue;\n                    }\n\n                    const size_t CN = cl->getEntries().size();\n                    for (size_t ci=0; ci<CN; ci++) {\n                        if (filterable && !filter->match(cl->getEntries().keyAt(ci))) {\n                            continue;\n                        }\n                        for (size_t cj=ci+1; cj<CN; cj++) {\n                            if (filterable && !filter->match(cl->getEntries().keyAt(cj))) {\n                                continue;\n                            }\n                            // printf(\"setTypeSpecFlags #%d: \\\"%s\\\"\\n\", ei, String8(cl->getName()).string());\n                            typeSpecFlags[ei] |= htodl(\n                                cl->getEntries().keyAt(ci).diff(cl->getEntries().keyAt(cj)));\n                        }\n                    }\n                }\n            }\n            \n            if (skipEntireType) {\n                continue;\n            }\n\n            // We need to write one type chunk for each configuration for\n            // which we have entries in this type.\n            const size_t NC = t->getUniqueConfigs().size();\n            \n            const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N;\n            \n            for (size_t ci=0; ci<NC; ci++) {\n                ConfigDescription config = t->getUniqueConfigs().itemAt(ci);\n\n                NOISY(printf(\"Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c \"\n                     \"orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d \"\n                     \"sw%ddp w%ddp h%ddp dir:%d\\n\",\n                      ti+1,\n                      config.mcc, config.mnc,\n                      config.language[0] ? config.language[0] : '-',\n                      config.language[1] ? config.language[1] : '-',\n                      config.country[0] ? config.country[0] : '-',\n                      config.country[1] ? config.country[1] : '-',\n                      config.orientation,\n                      config.uiMode,\n                      config.touchscreen,\n                      config.density,\n                      config.keyboard,\n                      config.inputFlags,\n                      config.navigation,\n                      config.screenWidth,\n                      config.screenHeight,\n                      config.smallestScreenWidthDp,\n                      config.screenWidthDp,\n                      config.screenHeightDp,\n                      config.layoutDirection));\n                      \n                if (filterable && !filter->match(config)) {\n                    continue;\n                }\n                \n                const size_t typeStart = data->getSize();\n\n                ResTable_type* tHeader = (ResTable_type*)\n                    (((uint8_t*)data->editData(typeStart+typeSize)) + typeStart);\n                if (tHeader == NULL) {\n                    fprintf(stderr, \"ERROR: out of memory creating ResTable_type\\n\");\n                    return NO_MEMORY;\n                }\n\n                memset(tHeader, 0, sizeof(*tHeader));\n                tHeader->header.type = htods(RES_TABLE_TYPE_TYPE);\n                tHeader->header.headerSize = htods(sizeof(*tHeader));\n                tHeader->id = ti+1;\n                tHeader->entryCount = htodl(N);\n                tHeader->entriesStart = htodl(typeSize);\n                tHeader->config = config;\n                NOISY(printf(\"Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c \"\n                     \"orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d \"\n                     \"sw%ddp w%ddp h%ddp dir:%d\\n\",\n                      ti+1,\n                      tHeader->config.mcc, tHeader->config.mnc,\n                      tHeader->config.language[0] ? tHeader->config.language[0] : '-',\n                      tHeader->config.language[1] ? tHeader->config.language[1] : '-',\n                      tHeader->config.country[0] ? tHeader->config.country[0] : '-',\n                      tHeader->config.country[1] ? tHeader->config.country[1] : '-',\n                      tHeader->config.orientation,\n                      tHeader->config.uiMode,\n                      tHeader->config.touchscreen,\n                      tHeader->config.density,\n                      tHeader->config.keyboard,\n                      tHeader->config.inputFlags,\n                      tHeader->config.navigation,\n                      tHeader->config.screenWidth,\n                      tHeader->config.screenHeight,\n                      tHeader->config.smallestScreenWidthDp,\n                      tHeader->config.screenWidthDp,\n                      tHeader->config.screenHeightDp,\n                      tHeader->config.layoutDirection));\n                tHeader->config.swapHtoD();\n\n                // Build the entries inside of this type.\n                for (size_t ei=0; ei<N; ei++) {\n                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);\n                    // Set the offset for this entry in its type.\n                    uint32_t* index = (uint32_t*)\n                        (((uint8_t*)data->editData())\n                         + typeStart + sizeof(ResTable_type));\n                    if (cl == NULL) {\n                        index[ei] = htodl(ResTable_type::NO_ENTRY);\n                        continue;\n                    }\n                    sp<Entry> e = cl->getEntries().valueFor(config);\n\n                    if (e != NULL) {\n                        // printf(\"setEntryIndex #%d: \\\"%s\\\"\\n\", ei, String8(cl->getName()).string());\n                        index[ei] = htodl(data->getSize()-typeStart-typeSize);\n\n                        // Create the entry.\n                        ssize_t amt = e->flatten(bundle, data, cl->getPublic());\n                        if (amt < 0) {\n                            return amt;\n                        }\n                        validResources.editItemAt(ei) = true;\n                    } else {\n                        // printf(\"setEntryIndex NO_ENTRY #%d: \\\"%s\\\"\\n\", ei, String8(cl->getName()).string());\n                        index[ei] = htodl(ResTable_type::NO_ENTRY);\n                    }\n                }\n\n                // Fill in the rest of the type information.\n                tHeader = (ResTable_type*)\n                    (((uint8_t*)data->editData()) + typeStart);\n                tHeader->header.size = htodl(data->getSize()-typeStart);\n            }\n\n            // If we're building splits, then each invocation of the flattening\n            // step will have 'missing' entries. Don't warn/error for this case.\n            if (bundle->getSplitConfigurations().isEmpty()) {\n                bool missing_entry = false;\n                const char* log_prefix = bundle->getErrorOnMissingConfigEntry() ?\n                        \"error\" : \"warning\";\n                for (size_t i = 0; i < N; ++i) {\n                    if (!validResources[i]) {\n                        sp<ConfigList> c = t->getOrderedConfigs().itemAt(i);\n                        if (c == NULL) {\n                            continue;\n                        }\n                        fprintf(stderr, \"%s: no entries written for %s/%s (0x%08x)\\n\", log_prefix,\n                                String8(typeName).string(), String8(c->getName()).string(),\n                                Res_MAKEID(p->getAssignedId() - 1, ti, i));\n                        missing_entry = true;\n                    }\n                }\n                if (bundle->getErrorOnMissingConfigEntry() && missing_entry) {\n                    fprintf(stderr, \"Error: Missing entries, quit!\\n\");\n                    return NOT_ENOUGH_DATA;\n                }\n            }\n        }\n\n        // Fill in the rest of the package information.\n        header = (ResTable_package*)data->editData();\n        header->header.size = htodl(data->getSize());\n        header->typeStrings = htodl(typeStringsStart);\n        header->lastPublicType = htodl(p->getTypeStrings().size());\n        header->keyStrings = htodl(keyStringsStart);\n        header->lastPublicKey = htodl(p->getKeyStrings().size());\n\n        flatPackages.add(data);\n    }\n\n    // And now write out the final chunks.\n    const size_t dataStart = dest->getSize();\n\n    {\n        // blah\n        ResTable_header header;\n        memset(&header, 0, sizeof(header));\n        header.header.type = htods(RES_TABLE_TYPE);\n        header.header.headerSize = htods(sizeof(header));\n        header.packageCount = htodl(flatPackages.size());\n        status_t err = dest->writeData(&header, sizeof(header));\n        if (err != NO_ERROR) {\n            fprintf(stderr, \"ERROR: out of memory creating ResTable_header\\n\");\n            return err;\n        }\n    }\n    \n    ssize_t strStart = dest->getSize();\n    status_t err = valueStrings.writeStringBlock(dest);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    ssize_t amt = (dest->getSize()-strStart);\n    strAmt += amt;\n    #if PRINT_STRING_METRICS\n    fprintf(stderr, \"**** value strings: %d\\n\", amt);\n    fprintf(stderr, \"**** total strings: %d\\n\", strAmt);\n    #endif\n\n    for (pi=0; pi<flatPackages.size(); pi++) {\n        err = dest->writeData(flatPackages[pi]->getData(),\n                              flatPackages[pi]->getSize());\n        if (err != NO_ERROR) {\n            fprintf(stderr, \"ERROR: out of memory creating package chunk for ResTable_header\\n\");\n            return err;\n        }\n    }\n\n    ResTable_header* header = (ResTable_header*)\n        (((uint8_t*)dest->getData()) + dataStart);\n    header->header.size = htodl(dest->getSize() - dataStart);\n\n    NOISY(aout << \"Resource table:\"\n          << HexDump(dest->getData(), dest->getSize()) << endl);\n\n    #if PRINT_STRING_METRICS\n    fprintf(stderr, \"**** total resource table size: %d / %d%% strings\\n\",\n        dest->getSize(), (strAmt*100)/dest->getSize());\n    #endif\n    \n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs) {\n    // Write out the library table if necessary\n    if (libs.size() > 0) {\n        NOISY(fprintf(stderr, \"Writing library reference table\\n\"));\n\n        const size_t libStart = dest->getSize();\n        const size_t count = libs.size();\n        ResTable_lib_header* libHeader = (ResTable_lib_header*) dest->editDataInRange(\n                libStart, sizeof(ResTable_lib_header));\n\n        memset(libHeader, 0, sizeof(*libHeader));\n        libHeader->header.type = htods(RES_TABLE_LIBRARY_TYPE);\n        libHeader->header.headerSize = htods(sizeof(*libHeader));\n        libHeader->header.size = htodl(sizeof(*libHeader) + (sizeof(ResTable_lib_entry) * count));\n        libHeader->count = htodl(count);\n\n        // Write the library entries\n        for (size_t i = 0; i < count; i++) {\n            const size_t entryStart = dest->getSize();\n            sp<Package> libPackage = libs[i];\n            NOISY(fprintf(stderr, \"  Entry %s -> 0x%02x\\n\",\n                        String8(libPackage->getName()).string(),\n                        (uint8_t)libPackage->getAssignedId()));\n\n            ResTable_lib_entry* entry = (ResTable_lib_entry*) dest->editDataInRange(\n                    entryStart, sizeof(ResTable_lib_entry));\n            memset(entry, 0, sizeof(*entry));\n            entry->packageId = htodl(libPackage->getAssignedId());\n            strcpy16_htod(entry->packageName, libPackage->getName().string());\n        }\n    }\n    return NO_ERROR;\n}\n\nvoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp)\n{\n    fprintf(fp,\n    \"<!-- This file contains <public> resource definitions for all\\n\"\n    \"     resources that were generated from the source data. -->\\n\"\n    \"\\n\"\n    \"<resources>\\n\");\n\n    writePublicDefinitions(package, fp, true);\n    writePublicDefinitions(package, fp, false);\n\n    fprintf(fp,\n    \"\\n\"\n    \"</resources>\\n\");\n}\n\nvoid ResourceTable::writePublicDefinitions(const String16& package, FILE* fp, bool pub)\n{\n    bool didHeader = false;\n\n    sp<Package> pkg = mPackages.valueFor(package);\n    if (pkg != NULL) {\n        const size_t NT = pkg->getOrderedTypes().size();\n        for (size_t i=0; i<NT; i++) {\n            sp<Type> t = pkg->getOrderedTypes().itemAt(i);\n            if (t == NULL) {\n                continue;\n            }\n\n            bool didType = false;\n\n            const size_t NC = t->getOrderedConfigs().size();\n            for (size_t j=0; j<NC; j++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(j);\n                if (c == NULL) {\n                    continue;\n                }\n\n                if (c->getPublic() != pub) {\n                    continue;\n                }\n\n                if (!didType) {\n                    fprintf(fp, \"\\n\");\n                    didType = true;\n                }\n                if (!didHeader) {\n                    if (pub) {\n                        fprintf(fp,\"  <!-- PUBLIC SECTION.  These resources have been declared public.\\n\");\n                        fprintf(fp,\"       Changes to these definitions will break binary compatibility. -->\\n\\n\");\n                    } else {\n                        fprintf(fp,\"  <!-- PRIVATE SECTION.  These resources have not been declared public.\\n\");\n                        fprintf(fp,\"       You can make them public my moving these lines into a file in res/values. -->\\n\\n\");\n                    }\n                    didHeader = true;\n                }\n                if (!pub) {\n                    const size_t NE = c->getEntries().size();\n                    for (size_t k=0; k<NE; k++) {\n                        const SourcePos& pos = c->getEntries().valueAt(k)->getPos();\n                        if (pos.file != \"\") {\n                            fprintf(fp,\"  <!-- Declared at %s:%d -->\\n\",\n                                    pos.file.string(), pos.line);\n                        }\n                    }\n                }\n                fprintf(fp, \"  <public type=\\\"%s\\\" name=\\\"%s\\\" id=\\\"0x%08x\\\" />\\n\",\n                        String8(t->getName()).string(),\n                        String8(c->getName()).string(),\n                        getResId(pkg, t, c->getEntryIndex()));\n            }\n        }\n    }\n}\n\nResourceTable::Item::Item(const SourcePos& _sourcePos,\n                          bool _isId,\n                          const String16& _value,\n                          const Vector<StringPool::entry_style_span>* _style,\n                          int32_t _format)\n    : sourcePos(_sourcePos)\n    , isId(_isId)\n    , value(_value)\n    , format(_format)\n    , bagKeyId(0)\n    , evaluating(false)\n{\n    if (_style) {\n        style = *_style;\n    }\n}\n\nResourceTable::Entry::Entry(const Entry& entry)\n    : RefBase()\n    , mName(entry.mName)\n    , mParent(entry.mParent)\n    , mType(entry.mType)\n    , mItem(entry.mItem)\n    , mItemFormat(entry.mItemFormat)\n    , mBag(entry.mBag)\n    , mNameIndex(entry.mNameIndex)\n    , mParentId(entry.mParentId)\n    , mPos(entry.mPos) {}\n\nResourceTable::Entry& ResourceTable::Entry::operator=(const Entry& entry) {\n    mName = entry.mName;\n    mParent = entry.mParent;\n    mType = entry.mType;\n    mItem = entry.mItem;\n    mItemFormat = entry.mItemFormat;\n    mBag = entry.mBag;\n    mNameIndex = entry.mNameIndex;\n    mParentId = entry.mParentId;\n    mPos = entry.mPos;\n    return *this;\n}\n\nstatus_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos)\n{\n    if (mType == TYPE_BAG) {\n        return NO_ERROR;\n    }\n    if (mType == TYPE_UNKNOWN) {\n        mType = TYPE_BAG;\n        return NO_ERROR;\n    }\n    sourcePos.error(\"Resource entry %s is already defined as a single item.\\n\"\n                    \"%s:%d: Originally defined here.\\n\",\n                    String8(mName).string(),\n                    mItem.sourcePos.file.string(), mItem.sourcePos.line);\n    return UNKNOWN_ERROR;\n}\n\nstatus_t ResourceTable::Entry::setItem(const SourcePos& sourcePos,\n                                       const String16& value,\n                                       const Vector<StringPool::entry_style_span>* style,\n                                       int32_t format,\n                                       const bool overwrite)\n{\n    Item item(sourcePos, false, value, style);\n\n    if (mType == TYPE_BAG) {\n        if (mBag.size() == 0) {\n            sourcePos.error(\"Resource entry %s is already defined as a bag.\",\n                    String8(mName).string());\n        } else {\n            const Item& item(mBag.valueAt(0));\n            sourcePos.error(\"Resource entry %s is already defined as a bag.\\n\"\n                            \"%s:%d: Originally defined here.\\n\",\n                            String8(mName).string(),\n                            item.sourcePos.file.string(), item.sourcePos.line);\n        }\n        return UNKNOWN_ERROR;\n    }\n    if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) {\n        sourcePos.error(\"Resource entry %s is already defined.\\n\"\n                        \"%s:%d: Originally defined here.\\n\",\n                        String8(mName).string(),\n                        mItem.sourcePos.file.string(), mItem.sourcePos.line);\n        return UNKNOWN_ERROR;\n    }\n\n    mType = TYPE_ITEM;\n    mItem = item;\n    mItemFormat = format;\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Entry::addToBag(const SourcePos& sourcePos,\n                                        const String16& key, const String16& value,\n                                        const Vector<StringPool::entry_style_span>* style,\n                                        bool replace, bool isId, int32_t format)\n{\n    status_t err = makeItABag(sourcePos);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    Item item(sourcePos, isId, value, style, format);\n    \n    // XXX NOTE: there is an error if you try to have a bag with two keys,\n    // one an attr and one an id, with the same name.  Not something we\n    // currently ever have to worry about.\n    ssize_t origKey = mBag.indexOfKey(key);\n    if (origKey >= 0) {\n        if (!replace) {\n            const Item& item(mBag.valueAt(origKey));\n            sourcePos.error(\"Resource entry %s already has bag item %s.\\n\"\n                    \"%s:%d: Originally defined here.\\n\",\n                    String8(mName).string(), String8(key).string(),\n                    item.sourcePos.file.string(), item.sourcePos.line);\n            return UNKNOWN_ERROR;\n        }\n        //printf(\"Replacing %s with %s\\n\",\n        //       String8(mBag.valueFor(key).value).string(), String8(value).string());\n        mBag.replaceValueFor(key, item);\n    }\n\n    mBag.add(key, item);\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Entry::removeFromBag(const String16& key) {\n    if (mType != Entry::TYPE_BAG) {\n        return NO_ERROR;\n    }\n\n    if (mBag.removeItem(key) >= 0) {\n        return NO_ERROR;\n    }\n    return UNKNOWN_ERROR;\n}\n\nstatus_t ResourceTable::Entry::emptyBag(const SourcePos& sourcePos)\n{\n    status_t err = makeItABag(sourcePos);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    mBag.clear();\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Entry::generateAttributes(ResourceTable* table,\n                                                  const String16& package)\n{\n    const String16 attr16(\"attr\");\n    const String16 id16(\"id\");\n    const size_t N = mBag.size();\n    for (size_t i=0; i<N; i++) {\n        const String16& key = mBag.keyAt(i);\n        const Item& it = mBag.valueAt(i);\n        if (it.isId) {\n            if (!table->hasBagOrEntry(key, &id16, &package)) {\n                String16 value(\"false\");\n                NOISY(fprintf(stderr, \"Generating %s:id/%s\\n\",\n                        String8(package).string(),\n                        String8(key).string()));\n                status_t err = table->addEntry(SourcePos(String8(\"<generated>\"), 0), package,\n                                               id16, key, value);\n                if (err != NO_ERROR) {\n                    return err;\n                }\n            }\n        } else if (!table->hasBagOrEntry(key, &attr16, &package)) {\n\n#if 1\n//             fprintf(stderr, \"ERROR: Bag attribute '%s' has not been defined.\\n\",\n//                     String8(key).string());\n//             const Item& item(mBag.valueAt(i));\n//             fprintf(stderr, \"Referenced from file %s line %d\\n\",\n//                     item.sourcePos.file.string(), item.sourcePos.line);\n//             return UNKNOWN_ERROR;\n#else\n            char numberStr[16];\n            sprintf(numberStr, \"%d\", ResTable_map::TYPE_ANY);\n            status_t err = table->addBag(SourcePos(\"<generated>\", 0), package,\n                                         attr16, key, String16(\"\"),\n                                         String16(\"^type\"),\n                                         String16(numberStr), NULL, NULL);\n            if (err != NO_ERROR) {\n                return err;\n            }\n#endif\n        }\n    }\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Entry::assignResourceIds(ResourceTable* table,\n                                                 const String16& package,\n                                                 Bundle *bundle)\n{\n    bool hasErrors = false;\n    \n    if (mType == TYPE_BAG) {\n        const char* errorMsg;\n        const String16 style16(\"style\");\n        const String16 attr16(\"attr\");\n        const String16 id16(\"id\");\n        mParentId = 0;\n        if (mParent.size() > 0) {\n            mParentId = table->getResId(mParent, &style16, NULL, &errorMsg);\n            if (mParentId == 0 && sktPackageName != NULL) {\n                String16 defPackage = String16(sktPackageName);\n                mParentId = table->getResId(mParent, &style16, &defPackage, &errorMsg, false);\n            }\n\n            if (mParentId == 0) {\n                mPos.error(\"Error retrieving parent for item: %s '%s'.\\n\",\n                        errorMsg, String8(mParent).string());\n                hasErrors = true;\n            }\n        }\n        const size_t N = mBag.size();\n        for (size_t i=0; i<N; i++) {\n            const String16& key = mBag.keyAt(i);\n            Item& it = mBag.editValueAt(i);\n            it.bagKeyId = table->getResId(key,\n                    it.isId ? &id16 : &attr16, NULL, &errorMsg);\n            //printf(\"Bag key of %s: #%08x\\n\", String8(key).string(), it.bagKeyId);\n            if (it.bagKeyId == 0 && sktPackageName != NULL) {\n                String16 defPackage = String16(sktPackageName);\n                it.bagKeyId = table->getResId(key,\n                    it.isId ? &id16 : &attr16, &defPackage, &errorMsg, false);\n            }\n            if (it.bagKeyId == 0) {\n                it.sourcePos.error(\"Error: %s: %s '%s'.\\n\", errorMsg,\n                        String8(it.isId ? id16 : attr16).string(),\n                        String8(key).string());\n                hasErrors = true;\n            }\n        }\n    }\n    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;\n}\n\nstatus_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table,\n        const String8* configTypeName, const ConfigDescription* config)\n{\n    if (mType == TYPE_ITEM) {\n        Item& it = mItem;\n        AccessorCookie ac(it.sourcePos, String8(mName), String8(it.value));\n        if (!table->stringToValue(&it.parsedValue, strings,\n                                  it.value, false, true, 0,\n                                  &it.style, NULL, &ac, mItemFormat,\n                                  configTypeName, config)) {\n            return UNKNOWN_ERROR;\n        }\n    } else if (mType == TYPE_BAG) {\n        const size_t N = mBag.size();\n        for (size_t i=0; i<N; i++) {\n            const String16& key = mBag.keyAt(i);\n            Item& it = mBag.editValueAt(i);\n            AccessorCookie ac(it.sourcePos, String8(key), String8(it.value));\n            if (!table->stringToValue(&it.parsedValue, strings,\n                                      it.value, false, true, it.bagKeyId,\n                                      &it.style, NULL, &ac, it.format,\n                                      configTypeName, config)) {\n                return UNKNOWN_ERROR;\n            }\n        }\n    } else {\n        mPos.error(\"Error: entry %s is not a single item or a bag.\\n\",\n                   String8(mName).string());\n        return UNKNOWN_ERROR;\n    }\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Entry::remapStringValue(StringPool* strings)\n{\n    if (mType == TYPE_ITEM) {\n        Item& it = mItem;\n        if (it.parsedValue.dataType == Res_value::TYPE_STRING) {\n            it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data);\n        }\n    } else if (mType == TYPE_BAG) {\n        const size_t N = mBag.size();\n        for (size_t i=0; i<N; i++) {\n            Item& it = mBag.editValueAt(i);\n            if (it.parsedValue.dataType == Res_value::TYPE_STRING) {\n                it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data);\n            }\n        }\n    } else {\n        mPos.error(\"Error: entry %s is not a single item or a bag.\\n\",\n                   String8(mName).string());\n        return UNKNOWN_ERROR;\n    }\n    return NO_ERROR;\n}\n\nssize_t ResourceTable::Entry::flatten(Bundle* bundle, const sp<AaptFile>& data, bool isPublic)\n{\n    size_t amt = 0;\n    ResTable_entry header;\n    memset(&header, 0, sizeof(header));\n    header.size = htods(sizeof(header));\n    const type ty = this != NULL ? mType : TYPE_ITEM;\n    if (this != NULL) {\n        if (ty == TYPE_BAG) {\n            header.flags |= htods(header.FLAG_COMPLEX);\n        }\n        if (isPublic) {\n            header.flags |= htods(header.FLAG_PUBLIC);\n        }\n        header.key.index = htodl(mNameIndex);\n    }\n    if (ty != TYPE_BAG) {\n        status_t err = data->writeData(&header, sizeof(header));\n        if (err != NO_ERROR) {\n            fprintf(stderr, \"ERROR: out of memory creating ResTable_entry\\n\");\n            return err;\n        }\n\n        const Item& it = mItem;\n        Res_value par;\n        memset(&par, 0, sizeof(par));\n        par.size = htods(it.parsedValue.size);\n        par.dataType = it.parsedValue.dataType;\n        par.res0 = it.parsedValue.res0;\n        par.data = htodl(it.parsedValue.data);\n        #if 0\n        printf(\"Writing item (%s): type=%d, data=0x%x, res0=0x%x\\n\",\n               String8(mName).string(), it.parsedValue.dataType,\n               it.parsedValue.data, par.res0);\n        #endif\n        err = data->writeData(&par, it.parsedValue.size);\n        if (err != NO_ERROR) {\n            fprintf(stderr, \"ERROR: out of memory creating Res_value\\n\");\n            return err;\n        }\n        amt += it.parsedValue.size;\n    } else {\n        size_t N = mBag.size();\n        size_t i;\n        // Create correct ordering of items.\n        KeyedVector<uint32_t, const Item*> items;\n        for (i=0; i<N; i++) {\n            const Item& it = mBag.valueAt(i);\n            items.add(it.bagKeyId, &it);\n        }\n        N = items.size();\n        \n        ResTable_map_entry mapHeader;\n        memcpy(&mapHeader, &header, sizeof(header));\n        mapHeader.size = htods(sizeof(mapHeader));\n        mapHeader.parent.ident = htodl(mParentId);\n        mapHeader.count = htodl(N);\n        status_t err = data->writeData(&mapHeader, sizeof(mapHeader));\n        if (err != NO_ERROR) {\n            fprintf(stderr, \"ERROR: out of memory creating ResTable_entry\\n\");\n            return err;\n        }\n\n        for (i=0; i<N; i++) {\n            const Item& it = *items.valueAt(i);\n            ResTable_map map;\n            map.name.ident = htodl(it.bagKeyId);\n            map.value.size = htods(it.parsedValue.size);\n            map.value.dataType = it.parsedValue.dataType;\n            map.value.res0 = it.parsedValue.res0;\n            map.value.data = htodl(it.parsedValue.data);\n            err = data->writeData(&map, sizeof(map));\n            if (err != NO_ERROR) {\n                fprintf(stderr, \"ERROR: out of memory creating Res_value\\n\");\n                return err;\n            }\n            amt += sizeof(map);\n        }\n    }\n    return amt;\n}\n\nvoid ResourceTable::ConfigList::appendComment(const String16& comment,\n                                              bool onlyIfEmpty)\n{\n    if (comment.size() <= 0) {\n        return;\n    }\n    if (onlyIfEmpty && mComment.size() > 0) {\n        return;\n    }\n    if (mComment.size() > 0) {\n        mComment.append(String16(\"\\n\"));\n    }\n    mComment.append(comment);\n}\n\nvoid ResourceTable::ConfigList::appendTypeComment(const String16& comment)\n{\n    if (comment.size() <= 0) {\n        return;\n    }\n    if (mTypeComment.size() > 0) {\n        mTypeComment.append(String16(\"\\n\"));\n    }\n    mTypeComment.append(comment);\n}\n\nstatus_t ResourceTable::Type::addMapping(const SourcePos& sourcePos,\n                     const sp<AaptSymbols> typeSymbols,\n                                        const String16& name,\n                                        const uint32_t ident)\n{\n    #if 0\n    int32_t entryIdx = Res_GETENTRY(ident);\n    if (entryIdx < 0) {\n        sourcePos.error(\"Public resource %s/%s has an invalid 0 identifier (0x%08x).\\n\",\n                String8(mName).string(), String8(name).string(), ident);\n        return UNKNOWN_ERROR;\n    }\n    #endif\n\n    typeSymbols->addSymbol(String8(name), ident, sourcePos);\n    int32_t typeIdx = Res_GETTYPE(ident);\n    if (typeIdx >= 0) {\n        typeIdx++;\n        if (mPublicIndex > 0 && mPublicIndex != typeIdx) {\n            sourcePos.error(\"Mapping resource %s/%s has conflicting type codes for its\"\n                    \" public identifiers (0x%x vs 0x%x).\\n\",\n                    String8(mName).string(), String8(name).string(),\n                    mPublicIndex, typeIdx);\n            return UNKNOWN_ERROR;\n        }\n        mPublicIndex = typeIdx;\n    }\n\n    /* if (mFirstPublicSourcePos == NULL) {\n        mFirstPublicSourcePos = new SourcePos(sourcePos);\n    } */\n\n    // printf(\"Add mapping %s/%s 0x%08x\\n\", String8(mName).string(), String8(name).string(), ident);\n    if (mMapping.indexOfKey(name) < 0) {\n        mMapping.add(name, Public(sourcePos, String16(), ident));\n    } else {\n        Public& p = mMapping.editValueFor(name);\n        if (p.ident != ident) {\n            sourcePos.error(\"Mapping resource %s/%s has conflicting mapping identifiers\"\n                    \" (0x%08x vs 0x%08x).\\n\"\n                    \"%s:%d: Originally defined here.\\n\",\n                    String8(mName).string(), String8(name).string(), p.ident, ident,\n                    p.sourcePos.file.string(), p.sourcePos.line);\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Type::addPublic(const SourcePos& sourcePos,\n                                        const String16& name,\n                                        const uint32_t ident)\n{\n    #if 0\n    int32_t entryIdx = Res_GETENTRY(ident);\n    if (entryIdx < 0) {\n        sourcePos.error(\"Public resource %s/%s has an invalid 0 identifier (0x%08x).\\n\",\n                String8(mName).string(), String8(name).string(), ident);\n        return UNKNOWN_ERROR;\n    }\n    #endif\n\n    int32_t typeIdx = Res_GETTYPE(ident);\n    if (typeIdx >= 0) {\n        typeIdx++;\n        if (mPublicIndex > 0 && mPublicIndex != typeIdx) {\n            sourcePos.error(\"Public resource %s/%s has conflicting type codes for its\"\n                    \" public identifiers (0x%x vs 0x%x).\\n\",\n                    String8(mName).string(), String8(name).string(),\n                    mPublicIndex, typeIdx);\n            return UNKNOWN_ERROR;\n        }\n        mPublicIndex = typeIdx;\n    }\n\n    if (mFirstPublicSourcePos == NULL) {\n        mFirstPublicSourcePos = new SourcePos(sourcePos);\n    }\n\n    if (mPublic.indexOfKey(name) < 0) {\n        mPublic.add(name, Public(sourcePos, String16(), ident));\n    } else {\n        Public& p = mPublic.editValueFor(name);\n        if (p.ident != ident) {\n            sourcePos.error(\"Public resource %s/%s has conflicting public identifiers\"\n                    \" (0x%08x vs 0x%08x).\\n\"\n                    \"%s:%d: Originally defined here.\\n\",\n                    String8(mName).string(), String8(name).string(), p.ident, ident,\n                    p.sourcePos.file.string(), p.sourcePos.line);\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    return NO_ERROR;\n}\n\nvoid ResourceTable::Type::canAddEntry(const String16& name)\n{\n    mCanAddEntries.add(name);\n}\n\nsp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,\n                                                       const SourcePos& sourcePos,\n                                                       const ResTable_config* config,\n                                                       bool doSetIndex,\n                                                       bool overlay,\n                                                       bool autoAddOverlay,\n                                                       int pos)\n{\n        // printf(\"#add Configs %d: \\\"%s\\\"\\n\", pos, String8(entry).string());\n    // int pos = -1;\n    sp<ConfigList> c = mConfigs.valueFor(entry);\n    if (c == NULL) {\n        if (overlay && !autoAddOverlay && mCanAddEntries.indexOf(entry) < 0) {\n            sourcePos.error(\"Resource at %s appears in overlay but not\"\n                            \" in the base package; use <add-resource> to add.\\n\",\n                            String8(entry).string());\n            return NULL;\n        }\n        c = new ConfigList(entry, sourcePos);\n        mConfigs.add(entry, c);\n        // printf(\"#add Configs %d: \\\"%s\\\"\\n\", pos, String8(entry).string());\n        if (pos != -1) {\n            mOrderedConfigs.replaceAt(c, pos);\n        } else {\n            pos = (int)mOrderedConfigs.size();\n            mOrderedConfigs.add(c);\n        }\n        // pos = (int)mOrderedConfigs.size();\n        // mOrderedConfigs.add(c);\n        if (doSetIndex) {\n            // printf(\"setEntryIndex #%d: \\\"%s\\\"\\n\", pos, String8(c->getName()).string());\n            c->setEntryIndex(pos);\n        }\n    }\n    \n    ConfigDescription cdesc;\n    if (config) cdesc = *config;\n    \n    sp<Entry> e = c->getEntries().valueFor(cdesc);\n    if (e == NULL) {\n        if (config != NULL) {\n            NOISY(printf(\"New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c \"\n                    \"orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d \"\n                    \"sw%ddp w%ddp h%ddp dir:%d\\n\",\n                      sourcePos.file.string(), sourcePos.line,\n                      config->mcc, config->mnc,\n                      config->language[0] ? config->language[0] : '-',\n                      config->language[1] ? config->language[1] : '-',\n                      config->country[0] ? config->country[0] : '-',\n                      config->country[1] ? config->country[1] : '-',\n                      config->orientation,\n                      config->touchscreen,\n                      config->density,\n                      config->keyboard,\n                      config->inputFlags,\n                      config->navigation,\n                      config->screenWidth,\n                      config->screenHeight,\n                      config->smallestScreenWidthDp,\n                      config->screenWidthDp,\n                      config->screenHeightDp,\n                      config->layoutDirection));\n            /* printf(\"New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c \"\n                    \"orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d \"\n                    \"sw%ddp w%ddp h%ddp dir:%d\\n\",\n                      sourcePos.file.string(), sourcePos.line,\n                      config->mcc, config->mnc,\n                      config->language[0] ? config->language[0] : '-',\n                      config->language[1] ? config->language[1] : '-',\n                      config->country[0] ? config->country[0] : '-',\n                      config->country[1] ? config->country[1] : '-',\n                      config->orientation,\n                      config->touchscreen,\n                      config->density,\n                      config->keyboard,\n                      config->inputFlags,\n                      config->navigation,\n                      config->screenWidth,\n                      config->screenHeight,\n                      config->smallestScreenWidthDp,\n                      config->screenWidthDp,\n                      config->screenHeightDp[>,<]\n                      [>config->layoutDirection<]); */\n        } else {\n            NOISY(printf(\"New entry at %s:%d: NULL config\\n\",\n                      sourcePos.file.string(), sourcePos.line));\n        }\n        e = new Entry(entry, sourcePos);\n        c->addEntry(cdesc, e);\n        /*\n        if (doSetIndex) {\n            if (pos < 0) {\n                for (pos=0; pos<(int)mOrderedConfigs.size(); pos++) {\n                    if (mOrderedConfigs[pos] == c) {\n                        break;\n                    }\n                }\n                if (pos >= (int)mOrderedConfigs.size()) {\n                    sourcePos.error(\"Internal error: config not found in mOrderedConfigs when adding entry\");\n                    return NULL;\n                }\n            }\n            e->setEntryIndex(pos);\n        }\n        */\n    }\n    \n    mUniqueConfigs.add(cdesc);\n    \n    return e;\n}\n\nstatus_t ResourceTable::Type::applyMappingEntryOrder()\n{\n    size_t N = mOrderedConfigs.size();\n    Vector<sp<ConfigList> > origOrder(mOrderedConfigs);\n    bool hasError = false;\n\n    size_t i;\n    for (i=0; i<N; i++) {\n        mOrderedConfigs.replaceAt(NULL, i);\n    }\n\n    const size_t NM = mMapping.size();\n    //printf(\"Ordering %d configs from %d public defs\\n\", N, NP);\n    SortedVector<int32_t> mappingIdxs;\n    size_t j;\n    for (j=0; j<NM; j++) {\n        const String16& name = mMapping.keyAt(j);\n        const Public& p = mMapping.valueAt(j);\n        int32_t idx = Res_GETENTRY(p.ident);\n        if (idx >= (int32_t)mOrderedConfigs.size()) {\n            for (size_t k = (int32_t)mOrderedConfigs.size(); k <= idx; k++) {\n                mOrderedConfigs.add();\n            }\n        }\n        //printf(\"Looking for entry \\\"%s\\\"/\\\"%s\\\" (0x%08x) in %d...\\n\",\n        //       String8(mName).string(), String8(name).string(), p.ident, N);\n        bool found = false;\n        for (i=0; i<N; i++) {\n            sp<ConfigList> e = origOrder.itemAt(i);\n            //printf(\"#%d: \\\"%s\\\"\\n\", i, String8(e->getName()).string());\n            if (e->getName() == name) {\n                if (idx >= (int32_t)mOrderedConfigs.size()) {\n                    p.sourcePos.error(\"Mapping entry identifier 0x%x entry index \"\n                            \"is larger than available symbols (index %d, total symbols %d).\\n\",\n                            p.ident, idx, mOrderedConfigs.size());\n                    hasError = true;\n                } else if (mOrderedConfigs.itemAt(idx) == NULL) {\n                    // e->setPublic(true);\n                    // e->setPublicSourcePos(p.sourcePos);\n                    mOrderedConfigs.replaceAt(e, idx);\n                    origOrder.removeAt(i);\n                    N--;\n                    found = true;\n                    break;\n                } else {\n                    sp<ConfigList> oe = mOrderedConfigs.itemAt(idx);\n\n                    p.sourcePos.error(\"Multiple entry names declared for public entry\"\n                            \" identifier 0x%x in type %s (%s vs %s).\\n\"\n                            \"%s:%d: Originally defined here.\",\n                            idx+1, String8(mName).string(),\n                            String8(oe->getName()).string(),\n                            String8(name).string(),\n                            oe->getPublicSourcePos().file.string(),\n                            oe->getPublicSourcePos().line);\n                    hasError = true;\n                }\n            }\n        }\n\n        if (!found) {\n            mappingIdxs.add(idx);\n            /* p.sourcePos.warning(\"Public symbol %s/%s %d  declared here is not defined.\",\n                    String8(mName).string(), String8(name).string(), idx); */\n            /* p.sourcePos.error(\"Public symbol %s/%s declared here is not defined.\",\n                    String8(mName).string(), String8(name).string());\n            hasError = true; */\n        } \n    }\n\n    //printf(\"Copying back in %d non-public configs, have %d\\n\", N, origOrder.size());\n    \n    if (N != origOrder.size()) {\n        printf(\"Internal error: remaining private symbol count mismatch\\n\");\n        N = origOrder.size();\n    }\n    \n    j = 0;\n    for (i=0; i<N; i++) {\n        sp<ConfigList> e = origOrder.itemAt(i);\n        // printf(\"#%d: \\\"%s\\\"\\n\", i, String8(e->getName()).string());\n        // There will always be enough room for the remaining entries.\n        while (mOrderedConfigs.itemAt(j) != NULL || mappingIdxs.indexOf(j) >= 0) {\n            j++;\n            // 到达末尾\n            if (j >= (int32_t)mOrderedConfigs.size()) {\n                // 扩容剩余的个数\n                for (size_t k = 0; k < N - i; k++) {\n                    mOrderedConfigs.add();\n                }\n            }\n        }\n        mOrderedConfigs.replaceAt(e, j);\n        // printf(\"#replace Configs At %d: \\\"%s\\\"\\n\", j, String8(e->getName()).string());\n        j++;\n        // 到达末尾\n        if (j >= (int32_t)mOrderedConfigs.size()) {\n            for (size_t k = 0; k < N - i - 1; k++) {\n                mOrderedConfigs.add();\n            }\n        }\n    }\n\n    return hasError ? UNKNOWN_ERROR : NO_ERROR;\n}\n\nstatus_t ResourceTable::Type::applyPublicEntryOrder()\n{\n    size_t N = mOrderedConfigs.size();\n    Vector<sp<ConfigList> > origOrder(mOrderedConfigs);\n    bool hasError = false;\n\n    size_t i;\n    for (i=0; i<N; i++) {\n        mOrderedConfigs.replaceAt(NULL, i);\n    }\n\n    const size_t NP = mPublic.size();\n    //printf(\"Ordering %d configs from %d public defs\\n\", N, NP);\n    size_t j;\n    for (j=0; j<NP; j++) {\n        const String16& name = mPublic.keyAt(j);\n        const Public& p = mPublic.valueAt(j);\n        int32_t idx = Res_GETENTRY(p.ident);\n        //printf(\"Looking for entry \\\"%s\\\"/\\\"%s\\\" (0x%08x) in %d...\\n\",\n        //       String8(mName).string(), String8(name).string(), p.ident, N);\n        bool found = false;\n        for (i=0; i<N; i++) {\n            sp<ConfigList> e = origOrder.itemAt(i);\n            //printf(\"#%d: \\\"%s\\\"\\n\", i, String8(e->getName()).string());\n            if (e->getName() == name) {\n                if (idx >= (int32_t)mOrderedConfigs.size()) {\n                    p.sourcePos.error(\"Public entry identifier 0x%x entry index \"\n                            \"is larger than available symbols (index %d, total symbols %d).\\n\",\n                            p.ident, idx, mOrderedConfigs.size());\n                    hasError = true;\n                } else if (mOrderedConfigs.itemAt(idx) == NULL) {\n                    e->setPublic(true);\n                    e->setPublicSourcePos(p.sourcePos);\n                    mOrderedConfigs.replaceAt(e, idx);\n                    origOrder.removeAt(i);\n                    N--;\n                    found = true;\n                    break;\n                } else {\n                    sp<ConfigList> oe = mOrderedConfigs.itemAt(idx);\n\n                    p.sourcePos.error(\"Multiple entry names declared for public entry\"\n                            \" identifier 0x%x in type %s (%s vs %s).\\n\"\n                            \"%s:%d: Originally defined here.\",\n                            idx+1, String8(mName).string(),\n                            String8(oe->getName()).string(),\n                            String8(name).string(),\n                            oe->getPublicSourcePos().file.string(),\n                            oe->getPublicSourcePos().line);\n                    hasError = true;\n                }\n            }\n        }\n\n        if (!found) {\n            p.sourcePos.error(\"Public symbol %s/%s declared here is not defined.\",\n                    String8(mName).string(), String8(name).string());\n            hasError = true;\n        }\n    }\n\n    //printf(\"Copying back in %d non-public configs, have %d\\n\", N, origOrder.size());\n    \n    if (N != origOrder.size()) {\n        printf(\"Internal error: remaining private symbol count mismatch\\n\");\n        N = origOrder.size();\n    }\n    \n    j = 0;\n    for (i=0; i<N; i++) {\n        sp<ConfigList> e = origOrder.itemAt(i);\n        // There will always be enough room for the remaining entries.\n        while (mOrderedConfigs.itemAt(j) != NULL) {\n            j++;\n        }\n        mOrderedConfigs.replaceAt(e, j);\n        j++;\n    }\n\n    return hasError ? UNKNOWN_ERROR : NO_ERROR;\n}\n\nResourceTable::Package::Package(const String16& name, size_t packageId)\n    : mName(name), mPackageId(packageId),\n      mTypeStringsMapping(0xffffffff),\n      mKeyStringsMapping(0xffffffff)\n{\n}\n\nsp<ResourceTable::Type> ResourceTable::Package::getType(const String16& type,\n                                                        const SourcePos& sourcePos,\n//                                                        const int32_t indexOffset,\n                                                        bool doSetIndex)\n{\n    sp<Type> t = mTypes.valueFor(type);\n    if (t == NULL) {\n        t = new Type(type, sourcePos);\n        mTypes.add(type, t);\n        mOrderedTypes.add(t);\n        if (doSetIndex) {\n            // For some reason the type's index is set to one plus the index\n            // in the mOrderedTypes list, rather than just the index.\n            t->setIndex(mOrderedTypes.size() /*+ indexOffset*/);\n        }\n    }\n    return t;\n}\n\nstatus_t ResourceTable::Package::setTypeStrings(const sp<AaptFile>& data)\n{\n    status_t err = setStrings(data, &mTypeStrings, &mTypeStringsMapping);\n    if (err != NO_ERROR) {\n        fprintf(stderr, \"ERROR: Type string data is corrupt!\\n\");\n        return err;\n    }\n\n    // Retain a reference to the new data after we've successfully replaced\n    // all uses of the old reference (in setStrings() ).\n    mTypeStringsData = data;\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Package::setKeyStrings(const sp<AaptFile>& data)\n{\n    status_t err = setStrings(data, &mKeyStrings, &mKeyStringsMapping);\n    if (err != NO_ERROR) {\n        fprintf(stderr, \"ERROR: Key string data is corrupt!\\n\");\n        return err;\n    }\n\n    // Retain a reference to the new data after we've successfully replaced\n    // all uses of the old reference (in setStrings() ).\n    mKeyStringsData = data;\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::Package::setStrings(const sp<AaptFile>& data,\n                                            ResStringPool* strings,\n                                            DefaultKeyedVector<String16, uint32_t>* mappings)\n{\n    if (data->getData() == NULL) {\n        return UNKNOWN_ERROR;\n    }\n\n    NOISY(aout << \"Setting restable string pool: \"\n          << HexDump(data->getData(), data->getSize()) << endl);\n\n    status_t err = strings->setTo(data->getData(), data->getSize());\n    if (err == NO_ERROR) {\n        const size_t N = strings->size();\n        for (size_t i=0; i<N; i++) {\n            size_t len;\n            mappings->add(String16(strings->stringAt(i, &len)), i);\n        }\n    }\n    return err;\n}\n\nstatus_t ResourceTable::Package::applyPublicTypeOrder()\n{\n    size_t N = mOrderedTypes.size();\n    Vector<sp<Type> > origOrder(mOrderedTypes);\n\n    size_t i;\n    for (i=0; i<N; i++) {\n        mOrderedTypes.replaceAt(NULL, i);\n    }\n\n    for (i=0; i<N; i++) {\n        sp<Type> t = origOrder.itemAt(i);\n        int32_t idx = t->getPublicIndex();\n        if (idx > 0) {\n            idx--;\n            while (idx >= (int32_t)mOrderedTypes.size()) {\n                mOrderedTypes.add();\n            }\n            if (mOrderedTypes.itemAt(idx) != NULL) {\n                sp<Type> ot = mOrderedTypes.itemAt(idx);\n                t->getFirstPublicSourcePos().error(\"Multiple type names declared for public type\"\n                        \" identifier 0x%x (%s vs %s).\\n\"\n                        \"%s:%d: Originally defined here.\",\n                        idx, String8(ot->getName()).string(),\n                        String8(t->getName()).string(),\n                        ot->getFirstPublicSourcePos().file.string(),\n                        ot->getFirstPublicSourcePos().line);\n                return UNKNOWN_ERROR;\n            }\n            mOrderedTypes.replaceAt(t, idx);\n            origOrder.removeAt(i);\n            i--;\n            N--;\n        }\n    }\n\n    size_t j=0;\n    for (i=0; i<N; i++) {\n        sp<Type> t = origOrder.itemAt(i);\n        // There will always be enough room for the remaining types.\n        while (mOrderedTypes.itemAt(j) != NULL) {\n            j++;\n        }\n        mOrderedTypes.replaceAt(t, j);\n    }\n\n    return NO_ERROR;\n}\n\nsp<ResourceTable::Package> ResourceTable::getPackage(const String16& package)\n{\n    if (package != mAssetsPackage) {\n        return NULL;\n    }\n    return mPackages.valueFor(package);\n}\n\nsp<ResourceTable::Type> ResourceTable::getType(const String16& package,\n                                               const String16& type,\n                                               const SourcePos& sourcePos,\n                                               bool doSetIndex)\n{\n    sp<Package> p = getPackage(package);\n    if (p == NULL) {\n        return NULL;\n    }\n//    int32_t indexOffset = mTypeIdOffset;\n    return p->getType(type, sourcePos, /*indexOffset, */doSetIndex);\n}\n\nsp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package,\n                                                 const String16& type,\n                                                 const String16& name,\n                                                 const SourcePos& sourcePos,\n                                                 bool overlay,\n                                                 const ResTable_config* config,\n                                                 bool doSetIndex,\n                    int pos)\n{\n    sp<Type> t = getType(package, type, sourcePos, doSetIndex);\n    if (t == NULL) {\n        return NULL;\n    }\n    return t->getEntry(name, sourcePos, config, doSetIndex, overlay, mBundle->getAutoAddOverlay(), pos);\n}\n\nsp<ResourceTable::ConfigList> ResourceTable::getConfigList(const String16& package,\n        const String16& type, const String16& name) const\n{\n    const size_t packageCount = mOrderedPackages.size();\n    for (size_t pi = 0; pi < packageCount; pi++) {\n        const sp<Package>& p = mOrderedPackages[pi];\n        if (p == NULL || p->getName() != package) {\n            continue;\n        }\n\n        const Vector<sp<Type> >& types = p->getOrderedTypes();\n        const size_t typeCount = types.size();\n        for (size_t ti = 0; ti < typeCount; ti++) {\n            const sp<Type>& t = types[ti];\n            if (t == NULL || t->getName() != type) {\n                continue;\n            }\n\n            const Vector<sp<ConfigList> >& configs = t->getOrderedConfigs();\n            const size_t configCount = configs.size();\n            for (size_t ci = 0; ci < configCount; ci++) {\n                const sp<ConfigList>& cl = configs[ci];\n                if (cl == NULL || cl->getName() != name) {\n                    continue;\n                }\n\n                return cl;\n            }\n        }\n    }\n    return NULL;\n}\n\nsp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID,\n                                                       const ResTable_config* config) const\n{\n    size_t pid = Res_GETPACKAGE(resID)+1;\n    const size_t N = mOrderedPackages.size();\n    sp<Package> p;\n    for (size_t i = 0; i < N; i++) {\n        sp<Package> check = mOrderedPackages[i];\n        if (check->getAssignedId() == pid) {\n            p = check;\n            break;\n        }\n\n    }\n    if (p == NULL) {\n        fprintf(stderr, \"warning: Package not found for resource #%08x\\n\", resID);\n        return NULL;\n    }\n\n    int tid = Res_GETTYPE(resID) + 1;\n//    if (tid < 0 || tid >= (int)p->getOrderedTypes().size()) {\n//        fprintf(stderr, \"warning: Type not found for resource #%08x\\n\", resID);\n//        return NULL;\n//    }\n    sp<Type> t = NULL;\n    const size_t typeCount = p->getOrderedTypes().size();\n    for (size_t ti = 0; ti < typeCount; ti++) {\n        sp<Type> t2 = p->getOrderedTypes().itemAt(ti);\n        if (t2 == NULL) {\n            continue;\n        }\n\n        if (t2->getIndex() == tid) {\n            t = t2;\n        }\n    }\n\n    if (t == NULL) {\n        fprintf(stderr, \"warning: Type not found for resource #%08x\\n\", resID);\n        return NULL;\n    }\n\n    int eid = Res_GETENTRY(resID);\n    if (eid < 0 || eid >= (int)t->getOrderedConfigs().size()) {\n        fprintf(stderr, \"warning: Entry not found for resource #%08x\\n\", resID);\n        return NULL;\n    }\n\n    sp<ConfigList> c = t->getOrderedConfigs()[eid];\n    if (c == NULL) {\n        fprintf(stderr, \"warning: Entry not found for resource #%08x\\n\", resID);\n        return NULL;\n    }\n    \n    ConfigDescription cdesc;\n    if (config) cdesc = *config;\n    sp<Entry> e = c->getEntries().valueFor(cdesc);\n    if (c == NULL) {\n        fprintf(stderr, \"warning: Entry configuration not found for resource #%08x\\n\", resID);\n        return NULL;\n    }\n    \n    return e;\n}\n\nconst ResourceTable::Item* ResourceTable::getItem(uint32_t resID, uint32_t attrID) const\n{\n    sp<const Entry> e = getEntry(resID);\n    if (e == NULL) {\n        return NULL;\n    }\n\n    const size_t N = e->getBag().size();\n    for (size_t i=0; i<N; i++) {\n        const Item& it = e->getBag().valueAt(i);\n        if (it.bagKeyId == 0) {\n            fprintf(stderr, \"warning: ID not yet assigned to '%s' in bag '%s'\\n\",\n                    String8(e->getName()).string(),\n                    String8(e->getBag().keyAt(i)).string());\n        }\n        if (it.bagKeyId == attrID) {\n            return &it;\n        }\n    }\n\n    return NULL;\n}\n\nbool ResourceTable::getItemValue(\n    uint32_t resID, uint32_t attrID, Res_value* outValue)\n{\n    const Item* item = getItem(resID, attrID);\n\n    bool res = false;\n    if (item != NULL) {\n        if (item->evaluating) {\n            sp<const Entry> e = getEntry(resID);\n            const size_t N = e->getBag().size();\n            size_t i;\n            for (i=0; i<N; i++) {\n                if (&e->getBag().valueAt(i) == item) {\n                    break;\n                }\n            }\n            fprintf(stderr, \"warning: Circular reference detected in key '%s' of bag '%s'\\n\",\n                    String8(e->getName()).string(),\n                    String8(e->getBag().keyAt(i)).string());\n            return false;\n        }\n        item->evaluating = true;\n        res = stringToValue(outValue, NULL, item->value, false, false, item->bagKeyId);\n        NOISY(\n            if (res) {\n                printf(\"getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\\n\",\n                       resID, attrID, String8(getEntry(resID)->getName()).string(),\n                       outValue->dataType, outValue->data);\n            } else {\n                printf(\"getItemValue of #%08x[#%08x]: failed\\n\",\n                       resID, attrID);\n            }\n        );\n        item->evaluating = false;\n    }\n    return res;\n}\n\n/**\n * Returns true if the given attribute ID comes from\n * a platform version from or after L.\n */\nbool ResourceTable::isAttributeFromL(uint32_t attrId) {\n    const uint32_t baseAttrId = 0x010103f7;\n    if ((attrId & 0xffff0000) != (baseAttrId & 0xffff0000)) {\n        return false;\n    }\n\n    uint32_t specFlags;\n    if (!mAssets->getIncludedResources().getResourceFlags(attrId, &specFlags)) {\n        return false;\n    }\n\n    return (specFlags & ResTable_typeSpec::SPEC_PUBLIC) != 0 &&\n        (attrId & 0x0000ffff) >= (baseAttrId & 0x0000ffff);\n}\n\nstatic bool isMinSdkVersionLOrAbove(const Bundle* bundle) {\n    if (bundle->getMinSdkVersion() != NULL && strlen(bundle->getMinSdkVersion()) > 0) {\n        const char firstChar = bundle->getMinSdkVersion()[0];\n        if (firstChar >= 'L' && firstChar <= 'Z') {\n            // L is the code-name for the v21 release.\n            return true;\n        }\n\n        const int minSdk = atoi(bundle->getMinSdkVersion());\n        if (minSdk >= SDK_L) {\n            return true;\n        }\n    }\n    return false;\n}\n\n/**\n * Modifies the entries in the resource table to account for compatibility\n * issues with older versions of Android.\n *\n * This primarily handles the issue of private/public attribute clashes\n * in framework resources.\n *\n * AAPT has traditionally assigned resource IDs to public attributes,\n * and then followed those public definitions with private attributes.\n *\n * --- PUBLIC ---\n * | 0x01010234 | attr/color\n * | 0x01010235 | attr/background\n *\n * --- PRIVATE ---\n * | 0x01010236 | attr/secret\n * | 0x01010237 | attr/shhh\n *\n * Each release, when attributes are added, they take the place of the private\n * attributes and the private attributes are shifted down again.\n *\n * --- PUBLIC ---\n * | 0x01010234 | attr/color\n * | 0x01010235 | attr/background\n * | 0x01010236 | attr/shinyNewAttr\n * | 0x01010237 | attr/highlyValuedFeature\n *\n * --- PRIVATE ---\n * | 0x01010238 | attr/secret\n * | 0x01010239 | attr/shhh\n *\n * Platform code may look for private attributes set in a theme. If an app\n * compiled against a newer version of the platform uses a new public\n * attribute that happens to have the same ID as the private attribute\n * the older platform is expecting, then the behavior is undefined.\n *\n * We get around this by detecting any newly defined attributes (in L),\n * copy the resource into a -v21 qualified resource, and delete the\n * attribute from the original resource. This ensures that older platforms\n * don't see the new attribute, but when running on L+ platforms, the\n * attribute will be respected.\n */\nstatus_t ResourceTable::modifyForCompat(const Bundle* bundle) {\n    if (isMinSdkVersionLOrAbove(bundle)) {\n        // If this app will only ever run on L+ devices,\n        // we don't need to do any compatibility work.\n        return NO_ERROR;\n    }\n\n    const String16 attr16(\"attr\");\n\n    const size_t packageCount = mOrderedPackages.size();\n    for (size_t pi = 0; pi < packageCount; pi++) {\n        sp<Package> p = mOrderedPackages.itemAt(pi);\n        if (p == NULL || p->getTypes().size() == 0) {\n            // Empty, skip!\n            continue;\n        }\n\n        const size_t typeCount = p->getOrderedTypes().size();\n        for (size_t ti = 0; ti < typeCount; ti++) {\n            sp<Type> t = p->getOrderedTypes().itemAt(ti);\n            if (t == NULL) {\n                continue;\n            }\n\n            const size_t configCount = t->getOrderedConfigs().size();\n            for (size_t ci = 0; ci < configCount; ci++) {\n                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);\n                if (c == NULL) {\n                    continue;\n                }\n\n                Vector<key_value_pair_t<ConfigDescription, sp<Entry> > > entriesToAdd;\n                const DefaultKeyedVector<ConfigDescription, sp<Entry> >& entries =\n                        c->getEntries();\n                const size_t entryCount = entries.size();\n                for (size_t ei = 0; ei < entryCount; ei++) {\n                    sp<Entry> e = entries.valueAt(ei);\n                    if (e == NULL || e->getType() != Entry::TYPE_BAG) {\n                        continue;\n                    }\n\n                    const ConfigDescription& config = entries.keyAt(ei);\n                    if (config.sdkVersion >= SDK_L) {\n                        // We don't need to do anything if the resource is\n                        // already qualified for version 21 or higher.\n                        continue;\n                    }\n\n                    Vector<String16> attributesToRemove;\n                    const KeyedVector<String16, Item>& bag = e->getBag();\n                    const size_t bagCount = bag.size();\n                    for (size_t bi = 0; bi < bagCount; bi++) {\n                        const Item& item = bag.valueAt(bi);\n                        const uint32_t attrId = getResId(bag.keyAt(bi), &attr16);\n                        if (isAttributeFromL(attrId)) {\n                            attributesToRemove.add(bag.keyAt(bi));\n                        }\n                    }\n\n                    if (attributesToRemove.isEmpty()) {\n                        continue;\n                    }\n\n                    // Duplicate the entry under the same configuration\n                    // but with sdkVersion == SDK_L.\n                    ConfigDescription newConfig(config);\n                    newConfig.sdkVersion = SDK_L;\n                    entriesToAdd.add(key_value_pair_t<ConfigDescription, sp<Entry> >(\n                            newConfig, new Entry(*e)));\n\n                    // Remove the attribute from the original.\n                    for (size_t i = 0; i < attributesToRemove.size(); i++) {\n                        e->removeFromBag(attributesToRemove[i]);\n                    }\n                }\n\n                const size_t entriesToAddCount = entriesToAdd.size();\n                for (size_t i = 0; i < entriesToAddCount; i++) {\n                    if (entries.indexOfKey(entriesToAdd[i].key) >= 0) {\n                        // An entry already exists for this config.\n                        // That means that any attributes that were\n                        // defined in L in the original bag will be overriden\n                        // anyways on L devices, so we do nothing.\n                        continue;\n                    }\n\n                    if (bundle->getVerbose()) {\n                        entriesToAdd[i].value->getPos()\n                                .printf(\"using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.\",\n                                        SDK_L,\n                                        String8(p->getName()).string(),\n                                        String8(t->getName()).string(),\n                                        String8(entriesToAdd[i].value->getName()).string(),\n                                        entriesToAdd[i].key.toString().string());\n                    }\n\n                    sp<Entry> newEntry = t->getEntry(c->getName(),\n                            entriesToAdd[i].value->getPos(),\n                            &entriesToAdd[i].key);\n\n                    *newEntry = *entriesToAdd[i].value;\n                }\n            }\n        }\n    }\n    return NO_ERROR;\n}\n\nstatus_t ResourceTable::modifyForCompat(const Bundle* bundle,\n                                        const String16& resourceName,\n                                        const sp<AaptFile>& target,\n                                        const sp<XMLNode>& root) {\n    const String16 vector16(\"vector\");\n    const String16 animatedVector16(\"animated-vector\");\n    if (isMinSdkVersionLOrAbove(bundle)) {\n        return NO_ERROR;\n    }\n\n    if (target->getResourceType() == \"\" || target->getGroupEntry().toParams().sdkVersion >= SDK_L) {\n        // Skip resources that have no type (AndroidManifest.xml) or are already version qualified with v21\n        // or higher.\n        return NO_ERROR;\n    }\n\n    Vector<key_value_pair_t<sp<XMLNode>, size_t> > attrsToRemove;\n\n    Vector<sp<XMLNode> > nodesToVisit;\n    nodesToVisit.push(root);\n    while (!nodesToVisit.isEmpty()) {\n        sp<XMLNode> node = nodesToVisit.top();\n        nodesToVisit.pop();\n\n        if (/*bundle->getNoVersionVectors() && */(node->getElementName() == vector16 ||\n                    node->getElementName() == animatedVector16)) {\n            // We were told not to version vector tags, so skip the children here.\n            continue;\n        }\n        const Vector<XMLNode::attribute_entry>& attrs = node->getAttributes();\n        const size_t attrCount = attrs.size();\n        for (size_t i = 0; i < attrCount; i++) {\n            const XMLNode::attribute_entry& attr = attrs[i];\n            if (isAttributeFromL(attr.nameResId)) {\n                attrsToRemove.add(key_value_pair_t<sp<XMLNode>, size_t>(node, i));\n            }\n        }\n\n        // Schedule a visit to the children.\n        const Vector<sp<XMLNode> >& children = node->getChildren();\n        const size_t childCount = children.size();\n        for (size_t i = 0; i < childCount; i++) {\n            nodesToVisit.push(children[i]);\n        }\n    }\n\n    if (attrsToRemove.isEmpty()) {\n        return NO_ERROR;\n    }\n\n    ConfigDescription newConfig(target->getGroupEntry().toParams());\n    newConfig.sdkVersion = SDK_L;\n\n    // Look to see if we already have an overriding v21 configuration.\n    sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()),\n            String16(target->getResourceType()), resourceName);\n    //if (cl == NULL) {\n    //    fprintf(stderr, \"fuuuuck\\n\");\n    //}\n    if (cl->getEntries().indexOfKey(newConfig) < 0) {\n        // We don't have an overriding entry for v21, so we must duplicate this one.\n        sp<XMLNode> newRoot = root->clone();\n        sp<AaptFile> newFile = new AaptFile(target->getSourceFile(),\n                AaptGroupEntry(newConfig), target->getResourceType());\n        String8 resPath = String8::format(\"res/%s/%s\",\n                newFile->getGroupEntry().toDirName(target->getResourceType()).string(),\n                target->getSourceFile().getPathLeaf().string());\n        resPath.convertToResPath();\n\n        // Add a resource table entry.\n        if (bundle->getVerbose()) {\n            SourcePos(target->getSourceFile(), -1).printf(\n                    \"using v%d attributes; synthesizing resource %s:%s/%s for configuration %s.\",\n                    SDK_L,\n                    mAssets->getPackage().string(),\n                    newFile->getResourceType().string(),\n                    String8(resourceName).string(),\n                    newConfig.toString().string());\n        }\n\n        addEntry(SourcePos(),\n                String16(mAssets->getPackage()),\n                String16(target->getResourceType()),\n                resourceName,\n                String16(resPath),\n                NULL,\n                &newConfig);\n\n        // Schedule this to be compiled.\n        CompileResourceWorkItem item;\n        item.resourceName = resourceName;\n        item.resPath = resPath;\n        item.file = newFile;\n        mWorkQueue.push(item);\n    }\n\n    const size_t removeCount = attrsToRemove.size();\n    for (size_t i = 0; i < removeCount; i++) {\n        sp<XMLNode> node = attrsToRemove[i].key;\n        size_t attrIndex = attrsToRemove[i].value;\n        const XMLNode::attribute_entry& ae = node->getAttributes()[attrIndex];\n        if (bundle->getVerbose()) {\n            SourcePos(node->getFilename(), node->getStartLineNumber()).printf(\n                    \"removing attribute %s%s%s from <%s>\",\n                    String8(ae.ns).string(),\n                    (ae.ns.size() == 0 ? \"\" : \":\"),\n                    String8(ae.name).string(),\n                    String8(node->getElementName()).string());\n        }\n        node->removeAttribute(attrIndex);\n    }\n\n    return NO_ERROR;\n\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/ResourceTable.h",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#ifndef RESOURCE_TABLE_H\n#define RESOURCE_TABLE_H\n\n#include \"ConfigDescription.h\"\n#include \"StringPool.h\"\n#include \"SourcePos.h\"\n#include \"ResourceFilter.h\"\n\n#include <map>\n#include <queue>\n#include <set>\n\nusing namespace std;\n\nclass XMLNode;\nclass ResourceTable;\n\nenum {\n    XML_COMPILE_STRIP_COMMENTS = 1<<0,\n    XML_COMPILE_ASSIGN_ATTRIBUTE_IDS = 1<<1,\n    XML_COMPILE_COMPACT_WHITESPACE = 1<<2,\n    XML_COMPILE_STRIP_WHITESPACE = 1<<3,\n    XML_COMPILE_STRIP_RAW_VALUES = 1<<4,\n    XML_COMPILE_UTF8 = 1<<5,\n    \n    XML_COMPILE_STANDARD_RESOURCE =\n            XML_COMPILE_STRIP_COMMENTS | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS\n            | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES\n};\n\nstatus_t compileXmlFile(const Bundle* bundle,\n                        const sp<AaptAssets>& assets,\n                        const String16& resourceName,\n                        const sp<AaptFile>& target,\n                        ResourceTable* table,\n                        int options = XML_COMPILE_STANDARD_RESOURCE);\n\nstatus_t compileXmlFile(const Bundle* bundle,\n                        const sp<AaptAssets>& assets,\n                        const String16& resourceName,\n                        const sp<AaptFile>& target,\n                        const sp<AaptFile>& outTarget,\n                        ResourceTable* table,\n                        int options = XML_COMPILE_STANDARD_RESOURCE);\n\nstatus_t compileXmlFile(const Bundle* bundle,\n                        const sp<AaptAssets>& assets,\n                        const String16& resourceName,\n                        const sp<XMLNode>& xmlTree,\n                        const sp<AaptFile>& target,\n                        ResourceTable* table,\n                        int options = XML_COMPILE_STANDARD_RESOURCE);\n\nstatus_t compileResourceFile(Bundle* bundle,\n                             const sp<AaptAssets>& assets,\n                             const sp<AaptFile>& in,\n                             const ResTable_config& defParams,\n                             const bool overwrite,\n                             ResourceTable* outTable);\n\nstruct AccessorCookie\n{\n    SourcePos sourcePos;\n    String8 attr;\n    String8 value;\n\n    AccessorCookie(const SourcePos&p, const String8& a, const String8& v)\n        :sourcePos(p),\n         attr(a),\n         value(v)\n    {\n    }\n};\n\n// Holds the necessary information to compile the\n// resource.\nstruct CompileResourceWorkItem {\n    String16 resourceName;\n    String8 resPath;\n    sp<AaptFile> file;\n};\n\nclass ResourceTable : public ResTable::Accessor\n{\npublic:\n    // The type of package to build.\n    enum PackageType {\n        App,\n        System,\n        SharedLibrary,\n        AppFeature\n    };\n\n    class Package;\n    class Type;\n    class Entry;\n\n    ResourceTable(Bundle* bundle, const String16& assetsPackage, PackageType type, uint32_t typeIdOffset);\n\n    const String16& getAssetsPackage() const {\n        return mAssetsPackage;\n    }\n\n    /**\n     * Returns the queue of resources that need to be compiled.\n     * This is only used for resources that have been generated\n     * during the compilation phase. If they were just added\n     * to the AaptAssets, then they may be skipped over\n     * and would mess up iteration order for the existing\n     * resources.\n     */\n    queue<CompileResourceWorkItem>& getWorkQueue() {\n        return mWorkQueue;\n    }\n\n    status_t addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets);\n\n    status_t addMapping(const SourcePos& pos,\n                     const sp<AaptAssets>& assets,\n                       const String16& package,\n                       const String16& type,\n                       const String16& name,\n                       const uint32_t ident);\n\n    status_t addPublic(const SourcePos& pos,\n                       const String16& package,\n                       const String16& type,\n                       const String16& name,\n                       const uint32_t ident);\n\n    status_t addEntry(const SourcePos& sourcePos,\n                      const String16& package,\n                      const String16& type,\n                      const String16& name,\n                      const String16& value,\n                      const Vector<StringPool::entry_style_span>* style = NULL,\n                      const ResTable_config* params = NULL,\n                      const bool doSetIndex = false,\n                      const int32_t format = ResTable_map::TYPE_ANY,\n                      const bool overwrite = false,\n                    int pos = -1);\n\n    status_t startBag(const SourcePos& pos,\n                    const String16& package,\n                    const String16& type,\n                    const String16& name,\n                    const String16& bagParent,\n                    const ResTable_config* params = NULL,\n                    bool overlay = false,\n                    bool replace = false,\n                    bool isId = false);\n    \n    status_t addBag(const SourcePos& pos,\n                    const String16& package,\n                    const String16& type,\n                    const String16& name,\n                    const String16& bagParent,\n                    const String16& bagKey,\n                    const String16& value,\n                    const Vector<StringPool::entry_style_span>* style = NULL,\n                    const ResTable_config* params = NULL,\n                    bool replace = false,\n                    bool isId = false,\n                    const int32_t format = ResTable_map::TYPE_ANY);\n\n    bool hasBagOrEntry(const String16& package,\n                       const String16& type,\n                       const String16& name) const;\n\n    bool hasBagOrEntry(const String16& package,\n                       const String16& type,\n                       const String16& name,\n                       const ResTable_config& config) const;\n\n    bool hasBagOrEntry(const String16& ref,\n                       const String16* defType = NULL,\n                       const String16* defPackage = NULL);\n\n    bool appendComment(const String16& package,\n                       const String16& type,\n                       const String16& name,\n                       const String16& comment,\n                       bool onlyIfEmpty = false);\n\n    bool appendTypeComment(const String16& package,\n                           const String16& type,\n                           const String16& name,\n                           const String16& comment);\n    \n    void canAddEntry(const SourcePos& pos,\n        const String16& package, const String16& type, const String16& name);\n        \n    size_t size() const;\n    size_t numLocalResources() const;\n    bool hasResources() const;\n\n    status_t modifyForCompat(const Bundle* bundle);\n    status_t modifyForCompat(const Bundle* bundle,\n                             const String16& resourceName,\n                             const sp<AaptFile>& file,\n                             const sp<XMLNode>& root);\n\n    sp<AaptFile> flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,\n            const bool isBase);\n\n    static inline uint32_t makeResId(uint32_t packageId,\n                                     uint32_t typeId,\n                                     uint32_t nameId)\n    {\n        return nameId | (typeId<<16) | (packageId<<24);\n    }\n\n    static inline uint32_t getResId(const sp<Package>& p,\n                                    const sp<Type>& t,\n                                    uint32_t nameId);\n\n    uint32_t getResId(const String16& package,\n                      const String16& type,\n                      const String16& name,\n                      bool onlyPublic = true) const;\n\n    uint32_t getResId(const String16& ref,\n                      const String16* defType = NULL,\n                      const String16* defPackage = NULL,\n                      const char** outErrorMsg = NULL,\n                      bool onlyPublic = true) const;\n\n    static bool isValidResourceName(const String16& s);\n    \n    bool stringToValue(Res_value* outValue, StringPool* pool,\n                       const String16& str,\n                       bool preserveSpaces, bool coerceType,\n                       uint32_t attrID,\n                       const Vector<StringPool::entry_style_span>* style = NULL,\n                       String16* outStr = NULL, void* accessorCookie = NULL,\n                       uint32_t attrType = ResTable_map::TYPE_ANY,\n                       const String8* configTypeName = NULL,\n                       const ConfigDescription* config = NULL);\n\n    status_t assignResourceIds(Bundle *bundle);\n    status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL);\n    void addLocalization(const String16& name, const String8& locale, const SourcePos& src);\n    status_t validateLocalizations(void);\n\n    status_t flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,\n            const sp<AaptFile>& dest, const bool isBase);\n    status_t flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs);\n\n    void writePublicDefinitions(const String16& package, FILE* fp);\n\n    virtual uint32_t getCustomResource(const String16& package,\n                                       const String16& type,\n                                       const String16& name) const;\n    virtual uint32_t getCustomResourceWithCreation(const String16& package,\n                                                   const String16& type,\n                                                   const String16& name,\n                                                   const bool createIfNeeded);\n    virtual uint32_t getRemappedPackage(uint32_t origPackage) const;\n    virtual bool getAttributeType(uint32_t attrID, uint32_t* outType);\n    virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin);\n    virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax);\n    virtual bool getAttributeKeys(uint32_t attrID, Vector<String16>* outKeys);\n    virtual bool getAttributeEnum(uint32_t attrID,\n                                  const char16_t* name, size_t nameLen,\n                                  Res_value* outValue);\n    virtual bool getAttributeFlags(uint32_t attrID,\n                                   const char16_t* name, size_t nameLen,\n                                   Res_value* outValue);\n    virtual uint32_t getAttributeL10N(uint32_t attrID);\n\n    virtual bool getLocalizationSetting();\n    virtual void reportError(void* accessorCookie, const char* fmt, ...);\n\n    void setCurrentXmlPos(const SourcePos& pos) { mCurrentXmlPos = pos; }\n\n    class Item {\n    public:\n        Item() : isId(false), format(ResTable_map::TYPE_ANY), bagKeyId(0), evaluating(false)\n            { memset(&parsedValue, 0, sizeof(parsedValue)); }\n        Item(const SourcePos& pos,\n             bool _isId,\n             const String16& _value,\n             const Vector<StringPool::entry_style_span>* _style = NULL,\n             int32_t format = ResTable_map::TYPE_ANY);\n        Item(const Item& o) : sourcePos(o.sourcePos),\n            isId(o.isId), value(o.value), style(o.style),\n            format(o.format), bagKeyId(o.bagKeyId), evaluating(false) {\n            memset(&parsedValue, 0, sizeof(parsedValue));\n        }\n        ~Item() { }\n\n        Item& operator=(const Item& o) {\n            sourcePos = o.sourcePos;\n            isId = o.isId;\n            value = o.value;\n            style = o.style;\n            format = o.format;\n            bagKeyId = o.bagKeyId;\n            parsedValue = o.parsedValue;\n            return *this;\n        }\n\n        SourcePos                               sourcePos;\n        mutable bool                            isId;\n        String16                                value;\n        Vector<StringPool::entry_style_span>    style;\n        int32_t                                 format;\n        uint32_t                                bagKeyId;\n        mutable bool                            evaluating;\n        Res_value                               parsedValue;\n    };\n\n    class Entry : public RefBase {\n    public:\n        Entry(const String16& name, const SourcePos& pos)\n            : mName(name), mType(TYPE_UNKNOWN),\n              mItemFormat(ResTable_map::TYPE_ANY), mNameIndex(-1), mPos(pos)\n        { }\n\n        Entry(const Entry& entry);\n        Entry& operator=(const Entry& entry);\n\n        virtual ~Entry() { }\n\n        enum type {\n            TYPE_UNKNOWN = 0,\n            TYPE_ITEM,\n            TYPE_BAG\n        };\n        \n        String16 getName() const { return mName; }\n        type getType() const { return mType; }\n\n        void setParent(const String16& parent) { mParent = parent; }\n        String16 getParent() const { return mParent; }\n\n        status_t makeItABag(const SourcePos& sourcePos);\n\n        status_t emptyBag(const SourcePos& sourcePos);\n \n        status_t setItem(const SourcePos& pos,\n                         const String16& value,\n                         const Vector<StringPool::entry_style_span>* style = NULL,\n                         int32_t format = ResTable_map::TYPE_ANY,\n                         const bool overwrite = false);\n\n        status_t addToBag(const SourcePos& pos,\n                          const String16& key, const String16& value,\n                          const Vector<StringPool::entry_style_span>* style = NULL,\n                          bool replace=false, bool isId = false,\n                          int32_t format = ResTable_map::TYPE_ANY);\n\n        status_t removeFromBag(const String16& key);\n\n        // Index of the entry's name string in the key pool.\n        int32_t getNameIndex() const { return mNameIndex; }\n        void setNameIndex(int32_t index) { mNameIndex = index; }\n\n        const Item* getItem() const { return mType == TYPE_ITEM ? &mItem : NULL; }\n        const KeyedVector<String16, Item>& getBag() const { return mBag; }\n\n        status_t generateAttributes(ResourceTable* table,\n                                    const String16& package);\n\n        status_t assignResourceIds( ResourceTable* table,\n                                   const String16& package,\n                                   Bundle *bundle);\n\n        status_t prepareFlatten(StringPool* strings, ResourceTable* table,\n               const String8* configTypeName, const ConfigDescription* config);\n\n        status_t remapStringValue(StringPool* strings);\n\n        ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic);\n\n        const SourcePos& getPos() const { return mPos; }\n\n    private:\n        String16 mName;\n        String16 mParent;\n        type mType;\n        Item mItem;\n        int32_t mItemFormat;\n        KeyedVector<String16, Item> mBag;\n        int32_t mNameIndex;\n        uint32_t mParentId;\n        SourcePos mPos;\n    };\n    \n    class ConfigList : public RefBase {\n    public:\n        ConfigList(const String16& name, const SourcePos& pos)\n            : mName(name), mPos(pos), mPublic(false), mEntryIndex(-1) { }\n        virtual ~ConfigList() { }\n        \n        String16 getName() const { return mName; }\n        const SourcePos& getPos() const { return mPos; }\n        \n        void appendComment(const String16& comment, bool onlyIfEmpty = false);\n        const String16& getComment() const { return mComment; }\n        \n        void appendTypeComment(const String16& comment);\n        const String16& getTypeComment() const { return mTypeComment; }\n        \n        // Index of this entry in its Type.\n        int32_t getEntryIndex() const { return mEntryIndex; }\n        void setEntryIndex(int32_t index) { mEntryIndex = index; }\n        \n        void setPublic(bool pub) { mPublic = pub; }\n        bool getPublic() const { return mPublic; }\n        void setPublicSourcePos(const SourcePos& pos) { mPublicSourcePos = pos; }\n        const SourcePos& getPublicSourcePos() { return mPublicSourcePos; }\n        \n        void addEntry(const ResTable_config& config, const sp<Entry>& entry) {\n            mEntries.add(config, entry);\n        }\n        \n        const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; }\n    private:\n        const String16 mName;\n        const SourcePos mPos;\n        String16 mComment;\n        String16 mTypeComment;\n        bool mPublic;\n        SourcePos mPublicSourcePos;\n        int32_t mEntryIndex;\n        DefaultKeyedVector<ConfigDescription, sp<Entry> > mEntries;\n    };\n    \n    class Public {\n    public:\n        Public() : sourcePos(), ident(0) { }\n        Public(const SourcePos& pos,\n               const String16& _comment,\n               uint32_t _ident)\n            : sourcePos(pos),\n            comment(_comment), ident(_ident) { }\n        Public(const Public& o) : sourcePos(o.sourcePos),\n            comment(o.comment), ident(o.ident) { }\n        ~Public() { }\n        \n        Public& operator=(const Public& o) {\n            sourcePos = o.sourcePos;\n            comment = o.comment;\n            ident = o.ident;\n            return *this;\n        }\n        \n        SourcePos   sourcePos;\n        String16    comment;\n        uint32_t    ident;\n    };\n    \n    class Type : public RefBase {\n    public:\n        Type(const String16& name, const SourcePos& pos)\n                : mName(name), mFirstPublicSourcePos(NULL), mPublicIndex(-1), mIndex(-1), mPos(pos)\n        { }\n        virtual ~Type() { delete mFirstPublicSourcePos; }\n\n        status_t addMapping(const SourcePos& pos,\n                     const sp<AaptSymbols> typeSymbols,\n                           const String16& name,\n                           const uint32_t ident);\n\n        status_t addPublic(const SourcePos& pos,\n                           const String16& name,\n                           const uint32_t ident);\n                           \n        void canAddEntry(const String16& name);\n        \n        String16 getName() const { return mName; }\n        sp<Entry> getEntry(const String16& entry,\n                           const SourcePos& sourcePos,\n                           const ResTable_config* config = NULL,\n                           bool doSetIndex = false,\n                           bool overlay = false,\n                           bool autoAddOverlay = false,\n                           int pos = -1);\n\n        const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }\n\n        int32_t getPublicIndex() const { return mPublicIndex; }\n\n        int32_t getIndex() const { return mIndex; }\n        void setIndex(int32_t index) { mIndex = index; }\n\n        status_t applyMappingEntryOrder();\n\n        status_t applyPublicEntryOrder();\n\n        const SortedVector<ConfigDescription>& getUniqueConfigs() const { return mUniqueConfigs; }\n        \n        const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }\n        const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }\n\n        const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }\n        \n        const SourcePos& getPos() const { return mPos; }\n    private:\n        String16 mName;\n        SourcePos* mFirstPublicSourcePos;\n        DefaultKeyedVector<String16, Public> mPublic;\n        DefaultKeyedVector<String16, Public> mMapping;\n        SortedVector<ConfigDescription> mUniqueConfigs;\n        DefaultKeyedVector<String16, sp<ConfigList> > mConfigs;\n        Vector<sp<ConfigList> > mOrderedConfigs;\n        SortedVector<String16> mCanAddEntries;\n        int32_t mPublicIndex;\n        int32_t mIndex;\n        SourcePos mPos;\n    };\n\n    class Package : public RefBase {\n    public:\n        Package(const String16& name, size_t packageId);\n        virtual ~Package() { }\n\n        String16 getName() const { return mName; }\n        sp<Type> getType(const String16& type,\n                         const SourcePos& pos,\n//                         const int32_t indexOffSet,\n                         bool doSetIndex = false);\n\n        size_t getAssignedId() const { return mPackageId; }\n\n        const ResStringPool& getTypeStrings() const { return mTypeStrings; }\n        uint32_t indexOfTypeString(const String16& s) const { return mTypeStringsMapping.valueFor(s); }\n        const sp<AaptFile> getTypeStringsData() const { return mTypeStringsData; }\n        status_t setTypeStrings(const sp<AaptFile>& data);\n\n        const ResStringPool& getKeyStrings() const { return mKeyStrings; }\n        uint32_t indexOfKeyString(const String16& s) const { return mKeyStringsMapping.valueFor(s); }\n        const sp<AaptFile> getKeyStringsData() const { return mKeyStringsData; }\n        status_t setKeyStrings(const sp<AaptFile>& data);\n\n        status_t applyPublicTypeOrder();\n\n        const DefaultKeyedVector<String16, sp<Type> >& getTypes() const { return mTypes; }\n        const Vector<sp<Type> >& getOrderedTypes() const { return mOrderedTypes; }\n\n    private:\n        status_t setStrings(const sp<AaptFile>& data,\n                            ResStringPool* strings,\n                            DefaultKeyedVector<String16, uint32_t>* mappings);\n\n        const String16 mName;\n        const size_t mPackageId;\n        DefaultKeyedVector<String16, sp<Type> > mTypes;\n        Vector<sp<Type> > mOrderedTypes;\n        sp<AaptFile> mTypeStringsData;\n        sp<AaptFile> mKeyStringsData;\n        ResStringPool mTypeStrings;\n        ResStringPool mKeyStrings;\n        DefaultKeyedVector<String16, uint32_t> mTypeStringsMapping;\n        DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;\n    };\n\nprivate:\n    void writePublicDefinitions(const String16& package, FILE* fp, bool pub);\n    sp<Package> getPackage(const String16& package);\n    sp<Type> getType(const String16& package,\n                     const String16& type,\n                     const SourcePos& pos,\n                     bool doSetIndex = false);\n    sp<Entry> getEntry(const String16& package,\n                       const String16& type,\n                       const String16& name,\n                       const SourcePos& sourcePos,\n                       bool overlay,\n                       const ResTable_config* config = NULL,\n                       bool doSetIndex = false,\n                    int pos = -1);\n    sp<const Entry> getEntry(uint32_t resID,\n                             const ResTable_config* config = NULL) const;\n    sp<ConfigList> getConfigList(const String16& package,\n                                 const String16& type,\n                                 const String16& name) const;\n    const Item* getItem(uint32_t resID, uint32_t attrID) const;\n    bool getItemValue(uint32_t resID, uint32_t attrID,\n                      Res_value* outValue);\n    bool isAttributeFromL(uint32_t attrId);\n\n\n    String16 mAssetsPackage;\n    PackageType mPackageType;\n    sp<AaptAssets> mAssets;\n    uint32_t mTypeIdOffset;\n    DefaultKeyedVector<String16, sp<Package> > mPackages;\n    Vector<sp<Package> > mOrderedPackages;\n    size_t mNumLocal;\n    SourcePos mCurrentXmlPos;\n    Bundle* mBundle;\n    \n    // key = string resource name, value = set of locales in which that name is defined\n    map<String16, map<String8, SourcePos> > mLocalizations;\n    queue<CompileResourceWorkItem> mWorkQueue;\n};\n\n#endif\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/SourcePos.cpp",
    "content": "#include \"SourcePos.h\"\n\n#include <stdarg.h>\n#include <vector>\n\nusing namespace std;\n\n\n// ErrorPos\n// =============================================================================\nstruct ErrorPos\n{\n    enum Level {\n        NOTE,\n        WARNING,\n        ERROR\n    };\n\n    String8 file;\n    int line;\n    String8 error;\n    Level level;\n\n    ErrorPos();\n    ErrorPos(const ErrorPos& that);\n    ErrorPos(const String8& file, int line, const String8& error, Level level);\n    ErrorPos& operator=(const ErrorPos& rhs);\n\n    void print(FILE* to) const;\n};\n\nstatic vector<ErrorPos> g_errors;\n\nErrorPos::ErrorPos()\n    :line(-1), level(NOTE)\n{\n}\n\nErrorPos::ErrorPos(const ErrorPos& that)\n    :file(that.file),\n     line(that.line),\n     error(that.error),\n     level(that.level)\n{\n}\n\nErrorPos::ErrorPos(const String8& f, int l, const String8& e, Level lev)\n    :file(f),\n     line(l),\n     error(e),\n     level(lev)\n{\n}\n\nErrorPos&\nErrorPos::operator=(const ErrorPos& rhs)\n{\n    this->file = rhs.file;\n    this->line = rhs.line;\n    this->error = rhs.error;\n    this->level = rhs.level;\n    return *this;\n}\n\nvoid\nErrorPos::print(FILE* to) const\n{\n    const char* type = \"\";\n    switch (level) {\n    case NOTE:\n        type = \"note: \";\n        break;\n    case WARNING:\n        type = \"warning: \";\n        break;\n    case ERROR:\n        type = \"error: \";\n        break;\n    }\n    \n    if (!this->file.isEmpty()) {\n        if (this->line >= 0) {\n            fprintf(to, \"%s:%d: %s%s\\n\", this->file.string(), this->line, type, this->error.string());\n        } else {\n            fprintf(to, \"%s: %s%s\\n\", this->file.string(), type, this->error.string());\n        }\n    } else {\n        fprintf(to, \"%s%s\\n\", type, this->error.string());\n    }\n}\n\n// SourcePos\n// =============================================================================\nSourcePos::SourcePos(const String8& f, int l)\n    : file(f), line(l)\n{\n}\n\nSourcePos::SourcePos(const SourcePos& that)\n    : file(that.file), line(that.line)\n{\n}\n\nSourcePos::SourcePos()\n    : file(\"???\", 0), line(-1)\n{\n}\n\nSourcePos::~SourcePos()\n{\n}\n\nvoid\nSourcePos::error(const char* fmt, ...) const\n{\n    va_list ap;\n    va_start(ap, fmt);\n    String8 msg = String8::formatV(fmt, ap);\n    va_end(ap);\n    g_errors.push_back(ErrorPos(this->file, this->line, msg, ErrorPos::ERROR));\n}\n\nvoid\nSourcePos::warning(const char* fmt, ...) const\n{\n    va_list ap;\n    va_start(ap, fmt);\n    String8 msg = String8::formatV(fmt, ap);\n    va_end(ap);\n    ErrorPos(this->file, this->line, msg, ErrorPos::WARNING).print(stderr);\n}\n\nvoid\nSourcePos::printf(const char* fmt, ...) const\n{\n    va_list ap;\n    va_start(ap, fmt);\n    String8 msg = String8::formatV(fmt, ap);\n    va_end(ap);\n    ErrorPos(this->file, this->line, msg, ErrorPos::NOTE).print(stderr);\n}\n\nbool\nSourcePos::hasErrors()\n{\n    return g_errors.size() > 0;\n}\n\nvoid\nSourcePos::printErrors(FILE* to)\n{\n    vector<ErrorPos>::const_iterator it;\n    for (it=g_errors.begin(); it!=g_errors.end(); it++) {\n        it->print(to);\n    }\n}\n\n\n\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/SourcePos.h",
    "content": "#ifndef SOURCEPOS_H\n#define SOURCEPOS_H\n\n#include <utils/String8.h>\n#include <stdio.h>\n\nusing namespace android;\n\nclass SourcePos\n{\npublic:\n    String8 file;\n    int line;\n\n    SourcePos(const String8& f, int l);\n    SourcePos(const SourcePos& that);\n    SourcePos();\n    ~SourcePos();\n\n    void error(const char* fmt, ...) const;\n    void warning(const char* fmt, ...) const;\n    void printf(const char* fmt, ...) const;\n\n    static bool hasErrors();\n    static void printErrors(FILE* to);\n};\n\n\n#endif // SOURCEPOS_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/StringPool.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#include \"StringPool.h\"\n#include \"ResourceTable.h\"\n\n#include <utils/ByteOrder.h>\n#include <utils/SortedVector.h>\n#include \"qsort_r_compat.h\"\n\n#if HAVE_PRINTF_ZD\n#  define ZD \"%zd\"\n#  define ZD_TYPE ssize_t\n#else\n#  define ZD \"%ld\"\n#  define ZD_TYPE long\n#endif\n\n#define NOISY(x) //x\n\nvoid strcpy16_htod(uint16_t* dst, const uint16_t* src)\n{\n    while (*src) {\n        char16_t s = htods(*src);\n        *dst++ = s;\n        src++;\n    }\n    *dst = 0;\n}\n\nvoid printStringPool(const ResStringPool* pool)\n{\n    if (pool->getError() == NO_INIT) {\n        printf(\"String pool is unitialized.\\n\");\n        return;\n    } else if (pool->getError() != NO_ERROR) {\n        printf(\"String pool is corrupt/invalid.\\n\");\n        return;\n    }\n\n    SortedVector<const void*> uniqueStrings;\n    const size_t N = pool->size();\n    for (size_t i=0; i<N; i++) {\n        size_t len;\n        if (pool->isUTF8()) {\n            uniqueStrings.add(pool->string8At(i, &len));\n        } else {\n            uniqueStrings.add(pool->stringAt(i, &len));\n        }\n    }\n\n    printf(\"String pool of \" ZD \" unique %s %s strings, \" ZD \" entries and \"\n            ZD \" styles using \" ZD \" bytes:\\n\",\n            (ZD_TYPE)uniqueStrings.size(), pool->isUTF8() ? \"UTF-8\" : \"UTF-16\",\n            pool->isSorted() ? \"sorted\" : \"non-sorted\",\n            (ZD_TYPE)N, (ZD_TYPE)pool->styleCount(), (ZD_TYPE)pool->bytes());\n\n    const size_t NS = pool->size();\n    for (size_t s=0; s<NS; s++) {\n        String8 str = pool->string8ObjectAt(s);\n        printf(\"String #\" ZD \": %s\\n\", (ZD_TYPE) s, str.string());\n    }\n}\n\nString8 StringPool::entry::makeConfigsString() const {\n    String8 configStr(configTypeName);\n    if (configStr.size() > 0) configStr.append(\" \");\n    if (configs.size() > 0) {\n        for (size_t j=0; j<configs.size(); j++) {\n            if (j > 0) configStr.append(\", \");\n            configStr.append(configs[j].toString());\n        }\n    } else {\n        configStr = \"(none)\";\n    }\n    return configStr;\n}\n\nint StringPool::entry::compare(const entry& o) const {\n    // Strings with styles go first, to reduce the size of the styles array.\n    // We don't care about the relative order of these strings.\n    if (hasStyles) {\n        return o.hasStyles ? 0 : -1;\n    }\n    if (o.hasStyles) {\n        return 1;\n    }\n\n    // Sort unstyled strings by type, then by logical configuration.\n    int comp = configTypeName.compare(o.configTypeName);\n    if (comp != 0) {\n        return comp;\n    }\n    const size_t LHN = configs.size();\n    const size_t RHN = o.configs.size();\n    size_t i=0;\n    while (i < LHN && i < RHN) {\n        comp = configs[i].compareLogical(o.configs[i]);\n        if (comp != 0) {\n            return comp;\n        }\n        i++;\n    }\n    if (LHN < RHN) return -1;\n    else if (LHN > RHN) return 1;\n    return 0;\n}\n\nStringPool::StringPool(bool utf8) :\n        mUTF8(utf8), mValues(-1)\n{\n}\n\nssize_t StringPool::add(const String16& value, const Vector<entry_style_span>& spans,\n        const String8* configTypeName, const ResTable_config* config)\n{\n    ssize_t res = add(value, false, configTypeName, config);\n    if (res >= 0) {\n        addStyleSpans(res, spans);\n    }\n    return res;\n}\n\nssize_t StringPool::add(const String16& value,\n        bool mergeDuplicates, const String8* configTypeName, const ResTable_config* config)\n{\n    ssize_t vidx = mValues.indexOfKey(value);\n    ssize_t pos = vidx >= 0 ? mValues.valueAt(vidx) : -1;\n    ssize_t eidx = pos >= 0 ? mEntryArray.itemAt(pos) : -1;\n    if (eidx < 0) {\n        eidx = mEntries.add(entry(value));\n        if (eidx < 0) {\n            fprintf(stderr, \"Failure adding string %s\\n\", String8(value).string());\n            return eidx;\n        }\n    }\n\n    if (configTypeName != NULL) {\n        entry& ent = mEntries.editItemAt(eidx);\n        NOISY(printf(\"*** adding config type name %s, was %s\\n\",\n                configTypeName->string(), ent.configTypeName.string()));\n        if (ent.configTypeName.size() <= 0) {\n            ent.configTypeName = *configTypeName;\n        } else if (ent.configTypeName != *configTypeName) {\n            ent.configTypeName = \" \";\n        }\n    }\n\n    if (config != NULL) {\n        // Add this to the set of configs associated with the string.\n        entry& ent = mEntries.editItemAt(eidx);\n        size_t addPos;\n        for (addPos=0; addPos<ent.configs.size(); addPos++) {\n            int cmp = ent.configs.itemAt(addPos).compareLogical(*config);\n            if (cmp >= 0) {\n                if (cmp > 0) {\n                    NOISY(printf(\"*** inserting config: %s\\n\", config->toString().string()));\n                    ent.configs.insertAt(*config, addPos);\n                }\n                break;\n            }\n        }\n        if (addPos >= ent.configs.size()) {\n            NOISY(printf(\"*** adding config: %s\\n\", config->toString().string()));\n            ent.configs.add(*config);\n        }\n    }\n\n    const bool first = vidx < 0;\n    const bool styled = (pos >= 0 && (size_t)pos < mEntryStyleArray.size()) ?\n        mEntryStyleArray[pos].spans.size() : 0;\n    if (first || styled || !mergeDuplicates) {\n        pos = mEntryArray.add(eidx);\n        if (first) {\n            vidx = mValues.add(value, pos);\n        }\n        entry& ent = mEntries.editItemAt(eidx);\n        ent.indices.add(pos);\n    }\n\n    NOISY(printf(\"Adding string %s to pool: pos=%d eidx=%d vidx=%d\\n\",\n            String8(value).string(), pos, eidx, vidx));\n    \n    return pos;\n}\n\nstatus_t StringPool::addStyleSpan(size_t idx, const String16& name,\n                                  uint32_t start, uint32_t end)\n{\n    entry_style_span span;\n    span.name = name;\n    span.span.firstChar = start;\n    span.span.lastChar = end;\n    return addStyleSpan(idx, span);\n}\n\nstatus_t StringPool::addStyleSpans(size_t idx, const Vector<entry_style_span>& spans)\n{\n    const size_t N=spans.size();\n    for (size_t i=0; i<N; i++) {\n        status_t err = addStyleSpan(idx, spans[i]);\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n    return NO_ERROR;\n}\n\nstatus_t StringPool::addStyleSpan(size_t idx, const entry_style_span& span)\n{\n    // Place blank entries in the span array up to this index.\n    while (mEntryStyleArray.size() <= idx) {\n        mEntryStyleArray.add();\n    }\n\n    entry_style& style = mEntryStyleArray.editItemAt(idx);\n    style.spans.add(span);\n    mEntries.editItemAt(mEntryArray[idx]).hasStyles = true;\n    return NO_ERROR;\n}\n\nint StringPool::config_sort(void* state, const void* lhs, const void* rhs)\n{\n    StringPool* pool = (StringPool*)state;\n    const entry& lhe = pool->mEntries[pool->mEntryArray[*static_cast<const size_t*>(lhs)]];\n    const entry& rhe = pool->mEntries[pool->mEntryArray[*static_cast<const size_t*>(rhs)]];\n    return lhe.compare(rhe);\n}\n\nvoid StringPool::sortByConfig()\n{\n    LOG_ALWAYS_FATAL_IF(mOriginalPosToNewPos.size() > 0, \"Can't sort string pool after already sorted.\");\n\n    const size_t N = mEntryArray.size();\n\n    // This is a vector that starts out with a 1:1 mapping to entries\n    // in the array, which we will sort to come up with the desired order.\n    // At that point it maps from the new position in the array to the\n    // original position the entry appeared.\n    Vector<size_t> newPosToOriginalPos;\n    newPosToOriginalPos.setCapacity(N);\n    for (size_t i=0; i < N; i++) {\n        newPosToOriginalPos.add(i);\n    }\n\n    // Sort the array.\n    NOISY(printf(\"SORTING STRINGS BY CONFIGURATION...\\n\"));\n    // Vector::sort uses insertion sort, which is very slow for this data set.\n    // Use quicksort instead because we don't need a stable sort here.\n    qsort_r_compat(newPosToOriginalPos.editArray(), N, sizeof(size_t), this, config_sort);\n    //newPosToOriginalPos.sort(config_sort, this);\n    NOISY(printf(\"DONE SORTING STRINGS BY CONFIGURATION.\\n\"));\n\n    // Create the reverse mapping from the original position in the array\n    // to the new position where it appears in the sorted array.  This is\n    // so that clients can re-map any positions they had previously stored.\n    mOriginalPosToNewPos = newPosToOriginalPos;\n    for (size_t i=0; i<N; i++) {\n        mOriginalPosToNewPos.editItemAt(newPosToOriginalPos[i]) = i;\n    }\n\n#if 0\n    SortedVector<entry> entries;\n\n    for (size_t i=0; i<N; i++) {\n        printf(\"#%d was %d: %s\\n\", i, newPosToOriginalPos[i],\n                mEntries[mEntryArray[newPosToOriginalPos[i]]].makeConfigsString().string());\n        entries.add(mEntries[mEntryArray[i]]);\n    }\n\n    for (size_t i=0; i<entries.size(); i++) {\n        printf(\"Sorted config #%d: %s\\n\", i,\n                entries[i].makeConfigsString().string());\n    }\n#endif\n\n    // Now we rebuild the arrays.\n    Vector<entry> newEntries;\n    Vector<size_t> newEntryArray;\n    Vector<entry_style> newEntryStyleArray;\n    DefaultKeyedVector<size_t, size_t> origOffsetToNewOffset;\n\n    for (size_t i=0; i<N; i++) {\n        // We are filling in new offset 'i'; oldI is where we can find it\n        // in the original data structure.\n        size_t oldI = newPosToOriginalPos[i];\n        // This is the actual entry associated with the old offset.\n        const entry& oldEnt = mEntries[mEntryArray[oldI]];\n        // This is the same entry the last time we added it to the\n        // new entry array, if any.\n        ssize_t newIndexOfOffset = origOffsetToNewOffset.indexOfKey(oldI);\n        size_t newOffset;\n        if (newIndexOfOffset < 0) {\n            // This is the first time we have seen the entry, so add\n            // it.\n            newOffset = newEntries.add(oldEnt);\n            newEntries.editItemAt(newOffset).indices.clear();\n        } else {\n            // We have seen this entry before, use the existing one\n            // instead of adding it again.\n            newOffset = origOffsetToNewOffset.valueAt(newIndexOfOffset);\n        }\n        // Update the indices to include this new position.\n        newEntries.editItemAt(newOffset).indices.add(i);\n        // And add the offset of the entry to the new entry array.\n        newEntryArray.add(newOffset);\n        // Add any old style to the new style array.\n        if (mEntryStyleArray.size() > 0) {\n            if (oldI < mEntryStyleArray.size()) {\n                newEntryStyleArray.add(mEntryStyleArray[oldI]);\n            } else {\n                newEntryStyleArray.add(entry_style());\n            }\n        }\n    }\n\n    // Now trim any entries at the end of the new style array that are\n    // not needed.\n    for (ssize_t i=newEntryStyleArray.size()-1; i>=0; i--) {\n        const entry_style& style = newEntryStyleArray[i];\n        if (style.spans.size() > 0) {\n            // That's it.\n            break;\n        }\n        // This one is not needed; remove.\n        newEntryStyleArray.removeAt(i);\n    }\n\n    // All done, install the new data structures and upate mValues with\n    // the new positions.\n    mEntries = newEntries;\n    mEntryArray = newEntryArray;\n    mEntryStyleArray = newEntryStyleArray;\n    mValues.clear();\n    for (size_t i=0; i<mEntries.size(); i++) {\n        const entry& ent = mEntries[i];\n        mValues.add(ent.value, ent.indices[0]);\n    }\n\n#if 0\n    printf(\"FINAL SORTED STRING CONFIGS:\\n\");\n    for (size_t i=0; i<mEntries.size(); i++) {\n        const entry& ent = mEntries[i];\n        printf(\"#\" ZD \" %s: %s\\n\", (ZD_TYPE)i, ent.makeConfigsString().string(),\n                String8(ent.value).string());\n    }\n#endif\n}\n\nsp<AaptFile> StringPool::createStringBlock()\n{\n    sp<AaptFile> pool = new AaptFile(String8(), AaptGroupEntry(),\n                                     String8());\n    status_t err = writeStringBlock(pool);\n    return err == NO_ERROR ? pool : NULL;\n}\n\n#define ENCODE_LENGTH(str, chrsz, strSize) \\\n{ \\\n    size_t maxMask = 1 << ((chrsz*8)-1); \\\n    size_t maxSize = maxMask-1; \\\n    if (strSize > maxSize) { \\\n        *str++ = maxMask | ((strSize>>(chrsz*8))&maxSize); \\\n    } \\\n    *str++ = strSize; \\\n}\n\nstatus_t StringPool::writeStringBlock(const sp<AaptFile>& pool)\n{\n    // Allow appending.  Sorry this is a little wacky.\n    if (pool->getSize() > 0) {\n        sp<AaptFile> block = createStringBlock();\n        if (block == NULL) {\n            return UNKNOWN_ERROR;\n        }\n        ssize_t res = pool->writeData(block->getData(), block->getSize());\n        return (res >= 0) ? (status_t)NO_ERROR : res;\n    }\n\n    // First we need to add all style span names to the string pool.\n    // We do this now (instead of when the span is added) so that these\n    // will appear at the end of the pool, not disrupting the order\n    // our client placed their own strings in it.\n    \n    const size_t STYLES = mEntryStyleArray.size();\n    size_t i;\n\n    for (i=0; i<STYLES; i++) {\n        entry_style& style = mEntryStyleArray.editItemAt(i);\n        const size_t N = style.spans.size();\n        for (size_t i=0; i<N; i++) {\n            entry_style_span& span = style.spans.editItemAt(i);\n            ssize_t idx = add(span.name, true);\n            if (idx < 0) {\n                fprintf(stderr, \"Error adding span for style tag '%s'\\n\",\n                        String8(span.name).string());\n                return idx;\n            }\n            span.span.name.index = (uint32_t)idx;\n        }\n    }\n\n    const size_t ENTRIES = mEntryArray.size();\n\n    // Now build the pool of unique strings.\n\n    const size_t STRINGS = mEntries.size();\n    const size_t preSize = sizeof(ResStringPool_header)\n                         + (sizeof(uint32_t)*ENTRIES)\n                         + (sizeof(uint32_t)*STYLES);\n    if (pool->editData(preSize) == NULL) {\n        fprintf(stderr, \"ERROR: Out of memory for string pool\\n\");\n        return NO_MEMORY;\n    }\n\n    const size_t charSize = mUTF8 ? sizeof(uint8_t) : sizeof(char16_t);\n\n    size_t strPos = 0;\n    for (i=0; i<STRINGS; i++) {\n        entry& ent = mEntries.editItemAt(i);\n        const size_t strSize = (ent.value.size());\n        const size_t lenSize = strSize > (size_t)(1<<((charSize*8)-1))-1 ?\n            charSize*2 : charSize;\n\n        String8 encStr;\n        if (mUTF8) {\n            encStr = String8(ent.value);\n        }\n\n        const size_t encSize = mUTF8 ? encStr.size() : 0;\n        const size_t encLenSize = mUTF8 ?\n            (encSize > (size_t)(1<<((charSize*8)-1))-1 ?\n                charSize*2 : charSize) : 0;\n\n        ent.offset = strPos;\n\n        const size_t totalSize = lenSize + encLenSize +\n            ((mUTF8 ? encSize : strSize)+1)*charSize;\n\n        void* dat = (void*)pool->editData(preSize + strPos + totalSize);\n        if (dat == NULL) {\n            fprintf(stderr, \"ERROR: Out of memory for string pool\\n\");\n            return NO_MEMORY;\n        }\n        dat = (uint8_t*)dat + preSize + strPos;\n        if (mUTF8) {\n            uint8_t* strings = (uint8_t*)dat;\n\n            ENCODE_LENGTH(strings, sizeof(uint8_t), strSize)\n\n            ENCODE_LENGTH(strings, sizeof(uint8_t), encSize)\n\n            strncpy((char*)strings, encStr, encSize+1);\n        } else {\n            uint16_t* strings = (uint16_t*)dat;\n\n            ENCODE_LENGTH(strings, sizeof(uint16_t), strSize)\n\n            strcpy16_htod(strings, ent.value);\n        }\n\n        strPos += totalSize;\n    }\n\n    // Pad ending string position up to a uint32_t boundary.\n\n    if (strPos&0x3) {\n        size_t padPos = ((strPos+3)&~0x3);\n        uint8_t* dat = (uint8_t*)pool->editData(preSize + padPos);\n        if (dat == NULL) {\n            fprintf(stderr, \"ERROR: Out of memory padding string pool\\n\");\n            return NO_MEMORY;\n        }\n        memset(dat+preSize+strPos, 0, padPos-strPos);\n        strPos = padPos;\n    }\n\n    // Build the pool of style spans.\n\n    size_t styPos = strPos;\n    for (i=0; i<STYLES; i++) {\n        entry_style& ent = mEntryStyleArray.editItemAt(i);\n        const size_t N = ent.spans.size();\n        const size_t totalSize = (N*sizeof(ResStringPool_span))\n                               + sizeof(ResStringPool_ref);\n\n        ent.offset = styPos-strPos;\n        uint8_t* dat = (uint8_t*)pool->editData(preSize + styPos + totalSize);\n        if (dat == NULL) {\n            fprintf(stderr, \"ERROR: Out of memory for string styles\\n\");\n            return NO_MEMORY;\n        }\n        ResStringPool_span* span = (ResStringPool_span*)(dat+preSize+styPos);\n        for (size_t i=0; i<N; i++) {\n            span->name.index = htodl(ent.spans[i].span.name.index);\n            span->firstChar = htodl(ent.spans[i].span.firstChar);\n            span->lastChar = htodl(ent.spans[i].span.lastChar);\n            span++;\n        }\n        span->name.index = htodl(ResStringPool_span::END);\n\n        styPos += totalSize;\n    }\n\n    if (STYLES > 0) {\n        // Add full terminator at the end (when reading we validate that\n        // the end of the pool is fully terminated to simplify error\n        // checking).\n        size_t extra = sizeof(ResStringPool_span)-sizeof(ResStringPool_ref);\n        uint8_t* dat = (uint8_t*)pool->editData(preSize + styPos + extra);\n        if (dat == NULL) {\n            fprintf(stderr, \"ERROR: Out of memory for string styles\\n\");\n            return NO_MEMORY;\n        }\n        uint32_t* p = (uint32_t*)(dat+preSize+styPos);\n        while (extra > 0) {\n            *p++ = htodl(ResStringPool_span::END);\n            extra -= sizeof(uint32_t);\n        }\n        styPos += extra;\n    }\n\n    // Write header.\n\n    ResStringPool_header* header =\n        (ResStringPool_header*)pool->padData(sizeof(uint32_t));\n    if (header == NULL) {\n        fprintf(stderr, \"ERROR: Out of memory for string pool\\n\");\n        return NO_MEMORY;\n    }\n    memset(header, 0, sizeof(*header));\n    header->header.type = htods(RES_STRING_POOL_TYPE);\n    header->header.headerSize = htods(sizeof(*header));\n    header->header.size = htodl(pool->getSize());\n    header->stringCount = htodl(ENTRIES);\n    header->styleCount = htodl(STYLES);\n    if (mUTF8) {\n        header->flags |= htodl(ResStringPool_header::UTF8_FLAG);\n    }\n    header->stringsStart = htodl(preSize);\n    header->stylesStart = htodl(STYLES > 0 ? (preSize+strPos) : 0);\n\n    // Write string index array.\n\n    uint32_t* index = (uint32_t*)(header+1);\n    for (i=0; i<ENTRIES; i++) {\n        entry& ent = mEntries.editItemAt(mEntryArray[i]);\n        *index++ = htodl(ent.offset);\n        NOISY(printf(\"Writing entry #%d: \\\"%s\\\" ent=%d off=%d\\n\", i,\n                String8(ent.value).string(),\n                mEntryArray[i], ent.offset));\n    }\n\n    // Write style index array.\n\n    for (i=0; i<STYLES; i++) {\n        *index++ = htodl(mEntryStyleArray[i].offset);\n    }\n\n    return NO_ERROR;\n}\n\nssize_t StringPool::offsetForString(const String16& val) const\n{\n    const Vector<size_t>* indices = offsetsForString(val);\n    ssize_t res = indices != NULL && indices->size() > 0 ? indices->itemAt(0) : -1;\n    NOISY(printf(\"Offset for string %s: %d (%s)\\n\", String8(val).string(), res,\n            res >= 0 ? String8(mEntries[mEntryArray[res]].value).string() : String8()));\n    return res;\n}\n\nconst Vector<size_t>* StringPool::offsetsForString(const String16& val) const\n{\n    ssize_t pos = mValues.valueFor(val);\n    if (pos < 0) {\n        return NULL;\n    }\n    return &mEntries[mEntryArray[pos]].indices;\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/StringPool.h",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#ifndef STRING_POOL_H\n#define STRING_POOL_H\n\n#include \"Main.h\"\n#include \"AaptAssets.h\"\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/String16.h>\n#include <utils/TypeHelpers.h>\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <ctype.h>\n#include <errno.h>\n\n#include <libexpat/expat.h>\n\nusing namespace android;\n\n#define PRINT_STRING_METRICS 0\n\nvoid strcpy16_htod(uint16_t* dst, const uint16_t* src);\n\nvoid printStringPool(const ResStringPool* pool);\n\n/**\n * The StringPool class is used as an intermediate representation for\n * generating the string pool resource data structure that can be parsed with\n * ResStringPool in include/utils/ResourceTypes.h.\n */\nclass StringPool\n{\npublic:\n    struct entry {\n        entry() : offset(0) { }\n        entry(const String16& _value) : value(_value), offset(0), hasStyles(false) { }\n        entry(const entry& o) : value(o.value), offset(o.offset),\n                hasStyles(o.hasStyles), indices(o.indices),\n                configTypeName(o.configTypeName), configs(o.configs) { }\n\n        String16 value;\n        size_t offset;\n        bool hasStyles;\n        Vector<size_t> indices;\n        String8 configTypeName;\n        Vector<ResTable_config> configs;\n\n        String8 makeConfigsString() const;\n\n        int compare(const entry& o) const;\n\n        inline bool operator<(const entry& o) const { return compare(o) < 0; }\n        inline bool operator<=(const entry& o) const { return compare(o) <= 0; }\n        inline bool operator==(const entry& o) const { return compare(o) == 0; }\n        inline bool operator!=(const entry& o) const { return compare(o) != 0; }\n        inline bool operator>=(const entry& o) const { return compare(o) >= 0; }\n        inline bool operator>(const entry& o) const { return compare(o) > 0; }\n    };\n\n    struct entry_style_span {\n        String16 name;\n        ResStringPool_span span;\n    };\n\n    struct entry_style {\n        entry_style() : offset(0) { }\n\n        entry_style(const entry_style& o) : offset(o.offset), spans(o.spans) { }\n\n        size_t offset;\n        Vector<entry_style_span> spans;\n    };\n\n    /**\n     * If 'utf8' is true, strings will be encoded with UTF-8 instead of\n     * left in Java's native UTF-16.\n     */\n    explicit StringPool(bool utf8 = false);\n\n    /**\n     * Add a new string to the pool.  If mergeDuplicates is true, thenif\n     * the string already exists the existing entry for it will be used;\n     * otherwise, or if the value doesn't already exist, a new entry is\n     * created.\n     *\n     * Returns the index in the entry array of the new string entry.\n     */\n    ssize_t add(const String16& value, bool mergeDuplicates = false,\n            const String8* configTypeName = NULL, const ResTable_config* config = NULL);\n\n    ssize_t add(const String16& value, const Vector<entry_style_span>& spans,\n            const String8* configTypeName = NULL, const ResTable_config* config = NULL);\n\n    status_t addStyleSpan(size_t idx, const String16& name,\n                          uint32_t start, uint32_t end);\n    status_t addStyleSpans(size_t idx, const Vector<entry_style_span>& spans);\n    status_t addStyleSpan(size_t idx, const entry_style_span& span);\n\n    // Sort the contents of the string block by the configuration associated\n    // with each item.  After doing this you can use mapOriginalPosToNewPos()\n    // to find out the new position given the position originally returned by\n    // add().\n    void sortByConfig();\n\n    // For use after sortByConfig() to map from the original position of\n    // a string to its new sorted position.\n    size_t mapOriginalPosToNewPos(size_t originalPos) const {\n        return mOriginalPosToNewPos.itemAt(originalPos);\n    }\n\n    sp<AaptFile> createStringBlock();\n\n    status_t writeStringBlock(const sp<AaptFile>& pool);\n\n    /**\n     * Find out an offset in the pool for a particular string.  If the string\n     * pool is sorted, this can not be called until after createStringBlock()\n     * or writeStringBlock() has been called\n     * (which determines the offsets).  In the case of a string that appears\n     * multiple times in the pool, the first offset will be returned.  Returns\n     * -1 if the string does not exist.\n     */\n    ssize_t offsetForString(const String16& val) const;\n\n    /**\n     * Find all of the offsets in the pool for a particular string.  If the\n     * string pool is sorted, this can not be called until after\n     * createStringBlock() or writeStringBlock() has been called\n     * (which determines the offsets).  Returns NULL if the string does not exist.\n     */\n    const Vector<size_t>* offsetsForString(const String16& val) const;\n\nprivate:\n    static int config_sort(void* state, const void* lhs, const void* rhs);\n\n    const bool                              mUTF8;\n\n    // The following data structures represent the actual structures\n    // that will be generated for the final string pool.\n\n    // Raw array of unique strings, in some arbitrary order.  This is the\n    // actual strings that appear in the final string pool, in the order\n    // that they will be written.\n    Vector<entry>                           mEntries;\n    // Array of indices into mEntries, in the order they were\n    // added to the pool.  This can be different than mEntries\n    // if the same string was added multiple times (it will appear\n    // once in mEntries, with multiple occurrences in this array).\n    // This is the lookup array that will be written for finding\n    // the string for each offset/position in the string pool.\n    Vector<size_t>                          mEntryArray;\n    // Optional style span information associated with each index of\n    // mEntryArray.\n    Vector<entry_style>                     mEntryStyleArray;\n\n    // The following data structures are used for book-keeping as the\n    // string pool is constructed.\n\n    // Unique set of all the strings added to the pool, mapped to\n    // the first index of mEntryArray where the value was added.\n    DefaultKeyedVector<String16, ssize_t>   mValues;\n    // This array maps from the original position a string was placed at\n    // in mEntryArray to its new position after being sorted with sortByConfig().\n    Vector<size_t>                          mOriginalPosToNewPos;\n};\n\n// The entry types are trivially movable because all fields they contain, including\n// the vectors and strings, are trivially movable.\nnamespace android {\n    ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry);\n    ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry_style_span);\n    ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry_style);\n};\n\n#endif\n\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/WorkQueue.cpp",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #define LOG_NDEBUG 0\n#define LOG_TAG \"WorkQueue\"\n\n#include <utils/Log.h>\n#include \"WorkQueue.h\"\n\nnamespace android {\n\n// --- WorkQueue ---\n\nWorkQueue::WorkQueue(size_t maxThreads, bool canCallJava) :\n        mMaxThreads(maxThreads), mCanCallJava(canCallJava),\n        mCanceled(false), mFinished(false), mIdleThreads(0) {\n}\n\nWorkQueue::~WorkQueue() {\n    if (!cancel()) {\n        finish();\n    }\n}\n\nstatus_t WorkQueue::schedule(WorkUnit* workUnit, size_t backlog) {\n    AutoMutex _l(mLock);\n\n    if (mFinished || mCanceled) {\n        return INVALID_OPERATION;\n    }\n\n    if (mWorkThreads.size() < mMaxThreads\n            && mIdleThreads < mWorkUnits.size() + 1) {\n        sp<WorkThread> workThread = new WorkThread(this, mCanCallJava);\n        status_t status = workThread->run(\"WorkQueue::WorkThread\");\n        if (status) {\n            return status;\n        }\n        mWorkThreads.add(workThread);\n        mIdleThreads += 1;\n    } else if (backlog) {\n        while (mWorkUnits.size() >= mMaxThreads * backlog) {\n            mWorkDequeuedCondition.wait(mLock);\n            if (mFinished || mCanceled) {\n                return INVALID_OPERATION;\n            }\n        }\n    }\n\n    mWorkUnits.add(workUnit);\n    mWorkChangedCondition.broadcast();\n    return OK;\n}\n\nstatus_t WorkQueue::cancel() {\n    AutoMutex _l(mLock);\n\n    return cancelLocked();\n}\n\nstatus_t WorkQueue::cancelLocked() {\n    if (mFinished) {\n        return INVALID_OPERATION;\n    }\n\n    if (!mCanceled) {\n        mCanceled = true;\n\n        size_t count = mWorkUnits.size();\n        for (size_t i = 0; i < count; i++) {\n            delete mWorkUnits.itemAt(i);\n        }\n        mWorkUnits.clear();\n        mWorkChangedCondition.broadcast();\n        mWorkDequeuedCondition.broadcast();\n    }\n    return OK;\n}\n\nstatus_t WorkQueue::finish() {\n    { // acquire lock\n        AutoMutex _l(mLock);\n\n        if (mFinished) {\n            return INVALID_OPERATION;\n        }\n\n        mFinished = true;\n        mWorkChangedCondition.broadcast();\n    } // release lock\n\n    // It is not possible for the list of work threads to change once the mFinished\n    // flag has been set, so we can access mWorkThreads outside of the lock here.\n    size_t count = mWorkThreads.size();\n    for (size_t i = 0; i < count; i++) {\n        mWorkThreads.itemAt(i)->join();\n    }\n    mWorkThreads.clear();\n    return OK;\n}\n\nbool WorkQueue::threadLoop() {\n    WorkUnit* workUnit;\n    { // acquire lock\n        AutoMutex _l(mLock);\n\n        for (;;) {\n            if (mCanceled) {\n                return false;\n            }\n\n            if (!mWorkUnits.isEmpty()) {\n                workUnit = mWorkUnits.itemAt(0);\n                mWorkUnits.removeAt(0);\n                mIdleThreads -= 1;\n                mWorkDequeuedCondition.broadcast();\n                break;\n            }\n\n            if (mFinished) {\n                return false;\n            }\n\n            mWorkChangedCondition.wait(mLock);\n        }\n    } // release lock\n\n    bool shouldContinue = workUnit->run();\n    delete workUnit;\n\n    { // acquire lock\n        AutoMutex _l(mLock);\n\n        mIdleThreads += 1;\n\n        if (!shouldContinue) {\n            cancelLocked();\n            return false;\n        }\n    } // release lock\n\n    return true;\n}\n\n// --- WorkQueue::WorkThread ---\n\nWorkQueue::WorkThread::WorkThread(WorkQueue* workQueue, bool canCallJava) :\n        Thread(canCallJava), mWorkQueue(workQueue) {\n}\n\nWorkQueue::WorkThread::~WorkThread() {\n}\n\nbool WorkQueue::WorkThread::threadLoop() {\n    return mWorkQueue->threadLoop();\n}\n\n};  // namespace android\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/WorkQueue.h",
    "content": "/*]\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef AAPT_WORK_QUEUE_H\n#define AAPT_WORK_QUEUE_H\n\n#include <utils/Errors.h>\n#include <utils/Vector.h>\n#include <utils/threads.h>\n\nnamespace android {\n\n/*\n * A threaded work queue.\n *\n * This class is designed to make it easy to run a bunch of isolated work\n * units in parallel, using up to the specified number of threads.\n * To use it, write a loop to post work units to the work queue, then synchronize\n * on the queue at the end.\n */\nclass WorkQueue {\npublic:\n    class WorkUnit {\n    public:\n        WorkUnit() { }\n        virtual ~WorkUnit() { }\n\n        /*\n         * Runs the work unit.\n         * If the result is 'true' then the work queue continues scheduling work as usual.\n         * If the result is 'false' then the work queue is canceled.\n         */\n        virtual bool run() = 0;\n    };\n\n    /* Creates a work queue with the specified maximum number of work threads. */\n    WorkQueue(size_t maxThreads, bool canCallJava = true);\n\n    /* Destroys the work queue.\n     * Cancels pending work and waits for all remaining threads to complete.\n     */\n    ~WorkQueue();\n\n    /* Posts a work unit to run later.\n     * If the work queue has been canceled or is already finished, returns INVALID_OPERATION\n     * and does not take ownership of the work unit (caller must destroy it itself).\n     * Otherwise, returns OK and takes ownership of the work unit (the work queue will\n     * destroy it automatically).\n     *\n     * For flow control, this method blocks when the size of the pending work queue is more\n     * 'backlog' times the number of threads.  This condition reduces the rate of entry into\n     * the pending work queue and prevents it from growing much more rapidly than the\n     * work threads can actually handle.\n     *\n     * If 'backlog' is 0, then no throttle is applied.\n     */\n    status_t schedule(WorkUnit* workUnit, size_t backlog = 2);\n\n    /* Cancels all pending work.\n     * If the work queue is already finished, returns INVALID_OPERATION.\n     * If the work queue is already canceled, returns OK and does nothing else.\n     * Otherwise, returns OK, discards all pending work units and prevents additional\n     * work units from being scheduled.\n     *\n     * Call finish() after cancel() to wait for all remaining work to complete.\n     */\n    status_t cancel();\n\n    /* Waits for all work to complete.\n     * If the work queue is already finished, returns INVALID_OPERATION.\n     * Otherwise, waits for all work to complete and returns OK.\n     */\n    status_t finish();\n\nprivate:\n    class WorkThread : public Thread {\n    public:\n        WorkThread(WorkQueue* workQueue, bool canCallJava);\n        virtual ~WorkThread();\n\n    private:\n        virtual bool threadLoop();\n\n        WorkQueue* const mWorkQueue;\n    };\n\n    status_t cancelLocked();\n    bool threadLoop(); // called from each work thread\n\n    const size_t mMaxThreads;\n    const bool mCanCallJava;\n\n    Mutex mLock;\n    Condition mWorkChangedCondition;\n    Condition mWorkDequeuedCondition;\n\n    bool mCanceled;\n    bool mFinished;\n    size_t mIdleThreads;\n    Vector<sp<WorkThread> > mWorkThreads;\n    Vector<WorkUnit*> mWorkUnits;\n};\n\n}; // namespace android\n\n#endif // AAPT_WORK_QUEUE_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/XMLNode.cpp",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#include \"XMLNode.h\"\n#include \"ResourceTable.h\"\n#include \"pseudolocalize.h\"\n\n#include <utils/ByteOrder.h>\n#include <errno.h>\n#include <string.h>\n#include <androidfw/ResourcePackageId.h>\n\n#ifndef HAVE_MS_C_RUNTIME\n#define O_BINARY 0\n#endif\n\n#define NOISY(x) //x\n#define NOISY_PARSE(x) //x\n\nconst char* const RESOURCES_ROOT_NAMESPACE = \"http://schemas.android.com/apk/res/\";\nconst char* const RESOURCES_ANDROID_NAMESPACE = \"http://schemas.android.com/apk/res/android\";\nconst char* const RESOURCES_AUTO_PACKAGE_NAMESPACE = \"http://schemas.android.com/apk/res-auto\";\nconst char* const RESOURCES_ROOT_PRV_NAMESPACE = \"http://schemas.android.com/apk/prv/res/\";\n\nconst char* const XLIFF_XMLNS = \"urn:oasis:names:tc:xliff:document:1.2\";\nconst char* const ALLOWED_XLIFF_ELEMENTS[] = {\n        \"bpt\",\n        \"ept\",\n        \"it\",\n        \"ph\",\n        \"g\",\n        \"bx\",\n        \"ex\",\n        \"x\"\n    };\n\nbool isWhitespace(const char16_t* str)\n{\n    while (*str != 0 && *str < 128 && isspace(*str)) {\n        str++;\n    }\n    return *str == 0;\n}\n\nstatic const String16 RESOURCES_PREFIX(RESOURCES_ROOT_NAMESPACE);\nstatic const String16 RESOURCES_PREFIX_AUTO_PACKAGE(RESOURCES_AUTO_PACKAGE_NAMESPACE);\nstatic const String16 RESOURCES_PRV_PREFIX(RESOURCES_ROOT_PRV_NAMESPACE);\nstatic const String16 RESOURCES_TOOLS_NAMESPACE(\"http://schemas.android.com/tools\");\n\nString16 getNamespaceResourcePackage(String16 appPackage, String16 namespaceUri, bool* outIsPublic)\n{\n    //printf(\"%s starts with %s?\\n\", String8(namespaceUri).string(),\n    //       String8(RESOURCES_PREFIX).string());\n    size_t prefixSize;\n    bool isPublic = true;\n    if(namespaceUri.startsWith(RESOURCES_PREFIX_AUTO_PACKAGE)) {\n        NOISY(printf(\"Using default application package: %s -> %s\\n\", String8(namespaceUri).string(), String8(appPackage).string()));\n        isPublic = true;\n        return appPackage;\n    } else if (namespaceUri.startsWith(RESOURCES_PREFIX)) {\n        prefixSize = RESOURCES_PREFIX.size();\n    } else if (namespaceUri.startsWith(RESOURCES_PRV_PREFIX)) {\n        isPublic = false;\n        prefixSize = RESOURCES_PRV_PREFIX.size();\n    } else {\n        if (outIsPublic) *outIsPublic = isPublic; // = true\n        return String16();\n    }\n\n    //printf(\"YES!\\n\");\n    //printf(\"namespace: %s\\n\", String8(String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize)).string());\n    if (outIsPublic) *outIsPublic = isPublic;\n    return String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize);\n}\n\nstatus_t hasSubstitutionErrors(const char* fileName,\n                               ResXMLTree* inXml,\n                               String16 str16)\n{\n    const char16_t* str = str16.string();\n    const char16_t* p = str;\n    const char16_t* end = str + str16.size();\n\n    bool nonpositional = false;\n    int argCount = 0;\n\n    while (p < end) {\n        /*\n         * Look for the start of a Java-style substitution sequence.\n         */\n        if (*p == '%' && p + 1 < end) {\n            p++;\n\n            // A literal percent sign represented by %%\n            if (*p == '%') {\n                p++;\n                continue;\n            }\n\n            argCount++;\n\n            if (*p >= '0' && *p <= '9') {\n                do {\n                    p++;\n                } while (*p >= '0' && *p <= '9');\n                if (*p != '$') {\n                    // This must be a size specification instead of position.\n                    nonpositional = true;\n                }\n            } else if (*p == '<') {\n                // Reusing last argument; bad idea since it can be re-arranged.\n                nonpositional = true;\n                p++;\n\n                // Optionally '$' can be specified at the end.\n                if (p < end && *p == '$') {\n                    p++;\n                }\n            } else {\n                nonpositional = true;\n            }\n\n            // Ignore flags and widths\n            while (p < end && (*p == '-' ||\n                    *p == '#' ||\n                    *p == '+' ||\n                    *p == ' ' ||\n                    *p == ',' ||\n                    *p == '(' ||\n                    (*p >= '0' && *p <= '9'))) {\n                p++;\n            }\n\n            /*\n             * This is a shortcut to detect strings that are going to Time.format()\n             * instead of String.format()\n             *\n             * Comparison of String.format() and Time.format() args:\n             *\n             * String: ABC E GH  ST X abcdefgh  nost x\n             *   Time:    DEFGHKMS W Za  d   hkm  s w yz\n             *\n             * Therefore we know it's definitely Time if we have:\n             *     DFKMWZkmwyz\n             */\n            if (p < end) {\n                switch (*p) {\n                case 'D':\n                case 'F':\n                case 'K':\n                case 'M':\n                case 'W':\n                case 'Z':\n                case 'k':\n                case 'm':\n                case 'w':\n                case 'y':\n                case 'z':\n                    return NO_ERROR;\n                }\n            }\n        }\n\n        p++;\n    }\n\n    /*\n     * If we have more than one substitution in this string and any of them\n     * are not in positional form, give the user an error.\n     */\n    if (argCount > 1 && nonpositional) {\n        SourcePos(String8(fileName), inXml->getLineNumber()).error(\n                \"Multiple substitutions specified in non-positional format; \"\n                \"did you mean to add the formatted=\\\"false\\\" attribute?\\n\");\n        return NOT_ENOUGH_DATA;\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t parseStyledString(Bundle* bundle,\n                           const char* fileName,\n                           ResXMLTree* inXml,\n                           const String16& endTag,\n                           String16* outString,\n                           Vector<StringPool::entry_style_span>* outSpans,\n                           bool isFormatted,\n                           PseudolocalizationMethod pseudolocalize)\n{\n    Vector<StringPool::entry_style_span> spanStack;\n    String16 curString;\n    String16 rawString;\n    const char* errorMsg;\n    int xliffDepth = 0;\n    bool firstTime = true;\n\n    size_t len;\n    ResXMLTree::event_code_t code;\n    // Bracketing if pseudolocalization accented method specified.\n    if (pseudolocalize == PSEUDO_ACCENTED) {\n        curString.append(String16(String8(\"[\")));\n    }\n    while ((code=inXml->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        if (code == ResXMLTree::TEXT) {\n            String16 text(inXml->getText(&len));\n            if (firstTime && text.size() > 0) {\n                firstTime = false;\n                if (text.string()[0] == '@') {\n                    // If this is a resource reference, don't do the pseudoloc.\n                    pseudolocalize = NO_PSEUDOLOCALIZATION;\n                }\n            }\n            if (xliffDepth == 0 && pseudolocalize > 0) {\n                String16 pseudo;\n                if (pseudolocalize == PSEUDO_ACCENTED) {\n                    pseudo = pseudolocalize_string(text);\n                } else if (pseudolocalize == PSEUDO_BIDI) {\n                    pseudo = pseudobidi_string(text);\n                } else {\n                    pseudo = text;\n                }\n                curString.append(pseudo);\n            } else {\n                if (isFormatted && hasSubstitutionErrors(fileName, inXml, text) != NO_ERROR) {\n                    return UNKNOWN_ERROR;\n                } else {\n                    curString.append(text);\n                }\n            }\n        } else if (code == ResXMLTree::START_TAG) {\n            const String16 element16(inXml->getElementName(&len));\n            const String8 element8(element16);\n\n            size_t nslen;\n            const uint16_t* ns = inXml->getElementNamespace(&nslen);\n            if (ns == NULL) {\n                ns = (const uint16_t*)\"\\0\\0\";\n                nslen = 0;\n            }\n            const String8 nspace(String16(ns, nslen));\n            if (nspace == XLIFF_XMLNS) {\n                const int N = sizeof(ALLOWED_XLIFF_ELEMENTS)/sizeof(ALLOWED_XLIFF_ELEMENTS[0]);\n                for (int i=0; i<N; i++) {\n                    if (element8 == ALLOWED_XLIFF_ELEMENTS[i]) {\n                        xliffDepth++;\n                        // in this case, treat it like it was just text, in other words, do nothing\n                        // here and silently drop this element\n                        goto moveon;\n                    }\n                }\n                {\n                    SourcePos(String8(fileName), inXml->getLineNumber()).error(\n                            \"Found unsupported XLIFF tag <%s>\\n\",\n                            element8.string());\n                    return UNKNOWN_ERROR;\n                }\nmoveon:\n                continue;\n            }\n\n            if (outSpans == NULL) {\n                SourcePos(String8(fileName), inXml->getLineNumber()).error(\n                        \"Found style tag <%s> where styles are not allowed\\n\", element8.string());\n                return UNKNOWN_ERROR;\n            }\n\n            if (!ResTable::collectString(outString, curString.string(),\n                                         curString.size(), false, &errorMsg, true)) {\n                SourcePos(String8(fileName), inXml->getLineNumber()).error(\"%s (in %s)\\n\",\n                        errorMsg, String8(curString).string());\n                return UNKNOWN_ERROR;\n            }\n            rawString.append(curString);\n            curString = String16();\n\n            StringPool::entry_style_span span;\n            span.name = element16;\n            for (size_t ai=0; ai<inXml->getAttributeCount(); ai++) {\n                span.name.append(String16(\";\"));\n                const char16_t* str = inXml->getAttributeName(ai, &len);\n                span.name.append(str, len);\n                span.name.append(String16(\"=\"));\n                str = inXml->getAttributeStringValue(ai, &len);\n                span.name.append(str, len);\n            }\n            //printf(\"Span: %s\\n\", String8(span.name).string());\n            span.span.firstChar = span.span.lastChar = outString->size();\n            spanStack.push(span);\n\n        } else if (code == ResXMLTree::END_TAG) {\n            size_t nslen;\n            const uint16_t* ns = inXml->getElementNamespace(&nslen);\n            if (ns == NULL) {\n                ns = (const uint16_t*)\"\\0\\0\";\n                nslen = 0;\n            }\n            const String8 nspace(String16(ns, nslen));\n            if (nspace == XLIFF_XMLNS) {\n                xliffDepth--;\n                continue;\n            }\n            if (!ResTable::collectString(outString, curString.string(),\n                                         curString.size(), false, &errorMsg, true)) {\n                SourcePos(String8(fileName), inXml->getLineNumber()).error(\"%s (in %s)\\n\",\n                        errorMsg, String8(curString).string());\n                return UNKNOWN_ERROR;\n            }\n            rawString.append(curString);\n            curString = String16();\n\n            if (spanStack.size() == 0) {\n                if (strcmp16(inXml->getElementName(&len), endTag.string()) != 0) {\n                    SourcePos(String8(fileName), inXml->getLineNumber()).error(\n                            \"Found tag %s where <%s> close is expected\\n\",\n                            String8(inXml->getElementName(&len)).string(),\n                            String8(endTag).string());\n                    return UNKNOWN_ERROR;\n                }\n                break;\n            }\n            StringPool::entry_style_span span = spanStack.top();\n            String16 spanTag;\n            ssize_t semi = span.name.findFirst(';');\n            if (semi >= 0) {\n                spanTag.setTo(span.name.string(), semi);\n            } else {\n                spanTag.setTo(span.name);\n            }\n            if (strcmp16(inXml->getElementName(&len), spanTag.string()) != 0) {\n                SourcePos(String8(fileName), inXml->getLineNumber()).error(\n                        \"Found close tag %s where close tag %s is expected\\n\",\n                        String8(inXml->getElementName(&len)).string(),\n                        String8(spanTag).string());\n                return UNKNOWN_ERROR;\n            }\n            bool empty = true;\n            if (outString->size() > 0) {\n                span.span.lastChar = outString->size()-1;\n                if (span.span.lastChar >= span.span.firstChar) {\n                    empty = false;\n                    outSpans->add(span);\n                }\n            }\n            spanStack.pop();\n\n            /*\n             * This warning seems to be just an irritation to most people,\n             * since it is typically introduced by translators who then never\n             * see the warning.\n             */\n            if (0 && empty) {\n                fprintf(stderr, \"%s:%d: warning: empty '%s' span found in text '%s'\\n\",\n                        fileName, inXml->getLineNumber(),\n                        String8(spanTag).string(), String8(*outString).string());\n\n            }\n        } else if (code == ResXMLTree::START_NAMESPACE) {\n            // nothing\n        }\n    }\n\n    // Bracketing if pseudolocalization accented method specified.\n    if (pseudolocalize == PSEUDO_ACCENTED) {\n        const char16_t* str = outString->string();\n        const char16_t* p = str;\n        const char16_t* e = p + outString->size();\n        int words_cnt = 0;\n        while (p < e) {\n            if (isspace(*p)) {\n                words_cnt++;\n            }\n            p++;\n        }\n        unsigned int length = words_cnt > 3 ? outString->size() :\n            outString->size() / 2;\n        curString.append(String16(String8(\" \")));\n        curString.append(pseudo_generate_expansion(length));\n        curString.append(String16(String8(\"]\")));\n    }\n\n    if (code == ResXMLTree::BAD_DOCUMENT) {\n            SourcePos(String8(fileName), inXml->getLineNumber()).error(\n                    \"Error parsing XML\\n\");\n    }\n\n    if (outSpans != NULL && outSpans->size() > 0) {\n        if (curString.size() > 0) {\n            if (!ResTable::collectString(outString, curString.string(),\n                                         curString.size(), false, &errorMsg, true)) {\n                SourcePos(String8(fileName), inXml->getLineNumber()).error(\n                        \"%s (in %s)\\n\",\n                        errorMsg, String8(curString).string());\n                return UNKNOWN_ERROR;\n            }\n        }\n    } else {\n        // There is no style information, so string processing will happen\n        // later as part of the overall type conversion.  Return to the\n        // client the raw unprocessed text.\n        rawString.append(curString);\n        outString->setTo(rawString);\n    }\n\n    return NO_ERROR;\n}\n\nstruct namespace_entry {\n    String8 prefix;\n    String8 uri;\n};\n\nstatic String8 make_prefix(int depth)\n{\n    String8 prefix;\n    int i;\n    for (i=0; i<depth; i++) {\n        prefix.append(\"  \");\n    }\n    return prefix;\n}\n\nstatic String8 build_namespace(const Vector<namespace_entry>& namespaces,\n        const uint16_t* ns)\n{\n    String8 str;\n    if (ns != NULL) {\n        str = String8(ns);\n        const size_t N = namespaces.size();\n        for (size_t i=0; i<N; i++) {\n            const namespace_entry& ne = namespaces.itemAt(i);\n            if (ne.uri == str) {\n                str = ne.prefix;\n                break;\n            }\n        }\n        str.append(\":\");\n    }\n    return str;\n}\n\nvoid printXMLBlock(ResXMLTree* block)\n{\n    block->restart();\n\n    Vector<namespace_entry> namespaces;\n    \n    ResXMLTree::event_code_t code;\n    int depth = 0;\n    while ((code=block->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {\n        String8 prefix = make_prefix(depth);\n        int i;\n        if (code == ResXMLTree::START_TAG) {\n            size_t len;\n            const uint16_t* ns16 = block->getElementNamespace(&len);\n            String8 elemNs = build_namespace(namespaces, ns16);\n            const uint16_t* com16 = block->getComment(&len);\n            if (com16) {\n                printf(\"%s <!-- %s -->\\n\", prefix.string(), String8(com16).string());\n            }\n            printf(\"%sE: %s%s (line=%d)\\n\", prefix.string(), elemNs.string(),\n                   String8(block->getElementName(&len)).string(),\n                   block->getLineNumber());\n            int N = block->getAttributeCount();\n            depth++;\n            prefix = make_prefix(depth);\n            for (i=0; i<N; i++) {\n                uint32_t res = block->getAttributeNameResID(i);\n                ns16 = block->getAttributeNamespace(i, &len);\n                String8 ns = build_namespace(namespaces, ns16);\n                String8 name(block->getAttributeName(i, &len));\n                printf(\"%sA: \", prefix.string());\n                if (res) {\n                    printf(\"%s%s(0x%08x)\", ns.string(), name.string(), res);\n                } else {\n                    printf(\"%s%s\", ns.string(), name.string());\n                }\n                Res_value value;\n                block->getAttributeValue(i, &value);\n                if (value.dataType == Res_value::TYPE_NULL) {\n                    printf(\"=(null)\");\n                } else if (value.dataType == Res_value::TYPE_REFERENCE) {\n                    printf(\"=@0x%x\", (int)value.data);\n                } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) {\n                    printf(\"=?0x%x\", (int)value.data);\n                } else if (value.dataType == Res_value::TYPE_STRING) {\n                    printf(\"=\\\"%s\\\"\",\n                            ResTable::normalizeForOutput(String8(block->getAttributeStringValue(i,\n                                        &len)).string()).string());\n                } else {\n                    printf(\"=(type 0x%x)0x%x\", (int)value.dataType, (int)value.data);\n                }\n                const char16_t* val = block->getAttributeStringValue(i, &len);\n                if (val != NULL) {\n                    printf(\" (Raw: \\\"%s\\\")\", ResTable::normalizeForOutput(String8(val).string()).\n                            string());\n                }\n                printf(\"\\n\");\n            }\n        } else if (code == ResXMLTree::END_TAG) {\n            depth--;\n        } else if (code == ResXMLTree::START_NAMESPACE) {\n            namespace_entry ns;\n            size_t len;\n            const uint16_t* prefix16 = block->getNamespacePrefix(&len);\n            if (prefix16) {\n                ns.prefix = String8(prefix16);\n            } else {\n                ns.prefix = \"<DEF>\";\n            }\n            ns.uri = String8(block->getNamespaceUri(&len));\n            namespaces.push(ns);\n            printf(\"%sN: %s=%s\\n\", prefix.string(), ns.prefix.string(),\n                    ns.uri.string());\n            depth++;\n        } else if (code == ResXMLTree::END_NAMESPACE) {\n            depth--;\n            const namespace_entry& ns = namespaces.top();\n            size_t len;\n            const uint16_t* prefix16 = block->getNamespacePrefix(&len);\n            String8 pr;\n            if (prefix16) {\n                pr = String8(prefix16);\n            } else {\n                pr = \"<DEF>\";\n            }\n            if (ns.prefix != pr) {\n                prefix = make_prefix(depth);\n                printf(\"%s*** BAD END NS PREFIX: found=%s, expected=%s\\n\",\n                        prefix.string(), pr.string(), ns.prefix.string());\n            }\n            String8 uri = String8(block->getNamespaceUri(&len));\n            if (ns.uri != uri) {\n                prefix = make_prefix(depth);\n                printf(\"%s *** BAD END NS URI: found=%s, expected=%s\\n\",\n                        prefix.string(), uri.string(), ns.uri.string());\n            }\n            namespaces.pop();\n        } else if (code == ResXMLTree::TEXT) {\n            size_t len;\n            printf(\"%sC: \\\"%s\\\"\\n\", prefix.string(),\n                    ResTable::normalizeForOutput(String8(block->getText(&len)).string()).string());\n        }\n    }\n\n    block->restart();\n}\n\nstatus_t parseXMLResource(const sp<AaptFile>& file, ResXMLTree* outTree,\n                          bool stripAll, bool keepComments,\n                          const char** cDataTags)\n{\n    sp<XMLNode> root = XMLNode::parse(file);\n    if (root == NULL) {\n        return UNKNOWN_ERROR;\n    }\n    root->removeWhitespace(stripAll, cDataTags);\n\n    NOISY(printf(\"Input XML from %s:\\n\", (const char*)file->getPrintableSource()));\n    NOISY(root->print());\n    sp<AaptFile> rsc = new AaptFile(String8(), AaptGroupEntry(), String8());\n    status_t err = root->flatten(rsc, !keepComments, false);\n    if (err != NO_ERROR) {\n        return err;\n    }\n    err = outTree->setTo(rsc->getData(), rsc->getSize(), true);\n    if (err != NO_ERROR) {\n        return err;\n    }\n\n    NOISY(printf(\"Output XML:\\n\"));\n    NOISY(printXMLBlock(outTree));\n\n    return NO_ERROR;\n}\n\nsp<XMLNode> XMLNode::parse(const sp<AaptFile>& file)\n{\n    char buf[16384];\n    int fd = open(file->getSourceFile().string(), O_RDONLY | O_BINARY);\n    if (fd < 0) {\n        SourcePos(file->getSourceFile(), -1).error(\"Unable to open file for read: %s\",\n                strerror(errno));\n        return NULL;\n    }\n\n    XML_Parser parser = XML_ParserCreateNS(NULL, 1);\n    ParseState state;\n    state.filename = file->getPrintableSource();\n    state.parser = parser;\n    XML_SetUserData(parser, &state);\n    XML_SetElementHandler(parser, startElement, endElement);\n    XML_SetNamespaceDeclHandler(parser, startNamespace, endNamespace);\n    XML_SetCharacterDataHandler(parser, characterData);\n    XML_SetCommentHandler(parser, commentData);\n\n    ssize_t len;\n    bool done;\n    do {\n        len = read(fd, buf, sizeof(buf));\n        done = len < (ssize_t)sizeof(buf);\n        if (len < 0) {\n            SourcePos(file->getSourceFile(), -1).error(\"Error reading file: %s\\n\", strerror(errno));\n            close(fd);\n            return NULL;\n        }\n        if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) {\n            SourcePos(file->getSourceFile(), (int)XML_GetCurrentLineNumber(parser)).error(\n                    \"Error parsing XML: %s\\n\", XML_ErrorString(XML_GetErrorCode(parser)));\n            close(fd);\n            return NULL;\n        }\n    } while (!done);\n\n    XML_ParserFree(parser);\n    if (state.root == NULL) {\n        SourcePos(file->getSourceFile(), -1).error(\"No XML data generated when parsing\");\n    }\n    close(fd);\n    return state.root;\n}\n\nXMLNode::XMLNode()\n    : mNextAttributeIndex(0x80000000)\n    , mStartLineNumber(0)\n    , mEndLineNumber(0)\n    , mUTF8(false) {}\n\nXMLNode::XMLNode(const String8& filename, const String16& s1, const String16& s2, bool isNamespace)\n    : mNextAttributeIndex(0x80000000)\n    , mFilename(filename)\n    , mStartLineNumber(0)\n    , mEndLineNumber(0)\n    , mUTF8(false)\n{\n    if (isNamespace) {\n        mNamespacePrefix = s1;\n        mNamespaceUri = s2;\n    } else {\n        mNamespaceUri = s1;\n        mElementName = s2;\n    }\n}\n\nXMLNode::XMLNode(const String8& filename)\n    : mFilename(filename)\n{\n    memset(&mCharsValue, 0, sizeof(mCharsValue));\n}\n\nXMLNode::type XMLNode::getType() const\n{\n    if (mElementName.size() != 0) {\n        return TYPE_ELEMENT;\n    }\n    if (mNamespaceUri.size() != 0) {\n        return TYPE_NAMESPACE;\n    }\n    return TYPE_CDATA;\n}\n\nconst String16& XMLNode::getNamespacePrefix() const\n{\n    return mNamespacePrefix;\n}\n\nconst String16& XMLNode::getNamespaceUri() const\n{\n    return mNamespaceUri;\n}\n\nconst String16& XMLNode::getElementNamespace() const\n{\n    return mNamespaceUri;\n}\n\nconst String16& XMLNode::getElementName() const\n{\n    return mElementName;\n}\n\nconst Vector<sp<XMLNode> >& XMLNode::getChildren() const\n{\n    return mChildren;\n}\n\nconst String8& XMLNode::getFilename() const\n{\n    return mFilename;\n}\n    \nconst Vector<XMLNode::attribute_entry>&\n    XMLNode::getAttributes() const\n{\n    return mAttributes;\n}\n\nconst XMLNode::attribute_entry* XMLNode::getAttribute(const String16& ns,\n        const String16& name) const\n{\n    for (size_t i=0; i<mAttributes.size(); i++) {\n        const attribute_entry& ae(mAttributes.itemAt(i));\n        if (ae.ns == ns && ae.name == name) {\n            return &ae;\n        }\n    }\n    \n    return NULL;\n}\n\nXMLNode::attribute_entry* XMLNode::editAttribute(const String16& ns,\n        const String16& name)\n{\n    for (size_t i=0; i<mAttributes.size(); i++) {\n        attribute_entry * ae = &mAttributes.editItemAt(i);\n        if (ae->ns == ns && ae->name == name) {\n            return ae;\n        }\n    }\n\n    return NULL;\n}\n\nconst String16& XMLNode::getCData() const\n{\n    return mChars;\n}\n\nconst String16& XMLNode::getComment() const\n{\n    return mComment;\n}\n\nint32_t XMLNode::getStartLineNumber() const\n{\n    return mStartLineNumber;\n}\n\nint32_t XMLNode::getEndLineNumber() const\n{\n    return mEndLineNumber;\n}\n\nsp<XMLNode> XMLNode::searchElement(const String16& tagNamespace, const String16& tagName)\n{\n    if (getType() == XMLNode::TYPE_ELEMENT\n            && mNamespaceUri == tagNamespace\n            && mElementName == tagName) {\n        return this;\n    }\n    \n    for (size_t i=0; i<mChildren.size(); i++) {\n        sp<XMLNode> found = mChildren.itemAt(i)->searchElement(tagNamespace, tagName);\n        if (found != NULL) {\n            return found;\n        }\n    }\n    \n    return NULL;\n}\n\nsp<XMLNode> XMLNode::getChildElement(const String16& tagNamespace, const String16& tagName)\n{\n    for (size_t i=0; i<mChildren.size(); i++) {\n        sp<XMLNode> child = mChildren.itemAt(i);\n        if (child->getType() == XMLNode::TYPE_ELEMENT\n                && child->mNamespaceUri == tagNamespace\n                && child->mElementName == tagName) {\n            return child;\n        }\n    }\n    \n    return NULL;\n}\n\nstatus_t XMLNode::addChild(const sp<XMLNode>& child)\n{\n    if (getType() == TYPE_CDATA) {\n        SourcePos(mFilename, child->getStartLineNumber()).error(\"Child to CDATA node.\");\n        return UNKNOWN_ERROR;\n    }\n    //printf(\"Adding child %p to parent %p\\n\", child.get(), this);\n    mChildren.add(child);\n    return NO_ERROR;\n}\n\nstatus_t XMLNode::insertChildAt(const sp<XMLNode>& child, size_t index)\n{\n    if (getType() == TYPE_CDATA) {\n        SourcePos(mFilename, child->getStartLineNumber()).error(\"Child to CDATA node.\");\n        return UNKNOWN_ERROR;\n    }\n    //printf(\"Adding child %p to parent %p\\n\", child.get(), this);\n    mChildren.insertAt(child, index);\n    return NO_ERROR;\n}\n\nstatus_t XMLNode::addAttribute(const String16& ns, const String16& name,\n                               const String16& value)\n{\n    if (getType() == TYPE_CDATA) {\n        SourcePos(mFilename, getStartLineNumber()).error(\"Child to CDATA node.\");\n        return UNKNOWN_ERROR;\n    }\n\n    if (ns != RESOURCES_TOOLS_NAMESPACE) {\n        attribute_entry e;\n        e.index = mNextAttributeIndex++;\n        e.ns = ns;\n        e.name = name;\n        e.string = value;\n        mAttributes.add(e);\n        mAttributeOrder.add(e.index, mAttributes.size()-1);\n    }\n    return NO_ERROR;\n}\n\nstatus_t XMLNode::removeAttribute(size_t index)\n{\n    if (getType() == TYPE_CDATA) {\n        return UNKNOWN_ERROR;\n    }\n\n    if (index >= mAttributes.size()) {\n        return UNKNOWN_ERROR;\n    }\n\n    const attribute_entry& e = mAttributes[index];\n    const uint32_t key = e.nameResId ? e.nameResId : e.index;\n    mAttributeOrder.removeItem(key);\n    mAttributes.removeAt(index);\n\n    // Shift all the indices.\n    const size_t attrCount = mAttributeOrder.size();\n    for (size_t i = 0; i < attrCount; i++) {\n        size_t attrIdx = mAttributeOrder[i];\n        if (attrIdx > index) {\n            mAttributeOrder.replaceValueAt(i, attrIdx - 1);\n        }\n    }\n    return NO_ERROR;\n}\n\nvoid XMLNode::setAttributeResID(size_t attrIdx, uint32_t resId)\n{\n    attribute_entry& e = mAttributes.editItemAt(attrIdx);\n    if (e.nameResId) {\n        mAttributeOrder.removeItem(e.nameResId);\n    } else {\n        mAttributeOrder.removeItem(e.index);\n    }\n    NOISY(printf(\"Elem %s %s=\\\"%s\\\": set res id = 0x%08x\\n\",\n            String8(getElementName()).string(),\n            String8(mAttributes.itemAt(attrIdx).name).string(),\n            String8(mAttributes.itemAt(attrIdx).string).string(),\n            resId));\n    mAttributes.editItemAt(attrIdx).nameResId = resId;\n    mAttributeOrder.add(resId, attrIdx);\n}\n\nstatus_t XMLNode::appendChars(const String16& chars)\n{\n    if (getType() != TYPE_CDATA) {\n        SourcePos(mFilename, getStartLineNumber()).error(\"Adding characters to element node.\");\n        return UNKNOWN_ERROR;\n    }\n    mChars.append(chars);\n    return NO_ERROR;\n}\n\nstatus_t XMLNode::appendComment(const String16& comment)\n{\n    if (mComment.size() > 0) {\n        mComment.append(String16(\"\\n\"));\n    }\n    mComment.append(comment);\n    return NO_ERROR;\n}\n\nvoid XMLNode::setStartLineNumber(int32_t line)\n{\n    mStartLineNumber = line;\n}\n\nvoid XMLNode::setEndLineNumber(int32_t line)\n{\n    mEndLineNumber = line;\n}\n\nvoid XMLNode::removeWhitespace(bool stripAll, const char** cDataTags)\n{\n    //printf(\"Removing whitespace in %s\\n\", String8(mElementName).string());\n    size_t N = mChildren.size();\n    if (cDataTags) {\n        String8 tag(mElementName);\n        const char** p = cDataTags;\n        while (*p) {\n            if (tag == *p) {\n                stripAll = false;\n                break;\n            }\n        }\n    }\n    for (size_t i=0; i<N; i++) {\n        sp<XMLNode> node = mChildren.itemAt(i);\n        if (node->getType() == TYPE_CDATA) {\n            // This is a CDATA node...\n            const char16_t* p = node->mChars.string();\n            while (*p != 0 && *p < 128 && isspace(*p)) {\n                p++;\n            }\n            //printf(\"Space ends at %d in \\\"%s\\\"\\n\",\n            //       (int)(p-node->mChars.string()),\n            //       String8(node->mChars).string());\n            if (*p == 0) {\n                if (stripAll) {\n                    // Remove this node!\n                    mChildren.removeAt(i);\n                    N--;\n                    i--;\n                } else {\n                    node->mChars = String16(\" \");\n                }\n            } else {\n                // Compact leading/trailing whitespace.\n                const char16_t* e = node->mChars.string()+node->mChars.size()-1;\n                while (e > p && *e < 128 && isspace(*e)) {\n                    e--;\n                }\n                if (p > node->mChars.string()) {\n                    p--;\n                }\n                if (e < (node->mChars.string()+node->mChars.size()-1)) {\n                    e++;\n                }\n                if (p > node->mChars.string() ||\n                    e < (node->mChars.string()+node->mChars.size()-1)) {\n                    String16 tmp(p, e-p+1);\n                    node->mChars = tmp;\n                }\n            }\n        } else {\n            node->removeWhitespace(stripAll, cDataTags);\n        }\n    }\n}\n\nstatus_t XMLNode::parseValues(const sp<AaptAssets>& assets,\n                              ResourceTable* table, const Bundle *bundle)\n{\n    bool hasErrors = false;\n    \n    if (getType() == TYPE_ELEMENT) {\n        const size_t N = mAttributes.size();\n        String16 defPackage(assets->getPackage());\n        for (size_t i=0; i<N; i++) {\n            attribute_entry& e = mAttributes.editItemAt(i);\n            AccessorCookie ac(SourcePos(mFilename, getStartLineNumber()), String8(e.name),\n                    String8(e.string));\n            table->setCurrentXmlPos(SourcePos(mFilename, getStartLineNumber()));\n            bool failGetFromDefaultPackage = false;\n            if (!assets->getIncludedResources()\n                    .stringToValue(&e.value, &e.string,\n                                  e.string.string(), e.string.size(), true, true,\n                                  e.nameResId, NULL, &defPackage, table, &ac, \n                                  ResTable_map::TYPE_ANY, true, sktPackageName == NULL)) {\n                failGetFromDefaultPackage = true;\n            }\n            if (failGetFromDefaultPackage && (sktPackageName != NULL)){\n                String16 defPackage = String16(sktPackageName);\n                if (!assets->getIncludedResources().stringToValue(&e.value, &e.string,\n                     e.string.string(), e.string.size(), true, true, e.nameResId, \n                     NULL, &defPackage, table, &ac, ResTable_map::TYPE_ANY, false, true)) {\n                     hasErrors = true;\n                }\n            } else if (failGetFromDefaultPackage){\n                hasErrors = true;\n            }\n\n            NOISY(printf(\"Attr %s: type=0x%x, str=%s\\n\",\n                   String8(e.name).string(), e.value.dataType,\n                   String8(e.string).string()));\n        }\n    }\n    const size_t N = mChildren.size();\n    for (size_t i=0; i<N; i++) {\n        status_t err = mChildren.itemAt(i)->parseValues(assets, table, bundle);\n        if (err != NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;\n}\n\nstatus_t XMLNode::assignResourceIds(const sp<AaptAssets>& assets,\n                                    const ResourceTable* table,\n                                    const Bundle* bundle)\n{\n    bool hasErrors = false;\n    \n    if (getType() == TYPE_ELEMENT) {\n        String16 attr(\"attr\");\n        const char* errorMsg;\n        const size_t N = mAttributes.size();\n        for (size_t i=0; i<N; i++) {\n            const attribute_entry& e = mAttributes.itemAt(i);\n            if (e.ns.size() <= 0) continue;\n            bool nsIsPublic;\n            String16 pkg(getNamespaceResourcePackage(String16(assets->getPackage()), e.ns, &nsIsPublic));\n            NOISY(printf(\"Elem %s %s=\\\"%s\\\": namespace(%s) %s ===> %s\\n\",\n                    String8(getElementName()).string(),\n                    String8(e.name).string(),\n                    String8(e.string).string(),\n                    String8(e.ns).string(),\n                    (nsIsPublic) ? \"public\" : \"private\",\n                    String8(pkg).string()));\n            if (pkg.size() <= 0) continue;\n            uint32_t res = table != NULL\n                ? table->getResId(e.name, &attr, &pkg, &errorMsg, nsIsPublic)\n                : assets->getIncludedResources().\n                    identifierForName(e.name.string(), e.name.size(),\n                                      attr.string(), attr.size(),\n                                      pkg.string(), pkg.size());\n            if (res == 0){\n                if (sktPackageName != NULL){\n                    String16 defPackage = String16(sktPackageName);\n                    res = table != NULL ? table->getResId(e.name, &attr, &defPackage, &errorMsg, false) : 0;\n                }\n            }\n            if (res != 0) {\n                NOISY(printf(\"XML attribute name %s: resid=0x%08x\\n\",\n                             String8(e.name).string(), res));\n                setAttributeResID(i, res);\n            } else {\n                SourcePos(mFilename, getStartLineNumber()).error(\n                        \"No resource identifier found for attribute '%s' in package '%s'\\n\",\n                        String8(e.name).string(), String8(pkg).string());\n                hasErrors = true;\n            }\n        }\n    }\n    const size_t N = mChildren.size();\n    for (size_t i=0; i<N; i++) {\n        status_t err = mChildren.itemAt(i)->assignResourceIds(assets, table, bundle);\n        if (err < NO_ERROR) {\n            hasErrors = true;\n        }\n    }\n\n    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;\n}\n\nsp<XMLNode> XMLNode::clone() const {\n    sp<XMLNode> copy = new XMLNode();\n    copy->mNamespacePrefix = mNamespacePrefix;\n    copy->mNamespaceUri = mNamespaceUri;\n    copy->mElementName = mElementName;\n\n    const size_t childCount = mChildren.size();\n    for (size_t i = 0; i < childCount; i++) {\n        copy->mChildren.add(mChildren[i]->clone());\n    }\n\n    copy->mAttributes = mAttributes;\n    copy->mAttributeOrder = mAttributeOrder;\n    copy->mNextAttributeIndex = mNextAttributeIndex;\n    copy->mChars = mChars;\n    memcpy(&copy->mCharsValue, &mCharsValue, sizeof(mCharsValue));\n    copy->mComment = mComment;\n    copy->mFilename = mFilename;\n    copy->mStartLineNumber = mStartLineNumber;\n    copy->mEndLineNumber = mEndLineNumber;\n    copy->mUTF8 = mUTF8;\n    return copy;\n}\n\nstatus_t XMLNode::flatten(const sp<AaptFile>& dest,\n        bool stripComments, bool stripRawValues) const\n{\n    StringPool strings(mUTF8);\n    Vector<uint32_t> resids;\n    \n    // First collect just the strings for attribute names that have a\n    // resource ID assigned to them.  This ensures that the resource ID\n    // array is compact, and makes it easier to deal with attribute names\n    // in different namespaces (and thus with different resource IDs).\n    collect_resid_strings(&strings, &resids);\n\n    // Next collect all remainibng strings.\n    collect_strings(&strings, &resids, stripComments, stripRawValues);\n\n#if 0  // No longer compiles\n    NOISY(printf(\"Found strings:\\n\");\n        const size_t N = strings.size();\n        for (size_t i=0; i<N; i++) {\n            printf(\"%s\\n\", String8(strings.entryAt(i).string).string());\n        }\n    );\n#endif    \n\n    sp<AaptFile> stringPool = strings.createStringBlock();\n    NOISY(aout << \"String pool:\"\n          << HexDump(stringPool->getData(), stringPool->getSize()) << endl);\n\n    ResXMLTree_header header;\n    memset(&header, 0, sizeof(header));\n    header.header.type = htods(RES_XML_TYPE);\n    header.header.headerSize = htods(sizeof(header));\n\n    const size_t basePos = dest->getSize();\n    dest->writeData(&header, sizeof(header));\n    dest->writeData(stringPool->getData(), stringPool->getSize());\n\n    // If we have resource IDs, write them.\n    if (resids.size() > 0) {\n        const size_t resIdsPos = dest->getSize();\n        const size_t resIdsSize =\n            sizeof(ResChunk_header)+(sizeof(uint32_t)*resids.size());\n        ResChunk_header* idsHeader = (ResChunk_header*)\n            (((const uint8_t*)dest->editData(resIdsPos+resIdsSize))+resIdsPos);\n        idsHeader->type = htods(RES_XML_RESOURCE_MAP_TYPE);\n        idsHeader->headerSize = htods(sizeof(*idsHeader));\n        idsHeader->size = htodl(resIdsSize);\n        uint32_t* ids = (uint32_t*)(idsHeader+1);\n        for (size_t i=0; i<resids.size(); i++) {\n            *ids++ = htodl(resids[i]);\n        }\n    }\n\n    flatten_node(strings, dest, stripComments, stripRawValues);\n\n    void* data = dest->editData();\n    ResXMLTree_header* hd = (ResXMLTree_header*)(((uint8_t*)data)+basePos);\n    size_t size = dest->getSize()-basePos;\n    hd->header.size = htodl(dest->getSize()-basePos);\n\n    NOISY(aout << \"XML resource:\"\n          << HexDump(dest->getData(), dest->getSize()) << endl);\n\n    #if PRINT_STRING_METRICS\n    fprintf(stderr, \"**** total xml size: %d / %d%% strings (in %s)\\n\",\n        dest->getSize(), (stringPool->getSize()*100)/dest->getSize(),\n        dest->getPath().string());\n    #endif\n        \n    return NO_ERROR;\n}\n\nvoid XMLNode::print(int indent)\n{\n    String8 prefix;\n    int i;\n    for (i=0; i<indent; i++) {\n        prefix.append(\"  \");\n    }\n    if (getType() == TYPE_ELEMENT) {\n        String8 elemNs(getNamespaceUri());\n        if (elemNs.size() > 0) {\n            elemNs.append(\":\");\n        }\n        printf(\"%s E: %s%s\", prefix.string(),\n               elemNs.string(), String8(getElementName()).string());\n        int N = mAttributes.size();\n        for (i=0; i<N; i++) {\n            ssize_t idx = mAttributeOrder.valueAt(i);\n            if (i == 0) {\n                printf(\" / \");\n            } else {\n                printf(\", \");\n            }\n            const attribute_entry& attr = mAttributes.itemAt(idx);\n            String8 attrNs(attr.ns);\n            if (attrNs.size() > 0) {\n                attrNs.append(\":\");\n            }\n            if (attr.nameResId) {\n                printf(\"%s%s(0x%08x)\", attrNs.string(),\n                       String8(attr.name).string(), attr.nameResId);\n            } else {\n                printf(\"%s%s\", attrNs.string(), String8(attr.name).string());\n            }\n            printf(\"=%s\", String8(attr.string).string());\n        }\n        printf(\"\\n\");\n    } else if (getType() == TYPE_NAMESPACE) {\n        printf(\"%s N: %s=%s\\n\", prefix.string(),\n               getNamespacePrefix().size() > 0\n                    ? String8(getNamespacePrefix()).string() : \"<DEF>\",\n               String8(getNamespaceUri()).string());\n    } else {\n        printf(\"%s C: \\\"%s\\\"\\n\", prefix.string(), String8(getCData()).string());\n    }\n    int N = mChildren.size();\n    for (i=0; i<N; i++) {\n        mChildren.itemAt(i)->print(indent+1);\n    }\n}\n\nstatic void splitName(const char* name, String16* outNs, String16* outName)\n{\n    const char* p = name;\n    while (*p != 0 && *p != 1) {\n        p++;\n    }\n    if (*p == 0) {\n        *outNs = String16();\n        *outName = String16(name);\n    } else {\n        *outNs = String16(name, (p-name));\n        *outName = String16(p+1);\n    }\n}\n\nvoid XMLCALL\nXMLNode::startNamespace(void *userData, const char *prefix, const char *uri)\n{\n    NOISY_PARSE(printf(\"Start Namespace: %s %s\\n\", prefix, uri));\n    ParseState* st = (ParseState*)userData;\n    sp<XMLNode> node = XMLNode::newNamespace(st->filename, \n            String16(prefix != NULL ? prefix : \"\"), String16(uri));\n    node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser));\n    if (st->stack.size() > 0) {\n        st->stack.itemAt(st->stack.size()-1)->addChild(node);\n    } else {\n        st->root = node;\n    }\n    st->stack.push(node);\n}\n\nvoid XMLCALL\nXMLNode::startElement(void *userData, const char *name, const char **atts)\n{\n    NOISY_PARSE(printf(\"Start Element: %s\\n\", name));\n    ParseState* st = (ParseState*)userData;\n    String16 ns16, name16;\n    splitName(name, &ns16, &name16);\n    sp<XMLNode> node = XMLNode::newElement(st->filename, ns16, name16);\n    node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser));\n    if (st->pendingComment.size() > 0) {\n        node->appendComment(st->pendingComment);\n        st->pendingComment = String16();\n    }\n    if (st->stack.size() > 0) {\n        st->stack.itemAt(st->stack.size()-1)->addChild(node);\n    } else {\n        st->root = node;\n    }\n    st->stack.push(node);\n\n    for (int i = 0; atts[i]; i += 2) {\n        splitName(atts[i], &ns16, &name16);\n        node->addAttribute(ns16, name16, String16(atts[i+1]));\n    }\n}\n\nvoid XMLCALL\nXMLNode::characterData(void *userData, const XML_Char *s, int len)\n{\n    NOISY_PARSE(printf(\"CDATA: \\\"%s\\\"\\n\", String8(s, len).string()));\n    ParseState* st = (ParseState*)userData;\n    sp<XMLNode> node = NULL;\n    if (st->stack.size() == 0) {\n        return;\n    }\n    sp<XMLNode> parent = st->stack.itemAt(st->stack.size()-1);\n    if (parent != NULL && parent->getChildren().size() > 0) {\n        node = parent->getChildren()[parent->getChildren().size()-1];\n        if (node->getType() != TYPE_CDATA) {\n            // Last node is not CDATA, need to make a new node.\n            node = NULL;\n        }\n    }\n\n    if (node == NULL) {\n        node = XMLNode::newCData(st->filename);\n        node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser));\n        parent->addChild(node);\n    }\n\n    node->appendChars(String16(s, len));\n}\n\nvoid XMLCALL\nXMLNode::endElement(void *userData, const char *name)\n{\n    NOISY_PARSE(printf(\"End Element: %s\\n\", name));\n    ParseState* st = (ParseState*)userData;\n    sp<XMLNode> node = st->stack.itemAt(st->stack.size()-1);\n    node->setEndLineNumber(XML_GetCurrentLineNumber(st->parser));\n    if (st->pendingComment.size() > 0) {\n        node->appendComment(st->pendingComment);\n        st->pendingComment = String16();\n    }\n    String16 ns16, name16;\n    splitName(name, &ns16, &name16);\n    LOG_ALWAYS_FATAL_IF(node->getElementNamespace() != ns16\n                        || node->getElementName() != name16,\n                        \"Bad end element %s\", name);\n    st->stack.pop();\n}\n\nvoid XMLCALL\nXMLNode::endNamespace(void *userData, const char *prefix)\n{\n    const char* nonNullPrefix = prefix != NULL ? prefix : \"\";\n    NOISY_PARSE(printf(\"End Namespace: %s\\n\", prefix));\n    ParseState* st = (ParseState*)userData;\n    sp<XMLNode> node = st->stack.itemAt(st->stack.size()-1);\n    node->setEndLineNumber(XML_GetCurrentLineNumber(st->parser));\n    LOG_ALWAYS_FATAL_IF(node->getNamespacePrefix() != String16(nonNullPrefix),\n                        \"Bad end namespace %s\", prefix);\n    st->stack.pop();\n}\n\nvoid XMLCALL\nXMLNode::commentData(void *userData, const char *comment)\n{\n    NOISY_PARSE(printf(\"Comment: %s\\n\", comment));\n    ParseState* st = (ParseState*)userData;\n    if (st->pendingComment.size() > 0) {\n        st->pendingComment.append(String16(\"\\n\"));\n    }\n    st->pendingComment.append(String16(comment));\n}\n\nstatus_t XMLNode::collect_strings(StringPool* dest, Vector<uint32_t>* outResIds,\n        bool stripComments, bool stripRawValues) const\n{\n    collect_attr_strings(dest, outResIds, true);\n    \n    int i;\n    if (RESOURCES_TOOLS_NAMESPACE != mNamespaceUri) {\n        if (mNamespacePrefix.size() > 0) {\n            dest->add(mNamespacePrefix, true);\n        }\n        if (mNamespaceUri.size() > 0) {\n            dest->add(mNamespaceUri, true);\n        }\n    }\n    if (mElementName.size() > 0) {\n        dest->add(mElementName, true);\n    }\n\n    if (!stripComments && mComment.size() > 0) {\n        dest->add(mComment, true);\n    }\n\n    const int NA = mAttributes.size();\n\n    for (i=0; i<NA; i++) {\n        const attribute_entry& ae = mAttributes.itemAt(i);\n        if (ae.ns.size() > 0) {\n            dest->add(ae.ns, true);\n        }\n        if (!stripRawValues || ae.needStringValue()) {\n            dest->add(ae.string, true);\n        }\n        /*\n        if (ae.value.dataType == Res_value::TYPE_NULL\n                || ae.value.dataType == Res_value::TYPE_STRING) {\n            dest->add(ae.string, true);\n        }\n        */\n    }\n\n    if (mElementName.size() == 0) {\n        // If not an element, include the CDATA, even if it is empty.\n        dest->add(mChars, true);\n    }\n\n    const int NC = mChildren.size();\n\n    for (i=0; i<NC; i++) {\n        mChildren.itemAt(i)->collect_strings(dest, outResIds,\n                stripComments, stripRawValues);\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t XMLNode::collect_attr_strings(StringPool* outPool,\n        Vector<uint32_t>* outResIds, bool allAttrs) const {\n    const int NA = mAttributes.size();\n\n    for (int i=0; i<NA; i++) {\n        const attribute_entry& attr = mAttributes.itemAt(i);\n        uint32_t id = attr.nameResId;\n        if (id || allAttrs) {\n            // See if we have already assigned this resource ID to a pooled\n            // string...\n            const Vector<size_t>* indices = outPool->offsetsForString(attr.name);\n            ssize_t idx = -1;\n            if (indices != NULL) {\n                const int NJ = indices->size();\n                const size_t NR = outResIds->size();\n                for (int j=0; j<NJ; j++) {\n                    size_t strIdx = indices->itemAt(j);\n                    if (strIdx >= NR) {\n                        if (id == 0) {\n                            // We don't need to assign a resource ID for this one.\n                            idx = strIdx;\n                            break;\n                        }\n                        // Just ignore strings that are out of range of\n                        // the currently assigned resource IDs...  we add\n                        // strings as we assign the first ID.\n                    } else if (outResIds->itemAt(strIdx) == id) {\n                        idx = strIdx;\n                        break;\n                    }\n                }\n            }\n            if (idx < 0) {\n                idx = outPool->add(attr.name);\n                NOISY(printf(\"Adding attr %s (resid 0x%08x) to pool: idx=%d\\n\",\n                        String8(attr.name).string(), id, idx));\n                if (id != 0) {\n                    while ((ssize_t)outResIds->size() <= idx) {\n                        outResIds->add(0);\n                    }\n                    outResIds->replaceAt(id, idx);\n                }\n            }\n            attr.namePoolIdx = idx;\n            NOISY(printf(\"String %s offset=0x%08x\\n\",\n                         String8(attr.name).string(), idx));\n        }\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t XMLNode::collect_resid_strings(StringPool* outPool,\n        Vector<uint32_t>* outResIds) const\n{\n    collect_attr_strings(outPool, outResIds, false);\n\n    const int NC = mChildren.size();\n\n    for (int i=0; i<NC; i++) {\n        mChildren.itemAt(i)->collect_resid_strings(outPool, outResIds);\n    }\n\n    return NO_ERROR;\n}\n\nstatus_t XMLNode::flatten_node(const StringPool& strings, const sp<AaptFile>& dest,\n        bool stripComments, bool stripRawValues) const\n{\n    ResXMLTree_node node;\n    ResXMLTree_cdataExt cdataExt;\n    ResXMLTree_namespaceExt namespaceExt;\n    ResXMLTree_attrExt attrExt;\n    const void* extData = NULL;\n    size_t extSize = 0;\n    ResXMLTree_attribute attr;\n    bool writeCurrentNode = true;\n\n    const size_t NA = mAttributes.size();\n    const size_t NC = mChildren.size();\n    size_t i;\n\n    LOG_ALWAYS_FATAL_IF(NA != mAttributeOrder.size(), \"Attributes messed up!\");\n\n    const String16 id16(\"id\");\n    const String16 class16(\"class\");\n    const String16 style16(\"style\");\n\n    const type type = getType();\n\n    memset(&node, 0, sizeof(node));\n    memset(&attr, 0, sizeof(attr));\n    node.header.headerSize = htods(sizeof(node));\n    node.lineNumber = htodl(getStartLineNumber());\n    if (!stripComments) {\n        node.comment.index = htodl(\n            mComment.size() > 0 ? strings.offsetForString(mComment) : -1);\n        //if (mComment.size() > 0) {\n        //  printf(\"Flattening comment: %s\\n\", String8(mComment).string());\n        //}\n    } else {\n        node.comment.index = htodl((uint32_t)-1);\n    }\n    if (type == TYPE_ELEMENT) {\n        node.header.type = htods(RES_XML_START_ELEMENT_TYPE);\n        extData = &attrExt;\n        extSize = sizeof(attrExt);\n        memset(&attrExt, 0, sizeof(attrExt));\n        if (mNamespaceUri.size() > 0) {\n            attrExt.ns.index = htodl(strings.offsetForString(mNamespaceUri));\n        } else {\n            attrExt.ns.index = htodl((uint32_t)-1);\n        }\n        attrExt.name.index = htodl(strings.offsetForString(mElementName));\n        attrExt.attributeStart = htods(sizeof(attrExt));\n        attrExt.attributeSize = htods(sizeof(attr));\n        attrExt.attributeCount = htods(NA);\n        attrExt.idIndex = htods(0);\n        attrExt.classIndex = htods(0);\n        attrExt.styleIndex = htods(0);\n        for (i=0; i<NA; i++) {\n            ssize_t idx = mAttributeOrder.valueAt(i);\n            const attribute_entry& ae = mAttributes.itemAt(idx);\n            if (ae.ns.size() == 0) {\n                if (ae.name == id16) {\n                    attrExt.idIndex = htods(i+1);\n                } else if (ae.name == class16) {\n                    attrExt.classIndex = htods(i+1);\n                } else if (ae.name == style16) {\n                    attrExt.styleIndex = htods(i+1);\n                }\n            }\n        }\n    } else if (type == TYPE_NAMESPACE) {\n        if (mNamespaceUri == RESOURCES_TOOLS_NAMESPACE) {\n            writeCurrentNode = false;\n        } else {\n            node.header.type = htods(RES_XML_START_NAMESPACE_TYPE);\n            extData = &namespaceExt;\n            extSize = sizeof(namespaceExt);\n            memset(&namespaceExt, 0, sizeof(namespaceExt));\n            if (mNamespacePrefix.size() > 0) {\n                namespaceExt.prefix.index = htodl(strings.offsetForString(mNamespacePrefix));\n            } else {\n                namespaceExt.prefix.index = htodl((uint32_t)-1);\n            }\n            namespaceExt.prefix.index = htodl(strings.offsetForString(mNamespacePrefix));\n            namespaceExt.uri.index = htodl(strings.offsetForString(mNamespaceUri));\n        }\n        LOG_ALWAYS_FATAL_IF(NA != 0, \"Namespace nodes can't have attributes!\");\n    } else if (type == TYPE_CDATA) {\n        node.header.type = htods(RES_XML_CDATA_TYPE);\n        extData = &cdataExt;\n        extSize = sizeof(cdataExt);\n        memset(&cdataExt, 0, sizeof(cdataExt));\n        cdataExt.data.index = htodl(strings.offsetForString(mChars));\n        cdataExt.typedData.size = htods(sizeof(cdataExt.typedData));\n        cdataExt.typedData.res0 = 0;\n        cdataExt.typedData.dataType = mCharsValue.dataType;\n        cdataExt.typedData.data = htodl(mCharsValue.data);\n        LOG_ALWAYS_FATAL_IF(NA != 0, \"CDATA nodes can't have attributes!\");\n    }\n\n    node.header.size = htodl(sizeof(node) + extSize + (sizeof(attr)*NA));\n\n    if (writeCurrentNode) {\n        dest->writeData(&node, sizeof(node));\n        if (extSize > 0) {\n            dest->writeData(extData, extSize);\n        }\n    }\n\n    for (i=0; i<NA; i++) {\n        ssize_t idx = mAttributeOrder.valueAt(i);\n        const attribute_entry& ae = mAttributes.itemAt(idx);\n        if (ae.ns.size() > 0) {\n            attr.ns.index = htodl(strings.offsetForString(ae.ns));\n        } else {\n            attr.ns.index = htodl((uint32_t)-1);\n        }\n        attr.name.index = htodl(ae.namePoolIdx);\n\n        if (!stripRawValues || ae.needStringValue()) {\n            attr.rawValue.index = htodl(strings.offsetForString(ae.string));\n        } else {\n            attr.rawValue.index = htodl((uint32_t)-1);\n        }\n        attr.typedValue.size = htods(sizeof(attr.typedValue));\n        if (ae.value.dataType == Res_value::TYPE_NULL\n                || ae.value.dataType == Res_value::TYPE_STRING) {\n            attr.typedValue.res0 = 0;\n            attr.typedValue.dataType = Res_value::TYPE_STRING;\n            attr.typedValue.data = htodl(strings.offsetForString(ae.string));\n        } else {\n            attr.typedValue.res0 = 0;\n            attr.typedValue.dataType = ae.value.dataType;\n            attr.typedValue.data = htodl(ae.value.data);\n        }\n        dest->writeData(&attr, sizeof(attr));\n    }\n\n    for (i=0; i<NC; i++) {\n        status_t err = mChildren.itemAt(i)->flatten_node(strings, dest,\n                stripComments, stripRawValues);\n        if (err != NO_ERROR) {\n            return err;\n        }\n    }\n\n    if (type == TYPE_ELEMENT) {\n        ResXMLTree_endElementExt endElementExt;\n        memset(&endElementExt, 0, sizeof(endElementExt));\n        node.header.type = htods(RES_XML_END_ELEMENT_TYPE);\n        node.header.size = htodl(sizeof(node)+sizeof(endElementExt));\n        node.lineNumber = htodl(getEndLineNumber());\n        node.comment.index = htodl((uint32_t)-1);\n        endElementExt.ns.index = attrExt.ns.index;\n        endElementExt.name.index = attrExt.name.index;\n        dest->writeData(&node, sizeof(node));\n        dest->writeData(&endElementExt, sizeof(endElementExt));\n    } else if (type == TYPE_NAMESPACE) {\n        if (writeCurrentNode) {\n            node.header.type = htods(RES_XML_END_NAMESPACE_TYPE);\n            node.lineNumber = htodl(getEndLineNumber());\n            node.comment.index = htodl((uint32_t)-1);\n            node.header.size = htodl(sizeof(node)+extSize);\n            dest->writeData(&node, sizeof(node));\n            dest->writeData(extData, extSize);\n        }\n    }\n\n    return NO_ERROR;\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/XMLNode.h",
    "content": "//\n// Copyright 2006 The Android Open Source Project\n//\n// Build resource files from raw assets.\n//\n\n#ifndef XML_NODE_H\n#define XML_NODE_H\n\n#include \"StringPool.h\"\n#include \"ResourceTable.h\"\n\nclass XMLNode;\n\nextern const char* const RESOURCES_ROOT_NAMESPACE;\nextern const char* const RESOURCES_ANDROID_NAMESPACE;\n\nbool isWhitespace(const char16_t* str);\n\nString16 getNamespaceResourcePackage(String16 namespaceUri, bool* outIsPublic = NULL);\n\nstatus_t parseStyledString(Bundle* bundle,\n                           const char* fileName,\n                           ResXMLTree* inXml,\n                           const String16& endTag,\n                           String16* outString,\n                           Vector<StringPool::entry_style_span>* outSpans,\n                           bool isFormatted,\n                           PseudolocalizationMethod isPseudolocalizable);\n\nvoid printXMLBlock(ResXMLTree* block);\n\nstatus_t parseXMLResource(const sp<AaptFile>& file, ResXMLTree* outTree,\n                          bool stripAll=true, bool keepComments=false,\n                          const char** cDataTags=NULL);\n\nclass XMLNode : public RefBase\n{\npublic:\n    static sp<XMLNode> parse(const sp<AaptFile>& file);\n\n    static inline\n    sp<XMLNode> newNamespace(const String8& filename, const String16& prefix, const String16& uri) {\n        return new XMLNode(filename, prefix, uri, true);\n    }\n    \n    static inline\n    sp<XMLNode> newElement(const String8& filename, const String16& ns, const String16& name) {\n        return new XMLNode(filename, ns, name, false);\n    }\n    \n    static inline\n    sp<XMLNode> newCData(const String8& filename) {\n        return new XMLNode(filename);\n    }\n    \n    enum type {\n        TYPE_NAMESPACE,\n        TYPE_ELEMENT,\n        TYPE_CDATA\n    };\n    \n    type getType() const;\n    \n    const String16& getNamespacePrefix() const;\n    const String16& getNamespaceUri() const;\n    \n    const String16& getElementNamespace() const;\n    const String16& getElementName() const;\n    const Vector<sp<XMLNode> >& getChildren() const;\n\n    const String8& getFilename() const;\n    \n    struct attribute_entry {\n        attribute_entry() : index(~(uint32_t)0), nameResId(0)\n        {\n            value.dataType = Res_value::TYPE_NULL;\n        }\n\n        bool needStringValue() const {\n            return nameResId == 0\n                || value.dataType == Res_value::TYPE_NULL\n                || value.dataType == Res_value::TYPE_STRING;\n        }\n        \n        String16 ns;\n        String16 name;\n        String16 string;\n        Res_value value;\n        uint32_t index;\n        uint32_t nameResId;\n        mutable uint32_t namePoolIdx;\n    };\n\n    const Vector<attribute_entry>& getAttributes() const;\n\n    const attribute_entry* getAttribute(const String16& ns, const String16& name) const;\n    \n    attribute_entry* editAttribute(const String16& ns, const String16& name);\n\n    const String16& getCData() const;\n\n    const String16& getComment() const;\n\n    int32_t getStartLineNumber() const;\n    int32_t getEndLineNumber() const;\n\n    sp<XMLNode> searchElement(const String16& tagNamespace, const String16& tagName);\n    \n    sp<XMLNode> getChildElement(const String16& tagNamespace, const String16& tagName);\n    \n    status_t addChild(const sp<XMLNode>& child);\n\n    status_t insertChildAt(const sp<XMLNode>& child, size_t index);\n\n    status_t addAttribute(const String16& ns, const String16& name,\n                          const String16& value);\n\n    status_t removeAttribute(size_t index);\n\n    void setAttributeResID(size_t attrIdx, uint32_t resId);\n\n    status_t appendChars(const String16& chars);\n\n    status_t appendComment(const String16& comment);\n\n    void setStartLineNumber(int32_t line);\n    void setEndLineNumber(int32_t line);\n\n    void removeWhitespace(bool stripAll=true, const char** cDataTags=NULL);\n\n    void setUTF8(bool val) { mUTF8 = val; }\n\n    status_t parseValues(const sp<AaptAssets>& assets, ResourceTable* table, const Bundle *bundle);\n\n    status_t assignResourceIds(const sp<AaptAssets>& assets,\n                               const ResourceTable* table = NULL,\n                               const Bundle *bundle = NULL);\n\n    status_t flatten(const sp<AaptFile>& dest, bool stripComments,\n            bool stripRawValues) const;\n\n    sp<XMLNode> clone() const;\n\n    void print(int indent=0);\n\nprivate:\n    struct ParseState\n    {\n        String8 filename;\n        XML_Parser parser;\n        sp<XMLNode> root;\n        Vector<sp<XMLNode> > stack;\n        String16 pendingComment;\n    };\n\n    static void XMLCALL\n    startNamespace(void *userData, const char *prefix, const char *uri);\n    static void XMLCALL\n    startElement(void *userData, const char *name, const char **atts);\n    static void XMLCALL\n    characterData(void *userData, const XML_Char *s, int len);\n    static void XMLCALL\n    endElement(void *userData, const char *name);\n    static void XMLCALL\n    endNamespace(void *userData, const char *prefix);\n    \n    static void XMLCALL\n    commentData(void *userData, const char *comment);\n    \n    // For cloning\n    XMLNode();\n\n    // Creating an element node.\n    XMLNode(const String8& filename, const String16& s1, const String16& s2, bool isNamespace);\n    \n    // Creating a CDATA node.\n    XMLNode(const String8& filename);\n    \n    status_t collect_strings(StringPool* dest, Vector<uint32_t>* outResIds,\n            bool stripComments, bool stripRawValues) const;\n\n    status_t collect_attr_strings(StringPool* outPool,\n        Vector<uint32_t>* outResIds, bool allAttrs) const;\n        \n    status_t collect_resid_strings(StringPool* outPool,\n            Vector<uint32_t>* outResIds) const;\n\n    status_t flatten_node(const StringPool& strings, const sp<AaptFile>& dest,\n            bool stripComments, bool stripRawValues) const;\n\n    String16 mNamespacePrefix;\n    String16 mNamespaceUri;\n    String16 mElementName;\n    Vector<sp<XMLNode> > mChildren;\n    Vector<attribute_entry> mAttributes;\n    KeyedVector<uint32_t, uint32_t> mAttributeOrder;\n    uint32_t mNextAttributeIndex;\n    String16 mChars;\n    Res_value mCharsValue;\n    String16 mComment;\n    String8 mFilename;\n    int32_t mStartLineNumber;\n    int32_t mEndLineNumber;\n\n    // Encode compiled XML with UTF-8 StringPools?\n    bool mUTF8;\n};\n\n#endif\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/ZipEntry.cpp",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Access to entries in a Zip archive.\n//\n\n#define LOG_TAG \"zip\"\n\n#include \"ZipEntry.h\"\n#include <utils/Log.h>\n\n#include <stdio.h>\n#include <string.h>\n#include <assert.h>\n\nusing namespace android;\n\n/*\n * Initialize a new ZipEntry structure from a FILE* positioned at a\n * CentralDirectoryEntry.\n *\n * On exit, the file pointer will be at the start of the next CDE or\n * at the EOCD.\n */\nstatus_t ZipEntry::initFromCDE(FILE* fp)\n{\n    status_t result;\n    long posn;\n    bool hasDD;\n\n    //ALOGV(\"initFromCDE ---\\n\");\n\n    /* read the CDE */\n    result = mCDE.read(fp);\n    if (result != NO_ERROR) {\n        ALOGD(\"mCDE.read failed\\n\");\n        return result;\n    }\n\n    //mCDE.dump();\n\n    /* using the info in the CDE, go load up the LFH */\n    posn = ftell(fp);\n    if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {\n        ALOGD(\"local header seek failed (%ld)\\n\",\n            mCDE.mLocalHeaderRelOffset);\n        return UNKNOWN_ERROR;\n    }\n\n    result = mLFH.read(fp);\n    if (result != NO_ERROR) {\n        ALOGD(\"mLFH.read failed\\n\");\n        return result;\n    }\n\n    if (fseek(fp, posn, SEEK_SET) != 0)\n        return UNKNOWN_ERROR;\n\n    //mLFH.dump();\n\n    /*\n     * We *might* need to read the Data Descriptor at this point and\n     * integrate it into the LFH.  If this bit is set, the CRC-32,\n     * compressed size, and uncompressed size will be zero.  In practice\n     * these seem to be rare.\n     */\n    hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0;\n    if (hasDD) {\n        // do something clever\n        //ALOGD(\"+++ has data descriptor\\n\");\n    }\n\n    /*\n     * Sanity-check the LFH.  Note that this will fail if the \"kUsesDataDescr\"\n     * flag is set, because the LFH is incomplete.  (Not a problem, since we\n     * prefer the CDE values.)\n     */\n    if (!hasDD && !compareHeaders()) {\n        ALOGW(\"warning: header mismatch\\n\");\n        // keep going?\n    }\n\n    /*\n     * If the mVersionToExtract is greater than 20, we may have an\n     * issue unpacking the record -- could be encrypted, compressed\n     * with something we don't support, or use Zip64 extensions.  We\n     * can defer worrying about that to when we're extracting data.\n     */\n\n    return NO_ERROR;\n}\n\n/*\n * Initialize a new entry.  Pass in the file name and an optional comment.\n *\n * Initializes the CDE and the LFH.\n */\nvoid ZipEntry::initNew(const char* fileName, const char* comment)\n{\n    assert(fileName != NULL && *fileName != '\\0');  // name required\n\n    /* most fields are properly initialized by constructor */\n    mCDE.mVersionMadeBy = kDefaultMadeBy;\n    mCDE.mVersionToExtract = kDefaultVersion;\n    mCDE.mCompressionMethod = kCompressStored;\n    mCDE.mFileNameLength = strlen(fileName);\n    if (comment != NULL)\n        mCDE.mFileCommentLength = strlen(comment);\n    mCDE.mExternalAttrs = 0x81b60020;   // matches what WinZip does\n\n    if (mCDE.mFileNameLength > 0) {\n        mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];\n        strcpy((char*) mCDE.mFileName, fileName);\n    }\n    if (mCDE.mFileCommentLength > 0) {\n        /* TODO: stop assuming null-terminated ASCII here? */\n        mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];\n        strcpy((char*) mCDE.mFileComment, comment);\n    }\n\n    copyCDEtoLFH();\n}\n\n/*\n * Initialize a new entry, starting with the ZipEntry from a different\n * archive.\n *\n * Initializes the CDE and the LFH.\n */\nstatus_t ZipEntry::initFromExternal(const ZipFile* pZipFile,\n    const ZipEntry* pEntry)\n{\n    /*\n     * Copy everything in the CDE over, then fix up the hairy bits.\n     */\n    memcpy(&mCDE, &pEntry->mCDE, sizeof(mCDE));\n\n    if (mCDE.mFileNameLength > 0) {\n        mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];\n        if (mCDE.mFileName == NULL)\n            return NO_MEMORY;\n        strcpy((char*) mCDE.mFileName, (char*)pEntry->mCDE.mFileName);\n    }\n    if (mCDE.mFileCommentLength > 0) {\n        mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];\n        if (mCDE.mFileComment == NULL)\n            return NO_MEMORY;\n        strcpy((char*) mCDE.mFileComment, (char*)pEntry->mCDE.mFileComment);\n    }\n    if (mCDE.mExtraFieldLength > 0) {\n        /* we null-terminate this, though it may not be a string */\n        mCDE.mExtraField = new unsigned char[mCDE.mExtraFieldLength+1];\n        if (mCDE.mExtraField == NULL)\n            return NO_MEMORY;\n        memcpy(mCDE.mExtraField, pEntry->mCDE.mExtraField,\n            mCDE.mExtraFieldLength+1);\n    }\n\n    /* construct the LFH from the CDE */\n    copyCDEtoLFH();\n\n    /*\n     * The LFH \"extra\" field is independent of the CDE \"extra\", so we\n     * handle it here.\n     */\n    assert(mLFH.mExtraField == NULL);\n    mLFH.mExtraFieldLength = pEntry->mLFH.mExtraFieldLength;\n    if (mLFH.mExtraFieldLength > 0) {\n        mLFH.mExtraField = new unsigned char[mLFH.mExtraFieldLength+1];\n        if (mLFH.mExtraField == NULL)\n            return NO_MEMORY;\n        memcpy(mLFH.mExtraField, pEntry->mLFH.mExtraField,\n            mLFH.mExtraFieldLength+1);\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Insert pad bytes in the LFH by tweaking the \"extra\" field.  This will\n * potentially confuse something that put \"extra\" data in here earlier,\n * but I can't find an actual problem.\n */\nstatus_t ZipEntry::addPadding(int padding)\n{\n    if (padding <= 0)\n        return INVALID_OPERATION;\n\n    //ALOGI(\"HEY: adding %d pad bytes to existing %d in %s\\n\",\n    //    padding, mLFH.mExtraFieldLength, mCDE.mFileName);\n\n    if (mLFH.mExtraFieldLength > 0) {\n        /* extend existing field */\n        unsigned char* newExtra;\n\n        newExtra = new unsigned char[mLFH.mExtraFieldLength + padding];\n        if (newExtra == NULL)\n            return NO_MEMORY;\n        memset(newExtra + mLFH.mExtraFieldLength, 0, padding);\n        memcpy(newExtra, mLFH.mExtraField, mLFH.mExtraFieldLength);\n\n        delete[] mLFH.mExtraField;\n        mLFH.mExtraField = newExtra;\n        mLFH.mExtraFieldLength += padding;\n    } else {\n        /* create new field */\n        mLFH.mExtraField = new unsigned char[padding];\n        memset(mLFH.mExtraField, 0, padding);\n        mLFH.mExtraFieldLength = padding;\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Set the fields in the LFH equal to the corresponding fields in the CDE.\n *\n * This does not touch the LFH \"extra\" field.\n */\nvoid ZipEntry::copyCDEtoLFH(void)\n{\n    mLFH.mVersionToExtract  = mCDE.mVersionToExtract;\n    mLFH.mGPBitFlag         = mCDE.mGPBitFlag;\n    mLFH.mCompressionMethod = mCDE.mCompressionMethod;\n    mLFH.mLastModFileTime   = mCDE.mLastModFileTime;\n    mLFH.mLastModFileDate   = mCDE.mLastModFileDate;\n    mLFH.mCRC32             = mCDE.mCRC32;\n    mLFH.mCompressedSize    = mCDE.mCompressedSize;\n    mLFH.mUncompressedSize  = mCDE.mUncompressedSize;\n    mLFH.mFileNameLength    = mCDE.mFileNameLength;\n    // the \"extra field\" is independent\n\n    delete[] mLFH.mFileName;\n    if (mLFH.mFileNameLength > 0) {\n        mLFH.mFileName = new unsigned char[mLFH.mFileNameLength+1];\n        strcpy((char*) mLFH.mFileName, (const char*) mCDE.mFileName);\n    } else {\n        mLFH.mFileName = NULL;\n    }\n}\n\n/*\n * Set some information about a file after we add it.\n */\nvoid ZipEntry::setDataInfo(long uncompLen, long compLen, unsigned long crc32,\n    int compressionMethod)\n{\n    mCDE.mCompressionMethod = compressionMethod;\n    mCDE.mCRC32 = crc32;\n    mCDE.mCompressedSize = compLen;\n    mCDE.mUncompressedSize = uncompLen;\n    mCDE.mCompressionMethod = compressionMethod;\n    if (compressionMethod == kCompressDeflated) {\n        mCDE.mGPBitFlag |= 0x0002;      // indicates maximum compression used\n    }\n    copyCDEtoLFH();\n}\n\n/*\n * See if the data in mCDE and mLFH match up.  This is mostly useful for\n * debugging these classes, but it can be used to identify damaged\n * archives.\n *\n * Returns \"false\" if they differ.\n */\nbool ZipEntry::compareHeaders(void) const\n{\n    if (mCDE.mVersionToExtract != mLFH.mVersionToExtract) {\n        ALOGV(\"cmp: VersionToExtract\\n\");\n        return false;\n    }\n    if (mCDE.mGPBitFlag != mLFH.mGPBitFlag) {\n        ALOGV(\"cmp: GPBitFlag\\n\");\n        return false;\n    }\n    if (mCDE.mCompressionMethod != mLFH.mCompressionMethod) {\n        ALOGV(\"cmp: CompressionMethod\\n\");\n        return false;\n    }\n    if (mCDE.mLastModFileTime != mLFH.mLastModFileTime) {\n        ALOGV(\"cmp: LastModFileTime\\n\");\n        return false;\n    }\n    if (mCDE.mLastModFileDate != mLFH.mLastModFileDate) {\n        ALOGV(\"cmp: LastModFileDate\\n\");\n        return false;\n    }\n    if (mCDE.mCRC32 != mLFH.mCRC32) {\n        ALOGV(\"cmp: CRC32\\n\");\n        return false;\n    }\n    if (mCDE.mCompressedSize != mLFH.mCompressedSize) {\n        ALOGV(\"cmp: CompressedSize\\n\");\n        return false;\n    }\n    if (mCDE.mUncompressedSize != mLFH.mUncompressedSize) {\n        ALOGV(\"cmp: UncompressedSize\\n\");\n        return false;\n    }\n    if (mCDE.mFileNameLength != mLFH.mFileNameLength) {\n        ALOGV(\"cmp: FileNameLength\\n\");\n        return false;\n    }\n#if 0       // this seems to be used for padding, not real data\n    if (mCDE.mExtraFieldLength != mLFH.mExtraFieldLength) {\n        ALOGV(\"cmp: ExtraFieldLength\\n\");\n        return false;\n    }\n#endif\n    if (mCDE.mFileName != NULL) {\n        if (strcmp((char*) mCDE.mFileName, (char*) mLFH.mFileName) != 0) {\n            ALOGV(\"cmp: FileName\\n\");\n            return false;\n        }\n    }\n\n    return true;\n}\n\n\n/*\n * Convert the DOS date/time stamp into a UNIX time stamp.\n */\ntime_t ZipEntry::getModWhen(void) const\n{\n    struct tm parts;\n\n    parts.tm_sec = (mCDE.mLastModFileTime & 0x001f) << 1;\n    parts.tm_min = (mCDE.mLastModFileTime & 0x07e0) >> 5;\n    parts.tm_hour = (mCDE.mLastModFileTime & 0xf800) >> 11;\n    parts.tm_mday = (mCDE.mLastModFileDate & 0x001f);\n    parts.tm_mon = ((mCDE.mLastModFileDate & 0x01e0) >> 5) -1;\n    parts.tm_year = ((mCDE.mLastModFileDate & 0xfe00) >> 9) + 80;\n    parts.tm_wday = parts.tm_yday = 0;\n    parts.tm_isdst = -1;        // DST info \"not available\"\n\n    return mktime(&parts);\n}\n\n/*\n * Set the CDE/LFH timestamp from UNIX time.\n */\nvoid ZipEntry::setModWhen(time_t when)\n{\n#ifdef HAVE_LOCALTIME_R\n    struct tm tmResult;\n#endif\n    time_t even;\n    unsigned short zdate, ztime;\n\n    struct tm* ptm;\n\n    /* round up to an even number of seconds */\n    even = (time_t)(((unsigned long)(when) + 1) & (~1));\n\n    /* expand */\n#ifdef HAVE_LOCALTIME_R\n    ptm = localtime_r(&even, &tmResult);\n#else\n    ptm = localtime(&even);\n#endif\n\n    int year;\n    year = ptm->tm_year;\n    if (year < 80)\n        year = 80;\n\n    zdate = (year - 80) << 9 | (ptm->tm_mon+1) << 5 | ptm->tm_mday;\n    ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;\n\n    mCDE.mLastModFileTime = mLFH.mLastModFileTime = ztime;\n    mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate;\n}\n\n\n/*\n * ===========================================================================\n *      ZipEntry::LocalFileHeader\n * ===========================================================================\n */\n\n/*\n * Read a local file header.\n *\n * On entry, \"fp\" points to the signature at the start of the header.\n * On exit, \"fp\" points to the start of data.\n */\nstatus_t ZipEntry::LocalFileHeader::read(FILE* fp)\n{\n    status_t result = NO_ERROR;\n    unsigned char buf[kLFHLen];\n\n    assert(mFileName == NULL);\n    assert(mExtraField == NULL);\n\n    if (fread(buf, 1, kLFHLen, fp) != kLFHLen) {\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {\n        ALOGD(\"whoops: didn't find expected signature\\n\");\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    mVersionToExtract = ZipEntry::getShortLE(&buf[0x04]);\n    mGPBitFlag = ZipEntry::getShortLE(&buf[0x06]);\n    mCompressionMethod = ZipEntry::getShortLE(&buf[0x08]);\n    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0a]);\n    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0c]);\n    mCRC32 = ZipEntry::getLongLE(&buf[0x0e]);\n    mCompressedSize = ZipEntry::getLongLE(&buf[0x12]);\n    mUncompressedSize = ZipEntry::getLongLE(&buf[0x16]);\n    mFileNameLength = ZipEntry::getShortLE(&buf[0x1a]);\n    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1c]);\n\n    // TODO: validate sizes\n\n    /* grab filename */\n    if (mFileNameLength != 0) {\n        mFileName = new unsigned char[mFileNameLength+1];\n        if (mFileName == NULL) {\n            result = NO_MEMORY;\n            goto bail;\n        }\n        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {\n            result = UNKNOWN_ERROR;\n            goto bail;\n        }\n        mFileName[mFileNameLength] = '\\0';\n    }\n\n    /* grab extra field */\n    if (mExtraFieldLength != 0) {\n        mExtraField = new unsigned char[mExtraFieldLength+1];\n        if (mExtraField == NULL) {\n            result = NO_MEMORY;\n            goto bail;\n        }\n        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {\n            result = UNKNOWN_ERROR;\n            goto bail;\n        }\n        mExtraField[mExtraFieldLength] = '\\0';\n    }\n\nbail:\n    return result;\n}\n\n/*\n * Write a local file header.\n */\nstatus_t ZipEntry::LocalFileHeader::write(FILE* fp)\n{\n    unsigned char buf[kLFHLen];\n\n    ZipEntry::putLongLE(&buf[0x00], kSignature);\n    ZipEntry::putShortLE(&buf[0x04], mVersionToExtract);\n    ZipEntry::putShortLE(&buf[0x06], mGPBitFlag);\n    ZipEntry::putShortLE(&buf[0x08], mCompressionMethod);\n    ZipEntry::putShortLE(&buf[0x0a], mLastModFileTime);\n    ZipEntry::putShortLE(&buf[0x0c], mLastModFileDate);\n    ZipEntry::putLongLE(&buf[0x0e], mCRC32);\n    ZipEntry::putLongLE(&buf[0x12], mCompressedSize);\n    ZipEntry::putLongLE(&buf[0x16], mUncompressedSize);\n    ZipEntry::putShortLE(&buf[0x1a], mFileNameLength);\n    ZipEntry::putShortLE(&buf[0x1c], mExtraFieldLength);\n\n    if (fwrite(buf, 1, kLFHLen, fp) != kLFHLen)\n        return UNKNOWN_ERROR;\n\n    /* write filename */\n    if (mFileNameLength != 0) {\n        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)\n            return UNKNOWN_ERROR;\n    }\n\n    /* write \"extra field\" */\n    if (mExtraFieldLength != 0) {\n        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)\n            return UNKNOWN_ERROR;\n    }\n\n    return NO_ERROR;\n}\n\n\n/*\n * Dump the contents of a LocalFileHeader object.\n */\nvoid ZipEntry::LocalFileHeader::dump(void) const\n{\n    ALOGD(\" LocalFileHeader contents:\\n\");\n    ALOGD(\"  versToExt=%u gpBits=0x%04x compression=%u\\n\",\n        mVersionToExtract, mGPBitFlag, mCompressionMethod);\n    ALOGD(\"  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\\n\",\n        mLastModFileTime, mLastModFileDate, mCRC32);\n    ALOGD(\"  compressedSize=%lu uncompressedSize=%lu\\n\",\n        mCompressedSize, mUncompressedSize);\n    ALOGD(\"  filenameLen=%u extraLen=%u\\n\",\n        mFileNameLength, mExtraFieldLength);\n    if (mFileName != NULL)\n        ALOGD(\"  filename: '%s'\\n\", mFileName);\n}\n\n\n/*\n * ===========================================================================\n *      ZipEntry::CentralDirEntry\n * ===========================================================================\n */\n\n/*\n * Read the central dir entry that appears next in the file.\n *\n * On entry, \"fp\" should be positioned on the signature bytes for the\n * entry.  On exit, \"fp\" will point at the signature word for the next\n * entry or for the EOCD.\n */\nstatus_t ZipEntry::CentralDirEntry::read(FILE* fp)\n{\n    status_t result = NO_ERROR;\n    unsigned char buf[kCDELen];\n\n    /* no re-use */\n    assert(mFileName == NULL);\n    assert(mExtraField == NULL);\n    assert(mFileComment == NULL);\n\n    if (fread(buf, 1, kCDELen, fp) != kCDELen) {\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {\n        ALOGD(\"Whoops: didn't find expected signature\\n\");\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    mVersionMadeBy = ZipEntry::getShortLE(&buf[0x04]);\n    mVersionToExtract = ZipEntry::getShortLE(&buf[0x06]);\n    mGPBitFlag = ZipEntry::getShortLE(&buf[0x08]);\n    mCompressionMethod = ZipEntry::getShortLE(&buf[0x0a]);\n    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0c]);\n    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0e]);\n    mCRC32 = ZipEntry::getLongLE(&buf[0x10]);\n    mCompressedSize = ZipEntry::getLongLE(&buf[0x14]);\n    mUncompressedSize = ZipEntry::getLongLE(&buf[0x18]);\n    mFileNameLength = ZipEntry::getShortLE(&buf[0x1c]);\n    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1e]);\n    mFileCommentLength = ZipEntry::getShortLE(&buf[0x20]);\n    mDiskNumberStart = ZipEntry::getShortLE(&buf[0x22]);\n    mInternalAttrs = ZipEntry::getShortLE(&buf[0x24]);\n    mExternalAttrs = ZipEntry::getLongLE(&buf[0x26]);\n    mLocalHeaderRelOffset = ZipEntry::getLongLE(&buf[0x2a]);\n\n    // TODO: validate sizes and offsets\n\n    /* grab filename */\n    if (mFileNameLength != 0) {\n        mFileName = new unsigned char[mFileNameLength+1];\n        if (mFileName == NULL) {\n            result = NO_MEMORY;\n            goto bail;\n        }\n        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {\n            result = UNKNOWN_ERROR;\n            goto bail;\n        }\n        mFileName[mFileNameLength] = '\\0';\n    }\n\n    /* read \"extra field\" */\n    if (mExtraFieldLength != 0) {\n        mExtraField = new unsigned char[mExtraFieldLength+1];\n        if (mExtraField == NULL) {\n            result = NO_MEMORY;\n            goto bail;\n        }\n        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {\n            result = UNKNOWN_ERROR;\n            goto bail;\n        }\n        mExtraField[mExtraFieldLength] = '\\0';\n    }\n\n\n    /* grab comment, if any */\n    if (mFileCommentLength != 0) {\n        mFileComment = new unsigned char[mFileCommentLength+1];\n        if (mFileComment == NULL) {\n            result = NO_MEMORY;\n            goto bail;\n        }\n        if (fread(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)\n        {\n            result = UNKNOWN_ERROR;\n            goto bail;\n        }\n        mFileComment[mFileCommentLength] = '\\0';\n    }\n\nbail:\n    return result;\n}\n\n/*\n * Write a central dir entry.\n */\nstatus_t ZipEntry::CentralDirEntry::write(FILE* fp)\n{\n    unsigned char buf[kCDELen];\n\n    ZipEntry::putLongLE(&buf[0x00], kSignature);\n    ZipEntry::putShortLE(&buf[0x04], mVersionMadeBy);\n    ZipEntry::putShortLE(&buf[0x06], mVersionToExtract);\n    ZipEntry::putShortLE(&buf[0x08], mGPBitFlag);\n    ZipEntry::putShortLE(&buf[0x0a], mCompressionMethod);\n    ZipEntry::putShortLE(&buf[0x0c], mLastModFileTime);\n    ZipEntry::putShortLE(&buf[0x0e], mLastModFileDate);\n    ZipEntry::putLongLE(&buf[0x10], mCRC32);\n    ZipEntry::putLongLE(&buf[0x14], mCompressedSize);\n    ZipEntry::putLongLE(&buf[0x18], mUncompressedSize);\n    ZipEntry::putShortLE(&buf[0x1c], mFileNameLength);\n    ZipEntry::putShortLE(&buf[0x1e], mExtraFieldLength);\n    ZipEntry::putShortLE(&buf[0x20], mFileCommentLength);\n    ZipEntry::putShortLE(&buf[0x22], mDiskNumberStart);\n    ZipEntry::putShortLE(&buf[0x24], mInternalAttrs);\n    ZipEntry::putLongLE(&buf[0x26], mExternalAttrs);\n    ZipEntry::putLongLE(&buf[0x2a], mLocalHeaderRelOffset);\n\n    if (fwrite(buf, 1, kCDELen, fp) != kCDELen)\n        return UNKNOWN_ERROR;\n\n    /* write filename */\n    if (mFileNameLength != 0) {\n        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)\n            return UNKNOWN_ERROR;\n    }\n\n    /* write \"extra field\" */\n    if (mExtraFieldLength != 0) {\n        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)\n            return UNKNOWN_ERROR;\n    }\n\n    /* write comment */\n    if (mFileCommentLength != 0) {\n        if (fwrite(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)\n            return UNKNOWN_ERROR;\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Dump the contents of a CentralDirEntry object.\n */\nvoid ZipEntry::CentralDirEntry::dump(void) const\n{\n    ALOGD(\" CentralDirEntry contents:\\n\");\n    ALOGD(\"  versMadeBy=%u versToExt=%u gpBits=0x%04x compression=%u\\n\",\n        mVersionMadeBy, mVersionToExtract, mGPBitFlag, mCompressionMethod);\n    ALOGD(\"  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\\n\",\n        mLastModFileTime, mLastModFileDate, mCRC32);\n    ALOGD(\"  compressedSize=%lu uncompressedSize=%lu\\n\",\n        mCompressedSize, mUncompressedSize);\n    ALOGD(\"  filenameLen=%u extraLen=%u commentLen=%u\\n\",\n        mFileNameLength, mExtraFieldLength, mFileCommentLength);\n    ALOGD(\"  diskNumStart=%u intAttr=0x%04x extAttr=0x%08lx relOffset=%lu\\n\",\n        mDiskNumberStart, mInternalAttrs, mExternalAttrs,\n        mLocalHeaderRelOffset);\n\n    if (mFileName != NULL)\n        ALOGD(\"  filename: '%s'\\n\", mFileName);\n    if (mFileComment != NULL)\n        ALOGD(\"  comment: '%s'\\n\", mFileComment);\n}\n\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/ZipEntry.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Zip archive entries.\n//\n// The ZipEntry class is tightly meshed with the ZipFile class.\n//\n#ifndef __LIBS_ZIPENTRY_H\n#define __LIBS_ZIPENTRY_H\n\n#include <utils/Errors.h>\n\n#include <stdlib.h>\n#include <stdio.h>\n\nnamespace android {\n\nclass ZipFile;\n\n/*\n * ZipEntry objects represent a single entry in a Zip archive.\n *\n * You can use one of these to get or set information about an entry, but\n * there are no functions here for accessing the data itself.  (We could\n * tuck a pointer to the ZipFile in here for convenience, but that raises\n * the likelihood of using ZipEntry objects after discarding the ZipFile.)\n *\n * File information is stored in two places: next to the file data (the Local\n * File Header, and possibly a Data Descriptor), and at the end of the file\n * (the Central Directory Entry).  The two must be kept in sync.\n */\nclass ZipEntry {\npublic:\n    friend class ZipFile;\n\n    ZipEntry(void)\n        : mDeleted(false), mMarked(false)\n        {}\n    ~ZipEntry(void) {}\n\n    /*\n     * Returns \"true\" if the data is compressed.\n     */\n    bool isCompressed(void) const {\n        return mCDE.mCompressionMethod != kCompressStored;\n    }\n    int getCompressionMethod(void) const { return mCDE.mCompressionMethod; }\n\n    /*\n     * Return the uncompressed length.\n     */\n    off_t getUncompressedLen(void) const { return mCDE.mUncompressedSize; }\n\n    /*\n     * Return the compressed length.  For uncompressed data, this returns\n     * the same thing as getUncompresesdLen().\n     */\n    off_t getCompressedLen(void) const { return mCDE.mCompressedSize; }\n\n    /*\n     * Return the offset of the local file header.\n     */\n    off_t getLFHOffset(void) const { return mCDE.mLocalHeaderRelOffset; }\n\n    /*\n     * Return the absolute file offset of the start of the compressed or\n     * uncompressed data.\n     */\n    off_t getFileOffset(void) const {\n        return mCDE.mLocalHeaderRelOffset +\n                LocalFileHeader::kLFHLen +\n                mLFH.mFileNameLength +\n                mLFH.mExtraFieldLength;\n    }\n\n    /*\n     * Return the data CRC.\n     */\n    unsigned long getCRC32(void) const { return mCDE.mCRC32; }\n\n    /*\n     * Return file modification time in UNIX seconds-since-epoch.\n     */\n    time_t getModWhen(void) const;\n\n    /*\n     * Return the archived file name.\n     */\n    const char* getFileName(void) const { return (const char*) mCDE.mFileName; }\n\n    /*\n     * Application-defined \"mark\".  Can be useful when synchronizing the\n     * contents of an archive with contents on disk.\n     */\n    bool getMarked(void) const { return mMarked; }\n    void setMarked(bool val) { mMarked = val; }\n\n    /*\n     * Some basic functions for raw data manipulation.  \"LE\" means\n     * Little Endian.\n     */\n    static inline unsigned short getShortLE(const unsigned char* buf) {\n        return buf[0] | (buf[1] << 8);\n    }\n    static inline unsigned long getLongLE(const unsigned char* buf) {\n        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);\n    }\n    static inline void putShortLE(unsigned char* buf, short val) {\n        buf[0] = (unsigned char) val;\n        buf[1] = (unsigned char) (val >> 8);\n    }\n    static inline void putLongLE(unsigned char* buf, long val) {\n        buf[0] = (unsigned char) val;\n        buf[1] = (unsigned char) (val >> 8);\n        buf[2] = (unsigned char) (val >> 16);\n        buf[3] = (unsigned char) (val >> 24);\n    }\n\n    /* defined for Zip archives */\n    enum {\n        kCompressStored     = 0,        // no compression\n        // shrunk           = 1,\n        // reduced 1        = 2,\n        // reduced 2        = 3,\n        // reduced 3        = 4,\n        // reduced 4        = 5,\n        // imploded         = 6,\n        // tokenized        = 7,\n        kCompressDeflated   = 8,        // standard deflate\n        // Deflate64        = 9,\n        // lib imploded     = 10,\n        // reserved         = 11,\n        // bzip2            = 12,\n    };\n\n    /*\n     * Deletion flag.  If set, the entry will be removed on the next\n     * call to \"flush\".\n     */\n    bool getDeleted(void) const { return mDeleted; }\n\nprotected:\n    /*\n     * Initialize the structure from the file, which is pointing at\n     * our Central Directory entry.\n     */\n    status_t initFromCDE(FILE* fp);\n\n    /*\n     * Initialize the structure for a new file.  We need the filename\n     * and comment so that we can properly size the LFH area.  The\n     * filename is mandatory, the comment is optional.\n     */\n    void initNew(const char* fileName, const char* comment);\n\n    /*\n     * Initialize the structure with the contents of a ZipEntry from\n     * another file.\n     */\n    status_t initFromExternal(const ZipFile* pZipFile, const ZipEntry* pEntry);\n\n    /*\n     * Add some pad bytes to the LFH.  We do this by adding or resizing\n     * the \"extra\" field.\n     */\n    status_t addPadding(int padding);\n\n    /*\n     * Set information about the data for this entry.\n     */\n    void setDataInfo(long uncompLen, long compLen, unsigned long crc32,\n        int compressionMethod);\n\n    /*\n     * Set the modification date.\n     */\n    void setModWhen(time_t when);\n\n    /*\n     * Set the offset of the local file header, relative to the start of\n     * the current file.\n     */\n    void setLFHOffset(off_t offset) {\n        mCDE.mLocalHeaderRelOffset = (long) offset;\n    }\n\n    /* mark for deletion; used by ZipFile::remove() */\n    void setDeleted(void) { mDeleted = true; }\n\nprivate:\n    /* these are private and not defined */\n    ZipEntry(const ZipEntry& src);\n    ZipEntry& operator=(const ZipEntry& src);\n\n    /* returns \"true\" if the CDE and the LFH agree */\n    bool compareHeaders(void) const;\n    void copyCDEtoLFH(void);\n\n    bool        mDeleted;       // set if entry is pending deletion\n    bool        mMarked;        // app-defined marker\n\n    /*\n     * Every entry in the Zip archive starts off with one of these.\n     */\n    class LocalFileHeader {\n    public:\n        LocalFileHeader(void) :\n            mVersionToExtract(0),\n            mGPBitFlag(0),\n            mCompressionMethod(0),\n            mLastModFileTime(0),\n            mLastModFileDate(0),\n            mCRC32(0),\n            mCompressedSize(0),\n            mUncompressedSize(0),\n            mFileNameLength(0),\n            mExtraFieldLength(0),\n            mFileName(NULL),\n            mExtraField(NULL)\n        {}\n        virtual ~LocalFileHeader(void) {\n            delete[] mFileName;\n            delete[] mExtraField;\n        }\n\n        status_t read(FILE* fp);\n        status_t write(FILE* fp);\n\n        // unsigned long mSignature;\n        unsigned short  mVersionToExtract;\n        unsigned short  mGPBitFlag;\n        unsigned short  mCompressionMethod;\n        unsigned short  mLastModFileTime;\n        unsigned short  mLastModFileDate;\n        unsigned long   mCRC32;\n        unsigned long   mCompressedSize;\n        unsigned long   mUncompressedSize;\n        unsigned short  mFileNameLength;\n        unsigned short  mExtraFieldLength;\n        unsigned char*  mFileName;\n        unsigned char*  mExtraField;\n\n        enum {\n            kSignature      = 0x04034b50,\n            kLFHLen         = 30,       // LocalFileHdr len, excl. var fields\n        };\n\n        void dump(void) const;\n    };\n\n    /*\n     * Every entry in the Zip archive has one of these in the \"central\n     * directory\" at the end of the file.\n     */\n    class CentralDirEntry {\n    public:\n        CentralDirEntry(void) :\n            mVersionMadeBy(0),\n            mVersionToExtract(0),\n            mGPBitFlag(0),\n            mCompressionMethod(0),\n            mLastModFileTime(0),\n            mLastModFileDate(0),\n            mCRC32(0),\n            mCompressedSize(0),\n            mUncompressedSize(0),\n            mFileNameLength(0),\n            mExtraFieldLength(0),\n            mFileCommentLength(0),\n            mDiskNumberStart(0),\n            mInternalAttrs(0),\n            mExternalAttrs(0),\n            mLocalHeaderRelOffset(0),\n            mFileName(NULL),\n            mExtraField(NULL),\n            mFileComment(NULL)\n        {}\n        virtual ~CentralDirEntry(void) {\n            delete[] mFileName;\n            delete[] mExtraField;\n            delete[] mFileComment;\n        }\n\n        status_t read(FILE* fp);\n        status_t write(FILE* fp);\n\n        // unsigned long mSignature;\n        unsigned short  mVersionMadeBy;\n        unsigned short  mVersionToExtract;\n        unsigned short  mGPBitFlag;\n        unsigned short  mCompressionMethod;\n        unsigned short  mLastModFileTime;\n        unsigned short  mLastModFileDate;\n        unsigned long   mCRC32;\n        unsigned long   mCompressedSize;\n        unsigned long   mUncompressedSize;\n        unsigned short  mFileNameLength;\n        unsigned short  mExtraFieldLength;\n        unsigned short  mFileCommentLength;\n        unsigned short  mDiskNumberStart;\n        unsigned short  mInternalAttrs;\n        unsigned long   mExternalAttrs;\n        unsigned long   mLocalHeaderRelOffset;\n        unsigned char*  mFileName;\n        unsigned char*  mExtraField;\n        unsigned char*  mFileComment;\n\n        void dump(void) const;\n\n        enum {\n            kSignature      = 0x02014b50,\n            kCDELen         = 46,       // CentralDirEnt len, excl. var fields\n        };\n    };\n\n    enum {\n        //kDataDescriptorSignature  = 0x08074b50,   // currently unused\n        kDataDescriptorLen  = 16,           // four 32-bit fields\n\n        kDefaultVersion     = 20,           // need deflate, nothing much else\n        kDefaultMadeBy      = 0x0317,       // 03=UNIX, 17=spec v2.3\n        kUsesDataDescr      = 0x0008,       // GPBitFlag bit 3\n    };\n\n    LocalFileHeader     mLFH;\n    CentralDirEntry     mCDE;\n};\n\n}; // namespace android\n\n#endif // __LIBS_ZIPENTRY_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/ZipFile.cpp",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// Access to Zip archives.\n//\n\n#define LOG_TAG \"zip\"\n\n#include <androidfw/ZipUtils.h>\n#include <utils/Log.h>\n\n#include \"ZipFile.h\"\n\n#include <zlib.h>\n#define DEF_MEM_LEVEL 8                // normally in zutil.h?\n\n#include <memory.h>\n#include <sys/stat.h>\n#include <errno.h>\n#include <assert.h>\n\nusing namespace android;\n\n/*\n * Some environments require the \"b\", some choke on it.\n */\n#define FILE_OPEN_RO        \"rb\"\n#define FILE_OPEN_RW        \"r+b\"\n#define FILE_OPEN_RW_CREATE \"w+b\"\n\n/* should live somewhere else? */\nstatic status_t errnoToStatus(int err)\n{\n    if (err == ENOENT)\n        return NAME_NOT_FOUND;\n    else if (err == EACCES)\n        return PERMISSION_DENIED;\n    else\n        return UNKNOWN_ERROR;\n}\n\n/*\n * Open a file and parse its guts.\n */\nstatus_t ZipFile::open(const char* zipFileName, int flags)\n{\n    bool newArchive = false;\n\n    assert(mZipFp == NULL);     // no reopen\n\n    if ((flags & kOpenTruncate))\n        flags |= kOpenCreate;           // trunc implies create\n\n    if ((flags & kOpenReadOnly) && (flags & kOpenReadWrite))\n        return INVALID_OPERATION;       // not both\n    if (!((flags & kOpenReadOnly) || (flags & kOpenReadWrite)))\n        return INVALID_OPERATION;       // not neither\n    if ((flags & kOpenCreate) && !(flags & kOpenReadWrite))\n        return INVALID_OPERATION;       // create requires write\n\n    if (flags & kOpenTruncate) {\n        newArchive = true;\n    } else {\n        newArchive = (access(zipFileName, F_OK) != 0);\n        if (!(flags & kOpenCreate) && newArchive) {\n            /* not creating, must already exist */\n            ALOGD(\"File %s does not exist\", zipFileName);\n            return NAME_NOT_FOUND;\n        }\n    }\n\n    /* open the file */\n    const char* openflags;\n    if (flags & kOpenReadWrite) {\n        if (newArchive)\n            openflags = FILE_OPEN_RW_CREATE;\n        else\n            openflags = FILE_OPEN_RW;\n    } else {\n        openflags = FILE_OPEN_RO;\n    }\n    mZipFp = fopen(zipFileName, openflags);\n    if (mZipFp == NULL) {\n        int err = errno;\n        ALOGD(\"fopen failed: %d\\n\", err);\n        return errnoToStatus(err);\n    }\n\n    status_t result;\n    if (!newArchive) {\n        /*\n         * Load the central directory.  If that fails, then this probably\n         * isn't a Zip archive.\n         */\n        result = readCentralDir();\n    } else {\n        /*\n         * Newly-created.  The EndOfCentralDir constructor actually\n         * sets everything to be the way we want it (all zeroes).  We\n         * set mNeedCDRewrite so that we create *something* if the\n         * caller doesn't add any files.  (We could also just unlink\n         * the file if it's brand new and nothing was added, but that's\n         * probably doing more than we really should -- the user might\n         * have a need for empty zip files.)\n         */\n        mNeedCDRewrite = true;\n        result = NO_ERROR;\n    }\n\n    if (flags & kOpenReadOnly)\n        mReadOnly = true;\n    else\n        assert(!mReadOnly);\n\n    return result;\n}\n\n/*\n * Return the Nth entry in the archive.\n */\nZipEntry* ZipFile::getEntryByIndex(int idx) const\n{\n    if (idx < 0 || idx >= (int) mEntries.size())\n        return NULL;\n\n    return mEntries[idx];\n}\n\n/*\n * Find an entry by name.\n */\nZipEntry* ZipFile::getEntryByName(const char* fileName) const\n{\n    /*\n     * Do a stupid linear string-compare search.\n     *\n     * There are various ways to speed this up, especially since it's rare\n     * to intermingle changes to the archive with \"get by name\" calls.  We\n     * don't want to sort the mEntries vector itself, however, because\n     * it's used to recreate the Central Directory.\n     *\n     * (Hash table works, parallel list of pointers in sorted order is good.)\n     */\n    int idx;\n\n    for (idx = mEntries.size()-1; idx >= 0; idx--) {\n        ZipEntry* pEntry = mEntries[idx];\n        if (!pEntry->getDeleted() &&\n            strcmp(fileName, pEntry->getFileName()) == 0)\n        {\n            return pEntry;\n        }\n    }\n\n    return NULL;\n}\n\n/*\n * Empty the mEntries vector.\n */\nvoid ZipFile::discardEntries(void)\n{\n    int count = mEntries.size();\n\n    while (--count >= 0)\n        delete mEntries[count];\n\n    mEntries.clear();\n}\n\n\n/*\n * Find the central directory and read the contents.\n *\n * The fun thing about ZIP archives is that they may or may not be\n * readable from start to end.  In some cases, notably for archives\n * that were written to stdout, the only length information is in the\n * central directory at the end of the file.\n *\n * Of course, the central directory can be followed by a variable-length\n * comment field, so we have to scan through it backwards.  The comment\n * is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff\n * itself, plus apparently sometimes people throw random junk on the end\n * just for the fun of it.\n *\n * This is all a little wobbly.  If the wrong value ends up in the EOCD\n * area, we're hosed.  This appears to be the way that everbody handles\n * it though, so we're in pretty good company if this fails.\n */\nstatus_t ZipFile::readCentralDir(void)\n{\n    status_t result = NO_ERROR;\n    unsigned char* buf = NULL;\n    off_t fileLength, seekStart;\n    long readAmount;\n    int i;\n\n    fseek(mZipFp, 0, SEEK_END);\n    fileLength = ftell(mZipFp);\n    rewind(mZipFp);\n\n    /* too small to be a ZIP archive? */\n    if (fileLength < EndOfCentralDir::kEOCDLen) {\n        ALOGD(\"Length is %ld -- too small\\n\", (long)fileLength);\n        result = INVALID_OPERATION;\n        goto bail;\n    }\n\n    buf = new unsigned char[EndOfCentralDir::kMaxEOCDSearch];\n    if (buf == NULL) {\n        ALOGD(\"Failure allocating %d bytes for EOCD search\",\n             EndOfCentralDir::kMaxEOCDSearch);\n        result = NO_MEMORY;\n        goto bail;\n    }\n\n    if (fileLength > EndOfCentralDir::kMaxEOCDSearch) {\n        seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch;\n        readAmount = EndOfCentralDir::kMaxEOCDSearch;\n    } else {\n        seekStart = 0;\n        readAmount = (long) fileLength;\n    }\n    if (fseek(mZipFp, seekStart, SEEK_SET) != 0) {\n        ALOGD(\"Failure seeking to end of zip at %ld\", (long) seekStart);\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    /* read the last part of the file into the buffer */\n    if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) {\n        ALOGD(\"short file? wanted %ld\\n\", readAmount);\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    /* find the end-of-central-dir magic */\n    for (i = readAmount - 4; i >= 0; i--) {\n        if (buf[i] == 0x50 &&\n            ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature)\n        {\n            ALOGV(\"+++ Found EOCD at buf+%d\\n\", i);\n            break;\n        }\n    }\n    if (i < 0) {\n        ALOGD(\"EOCD not found, not Zip\\n\");\n        result = INVALID_OPERATION;\n        goto bail;\n    }\n\n    /* extract eocd values */\n    result = mEOCD.readBuf(buf + i, readAmount - i);\n    if (result != NO_ERROR) {\n        ALOGD(\"Failure reading %ld bytes of EOCD values\", readAmount - i);\n        goto bail;\n    }\n    //mEOCD.dump();\n\n    if (mEOCD.mDiskNumber != 0 || mEOCD.mDiskWithCentralDir != 0 ||\n        mEOCD.mNumEntries != mEOCD.mTotalNumEntries)\n    {\n        ALOGD(\"Archive spanning not supported\\n\");\n        result = INVALID_OPERATION;\n        goto bail;\n    }\n\n    /*\n     * So far so good.  \"mCentralDirSize\" is the size in bytes of the\n     * central directory, so we can just seek back that far to find it.\n     * We can also seek forward mCentralDirOffset bytes from the\n     * start of the file.\n     *\n     * We're not guaranteed to have the rest of the central dir in the\n     * buffer, nor are we guaranteed that the central dir will have any\n     * sort of convenient size.  We need to skip to the start of it and\n     * read the header, then the other goodies.\n     *\n     * The only thing we really need right now is the file comment, which\n     * we're hoping to preserve.\n     */\n    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {\n        ALOGD(\"Failure seeking to central dir offset %ld\\n\",\n             mEOCD.mCentralDirOffset);\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    /*\n     * Loop through and read the central dir entries.\n     */\n    ALOGV(\"Scanning %d entries...\\n\", mEOCD.mTotalNumEntries);\n    int entry;\n    for (entry = 0; entry < mEOCD.mTotalNumEntries; entry++) {\n        ZipEntry* pEntry = new ZipEntry;\n\n        result = pEntry->initFromCDE(mZipFp);\n        if (result != NO_ERROR) {\n            ALOGD(\"initFromCDE failed\\n\");\n            delete pEntry;\n            goto bail;\n        }\n\n        mEntries.add(pEntry);\n    }\n\n\n    /*\n     * If all went well, we should now be back at the EOCD.\n     */\n    {\n        unsigned char checkBuf[4];\n        if (fread(checkBuf, 1, 4, mZipFp) != 4) {\n            ALOGD(\"EOCD check read failed\\n\");\n            result = INVALID_OPERATION;\n            goto bail;\n        }\n        if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) {\n            ALOGD(\"EOCD read check failed\\n\");\n            result = UNKNOWN_ERROR;\n            goto bail;\n        }\n        ALOGV(\"+++ EOCD read check passed\\n\");\n    }\n\nbail:\n    delete[] buf;\n    return result;\n}\n\n\n/*\n * Add a new file to the archive.\n *\n * This requires creating and populating a ZipEntry structure, and copying\n * the data into the file at the appropriate position.  The \"appropriate\n * position\" is the current location of the central directory, which we\n * casually overwrite (we can put it back later).\n *\n * If we were concerned about safety, we would want to make all changes\n * in a temp file and then overwrite the original after everything was\n * safely written.  Not really a concern for us.\n */\nstatus_t ZipFile::addCommon(const char* fileName, const void* data, size_t size,\n    const char* storageName, int sourceType, int compressionMethod,\n    ZipEntry** ppEntry)\n{\n    ZipEntry* pEntry = NULL;\n    status_t result = NO_ERROR;\n    long lfhPosn, startPosn, endPosn, uncompressedLen;\n    FILE* inputFp = NULL;\n    unsigned long crc;\n    time_t modWhen;\n\n    if (mReadOnly)\n        return INVALID_OPERATION;\n\n    assert(compressionMethod == ZipEntry::kCompressDeflated ||\n           compressionMethod == ZipEntry::kCompressStored);\n\n    /* make sure we're in a reasonable state */\n    assert(mZipFp != NULL);\n    assert(mEntries.size() == mEOCD.mTotalNumEntries);\n\n    /* make sure it doesn't already exist */\n    if (getEntryByName(storageName) != NULL)\n        return ALREADY_EXISTS;\n\n    if (!data) {\n        inputFp = fopen(fileName, FILE_OPEN_RO);\n        if (inputFp == NULL)\n            return errnoToStatus(errno);\n    }\n\n    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    pEntry = new ZipEntry;\n    pEntry->initNew(storageName, NULL);\n\n    /*\n     * From here on out, failures are more interesting.\n     */\n    mNeedCDRewrite = true;\n\n    /*\n     * Write the LFH, even though it's still mostly blank.  We need it\n     * as a place-holder.  In theory the LFH isn't necessary, but in\n     * practice some utilities demand it.\n     */\n    lfhPosn = ftell(mZipFp);\n    pEntry->mLFH.write(mZipFp);\n    startPosn = ftell(mZipFp);\n\n    /*\n     * Copy the data in, possibly compressing it as we go.\n     */\n    if (sourceType == ZipEntry::kCompressStored) {\n        if (compressionMethod == ZipEntry::kCompressDeflated) {\n            bool failed = false;\n            result = compressFpToFp(mZipFp, inputFp, data, size, &crc);\n            if (result != NO_ERROR) {\n                ALOGD(\"compression failed, storing\\n\");\n                failed = true;\n            } else {\n                /*\n                 * Make sure it has compressed \"enough\".  This probably ought\n                 * to be set through an API call, but I don't expect our\n                 * criteria to change over time.\n                 */\n                long src = inputFp ? ftell(inputFp) : size;\n                long dst = ftell(mZipFp) - startPosn;\n                if (dst + (dst / 10) > src) {\n                    ALOGD(\"insufficient compression (src=%ld dst=%ld), storing\\n\",\n                        src, dst);\n                    failed = true;\n                }\n            }\n\n            if (failed) {\n                compressionMethod = ZipEntry::kCompressStored;\n                if (inputFp) rewind(inputFp);\n                fseek(mZipFp, startPosn, SEEK_SET);\n                /* fall through to kCompressStored case */\n            }\n        }\n        /* handle \"no compression\" request, or failed compression from above */\n        if (compressionMethod == ZipEntry::kCompressStored) {\n            if (inputFp) {\n                result = copyFpToFp(mZipFp, inputFp, &crc);\n            } else {\n                result = copyDataToFp(mZipFp, data, size, &crc);\n            }\n            if (result != NO_ERROR) {\n                // don't need to truncate; happens in CDE rewrite\n                ALOGD(\"failed copying data in\\n\");\n                goto bail;\n            }\n        }\n\n        // currently seeked to end of file\n        uncompressedLen = inputFp ? ftell(inputFp) : size;\n    } else if (sourceType == ZipEntry::kCompressDeflated) {\n        /* we should support uncompressed-from-compressed, but it's not\n         * important right now */\n        assert(compressionMethod == ZipEntry::kCompressDeflated);\n\n        bool scanResult;\n        int method;\n        long compressedLen;\n\n        scanResult = ZipUtils::examineGzip(inputFp, &method, &uncompressedLen,\n                        &compressedLen, &crc);\n        if (!scanResult || method != ZipEntry::kCompressDeflated) {\n            ALOGD(\"this isn't a deflated gzip file?\");\n            result = UNKNOWN_ERROR;\n            goto bail;\n        }\n\n        result = copyPartialFpToFp(mZipFp, inputFp, compressedLen, NULL);\n        if (result != NO_ERROR) {\n            ALOGD(\"failed copying gzip data in\\n\");\n            goto bail;\n        }\n    } else {\n        assert(false);\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    /*\n     * We could write the \"Data Descriptor\", but there doesn't seem to\n     * be any point since we're going to go back and write the LFH.\n     *\n     * Update file offsets.\n     */\n    endPosn = ftell(mZipFp);            // seeked to end of compressed data\n\n    /*\n     * Success!  Fill out new values.\n     */\n    pEntry->setDataInfo(uncompressedLen, endPosn - startPosn, crc,\n        compressionMethod);\n    modWhen = getModTime(inputFp ? fileno(inputFp) : fileno(mZipFp));\n    pEntry->setModWhen(modWhen);\n    pEntry->setLFHOffset(lfhPosn);\n    mEOCD.mNumEntries++;\n    mEOCD.mTotalNumEntries++;\n    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()\n    mEOCD.mCentralDirOffset = endPosn;\n\n    /*\n     * Go back and write the LFH.\n     */\n    if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) {\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n    pEntry->mLFH.write(mZipFp);\n\n    /*\n     * Add pEntry to the list.\n     */\n    mEntries.add(pEntry);\n    if (ppEntry != NULL)\n        *ppEntry = pEntry;\n    pEntry = NULL;\n\nbail:\n    if (inputFp != NULL)\n        fclose(inputFp);\n    delete pEntry;\n    return result;\n}\n\n/*\n * Add an entry by copying it from another zip file.  If \"padding\" is\n * nonzero, the specified number of bytes will be added to the \"extra\"\n * field in the header.\n *\n * If \"ppEntry\" is non-NULL, a pointer to the new entry will be returned.\n */\nstatus_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,\n    int padding, ZipEntry** ppEntry)\n{\n    ZipEntry* pEntry = NULL;\n    status_t result;\n    long lfhPosn, endPosn;\n\n    if (mReadOnly)\n        return INVALID_OPERATION;\n\n    /* make sure we're in a reasonable state */\n    assert(mZipFp != NULL);\n    assert(mEntries.size() == mEOCD.mTotalNumEntries);\n\n    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    pEntry = new ZipEntry;\n    if (pEntry == NULL) {\n        result = NO_MEMORY;\n        goto bail;\n    }\n\n    result = pEntry->initFromExternal(pSourceZip, pSourceEntry);\n    if (result != NO_ERROR)\n        goto bail;\n    if (padding != 0) {\n        result = pEntry->addPadding(padding);\n        if (result != NO_ERROR)\n            goto bail;\n    }\n\n    /*\n     * From here on out, failures are more interesting.\n     */\n    mNeedCDRewrite = true;\n\n    /*\n     * Write the LFH.  Since we're not recompressing the data, we already\n     * have all of the fields filled out.\n     */\n    lfhPosn = ftell(mZipFp);\n    pEntry->mLFH.write(mZipFp);\n\n    /*\n     * Copy the data over.\n     *\n     * If the \"has data descriptor\" flag is set, we want to copy the DD\n     * fields as well.  This is a fixed-size area immediately following\n     * the data.\n     */\n    if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0)\n    {\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    off_t copyLen;\n    copyLen = pSourceEntry->getCompressedLen();\n    if ((pSourceEntry->mLFH.mGPBitFlag & ZipEntry::kUsesDataDescr) != 0)\n        copyLen += ZipEntry::kDataDescriptorLen;\n\n    if (copyPartialFpToFp(mZipFp, pSourceZip->mZipFp, copyLen, NULL)\n        != NO_ERROR)\n    {\n        ALOGW(\"copy of '%s' failed\\n\", pEntry->mCDE.mFileName);\n        result = UNKNOWN_ERROR;\n        goto bail;\n    }\n\n    /*\n     * Update file offsets.\n     */\n    endPosn = ftell(mZipFp);\n\n    /*\n     * Success!  Fill out new values.\n     */\n    pEntry->setLFHOffset(lfhPosn);      // sets mCDE.mLocalHeaderRelOffset\n    mEOCD.mNumEntries++;\n    mEOCD.mTotalNumEntries++;\n    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()\n    mEOCD.mCentralDirOffset = endPosn;\n\n    /*\n     * Add pEntry to the list.\n     */\n    mEntries.add(pEntry);\n    if (ppEntry != NULL)\n        *ppEntry = pEntry;\n    pEntry = NULL;\n\n    result = NO_ERROR;\n\nbail:\n    delete pEntry;\n    return result;\n}\n\n/*\n * Copy all of the bytes in \"src\" to \"dst\".\n *\n * On exit, \"srcFp\" will be seeked to the end of the file, and \"dstFp\"\n * will be seeked immediately past the data.\n */\nstatus_t ZipFile::copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32)\n{\n    unsigned char tmpBuf[32768];\n    size_t count;\n\n    *pCRC32 = crc32(0L, Z_NULL, 0);\n\n    while (1) {\n        count = fread(tmpBuf, 1, sizeof(tmpBuf), srcFp);\n        if (ferror(srcFp) || ferror(dstFp))\n            return errnoToStatus(errno);\n        if (count == 0)\n            break;\n\n        *pCRC32 = crc32(*pCRC32, tmpBuf, count);\n\n        if (fwrite(tmpBuf, 1, count, dstFp) != count) {\n            ALOGD(\"fwrite %d bytes failed\\n\", (int) count);\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Copy all of the bytes in \"src\" to \"dst\".\n *\n * On exit, \"dstFp\" will be seeked immediately past the data.\n */\nstatus_t ZipFile::copyDataToFp(FILE* dstFp,\n    const void* data, size_t size, unsigned long* pCRC32)\n{\n    size_t count;\n\n    *pCRC32 = crc32(0L, Z_NULL, 0);\n    if (size > 0) {\n        *pCRC32 = crc32(*pCRC32, (const unsigned char*)data, size);\n        if (fwrite(data, 1, size, dstFp) != size) {\n            ALOGD(\"fwrite %d bytes failed\\n\", (int) size);\n            return UNKNOWN_ERROR;\n        }\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Copy some of the bytes in \"src\" to \"dst\".\n *\n * If \"pCRC32\" is NULL, the CRC will not be computed.\n *\n * On exit, \"srcFp\" will be seeked to the end of the file, and \"dstFp\"\n * will be seeked immediately past the data just written.\n */\nstatus_t ZipFile::copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,\n    unsigned long* pCRC32)\n{\n    unsigned char tmpBuf[32768];\n    size_t count;\n\n    if (pCRC32 != NULL)\n        *pCRC32 = crc32(0L, Z_NULL, 0);\n\n    while (length) {\n        long readSize;\n        \n        readSize = sizeof(tmpBuf);\n        if (readSize > length)\n            readSize = length;\n\n        count = fread(tmpBuf, 1, readSize, srcFp);\n        if ((long) count != readSize) {     // error or unexpected EOF\n            ALOGD(\"fread %d bytes failed\\n\", (int) readSize);\n            return UNKNOWN_ERROR;\n        }\n\n        if (pCRC32 != NULL)\n            *pCRC32 = crc32(*pCRC32, tmpBuf, count);\n\n        if (fwrite(tmpBuf, 1, count, dstFp) != count) {\n            ALOGD(\"fwrite %d bytes failed\\n\", (int) count);\n            return UNKNOWN_ERROR;\n        }\n\n        length -= readSize;\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Compress all of the data in \"srcFp\" and write it to \"dstFp\".\n *\n * On exit, \"srcFp\" will be seeked to the end of the file, and \"dstFp\"\n * will be seeked immediately past the compressed data.\n */\nstatus_t ZipFile::compressFpToFp(FILE* dstFp, FILE* srcFp,\n    const void* data, size_t size, unsigned long* pCRC32)\n{\n    status_t result = NO_ERROR;\n    const size_t kBufSize = 32768;\n    unsigned char* inBuf = NULL;\n    unsigned char* outBuf = NULL;\n    z_stream zstream;\n    bool atEof = false;     // no feof() aviailable yet\n    unsigned long crc;\n    int zerr;\n\n    /*\n     * Create an input buffer and an output buffer.\n     */\n    inBuf = new unsigned char[kBufSize];\n    outBuf = new unsigned char[kBufSize];\n    if (inBuf == NULL || outBuf == NULL) {\n        result = NO_MEMORY;\n        goto bail;\n    }\n\n    /*\n     * Initialize the zlib stream.\n     */\n    memset(&zstream, 0, sizeof(zstream));\n    zstream.zalloc = Z_NULL;\n    zstream.zfree = Z_NULL;\n    zstream.opaque = Z_NULL;\n    zstream.next_in = NULL;\n    zstream.avail_in = 0;\n    zstream.next_out = outBuf;\n    zstream.avail_out = kBufSize;\n    zstream.data_type = Z_UNKNOWN;\n\n    zerr = deflateInit2(&zstream, Z_BEST_COMPRESSION,\n        Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);\n    if (zerr != Z_OK) {\n        result = UNKNOWN_ERROR;\n        if (zerr == Z_VERSION_ERROR) {\n            ALOGE(\"Installed zlib is not compatible with linked version (%s)\\n\",\n                ZLIB_VERSION);\n        } else {\n            ALOGD(\"Call to deflateInit2 failed (zerr=%d)\\n\", zerr);\n        }\n        goto bail;\n    }\n\n    crc = crc32(0L, Z_NULL, 0);\n\n    /*\n     * Loop while we have data.\n     */\n    do {\n        size_t getSize;\n        int flush;\n\n        /* only read if the input buffer is empty */\n        if (zstream.avail_in == 0 && !atEof) {\n            ALOGV(\"+++ reading %d bytes\\n\", (int)kBufSize);\n            if (data) {\n                getSize = size > kBufSize ? kBufSize : size;\n                memcpy(inBuf, data, getSize);\n                data = ((const char*)data) + getSize;\n                size -= getSize;\n            } else {\n                getSize = fread(inBuf, 1, kBufSize, srcFp);\n                if (ferror(srcFp)) {\n                    ALOGD(\"deflate read failed (errno=%d)\\n\", errno);\n                    goto z_bail;\n                }\n            }\n            if (getSize < kBufSize) {\n                ALOGV(\"+++  got %d bytes, EOF reached\\n\",\n                    (int)getSize);\n                atEof = true;\n            }\n\n            crc = crc32(crc, inBuf, getSize);\n\n            zstream.next_in = inBuf;\n            zstream.avail_in = getSize;\n        }\n\n        if (atEof)\n            flush = Z_FINISH;       /* tell zlib that we're done */\n        else\n            flush = Z_NO_FLUSH;     /* more to come! */\n\n        zerr = deflate(&zstream, flush);\n        if (zerr != Z_OK && zerr != Z_STREAM_END) {\n            ALOGD(\"zlib deflate call failed (zerr=%d)\\n\", zerr);\n            result = UNKNOWN_ERROR;\n            goto z_bail;\n        }\n\n        /* write when we're full or when we're done */\n        if (zstream.avail_out == 0 ||\n            (zerr == Z_STREAM_END && zstream.avail_out != (uInt) kBufSize))\n        {\n            ALOGV(\"+++ writing %d bytes\\n\", (int) (zstream.next_out - outBuf));\n            if (fwrite(outBuf, 1, zstream.next_out - outBuf, dstFp) !=\n                (size_t)(zstream.next_out - outBuf))\n            {\n                ALOGD(\"write %d failed in deflate\\n\",\n                    (int) (zstream.next_out - outBuf));\n                goto z_bail;\n            }\n\n            zstream.next_out = outBuf;\n            zstream.avail_out = kBufSize;\n        }\n    } while (zerr == Z_OK);\n\n    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */\n\n    *pCRC32 = crc;\n\nz_bail:\n    deflateEnd(&zstream);        /* free up any allocated structures */\n\nbail:\n    delete[] inBuf;\n    delete[] outBuf;\n\n    return result;\n}\n\n/*\n * Mark an entry as deleted.\n *\n * We will eventually need to crunch the file down, but if several files\n * are being removed (perhaps as part of an \"update\" process) we can make\n * things considerably faster by deferring the removal to \"flush\" time.\n */\nstatus_t ZipFile::remove(ZipEntry* pEntry)\n{\n    /*\n     * Should verify that pEntry is actually part of this archive, and\n     * not some stray ZipEntry from a different file.\n     */\n\n    /* mark entry as deleted, and mark archive as dirty */\n    pEntry->setDeleted();\n    mNeedCDRewrite = true;\n    return NO_ERROR;\n}\n\n/*\n * Flush any pending writes.\n *\n * In particular, this will crunch out deleted entries, and write the\n * Central Directory and EOCD if we have stomped on them.\n */\nstatus_t ZipFile::flush(void)\n{\n    status_t result = NO_ERROR;\n    long eocdPosn;\n    int i, count;\n\n    if (mReadOnly)\n        return INVALID_OPERATION;\n    if (!mNeedCDRewrite)\n        return NO_ERROR;\n\n    assert(mZipFp != NULL);\n\n    result = crunchArchive();\n    if (result != NO_ERROR)\n        return result;\n\n    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0)\n        return UNKNOWN_ERROR;\n\n    count = mEntries.size();\n    for (i = 0; i < count; i++) {\n        ZipEntry* pEntry = mEntries[i];\n        pEntry->mCDE.write(mZipFp);\n    }\n\n    eocdPosn = ftell(mZipFp);\n    mEOCD.mCentralDirSize = eocdPosn - mEOCD.mCentralDirOffset;\n\n    mEOCD.write(mZipFp);\n\n    /*\n     * If we had some stuff bloat up during compression and get replaced\n     * with plain files, or if we deleted some entries, there's a lot\n     * of wasted space at the end of the file.  Remove it now.\n     */\n    if (ftruncate(fileno(mZipFp), ftell(mZipFp)) != 0) {\n        ALOGW(\"ftruncate failed %ld: %s\\n\", ftell(mZipFp), strerror(errno));\n        // not fatal\n    }\n\n    /* should we clear the \"newly added\" flag in all entries now? */\n\n    mNeedCDRewrite = false;\n    return NO_ERROR;\n}\n\n/*\n * Crunch deleted files out of an archive by shifting the later files down.\n *\n * Because we're not using a temp file, we do the operation inside the\n * current file.\n */\nstatus_t ZipFile::crunchArchive(void)\n{\n    status_t result = NO_ERROR;\n    int i, count;\n    long delCount, adjust;\n\n#if 0\n    printf(\"CONTENTS:\\n\");\n    for (i = 0; i < (int) mEntries.size(); i++) {\n        printf(\" %d: lfhOff=%ld del=%d\\n\",\n            i, mEntries[i]->getLFHOffset(), mEntries[i]->getDeleted());\n    }\n    printf(\"  END is %ld\\n\", (long) mEOCD.mCentralDirOffset);\n#endif\n\n    /*\n     * Roll through the set of files, shifting them as appropriate.  We\n     * could probably get a slight performance improvement by sliding\n     * multiple files down at once (because we could use larger reads\n     * when operating on batches of small files), but it's not that useful.\n     */\n    count = mEntries.size();\n    delCount = adjust = 0;\n    for (i = 0; i < count; i++) {\n        ZipEntry* pEntry = mEntries[i];\n        long span;\n\n        if (pEntry->getLFHOffset() != 0) {\n            long nextOffset;\n\n            /* Get the length of this entry by finding the offset\n             * of the next entry.  Directory entries don't have\n             * file offsets, so we need to find the next non-directory\n             * entry.\n             */\n            nextOffset = 0;\n            for (int ii = i+1; nextOffset == 0 && ii < count; ii++)\n                nextOffset = mEntries[ii]->getLFHOffset();\n            if (nextOffset == 0)\n                nextOffset = mEOCD.mCentralDirOffset;\n            span = nextOffset - pEntry->getLFHOffset();\n\n            assert(span >= ZipEntry::LocalFileHeader::kLFHLen);\n        } else {\n            /* This is a directory entry.  It doesn't have\n             * any actual file contents, so there's no need to\n             * move anything.\n             */\n            span = 0;\n        }\n\n        //printf(\"+++ %d: off=%ld span=%ld del=%d [count=%d]\\n\",\n        //    i, pEntry->getLFHOffset(), span, pEntry->getDeleted(), count);\n\n        if (pEntry->getDeleted()) {\n            adjust += span;\n            delCount++;\n\n            delete pEntry;\n            mEntries.removeAt(i);\n\n            /* adjust loop control */\n            count--;\n            i--;\n        } else if (span != 0 && adjust > 0) {\n            /* shuffle this entry back */\n            //printf(\"+++ Shuffling '%s' back %ld\\n\",\n            //    pEntry->getFileName(), adjust);\n            result = filemove(mZipFp, pEntry->getLFHOffset() - adjust,\n                        pEntry->getLFHOffset(), span);\n            if (result != NO_ERROR) {\n                /* this is why you use a temp file */\n                ALOGE(\"error during crunch - archive is toast\\n\");\n                return result;\n            }\n\n            pEntry->setLFHOffset(pEntry->getLFHOffset() - adjust);\n        }\n    }\n\n    /*\n     * Fix EOCD info.  We have to wait until the end to do some of this\n     * because we use mCentralDirOffset to determine \"span\" for the\n     * last entry.\n     */\n    mEOCD.mCentralDirOffset -= adjust;\n    mEOCD.mNumEntries -= delCount;\n    mEOCD.mTotalNumEntries -= delCount;\n    mEOCD.mCentralDirSize = 0;  // mark invalid; set by flush()\n\n    assert(mEOCD.mNumEntries == mEOCD.mTotalNumEntries);\n    assert(mEOCD.mNumEntries == count);\n\n    return result;\n}\n\n/*\n * Works like memmove(), but on pieces of a file.\n */\nstatus_t ZipFile::filemove(FILE* fp, off_t dst, off_t src, size_t n)\n{\n    if (dst == src || n <= 0)\n        return NO_ERROR;\n\n    unsigned char readBuf[32768];\n\n    if (dst < src) {\n        /* shift stuff toward start of file; must read from start */\n        while (n != 0) {\n            size_t getSize = sizeof(readBuf);\n            if (getSize > n)\n                getSize = n;\n\n            if (fseek(fp, (long) src, SEEK_SET) != 0) {\n                ALOGD(\"filemove src seek %ld failed\\n\", (long) src);\n                return UNKNOWN_ERROR;\n            }\n\n            if (fread(readBuf, 1, getSize, fp) != getSize) {\n                ALOGD(\"filemove read %ld off=%ld failed\\n\",\n                    (long) getSize, (long) src);\n                return UNKNOWN_ERROR;\n            }\n\n            if (fseek(fp, (long) dst, SEEK_SET) != 0) {\n                ALOGD(\"filemove dst seek %ld failed\\n\", (long) dst);\n                return UNKNOWN_ERROR;\n            }\n\n            if (fwrite(readBuf, 1, getSize, fp) != getSize) {\n                ALOGD(\"filemove write %ld off=%ld failed\\n\",\n                    (long) getSize, (long) dst);\n                return UNKNOWN_ERROR;\n            }\n\n            src += getSize;\n            dst += getSize;\n            n -= getSize;\n        }\n    } else {\n        /* shift stuff toward end of file; must read from end */\n        assert(false);      // write this someday, maybe\n        return UNKNOWN_ERROR;\n    }\n\n    return NO_ERROR;\n}\n\n\n/*\n * Get the modification time from a file descriptor.\n */\ntime_t ZipFile::getModTime(int fd)\n{\n    struct stat sb;\n\n    if (fstat(fd, &sb) < 0) {\n        ALOGD(\"HEY: fstat on fd %d failed\\n\", fd);\n        return (time_t) -1;\n    }\n\n    return sb.st_mtime;\n}\n\n\n#if 0       /* this is a bad idea */\n/*\n * Get a copy of the Zip file descriptor.\n *\n * We don't allow this if the file was opened read-write because we tend\n * to leave the file contents in an uncertain state between calls to\n * flush().  The duplicated file descriptor should only be valid for reads.\n */\nint ZipFile::getZipFd(void) const\n{\n    if (!mReadOnly)\n        return INVALID_OPERATION;\n    assert(mZipFp != NULL);\n\n    int fd;\n    fd = dup(fileno(mZipFp));\n    if (fd < 0) {\n        ALOGD(\"didn't work, errno=%d\\n\", errno);\n    }\n\n    return fd;\n}\n#endif\n\n\n#if 0\n/*\n * Expand data.\n */\nbool ZipFile::uncompress(const ZipEntry* pEntry, void* buf) const\n{\n    return false;\n}\n#endif\n\n// free the memory when you're done\nvoid* ZipFile::uncompress(const ZipEntry* entry)\n{\n    size_t unlen = entry->getUncompressedLen();\n    size_t clen = entry->getCompressedLen();\n\n    void* buf = malloc(unlen);\n    if (buf == NULL) {\n        return NULL;\n    }\n\n    fseek(mZipFp, 0, SEEK_SET);\n\n    off_t offset = entry->getFileOffset();\n    if (fseek(mZipFp, offset, SEEK_SET) != 0) {\n        goto bail;\n    }\n\n    switch (entry->getCompressionMethod())\n    {\n        case ZipEntry::kCompressStored: {\n            ssize_t amt = fread(buf, 1, unlen, mZipFp);\n            if (amt != (ssize_t)unlen) {\n                goto bail;\n            }\n#if 0\n            printf(\"data...\\n\");\n            const unsigned char* p = (unsigned char*)buf;\n            const unsigned char* end = p+unlen;\n            for (int i=0; i<32 && p < end; i++) {\n                printf(\"0x%08x \", (int)(offset+(i*0x10)));\n                for (int j=0; j<0x10 && p < end; j++) {\n                    printf(\" %02x\", *p);\n                    p++;\n                }\n                printf(\"\\n\");\n            }\n#endif\n\n            }\n            break;\n        case ZipEntry::kCompressDeflated: {\n            if (!ZipUtils::inflateToBuffer(mZipFp, buf, unlen, clen)) {\n                goto bail;\n            }\n            }\n            break;\n        default:\n            goto bail;\n    }\n    return buf;\n\nbail:\n    free(buf);\n    return NULL;\n}\n\n\n/*\n * ===========================================================================\n *      ZipFile::EndOfCentralDir\n * ===========================================================================\n */\n\n/*\n * Read the end-of-central-dir fields.\n *\n * \"buf\" should be positioned at the EOCD signature, and should contain\n * the entire EOCD area including the comment.\n */\nstatus_t ZipFile::EndOfCentralDir::readBuf(const unsigned char* buf, int len)\n{\n    /* don't allow re-use */\n    assert(mComment == NULL);\n\n    if (len < kEOCDLen) {\n        /* looks like ZIP file got truncated */\n        ALOGD(\" Zip EOCD: expected >= %d bytes, found %d\\n\",\n            kEOCDLen, len);\n        return INVALID_OPERATION;\n    }\n\n    /* this should probably be an assert() */\n    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature)\n        return UNKNOWN_ERROR;\n\n    mDiskNumber = ZipEntry::getShortLE(&buf[0x04]);\n    mDiskWithCentralDir = ZipEntry::getShortLE(&buf[0x06]);\n    mNumEntries = ZipEntry::getShortLE(&buf[0x08]);\n    mTotalNumEntries = ZipEntry::getShortLE(&buf[0x0a]);\n    mCentralDirSize = ZipEntry::getLongLE(&buf[0x0c]);\n    mCentralDirOffset = ZipEntry::getLongLE(&buf[0x10]);\n    mCommentLen = ZipEntry::getShortLE(&buf[0x14]);\n\n    // TODO: validate mCentralDirOffset\n\n    if (mCommentLen > 0) {\n        if (kEOCDLen + mCommentLen > len) {\n            ALOGD(\"EOCD(%d) + comment(%d) exceeds len (%d)\\n\",\n                kEOCDLen, mCommentLen, len);\n            return UNKNOWN_ERROR;\n        }\n        mComment = new unsigned char[mCommentLen];\n        memcpy(mComment, buf + kEOCDLen, mCommentLen);\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Write an end-of-central-directory section.\n */\nstatus_t ZipFile::EndOfCentralDir::write(FILE* fp)\n{\n    unsigned char buf[kEOCDLen];\n\n    ZipEntry::putLongLE(&buf[0x00], kSignature);\n    ZipEntry::putShortLE(&buf[0x04], mDiskNumber);\n    ZipEntry::putShortLE(&buf[0x06], mDiskWithCentralDir);\n    ZipEntry::putShortLE(&buf[0x08], mNumEntries);\n    ZipEntry::putShortLE(&buf[0x0a], mTotalNumEntries);\n    ZipEntry::putLongLE(&buf[0x0c], mCentralDirSize);\n    ZipEntry::putLongLE(&buf[0x10], mCentralDirOffset);\n    ZipEntry::putShortLE(&buf[0x14], mCommentLen);\n\n    if (fwrite(buf, 1, kEOCDLen, fp) != kEOCDLen)\n        return UNKNOWN_ERROR;\n    if (mCommentLen > 0) {\n        assert(mComment != NULL);\n        if (fwrite(mComment, mCommentLen, 1, fp) != mCommentLen)\n            return UNKNOWN_ERROR;\n    }\n\n    return NO_ERROR;\n}\n\n/*\n * Dump the contents of an EndOfCentralDir object.\n */\nvoid ZipFile::EndOfCentralDir::dump(void) const\n{\n    ALOGD(\" EndOfCentralDir contents:\\n\");\n    ALOGD(\"  diskNum=%u diskWCD=%u numEnt=%u totalNumEnt=%u\\n\",\n        mDiskNumber, mDiskWithCentralDir, mNumEntries, mTotalNumEntries);\n    ALOGD(\"  centDirSize=%lu centDirOff=%lu commentLen=%u\\n\",\n        mCentralDirSize, mCentralDirOffset, mCommentLen);\n}\n\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/ZipFile.h",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//\n// General-purpose Zip archive access.  This class allows both reading and\n// writing to Zip archives, including deletion of existing entries.\n//\n#ifndef __LIBS_ZIPFILE_H\n#define __LIBS_ZIPFILE_H\n\n#include <utils/Vector.h>\n#include <utils/Errors.h>\n#include <stdio.h>\n\n#include \"ZipEntry.h\"\n\nnamespace android {\n\n/*\n * Manipulate a Zip archive.\n *\n * Some changes will not be visible in the until until \"flush\" is called.\n *\n * The correct way to update a file archive is to make all changes to a\n * copy of the archive in a temporary file, and then unlink/rename over\n * the original after everything completes.  Because we're only interested\n * in using this for packaging, we don't worry about such things.  Crashing\n * after making changes and before flush() completes could leave us with\n * an unusable Zip archive.\n */\nclass ZipFile {\npublic:\n    ZipFile(void)\n      : mZipFp(NULL), mReadOnly(false), mNeedCDRewrite(false)\n      {}\n    ~ZipFile(void) {\n        if (!mReadOnly)\n            flush();\n        if (mZipFp != NULL)\n            fclose(mZipFp);\n        discardEntries();\n    }\n\n    /*\n     * Open a new or existing archive.\n     */\n    enum {\n        kOpenReadOnly   = 0x01,\n        kOpenReadWrite  = 0x02,\n        kOpenCreate     = 0x04,     // create if it doesn't exist\n        kOpenTruncate   = 0x08,     // if it exists, empty it\n    };\n    status_t open(const char* zipFileName, int flags);\n\n    /*\n     * Add a file to the end of the archive.  Specify whether you want the\n     * library to try to store it compressed.\n     *\n     * If \"storageName\" is specified, the archive will use that instead\n     * of \"fileName\".\n     *\n     * If there is already an entry with the same name, the call fails.\n     * Existing entries with the same name must be removed first.\n     *\n     * If \"ppEntry\" is non-NULL, a pointer to the new entry will be returned.\n     */\n    status_t add(const char* fileName, int compressionMethod,\n        ZipEntry** ppEntry)\n    {\n        return add(fileName, fileName, compressionMethod, ppEntry);\n    }\n    status_t add(const char* fileName, const char* storageName,\n        int compressionMethod, ZipEntry** ppEntry)\n    {\n        return addCommon(fileName, NULL, 0, storageName,\n                         ZipEntry::kCompressStored,\n                         compressionMethod, ppEntry);\n    }\n\n    /*\n     * Add a file that is already compressed with gzip.\n     *\n     * If \"ppEntry\" is non-NULL, a pointer to the new entry will be returned.\n     */\n    status_t addGzip(const char* fileName, const char* storageName,\n        ZipEntry** ppEntry)\n    {\n        return addCommon(fileName, NULL, 0, storageName,\n                         ZipEntry::kCompressDeflated,\n                         ZipEntry::kCompressDeflated, ppEntry);\n    }\n\n    /*\n     * Add a file from an in-memory data buffer.\n     *\n     * If \"ppEntry\" is non-NULL, a pointer to the new entry will be returned.\n     */\n    status_t add(const void* data, size_t size, const char* storageName,\n        int compressionMethod, ZipEntry** ppEntry)\n    {\n        return addCommon(NULL, data, size, storageName,\n                         ZipEntry::kCompressStored,\n                         compressionMethod, ppEntry);\n    }\n\n    /*\n     * Add an entry by copying it from another zip file.  If \"padding\" is\n     * nonzero, the specified number of bytes will be added to the \"extra\"\n     * field in the header.\n     *\n     * If \"ppEntry\" is non-NULL, a pointer to the new entry will be returned.\n     */\n    status_t add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,\n        int padding, ZipEntry** ppEntry);\n\n    /*\n     * Mark an entry as having been removed.  It is not actually deleted\n     * from the archive or our internal data structures until flush() is\n     * called.\n     */\n    status_t remove(ZipEntry* pEntry);\n\n    /*\n     * Flush changes.  If mNeedCDRewrite is set, this writes the central dir.\n     */\n    status_t flush(void);\n\n    /*\n     * Expand the data into the buffer provided.  The buffer must hold\n     * at least <uncompressed len> bytes.  Variation expands directly\n     * to a file.\n     *\n     * Returns \"false\" if an error was encountered in the compressed data.\n     */\n    //bool uncompress(const ZipEntry* pEntry, void* buf) const;\n    //bool uncompress(const ZipEntry* pEntry, FILE* fp) const;\n    void* uncompress(const ZipEntry* pEntry);\n\n    /*\n     * Get an entry, by name.  Returns NULL if not found.\n     *\n     * Does not return entries pending deletion.\n     */\n    ZipEntry* getEntryByName(const char* fileName) const;\n\n    /*\n     * Get the Nth entry in the archive.\n     *\n     * This will return an entry that is pending deletion.\n     */\n    int getNumEntries(void) const { return mEntries.size(); }\n    ZipEntry* getEntryByIndex(int idx) const;\n\nprivate:\n    /* these are private and not defined */\n    ZipFile(const ZipFile& src);\n    ZipFile& operator=(const ZipFile& src);\n\n    class EndOfCentralDir {\n    public:\n        EndOfCentralDir(void) :\n            mDiskNumber(0),\n            mDiskWithCentralDir(0),\n            mNumEntries(0),\n            mTotalNumEntries(0),\n            mCentralDirSize(0),\n            mCentralDirOffset(0),\n            mCommentLen(0),\n            mComment(NULL)\n            {}\n        virtual ~EndOfCentralDir(void) {\n            delete[] mComment;\n        }\n\n        status_t readBuf(const unsigned char* buf, int len);\n        status_t write(FILE* fp);\n\n        //unsigned long   mSignature;\n        unsigned short  mDiskNumber;\n        unsigned short  mDiskWithCentralDir;\n        unsigned short  mNumEntries;\n        unsigned short  mTotalNumEntries;\n        unsigned long   mCentralDirSize;\n        unsigned long   mCentralDirOffset;      // offset from first disk\n        unsigned short  mCommentLen;\n        unsigned char*  mComment;\n\n        enum {\n            kSignature      = 0x06054b50,\n            kEOCDLen        = 22,       // EndOfCentralDir len, excl. comment\n\n            kMaxCommentLen  = 65535,    // longest possible in ushort\n            kMaxEOCDSearch  = kMaxCommentLen + EndOfCentralDir::kEOCDLen,\n\n        };\n\n        void dump(void) const;\n    };\n\n\n    /* read all entries in the central dir */\n    status_t readCentralDir(void);\n\n    /* crunch deleted entries out */\n    status_t crunchArchive(void);\n\n    /* clean up mEntries */\n    void discardEntries(void);\n\n    /* common handler for all \"add\" functions */\n    status_t addCommon(const char* fileName, const void* data, size_t size,\n        const char* storageName, int sourceType, int compressionMethod,\n        ZipEntry** ppEntry);\n\n    /* copy all of \"srcFp\" into \"dstFp\" */\n    status_t copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32);\n    /* copy all of \"data\" into \"dstFp\" */\n    status_t copyDataToFp(FILE* dstFp,\n        const void* data, size_t size, unsigned long* pCRC32);\n    /* copy some of \"srcFp\" into \"dstFp\" */\n    status_t copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,\n        unsigned long* pCRC32);\n    /* like memmove(), but on parts of a single file */\n    status_t filemove(FILE* fp, off_t dest, off_t src, size_t n);\n    /* compress all of \"srcFp\" into \"dstFp\", using Deflate */\n    status_t compressFpToFp(FILE* dstFp, FILE* srcFp,\n        const void* data, size_t size, unsigned long* pCRC32);\n\n    /* get modification date from a file descriptor */\n    time_t getModTime(int fd);\n\n    /*\n     * We use stdio FILE*, which gives us buffering but makes dealing\n     * with files >2GB awkward.  Until we support Zip64, we're fine.\n     */\n    FILE*           mZipFp;             // Zip file pointer\n\n    /* one of these per file */\n    EndOfCentralDir mEOCD;\n\n    /* did we open this read-only? */\n    bool            mReadOnly;\n\n    /* set this when we trash the central dir */\n    bool            mNeedCDRewrite;\n\n    /*\n     * One ZipEntry per entry in the zip file.  I'm using pointers instead\n     * of objects because it's easier than making operator= work for the\n     * classes and sub-classes.\n     */\n    Vector<ZipEntry*>   mEntries;\n};\n\n}; // namespace android\n\n#endif // __LIBS_ZIPFILE_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/printapk.cpp",
    "content": "#include <utils/ResourceTypes.h>\n#include <utils/String8.h>\n#include <utils/String16.h>\n#include <zipfile/zipfile.h>\n#include <stdio.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <stdlib.h>\n\nusing namespace android;\n\nstatic int\nusage()\n{\n    fprintf(stderr,\n            \"usage: apk APKFILE\\n\"\n            \"\\n\"\n            \"APKFILE   an android packge file produced by aapt.\\n\"\n            );\n    return 1;\n}\n\n\nint\nmain(int argc, char** argv)\n{\n    const char* filename;\n    int fd;\n    ssize_t amt;\n    off_t size;\n    void* buf;\n    zipfile_t zip;\n    zipentry_t entry;\n    void* cookie;\n    void* resfile;\n    int bufsize;\n    int err;\n\n    if (argc != 2) {\n        return usage();\n    }\n\n    filename = argv[1];\n    fd = open(filename, O_RDONLY);\n    if (fd == -1) {\n        fprintf(stderr, \"apk: couldn't open file for read: %s\\n\", filename);\n        return 1;\n    }\n\n    size = lseek(fd, 0, SEEK_END);\n    amt = lseek(fd, 0, SEEK_SET);\n\n    if (size < 0 || amt < 0) {\n        fprintf(stderr, \"apk: error determining file size: %s\\n\", filename);\n        return 1;\n    }\n\n    buf = malloc(size);\n    if (buf == NULL) {\n        fprintf(stderr, \"apk: file too big: %s\\n\", filename);\n        return 1;\n    }\n\n    amt = read(fd, buf, size);\n    if (amt != size) {\n        fprintf(stderr, \"apk: error reading file: %s\\n\", filename);\n        return 1;\n    }\n\n    close(fd);\n\n    zip = init_zipfile(buf, size);\n    if (zip == NULL) {\n        fprintf(stderr, \"apk: file doesn't seem to be a zip file: %s\\n\",\n                filename);\n        return 1;\n    }\n\n    printf(\"files:\\n\");\n    cookie = NULL;\n    while ((entry = iterate_zipfile(zip, &cookie))) {\n        char* name = get_zipentry_name(entry);\n        printf(\"  %s\\n\", name);\n        free(name);\n    }\n\n    entry = lookup_zipentry(zip, \"resources.arsc\");\n    if (entry != NULL) {\n        size = get_zipentry_size(entry);\n        bufsize = size + (size / 1000) + 1;\n        resfile = malloc(bufsize);\n\n        err = decompress_zipentry(entry, resfile, bufsize);\n        if (err != 0) {\n            fprintf(stderr, \"apk: error decompressing resources.arsc\");\n            return 1;\n        }\n\n        ResTable res(resfile, size, resfile);\n        res.print();\n#if 0\n        size_t tableCount = res.getTableCount();\n        printf(\"Tables: %d\\n\", (int)tableCount);\n        for (size_t tableIndex=0; tableIndex<tableCount; tableIndex++) {\n            const ResStringPool* strings = res.getTableStringBlock(tableIndex);\n            size_t stringCount = strings->size();\n            for (size_t stringIndex=0; stringIndex<stringCount; stringIndex++) {\n                size_t len;\n                const char16_t* ch = strings->stringAt(stringIndex, &len);\n                String8 s(String16(ch, len));\n                printf(\"  [%3d] %s\\n\", (int)stringIndex, s.string());\n            }\n        }\n\n        size_t basePackageCount = res.getBasePackageCount();\n        printf(\"Base Packages: %d\\n\", (int)basePackageCount);\n        for (size_t bpIndex=0; bpIndex<basePackageCount; bpIndex++) {\n            const String16 ch = res.getBasePackageName(bpIndex);\n            String8 s = String8(ch);\n            printf(\"  [%3d] %s\\n\", (int)bpIndex, s.string());\n        }\n#endif\n    }\n\n\n    return 0;\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/pseudolocalize.cpp",
    "content": "#include \"pseudolocalize.h\"\n\nusing namespace std;\n\n// String basis to generate expansion\nstatic const String16 k_expansion_string = String16(\"one two three \"\n    \"four five six seven eight nine ten eleven twelve thirteen \"\n    \"fourteen fiveteen sixteen seventeen nineteen twenty\");\n\n// Special unicode characters to override directionality of the words\nstatic const String16 k_rlm = String16(\"\\xe2\\x80\\x8f\");\nstatic const String16 k_rlo = String16(\"\\xE2\\x80\\xae\");\nstatic const String16 k_pdf = String16(\"\\xE2\\x80\\xac\");\n\n// Placeholder marks\nstatic const String16 k_placeholder_open = String16(\"\\xc2\\xbb\");\nstatic const String16 k_placeholder_close = String16(\"\\xc2\\xab\");\n\nstatic const char*\npseudolocalize_char(const char16_t c)\n{\n    switch (c) {\n        case 'a':   return \"\\xc3\\xa5\";\n        case 'b':   return \"\\xc9\\x93\";\n        case 'c':   return \"\\xc3\\xa7\";\n        case 'd':   return \"\\xc3\\xb0\";\n        case 'e':   return \"\\xc3\\xa9\";\n        case 'f':   return \"\\xc6\\x92\";\n        case 'g':   return \"\\xc4\\x9d\";\n        case 'h':   return \"\\xc4\\xa5\";\n        case 'i':   return \"\\xc3\\xae\";\n        case 'j':   return \"\\xc4\\xb5\";\n        case 'k':   return \"\\xc4\\xb7\";\n        case 'l':   return \"\\xc4\\xbc\";\n        case 'm':   return \"\\xe1\\xb8\\xbf\";\n        case 'n':   return \"\\xc3\\xb1\";\n        case 'o':   return \"\\xc3\\xb6\";\n        case 'p':   return \"\\xc3\\xbe\";\n        case 'q':   return \"\\x51\";\n        case 'r':   return \"\\xc5\\x95\";\n        case 's':   return \"\\xc5\\xa1\";\n        case 't':   return \"\\xc5\\xa3\";\n        case 'u':   return \"\\xc3\\xbb\";\n        case 'v':   return \"\\x56\";\n        case 'w':   return \"\\xc5\\xb5\";\n        case 'x':   return \"\\xd1\\x85\";\n        case 'y':   return \"\\xc3\\xbd\";\n        case 'z':   return \"\\xc5\\xbe\";\n        case 'A':   return \"\\xc3\\x85\";\n        case 'B':   return \"\\xce\\xb2\";\n        case 'C':   return \"\\xc3\\x87\";\n        case 'D':   return \"\\xc3\\x90\";\n        case 'E':   return \"\\xc3\\x89\";\n        case 'G':   return \"\\xc4\\x9c\";\n        case 'H':   return \"\\xc4\\xa4\";\n        case 'I':   return \"\\xc3\\x8e\";\n        case 'J':   return \"\\xc4\\xb4\";\n        case 'K':   return \"\\xc4\\xb6\";\n        case 'L':   return \"\\xc4\\xbb\";\n        case 'M':   return \"\\xe1\\xb8\\xbe\";\n        case 'N':   return \"\\xc3\\x91\";\n        case 'O':   return \"\\xc3\\x96\";\n        case 'P':   return \"\\xc3\\x9e\";\n        case 'Q':   return \"\\x71\";\n        case 'R':   return \"\\xc5\\x94\";\n        case 'S':   return \"\\xc5\\xa0\";\n        case 'T':   return \"\\xc5\\xa2\";\n        case 'U':   return \"\\xc3\\x9b\";\n        case 'V':   return \"\\xce\\xbd\";\n        case 'W':   return \"\\xc5\\xb4\";\n        case 'X':   return \"\\xc3\\x97\";\n        case 'Y':   return \"\\xc3\\x9d\";\n        case 'Z':   return \"\\xc5\\xbd\";\n        case '!':   return \"\\xc2\\xa1\";\n        case '?':   return \"\\xc2\\xbf\";\n        case '$':   return \"\\xe2\\x82\\xac\";\n        default:    return NULL;\n    }\n}\n\nstatic bool\nis_possible_normal_placeholder_end(const char16_t c) {\n    switch (c) {\n        case 's': return true;\n        case 'S': return true;\n        case 'c': return true;\n        case 'C': return true;\n        case 'd': return true;\n        case 'o': return true;\n        case 'x': return true;\n        case 'X': return true;\n        case 'f': return true;\n        case 'e': return true;\n        case 'E': return true;\n        case 'g': return true;\n        case 'G': return true;\n        case 'a': return true;\n        case 'A': return true;\n        case 'b': return true;\n        case 'B': return true;\n        case 'h': return true;\n        case 'H': return true;\n        case '%': return true;\n        case 'n': return true;\n        default:  return false;\n    }\n}\n\nString16\npseudo_generate_expansion(const unsigned int length) {\n    String16 result = k_expansion_string;\n    const char16_t* s = result.string();\n    if (result.size() < length) {\n        result += String16(\" \");\n        result += pseudo_generate_expansion(length - result.size());\n    } else {\n        int ext = 0;\n        // Should contain only whole words, so looking for a space\n        for (unsigned int i = length + 1; i < result.size(); ++i) {\n          ++ext;\n          if (s[i] == ' ') {\n            break;\n          }\n        }\n        result.remove(length + ext, 0);\n    }\n    return result;\n}\n\n/**\n * Converts characters so they look like they've been localized.\n *\n * Note: This leaves escape sequences untouched so they can later be\n * processed by ResTable::collectString in the normal way.\n */\nString16\npseudolocalize_string(const String16& source)\n{\n    const char16_t* s = source.string();\n    String16 result;\n    const size_t I = source.size();\n    for (size_t i=0; i<I; i++) {\n        char16_t c = s[i];\n        if (c == '\\\\') {\n            // Escape syntax, no need to pseudolocalize\n            if (i<I-1) {\n                result += String16(\"\\\\\");\n                i++;\n                c = s[i];\n                switch (c) {\n                    case 'u':\n                        // this one takes up 5 chars\n                        result += String16(s+i, 5);\n                        i += 4;\n                        break;\n                    case 't':\n                    case 'n':\n                    case '#':\n                    case '@':\n                    case '?':\n                    case '\"':\n                    case '\\'':\n                    case '\\\\':\n                    default:\n                        result.append(&c, 1);\n                        break;\n                }\n            } else {\n                result.append(&c, 1);\n            }\n        } else if (c == '%') {\n            // Placeholder syntax, no need to pseudolocalize\n            result += k_placeholder_open;\n            bool end = false;\n            result.append(&c, 1);\n            while (!end && i < I) {\n                ++i;\n                c = s[i];\n                result.append(&c, 1);\n                if (is_possible_normal_placeholder_end(c)) {\n                    end = true;\n                } else if (c == 't') {\n                    ++i;\n                    c = s[i];\n                    result.append(&c, 1);\n                    end = true;\n                }\n            }\n            result += k_placeholder_close;\n        } else if (c == '<' || c == '&') {\n            // html syntax, no need to pseudolocalize\n            bool tag_closed = false;\n            while (!tag_closed && i < I) {\n                if (c == '&') {\n                    String16 escape_text;\n                    escape_text.append(&c, 1);\n                    bool end = false;\n                    size_t htmlCodePos = i;\n                    while (!end && htmlCodePos < I) {\n                        ++htmlCodePos;\n                        c = s[htmlCodePos];\n                        escape_text.append(&c, 1);\n                        // Valid html code\n                        if (c == ';') {\n                            end = true;\n                            i = htmlCodePos;\n                        }\n                        // Wrong html code\n                        else if (!((c == '#' ||\n                                 (c >= 'a' && c <= 'z') ||\n                                 (c >= 'A' && c <= 'Z') ||\n                                 (c >= '0' && c <= '9')))) {\n                            end = true;\n                        }\n                    }\n                    result += escape_text;\n                    if (escape_text != String16(\"&lt;\")) {\n                        tag_closed = true;\n                    }\n                    continue;\n                }\n                if (c == '>') {\n                    tag_closed = true;\n                    result.append(&c, 1);\n                    continue;\n                }\n                result.append(&c, 1);\n                i++;\n                c = s[i];\n            }\n        } else {\n            // This is a pure text that should be pseudolocalized\n            const char* p = pseudolocalize_char(c);\n            if (p != NULL) {\n                result += String16(p);\n            } else {\n                result.append(&c, 1);\n            }\n        }\n    }\n    return result;\n}\n\nString16\npseudobidi_string(const String16& source)\n{\n    const char16_t* s = source.string();\n    String16 result;\n    result += k_rlm;\n    result += k_rlo;\n    for (size_t i=0; i<source.size(); i++) {\n        char16_t c = s[i];\n        switch(c) {\n            case ' ': result += k_pdf;\n                      result += k_rlm;\n                      result.append(&c, 1);\n                      result += k_rlm;\n                      result += k_rlo;\n                      break;\n            default: result.append(&c, 1);\n                     break;\n        }\n    }\n    result += k_pdf;\n    result += k_rlm;\n    return result;\n}\n\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/pseudolocalize.h",
    "content": "#ifndef HOST_PSEUDOLOCALIZE_H\n#define HOST_PSEUDOLOCALIZE_H\n\n#include \"StringPool.h\"\n\n#include <string>\n\nString16 pseudolocalize_string(const String16& source);\n// Surrounds every word in the sentance with specific characters that makes\n// the word directionality RTL.\nString16 pseudobidi_string(const String16& source);\n// Generates expansion string based on the specified lenght.\n// Generated string could not be shorter that length, but it could be slightly\n// longer.\nString16 pseudo_generate_expansion(const unsigned int length);\n\n#endif // HOST_PSEUDOLOCALIZE_H\n\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/qsort_r_compat.c",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <stdlib.h>\n#include \"qsort_r_compat.h\"\n\n/*\n * Note: This code is only used on the host, and is primarily here for\n * Mac OS compatibility. Apparently, glibc and Apple's libc disagree on\n * the parameter order for qsort_r.\n */\n\n#if HAVE_BSD_QSORT_R\n\n/*\n * BSD qsort_r parameter order is as we have defined here.\n */\n\nvoid qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,\n        int (*compar)(void*, const void* , const void*)) {\n    qsort_r(base, nel, width, thunk, compar);\n}\n\n#elif HAVE_GNU_QSORT_R\n\n/*\n * GNU qsort_r parameter order places the thunk parameter last.\n */\n\nstruct compar_data {\n    void* thunk;\n    int (*compar)(void*, const void* , const void*);\n};\n\nstatic int compar_wrapper(const void* a, const void* b, void* data) {\n    struct compar_data* compar_data = (struct compar_data*)data;\n    return compar_data->compar(compar_data->thunk, a, b);\n}\n\nvoid qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,\n        int (*compar)(void*, const void* , const void*)) {\n    struct compar_data compar_data;\n    compar_data.thunk = thunk;\n    compar_data.compar = compar;\n    qsort_r(base, nel, width, compar_wrapper, &compar_data);\n}\n\n#else\n\n/*\n * Emulate qsort_r using thread local storage to access the thunk data.\n */\n\n#include <cutils/threads.h>\n\nstatic thread_store_t compar_data_key = THREAD_STORE_INITIALIZER;\n\nstruct compar_data {\n    void* thunk;\n    int (*compar)(void*, const void* , const void*);\n};\n\nstatic int compar_wrapper(const void* a, const void* b) {\n    struct compar_data* compar_data = (struct compar_data*)thread_store_get(&compar_data_key);\n    return compar_data->compar(compar_data->thunk, a, b);\n}\n\nvoid qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,\n        int (*compar)(void*, const void* , const void*)) {\n    struct compar_data compar_data;\n    compar_data.thunk = thunk;\n    compar_data.compar = compar;\n    thread_store_set(&compar_data_key, &compar_data, NULL);\n    qsort(base, nel, width, compar_wrapper);\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/qsort_r_compat.h",
    "content": "/*\n * Copyright (C) 2012 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * Provides a portable version of qsort_r, called qsort_r_compat, which is a\n * reentrant variant of qsort that passes a user data pointer to its comparator.\n * This implementation follows the BSD parameter convention.\n */\n\n#ifndef ___QSORT_R_COMPAT_H\n#define ___QSORT_R_COMPAT_H\n\n#include <stdlib.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nvoid qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,\n        int (*compar)(void*, const void* , const void* ));\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // ___QSORT_R_COMPAT_H\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/tests/AaptConfig_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <utils/String8.h>\n#include <gtest/gtest.h>\n\n#include \"AaptConfig.h\"\n#include \"ConfigDescription.h\"\n#include \"TestHelper.h\"\n\nusing android::String8;\n\nstatic ::testing::AssertionResult TestParse(const String8& input, ConfigDescription* config=NULL) {\n    if (AaptConfig::parse(String8(input), config)) {\n        return ::testing::AssertionSuccess() << input << \" was successfully parsed\";\n    }\n    return ::testing::AssertionFailure() << input << \" could not be parsed\";\n}\n\nstatic ::testing::AssertionResult TestParse(const char* input, ConfigDescription* config=NULL) {\n    return TestParse(String8(input), config);\n}\n\nTEST(AaptConfigTest, ParseFailWhenQualifiersAreOutOfOrder) {\n    EXPECT_FALSE(TestParse(\"en-sw600dp-ldrtl\"));\n    EXPECT_FALSE(TestParse(\"land-en\"));\n    EXPECT_FALSE(TestParse(\"hdpi-320dpi\"));\n}\n\nTEST(AaptConfigTest, ParseFailWhenQualifiersAreNotMatched) {\n    EXPECT_FALSE(TestParse(\"en-sw600dp-ILLEGAL\"));\n}\n\nTEST(AaptConfigTest, ParseFailWhenQualifiersHaveTrailingDash) {\n    EXPECT_FALSE(TestParse(\"en-sw600dp-land-\"));\n}\n\nTEST(AaptConfigTest, ParseBasicQualifiers) {\n    ConfigDescription config;\n    EXPECT_TRUE(TestParse(\"\", &config));\n    EXPECT_EQ(String8(\"\"), config.toString());\n\n    EXPECT_TRUE(TestParse(\"fr-land\", &config));\n    EXPECT_EQ(String8(\"fr-land\"), config.toString());\n\n    EXPECT_TRUE(TestParse(\"mcc310-pl-sw720dp-normal-long-port-night-\"\n                \"xhdpi-keyssoft-qwerty-navexposed-nonav\", &config));\n    EXPECT_EQ(String8(\"mcc310-pl-sw720dp-normal-long-port-night-\"\n                \"xhdpi-keyssoft-qwerty-navexposed-nonav-v13\"), config.toString());\n}\n\nTEST(AaptConfigTest, ParseLocales) {\n    ConfigDescription config;\n    EXPECT_TRUE(TestParse(\"en-rUS\", &config));\n    EXPECT_EQ(String8(\"en-US\"), config.toString());\n}\n\nTEST(AaptConfigTest, ParseQualifierAddedInApi13) {\n    ConfigDescription config;\n    EXPECT_TRUE(TestParse(\"sw600dp\", &config));\n    EXPECT_EQ(String8(\"sw600dp-v13\"), config.toString());\n\n    EXPECT_TRUE(TestParse(\"sw600dp-v8\", &config));\n    EXPECT_EQ(String8(\"sw600dp-v13\"), config.toString());\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/tests/AaptGroupEntry_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <utils/String8.h>\n#include <gtest/gtest.h>\n\n#include \"AaptAssets.h\"\n#include \"ResourceFilter.h\"\n#include \"TestHelper.h\"\n\nusing android::String8;\n\nstatic ::testing::AssertionResult TestParse(AaptGroupEntry& entry, const String8& dirName,\n        String8* outType) {\n    if (entry.initFromDirName(dirName, outType)) {\n        return ::testing::AssertionSuccess() << dirName << \" was successfully parsed\";\n    }\n    return ::testing::AssertionFailure() << dirName << \" could not be parsed\";\n}\n\nstatic ::testing::AssertionResult TestParse(AaptGroupEntry& entry, const char* input,\n        String8* outType) {\n    return TestParse(entry, String8(input), outType);\n}\n\nTEST(AaptGroupEntryTest, ParseNoQualifier) {\n    AaptGroupEntry entry;\n    String8 type;\n    EXPECT_TRUE(TestParse(entry, \"menu\", &type));\n    EXPECT_EQ(String8(\"menu\"), type);\n}\n\nTEST(AaptGroupEntryTest, ParseCorrectType) {\n    AaptGroupEntry entry;\n    String8 type;\n    EXPECT_TRUE(TestParse(entry, \"anim\", &type));\n    EXPECT_EQ(String8(\"anim\"), type);\n\n    EXPECT_TRUE(TestParse(entry, \"animator\", &type));\n    EXPECT_EQ(String8(\"animator\"), type);\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/tests/CrunchCache_test.cpp",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n#include <utils/String8.h>\n#include <iostream>\n#include <errno.h>\n\n#include \"CrunchCache.h\"\n#include \"FileFinder.h\"\n#include \"MockFileFinder.h\"\n#include \"CacheUpdater.h\"\n#include \"MockCacheUpdater.h\"\n\nusing namespace android;\nusing std::cout;\nusing std::endl;\n\nvoid expectEqual(int got, int expected, const char* desc) {\n    cout << \"Checking \" << desc << \": \";\n    cout << \"Got \" << got << \", expected \" << expected << \"...\";\n    cout << ( (got == expected) ? \"PASSED\" : \"FAILED\") << endl;\n    errno += ((got == expected) ? 0 : 1);\n}\n\nint main() {\n\n    errno = 0;\n\n    String8 source(\"res\");\n    String8 dest(\"res2\");\n\n    // Create data for MockFileFinder to feed to the cache\n    KeyedVector<String8, time_t> sourceData;\n    // This shouldn't be updated\n    sourceData.add(String8(\"res/drawable/hello.png\"),3);\n    // This should be updated\n    sourceData.add(String8(\"res/drawable/world.png\"),5);\n    // This should cause make directory to be called\n    sourceData.add(String8(\"res/drawable-cool/hello.png\"),3);\n\n    KeyedVector<String8, time_t> destData;\n    destData.add(String8(\"res2/drawable/hello.png\"),3);\n    destData.add(String8(\"res2/drawable/world.png\"),3);\n    // this should call delete\n    destData.add(String8(\"res2/drawable/dead.png\"),3);\n\n    // Package up data and create mock file finder\n    KeyedVector<String8, KeyedVector<String8,time_t> > data;\n    data.add(source,sourceData);\n    data.add(dest,destData);\n    FileFinder* ff = new MockFileFinder(data);\n    CrunchCache cc(source,dest,ff);\n\n    MockCacheUpdater* mcu = new MockCacheUpdater();\n    CacheUpdater* cu(mcu);\n\n    cout << \"Running Crunch...\";\n    int result = cc.crunch(cu);\n    cout << ((result > 0) ? \"PASSED\" : \"FAILED\") << endl;\n    errno += ((result > 0) ? 0 : 1);\n\n    const int EXPECTED_RESULT = 2;\n    expectEqual(result, EXPECTED_RESULT, \"number of files touched\");\n\n    cout << \"Checking calls to deleteFile and processImage:\" << endl;\n    const int EXPECTED_DELETES = 1;\n    const int EXPECTED_PROCESSED = 2;\n    // Deletes\n    expectEqual(mcu->deleteCount, EXPECTED_DELETES, \"deleteFile\");\n    // processImage\n    expectEqual(mcu->processCount, EXPECTED_PROCESSED, \"processImage\");\n\n    const int EXPECTED_OVERWRITES = 3;\n    result = cc.crunch(cu, true);\n    expectEqual(result, EXPECTED_OVERWRITES, \"number of files touched with overwrite\");\n    \\\n\n    if (errno == 0)\n        cout << \"ALL TESTS PASSED!\" << endl;\n    else\n        cout << errno << \" TESTS FAILED\" << endl;\n\n    delete ff;\n    delete cu;\n\n    // TESTS BELOW WILL GO AWAY SOON\n\n    String8 source2(\"ApiDemos/res\");\n    String8 dest2(\"ApiDemos/res2\");\n\n    FileFinder* sff = new SystemFileFinder();\n    CacheUpdater* scu = new SystemCacheUpdater();\n\n    CrunchCache scc(source2,dest2,sff);\n\n    scc.crunch(scu);\n}"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/tests/FileFinder_test.cpp",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n#include <utils/Vector.h>\n#include <utils/KeyedVector.h>\n#include <iostream>\n#include <cassert>\n#include <utils/String8.h>\n#include <utility>\n\n#include \"DirectoryWalker.h\"\n#include \"MockDirectoryWalker.h\"\n#include \"FileFinder.h\"\n\nusing namespace android;\n\nusing std::pair;\nusing std::cout;\nusing std::endl;\n\n\n\nint main()\n{\n\n    cout << \"\\n\\n STARTING FILE FINDER TESTS\" << endl;\n    String8 path(\"ApiDemos\");\n\n    // Storage to pass to findFiles()\n    KeyedVector<String8,time_t> testStorage;\n\n    // Mock Directory Walker initialization. First data, then sdw\n    Vector< pair<String8,time_t> > data;\n    data.push( pair<String8,time_t>(String8(\"hello.png\"),3) );\n    data.push( pair<String8,time_t>(String8(\"world.PNG\"),3) );\n    data.push( pair<String8,time_t>(String8(\"foo.pNg\"),3) );\n    // Neither of these should be found\n    data.push( pair<String8,time_t>(String8(\"hello.jpg\"),3) );\n    data.push( pair<String8,time_t>(String8(\".hidden.png\"),3));\n\n    DirectoryWalker* sdw = new StringDirectoryWalker(path,data);\n\n    // Extensions to look for\n    Vector<String8> exts;\n    exts.push(String8(\".png\"));\n\n    errno = 0;\n\n    // Make sure we get a valid mock directory walker\n    // Make sure we finish without errors\n    cout << \"Checking DirectoryWalker...\";\n    assert(sdw != NULL);\n    cout << \"PASSED\" << endl;\n\n    // Make sure we finish without errors\n    cout << \"Running findFiles()...\";\n    bool findStatus = FileFinder::findFiles(path,exts, testStorage, sdw);\n    assert(findStatus);\n    cout << \"PASSED\" << endl;\n\n    const size_t SIZE_EXPECTED = 3;\n    // Check to make sure we have the right number of things in our storage\n    cout << \"Running size comparison: Size is \" << testStorage.size() << \", \";\n    cout << \"Expected \" << SIZE_EXPECTED << \"...\";\n    if(testStorage.size() == SIZE_EXPECTED)\n        cout << \"PASSED\" << endl;\n    else {\n        cout << \"FAILED\" << endl;\n        errno++;\n    }\n\n    // Check to make sure that each of our found items has the right extension\n    cout << \"Checking Returned Extensions...\";\n    bool extsOkay = true;\n    String8 wrongExts;\n    for (size_t i = 0; i < SIZE_EXPECTED; ++i) {\n        String8 testExt(testStorage.keyAt(i).getPathExtension());\n        testExt.toLower();\n        if (testExt != \".png\") {\n            wrongExts += testStorage.keyAt(i);\n            wrongExts += \"\\n\";\n            extsOkay = false;\n        }\n    }\n    if (extsOkay)\n        cout << \"PASSED\" << endl;\n    else {\n        cout << \"FAILED\" << endl;\n        cout << \"The following extensions didn't check out\" << endl << wrongExts;\n    }\n\n    // Clean up\n    delete sdw;\n\n    if(errno == 0) {\n        cout << \"ALL TESTS PASSED\" << endl;\n    } else {\n        cout << errno << \" TESTS FAILED\" << endl;\n    }\n    return errno;\n}"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/tests/MockCacheUpdater.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n#ifndef MOCKCACHEUPDATER_H\n#define MOCKCACHEUPDATER_H\n\n#include <utils/String8.h>\n#include \"CacheUpdater.h\"\n\nusing namespace android;\n\nclass MockCacheUpdater : public CacheUpdater {\npublic:\n\n    MockCacheUpdater()\n        : deleteCount(0), processCount(0) { };\n\n    // Make sure all the directories along this path exist\n    virtual void ensureDirectoriesExist(String8 path)\n    {\n        // Nothing to do\n    };\n\n    // Delete a file\n    virtual void deleteFile(String8 path) {\n        deleteCount++;\n    };\n\n    // Process an image from source out to dest\n    virtual void processImage(String8 source, String8 dest) {\n        processCount++;\n    };\n\n    // DATA MEMBERS\n    int deleteCount;\n    int processCount;\nprivate:\n};\n\n#endif // MOCKCACHEUPDATER_H"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/tests/MockDirectoryWalker.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n#ifndef MOCKDIRECTORYWALKER_H\n#define MOCKDIRECTORYWALKER_H\n\n#include <utils/Vector.h>\n#include <utils/String8.h>\n#include <utility>\n#include \"DirectoryWalker.h\"\n\nusing namespace android;\nusing std::pair;\n\n// String8 Directory Walker\n// This is an implementation of the Directory Walker abstraction that is built\n// for testing.\n// Instead of system calls it queries a private data structure for the directory\n// entries. It takes a path and a map of filenames and their modification times.\n// functions are inlined since they are short and simple\n\nclass StringDirectoryWalker : public DirectoryWalker {\npublic:\n    StringDirectoryWalker(String8& path, Vector< pair<String8,time_t> >& data)\n        :  mPos(0), mBasePath(path), mData(data) {\n        //fprintf(stdout,\"StringDW built to mimic %s with %d files\\n\",\n        //       mBasePath.string());\n    };\n    // Default copy constructor, and destructor are fine\n\n    virtual bool openDir(String8 path) {\n        // If the user is trying to query the \"directory\" that this\n        // walker was initialized with, then return success. Else fail.\n        return path == mBasePath;\n    };\n    virtual bool openDir(const char* path) {\n        String8 p(path);\n        openDir(p);\n        return true;\n    };\n    // Advance to next entry in the Vector\n    virtual struct dirent* nextEntry() {\n        // Advance position and check to see if we're done\n        if (mPos >= mData.size())\n            return NULL;\n\n        // Place data in the entry descriptor. This class only returns files.\n        mEntry.d_type = DT_REG;\n        mEntry.d_ino = mPos;\n        // Copy chars from the string name to the entry name\n        size_t i = 0;\n        for (i; i < mData[mPos].first.size(); ++i)\n            mEntry.d_name[i] = mData[mPos].first[i];\n        mEntry.d_name[i] = '\\0';\n\n        // Place data in stats\n        mStats.st_ino = mPos;\n        mStats.st_mtime = mData[mPos].second;\n\n        // Get ready to move to the next entry\n        mPos++;\n\n        return &mEntry;\n    };\n    // Get the stats for the current entry\n    virtual struct stat*   entryStats() {\n        return &mStats;\n    };\n    // Nothing to do in clean up\n    virtual void closeDir() {\n        // Nothing to do\n    };\n    virtual DirectoryWalker* clone() {\n        return new StringDirectoryWalker(*this);\n    };\nprivate:\n    // Current position in the Vector\n    size_t mPos;\n    // Base path\n    String8 mBasePath;\n    // Data to simulate a directory full of files.\n    Vector< pair<String8,time_t> > mData;\n};\n\n#endif // MOCKDIRECTORYWALKER_H"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/tests/MockFileFinder.h",
    "content": "//\n// Copyright 2011 The Android Open Source Project\n//\n\n#ifndef MOCKFILEFINDER_H\n#define MOCKFILEFINDER_H\n\n#include <utils/Vector.h>\n#include <utils/KeyedVector.h>\n#include <utils/String8.h>\n\n#include \"DirectoryWalker.h\"\n\nusing namespace android;\n\nclass MockFileFinder : public FileFinder {\npublic:\n    MockFileFinder (KeyedVector<String8, KeyedVector<String8,time_t> >& files)\n        : mFiles(files)\n    {\n        // Nothing left to do\n    };\n\n    /**\n     * findFiles implementation for the abstraction.\n     * PRECONDITIONS:\n     *  No checking is done, so there MUST be an entry in mFiles with\n     *  path matching basePath.\n     *\n     * POSTCONDITIONS:\n     *  fileStore is filled with a copy of the data in mFiles corresponding\n     *  to the basePath.\n     */\n\n    virtual bool findFiles(String8 basePath, Vector<String8>& extensions,\n                           KeyedVector<String8,time_t>& fileStore,\n                           DirectoryWalker* dw)\n    {\n        const KeyedVector<String8,time_t>* payload(&mFiles.valueFor(basePath));\n        // Since KeyedVector doesn't implement swap\n        // (who doesn't use swap??) we loop and add one at a time.\n        for (size_t i = 0; i < payload->size(); ++i) {\n            fileStore.add(payload->keyAt(i),payload->valueAt(i));\n        }\n        return true;\n    }\n\nprivate:\n    // Virtual mapping between \"directories\" and the \"files\" contained\n    // in them\n    KeyedVector<String8, KeyedVector<String8,time_t> > mFiles;\n};\n\n\n#endif // MOCKFILEFINDER_H"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/tests/ResourceFilter_test.cpp",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#include <androidfw/ResourceTypes.h>\n#include <utils/String8.h>\n#include <gtest/gtest.h>\n\n#include \"AaptConfig.h\"\n#include \"ResourceFilter.h\"\n#include \"ConfigDescription.h\"\n\nusing android::String8;\n\n// In this context, 'Axis' represents a particular field in the configuration,\n// such as language or density.\n\nTEST(WeakResourceFilterTest, EmptyFilterMatchesAnything) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"\")));\n\n    ConfigDescription config;\n    config.density = 320;\n\n    EXPECT_TRUE(filter.match(config));\n\n    config.language[0] = 'f';\n    config.language[1] = 'r';\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, MatchesConfigWithUnrelatedAxis) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"fr\")));\n\n    ConfigDescription config;\n    config.density = 320;\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, MatchesConfigWithSameValueAxis) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"fr\")));\n\n    ConfigDescription config;\n    config.language[0] = 'f';\n    config.language[1] = 'r';\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, MatchesConfigWithSameValueAxisAndOtherUnrelatedAxis) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"fr\")));\n\n    ConfigDescription config;\n    config.language[0] = 'f';\n    config.language[1] = 'r';\n    config.density = 320;\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, MatchesConfigWithOneMatchingAxis) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"fr_FR,sw360dp,normal,en_US\")));\n\n    ConfigDescription config;\n    config.language[0] = 'e';\n    config.language[1] = 'n';\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, DoesNotMatchConfigWithDifferentValueAxis) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"fr\")));\n\n    ConfigDescription config;\n    config.language[0] = 'd';\n    config.language[1] = 'e';\n\n    EXPECT_FALSE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, DoesNotMatchWhenOneQualifierIsExplicitlyNotMatched) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"fr_FR,en_US,normal,large,xxhdpi,sw320dp\")));\n\n    ConfigDescription config;\n    config.language[0] = 'f';\n    config.language[1] = 'r';\n    config.smallestScreenWidthDp = 600;\n    config.version = 13;\n\n    EXPECT_FALSE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, MatchesSmallestWidthWhenSmaller) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"sw600dp\")));\n\n    ConfigDescription config;\n    config.language[0] = 'f';\n    config.language[1] = 'r';\n    config.smallestScreenWidthDp = 320;\n    config.version = 13;\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, MatchesConfigWithSameLanguageButNoRegionSpecified) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"de-rDE\")));\n\n    ConfigDescription config;\n    config.language[0] = 'd';\n    config.language[1] = 'e';\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, ParsesStandardLocaleOnlyString) {\n    WeakResourceFilter filter;\n    EXPECT_EQ(NO_ERROR, filter.parse(String8(\"de_DE\")));\n}\n\nTEST(WeakResourceFilterTest, IgnoresVersion) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"normal-v4\")));\n\n    ConfigDescription config;\n    config.smallestScreenWidthDp = 600;\n    config.version = 13;\n\n    // The configs don't match on any axis besides version, which should be ignored.\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(WeakResourceFilterTest, MatchesConfigWithRegion) {\n    WeakResourceFilter filter;\n    ASSERT_EQ(NO_ERROR, filter.parse(String8(\"kok,kok_IN,kok_419\")));\n\n    ConfigDescription config;\n    AaptLocaleValue val;\n    ASSERT_TRUE(val.initFromFilterString(String8(\"kok_IN\")));\n    val.writeTo(&config);\n\n    EXPECT_TRUE(filter.match(config));\n}\n\nTEST(StrongResourceFilterTest, MatchesDensities) {\n    ConfigDescription config;\n    config.density = 160;\n    config.version = 4;\n    std::set<ConfigDescription> configs;\n    configs.insert(config);\n\n    StrongResourceFilter filter(configs);\n\n    ConfigDescription expectedConfig;\n    expectedConfig.density = 160;\n    expectedConfig.version = 4;\n    ASSERT_TRUE(filter.match(expectedConfig));\n}\n\nTEST(StrongResourceFilterTest, MatchOnlyMdpiAndExcludeAllOthers) {\n    std::set<ConfigDescription> configsToMatch;\n    ConfigDescription config;\n    config.density = 160;\n    config.version = 4;\n    configsToMatch.insert(config);\n\n    std::set<ConfigDescription> configsToNotMatch;\n    config.density = 480;\n    configsToNotMatch.insert(config);\n\n    AndResourceFilter filter;\n    filter.addFilter(new InverseResourceFilter(new StrongResourceFilter(configsToNotMatch)));\n    filter.addFilter(new StrongResourceFilter(configsToMatch));\n\n    ConfigDescription expectedConfig;\n    expectedConfig.density = 160;\n    expectedConfig.version = 4;\n    ASSERT_TRUE(filter.match(expectedConfig));\n}\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/tests/TestHelper.h",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#ifndef __TEST_HELPER_H\n#define __TEST_HELPER_H\n\n#include <utils/String8.h>\n\nnamespace android {\n\n/**\n * Stream operator for nicely printing String8's in gtest output.\n */\ninline std::ostream& operator<<(std::ostream& stream, const String8& str) {\n    return stream << str.string();\n}\n\n}\n\n#endif\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/tests/plurals/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.android.aapt.test.plurals\">\n\n</manifest>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/tests/plurals/res/values/strings.xml",
    "content": "<resources xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n    <string name=\"ok\">OK</string>\n    <plurals name=\"a_plural\">\n        <item quantity=\"one\">A dog</item>\n        <item quantity=\"other\">Some dogs</item>\n    </plurals>\n</resources>\n"
  },
  {
    "path": "atlas-aapt-old/frameworks/base/tools/aapt/tests/plurals/run.sh",
    "content": "TEST_DIR=tools/aapt/tests/plurals\nTEST_OUT_DIR=out/plurals_test\n\nrm -rf $TEST_OUT_DIR\nmkdir -p $TEST_OUT_DIR\nmkdir -p $TEST_OUT_DIR/java\n\n#gdb --args \\\naapt package -v -x -m -z  -J $TEST_OUT_DIR/java -M $TEST_DIR/AndroidManifest.xml \\\n             -I out/target/common/obj/APPS/framework-res_intermediates/package-export.apk \\\n             -P $TEST_OUT_DIR/public_resources.xml \\\n             -S $TEST_DIR/res\n\necho\necho \"==================== FILES CREATED ==================== \"\nfind $TEST_OUT_DIR -type f\n"
  },
  {
    "path": "atlas-core/.gitignore",
    "content": "*.iml\n.gradle\n.idea/\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n!.idea/codeStyleSettings.xml\n.DS_Store\n/build\n/captures\n.vscode/\n\n# Taken from Android.gitignore https://github.com/github/gitignore/blob/master/Android.gitignore\n#\n# Built application files\n*.apk\n*.ap_\n\n# Files for the Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# Intellij\n*.iml\n"
  },
  {
    "path": "atlas-core/README.md",
    "content": "## atlas-core\n\nAtlas-core is the client side runtime library in Atlas framework, the core's duty is to manage all bundles installation, operation, and update after application installed, When the client starts, the entrance is AtlasBridgeApplication (build process automatically replace), responsible for the operation of the container run, and start business specific Application code.\n\n### main function\n\nAtlas-core starts, all of the bundle installation based on runtime, on-demand loaded by the container itself, at the same time, there are two tools allow direct call external at runtime to accomplish a specific function:\n\n1. RuntimeVariables.java: provides some commonly used variables are easy to use, such as application, currentprocess, etc.\n2. Atlas.java: provide some useful methods for external runtime, reference when using Atlas inside for public use block method\n\n###  key classes\n\nIn addition to the above two classes and associated use some of the classes, the other type of container used internal operation, direct call at runtime is not recommended or modify the contents of the inside, the following basic mainly introduces several key classes:\n\n1. AtlasBundleInfoManager : using bundleinfo generated by parsing packaging files, manage inventory of all bundles in the information, component when trigger the bundle of routing through the list class bundle lookup.\n\n2. BaselineInfoManager: BaselineInfoManager: application, after dynamic deployment BaselinfInfoManager record the latest version , and all the bundles of the change of version, when the bundle loading by BaselineInfoManager for further checking, dynamic deployment failure will trigger version rollback also depends on the manager.\n\n3. DelegateClassLoader: replacing the original PathClassloader, taking it as a parent, is responsible for all bundleclassloader routing, itself is not responsible for the real class loading\n\n4. DelegateResource：run-time globally unique resource, each bundle installation update DelegateResources corresponding AssetsManager gives effect to its own resources\n\n5. BundleImpl BundleArchive  BundleArchiveRevision: each runtime Bundle corresponding to an instance of BundleImpl , and Archive classes are used to bundle version of arbitration to choose matching, currentRevision record current bundle in the inside of the file system content\n\n6. KernalBundle & KernalBunleArchive: imitate the structure of the bundle, the host dynamic deployment occurs to the load in the form of KernalBundle dynamic deployment inside the host part of the updated content, ensure the runtime can cover the original logic in order to satisfy the host content dynamic update capability\n\n7. InstrumetionHook、ActivityManagerHook : those tools injection by hook or replace the android framework, guarantee the run-time correctly trigger a bundle installation, running task\n"
  },
  {
    "path": "atlas-core/README.zh_cn.md",
    "content": "## atlas-core\n\nAtlas-core 是Atlas框架端侧的运行库，构建产生的产物在应用安装后由core负责管理所有bundle的安装、运行、更新等内容，客户端启动后，入口为AtlasBridgeApplication（构建过程自动替换），负责atlas自身容器的运行，启动后开始执行业务代码具体的Application。\n\n### 主要功能\n\nAtlas-core启动后，所有的bundle安装基于运行时的情况按需加载，这个由容器自身完成；同时容器有两个工具类在运行时允许外部进行直接调用以完成特定的功能：\n\n1. RuntimeVariables.java:提供了常用的一些变量方便使用，比如application，currentprocess等.\n2. Atlas.java: 提供运行时外部可能需要用到的一些方法，使用时查阅Atlas里面 for public use区块的方法  \n\n### 关键类\n\n除了上述两个类以及关联用到的一些类外，其他的类容器内部运行使用，不建议在运行时直接调用或者修改里面的内容，下面基本介绍下主要几个关键类\n\n1.  AtlasBundleInfoManager : 通过解析打包生成的bundleinfo文件，管理整个apk内所有bundle的清单信息，component触发的bundle路由时通过清单类进行bundle查找\n2. BaselineInfoManager: 应用发生动态部署后，BaselinfInfoManager记录最新的版本以及所有发生变更的bundle的版本，在bundle加载时会通过BaselineInfoManager进行进一步校验，动态部署故障时也依托于manager触发版本回滚\n3. DelegateClassLoader： 替换原有PathClassloader，并以它为parent，负责对所有bundleclassloader的路由，本身不负责真正类的加载\n4. DelegateResource：运行期全局唯一的resource，每个bundle安装时更新DelegateResources对应的AssetsManager使自身资源生效\n5. BundleImpl BundleArchive  BundleArchiveRevision: 运行时每个Bundle对应一个BundleImpl的实例，同时Archive类用于仲裁选择匹配的bundle版本，currentRevision记录当前bundle在文件系统里面的内容\n6. KernalBundle & KernalBunleArchive ：模仿bundle的结构，host发生动态部署时以KernalBundle的方式去load 动态部署里面host部分的更新内容，保证运行时能够覆盖原有逻辑以满足host内容动态更新的能力\n7. InstrumetionHook、ActivityManagerHook 等其他工具类以hook或者替换的方式注入android framework，保障运行期能够正确的触发bundle的安装，运行的任务\n"
  },
  {
    "path": "atlas-core/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'com.github.dcendents.android-maven'\napply plugin: 'com.jfrog.bintray'\n\ndef mini = getEnvValue(\"mini\", 'false')\ndef commitTag = getEnvValue(\"commitTag\", 'false')\n\nbuildscript {\n\n    repositories {\n        mavenCentral()\n        jcenter()\n        google()\n    }\n\n    dependencies {\n        classpath \"com.taobao.android:atlasplugin:3.0.1-rc55\"\n        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'\n        classpath \"com.github.dcendents:android-maven-gradle-plugin:1.4.1\"\n    }\n}\nrepositories {\n    mavenCentral()\n    jcenter()\n\n}\n\n\ngroup = 'com.taobao.android'\ndescription = \"\"\"atlas_core\"\"\"\nString postFix = mini=='true' ? \"-mini\" : \"\";\n\n\nversion \"5.1.0.9-rc26\"\n\n\nString getEnvValue(key, defValue) {\n    def val = System.getProperty(key);\n    if (null != val) {\n        return val;\n    }\n    val = System.getenv(key);\n    if (null != val) {\n        return val;\n    }\n    return defValue;\n}\n\n\nsourceCompatibility = 1.7\ntargetCompatibility = 1.7\n\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    provided ('com.android.support:support-v4:25.3.1'){\n        transitive = true\n    }\n    provided 'com.android.support:support-annotations:24.1.1'\n\n}\n\ntasks.whenTaskAdded {task ->\n\n    if (task.name.startsWith(\"compile\") && task.name.endsWith(\"JavaWithJavac\")) {\n        task.doLast {\n            new File(task.getDestinationDir(),\"android/app/Instrumentation.class\").delete()\n            new File(task.getDestinationDir(),\"android/app/Instrumentation.class\").delete();\n            new File(task.getDestinationDir(),\"android/app/Instrumentation\\$ActivityMonitor.class\").delete();\n            new File(task.getDestinationDir(),\"android/app/Instrumentation\\$ActivityResult.class\").delete();\n            new File(task.getDestinationDir(),\"android/app/PreVerifier.class\").delete();\n            new File(task.getDestinationDir(),\"android/app/IActivityManager.class\").delete();\n            new File(task.getDestinationDir(),\"android/app/IActivityManager\\$1.class\").delete();\n            new File(task.getDestinationDir(),\"android/app/IActivityManager\\$ContentProviderHolder.class\").delete();\n            new File(task.getDestinationDir(),\"android/app/IActivityManager\\$ContentProviderHolder\\$1.class\").delete();\n            new File(task.getDestinationDir(),\"android/app/IActivityManager\\$1.class\").delete();\n            new File(task.getDestinationDir(), \"android/app/ContentProviderHolder.class\").delete();\n            new File(task.getDestinationDir(), \"android/app/ContentProviderHolder\\$1.class\").delete();\n            new File(task.getDestinationDir(),\"android/app/IServiceConnection.class\").delete();\n            new File(task.getDestinationDir(),\"android/app/IServiceConnection\\$Stub.class\").delete();\n            new File(task.getDestinationDir(),\"android/app/IServiceConnection\\$Stub\\$Proxy.class\").delete();\n            new File(task.getDestinationDir(),\"android/content/IContentProvider.class\").delete();\n            new File(task.getDestinationDir(),\"android/databinding/DataBindingComponent.class\").delete();\n            new File(task.getDestinationDir(),\"android/databinding/ViewDataBinding.class\").delete();\n            new File(task.getDestinationDir(),\"android/taobao/atlas/framework/FrameworkProperties.class\").delete();\n            new File(task.getDestinationDir(),\"android/taobao/atlas/bundleInfo/AtlasBundleInfoGenerator.class\").delete();\n        }\n    } else if(task.name.equals('mergeReleaseJniLibFolders')){\n        task.doLast {\n            if(mini=='true') {\n                new File(project.buildDir, \"intermediates/jniLibs/release/armeabi-v7a\").deleteDir()\n                new File(project.buildDir, \"intermediates/jniLibs/release/mips64\").deleteDir()\n                new File(project.buildDir, \"intermediates/jniLibs/release/arm64-v8a\").deleteDir()\n                new File(project.buildDir, \"intermediates/jniLibs/release/mips\").deleteDir()\n                new File(project.buildDir, \"intermediates/jniLibs/release/x86\").deleteDir()\n                new File(project.buildDir, \"intermediates/jniLibs/release/x86_64\").deleteDir()\n            }\n\n        }\n    }\n\n//    if(task.name == \"bintrayUpload\"){\n//        task.doFirst{\n//            println \"tag has been created!\"\n//        }\n//\n//        task.doLast {\n//            String newTag = \"v${version}\"\n//            println \"new Tag is ${newTag}\"\n//            \"git tag v${version}\".execute()\n//            \"git push origin v${version}\".execute()\n//            println \"tag v${version} has been created!\"\n//        }\n//    }\n\n}\n\n\nproject.gradle.buildFinished{\n    if(commitTag=='true') {\n        \"git tag v${version}\".execute()\n        \"git push origin v${version}\".execute()\n        \"git push origin v${version}\".execute()\n        println \"tag v${version} has been created!\"\n    }\n}\n\n\n\n\n\nandroid {\n    compileSdkVersion 28\n    buildToolsVersion '26.0.2'\n    lintOptions {\n        abortOnError false\n    }\n\n    sourceSets {\n        main {\n            jniLibs.srcDirs = ['libs']\n        }\n    }\n\n\n\n    defaultConfig {\n        consumerProguardFiles 'proguard.cfg'\n    }\n\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_7\n        targetCompatibility JavaVersion.VERSION_1_7\n    }\n\n    buildTypes {\n        release {\n            if(mini=='true') {\n                minifyEnabled true\n                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg'\n            }\n        }\n    }\n\n}\ndef siteUrl = 'https://github.com/alibaba/atlas'\n// 项目的主页\ndef gitUrl = 'https://github.com/alibaba/atlas'\n// Git仓库的url\n\ninstall {\n    repositories.mavenInstaller {\n        // This generates POM.xml with proper parameters\n        pom {\n            project {\n                packaging 'aar'\n                // Add your description here\n                name 'atlas' //项目描述\n                groupId 'com.taobao.android'\n                artifactId 'atlas_core'\n                url siteUrl\n                // Set your license\n                licenses {\n                    license {\n                        name 'The Apache Software License, Version 2.0'\n                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'\n                    }\n                }\n                developers {\n                    developer {\n                        id 'alibabaatlas' //填写的一些基本信息\n                        name 'atlas-framework'\n                        email 'alibabaatlasframework@gmail.com'\n                    }\n                }\n                scm {\n                    connection gitUrl\n                    developerConnection gitUrl\n                    url siteUrl\n                }\n            }\n        }\n    }\n}\n\n//task sourcesJar(type: Jar) {\n//    from('src/main/java') {\n//        include '**'\n//    }\n//    classifier = 'sources'\n//}\n\n//artifacts {\n//    archives sourcesJar\n//}\n\nProperties properties = new Properties()\nproperties.load(project.rootProject.file('local.properties').newDataInputStream())\nbintray {\n    user = project.hasProperty('bintray.user') ? project.getProperty('bintray.user') : properties.getProperty(\"bintray.user\")\n    key = project.hasProperty('bintray.apikey') ? project.getProperty('bintray.apikey') : properties.getProperty(\"bintray.apikey\")\n    configurations = ['archives']\n    pkg {\n        repo = \"maven\"\n        name = \"atlas\" //发布到JCenter上的项目名字\n        websiteUrl = \"https://github.com/alibaba/atlas\"\n        vcsUrl = gitUrl\n        licenses = [\"Apache-2.0\"]\n        publish = true\n    }\n}\n"
  },
  {
    "path": "atlas-core/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Wed Jan 06 10:55:30 CST 2016\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.1-all.zip\n"
  },
  {
    "path": "atlas-core/gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched.\nif $cygwin ; then\n    [ -n \"$JAVA_HOME\" ] && JAVA_HOME=`cygpath --unix \"$JAVA_HOME\"`\nfi\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >&-\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >&-\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "atlas-core/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windowz variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\ngoto execute\r\n\r\n:4NT_args\r\n@rem Get arguments from the 4NT Shell from JP Software\r\nset CMD_LINE_ARGS=%$\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "atlas-core/lint.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<lint>\n</lint>"
  },
  {
    "path": "atlas-core/proguard.cfg",
    "content": "-dontwarn java.awt.**\n-dontwarn com.taobao.**\n-dontwarn com.google.android.maps.**\n-dontwarn android.support.v7.widget.**\n-dontwarn android.support.v4.**\n-dontwarn android.taobao.atlas.**\n-dontwarn android.databinding.**\n-dontwarn android.app.**\n\n\n-keep class android.taobao.atlas.bridge.BridgeApplicationDelegate{*;}\n-keep class android.taobao.atlas.runtime.AtlasPreLauncher{*;}\n-keep class com.taobao.android.runtime.RuntimeUtils{*;}\n-keepclassmembers class com.taobao.android.runtime.RuntimeUtils{\n    public <methods>;\n}\n-keepclassmembers class * implements android.taobao.atlas.runtime.AtlasPreLauncher {\n    public <fields>;\n    public <methods>;\n}\n\n-keep class * implements android.taobao.atlas.runtime.AtlasPreLauncher {\n public <fields>;\n  public <methods>;\n}\n-keepclassmembers class android.taobao.atlas.**{\n    public <fields>;\n    public <methods>;\n}"
  },
  {
    "path": "atlas-core/project.properties",
    "content": "# This file is automatically generated by Android Tools.\n# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n#\n# This file must be checked in Version Control Systems.\n#\n# To customize properties used by the Ant build system edit\n# \"ant.properties\", and override values to adapt the script to your\n# project structure.\n#\n# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):\n#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt\n\n# Project target.\ntarget=android-18\nandroid.library=true\nproguard.config=proguard.cfg"
  },
  {
    "path": "atlas-core/publish.sh",
    "content": "#!/usr/bin/env bash\n./gradlew clean assemble bintray -DcommitTag=true\ngit push --follow-tags\n"
  },
  {
    "path": "atlas-core/settings.gradle",
    "content": "rootProject.name = 'atlas_core'\n"
  },
  {
    "path": "atlas-core/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"android.taobao.atlas\"\n    android:versionCode=\"1\"\n    android:versionName=\"1.0\" >\n\n    <uses-sdk\n        android:minSdkVersion=\"14\"\n        android:targetSdkVersion=\"23\" />\n\n    <application>\n\n    </application>\n\n\n\n</manifest>\n"
  },
  {
    "path": "atlas-core/src/main/aidl/android/app/IActivityManager/ContentProviderHolder.aidl",
    "content": "// ContentProviderHolder.aidl\npackage android.app.IActivityManager;\n\nparcelable ContentProviderHolder;\n"
  },
  {
    "path": "atlas-core/src/main/aidl/android/app/IServiceConnection.aidl",
    "content": "/* //device/java/android/android/app/IServiceConnection.aidl\n**\n** Copyright 2007, The Android Open Source Project\n**\n** Licensed under the Apache License, Version 2.0 (the \"License\"); \n** you may not use this file except in compliance with the License. \n** You may obtain a copy of the License at \n**\n**     http://www.apache.org/licenses/LICENSE-2.0 \n**\n** Unless required by applicable law or agreed to in writing, software \n** distributed under the License is distributed on an \"AS IS\" BASIS, \n** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n** See the License for the specific language governing permissions and \n** limitations under the License.\n*/\n\npackage android.app;\n\nimport android.content.ComponentName;\n\n/** @hide */\noneway interface IServiceConnection {\n    void connected(in ComponentName name, IBinder service);\n}\n\n"
  },
  {
    "path": "atlas-core/src/main/aidl/android/taobao/atlas/runtime/ApplicationInitException.java",
    "content": "package android.taobao.atlas.runtime;\n\n/**\n * 创建日期：2019/3/4 on 下午1:54\n * 描述:\n * 作者:zhayu.ll\n */\npublic class ApplicationInitException extends Exception {\n\n    public ApplicationInitException(Exception e) {\n        super(e);\n    }\n\n    public ApplicationInitException(String format) {\n        super(format);\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/aidl/android/taobao/atlas/runtime/newcomponent/service/IDelegateBinder.aidl",
    "content": "package android.taobao.atlas.runtime.newcomponent.service;\n\nimport android.content.Intent;\nimport android.content.ComponentName;\nimport android.content.pm.ServiceInfo;\nimport android.content.pm.ActivityInfo;\nimport android.app.IServiceConnection;\nimport android.content.pm.ProviderInfo;\nimport android.app.IActivityManager.ContentProviderHolder;\n\ninterface IDelegateBinder {\n\n    IBinder startService(in Intent serviceIntent,in ServiceInfo info);\n\n    IBinder bindService(in Intent serviceIntent,in IBinder activityToken,in IServiceConnection conn);\n\n    boolean unbindService(in IServiceConnection conn);\n\n    int stopService(in Intent serviceIntent);\n\n    Intent handleActivityStack(in Intent intent,in ActivityInfo info);\n\n    void handleReceiver(in Intent intent, in ActivityInfo info);\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/support/multidex/DexElementsMaker.java",
    "content": "package android.support.multidex;\n\nimport android.util.Log;\n\nimport java.io.File;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.ArrayList;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.FutureTask;\n\n/**\n * Created by jingchaoqinjc on 18/3/4.\n */\n\npublic class DexElementsMaker implements IDexElementsMaker {\n\n    private static final String TAG = \"DexElementsMaker\";\n\n    final ArrayList<File> files;\n    final IDexElementsMethodInvoker invoker;\n\n    DexElementsMaker(ArrayList<File> files, IDexElementsMethodInvoker invoker) {\n        this.files = files;\n        this.invoker = invoker;\n    }\n\n    @Override\n    public Object[] make() throws IllegalAccessException, InvocationTargetException,\n            NoSuchMethodException {\n\n        if (files.size() <= 1) {\n            return invoker.invoke(files);\n        }\n\n        //通过算法，将文件分解成大小相似的文件集，使得每个文件集在加载的时候时间相似\n        ArrayList<ArrayList<File>> filesList = makeFilesList();\n\n        int size = filesList.size();\n        FutureTask<Object[]>[] futureTasks = new FutureTask[size];\n        for (int i = 0; i < size; i++) {\n            futureTasks[i] = new FutureTask<Object[]>(new DexElementsCallable(i, filesList.get(i), invoker));\n        }\n\n        //其他任务在子线程里完成，加速加载\n        for (int i = 1; i < size; i++) {\n            new Thread(futureTasks[i]).start();\n        }\n        //一个任务在主线程完成，充分利用主线程资源\n        futureTasks[0].run();\n\n        ArrayList<Object[]> objectsList = new ArrayList<Object[]>();\n        int objectsTotalLength = 0;\n\n        try {\n            for (int i = 0; i < size; i++) {\n                Object[] objects = futureTasks[i].get();\n                if (objects == null) throw new RuntimeException(\"Illegal Action\");\n\n                objectsTotalLength += objects.length;\n                objectsList.add(objects);\n            }\n\n            Object[] objects = new Object[objectsTotalLength];\n\n            int offset = 0;\n            for (Object[] subObjects : objectsList) {\n                if (subObjects != null) {\n                    System.arraycopy(subObjects, 0, objects, offset, subObjects.length);\n                    offset += subObjects.length;\n                }\n            }\n\n            return objects;\n        } catch (Exception e) {\n\n        }\n\n        return invoker.invoke(files);\n    }\n\n    private long getMaxFileLength() {\n        long max = 0;\n        for (File file : files) {\n            if (file != null) {\n                long length = file.length();\n                max = length > max ? length : max;\n            }\n        }\n        return max;\n    }\n\n    private ArrayList<ArrayList<File>> makeFilesList() {\n        ArrayList<ArrayList<File>> filesList = new ArrayList<ArrayList<File>>();\n\n        long maxFileLength = getMaxFileLength();\n        long subTotalLength = 0;\n        ArrayList<File> subFiles = new ArrayList<File>();\n        filesList.add(subFiles);\n\n        for (File file : files) {\n            if (file != null) {\n                long subLength = file.length();\n                if (subLength + subTotalLength > maxFileLength) {\n                    subTotalLength = 0;\n                    subFiles = new ArrayList<File>();\n                    filesList.add(subFiles);\n                }\n\n                subFiles.add(file);\n                subTotalLength += subLength;\n            }\n        }\n\n        return filesList;\n    }\n\n    private static class DexElementsCallable implements Callable<Object[]> {\n        final int id;\n        final ArrayList<File> files;\n        final IDexElementsMethodInvoker invoker;\n\n        private DexElementsCallable(int id, ArrayList<File> files, IDexElementsMethodInvoker invoker) {\n            this.id = id;\n            this.files = files;\n            this.invoker = invoker;\n        }\n\n        @Override\n        public Object[] call() throws Exception {\n            try {\n                long startTime = System.currentTimeMillis();\n                Object[] objects = invoker.invoke(files);\n                long endTime = System.currentTimeMillis();\n                Log.i(TAG, \"cost \" + id + \" time:\" + (endTime - startTime));\n                return objects;\n            } catch (Exception e) {\n\n            }\n            return null;\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/support/multidex/DexElementsMethodInvokerV14.java",
    "content": "package android.support.multidex;\n\nimport java.io.File;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\n\n/**\n * Created by jingchaoqinjc on 18/3/4.\n */\n\npublic class DexElementsMethodInvokerV14 implements IDexElementsMethodInvoker {\n\n    final Object dexPathList;\n    final File optimizedDirectory;\n    final Method makeDexElements;\n\n    public DexElementsMethodInvokerV14(Object dexPathList, File optimizedDirectory, Method makeDexElements) {\n        this.dexPathList = dexPathList;\n        this.optimizedDirectory = optimizedDirectory;\n        this.makeDexElements = makeDexElements;\n    }\n\n    @Override\n    public Object[] invoke(ArrayList<File> files) throws InvocationTargetException, IllegalAccessException {\n        return (Object[]) makeDexElements.invoke(dexPathList, files, optimizedDirectory);\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/support/multidex/DexElementsMethodInvokerV19.java",
    "content": "package android.support.multidex;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\n\n/**\n * Created by jingchaoqinjc on 18/3/4.\n */\n\npublic class DexElementsMethodInvokerV19 implements IDexElementsMethodInvoker {\n\n    final Object dexPathList;\n    final File optimizedDirectory;\n    final ArrayList<IOException> suppressedExceptions;\n    final Method makeDexElements;\n\n    public DexElementsMethodInvokerV19(Object dexPathList, File optimizedDirectory, ArrayList<IOException> suppressedExceptions, Method makeDexElements) {\n        this.dexPathList = dexPathList;\n        this.optimizedDirectory = optimizedDirectory;\n        this.suppressedExceptions = suppressedExceptions;\n        this.makeDexElements = makeDexElements;\n    }\n\n    @Override\n    public Object[] invoke(ArrayList<File> files) throws InvocationTargetException, IllegalAccessException {\n        return (Object[]) makeDexElements.invoke(dexPathList, files, optimizedDirectory, suppressedExceptions);\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/support/multidex/IDexElementsMaker.java",
    "content": "package android.support.multidex;\n\nimport java.lang.reflect.InvocationTargetException;\n\n/**\n * Created by jingchaoqinjc on 18/3/4.\n */\n\npublic interface IDexElementsMaker {\n\n    Object[] make() throws IllegalAccessException, InvocationTargetException,\n            NoSuchMethodException;\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/support/multidex/IDexElementsMethodInvoker.java",
    "content": "package android.support.multidex;\n\nimport java.io.File;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.ArrayList;\n\n/**\n * Created by jingchaoqinjc on 18/3/4.\n */\n\npublic interface IDexElementsMethodInvoker {\n\n    public Object[] invoke(ArrayList<File> files) throws InvocationTargetException, IllegalAccessException;\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/support/multidex/MultiDex.java",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage android.support.multidex;\n\nimport android.app.Application;\nimport android.app.Instrumentation;\nimport android.content.Context;\nimport android.content.pm.ApplicationInfo;\nimport android.os.Build;\nimport android.util.Log;\n\nimport dalvik.system.DexFile;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.lang.reflect.Array;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.ListIterator;\nimport java.util.Set;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport java.util.zip.ZipFile;\n\n/**\n * MultiDex patches {@link Context#getClassLoader() the application context class\n * loader} in order to load classes from more than one dex file. The primary\n * {@code classes.dex} must contain the classes necessary for calling this\n * class methods. Secondary dex files named classes2.dex, classes3.dex... found\n * in the application apk will be added to the classloader after first call to\n * {@link #install(Context)}.\n * <p>\n * <p/>\n * This library provides compatibility for platforms with API level 4 through 20. This library does\n * nothing on newer versions of the platform which provide built-in support for secondary dex files.\n */\npublic final class MultiDex {\n\n    static final String TAG = \"MultiDex\";\n\n    private static final String OLD_SECONDARY_FOLDER_NAME = \"secondary-dexes\";\n\n    private static final String CODE_CACHE_NAME = \"code_cache\";\n\n    private static final String CODE_CACHE_SECONDARY_FOLDER_NAME = \"secondary-dexes\";\n\n    private static final int MAX_SUPPORTED_SDK_VERSION = 20;\n\n    private static final int MIN_SDK_VERSION = 4;\n\n    private static final int VM_WITH_MULTIDEX_VERSION_MAJOR = 2;\n\n    private static final int VM_WITH_MULTIDEX_VERSION_MINOR = 1;\n\n    private static final String NO_KEY_PREFIX = \"\";\n\n    private static final Set<File> installedApk = new HashSet<File>();\n\n    public static final boolean IS_VM_MULTIDEX_CAPABLE =\n            isVMMultidexCapable(System.getProperty(\"java.vm.version\"));\n\n    private MultiDex() {\n    }\n\n    /**\n     * Patches the application context class loader by appending extra dex files\n     * loaded from the application apk. This method should be called in the\n     * attachBaseContext of your {@link Application}, see\n     * {@link MultiDexApplication} for more explanation and an example.\n     *\n     * @param context application context.\n     * @throws RuntimeException if an error occurred preventing the classloader\n     *                          extension.\n     */\n    public static void install(Context context) {\n        Log.i(TAG, \"Installing application\");\n        if (IS_VM_MULTIDEX_CAPABLE) {\n            Log.i(TAG, \"VM has multidex support, MultiDex support library is disabled.\");\n            return;\n        }\n\n        if (Build.VERSION.SDK_INT < MIN_SDK_VERSION) {\n            throw new RuntimeException(\"MultiDex installation failed. SDK \" + Build.VERSION.SDK_INT\n                    + \" is unsupported. Min SDK version is \" + MIN_SDK_VERSION + \".\");\n        }\n\n        try {\n            ApplicationInfo applicationInfo = getApplicationInfo(context);\n            if (applicationInfo == null) {\n                Log.i(TAG, \"No ApplicationInfo available, i.e. running on a test Context:\"\n                        + \" MultiDex support library is disabled.\");\n                return;\n            }\n\n            doInstallation(context,\n                    new File(applicationInfo.sourceDir),\n                    new File(applicationInfo.dataDir),\n                    CODE_CACHE_SECONDARY_FOLDER_NAME,\n                    NO_KEY_PREFIX);\n\n        } catch (Exception e) {\n            Log.e(TAG, \"MultiDex installation failure\", e);\n            throw new RuntimeException(\"MultiDex installation failed (\" + e.getMessage() + \").\");\n        }\n        Log.i(TAG, \"install done\");\n    }\n\n    /**\n     * Patches the instrumentation context class loader by appending extra dex files\n     * loaded from the instrumentation apk and the application apk. This method should be called in\n     * the onCreate of your {@link Instrumentation}, see\n     * {@link com.android.test.runner.MultiDexTestRunner} for an example.\n     *\n     * @param instrumentationContext instrumentation context.\n     * @param targetContext          target application context.\n     * @throws RuntimeException if an error occurred preventing the classloader\n     *                          extension.\n     */\n    public static void installInstrumentation(Context instrumentationContext,\n                                              Context targetContext) {\n        Log.i(TAG, \"Installing instrumentation\");\n\n        if (IS_VM_MULTIDEX_CAPABLE) {\n            Log.i(TAG, \"VM has multidex support, MultiDex support library is disabled.\");\n            return;\n        }\n\n        if (Build.VERSION.SDK_INT < MIN_SDK_VERSION) {\n            throw new RuntimeException(\"MultiDex installation failed. SDK \" + Build.VERSION.SDK_INT\n                    + \" is unsupported. Min SDK version is \" + MIN_SDK_VERSION + \".\");\n        }\n        try {\n\n            ApplicationInfo instrumentationInfo = getApplicationInfo(instrumentationContext);\n            if (instrumentationInfo == null) {\n                Log.i(TAG, \"No ApplicationInfo available for instrumentation, i.e. running on a\"\n                        + \" test Context: MultiDex support library is disabled.\");\n                return;\n            }\n\n            ApplicationInfo applicationInfo = getApplicationInfo(targetContext);\n            if (applicationInfo == null) {\n                Log.i(TAG, \"No ApplicationInfo available, i.e. running on a test Context:\"\n                        + \" MultiDex support library is disabled.\");\n                return;\n            }\n\n            String instrumentationPrefix = instrumentationContext.getPackageName() + \".\";\n\n            File dataDir = new File(applicationInfo.dataDir);\n\n            doInstallation(targetContext,\n                    new File(instrumentationInfo.sourceDir),\n                    dataDir,\n                    instrumentationPrefix + CODE_CACHE_SECONDARY_FOLDER_NAME,\n                    instrumentationPrefix);\n\n            doInstallation(targetContext,\n                    new File(applicationInfo.sourceDir),\n                    dataDir,\n                    CODE_CACHE_SECONDARY_FOLDER_NAME,\n                    NO_KEY_PREFIX);\n        } catch (Exception e) {\n            Log.e(TAG, \"MultiDex installation failure\", e);\n            throw new RuntimeException(\"MultiDex installation failed (\" + e.getMessage() + \").\");\n        }\n        Log.i(TAG, \"Installation done\");\n    }\n\n    /**\n     * @param mainContext         context used to get filesDir, to save preference and to get the\n     *                            classloader to patch.\n     * @param sourceApk           Apk file.\n     * @param dataDir             data directory to use for code cache simulation.\n     * @param secondaryFolderName name of the folder for storing extractions.\n     * @param prefsKeyPrefix      prefix of all stored preference keys.\n     */\n    private static void doInstallation(Context mainContext, File sourceApk, File dataDir,\n                                       String secondaryFolderName, String prefsKeyPrefix) throws IOException,\n            IllegalArgumentException, IllegalAccessException, NoSuchFieldException,\n            InvocationTargetException, NoSuchMethodException {\n        synchronized (installedApk) {\n            if (installedApk.contains(sourceApk)) {\n                return;\n            }\n            installedApk.add(sourceApk);\n\n            if (Build.VERSION.SDK_INT > MAX_SUPPORTED_SDK_VERSION) {\n                Log.w(TAG, \"MultiDex is not guaranteed to work in SDK version \"\n                        + Build.VERSION.SDK_INT + \": SDK version higher than \"\n                        + MAX_SUPPORTED_SDK_VERSION + \" should be backed by \"\n                        + \"runtime with built-in multidex capabilty but it's not the \"\n                        + \"case here: java.vm.version=\\\"\"\n                        + System.getProperty(\"java.vm.version\") + \"\\\"\");\n            }\n\n            /* The patched class loader is expected to be a descendant of\n             * dalvik.system.BaseDexClassLoader. We modify its\n             * dalvik.system.DexPathList pathList field to append additional DEX\n             * file entries.\n             */\n            ClassLoader loader;\n            try {\n                loader = mainContext.getClassLoader();\n            } catch (RuntimeException e) {\n                /* Ignore those exceptions so that we don't break tests relying on Context like\n                 * a android.test.mock.MockContext or a android.content.ContextWrapper with a\n                 * null base Context.\n                 */\n                Log.w(TAG, \"Failure while trying to obtain Context class loader. \" +\n                        \"Must be running in test mode. Skip patching.\", e);\n                return;\n            }\n            if (loader == null) {\n                // Note, the context class loader is null when running Robolectric tests.\n                Log.e(TAG,\n                        \"Context class loader is null. Must be running in test mode. \"\n                                + \"Skip patching.\");\n                return;\n            }\n\n            try {\n                clearOldDexDir(mainContext);\n            } catch (Throwable t) {\n                Log.w(TAG, \"Something went wrong when trying to clear old MultiDex extraction, \"\n                        + \"continuing without cleaning.\", t);\n            }\n\n            File dexDir = getDexDir(mainContext, dataDir, secondaryFolderName);\n            List<? extends File> files =\n                    MultiDexExtractor.load(mainContext, sourceApk, dexDir, prefsKeyPrefix, false);\n            installSecondaryDexes(loader, dexDir, files);\n        }\n    }\n\n    private static ApplicationInfo getApplicationInfo(Context context) {\n        try {\n            /* Due to package install races it is possible for a process to be started from an old\n             * apk even though that apk has been replaced. Querying for ApplicationInfo by package\n             * name may return information for the new apk, leading to a runtime with the old main\n             * dex file and new secondary dex files. This leads to various problems like\n             * ClassNotFoundExceptions. Using context.getApplicationInfo() should result in the\n             * process having a consistent view of the world (even if it is of the old world). The\n             * package install races are eventually resolved and old processes are killed.\n             */\n            return context.getApplicationInfo();\n        } catch (RuntimeException e) {\n            /* Ignore those exceptions so that we don't break tests relying on Context like\n             * a android.test.mock.MockContext or a android.content.ContextWrapper with a null\n             * base Context.\n             */\n            Log.w(TAG, \"Failure while trying to obtain ApplicationInfo from Context. \" +\n                    \"Must be running in test mode. Skip patching.\", e);\n            return null;\n        }\n    }\n\n    /**\n     * Identifies if the current VM has a native support for multidex, meaning there is no need for\n     * additional installation by this library.\n     *\n     * @return true if the VM handles multidex\n     */\n    /* package visible for test */\n    static boolean isVMMultidexCapable(String versionString) {\n        boolean isMultidexCapable = false;\n        if (versionString != null) {\n            Matcher matcher = Pattern.compile(\"(\\\\d+)\\\\.(\\\\d+)(\\\\.\\\\d+)?\").matcher(versionString);\n            if (matcher.matches()) {\n                try {\n                    int major = Integer.parseInt(matcher.group(1));\n                    int minor = Integer.parseInt(matcher.group(2));\n                    isMultidexCapable = (major > VM_WITH_MULTIDEX_VERSION_MAJOR)\n                            || ((major == VM_WITH_MULTIDEX_VERSION_MAJOR)\n                            && (minor >= VM_WITH_MULTIDEX_VERSION_MINOR));\n                } catch (NumberFormatException e) {\n                    // let isMultidexCapable be false\n                }\n            }\n        }\n        Log.i(TAG, \"VM with version \" + versionString +\n                (isMultidexCapable ?\n                        \" has multidex support\" :\n                        \" does not have multidex support\"));\n        return isMultidexCapable;\n    }\n\n    private static void installSecondaryDexes(ClassLoader loader, File dexDir,\n                                              List<? extends File> files)\n            throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException,\n            InvocationTargetException, NoSuchMethodException, IOException {\n        if (!files.isEmpty()) {\n            if (Build.VERSION.SDK_INT >= 19) {\n                V19.install(loader, files, dexDir);\n            } else if (Build.VERSION.SDK_INT >= 14) {\n                V14.install(loader, files, dexDir);\n            } else {\n                V4.install(loader, files);\n            }\n        }\n    }\n\n    /**\n     * Locates a given field anywhere in the class inheritance hierarchy.\n     *\n     * @param instance an object to search the field into.\n     * @param name     field name\n     * @return a field object\n     * @throws NoSuchFieldException if the field cannot be located\n     */\n    private static Field findField(Object instance, String name) throws NoSuchFieldException {\n        for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {\n            try {\n                Field field = clazz.getDeclaredField(name);\n\n\n                if (!field.isAccessible()) {\n                    field.setAccessible(true);\n                }\n\n                return field;\n            } catch (NoSuchFieldException e) {\n                // ignore and search next\n            }\n        }\n\n        throw new NoSuchFieldException(\"Field \" + name + \" not found in \" + instance.getClass());\n    }\n\n    /**\n     * Locates a given method anywhere in the class inheritance hierarchy.\n     *\n     * @param instance       an object to search the method into.\n     * @param name           method name\n     * @param parameterTypes method parameter types\n     * @return a method object\n     * @throws NoSuchMethodException if the method cannot be located\n     */\n    private static Method findMethod(Object instance, String name, Class<?>... parameterTypes)\n            throws NoSuchMethodException {\n        for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {\n            try {\n                Method method = clazz.getDeclaredMethod(name, parameterTypes);\n\n\n                if (!method.isAccessible()) {\n                    method.setAccessible(true);\n                }\n\n                return method;\n            } catch (NoSuchMethodException e) {\n                // ignore and search next\n            }\n        }\n\n        throw new NoSuchMethodException(\"Method \" + name + \" with parameters \" +\n                Arrays.asList(parameterTypes) + \" not found in \" + instance.getClass());\n    }\n\n    /**\n     * Replace the value of a field containing a non null array, by a new array containing the\n     * elements of the original array plus the elements of extraElements.\n     *\n     * @param instance      the instance whose field is to be modified.\n     * @param fieldName     the field to modify.\n     * @param extraElements elements to append at the end of the array.\n     */\n    private static void expandFieldArray(Object instance, String fieldName,\n                                         Object[] extraElements) throws NoSuchFieldException, IllegalArgumentException,\n            IllegalAccessException {\n        Field jlrField = findField(instance, fieldName);\n        Object[] original = (Object[]) jlrField.get(instance);\n        Object[] combined = (Object[]) Array.newInstance(\n                original.getClass().getComponentType(), original.length + extraElements.length);\n        System.arraycopy(original, 0, combined, 0, original.length);\n        System.arraycopy(extraElements, 0, combined, original.length, extraElements.length);\n        jlrField.set(instance, combined);\n    }\n\n    private static void clearOldDexDir(Context context) throws Exception {\n        File dexDir = new File(context.getFilesDir(), OLD_SECONDARY_FOLDER_NAME);\n        if (dexDir.isDirectory()) {\n            Log.i(TAG, \"Clearing old secondary dex dir (\" + dexDir.getPath() + \").\");\n            File[] files = dexDir.listFiles();\n            if (files == null) {\n                Log.w(TAG, \"Failed to list secondary dex dir content (\" + dexDir.getPath() + \").\");\n                return;\n            }\n            for (File oldFile : files) {\n                Log.i(TAG, \"Trying to delete old file \" + oldFile.getPath() + \" of size \"\n                        + oldFile.length());\n                if (!oldFile.delete()) {\n                    Log.w(TAG, \"Failed to delete old file \" + oldFile.getPath());\n                } else {\n                    Log.i(TAG, \"Deleted old file \" + oldFile.getPath());\n                }\n            }\n            if (!dexDir.delete()) {\n                Log.w(TAG, \"Failed to delete secondary dex dir \" + dexDir.getPath());\n            } else {\n                Log.i(TAG, \"Deleted old secondary dex dir \" + dexDir.getPath());\n            }\n        }\n    }\n\n    private static File getDexDir(Context context, File dataDir, String secondaryFolderName)\n            throws IOException {\n        File cache = new File(dataDir, CODE_CACHE_NAME);\n        try {\n            mkdirChecked(cache);\n        } catch (IOException e) {\n            /* If we can't emulate code_cache, then store to filesDir. This means abandoning useless\n             * files on disk if the device ever updates to android 5+. But since this seems to\n             * happen only on some devices running android 2, this should cause no pollution.\n             */\n            cache = new File(context.getFilesDir(), CODE_CACHE_NAME);\n            mkdirChecked(cache);\n        }\n        File dexDir = new File(cache, secondaryFolderName);\n        mkdirChecked(dexDir);\n        return dexDir;\n    }\n\n    private static void mkdirChecked(File dir) throws IOException {\n        dir.mkdir();\n        if (!dir.isDirectory()) {\n            File parent = dir.getParentFile();\n            if (parent == null) {\n                Log.e(TAG, \"Failed to create dir \" + dir.getPath() + \". Parent file is null.\");\n            } else {\n                Log.e(TAG, \"Failed to create dir \" + dir.getPath() +\n                        \". parent file is a dir \" + parent.isDirectory() +\n                        \", a file \" + parent.isFile() +\n                        \", exists \" + parent.exists() +\n                        \", readable \" + parent.canRead() +\n                        \", writable \" + parent.canWrite());\n            }\n            throw new IOException(\"Failed to create directory \" + dir.getPath());\n        }\n    }\n\n    /**\n     * Installer for platform versions 19.\n     */\n    private static final class V19 {\n\n        private static void install(ClassLoader loader,\n                                    List<? extends File> additionalClassPathEntries,\n                                    File optimizedDirectory)\n                throws IllegalArgumentException, IllegalAccessException,\n                NoSuchFieldException, InvocationTargetException, NoSuchMethodException {\n            /* The patched class loader is expected to be a descendant of\n             * dalvik.system.BaseDexClassLoader. We modify its\n             * dalvik.system.DexPathList pathList field to append additional DEX\n             * file entries.\n             */\n            Field pathListField = findField(loader, \"pathList\");\n            Object dexPathList = pathListField.get(loader);\n            ArrayList<IOException> suppressedExceptions = new ArrayList<IOException>();\n            expandFieldArray(dexPathList, \"dexElements\", makeDexElements(dexPathList,\n                    new ArrayList<File>(additionalClassPathEntries), optimizedDirectory,\n                    suppressedExceptions));\n            if (suppressedExceptions.size() > 0) {\n                for (IOException e : suppressedExceptions) {\n                    Log.w(TAG, \"Exception in makeDexElement\", e);\n                }\n                Field suppressedExceptionsField =\n                        findField(dexPathList, \"dexElementsSuppressedExceptions\");\n                IOException[] dexElementsSuppressedExceptions =\n                        (IOException[]) suppressedExceptionsField.get(dexPathList);\n\n                if (dexElementsSuppressedExceptions == null) {\n                    dexElementsSuppressedExceptions =\n                            suppressedExceptions.toArray(\n                                    new IOException[suppressedExceptions.size()]);\n                } else {\n                    IOException[] combined =\n                            new IOException[suppressedExceptions.size() +\n                                    dexElementsSuppressedExceptions.length];\n                    suppressedExceptions.toArray(combined);\n                    System.arraycopy(dexElementsSuppressedExceptions, 0, combined,\n                            suppressedExceptions.size(), dexElementsSuppressedExceptions.length);\n                    dexElementsSuppressedExceptions = combined;\n                }\n\n                suppressedExceptionsField.set(dexPathList, dexElementsSuppressedExceptions);\n            }\n        }\n\n        /**\n         * A wrapper around\n         * {@code private static final dalvik.system.DexPathList#makeDexElements}.\n         */\n        private static Object[] makeDexElements(\n                Object dexPathList, ArrayList<File> files, File optimizedDirectory,\n                ArrayList<IOException> suppressedExceptions)\n                throws IllegalAccessException, InvocationTargetException,\n                NoSuchMethodException {\n            Method makeDexElements =\n                    findMethod(dexPathList, \"makeDexElements\", ArrayList.class, File.class,\n                            ArrayList.class);\n\n            IDexElementsMethodInvoker invoker = new DexElementsMethodInvokerV19(dexPathList, optimizedDirectory, suppressedExceptions, makeDexElements);\n            DexElementsMaker dexElementsMaker = new DexElementsMaker(files, invoker);\n\n            return dexElementsMaker.make();\n        }\n    }\n\n    /**\n     * Installer for platform versions 14, 15, 16, 17 and 18.\n     */\n    private static final class V14 {\n\n        private static void install(ClassLoader loader,\n                                    List<? extends File> additionalClassPathEntries,\n                                    File optimizedDirectory)\n                throws IllegalArgumentException, IllegalAccessException,\n                NoSuchFieldException, InvocationTargetException, NoSuchMethodException {\n            /* The patched class loader is expected to be a descendant of\n             * dalvik.system.BaseDexClassLoader. We modify its\n             * dalvik.system.DexPathList pathList field to append additional DEX\n             * file entries.\n             */\n            Field pathListField = findField(loader, \"pathList\");\n            Object dexPathList = pathListField.get(loader);\n            expandFieldArray(dexPathList, \"dexElements\", makeDexElements(dexPathList,\n                    new ArrayList<File>(additionalClassPathEntries), optimizedDirectory));\n        }\n\n        /**\n         * A wrapper around\n         * {@code private static final dalvik.system.DexPathList#makeDexElements}.\n         */\n        private static Object[] makeDexElements(\n                Object dexPathList, ArrayList<File> files, File optimizedDirectory)\n                throws IllegalAccessException, InvocationTargetException,\n                NoSuchMethodException {\n            Method makeDexElements =\n                    findMethod(dexPathList, \"makeDexElements\", ArrayList.class, File.class);\n\n            IDexElementsMethodInvoker invoker = new DexElementsMethodInvokerV14(dexPathList, optimizedDirectory, makeDexElements);\n            DexElementsMaker dexElementsMaker = new DexElementsMaker(files, invoker);\n\n            return dexElementsMaker.make();\n        }\n    }\n\n    /**\n     * Installer for platform versions 4 to 13.\n     */\n    private static final class V4 {\n        private static void install(ClassLoader loader,\n                                    List<? extends File> additionalClassPathEntries)\n                throws IllegalArgumentException, IllegalAccessException,\n                NoSuchFieldException, IOException {\n            /* The patched class loader is expected to be a descendant of\n             * dalvik.system.DexClassLoader. We modify its\n             * fields mPaths, mFiles, mZips and mDexs to append additional DEX\n             * file entries.\n             */\n            int extraSize = additionalClassPathEntries.size();\n\n            Field pathField = findField(loader, \"path\");\n\n            StringBuilder path = new StringBuilder((String) pathField.get(loader));\n            String[] extraPaths = new String[extraSize];\n            File[] extraFiles = new File[extraSize];\n            ZipFile[] extraZips = new ZipFile[extraSize];\n            DexFile[] extraDexs = new DexFile[extraSize];\n            for (ListIterator<? extends File> iterator = additionalClassPathEntries.listIterator();\n                 iterator.hasNext(); ) {\n                File additionalEntry = iterator.next();\n                String entryPath = additionalEntry.getAbsolutePath();\n                path.append(':').append(entryPath);\n                int index = iterator.previousIndex();\n                extraPaths[index] = entryPath;\n                extraFiles[index] = additionalEntry;\n                extraZips[index] = new ZipFile(additionalEntry);\n                extraDexs[index] = DexFile.loadDex(entryPath, entryPath + \".dex\", 0);\n            }\n\n            pathField.set(loader, path.toString());\n            expandFieldArray(loader, \"mPaths\", extraPaths);\n            expandFieldArray(loader, \"mFiles\", extraFiles);\n            expandFieldArray(loader, \"mZips\", extraZips);\n            expandFieldArray(loader, \"mDexs\", extraDexs);\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/support/multidex/MultiDexExtractor.java",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage android.support.multidex;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.os.Build;\nimport android.util.Log;\nimport java.io.BufferedOutputStream;\nimport java.io.Closeable;\nimport java.io.File;\nimport java.io.FileFilter;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.RandomAccessFile;\nimport java.nio.channels.FileChannel;\nimport java.nio.channels.FileLock;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\nimport java.util.zip.ZipOutputStream;\n\n/**\n * Exposes application secondary dex files as files in the application data\n * directory.\n */\nfinal class MultiDexExtractor {\n\n    /**\n     * Zip file containing one secondary dex file.\n     */\n    private static class ExtractedDex extends File {\n        public long crc = NO_VALUE;\n\n        public ExtractedDex(File dexDir, String fileName) {\n            super(dexDir, fileName);\n        }\n    }\n\n    private static final String TAG = MultiDex.TAG;\n\n    /**\n     * We look for additional dex files named {@code classes2.dex},\n     * {@code classes3.dex}, etc.\n     */\n    private static final String DEX_PREFIX = \"classes\";\n    private static final String DEX_SUFFIX = \".dex\";\n\n    private static final String EXTRACTED_NAME_EXT = \".classes\";\n    private static final String EXTRACTED_SUFFIX = \".zip\";\n    private static final int MAX_EXTRACT_ATTEMPTS = 3;\n\n    private static final String PREFS_FILE = \"multidex.version\";\n    private static final String KEY_TIME_STAMP = \"timestamp\";\n    private static final String KEY_CRC = \"crc\";\n    private static final String KEY_DEX_NUMBER = \"dex.number\";\n    private static final String KEY_DEX_CRC = \"dex.crc.\";\n    private static final String KEY_DEX_TIME = \"dex.time.\";\n\n    /**\n     * Size of reading buffers.\n     */\n    private static final int BUFFER_SIZE = 0x4000;\n    /* Keep value away from 0 because it is a too probable time stamp value */\n    private static final long NO_VALUE = -1L;\n\n    private static final String LOCK_FILENAME = \"MultiDex.lock\";\n\n    /**\n     * Extracts application secondary dexes into files in the application data\n     * directory.\n     *\n     * @return a list of files that were created. The list may be empty if there\n     *         are no secondary dex files. Never return null.\n     * @throws IOException if encounters a problem while reading or writing\n     *         secondary dex files\n     */\n    static List<? extends File> load(Context context, File sourceApk, File dexDir,\n            String prefsKeyPrefix,\n            boolean forceReload) throws IOException {\n        Log.i(TAG, \"MultiDexExtractor.load(\" + sourceApk.getPath() + \", \" + forceReload + \", \" +\n                prefsKeyPrefix + \")\");\n\n        long currentCrc = getZipCrc(sourceApk);\n\n        // Validity check and extraction must be done only while the lock file has been taken.\n        File lockFile = new File(dexDir, LOCK_FILENAME);\n        RandomAccessFile lockRaf = new RandomAccessFile(lockFile, \"rw\");\n        FileChannel lockChannel = null;\n        FileLock cacheLock = null;\n        List<ExtractedDex> files;\n        IOException releaseLockException = null;\n        try {\n            lockChannel = lockRaf.getChannel();\n            Log.i(TAG, \"Blocking on lock \" + lockFile.getPath());\n            cacheLock = lockChannel.lock();\n            Log.i(TAG, lockFile.getPath() + \" locked\");\n\n            if (!forceReload && !isModified(context, sourceApk, currentCrc, prefsKeyPrefix)) {\n                try {\n                    files = loadExistingExtractions(context, sourceApk, dexDir, prefsKeyPrefix);\n                } catch (IOException ioe) {\n                    Log.w(TAG, \"Failed to reload existing extracted secondary dex files,\"\n                            + \" falling back to fresh extraction\", ioe);\n                    files = performExtractions(sourceApk, dexDir);\n                    putStoredApkInfo(context, prefsKeyPrefix, getTimeStamp(sourceApk), currentCrc,\n                            files);\n                }\n            } else {\n                Log.i(TAG, \"Detected that extraction must be performed.\");\n                files = performExtractions(sourceApk, dexDir);\n                putStoredApkInfo(context, prefsKeyPrefix, getTimeStamp(sourceApk), currentCrc,\n                        files);\n            }\n        } finally {\n            if (cacheLock != null) {\n                try {\n                    cacheLock.release();\n                } catch (IOException e) {\n                    Log.e(TAG, \"Failed to release lock on \" + lockFile.getPath());\n                    // Exception while releasing the lock is bad, we want to report it, but not at\n                    // the price of overriding any already pending exception.\n                    releaseLockException = e;\n                }\n            }\n            if (lockChannel != null) {\n                closeQuietly(lockChannel);\n            }\n            closeQuietly(lockRaf);\n        }\n\n        if (releaseLockException != null) {\n            throw releaseLockException;\n        }\n\n        Log.i(TAG, \"load found \" + files.size() + \" secondary dex files\");\n        return files;\n    }\n\n    /**\n     * Load previously extracted secondary dex files. Should be called only while owning the lock on\n     * {@link #LOCK_FILENAME}.\n     */\n    private static List<ExtractedDex> loadExistingExtractions(\n            Context context, File sourceApk, File dexDir,\n            String prefsKeyPrefix)\n            throws IOException {\n        Log.i(TAG, \"loading existing secondary dex files\");\n\n        final String extractedFilePrefix = sourceApk.getName() + EXTRACTED_NAME_EXT;\n        SharedPreferences multiDexPreferences = getMultiDexPreferences(context);\n        int totalDexNumber = multiDexPreferences.getInt(prefsKeyPrefix + KEY_DEX_NUMBER, 1);\n        final List<ExtractedDex> files = new ArrayList<ExtractedDex>(totalDexNumber - 1);\n\n        for (int secondaryNumber = 2; secondaryNumber <= totalDexNumber; secondaryNumber++) {\n            String fileName = extractedFilePrefix + secondaryNumber + EXTRACTED_SUFFIX;\n            ExtractedDex extractedFile = new ExtractedDex(dexDir, fileName);\n            if (extractedFile.isFile()) {\n                extractedFile.crc = getZipCrc(extractedFile);\n                long expectedCrc = multiDexPreferences.getLong(\n                        prefsKeyPrefix + KEY_DEX_CRC + secondaryNumber, NO_VALUE);\n                long expectedModTime = multiDexPreferences.getLong(\n                        prefsKeyPrefix + KEY_DEX_TIME + secondaryNumber, NO_VALUE);\n                long lastModified = extractedFile.lastModified();\n                if ((expectedModTime != lastModified)\n                        || (expectedCrc != extractedFile.crc)) {\n                    throw new IOException(\"Invalid extracted dex: \" + extractedFile +\n                            \" (key \\\"\" + prefsKeyPrefix + \"\\\"), expected modification time: \"\n                            + expectedModTime + \", modification time: \"\n                            + lastModified + \", expected crc: \"\n                            + expectedCrc + \", file crc: \" + extractedFile.crc);\n                }\n                files.add(extractedFile);\n            } else {\n                throw new IOException(\"Missing extracted secondary dex file '\" +\n                        extractedFile.getPath() + \"'\");\n            }\n        }\n\n        return files;\n    }\n\n\n    /**\n     * Compare current archive and crc with values stored in {@link SharedPreferences}. Should be\n     * called only while owning the lock on {@link #LOCK_FILENAME}.\n     */\n    private static boolean isModified(Context context, File archive, long currentCrc,\n            String prefsKeyPrefix) {\n        SharedPreferences prefs = getMultiDexPreferences(context);\n        return (prefs.getLong(prefsKeyPrefix + KEY_TIME_STAMP, NO_VALUE) != getTimeStamp(archive))\n                || (prefs.getLong(prefsKeyPrefix + KEY_CRC, NO_VALUE) != currentCrc);\n    }\n\n    private static long getTimeStamp(File archive) {\n        long timeStamp = archive.lastModified();\n        if (timeStamp == NO_VALUE) {\n            // never return NO_VALUE\n            timeStamp--;\n        }\n        return timeStamp;\n    }\n\n\n    private static long getZipCrc(File archive) throws IOException {\n        long computedValue = ZipUtil.getZipCrc(archive);\n        if (computedValue == NO_VALUE) {\n            // never return NO_VALUE\n            computedValue--;\n        }\n        return computedValue;\n    }\n\n    private static List<ExtractedDex> performExtractions(File sourceApk, File dexDir)\n            throws IOException {\n\n        final String extractedFilePrefix = sourceApk.getName() + EXTRACTED_NAME_EXT;\n\n        // Ensure that whatever deletions happen in prepareDexDir only happen if the zip that\n        // contains a secondary dex file in there is not consistent with the latest apk.  Otherwise,\n        // multi-process race conditions can cause a crash loop where one process deletes the zip\n        // while another had created it.\n        prepareDexDir(dexDir, extractedFilePrefix);\n\n        List<ExtractedDex> files = new ArrayList<ExtractedDex>();\n\n        final ZipFile apk = new ZipFile(sourceApk);\n        try {\n\n            int secondaryNumber = 2;\n\n            ZipEntry dexFile = apk.getEntry(DEX_PREFIX + secondaryNumber + DEX_SUFFIX);\n            while (dexFile != null) {\n                String fileName = extractedFilePrefix + secondaryNumber + EXTRACTED_SUFFIX;\n                ExtractedDex extractedFile = new ExtractedDex(dexDir, fileName);\n                files.add(extractedFile);\n\n                Log.i(TAG, \"Extraction is needed for file \" + extractedFile);\n                int numAttempts = 0;\n                boolean isExtractionSuccessful = false;\n                while (numAttempts < MAX_EXTRACT_ATTEMPTS && !isExtractionSuccessful) {\n                    numAttempts++;\n\n                    // Create a zip file (extractedFile) containing only the secondary dex file\n                    // (dexFile) from the apk.\n                    extract(apk, dexFile, extractedFile, extractedFilePrefix);\n\n                    // Read zip crc of extracted dex\n                    try {\n                        extractedFile.crc = getZipCrc(extractedFile);\n                        isExtractionSuccessful = true;\n                    } catch (IOException e) {\n                        isExtractionSuccessful = false;\n                        Log.w(TAG, \"Failed to read crc from \" + extractedFile.getAbsolutePath(), e);\n                    }\n\n                    // Log size and crc of the extracted zip file\n                    Log.i(TAG, \"Extraction \" + (isExtractionSuccessful ? \"succeeded\" : \"failed\") +\n                            \" - length \" + extractedFile.getAbsolutePath() + \": \" +\n                            extractedFile.length() + \" - crc: \" + extractedFile.crc);\n                    if (!isExtractionSuccessful) {\n                        // Delete the extracted file\n                        extractedFile.delete();\n                        if (extractedFile.exists()) {\n                            Log.w(TAG, \"Failed to delete corrupted secondary dex '\" +\n                                    extractedFile.getPath() + \"'\");\n                        }\n                    }\n                }\n                if (!isExtractionSuccessful) {\n                    throw new IOException(\"Could not create zip file \" +\n                            extractedFile.getAbsolutePath() + \" for secondary dex (\" +\n                            secondaryNumber + \")\");\n                }\n                secondaryNumber++;\n                dexFile = apk.getEntry(DEX_PREFIX + secondaryNumber + DEX_SUFFIX);\n            }\n        } finally {\n            try {\n                apk.close();\n            } catch (IOException e) {\n                Log.w(TAG, \"Failed to close resource\", e);\n            }\n        }\n\n        return files;\n    }\n\n    /**\n     * Save {@link SharedPreferences}. Should be called only while owning the lock on\n     * {@link #LOCK_FILENAME}.\n     */\n    private static void putStoredApkInfo(Context context, String keyPrefix, long timeStamp,\n            long crc, List<ExtractedDex> extractedDexes) {\n        SharedPreferences prefs = getMultiDexPreferences(context);\n        SharedPreferences.Editor edit = prefs.edit();\n        edit.putLong(keyPrefix + KEY_TIME_STAMP, timeStamp);\n        edit.putLong(keyPrefix + KEY_CRC, crc);\n        edit.putInt(keyPrefix + KEY_DEX_NUMBER, extractedDexes.size() + 1);\n\n        int extractedDexId = 2;\n        for (ExtractedDex dex : extractedDexes) {\n            edit.putLong(keyPrefix + KEY_DEX_CRC + extractedDexId, dex.crc);\n            edit.putLong(keyPrefix + KEY_DEX_TIME + extractedDexId, dex.lastModified());\n            extractedDexId++;\n        }\n        /* Use commit() and not apply() as advised by the doc because we need synchronous writing of\n         * the editor content and apply is doing an \"asynchronous commit to disk\".\n         */\n        edit.commit();\n    }\n\n    /**\n     * Get the MuliDex {@link SharedPreferences} for the current application. Should be called only\n     * while owning the lock on {@link #LOCK_FILENAME}.\n     */\n    private static SharedPreferences getMultiDexPreferences(Context context) {\n        return context.getSharedPreferences(PREFS_FILE,\n                Build.VERSION.SDK_INT < 11 /* Build.VERSION_CODES.HONEYCOMB */\n                        ? Context.MODE_PRIVATE\n                        : Context.MODE_PRIVATE | 0x0004 /* Context.MODE_MULTI_PROCESS */);\n    }\n\n    /**\n     * This removes old files.\n     */\n    private static void prepareDexDir(File dexDir, final String extractedFilePrefix) {\n        FileFilter filter = new FileFilter() {\n\n            @Override\n            public boolean accept(File pathname) {\n                String name = pathname.getName();\n                return !(name.startsWith(extractedFilePrefix)\n                        || name.equals(LOCK_FILENAME));\n            }\n        };\n        File[] files = dexDir.listFiles(filter);\n        if (files == null) {\n            Log.w(TAG, \"Failed to list secondary dex dir content (\" + dexDir.getPath() + \").\");\n            return;\n        }\n        for (File oldFile : files) {\n            Log.i(TAG, \"Trying to delete old file \" + oldFile.getPath() + \" of size \" +\n                    oldFile.length());\n            if (!oldFile.delete()) {\n                Log.w(TAG, \"Failed to delete old file \" + oldFile.getPath());\n            } else {\n                Log.i(TAG, \"Deleted old file \" + oldFile.getPath());\n            }\n        }\n    }\n\n    private static void extract(ZipFile apk, ZipEntry dexFile, File extractTo,\n            String extractedFilePrefix) throws IOException, FileNotFoundException {\n\n        InputStream in = apk.getInputStream(dexFile);\n        ZipOutputStream out = null;\n        // Temp files must not start with extractedFilePrefix to get cleaned up in prepareDexDir()\n        File tmp = File.createTempFile(\"tmp-\" + extractedFilePrefix, EXTRACTED_SUFFIX,\n                extractTo.getParentFile());\n        Log.i(TAG, \"Extracting \" + tmp.getPath());\n        try {\n            out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(tmp)));\n            try {\n                ZipEntry classesDex = new ZipEntry(\"classes.dex\");\n                // keep zip entry time since it is the criteria used by Dalvik\n                classesDex.setTime(dexFile.getTime());\n                out.putNextEntry(classesDex);\n\n                byte[] buffer = new byte[BUFFER_SIZE];\n                int length = in.read(buffer);\n                while (length != -1) {\n                    out.write(buffer, 0, length);\n                    length = in.read(buffer);\n                }\n                out.closeEntry();\n            } finally {\n                out.close();\n            }\n            if (!tmp.setReadOnly()) {\n                throw new IOException(\"Failed to mark readonly \\\"\" + tmp.getAbsolutePath() +\n                        \"\\\" (tmp of \\\"\" + extractTo.getAbsolutePath() + \"\\\")\");\n            }\n            Log.i(TAG, \"Renaming to \" + extractTo.getPath());\n            if (!tmp.renameTo(extractTo)) {\n                throw new IOException(\"Failed to rename \\\"\" + tmp.getAbsolutePath() +\n                        \"\\\" to \\\"\" + extractTo.getAbsolutePath() + \"\\\"\");\n            }\n        } finally {\n            closeQuietly(in);\n            tmp.delete(); // return status ignored\n        }\n    }\n\n    /**\n     * Closes the given {@code Closeable}. Suppresses any IO exceptions.\n     */\n    private static void closeQuietly(Closeable closeable) {\n        try {\n            closeable.close();\n        } catch (IOException e) {\n            Log.w(TAG, \"Failed to close resource\", e);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/support/multidex/ZipUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/* Apache Harmony HEADER because the code in this class comes mostly from ZipFile, ZipEntry and\n * ZipConstants from android libcore.\n */\n\npackage android.support.multidex;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\nimport java.util.zip.CRC32;\nimport java.util.zip.ZipException;\n\n/**\n * Tools to build a quick partial crc of zip files.\n */\nfinal class ZipUtil {\n    static class CentralDirectory {\n        long offset;\n        long size;\n    }\n\n    /* redefine those constant here because of bug 13721174 preventing to compile using the\n     * constants defined in ZipFile */\n    private static final int ENDHDR = 22;\n    private static final int ENDSIG = 0x6054b50;\n\n    /**\n     * Size of reading buffers.\n     */\n    private static final int BUFFER_SIZE = 0x4000;\n\n    /**\n     * Compute crc32 of the central directory of an apk. The central directory contains\n     * the crc32 of each entries in the zip so the computed result is considered valid for the whole\n     * zip file. Does not support zip64 nor multidisk but it should be OK for now since ZipFile does\n     * not either.\n     */\n    static long getZipCrc(File apk) throws IOException {\n        RandomAccessFile raf = new RandomAccessFile(apk, \"r\");\n        try {\n            CentralDirectory dir = findCentralDirectory(raf);\n\n            return computeCrcOfCentralDir(raf, dir);\n        } finally {\n            raf.close();\n        }\n    }\n\n    /* Package visible for testing */\n    static CentralDirectory findCentralDirectory(RandomAccessFile raf) throws IOException,\n            ZipException {\n        long scanOffset = raf.length() - ENDHDR;\n        if (scanOffset < 0) {\n            throw new ZipException(\"File too short to be a zip file: \" + raf.length());\n        }\n\n        long stopOffset = scanOffset - 0x10000 /* \".ZIP file comment\"'s max length */;\n        if (stopOffset < 0) {\n            stopOffset = 0;\n        }\n\n        int endSig = Integer.reverseBytes(ENDSIG);\n        while (true) {\n            raf.seek(scanOffset);\n            if (raf.readInt() == endSig) {\n                break;\n            }\n\n            scanOffset--;\n            if (scanOffset < stopOffset) {\n                throw new ZipException(\"End Of Central Directory signature not found\");\n            }\n        }\n        // Read the End Of Central Directory. ENDHDR includes the signature\n        // bytes,\n        // which we've already read.\n\n        // Pull out the information we need.\n        raf.skipBytes(2); // diskNumber\n        raf.skipBytes(2); // diskWithCentralDir\n        raf.skipBytes(2); // numEntries\n        raf.skipBytes(2); // totalNumEntries\n        CentralDirectory dir = new CentralDirectory();\n        dir.size = Integer.reverseBytes(raf.readInt()) & 0xFFFFFFFFL;\n        dir.offset = Integer.reverseBytes(raf.readInt()) & 0xFFFFFFFFL;\n        return dir;\n    }\n\n    /* Package visible for testing */\n    static long computeCrcOfCentralDir(RandomAccessFile raf, CentralDirectory dir)\n            throws IOException {\n        CRC32 crc = new CRC32();\n        long stillToRead = dir.size;\n        raf.seek(dir.offset);\n        int length = (int) Math.min(BUFFER_SIZE, stillToRead);\n        byte[] buffer = new byte[BUFFER_SIZE];\n        length = raf.read(buffer, 0, length);\n        while (length != -1) {\n            crc.update(buffer, 0, length);\n            stillToRead -= length;\n            if (stillToRead == 0) {\n                break;\n            }\n            length = (int) Math.min(BUFFER_SIZE, stillToRead);\n            length = raf.read(buffer, 0, length);\n        }\n        return crc.getValue();\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/bridge/BridgeApplicationDelegate.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.bridge;\n\nimport android.app.Application;\nimport android.content.ComponentCallbacks;\nimport android.content.Context;\nimport android.content.pm.ApplicationInfo;\nimport android.content.pm.PackageManager;\nimport android.content.pm.ProviderInfo;\nimport android.content.res.Configuration;\nimport android.content.res.Resources;\nimport android.os.Build;\nimport android.os.Process;\nimport android.support.multidex.MultiDex;\nimport android.taobao.atlas.framework.Atlas;\nimport android.taobao.atlas.framework.Framework;\nimport android.taobao.atlas.hack.AndroidHack;\nimport android.taobao.atlas.hack.AtlasHacks;\nimport android.taobao.atlas.runtime.AtlasPreLauncher;\nimport android.taobao.atlas.runtime.RuntimeVariables;\n\nimport android.taobao.atlas.startup.KernalVersionManager;\nimport android.taobao.atlas.util.SoLoader;\nimport android.taobao.atlas.util.log.IAlarmer;\nimport android.taobao.atlas.util.log.IMonitor;\nimport android.taobao.atlas.util.log.impl.AtlasAlarmer;\nimport android.taobao.atlas.util.log.impl.AtlasMonitor;\nimport android.text.TextUtils;\nimport android.util.DisplayMetrics;\nimport android.util.Log;\nimport android.view.WindowManager;\n\nimport java.io.File;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.List;\n\nimport dalvik.system.DexFile;\n\n/**\n * Created by guanjie on 2017/1/26.\n */\n\npublic class BridgeApplicationDelegate {\n\n    private String mRealApplicationName ;\n    private Application mRealApplication;\n    private Application mRawApplication;\n    private String mInstalledVersionName;\n    private String mCurrentProcessname;\n    private long   mInstalledVersionCode;\n    private long   mLastUpdateTime;\n    private boolean mIsUpdated;\n    private String mApkPath;\n    private Object mdexLoadBooster;\n    private List<ProviderInfo> mBoundApplication_provider;\n\n    public BridgeApplicationDelegate(Application rawApplication,String processname,String installedVersion,\n                                     long versioncode,long lastupdatetime,String apkPath,boolean isUpdated,Object dexLoadBooster){\n//        if(Build.VERSION.SDK_INT<=19 && getClass().getClassLoader().getClass().getName().startsWith(\"com.ali.mobisecenhance\")){\n//            try {\n//                Field pathListField = AndroidHack.findField(rawApplication.getClassLoader(), \"pathList\");\n//                Object dexPathList = pathListField.get(rawApplication.getClassLoader());\n//                Field elementsField = AndroidHack.findField(dexPathList,\"dexElements\");\n//                Object[] elements = (Object[])elementsField.get(dexPathList);\n//                Log.e(\"BridgeApplication\",\"get Elements :\"+ elements);\n//\n//                if(elements.length>0) {\n//                    Field dexFileField = elements[0].getClass().getDeclaredField(\"dexFile\");\n//                    dexFileField.setAccessible(true);\n//                    for(int x=elements.length-1; x>=0; x--){\n//                        DexFile dexFile = (DexFile) dexFileField.get(elements[x]);\n//                        if(dexFile.getName().contains(\"com.taobao.maindex\")) {\n//                            //针对动态部署处理过的dex做判断\n//                            boolean findDexToDelete = false;\n//                            Enumeration<String> enumeration = dexFile.entries();\n//                            while (enumeration.hasMoreElements()) {\n//                                if (enumeration.nextElement().replace(\"/\", \".\").startsWith(\"com.ali.mobisecenhance.ld.util\")) {\n//                                    findDexToDelete = true;\n//                                    break;\n//                                }\n//                            }\n//                            if(findDexToDelete){\n//                                Log.e(\"BridgeApplication\",\"delete dexfile :\"+dexFile.getName());\n//                                dexFileField.set(elements[x],null);\n//                                break;\n//                            }\n//                        }\n//                    }\n//                }\n//            }catch(Throwable e){\n//                e.printStackTrace();\n//            }\n//        }\n\n        mRawApplication = rawApplication;\n        mCurrentProcessname = processname;\n        mInstalledVersionName = installedVersion;\n        mInstalledVersionCode = versioncode;\n        mLastUpdateTime = lastupdatetime;\n        mIsUpdated = isUpdated;\n        mApkPath = apkPath;\n        mdexLoadBooster = dexLoadBooster;\n//        PackageManagerDelegate.delegatepackageManager(rawApplication.getBaseContext());\n    }\n\n    public void attachBaseContext(){\n        AtlasHacks.defineAndVerify();\n        RuntimeVariables.androidApplication = mRawApplication;\n        RuntimeVariables.originalResources = mRawApplication.getResources();\n        RuntimeVariables.sCurrentProcessName = mCurrentProcessname;\n        RuntimeVariables.sInstalledVersionCode = mInstalledVersionCode;\n        RuntimeVariables.sAppLastUpdateTime = mLastUpdateTime;\n        RuntimeVariables.sApkPath = mApkPath;\n        RuntimeVariables.delegateResources = mRawApplication.getResources();\n        RuntimeVariables.sDexLoadBooster = mdexLoadBooster;\n        Log.e(\"BridgeApplication\",\"length =\" + new File(mRawApplication.getApplicationInfo().sourceDir).length());\n\n//        if(Build.MANUFACTURER.equalsIgnoreCase(\"vivo\") && Build.VERSION.SDK_INT== 23) {\n//            ;\n////            try {\n////                File appSGLib = mRawApplication.getDir(\"SGLib\", Context.MODE_PRIVATE);\n////                File mark = new File(mRawApplication.getFilesDir(), \"vivo_appSGLib_mark\");\n////                if (appSGLib.exists() && !mark.exists()) {\n////                    mark.createNewFile();\n////                    File[] files = appSGLib.listFiles();\n////                    for(File file : files){\n////                        if(file.exists() && file.isDirectory() && file.getName().startsWith(\"app_\")){\n////                            deleteDirectory(file);\n////                        }\n////                    }\n////                }\n////            }catch(Throwable e){\n////                e.printStackTrace();\n////            }\n//        }else{\n//            try {\n//                RuntimeVariables.sDexLoadBooster.getClass().getDeclaredMethod(\"setVerificationEnabled\", boolean.class).invoke(RuntimeVariables.sDexLoadBooster, false);\n//            } catch (Throwable e){\n//                e.printStackTrace();\n//            }\n//        }\n\n\n        if(!TextUtils.isEmpty(mInstalledVersionName)){\n            RuntimeVariables.sInstalledVersionName = mInstalledVersionName;\n        }\n        System.out.print(SoLoader.class.getName());\n        try {\n            String preLaunchStr = (String) RuntimeVariables.getFrameworkProperty(\"preLaunch\");\n            if (!TextUtils.isEmpty(preLaunchStr)) {\n                AtlasPreLauncher launcher = (AtlasPreLauncher) Class.forName(preLaunchStr).newInstance();\n                if (launcher != null) {\n                    launcher.initBeforeAtlas(mRawApplication.getBaseContext());\n                }\n            }\n        } catch (Throwable e) {\n            throw new RuntimeException(e);\n        }\n\n\n        // *2 init atlas use reflect\n        boolean multidexEnable = false;\n        try {\n            ApplicationInfo appInfo = mRawApplication.getPackageManager()\n                    .getApplicationInfo(mRawApplication.getPackageName(),\n                            PackageManager.GET_META_DATA);\n            mRealApplicationName = appInfo.metaData.getString(\"REAL_APPLICATION\");\n            multidexEnable = appInfo.metaData.getBoolean(\"multidex_enable\");\n        }catch(PackageManager.NameNotFoundException e){\n            throw new RuntimeException(e);\n        }\n\n        if(multidexEnable){\n            MultiDex.install(mRawApplication);\n        }\n\n        mRealApplicationName = TextUtils.isEmpty(mRealApplicationName) ? \"android.app.Application\" : mRealApplicationName;\n        if(mRealApplicationName.startsWith(\".\")){\n            mRealApplicationName = mRawApplication.getPackageName() + mRealApplicationName;\n        }\n        RuntimeVariables.sRealApplicationName = mRealApplicationName;\n\n        try {\n\n            Atlas.getInstance().init(mRawApplication, mIsUpdated);\n        } catch (Throwable e) {\n                File storageDir = new File(mRawApplication.getFilesDir(),\"storage\");\n                Framework.deleteDirectory(storageDir);\n                KernalVersionManager.instance().removeBaseLineInfo();\n                android.os.Process.killProcess(Process.myPid());\n//                throw new RuntimeException(\"atlas initialization fail--->\" + e.getMessage());\n        }\n        //////////////////////////////////////////launchTime////////////////////\n        try{\n            Class BuildConfig = Class.forName(mRawApplication.getPackageName()+\".BuildConfig\");\n            Field launchTimeField = BuildConfig.getDeclaredField(\"launchTime\");\n            launchTimeField.setAccessible(true);\n            launchTimeField.set(BuildConfig,System.currentTimeMillis());\n        }catch(Throwable e){}\n        //////////////////////////////////////////launchTime////////////////////\n\n        // *3 remove providerinfo for so installcontentprovider is delayed\n        try {\n            Object activityThread = AndroidHack.getActivityThread();\n            Object mBoundApplication = AtlasHacks.ActivityThread_mBoundApplication.get(activityThread);\n            mBoundApplication_provider = AtlasHacks.ActivityThread$AppBindData_providers.get(mBoundApplication);\n            if(mBoundApplication_provider!=null && mBoundApplication_provider.size()>0){\n                AtlasHacks.ActivityThread$AppBindData_providers.set(mBoundApplication,null);\n            }else if (Build.VERSION.SDK_INT >= 24 && mCurrentProcessname!= null && mCurrentProcessname.equals(mRawApplication.getPackageName())){\n                mBoundApplication_provider = new ArrayList<>();\n                ProviderInfo providerInfo = mRawApplication.getPackageManager().resolveContentProvider(mRawApplication.getPackageName()+\".update.provider\",0);\n                if (providerInfo!= null){\n                    providerInfo.exported = false;\n                    providerInfo.grantUriPermissions = true;\n                    mBoundApplication_provider.add(providerInfo);\n                }\n\n            }\n        } catch (Exception e) {\n            if(e instanceof InvocationTargetException){\n                throw new RuntimeException(((InvocationTargetException)e).getTargetException());\n            }else {\n                throw new RuntimeException(e);\n            }\n        }\n    }\n\n    public void onCreate(){\n        try {\n            // *3 create real Application\n            mRealApplication = (Application) mRawApplication.getBaseContext().getClassLoader().loadClass(mRealApplicationName).newInstance();\n\n            Object activityThread = AndroidHack.getActivityThread();\n            //replace baseContext.mOuterContext\n            AtlasHacks.ContextImpl_setOuterContext.invoke(mRawApplication.getBaseContext(), mRealApplication);\n            //replace baseContext.mPackageInfo.mApplication\n            Object mPackageInfo = AtlasHacks.ContextImpl_mPackageInfo.get(mRawApplication.getBaseContext());\n            AtlasHacks.LoadedApk_mApplication.set(mPackageInfo,mRealApplication);\n            //replace baseContext.mPackageInfo.mActivityThread.mInitialApplication\n            AtlasHacks.ActivityThread_mInitialApplication.set(activityThread,mRealApplication);\n            //update  baseContext.mPackageInfo.mActivityThread.mAllApplications\n            List<Application> allApplications = AtlasHacks.ActivityThread_mAllApplications.get(activityThread);\n            for (int i = 0; i < allApplications.size(); i++) {\n                if (allApplications.get(i) == mRawApplication) {\n                    //替换掉ActivityThread.mAllApplications**\n                    allApplications.set(i, mRealApplication);\n                }\n            }\n            RuntimeVariables.androidApplication = mRealApplication;\n\n            /**\n             * configuration update\n             */\n            mRealApplication.registerComponentCallbacks(new ComponentCallbacks() {\n                @Override\n                public void onConfigurationChanged(Configuration newConfig) {\n                    DisplayMetrics newMetrics = new DisplayMetrics();\n                    if(RuntimeVariables.delegateResources!=null && RuntimeVariables.androidApplication!=null){\n                        WindowManager manager = (WindowManager) RuntimeVariables.androidApplication.getSystemService(Context.WINDOW_SERVICE);\n                        if(manager==null || manager.getDefaultDisplay()==null){\n                            Log.e(\"BridgeApplication\",\"get windowmanager service failed\");\n                            return;\n                        }\n                        manager.getDefaultDisplay().getMetrics(newMetrics);\n                        RuntimeVariables.delegateResources.updateConfiguration(newConfig,newMetrics);\n                        try {\n                            Method method = Resources.class.getDeclaredMethod(\"updateSystemConfiguration\",\n                                    Configuration.class,DisplayMetrics.class,Class.forName(\"android.content.res.CompatibilityInfo\"));\n                            method.setAccessible(true);\n                            method.invoke(RuntimeVariables.delegateResources,newConfig,newMetrics,null);\n                        } catch (Throwable e) {\n                            e.printStackTrace();\n                        }\n                    }\n                }\n\n                @Override\n                public void onLowMemory() {\n\n                }\n            });\n\n            AtlasHacks.Application_attach.invoke(mRealApplication,mRawApplication.getBaseContext());\n            // install content providers\n            if (mBoundApplication_provider != null && mBoundApplication_provider.size() > 0) {\n                Object mBoundApplication = AtlasHacks.ActivityThread_mBoundApplication.get(activityThread);\n                AtlasHacks.ActivityThread$AppBindData_providers.set(mBoundApplication,mBoundApplication_provider);\n                AtlasHacks.ActivityThread_installContentProviders.invoke(activityThread,mRealApplication,mBoundApplication_provider);\n            }else {\n\n            }\n\n        }catch(Throwable e){\n            if(e instanceof InvocationTargetException){\n                throw new RuntimeException(((InvocationTargetException)e).getTargetException());\n            }else {\n                throw new RuntimeException(e);\n            }\n        }\n\n        Atlas.getInstance().startup(mRealApplication,mIsUpdated);\n\n        mRealApplication.onCreate();\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/bundleInfo/AtlasBundleInfoGenerator.java",
    "content": "package android.taobao.atlas.bundleInfo;\n\n/**\n * Created by guanjie on 2017/10/6.\n */\n\npublic class AtlasBundleInfoGenerator {\n\n    public static BundleListing generateBundleInfo(){\n        return null;\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/bundleInfo/AtlasBundleInfoManager.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.bundleInfo;\n\nimport android.content.ComponentName;\nimport android.content.Context;\nimport android.content.pm.ActivityInfo;\nimport android.content.pm.ApplicationInfo;\nimport android.content.pm.PackageInfo;\nimport android.content.pm.PackageManager;\nimport android.content.pm.ProviderInfo;\nimport android.content.pm.ServiceInfo;\nimport android.taobao.atlas.bundleInfo.BundleListing.BundleInfo;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.taobao.atlas.util.WrapperUtil;\nimport android.taobao.atlas.util.log.impl.AtlasMonitor;\nimport android.text.TextUtils;\nimport android.util.Base64;\nimport android.util.Log;\n\nimport org.json.JSONArray;\nimport org.json.JSONObject;\n\nimport java.io.BufferedReader;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.util.*;\nimport java.util.zip.GZIPInputStream;\n\n/**\n * Created by guanjie on 15/7/6.\n */\npublic class AtlasBundleInfoManager {\n\n    public static final String TAG = \"AtlasBundleInfoManager\";\n\n    private static AtlasBundleInfoManager sManager;\n    private BundleListing mCurrentBundleListing;\n\n    public static synchronized AtlasBundleInfoManager instance(){\n        if(sManager==null){\n            sManager = new AtlasBundleInfoManager();\n        }\n        return sManager;\n    }\n\n    private AtlasBundleInfoManager(){\n        if(mCurrentBundleListing==null){\n            String bundleInfoStr = null;\n            int retryCount = 2;\n            Throwable e = null;\n            do {\n                try {\n                    try {\n                        mCurrentBundleListing = AtlasBundleInfoGenerator.generateBundleInfo();\n                        Log.e(\"AtlasBundleInfoManager\", \"generate info from generator\");\n                    } catch (Throwable exception) {\n                        exception.printStackTrace();\n                        if (bundleInfoStr == null) {\n                            bundleInfoStr = (String)RuntimeVariables.getFrameworkProperty(\"bundleInfo\");\n                            if (TextUtils.isEmpty(bundleInfoStr)) {\n                                throw new RuntimeException(\"read bundleInfo failed\");\n                            }\n                            Object compressInfo = RuntimeVariables.getFrameworkProperty(\"compressInfo\");\n                            if (compressInfo != null && (boolean)compressInfo) {\n                                bundleInfoStr = uncompress(bundleInfoStr);\n                                Log.e(\"AtlasBundleInfoManager\", \"the result of decoded info \" + bundleInfoStr);\n                            }\n                            if (bundleInfoStr == null) {\n                                throw new RuntimeException(\"bundleinfo is invalid\");\n                            }\n                        }\n                        LinkedHashMap<String, BundleInfo> infos = BundleListingUtil.parseArray(bundleInfoStr);\n                        if (infos == null) {\n                            Map<String, Object> detail = new HashMap<>();\n                            detail.put(\"InitBundleInfoByVersionIfNeed\", bundleInfoStr);\n                            AtlasMonitor.getInstance().report(AtlasMonitor.CONTAINER_BUNDLEINFO_PARSE_FAIL,\n                                                              detail,\n                                                              new RuntimeException(\"the infos is null!\"));\n                        }\n                        BundleListing listing = new BundleListing();\n                        listing.setBundles(infos);\n                        mCurrentBundleListing = listing;\n                    }\n                    updateBundleListingWithExtraInfo();\n                    break;\n                } catch (Throwable error) {\n                    e = error;\n                    e.printStackTrace();\n                }\n                retryCount--;\n            } while (retryCount > 0);\n            if (e != null) {\n                Map<String, Object> detail = new HashMap<>();\n                detail.put(\"InitBundleInfoByVersionIfNeed\", bundleInfoStr);\n                AtlasMonitor.getInstance().report(AtlasMonitor.CONTAINER_BUNDLEINFO_PARSE_FAIL, detail, e);\n                throw new RuntimeException(\"parse bundleinfo failed\");\n            }\n        }\n    }\n\n    public BundleListing getBundleInfo(){\n        return mCurrentBundleListing;\n    }\n\n    /*\n     * Get all dependent bundles for the designated bundle\n     */\n    public List<String> getDependencyForBundle(String bundleName){\n        if(mCurrentBundleListing==null || mCurrentBundleListing.getBundles()==null){\n            return null;\n        }\n        BundleListing.BundleInfo bundleInfo = mCurrentBundleListing.getBundles().get(bundleName);\n        if(bundleInfo != null && bundleInfo.getDependency() != null){\n            List<String> dependencies = new ArrayList<String>();\n            for(int x=0; x<bundleInfo.getDependency().size();x++){\n                if(!TextUtils.isEmpty(bundleInfo.getDependency().get(x))){\n                    dependencies.add(bundleInfo.getDependency().get(x));\n                }\n            }\n            return dependencies;\n        }\n\n        return null;\n    }\n\n    public boolean isInternalBundle(String bundleName){\n        if(mCurrentBundleListing==null || mCurrentBundleListing.getBundles()==null){\n            return true;\n        }\n        BundleListing.BundleInfo info = mCurrentBundleListing.getBundles().get(bundleName);\n        if(info!=null){\n            return info.isInternal();\n        }else{\n            return true;\n        }\n    }\n\n    public String getBundleForRemoteFragment(String rFname){\n        if(mCurrentBundleListing==null || mCurrentBundleListing.getBundles()==null){\n            return null;\n        }\n        Iterator<Map.Entry<String, BundleListing.BundleInfo>> iterator = mCurrentBundleListing.getBundles().entrySet().iterator();\n        while (iterator.hasNext()) {\n            Map.Entry<String, BundleListing.BundleInfo> entry = iterator.next();\n            BundleListing.BundleInfo bundleInfo = entry.getValue();\n            if(bundleInfo!=null && bundleInfo.remoteFragments!=null && bundleInfo.remoteFragments.containsKey(rFname)) {\n                return bundleInfo.getPkgName();\n            }\n        }\n\n        return null;\n    }\n\n    public String getBundleForRemoteTransactor(String tName){\n        if(mCurrentBundleListing==null || mCurrentBundleListing.getBundles()==null){\n            return null;\n        }\n        Iterator<Map.Entry<String, BundleListing.BundleInfo>> iterator = mCurrentBundleListing.getBundles().entrySet().iterator();\n        while (iterator.hasNext()) {\n            Map.Entry<String, BundleListing.BundleInfo> entry = iterator.next();\n            BundleListing.BundleInfo bundleInfo = entry.getValue();\n            if(bundleInfo!=null && bundleInfo.remoteTransactors!=null && bundleInfo.remoteTransactors.containsKey(tName)) {\n                return bundleInfo.getPkgName();\n            }\n        }\n        return null;\n    }\n\n    public String getBundleForRemoteView(String rVname){\n        if(mCurrentBundleListing==null || mCurrentBundleListing.getBundles()==null){\n            return null;\n        }\n        Iterator<Map.Entry<String, BundleListing.BundleInfo>> iterator = mCurrentBundleListing.getBundles().entrySet().iterator();\n        while (iterator.hasNext()) {\n            Map.Entry<String, BundleListing.BundleInfo> entry = iterator.next();\n            BundleListing.BundleInfo bundleInfo = entry.getValue();\n            if(bundleInfo!=null && bundleInfo.remoteViews!=null && bundleInfo.remoteViews.containsKey(rVname)) {\n                return bundleInfo.getPkgName();\n            }\n        }\n        return null;\n    }\n\n    public String getBundleForComponet(String componentName){\n        if(mCurrentBundleListing==null || mCurrentBundleListing.getBundles()==null){\n            return null;\n        }\n        Iterator<Map.Entry<String, BundleListing.BundleInfo>> iterator = mCurrentBundleListing.getBundles().entrySet().iterator();\n        while (iterator.hasNext()) {\n            Map.Entry<String, BundleListing.BundleInfo> entry = iterator.next();\n            BundleListing.BundleInfo bundleInfo = entry.getValue();\n            if(bundleInfo!=null && bundleInfo.getActivities()!=null && bundleInfo.getActivities().containsKey(componentName)) {\n                return bundleInfo.getPkgName();\n            }\n\n            if(bundleInfo!=null && bundleInfo.getServices()!=null && bundleInfo.getServices().containsKey(componentName)) {\n                return bundleInfo.getPkgName();\n            }\n\n            if(bundleInfo!=null && bundleInfo.getReceivers()!=null && bundleInfo.getReceivers().containsKey(componentName) ) {\n                return bundleInfo.getPkgName();\n            }\n\n            if(bundleInfo!=null && bundleInfo.getContentProviders()!=null && bundleInfo.getContentProviders().containsKey(componentName)) {\n                return bundleInfo.getPkgName();\n            }\n\n        }\n\n        return null;\n    }\n\n\n    public boolean isMbundle(String location){\n        BundleListing.BundleInfo bundleInfo = getBundleInfo(location);\n        if (bundleInfo!= null){\n            return bundleInfo.isMBundle();\n        }\n        return false;\n    }\n\n    public BundleListing.BundleInfo getBundleInfo(String name){\n        if(mCurrentBundleListing==null || mCurrentBundleListing.getBundles()==null){\n            return null;\n        }\n        BundleListing.BundleInfo info = mCurrentBundleListing.getBundles().get(name);\n        if(info!=null){\n            return info;\n        }\n\n        Log.w(TAG, \"Could not find info for: \" + name);\n        \n        return null;\n    }\n\n    private void updateBundleListingWithExtraInfo(){\n        if(mCurrentBundleListing==null || mCurrentBundleListing.getBundles()==null){\n            return;\n        }\n        String fileName = String.format(\"%s%s.json\",\"bundleInfo-\", WrapperUtil.getPackageInfo(RuntimeVariables.androidApplication).versionName);\n        String extraInfo = getFromAssets(fileName,RuntimeVariables.androidApplication);\n        if(!TextUtils.isEmpty(extraInfo)){\n            try {\n                JSONArray array = new JSONArray(extraInfo);\n                if(array!=null){\n                    for(int x=0; x<array.length(); x++){\n                        JSONObject jb = array.getJSONObject(x);\n                        BundleListing.BundleInfo info = getBundleInfo(jb.optString(\"name\"));\n                        info.size = jb.optInt(\"size\");\n                        info.md5 = jb.optString(\"md5\");\n                        info.url = jb.optString(\"url\");\n                    }\n                }\n            }catch (Throwable e){\n                e.printStackTrace();\n            }\n\n        }\n    }\n\n    public static String uncompress(String base64EncodeStr) {\n        byte[] gzipArray = Base64.decode(base64EncodeStr,Base64.DEFAULT);\n        ByteArrayOutputStream out = new ByteArrayOutputStream();\n        ByteArrayInputStream in = new ByteArrayInputStream(gzipArray);\n        try {\n            GZIPInputStream ungzip = new GZIPInputStream(in);\n            byte[] buffer = new byte[1024];\n            int n;\n            while ((n = ungzip.read(buffer)) >= 0) {\n                out.write(buffer, 0, n);\n            }\n            return new String(out.toByteArray(),\"UTF-8\");\n        } catch (IOException e) {\n        }finally {\n            try{\n                in.close();\n                out.close();\n            }catch (Throwable e){}\n        }\n        return null;\n    }\n\n    private String getFromAssets(String fileName,Context context){\n        BufferedReader bufReader = null;\n        try {\n            InputStreamReader inputReader = new InputStreamReader(context.getResources().getAssets().open(fileName), \"UTF-8\");\n            bufReader = new BufferedReader(inputReader);\n            String line=\"\";\n            String result=\"\";\n            while((line = bufReader.readLine()) != null)\n                result += line;\n            return result;\n        } catch (Exception e) {\n            e.printStackTrace();\n            return null;\n        } finally {\n            if(bufReader!=null){\n                try {\n                    bufReader.close();\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/bundleInfo/BundleListing.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.bundleInfo;\n\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport java.io.Serializable;\nimport java.util.*;\n\n/**\n * Bundle清单信息\n * Created by guanjie on 14-9-15.\n */\npublic class BundleListing implements Serializable{\n\n    public LinkedHashMap<String,BundleInfo> bundles = new LinkedHashMap<String,BundleInfo>();\n\n    public LinkedHashMap<String,BundleInfo> getBundles() {\n        return bundles;\n    }\n\n    public void setBundles(LinkedHashMap<String,BundleInfo> bundles) {\n        this.bundles = bundles;\n    }\n\n\n    public static class BundleInfo{\n        public String name;\n        public String pkgName;\n        public String applicationName;\n        public String version;\n        public String desc;\n        public String url;\n        public String md5;\n        public boolean isInternal = true;\n        public boolean isMBundle = false;\n        public List<String> dependency;\n        public List<String> totalDependency;\n        public HashMap<String,Boolean> activities;\n        public HashMap<String,Boolean> services;\n        public HashMap<String,Boolean> receivers;\n        public HashMap<String,Boolean> contentProviders;\n        public HashMap<String,String>  remoteFragments;\n        public HashMap<String,String>  remoteViews;\n        public HashMap<String,String>  remoteTransactors;\n        public String unique_tag;\n        public long size;\n\n        public long getSize() {\n            return size;\n        }\n\n        public boolean isMBundle() {\n            return isMBundle;\n        }\n\n        public boolean isInternal() {\n            return isInternal;\n        }\n\n        public String getApplicationName() {\n\t\t\treturn applicationName;\n\t\t}\n\n        public HashMap<String,Boolean> getReceivers() {\n            return receivers;\n        }\n\n        public HashMap<String,Boolean> getContentProviders() {\n            return contentProviders;\n        }\n\n        public String getUnique_tag() {\n            return unique_tag;\n        }\n\n        public String getMd5() {\n            return md5;\n        }\n\n        public String getUrl() {\n            return url;\n        }\n\n        public String getDesc() {\n            return desc;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public String getPkgName() {\n            return pkgName;\n        }\n\n        public String getVersion() {\n            return version;\n        }\n\n        public List<String> getDependency() {\n            return dependency;\n        }\n\n        public void setDependency(List<String> dependency) {\n            if(dependency!=null && dependency.size()>0){\n                for(int x=0; x<dependency.size();){\n                    if(TextUtils.isEmpty(dependency.get(x))){\n                        dependency.remove(x);\n                    }else{\n                        x++;\n                    }\n                }\n            }\n            this.dependency = dependency;\n        }\n\n        public HashMap<String,Boolean> getActivities() {\n            return activities;\n        }\n\n        public HashMap<String,Boolean> getServices() {\n            return services;\n        }\n\n        public HashMap<String,Boolean> getComponents(){\n            HashMap<String,Boolean> components = new HashMap<String,Boolean>();\n            if(activities!=null && activities.size()>0){\n                components.putAll(activities);\n            }\n            if(services!=null && services.size()>0){\n                components.putAll(services);\n            }\n            if(receivers!=null && receivers.size()>0){\n                components.putAll(receivers);\n            }\n            if(contentProviders!=null && contentProviders.size()>0){\n                components.putAll(contentProviders);\n            }\n            return components;\n        }\n\n        public synchronized void addRuntimeDependency(String location){\n            if(totalDependency!=null){\n                getTotalDependency();\n            }\n            if(!totalDependency.contains(location)){\n                totalDependency.add(location);\n            }\n        }\n\n        public synchronized List<String> getTotalDependency(){\n            if(totalDependency == null){\n                totalDependency = new ArrayList<String>();\n                findBundleTransitively(getPkgName(),totalDependency);\n            }\n            ArrayList<String> temp_dependency = new ArrayList<String>();\n            temp_dependency.addAll(totalDependency);\n            return temp_dependency;\n        }\n\n        private void findBundleTransitively(String location,List<String> bundlesListForInstall){\n//            //打断循环依赖\n            findBundleTransitivelyInternal(location,bundlesListForInstall,location);\n        }\n\n        private void findBundleTransitivelyInternal(String location,List<String> bundlesListForInstall,final String root){\n//            //打断循环依赖\n            if(!bundlesListForInstall.contains(location)) {\n                bundlesListForInstall.add(0,location);\n            }else{\n                if(!location.equals(root)) {\n                    bundlesListForInstall.remove(location);\n                    bundlesListForInstall.add(0, location);\n                }\n                return;\n            }\n\n            List<String> singleLevelDependencies = AtlasBundleInfoManager.instance().getDependencyForBundle(location);\n            if(singleLevelDependencies!=null){\n                for(String dependepcy : singleLevelDependencies){\n                    if(dependepcy!=null){\n                        findBundleTransitivelyInternal(dependepcy,bundlesListForInstall,root);\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/bundleInfo/BundleListingUtil.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.bundleInfo;\n\nimport android.text.TextUtils;\n\nimport android.util.Log;\nimport org.json.JSONArray;\nimport org.json.JSONObject;\n\nimport java.io.IOException;\nimport java.util.*;\n\n/**\n * Created by guanjie on 15/7/7.\n */\npublic class BundleListingUtil {\n\n    public static LinkedHashMap<String,BundleListing.BundleInfo> parseArray(String listingStr) throws Exception{\n        LinkedHashMap<String,BundleListing.BundleInfo> infos= new LinkedHashMap<>();\n        JSONArray array = new JSONArray(listingStr);\n        for(int x=0; x<array.length(); x++){\n            JSONObject object = array.getJSONObject(x);\n            BundleListing.BundleInfo info = new BundleListing.BundleInfo();\n            info.name = object.optString(\"name\");\n            info.pkgName = object.optString(\"pkgName\");\n            info.applicationName = object.optString(\"applicationName\");\n            info.version = object.optString(\"version\");\n            info.desc = object.optString(\"desc\");\n            info.url = object.optString(\"url\");\n            info.md5 = object.optString(\"md5\");\n            String uniqueTag = object.optString(\"unique_tag\");\n            if(TextUtils.isEmpty(uniqueTag)){\n                throw new IOException(\"uniqueTag is empty\");\n            }\n            info.unique_tag = object.optString(\"unique_tag\");\n            if (object.has(\"isInternal\")) {\n                info.isInternal = object.optBoolean(\"isInternal\");\n            }\n            if (object.has(\"isMBundle\")) {\n                info.isMBundle = object.optBoolean(\"isMBundle\");\n            }\n\n            JSONArray dependency = object.optJSONArray(\"dependency\");\n            if(dependency!=null && dependency.length()>0){\n                List<String> dependencyList = new ArrayList<String>();\n                for(int i=0; i<dependency.length(); i++){\n                    dependencyList.add(dependency.getString(i));\n                }\n                info.setDependency(dependencyList);\n            }\n\n            JSONArray activities = object.optJSONArray(\"activities\");\n            if(activities!=null && activities.length()>0){\n                HashMap<String,Boolean> activitiesList = new HashMap<String,Boolean>();\n                for(int i=0; i<activities.length(); i++){\n                    activitiesList.put(activities.getString(i),Boolean.FALSE);\n                }\n                info.activities = activitiesList;\n            }\n\n            JSONArray services = object.optJSONArray(\"services\");\n            if(services!=null && services.length()>0){\n                HashMap<String,Boolean> servicesList = new HashMap<String,Boolean>();\n                for(int i=0; i<services.length(); i++){\n                    servicesList.put(services.getString(i),Boolean.FALSE);\n                }\n                info.services = servicesList;\n            }\n\n            JSONArray receivers = object.optJSONArray(\"receivers\");\n            if(receivers!=null && receivers.length()>0){\n                HashMap<String,Boolean> receiversList = new HashMap<String,Boolean>();\n                for(int i=0; i<receivers.length(); i++){\n                    receiversList.put(receivers.getString(i),Boolean.FALSE);\n                }\n                info.receivers = receiversList;\n            }\n\n            JSONArray contentProviders = object.optJSONArray(\"contentProviders\");\n            if(contentProviders!=null && contentProviders.length()>0){\n                HashMap<String,Boolean> contentProvidersList = new HashMap<String,Boolean>();\n                for(int i=0; i<contentProviders.length(); i++){\n                    contentProvidersList.put(contentProviders.getString(i),Boolean.FALSE);\n                }\n                info.contentProviders = contentProvidersList;\n            }\n\n            JSONObject remoteFragments = object.optJSONObject(\"remoteFragments\");\n            if (remoteFragments != null && remoteFragments.length() > 0) {\n                HashMap<String, String> remoteFragmentsList = new HashMap<String, String>();\n\n                final Iterator keys = remoteFragments.keys();\n                while (keys.hasNext()) {\n                    final String next = (String) keys.next();\n\n                    // Could be single object or array.\n                    final String remoteFragment = remoteFragments.getString(next);\n                    if (remoteFragment == null) {\n                        Log.w(\"BundleListingUtil\",\n                                \"parseArray: No remoteFragment found for next \" + next);\n                    } else {\n                        remoteFragmentsList.put(next, remoteFragment);\n                    }\n                }\n\n                info.remoteFragments = remoteFragmentsList;\n            }\n\n            JSONObject remoteViews = object.optJSONObject(\"remoteViews\");\n            if (remoteViews != null && remoteViews.length() > 0) {\n                HashMap<String, String> remoteViewsList = new HashMap<String, String>();\n\n                final Iterator keys = remoteViews.keys();\n                while (keys.hasNext()) {\n                    final String next = (String) keys.next();\n\n                    // Could be single object or array.\n                    final String remoteView = remoteViews.getString(next);\n                    if (remoteView == null) {\n                        Log.w(\"BundleListingUtil\",\n                                \"parseArray: No remoteView found for next \" + next);\n                    } else {\n                        remoteViewsList.put(next, remoteView);\n                    }\n                }\n\n                info.remoteViews = remoteViewsList;\n            }\n\n            JSONObject remoteTransactors = object.optJSONObject(\"remoteTransactors\");\n            if (remoteTransactors != null && remoteTransactors.length() > 0) {\n                HashMap<String, String> remoteTransactorsList = new HashMap<String, String>();\n\n                final Iterator keys = remoteTransactors.keys();\n                while (keys.hasNext()) {\n                    final String next = (String) keys.next();\n\n                    // Could be single object or array.\n                    final String remoteTransactor = remoteTransactors.getString(next);\n                    if (remoteTransactor == null) {\n                        Log.w(\"BundleListingUtil\",\n                                \"parseArray: No remoteTransactor found for next \" + next);\n                    } else {\n                        remoteTransactorsList.put(next, remoteTransactor);\n                    }\n                }\n\n                info.remoteTransactors = remoteTransactorsList;\n            }\n\n            infos.put(info.getPkgName(),info);\n\n        }\n        return infos.size()>0 ? infos : null;\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/framework/Atlas.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.framework;\n\nimport android.app.Activity;\nimport android.app.Application;\nimport android.app.Dialog;\nimport android.content.Intent;\nimport android.content.pm.ApplicationInfo;\nimport android.content.res.Resources;\nimport android.net.Uri;\nimport android.os.Build;\nimport android.os.Looper;\nimport android.taobao.atlas.hack.AssertionArrayException;\nimport android.taobao.atlas.runtime.ActivityTaskMgr;\nimport android.taobao.atlas.runtime.FrameworkLifecycleHandler;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport java.util.Set;\n\n\npublic class Atlas {\n\n    public static String sAPKSource ;\n    public static boolean Downgrade_H5 = false;\n    public static boolean isDebug;\n\n\n    public static Set<String> sDisableBundle = null;\n\n    private Atlas(){\n    }\n\n//    private static class SingleTonHolder{\n        private final static Atlas INSTANCE = new Atlas();\n//    }\n\n    public static Atlas getInstance() {\n       return INSTANCE;\n    }\n\n    private FrameworkLifecycleHandler frameworkLifecycleHandler;\n\n    /**\n     * Init the framework\n     * \n     * @param application\n     * @return\n     * @throws Exception\n     */\n    public void init(Application application,boolean reset) throws AssertionArrayException, Exception {\n        if(application==null){\n            throw new RuntimeException(\"application is null,atlas init failed!\");\n        }\n        ApplicationInfo app_info = application.getApplicationInfo();\n        sAPKSource = app_info.sourceDir;\n        RuntimeVariables.androidApplication = application;\n        RuntimeVariables.delegateResources  = application.getResources();\n        Framework.containerVersion = RuntimeVariables.sInstalledVersionName;\n        ClassLoader cl = Atlas.class.getClassLoader();\n        Framework.systemClassLoader = cl;\n        // defineAndVerify\n        String packageName = application.getPackageName();\n\n        RuntimeVariables.delegateClassLoader = Atlas.class.getClassLoader();\n\n        frameworkLifecycleHandler = new FrameworkLifecycleHandler();\n        Framework.frameworkListeners.add(frameworkLifecycleHandler);\n\n    }\n\n    public void startup(Application application,boolean isUpdated) {\n        if(!RuntimeVariables.safeMode) {\n            try {\n                Framework.startup(isUpdated);\n            } catch (Exception e) {\n                throw new RuntimeException( e);\n            }\n            if(RuntimeVariables.sCurrentProcessName.equals(RuntimeVariables.androidApplication.getPackageName())) {\n                System.setProperty(\"BUNDLES_INSTALLED\", \"true\");\n//                application.getBaseContext().sendBroadcast(new Intent(\"com.taobao.taobao.action.BUNDLES_INSTALLED\"));\n            }\n        }\n    }\n\n    public void checkDownGradeToH5(Intent intent) {\n        if (Downgrade_H5) {\n            if (intent != null && intent.getComponent() != null) {\n                intent.setComponent(null);\n            }\n            String url = intent.getDataString();\n            if(!TextUtils.isEmpty(url)){\n                if(url.contains(\"?\")){\n                    url = url+\"&hybrid=true\";\n                }else{\n                    url = url+\"?hybrid=true\";\n                }\n            }\n            intent.setData(Uri.parse(url));\n            intent.addCategory(\"com.taobao.intent.category.HYBRID_UI\");\n        }\n    }\n\n    private void checkingThread(boolean strict){\n        if(Thread.currentThread().getId()==Looper.getMainLooper().getThread().getId() && Framework.isDeubgMode()){\n            if(strict) {\n                throw new RuntimeException(\"can not install bundle in ui thread\");\n            }else{\n                Log.w(\"Atlas\",\"can not install bundle in ui thread\");\n            }\n        }\n    }\n\n\n\n\n    /**\n     * 设置bundle安装的校验器，会在bundle启动时回调提示校验，校验不通过将无法运行\n     * @param checker\n     */\n    public void setBundleSecurityChecker(BundleVerifier checker){\n        RuntimeVariables.sBundleVerifier = checker;\n    }\n\n    public static boolean isDisableBundle(String bundleName) {\n        Set<String> disableBundle = sDisableBundle;\n        if (disableBundle != null) {\n            return disableBundle.contains(bundleName);\n        }\n        return false;\n    }\n\n    public void forceStopSelf(){\n//        setPackageStoppedState\n    }\n\n    /*************************************************↑↑↑↑↑↑for public use↑↑↑↑↑↑*************************************************************\n     **************************************************↑↑↑↑↑↑for public use↑↑↑↑↑↑*************************************************************\n     **************************************************↑↑↑↑↑↑for public use↑↑↑↑↑↑***************************************************************/\n\n    public static interface ExternalBundleInstallReminder{\n        public Dialog createReminderDialog(Activity activity,String installingBundleName);\n    }\n\n    public static interface BundleVerifier{\n        public boolean verifyBundle(String bundlePath);\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/framework/Framework.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.framework;\n\nimport android.content.Context;\nimport android.content.pm.ApplicationInfo;\nimport android.os.Build;\nimport android.os.Environment;\nimport android.os.Looper;\nimport android.os.Process;\nimport android.taobao.atlas.bundleInfo.AtlasBundleInfoManager;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.taobao.atlas.util.AtlasFileLock;\nimport android.taobao.atlas.util.BundleLock;\nimport android.taobao.atlas.versionInfo.BaselineInfoManager;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport org.osgi.framework.Bundle;\nimport org.osgi.framework.BundleEvent;\nimport org.osgi.framework.BundleException;\nimport org.osgi.framework.BundleListener;\nimport org.osgi.framework.FrameworkEvent;\nimport org.osgi.framework.FrameworkListener;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.lang.reflect.Array;\nimport java.lang.reflect.Constructor;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport android.os.*;\nimport android.widget.Toast;\n\nimport java.util.zip.ZipEntry;\n\nimport static android.os.Environment.MEDIA_UNKNOWN;\n\npublic final class Framework {\n\n    public final static String DEPRECATED_MARK = \"deprecated\";\n    static String containerVersion = \"\";\n\n    /**\n     * framework basedir.\n     */\n    private static String BASEDIR;\n\n    /**\n     * the location where the storage resides.\n     */\n    public static final String STORAGE_LOCATION;\n\n    /**\n     * debug outputs from bundles ?\n     */\n    static boolean DEBUG_BUNDLES;\n\n    /**\n     * location -> bundle.\n     */\n    public static Map<String, Bundle> bundles = new ConcurrentHashMap<String, Bundle>();\n\n    /**\n     * bundle listeners.\n     */\n    static List<BundleListener> bundleListeners = new ArrayList<BundleListener>();\n\n    /**\n     * synchronous bundle listeners.\n     */\n    static List<BundleListener> syncBundleListeners = new ArrayList<BundleListener>();\n\n    /**\n     * framework listeners.\n     */\n    static List<FrameworkListener> frameworkListeners = new ArrayList<FrameworkListener>();\n\n    static HashMap<String,Integer> installingBundles = new HashMap<>();\n\n    /**\n     * system ClassLoader\n     */\n    static ClassLoader systemClassLoader;\n\n    private static boolean bundleUpdated = false;\n    public static boolean updateHappend = false;\n    public static boolean DEBUG = false;\n\n    static {\n        File fileDir = RuntimeVariables.androidApplication.getFilesDir();\n        if (fileDir == null || !fileDir.exists()) {\n            fileDir = RuntimeVariables.androidApplication.getFilesDir();\n        }\n        BASEDIR = fileDir.getAbsolutePath();\n        STORAGE_LOCATION = BASEDIR + File.separatorChar + \"storage\" + File.separatorChar;\n\n        try {\n            ApplicationInfo app_info = RuntimeVariables.androidApplication.getApplicationInfo();\n            DEBUG = (app_info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;\n        } catch (final Exception e) {\n            DEBUG = true;\n        }\n    }\n\n    /**\n     * Hide defautlt constructor\n     */\n    private Framework() {\n    }\n\n    /**\n     * launch the framework.\n     *\n     * @throws Throwable\n     */\n    static void startup(boolean updated) throws BundleException {\n        AtlasBundleInfoManager.instance().getBundleInfo();\n        notifyFrameworkListeners(0 /* STARTING */, null, null);\n        notifyFrameworkListeners(FrameworkEvent.STARTED, null, null);\n    }\n\n    public static ClassLoader getSystemClassLoader() {\n        return systemClassLoader;\n    }\n\n    public static List<Bundle> getBundles() {\n        final List<Bundle> res = new ArrayList<Bundle>(bundles.size());\n        synchronized (bundles) {\n            res.addAll(bundles.values());\n        }\n        return res;\n    }\n\n    public synchronized static Bundle getBundle(String location) {\n        if (location == null){\n            return null;\n        }\n        return bundles.get(location);\n    }\n\n    /**\n     * delete a directory with all subdirs.\n     *\n     * @param path the directory.\n     */\n    public static void deleteDirectory(final File path) {\n        final File[] files = path.listFiles();\n        if (files == null){\n            return;\n        }\n        Log.e(\"delete\",path.getAbsolutePath());\n        for (int i = 0; i < files.length; i++) {\n            if (files[i].isDirectory()) {\n                deleteDirectory(files[i]);\n            } else {\n                files[i].delete();\n            }\n        }\n        path.delete();\n    }\n\n    public static void update(boolean upgrade,final String[] locations, final File[] files, String[] newBundleTag,long[] dexPatchVersions,String newBaselineVersion,boolean lowInternalDisk) throws BundleException {\n        if (locations == null || files == null || locations.length != files.length) {\n            throw new IllegalArgumentException(\"locations and files must not be null and must be same length\");\n        }\n        Class KernalBundleClass = null;\n        HashMap<String,String> updateBundles = new HashMap<>();\n        File updateStorageDir = new File(STORAGE_LOCATION);\n        if(lowInternalDisk){\n            updateStorageDir = null;\n            File[] externalStorages = getExternalFilesDirs(RuntimeVariables.androidApplication,\"storage\");\n            if(externalStorages!=null && externalStorages.length>0){\n                for(File externalStorage : externalStorages){\n                    if(externalStorage!=null && getStorageState(externalStorage).equals(Environment.MEDIA_MOUNTED) && externalStorage.getUsableSpace()>50*1024*1024) {\n                        updateStorageDir = externalStorage;\n                    }\n                }\n            }\n        }\n        if(updateStorageDir==null){\n            throw new BundleException(\"no enough space\");\n        }\n        updateHappend = true;\n        for (int i = 0; i < locations.length; i++) {\n            //reset\n            if(!upgrade && dexPatchVersions[i]==-1){\n                updateBundles.put(locations[i],\"-1\");\n                continue;\n            }\n\n            if (locations[i] == null || files[i] == null) {\n                continue;\n            }\n\n            File bundleDir = null;\n            try {\n                if (isKernalBundle(locations[i])) {\n                    BundleLock.WriteLock(locations[i]);\n                    KernalBundleClass = RuntimeVariables.getRawClassLoader().loadClass(\"android.taobao.atlas.startup.patch.KernalBundle\");\n                    bundleDir = new File(updateStorageDir, \"com.taobao.maindex\");\n                    if (!bundleDir.exists()){\n                        bundleDir.mkdirs();\n                    }\n                    AtlasFileLock.getInstance().LockExclusive(bundleDir);\n                    Constructor cons = KernalBundleClass.getDeclaredConstructor(File.class,File.class,String.class,long.class);\n                    cons.setAccessible(true);\n                    if(upgrade) {\n                        cons.newInstance(bundleDir, files[i], makeMainDexUniqueTag(newBaselineVersion,newBundleTag[i]), -1l);\n                    }else{\n                        cons.newInstance(bundleDir, files[i],null,dexPatchVersions[i]);                    }\n                } else {\n\n                }\n                if(upgrade){\n                    updateBundles.put(locations[i],newBundleTag[i]);\n                }else{\n                    updateBundles.put(locations[i],Long.toString(dexPatchVersions[i]));\n                }\n            } catch (Exception e) {\n                if(upgrade) {\n                    throw new BundleException(\"failed to installOrUpdate bundles \", e);\n                }\n            } finally {\n                if (bundleDir != null) {\n                    AtlasFileLock.getInstance().unLock(bundleDir);\n                }\n                BundleLock.WriteUnLock(locations[i]);\n            }\n        }\n\n            if(updateBundles.size()>0){\n                try {\n                    BaselineInfoManager.instance().saveDexPathInfo(updateBundles,lowInternalDisk ? updateStorageDir.getAbsolutePath() : \"\");\n                } catch (IOException e) {\n                    throw new BundleException(\"save dexpatch info fail\");\n                }\n            }\n\n    }\n\n    private static String makeMainDexUniqueTag(String appVersion,String maindexTag){\n        if(maindexTag.startsWith(appVersion)){\n            return maindexTag;\n        }\n        return appVersion+\"_\"+maindexTag;\n    }\n\n    public static void rollback(){\n        BaselineInfoManager.instance().rollback();\n    }\n\n    static boolean isKernalBundle(String location) {\n        if (TextUtils.isEmpty(location)) {\n            return false;\n        }\n        return location.equals(\"com.taobao.maindex\");\n    }\n\n\n\n\n\n\n\n\n    /**\n     * notify all framework listeners.\n     *\n     * @param state the new state.\n     * @param bundle the bundle.\n     * @param throwable a throwable.\n     */\n    static void notifyFrameworkListeners(final int state, final Bundle bundle, final Throwable throwable) {\n\n        if (frameworkListeners.isEmpty()) {\n            return;\n        }\n\n        final FrameworkEvent event = new FrameworkEvent(state);\n\n        final FrameworkListener[] listeners = frameworkListeners.toArray(new FrameworkListener[frameworkListeners.size()]);\n\n        for (int i = 0; i < listeners.length; i++) {\n            final FrameworkListener listener = listeners[i];\n\n            listener.frameworkEvent(event);\n        }\n    }\n\n    public static File[] getExternalFilesDirs(Context context, String type) {\n        final int version = Build.VERSION.SDK_INT;\n        if (version >= 19) {\n            //返回结果可能存在null值\n            return context.getExternalFilesDirs(type);\n        } else {\n            return new File[] { context.getExternalFilesDir(type) };\n        }\n    }\n\n    public static String getStorageState(File path) {\n        final int version = Build.VERSION.SDK_INT;\n        if (version >= 19) {\n            return Environment.getStorageState(path);\n        }\n\n        try {\n            final String canonicalPath = path.getCanonicalPath();\n            final String canonicalExternal = Environment.getExternalStorageDirectory()\n                    .getCanonicalPath();\n\n            if (canonicalPath.startsWith(canonicalExternal)) {\n                return Environment.getExternalStorageState();\n            }\n        } catch (IOException e) {\n        }\n\n        return MEDIA_UNKNOWN;\n    }\n\n\n\n\n    public static boolean isDeubgMode() {\n        return DEBUG;\n    }\n}"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/framework/FrameworkProperties.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.framework;\n\n/**\n * Created by guanjie on 2016/12/8.\n */\n\npublic class FrameworkProperties {\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/hack/AndroidHack.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.hack;\n\nimport android.app.Application;\nimport android.app.Instrumentation;\nimport android.content.Context;\nimport android.content.ContextWrapper;\nimport android.content.pm.ApplicationInfo;\nimport android.content.pm.PackageManager;\nimport android.content.res.Resources;\nimport android.os.Build;\nimport android.os.Handler;\nimport android.os.IBinder;\nimport android.os.Looper;\nimport android.taobao.atlas.framework.Atlas;\nimport android.taobao.atlas.framework.Framework;\nimport android.taobao.atlas.runtime.ActivityTaskMgr;\n\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.util.ArrayMap;\nimport android.util.Log;\n\nimport java.lang.ref.WeakReference;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.WeakHashMap;\n\npublic class AndroidHack {\n\n    private static Object _sActivityThread = null;\n    private static Object _mLoadedApk      = null;\n\n    public static Object getActivityThread() throws Exception {\n        if (_sActivityThread == null) {\n            if (Thread.currentThread().getId() == Looper.getMainLooper().getThread().getId()) {\n                _sActivityThread = AtlasHacks.ActivityThread_currentActivityThread.invoke(null);\n            } else {\n                Handler handler = new Handler(Looper.getMainLooper());\n                synchronized (AtlasHacks.ActivityThread_currentActivityThread) {\n                    handler.post(new ActvityThreadGetter());\n                    AtlasHacks.ActivityThread_currentActivityThread.wait();\n                }\n            }\n        }\n        return _sActivityThread;\n    }\n\n\n\n    public static Object getLoadedApk(Application application,Object activityThread, String packageName) {\n        if(_mLoadedApk!=null){\n            return _mLoadedApk;\n        }else {\n            Map<String, Object> mPackages = (Map<String, Object>) AtlasHacks.ActivityThread_mPackages.get(activityThread);\n            WeakReference<?> rf = (WeakReference<?>) mPackages.get(packageName);\n            if (rf != null && rf.get() != null) {\n                _mLoadedApk = rf.get();\n                return rf.get();\n            }\n        }\n        return null;\n    }\n\n    /**\n     * 用getPackageInfoNoCheck 创建一个新的LoadedApk\n     * @param application\n     * @param activityThread\n     * @return\n     */\n    public static Object createNewLoadedApk(Application application,Object activityThread){\n        try {\n            PackageManager manager = RuntimeVariables.androidApplication.getPackageManager();\n            ApplicationInfo info = manager.getApplicationInfo(RuntimeVariables.androidApplication.getPackageName(),PackageManager.GET_ACTIVITIES);\n            String currentSource = info!=null ? info.sourceDir : null;\n            if(Atlas.sAPKSource == null || currentSource==null || !currentSource.equals(Atlas.sAPKSource)){\n                Log.e(\"AndroidHack\",Atlas.sAPKSource + \" | \" + currentSource);\n                ActivityTaskMgr.getInstance().clearActivityStack();\n                android.os.Process.killProcess(android.os.Process.myPid());\n                System.exit(0);\n                return null;\n            }\n\n            ApplicationInfo ai = application.getPackageManager().getApplicationInfo(application.getPackageName(),\n                    PackageManager.GET_META_DATA | PackageManager.GET_SHARED_LIBRARY_FILES);\n            PackageManager packageManager = application.getPackageManager();\n            Resources mResources = application.getResources();\n            Method getCompatibilityInfo = null;\n//            if(mResources instanceof DelegateResources) {\n//                getCompatibilityInfo = mResources.getClass().getSuperclass().getDeclaredMethod(\"getCompatibilityInfo\");\n//            }else{\n                getCompatibilityInfo = findMethod(mResources,\"getCompatibilityInfo\");\n//            }\n            getCompatibilityInfo.setAccessible(true);\n            Class ComplatibilityInfoClass = Class.forName(\"android.content.res.CompatibilityInfo\");\n            Object compatibilityInfo = getCompatibilityInfo.invoke(application.getResources());\n\n            Class<?> args[] = {ApplicationInfo.class,ComplatibilityInfoClass};\n            Method getPackageInfoNoCheck = AtlasHacks.ActivityThread.getmClass().getDeclaredMethod(\n                    \"getPackageInfoNoCheck\", args);\n            getPackageInfoNoCheck.setAccessible(true);\n            Object loadedApk = getPackageInfoNoCheck.invoke(activityThread, ai, compatibilityInfo);\n            _mLoadedApk = loadedApk;\n            Field mApplicationField = _mLoadedApk.getClass().getDeclaredField(\"mApplication\");\n            mApplicationField.setAccessible(true);\n            mApplicationField.set(_mLoadedApk,RuntimeVariables.androidApplication);\n            return loadedApk;\n        }catch(Exception e){\n            e.printStackTrace();\n            throw new RuntimeException(e);\n        }\n    }\n\n//    private static Method findMethod(Object instance, String name,Class<?>... params) throws NoSuchFieldException {\n//        for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {\n//            try {\n//                Method method = clazz.getDeclaredMethod(name, params);\n//\n//\n//                if (!method.isAccessible()) {\n//                    method.setAccessible(true);\n//                }\n//\n//                return method;\n//            } catch (NoSuchMethodException e) {\n//                // ignore and search next\n//            }\n//        }\n//\n//        throw new NoSuchFieldException(\"Field \" + name + \" not found in \" + instance.getClass());\n//    }\n\n    /**\n     * Set classLoader to LoadedApk.mClassLoader and set LoadedApk.mApplication to null\n     *\n     * @param packageName\n     * @param classLoader\n     * @throws Exception\n     */\n    public static void injectClassLoader(String packageName, ClassLoader classLoader) throws Exception {\n\n        try {\n            Object oApplicationLoaders = AtlasHacks.ApplicationLoaders_getDefault.invoke(null);\n            Map<String, ClassLoader> mLoaders = (Map<String, ClassLoader>) AtlasHacks.ApplicationLoaders_mLoaders.get(oApplicationLoaders);\n            for (Map.Entry<String, ClassLoader> e : mLoaders.entrySet()) {\n//                log.v(TAG, \"loader: \" + e.getKey() + \" -> \" + e.getValue());\n                if (e.getValue() == Framework.getSystemClassLoader()) {\n//                    log.v(TAG, \" YES, that is we want!\");\n                    e.setValue(classLoader);\n                }\n            }\n        } catch (Throwable ex) {\n//            log.e(TAG, \"fail to replace ApplicationLoaders.mLoaders[PKG]\", ex);\n            ex.printStackTrace();\n        }\n\n        Object activityThread = getActivityThread();\n        if (activityThread == null) {\n            throw new Exception(\"Failed to get ActivityThread.sCurrentActivityThread\");\n        }\n\n        // Try to get loadedAPK from weak reference cache\n        Object loadedApk = getLoadedApk(RuntimeVariables.androidApplication,activityThread, packageName);\n        if(loadedApk==null){\n            loadedApk = createNewLoadedApk(RuntimeVariables.androidApplication,activityThread);\n        }\n        if (loadedApk == null) {\n            throw new Exception(\"Failed to get ActivityThread.mLoadedApk\");\n        }\n\n        //AtlasHacks.LoadedApk_mClassLoader.on(loadedApk).set(classLoader);\n        AtlasHacks.LoadedApk_mClassLoader.set(loadedApk,classLoader);\n        //AtlasHacks.LoadedApk_mApplication.on(loadedApk).set(null);\n    }\n\n//    public static void injectApplication(String packageName, Application application) throws Exception {\n//        Object activityThread = getActivityThread();\n//        if (activityThread == null) {\n//            throw new Exception(\"Failed to get ActivityThread.sCurrentActivityThread\");\n//        }\n//\n//        Object loadedApk = getLoadedApk(application,activityThread, application.getPackageName());\n//        if (loadedApk == null) {\n//            throw new Exception(\"Failed to get ActivityThread.mLoadedApk\");\n//        }\n//\n////        try{\n////            Field field = activityThread.getClass().getDeclaredField(\"mAllApplications\");\n////            field.setAccessible(true);\n////            ArrayList<Application> mAllApplications = (ArrayList<Application>)field.get(activityThread);\n////            mAllApplications.add(RuntimeVariables.androidApplication);\n////        }catch(Throwable e){}\n//        AtlasHacks.LoadedApk_mApplication.set(loadedApk,application);\n//        AtlasHacks.ActivityThread_mInitialApplication.set(activityThread,application);\n//    }\n\n\n\n    static Field sActiveResourcesField =null;\n    static Class sResourcesManagerClazz = null;\n    static Method sgetInstanceMethod = null;\n    static Field sAssetsField = null;\n    static{\n        try {\n            if (Build.VERSION.SDK_INT <= 18) {\n                Class ActivityThreadClazz = Class.forName(\"android.app.ActivityThread\");\n                sActiveResourcesField = ActivityThreadClazz.getDeclaredField(\"mActiveResources\");\n                sActiveResourcesField.setAccessible(true);\n                sAssetsField = Resources.class.getDeclaredField(\"mAssets\");\n                sAssetsField.setAccessible(true);\n            } else if (Build.VERSION.SDK_INT < 24) {\n                sResourcesManagerClazz = Class.forName(\"android.app.ResourcesManager\");\n                sActiveResourcesField = sResourcesManagerClazz.getDeclaredField(\"mActiveResources\");\n                sActiveResourcesField.setAccessible(true);\n                sgetInstanceMethod = sResourcesManagerClazz.getDeclaredMethod(\"getInstance\");\n                sgetInstanceMethod.setAccessible(true);\n                sAssetsField = Resources.class.getDeclaredField(\"mAssets\");\n                sAssetsField.setAccessible(true);\n            } else {\n                sResourcesManagerClazz = Class.forName(\"android.app.ResourcesManager\");\n                sActiveResourcesField = sResourcesManagerClazz.getDeclaredField(\"mResourceReferences\");\n                sActiveResourcesField.setAccessible(true);\n                sgetInstanceMethod = sResourcesManagerClazz.getDeclaredMethod(\"getInstance\");\n                sgetInstanceMethod.setAccessible(true);\n            }\n        }catch(Throwable e){}\n    }\n\n    public static Field findField(Object instance, String name) throws NoSuchFieldException {\n        for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {\n            try {\n                Field field = clazz.getDeclaredField(name);\n\n\n                if (!field.isAccessible()) {\n                    field.setAccessible(true);\n                }\n\n                return field;\n            } catch (NoSuchFieldException e) {\n                // ignore and search next\n            }\n        }\n\n        throw new NoSuchFieldException(\"Field \" + name + \" not found in \" + instance.getClass());\n    }\n\n    public static Method findMethod(Object instance, String name,Class<?>... args) throws NoSuchMethodException {\n        for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {\n            try {\n                Method method = clazz.getDeclaredMethod(name,args);\n\n                if (!method.isAccessible()) {\n                    method.setAccessible(true);\n                }\n\n                return method;\n            } catch (NoSuchMethodException e) {\n                // ignore and search next\n            }\n        }\n        throw new NoSuchMethodException(\"Method \" + name + \" not found in \" + instance.getClass());\n    }\n\n    public static Instrumentation getInstrumentation() throws Exception {\n        Object activityThread = getActivityThread();\n        if (activityThread == null) {\n            throw new Exception(\"Failed to get ActivityThread.sCurrentActivityThread\");\n        }\n        //return (Instrumentation)AtlasHacks.ActivityThread_mInstrumentation.on(activityThread).get();\n        return (Instrumentation)AtlasHacks.ActivityThread_mInstrumentation.get(activityThread);\n    }\n\n    public static void injectInstrumentationHook(Instrumentation instrumentation) throws Exception {\n        Object activityThread = getActivityThread();\n        if (activityThread == null) {\n            throw new Exception(\"Failed to get ActivityThread.sCurrentActivityThread\");\n        }\n        //AtlasHacks.ActivityThread_mInstrumentation.on(activityThread).set(instrumentation);\n        AtlasHacks.ActivityThread_mInstrumentation.set(activityThread,instrumentation);\n    }\n\n//    public static void injectContextHook(ContextWrapper wrapper, ContextWrapper contextHook) {\n//        //AtlasHacks.ContextWrapper_mBase.on(wrapper).set(contextHook);\n//        AtlasHacks.ContextWrapper_mBase.set(wrapper,contextHook);\n//    }\n\n    static class ActvityThreadGetter implements Runnable {\n\n        @Override\n        public void run() {\n\n            Class<?> activityThreadCls = AtlasHacks.ActivityThread.getmClass();\n            try {\n                _sActivityThread = AtlasHacks.ActivityThread_currentActivityThread.invoke(activityThreadCls);\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n            synchronized (AtlasHacks.ActivityThread_currentActivityThread) {\n                AtlasHacks.ActivityThread_currentActivityThread.notify();\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/hack/AssertionArrayException.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.hack;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport android.taobao.atlas.hack.Hack.HackDeclaration.HackAssertionException;\n\n/**\n * 校验android平台 atlas hack失败列表 getExceptions获取所有HackAssertionException列表\n * \n * @author bokui\n */\npublic class AssertionArrayException extends Exception {\n\n    private static final long            serialVersionUID = 1L;\n    private List<HackAssertionException> mAssertionErr    = new ArrayList<HackAssertionException>();\n\n    public AssertionArrayException(String detailMsg){\n        super(detailMsg);\n    }\n\n    /**\n     * 添加hack异常\n     * \n     * @param exception hack异常实例\n     */\n    public void addException(HackAssertionException exception) {\n        mAssertionErr.add(exception);\n    }\n\n    public void addException(List<HackAssertionException> exception) {\n        mAssertionErr.addAll(exception);\n    }\n\n    /**\n     * 获取hack异常列表\n     * \n     * @return hack异常列表\n     */\n    public List<HackAssertionException> getExceptions() {\n        return mAssertionErr;\n    }\n\n    /**\n     * 合并异常，first为null 则返回second second为空 则返回first 都为空则返回null 都不为空则合并\n     * \n     * @param first AssertionArrayException实例\n     * @param second AssertionArrayException实例\n     * @return\n     */\n    public static AssertionArrayException mergeException(AssertionArrayException first, AssertionArrayException second) {\n        if (first == null) return second;\n        if (second == null) return first;\n        String detailMsg = first.getMessage() + \";\" + second.getMessage();\n        AssertionArrayException ret = new AssertionArrayException(detailMsg);\n        ret.addException(first.getExceptions());\n        ret.addException(second.getExceptions());\n        return ret;\n\n    }\n\n    public String toString() {\n        StringBuilder sb = new StringBuilder();\n\n        for (HackAssertionException failure : mAssertionErr) {\n            sb.append(failure.toString()).append(\";\");\n            try {\n                if (failure.getCause() instanceof NoSuchFieldException) {\n                    Field[] fields = failure.getHackedClass().getDeclaredFields();\n                    sb.append(failure.getHackedClass().getName()).append(\".\").append(failure.getHackedFieldName()).append(\";\");\n                    for (int i = 0; i < fields.length; i++) {\n                        sb.append(fields[i].getName()).append(\"/\");\n                    }\n                } else if (failure.getCause() instanceof NoSuchMethodException) {\n                    Method[] methods = failure.getHackedClass().getDeclaredMethods();\n                    sb.append(failure.getHackedClass().getName()).append(\"->\").append(failure.getHackedMethodName()).append(\";\");\n                    for (int i = 0; i < methods.length; i++) {\n                        if (failure.getHackedMethodName().equals(methods[i].getName())) {\n                            sb.append(methods[i].toGenericString()).append(\"/\");\n                        }\n                    }\n                } else{\n                    sb.append(failure.getCause());\n                }\n            } catch (Exception ex) {\n                ex.printStackTrace();\n            }\n            sb.append(\"@@@@\");\n        }\n        \n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/hack/AtlasHacks.java",
    "content": "/*\r\n *\r\n *                                Apache License\r\n *                          Version 2.0, January 2004\r\n *                       http://www.apache.org/licenses/\r\n *\r\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r\n *\r\n *  1. Definitions.\r\n *\r\n *     \"License\" shall mean the terms and conditions for use, reproduction,\r\n *     and distribution as defined by Sections 1 through 9 of this document.\r\n *\r\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\r\n *     the copyright owner that is granting the License.\r\n *\r\n *     \"Legal Entity\" shall mean the union of the acting entity and all\r\n *     other entities that control, are controlled by, or are under common\r\n *     control with that entity. For the purposes of this definition,\r\n *     \"control\" means (i) the power, direct or indirect, to cause the\r\n *     direction or management of such entity, whether by contract or\r\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\r\n *     outstanding shares, or (iii) beneficial ownership of such entity.\r\n *\r\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\r\n *     exercising permissions granted by this License.\r\n *\r\n *     \"Source\" form shall mean the preferred form for making modifications,\r\n *     including but not limited to software source code, documentation\r\n *     source, and configuration files.\r\n *\r\n *     \"Object\" form shall mean any form resulting from mechanical\r\n *     transformation or translation of a Source form, including but\r\n *     not limited to compiled object code, generated documentation,\r\n *     and conversions to other media types.\r\n *\r\n *     \"Work\" shall mean the work of authorship, whether in Source or\r\n *     Object form, made available under the License, as indicated by a\r\n *     copyright notice that is included in or attached to the work\r\n *     (an example is provided in the Appendix below).\r\n *\r\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\r\n *     form, that is based on (or derived from) the Work and for which the\r\n *     editorial revisions, annotations, elaborations, or other modifications\r\n *     represent, as a whole, an original work of authorship. For the purposes\r\n *     of this License, Derivative Works shall not include works that remain\r\n *     separable from, or merely link (or bind by name) to the interfaces of,\r\n *     the Work and Derivative Works thereof.\r\n *\r\n *     \"Contribution\" shall mean any work of authorship, including\r\n *     the original version of the Work and any modifications or additions\r\n *     to that Work or Derivative Works thereof, that is intentionally\r\n *     submitted to Licensor for inclusion in the Work by the copyright owner\r\n *     or by an individual or Legal Entity authorized to submit on behalf of\r\n *     the copyright owner. For the purposes of this definition, \"submitted\"\r\n *     means any form of electronic, verbal, or written communication sent\r\n *     to the Licensor or its representatives, including but not limited to\r\n *     communication on electronic mailing lists, source code control systems,\r\n *     and issue tracking systems that are managed by, or on behalf of, the\r\n *     Licensor for the purpose of discussing and improving the Work, but\r\n *     excluding communication that is conspicuously marked or otherwise\r\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\r\n *\r\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\r\n *     on behalf of whom a Contribution has been received by Licensor and\r\n *     subsequently incorporated within the Work.\r\n *\r\n *  2. Grant of Copyright License. Subject to the terms and conditions of\r\n *     this License, each Contributor hereby grants to You a perpetual,\r\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n *     copyright license to reproduce, prepare Derivative Works of,\r\n *     publicly display, publicly perform, sublicense, and distribute the\r\n *     Work and such Derivative Works in Source or Object form.\r\n *\r\n *  3. Grant of Patent License. Subject to the terms and conditions of\r\n *     this License, each Contributor hereby grants to You a perpetual,\r\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n *     (except as stated in this section) patent license to make, have made,\r\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\r\n *     where such license applies only to those patent claims licensable\r\n *     by such Contributor that are necessarily infringed by their\r\n *     Contribution(s) alone or by combination of their Contribution(s)\r\n *     with the Work to which such Contribution(s) was submitted. If You\r\n *     institute patent litigation against any entity (including a\r\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\r\n *     or a Contribution incorporated within the Work constitutes direct\r\n *     or contributory patent infringement, then any patent licenses\r\n *     granted to You under this License for that Work shall terminate\r\n *     as of the date such litigation is filed.\r\n *\r\n *  4. Redistribution. You may reproduce and distribute copies of the\r\n *     Work or Derivative Works thereof in any medium, with or without\r\n *     modifications, and in Source or Object form, provided that You\r\n *     meet the following conditions:\r\n *\r\n *     (a) You must give any other recipients of the Work or\r\n *         Derivative Works a copy of this License; and\r\n *\r\n *     (b) You must cause any modified files to carry prominent notices\r\n *         stating that You changed the files; and\r\n *\r\n *     (c) You must retain, in the Source form of any Derivative Works\r\n *         that You distribute, all copyright, patent, trademark, and\r\n *         attribution notices from the Source form of the Work,\r\n *         excluding those notices that do not pertain to any part of\r\n *         the Derivative Works; and\r\n *\r\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\r\n *         distribution, then any Derivative Works that You distribute must\r\n *         include a readable copy of the attribution notices contained\r\n *         within such NOTICE file, excluding those notices that do not\r\n *         pertain to any part of the Derivative Works, in at least one\r\n *         of the following places: within a NOTICE text file distributed\r\n *         as part of the Derivative Works; within the Source form or\r\n *         documentation, if provided along with the Derivative Works; or,\r\n *         within a display generated by the Derivative Works, if and\r\n *         wherever such third-party notices normally appear. The contents\r\n *         of the NOTICE file are for informational purposes only and\r\n *         do not modify the License. You may add Your own attribution\r\n *         notices within Derivative Works that You distribute, alongside\r\n *         or as an addendum to the NOTICE text from the Work, provided\r\n *         that such additional attribution notices cannot be construed\r\n *         as modifying the License.\r\n *\r\n *     You may add Your own copyright statement to Your modifications and\r\n *     may provide additional or different license terms and conditions\r\n *     for use, reproduction, or distribution of Your modifications, or\r\n *     for any such Derivative Works as a whole, provided Your use,\r\n *     reproduction, and distribution of the Work otherwise complies with\r\n *     the conditions stated in this License.\r\n *\r\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\r\n *     any Contribution intentionally submitted for inclusion in the Work\r\n *     by You to the Licensor shall be under the terms and conditions of\r\n *     this License, without any additional terms or conditions.\r\n *     Notwithstanding the above, nothing herein shall supersede or modify\r\n *     the terms of any separate license agreement you may have executed\r\n *     with Licensor regarding such Contributions.\r\n *\r\n *  6. Trademarks. This License does not grant permission to use the trade\r\n *     names, trademarks, service marks, or product names of the Licensor,\r\n *     except as required for reasonable and customary use in describing the\r\n *     origin of the Work and reproducing the content of the NOTICE file.\r\n *\r\n *  7. Disclaimer of Warranty. Unless required by applicable law or\r\n *     agreed to in writing, Licensor provides the Work (and each\r\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\r\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r\n *     implied, including, without limitation, any warranties or conditions\r\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\r\n *     appropriateness of using or redistributing the Work and assume any\r\n *     risks associated with Your exercise of permissions under this License.\r\n *\r\n *  8. Limitation of Liability. In no event and under no legal theory,\r\n *     whether in tort (including negligence), contract, or otherwise,\r\n *     unless required by applicable law (such as deliberate and grossly\r\n *     negligent acts) or agreed to in writing, shall any Contributor be\r\n *     liable to You for damages, including any direct, indirect, special,\r\n *     incidental, or consequential damages of any character arising as a\r\n *     result of this License or out of the use or inability to use the\r\n *     Work (including but not limited to damages for loss of goodwill,\r\n *     work stoppage, computer failure or malfunction, or any and all\r\n *     other commercial damages or losses), even if such Contributor\r\n *     has been advised of the possibility of such damages.\r\n *\r\n *  9. Accepting Warranty or Additional Liability. While redistributing\r\n *     the Work or Derivative Works thereof, You may choose to offer,\r\n *     and charge a fee for, acceptance of support, warranty, indemnity,\r\n *     or other liability obligations and/or rights consistent with this\r\n *     License. However, in accepting such obligations, You may act only\r\n *     on Your own behalf and on Your sole responsibility, not on behalf\r\n *     of any other Contributor, and only if You agree to indemnify,\r\n *     defend, and hold each Contributor harmless for any liability\r\n *     incurred by, or claims asserted against, such Contributor by reason\r\n *     of your accepting any such warranty or additional liability.\r\n *\r\n *  END OF TERMS AND CONDITIONS\r\n *\r\n *  APPENDIX: How to apply the Apache License to your work.\r\n *\r\n *     To apply the Apache License to your work, attach the following\r\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\r\n *     replaced with your own identifying information. (Don't include\r\n *     the brackets!)  The text should be enclosed in the appropriate\r\n *     comment syntax for the file format. We also recommend that a\r\n *     file or class name and description of purpose be included on the\r\n *     same \"printed page\" as the copyright notice for easier\r\n *     identification within third-party archives.\r\n *\r\n *  Copyright 2016 Alibaba Group\r\n *\r\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\r\n *  you may not use this file except in compliance with the License.\r\n *  You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n *  Unless required by applicable law or agreed to in writing, software\r\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\r\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n *  See the License for the specific language governing permissions and\r\n *  limitations under the License.\r\n *\r\n *\r\n *\r\n */\r\n\r\npackage android.taobao.atlas.hack;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\nimport java.util.Map;\r\n\r\nimport android.app.Application;\r\n\r\nimport android.app.Instrumentation;\r\nimport android.content.Context;\r\nimport android.content.ContextWrapper;\r\nimport android.content.pm.ApplicationInfo;\r\nimport android.content.pm.ProviderInfo;\r\nimport android.content.res.Resources;\r\nimport android.content.res.Resources.Theme;\r\nimport android.os.Build;\r\nimport android.os.IBinder;\r\nimport android.taobao.atlas.hack.Hack.AssertionFailureHandler;\r\nimport android.taobao.atlas.hack.Hack.HackDeclaration;\r\nimport android.taobao.atlas.hack.Hack.HackedClass;\r\nimport android.taobao.atlas.hack.Hack.HackedField;\r\nimport android.taobao.atlas.hack.Hack.HackedMethod;\r\nimport android.util.Log;\r\nimport android.view.ContextThemeWrapper;\r\n\r\npublic class AtlasHacks extends HackDeclaration implements AssertionFailureHandler {\r\n\r\n    public static boolean                                       sIsReflectAvailable     = false;\r\n    public static boolean                                       sIsReflectChecked       = false;\r\n    public static boolean                                       sIsIgnoreFailure        = false;\r\n\r\n    private AssertionArrayException                             mExceptionArray         = null;\r\n\r\n    // Classes\r\n    public static HackedClass<Object>                           LoadedApk;\r\n    public static HackedClass<Object>                           ActivityThread;\r\n    public static HackedClass<android.content.res.Resources>    Resources;\r\n    public static HackedClass<android.app.Application>          Application;\r\n    public static HackedClass<android.content.res.AssetManager> AssetManager;\r\n    public static HackedClass<Object>                           IPackageManager;\r\n    public static HackedClass<android.app.Service>              Service;\r\n    public static HackedClass<Object>                           ContextImpl;\r\n    public static HackedClass<ContextThemeWrapper>              ContextThemeWrapper;\r\n    public static HackedClass<android.content.ContextWrapper>   ContextWrapper;\r\n    public static HackedClass<java.lang.ClassLoader>            ClassLoader;\r\n    public static HackedClass<dalvik.system.DexClassLoader>     DexClassLoader;\r\n    public static HackedClass<Object>                           LexFile;\r\n    public static HackedClass<Object>                           PackageParser$Component;\r\n    public static HackedClass<Object>                           PackageParser$Activity;\r\n    public static HackedClass<Object>                           PackageParser$Service;\r\n    public static HackedClass<Object>                           PackageParser$Provider;\r\n    public static HackedClass<Object>                           PackageParser;\r\n    public static HackedClass<Object>                           PackageParser$Package;\r\n    public static HackedClass<Object>                           PackageParser$ActivityIntentInfo;\r\n    public static HackedClass<Object>                           PackageParser$ServiceIntentInfo;\r\n    public static HackedClass<Object>                           PackageParser$ProviderIntentInfo;\r\n    public static HackedClass<Object>                           ActivityManagerNative;\r\n    public static HackedClass<Object>                                                       Singleton;\r\n    public static HackedClass<Object>                           ActivityThread$AppBindData;\r\n    public static HackedClass<Object>                           ActivityManager;\r\n    public static HackedClass<Object>                           StringBlock;\r\n    public static HackedClass<Object> ApplicationLoaders;\r\n\r\n    // Fields\r\n    public static HackedField<Object, Instrumentation>          ActivityThread_mInstrumentation;\r\n    public static HackedField<Object, Application>          ActivityThread_mInitialApplication;    \r\n    public static HackedField<Object, ArrayList<Application>>   ActivityThread_mAllApplications;\r\n    public static HackedField<Object, Map<String, Object>>      ActivityThread_mPackages;\r\n    public static HackedField<Object, Object>                   ActivityThread_sPackageManager;\r\n    public static HackedField<Object, Application>              LoadedApk_mApplication;\r\n    public static HackedField<Object, Resources>                LoadedApk_mResources;\r\n    public static HackedField<Object, String>                   LoadedApk_mResDir;\r\n    public static HackedField<Object, ClassLoader>              LoadedApk_mClassLoader;\r\n    public static HackedField<Object, ClassLoader>              LoadedApk_mBaseClassLoader;\r\n    public static HackedField<Object, String>                   LoadedApk_mAppDir;\r\n    public static HackedField<Object, Resources>                ContextImpl_mResources;\r\n    public static HackedField<Object, Theme>                    ContextImpl_mTheme;\r\n    public static HackedField<ContextThemeWrapper, Context>     ContextThemeWrapper_mBase;\r\n    public static HackedField<ContextThemeWrapper, Theme>       ContextThemeWrapper_mTheme;\r\n    public static HackedField<ContextThemeWrapper, Resources>   ContextThemeWrapper_mResources;\r\n    public static HackedField<ContextWrapper, Context>          ContextWrapper_mBase;\r\n    public static HackedField<Object, ArrayList<Object>>        PackageParser$Component_intents;\r\n    public static HackedField<Object, String>                   PackageParser$Package_packageName;\r\n    public static HackedField<Object, ArrayList<Object>>                                    PackageParser$Package_activities;\r\n    public static HackedField<Object, ArrayList<Object>>                                    PackageParser$Package_services;\r\n    public static HackedField<Object, ArrayList<Object>>                                    PackageParser$Package_receivers;\r\n    public static HackedField<Object, ArrayList<Object>>                                    PackageParser$Package_providers;\r\n    public static HackedField<Object, ApplicationInfo>                                      PackageParser$Package_applicationInfo;\r\n    public static HackedField<Object,Object>          PackageParser$ActivityIntentInfo_activity;\r\n    public static HackedField<Object,Object>          PackageParser$ServiceIntentInfo_service;\r\n    public static HackedField<Object,Object>          PackageParser$ProviderIntentInfo_provider;\r\n    public static HackedField<Object,ProviderInfo>          PackageParser$Provider_info;\r\n    public static HackedField<Object,Object>          ActivityManagerNative_gDefault;\r\n    public static HackedField<Object, Object>         Singleton_mInstance;\r\n    public static HackedField<Object,List<ProviderInfo>>      ActivityThread$AppBindData_providers;\r\n    public static HackedField<Object,Object>  ActivityThread_mBoundApplication;\r\n    public static HackedField<Object,Object>  ContextImpl_mPackageInfo;\r\n    public static HackedField<Object,Object>                                  ActivityManager_IActivityManagerSingleton;\r\n    public static HackedField<Object, Map<String, ClassLoader>> ApplicationLoaders_mLoaders;\r\n\r\n\r\n\r\n    // Methods\r\n    public static HackedMethod                                  ActivityThread_currentActivityThread;\r\n    public static HackedMethod                                  AssetManager_addAssetPath;\r\n    public static HackedMethod                                  AssetManager_addAssetPathAsSharedLibrary;\r\n    public static HackedField<android.content.res.AssetManager,Object>                    AssetManager_mStringBlocks;\r\n    public static HackedMethod                                  Application_attach;\r\n    public static HackedMethod                                  ClassLoader_findLibrary;\r\n    public static HackedMethod                                  DexClassLoader_findClass;\r\n    public static HackedMethod                                  PackageParser$Component_getComponentName;\r\n    public static HackedMethod                                  LexFile_loadLex;\r\n    public static HackedMethod                                  LexFile_loadClass;\r\n    public static HackedMethod                                  LexFile_close;\r\n    public static HackedMethod                                  PackageParser_parsePackage;\r\n    public static HackedMethod                                  PackageParser_generatePackageInfo;\r\n    public static HackedMethod                                  AssetManager_getResourceIdentifier;\r\n    public static HackedMethod                                  AssetManager_ensureStringBlocks;\r\n    public static HackedMethod                                  ContextImpl_setOuterContext;\r\n    public static HackedMethod                                  Service_attach;\r\n    public static HackedMethod                                  ActivityThread_installContentProviders;\r\n    public static HackedMethod                                  ActivityThread_installProvider;\r\n    public static HackedMethod                                  AssetManager_addAssetPathNative;\r\n    public static HackedMethod                                  AssetManager_addAssetPathNative24;\r\n    public static HackedMethod                                  AssetManager_addAssetPathNativeSamSung;\r\n    public static HackedMethod                                  AssetManager_getStringBlockCount;\r\n    public static HackedMethod                                  AssetManager_getNativeStringBlock;\r\n    public static HackedMethod ApplicationLoaders_getDefault;\r\n\r\n\r\n\r\n    // Constructor\r\n    public static Hack.HackedConstructor                        PackageParser_constructor;\r\n    public static Hack.HackedConstructor                        StringBlock_constructor;\r\n\r\n    // Match method\r\n    public static ArrayList<HackedMethod>                       GeneratePackageInfoList = new ArrayList<HackedMethod>();\r\n    public static ArrayList<HackedMethod>                       GetPackageInfoList      = new ArrayList<HackedMethod>();\r\n\r\n    public static boolean defineAndVerify(){\r\n        if (sIsReflectChecked) return sIsReflectAvailable;\r\n        AtlasHacks atlasHacks = new AtlasHacks();\r\n        try {\r\n            Hack.setAssertionFailureHandler(atlasHacks);\r\n            if (Build.VERSION.SDK_INT == 11) {\r\n                atlasHacks.onAssertionFailure(new HackAssertionException(\"Hack Assertion Failed: Android OS Version 11\"));\r\n            }\r\n            allClasses();\r\n            allConstructors();\r\n            allFields();\r\n            allMethods();\r\n            // 校验完成\r\n            if (atlasHacks.mExceptionArray != null) {\r\n                // 校验存在失败\r\n                sIsReflectAvailable = false;\r\n            } else {\r\n                // 校验成功\r\n                sIsReflectAvailable = true;\r\n            }\r\n        } catch (HackAssertionException e) {\r\n            sIsReflectAvailable = false;\r\n            e.printStackTrace();\r\n        } finally {\r\n            Hack.setAssertionFailureHandler(null);\r\n            sIsReflectChecked = true;\r\n        }\r\n        return sIsReflectAvailable;\r\n    }\r\n\r\n    // Must init at first\r\n    public static void allClasses() throws HackAssertionException {\r\n        if (android.os.Build.VERSION.SDK_INT <= 8) {\r\n            LoadedApk = Hack.into(\"android.app.ActivityThread$PackageInfo\");\r\n        } else {\r\n            LoadedApk = Hack.into(\"android.app.LoadedApk\");\r\n        }\r\n        ActivityThread = Hack.into(\"android.app.ActivityThread\");\r\n        Resources = Hack.into(Resources.class);\r\n        Application = Hack.into(Application.class);\r\n        AssetManager = Hack.into(android.content.res.AssetManager.class);\r\n        IPackageManager = Hack.into(\"android.content.pm.IPackageManager\");\r\n        Service = Hack.into(android.app.Service.class);\r\n        ContextImpl = Hack.into(\"android.app.ContextImpl\");\r\n        ContextThemeWrapper = Hack.into(ContextThemeWrapper.class);\r\n        ContextWrapper = Hack.into(\"android.content.ContextWrapper\");\r\n        sIsIgnoreFailure = true;\r\n        ClassLoader = Hack.into(java.lang.ClassLoader.class);\r\n        DexClassLoader = Hack.into(dalvik.system.DexClassLoader.class);\r\n        LexFile = Hack.into(\"dalvik.system.LexFile\");\r\n        PackageParser$Component = Hack.into(\"android.content.pm.PackageParser$Component\");\r\n        PackageParser$Activity = Hack.into(\"android.content.pm.PackageParser$Activity\");\r\n        PackageParser$Service = Hack.into(\"android.content.pm.PackageParser$Service\");\r\n        PackageParser$Provider = Hack.into(\"android.content.pm.PackageParser$Provider\");\r\n\r\n        PackageParser = Hack.into(\"android.content.pm.PackageParser\");\r\n        PackageParser$Package = Hack.into(\"android.content.pm.PackageParser$Package\");\r\n        PackageParser$ActivityIntentInfo = Hack.into(\"android.content.pm.PackageParser$ActivityIntentInfo\");\r\n        PackageParser$ServiceIntentInfo = Hack.into(\"android.content.pm.PackageParser$ServiceIntentInfo\");\r\n        PackageParser$ProviderIntentInfo = Hack.into(\"android.content.pm.PackageParser$ProviderIntentInfo\");\r\n\r\n        ActivityManagerNative = Hack.into(\"android.app.ActivityManagerNative\");\r\n        Singleton = Hack.into(\"android.util.Singleton\");\r\n        ActivityThread$AppBindData = Hack.into(\"android.app.ActivityThread$AppBindData\");\r\n        ActivityManager = Hack.into(\"android.app.ActivityManager\");\r\n        StringBlock=Hack.into(\"android.content.res.StringBlock\");\r\n        ApplicationLoaders = Hack.into(\"android.app.ApplicationLoaders\");\r\n        sIsIgnoreFailure = false;\r\n    }\r\n\r\n    public static void allFields() throws HackAssertionException {\r\n        ActivityThread_mInstrumentation = ActivityThread.field(\"mInstrumentation\").ofType(Instrumentation.class);\r\n        ActivityThread_mAllApplications = ActivityThread.field(\"mAllApplications\").ofGenericType(ArrayList.class);\r\n        ActivityThread_mInitialApplication =  ActivityThread.field(\"mInitialApplication\").ofType(Application.class);       \r\n        ActivityThread_mPackages = ActivityThread.field(\"mPackages\").ofGenericType(Map.class);\r\n        ActivityThread_sPackageManager = ActivityThread.staticField(\"sPackageManager\").ofType(IPackageManager.getmClass());\r\n\r\n        LoadedApk_mApplication = LoadedApk.field(\"mApplication\").ofType(Application.class);\r\n        LoadedApk_mResources = LoadedApk.field(\"mResources\").ofType(Resources.class);\r\n        LoadedApk_mResDir = LoadedApk.field(\"mResDir\").ofType(String.class);\r\n        LoadedApk_mClassLoader = LoadedApk.field(\"mClassLoader\").ofType(ClassLoader.class);\r\n        LoadedApk_mBaseClassLoader = LoadedApk.field(\"mBaseClassLoader\").ofType(ClassLoader.class);\r\n        LoadedApk_mAppDir = LoadedApk.field(\"mAppDir\").ofType(String.class);\r\n\r\n        ContextImpl_mResources = ContextImpl.field(\"mResources\").ofType(Resources.class);\r\n        ContextImpl_mTheme = ContextImpl.field(\"mTheme\").ofType(Theme.class);\r\n        sIsIgnoreFailure = true;\r\n        //not exists on android L\r\n        ContextThemeWrapper_mBase = ContextThemeWrapper.field(\"mBase\").ofType(Context.class);\r\n        sIsIgnoreFailure = false;\r\n        ContextThemeWrapper_mTheme = ContextThemeWrapper.field(\"mTheme\").ofType(Theme.class);\r\n        try {\r\n            if (android.os.Build.VERSION.SDK_INT >= 17\r\n                && ContextThemeWrapper.getmClass().getDeclaredField(\"mResources\") != null) {\r\n                ContextThemeWrapper_mResources = ContextThemeWrapper.field(\"mResources\").ofType(Resources.class);\r\n            }\r\n        } catch (NoSuchFieldException e) {\r\n            e.printStackTrace();\r\n        }\r\n\r\n        ContextWrapper_mBase = ContextWrapper.field(\"mBase\").ofType(Context.class);\r\n//        Resources_mAssets = Resources.field(\"mAssets\");\r\n        PackageParser$Component_intents = PackageParser$Component.field(\"intents\").ofGenericType(ArrayList.class);\r\n        PackageParser$Package_activities = PackageParser$Package.field(\"activities\").ofGenericType(ArrayList.class);\r\n        PackageParser$Package_services = PackageParser$Package.field(\"services\").ofGenericType(ArrayList.class);\r\n        PackageParser$Package_receivers = PackageParser$Package.field(\"receivers\").ofGenericType(ArrayList.class);\r\n        PackageParser$Package_providers = PackageParser$Package.field(\"providers\").ofGenericType(ArrayList.class);\r\n        PackageParser$Package_applicationInfo = PackageParser$Package.field(\"applicationInfo\").ofType(ApplicationInfo.class);\r\n        PackageParser$Package_packageName = PackageParser$Package.field(\"packageName\").ofGenericType(String.class);\r\n        PackageParser$ActivityIntentInfo_activity = PackageParser$ActivityIntentInfo.field(\"activity\").ofType(PackageParser$Activity.getmClass());\r\n        PackageParser$ServiceIntentInfo_service = PackageParser$ServiceIntentInfo.field(\"service\").ofType(PackageParser$Service.getmClass());\r\n        PackageParser$ProviderIntentInfo_provider = PackageParser$ProviderIntentInfo.field(\"provider\").ofType(PackageParser$Provider.getmClass());\r\n        PackageParser$Provider_info = PackageParser$Provider.field(\"info\").ofType(ProviderInfo.class);\r\n        if(Build.VERSION.SDK_INT>25 || (Build.VERSION.SDK_INT==25 && Build.VERSION.PREVIEW_SDK_INT>0)) {\r\n            ActivityManager_IActivityManagerSingleton = ActivityManager.staticField(\"IActivityManagerSingleton\");\r\n        }else{\r\n            ActivityManagerNative_gDefault = ActivityManagerNative.staticField(\"gDefault\");\r\n        }\r\n        Singleton_mInstance = Singleton.field(\"mInstance\");\r\n        ActivityThread$AppBindData_providers = ActivityThread$AppBindData.field(\"providers\").ofGenericType(List.class);\r\n        ActivityThread_mBoundApplication = ActivityThread.field(\"mBoundApplication\");\r\n        ContextImpl_mPackageInfo = ContextImpl.field(\"mPackageInfo\");\r\n        AssetManager_mStringBlocks = AssetManager.field(\"mStringBlocks\");\r\n        ApplicationLoaders_mLoaders = ApplicationLoaders.field(\"mLoaders\").ofGenericType(Map.class);\r\n    }\r\n\r\n    public static void allMethods() throws HackAssertionException {\r\n\r\n        ActivityThread_currentActivityThread = ActivityThread.method(\"currentActivityThread\");\r\n        AssetManager_addAssetPath = AssetManager.method(\"addAssetPath\", String.class);\r\n        if(Build.VERSION.SDK_INT>=24) {\r\n            AssetManager_addAssetPathAsSharedLibrary = AssetManager.method(\"addAssetPathAsSharedLibrary\", String.class);\r\n        }\r\n        Application_attach = Application.method(\"attach\", Context.class);\r\n        PackageParser$Component_getComponentName = PackageParser$Component.method(\"getComponentName\");\r\n        ClassLoader_findLibrary = ClassLoader.method(\"findLibrary\", String.class);\r\n        ContextImpl_setOuterContext = ContextImpl.method(\"setOuterContext\",Context.class);\r\n\r\n        if (LexFile != null && LexFile.getmClass() !=null ) {\r\n            LexFile_loadLex = LexFile.method(\"loadLex\", String.class, int.class);\r\n            LexFile_loadClass = LexFile.method(\"loadClass\", String.class, java.lang.ClassLoader.class);\r\n            LexFile_close = LexFile.method(\"close\");\r\n            DexClassLoader_findClass = DexClassLoader.method(\"findClass\", String.class);\r\n        }\r\n\r\n        try {\r\n            if (Build.VERSION.SDK_INT>20){\r\n                AssetManager_getResourceIdentifier = AssetManager.method(\"getResourceIdentifier\", String.class, String.class, String.class);\r\n                AssetManager_ensureStringBlocks = AssetManager.method(\"ensureStringBlocks\");\r\n            }\r\n        } catch (Throwable e) {\r\n        }\r\n\r\n        ActivityThread_installContentProviders = ActivityThread.method(\"installContentProviders\",Context.class,List.class);\r\n\r\n//        try {\r\n//            if (Build.VERSION.SDK_INT > 25 || (Build.VERSION.SDK_INT == 25\r\n//                    && Build.VERSION.PREVIEW_SDK_INT > 0)) {\r\n//                ActivityThread_installProvider = ActivityThread.method(\"installProvider\",\r\n//                        Context.class, ContentProviderHolder.class, ProviderInfo.class,\r\n//                        boolean.class, boolean.class, boolean.class);\r\n//            } else if (Build.VERSION.SDK_INT == 14) {\r\n//                ActivityThread_installProvider = ActivityThread.method(\"installProvider\",\r\n//                        Context.class, IContentProvider.class, ProviderInfo.class, boolean.class);\r\n//            } else if (Build.VERSION.SDK_INT == 15) {\r\n//                ActivityThread_installProvider = ActivityThread.method(\"installProvider\",\r\n//                        Context.class, IContentProvider.class, ProviderInfo.class, boolean.class,\r\n//                        boolean.class);\r\n//            } else {\r\n//                ActivityThread_installProvider = ActivityThread.method(\"installProvider\",\r\n//                        Context.class, IActivityManager.ContentProviderHolder.class,\r\n//                        ProviderInfo.class, boolean.class, boolean.class, boolean.class);\r\n//            }\r\n//        } catch (Throwable t) {\r\n//            Log.w(\"AtlasHacks\", \"Error getting ActivityThread_installProvider\", t);\r\n//        }\r\n\r\n        Service_attach = Service.method(\"attach\",Context.class,ActivityThread.getmClass(),String.class,IBinder.class,Application.getmClass(),Object.class);\r\n\r\n        AssetManager_addAssetPathNative = AssetManager.method(\"addAssetPathNative\", String.class);\r\n        if(AssetManager_addAssetPathNative==null || AssetManager_addAssetPathNative.getMethod()==null) {\r\n            AssetManager_addAssetPathNative24 = AssetManager.method(\"addAssetPathNative\", String.class, boolean.class);\r\n        }\r\n        if((AssetManager_addAssetPathNative==null || AssetManager_addAssetPathNative.getMethod()==null) &&\r\n                (AssetManager_addAssetPathNative24==null || AssetManager_addAssetPathNative24.getMethod()==null)){\r\n            AssetManager_addAssetPathNativeSamSung = AssetManager.method(\"addAssetPathNative\", String.class, int.class);\r\n        }\r\n        AssetManager_getStringBlockCount=AssetManager.method(\"getStringBlockCount\");\r\n        AssetManager_getNativeStringBlock = AssetManager.method(\"getNativeStringBlock\",int.class);\r\n        ApplicationLoaders_getDefault = ApplicationLoaders.method(\"getDefault\");\r\n    }\r\n\r\n    public static void allConstructors() throws HackAssertionException {\r\n        if(Build.VERSION.SDK_INT<=20) {\r\n            PackageParser_constructor = PackageParser.constructor(String.class);\r\n        }else{\r\n            PackageParser_constructor = PackageParser.constructor();\r\n        }\r\n        if(Build.VERSION.SDK_INT>=21) {\r\n            StringBlock_constructor = StringBlock.constructor(long.class, boolean.class);\r\n        }else {\r\n            StringBlock_constructor = StringBlock.constructor(int.class, boolean.class);\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public boolean onAssertionFailure(HackAssertionException failure) {\r\n        if (sIsIgnoreFailure) return true;\r\n        if (mExceptionArray == null) {\r\n            mExceptionArray = new AssertionArrayException(\"atlas hack assert failed\");\r\n        }\r\n        mExceptionArray.addException(failure);\r\n        return true;\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/hack/Hack.java",
    "content": "/*\r\n *\r\n *                                Apache License\r\n *                          Version 2.0, January 2004\r\n *                       http://www.apache.org/licenses/\r\n *\r\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r\n *\r\n *  1. Definitions.\r\n *\r\n *     \"License\" shall mean the terms and conditions for use, reproduction,\r\n *     and distribution as defined by Sections 1 through 9 of this document.\r\n *\r\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\r\n *     the copyright owner that is granting the License.\r\n *\r\n *     \"Legal Entity\" shall mean the union of the acting entity and all\r\n *     other entities that control, are controlled by, or are under common\r\n *     control with that entity. For the purposes of this definition,\r\n *     \"control\" means (i) the power, direct or indirect, to cause the\r\n *     direction or management of such entity, whether by contract or\r\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\r\n *     outstanding shares, or (iii) beneficial ownership of such entity.\r\n *\r\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\r\n *     exercising permissions granted by this License.\r\n *\r\n *     \"Source\" form shall mean the preferred form for making modifications,\r\n *     including but not limited to software source code, documentation\r\n *     source, and configuration files.\r\n *\r\n *     \"Object\" form shall mean any form resulting from mechanical\r\n *     transformation or translation of a Source form, including but\r\n *     not limited to compiled object code, generated documentation,\r\n *     and conversions to other media types.\r\n *\r\n *     \"Work\" shall mean the work of authorship, whether in Source or\r\n *     Object form, made available under the License, as indicated by a\r\n *     copyright notice that is included in or attached to the work\r\n *     (an example is provided in the Appendix below).\r\n *\r\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\r\n *     form, that is based on (or derived from) the Work and for which the\r\n *     editorial revisions, annotations, elaborations, or other modifications\r\n *     represent, as a whole, an original work of authorship. For the purposes\r\n *     of this License, Derivative Works shall not include works that remain\r\n *     separable from, or merely link (or bind by name) to the interfaces of,\r\n *     the Work and Derivative Works thereof.\r\n *\r\n *     \"Contribution\" shall mean any work of authorship, including\r\n *     the original version of the Work and any modifications or additions\r\n *     to that Work or Derivative Works thereof, that is intentionally\r\n *     submitted to Licensor for inclusion in the Work by the copyright owner\r\n *     or by an individual or Legal Entity authorized to submit on behalf of\r\n *     the copyright owner. For the purposes of this definition, \"submitted\"\r\n *     means any form of electronic, verbal, or written communication sent\r\n *     to the Licensor or its representatives, including but not limited to\r\n *     communication on electronic mailing lists, source code control systems,\r\n *     and issue tracking systems that are managed by, or on behalf of, the\r\n *     Licensor for the purpose of discussing and improving the Work, but\r\n *     excluding communication that is conspicuously marked or otherwise\r\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\r\n *\r\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\r\n *     on behalf of whom a Contribution has been received by Licensor and\r\n *     subsequently incorporated within the Work.\r\n *\r\n *  2. Grant of Copyright License. Subject to the terms and conditions of\r\n *     this License, each Contributor hereby grants to You a perpetual,\r\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n *     copyright license to reproduce, prepare Derivative Works of,\r\n *     publicly display, publicly perform, sublicense, and distribute the\r\n *     Work and such Derivative Works in Source or Object form.\r\n *\r\n *  3. Grant of Patent License. Subject to the terms and conditions of\r\n *     this License, each Contributor hereby grants to You a perpetual,\r\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n *     (except as stated in this section) patent license to make, have made,\r\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\r\n *     where such license applies only to those patent claims licensable\r\n *     by such Contributor that are necessarily infringed by their\r\n *     Contribution(s) alone or by combination of their Contribution(s)\r\n *     with the Work to which such Contribution(s) was submitted. If You\r\n *     institute patent litigation against any entity (including a\r\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\r\n *     or a Contribution incorporated within the Work constitutes direct\r\n *     or contributory patent infringement, then any patent licenses\r\n *     granted to You under this License for that Work shall terminate\r\n *     as of the date such litigation is filed.\r\n *\r\n *  4. Redistribution. You may reproduce and distribute copies of the\r\n *     Work or Derivative Works thereof in any medium, with or without\r\n *     modifications, and in Source or Object form, provided that You\r\n *     meet the following conditions:\r\n *\r\n *     (a) You must give any other recipients of the Work or\r\n *         Derivative Works a copy of this License; and\r\n *\r\n *     (b) You must cause any modified files to carry prominent notices\r\n *         stating that You changed the files; and\r\n *\r\n *     (c) You must retain, in the Source form of any Derivative Works\r\n *         that You distribute, all copyright, patent, trademark, and\r\n *         attribution notices from the Source form of the Work,\r\n *         excluding those notices that do not pertain to any part of\r\n *         the Derivative Works; and\r\n *\r\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\r\n *         distribution, then any Derivative Works that You distribute must\r\n *         include a readable copy of the attribution notices contained\r\n *         within such NOTICE file, excluding those notices that do not\r\n *         pertain to any part of the Derivative Works, in at least one\r\n *         of the following places: within a NOTICE text file distributed\r\n *         as part of the Derivative Works; within the Source form or\r\n *         documentation, if provided along with the Derivative Works; or,\r\n *         within a display generated by the Derivative Works, if and\r\n *         wherever such third-party notices normally appear. The contents\r\n *         of the NOTICE file are for informational purposes only and\r\n *         do not modify the License. You may add Your own attribution\r\n *         notices within Derivative Works that You distribute, alongside\r\n *         or as an addendum to the NOTICE text from the Work, provided\r\n *         that such additional attribution notices cannot be construed\r\n *         as modifying the License.\r\n *\r\n *     You may add Your own copyright statement to Your modifications and\r\n *     may provide additional or different license terms and conditions\r\n *     for use, reproduction, or distribution of Your modifications, or\r\n *     for any such Derivative Works as a whole, provided Your use,\r\n *     reproduction, and distribution of the Work otherwise complies with\r\n *     the conditions stated in this License.\r\n *\r\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\r\n *     any Contribution intentionally submitted for inclusion in the Work\r\n *     by You to the Licensor shall be under the terms and conditions of\r\n *     this License, without any additional terms or conditions.\r\n *     Notwithstanding the above, nothing herein shall supersede or modify\r\n *     the terms of any separate license agreement you may have executed\r\n *     with Licensor regarding such Contributions.\r\n *\r\n *  6. Trademarks. This License does not grant permission to use the trade\r\n *     names, trademarks, service marks, or product names of the Licensor,\r\n *     except as required for reasonable and customary use in describing the\r\n *     origin of the Work and reproducing the content of the NOTICE file.\r\n *\r\n *  7. Disclaimer of Warranty. Unless required by applicable law or\r\n *     agreed to in writing, Licensor provides the Work (and each\r\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\r\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r\n *     implied, including, without limitation, any warranties or conditions\r\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\r\n *     appropriateness of using or redistributing the Work and assume any\r\n *     risks associated with Your exercise of permissions under this License.\r\n *\r\n *  8. Limitation of Liability. In no event and under no legal theory,\r\n *     whether in tort (including negligence), contract, or otherwise,\r\n *     unless required by applicable law (such as deliberate and grossly\r\n *     negligent acts) or agreed to in writing, shall any Contributor be\r\n *     liable to You for damages, including any direct, indirect, special,\r\n *     incidental, or consequential damages of any character arising as a\r\n *     result of this License or out of the use or inability to use the\r\n *     Work (including but not limited to damages for loss of goodwill,\r\n *     work stoppage, computer failure or malfunction, or any and all\r\n *     other commercial damages or losses), even if such Contributor\r\n *     has been advised of the possibility of such damages.\r\n *\r\n *  9. Accepting Warranty or Additional Liability. While redistributing\r\n *     the Work or Derivative Works thereof, You may choose to offer,\r\n *     and charge a fee for, acceptance of support, warranty, indemnity,\r\n *     or other liability obligations and/or rights consistent with this\r\n *     License. However, in accepting such obligations, You may act only\r\n *     on Your own behalf and on Your sole responsibility, not on behalf\r\n *     of any other Contributor, and only if You agree to indemnify,\r\n *     defend, and hold each Contributor harmless for any liability\r\n *     incurred by, or claims asserted against, such Contributor by reason\r\n *     of your accepting any such warranty or additional liability.\r\n *\r\n *  END OF TERMS AND CONDITIONS\r\n *\r\n *  APPENDIX: How to apply the Apache License to your work.\r\n *\r\n *     To apply the Apache License to your work, attach the following\r\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\r\n *     replaced with your own identifying information. (Don't include\r\n *     the brackets!)  The text should be enclosed in the appropriate\r\n *     comment syntax for the file format. We also recommend that a\r\n *     file or class name and description of purpose be included on the\r\n *     same \"printed page\" as the copyright notice for easier\r\n *     identification within third-party archives.\r\n *\r\n *  Copyright 2016 Alibaba Group\r\n *\r\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\r\n *  you may not use this file except in compliance with the License.\r\n *  You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n *  Unless required by applicable law or agreed to in writing, software\r\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\r\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n *  See the License for the specific language governing permissions and\r\n *  limitations under the License.\r\n *\r\n *\r\n *\r\n */\r\n\r\npackage android.taobao.atlas.hack;\r\n\r\nimport java.lang.reflect.Constructor;\r\nimport java.lang.reflect.Field;\r\nimport java.lang.reflect.InvocationTargetException;\r\nimport java.lang.reflect.Method;\r\nimport java.lang.reflect.Modifier;\r\n\r\nimport android.taobao.atlas.hack.Hack.HackDeclaration.HackAssertionException;\r\nimport android.taobao.atlas.hack.Interception.InterceptionHandler;\r\nimport android.util.Log;\r\n\r\n/** @author Oasis */\r\npublic class Hack {\r\n\r\n\t/** All hacks should be declared in a centralized point extending this class, typically as static\r\n\t * method, and call it in your application initialization stage to verify all the hack\r\n\t * assertions by catching exception thrown:\r\n\t * <pre>\r\n\t * class MyHacks extends HackDeclaration {\r\n\t *\r\n\t *     static HackedField<Object, PackageManager> ContextImpl_mPackageManager;\r\n\t *     static HackedField<Object, Map<String, IBinder>> ServiceManager_sCache;\r\n\t *\r\n\t *     static void defineAndVerify() {\r\n\t *         try {\r\n\t *             ContextImpl_mPackageManager = Hack.into(\"android.app.ContextImpl\").field(\"mPackageManager\").ofType(PackageManager.class);\r\n\t *             ServiceManager_sCache = Hack.into(\"android.os.ServiceManager\").staticField(\"sCache\").ofGenericType(Map.class)\r\n\t *             \r\n\t *             ...\r\n\t *         } catch (HackAssertionException e) {\r\n\t *             // Report the failure and activate fall-back strategy.\r\n\t *             ...\r\n\t *         }\r\n\t *     }\r\n\t * }\r\n\t * <pre>\r\n\t * Thus we can verify them all together in an early application initialization stage. If any assertion\r\n\t * failed, a fall-back strategy is suggested. */\r\n\tpublic static abstract class HackDeclaration {\r\n\r\n\t\t/** This exception is purposely defined as \"protected\" and not extending Exception to avoid\r\n\t\t * developers unconsciously catch it outside the centralized hacks declaration, which results\r\n\t\t * in potentially pre-checked usage of hacks. */\r\n\t\tpublic static class HackAssertionException extends Throwable {\r\n\r\n\t\t\tprivate Class<?> mHackedClass;\r\n\t\t\tprivate String mHackedFieldName;\t\t\t\r\n\t\t\tprivate String mHackedMethodName;\r\n\t\r\n\t\t\tpublic HackAssertionException(final String e) { super(e); }\r\n\t\t\tpublic HackAssertionException(final Exception e) { super(e); }\r\n\t\t\t@Override public String toString() {\r\n\t\t\t\treturn getCause() != null ? getClass().getName() + \": \" + getCause() : super.toString();\r\n\t\t\t}\t\t\t\r\n\t\t\t\r\n\t\t\tpublic Class<?> getHackedClass() {\r\n\t\t\t\treturn mHackedClass;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tpublic void setHackedClass(Class<?> mHackedClass) {\r\n\t\t\t\tthis.mHackedClass = mHackedClass;\r\n\t\t\t}\t\t\r\n\t\t\t\r\n\t\t\tpublic String getHackedMethodName() {\r\n\t\t\t\treturn mHackedMethodName;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tpublic void setHackedMethodName(String methodName) {\r\n\t\t\t\tthis.mHackedMethodName = methodName;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tpublic String getHackedFieldName() {\r\n\t\t\t\treturn mHackedFieldName;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tpublic void setHackedFieldName(String fieldName) {\r\n\t\t\t\tthis.mHackedFieldName = fieldName;\r\n\t\t\t}\r\n\r\n\t\t\tprivate static final long serialVersionUID = 1L;\r\n\t\t}\r\n\t}\r\n\r\n\t/** Use {@link Hack#setAssertionFailureHandler(AssertionFailureHandler) } to set the global handler */\r\n\tpublic interface AssertionFailureHandler {\r\n\t\t\r\n\t\t/** @return whether the failure is handled and no need to throw out, return false to let it thrown */\r\n\t\tboolean onAssertionFailure(HackAssertionException failure);\r\n\t}\r\n\r\n\t/** @beta */\r\n\tpublic static class HackedField<C, T> {\r\n\r\n\t\t@SuppressWarnings(\"unchecked\")\t\t// TODO: Add more check\r\n\t\tpublic <T2> HackedField<C, T2> ofGenericType(final Class<?> type) throws HackAssertionException {\r\n\t\t\tif (mField != null && !type.isAssignableFrom(mField.getType()))\r\n\t\t\t\tfail(new HackAssertionException(new ClassCastException(mField + \" is not of type \" + type)));\r\n\t\t\treturn (HackedField<C, T2>) this;\r\n\t\t}\r\n\r\n\t\t@SuppressWarnings(\"unchecked\")\r\n\t\tpublic <T2> HackedField<C, T2> ofType(final Class<T2> type) throws HackAssertionException {\r\n\t\t\tif (mField != null && !type.isAssignableFrom(mField.getType()))\r\n\t\t\t\tfail(new HackAssertionException(new ClassCastException(mField + \" is not of type \" + type)));\r\n\t\t\treturn (HackedField<C, T2>) this;\r\n\t\t}\r\n\t\t@SuppressWarnings(\"unchecked\")\r\n\t\tpublic HackedField<C, T> ofType(final String type_name) throws HackAssertionException {\r\n\t\t\ttry { return (HackedField<C, T>) ofType(Class.forName(type_name));\r\n\t\t\t} catch (final ClassNotFoundException e) { fail(new HackAssertionException(e)); return this; }\r\n\t\t}\r\n\r\n\t\t/** Get current value of this field */\r\n\t\tpublic T get(final C instance) {\r\n\t\t\ttry {\r\n\t\t\t\t@SuppressWarnings(\"unchecked\") final T value = (T) mField.get(instance);\r\n\t\t\treturn value;\r\n\t\t\t} catch (final IllegalAccessException e) {\r\n\t\t\t\te.printStackTrace();\r\n\t\t\t\t//TBS.Ext.commitEvent(\"AtlasRuntimeException\", AtlasConstant.ATLAS_RUNTIME_EXCEPTION, e.toString());\r\n\t\t\t\treturn null; /* Should never happen */ }\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Set value of this field\r\n\t\t * \r\n\t\t * <p>No type enforced here since most type mismatch can be easily tested and exposed early.</p>\r\n\t\t */\r\n\t\tpublic void set(final C instance,final Object value) {\r\n\t\t\ttry {\r\n\t\t\tmField.set(instance, value);\r\n\t\t\t} catch (final IllegalAccessException e) { \r\n\t\t\t\te.printStackTrace();\r\n\t\t\t\t/* Should never happen */\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Hijack the current instance of this field.\r\n\t\t *\r\n\t\t * <p><b>The instance must not be null at the time of hijacking</b>, or an IllegalStateException will be thrown.\r\n\t\t *\r\n\t\t * @param handler a invocation handler to implement the hijack logic.\r\n\t\t */\r\n\t\tpublic void hijack(final C instance,final InterceptionHandler<?> handler) {\r\n\t\t\tfinal Object delegatee = get(instance);\r\n\t\t\tif (delegatee == null) throw new IllegalStateException(\"Cannot hijack null\");\r\n\t\t\tfinal Class<?>[] interfaces = delegatee.getClass().getInterfaces();\r\n\t\t\tset(instance,Interception.proxy(delegatee, handler, interfaces));\r\n\t\t}\r\n\r\n\t\t/** @param modifiers the modifiers this field must have */\r\n\t\tHackedField(final Class<C> clazz, final String name, int modifiers) throws HackAssertionException {\r\n\t\t\tField field = null;\r\n\t\t\ttry {\r\n\t\t\t\tif (clazz == null) return;\r\n\t\t\t\tfield = clazz.getDeclaredField(name);\r\n\t\t\t\tif (modifiers > 0 && (field.getModifiers() & modifiers) != modifiers)\r\n\t\t\t\t\tfail(new HackAssertionException(field + \" does not match modifiers: \" + modifiers));\r\n\t\t\t\tfield.setAccessible(true);\r\n\t\t\t} catch (final NoSuchFieldException e) {\r\n\t\t\t\tHackAssertionException hae = new HackAssertionException(e);\r\n\t\t\t\thae.setHackedClass(clazz);\r\n\t\t\t\thae.setHackedFieldName(name);\r\n\t\t\t\tfail(hae);\r\n\t\t\t} finally { mField = field; }\r\n\t\t}\r\n\t\tprivate final Field mField;\r\n\t\t\r\n\t\tpublic Field getField() {\r\n\t\t\treturn mField;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic static class HackedMethod {\r\n        private static final String TAG = \"HackedMethod\";\r\n\r\n\t\tpublic Object invoke(final Object receiver, final Object... args) throws IllegalArgumentException, InvocationTargetException {\r\n\t\t\tObject obj = null;\r\n\t\t\ttry {\r\n\t\t\t\tobj = mMethod.invoke(receiver, args);\r\n\t\t\t\treturn obj;\r\n\t\t\t} catch (final IllegalAccessException e) { /* Should never happen */\r\n\t\t\t\te.printStackTrace();\r\n\t\t\t}\r\n\t\t\treturn obj;\r\n\t\t}\r\n\r\n\t\tHackedMethod(final Class<?> clazz, final String name, final Class<?>[] arg_types, int modifiers) throws HackAssertionException {\r\n\t\t\tMethod method = null;\r\n\t\t\ttry {\r\n\t\t\t\tif (clazz == null) return;\r\n\t\t\t\tmethod = clazz.getDeclaredMethod(name, arg_types);\r\n\t\t\t\tif (modifiers > 0 && (method.getModifiers() & modifiers) != modifiers)\r\n\t\t\t\t\tfail(new HackAssertionException(method + \" does not match modifiers: \" + modifiers));\r\n\t\t\t\tmethod.setAccessible(true);\r\n\t\t\t} catch (final NoSuchMethodException e) {\r\n                Log.e(TAG, \"No such method: \" + e.getMessage());\r\n                HackAssertionException hae = new HackAssertionException(e);\r\n\t\t\t\thae.setHackedClass(clazz);\r\n\t\t\t\thae.setHackedMethodName(name);\r\n\t\t\t\tfail(hae);\r\n\t\t\t} finally { mMethod = method; }\r\n\t\t}\r\n\r\n\t\tprotected final Method mMethod;\r\n\r\n\t\tpublic Method getMethod() {\r\n\t\t\treturn mMethod;\r\n\t\t}\t\t\r\n\t}\r\n\r\n\tpublic static class HackedConstructor {\r\n\r\n\t\tprotected Constructor<?> mConstructor;\r\n\r\n\t\tHackedConstructor(final Class<?> clazz, final Class<?>[] arg_types) throws HackAssertionException {\r\n\t\t\ttry {\r\n\t\t\t\tif (clazz == null) return;\r\n\t\t\t\tmConstructor = clazz.getDeclaredConstructor(arg_types);\r\n\t\t\t} catch (NoSuchMethodException e) {\r\n\t\t\t\tHackAssertionException hae = new HackAssertionException(e);\r\n\t\t\t\thae.setHackedClass(clazz);\r\n\t\t\t\tfail(hae);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tpublic Object getInstance(final Object... arg_types) throws IllegalArgumentException {\r\n\t\t\tObject obj = null;\r\n\t\t\tmConstructor.setAccessible(true);\r\n\t\t\ttry {\r\n\t\t\tobj = mConstructor.newInstance(arg_types);\r\n\t\t\t} catch (Exception e) {\r\n\t\t\t\te.printStackTrace();\r\n\t\t\t} \r\n\t\t\treturn obj;\r\n\t\t}\r\n\t}\r\n\t\r\n\tpublic static class HackedClass<C> {\r\n\r\n\t\tpublic HackedField<C, Object> staticField(final String name) throws HackAssertionException {\r\n\t\t\treturn new HackedField<C, Object>(mClass, name, Modifier.STATIC);\r\n\t\t}\r\n\r\n\t\tpublic HackedField<C, Object> field(final String name) throws HackAssertionException {\r\n\t\t\treturn new HackedField<C, Object>(mClass, name, 0);\r\n\t\t}\r\n\r\n\t\tpublic HackedMethod staticMethod(final String name, final Class<?>... arg_types) throws HackAssertionException {\r\n\t\t\treturn new HackedMethod(mClass, name, arg_types, Modifier.STATIC);\r\n\t\t}\r\n\r\n\t\tpublic HackedMethod method(final String name, final Class<?>... arg_types) throws HackAssertionException {\r\n\t\t\treturn new HackedMethod(mClass, name, arg_types, 0);\r\n\t\t}\r\n\r\n\t\tpublic HackedConstructor constructor(final Class<?>... arg_types) throws HackAssertionException {\r\n\t\t\treturn new HackedConstructor(mClass, arg_types);\r\n\t\t}\r\n\t\t\r\n\t\tpublic HackedClass(final Class<C> clazz) { mClass = clazz; }\r\n\r\n\t\tprotected Class<C> mClass;\r\n\r\n\t\tpublic Class<C> getmClass() {\r\n\t\t\treturn mClass;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic static <T> HackedClass<T> into(final Class<T> clazz) {\r\n\t\treturn new HackedClass<T>(clazz);\r\n\t}\r\n\r\n\t@SuppressWarnings({ \"rawtypes\", \"unchecked\" })\r\n\tpublic static <T> HackedClass<T> into(final String class_name) throws HackAssertionException {\r\n\t\ttry {\r\n\t\t\treturn new HackedClass(Class.forName(class_name));\r\n\t\t} catch (final ClassNotFoundException e) {\r\n\t\t\tfail(new HackAssertionException(e));\r\n\t\t\treturn new HackedClass(null);\t// TODO: Better solution to avoid null?\r\n\t\t}\r\n\t}\r\n\t\r\n\tprivate static void fail(HackAssertionException e) throws HackAssertionException {\r\n\t\tif (sFailureHandler == null || ! sFailureHandler.onAssertionFailure(e)) throw e;\r\n\t}\r\n\r\n\t/** Specify a handler to deal with assertion failure, and decide whether the failure should be thrown. */\r\n\tpublic static void setAssertionFailureHandler(AssertionFailureHandler handler) {\r\n\t\tsFailureHandler = handler;\r\n\t}\r\n\r\n\tprivate Hack() {}\r\n\r\n\tprivate static AssertionFailureHandler sFailureHandler;\r\n}\r\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/hack/Interception.java",
    "content": "/*\r\n *\r\n *                                Apache License\r\n *                          Version 2.0, January 2004\r\n *                       http://www.apache.org/licenses/\r\n *\r\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r\n *\r\n *  1. Definitions.\r\n *\r\n *     \"License\" shall mean the terms and conditions for use, reproduction,\r\n *     and distribution as defined by Sections 1 through 9 of this document.\r\n *\r\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\r\n *     the copyright owner that is granting the License.\r\n *\r\n *     \"Legal Entity\" shall mean the union of the acting entity and all\r\n *     other entities that control, are controlled by, or are under common\r\n *     control with that entity. For the purposes of this definition,\r\n *     \"control\" means (i) the power, direct or indirect, to cause the\r\n *     direction or management of such entity, whether by contract or\r\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\r\n *     outstanding shares, or (iii) beneficial ownership of such entity.\r\n *\r\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\r\n *     exercising permissions granted by this License.\r\n *\r\n *     \"Source\" form shall mean the preferred form for making modifications,\r\n *     including but not limited to software source code, documentation\r\n *     source, and configuration files.\r\n *\r\n *     \"Object\" form shall mean any form resulting from mechanical\r\n *     transformation or translation of a Source form, including but\r\n *     not limited to compiled object code, generated documentation,\r\n *     and conversions to other media types.\r\n *\r\n *     \"Work\" shall mean the work of authorship, whether in Source or\r\n *     Object form, made available under the License, as indicated by a\r\n *     copyright notice that is included in or attached to the work\r\n *     (an example is provided in the Appendix below).\r\n *\r\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\r\n *     form, that is based on (or derived from) the Work and for which the\r\n *     editorial revisions, annotations, elaborations, or other modifications\r\n *     represent, as a whole, an original work of authorship. For the purposes\r\n *     of this License, Derivative Works shall not include works that remain\r\n *     separable from, or merely link (or bind by name) to the interfaces of,\r\n *     the Work and Derivative Works thereof.\r\n *\r\n *     \"Contribution\" shall mean any work of authorship, including\r\n *     the original version of the Work and any modifications or additions\r\n *     to that Work or Derivative Works thereof, that is intentionally\r\n *     submitted to Licensor for inclusion in the Work by the copyright owner\r\n *     or by an individual or Legal Entity authorized to submit on behalf of\r\n *     the copyright owner. For the purposes of this definition, \"submitted\"\r\n *     means any form of electronic, verbal, or written communication sent\r\n *     to the Licensor or its representatives, including but not limited to\r\n *     communication on electronic mailing lists, source code control systems,\r\n *     and issue tracking systems that are managed by, or on behalf of, the\r\n *     Licensor for the purpose of discussing and improving the Work, but\r\n *     excluding communication that is conspicuously marked or otherwise\r\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\r\n *\r\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\r\n *     on behalf of whom a Contribution has been received by Licensor and\r\n *     subsequently incorporated within the Work.\r\n *\r\n *  2. Grant of Copyright License. Subject to the terms and conditions of\r\n *     this License, each Contributor hereby grants to You a perpetual,\r\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n *     copyright license to reproduce, prepare Derivative Works of,\r\n *     publicly display, publicly perform, sublicense, and distribute the\r\n *     Work and such Derivative Works in Source or Object form.\r\n *\r\n *  3. Grant of Patent License. Subject to the terms and conditions of\r\n *     this License, each Contributor hereby grants to You a perpetual,\r\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n *     (except as stated in this section) patent license to make, have made,\r\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\r\n *     where such license applies only to those patent claims licensable\r\n *     by such Contributor that are necessarily infringed by their\r\n *     Contribution(s) alone or by combination of their Contribution(s)\r\n *     with the Work to which such Contribution(s) was submitted. If You\r\n *     institute patent litigation against any entity (including a\r\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\r\n *     or a Contribution incorporated within the Work constitutes direct\r\n *     or contributory patent infringement, then any patent licenses\r\n *     granted to You under this License for that Work shall terminate\r\n *     as of the date such litigation is filed.\r\n *\r\n *  4. Redistribution. You may reproduce and distribute copies of the\r\n *     Work or Derivative Works thereof in any medium, with or without\r\n *     modifications, and in Source or Object form, provided that You\r\n *     meet the following conditions:\r\n *\r\n *     (a) You must give any other recipients of the Work or\r\n *         Derivative Works a copy of this License; and\r\n *\r\n *     (b) You must cause any modified files to carry prominent notices\r\n *         stating that You changed the files; and\r\n *\r\n *     (c) You must retain, in the Source form of any Derivative Works\r\n *         that You distribute, all copyright, patent, trademark, and\r\n *         attribution notices from the Source form of the Work,\r\n *         excluding those notices that do not pertain to any part of\r\n *         the Derivative Works; and\r\n *\r\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\r\n *         distribution, then any Derivative Works that You distribute must\r\n *         include a readable copy of the attribution notices contained\r\n *         within such NOTICE file, excluding those notices that do not\r\n *         pertain to any part of the Derivative Works, in at least one\r\n *         of the following places: within a NOTICE text file distributed\r\n *         as part of the Derivative Works; within the Source form or\r\n *         documentation, if provided along with the Derivative Works; or,\r\n *         within a display generated by the Derivative Works, if and\r\n *         wherever such third-party notices normally appear. The contents\r\n *         of the NOTICE file are for informational purposes only and\r\n *         do not modify the License. You may add Your own attribution\r\n *         notices within Derivative Works that You distribute, alongside\r\n *         or as an addendum to the NOTICE text from the Work, provided\r\n *         that such additional attribution notices cannot be construed\r\n *         as modifying the License.\r\n *\r\n *     You may add Your own copyright statement to Your modifications and\r\n *     may provide additional or different license terms and conditions\r\n *     for use, reproduction, or distribution of Your modifications, or\r\n *     for any such Derivative Works as a whole, provided Your use,\r\n *     reproduction, and distribution of the Work otherwise complies with\r\n *     the conditions stated in this License.\r\n *\r\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\r\n *     any Contribution intentionally submitted for inclusion in the Work\r\n *     by You to the Licensor shall be under the terms and conditions of\r\n *     this License, without any additional terms or conditions.\r\n *     Notwithstanding the above, nothing herein shall supersede or modify\r\n *     the terms of any separate license agreement you may have executed\r\n *     with Licensor regarding such Contributions.\r\n *\r\n *  6. Trademarks. This License does not grant permission to use the trade\r\n *     names, trademarks, service marks, or product names of the Licensor,\r\n *     except as required for reasonable and customary use in describing the\r\n *     origin of the Work and reproducing the content of the NOTICE file.\r\n *\r\n *  7. Disclaimer of Warranty. Unless required by applicable law or\r\n *     agreed to in writing, Licensor provides the Work (and each\r\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\r\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r\n *     implied, including, without limitation, any warranties or conditions\r\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\r\n *     appropriateness of using or redistributing the Work and assume any\r\n *     risks associated with Your exercise of permissions under this License.\r\n *\r\n *  8. Limitation of Liability. In no event and under no legal theory,\r\n *     whether in tort (including negligence), contract, or otherwise,\r\n *     unless required by applicable law (such as deliberate and grossly\r\n *     negligent acts) or agreed to in writing, shall any Contributor be\r\n *     liable to You for damages, including any direct, indirect, special,\r\n *     incidental, or consequential damages of any character arising as a\r\n *     result of this License or out of the use or inability to use the\r\n *     Work (including but not limited to damages for loss of goodwill,\r\n *     work stoppage, computer failure or malfunction, or any and all\r\n *     other commercial damages or losses), even if such Contributor\r\n *     has been advised of the possibility of such damages.\r\n *\r\n *  9. Accepting Warranty or Additional Liability. While redistributing\r\n *     the Work or Derivative Works thereof, You may choose to offer,\r\n *     and charge a fee for, acceptance of support, warranty, indemnity,\r\n *     or other liability obligations and/or rights consistent with this\r\n *     License. However, in accepting such obligations, You may act only\r\n *     on Your own behalf and on Your sole responsibility, not on behalf\r\n *     of any other Contributor, and only if You agree to indemnify,\r\n *     defend, and hold each Contributor harmless for any liability\r\n *     incurred by, or claims asserted against, such Contributor by reason\r\n *     of your accepting any such warranty or additional liability.\r\n *\r\n *  END OF TERMS AND CONDITIONS\r\n *\r\n *  APPENDIX: How to apply the Apache License to your work.\r\n *\r\n *     To apply the Apache License to your work, attach the following\r\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\r\n *     replaced with your own identifying information. (Don't include\r\n *     the brackets!)  The text should be enclosed in the appropriate\r\n *     comment syntax for the file format. We also recommend that a\r\n *     file or class name and description of purpose be included on the\r\n *     same \"printed page\" as the copyright notice for easier\r\n *     identification within third-party archives.\r\n *\r\n *  Copyright 2016 Alibaba Group\r\n *\r\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\r\n *  you may not use this file except in compliance with the License.\r\n *  You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n *  Unless required by applicable law or agreed to in writing, software\r\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\r\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n *  See the License for the specific language governing permissions and\r\n *  limitations under the License.\r\n *\r\n *\r\n *\r\n */\r\n\r\npackage android.taobao.atlas.hack;\r\n\r\nimport java.lang.reflect.InvocationHandler;\r\nimport java.lang.reflect.InvocationTargetException;\r\nimport java.lang.reflect.Method;\r\nimport java.lang.reflect.Proxy;\r\n\r\n/** @author Oasis */\r\npublic class Interception {\r\n\r\n\t/**\r\n\t * Derive this class and override {@link #invoke(Object, Method, Object[])} to implement an\r\n\t * interception handler.\r\n\t * \r\n\t * A typical usage example as below:<pre>\r\n\t * public class PackageManagerProxy extends InterceptionHandler {\r\n     *\r\n     *     public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {\r\n     *         if (\"getActivityInfo\".equals(method.getName())) {\r\n     *             final ActivityInfo found = mActivities.get(((ComponentName) args[0]).getClassName());\r\n     *             if (found != null) {\r\n     *                 ...\r\n     *                 return found;\r\n     *             }\r\n     *         }\r\n     *         return super.invoke(proxy, method, args);\r\n     *     }\r\n     *\r\n     *     private final Map<String, ActivityInfo> mActivities;\r\n     *     ...\r\n\t * }</pre>\r\n\t */\r\n\tpublic abstract static class InterceptionHandler<T> implements InvocationHandler {\r\n\r\n\t\t/**\r\n\t\t * Derived class should override this method and call <code>super.invoke(...)</code> to delegate the\r\n\t\t * procedure to original delegatee instance if needed.\r\n\t\t *\r\n\t\t * @param proxy is ignored, instead the actual delegatee instance will be used to invoke this method on.\r\n\t\t */\r\n\t\t@Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable  {\r\n\t\t\t\ttry {\r\n\t\t\t\t\treturn method.invoke(delegatee(), args);\r\n\t\t\t\t} catch (IllegalArgumentException e) {/* Should never happen */\r\n\t\t\t\t\te.printStackTrace();\r\n\t\t\t\t\treturn null;\r\n\t\t\t\t} catch (IllegalAccessException e) {/* Should never happen */\r\n\t\t\t\t\te.printStackTrace();\r\n\t\t\t\t\treturn null;\r\n\t\t\t\t} catch (InvocationTargetException e) {\r\n\t\t\t\t\tthrow e.getTargetException();\r\n\t\t\t\t}\r\n\t\t}\r\n\r\n\t\tprotected T delegatee() { return mDelegatee; }\r\n\r\n\t\tvoid setDelegatee(final T delegatee) { mDelegatee = delegatee; }\r\n\r\n\t\tprivate T mDelegatee;\r\n\t}\r\n\r\n\t@SuppressWarnings(\"unchecked\")\r\n\tpublic static <T> T proxy(final Object delegatee, final Class<T> interface_class, final InterceptionHandler<T> handler) throws IllegalArgumentException {\r\n\t\tif (delegatee instanceof Intercepted) return (T) delegatee;\r\n\t\thandler.setDelegatee((T) delegatee);\r\n\t\treturn (T) Proxy.newProxyInstance(Interception.class.getClassLoader(), new Class<?>[] { interface_class, Intercepted.class }, handler);\r\n\t}\r\n\r\n\t@SuppressWarnings(\"unchecked\")\r\n\tpublic static <T> T proxy(final Object delegatee, final InterceptionHandler<T> handler, final Class<?>... interfaces) throws IllegalArgumentException {\r\n\t\t//if (Proxy.isProxyClass(delegatee.getClass())) return (T) delegatee;\r\n\t\thandler.setDelegatee((T) delegatee);\r\n\t\treturn (T) Proxy.newProxyInstance(Interception.class.getClassLoader(), interfaces, handler);\r\n\t}\r\n\r\n\tprivate Interception() {}\r\n\r\n\tprivate interface Intercepted {}\t\t// A mark to identify our proxy class\r\n}\r\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/profile/AtlasProfile.java",
    "content": "package android.taobao.atlas.profile;\n\nimport java.util.HashMap;\nimport java.util.Map;\n/**\n * AtlasProfiler\n *\n * @author zhayu.ll\n * @date 18/7/4\n */\npublic class AtlasProfile\n{\n    private static final Map<String, AtlasProfile> cacheMap = new HashMap();\n    private String tag;\n    private long start;\n\n    private AtlasProfile(String tag)\n    {\n        this.tag = tag;\n    }\n\n    public static  AtlasProfile profile(String tag) {\n        synchronized (cacheMap) {\n            if (cacheMap.containsKey(tag)) {\n                return (AtlasProfile) cacheMap.get(tag);\n            }\n            AtlasProfile atlasProfile = new AtlasProfile(tag);\n            cacheMap.put(tag, atlasProfile);\n            return atlasProfile;\n        }\n    }\n\n    public void start()\n    {\n        this.start = System.currentTimeMillis();\n    }\n\n    public String stop()\n    {\n        return String.format(\"%s |cost: %sms\",this.tag,String.valueOf(System.currentTimeMillis() - this.start));\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/runtime/ActivityLifeCycleObserver.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.runtime;\n\nimport android.app.Activity;\nimport android.app.Application;\nimport android.os.Bundle;\n\n/**\n * Created by guanjie on 15/3/16.\n */\npublic class ActivityLifeCycleObserver implements Application.ActivityLifecycleCallbacks{\n    @Override\n    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {\n        ActivityTaskMgr.getInstance().pushToActivityStack(activity);\n    }\n\n    @Override\n    public void onActivityStarted(Activity activity) {\n\n    }\n\n    @Override\n    public void onActivityResumed(Activity activity) {\n\n    }\n\n    @Override\n    public void onActivityPaused(Activity activity) {\n\n    }\n\n    @Override\n    public void onActivityStopped(Activity activity) {\n\n    }\n\n    @Override\n    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {\n\n    }\n\n    @Override\n    public void onActivityDestroyed(Activity activity) {\n        ActivityTaskMgr.getInstance().popFromActivityStack(activity);\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/runtime/ActivityTaskMgr.java",
    "content": "/*\r\n *\r\n *                                Apache License\r\n *                          Version 2.0, January 2004\r\n *                       http://www.apache.org/licenses/\r\n *\r\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r\n *\r\n *  1. Definitions.\r\n *\r\n *     \"License\" shall mean the terms and conditions for use, reproduction,\r\n *     and distribution as defined by Sections 1 through 9 of this document.\r\n *\r\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\r\n *     the copyright owner that is granting the License.\r\n *\r\n *     \"Legal Entity\" shall mean the union of the acting entity and all\r\n *     other entities that control, are controlled by, or are under common\r\n *     control with that entity. For the purposes of this definition,\r\n *     \"control\" means (i) the power, direct or indirect, to cause the\r\n *     direction or management of such entity, whether by contract or\r\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\r\n *     outstanding shares, or (iii) beneficial ownership of such entity.\r\n *\r\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\r\n *     exercising permissions granted by this License.\r\n *\r\n *     \"Source\" form shall mean the preferred form for making modifications,\r\n *     including but not limited to software source code, documentation\r\n *     source, and configuration files.\r\n *\r\n *     \"Object\" form shall mean any form resulting from mechanical\r\n *     transformation or translation of a Source form, including but\r\n *     not limited to compiled object code, generated documentation,\r\n *     and conversions to other media types.\r\n *\r\n *     \"Work\" shall mean the work of authorship, whether in Source or\r\n *     Object form, made available under the License, as indicated by a\r\n *     copyright notice that is included in or attached to the work\r\n *     (an example is provided in the Appendix below).\r\n *\r\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\r\n *     form, that is based on (or derived from) the Work and for which the\r\n *     editorial revisions, annotations, elaborations, or other modifications\r\n *     represent, as a whole, an original work of authorship. For the purposes\r\n *     of this License, Derivative Works shall not include works that remain\r\n *     separable from, or merely link (or bind by name) to the interfaces of,\r\n *     the Work and Derivative Works thereof.\r\n *\r\n *     \"Contribution\" shall mean any work of authorship, including\r\n *     the original version of the Work and any modifications or additions\r\n *     to that Work or Derivative Works thereof, that is intentionally\r\n *     submitted to Licensor for inclusion in the Work by the copyright owner\r\n *     or by an individual or Legal Entity authorized to submit on behalf of\r\n *     the copyright owner. For the purposes of this definition, \"submitted\"\r\n *     means any form of electronic, verbal, or written communication sent\r\n *     to the Licensor or its representatives, including but not limited to\r\n *     communication on electronic mailing lists, source code control systems,\r\n *     and issue tracking systems that are managed by, or on behalf of, the\r\n *     Licensor for the purpose of discussing and improving the Work, but\r\n *     excluding communication that is conspicuously marked or otherwise\r\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\r\n *\r\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\r\n *     on behalf of whom a Contribution has been received by Licensor and\r\n *     subsequently incorporated within the Work.\r\n *\r\n *  2. Grant of Copyright License. Subject to the terms and conditions of\r\n *     this License, each Contributor hereby grants to You a perpetual,\r\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n *     copyright license to reproduce, prepare Derivative Works of,\r\n *     publicly display, publicly perform, sublicense, and distribute the\r\n *     Work and such Derivative Works in Source or Object form.\r\n *\r\n *  3. Grant of Patent License. Subject to the terms and conditions of\r\n *     this License, each Contributor hereby grants to You a perpetual,\r\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n *     (except as stated in this section) patent license to make, have made,\r\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\r\n *     where such license applies only to those patent claims licensable\r\n *     by such Contributor that are necessarily infringed by their\r\n *     Contribution(s) alone or by combination of their Contribution(s)\r\n *     with the Work to which such Contribution(s) was submitted. If You\r\n *     institute patent litigation against any entity (including a\r\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\r\n *     or a Contribution incorporated within the Work constitutes direct\r\n *     or contributory patent infringement, then any patent licenses\r\n *     granted to You under this License for that Work shall terminate\r\n *     as of the date such litigation is filed.\r\n *\r\n *  4. Redistribution. You may reproduce and distribute copies of the\r\n *     Work or Derivative Works thereof in any medium, with or without\r\n *     modifications, and in Source or Object form, provided that You\r\n *     meet the following conditions:\r\n *\r\n *     (a) You must give any other recipients of the Work or\r\n *         Derivative Works a copy of this License; and\r\n *\r\n *     (b) You must cause any modified files to carry prominent notices\r\n *         stating that You changed the files; and\r\n *\r\n *     (c) You must retain, in the Source form of any Derivative Works\r\n *         that You distribute, all copyright, patent, trademark, and\r\n *         attribution notices from the Source form of the Work,\r\n *         excluding those notices that do not pertain to any part of\r\n *         the Derivative Works; and\r\n *\r\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\r\n *         distribution, then any Derivative Works that You distribute must\r\n *         include a readable copy of the attribution notices contained\r\n *         within such NOTICE file, excluding those notices that do not\r\n *         pertain to any part of the Derivative Works, in at least one\r\n *         of the following places: within a NOTICE text file distributed\r\n *         as part of the Derivative Works; within the Source form or\r\n *         documentation, if provided along with the Derivative Works; or,\r\n *         within a display generated by the Derivative Works, if and\r\n *         wherever such third-party notices normally appear. The contents\r\n *         of the NOTICE file are for informational purposes only and\r\n *         do not modify the License. You may add Your own attribution\r\n *         notices within Derivative Works that You distribute, alongside\r\n *         or as an addendum to the NOTICE text from the Work, provided\r\n *         that such additional attribution notices cannot be construed\r\n *         as modifying the License.\r\n *\r\n *     You may add Your own copyright statement to Your modifications and\r\n *     may provide additional or different license terms and conditions\r\n *     for use, reproduction, or distribution of Your modifications, or\r\n *     for any such Derivative Works as a whole, provided Your use,\r\n *     reproduction, and distribution of the Work otherwise complies with\r\n *     the conditions stated in this License.\r\n *\r\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\r\n *     any Contribution intentionally submitted for inclusion in the Work\r\n *     by You to the Licensor shall be under the terms and conditions of\r\n *     this License, without any additional terms or conditions.\r\n *     Notwithstanding the above, nothing herein shall supersede or modify\r\n *     the terms of any separate license agreement you may have executed\r\n *     with Licensor regarding such Contributions.\r\n *\r\n *  6. Trademarks. This License does not grant permission to use the trade\r\n *     names, trademarks, service marks, or product names of the Licensor,\r\n *     except as required for reasonable and customary use in describing the\r\n *     origin of the Work and reproducing the content of the NOTICE file.\r\n *\r\n *  7. Disclaimer of Warranty. Unless required by applicable law or\r\n *     agreed to in writing, Licensor provides the Work (and each\r\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\r\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r\n *     implied, including, without limitation, any warranties or conditions\r\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\r\n *     appropriateness of using or redistributing the Work and assume any\r\n *     risks associated with Your exercise of permissions under this License.\r\n *\r\n *  8. Limitation of Liability. In no event and under no legal theory,\r\n *     whether in tort (including negligence), contract, or otherwise,\r\n *     unless required by applicable law (such as deliberate and grossly\r\n *     negligent acts) or agreed to in writing, shall any Contributor be\r\n *     liable to You for damages, including any direct, indirect, special,\r\n *     incidental, or consequential damages of any character arising as a\r\n *     result of this License or out of the use or inability to use the\r\n *     Work (including but not limited to damages for loss of goodwill,\r\n *     work stoppage, computer failure or malfunction, or any and all\r\n *     other commercial damages or losses), even if such Contributor\r\n *     has been advised of the possibility of such damages.\r\n *\r\n *  9. Accepting Warranty or Additional Liability. While redistributing\r\n *     the Work or Derivative Works thereof, You may choose to offer,\r\n *     and charge a fee for, acceptance of support, warranty, indemnity,\r\n *     or other liability obligations and/or rights consistent with this\r\n *     License. However, in accepting such obligations, You may act only\r\n *     on Your own behalf and on Your sole responsibility, not on behalf\r\n *     of any other Contributor, and only if You agree to indemnify,\r\n *     defend, and hold each Contributor harmless for any liability\r\n *     incurred by, or claims asserted against, such Contributor by reason\r\n *     of your accepting any such warranty or additional liability.\r\n *\r\n *  END OF TERMS AND CONDITIONS\r\n *\r\n *  APPENDIX: How to apply the Apache License to your work.\r\n *\r\n *     To apply the Apache License to your work, attach the following\r\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\r\n *     replaced with your own identifying information. (Don't include\r\n *     the brackets!)  The text should be enclosed in the appropriate\r\n *     comment syntax for the file format. We also recommend that a\r\n *     file or class name and description of purpose be included on the\r\n *     same \"printed page\" as the copyright notice for easier\r\n *     identification within third-party archives.\r\n *\r\n *  Copyright 2016 Alibaba Group\r\n *\r\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\r\n *  you may not use this file except in compliance with the License.\r\n *  You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n *  Unless required by applicable law or agreed to in writing, software\r\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\r\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n *  See the License for the specific language governing permissions and\r\n *  limitations under the License.\r\n *\r\n *\r\n *\r\n */\r\n\r\npackage android.taobao.atlas.runtime;\r\n\r\nimport android.app.Activity;\r\nimport android.app.Dialog;\r\nimport android.content.ContextWrapper;\r\nimport android.content.Intent;\r\nimport android.content.pm.ActivityInfo;\r\nimport android.os.Build;\r\nimport android.taobao.atlas.util.StringUtils;\r\n\r\nimport java.lang.ref.WeakReference;\r\nimport java.lang.reflect.Field;\r\nimport java.util.ArrayList;\r\nimport java.util.HashMap;\r\nimport java.util.List;\r\n\r\npublic class ActivityTaskMgr {\r\n\r\n    private List<WeakReference<Activity>> activityList = new ArrayList<WeakReference<Activity>>();\r\n    public  static Dialog sReminderDialog;\r\n\r\n    private static ActivityTaskMgr       sInstance = null;\r\n\r\n\r\n    private ActivityTaskMgr(){\r\n    }\r\n\r\n    /**\r\n     * Get the instance of this.\r\n     * \r\n     * @return instance\r\n     */\r\n    public static synchronized ActivityTaskMgr getInstance() {\r\n        if (sInstance == null) {\r\n            sInstance = new ActivityTaskMgr();\r\n        }\r\n        return sInstance;\r\n    }\r\n\r\n    public List<WeakReference<Activity>> getActivityList(){\r\n        return activityList;\r\n    }\r\n\r\n    public Activity peekTopActivity(){\r\n        if(activityList!=null && activityList.size()>0){\r\n            WeakReference<Activity> ref = activityList.get(activityList.size()-1);\r\n            if(ref!=null && ref.get()!=null){\r\n                return ref.get();\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    public void pushToActivityStack(Activity activity) {\r\n        activityList.add(new WeakReference<Activity>(activity));\r\n    }\r\n\r\n    public void popFromActivityStack(Activity activity) {\r\n        if(sReminderDialog!=null &&\r\n                (sReminderDialog.getContext()==activity ||\r\n                        (sReminderDialog.getContext() instanceof ContextWrapper && ((ContextWrapper)sReminderDialog.getContext()).getBaseContext()==activity))){\r\n            try{\r\n                sReminderDialog.dismiss();\r\n            }catch (Throwable e){}finally {\r\n                sReminderDialog = null;\r\n            }\r\n        }\r\n        for(int x=0; x<activityList.size(); x++){\r\n            WeakReference<Activity> ref = activityList.get(x);\r\n            if(ref!=null && ref.get()!=null && ref.get()==activity){\r\n                activityList.remove(ref);\r\n            }\r\n        }\r\n    }\r\n\r\n    public void clearActivityStack(){\r\n        try {\r\n            for (WeakReference<Activity> ref : activityList) {\r\n                if (ref != null && ref.get() != null && !ref.get().isFinishing()) {\r\n                    ref.get().finish();\r\n                }\r\n            }\r\n        }catch (Throwable e){\r\n\r\n        }finally {\r\n            activityList.clear();\r\n        }\r\n    }\r\n\r\n    public boolean isActivityStackEmpty() {\r\n        return activityList.size() == 0;\r\n    }\r\n    \r\n\tpublic int sizeOfActivityStack() {\r\n\t\treturn activityList.size();\r\n\t}\r\n\r\n    public void updateBundleActivityResource(String bundleName){\r\n        for(int x=0; x<activityList.size(); x++){\r\n            WeakReference<Activity> ref = activityList.get(x);\r\n            if(ref!=null && ref.get()!=null && !ref.get().isFinishing()){\r\n                Activity activity =  ref.get();\r\n                try {\r\n                    if(Build.VERSION.SDK_INT>=17 && activity.getResources()!=RuntimeVariables.delegateResources) {\r\n                        Field mResourcesField = Activity.class.getSuperclass().getDeclaredField(\"mResources\");\r\n                        mResourcesField.setAccessible(true);\r\n                        mResourcesField.set(activity, RuntimeVariables.delegateResources);\r\n                    }\r\n                    Field mThemeField = Activity.class.getSuperclass().getDeclaredField(\"mTheme\");\r\n                    mThemeField.setAccessible(true);\r\n                    Object mTheme = mThemeField.get(activity);\r\n                    Field mReferenceResource = mTheme.getClass().getDeclaredField(\"this$0\");\r\n                    mReferenceResource.setAccessible(true);\r\n                    if(mReferenceResource.get(mTheme) != RuntimeVariables.delegateResources){\r\n                        mThemeField.set(activity, null);\r\n                    }\r\n\r\n                    Class TintContextWrapper = Class.forName(\"android.support.v7.widget.TintContextWrapper\");\r\n                    Field tintWrapperField = TintContextWrapper.getDeclaredField(\"sCache\");\r\n                    tintWrapperField.setAccessible(true);\r\n                    ArrayList<WeakReference<Object>> sCache = (ArrayList<WeakReference<Object>>)tintWrapperField.get(TintContextWrapper);\r\n\r\n                    if(sCache!=null){\r\n                        for(int n=0; n<sCache.size();n++){\r\n                            final WeakReference<Object> wrappRef = sCache.get(n);\r\n                            final Object wrapper = wrappRef != null ? wrappRef.get() : null;\r\n                            if (wrapper != null && ((ContextWrapper)wrapper).getBaseContext() == activity) {\r\n                                Field mTintResourcesField = TintContextWrapper.getDeclaredField(\"mResources\");\r\n                                mTintResourcesField.setAccessible(true);\r\n                                mTintResourcesField.set(wrapper,RuntimeVariables.delegateResources);\r\n                                break;\r\n                            }\r\n                        }\r\n                    }\r\n                } catch (Throwable e) {\r\n                    //e.printStackTrace();\r\n                }\r\n\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/runtime/ApplicationInvoker.java",
    "content": "package android.taobao.atlas.runtime;\n\nimport android.app.Application;\nimport android.content.Context;\nimport android.taobao.atlas.util.RefectUtils;\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport java.lang.reflect.Method;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\n/**\n * 创建日期：2019/4/8 on 上午11:29\n * 描述:\n * 作者:zhayu.ll\n */\npublic class ApplicationInvoker {\n    private static Map<String, ApplicationInvoker> mApplications = new ConcurrentHashMap();\n    private volatile boolean inited = false;\n\n    private ApplicationInvoker() {\n    }\n\n    public static ApplicationInvoker getInstance(String bundleName) {\n        synchronized (mApplications) {\n            if (mApplications.containsKey(bundleName)) {\n                return  mApplications.get(bundleName);\n            } else {\n                ApplicationInvoker applicationInvoker = new ApplicationInvoker();\n                mApplications.put(bundleName, applicationInvoker);\n                return applicationInvoker;\n            }\n        }\n    }\n\n    public synchronized void invoke(String applicationClassName, Context context) {\n        if (!this.inited) {\n            this.inited = true;\n            if (!TextUtils.isEmpty(applicationClassName)) {\n                try {\n                    Class<?> applicationClass = ApplicationInvoker.class.getClassLoader().loadClass(applicationClassName);\n                    if (applicationClass == null) {\n                        throw new ClassNotFoundException(String.format(\"can not find class: %s\", applicationClassName));\n                    }\n\n                    Application app = (Application) applicationClass.newInstance();\n                    Method attachBaseContext = RefectUtils.method(app, \"attachBaseContext\", new Class[]{Context.class});\n                    attachBaseContext.invoke(app, context);\n                    Method onCreate = RefectUtils.method(app, \"onCreate\", new Class[0]);\n                    onCreate.invoke(app);\n                    Log.e(\"ApplicationInvoker\", \"successfully invoke start application \" + applicationClassName);\n                } catch (Exception var7) {\n                    var7.printStackTrace();\n                    this.inited = false;\n                }\n\n            }\n        }\n    }\n\n    public synchronized void invoke(String applicationClassName, Context context, ApplicationInvoker.AppInitListener appInitListener) {\n        if (this.inited) {\n            if (appInitListener != null) {\n                appInitListener.onInitFinish();\n            }\n\n        } else {\n            this.inited = true;\n            if (TextUtils.isEmpty(applicationClassName)) {\n                if (appInitListener != null) {\n                    appInitListener.onInitFinish();\n                }\n\n            } else {\n                Class applicationClass = null;\n\n                try {\n                    applicationClass = ApplicationInvoker.class.getClassLoader().loadClass(applicationClassName);\n                    if (applicationClass == null) {\n                        throw new ClassNotFoundException(String.format(\"can not find class: %s\", applicationClassName));\n                    }\n\n                    Application app = (Application) applicationClass.newInstance();\n                    Method attachBaseContext = RefectUtils.method(app, \"attachBaseContext\", new Class[]{Context.class});\n                    attachBaseContext.invoke(app, context);\n                    Method onCreate = RefectUtils.method(app, \"onCreate\", new Class[0]);\n                    onCreate.invoke(app);\n                    Log.e(\"ApplicationInvoker\", \"successfully invoke start application \" + applicationClassName);\n                    if (appInitListener != null) {\n                        appInitListener.onInitFinish();\n                    }\n                } catch (Exception var8) {\n                    this.inited = false;\n                    if (appInitListener!= null) {\n                        appInitListener.onInitError(var8.getMessage());\n                    }\n                }\n\n            }\n        }\n    }\n\n    public interface AppInitListener {\n        void onInitFinish();\n\n        void onInitError(String var1);\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/runtime/AtlasPreLauncher.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.runtime;\n\nimport android.content.Context;\n\n\npublic interface AtlasPreLauncher {\n\n    void initBeforeAtlas(final Context context);\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/runtime/BundleIniter.java",
    "content": "package android.taobao.atlas.runtime;\n\nimport android.taobao.atlas.bundleInfo.AtlasBundleInfoManager;\nimport android.text.TextUtils;\n\n/**\n * 创建日期：2019/4/8 on 上午11:27\n * 描述:\n * 作者:zhayu.ll\n */\npublic class BundleIniter {\n\n    public static void initBundle(String bundleName, ApplicationInvoker.AppInitListener appInitListener){\n\n        if (TextUtils.isEmpty(bundleName)|| AtlasBundleInfoManager.instance().getBundleInfo(bundleName) == null) {\n\n            return;\n        }\n\n        String appName = AtlasBundleInfoManager.instance().getBundleInfo(bundleName).applicationName;\n\n        if (!TextUtils.isEmpty(appName)) {\n            ApplicationInvoker.getInstance(bundleName).invoke(appName, RuntimeVariables.androidApplication,appInitListener);\n\n        }else {\n            if (appInitListener != null){\n                appInitListener.onInitFinish();\n            }\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/runtime/FrameworkLifecycleHandler.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.runtime;\n\nimport android.content.ComponentCallbacks;\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.content.res.Configuration;\nimport android.os.Looper;\nimport android.preference.PreferenceManager;\nimport android.taobao.atlas.bundleInfo.AtlasBundleInfoManager;\nimport android.taobao.atlas.bundleInfo.BundleListing;\nimport android.taobao.atlas.framework.Atlas;\n\n\nimport android.taobao.atlas.hack.AtlasHacks;\nimport android.text.TextUtils;\nimport org.osgi.framework.BundleException;\nimport org.osgi.framework.FrameworkEvent;\nimport org.osgi.framework.FrameworkListener;\n\nimport android.app.Application;\nimport android.content.pm.ApplicationInfo;\nimport android.content.pm.PackageManager;\nimport android.content.pm.PackageManager.NameNotFoundException;\nimport android.taobao.atlas.framework.Framework;\nimport android.taobao.atlas.startup.patch.KernalConstants;\nimport android.taobao.atlas.util.StringUtils;\nimport android.taobao.atlas.util.log.impl.AtlasMonitor;\nimport android.taobao.atlas.versionInfo.BaselineInfoManager;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.Arrays;\nimport java.util.List;\n\n\npublic class FrameworkLifecycleHandler implements FrameworkListener {\n\n    @Override\n    public void frameworkEvent(FrameworkEvent event) {\n        switch (event.getType()) {\n            case 0:/* STARTING */\n                starting();\n                break;\n            case FrameworkEvent.STARTED:\n                started();\n                break;\n            case FrameworkEvent.STARTLEVEL_CHANGED:\n            case FrameworkEvent.PACKAGES_REFRESHED:\n            case FrameworkEvent.ERROR:\n        }\n\n    }\n\n    private void starting() {\n        if (RuntimeVariables.safeMode) {\n            return;\n        }\n\n        if (BaselineInfoManager.instance().isUpdated(\"com.taobao.maindex\")) {\n//            AdditionalPackageManager.getInstance();\n        }\n\n        long time = System.currentTimeMillis();\n        android.os.Bundle metaData = null;\n        try {\n            ApplicationInfo applicationInfo = RuntimeVariables.androidApplication.getPackageManager().getApplicationInfo(RuntimeVariables.androidApplication.getPackageName(),\n                    PackageManager.GET_META_DATA);\n            metaData = applicationInfo.metaData;\n        } catch (NameNotFoundException e1) {\n            e1.printStackTrace();\n        }\n\n        if (metaData != null) {\n            String strApps = metaData.getString(\"application\");\n            if (StringUtils.isNotEmpty(strApps)) {\n                String[] appClassNames = StringUtils.split(strApps, \",\");\n                if (appClassNames == null || appClassNames.length == 0) {\n                    appClassNames = new String[]{strApps};\n                }\n                for (String appClassName : appClassNames) {\n                    try {\n                        Application app = newApplication(appClassName,\n                                Framework.getSystemClassLoader());\n                        app.onCreate();\n                    } catch (Exception e) {\n                        e.printStackTrace();\n                    }\n                }\n            }\n        }\n\n        final long timediff = System.currentTimeMillis() - time;\n    }\n\n    private void started() {\n        RuntimeVariables.androidApplication.registerActivityLifecycleCallbacks(new ActivityLifeCycleObserver());\n        RuntimeVariables.androidApplication.registerComponentCallbacks(new ComponentCallbacks() {\n            @Override\n            public void onConfigurationChanged(Configuration newConfig) {\n                if (RuntimeVariables.delegateResources != null) {\n                    RuntimeVariables.delegateResources.updateConfiguration(newConfig, RuntimeVariables.delegateResources.getDisplayMetrics());\n                }\n            }\n\n            @Override\n            public void onLowMemory() {\n\n            }\n        });\n\n\n   }\n\n\n    protected static Application newApplication(String applicationClassName, ClassLoader cl) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException {\n            final Class<?> applicationClass = cl.loadClass(applicationClassName);\n\n            Application app = (Application) applicationClass.newInstance();\n            AtlasHacks.Application_attach.invoke(app, RuntimeVariables.androidApplication);\n\n            return app;\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/runtime/LowDiskException.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.runtime;\n\n/**\n * Created by xieguo on 15-9-16.\n */\npublic class LowDiskException extends RuntimeException{\n    /**\n     * Nested exception.\n     */\n    private transient Throwable throwable;\n\n    /**\n     * Thredshold for report LowDiskException\n     */\n    public static int thredshold = 150;\n\n    /**\n     * Creates a <tt>LowDiskException</tt> that wraps another exception.\n     *\n     * @param msg The associated message.\n     * @param throwable The nested exception.\n     */\n    public LowDiskException(String msg, Throwable throwable)\n    {\n        super(msg, throwable);\n        this.throwable = throwable;\n    }\n\n    /**\n     * Creates a <tt>LowDiskException</tt> object with the specified message.\n     *\n     * @param msg The message.\n     */\n    public LowDiskException(String msg)\n    {\n        super(msg);\n        this.throwable = null;\n    }\n\n    /**\n     * Returns any nested exceptions included in this exception.\n     *\n     * @return The nested exception; <tt>null</tt> if there is\n     * no nested exception.\n     */\n    public Throwable getNestedException()\n    {\n        return(throwable);\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/runtime/RuntimeVariables.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.runtime;\n\nimport android.app.Activity;\nimport android.app.Application;\nimport android.app.Dialog;\nimport android.content.ComponentName;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.res.Resources;\nimport android.taobao.atlas.R;\nimport android.taobao.atlas.framework.Atlas;\nimport android.taobao.atlas.framework.FrameworkProperties;\nimport android.text.TextUtils;\nimport android.view.ViewGroup;\nimport java.io.Serializable;\nimport java.lang.reflect.Field;\n\npublic class RuntimeVariables implements Serializable{\n\n    public static Application         androidApplication;\n\n    public static ClassLoader delegateClassLoader;\n\n    public static Resources           delegateResources;\n\n    public static Resources           originalResources;\n\n    public static String              sRealApplicationName;\n\n    public static String              sCurrentProcessName;\n\n    public static boolean             safeMode = false;\n\n    public static int                 patchVersion = 1;\n\n    public static String              sInstalledVersionName;\n\n    public static long                sInstalledVersionCode;\n\n    public static long                sAppLastUpdateTime;\n\n    public static String              sApkPath;\n\n    public static Atlas.ExternalBundleInstallReminder sReminder;\n\n    public static Atlas.BundleVerifier sBundleVerifier;\n\n    public static boolean             sCachePreVersionBundles = false;\n\n    /**\n     * apilevel >=23\n     */\n    public static ClassLoader sRawClassLoader;\n    public static Object      sDexLoadBooster;\n    private static String launchActivityName;\n\n\n    public static Class FrameworkPropertiesClazz;\n\n    public static Object getFrameworkProperty(String fieldName){\n        if(FrameworkPropertiesClazz==null){\n            FrameworkPropertiesClazz = FrameworkProperties.class;\n        }\n        try {\n            Field field = FrameworkPropertiesClazz.getDeclaredField(fieldName);\n            field.setAccessible(true);\n            return field.get(FrameworkPropertiesClazz);\n        }catch(Throwable e){\n            return null;\n        }\n    }\n\n    public static String getProcessName(Context context) {\n        return sCurrentProcessName;\n    }\n\n    public static boolean shouldSyncUpdateInThisProcess(){\n        String processName = RuntimeVariables.sCurrentProcessName;\n        if(processName!=null &&\n                (processName.equals(RuntimeVariables.androidApplication.getPackageName()) ||\n                        processName.toLowerCase().contains(\":safemode\")\n                )){\n            return true;\n        }else{\n            return false;\n        }\n    }\n\n    public static ClassLoader getRawClassLoader(){\n        if(sRawClassLoader!=null){\n            return sRawClassLoader;\n        }else{\n            return RuntimeVariables.class.getClassLoader();\n        }\n    }\n\n    public static String getLauncherClassName() {\n        if (!TextUtils.isEmpty(launchActivityName)){\n            return launchActivityName;\n        }\n        if (androidApplication == null){\n            return null;\n        }\n        Intent launchIntentForPackage = RuntimeVariables.androidApplication.getPackageManager().getLaunchIntentForPackage(RuntimeVariables.androidApplication.getPackageName());\n        if (launchIntentForPackage != null) {\n            ComponentName componentName = launchIntentForPackage.resolveActivity(RuntimeVariables.androidApplication.getPackageManager());\n            launchActivityName = componentName.getClassName();\n        }\n        return launchActivityName;\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/AtlasBridgeApplication.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.startup;\n\nimport android.annotation.TargetApi;\nimport android.app.ActivityManager;\nimport android.app.Application;\nimport android.app.Notification;\nimport android.app.NotificationManager;\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.content.pm.ApplicationInfo;\nimport android.content.pm.PackageInfo;\nimport android.content.pm.PackageManager;\nimport android.content.res.Resources;\nimport android.os.Build;\nimport android.os.Process;\nimport android.preference.PreferenceManager;\nimport android.taobao.atlas.startup.patch.KernalBundle;\nimport android.taobao.atlas.startup.patch.KernalConstants;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\n\n/**\n * Created by guanjie on 16/10/20.\n */\n\n/**\n * android.taobao.atlas.start.* package can't be tpatched\n * any class in this package could not import external classes except framework classes\n *\n *  * android.taobao.atlas.start.* package can't be tpatched\n * any class in this package could not import external classes except framework classes\n *\n *  * android.taobao.atlas.start.* package can't be tpatched\n * any class in this package could not import external classes except framework classes\n */\npublic class AtlasBridgeApplication extends Application{\n\n    public  Object mBridgeApplicationDelegate;\n    @Override\n    protected void attachBaseContext(Context base) {\n        super.attachBaseContext(base);\n        if (!isApplicationNormalCreate(base)) {\n            android.os.Process.killProcess(android.os.Process.myPid());\n        }\n        System.setProperty(\"BOOT_TIME\",System.currentTimeMillis()+\"\");\n        // *0 checkload kernalpatch\n        boolean isUpdated = isUpdated(getBaseContext());\n        Log.e(\"AtlasBridgeApplication\", \"attachBaseContext() - isUpdated = \" + isUpdated);\n\n        KernalConstants.baseContext = getBaseContext();\n        KernalConstants.APK_PATH = getBaseContext().getApplicationInfo().sourceDir;\n        KernalConstants.RAW_APPLICATION_NAME = getClass().getName();\n        boolean hasKernalPatched  = false;\n        boolean isMainProcess = getBaseContext().getPackageName().equals(KernalConstants.PROCESS);\n        if(isUpdated){\n            if (!isMainProcess) {\n                android.os.Process.killProcess(android.os.Process.myPid());\n            }\n            File storageDir = new File(getFilesDir(),\"storage\");\n            File bundleBaseline = new File(getFilesDir(),\"bundleBaseline\");\n            deleteDirectory(storageDir);\n            KernalVersionManager.instance().removeBaseLineInfo();\n            if(storageDir.exists() || bundleBaseline.exists()){\n                android.os.Process.killProcess(Process.myPid());\n            }\n            storePackageVersion(base);\n            KernalVersionManager.instance().init();\n            System.setProperty(\"APK_INSTALLED\", \"true\");\n        }else{\n            if(KernalConstants.PROCESS.contains(\":dex2oat\")){\n                return;\n            }\n            KernalVersionManager.instance().init();\n            if(!KernalBundle.checkLoadKernalDebugPatch(this)){\n\n                if(KernalBundle.hasKernalPatch() && Build.VERSION.SDK_INT < 28) {\n                    //has patch ? true -> must load successed\n                    hasKernalPatched = KernalBundle.checkloadKernalBundle(this, KernalConstants.PROCESS);\n                    if (!hasKernalPatched) {\n                        // load failed\n                        if(isMainProcess) {\n                            KernalVersionManager.instance().rollbackHardly();\n                        }\n                        android.os.Process.killProcess(android.os.Process.myPid());\n                    }\n                }else{\n                    //remove deprecated info\n                    if(isMainProcess) {\n                        KernalBundle.clear();\n                    }\n                }\n            }\n        }\n\n\n        try {\n            //初始化baselineinfomanager\n            Class BaselineInfoManagerClazz = getBaseContext().getClassLoader().loadClass(\"android.taobao.atlas.versionInfo.BaselineInfoManager\");\n            Method instanceMethod = BaselineInfoManagerClazz.getDeclaredMethod(\"instance\");\n            Object instance = instanceMethod.invoke(BaselineInfoManagerClazz);\n            Field mVersionManager = BaselineInfoManagerClazz.getDeclaredField(\"mVersionManager\");\n            mVersionManager.setAccessible(true);\n            mVersionManager.set(instance,KernalVersionManager.instance());\n\n            Class BridgeApplicationDelegateClazz = getBaseContext().getClassLoader().loadClass(\"android.taobao.atlas.bridge.BridgeApplicationDelegate\");\n            Class<?>[] parTypes=new Class<?>[8];\n            parTypes[0]= Application.class;\n            parTypes[1]= String.class;\n            parTypes[2]= String.class;\n            parTypes[3]= long.class;\n            parTypes[4]= long.class;\n            parTypes[5]= String.class;\n            parTypes[6]= boolean.class;\n            parTypes[7]= Object.class;\n            Constructor<?> con = BridgeApplicationDelegateClazz.getConstructor(parTypes);\n            mBridgeApplicationDelegate = con.newInstance(this,KernalConstants.PROCESS,KernalConstants.INSTALLED_VERSIONNAME,\n                    KernalConstants.INSTALLED_VERSIONCODE,KernalConstants.LASTUPDATETIME,KernalConstants.APK_PATH,isUpdated,null);\n            Method method = BridgeApplicationDelegateClazz.getDeclaredMethod(\"attachBaseContext\");\n            method.invoke(mBridgeApplicationDelegate);\n        } catch (Throwable e) {\n            throw new RuntimeException(e);\n        }\n        if (KernalBundle.hasNativeLibPatch(this)){\n            KernalBundle.patchNativeLib(this);\n        }\n    }\n\n    @Override\n    public Resources getResources() {\n        Resources rs =  super.getResources();\n        if (rs == null){\n            PackageManager pm = getPackageManager();\n            try {\n                rs = pm.getResourcesForApplication(getApplicationInfo());\n            } catch (PackageManager.NameNotFoundException e) {\n                e.printStackTrace();\n                return null;\n            }\n        }\n        return rs;\n    }\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        if(!KernalConstants.PROCESS.contains(\":dex2oat\")){\n            try {\n                Method method = mBridgeApplicationDelegate.getClass().getDeclaredMethod(\"onCreate\");\n                method.invoke(mBridgeApplicationDelegate);\n            } catch (InvocationTargetException e) {\n                throw new RuntimeException(e.getTargetException());\n            } catch(NoSuchMethodException e){\n                throw new RuntimeException(e);\n            } catch(IllegalAccessException e){\n                throw new RuntimeException(e);\n            }\n        }\n    }\n\n    private boolean isApplicationNormalCreate(Context base) {\n        Throwable ex = new Throwable();\n        StackTraceElement[] stackElements = ex.getStackTrace();\n        if (stackElements != null) {\n            for (int i = 0; i < stackElements.length; i++) {\n                if (stackElements[i].getClassName().equalsIgnoreCase(\"android.taobao.atlas.runtime.InstrumentationHook\")) {\n                    return false;\n                }\n            }\n        }\n\n        ApplicationInfo info = base.getApplicationInfo();\n        if (info == null) {\n            return false;\n        }\n        String apkPath = info.sourceDir;\n        String nativeLibDir = info.nativeLibraryDir;\n        if (apkPath == null || !new File(apkPath).exists()) {\n            checkShowErrorNotification(\"InvalidApkPath\");\n            return false;\n        }\n\n        if (nativeLibDir == null || !new File(nativeLibDir).exists()) {\n            Log.e(\"AtlasBridgeApplication\",\"can not find nativeLibDir : \"+nativeLibDir);\n //           checkShowErrorNotification(\"InvalidLibPath\");\n//            return false;\n        }\n\n        int pid = android.os.Process.myPid();\n        try {\n            ActivityManager mActivityManager = (ActivityManager) base.getSystemService(Context.ACTIVITY_SERVICE);\n            for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager.getRunningAppProcesses()) {\n                if (appProcess.pid == pid) {\n                    KernalConstants.PROCESS =  appProcess.processName;\n                }\n            }\n        } catch (Exception e) {\n        }\n        if(TextUtils.isEmpty(KernalConstants.PROCESS)){\n            Log.e(\"AtlasBridgeApplication\",\"getProcess failed\");\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * TODO 如果supportv4 在子dex这种写法会存在问题\n     *\n     * @param errorInfo\n     */\n    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)\n    private void checkShowErrorNotification(String errorInfo) {\n        SharedPreferences preferences = getSharedPreferences(\"err_log\", Context.MODE_PRIVATE);\n        int errorCount = preferences.getInt(errorInfo, 0);\n        if (errorCount >= 3) {\n            Notification.Builder mBuilder =\n                    new Notification.Builder(this)\n                            .setSmallIcon(this.getResources().getIdentifier(\"icon\",\"drawable\",getPackageName()))\n                            .setContentTitle(\"提示\").setAutoCancel(true)\n                            .setContentText(\"应用安装不完整,请您卸载重新安装!\");\n\n            NotificationManager mNotificationManager =\n                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);\n            mNotificationManager.notify(123, mBuilder.build());\n        } else {\n            preferences.edit().putInt(errorInfo, ++errorCount).commit();\n        }\n    }\n\n    public  boolean isUpdated(Context context){\n        PackageInfo packageInfo = null;\n        // 获取当前的版本号\n        try {\n            PackageManager packageManager = context.getPackageManager();\n            packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);\n        } catch (Exception e) {\n            // 不可能发生\n            android.os.Process.killProcess(android.os.Process.myPid());\n        }\n        KernalConstants.INSTALLED_VERSIONNAME = packageInfo.versionName;\n        KernalConstants.INSTALLED_VERSIONCODE = packageInfo.versionCode;\n        KernalConstants.LASTUPDATETIME = packageInfo.lastUpdateTime;\n        if(TextUtils.isEmpty(KernalConstants.INSTALLED_VERSIONNAME )){\n            //不可能发生\n            Log.e(\"AtlasBridgeApplication\",\"version name is empty \");\n            android.os.Process.killProcess(android.os.Process.myPid());\n        }\n\n        File metafile = new File(context.getFilesDir(), \"storage/version_meta\");\n        if (metafile.exists()) {\n            DataInputStream in = null;\n            try {\n                in = new DataInputStream(new FileInputStream(metafile));\n                String storedVersionName = in.readUTF();\n                long   storedVersionCode = in.readLong();\n                long   storedLastUpdateTime = in.readLong();\n                String storedApkPath = in.readUTF();\n                String fingerprint = in.readUTF();\n\n                System.setProperty(\"APP_VERSION_TAG\",KernalConstants.INSTALLED_VERSIONNAME);\n                // 检测之前的版本记录\n                if(packageInfo.versionCode == storedVersionCode &&\n                        TextUtils.equals(packageInfo.versionName, storedVersionName) &&\n                        packageInfo.lastUpdateTime == storedLastUpdateTime &&\n                        context.getApplicationInfo().sourceDir.equals(storedApkPath) &&\n                        !needRollback() &&\n                        (Build.FINGERPRINT + \"\"+  Build.VERSION.SDK_INT).equals(fingerprint)){\n\n                    return false;\n                }else {\n                    if (!TextUtils.isEmpty(storedVersionName)){\n                        PreferenceManager.getDefaultSharedPreferences(this).edit().putString(\"lastInstalledVersionName\",storedVersionName).apply();\n                    }\n                }\n            }catch(Throwable e){\n//                throw new RuntimeException(e);\n            }finally {\n                if(in!=null){\n                    try {\n                        in.close();\n                    }catch(Throwable e){ }\n                }\n            }\n        }\n        return true;\n    }\n\n    private void storePackageVersion(Context base){\n        File file = new File(base.getFilesDir(), \"storage/version_meta\");\n        DataOutputStream out = null;\n        try {\n            if (!file.getParentFile().exists()) {\n                file.getParentFile().mkdirs();\n            }\n\n            FileOutputStream fos = new FileOutputStream(file);\n            out = new DataOutputStream(fos);\n            out.writeUTF(KernalConstants.INSTALLED_VERSIONNAME);\n            out.writeLong(KernalConstants.INSTALLED_VERSIONCODE);\n            out.writeLong(KernalConstants.LASTUPDATETIME);\n            out.writeUTF(KernalConstants.APK_PATH);\n            out.writeUTF(Build.FINGERPRINT + \"\" + Build.VERSION.SDK_INT);\n            out.flush();\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        } finally {\n            try{\n                if(out!=null)\n                    out.close();\n            }catch (Throwable e){}\n        }\n    }\n\n    public boolean needRollback(){\n        File baseLineDir = new File(getBaseContext().getFilesDir().getAbsolutePath() + File.separatorChar + \"bundleBaseline\");\n        if(baseLineDir.exists()){\n            File deprecated = new File(baseLineDir, \"deprecated_mark\");\n            if(deprecated.exists()){\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public void deleteDirectory(final File path) {\n        if(!path.exists()){\n            return;\n        }\n        final File[] files = path.listFiles();\n        if (files == null){\n            return;\n        }\n        for (int i = 0; i < files.length; i++) {\n            if (files[i].isDirectory()) {\n                deleteDirectory(files[i]);\n            } else {\n                files[i].delete();\n            }\n        }\n        path.delete();\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/DexFileCompat.java",
    "content": "package android.taobao.atlas.startup;\n\nimport android.content.Context;\nimport android.os.Build;\n\nimport java.io.Serializable;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport dalvik.system.DexFile;\n\n/**\n * Created by guanjie on 2017/5/24.\n */\n\npublic class DexFileCompat implements Serializable{\n\n    public static Method openDexFile;\n    public static Field  mCookie;\n    public static Field  mFileName;\n\n    static{\n        try {\n            openDexFile = DexFile.class.getDeclaredMethod(\"openDexFile\", String.class, String.class, int.class);\n            openDexFile.setAccessible(true);\n\n            mCookie = DexFile.class.getDeclaredField(\"mCookie\");\n            mCookie.setAccessible(true);\n            mFileName = DexFile.class.getDeclaredField(\"mFileName\");\n            mFileName.setAccessible(true);\n        }catch(Throwable e){\n            if(Build.VERSION.SDK_INT>15) {\n                throw new RuntimeException(e);\n            }\n        }\n    }\n\n    static public DexFile loadDex(Context context, String sourcePathName, String outputPathName,\n                                  int flags) throws Exception {\n        if(Build.VERSION.SDK_INT<=15) {\n            return DexFile.loadDex(sourcePathName,outputPathName,flags);\n        }else{\n            DexFile dexFile = DexFile.loadDex(context.getApplicationInfo().sourceDir,null,0);\n            try {\n                int cookie = (int)openDexFile.invoke(null,sourcePathName,outputPathName,flags);\n                mFileName.set(dexFile,sourcePathName);\n                mCookie.set(dexFile,cookie);\n            } catch (Exception e) {\n                throw  e;\n            }\n            return dexFile;\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/KernalVersionManager.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.startup;\n\nimport android.app.ActivityManager;\nimport android.content.Context;\nimport android.os.Build;\nimport android.os.Environment;\nimport android.os.Process;\nimport android.taobao.atlas.startup.patch.KernalConstants;\nimport android.taobao.atlas.startup.patch.KernalFileLock;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport java.io.*;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport static android.os.Environment.MEDIA_MOUNTED;\nimport static android.os.Environment.MEDIA_UNKNOWN;\n\n/**\n * Created by guanjie on 15/9/10.\n */\npublic class KernalVersionManager {\n\n    private static KernalVersionManager sBaseInfoManager;\n    private final File  BASELINEINFO_DIR ;\n    private final File  BASELINEINFO;\n    private final File  BASELINEINFO_NEW;\n    private String LAST_VERSIONNAME;\n    private String LAST_UPDATE_BUNDLES;\n    private String LAST_STORAGE_LOCATION;\n    private String CURRENT_UPDATE_BUNDLES;\n    private String CURRENT_VERSIONAME;\n    public String CURRENT_STORAGE_LOCATION;\n    private String DEXPATCH_BUNDLES;\n    public String DEXPATCH_STORAGE_LOCATION;\n    private HashMap<String,String> currentUpdateBundles = new HashMap<String,String>();\n    public ConcurrentHashMap<String,Long> dexPatchBundles = new ConcurrentHashMap<>();\n\n    public boolean cachePreVersion = false;\n\n    private static class SingleTonHolder{\n        private final static KernalVersionManager INSTANCE = new KernalVersionManager();\n    }\n\n    public static KernalVersionManager instance(){\n        return SingleTonHolder.INSTANCE;\n    }\n\n    @Override\n    public String toString(){\n        return String.format(\"%s@%s--%s--dexPatchBundles:%s\",\n            LAST_VERSIONNAME,CURRENT_VERSIONAME,\n            LAST_UPDATE_BUNDLES,\n            TextUtils.isEmpty(DEXPATCH_BUNDLES)?\"\":DEXPATCH_BUNDLES\n        );\n    }\n\n    public void reset(){\n        LAST_VERSIONNAME = \"\";\n        LAST_UPDATE_BUNDLES = \"\";\n        LAST_STORAGE_LOCATION=\"\";\n        CURRENT_STORAGE_LOCATION=\"\";\n        DEXPATCH_STORAGE_LOCATION=\"\";\n        CURRENT_VERSIONAME = \"\";\n        CURRENT_UPDATE_BUNDLES=\"\";\n        DEXPATCH_BUNDLES = \"\";\n        currentUpdateBundles.clear();\n        dexPatchBundles.clear();\n    }\n\n    private KernalVersionManager(){\n        BASELINEINFO_DIR = new File(KernalConstants.baseContext.getFilesDir().getAbsolutePath() + File.separatorChar + \"bundleBaseline\");\n        BASELINEINFO     = new File(BASELINEINFO_DIR,\"updateInfo\");\n        BASELINEINFO_NEW = new File(BASELINEINFO_DIR,\"updateInfo_new\");\n    }\n\n    public void init(){\n        KernalFileLock.getInstance().LockExclusive(BASELINEINFO_DIR);\n        if(shouldSyncUpdateInThisProcess()){\n            if(BASELINEINFO_NEW.exists()){\n                killChildProcesses(KernalConstants.baseContext);\n                int retry  = 3;\n                do {\n                    if (BASELINEINFO.exists()) {\n                        BASELINEINFO.delete();\n                    }\n                    retry--;\n                }while(retry>0 && BASELINEINFO.exists());\n                long length = BASELINEINFO_NEW.length();\n                retry = 3;\n                do {\n                    if(BASELINEINFO_NEW.renameTo(BASELINEINFO)){\n                        break;\n                    }\n                    retry--;\n                }while(retry>0);\n                if(length != BASELINEINFO.length()){\n                    throw new RuntimeException(\"rename baselineinfo fail\");\n                }\n            }\n        }\n        KernalFileLock.getInstance().unLock(BASELINEINFO_DIR);\n\n        String baselineVersion = \"\";\n        String updateBundles = \"\";\n        String lastVersionName = \"\";\n        String lastUpdateBundles=\"\";\n        String lastStorageLocation=\"\";\n        String currentStorageLocation=\"\";\n        String dexpatchStorageLocation=\"\";\n        String dexPatchBundles=\"\";\n        if(BASELINEINFO.exists()){\n            try {\n                /**\n                 * 写入顺序\n                 * 上一次versionname\n                 * 上一次更新内容\n                 * 上一次的存储地址\n                 * 本次versionname\n                 * 本次更新内容\n                 * 本次存储地址\n                 * dexpatch 更新内容\n                 * dexpatch 存储地址\n                 * 是否发生了回滚\n                 */\n                DataInputStream input = new DataInputStream(new BufferedInputStream(new FileInputStream(BASELINEINFO)));\n                lastVersionName = input.readUTF();\n                lastUpdateBundles = input.readUTF();\n                lastStorageLocation=input.readUTF();\n                baselineVersion = input.readUTF();\n                updateBundles = input.readUTF();\n                currentStorageLocation=input.readUTF();\n                dexPatchBundles = input.readUTF();\n                dexpatchStorageLocation = input.readUTF();\n                cachePreVersion = input.readBoolean();\n                if(!TextUtils.isEmpty(dexPatchBundles) && !TextUtils.isEmpty(dexpatchStorageLocation)){\n                    //external dexpatch\n                    File storage = new File(dexpatchStorageLocation);\n                    if(!storage.exists() || !getStorageState(storage).equals(Environment.MEDIA_MOUNTED)){\n                        dexPatchBundles=\"\";\n                        dexpatchStorageLocation = \"\";\n                    }\n                }\n\n                if(!TextUtils.isEmpty(updateBundles) && !TextUtils.isEmpty(currentStorageLocation)){\n                    //no dexpatch,but external bundle update\n                    File storage = new File(currentStorageLocation);\n                    if(!storage.exists() || !getStorageState(storage).equals(Environment.MEDIA_MOUNTED)){\n                        throw new IOException(\"update bundle location storage is not usable\");\n                    }\n                }\n\n                try {\n                    input.close();\n                }catch(Throwable e){}\n            } catch (Throwable e) {\n                if(KernalConstants.PROCESS.equals(KernalConstants.baseContext.getPackageName())) {\n                    rollbackHardly();\n                }\n                killChildProcesses(KernalConstants.baseContext);\n                android.os.Process.killProcess(Process.myPid());\n            }\n        }\n        LAST_VERSIONNAME = lastVersionName;\n        LAST_UPDATE_BUNDLES = lastUpdateBundles;\n        CURRENT_VERSIONAME = baselineVersion;\n        CURRENT_UPDATE_BUNDLES= updateBundles;\n        DEXPATCH_BUNDLES = dexPatchBundles;\n        LAST_STORAGE_LOCATION = lastStorageLocation;\n        CURRENT_STORAGE_LOCATION = currentStorageLocation;\n        DEXPATCH_STORAGE_LOCATION = dexpatchStorageLocation;\n        parseUpdatedBundles();\n    }\n\n    public void removeBaseLineInfo(){\n        if(BASELINEINFO_DIR.exists()) {\n            deleteDirectory(BASELINEINFO_DIR);\n        }\n        File bundleupdate = new File(KernalConstants.baseContext.getFilesDir(),\"bundleupdate\");\n        if(bundleupdate.exists()) {\n            deleteDirectory(bundleupdate);\n        }\n    }\n\n    public void deleteDirectory(final File path) {\n        final File[] files = path.listFiles();\n        if (files == null){\n            return;\n        }\n        for (int i = 0; i < files.length; i++) {\n            if (files[i].isDirectory()) {\n                deleteDirectory(files[i]);\n            } else {\n                files[i].delete();\n            }\n        }\n        path.delete();\n    }\n\n    public String getBaseBundleVersion(String bundleName){\n        return currentUpdateBundles.get(bundleName);\n    }\n\n    public long getDexPatchBundleVersion(String bundleName){\n        if(dexPatchBundles.containsKey(bundleName)){\n            return dexPatchBundles.get(bundleName);\n        }else {\n            return -1;\n        }\n    }\n\n    public Set<String> getUpdateBundles(){\n        return currentUpdateBundles.keySet();\n    }\n\n    public String lastVersionName(){\n        return LAST_VERSIONNAME;\n    }\n\n    public String currentVersionName(){\n        return CURRENT_VERSIONAME;\n    }\n\n    public boolean isCachePreVersion(){\n        boolean flag = Boolean.FALSE.booleanValue();\n        if(flag) {\n            Log.e(\"KernalVersionManager\", \"can no be inlined\");\n        }\n        return cachePreVersion;\n    }\n\n    //updated\n    public boolean isUpdated(String bundleName){\n        if(!TextUtils.isEmpty(getBaseBundleVersion(bundleName))){\n            return true;\n        }\n        return false;\n    }\n\n    //dexpatched\n    public boolean isDexPatched(String bundleName){\n        return getDexPatchBundleVersion(bundleName)>0;\n    }\n\n    public synchronized void parseUpdatedBundles(){\n        if(!TextUtils.isEmpty(CURRENT_UPDATE_BUNDLES)){\n            String[] bundles = CURRENT_UPDATE_BUNDLES.split(\";\");\n            if(bundles!=null && bundles.length>0){\n                for(String bundleInfo : bundles){\n                    String[] infoItems = bundleInfo.split(\"@\");\n                    currentUpdateBundles.put(infoItems[0],infoItems[1]);\n                }\n            }\n        }\n        if(!TextUtils.isEmpty(DEXPATCH_BUNDLES)){\n            String[] bundles = DEXPATCH_BUNDLES.split(\";\");\n            if(bundles!=null && bundles.length>0){\n                for(String bundleInfo : bundles){\n                    String[] infoItems = bundleInfo.split(\"@\");\n                    dexPatchBundles.put(infoItems[0],Long.parseLong(infoItems[1]));\n                }\n            }\n        }\n    }\n\n    public void rollbackHardly(){\n        try {\n            File baseLineDir = BASELINEINFO_DIR;\n            if (!baseLineDir.exists()) {\n                baseLineDir.mkdirs();\n            }\n            File deprecated = new File(baseLineDir, \"deprecated_mark\");\n            if(!deprecated.exists()) {\n                deprecated.createNewFile();\n            }\n            File file = BASELINEINFO;\n            if(file.exists()){\n                file.delete();\n            }\n        }catch(Exception e){\n        }\n    }\n\n    public void rollback(){\n        File baseinfoDir = new File(BASELINEINFO_DIR.getAbsolutePath());\n        if (!baseinfoDir.exists()) {\n            baseinfoDir.mkdir();\n        }\n        try {\n            /**\n             * 写入顺序\n             * 上一次versionname\n             * 上一次更新内容\n             * 本次versionname\n             * 本次更新内容\n             * dexpatch versionname\n             * dexpatch 更新内容\n             * 是否发生了回滚\n             */\n            DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(new File(baseinfoDir.getAbsolutePath(), \"baselineInfo\"))));\n\n            out.writeUTF(\"\");\n            out.writeUTF(\"\");\n            out.writeUTF(\"\");\n            if(cachePreVersion){\n                out.writeUTF(LAST_VERSIONNAME);\n                out.writeUTF(LAST_UPDATE_BUNDLES);\n                out.writeUTF(LAST_STORAGE_LOCATION);\n            }else {\n                out.writeUTF(\"\");\n                out.writeUTF(\"\");\n                out.writeUTF(\"\");\n            }\n            out.writeUTF(\"\");\n            out.writeUTF(\"\");\n            out.writeBoolean(cachePreVersion);\n            out.flush();\n            out.close();\n        } catch (Throwable e) {\n            e.printStackTrace();\n            rollbackHardly();\n        }\n\n    }\n\n    public void saveDexPatchInfo(HashMap<String,String> infos,String storageLocation) throws IOException{\n        for(Iterator iterator = infos.entrySet().iterator(); iterator.hasNext();)\n        {\n            Map.Entry entry = (java.util.Map.Entry)iterator.next();\n            if(entry.getValue().equals(\"-1\") && dexPatchBundles.containsKey(entry.getKey())){\n                //dexPatchBundles.remove(entry.getKey());\n            }else{\n                dexPatchBundles.put((String)entry.getKey(),Long.parseLong((String)entry.getValue()));\n            }\n        }\n\n        StringBuilder bundleList = new StringBuilder(\"\");\n        for(Iterator iterator = dexPatchBundles.entrySet().iterator(); iterator.hasNext();)\n        {\n            Map.Entry entry = (java.util.Map.Entry)iterator.next();\n            if(\"-1\".equals(infos.get(entry.getKey()))){\n                continue;\n            }\n            bundleList.append(entry.getKey());\n            bundleList.append(\"@\");\n            bundleList.append(entry.getValue());\n            bundleList.append(\";\");\n        }\n\n        File baseinfoFile = BASELINEINFO_DIR;\n        if(!baseinfoFile.exists()){\n            baseinfoFile.mkdirs();\n        }\n        File newBaselineInfoFile = new File(BASELINEINFO.getAbsolutePath());\n        if(!newBaselineInfoFile.exists()){\n            newBaselineInfoFile.createNewFile();\n        }\n\n        DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(new File(newBaselineInfoFile.getAbsolutePath()))));\n        String bundleListStr = bundleList.toString();\n        /**\n         * 写入顺序\n         * 上一次versionname\n         * 上一次更新内容\n         * 本次versionname\n         * 本次更新内容\n         * dexpatch versionname\n         * dexpatch 更新内容\n         * 是否发生了回滚\n         */\n        out.writeUTF(LAST_VERSIONNAME);\n        out.writeUTF(LAST_UPDATE_BUNDLES != null ? LAST_UPDATE_BUNDLES : \"\");\n        out.writeUTF(LAST_STORAGE_LOCATION!=null ? LAST_STORAGE_LOCATION:\"\");\n        //如果是和基线dexPatch，由于没有做过动态部署，updateinfo文件可能不存在。\n        //下次启动时，kernealbundle.patchKernalDex方法在比对版本时versionName为\"\"，启动异常。\n        out.writeUTF(TextUtils.isEmpty(CURRENT_VERSIONAME)? KernalConstants.INSTALLED_VERSIONNAME:CURRENT_VERSIONAME);\n        out.writeUTF(CURRENT_UPDATE_BUNDLES);\n        out.writeUTF(CURRENT_STORAGE_LOCATION);\n        //dexpatch 部分\n        out.writeUTF(bundleListStr);\n        out.writeUTF(storageLocation!=null ? storageLocation : \"\");\n        out.writeBoolean(cachePreVersion);\n        out.flush();\n        out.close();\n    }\n\n    public void saveUpdateInfo(String newBaselineVersion, HashMap<String,String> infos,boolean cachePreVersion,String storageLocation) throws IOException{\n        StringBuilder bundleList = new StringBuilder(\"\");\n        for(Iterator iterator = infos.entrySet().iterator(); iterator.hasNext();)\n        {\n            Map.Entry entry = (java.util.Map.Entry)iterator.next();\n            bundleList.append(entry.getKey());\n            bundleList.append(\"@\");\n            bundleList.append(entry.getValue());\n            bundleList.append(\";\");\n        }\n        File baseinfoFile = BASELINEINFO_DIR;\n        if(!baseinfoFile.exists()){\n            baseinfoFile.mkdirs();\n        }\n        File newBaselineInfoFile = new File(BASELINEINFO_NEW.getAbsolutePath());\n        if(!newBaselineInfoFile.exists()){\n            newBaselineInfoFile.createNewFile();\n        }\n        DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(new File(newBaselineInfoFile.getAbsolutePath()))));\n        String bundleListStr = bundleList.toString();\n        /**\n         * 写入顺序\n         * 上一次versionname\n         * 上一次更新内容\n         * 上一次的存储地址\n         * 本次versionname\n         * 本次更新内容\n         * 本次存储地址\n         * dexpatch 更新内容\n         * dexpatch 存储地址\n         * 是否发生了回滚\n         */\n        if(cachePreVersion) {\n            out.writeUTF(!TextUtils.isEmpty(CURRENT_VERSIONAME) ? CURRENT_VERSIONAME : \"\");\n            out.writeUTF(CURRENT_UPDATE_BUNDLES != null ? CURRENT_UPDATE_BUNDLES : \"\");\n            out.writeUTF(CURRENT_STORAGE_LOCATION != null ? CURRENT_STORAGE_LOCATION : \"\");\n        }else{\n            out.writeUTF(\"\");\n            out.writeUTF(\"\");\n            out.writeUTF(\"\");\n        }\n        out.writeUTF(newBaselineVersion);\n        out.writeUTF(bundleListStr);\n        out.writeUTF(storageLocation!=null ? storageLocation : \"\");\n        //dexpatch 部分\n        out.writeUTF(\"\");\n        out.writeUTF(\"\");\n        out.writeBoolean(cachePreVersion);\n        out.flush();\n        out.close();\n    }\n\n    private boolean shouldSyncUpdateInThisProcess(){\n        String processName = KernalConstants.PROCESS;\n        if(processName!=null &&\n                (processName.equals(KernalConstants.baseContext.getPackageName()) ||\n                        processName.toLowerCase().contains(\":safemode\")\n                )){\n            return true;\n        }else{\n            return false;\n        }\n    }\n\n    public void killChildProcesses(Context context) {\n        try {\n            long uid = context.getApplicationInfo().uid;\n            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);\n            List<ActivityManager.RunningAppProcessInfo> a = am.getRunningAppProcesses();\n            for (int i = 0; i < a.size(); i++) {\n                ActivityManager.RunningAppProcessInfo b = a.get(i);\n                if(b.uid == uid && !b.processName.equals(context.getPackageName())){\n                    android.os.Process.killProcess(b.pid);\n                }\n\n            }\n        } catch (Exception e) {\n\n        }\n    }\n\n    private String getStorageState(File path) {\n        if(path.getAbsolutePath().startsWith(KernalConstants.baseContext.getFilesDir().getAbsolutePath())){\n            return MEDIA_MOUNTED;\n        }\n        final int version = Build.VERSION.SDK_INT;\n        if (version >= 19) {\n            return Environment.getStorageState(path);\n        }\n\n        try {\n            final String canonicalPath = path.getCanonicalPath();\n            final String canonicalExternal = Environment.getExternalStorageDirectory()\n                    .getCanonicalPath();\n\n            if (canonicalPath.startsWith(canonicalExternal)) {\n                return Environment.getExternalStorageState();\n            }\n        } catch (IOException e) {\n        }\n\n        return MEDIA_UNKNOWN;\n    }\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/NClassLoader.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.startup;\n\nimport android.content.Context;\nimport java.io.File;\nimport java.io.IOException;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport dalvik.system.DexFile;\nimport dalvik.system.PathClassLoader;\n\n/**\n * Created by guanjie on 16/10/25.\n */\n\npublic class NClassLoader extends PathClassLoader{\n\n    public NClassLoader(String dexPath, String libraryPath, ClassLoader parent) {\n        super(dexPath, libraryPath, parent);\n    }\n\n    public NClassLoader(String dexPath, ClassLoader parent) {\n        super(dexPath, parent);\n    }\n\n    public static void replacePathClassLoader(Context base,ClassLoader original,NClassLoader target) throws Exception {\n        NClassLoader loader = target;\n        Field pathListField = findField(original, \"pathList\");\n        pathListField.setAccessible(true);\n        Object originPathListObject = pathListField.get(original);\n//\n        Field definingContextField = findField(originPathListObject, \"definingContext\");\n        definingContextField.set(originPathListObject, loader);\n\n        Field loadPathList = findField(loader, \"pathList\");\n        //just use PathClassloader's pathList\n        loadPathList.set(loader, originPathListObject);\n\n        List<File> additionalClassPathEntries = new ArrayList<File>();\n        Field dexElement = findField(originPathListObject, \"dexElements\");\n        Object[] originDexElements = (Object[]) dexElement.get(originPathListObject);\n        for (Object element : originDexElements) {\n            DexFile dexFile = (DexFile) findField(element, \"dexFile\").get(element);\n            additionalClassPathEntries.add(new File(dexFile.getName()));\n            //protect for java.lang.AssertionError: Failed to close dex file in finalizer.\n//            oldDexFiles.add(dexFile);\n        }\n        Method makePathElements = findMethod(originPathListObject, \"makePathElements\", List.class, File.class,\n                List.class);\n        ArrayList<IOException> suppressedExceptions = new ArrayList<IOException>();\n        Object[] newDexElements = (Object[]) makePathElements.invoke(originPathListObject, additionalClassPathEntries, null, suppressedExceptions);\n        dexElement.set(originPathListObject, newDexElements);\n\n        Field mPackageInfoField = base.getClass().getDeclaredField(\"mPackageInfo\");\n        mPackageInfoField.setAccessible(true);\n        Object loadedApk = mPackageInfoField.get(base);\n        Field classloaderField = loadedApk.getClass().getDeclaredField(\"mClassLoader\");\n        classloaderField.setAccessible(true);\n        classloaderField.set(loadedApk,loader);\n        Thread.currentThread().setContextClassLoader(loader);\n    }\n\n    public static Field findField(Object instance, String name) throws NoSuchFieldException {\n        for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {\n            try {\n                Field field = clazz.getDeclaredField(name);\n\n                if (!field.isAccessible()) {\n                    field.setAccessible(true);\n                }\n\n                return field;\n            } catch (NoSuchFieldException e) {\n                // ignore and search next\n            }\n        }\n\n        throw new NoSuchFieldException(\"Field \" + name + \" not found in \" + instance.getClass());\n    }\n\n    public static Method findMethod(Object instance, String name, Class<?>... parameterTypes)\n            throws NoSuchMethodException {\n        for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {\n            try {\n                Method method = clazz.getDeclaredMethod(name, parameterTypes);\n\n                if (!method.isAccessible()) {\n                    method.setAccessible(true);\n                }\n\n                return method;\n            } catch (NoSuchMethodException e) {\n                // ignore and search next\n            }\n        }\n\n        throw new NoSuchMethodException(\"Method \"\n                + name\n                + \" with parameters \"\n                + Arrays.asList(parameterTypes)\n                + \" not found in \" + instance.getClass());\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/patch/CombineDexMerger.java",
    "content": "package android.taobao.atlas.startup.patch;\n\nimport android.taobao.atlas.util.StringUtils;\n\nimport java.io.*;\nimport java.util.Enumeration;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\nimport java.util.zip.ZipOutputStream;\n\n/**\n * CombineDexMerger\n *\n * @author zhayu.ll\n * @date 18/5/10\n */\npublic class CombineDexMerger extends PatchMerger{\n\n\n    private static final int BUFFER_SIZE = 0x4000;\n\n    private static final String DEX_SUFFIX = \".dex\";\n\n    private static final String CLASS_SUFFIX = \"classes\";\n    public CombineDexMerger(PatchVerifier patchVerifier) {\n        super(patchVerifier);\n    }\n\n    @Override\n    public boolean merge(File sourceFile, File patchFile, File newFile) {\n        ZipOutputStream target = null;\n        ZipFile patchZip = null;\n        ZipFile rawZip = null;\n        try {\n             patchZip = new ZipFile(patchFile);\n             rawZip = new ZipFile(sourceFile);\n            boolean dexPatch = patchFile.getAbsolutePath().contains(\"dexpatch\");\n            target = new ZipOutputStream(new FileOutputStream(newFile));\n            int dexIndex = 1;\n\n            // first, copy source content\n            Enumeration<? extends ZipEntry> sourceEntries = patchZip.entries();\n            while (sourceEntries.hasMoreElements()) {\n                ZipEntry e = sourceEntries.nextElement();\n                //META-INF重复\n                if (dexPatch && e.getName().startsWith(\"META-INF\")) {\n                    continue;\n                }\n                ZipEntry out = new ZipEntry(e.getName());\n                target.putNextEntry(out);\n                if (!e.isDirectory()) {\n                    copy(patchZip.getInputStream(e), target);\n                }\n            }\n\n            if (!dexPatch || (dexPatch && KernalBundle.kernalBundle == null)) {\n                // second copy main dex from base.apk\n                do {\n                    ZipEntry entry = rawZip.getEntry(String.format(\"%s%s%s\", CLASS_SUFFIX, dexIndex > 1 ? dexIndex : \"\", DEX_SUFFIX));\n                    if (entry != null && !entry.isDirectory()) {\n                        ZipEntry targetEntry = new ZipEntry(getUpdatedDexEntryName(entry.getName()));\n                        target.putNextEntry(targetEntry);\n                        copy(rawZip.getInputStream(entry), target);\n                        dexIndex++;\n                    } else {\n                        return true;\n                    }\n                } while (true);\n            } else {\n                // second copy all from com.taobao.maindex.zip\n                Enumeration<? extends ZipEntry> rawEntries = rawZip.entries();\n                while (rawEntries.hasMoreElements()) {\n                    ZipEntry e = rawEntries.nextElement();\n                    ZipEntry out = e.getName().startsWith(CLASS_SUFFIX) && e.getName().endsWith(DEX_SUFFIX)\n                            ? new ZipEntry(getUpdatedDexEntryName(e.getName()))\n                            : new ZipEntry(e.getName());\n                    target.putNextEntry(out);\n                    if (!e.isDirectory()) {\n                        copy(rawZip.getInputStream(e), target);\n                    }\n                }\n                return true;\n            }\n\n        }catch (Exception e){\n            e.printStackTrace();\n\n        }finally {\n            try {\n                if (target != null) {\n                    target.closeEntry();\n                    target.close();\n                }\n                if (rawZip != null)\n                    rawZip.close();\n                if (patchZip != null){\n                    patchZip.close();\n                }\n                if (patchVerifier!= null && newFile.exists()){\n                    return patchVerifier.verify(newFile);\n                }\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n\n        }\n        return true;\n    }\n\n    private static String getUpdatedDexEntryName(String originalEntryName){\n        if(originalEntryName.equals(\"classes.dex\")){\n            return \"classes2.dex\";\n        }else{\n            int dexIndex = Integer.parseInt(StringUtils.substringBetween(originalEntryName,\"classes\",\".dex\"));\n            return String.format(\"classes%s.dex\",++dexIndex);\n        }\n    }\n\n    public static void copy(InputStream input, OutputStream output) throws IOException {\n        byte[] readContent = new byte[BUFFER_SIZE];\n        int bytesRead;\n        while ((bytesRead = input.read(readContent)) != -1) {\n            output.write(readContent, 0, bytesRead);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/patch/CombineDexVerifier.java",
    "content": "package android.taobao.atlas.startup.patch;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.zip.ZipFile;\n\n/**\n * CombineDexVerifier\n *\n * @author zhayu.ll\n * @date 18/5/10\n */\npublic class CombineDexVerifier implements PatchVerifier {\n\n    private static final String DEX_SUFFIX = \".dex\";\n\n    private static final String CLASS_SUFFIX = \"classes\";\n\n    @Override\n    public boolean verify(File mergeFile) {\n        if (mergeFile != null && mergeFile.exists()) {\n            if (!isNewBundleFileValid(mergeFile)) {\n                return false;\n            }else {\n                return true;\n            }\n        }\n            return false;\n    }\n\n    private static boolean isNewBundleFileValid(File bundleFile) {\n        boolean result;\n        ZipFile zipFile = null;\n        try {\n            zipFile = new ZipFile(bundleFile);\n            result = zipFile.getEntry(CLASS_SUFFIX + DEX_SUFFIX) != null && zipFile.getEntry(CLASS_SUFFIX + 2 + DEX_SUFFIX) != null;\n        } catch (Throwable e) {\n            return true;\n        }finally {\n            if (zipFile != null) {\n                try {\n                    zipFile.close();\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n            }\n        }\n        return result;\n}\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/patch/KernalBundle.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.startup.patch;\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.Closeable;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.lang.reflect.Array;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\nimport android.app.Application;\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.content.pm.ApplicationInfo;\nimport android.content.pm.PackageManager;\nimport android.os.Build;\nimport android.taobao.atlas.startup.KernalVersionManager;\nimport android.taobao.atlas.startup.NClassLoader;\nimport android.taobao.atlas.startup.patch.releaser.PatchDexProfile;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.widget.Toast;\nimport dalvik.system.DexFile;\nimport dalvik.system.PathClassLoader;\n\n/**\n * Created by guanjie on 15/6/4.\n */\npublic class KernalBundle {\n    /**\n     * the storage location.\n     */\n    File bundleDir;\n\n    /**\n     * the bundle archive file.\n     */\n    KernalBundleArchive archive;\n    private Class FrameworkPropertiesClazz;\n    private NClassLoader replaceClassLoader;\n\n    public static boolean nativeLibPatched;\n\n    static List <String>blackList = Arrays.asList(\n            \"/Plugin/\",\n            \"/virtual/\");\n\n    public static String KERNAL_BUNDLE_NAME = \"com.taobao.maindex\";\n\n    public static KernalBundle kernalBundle = null;\n    public static boolean patchWithApk = false;\n\n    public static boolean checkloadKernalBundle(Application application, String currentProcessName) {\n        File updateDir = null;\n        File dexPatchDir = null;\n        dexPatchDir = updateDir = new File(KernalConstants.baseContext.getFilesDir(), \"storage\");\n\n        if (!TextUtils.isEmpty(KernalVersionManager.instance().DEXPATCH_STORAGE_LOCATION)) {\n            dexPatchDir = new File(KernalVersionManager.instance().DEXPATCH_STORAGE_LOCATION);\n        }\n\n        if (!TextUtils.isEmpty(KernalVersionManager.instance().CURRENT_STORAGE_LOCATION)) {\n            updateDir = new File(KernalVersionManager.instance().CURRENT_STORAGE_LOCATION);\n        }\n\n        final File kernalUpdateDir = new File(updateDir, KERNAL_BUNDLE_NAME);\n        final File kernalDexPatchDir = new File(dexPatchDir, KERNAL_BUNDLE_NAME);\n\n        if (kernalUpdateDir.exists() || kernalDexPatchDir.exists()) {\n            try {\n                kernalBundle = new KernalBundle(kernalUpdateDir, kernalDexPatchDir, KernalVersionManager.instance().getBaseBundleVersion(KERNAL_BUNDLE_NAME), currentProcessName);\n                if (isInBlackList(kernalBundle)){\n                    throw new IOException(kernalBundle.getArchive().getArchiveFile().getAbsolutePath());\n                }\n                kernalBundle.patchKernalDex(application);\n//                kernalBundle.patchKernalResource(application);\n\n                return true;\n            } catch (Throwable e) {\n                e.printStackTrace();\n                kernalBundle = null;\n                deleteDirectory(kernalUpdateDir);\n                if (kernalDexPatchDir.exists()) {\n                    deleteDirectory(kernalDexPatchDir);\n                }\n                return false;\n            }\n        }\n        return false;\n    }\n\n    private static boolean isInBlackList(KernalBundle kernalBundle) {\n        if (kernalBundle!= null && kernalBundle.getArchive()!= null && kernalBundle.getArchive().getArchiveFile()!= null){\n            for (String s:blackList) {\n                if (kernalBundle.getArchive().getArchiveFile().getAbsolutePath().contains(s)){\n                    return true;\n                }\n            }\n        }\n        return false;\n\n    }\n\n    public static boolean checkLoadKernalDebugPatch(Application application) {\n        if (Build.VERSION.SDK_INT < 21) {\n            //暂时只支持art设备的debug调试\n            return false;\n        }\n\n        boolean loadKernalPatch = false;\n        try {\n            ApplicationInfo app_info = application.getApplicationInfo();\n            boolean debug = (app_info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;\n            if (debug) {\n                File debugBundleDir = new File(KernalConstants.baseContext.getExternalFilesDir(\"debug_storage\"), KERNAL_BUNDLE_NAME);\n                File patchFile = new File(debugBundleDir, \"patch.zip\");\n                if (patchFile.exists()) {\n                    loadKernalPatch = true;\n                    KernalBundle bundle = new KernalBundle();\n                    //DexFile dexFile = (DexFile) KernalConstants.dexBooster.loadDex(KernalConstants.baseContext, KernalConstants.baseContext.getApplicationInfo().sourceDir,\n                    //        new File(patchFile.getParent(), \"base.dex\").getAbsolutePath(), 0, true);\n\n                    File internalDebugBundleDir = new File(new File(application.getFilesDir(), \"debug_storage\"), KERNAL_BUNDLE_NAME);\n                    internalDebugBundleDir.mkdirs();\n                    DexFile patchDexFile = (DexFile) DexFile.loadDex(patchFile.getAbsolutePath(),new File(internalDebugBundleDir, \"patch.dex\").getAbsolutePath(), 0);\n                    if (bundle.needReplaceClassLoader(application)) {\n                        NClassLoader loader = new NClassLoader(\".\", KernalBundle.class.getClassLoader().getParent());\n                        try {\n                            NClassLoader.replacePathClassLoader(KernalConstants.baseContext, KernalBundle.class.getClassLoader(), loader);\n                        } catch (Exception e) {\n                            throw new RuntimeException(e);\n                        }\n                    }\n                    bundle.installKernalBundle(KernalConstants.baseContext.getClassLoader(), patchFile, new DexFile[]{patchDexFile/*, dexFile*/}, null,\n                        true /*(app_info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0*/);\n                    bundle.prepareRuntimeVariables(application);\n                    Class DelegateResourcesClazz = application.getClassLoader().loadClass(\"android.taobao.atlas.runtime.DelegateResources\");\n                    DelegateResourcesClazz.getDeclaredMethod(\"addApkpatchResources\", String.class)\n                            .invoke(DelegateResourcesClazz, patchFile.getAbsolutePath());\n                    Toast.makeText(KernalConstants.baseContext, \"当前处于DEBUG调试状态，不支持动态更新，清除数据可恢复\", Toast.LENGTH_LONG).show();\n                }\n            }\n        } finally {\n            return loadKernalPatch;\n        }\n    }\n\n    public static boolean hasKernalPatch() {\n        return KernalVersionManager.instance().isUpdated(KERNAL_BUNDLE_NAME) || KernalVersionManager.instance().isDexPatched(KERNAL_BUNDLE_NAME);\n    }\n\n\n    public static boolean hasNativeLibPatch(Context base) {\n        try {\n            return new File(base.getFilesDir(), String.format(\"nativeLib-%s\", base.getPackageManager().getPackageInfo(base.getPackageName(), 0).versionName)).exists()\n                    && new File(new File(base.getFilesDir(), String.format(\"nativeLib-%s\", base.getPackageManager().getPackageInfo(base.getPackageName(), 0).versionName)), \"mark\").exists();\n        } catch (PackageManager.NameNotFoundException e) {\n            e.printStackTrace();\n        }\n        return false;\n    }\n\n    public static void clear() {\n        File storageDir = new File(KernalConstants.baseContext.getFilesDir(), \"storage\");\n        final File kernalDir = new File(storageDir, KERNAL_BUNDLE_NAME);\n        if (kernalDir.exists()) {\n            deleteDirectory(kernalDir);\n        }\n    }\n\n    //DEBUG\n    private KernalBundle() {\n    }\n\n    //create\n    public KernalBundle(final File bundleDir,\n                        final File file, String version, long dexPatchVersion) throws Exception {\n        this.bundleDir = bundleDir;\n        try {\n            archive = new KernalBundleArchive(bundleDir, file, version, dexPatchVersion);\n        } catch (IOException e) {\n            e.printStackTrace();\n            if (bundleDir.exists()) {\n                deleteDirectory(bundleDir);\n            }\n            throw new IOException(\"install kernal Bundlele fail \", e);\n        }\n    }\n\n    //reload\n    public KernalBundle(final File updateDir, final File dexPatchDir, String version, String process) throws Exception {\n        long dexPatchVersion = KernalVersionManager.instance().getDexPatchBundleVersion(KERNAL_BUNDLE_NAME);\n        if (dexPatchVersion > 0) {\n            try {\n                bundleDir = dexPatchDir;\n                archive = new KernalBundleArchive(KernalConstants.baseContext, dexPatchDir, \"\", dexPatchVersion, process);\n            } catch (Throwable e) {\n                bundleDir = updateDir;\n                archive = new KernalBundleArchive(KernalConstants.baseContext, bundleDir, makeMainDexUniqueTag(KernalVersionManager.instance().currentVersionName(), version), dexPatchVersion, process);\n            }\n        } else {\n            bundleDir = updateDir;\n            archive = new KernalBundleArchive(KernalConstants.baseContext, bundleDir, makeMainDexUniqueTag(KernalVersionManager.instance().currentVersionName(), version), dexPatchVersion, process);\n        }\n    }\n\n    public static void patchNativeLib(Context base) {\n        try {\n            File dir = new File(base.getFilesDir(), String.format(\"nativeLib-%s\", base.getPackageManager().getPackageInfo(base.getPackageName(), 0).versionName));\n            ClassLoader loader = KernalBundle.class.getClassLoader();\n            Field pathListField = findField(loader, \"pathList\");\n            Object dexPathList = pathListField.get(loader);\n            patchLibrary(dexPathList, dir);\n            nativeLibPatched = true;\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n\n\n    }\n\n    private String makeMainDexUniqueTag(String appVersion, String maindexTag) {\n        if (maindexTag.startsWith(appVersion)) {\n            return maindexTag;\n        }\n        return appVersion + \"_\" + maindexTag;\n    }\n\n    public void  patchKernalDex(Application application) throws Exception {\n        DexFile[] dexFile = archive.getOdexFile();\n        if ((dexFile != null && dexFile.length > 0) || archive.getLibraryDirectory().exists()) {\n            boolean needReplaceClassLoader = needReplaceClassLoader(application);\n            boolean dexPatch = dexFile[dexFile.length - 1].getName().contains(KernalBundleArchive.DEXPATCH_DIR);\n            int newFrameworkPropertiesDexIndex;\n            if (dexPatch) {\n                    newFrameworkPropertiesDexIndex = 0;\n            } else {\n                newFrameworkPropertiesDexIndex = dexFile.length - 1;\n            }\n            //临时处理方案，需要替换为dexopt时传入classsLoader以兼容8.0\n            patchWithApk = dexPatch &&\n                    (TextUtils.isEmpty(KernalVersionManager.instance().currentVersionName()) || KernalVersionManager.instance().currentVersionName().equals(KernalConstants.INSTALLED_VERSIONNAME));\n            if (!needReplaceClassLoader) {\n                Log.e(\"KernalBundle\",\"no need replace Classloader!\");\n                FrameworkPropertiesClazz = archive.getOdexFile()[newFrameworkPropertiesDexIndex].loadClass(\"android.taobao.atlas.framework.FrameworkProperties\", application.getClassLoader());\n            } else if (patchWithApk) {\n                Log.e(\"KernalBundle\",\"need replace Classloader && patchWithApk!\");\n                replaceClassLoader = new NClassLoader(\".\", KernalBundle.class.getClassLoader().getParent());\n                if (needReplaceClassLoader) {\n                    try {\n                        NClassLoader.replacePathClassLoader(KernalConstants.baseContext, KernalBundle.class.getClassLoader(), replaceClassLoader);\n                    } catch (Exception e) {\n                        throw new RuntimeException(e);\n                    }\n                }\n                FrameworkPropertiesClazz = archive.getOdexFile()[newFrameworkPropertiesDexIndex].loadClass(\"android.taobao.atlas.framework.FrameworkProperties\", replaceClassLoader);\n\n            } else {\n                Log.e(\"KernalBundle\",\"need replace Classloader && load FrameworkPropertiesClazz to NclassLoader!\");\n                replaceClassLoader = new NClassLoader(\".\", KernalBundle.class.getClassLoader().getParent());\n                if (needReplaceClassLoader) {\n                    try {\n                        NClassLoader.replacePathClassLoader(KernalConstants.baseContext, KernalBundle.class.getClassLoader(), replaceClassLoader);\n                    } catch (Exception e) {\n                        throw new RuntimeException(e);\n                    }\n                }\n                FrameworkPropertiesClazz = archive.getOdexFile()[newFrameworkPropertiesDexIndex].loadClass(\"android.taobao.atlas.framework.FrameworkProperties\", replaceClassLoader);\n            }\n\n\n            //for mini sdk 21\n            if (FrameworkPropertiesClazz == null){\n                Log.e(\"KernalBundle\",\"FrameworkPropertiesClazz is null, load from source apk\");\n                FrameworkPropertiesClazz = Class.forName(\"android.taobao.atlas.framework.FrameworkProperties\");\n            }\n\n            if (FrameworkPropertiesClazz == null && isDeubgMode()) {\n                Log.e(\"KernalBundle\", \"main dex is not match, library awo test?\");\n                return;\n            }\n            Field versionField = FrameworkPropertiesClazz.getDeclaredField(\"version\");\n            versionField.setAccessible(true);\n            String version = (String) versionField.get(FrameworkPropertiesClazz.newInstance());\n            if (!KernalVersionManager.instance().currentVersionName().equals(version)) {\n                if (isDeubgMode()) {\n                    Log.e(\"KernalBundle\", \"main dex is not match, awo test?\");\n                } else {\n                    throw new RuntimeException(String.format(\"maindex version is not mismatch %s vs %s!\",KernalVersionManager.instance().currentVersionName(),version));\n                }\n            }\n\n            installKernalBundle(KernalConstants.baseContext.getClassLoader(), archive.getArchiveFile(), archive.getOdexFile(), archive.getLibraryDirectory());\n\n            prepareRuntimeVariables(application);\n\n            prepareKernalConstant(application);\n        }\n    }\n\n    private void prepareKernalConstant(Application application) {\n        try {\n            Class kernalConstantClass = application.getClassLoader().loadClass(\"android.taobao.atlas.startup.patch.KernalConstants\");\n            kernalConstantClass.getDeclaredField(\"APK_PATH\").set(null,application.getApplicationInfo().sourceDir);\n            kernalConstantClass.getDeclaredField(\"baseContext\").set(null,application.getBaseContext());\n        } catch (Exception e) {\n            throw new RuntimeException(e);\n        }\n\n    }\n\n    public boolean needReplaceClassLoader(Application application) {\n        if (Build.VERSION.SDK_INT >= 24) {\n            ClassLoader loader = getClass().getClassLoader();\n            boolean needReplace = false;\n            do {\n                if (loader.getClass().getName().equals(PathClassLoader.class.getName())) {\n                    needReplace = true;\n                    break;\n                }\n            } while ((loader = loader.getParent()) != null);\n            return needReplace;\n        } else {\n            return false;\n        }\n    }\n\n    public void prepareRuntimeVariables(Application application) {\n        try {\n            Class RuntimeVariablesClass = application.getClassLoader().loadClass(\"android.taobao.atlas.runtime.RuntimeVariables\");\n            RuntimeVariablesClass.getDeclaredField(\"sRawClassLoader\").set(RuntimeVariablesClass, KernalBundle.class.getClassLoader());\n            if (FrameworkPropertiesClazz != null) {\n                RuntimeVariablesClass.getDeclaredField(\"FrameworkPropertiesClazz\").set(RuntimeVariablesClass, FrameworkPropertiesClazz);\n            } else if (!isDeubgMode()) {\n                throw new RuntimeException(\"FrameworkPropertiesClazz find error,will be rollback!\");\n            }\n            RuntimeVariablesClass.getDeclaredField(\"sCurrentProcessName\").set(RuntimeVariablesClass, KernalConstants.PROCESS);\n            RuntimeVariablesClass.getDeclaredField(\"androidApplication\").set(RuntimeVariablesClass, application);\n            RuntimeVariablesClass.getDeclaredField(\"delegateResources\").set(RuntimeVariablesClass, KernalConstants.baseContext.getResources());\n\n        } catch (Throwable e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    /**\n     * 主dex动态资源部署\n     * See {@link android.taobao.atlas.runtime.DelegateResources#addApkpatchResources}\n     *\n     * @param application\n     * @throws Exception\n     */\n    public void patchKernalResource(Application application) throws Exception {\n        if (!patchWithApk) {\n            Class DelegateResourcesClazz = application.getClassLoader().loadClass(\"android.taobao.atlas.runtime.DelegateResources\");\n            DelegateResourcesClazz.getDeclaredMethod(\"addApkpatchResources\", String.class)\n                    .invoke(DelegateResourcesClazz, archive.getArchiveFile().getAbsolutePath());\n        }\n    }\n\n    public int getState() {\n        return 0;\n    }\n\n    /**\n     * 安装so库\n     */\n    private static void extract(String zipPath, String entryPath, File targetPath) {\n        ZipFile zip = null;\n        try {\n            zip = new ZipFile(new File(zipPath));\n            ZipEntry entry = zip.getEntry(entryPath);\n            BufferedOutputStream bos = new BufferedOutputStream(\n                    new FileOutputStream(targetPath));\n            BufferedInputStream bi = new BufferedInputStream(zip.getInputStream(entry));\n            byte[] readContent = new byte[600];\n            int readCount = bi.read(readContent);\n            while (readCount != -1) {\n                bos.write(readContent, 0, readCount);\n                readCount = bi.read(readContent);\n            }\n            bos.close();\n        } catch (final Exception e) {\n            e.printStackTrace();\n        } finally {\n            try {\n                if (zip != null) {\n                    zip.close();\n                }\n            } catch (Throwable e) {\n            }\n        }\n    }\n\n    /**\n     * Locates a given field anywhere in the class inheritance hierarchy.\n     *\n     * @param instance an object to search the field into.\n     * @param name     field name\n     * @return a field object\n     * @throws NoSuchFieldException if the field cannot be located\n     */\n    private static Field findField(Object instance, String name) throws NoSuchFieldException {\n        for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {\n            try {\n                Field field = clazz.getDeclaredField(name);\n\n\n                if (!field.isAccessible()) {\n                    field.setAccessible(true);\n                }\n\n                return field;\n            } catch (NoSuchFieldException e) {\n                // ignore and search next\n            }\n        }\n\n        throw new NoSuchFieldException(\"Field \" + name + \" not found in \" + instance.getClass());\n    }\n\n\n    /**\n     * Replace the value of a field containing a non null array, by a new array containing the\n     * elements of the original array plus the elements of extraElements.\n     *\n     * @param instance     the instance whose field is to be modified.\n     * @param fieldName    the field to modify.\n     * @param extraElement element to append at the end of the array.\n     */\n    private static void expandFieldArray(Object instance, String fieldName,\n                                         Object[] extraElement) throws NoSuchFieldException, IllegalArgumentException,\n            IllegalAccessException {\n        Field jlrField = findField(instance, fieldName);\n        Object[] original = (Object[]) jlrField.get(instance);\n        Object[] combined = (Object[]) Array.newInstance(\n                original.getClass().getComponentType(), original.length + extraElement.length);\n        for (int i = 0; i < extraElement.length; i++) {\n            combined[i] = extraElement[i];\n        }\n        System.arraycopy(original, 0, combined, extraElement.length, original.length);\n        jlrField.set(instance, combined);\n    }\n\n    private static void expandFieldList(Object instance, String fieldName,\n                                        Object extraElement) throws NoSuchFieldException, IllegalArgumentException,\n            IllegalAccessException {\n        Field jlrField = findField(instance, fieldName);\n        List original = (List) jlrField.get(instance);\n        original.add(0, extraElement);\n    }\n\n    private static boolean replaceElement(Object instance, String fieldName, Object[] replaceElement) throws NoSuchFieldException, IllegalArgumentException,\n            IllegalAccessException {\n        boolean replaceSuccess = false;\n        Field jlrField = findField(instance, fieldName);\n        Object[] original = (Object[]) jlrField.get(instance);\n        for (int x = 0; x < original.length; x++) {\n            Object element = original[x];\n            File apkFile = findDexRawFile(element);\n            if (apkFile != null) {\n                if (apkFile.getAbsolutePath() != null && apkFile.getAbsolutePath().contains(KernalConstants.baseContext.getPackageName())) {\n                    original[x] = replaceElement;\n                    replaceSuccess = true;\n                    break;\n                }\n            }\n        }\n        return replaceSuccess;\n\n    }\n\n    private static File findDexRawFile(Object element) {\n        Field field = null;\n        File dexRawFile = null;\n        if (Build.VERSION.SDK_INT >= 25) {\n            try {\n                field = element.getClass().getDeclaredField(\"path\");\n                field.setAccessible(true);\n                dexRawFile = (File) field.get(element);\n                return dexRawFile;\n            } catch (Throwable e) {\n            }\n        }\n        try {\n            field = element.getClass().getDeclaredField(\"file\");\n            field.setAccessible(true);\n            dexRawFile = (File) field.get(element);\n        } catch (Throwable e) {\n        }\n\n        if (field == null) {\n            try {\n                field = element.getClass().getDeclaredField(\"zip\");\n                field.setAccessible(true);\n                dexRawFile = (File) field.get(element);\n            } catch (Throwable e) {\n            }\n        }\n        return dexRawFile;\n    }\n\n    public boolean installKernalBundle(ClassLoader updateClassLoader, File archiveFile, DexFile[] odexFiles, File libraryDirectory) throws IOException, NoSuchFieldException, IllegalAccessException {\n        return installKernalBundle(updateClassLoader, archiveFile, odexFiles, libraryDirectory, false);\n    }\n\n\n    public boolean installKernalBundle(ClassLoader updateClassLoader, File archiveFile, DexFile[] odexFiles, File libraryDirectory, boolean vmSafeMode) throws IOException, NoSuchFieldException, IllegalAccessException {\n        Object[] element = null;\n        boolean success = false;\n        try {\n            ClassLoader loader = updateClassLoader;\n            Field pathListField = findField(loader, \"pathList\");\n            Object dexPathList = pathListField.get(loader);\n            if (odexFiles != null) {\n                element = makeDexElement(archiveFile, odexFiles);\n                if (element == null || element.length == 0) {\n                    throw new IOException(\"makeDexElement failed\");\n                }\n\n                //增加kernal bundle\n               expandFieldArray(dexPathList, \"dexElements\", element);\n//                if (Build.VERSION.SDK_INT > 20 && !vmSafeMode) {\n//                     success = removeOrignalElement(dexPathList, \"dexElements\");\n//                    if(!success){\n//                        throw new IOException(\"replaceElement failed\");\n//                    }\n//                } else {\n////                    expandFieldArray(dexPathList, \"dexElements\", element);\n//                }\n            }\n            //增加kernal bundle library\n\n            patchLibrary(dexPathList, libraryDirectory);\n\n            return true;\n        } catch (Exception e) {\n            throw new IOException(\"install kernal fail\", e);\n        }\n\n    }\n\n    private boolean removeOrignalElement(Object instance, String fieldName) throws NoSuchFieldException, IllegalAccessException {\n        Field jlrField = findField(instance, fieldName);\n        Object[] original = (Object[]) jlrField.get(instance);\n        for (int x = 0; x < original.length; x++) {\n            Object element = original[x];\n            Field dexFileField = element.getClass().getDeclaredField(\"dexFile\");\n            dexFileField.setAccessible(true);\n            File apkFile = findDexRawFile(element);\n            if (apkFile != null) {\n                if (apkFile.getAbsolutePath() != null && apkFile.getAbsolutePath().contains(KernalConstants.baseContext.getPackageName())) {\n                    dexFileField.set(element,null);\n                    break;\n                }\n            }\n        }\n        return true;\n    }\n\n    private static void patchLibrary(Object dexPathList, File libraryDirectory) throws NoSuchFieldException, IllegalAccessException, IOException {\n        if (libraryDirectory != null && !TextUtils.isEmpty(libraryDirectory.getAbsolutePath()) && libraryDirectory.exists()) {\n            if (Build.VERSION.SDK_INT < 23) {\n                expandFieldArray(dexPathList, \"nativeLibraryDirectories\", new Object[]{libraryDirectory});\n            } else {\n                expandFieldList(dexPathList, \"nativeLibraryDirectories\", libraryDirectory);\n            }\n\n            if (Build.VERSION.SDK_INT >= 23) {\n                Object nativeLibraryElement = makeNativeLibraryElement(libraryDirectory);\n                expandFieldArray(dexPathList, \"nativeLibraryPathElements\", new Object[]{nativeLibraryElement});\n            }\n        }\n    }\n\n    private void quietClose(Closeable closeable) {\n        try {\n            if (closeable != null) {\n                closeable.close();\n            }\n        } catch (Throwable e) {\n\n        }\n    }\n\n\n    static Class[] constructorArgs3 = {File.class, ZipFile.class, DexFile.class};\n    static Class[] constructorArgs2 = {File.class, File.class, DexFile.class};\n    static Class[] constructorArgs1 = {File.class, boolean.class, File.class, DexFile.class};\n\n    static Class[] constructorArgsO = {DexFile.class, File.class};\n\n\n    public static Object[] makeDexElement(File file, DexFile[] dex) throws Exception {\n        Object[] objects = new Object[dex.length];\n        for (int i = 0; i < dex.length; i++) {\n            try {\n                Class Element = Class.forName(\"dalvik.system.DexPathList$Element\");\n                if (Build.VERSION.SDK_INT > 25 || Build.VERSION.SDK_INT == 25 && Build.VERSION.PREVIEW_SDK_INT > 0) {\n                    Constructor cons = getElementConstructor(Element, constructorArgsO);\n                    objects[i] = cons.newInstance(dex[i], file);\n                } else {\n                    File apkFile = new File(KernalConstants.baseContext.getApplicationInfo().sourceDir);\n                    Constructor cons = getElementConstructor(Element, constructorArgs1);\n                    if (cons != null) {\n                        objects[i] = cons.newInstance(apkFile, false, apkFile, dex[i]);\n                    } else {\n                        cons = getElementConstructor(Element, constructorArgs2);\n                        if (cons != null) {\n                            objects[i] = cons.newInstance(apkFile, apkFile, dex[i]);\n                        } else {\n                            cons = getElementConstructor(Element, constructorArgs3);\n                            if (cons != null) {\n                                objects[i] = cons.newInstance(apkFile, null, dex[i]);\n                            }\n                        }\n                    }\n                }\n            } catch (Exception e) {\n                throw new RuntimeException(\"make DexElement fail\", e);\n            }\n        }\n        return objects;\n    }\n\n\n    // for api level >=23\n    public static Object makeNativeLibraryElement(File dir) throws IOException {\n        if (Build.VERSION.SDK_INT > 25 || Build.VERSION.SDK_INT == 25 && Build.VERSION.PREVIEW_SDK_INT > 0) {\n            try {\n                Class NativeLibraryElement = Class.forName(\"dalvik.system.DexPathList$NativeLibraryElement\");\n                Class[] oconstructorArgs = {File.class};\n                Constructor constructor = NativeLibraryElement.getDeclaredConstructor(oconstructorArgs);\n                constructor.setAccessible(true);\n                return constructor.newInstance(dir);\n            } catch (Exception e) {\n                throw new IOException(\"make nativeElement fail\", e);\n            }\n        } else {\n            try {\n                Class Element = Class.forName(\"dalvik.system.DexPathList$Element\");\n                Constructor cons = getElementConstructor(Element, constructorArgs1);\n                if (cons != null) {\n                    return cons.newInstance(dir, true, null, null);\n                } else {\n                    throw new IOException(\"make nativeElement fail | error constructor\");\n                }\n            } catch (Exception e) {\n                throw new IOException(\"make nativeElement fail\", e);\n            }\n        }\n    }\n\n    private static Constructor getElementConstructor(Class element, Class... args) {\n        try {\n            return element.getDeclaredConstructor(args);\n        } catch (Throwable e) {\n            Log.w(\"KernalBundleImpl\", \"can not create element by args\" + args);\n        }\n        return null;\n    }\n\n    public KernalBundleArchive getArchive() {\n        return archive;\n    }\n\n    public File getRevisionDir() {\n        return getArchive().getRevisionDir();\n    }\n\n    public File getRevisionZip() {\n        return getArchive().getArchiveFile();\n    }\n\n    public static boolean shouldSyncUpdateInThisProcess(String process) {\n        String processName = process;\n        if (processName != null &&\n                (processName.equals(KernalConstants.baseContext.getPackageName()) ||\n                        processName.toLowerCase().contains(\":safemode\")\n                )) {\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    public static void deleteDirectory(final File path) {\n        final File[] files = path.listFiles();\n        if (files == null) {\n            return;\n        }\n        for (int i = 0; i < files.length; i++) {\n            if (files[i].isDirectory()) {\n                deleteDirectory(files[i]);\n            } else {\n                files[i].delete();\n            }\n        }\n        path.delete();\n    }\n\n    public boolean isDeubgMode() {\n        try {\n            /**\n             * enable patch debug if in debug mode\n             */\n            final ApplicationInfo app_info = KernalConstants.baseContext.getApplicationInfo();\n            boolean DEBUG = (app_info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;\n            if (DEBUG) {\n                return true;\n            }\n            SharedPreferences sharedPreferences = KernalConstants.baseContext.getSharedPreferences(\"dynamic_test\", Context.MODE_PRIVATE);\n            boolean dynamic_test_flag = sharedPreferences.getBoolean(\"dynamic_test_key\", false);\n            if (dynamic_test_flag) {\n                return true;\n            }\n        } catch (final Exception e) {\n            return false;\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/patch/KernalBundleArchive.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.startup.patch;\n\nimport android.content.Context;\nimport android.os.Looper;\nimport android.taobao.atlas.startup.patch.releaser.BundleReleaser;\nimport android.text.TextUtils;\nimport dalvik.system.DexFile;\nimport java.io.*;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.FileChannel;\nimport java.util.zip.ZipFile;\n\n/**\n * Created by guanjie on 15/6/4.\n */\n class KernalBundleArchive {\n\n    public static final String TAG = \"KernalBundleArchive\";\n    private static final String BUNDLE_NAME = \"com_taobao_maindex.zip\";\n    public final static String DEXPATCH_DIR = \"dexpatch/\";\n    /**\n     * Size of reading buffers.\n     */\n    private static final int BUFFER_SIZE = 0x4000;\n    private File bundleDir;\n    /**\n     * the bundle revision file location.\n     */\n    private File   revisionDir;\n    private File   libraryDirectory;\n    private DexFile[] odexFile;\n    private boolean hasResources = false;\n    private Context mContext;\n\n    //reload\n    public KernalBundleArchive(Context context, File bundleDir,String version,long dexPatchVersion,String process) throws IOException {\n        mContext = context;\n        this.bundleDir = bundleDir;\n        if(process.equals(KernalConstants.baseContext.getPackageName())) {\n            purge(version, dexPatchVersion);\n        }\n        if(dexPatchVersion>0){\n            revisionDir = new File(bundleDir,DEXPATCH_DIR+dexPatchVersion);\n        }else {\n            revisionDir = new File(bundleDir, version);\n        }\n        if (revisionDir==null || !revisionDir.exists()) {\n            throw new IOException(\"can not find kernal bundle\");\n        }\n        libraryDirectory = new File(mappingInternalDirectory(),\"lib\");\n        File bundleFile = new File(revisionDir, BUNDLE_NAME);\n        boolean success = new KernalBundleRelease(revisionDir,true).release(bundleFile,true);\n        if (!success||odexFile == null){\n            throw new IOException(\"process patch failed!\");\n        }\n    }\n\n    //create\n    public KernalBundleArchive(final File bundleDir, File file,String version,long dexPatchVersion) throws IOException {\n        this.bundleDir = bundleDir;\n        if(dexPatchVersion>0) {\n            revisionDir = new File(bundleDir, DEXPATCH_DIR+dexPatchVersion);\n        }else{\n            revisionDir = new File(bundleDir, version);\n        }\n        if (!revisionDir.exists()) {\n            revisionDir.mkdirs();\n        }\n        File bundleFile = new File(revisionDir, BUNDLE_NAME);\n        if (!file.renameTo(bundleFile)) {\n            copyInputStreamToFile(new FileInputStream(file), bundleFile);\n        }\n        ZipFile zip = new ZipFile(bundleFile);\n        hasResources = false;\n\n        if (zip.getEntry(\"resources.arsc\") != null || new File(revisionDir, \"newAssets/assets\").exists()) {\n            hasResources = true;\n        }\n        zip.close();\n        libraryDirectory = new File(mappingInternalDirectory(), \"lib\");\n        boolean success = new KernalBundleRelease(revisionDir,false).release(bundleFile,false);\n        if (!success||odexFile == null){\n            throw new IOException(\"process mainDex failed!\");\n        }\n    }\n\n    /**\n     * This method removes all old revisions associated with the archive and keeps only the current revision.\n     **/\n    public void purge(String uniqueTag, final long dexPatchVersion) {\n        // remove old dexpatch\n        try {\n            File dexPatchDir = new File(bundleDir, DEXPATCH_DIR);\n            File[] dexPatchs = dexPatchDir.listFiles(new FilenameFilter() {\n                @Override\n                public boolean accept(File dir, String filename) {\n                    if (dexPatchVersion > 0 && filename.equals(dexPatchVersion + \"\")) {\n                        return false;\n                    } else {\n                        return true;\n                    }\n                }\n            });\n            if (dexPatchs != null) {\n                for (File patch : dexPatchs) {\n                    if(patch.isDirectory()) {\n                        deleteDirectory(patch);\n                    }\n                }\n            }\n\n            // remove old update version\n            File[] dirs = bundleDir.listFiles();\n            for (File dir : dirs) {\n                if (dir.isDirectory() && !dir.getName().contains(\"dexpatch\") && !dir.getName().equals(uniqueTag)) {\n                    deleteDirectory(dir);\n                }\n            }\n        }catch(Throwable e){\n            e.printStackTrace();\n        }\n    }\n\n\n\n    /**\n     * copy input to output stream - available in several StreamUtils or Streams classes\n     */\n    public static void copy(InputStream input, OutputStream output) throws IOException {\n        byte[] readContent = new byte[BUFFER_SIZE];\n        int bytesRead;\n        while ((bytesRead = input.read(readContent)) != -1) {\n            output.write(readContent, 0, bytesRead);\n        }\n    }\n\n\n    public File getLibraryDirectory(){\n        return libraryDirectory;\n    }\n\n    public DexFile[] getOdexFile(){\n        return odexFile;\n    }\n\n    public File getArchiveFile(){\n        return new File(revisionDir,BUNDLE_NAME);\n    }\n\n    public File getRevisionDir(){\n        return revisionDir;\n    }\n\n    public static void deleteDirectory(final File path) {\n        final File[] files = path.listFiles();\n        if (files == null){\n            return;\n        }\n        for (int i = 0; i < files.length; i++) {\n            if (files[i].isDirectory()) {\n                deleteDirectory(files[i]);\n            } else {\n                files[i].delete();\n            }\n        }\n        path.delete();\n    }\n\n    public static String substringAfter(String str, String separator) {\n        if (TextUtils.isEmpty(str)) {\n            return str;\n        }\n        if (separator == null) {\n            return \"\";\n        }\n        int pos = str.indexOf(separator);\n        if (pos == -1) {\n            return \"\";\n        }\n        return str.substring(pos + separator.length());\n    }\n\n    public static void copyInputStreamToFile(InputStream input, File file) throws IOException {\n        FileOutputStream os = null;\n        FileChannel channel = null;\n        try {\n            // copy 文件\n            os = new FileOutputStream(file);\n            channel = os.getChannel();\n            byte[] buffers = new byte[1024];\n            int realLength;\n            while ((realLength = input.read(buffers)) > 0) {\n                channel.write(ByteBuffer.wrap(buffers, 0, realLength));\n            }\n        } finally {\n            if (input != null) try {\n                input.close();\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n            if (channel != null) try {\n                channel.close();\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n            if (os != null) try {\n                os.close();\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n        }\n    }\n\n    private File mappingInternalDirectory(){\n        if(!revisionDir.getAbsolutePath().startsWith(KernalConstants.baseContext.getFilesDir().getAbsolutePath())){\n            File internalLibDir = new File(KernalConstants.baseContext.getFilesDir(),String.format(\"storage/com.taobao.maindex_internal/%s\",revisionDir.getName()));\n            return internalLibDir;\n        }else{\n            return revisionDir;\n        }\n    }\n\n    /**\n     * 写这个类而不用匿名内部类的原因：\n     * 如果之前发生过动态部署，则再次进行update的时候饮用的第二个内部类与Archive不同于同一个dex，会引发PRE_VERIFY\n     */\n    public class KernalBundleRelease{\n        private BundleReleaser mBundlereleaser;\n        public KernalBundleRelease(File dir,boolean hasReleasedBefore) {\n            mBundlereleaser = new BundleReleaser(dir,hasReleasedBefore);\n        }\n\n        public boolean release(final File bundleFile,final boolean start) throws IOException{\n            final Boolean[] success = {true};\n            mBundlereleaser.release(new BundleReleaser.ProcessCallBack() {\n                @Override\n                public void onFailed() throws IOException {\n                    success[0] = false;\n                    odexFile = null;\n                    mBundlereleaser.close();\n\n                }\n\n                @Override\n                public void onFinish(int event) {\n                    if (event == BundleReleaser.MSG_ID_DEX_OPT_DONE){\n                        odexFile = mBundlereleaser.getDexFile();\n                    }\n                }\n\n                @Override\n                public void onAllFinish() {\n                    mBundlereleaser.close();\n                }\n            },bundleFile,start);\n            if(Thread.currentThread().getId()!=Looper.getMainLooper().getThread().getId()) {\n                Looper.loop();\n            }\n            return success[0];\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/patch/KernalConstants.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.startup.patch;\n\nimport android.content.Context;\n\n/**\n * Created by guanjie on 2017/1/19.\n */\n\npublic class KernalConstants {\n\n    public static  String  PROCESS;\n    public static  String  APK_PATH;\n    public static  String  INSTALLED_VERSIONNAME;\n    public static  long INSTALLED_VERSIONCODE;\n    public static  long LASTUPDATETIME;\n    public static  Context baseContext;\n    public static  String  RAW_APPLICATION_NAME;\n\n    public static final String ATLAS_MONITOR = \"Atlas_monitor\";\n\n    //动态部署稳定性stage\n//    public static final String DD_BASELINEINFO_FAIL = \"dd_baselineinfo_fail\";\n//\n//    public static final String DD_INSTALL_DEXOPT_FAIL = \"dd_install_dexopt_fail\";\n//    public static final String DD_INSTALL_NATIVE_SO_UZIP_FAIL = \"dd_install_native_os_uzip_fail\";\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/patch/KernalFileLock.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.startup.patch;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\nimport java.nio.channels.FileChannel;\nimport java.nio.channels.FileLock;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class KernalFileLock {\n\n    private static KernalFileLock singleton;\n    \n    public static KernalFileLock getInstance(){\n    \tif (singleton == null){\n    \t\tsingleton = new KernalFileLock();\n    \t}\n\t\treturn singleton;\n    }\n    \n\tprivate class FileLockCount{\n    \tRandomAccessFile fOs;\n    \tFileChannel fChannel;\n\t\tFileLock mFileLock;\n\t\tint mRefCount;\n\t\t\n\t\tFileLockCount(FileLock mFileLock, int mRefCount, RandomAccessFile fOs, FileChannel fChannel){\n\t\t\tthis.mFileLock = mFileLock;\n\t\t\tthis.mRefCount = mRefCount;\n\t\t\tthis.fOs = fOs;\n\t\t\tthis.fChannel = fChannel;\n\t\t}\n\t}\n\t\n\t/*\n\t * The FileLock is interesting, 1st not suitable for intraprocess\n\t * i.e., once the current process already hold the lock, another\n\t * thread's aquirement would be always success.\n\t * 2nd is that FileLock has no reference count, i.e., Once both\n\t * threads hold the lock, any thread release that would totally\n\t * release the FileLock.\n\t * To resolve the 1st issue, we used BundleLock.\n\t * To resolve the 2nd issue, we need add ref count ourselves.\n\t */\n\tprivate Map<String, FileLockCount> mRefCountMap = new ConcurrentHashMap<String, FileLockCount>();\n\n\t/*\n\t * Refcnt increment\n\t * return the ref count of current file's filelock\n\t */\t\n\tprivate int RefCntInc(String name, FileLock fileLock, RandomAccessFile fOs, FileChannel fChannel){\n\t\tInteger val = 0;\n\t\t\n\t\tif (mRefCountMap.containsKey(name)){\n\t\t\tval = mRefCountMap.get(name).mRefCount++;\n\t\t} else {\n\t\t\tval = 1;\n\t\t\tFileLockCount newFileLockCount = new FileLockCount(fileLock, val, fOs, fChannel);\n\t\t\tmRefCountMap.put(name, newFileLockCount);\n\t\t}\n\n\t\treturn val;\n\t}\n\t\n\t/*\n\t * Refcnt decrement\n\t * return the ref count of current file's filelock\n\t */\n\tprivate int RefCntDec(String name){\n\t\tInteger val = 0;\n\t\t\n\t\tif (mRefCountMap.containsKey(name)){\n\t\t\tval = --mRefCountMap.get(name).mRefCount;\n\t\t\t/*\n\t\t\t * Remove the item once value is already 0\n\t\t\t */\n\t\t\tif (val <= 0){\n\t\t\t\tmRefCountMap.remove(name);\n\t\t\t}\t\t\t\n\t\t}\n\t\t\n\t\treturn val;\n\t}\n\t\n    /*\n     * Hold a exclusive lock, file is the directory\n     */\n\tpublic boolean LockExclusive(File orgFile) {  \n    \tRandomAccessFile fOs = null;\n    \tFileChannel fChannel = null;\n        try {\n        \tif (orgFile == null){\n        \t\treturn false;\n        \t}\n        \t\n        \tFile file ;\n\t\t\tif(orgFile.exists() && orgFile.isDirectory()){\n\t\t\t\tfile = new File(orgFile.getAbsolutePath().concat(\"/lock\"));\n\t\t\t}else{\n\t\t\t\tfile = new File(orgFile.getParentFile().getAbsolutePath().concat(\"/lock\"));\n\t\t\t}\n        \tif (file.exists() != true){\n        \t\tfile.createNewFile();\n        \t}\n        \t\n        \tfOs = new RandomAccessFile(file.getAbsolutePath(), \"rw\");\n        \tfChannel = fOs.getChannel();\n        \t\n        \tFileLock fFileLock = fChannel.lock();\n            if(fFileLock.isValid()) {  \n            \tRefCntInc(file.getAbsolutePath(), fFileLock, fOs, fChannel);\n                return true;  \n            }          \t\n        }catch (Exception e) {  \n            e.printStackTrace();\n         }\n\t\treturn false;  \n    }  \n      \n    \n\t/*\n\t * Free file lock, do remember to invoke it once caught exception\n\t */        \n    public void unLock(File orgFile) {\n\n\t\tFile file ;\n\t\tif(orgFile.exists() && orgFile.isDirectory()){\n\t\t\tfile = new File(orgFile.getAbsolutePath().concat(\"/lock\"));\n\t\t}else{\n\t\t\tfile = new File(orgFile.getParentFile().getAbsolutePath().concat(\"/lock\"));\n\t\t}\n\n\t\tif (file.exists() == false){\n    \t\treturn;\n    \t}\n    \t\n    \tif ((file != null) && !mRefCountMap.containsKey(file.getAbsolutePath())){\n    \t\treturn;\n    \t}\n    \t\n    \tFileLockCount flc = mRefCountMap.get(file.getAbsolutePath());\n    \tif (flc == null){\n    \t\treturn;\n    \t}\n    \t\n    \tFileLock fl = flc.mFileLock;\n    \tRandomAccessFile fOs = flc.fOs;\n    \tFileChannel fChannel = flc.fChannel;\n    \t\n        try {\n        \tif (RefCntDec(file.getAbsolutePath()) <= 0){\n        \t\tif (fl != null && fl.isValid()){\n        \t\t\tfl.release();  \n        \t\t}\n        \t\tif (fOs != null){\n        \t\t\tfOs.close();\n        \t\t}\n        \t\tif (fChannel != null){\n        \t\t\tfChannel.close();\n        \t\t}\n        \t}\n        } catch (IOException e) {  \n        \t e.printStackTrace();\n        }  \n    }\n\n    \n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/patch/PatchMerger.java",
    "content": "package android.taobao.atlas.startup.patch;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.*;\n\n/**\n * PatchMerger\n *\n * @author zhayu.ll\n * @date 18/5/10\n */\npublic abstract class PatchMerger {\n\n    protected PatchVerifier patchVerifier;\n\n    protected ExecutorService service = null;\n\n    protected List<Future<Boolean>> futures = new ArrayList<>();\n\n    public PatchMerger(PatchVerifier patchVerifier) {\n        this.patchVerifier = patchVerifier;\n        service = Executors.newFixedThreadPool(3);\n    }\n\n    public abstract boolean merge(File sourceFile, File patchFile, File newFile);\n\n    public void sumitForMerge(final File sourceFile, final File patchFile, final File newFile){\n\n        Future <Boolean>future = service.submit(new Callable<Boolean>() {\n            @Override\n            public Boolean call() throws Exception {\n\n                return merge(sourceFile,patchFile,newFile);\n            }\n        });\n        futures.add(future);\n    }\n\n    public boolean waitForResult(){\n        for (Future future:futures){\n            try {\n                Boolean flag = (Boolean) future.get(5000,TimeUnit.SECONDS);\n                if (!flag){\n                    return false;\n                }\n            } catch (Throwable e){\n                e.printStackTrace();\n                return false;\n            }\n        }\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/patch/PatchVerifier.java",
    "content": "package android.taobao.atlas.startup.patch;\n\nimport java.io.File;\n\n/**\n * PatchVerifier\n *\n * @author zhayu.ll\n * @date 18/5/10\n */\npublic interface PatchVerifier {\n\n\n    public boolean verify(File mergeFile);\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/patch/releaser/BundleReleaser.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.startup.patch.releaser;\n\n/**\n * Created by lilong on 16/12/21.\n */\nimport android.os.Build;\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.os.Message;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.taobao.atlas.startup.DexFileCompat;\nimport android.taobao.atlas.startup.patch.KernalConstants;\nimport android.util.Log;\nimport java.io.File;\nimport java.io.FilenameFilter;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.lang.reflect.Method;\nimport java.util.*;\nimport java.util.Enumeration;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.Executor;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport dalvik.system.DexFile;\n\npublic class BundleReleaser {\n    private static final int MSG_ID_DEX_RELEASE_DONE = 1;\n    public static final int MSG_ID_DEX_OPT_DONE = 2;\n    private static final int MSG_ID_RESOURCE_RELEASE_DONE = 3;\n    private static final int MSG_ID_SOLIB_RELEASE_DONE = 4;\n    private static final int MSG_ID_RELEASE_DONE = 5;\n    private static final int MSG_ID_RELEASE_FAILED = 6;\n\n    private static final String TAG = BundleReleaser.class.getSimpleName();\n    private static final String DEX_SUFFIX = \".dex\";\n    private boolean isReleasing = false;\n    private ExecutorService service;\n    private File reversionDir;\n    private Handler handler;\n    private ProcessCallBack processCallBack;\n    private File apkFile;\n    private boolean hasReleased;\n    private boolean externalStorage = false;\n\n    public DexFile[] getDexFile() {\n        return dexFiles;\n    }\n\n    private DexFile[] dexFiles = null;\n\n    public BundleReleaser(final File reversionDir,boolean hasReleased) {\n\n        this.hasReleased = hasReleased;\n        this.reversionDir = reversionDir;\n        if(!reversionDir.getAbsolutePath().startsWith(KernalConstants.baseContext.getFilesDir().getAbsolutePath())){\n            externalStorage = true;\n        }\n        if (!(Looper.getMainLooper() == Looper.myLooper())) {\n            if (Looper.myLooper() == null)\n                Looper.prepare();\n        }\n        handler = new Handler(new Handler.Callback() {\n            @Override\n            public boolean handleMessage(Message msg) {\n                try {\n                    return handleMsg(msg);\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n                return false;\n            }\n        });\n\n        this.service = Executors.newFixedThreadPool(3);\n    }\n\n    private boolean handleMsg(Message msg) throws IOException {\n        switch (msg.what) {\n            case MSG_ID_DEX_OPT_DONE:\n                isReleasing = false;\n                if (processCallBack != null)\n                    processCallBack.onFinish(MSG_ID_DEX_OPT_DONE);\n                try {\n                    release(ReleaseType.RESOURCE);\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n                return true;\n            case MSG_ID_RELEASE_FAILED:\n                if (processCallBack != null) {\n                    processCallBack.onFailed();\n                }\n\n                break;\n            case MSG_ID_DEX_RELEASE_DONE:\n                if (processCallBack != null) {\n                    processCallBack.onFinish(MSG_ID_DEX_RELEASE_DONE);\n                }\n                dexOptimization();\n                return true;\n\n            case MSG_ID_RELEASE_DONE:\n                if (processCallBack != null) {\n                    processCallBack.onAllFinish();\n                }\n                return true;\n\n            case MSG_ID_RESOURCE_RELEASE_DONE:\n                if (processCallBack != null) {\n                    processCallBack.onFinish(MSG_ID_RESOURCE_RELEASE_DONE);\n                }\n                try {\n                    release(ReleaseType.SOLIB);\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n                break;\n            default:\n                break;\n        }\n\n        return false;\n    }\n\n\n    public void release(final ProcessCallBack processCallBack, final File bundleFile,boolean start) throws IOException {\n        Log.e(TAG, \"release doing--->\" + isReleasing);\n        apkFile = bundleFile;\n        if (isReleasing) {\n            return;\n        }\n        isReleasing = true;\n        this.processCallBack = processCallBack;\n        if (!start) {\n            release(ReleaseType.DEX);\n        }else {\n            dexOptimization();\n            if (!handler.hasMessages(MSG_ID_RELEASE_FAILED)) {\n                processCallBack.onFinish(MSG_ID_DEX_OPT_DONE);\n                processCallBack.onAllFinish();\n//                handler.removeCallbacksAndMessages(null);\n            }else {\n                processCallBack.onFailed();\n//                handler.removeCallbacksAndMessages(null);\n            }\n        }\n    }\n\n\n    public void release(final ReleaseType releaseType) throws IOException {\n                switch (releaseType) {\n                    case DEX:\n                        try {\n                            Log.e(TAG, \"DexReleaser start!\");\n                            boolean result = DexReleaser.releaseDexes(apkFile, reversionDir,externalStorage);\n                            Log.e(TAG, \"DexReleaser done!----->\"+result);\n                            Message message = handler.obtainMessage();\n                            if (result) {\n                                message.what = MSG_ID_DEX_RELEASE_DONE;\n                            } else {\n                                message.what = MSG_ID_RELEASE_FAILED;\n                            }\n                            handler.sendMessage(message);\n                        } catch (IOException e) {\n                            e.printStackTrace();\n                        }\n                        break;\n//                    case RESOURCE:\n//                        try {\n//                            Log.e(TAG, \"ResourceReleaser start!\");\n//                            boolean result = ResourceReleaser.releaseResource(apkFile, reversionDir);\n//                            Log.e(TAG, \"ResourceReleaser done!----->\"+result);\n//\n//                            Message message = handler.obtainMessage();\n//                            if (result) {\n//                                message.what = MSG_ID_RESOURCE_RELEASE_DONE;\n//                            } else {\n//                                message.what = MSG_ID_RELEASE_FAILED;\n//                            }\n//                            handler.sendMessage(message);\n//                        } catch (IOException e) {\n//                            e.printStackTrace();\n//                        }\n//                        break;\n//                    case SOLIB:\n//                        try {\n//                            Log.e(TAG, \"NativeLibReleaser start!\");\n////                            boolean result = NativeLibReleaser.releaseLibs(apkFile, reversionDir);\n//                            Log.e(TAG, \"NativeLibReleaser done!----->\"+result);\n//                            Message message = handler.obtainMessage();\n//                            if (result) {\n//                                message.what = MSG_ID_RELEASE_DONE;\n//                            } else {\n//                                message.what = MSG_ID_RELEASE_FAILED;\n//                            }\n//                            handler.sendMessage(message);\n//                        } catch (IOException e) {\n//                            e.printStackTrace();\n//                        }\n//                        break;\n                    default:\n                        break;\n\n                }\n\n    }\n\n    private void dexOptimization() {\n        Log.e(TAG, \"dexOptimization start\");\n        File[] validDexes = reversionDir.listFiles(new FilenameFilter() {\n            @Override\n\n            public boolean accept(File dir,String pathname) {\n                if (!DexReleaser.isArt() || externalStorage) {\n                  return pathname.endsWith(DEX_SUFFIX);\n                } else {\n                    return pathname.endsWith(\".zip\");\n                }\n            }\n        });\n\n        File[] rawMainDexZip = reversionDir.listFiles(new FilenameFilter() {\n            @Override\n            public boolean accept(File dir, String pathname) {\n                return pathname.endsWith(\".zip\");\n\n            }\n        });\n\n        if (validDexes!= null && validDexes.length > 0) {\n            validDexes = sortDexs(validDexes);\n            if (Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT <= 24) {\n                PatchDexProfile.instance(RuntimeVariables.androidApplication).disableJitCompile();\n            }\n        }else if (rawMainDexZip!= null){\n\n            validDexes = rawMainDexZip;\n        }\n\n        dexFiles = new DexFile[validDexes.length];\n        if(!hasReleased) {\n            Log.e(TAG,\"start dexopt | hasRelease : \"+hasReleased);\n            final CountDownLatch countDownLatch = new CountDownLatch(validDexes.length);\n            for (int i = 0; i < validDexes.length; i++) {\n                final int j = i;\n                final File[] finalValidDexes = validDexes;\n\n                service.submit(new Runnable() {\n                    @Override\n                    public void run() {\n                        dexFiles[j] = dexoptInternal(finalValidDexes[j]);\n                        countDownLatch.countDown();\n                    }\n                });\n            }\n            try {\n                countDownLatch.await();\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n        }else{\n            Log.e(TAG,\"start dexopt | hasRelease : \"+hasReleased);\n            for (int i = 0; i < validDexes.length; i++) {\n                dexFiles[i] = dexoptInternal(validDexes[i]);\n            }\n        }\n\n        Log.e(TAG, \"dex opt done\");\n        handler.sendMessage(handler.obtainMessage(MSG_ID_DEX_OPT_DONE));\n    }\n\n    private String[] toString(File[] validDexes) {\n        String[]ss = new String[validDexes.length];\n        for (int i = 0; i < ss.length; i ++){\n            ss[i] = validDexes[i].getPath();\n        }\n        return ss;\n    }\n\n    private File[] sortDexs(File[] validDexes) {\n        if (validDexes == null){\n            return validDexes;\n        }else {\n           List<File>files = Arrays.asList(validDexes);\n           Collections.sort(files, new Comparator<File>() {\n               @Override\n               public int compare(File lhs, File rhs) {\n                   if (lhs.getName().equals(\"classes.dex\")) {\n                       return -1;\n                   } else if (rhs.getName().equals(\"classes.dex\")) {\n                       return 1;\n                   }\n                   return Integer.valueOf(lhs.getName().substring(7, lhs.getName().indexOf(\".\"))) - Integer.valueOf(rhs.getName().substring(7, rhs.getName().indexOf(\".\")));\n               }\n           });\n           return files.toArray(new File[0]);\n        }\n\n    }\n\n    private DexFile dexoptInternal(File validDex){\n        long startTime = System.currentTimeMillis();\n        DexFile dexFile = null;\n        String optimizedPath = optimizedPathFor(validDex, dexOptDir());\n        try {\n            if(!externalStorage) {\n\n                if(!new File(optimizedPath).exists()){\n                    Log.e(TAG,\"odex not exist\");\n                }\n            }else{\n                //interpretOnly\n                if(Build.VERSION.SDK_INT>=21 && isVMMultidexCapable(System.getProperty(\"java.vm.version\"))) {\n                    optimizedPath = KernalConstants.baseContext.getFilesDir()+File.separator+\"fake.dex\";\n                    new File(optimizedPath).createNewFile();\n                    dexFile = DexFileCompat.loadDex(KernalConstants.baseContext, validDex.getPath(), optimizedPath, 0);\n                }else{\n                    dexFile = DexFileCompat.loadDex(KernalConstants.baseContext,validDex.getPath(), optimizedPath,0);\n                }\n            }\n            boolean result = verifyDexFile(dexFile,optimizedPath);\n            if (!result) {\n                \n                handler.sendMessage(handler.obtainMessage(MSG_ID_RELEASE_FAILED));\n            }else {\n                Log.e(TAG,\"oat length:\"+String.valueOf(new File(optimizedPath).length()));\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n            handler.sendMessage(handler.obtainMessage(MSG_ID_RELEASE_FAILED));\n        } finally {\n            Log.e(TAG, String.format(\"dex %s consume %d ms\", validDex.getAbsolutePath(),\n                    System.currentTimeMillis() - startTime));\n        }\n        return dexFile;\n    }\n\n    private boolean verifyDexFile(DexFile dexFile,String optimizedPath) throws IOException {\n        if (dexFile != null) {\n            if(externalStorage){\n                return true;\n            }\n            if (!checkDexValid(dexFile)) {\n                return false;\n            }\n\n            return true;\n        }\n        return false;\n    }\n\n    public boolean checkDexValid(DexFile odexFile) throws IOException {\n        if (DexReleaser.isArt()) {\n            String applicationName = KernalConstants.RAW_APPLICATION_NAME;\n            try {\n                Enumeration<String> enumeration = odexFile.entries();\n                while (enumeration.hasMoreElements()) {\n                    if (enumeration.nextElement().replace(\"/\", \".\").equals(applicationName)) {\n                        return true;\n                    }\n                }\n                return false;\n            } catch (Throwable e) {\n                e.printStackTrace();\n                return false;\n            }\n        }\n        return true;\n    }\n\n\n    private String optimizedPathFor(File path, File optimizedDirectory) {\n        String fileName = path.getName();\n        if (!fileName.endsWith(DEX_SUFFIX)) {\n            int lastDot = fileName.lastIndexOf(\".\");\n            if (lastDot < 0) {\n                fileName += DEX_SUFFIX;\n            } else {\n                StringBuilder sb = new StringBuilder(lastDot + 4);\n                sb.append(fileName, 0, lastDot);\n                sb.append(DEX_SUFFIX);\n                fileName = sb.toString();\n            }\n        }\n        File result = new File(optimizedDirectory, fileName);\n        return result.getPath();\n\n    }\n\n    private File dexOptDir() {\n        File optDir = new File(reversionDir, \"opt\");\n        if (!optDir.exists()){\n            optDir.mkdirs();\n        }\n        return optDir;\n    }\n\n    public void close(){\n        if (!(Looper.getMainLooper() == Looper.myLooper())){\n            Looper.myLooper().quit();\n        }\n        handler.removeCallbacksAndMessages(null);\n        handler = null;\n        service.shutdown();\n    }\n\n    /**\n     * Identifies if the current VM has a native support for multidex, meaning there is no need for\n     * additional installation by this library.\n     * @return true if the VM handles multidex\n     */\n    /* package visible for test */\n    static boolean isVMMultidexCapable(String versionString) {\n        boolean isMultidexCapable = false;\n        if (versionString != null) {\n            Matcher matcher = Pattern.compile(\"(\\\\d+)\\\\.(\\\\d+)(\\\\.\\\\d+)?\").matcher(versionString);\n            if (matcher.matches()) {\n                try {\n                    int major = Integer.parseInt(matcher.group(1));\n                    int minor = Integer.parseInt(matcher.group(2));\n                    isMultidexCapable = (major > 2)\n                            || ((major == 2)\n                            && (minor >= 1));\n                } catch (NumberFormatException e) {\n                    // let isMultidexCapable be false\n                }\n            }\n        }\n        Log.i(TAG, \"VM with version \" + versionString +\n                (isMultidexCapable ?\n                        \" has multidex support\" :\n                        \" does not have multidex support\"));\n        return isMultidexCapable;\n    }\n\n\n    private void dexOat(String dexFilePath,String oatFilePath,String targetISA) throws IOException, InterruptedException {\n        final List<String> commandAndParams = new ArrayList<>();\n        commandAndParams.add(\"dex2oat\");\n        if (Build.VERSION.SDK_INT >= 24) {\n            commandAndParams.add(\"--runtime-arg\");\n            commandAndParams.add(\"-classpath\");\n            commandAndParams.add(\"--runtime-arg\");\n            commandAndParams.add(\"&\");\n        }\n        commandAndParams.add(\"--dex-file=\" + dexFilePath);\n        commandAndParams.add(\"--oat-file=\" + oatFilePath);\n        commandAndParams.add(\"--instruction-set=\" + targetISA);\n        if (Build.VERSION.SDK_INT > 25) {\n            commandAndParams.add(\"--compiler-filter=quicken\");\n        } else {\n            commandAndParams.add(\"--compiler-filter=interpret-only\");\n        }\n        final ProcessBuilder pb = new ProcessBuilder(commandAndParams);\n        pb.redirectErrorStream(true);\n        final Process dex2oatProcess = pb.start();\n        StreamConsumer.consumeInputStream(dex2oatProcess.getInputStream());\n        StreamConsumer.consumeInputStream(dex2oatProcess.getErrorStream());\n            final int ret = dex2oatProcess.waitFor();\n            if (ret != 0) {\n                throw new IOException(\"dex2oat works unsuccessfully, exit code: \" + ret);\n            }\n\n    }\n\n    public interface ProcessCallBack{\n\n        void onFailed() throws IOException;\n\n        void onFinish(int event);\n\n        void onAllFinish();\n\n    }\n\n    private static class StreamConsumer {\n        static final Executor STREAM_CONSUMER = Executors.newSingleThreadExecutor();\n\n        static void consumeInputStream(final InputStream is) {\n            STREAM_CONSUMER.execute(new Runnable() {\n                @Override\n                public void run() {\n                    if (is == null) {\n                        return;\n                    }\n                    final byte[] buffer = new byte[256];\n                    try {\n                        while ((is.read(buffer)) > 0) {\n                            // To satisfy checkstyle rules.\n                        }\n                    } catch (IOException ignored) {\n                        // Ignored.\n                    } finally {\n                        try {\n                            is.close();\n                        } catch (Exception ignored) {\n                            // Ignored.\n                        }\n                    }\n                }\n            });\n        }\n    }\n\n    public static String getCurrentInstructionSet() throws Exception {\n        String currentInstructionSet = null;\n        if (currentInstructionSet != null) {\n            return currentInstructionSet;\n        }\n        Class<?> clazz = Class.forName(\"dalvik.system.VMRuntime\");\n        Method currentGet = clazz.getDeclaredMethod(\"getCurrentInstructionSet\");\n\n        currentInstructionSet = (String) currentGet.invoke(null);\n        Log.d(TAG, \"getCurrentInstructionSet:\" + currentInstructionSet);\n        return currentInstructionSet;\n    }\n\n\n}"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/patch/releaser/DexReleaser.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.startup.patch.releaser;\n\nimport android.content.SharedPreferences;\nimport android.os.Build;\nimport android.preference.PreferenceManager;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.taobao.atlas.startup.patch.CombineDexMerger;\nimport android.taobao.atlas.startup.patch.CombineDexVerifier;\nimport android.taobao.atlas.startup.patch.KernalBundle;\nimport android.taobao.atlas.startup.patch.KernalConstants;\nimport android.taobao.atlas.util.StringUtils;\nimport android.util.Log;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.Enumeration;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\nimport java.util.zip.ZipOutputStream;\n\n/**\n * Created by lilong on 16/12/21.\n */\npublic class DexReleaser {\n\n    private static final int BUFFER_SIZE = 0x4000;\n\n    private static final String DEX_SUFFIX = \".dex\";\n\n    private static final String CLASS_SUFFIX = \"classes\";\n\n    public static boolean   releaseDexes(File bundleFile, File reversionDir, boolean externalStorage) throws IOException {\n        boolean dexPatch = bundleFile.getAbsolutePath().contains(\"dexpatch\");\n        ZipFile zipFile = null;\n        try {\n            zipFile = new ZipFile(bundleFile);\n            boolean hasDexFile = hasDexFile(zipFile);\n            if (!hasDexFile) {\n                return true;\n            }\n            if (externalStorage || !isArt()) {\n\n\n\n            if (Build.VERSION.SDK_INT > 27){\n\n                return true;\n            }\n\n\n            if (!isArt()) {\n                Enumeration entryEnumeration = zipFile.entries();\n                while (entryEnumeration.hasMoreElements()) {\n                    ZipEntry zipEntry = (ZipEntry) entryEnumeration.nextElement();\n                    if (zipEntry.getName().endsWith(DEX_SUFFIX)) {\n                        File dexFile = new File(reversionDir, zipEntry.getName());\n                        FileOutputStream fileOutputStream = new FileOutputStream(dexFile);\n                        copy(zipFile.getInputStream(zipEntry), fileOutputStream);\n                        fileOutputStream.close();\n                    }\n                }\n            }else {\n                File sourceFile;\n                if (dexPatch) {\n                    //如果kernalBundle==null，说明主dex没有被升级过，那么就和base.apk做merge\n                    sourceFile = null == KernalBundle.kernalBundle\n                            ? new File(KernalConstants.APK_PATH)\n                            : KernalBundle.kernalBundle.getRevisionZip();\n                } else {\n                    sourceFile = new File(KernalConstants.APK_PATH);\n                }\n                File targetFile = File.createTempFile(sourceFile.getName(), \".tmp\", bundleFile.getParentFile());\n                CombineDexMerger combineDexMerger = new CombineDexMerger(new CombineDexVerifier());\n                boolean result = combineDexMerger.merge(sourceFile, bundleFile, targetFile);\n                if (result && bundleFile.delete() && targetFile.renameTo(bundleFile)) {\n                    return true;\n                } else {\n                    return false;\n                }\n            }\n\n                return true;\n            } else {\n                File sourceFile;\n                if (dexPatch) {\n                    //如果kernalBundle==null，说明主dex没有被升级过，那么就和base.apk做merge\n                    sourceFile = null == KernalBundle.kernalBundle\n                            ? new File(KernalConstants.APK_PATH)\n                            : KernalBundle.kernalBundle.getRevisionZip();\n                } else {\n                    sourceFile = new File(KernalConstants.APK_PATH);\n                }\n                File targetFile = File.createTempFile(sourceFile.getName(), \".tmp\", bundleFile.getParentFile());\n                CombineDexMerger combineDexMerger = new CombineDexMerger(new CombineDexVerifier());\n                boolean result = combineDexMerger.merge(sourceFile, bundleFile, targetFile);\n                if (result && bundleFile.delete() && targetFile.renameTo(bundleFile)) {\n                    return true;\n                } else {\n                    return false;\n                }\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n\n        } finally {\n            if (zipFile != null) {\n                zipFile.close();\n            }\n        }\n        return false;\n    }\n\n\n\n    public static boolean isArt() {\n\n//        return false;\n\n        return Build.VERSION.SDK_INT > 20;\n\n    }\n\n\n    private static boolean hasDexFile(ZipFile zipFile) {\n        return zipFile.getEntry(CLASS_SUFFIX + DEX_SUFFIX) != null;\n    }\n\n    public static void copy(InputStream input, OutputStream output) throws IOException {\n        byte[] readContent = new byte[BUFFER_SIZE];\n        int bytesRead;\n        while ((bytesRead = input.read(readContent)) != -1) {\n            output.write(readContent, 0, bytesRead);\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/patch/releaser/PatchDexProfile.java",
    "content": "package android.taobao.atlas.startup.patch.releaser;\n\nimport android.app.Application;\nimport android.content.pm.ApplicationInfo;\nimport android.graphics.Path;\nimport android.os.Environment;\nimport android.os.Process;\nimport android.os.UserHandle;\nimport android.taobao.atlas.hack.Hack;\nimport android.taobao.atlas.startup.patch.KernalBundle;\nimport android.text.TextUtils;\n\nimport java.io.File;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * DexProfile\n *\n * @author zhayu.ll\n * @date 18/9/5\n */\npublic class PatchDexProfile {\n\n    private static PatchDexProfile mPatchDexProfile = null;\n    private Application mApp;\n\n    static Hack.HackedClass vmRuntime_clazz = null;\n    static Hack.HackedField vmRuntime_THE_ONE = null;\n    static Hack.HackedMethod vmRuntime_disableJitCompilation = null;\n    static Hack.HackedMethod vmRuntime_registerAppInfo = null;\n\n\n    static Hack.HackedClass systemProperties_clazz = null;\n    static Hack.HackedMethod systemProperties_getBoolean = null;\n    static Hack.HackedMethod systemProperties_set = null;\n\n\n    static Hack.HackedClass applicationLoaders_clazz = null;\n    static Hack.HackedField applicationLoaders_gApplicationLoaders = null;\n    static Hack.HackedMethod applicationLoaders_addPath = null;\n\n\n    static {\n        try {\n            vmRuntime_clazz = Hack.into(\"dalvik.system.VMRuntime\");\n            vmRuntime_THE_ONE = vmRuntime_clazz.staticField(\"THE_ONE\");\n            vmRuntime_disableJitCompilation = vmRuntime_clazz.method(\"disableJitCompilation\");\n\n\n            systemProperties_clazz = Hack.into(\"android.os.SystemProperties\");\n            systemProperties_getBoolean = systemProperties_clazz.staticMethod(\"getBoolean\", String.class, boolean.class);\n            systemProperties_set = systemProperties_clazz.staticMethod(\"set\",String.class,String.class);\n//            dexLoadReporter_clazz = Hack.into(\"android.app.DexLoadReporter\");\n//            dexLoadReporter_INSTANCE = dexLoadReporter_clazz.staticField(\"INSTANCE\");\n//            dexLoadReporter_registerAppDataDir = dexLoadReporter_clazz.method(\"registerAppDataDir\", String.class, String.class);\n\n            applicationLoaders_clazz = Hack.into(\"android.app.ApplicationLoaders\");\n            applicationLoaders_gApplicationLoaders = applicationLoaders_clazz.staticField(\"gApplicationLoaders\");\n//            applicationLoaders_addPath = applicationLoaders_clazz.method(\"addPath\", ClassLoader.class, String.class);\n        }catch (Throwable e){\n            e.printStackTrace();\n        }\n\n    }\n\n    private PatchDexProfile(Application mApplication) {\n        this.mApp = mApplication;\n    }\n\n\n    public static PatchDexProfile instance(Application mApp) {\n        if (mPatchDexProfile == null) {\n            mPatchDexProfile = new PatchDexProfile(mApp);\n        }\n        return mPatchDexProfile;\n    }\n\n\n    public void disableJitCompile() {\n        try {\n            if (vmRuntime_disableJitCompilation != null) {\n                vmRuntime_disableJitCompilation.invoke(vmRuntime_THE_ONE.get(null));\n            }\n//            systemProperties_set.invoke(null,\"dalvik.vm.usejitprofiles\",\"false\");\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n\n    }\n\n    public void setupJitProfileSupport(String[] dexFiles) {\n\n        try {\n            boolean jitEnabled = (boolean) systemProperties_getBoolean.invoke(null, \"dalvik.vm.usejitprofiles\", false);\n            if (!jitEnabled) {\n                return;\n            }\n        } catch (InvocationTargetException e) {\n            e.printStackTrace();\n        }\n\n        // Only set up profile support if the loaded apk has the same uid as the\n        // current process.\n        // Currently, we do not support profiling across different apps.\n        // (e.g. application's uid might be different when the code is\n        // loaded by another app via createApplicationContext)\n        if (mApp.getApplicationInfo().uid != Process.myUid()) {\n            return;\n        }\n\n        final List<String> codePaths = new ArrayList<>();\n\n        //we no need to add orignal apk path to profile\n//        if ((mApp.getApplicationInfo().flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {\n//            codePaths.add(mApp.getApplicationInfo().sourceDir);\n//        }\n\n        if (dexFiles != null) {\n            Collections.addAll(codePaths, dexFiles);\n        }\n\n        if (codePaths.isEmpty()) {\n            // If there are no code paths there's no need to setup a profile file and register with\n            // the runtime,\n            return;\n        }\n\n        final File profileFile = getPrimaryProfileFile(mApp.getPackageName());\n\n        try {\n\n            vmRuntime_registerAppInfo.invoke(null, profileFile.getPath(),\n                    codePaths.toArray(new String[codePaths.size()]));\n        } catch (InvocationTargetException e) {\n            e.printStackTrace();\n        }\n\n\n//        // Register the app data directory with the reporter. It will\n//        // help deciding whether or not a dex file is the primary apk or a\n//        // secondary dex.\n//\n//        try {\n//\n//            dexLoadReporter_registerAppDataDir.invoke(dexLoadReporter_INSTANCE.get(null), mApp.getPackageName(), mApp.getApplicationInfo().dataDir);\n//        } catch (Exception e) {\n//            e.printStackTrace();\n//        }\n\n    }\n\n\n    public static void addPathes(List<String> addedPaths) {\n        try {\n            if (addedPaths != null && addedPaths.size() > 0) {\n                String add = TextUtils.join(File.pathSeparator, addedPaths);\n                applicationLoaders_addPath.invoke(applicationLoaders_gApplicationLoaders.get(null), KernalBundle.class.getClassLoader(), add);\n            }\n\n        } catch (Exception e) {\n            e.printStackTrace();\n\n        }\n\n\n    }\n\n\n    private File getPrimaryProfileFile(String packageName) {\n        try {\n            Method m = Environment.class.getDeclaredMethod(\"getDataProfilesDePackageDirectory\", int.class, String.class);\n            m.setAccessible(true);\n            File profileDir = (File) m.invoke(null, mApp.getApplicationInfo().uid / 100000, packageName);\n            return new File(profileDir, \"primary-patch.prof\");\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/startup/patch/releaser/ReleaseType.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.startup.patch.releaser;\n\n/**\n * Created by lilong on 16/12/21.\n */\npublic enum  ReleaseType {\n\n    DEX,SOLIB,RESOURCE\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/ApkUtils.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.util;\n\nimport java.io.BufferedInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.FileChannel;\nimport java.security.PublicKey;\nimport java.security.cert.Certificate;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\nimport java.util.zip.ZipFile;\n\nimport android.taobao.atlas.hack.AssertionArrayException;\nimport android.taobao.atlas.hack.AtlasHacks;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.taobao.atlas.util.log.impl.AtlasMonitor;\n\npublic class ApkUtils {\n\n    final static int SYSTEM_ROOT_STATE_UNKNOW  = -1;\n    final static int SYSTEM_ROOT_STATE_DISABLE = 0;\n    final static int SYSTEM_ROOT_STATE_ENABLE  = 1;\n    private static ZipFile sApkZip;\n\n    public static ZipFile getApk(){\n        if(sApkZip==null){\n            loadZip();\n        }\n        return sApkZip;\n    }\n\n    private static synchronized void loadZip(){\n        if(sApkZip!=null){\n            return;\n        }\n        try {\n            sApkZip = new ZipFile(RuntimeVariables.androidApplication.getApplicationInfo().sourceDir);\n        }catch(Throwable e){e.printStackTrace();}\n    }\n\n    public static final String[] getApkPublicKey(String apkPath) {\n    \tJarFile jarFile = null;\n        try {\n            jarFile = new JarFile(apkPath);\n            final JarEntry je = jarFile.getJarEntry(\"classes.dex\");\n            if (je != null) {\n                byte[] readBuffer = new byte[4096];\n                final Certificate[] certs = loadCertificates(jarFile, je, readBuffer);\n                if (certs != null) {\n                    String[] publicKeys = new String[certs.length];\n                    for (int i = 0; i < certs.length; i++) {\n                        Certificate cert = certs[i];\n                        PublicKey publicKey = cert.getPublicKey();\n                        publicKeys[i] = bytesToHexString(publicKey.getEncoded());\n                    }\n                    return publicKeys;\n                }\n            }\n        } catch (IOException e) {\n        } finally {\n        \tif (jarFile!=null) {\n        \t\ttry {\n\t\t\t\t\tjarFile.close();\n\t\t\t\t} catch (IOException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n        \t}\n        }\n\n        return null;\n    }\n\n    private static Certificate[] loadCertificates(JarFile jarFile, JarEntry je,\n                                           byte[] readBuffer) {\n        try {\n            // We must read the stream for the JarEntry to retrieve\n            // its certificates.\n            InputStream is = new BufferedInputStream(jarFile.getInputStream(je));\n            while (is.read(readBuffer, 0, readBuffer.length) != -1) {\n                // not using\n            }\n            is.close();\n            return je != null ? je.getCertificates() : null;\n        } catch (IOException e) {\n            e.printStackTrace();\n        } catch (RuntimeException e) {\n            e.printStackTrace();\n        }\n        return null;\n    }\n\n    private static final String bytesToHexString(byte[] src) {\n        StringBuilder stringBuilder = new StringBuilder();\n        if (src == null || src.length <= 0) {\n            return null;\n        }\n        for (int i = 0; i < src.length; i++) {\n            int v = src[i] & 0xFF;\n            String hv = Integer.toHexString(v);\n            if (hv.length() < 2) {\n                stringBuilder.append(0);\n            }\n            stringBuilder.append(hv);\n        }\n        return stringBuilder.toString();\n    }\n\n    public static final void chmod(File file) {\n        if (file != null && !file.exists()) {\n            file.mkdirs();\n            try {\n                String command = \"chmod 555 \" + file.getAbsolutePath();\n                Runtime runtime = Runtime.getRuntime();\n                runtime.exec(command);\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n        }\n    }\n\n    private static int systemRootState = SYSTEM_ROOT_STATE_UNKNOW;\n\n    public static boolean isRootSystem() {\n        if (systemRootState != SYSTEM_ROOT_STATE_UNKNOW) {\n            return systemRootState == SYSTEM_ROOT_STATE_ENABLE;\n        }\n        final String suSearchPaths[] = { \"/system/bin/\", \"/system/xbin/\", \"/system/sbin/\", \"/sbin/\", \"/vendor/bin/\" };\n        for (String searchPath : suSearchPaths) {\n            File file = new File(searchPath, \"su\");\n            if (file.exists()) {\n                systemRootState = SYSTEM_ROOT_STATE_ENABLE;\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public static void copyDirectory(File sourceDir,File targetDir) throws Exception{\n        File[] files = sourceDir.listFiles();\n        for(File childFile : files){\n            if(childFile.isFile()){\n                File dir = new File(targetDir.getAbsolutePath());\n                if(!dir.exists()){\n                    dir.mkdirs();\n                }\n                copyInputStreamToFile(new FileInputStream(childFile),new File(dir,childFile.getName()));\n            }else{\n                copyDirectory(childFile,new File(targetDir,childFile.getName()));\n            }\n        }\n    }\n    \n    public static void copyInputStreamToFile(InputStream input, File file) throws IOException {\n        FileOutputStream os = null;\n        FileChannel channel = null;\n        try {\n            // copy 文件\n            os = new FileOutputStream(file);\n            channel = os.getChannel();\n            byte[] buffers = new byte[1024];\n            int realLength;\n            while ((realLength = input.read(buffers)) > 0) {\n                channel.write(ByteBuffer.wrap(buffers, 0, realLength));\n            }\n        } catch (IOException e) {\n            AtlasMonitor.getInstance().report(AtlasMonitor.CONTAINER_BUNDLE_SOURCE_UNZIP_FAIL, null, e);\n            throw new IOException(e);\n        } finally {\n            if (input != null) try {\n            \tinput.close();\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n            if (channel != null) try {\n                channel.close();\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n            if (os != null) try {\n                os.close();\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/AtlasFileLock.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.util;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\nimport java.nio.channels.FileChannel;\nimport java.nio.channels.FileLock;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport android.app.ActivityManager;\nimport android.content.Context;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.util.Log;\n\npublic class AtlasFileLock {\n\n\tprivate static class SingleTonHolder{\n\t\tprivate final static AtlasFileLock INSTANCE = new AtlasFileLock();\n\t}\n    public static AtlasFileLock getInstance(){\n\t\treturn SingleTonHolder.INSTANCE;\n    }\n    \n\tprivate class FileLockCount{\n    \tRandomAccessFile fOs;\n    \tFileChannel fChannel;\n\t\tFileLock mFileLock;\n\t\tint mRefCount;\n\t\t\n\t\tFileLockCount(FileLock mFileLock, int mRefCount, RandomAccessFile fOs, FileChannel fChannel){\n\t\t\tthis.mFileLock = mFileLock;\n\t\t\tthis.mRefCount = mRefCount;\n\t\t\tthis.fOs = fOs;\n\t\t\tthis.fChannel = fChannel;\n\t\t}\n\t}\n\t\n\t/*\n\t * The FileLock is interesting, 1st not suitable for intraprocess\n\t * i.e., once the current process already hold the lock, another\n\t * thread's aquirement would be always success.\n\t * 2nd is that FileLock has no reference count, i.e., Once both\n\t * threads hold the lock, any thread release that would totally\n\t * release the FileLock.\n\t * To resolve the 1st issue, we used BundleLock.\n\t * To resolve the 2nd issue, we need add ref count ourselves.\n\t */\n\tprivate Map<String, FileLockCount> mRefCountMap = new ConcurrentHashMap<String, FileLockCount>();\n\n\t/*\n\t * Refcnt increment\n\t * return the ref count of current file's filelock\n\t */\t\n\tprivate int RefCntInc(String name, FileLock fileLock, RandomAccessFile fOs, FileChannel fChannel){\n\t\tInteger val = 0;\n\t\t\n\t\tif (mRefCountMap.containsKey(name)){\n\t\t\tval = mRefCountMap.get(name).mRefCount++;\n\t\t} else {\n\t\t\tval = 1;\n\t\t\tFileLockCount newFileLockCount = new FileLockCount(fileLock, val, fOs, fChannel);\n\t\t\tmRefCountMap.put(name, newFileLockCount);\n\t\t}\n\n\t\treturn val;\n\t}\n\t\n\t/*\n\t * Refcnt decrement\n\t * return the ref count of current file's filelock\n\t */\n\tprivate int RefCntDec(String name){\n\t\tInteger val = 0;\n\t\t\n\t\tif (mRefCountMap.containsKey(name)){\n\t\t\tval = --mRefCountMap.get(name).mRefCount;\n\t\t\t/*\n\t\t\t * Remove the item once value is already 0\n\t\t\t */\n\t\t\tif (val <= 0){\n\t\t\t\tmRefCountMap.remove(name);\n\t\t\t}\t\t\t\n\t\t}\n\t\t\n\t\treturn val;\n\t}\n\t\n    /*\n     * Hold a exclusive lock, file is the directory\n     */\n\tpublic boolean LockExclusive(File orgFile) {  \n    \tRandomAccessFile fOs = null;\n    \tFileChannel fChannel = null;\n        try {\n        \tif (orgFile == null){\n        \t\treturn false;\n        \t}\n        \t\n        \tFile file ;\n\t\t\tif(orgFile.exists() && orgFile.isDirectory()){\n\t\t\t\tfile = new File(orgFile.getAbsolutePath().concat(\"/lock\"));\n\t\t\t}else{\n\t\t\t\tfile = new File(orgFile.getParentFile().getAbsolutePath().concat(\"/lock\"));\n\t\t\t}\n        \tif (file.exists() != true){\n        \t\tfile.createNewFile();\n        \t}\n        \t\n        \tfOs = new RandomAccessFile(file.getAbsolutePath(), \"rw\");\n        \tfChannel = fOs.getChannel();\n        \t\n        \tFileLock fFileLock = fChannel.lock();\n            if(fFileLock.isValid()) {  \n            \tRefCntInc(file.getAbsolutePath(), fFileLock, fOs, fChannel);\n                return true;  \n            }          \t\n        }catch (Exception e) {  \n            e.printStackTrace();\n         }\n\t\treturn false;  \n    }  \n      \n    \n\t/*\n\t * Free file lock, do remember to invoke it once caught exception\n\t */        \n    public void unLock(File orgFile) {\n\n\t\tFile file ;\n\t\tif(orgFile.exists() && orgFile.isDirectory()){\n\t\t\tfile = new File(orgFile.getAbsolutePath().concat(\"/lock\"));\n\t\t}else{\n\t\t\tfile = new File(orgFile.getParentFile().getAbsolutePath().concat(\"/lock\"));\n\t\t}\n\n\t\tif (file.exists() == false){\n    \t\treturn;\n    \t}\n    \t\n    \tif ((file != null) && !mRefCountMap.containsKey(file.getAbsolutePath())){\n    \t\treturn;\n    \t}\n    \t\n    \tFileLockCount flc = mRefCountMap.get(file.getAbsolutePath());\n    \tif (flc == null){\n    \t\treturn;\n    \t}\n    \t\n    \tFileLock fl = flc.mFileLock;\n    \tRandomAccessFile fOs = flc.fOs;\n    \tFileChannel fChannel = flc.fChannel;\n    \t\n        try {\n        \tif (RefCntDec(file.getAbsolutePath()) <= 0){\n        \t\tif (fl != null && fl.isValid()){\n        \t\t\tfl.release();  \n        \t\t}\n        \t\tif (fOs != null){\n        \t\t\tfOs.close();\n        \t\t}\n        \t\tif (fChannel != null){\n        \t\t\tfChannel.close();\n        \t\t}\n        \t}\n        } catch (IOException e) {  \n        \t e.printStackTrace();\n        }  \n    }\n\n    \n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/BundleLock.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.util;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.locks.ReentrantReadWriteLock;\n\n/**\n * @author xieguo\n *\n */\npublic class BundleLock {\n\n\t/*\n\t * Lock maps\n\t */\n\tstatic Map<String, ReentrantReadWriteLock> bundleIdentifierMap = new HashMap<String, ReentrantReadWriteLock>();\n\t\n\t/*\n\t * Synchronized lock.\n\t */\n\tpublic static void WriteLock(String bundle){\n\t\tReentrantReadWriteLock lock = null;\n\t\tsynchronized(bundleIdentifierMap){\n\t\t\tlock = bundleIdentifierMap.get(bundle);\n\t\t\tif (lock == null){\n\t\t\t\tlock = new ReentrantReadWriteLock();\n\t\t\t\tbundleIdentifierMap.put(bundle, lock);\n\t\t\t}\n\t\t}\n\t\tlock.writeLock().lock();\n\t}\n\t\n\tpublic static void WriteUnLock(String bundle){\n\t\tReentrantReadWriteLock lock = null;\n\t\tsynchronized(bundleIdentifierMap){\n\t\t\tlock = bundleIdentifierMap.get(bundle);\n\t\t\tif (lock == null){\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tlock.writeLock().unlock();\n\t}\t\n\t\n\tpublic static boolean ReadLock(String bundle){\n\t\tReentrantReadWriteLock lock = null;\n\t\tsynchronized(bundleIdentifierMap){\n\t\t\tlock = bundleIdentifierMap.get(bundle);\n\t\t\tif (lock == null){\n\t\t\t\tlock = new ReentrantReadWriteLock();\n\t\t\t\tbundleIdentifierMap.put(bundle, lock);\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\treturn lock.readLock().tryLock(3, TimeUnit.SECONDS);\n\t\t} catch (InterruptedException e) {\n//\t\t\te.printStackTrace();\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic static void ReadUnLock(String bundle){\n\t\tReentrantReadWriteLock lock = null;\n\t\tsynchronized(bundleIdentifierMap){\n\t\t\tlock = bundleIdentifierMap.get(bundle);\n\t\t\tif (lock == null){\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tlock.readLock().unlock();\n\t}\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/FileUtils.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.util;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.math.BigInteger;\nimport java.nio.MappedByteBuffer;\nimport java.nio.channels.FileChannel;\nimport java.security.MessageDigest;\n\nimport android.os.Build;\nimport android.os.Environment;\nimport android.os.StatFs;\n\npublic class FileUtils {\n\t\n\tpublic static boolean CheckFileValidation(String path) {\n\t\tboolean flag = false;\n\t\tFileInputStream in = null;\n\t\ttry{\n\t\t\tin = new FileInputStream(path);\n\t\t} catch (FileNotFoundException e){\n\t\t\tflag = false;\n\t\t}\n\t\t\n\t\tif ((flag == true) && (in != null)){\n\t\t\ttry{\n\t\t\t\tif (in.available() <= 0)\n\t\t\t\t\tflag = false;\n\t\t\t}catch(IOException e){\n\t\t\t\tflag = false;\n\t\t\t}\n\t\t}\n\t\treturn flag;\n\t}\n\n//\tpublic static String getDataAvailableSpace(){\n//\t\tlong avliableSpace = 0;\n//\t\tavliableSpace = FileUtils.getUsableSpace(Environment.getDataDirectory());\n//\t\treturn String.valueOf(avliableSpace);\n//\t}\n\t\n    public static long getUsableSpace(File path) {\n        if (path == null) {\n            return -1;\n        }\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {\n            return path.getUsableSpace()/1024/1024;\n        } else {\n            if (!path.exists()) {\n                return 0;\n            } else {\n                final StatFs stats = new StatFs(path.getPath());\n                return (long) stats.getBlockSize() * (long) stats.getAvailableBlocks()/1024/1024;\n            }\n        }\n    }\n    \n//    public static long folderSize(File directory) {\n//        long length = 0;\n//        for (File file : directory.listFiles()) {\n//            if (file.isFile())\n//                length += file.length();\n//            else\n//                length += folderSize(file);\n//        }\n//        return length;\n//    }\n \n//\tprivate static String getFreeInodes(){\n//\t\ttry {\n//\t\t\tlong f_ffree = -1;\n//\t\t\tlong f_favail = -1;\n//\t\t\tClass clsStatFs = Class.forName(\"android.os.StatFs\");\n//\t\t\tMethod doStat = clsStatFs.getDeclaredMethod(\"doStat\", String.class);\n//\t\t\tdoStat.setAccessible(true);\n//\t\t\tfinal Object stat = doStat.invoke(null, Environment.getDataDirectory().getAbsolutePath());\n//\t\t\tClass clsStructStatFs = stat.getClass();\n//\t\t\tField filed_f_free = clsStructStatFs.getDeclaredField(\"f_ffree\");\n//\t\t\tField filed_f_favail = null;\n//\t\t\ttry{\n//\t\t\t\tfiled_f_favail = clsStructStatFs.getDeclaredField(\"f_favail\");\n//\t\t\t} catch(Exception e){\n//\t\t\t}\n//\t\t\tf_ffree = filed_f_free.getLong(stat);\n//\t\t\tif (filed_f_favail != null){\n//\t\t\t\tf_favail = filed_f_favail.getLong(stat);\n//\t\t\t}\n//\t\t\treturn \"avaiable free nodes: \" +  f_ffree + (f_favail == -1 ? (\"avaiable free nodes for non-root:  \" + f_favail) : \"\");\n//\t\t} catch (Exception e) {\n//\t\t\t// TODO Auto-generated catch block\n//\t\t\te.printStackTrace();\n//\t\t}\n//\t\treturn \"\";\n//\t}\n\t\n\tpublic static String getAvailableDisk(){\n\t    String avliableSpace = \"\";\n\n\t    try{\n\t\t\tavliableSpace = getUsableSpace(Environment.getDataDirectory())+\"M\";\n\t    } catch(Exception e){\n\t    }\n\n\t    return avliableSpace;\n\t}\n\n\tpublic static String getMd5ByFile(File file) throws IOException {\n\t\tString value = null;\n\t\tFileInputStream in = new FileInputStream(file);\n\t\ttry {\n\t\t\tMappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());\n\t\t\tMessageDigest md5 = MessageDigest.getInstance(\"MD5\");\n\t\t\tmd5.update(byteBuffer);\n\t\t\tBigInteger bi = new BigInteger(1, md5.digest());\n\t\t\tvalue = bi.toString(16);\n\t\t} catch (Exception e) {\n\t\t\te.printStackTrace();\n\t\t} finally {\n\t\t\tif(null != in) {\n\t\t\t\ttry {\n\t\t\t\t\tin.close();\n\t\t\t\t} catch (IOException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn value;\n\t}\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/IOUtil.java",
    "content": "package android.taobao.atlas.util;\n\nimport java.io.Closeable;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.zip.ZipFile;\n\n/**\n * Created by guanjie on 2017/5/5.\n */\n\npublic class IOUtil {\n    public static void quietClose(Closeable closeable){\n        if (closeable != null) {\n            try {\n                closeable.close();\n            } catch (Throwable e) {\n            }\n        }\n    }\n\n    public static void quietClose(ZipFile zip){\n        try {\n            if (zip != null) {\n                zip.close();\n            }\n        }catch(Throwable e){\n        }\n    }\n\n    public static void copyStream(InputStream in, OutputStream out) throws IOException {\n\n        try {\n            int c;\n            byte[] by = new byte[1024];\n            while ((c = in.read(by)) != -1) {\n                out.write(by, 0, c);\n            }\n            out.flush();\n        } catch (IOException e) {\n            throw e;\n        } finally {\n            quietClose(out);\n            quietClose(in);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/RefectUtils.java",
    "content": "package android.taobao.atlas.util;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\n\n/**\n * 创建日期：2019/4/8 on 上午11:38\n * 描述:\n * 作者:zhayu.ll\n */\npublic class RefectUtils {\n    public RefectUtils() {\n    }\n\n    public static Method method(Object o, String methodName, Class... clazz) {\n        Class c = o.getClass();\n\n        while(c != Object.class) {\n            try {\n                Method method = c.getDeclaredMethod(methodName, clazz);\n                method.setAccessible(true);\n                return method;\n            } catch (NoSuchMethodException var5) {\n                c = c.getSuperclass();\n            }\n        }\n\n        return null;\n    }\n\n    public static Field field(Object o, String fieldName) {\n        Class c = o.getClass();\n\n        while(c != Object.class) {\n            try {\n                Field field = c.getDeclaredField(fieldName);\n                field.setAccessible(true);\n                return field;\n            } catch (NoSuchFieldException var4) {\n                c = c.getSuperclass();\n            }\n        }\n\n        return null;\n    }\n\n    public static Object invoke(Object o, Method m, Object... objects) {\n        m.setAccessible(true);\n\n        try {\n            return m.invoke(o, objects);\n        } catch (IllegalAccessException var4) {\n            var4.printStackTrace();\n        } catch (InvocationTargetException var5) {\n            var5.printStackTrace();\n        }\n\n        return null;\n    }\n\n    public static Object fieldGet(Object o, Field field) {\n        field.setAccessible(true);\n\n        try {\n            return field.get(o);\n        } catch (IllegalAccessException var3) {\n            var3.printStackTrace();\n            return null;\n        }\n    }\n}\n\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/SoLoader.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.util;\n\nimport android.annotation.TargetApi;\nimport android.os.Build;\nimport android.taobao.atlas.framework.Framework;\nimport android.text.TextUtils;\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.util.zip.ZipEntry;\n\n/**\n * Created by guanjie on 2016/12/12.\n */\n\npublic class SoLoader {\n\n    private static final File LIB_DIR;\n\n    static {\n        LIB_DIR = new File(Framework.STORAGE_LOCATION,\"lib\");\n        if(!LIB_DIR.exists()){\n            LIB_DIR.mkdirs();\n        }\n    }\n\n    public static void loadLibrary(String libName){\n        if(TextUtils.isEmpty(libName)){\n            throw new RuntimeException(\"can not load library without a name\");\n        }\n        try{\n            Runtime.getRuntime().loadLibrary(libName);\n        }catch(UnsatisfiedLinkError error){\n            if(!LIB_DIR.exists()){\n                LIB_DIR.mkdirs();\n            }\n            if(!LIB_DIR.exists()){\n                throw error;\n            }\n            String soName = System.mapLibraryName(libName);\n            if(supportArmeabi()){\n                File soFile = null;\n                if(findLocalLibrary(soName) == null){\n                    extractSoFromApk(soName);\n                }\n                if((soFile=findLocalLibrary(soName))!=null){\n                    System.load(soFile.getAbsolutePath());\n                }else{\n                    throw error;\n                }\n            }\n        }\n    }\n\n    @TargetApi(Build.VERSION_CODES.LOLLIPOP)\n    private static boolean supportArmeabi(){\n        if(Build.VERSION.SDK_INT>=21) {\n            String[] abis = Build.SUPPORTED_ABIS;\n            if (abis != null) {\n                for (String abi : abis) {\n                    if (abi.equalsIgnoreCase(\"armeabi\")) {\n                        return true;\n                    }\n                }\n            }\n        }else{\n            if(Build.CPU_ABI.contains(\"armeabi\") || Build.CPU_ABI2.contains(\"armeabi\")){\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    private static File findLocalLibrary(String libraryName){\n        File soFile;\n        if(LIB_DIR.exists() && (soFile=new File(LIB_DIR,libraryName)).exists()){\n            return soFile;\n        }else{\n            return null;\n        }\n    }\n\n    private static synchronized void extractSoFromApk(String soName){\n        AtlasFileLock.getInstance().LockExclusive(LIB_DIR);\n        if(findLocalLibrary(soName)!=null){\n            AtlasFileLock.getInstance().unLock(LIB_DIR);\n            return;\n        }\n        try {\n            int retryCount = 2;\n            do {\n                --retryCount;\n                String entryName = String.format(\"lib/armeabi/%s\", soName);\n                ZipEntry targetEntry = null;\n                if (ApkUtils.getApk() != null && (targetEntry = ApkUtils.getApk().getEntry(entryName)) != null) {\n                    File targetFile = new File(LIB_DIR, soName);\n                    File targetFileTmp = new File(LIB_DIR,soName+\".tmp\");\n                    if(!targetFileTmp.exists() || targetFileTmp.length()!=targetEntry.getSize()) {\n                        if(targetFileTmp.exists()){\n                            targetFileTmp.delete();\n                        }\n                        BufferedOutputStream bos = new BufferedOutputStream(\n                                new FileOutputStream(targetFileTmp.getAbsolutePath()));\n                        BufferedInputStream bi = new BufferedInputStream(ApkUtils.getApk().getInputStream(targetEntry));\n                        byte[] readContent = new byte[512];\n                        int readCount = bi.read(readContent);\n                        while (readCount != -1) {\n                            bos.write(readContent, 0, readCount);\n                            readCount = bi.read(readContent);\n                        }\n                        try {\n                            bos.close();\n                            bi.close();\n                        } catch (Throwable e) {\n                        }\n                    }\n                    if (targetFileTmp.exists()) {\n                        if(targetFileTmp.length() == targetEntry.getSize()){\n                            targetFileTmp.renameTo(targetFile);\n                            if(!targetFile.exists()){\n                                targetFileTmp.renameTo(targetFile);\n                            }\n                            if(targetFile.exists()){\n                                break;\n                            }\n                        }else{\n                            targetFileTmp.delete();\n                        }\n                    }\n\n                }\n            } while (retryCount > 0);\n        }catch(Exception e){\n            e.printStackTrace();\n        }finally {\n            AtlasFileLock.getInstance().unLock(LIB_DIR);\n        }\n\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/StringUtils.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.util;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class StringUtils {\n\n    public static final String EMPTY = \"\";\n\n    public static boolean isEmpty(String str) {\n        if (str == null || str.length() == 0) {\n            return true;\n        }\n        return false;\n    }\n\n    public static boolean isNotEmpty(String str) {\n        return (str != null && str.length() > 0);\n    }\n    \n    public static boolean startWith(String str, String prefix) {\n        if (str == null || prefix == null) {\n            return false;\n        }\n        return str.startsWith(prefix);\n    }\n\n    public static boolean equals(String str1, String str2) {\n        if (str1 == null) {\n            return false;\n        }\n        return str1.equals(str2);\n    }\n\n    public static String substringAfter(String str, String separator) {\n        if (isEmpty(str)) {\n            return str;\n        }\n        if (separator == null) {\n            return \"\";\n        }\n        int pos = str.indexOf(separator);\n        if (pos == -1) {\n            return \"\";\n        }\n        return str.substring(pos + separator.length());\n    }\n\n    public static String substringBetween(String str, String open, String close) {\n        if (str == null || open == null || close == null) {\n            return null;\n        }\n        int start = str.indexOf(open);\n        if (start != -1) {\n            int end = str.indexOf(close, start + open.length());\n            if (end != -1) {\n                return str.substring(start + open.length(), end);\n            }\n        }\n        return null;\n    }\n\n//    public static String replace(String text, String searchString, String replacement) {\n//        return replace(text, searchString, replacement, -1);\n//    }\n//\n//    public static String replace(String text, String searchString, String replacement, int max) {\n//        if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) {\n//            return text;\n//        }\n//        int start = 0;\n//        int end = text.indexOf(searchString, start);\n//        if (end == -1) {\n//            return text;\n//        }\n//        int replLength = searchString.length();\n//        int increase = replacement.length() - replLength;\n//        increase = (increase < 0 ? 0 : increase);\n//        increase *= (max < 0 ? 16 : (max > 64 ? 64 : max));\n//        StringBuilder buf = new StringBuilder(text.length() + increase);\n//        while (end != -1) {\n//            buf.append(text.substring(start, end)).append(replacement);\n//            start = end + replLength;\n//            if (--max == 0) {\n//                break;\n//            }\n//            end = text.indexOf(searchString, start);\n//        }\n//        buf.append(text.substring(start));\n//        return buf.toString();\n//    }\n\n//    public static boolean endsWith(String str, String suffix) {\n//        return endsWith(str, suffix, false);\n//    }\n//\n//    private static boolean endsWith(String str, String suffix, boolean ignoreCase) {\n//        if (str == null || suffix == null) {\n//            return (str == null && suffix == null);\n//        }\n//        if (suffix.length() > str.length()) {\n//            return false;\n//        }\n//        int strOffset = str.length() - suffix.length();\n//        return str.regionMatches(ignoreCase, strOffset, suffix, 0, suffix.length());\n//    }\n\n    /**\n     * <p>Splits the provided text into an array, separators specified.\n     * This is an alternative to using StringTokenizer.</p>\n     *\n     * <p>The separator is not included in the returned String array.\n     * Adjacent separators are treated as one separator.\n     * For more control over the split use the StrTokenizer class.</p>\n     *\n     * <p>A <code>null</code> input String returns <code>null</code>.\n     * A <code>null</code> separatorChars splits on whitespace.</p>\n     *\n     * <pre>\n     * StringUtils.split(null, *)         = null\n     * StringUtils.split(\"\", *)           = []\n     * StringUtils.split(\"abc def\", null) = [\"abc\", \"def\"]\n     * StringUtils.split(\"abc def\", \" \")  = [\"abc\", \"def\"]\n     * StringUtils.split(\"abc  def\", \" \") = [\"abc\", \"def\"]\n     * StringUtils.split(\"ab:cd:ef\", \":\") = [\"ab\", \"cd\", \"ef\"]\n     * </pre>\n     *\n     * @param str  the String to parse, may be null\n     * @param separatorChars  the characters used as the delimiters,\n     *  <code>null</code> splits on whitespace\n     * @return an array of parsed Strings, <code>null</code> if null String input\n     */    \n    public static String[] split(String str, String separatorChars) {\n        return splitWorker(str, separatorChars, -1, false);\n    }\n    \n    /**\n     * Performs the logic for the <code>split</code> and \n     * <code>splitPreserveAllTokens</code> methods that return a maximum array \n     * length.\n     *\n     * @param str  the String to parse, may be <code>null</code>\n     * @param separatorChars the separate character\n     * @param max  the maximum number of elements to include in the\n     *  array. A zero or negative value implies no limit.\n     * @param preserveAllTokens if <code>true</code>, adjacent separators are\n     * treated as empty token separators; if <code>false</code>, adjacent\n     * separators are treated as one separator.\n     * @return an array of parsed Strings, <code>null</code> if null String input\n     */\n    private static String[] splitWorker(String str, String separatorChars, int max, boolean preserveAllTokens) {\n        // Performance tuned for 2.0 (JDK1.4)\n        // Direct code is quicker than StringTokenizer.\n        // Also, StringTokenizer uses isSpace() not isWhitespace()\n\n        if (str == null) {\n            return null;\n        }\n        int len = str.length();\n        if (len == 0) {\n            return new String[0];\n        }\n        List<String> list = new ArrayList<String>();\n        int sizePlus1 = 1;\n        int i = 0, start = 0;\n        boolean match = false;\n        boolean lastMatch = false;\n        if (separatorChars == null) {\n            // Null separator means use whitespace\n            while (i < len) {\n                if (Character.isWhitespace(str.charAt(i))) {\n                    if (match || preserveAllTokens) {\n                        lastMatch = true;\n                        if (sizePlus1++ == max) {\n                            i = len;\n                            lastMatch = false;\n                        }\n                        list.add(str.substring(start, i));\n                        match = false;\n                    }\n                    start = ++i;\n                    continue;\n                }\n                lastMatch = false;\n                match = true;\n                i++;\n            }\n        } else if (separatorChars.length() == 1) {\n            // Optimise 1 character case\n            char sep = separatorChars.charAt(0);\n            while (i < len) {\n                if (str.charAt(i) == sep) {\n                    if (match || preserveAllTokens) {\n                        lastMatch = true;\n                        if (sizePlus1++ == max) {\n                            i = len;\n                            lastMatch = false;\n                        }\n                        list.add(str.substring(start, i));\n                        match = false;\n                    }\n                    start = ++i;\n                    continue;\n                }\n                lastMatch = false;\n                match = true;\n                i++;\n            }\n        } else {\n            // standard case\n            while (i < len) {\n                if (separatorChars.indexOf(str.charAt(i)) >= 0) {\n                    if (match || preserveAllTokens) {\n                        lastMatch = true;\n                        if (sizePlus1++ == max) {\n                            i = len;\n                            lastMatch = false;\n                        }\n                        list.add(str.substring(start, i));\n                        match = false;\n                    }\n                    start = ++i;\n                    continue;\n                }\n                lastMatch = false;\n                match = true;\n                i++;\n            }\n        }\n        if (match || (preserveAllTokens && lastMatch)) {\n            list.add(str.substring(start, i));\n        }\n        return (String[]) list.toArray(new String[list.size()]);\n    }\n\n//    public static String join(Object[] array, String separator) {\n//        if (array == null) {\n//            return null;\n//        }\n//        return join(array, separator, 0, array.length);\n//    }\n//\n//    public static String join(Object[] array, String separator, int startIndex, int endIndex) {\n//        if (array == null) {\n//            return null;\n//        }\n//        if (separator == null) {\n//            separator = EMPTY;\n//        }\n//\n//        // endIndex - startIndex > 0:   Len = NofStrings *(len(firstString) + len(separator))\n//        //           (Assuming that all Strings are roughly equally long)\n//        int bufSize = (endIndex - startIndex);\n//        if (bufSize <= 0) {\n//            return EMPTY;\n//        }\n//\n//        bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString().length())\n//                + separator.length());\n//\n//        StringBuilder buf = new StringBuilder(bufSize);\n//\n//        for (int i = startIndex; i < endIndex; i++) {\n//            if (i > startIndex) {\n//                buf.append(separator);\n//            }\n//            if (array[i] != null) {\n//                buf.append(array[i]);\n//            }\n//        }\n//        return buf.toString();\n//    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/WrapperUtil.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.util;\n\nimport android.app.ActivityManager;\nimport android.app.Application;\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.content.pm.ApplicationInfo;\nimport android.content.pm.PackageInfo;\nimport android.content.pm.PackageManager;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Created by guanjie on 15/7/6.\n */\npublic class WrapperUtil {\n\n    final static String   TAG                = \"Utils\";\n\n    static HashMap<String,Object> keyPointLog = new HashMap<String,Object>();\n\n    public static boolean isDebugMode(Application application){\n        final ApplicationInfo app_info = application.getApplicationInfo();\n        return (app_info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;\n    }\n\n    public static PackageInfo getPackageInfo(Application mApplication){\n        PackageInfo packageInfo = null;\n        // 获取当前的版本号\n        try {\n            PackageManager packageManager = mApplication.getPackageManager();\n            packageInfo = packageManager.getPackageInfo(mApplication.getPackageName(), 0);\n        } catch (Exception e) {\n            // 不可能发生\n            Log.e(TAG, \"Error to get PackageInfo >>>\", e);\n            packageInfo = new PackageInfo();\n            packageInfo.versionName = \"\";\n            packageInfo.versionCode = 1;\n        }\n        return packageInfo;\n    }\n\n    public static void persisitKeyPointLog(String newVersion){\n        String logs = keyPointLog.toString();\n        SharedPreferences preferences = RuntimeVariables.androidApplication.getSharedPreferences(\"atlas_log\",Context.MODE_PRIVATE);\n        preferences.edit().putString(newVersion,logs).commit();\n    }\n\n    public static String getLastDDUpdateKeyPointLog(String currentVersion){\n        SharedPreferences preferences = RuntimeVariables.androidApplication.getSharedPreferences(\"atlas_log\",Context.MODE_PRIVATE);\n        String logs = preferences.getString(currentVersion,\"\");\n        return logs;\n    }\n\n    public static void clearLastDDUpdateKeyPointLog(String currentVersion){\n        SharedPreferences preferences = RuntimeVariables.androidApplication.getSharedPreferences(\"atlas_log\",Context.MODE_PRIVATE);\n        preferences.edit().clear();\n        preferences.edit().commit();\n    }\n\n    public static void appendLog(String key,Object value){\n        keyPointLog.put(key,value);\n    }\n\n    public static Map<String,Object> getKeyPointLog(){\n        return keyPointLog;\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/log/IAlarmer.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.util.log;\n\n/**\n * Created by guanjie on 16/9/21.\n */\npublic interface IAlarmer {\n\n    public void commitFail(final String module, final String monitorPoint, final String errorCode, final String errorMsg);\n\n    public void commitSuccess(final String module, final String monitorPoint);\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/log/ILog.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.util.log;\n\n/**\n * Created by guanjie on 15/1/30.\n */\npublic interface ILog {\n    public void v(String tag,String msg);\n    public void i(String tag,String msg);\n    public void d(String tag,String msg);\n    public void w(String tag,String msg);\n    public void e(String tag,String msg);\n    public void e(String tag,String msg,Throwable e);    \n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/log/IMonitor.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.util.log;\n\nimport java.util.Map;\n\npublic interface IMonitor {\n\n\tpublic void report(String errCode, Map<String, Object> detail, Throwable throwable);\n\n}"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/log/impl/AtlasAlarmer.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.util.log.impl;\n\nimport android.taobao.atlas.util.log.IAlarmer;\n\n/**\n * Created by guanjie on 16/9/21.\n */\npublic class AtlasAlarmer implements IAlarmer {\n\n    private static AtlasAlarmer singleton;\n    private static IAlarmer externalMonitor;\n\n\n    public static synchronized AtlasAlarmer getInstance(){\n        if (singleton == null){\n            singleton = new AtlasAlarmer();\n        }\n        return singleton;\n    }\n\n    public static void setExternalAlarmer(IAlarmer alarmer){\n        externalMonitor = alarmer;\n    }\n\n    @Override\n    public void commitFail(String module, String monitorPoint, String errorCode, String errorMsg) {\n\n    }\n\n    @Override\n    public void commitSuccess(String module, String monitorPoint) {\n\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/log/impl/AtlasLog.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.util.log.impl;\n\nimport android.taobao.atlas.util.log.ILog;\nimport android.util.Log;\n\n/**\n * Created by guanjie on 15/1/30.\n */\npublic class AtlasLog{\n\n    private static ILog externalLogger;\n    private static final String PreFix = \"Atlas.\";\n\n    public static void setExternalLogger(ILog logger){\n        externalLogger = logger;\n    }\n    \n    public static void v(String tag, String msg) {\n        if(externalLogger!=null){\n            externalLogger.v(PreFix.concat(tag),msg);\n        } else {\n            Log.v(tag,msg);\n        }\n    }\n    \n    public static void i(String tag, String msg) {\n        if(externalLogger!=null){\n            externalLogger.i(PreFix.concat(tag),msg);\n        } else {\n            Log.i(tag,msg);        \t\n        }\n    }\n\n    public static void d(String tag, String msg) {\n        if(externalLogger!=null){\n            externalLogger.d(PreFix.concat(tag),msg);\n        } else {\n            Log.d(tag,msg);        \t\n        }\n    }\n\n    public static void w(String tag, String msg) {\n        Log.w(tag,msg);\n        if(externalLogger!=null){\n            externalLogger.w(PreFix.concat(tag),msg);\n        }\n    }\n\n    public static  void e(String tag, String msg) {\n        if(externalLogger!=null){\n            externalLogger.e(PreFix.concat(tag),msg);\n        } else {\n            Log.e(tag,msg);        \t\n        }\n    }\n    \n    public static void e(String tag, String msg, Throwable e) {\n        if(externalLogger!=null){\n            externalLogger.e(PreFix.concat(tag),msg,e);\n        } else {\n            Log.e(tag,msg,e);        \t\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/util/log/impl/AtlasMonitor.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.util.log.impl;\n\nimport java.util.Map;\n\nimport android.taobao.atlas.util.log.IMonitor;\n\npublic class AtlasMonitor {\n\n    private static IMonitor externalMonitor;\n    private static AtlasMonitor singleton;\n\n    //容器稳定性stage\n    public static final String CONTAINER_BUNDLE_SOURCE_UNZIP_FAIL = \"container_bundle_unzip_fail\";\n    public static final String CONTAINER_BUNDLE_SOURCE_MISMATCH = \"container_bundle_mismatch\";\n    public static final String CONTAINER_SOLIB_UNZIP_FAIL = \"container_solib_unzip_fail\";\n    public static final String CONTAINER_DEXOPT_FAIL = \"container_dexopt_fail\";\n    public static final String CONTAINER_APPEND_ASSETPATH_FAIL = \"container_append_assetpath_fail\";\n    public static final String CONTAINER_BUNDLEINFO_PARSE_FAIL = \"container_bundleinfo_parse_fail\";\n    public static final String CONTAINER_LOADEDAPK_CHANGE = \"container_loadapk_change\";\n    public static final String WALKROUND_GETLAYOUT = \"walkround_getlayout\";\n    public static final String VALIDATE_CLASSES = \"validate_classes\";\n    public static final String INSTALL = \"install\";\n\n    public static final String INSTRUMENTATION_HOOK_CLASS_NOT_FOUND_EXCEPTION\n        = \"instrumentation_hook_class_not_found_exception\";\n    public static final String ACTIVITY_THREAD_HOOK_BAD_TOKEN_EXCEPTION = \"activity_thread_hook_bad_token_exception\";\n    public static final String ACTIVITY_THREAD_HOOK_EXCEPTION = \"activity_thread_hook_exception\";\n    public static final String ACTIVITY_THREAD_HOOK_CLASS_NOT_FOUND_EXCEPTION = \"activity_thread_hook_class_not_found_exception\";\n\n    public static final String NEWCOMPONENT_SERVICE = \"newcomponent_service\";\n\n\n    //动态部署稳定性stage\n    public static final String DD_BUNDLE_MISMATCH = \"dd_bundle_mismatch\";\n    public static final String DD_BUNDLE_RESOLVEFAIL = \"bundle_resolve_fail\";\n    public static final String BUNDLE_DEPENDENCY_ERROR = \"bundle_dependency_error\";\n    public static final String ADD_BAD_APP_TOKEN = \"add_bad_app_token\";\n    public static final String ADD_BAD_SUBWINDOW_TOKEN = \"add_bad_subwindow_token\";\n\n\n\n\n\n\n    public static synchronized AtlasMonitor getInstance(){\n    \tif (singleton == null){\n    \t\tsingleton = new AtlasMonitor();\n    \t}\n\t\treturn singleton;\n    }\n    \n    public static void setExternalMonitor(IMonitor monitor){\n    \texternalMonitor = monitor;\n    }\n\n \tpublic void report(String errCode, Map<String, Object> detail, Throwable throwable) {\n        if(externalMonitor != null) {\n            externalMonitor.report(errCode, detail, throwable);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/android/taobao/atlas/versionInfo/BaselineInfoManager.java",
    "content": "/*\n *\n *                                Apache License\n *                          Version 2.0, January 2004\n *                       http://www.apache.org/licenses/\n *\n *  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *  1. Definitions.\n *\n *     \"License\" shall mean the terms and conditions for use, reproduction,\n *     and distribution as defined by Sections 1 through 9 of this document.\n *\n *     \"Licensor\" shall mean the copyright owner or entity authorized by\n *     the copyright owner that is granting the License.\n *\n *     \"Legal Entity\" shall mean the union of the acting entity and all\n *     other entities that control, are controlled by, or are under common\n *     control with that entity. For the purposes of this definition,\n *     \"control\" means (i) the power, direct or indirect, to cause the\n *     direction or management of such entity, whether by contract or\n *     otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *     outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *     \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *     exercising permissions granted by this License.\n *\n *     \"Source\" form shall mean the preferred form for making modifications,\n *     including but not limited to software source code, documentation\n *     source, and configuration files.\n *\n *     \"Object\" form shall mean any form resulting from mechanical\n *     transformation or translation of a Source form, including but\n *     not limited to compiled object code, generated documentation,\n *     and conversions to other media types.\n *\n *     \"Work\" shall mean the work of authorship, whether in Source or\n *     Object form, made available under the License, as indicated by a\n *     copyright notice that is included in or attached to the work\n *     (an example is provided in the Appendix below).\n *\n *     \"Derivative Works\" shall mean any work, whether in Source or Object\n *     form, that is based on (or derived from) the Work and for which the\n *     editorial revisions, annotations, elaborations, or other modifications\n *     represent, as a whole, an original work of authorship. For the purposes\n *     of this License, Derivative Works shall not include works that remain\n *     separable from, or merely link (or bind by name) to the interfaces of,\n *     the Work and Derivative Works thereof.\n *\n *     \"Contribution\" shall mean any work of authorship, including\n *     the original version of the Work and any modifications or additions\n *     to that Work or Derivative Works thereof, that is intentionally\n *     submitted to Licensor for inclusion in the Work by the copyright owner\n *     or by an individual or Legal Entity authorized to submit on behalf of\n *     the copyright owner. For the purposes of this definition, \"submitted\"\n *     means any form of electronic, verbal, or written communication sent\n *     to the Licensor or its representatives, including but not limited to\n *     communication on electronic mailing lists, source code control systems,\n *     and issue tracking systems that are managed by, or on behalf of, the\n *     Licensor for the purpose of discussing and improving the Work, but\n *     excluding communication that is conspicuously marked or otherwise\n *     designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *     \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *     on behalf of whom a Contribution has been received by Licensor and\n *     subsequently incorporated within the Work.\n *\n *  2. Grant of Copyright License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     copyright license to reproduce, prepare Derivative Works of,\n *     publicly display, publicly perform, sublicense, and distribute the\n *     Work and such Derivative Works in Source or Object form.\n *\n *  3. Grant of Patent License. Subject to the terms and conditions of\n *     this License, each Contributor hereby grants to You a perpetual,\n *     worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *     (except as stated in this section) patent license to make, have made,\n *     use, offer to sell, sell, import, and otherwise transfer the Work,\n *     where such license applies only to those patent claims licensable\n *     by such Contributor that are necessarily infringed by their\n *     Contribution(s) alone or by combination of their Contribution(s)\n *     with the Work to which such Contribution(s) was submitted. If You\n *     institute patent litigation against any entity (including a\n *     cross-claim or counterclaim in a lawsuit) alleging that the Work\n *     or a Contribution incorporated within the Work constitutes direct\n *     or contributory patent infringement, then any patent licenses\n *     granted to You under this License for that Work shall terminate\n *     as of the date such litigation is filed.\n *\n *  4. Redistribution. You may reproduce and distribute copies of the\n *     Work or Derivative Works thereof in any medium, with or without\n *     modifications, and in Source or Object form, provided that You\n *     meet the following conditions:\n *\n *     (a) You must give any other recipients of the Work or\n *         Derivative Works a copy of this License; and\n *\n *     (b) You must cause any modified files to carry prominent notices\n *         stating that You changed the files; and\n *\n *     (c) You must retain, in the Source form of any Derivative Works\n *         that You distribute, all copyright, patent, trademark, and\n *         attribution notices from the Source form of the Work,\n *         excluding those notices that do not pertain to any part of\n *         the Derivative Works; and\n *\n *     (d) If the Work includes a \"NOTICE\" text file as part of its\n *         distribution, then any Derivative Works that You distribute must\n *         include a readable copy of the attribution notices contained\n *         within such NOTICE file, excluding those notices that do not\n *         pertain to any part of the Derivative Works, in at least one\n *         of the following places: within a NOTICE text file distributed\n *         as part of the Derivative Works; within the Source form or\n *         documentation, if provided along with the Derivative Works; or,\n *         within a display generated by the Derivative Works, if and\n *         wherever such third-party notices normally appear. The contents\n *         of the NOTICE file are for informational purposes only and\n *         do not modify the License. You may add Your own attribution\n *         notices within Derivative Works that You distribute, alongside\n *         or as an addendum to the NOTICE text from the Work, provided\n *         that such additional attribution notices cannot be construed\n *         as modifying the License.\n *\n *     You may add Your own copyright statement to Your modifications and\n *     may provide additional or different license terms and conditions\n *     for use, reproduction, or distribution of Your modifications, or\n *     for any such Derivative Works as a whole, provided Your use,\n *     reproduction, and distribution of the Work otherwise complies with\n *     the conditions stated in this License.\n *\n *  5. Submission of Contributions. Unless You explicitly state otherwise,\n *     any Contribution intentionally submitted for inclusion in the Work\n *     by You to the Licensor shall be under the terms and conditions of\n *     this License, without any additional terms or conditions.\n *     Notwithstanding the above, nothing herein shall supersede or modify\n *     the terms of any separate license agreement you may have executed\n *     with Licensor regarding such Contributions.\n *\n *  6. Trademarks. This License does not grant permission to use the trade\n *     names, trademarks, service marks, or product names of the Licensor,\n *     except as required for reasonable and customary use in describing the\n *     origin of the Work and reproducing the content of the NOTICE file.\n *\n *  7. Disclaimer of Warranty. Unless required by applicable law or\n *     agreed to in writing, Licensor provides the Work (and each\n *     Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *     implied, including, without limitation, any warranties or conditions\n *     of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *     PARTICULAR PURPOSE. You are solely responsible for determining the\n *     appropriateness of using or redistributing the Work and assume any\n *     risks associated with Your exercise of permissions under this License.\n *\n *  8. Limitation of Liability. In no event and under no legal theory,\n *     whether in tort (including negligence), contract, or otherwise,\n *     unless required by applicable law (such as deliberate and grossly\n *     negligent acts) or agreed to in writing, shall any Contributor be\n *     liable to You for damages, including any direct, indirect, special,\n *     incidental, or consequential damages of any character arising as a\n *     result of this License or out of the use or inability to use the\n *     Work (including but not limited to damages for loss of goodwill,\n *     work stoppage, computer failure or malfunction, or any and all\n *     other commercial damages or losses), even if such Contributor\n *     has been advised of the possibility of such damages.\n *\n *  9. Accepting Warranty or Additional Liability. While redistributing\n *     the Work or Derivative Works thereof, You may choose to offer,\n *     and charge a fee for, acceptance of support, warranty, indemnity,\n *     or other liability obligations and/or rights consistent with this\n *     License. However, in accepting such obligations, You may act only\n *     on Your own behalf and on Your sole responsibility, not on behalf\n *     of any other Contributor, and only if You agree to indemnify,\n *     defend, and hold each Contributor harmless for any liability\n *     incurred by, or claims asserted against, such Contributor by reason\n *     of your accepting any such warranty or additional liability.\n *\n *  END OF TERMS AND CONDITIONS\n *\n *  APPENDIX: How to apply the Apache License to your work.\n *\n *     To apply the Apache License to your work, attach the following\n *     boilerplate notice, with the fields enclosed by brackets \"[]\"\n *     replaced with your own identifying information. (Don't include\n *     the brackets!)  The text should be enclosed in the appropriate\n *     comment syntax for the file format. We also recommend that a\n *     file or class name and description of purpose be included on the\n *     same \"printed page\" as the copyright notice for easier\n *     identification within third-party archives.\n *\n *  Copyright 2016 Alibaba Group\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n *\n *\n */\n\npackage android.taobao.atlas.versionInfo;\n\nimport android.content.pm.PackageInfo;\nimport android.taobao.atlas.framework.Atlas;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.taobao.atlas.util.WrapperUtil;\nimport android.text.TextUtils;\nimport android.util.Pair;\n\nimport java.io.*;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.concurrent.ConcurrentHashMap;\n\n/**\n * Created by guanjie on 15/9/10.\n */\npublic class BaselineInfoManager{\n\n    private static BaselineInfoManager sBaseInfoManager;\n\n    private Object mVersionManager;\n    private String dexPatchStorageLocation;\n    private String updateBundleStorageLocation;\n\n    public synchronized static BaselineInfoManager instance(){\n        if(sBaseInfoManager==null){\n            sBaseInfoManager = new BaselineInfoManager();\n        }\n        return sBaseInfoManager;\n    }\n\n    private BaselineInfoManager(){\n    }\n\n    @Override\n    public String toString(){\n        return mVersionManager.toString();\n    }\n\n    public void reset(){\n        try {\n            mVersionManager.getClass().getDeclaredMethod(\"reset\").invoke(mVersionManager);\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n    }\n\n    public void removeBaseLineInfo(){\n        try {\n            mVersionManager.getClass().getDeclaredMethod(\"removeBaseLineInfo\").invoke(mVersionManager);\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n    }\n\n    public String getBaseBundleVersion(String bundleName){\n        try {\n            return (String)mVersionManager.getClass().getDeclaredMethod(\"getBaseBundleVersion\",String.class).invoke(mVersionManager,bundleName);\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n        return null;\n    }\n\n//    public String getDexPatchStorageLocation(){\n//        if(dexPatchStorageLocation==null) {\n//            try {\n//                dexPatchStorageLocation = (String) mVersionManager.getClass().getDeclaredField(\"DEXPATCH_STORAGE_LOCATION\").get(mVersionManager);\n//            } catch (Throwable e) {\n//                e.printStackTrace();\n//            }\n//        }\n//        return dexPatchStorageLocation;\n//    }\n//\n//    public String getUpdateStorageLocation(){\n//        if(updateBundleStorageLocation==null) {\n//            try {\n//                updateBundleStorageLocation = (String) mVersionManager.getClass().getDeclaredField(\"CURRENT_STORAGE_LOCATION\").get(mVersionManager);\n//            } catch (Throwable e) {\n//                e.printStackTrace();\n//            }\n//        }\n//        return updateBundleStorageLocation;\n//    }\n\n    public long getDexPatchBundleVersion(String bundleName){\n        try {\n            return (long)mVersionManager.getClass().getDeclaredMethod(\"getDexPatchBundleVersion\",String.class).invoke(mVersionManager,bundleName);\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n        return -1;\n    }\n\n    public ConcurrentHashMap<String,Long> getDexPatchBundles(){\n        try {\n            Field dexPatchBundles = mVersionManager.getClass().getDeclaredField(\"dexPatchBundles\");\n            if (!dexPatchBundles.isAccessible()){\n                dexPatchBundles.setAccessible(true);\n            }\n            return (ConcurrentHashMap<String,Long>) dexPatchBundles.get(mVersionManager);\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n        return null;\n    }\n\n    public boolean isUpdated(String bundleName){\n        try {\n            return (boolean)mVersionManager.getClass().getDeclaredMethod(\"isUpdated\",String.class).invoke(mVersionManager,bundleName);\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n        return false;\n    }\n\n    public boolean isDexPatched(String bundleName){\n        try {\n            return (boolean)mVersionManager.getClass().getDeclaredMethod(\"isDexPatched\",String.class).invoke(mVersionManager,bundleName);\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n        return false;\n    }\n\n    public boolean isCachePreVersion(){\n        try {\n            return (boolean)mVersionManager.getClass().getDeclaredMethod(\"isCachePreVersion\").invoke(mVersionManager);\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n        return false;\n    }\n\n    public String currentVersionName(){\n        try {\n            return (String)mVersionManager.getClass().getDeclaredMethod(\"currentVersionName\").invoke(mVersionManager);\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n        return \"\";\n    }\n\n    public void rollbackHardly(){\n        try {\n            mVersionManager.getClass().getDeclaredMethod(\"rollbackHardly\").invoke(mVersionManager);\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n    }\n\n    public String lastVersionName(){\n        try {\n            return (String)mVersionManager.getClass().getDeclaredMethod(\"lastVersionName\").invoke(mVersionManager);\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n        return \"\";\n    }\n\n    public Set<String> getUpdateBundles(){\n        try {\n            return (Set<String>)mVersionManager.getClass().getDeclaredMethod(\"getUpdateBundles\").invoke(mVersionManager);\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n        return new HashMap<String,String>().keySet();\n    }\n\n    private void rollbackInternal(){\n        try {\n            mVersionManager.getClass().getDeclaredMethod(\"rollback\").invoke(mVersionManager);\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n    }\n\n    public void rollback(){\n        if (!TextUtils.isEmpty(lastVersionName())) {\n            List<String> bundles = new ArrayList<String>(getUpdateBundles());\n            PackageInfo info = WrapperUtil.getPackageInfo(RuntimeVariables.androidApplication);\n            if (RuntimeVariables.sCachePreVersionBundles && bundles != null && !info.versionName.equals(lastVersionName()) && bundles.size() > 0) {\n                rollbackInternal();\n            } else {\n                //回滚到安装时期\n                rollbackHardly();\n            }\n        } else {\n            rollbackHardly();\n        }\n    }\n\n    public void saveBaselineInfo(String newBaselineVersion, HashMap<String,String> infos,String storageLocation) throws IOException{\n        try {\n            mVersionManager.getClass().getDeclaredMethod(\"saveUpdateInfo\",String.class,HashMap.class,boolean.class,String.class).invoke(\n                    mVersionManager,newBaselineVersion,infos,RuntimeVariables.sCachePreVersionBundles,storageLocation\n            );\n        } catch (IllegalAccessException e) {\n            e.printStackTrace();\n        } catch (InvocationTargetException e) {\n            e.printStackTrace();\n        } catch (NoSuchMethodException e) {\n            e.printStackTrace();\n        }\n\n        WrapperUtil.persisitKeyPointLog(newBaselineVersion);\n    }\n\n    public void saveDexPathInfo(HashMap<String,String> infos,String storageLocation) throws IOException{\n        try {\n            mVersionManager.getClass().getDeclaredMethod(\"saveDexPatchInfo\",HashMap.class,String.class).invoke(\n                    mVersionManager,infos,storageLocation);\n        } catch (IllegalAccessException e) {\n            e.printStackTrace();\n        } catch (InvocationTargetException e) {\n            e.printStackTrace();\n        } catch (NoSuchMethodException e) {\n            e.printStackTrace();\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-core/src/main/java/org/osgi/framework/Bundle.java",
    "content": "\npackage org.osgi.framework;\n\nimport java.net.URL;\n\n/**\n * An installed bundle in the Framework.\n *\n * <p>A <tt>Bundle</tt> object is the access point to define the life cycle\n * of an installed bundle. Each bundle installed in the OSGi environment\n * will have an associated <tt>Bundle</tt> object.\n *\n * <p>A bundle will have a unique identity, a <tt>long</tt>, chosen by the\n * Framework. This identity will not change during the life cycle of a bundle, even when\n * the bundle is updated. Uninstalling and then reinstalling the bundle will create\n * a new unique identity.\n *\n * <p>A bundle can be in one of six states:\n * <ul>\n * <li>{@link #UNINSTALLED}\n * <li>{@link #INSTALLED}\n * <li>{@link #RESOLVED}\n * <li>{@link #STARTING}\n * <li>{@link #STOPPING}\n * <li>{@link #ACTIVE}\n * </ul>\n * <p>Values assigned to these states have no specified ordering;\n * they represent bit values that may be ORed together to determine if\n * a bundle is in one of the valid states.\n *\n * <p>A bundle should only execute code when its state is one of\n * <tt>STARTING</tt>, <tt>ACTIVE</tt>, or <tt>STOPPING</tt>.\n * An <tt>UNINSTALLED</tt> bundle can not be set to another state; it\n * is a zombie and can only be reached because invalid references are kept somewhere.\n *\n * <p>The Framework is the only entity that is allowed to\n * create <tt>Bundle</tt> objects, and these objects are only valid\n * within the Framework that created them.\n *\n * @version $Revision: 1.1 $\n * @author Open Services Gateway Initiative\n */\npublic abstract interface Bundle\n{\n    /**\n\t * This bundle is uninstalled and may not be used.\n\t *\n\t * <p>The <tt>UNINSTALLED</tt> state is only visible after a bundle\n\t * is uninstalled; the bundle is in an unusable state\n\t * and all references to the <tt>Bundle</tt> object should be released\n\t * immediately.\n\t * <p>The value of <tt>UNINSTALLED</tt> is 0x00000001.\n\t */\n    public static final int UNINSTALLED = 0x00000001;\n\n    /**\n\t * This bundle is installed but not yet resolved.\n\t *\n\t * <p>A bundle is in the <tt>INSTALLED</tt> state when it has been installed\n\t * in the Framework but cannot run.\n\t * <p>This state is visible if the bundle's code dependencies are not resolved.\n\t * The Framework may attempt to resolve an <tt>INSTALLED</tt> bundle's\n\t * code dependencies and move the bundle to the <tt>RESOLVED</tt> state.\n\t * <p>The value of <tt>INSTALLED</tt> is 0x00000002.\n\t */\n    public static final int INSTALLED = 0x00000002;\n\n    /**\n\t * This bundle is resolved and is able to be started.\n\t *\n\t * <p>A bundle is in the <tt>RESOLVED</tt> state when the Framework has successfully\n\t * resolved the bundle's dependencies. These dependencies include:\n\t * <ul>\n\t * <li>The bundle's class path from its {@link Constants#BUNDLE_CLASSPATH} Manifest header.\n\t * <li>The bundle's package dependencies from\n\t * its {@link Constants#EXPORT_PACKAGE}and {@link Constants#IMPORT_PACKAGE} Manifest headers.\n\t * </ul>\n\t * <p>Note that the bundle is not active yet. A bundle must be put in the\n\t * <tt>RESOLVED</tt> state before it can be started. The Framework may attempt to\n\t * resolve a bundle at any time.\n\t * <p>The value of <tt>RESOLVED</tt> is 0x00000004.\n\t */\n    public static final int RESOLVED = 0x00000004;\n\n\n    public static final int STARTING = 0x00000008;\n\n\n    public static final int STOPPING = 0x00000010;\n\n    /**\n\t * This bundle is now running.\n\t *\n\t * <p>A bundle is in the <tt>ACTIVE</tt> state when it has been successfully started.\n\t * <p>The value of <tt>ACTIVE</tt> is 0x00000020.\n\t */\n    public static final int ACTIVE    = 0x00000020;\n\n    /**\n\t * Returns this bundle's current state.\n\t *\n\t * <p>A bundle can be in only one state at any time.\n\t *\n\t * @return An element of <tt>UNINSTALLED</tt>, <tt>INSTALLED</tt>,\n\t * <tt>RESOLVED</tt>, <tt>STARTING</tt>, <tt>STOPPING</tt>,\n\t * <tt>ACTIVE</tt>.\n\t */\n    public abstract int getState();\n\n\n    public abstract void start() throws BundleException;\n\n    public abstract void stop() throws BundleException;\n\n    /**\n\t * Uninstalls this bundle.\n\t *\n\t * <p>This method causes the Framework to notify other bundles that this bundle\n\t * is being uninstalled, and then puts this bundle into the <tt>UNINSTALLED</tt>\n\t * state. The Framework will remove any resources related to this\n\t * bundle that it is able to remove.\n\t *\n\t * <p>If this bundle has exported any packages, the Framework will\n\t * continue to make these packages available to their importing bundles\n\t * until the <tt>PackageAdmin.refreshPackages</tt> method has been called\n\t * or the Framework is relaunched.\n\t *\n\t * <p>The following steps are required to uninstall a bundle:\n\t * <ol>\n\t * <li>If this bundle's state is <tt>UNINSTALLED</tt> then\n\t * an <tt>IllegalStateException</tt> is thrown.\n\t *\n\t * <li>If this bundle's state is <tt>ACTIVE</tt>, <tt>STARTING</tt> or <tt>STOPPING</tt>,\n\t * this bundle is stopped as described in the <tt>Bundle.stop</tt> method.\n\t * If <tt>Bundle.stop</tt> throws an exception, a Framework event of type\n\t * {@link FrameworkEvent#ERROR}is broadcast containing the exception.\n\t *\n\t * <li>This bundle's state is set to <tt>UNINSTALLED</tt>.\n\t *\n\t * <li>A bundle event of type {@link BundleEvent#UNINSTALLED}is broadcast.\n\t *\n\t * <li>This bundle and any persistent storage area provided for this bundle\n\t * by the Framework are removed.\n\t * </ol>\n\t *\n\t * <b>Preconditions</b>\n\t * <ul>\n\t * <li><tt>getState()</tt> not in {<tt>UNINSTALLED</tt>}.\n\t * </ul>\n\t * <b>Postconditions, no exceptions thrown</b>\n\t * <ul>\n\t * <li><tt>getState()</tt> in {<tt>UNINSTALLED</tt>}.\n\t * <li>This bundle has been uninstalled.\n\t * </ul>\n\t * <b>Postconditions, when an exception is thrown</b>\n\t * <ul>\n\t * <li><tt>getState()</tt> not in {<tt>UNINSTALLED</tt>}.\n\t * <li>This Bundle has not been uninstalled.\n\t * </ul>\n\t *\n\t * @exception BundleException If the uninstall failed.\n\t * This can occur if another thread is attempting to change the bundle's state\n\t * and does not complete in a timely manner.\n\t * @exception java.lang.IllegalStateException If this\n\t * bundle has been uninstalled or this bundle tries to change its own state.\n\t * @exception java.lang.SecurityException If the caller does not have\n\t * the appropriate <tt>AdminPermission</tt>, and the Java Runtime Environment\n\t * supports permissions.\n\t * @see #stop()\n\t */\n    public abstract void uninstall() throws BundleException;\n\n    /**\n\t * Returns this bundle's identifier. The bundle is assigned a unique identifier by the Framework\n\t * when it is installed in the OSGi environment.\n\t *\n\t * <p>A bundle's unique identifier has the following attributes:\n\t * <ul>\n\t * <li>Is unique and persistent.\n\t * <li>Is a <tt>long</tt>.\n\t * <li>Its value is not reused for another bundle, even after the bundle is uninstalled.\n\t * <li>Does not change while the bundle remains installed.\n\t * <li>Does not change when the bundle is updated.\n\t * </ul>\n\t *\n\t * <p>This method will continue to return this bundle's unique identifier\n\t * while this bundle is in the <tt>UNINSTALLED</tt> state.\n\t *\n\t * @return The unique identifier of this bundle.\n\t */\n    public abstract long getBundleId();\n\n\n    public abstract String getLocation();\n\n    /**\n\t * Find the specified resource in this bundle.\n\t *\n\t * This bundle's class loader is called to search for the named resource.\n\t * If this bundle's state is <tt>INSTALLED</tt>, then only this bundle will\n\t * be searched for the specified resource. Imported packages cannot be searched\n\t * when a bundle has not been resolved.\n\t *\n\t * @param name The name of the resource.\n\t * See <tt>java.lang.ClassLoader.getResource</tt> for a description of\n\t * the format of a resource name.\n\t * @return a URL to the named resource, or <tt>null</tt> if the resource could\n\t * not be found or if the caller does not have\n\t * the <tt>AdminPermission</tt>, and the Java Runtime Environment supports permissions.\n\t *\n\t * @since 1.1\n\t * @exception java.lang.IllegalStateException If this bundle has been uninstalled.\n\t */\n    public abstract URL getResource(String name);\n\n}\n\n"
  },
  {
    "path": "atlas-core/src/main/java/org/osgi/framework/BundleEvent.java",
    "content": "\r\n\r\npackage org.osgi.framework;\r\n\r\nimport java.util.EventObject;\r\n\r\n/**\r\n * A Framework event describing a bundle lifecycle change.\r\n * <p><tt>BundleEvent</tt> objects are delivered to <tt>BundleListener</tt> objects when a change\r\n * occurs in a bundle's lifecycle. A type code is used to identify the event type\r\n * for future extendability.\r\n *\r\n * <p>OSGi reserves the right to extend the set of types.\r\n *\r\n * @version $Revision: 1.1 $\r\n * @author Open Services Gateway Initiative\r\n */\r\n\r\npublic class BundleEvent extends EventObject\r\n{\r\n    /**\r\n     * Bundle that had a change occur in its lifecycle.\r\n     */\r\n    private transient Bundle bundle;\r\n\r\n    /**\r\n     * Type of bundle lifecycle change.\r\n     */\r\n    private transient int type;\r\n\r\n    /**\r\n     * This bundle has been installed.\r\n     * <p>The value of <tt>INSTALLED</tt> is 0x00000001.\r\n     *\r\n     * @see BundleContext#installBundle\r\n     */\r\n    public final static int INSTALLED = 0x00000001;\r\n\r\n    /**\r\n     * This bundle has been started.\r\n     * <p>The value of <tt>STARTED</tt> is 0x00000002.\r\n     *\r\n     * @see Bundle#start\r\n     */\r\n    public final static int STARTED = 0x00000002;\r\n\r\n    /**\r\n     * This bundle has been stopped.\r\n     * <p>The value of <tt>STOPPED</tt> is 0x00000004.\r\n     *\r\n     * @see Bundle#stop\r\n     */\r\n    public final static int STOPPED = 0x00000004;\r\n\r\n    /**\r\n     * This bundle has been updated.\r\n     * <p>The value of <tt>UPDATED</tt> is 0x00000008.\r\n     *\r\n     * @see Bundle#update\r\n     */\r\n    public final static int UPDATED = 0x00000008;\r\n\r\n    /**\r\n     * This bundle has been uninstalled.\r\n     * <p>The value of <tt>UNINSTALLED</tt> is 0x00000010.\r\n     *\r\n     * @see Bundle#uninstall\r\n     */\r\n    public final static int UNINSTALLED = 0x00000010;\r\n\r\n    public final static int BEFORE_INSTALL = 10086;\r\n    public final static int BEFORE_STARTED = 10087;\r\n\r\n    /**\r\n     * Creates a bundle event of the specified type.\r\n     *\r\n     * @param type The event type.\r\n     * @param bundle The bundle which had a lifecycle change.\r\n     */\r\n\r\n    public BundleEvent(int type, Bundle bundle)\r\n    {\r\n        super(bundle);\r\n        this.bundle = bundle;\r\n        this.type = type;\r\n    }\r\n\r\n    /**\r\n     * Returns the bundle which had a lifecycle change.\r\n     * This bundle is the source of the event.\r\n     *\r\n     * @return A bundle that had a change occur in its lifecycle.\r\n     */\r\n    public Bundle getBundle()\r\n    {\r\n        return bundle;\r\n    }\r\n\r\n    /**\r\n     * Returns the type of lifecyle event.\r\n     * The type values are:\r\n     * <ul>\r\n     * <li>{@link #INSTALLED}\r\n     * <li>{@link #STARTED}\r\n     * <li>{@link #STOPPED}\r\n     * <li>{@link #UPDATED}\r\n     * <li>{@link #UNINSTALLED}\r\n     * </ul>\r\n     *\r\n     * @return The type of lifecycle event.\r\n     */\r\n\r\n    public int getType()\r\n    {\r\n        return type;\r\n    }\r\n}\r\n\r\n\r\n"
  },
  {
    "path": "atlas-core/src/main/java/org/osgi/framework/BundleException.java",
    "content": "\r\n\r\npackage org.osgi.framework;\r\n\r\n/**\r\n * A Framework exception used to indicate that a bundle lifecycle problem occurred.\r\n *\r\n * <p><tt>BundleException</tt> object is created by the Framework to denote an exception condition\r\n * in the lifecycle of a bundle.\r\n * <tt>BundleException</tt>s should not be created by bundle developers.\r\n *\r\n * @version $Revision: 1.1 $\r\n * @author Open Services Gateway Initiative\r\n */\r\n\r\npublic class BundleException extends Exception\r\n{\r\n    /**\r\n     * Nested exception.\r\n     */\r\n    private transient Throwable throwable;\r\n\r\n    public BundleException(Throwable throwable) {\r\n        super(throwable);\r\n        this.throwable = throwable;\r\n    }\r\n\r\n    /**\r\n     * Creates a <tt>BundleException</tt> that wraps another exception.\r\n     *\r\n     * @param msg The associated message.\r\n     * @param throwable The nested exception.\r\n     */\r\n    public BundleException(String msg, Throwable throwable)\r\n    {\r\n        super(msg, throwable);\r\n        this.throwable = throwable;\r\n    }\r\n\r\n    /**\r\n     * Creates a <tt>BundleException</tt> object with the specified message.\r\n     *\r\n     * @param msg The message.\r\n     */\r\n    public BundleException(String msg)\r\n    {\r\n        super(msg);\r\n        this.throwable = null;\r\n    }\r\n    \r\n}\r\n\r\n\r\n"
  },
  {
    "path": "atlas-core/src/main/java/org/osgi/framework/BundleListener.java",
    "content": "\r\n\r\npackage org.osgi.framework;\r\n\r\nimport java.util.EventListener;\r\n\r\n/**\r\n * A <tt>BundleEvent</tt> listener.\r\n * \r\n * <p>\r\n * <tt>BundleListener</tt> is a listener interface that may be implemented by\r\n * a bundle developer.\r\n * <p>\r\n * A <tt>BundleListener</tt> object is registered with the Framework using the\r\n * {@link BundleContext#addBundleListener}method. <tt>BundleListener</tt>s\r\n * are called with a <tt>BundleEvent</tt> object when a bundle has been\r\n * installed, started, stopped, updated, or uninstalled.\r\n * \r\n * @version $Revision: 1.1 $\r\n * @author Open Services Gateway Initiative\r\n * @see BundleEvent\r\n */\r\n\r\npublic interface BundleListener extends EventListener {\r\n\t/**\r\n\t * Receives notification that a bundle has had a lifecycle change.\r\n\t * \r\n\t * @param event\r\n\t *            The <tt>BundleEvent</tt>.\r\n\t */\r\n\tpublic abstract void bundleChanged(final BundleEvent event);\r\n}\r\n"
  },
  {
    "path": "atlas-core/src/main/java/org/osgi/framework/Constants.java",
    "content": "\r\n\r\npackage org.osgi.framework;\r\n\r\n/**\r\n * Defines standard names for the OSGi environment property, service property,\r\n * and Manifest header attribute keys.\r\n * \r\n * <p>\r\n * The values associated with these keys are of type <tt>java.lang.String</tt>,\r\n * unless otherwise indicated.\r\n * \r\n * @version $Revision: 1.1 $\r\n * @author Open Services Gateway Initiative\r\n * @since 1.1\r\n * @see Bundle#getHeaders\r\n * @see BundleContext#getProperty\r\n * @see BundleContext#registerService\r\n */\r\n\r\npublic interface Constants {\r\n\t/**\r\n\t * Location identifier of the OSGi <i>system bundle</i>, which is defined\r\n\t * to be &quot;System Bundle&quot;.\r\n\t */\r\n\tpublic static final String SYSTEM_BUNDLE_LOCATION = \"System Bundle\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Bundle-Category&quot;) identifying the\r\n\t * bundle's category.\r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String BUNDLE_CATEGORY = \"Bundle-Category\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Bundle-ClassPath&quot;) identifying a list\r\n\t * of nested JAR files, which are bundle resources used to extend the\r\n\t * bundle's classpath.\r\n\t * \r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String BUNDLE_CLASSPATH = \"Bundle-ClassPath\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Bundle-Copyright&quot;) identifying the\r\n\t * bundle's copyright information, which may be retrieved from the\r\n\t * <tt>Dictionary</tt> object returned by the <tt>Bundle.getHeaders</tt>\r\n\t * method.\r\n\t */\r\n\tpublic static final String BUNDLE_COPYRIGHT = \"Bundle-Copyright\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Bundle-Description&quot;) containing a brief\r\n\t * description of the bundle's functionality.\r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String BUNDLE_DESCRIPTION = \"Bundle-Description\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Bundle-Name&quot;) identifying the bundle's\r\n\t * name.\r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String BUNDLE_NAME = \"Bundle-Name\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Bundle-NativeCode&quot;) identifying a\r\n\t * number of hardware environments and the native language code libraries\r\n\t * that the bundle is carrying for each of these environments.\r\n\t * \r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String BUNDLE_NATIVECODE = \"Bundle-NativeCode\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Export-Package&quot;) identifying the names\r\n\t * (and optionally version numbers) of the packages that the bundle offers\r\n\t * to the Framework for export.\r\n\t * \r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String EXPORT_PACKAGE = \"Export-Package\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Export-Service&quot;) identifying the fully\r\n\t * qualified class names of the services that the bundle may register (used\r\n\t * for informational purposes only).\r\n\t * \r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String EXPORT_SERVICE = \"Export-Service\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Import-Package&quot;) identifying the names\r\n\t * (and optionally, version numbers) of the packages that the bundle is\r\n\t * dependent on.\r\n\t * \r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String IMPORT_PACKAGE = \"Import-Package\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;DynamicImport-Package&quot;) identifying the\r\n\t * names of the packages that the bundle may dynamically import during\r\n\t * execution.\r\n\t * \r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t * \r\n\t * @since 1.2\r\n\t */\r\n\tpublic static final String DYNAMICIMPORT_PACKAGE = \"DynamicImport-Package\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Import-Service&quot;) identifying the fully\r\n\t * qualified class names of the services that the bundle requires (used for\r\n\t * informational purposes only).\r\n\t * \r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String IMPORT_SERVICE = \"Import-Service\";\r\n\t\r\n\t/**\r\n     * Manifest header identifying the symbolic names of other bundles required\r\n     * by the bundle.\r\n     * \r\n     * <p>\r\n     * The header value may be retrieved from the {@code Dictionary} object\r\n     * returned by the {@code Bundle.getHeaders} method.\r\n     * \r\n     * @since 1.3\r\n     */\r\n    String  REQUIRE_BUNDLE                          = \"Require-Bundle\";\r\n    \r\n    /**\r\n     * Manifest header attribute identifying a range of versions for a bundle\r\n     * specified in the {@code Require-Bundle} or {@code Fragment-Host} manifest\r\n     * headers. The default value is {@code 0.0.0}.\r\n     * \r\n     * <p>\r\n     * The attribute value is encoded in the Require-Bundle manifest header\r\n     * like:\r\n     * \r\n     * <pre>\r\n     *     Require-Bundle: com.acme.module.test; bundle-version=&quot;1.1&quot;\r\n     *     Require-Bundle: com.acme.module.test; bundle-version=&quot;[1.0,2.0)&quot;\r\n     * </pre>\r\n     * \r\n     * <p>\r\n     * The bundle-version attribute value uses a mathematical interval notation\r\n     * to specify a range of bundle versions. A bundle-version attribute value\r\n     * specified as a single version means a version range that includes any\r\n     * bundle version greater than or equal to the specified version.\r\n     * \r\n     * @see #REQUIRE_BUNDLE\r\n     * @since 1.3\r\n     */\r\n    String  BUNDLE_VERSION_ATTRIBUTE                = \"bundle-version\";    \r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Bundle-Vendor&quot;) identifying the\r\n\t * bundle's vendor.\r\n\t * \r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String BUNDLE_VENDOR = \"Bundle-Vendor\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Bundle-Version&quot;) identifying the\r\n\t * bundle's version.\r\n\t * \r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String BUNDLE_VERSION = \"Bundle-Version\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Bundle-DocURL&quot;) identifying the\r\n\t * bundle's documentation URL, from which further information about the\r\n\t * bundle may be obtained.\r\n\t * \r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String BUNDLE_DOCURL = \"Bundle-DocURL\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Bundle-ContactAddress&quot;) identifying the\r\n\t * contact address where problems with the bundle may be reported; for\r\n\t * example, an email address.\r\n\t * \r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String BUNDLE_CONTACTADDRESS = \"Bundle-ContactAddress\";\r\n\r\n\t/**\r\n\t * Manifest header attribute (named &quot;Bundle-Activator&quot;)\r\n\t * identifying the bundle's activator class.\r\n\t * \r\n\t * <p>\r\n\t * If present, this header specifies the name of the bundle resource class\r\n\t * that implements the <tt>BundleActivator</tt> interface and whose\r\n\t * <tt>start</tt> and <tt>stop</tt> methods are called by the Framework\r\n\t * when the bundle is started and stopped, respectively.\r\n\t * \r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String BUNDLE_ACTIVATOR = \"Bundle-Activator\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Bundle-UpdateLocation&quot;) identifying the\r\n\t * location from which a new bundle version is obtained during a bundle\r\n\t * update operation.\r\n\t * \r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t */\r\n\tpublic static final String BUNDLE_UPDATELOCATION = \"Bundle-UpdateLocation\";\r\n\r\n\t/**\r\n\t * Manifest header attribute (named &quot;specification-version&quot;)\r\n\t * identifying the version of a package specified in the Export-Package or\r\n\t * Import-Package Manifest header.\r\n\t * \r\n\t * <p>\r\n\t * The attribute value is encoded in the Export-Package or Import-Package\r\n\t * Manifest header like:\r\n\t * \r\n\t * <pre>\r\n\t *  Import-Package: org.osgi.framework ; specification-version=&quot;1.1&quot;\r\n\t * </pre>\r\n\t */\r\n\tpublic static final String PACKAGE_SPECIFICATION_VERSION = \"specification-version\";\r\n\r\n\t/**\r\n\t * Manifest header attribute (named &quot;processor&quot;) identifying the\r\n\t * processor required to run native bundle code specified in the\r\n\t * Bundle-NativeCode Manifest header).\r\n\t * \r\n\t * <p>\r\n\t * The attribute value is encoded in the Bundle-NativeCode Manifest header\r\n\t * like:\r\n\t * \r\n\t * <pre>\r\n\t *  Bundle-NativeCode: http.so ; processor=x86 ...\r\n\t * </pre>\r\n\t */\r\n\tpublic static final String BUNDLE_NATIVECODE_PROCESSOR = \"processor\";\r\n\r\n\t/**\r\n\t * Manifest header attribute (named &quot;osname&quot;) identifying the\r\n\t * operating system required to run native bundle code specified in the\r\n\t * Bundle-NativeCode Manifest header).\r\n\t * <p>\r\n\t * The attribute value is encoded in the Bundle-NativeCode Manifest header\r\n\t * like:\r\n\t * \r\n\t * <pre>\r\n\t *  Bundle-NativeCode: http.so ; osname=Linux ...\r\n\t * </pre>\r\n\t */\r\n\tpublic static final String BUNDLE_NATIVECODE_OSNAME = \"osname\";\r\n\r\n\t/**\r\n\t * Manifest header attribute (named &quot;osversion&quot;) identifying the\r\n\t * operating system version required to run native bundle code specified in\r\n\t * the Bundle-NativeCode Manifest header).\r\n\t * <p>\r\n\t * The attribute value is encoded in the Bundle-NativeCode Manifest header\r\n\t * like:\r\n\t * \r\n\t * <pre>\r\n\t *  Bundle-NativeCode: http.so ; osversion=&quot;2.34&quot; ...\r\n\t * </pre>\r\n\t */\r\n\tpublic static final String BUNDLE_NATIVECODE_OSVERSION = \"osversion\";\r\n\r\n\t/**\r\n\t * Manifest header attribute (named &quot;language&quot;) identifying the\r\n\t * language in which the native bundle code is written specified in the\r\n\t * Bundle-NativeCode Manifest header. See ISO 639 for possible values.\r\n\t * <p>\r\n\t * The attribute value is encoded in the Bundle-NativeCode Manifest header\r\n\t * like:\r\n\t * \r\n\t * <pre>\r\n\t *  Bundle-NativeCode: http.so ; language=nl_be ...\r\n\t * </pre>\r\n\t */\r\n\tpublic static final String BUNDLE_NATIVECODE_LANGUAGE = \"language\";\r\n\r\n\t/**\r\n\t * Manifest header (named &quot;Bundle-RequiredExecutionEnvironment&quot;)\r\n\t * identifying the required execution environment for the bundle. The\r\n\t * service platform may run this bundle if any of the execution environments\r\n\t * named in this header matches one of the execution environments it\r\n\t * implements.\r\n\t * \r\n\t * <p>\r\n\t * The attribute value may be retrieved from the <tt>Dictionary</tt>\r\n\t * object returned by the <tt>Bundle.getHeaders</tt> method.\r\n\t * \r\n\t * @since 1.2\r\n\t */\r\n\tpublic static final String BUNDLE_REQUIREDEXECUTIONENVIRONMENT = \"Bundle-RequiredExecutionEnvironment\";\r\n\r\n\t/*\r\n\t * Framework environment properties.\r\n\t */\r\n\r\n\t/**\r\n\t * Framework environment property (named\r\n\t * &quot;org.osgi.framework.version&quot;) identifying the Framework\r\n\t * version.\r\n\t * \r\n\t * <p>\r\n\t * The value of this property may be retrieved by calling the\r\n\t * <tt>BundleContext.getProperty</tt> method.\r\n\t */\r\n\tpublic static final String FRAMEWORK_VERSION = \"org.osgi.framework.version\";\r\n\r\n\t/**\r\n\t * Framework environment property (named\r\n\t * &quot;org.osgi.framework.vendor&quot;) identifying the Framework\r\n\t * implementation vendor.\r\n\t * \r\n\t * <p>\r\n\t * The value of this property may be retrieved by calling the\r\n\t * <tt>BundleContext.getProperty</tt> method.\r\n\t */\r\n\tpublic static final String FRAMEWORK_VENDOR = \"org.osgi.framework.vendor\";\r\n\r\n\t/**\r\n\t * Framework environment property (named\r\n\t * &quot;org.osgi.framework.language&quot;) identifying the Framework\r\n\t * implementation language (see ISO 639 for possible values).\r\n\t * \r\n\t * <p>\r\n\t * The value of this property may be retrieved by calling the\r\n\t * <tt>BundleContext.getProperty</tt> method.\r\n\t */\r\n\tpublic static final String FRAMEWORK_LANGUAGE = \"org.osgi.framework.language\";\r\n\r\n\t/**\r\n\t * Framework environment property (named\r\n\t * &quot;org.osgi.framework.os.name&quot;) identifying the Framework\r\n\t * host-computer's operating system.\r\n\t * \r\n\t * <p>\r\n\t * The value of this property may be retrieved by calling the\r\n\t * <tt>BundleContext.getProperty</tt> method.\r\n\t */\r\n\tpublic static final String FRAMEWORK_OS_NAME = \"org.osgi.framework.os.name\";\r\n\r\n\t/**\r\n\t * Framework environment property (named\r\n\t * &quot;org.osgi.framework.os.version&quot;) identifying the Framework\r\n\t * host-computer's operating system version number.\r\n\t * \r\n\t * <p>\r\n\t * The value of this property may be retrieved by calling the\r\n\t * <tt>BundleContext.getProperty</tt> method.\r\n\t */\r\n\tpublic static final String FRAMEWORK_OS_VERSION = \"org.osgi.framework.os.version\";\r\n\r\n\t/**\r\n\t * Framework environment property (named\r\n\t * &quot;org.osgi.framework.processor&quot;) identifying the Framework\r\n\t * host-computer's processor name.\r\n\t * <p>\r\n\t * The value of this property may be retrieved by calling the\r\n\t * <tt>BundleContext.getProperty</tt> method.\r\n\t */\r\n\tpublic static final String FRAMEWORK_PROCESSOR = \"org.osgi.framework.processor\";\r\n\r\n\t/**\r\n\t * Framework environment property (named\r\n\t * &quot;org.osgi.framework.executionenvironment&quot;) identifying\r\n\t * execution environments provided by the Framework.\r\n\t * <p>\r\n\t * The value of this property may be retrieved by calling the\r\n\t * <tt>BundleContext.getProperty</tt> method.\r\n\t * \r\n\t * @since 1.2\r\n\t */\r\n\tpublic static final String FRAMEWORK_EXECUTIONENVIRONMENT = \"org.osgi.framework.executionenvironment\";\r\n\r\n\t/*\r\n\t * Service properties.\r\n\t */\r\n\r\n\t/**\r\n\t * Service property (named &quot;objectClass&quot;) identifying all of the\r\n\t * class names under which a service was registered in the Framework (of\r\n\t * type <tt>java.lang.String[]</tt>).\r\n\t * \r\n\t * <p>\r\n\t * This property is set by the Framework when a service is registered.\r\n\t */\r\n\tpublic static final String OBJECTCLASS = \"objectClass\";\r\n\r\n\t/**\r\n\t * Service property (named &quot;service.id&quot;) identifying a service's\r\n\t * registration number (of type <tt>java.lang.Long</tt>).\r\n\t * \r\n\t * <p>\r\n\t * The value of this property is assigned by the Framework when a service is\r\n\t * registered. The Framework assigns a unique value that is larger than all\r\n\t * previously assigned values since the Framework was started. These values\r\n\t * are NOT persistent across restarts of the Framework.\r\n\t */\r\n\tpublic static final String SERVICE_ID = \"service.id\";\r\n\r\n\t/**\r\n\t * Service property (named &quot;service.pid&quot;) identifying a service's\r\n\t * persistent identifier.\r\n\t * \r\n\t * <p>\r\n\t * This property may be supplied in the <tt>properties</tt>\r\n\t * <tt>Dictionary</tt>\r\n\t * object passed to the <tt>BundleContext.registerService</tt> method.\r\n\t * \r\n\t * <p>\r\n\t * A service's persistent identifier uniquely identifies the service and\r\n\t * persists across multiple Framework invocations.\r\n\t * \r\n\t * <p>\r\n\t * By convention, every bundle has its own unique namespace, starting with\r\n\t * the bundle's identifier (see {@link Bundle#getBundleId}) and followed by\r\n\t * a dot (.). A bundle may use this as the prefix of the persistent\r\n\t * identifiers for the services it registers.\r\n\t */\r\n\tpublic static final String SERVICE_PID = \"service.pid\";\r\n\r\n\t/**\r\n\t * Service property (named &quot;service.ranking&quot;) identifying a\r\n\t * service's ranking number (of type <tt>java.lang.Integer</tt>).\r\n\t * \r\n\t * <p>\r\n\t * This property may be supplied in the <tt>properties\r\n\t * Dictionary</tt>\r\n\t * object passed to the <tt>BundleContext.registerService</tt> method.\r\n\t * \r\n\t * <p>\r\n\t * The service ranking is used by the Framework to determine the <i>default</i>\r\n\t * service to be returned from a call to the\r\n\t * {@link BundleContext#getServiceReference}method: If more than one\r\n\t * service implements the specified class, the <tt>ServiceReference</tt>\r\n\t * object with the highest ranking is returned.\r\n\t * \r\n\t * <p>\r\n\t * The default ranking is zero (0). A service with a ranking of\r\n\t * <tt>Integer.MAX_VALUE</tt> is very likely to be returned as the default\r\n\t * service, whereas a service with a ranking of <tt>Integer.MIN_VALUE</tt>\r\n\t * is very unlikely to be returned.\r\n\t * \r\n\t * <p>\r\n\t * If the supplied property value is not of type <tt>java.lang.Integer</tt>,\r\n\t * it is deemed to have a ranking value of zero.\r\n\t */\r\n\tpublic static final String SERVICE_RANKING = \"service.ranking\";\r\n\r\n\t/**\r\n\t * Service property (named &quot;service.vendor&quot;) identifying a\r\n\t * service's vendor.\r\n\t * \r\n\t * <p>\r\n\t * This property may be supplied in the properties <tt>Dictionary</tt>\r\n\t * object passed to the <tt>BundleContext.registerService</tt> method.\r\n\t */\r\n\tpublic static final String SERVICE_VENDOR = \"service.vendor\";\r\n\r\n\t/**\r\n\t * Service property (named &quot;service.description&quot;) identifying a\r\n\t * service's description.\r\n\t * \r\n\t * <p>\r\n\t * This property may be supplied in the properties <tt>Dictionary</tt>\r\n\t * object passed to the <tt>BundleContext.registerService</tt> method.\r\n\t */\r\n\tpublic static final String SERVICE_DESCRIPTION = \"service.description\";\r\n}\r\n"
  },
  {
    "path": "atlas-core/src/main/java/org/osgi/framework/FrameworkEvent.java",
    "content": "\r\n\r\npackage org.osgi.framework;\r\n\r\n/**\r\n * A general Framework event.\r\n * \r\n * <p>\r\n * <tt>FrameworkEvent</tt> is the event class used when notifying listeners of\r\n * general events occuring within the OSGI environment. A type code is used to\r\n * identify the event type for future extendability.\r\n * \r\n * <p>\r\n * OSGi reserves the right to extend the set of event types.\r\n * \r\n * @version $Revision: 1.1 $\r\n * @author Open Services Gateway Initiative\r\n */\r\n\r\npublic class FrameworkEvent {\r\n\r\n\tpublic static final int STARTED = 0x00000001;\r\n\r\n\tpublic static final int ERROR = 0x00000002;\r\n\r\n\r\n\tpublic static final int PACKAGES_REFRESHED = 0x00000004;\r\n\r\n\r\n\tpublic static final int STARTLEVEL_CHANGED = 0x00000008;\r\n\r\n\tpublic int state;\r\n\r\n\tpublic FrameworkEvent(int state){\r\n\t\tthis.state = state;\r\n\t}\r\n\r\n\tpublic int getType(){\r\n\t\treturn state;\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "atlas-core/src/main/java/org/osgi/framework/FrameworkListener.java",
    "content": "\r\npackage org.osgi.framework;\r\n\r\nimport java.util.EventListener;\r\n\r\n\r\npublic abstract interface FrameworkListener extends EventListener {\r\n\r\n\t/**\r\n\t * Receives notification of a general <tt>FrameworkEvent</tt> object.\r\n\t * \r\n\t * @param event\r\n\t *            The <tt>FrameworkEvent</tt> object.\r\n\t */\r\n\tpublic abstract void frameworkEvent(final FrameworkEvent event);\r\n}\r\n"
  },
  {
    "path": "atlas-core/src/main/java/org/osgi/framework/SynchronousBundleListener.java",
    "content": "\r\npackage org.osgi.framework;\r\n\r\n/**\r\n * A synchronous <tt>BundleEvent</tt> listener.\r\n *\r\n * @version $Revision: 1.1 $\r\n * @author Open Services Gateway Initiative\r\n * @since 1.1\r\n * @see BundleEvent\r\n */\r\n\r\npublic interface SynchronousBundleListener extends BundleListener {\r\n}\r\n"
  },
  {
    "path": "atlas-core/src/main/res/drawable/atlas_waitview.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n\n    <solid android:color=\"#b4000000\"/>\n    <corners android:radius=\"4dp\"/>\n</shape>"
  },
  {
    "path": "atlas-core/src/main/res/layout/atlas_progress.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<merge xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <ImageView\n        android:id=\"@+id/at_circularProgress\"\n        android:layout_width=\"32dp\"\n        android:layout_height=\"32dp\"\n        android:layout_gravity=\"center\"/>\n\n    <!--<TextView-->\n        <!--android:id=\"@+id/at_progressText\"-->\n        <!--android:layout_width=\"wrap_content\"-->\n        <!--android:layout_height=\"wrap_content\"-->\n        <!--android:layout_gravity=\"center_horizontal\"-->\n        <!--android:text=\"加载中...\"-->\n        <!--android:textColor=\"#FF999999\"-->\n        <!--android:textSize=\"14dp\" />-->\n</merge>"
  },
  {
    "path": "atlas-core/src/main/res/values/style_atlas.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <style name=\"atlas_default_dialog\" parent=\"@android:style/Theme.Dialog\">\n        <item name=\"android:windowFrame\">@null</item><!--边框-->\n        <item name=\"android:windowIsFloating\">true</item><!--是否浮现在activity之上-->\n        <item name=\"android:windowIsTranslucent\">false</item><!--半透明-->\n        <item name=\"android:windowNoTitle\">true</item><!--无标题-->\n        <item name=\"android:windowBackground\">@android:color/transparent</item>\n        <item name=\"android:background\">#00000000</item>\n        <item name=\"android:backgroundDimEnabled\">false</item>\n    </style>\n</resources>"
  },
  {
    "path": "atlas-demo/.gitignore",
    "content": "*.iml\n.gradle\n.idea/\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n!.idea/codeStyleSettings.xml\n.DS_Store\n/build\n/captures\n.vscode/\n\n# Taken from Android.gitignore https://github.com/github/gitignore/blob/master/Android.gitignore\n#\n# Built application files\n*.apk\n*.ap_\n\n# Files for the Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# Intellij\n*.iml\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/.gitignore",
    "content": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/AwoForBundle.txt",
    "content": "atlas {\n    bundleConfig{\n        awbBundle true\n    }\n    buildTypes {\n        debug {\n            baseApFile file('/Users/wuzhong/gitlab/AtlasDemo/AtlasDemo/app/build/outputs/apk/app-debug.ap')\n        }\n    }\n}"
  },
  {
    "path": "atlas-demo/AtlasDemo/AwoForHost.txt",
    "content": ""
  },
  {
    "path": "atlas-demo/AtlasDemo/README.md",
    "content": "## 更新日志\n\n1. 升级atlasplugin到2.3.3.beta1\n2. 支持awb之间的依赖，具体参考 firstbundle的配置\n\t1. dependencies 里添加 provided依赖 \n\n\t\t \tprovidedCompile project(':publicbundle')\n\t\t \n\t2. 申明bundle之间依赖关系\n\n\t\t\t➜  firstbundle git:(gradle/2.3.3) ✗ more bundleBaseInfoFile.json\n\t\t\t{\n\t\t\t  \"name\": \"第一个bundle\",\n\t\t\t  \"dependency\": [\"com.taobao.publicBundle\"]\n\t\t\t}\n\t\t\t\n\t3. 在 app中添加被依赖的bundle\n\n\t\t\tbundleCompile project(':publicbundle')\n    \t\t\n3. 加入databinding的bundle，具体参见app的配置\n\n\t1. 添加databinding的bundle依赖\n\n\t\t\tbundleCompile project(':databindbundle')\n\t\t\t\n\t2. 配置需要开启的databinding列表\n\n\t\t\tatlas {\n\t\t\n\t\t    tBuildConfig {\n\t\t        dataBindingBundles = ['com.taobao.databindbundle']\n\t\t    \t ...\n\t\t    \t \n    3. 注意同时开启app的databinding\n\t\t\n\t\t\tandroid {\n\t\t\t \tdataBinding {\n\t        \t\tenabled = true\n\t    \t \t}\n\t    \t\t"
  },
  {
    "path": "atlas-demo/AtlasDemo/Tpatch.txt",
    "content": "1、 app的build.gradle的语句\"version = getEnvValue(\"versionName\", \"1.0.0\");\"中修改想要生成的app的versionName（默认为1.0.0）\n\n    app目录下执行../gradlew clean assembleDebug 生成apk  (windows 环境的命令为 ..\\gradlew.bat clean assembleDebug  以下类同)\n\n2、 app目录下执行../gradlew publish 将跟apk同目录的ap文件发布到仓库,此时ap的版本是1.0.0\n\n3、 手机上安装生成的apk，同时进到动态部署界面（侧边栏里面划开点击进入),且手机连接电脑adb（确保adb devices可见）\n\n///////////////////////////////^^^^^^^准备工作^^^^^^^^^^////////////////////////\n\n4、 进行一些想要的修改（不支持manifest的修改），改动完成后需要升级一下对应bundle/lib的版本号\n\n5、 app工程目录下执行../gradlew clean assembleDebug -DapVersion=apVersion -DversionName=newVersion,\n    其中apVersion为之前打的完整apk的版本，newVersion为此次动态部署要生成的新的版本号，\n    例如命令 ../gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.1\n\n6、 检查build/output/tpatch-debug 目录下文件是否生成，然后执行下面的命令(以下为mac下的命令，windows请修改文件分隔符)\n    (根据你手机的当前版本推送对应版本的update-**.json,和对应的tpatch文件)\n    例如，这时是第1次部署，versionName是1.0.0，所以命令行是:\n    adb push build/outputs/tpatch-debug/update-1.0.0.json /sdcard/Android/data/com.taobao.demo/cache/update-1.0.0.json\n    adb push build/outputs/tpatch-debug/patch-1.0.1@1.0.0.tpatch /sdcard/Android/data/com.taobao.demo/cache/patch-1.0.1@1.0.0.tpatch\n\n7、 点击动态部署页面红色按钮执行动态部署,生效后app的versionName变为了1.0.1\n\n8、 后续继续做想要的修改，我们要变成1.0.2 (某个bundle做动态部署的时候请更新版本号(versionName)，因为差量会基于版本号对比)\n\t../gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.2   这时候会生成两个  patch-1.0.2@1.0.0.tpatch  patch-1.0.2@1.0.1.tpatch\n\n\t根据你目前的app版本，重复6步骤，推送对应版本的update-**.json,和对应的tpatch文件。\n\n\t例如: 如果这时你app的versionName是1.0.1\n你的命令行就是:\n    adb push build/outputs/tpatch-debug/update-1.0.1.json /sdcard/Android/data/com.taobao.demo/cache/update-1.0.1.json\n    adb push build/outputs/tpatch-debug/patch-1.0.2@1.0.1.tpatch /sdcard/Android/data/com.taobao.demo/cache/patch-1.0.2@1.0.1.tpatch\n\n如果这时你app的versionName是1.0.0,也就是还是基线版本\n你的命令行就是:\n    adb push build/outputs/tpatch-debug/update-1.0.0.json /sdcard/Android/data/com.taobao.demo/cache/update-1.0.0.json\n    adb push build/outputs/tpatch-debug/patch-1.0.2@1.0.0.tpatch /sdcard/Android/data/com.taobao.demo/cache/patch-1.0.2@1.0.0.tpatch\n\n\n9、 后续继续做想要的修改，我们要变成1.0.3 (某个bundle做动态部署的时候请更新版本号，因为差量会基于版本号对比)\n\t../gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.3   这时候会生成三个  patch-1.0.3@1.0.2.tpatch  patch-1.0.3@1.0.1.tpatch  patch-1.0.3@1.0.0.tpatch\n\n\t根据你目前的app版本，重复6步骤，推送对应版本的update-**.json,和对应的tpatch文件。\t\n\n10、 如果做了多次动态部署后，需要从头开始测试，请先清除AtlasDemo根目录下的hisTpatch文件夹。\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/activitygroupcompat/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/activitygroupcompat/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\ngroup = 'com.atlas.demo'\nversion = '1.0.1'\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion '26.0.2'\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile 'com.android.support:appcompat-v7:25.1.0'\n//    compile('com.taobao.android:atlas_core:5.0.7.55')\n    compile project(':atlas_core')\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/activitygroupcompat/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/activitygroupcompat/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.taobao.activitygroupcompat\">\n\n</manifest>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/activitygroupcompat/src/main/java/com/taobao/android/ActivityGroupDelegate.java",
    "content": "package com.taobao.android;\n\nimport android.app.Activity;\nimport android.app.Application;\nimport android.app.Dialog;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.content.Intent;\nimport android.content.pm.ResolveInfo;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Looper;\nimport android.support.v4.app.FragmentActivity;\nimport android.taobao.atlas.bundleInfo.AtlasBundleInfoManager;\nimport android.taobao.atlas.framework.Atlas;\nimport android.taobao.atlas.framework.BundleImpl;\nimport android.taobao.atlas.framework.Framework;\nimport android.taobao.atlas.runtime.ActivityTaskMgr;\nimport android.taobao.atlas.runtime.BundleUtil;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.taobao.atlas.util.StringUtils;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.view.ViewGroup;\n\n/**\n * Created by guanjie on 16/11/16.\n */\n\npublic class ActivityGroupDelegate {\n\n    private static final String STATES_KEY = \"android:states\";\n\n\n    private LocalActivityManager mLocalActivityManager;\n    private FragmentActivity mActivity;\n\n    public LocalActivityManager getLocalActivityManager(){\n        return mLocalActivityManager;\n    }\n\n    public ActivityGroupDelegate(FragmentActivity activity, Bundle bundle){\n        mActivity = activity;\n        try {\n            mLocalActivityManager = new LocalActivityManager(activity, true);\n        }catch(Throwable e){\n            throw new RuntimeException(e);\n        }\n//        Bundle states = bundle != null\n//                ? (Bundle) bundle.getBundle(STATES_KEY) : null;\n        mLocalActivityManager.dispatchCreate(null);\n        activity.getApplication().registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {\n            @Override\n            public void onActivityCreated(Activity activity, Bundle bundle) {\n            }\n\n            @Override\n            public void onActivityStarted(Activity activity) {\n            }\n\n            @Override\n            public void onActivityResumed(Activity activity) {\n                if(mActivity == activity) {\n                    mLocalActivityManager.dispatchResume();\n                }\n            }\n\n            @Override\n            public void onActivityPaused(Activity activity) {\n                if(mActivity == activity) {\n                    mLocalActivityManager.dispatchPause(mActivity.isFinishing());\n                }\n            }\n\n            @Override\n            public void onActivityStopped(Activity activity) {\n                if(mActivity == activity) {\n                    mLocalActivityManager.dispatchStop();\n                }\n            }\n\n            @Override\n            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {\n                if(mActivity == activity) {\n                    Bundle state = mLocalActivityManager.saveInstanceState();\n                    if (state != null) {\n                        bundle.putBundle(STATES_KEY, state);\n                    }\n                }\n            }\n\n            @Override\n            public void onActivityDestroyed(Activity activity) {\n                if(mActivity == activity) {\n                    mLocalActivityManager.removeAllActivities();\n                }\n            }\n        });\n    }\n\n//    public HashMap<String,Object> onRetainNonConfigurationChildInstances() {\n//        if(dispatchRetainNonConfigurationInstanceMethod!=null) {\n//            try {\n//                return (HashMap<String, Object>) dispatchRetainNonConfigurationInstanceMethod.invoke(mLocalActivityManager);\n//            } catch (Throwable e) {\n//                e.printStackTrace();\n//            }\n//        }\n//        return null;\n//    }\n\n//    private static Method dispatchRetainNonConfigurationInstanceMethod = null;\n//    private static Method onActivityResultMethod = null;\n//    private static Method noteStateNotSavedMethod = null;\n//    private static Method findFragmentByWhoMethod = null;\n//    static{\n//        try {\n//            dispatchRetainNonConfigurationInstanceMethod = LocalActivityManager.class.getDeclaredMethod(\"dispatchRetainNonConfigurationInstance\");\n//            dispatchRetainNonConfigurationInstanceMethod.setAccessible(true);\n//            onActivityResultMethod = Activity.class.getDeclaredMethod(\"onActivityResult\",int.class,int.class,Intent.class);\n//            onActivityResultMethod.setAccessible(true);\n//            noteStateNotSavedMethod = Class.forName(\"android.support.v4.app.FragmentManagerImpl\").\n//                    getDeclaredMethod(\"noteStateNotSaved\");\n//            noteStateNotSavedMethod.setAccessible(true);\n//            findFragmentByWhoMethod = Class.forName(\"android.support.v4.app.FragmentManagerImpl\").\n//                    getDeclaredMethod(\"findFragmentByWho\",String.class);\n//            findFragmentByWhoMethod.setAccessible(true);\n//        } catch (Throwable e) {\n//            e.printStackTrace();\n//        }\n//\n//    }\n\n\n    public void startChildActivity(ViewGroup container, String key, Intent intent){\n        //移除内容部分全部的View\n        container.removeAllViews();\n        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);\n\n        Activity contentActivity = mLocalActivityManager.getActivity(key);\n        if(contentActivity!=null) {\n            container.addView(\n                    mLocalActivityManager.getActivity(key)\n                            .getWindow().getDecorView(),\n                    new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,\n                            ViewGroup.LayoutParams.MATCH_PARENT));\n            mLocalActivityManager.switchToChildActivity(key);\n        }else{\n            execStartChildActivityInternal(container, key, intent);\n        }\n    }\n\n    private void performLaunchChildActivity(ViewGroup container,String key,Intent intent ){\n        if(intent==null){\n            Log.e(\"ActivityGroupDelegate\",\"intent is null stop performLaunchChildActivity\");\n            return ;\n        }\n        mLocalActivityManager.startActivity(key,intent);\n        container.addView(\n                mLocalActivityManager.getActivity(key)\n                        .getWindow().getDecorView(),\n                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,\n                        ViewGroup.LayoutParams.MATCH_PARENT));\n    }\n\n    public void execStartChildActivityInternal(ViewGroup container,String key, Intent intent){\n        String packageName = null;\n        String componentName = null ;\n        Context context = container.getContext();\n        if (intent.getComponent() != null) {\n            packageName = intent.getComponent().getPackageName();\n            componentName = intent.getComponent().getClassName();\n        } else {\n            ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent, 0);\n            if (resolveInfo != null && resolveInfo.activityInfo != null) {\n                packageName = resolveInfo.activityInfo.packageName;\n                componentName = resolveInfo.activityInfo.name;\n            }\n        }\n        if (componentName == null){\n            Log.e(\"ActivityGroupDelegate\",\"can not find componentName\");\n        }\n        if (!StringUtils.equals(context.getPackageName(), packageName)) {\n            Log.e(\"ActivityGroupDelegate\",\"childActivity can not be external Activity\");\n        }\n\n        String bundleName = AtlasBundleInfoManager.instance().getBundleForComponet(componentName);\n        if(!TextUtils.isEmpty(bundleName)){\n            BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(bundleName);\n            if(impl!=null&&impl.checkValidate()) {\n                performLaunchChildActivity(container,key,intent);\n            }else {\n                if(ActivityTaskMgr.getInstance().peekTopActivity()!=null && Looper.getMainLooper().getThread().getId()==Thread.currentThread().getId()) {\n                    asyncStartActivity(container,key,bundleName,intent);\n                }else{\n                    performLaunchChildActivity(container,key,intent);\n                }\n            }\n        }else{\n            // Try to get class from system Classloader\n            try {\n                Class<?> clazz = null;\n                clazz = Framework.getSystemClassLoader().loadClass(componentName);\n                if (clazz != null) {\n                    performLaunchChildActivity(container,key,intent);\n                }\n            } catch (ClassNotFoundException e) {\n                Log.e(\"ActivityGroupDelegate\",\"\",e);\n            }\n        }\n\n    }\n\n    private void asyncStartActivity(final ViewGroup container,final String key,final String bundleName,final Intent intent){\n        final Activity current = ActivityTaskMgr.getInstance().peekTopActivity();\n        final Dialog dialog = current!=null ? RuntimeVariables.alertDialogUntilBundleProcessed(current,bundleName) : null;\n        if(current!=null && dialog==null){\n            throw new RuntimeException(\"alertDialogUntilBundleProcessed can not return null\");\n        }\n        final int currentActivitySize = ActivityTaskMgr.getInstance().sizeOfActivityStack();\n        final BundleUtil.CancelableTask successTask = new BundleUtil.CancelableTask(new Runnable() {\n            @Override\n            public void run() {\n                if (current == ActivityTaskMgr.getInstance().peekTopActivity() || currentActivitySize==ActivityTaskMgr.getInstance().sizeOfActivityStack()+1) {\n                    performLaunchChildActivity(container,key,intent);\n                }\n\n                if (dialog != null && current != null && !current.isFinishing()) {\n                    try {\n                        if(dialog.isShowing())\n                            dialog.dismiss();\n                    }catch (Throwable e){}\n                }\n            }\n        });\n        final BundleUtil.CancelableTask failedTask = new BundleUtil.CancelableTask(new Runnable() {\n            @Override\n            public void run() {\n                if (current == ActivityTaskMgr.getInstance().peekTopActivity()) {\n\n                }\n\n                if (dialog != null && current != null && !current.isFinishing()) {\n                    try {\n                        if(dialog.isShowing())\n                            dialog.dismiss();\n                    }catch(Throwable e){}\n                }\n            }\n        });\n\n        if(dialog!=null) {\n            dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {\n                @Override\n                public void onDismiss(DialogInterface dialog) {\n                    successTask.cancel();\n                    failedTask.cancel();\n                }\n            });\n            if(Atlas.getInstance().getBundle(bundleName)==null || Build.VERSION.SDK_INT<22) {\n                if (dialog != null && current != null && !current.isFinishing() && !dialog.isShowing()) {\n                    try {\n                        dialog.show();\n                    } catch (Throwable e) {\n                    }\n                }\n            }\n            BundleUtil.checkBundleStateAsync(bundleName, successTask, failedTask);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/activitygroupcompat/src/main/java/com/taobao/android/LocalActivityManager.java",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android;\n\nimport android.app.Activity;\nimport android.content.ActivityNotFoundException;\nimport android.content.Intent;\nimport android.content.pm.ActivityInfo;\nimport android.content.pm.PackageManager;\nimport android.os.Binder;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.IBinder;\nimport android.taobao.atlas.hack.AndroidHack;\nimport android.taobao.atlas.hack.AtlasHacks;\nimport android.taobao.atlas.hack.Hack;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.util.Log;\nimport android.view.Window;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class LocalActivityManager {\n    private static final String TAG = \"LocalActivityManager\";\n    private static final boolean localLOGV = false;\n\n    // Internal token for an Activity being managed by LocalActivityManager.\n    private static class LocalActivityRecord extends Binder {\n        LocalActivityRecord(String _id, Intent _intent) {\n            id = _id;\n            intent = _intent;\n        }\n\n        final String id;                // Unique name of this record.\n        Intent intent;                  // Which activity to run here.\n        ActivityInfo activityInfo;      // Package manager info about activity.\n        Activity activity;              // Currently instantiated activity.\n        Window window;                  // Activity's top-level window.\n        Bundle instanceState;           // Last retrieved freeze state.\n        int curState = RESTORED;        // Current state the activity is in.\n    }\n\n    static final int RESTORED = 0;      // State restored, but no startActivity().\n    static final int INITIALIZING = 1;  // Ready to launch (after startActivity()).\n    static final int CREATED = 2;       // Created, not started or resumed.\n    static final int STARTED = 3;       // Created and started, not resumed.\n    static final int RESUMED = 4;       // Created started and resumed.\n    static final int DESTROYED = 5;     // No longer with us.\n\n    /** Thread our activities are running in. */\n    private final Object mActivityThread;\n    /** The containing activity that owns the activities we create. */\n    private final Activity mParent;\n\n    /** The activity that is currently resumed. */\n    private LocalActivityRecord mResumed;\n    /** id -> record of all known activities. */\n    private final Map<String, LocalActivityRecord> mActivities\n            = new HashMap<String, LocalActivityRecord>();\n    /** array of all known activities for easy iterating. */\n    private final ArrayList<LocalActivityRecord> mActivityArray\n            = new ArrayList<LocalActivityRecord>();\n\n    /** True if only one activity can be resumed at a time */\n    private final boolean mSingleMode;\n\n    /** Set to true once we find out the container is finishing. */\n    private boolean mFinishing;\n\n    /** Current state the owner (ActivityGroup) is in */\n    private int mCurState = INITIALIZING;\n\n    private Hack.HackedClass  NonConfigurationInstances;\n    private Hack.HackedMethod ActivityThread_startActivityNow;\n    private Hack.HackedMethod ActivityThread_performRestartActivity;\n    private Hack.HackedMethod ActivityThread_performDestroyActivity;\n    private Hack.HackedMethod Activity_performSaveInstanceState;\n\n    private Hack.HackedMethod ActivityThread_performResumeActivity;\n    private Hack.HackedMethod ActivityThread_performStopActivity;\n    private Hack.HackedMethod ActivityThread_performPauseActivity;\n\n    private Hack.HackedMethod Activity_onStart;\n    private Hack.HackedMethod Activity_onStop;\n\n\n    /**\n     * Create a new LocalActivityManager for holding activities running within\n     * the given <var>parent</var>.\n     *\n     * @param parent the host of the embedded activities\n     * @param singleMode True if the LocalActivityManger should keep a maximum\n     * of one activity resumed\n     */\n    public LocalActivityManager(Activity parent, boolean singleMode) throws Throwable{\n        defineAndVerify();\n        mActivityThread = AndroidHack.getActivityThread();\n        mParent = parent;\n        mSingleMode = singleMode;\n    }\n\n    private void defineAndVerify() throws Hack.HackDeclaration.HackAssertionException{\n        NonConfigurationInstances = Hack.into(\"android.app.Activity$NonConfigurationInstances\");\n        ActivityThread_startActivityNow = AtlasHacks.ActivityThread.method(\"startActivityNow\",Activity.class,String.class,\n                Intent.class,ActivityInfo.class, IBinder.class,Bundle.class,NonConfigurationInstances.getmClass());\n        if (Build.VERSION.SDK_INT >= 28) {\n            ActivityThread_performRestartActivity = AtlasHacks.ActivityThread.method(\n                    \"performRestartActivity\", IBinder.class, boolean.class);\n        } else {\n            ActivityThread_performRestartActivity = AtlasHacks.ActivityThread.method(\n                    \"performRestartActivity\", IBinder.class);\n\n        }\n\n        if (Build.VERSION.SDK_INT >= 28) {\n            ActivityThread_performDestroyActivity = AtlasHacks.ActivityThread.method(\n                    \"performDestroyActivity\", IBinder.class, boolean.class, int.class,\n                    boolean.class, String.class);\n\n        } else {\n            ActivityThread_performDestroyActivity = AtlasHacks.ActivityThread.method(\n                    \"performDestroyActivity\", IBinder.class, boolean.class);\n\n        }\n        Activity_performSaveInstanceState = Hack.into(Activity.class).method(\"performSaveInstanceState\",Bundle.class);\n        Activity_onStart = Hack.into(Activity.class).method(\"onStart\");\n        Activity_onStop = Hack.into(Activity.class).method(\"onStop\");\n        if(Build.VERSION.SDK_INT<=23) {\n            ActivityThread_performResumeActivity = AtlasHacks.ActivityThread.method(\"performResumeActivity\",\n                    IBinder.class,boolean.class);\n            ActivityThread_performStopActivity = AtlasHacks.ActivityThread.method(\"performStopActivity\",\n                    IBinder.class,boolean.class);\n            ActivityThread_performPauseActivity = AtlasHacks.ActivityThread.method(\"performPauseActivity\",\n                    IBinder.class,boolean.class,boolean.class);\n        }else{\n            ActivityThread_performResumeActivity = AtlasHacks.ActivityThread.method(\"performResumeActivity\",\n                    IBinder.class,boolean.class,String.class);\n            ActivityThread_performStopActivity = AtlasHacks.ActivityThread.method(\"performStopActivity\",\n                    IBinder.class,boolean.class,String.class);\n            if (Build.VERSION.SDK_INT >= 28) {\n\n                try {\n\n\n                    ActivityThread_performPauseActivity = AtlasHacks.ActivityThread.method(\n                            \"performPauseActivity\",\n                            IBinder.class, boolean.class, /*boolean.class,*/ String.class,\n                            Class.forName(\n                                    \"android.app.servertransaction.PendingTransactionActions\"));\n                    ;\n                } catch (Exception e) {\n                    throw new IllegalStateException(e);\n                }\n\n            } else {\n                ActivityThread_performPauseActivity = AtlasHacks.ActivityThread.method(\n                        \"performPauseActivity\",\n                        IBinder.class, boolean.class, boolean.class, String.class);\n\n            }\n        }\n    }\n\n    private void moveToState(LocalActivityRecord r, int desiredState) {\n        if (r.curState == RESTORED || r.curState == DESTROYED) {\n            // startActivity() has not yet been called, so nothing to do.\n            return;\n        }\n\n        if (r.curState == INITIALIZING) {\n            // We need to have always created the activity.\n            if (localLOGV) Log.v(TAG, r.id + \": starting \" + r.intent);\n            if (r.activityInfo == null) {\n                r.activityInfo = r.intent.resolveActivityInfo(\n                        RuntimeVariables.androidApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);\n            }\n            try {\n                r.activity = (Activity) ActivityThread_startActivityNow.invoke(mActivityThread,\n                        mParent, r.id, r.intent, r.activityInfo, r, r.instanceState, null);\n            }catch(InvocationTargetException e){\n                throw new RuntimeException(e.getTargetException());\n            }\n            if (r.activity == null) {\n                return;\n            }\n            r.window = r.activity.getWindow();\n            r.instanceState = null;\n            r.curState = STARTED;\n\n            if (desiredState == RESUMED) {\n                if (localLOGV) Log.v(TAG, r.id + \": resuming\");\n//                mActivityThread.performResumeActivity(r, true, \"moveToState-INITIALIZING\");\n                try {\n                    if(ActivityThread_performResumeActivity.getMethod().getParameterTypes().length==2){\n                        ActivityThread_performResumeActivity.invoke(mActivityThread,r,true);\n                    }else{\n                        ActivityThread_performResumeActivity.invoke(mActivityThread,r,true,\"moveToState-INITIALIZING\");\n                    }\n                }catch (InvocationTargetException e){\n                    throw new RuntimeException(e.getTargetException());\n                }\n                r.curState = RESUMED;\n            }\n\n            // Don't do anything more here.  There is an important case:\n            // if this is being done as part of onCreate() of the group, then\n            // the launching of the activity gets its state a little ahead\n            // of our own (it is now STARTED, while we are only CREATED).\n            // If we just leave things as-is, we'll deal with it as the\n            // group's state catches up.\n            return;\n        }\n\n        switch (r.curState) {\n            case CREATED:\n                if (desiredState == STARTED) {\n                    if (localLOGV) Log.v(TAG, r.id + \": restarting\");\n                    try {\n                        ActivityThread_performRestartActivity.invoke(mActivityThread, r);\n                    }catch (InvocationTargetException e){\n                        throw new RuntimeException(e.getTargetException());\n                    }\n                    r.curState = STARTED;\n                }\n                if (desiredState == RESUMED) {\n                    if (localLOGV) Log.v(TAG, r.id + \": restarting and resuming\");\n                    try {\n                        if (Build.VERSION.SDK_INT >= 28) {\n                            ActivityThread_performRestartActivity.invoke(mActivityThread, r, false);\n                        } else {\n                            ActivityThread_performRestartActivity.invoke(mActivityThread, r);\n\n                        }\n\n                        if(ActivityThread_performResumeActivity.getMethod().getParameterTypes().length==2){\n                            ActivityThread_performResumeActivity.invoke(mActivityThread,r,true);\n                        }else{\n                            ActivityThread_performResumeActivity.invoke(mActivityThread,r,true,\"moveToState-CREATED\");\n                        }\n                    }catch (InvocationTargetException e){\n                        throw new RuntimeException(e.getTargetException());\n                    }\n//                    mActivityThread.performResumeActivity(r, true, \"moveToState-CREATED\");\n                    r.curState = RESUMED;\n                }\n                return;\n\n            case STARTED:\n                if (desiredState == RESUMED) {\n                    // Need to resume it...\n                    if (localLOGV) Log.v(TAG, r.id + \": resuming\");\n//                    mActivityThread.performResumeActivity(r, true, \"moveToState-STARTED\");\n                    try {\n                        if(ActivityThread_performResumeActivity.getMethod().getParameterTypes().length==2){\n                            ActivityThread_performResumeActivity.invoke(mActivityThread,r,true);\n                        }else{\n                            ActivityThread_performResumeActivity.invoke(mActivityThread,r,true,\"moveToState-STARTED\");\n                        }\n                    }catch (InvocationTargetException e){\n                        throw new RuntimeException(e.getTargetException());\n                    }\n                    r.instanceState = null;\n                    r.curState = RESUMED;\n                }\n                if (desiredState == CREATED) {\n                    if (localLOGV) Log.v(TAG, r.id + \": stopping\");\n//                    mActivityThread.performStopActivity(r, false, \"moveToState-STARTED\");\n                    try {\n                        if(ActivityThread_performStopActivity.getMethod().getParameterTypes().length==2){\n                            ActivityThread_performStopActivity.invoke(mActivityThread,r,false);\n                        }else{\n                            ActivityThread_performStopActivity.invoke(mActivityThread,r,false,\"moveToState-STARTED\");\n                        }\n                    }catch (InvocationTargetException e){\n                        throw new RuntimeException(e.getTargetException());\n                    }\n                    r.curState = CREATED;\n                }\n                return;\n\n            case RESUMED:\n                if (desiredState == STARTED) {\n                    if (localLOGV) Log.v(TAG, r.id + \": pausing\");\n                    performPause(r, mFinishing);\n                    r.curState = STARTED;\n                }\n                if (desiredState == CREATED) {\n                    if (localLOGV) Log.v(TAG, r.id + \": pausing\");\n                    performPause(r, mFinishing);\n                    if (localLOGV) Log.v(TAG, r.id + \": stopping\");\n//                    mActivityThread.performStopActivity(r, false, \"moveToState-RESUMED\");\n                    try {\n                        if(ActivityThread_performStopActivity.getMethod().getParameterTypes().length==2){\n                            ActivityThread_performStopActivity.invoke(mActivityThread,r,false);\n                        }else{\n                            ActivityThread_performStopActivity.invoke(mActivityThread,r,false,\"moveToState-RESUMED\");\n                        }\n                    }catch (InvocationTargetException e){\n                        throw new RuntimeException(e.getTargetException());\n                    }\n                    r.curState = CREATED;\n                }\n                return;\n        }\n    }\n\n    private void performPause(LocalActivityRecord r, boolean finishing) {\n        final boolean needState = r.instanceState == null;\n//        final Bundle instanceState = mActivityThread.performPauseActivity(\n//                r, finishing, needState, \"performPause\");\n        Bundle instanceState = null;\n        try {\n            if(ActivityThread_performPauseActivity.getMethod().getParameterTypes().length==3){\n                instanceState = (Bundle) ActivityThread_performPauseActivity.invoke(mActivityThread,r,finishing,needState);\n            }else{\n                if (Build.VERSION.SDK_INT >= 28) {\n                    instanceState = (Bundle) ActivityThread_performPauseActivity.invoke(\n                            mActivityThread, r, finishing,/*needState,*/\"moveToState-RESUMED\",\n                            null);\n                } else {\n                    instanceState = (Bundle) ActivityThread_performPauseActivity.invoke(\n                            mActivityThread, r, finishing, needState, \"moveToState-RESUMED\");\n\n                }\n\n            }\n        }catch (InvocationTargetException e){\n            throw new RuntimeException(e.getTargetException());\n        }\n        if (needState) {\n            r.instanceState = instanceState;\n        }\n    }\n\n    /**\n     * Start a new activity running in the group.  Every activity you start\n     * must have a unique string ID associated with it -- this is used to keep\n     * track of the activity, so that if you later call startActivity() again\n     * on it the same activity object will be retained.\n     *\n     * <p>When there had previously been an activity started under this id,\n     * it may either be destroyed and a new one started, or the current\n     * one re-used, based on these conditions, in order:</p>\n     *\n     * <ul>\n     * <li> If the Intent maps to a different activity component than is\n     * currently running, the current activity is finished and a new one\n     * started.\n     * <li> If the current activity uses a non-multiple launch mode (such\n     * as singleTop), or the Intent has the\n     * {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} flag set, then the current\n     * activity will remain running and its\n     * {@link Activity#onNewIntent(Intent) Activity.onNewIntent()} method\n     * called.\n     * <li> If the new Intent is the same (excluding extras) as the previous\n     * one, and the new Intent does not have the\n     * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP} set, then the current activity\n     * will remain running as-is.\n     * <li> Otherwise, the current activity will be finished and a new\n     * one started.\n     * </ul>\n     *\n     * <p>If the given Intent can not be resolved to an available Activity,\n     * this method throws {@link ActivityNotFoundException}.\n     *\n     * <p>Warning: There is an issue where, if the Intent does not\n     * include an explicit component, we can restore the state for a different\n     * activity class than was previously running when the state was saved (if\n     * the set of available activities changes between those points).\n     *\n     * @param id Unique identifier of the activity to be started\n     * @param intent The Intent describing the activity to be started\n     *\n     * @return Returns the window of the activity.  The caller needs to take\n     * care of adding this window to a view hierarchy, and likewise dealing\n     * with removing the old window if the activity has changed.\n     *\n     * @throws ActivityNotFoundException\n     */\n    public Window startActivity(String id, Intent intent) {\n        if (mCurState == INITIALIZING) {\n            throw new IllegalStateException(\n                    \"Activities can't be added until the containing group has been created.\");\n        }\n\n        boolean adding = false;\n        boolean sameIntent = false;\n\n        ActivityInfo aInfo = null;\n\n        // Already have information about the new activity id?\n        LocalActivityRecord r = mActivities.get(id);\n        if (r == null) {\n            // Need to create it...\n            r = new LocalActivityRecord(id, intent);\n            adding = true;\n        } else if (r.intent != null) {\n            sameIntent = r.intent.filterEquals(intent);\n            if (sameIntent) {\n                // We are starting the same activity.\n                aInfo = r.activityInfo;\n            }\n        }\n        if (aInfo == null) {\n            aInfo = r.intent.resolveActivityInfo(\n                    RuntimeVariables.androidApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);\n            if (aInfo == null) {\n                // Throw an exception.\n                throw new ActivityNotFoundException(\n                        \"No Activity found to handle \" + intent);\n            }\n        }\n\n        // Pause the currently running activity if there is one and only a single\n        // activity is allowed to be running at a time.\n        if (mSingleMode) {\n            LocalActivityRecord old = mResumed;\n\n            // If there was a previous activity, and it is not the current\n            // activity, we need to stop it.\n            if (old != null && old != r && mCurState == RESUMED) {\n                moveToState(old, STARTED);\n            }\n        }\n\n        if (adding) {\n            // It's a brand new world.\n            mActivities.put(id, r);\n            mActivityArray.add(r);\n        } else if (r.activityInfo != null) {\n            // If the new activity is the same as the current one, then\n            // we may be able to reuse it.\n            if (aInfo == r.activityInfo ||\n                    (aInfo.name.equals(r.activityInfo.name) &&\n                            aInfo.packageName.equals(r.activityInfo.packageName))) {\n                if (aInfo.launchMode != ActivityInfo.LAUNCH_MULTIPLE ||\n                        (intent.getFlags()&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0) {\n                    // The activity wants onNewIntent() called.\n                    intent.setExtrasClassLoader(r.activity.getClassLoader());\n                    //TODO callActivityOnNewIntent use reflect\n                    //callActivityOnNewIntent(r.activity, intent);\n                    r.intent = intent;\n                    moveToState(r, mCurState);\n                    if (mSingleMode) {\n                        mResumed = r;\n                    }\n                    return r.window;\n                }\n                if (sameIntent &&\n                        (intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_TOP) == 0) {\n                    // We are showing the same thing, so this activity is\n                    // just resumed and stays as-is.\n                    r.intent = intent;\n                    moveToState(r, mCurState);\n                    if (mSingleMode) {\n                        mResumed = r;\n                    }\n                    return r.window;\n                }\n            }\n\n            // The new activity is different than the current one, or it\n            // is a multiple launch activity, so we need to destroy what\n            // is currently there.\n            performDestroy(r, true);\n        }\n\n        r.intent = intent;\n        r.curState = INITIALIZING;\n        r.activityInfo = aInfo;\n\n        moveToState(r, mCurState);\n\n        // When in single mode keep track of the current activity\n        if (mSingleMode) {\n            mResumed = r;\n        }\n        return r.window;\n    }\n\n    private Window performDestroy(LocalActivityRecord r, boolean finish) {\n        Window win;\n        win = r.window;\n        if (r.curState == RESUMED && !finish) {\n            performPause(r, finish);\n        }\n        if (localLOGV) Log.v(TAG, r.id + \": destroying\");\n        try {\n            if (Build.VERSION.SDK_INT >= 28) {\n                ActivityThread_performDestroyActivity.invoke(mActivityThread, r, finish, 0, false,\n                        \"destroy\");\n            } else {\n                ActivityThread_performDestroyActivity.invoke(mActivityThread, r, finish);\n\n            }\n\n        }catch (InvocationTargetException e){\n            throw new RuntimeException(e.getTargetException());\n        }\n        r.activity = null;\n        r.window = null;\n        if (finish) {\n            r.instanceState = null;\n        }\n        r.curState = DESTROYED;\n        return win;\n    }\n\n    /**\n     * Destroy the activity associated with a particular id.  This activity\n     * will go through the normal lifecycle events and fine onDestroy(), and\n     * then the id removed from the group.\n     *\n     * @param id Unique identifier of the activity to be destroyed\n     * @param finish If true, this activity will be finished, so its id and\n     * all state are removed from the group.\n     *\n     * @return Returns the window that was used to display the activity, or\n     * null if there was none.\n     */\n    public Window destroyActivity(String id, boolean finish) {\n        LocalActivityRecord r = mActivities.get(id);\n        Window win = null;\n        if (r != null) {\n            win = performDestroy(r, finish);\n            if (finish) {\n                mActivities.remove(id);\n                mActivityArray.remove(r);\n            }\n        }\n        return win;\n    }\n\n    /**\n     * Retrieve the Activity that is currently running.\n     *\n     * @return the currently running (resumed) Activity, or null if there is\n     *         not one\n     *\n     * @see #startActivity\n     * @see #getCurrentId\n     */\n    public Activity getCurrentActivity() {\n        return mResumed != null ? mResumed.activity : null;\n    }\n\n    /**\n     * Retrieve the ID of the activity that is currently running.\n     *\n     * @return the ID of the currently running (resumed) Activity, or null if\n     *         there is not one\n     *\n     * @see #startActivity\n     * @see #getCurrentActivity\n     */\n    public String getCurrentId() {\n        return mResumed != null ? mResumed.id : null;\n    }\n\n    /**\n     * Return the Activity object associated with a string ID.\n     *\n     * @see #startActivity\n     *\n     * @return the associated Activity object, or null if the id is unknown or\n     *         its activity is not currently instantiated\n     */\n    public Activity getActivity(String id) {\n        LocalActivityRecord r = mActivities.get(id);\n        return r != null ? r.activity : null;\n    }\n\n    /**\n     * Restore a state that was previously returned by {@link #saveInstanceState}.  This\n     * adds to the activity group information about all activity IDs that had\n     * previously been saved, even if they have not been started yet, so if the\n     * user later navigates to them the correct state will be restored.\n     *\n     * <p>Note: This does <b>not</b> change the current running activity, or\n     * start whatever activity was previously running when the state was saved.\n     * That is up to the client to do, in whatever way it thinks is best.\n     *\n     * @param state a previously saved state; does nothing if this is null\n     *\n     * @see #saveInstanceState\n     */\n    public void dispatchCreate(Bundle state) {\n        if (state != null) {\n            for (String id : state.keySet()) {\n                try {\n                    final Bundle astate = state.getBundle(id);\n                    LocalActivityRecord r = mActivities.get(id);\n                    if (r != null) {\n                        r.instanceState = astate;\n                    } else {\n                        r = new LocalActivityRecord(id, null);\n                        r.instanceState = astate;\n                        mActivities.put(id, r);\n                        mActivityArray.add(r);\n                    }\n                } catch (Exception e) {\n                    // Recover from -all- app errors.\n                    Log.e(TAG, \"Exception thrown when restoring LocalActivityManager state\", e);\n                }\n            }\n        }\n\n        mCurState = CREATED;\n    }\n\n    /**\n     * Retrieve the state of all activities known by the group.  For\n     * activities that have previously run and are now stopped or finished, the\n     * last saved state is used.  For the current running activity, its\n     * {@link Activity#onSaveInstanceState} is called to retrieve its current state.\n     *\n     * @return a Bundle holding the newly created state of all known activities\n     *\n     * @see #dispatchCreate\n     */\n    public Bundle saveInstanceState() {\n        Bundle state = null;\n\n        // FIXME: child activities will freeze as part of onPaused. Do we\n        // need to do this here?\n        final int N = mActivityArray.size();\n        for (int i=0; i<N; i++) {\n            final LocalActivityRecord r = mActivityArray.get(i);\n            if (state == null) {\n                state = new Bundle();\n            }\n            if ((r.instanceState != null || r.curState == RESUMED)\n                    && r.activity != null) {\n                // We need to save the state now, if we don't currently\n                // already have it or the activity is currently resumed.\n                final Bundle childState = new Bundle();\n//                r.activity.performSaveInstanceState(childState);\n                try {\n                    Activity_performSaveInstanceState.invoke(r.activity, childState);\n                }catch (InvocationTargetException e){\n                    throw new RuntimeException(e.getTargetException());\n                }\n                r.instanceState = childState;\n            }\n            if (r.instanceState != null) {\n                state.putBundle(r.id, r.instanceState);\n            }\n        }\n\n        return state;\n    }\n\n    /**\n     * Called by the container activity in its {@link Activity#onResume} so\n     * that LocalActivityManager can perform the corresponding action on the\n     * activities it holds.\n     *\n     * @see Activity#onResume\n     */\n    public void dispatchResume() {\n        mCurState = RESUMED;\n        if (mSingleMode) {\n            if (mResumed != null) {\n                moveToState(mResumed, RESUMED);\n            }\n        } else {\n            final int N = mActivityArray.size();\n            for (int i=0; i<N; i++) {\n                moveToState(mActivityArray.get(i), RESUMED);\n            }\n        }\n    }\n\n    public void dispatchStart(){\n        if (mSingleMode) {\n            if (mResumed != null) {\n                try {\n                    Activity_onStart.invoke(mResumed.activity);\n                } catch (InvocationTargetException e) {\n                    e.printStackTrace();\n                }\n            }\n        } else {\n            final int N = mActivityArray.size();\n            for (int i=0; i<N; i++) {\n                try {\n                    Activity_onStart.invoke(mActivityArray.get(i).activity);\n                } catch (InvocationTargetException e) {\n                    e.printStackTrace();\n                }\n            }\n        }\n    }\n\n    public void fakeStop(){\n        if (mSingleMode) {\n            if (mResumed != null) {\n                try {\n                    Activity_onStop.invoke(mResumed.activity);\n                } catch (InvocationTargetException e) {\n                    e.printStackTrace();\n                }\n            }\n        } else {\n            final int N = mActivityArray.size();\n            for (int i=0; i<N; i++) {\n                try {\n                    Activity_onStop.invoke(mActivityArray.get(i).activity);\n                } catch (InvocationTargetException e) {\n                    e.printStackTrace();\n                }\n            }\n        }\n    }\n\n    /**\n     * Called by the container activity in its {@link Activity#onPause} so\n     * that LocalActivityManager can perform the corresponding action on the\n     * activities it holds.\n     *\n     * @param finishing set to true if the parent activity has been finished;\n     *                  this can be determined by calling\n     *                  Activity.isFinishing()\n     *\n     * @see Activity#onPause\n     * @see Activity#isFinishing\n     */\n    public void dispatchPause(boolean finishing) {\n        if (finishing) {\n            mFinishing = true;\n        }\n        mCurState = STARTED;\n        if (mSingleMode) {\n            if (mResumed != null) {\n                moveToState(mResumed, STARTED);\n            }\n        } else {\n            final int N = mActivityArray.size();\n            for (int i=0; i<N; i++) {\n                LocalActivityRecord r = mActivityArray.get(i);\n                if (r.curState == RESUMED) {\n                    moveToState(r, STARTED);\n                }\n            }\n        }\n    }\n\n    /**\n     * Called by the container activity in its {@link Activity#onStop} so\n     * that LocalActivityManager can perform the corresponding action on the\n     * activities it holds.\n     *\n     * @see Activity#onStop\n     */\n    public void dispatchStop() {\n        mCurState = CREATED;\n        final int N = mActivityArray.size();\n        for (int i=0; i<N; i++) {\n            LocalActivityRecord r = mActivityArray.get(i);\n            moveToState(r, CREATED);\n        }\n    }\n\n    /**\n     * Call onRetainNonConfigurationInstance on each child activity and store the\n     * results in a HashMap by id.  Only construct the HashMap if there is a non-null\n     * object to store.  Note that this does not support nested ActivityGroups.\n     *\n     * {@hide}\n     */\n    public HashMap<String,Object> dispatchRetainNonConfigurationInstance() {\n        HashMap<String,Object> instanceMap = null;\n\n        final int N = mActivityArray.size();\n        for (int i=0; i<N; i++) {\n            LocalActivityRecord r = mActivityArray.get(i);\n            if ((r != null) && (r.activity != null)) {\n                Object instance = r.activity.onRetainNonConfigurationInstance();\n                if (instance != null) {\n                    if (instanceMap == null) {\n                        instanceMap = new HashMap<String,Object>();\n                    }\n                    instanceMap.put(r.id, instance);\n                }\n            }\n        }\n        return instanceMap;\n    }\n\n    /**\n     * Remove all activities from this LocalActivityManager, performing an\n     * {@link Activity#onDestroy} on any that are currently instantiated.\n     */\n    public void removeAllActivities() {\n        dispatchDestroy(true);\n    }\n\n    /**\n     * Called by the container activity in its {@link Activity#onDestroy} so\n     * that LocalActivityManager can perform the corresponding action on the\n     * activities it holds.\n     *\n     * @see Activity#onDestroy\n     */\n    public void dispatchDestroy(boolean finishing) {\n        final int N = mActivityArray.size();\n        for (int i=0; i<N; i++) {\n            LocalActivityRecord r = mActivityArray.get(i);\n            if (localLOGV) Log.v(TAG, r.id + \": destroying\");\n//            mActivityThread.performDestroyActivity(r, finishing);\n            try {\n                if (Build.VERSION.SDK_INT >= 28) {\n                    ActivityThread_performDestroyActivity.invoke(mActivityThread, r, finishing, 0,\n                            false, \"destroy\");\n                } else {\n                    ActivityThread_performDestroyActivity.invoke(mActivityThread, r, finishing);\n\n                }\n\n            }catch (InvocationTargetException e){\n                throw new RuntimeException(e.getTargetException());\n            }\n        }\n        mActivities.clear();\n        mActivityArray.clear();\n    }\n\n    public void switchToChildActivity(String key){\n        LocalActivityRecord r = mActivities.get(key);\n        if(r!=null){\n            dispatchPause(false);\n            fakeStop();\n            mResumed = r;\n            dispatchStart();\n            dispatchResume();\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/activitygroupcompat/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"libraryname_name\">ActivityGroupDelegateCompat</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/.gradletasknamecache",
    "content": "\n\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/build.gradle",
    "content": "group = 'com.taobao.android.atlasdemo'\nversion = getEnvValue(\"versionName\", \"1.0.0\");\ndef apVersion = getEnvValue(\"apVersion\", \"\");\n\napply plugin: 'com.android.application'\napply plugin: 'com.taobao.atlas'\n//apply plugin: 'com.taobao.atlas.dexpatch'\n\n//通过增加判断逻辑，打出不同类型的定制包\ndef appId = \"com.taobao.demo\"\ndef minVersion = 14\nif (project.hasProperty(\"beta\")) {\n\tappId = \"com.taobao.atlas.beta\"\n\tminVersion = 21\n}\n\nrepositories {\n    mavenLocal()\n    jcenter()\n}\n\nandroid {\n    compileSdkVersion 26\n    buildToolsVersion '26.0.2'\n    defaultConfig {\n        applicationId appId\n        minSdkVersion minVersion\n        targetSdkVersion 26\n        versionCode 1\n        versionName version\n        vectorDrawables.useSupportLibrary = true\n        //通过增加判断逻辑，打出不同类型的定制包\n        if (project.hasProperty(\"beta\")) {\n            buildConfigField \"boolean\", \"API_ENV\", \"false\"\n        }else{\n        \tbuildConfigField \"boolean\", \"API_ENV\", \"false\"\n        }\n        multiDexEnabled = false\n\n    }\n        \n    dataBinding {\n        enabled = true\n    }\n\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n\n\n    buildTypes {\n        release {\n            minifyEnabled true\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n        debug {\n            ndk {\n                abiFilters \"x86\",\"armeabi\"\n            }\n\n        }\n    }\n\n}\n\natlas {\n    instantAppEnabled true\n    atlasEnabled true\n    tBuildConfig {\n        preLaunch = 'com.taobao.demo.DemoPreLaunch'\n        classInject false\n        aaptConstantId true\n        dataBindingBundles = ['com.taobao.databindbundle']\n       allBundlesToMdex true\n\n    }\n\n   \n\n    patchConfigs {\n        debug {\n            createTPatch false\n        }\n    }\n\n\n    buildTypes {\n        debug {\n            if (apVersion) {\n                baseApDependency \"com.taobao.android.atlasdemo:AP-debug:${apVersion}@ap\"\n                patchConfig patchConfigs.debug\n            }\n        }\n    }\n}\n\n\ndependencies {\n\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n\n    compile project(':middlewarelibrary')\n    compile project(':splashscreen')\n    compile project(':databindinglibrary')\n//    compile project(':activitygroupcompat')\n    bundleCompile project(':firstbundle')\n    bundleCompile project(':secondbundle')\n    bundleCompile project(':remotebundle')\n    bundleCompile project(':publicbundle')\n    bundleCompile project(':databindbundle')\n    compile 'com.android.support:appcompat-v7:25.1.0'\n    compile 'com.android.support:design:25.1.0'\n    compile 'com.android.support:support-vector-drawable:25.1.0'\n    compile 'com.android.support:support-v4:25.1.0'\n    compile 'com.alibaba:fastjson:1.1.45.android@jar'\n    compile 'com.android.support.constraint:constraint-layout:1.0.2'\n    compile 'com.android.support:recyclerview-v7:25.3.0'\n    compile project(':atlas_core')\n}\n\nString getEnvValue(key, defValue) {\n    def val = System.getProperty(key);\n    if (null != val) {\n        return val;\n    }\n    val = System.getenv(key);\n    if (null != val) {\n        return val;\n    }\n    return defValue;\n}\n\ntasks.whenTaskAdded { task ->\n    if (task.name.contains(\"DebugAndroidTest\")) {\n        task.setEnabled(false);\n    }\n    if (task.name.contains(\"assemble\")) {\n        def files = null;\n        def file = new File(task.project.getBuildDir(), \"outputs\");\n        if (file.exists() && new File(file, \"tpatch-debug\").exists()) {\n            files = new File(file, \"tpatch-debug\").listFiles();\n        }\n        if (files != null) {\n            for (File file1 : files) {\n                if (file1.getName().endsWith(\".json\") || file1.getName().endsWith(\".tpatch\")) {\n\n                    if (!new File(task.project.getRootDir(), \"hisTpatch\").exists()) {\n                        new File(task.project.getRootDir(), \"hisTpatch\").mkdirs();\n                    }\n                    org.apache.commons.io.FileUtils.copyFileToDirectory(file1, new File(task.project.getRootDir(), \"hisTpatch\"));\n                }\n            }\n        }\n    }\n}\n\napply plugin: 'maven'\napply plugin: 'maven-publish'\n\npublishing {\n    repositories {\n        mavenLocal()\n    }\n}\n\npublishing {\n    publications {\n        maven(MavenPublication) {\n            artifact \"${project.buildDir}/outputs/apk/debug/${project.name}-debug.ap\"\n            artifactId \"AP-debug\"\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/dexPatchWraper.gradle",
    "content": "import groovy.json.JsonSlurper\nimport groovy.json.JsonOutput\nimport static Constants.*\n\n\n/**\n * Created by 种藏 on 2017/8/30.\n *\n * 1. 这个类只是对产物patches.json文件做个包装，用来模拟服务器控制dexPatch版本的逻辑,生成的产物是dexpatch-versionName.json\n *\n * 2. 正常开发情况，做dexPatch时，服务器会分配一个对应的dexPatchVersion。\n *    客户端比较dexPatchVersion来判断要不要做patch。\n *\n * 3. 这里只是每次做dexPatch时，简单的将dexPatchVersion 加 1.\n *\n * 4. 具体字段含义，参考https://alibaba.github.io/atlas/update/dexpatch_use_guide.html\n *\n */\n\ntasks.whenTaskAdded { task ->\n    if (task.name == \"assembleDebug\" || task.name == \"assembleRelease\") {\n        task.doLast {\n            wrapDexPatchFile(task.name.contains(\"Debug\"))\n        }\n    }\n//    if (task.name == \"clean\") {\n//        task.doLast { cleanPatchVersion() }\n//    }\n}\n\nclass Constants {\n    static final ENCODE_UTF_8 = \"UTF-8\"\n    static final PATH_VERSION_FILE = \"dexPatch.version\"\n}\n\ntask tesetm << {\n    wrapDexPatchFile(true)\n}\n\ndef wrapDexPatchFile(boolean debug) {\n\n    println \"root project :${rootProject.projectDir.path}\"\n\n    def apVersion = getEnvValue(\"apVersion\", \"-1\")\n    def versionName = getEnvValue(\"versionName\", \"-1\")\n    if (apVersion == \"-1\" || versionName == \"-1\") {\n        println(\"jump dexPatch\")\n        return\n    }\n\n    if (apVersion != versionName) {\n        return\n    }\n\n\n    println \"DexPatch wrap ,version  $versionName\"\n\n    String path = rootProject.projectDir.path + \"/app/build/outputs/tpatch-\" + (debug ? \"debug\" : \"release\") + \"/patchs.json\"\n    String patchPath = path.replace('/', File.separator)\n    println \"patchFile path :$patchPath\"\n\n    String fileContents = new File(patchPath).getText(ENCODE_UTF_8)\n    def patchConfig = new JsonSlurper().parseText(fileContents)\n    def updateInfo = patchConfig.patches[0]\n    updateInfo.dexPatch = true\n    def bundles = updateInfo.bundles\n    assert bundles instanceof List\n    def patchVersion = getPatchVersion()\n    bundles.each {\n        assert it instanceof Map\n        it.dexpatchVersion = patchVersion\n        it.isMainDex = it.mainBundle\n        it.remove(\"mainBundle\")\n        if (it.isMainDex) {\n            println \"=================>add empty main_dex dependency =============\"\n            it.dependency=[]\n        }\n    }\n    //写回到最终的dexPatch产物文件中\n    String wrapFilePath = \"${rootProject.projectDir.path}/app/build/outputs/tpatch-\" + (debug ? \"debug\" : \"release\") + \"/dexpatch-${patchConfig.baseVersion}.json\"\n    File wrapFile = new File(wrapFilePath.replace('/', File.separator))\n    if (wrapFile.exists()) wrapFile.delete()\n    wrapFile.createNewFile()\n    def dexPatchJson = JsonOutput.toJson(patchConfig)\n    wrapFile.setText(dexPatchJson, ENCODE_UTF_8)\n}\n\n//粗暴+1\ndef getPatchVersion() {\n    File versionFile = new File(rootProject.projectDir.path, PATH_VERSION_FILE)\n    if (!versionFile.exists()) versionFile.createNewFile()\n    String versionStr = versionFile.getText(ENCODE_UTF_8)\n    if (null == versionStr || versionStr.isEmpty()) {\n        versionStr = \"1\"\n    }\n    String nextVersion = String.valueOf(Integer.valueOf(versionStr) + 1)\n    versionFile.setText(nextVersion, ENCODE_UTF_8)\n    return versionStr\n}\n\ndef cleanPatchVersion() {\n    File versionFile = new File(rootProject.projectDir.path, PATH_VERSION_FILE)\n    if (versionFile.exists()) {\n        versionFile.delete()\n    }\n}\n\nString getEnvValue(key, defValue) {\n    def val = System.getProperty(key)\n    if (null != val) {\n        return val\n    }\n    val = System.getenv(key)\n    if (null != val) {\n        return val\n    }\n    return defValue\n}"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/jd-gui.cfg",
    "content": "<configuration>\n  <gui>\n    <mainWindow>\n      <location x='420' y='250' />\n      <size w='600' h='400' />\n      <maximize>false</maximize>\n    </mainWindow>\n    <lookAndFeel>system</lookAndFeel>\n  </gui>\n  <recentFilePaths>\n    <filePath>/Users/wuzhong/github/atlas/atlas-demo/AtlasDemo/app/build/intermediates/exploded-awb/AtlasDemo/firstbundle/unspecified/jars/classes.jar</filePath>\n  </recentFilePaths>\n  <recentDirectories>\n    <loadPath>/Users/wuzhong/github/atlas/atlas-demo/AtlasDemo/app</loadPath>\n    <savePath>/Users/wuzhong/github/atlas/atlas-demo/AtlasDemo/app</savePath>\n  </recentDirectories>\n  <preferences>\n    <JdGuiPreferences.errorBackgroundColor>0xFF6666</JdGuiPreferences.errorBackgroundColor>\n  </preferences>\n</configuration>"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n-dontwarn **\n-dontshrink\n-dontoptimize\n-dontobfuscate\n-ignorewarnings\n\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/push_dexpatch_out.sh",
    "content": "#!/bin/sh\n\nadb shell rm -rf /sdcard/Android/data/com.taobao.demo/cache\nadb shell mkdir /sdcard/Android/data/com.taobao.demo/cache\nadb push build/outputs/tpatch-debug/dexpatch-1.0.0.json /sdcard/Android/data/com.taobao.demo/cache/\nadb push build/outputs/tpatch-debug/1.0.0@1.0.0.tpatch /sdcard/Android/data/com.taobao.demo/cache/"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/androidTest/java/com/taobao/demo/ExampleInstrumentedTest.java",
    "content": "package com.taobao.demo;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() throws Exception {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.taobao.demo\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.taobao.demo\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n\n    <application\n        android:name=\".DemoApplication\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"Atlas\"\n        android:supportsRtl=\"true\">\n        <activity\n            android:name=\".MainActivity\"\n            android:label=\"@string/app_name\"\n            android:theme=\"@style/AppTheme.NoActionBar\" />\n        <activity\n            android:name=\".MainActivity2\"\n            android:label=\"@string/app_name\"\n            android:process=\":remote\"\n            android:theme=\"@style/AppTheme.NoActionBar\" />\n        <activity\n            android:name=\".UpdateDemoActivity\"\n            android:label=\"@string/title_activity_scrolling\"\n            android:theme=\"@style/AppTheme.NoActionBar\" />\n        <activity\n            android:name=\".RemoteDemoActivity\"\n            android:label=\"@string/title_activity_update\"\n            android:process=\":remote\"\n            android:theme=\"@style/AppTheme.NoActionBar\"></activity>\n\n        <provider\n            android:name=\".MyContentProvider\"\n            android:authorities=\"com.test.abc\"\n            android:enabled=\"true\"\n            android:exported=\"true\"></provider>\n    </application>\n\n</manifest>"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/java/com/taobao/demo/DemoApplication.java",
    "content": "package com.taobao.demo;\n\nimport android.app.Activity;\nimport android.app.Application;\nimport android.content.Intent;\nimport android.content.pm.PackageInfo;\nimport android.taobao.atlas.bundleInfo.AtlasBundleInfoManager;\nimport android.taobao.atlas.framework.Atlas;\nimport android.taobao.atlas.runtime.ActivityTaskMgr;\nimport android.text.TextUtils;\nimport android.widget.Toast;\n\nimport org.osgi.framework.BundleException;\n\nimport java.io.File;\n\n/**\n * Created by guanjie on 2017/3/16.\n */\n\npublic class DemoApplication extends Application {\n\n    @Override\n    public void onCreate() {\n\n        super.onCreate();\n//        Atlas.getInstance().setClassNotFoundInterceptorCallback(intent -> {\n//            final String className = intent.getComponent().getClassName();\n//            final String bundleName = AtlasBundleInfoManager.instance().getBundleForComponet(className);\n//\n//            if (!TextUtils.isEmpty(bundleName) && !AtlasBundleInfoManager.instance().isInternalBundle(bundleName)) {\n//\n//                //远程bundle\n//                Activity activity = ActivityTaskMgr.getInstance().peekTopActivity();\n//                File remoteBundleFile = new File(activity.getExternalCacheDir(),\"lib\" + bundleName.replace(\".\",\"_\") + \".so\");\n//\n//                String path = \"\";\n//                if (remoteBundleFile.exists()){\n//                    path = remoteBundleFile.getAbsolutePath();\n//                }else {\n//                    Toast.makeText(activity, \" 远程bundle不存在，请确定 : \" + remoteBundleFile.getAbsolutePath() , Toast.LENGTH_LONG).show();\n//                    return intent;\n//                }\n//\n//\n//                PackageInfo info = activity.getPackageManager().getPackageArchiveInfo(path, 0);\n//                try {\n//                    Atlas.getInstance().installBundle(info.packageName, new File(path));\n//                } catch (BundleException e) {\n//                    Toast.makeText(activity, \" 远程bundle 安装失败，\" + e.getMessage() , Toast.LENGTH_LONG).show();\n//\n//                    e.printStackTrace();\n//                }\n//\n//                activity.startActivities(new Intent[]{intent});\n//\n//            }\n//\n//            return intent;\n//        });\n\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/java/com/taobao/demo/DemoPreLaunch.java",
    "content": "package com.taobao.demo;\n\nimport android.content.Context;\nimport android.taobao.atlas.runtime.AtlasPreLauncher;\nimport android.util.Log;\n\n/**\n * Created by wuzhong on 2017/3/28.\n */\n\npublic class DemoPreLaunch implements AtlasPreLauncher {\n    @Override\n    public void initBeforeAtlas(Context context) {\n        Log.d(\"prelaunch\", \"prelaunch invokded\");\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/java/com/taobao/demo/MainActivity.java",
    "content": "package com.taobao.demo;\n\nimport android.content.Intent;\nimport android.os.AsyncTask;\nimport android.os.Bundle;\nimport android.support.design.widget.BottomNavigationView;\nimport android.support.design.widget.NavigationView;\nimport android.support.v4.view.GravityCompat;\nimport android.support.v4.widget.DrawerLayout;\nimport android.support.v7.app.ActionBarDrawerToggle;\nimport android.support.v7.app.AppCompatActivity;\nimport android.support.v7.widget.Toolbar;\nimport android.taobao.atlas.runtime.BundleIniter;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.util.Log;\nimport android.view.Menu;\nimport android.view.MenuItem;\nimport android.view.ViewGroup;\nimport android.widget.Toast;\n\nimport com.middleware.dialog.Dialog;\n\npublic class MainActivity extends AppCompatActivity\n        implements NavigationView.OnNavigationItemSelectedListener {\n\n\n    //    private ActivityGroupDelegate mActivityDelegate;\n\n    private final BottomNavigationView.OnNavigationItemSelectedListener\n            mOnNavigationItemSelectedListener\n\n            = item -> {\n                switch (item.getItemId()) {\n                    case R.id.navigation_home:\n                        switchToActivity(\"com.taobao.firstbundle.FirstBundleActivity\");\n                        Toast.makeText(RuntimeVariables.androidApplication,\"on click\",Toast.LENGTH_SHORT).show();\n                        return true;\n                    case R.id.navigation_dashboard:\n                        BundleIniter.initBundle(\"com.taobao.secondbundle\",null);\n                        switchToActivity(\"com.taobao.secondbundle.SecondBundleActivity\");\n                        return true;\n                    case R.id.navigation_notifications:\n                        \n    //                    Intent intent3 = new Intent();\n    //                    intent3.setClassName(getBaseContext(),\"com.taobao.firstBundle.FirstBundleActivity\");\n    //                    mActivityDelegate.execStartChildActivityInternal(mActivityGroupContainer,\"third\",intent3);\n                        return true;\n                }\n                return false;\n            };\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_navigation);\n        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);\n        setSupportActionBar(toolbar);\n        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);\n        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(\n                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);\n        drawer.setDrawerListener(toggle);\n        toggle.syncState();\n        Log.e(\"aa\",\"bbb\");\n\n\n        ((BottomNavigationView)findViewById(R.id.navigation)).setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);\n\n        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);\n        navigationView.setNavigationItemSelectedListener(this);\n//        mActivityDelegate = new ActivityGroupDelegate(this,savedInstanceState);\n        switchToActivity(\"com.taobao.firstbundle.FirstBundleActivity\");\n    }\n\n    public void switchToActivity(String activityName){\n//        RemoteFactory.requestRemote(RemoteFragment.class, this, new Intent(activityName),\n//                new RemoteFactory.OnRemoteStateListener<RemoteFragment>() {\n//                    @Override\n//                    public void onRemotePrepared(RemoteFragment iRemote) {\n//                        getSupportFragmentManager().beginTransaction()\n//                                .replace(R.id.content, iRemote)\n//                                .commit();\n//                    }\n//\n//                    @Override\n//                    public void onFailed(String s) {\n//                        Log.e(\"UserRemoteActivity\", s);\n//                    }\n//                });\n        Intent intent = new Intent();\n        intent.setClassName(getBaseContext(),activityName);\n        startActivity(intent);\n    }\n\n    @Override\n    public void onBackPressed() {\n        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);\n        if (drawer.isDrawerOpen(GravityCompat.START)) {\n            drawer.closeDrawer(GravityCompat.START);\n        } else {\n            super.onBackPressed();\n        }\n    }\n\n    @Override\n    public boolean onCreateOptionsMenu(Menu menu) {\n        // Inflate the menu; this adds items to the action bar if it is present.\n//        getMenuInflater().inflate(R.menu.main, menu);\n        return true;\n    }\n\n    @Override\n    public boolean onOptionsItemSelected(MenuItem item) {\n        // Handle action bar item clicks here. The action bar will\n        // automatically handle clicks on the Home/Up button, so long\n        // as you specify a parent activity in AndroidManifest.xml.\n        int id = item.getItemId();\n\n        //noinspection SimplifiableIfStatement\n        if (id == R.id.action_settings) {\n            Intent intent = new Intent();\n            intent.setClassName(this,\"com.taobao.firstbundle.WebViewDemoActivity\");\n            startActivity(intent);\n            return true;\n        }\n\n        return super.onOptionsItemSelected(item);\n    }\n\n    @SuppressWarnings(\"StatementWithEmptyBody\")\n    @Override\n    public boolean onNavigationItemSelected(MenuItem item) {\n        // Handle navigation view item clicks here.\n        int id = item.getItemId();\n\n//        if (id == R.id.nav_camera) {\n//            // Handle the camera action\n//        }\n//        else\n            if (id == R.id.nav_slideshow) {\n            Intent intent = new Intent();\n            intent.setClassName(this,\"com.taobao.demo.UpdateDemoActivity\");\n            startActivity(intent);\n\n        } else if (id == R.id.nav_manage) {\n\n            Intent intent = new Intent();\n                intent.setPackage(getPackageName());\n            intent.setClassName(this,\"com.taobao.demo.RemoteDemoActivity\");\n            startActivity(intent);\n\n        } else if (id == R.id.awo_manager) {\n            Dialog dialog = new Dialog(this,\"单bundle调试\",\n                    \"1、安装设备且连接电脑成功\\n\\n\"+\n                     \"2、修改一个bundle工程的代码或者自由（设置生效的标识）\\n\\n\"+\n                            \"3、bundle工程的目录下执行 ../gradlew clean assemblePatchDebug,然后等应用重启或者应用关闭后点击重启\");\n\n            dialog.show();\n\n\n        } else if (id == R.id.nav_databind_bundle) {\n\n                Intent intent = new Intent();\n                intent.setPackage(getPackageName());\n                intent.setClassName(this,\"com.taobao.databindbundle.databind.DataBundleSampleActivity\");\n                startActivity(intent);\n            }else if (id == R.id.nav_remote) {\n\n                Intent intent = new Intent();\n                intent.setPackage(getPackageName());\n                intent.setClassName(this,\"com.taobao.firstbundle.UseremoteActivity\");\n                startActivity(intent);\n            }\n\n        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);\n        drawer.closeDrawer(GravityCompat.START);\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/java/com/taobao/demo/MyContentProvider.java",
    "content": "package com.taobao.demo;\n\nimport android.content.ContentProvider;\nimport android.content.ContentValues;\nimport android.database.Cursor;\nimport android.net.Uri;\n\npublic class MyContentProvider extends ContentProvider {\n    public MyContentProvider() {\n    }\n\n    @Override\n    public int delete(Uri uri, String selection, String[] selectionArgs) {\n        // Implement this to handle requests to delete one or more rows.\n        throw new UnsupportedOperationException(\"Not yet implemented\");\n    }\n\n    @Override\n    public String getType(Uri uri) {\n        // TODO: Implement this to handle requests for the MIME type of the data\n        // at the given URI.\n        throw new UnsupportedOperationException(\"Not yet implemented\");\n    }\n\n    @Override\n    public Uri insert(Uri uri, ContentValues values) {\n        // TODO: Implement this to handle requests to insert a new row.\n        throw new UnsupportedOperationException(\"Not yet implemented\");\n    }\n\n    @Override\n    public boolean onCreate() {\n        // TODO: Implement this to initialize your content provider on startup.\n        return false;\n    }\n\n    @Override\n    public Cursor query(Uri uri, String[] projection, String selection,\n                        String[] selectionArgs, String sortOrder) {\n        // TODO: Implement this to handle query requests from clients.\n        throw new UnsupportedOperationException(\"Not yet implemented\");\n    }\n\n    @Override\n    public int update(Uri uri, ContentValues values, String selection,\n                      String[] selectionArgs) {\n        // TODO: Implement this to handle requests to update one or more rows.\n        throw new UnsupportedOperationException(\"Not yet implemented\");\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/java/com/taobao/demo/RemoteDemoActivity.java",
    "content": "package com.taobao.demo;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\nimport android.widget.Button;\n\n\npublic class RemoteDemoActivity extends AppCompatActivity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.guild_remote_bundle);\n\n        final Activity activity = this;\n\n        Button button = (Button) findViewById(R.id.load_remote_bundle);\n        button.setOnClickListener(view -> {\n            Intent intent = new Intent();\n            intent.setClassName(activity, \"com.taobao.remotebunle.RemoteBundleActivity\");\n            startActivity(intent);\n        });\n\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/java/com/taobao/demo/UpdateDemoActivity.java",
    "content": "package com.taobao.demo;\n\nimport android.os.AsyncTask;\nimport android.os.Bundle;\nimport android.support.design.widget.FloatingActionButton;\nimport android.support.v7.app.AppCompatActivity;\nimport android.support.v7.widget.Toolbar;\nimport android.view.Menu;\nimport android.widget.TextView;\n\n\npublic class UpdateDemoActivity extends AppCompatActivity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_scrolling);\n        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);\n        setSupportActionBar(toolbar);\n        ((TextView)findViewById(R.id.tv_guide)).setText(getString(R.string.update_step));\n        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);\n        fab.setOnClickListener(view -> {\n//                Snackbar.make(view, \"Replace with your own action\", Snackbar.LENGTH_LONG)\n//                        .setAction(\"Action\", null).show();\n            new AsyncTask<Void, Void, Void>() {\n                @Override\n                protected Void doInBackground(Void... voids) {\n//                    Updater.update(getBaseContext());\n                    return null;\n                }\n\n                @Override\n                protected void onPostExecute(Void aVoid) {\n                    android.os.Process.killProcess(android.os.Process.myPid());\n                }\n            }.execute();\n        });\n    }\n\n    @Override\n    public boolean onCreateOptionsMenu(Menu menu) {\n        // Inflate the menu; this adds items to the action bar if it is present.\n//        getMenuInflater().inflate(R.menu.menu_scrolling, menu);\n        return true;\n    }\n\n//    @Override\n//    public boolean onOptionsItemSelected(MenuItem item) {\n//        // Handle action bar item clicks here. The action bar will\n//        // automatically handle clicks on the Home/Up button, so long\n//        // as you specify a parent activity in AndroidManifest.xml.\n//        int id = item.getItemId();\n//\n//        //noinspection SimplifiableIfStatement\n//        if (id == R.id.action_settings) {\n//            return true;\n//        }\n//        return super.onOptionsItemSelected(item);\n//    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/java/com/taobao/demo/databind/DataBundleAarActivity.java",
    "content": "package com.taobao.demo.databind;\n\nimport android.app.Activity;\nimport android.databinding.DataBindingUtil;\nimport android.os.Bundle;\nimport android.text.Editable;\nimport android.text.TextWatcher;\nimport android.widget.EditText;\nimport android.widget.TextView;\n\nimport com.taobao.demo.R;\nimport com.taobao.demo.databinding.AarDatabindMainBinding;\n\n\npublic class DataBundleAarActivity extends Activity {\n    /**\n     * Called when the activity is first created.\n     */\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n\n        super.onCreate(savedInstanceState);\n\n        setContentView(R.layout.aar_databind_main);\n\n        TextView textView = (TextView) findViewById(R.id.xxxxx_aar);\n\n        AarDatabindMainBinding binding = DataBindingUtil.setContentView(this, R.layout.aar_databind_main);\n        final User user = new User(\"Test\", \"User\");\n        binding.setUser(user);\n\n        EditText editText = (EditText) findViewById(R.id.inputText_aar);\n        editText.addTextChangedListener(new TextWatcher() {\n            @Override\n            public void beforeTextChanged(CharSequence s, int start, int count, int after) {\n\n            }\n\n            @Override\n            public void onTextChanged(CharSequence s, int start, int before, int count) {\n                System.out.println(s);\n                user.setFirstName(s.toString());\n            }\n\n            @Override\n            public void afterTextChanged(Editable s) {\n\n            }\n        });\n\n\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/java/com/taobao/demo/databind/User.java",
    "content": "package com.taobao.demo.databind;\n\nimport android.databinding.BaseObservable;\nimport android.databinding.Bindable;\n\nimport com.taobao.demo.BR;\n\n/**\n * Created by wuzhong on 2016/10/19.\n */\n\npublic class User extends BaseObservable {\n\n    String firstName;\n    String lastName;\n\n    public User(String firstName, String lastName) {\n        this.firstName = firstName;\n        this.lastName = lastName;\n    }\n\n    @Bindable\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n        this.notifyPropertyChanged(BR.firstName);\n    }\n\n    @Bindable\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/java/com/taobao/update/Updater.java",
    "content": "//package com.taobao.update;/*\n// *\n// *\n// *                                  Apache License\n// *                            Version 2.0, January 2004\n// *                         http://www.apache.org/licenses/\n// *\n// *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n// *\n// *    1. Definitions.\n// *\n// *       \"License\" shall mean the terms and conditions for use, reproduction,\n// *       and distribution as defined by Sections 1 through 9 of this document.\n// *\n// *       \"Licensor\" shall mean the copyright owner or entity authorized by\n// *       the copyright owner that is granting the License.\n// *\n// *       \"Legal Entity\" shall mean the union of the acting entity and all\n// *       other entities that control, are controlled by, or are under common\n// *       control with that entity. For the purposes of this definition,\n// *       \"control\" means (i) the power, direct or indirect, to cause the\n// *       direction or management of such entity, whether by contract or\n// *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n// *       outstanding shares, or (iii) beneficial ownership of such entity.\n// *\n// *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n// *       exercising permissions granted by this License.\n// *\n// *       \"Source\" form shall mean the preferred form for making modifications,\n// *       including but not limited to software source code, documentation\n// *       source, and configuration files.\n// *\n// *       \"Object\" form shall mean any form resulting from mechanical\n// *       transformation or translation of a Source form, including but\n// *       not limited to compiled object code, generated documentation,\n// *       and conversions to other media types.\n// *\n// *       \"Work\" shall mean the work of authorship, whether in Source or\n// *       Object form, made available under the License, as indicated by a\n// *       copyright notice that is included in or attached to the work\n// *       (an example is provided in the Appendix below).\n// *\n// *       \"Derivative Works\" shall mean any work, whether in Source or Object\n// *       form, that is based on (or derived from) the Work and for which the\n// *       editorial revisions, annotations, elaborations, or other modifications\n// *       represent, as a whole, an original work of authorship. For the purposes\n// *       of this License, Derivative Works shall not include works that remain\n// *       separable from, or merely link (or bind by name) to the interfaces of,\n// *       the Work and Derivative Works thereof.\n// *\n// *       \"Contribution\" shall mean any work of authorship, including\n// *       the original version of the Work and any modifications or additions\n// *       to that Work or Derivative Works thereof, that is intentionally\n// *       submitted to Licensor for inclusion in the Work by the copyright owner\n// *       or by an individual or Legal Entity authorized to submit on behalf of\n// *       the copyright owner. For the purposes of this definition, \"submitted\"\n// *       means any form of electronic, verbal, or written communication sent\n// *       to the Licensor or its representatives, including but not limited to\n// *       communication on electronic mailing lists, source code control systems,\n// *       and issue tracking systems that are managed by, or on behalf of, the\n// *       Licensor for the purpose of discussing and improving the Work, but\n// *       excluding communication that is conspicuously marked or otherwise\n// *       designated in writing by the copyright owner as \"Not a Contribution.\"\n// *\n// *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n// *       on behalf of whom a Contribution has been received by Licensor and\n// *       subsequently incorporated within the Work.\n// *\n// *    2. Grant of Copyright License. Subject to the terms and conditions of\n// *       this License, each Contributor hereby grants to You a perpetual,\n// *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n// *       copyright license to reproduce, prepare Derivative Works of,\n// *       publicly display, publicly perform, sublicense, and distribute the\n// *       Work and such Derivative Works in Source or Object form.\n// *\n// *    3. Grant of Patent License. Subject to the terms and conditions of\n// *       this License, each Contributor hereby grants to You a perpetual,\n// *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n// *       (except as stated in this section) patent license to make, have made,\n// *       use, offer to sell, sell, import, and otherwise transfer the Work,\n// *       where such license applies only to those patent claims licensable\n// *       by such Contributor that are necessarily infringed by their\n// *       Contribution(s) alone or by combination of their Contribution(s)\n// *       with the Work to which such Contribution(s) was submitted. If You\n// *       institute patent litigation against any entity (including a\n// *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n// *       or a Contribution incorporated within the Work constitutes direct\n// *       or contributory patent infringement, then any patent licenses\n// *       granted to You under this License for that Work shall terminate\n// *       as of the date such litigation is filed.\n// *\n// *    4. Redistribution. You may reproduce and distribute copies of the\n// *       Work or Derivative Works thereof in any medium, with or without\n// *       modifications, and in Source or Object form, provided that You\n// *       meet the following conditions:\n// *\n// *       (a) You must give any other recipients of the Work or\n// *           Derivative Works a copy of this License; and\n// *\n// *       (b) You must cause any modified files to carry prominent notices\n// *           stating that You changed the files; and\n// *\n// *       (c) You must retain, in the Source form of any Derivative Works\n// *           that You distribute, all copyright, patent, trademark, and\n// *           attribution notices from the Source form of the Work,\n// *           excluding those notices that do not pertain to any part of\n// *           the Derivative Works; and\n// *\n// *       (d) If the Work includes a \"NOTICE\" text file as part of its\n// *           distribution, then any Derivative Works that You distribute must\n// *           include a readable copy of the attribution notices contained\n// *           within such NOTICE file, excluding those notices that do not\n// *           pertain to any part of the Derivative Works, in at least one\n// *           of the following places: within a NOTICE text file distributed\n// *           as part of the Derivative Works; within the Source form or\n// *           documentation, if provided along with the Derivative Works; or,\n// *           within a display generated by the Derivative Works, if and\n// *           wherever such third-party notices normally appear. The contents\n// *           of the NOTICE file are for informational purposes only and\n// *           do not modify the License. You may add Your own attribution\n// *           notices within Derivative Works that You distribute, alongside\n// *           or as an addendum to the NOTICE text from the Work, provided\n// *           that such additional attribution notices cannot be construed\n// *           as modifying the License.\n// *\n// *       You may add Your own copyright statement to Your modifications and\n// *       may provide additional or different license terms and conditions\n// *       for use, reproduction, or distribution of Your modifications, or\n// *       for any such Derivative Works as a whole, provided Your use,\n// *       reproduction, and distribution of the Work otherwise complies with\n// *       the conditions stated in this License.\n// *\n// *    5. Submission of Contributions. Unless You explicitly state otherwise,\n// *       any Contribution intentionally submitted for inclusion in the Work\n// *       by You to the Licensor shall be under the terms and conditions of\n// *       this License, without any additional terms or conditions.\n// *       Notwithstanding the above, nothing herein shall supersede or modify\n// *       the terms of any separate license agreement you may have executed\n// *       with Licensor regarding such Contributions.\n// *\n// *    6. Trademarks. This License does not grant permission to use the trade\n// *       names, trademarks, service marks, or product names of the Licensor,\n// *       except as required for reasonable and customary use in describing the\n// *       origin of the Work and reproducing the content of the NOTICE file.\n// *\n// *    7. Disclaimer of Warranty. Unless required by applicable law or\n// *       agreed to in writing, Licensor provides the Work (and each\n// *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n// *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n// *       implied, including, without limitation, any warranties or conditions\n// *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n// *       PARTICULAR PURPOSE. You are solely responsible for determining the\n// *       appropriateness of using or redistributing the Work and assume any\n// *       risks associated with Your exercise of permissions under this License.\n// *\n// *    8. Limitation of Liability. In no event and under no legal theory,\n// *       whether in tort (including negligence), contract, or otherwise,\n// *       unless required by applicable law (such as deliberate and grossly\n// *       negligent acts) or agreed to in writing, shall any Contributor be\n// *       liable to You for damages, including any direct, indirect, special,\n// *       incidental, or consequential damages of any character arising as a\n// *       result of this License or out of the use or inability to use the\n// *       Work (including but not limited to damages for loss of goodwill,\n// *       work stoppage, computer failure or malfunction, or any and all\n// *       other commercial damages or losses), even if such Contributor\n// *       has been advised of the possibility of such damages.\n// *\n// *    9. Accepting Warranty or Additional Liability. While redistributing\n// *       the Work or Derivative Works thereof, You may choose to offer,\n// *       and charge a fee for, acceptance of support, warranty, indemnity,\n// *       or other liability obligations and/or rights consistent with this\n// *       License. However, in accepting such obligations, You may act only\n// *       on Your own behalf and on Your sole responsibility, not on behalf\n// *       of any other Contributor, and only if You agree to indemnify,\n// *       defend, and hold each Contributor harmless for any liability\n// *       incurred by, or claims asserted against, such Contributor by reason\n// *       of your accepting any such warranty or additional liability.\n// *\n// *    END OF TERMS AND CONDITIONS\n// *\n// *    APPENDIX: How to apply the Apache License to your work.\n// *\n// *       To apply the Apache License to your work, attach the following\n// *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n// *       replaced with your own identifying information. (Don't include\n// *       the brackets!)  The text should be enclosed in the appropriate\n// *       comment syntax for the file format. We also recommend that a\n// *       file or class name and description of purpose be included on the\n// *       same \"printed page\" as the copyright notice for easier\n// *       identification within third-party archives.\n// *\n// *    Copyright 2016 Alibaba Group\n// *\n// *    Licensed under the Apache License, Version 2.0 (the \"License\");\n// *    you may not use this file except in compliance with the License.\n// *    You may obtain a copy of the License at\n// *\n// *        http://www.apache.org/licenses/LICENSE-2.0\n// *\n// *    Unless required by applicable law or agreed to in writing, software\n// *    distributed under the License is distributed on an \"AS IS\" BASIS,\n// *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// *    See the License for the specific language governing permissions and\n// *    limitations under the License.\n// *\n// *\n// *//*\n//\n//\n//package com.taobao.update;\n//\n//import android.content.Context;\n//import android.os.Handler;\n//import android.os.Looper;\n//import android.text.TextUtils;\n//import android.util.Log;\n//import android.widget.Toast;\n//\n//import com.alibaba.fastjson.JSON;\n//\n//import com.taobao.atlas.dex.util.FileUtils;\n//import com.taobao.atlas.update.AtlasUpdater;\n//import com.taobao.atlas.update.model.UpdateInfo;\n//\n//import org.json.JSONArray;\n//import org.json.JSONException;\n//import org.json.JSONObject;\n//\n//import java.io.File;\n//import java.util.ArrayList;\n//import java.util.List;\n//\n//*/\n//\n//import android.content.Context;\n//\n//import java.io.File;\n//\n///**\n// * Created by wuzhong on 2016/12/20.\n// *//*\n//\n//*/\n//public class Updater {\n//\n//    public static void update(Context context) {\n//\n//\n////        try {\n////            String versionName = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;\n////            File updateInfo = new File(context.getExternalCacheDir(), \"update-\" + versionName + \".json\");\n////\n////            if (!updateInfo.exists()) {\n////                Log.e(\"update\", \"更新信息不存在，请先 执行 buildTpatch.sh\");\n////                toast(\"更新信息不存在，请先 执行 buildTpatch.sh\", context);\n////                return;\n////            }\n////\n////            String jsonStr = new String(FileUtils.readFile(updateInfo));\n////            UpdateInfo info = JSON.parseObject(jsonStr, UpdateInfo.class);\n////\n////            File patchFile = new File(context.getExternalCacheDir(),\n////                    \"patch-\" + info.updateVersion + \"@\" + info.baseVersion + \".tpatch\");\n////            AtlasUpdater.update(info, patchFile);\n////            Log.e(\"update\", \"update success\");\n////            toast(\"更新成功，请重启app\", context);\n////        } catch (Throwable e) {\n////            e.printStackTrace();\n////            toast(\"更新失败, \" + e.getMessage(), context);\n////        }\n//    }\n//\n//\n//\n//    private static UpdateInfo parseDexPatchJson(JSONObject data) throws JSONException {\n//        if (null == data) {\n//            return null;\n//        }\n//        JSONObject updateJson = data.getJSONArray(\"patches\").getJSONObject(0);\n//        JSONArray bundles = updateJson.getJSONArray(\"bundles\");\n//        if (null == bundles || bundles.length() < 1) {\n//            return null;\n//        }\n//        UpdateInfo updateInfo = new UpdateInfo();\n//        updateInfo.dexPatch = updateJson.optBoolean(\"dexPatch\", true);\n//        updateInfo.baseVersion = data.getString(\"baseVersion\");\n//        updateInfo.updateBundles = new ArrayList<>(bundles.length());\n//        for (int i = 0; i < bundles.length(); i++) {\n//            JSONObject object = bundles.getJSONObject(i);\n//            JSONArray dependencies = object.getJSONArray(\"dependency\");\n//            List<String> dep = new ArrayList<>();\n//            if (dependencies != null && dependencies.length() > 0) {\n//                for (int j = 0; j < dependencies.length(); j++) {\n//                    dep.add((String)dependencies.get(j));\n//                }\n//            }\n//            UpdateInfo.Item item = new UpdateInfo.Item();\n//            item.dependency = dep;\n//            item.dexpatchVersion = object.getLong(\"dexpatchVersion\");\n//            item.isMainDex = object.getBoolean(\"isMainDex\");\n//            item.reset = object.optBoolean(\"reset\", false);\n//            item.name = object.getString(\"name\");\n//            item.unitTag = object.getString(\"unitTag\");\n//            item.srcUnitTag = object.getString(\"srcUnitTag\");\n//            updateInfo.updateBundles.add(item);\n//        }\n//        return updateInfo;\n//    }\n//}\n//\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/drawable/ic_dashboard_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z\" />\n</vector>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/drawable/ic_home_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z\" />\n</vector>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/drawable/ic_notifications_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z\" />\n</vector>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/drawable/side_nav_bar.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:endColor=\"#336699\"\n        android:startColor=\"#669999\"\n        android:type=\"linear\" />\n</shape>"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/layout/aar_databind_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <data>\n        <variable name=\"user\" type=\"com.taobao.demo.databind.User\"/>\n    </data>\n    <LinearLayout\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <EditText\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:id=\"@+id/inputText_aar\" />\n\n\n        <TextView android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"@{user.firstName}\"/>\n        <TextView android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"@{user.lastName}\"/>\n\n\n        <TextView\n            android:layout_width=\"fill_parent\"\n            android:layout_height=\"fill_parent\"\n            android:id=\"@+id/xxxxx_aar\"\n            android:text=\"abcd\"\n            />\n\n    </LinearLayout>\n</layout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/container\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\"\n    tools:context=\"com.taobao.demo.MainActivity2\">\n\n    <FrameLayout\n        android:id=\"@+id/content\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\">\n\n    </FrameLayout>\n\n    <android.support.design.widget.BottomNavigationView\n        android:id=\"@+id/navigation\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom\"\n        android:background=\"?android:attr/windowBackground\"\n        app:menu=\"@menu/navigation\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/layout/activity_navigation.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.v4.widget.DrawerLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/drawer_layout\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:fitsSystemWindows=\"true\"\n    tools:openDrawer=\"start\">\n\n    <include\n        layout=\"@layout/app_bar_main\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n\n    <android.support.design.widget.NavigationView\n        android:id=\"@+id/nav_view\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"match_parent\"\n        android:layout_gravity=\"start\"\n        android:fitsSystemWindows=\"true\"\n        app:headerLayout=\"@layout/nav_header_main\"\n        app:menu=\"@menu/activity_main_drawer\" />\n\n</android.support.v4.widget.DrawerLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/layout/activity_scrolling.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.design.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.taobao.demo.UpdateDemoActivity\">\n\n    <android.support.design.widget.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <android.support.v7.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?attr/actionBarSize\"\n            android:background=\"?attr/colorPrimary\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\" />\n\n    </android.support.design.widget.AppBarLayout>\n\n    <include layout=\"@layout/content_main\" />\n\n    <android.support.design.widget.FloatingActionButton\n        android:id=\"@+id/fab\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom|end\"\n        android:layout_margin=\"@dimen/fab_margin\"\n        app:srcCompat=\"@android:drawable/ic_dialog_email\" />\n\n</android.support.design.widget.CoordinatorLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/layout/activity_update.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.taobao.demo.RemoteDemoActivity\">\n\n</android.support.constraint.ConstraintLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/layout/app_bar_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\"\n    tools:context=\"com.taobao.demo.MainActivity\">\n\n    <android.support.design.widget.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <android.support.v7.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?attr/actionBarSize\"\n            android:background=\"?attr/colorPrimary\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\" />\n\n    </android.support.design.widget.AppBarLayout>\n\n    <include layout=\"@layout/content_navigation_main\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/layout/content_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    >\n\n    <TextView\n        android:id=\"@+id/tv_guide\"\n        android:paddingLeft=\"8dp\"\n        android:paddingRight=\"8dp\"\n        android:paddingTop=\"52dp\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"@string/awo_step\"\n        tools:layout_editor_absoluteX=\"0dp\"\n        android:layout_marginBottom=\"8dp\"\n        android:layout_marginTop=\"8dp\" />\n\n</FrameLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/layout/content_navigation_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n    <LinearLayout\n        xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n        android:id=\"@+id/container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <FrameLayout\n            android:id=\"@+id/content\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\">\n\n        </FrameLayout>\n\n        <android.support.design.widget.BottomNavigationView\n            android:id=\"@+id/navigation\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"bottom\"\n            android:background=\"?android:attr/windowBackground\"\n            app:menu=\"@menu/navigation\" />\n\n    </LinearLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/layout/content_scrolling.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.v4.widget.NestedScrollView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n    tools:context=\"taobao.myapplication.ScrollingActivity\"\n    tools:showIn=\"@layout/activity_scrolling\">\n\n    <TextView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"@dimen/text_margin\"\n        android:text=\"sdfsdfsdfsdfsdfsdfsdfsdfsdfsd\" />\n\n</android.support.v4.widget.NestedScrollView>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/layout/guild_remote_bundle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"vertical\" android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <TextView\n        android:id=\"@+id/tv_guide\"\n        android:paddingLeft=\"8dp\"\n        android:paddingRight=\"8dp\"\n        android:paddingTop=\"52dp\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"@string/remote_bundle_step\"\n        android:layout_marginBottom=\"8dp\"\n        android:layout_marginTop=\"8dp\" />\n\n\n    <Button\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:id=\"@+id/load_remote_bundle\"\n        android:text=\"加载远程bundle\"/>\n\n\n\n\n</LinearLayout>"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/layout/nav_header_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"@dimen/nav_header_height\"\n    android:background=\"@drawable/side_nav_bar\"\n    android:gravity=\"bottom\"\n    android:orientation=\"vertical\"\n    android:paddingBottom=\"@dimen/activity_vertical_margin\"\n    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n    android:paddingRight=\"@dimen/activity_horizontal_margin\"\n    android:paddingTop=\"@dimen/activity_vertical_margin\"\n    android:theme=\"@style/ThemeOverlay.AppCompat.Dark\">\n\n    <ImageView\n        android:id=\"@+id/imageView\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:paddingTop=\"@dimen/nav_header_vertical_spacing\"\n        app:srcCompat=\"@drawable/logo\" />\n\n    <TextView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:paddingTop=\"@dimen/nav_header_vertical_spacing\"\n        android:text=\"AtlasDemo\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Body1\" />\n\n    <TextView\n        android:id=\"@+id/textView\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:autoLink=\"web\"\n        android:text=\"https://github.com/alibaba/atlas\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/menu/activity_main_drawer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <group android:checkableBehavior=\"single\">\n        <!--<item-->\n            <!--android:id=\"@+id/nav_gallery\"-->\n            <!--android:title=\"Gallery\" />-->\n        <item\n            android:id=\"@+id/nav_slideshow\"\n            android:title=\"动态部署模拟\" />\n        <item\n            android:id=\"@+id/nav_manage\"\n            android:title=\"远程组件模拟\" />\n        <item\n            android:id=\"@+id/awo_manager\"\n            android:title=\"单模块调试模拟\" />\n        <item\n            android:id=\"@+id/nav_dex_patch\"\n            android:title=\"dex_patch模拟\" />\n        <item\n            android:id=\"@+id/nav_databind_bundle\"\n            android:title=\"databinding模拟\" />\n\n        <item\n            android:id=\"@+id/nav_remote\"\n            android:title=\"跨bundle使用View模拟\" />\n    </group>\n\n    <item android:title=\"Communicate\">\n        <menu>\n            <!--<item-->\n                <!--android:id=\"@+id/nav_send\"-->\n                <!--android:title=\"介绍\" />-->\n            <item\n                android:id=\"@+id/nav_share\"\n                android:title=\"分享\" />\n        </menu>\n    </item>\n\n</menu>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/menu/main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n    <item\n        android:id=\"@+id/action_settings\"\n        android:orderInCategory=\"100\"\n        android:title=\"@string/action_settings\"\n        app:showAsAction=\"never\" />\n</menu>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/menu/navigation.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item\n        android:id=\"@+id/navigation_home\"\n        android:icon=\"@drawable/ic_home_black_24dp\"\n        android:title=\"@string/title_home\" />\n\n    <item\n        android:id=\"@+id/navigation_dashboard\"\n        android:icon=\"@drawable/ic_dashboard_black_24dp\"\n        android:title=\"@string/title_dashboard\" />\n\n    <item\n        android:id=\"@+id/navigation_notifications\"\n        android:icon=\"@drawable/ic_notifications_black_24dp\"\n        android:title=\"@string/title_notifications\" />\n\n</menu>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n    <dimen name=\"text_margin\">16dp</dimen>\n    <dimen name=\"nav_header_vertical_spacing\">16dp</dimen>\n    <dimen name=\"nav_header_height\">160dp</dimen>\n    <dimen name=\"fab_margin\">16dp</dimen>\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/values/main_style.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <style name=\"NavigationDrawAppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n    <style name=\"AppTheme.AppBarOverlay\" parent=\"ThemeOverlay.AppCompat.Dark.ActionBar\" />\n\n    <style name=\"AppTheme.PopupOverlay\" parent=\"ThemeOverlay.AppCompat.Light\" />\n\n</resources>"
  },
  {
    "path": "atlas-demo/AtlasDemo/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">AtlasDemo</string>\n    <string name=\"title_home\">goFirst</string>\n    <string name=\"title_dashboard\">goSecond</string>\n    <string name=\"title_notifications\">待定</string>\n\n    <string name=\"navigation_drawer_open\">Open navigation drawer</string>\n    <string name=\"navigation_drawer_close\">Close navigation drawer</string>\n\n    <string name=\"action_settings\">Settings</string>\n    <string name=\"title_activity_welcome\">WelcomeActivity</string>\n    <string name=\"dummy_button\">Dummy Button</string>\n    <string name=\"dummy_content\">DUMMY\\nCONTENT</string>\n    <string name=\"title_activity_scrolling\">动态部署模拟</string>\n    <string name=\"update_step\">\n        \"请根据工程根目录下的Tpatch.txt执行动态部署的过程\"\n\n\n    </string>\n    <string name=\"awo_step\">\n\n        \"请根据下面步骤执行单模块替换（用于开发测试）.\\n\\n\"\n\n        \"1、设备上安装基线版本\\n\"\n        \"看到这个界面表示你的设备上已经安装成功demo，成功的开始！\\n\\n\"\n\n        \"2、修改你的代码或者资源\\n\"\n        \"可以通过明显样式的修改或者打log来标识你的修改是否成功，manifest不能修改，新增Component的机制我们后续会尽快支持\\n\\n\"\n\n        \"3、执行awo构建\\n\"\n\n        \"Motion respects and reinforces the user as the prime mover. Primary user actions are \\n\\n\"\n\n        \"4、将patch产物push倒你的设备上\\n\"\n\n        \"The material environment is a 3D space, which means all objects have x, y, and z \\n\\n\"\n\n        \"5、点击红色按钮执行动态部署\\n\"\n\n        \"也可以尝试PC上执行adb shell am broadcast sdfsdfsdf -e pkg com.taobao.demo\"\n\n\n    </string>\n\n    <string name=\"remote_bundle_step\">\n\n        \"请根据下面步骤执行: \\n\\n\"\n\n        \"1、添加远程bundle的依赖， 如 `bundleCompile project(':remotebundle')` ， 参考 app/build.gradle  \\n\\n\"\n\n        \"2、声明远程bundle列表， \\n atlas { tBuildConfig { outOfApkBundles = ['remotebundle'] }  \\n\\n\"\n\n        \"3、构建完整包  assembleDebug \\n\"\n\n           apk 路径：app/build/outputs/apk/ \\n\"\n           远程bundle 路径：app/build/outputs/remote-bundles-debug \\n\\n\"\n\n        \"4、将远程sopush倒你的设备上\\n\"\n\n            \"可以尝试PC上执行adb push app/build/outputs/remote-bundles-debug/libcom_taobao_remotebunle.so /sdcard/Android/data/com.taobao.demo/cache/libcom_taobao_remotebunle.so \\n\\n\"\n\n        \"5、点击下方按钮，加载远程bundle \\n\"\n\n    </string>\n\n\n    <string name=\"title_activity_update\">UpdateActivity</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    repositories {\n        mavenLocal()\n        jcenter()\n        google()\n\n    }\n    configurations.all {\n        resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds'\n        resolutionStrategy.cacheChangingModulesFor 0, 'seconds'\n    }\n    dependencies {\n        classpath \"com.taobao.android:atlasplugin:3.0.1-rc88\"\n    }\n}\n\next {\n    lib_atlas_core = \"com.taobao.android:atlas_core:5.1.0.9-rc26\"\n}\n\nsubprojects {\n    repositories {\n        jcenter()\n        google()\n\n    }\n\n    configurations {\n        compileProject.extendsFrom compile, archives\n        runtimeProject.extendsFrom runtime, archives\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindbundle/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindbundle/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'com.taobao.atlas'\n\natlas {\n    bundleConfig{\n        awbBundle true\n    }\n    buildTypes {\n        debug {\n            baseApFile project.rootProject.file('app/build/outputs/apk/app-debug.ap')\n        }\n    }\n}\ngroup = 'com.atlas.demo'\nversion = '1.0.0'\n\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion '26.0.2'\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n\n    dataBinding{\n        enabled=true\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    providedCompile project(':middlewarelibrary')\n//    bundleCompile project(':publicbundle')\n\n    providedCompile 'com.android.support:support-v4:25.3.0'\n    providedCompile 'com.android.support:appcompat-v7:25.1.0'\n    providedCompile 'com.android.support.constraint:constraint-layout:1.0.2'\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindbundle/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindbundle/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.taobao.databindbundle\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:supportsRtl=\"true\">\n\n        <activity\n            android:name=\".databind.DataBundleSampleActivity\"\n            android:theme=\"@style/AppTheme.NoActionBar\"\n            android:label=\"databind\"\n            >\n            <!--<intent-filter>-->\n                <!--<action android:name=\"android.intent.action.MAIN\" />-->\n                <!--<category android:name=\"android.intent.category.LAUNCHER\" />-->\n            <!--</intent-filter>-->\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindbundle/src/main/java/com/taobao/databindbundle/databind/DataBundleSampleActivity.java",
    "content": "package com.taobao.databindbundle.databind;\n\nimport android.app.Activity;\nimport android.databinding.DataBindingUtil;\nimport android.os.Bundle;\nimport android.text.Editable;\nimport android.text.TextWatcher;\nimport android.widget.EditText;\nimport android.widget.TextView;\n\nimport com.taobao.databindbundle.R;\nimport com.taobao.databindbundle.databinding.BundleDatabindMainBinding;\n\nimport static com.taobao.databindbundle.R.layout.bundle_databind_main;\n\n\npublic class DataBundleSampleActivity extends Activity {\n    /**\n     * Called when the activity is first created.\n     */\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n\n        super.onCreate(savedInstanceState);\n\n        setContentView(bundle_databind_main);\n\n        TextView textView = (TextView) findViewById(R.id.xxxxx);\n\n        BundleDatabindMainBinding binding = DataBindingUtil.setContentView(this, bundle_databind_main);\n        final User user = new User(\"Test\", \"User\");\n        binding.setUser(user);\n\n        EditText editText = (EditText) findViewById(R.id.inputText);\n        editText.addTextChangedListener(new TextWatcher() {\n            @Override\n            public void beforeTextChanged(CharSequence s, int start, int count, int after) {\n\n            }\n\n            @Override\n            public void onTextChanged(CharSequence s, int start, int before, int count) {\n                System.out.println(s);\n                user.setFirstName(s.toString());\n            }\n\n            @Override\n            public void afterTextChanged(Editable s) {\n\n            }\n        });\n\n\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindbundle/src/main/java/com/taobao/databindbundle/databind/User.java",
    "content": "package com.taobao.databindbundle.databind;\n\nimport android.databinding.BaseObservable;\nimport android.databinding.Bindable;\n\nimport com.taobao.databindbundle.BR;\n\n/**\n * Created by wuzhong on 2016/10/19.\n */\n\npublic class User extends BaseObservable {\n\n    String firstName;\n    String lastName;\n\n    public User(String firstName, String lastName) {\n        this.firstName = firstName;\n        this.lastName = lastName;\n    }\n\n    @Bindable\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n        this.notifyPropertyChanged(BR.firstName);\n    }\n\n    @Bindable\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindbundle/src/main/res/layout/bundle_databind_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <data>\n        <variable name=\"user\" type=\"com.taobao.databindbundle.databind.User\"/>\n    </data>\n    <LinearLayout\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <EditText\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:id=\"@+id/inputText\" />\n\n\n        <TextView android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"@{user.firstName}\"/>\n        <TextView android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"@{user.lastName}\"/>\n\n\n        <TextView\n            android:layout_width=\"fill_parent\"\n            android:layout_height=\"fill_parent\"\n            android:id=\"@+id/xxxxx\"\n            android:text=\"abcd\"\n            />\n\n    </LinearLayout>\n</layout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindbundle/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">DataBinding</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindinglibrary/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindinglibrary/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\ngroup = 'com.atlas.demo'\nversion = '1.0.0'\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion '26.0.2'\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n\n    dataBinding{\n        enabled=true\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile 'com.android.support:appcompat-v7:25.1.0'\n    compile 'com.android.support:support-v4:25.1.0'\n    compile 'com.android.support:recyclerview-v7:25.3.0'\n    compile 'com.android.support:design:25.3.0'\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindinglibrary/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindinglibrary/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.taobao.databindlibrary\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:supportsRtl=\"true\">\n        <activity\n            android:name=\"com.taobao.databinding.library.DataBingAarActivity\"\n            android:label=\"aaa\"\n            android:theme=\"@style/Theme.AppCompat.NoActionBar\"></activity>\n\n    </application>\n\n</manifest>"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindinglibrary/src/main/java/com/taobao/databinding/library/DataBingAarActivity.java",
    "content": "package com.taobao.databinding.library;\nimport android.app.Activity;\nimport android.databinding.DataBindingUtil;\nimport android.os.Bundle;\nimport android.text.Editable;\nimport android.text.TextWatcher;\nimport android.widget.EditText;\nimport android.widget.TextView;\nimport com.taobao.databindlibrary.R;\nimport com.taobao.databindlibrary.databinding.AarDatabindBinding;\n\n\n\npublic class DataBingAarActivity extends Activity {\n    /**\n     * Called when the activity is first created.\n     */\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n\n        super.onCreate(savedInstanceState);\n\n        setContentView(R.layout.aar_databind);\n\n        TextView textView = (TextView) findViewById(R.id.library_aar);\n\n        AarDatabindBinding binding = DataBindingUtil.setContentView(this, R.layout.aar_databind);\n        final User user = new User(\"Test\", \"User\");\n        binding.setUser(user);\n\n        EditText editText = (EditText) findViewById(R.id.inputText_library_aar);\n        editText.addTextChangedListener(new TextWatcher() {\n            @Override\n            public void beforeTextChanged(CharSequence s, int start, int count, int after) {\n\n            }\n\n            @Override\n            public void onTextChanged(CharSequence s, int start, int before, int count) {\n                System.out.println(s);\n                user.setFirstName(s.toString());\n            }\n\n            @Override\n            public void afterTextChanged(Editable s) {\n\n            }\n        });\n\n\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindinglibrary/src/main/java/com/taobao/databinding/library/User.java",
    "content": "package com.taobao.databinding.library;\n\nimport android.databinding.BaseObservable;\nimport android.databinding.Bindable;\n\nimport com.taobao.databindlibrary.BR;\n\n/**\n * Created by wuzhong on 2016/10/19.\n */\n\npublic class User extends BaseObservable {\n\n    String firstName;\n    String lastName;\n\n    public User(String firstName, String lastName) {\n        this.firstName = firstName;\n        this.lastName = lastName;\n    }\n\n    @Bindable\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n        this.notifyPropertyChanged(BR.firstName);\n    }\n\n    @Bindable\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/databindinglibrary/src/main/res/layout/aar_databind.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <data>\n        <variable name=\"user\" type=\"com.taobao.databinding.library.User\"/>\n    </data>\n    <LinearLayout\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <EditText\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:id=\"@+id/inputText_library_aar\" />\n\n\n        <TextView android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"@{user.firstName}\"/>\n        <TextView android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"@{user.lastName}\"/>\n\n\n        <TextView\n            android:layout_width=\"fill_parent\"\n            android:layout_height=\"fill_parent\"\n            android:id=\"@+id/library_aar\"\n            android:text=\"abcd\"\n            />\n\n    </LinearLayout>\n</layout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'com.taobao.atlas'\n\natlas {\n    bundleConfig {\n        awbBundle true\n    }\n    buildTypes {\n        debug {\n            baseApFile project.rootProject.file('app/build/outputs/apk/app-debug.ap')\n        }\n    }\n}\ngroup = 'com.atlas.demo'\nversion = '1.0.2'\n\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion '26.0.2'\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n\n//    dataBinding {\n//        enabled = true\n//    }\n}\n\n\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    providedCompile project(':middlewarelibrary')\n\n    providedCompile project(':publicbundle')\n\n    providedCompile 'com.android.support:support-v4:25.3.0'\n    providedCompile 'com.android.support:appcompat-v7:25.1.0'\n\n//    providedCompile 'com.taobao.android:atlas_core:5.0.8.1-rc1@aar'\n    providedCompile 'com.android.support.constraint:constraint-layout:1.0.2'\n\n    compile project(':atlas_core')\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.taobao.firstbundle\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:supportsRtl=\"true\">\n        <activity\n            android:name=\".FirstBundleActivity\"\n            android:theme=\"@style/AppTheme.NoActionBar\" />\n\n        <activity\n            android:name=\".UseremoteActivity\"\n            android:theme=\"@style/AppTheme.NoActionBar\" />\n\n        <service\n            android:name=\".FirstBundleService\"\n            android:enabled=\"true\"\n            android:exported=\"true\" />\n\n    </application>\n\n</manifest>"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/java/com/taobao/firstbundle/FirstBundleActivity.java",
    "content": "package com.taobao.firstbundle;\n\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\nimport android.util.Log;\n\nimport com.taobao.firstbundle.fragment.BlankFragment;\n\npublic class FirstBundleActivity extends AppCompatActivity implements BlankFragment.OnFragmentInteractionListener {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_firstbundle);\n    }\n\n\n    @Override\n    public void onFragmentInteraction(Uri uri) {\n\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/java/com/taobao/firstbundle/FirstBundleService.java",
    "content": "package com.taobao.firstbundle;\n\nimport android.app.Service;\nimport android.content.Intent;\nimport android.os.IBinder;\n\npublic class FirstBundleService extends Service {\n\t\n   public FirstBundleService(){\n}\t\n    @Override\n    public IBinder onBind(Intent intent) {\n        // TODO: Return the communication channel to the service.\n        throw new UnsupportedOperationException(\"Not yet implemented\");\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/java/com/taobao/firstbundle/UseremoteActivity.java",
    "content": "package com.taobao.firstbundle;\n\nimport android.content.Intent;\nimport android.support.v7.app.AppCompatActivity;\nimport android.os.Bundle;\n\npublic class UseremoteActivity extends AppCompatActivity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_useremote);\n\n\n//\n\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/java/com/taobao/firstbundle/fragment/BlankFragment.java",
    "content": "package com.taobao.firstbundle.fragment;\n\nimport android.content.Context;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.support.v4.app.Fragment;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport com.taobao.firstbundle.R;\n\n/**\n * A simple {@link Fragment} subclass.\n * Activities that contain this fragment must implement the\n * {@link BlankFragment.OnFragmentInteractionListener} interface\n * to handle interaction events.\n * Use the {@link BlankFragment#newInstance} factory method to\n * create an instance of this fragment.\n */\npublic class BlankFragment extends Fragment {\n    // TODO: Rename parameter arguments, choose names that match\n    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER\n    private static final String ARG_PARAM1 = \"param1\";\n    private static final String ARG_PARAM2 = \"param2\";\n    private static final String ARG_PARAM211 = \"param2\";\n\n\n    // TODO: Rename and change types of parameters\n    private String mParam1;\n    private String mParam2;\n\n    private OnFragmentInteractionListener mListener;\n\n    public BlankFragment() {\n        // Required empty public constructor\n    }\n\n    /**\n     * Use this factory method to create a new instance of\n     * this fragment using the provided parameters.\n     *\n     * @param param1 Parameter 1.\n     * @param param2 Parameter 2.\n     * @return A new instance of fragment BlankFragment.\n     */\n    // TODO: Rename and change types and number of parameters\n    public static BlankFragment newInstance(String param1, String param2) {\n        BlankFragment fragment = new BlankFragment();\n        Bundle args = new Bundle();\n        args.putString(ARG_PARAM1, param1);\n        args.putString(ARG_PARAM2, param2);\n        fragment.setArguments(args);\n        return fragment;\n    }\n\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        if (getArguments() != null) {\n            mParam1 = getArguments().getString(ARG_PARAM1);\n            mParam2 = getArguments().getString(ARG_PARAM2);\n        }\n    }\n\n    @Override\n    public View onCreateView(LayoutInflater inflater, ViewGroup container,\n                             Bundle savedInstanceState) {\n        // Inflate the layout for this fragment\n        View view =  inflater.inflate(R.layout.fragment_blank, container, false);\n//        view.findViewById(R.id.btn_Test).setOnClickListener(new View.OnClickListener() {\n//            @Override\n//            public void onClick(View view) {\n//                Toast.makeText(getContext(),\"test\",Toast.LENGTH_LONG).show();\n//            }\n//        });\n        return view;\n    }\n\n    // TODO: Rename method, update argument and hook method into UI event\n    public void onButtonPressed(Uri uri) {\n        if (mListener != null) {\n            mListener.onFragmentInteraction(uri);\n        }\n    }\n\n    @Override\n    public void onAttach(Context context) {\n        super.onAttach(context);\n        if (context instanceof OnFragmentInteractionListener) {\n            mListener = (OnFragmentInteractionListener) context;\n        } else {\n//            throw new RuntimeException(context.toString()\n//                    + \" must implement OnFragmentInteractionListener\");\n        }\n    }\n\n    @Override\n    public void onDetach() {\n        super.onDetach();\n        mListener = null;\n    }\n\n    /**\n     * This interface must be implemented by activities that contain this\n     * fragment to allow an interaction in this fragment to be communicated\n     * to the activity and potentially other fragments contained in that\n     * activity.\n     * <p>\n     * See the Android Training lesson <a href=\n     * \"http://developer.android.com/training/basics/fragments/communicating.html\"\n     * >Communicating with Other Fragments</a> for more information.\n     */\n    public interface OnFragmentInteractionListener {\n        // TODO: Update argument type and name\n        void onFragmentInteraction(Uri uri);\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/java/com/taobao/firstbundle/fragment/DummyContent.java",
    "content": "package com.taobao.firstbundle.fragment;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Helper class for providing sample content for user interfaces created by\n * Android template wizards.\n * <p>\n * TODO: Replace all uses of this class before publishing your app.\n */\npublic class DummyContent {\n\n    /**\n     * An array of sample (dummy) items.\n     */\n    public static final List<DummyItem> ITEMS = new ArrayList<DummyItem>();\n\n    /**\n     * A map of sample (dummy) items, by ID.\n     */\n    public static final Map<String, DummyItem> ITEM_MAP = new HashMap<String, DummyItem>();\n\n    private static final int COUNT = 25;\n\n    static {\n        // Add some sample items.\n        for (int i = 1; i <= COUNT; i++) {\n            addItem(createDummyItem(i));\n        }\n    }\n\n    private static void addItem(DummyItem item) {\n        ITEMS.add(item);\n        ITEM_MAP.put(item.id, item);\n    }\n\n    private static DummyItem createDummyItem(int position) {\n        return new DummyItem(String.valueOf(position), \"Item \" + position, makeDetails(position));\n    }\n\n    private static String makeDetails(int position) {\n        StringBuilder builder = new StringBuilder();\n        builder.append(\"Details about Item: \").append(position);\n        for (int i = 0; i < position; i++) {\n            builder.append(\"\\nMore details information here.\");\n        }\n        return builder.toString();\n    }\n\n    /**\n     * A dummy item representing a piece of content.\n     */\n    public static class DummyItem {\n        public final String id;\n        public final String content;\n        public final String details;\n\n        public DummyItem(String id, String content, String details) {\n            this.id = id;\n            this.content = content;\n            this.details = details;\n        }\n\n        @Override\n        public String toString() {\n            return content;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/java/com/taobao/firstbundle/fragment/ItemFragment.java",
    "content": "package com.taobao.firstbundle.fragment;\n\nimport android.content.Context;\nimport android.os.Bundle;\nimport android.support.v4.app.Fragment;\nimport android.support.v7.widget.GridLayoutManager;\nimport android.support.v7.widget.LinearLayoutManager;\nimport android.support.v7.widget.RecyclerView;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport com.taobao.firstbundle.R;\n\n/**\n * A fragment representing a list of Items.\n * <p/>\n * Activities containing this fragment MUST implement the {@link OnListFragmentInteractionListener}\n * interface.\n */\npublic class ItemFragment extends Fragment {\n\n    // TODO: Customize parameter argument names\n    private static final String ARG_COLUMN_COUNT = \"column-count\";\n    // TODO: Customize parameters\n    private int mColumnCount = 1;\n    private OnListFragmentInteractionListener mListener;\n\n    /**\n     * Mandatory empty constructor for the fragment manager to instantiate the\n     * fragment (e.g. upon screen orientation changes).\n     */\n    public ItemFragment() {\n    }\n\n    // TODO: Customize parameter initialization\n    @SuppressWarnings(\"unused\")\n    public static ItemFragment newInstance(int columnCount) {\n        ItemFragment fragment = new ItemFragment();\n        Bundle args = new Bundle();\n        args.putInt(ARG_COLUMN_COUNT, columnCount);\n        fragment.setArguments(args);\n        return fragment;\n    }\n\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n\n        if (getArguments() != null) {\n            mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);\n        }\n    }\n\n    @Override\n    public View onCreateView(LayoutInflater inflater, ViewGroup container,\n                             Bundle savedInstanceState) {\n        View view = inflater.inflate(R.layout.fragment_item_list, container, false);\n        // Set the adapter\n        if (view instanceof RecyclerView) {\n            Context context = view.getContext();\n            RecyclerView recyclerView = (RecyclerView) view;\n            if (mColumnCount <= 1) {\n                recyclerView.setLayoutManager(new LinearLayoutManager(context));\n            } else {\n                recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));\n            }\n            recyclerView.setAdapter(new MyItemRecyclerViewAdapter(DummyContent.ITEMS, mListener));\n        }\n        return view;\n    }\n\n\n    @Override\n    public void onAttach(Context context) {\n        super.onAttach(context);\n        if (context instanceof OnListFragmentInteractionListener) {\n            mListener = (OnListFragmentInteractionListener) context;\n        } else {\n            throw new RuntimeException(context.toString()\n                    + \" must implement OnListFragmentInteractionListener\");\n        }\n    }\n\n    @Override\n    public void onDetach() {\n        super.onDetach();\n        mListener = null;\n    }\n\n    /**\n     * This interface must be implemented by activities that contain this\n     * fragment to allow an interaction in this fragment to be communicated\n     * to the activity and potentially other fragments contained in that\n     * activity.\n     * <p/>\n     * See the Android Training lesson <a href=\n     * \"http://developer.android.com/training/basics/fragments/communicating.html\"\n     * >Communicating with Other Fragments</a> for more information.\n     */\n    public interface OnListFragmentInteractionListener {\n        // TODO: Update argument type and name\n        void onListFragmentInteraction(DummyContent.DummyItem item);\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/java/com/taobao/firstbundle/fragment/MyItemRecyclerViewAdapter.java",
    "content": "package com.taobao.firstbundle.fragment;\n\nimport android.support.v7.widget.RecyclerView;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.TextView;\nimport com.taobao.firstbundle.R;\n\nimport java.util.List;\n\npublic class MyItemRecyclerViewAdapter extends RecyclerView.Adapter<MyItemRecyclerViewAdapter.ViewHolder> {\n\n    private final List<DummyContent.DummyItem> mValues;\n    private final ItemFragment.OnListFragmentInteractionListener mListener;\n\n    public MyItemRecyclerViewAdapter(List<DummyContent.DummyItem> items, ItemFragment.OnListFragmentInteractionListener listener) {\n        mValues = items;\n        mListener = listener;\n    }\n\n    @Override\n    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {\n        View view = LayoutInflater.from(parent.getContext())\n                .inflate(R.layout.fragment_item, parent, false);\n        return new ViewHolder(view);\n    }\n\n    @Override\n    public void onBindViewHolder(final ViewHolder holder, int position) {\n        holder.mItem = mValues.get(position);\n        holder.mIdView.setText(mValues.get(position).id);\n        holder.mContentView.setText(mValues.get(position).content);\n\n        holder.mView.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                if (null != mListener) {\n                    // Notify the active callbacks interface (the activity, if the\n                    // fragment is attached to one) that an item has been selected.\n                    mListener.onListFragmentInteraction(holder.mItem);\n                }\n            }\n        });\n    }\n\n    @Override\n    public int getItemCount() {\n        return mValues.size();\n    }\n\n    public class ViewHolder extends RecyclerView.ViewHolder {\n        public final View mView;\n        public final TextView mIdView;\n        public final TextView mContentView;\n        public DummyContent.DummyItem mItem;\n\n        public ViewHolder(View view) {\n            super(view);\n            mView = view;\n            mIdView = (TextView) view.findViewById(R.id.id);\n            mContentView = (TextView) view.findViewById(R.id.content);\n        }\n\n        @Override\n        public String toString() {\n            return super.toString() + \" '\" + mContentView.getText() + \"'\";\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/res/layout/activity_firstbundle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.taobao.firstbundle.FirstBundleActivity\">\n\n    <fragment\n        android:id=\"@+id/fragment_hello\"\n        android:name=\"com.taobao.firstbundle.fragment.BlankFragment\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\" />\n\n</FrameLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/res/layout/activity_useremote.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.taobao.firstbundle.UseremoteActivity\">\n\n<LinearLayout\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"horizontal\"\n    >\n\n    <Button\n        android:id=\"@+id/btn_view\"\n        android:layout_weight=\"1\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"use RemoteView\"\n        android:textSize=\"14dp\"\n        tools:layout_editor_absoluteY=\"6dp\"\n        tools:layout_editor_absoluteX=\"16dp\" />\n\n    <Button\n        android:id=\"@+id/btn_frag\"\n        android:layout_width=\"0dp\"\n        android:layout_weight=\"1\"\n        android:textSize=\"14dp\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"use RemoteFragment\"\n        tools:layout_editor_absoluteY=\"6dp\"\n        app:layout_constraintLeft_toRightOf=\"@+id/button3\"\n        android:layout_marginLeft=\"8dp\" />\n\n    <Button\n        android:id=\"@+id/btn_tran\"\n        android:layout_width=\"0dp\"\n        android:layout_weight=\"1\"\n        android:textSize=\"14dp\"\n\n        android:layout_height=\"wrap_content\"\n        android:text=\"use RemoteTransaction\"\n        tools:layout_editor_absoluteY=\"6dp\"\n        app:layout_constraintLeft_toRightOf=\"@+id/button4\"\n        android:layout_marginLeft=\"8dp\" />\n\n</LinearLayout>\n\n\n    <FrameLayout\n        android:id=\"@+id/fl_content\"\n        android:layout_width=\"200dp\"\n        android:layout_height=\"200dp\"\n        android:layout_gravity=\"left\"\n        android:layout_marginTop=\"100dp\"></FrameLayout>\n\n    <FrameLayout\n        android:id=\"@+id/fl_content2\"\n        android:layout_width=\"200dp\"\n        android:layout_height=\"200dp\"\n        android:layout_gravity=\"right\"\n\n        android:layout_marginTop=\"100dp\"></FrameLayout>\n</FrameLayout>"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/res/layout/activity_web_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <WebView\n        android:id=\"@+id/webView1\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"fill_parent\" />\n\n</FrameLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/res/layout/fragment_blank.xml",
    "content": "<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.taobao.firstbundle.fragment.BlankFragment\">\n\n    <!-- TODO: Update blank fragment layout -->\n    <TextView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:text=\"@string/hello_blank_fragment\" />\n\n    <!--<Button-->\n        <!--android:id=\"@+id/btn_Test\"-->\n        <!--android:text=\"buttontest\"-->\n        <!--android:layout_width=\"wrap_content\"-->\n        <!--android:layout_height=\"wrap_content\">-->\n        <!--</Button>-->\n\n</FrameLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/res/layout/fragment_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"horizontal\">\n\n    <TextView\n        android:id=\"@+id/id\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"@dimen/text_margin\"\n        android:textAppearance=\"?attr/textAppearanceListItem\" />\n\n    <TextView\n        android:id=\"@+id/content\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"@dimen/text_margin\"\n        android:textAppearance=\"?attr/textAppearanceListItem\" />\n</LinearLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/res/layout/fragment_item_list.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.v7.widget.RecyclerView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/list\"\n    android:name=\"com.taobao.demo.ItemFragment\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:layout_marginLeft=\"16dp\"\n    android:layout_marginRight=\"16dp\"\n    app:layoutManager=\"LinearLayoutManager\"\n    tools:context=\"com.taobao.firstbundle.fragment.ItemFragment\"\n    tools:listitem=\"@layout/fragment_item\" />\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/firstbundle/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">FirstBundle</string>\n\n    <!-- TODO: Remove or change this placeholder text -->\n    <string name=\"hello_blank_fragment\">this is bbbbb fragment of firstBundle</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Thu Mar 16 12:49:23 CST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.1-all.zip\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/gradle.properties",
    "content": "## Project-wide Gradle settings.\n#\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n#\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\n# Default value: -Xmx1024m -XX:MaxPermSize=256m\n# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\n#\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n#Sun Mar 26 09:43:28 CST 2017\n#systemProp.http.proxyHost=127.0.0.1\n#org.gradle.jvmargs=-Xmx1536m\n#systemProp.http.proxyPort=1080\norg.gradle.parallel=true\norg.gradle.daemon=true\nandroid.keepTimestampsInApk=true\nandroid.enableAapt2=false\nandroid.injected.testOnly=false\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windowz variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\ngoto execute\r\n\r\n:4NT_args\r\n@rem Get arguments from the 4NT Shell from JP Software\r\nset CMD_LINE_ARGS=%$\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\ngroup = 'com.atlas.demo'\nversion = '1.0.0'\n\nandroid {\n  compileSdkVersion 25\n  buildToolsVersion \"26.0.2\"\n  resourcePrefix 'lottie_'\n\n  defaultConfig {\n    minSdkVersion 14\n    targetSdkVersion 25\n\n  }\n  lintOptions {\n    abortOnError true\n  }\n  compileOptions {\n    sourceCompatibility JavaVersion.VERSION_1_7\n    targetCompatibility JavaVersion.VERSION_1_7\n  }\n}\n\ndependencies {\n  compile 'com.android.support:appcompat-v7:25.2.0'\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/gradle.properties",
    "content": "POM_NAME=Lottie\nPOM_ARTIFACT_ID=lottie\nPOM_PACKAGING=aar\nGROUP=com.airbnb.android"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/AndroidManifest.xml",
    "content": "<manifest package=\"com.airbnb.lottie\" >\n\n    <application />\n\n</manifest>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/AnimatableColorValue.java",
    "content": "package com.airbnb.lottie;\n\nimport org.json.JSONObject;\n\nimport java.util.List;\n\nclass AnimatableColorValue extends BaseAnimatableValue<Integer, Integer> {\n  private AnimatableColorValue(List<Keyframe<Integer>> keyframes, Integer initialValue) {\n    super(keyframes, initialValue);\n  }\n\n  @Override public KeyframeAnimation<Integer> createAnimation() {\n    if (!hasAnimation()) {\n      return new StaticKeyframeAnimation<>(initialValue);\n    }\n    return new ColorKeyframeAnimation(keyframes);\n  }\n\n  @Override public String toString() {\n    return \"AnimatableColorValue{\" + \"initialValue=\" + initialValue + '}';\n  }\n\n  static final class Factory {\n    private Factory() {\n    }\n\n    static AnimatableColorValue newInstance(JSONObject json, LottieComposition composition) {\n      AnimatableValueParser.Result<Integer> result = AnimatableValueParser\n          .newInstance(json, 1f, composition, ColorFactory.INSTANCE)\n          .parseJson();\n      return new AnimatableColorValue(result.keyframes, result.initialValue);\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/AnimatableFloatValue.java",
    "content": "package com.airbnb.lottie;\n\nimport org.json.JSONObject;\n\nimport java.util.List;\n\nclass AnimatableFloatValue extends BaseAnimatableValue<Float, Float> {\n  private AnimatableFloatValue() {\n    super(0f);\n  }\n\n  private AnimatableFloatValue(List<Keyframe<Float>> keyframes, Float initialValue) {\n    super(keyframes, initialValue);\n  }\n\n  @Override public KeyframeAnimation<Float> createAnimation() {\n    if (!hasAnimation()) {\n      return new StaticKeyframeAnimation<>(initialValue);\n    }\n\n    return new FloatKeyframeAnimation(keyframes);\n  }\n\n  public Float getInitialValue() {\n    return initialValue;\n  }\n\n  private static class ValueFactory implements AnimatableValue.Factory<Float> {\n    static final ValueFactory INSTANCE = new ValueFactory();\n\n    private ValueFactory() {\n    }\n\n    @Override public Float valueFromObject(Object object, float scale) {\n      return JsonUtils.valueFromObject(object) * scale;\n    }\n  }\n\n  static final class Factory {\n    private Factory() {\n    }\n\n    static AnimatableFloatValue newInstance() {\n      return new AnimatableFloatValue();\n    }\n\n    static AnimatableFloatValue newInstance(JSONObject json, LottieComposition composition) {\n      return newInstance(json, composition, true);\n    }\n\n    static AnimatableFloatValue newInstance(JSONObject json, LottieComposition composition,\n        boolean isDp) {\n      float scale = isDp ? composition.getDpScale() : 1f;\n      AnimatableValueParser.Result<Float> result = AnimatableValueParser\n          .newInstance(json, scale, composition, ValueFactory.INSTANCE)\n          .parseJson();\n      return new AnimatableFloatValue(result.keyframes, result.initialValue);\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/AnimatableIntegerValue.java",
    "content": "package com.airbnb.lottie;\n\nimport org.json.JSONObject;\n\nimport java.util.List;\n\nclass AnimatableIntegerValue extends BaseAnimatableValue<Integer, Integer> {\n  private AnimatableIntegerValue() {\n    super(100);\n  }\n\n  AnimatableIntegerValue(List<Keyframe<Integer>> keyframes, Integer initialValue) {\n    super(keyframes, initialValue);\n  }\n\n  @Override public KeyframeAnimation<Integer> createAnimation() {\n    if (!hasAnimation()) {\n      return new StaticKeyframeAnimation<>(initialValue);\n    }\n\n    return new IntegerKeyframeAnimation(keyframes);\n  }\n\n  public Integer getInitialValue() {\n    return initialValue;\n  }\n\n  static final class Factory {\n    private Factory() {\n    }\n\n    static AnimatableIntegerValue newInstance() {\n      return new AnimatableIntegerValue();\n    }\n\n    static AnimatableIntegerValue newInstance(\n        JSONObject json, LottieComposition composition) {\n      AnimatableValueParser.Result<Integer> result = AnimatableValueParser\n          .newInstance(json, 1, composition, ValueFactory.INSTANCE)\n          .parseJson();\n      Integer initialValue = result.initialValue;\n      return new AnimatableIntegerValue(result.keyframes, initialValue);\n    }\n  }\n\n  private static class ValueFactory implements AnimatableValue.Factory<Integer> {\n    private static final ValueFactory INSTANCE = new ValueFactory();\n\n    private ValueFactory() {\n    }\n\n    @Override public Integer valueFromObject(Object object, float scale) {\n      return Math.round(JsonUtils.valueFromObject(object) * scale);\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/AnimatablePathValue.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.PointF;\n\nimport org.json.JSONArray;\nimport org.json.JSONObject;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nclass AnimatablePathValue implements AnimatableValue<PointF> {\n  static AnimatableValue<PointF> createAnimatablePathOrSplitDimensionPath(\n      JSONObject json, LottieComposition composition) {\n    if (json.has(\"k\")) {\n      return new AnimatablePathValue(json.opt(\"k\"), composition);\n    } else {\n      return new AnimatableSplitDimensionPathValue(\n          AnimatableFloatValue.Factory.newInstance(json.optJSONObject(\"x\"), composition),\n          AnimatableFloatValue.Factory.newInstance(json.optJSONObject(\"y\"), composition));\n    }\n  }\n\n  private final List<PathKeyframe> keyframes = new ArrayList<>();\n  private PointF initialPoint;\n\n  /**\n   * Create a default static animatable path.\n   */\n  AnimatablePathValue() {\n    this.initialPoint = new PointF(0, 0);\n  }\n\n  AnimatablePathValue(Object json, LottieComposition composition) {\n    if (hasKeyframes(json)) {\n      JSONArray jsonArray = (JSONArray) json;\n      int length = jsonArray.length();\n      for (int i = 0; i < length; i++) {\n        JSONObject jsonKeyframe = jsonArray.optJSONObject(i);\n        PathKeyframe keyframe = PathKeyframe.Factory.newInstance(jsonKeyframe, composition,\n            ValueFactory.INSTANCE);\n        keyframes.add(keyframe);\n      }\n      Keyframe.setEndFrames(keyframes);\n    } else {\n      initialPoint = JsonUtils.pointFromJsonArray((JSONArray) json, composition.getDpScale());\n    }\n  }\n\n  private boolean hasKeyframes(Object json) {\n    if (!(json instanceof JSONArray)) {\n      return false;\n    }\n\n    Object firstObject = ((JSONArray) json).opt(0);\n    return firstObject instanceof JSONObject && ((JSONObject) firstObject).has(\"t\");\n  }\n\n  @Override\n  public BaseKeyframeAnimation<?, PointF> createAnimation() {\n    if (!hasAnimation()) {\n      return new StaticKeyframeAnimation<>(initialPoint);\n    }\n\n    return new PathKeyframeAnimation(keyframes);\n  }\n\n  @Override\n  public boolean hasAnimation() {\n    return !keyframes.isEmpty();\n  }\n\n  @Override\n  public String toString() {\n    return \"initialPoint=\" + initialPoint;\n  }\n\n  private static class ValueFactory implements AnimatableValue.Factory<PointF> {\n    private static final Factory<PointF> INSTANCE = new ValueFactory();\n\n    private ValueFactory() {\n    }\n\n    @Override public PointF valueFromObject(Object object, float scale) {\n      return JsonUtils.pointFromJsonArray((JSONArray) object, scale);\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/AnimatablePointValue.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.PointF;\n\nimport org.json.JSONObject;\n\nimport java.util.List;\n\nclass AnimatablePointValue extends BaseAnimatableValue<PointF, PointF> {\n  private AnimatablePointValue(List<Keyframe<PointF>> keyframes, PointF initialValue) {\n    super(keyframes, initialValue);\n  }\n\n  @Override public KeyframeAnimation<PointF> createAnimation() {\n    if (!hasAnimation()) {\n      return new StaticKeyframeAnimation<>(initialValue);\n    } else {\n      return new PointKeyframeAnimation(keyframes);\n    }\n  }\n\n  static final class Factory {\n    private Factory() {\n    }\n\n    static AnimatablePointValue newInstance(JSONObject json, LottieComposition composition) {\n      AnimatableValueParser.Result<PointF> result = AnimatableValueParser\n          .newInstance(json, composition.getDpScale(), composition, PointFFactory.INSTANCE)\n          .parseJson();\n      return new AnimatablePointValue(result.keyframes, result.initialValue);\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/AnimatableScaleValue.java",
    "content": "package com.airbnb.lottie;\n\nimport org.json.JSONObject;\n\nimport java.util.List;\n\nclass AnimatableScaleValue extends BaseAnimatableValue<ScaleXY, ScaleXY> {\n  private AnimatableScaleValue() {\n    super(new ScaleXY());\n  }\n\n  AnimatableScaleValue(List<Keyframe<ScaleXY>> keyframes, ScaleXY initialValue) {\n    super(keyframes, initialValue);\n  }\n\n  @Override public KeyframeAnimation<ScaleXY> createAnimation() {\n    if (!hasAnimation()) {\n      return new StaticKeyframeAnimation<>(initialValue);\n    } else {\n      return new ScaleKeyframeAnimation(keyframes);\n    }\n  }\n\n  static final class Factory {\n    private Factory() {\n    }\n\n    static AnimatableScaleValue newInstance(JSONObject json, LottieComposition\n        composition) {\n      AnimatableValueParser.Result<ScaleXY> result = AnimatableValueParser\n          .newInstance(json, 1, composition, ScaleXY.Factory.INSTANCE)\n          .parseJson();\n      return new AnimatableScaleValue(result.keyframes, result.initialValue);\n    }\n\n    static AnimatableScaleValue newInstance() {\n      return new AnimatableScaleValue();\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/AnimatableShapeValue.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Path;\n\nimport org.json.JSONObject;\n\nimport java.util.List;\n\nclass AnimatableShapeValue extends BaseAnimatableValue<ShapeData, Path> {\n  private final Path convertTypePath = new Path();\n\n  private AnimatableShapeValue(List<Keyframe<ShapeData>> keyframes, ShapeData initialValue) {\n    super(keyframes, initialValue);\n  }\n\n  @Override public BaseKeyframeAnimation<?, Path> createAnimation() {\n    if (!hasAnimation()) {\n      return new StaticKeyframeAnimation<>(convertType(initialValue));\n    } else {\n      return new ShapeKeyframeAnimation(keyframes);\n    }\n  }\n\n  @Override Path convertType(ShapeData shapeData) {\n    convertTypePath.reset();\n    MiscUtils.getPathFromData(shapeData, convertTypePath);\n    return convertTypePath;\n  }\n\n  static final class Factory {\n    private Factory() {\n    }\n\n    static AnimatableShapeValue newInstance(JSONObject json, LottieComposition composition) {\n      AnimatableValueParser.Result<ShapeData> result = AnimatableValueParser\n          .newInstance(json, composition.getDpScale(), composition, ShapeData.Factory.INSTANCE)\n          .parseJson();\n      return new AnimatableShapeValue(result.keyframes, result.initialValue);\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/AnimatableSplitDimensionPathValue.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.PointF;\n\nclass AnimatableSplitDimensionPathValue implements AnimatableValue<PointF> {\n  private final AnimatableFloatValue animatableXDimension;\n  private final AnimatableFloatValue animatableYDimension;\n\n  AnimatableSplitDimensionPathValue(\n      AnimatableFloatValue animatableXDimension,\n      AnimatableFloatValue animatableYDimension) {\n    this.animatableXDimension = animatableXDimension;\n    this.animatableYDimension = animatableYDimension;\n  }\n\n  @Override public KeyframeAnimation<PointF> createAnimation() {\n    return new SplitDimensionPathKeyframeAnimation(\n        animatableXDimension.createAnimation(), animatableYDimension.createAnimation());\n  }\n\n  @Override public boolean hasAnimation() {\n    return animatableXDimension.hasAnimation() || animatableYDimension.hasAnimation();\n  }\n\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/AnimatableTransform.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.PointF;\n\nimport org.json.JSONObject;\n\nimport java.util.Collections;\n\nclass AnimatableTransform implements ModifierContent {\n  private final AnimatablePathValue anchorPoint;\n  private final AnimatableValue<PointF> position;\n  private final AnimatableScaleValue scale;\n  private final AnimatableFloatValue rotation;\n  private final AnimatableIntegerValue opacity;\n\n  private AnimatableTransform(AnimatablePathValue anchorPoint, AnimatableValue<PointF> position,\n      AnimatableScaleValue scale, AnimatableFloatValue rotation, AnimatableIntegerValue opacity) {\n    this.anchorPoint = anchorPoint;\n    this.position = position;\n    this.scale = scale;\n    this.rotation = rotation;\n    this.opacity = opacity;\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    static AnimatableTransform newInstance() {\n      AnimatablePathValue anchorPoint = new AnimatablePathValue();\n      AnimatableValue<PointF> position = new AnimatablePathValue();\n      AnimatableScaleValue scale = AnimatableScaleValue.Factory.newInstance();\n      AnimatableFloatValue rotation = AnimatableFloatValue.Factory.newInstance();\n      AnimatableIntegerValue opacity = AnimatableIntegerValue.Factory.newInstance();\n      return new AnimatableTransform(anchorPoint, position, scale, rotation, opacity);\n    }\n\n    static AnimatableTransform newInstance(JSONObject json, LottieComposition composition) {\n      AnimatablePathValue anchorPoint = null;\n      AnimatableValue<PointF> position = null;\n      AnimatableScaleValue scale;\n      AnimatableFloatValue rotation = null;\n      AnimatableIntegerValue opacity;\n      JSONObject anchorJson = json.optJSONObject(\"a\");\n      if (anchorJson != null) {\n        anchorPoint = new AnimatablePathValue(anchorJson.opt(\"k\"), composition);\n      } else {\n        throwMissingTransform(\"anchor\");\n      }\n\n      JSONObject positionJson = json.optJSONObject(\"p\");\n      if (positionJson != null) {\n        position =\n            AnimatablePathValue.createAnimatablePathOrSplitDimensionPath(positionJson, composition);\n      } else {\n        throwMissingTransform(\"position\");\n      }\n\n      JSONObject scaleJson = json.optJSONObject(\"s\");\n      if (scaleJson != null) {\n        scale = AnimatableScaleValue.Factory.newInstance(scaleJson, composition);\n      } else {\n        // Somehow some community animations don't have scale in the transform.\n        scale = new AnimatableScaleValue(Collections.<Keyframe<ScaleXY>>emptyList(), new ScaleXY());\n      }\n\n      JSONObject rotationJson = json.optJSONObject(\"r\");\n      if (rotationJson == null) {\n        rotationJson = json.optJSONObject(\"rz\");\n      }\n      if (rotationJson != null) {\n        rotation = AnimatableFloatValue.Factory.newInstance(rotationJson, composition, false);\n      } else {\n        throwMissingTransform(\"rotation\");\n      }\n\n      JSONObject opacityJson = json.optJSONObject(\"o\");\n      if (opacityJson != null) {\n        opacity = AnimatableIntegerValue.Factory.newInstance(opacityJson, composition);\n      } else {\n        // Somehow some community animations don't have opacity in the transform.\n        opacity = new AnimatableIntegerValue(Collections.<Keyframe<Integer>>emptyList(), 100);\n      }\n      return new AnimatableTransform(anchorPoint, position, scale, rotation, opacity);\n    }\n\n    private static void throwMissingTransform(String missingProperty) {\n      throw new IllegalArgumentException(\"Missing transform for \" + missingProperty);\n    }\n  }\n\n  AnimatablePathValue getAnchorPoint() {\n    return anchorPoint;\n  }\n\n  AnimatableValue<PointF> getPosition() {\n    return position;\n  }\n\n  AnimatableScaleValue getScale() {\n    return scale;\n  }\n\n  AnimatableFloatValue getRotation() {\n    return rotation;\n  }\n\n  AnimatableIntegerValue getOpacity() {\n    return opacity;\n  }\n\n  public TransformKeyframeAnimation createAnimation() {\n    return new TransformKeyframeAnimation(this);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/AnimatableValue.java",
    "content": "package com.airbnb.lottie;\n\ninterface AnimatableValue<O> {\n  BaseKeyframeAnimation<?, O> createAnimation();\n  boolean hasAnimation();\n\n  interface Factory<V> {\n    V valueFromObject(Object object, float scale);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/AnimatableValueParser.java",
    "content": "package com.airbnb.lottie;\n\nimport android.support.annotation.Nullable;\n\nimport org.json.JSONArray;\nimport org.json.JSONObject;\n\nimport java.util.Collections;\nimport java.util.List;\n\nclass AnimatableValueParser<T> {\n  @Nullable private final JSONObject json;\n  private final float scale;\n  private final LottieComposition composition;\n  private final AnimatableValue.Factory<T> valueFactory;\n\n  private AnimatableValueParser(@Nullable JSONObject json, float scale, LottieComposition\n      composition, AnimatableValue.Factory<T> valueFactory) {\n    this.json = json;\n    this.scale = scale;\n    this.composition = composition;\n    this.valueFactory = valueFactory;\n  }\n\n  static <T> AnimatableValueParser<T> newInstance(@Nullable JSONObject json, float scale,\n      LottieComposition composition, AnimatableValue.Factory<T> valueFactory) {\n    return new AnimatableValueParser<>(json, scale, composition, valueFactory);\n  }\n\n  Result<T> parseJson() {\n    List<Keyframe<T>> keyframes = parseKeyframes();\n    T initialValue = parseInitialValue(keyframes);\n    return new Result<>(keyframes, initialValue);\n  }\n\n  private List<Keyframe<T>> parseKeyframes() {\n    if (json != null) {\n      Object k = json.opt(\"k\");\n      if (hasKeyframes(k)) {\n        return Keyframe.Factory.parseKeyframes((JSONArray) k, composition, scale, valueFactory);\n      } else {\n        return Collections.emptyList();\n      }\n    } else {\n      return Collections.emptyList();\n    }\n  }\n\n  @Nullable private T parseInitialValue(List<Keyframe<T>> keyframes) {\n    if (json != null) {\n      if (!keyframes.isEmpty()) {\n        return keyframes.get(0).startValue;\n      } else {\n        return valueFactory.valueFromObject(json.opt(\"k\"), scale);\n      }\n    } else {\n      return null;\n    }\n  }\n\n  private static boolean hasKeyframes(Object json) {\n    if (!(json instanceof JSONArray)) {\n      return false;\n    } else {\n      Object firstObject = ((JSONArray) json).opt(0);\n      return firstObject instanceof JSONObject && ((JSONObject) firstObject).has(\"t\");\n    }\n  }\n\n  static class Result<T> {\n    final List<Keyframe<T>> keyframes;\n    final @Nullable T initialValue;\n\n    Result(List<Keyframe<T>> keyframes, @Nullable T initialValue) {\n      this.keyframes = keyframes;\n      this.initialValue = initialValue;\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/BaseAnimatableValue.java",
    "content": "package com.airbnb.lottie;\n\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\n\nabstract class BaseAnimatableValue<V, O> implements AnimatableValue<O> {\n  final List<Keyframe<V>> keyframes;\n  final V initialValue;\n\n  /**\n   * Create a default static animatable path.\n   */\n  BaseAnimatableValue(V initialValue) {\n    this(Collections.<Keyframe<V>>emptyList(), initialValue);\n  }\n\n  BaseAnimatableValue(List<Keyframe<V>> keyframes, V initialValue) {\n    this.keyframes = keyframes;\n    this.initialValue = initialValue;\n  }\n\n  /**\n   * Convert the value type of the keyframe to the value type of the animation. Often, these\n   * are the same type.\n   */\n  O convertType(V value) {\n    //noinspection unchecked\n    return (O) value;\n  }\n\n  public boolean hasAnimation() {\n    return !keyframes.isEmpty();\n  }\n\n  public O getInitialValue() {\n    return convertType(initialValue);\n  }\n\n  @Override public String toString() {\n    final StringBuilder sb = new StringBuilder();\n    sb.append(\"parseInitialValue=\").append(initialValue);\n    if (!keyframes.isEmpty()) {\n      sb.append(\", values=\").append(Arrays.toString(keyframes.toArray()));\n    }\n    return sb.toString();\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/BaseKeyframeAnimation.java",
    "content": "package com.airbnb.lottie;\n\nimport android.support.annotation.FloatRange;\nimport android.support.annotation.Nullable;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * @param <K> Keyframe type\n * @param <A> Animation type\n */\nabstract class BaseKeyframeAnimation<K, A> {\n  interface AnimationListener {\n    void onValueChanged();\n  }\n\n  final List<AnimationListener> listeners = new ArrayList<>();\n  private boolean isDiscrete = false;\n\n  private final List<? extends Keyframe<K>> keyframes;\n  private float progress = 0f;\n\n  @Nullable private Keyframe<K> cachedKeyframe;\n\n  BaseKeyframeAnimation(List<? extends Keyframe<K>> keyframes) {\n    this.keyframes = keyframes;\n  }\n\n  void setIsDiscrete() {\n    isDiscrete = true;\n  }\n\n  void addUpdateListener(AnimationListener listener) {\n    listeners.add(listener);\n  }\n\n  void setProgress(@FloatRange(from = 0f, to = 1f) float progress) {\n    if (progress < getStartDelayProgress()) {\n      progress = 0f;\n    } else if (progress > getEndProgress()) {\n      progress = 1f;\n    }\n\n    if (progress == this.progress) {\n      return;\n    }\n    this.progress = progress;\n\n    for (int i = 0; i < listeners.size(); i++) {\n      listeners.get(i).onValueChanged();\n    }\n  }\n\n  private Keyframe<K> getCurrentKeyframe() {\n    if (keyframes.isEmpty()) {\n      throw new IllegalStateException(\"There are no keyframes\");\n    }\n\n    if (cachedKeyframe != null && cachedKeyframe.containsProgress(progress)) {\n      return cachedKeyframe;\n    }\n\n    int i = 0;\n    Keyframe<K> keyframe = keyframes.get(0);\n    if (progress < keyframe.getStartProgress()) {\n      cachedKeyframe = keyframe;\n      return keyframe;\n    }\n\n    while (!keyframe.containsProgress(progress) && i < keyframes.size()) {\n      keyframe = keyframes.get(i);\n      i++;\n    }\n    cachedKeyframe = keyframe;\n    return keyframe;\n  }\n\n  /**\n   * This wil be [0, 1] unless the interpolator has overshoot in which case getValue() should be\n   * able to handle values outside of that range.\n   */\n  private float getCurrentKeyframeProgress() {\n    if (isDiscrete) {\n      return 0f;\n    }\n\n    Keyframe<K> keyframe = getCurrentKeyframe();\n    if (keyframe.isStatic()) {\n      return 0f;\n    }\n    float progressIntoFrame = progress - keyframe.getStartProgress();\n    float keyframeProgress = keyframe.getEndProgress() - keyframe.getStartProgress();\n    //noinspection ConstantConditions\n    return keyframe.interpolator.getInterpolation(progressIntoFrame / keyframeProgress);\n  }\n\n  @FloatRange(from = 0f, to = 1f)\n  private float getStartDelayProgress() {\n    return keyframes.isEmpty() ? 0f : keyframes.get(0).getStartProgress();\n  }\n\n  @FloatRange(from = 0f, to = 1f)\n  private float getEndProgress() {\n    return keyframes.isEmpty() ? 1f : keyframes.get(keyframes.size() - 1).getEndProgress();\n  }\n\n  public A getValue() {\n    return getValue(getCurrentKeyframe(), getCurrentKeyframeProgress());\n  }\n\n  /**\n   * keyframeProgress will be [0, 1] unless the interpolator has overshoot in which case, this\n   * should be able to handle values outside of that range.\n   */\n  abstract A getValue(Keyframe<K> keyframe, float keyframeProgress);\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/BaseLayer.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Canvas;\nimport android.graphics.Matrix;\nimport android.graphics.Paint;\nimport android.graphics.Path;\nimport android.graphics.PorterDuff;\nimport android.graphics.PorterDuffXfermode;\nimport android.graphics.RectF;\nimport android.support.annotation.FloatRange;\nimport android.support.annotation.Nullable;\nimport android.util.Log;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\nabstract class BaseLayer implements DrawingContent, BaseKeyframeAnimation.AnimationListener {\n  private static final int SAVE_FLAGS = Canvas.CLIP_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG |\n      Canvas.MATRIX_SAVE_FLAG;\n\n  static BaseLayer forModel(\n    Layer layerModel, LottieDrawable drawable, LottieComposition composition) {\n    switch (layerModel.getLayerType()) {\n      case Shape:\n        return new ShapeLayer(drawable, layerModel);\n      case PreComp:\n        return new CompositionLayer(drawable, layerModel,\n            composition.getPrecomps(layerModel.getRefId()), composition);\n      case Solid:\n        return new SolidLayer(drawable, layerModel);\n      case Image:\n        return new ImageLayer(drawable, layerModel);\n      case Null:\n        return new NullLayer(drawable, layerModel);\n      case Text:\n      case Unknown:\n      default:\n        // Do nothing\n        Log.w(L.TAG, \"Unknown layer type \" + layerModel.getLayerType());\n        return new NullLayer(drawable, layerModel);\n    }\n  }\n\n  private final Path path = new Path();\n  private final Matrix matrix = new Matrix();\n  private final Paint contentPaint = new Paint(Paint.ANTI_ALIAS_FLAG);\n  private final Paint maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);\n  private final Paint mattePaint = new Paint(Paint.ANTI_ALIAS_FLAG);\n  private final Paint clearPaint = new Paint();\n  private final RectF rect = new RectF();\n  final LottieDrawable lottieDrawable;\n  final Layer layerModel;\n  @Nullable private MaskKeyframeAnimation mask;\n  @Nullable private BaseLayer matteLayer;\n  @Nullable private BaseLayer parentLayer;\n  private List<BaseLayer> parentLayers;\n\n  private final List<BaseKeyframeAnimation<?, ?>> animations = new ArrayList<>();\n  final TransformKeyframeAnimation transform;\n  private boolean visible = true;\n\n  BaseLayer(LottieDrawable lottieDrawable, Layer layerModel) {\n    this.lottieDrawable = lottieDrawable;\n    this.layerModel = layerModel;\n    clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));\n    maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));\n    if (layerModel.getMatteType() == Layer.MatteType.Invert) {\n      mattePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));\n    } else {\n      mattePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));\n    }\n\n    this.transform = layerModel.getTransform().createAnimation();\n    transform.addListener(this);\n    transform.addAnimationsToLayer(this);\n\n    if (layerModel.getMasks() != null && !layerModel.getMasks().isEmpty()) {\n      this.mask = new MaskKeyframeAnimation(layerModel.getMasks());\n      for (BaseKeyframeAnimation<?, Path> animation : mask.getMaskAnimations()) {\n        addAnimation(animation);\n        animation.addUpdateListener(this);\n      }\n    }\n    setupInOutAnimations();\n  }\n\n  @Override public void onValueChanged() {\n    invalidateSelf();\n  }\n\n  Layer getLayerModel() {\n    return layerModel;\n  }\n\n  void setMatteLayer(@Nullable BaseLayer matteLayer) {\n    this.matteLayer = matteLayer;\n  }\n\n  boolean hasMatteOnThisLayer() {\n    return matteLayer != null;\n  }\n\n  void setParentLayer(@Nullable BaseLayer parentLayer) {\n    this.parentLayer = parentLayer;\n  }\n\n  private void setupInOutAnimations() {\n    if (!layerModel.getInOutKeyframes().isEmpty()) {\n      final FloatKeyframeAnimation inOutAnimation =\n          new FloatKeyframeAnimation(layerModel.getInOutKeyframes());\n      inOutAnimation.setIsDiscrete();\n      inOutAnimation.addUpdateListener(new BaseKeyframeAnimation.AnimationListener() {\n        @Override public void onValueChanged() {\n          setVisible(inOutAnimation.getValue() == 1f);\n        }\n      });\n      setVisible(inOutAnimation.getValue() == 1f);\n      addAnimation(inOutAnimation);\n    } else {\n      setVisible(true);\n    }\n  }\n\n  private void invalidateSelf() {\n    lottieDrawable.invalidateSelf();\n  }\n\n  void addAnimation(BaseKeyframeAnimation<?, ?> newAnimation) {\n    if (!(newAnimation instanceof StaticKeyframeAnimation)) {\n      animations.add(newAnimation);\n    }\n  }\n\n  @Override\n  public void draw(Canvas canvas, Matrix parentMatrix, int parentAlpha) {\n    if (!visible) {\n      return;\n    }\n    buildParentLayerListIfNeeded();\n    matrix.reset();\n    matrix.set(parentMatrix);\n    for (int i = parentLayers.size() - 1; i >= 0; i--) {\n      matrix.preConcat(parentLayers.get(i).transform.getMatrix());\n    }\n    matrix.preConcat(transform.getMatrix());\n    int alpha = (int)\n        ((parentAlpha / 255f * (float) transform.getOpacity().getValue() / 100f) * 255);\n    if (!hasMatteOnThisLayer() && !hasMasksOnThisLayer()) {\n      drawLayer(canvas, matrix, alpha);\n      return;\n    }\n\n    // TODO: make sure this is the right clip.\n    rect.set(canvas.getClipBounds());\n    canvas.saveLayer(rect, contentPaint, Canvas.ALL_SAVE_FLAG);\n    // Clear the off screen buffer. This is necessary for some phones.\n    canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), clearPaint);\n    drawLayer(canvas, matrix, alpha);\n\n    if (hasMasksOnThisLayer()) {\n      applyMasks(canvas, matrix);\n    }\n\n    if (hasMatteOnThisLayer()) {\n      canvas.saveLayer(rect, mattePaint, SAVE_FLAGS);\n      canvas.drawRect(rect, clearPaint);\n      //noinspection ConstantConditions\n      matteLayer.draw(canvas, parentMatrix, alpha);\n      canvas.restore();\n    }\n\n    canvas.restore();\n  }\n\n  abstract void drawLayer(Canvas canvas, Matrix parentMatrix, int parentAlpha);\n\n  private void applyMasks(Canvas canvas, Matrix matrix) {\n    canvas.saveLayer(rect, maskPaint, SAVE_FLAGS);\n    canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), clearPaint);\n\n    //noinspection ConstantConditions\n    int size = mask.getMasks().size();\n    for (int i = 0; i < size; i++) {\n      Mask mask = this.mask.getMasks().get(i);\n      BaseKeyframeAnimation<?, Path> maskAnimation = this.mask.getMaskAnimations().get(i);\n      Path maskPath = maskAnimation.getValue();\n      path.set(maskPath);\n      path.transform(matrix);\n\n      switch (mask.getMaskMode()) {\n        case MaskModeSubtract:\n          maskPath.setFillType(Path.FillType.INVERSE_WINDING);\n          break;\n        case MaskModeAdd:\n        default:\n          maskPath.setFillType(Path.FillType.WINDING);\n      }\n      canvas.drawPath(path, contentPaint);\n    }\n    canvas.restore();\n  }\n\n  boolean hasMasksOnThisLayer() {\n    return mask != null && !mask.getMaskAnimations().isEmpty();\n  }\n\n  private void setVisible(boolean visible) {\n    if (visible != this.visible) {\n      this.visible = visible;\n      invalidateSelf();\n    }\n  }\n\n  void setProgress(@FloatRange(from = 0f, to = 1f) float progress) {\n    if (matteLayer != null) {\n      matteLayer.setProgress(progress);\n    }\n    for (int i = 0; i < animations.size(); i++) {\n      animations.get(i).setProgress(progress);\n    }\n  }\n\n  private void buildParentLayerListIfNeeded() {\n    if (parentLayers != null) {\n      return;\n    }\n    if (parentLayer == null) {\n      parentLayers = Collections.emptyList();\n      return;\n    }\n\n    parentLayers = new ArrayList<>();\n    BaseLayer layer = parentLayer;\n    while (layer != null) {\n      parentLayers.add(layer);\n      layer = layer.parentLayer;\n    }\n  }\n\n  @Override public void setContents(List<Content> contentsBefore, List<Content> contentsAfter) {\n    // Do nothing\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/BitmapCanvas.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\n\nclass BitmapCanvas extends Canvas {\n\n  private final Bitmap bitmap;\n\n  BitmapCanvas(Bitmap bitmap) {\n    super(bitmap);\n    this.bitmap = bitmap;\n  }\n\n  Bitmap getBitmap() {\n    return bitmap;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/Cancellable.java",
    "content": "package com.airbnb.lottie;\n\ninterface Cancellable {\n  void cancel();\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/CanvasPool.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Color;\nimport android.support.v4.util.LongSparseArray;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\n\nimport static junit.framework.Assert.assertNotNull;\n\n/**\n * Can be used for debugging. When needed, you can acquire and\n * draw to this bitmap layer when rendering to an offscreen\n * buffer to view the contents.\n */\n@SuppressWarnings(\"unused\") class CanvasPool {\n  private final LongSparseArray<List<Bitmap>> availableBitmaps = new LongSparseArray<>();\n  private final Map<BitmapCanvas, Bitmap> canvasBitmapMap = new HashMap<>();\n  private final Map<Bitmap, BitmapCanvas> bitmapCanvasMap = new HashMap<>();\n\n  BitmapCanvas acquire(int width, int height, Bitmap.Config config) {\n    int key = getKey(width, height, config);\n    List<Bitmap> bitmaps = availableBitmaps.get(key);\n    if (bitmaps == null) {\n      bitmaps = new ArrayList<>();\n      availableBitmaps.put(key, bitmaps);\n    }\n\n    BitmapCanvas canvas;\n    if (bitmaps.isEmpty()) {\n      Bitmap bitmap = Bitmap.createBitmap(width, height, config);\n      canvas = new BitmapCanvas(bitmap);\n      canvasBitmapMap.put(canvas, bitmap);\n      bitmapCanvasMap.put(bitmap, canvas);\n    } else {\n      Bitmap bitmap = bitmaps.remove(0);\n      canvas = bitmapCanvasMap.get(bitmap);\n      assertNotNull(canvas);\n    }\n    canvas.getBitmap().eraseColor(Color.TRANSPARENT);\n    return canvas;\n  }\n\n  void release(BitmapCanvas canvas) {\n    assertNotNull(canvas);\n    Bitmap bitmap = canvasBitmapMap.get(canvas);\n    assertNotNull(bitmap);\n    int key = getKey(bitmap);\n    List<Bitmap> bitmaps = availableBitmaps.get(key);\n    assertNotNull(bitmaps);\n    if (bitmaps.contains(bitmap)) {\n      throw new IllegalStateException(\"Canvas already released.\");\n    }\n    bitmaps.add(bitmap);\n  }\n\n  void recycleBitmaps() {\n    for (int i = 0; i < availableBitmaps.size(); i++) {\n      List<Bitmap> bitmaps = availableBitmaps.valueAt(i);\n      Iterator<Bitmap> it = bitmaps.iterator();\n      while (it.hasNext()) {\n        Bitmap bitmap = it.next();\n        BitmapCanvas canvas = bitmapCanvasMap.get(bitmap);\n        bitmapCanvasMap.remove(bitmap);\n        canvasBitmapMap.remove(canvas);\n        bitmap.recycle();\n        it.remove();\n      }\n    }\n    if (!bitmapCanvasMap.isEmpty()) {\n      throw new IllegalStateException(\"Not all canvases have been released!\");\n    }\n  }\n\n  private int getKey(Bitmap bitmap) {\n    return getKey(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());\n  }\n\n  private int getKey(int width, int height, Bitmap.Config config) {\n    return (width & 0xffff) << 17 | (height & 0xffff) << 1 | (config.ordinal() & 0x1);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/CircleShape.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.PointF;\n\nimport org.json.JSONObject;\n\nclass CircleShape {\n  private final AnimatableValue<PointF> position;\n  private final AnimatablePointValue size;\n\n  private CircleShape(AnimatableValue<PointF> position, AnimatablePointValue size) {\n    this.position = position;\n    this.size = size;\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    static CircleShape newInstance(JSONObject json, LottieComposition composition) {\n      return new CircleShape(\n          AnimatablePathValue\n              .createAnimatablePathOrSplitDimensionPath(json.optJSONObject(\"p\"), composition),\n          AnimatablePointValue.Factory.newInstance(json.optJSONObject(\"s\"), composition));\n    }\n  }\n\n  public AnimatableValue<PointF> getPosition() {\n    return position;\n  }\n\n  public AnimatablePointValue getSize() {\n    return size;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ColorFactory.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Color;\n\nimport org.json.JSONArray;\n\nclass ColorFactory implements AnimatableValue.Factory<Integer> {\n  static final ColorFactory INSTANCE = new ColorFactory();\n\n  @Override public Integer valueFromObject(Object object, float scale) {\n    JSONArray colorArray = (JSONArray) object;\n    if (colorArray.length() == 4) {\n      boolean shouldUse255 = true;\n      for (int i = 0; i < colorArray.length(); i++) {\n        double colorChannel = colorArray.optDouble(i);\n        if (colorChannel > 1f) {\n          shouldUse255 = false;\n        }\n      }\n\n      float multiplier = shouldUse255 ? 255f : 1f;\n      return Color.argb(\n          (int) (colorArray.optDouble(3) * multiplier),\n          (int) (colorArray.optDouble(0) * multiplier),\n          (int) (colorArray.optDouble(1) * multiplier),\n          (int) (colorArray.optDouble(2) * multiplier));\n    }\n    return Color.BLACK;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ColorKeyframeAnimation.java",
    "content": "package com.airbnb.lottie;\n\nimport java.util.List;\n\nclass ColorKeyframeAnimation extends KeyframeAnimation<Integer> {\n\n  ColorKeyframeAnimation(List<Keyframe<Integer>> keyframes) {\n    super(keyframes);\n  }\n\n  @Override public Integer getValue(Keyframe<Integer> keyframe, float keyframeProgress) {\n    if (keyframe.startValue == null || keyframe.endValue == null) {\n      throw new IllegalStateException(\"Missing values for keyframe.\");\n    }\n    int startColor = keyframe.startValue;\n    int endColor = keyframe.endValue;\n\n    return GammaEvaluator.evaluate(keyframeProgress, startColor, endColor);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/CompositionLayer.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Canvas;\nimport android.graphics.Matrix;\nimport android.support.annotation.FloatRange;\nimport android.support.v4.util.LongSparseArray;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nclass CompositionLayer extends BaseLayer {\n  private final List<BaseLayer> layers = new ArrayList<>();\n\n  CompositionLayer(LottieDrawable lottieDrawable, Layer layerModel, List<Layer> layerModels,\n      LottieComposition composition) {\n    super(lottieDrawable, layerModel);\n\n    LongSparseArray<BaseLayer> layerMap =\n        new LongSparseArray<>(composition.getLayers().size());\n\n    BaseLayer mattedLayer = null;\n    for (int i = layerModels.size() - 1; i >= 0; i--) {\n      Layer lm = layerModels.get(i);\n      BaseLayer layer = BaseLayer.forModel(lm, lottieDrawable, composition);\n      layerMap.put(layer.getLayerModel().getId(), layer);\n      if (mattedLayer != null) {\n        mattedLayer.setMatteLayer(layer);\n        mattedLayer = null;\n      } else {\n        layers.add(0, layer);\n        switch (lm.getMatteType()) {\n          case Add:\n          case Invert:\n            mattedLayer = layer;\n            break;\n        }\n      }\n    }\n\n    for (int i = 0; i < layerMap.size(); i++) {\n      long key = layerMap.keyAt(i);\n      BaseLayer layerView = layerMap.get(key);\n      BaseLayer parentLayer = layerMap.get(layerView.getLayerModel().getParentId());\n      if (parentLayer != null) {\n        layerView.setParentLayer(parentLayer);\n      }\n    }\n  }\n\n  @Override void drawLayer(Canvas canvas, Matrix parentMatrix, int parentAlpha) {\n    for (int i = layers.size() - 1; i >= 0 ; i--) {\n      layers.get(i).draw(canvas, parentMatrix, parentAlpha);\n    }\n  }\n\n  @Override public void setProgress(@FloatRange(from = 0f, to = 1f) float progress) {\n    super.setProgress(progress);\n    progress -= layerModel.getStartProgress();\n    for (int i = layers.size() - 1; i >= 0; i--) {\n      layers.get(i).setProgress(progress);\n    }\n  }\n\n  boolean hasMasks() {\n    for (int i = layers.size() - 1; i >= 0; i--) {\n      BaseLayer layer = layers.get(i);\n      if (layer instanceof ShapeLayer) {\n        if (layer.hasMasksOnThisLayer()) {\n          return true;\n        }\n      }\n    }\n    return false;\n  }\n\n  boolean hasMatte() {\n    if (hasMatteOnThisLayer()) {\n      return true;\n    }\n\n    for (int i = layers.size() - 1; i >= 0; i--) {\n      if (layers.get(i).hasMatteOnThisLayer()) {\n        return true;\n      }\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/CompositionLoader.java",
    "content": "package com.airbnb.lottie;\n\nimport android.os.AsyncTask;\n\nabstract class CompositionLoader<Params> extends AsyncTask<Params, Void, LottieComposition>\n    implements Cancellable {\n  @Override public void cancel() {\n    cancel(true);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/Content.java",
    "content": "package com.airbnb.lottie;\n\nimport java.util.List;\n\ninterface Content {\n  void setContents(List<Content> contentsBefore, List<Content> contentsAfter);\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ContentGroup.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Canvas;\nimport android.graphics.Matrix;\nimport android.graphics.Path;\nimport android.support.annotation.Nullable;\n\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\n\nclass ContentGroup implements DrawingContent, PathContent,\n    BaseKeyframeAnimation.AnimationListener {\n  private final Matrix matrix = new Matrix();\n  private final Path path = new Path();\n\n  private final List<Content> contents = new ArrayList<>();\n  private final LottieDrawable lottieDrawable;\n  @Nullable private List<PathContent> pathContents;\n  @Nullable private TransformKeyframeAnimation transformAnimation;\n\n  ContentGroup(final LottieDrawable lottieDrawable, BaseLayer layer, ShapeGroup shapeGroup) {\n    this.lottieDrawable = lottieDrawable;\n    List<Object> items = shapeGroup.getItems();\n    if (items.isEmpty()) {\n      return;\n    }\n\n    Object potentialTransform = items.get(items.size() - 1);\n    if (potentialTransform instanceof AnimatableTransform) {\n      transformAnimation = ((AnimatableTransform) potentialTransform).createAnimation();\n      //noinspection ConstantConditions\n      transformAnimation.addAnimationsToLayer(layer);\n      transformAnimation.addListener(this);\n    }\n\n    for (int i = 0; i < items.size(); i++) {\n      Object item = items.get(i);\n      if (item instanceof ShapeFill) {\n        contents.add(new FillContent(lottieDrawable, layer, (ShapeFill) item));\n      } else if (item instanceof ShapeStroke) {\n        contents.add(new StrokeContent(lottieDrawable, layer, (ShapeStroke) item));\n      } else if (item instanceof ShapeGroup) {\n        contents.add(new ContentGroup(lottieDrawable, layer, (ShapeGroup) item));\n      } else if (item instanceof RectangleShape) {\n        contents.add(new RectangleContent(lottieDrawable, layer, (RectangleShape) item));\n      } else if (item instanceof CircleShape) {\n        contents.add(new EllipseContent(lottieDrawable, layer, (CircleShape) item));\n      } else if (item instanceof ShapePath) {\n        contents.add(new ShapeContent(lottieDrawable, layer, (ShapePath) item));\n      } else if (item instanceof PolystarShape) {\n        contents.add(new PolystarContent(lottieDrawable, layer, (PolystarShape) item));\n      } else if (item instanceof ShapeTrimPath) {\n        contents.add(new TrimPathContent(layer, (ShapeTrimPath) item));\n      } else //noinspection StatementWithEmptyBody\n        if (item instanceof MergePaths) {\n        // Merge paths are not ready yet.\n        // contents.add(new MergePathsContent((MergePaths) item));\n      }\n    }\n\n    List<Content> contentsToRemove = new ArrayList<>();\n    MergePathsContent currentMergePathsContent = null;\n    for (int i = contents.size() - 1; i >= 0; i--) {\n      Content content = contents.get(i);\n      if (content instanceof MergePathsContent) {\n        currentMergePathsContent = (MergePathsContent) content;\n      }\n      if (currentMergePathsContent != null && content != currentMergePathsContent) {\n        currentMergePathsContent.addContentIfNeeded(content);\n        contentsToRemove.add(content);\n      }\n    }\n\n    Iterator<Content> it = contents.iterator();\n    while (it.hasNext()) {\n      Content content = it.next();\n      if (contentsToRemove.contains(content)) {\n        it.remove();\n      }\n    }\n  }\n\n  @Override public void onValueChanged() {\n    lottieDrawable.invalidateSelf();\n  }\n\n  @Override public void setContents(List<Content> contentsBefore, List<Content> contentsAfter) {\n    // Do nothing with contents after.\n    List<Content> myContentsBefore = new ArrayList<>(contentsBefore.size() + contents.size());\n    myContentsBefore.addAll(contentsBefore);\n\n    for (int i = contents.size() - 1; i >= 0; i--) {\n      Content content = contents.get(i);\n      content.setContents(myContentsBefore, contents.subList(0, i));\n      myContentsBefore.add(content);\n    }\n  }\n\n  List<PathContent> getPathList() {\n    if (pathContents == null) {\n      pathContents = new ArrayList<>();\n      for (int i = 0; i < contents.size(); i++) {\n        Content content = contents.get(i);\n        if (content instanceof PathContent) {\n          pathContents.add((PathContent) content);\n        }\n      }\n    }\n    return pathContents;\n  }\n\n  Matrix getTransformationMatrix() {\n    if (transformAnimation != null) {\n      return transformAnimation.getMatrix();\n    }\n    matrix.reset();\n    return matrix;\n  }\n\n  @Override public Path getPath() {\n    // TODO: cache this somehow.\n    matrix.reset();\n    if (transformAnimation != null) {\n      matrix.set(transformAnimation.getMatrix());\n    }\n    path.reset();\n    for (int i = contents.size() - 1; i >= 0; i--) {\n      Content content = contents.get(i);\n      if (content instanceof PathContent) {\n        path.addPath(((PathContent) content).getPath(), matrix);\n      }\n    }\n    return path;\n  }\n\n  @Override public void draw(Canvas canvas, Matrix parentMatrix, int parentAlpha) {\n    matrix.set(parentMatrix);\n    int alpha;\n    if (transformAnimation != null) {\n      matrix.preConcat(transformAnimation.getMatrix());\n      alpha =\n          (int) ((transformAnimation.getOpacity().getValue() / 100f * parentAlpha / 255f) * 255);\n    } else {\n      alpha = parentAlpha;\n    }\n\n\n    for (int i = contents.size() - 1; i >= 0; i--) {\n      Object content = contents.get(i);\n      if (content instanceof DrawingContent) {\n        ((DrawingContent) content).draw(canvas, matrix, alpha);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/CubicCurveData.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.PointF;\n\nclass CubicCurveData {\n  private final PointF controlPoint1;\n  private final PointF controlPoint2;\n  private final PointF vertex;\n\n  CubicCurveData() {\n    controlPoint1 = new PointF();\n    controlPoint2 = new PointF();\n    vertex = new PointF();\n  }\n\n  CubicCurveData(PointF controlPoint1, PointF controlPoint2, PointF vertex) {\n    this.controlPoint1 = controlPoint1;\n    this.controlPoint2 = controlPoint2;\n    this.vertex = vertex;\n  }\n\n  void setControlPoint1(float x, float y) {\n    controlPoint1.set(x, y);\n  }\n\n  PointF getControlPoint1() {\n    return controlPoint1;\n  }\n\n  void setControlPoint2(float x, float y) {\n    controlPoint2.set(x, y);\n  }\n\n  PointF getControlPoint2() {\n    return controlPoint2;\n  }\n\n  void setVertex(float x, float y) {\n    vertex.set(x, y);\n  }\n\n  PointF getVertex() {\n    return vertex;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/DrawingContent.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Canvas;\nimport android.graphics.Matrix;\n\ninterface DrawingContent extends Content {\n  void draw(Canvas canvas, Matrix parentMatrix, int alpha);\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/EllipseContent.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Path;\nimport android.graphics.PointF;\nimport android.support.annotation.Nullable;\n\nimport java.util.List;\n\nclass EllipseContent implements PathContent, BaseKeyframeAnimation.AnimationListener {\n  private static final float ELLIPSE_CONTROL_POINT_PERCENTAGE = 0.55228f;\n\n  private final Path path = new Path();\n\n  private final LottieDrawable lottieDrawable;\n  private final BaseKeyframeAnimation<?, PointF> sizeAnimation;\n  private final BaseKeyframeAnimation<?, PointF> positionAnimation;\n\n  @Nullable private TrimPathContent trimPath;\n  private boolean isPathValid;\n\n  EllipseContent(LottieDrawable lottieDrawable, BaseLayer layer, CircleShape circleShape) {\n    this.lottieDrawable = lottieDrawable;\n    sizeAnimation = circleShape.getSize().createAnimation();\n    positionAnimation = circleShape.getPosition().createAnimation();\n\n    layer.addAnimation(sizeAnimation);\n    layer.addAnimation(positionAnimation);\n\n    sizeAnimation.addUpdateListener(this);\n    positionAnimation.addUpdateListener(this);\n  }\n\n  @Override public void onValueChanged() {\n    invalidate();\n  }\n\n  private void invalidate() {\n    isPathValid = false;\n    lottieDrawable.invalidateSelf();\n  }\n\n  @Override public void setContents(List<Content> contentsBefore, List<Content> contentsAfter) {\n    for (int i = 0; i < contentsBefore.size(); i++) {\n      Content content = contentsBefore.get(i);\n      if (content instanceof TrimPathContent) {\n        trimPath = (TrimPathContent) content;\n        trimPath.addListener(this);\n      }\n    }\n  }\n\n  @Override public Path getPath() {\n    if (isPathValid) {\n      return path;\n    }\n\n    path.reset();\n\n\n    PointF size = sizeAnimation.getValue();\n    float halfWidth = size.x / 2f;\n    float halfHeight = size.y / 2f;\n    // TODO: handle bounds\n\n    float cpW = halfWidth * ELLIPSE_CONTROL_POINT_PERCENTAGE;\n    float cpH = halfHeight * ELLIPSE_CONTROL_POINT_PERCENTAGE;\n\n    path.reset();\n    path.moveTo(0, -halfHeight);\n    path.cubicTo(0 + cpW, -halfHeight, halfWidth, 0 - cpH, halfWidth, 0);\n    path.cubicTo(halfWidth, 0 + cpH, 0 + cpW, halfHeight, 0, halfHeight);\n    path.cubicTo(0 - cpW, halfHeight, -halfWidth, 0 + cpH, -halfWidth, 0);\n    path.cubicTo(-halfWidth, 0 - cpH, 0 - cpW, -halfHeight, 0, -halfHeight);\n\n    PointF position = positionAnimation.getValue();\n    path.offset(position.x, position.y);\n\n    path.close();\n\n    Utils.applyTrimPathIfNeeded(path, trimPath);\n\n    isPathValid = true;\n    return path;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/FileCompositionLoader.java",
    "content": "package com.airbnb.lottie;\n\nimport android.content.res.Resources;\n\nimport java.io.InputStream;\n\nfinal class FileCompositionLoader extends CompositionLoader<InputStream> {\n  private final Resources res;\n  private final OnCompositionLoadedListener loadedListener;\n\n  FileCompositionLoader(Resources res, OnCompositionLoadedListener loadedListener) {\n    this.res = res;\n    this.loadedListener = loadedListener;\n  }\n\n  @Override protected LottieComposition doInBackground(InputStream... params) {\n    return LottieComposition.Factory.fromInputStream(res, params[0]);\n  }\n\n  @Override protected void onPostExecute(LottieComposition composition) {\n    loadedListener.onCompositionLoaded(composition);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/FillContent.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Canvas;\nimport android.graphics.Matrix;\nimport android.graphics.Paint;\nimport android.graphics.Path;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nclass FillContent implements DrawingContent, BaseKeyframeAnimation.AnimationListener {\n  private final Path path = new Path();\n  private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);\n  private final List<PathContent> paths = new ArrayList<>();\n  private final KeyframeAnimation<Integer> colorAnimation;\n  private final KeyframeAnimation<Integer> opacityAnimation;\n  private final LottieDrawable lottieDrawable;\n\n  FillContent(final LottieDrawable lottieDrawable, BaseLayer layer, ShapeFill fill) {\n    this.lottieDrawable = lottieDrawable;\n    if (fill.getColor() == null || fill.getOpacity() == null ) {\n      colorAnimation = null;\n      opacityAnimation = null;\n      return;\n    }\n\n    path.setFillType(fill.getFillType());\n\n    colorAnimation = fill.getColor().createAnimation();\n    colorAnimation.addUpdateListener(this);\n    layer.addAnimation(colorAnimation);\n    opacityAnimation = fill.getOpacity().createAnimation();\n    opacityAnimation.addUpdateListener(this);\n    layer.addAnimation(opacityAnimation);\n  }\n\n  @Override public void onValueChanged() {\n    lottieDrawable.invalidateSelf();\n  }\n\n  @Override public void setContents(List<Content> contentsBefore, List<Content> contentsAfter) {\n    for (int i = 0; i < contentsAfter.size(); i++) {\n      Content content = contentsAfter.get(i);\n      if (content instanceof PathContent) {\n        paths.add((PathContent) content);\n      }\n    }\n  }\n\n  @Override public void draw(Canvas canvas, Matrix parentMatrix, int parentAlpha) {\n    paint.setColor(colorAnimation.getValue());\n    int alpha = (int) ((parentAlpha / 255f * opacityAnimation.getValue() / 100f) * 255);\n    paint.setAlpha(alpha);\n\n    path.reset();\n    for (int i = 0; i < paths.size(); i++) {\n      path.addPath(paths.get(i).getPath(), parentMatrix);\n    }\n\n    canvas.drawPath(path, paint);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/FloatKeyframeAnimation.java",
    "content": "package com.airbnb.lottie;\n\nimport java.util.List;\n\nimport static com.airbnb.lottie.MiscUtils.lerp;\n\nclass FloatKeyframeAnimation extends KeyframeAnimation<Float> {\n\n  FloatKeyframeAnimation(List<Keyframe<Float>> keyframes) {\n    super(keyframes);\n  }\n\n  @Override Float getValue(Keyframe<Float> keyframe, float keyframeProgress) {\n    if (keyframe.startValue == null || keyframe.endValue == null) {\n      throw new IllegalStateException(\"Missing values for keyframe.\");\n    }\n    return lerp(keyframe.startValue, keyframe.endValue, keyframeProgress);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/GammaEvaluator.java",
    "content": "package com.airbnb.lottie;\n\n/**\n * Use this instead of {@link android.animation.ArgbEvaluator} because it interpolates through the gamma color\n * space which looks better to us humans.\n * <p>\n * Writted by Romain Guy and Francois Blavoet.\n * https://androidstudygroup.slack.com/archives/animation/p1476461064000335\n */\nclass GammaEvaluator {\n\n  // Opto-electronic conversion function for the sRGB color space\n  // Takes a gamma-encoded sRGB value and converts it to a linear sRGB value\n  private static float OECF_sRGB(float linear) {\n    // IEC 61966-2-1:1999\n    return linear <= 0.0031308f ?\n        linear * 12.92f : (float) ((Math.pow(linear, 1.0f / 2.4f) * 1.055f) - 0.055f);\n  }\n\n  // Electro-optical conversion function for the sRGB color space\n  // Takes a linear sRGB value and converts it to a gamma-encoded sRGB value\n  private static float EOCF_sRGB(float srgb) {\n    // IEC 61966-2-1:1999\n    return srgb <= 0.04045f ? srgb / 12.92f : (float) Math.pow((srgb + 0.055f) / 1.055f, 2.4f);\n  }\n\n  static int evaluate(float fraction, int startInt, int endInt) {\n    float startA = ((startInt >> 24) & 0xff) / 255.0f;\n    float startR = ((startInt >> 16) & 0xff) / 255.0f;\n    float startG = ((startInt >> 8) & 0xff) / 255.0f;\n    float startB = (startInt & 0xff) / 255.0f;\n\n    float endA = ((endInt >> 24) & 0xff) / 255.0f;\n    float endR = ((endInt >> 16) & 0xff) / 255.0f;\n    float endG = ((endInt >> 8) & 0xff) / 255.0f;\n    float endB = (endInt & 0xff) / 255.0f;\n\n    // convert from sRGB to linear\n    startR = EOCF_sRGB(startR);\n    startG = EOCF_sRGB(startG);\n    startB = EOCF_sRGB(startB);\n\n    endR = EOCF_sRGB(endR);\n    endG = EOCF_sRGB(endG);\n    endB = EOCF_sRGB(endB);\n\n    // compute the interpolated color in linear space\n    float a = startA + fraction * (endA - startA);\n    float r = startR + fraction * (endR - startR);\n    float g = startG + fraction * (endG - startG);\n    float b = startB + fraction * (endB - startB);\n\n    // convert back to sRGB in the [0..255] range\n    a = a * 255.0f;\n    r = OECF_sRGB(r) * 255.0f;\n    g = OECF_sRGB(g) * 255.0f;\n    b = OECF_sRGB(b) * 255.0f;\n\n    return Math.round(a) << 24 | Math.round(r) << 16 | Math.round(g) << 8 | Math.round(b);\n  }\n}"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ImageAssetBitmapManager.java",
    "content": "package com.airbnb.lottie;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.graphics.drawable.Drawable;\nimport android.support.annotation.Nullable;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.view.View;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.Map;\n\nimport static junit.framework.Assert.assertNotNull;\n\nclass ImageAssetBitmapManager {\n  private final Context context;\n  private String imagesFolder;\n  @Nullable private ImageAssetDelegate assetDelegate;\n  private final Map<String, LottieImageAsset> imageAssets;\n  private final Map<String, Bitmap> bitmaps = new HashMap<>();\n\n  ImageAssetBitmapManager(Drawable.Callback callback, String imagesFolder,\n      ImageAssetDelegate assetDelegate, Map<String, LottieImageAsset> imageAssets) {\n    assertNotNull(callback);\n\n    this.imagesFolder = imagesFolder;\n    if (!TextUtils.isEmpty(imagesFolder) &&\n        this.imagesFolder.charAt(this.imagesFolder.length() - 1) != '/') {\n      this.imagesFolder += '/';\n    }\n\n    if (!(callback instanceof View)) {\n      Log.w(L.TAG, \"LottieDrawable must be inside of a view for images to work.\");\n      this.imageAssets = new HashMap<>();\n      context = null;\n      return;\n    }\n\n    context = ((View) callback).getContext();\n    this.imageAssets = imageAssets;\n    setAssetDelegate(assetDelegate);\n  }\n\n  void setAssetDelegate(@Nullable ImageAssetDelegate assetDelegate) {\n    this.assetDelegate = assetDelegate;\n  }\n\n  Bitmap bitmapForId(String id) {\n    Bitmap bitmap = bitmaps.get(id);\n    if (bitmap == null) {\n      LottieImageAsset imageAsset = imageAssets.get(id);\n      if (imageAsset == null) {\n        return null;\n      }\n      if (assetDelegate != null) {\n        bitmap = assetDelegate.fetchBitmap(imageAsset);\n        bitmaps.put(id, bitmap);\n        return bitmap;\n      }\n\n      InputStream is;\n      try {\n        if (TextUtils.isEmpty(imagesFolder)) {\n          throw new IllegalStateException(\"You must set an images folder before loading an image.\" +\n              \" Set it with LottieComposition#setImagesFolder or LottieDrawable#setImagesFolder\");\n        }\n        is = context.getAssets().open(imagesFolder + imageAsset.getFileName());\n      } catch (IOException e) {\n        Log.w(L.TAG, \"Unable to open asset.\", e);\n        return null;\n      }\n      BitmapFactory.Options opts = new BitmapFactory.Options();\n      opts.inScaled = true;\n      opts.inDensity = 160;\n      bitmap = BitmapFactory.decodeStream(is, null, opts);\n      bitmaps.put(id, bitmap);\n    }\n    return bitmap;\n  }\n\n  void recycleBitmaps() {\n    Iterator<Map.Entry<String, Bitmap>> it = bitmaps.entrySet().iterator();\n    while (it.hasNext()) {\n      Map.Entry<String, Bitmap> entry = it.next();\n      entry.getValue().recycle();\n      it.remove();\n    }\n  }\n\n  boolean hasSameContext(Context context) {\n    return context == null && this.context == null ||\n        context != null && this.context.equals(context);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ImageAssetDelegate.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Bitmap;\n\n/**\n * Delegate to handle the loading of bitmaps that are not packaged in the assets of your app.\n *\n * @see LottieDrawable#setImageAssetDelegate(ImageAssetDelegate)\n */\npublic interface ImageAssetDelegate {\n  Bitmap fetchBitmap(LottieImageAsset asset);\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ImageLayer.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Matrix;\nimport android.graphics.Paint;\nimport android.support.annotation.NonNull;\n\nclass ImageLayer extends BaseLayer {\n\n  private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);\n\n  ImageLayer(LottieDrawable lottieDrawable, Layer layerModel) {\n    super(lottieDrawable, layerModel);\n  }\n\n  @Override public void drawLayer(@NonNull Canvas canvas, Matrix parentMatrix, int parentAlpha) {\n    String refId = layerModel.getRefId();\n    Bitmap bitmap = lottieDrawable.getImageAsset(refId);\n    if (bitmap == null) {\n      return;\n    }\n\n    paint.setAlpha(parentAlpha);\n    canvas.save();\n    canvas.concat(parentMatrix);\n    canvas.drawBitmap(bitmap, 0, 0 , paint);\n    canvas.restore();\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/IntegerKeyframeAnimation.java",
    "content": "package com.airbnb.lottie;\n\nimport java.util.List;\n\nimport static com.airbnb.lottie.MiscUtils.lerp;\n\nclass IntegerKeyframeAnimation extends KeyframeAnimation<Integer> {\n\n  IntegerKeyframeAnimation(List<Keyframe<Integer>> keyframes) {\n    super(keyframes);\n  }\n\n  @Override Integer getValue(Keyframe<Integer> keyframe, float keyframeProgress) {\n    if (keyframe.startValue == null || keyframe.endValue == null) {\n      throw new IllegalStateException(\"Missing values for keyframe.\");\n    }\n    return lerp(keyframe.startValue, keyframe.endValue, keyframeProgress);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/JsonCompositionLoader.java",
    "content": "package com.airbnb.lottie;\n\nimport android.content.res.Resources;\n\nimport org.json.JSONObject;\n\nfinal class JsonCompositionLoader extends CompositionLoader<JSONObject> {\n  private final Resources res;\n  private final OnCompositionLoadedListener loadedListener;\n\n  JsonCompositionLoader(Resources res, OnCompositionLoadedListener loadedListener) {\n    this.res = res;\n    this.loadedListener = loadedListener;\n  }\n\n  @Override protected LottieComposition doInBackground(JSONObject... params) {\n    return LottieComposition.Factory.fromJsonSync(res, params[0]);\n  }\n\n  @Override protected void onPostExecute(LottieComposition composition) {\n    loadedListener.onCompositionLoaded(composition);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/JsonUtils.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.PointF;\n\nimport org.json.JSONArray;\nimport org.json.JSONObject;\n\nclass JsonUtils {\n  private JsonUtils() {\n  }\n\n  static PointF pointFromJsonObject(JSONObject values, float scale) {\n    return new PointF(\n        valueFromObject(values.opt(\"x\")) * scale,\n        valueFromObject(values.opt(\"y\")) * scale);\n  }\n\n  static PointF pointFromJsonArray(JSONArray values, float scale) {\n    if (values.length() < 2) {\n      throw new IllegalArgumentException(\"Unable to parse point for \" + values);\n    }\n    return new PointF(\n        (float) values.optDouble(0, 1) * scale,\n        (float) values.optDouble(1, 1) * scale);\n  }\n\n  static float valueFromObject(Object object) {\n    if (object instanceof Float) {\n      return (float) object;\n    } else if (object instanceof Integer) {\n      return (Integer) object;\n    } else if (object instanceof Double) {\n      return (float) (double) object;\n    } else if (object instanceof JSONArray) {\n      return (float) ((JSONArray) object).optDouble(0);\n    } else {\n      return 0;\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/Keyframe.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.PointF;\nimport android.support.annotation.FloatRange;\nimport android.support.annotation.Nullable;\nimport android.support.v4.view.animation.PathInterpolatorCompat;\nimport android.view.animation.Interpolator;\nimport android.view.animation.LinearInterpolator;\n\nimport org.json.JSONArray;\nimport org.json.JSONObject;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\nclass Keyframe<T> {\n  private static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();\n\n  /**\n   * The json doesn't include end frames. The data can be taken from the start frame of the next\n   * keyframe though.\n   */\n  static void setEndFrames(List<? extends Keyframe<?>> keyframes) {\n    int size = keyframes.size();\n    for (int i = 0; i < size - 1; i++) {\n      // In the json, the keyframes only contain their starting frame.\n      keyframes.get(i).endFrame = keyframes.get(i + 1).startFrame;\n    }\n    Keyframe<?> lastKeyframe = keyframes.get(size - 1);\n    if (lastKeyframe.startValue == null) {\n      // The only purpose the last keyframe has is to provide the end frame of the previous\n      // keyframe.\n      //noinspection SuspiciousMethodCalls\n      keyframes.remove(lastKeyframe);\n    }\n  }\n\n\n  private final LottieComposition composition;\n  @Nullable final T startValue;\n  @Nullable final T endValue;\n  @Nullable final Interpolator interpolator;\n  @SuppressWarnings(\"WeakerAccess\") final float startFrame;\n  @SuppressWarnings(\"WeakerAccess\") @Nullable Float endFrame;\n\n  public Keyframe(LottieComposition composition, @Nullable T startValue, @Nullable T endValue,\n      @Nullable Interpolator interpolator, float startFrame, @Nullable Float endFrame) {\n    this.composition = composition;\n    this.startValue = startValue;\n    this.endValue = endValue;\n    this.interpolator = interpolator;\n    this.startFrame = startFrame;\n    this.endFrame = endFrame;\n  }\n\n  @FloatRange(from = 0f, to = 1f)\n  float getStartProgress() {\n    return startFrame / composition.getDurationFrames();\n  }\n\n  @FloatRange(from = 0f, to = 1f)\n  float getEndProgress() {\n    //noinspection Range\n    return endFrame == null ? 1f : endFrame / composition.getDurationFrames();\n  }\n\n  boolean isStatic() {\n    return interpolator == null;\n  }\n\n  boolean containsProgress(@FloatRange(from = 0f, to = 1f) float progress) {\n    return progress >= getStartProgress() && progress <= getEndProgress();\n  }\n\n  @Override public String toString() {\n    return \"Keyframe{\" + \"startValue=\" + startValue +\n        \", endValue=\" + endValue +\n        \", startFrame=\" + startFrame +\n        \", endFrame=\" + endFrame +\n        \", interpolator=\" + interpolator +\n        '}';\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    static <T> Keyframe<T> newInstance(JSONObject json, LottieComposition composition, float scale,\n        AnimatableValue.Factory<T> valueFactory) {\n      PointF cp1 = null;\n      PointF cp2 = null;\n      float startFrame = 0;\n      T startValue = null;\n      T endValue = null;\n      Interpolator interpolator = null;\n\n      if (json.has(\"t\")) {\n        startFrame = (float) json.optDouble(\"t\", 0);\n        Object startValueJson = json.opt(\"s\");\n        if (startValueJson != null) {\n          startValue = valueFactory.valueFromObject(startValueJson, scale);\n        }\n\n        Object endValueJson = json.opt(\"e\");\n        if (endValueJson != null) {\n          endValue = valueFactory.valueFromObject(endValueJson, scale);\n        }\n\n        JSONObject cp1Json = json.optJSONObject(\"o\");\n        JSONObject cp2Json = json.optJSONObject(\"i\");\n        if (cp1Json != null && cp2Json != null) {\n          cp1 = JsonUtils.pointFromJsonObject(cp1Json, scale);\n          cp2 = JsonUtils.pointFromJsonObject(cp2Json, scale);\n        }\n\n        boolean hold = json.optInt(\"h\", 0) == 1;\n\n        if (hold) {\n          endValue = startValue;\n          // TODO: create a HoldInterpolator so progress changes don't invalidate.\n          interpolator = LINEAR_INTERPOLATOR;\n        } else if (cp1 != null) {\n          interpolator = PathInterpolatorCompat.create(\n              cp1.x / scale, cp1.y / scale, cp2.x / scale, cp2.y / scale);\n        } else {\n          interpolator = LINEAR_INTERPOLATOR;\n        }\n      } else {\n        startValue = valueFactory.valueFromObject(json, scale);\n        endValue = startValue;\n      }\n      return new Keyframe<>(composition, startValue, endValue, interpolator, startFrame, null);\n    }\n\n    static <T> List<Keyframe<T>> parseKeyframes(JSONArray json, LottieComposition composition,\n        float scale, AnimatableValue.Factory<T> valueFactory) {\n      int length = json.length();\n      if (length == 0) {\n        return Collections.emptyList();\n      }\n      List<Keyframe<T>> keyframes = new ArrayList<>();\n      for (int i = 0; i < length; i++) {\n        keyframes.add(Keyframe.Factory.newInstance(json.optJSONObject(i), composition, scale,\n            valueFactory));\n      }\n\n      setEndFrames(keyframes);\n      return keyframes;\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/KeyframeAnimation.java",
    "content": "package com.airbnb.lottie;\n\nimport java.util.List;\n\npublic abstract class KeyframeAnimation<T> extends BaseKeyframeAnimation<T, T> {\n  KeyframeAnimation(List<? extends Keyframe<T>> keyframes) {\n    super(keyframes);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/L.java",
    "content": "package com.airbnb.lottie;\n\npublic class L {\n  static final String TAG = \"LOTTIE\";\n  public static final boolean DBG = false;\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/Layer.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Color;\nimport android.support.annotation.Nullable;\nimport android.util.Log;\n\nimport org.json.JSONArray;\nimport org.json.JSONObject;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Locale;\n\nclass Layer {\n  private static final String TAG = Layer.class.getSimpleName();\n\n  enum LayerType {\n    PreComp,\n    Solid,\n    Image,\n    Null,\n    Shape,\n    Text,\n    Unknown\n  }\n\n  enum MatteType {\n    None,\n    Add,\n    Invert,\n    Unknown\n  }\n\n  private final List<Object> shapes;\n  private final LottieComposition composition;\n  private final String layerName;\n  private final long layerId;\n  private final LayerType layerType;\n  private final long parentId;\n  @Nullable private final String refId;\n  private final List<Mask> masks;\n  private final AnimatableTransform transform;\n  private final int solidWidth;\n  private final int solidHeight;\n  private final int solidColor;\n  private final float timeStretch;\n  private final float startProgress;\n  private final int preCompWidth;\n  private final int preCompHeight;\n  private final List<Keyframe<Float>> inOutKeyframes;\n  private final MatteType matteType;\n\n  private Layer(List<Object> shapes, LottieComposition composition, String layerName, long layerId,\n      LayerType layerType, long parentId, @Nullable String refId, List<Mask> masks,\n      AnimatableTransform transform, int solidWidth, int solidHeight, int solidColor,\n      float timeStretch, float startProgress, int preCompWidth, int preCompHeight,\n      List<Keyframe<Float>> inOutKeyframes, MatteType matteType) {\n    this.shapes = shapes;\n    this.composition = composition;\n    this.layerName = layerName;\n    this.layerId = layerId;\n    this.layerType = layerType;\n    this.parentId = parentId;\n    this.refId = refId;\n    this.masks = masks;\n    this.transform = transform;\n    this.solidWidth = solidWidth;\n    this.solidHeight = solidHeight;\n    this.solidColor = solidColor;\n    this.timeStretch = timeStretch;\n    this.startProgress = startProgress;\n    this.preCompWidth = preCompWidth;\n    this.preCompHeight = preCompHeight;\n    this.inOutKeyframes = inOutKeyframes;\n    this.matteType = matteType;\n  }\n\n  LottieComposition getComposition() {\n    return composition;\n  }\n\n  float getTimeStretch() {\n    return timeStretch;\n  }\n\n  float getStartProgress() {\n    return startProgress;\n  }\n\n  List<Keyframe<Float>> getInOutKeyframes() {\n    return inOutKeyframes;\n  }\n\n  long getId() {\n    return layerId;\n  }\n\n  String getName() {\n    return layerName;\n  }\n\n  @Nullable String getRefId() {\n    return refId;\n  }\n\n  int getPreCompWidth() {\n    return preCompWidth;\n  }\n\n  int getPreCompHeight() {\n    return preCompHeight;\n  }\n\n  List<Mask> getMasks() {\n    return masks;\n  }\n\n  LayerType getLayerType() {\n    return layerType;\n  }\n\n  MatteType getMatteType() {\n    return matteType;\n  }\n\n  long getParentId() {\n    return parentId;\n  }\n\n  List<Object> getShapes() {\n    return shapes;\n  }\n\n  AnimatableTransform getTransform() {\n    return transform;\n  }\n\n  int getSolidColor() {\n    return solidColor;\n  }\n\n  int getSolidHeight() {\n    return solidHeight;\n  }\n\n  int getSolidWidth() {\n    return solidWidth;\n  }\n\n  @Override public String toString() {\n    return toString(\"\");\n  }\n\n  String toString(String prefix) {\n    StringBuilder sb = new StringBuilder();\n    sb.append(prefix).append(getName()).append(\"\\n\");\n    Layer parent = composition.layerModelForId(getParentId());\n    if (parent != null) {\n      sb.append(\"\\t\\tParents: \").append(parent.getName());\n      parent = composition.layerModelForId(parent.getParentId());\n      while (parent != null) {\n        sb.append(\"->\").append(parent.getName());\n        parent = composition.layerModelForId(parent.getParentId());\n      }\n      sb.append(prefix).append(\"\\n\");\n    }\n    if (!getMasks().isEmpty()) {\n      sb.append(prefix).append(\"\\tMasks: \").append(getMasks().size()).append(\"\\n\");\n    }\n    if (getSolidWidth() != 0 && getSolidHeight() != 0) {\n      sb.append(prefix).append(\"\\tBackground: \").append(String\n          .format(Locale.US, \"%dx%d %X\\n\", getSolidWidth(), getSolidHeight(), getSolidColor()));\n    }\n    if (!shapes.isEmpty()) {\n      sb.append(prefix).append(\"\\tShapes:\\n\");\n      for (Object shape : shapes) {\n        sb.append(prefix).append(\"\\t\\t\").append(shape).append(\"\\n\");\n      }\n    }\n    return sb.toString();\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    static Layer newInstance(LottieComposition composition) {\n      // TODO: make sure in out keyframes work\n      return new Layer(Collections.emptyList(), composition, null, -1, LayerType.PreComp, -1, null,\n          Collections.<Mask>emptyList(), AnimatableTransform.Factory.newInstance(),\n          0, 0, 0, 0, 0, 0, 0, Collections.<Keyframe<Float>>emptyList(), MatteType.None);\n    }\n\n    static Layer newInstance(JSONObject json, LottieComposition composition) {\n      String layerName = json.optString(\"nm\");\n      String refId = json.optString(\"refId\");\n      long layerId = json.optLong(\"ind\");\n      int solidWidth = 0;\n      int solidHeight = 0;\n      int solidColor = 0;\n      int preCompWidth = 0;\n      int preCompHeight = 0;\n      LayerType layerType;\n      int layerTypeInt = json.optInt(\"ty\", -1);\n      if (layerTypeInt < LayerType.Unknown.ordinal()) {\n        layerType = LayerType.values()[layerTypeInt];\n      } else {\n        layerType = LayerType.Unknown;\n      }\n\n      long parentId = json.optLong(\"parent\", -1);\n\n      if (layerType == LayerType.Solid) {\n        solidWidth = (int) (json.optInt(\"sw\") * composition.getDpScale());\n        solidHeight = (int) (json.optInt(\"sh\") * composition.getDpScale());\n        solidColor = Color.parseColor(json.optString(\"sc\"));\n        if (L.DBG) {\n          Log.d(TAG, \"\\tSolid=\" + Integer.toHexString(solidColor) + \" \" +\n              solidWidth + \"x\" + solidHeight + \" \" + composition.getBounds());\n        }\n      }\n\n      AnimatableTransform transform = AnimatableTransform.Factory.newInstance(json.optJSONObject(\"ks\"),\n          composition);\n      MatteType matteType = MatteType.values()[json.optInt(\"tt\")];\n      List<Object> shapes = new ArrayList<>();\n      List<Mask> masks = new ArrayList<>();\n      List<Keyframe<Float>> inOutKeyframes = new ArrayList<>();\n      JSONArray jsonMasks = json.optJSONArray(\"masksProperties\");\n      if (jsonMasks != null) {\n        for (int i = 0; i < jsonMasks.length(); i++) {\n          Mask mask = Mask.Factory.newMask(jsonMasks.optJSONObject(i), composition);\n          masks.add(mask);\n        }\n      }\n\n      JSONArray shapesJson = json.optJSONArray(\"shapes\");\n      if (shapesJson != null) {\n        for (int i = 0; i < shapesJson.length(); i++) {\n          Object shape = ShapeGroup.shapeItemWithJson(shapesJson.optJSONObject(i), composition);\n          if (shape != null) {\n            shapes.add(shape);\n          }\n        }\n      }\n\n      float timeStretch = (float) json.optDouble(\"sr\", 1.0);\n      float startFrame = (float) json.optDouble(\"st\");\n      float frames = composition.getDurationFrames();\n      float startProgress = startFrame / frames;\n\n      if (layerType == LayerType.PreComp) {\n        preCompWidth = (int) (json.optInt(\"w\") * composition.getDpScale());\n        preCompHeight = (int) (json.optInt(\"h\") * composition.getDpScale());\n      }\n\n      float inFrame = json.optLong(\"ip\");\n      float outFrame = json.optLong(\"op\");\n\n      // Before the in frame\n      if (inFrame > 0) {\n        Keyframe<Float> preKeyframe = new Keyframe<>(composition, 0f, 0f, null, 0f, inFrame);\n        inOutKeyframes.add(preKeyframe);\n      }\n\n      // The + 1 is because the animation should be visible on the out frame itself.\n      outFrame = (outFrame > 0 ? outFrame : composition.getEndFrame() + 1);\n      Keyframe<Float> visibleKeyframe =\n          new Keyframe<>(composition, 1f, 1f, null, inFrame, outFrame);\n      inOutKeyframes.add(visibleKeyframe);\n\n      if (outFrame <= composition.getDurationFrames()) {\n        Keyframe<Float> outKeyframe =\n            new Keyframe<>(composition, 0f, 0f, null, outFrame, (float) composition.getEndFrame());\n        inOutKeyframes.add(outKeyframe);\n      }\n\n      return new Layer(shapes, composition, layerName, layerId, layerType, parentId, refId,\n          masks, transform, solidWidth, solidHeight, solidColor, timeStretch, startProgress,\n          preCompWidth, preCompHeight, inOutKeyframes, matteType);\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java",
    "content": "package com.airbnb.lottie;\n\nimport android.animation.Animator;\nimport android.animation.ValueAnimator;\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport android.graphics.drawable.Drawable;\nimport android.os.Build;\nimport android.os.Parcel;\nimport android.os.Parcelable;\nimport android.provider.Settings;\nimport android.support.annotation.FloatRange;\nimport android.support.annotation.NonNull;\nimport android.support.annotation.Nullable;\nimport android.support.annotation.VisibleForTesting;\nimport android.support.v7.widget.AppCompatImageView;\nimport android.text.TextUtils;\nimport android.util.AttributeSet;\nimport android.util.Log;\n\nimport org.json.JSONObject;\n\nimport java.lang.ref.WeakReference;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * This view will load, deserialize, and display an After Effects animation exported with\n * bodymovin (https://github.com/bodymovin/bodymovin).\n * <p>\n * You may set the animation in one of two ways:\n * 1) Attrs: {@link R.styleable#LottieAnimationView_lottie_fileName}\n * 2) Programatically: {@link #setAnimation(String)}, {@link #setComposition(LottieComposition)},\n * or {@link #setAnimation(JSONObject)}.\n * <p>\n * You can set a default cache strategy with {@link R.attr#lottie_cacheStrategy}.\n * <p>\n * You can manually set the progress of the animation with {@link #setProgress(float)} or\n * {@link R.attr#lottie_progress}\n */\npublic class LottieAnimationView extends AppCompatImageView {\n  private static final String TAG = LottieAnimationView.class.getSimpleName();\n\n  /**\n   * Caching strategy for compositions that will be reused frequently.\n   * Weak or Strong indicates the GC reference strength of the composition in the cache.\n   */\n  @SuppressWarnings(\"WeakerAccess\")\n  public enum CacheStrategy {\n    None,\n    Weak,\n    Strong\n  }\n\n  private static final Map<String, LottieComposition> strongRefCache = new HashMap<>();\n  private static final Map<String, WeakReference<LottieComposition>> weakRefCache =\n      new HashMap<>();\n\n  private final OnCompositionLoadedListener loadedListener =\n      new OnCompositionLoadedListener() {\n        @Override\n        public void onCompositionLoaded(LottieComposition composition) {\n          setComposition(composition);\n          compositionLoader = null;\n        }\n      };\n\n  private final LottieDrawable lottieDrawable = new LottieDrawable();\n  private CacheStrategy defaultCacheStrategy;\n  private String animationName;\n  private boolean wasAnimatingWhenDetached = false;\n\n  @Nullable private Cancellable compositionLoader;\n  /**\n   * Can be null because it is created async\n   */\n  @Nullable private LottieComposition composition;\n\n  public LottieAnimationView(Context context) {\n    super(context);\n    init(null);\n  }\n\n  public LottieAnimationView(Context context, AttributeSet attrs) {\n    super(context, attrs);\n    init(attrs);\n  }\n\n  public LottieAnimationView(Context context, AttributeSet attrs, int defStyleAttr) {\n    super(context, attrs, defStyleAttr);\n    init(attrs);\n  }\n\n  private void init(@Nullable AttributeSet attrs) {\n    TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.LottieAnimationView);\n    String fileName = ta.getString(R.styleable.LottieAnimationView_lottie_fileName);\n    if (!isInEditMode() && fileName != null) {\n      setAnimation(fileName);\n    }\n    if (ta.getBoolean(R.styleable.LottieAnimationView_lottie_autoPlay, false)) {\n      lottieDrawable.playAnimation();\n    }\n    lottieDrawable.loop(ta.getBoolean(R.styleable.LottieAnimationView_lottie_loop, false));\n    setImageAssetsFolder(ta.getString(R.styleable.LottieAnimationView_lottie_imageAssetsFolder));\n    setProgress(ta.getFloat(R.styleable.LottieAnimationView_lottie_progress, 0));\n    int cacheStrategy = ta.getInt(\n        R.styleable.LottieAnimationView_lottie_cacheStrategy,\n        CacheStrategy.None.ordinal());\n    defaultCacheStrategy = CacheStrategy.values()[cacheStrategy];\n    ta.recycle();\n    setLayerType(LAYER_TYPE_SOFTWARE, null);\n\n    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {\n    float systemAnimationScale = Settings.Global.getFloat(getContext().getContentResolver(),\n        Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f);\n      if (systemAnimationScale == 0f) {\n        lottieDrawable.systemAnimationsAreDisabled();\n      }\n    }\n  }\n\n  @Override public void setImageResource(int resId) {\n    super.setImageResource(resId);\n    recycleBitmaps();\n  }\n\n  @Override public void setImageDrawable(Drawable drawable) {\n    if (drawable != lottieDrawable) {\n      recycleBitmaps();\n    }\n    super.setImageDrawable(drawable);\n  }\n\n  @Override public void invalidateDrawable(@NonNull Drawable dr) {\n    if (getDrawable() == lottieDrawable) {\n      // We always want to invalidate the root drawable to it redraws the whole drawable.\n      // Eventually it would be great to be able to invalidate just the changed region.\n      super.invalidateDrawable(lottieDrawable);\n    } else {\n      // Otherwise work as regular ImageView\n      super.invalidateDrawable(dr);\n    }\n  }\n\n  @Override protected Parcelable onSaveInstanceState() {\n    Parcelable superState = super.onSaveInstanceState();\n    SavedState ss = new SavedState(superState);\n    ss.animationName = animationName;\n    ss.progress = lottieDrawable.getProgress();\n    ss.isAnimating = lottieDrawable.isAnimating();\n    ss.isLooping = lottieDrawable.isLooping();\n    return ss;\n  }\n\n  @Override protected void onRestoreInstanceState(Parcelable state) {\n    if (!(state instanceof SavedState)) {\n      super.onRestoreInstanceState(state);\n      return;\n    }\n\n    SavedState ss = (SavedState) state;\n    super.onRestoreInstanceState(ss.getSuperState());\n    this.animationName = ss.animationName;\n    if (!TextUtils.isEmpty(animationName)) {\n      setAnimation(animationName);\n    }\n    setProgress(ss.progress);\n    loop(ss.isLooping);\n    if (ss.isAnimating) {\n      playAnimation();\n    }\n  }\n\n  @Override protected void onAttachedToWindow() {\n    super.onAttachedToWindow();\n    if (wasAnimatingWhenDetached) {\n      playAnimation();\n    }\n  }\n\n  @Override protected void onDetachedFromWindow() {\n    if (isAnimating()) {\n      cancelAnimation();\n      wasAnimatingWhenDetached = true;\n    }\n    recycleBitmaps();\n    super.onDetachedFromWindow();\n  }\n\n  @VisibleForTesting void recycleBitmaps() {\n    lottieDrawable.recycleBitmaps();\n  }\n\n  /**\n   * Enable hardware acceleration for this view.\n   * READ THIS BEFORE ENABLING HARDWARE ACCELERATION:\n   * 1) Test your animation on the minimum API level you support. Some drawing features such as\n   *    dashes and stroke caps have min api levels\n   *    (https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported)\n   * 2) Enabling hardware acceleration is not always more performant. Check it with your specific\n   *    animation only if you are having performance issues with software rendering.\n   * 3) Software rendering is safer and will be consistent across devices. Manufacturers can\n   *    potentially break hardware rendering with bugs in their SKIA engine. Lottie cannot do\n   *    anything about that.\n   */\n  @SuppressWarnings(\"WeakerAccess\") public void useExperimentalHardwareAcceleration() {\n    setLayerType(LAYER_TYPE_HARDWARE, null);\n  }\n\n  /**\n   * Sets the animation from a file in the assets directory.\n   * This will load and deserialize the file asynchronously.\n   * <p>\n   * Will not cache the composition once loaded.\n   */\n  @SuppressWarnings(\"WeakerAccess\") public void setAnimation(String animationName) {\n    setAnimation(animationName, defaultCacheStrategy);\n  }\n\n  /**\n   * Sets the animation from a file in the assets directory.\n   * This will load and deserialize the file asynchronously.\n   * <p>\n   * You may also specify a cache strategy. Specifying {@link CacheStrategy#Strong} will hold a\n   * strong reference to the composition once it is loaded\n   * and deserialized. {@link CacheStrategy#Weak} will hold a weak reference to said composition.\n   */\n  @SuppressWarnings(\"WeakerAccess\") public void setAnimation(final String animationName, final CacheStrategy cacheStrategy) {\n    this.animationName = animationName;\n    if (weakRefCache.containsKey(animationName)) {\n      WeakReference<LottieComposition> compRef = weakRefCache.get(animationName);\n      if (compRef.get() != null) {\n        setComposition(compRef.get());\n        return;\n      }\n    } else if (strongRefCache.containsKey(animationName)) {\n      setComposition(strongRefCache.get(animationName));\n      return;\n    }\n\n    this.animationName = animationName;\n    lottieDrawable.cancelAnimation();\n    cancelLoaderTask();\n    compositionLoader = LottieComposition.Factory.fromAssetFileName(getContext(), animationName,\n        new OnCompositionLoadedListener() {\n          @Override\n          public void onCompositionLoaded(LottieComposition composition) {\n            if (cacheStrategy == CacheStrategy.Strong) {\n              strongRefCache.put(animationName, composition);\n            } else if (cacheStrategy == CacheStrategy.Weak) {\n              weakRefCache.put(animationName, new WeakReference<>(composition));\n            }\n\n            setComposition(composition);\n          }\n        });\n  }\n\n  /**\n   * Sets the animation from a JSONObject.\n   * This will load and deserialize the file asynchronously.\n   * <p>\n   * This is particularly useful for animations loaded from the network. You can fetch the\n   * bodymovin json from the network and pass it directly here.\n   */\n  public void setAnimation(final JSONObject json) {\n    cancelLoaderTask();\n    compositionLoader = LottieComposition.Factory.fromJson(getResources(), json, loadedListener);\n  }\n\n  private void cancelLoaderTask() {\n    if (compositionLoader != null) {\n      compositionLoader.cancel();\n      compositionLoader = null;\n    }\n  }\n\n  /**\n   * Sets a composition.\n   * You can set a default cache strategy if this view was inflated with xml by\n   * using {@link R.attr#lottie_cacheStrategy}.\n   */\n  public void setComposition(@NonNull LottieComposition composition) {\n    if (L.DBG) {\n      Log.v(TAG, \"Set Composition \\n\" + composition);\n    }\n    lottieDrawable.setCallback(this);\n\n    boolean isNewComposition = lottieDrawable.setComposition(composition);\n    if (!isNewComposition) {\n      // We can avoid re-setting the drawable, and invalidating the view, since the composition\n      // hasn't changed.\n      return;\n    }\n\n    int screenWidth = Utils.getScreenWidth(getContext());\n    int screenHeight = Utils.getScreenHeight(getContext());\n    int compWidth = composition.getBounds().width();\n    int compHeight = composition.getBounds().height();\n    if (compWidth > screenWidth ||\n        compHeight > screenHeight) {\n      float xScale = screenWidth / (float) compWidth;\n      float yScale = screenHeight / (float) compHeight;\n      setScale(Math.min(xScale, yScale));\n      Log.w(L.TAG, String.format(\n          \"Composition larger than the screen %dx%d vs %dx%d. Scaling down.\",\n          compWidth, compHeight, screenWidth, screenHeight));\n    }\n\n\n    // If you set a different composition on the view, the bounds will not update unless\n    // the drawable is different than the original.\n    setImageDrawable(null);\n    setImageDrawable(lottieDrawable);\n\n    this.composition = composition;\n\n    requestLayout();\n  }\n\n  /**\n   * Returns whether or not any layers in this composition has masks.\n   */\n  @SuppressWarnings(\"unused\") public boolean hasMasks() {\n    return lottieDrawable.hasMasks();\n  }\n\n  /**\n   * Returns whether or not any layers in this composition has a matte layer.\n   */\n  @SuppressWarnings(\"unused\") public boolean hasMatte() {\n    return lottieDrawable.hasMatte();\n  }\n\n  /**\n   * If you use image assets, you must explicitly specify the folder in assets/ in which they are\n   * located because bodymovin uses the name filenames across all compositions (img_#).\n   * Do NOT rename the images themselves.\n   *\n   * If your images are located in src/main/assets/airbnb_loader/ then call\n   * `setImageAssetsFolder(\"airbnb_loader/\");`.\n   */\n  @SuppressWarnings(\"WeakerAccess\") public void setImageAssetsFolder(String imageAssetsFolder) {\n    lottieDrawable.setImagesAssetsFolder(imageAssetsFolder);\n  }\n\n  public void addAnimatorUpdateListener(ValueAnimator.AnimatorUpdateListener updateListener) {\n    lottieDrawable.addAnimatorUpdateListener(updateListener);\n  }\n\n  @SuppressWarnings(\"unused\")\n  public void removeUpdateListener(ValueAnimator.AnimatorUpdateListener updateListener) {\n    lottieDrawable.removeAnimatorUpdateListener(updateListener);\n  }\n\n  public void addAnimatorListener(Animator.AnimatorListener listener) {\n    lottieDrawable.addAnimatorListener(listener);\n  }\n\n  @SuppressWarnings(\"unused\")\n  public void removeAnimatorListener(Animator.AnimatorListener listener) {\n    lottieDrawable.removeAnimatorListener(listener);\n  }\n\n  public void loop(boolean loop) {\n    lottieDrawable.loop(loop);\n  }\n\n  public boolean isAnimating() {\n    return lottieDrawable.isAnimating();\n  }\n\n  public void playAnimation() {\n    lottieDrawable.playAnimation();\n  }\n\n  public void resumeAnimation() {\n    lottieDrawable.resumeAnimation();\n  }\n\n  @SuppressWarnings(\"unused\") public void reverseAnimation() {\n    lottieDrawable.reverseAnimation();\n  }\n\n  @SuppressWarnings(\"unused\") public void resumeReverseAnimation() {\n    lottieDrawable.resumeReverseAnimation();\n  }\n\n  @SuppressWarnings(\"unused\") public void setSpeed(float speed) {\n    lottieDrawable.setSpeed(speed);\n  }\n\n  /**\n   * Use this if you can't bundle images with your app. This may be useful if you download the\n   * animations from the network or have the images saved to an SD Card. In that case, Lottie\n   * will defer the loading of the bitmap to this delegate.\n   */\n  @SuppressWarnings(\"unused\") public void setImageAssetDelegate(ImageAssetDelegate assetDelegate) {\n    lottieDrawable.setImageAssetDelegate(assetDelegate);\n  }\n\n  void setScale(float scale) {\n    lottieDrawable.setScale(scale);\n    setImageDrawable(null);\n    setImageDrawable(lottieDrawable);\n  }\n\n  public void cancelAnimation() {\n    lottieDrawable.cancelAnimation();\n  }\n\n  public void pauseAnimation() {\n    float progress = getProgress();\n    lottieDrawable.cancelAnimation();\n    setProgress(progress);\n  }\n\n  public void setProgress(@FloatRange(from = 0f, to = 1f) float progress) {\n    lottieDrawable.setProgress(progress);\n  }\n\n  @FloatRange(from = 0.0f, to = 1.0f) public float getProgress() {\n    return lottieDrawable.getProgress();\n  }\n\n  @SuppressWarnings(\"unused\") public long getDuration() {\n    return composition != null ? composition.getDuration() : 0;\n  }\n\n  private static class SavedState extends BaseSavedState {\n    String animationName;\n    float progress;\n    boolean isAnimating;\n    boolean isLooping;\n\n    SavedState(Parcelable superState) {\n      super(superState);\n    }\n\n    private SavedState(Parcel in) {\n      super(in);\n      animationName = in.readString();\n      progress = in.readFloat();\n      isAnimating = in.readInt() == 1;\n      isLooping = in.readInt() == 1;\n    }\n\n    @Override\n    public void writeToParcel(Parcel out, int flags) {\n      super.writeToParcel(out, flags);\n      out.writeString(animationName);\n      out.writeFloat(progress);\n      out.writeInt(isAnimating ? 1 : 0);\n      out.writeInt(isLooping ? 1 : 0);\n\n    }\n\n    public static final Parcelable.Creator<SavedState> CREATOR =\n        new Parcelable.Creator<SavedState>() {\n          public SavedState createFromParcel(Parcel in) {\n            return new SavedState(in);\n          }\n\n          public SavedState[] newArray(int size) {\n            return new SavedState[size];\n          }\n        };\n  }\n}"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/LottieComposition.java",
    "content": "package com.airbnb.lottie;\n\nimport android.content.Context;\nimport android.content.res.Resources;\nimport android.graphics.Rect;\nimport android.os.AsyncTask;\nimport android.support.annotation.Nullable;\nimport android.support.v4.util.LongSparseArray;\n\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport static com.airbnb.lottie.Utils.closeQuietly;\n\n/**\n * After Effects/Bodymovin composition model. This is the serialized model from which the\n * animation will be created.\n * It can be used with a {@link com.airbnb.lottie.LottieAnimationView} or\n * {@link com.airbnb.lottie.LottieDrawable}.\n */\npublic class LottieComposition {\n\n  private final Map<String, List<Layer>> precomps = new HashMap<>();\n  private final Map<String, LottieImageAsset> images = new HashMap<>();\n  private final LongSparseArray<Layer> layerMap = new LongSparseArray<>();\n  private final List<Layer> layers = new ArrayList<>();\n  private final Rect bounds;\n  private final long startFrame;\n  private final long endFrame;\n  private final int frameRate;\n  private final float dpScale;\n\n  private LottieComposition(\n      Rect bounds, long startFrame, long endFrame, int frameRate, float dpScale) {\n    this.bounds = bounds;\n    this.startFrame = startFrame;\n    this.endFrame = endFrame;\n    this.frameRate = frameRate;\n    this.dpScale = dpScale;\n  }\n\n  Layer layerModelForId(long id) {\n    return layerMap.get(id);\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public Rect getBounds() {\n    return bounds;\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public long getDuration() {\n    long frameDuration = endFrame - startFrame;\n    return (long) (frameDuration / (float) frameRate * 1000);\n  }\n\n  long getEndFrame() {\n    return endFrame;\n  }\n\n  List<Layer> getLayers() {\n    return layers;\n  }\n\n  @Nullable\n  List<Layer> getPrecomps(String id) {\n    return precomps.get(id);\n  }\n\n  @SuppressWarnings(\"unused\") boolean hasImages() {\n    return !images.isEmpty();\n  }\n\n  Map<String, LottieImageAsset> getImages() {\n    return images;\n  }\n\n  float getDurationFrames() {\n    return getDuration() * (float) frameRate / 1000f;\n  }\n\n\n  public float getDpScale() {\n    return dpScale;\n  }\n\n  @Override public String toString() {\n    final StringBuilder sb = new StringBuilder(\"LottieComposition:\\n\");\n    for (Layer layer : layers) {\n      sb.append(layer.toString(\"\\t\"));\n    }\n    return sb.toString();\n  }\n\n  public static class Factory {\n    private Factory() {\n    }\n\n    /**\n     * Loads a composition from a file stored in /assets.\n     */\n    public static Cancellable fromAssetFileName(Context context, String fileName,\n        OnCompositionLoadedListener loadedListener) {\n      InputStream stream;\n      try {\n        stream = context.getAssets().open(fileName);\n      } catch (IOException e) {\n        throw new IllegalStateException(\"Unable to find file \" + fileName, e);\n      }\n      return fromInputStream(context, stream, loadedListener);\n    }\n\n    /**\n     * Loads a composition from an arbitrary input stream.\n     * <p>\n     * ex: fromInputStream(context, new FileInputStream(filePath), (composition) -> {});\n     */\n    public static Cancellable fromInputStream(Context context, InputStream stream,\n        OnCompositionLoadedListener loadedListener) {\n      FileCompositionLoader loader =\n          new FileCompositionLoader(context.getResources(), loadedListener);\n      loader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, stream);\n      return loader;\n    }\n\n    static LottieComposition fromFileSync(Context context, String fileName) {\n      InputStream stream;\n      try {\n        stream = context.getAssets().open(fileName);\n      } catch (IOException e) {\n        throw new IllegalStateException(\"Unable to find file \" + fileName, e);\n      }\n      return fromInputStream(context.getResources(), stream);\n    }\n\n    /**\n     * Loads a composition from a raw json object. This is useful for animations loaded from the\n     * network.\n     */\n    public static Cancellable fromJson(Resources res, JSONObject json,\n        OnCompositionLoadedListener loadedListener) {\n      JsonCompositionLoader loader = new JsonCompositionLoader(res, loadedListener);\n      loader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, json);\n      return loader;\n    }\n\n    @SuppressWarnings(\"WeakerAccess\")\n    static LottieComposition fromInputStream(Resources res, InputStream stream) {\n      try {\n        // TODO: It's not correct to use available() to allocate the byte array.\n        int size = stream.available();\n        byte[] buffer = new byte[size];\n        //noinspection ResultOfMethodCallIgnored\n        stream.read(buffer);\n        String json = new String(buffer, \"UTF-8\");\n        JSONObject jsonObject = new JSONObject(json);\n        return fromJsonSync(res, jsonObject);\n      } catch (IOException e) {\n        throw new IllegalStateException(\"Unable to find file.\", e);\n      } catch (JSONException e) {\n        throw new IllegalStateException(\"Unable to load JSON.\", e);\n      } finally {\n        closeQuietly(stream);\n      }\n    }\n\n    @SuppressWarnings(\"WeakerAccess\")\n    static LottieComposition fromJsonSync(Resources res, JSONObject json) {\n      Rect bounds = null;\n      float scale = res.getDisplayMetrics().density;\n      int width = json.optInt(\"w\", -1);\n      int height = json.optInt(\"h\", -1);\n\n      if (width != -1 && height != -1) {\n        int scaledWidth = (int) (width * scale);\n        int scaledHeight = (int) (height * scale);\n        bounds = new Rect(0, 0, scaledWidth, scaledHeight);\n      }\n\n      long startFrame = json.optLong(\"ip\", 0);\n      long endFrame = json.optLong(\"op\", 0);\n      int frameRate = json.optInt(\"fr\", 0);\n      LottieComposition composition =\n          new LottieComposition(bounds, startFrame, endFrame, frameRate, scale);\n      JSONArray assetsJson = json.optJSONArray(\"assets\");\n      parseImages(assetsJson, composition);\n      parsePrecomps(assetsJson, composition);\n      parseLayers(json, composition);\n      return composition;\n    }\n\n    private static void parseLayers(JSONObject json, LottieComposition composition) {\n      JSONArray jsonLayers = json.optJSONArray(\"layers\");\n      int length = jsonLayers.length();\n      for (int i = 0; i < length; i++) {\n        Layer layer = Layer.Factory.newInstance(jsonLayers.optJSONObject(i), composition);\n        addLayer(composition.layers, composition.layerMap, layer);\n      }\n    }\n\n    private static void parsePrecomps(\n        @Nullable JSONArray assetsJson, LottieComposition composition) {\n      if (assetsJson == null) {\n        return;\n      }\n      int length = assetsJson.length();\n      for (int i = 0; i < length; i++) {\n        JSONObject assetJson = assetsJson.optJSONObject(i);\n        JSONArray layersJson = assetJson.optJSONArray(\"layers\");\n        if (layersJson == null) {\n          continue;\n        }\n        List<Layer> layers = new ArrayList<>(layersJson.length());\n        LongSparseArray<Layer> layerMap = new LongSparseArray<>();\n        for (int j = 0; j < layersJson.length(); j++) {\n          Layer layer = Layer.Factory.newInstance(layersJson.optJSONObject(j), composition);\n          layerMap.put(layer.getId(), layer);\n          layers.add(layer);\n        }\n        String id = assetJson.optString(\"id\");\n        composition.precomps.put(id, layers);\n      }\n    }\n\n    private static void parseImages(\n        @Nullable JSONArray assetsJson, LottieComposition composition) {\n      if (assetsJson == null) {\n        return;\n      }\n      int length = assetsJson.length();\n      for (int i = 0; i < length; i++) {\n        JSONObject assetJson = assetsJson.optJSONObject(i);\n        if (!assetJson.has(\"p\")) {\n          continue;\n        }\n        LottieImageAsset image = LottieImageAsset.Factory.newInstance(assetJson);\n        composition.images.put(image.getId(), image);\n      }\n    }\n\n    private static void addLayer(List<Layer> layers, LongSparseArray<Layer> layerMap, Layer layer) {\n      layers.add(layer);\n      layerMap.put(layer.getId(), layer);\n    }\n  }\n}"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java",
    "content": "package com.airbnb.lottie;\n\nimport android.animation.Animator;\nimport android.animation.ValueAnimator;\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.ColorFilter;\nimport android.graphics.Matrix;\nimport android.graphics.PixelFormat;\nimport android.graphics.drawable.Drawable;\nimport android.support.annotation.FloatRange;\nimport android.support.annotation.IntRange;\nimport android.support.annotation.NonNull;\nimport android.support.annotation.Nullable;\nimport android.view.View;\nimport android.view.animation.LinearInterpolator;\n\n/**\n * This can be used to show an lottie animation in any place that would normally take a drawable.\n * If there are masks or mattes, then you MUST call {@link #recycleBitmaps()} when you are done\n * or else you will leak bitmaps.\n * <p>\n * It is preferable to use {@link com.airbnb.lottie.LottieAnimationView} when possible because it\n * handles bitmap recycling and asynchronous loading\n * of compositions.\n */\npublic class LottieDrawable extends Drawable implements Drawable.Callback {\n  private final Matrix matrix = new Matrix();\n  private LottieComposition composition;\n  private final ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);\n  private float speed = 0.7f;\n  private float scale = 1.5f;\n  private float progress = 0f;\n\n  @Nullable private ImageAssetBitmapManager imageAssetBitmapManager;\n  @Nullable private String imageAssetsFolder;\n  @Nullable private ImageAssetDelegate imageAssetDelegate;\n  private boolean playAnimationWhenCompositionAdded;\n  private boolean reverseAnimationWhenCompositionAdded;\n  private boolean systemAnimationsAreDisabled;\n  @Nullable private CompositionLayer compositionLayer;\n  private int alpha = 255;\n\n  @SuppressWarnings(\"WeakerAccess\") public LottieDrawable() {\n    animator.setRepeatCount(0);\n    animator.setInterpolator(new LinearInterpolator());\n    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {\n      @Override public void onAnimationUpdate(ValueAnimator animation) {\n        if (systemAnimationsAreDisabled) {\n          animator.cancel();\n          setProgress(1f);\n        } else {\n          setProgress((float) animation.getAnimatedValue());\n        }\n      }\n    });\n  }\n\n  /**\n   * Returns whether or not any layers in this composition has masks.\n   */\n  @SuppressWarnings({\"unused\", \"WeakerAccess\"}) public boolean hasMasks() {\n    return compositionLayer != null && compositionLayer.hasMasks();\n  }\n\n  /**\n   * Returns whether or not any layers in this composition has a matte layer.\n   */\n  @SuppressWarnings({\"unused\", \"WeakerAccess\"}) public boolean hasMatte() {\n    return compositionLayer != null && compositionLayer.hasMatte();\n  }\n\n  /**\n   * If you use image assets, you must explicitly specify the folder in assets/ in which they are\n   * located because bodymovin uses the name filenames across all compositions (img_#).\n   * Do NOT rename the images themselves.\n   *\n   * If your images are located in src/main/assets/airbnb_loader/ then call\n   * `setImageAssetsFolder(\"airbnb_loader/\");`.\n   *\n   *\n   * If you use LottieDrawable directly, you MUST call {@link #recycleBitmaps()} when you\n   * are done. Calling {@link #recycleBitmaps()} doesn't have to be final and {@link LottieDrawable}\n   * will recreate the bitmaps if needed but they will leak if you don't recycle them.\n   */\n  @SuppressWarnings(\"WeakerAccess\") public void setImagesAssetsFolder(@Nullable String imageAssetsFolder) {\n    this.imageAssetsFolder = imageAssetsFolder;\n  }\n\n  /**\n   * If you have image assets and use {@link LottieDrawable} directly, you must call this yourself.\n   *\n   * Calling recycleBitmaps() doesn't have to be final and {@link LottieDrawable}\n   * will recreate the bitmaps if needed but they will leak if you don't recycle them.\n   *\n   */\n  @SuppressWarnings(\"WeakerAccess\") public void recycleBitmaps() {\n    if (imageAssetBitmapManager != null) {\n      imageAssetBitmapManager.recycleBitmaps();\n    }\n  }\n\n  /**\n   * @return True if the composition is different from the previously set composition, false otherwise.\n   */\n  @SuppressWarnings(\"WeakerAccess\") public boolean setComposition(LottieComposition composition) {\n    if (getCallback() == null) {\n      throw new IllegalStateException(\n          \"You or your view must set a Drawable.Callback before setting the composition. This \" +\n              \"gets done automatically when added to an ImageView. \" +\n              \"Either call ImageView.setImageDrawable() before setComposition() or call \" +\n              \"setCallback(yourView.getCallback()) first.\");\n    }\n\n    if (this.composition == composition) {\n      return false;\n    }\n\n    clearComposition();\n    this.composition = composition;\n    setSpeed(speed);\n    setScale(1f);\n    updateBounds();\n    compositionLayer = new CompositionLayer(\n        this, Layer.Factory.newInstance(composition), composition.getLayers(), composition);\n\n    setProgress(progress);\n    if (playAnimationWhenCompositionAdded) {\n      playAnimationWhenCompositionAdded = false;\n      playAnimation();\n    }\n    if (reverseAnimationWhenCompositionAdded) {\n      reverseAnimationWhenCompositionAdded = false;\n      reverseAnimation();\n    }\n\n    return true;\n  }\n\n  private void clearComposition() {\n    recycleBitmaps();\n    compositionLayer = null;\n    imageAssetBitmapManager = null;\n    invalidateSelf();\n  }\n\n  @Override public void invalidateSelf() {\n    final Callback callback = getCallback();\n    if (callback != null) {\n      callback.invalidateDrawable(this);\n    }\n  }\n\n  @Override public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {\n    this.alpha = alpha;\n  }\n\n  @Override public int getAlpha() {\n    return alpha;\n  }\n\n  @Override public void setColorFilter(@Nullable ColorFilter colorFilter) {\n    // Do nothing.\n  }\n\n  @Override public int getOpacity() {\n    return PixelFormat.TRANSLUCENT;\n  }\n\n  @Override public void draw(@NonNull Canvas canvas) {\n    if (compositionLayer == null) {\n      return;\n    }\n    matrix.reset();\n    matrix.preScale(scale, scale);\n    compositionLayer.draw(canvas, matrix, alpha);\n  }\n\n  void systemAnimationsAreDisabled() {\n    systemAnimationsAreDisabled = true;\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public void loop(boolean loop) {\n    animator.setRepeatCount(loop ? ValueAnimator.INFINITE : 0);\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public boolean isLooping() {\n    return animator.getRepeatCount() == ValueAnimator.INFINITE;\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public boolean isAnimating() {\n    return animator.isRunning();\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public void playAnimation() {\n    playAnimation(false);\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public void resumeAnimation() {\n    playAnimation(true);\n  }\n\n  private void playAnimation(boolean setStartTime) {\n    if (compositionLayer == null) {\n      playAnimationWhenCompositionAdded = true;\n      reverseAnimationWhenCompositionAdded = false;\n      return;\n    }\n    if (setStartTime) {\n      animator.setCurrentPlayTime((long) (progress * animator.getDuration()));\n    }\n    animator.start();\n  }\n\n  @SuppressWarnings({\"unused\", \"WeakerAccess\"}) public void resumeReverseAnimation() {\n    reverseAnimation(true);\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public void reverseAnimation() {\n    reverseAnimation(false);\n  }\n\n  private void reverseAnimation(boolean setStartTime) {\n    if (compositionLayer == null) {\n      playAnimationWhenCompositionAdded = false;\n      reverseAnimationWhenCompositionAdded = true;\n      return;\n    }\n    if (setStartTime) {\n      animator.setCurrentPlayTime((long) (progress * animator.getDuration()));\n    }\n    animator.reverse();\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public void setSpeed(float speed) {\n    this.speed = speed;\n    if (speed < 0) {\n      animator.setFloatValues(1f, 0f);\n    } else {\n      animator.setFloatValues(0f, 1f);\n    }\n\n    if (composition != null) {\n      animator.setDuration((long) (composition.getDuration() / Math.abs(speed)));\n    }\n  }\n\n  public void setProgress(@FloatRange(from = 0f, to = 1f) float progress) {\n    this.progress = progress;\n    if (compositionLayer != null) {\n      compositionLayer.setProgress(progress);\n    }\n  }\n\n  public float getProgress() {\n    return progress;\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public void setScale(float scale) {\n    this.scale = scale;\n    updateBounds();\n  }\n\n  /**\n   * Use this if you can't bundle images with your app. This may be useful if you download the\n   * animations from the network or have the images saved to an SD Card. In that case, Lottie\n   * will defer the loading of the bitmap to this delegate.\n   */\n  @SuppressWarnings({\"unused\", \"WeakerAccess\"}) public void setImageAssetDelegate(\n      @SuppressWarnings(\"NullableProblems\") ImageAssetDelegate assetDelegate) {\n    this.imageAssetDelegate = assetDelegate;\n    if (imageAssetBitmapManager != null) {\n      imageAssetBitmapManager.setAssetDelegate(assetDelegate);\n    }\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public float getScale() {\n    return scale;\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public LottieComposition getComposition() {\n    return composition;\n  }\n\n  private void updateBounds() {\n    if (composition == null) {\n      return;\n    }\n    setBounds(0, 0, (int) (composition.getBounds().width() * scale),\n        (int) (composition.getBounds().height() * scale));\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public void cancelAnimation() {\n    playAnimationWhenCompositionAdded = false;\n    reverseAnimationWhenCompositionAdded = false;\n    animator.cancel();\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public void addAnimatorUpdateListener(ValueAnimator.AnimatorUpdateListener updateListener) {\n    animator.addUpdateListener(updateListener);\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public void removeAnimatorUpdateListener(ValueAnimator.AnimatorUpdateListener updateListener) {\n    animator.removeUpdateListener(updateListener);\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public void addAnimatorListener(Animator.AnimatorListener listener) {\n    animator.addListener(listener);\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public void removeAnimatorListener(Animator.AnimatorListener listener) {\n    animator.removeListener(listener);\n  }\n\n  @Override public int getIntrinsicWidth() {\n    return composition == null ? -1 : (int) (composition.getBounds().width() * scale);\n  }\n\n  @Override public int getIntrinsicHeight() {\n    return composition == null ? -1 : (int) (composition.getBounds().height() * scale);\n  }\n\n  Bitmap getImageAsset(String id) {\n    return getImageAssetBitmapManager().bitmapForId(id);\n  }\n\n  private ImageAssetBitmapManager getImageAssetBitmapManager() {\n    if (imageAssetBitmapManager != null && !imageAssetBitmapManager.hasSameContext(getContext())) {\n      imageAssetBitmapManager.recycleBitmaps();\n      imageAssetBitmapManager = null;\n    }\n\n    if (imageAssetBitmapManager == null) {\n      imageAssetBitmapManager = new ImageAssetBitmapManager(getCallback(),\n          imageAssetsFolder, imageAssetDelegate, composition.getImages());\n    }\n\n    return imageAssetBitmapManager;\n  }\n\n  private @Nullable Context getContext() {\n    Callback callback = getCallback();\n    if (callback == null) {\n      return null;\n    }\n\n    if (callback instanceof View) {\n      return ((View) callback).getContext();\n    }\n    return null;\n  }\n\n  /**\n   * These Drawable.Callback methods proxy the calls so that this is the drawable that is\n   * actually invalidated, not a child one which will not pass the view's validateDrawable check.\n   */\n  @Override public void invalidateDrawable(@NonNull Drawable who) {\n    Callback callback = getCallback();\n    if (callback == null) {\n      return;\n    }\n    callback.invalidateDrawable(this);\n  }\n\n  @Override public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {\n    Callback callback = getCallback();\n    if (callback == null) {\n      return;\n    }\n    callback.scheduleDrawable(this, what, when);\n  }\n\n  @Override public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {\n    Callback callback = getCallback();\n    if (callback == null) {\n      return;\n    }\n    callback.unscheduleDrawable(this, what);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/LottieImageAsset.java",
    "content": "package com.airbnb.lottie;\n\nimport org.json.JSONObject;\n\n/**\n * Data class describing an image asset exported by bodymovin.\n */\n@SuppressWarnings(\"WeakerAccess\")\npublic class LottieImageAsset {\n  private final int width;\n  private final int height;\n  private final String id;\n  private final String fileName;\n\n  private LottieImageAsset(int width, int height, String id, String fileName) {\n    this.width = width;\n    this.height = height;\n    this.id = id;\n    this.fileName = fileName;\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    static LottieImageAsset newInstance(JSONObject imageJson) {\n      return new LottieImageAsset(imageJson.optInt(\"w\"), imageJson.optInt(\"h\"), imageJson.optString(\"id\"),\n          imageJson.optString(\"p\"));\n    }\n  }\n\n  @SuppressWarnings(\"WeakerAccess\") public int getWidth() {\n    return width;\n  }\n\n  @SuppressWarnings(\"WeakerAccess\")public int getHeight() {\n    return height;\n  }\n\n  public String getId() {\n    return id;\n  }\n\n  public String getFileName() {\n    return fileName;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/Mask.java",
    "content": "package com.airbnb.lottie;\n\nimport org.json.JSONObject;\n\nclass Mask {\n  enum MaskMode {\n    MaskModeAdd,\n    MaskModeSubtract,\n    MaskModeIntersect,\n    MaskModeUnknown\n  }\n\n  private final MaskMode maskMode;\n  private final AnimatableShapeValue maskPath;\n\n  private Mask(MaskMode maskMode, AnimatableShapeValue maskPath) {\n    this.maskMode = maskMode;\n    this.maskPath = maskPath;\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    static Mask newMask(JSONObject json, LottieComposition composition) {\n      MaskMode maskMode;\n      switch (json.optString(\"mode\")) {\n        case \"a\":\n          maskMode = MaskMode.MaskModeAdd;\n          break;\n        case \"s\":\n          maskMode = MaskMode.MaskModeSubtract;\n          break;\n        case \"i\":\n          maskMode = MaskMode.MaskModeIntersect;\n          break;\n        default:\n          maskMode = MaskMode.MaskModeUnknown;\n      }\n\n      AnimatableShapeValue maskPath = AnimatableShapeValue.Factory.newInstance(\n          json.optJSONObject(\"pt\"), composition);\n      // TODO: use this\n      // JSONObject opacityJson = json.optJSONObject(\"o\");\n      // if (opacityJson != null) {\n      //   AnimatableIntegerValue opacity =\n      //       new AnimatableIntegerValue(opacityJson, composition, false, true);\n      // }\n\n      return new Mask(maskMode, maskPath);\n    }\n  }\n\n  @SuppressWarnings(\"unused\") MaskMode getMaskMode() {\n    return maskMode;\n  }\n\n  AnimatableShapeValue getMaskPath() {\n    return maskPath;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/MaskKeyframeAnimation.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Path;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nclass MaskKeyframeAnimation {\n  private final List<BaseKeyframeAnimation<?, Path>> maskAnimations;\n  private final List<Mask> masks;\n\n  MaskKeyframeAnimation(List<Mask> masks) {\n    this.masks = masks;\n    this.maskAnimations = new ArrayList<>(masks.size());\n    for (int i = 0; i < masks.size(); i++) {\n      this.maskAnimations.add(masks.get(i).getMaskPath().createAnimation());\n    }\n  }\n\n  List<Mask> getMasks() {\n    return masks;\n  }\n\n  List<BaseKeyframeAnimation<?, Path>> getMaskAnimations() {\n    return maskAnimations;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/MergePaths.java",
    "content": "package com.airbnb.lottie;\n\nimport org.json.JSONObject;\n\n\npublic class MergePaths {\n\n  enum MergePathsMode {\n    Merge,\n    Add,\n    Subtract,\n    Intersect,\n    ExcludeIntersections;\n\n    private static MergePathsMode forId(int id) {\n      switch (id) {\n        case 1:\n          return Merge;\n        case 2:\n          return Add;\n        case 3:\n          return Subtract;\n        case 4:\n          return Intersect;\n        case 5:\n          return ExcludeIntersections;\n        default:\n          return Merge;\n      }\n    }\n  }\n\n  private final MergePathsMode mode;\n\n  private MergePaths(MergePathsMode mode) {\n    this.mode = mode;\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    static MergePaths newInstance(JSONObject json) {\n      return new MergePaths(MergePathsMode.forId(json.optInt(\"mm\", 1)));\n    }\n  }\n\n  MergePathsMode getMode() {\n    return mode;\n  }\n\n  @Override\n  public String toString() {\n    return \"MergePaths{\" + \"mode=\" +  mode + '}';\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/MergePathsContent.java",
    "content": "package com.airbnb.lottie;\n\nimport android.annotation.TargetApi;\nimport android.graphics.Path;\nimport android.os.Build;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nclass MergePathsContent implements PathContent {\n  private final Path firstPath = new Path();\n  private final Path remainderPath = new Path();\n  private final Path path = new Path();\n\n  private final List<PathContent> pathContents = new ArrayList<>();\n  private final MergePaths mergePaths;\n\n  MergePathsContent(MergePaths mergePaths) {\n    this.mergePaths = mergePaths;\n  }\n\n  void addContentIfNeeded(Content content) {\n    if (content instanceof PathContent) {\n      pathContents.add((PathContent) content);\n    }\n  }\n\n  @Override public void setContents(List<Content> contentsBefore, List<Content> contentsAfter) {\n    for (int i = 0; i < pathContents.size(); i++) {\n      pathContents.get(i).setContents(contentsBefore, contentsAfter);\n    }\n  }\n\n  @Override public Path getPath() {\n    path.reset();\n\n    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {\n      mergePaths();\n    } else {\n      supportMergePaths();\n    }\n\n\n    return path;\n  }\n\n  private void supportMergePaths() {\n    for (int i = 0; i < pathContents.size(); i++) {\n      path.addPath(pathContents.get(i).getPath());\n    }\n  }\n\n  @TargetApi(Build.VERSION_CODES.KITKAT)\n  private void mergePaths() {\n\n    switch (mergePaths.getMode()) {\n      case Merge:\n        supportMergePaths();\n        break;\n      case Add:\n        opFirstPathWithRest(Path.Op.UNION);\n        break;\n      case Subtract:\n        opFirstPathWithRest(Path.Op.REVERSE_DIFFERENCE);\n        break;\n      case Intersect:\n        opFirstPathWithRest(Path.Op.INTERSECT);\n        break;\n      case ExcludeIntersections:\n        opFirstPathWithRest(Path.Op.XOR);\n        break;\n    }\n  }\n\n  @TargetApi(Build.VERSION_CODES.KITKAT)\n  private void opFirstPathWithRest(Path.Op op) {\n    remainderPath.reset();\n    firstPath.reset();\n\n    for (int i = pathContents.size() - 1; i >= 1; i--) {\n      PathContent content = pathContents.get(i);\n\n      if (content instanceof ContentGroup) {\n        List<PathContent> pathList = ((ContentGroup) content).getPathList();\n        for (int j = pathList.size() - 1; j >= 0; j--) {\n          Path path = pathList.get(j).getPath();\n          path.transform(((ContentGroup) content).getTransformationMatrix());\n          this.remainderPath.addPath(path);\n        }\n      } else {\n        remainderPath.addPath(content.getPath());\n      }\n    }\n\n    PathContent lastContent = pathContents.get(0);\n    if (lastContent instanceof ContentGroup) {\n      List<PathContent> pathList = ((ContentGroup) lastContent).getPathList();\n      for (int j = 0; j < pathList.size(); j++) {\n        Path path = pathList.get(j).getPath();\n        path.transform(((ContentGroup) lastContent).getTransformationMatrix());\n        this.firstPath.addPath(path);\n      }\n    } else {\n      firstPath.set(lastContent.getPath());\n    }\n\n    path.op(firstPath, remainderPath, op);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/MiscUtils.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Path;\nimport android.graphics.PointF;\nimport android.support.annotation.FloatRange;\n\nclass MiscUtils {\n  static PointF addPoints(PointF p1, PointF p2) {\n    return new PointF(p1.x + p2.x, p1.y + p2.y);\n  }\n\n  static void getPathFromData(ShapeData shapeData, Path outPath) {\n    outPath.reset();\n    PointF initialPoint = shapeData.getInitialPoint();\n    outPath.moveTo(initialPoint.x, initialPoint.y);\n    for (int i = 0; i < shapeData.getCurves().size(); i++) {\n      CubicCurveData curveData = shapeData.getCurves().get(i);\n      outPath.cubicTo(curveData.getControlPoint1().x, curveData.getControlPoint1().y,\n          curveData.getControlPoint2().x, curveData.getControlPoint2().y,\n          curveData.getVertex().x, curveData.getVertex().y);\n    }\n    if (shapeData.isClosed()) {\n      outPath.close();\n    }\n  }\n\n  static float lerp(float a, float b, @FloatRange(from = 0f, to = 1f) float percentage) {\n    return a + percentage * (b - a);\n  }\n\n  static int lerp(int a, int b, @FloatRange(from = 0f, to = 1f) float percentage) {\n    return (int) (a + percentage * (b - a));\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ModifierContent.java",
    "content": "package com.airbnb.lottie;\n\ninterface ModifierContent {\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/NullLayer.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Canvas;\nimport android.graphics.Matrix;\n\nclass NullLayer extends BaseLayer {\n  NullLayer(LottieDrawable lottieDrawable, Layer layerModel) {\n    super(lottieDrawable, layerModel);\n  }\n\n  @Override void drawLayer(Canvas canvas, Matrix parentMatrix, int parentAlpha) {\n    // Do nothing.\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/OnCompositionLoadedListener.java",
    "content": "package com.airbnb.lottie;\n\npublic interface OnCompositionLoadedListener {\n  void onCompositionLoaded(LottieComposition composition);\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/PathContent.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Path;\n\ninterface PathContent extends Content {\n  Path getPath();\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/PathKeyframe.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Path;\nimport android.graphics.PointF;\nimport android.support.annotation.Nullable;\nimport android.view.animation.Interpolator;\n\nimport org.json.JSONArray;\nimport org.json.JSONObject;\n\nclass PathKeyframe extends Keyframe<PointF> {\n  @Nullable private Path path;\n\n  private PathKeyframe(LottieComposition composition, @Nullable PointF startValue,\n      @Nullable PointF endValue, @Nullable Interpolator interpolator, float startFrame,\n      @Nullable Float endFrame) {\n    super(composition, startValue, endValue, interpolator, startFrame, endFrame);\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    static PathKeyframe newInstance(JSONObject json, LottieComposition composition,\n        AnimatableValue.Factory<PointF> valueFactory) {\n      Keyframe<PointF> keyframe = Keyframe.Factory.newInstance(json, composition,\n          composition.getDpScale(), valueFactory);\n      PointF cp1 = null;\n      PointF cp2 = null;\n      JSONArray tiJson = json.optJSONArray(\"ti\");\n      JSONArray toJson = json.optJSONArray(\"to\");\n      if (tiJson != null && toJson != null) {\n        cp1 = JsonUtils.pointFromJsonArray(toJson, composition.getDpScale());\n        cp2 = JsonUtils.pointFromJsonArray(tiJson, composition.getDpScale());\n      }\n\n      PathKeyframe pathKeyframe = new PathKeyframe(composition, keyframe.startValue,\n          keyframe.endValue, keyframe.interpolator, keyframe.startFrame, keyframe.endFrame);\n\n      //noinspection ConstantConditions\n      if (keyframe.endValue != null && !keyframe.startValue.equals(keyframe.endValue)) {\n        pathKeyframe.path = Utils.createPath(keyframe.startValue, keyframe.endValue, cp1, cp2);\n      }\n      return pathKeyframe;\n    }\n  }\n\n  /** This will be null if the startValue and endValue are the same. */\n  @Nullable Path getPath() {\n    return path;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/PathKeyframeAnimation.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Path;\nimport android.graphics.PathMeasure;\nimport android.graphics.PointF;\n\nimport java.util.List;\n\nclass PathKeyframeAnimation extends KeyframeAnimation<PointF> {\n  private final PointF point = new PointF();\n  private final float[] pos = new float[2];\n  private PathKeyframe pathMeasureKeyframe;\n  private PathMeasure pathMeasure;\n\n  PathKeyframeAnimation(List<? extends Keyframe<PointF>> keyframes) {\n    super(keyframes);\n  }\n\n  @Override public PointF getValue(Keyframe<PointF> keyframe, float keyframeProgress) {\n    PathKeyframe pathKeyframe = (PathKeyframe) keyframe;\n    Path path = pathKeyframe.getPath();\n    if (path == null) {\n      return keyframe.startValue;\n    }\n\n    if (pathMeasureKeyframe != pathKeyframe) {\n      pathMeasure = new PathMeasure(path, false);\n      pathMeasureKeyframe = pathKeyframe;\n    }\n\n    pathMeasure.getPosTan(keyframeProgress * pathMeasure.getLength(), pos, null);\n    point.set(pos[0], pos[1]);\n    return point;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/PointFFactory.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.PointF;\n\nimport org.json.JSONArray;\nimport org.json.JSONObject;\n\nclass PointFFactory implements AnimatableValue.Factory<PointF> {\n  static final PointFFactory INSTANCE = new PointFFactory();\n\n  private PointFFactory() {\n  }\n\n  @Override public PointF valueFromObject(Object object, float scale) {\n    if (object instanceof JSONArray) {\n      return JsonUtils.pointFromJsonArray((JSONArray) object, scale);\n    } else if (object instanceof JSONObject) {\n      return JsonUtils.pointFromJsonObject((JSONObject) object, scale);\n    } else {\n      throw new IllegalArgumentException(\"Unable to parse point from \" + object);\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/PointKeyframeAnimation.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.PointF;\n\nimport java.util.List;\n\nclass PointKeyframeAnimation extends KeyframeAnimation<PointF> {\n  private final PointF point = new PointF();\n\n  PointKeyframeAnimation(List<Keyframe<PointF>> keyframes) {\n    super(keyframes);\n  }\n\n  @Override public PointF getValue(Keyframe<PointF> keyframe, float keyframeProgress) {\n    if (keyframe.startValue == null || keyframe.endValue == null) {\n      throw new IllegalStateException(\"Missing values for keyframe.\");\n    }\n\n    PointF startPoint = keyframe.startValue;\n    PointF endPoint = keyframe.endValue;\n\n    point.set(startPoint.x + keyframeProgress * (endPoint.x - startPoint.x),\n        startPoint.y + keyframeProgress * (endPoint.y - startPoint.y));\n    return point;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/PolystarContent.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Path;\nimport android.graphics.PointF;\nimport android.support.annotation.Nullable;\n\nimport java.util.List;\n\nclass PolystarContent implements PathContent, BaseKeyframeAnimation.AnimationListener {\n  /**\n   * This was empirically derived by creating polystars, converting them to\n   * curves, and calculating a scale factor.\n   * It works best for polygons and stars with 3 points and needs more\n   * work otherwise.\n   */\n  private static final float POLYSTAR_MAGIC_NUMBER = .47829f;\n  private static final float POLYGON_MAGIC_NUMBER = .25f;\n  private final Path path = new Path();\n\n  private final LottieDrawable lottieDrawable;\n  private final PolystarShape.Type type;\n  private final BaseKeyframeAnimation<?, Float> pointsAnimation;\n  private final BaseKeyframeAnimation<?, PointF> positionAnimation;\n  private final BaseKeyframeAnimation<?, Float> rotationAnimation;\n  @Nullable private final BaseKeyframeAnimation<?, Float> innerRadiusAnimation;\n  private final BaseKeyframeAnimation<?, Float> outerRadiusAnimation;\n  @Nullable private final BaseKeyframeAnimation<?, Float> innerRoundednessAnimation;\n  private final BaseKeyframeAnimation<?, Float> outerRoundednessAnimation;\n\n  @Nullable private TrimPathContent trimPath;\n  private boolean isPathValid;\n\n  PolystarContent(LottieDrawable lottieDrawable, BaseLayer layer, PolystarShape polystarShape) {\n    this.lottieDrawable = lottieDrawable;\n\n    type = polystarShape.getType();\n    pointsAnimation = polystarShape.getPoints().createAnimation();\n    positionAnimation = polystarShape.getPosition().createAnimation();\n    rotationAnimation = polystarShape.getRotation().createAnimation();\n    outerRadiusAnimation = polystarShape.getOuterRadius().createAnimation();\n    outerRoundednessAnimation = polystarShape.getOuterRoundedness().createAnimation();\n    if (type == PolystarShape.Type.Star) {\n      innerRadiusAnimation = polystarShape.getInnerRadius().createAnimation();\n      innerRoundednessAnimation = polystarShape.getInnerRoundedness().createAnimation();\n    } else {\n      innerRadiusAnimation = null;\n      innerRoundednessAnimation = null;\n    }\n\n    layer.addAnimation(pointsAnimation);\n    layer.addAnimation(positionAnimation);\n    layer.addAnimation(rotationAnimation);\n    layer.addAnimation(outerRadiusAnimation);\n    layer.addAnimation(outerRoundednessAnimation);\n    if (type == PolystarShape.Type.Star) {\n      layer.addAnimation(innerRadiusAnimation);\n      layer.addAnimation(innerRoundednessAnimation);\n    }\n\n    pointsAnimation.addUpdateListener(this);\n    positionAnimation.addUpdateListener(this);\n    rotationAnimation.addUpdateListener(this);\n    outerRadiusAnimation.addUpdateListener(this);\n    outerRoundednessAnimation.addUpdateListener(this);\n    if (type == PolystarShape.Type.Star) {\n      outerRadiusAnimation.addUpdateListener(this);\n      outerRoundednessAnimation.addUpdateListener(this);\n    }\n  }\n\n  @Override public void onValueChanged() {\n    invalidate();\n  }\n\n  private void invalidate() {\n    isPathValid = false;\n    lottieDrawable.invalidateSelf();\n  }\n\n  @Override public void setContents(List<Content> contentsBefore, List<Content> contentsAfter) {\n    for (int i = 0; i < contentsBefore.size(); i++) {\n      Content content = contentsBefore.get(i);\n      if (content instanceof TrimPathContent) {\n        trimPath = (TrimPathContent) content;\n        trimPath.addListener(this);\n      }\n    }\n  }\n\n  @Override public Path getPath() {\n    if (isPathValid) {\n      return path;\n    }\n\n    path.reset();\n\n    switch (type) {\n      case Star:\n        createStarPath();\n        break;\n      case Polygon:\n        createPolygonPath();\n        break;\n    }\n\n    path.close();\n\n    Utils.applyTrimPathIfNeeded(path, trimPath);\n\n    isPathValid = true;\n    return path;\n  }\n\n  private void createStarPath() {\n    float points = pointsAnimation.getValue();\n    double currentAngle = rotationAnimation == null ? 0f : rotationAnimation.getValue();\n    // Start at +y instead of +x\n    currentAngle -= 90;\n    // convert to radians\n    currentAngle = Math.toRadians(currentAngle);\n    // adjust current angle for partial points\n    float anglePerPoint = (float) (2 * Math.PI / points);\n    float halfAnglePerPoint = anglePerPoint / 2.0f;\n    float partialPointAmount = points - (int) points;\n    if (partialPointAmount != 0) {\n      currentAngle += halfAnglePerPoint * (1f - partialPointAmount);\n    }\n\n    float outerRadius = outerRadiusAnimation.getValue();\n    //noinspection ConstantConditions\n    float innerRadius = innerRadiusAnimation.getValue();\n\n    float innerRoundedness = 0f;\n    if (innerRoundednessAnimation != null) {\n      innerRoundedness = innerRoundednessAnimation.getValue() / 100f;\n    }\n    float outerRoundedness = 0f;\n    if (outerRoundednessAnimation != null) {\n      outerRoundedness = outerRoundednessAnimation.getValue() / 100f;\n    }\n\n    float x;\n    float y;\n    float previousX;\n    float previousY;\n    float partialPointRadius = 0;\n    if (partialPointAmount != 0) {\n      partialPointRadius = innerRadius + partialPointAmount * (outerRadius - innerRadius);\n      x = (float) (partialPointRadius * Math.cos(currentAngle));\n      y = (float) (partialPointRadius * Math.sin(currentAngle));\n      path.moveTo(x, y);\n      currentAngle += anglePerPoint * partialPointAmount / 2f;\n    } else {\n      x = (float) (outerRadius * Math.cos(currentAngle));\n      y = (float) (outerRadius * Math.sin(currentAngle));\n      path.moveTo(x, y);\n      currentAngle += halfAnglePerPoint;\n    }\n\n    // True means the line will go to outer radius. False means inner radius.\n    boolean longSegment = false;\n    double numPoints = Math.ceil(points) * 2;\n    for (int i = 0; i < numPoints; i++) {\n      float radius = longSegment ? outerRadius : innerRadius;\n      float dTheta = halfAnglePerPoint;\n      if (partialPointRadius != 0 && i == numPoints - 2) {\n        dTheta = anglePerPoint * partialPointAmount / 2f;\n      }\n      if (partialPointRadius != 0 && i == numPoints - 1) {\n        radius = partialPointRadius;\n      }\n      previousX = x;\n      previousY = y;\n      x = (float) (radius * Math.cos(currentAngle));\n      y = (float) (radius * Math.sin(currentAngle));\n\n      if (innerRoundedness == 0 && outerRoundedness == 0) {\n        path.lineTo(x, y);\n      } else {\n        float cp1Theta = (float) (Math.atan2(previousY, previousX) - Math.PI / 2f);\n        float cp1Dx = (float) Math.cos(cp1Theta);\n        float cp1Dy = (float) Math.sin(cp1Theta);\n\n        float cp2Theta = (float) (Math.atan2(y, x) - Math.PI / 2f);\n        float cp2Dx = (float) Math.cos(cp2Theta);\n        float cp2Dy = (float) Math.sin(cp2Theta);\n\n        float cp1Roundedness = longSegment ? innerRoundedness : outerRoundedness;\n        float cp2Roundedness = longSegment ? outerRoundedness : innerRoundedness;\n        float cp1Radius = longSegment ? innerRadius : outerRadius;\n        float cp2Radius = longSegment ? outerRadius : innerRadius;\n\n        float cp1x = cp1Radius * cp1Roundedness * POLYSTAR_MAGIC_NUMBER * cp1Dx;\n        float cp1y = cp1Radius * cp1Roundedness * POLYSTAR_MAGIC_NUMBER * cp1Dy;\n        float cp2x = cp2Radius * cp2Roundedness * POLYSTAR_MAGIC_NUMBER * cp2Dx;\n        float cp2y = cp2Radius * cp2Roundedness * POLYSTAR_MAGIC_NUMBER * cp2Dy;\n        if (partialPointAmount != 0) {\n          if (i == 0) {\n            cp1x *= partialPointAmount;\n            cp1y *= partialPointAmount;\n          } else if (i == numPoints - 1) {\n            cp2x *= partialPointAmount;\n            cp2y *= partialPointAmount;\n          }\n        }\n\n        path.cubicTo(previousX - cp1x,previousY - cp1y, x + cp2x, y + cp2y, x, y);\n      }\n\n      currentAngle += dTheta;\n      longSegment = !longSegment;\n    }\n\n\n    PointF position = positionAnimation.getValue();\n    path.offset(position.x, position.y);\n    path.close();\n  }\n\n  private void createPolygonPath() {\n    int points = (int) Math.floor(pointsAnimation.getValue());\n    double currentAngle = rotationAnimation == null ? 0f : rotationAnimation.getValue();\n    // Start at +y instead of +x\n    currentAngle -= 90;\n    // convert to radians\n    currentAngle = Math.toRadians(currentAngle);\n    // adjust current angle for partial points\n    float anglePerPoint = (float) (2 * Math.PI / points);\n\n    float roundedness = outerRoundednessAnimation.getValue() / 100f;\n    float radius = outerRadiusAnimation.getValue();\n    float x;\n    float y;\n    float previousX;\n    float previousY;\n    x = (float) (radius * Math.cos(currentAngle));\n    y = (float) (radius * Math.sin(currentAngle));\n    path.moveTo(x, y);\n    currentAngle += anglePerPoint;\n\n    double numPoints = Math.ceil(points);\n    for (int i = 0; i < numPoints; i++) {\n      previousX = x;\n      previousY = y;\n      x = (float) (radius * Math.cos(currentAngle));\n      y = (float) (radius * Math.sin(currentAngle));\n\n      if (roundedness != 0) {\n        float cp1Theta = (float) (Math.atan2(previousY, previousX) - Math.PI / 2f);\n        float cp1Dx = (float) Math.cos(cp1Theta);\n        float cp1Dy = (float) Math.sin(cp1Theta);\n\n        float cp2Theta = (float) (Math.atan2(y, x) - Math.PI / 2f);\n        float cp2Dx = (float) Math.cos(cp2Theta);\n        float cp2Dy = (float) Math.sin(cp2Theta);\n\n        float cp1x = radius * roundedness * POLYGON_MAGIC_NUMBER * cp1Dx;\n        float cp1y = radius * roundedness * POLYGON_MAGIC_NUMBER * cp1Dy;\n        float cp2x = radius * roundedness * POLYGON_MAGIC_NUMBER * cp2Dx;\n        float cp2y = radius * roundedness * POLYGON_MAGIC_NUMBER * cp2Dy;\n        path.cubicTo(previousX - cp1x,previousY - cp1y, x + cp2x, y + cp2y, x, y);\n      } else {\n        path.lineTo(x, y);\n      }\n\n      currentAngle += anglePerPoint;\n    }\n\n    PointF position = positionAnimation.getValue();\n    path.offset(position.x, position.y);\n    path.close();\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/PolystarShape.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.PointF;\n\nimport org.json.JSONObject;\n\nclass PolystarShape {\n  enum Type {\n    Star(1),\n    Polygon(2);\n\n    private final int value;\n\n    Type(int value) {\n      this.value = value;\n    }\n\n    static Type forValue(int value) {\n      for (Type type : Type.values()) {\n        if (type.value == value) {\n          return type;\n        }\n      }\n      return null;\n    }\n  }\n\n  private final Type type;\n  private final AnimatableFloatValue points;\n  private final AnimatableValue<PointF> position;\n  private final AnimatableFloatValue rotation;\n  private final AnimatableFloatValue innerRadius;\n  private final AnimatableFloatValue outerRadius;\n  private final AnimatableFloatValue innerRoundedness;\n  private final AnimatableFloatValue outerRoundedness;\n\n  private PolystarShape(Type type, AnimatableFloatValue points, AnimatableValue<PointF> position,\n      AnimatableFloatValue rotation, AnimatableFloatValue innerRadius,\n      AnimatableFloatValue outerRadius, AnimatableFloatValue innerRoundedness,\n      AnimatableFloatValue outerRoundedness) {\n    this.type = type;\n    this.points = points;\n    this.position = position;\n    this.rotation = rotation;\n    this.innerRadius = innerRadius;\n    this.outerRadius = outerRadius;\n    this.innerRoundedness = innerRoundedness;\n    this.outerRoundedness = outerRoundedness;\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    static PolystarShape newInstance(JSONObject json, LottieComposition composition) {\n      Type type = Type.forValue(json.optInt(\"sy\"));\n      AnimatableFloatValue points =\n          AnimatableFloatValue.Factory.newInstance(json.optJSONObject(\"pt\"), composition, false);\n      AnimatableValue<PointF> position = AnimatablePathValue.createAnimatablePathOrSplitDimensionPath(\n          json.optJSONObject(\"p\"), composition);\n      AnimatableFloatValue rotation =\n          AnimatableFloatValue.Factory.newInstance(json.optJSONObject(\"r\"), composition, false);\n      AnimatableFloatValue outerRadius =\n          AnimatableFloatValue.Factory.newInstance(json.optJSONObject(\"or\"), composition);\n      AnimatableFloatValue outerRoundedness =\n          AnimatableFloatValue.Factory.newInstance(json.optJSONObject(\"os\"), composition, false);\n      AnimatableFloatValue innerRadius;\n      AnimatableFloatValue innerRoundedness;\n\n      if (type == Type.Star) {\n        innerRadius =\n            AnimatableFloatValue.Factory.newInstance(json.optJSONObject(\"ir\"), composition);\n        innerRoundedness =\n            AnimatableFloatValue.Factory.newInstance(json.optJSONObject(\"is\"), composition, false);\n      } else {\n        innerRadius = null;\n        innerRoundedness = null;\n      }\n      return new PolystarShape(type, points, position, rotation, innerRadius, outerRadius,\n          innerRoundedness, outerRoundedness);\n    }\n  }\n\n  Type getType() {\n    return type;\n  }\n\n  AnimatableFloatValue getPoints() {\n    return points;\n  }\n\n  AnimatableValue<PointF> getPosition() {\n    return position;\n  }\n\n  AnimatableFloatValue getRotation() {\n    return rotation;\n  }\n\n  AnimatableFloatValue getInnerRadius() {\n    return innerRadius;\n  }\n\n  AnimatableFloatValue getOuterRadius() {\n    return outerRadius;\n  }\n\n  AnimatableFloatValue getInnerRoundedness() {\n    return innerRoundedness;\n  }\n\n  AnimatableFloatValue getOuterRoundedness() {\n    return outerRoundedness;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/RectangleContent.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Path;\nimport android.graphics.PointF;\nimport android.graphics.RectF;\nimport android.support.annotation.Nullable;\n\nimport java.util.List;\n\nclass RectangleContent implements PathContent, BaseKeyframeAnimation.AnimationListener {\n  private final Path path = new Path();\n  private final RectF rect = new RectF();\n\n  private final LottieDrawable lottieDrawable;\n  private final BaseKeyframeAnimation<?, PointF> positionAnimation;\n  private final BaseKeyframeAnimation<?, PointF> sizeAnimation;\n  private final BaseKeyframeAnimation<?, Float> cornerRadiusAnimation;\n\n  @Nullable private TrimPathContent trimPath;\n  private boolean isPathValid;\n\n  RectangleContent(LottieDrawable lottieDrawable, BaseLayer layer, RectangleShape rectShape) {\n    this.lottieDrawable = lottieDrawable;\n    positionAnimation = rectShape.getPosition().createAnimation();\n    sizeAnimation = rectShape.getSize().createAnimation();\n    cornerRadiusAnimation = rectShape.getCornerRadius().createAnimation();\n\n    layer.addAnimation(positionAnimation);\n    layer.addAnimation(sizeAnimation);\n    layer.addAnimation(cornerRadiusAnimation);\n\n    positionAnimation.addUpdateListener(this);\n    sizeAnimation.addUpdateListener(this);\n    cornerRadiusAnimation.addUpdateListener(this);\n  }\n\n  @Override public void onValueChanged() {\n    invalidate();\n  }\n\n  private void invalidate() {\n    isPathValid = false;\n    lottieDrawable.invalidateSelf();\n  }\n\n  @Override public void setContents(List<Content> contentsBefore, List<Content> contentsAfter) {\n    for (int i = 0; i < contentsBefore.size(); i++) {\n      Content content = contentsBefore.get(i);\n      if (content instanceof TrimPathContent) {\n        trimPath = (TrimPathContent) content;\n        trimPath.addListener(this);\n      }\n    }\n  }\n\n  @Override public Path getPath() {\n    if (isPathValid) {\n      return path;\n    }\n\n    path.reset();\n\n    PointF size = sizeAnimation.getValue();\n    float halfWidth = size.x / 2f;\n    float halfHeight = size.y / 2f;\n    float radius = cornerRadiusAnimation == null ? 0f : cornerRadiusAnimation.getValue();\n    float maxRadius = Math.min(halfWidth, halfHeight);\n    if (radius > maxRadius) {\n      radius = maxRadius;\n    }\n\n    // Draw the rectangle top right to bottom left.\n    PointF position = positionAnimation.getValue();\n\n    path.moveTo(position.x + halfWidth, position.y - halfHeight + radius);\n\n    path.lineTo(position.x + halfWidth, position.y + halfHeight - radius);\n\n    if (radius > 0) {\n      rect.set(position.x + halfWidth - 2 * radius,\n          position.y + halfHeight - 2 * radius,\n          position.x + halfWidth,\n          position.y + halfHeight);\n      path.arcTo(rect, 0, 90, false);\n    }\n\n    path.lineTo(position.x - halfWidth + radius, position.y + halfHeight);\n\n    if (radius > 0) {\n      rect.set(position.x - halfWidth,\n          position.y + halfHeight - 2 * radius,\n          position.x - halfWidth + 2 * radius,\n          position.y + halfHeight);\n      path.arcTo(rect, 90, 90, false);\n    }\n\n    path.lineTo(position.x - halfWidth, position.y - halfHeight + 2 * radius);\n\n    if (radius > 0) {\n      rect.set(position.x - halfWidth,\n          position.y - halfHeight,\n          position.x - halfWidth + 2 * radius,\n          position.y - halfHeight + 2 * radius);\n      path.arcTo(rect, 180, 90, false);\n    }\n\n    path.lineTo(position.x + halfWidth - 2 * radius, position.y - halfHeight);\n\n    if (radius > 0) {\n      rect.set(position.x + halfWidth - 2 * radius,\n          position.y - halfHeight,\n          position.x + halfWidth,\n          position.y - halfHeight + 2 * radius);\n      path.arcTo(rect, 270, 90, false);\n    }\n    path.close();\n\n    Utils.applyTrimPathIfNeeded(path, trimPath);\n\n    isPathValid = true;\n    return path;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/RectangleShape.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.PointF;\n\nimport org.json.JSONObject;\n\nclass RectangleShape {\n  private final AnimatableValue<PointF> position;\n  private final AnimatablePointValue size;\n  private final AnimatableFloatValue cornerRadius;\n\n  private RectangleShape(AnimatableValue<PointF> position, AnimatablePointValue size,\n      AnimatableFloatValue cornerRadius) {\n    this.position = position;\n    this.size = size;\n    this.cornerRadius = cornerRadius;\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    static RectangleShape newInstance(JSONObject json, LottieComposition composition) {\n      return new RectangleShape(\n          AnimatablePathValue.createAnimatablePathOrSplitDimensionPath(\n              json.optJSONObject(\"p\"), composition),\n          AnimatablePointValue.Factory.newInstance(json.optJSONObject(\"s\"), composition),\n          AnimatableFloatValue.Factory.newInstance(json.optJSONObject(\"r\"), composition));\n    }\n  }\n\n  AnimatableFloatValue getCornerRadius() {\n    return cornerRadius;\n  }\n\n  AnimatablePointValue getSize() {\n    return size;\n  }\n\n  AnimatableValue<PointF> getPosition() {\n    return position;\n  }\n\n  @Override public String toString() {\n    return \"RectangleShape{\" + \"cornerRadius=\" + cornerRadius.getInitialValue() +\n        \", position=\" + position +\n        \", size=\" + size +\n        '}';\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ScaleKeyframeAnimation.java",
    "content": "package com.airbnb.lottie;\n\nimport java.util.List;\n\nimport static com.airbnb.lottie.MiscUtils.lerp;\n\nclass ScaleKeyframeAnimation extends KeyframeAnimation<ScaleXY> {\n  ScaleKeyframeAnimation(List<Keyframe<ScaleXY>> keyframes) {\n    super(keyframes);\n  }\n\n  @Override public ScaleXY getValue(Keyframe<ScaleXY> keyframe, float keyframeProgress) {\n    if (keyframe.startValue == null || keyframe.endValue == null) {\n      throw new IllegalStateException(\"Missing values for keyframe.\");\n    }\n    ScaleXY startTransform = keyframe.startValue;\n    ScaleXY endTransform = keyframe.endValue;\n    return new ScaleXY(\n        lerp(startTransform.getScaleX(), endTransform.getScaleX(), keyframeProgress),\n        lerp(startTransform.getScaleY(), endTransform.getScaleY(), keyframeProgress));\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ScaleXY.java",
    "content": "package com.airbnb.lottie;\n\nimport org.json.JSONArray;\n\nclass ScaleXY {\n  private final float scaleX;\n  private final float scaleY;\n\n  ScaleXY(float sx, float sy) {\n    this.scaleX = sx;\n    this.scaleY = sy;\n  }\n\n  ScaleXY() {\n    this(1f, 1f);\n  }\n\n  float getScaleX() {\n    return scaleX;\n  }\n\n  float getScaleY() {\n    return scaleY;\n  }\n\n  @Override public String toString() {\n    return getScaleX() + \"x\" + getScaleY();\n  }\n\n  static class Factory implements AnimatableValue.Factory<ScaleXY> {\n    static final Factory INSTANCE = new Factory();\n\n    private Factory() {\n    }\n\n    @Override public ScaleXY valueFromObject(Object object, float scale) {\n      JSONArray array = (JSONArray) object;\n      return new ScaleXY(\n          (float) array.optDouble(0, 1) / 100f * scale,\n          (float) array.optDouble(1, 1) / 100f * scale);\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ShapeContent.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Path;\nimport android.support.annotation.Nullable;\n\nimport java.util.List;\n\nclass ShapeContent implements PathContent, BaseKeyframeAnimation.AnimationListener {\n  private final Path path = new Path();\n\n  private final LottieDrawable lottieDrawable;\n  private final BaseKeyframeAnimation<?, Path> shapeAnimation;\n\n  private boolean isPathValid;\n  @Nullable private TrimPathContent trimPath;\n\n  ShapeContent(LottieDrawable lottieDrawable, BaseLayer layer, ShapePath shape) {\n    this.lottieDrawable = lottieDrawable;\n    shapeAnimation = shape.getShapePath().createAnimation();\n    layer.addAnimation(shapeAnimation);\n    shapeAnimation.addUpdateListener(this);\n  }\n\n  @Override public void onValueChanged() {\n    invalidate();\n  }\n\n  private void invalidate() {\n    isPathValid = false;\n    lottieDrawable.invalidateSelf();\n  }\n\n  @Override public void setContents(List<Content> contentsBefore, List<Content> contentsAfter) {\n    for (int i = 0; i < contentsBefore.size(); i++) {\n      Content content = contentsBefore.get(i);\n      if (content instanceof TrimPathContent) {\n        trimPath = (TrimPathContent) content;\n        trimPath.addListener(this);\n      }\n    }\n  }\n\n  @Override public Path getPath() {\n    if (isPathValid) {\n      return path;\n    }\n\n    path.reset();\n\n    path.set(shapeAnimation.getValue());\n    path.setFillType(Path.FillType.EVEN_ODD);\n\n    Utils.applyTrimPathIfNeeded(path, trimPath);\n\n    isPathValid = true;\n    return path;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ShapeData.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.PointF;\nimport android.support.annotation.FloatRange;\n\nimport org.json.JSONArray;\nimport org.json.JSONObject;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\nclass ShapeData {\n  private final List<CubicCurveData> curves = new ArrayList<>();\n  private PointF initialPoint;\n  private boolean closed;\n\n  private ShapeData(PointF initialPoint, boolean closed, List<CubicCurveData> curves) {\n    this.initialPoint = initialPoint;\n    this.closed = closed;\n    this.curves.addAll(curves);\n  }\n\n  ShapeData() {\n  }\n\n  private void setInitialPoint(float x, float y) {\n    if (initialPoint == null) {\n      initialPoint = new PointF();\n    }\n    initialPoint.set(x, y);\n  }\n\n  PointF getInitialPoint() {\n    return initialPoint;\n  }\n\n  boolean isClosed() {\n    return closed;\n  }\n\n  List<CubicCurveData> getCurves() {\n    return curves;\n  }\n\n  void interpolateBetween(ShapeData shapeData1, ShapeData shapeData2,\n      @FloatRange(from = 0f, to = 1f) float percentage) {\n    if (initialPoint == null) {\n      initialPoint = new PointF();\n    }\n    closed = shapeData1.isClosed() || shapeData2.isClosed();\n\n    if (!curves.isEmpty() && curves.size() != shapeData1.getCurves().size()\n        && curves.size() != shapeData2.getCurves().size()) {\n      throw new IllegalStateException(\"Curves must have the same number of control points. This: \"\n          + getCurves().size()\n          + \"\\tShape 1: \" + shapeData1.getCurves().size() + \"\\tShape 2: \"\n          + shapeData2.getCurves().size());\n    } else if (curves.isEmpty()) {\n      for (int i = shapeData1.getCurves().size() - 1; i >= 0; i--) {\n        curves.add(new CubicCurveData());\n      }\n    }\n\n    PointF initialPoint1 = shapeData1.getInitialPoint();\n    PointF initialPoint2 = shapeData2.getInitialPoint();\n\n    setInitialPoint(MiscUtils.lerp(initialPoint1.x, initialPoint2.x, percentage),\n        MiscUtils.lerp(initialPoint1.y, initialPoint2.y, percentage));\n\n    for (int i = curves.size() - 1; i >= 0; i--) {\n      CubicCurveData curve1 = shapeData1.getCurves().get(i);\n      CubicCurveData curve2 = shapeData2.getCurves().get(i);\n\n      PointF cp11 = curve1.getControlPoint1();\n      PointF cp21 = curve1.getControlPoint2();\n      PointF vertex1 = curve1.getVertex();\n\n      PointF cp12 = curve2.getControlPoint1();\n      PointF cp22 = curve2.getControlPoint2();\n      PointF vertex2 = curve2.getVertex();\n\n      curves.get(i).setControlPoint1(\n          MiscUtils.lerp(cp11.x, cp12.x, percentage), MiscUtils.lerp(cp11.y, cp12.y,\n              percentage));\n      curves.get(i).setControlPoint2(\n          MiscUtils.lerp(cp21.x, cp22.x, percentage), MiscUtils.lerp(cp21.y, cp22.y,\n              percentage));\n      curves.get(i).setVertex(\n          MiscUtils.lerp(vertex1.x, vertex2.x, percentage), MiscUtils.lerp(vertex1.y, vertex2.y,\n              percentage));\n    }\n  }\n\n  @Override public String toString() {\n    return \"ShapeData{\" + \"numCurves=\" + curves.size() +\n        \"closed=\" + closed +\n        '}';\n  }\n\n  static class Factory implements AnimatableValue.Factory<ShapeData> {\n    static final ShapeData.Factory INSTANCE = new Factory();\n\n    private Factory() {\n    }\n\n    @Override public ShapeData valueFromObject(Object object, float scale) {\n      JSONObject pointsData = null;\n      if (object instanceof JSONArray) {\n        Object firstObject = ((JSONArray) object).opt(0);\n        if (firstObject instanceof JSONObject && ((JSONObject) firstObject).has(\"v\")) {\n          pointsData = (JSONObject) firstObject;\n        }\n      } else if (object instanceof JSONObject && ((JSONObject) object).has(\"v\")) {\n        pointsData = (JSONObject) object;\n      }\n\n      if (pointsData == null) {\n        return null;\n      }\n\n      JSONArray pointsArray = pointsData.optJSONArray(\"v\");\n      JSONArray inTangents = pointsData.optJSONArray(\"i\");\n      JSONArray outTangents = pointsData.optJSONArray(\"o\");\n      boolean closed = pointsData.optBoolean(\"c\", false);\n\n      if (pointsArray == null || inTangents == null || outTangents == null ||\n          pointsArray.length() != inTangents.length() ||\n          pointsArray.length() != outTangents.length()) {\n        throw new IllegalStateException(\n            \"Unable to process points array or tangents. \" + pointsData);\n      } else if (pointsArray.length() == 0) {\n        return new ShapeData(new PointF(), false, Collections.<CubicCurveData>emptyList());\n      }\n\n      int length = pointsArray.length();\n      PointF vertex = vertexAtIndex(0, pointsArray);\n      vertex.x *= scale;\n      vertex.y *= scale;\n      PointF initialPoint = vertex;\n      List<CubicCurveData> curves = new ArrayList<>(length);\n\n      for (int i = 1; i < length; i++) {\n        vertex = vertexAtIndex(i, pointsArray);\n        PointF previousVertex = vertexAtIndex(i - 1, pointsArray);\n        PointF cp1 = vertexAtIndex(i - 1, outTangents);\n        PointF cp2 = vertexAtIndex(i, inTangents);\n        PointF shapeCp1 = MiscUtils.addPoints(previousVertex, cp1);\n        PointF shapeCp2 = MiscUtils.addPoints(vertex, cp2);\n\n        shapeCp1.x *= scale;\n        shapeCp1.y *= scale;\n        shapeCp2.x *= scale;\n        shapeCp2.y *= scale;\n        vertex.x *= scale;\n        vertex.y *= scale;\n\n        curves.add(new CubicCurveData(shapeCp1, shapeCp2, vertex));\n      }\n\n      if (closed) {\n        vertex = vertexAtIndex(0, pointsArray);\n        PointF previousVertex = vertexAtIndex(length - 1, pointsArray);\n        PointF cp1 = vertexAtIndex(length - 1, outTangents);\n        PointF cp2 = vertexAtIndex(0, inTangents);\n\n        PointF shapeCp1 = MiscUtils.addPoints(previousVertex, cp1);\n        PointF shapeCp2 = MiscUtils.addPoints(vertex, cp2);\n\n        if (scale != 1f) {\n          shapeCp1.x *= scale;\n          shapeCp1.y *= scale;\n          shapeCp2.x *= scale;\n          shapeCp2.y *= scale;\n          vertex.x *= scale;\n          vertex.y *= scale;\n        }\n\n        curves.add(new CubicCurveData(shapeCp1, shapeCp2, vertex));\n      }\n      return new ShapeData(initialPoint, closed, curves);\n    }\n\n    private static PointF vertexAtIndex(int idx, JSONArray points) {\n      if (idx >= points.length()) {\n        throw new IllegalArgumentException(\n            \"Invalid index \" + idx + \". There are only \" + points.length() + \" points.\");\n      }\n\n      JSONArray pointArray = points.optJSONArray(idx);\n      Object x = pointArray.opt(0);\n      Object y = pointArray.opt(1);\n      return new PointF(\n          x instanceof Double ? new Float((Double) x) : (int) x,\n          y instanceof Double ? new Float((Double) y) : (int) y);\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ShapeFill.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Path;\nimport android.support.annotation.Nullable;\n\nimport org.json.JSONObject;\n\nclass ShapeFill {\n  private final boolean fillEnabled;\n  private final Path.FillType fillType;\n  @Nullable private final AnimatableColorValue color;\n  @Nullable private final AnimatableIntegerValue opacity;\n\n  private ShapeFill(boolean fillEnabled, Path.FillType fillType,\n      @Nullable AnimatableColorValue color, @Nullable AnimatableIntegerValue opacity) {\n    this.fillEnabled = fillEnabled;\n    this.fillType = fillType;\n    this.color = color;\n    this.opacity = opacity;\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    static ShapeFill newInstance(JSONObject json, LottieComposition composition) {\n      AnimatableColorValue color = null;\n      boolean fillEnabled;\n      AnimatableIntegerValue opacity = null;\n\n      JSONObject jsonColor = json.optJSONObject(\"c\");\n      if (jsonColor != null) {\n        color = AnimatableColorValue.Factory.newInstance(jsonColor, composition);\n      }\n\n      JSONObject jsonOpacity = json.optJSONObject(\"o\");\n      if (jsonOpacity != null) {\n        opacity = AnimatableIntegerValue.Factory.newInstance(jsonOpacity, composition);\n      }\n      fillEnabled = json.optBoolean(\"fillEnabled\");\n\n      int fillTypeInt = json.optInt(\"r\", 1);\n      Path.FillType fillType = fillTypeInt == 1 ? Path.FillType.WINDING : Path.FillType.EVEN_ODD;\n\n      return new ShapeFill(fillEnabled, fillType, color, opacity);\n    }\n  }\n\n  @Nullable AnimatableColorValue getColor() {\n    return color;\n  }\n\n  @Nullable AnimatableIntegerValue getOpacity() {\n    return opacity;\n  }\n\n  Path.FillType getFillType() {\n    return fillType;\n  }\n\n  @Override\n  public String toString() {\n    return \"ShapeFill{\" + \"color=\" +\n        (color == null ? \"null\" :  Integer.toHexString(color.getInitialValue())) +\n        \", fillEnabled=\" + fillEnabled +\n        \", opacity=\" + (opacity == null ? \"null\" : opacity.getInitialValue()) +\n        '}';\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ShapeGroup.java",
    "content": "package com.airbnb.lottie;\n\nimport android.support.annotation.Nullable;\nimport android.util.Log;\n\nimport org.json.JSONArray;\nimport org.json.JSONObject;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\nclass ShapeGroup {\n  @Nullable static Object shapeItemWithJson(JSONObject json, LottieComposition composition) {\n    String type = json.optString(\"ty\");\n\n    switch (type) {\n      case \"gr\":\n        return ShapeGroup.Factory.newInstance(json, composition);\n      case \"st\":\n        return ShapeStroke.Factory.newInstance(json, composition);\n      case \"fl\":\n        return ShapeFill.Factory.newInstance(json, composition);\n      case \"tr\":\n        return AnimatableTransform.Factory.newInstance(json, composition);\n      case \"sh\":\n        return ShapePath.Factory.newInstance(json, composition);\n      case \"el\":\n        return CircleShape.Factory.newInstance(json, composition);\n      case \"rc\":\n        return RectangleShape.Factory.newInstance(json, composition);\n      case \"tm\":\n        return ShapeTrimPath.Factory.newInstance(json, composition);\n      case \"sr\":\n        return PolystarShape.Factory.newInstance(json, composition);\n      case \"mm\":\n        return MergePaths.Factory.newInstance(json);\n      default:\n        Log.w(L.TAG, \"Unknown shape type \" + type);\n    }\n    return null;\n  }\n\n  private final String name;\n  private final List<Object> items;\n\n  ShapeGroup(String name, List<Object> items) {\n    this.name = name;\n    this.items = items;\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    private static ShapeGroup newInstance(JSONObject json, LottieComposition composition) {\n      JSONArray jsonItems = json.optJSONArray(\"it\");\n      String name = json.optString(\"nm\");\n      List<Object> items = new ArrayList<>();\n\n      for (int i = 0; i < jsonItems.length(); i++) {\n        Object newItem = shapeItemWithJson(jsonItems.optJSONObject(i), composition);\n        if (newItem != null) {\n          items.add(newItem);\n        }\n      }\n      return new ShapeGroup(name, items);\n    }\n  }\n\n  List<Object> getItems() {\n    return items;\n  }\n\n  @Override public String toString() {\n    return \"ShapeGroup{\" + \"name='\" + name + \"\\' Shapes: \" + Arrays.toString(items.toArray()) + '}';\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ShapeKeyframeAnimation.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Path;\n\nimport java.util.List;\n\nclass ShapeKeyframeAnimation extends BaseKeyframeAnimation<ShapeData, Path> {\n  private final ShapeData tempShapeData = new ShapeData();\n  private final Path tempPath = new Path();\n\n  ShapeKeyframeAnimation(List<Keyframe<ShapeData>> keyframes) {\n    super(keyframes);\n  }\n\n  @Override public Path getValue(Keyframe<ShapeData> keyframe, float keyframeProgress) {\n    ShapeData startShapeData = keyframe.startValue;\n    ShapeData endShapeData = keyframe.endValue;\n\n    tempShapeData.interpolateBetween(startShapeData, endShapeData, keyframeProgress);\n    MiscUtils.getPathFromData(tempShapeData, tempPath);\n    return tempPath;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ShapeLayer.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Canvas;\nimport android.graphics.Matrix;\nimport android.support.annotation.NonNull;\n\nimport java.util.Collections;\n\nclass ShapeLayer extends BaseLayer {\n\n  private final ContentGroup contentGroup;\n\n  ShapeLayer(LottieDrawable lottieDrawable, Layer layerModel) {\n    super(lottieDrawable, layerModel);\n\n    ShapeGroup shapeGroup = new ShapeGroup(layerModel.getName(), layerModel.getShapes());\n    contentGroup = new ContentGroup(lottieDrawable, this, shapeGroup);\n    contentGroup.setContents(Collections.<Content>emptyList(), Collections.<Content>emptyList());\n  }\n\n\n\n  @Override void drawLayer(@NonNull Canvas canvas, Matrix parentMatrix, int parentAlpha) {\n    contentGroup.draw(canvas, parentMatrix, parentAlpha);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ShapePath.java",
    "content": "package com.airbnb.lottie;\n\nimport org.json.JSONObject;\n\nclass ShapePath {\n  private final String name;\n  private final int index;\n  private final AnimatableShapeValue shapePath;\n\n  private ShapePath(String name, int index, AnimatableShapeValue shapePath) {\n    this.name = name;\n    this.index = index;\n    this.shapePath = shapePath;\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    static ShapePath newInstance(JSONObject json, LottieComposition composition) {\n      AnimatableShapeValue animatableShapeValue =\n          AnimatableShapeValue.Factory.newInstance(json.optJSONObject(\"ks\"), composition);\n      return new ShapePath(json.optString(\"nm\"), json.optInt(\"ind\"), animatableShapeValue);\n    }\n  }\n\n  AnimatableShapeValue getShapePath() {\n    return shapePath;\n  }\n\n  @Override public String toString() {\n    return \"ShapePath{\" + \"name=\" + name +\n        \", index=\" + index +\n        \", hasAnimation=\" + shapePath.hasAnimation() +\n        '}';\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ShapeStroke.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Paint;\nimport android.support.annotation.Nullable;\n\nimport org.json.JSONArray;\nimport org.json.JSONObject;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nclass ShapeStroke {\n  enum LineCapType {\n    Butt,\n    Round,\n    Unknown;\n\n    Paint.Cap toPaintCap() {\n      switch (this) {\n        case Butt:\n          return Paint.Cap.BUTT;\n        case Round:\n          return Paint.Cap.ROUND;\n        case Unknown:\n        default:\n          return Paint.Cap.SQUARE;\n      }\n    }\n  }\n\n  enum LineJoinType {\n    Miter,\n    Round,\n    Bevel;\n\n    Paint.Join toPaintJoin() {\n      switch (this) {\n        case Bevel:\n          return Paint.Join.BEVEL;\n        case Miter:\n          return Paint.Join.MITER;\n        case Round:\n          return Paint.Join.ROUND;\n      }\n      return null;\n    }\n  }\n\n  @Nullable private final AnimatableFloatValue offset;\n  private final List<AnimatableFloatValue> lineDashPattern;\n  private final AnimatableColorValue color;\n  private final AnimatableIntegerValue opacity;\n  private final AnimatableFloatValue width;\n  private final LineCapType capType;\n  private final LineJoinType joinType;\n\n  private ShapeStroke(@Nullable AnimatableFloatValue offset,\n      List<AnimatableFloatValue> lineDashPattern, AnimatableColorValue color,\n      AnimatableIntegerValue opacity, AnimatableFloatValue width, LineCapType capType,\n      LineJoinType joinType) {\n    this.offset = offset;\n    this.lineDashPattern = lineDashPattern;\n    this.color = color;\n    this.opacity = opacity;\n    this.width = width;\n    this.capType = capType;\n    this.joinType = joinType;\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    static ShapeStroke newInstance(JSONObject json, LottieComposition composition) {\n      List<AnimatableFloatValue> lineDashPattern = new ArrayList<>();\n      AnimatableColorValue color = AnimatableColorValue.Factory.newInstance(json.optJSONObject(\"c\"),\n          composition);\n      AnimatableFloatValue width = AnimatableFloatValue.Factory.newInstance(json.optJSONObject(\"w\"),\n          composition);\n      AnimatableIntegerValue opacity = AnimatableIntegerValue.Factory.newInstance(\n          json.optJSONObject(\"o\"), composition);\n      LineCapType capType = LineCapType.values()[json.optInt(\"lc\") - 1];\n      LineJoinType joinType = LineJoinType.values()[json.optInt(\"lj\") - 1];\n      AnimatableFloatValue offset = null;\n\n      if (json.has(\"d\")) {\n        JSONArray dashesJson = json.optJSONArray(\"d\");\n        for (int i = 0; i < dashesJson.length(); i++) {\n          JSONObject dashJson = dashesJson.optJSONObject(i);\n          String n = dashJson.optString(\"n\");\n          if (n.equals(\"o\")) {\n            JSONObject value = dashJson.optJSONObject(\"v\");\n            offset = AnimatableFloatValue.Factory.newInstance(value, composition);\n          } else if (n.equals(\"d\") || n.equals(\"g\")) {\n            JSONObject value = dashJson.optJSONObject(\"v\");\n            lineDashPattern.add(AnimatableFloatValue.Factory.newInstance(value, composition));\n          }\n        }\n        if (lineDashPattern.size() == 1) {\n          // If there is only 1 value then it is assumed to be equal parts on and off.\n          lineDashPattern.add(lineDashPattern.get(0));\n        }\n      }\n      return new ShapeStroke(offset, lineDashPattern, color, opacity, width, capType, joinType);\n    }\n  }\n\n  AnimatableColorValue getColor() {\n    return color;\n  }\n\n  AnimatableIntegerValue getOpacity() {\n    return opacity;\n  }\n\n  AnimatableFloatValue getWidth() {\n    return width;\n  }\n\n  List<AnimatableFloatValue> getLineDashPattern() {\n    return lineDashPattern;\n  }\n\n  AnimatableFloatValue getDashOffset() {\n    return offset;\n  }\n\n  LineCapType getCapType() {\n    return capType;\n  }\n\n  LineJoinType getJoinType() {\n    return joinType;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/ShapeTrimPath.java",
    "content": "package com.airbnb.lottie;\n\nimport org.json.JSONObject;\n\nclass ShapeTrimPath {\n  private final AnimatableFloatValue start;\n  private final AnimatableFloatValue end;\n  private final AnimatableFloatValue offset;\n\n  private ShapeTrimPath(AnimatableFloatValue start, AnimatableFloatValue end, AnimatableFloatValue\n      offset) {\n    this.start = start;\n    this.end = end;\n    this.offset = offset;\n  }\n\n  static class Factory {\n    private Factory() {\n    }\n\n    static ShapeTrimPath newInstance(JSONObject json, LottieComposition composition) {\n      return new ShapeTrimPath(\n          AnimatableFloatValue.Factory.newInstance(json.optJSONObject(\"s\"), composition, false),\n          AnimatableFloatValue.Factory.newInstance(json.optJSONObject(\"e\"), composition, false),\n          AnimatableFloatValue.Factory.newInstance(json.optJSONObject(\"o\"), composition, false));\n    }\n  }\n\n  AnimatableFloatValue getEnd() {\n    return end;\n  }\n\n  AnimatableFloatValue getStart() {\n    return start;\n  }\n\n  AnimatableFloatValue getOffset() {\n    return offset;\n  }\n\n  @Override public String toString() {\n    return \"Trim Path: {start: \" + start + \", end: \" + end + \", offset: \" + offset + \"}\";\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/SolidLayer.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Matrix;\nimport android.graphics.Paint;\nimport android.graphics.RectF;\n\nclass SolidLayer extends BaseLayer {\n\n  private final RectF rect = new RectF();\n  private final Paint paint = new Paint();\n  private final Layer layerModel;\n\n  SolidLayer(LottieDrawable lottieDrawable, Layer layerModel) {\n    super(lottieDrawable, layerModel);\n    this.layerModel = layerModel;\n\n    paint.setAlpha(0);\n    paint.setStyle(Paint.Style.FILL);\n    paint.setColor(layerModel.getSolidColor());\n  }\n\n  @Override public void drawLayer(Canvas canvas, Matrix parentMatrix, int parentAlpha) {\n    int backgroundAlpha = Color.alpha(layerModel.getSolidColor());\n    if (backgroundAlpha == 0) {\n      return;\n    }\n\n    int alpha = (int) ((backgroundAlpha / 255f * transform.getOpacity().getValue() / 100f) * 255);\n    paint.setAlpha(alpha);\n    if (alpha > 0) {\n      rect.set(0, 0, layerModel.getSolidWidth(), layerModel.getSolidHeight());\n      parentMatrix.mapRect(rect);\n      canvas.drawRect((int) rect.left, (int) rect.top, (int) rect.right, (int) rect.bottom, paint);\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/SplitDimensionPathKeyframeAnimation.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.PointF;\n\nimport java.util.Collections;\n\nclass SplitDimensionPathKeyframeAnimation extends KeyframeAnimation<PointF> {\n  private final PointF point = new PointF();\n  private final KeyframeAnimation<Float> xAnimation;\n  private final KeyframeAnimation<Float> yAnimation;\n\n  SplitDimensionPathKeyframeAnimation(\n      KeyframeAnimation<Float> xAnimation, KeyframeAnimation<Float> yAnimation) {\n    super(Collections.<Keyframe<PointF>>emptyList());\n\n    this.xAnimation = xAnimation;\n    this.yAnimation = yAnimation;\n  }\n\n  @Override void setProgress(float progress) {\n    xAnimation.setProgress(progress);\n    yAnimation.setProgress(progress);\n    point.set(xAnimation.getValue(), yAnimation.getValue());\n    for (int i = 0; i < listeners.size(); i++) {\n      listeners.get(i).onValueChanged();\n    }\n  }\n\n  @Override public PointF getValue() {\n    return getValue(null, 0);\n  }\n\n  @Override PointF getValue(Keyframe<PointF> keyframe, float keyframeProgress) {\n    return point;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/StaticKeyframeAnimation.java",
    "content": "package com.airbnb.lottie;\n\nimport android.support.annotation.FloatRange;\n\nimport java.util.Collections;\n\nclass StaticKeyframeAnimation<T> extends KeyframeAnimation<T> {\n  private final T initialValue;\n\n  StaticKeyframeAnimation(T initialValue) {\n    super(Collections.<Keyframe<T>>emptyList());\n    this.initialValue = initialValue;\n  }\n\n  @Override public void setProgress(@FloatRange(from = 0f, to = 1f) float progress) {\n    // Do nothing\n  }\n\n  @Override public T getValue() {\n    return initialValue;\n  }\n\n  @Override public T getValue(Keyframe<T> keyframe, float keyframeProgress) {\n    return initialValue;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/StrokeContent.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Canvas;\nimport android.graphics.DashPathEffect;\nimport android.graphics.Matrix;\nimport android.graphics.Paint;\nimport android.graphics.Path;\nimport android.support.annotation.Nullable;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nclass StrokeContent implements DrawingContent, BaseKeyframeAnimation.AnimationListener {\n  private final Path path = new Path();\n  private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);\n  private final LottieDrawable lottieDrawable;\n  private final List<PathContent> paths = new ArrayList<>();\n  private final float[] dashPatternValues;\n\n  private final BaseKeyframeAnimation<?, Integer> colorAnimation;\n  private final BaseKeyframeAnimation<?, Float> widthAnimation;\n  private final BaseKeyframeAnimation<?, Integer> opacityAnimation;\n  private final List<BaseKeyframeAnimation<?, Float>> dashPatternAnimations;\n  @Nullable private final BaseKeyframeAnimation<?, Float> dashPatternOffsetAnimation;\n\n  StrokeContent(final LottieDrawable lottieDrawable, BaseLayer layer, ShapeStroke stroke) {\n    this.lottieDrawable = lottieDrawable;\n    paint.setStyle(Paint.Style.STROKE);\n    paint.setStrokeCap(stroke.getCapType().toPaintCap());\n    paint.setStrokeJoin(stroke.getJoinType().toPaintJoin());\n\n    colorAnimation = stroke.getColor().createAnimation();\n    opacityAnimation = stroke.getOpacity().createAnimation();\n    widthAnimation = stroke.getWidth().createAnimation();\n\n    if (stroke.getDashOffset() == null) {\n      dashPatternOffsetAnimation = null;\n    } else {\n      dashPatternOffsetAnimation = stroke.getDashOffset().createAnimation();\n    }\n    List<AnimatableFloatValue> dashPattern = stroke.getLineDashPattern();\n    dashPatternAnimations = new ArrayList<>(dashPattern.size());\n    dashPatternValues = new float[dashPattern.size()];\n\n    for (int i = 0; i < dashPattern.size(); i++) {\n      dashPatternAnimations.add(dashPattern.get(i).createAnimation());\n    }\n\n    layer.addAnimation(colorAnimation);\n    layer.addAnimation(opacityAnimation);\n    layer.addAnimation(widthAnimation);\n    for (int i = 0; i < dashPatternAnimations.size(); i++) {\n      layer.addAnimation(dashPatternAnimations.get(i));\n    }\n    if (dashPatternOffsetAnimation != null) {\n      layer.addAnimation(dashPatternOffsetAnimation);\n    }\n\n    colorAnimation.addUpdateListener(this);\n    opacityAnimation.addUpdateListener(this);\n    widthAnimation.addUpdateListener(this);\n\n    for (int i = 0; i < dashPattern.size(); i++) {\n      dashPatternAnimations.get(i).addUpdateListener(this);\n    }\n    if (dashPatternOffsetAnimation != null) {\n      dashPatternOffsetAnimation.addUpdateListener(this);\n    }\n  }\n\n  @Override public void onValueChanged() {\n    lottieDrawable.invalidateSelf();\n  }\n\n  @Override public void setContents(List<Content> contentsBefore, List<Content> contentsAfter) {\n    for (int i = 0; i < contentsAfter.size(); i++) {\n      Content content = contentsAfter.get(i);\n      if (content instanceof PathContent) {\n        paths.add((PathContent) content);\n      }\n    }\n  }\n\n  @Override public void draw(Canvas canvas, Matrix parentMatrix, int parentAlpha) {\n    paint.setColor(colorAnimation.getValue());\n    int alpha = (int) ((parentAlpha / 255f * opacityAnimation.getValue() / 100f) * 255);\n    paint.setAlpha(alpha);\n    paint.setStrokeWidth(widthAnimation.getValue() * Utils.getScale(parentMatrix));\n    if (paint.getStrokeWidth() < 1) {\n      // Android draws a hairline stroke for 0, After Effects doesn't.\n      return;\n    }\n    applyDashPatternIfNeeded();\n\n    path.reset();\n    for (int i = 0; i < paths.size(); i++) {\n      this.path.addPath(paths.get(i).getPath(), parentMatrix);\n    }\n\n    canvas.drawPath(path, paint);\n  }\n\n  private void applyDashPatternIfNeeded() {\n    if (dashPatternAnimations.isEmpty()) {\n      return;\n    }\n\n    float scale = lottieDrawable.getScale();\n    for (int i = 0; i < dashPatternAnimations.size(); i++) {\n      dashPatternValues[i] = dashPatternAnimations.get(i).getValue();\n      // If the value of the dash pattern or gap is too small, the number of individual sections\n      // approaches infinity as the value approaches 0.\n      // To mitigate this, we essentially put a minimum value on the dash pattern size of 1px\n      // and a minimum gap size of 0.01.\n      if (i % 2 == 0) {\n        if (dashPatternValues[i] < 1f) {\n          dashPatternValues[i] = 1f;\n        }\n      } else {\n        if (dashPatternValues[i] < 0.1f) {\n          dashPatternValues[i] = 0.1f;\n        }\n      }\n      dashPatternValues[i] *= scale;\n    }\n    float offset = dashPatternOffsetAnimation == null ? 0f : dashPatternOffsetAnimation.getValue();\n    paint.setPathEffect(new DashPathEffect(dashPatternValues, offset));\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/TransformKeyframeAnimation.java",
    "content": "package com.airbnb.lottie;\n\nimport android.graphics.Matrix;\nimport android.graphics.PointF;\n\nclass TransformKeyframeAnimation {\n  private final Matrix matrix = new Matrix();\n\n  private final BaseKeyframeAnimation<?, PointF> anchorPoint;\n  private final BaseKeyframeAnimation<?, PointF> position;\n  private final BaseKeyframeAnimation<?, ScaleXY> scale;\n  private final BaseKeyframeAnimation<?, Float> rotation;\n  private final BaseKeyframeAnimation<?, Integer> opacity;\n\n  TransformKeyframeAnimation(AnimatableTransform animatableTransform) {\n    anchorPoint = animatableTransform.getAnchorPoint().createAnimation();\n    position = animatableTransform.getPosition().createAnimation();\n    scale = animatableTransform.getScale().createAnimation();\n    rotation = animatableTransform.getRotation().createAnimation();\n    opacity = animatableTransform.getOpacity().createAnimation();\n  }\n\n  void addAnimationsToLayer(BaseLayer layer) {\n    layer.addAnimation(anchorPoint);\n    layer.addAnimation(position);\n    layer.addAnimation(scale);\n    layer.addAnimation(rotation);\n    layer.addAnimation(opacity);\n  }\n\n  void addListener(final BaseKeyframeAnimation.AnimationListener listener) {\n    anchorPoint.addUpdateListener(listener);\n    position.addUpdateListener(listener);\n    scale.addUpdateListener(listener);\n    rotation.addUpdateListener(listener);\n    opacity.addUpdateListener(listener);\n  }\n\n  BaseKeyframeAnimation<?, Integer> getOpacity() {\n    return opacity;\n  }\n\n  Matrix getMatrix() {\n    matrix.reset();\n    PointF position = this.position.getValue();\n    if (position.x != 0 || position.y != 0) {\n      matrix.preTranslate(position.x, position.y);\n    }\n\n    float rotation = this.rotation.getValue();\n    if (rotation != 0f) {\n      matrix.preRotate(rotation);\n    }\n\n    ScaleXY scaleTransform = this.scale.getValue();\n    if (scaleTransform.getScaleX() != 1f || scaleTransform.getScaleY() != 1f) {\n      matrix.preScale(scaleTransform.getScaleX(), scaleTransform.getScaleY());\n    }\n\n    PointF anchorPoint = this.anchorPoint.getValue();\n    if (anchorPoint.x != 0 || anchorPoint.y != 0) {\n      matrix.preTranslate(-anchorPoint.x, -anchorPoint.y);\n    }\n    return matrix;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/TrimPathContent.java",
    "content": "package com.airbnb.lottie;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nclass TrimPathContent implements Content, BaseKeyframeAnimation.AnimationListener {\n\n  private final List<BaseKeyframeAnimation.AnimationListener> listeners = new ArrayList<>();\n  private final BaseKeyframeAnimation<?, Float> startAnimation;\n  private final BaseKeyframeAnimation<?, Float> endAnimation;\n  private final BaseKeyframeAnimation<?, Float> offsetAnimation;\n\n  TrimPathContent(BaseLayer layer, ShapeTrimPath trimPath) {\n    startAnimation = trimPath.getStart().createAnimation();\n    endAnimation = trimPath.getEnd().createAnimation();\n    offsetAnimation = trimPath.getOffset().createAnimation();\n\n    layer.addAnimation(startAnimation);\n    layer.addAnimation(endAnimation);\n    layer.addAnimation(offsetAnimation);\n\n    startAnimation.addUpdateListener(this);\n    endAnimation.addUpdateListener(this);\n    offsetAnimation.addUpdateListener(this);\n  }\n\n  @Override public void onValueChanged() {\n    for (int i = 0; i < listeners.size(); i++) {\n      listeners.get(i).onValueChanged();\n    }\n  }\n\n  @Override public void setContents(List<Content> contentsBefore, List<Content> contentsAfter) {\n    // Do nothing.\n  }\n\n  void addListener(BaseKeyframeAnimation.AnimationListener listener) {\n    listeners.add(listener);\n  }\n\n  public BaseKeyframeAnimation<?, Float> getStart() {\n    return startAnimation;\n  }\n\n  public BaseKeyframeAnimation<?, Float> getEnd() {\n    return endAnimation;\n  }\n\n  public BaseKeyframeAnimation<?, Float> getOffset() {\n    return offsetAnimation;\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/java/com/airbnb/lottie/Utils.java",
    "content": "package com.airbnb.lottie;\n\nimport android.content.Context;\nimport android.graphics.Matrix;\nimport android.graphics.Path;\nimport android.graphics.PathMeasure;\nimport android.graphics.PointF;\nimport android.support.annotation.Nullable;\nimport android.util.DisplayMetrics;\nimport android.view.WindowManager;\n\nimport java.io.Closeable;\n\nfinal class Utils {\n  private static final PathMeasure pathMeasure = new PathMeasure();\n  private static final Path tempPath = new Path();\n  private static final Path tempPath2 = new Path();\n  private static DisplayMetrics displayMetrics;\n  private static final float[] points = new float[4];\n  private static final float SQRT_2 = (float) Math.sqrt(2);\n\n  private Utils() {}\n\n  static Path createPath(PointF startPoint, PointF endPoint, PointF cp1, PointF cp2) {\n    Path path = new Path();\n    path.moveTo(startPoint.x, startPoint.y);\n\n    if (cp1 != null && cp1.length() != 0 && cp2 != null && cp2.length() != 0) {\n      path.cubicTo(\n          startPoint.x + cp1.x, startPoint.y + cp1.y,\n          endPoint.x + cp2.x, endPoint.y + cp2.y,\n          endPoint.x, endPoint.y);\n    } else {\n      path.lineTo(endPoint.x, endPoint.y);\n    }\n    return path;\n  }\n\n  static void closeQuietly(Closeable closeable) {\n    if (closeable != null) {\n      try {\n        closeable.close();\n      } catch (RuntimeException rethrown) {\n        throw rethrown;\n      } catch (Exception ignored) {\n      }\n    }\n  }\n\n  static int getScreenWidth(Context context) {\n    if (displayMetrics == null) {\n      displayMetrics = new DisplayMetrics();\n    }\n    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);\n    wm.getDefaultDisplay().getMetrics(displayMetrics);\n    return displayMetrics.widthPixels;\n  }\n\n  static int getScreenHeight(Context context) {\n    if (displayMetrics == null) {\n      displayMetrics = new DisplayMetrics();\n    }\n    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);\n    wm.getDefaultDisplay().getMetrics(displayMetrics);\n    return displayMetrics.heightPixels;\n  }\n\n  static float getScale(Matrix matrix) {\n    points[0] = 0;\n    points[1] = 0;\n    // Use sqrt(2) so that the hypotenuse is of length 1.\n    points[2] = SQRT_2;\n    points[3] = SQRT_2;\n    matrix.mapPoints(points);\n    float dx = points[2] - points[0];\n    float dy = points[3] - points[1];\n\n    // TODO: figure out why the result needs to be divided by 2.\n    return (float) Math.hypot(dx, dy) / 2f;\n  }\n\n  static void applyTrimPathIfNeeded(Path path, @Nullable TrimPathContent trimPath) {\n    if (trimPath == null) {\n      return;\n    }\n\n    pathMeasure.setPath(path, false);\n\n    float length = pathMeasure.getLength();\n    float start = length * trimPath.getStart().getValue() / 100f;\n    float end = length * trimPath.getEnd().getValue() / 100f;\n    float newStart = Math.min(start, end);\n    float newEnd = Math.max(start, end);\n\n    float offset = trimPath.getOffset().getValue() / 360f * length;\n    newStart += offset;\n    newEnd += offset;\n\n    // If the trim path has rotated around the path, we need to shift it back.\n    if (newStart > length && newEnd > length) {\n      newStart %= length;\n      newEnd %= length;\n    }\n    if (newStart > newEnd) {\n      newStart -= length;\n    }\n\n    tempPath.reset();\n    pathMeasure.getSegment(\n        newStart,\n        newEnd,\n        tempPath,\n        true);\n\n    if (newEnd > length) {\n      tempPath2.reset();\n      pathMeasure.getSegment(\n          0,\n          newEnd % length,\n          tempPath2,\n          true);\n      tempPath.addPath(tempPath2);\n    } else if (newStart < 0) {\n      tempPath2.reset();\n      pathMeasure.getSegment(\n          length + newStart,\n          length,\n          tempPath2,\n          true);\n      tempPath.addPath(tempPath2);\n    }\n    path.set(tempPath);\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/res/values/attrs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <declare-styleable name=\"LottieAnimationView\">\n        <attr name=\"lottie_fileName\" format=\"string\"/>\n        <attr name=\"lottie_autoPlay\" format=\"boolean\" />\n        <attr name=\"lottie_loop\" format=\"boolean\" />\n        <attr name=\"lottie_imageAssetsFolder\" format=\"string\" />\n        <attr name=\"lottie_progress\" format=\"float\" />\n        <attr name=\"lottie_cacheStrategy\" format=\"enum\">\n            <enum name=\"none\" value=\"0\" />\n            <enum name=\"weak\" value=\"1\" />\n            <enum name=\"strong\" value=\"2\" />\n        </attr>\n    </declare-styleable>\n</resources>"
  },
  {
    "path": "atlas-demo/AtlasDemo/lottie/src/main/res/values/ids.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <item name=\"lottie_layer_name\" type=\"id\" />\n</resources>"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\ngroup = 'com.atlas.demo'\nversion = '1.0.0'\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion '26.0.2'\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile 'com.android.support:appcompat-v7:25.1.0'\n    compile 'com.android.support:support-v4:25.1.0'\n    compile 'com.android.support:recyclerview-v7:25.3.0'\n    compile 'com.android.support:design:25.3.0'\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/androidTest/java/com/taobao/middleware/ExampleInstrumentedTest.java",
    "content": "package com.taobao.middleware;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() throws Exception {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.taobao.middleware.test\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.taobao.middleware\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:supportsRtl=\"true\">\n        <activity\n            android:name=\".ItemListActivity\"\n            android:label=\"@string/title_item_list\"\n            android:theme=\"@style/AppTheme.NoActionBar\"></activity>\n        <activity\n            android:name=\".ItemDetailActivity\"\n            android:label=\"@string/title_item_detail\"\n            android:parentActivityName=\".ItemListActivity\"\n            android:theme=\"@style/AppTheme.NoActionBar\">\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/java/com/middleware/dialog/Button.java",
    "content": "package com.middleware.dialog;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.Bitmap.Config;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.graphics.Rect;\nimport android.graphics.drawable.GradientDrawable;\nimport android.graphics.drawable.LayerDrawable;\nimport android.util.AttributeSet;\nimport android.view.MotionEvent;\nimport android.widget.TextView;\n\nimport com.taobao.middleware.R;\n\n\npublic abstract class Button extends CustomView {\n\n\tfinal static String ANDROIDXML = \"http://schemas.android.com/apk/res/android\";\n\n\t// Complete in child class\n\tint minWidth;\n\tint minHeight;\n\tint background;\n\tfloat rippleSpeed = 12f;\n\tint rippleSize = 3;\n\tInteger rippleColor;\n\tOnClickListener onClickListener;\n\tboolean clickAfterRipple = true;\n\tint backgroundColor = Color.parseColor(\"#1E88E5\");\n\tTextView textButton;\n\n\tpublic Button(Context context, AttributeSet attrs) {\n\t\tsuper(context, attrs);\n\t\tsetDefaultProperties();\n\t\tclickAfterRipple = attrs.getAttributeBooleanValue(MATERIALDESIGNXML,\n\t\t\t\t\"animate\", true);\n\t\tsetAttributes(attrs);\n\t\tbeforeBackground = backgroundColor;\n\t\tif (rippleColor == null)\n\t\t\trippleColor = makePressColor();\n\t}\n\n\tprotected void setDefaultProperties() {\n\t\t// Min size\n\t\tsetMinimumHeight(Utils.dpToPx(minHeight, getResources()));\n\t\tsetMinimumWidth(Utils.dpToPx(minWidth, getResources()));\n\t\t// Background shape\n\t\tsetBackgroundResource(background);\n\t\tsetBackgroundColor(backgroundColor);\n\t}\n\n\t// Set atributtes of XML to View\n\tabstract protected void setAttributes(AttributeSet attrs);\n\n\t// ### RIPPLE EFFECT ###\n\n\tfloat x = -1, y = -1;\n\tfloat radius = -1;\n\n\t@Override\n\tpublic boolean onTouchEvent(MotionEvent event) {\n\t\tinvalidate();\n\t\tif (isEnabled()) {\n\t\t\tisLastTouch = true;\n\t\t\tif (event.getAction() == MotionEvent.ACTION_DOWN) {\n\t\t\t\tradius = getHeight() / rippleSize;\n\t\t\t\tx = event.getX();\n\t\t\t\ty = event.getY();\n\t\t\t} else if (event.getAction() == MotionEvent.ACTION_MOVE) {\n\t\t\t\tradius = getHeight() / rippleSize;\n\t\t\t\tx = event.getX();\n\t\t\t\ty = event.getY();\n\t\t\t\tif (!((event.getX() <= getWidth() && event.getX() >= 0) && (event\n\t\t\t\t\t\t.getY() <= getHeight() && event.getY() >= 0))) {\n\t\t\t\t\tisLastTouch = false;\n\t\t\t\t\tx = -1;\n\t\t\t\t\ty = -1;\n\t\t\t\t}\n\t\t\t} else if (event.getAction() == MotionEvent.ACTION_UP) {\n\t\t\t\tif ((event.getX() <= getWidth() && event.getX() >= 0)\n\t\t\t\t\t\t&& (event.getY() <= getHeight() && event.getY() >= 0)) {\n\t\t\t\t\tradius++;\n\t\t\t\t\tif (!clickAfterRipple && onClickListener != null) {\n\t\t\t\t\t\tonClickListener.onClick(this);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tisLastTouch = false;\n\t\t\t\t\tx = -1;\n\t\t\t\t\ty = -1;\n\t\t\t\t}\n\t\t\t} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {\n\t\t\t\tisLastTouch = false;\n\t\t\t\tx = -1;\n\t\t\t\ty = -1;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tprotected void onFocusChanged(boolean gainFocus, int direction,\n\t\t\tRect previouslyFocusedRect) {\n\t\tif (!gainFocus) {\n\t\t\tx = -1;\n\t\t\ty = -1;\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean onInterceptTouchEvent(MotionEvent ev) {\n\t\t// super.onInterceptTouchEvent(ev);\n\t\treturn true;\n\t}\n\n\tpublic Bitmap makeCircle() {\n\t\tBitmap output = Bitmap.createBitmap(\n\t\t\t\tgetWidth() - Utils.dpToPx(6, getResources()), getHeight()\n\t\t\t\t\t\t- Utils.dpToPx(7, getResources()), Config.ARGB_8888);\n\t\tCanvas canvas = new Canvas(output);\n\t\tcanvas.drawARGB(0, 0, 0, 0);\n\t\tPaint paint = new Paint();\n\t\tpaint.setAntiAlias(true);\n\t\tpaint.setColor(rippleColor);\n\t\tcanvas.drawCircle(x, y, radius, paint);\n\t\tif (radius > getHeight() / rippleSize)\n\t\t\tradius += rippleSpeed;\n\t\tif (radius >= getWidth()) {\n\t\t\tx = -1;\n\t\t\ty = -1;\n\t\t\tradius = getHeight() / rippleSize;\n\t\t\tif (onClickListener != null && clickAfterRipple)\n\t\t\t\tonClickListener.onClick(this);\n\t\t}\n\t\treturn output;\n\t}\n\n\t/**\n\t * Make a dark color to ripple effect\n\t *\n\t * @return\n\t */\n\tprotected int makePressColor() {\n\t\tint r = (this.backgroundColor >> 16) & 0xFF;\n\t\tint g = (this.backgroundColor >> 8) & 0xFF;\n\t\tint b = (this.backgroundColor >> 0) & 0xFF;\n\t\tr = (r - 30 < 0) ? 0 : r - 30;\n\t\tg = (g - 30 < 0) ? 0 : g - 30;\n\t\tb = (b - 30 < 0) ? 0 : b - 30;\n\t\treturn Color.rgb(r, g, b);\n\t}\n\n\t@Override\n\tpublic void setOnClickListener(OnClickListener l) {\n\t\tonClickListener = l;\n\t}\n\n\t// Set color of background\n\tpublic void setBackgroundColor(int color) {\n\t\tthis.backgroundColor = color;\n\t\tif (isEnabled())\n\t\t\tbeforeBackground = backgroundColor;\n\t\ttry {\n\t\t\tLayerDrawable layer = (LayerDrawable) getBackground();\n\t\t\tGradientDrawable shape = (GradientDrawable) layer\n\t\t\t\t\t.findDrawableByLayerId(R.id.shape_bacground);\n\t\t\tshape.setColor(backgroundColor);\n\t\t\trippleColor = makePressColor();\n\t\t} catch (Exception ex) {\n\t\t\t// Without bacground\n\t\t}\n\t}\n\n\tpublic void setRippleSpeed(float rippleSpeed) {\n\t\tthis.rippleSpeed = rippleSpeed;\n\t}\n\n\tpublic float getRippleSpeed() {\n\t\treturn this.rippleSpeed;\n\t}\n\n\tpublic void setText(String text) {\n\t\ttextButton.setText(text);\n\t}\n\n\tpublic void setTextColor(int color) {\n\t\ttextButton.setTextColor(color);\n\t}\n\n\tpublic TextView getTextView() {\n\t\treturn textButton;\n\t}\n\n\tpublic String getText() {\n\t\treturn textButton.getText().toString();\n\t}\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/java/com/middleware/dialog/ButtonFlat.java",
    "content": "package com.middleware.dialog;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.graphics.Typeface;\nimport android.util.AttributeSet;\nimport android.widget.RelativeLayout;\nimport android.widget.TextView;\n\nimport com.taobao.middleware.R;\n\n\npublic class ButtonFlat extends Button {\n\t\n\tTextView textButton;\n\n\tpublic ButtonFlat(Context context, AttributeSet attrs) {\n\t\tsuper(context, attrs);\n\t\t\n\t}\n\t\n\tprotected void setDefaultProperties(){\n\t\tminHeight = 36;\n\t\tminWidth = 88;\n\t\trippleSize = 3;\n\t\t// Min size\n\t\tsetMinimumHeight(Utils.dpToPx(minHeight, getResources()));\n\t\tsetMinimumWidth(Utils.dpToPx(minWidth, getResources()));\n\t\tsetBackgroundResource(R.drawable.background_transparent);\n\t}\n\n\t@Override\n\tprotected void setAttributes(AttributeSet attrs) {\n\t\t// Set text button\n\t\tString text = null;\n\t\tint textResource = attrs.getAttributeResourceValue(ANDROIDXML,\"text\",-1);\n\t\tif(textResource != -1){\n\t\t\ttext = getResources().getString(textResource);\n\t\t}else{\n\t\t\ttext = attrs.getAttributeValue(ANDROIDXML,\"text\");\n\t\t}\n\t\tif(text != null){\n\t\t\ttextButton = new TextView(getContext());\n\t\t\ttextButton.setText(text.toUpperCase());\n\t\t\ttextButton.setTextColor(backgroundColor);\n\t\t\ttextButton.setTypeface(null, Typeface.BOLD);\n\t\t\tLayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);\n\t\t\tparams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);\n\t\t\ttextButton.setLayoutParams(params);\n\t\t\taddView(textButton);\n\t\t}\n\t\tint bacgroundColor = attrs.getAttributeResourceValue(ANDROIDXML,\"background\",-1);\n\t\tif(bacgroundColor != -1){\n\t\t\tsetBackgroundColor(getResources().getColor(bacgroundColor));\n\t\t}else{\n\t\t\t// Color by hexadecimal\n\t\t\t// Color by hexadecimal\n\t\t\tbackground = attrs.getAttributeIntValue(ANDROIDXML, \"background\", -1);\n\t\t\tif (background != -1)\n\t\t\t\tsetBackgroundColor(background);\n\t\t}\n\t}\n\t\n\t\n\t@Override\n\tprotected void onDraw(Canvas canvas) {\n\t\tsuper.onDraw(canvas);\n\t\tif (x != -1) {\n\t\t\t\n\t\t\tPaint paint = new Paint();\n\t\t\tpaint.setAntiAlias(true);\n\t\t\tpaint.setColor(makePressColor());\n\t\t\tcanvas.drawCircle(x, y, radius, paint);\n\t\t\tif(radius > getHeight()/rippleSize)\n\t\t\t\tradius += rippleSpeed;\n\t\t\tif(radius >= getWidth()){\n\t\t\t\tx = -1;\n\t\t\t\ty = -1;\n\t\t\t\tradius = getHeight()/rippleSize;\n\t\t\t\tif(onClickListener != null&& clickAfterRipple)\n\t\t\t\t\tonClickListener.onClick(this);\n\t\t\t}\n\t\t\tinvalidate();\n\t\t}\t\t\n\t\t\n\t}\n\t\n\t/**\n\t * Make a dark color to ripple effect\n\t * @return\n\t */\n\t@Override\n\tprotected int makePressColor(){\n\t\treturn Color.parseColor(\"#88DDDDDD\");\n\t}\n\t\n\tpublic void setText(String text){\n\t\ttextButton.setText(text.toUpperCase());\n\t}\n\t\n\t// Set color of background\n\tpublic void setBackgroundColor(int color){\n\t\tbackgroundColor = color;\n\t\tif(isEnabled())\n\t\t\tbeforeBackground = backgroundColor;\n\t\ttextButton.setTextColor(color);\n\t}\n\n\t@Override\n\tpublic TextView getTextView() {\n\t\treturn textButton;\n\t}\n\t\n\tpublic String getText(){\n        \treturn textButton.getText().toString();\n \t}\n\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/java/com/middleware/dialog/CustomView.java",
    "content": "package com.middleware.dialog;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.util.AttributeSet;\nimport android.widget.RelativeLayout;\n\npublic class CustomView extends RelativeLayout {\n\t\n\t\n\tfinal static String MATERIALDESIGNXML = \"http://schemas.android.com/apk/res-auto\";\n\tfinal static String ANDROIDXML = \"http://schemas.android.com/apk/res/android\";\n\t\n\tfinal int disabledBackgroundColor = Color.parseColor(\"#E2E2E2\");\n\tint beforeBackground;\n\t\n\t// Indicate if user touched this view the last time\n\tpublic boolean isLastTouch = false;\n\n\tpublic CustomView(Context context, AttributeSet attrs) {\n\t\tsuper(context, attrs);\n\t}\n\t\n\t@Override\n\tpublic void setEnabled(boolean enabled) {\n\t\tsuper.setEnabled(enabled);\n\t\tif(enabled)\n\t\t\tsetBackgroundColor(beforeBackground);\n\t\telse\n\t\t\tsetBackgroundColor(disabledBackgroundColor);\n\t\tinvalidate();\n\t}\n\t\n\tboolean animation = false;\n\t\n\t@Override\n\tprotected void onAnimationStart() {\n\t\tsuper.onAnimationStart();\n\t\tanimation = true;\n\t}\n\t\n\t@Override\n\tprotected void onAnimationEnd() {\n\t\tsuper.onAnimationEnd();\n\t\tanimation = false;\n\t}\n\t\n\t@Override\n\tprotected void onDraw(Canvas canvas) {\n\t\tsuper.onDraw(canvas);\n\t\tif(animation)\n\t\t\tinvalidate();\n\t}\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/java/com/middleware/dialog/Dialog.java",
    "content": "package com.middleware.dialog;\n\nimport android.content.Context;\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.view.View.OnTouchListener;\nimport android.view.Window;\nimport android.view.animation.Animation;\nimport android.view.animation.Animation.AnimationListener;\nimport android.view.animation.AnimationUtils;\nimport android.widget.FrameLayout;\nimport android.widget.RelativeLayout;\nimport android.widget.TextView;\n\nimport com.taobao.middleware.R;\n\npublic class Dialog extends android.app.Dialog {\n\n    Context context;\n    View view;\n    View backView;\n    String message;\n    TextView messageTextView;\n    String title;\n    TextView titleTextView;\n\n    ButtonFlat buttonAccept;\n    ButtonFlat buttonCancel;\n\n    String buttonCancelText;\n    String buttonAcceptText;\n\n    View.OnClickListener onAcceptButtonClickListener;\n    View.OnClickListener onCancelButtonClickListener;\n\n    boolean clickBackViewToExit = true;\n\n    public Dialog(Context context, String title, String message) {\n        super(context, android.R.style.Theme_Translucent);\n        this.context = context;// init Context\n        this.message = message;\n        this.title = title;\n    }\n\n    public Dialog(Context context, String title, String message, boolean clickBackViewToExit) {\n        super(context, android.R.style.Theme_Translucent);\n        this.context = context;// init Context\n        this.message = message;\n        this.title = title;\n        this.clickBackViewToExit = clickBackViewToExit;\n    }\n\n    public void addCancelButton(String buttonCancelText) {\n        this.buttonCancelText = buttonCancelText;\n        if (buttonCancel != null) {\n            buttonCancel.setText(buttonCancelText);\n        }\n    }\n\n    public void addCancelButton(String buttonCancelText, View.OnClickListener onCancelButtonClickListener) {\n        this.buttonCancelText = buttonCancelText;\n        this.onCancelButtonClickListener = onCancelButtonClickListener;\n    }\n\n    public void addAcceptButton(String buttonAcceptText) {\n        this.buttonAcceptText = buttonAcceptText;\n        if (buttonAccept != null) {\n            buttonAccept.setText(buttonAcceptText);\n        }\n    }\n\n    public void addAcceptButton(String buttonAcceptText, View.OnClickListener onAcceptButtonClickListener) {\n        this.buttonAcceptText = buttonAcceptText;\n        this.onAcceptButtonClickListener = onAcceptButtonClickListener;\n    }\n\n    private View mCustomContentView;\n\n    @Override\n    public void setContentView(View view) {\n        mCustomContentView = view;\n    }\n\n    public View getContentView() {\n        return mCustomContentView;\n    }\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        requestWindowFeature(Window.FEATURE_NO_TITLE);\n        super.onCreate(savedInstanceState);\n\n        View dialogContent = LayoutInflater.from(getContext()).inflate(R.layout.update_dialog, null);\n        super.setContentView(dialogContent);\n\n        view = (RelativeLayout) findViewById(R.id.update_contentDialog);\n        backView = (FrameLayout) findViewById(R.id.update_dialog_rootView);\n        backView.setOnTouchListener(new OnTouchListener() {\n\n            @Override\n            public boolean onTouch(View v, MotionEvent event) {\n                if (event.getX() < view.getLeft()\n                        || event.getX() > view.getRight()\n                        || event.getY() > view.getBottom()\n                        || event.getY() < view.getTop()) {\n\n                    if (clickBackViewToExit) {\n                        if (null != onCancelButtonClickListener) {\n                            onCancelButtonClickListener.onClick(buttonCancel);\n                        }\n                        dismiss();\n                    }\n\n                }\n                return false;\n            }\n        });\n\n        this.titleTextView = (TextView) findViewById(R.id.update_title);\n        setTitle(title);\n\n        if (mCustomContentView != null) {\n            FrameLayout dialogContentFrame = (FrameLayout) findViewById(R.id.update_dialog_content);\n            dialogContentFrame.addView(mCustomContentView);\n            findViewById(R.id.message_scrollView).setVisibility(View.GONE);\n\n        } else {\n            this.messageTextView = (TextView) findViewById(R.id.update_message);\n            setMessage(message);\n        }\n\n//        this.buttonAccept = (ButtonFlat) findViewById(R.id.button_accept);\n//        buttonAccept.setOnClickListener(new View.OnClickListener() {\n//            @Override\n//            public void onClick(View v) {\n//                dismiss();\n//                if(onAcceptButtonClickListener != null)\n//                    onAcceptButtonClickListener.onClick(v);\n//            }\n//        });\n\n        if (buttonCancelText != null) {\n            this.buttonCancel = (ButtonFlat) findViewById(R.id.update_button_cancel);\n            this.buttonCancel.setVisibility(View.VISIBLE);\n            this.buttonCancel.setText(buttonCancelText);\n            buttonCancel.setOnClickListener(new View.OnClickListener() {\n\n                @Override\n                public void onClick(View v) {\n                    dismiss();\n                    if (onCancelButtonClickListener != null)\n                        onCancelButtonClickListener.onClick(v);\n                }\n            });\n        }\n\n        if (buttonAcceptText != null) {\n            this.buttonAccept = (ButtonFlat) findViewById(R.id.update_button_accept);\n            this.buttonAccept.setVisibility(View.VISIBLE);\n            this.buttonAccept.setText(buttonAcceptText);\n            buttonAccept.setOnClickListener(new View.OnClickListener() {\n\n                @Override\n                public void onClick(View v) {\n                    dismiss();\n                    if (onAcceptButtonClickListener != null)\n                        onAcceptButtonClickListener.onClick(v);\n                }\n            });\n        }\n\n    }\n\n    @Override\n    public void show() {\n        super.show();\n        // set update_dialog enter animations\n        view.startAnimation(AnimationUtils.loadAnimation(context.getApplicationContext(), R.anim.dialog_main_show_amination));\n        backView.startAnimation(AnimationUtils.loadAnimation(context.getApplicationContext(), R.anim.dialog_root_show_amin));\n    }\n\n    // GETERS & SETTERS\n\n    public String getMessage() {\n        return message;\n    }\n\n    public void setMessage(String message) {\n        this.message = message;\n        messageTextView.setText(message);\n    }\n\n    public TextView getMessageTextView() {\n        return messageTextView;\n    }\n\n    public void setMessageTextView(TextView messageTextView) {\n        this.messageTextView = messageTextView;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    public void setTitle(String title) {\n        this.title = title;\n        if (title == null)\n            titleTextView.setVisibility(View.GONE);\n        else {\n            titleTextView.setVisibility(View.VISIBLE);\n            titleTextView.setText(title);\n        }\n    }\n\n    public TextView getTitleTextView() {\n        return titleTextView;\n    }\n\n    public void setTitleTextView(TextView titleTextView) {\n        this.titleTextView = titleTextView;\n    }\n\n    public ButtonFlat getButtonAccept() {\n        return buttonAccept;\n    }\n\n    public void setButtonAccept(ButtonFlat buttonAccept) {\n        this.buttonAccept = buttonAccept;\n    }\n\n    public ButtonFlat getButtonCancel() {\n        return buttonCancel;\n    }\n\n    public void setButtonCancel(ButtonFlat buttonCancel) {\n        this.buttonCancel = buttonCancel;\n    }\n\n    public void setOnAcceptButtonClickListener(\n            View.OnClickListener onAcceptButtonClickListener) {\n        this.onAcceptButtonClickListener = onAcceptButtonClickListener;\n        if (buttonAccept != null)\n            buttonAccept.setOnClickListener(onAcceptButtonClickListener);\n    }\n\n    public void setOnCancelButtonClickListener(\n            View.OnClickListener onCancelButtonClickListener) {\n        this.onCancelButtonClickListener = onCancelButtonClickListener;\n        if (buttonCancel != null)\n            buttonCancel.setOnClickListener(onCancelButtonClickListener);\n    }\n\n    @Override\n    public void dismiss() {\n        Animation anim = AnimationUtils.loadAnimation(context.getApplicationContext(), R.anim.dialog_main_hide_amination);\n        anim.setAnimationListener(new AnimationListener() {\n\n            @Override\n            public void onAnimationStart(Animation animation) {\n            }\n\n            @Override\n            public void onAnimationRepeat(Animation animation) {\n            }\n\n            @Override\n            public void onAnimationEnd(Animation animation) {\n                view.post(new Runnable() {\n                    @Override\n                    public void run() {\n                        Dialog.super.dismiss();\n                    }\n                });\n\n            }\n        });\n        Animation backAnim = AnimationUtils.loadAnimation(context.getApplicationContext(), R.anim.dialog_root_hide_amin);\n\n        view.startAnimation(anim);\n        backView.startAnimation(backAnim);\n    }\n\n    @Override\n    public void onBackPressed() {\n        super.onBackPressed();\n        if (onCancelButtonClickListener != null)\n            onCancelButtonClickListener.onClick(null);\n    }\n}"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/java/com/middleware/dialog/Utils.java",
    "content": "package com.middleware.dialog;\n\nimport android.content.res.Resources;\nimport android.util.TypedValue;\n\n/**\n * Created by guanjie on 15/9/19.\n */\npublic class Utils {\n    /**\n     * Convert Dp to Pixel\n     */\n    public static int dpToPx(float dp, Resources resources){\n        float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, resources.getDisplayMetrics());\n        return (int) px;\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/java/com/taobao/middleware/ICaculator.java",
    "content": "package com.taobao.middleware;\n\n/**\n * Created by guanjie on 2017/12/8.\n */\n\npublic interface ICaculator {\n\n    int sum(int a,int b);\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/java/com/taobao/middleware/ItemDetailActivity.java",
    "content": "package com.taobao.middleware;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.design.widget.FloatingActionButton;\nimport android.support.design.widget.Snackbar;\nimport android.support.v7.widget.Toolbar;\nimport android.view.View;\nimport android.support.v7.app.AppCompatActivity;\nimport android.support.v7.app.ActionBar;\nimport android.support.v4.app.NavUtils;\nimport android.view.MenuItem;\n\n/**\n * An activity representing a single Item detail screen. This\n * activity is only used narrow width devices. On tablet-size devices,\n * item details are presented side-by-side with a list of items\n * in a {@link ItemListActivity}.\n */\npublic class ItemDetailActivity extends AppCompatActivity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_item_detail);\n        Toolbar toolbar = (Toolbar) findViewById(R.id.detail_toolbar);\n        setSupportActionBar(toolbar);\n\n        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);\n        fab.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                Snackbar.make(view, \"Replace with your own detail action\", Snackbar.LENGTH_LONG)\n                        .setAction(\"Action\", null).show();\n            }\n        });\n\n        // Show the Up button in the action bar.\n        ActionBar actionBar = getSupportActionBar();\n        if (actionBar != null) {\n            actionBar.setDisplayHomeAsUpEnabled(true);\n        }\n\n        // savedInstanceState is non-null when there is fragment state\n        // saved from previous configurations of this activity\n        // (e.g. when rotating the screen from portrait to landscape).\n        // In this case, the fragment will automatically be re-added\n        // to its container so we don't need to manually add it.\n        // For more information, see the Fragments API guide at:\n        //\n        // http://developer.android.com/guide/components/fragments.html\n        //\n        if (savedInstanceState == null) {\n            // Create the detail fragment and add it to the activity\n            // using a fragment transaction.\n            Bundle arguments = new Bundle();\n            arguments.putString(ItemDetailFragment.ARG_ITEM_ID,\n                    getIntent().getStringExtra(ItemDetailFragment.ARG_ITEM_ID));\n            ItemDetailFragment fragment = new ItemDetailFragment();\n            fragment.setArguments(arguments);\n            getSupportFragmentManager().beginTransaction()\n                    .add(R.id.item_detail_container, fragment)\n                    .commit();\n        }\n    }\n\n    @Override\n    public boolean onOptionsItemSelected(MenuItem item) {\n        int id = item.getItemId();\n        if (id == android.R.id.home) {\n            // This ID represents the Home or Up button. In the case of this\n            // activity, the Up button is shown. Use NavUtils to allow users\n            // to navigate up one level in the application structure. For\n            // more details, see the Navigation pattern on Android Design:\n            //\n            // http://developer.android.com/design/patterns/navigation.html#up-vs-back\n            //\n            NavUtils.navigateUpTo(this, new Intent(this, ItemListActivity.class));\n            return true;\n        }\n        return super.onOptionsItemSelected(item);\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/java/com/taobao/middleware/ItemDetailFragment.java",
    "content": "package com.taobao.middleware;\n\nimport android.app.Activity;\nimport android.support.design.widget.CollapsingToolbarLayout;\nimport android.os.Bundle;\nimport android.support.v4.app.Fragment;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.TextView;\n\nimport com.taobao.middleware.dummy.DummyContent;\n\n/**\n * A fragment representing a single Item detail screen.\n * This fragment is either contained in a {@link ItemListActivity}\n * in two-pane mode (on tablets) or a {@link ItemDetailActivity}\n * on handsets.\n */\npublic class ItemDetailFragment extends Fragment {\n    /**\n     * The fragment argument representing the item ID that this fragment\n     * represents.\n     */\n    public static final String ARG_ITEM_ID = \"item_id\";\n\n    /**\n     * The dummy content this fragment is presenting.\n     */\n    private DummyContent.DummyItem mItem;\n\n    /**\n     * Mandatory empty constructor for the fragment manager to instantiate the\n     * fragment (e.g. upon screen orientation changes).\n     */\n    public ItemDetailFragment() {\n    }\n\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n\n        if (getArguments().containsKey(ARG_ITEM_ID)) {\n            // Load the dummy content specified by the fragment\n            // arguments. In a real-world scenario, use a Loader\n            // to load content from a content provider.\n            mItem = DummyContent.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID));\n\n            Activity activity = this.getActivity();\n            CollapsingToolbarLayout appBarLayout = (CollapsingToolbarLayout) activity.findViewById(R.id.toolbar_layout);\n            if (appBarLayout != null) {\n                appBarLayout.setTitle(mItem.content);\n            }\n        }\n    }\n\n    @Override\n    public View onCreateView(LayoutInflater inflater, ViewGroup container,\n                             Bundle savedInstanceState) {\n        View rootView = inflater.inflate(R.layout.item_detail, container, false);\n\n        // Show the dummy content as text in a TextView.\n        if (mItem != null) {\n            ((TextView) rootView.findViewById(R.id.item_detail)).setText(mItem.details);\n        }\n\n        return rootView;\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/java/com/taobao/middleware/ItemListActivity.java",
    "content": "package com.taobao.middleware;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.annotation.NonNull;\nimport android.support.v7.app.AppCompatActivity;\nimport android.support.v7.widget.RecyclerView;\nimport android.support.v7.widget.Toolbar;\nimport android.support.design.widget.FloatingActionButton;\nimport android.support.design.widget.Snackbar;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.TextView;\n\n\nimport com.taobao.middleware.dummy.DummyContent;\n\nimport java.util.List;\n\n/**\n * An activity representing a list of Items. This activity\n * has different presentations for handset and tablet-size devices. On\n * handsets, the activity presents a list of items, which when touched,\n * lead to a {@link ItemDetailActivity} representing\n * item details. On tablets, the activity presents the list of items and\n * item details side-by-side using two vertical panes.\n */\npublic class ItemListActivity extends AppCompatActivity {\n\n    /**\n     * Whether or not the activity is in two-pane mode, i.e. running on a tablet\n     * device.\n     */\n    private boolean mTwoPane;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_item_list);\n\n        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);\n        setSupportActionBar(toolbar);\n        toolbar.setTitle(getTitle());\n\n        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);\n        fab.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                Snackbar.make(view, \"Replace with your own action\", Snackbar.LENGTH_LONG)\n                        .setAction(\"Action\", null).show();\n            }\n        });\n\n        View recyclerView = findViewById(R.id.item_list);\n        assert recyclerView != null;\n        setupRecyclerView((RecyclerView) recyclerView);\n\n        if (findViewById(R.id.item_detail_container) != null) {\n            // The detail container view will be present only in the\n            // large-screen layouts (res/values-w900dp).\n            // If this view is present, then the\n            // activity should be in two-pane mode.\n            mTwoPane = true;\n        }\n    }\n\n    private void setupRecyclerView(@NonNull RecyclerView recyclerView) {\n        recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(DummyContent.ITEMS));\n    }\n\n    public class SimpleItemRecyclerViewAdapter\n            extends RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder> {\n\n        private final List<DummyContent.DummyItem> mValues;\n\n        public SimpleItemRecyclerViewAdapter(List<DummyContent.DummyItem> items) {\n            mValues = items;\n        }\n\n        @Override\n        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {\n            View view = LayoutInflater.from(parent.getContext())\n                    .inflate(R.layout.item_list_content, parent, false);\n            return new ViewHolder(view);\n        }\n\n        @Override\n        public void onBindViewHolder(final ViewHolder holder, int position) {\n            holder.mItem = mValues.get(position);\n            holder.mIdView.setText(mValues.get(position).id);\n            holder.mContentView.setText(mValues.get(position).content);\n\n            holder.mView.setOnClickListener(new View.OnClickListener() {\n                @Override\n                public void onClick(View v) {\n                    if (mTwoPane) {\n                        Bundle arguments = new Bundle();\n                        arguments.putString(ItemDetailFragment.ARG_ITEM_ID, holder.mItem.id);\n                        ItemDetailFragment fragment = new ItemDetailFragment();\n                        fragment.setArguments(arguments);\n                        getSupportFragmentManager().beginTransaction()\n                                .replace(R.id.item_detail_container, fragment)\n                                .commit();\n                    } else {\n                        Context context = v.getContext();\n                        Intent intent = new Intent(context, ItemDetailActivity.class);\n                        intent.putExtra(ItemDetailFragment.ARG_ITEM_ID, holder.mItem.id);\n\n                        context.startActivity(intent);\n                    }\n                }\n            });\n        }\n\n        @Override\n        public int getItemCount() {\n            return mValues.size();\n        }\n\n        public class ViewHolder extends RecyclerView.ViewHolder {\n            public final View mView;\n            public final TextView mIdView;\n            public final TextView mContentView;\n            public DummyContent.DummyItem mItem;\n\n            public ViewHolder(View view) {\n                super(view);\n                mView = view;\n                mIdView = (TextView) view.findViewById(R.id.id);\n                mContentView = (TextView) view.findViewById(R.id.content);\n            }\n\n            @Override\n            public String toString() {\n                return super.toString() + \" '\" + mContentView.getText() + \"'\";\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/java/com/taobao/middleware/StringUtil.java",
    "content": "package com.taobao.middleware;\n\nimport android.text.TextUtils;\n\n/**\n * Created by guanjie on 2017/3/16.\n */\n\npublic class StringUtil {\n    public boolean isEmpty(String str){\n        return TextUtils.isEmpty(str);\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/java/com/taobao/middleware/dummy/DummyContent.java",
    "content": "package com.taobao.middleware.dummy;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Helper class for providing sample content for user interfaces created by\n * Android template wizards.\n * <p>\n * TODO: Replace all uses of this class before publishing your app.\n */\npublic class DummyContent {\n\n    /**\n     * An array of sample (dummy) items.\n     */\n    public static final List<DummyItem> ITEMS = new ArrayList<DummyItem>();\n\n    /**\n     * A map of sample (dummy) items, by ID.\n     */\n    public static final Map<String, DummyItem> ITEM_MAP = new HashMap<String, DummyItem>();\n\n    private static final int COUNT = 25;\n\n    static {\n        // Add some sample items.\n        for (int i = 1; i <= COUNT; i++) {\n            addItem(createDummyItem(i));\n        }\n    }\n\n    private static void addItem(DummyItem item) {\n        ITEMS.add(item);\n        ITEM_MAP.put(item.id, item);\n    }\n\n    private static DummyItem createDummyItem(int position) {\n        return new DummyItem(String.valueOf(position), \"Item \" + position, makeDetails(position));\n    }\n\n    private static String makeDetails(int position) {\n        StringBuilder builder = new StringBuilder();\n        builder.append(\"Details about Item: \").append(position);\n        for (int i = 0; i < position; i++) {\n            builder.append(\"\\nMore details information here.\");\n        }\n        return builder.toString();\n    }\n\n    /**\n     * A dummy item representing a piece of content.\n     */\n    public static class DummyItem {\n        public final String id;\n        public final String content;\n        public final String details;\n\n        public DummyItem(String id, String content, String details) {\n            this.id = id;\n            this.content = content;\n            this.details = details;\n        }\n\n        @Override\n        public String toString() {\n            return content;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/anim/dialog_main_hide_amination.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>  \n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:interpolator=\"@android:anim/accelerate_interpolator\"\n\tandroid:shareInterpolator=\"true\"\n\tandroid:startOffset=\"50\">  \n\n    <alpha\n        android:duration=\"200\"\n        android:fromAlpha=\"1.0\"\n        android:toAlpha=\"0.0\" />\n  \n        <scale\n        android:fromXScale=\"1.0\"\n        android:toXScale=\"0.8\"\n        android:fromYScale=\"1.0\"\n        android:toYScale=\"0.8\"\n        android:pivotX=\"50%\"\n        android:pivotY=\"50%\"\n        android:duration=\"200\"/>\n    \n</set> \n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/anim/dialog_main_show_amination.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <alpha\n        android:duration=\"200\"\n        android:fromAlpha=\"0.0\"\n        android:toAlpha=\"1.0\" />\n\n    <scale\n        android:duration=\"200\"\n        android:fromXScale=\"0.8\"\n        android:fromYScale=\"0.8\"\n        android:pivotX=\"50%\"\n        android:pivotY=\"50%\"\n        android:toXScale=\"1.0\"\n        android:toYScale=\"1.0\" />\n\n</set>"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/anim/dialog_root_hide_amin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>  \n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:interpolator=\"@android:anim/accelerate_interpolator\"\n\tandroid:shareInterpolator=\"true\"\n\tandroid:startOffset=\"50\">  \n    <alpha  \n        android:fromAlpha=\"1.0\"  \n        android:toAlpha=\"0.0\"  \n        android:duration=\"200\" />  \n</set> \n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/anim/dialog_root_show_amin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>  \n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">  \n    <alpha  \n        android:fromAlpha=\"0.0\"  \n        android:toAlpha=\"1.0\"  \n        android:duration=\"200\" />  \n</set> \n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/drawable/background_transparent.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n    <item android:id=\"@+id/shape_bacground\">\n        <shape android:shape=\"rectangle\" >\n            <corners android:radius=\"2dp\" />\n\n            <solid android:color=\"#00000000\" />\n        </shape>\n    </item>\n\n</layer-list>"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/layout/activity_item_detail.xml",
    "content": "<android.support.design.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:fitsSystemWindows=\"true\"\n    tools:context=\"com.taobao.middleware.ItemDetailActivity\"\n    tools:ignore=\"MergeRootFrame\">\n\n    <android.support.design.widget.AppBarLayout\n        android:id=\"@+id/app_bar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"@dimen/app_bar_height\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/ThemeOverlay.AppCompat.Dark.ActionBar\">\n\n        <android.support.design.widget.CollapsingToolbarLayout\n            android:id=\"@+id/toolbar_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:fitsSystemWindows=\"true\"\n            app:contentScrim=\"?attr/colorPrimary\"\n            app:layout_scrollFlags=\"scroll|exitUntilCollapsed\"\n            app:toolbarId=\"@+id/toolbar\">\n\n            <android.support.v7.widget.Toolbar\n                android:id=\"@+id/detail_toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?attr/actionBarSize\"\n                app:layout_collapseMode=\"pin\"\n                app:popupTheme=\"@style/ThemeOverlay.AppCompat.Light\" />\n\n        </android.support.design.widget.CollapsingToolbarLayout>\n\n    </android.support.design.widget.AppBarLayout>\n\n    <android.support.v4.widget.NestedScrollView\n        android:id=\"@+id/item_detail_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\" />\n\n    <android.support.design.widget.FloatingActionButton\n        android:id=\"@+id/fab\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center_vertical|start\"\n        android:layout_margin=\"@dimen/fab_margin\"\n        app:layout_anchor=\"@+id/item_detail_container\"\n        app:layout_anchorGravity=\"top|end\"\n        app:srcCompat=\"@android:drawable/stat_notify_chat\" />\n\n</android.support.design.widget.CoordinatorLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/layout/activity_item_list.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.design.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:fitsSystemWindows=\"true\"\n    tools:context=\"com.taobao.middleware.ItemListActivity\">\n\n    <android.support.design.widget.AppBarLayout\n        android:id=\"@+id/app_bar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <android.support.v7.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?attr/actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\" />\n\n    </android.support.design.widget.AppBarLayout>\n\n    <FrameLayout\n        android:id=\"@+id/frameLayout\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <include layout=\"@layout/item_list\" />\n    </FrameLayout>\n\n    <android.support.design.widget.FloatingActionButton\n        android:id=\"@+id/fab\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom|end\"\n        android:layout_margin=\"@dimen/fab_margin\"\n        app:srcCompat=\"@android:drawable/ic_dialog_email\" />\n\n\n</android.support.design.widget.CoordinatorLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/layout/item_detail.xml",
    "content": "<TextView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/item_detail\"\n    style=\"?android:attr/textAppearanceLarge\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:padding=\"16dp\"\n    android:textIsSelectable=\"true\"\n    tools:context=\"com.taobao.middleware.ItemDetailFragment\" />\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/layout/item_list.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.v7.widget.RecyclerView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/item_list\"\n    android:name=\"com.taobao.middleware.ItemListFragment\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:layout_marginLeft=\"16dp\"\n    android:layout_marginRight=\"16dp\"\n    app:layoutManager=\"LinearLayoutManager\"\n    tools:context=\"com.taobao.middleware.ItemListActivity\"\n    tools:listitem=\"@layout/item_list_content\" />\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/layout/item_list_content.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"horizontal\">\n\n    <TextView\n        android:id=\"@+id/id\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"@dimen/text_margin\"\n        android:textAppearance=\"?attr/textAppearanceListItem\" />\n\n    <TextView\n        android:id=\"@+id/content\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"@dimen/text_margin\"\n        android:textAppearance=\"?attr/textAppearanceListItem\" />\n</LinearLayout>"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/layout/update_dialog.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/update_dialog_rootView\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"#55000000\"\n    android:padding=\"42dp\" >\n\n    <RelativeLayout\n        android:id=\"@+id/update_contentDialog\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:gravity=\"center\"\n        android:layout_gravity=\"center\"\n        android:background=\"@drawable/dialog_background\"\n        android:padding=\"32dp\">\n\n        <TextView\n            android:id=\"@+id/update_title\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginBottom=\"16dp\"\n            android:text=\"提示\"\n            android:textAppearance=\"?android:attr/textAppearanceMedium\"\n            android:textColor=\"#3e3e3e\" />\n        <FrameLayout\n                android:id=\"@+id/update_dialog_content\"\n                android:layout_below=\"@id/update_title\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:paddingBottom=\"32dp\">\n            <ScrollView\n                    android:id=\"@+id/message_scrollView\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:scrollbarSize=\"2dp\"\n                    android:scrollbarThumbVertical=\"@color/thumbColor\">\n\n                <LinearLayout\n                        android:layout_width=\"match_parent\"\n                        android:layout_height=\"match_parent\"\n                        android:orientation=\"vertical\">\n\n                    <TextView\n                            android:id=\"@+id/update_message\"\n                            android:layout_width=\"wrap_content\"\n                            android:layout_height=\"wrap_content\"\n                            android:text=\"有更新内容\"\n                            android:textColor=\"#3e3e3e\"\n                            android:textSize=\"14dp\"/>\n                </LinearLayout>\n            </ScrollView>\n        </FrameLayout>\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignBottom=\"@id/update_dialog_content\"\n            android:layout_marginTop=\"12dp\"\n            android:gravity=\"right\"\n            android:orientation=\"horizontal\" >\n\n            <com.middleware.dialog.ButtonFlat\n                android:id=\"@+id/update_button_cancel\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"取消\"\n                android:background=\"#555555\"\n                android:visibility=\"gone\" />\n\n            <com.middleware.dialog.ButtonFlat\n                android:id=\"@+id/update_button_accept\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"确定\"\n                android:background=\"#1E88E5\"\n                android:visibility=\"gone\" />\n        </LinearLayout>\n    </RelativeLayout>\n\n</FrameLayout>"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/layout-w900dp/item_list.xml",
    "content": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:layout_marginLeft=\"16dp\"\n    android:layout_marginRight=\"16dp\"\n    android:baselineAligned=\"false\"\n    android:divider=\"?android:attr/dividerHorizontal\"\n    android:orientation=\"horizontal\"\n    android:showDividers=\"middle\"\n    tools:context=\"com.taobao.middleware.ItemListActivity\">\n\n    <!--\n    This layout is a two-pane layout for the Items\n    master/detail flow.\n    \n    -->\n\n    <android.support.v7.widget.RecyclerView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        xmlns:tools=\"http://schemas.android.com/tools\"\n        android:id=\"@+id/item_list\"\n        android:name=\"com.taobao.middleware.ItemListFragment\"\n        android:layout_width=\"@dimen/item_width\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginLeft=\"16dp\"\n        android:layout_marginRight=\"16dp\"\n        app:layoutManager=\"LinearLayoutManager\"\n        tools:context=\"com.taobao.middleware.ItemListActivity\"\n        tools:listitem=\"@layout/item_list_content\" />\n\n    <FrameLayout\n        android:id=\"@+id/item_detail_container\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"match_parent\"\n        android:layout_weight=\"3\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n\n    <color name=\"transparent\">#00000000</color>\n    <color name=\"B_A\">#F9F9F9</color>\n    <color name=\"F_black_light_4\">#FF999999</color>\n    <color name=\"E_black_light_3\">#FF666666</color>\n    <color name=\"C_white\">#FFFFFFFF</color>\n    <color name=\"K_black_light_6\">#FFE5E5E5</color>\n    <color name=\"thumbColor\">#66aaaaaa</color>\n    <color name=\"orange\">#ff3e00</color>\n    <color name=\"H_orange_light_1\">#FFE55245</color>\n    <color name=\"T\">#BBBBBB</color>\n    <color name=\"G_black_light_5\">#CCCCCC</color>\n    <color name=\"G\">#cccccc</color>\n\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/values/dimens.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <dimen name=\"fab_margin\">16dp</dimen>\n    <dimen name=\"app_bar_height\">200dp</dimen>\n    <dimen name=\"item_width\">200dp</dimen>\n    <dimen name=\"text_margin\">16dp</dimen>\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"library_name\">MiddleWareLibrary</string>\n    <string name=\"title_item_list\">Items</string>\n    <string name=\"title_item_detail\">Item Detail</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n    <style name=\"AppTheme.NoActionBar\">\n        <item name=\"windowActionBar\">false</item>\n        <item name=\"windowNoTitle\">true</item>\n    </style>\n\n    <style name=\"AppTheme.AppBarOverlay\" parent=\"ThemeOverlay.AppCompat.Dark.ActionBar\" />\n\n    <style name=\"AppTheme.PopupOverlay\" parent=\"ThemeOverlay.AppCompat.Light\" />\n\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/middlewarelibrary/src/test/java/com/taobao/middleware/ExampleUnitTest.java",
    "content": "package com.taobao.middleware;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "atlas-demo/AtlasDemo/publicbundle/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/publicbundle/build.gradle",
    "content": "apply plugin: 'com.taobao.atlas.library'\n\natlas {\n    bundleConfig{\n        awbBundle true\n    }\n}\n\ngroup = 'com.atlas.demo'\nversion = '1.0.0'\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion '26.0.2'\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n        //bundle的自有配置\n        consumerProguardFiles 'proguard-rules.pro'\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile 'com.android.support:appcompat-v7:25.1.0'\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/publicbundle/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n-keep class com.taobao.publicBundle.Tools {*;}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/publicbundle/src/androidTest/java/com/taobao/publicBundle/ExampleInstrumentedTest.java",
    "content": "package com.taobao.publicBundle;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() throws Exception {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.taobao.publicBundle.test\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/publicbundle/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\n    package=\"com.taobao.publicBundle\">\n\n    <application android:allowBackup=\"true\"\n        android:supportsRtl=\"true\">\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/publicbundle/src/main/java/com/taobao/publicBundle/Tools.java",
    "content": "package com.taobao.publicBundle;\n\n/**\n * Created by guanjie on 2017/3/21.\n */\n\npublic class Tools {\n\n    public static long getCurrentTime(){\n        return System.currentTimeMillis();\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/publicbundle/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"public_name\">PublicBundle</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/publicbundle/src/test/java/com/taobao/publicBundle/ExampleUnitTest.java",
    "content": "package com.taobao.publicBundle;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "atlas-demo/AtlasDemo/remotebundle/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/remotebundle/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'com.taobao.atlas'\n\natlas.bundleConfig.awbBundle = true\n\n\ngroup = 'com.atlas.demo'\nversion = '1.0.0'\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion '26.0.2'\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    providedCompile project(':middlewarelibrary')\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/remotebundle/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/remotebundle/src/androidTest/java/com/taobao/remotebunle/ExampleInstrumentedTest.java",
    "content": "package com.taobao.remotebunle;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() throws Exception {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.taobao.remotebunle.test\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/remotebundle/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.taobao.remotebunle\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:supportsRtl=\"true\">\n        <activity android:name=\".RemoteBundleActivity\"\n            android:theme=\"@style/AppTheme.NoActionBar\"\n            ></activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "atlas-demo/AtlasDemo/remotebundle/src/main/java/com/taobao/remotebunle/RemoteBundleActivity.java",
    "content": "package com.taobao.remotebunle;\n\nimport android.app.Activity;\nimport android.os.Bundle;\n\npublic class RemoteBundleActivity extends Activity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_remote_bundle);\n\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/remotebundle/src/main/res/layout/activity_remote_bundle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"horizontal\">\n\n    <TextView\n\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"this is remote bundle activity\" />\n\n\n</LinearLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/remotebundle/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">RemoteBundle</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/remotebundle/src/test/java/com/taobao/remotebunle/ExampleUnitTest.java",
    "content": "package com.taobao.remotebunle;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'com.taobao.atlas'\n\natlas {\n    bundleConfig{\n        awbBundle true\n    }\n}\ngroup = 'com.atlas.demo'\nversion = '1.0.0'\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion '26.0.2'\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile project(\":secondbundlelibrary\")\n    providedCompile 'com.android.support:appcompat-v7:25.1.0'\n    providedCompile 'com.android.support:support-v4:25.3.0'\n\n//    providedCompile 'com.taobao.android:atlas_core:5.0.8.0-rc45@aar'\n    providedCompile 'com.android.support.constraint:constraint-layout:1.0.2'\n    providedCompile project(':middlewarelibrary')\n\n    providedCompile project(':atlas_core')\n\n\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.taobao.secondbundle\">\n\n    <!-- To access Google+ APIs: -->\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n\n    <application\n            android:name=\".SecondBundleApplication\"\n        android:allowBackup=\"true\"\n        android:supportsRtl=\"true\">\n        <activity\n            android:theme=\"@style/AppTheme.NoActionBar\"\n            android:name=\"com.taobao.secondbundle.SecondBundleActivity\"></activity>\n\n    </application>\n\n</manifest>"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/src/main/java/com/taobao/secondbundle/MyRichView.java",
    "content": "package com.taobao.secondbundle;\n\nimport android.content.Context;\nimport android.support.annotation.Nullable;\nimport android.util.AttributeSet;\nimport android.widget.TextView;\n\n/**\n * Created by guanjie on 2017/11/14.\n */\n\npublic class MyRichView extends TextView{\n    public MyRichView(Context context) {\n        super(context);\n    }\n\n    public MyRichView(Context context, @Nullable AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    public MyRichView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {\n        super(context, attrs, defStyleAttr);\n    }\n\n    public MyRichView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {\n        super(context, attrs, defStyleAttr, defStyleRes);\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/src/main/java/com/taobao/secondbundle/PlusOneFragment.java",
    "content": "package com.taobao.secondbundle;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.support.v4.app.Fragment;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport com.taobao.secondbundle.R;\nimport com.taobao.secondbundlelibrary.SecondbundleShareActivity;\n\n/**\n * A fragment with a Google +1 button.\n * Activities that contain this fragment must implement the\n * {@link PlusOneFragment.OnFragmentInteractionListener} interface\n * to handle interaction events.\n * Use the {@link PlusOneFragment#newInstance} factory method to\n * create an instance of this fragment.\n */\npublic class PlusOneFragment extends Fragment{\n    // TODO: Rename parameter arguments, choose names that match\n    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER\n    private static final String ARG_PARAM1 = \"param1\";\n    private static final String ARG_PARAM2 = \"param2\";\n    // The request code must be 0 or greater.\n    private static final int PLUS_ONE_REQUEST_CODE = 0;\n    // The URL to +1.  Must be a valid URL.\n    private final String PLUS_ONE_URL = \"http://developer.android.com\";\n    // TODO: Rename and change types of parameters\n    private String mParam1;\n    private String mParam2;\n//    private PlusOneButton mPlusOneButton;\n\n    private OnFragmentInteractionListener mListener;\n\n    public PlusOneFragment() {\n        // Required empty public constructor\n    }\n\n    /**\n     * Use this factory method to create a new instance of\n     * this fragment using the provided parameters.\n     *\n     * @param param1 Parameter 1.\n     * @param param2 Parameter 2.\n     * @return A new instance of fragment PlusOneFragment.\n     */\n    // TODO: Rename and change types and number of parameters\n    public static PlusOneFragment newInstance(String param1, String param2) {\n        PlusOneFragment fragment = new PlusOneFragment();\n        Bundle args = new Bundle();\n        args.putString(ARG_PARAM1, param1);\n        args.putString(ARG_PARAM2, param2);\n        fragment.setArguments(args);\n        return fragment;\n    }\n\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        if (getArguments() != null) {\n            mParam1 = getArguments().getString(ARG_PARAM1);\n            mParam2 = getArguments().getString(ARG_PARAM2);\n        }\n    }\n\n    @Override\n    public View onCreateView(LayoutInflater inflater, ViewGroup container,\n                             Bundle savedInstanceState) {\n        // Inflate the layout for this fragment\n        View view = inflater.inflate(R.layout.fragment_plus_one, container, false);\n        view.findViewById(R.id.plus_one_button).setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                Intent intent = new Intent();\n                intent.setClass(view.getContext(), SecondbundleShareActivity.class);\n                startActivity(intent);\n            }\n        });\n\n        return view;\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n\n        // Refresh the state of the +1 button each time the activity receives focus.\n//        mPlusOneButton.initialize(PLUS_ONE_URL, PLUS_ONE_REQUEST_CODE);\n    }\n\n    // TODO: Rename method, update argument and hook method into UI event\n    public void onButtonPressed(Uri uri) {\n        if (mListener != null) {\n            mListener.onFragmentInteraction(uri);\n        }\n    }\n\n    @Override\n    public void onAttach(Context context) {\n        super.onAttach(context);\n        if (context instanceof OnFragmentInteractionListener) {\n            mListener = (OnFragmentInteractionListener) context;\n        } else {\n//            throw new RuntimeException(context.toString()\n//                    + \" must implement OnFragmentInteractionListener\");\n        }\n    }\n\n    @Override\n    public void onDetach() {\n        super.onDetach();\n        mListener = null;\n    }\n\n    /**\n     * This interface must be implemented by activities that contain this\n     * fragment to allow an interaction in this fragment to be communicated\n     * to the activity and potentially other fragments contained in that\n     * activity.\n     * <p>\n     * See the Android Training lesson <a href=\n     * \"http://developer.android.com/training/basics/fragments/communicating.html\"\n     * >Communicating with Other Fragments</a> for more information.\n     */\n    public interface OnFragmentInteractionListener {\n        // TODO: Update argument type and name\n        void onFragmentInteraction(Uri uri);\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/src/main/java/com/taobao/secondbundle/SecondBundleActivity.java",
    "content": "package com.taobao.secondbundle;\n\nimport android.net.Uri;\nimport android.support.v7.app.AppCompatActivity;\nimport android.os.Bundle;\nimport android.widget.Toast;\n\nimport com.taobao.secondbundle.R;\n\npublic class SecondBundleActivity extends AppCompatActivity implements PlusOneFragment.OnFragmentInteractionListener {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_secondbundle);\n\n        Toast.makeText(this,  SecondBundleApplication.secondBundleIniter.getApplication().toString(), Toast.LENGTH_LONG).show();\n\n\n    }\n\n    @Override\n    public void onFragmentInteraction(Uri uri) {\n\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/src/main/java/com/taobao/secondbundle/SecondBundleApplication.java",
    "content": "package com.taobao.secondbundle;\n\nimport android.app.Application;\n\n/**\n * 创建日期：2019/4/8 on 下午2:21\n * 描述:\n * 作者:zhayu.ll\n */\npublic class SecondBundleApplication extends Application {\n\n    public static SecondBundleIniter secondBundleIniter;\n    // here is the second bundle init method\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        secondBundleIniter = new SecondBundleIniter();\n        secondBundleIniter.init(this);\n\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/src/main/java/com/taobao/secondbundle/SecondBundleFragment.java",
    "content": "package com.taobao.secondbundle;\n\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.support.v4.app.Fragment;\nimport android.support.v7.app.AppCompatActivity;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\npublic class SecondBundleFragment extends Fragment{\n\n\n    @Override\n    public View onCreateView(LayoutInflater inflater, ViewGroup container,\n            Bundle savedInstanceState) {\n        View rootView = inflater.inflate(R.layout.activity_secondbundle, container, false);\n\n\n        return rootView;\n    }\n\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/src/main/java/com/taobao/secondbundle/SecondBundleIniter.java",
    "content": "package com.taobao.secondbundle;\n\nimport android.app.Application;\n\n/**\n * 创建日期：2019/4/8 on 下午2:25\n * 描述:\n * 作者:zhayu.ll\n */\npublic class SecondBundleIniter {\n\n\n    private Application application;\n\n\n    public void init(Application application){\n\n        this.application = application;\n    }\n\n\n    public Application getApplication(){\n\n        return application;\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/src/main/res/layout/activity_secondbundle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.taobao.secondbundle.SecondBundleActivity\">\n\n    <fragment\n        android:id=\"@+id/fragment_hello\"\n        android:name=\"com.taobao.secondbundle.PlusOneFragment\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\" />\n\n</FrameLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/src/main/res/layout/fragment_plus_one.xml",
    "content": "<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    >\n\n    <Button\n        android:id=\"@+id/plus_one_button\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"去这个Bundle的aar的Activity\"\n         />\n\n</FrameLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/src/main/res/layout/test_layout.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"vertical\" android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <com.taobao.secondbundle.MyRichView\n        android:id=\"@+id/cccc\"\n        android:layout_width=\"100dp\"\n        android:layout_height=\"100dp\"\n        android:textSize=\"18dp\"\n        android:text=\"不要激动\">\n        </com.taobao.secondbundle.MyRichView>\n</LinearLayout>"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">SecondBundle</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundle/src/test/java/com/taobao/secondbundle/ExampleUnitTest.java",
    "content": "package com.taobao.secondbundle;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundlelibrary/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundlelibrary/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\ngroup = 'com.atlas.demo'\nversion = '1.0.0'\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion \"26.0.2\"\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {\n        exclude group: 'com.android.support', module: 'support-annotations'\n    })\n    compile 'com.android.support:appcompat-v7:25.3.0'\n    compile 'com.android.support.constraint:constraint-layout:1.0.2'\n    testCompile 'junit:junit:4.12'\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundlelibrary/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundlelibrary/src/androidTest/java/com/taobao/secondbundlelibrary/ExampleInstrumentedTest.java",
    "content": "package com.taobao.secondbundlelibrary;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() throws Exception {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.taobao.secondbundlelibrary.test\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundlelibrary/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.taobao.secondbundlelibrary\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:supportsRtl=\"true\">\n        <activity android:name=\".SecondbundleShareActivity\"\n            android:theme=\"@style/Theme.AppCompat.Light\"></activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundlelibrary/src/main/java/com/taobao/secondbundlelibrary/SecondbundleShareActivity.java",
    "content": "package com.taobao.secondbundlelibrary;\n\nimport android.support.v7.app.AppCompatActivity;\nimport android.os.Bundle;\n\npublic class SecondbundleShareActivity extends AppCompatActivity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_secondbundle_share);\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundlelibrary/src/main/res/layout/activity_secondbundle_share.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n<TextView\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:textSize=\"20dp\"\n    android:text=\"this is a Activity from second bundle's library\">\n    </TextView>\n</FrameLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundlelibrary/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">SecondBundleLibrary</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/secondbundlelibrary/src/test/java/com/taobao/secondbundlelibrary/ExampleUnitTest.java",
    "content": "package com.taobao.secondbundlelibrary;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "atlas-demo/AtlasDemo/settings.gradle",
    "content": "include ':middlewarelibrary', ':databindinglibrary'\ninclude ':secondbundlelibrary'\ninclude ':lottie'\n//include ':activitygroupcompat'\ninclude ':firstbundle'\ninclude ':secondbundle'\ninclude ':publicbundle'\ninclude ':remotebundle'\ninclude ':databindbundle'\ninclude ':splashscreen'\ninclude ':app'\ninclude ':atlas_core'\nproject(':atlas_core').projectDir = file(\"../../atlas-core\")"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\ngroup = 'com.atlas.demo'\nversion = '1.0.1'\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion \"26.0.2\"\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile 'com.android.support:appcompat-v7:25.1.0'\n    compile project(':middlewarelibrary')\n    compile project(':lottie')\n\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/src/androidTest/java/com/taobao/splashscreen/ExampleInstrumentedTest.java",
    "content": "package com.taobao.splashscreen;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() throws Exception {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.taobao.splashscreen.test\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\n    package=\"com.taobao.splashscreen\">\n\n    <application android:allowBackup=\"true\"\n        android:supportsRtl=\"true\">\n\n        <activity\n            android:name=\".WelcomeActivity\"\n            android:configChanges=\"orientation|keyboardHidden|screenSize\"\n            android:theme=\"@style/FullscreenTheme\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/src/main/assets/A.json",
    "content": "{\"assets\":[],\"layers\":[{\"ddd\":0,\"ind\":0,\"ty\":4,\"nm\":\"smile\",\"parent\":10,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-90,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.714,\"y\":0.995},\"o\":{\"x\":0.323,\"y\":0},\"n\":\"0p714_0p995_0p323_0\",\"t\":1,\"s\":[{\"i\":[[0,0],[-10.378,0],[0,0]],\"o\":[[0,0],[10.378,0],[0,0]],\"v\":[[-17.75,13.562],[-0.466,7.938],[16,12.394]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-19.708,0],[0,0]],\"o\":[[0,0],[19.708,0],[0,0]],\"v\":[[-30.557,-0.854],[-0.099,5.41],[30.186,-1.101]],\"c\":false}]},{\"i\":{\"x\":0.52,\"y\":0.944},\"o\":{\"x\":0.122,\"y\":0.002},\"n\":\"0p52_0p944_0p122_0p002\",\"t\":5.5,\"s\":[{\"i\":[[0,0],[-19.708,0],[0,0]],\"o\":[[0,0],[19.708,0],[0,0]],\"v\":[[-30.557,-0.854],[-0.099,5.41],[30.186,-1.101]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-22.217,0],[0,0]],\"o\":[[0,0],[22.217,0],[0,0]],\"v\":[[-34,-4.73],[0,4.73],[34,-4.73]],\"c\":false}]},{\"t\":19}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":11.8,\"s\":[0,0.32,0.5,1],\"e\":[0,0.32,0.5,1]},{\"t\":25}]},\"o\":{\"k\":100},\"w\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":6.4,\"s\":[2],\"e\":[8]},{\"t\":13.599609375}]},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":1,\"op\":20,\"st\":-2,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":1,\"ty\":4,\"nm\":\"cap\",\"parent\":10,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":8,\"s\":[0],\"e\":[-4]},{\"t\":18.099609375}]},\"p\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[0,-160.338,0],\"e\":[0,-168.938,0],\"to\":[0,-1.43333327770233,0],\"ti\":[0,1.43333327770233,0]},{\"t\":18.099609375}]},\"a\":{\"k\":[0,-156.338,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[15.594,6.969],[9.216,-10.513],[-22.981,-10.513],[-30.517,10.492],[-2.884,10.504],[-2.884,10.513],[45.258,11.023],[45.258,7.479]],\"c\":true}},\"nm\":\"Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[6.024,-156.338],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":1,\"op\":20,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":2,\"ty\":4,\"nm\":\"glasses\",\"parent\":10,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8.2,\"s\":[0,-106,0],\"e\":[0,-126,0],\"to\":[0,-3.33333325386047,0],\"ti\":[0,3.33333325386047,0]},{\"t\":15.400390625}]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"hasMask\":true,\"masksProperties\":[{\"inv\":false,\"mode\":\"s\",\"pt\":{\"k\":{\"i\":[[6.099,0],[0.456,5.986],[0,0.299],[-0.022,0.293],[-6.101,0],[-0.456,-5.985],[0,-0.299],[0.022,-0.293]],\"o\":[[-6.101,0],[-0.022,-0.293],[0,-0.299],[0.456,-5.985],[6.099,0],[0.022,0.293],[0,0.299],[-0.456,5.986]],\"v\":[[-14.967,11.605],[-26.528,0.885],[-26.573,-0.001],[-26.528,-0.887],[-14.967,-11.605],[-3.408,-0.887],[-3.363,-0.001],[-3.408,0.885]],\"c\":true}},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 1\"},{\"inv\":false,\"mode\":\"s\",\"pt\":{\"k\":{\"i\":[[6.101,0],[0.455,5.986],[0,0.299],[-0.022,0.293],[-6.099,0],[-0.456,-5.985],[0,-0.299],[0.022,-0.293]],\"o\":[[-6.099,0],[-0.022,-0.293],[0,-0.299],[0.456,-5.985],[6.101,0],[0.022,0.293],[0,0.299],[-0.456,5.986]],\"v\":[[14.186,11.73],[2.627,1.01],[2.582,0.124],[2.627,-0.762],[14.186,-11.48],[25.747,-0.762],[25.792,0.124],[25.747,1.01]],\"c\":true}},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 2\"}],\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0,0],[7.077,0],[0.459,-6.963],[0,0],[7.077,0],[0.46,-6.963],[0,0],[0,0],[0,0],[-7.077,0],[-0.46,6.963],[0,0],[-7.077,0],[-0.46,6.963],[0,0],[0,0]],\"o\":[[-0.46,-6.963],[-7.077,0],[0,0],[-0.46,-6.963],[-7.077,0],[0,0],[0,0],[0,0],[0.46,6.963],[7.077,0],[0,0],[0.459,6.963],[7.077,0],[0,0],[0,0],[0,0]],\"v\":[[27.473,-0.887],[14.14,-13.377],[0.808,-0.887],[-1.651,-0.887],[-14.982,-13.377],[-28.315,-0.887],[-41.647,-0.887],[-41.647,0.885],[-28.315,0.885],[-14.982,13.377],[-1.651,0.885],[0.808,0.885],[14.14,13.377],[27.473,0.885],[41.647,0.885],[41.647,-0.887]],\"c\":true}},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"w\":{\"k\":6},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":1,\"op\":20,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":3,\"ty\":1,\"nm\":\"mask darkblue 2\",\"parent\":17,\"td\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[250,100,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"ef\":[{\"ty\":21,\"nm\":\"Fill\",\"mn\":\"ADBE Fill\",\"ix\":1,\"ef\":[{\"ty\":3,\"nm\":\"Fill Mask\",\"mn\":\"ADBE Fill-0001\",\"ix\":1,\"v\":{\"k\":0}},{\"ty\":7,\"nm\":\"All Masks\",\"mn\":\"ADBE Fill-0007\",\"ix\":2,\"v\":{\"k\":0}},{\"ty\":2,\"nm\":\"Color\",\"mn\":\"ADBE Fill-0002\",\"ix\":3,\"v\":{\"k\":[0,0,0.01,1]}},{\"ty\":7,\"nm\":\"Invert\",\"mn\":\"ADBE Fill-0006\",\"ix\":4,\"v\":{\"k\":0}},{\"ty\":0,\"nm\":\"Horizontal Feather\",\"mn\":\"ADBE Fill-0003\",\"ix\":5,\"v\":{\"k\":0}},{\"ty\":0,\"nm\":\"Vertical Feather\",\"mn\":\"ADBE Fill-0004\",\"ix\":6,\"v\":{\"k\":0}},{\"ty\":0,\"nm\":\"Opacity\",\"mn\":\"ADBE Fill-0005\",\"ix\":7,\"v\":{\"k\":1}}]}],\"sw\":500,\"sh\":600,\"sc\":\"#000000\",\"ip\":1,\"op\":20,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":4,\"ty\":4,\"nm\":\"darkblue 2\",\"parent\":10,\"tt\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,64.663,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.32,0.5,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":4,\"op\":20,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":5,\"ty\":1,\"nm\":\"mask darkblue\",\"parent\":17,\"td\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[250,100,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"ef\":[{\"ty\":21,\"nm\":\"Fill\",\"mn\":\"ADBE Fill\",\"ix\":1,\"ef\":[{\"ty\":3,\"nm\":\"Fill Mask\",\"mn\":\"ADBE Fill-0001\",\"ix\":1,\"v\":{\"k\":0}},{\"ty\":7,\"nm\":\"All Masks\",\"mn\":\"ADBE Fill-0007\",\"ix\":2,\"v\":{\"k\":0}},{\"ty\":2,\"nm\":\"Color\",\"mn\":\"ADBE Fill-0002\",\"ix\":3,\"v\":{\"k\":[0,0,0.01,1]}},{\"ty\":7,\"nm\":\"Invert\",\"mn\":\"ADBE Fill-0006\",\"ix\":4,\"v\":{\"k\":0}},{\"ty\":0,\"nm\":\"Horizontal Feather\",\"mn\":\"ADBE Fill-0003\",\"ix\":5,\"v\":{\"k\":0}},{\"ty\":0,\"nm\":\"Vertical Feather\",\"mn\":\"ADBE Fill-0004\",\"ix\":6,\"v\":{\"k\":0}},{\"ty\":0,\"nm\":\"Opacity\",\"mn\":\"ADBE Fill-0005\",\"ix\":7,\"v\":{\"k\":1}}]}],\"sw\":500,\"sh\":600,\"sc\":\"#000000\",\"ip\":1,\"op\":20,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":6,\"ty\":4,\"nm\":\"darkblue\",\"parent\":10,\"tt\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,64.663,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.615,\"y\":1},\"o\":{\"x\":0.112,\"y\":1},\"n\":\"0p615_1_0p112_1\",\"t\":4.257,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[116.264,38.687],[-127.514,72.687],[-136.922,102.313],[-103.324,102.313],[-84.081,102.313],[42.391,102.313],[90.931,102.313],[136.922,102.313]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[62.264,-102.313],[-63.514,-102.313],[-136.922,102.313],[-103.324,102.313],[-84.081,102.313],[42.391,102.313],[90.931,102.313],[136.922,102.313]],\"c\":true}]},{\"t\":18.099609375}]},\"nm\":\"Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":4,\"op\":20,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":7,\"ty\":1,\"nm\":\"mask lightblue\",\"parent\":17,\"td\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[250,100,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"ef\":[{\"ty\":21,\"nm\":\"Fill\",\"mn\":\"ADBE Fill\",\"ix\":1,\"ef\":[{\"ty\":3,\"nm\":\"Fill Mask\",\"mn\":\"ADBE Fill-0001\",\"ix\":1,\"v\":{\"k\":0}},{\"ty\":7,\"nm\":\"All Masks\",\"mn\":\"ADBE Fill-0007\",\"ix\":2,\"v\":{\"k\":0}},{\"ty\":2,\"nm\":\"Color\",\"mn\":\"ADBE Fill-0002\",\"ix\":3,\"v\":{\"k\":[0,0,0.01,1]}},{\"ty\":7,\"nm\":\"Invert\",\"mn\":\"ADBE Fill-0006\",\"ix\":4,\"v\":{\"k\":0}},{\"ty\":0,\"nm\":\"Horizontal Feather\",\"mn\":\"ADBE Fill-0003\",\"ix\":5,\"v\":{\"k\":0}},{\"ty\":0,\"nm\":\"Vertical Feather\",\"mn\":\"ADBE Fill-0004\",\"ix\":6,\"v\":{\"k\":0}},{\"ty\":0,\"nm\":\"Opacity\",\"mn\":\"ADBE Fill-0005\",\"ix\":7,\"v\":{\"k\":1}}]}],\"sw\":500,\"sh\":600,\"sc\":\"#000000\",\"ip\":1,\"op\":20,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":8,\"ty\":4,\"nm\":\"lightblue\",\"parent\":10,\"tt\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,55.875,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.686,\"y\":1},\"o\":{\"x\":0.108,\"y\":1},\"n\":\"0p686_1_0p108_1\",\"t\":1,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[104.851,19.399],[-112.209,39.899],[-136.922,111.101],[136.922,111.101]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[55.851,-111.101],[-57.209,-111.101],[-136.922,111.101],[136.922,111.101]],\"c\":true}]},{\"t\":5}]},\"nm\":\"Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":1,\"op\":20,\"st\":-3,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":9,\"ty\":1,\"nm\":\"mask skin\",\"parent\":17,\"td\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[250,100,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"ef\":[{\"ty\":21,\"nm\":\"Fill\",\"mn\":\"ADBE Fill\",\"ix\":1,\"ef\":[{\"ty\":3,\"nm\":\"Fill Mask\",\"mn\":\"ADBE Fill-0001\",\"ix\":1,\"v\":{\"k\":0}},{\"ty\":7,\"nm\":\"All Masks\",\"mn\":\"ADBE Fill-0007\",\"ix\":2,\"v\":{\"k\":0}},{\"ty\":2,\"nm\":\"Color\",\"mn\":\"ADBE Fill-0002\",\"ix\":3,\"v\":{\"k\":[0,0,0.01,1]}},{\"ty\":7,\"nm\":\"Invert\",\"mn\":\"ADBE Fill-0006\",\"ix\":4,\"v\":{\"k\":0}},{\"ty\":0,\"nm\":\"Horizontal Feather\",\"mn\":\"ADBE Fill-0003\",\"ix\":5,\"v\":{\"k\":0}},{\"ty\":0,\"nm\":\"Vertical Feather\",\"mn\":\"ADBE Fill-0004\",\"ix\":6,\"v\":{\"k\":0}},{\"ty\":0,\"nm\":\"Opacity\",\"mn\":\"ADBE Fill-0005\",\"ix\":7,\"v\":{\"k\":1}}]}],\"sw\":500,\"sh\":600,\"sc\":\"#000000\",\"ip\":1,\"op\":20,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":10,\"ty\":4,\"nm\":\"skin\",\"parent\":17,\"tt\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[{\"i\":{\"x\":0,\"y\":1},\"o\":{\"x\":0,\"y\":0},\"n\":\"0_1_0_0\",\"t\":1,\"s\":[250,469,0],\"e\":[250,177.524,0],\"to\":[0,-122.367813110352,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":15.4,\"s\":[250,177.524,0],\"e\":[250,234.269,0],\"to\":[0,0,0],\"ti\":[0,-22.1301918029785,0]},{\"t\":19}]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[15.078,-166.976],[-17.119,-166.976],[-136.922,166.976],[136.922,166.976]],\"c\":true}},\"nm\":\"Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":1,\"op\":20,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":11,\"ty\":4,\"nm\":\"left arm \",\"parent\":10,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[-93,-85.163,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[-100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":1,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"1_1_0p167_0p167\",\"t\":4,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[11.299,13.7],[0,0]],\"v\":[[-36.299,42.462],[-43.468,67.538]],\"c\":false}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[19.926,-2.45],[0,0]],\"v\":[[-36.299,42.462],[-2.82,20.313]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.815},\"o\":{\"x\":0.18,\"y\":1},\"n\":\"0p833_0p815_0p18_1\",\"t\":5,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[19.926,-2.45],[0,0]],\"v\":[[-36.299,42.462],[-2.82,20.313]],\"c\":false}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[68.529,-28.784],[0,0]],\"v\":[[-36.299,42.462],[53.207,-43.838]],\"c\":false}]},{\"i\":{\"x\":0.547,\"y\":0},\"o\":{\"x\":0.167,\"y\":0.185},\"n\":\"0p547_0_0p167_0p185\",\"t\":6.4,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[68.529,-28.784],[0,0]],\"v\":[[-36.299,42.462],[53.207,-43.838]],\"c\":false}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[55.222,-34.123],[0,0]],\"v\":[[-36.299,42.462],[9.015,-58.738]],\"c\":false}]},{\"i\":{\"x\":0.8,\"y\":0.778},\"o\":{\"x\":0.453,\"y\":1},\"n\":\"0p8_0p778_0p453_1\",\"t\":8.2,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[55.222,-34.123],[0,0]],\"v\":[[-36.299,42.462],[9.015,-58.738]],\"c\":false}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[85.988,-8.836],[0,0]],\"v\":[[-36.299,42.462],[58.474,-42.979]],\"c\":false}]},{\"i\":{\"x\":0.8,\"y\":0.778},\"o\":{\"x\":0.519,\"y\":0},\"n\":\"0p8_0p778_0p519_0\",\"t\":10,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[85.988,-8.836],[0,0]],\"v\":[[-36.299,42.462],[58.474,-42.979]],\"c\":false}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[71.296,-41.974],[0,0]],\"v\":[[-36.299,42.462],[15.755,-73.378]],\"c\":false}]},{\"i\":{\"x\":0.547,\"y\":0},\"o\":{\"x\":0.514,\"y\":0},\"n\":\"0p547_0_0p514_0\",\"t\":11.8,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[71.296,-41.974],[0,0]],\"v\":[[-36.299,42.462],[15.755,-73.378]],\"c\":false}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[72.379,-50.965],[0,0]],\"v\":[[-36.299,42.462],[86.466,25.36]],\"c\":false}]},{\"i\":{\"x\":0.443,\"y\":0.381},\"o\":{\"x\":0.167,\"y\":0.368},\"n\":\"0p443_0p381_0p167_0p368\",\"t\":17.2,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[72.379,-50.965],[0,0]],\"v\":[[-36.299,42.462],[86.466,25.36]],\"c\":false}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[56.859,4.894],[0,0]],\"v\":[[-36.299,42.462],[11.877,128.595]],\"c\":false}]},{\"t\":19}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"w\":{\"k\":20},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":-0.533,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":4,\"op\":20,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":12,\"ty\":4,\"nm\":\"right arm\",\"parent\":10,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[92,-85.163,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":1,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"1_1_0p167_0p167\",\"t\":4,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[11.299,13.7],[0,0]],\"v\":[[-36.299,42.462],[-43.468,67.538]],\"c\":false}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[19.926,-2.45],[0,0]],\"v\":[[-36.299,42.462],[-2.82,20.313]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.815},\"o\":{\"x\":0.18,\"y\":1},\"n\":\"0p833_0p815_0p18_1\",\"t\":5,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[19.926,-2.45],[0,0]],\"v\":[[-36.299,42.462],[-2.82,20.313]],\"c\":false}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[68.529,-28.784],[0,0]],\"v\":[[-36.299,42.462],[53.207,-43.838]],\"c\":false}]},{\"i\":{\"x\":0.547,\"y\":0},\"o\":{\"x\":0.167,\"y\":0.185},\"n\":\"0p547_0_0p167_0p185\",\"t\":6.4,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[68.529,-28.784],[0,0]],\"v\":[[-36.299,42.462],[53.207,-43.838]],\"c\":false}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[55.222,-34.123],[0,0]],\"v\":[[-36.299,42.462],[9.015,-58.738]],\"c\":false}]},{\"i\":{\"x\":0.8,\"y\":0.778},\"o\":{\"x\":0.453,\"y\":1},\"n\":\"0p8_0p778_0p453_1\",\"t\":8.2,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[55.222,-34.123],[0,0]],\"v\":[[-36.299,42.462],[9.015,-58.738]],\"c\":false}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[85.988,-8.836],[0,0]],\"v\":[[-36.299,42.462],[58.474,-42.979]],\"c\":false}]},{\"i\":{\"x\":0.8,\"y\":0.778},\"o\":{\"x\":0.519,\"y\":0},\"n\":\"0p8_0p778_0p519_0\",\"t\":10,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[85.988,-8.836],[0,0]],\"v\":[[-36.299,42.462],[58.474,-42.979]],\"c\":false}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[71.296,-41.974],[0,0]],\"v\":[[-36.299,42.462],[15.755,-73.378]],\"c\":false}]},{\"i\":{\"x\":0.547,\"y\":0},\"o\":{\"x\":0.514,\"y\":0},\"n\":\"0p547_0_0p514_0\",\"t\":11.8,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[71.296,-41.974],[0,0]],\"v\":[[-36.299,42.462],[15.755,-73.378]],\"c\":false}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[72.379,-50.965],[0,0]],\"v\":[[-36.299,42.462],[86.466,25.36]],\"c\":false}]},{\"i\":{\"x\":0.443,\"y\":0.381},\"o\":{\"x\":0.167,\"y\":0.368},\"n\":\"0p443_0p381_0p167_0p368\",\"t\":17.2,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[72.379,-50.965],[0,0]],\"v\":[[-36.299,42.462],[86.466,25.36]],\"c\":false}],\"e\":[{\"i\":[[0,0],[0,0]],\"o\":[[56.859,4.894],[0,0]],\"v\":[[-36.299,42.462],[11.877,128.595]],\"c\":false}]},{\"t\":19}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"w\":{\"k\":20},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":-0.533,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":4,\"op\":20,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":13,\"ty\":4,\"nm\":\"shadow\",\"parent\":17,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[250,246,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"k\":[{\"i\":{\"x\":[0.416,0.416],\"y\":[1,1]},\"o\":{\"x\":[0.187,0.187],\"y\":[0.17,0.924]},\"n\":[\"0p416_1_0p187_0p17\",\"0p416_1_0p187_0p924\"],\"t\":5.5,\"s\":[14.338,2.637],\"e\":[72.797,13.391]},{\"i\":{\"x\":[0.833,0.833],\"y\":[0.833,0.833]},\"o\":{\"x\":[0.767,0.767],\"y\":[0,0]},\"n\":[\"0p833_0p833_0p767_0\",\"0p833_0p833_0p767_0\"],\"t\":12.7,\"s\":[72.797,13.391],\"e\":[19.869,3.655]},{\"t\":18.099609375}]},\"p\":{\"k\":[0,0]},\"nm\":\"Ellipse Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.32,0.5,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[1.398,152.633],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[199.741,199.741],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\"}],\"ip\":6,\"op\":20,\"st\":7,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":14,\"ty\":4,\"nm\":\"A Outlines 3\",\"parent\":17,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[250,400,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":-22,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[66.258,-44],[66.184,-83.343],[-70.187,-84.093],[-70.306,-44]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[66.258,-44],[21.299,-186.393],[-24.073,-187.042],[-70.306,-44]],\"c\":true}]},{\"i\":{\"x\":1,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"1_1_0p167_0p167\",\"t\":20,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[66.258,-44],[21.299,-186.393],[-24.073,-187.042],[-70.306,-44]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[77.021,-18.988],[76.929,-58.331],[-80.995,-59.105],[-81.125,-19.012]],\"c\":true}]},{\"i\":{\"x\":0.8,\"y\":0.674},\"o\":{\"x\":0.123,\"y\":1},\"n\":\"0p8_0p674_0p123_1\",\"t\":22,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[77.021,-18.988],[76.929,-58.331],[-80.995,-59.105],[-81.125,-19.012]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[66.258,-44],[66.184,-83.343],[-70.187,-84.093],[-70.306,-44]],\"c\":true}]},{\"t\":25}]},\"nm\":\" \"},{\"ty\":\"mm\",\"mm\":1,\"nm\":\"Merge Paths 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":-0.064,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"A\"}],\"ip\":20,\"op\":26,\"st\":-22,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":15,\"ty\":4,\"nm\":\"A Outlines 2\",\"parent\":17,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[250,400,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":1,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"1_1_0p167_0p167\",\"t\":20,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[17.441,-226.593],[-25.687,-226.593],[-108.831,-0.095],[-57.067,-0.095]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[15.427,-204.577],[-27.702,-204.577],[-134.011,-0.189],[-82.246,-0.189]],\"c\":true}]},{\"i\":{\"x\":0.8,\"y\":0.674},\"o\":{\"x\":0.123,\"y\":1},\"n\":\"0p8_0p674_0p123_1\",\"t\":22,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[15.427,-204.577],[-27.702,-204.577],[-134.011,-0.189],[-82.246,-0.189]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[17.441,-226.593],[-25.687,-226.593],[-108.831,-0.095],[-57.067,-0.095]],\"c\":true}]},{\"t\":25}]},\"nm\":\"A\"},{\"ty\":\"mm\",\"mm\":1,\"nm\":\"Merge Paths 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[99.286,99.925],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"A\"}],\"ip\":20,\"op\":26,\"st\":-13,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":16,\"ty\":4,\"nm\":\"A Outlines 1\",\"parent\":17,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[250,400,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":1,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"1_1_0p167_0p167\",\"t\":20,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[57.6,0.453],[108.805,0.453],[26.544,-226.327],[-15.984,-226.327]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[74.6,0.906],[125.805,0.906],[26.559,-203.327],[-15.969,-203.327]],\"c\":true}]},{\"i\":{\"x\":0.8,\"y\":0.674},\"o\":{\"x\":0.123,\"y\":1},\"n\":\"0p8_0p674_0p123_1\",\"t\":22,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[74.6,0.906],[125.805,0.906],[26.559,-203.327],[-15.969,-203.327]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[57.6,0.453],[108.805,0.453],[26.544,-226.327],[-15.984,-226.327]],\"c\":true}]},{\"t\":25}]},\"nm\":\"A\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0.441,-0.604],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"A\"}],\"ip\":20,\"op\":26,\"st\":-8,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":17,\"ty\":1,\"nm\":\"ResizerTemp\",\"parent\":18,\"ks\":{\"o\":{\"k\":0},\"r\":{\"k\":0},\"p\":{\"k\":[70,102,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[30,30,100]}},\"ao\":0,\"sw\":500,\"sh\":600,\"sc\":\"#ffffff\",\"ip\":0,\"op\":26,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":18,\"ty\":1,\"nm\":\"White Solid 7\",\"ks\":{\"o\":{\"k\":0},\"r\":{\"k\":0},\"p\":{\"k\":[40,50,0]},\"a\":{\"k\":[70,100,0]},\"s\":{\"k\":[57.143,50,100]}},\"ao\":0,\"sw\":140,\"sh\":200,\"sc\":\"#ffffff\",\"ip\":0,\"op\":26,\"st\":0,\"bm\":0,\"sr\":1}],\"v\":\"4.4.26\",\"ddd\":0,\"ip\":0,\"op\":26,\"fr\":25,\"w\":80,\"h\":100}"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/src/main/assets/L.json",
    "content": "{\"assets\":[],\"layers\":[{\"ddd\":0,\"ind\":0,\"ty\":4,\"nm\":\"triangle_light_blue\",\"parent\":18,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":9,\"s\":[0],\"e\":[-123]},{\"t\":17}]},\"p\":{\"k\":[34,308.937,0]},\"a\":{\"k\":[-15,-179.063,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":9,\"s\":[0,0,100],\"e\":[100,100,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":13,\"s\":[100,100,100],\"e\":[0,0,100]},{\"t\":17}]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"sr\",\"sy\":2,\"d\":1,\"pt\":{\"k\":3,\"ix\":3},\"p\":{\"k\":[0,0],\"ix\":4},\"r\":{\"k\":0,\"ix\":5},\"or\":{\"k\":16.279,\"ix\":7},\"os\":{\"k\":-10,\"ix\":9},\"ix\":1,\"nm\":\"Polystar Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"w\":{\"k\":7},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[-15,-175],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Polystar 1\"}],\"ip\":9,\"op\":17,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":1,\"ty\":4,\"nm\":\"triangle_white\",\"parent\":18,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":6,\"s\":[0],\"e\":[-123]},{\"t\":14}]},\"p\":{\"k\":[207.721,129.686,0]},\"a\":{\"k\":[5,-199.063,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":6,\"s\":[0,0,100],\"e\":[100,100,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":10,\"s\":[100,100,100],\"e\":[0,0,100]},{\"t\":14}]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"sr\",\"sy\":2,\"d\":1,\"pt\":{\"k\":3,\"ix\":3},\"p\":{\"k\":[0,0],\"ix\":4},\"r\":{\"k\":0,\"ix\":5},\"or\":{\"k\":16.279,\"ix\":7},\"os\":{\"k\":-10,\"ix\":9},\"ix\":1,\"nm\":\"Polystar Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.32,0.5,1]},\"o\":{\"k\":100},\"w\":{\"k\":9},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[5,-195],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Polystar 1\"}],\"ip\":6,\"op\":14,\"st\":-3,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":2,\"ty\":4,\"nm\":\"triangle_orange\",\"parent\":18,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":7,\"s\":[0],\"e\":[74]},{\"t\":15}]},\"p\":{\"k\":[153,490.937,0]},\"a\":{\"k\":[-15,-179.063,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":7,\"s\":[0,0,100],\"e\":[76.7,76.7,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":11,\"s\":[76.7,76.7,100],\"e\":[0,0,100]},{\"t\":15}]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"sr\",\"sy\":2,\"d\":1,\"pt\":{\"k\":3,\"ix\":3},\"p\":{\"k\":[0,0],\"ix\":4},\"r\":{\"k\":0,\"ix\":5},\"or\":{\"k\":16.279,\"ix\":7},\"os\":{\"k\":-10,\"ix\":9},\"ix\":1,\"nm\":\"Polystar Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"w\":{\"k\":4},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[-15,-175],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Polystar 1\"}],\"ip\":7,\"op\":15,\"st\":-2,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":3,\"ty\":4,\"nm\":\"cell4\",\"parent\":18,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[250,300,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":3,\"s\":[{\"i\":[[0,0],[-1.461,-14],[0.242,-20],[-2.402,-17],[-2.339,10.239],[-3.393,25.798],[-2.926,28.772],[9.085,0.226],[5.464,1]],\"o\":[[0,0],[1.08,10.351],[-0.266,21.987],[0.851,6.024],[2.039,-8.926],[3.952,-30.05],[3,-29.5],[-20.105,-0.5],[-5.464,-1]],\"v\":[[184.275,-100],[177.961,-51],[169.758,-8],[126.814,70],[161.906,37.411],[182.666,2.05],[210,-66.5],[201.605,-123.5],[193.725,-109.5]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-1.461,-14],[0.242,-20],[-17.66,37],[-15.231,18.718],[-4.245,10.314],[-2.921,28.722],[9.085,0.226],[5.464,1]],\"o\":[[0,0],[1.08,10.351],[-0.266,21.987],[4.735,-9.921],[7.198,-8.846],[12.991,-31.566],[3,-29.5],[-20.105,-0.5],[-5.464,-1]],\"v\":[[205.401,-96],[199.087,-47],[148.045,15],[137.964,96],[181.896,68.282],[202.976,27.902],[249.906,-62.5],[223.905,-120.5],[214.852,-105.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":4,\"s\":[{\"i\":[[0,0],[-1.461,-14],[0.242,-20],[-17.66,37],[-15.231,18.718],[-4.245,10.314],[-2.921,28.722],[9.085,0.226],[5.464,1]],\"o\":[[0,0],[1.08,10.351],[-0.266,21.987],[4.735,-9.921],[7.198,-8.846],[12.991,-31.566],[3,-29.5],[-20.105,-0.5],[-5.464,-1]],\"v\":[[205.401,-96],[199.087,-47],[148.045,15],[137.964,96],[181.896,68.282],[202.976,27.902],[249.906,-62.5],[223.905,-120.5],[214.852,-105.5]],\"c\":true}],\"e\":[{\"i\":[[14.088,-27],[11.128,-46.971],[0.242,-20],[-54.045,17],[1.827,16.795],[-4.245,10.314],[-9.638,56.262],[9.085,0.226],[0.974,-5.469]],\"o\":[[-14.088,27],[-3.08,13],[-0.266,21.987],[10.487,-3.299],[-1.593,-14.642],[12.991,-31.566],[8.308,-48.5],[-20.105,-0.5],[-8.281,46.5]],\"v\":[[191.317,-39],[114.581,-18],[176.8,-9],[186.673,103],[194.321,67.732],[194.76,26.902],[255.774,-65.5],[203.952,-119.5],[166.73,-104.5]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[{\"i\":[[14.088,-27],[11.128,-46.971],[0.242,-20],[-54.045,17],[1.827,16.795],[-4.245,10.314],[-9.638,56.262],[9.085,0.226],[0.974,-5.469]],\"o\":[[-14.088,27],[-3.08,13],[-0.266,21.987],[10.487,-3.299],[-1.593,-14.642],[12.991,-31.566],[8.308,-48.5],[-20.105,-0.5],[-8.281,46.5]],\"v\":[[191.317,-39],[114.581,-18],[176.8,-9],[186.673,103],[194.321,67.732],[194.76,26.902],[255.774,-65.5],[203.952,-119.5],[166.73,-104.5]],\"c\":true}],\"e\":[{\"i\":[[4.104,-26.5],[-1.461,-14],[0.242,-20],[-79.867,-15],[-4.01,46.184],[-9.556,42.817],[-20.864,71.917],[21.398,9.5],[16.811,-5.105]],\"o\":[[-5.497,35.491],[1.08,10.351],[-0.266,21.987],[48.916,9.187],[4.731,-54.487],[9.463,-42.402],[4.787,-16.5],[-18.381,-8.16],[-32.929,10]],\"v\":[[54.581,-65.5],[111.06,-35],[147.458,-9],[103.34,134],[190.103,83.487],[160.723,8.402],[247.558,-62.5],[208.647,-113.5],[133.867,-115]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":6,\"s\":[{\"i\":[[4.104,-26.5],[-1.461,-14],[0.242,-20],[-79.867,-15],[-4.01,46.184],[-9.556,42.817],[-20.864,71.917],[21.398,9.5],[16.811,-5.105]],\"o\":[[-5.497,35.491],[1.08,10.351],[-0.266,21.987],[48.916,9.187],[4.731,-54.487],[9.463,-42.402],[4.787,-16.5],[-18.381,-8.16],[-32.929,10]],\"v\":[[54.581,-65.5],[111.06,-35],[147.458,-9],[103.34,134],[190.103,83.487],[160.723,8.402],[247.558,-62.5],[208.647,-113.5],[133.867,-115]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-10.184,-9.717],[1.602,-43],[-56.18,-7.329],[-1.574,21.443],[1.231,30.949],[-21.621,89],[21.155,10.029],[11.114,-18.017]],\"o\":[[0,0],[11.005,10.5],[-3.888,104.375],[49.827,6.5],[2.262,-30.814],[-2.861,-71.902],[6.182,-25.447],[-23.202,-11],[-19.431,31.5]],\"v\":[[32.281,-102],[59.417,-50.5],[92.294,-3],[61.674,98.5],[124.498,66.814],[102.038,-4.598],[240.516,-65.5],[208.647,-113.5],[83.985,-120.5]],\"c\":true}]},{\"t\":7}]},\"nm\":\"Path 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[27,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[85.201,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"}],\"ip\":3,\"op\":8,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":4,\"ty\":4,\"nm\":\"cell3\",\"parent\":18,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[346.5,203,0]},\"a\":{\"k\":[96.5,-97,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[{\"i\":[[-6.756,0],[-14.83,-2.05],[0,-12.932],[10.048,1.715],[15.011,8.154],[0,23.481],[-4.929,0.352]],\"o\":[[7.793,0],[10.203,1.41],[0,15.773],[-11.506,-1.964],[-15.242,-8.279],[0,-20.095],[7.641,-0.545]],\"v\":[[-7.003,-14.3],[17.863,-31.217],[33.934,-7.058],[14.54,23.443],[-10.944,12.755],[-49.5,0.095],[-32.085,-24.058]],\"c\":true}],\"e\":[{\"i\":[[-5.8,0],[-10.863,3.877],[0,-7.083],[8.627,0.939],[12.909,4.402],[-0.934,-36.321],[-26.024,5.718]],\"o\":[[6.69,0],[8.282,-2.956],[0,8.639],[-9.878,-1.075],[-15.755,-5.373],[-18.368,-17.821],[6.414,-1.409]],\"v\":[[-64.877,-2.516],[-48.599,-9.877],[-35.425,0.355],[-48.962,13.061],[-65.5,7.373],[-82.5,65.821],[-91.033,-34.218]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":9,\"s\":[{\"i\":[[-5.8,0],[-10.863,3.877],[0,-7.083],[8.627,0.939],[12.909,4.402],[-0.934,-36.321],[-26.024,5.718]],\"o\":[[6.69,0],[8.282,-2.956],[0,8.639],[-9.878,-1.075],[-15.755,-5.373],[-18.368,-17.821],[6.414,-1.409]],\"v\":[[-64.877,-2.516],[-48.599,-9.877],[-35.425,0.355],[-48.962,13.061],[-65.5,7.373],[-82.5,65.821],[-91.033,-34.218]],\"c\":true}],\"e\":[{\"i\":[[-2.88,0],[-5.884,-13.371],[-0.311,-16.5],[-3.308,-16.665],[-1.712,-44.664],[0,7.271],[-3.422,2.385]],\"o\":[[2.982,0],[3.557,8.084],[0.274,14.497],[8.539,43.022],[-14.165,-17.164],[0,-4.438],[2.184,-1.522]],\"v\":[[-112.075,-33.164],[-100.378,-23.084],[-91.84,-2],[-100.067,40.478],[-94.486,148.664],[-121.104,-1],[-115.448,-11.749]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[-2.88,0],[-5.884,-13.371],[-0.311,-16.5],[-3.308,-16.665],[-1.712,-44.664],[0,7.271],[-3.422,2.385]],\"o\":[[2.982,0],[3.557,8.084],[0.274,14.497],[8.539,43.022],[-14.165,-17.164],[0,-4.438],[2.184,-1.522]],\"v\":[[-112.075,-33.164],[-100.378,-23.084],[-91.84,-2],[-100.067,40.478],[-94.486,148.664],[-121.104,-1],[-115.448,-11.749]],\"c\":true}],\"e\":[{\"i\":[[-2.88,0],[-4.381,-6.666],[0,-4.338],[-0.022,-6.978],[-1.774,-19.914],[0,7.271],[-3.422,2.385]],\"o\":[[2.982,0],[2.237,3.403],[0,4.927],[0.053,16.567],[-7.391,-0.197],[0,-4.439],[2.184,-1.522]],\"v\":[[-118.302,-30.664],[-109.718,-14.334],[-104.604,8.75],[-108.473,35.478],[-107.188,75.414],[-129.821,2],[-124.165,-8.749]],\"c\":true}]},{\"t\":11}]},\"nm\":\"Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[133.5,-96],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[160.606,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\"}],\"ip\":8,\"op\":12,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":5,\"ty\":4,\"nm\":\"cell2\",\"parent\":18,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[250,300,0],\"e\":[170,261,0],\"to\":[-13.3333330154419,-6.5,0],\"ti\":[23.3333339691162,4,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":9,\"s\":[170,261,0],\"e\":[110,276,0],\"to\":[-23.3333339691162,-4,0],\"ti\":[10,-2.5,0]},{\"t\":10}]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":8,\"s\":[100,100,100],\"e\":[100,74,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":9,\"s\":[100,74,100],\"e\":[100,118,100]},{\"t\":10}]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"k\":[23,18]},\"p\":{\"k\":[0,0]},\"nm\":\"Ellipse Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[108.5,-34],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\"}],\"ip\":8,\"op\":11,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":6,\"ty\":4,\"nm\":\"cell1\",\"parent\":18,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":8,\"s\":[0],\"e\":[1]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":9,\"s\":[1],\"e\":[-4]},{\"t\":10}]},\"p\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[386.5,304,0],\"e\":[232,287,0],\"to\":[-19.75,-18.5,0],\"ti\":[36.75,-18.5,0]},{\"t\":10}]},\"a\":{\"k\":[108.5,-34,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":8,\"s\":[200,100,100],\"e\":[234,74,100]},{\"t\":10}]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[{\"i\":[[-6.351,0],[0,-7.116],[6.351,0],[0,7.116]],\"o\":[[6.351,0],[0,7.116],[-6.351,0],[0,-7.116]],\"v\":[[1,-3.884],[11.5,-3.884],[0,9],[-11.5,-3.884]],\"c\":true}],\"e\":[{\"i\":[[-7.021,-1.19],[-0.16,-8.875],[6.58,2.372],[0.416,4.953]],\"o\":[[6.262,1.061],[0.193,10.656],[-5.904,-2.128],[-0.802,-9.538]],\"v\":[[0.984,-2.299],[18.574,-9.764],[0.463,2.767],[-12.59,8.957]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":9,\"s\":[{\"i\":[[-7.021,-1.19],[-0.16,-8.875],[6.58,2.372],[0.416,4.953]],\"o\":[[6.262,1.061],[0.193,10.656],[-5.904,-2.128],[-0.802,-9.538]],\"v\":[[0.984,-2.299],[18.574,-9.764],[0.463,2.767],[-12.59,8.957]],\"c\":true}],\"e\":[{\"i\":[[-0.302,-6.344],[-1.187,-19.148],[-1.717,-95.564],[0,4.971]],\"o\":[[2.388,50.194],[1.187,19.148],[0.971,54.042],[0,-4.971]],\"v\":[[-1.735,-21.602],[12.076,20.36],[-0.149,141.21],[-12.877,-15.206]],\"c\":true}]},{\"t\":10}]},\"nm\":\"Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[108.5,-34],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\"}],\"ip\":8,\"op\":11,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":7,\"ty\":4,\"nm\":\"stroke_circle_orange\",\"parent\":16,\"ks\":{\"o\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":14,\"s\":[100],\"e\":[0]},{\"t\":21}]},\"r\":{\"k\":0},\"p\":{\"k\":[155,56,0]},\"a\":{\"k\":[182,120,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":14,\"s\":[10,10,100],\"e\":[100,100,100]},{\"t\":21}]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"k\":[30,30]},\"p\":{\"k\":[0,0]},\"nm\":\"Ellipse Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"w\":{\"k\":7.4},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[182,120],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\"}],\"ip\":14,\"op\":21,\"st\":-4,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":8,\"ty\":4,\"nm\":\"stroke_circle_light_blue\",\"parent\":16,\"ks\":{\"o\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":17,\"s\":[100],\"e\":[0]},{\"t\":24}]},\"r\":{\"k\":0},\"p\":{\"k\":[221,10,0]},\"a\":{\"k\":[182,120,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":17,\"s\":[10,10,100],\"e\":[100,100,100]},{\"t\":24}]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"k\":[30,30]},\"p\":{\"k\":[0,0]},\"nm\":\"Ellipse Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"w\":{\"k\":7.4},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[182,120],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\"}],\"ip\":17,\"op\":24,\"st\":-1,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":9,\"ty\":4,\"nm\":\"stroke_semi_circle_orange\",\"parent\":16,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":9,\"s\":[52],\"e\":[7]},{\"t\":20}]},\"p\":{\"k\":[34,-55,0]},\"a\":{\"k\":[-38,119,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":3,\"ty\":\"el\",\"s\":{\"k\":[328,328]},\"p\":{\"k\":[0,0]},\"nm\":\"Ellipse Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"w\":{\"k\":7.4},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[-38,119],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\"},{\"ty\":\"tm\",\"s\":{\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":13,\"s\":[32],\"e\":[66]},{\"t\":20}],\"ix\":1},\"e\":{\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":9,\"s\":[32],\"e\":[66]},{\"t\":15}],\"ix\":2},\"o\":{\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\"}],\"ip\":9,\"op\":20,\"st\":9,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":10,\"ty\":4,\"nm\":\"stroke_semi_circle_light_blue\",\"parent\":16,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":8,\"s\":[52],\"e\":[-19]},{\"t\":19}]},\"p\":{\"k\":[32,-55,0]},\"a\":{\"k\":[-38,119,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":3,\"ty\":\"el\",\"s\":{\"k\":[400,400]},\"p\":{\"k\":[0,0]},\"nm\":\"Ellipse Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"w\":{\"k\":7.4},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[-38,119],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\"},{\"ty\":\"tm\",\"s\":{\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":12,\"s\":[32],\"e\":[66]},{\"t\":19}],\"ix\":1},\"e\":{\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":8,\"s\":[32],\"e\":[66]},{\"t\":14}],\"ix\":2},\"o\":{\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\"}],\"ip\":8,\"op\":19,\"st\":8,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":11,\"ty\":4,\"nm\":\"stroke_semi_circle_white\",\"parent\":16,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":6,\"s\":[177],\"e\":[-14]},{\"t\":17}]},\"p\":{\"k\":[32,-55,0]},\"a\":{\"k\":[-38,119,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":3,\"ty\":\"el\",\"s\":{\"k\":[430,430]},\"p\":{\"k\":[0,0]},\"nm\":\"Ellipse Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.32,0.5,1]},\"o\":{\"k\":100},\"w\":{\"k\":12},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[-38,119],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\"},{\"ty\":\"tm\",\"s\":{\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":10,\"s\":[32],\"e\":[66]},{\"t\":17}],\"ix\":1},\"e\":{\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":6,\"s\":[32],\"e\":[66]},{\"t\":12}],\"ix\":2},\"o\":{\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\"}],\"ip\":6,\"op\":17,\"st\":6,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":12,\"ty\":4,\"nm\":\"L_down_dark_blue\",\"parent\":16,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.164],\"y\":[0.248]},\"n\":[\"0p667_1_0p164_0p248\"],\"t\":10,\"s\":[265],\"e\":[-15.441]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.4],\"y\":[0]},\"n\":[\"0p667_1_0p4_0\"],\"t\":18,\"s\":[-15.441],\"e\":[8.796]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":23,\"s\":[8.796],\"e\":[0]},{\"t\":25}]},\"p\":{\"k\":[-1.457,-4,0]},\"a\":{\"k\":[-51.457,0,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.667,0.505,0.667],\"y\":[0.667,1,0.667]},\"o\":{\"x\":[0.333,0.14,0.333],\"y\":[0.333,0.203,0.333]},\"n\":[\"0p667_0p667_0p333_0p333\",\"0p505_1_0p14_0p203\",\"0p667_0p667_0p333_0p333\"],\"t\":10,\"s\":[100,0,100],\"e\":[100,180,100]},{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[0.667,1,0.667]},\"o\":{\"x\":[0.333,0.458,0.333],\"y\":[0.333,0,0.333]},\"n\":[\"0p667_0p667_0p333_0p333\",\"0p667_1_0p458_0\",\"0p667_0p667_0p333_0p333\"],\"t\":15,\"s\":[100,180,100],\"e\":[100,100,100]},{\"t\":23}]}},\"ao\":0,\"hasMask\":true,\"masksProperties\":[{\"inv\":false,\"mode\":\"a\",\"pt\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-51.457,-41.995],[-51.457,0],[26.048,0],[71.507,0],[71.507,-41.995],[14.441,-41.995]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-15.605,0.991],[0,0],[0,0],[18.545,-1.393]],\"o\":[[0,0],[0,0],[15.178,-0.964],[0,0],[0,0],[-16.955,1.273]],\"v\":[[-30.278,-32.891],[-65.971,17.958],[19.277,5.406],[71.255,2.353],[71.426,-39.953],[17.638,-36.604]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[0,0],[0,0],[-15.605,0.991],[0,0],[0,0],[18.545,-1.393]],\"o\":[[0,0],[0,0],[15.178,-0.964],[0,0],[0,0],[-16.955,1.273]],\"v\":[[-30.278,-32.891],[-65.971,17.958],[19.277,5.406],[71.255,2.353],[71.426,-39.953],[17.638,-36.604]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-25.782,5.285],[0,0],[0,0],[35.943,-8.751]],\"o\":[[0,0],[0,0],[29.363,-6.019],[0,0],[0,0],[-35.943,8.751]],\"v\":[[-57.449,-0.855],[-16.235,6.922],[18.463,-11.162],[72.288,-6.158],[72.898,-32.862],[3.007,-33.261]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0,0],[0,0],[-25.782,5.285],[0,0],[0,0],[35.943,-8.751]],\"o\":[[0,0],[0,0],[29.363,-6.019],[0,0],[0,0],[-35.943,8.751]],\"v\":[[-57.449,-0.855],[-16.235,6.922],[18.463,-11.162],[72.288,-6.158],[72.898,-32.862],[3.007,-33.261]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-29.127,4.055],[0,0],[0,0],[37.836,-4.265]],\"o\":[[0,0],[0,0],[23.338,-3.249],[0,0],[0,0],[-32.662,4.85]],\"v\":[[-73.079,-14.476],[-38.48,17.74],[8.819,3.635],[70.751,7.06],[71.265,-35.868],[13.389,-36.034]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":13,\"s\":[{\"i\":[[0,0],[0,0],[-29.127,4.055],[0,0],[0,0],[37.836,-4.265]],\"o\":[[0,0],[0,0],[23.338,-3.249],[0,0],[0,0],[-32.662,4.85]],\"v\":[[-73.079,-14.476],[-38.48,17.74],[8.819,3.635],[70.751,7.06],[71.265,-35.868],[13.389,-36.034]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-28.508,0.857],[0,0],[0,0],[37.053,0]],\"o\":[[0,0],[0,0],[32.048,0.086],[0,0],[0,0],[-37.053,0]],\"v\":[[-71.714,-22.674],[-50.646,5.392],[6.6,-6.665],[70.5,9.414],[74.791,-26.592],[7.963,-38.133]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[0,0],[0,0],[-28.508,0.857],[0,0],[0,0],[37.053,0]],\"o\":[[0,0],[0,0],[32.048,0.086],[0,0],[0,0],[-37.053,0]],\"v\":[[-71.714,-22.674],[-50.646,5.392],[6.6,-6.665],[70.5,9.414],[74.791,-26.592],[7.963,-38.133]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-27.889,-2.341],[0,0],[0,0],[41.857,1.586]],\"o\":[[0,0],[0,0],[40.758,3.421],[0,0],[0,0],[-38.281,-1.45]],\"v\":[[-61.426,-35.713],[-51.457,0],[10.03,-3.866],[70.248,11.767],[71.103,-31.783],[8.055,-41.733]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[0,0],[0,0],[-27.889,-2.341],[0,0],[0,0],[41.857,1.586]],\"o\":[[0,0],[0,0],[40.758,3.421],[0,0],[0,0],[-38.281,-1.45]],\"v\":[[-61.426,-35.713],[-51.457,0],[10.03,-3.866],[70.248,11.767],[71.103,-31.783],[8.055,-41.733]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-51.457,-41.995],[-51.457,0],[26.048,0],[71.507,0],[71.507,-41.995],[14.441,-41.995]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-51.457,-41.995],[-51.457,0],[26.048,0],[71.507,0],[71.507,-41.995],[14.441,-41.995]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-29.557,0],[0,0],[0,0],[22.142,0]],\"o\":[[0,0],[0,0],[29.557,0],[0,0],[0,0],[-30.576,0]],\"v\":[[-20.513,-42.964],[-51.457,0],[19.91,5.135],[72.004,2.386],[71.507,-41.995],[28.802,-40.095]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[0,0],[0,0],[-29.557,0],[0,0],[0,0],[22.142,0]],\"o\":[[0,0],[0,0],[29.557,0],[0,0],[0,0],[-30.576,0]],\"v\":[[-20.513,-42.964],[-51.457,0],[19.91,5.135],[72.004,2.386],[71.507,-41.995],[28.802,-40.095]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-42.314,-1.068],[0,0],[0,0],[26.578,-0.442]],\"o\":[[0,0],[0,0],[34.155,0.862],[0,0],[0,0],[-26.578,0.442]],\"v\":[[-24.381,-42.843],[-51.457,0],[21.644,9.826],[86.498,1.285],[71.507,-41.995],[25.424,-34.404]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[0,0],[0,0],[-42.314,-1.068],[0,0],[0,0],[26.578,-0.442]],\"o\":[[0,0],[0,0],[34.155,0.862],[0,0],[0,0],[-26.578,0.442]],\"v\":[[-24.381,-42.843],[-51.457,0],[21.644,9.826],[86.498,1.285],[71.507,-41.995],[25.424,-34.404]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-36.269,-0.916],[0,0],[0,0],[22.781,-0.379]],\"o\":[[0,0],[0,0],[29.275,0.739],[0,0],[0,0],[-22.781,0.379]],\"v\":[[-28.249,-42.721],[-51.457,0],[21.953,9.337],[84.357,1.102],[71.507,-41.995],[23.855,-35.488]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":19,\"s\":[{\"i\":[[0,0],[0,0],[-36.269,-0.916],[0,0],[0,0],[22.781,-0.379]],\"o\":[[0,0],[0,0],[29.275,0.739],[0,0],[0,0],[-22.781,0.379]],\"v\":[[-28.249,-42.721],[-51.457,0],[21.953,9.337],[84.357,1.102],[71.507,-41.995],[23.855,-35.488]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-32.329,0],[0,0],[0,0],[11.391,-0.189]],\"o\":[[0,0],[0,0],[32.329,0],[0,0],[0,0],[-11.391,0.189]],\"v\":[[-39.853,-42.358],[-51.457,0],[24.001,4.669],[77.932,0.551],[71.507,-41.995],[19.148,-38.742]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":22,\"s\":[{\"i\":[[0,0],[0,0],[-32.329,0],[0,0],[0,0],[11.391,-0.189]],\"o\":[[0,0],[0,0],[32.329,0],[0,0],[0,0],[-11.391,0.189]],\"v\":[[-39.853,-42.358],[-51.457,0],[24.001,4.669],[77.932,0.551],[71.507,-41.995],[19.148,-38.742]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-22.035,0],[0,0],[0,0],[3.797,-0.063]],\"o\":[[0,0],[0,0],[22.035,0],[0,0],[0,0],[-3.797,0.063]],\"v\":[[-47.589,-42.116],[-51.457,0],[25.461,2.803],[73.649,0.184],[71.507,-41.995],[16.01,-40.911]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[0,0],[0,0],[-22.035,0],[0,0],[0,0],[3.797,-0.063]],\"o\":[[0,0],[0,0],[22.035,0],[0,0],[0,0],[-3.797,0.063]],\"v\":[[-47.589,-42.116],[-51.457,0],[25.461,2.803],[73.649,0.184],[71.507,-41.995],[16.01,-40.911]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-51.457,-41.995],[-51.457,0],[26.048,0],[71.507,0],[71.507,-41.995],[14.441,-41.995]],\"c\":true}]},{\"t\":25}]},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 1\"}],\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-54.455,-34.192],[-52.283,18.884],[-13.504,24.771],[13.121,7.776],[68.467,7.776],[68.467,-34.219]],\"c\":true}},\"nm\":\"L\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[161,161],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"L\"}],\"ip\":10,\"op\":37,\"st\":-2,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":13,\"ty\":4,\"nm\":\"L_side_dark_blue\",\"parent\":16,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.353],\"y\":[1]},\"o\":{\"x\":[0.125],\"y\":[0.254]},\"n\":[\"0p353_1_0p125_0p254\"],\"t\":2,\"s\":[0],\"e\":[8.031]},{\"i\":{\"x\":[0.575],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p575_1_0p333_0\"],\"t\":4,\"s\":[8.031],\"e\":[-8]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.542],\"y\":[0]},\"n\":[\"0p667_1_0p542_0\"],\"t\":10.4,\"s\":[-8],\"e\":[1]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":15,\"s\":[1],\"e\":[0]},{\"t\":20}]},\"p\":{\"k\":[{\"i\":{\"x\":0.098,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p098_1_0p333_0\",\"t\":2,\"s\":[202.108,-4,0],\"e\":[22.108,-4,0],\"to\":[92.2331924438477,0,0],\"ti\":[-125.636123657227,0,0]},{\"t\":12.400390625}]},\"a\":{\"k\":[-27.892,0,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,0.667,0.667]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0,0.167,0.167]},\"n\":[\"0p667_1_0p167_0\",\"0p667_0p667_0p167_0p167\",\"0p667_0p667_0p167_0p167\"],\"t\":2,\"s\":[0,100,100],\"e\":[252,100,100]},{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,0.667,0.667]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0.333,0.333]},\"n\":[\"0p667_1_0p333_0\",\"0p667_0p667_0p333_0p333\",\"0p667_0p667_0p333_0p333\"],\"t\":7,\"s\":[252,100,100],\"e\":[100,100,100]},{\"t\":12.400390625}]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":4,\"s\":[{\"i\":[[3.47,26.064],[1.003,-13.99],[12.611,-68.579],[-2.57,-22.162],[0,0],[-8.785,40.076],[8.178,41.626]],\"o\":[[-3.47,-26.064],[-1.149,16.02],[-7.848,42.678],[1.56,13.45],[0,0],[11.02,-50.267],[-9.591,-48.816]],\"v\":[[-4.326,-226.593],[-55.334,-224.968],[-51.457,-123.528],[-54.816,-21.288],[-51.457,0],[-4.493,0],[-6.758,-113.63]],\"c\":true}],\"e\":[{\"i\":[[3.47,26.064],[1.558,-25.465],[18.933,-67.109],[-5.588,-16.574],[-3.526,-8.686],[-8.785,40.076],[8.178,41.626]],\"o\":[[-3.47,-26.064],[-1.745,28.523],[-11.663,41.341],[3.391,10.059],[5.532,13.626],[11.02,-50.267],[-9.591,-48.816]],\"v\":[[-4.326,-226.593],[-56.073,-214.867],[-59.337,-117.768],[-63.196,-37.443],[-51.645,-10.79],[-4.493,0],[-8.413,-116.217]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[{\"i\":[[3.47,26.064],[1.558,-25.465],[18.933,-67.109],[-5.588,-16.574],[-3.526,-8.686],[-8.785,40.076],[8.178,41.626]],\"o\":[[-3.47,-26.064],[-1.745,28.523],[-11.663,41.341],[3.391,10.059],[5.532,13.626],[11.02,-50.267],[-9.591,-48.816]],\"v\":[[-4.326,-226.593],[-56.073,-214.867],[-59.337,-117.768],[-63.196,-37.443],[-51.645,-10.79],[-4.493,0],[-8.413,-116.217]],\"c\":true}],\"e\":[{\"i\":[[-1.001,26.275],[1.188,-17.815],[14.718,-68.089],[-3.576,-20.3],[-1.175,-2.895],[-10.488,49.102],[8.178,41.626]],\"o\":[[0.969,-25.418],[-1.348,20.188],[-9.12,42.232],[2.17,12.32],[1.844,4.542],[10.749,-50.325],[-9.591,-48.816]],\"v\":[[-2.243,-201.316],[-55.58,-221.601],[-54.084,-121.608],[-57.609,-26.673],[-51.52,-3.597],[-12.112,-12.374],[-11.723,-121.391]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7,\"s\":[{\"i\":[[-1.001,26.275],[1.188,-17.815],[14.718,-68.089],[-3.576,-20.3],[-1.175,-2.895],[-10.488,49.102],[8.178,41.626]],\"o\":[[0.969,-25.418],[-1.348,20.188],[-9.12,42.232],[2.17,12.32],[1.844,4.542],[10.749,-50.325],[-9.591,-48.816]],\"v\":[[-2.243,-201.316],[-55.58,-221.601],[-54.084,-121.608],[-57.609,-26.673],[-51.52,-3.597],[-12.112,-12.374],[-11.723,-121.391]],\"c\":true}],\"e\":[{\"i\":[[3.47,26.064],[1.003,-13.99],[12.611,-68.579],[-2.57,-22.162],[0,0],[-8.785,40.076],[8.178,41.626]],\"o\":[[-3.47,-26.064],[-1.149,16.02],[-7.848,42.678],[1.56,13.45],[0,0],[11.02,-50.267],[-9.591,-48.816]],\"v\":[[-4.326,-226.593],[-55.334,-224.968],[-51.457,-123.528],[-54.816,-21.288],[-51.457,0],[-4.493,0],[-13.378,-123.978]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[{\"i\":[[3.47,26.064],[1.003,-13.99],[12.611,-68.579],[-2.57,-22.162],[0,0],[-8.785,40.076],[8.178,41.626]],\"o\":[[-3.47,-26.064],[-1.149,16.02],[-7.848,42.678],[1.56,13.45],[0,0],[11.02,-50.267],[-9.591,-48.816]],\"v\":[[-4.326,-226.593],[-55.334,-224.968],[-51.457,-123.528],[-54.816,-21.288],[-51.457,0],[-4.493,0],[-13.378,-123.978]],\"c\":true}],\"e\":[{\"i\":[[5.028,6.595],[3.896,-7.735],[0,-39.964],[2.727,-23.759],[-2.112,-11.718],[4.399,28.951],[-2.355,24.474]],\"o\":[[-5.028,-6.595],[-3.896,7.735],[0,24.87],[-1.655,14.419],[2.516,13.962],[-10.234,-67.36],[3.598,-37.386]],\"v\":[[-4.326,-226.593],[-51.457,-226.593],[-45.75,-120.171],[-53.872,-45.291],[-54.088,-5.652],[-5.819,-11.385],[-3.913,-129.252]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":9,\"s\":[{\"i\":[[5.028,6.595],[3.896,-7.735],[0,-39.964],[2.727,-23.759],[-2.112,-11.718],[4.399,28.951],[-2.355,24.474]],\"o\":[[-5.028,-6.595],[-3.896,7.735],[0,24.87],[-1.655,14.419],[2.516,13.962],[-10.234,-67.36],[3.598,-37.386]],\"v\":[[-4.326,-226.593],[-51.457,-226.593],[-45.75,-120.171],[-53.872,-45.291],[-54.088,-5.652],[-5.819,-11.385],[-3.913,-129.252]],\"c\":true}],\"e\":[{\"i\":[[0,0],[7.014,-6.662],[0,-39.18],[-3.89,-25.385],[-3.467,-3.467],[-4.994,11.748],[0,0]],\"o\":[[0,0],[-7.014,6.662],[0,20.609],[3.505,22.874],[7.314,7.314],[4.994,-11.748],[0,0]],\"v\":[[-4.326,-226.593],[-51.457,-226.593],[-69.542,-121.562],[-51.946,-47.65],[-51.457,0],[-4.054,2.118],[-4.397,-129.366]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[0,0],[7.014,-6.662],[0,-39.18],[-3.89,-25.385],[-3.467,-3.467],[-4.994,11.748],[0,0]],\"o\":[[0,0],[-7.014,6.662],[0,20.609],[3.505,22.874],[7.314,7.314],[4.994,-11.748],[0,0]],\"v\":[[-4.326,-226.593],[-51.457,-226.593],[-69.542,-121.562],[-51.946,-47.65],[-51.457,0],[-4.054,2.118],[-4.397,-129.366]],\"c\":true}],\"e\":[{\"i\":[[2.125,5.911],[6.776,-5.466],[-3.424,-42.933],[-5.182,-39.435],[-3.12,-3.12],[-4.494,10.573],[0,0]],\"o\":[[-2.125,-5.911],[-21.113,17.033],[2.394,30.025],[2.713,20.649],[6.582,6.582],[4.494,-10.573],[0,0]],\"v\":[[-5.639,-223.791],[-51.426,-219.522],[-84.182,-129.635],[-42.662,-50.299],[-51.457,0],[-4.098,1.906],[-4.397,-129.366]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[2.125,5.911],[6.776,-5.466],[-3.424,-42.933],[-5.182,-39.435],[-3.12,-3.12],[-4.494,10.573],[0,0]],\"o\":[[-2.125,-5.911],[-21.113,17.033],[2.394,30.025],[2.713,20.649],[6.582,6.582],[4.494,-10.573],[0,0]],\"v\":[[-5.639,-223.791],[-51.426,-219.522],[-84.182,-129.635],[-42.662,-50.299],[-51.457,0],[-4.098,1.906],[-4.397,-129.366]],\"c\":true}],\"e\":[{\"i\":[[26.53,20.045],[6.023,-4.859],[-4.96,-45.859],[-5.991,-42.021],[-2.773,-2.773],[-3.995,9.399],[-3.195,56.736]],\"o\":[[-15.176,-11.466],[-18.767,15.14],[4.861,44.948],[2.613,18.327],[5.851,5.851],[3.995,-9.399],[3.195,-56.736]],\"v\":[[-0.623,-220.122],[-39.452,-221.929],[-65.47,-128.643],[-39.426,-51.632],[-42.183,0.579],[5.132,2.274],[18.199,-129.245]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[26.53,20.045],[6.023,-4.859],[-4.96,-45.859],[-5.991,-42.021],[-2.773,-2.773],[-3.995,9.399],[-3.195,56.736]],\"o\":[[-15.176,-11.466],[-18.767,15.14],[4.861,44.948],[2.613,18.327],[5.851,5.851],[3.995,-9.399],[3.195,-56.736]],\"v\":[[-0.623,-220.122],[-39.452,-221.929],[-65.47,-128.643],[-39.426,-51.632],[-42.183,0.579],[5.132,2.274],[18.199,-129.245]],\"c\":true}],\"e\":[{\"i\":[[15.572,10.171],[5.772,-4.657],[-4.753,-43.949],[-5.741,-40.27],[-2.658,-2.658],[-3.828,9.007],[-3.016,57.604]],\"o\":[[-7.924,-5.176],[-17.985,14.509],[4.659,43.076],[2.504,17.564],[5.607,5.607],[3.828,-9.007],[3.016,-57.604]],\"v\":[[-2.852,-220.986],[-40.886,-223.186],[-69.863,-128.791],[-52.524,-52.613],[-51.457,0],[1.887,0.317],[14.39,-129.779]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":13,\"s\":[{\"i\":[[15.572,10.171],[5.772,-4.657],[-4.753,-43.949],[-5.741,-40.27],[-2.658,-2.658],[-3.828,9.007],[-3.016,57.604]],\"o\":[[-7.924,-5.176],[-17.985,14.509],[4.659,43.076],[2.504,17.564],[5.607,5.607],[3.828,-9.007],[3.016,-57.604]],\"v\":[[-2.852,-220.986],[-40.886,-223.186],[-69.863,-128.791],[-52.524,-52.613],[-51.457,0],[1.887,0.317],[14.39,-129.779]],\"c\":true}],\"e\":[{\"i\":[[7.284,3.607],[4.474,-7.496],[-2.789,-33.477],[-2.634,-25.281],[-5.09,-3.455],[-1.697,27.839],[-3.798,62.729]],\"o\":[[-6.66,-3.298],[-12.842,19.783],[2.793,34.473],[0.818,18.247],[6.564,4.929],[1.549,-43.685],[2.798,-47.908]],\"v\":[[-2.597,-224.102],[-49.622,-221.884],[-60.66,-126.16],[-53.053,-50.066],[-50.442,0.984],[-0.194,-24.862],[14.685,-150.122]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[7.284,3.607],[4.474,-7.496],[-2.789,-33.477],[-2.634,-25.281],[-5.09,-3.455],[-1.697,27.839],[-3.798,62.729]],\"o\":[[-6.66,-3.298],[-12.842,19.783],[2.793,34.473],[0.818,18.247],[6.564,4.929],[1.549,-43.685],[2.798,-47.908]],\"v\":[[-2.597,-224.102],[-49.622,-221.884],[-60.66,-126.16],[-53.053,-50.066],[-50.442,0.984],[-0.194,-24.862],[14.685,-150.122]],\"c\":true}],\"e\":[{\"i\":[[14.089,8.109],[3.175,-10.335],[-0.825,-23.005],[0.472,-10.292],[-7.522,-4.251],[0.435,46.672],[-4.58,67.854]],\"o\":[[-15.773,-9.079],[-7.698,25.057],[0.927,25.87],[-0.868,18.931],[7.522,4.251],[-0.73,-78.364],[2.579,-38.212]],\"v\":[[5.738,-222.268],[-51.316,-217.594],[-51.457,-123.528],[-53.582,-47.519],[-49.426,1.969],[-2.275,-50.041],[14.98,-170.465]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[14.089,8.109],[3.175,-10.335],[-0.825,-23.005],[0.472,-10.292],[-7.522,-4.251],[0.435,46.672],[-4.58,67.854]],\"o\":[[-15.773,-9.079],[-7.698,25.057],[0.927,25.87],[-0.868,18.931],[7.522,4.251],[-0.73,-78.364],[2.579,-38.212]],\"v\":[[5.738,-222.268],[-51.316,-217.594],[-51.457,-123.528],[-53.582,-47.519],[-49.426,1.969],[-2.275,-50.041],[14.98,-170.465]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-4.326,-226.593],[-51.457,-226.593],[-51.457,-123.528],[-51.457,-39.551],[-51.457,0],[-4.493,0],[-4.397,-129.366]],\"c\":true}]},{\"t\":18}]},\"nm\":\"L\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"L\"}],\"ip\":2,\"op\":37,\"st\":2,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":14,\"ty\":4,\"nm\":\"L_side_dark_orange\",\"parent\":16,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.353],\"y\":[1]},\"o\":{\"x\":[0.125],\"y\":[0.254]},\"n\":[\"0p353_1_0p125_0p254\"],\"t\":0,\"s\":[0],\"e\":[8.031]},{\"i\":{\"x\":[0.575],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p575_1_0p333_0\"],\"t\":2,\"s\":[8.031],\"e\":[-8]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.542],\"y\":[0]},\"n\":[\"0p667_1_0p542_0\"],\"t\":8.4,\"s\":[-8],\"e\":[1]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":13,\"s\":[1],\"e\":[0]},{\"t\":18}]},\"p\":{\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":0,\"s\":[202.108,-4,0],\"e\":[22.108,-4,0],\"to\":[92.2331924438477,0,0],\"ti\":[-125.636123657227,0,0]},{\"t\":10.400390625}]},\"a\":{\"k\":[-27.892,0,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,0.667,0.667]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0,0.167,0.167]},\"n\":[\"0p667_1_0p167_0\",\"0p667_0p667_0p167_0p167\",\"0p667_0p667_0p167_0p167\"],\"t\":0,\"s\":[0,100,100],\"e\":[328.8,100,100]},{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,0.667,0.667]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0.333,0.333]},\"n\":[\"0p667_1_0p333_0\",\"0p667_0p667_0p333_0p333\",\"0p667_0p667_0p333_0p333\"],\"t\":5,\"s\":[328.8,100,100],\"e\":[100,100,100]},{\"t\":10.400390625}]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":1,\"s\":[{\"i\":[[3.177,19.767],[0,0],[0,0],[0,0],[-7.48,43.926],[0.289,48.674]],\"o\":[[-6.787,-42.231],[0,0],[0,0],[0,0],[3.979,-23.365],[-0.254,-42.831]],\"v\":[[-4.326,-226.593],[-51.457,-226.593],[-51.457,-132.718],[-51.457,0],[-4.493,0],[0.91,-122.711]],\"c\":true}],\"e\":[{\"i\":[[-0.583,11.813],[6.544,-45.247],[0.31,-41.416],[-3.136,-6.622],[-3.154,30.786],[0.527,49.779]],\"o\":[[1.205,-24.41],[-2.711,18.742],[-0.439,58.568],[5.354,11.305],[1.628,-15.887],[-0.494,-46.682]],\"v\":[[-4.299,-220.867],[-51.457,-226.593],[-60.408,-124.844],[-51.457,0],[-4.493,0],[-7.13,-117.83]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":3,\"s\":[{\"i\":[[-0.583,11.813],[6.544,-45.247],[0.31,-41.416],[-3.136,-6.622],[-3.154,30.786],[0.527,49.779]],\"o\":[[1.205,-24.41],[-2.711,18.742],[-0.439,58.568],[5.354,11.305],[1.628,-15.887],[-0.494,-46.682]],\"v\":[[-4.299,-220.867],[-51.457,-226.593],[-60.408,-124.844],[-51.457,0],[-4.493,0],[-7.13,-117.83]],\"c\":true}],\"e\":[{\"i\":[[-0.583,11.813],[1.793,-45.682],[0.31,-41.416],[-3.281,-62.017],[-3.154,30.786],[0.527,49.779]],\"o\":[[1.205,-24.41],[-2.277,58.023],[-0.439,58.568],[0.661,12.491],[1.628,-15.887],[-0.494,-46.682]],\"v\":[[-4.299,-220.867],[-49.232,-227.286],[-67.531,-124.936],[-51.457,0],[-4.493,0],[-1.011,-125.508]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":6,\"s\":[{\"i\":[[-0.583,11.813],[1.793,-45.682],[0.31,-41.416],[-3.281,-62.017],[-3.154,30.786],[0.527,49.779]],\"o\":[[1.205,-24.41],[-2.277,58.023],[-0.439,58.568],[0.661,12.491],[1.628,-15.887],[-0.494,-46.682]],\"v\":[[-4.299,-220.867],[-49.232,-227.286],[-67.531,-124.936],[-51.457,0],[-4.493,0],[-1.011,-125.508]],\"c\":true}],\"e\":[{\"i\":[[-0.583,11.813],[1.793,-45.682],[0.31,-41.416],[-3.281,-62.017],[-3.154,30.786],[0.527,49.779]],\"o\":[[1.205,-24.41],[-2.277,58.023],[-0.439,58.568],[0.661,12.491],[1.628,-15.887],[-0.494,-46.682]],\"v\":[[-4.299,-220.867],[-43.604,-213.992],[-67.531,-124.936],[-43.612,1.735],[-4.493,0],[-1.011,-125.508]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7,\"s\":[{\"i\":[[-0.583,11.813],[1.793,-45.682],[0.31,-41.416],[-3.281,-62.017],[-3.154,30.786],[0.527,49.779]],\"o\":[[1.205,-24.41],[-2.277,58.023],[-0.439,58.568],[0.661,12.491],[1.628,-15.887],[-0.494,-46.682]],\"v\":[[-4.299,-220.867],[-43.604,-213.992],[-67.531,-124.936],[-43.612,1.735],[-4.493,0],[-1.011,-125.508]],\"c\":true}],\"e\":[{\"i\":[[-0.583,11.813],[1.793,-45.682],[-0.132,-41.417],[-3.281,-62.017],[-3.154,30.786],[0.527,49.779]],\"o\":[[1.205,-24.41],[-2.277,58.023],[0.295,92.398],[0.661,12.491],[1.628,-15.887],[-0.494,-46.682]],\"v\":[[-4.299,-220.867],[-43.41,-199.609],[-73.34,-124.204],[-38.717,-1.253],[-4.493,0],[-1.011,-125.508]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[{\"i\":[[-0.583,11.813],[1.793,-45.682],[-0.132,-41.417],[-3.281,-62.017],[-3.154,30.786],[0.527,49.779]],\"o\":[[1.205,-24.41],[-2.277,58.023],[0.295,92.398],[0.661,12.491],[1.628,-15.887],[-0.494,-46.682]],\"v\":[[-4.299,-220.867],[-43.41,-199.609],[-73.34,-124.204],[-38.717,-1.253],[-4.493,0],[-1.011,-125.508]],\"c\":true}],\"e\":[{\"i\":[[-0.583,11.813],[1.793,-45.682],[-0.132,-41.417],[-3.281,-62.017],[-3.154,30.786],[0.527,49.779]],\"o\":[[1.205,-24.41],[-2.277,58.023],[0.295,92.398],[0.661,12.491],[1.628,-15.887],[-0.494,-46.682]],\"v\":[[-0.011,-197.848],[-43.41,-199.609],[-56.23,-119.95],[-38.717,-1.253],[-3.214,-12.879],[-1.011,-125.508]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":9,\"s\":[{\"i\":[[-0.583,11.813],[1.793,-45.682],[-0.132,-41.417],[-3.281,-62.017],[-3.154,30.786],[0.527,49.779]],\"o\":[[1.205,-24.41],[-2.277,58.023],[0.295,92.398],[0.661,12.491],[1.628,-15.887],[-0.494,-46.682]],\"v\":[[-0.011,-197.848],[-43.41,-199.609],[-56.23,-119.95],[-38.717,-1.253],[-3.214,-12.879],[-1.011,-125.508]],\"c\":true}],\"e\":[{\"i\":[[11.821,-0.386],[1.793,-45.682],[-0.132,-41.417],[-5.714,-61.84],[0.915,30.933],[-0.582,36.69]],\"o\":[[-33.274,1.087],[-2.277,58.023],[0.295,92.398],[1.635,17.693],[-2.481,-83.888],[1.239,-78.099]],\"v\":[[-40.306,-225.512],[-76.701,-180.722],[-56.23,-119.95],[-58.833,-15.584],[-19.309,-11.918],[11.195,-143.757]],\"c\":true}]},{\"t\":11}]},\"nm\":\"L\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"L\"}],\"ip\":0,\"op\":15,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":15,\"ty\":4,\"nm\":\"L_down_light_blue\",\"parent\":16,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.164],\"y\":[0.248]},\"n\":[\"0p667_1_0p164_0p248\"],\"t\":11,\"s\":[265],\"e\":[-15.441]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.4],\"y\":[0]},\"n\":[\"0p667_1_0p4_0\"],\"t\":19,\"s\":[-15.441],\"e\":[8.796]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":24,\"s\":[8.796],\"e\":[0]},{\"t\":26}]},\"p\":{\"k\":[-1.457,-4,0]},\"a\":{\"k\":[-51.457,0,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.667,0.505,0.667],\"y\":[0.667,1,0.667]},\"o\":{\"x\":[0.333,0.14,0.333],\"y\":[0.333,0.203,0.333]},\"n\":[\"0p667_0p667_0p333_0p333\",\"0p505_1_0p14_0p203\",\"0p667_0p667_0p333_0p333\"],\"t\":11,\"s\":[100,0,100],\"e\":[100,180,100]},{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[0.667,1,0.667]},\"o\":{\"x\":[0.333,0.458,0.333],\"y\":[0.333,0,0.333]},\"n\":[\"0p667_0p667_0p333_0p333\",\"0p667_1_0p458_0\",\"0p667_0p667_0p333_0p333\"],\"t\":16,\"s\":[100,180,100],\"e\":[100,100,100]},{\"t\":24}]}},\"ao\":0,\"hasMask\":true,\"masksProperties\":[{\"inv\":false,\"mode\":\"a\",\"pt\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-51.457,-41.995],[-51.457,0],[26.048,0],[71.507,0],[71.507,-18.863],[71.507,-41.995],[14.441,-41.995]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-41.015,7.09],[0,0],[1.24,13.664],[0,0],[27.171,-7.292]],\"o\":[[0,0],[0,0],[31.541,-5.452],[0,0],[-0.86,-9.477],[0,0],[-28.627,7.683]],\"v\":[[-23.744,-36.058],[-56.318,1.328],[12.921,14.397],[73.907,-14.61],[72.622,-38.639],[68.974,-62.345],[22.419,-35.837]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0,0],[0,0],[-41.015,7.09],[0,0],[1.24,13.664],[0,0],[27.171,-7.292]],\"o\":[[0,0],[0,0],[31.541,-5.452],[0,0],[-0.86,-9.477],[0,0],[-28.627,7.683]],\"v\":[[-23.744,-36.058],[-56.318,1.328],[12.921,14.397],[73.907,-14.61],[72.622,-38.639],[68.974,-62.345],[22.419,-35.837]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-25.782,5.285],[0,0],[8.385,14.678],[0,0],[35.943,-8.751]],\"o\":[[0,0],[0,0],[29.363,-6.019],[0,0],[-8.718,-15.261],[0,0],[-35.943,8.751]],\"v\":[[-61.276,1.453],[-24.465,8.364],[15.813,-7.628],[80.317,-6.952],[62.858,-44.156],[41.047,-72.5],[-4.863,-63.188]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":13,\"s\":[{\"i\":[[0,0],[0,0],[-25.782,5.285],[0,0],[8.385,14.678],[0,0],[35.943,-8.751]],\"o\":[[0,0],[0,0],[29.363,-6.019],[0,0],[-8.718,-15.261],[0,0],[-35.943,8.751]],\"v\":[[-61.276,1.453],[-24.465,8.364],[15.813,-7.628],[80.317,-6.952],[62.858,-44.156],[41.047,-72.5],[-4.863,-63.188]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-44.861,-0.831],[0,0],[0,0],[0,0],[37.836,-4.265]],\"o\":[[0,0],[0,0],[47.99,0.889],[0,0],[0,0],[0,0],[-32.662,4.85]],\"v\":[[-73.079,-14.476],[-44.967,4.229],[27.959,-22.056],[89.877,-9.778],[76.196,-22.138],[50.824,-45.839],[10.031,-42.074]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[0,0],[0,0],[-44.861,-0.831],[0,0],[0,0],[0,0],[37.836,-4.265]],\"o\":[[0,0],[0,0],[47.99,0.889],[0,0],[0,0],[0,0],[-32.662,4.85]],\"v\":[[-73.079,-14.476],[-44.967,4.229],[27.959,-22.056],[89.877,-9.778],[76.196,-22.138],[50.824,-45.839],[10.031,-42.074]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-32.063,0.852],[0,0],[4.163,9.643],[0,0],[37.053,0]],\"o\":[[0,0],[0,0],[36.47,-0.969],[0,0],[-3.131,-7.252],[0,0],[-37.053,0]],\"v\":[[-71.714,-22.674],[-50.089,-0.613],[11.231,-14.118],[74.055,0.651],[68.636,-17.864],[59.165,-31.532],[7.963,-38.133]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[0,0],[0,0],[-32.063,0.852],[0,0],[4.163,9.643],[0,0],[37.053,0]],\"o\":[[0,0],[0,0],[36.47,-0.969],[0,0],[-3.131,-7.252],[0,0],[-37.053,0]],\"v\":[[-71.714,-22.674],[-50.089,-0.613],[11.231,-14.118],[74.055,0.651],[68.636,-17.864],[59.165,-31.532],[7.963,-38.133]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-28.255,3.777],[0,0],[4.338,5.486],[0,0],[41.857,1.586]],\"o\":[[0,0],[0,0],[34.579,-4.622],[0,0],[-4.149,-5.246],[0,0],[-38.281,-1.45]],\"v\":[[-61.426,-35.713],[-50.593,0.313],[12.382,-12.663],[69.506,-14.389],[63.246,-24.456],[52.363,-37.277],[8.055,-41.733]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[{\"i\":[[0,0],[0,0],[-28.255,3.777],[0,0],[4.338,5.486],[0,0],[41.857,1.586]],\"o\":[[0,0],[0,0],[34.579,-4.622],[0,0],[-4.149,-5.246],[0,0],[-38.281,-1.45]],\"v\":[[-61.426,-35.713],[-50.593,0.313],[12.382,-12.663],[69.506,-14.389],[63.246,-24.456],[52.363,-37.277],[8.055,-41.733]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-31.713,4.104],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[22.54,-2.917],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-36.188,-41.182],[-51.457,0],[23.546,-3.418],[72.059,-14.242],[64.294,-23.664],[49.317,-42.156],[14.441,-41.995]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[0,0],[0,0],[-31.713,4.104],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[22.54,-2.917],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-36.188,-41.182],[-51.457,0],[23.546,-3.418],[72.059,-14.242],[64.294,-23.664],[49.317,-42.156],[14.441,-41.995]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-29.557,0],[0,0],[0,0],[0,0],[22.142,0]],\"o\":[[0,0],[0,0],[29.557,0],[0,0],[0,0],[0,0],[-30.576,0]],\"v\":[[-18.648,-28.14],[-51.457,0],[21.52,-2.386],[66.17,-12.726],[71.781,-17.549],[54.64,-38.523],[24.588,-29.826]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[0,0],[0,0],[-29.557,0],[0,0],[0,0],[0,0],[22.142,0]],\"o\":[[0,0],[0,0],[29.557,0],[0,0],[0,0],[0,0],[-30.576,0]],\"v\":[[-18.648,-28.14],[-51.457,0],[21.52,-2.386],[66.17,-12.726],[71.781,-17.549],[54.64,-38.523],[24.588,-29.826]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-42.314,-1.068],[0,0],[0,0],[0,0],[24.679,1.827]],\"o\":[[0,0],[0,0],[34.155,0.862],[0,0],[0,0],[0,0],[-5.594,0.498]],\"v\":[[-9.46,-19.781],[-48.074,-1.194],[21.355,6.387],[80.573,2.365],[73.798,-34.513],[72.281,-43.153],[9.841,-31.433]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":19,\"s\":[{\"i\":[[0,0],[0,0],[-42.314,-1.068],[0,0],[0,0],[0,0],[24.679,1.827]],\"o\":[[0,0],[0,0],[34.155,0.862],[0,0],[0,0],[0,0],[-5.594,0.498]],\"v\":[[-9.46,-19.781],[-48.074,-1.194],[21.355,6.387],[80.573,2.365],[73.798,-34.513],[72.281,-43.153],[9.841,-31.433]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-36.269,-0.916],[0,0],[0,0],[0,0],[29.492,3.576]],\"o\":[[0,0],[0,0],[29.275,0.739],[0,0],[0,0],[0,0],[-4.795,0.426]],\"v\":[[-15.459,-22.954],[-48.558,-1.023],[22.025,5.474],[79.278,2.027],[76.578,-27.194],[75.278,-37.904],[3.383,-30.236]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":20,\"s\":[{\"i\":[[0,0],[0,0],[-36.269,-0.916],[0,0],[0,0],[0,0],[29.492,3.576]],\"o\":[[0,0],[0,0],[29.275,0.739],[0,0],[0,0],[0,0],[-4.795,0.426]],\"v\":[[-15.459,-22.954],[-48.558,-1.023],[22.025,5.474],[79.278,2.027],[76.578,-27.194],[75.278,-37.904],[3.383,-30.236]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-30.224,-0.763],[0,0],[0,0],[0,0],[32.203,3.763]],\"o\":[[0,0],[0,0],[24.396,0.616],[0,0],[0,0],[0,0],[-3.996,0.355]],\"v\":[[-21.459,-26.128],[-49.041,-0.853],[22.696,4.562],[77.982,1.689],[77.025,-21.771],[76.538,-31.566],[0.396,-29.209]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[0,0],[0,0],[-30.224,-0.763],[0,0],[0,0],[0,0],[32.203,3.763]],\"o\":[[0,0],[0,0],[24.396,0.616],[0,0],[0,0],[0,0],[-3.996,0.355]],\"v\":[[-21.459,-26.128],[-49.041,-0.853],[22.696,4.562],[77.982,1.689],[77.025,-21.771],[76.538,-31.566],[0.396,-29.209]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-24.179,-0.61],[0,0],[0,0],[0,0],[38.059,3.335]],\"o\":[[0,0],[0,0],[19.517,0.493],[0,0],[0,0],[0,0],[-3.197,0.284]],\"v\":[[-27.459,-29.301],[-49.524,-0.682],[23.366,3.65],[74.441,0.898],[75.457,-25.129],[76.034,-33.867],[-4.053,-30.942]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":22,\"s\":[{\"i\":[[0,0],[0,0],[-24.179,-0.61],[0,0],[0,0],[0,0],[38.059,3.335]],\"o\":[[0,0],[0,0],[19.517,0.493],[0,0],[0,0],[0,0],[-3.197,0.284]],\"v\":[[-27.459,-29.301],[-49.524,-0.682],[23.366,3.65],[74.441,0.898],[75.457,-25.129],[76.034,-33.867],[-4.053,-30.942]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-18.134,-0.458],[0,0],[0,0],[0,0],[28.544,2.501]],\"o\":[[0,0],[0,0],[14.638,0.37],[0,0],[0,0],[0,0],[-2.398,0.213]],\"v\":[[-33.458,-32.475],[-44.734,-7.358],[24.037,2.737],[73.708,0.674],[66.444,-18.855],[66.149,-28.693],[0.499,-29.82]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":23,\"s\":[{\"i\":[[0,0],[0,0],[-18.134,-0.458],[0,0],[0,0],[0,0],[28.544,2.501]],\"o\":[[0,0],[0,0],[14.638,0.37],[0,0],[0,0],[0,0],[-2.398,0.213]],\"v\":[[-33.458,-32.475],[-44.734,-7.358],[24.037,2.737],[73.708,0.674],[66.444,-18.855],[66.149,-28.693],[0.499,-29.82]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-25.887,0.26],[0,0],[0,0],[0,0],[19.029,1.667]],\"o\":[[0,0],[0,0],[23.079,-0.232],[0,0],[0,0],[0,0],[-1.598,0.142]],\"v\":[[-39.458,-35.648],[-50.934,-0.245],[23.331,3.556],[74.885,0.533],[73.386,-9.426],[69.092,-35.457],[5.146,-33.879]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[0,0],[0,0],[-25.887,0.26],[0,0],[0,0],[0,0],[19.029,1.667]],\"o\":[[0,0],[0,0],[23.079,-0.232],[0,0],[0,0],[0,0],[-1.598,0.142]],\"v\":[[-39.458,-35.648],[-50.934,-0.245],[23.331,3.556],[74.885,0.533],[73.386,-9.426],[69.092,-35.457],[5.146,-33.879]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[-29.614,1.888],[0,0],[0,0],[0,0],[9.515,0.834]],\"o\":[[0,0],[0,0],[29.614,-1.888],[0,0],[0,0],[0,0],[-0.799,0.071]],\"v\":[[-45.458,-38.822],[-51.196,-0.123],[24.383,-2.21],[71.374,-0.596],[71.196,-10.036],[67.615,-41.027],[9.794,-37.937]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":25,\"s\":[{\"i\":[[0,0],[0,0],[-29.614,1.888],[0,0],[0,0],[0,0],[9.515,0.834]],\"o\":[[0,0],[0,0],[29.614,-1.888],[0,0],[0,0],[0,0],[-0.799,0.071]],\"v\":[[-45.458,-38.822],[-51.196,-0.123],[24.383,-2.21],[71.374,-0.596],[71.196,-10.036],[67.615,-41.027],[9.794,-37.937]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-51.457,-41.995],[-51.457,0],[26.048,0],[71.507,0],[71.507,-18.863],[71.507,-41.995],[14.441,-41.995]],\"c\":true}]},{\"t\":26}]},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 1\"}],\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-54.455,-34.192],[-52.283,18.884],[-13.504,24.771],[13.704,20.225],[68.467,7.776],[56.929,-57.361]],\"c\":true}},\"nm\":\"L\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[161,161],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"L\"}],\"ip\":11,\"op\":24,\"st\":-1,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":16,\"ty\":3,\"nm\":\"All rotation\",\"parent\":18,\"ks\":{\"o\":{\"k\":0},\"r\":{\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":0,\"s\":[37],\"e\":[0]},{\"t\":9}]},\"p\":{\"k\":[200,404,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.667,0.667,0.667],\"y\":[1,1,0.667]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0.333]},\"n\":[\"0p667_1_0p333_0\",\"0p667_1_0p333_0\",\"0p667_0p667_0p333_0p333\"],\"t\":0,\"s\":[50,50,100],\"e\":[100,100,100]},{\"t\":9}]}},\"ao\":0,\"ip\":0,\"op\":37,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":18,\"ty\":1,\"nm\":\"ResizerTemp\",\"parent\":19,\"ks\":{\"o\":{\"k\":0},\"r\":{\"k\":0},\"p\":{\"k\":[26.6,35.7,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[10.5,10.5,100]}},\"ao\":0,\"sw\":500,\"sh\":600,\"sc\":\"#ffffff\",\"ip\":0,\"op\":37,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":19,\"ty\":1,\"nm\":\"White Solid 41\",\"ks\":{\"o\":{\"k\":0},\"r\":{\"k\":0},\"p\":{\"k\":[40,50,0]},\"a\":{\"k\":[28,35,0]},\"s\":{\"k\":[142.857,142.857,100]}},\"ao\":0,\"sw\":56,\"sh\":70,\"sc\":\"#ffffff\",\"ip\":0,\"op\":37,\"st\":0,\"bm\":0,\"sr\":1}],\"v\":\"4.4.26\",\"ddd\":0,\"ip\":0,\"op\":37,\"fr\":25,\"w\":80,\"h\":100}"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/src/main/assets/S.json",
    "content": "{\"assets\":[],\"layers\":[{\"ddd\":0,\"ind\":0,\"ty\":4,\"nm\":\"S Outlines\",\"parent\":16,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[-0.015,-0.015,0]},\"a\":{\"k\":[-0.14,-118.547,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":0,\"s\":[{\"i\":[[-38.37,0],[0,41.693],[0,41.089],[-13.596,0],[-11.179,-12.689],[0,0],[27.493,0],[0,-44.11],[0,-42.297],[18.732,0],[7.855,18.43],[0,0]],\"o\":[[41.693,0],[0,-82.782],[0,-14.804],[13.293,0],[0,0],[-16.013,-19.034],[-35.651,0],[0,76.437],[0,14.502],[-21.451,0],[0,0],[13.898,28.4]],\"v\":[[3.486,3.021],[80.225,-63.446],[-24.914,-167.075],[-0.14,-188.525],[37.324,-168.887],[68.443,-197.891],[-0.14,-229.614],[-70.837,-164.053],[34.605,-63.748],[3.788,-40.485],[-42.437,-70.697],[-80.505,-46.829]],\"c\":true}],\"e\":[{\"i\":[[-38.37,0],[0,41.693],[0,41.089],[-13.596,0],[-11.179,-12.689],[0,0],[27.493,0],[0,-44.11],[0,-42.297],[18.732,0],[5.736,18.721],[0,0]],\"o\":[[41.693,0],[0,-82.782],[0,-14.804],[13.293,0],[0,0],[-16.013,-19.034],[-35.651,0],[0,76.437],[0,14.502],[-21.451,0],[0,0],[8.77,30.377]],\"v\":[[4.445,2.22],[80.974,-63.485],[-23.626,-166.391],[0.07,-184.531],[40.553,-155.037],[71.961,-183.305],[-0.574,-228.34],[-68.668,-165.669],[35.84,-64.063],[6.916,-42.902],[-42.382,-76.977],[-83.022,-60.364]],\"c\":true}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":18,\"s\":[{\"i\":[[-38.37,0],[0,41.693],[0,41.089],[-13.596,0],[-11.179,-12.689],[0,0],[27.493,0],[0,-44.11],[0,-42.297],[18.732,0],[5.736,18.721],[0,0]],\"o\":[[41.693,0],[0,-82.782],[0,-14.804],[13.293,0],[0,0],[-16.013,-19.034],[-35.651,0],[0,76.437],[0,14.502],[-21.451,0],[0,0],[8.77,30.377]],\"v\":[[4.445,2.22],[80.974,-63.485],[-23.626,-166.391],[0.07,-184.531],[40.553,-155.037],[71.961,-183.305],[-0.574,-228.34],[-68.668,-165.669],[35.84,-64.063],[6.916,-42.902],[-42.382,-76.977],[-83.022,-60.364]],\"c\":true}],\"e\":[{\"i\":[[-38.37,0],[0,41.693],[0,41.089],[-13.596,0],[-11.179,-12.689],[0,0],[27.493,0],[0,-44.11],[0,-42.297],[18.732,0],[7.855,18.43],[0,0]],\"o\":[[41.693,0],[0,-82.782],[0,-14.804],[13.293,0],[0,0],[-16.013,-19.034],[-35.651,0],[0,76.437],[0,14.502],[-21.451,0],[0,0],[13.898,28.4]],\"v\":[[3.486,3.021],[80.225,-63.446],[-24.914,-167.075],[-0.14,-188.525],[36.083,-169.409],[65.982,-200.185],[-0.14,-229.614],[-70.837,-164.053],[34.605,-63.748],[3.788,-40.485],[-40.235,-67.908],[-79.035,-45.053]],\"c\":true}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":23,\"s\":[{\"i\":[[-38.37,0],[0,41.693],[0,41.089],[-13.596,0],[-11.179,-12.689],[0,0],[27.493,0],[0,-44.11],[0,-42.297],[18.732,0],[7.855,18.43],[0,0]],\"o\":[[41.693,0],[0,-82.782],[0,-14.804],[13.293,0],[0,0],[-16.013,-19.034],[-35.651,0],[0,76.437],[0,14.502],[-21.451,0],[0,0],[13.898,28.4]],\"v\":[[3.486,3.021],[80.225,-63.446],[-24.914,-167.075],[-0.14,-188.525],[36.083,-169.409],[65.982,-200.185],[-0.14,-229.614],[-70.837,-164.053],[34.605,-63.748],[3.788,-40.485],[-40.235,-67.908],[-79.035,-45.053]],\"c\":true}],\"e\":[{\"i\":[[-38.37,0],[0,41.693],[0,41.089],[-13.596,0],[-11.179,-12.689],[0,0],[27.493,0],[0,-44.11],[0,-42.297],[18.732,0],[7.855,18.43],[0,0]],\"o\":[[41.693,0],[0,-82.782],[0,-14.804],[13.293,0],[0,0],[-16.013,-19.034],[-35.651,0],[0,76.437],[0,14.502],[-21.451,0],[0,0],[13.898,28.4]],\"v\":[[3.486,3.021],[80.225,-63.446],[-24.914,-167.075],[-0.14,-188.525],[37.324,-168.887],[68.443,-197.891],[-0.14,-229.614],[-70.837,-164.053],[34.605,-63.748],[3.788,-40.485],[-42.437,-70.697],[-80.505,-46.829]],\"c\":true}]},{\"t\":25}]},\"nm\":\"S\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"S\"}],\"ip\":18,\"op\":37,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":1,\"ty\":4,\"nm\":\"S Start\",\"parent\":17,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[250,280,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"rc\",\"d\":1,\"s\":{\"k\":[{\"i\":{\"x\":[0.833,0.833],\"y\":[0.833,0.833]},\"o\":{\"x\":[0.167,0.167],\"y\":[0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":0,\"s\":[44,0],\"e\":[44,44]},{\"i\":{\"x\":[0.833,0.833],\"y\":[0.833,0.833]},\"o\":{\"x\":[0.167,0.167],\"y\":[0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":3,\"s\":[44,44],\"e\":[44,55]},{\"t\":6}]},\"p\":{\"k\":[0,0]},\"r\":{\"k\":0},\"nm\":\"Rectangle Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\"}],\"ip\":0,\"op\":6,\"st\":-10,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":2,\"ty\":3,\"nm\":\"S Half 1 Position\",\"parent\":16,\"ks\":{\"o\":{\"k\":0},\"r\":{\"k\":180},\"p\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":0,\"s\":[2.868,0.533,0],\"e\":[2.745,0.434,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":1,\"s\":[2.745,0.434,0],\"e\":[0.27,1.349,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[0.27,1.349,0],\"e\":[-0.674,1.77,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":13,\"s\":[-0.674,1.77,0],\"e\":[5.017,2.831,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[5.017,2.831,0],\"e\":[2.272,3.682,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[2.272,3.682,0],\"e\":[8.681,3.135,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[8.681,3.135,0],\"e\":[6.073,3.007,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[6.073,3.007,0],\"e\":[0.473,2.975,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[0.473,2.975,0],\"e\":[0,3.5,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":22,\"s\":[0,3.5,0],\"e\":[0,3.5,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"t\":25}]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"ip\":0,\"op\":37,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":3,\"ty\":1,\"nm\":\"Medium Gray-Royal Blue Solid 2\",\"parent\":2,\"td\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":-50.4},\"p\":{\"k\":[20.589,-2.274,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"hasMask\":true,\"masksProperties\":[{\"inv\":false,\"mode\":\"a\",\"pt\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[157.548,213.516],[336.805,88.815],[509.326,416.135],[262.263,309.846],[198.954,266.992]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[157.548,213.516],[336.805,88.815],[509.326,416.135],[259.326,305.009],[183.593,291.306]],\"c\":true}]},{\"t\":17}]},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 1\"}],\"sw\":500,\"sh\":600,\"sc\":\"#416eb0\",\"ip\":6,\"op\":18,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":4,\"ty\":4,\"nm\":\"S Half 1\",\"parent\":2,\"tt\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":-69},\"p\":{\"k\":[17.35,6.501,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_0p833_0p333_0\",\"t\":0,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-13.144,38.707],[-10.555,31.766],[-16.109,48.597]],\"o\":[[-48.755,63.436],[31.77,-0.948],[14.063,-41.41],[14.357,-43.209],[31.244,-94.254]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[0.264,-17.385],[33.263,-118.602],[75.014,-241.424]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-25.391,22.5],[-19.169,24.293],[-26.423,53.905]],\"o\":[[-48.755,63.436],[31.77,-0.948],[21.921,-23.805],[19.169,-24.293],[60.34,-61.93]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.504,-17.877],[62.417,-86.985],[127.519,-189.919]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":6,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-25.391,22.5],[-19.169,24.293],[-26.423,53.905]],\"o\":[[-48.755,63.436],[31.77,-0.948],[21.921,-23.805],[19.169,-24.293],[60.34,-61.93]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.504,-17.877],[62.417,-86.985],[127.519,-189.919]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-28.036,19],[-21.372,20.816],[-31.166,51.686]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.912,-19.215],[21.865,-20.878],[66.623,-54.949]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.67,-17.983],[66.006,-72.265],[141.011,-169.751]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-28.036,19],[-21.372,20.816],[-31.166,51.686]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.912,-19.215],[21.865,-20.878],[66.623,-54.949]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.67,-17.983],[66.006,-72.265],[141.011,-169.751]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-30.68,15.501],[-23.576,17.34],[-35.908,49.466]],\"o\":[[-48.755,63.436],[31.77,-0.948],[25.902,-14.625],[24.562,-17.463],[72.907,-47.969]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.836,-18.089],[69.376,-57.995],[154.504,-149.582]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-30.68,15.501],[-23.576,17.34],[-35.908,49.466]],\"o\":[[-48.755,63.436],[31.77,-0.948],[25.902,-14.625],[24.562,-17.463],[72.907,-47.969]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.836,-18.089],[69.376,-57.995],[154.504,-149.582]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-33.325,12.001],[-25.779,13.863],[-40.65,47.247]],\"o\":[[-48.755,63.436],[31.77,-0.948],[27.893,-10.035],[27.258,-14.048],[79.19,-40.988]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.002,-18.196],[71.735,-45.003],[167.996,-129.414]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":9,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-33.325,12.001],[-25.779,13.863],[-40.65,47.247]],\"o\":[[-48.755,63.436],[31.77,-0.948],[27.893,-10.035],[27.258,-14.048],[79.19,-40.988]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.002,-18.196],[71.735,-45.003],[167.996,-129.414]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-35.969,8.501],[-27.983,10.387],[-44.889,39.683]],\"o\":[[-48.755,63.436],[31.77,-0.948],[29.191,-6.456],[29.954,-10.633],[85.474,-34.008]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.168,-18.302],[72.787,-36.619],[177.949,-107.754]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-35.969,8.501],[-27.983,10.387],[-44.889,39.683]],\"o\":[[-48.755,63.436],[31.77,-0.948],[29.191,-6.456],[29.954,-10.633],[85.474,-34.008]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.168,-18.302],[72.787,-36.619],[177.949,-107.754]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-38.614,5.001],[-30.186,6.91],[-49.129,32.119]],\"o\":[[-48.755,63.436],[31.77,-0.948],[30.49,-2.877],[32.651,-7.218],[91.757,-27.027]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.334,-18.408],[73.244,-29.181],[185.674,-86.278]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-38.614,5.001],[-30.186,6.91],[-49.129,32.119]],\"o\":[[-48.755,63.436],[31.77,-0.948],[30.49,-2.877],[32.651,-7.218],[91.757,-27.027]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.334,-18.408],[73.244,-29.181],[185.674,-86.278]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.022,3.137],[-31.359,5.059],[-39.276,16.342]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.341,-2.075],[34.087,-5.4],[95.103,-23.31]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.422,-18.465],[73.789,-25.635],[186.799,-62.683]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.022,3.137],[-31.359,5.059],[-39.276,16.342]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.341,-2.075],[34.087,-5.4],[95.103,-23.31]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.422,-18.465],[73.789,-25.635],[186.799,-62.683]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.825,2.076],[-32.028,4.004],[-33.662,7.354]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.825,-1.618],[34.905,-4.364],[97.01,-21.192]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.472,-18.497],[74.099,-23.615],[186.309,-43.065]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_0p833_0p333_0\",\"t\":13,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.825,2.076],[-32.028,4.004],[-33.662,7.354]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.825,-1.618],[34.905,-4.364],[97.01,-21.192]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.472,-18.497],[74.099,-23.615],[186.309,-43.065]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-32.208,9.824],[-32.062,2.748],[-32.911,-10.4]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.275,-8.874],[32.309,-2.288],[68.544,0.717]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.499,-15.347],[71.936,-32.429],[171.633,-21.674]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-32.208,9.824],[-32.062,2.748],[-32.911,-10.4]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.275,-8.874],[32.309,-2.288],[68.544,0.717]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.499,-15.347],[71.936,-32.429],[171.633,-21.674]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-23.591,17.571],[-32.096,1.493],[-19.175,-32.366]],\"o\":[[-48.755,63.436],[31.77,-0.948],[18.917,-15.79],[29.713,-0.213],[40.079,22.626]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-2.363,-16.111],[64.163,-55.885],[139.726,-0.265]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-23.591,17.571],[-32.096,1.493],[-19.175,-32.366]],\"o\":[[-48.755,63.436],[31.77,-0.948],[18.917,-15.79],[29.713,-0.213],[40.079,22.626]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-2.363,-16.111],[64.163,-55.885],[139.726,-0.265]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-6.089,21.355],[-43.828,2.289],[2.522,-42.41]],\"o\":[[-48.755,63.436],[31.77,-0.948],[10.807,-35.811],[37.463,5.632],[11.613,44.535]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-2.594,-6.627],[60.245,-67.029],[105.525,18.412]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-6.089,21.355],[-43.828,2.289],[2.522,-42.41]],\"o\":[[-48.755,63.436],[31.77,-0.948],[10.807,-35.811],[37.463,5.632],[11.613,44.535]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-2.594,-6.627],[60.245,-67.029],[105.525,18.412]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-4.64,34.278],[-29.264,-0.902],[27.265,-54.028]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-1.337,-65.69],[33.671,2.352],[-16.852,66.444]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.001,-7.715],[51.792,-83.071],[78.094,20.372]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-4.64,34.278],[-29.264,-0.902],[27.265,-54.028]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-1.337,-65.69],[33.671,2.352],[-16.852,66.444]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.001,-7.715],[51.792,-83.071],[78.094,20.372]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-35.73,0.479],[43.214,-42.137]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.935,-0.616],[-71.095,69.322]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.944,-2.493],[42.192,-93.986],[66.863,24.003]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":18,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-35.73,0.479],[43.214,-42.137]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.935,-0.616],[-71.095,69.322]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.944,-2.493],[42.192,-93.986],[66.863,24.003]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-0.449,40.875],[-39.993,2.038],[37.355,-43.128]],\"o\":[[-48.755,63.436],[31.77,-0.948],[0.642,-58.448],[45.879,-2.338],[-65.01,75.058]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.897,-2.638],[40.415,-94.559],[76.21,15.125]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":22,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-0.449,40.875],[-39.993,2.038],[37.355,-43.128]],\"o\":[[-48.755,63.436],[31.77,-0.948],[0.642,-58.448],[45.879,-2.338],[-65.01,75.058]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.897,-2.638],[40.415,-94.559],[76.21,15.125]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-0.449,40.875],[-39.993,2.038],[37.355,-43.128]],\"o\":[[-48.755,63.436],[31.77,-0.948],[0.642,-58.448],[45.879,-2.338],[-65.01,75.058]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.604,-2.747],[41.025,-92.919],[74.271,18.515]],\"c\":false}]},{\"t\":25}]},\"nm\":\"Path 1\"},{\"ty\":\"tm\",\"s\":{\"k\":0,\"ix\":1},\"e\":{\"k\":[{\"i\":{\"x\":[0.667],\"y\":[0.835]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_0p835_0p333_0\"],\"t\":0,\"s\":[50],\"e\":[55.073]},{\"i\":{\"x\":[0.667],\"y\":[-1.227]},\"o\":{\"x\":[0.333],\"y\":[2.227]},\"n\":[\"0p667_-1p227_0p333_2p227\"],\"t\":1,\"s\":[55.073],\"e\":[56.573]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0.25]},\"n\":[\"0p667_1_0p333_0p25\"],\"t\":5,\"s\":[56.573],\"e\":[100]},{\"t\":18}],\"ix\":2},\"o\":{\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"w\":{\"k\":43},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":6,\"op\":18,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":5,\"ty\":1,\"nm\":\"Medium Gray-Royal Blue Solid 2\",\"parent\":2,\"td\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":-50.4},\"p\":{\"k\":[20.589,-2.274,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"hasMask\":true,\"masksProperties\":[{\"inv\":false,\"mode\":\"a\",\"pt\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[157.549,213.516],[-8.291,213.727],[164.23,541.048],[267.359,303.802],[203.111,254.296]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[157.548,213.516],[6.827,343.576],[275.689,530.99],[268.39,303.776],[192.657,290.073]],\"c\":true}]},{\"t\":17}]},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 1\"}],\"sw\":500,\"sh\":600,\"sc\":\"#416eb0\",\"ip\":6,\"op\":18,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":6,\"ty\":4,\"nm\":\"S Half 2\",\"parent\":16,\"tt\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":-69},\"p\":{\"k\":[17.35,6.501,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_0p833_0p333_0\",\"t\":0,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-13.144,38.707],[-10.555,31.766],[-16.109,48.597]],\"o\":[[-48.755,63.436],[31.77,-0.948],[14.063,-41.41],[14.357,-43.209],[31.244,-94.254]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[0.264,-17.385],[33.263,-118.602],[75.014,-241.424]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-25.391,22.5],[-19.169,24.293],[-26.423,53.905]],\"o\":[[-48.755,63.436],[31.77,-0.948],[21.921,-23.805],[19.169,-24.293],[60.34,-61.93]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.504,-17.877],[62.417,-86.985],[127.519,-189.919]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":6,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-25.391,22.5],[-19.169,24.293],[-26.423,53.905]],\"o\":[[-48.755,63.436],[31.77,-0.948],[21.921,-23.805],[19.169,-24.293],[60.34,-61.93]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.504,-17.877],[62.417,-86.985],[127.519,-189.919]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-28.036,19],[-21.372,20.816],[-31.166,51.686]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.912,-19.215],[21.865,-20.878],[66.623,-54.949]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.67,-17.983],[66.006,-72.265],[141.011,-169.751]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-28.036,19],[-21.372,20.816],[-31.166,51.686]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.912,-19.215],[21.865,-20.878],[66.623,-54.949]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.67,-17.983],[66.006,-72.265],[141.011,-169.751]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-30.68,15.501],[-23.576,17.34],[-35.908,49.466]],\"o\":[[-48.755,63.436],[31.77,-0.948],[25.902,-14.625],[24.562,-17.463],[72.907,-47.969]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.836,-18.089],[69.376,-57.995],[154.504,-149.582]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-30.68,15.501],[-23.576,17.34],[-35.908,49.466]],\"o\":[[-48.755,63.436],[31.77,-0.948],[25.902,-14.625],[24.562,-17.463],[72.907,-47.969]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.836,-18.089],[69.376,-57.995],[154.504,-149.582]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-33.325,12.001],[-25.779,13.863],[-40.65,47.247]],\"o\":[[-48.755,63.436],[31.77,-0.948],[27.893,-10.035],[27.258,-14.048],[79.19,-40.988]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.002,-18.196],[71.735,-45.003],[167.996,-129.414]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":9,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-33.325,12.001],[-25.779,13.863],[-40.65,47.247]],\"o\":[[-48.755,63.436],[31.77,-0.948],[27.893,-10.035],[27.258,-14.048],[79.19,-40.988]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.002,-18.196],[71.735,-45.003],[167.996,-129.414]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-35.969,8.501],[-27.983,10.387],[-44.889,39.683]],\"o\":[[-48.755,63.436],[31.77,-0.948],[29.191,-6.456],[29.954,-10.633],[85.474,-34.008]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.168,-18.302],[72.787,-36.619],[177.949,-107.754]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-35.969,8.501],[-27.983,10.387],[-44.889,39.683]],\"o\":[[-48.755,63.436],[31.77,-0.948],[29.191,-6.456],[29.954,-10.633],[85.474,-34.008]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.168,-18.302],[72.787,-36.619],[177.949,-107.754]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-38.614,5.001],[-30.186,6.91],[-49.129,32.119]],\"o\":[[-48.755,63.436],[31.77,-0.948],[30.49,-2.877],[32.651,-7.218],[91.757,-27.027]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.334,-18.408],[73.244,-29.181],[185.674,-86.278]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-38.614,5.001],[-30.186,6.91],[-49.129,32.119]],\"o\":[[-48.755,63.436],[31.77,-0.948],[30.49,-2.877],[32.651,-7.218],[91.757,-27.027]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.334,-18.408],[73.244,-29.181],[185.674,-86.278]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.022,3.137],[-31.359,5.059],[-39.276,16.342]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.341,-2.075],[34.087,-5.4],[95.103,-23.31]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.422,-18.465],[73.789,-25.635],[186.799,-62.683]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.022,3.137],[-31.359,5.059],[-39.276,16.342]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.341,-2.075],[34.087,-5.4],[95.103,-23.31]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.422,-18.465],[73.789,-25.635],[186.799,-62.683]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.825,2.076],[-32.028,4.004],[-33.662,7.354]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.825,-1.618],[34.905,-4.364],[97.01,-21.192]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.472,-18.497],[74.099,-23.615],[186.309,-43.065]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_0p833_0p333_0\",\"t\":13,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.825,2.076],[-32.028,4.004],[-33.662,7.354]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.825,-1.618],[34.905,-4.364],[97.01,-21.192]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.472,-18.497],[74.099,-23.615],[186.309,-43.065]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-32.208,9.824],[-32.062,2.748],[-32.911,-10.4]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.275,-8.874],[32.309,-2.288],[68.544,0.717]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.499,-15.347],[71.936,-32.429],[171.633,-21.674]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-32.208,9.824],[-32.062,2.748],[-32.911,-10.4]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.275,-8.874],[32.309,-2.288],[68.544,0.717]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.499,-15.347],[71.936,-32.429],[171.633,-21.674]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-23.591,17.571],[-32.096,1.493],[-14.855,-21.353]],\"o\":[[-48.755,63.436],[31.77,-0.948],[18.917,-15.79],[29.713,-0.213],[40.079,22.626]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-2.363,-16.111],[65.145,-49.966],[139.726,-0.265]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-23.591,17.571],[-32.096,1.493],[-14.855,-21.353]],\"o\":[[-48.755,63.436],[31.77,-0.948],[18.917,-15.79],[29.713,-0.213],[40.079,22.626]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-2.363,-16.111],[65.145,-49.966],[139.726,-0.265]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-14.974,25.319],[-34.761,-0.676],[0.212,-31.999]],\"o\":[[-48.755,63.436],[31.77,-0.948],[10.782,-35.831],[37.463,5.632],[11.613,44.535]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.492,-8.678],[58.69,-65.586],[108.233,10.247]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-14.974,25.319],[-34.761,-0.676],[0.212,-31.999]],\"o\":[[-48.755,63.436],[31.77,-0.948],[10.782,-35.831],[37.463,5.632],[11.613,44.535]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.492,-8.678],[58.69,-65.586],[108.233,10.247]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-6.357,33.067],[-32.163,-1.018],[18.882,-47.646]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-0.623,-55.054],[33.671,2.352],[-16.852,66.444]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.009,-7.043],[48.978,-75.477],[78.055,14.987]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-6.357,33.067],[-32.163,-1.018],[18.882,-47.646]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-0.623,-55.054],[33.671,2.352],[-16.852,66.444]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.009,-7.043],[48.978,-75.477],[78.055,14.987]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.197,-2.274],[20.4,-39.774]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[40.224,2.841],[-45.317,88.353]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.919,-3.052],[49.064,-78.565],[66.993,16.341]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":18,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.197,-2.274],[20.4,-39.774]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[40.224,2.841],[-45.317,88.353]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.919,-3.052],[49.064,-78.565],[66.993,16.341]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.234,0.724],[13.367,-36.444]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[44.758,-1.109],[-33.684,93.197]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.313,-2.322],[43.863,-82.38],[81.942,4.044]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":22,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.234,0.724],[13.367,-36.444]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[44.758,-1.109],[-33.684,93.197]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.313,-2.322],[43.863,-82.38],[81.942,4.044]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[16.5,-33.767]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-43.595,89.216]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[79.285,8.556]],\"c\":false}]},{\"t\":25}]},\"nm\":\"Path 1\"},{\"ty\":\"tm\",\"s\":{\"k\":0,\"ix\":1},\"e\":{\"k\":[{\"i\":{\"x\":[0.667],\"y\":[0.809]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_0p809_0p333_0\"],\"t\":0,\"s\":[50],\"e\":[54.381]},{\"i\":{\"x\":[0.667],\"y\":[-1.092]},\"o\":{\"x\":[0.333],\"y\":[2.092]},\"n\":[\"0p667_-1p092_0p333_2p092\"],\"t\":1,\"s\":[54.381],\"e\":[55.981]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0.247]},\"n\":[\"0p667_1_0p333_0p247\"],\"t\":5,\"s\":[55.981],\"e\":[100]},{\"t\":18}],\"ix\":2},\"o\":{\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"w\":{\"k\":43},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":6,\"op\":18,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":7,\"ty\":1,\"nm\":\"Medium Gray-Royal Blue Solid 2\",\"parent\":2,\"td\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":-50.4},\"p\":{\"k\":[20.589,-2.274,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"hasMask\":true,\"masksProperties\":[{\"inv\":false,\"mode\":\"a\",\"pt\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[157.549,213.516],[-8.291,213.727],[164.23,541.048],[267.359,303.802],[203.111,254.296]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[157.549,213.516],[-8.291,213.727],[164.23,541.048],[257.128,321.693],[211.558,245.538]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":13,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[157.549,213.516],[-8.291,213.727],[164.23,541.048],[257.128,321.693],[211.558,245.538]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[157.548,213.516],[45.318,288.083],[217.839,615.403],[276.718,310.734],[192.657,290.073]],\"c\":true}]},{\"t\":17}]},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 1\"}],\"sw\":500,\"sh\":600,\"sc\":\"#416eb0\",\"ip\":0,\"op\":25,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":8,\"ty\":4,\"nm\":\"Sleeve\",\"parent\":16,\"tt\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":-69},\"p\":{\"k\":[17.35,6.501,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_0p833_0p333_0\",\"t\":0,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-13.144,38.707],[-10.555,31.766],[-16.109,48.597]],\"o\":[[-48.755,63.436],[31.77,-0.948],[14.063,-41.41],[14.357,-43.209],[31.244,-94.254]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[0.264,-17.385],[33.263,-118.602],[75.014,-241.424]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-18.052,32.212],[-14.007,28.771],[-20.242,50.724]],\"o\":[[-48.755,63.436],[31.77,-0.948],[17.212,-34.356],[16.285,-35.629],[42.903,-81.301]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.044,-17.582],[22.249,-65.945],[86.755,-200.764]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":3,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-18.052,32.212],[-14.007,28.771],[-20.242,50.724]],\"o\":[[-48.755,63.436],[31.77,-0.948],[17.212,-34.356],[16.285,-35.629],[42.903,-81.301]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.044,-17.582],[22.249,-65.945],[86.755,-200.764]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-20.371,29.143],[-15.638,27.355],[-22.196,51.729]],\"o\":[[-48.755,63.436],[31.77,-0.948],[18.7,-31.021],[17.197,-32.046],[48.414,-75.178]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.19,-17.675],[32.119,-72.427],[107.38,-212.916]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":4,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-20.371,29.143],[-15.638,27.355],[-22.196,51.729]],\"o\":[[-48.755,63.436],[31.77,-0.948],[18.7,-31.021],[17.197,-32.046],[48.414,-75.178]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.19,-17.675],[32.119,-72.427],[107.38,-212.916]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-22.831,25.888],[-17.368,25.855],[-24.267,52.795]],\"o\":[[-48.755,63.436],[31.77,-0.948],[20.278,-27.486],[18.163,-28.247],[54.257,-68.687]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.344,-17.774],[33.167,-62.907],[119.831,-209.409]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-22.831,25.888],[-17.368,25.855],[-24.267,52.795]],\"o\":[[-48.755,63.436],[31.77,-0.948],[20.278,-27.486],[18.163,-28.247],[54.257,-68.687]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.344,-17.774],[33.167,-62.907],[119.831,-209.409]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-25.391,22.5],[-19.169,24.293],[-26.423,53.905]],\"o\":[[-48.755,63.436],[31.77,-0.948],[21.921,-23.805],[19.169,-24.293],[60.34,-61.93]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.504,-17.877],[50.413,-73.563],[126.066,-191.293]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":6,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-25.391,22.5],[-19.169,24.293],[-26.423,53.905]],\"o\":[[-48.755,63.436],[31.77,-0.948],[21.921,-23.805],[19.169,-24.293],[60.34,-61.93]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.504,-17.877],[50.413,-73.563],[126.066,-191.293]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-28.036,19],[-21.372,20.816],[-31.166,51.686]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.912,-19.215],[21.865,-20.878],[66.623,-54.949]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.67,-17.983],[46.23,-58.224],[124.489,-176.552]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-28.036,19],[-21.372,20.816],[-31.166,51.686]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.912,-19.215],[21.865,-20.878],[66.623,-54.949]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.67,-17.983],[46.23,-58.224],[124.489,-176.552]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-30.68,15.501],[-23.576,17.34],[-35.908,49.466]],\"o\":[[-48.755,63.436],[31.77,-0.948],[25.902,-14.625],[24.562,-17.463],[72.907,-47.969]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.836,-18.089],[46.646,-45.01],[141.12,-155.509]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-30.68,15.501],[-23.576,17.34],[-35.908,49.466]],\"o\":[[-48.755,63.436],[31.77,-0.948],[25.902,-14.625],[24.562,-17.463],[72.907,-47.969]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.836,-18.089],[46.646,-45.01],[141.12,-155.509]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-33.325,12.001],[-25.779,13.863],[-40.65,47.247]],\"o\":[[-48.755,63.436],[31.77,-0.948],[27.893,-10.035],[27.258,-14.048],[79.19,-40.988]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.002,-18.196],[71.735,-45.003],[145.792,-143.314]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":9,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-33.325,12.001],[-25.779,13.863],[-40.65,47.247]],\"o\":[[-48.755,63.436],[31.77,-0.948],[27.893,-10.035],[27.258,-14.048],[79.19,-40.988]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.002,-18.196],[71.735,-45.003],[145.792,-143.314]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-35.969,8.501],[-27.983,10.387],[-44.889,39.683]],\"o\":[[-48.755,63.436],[31.77,-0.948],[29.191,-6.456],[29.954,-10.633],[85.474,-34.008]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.168,-18.302],[72.787,-36.619],[164.915,-118.354]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-35.969,8.501],[-27.983,10.387],[-44.889,39.683]],\"o\":[[-48.755,63.436],[31.77,-0.948],[29.191,-6.456],[29.954,-10.633],[85.474,-34.008]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.168,-18.302],[72.787,-36.619],[164.915,-118.354]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-38.614,5.001],[-30.186,6.91],[-49.128,32.119]],\"o\":[[-48.755,63.436],[31.77,-0.948],[30.49,-2.877],[32.651,-7.218],[91.757,-27.027]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.334,-18.408],[73.244,-29.181],[178.267,-90.417]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-38.614,5.001],[-30.186,6.91],[-49.128,32.119]],\"o\":[[-48.755,63.436],[31.77,-0.948],[30.49,-2.877],[32.651,-7.218],[91.757,-27.027]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.334,-18.408],[73.244,-29.181],[178.267,-90.417]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.022,3.137],[-31.359,5.059],[-39.276,16.342]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.341,-2.075],[34.087,-5.4],[95.103,-23.31]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.422,-18.465],[73.789,-25.635],[180.476,-65.557]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.022,3.137],[-31.359,5.059],[-39.276,16.342]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.341,-2.075],[34.087,-5.4],[95.103,-23.31]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.422,-18.465],[73.789,-25.635],[180.476,-65.557]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.825,2.076],[-32.028,4.004],[-33.662,7.354]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.825,-1.618],[34.905,-4.364],[97.01,-21.192]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.472,-18.497],[74.099,-23.615],[181.179,-45.767]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_0p833_0p333_0\",\"t\":13,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.825,2.076],[-32.028,4.004],[-33.662,7.354]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.825,-1.618],[34.905,-4.364],[97.01,-21.192]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.472,-18.497],[74.099,-23.615],[181.179,-45.767]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-32.208,9.824],[-32.062,2.748],[-32.911,-10.4]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.275,-8.874],[32.309,-2.288],[68.544,0.717]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.499,-15.347],[71.936,-32.429],[167.809,-25.441]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-32.208,9.824],[-32.062,2.748],[-32.911,-10.4]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.275,-8.874],[32.309,-2.288],[68.544,0.717]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.499,-15.347],[71.936,-32.429],[167.809,-25.441]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-23.591,17.571],[-32.096,1.493],[-14.855,-21.353]],\"o\":[[-48.755,63.436],[31.77,-0.948],[18.917,-15.79],[29.713,-0.213],[40.079,22.626]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-2.363,-16.111],[65.145,-49.966],[139.773,-4.765]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-23.591,17.571],[-32.096,1.493],[-14.855,-21.353]],\"o\":[[-48.755,63.436],[31.77,-0.948],[18.917,-15.79],[29.713,-0.213],[40.079,22.626]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-2.363,-16.111],[65.145,-49.966],[139.773,-4.765]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-14.974,25.319],[-34.761,-0.676],[0.212,-31.999]],\"o\":[[-48.755,63.436],[31.77,-0.948],[10.782,-35.831],[37.463,5.632],[11.613,44.535]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.492,-8.678],[58.69,-65.586],[109.927,6.294]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-14.974,25.319],[-34.761,-0.676],[0.212,-31.999]],\"o\":[[-48.755,63.436],[31.77,-0.948],[10.782,-35.831],[37.463,5.632],[11.613,44.535]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.492,-8.678],[58.69,-65.586],[109.927,6.294]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-6.357,33.067],[-32.163,-1.018],[18.882,-47.646]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-0.623,-55.054],[33.671,2.352],[-16.852,66.444]],\"v\":[[-88.083,-45.182],[-47.532,57.637],[-0.009,-7.043],[48.978,-75.477],[82.081,12.915]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-6.357,33.067],[-32.163,-1.018],[18.882,-47.646]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-0.623,-55.054],[33.671,2.352],[-16.852,66.444]],\"v\":[[-88.083,-45.182],[-47.532,57.637],[-0.009,-7.043],[48.978,-75.477],[82.081,12.915]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.197,-2.274],[20.4,-39.774]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[40.224,2.841],[-45.317,88.353]],\"v\":[[-88.528,-42.016],[-47.532,57.637],[-0.919,-3.052],[49.064,-78.565],[72.144,13.774]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_0p833_0p333_0\",\"t\":18,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.197,-2.274],[20.4,-39.774]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[40.224,2.841],[-45.317,88.353]],\"v\":[[-88.528,-42.016],[-47.532,57.637],[-0.919,-3.052],[49.064,-78.565],[72.144,13.774]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.204,-1.73],[22.911,-37.624]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[41.047,2.124],[-43.206,89.232]],\"v\":[[-88.023,-40.472],[-47.532,57.637],[-0.991,-2.919],[48.12,-79.258],[72.28,14.439]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":19,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.204,-1.73],[22.911,-37.624]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[41.047,2.124],[-43.206,89.232]],\"v\":[[-88.023,-40.472],[-47.532,57.637],[-0.991,-2.919],[48.12,-79.258],[72.28,14.439]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.216,-0.775],[25.971,-33.848]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[42.491,0.866],[-39.5,90.775]],\"v\":[[-87.137,-37.763],[-47.532,57.637],[-1.116,-2.687],[46.463,-80.473],[73.652,10.85]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":20,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.216,-0.775],[25.971,-33.848]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[42.491,0.866],[-39.5,90.775]],\"v\":[[-87.137,-37.763],[-47.532,57.637],[-1.116,-2.687],[46.463,-80.473],[73.652,10.85]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.227,0.18],[18.43,-35.503]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[43.935,-0.392],[-35.795,92.318]],\"v\":[[-84.958,-44.422],[-47.532,57.637],[-1.241,-2.454],[44.807,-81.688],[77.192,8.098]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.227,0.18],[18.43,-35.503]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[43.935,-0.392],[-35.795,92.318]],\"v\":[[-84.958,-44.422],[-47.532,57.637],[-1.241,-2.454],[44.807,-81.688],[77.192,8.098]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.234,0.724],[16.27,-36.178]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[44.758,-1.109],[-33.684,93.197]],\"v\":[[-93.365,-39.106],[-47.532,57.637],[-1.313,-2.322],[43.863,-82.38],[80.535,4.564]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_0p833_0p333_0\",\"t\":22,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.234,0.724],[16.27,-36.178]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[44.758,-1.109],[-33.684,93.197]],\"v\":[[-93.365,-39.106],[-47.532,57.637],[-1.313,-2.322],[43.863,-82.38],[80.535,4.564]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.237,0.918],[14.814,-33.525]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[39.578,2.006],[-36.253,92.165]],\"v\":[[-86.619,-43.804],[-47.532,57.637],[-1.388,-2.432],[43.526,-82.627],[85.368,-0.902]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":23,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.237,0.918],[14.814,-33.525]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[39.578,2.006],[-36.253,92.165]],\"v\":[[-86.619,-43.804],[-47.532,57.637],[-1.388,-2.432],[43.526,-82.627],[85.368,-0.902]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.241,1.272],[15.171,-34.19]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.586,-1.831],[-40.931,90.286]],\"v\":[[-86.326,-45.002],[-47.532,57.637],[-1.526,-2.632],[42.912,-83.077],[85.719,-9.595]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.241,1.272],[15.171,-34.19]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.586,-1.831],[-40.931,90.286]],\"v\":[[-86.326,-45.002],[-47.532,57.637],[-1.526,-2.632],[42.912,-83.077],[85.719,-9.595]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[16.5,-33.767]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-43.595,89.216]],\"v\":[[-87.207,-40.139],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[79.952,4.016]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_1_0p333_0\",\"t\":25,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[16.5,-33.767]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-43.595,89.216]],\"v\":[[-87.207,-40.139],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[79.952,4.016]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[24.943,-36.221]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-56.318,81.782]],\"v\":[[-89.574,-43.515],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[80.132,4.483]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p833_0p833_0p167_0\",\"t\":26,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[24.943,-36.221]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-56.318,81.782]],\"v\":[[-89.574,-43.515],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[80.132,4.483]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[22.952,-38.269]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-51.062,84.942]],\"v\":[[-84.043,-47.245],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[80.275,4.16]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_1_0p167_0p167\",\"t\":27,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[22.952,-38.269]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-51.062,84.942]],\"v\":[[-84.043,-47.245],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[80.275,4.16]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.27,0.688],[20.961,-40.316]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[34.923,-0.744],[-45.805,88.101]],\"v\":[[-84.623,-38.988],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[79.719,4.105]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p833_1_0p167_0\",\"t\":28,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.27,0.688],[20.961,-40.316]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[34.923,-0.744],[-45.805,88.101]],\"v\":[[-84.623,-38.988],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[79.719,4.105]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.198,2.258],[20.961,-40.316]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[30.113,-2.112],[-45.805,88.101]],\"v\":[[-84.623,-38.988],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[82.487,-1.242]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p833_1_0p167_0\",\"t\":29,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.198,2.258],[20.961,-40.316]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[30.113,-2.112],[-45.805,88.101]],\"v\":[[-84.623,-38.988],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[82.487,-1.242]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[20.961,-40.316]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-45.805,88.101]],\"v\":[[-84.623,-38.988],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[85.938,-8.993]],\"c\":false}]},{\"t\":30}]},\"nm\":\"Path 1\"},{\"ty\":\"tm\",\"s\":{\"k\":0,\"ix\":1},\"e\":{\"k\":[{\"i\":{\"x\":[0.667],\"y\":[0.809]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_0p809_0p333_0\"],\"t\":0,\"s\":[50],\"e\":[54.381]},{\"i\":{\"x\":[0.667],\"y\":[-1.092]},\"o\":{\"x\":[0.333],\"y\":[2.092]},\"n\":[\"0p667_-1p092_0p333_2p092\"],\"t\":1,\"s\":[54.381],\"e\":[55.981]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0.247]},\"n\":[\"0p667_1_0p333_0p247\"],\"t\":5,\"s\":[55.981],\"e\":[100]},{\"t\":18}],\"ix\":2},\"o\":{\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.32,0.5,1]},\"o\":{\"k\":100},\"w\":{\"k\":30},\"lc\":3,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":4,\"op\":25,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":9,\"ty\":1,\"nm\":\"Medium Gray-Royal Blue Solid 2\",\"parent\":2,\"td\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":-50.4},\"p\":{\"k\":[20.589,-2.274,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"hasMask\":true,\"masksProperties\":[{\"inv\":false,\"mode\":\"a\",\"pt\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[157.549,213.516],[-8.291,213.727],[164.23,541.048],[267.359,303.802],[203.111,254.296]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[157.549,213.516],[-8.291,213.727],[164.23,541.048],[257.128,321.693],[211.558,245.538]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":13,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[157.549,213.516],[-8.291,213.727],[164.23,541.048],[257.128,321.693],[211.558,245.538]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[157.548,213.516],[45.318,288.083],[217.839,615.403],[276.718,310.734],[192.657,290.073]],\"c\":true}]},{\"t\":17}]},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 1\"}],\"sw\":500,\"sh\":600,\"sc\":\"#416eb0\",\"ip\":0,\"op\":25,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":10,\"ty\":4,\"nm\":\"Arm\",\"parent\":16,\"tt\":1,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":-69},\"p\":{\"k\":[17.35,6.501,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_0p833_0p333_0\",\"t\":0,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-13.144,38.707],[-10.555,31.766],[-16.109,48.597]],\"o\":[[-48.755,63.436],[31.77,-0.948],[14.063,-41.41],[14.357,-43.209],[31.244,-94.254]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[0.264,-17.385],[33.263,-118.602],[75.014,-241.424]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-22.831,25.888],[-17.368,25.855],[-24.267,52.795]],\"o\":[[-48.755,63.436],[31.77,-0.948],[20.278,-27.486],[18.163,-28.247],[54.257,-68.687]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.344,-17.774],[57.999,-93.642],[144.664,-240.143]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-22.831,25.888],[-17.368,25.855],[-24.267,52.795]],\"o\":[[-48.755,63.436],[31.77,-0.948],[20.278,-27.486],[18.163,-28.247],[54.257,-68.687]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.344,-17.774],[57.999,-93.642],[144.664,-240.143]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-25.391,22.5],[-19.169,24.293],[-26.423,53.905]],\"o\":[[-48.755,63.436],[31.77,-0.948],[21.921,-23.805],[19.169,-24.293],[60.34,-61.93]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.504,-17.877],[64.538,-87.044],[140.19,-204.774]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":6,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-25.391,22.5],[-19.169,24.293],[-26.423,53.905]],\"o\":[[-48.755,63.436],[31.77,-0.948],[21.921,-23.805],[19.169,-24.293],[60.34,-61.93]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.504,-17.877],[64.538,-87.044],[140.19,-204.774]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-28.036,19],[-21.372,20.816],[-31.166,51.686]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.912,-19.215],[21.865,-20.878],[66.623,-54.949]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.67,-17.983],[67.981,-78.458],[146.24,-196.786]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-28.036,19],[-21.372,20.816],[-31.166,51.686]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.912,-19.215],[21.865,-20.878],[66.623,-54.949]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.67,-17.983],[67.981,-78.458],[146.24,-196.786]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-30.68,15.501],[-23.576,17.34],[-35.908,49.466]],\"o\":[[-48.755,63.436],[31.77,-0.948],[25.902,-14.625],[24.562,-17.463],[72.907,-47.969]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.836,-18.089],[70.468,-62.611],[164.942,-173.11]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-30.68,15.501],[-23.576,17.34],[-35.908,49.466]],\"o\":[[-48.755,63.436],[31.77,-0.948],[25.902,-14.625],[24.562,-17.463],[72.907,-47.969]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-0.836,-18.089],[70.468,-62.611],[164.942,-173.11]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-33.325,12.001],[-25.779,13.863],[-40.65,47.247]],\"o\":[[-48.755,63.436],[31.77,-0.948],[27.893,-10.035],[27.258,-14.048],[79.19,-40.988]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.002,-18.196],[71.735,-45.003],[172.591,-155.315]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":9,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-33.325,12.001],[-25.779,13.863],[-40.65,47.247]],\"o\":[[-48.755,63.436],[31.77,-0.948],[27.893,-10.035],[27.258,-14.048],[79.19,-40.988]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.002,-18.196],[71.735,-45.003],[172.591,-155.315]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-35.969,8.501],[-27.982,10.387],[-44.889,39.683]],\"o\":[[-48.755,63.436],[31.77,-0.948],[29.191,-6.456],[29.954,-10.633],[85.474,-34.008]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.168,-18.302],[72.787,-36.619],[183.962,-130.005]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-35.969,8.501],[-27.982,10.387],[-44.889,39.683]],\"o\":[[-48.755,63.436],[31.77,-0.948],[29.191,-6.456],[29.954,-10.633],[85.474,-34.008]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.168,-18.302],[72.787,-36.619],[183.962,-130.005]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-38.614,5.001],[-30.186,6.91],[-49.129,32.119]],\"o\":[[-48.755,63.436],[31.77,-0.948],[30.49,-2.877],[32.651,-7.218],[91.757,-27.027]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.334,-18.408],[73.244,-29.181],[200.206,-102.864]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-38.614,5.001],[-30.186,6.91],[-49.129,32.119]],\"o\":[[-48.755,63.436],[31.77,-0.948],[30.49,-2.877],[32.651,-7.218],[91.757,-27.027]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.334,-18.408],[73.244,-29.181],[200.206,-102.864]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.022,3.137],[-31.359,5.059],[-39.276,16.342]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.341,-2.075],[34.087,-5.4],[95.103,-23.31]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.422,-18.465],[73.789,-25.635],[205.57,-75.974]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.022,3.137],[-31.359,5.059],[-39.276,16.342]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.341,-2.075],[34.087,-5.4],[95.103,-23.31]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.422,-18.465],[73.789,-25.635],[205.57,-75.974]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.825,2.076],[-32.028,4.004],[-33.662,7.354]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.825,-1.618],[34.905,-4.364],[97.01,-21.192]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.472,-18.497],[74.099,-23.615],[204.569,-51.598]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_0p833_0p333_0\",\"t\":13,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-40.825,2.076],[-32.028,4.004],[-33.662,7.354]],\"o\":[[-48.755,63.436],[31.77,-0.948],[31.825,-1.618],[34.905,-4.364],[97.01,-21.192]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.472,-18.497],[74.099,-23.615],[204.569,-51.598]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-32.208,9.824],[-32.062,2.748],[-32.911,-10.4]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.275,-8.874],[32.309,-2.288],[68.544,0.717]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.499,-15.347],[71.936,-32.429],[191.128,-23.098]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-32.208,9.824],[-32.062,2.748],[-32.911,-10.4]],\"o\":[[-48.755,63.436],[31.77,-0.948],[23.275,-8.874],[32.309,-2.288],[68.544,0.717]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.499,-15.347],[71.936,-32.429],[191.128,-23.098]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-23.591,17.571],[-32.096,1.493],[-14.855,-21.353]],\"o\":[[-48.755,63.436],[31.77,-0.948],[18.917,-15.79],[29.713,-0.213],[40.079,22.626]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-2.363,-16.111],[65.145,-49.966],[154.616,10.39]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-23.591,17.571],[-32.096,1.493],[-14.855,-21.353]],\"o\":[[-48.755,63.436],[31.77,-0.948],[18.917,-15.79],[29.713,-0.213],[40.079,22.626]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-2.363,-16.111],[65.145,-49.966],[154.616,10.39]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-14.974,25.319],[-34.761,-0.676],[0.212,-31.999]],\"o\":[[-48.755,63.436],[31.77,-0.948],[10.782,-35.831],[37.463,5.632],[11.613,44.535]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.492,-8.678],[58.69,-65.586],[112.615,30.274]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-14.974,25.319],[-34.761,-0.676],[0.212,-31.999]],\"o\":[[-48.755,63.436],[31.77,-0.948],[10.782,-35.831],[37.463,5.632],[11.613,44.535]],\"v\":[[-78.079,-55.425],[-47.532,57.637],[-1.492,-8.678],[58.69,-65.586],[112.615,30.274]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-6.357,33.067],[-32.163,-1.018],[18.882,-47.646]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-0.623,-55.054],[33.671,2.352],[-16.852,66.444]],\"v\":[[-88.083,-45.182],[-47.532,57.637],[-0.009,-7.043],[48.978,-75.477],[74.889,33.324]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[-6.357,33.067],[-32.163,-1.018],[18.882,-47.646]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-0.623,-55.054],[33.671,2.352],[-16.852,66.444]],\"v\":[[-88.083,-45.182],[-47.532,57.637],[-0.009,-7.043],[48.978,-75.477],[74.889,33.324]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.197,-2.274],[20.4,-39.774]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[40.224,2.841],[-45.317,88.353]],\"v\":[[-88.528,-42.016],[-47.532,57.637],[-0.919,-3.052],[49.064,-78.565],[61.953,33.91]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_0p833_0p333_0\",\"t\":18,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.197,-2.274],[20.4,-39.774]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[40.224,2.841],[-45.317,88.353]],\"v\":[[-88.528,-42.016],[-47.532,57.637],[-0.919,-3.052],[49.064,-78.565],[61.953,33.91]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.216,-0.775],[27.318,-33.851]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[42.491,0.866],[-39.5,90.775]],\"v\":[[-87.137,-37.763],[-47.532,57.637],[-1.116,-2.687],[46.463,-80.473],[61.989,26.058]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":20,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.216,-0.775],[27.318,-33.851]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[42.491,0.866],[-39.5,90.775]],\"v\":[[-87.137,-37.763],[-47.532,57.637],[-1.116,-2.687],[46.463,-80.473],[61.989,26.058]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.227,0.18],[18.43,-35.503]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[43.935,-0.392],[-35.795,92.318]],\"v\":[[-84.958,-44.422],[-47.532,57.637],[-1.241,-2.454],[44.807,-81.688],[69.881,19.744]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":21,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.227,0.18],[18.43,-35.503]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[43.935,-0.392],[-35.795,92.318]],\"v\":[[-84.958,-44.422],[-47.532,57.637],[-1.241,-2.454],[44.807,-81.688],[69.881,19.744]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.234,0.724],[13.367,-36.444]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[44.758,-1.109],[-33.684,93.197]],\"v\":[[-93.365,-39.106],[-47.532,57.637],[-1.313,-2.322],[43.863,-82.38],[73.577,16.736]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_0p833_0p333_0\",\"t\":22,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.234,0.724],[13.367,-36.444]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[44.758,-1.109],[-33.684,93.197]],\"v\":[[-93.365,-39.106],[-47.532,57.637],[-1.313,-2.322],[43.863,-82.38],[73.577,16.736]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.237,0.918],[14.814,-33.525]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.051,-1.365],[-36.253,92.165]],\"v\":[[-86.619,-43.804],[-47.532,57.637],[-1.388,-2.432],[43.526,-82.627],[77.429,18.217]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":23,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.237,0.918],[14.814,-33.525]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.051,-1.365],[-36.253,92.165]],\"v\":[[-86.619,-43.804],[-47.532,57.637],[-1.388,-2.432],[43.526,-82.627],[77.429,18.217]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.241,1.272],[15.888,-33.679]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.586,-1.831],[-40.931,90.286]],\"v\":[[-86.326,-45.002],[-47.532,57.637],[-1.526,-2.632],[42.912,-83.077],[75.08,16.832]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":24,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.241,1.272],[15.888,-33.679]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.586,-1.831],[-40.931,90.286]],\"v\":[[-86.326,-45.002],[-47.532,57.637],[-1.526,-2.632],[42.912,-83.077],[75.08,16.832]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[16.5,-33.767]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-43.595,89.216]],\"v\":[[-87.207,-40.139],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[73.609,16.091]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_1_0p333_0\",\"t\":25,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[16.5,-33.767]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-43.595,89.216]],\"v\":[[-87.207,-40.139],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[73.609,16.091]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[24.943,-36.221]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-56.318,81.782]],\"v\":[[-89.574,-43.515],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[72.119,16.395]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p833_0p833_0p167_0\",\"t\":26,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[24.943,-36.221]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-56.318,81.782]],\"v\":[[-89.574,-43.515],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[72.119,16.395]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[22.952,-38.269]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-51.062,84.942]],\"v\":[[-84.043,-47.245],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[72.477,17.329]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_1_0p167_0p167\",\"t\":27,\"s\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[22.952,-38.269]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-51.062,84.942]],\"v\":[[-84.043,-47.245],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[72.477,17.329]],\"c\":false}],\"e\":[{\"i\":[[46.121,-60.008],[-24.32,0.726],[2.26,40.815],[-32.244,1.473],[20.961,-40.316]],\"o\":[[-48.755,63.436],[31.77,-0.948],[-3.247,-58.639],[45.891,-2.097],[-45.805,88.101]],\"v\":[[-84.623,-38.988],[-47.532,57.637],[-1.604,-2.747],[42.562,-83.333],[72.835,18.263]],\"c\":false}]},{\"t\":28}]},\"nm\":\"Path 1\"},{\"ty\":\"tm\",\"s\":{\"k\":0,\"ix\":1},\"e\":{\"k\":[{\"i\":{\"x\":[0.667],\"y\":[0.809]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_0p809_0p333_0\"],\"t\":0,\"s\":[50],\"e\":[54.381]},{\"i\":{\"x\":[0.667],\"y\":[-1.092]},\"o\":{\"x\":[0.333],\"y\":[2.092]},\"n\":[\"0p667_-1p092_0p333_2p092\"],\"t\":1,\"s\":[54.381],\"e\":[55.981]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0.247]},\"n\":[\"0p667_1_0p333_0p247\"],\"t\":5,\"s\":[55.981],\"e\":[100]},{\"t\":18}],\"ix\":2},\"o\":{\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"w\":{\"k\":24},\"lc\":3,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":3,\"op\":25,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":11,\"ty\":3,\"nm\":\"FootNull\",\"parent\":17,\"ks\":{\"o\":{\"k\":0},\"r\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":4,\"s\":[-90],\"e\":[-87.8]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":5,\"s\":[-87.8],\"e\":[-87.5]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":6,\"s\":[-87.5],\"e\":[-78.6]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":7,\"s\":[-78.6],\"e\":[-62.9]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":8,\"s\":[-62.9],\"e\":[-46.2]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":9,\"s\":[-46.2],\"e\":[-29.2]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":10,\"s\":[-29.2],\"e\":[-8.4]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":11,\"s\":[-8.4],\"e\":[16.3]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":12,\"s\":[16.3],\"e\":[44.8]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":13,\"s\":[44.8],\"e\":[83.4]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":14,\"s\":[83.4],\"e\":[142.6]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":15,\"s\":[142.6],\"e\":[193]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":16,\"s\":[193],\"e\":[226]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":17,\"s\":[226],\"e\":[250.8]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":18,\"s\":[250.8],\"e\":[248.8]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":19,\"s\":[248.8],\"e\":[246.1]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":20,\"s\":[246.1],\"e\":[242.4]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":21,\"s\":[242.4],\"e\":[238.7]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":22,\"s\":[238.7],\"e\":[295.267]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":24,\"s\":[295.267],\"e\":[306.4]},{\"t\":25}]},\"p\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":1,\"s\":[228.125,273,0],\"e\":[228.125,265.125,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":2,\"s\":[228.125,265.125,0],\"e\":[228.125,258,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":3,\"s\":[228.125,258,0],\"e\":[228.125,256.125,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":4,\"s\":[228.125,256.125,0],\"e\":[228.125,254.25,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[228.125,254.25,0],\"e\":[228.125,248.25,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":6,\"s\":[228.125,248.25,0],\"e\":[238.375,233.5,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7,\"s\":[238.375,233.5,0],\"e\":[261.25,219.75,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[261.25,219.75,0],\"e\":[295.75,216.875,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":9,\"s\":[295.75,216.875,0],\"e\":[330.875,232.375,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[330.875,232.375,0],\"e\":[360.875,268.25,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[360.875,268.25,0],\"e\":[370.375,317.625,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[370.375,317.625,0],\"e\":[358.25,372.25,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":13,\"s\":[358.25,372.25,0],\"e\":[327.75,410.375,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[327.75,410.375,0],\"e\":[265,431,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[265,431,0],\"e\":[204.25,401.5,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[204.25,401.5,0],\"e\":[178.375,360.25,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[178.375,360.25,0],\"e\":[164.75,335.125,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[164.75,335.125,0],\"e\":[165.75,338.375,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":19,\"s\":[165.75,338.375,0],\"e\":[167.875,343.625,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":20,\"s\":[167.875,343.625,0],\"e\":[170,349.5,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[170,349.5,0],\"e\":[173.25,358.5,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":22,\"s\":[173.25,358.5,0],\"e\":[163.917,359.882,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":23,\"s\":[163.917,359.882,0],\"e\":[176.334,378.626,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[176.334,378.626,0],\"e\":[190,398.125,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"t\":25}]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"ip\":0,\"op\":37,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":12,\"ty\":3,\"nm\":\"HandNull\",\"parent\":17,\"ks\":{\"o\":{\"k\":0},\"r\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":2,\"s\":[-270],\"e\":[-269.9]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":3,\"s\":[-269.9],\"e\":[-270]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":4,\"s\":[-270],\"e\":[-269.9]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":5,\"s\":[-269.9],\"e\":[-269.8]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":6,\"s\":[-269.8],\"e\":[-257.9]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":7,\"s\":[-257.9],\"e\":[-242.1]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":8,\"s\":[-242.1],\"e\":[-225.9]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":9,\"s\":[-225.9],\"e\":[-207.9]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":10,\"s\":[-207.9],\"e\":[-188.3]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":11,\"s\":[-188.3],\"e\":[-163]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":12,\"s\":[-163],\"e\":[-134.6]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":13,\"s\":[-134.6],\"e\":[-96.4]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":14,\"s\":[-96.4],\"e\":[-42.3]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":15,\"s\":[-42.3],\"e\":[8.3]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":16,\"s\":[8.3],\"e\":[41.6]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":17,\"s\":[41.6],\"e\":[50.9]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":18,\"s\":[50.9],\"e\":[50.1]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":19,\"s\":[50.1],\"e\":[48.2]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":20,\"s\":[48.2],\"e\":[45.3]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":21,\"s\":[45.3],\"e\":[44.6]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":22,\"s\":[44.6],\"e\":[43.3]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":23,\"s\":[43.3],\"e\":[45.1]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":24,\"s\":[45.1],\"e\":[46.8]},{\"t\":25}]},\"p\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":0,\"s\":[270.875,280.75,0],\"e\":[272,287.375,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":1,\"s\":[272,287.375,0],\"e\":[272,295,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":2,\"s\":[272,295,0],\"e\":[272,302.125,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":3,\"s\":[272,302.125,0],\"e\":[272,303.875,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":4,\"s\":[272,303.875,0],\"e\":[272,305,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[272,305,0],\"e\":[271,310.375,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":6,\"s\":[271,310.375,0],\"e\":[262.062,326.125,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7,\"s\":[262.062,326.125,0],\"e\":[240,340.438,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[240,340.438,0],\"e\":[206.188,343.625,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":9,\"s\":[206.188,343.625,0],\"e\":[171.25,329.562,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[171.25,329.562,0],\"e\":[141.75,294.875,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[141.75,294.875,0],\"e\":[131.75,246.75,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[131.75,246.75,0],\"e\":[143.125,192.75,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":13,\"s\":[143.125,192.75,0],\"e\":[177.875,152.25,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[177.875,152.25,0],\"e\":[237.75,137.5,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[237.75,137.5,0],\"e\":[295.25,159.125,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[295.25,159.125,0],\"e\":[321.438,202.75,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[321.438,202.75,0],\"e\":[325.25,220.75,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[325.25,220.75,0],\"e\":[323.875,218.625,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":19,\"s\":[323.875,218.625,0],\"e\":[321.5,212.875,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":20,\"s\":[321.5,212.875,0],\"e\":[318.25,206.375,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21,\"s\":[318.25,206.375,0],\"e\":[316.125,201,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":22,\"s\":[316.125,201,0],\"e\":[314.5,198.875,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":23,\"s\":[314.5,198.875,0],\"e\":[316.5,200.875,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24,\"s\":[316.5,200.875,0],\"e\":[318.375,202.5,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"t\":25}]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"ip\":0,\"op\":37,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":13,\"ty\":4,\"nm\":\"Hand\",\"parent\":12,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":6,\"s\":[92.5],\"e\":[57.5]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0.333]},\"n\":[\"0p833_0p833_0p333_0p333\"],\"t\":8,\"s\":[57.5],\"e\":[57.5]},{\"i\":{\"x\":[0.833],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_1_0p167_0p167\"],\"t\":18,\"s\":[57.5],\"e\":[109.3]},{\"i\":{\"x\":[0.833],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0]},\"n\":[\"0p833_1_0p167_0\"],\"t\":20,\"s\":[109.3],\"e\":[88.8]},{\"t\":23}]},\"p\":{\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":1,\"s\":[-49.086,22.028,0],\"e\":[16.619,21.966,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":5,\"s\":[16.619,21.966,0],\"e\":[21.014,21.528,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":8,\"s\":[21.014,21.528,0],\"e\":[16.619,21.966,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p833_0p833_0p333_0\",\"t\":22,\"s\":[16.619,21.966,0],\"e\":[-55.711,22.372,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"t\":25}]},\"a\":{\"k\":[-1.077,24.664,0]},\"s\":{\"k\":[80,80,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":2,\"s\":[{\"i\":[[0.916,5.582],[-0.007,6.497]],\"o\":[[-1.375,-8.375],[0.007,-6.731]],\"v\":[[-18.375,0.375],[-17.876,-22.4]],\"c\":false}],\"e\":[{\"i\":[[0.916,5.582],[4.63,7.763]],\"o\":[[-1.375,-8.375],[-3.448,-5.781]],\"v\":[[-18.375,0.375],[-26.713,-20.596]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":6,\"s\":[{\"i\":[[0.916,5.582],[4.63,7.763]],\"o\":[[-1.375,-8.375],[-3.448,-5.781]],\"v\":[[-18.375,0.375],[-26.713,-20.596]],\"c\":false}],\"e\":[{\"i\":[[0.916,5.582],[-1.023,6.899]],\"o\":[[-1.375,-8.375],[0.987,-6.659]],\"v\":[[-18.375,0.375],[-22.067,-24.193]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p667_1_0p167_0\",\"t\":9,\"s\":[{\"i\":[[0.916,5.582],[-1.023,6.899]],\"o\":[[-1.375,-8.375],[0.987,-6.659]],\"v\":[[-18.375,0.375],[-22.067,-24.193]],\"c\":false}],\"e\":[{\"i\":[[0.916,5.582],[-1.023,6.899]],\"o\":[[-1.375,-8.375],[0.987,-6.659]],\"v\":[[-18.375,0.375],[-22.067,-24.193]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p667_1_0p167_0\",\"t\":19,\"s\":[{\"i\":[[0.916,5.582],[-1.023,6.899]],\"o\":[[-1.375,-8.375],[0.987,-6.659]],\"v\":[[-18.375,0.375],[-22.067,-24.193]],\"c\":false}],\"e\":[{\"i\":[[0.916,5.582],[3,7.625]],\"o\":[[-1.375,-8.375],[-2.465,-6.264]],\"v\":[[-18.375,0.375],[-24.5,-21.125]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p833_1_0p167_0\",\"t\":22,\"s\":[{\"i\":[[0.916,5.582],[3,7.625]],\"o\":[[-1.375,-8.375],[-2.465,-6.264]],\"v\":[[-18.375,0.375],[-24.5,-21.125]],\"c\":false}],\"e\":[{\"i\":[[0.916,5.582],[-0.007,6.497]],\"o\":[[-1.375,-8.375],[0.007,-6.731]],\"v\":[[-18.375,0.375],[-17.876,-22.4]],\"c\":false}]},{\"t\":25}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"w\":{\"k\":12.5},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 5\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":2,\"s\":[{\"i\":[[0.208,5.653],[-0.834,7.548]],\"o\":[[-0.354,-9.588],[0.74,-6.691]],\"v\":[[-7.375,-9.625],[-6.621,-33.005]],\"c\":false}],\"e\":[{\"i\":[[0.916,5.582],[2.825,9.71]],\"o\":[[-1.375,-8.375],[-1.88,-6.463]],\"v\":[[-7.375,-9.625],[-13.123,-34.54]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":6,\"s\":[{\"i\":[[0.916,5.582],[2.825,9.71]],\"o\":[[-1.375,-8.375],[-1.88,-6.463]],\"v\":[[-7.375,-9.625],[-13.123,-34.54]],\"c\":false}],\"e\":[{\"i\":[[0.916,5.582],[-1.611,7.514]],\"o\":[[-1.375,-8.375],[1.411,-6.582]],\"v\":[[-7.375,-9.625],[-6.312,-35.508]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p667_1_0p167_0\",\"t\":9,\"s\":[{\"i\":[[0.916,5.582],[-1.611,7.514]],\"o\":[[-1.375,-8.375],[1.411,-6.582]],\"v\":[[-7.375,-9.625],[-6.312,-35.508]],\"c\":false}],\"e\":[{\"i\":[[0.916,5.582],[-1.611,7.514]],\"o\":[[-1.375,-8.375],[1.411,-6.582]],\"v\":[[-7.375,-9.625],[-6.312,-35.508]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p667_1_0p167_0\",\"t\":19,\"s\":[{\"i\":[[0.916,5.582],[-1.611,7.514]],\"o\":[[-1.375,-8.375],[1.411,-6.582]],\"v\":[[-7.375,-9.625],[-6.312,-35.508]],\"c\":false}],\"e\":[{\"i\":[[0.916,5.582],[1.75,9.375]],\"o\":[[-1.375,-8.375],[-1.235,-6.617]],\"v\":[[-7.375,-9.625],[-11.25,-34.458]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p833_1_0p167_0\",\"t\":22,\"s\":[{\"i\":[[0.916,5.582],[1.75,9.375]],\"o\":[[-1.375,-8.375],[-1.235,-6.617]],\"v\":[[-7.375,-9.625],[-11.25,-34.458]],\"c\":false}],\"e\":[{\"i\":[[0.208,5.653],[-0.834,7.548]],\"o\":[[-0.354,-9.588],[0.74,-6.691]],\"v\":[[-7.375,-9.625],[-6.621,-33.005]],\"c\":false}]},{\"t\":25}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"w\":{\"k\":12.5},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 4\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":2,\"s\":[{\"i\":[[-0.676,5.616],[-0.471,9.931]],\"o\":[[1.356,-11.255],[0.319,-6.724]],\"v\":[[2.875,-9.625],[5.327,-37.978]],\"c\":false}],\"e\":[{\"i\":[[-0.818,5.597],[-1.75,10.625]],\"o\":[[1.625,-11.125],[1.094,-6.642]],\"v\":[[2.875,-9.625],[7.485,-37.258]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":6,\"s\":[{\"i\":[[-0.818,5.597],[-1.75,10.625]],\"o\":[[1.625,-11.125],[1.094,-6.642]],\"v\":[[2.875,-9.625],[7.485,-37.258]],\"c\":false}],\"e\":[{\"i\":[[-0.818,5.597],[-4.699,6.193]],\"o\":[[1.625,-11.125],[4.069,-5.363]],\"v\":[[2.875,-9.625],[11.793,-36.668]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p667_1_0p167_0\",\"t\":9,\"s\":[{\"i\":[[-0.818,5.597],[-4.699,6.193]],\"o\":[[1.625,-11.125],[4.069,-5.363]],\"v\":[[2.875,-9.625],[11.793,-36.668]],\"c\":false}],\"e\":[{\"i\":[[-0.818,5.597],[-4.699,6.193]],\"o\":[[1.625,-11.125],[4.069,-5.363]],\"v\":[[2.875,-9.625],[11.793,-36.668]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p667_1_0p167_0\",\"t\":19,\"s\":[{\"i\":[[-0.818,5.597],[-4.699,6.193]],\"o\":[[1.625,-11.125],[4.069,-5.363]],\"v\":[[2.875,-9.625],[11.793,-36.668]],\"c\":false}],\"e\":[{\"i\":[[-0.818,5.597],[-1.75,10.625]],\"o\":[[1.625,-11.125],[1.094,-6.642]],\"v\":[[2.875,-9.625],[6.25,-37.625]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p833_1_0p167_0\",\"t\":22,\"s\":[{\"i\":[[-0.818,5.597],[-1.75,10.625]],\"o\":[[1.625,-11.125],[1.094,-6.642]],\"v\":[[2.875,-9.625],[6.25,-37.625]],\"c\":false}],\"e\":[{\"i\":[[-0.676,5.616],[-0.471,9.931]],\"o\":[[1.356,-11.255],[0.319,-6.724]],\"v\":[[2.875,-9.625],[5.327,-37.978]],\"c\":false}]},{\"t\":25}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"w\":{\"k\":12.5},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 3\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":2,\"s\":[{\"i\":[[-1.009,5.566],[-0.253,8.059]],\"o\":[[2.002,-11.047],[0.211,-6.728]],\"v\":[[12.625,-4.375],[15.845,-31.258]],\"c\":false}],\"e\":[{\"i\":[[-1.753,5.379],[-3.312,6.486]],\"o\":[[3.625,-11.125],[3.061,-5.995]],\"v\":[[12.625,-4.375],[24.858,-29.926]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":6,\"s\":[{\"i\":[[-1.753,5.379],[-3.312,6.486]],\"o\":[[3.625,-11.125],[3.061,-5.995]],\"v\":[[12.625,-4.375],[24.858,-29.926]],\"c\":false}],\"e\":[{\"i\":[[-1.753,5.379],[-8.159,4.511]],\"o\":[[3.625,-11.125],[5.891,-3.257]],\"v\":[[12.625,-4.375],[28.863,-25.658]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p667_1_0p167_0\",\"t\":9,\"s\":[{\"i\":[[-1.753,5.379],[-8.159,4.511]],\"o\":[[3.625,-11.125],[5.891,-3.257]],\"v\":[[12.625,-4.375],[28.863,-25.658]],\"c\":false}],\"e\":[{\"i\":[[-1.753,5.379],[-8.159,4.511]],\"o\":[[3.625,-11.125],[5.891,-3.257]],\"v\":[[12.625,-4.375],[28.863,-25.658]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p667_1_0p167_0\",\"t\":19,\"s\":[{\"i\":[[-1.753,5.379],[-8.159,4.511]],\"o\":[[3.625,-11.125],[5.891,-3.257]],\"v\":[[12.625,-4.375],[28.863,-25.658]],\"c\":false}],\"e\":[{\"i\":[[-1.753,5.379],[-3.5,9.375]],\"o\":[[3.625,-11.125],[2.354,-6.306]],\"v\":[[12.625,-4.375],[21.75,-30.375]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p833_1_0p167_0\",\"t\":22,\"s\":[{\"i\":[[-1.753,5.379],[-3.5,9.375]],\"o\":[[3.625,-11.125],[2.354,-6.306]],\"v\":[[12.625,-4.375],[21.75,-30.375]],\"c\":false}],\"e\":[{\"i\":[[-1.009,5.566],[-0.253,8.059]],\"o\":[[2.002,-11.047],[0.211,-6.728]],\"v\":[[12.625,-4.375],[15.845,-31.258]],\"c\":false}]},{\"t\":25}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"w\":{\"k\":12.5},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 2\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":2,\"s\":[{\"i\":[[-1.138,5.541],[0.866,4.868]],\"o\":[[1.715,-8.348],[-1.179,-6.627]],\"v\":[[18.625,5.375],[18.43,-12.578]],\"c\":false}],\"e\":[{\"i\":[[-2.657,4.994],[-3.5,0.875]],\"o\":[[3.125,-5.875],[6.53,-1.633]],\"v\":[[18.625,5.375],[34.174,-0.63]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.333,\"y\":0},\"n\":\"0p667_1_0p333_0\",\"t\":6,\"s\":[{\"i\":[[-2.657,4.994],[-3.5,0.875]],\"o\":[[3.125,-5.875],[6.53,-1.633]],\"v\":[[18.625,5.375],[34.174,-0.63]],\"c\":false}],\"e\":[{\"i\":[[-2.657,4.994],[-5.543,-1.777]],\"o\":[[3.125,-5.875],[6.41,2.054]],\"v\":[[18.625,5.375],[33.485,-0.678]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p667_1_0p167_0\",\"t\":9,\"s\":[{\"i\":[[-2.657,4.994],[-5.543,-1.777]],\"o\":[[3.125,-5.875],[6.41,2.054]],\"v\":[[18.625,5.375],[33.485,-0.678]],\"c\":false}],\"e\":[{\"i\":[[-2.657,4.994],[-5.543,-1.777]],\"o\":[[3.125,-5.875],[6.41,2.054]],\"v\":[[18.625,5.375],[33.485,-0.678]],\"c\":false}]},{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p667_1_0p167_0\",\"t\":19,\"s\":[{\"i\":[[-2.657,4.994],[-5.543,-1.777]],\"o\":[[3.125,-5.875],[6.41,2.054]],\"v\":[[18.625,5.375],[33.485,-0.678]],\"c\":false}],\"e\":[{\"i\":[[-2.657,4.994],[-3.5,0.875]],\"o\":[[3.125,-5.875],[6.53,-1.633]],\"v\":[[18.625,5.375],[31.5,-3.875]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":1},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p833_1_0p167_0\",\"t\":22,\"s\":[{\"i\":[[-2.657,4.994],[-3.5,0.875]],\"o\":[[3.125,-5.875],[6.53,-1.633]],\"v\":[[18.625,5.375],[31.5,-3.875]],\"c\":false}],\"e\":[{\"i\":[[-1.138,5.541],[0.866,4.868]],\"o\":[[1.715,-8.348],[-1.179,-6.627]],\"v\":[[18.625,5.375],[18.43,-12.578]],\"c\":false}]},{\"t\":25}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"w\":{\"k\":12.5},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"},{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"k\":[50,50]},\"p\":{\"k\":[0,0]},\"nm\":\"Ellipse Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\"}],\"ip\":3,\"op\":25,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":14,\"ty\":4,\"nm\":\"Shoe\",\"parent\":11,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.185],\"y\":[0.185]},\"n\":[\"0p833_0p833_0p185_0p185\"],\"t\":1,\"s\":[350.1],\"e\":[350.1]},{\"i\":{\"x\":[0.575],\"y\":[0.154]},\"o\":{\"x\":[0.185],\"y\":[0]},\"n\":[\"0p575_0p154_0p185_0\"],\"t\":2,\"s\":[350.1],\"e\":[331.62]},{\"i\":{\"x\":[0.703],\"y\":[1]},\"o\":{\"x\":[0.341],\"y\":[0.257]},\"n\":[\"0p703_1_0p341_0p257\"],\"t\":4,\"s\":[331.62],\"e\":[282.9]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":6,\"s\":[282.9],\"e\":[253.486]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":9,\"s\":[253.486],\"e\":[250.2]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":13,\"s\":[250.2],\"e\":[291.6]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p833_0p833_0p333_0\"],\"t\":20,\"s\":[291.6],\"e\":[304.262]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p667_1_0p167_0p167\"],\"t\":22,\"s\":[304.262],\"e\":[278.8]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0]},\"n\":[\"0p667_1_0p167_0\"],\"t\":27,\"s\":[278.8],\"e\":[282.9]},{\"t\":30}]},\"p\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":1,\"s\":[-58.434,14.26,0],\"e\":[-46.134,13.06,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":2,\"s\":[-46.134,13.06,0],\"e\":[-29.953,12.11,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":3,\"s\":[-29.953,12.11,0],\"e\":[-10.778,12.16,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":4,\"s\":[-10.778,12.16,0],\"e\":[3.894,17.21,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[3.894,17.21,0],\"e\":[12.566,22.26,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":6,\"s\":[12.566,22.26,0],\"e\":[12.566,22.26,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"t\":25}]},\"a\":{\"k\":[-81.625,145.258,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[2.438,-0.094],[18.125,6.562],[0,0],[0,0],[0,0],[0.125,2.75],[-28.875,0.141]],\"o\":[[-1.812,0.016],[-3.625,-0.062],[0,0],[0,0],[0,0],[13.875,5],[2.75,0]],\"v\":[[42,-0.406],[-12.125,-6.312],[-33.812,-6.312],[-33.812,3],[-12.875,3],[-12.875,-3],[41.875,2.938]],\"c\":true}},\"nm\":\"Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[-64.375,169.25],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 2\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[-49.375,150.25],[-50.75,153.875]],\"c\":false}},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"w\":{\"k\":3},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 3\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[-53.75,148.25],[-55.375,152]],\"c\":false}},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"w\":{\"k\":3},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 2\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0.437,-1.972],[-4.357,1.829]],\"o\":[[-0.704,3.175],[7.423,-3.117]],\"v\":[[-66.757,143.065],[-60.694,150.987]],\"c\":true}},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"w\":{\"k\":3},\"lc\":2,\"lj\":2,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[9.29,1.227],[11.384,7.629],[3.25,7.375],[0,0],[-5.745,-0.037],[-3.125,0.016]],\"o\":[[-13.25,-1.75],[1.009,9.754],[-5,8.25],[0,0],[30.63,6.713],[7.125,-2.234]],\"v\":[[35.5,5.125],[-7.634,-9.879],[-30.125,-4.25],[-33.75,14.375],[-13.63,14.412],[37.5,19.984]],\"c\":true}},\"nm\":\"Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[-63,150.5],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\"}],\"ip\":3,\"op\":25,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":15,\"ty\":4,\"nm\":\"Sock\",\"parent\":11,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":121.3},\"p\":{\"k\":[7.884,95.787,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[{\"i\":[[-4.741,-10.62],[-8.5,-10.5]],\"o\":[[6.25,14],[8.5,10.5]],\"v\":[[-71.802,35.423],[-46,63.5]],\"c\":false}],\"e\":[{\"i\":[[-4.741,-10.62],[-8.5,-10.5]],\"o\":[[6.25,14],[8.5,10.5]],\"v\":[[-71,23.5],[-46,63.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":6,\"s\":[{\"i\":[[-4.741,-10.62],[-8.5,-10.5]],\"o\":[[6.25,14],[8.5,10.5]],\"v\":[[-71,23.5],[-46,63.5]],\"c\":false}],\"e\":[{\"i\":[[-5.571,-10.057],[-7.689,-10.78]],\"o\":[[9.042,16.528],[7.767,10.952]],\"v\":[[-71.35,23.936],[-46,63.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[{\"i\":[[-5.571,-10.057],[-7.689,-10.78]],\"o\":[[9.042,16.528],[7.767,10.952]],\"v\":[[-71.35,23.936],[-46,63.5]],\"c\":false}],\"e\":[{\"i\":[[-5.987,-9.776],[-7.283,-10.919]],\"o\":[[11.843,16.458],[7.401,11.178]],\"v\":[[-71.525,24.154],[-46,63.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":9,\"s\":[{\"i\":[[-5.987,-9.776],[-7.283,-10.919]],\"o\":[[11.843,16.458],[7.401,11.178]],\"v\":[[-71.525,24.154],[-46,63.5]],\"c\":false}],\"e\":[{\"i\":[[-6.402,-9.495],[-6.878,-11.059]],\"o\":[[12.471,15.313],[7.034,11.404]],\"v\":[[-71.7,24.372],[-46,63.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[-6.402,-9.495],[-6.878,-11.059]],\"o\":[[12.471,15.313],[7.034,11.404]],\"v\":[[-71.7,24.372],[-46,63.5]],\"c\":false}],\"e\":[{\"i\":[[-6.817,-9.213],[-6.472,-11.199]],\"o\":[[12.754,13.049],[6.668,11.63]],\"v\":[[-71.874,24.59],[-46,63.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[-6.817,-9.213],[-6.472,-11.199]],\"o\":[[12.754,13.049],[6.668,11.63]],\"v\":[[-71.874,24.59],[-46,63.5]],\"c\":false}],\"e\":[{\"i\":[[-7.232,-8.932],[-6.067,-11.339]],\"o\":[[12.377,12.821],[6.301,11.856]],\"v\":[[-72.049,24.808],[-46,63.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[-7.232,-8.932],[-6.067,-11.339]],\"o\":[[12.377,12.821],[6.301,11.856]],\"v\":[[-72.049,24.808],[-46,63.5]],\"c\":false}],\"e\":[{\"i\":[[-7.648,-8.651],[-5.661,-11.479]],\"o\":[[11.225,12.698],[5.935,12.082]],\"v\":[[-72.224,25.026],[-46,63.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":13,\"s\":[{\"i\":[[-7.648,-8.651],[-5.661,-11.479]],\"o\":[[11.225,12.698],[5.935,12.082]],\"v\":[[-72.224,25.026],[-46,63.5]],\"c\":false}],\"e\":[{\"i\":[[-7.571,-8.784],[-5.256,-11.619]],\"o\":[[10.215,11.851],[5.568,12.308]],\"v\":[[-72.399,25.244],[-46,63.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14,\"s\":[{\"i\":[[-7.571,-8.784],[-5.256,-11.619]],\"o\":[[10.215,11.851],[5.568,12.308]],\"v\":[[-72.399,25.244],[-46,63.5]],\"c\":false}],\"e\":[{\"i\":[[-6.712,-9.482],[-8.5,-10.5]],\"o\":[[9.651,13.633],[8.5,10.5]],\"v\":[[-71,23.5],[-46,63.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":15,\"s\":[{\"i\":[[-6.712,-9.482],[-8.5,-10.5]],\"o\":[[9.651,13.633],[8.5,10.5]],\"v\":[[-71,23.5],[-46,63.5]],\"c\":false}],\"e\":[{\"i\":[[-6.214,-9.828],[-8.5,-10.5]],\"o\":[[8.689,13.742],[8.5,10.5]],\"v\":[[-71,23.5],[-46,63.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16,\"s\":[{\"i\":[[-6.214,-9.828],[-8.5,-10.5]],\"o\":[[8.689,13.742],[8.5,10.5]],\"v\":[[-71,23.5],[-46,63.5]],\"c\":false}],\"e\":[{\"i\":[[-5.461,-10.268],[-8.5,-10.5]],\"o\":[[7.232,13.599],[8.5,10.5]],\"v\":[[-71,23.5],[-46,63.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":17,\"s\":[{\"i\":[[-5.461,-10.268],[-8.5,-10.5]],\"o\":[[7.232,13.599],[8.5,10.5]],\"v\":[[-71,23.5],[-46,63.5]],\"c\":false}],\"e\":[{\"i\":[[-4.741,-10.62],[-8.5,-10.5]],\"o\":[[6.25,14],[8.5,10.5]],\"v\":[[-71,23.5],[-46,63.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":18,\"s\":[{\"i\":[[-4.741,-10.62],[-8.5,-10.5]],\"o\":[[6.25,14],[8.5,10.5]],\"v\":[[-71,23.5],[-46,63.5]],\"c\":false}],\"e\":[{\"i\":[[-4.188,-10.85],[-8.5,-10.5]],\"o\":[[5.5,14.25],[8.5,10.5]],\"v\":[[-71,23.5],[-46,63.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":22,\"s\":[{\"i\":[[-4.188,-10.85],[-8.5,-10.5]],\"o\":[[5.5,14.25],[8.5,10.5]],\"v\":[[-71,23.5],[-46,63.5]],\"c\":false}],\"e\":[{\"i\":[[-10.631,-4.715],[-20.345,-3.918]],\"o\":[[20.511,9.097],[13.266,2.554]],\"v\":[[-76.944,26.698],[-32.347,45.082]],\"c\":false}]},{\"t\":23}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.32,0.5,1]},\"o\":{\"k\":100},\"w\":{\"k\":20},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":5,\"op\":23,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":16,\"ty\":3,\"nm\":\"Rotation Null\",\"parent\":17,\"ks\":{\"o\":{\"k\":0},\"r\":{\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":0,\"s\":[-129.6],\"e\":[-130.533]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":1,\"s\":[-130.533],\"e\":[-133.367]},{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":2,\"s\":[-133.367],\"e\":[-137.2]},{\"i\":{\"x\":[0.649],\"y\":[0.642]},\"o\":{\"x\":[0.302],\"y\":[0]},\"n\":[\"0p649_0p642_0p302_0\"],\"t\":3,\"s\":[-137.2],\"e\":[-142.503]},{\"i\":{\"x\":[0.688],\"y\":[0.683]},\"o\":{\"x\":[0.342],\"y\":[0.309]},\"n\":[\"0p688_0p683_0p342_0p309\"],\"t\":4,\"s\":[-142.503],\"e\":[-148.487]},{\"i\":{\"x\":[0.797],\"y\":[0.804]},\"o\":{\"x\":[0.431],\"y\":[0.442]},\"n\":[\"0p797_0p804_0p431_0p442\"],\"t\":5,\"s\":[-148.487],\"e\":[-154.4]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":6,\"s\":[-154.4],\"e\":[3]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p667_1_0p167_0p167\"],\"t\":18,\"s\":[3],\"e\":[-1]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0]},\"n\":[\"0p667_1_0p167_0\"],\"t\":23,\"s\":[-1],\"e\":[0]},{\"t\":25}]},\"p\":{\"k\":[249.875,281.469,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"ip\":0,\"op\":37,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":17,\"ty\":1,\"nm\":\"ResizerTemp\",\"parent\":18,\"ks\":{\"o\":{\"k\":0},\"r\":{\"k\":0},\"p\":{\"k\":[26.6,35.7,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[10.5,10.5,100]}},\"ao\":0,\"sw\":500,\"sh\":600,\"sc\":\"#ffffff\",\"ip\":0,\"op\":37,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":18,\"ty\":1,\"nm\":\"White Solid 49\",\"ks\":{\"o\":{\"k\":0},\"r\":{\"k\":0},\"p\":{\"k\":[40,50,0]},\"a\":{\"k\":[28,35,0]},\"s\":{\"k\":[142.857,142.857,100]}},\"ao\":0,\"sw\":56,\"sh\":70,\"sc\":\"#ffffff\",\"ip\":0,\"op\":37,\"st\":0,\"bm\":0,\"sr\":1}],\"v\":\"4.4.26\",\"ddd\":0,\"ip\":0,\"op\":37,\"fr\":25,\"w\":80,\"h\":100}"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/src/main/assets/T.json",
    "content": "{\"assets\":[],\"layers\":[{\"ddd\":0,\"ind\":0,\"ty\":3,\"nm\":\"Null 3\",\"parent\":22,\"ks\":{\"o\":{\"k\":0},\"r\":{\"k\":0},\"p\":{\"k\":[250,400,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":2,\"s\":[77.8,77.8,100],\"e\":[110.9,110.9,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":3,\"s\":[110.9,110.9,100],\"e\":[100,100,100]},{\"t\":5}]}},\"ao\":0,\"ip\":0,\"op\":25,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":1,\"ty\":1,\"nm\":\"Turquoise Solid 1\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[54,-55,0]},\"a\":{\"k\":[304,358,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":10,\"s\":[100,100,100],\"e\":[110.9,110.9,100]},{\"t\":15}]}},\"ao\":0,\"hasMask\":true,\"masksProperties\":[{\"inv\":false,\"mode\":\"f\",\"pt\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[0,0],[0.83,8.468],[-0.188,-1.923],[-1.225,-8.691],[0.267,1.891]],\"o\":[[-1.188,-8.425],[-0.187,-1.904],[0.856,8.735],[0.268,1.904],[0,0]],\"v\":[[301.063,338.408],[298.043,313.068],[295.043,313.068],[298.17,339.205],[301.063,338.408]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0.83,8.468],[-0.188,-1.923],[-1.225,-8.691],[0.267,1.891]],\"o\":[[-1.188,-8.425],[-0.187,-1.904],[0.856,8.735],[0.268,1.904],[0,0]],\"v\":[[301.063,338.408],[296.043,299.568],[293.043,299.568],[298.17,339.205],[301.063,338.408]],\"c\":true}]},{\"t\":14}]},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 1\"}],\"sw\":500,\"sh\":600,\"sc\":\"#25cc8c\",\"ip\":10,\"op\":15,\"st\":-2,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":2,\"ty\":1,\"nm\":\"Turquoise Solid 1\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[54,-55,0]},\"a\":{\"k\":[304,358,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":10,\"s\":[100,100,100],\"e\":[110.9,110.9,100]},{\"t\":15}]}},\"ao\":0,\"hasMask\":true,\"masksProperties\":[{\"inv\":false,\"mode\":\"f\",\"pt\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[0,0],[-1.729,4.057],[0.755,-1.772],[1.413,-4.454],[-0.583,1.837]],\"o\":[[1.333,-4.204],[0.749,-1.756],[-1.832,4.298],[-0.585,1.845],[0,0]],\"v\":[[314.996,338.834],[319.574,326.437],[316.983,324.923],[312.103,338.037],[314.996,338.834]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-1.729,4.057],[0.755,-1.772],[1.413,-4.454],[-0.583,1.837]],\"o\":[[1.333,-4.204],[0.749,-1.756],[-1.832,4.298],[-0.585,1.845],[0,0]],\"v\":[[314.996,338.834],[323.574,313.437],[320.983,311.923],[312.103,338.037],[314.996,338.834]],\"c\":true}]},{\"t\":14}]},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 2\"}],\"sw\":500,\"sh\":600,\"sc\":\"#25cc8c\",\"ip\":10,\"op\":15,\"st\":-2,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":3,\"ty\":1,\"nm\":\"Turquoise Solid 1\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[54,-55,0]},\"a\":{\"k\":[304,358,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":10,\"s\":[100,100,100],\"e\":[110.9,110.9,100]},{\"t\":15}]}},\"ao\":0,\"hasMask\":true,\"masksProperties\":[{\"inv\":false,\"mode\":\"f\",\"pt\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[0,0],[-1.128,0.866],[0.445,0.762],[0.647,-0.496],[1.054,-1.66],[-1.033,1.627]],\"o\":[[0.76,-1.196],[0.642,-0.492],[-0.369,-0.632],[-1.556,1.194],[-1.038,1.635],[0,0]],\"v\":[[324.322,343.228],[327.162,340.073],[327.7,338.021],[325.648,337.483],[321.731,341.714],[324.322,343.228]],\"c\":true}],\"e\":[{\"i\":[[0,0],[-1.128,0.866],[0.445,0.762],[0.647,-0.496],[1.054,-1.66],[-1.033,1.627]],\"o\":[[0.76,-1.196],[0.642,-0.492],[-0.369,-0.632],[-1.556,1.194],[-1.038,1.635],[0,0]],\"v\":[[324.322,343.228],[331.662,333.073],[331.2,330.021],[329.148,330.983],[321.731,341.714],[324.322,343.228]],\"c\":true}]},{\"t\":14}]},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 3\"}],\"sw\":500,\"sh\":600,\"sc\":\"#25cc8c\",\"ip\":10,\"op\":15,\"st\":-2,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":4,\"ty\":1,\"nm\":\"White Solid 6\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-113,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"hasMask\":true,\"masksProperties\":[{\"inv\":false,\"mode\":\"f\",\"pt\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[{\"i\":[[-1.454,-2.729],[-3.886,1.591],[-0.431,1.503],[0.871,1.309],[3.206,-0.946]],\"o\":[[1.643,3.082],[1.447,-0.593],[0.433,-1.511],[-1.851,-2.783],[-4.121,1.216]],\"v\":[[179.637,302.159],[189.222,306.147],[192.415,302.929],[191.455,298.462],[182.741,295.027]],\"c\":true}],\"e\":[{\"i\":[[-0.697,-1.308],[-1.863,0.763],[-0.207,0.721],[0.417,0.628],[1.537,-0.453]],\"o\":[[0.788,1.478],[0.694,-0.284],[0.208,-0.724],[-0.887,-1.334],[-1.976,0.583]],\"v\":[[197.197,310.508],[201.792,312.42],[203.323,310.878],[202.862,308.736],[198.685,307.09]],\"c\":true}]},{\"t\":10}]},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 1\"}],\"sw\":500,\"sh\":600,\"sc\":\"#ffffff\",\"ip\":8,\"op\":10,\"st\":-1,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":5,\"ty\":1,\"nm\":\"White Solid 6\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-113,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"hasMask\":true,\"masksProperties\":[{\"inv\":false,\"mode\":\"f\",\"pt\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[{\"i\":[[-4.593,-1.022],[-1.755,1.806],[2.618,2.423],[6.077,0.799],[2.363,-0.842]],\"o\":[[2.459,0.547],[2.486,-2.558],[-4.499,-4.163],[-2.487,-0.327],[-15.378,5.479]],\"v\":[[227.404,298.046],[234.553,297.05],[232.453,287.711],[215.815,280.598],[208.373,281.005]],\"c\":true}],\"e\":[{\"i\":[[-4.593,-1.022],[-1.755,1.806],[2.618,2.423],[6.077,0.799],[2.363,-0.842]],\"o\":[[2.459,0.547],[2.486,-2.558],[-4.499,-4.163],[-2.487,-0.327],[-15.378,5.479]],\"v\":[[240.404,302.046],[247.553,301.05],[245.453,291.711],[223.315,283.098],[215.873,283.505]],\"c\":true}]},{\"t\":10}]},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 2\"}],\"sw\":500,\"sh\":600,\"sc\":\"#ffffff\",\"ip\":8,\"op\":10,\"st\":-1,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":6,\"ty\":1,\"nm\":\"White Solid 6\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-113,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"hasMask\":true,\"masksProperties\":[{\"inv\":false,\"mode\":\"f\",\"pt\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[{\"i\":[[2.396,-2.493],[0.271,-0.73],[-1.888,3.144],[0.644,1.124]],\"o\":[[-0.465,0.484],[-2.099,5.658],[0.667,-1.11],[-1.845,-3.221]],\"v\":[[181.182,256.932],[180.061,258.751],[190.18,262.069],[189.932,258.373]],\"c\":true}],\"e\":[{\"i\":[[0.812,-0.845],[0.092,-0.248],[-0.64,1.066],[0.218,0.381]],\"o\":[[-0.158,0.164],[-0.712,1.918],[0.226,-0.376],[-0.625,-1.092]],\"v\":[[195.812,265.345],[195.432,265.961],[198.862,267.086],[198.778,265.834]],\"c\":true}]},{\"t\":10}]},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 3\"}],\"sw\":500,\"sh\":600,\"sc\":\"#ffffff\",\"ip\":8,\"op\":10,\"st\":-1,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":7,\"ty\":1,\"nm\":\"White Solid 6\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-113,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"hasMask\":true,\"masksProperties\":[{\"inv\":false,\"mode\":\"f\",\"pt\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":8,\"s\":[{\"i\":[[-1.667,0.479],[-1.159,-0.275],[-4.38,-1.746],[-0.176,-3.375],[2.036,1.97]],\"o\":[[1.806,-0.519],[4.548,1.081],[3.139,1.251],[-0.039,0.423],[-2.156,-2.087]],\"v\":[[210.764,231.781],[216.548,231.7],[230.24,235.248],[236.887,242.147],[210.449,235.406]],\"c\":true}],\"e\":[{\"i\":[[-1.097,0.315],[-0.763,-0.181],[-2.883,-1.149],[-0.116,-2.221],[1.34,1.297]],\"o\":[[1.189,-0.342],[2.993,0.711],[2.066,0.824],[-0.026,0.278],[-1.419,-1.374]],\"v\":[[220.306,237.036],[224.113,236.983],[239.625,242.818],[244,247.359],[220.099,239.422]],\"c\":true}]},{\"t\":10}]},\"o\":{\"k\":100},\"x\":{\"k\":0},\"nm\":\"Mask 4\"}],\"sw\":500,\"sh\":600,\"sc\":\"#ffffff\",\"ip\":8,\"op\":10,\"st\":-1,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":8,\"ty\":4,\"nm\":\"Shape Layer 4\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":4,\"s\":[-90.5,-136.662,0],\"e\":[-90.5,-141.662,0],\"to\":[0,-0.83333331346512,0],\"ti\":[0,0.83333331346512,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":9,\"s\":[-90.5,-141.662,0],\"e\":[-90.5,-141.662,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"t\":40}]},\"a\":{\"k\":[-78.5,-9.5,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":4,\"s\":[{\"i\":[[-3.314,0],[-1.75,-3.838],[3.314,0],[1.655,2.871]],\"o\":[[3.314,0],[1.375,3.015],[-3.314,0],[-2.5,-4.338]],\"v\":[[1.5,-1.5],[9,6.25],[8,19.5],[-0.5,10]],\"c\":true}],\"e\":[{\"i\":[[-4.28,0],[0,-4.28],[4.28,0],[0,4.28]],\"o\":[[4.28,0],[0,4.28],[-4.28,0],[0,-4.28]],\"v\":[[0,-7.75],[7.75,0],[0,7.75],[-7.75,0]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":6,\"s\":[{\"i\":[[-4.28,0],[0,-4.28],[4.28,0],[0,4.28]],\"o\":[[4.28,0],[0,4.28],[-4.28,0],[0,-4.28]],\"v\":[[0,-7.75],[7.75,0],[0,7.75],[-7.75,0]],\"c\":true}],\"e\":[{\"i\":[[-3.314,0],[0,-3.314],[3.314,0],[0,3.314]],\"o\":[[3.314,0],[0,3.314],[-3.314,0],[0,-3.314]],\"v\":[[-0.188,-6],[5.812,0],[-0.188,6],[-6.188,0]],\"c\":true}]},{\"t\":8}]},\"nm\":\"Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[-77,8],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":4,\"s\":[{\"i\":[[0,9.5],[0,-14],[0,0],[-1.5,4]],\"o\":[[0,-9.5],[0,14],[0,0],[1.5,-4]],\"v\":[[-83,-26.5],[-84.75,-10.25],[-80,4],[-75,0.5]],\"c\":true}],\"e\":[{\"i\":[[0,9.5],[0,-14],[0,0],[-1.5,4]],\"o\":[[0,-9.5],[0,14],[0,0],[1.5,-4]],\"v\":[[-74.5,-51.5],[-90.75,-48],[-81.5,-1.5],[-75,-5.75]],\"c\":true}]},{\"t\":6}]},\"nm\":\"Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":4,\"op\":8,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":9,\"ty\":4,\"nm\":\"Shape Layer 3\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-113,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"t\":9,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[59.847,88.792],[60.347,81.667]],\"c\":false}],\"h\":1},{\"t\":13,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[64.875,82.625],[65.375,75.5]],\"c\":false}],\"h\":1},{\"t\":15,\"s\":[{\"i\":[[1.265,3.857],[0,0]],\"o\":[[-1.708,-5.208],[0,0]],\"v\":[[43.708,83.208],[44.208,73.583]],\"c\":false}],\"h\":1},{\"t\":17,\"s\":[{\"i\":[[5.042,0.292],[0,0]],\"o\":[[-5.042,-0.292],[0,0]],\"v\":[[56.708,80.625],[49.042,78.5]],\"c\":false}],\"h\":1},{\"t\":18,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[52.031,79.508],[52.91,64.971]],\"c\":false}],\"h\":1},{\"t\":19,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[51.865,53.008],[52.743,44.471]],\"c\":false}],\"h\":1},{\"t\":21,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[52.24,56.095],[53.118,49.924]],\"c\":false}],\"h\":1},{\"t\":22,\"s\":[{\"i\":[[0,0],[0,0]],\"o\":[[0,0],[0,0]],\"v\":[[51.668,-27.742],[52.716,-61.529]],\"c\":false}],\"h\":1}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.32,0.5,1]},\"o\":{\"k\":100},\"w\":{\"k\":2},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 3\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"t\":9,\"s\":[{\"i\":[[0,0],[-0.625,2.875]],\"o\":[[0,0],[0.625,-2.875]],\"v\":[[60.75,85.75],[62.25,74.75]],\"c\":false}],\"h\":1},{\"t\":11,\"s\":[{\"i\":[[0,0],[-0.625,2.875]],\"o\":[[0,0],[0.625,-2.875]],\"v\":[[61.5,83.75],[62.25,76.125]],\"c\":false}],\"h\":1},{\"t\":13,\"s\":[{\"i\":[[0,0],[-0.625,2.875]],\"o\":[[0,0],[0.625,-2.875]],\"v\":[[58.625,83.75],[59.375,76.125]],\"c\":false}],\"h\":1},{\"t\":15,\"s\":[{\"i\":[[0.458,5.5],[-1.708,3.042]],\"o\":[[-0.458,-5.5],[1.441,-2.565]],\"v\":[[37.292,82.833],[38.708,70.125]],\"c\":false}],\"h\":1},{\"t\":17,\"s\":[{\"i\":[[0,0],[0.458,3.042]],\"o\":[[0,0],[-0.438,-2.909]],\"v\":[[44.292,77.75],[39.542,76.125]],\"c\":false}],\"h\":1},{\"t\":18,\"s\":[{\"i\":[[0,0],[-1.56,2.495]],\"o\":[[0,0],[1.56,-2.495]],\"v\":[[44.936,77.788],[46.287,64.515]],\"c\":false}],\"h\":1},{\"t\":19,\"s\":[{\"i\":[[0,0],[-1.56,2.495]],\"o\":[[0,0],[1.56,-2.495]],\"v\":[[44.769,51.288],[45.953,45.515]],\"c\":false}],\"h\":1},{\"t\":21,\"s\":[{\"i\":[[0,0],[-1.56,1.803]],\"o\":[[0,0],[1.56,-1.803]],\"v\":[[45.144,54.851],[46.328,50.678]],\"c\":false}],\"h\":1},{\"t\":22,\"s\":[{\"i\":[[0,0],[-1.56,2.495]],\"o\":[[0,0],[1.56,-2.495]],\"v\":[[44.534,-10.962],[45.318,-65.485]],\"c\":false}],\"h\":1}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.32,0.5,1]},\"o\":{\"k\":100},\"w\":{\"k\":2},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 2\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"t\":9,\"s\":[{\"i\":[[0.585,-0.026],[-0.212,-0.539],[-0.764,0.155],[0,0]],\"o\":[[-0.585,0.026],[0.212,0.539],[0.764,-0.155],[0,0]],\"v\":[[64.182,91.25],[63.321,93.51],[64.443,95.406],[64.993,92.783]],\"c\":true}],\"h\":1},{\"t\":13,\"s\":[{\"i\":[[0.585,-0.026],[-0.212,-0.539],[-0.764,0.155],[0,0]],\"o\":[[-0.585,0.026],[0.212,0.539],[0.764,-0.155],[0,0]],\"v\":[[61.932,88],[61.071,90.26],[63.068,91.906],[62.743,89.533]],\"c\":true}],\"h\":1},{\"t\":15,\"s\":[{\"i\":[[0.585,-0.026],[-0.212,-0.539],[-0.764,0.155],[0,0]],\"o\":[[-0.585,0.026],[0.212,0.539],[0.764,-0.155],[0,0]],\"v\":[[44.076,89.164],[42.188,91.092],[49.664,90.243],[46.428,89.367]],\"c\":true}],\"h\":1},{\"t\":17,\"s\":[{\"i\":[[0.26,-0.012],[-0.094,-0.24],[-0.34,0.069],[0,0]],\"o\":[[-0.26,0.012],[0.094,0.24],[0.34,-0.069],[0,0]],\"v\":[[48.167,83.52],[47.326,84.378],[50.653,84],[49.213,83.61]],\"c\":true}],\"h\":1},{\"t\":19,\"s\":[{\"i\":[[0.26,-0.012],[-0.094,-0.24],[-0.34,0.069],[0,0]],\"o\":[[-0.26,0.012],[0.094,0.24],[0.34,-0.069],[0,0]],\"v\":[[47.995,57.07],[48.525,58.76],[50.482,57.55],[49.042,57.16]],\"c\":true}],\"h\":1},{\"t\":21,\"s\":[{\"i\":[[0.26,-0.008],[-0.094,-0.173],[-0.34,0.05],[0,0]],\"o\":[[-0.26,0.008],[0.094,0.173],[0.34,-0.05],[0,0]],\"v\":[[48.381,58.997],[48.91,60.219],[50.867,59.344],[49.427,59.063]],\"c\":true}],\"h\":1},{\"t\":22,\"s\":[{\"i\":[[0.26,-0.012],[-0.094,-0.24],[-0.34,0.069],[0,0]],\"o\":[[-0.26,0.012],[0.094,0.24],[0.34,-0.069],[0,0]],\"v\":[[51.309,-12.52],[51.839,-10.831],[53.795,-12.04],[52.356,-12.43]],\"c\":true}],\"h\":1}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.32,0.5,1]},\"o\":{\"k\":100},\"w\":{\"k\":2},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[97.348,100.189],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":9,\"op\":23,\"st\":7,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":10,\"ty\":4,\"nm\":\"Shape Layer 2\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-113,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0,0],[-2.547,-0.106],[0,0]],\"o\":[[0,0],[2.547,0.106],[0,0]],\"v\":[[59.375,80.5],[61.453,87.394],[65.125,80.125]],\"c\":false}},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.32,0.5,1]},\"o\":{\"k\":100},\"w\":{\"k\":2},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":2,\"op\":9,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":11,\"ty\":4,\"nm\":\"CHAR Body LEFT 2\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-113,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"t\":2,\"s\":[{\"i\":[[0,0],[0,0],[-0.422,10.398],[0,0],[7.926,2.015],[0,0],[0.922,-11.031]],\"o\":[[0,0],[0,0],[0.422,-10.398],[0,0],[-7.267,-1.847],[0,0],[-0.922,11.031]],\"v\":[[23.085,112.267],[67.741,112.216],[66.745,93.463],[70.839,74.075],[53.407,67.985],[28.502,65.05],[24.089,88.636]],\"c\":true}],\"h\":1},{\"t\":9,\"s\":[{\"i\":[[0,0],[0,0],[-0.422,10.398],[0,0],[8.093,-1.485],[0,0],[3.078,-13.636]],\"o\":[[0,0],[0,0],[0.422,-10.398],[0,0],[-7.375,1.353],[0,0],[-2.437,10.798]],\"v\":[[23.085,112.267],[67.741,112.216],[64.411,85.963],[73.339,51.908],[55.741,53.152],[35.835,58.883],[30.422,83.803]],\"c\":true}],\"h\":1},{\"t\":11,\"s\":[{\"i\":[[0,0],[0,0],[-0.422,10.398],[0,0],[7.759,-2.485],[0,0],[3.078,-13.636]],\"o\":[[0,0],[0,0],[0.422,-10.398],[0,0],[-7.141,2.287],[0,0],[-2.437,10.798]],\"v\":[[23.085,112.267],[67.741,112.216],[66.078,84.963],[70.839,56.575],[56.407,57.485],[35.335,62.217],[28.089,84.303]],\"c\":true}],\"h\":1},{\"t\":14,\"s\":[{\"i\":[[0,0],[0,0],[-0.422,10.398],[0,0],[8.593,-0.319],[0,0],[0.922,-11.031]],\"o\":[[0,0],[0,0],[0.422,-10.398],[0,0],[-7.493,0.278],[0,0],[-0.922,11.031]],\"v\":[[23.085,112.267],[67.741,112.216],[66.745,93.463],[71.672,65.075],[53.074,62.985],[28.502,65.05],[24.089,88.636]],\"c\":true}],\"h\":1},{\"t\":15,\"s\":[{\"i\":[[0,0],[0,0],[-0.422,10.398],[0,0],[10.426,-0.652],[0,0],[0.922,-11.031]],\"o\":[[0,0],[0,0],[0.422,-10.398],[0,0],[-7.483,0.468],[0,0],[-0.922,11.031]],\"v\":[[23.085,112.267],[67.741,112.216],[57.245,90.629],[59.672,72.408],[43.407,64.652],[27.335,61.217],[23.089,83.969]],\"c\":true}],\"h\":1},{\"t\":16,\"s\":[{\"i\":[[0,0],[0,0],[-0.422,10.398],[0,0],[11.426,3.848],[0,0],[0.922,-11.031]],\"o\":[[0,0],[0,0],[0.422,-10.398],[0,0],[-7.106,-2.393],[0,0],[-0.922,11.031]],\"v\":[[23.085,112.267],[67.741,112.216],[57.245,90.629],[57.672,74.908],[42.407,65.902],[31.835,60.217],[25.589,82.469]],\"c\":true}],\"h\":1},{\"t\":18,\"s\":[{\"i\":[[0,0],[0,0],[-1.402,10.312],[0,0],[7.926,2.015],[0,0],[2.578,-12.136]],\"o\":[[0,0],[0,0],[1.422,-10.463],[0,0],[-7.267,-1.847],[0,0],[-2.242,10.556]],\"v\":[[22.585,92.267],[66.241,99.883],[68.245,80.463],[72.005,62.408],[54.907,56.152],[31.335,49.05],[26.256,72.136]],\"c\":true}],\"h\":1},{\"t\":19,\"s\":[{\"i\":[[0,0],[0,0],[-1.402,10.312],[0,0],[7.593,2.348],[0,0],[2.578,-12.136]],\"o\":[[0,0],[0,0],[1.422,-10.463],[0,0],[-7.163,-2.215],[0,0],[-2.242,10.556]],\"v\":[[25.418,79.434],[69.408,87.716],[71.078,70.463],[74.505,50.242],[56.574,43.985],[33.835,37.55],[30.422,53.969]],\"c\":true}],\"h\":1},{\"t\":21,\"s\":[{\"i\":[[0,0],[0,0],[-1.402,10.312],[0,0],[7.593,2.348],[0,0],[2.578,-12.136]],\"o\":[[0,0],[0,0],[1.422,-10.463],[0,0],[-7.163,-2.215],[0,0],[-2.242,10.556]],\"v\":[[25.326,82.684],[69.316,90.966],[73.361,72.838],[73.913,55.617],[55.982,49.36],[33.243,42.925],[28.205,59.094]],\"c\":true}],\"h\":1},{\"t\":22,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.957,30.608],[79.375,30.8],[79.541,-26.758],[79.345,-110.567],[51.519,-110.828],[22.972,-110.32],[22.941,14.075]],\"c\":true}],\"h\":1},{\"t\":23,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.957,30.608],[79.375,30.8],[79.541,-26.758],[79.293,-80.4],[51.503,-80.662],[22.955,-80.737],[22.941,14.075]],\"c\":true}],\"h\":1}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"w\":{\"k\":2},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0.667,-0.5],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\"}],\"ip\":2,\"op\":23,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":12,\"ty\":4,\"nm\":\"legs LEFT 2\",\"parent\":11,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,0,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"t\":2,\"s\":[{\"i\":[[0,0],[-7.474,0.247],[-0.933,0.35],[0,0]],\"o\":[[0,0],[6.535,-0.216],[2,-0.75],[0,0]],\"v\":[[69.208,110.875],[84.368,110.486],[136.875,109.583],[139.125,106.583]],\"c\":false}],\"h\":1},{\"t\":9,\"s\":[{\"i\":[[0,0],[-7.467,0.397],[-0.926,0.369],[0,0]],\"o\":[[0,0],[6.529,-0.347],[1.984,-0.79],[0,0]],\"v\":[[69.208,110.875],[92.912,110.102],[133.557,108.14],[134.246,101.096]],\"c\":false}],\"h\":1},{\"t\":13,\"s\":[{\"i\":[[0,0],[-7.474,0.247],[-0.933,0.35],[0,0]],\"o\":[[0,0],[6.535,-0.216],[2,-0.75],[0,0]],\"v\":[[69.208,110.875],[104.534,98.486],[129.875,109.667],[132.125,106.667]],\"c\":false}],\"h\":1},{\"t\":15,\"s\":[{\"i\":[[0,0],[-1.966,0.153],[-0.933,0.35],[0,0]],\"o\":[[0,0],[8.632,5.014],[2,-0.75],[0,0]],\"v\":[[55.042,110.833],[87.201,100.986],[112.042,113.5],[114.292,110.5]],\"c\":false}],\"h\":1},{\"t\":18,\"s\":[{\"i\":[[0,0],[-1.132,-1.347],[-0.933,0.35],[0,0]],\"o\":[[0,0],[1.132,1.347],[2,-0.75],[0,0]],\"v\":[[50.708,96.167],[57.201,110.486],[76.875,111.167],[81.292,113.5]],\"c\":false}],\"h\":1},{\"t\":19,\"s\":[{\"i\":[[0,0],[-1.132,-1.347],[-0.986,-0.146],[0,0]],\"o\":[[0,0],[1.132,1.347],[0.292,0.667],[0,0]],\"v\":[[51.542,85.167],[66.368,98.819],[83.042,114.833],[83.458,117.167]],\"c\":false}],\"h\":1},{\"t\":21,\"s\":[{\"i\":[[0,0],[-1.132,-1.347],[-0.986,-0.146],[0,0]],\"o\":[[0,0],[1.132,1.347],[0.292,0.667],[0,0]],\"v\":[[52.792,88.917],[64.118,101.319],[83.042,114.833],[83.458,117.167]],\"c\":false}],\"h\":1},{\"t\":22,\"s\":[{\"i\":[[0,0],[0.034,-10.847],[-0.958,-4.5],[0,0]],\"o\":[[0,0],[-0.034,10.847],[0.958,4.5],[0,0]],\"v\":[[59.708,-39],[59.868,-7.347],[62.042,47.5],[65.292,62.5]],\"c\":false}],\"h\":1},{\"t\":23,\"s\":[{\"i\":[[0,0],[0.034,-10.847],[-0.958,-4.5],[0,0]],\"o\":[[0,0],[-0.034,10.847],[0.958,4.5],[0,0]],\"v\":[[51.667,-114.583],[58.652,-135.681],[62.167,-96.333],[60,-89]],\"c\":false}],\"h\":1},{\"t\":24,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[56.667,-109.333],[59.235,-114.597],[60.667,-118],[59.167,-121]],\"c\":false}],\"h\":1}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"w\":{\"k\":4},\"lc\":2,\"lj\":2,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 2\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"t\":2,\"s\":[{\"i\":[[-1.767,0],[-4.219,4.167],[-0.356,0],[0,0]],\"o\":[[0.937,0],[4.614,13.333],[0.757,0],[0,0]],\"v\":[[66.934,110.833],[84.219,90.5],[110.571,108.333],[114.333,109.667]],\"c\":false}],\"h\":1},{\"t\":9,\"s\":[{\"i\":[[-1.767,0],[-4.219,4.167],[-0.356,0],[0,0]],\"o\":[[0.937,0],[4.614,13.333],[0.757,0],[0,0]],\"v\":[[66.934,110.833],[95.053,86.333],[111.904,109.667],[116.167,99.833]],\"c\":false}],\"h\":1},{\"t\":13,\"s\":[{\"i\":[[-1.767,0],[-4.219,4.167],[-0.356,0],[0,0]],\"o\":[[0.937,0],[4.614,13.333],[0.757,0],[0,0]],\"v\":[[66.934,110.833],[84.219,90.5],[110.238,110.333],[115.333,110.167]],\"c\":false}],\"h\":1},{\"t\":15,\"s\":[{\"i\":[[-1.767,0],[-4.219,4.167],[-0.356,0],[0,0]],\"o\":[[0.937,0],[4.614,13.333],[0.757,0],[0,0]],\"v\":[[39.601,111],[66.219,89.667],[76.071,110.667],[80.667,110.167]],\"c\":false}],\"h\":1},{\"t\":17,\"s\":[{\"i\":[[-1.767,0],[1.614,-0.833],[-0.356,0],[0,0]],\"o\":[[0.937,0],[-2.494,1.288],[0.757,0],[0,0]],\"v\":[[43.101,93.833],[36.386,85.167],[37.571,111],[31.833,113.667]],\"c\":false}],\"h\":1},{\"t\":19,\"s\":[{\"i\":[[-1.767,0],[1.447,-4.5],[-0.356,0],[0,0]],\"o\":[[0.937,0],[-0.859,2.672],[0.757,0],[0,0]],\"v\":[[40.101,84.5],[36.553,96],[34.571,111.333],[30.833,113.667]],\"c\":false}],\"h\":1},{\"t\":21,\"s\":[{\"i\":[[-1.767,0],[1.447,-4.5],[-0.356,0],[0,0]],\"o\":[[0.937,0],[-0.859,2.672],[0.757,0],[0,0]],\"v\":[[39.601,87.25],[32.553,97],[34.571,111.333],[30.833,113.667]],\"c\":false}],\"h\":1},{\"t\":22,\"s\":[{\"i\":[[-1.767,0],[0.281,-13.333],[-0.262,-6.5],[0,0]],\"o\":[[0.937,0],[-0.059,2.806],[0.262,6.5],[0,0]],\"v\":[[43.434,-37.167],[44.719,2.667],[43.238,64.333],[47,84.5]],\"c\":false}],\"h\":1},{\"t\":23,\"s\":[{\"i\":[[0,0],[-3.208,-12.945],[-0.262,-6.5],[0,0]],\"o\":[[0,0],[1.239,5],[0.262,6.5],[0,0]],\"v\":[[38.642,-114.333],[43.928,-128.333],[46.529,-94.75],[49.292,-88.167]],\"c\":false}],\"h\":1},{\"t\":24,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[43.642,-109.083],[45.261,-114.083],[49.696,-123.083],[47.792,-128.833]],\"c\":false}],\"h\":1}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"w\":{\"k\":4},\"lc\":2,\"lj\":2,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":2,\"op\":25,\"st\":2,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":13,\"ty\":4,\"nm\":\"DEPTH R\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-13,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"t\":18,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.226,-8.271],[27.832,-1.557],[33.439,5.158],[73.024,11.271],[80.709,-23.409],[79.06,-26.812],[73.561,-38.158],[43.368,-37.446]],\"c\":true}],\"h\":1},{\"t\":19,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[24.476,-20.771],[27.082,-17.682],[29.689,-14.592],[73.274,-7.479],[78.959,-43.159],[78.232,-44.889],[75.811,-50.658],[69.118,-14.113]],\"c\":true}],\"h\":1},{\"t\":20,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[24.476,-20.771],[27.707,-16.057],[30.939,-11.342],[74.524,-4.229],[80.459,-38.909],[79.386,-41.62],[75.811,-50.658],[69.118,-14.113]],\"c\":true}],\"h\":1},{\"t\":21,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[25.226,-17.021],[28.207,-13.619],[31.189,-10.217],[74.524,-3.354],[80.084,-34.034],[79.011,-36.745],[75.436,-45.783],[69.118,-14.113]],\"c\":true}],\"h\":1},{\"t\":22,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[23.225,-59],[52.091,-59],[80.963,-59],[81.176,-89.123],[64.901,-89.123],[55.334,-89.123],[23.438,-89.123],[23.438,-82.347]],\"c\":true}],\"h\":1},{\"t\":23,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.05,-171.255],[51.665,-171.316],[81.287,-171.377],[81.494,-213.419],[65.219,-213.419],[55.306,-213.391],[22.256,-213.297],[22.256,-197.354]],\"c\":true}],\"h\":1},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.5,\"y\":0},\"n\":\"0p833_0p833_0p5_0\",\"t\":24,\"s\":[{\"i\":[[0,0],[-10.834,0.351],[0,0],[0,0],[0,0],[11.333,-0.215],[0,0],[0,0]],\"o\":[[0,0],[10.834,-0.351],[0,0],[0,0],[0,0],[-11.333,0.215],[0,0],[0,0]],\"v\":[[22.05,-166.255],[51.333,-164.649],[81.287,-166.377],[81.494,-208.419],[65.219,-208.419],[51.5,-207.715],[22.256,-208.297],[22.256,-192.354]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.05,-171.255],[51.665,-171.316],[81.287,-171.377],[81.494,-213.419],[65.219,-213.419],[55.306,-213.391],[22.256,-213.297],[22.256,-197.354]],\"c\":true}]},{\"t\":25}]},\"nm\":\"T\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"T\"}],\"ip\":18,\"op\":25,\"st\":-1,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":14,\"ty\":4,\"nm\":\"face left\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-113,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"t\":2,\"s\":[{\"i\":[[2.625,0.361],[-0.154,-1.119],[-1.25,-0.174],[-0.154,1.599]],\"o\":[[-1.939,-0.267],[0.154,1.119],[1.601,0.222],[0.146,-1.517]],\"v\":[[-72.75,59.665],[-74.596,59.869],[-73.375,61.694],[-70.337,60.569]],\"c\":true}],\"h\":1},{\"t\":4,\"s\":[{\"i\":[[2.625,0.695],[-0.154,-2.154],[-1.25,-0.334],[-0.154,3.077]],\"o\":[[-1.939,-0.513],[0.154,2.154],[1.601,0.428],[0.146,-2.919]],\"v\":[[-72.75,58.93],[-74.596,59.325],[-73.375,62.834],[-70.337,60.671]],\"c\":true}],\"h\":1},{\"t\":6,\"s\":[{\"i\":[[2.625,0.695],[-0.154,-2.154],[-1.25,-0.334],[-0.154,3.077]],\"o\":[[-1.939,-0.513],[0.154,2.154],[1.601,0.428],[0.146,-2.919]],\"v\":[[-71.75,48.93],[-73.596,49.325],[-72.375,52.834],[-69.337,50.671]],\"c\":true}],\"h\":1},{\"t\":7,\"s\":[{\"i\":[[2,-0.154],[-0.154,-2.154],[-1.818,0.727],[-0.154,3.077]],\"o\":[[-2,0.154],[0.154,2.154],[1.538,-0.615],[0.146,-2.919]],\"v\":[[-70.75,47.305],[-72.596,50.075],[-71,54.959],[-69.212,49.921]],\"c\":true}],\"h\":1},{\"t\":8,\"s\":[{\"i\":[[2,-0.154],[-0.154,-2.154],[-1.818,0.727],[-0.154,3.077]],\"o\":[[-2,0.154],[0.154,2.154],[1.538,-0.615],[0.146,-2.919]],\"v\":[[-71,47.055],[-72.846,49.825],[-71.5,58.959],[-69.462,49.671]],\"c\":true}],\"h\":1},{\"t\":9,\"s\":[{\"i\":[[0.162,-0.729],[-1.984,-0.839],[0.388,0.905],[2.778,1.323]],\"o\":[[-0.162,0.729],[1.984,0.839],[-0.328,-0.766],[-2.636,-1.256]],\"v\":[[-27.574,57.624],[-25.331,59.383],[-21.97,60.169],[-25.433,58.33]],\"c\":true}],\"h\":1},{\"t\":10,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[-15.125,72.055],[-39.221,59.45],[-13.875,73.334],[-18.962,69.171]],\"c\":true}],\"h\":1},{\"t\":11,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[-14.933,71.386],[-16.038,71.429],[-15.3,72.637],[-14.034,71.585]],\"c\":true}],\"h\":1},{\"t\":13,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[-14.933,71.386],[-16.038,71.429],[-16.3,78.887],[-14.034,71.585]],\"c\":true}],\"h\":1},{\"t\":14,\"s\":[{\"i\":[[0.138,0.734],[2.155,-0.008],[-0.712,-0.68],[-3.075,-0.125]],\"o\":[[-0.138,-0.734],[-2.155,0.008],[0.603,0.576],[2.918,0.118]],\"v\":[[-55.013,74.267],[-57.767,73.531],[-61.165,74.13],[-57.258,74.459]],\"c\":true}],\"h\":1},{\"t\":15,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[-59.25,62.18],[-59.846,62.7],[-59,63.834],[-57.837,62.671]],\"c\":true}],\"h\":1}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.32,0.5,1]},\"o\":{\"k\":100},\"w\":{\"k\":2},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 3\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"t\":2,\"s\":[{\"i\":[[0,0],[-1.182,5.194]],\"o\":[[0,0],[0.388,-1.706]],\"v\":[[-61.417,47.746],[-67.818,47.806]],\"c\":false}],\"h\":1},{\"t\":4,\"s\":[{\"i\":[[0,0],[-0.118,1.746]],\"o\":[[0,0],[0.118,-1.746]],\"v\":[[-68.292,55.121],[-65.068,40.806]],\"c\":false}],\"h\":1},{\"t\":6,\"s\":[{\"i\":[[0,0],[0,1.75]],\"o\":[[0,0],[0,-1.75]],\"v\":[[-67,42.25],[-64.75,27.75]],\"c\":false}],\"h\":1},{\"t\":7,\"s\":[{\"i\":[[0,0],[0,1.75]],\"o\":[[0,0],[0,-1.75]],\"v\":[[-67,42],[-64.75,27.5]],\"c\":false}],\"h\":1},{\"t\":8,\"s\":[{\"i\":[[0,0],[0.25,2.75]],\"o\":[[0,0],[-0.158,-1.743]],\"v\":[[-66.75,41.75],[-65,27.25]],\"c\":false}],\"h\":1},{\"t\":9,\"s\":[{\"i\":[[0,0],[0,1.75]],\"o\":[[0,0],[0,-1.75]],\"v\":[[-7.625,57.5],[-56.875,32.5]],\"c\":false}],\"h\":1},{\"t\":10,\"s\":[{\"i\":[[0,0],[0,1.75]],\"o\":[[0,0],[0,-1.75]],\"v\":[[-6.875,63.25],[-26.125,46.625]],\"c\":false}],\"h\":1},{\"t\":11,\"s\":[{\"i\":[[0,0],[-0.16,1.743]],\"o\":[[0,0],[0.16,-1.743]],\"v\":[[-10.667,65.949],[-7.001,56.119]],\"c\":false}],\"h\":1},{\"t\":14,\"s\":[{\"i\":[[0,0],[-0.688,-1.609]],\"o\":[[0,0],[0.688,1.609]],\"v\":[[-73.307,82.223],[-18.194,85.849]],\"c\":false}],\"h\":1},{\"t\":15,\"s\":[{\"i\":[[0,0],[0,1.75]],\"o\":[[0,0],[0,-1.75]],\"v\":[[-56.5,59],[-55.625,55.875]],\"c\":false}],\"h\":1}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.32,0.5,1]},\"o\":{\"k\":100},\"w\":{\"k\":2},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 2\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"t\":2,\"s\":[{\"i\":[[0,0],[-5.431,3.65]],\"o\":[[0,0],[-0.685,2.71]],\"v\":[[-79.961,46.718],[-72.319,48.1]],\"c\":false}],\"h\":1},{\"t\":4,\"s\":[{\"i\":[[0,0],[0.685,-2.71]],\"o\":[[0,0],[-0.685,2.71]],\"v\":[[-74.211,53.718],[-71.819,40.6]],\"c\":false}],\"h\":1},{\"t\":6,\"s\":[{\"i\":[[0,0],[0.5,-2.75]],\"o\":[[0,0],[-0.5,2.75]],\"v\":[[-73,41.25],[-71.5,28]],\"c\":false}],\"h\":1},{\"t\":7,\"s\":[{\"i\":[[0,0],[0.5,-2.75]],\"o\":[[0,0],[-0.5,2.75]],\"v\":[[-73,41],[-71.5,27.75]],\"c\":false}],\"h\":1},{\"t\":8,\"s\":[{\"i\":[[0.25,7],[-0.436,-2.761]],\"o\":[[-0.25,-7],[0.75,4.75]],\"v\":[[-73.25,40.75],[-71.75,27.5]],\"c\":false}],\"h\":1},{\"t\":9,\"s\":[{\"i\":[[0,0],[1.625,2.625]],\"o\":[[0,0],[-1.471,-2.377]],\"v\":[[-15.625,73.875],[-40.625,62.125]],\"c\":false}],\"h\":1},{\"t\":10,\"s\":[{\"i\":[[0,0],[0.5,-2.75]],\"o\":[[0,0],[-0.5,2.75]],\"v\":[[-16.375,63.375],[-36.25,45.75]],\"c\":false}],\"h\":1},{\"t\":11,\"s\":[{\"i\":[[0,0],[0.75,-2.693]],\"o\":[[0,0],[-0.75,2.693]],\"v\":[[-16.133,65.32],[-16.551,54.863]],\"c\":false}],\"h\":1},{\"t\":14,\"s\":[{\"i\":[[0,0],[-2.526,-1.775]],\"o\":[[0,0],[2.287,1.607]],\"v\":[[-72.388,64.022],[-44.782,64.998]],\"c\":false}],\"h\":1},{\"t\":15,\"s\":[{\"i\":[[0,0],[0.875,-0.375]],\"o\":[[0,0],[-2.122,1.819]],\"v\":[[-61.75,58.375],[-64.125,56]],\"c\":false}],\"h\":1}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.32,0.5,1]},\"o\":{\"k\":100},\"w\":{\"k\":2},\"lc\":1,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":2,\"op\":17,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":15,\"ty\":4,\"nm\":\"CHAR Body LEFT\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-113,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"t\":2,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-88.961,79.682],[-42.934,84.907],[-40.448,63.004],[-37.872,40.318],[-54.539,38.426],[-83.899,35.093],[-86.145,54.877]],\"c\":true}],\"h\":1},{\"t\":4,\"s\":[{\"i\":[[0,0],[0,0],[-2.704,10.299],[0,0],[0,0],[0,0],[7.058,-10.21]],\"o\":[[0,0],[0,0],[3.355,-12.777],[0,0],[0,0],[0,0],[-7.174,10.378]],\"v\":[[-87.461,78.432],[-44.184,85.407],[-48.771,63.027],[-44.122,35.568],[-57.349,32.137],[-80.649,26.093],[-84.993,48.372]],\"c\":true}],\"h\":1},{\"t\":6,\"s\":[{\"i\":[[0,0],[0,0],[-1.386,10.558],[0,0],[0,0],[0,0],[2.826,-13.622]],\"o\":[[0,0],[0,0],[2.105,-16.027],[0,0],[0,0],[0,0],[-2.563,12.353]],\"v\":[[-86.461,74.682],[-43.184,81.657],[-43.771,52.027],[-38.622,23.818],[-54.112,21.655],[-81.399,17.843],[-83.743,42.372]],\"c\":true}],\"h\":1},{\"t\":8,\"s\":[{\"i\":[[0,0],[0,0],[-1.386,10.558],[0,0],[0,0],[0,0],[2.826,-13.622]],\"o\":[[0,0],[0,0],[2.105,-16.027],[0,0],[0,0],[0,0],[-2.563,12.353]],\"v\":[[-86.461,74.682],[-43.184,81.657],[-40.771,52.527],[-40.622,27.068],[-54.862,23.405],[-82.899,21.843],[-87.993,42.372]],\"c\":true}],\"h\":1},{\"t\":9,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[14.344,6.557],[0,0],[2.911,-9.115]],\"o\":[[0,0],[0,0],[0,0],[0,0],[-14.344,-6.557],[0,0],[-2.911,9.115]],\"v\":[[-74.248,63.12],[-14.098,86.447],[-9.496,68.152],[-2.836,46.38],[-27.323,31.557],[-67.485,13.553],[-72.005,39.885]],\"c\":true}],\"h\":1},{\"t\":10,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-51.44,71.971],[-30.6025,80.659],[-9.765,89.347],[-3.591,71.183],[4.107,52.279],[-38.068,30.653],[-44.999,51.318]],\"c\":true}],\"h\":1},{\"t\":14,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[-0.934,7.736],[0,0],[0,0],[-0.823,-7.184]],\"o\":[[0,0],[0,0],[0,0],[0.934,-7.736],[0,0],[0,0],[0.823,7.184]],\"v\":[[-77.426,90.711],[-54.426,89.673],[-31.426,88.635],[-20.35,67.236],[-27.394,58.325],[-76.348,60.494],[-83.177,76.556]],\"c\":true}],\"h\":1},{\"t\":15,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[-0.934,7.736],[0,0],[0,0],[0.718,-7.195]],\"o\":[[0,0],[0,0],[0,0],[0.934,-7.736],[0,0],[0,0],[-0.718,7.195]],\"v\":[[-88.077,83.608],[-63.1265,87.1215],[-38.176,90.635],[-29.85,71.486],[-37.394,59.325],[-80.62,54.305],[-90.698,68.555]],\"c\":true}],\"h\":1},{\"t\":17,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-80.497,8.274],[-25.073,8.75],[-24.873,-21.158],[-24.667,-52.136],[-44.736,-52.309],[-80.091,-52.612],[-80.271,-25.597]],\"c\":true}],\"h\":1}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"w\":{\"k\":2},\"lc\":2,\"lj\":2,\"nm\":\"Stroke 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0.667,-0.5],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\"}],\"ip\":2,\"op\":19,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":16,\"ty\":4,\"nm\":\"legs LEFT\",\"parent\":15,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,0,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"t\":2,\"s\":[{\"i\":[[0,0],[-0.247,-7.474],[-0.35,-0.933],[0,0]],\"o\":[[0,0],[0.216,6.535],[0.75,2],[0,0]],\"v\":[[-59.625,82.125],[-59.236,97.284],[-58.375,111.125],[-55.375,113.375]],\"c\":false}],\"h\":1},{\"t\":4,\"s\":[{\"i\":[[0,0],[-0.253,-7.576],[0,0],[0,0]],\"o\":[[0,0],[0.215,6.418],[0,0],[0,0]],\"v\":[[-59.625,82.125],[-58.392,97.782],[-58.542,112.125],[-55.542,112.375]],\"c\":false}],\"h\":1},{\"t\":6,\"s\":[{\"i\":[[0,0],[-0.253,-7.576],[0,0],[0,0]],\"o\":[[0,0],[0.215,6.418],[0,0],[0,0]],\"v\":[[-59.458,76.958],[-59.225,96.282],[-58.542,112.125],[-55.542,112.375]],\"c\":false}],\"h\":1},{\"t\":9,\"s\":[{\"i\":[[0,0],[-0.775,-3.615],[0,0],[0,0]],\"o\":[[0,0],[0.215,6.418],[0,0],[0,0]],\"v\":[[-30.458,77.625],[-17.225,80.615],[-51.066,107.829],[-48.684,109.671]],\"c\":false}],\"h\":1},{\"t\":10,\"s\":[{\"i\":[[0,0],[-0.775,-3.615],[0,0],[0,0]],\"o\":[[0,0],[0.215,6.418],[0,0],[0,0]],\"v\":[[-22.125,83.625],[2.442,97.282],[-1.732,112.162],[0.649,114.004]],\"c\":false}],\"h\":1},{\"t\":14,\"s\":[{\"i\":[[0,0],[-12.775,-8.282],[0,0],[0,0]],\"o\":[[0,0],[9.225,9.051],[0,0],[0,0]],\"v\":[[-42.458,86.958],[-20.225,98.615],[0.268,109.162],[2.649,111.004]],\"c\":false}],\"h\":1},{\"t\":15,\"s\":[{\"i\":[[0,0],[-0.058,-0.885],[0,0],[0,0]],\"o\":[[0,0],[0.058,0.885],[0,0],[0,0]],\"v\":[[-57.958,89.458],[-45.392,102.115],[-55.208,112.167],[-52.208,112.417]],\"c\":false}],\"h\":1},{\"t\":17,\"s\":[{\"i\":[[0,0],[-0.058,-0.885],[0,0],[0,0]],\"o\":[[0,0],[0.058,0.885],[0,0],[0,0]],\"v\":[[-48.958,-9.875],[-48.392,27.449],[-49.208,45.167],[-47.542,50.083]],\"c\":false}],\"h\":1},{\"t\":19,\"s\":[{\"i\":[[0,0],[-3.6,-2.218],[0,0],[0,0]],\"o\":[[0,0],[3.6,2.218],[0,0],[0,0]],\"v\":[[-49.5,-114.708],[-44.6,-122.218],[-46.083,-99.833],[-45.083,-93.417]],\"c\":false}],\"h\":1},{\"t\":20,\"s\":[{\"i\":[[0,0],[-0.973,4.115],[0,0],[0,0]],\"o\":[[0,0],[0.933,-3.949],[0,0],[0,0]],\"v\":[[-48.5,-102.208],[-47.433,-104.885],[-46.417,-108.333],[-46.917,-112.083]],\"c\":false}],\"h\":1}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"w\":{\"k\":4},\"lc\":2,\"lj\":2,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 2\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"t\":2,\"s\":[{\"i\":[[0,-1.75],[0,-7.713],[0,-0.352],[0,0]],\"o\":[[0,0.928],[0,6.833],[0,0.75],[0,0]],\"v\":[[-66.5,81.75],[-66.5,98.7],[-66.5,112.25],[-69,113.5]],\"c\":false}],\"h\":1},{\"t\":4,\"s\":[{\"i\":[[0,-1.75],[0,-7.485],[0,-0.366],[0,0]],\"o\":[[0,0.897],[0,7.12],[0,0.75],[0,0]],\"v\":[[-66.5,81.75],[-68.5,98.09],[-66,112.25],[-69,112.667]],\"c\":false}],\"h\":1},{\"t\":6,\"s\":[{\"i\":[[0,-1.75],[0,-7.485],[0,-0.366],[0,0]],\"o\":[[0,0.897],[0,7.12],[0,0.75],[0,0]],\"v\":[[-67.333,76.75],[-66.5,96.59],[-66,112.25],[-69,112.667]],\"c\":false}],\"h\":1},{\"t\":9,\"s\":[{\"i\":[[0,-1.75],[4.167,-7.744],[0,-0.366],[0,0]],\"o\":[[0,0.897],[-4.167,7.744],[0,0.75],[0,0]],\"v\":[[-39.833,72.583],[-52.333,91.59],[-63.333,109.417],[-69,112.667]],\"c\":false}],\"h\":1},{\"t\":11,\"s\":[{\"i\":[[0,-1.75],[4.333,-4.256],[0,-0.366],[0,0]],\"o\":[[0,0.897],[-6.273,6.162],[0,0.75],[0,0]],\"v\":[[-31.5,79.917],[-42.333,93.923],[-60,105.417],[-64,110]],\"c\":false}],\"h\":1},{\"t\":14,\"s\":[{\"i\":[[0,-1.75],[4.167,-7.744],[0,-0.366],[0,0]],\"o\":[[0,0.897],[-4.167,7.744],[0,0.75],[0,0]],\"v\":[[-61.833,89.25],[-46.333,96.256],[-63.333,109.417],[-70.333,112]],\"c\":false}],\"h\":1},{\"t\":15,\"s\":[{\"i\":[[0,-1.75],[0.5,-2.244],[0,-0.366],[0,0]],\"o\":[[0,0.897],[-0.5,2.244],[0,0.75],[0,0]],\"v\":[[-67.167,87.75],[-84.833,94.423],[-73.667,110.917],[-76.667,111.333]],\"c\":false}],\"h\":1},{\"t\":17,\"s\":[{\"i\":[[0,-1.75],[0.5,-2.244],[0,-0.366],[0,0]],\"o\":[[0,0.897],[-0.5,2.244],[0,0.75],[0,0]],\"v\":[[-56.5,-10.583],[-60.167,40.09],[-57.333,75.25],[-60,84.667]],\"c\":false}],\"h\":1},{\"t\":19,\"s\":[{\"i\":[[0,-1.75],[-3.042,-4.577],[0,-0.366],[0,0]],\"o\":[[0,0.897],[3.042,4.577],[0,0.75],[0,0]],\"v\":[[-61.042,-115.583],[-57.542,-125.91],[-54.542,-108.083],[-56.208,-96.333]],\"c\":false}],\"h\":1},{\"t\":20,\"s\":[{\"i\":[[0,-1.75],[0,0],[0,-0.366],[0,0]],\"o\":[[0,0.897],[0,0],[0,0.75],[0,0]],\"v\":[[-60.042,-103.083],[-58.708,-109.077],[-56.375,-119.417],[-58.542,-124.333]],\"c\":false}],\"h\":1}]},\"nm\":\"Path 1\"},{\"ty\":\"st\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"w\":{\"k\":4},\"lc\":2,\"lj\":2,\"nm\":\"Stroke 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\"}],\"ip\":2,\"op\":21,\"st\":2,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":17,\"ty\":4,\"nm\":\"DEPTH L\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-13,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"t\":3,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-89.722,-19.664],[-75.25,-8.22],[-30.403,-3.34],[-28.748,-28.87],[-27.375,-50.035],[-36.667,-61.68]],\"c\":true}],\"h\":1},{\"t\":4,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[-6.588,11.261],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[5.688,-9.723],[0,0],[0,0]],\"v\":[[-87.722,-21.664],[-78,-13.72],[-36.153,-5.84],[-36.412,-34.761],[-33.875,-53.285],[-42.667,-65.68]],\"c\":true}],\"h\":1},{\"t\":6,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[-1.639,9.503],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[1.748,-10.13],[0,0],[0,0]],\"v\":[[-87.222,-26.164],[-81,-20.47],[-36.903,-12.84],[-35.998,-41.87],[-28.625,-65.785],[-37.917,-77.43]],\"c\":true}],\"h\":1},{\"t\":8,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[-0.519,9.629],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0.748,-13.88],[0,0],[0,0]],\"v\":[[-87.222,-26.164],[-81,-20.47],[-36.903,-12.84],[-33.248,-41.62],[-31.875,-63.785],[-40.417,-75.68]],\"c\":true}],\"h\":1},{\"t\":9,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-64.722,-87.164],[-69.25,-86.72],[-88.653,-29.34],[-18.748,-9.62],[-12.625,-11.535],[-48.417,-43.93]],\"c\":true}],\"h\":1},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":10,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-37.222,-69.914],[-41.75,-69.47],[-63.153,-25.84],[-18.998,-10.62],[-12.625,-11.535],[-48.667,-30.68]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-37.222,-69.914],[-48.25,-64.97],[-63.153,-25.84],[-25.998,-8.12],[-12.625,-11.535],[-48.667,-30.68]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":13,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-37.222,-69.914],[-48.25,-64.97],[-63.153,-25.84],[-25.998,-8.12],[-12.625,-11.535],[-48.667,-30.68]],\"c\":true}],\"e\":[{\"i\":[[-1.543,-0.911],[-1.387,0.745],[0,0],[0,0],[0,0],[-0.221,-0.843]],\"o\":[[2.125,1.255],[1.387,-0.745],[0,0],[0,0],[0,0],[0.585,2.232]],\"v\":[[-50.625,-8.005],[18.363,-12.505],[1.863,-41.5],[-39.158,-43.137],[-73.375,-14.25],[-63.032,-10.845]],\"c\":true}]},{\"t\":14,\"s\":[{\"i\":[[-1.543,-0.911],[-1.387,0.745],[0,0],[0,0],[0,0],[-0.221,-0.843]],\"o\":[[2.125,1.255],[1.387,-0.745],[0,0],[0,0],[0,0],[0.585,2.232]],\"v\":[[-50.625,-8.005],[18.363,-12.505],[1.863,-41.5],[-39.158,-43.137],[-73.375,-14.25],[-63.032,-10.845]],\"c\":true}],\"h\":1},{\"t\":15,\"s\":[{\"i\":[[-1.543,-0.911],[-1.387,0.745],[0,0],[0,0],[0,0],[-0.221,-0.843]],\"o\":[[2.125,1.255],[1.387,-0.745],[0,0],[0,0],[0,0],[0.585,2.232]],\"v\":[[-85.125,-8.505],[-40.637,-3.005],[-32.137,-17],[-63.158,-17.137],[-88.875,-17.25],[-88.532,-15.845]],\"c\":true}],\"h\":1},{\"t\":17,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-80.512,-59.63],[-22.775,-59.63],[-22.887,-120.125],[-54.454,-120.125],[-80.625,-120.125],[-80.625,-112.391]],\"c\":true}],\"h\":1},{\"t\":19,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-80.587,-161.13],[-21.1,-161.255],[-21.025,-214],[-54.342,-213.875],[-80.512,-213.875],[-80.512,-206.141]],\"c\":true}],\"h\":1},{\"t\":20,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-80.587,-148.63],[-21.1,-148.755],[-21.025,-201.5],[-54.342,-201.375],[-80.512,-201.375],[-80.512,-193.641]],\"c\":true}],\"h\":1},{\"t\":21,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-80.587,-161.13],[-21.1,-161.255],[-21.025,-214],[-54.342,-213.875],[-80.512,-213.875],[-80.512,-206.141]],\"c\":true}],\"h\":1},{\"t\":23,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[-80.408,-171.213],[-20.92,-171.338],[-21.05,-213.047],[-54.367,-212.922],[-80.537,-212.922],[-80.512,-206.141]],\"c\":true}],\"h\":1}]},\"nm\":\"T 2\"},{\"ty\":\"tr\",\"p\":{\"k\":[-55.562,-42.877],\"ix\":2},\"a\":{\"k\":[-55.562,-42.877],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Group 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[-55.562,-42.877],\"ix\":2},\"a\":{\"k\":[-55.562,-42.877],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Group 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"T\"}],\"ip\":3,\"op\":25,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":18,\"ty\":4,\"nm\":\"T main body 2\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-113,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":2,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.333,102.312],[22.333,113.5],[-22.333,113.5],[-22.333,102.312]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.667,62.312],[22.333,113.5],[-22.333,113.5],[-22,62.312]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.667,62.312],[22.333,113.5],[-22.333,113.5],[-22,62.312]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.591,-23.742],[22.333,113.5],[-22.333,113.5],[-22.076,-23.742]],\"c\":true}]},{\"i\":{\"x\":0.1,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p1_1_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.591,-23.742],[22.333,113.5],[-22.333,113.5],[-22.076,-23.742]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.333,-112.688],[22.333,113.5],[-22.333,113.5],[-22.333,-112.688]],\"c\":true}]},{\"t\":16}]},\"nm\":\"Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0.667,-0.5],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\"}],\"ip\":2,\"op\":25,\"st\":2,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":19,\"ty\":4,\"nm\":\"T main body 4\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-113,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.1,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p1_1_0p167_0p167\",\"t\":4,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.333,102.312],[22.333,113.5],[-22.333,113.5],[-22.333,102.312]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.333,-112.688],[22.333,113.5],[-22.333,113.5],[-22.333,-112.688]],\"c\":true}]},{\"t\":17}]},\"nm\":\"Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.15,0.8,0.55,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0.667,-0.5],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\"}],\"ip\":4,\"op\":25,\"st\":4,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":20,\"ty\":4,\"nm\":\"T main body 3\",\"parent\":0,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[0,-113,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":[{\"i\":{\"x\":0.1,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p1_1_0p167_0p167\",\"t\":2,\"s\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.333,102.312],[22.333,113.5],[-22.333,113.5],[-22.333,102.312]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0]],\"v\":[[22.333,-112.688],[22.333,113.5],[-22.333,113.5],[-22.333,-112.688]],\"c\":true}]},{\"t\":15}]},\"nm\":\"Path 1\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.86,0.86,0.86,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0.667,-0.5],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Rectangle 1\"}],\"ip\":2,\"op\":25,\"st\":2,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":21,\"ty\":4,\"nm\":\"T Outlines\",\"parent\":22,\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[250,400,0]},\"a\":{\"k\":[0,0,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[81.56,-226.593],[-80.681,-226.593],[-80.681,-184.598],[-22.975,-184.598],[-22.975,0],[23.854,0],[23.854,-184.598],[81.56,-184.598]],\"c\":true}},\"nm\":\"T\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0,0.01,0.24,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\"},{\"ty\":\"tr\",\"p\":{\"k\":[0,0],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"T\"}],\"ip\":25,\"op\":30,\"st\":25,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":22,\"ty\":1,\"nm\":\"ResizerTemp\",\"parent\":23,\"ks\":{\"o\":{\"k\":0},\"r\":{\"k\":0},\"p\":{\"k\":[26.6,35.7,0]},\"a\":{\"k\":[250,300,0]},\"s\":{\"k\":[10.5,10.5,100]}},\"ao\":0,\"sw\":500,\"sh\":600,\"sc\":\"#ffffff\",\"ip\":0,\"op\":30,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":23,\"ty\":1,\"nm\":\"White Solid 50\",\"ks\":{\"o\":{\"k\":0},\"r\":{\"k\":0},\"p\":{\"k\":[40,50,0]},\"a\":{\"k\":[28,35,0]},\"s\":{\"k\":[142.857,142.857,100]}},\"ao\":0,\"sw\":56,\"sh\":70,\"sc\":\"#ffffff\",\"ip\":0,\"op\":30,\"st\":0,\"bm\":0,\"sr\":1}],\"v\":\"4.4.26\",\"ddd\":0,\"ip\":0,\"op\":30,\"fr\":25,\"w\":80,\"h\":100}"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/src/main/java/com/airbnb/lottiesplash/LottieFontViewGroup.java",
    "content": "package com.airbnb.lottiesplash;\n\nimport android.content.Context;\nimport android.graphics.Color;\nimport android.graphics.drawable.ColorDrawable;\nimport android.support.annotation.Nullable;\nimport android.util.AttributeSet;\nimport android.view.View;\nimport android.widget.FrameLayout;\n\nimport com.airbnb.lottie.LottieAnimationView;\nimport com.airbnb.lottie.LottieComposition;\nimport com.airbnb.lottie.OnCompositionLoadedListener;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class LottieFontViewGroup extends FrameLayout {\n  private final List<LottieAnimationView> views = new ArrayList<>();\n\n  @Nullable\n  private LottieAnimationView cursorView;\n\n  public LottieFontViewGroup(Context context) {\n    super(context);\n    init();\n  }\n\n  public LottieFontViewGroup(Context context, AttributeSet attrs) {\n    super(context, attrs);\n    init();\n  }\n\n  public LottieFontViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {\n    super(context, attrs, defStyleAttr);\n    init();\n  }\n\n  private int textSize;\n\n  private void init() {\n    final float density = getContext().getResources().getDisplayMetrics().density;\n    textSize = (int)(density*120);\n\n    for(int x=0; x<5; x++) {\n      cursorView = new LottieAnimationView(getContext());\n      cursorView.setLayoutParams(new LayoutParams(\n          textSize,\n          textSize\n      ));\n      addView(cursorView);\n      views.add(cursorView);\n    }\n\n\n\n    this.postDelayed(new Runnable() {\n      @Override public void run() {\n        LottieComposition.Factory.fromAssetFileName(getContext(), \"A.json\",\n            new OnCompositionLoadedListener() {\n              @Override\n              public void onCompositionLoaded(LottieComposition composition) {\n                  views.get(0).setBackgroundDrawable(new ColorDrawable(0x112233));\n                views.get(0).setComposition(composition);\n                views.get(0).playAnimation();\n              }\n            });\n      }\n    },300);\n\n    this.postDelayed(new Runnable() {\n      @Override public void run() {\n        LottieComposition.Factory.fromAssetFileName(getContext(), \"T.json\",\n            new OnCompositionLoadedListener() {\n              @Override\n              public void onCompositionLoaded(LottieComposition composition) {\n                views.get(1).setComposition(composition);\n                views.get(1).playAnimation();\n              }\n            });\n      }\n    },300);\n\n    this.postDelayed(new Runnable() {\n      @Override public void run() {\n        LottieComposition.Factory.fromAssetFileName(getContext(), \"L.json\",\n            new OnCompositionLoadedListener() {\n              @Override\n              public void onCompositionLoaded(LottieComposition composition) {\n                views.get(2).setComposition(composition);\n                views.get(2).playAnimation();\n              }\n            });\n      }\n    },300);\n\n    this.postDelayed(new Runnable() {\n      @Override public void run() {\n        LottieComposition.Factory.fromAssetFileName(getContext(), \"A.json\",\n            new OnCompositionLoadedListener() {\n              @Override\n              public void onCompositionLoaded(LottieComposition composition) {\n                views.get(3).setComposition(composition);\n                views.get(3).playAnimation();\n              }\n            });\n      }\n    },300);\n\n    this.postDelayed(new Runnable() {\n      @Override public void run() {\n        LottieComposition.Factory.fromAssetFileName(getContext(), \"S.json\",\n            new OnCompositionLoadedListener() {\n              @Override\n              public void onCompositionLoaded(LottieComposition composition) {\n                views.get(4).setComposition(composition);\n                views.get(4).playAnimation();\n              }\n            });\n      }\n    },300);\n\n  }\n\n  @Override\n  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {\n    int currentX = (getWidth()-textSize/2*5)/2;\n    int currentY = getPaddingLeft();\n\n    for (int i = 0; i < views.size(); i++) {\n      View view = views.get(i);\n      view.layout(currentX, currentY, currentX + view.getMeasuredWidth()/2,\n          currentY + view.getMeasuredHeight());\n          currentX += view.getMeasuredWidth()/2;\n    }\n  }\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/src/main/java/com/taobao/splashscreen/WelcomeActivity.java",
    "content": "package com.taobao.splashscreen;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\nimport android.view.View;\n\n/**\n * An example full-screen activity that shows and hides the system UI (i.e.\n * status bar and navigation/system bar) with user interaction.\n */\npublic class WelcomeActivity extends AppCompatActivity {\n\n    private View mContentView;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n\n        setContentView(R.layout.activity_welcome);\n\n        mContentView = findViewById(R.id.fullscreen_content);\n\n\n        mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE\n                | View.SYSTEM_UI_FLAG_FULLSCREEN\n                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE\n                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY\n                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION\n                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);\n\n        mContentView.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n//                toggle();\n            }\n        });\n\n    }\n\n    @Override\n    protected void onPostCreate(Bundle savedInstanceState) {\n        super.onPostCreate(savedInstanceState);\n\n        mContentView.postDelayed(new Runnable() {\n            @Override\n            public void run() {\n                Intent intent = new Intent();\n                intent.setClassName(getBaseContext(),\"com.taobao.demo.MainActivity\");\n                startActivity(intent);\n                finish();\n                overridePendingTransition(-1,android.R.anim.slide_out_right);\n            }\n        },3000);\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/src/main/res/layout/activity_welcome.xml",
    "content": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"#EEEEEE\"\n    android:orientation=\"vertical\"\n    tools:context=\"com.taobao.splashscreen.WelcomeActivity\">\n\n    <!-- The primary full-screen view. This can be replaced with whatever view\n         is needed to present your content, e.g. VideoView, SurfaceView,\n         TextureView, etc. -->\n\n    <FrameLayout\n        android:layout_weight=\"1\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <com.airbnb.lottiesplash.LottieFontViewGroup\n            android:id=\"@+id/font_view\"\n            android:layout_gravity=\"center_vertical\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"/>\n    </FrameLayout>\n\n    <TextView\n        android:layout_weight=\"2\"\n        android:id=\"@+id/fullscreen_content\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:gravity=\"center\"\n        android:keepScreenOn=\"true\"\n        android:text=\"be simple,be effective\"\n        android:textColor=\"#33b5e5\"\n        android:textSize=\"16dp\"\n        android:textStyle=\"italic\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/src/main/res/values/attrs.xml",
    "content": "<resources>\n\n    <!-- Declare custom theme attributes that allow changing which styles are\n         used for button bars depending on the API level.\n         ?android:attr/buttonBarStyle is new as of API 11 so this is\n         necessary to support previous API levels. -->\n    <declare-styleable name=\"ButtonBarContainerTheme\">\n        <attr name=\"metaButtonBarStyle\" format=\"reference\" />\n        <attr name=\"metaButtonBarButtonStyle\" format=\"reference\" />\n    </declare-styleable>\n\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"black_overlay\">#66000000</color>\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"title_activity_welcome\">WelcomeActivity</string>\n    <string name=\"dummy_button\">Dummy Button</string>\n    <string name=\"dummy_content\">DUMMY\\nCONTENT</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <style name=\"FullscreenTheme\" parent=\"Theme.AppCompat.NoActionBar\">\n        <item name=\"android:actionBarStyle\">@style/FullscreenActionBarStyle</item>\n        <item name=\"android:windowActionBarOverlay\">true</item>\n        <item name=\"android:windowBackground\">@null</item>\n    </style>\n\n    <style name=\"FullscreenActionBarStyle\" parent=\"Widget.AppCompat.ActionBar\">\n        <item name=\"android:background\">@color/black_overlay</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "atlas-demo/AtlasDemo/splashscreen/src/test/java/com/taobao/splashscreen/ExampleUnitTest.java",
    "content": "package com.taobao.splashscreen;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "atlas-demo/AtlasDemo/structor.md",
    "content": "##demo的依赖关系\n    {\n\t\"awbs\":{\n\t\t\"AtlasDemo:remotebundle:unspecified@awb\":[],\n\t\t\"AtlasDemo:publicbundle:unspecified@awb\":[],\n\t\t\"AtlasDemo:firstbundle:unspecified@awb\":[],\n\t\t\"AtlasDemo:secondbundle:unspecified@awb\":[\n\t\t\t\"AtlasDemo:secondbundlelibrary:unspecified@aar\"\n\t\t]\n\t},\n\t\"mainDex\":[\n\t\t\"AtlasDemo:activitygroupcompat:unspecified@aar\",\n\t\t\"AtlasDemo:lottie:unspecified@aar\",\n\t\t\"AtlasDemo:middlewarelibrary:unspecified@aar\",\n\t\t\"AtlasDemo:splashscreen:unspecified@aar\",\n\t\t\"com.alibaba:fastjson:1.1.45.android@jar\",\n\t\t\"com.android.support.constraint:constraint-layout-solver:1.0.0-alpha8@jar\",\n\t\t\"com.android.support.constraint:constraint-layout:1.0.0-alpha8@aar\",\n\t\t\"com.android.support:animated-vector-drawable:25.3.0@aar\",\n\t\t\"com.android.support:appcompat-v7:25.3.0@aar\",\n\t\t\"com.android.support:design:25.3.0@aar\",\n\t\t\"com.android.support:recyclerview-v7:25.3.0@aar\",\n\t\t\"com.android.support:support-annotations:25.3.0@jar\",\n\t\t\"com.android.support:support-compat:25.3.0@aar\",\n\t\t\"com.android.support:support-core-ui:25.3.0@aar\",\n\t\t\"com.android.support:support-core-utils:25.3.0@aar\",\n\t\t\"com.android.support:support-fragment:25.3.0@aar\",\n\t\t\"com.android.support:support-media-compat:25.3.0@aar\",\n\t\t\"com.android.support:support-v4:25.3.0@aar\",\n\t\t\"com.android.support:support-vector-drawable:25.3.0@aar\",\n\t\t\"com.android.support:transition:25.3.0@aar\",\n\t\t\"com.taobao.android:atlas_core:5.0.6-rc3@aar\",\n\t\t\"com.taobao.android:atlasupdate:1.1.4@aar\"\n\t]\n    }\n \n \n ## 一些提示\n \n1. MainActivity 通过ActivityGroupCompat 实现展示bundle 内的Fragment，因为bundle只通过Component的方式可以被依赖安装\n2. 左侧nativetiondraw里面展示动态部署和远程bundle的测试过程"
  },
  {
    "path": "atlas-demo/IncrementAtlasDemo/.gitignore",
    "content": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n"
  },
  {
    "path": "atlas-demo/IncrementAtlasDemo/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    repositories {\n        mavenLocal()\n        jcenter()\n        maven {\n//            url \"http://mvnrepo.alibaba-inc.com/mvn/repository\"\n            url \"http://maven.aliyun.com/nexus/content/groups/public\"\n        }\n    }\n    configurations.all {\n        resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds'\n        resolutionStrategy.cacheChangingModulesFor 0, 'seconds'\n    }\n    dependencies {\n//        classpath \"com.taobao.android:atlasplugin:2.3.3.rc12\"\n        classpath \"com.taobao.android:atlasplugin:2.3.1.beta37-incremental\"\n        classpath 'com.android.tools.build:gradle:2.3.3'\n    }\n}\n\nsubprojects {\n    repositories {\n        jcenter()\n        maven {\n//            url \"http://mvnrepo.alibaba-inc.com/mvn/repository\"\n            url \"http://maven.aliyun.com/nexus/content/groups/public\"\n        }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "atlas-demo/IncrementAtlasDemo/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Thu Mar 16 12:49:23 CST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-3.3-all.zip\n"
  },
  {
    "path": "atlas-demo/IncrementAtlasDemo/gradle.properties",
    "content": "\n## Project-wide Gradle settings.\n#\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n#\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\n# Default value: -Xmx1024m -XX:MaxPermSize=256m\n# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\n#\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n#Sun Mar 26 09:43:28 CST 2017\n#systemProp.http.proxyHost=127.0.0.1\n#org.gradle.jvmargs=-Xmx1536m\n#systemProp.http.proxyPort=1080\norg.gradle.parallel=true\norg.gradle.daemon=true\nandroid.keepTimestampsInApk=true\n"
  },
  {
    "path": "atlas-demo/IncrementAtlasDemo/gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "atlas-demo/IncrementAtlasDemo/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windowz variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\ngoto execute\n\n:4NT_args\n@rem Get arguments from the 4NT Shell from JP Software\nset CMD_LINE_ARGS=%$\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "atlas-demo/IncrementAtlasDemo/increment_app/build.gradle",
    "content": "group = 'com.taobao.android.atlasdemo'\nversion = getEnvValue(\"versionName\", \"1.0.0\");\ndef apVersion = getEnvValue(\"apVersion\", \"\");\n\napply plugin: 'com.android.application'\napply plugin: 'com.taobao.atlas'\n//apply plugin: 'com.taobao.atlas.dexpatch'\n//apply from: 'dexPatchWraper.gradle'\n\n//通过增加判断逻辑，打出不同类型的定制包\ndef appId = \"com.taobao.demo\"\ndef minVersion = 14\nif (project.hasProperty(\"beta\")) {\n    appId = \"com.taobao.atlas.beta\"\n    minVersion = 21\n}\n// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    repositories {\n        mavenLocal()\n        jcenter()\n        maven {\n//            url \"http://mvnrepo.alibaba-inc.com/mvn/repository\"\n            url \"http://maven.aliyun.com/nexus/content/groups/public\"\n        }\n    }\n    configurations.all {\n        resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds'\n        resolutionStrategy.cacheChangingModulesFor 0, 'seconds'\n    }\n    dependencies {\n        classpath \"com.taobao.android:atlasplugin:2.3.1.beta36-incremental\"\n    }\n}\n\n\nrepositories {\n    mavenLocal()\n    jcenter()\n}\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion '25.0.0'\n    defaultConfig {\n        applicationId appId\n        minSdkVersion minVersion\n        targetSdkVersion 25\n        versionCode 1\n        versionName version\n        vectorDrawables.useSupportLibrary = true\n        //通过增加判断逻辑，打出不同类型的定制包\n        if (project.hasProperty(\"beta\")) {\n            buildConfigField \"boolean\", \"API_ENV\", \"false\"\n        } else {\n            buildConfigField \"boolean\", \"API_ENV\", \"false\"\n        }\n    }\n\n//    dataBinding {\n//        enabled = true\n//    }\n\n\n    buildTypes {\n        release {\n            minifyEnabled true\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n        debug {\n            ndk {\n                abiFilters \"x86\", \"armeabi\"\n            }\n\n        }\n    }\n\n    //    productFlavors {\n    //        dev {\n    //            minSdkVersion 14\n    //        }\n\n    //        beta {\n    //            minSdkVersion 21\n    //        }\n    //    }\n}\n\natlas {\n\n//    atlasEnabled true\n//    tBuildConfig {\n//        autoStartBundles = ['com.taobao.firstbundle'] //自启动bundle配置\n//        outOfApkBundles = ['remotebundle']\n//        preLaunch = 'com.taobao.demo.DemoPreLaunch'\n//        classInject false\n//        dataBindingBundles = ['com.taobao.databindbundle']\n//    }\n//\n//    manifestOptions {\n//        addAtlasProxyComponents true\n//    }\n//\n//\n//    patchConfigs {\n//        debug {\n//            createTPatch true\n//        }\n//    }\n\n\n    buildTypes {\n        debug {\n            baseApFile project.rootProject.file('../AtlasDemo/app/build/outputs/apk/app-debug.ap')\n//            if (apVersion) {\n//                baseApDependency \"com.taobao.android.atlasdemo:AP-debug:${apVersion}@ap\"\n//                patchConfig patchConfigs.debug\n//            }\n        }\n    }\n}\nconfigurations.all {\n    transitive = false\n}\n\ndependencies {\n\n    //    compile fileTree(dir: 'libs', include: ['*.jar'])\n\n    //\n\n    compile('com.taobao.android:atlas_core:5.0.7.41@aar') {\n\n\n        transitive = true\n\n    }\n\n    //\n\n    //    compile project(':middlewarelibrary')\n\n    //    compile project(':splashscreen')\n    compile project(':activitygroupcompat')\n    //    bundleCompile project(':firstbundle')\n\n    //    bundleCompile project(':secondbundle')\n\n    //    bundleCompile project(':remotebundle')\n\n    //    bundleCompile project(':publicbundle')\n\n    //    bundleCompile project(':databindbundle')\n\n    //\n\n    //    compile 'com.android.support:appcompat-v7:25.1.0'\n\n    //    compile 'com.android.support:design:25.1.0'\n\n    //    compile 'com.android.support:support-vector-drawable:25.1.0'\n\n    //    compile 'com.android.support:support-v4:25.1.0'\n\n    //    compile 'com.taobao.android:atlasupdate:1.1.4.11@aar'\n\n    //\n\n    //    compile 'com.alibaba:fastjson:1.1.45.android@jar'\n\n    //    compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8'\n\n    //    compile 'com.android.support:recyclerview-v7:25.3.0'\n    compile project(':publicbundle')\n    compile project(':middlewarelibrary')\n    compile project(':firstbundle')\n}\n\nString getEnvValue(key, defValue) {\n    def val = System.getProperty(key);\n    if (null != val) {\n        return val;\n    }\n    val = System.getenv(key);\n    if (null != val) {\n        return val;\n    }\n    return defValue;\n}\n\ntasks.whenTaskAdded { task ->\n    if (task.name.contains(\"DebugAndroidTest\")) {\n        task.setEnabled(false);\n    }\n    if (task.name.contains(\"assemble\")) {\n        def files = null;\n        def file = new File(task.project.getBuildDir(), \"outputs\");\n        if (file.exists() && new File(file, \"tpatch-debug\").exists()) {\n            files = new File(file, \"tpatch-debug\").listFiles();\n        }\n        if (files != null) {\n            for (File file1 : files) {\n                if (file1.getName().endsWith(\".json\") || file1.getName().endsWith(\".tpatch\")) {\n\n                    if (!new File(task.project.getRootDir(), \"hisTpatch\").exists()) {\n                        new File(task.project.getRootDir(), \"hisTpatch\").mkdirs();\n                    }\n                    org.apache.commons.io.FileUtils.copyFileToDirectory(file1, new File(task.project.getRootDir(), \"hisTpatch\"));\n                }\n            }\n        }\n    }\n}\n\napply plugin: 'maven'\napply plugin: 'maven-publish'\n\npublishing {\n    repositories {\n        mavenLocal()\n    }\n}\n\npublishing {\n    publications {\n        maven(MavenPublication) {\n            artifact \"${project.buildDir}/outputs/apk/${project.name}-debug.ap\"\n            artifactId \"AP-debug\"\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-demo/IncrementAtlasDemo/increment_app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n          package=\"com.taobao.demo\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\"/>\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>\n\n    <application\n        android:name=\".DemoApplication\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"Atlas\"\n        android:supportsRtl=\"true\">\n        <activity\n            android:name=\"com.taobao.splashscreen.WelcomeActivity\"\n            android:configChanges=\"orientation|keyboardHidden|screenSize\"\n            android:theme=\"@style/FullscreenTheme\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\"/>\n\n                <category android:name=\"android.intent.category.LAUNCHER\"/>\n            </intent-filter>\n        </activity>\n        <!--\n                <activity\n                    android:name=\".MainActivity\"\n                    android:label=\"@string/app_name\"\n                    android:theme=\"@style/AppTheme.NoActionBar\" />\n                <activity\n                    android:name=\".MainActivity2\"\n                    android:label=\"@string/app_name\"\n                    android:process=\":remote\"\n                    android:theme=\"@style/AppTheme.NoActionBar\" />\n                <activity\n                    android:name=\".UpdateDemoActivity\"\n                    android:label=\"@string/title_activity_scrolling\"\n                    android:theme=\"@style/AppTheme.NoActionBar\" />\n                <activity\n                    android:name=\".RemoteDemoActivity\"\n                    android:label=\"@string/title_activity_update\"\n                    android:process=\":remote\"\n                    android:theme=\"@style/AppTheme.NoActionBar\"></activity>\n\n                <provider\n                    android:name=\".MyContentProvider\"\n                    android:authorities=\"com.test.abc\"\n                    android:enabled=\"true\"\n                    android:exported=\"true\"></provider>\n        -->\n    </application>\n\n</manifest>"
  },
  {
    "path": "atlas-demo/IncrementAtlasDemo/settings.gradle",
    "content": "//include ':middlewarelibrary'\n//include ':secondbundlelibrary'\n//include ':lottie'\n//include ':activitygroupcompat'\n//include ':firstbundle'\n//include ':secondbundle'\n//include ':publicbundle'\n//include ':remotebundle'\n//include ':databindbundle'\n//include ':splashscreen'\n//include ':app'\ninclude ':increment_app'\n\ninclude \":activitygroupcompat\"\nproject(\":activitygroupcompat\").projectDir = file(\"../AtlasDemo/activitygroupcompat\")\n\ninclude \":publicbundle\"\nproject(\":publicbundle\").projectDir = file(\"../AtlasDemo/publicbundle\")\n\ninclude \":middlewarelibrary\"\nproject(\":middlewarelibrary\").projectDir = file(\"../AtlasDemo/middlewarelibrary\")\n\ninclude \":firstbundle\"\nproject(\":firstbundle\").projectDir = file(\"../AtlasDemo/firstbundle\")\n"
  },
  {
    "path": "atlas-demo/MyApplication/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Mon Dec 28 10:00:20 PST 2015\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-2.14.1-all.zip\n"
  },
  {
    "path": "atlas-demo/MyApplication/gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "atlas-demo/README.md",
    "content": "Atlas Demo已经具备了一个小型app的基本框架，本demo中主要展示了Atlas的主客户端、业务bundle、业务bundle独有library、中间件library、远程bundle、公共bundle、闪屏等特性。\n\n## 工程导入\n\nAtlas Demo地址https://github.com/alibaba/atlas/tree/master/atlas-demo/AtlasDemo 。git等安装详情不表。\nAtlas Demo基于gradle，使用Android Studio打开。Android开发环境搭建详情不表。\n需要注意的是Atlas是基于gradle的最新版本3.3的，如果没有安装gradle 3.3的用户使用Android Studio第一次启动会卡住，这里建议在使用Android Studio启动之前可以先在终端使用\n\n  `./gradlew build`\n  \n编译工程，如果等待时间依旧过长，可以选择以下两种方式：\n\n1. 翻墙（推荐）。因为Atals Demo除了gradle还需要其他一下远程资源。\n\n2. 手动下载gradle-3.3-all.zip，拷贝到相应的grdle安装目录（mac默认为/Users/<用户名>/.gradle/wrapper/dists目录，Windows默认为C:\\Users\\计算机名.gradle\\wrapper\\dists目录）。\n\n## 工程框架\n\n我们从几个方面结合起来共同来看Atlas Demo的工程框架，也会大家开发更为复杂的APP提供帮助。\n\n## 工程目录\n\n<img src=\"./img/dictionary.png\" width=\"30%\"  alt=\"工程目录.png\"/>\n\napp目录：主客户端代码\n\nfirstbundle目录：第一个业务bundle代码\n\nsecondbundle目录：第二个业务bundle代码\n\nsecondbundlelibrary目录：第二个业务bundle单独依赖的library代码\n\nremotebundle目录：远程bundle代码（远程bundle在APK发布时不会编译进APK内，而是在客户端使用时下载后加载）\n\npublicbundle目录：公共bundle代码（不会打入主dex）\n\nmiddlewarelibrary目录：中间件library（会打入主dex）\n\nsplashscreen目录：闪屏代码\n\nlottie目录：splahscreen的依赖代码\n\nactivitygroupcompat目录：实现展示bundle 内的Fragment，因为bundle只通过Component的方式可以被依赖安装\n\n## strutor.md\n\n<img src=\"./img/structer.png\" width=\"80%\"  alt=\"strutor.md.png\"/>\n\nAtlas Demo作者也在structor.md里面列出了demo的依赖关系，其中**mainDex指的是会被编译进主dex的依赖**；awbs指的是各个bundle，它们将以**so文件的形式放在APK的lib文件夹**下（这些个so文件其实就是各个业务bundle的独立APK，只不过这个APK可能要依赖容器里面的中间件代码才能运行，只是后缀改成了so而已），从awbs中也可以看出secondbundlelibrary只被secondbundle依赖。\n\n## app/build.gradle\n\n<img src=\"./img/buildgradle.png\" width=\"80%\"  alt=\" buildgradle.png\"/>\n\n我们再来看下主客户端的build.gradle代码，如上图所示，从中可以看到业务bundle都是使用Atlas自定义的编译方法**bundleCompile**来进行依赖，其余需要编译进主dex的依赖都是使用原生**compile**命令进行依赖，如果只是provided依赖则使用**providedCompile**,使用atlas功能的主客户端代码需要依赖atlasplugin、atlas_core和atlasupdate。\n\n## APK解压后的文件目录（构建APK参见“主APK构建”章节）\n\n<img src=\"./img/apk目录.png\" width=\"80%\"  alt=\" apk解压.png\"/>\n\n通过解压编译出来的APK我们也可以发现firstbundle，secondbundle，publicbundle是以so包的形式放在了lib/armeabi目录下面，注意这里并没有remotebundle的so文件，remotebundle的加载方式将在下文介绍。strutor.md中mainDex下的bundle都编译进了class.dex中。\n\n## Activity跳转关系\n\nAtlas Demo里面的Activity分布比较散，为了方便大家的快速入手，这里简单介绍下个Activity的跳转关系。\n\n## WelcomeActivity\n\nsplashscreen bundle是会被编译进主dex里面的，从spllashscreen的manifest文件（splashscreen/src/main/AndroidManifest.xml）我们可以看到，WelcomeActivity是接收“android.intent.action.MAIN”和“android.intent.category.LAUNCHER”的Activity，WelcomeActivity是APP的入口Activity。\n<img src=\"./img/manifest.png\" width=\"80%\"  alt=\" manifest.png\"/>\n\n## WelcomeActivity->MainActivity\n\n在WelcomeActivity.java（splashscreen目录）中的onPostCreate通过startActivity跳转到APP的首页MainActivity（app目录）。\n<img src=\"./img/welcomepostcreate.png\" width=\"80%\"  alt=\" WelcomeActivity.png\"/>\n\n## MainActivity->FirstBundleActivity\n\nMainActivity其实是个壳子Activity，在其onCreate函数中我们可以看到它其实是默认加载了firstbundle的FirstBundleActivity，并设置了导航栏，关于导航栏的具体实现细节大家可以参考activitygroupcompat bundle。\n<img src=\"./img/mainactivityoncreate.png\" width=\"90%\"  alt=\" MainActivity.png\"/>\n\n## MainActivity->FirstBundleActivity、MainActivity->SecondBundleActivity\n\n通过导航栏我们可以实现在FirstBundleActivity和SecondBundleActivity之间进行跳转，FirstBundleActivity和SecondBundleActivity是属于不同的bundle，通过这种方式我们就实现了不同bundle的Activity在同一个APP中的展示。\n<img src=\"./img/mainactivitynav.png\" width=\"90%\"  alt=\" MainActivity.png\"/>\n\n## 场景构建\n\nAtlas Demo里面集成了主APK构建、动态部署构建、远程bundle构建等功能，下面我们进行单独介绍。\n\n## 问题1：如何构建一个APK，发布到各个应用市场？\n\n### 主APK构建步骤：\n\n1. Atlas Demo中将主客户端代码和所有bundle都放在了一个工程下面，这也符合gradle工程的标准框架格式。\n\n2. 各个业务bundle可以根据业务需求修改更新各自bundle的代码。然后再通过修改app/build.gradle中的version = getEnvValue(\"versionName\", \"1.0.0\");来修改版本号，版本号默认为1.0.0。\n3. 然后再在app目录下面执行`../gradlew clean assembleDebug publish`命令从而进行APK打包，生成的APK文件目录是app/build/outputs/apk/app-debug.apk，上述命令也会将该目录下的ap文件发布到仓库以便于后续生成patch。\n4. 如果有手机连接在pc上可以直接使用adb install安装上述APK，在app目录下执行`adb install app/build/outputs/apk/app-debug.apk`。\n\n## 问题2：如何在用户无感知的情况下，实现所有业务模块的独立动态更新？\n\n### 动态部署（patch）构建步骤：\n\n1. 各个业务bundle可以根据业务需求修改更新各自bundle的代码。\n\n2. app工程目录下执行`../gradlew clean assembleDebug -DapVersion=apVersion -DversionName=newVersion`, 其中apVersion为之前打的完整APK的版本，newVersion为此次动态部署要生成的新的版本号。\n这里举一个简单的例子，例如“主APK构建”步骤的APK版本是1.0.0，然后我简单更新firstbundle的string.xml里面的hello_blank_fragment属性为“this is fragment of firstBundle”，然后执行`../gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.1`。\n<img src=\"./img/_firstbundlepatch.png\" width=\"100%\"  alt=\" MainActivity.png\"/>\n\n3. 检查build/output/tpatch-debug 目录下文件是否生成，将远程patch下载到你的设备上（主动下载和被动推送都可以，这里直接在PC上执行下面的命令(以下为mac下的命令，windows请修改文件分隔符)：\n   ` adb push build/outputs/tpatch-debug/update.json /sdcard/Android/data/com.taobao.demo/cache/update.json`\n   ` adb push build/outputs/tpatch-debug/patch-*.tpatch /sdcard/Android/data/com.taobao.demo/cache`\n4. 打开Demo侧边栏，点击“动态部署模拟”，页面红色按钮执行动态部署，等待几秒钟之后APP会关闭此时说明动态部署已经成功，重启APP后就会发现自己改动的代码已经更新成功。\n<img src=\"./img/app动态部署.png\" width=\"40%\"  alt=\"动态部署.png\"/>  <img src=\"./img/appfirstbundlepatch.png\" width=\"40%\"  alt=\"动态部署结果.png\"/>\n\n5. 感兴趣的同学可以研究下update.json和tpatch文件\n6. 动态部署的主要优势：摆脱版本迭代周期限制，新增需求灵活发布；降低版本频繁发布给用户带来困扰；发现问题及时回滚；短时间内更高的覆盖率\n\n## 问题3：如果在APK发布时，我不想把某个bundle编译进APK，而是在客户端使用时下载后加载，该怎么办？\n\n### 远程bundle构建步骤：\n\n1. 添加远程bundle的依赖，参考 app/build.gradle下的 `bundleCompile project(':remotebundle')` ，\n2. 声明远程bundle列表，参考 app/build.gradle下的`atlas { tBuildConfig { outOfApkBundles = ['remotebundle'] }`。\n3. 构建完整包，在app目录下执行`../gradlew clean assembleDebug publish`，远程bundle 路径：app/build/outputs/remote-bundles-debug。\n4. 将远程so下载到你的设备上（主动下载和被动推送都可以），这里直接在PC上执行`adb push app/build/outputs/remote-bundles-debug/libcom_taobao_remotebunle.so /sdcard/Android/data/com.taobao.demo/cache/libcom_taobao_remotebunle.so`。\n5. 打开Demo侧边栏，点击“远程组件模拟”，点击“加载远程bundle”，加载成功后就会跳到remotebundle的页面。\n\n<img src=\"./img/appremotebundle.png\" width=\"40%\"  alt=\"动态部署.png\"/>\n\n## 调试工具\n\n### 单bundle调试（供线下调试使用，当只更改了单个bundle的代码时，无需对整个APP进行动态部署，可以一键进行单bundle的部署调试）\n\n1. 在设备上安装APP，设备ADB连接电脑成功。\n2. 修改一个bundle工程的代码或者资源（设置生效的标识）。\n例如，我们这里在firstbundle中的FirstBundleActivity的onCreate的中加一个Toast提示，如下\n<img src=\"./img/toast.png\" width=\"100%\"  alt=\"单bundle.png\"/>\n3. bundle工程的目录下执行`../gradlew clean assemblePatchDebug`，然后等应用重启或者应用关闭后点击重启\")就可以看到代码生效。\n根据上述改动，我们在firstbundle的目录下执行`../gradlew clean assemblePatchDebug`，然后就可以看到客户端重启，Toast提示生效。\n\n<img src=\"./img/apptoast.png\" width=\"40%\"  alt=\"单bundle.png\"/>\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/.google/packaging.yaml",
    "content": "#\n# Copyright (C) 2017 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# GOOGLE SAMPLE PACKAGING DATA\n#\n# This file is used by Google as part of our samples packaging process.\n# End users may safely ignore this file. It has no relevance to other systems.\n---\n# Values: {DRAFT | PUBLISHED | INTERNAL | DEPRECATED | SUPERCEDED}\nstatus:       PUBLISHED\n\n# Optional, put additional explanation here for DEPRECATED or SUPERCEDED.\n# statusNote:\n\n# See http://go/sample-categories\ntechnologies: [Android]\ncategories:   [Instant Apps]\nlanguages:    [Java]\nsolutions:    [Mobile]\n\n# May be omitted if unpublished\ngithub:       googlesamples/android-instant-apps\n\n# Values: BEGINNER | INTERMEDIATE | ADVANCED | EXPERT\nlevel:        ADVANCED\n\n# Default: apache2. May be omitted for most samples.\n# Alternatives: apache2-android (for AOSP)\nlicense: apache2\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2017 Google Inc.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/NOTICE",
    "content": "This sample uses the following software:\n\nCopyright 2017 Google Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/README.md",
    "content": "# Android Instant Apps - Multi feature sample app\n\nThis sample app demonstrates building an installable and an instant app\nwith the same behaviors. The functionality of the instant app is split\nin two features, which can be individually launched on a device.\n\n## Launch URLs\n\n```\nhttps://multi-feature.instantappsample.com/main\nhttps://multi-feature.instantappsample.com/detail\n```\n\n## License\n\n```\nCopyright 2017 Google Inc.\n\nLicensed to the Apache Software Foundation (ASF) under one or more contributor\nlicense agreements. See the NOTICE file distributed with this work for\nadditional information regarding copyright ownership. The ASF licenses this\nfile to you under the Apache License, Version 2.0 (the \"License\"); you may not\nuse this file except in compliance with the License. You may obtain a copy of\nthe License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\nWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\nLicense for the specific language governing permissions and limitations under\nthe License.\n```\n\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/build.gradle",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\napply plugin: 'com.taobao.atlas.feature'\napply plugin: 'kotlin-android'\n\n\nandroid {\n    baseFeature true\n\n    compileSdkVersion rootProject.compileSdk\n    buildToolsVersion rootProject.buildTools\n\n    defaultConfig {\n        minSdkVersion rootProject.minSdk\n        targetSdkVersion rootProject.targetSdk\n        versionCode rootProject.versionCode\n        versionName rootProject.versionName\n    }\n\n    // Switch between test types by swapping commented out state\n    testBuildType /* 'debug' */  'minified'\n\n    buildTypes {\n        minified {\n            debuggable true\n            minifyEnabled true\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), '../proguard.pro'\n            signingConfig signingConfigs.debug\n        }\n        debug {}\n    }\n\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n}\n\ndependencies {\n    api \"com.android.support:appcompat-v7:$supportLib\"\n    api \"com.android.support:recyclerview-v7:$supportLib\"\n    api \"com.github.bumptech.glide:glide:$glide\"\n    api \"com.squareup.retrofit:retrofit:$retrofit\"\n    api 'com.taobao.android:atlas_core:5.0.8.0-rc46@aar'\n    api 'com.taobao.android:atlasupdate:1.1.4.14@aar'\n//    api \"org.jetbrains.kotlin:kotlin-stdlib:1.0.4\"\n\n\n\n    application project(':installed')\n    feature project(':main')\n    feature project(':detail')\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/AndroidManifest.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n          package=\"com.example.android.unsplash.base\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n\n    <application tools:replace=\"android:icon,android:allowBackup,android:label\" tools:remove=\"android:hardwareAccelerated,android:debuggable\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:theme=\"@style/App\">\n    </application>\n</manifest>\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/IntentUtil.kt",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash\n\nimport android.content.Intent\nimport com.example.android.unsplash.base.R\n\n/**\n * Holding intent extra names and utility methods for intent handling.\n */\nobject IntentUtil {\n    val FONT_SIZE = \"fontSize\"\n    val PADDING = \"padding\"\n    val PHOTO = \"photo\"\n    val TEXT_COLOR = \"color\"\n    val RELEVANT_PHOTOS = \"relevant\"\n    val SELECTED_ITEM_POSITION = \"selected\"\n    val BUNDLE_PHOTOS = \"photos\"\n    val REQUEST_CODE = R.id.requestCode\n\n    /**\n     * Checks if all extras are present in an intent.\n     *\n     * @param intent The intent to check.\n     * @param extras The extras to check for.\n     * @return `true` if all extras are present, else `false`.\n     */\n    fun hasAll(intent: Intent, vararg extras: String): Boolean {\n        for (extra in extras) {\n            if (!intent.hasExtra(extra)) {\n                return false\n            }\n        }\n        return true\n    }\n\n    /**\n     * Checks if any extra is present in an intent.\n     *\n     * @param intent The intent to check.\n     * @param extras The extras to check for.\n     * @return `true` if any checked extra is present, else `false`.\n     */\n    fun hasAny(intent: Intent, vararg extras: String): Boolean {\n        for (extra in extras) {\n            if (intent.hasExtra(extra)) {\n                return true\n            }\n        }\n        return false\n    }\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/data/PhotoService.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash.data;\n\nimport android.util.Log;\n\nimport com.example.android.unsplash.data.model.Photo;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport retrofit.Callback;\nimport retrofit.RestAdapter;\nimport retrofit.RetrofitError;\nimport retrofit.client.Response;\n\n/**\n * Only gets photos once per runtime.\n */\npublic class PhotoService {\n\n    public interface PhotoCallback {\n        void success(ArrayList<Photo> photos);\n        void error();\n    }\n\n    private static final int PHOTO_COUNT = 12;\n    private static final String TAG = \"PhotoService\";\n    private static ArrayList<Photo> mPhotos;\n    private static PhotoService sPhotoService;\n\n    public static PhotoService getInstance() {\n        if (sPhotoService == null) {\n            sPhotoService = new PhotoService();\n        }\n        return sPhotoService;\n    }\n\n    public void getPhotosAsync(final PhotoCallback callback) {\n        if (mPhotos == null) {\n            new RestAdapter.Builder()\n                    .setEndpoint(UnsplashService.ENDPOINT)\n                    .build()\n                    .create(UnsplashService.class).getFeed(new Callback<List<Photo>>() {\n                @Override\n                public void success(List<Photo> photos, Response response) {\n                    // the first items not interesting to us, get the last <n>\n                    mPhotos = new ArrayList<>(photos.subList(photos.size() - PHOTO_COUNT,\n                            photos.size()));\n                    callback.success(mPhotos);\n                }\n\n                @Override\n                public void failure(RetrofitError error) {\n                    callback.error();\n                    Log.e(TAG, \"Could not load photos, \" + error);\n                }\n            });\n        } else {\n            callback.success(mPhotos);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/data/UnsplashService.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash.data;\n\nimport com.example.android.unsplash.data.model.Photo;\n\nimport java.util.List;\n\nimport retrofit.Callback;\nimport retrofit.http.GET;\n\n/**\n * Modeling the unsplash.it API.\n */\npublic interface UnsplashService {\n\n    String ENDPOINT = \"https://unsplash.it\";\n\n    @GET(\"/list\")\n    void getFeed(Callback<List<Photo>> callback);\n\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/data/model/Photo.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash.data.model;\n\nimport android.os.Parcel;\nimport android.os.Parcelable;\nimport android.support.annotation.NonNull;\n\nimport java.util.Locale;\n\n/**\n * Model class representing data returned from unsplash.it\n */\npublic class Photo implements Parcelable {\n\n    /*{\n        \"format\": \"jpeg\",\n        \"width\": 5616,\n        \"height\": 3744,\n        \"filename\": \"0000_yC-Yzbqy7PY.jpeg\",\n        \"id\": 0,\n        \"author\": \"Alejandro Escamilla\",\n        \"author_url\": \"https://unsplash.com/alejandroescamilla\",\n        \"post_url\": \"https://unsplash.com/photos/yC-Yzbqy7PY\"\n    }*/\n\n    public final String format;\n    public final int width;\n    public final int height;\n    public final String filename;\n    public final long id;\n    public final String author;\n    public final String author_url;\n    public final String post_url;\n\n    private static final String PHOTO_URL_BASE = \"https://unsplash.it/%d?image=%d\";\n\n    public Photo(String format,\n                 int width,\n                 int height,\n                 String filename,\n                 long id,\n                 String author,\n                 String author_url,\n                 String post_url) {\n        this.format = format;\n        this.width = width;\n        this.height = height;\n        this.filename = filename;\n        this.id = id;\n        this.author = author;\n        this.author_url = author_url;\n        this.post_url = post_url;\n    }\n\n    protected Photo(Parcel in) {\n        format = in.readString();\n        width = in.readInt();\n        height = in.readInt();\n        filename = in.readString();\n        id = in.readLong();\n        author = in.readString();\n        author_url = in.readString();\n        post_url = in.readString();\n    }\n\n    public String getPhotoUrl(int requestWidth) {\n        return String.format(Locale.getDefault(), PHOTO_URL_BASE, requestWidth, id);\n    }\n\n    @Override\n    public int describeContents() {\n        return 0;\n    }\n\n    @Override\n    public void writeToParcel(@NonNull Parcel dest, int flags) {\n        dest.writeString(format);\n        dest.writeInt(width);\n        dest.writeInt(height);\n        dest.writeString(filename);\n        dest.writeLong(id);\n        dest.writeString(author);\n        dest.writeString(author_url);\n        dest.writeString(post_url);\n    }\n\n    public static final Creator<Photo> CREATOR = new Creator<Photo>() {\n        @Override\n        public Photo createFromParcel(Parcel in) {\n            return new Photo(in);\n        }\n\n        @Override\n        public Photo[] newArray(int size) {\n            return new Photo[size];\n        }\n    };\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/test.kt",
    "content": "package com.example.android.unsplash\n\nimport android.util.Log\n\n/**\n * Created by lilong on 18/2/1.\n * */\n\nclass test {\n\n    var str: String = \"\"\n\n    fun main(args: Array<String>) {\n        str = \"Hello World!\"\n        Log.d(str, str)\n    }\n}"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/transition/TextResize.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash.transition;\n\nimport android.animation.Animator;\nimport android.animation.AnimatorListenerAdapter;\nimport android.animation.ArgbEvaluator;\nimport android.animation.ObjectAnimator;\nimport android.animation.PropertyValuesHolder;\nimport android.content.Context;\nimport android.content.res.ColorStateList;\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.ColorFilter;\nimport android.graphics.Paint;\nimport android.graphics.PixelFormat;\nimport android.graphics.PorterDuff;\nimport android.graphics.drawable.Drawable;\nimport android.transition.Transition;\nimport android.transition.TransitionValues;\nimport android.util.AttributeSet;\nimport android.util.TypedValue;\nimport android.view.Gravity;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.TextView;\n\n/**\n * Transitions a TextView from one font size to another. This does not\n * do any animation of TextView content and if the text changes, this\n * transition will not run.\n * <p>\n * The animation works by capturing a bitmap of the text at the start\n * and end states. It then scales the start bitmap until it reaches\n * a threshold and switches to the scaled end bitmap for the remainder\n * of the animation. This keeps the jump in bitmaps in the middle of\n * the animation, where it is less noticeable than at the beginning\n * or end of the animation. This transition does not work well with\n * cropped text. TextResize also does not work with changes in\n * TextView gravity.\n */\npublic class TextResize extends Transition {\n    private static final String FONT_SIZE = \"TextResize:fontSize\";\n    private static final String DATA = \"TextResize:data\";\n\n    private static final String[] PROPERTIES = {\n            // We only care about FONT_SIZE. If anything else changes, we don't\n            // want this transition to be called to create an Animator.\n            FONT_SIZE,\n    };\n\n    public TextResize() {\n        addTarget(TextView.class);\n    }\n\n    /**\n     * Constructor used from XML.\n     */\n    public TextResize(Context context, AttributeSet attrs) {\n        super(context, attrs);\n        addTarget(TextView.class);\n    }\n\n    @Override\n    public String[] getTransitionProperties() {\n        return PROPERTIES;\n    }\n\n    @Override\n    public void captureStartValues(TransitionValues transitionValues) {\n        captureValues(transitionValues);\n    }\n\n    @Override\n    public void captureEndValues(TransitionValues transitionValues) {\n        captureValues(transitionValues);\n    }\n\n    private void captureValues(TransitionValues transitionValues) {\n        if (!(transitionValues.view instanceof TextView)) {\n            return;\n        }\n        final TextView view = (TextView) transitionValues.view;\n        final float fontSize = view.getTextSize();\n        transitionValues.values.put(FONT_SIZE, fontSize);\n        final TextResizeData data = new TextResizeData(view);\n        transitionValues.values.put(DATA, data);\n    }\n\n    @Override\n    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,\n                                   TransitionValues endValues) {\n        if (startValues == null || endValues == null) {\n            return null;\n        }\n\n        final TextResizeData startData = (TextResizeData) startValues.values.get(DATA);\n        final TextResizeData endData = (TextResizeData) endValues.values.get(DATA);\n        if (startData.gravity != endData.gravity) {\n            return null; // Can't deal with changes in gravity\n        }\n\n        final TextView textView = (TextView) endValues.view;\n        float startFontSize = (Float) startValues.values.get(FONT_SIZE);\n        // Capture the start bitmap -- we need to set the values to the start values first\n        setTextViewData(textView, startData, startFontSize);\n        final float startWidth = textView.getPaint().measureText(textView.getText().toString());\n\n        final Bitmap startBitmap = captureTextBitmap(textView);\n\n        if (startBitmap == null) {\n            startFontSize = 0;\n        }\n\n        float endFontSize = (Float) endValues.values.get(FONT_SIZE);\n\n        // Set the values to the end values\n        setTextViewData(textView, endData, endFontSize);\n\n        final float endWidth = textView.getPaint().measureText(textView.getText().toString());\n\n        // Capture the end bitmap\n        final Bitmap endBitmap = captureTextBitmap(textView);\n        if (endBitmap == null) {\n            endFontSize = 0;\n        }\n\n        if (startFontSize == 0 && endFontSize == 0) {\n            return null; // Can't animate null bitmaps\n        }\n\n        // Set the colors of the TextView so that nothing is drawn.\n        // Only draw the bitmaps in the overlay.\n        final ColorStateList textColors = textView.getTextColors();\n        final ColorStateList hintColors = textView.getHintTextColors();\n        final int highlightColor = textView.getHighlightColor();\n        final ColorStateList linkColors = textView.getLinkTextColors();\n        textView.setTextColor(Color.TRANSPARENT);\n        textView.setHintTextColor(Color.TRANSPARENT);\n        textView.setHighlightColor(Color.TRANSPARENT);\n        textView.setLinkTextColor(Color.TRANSPARENT);\n\n        // Create the drawable that will be animated in the TextView's overlay.\n        // Ensure that it is showing the start state now.\n        final SwitchBitmapDrawable drawable = new SwitchBitmapDrawable(textView, startData.gravity,\n                startBitmap, startFontSize, startWidth, endBitmap, endFontSize, endWidth);\n        textView.getOverlay().add(drawable);\n\n        // Properties: left, top, font size, text color\n        final PropertyValuesHolder leftProp =\n                PropertyValuesHolder.ofFloat(\"left\", startData.paddingLeft, endData.paddingLeft);\n        final PropertyValuesHolder topProp =\n                PropertyValuesHolder.ofFloat(\"top\", startData.paddingTop, endData.paddingTop);\n        final PropertyValuesHolder rightProp = PropertyValuesHolder.ofFloat(\"right\",\n                startData.width - startData.paddingRight, endData.width - endData.paddingRight);\n        final PropertyValuesHolder bottomProp = PropertyValuesHolder.ofFloat(\"bottom\",\n                startData.height - startData.paddingBottom, endData.height - endData.paddingBottom);\n        final PropertyValuesHolder fontSizeProp =\n                PropertyValuesHolder.ofFloat(\"fontSize\", startFontSize, endFontSize);\n        final ObjectAnimator animator;\n        if (startData.textColor != endData.textColor) {\n            final PropertyValuesHolder textColorProp = PropertyValuesHolder.ofObject(\"textColor\",\n                    new ArgbEvaluator(), startData.textColor, endData.textColor);\n            animator = ObjectAnimator.ofPropertyValuesHolder(drawable,\n                    leftProp, topProp, rightProp, bottomProp, fontSizeProp, textColorProp);\n        } else {\n            animator = ObjectAnimator.ofPropertyValuesHolder(drawable,\n                    leftProp, topProp, rightProp, bottomProp, fontSizeProp);\n        }\n\n        final float finalFontSize = endFontSize;\n        AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {\n            @Override\n            public void onAnimationEnd(Animator animation) {\n                textView.getOverlay().remove(drawable);\n                textView.setTextColor(textColors);\n                textView.setHintTextColor(hintColors);\n                textView.setHighlightColor(highlightColor);\n                textView.setLinkTextColor(linkColors);\n            }\n\n            @Override\n            public void onAnimationPause(Animator animation) {\n                textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, drawable.getFontSize());\n                final int paddingLeft = Math.round(drawable.getLeft());\n                final int paddingTop = Math.round(drawable.getTop());\n                final float fraction = animator.getAnimatedFraction();\n                final int paddingRight = Math.round(interpolate(startData.paddingRight,\n                        endData.paddingRight, fraction));\n                final int paddingBottom = Math.round(interpolate(startData.paddingBottom,\n                        endData.paddingBottom, fraction));\n                textView.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);\n                textView.setTextColor(drawable.getTextColor());\n            }\n\n            @Override\n            public void onAnimationResume(Animator animation) {\n                textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, finalFontSize);\n                textView.setPadding(endData.paddingLeft, endData.paddingTop,\n                        endData.paddingRight, endData.paddingBottom);\n                textView.setTextColor(endData.textColor);\n            }\n        };\n        animator.addListener(listener);\n        animator.addPauseListener(listener);\n        return animator;\n    }\n\n    private static void setTextViewData(TextView view, TextResizeData data, float fontSize) {\n        view.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize);\n        view.setPadding(data.paddingLeft, data.paddingTop, data.paddingRight, data.paddingBottom);\n        view.setRight(view.getLeft() + data.width);\n        view.setBottom(view.getTop() + data.height);\n        view.setTextColor(data.textColor);\n        int widthSpec = View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY);\n        int heightSpec = View.MeasureSpec.makeMeasureSpec(view.getHeight(), View.MeasureSpec.EXACTLY);\n        view.measure(widthSpec, heightSpec);\n        view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());\n    }\n\n    private static Bitmap captureTextBitmap(TextView textView) {\n        Drawable background = textView.getBackground();\n        textView.setBackground(null);\n        int width = textView.getWidth() - textView.getPaddingLeft() - textView.getPaddingRight();\n        int height = textView.getHeight() - textView.getPaddingTop() - textView.getPaddingBottom();\n        if (width == 0 || height == 0) {\n            return null;\n        }\n        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);\n        Canvas canvas = new Canvas(bitmap);\n        canvas.translate(-textView.getPaddingLeft(), -textView.getPaddingTop());\n        textView.draw(canvas);\n        textView.setBackground(background);\n        return bitmap;\n    }\n\n    private static float interpolate(float start, float end, float fraction) {\n        return start + (fraction * (end - start));\n    }\n\n    /**\n     * This Drawable is used to scale the start and end bitmaps and switch between them\n     * at the appropriate progress.\n     */\n    private static class SwitchBitmapDrawable extends Drawable {\n        private final TextView view;\n        private final int horizontalGravity;\n        private final int verticalGravity;\n        private final Bitmap startBitmap;\n        private final Bitmap endBitmap;\n        private final Paint paint = new Paint();\n        private final float startFontSize;\n        private final float endFontSize;\n        private final float startWidth;\n        private final float endWidth;\n        private float fontSize;\n        private float left;\n        private float top;\n        private float right;\n        private float bottom;\n        private int textColor;\n\n        public SwitchBitmapDrawable(TextView view, int gravity,\n                                    Bitmap startBitmap, float startFontSize, float startWidth,\n                                    Bitmap endBitmap, float endFontSize, float endWidth) {\n            this.view = view;\n            this.horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;\n            this.verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;\n            this.startBitmap = startBitmap;\n            this.endBitmap = endBitmap;\n            this.startFontSize = startFontSize;\n            this.endFontSize = endFontSize;\n            this.startWidth = startWidth;\n            this.endWidth = endWidth;\n        }\n\n        @Override\n        public void invalidateSelf() {\n            super.invalidateSelf();\n            view.invalidate();\n        }\n\n        /**\n         * Sets the font size that the text should be displayed at.\n         *\n         * @param fontSize The font size in pixels of the scaled bitmap text.\n         */\n        public void setFontSize(float fontSize) {\n            this.fontSize = fontSize;\n            invalidateSelf();\n        }\n\n        /**\n         * Sets the color of the text to be displayed.\n         *\n         * @param textColor The color of the text to be displayed.\n         */\n        public void setTextColor(int textColor) {\n            this.textColor = textColor;\n            setColorFilter(textColor, PorterDuff.Mode.SRC_IN);\n            invalidateSelf();\n        }\n\n        /**\n         * Sets the left side of the text. This should be the same as the left padding.\n         *\n         * @param left The left side of the text in pixels.\n         */\n        public void setLeft(float left) {\n            this.left = left;\n            invalidateSelf();\n        }\n\n        /**\n         * Sets the top of the text. This should be the same as the top padding.\n         *\n         * @param top The top of the text in pixels.\n         */\n        public void setTop(float top) {\n            this.top = top;\n            invalidateSelf();\n        }\n\n        /**\n         * Sets the right of the drawable.\n         *\n         * @param right The right pixel of the drawn area.\n         */\n        public void setRight(float right) {\n            this.right = right;\n            invalidateSelf();\n        }\n\n        /**\n         * Sets the bottom of the drawable.\n         *\n         * @param bottom The bottom pixel of the drawn area.\n         */\n        public void setBottom(float bottom) {\n            this.bottom = bottom;\n            invalidateSelf();\n        }\n\n        /**\n         * @return The left side of the text.\n         */\n        public float getLeft() {\n            return left;\n        }\n\n        /**\n         * @return The top of the text.\n         */\n        public float getTop() {\n            return top;\n        }\n\n        /**\n         * @return The right side of the text.\n         */\n        public float getRight() {\n            return right;\n        }\n\n        /**\n         * @return The bottom of the text.\n         */\n        public float getBottom() {\n            return bottom;\n        }\n\n        /**\n         * @return The font size of the text in the displayed bitmap.\n         */\n        public float getFontSize() {\n            return fontSize;\n        }\n\n        /**\n         * @return The color of the text being displayed.\n         */\n        public int getTextColor() {\n            return textColor;\n        }\n\n        @Override\n        public void draw(Canvas canvas) {\n            int saveCount = canvas.save();\n            // The threshold changes depending on the target font sizes. Because scaled-up\n            // fonts look bad, we want to switch when closer to the smaller font size. This\n            // algorithm ensures that null bitmaps (font size = 0) are never used.\n            final float threshold = startFontSize / (startFontSize + endFontSize);\n            final float fontSize = getFontSize();\n            final float progress = (fontSize - startFontSize)/(endFontSize - startFontSize);\n\n            // The drawn text width is a more accurate scale than font size. This avoids\n            // jump when switching bitmaps.\n            final float expectedWidth = interpolate(startWidth, endWidth, progress);\n            if (progress < threshold) {\n                // draw start bitmap\n                final float scale = expectedWidth / startWidth;\n                float tx = getTranslationPoint(horizontalGravity, left, right,\n                        startBitmap.getWidth(), scale);\n                float ty = getTranslationPoint(verticalGravity, top, bottom,\n                        startBitmap.getHeight(), scale);\n                canvas.translate(tx, ty);\n                canvas.scale(scale, scale);\n                canvas.drawBitmap(startBitmap, 0, 0, paint);\n            } else {\n                // draw end bitmap\n                final float scale = expectedWidth / endWidth;\n                float tx = getTranslationPoint(horizontalGravity, left, right,\n                        endBitmap.getWidth(), scale);\n                float ty = getTranslationPoint(verticalGravity, top, bottom,\n                        endBitmap.getHeight(), scale);\n                canvas.translate(tx, ty);\n                canvas.scale(scale, scale);\n                canvas.drawBitmap(endBitmap, 0, 0, paint);\n            }\n            canvas.restoreToCount(saveCount);\n        }\n\n        @Override\n        public void setAlpha(int alpha) {\n        }\n\n        @Override\n        public void setColorFilter(ColorFilter colorFilter) {\n            paint.setColorFilter(colorFilter);\n        }\n\n        @Override\n        public int getOpacity() {\n            return PixelFormat.TRANSLUCENT;\n        }\n\n        private float getTranslationPoint(int gravity, float start, float end, float dim,\n                                          float scale) {\n            switch (gravity) {\n                case Gravity.CENTER_HORIZONTAL:\n                case Gravity.CENTER_VERTICAL:\n                    return ((start + end) - (dim * scale))/2f;\n                case Gravity.RIGHT:\n                case Gravity.BOTTOM:\n                    return end - (dim * scale);\n                case Gravity.LEFT:\n                case Gravity.TOP:\n                default:\n                    return start;\n            }\n        }\n    }\n\n    /**\n     * Contains all the non-font-size data used by the TextResize transition.\n     * None of these values should trigger the transition, so they are not listed\n     * in PROPERTIES. These are captured together to avoid boxing of all the\n     * primitives while adding to TransitionValues.\n     */\n    static class TextResizeData {\n        public final int paddingLeft;\n        public final int paddingTop;\n        public final int paddingRight;\n        public final int paddingBottom;\n        public final int width;\n        public final int height;\n        public final int gravity;\n        public final int textColor;\n\n        public TextResizeData(TextView textView) {\n            this.paddingLeft = textView.getPaddingLeft();\n            this.paddingTop = textView.getPaddingTop();\n            this.paddingRight = textView.getPaddingRight();\n            this.paddingBottom = textView.getPaddingBottom();\n            this.width = textView.getWidth();\n            this.height = textView.getHeight();\n            this.gravity = textView.getGravity();\n            this.textColor = textView.getCurrentTextColor();\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/ui/DetailSharedElementEnterCallback.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash.ui;\n\nimport android.app.SharedElementCallback;\nimport android.content.Intent;\nimport android.content.res.ColorStateList;\nimport android.graphics.Color;\nimport android.graphics.Rect;\nimport android.support.annotation.NonNull;\nimport android.support.v7.view.menu.MenuView;\nimport android.util.TypedValue;\nimport android.view.View;\nimport android.widget.ImageView;\nimport android.widget.TextView;\n\nimport com.example.android.unsplash.base.R;\nimport com.example.android.unsplash.IntentUtil;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\npublic class DetailSharedElementEnterCallback extends SharedElementCallback {\n\n    private final Intent intent;\n    private float targetTextSize;\n    private ColorStateList targetTextColors;\n    private View currentView;\n    private Rect targetPadding;\n\n    public DetailSharedElementEnterCallback(Intent intent) {\n        this.intent = intent;\n    }\n\n    @Override\n    public void onSharedElementStart(List<String> sharedElementNames,\n                                     List<View> sharedElements,\n                                     List<View> sharedElementSnapshots) {\n        TextView author = getAuthor();\n        targetTextSize = author.getTextSize();\n        targetTextColors = author.getTextColors();\n        targetPadding = new Rect(author.getPaddingLeft(),\n                author.getPaddingTop(),\n                author.getPaddingRight(),\n                author.getPaddingBottom());\n        if (IntentUtil.INSTANCE.hasAll(intent,\n                IntentUtil.INSTANCE.getTEXT_COLOR(), IntentUtil.INSTANCE.getFONT_SIZE(), IntentUtil.INSTANCE.getPADDING())) {\n            author.setTextColor(intent.getIntExtra(IntentUtil.INSTANCE.getTEXT_COLOR(), Color.BLACK));\n            float textSize = intent.getFloatExtra(IntentUtil.INSTANCE.getFONT_SIZE(), targetTextSize);\n            author.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);\n            Rect padding = intent.getParcelableExtra(IntentUtil.INSTANCE.getPADDING());\n            author.setPadding(padding.left, padding.top, padding.right, padding.bottom);\n        }\n    }\n\n    @Override\n    public void onSharedElementEnd(List<String> sharedElementNames,\n                                   List<View> sharedElements,\n                                   List<View> sharedElementSnapshots) {\n        TextView author = getAuthor();\n        author.setTextSize(TypedValue.COMPLEX_UNIT_PX, targetTextSize);\n        if (targetTextColors != null) {\n            author.setTextColor(targetTextColors);\n        }\n        if (targetPadding != null) {\n            author.setPadding(targetPadding.left, targetPadding.top,\n                    targetPadding.right, targetPadding.bottom);\n        }\n        if (currentView != null) {\n            View descView = currentView.findViewById(R.id.description);\n            if (descView != null) {\n                forceSharedElementLayout(descView);\n            }\n        }\n    }\n\n    @Override\n    public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {\n        removeObsoleteElements(names, sharedElements, mapObsoleteElements(names));\n        mapSharedElement(names, sharedElements, getAuthor());\n        mapSharedElement(names, sharedElements, getPhoto());\n    }\n\n    public void setView(@NonNull View view) {\n        currentView = view;\n    }\n\n    private TextView getAuthor() {\n        if (currentView != null) {\n            return currentView.findViewById(R.id.author);\n        } else {\n            throw new NullPointerException(\"Must set a binding before transitioning.\");\n        }\n    }\n\n    private ImageView getPhoto() {\n        if (currentView != null) {\n            return currentView.findViewById(R.id.photo);\n        } else {\n            throw new NullPointerException(\"Must set a binding before transitioning.\");\n        }\n    }\n\n    /**\n     * Maps all views that don't start with \"android\" namespace.\n     *\n     * @param names All shared element names.\n     * @return The obsolete shared element names.\n     */\n    @NonNull\n    private List<String> mapObsoleteElements(List<String> names) {\n        List<String> elementsToRemove = new ArrayList<>(names.size());\n        for (String name : names) {\n            if (name.startsWith(\"android\")) continue;\n            elementsToRemove.add(name);\n        }\n        return elementsToRemove;\n    }\n\n    /**\n     * Removes obsolete elements from names and shared elements.\n     *\n     * @param names Shared element names.\n     * @param sharedElements Shared elements.\n     * @param elementsToRemove The elements that should be removed.\n     */\n    private void removeObsoleteElements(List<String> names,\n                                        Map<String, View> sharedElements,\n                                        List<String> elementsToRemove) {\n        if (elementsToRemove.size() > 0) {\n            names.removeAll(elementsToRemove);\n            for (String elementToRemove : elementsToRemove) {\n                sharedElements.remove(elementToRemove);\n            }\n        }\n    }\n\n    /**\n     * Puts a shared element to transitions and names.\n     *\n     * @param names The names for this transition.\n     * @param sharedElements The elements for this transition.\n     * @param view The view to add.\n     */\n    private void mapSharedElement(List<String> names, Map<String, View> sharedElements, View view) {\n        String transitionName = view.getTransitionName();\n        names.add(transitionName);\n        sharedElements.put(transitionName, view);\n    }\n\n    private void forceSharedElementLayout(View view) {\n        int widthSpec = View.MeasureSpec.makeMeasureSpec(view.getWidth(),\n                View.MeasureSpec.EXACTLY);\n        int heightSpec = View.MeasureSpec.makeMeasureSpec(view.getHeight(),\n                View.MeasureSpec.EXACTLY);\n        view.measure(widthSpec, heightSpec);\n        view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());\n    }\n\n}"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/ui/ForegroundImageView.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash.ui;\n\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport android.graphics.Canvas;\nimport android.graphics.drawable.Drawable;\nimport android.util.AttributeSet;\nimport android.view.ViewOutlineProvider;\nimport android.widget.ImageView;\n\nimport com.example.android.unsplash.base.R;\n\n\npublic class ForegroundImageView extends ImageView {\n\n    private Drawable foreground;\n\n    public ForegroundImageView(Context context, AttributeSet attrs) {\n        super(context, attrs);\n\n        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ForegroundView);\n\n        final Drawable d = a.getDrawable(R.styleable.ForegroundView_android_foreground);\n        if (d != null) {\n            setForeground(d);\n        }\n        a.recycle();\n        setOutlineProvider(ViewOutlineProvider.BOUNDS);\n    }\n\n    @Override\n    protected void onSizeChanged(int w, int h, int oldw, int oldh) {\n        super.onSizeChanged(w, h, oldw, oldh);\n        if (foreground != null) {\n            foreground.setBounds(0, 0, w, h);\n        }\n    }\n\n    @Override\n    public boolean hasOverlappingRendering() {\n        return false;\n    }\n\n    @Override\n    protected boolean verifyDrawable(Drawable who) {\n        return super.verifyDrawable(who) || (who == foreground);\n    }\n\n    @Override\n    public void jumpDrawablesToCurrentState() {\n        super.jumpDrawablesToCurrentState();\n        if (foreground != null) foreground.jumpToCurrentState();\n    }\n\n    @Override\n    protected void drawableStateChanged() {\n        super.drawableStateChanged();\n        if (foreground != null && foreground.isStateful()) {\n            foreground.setState(getDrawableState());\n        }\n    }\n\n    /**\n     * Returns the drawable used as the foreground of this view. The\n     * foreground drawable, if non-null, is always drawn on top of the children.\n     *\n     * @return A Drawable or null if no foreground was set.\n     */\n    public Drawable getForeground() {\n        return foreground;\n    }\n\n    /**\n     * Supply a Drawable that is to be rendered on top of the contents of this ImageView\n     *\n     * @param drawable The Drawable to be drawn on top of the ImageView\n     */\n    public void setForeground(Drawable drawable) {\n        if (foreground != drawable) {\n            if (foreground != null) {\n                foreground.setCallback(null);\n                unscheduleDrawable(foreground);\n            }\n\n            foreground = drawable;\n\n            if (foreground != null) {\n                foreground.setBounds(0, 0, getWidth(), getHeight());\n                setWillNotDraw(false);\n                foreground.setCallback(this);\n                if (foreground.isStateful()) {\n                    foreground.setState(getDrawableState());\n                }\n            } else {\n                setWillNotDraw(true);\n            }\n            invalidate();\n        }\n    }\n\n    @Override\n    public void draw(Canvas canvas) {\n        super.draw(canvas);\n        if (foreground != null) {\n            foreground.draw(canvas);\n        }\n    }\n\n    @Override\n    public void drawableHotspotChanged(float x, float y) {\n        super.drawableHotspotChanged(x, y);\n        if (foreground != null) {\n            foreground.setHotspot(x, y);\n        }\n    }\n}\n\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/ui/ImageSize.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash.ui;\n\npublic class ImageSize {\n\n    public static final int[] NORMAL = new int[] {480, 400};\n    public static final int[] LARGE = new int[] {960, 800};\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/ui/ThreeTwoImageView.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash.ui;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\n\npublic class ThreeTwoImageView extends ForegroundImageView {\n\n    public ThreeTwoImageView(Context context, AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    @Override\n    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {\n        int width = MeasureSpec.getSize(widthMeasureSpec);\n        int desiredHeight = width * 2 / 3;\n        super.onMeasure(widthMeasureSpec,\n                MeasureSpec.makeMeasureSpec(desiredHeight, MeasureSpec.EXACTLY));\n    }\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/ui/TransitionCallback.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash.ui;\n\nimport android.transition.Transition;\n\n/**\n * Dummy implementations of TransitionListener methods.\n */\npublic abstract class TransitionCallback implements Transition.TransitionListener {\n\n    @Override\n    public void onTransitionStart(Transition transition) {\n        // no-op\n    }\n\n    @Override\n    public void onTransitionEnd(Transition transition) {\n        // no-op\n    }\n\n    @Override\n    public void onTransitionCancel(Transition transition) {\n        // no-op\n    }\n\n    @Override\n    public void onTransitionPause(Transition transition) {\n        // no-op\n    }\n\n    @Override\n    public void onTransitionResume(Transition transition) {\n        // no-op\n    }\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/ui/grid/GridMarginDecoration.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash.ui.grid;\n\nimport android.graphics.Rect;\nimport android.support.v7.widget.RecyclerView;\nimport android.view.View;\n\npublic class GridMarginDecoration extends RecyclerView.ItemDecoration {\n\n    private int space;\n\n    public GridMarginDecoration(int space) {\n        this.space = space;\n    }\n\n    @Override\n    public void getItemOffsets(Rect outRect, View view,\n                               RecyclerView parent, RecyclerView.State state) {\n        outRect.left = space;\n        outRect.top = space;\n        outRect.right = space;\n        outRect.bottom = space;\n    }\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/ui/grid/OnItemSelectedListener.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash.ui.grid;\n\nimport android.content.Context;\nimport android.support.v7.widget.RecyclerView;\nimport android.view.GestureDetector;\nimport android.view.MotionEvent;\nimport android.view.View;\n\npublic abstract class OnItemSelectedListener implements RecyclerView.OnItemTouchListener {\n\n    private final GestureDetector gestureDetector;\n\n    public OnItemSelectedListener(Context context) {\n        gestureDetector = new GestureDetector(context,\n                new GestureDetector.SimpleOnGestureListener() {\n                    @Override\n                    public boolean onSingleTapUp(MotionEvent e) {\n                        return true;\n                    }\n                });\n    }\n\n    public abstract void onItemSelected(RecyclerView.ViewHolder holder, int position);\n\n    @Override\n    public final boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {\n        if (gestureDetector.onTouchEvent(e)) {\n            View touchedView = rv.findChildViewUnder(e.getX(), e.getY());\n            onItemSelected(rv.findContainingViewHolder(touchedView),\n                    rv.getChildAdapterPosition(touchedView));\n        }\n        return false;\n    }\n\n\n\n    @Override\n    public final void onTouchEvent(RecyclerView rv, MotionEvent e) {\n        throw new UnsupportedOperationException(\"Not implemented\");\n    }\n\n    @Override\n    public final void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {\n        throw new UnsupportedOperationException(\"Not implemented\");\n    }\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/ui/grid/PhotoAdapter.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash.ui.grid;\n\nimport android.content.Context;\nimport android.support.annotation.NonNull;\nimport android.support.v7.widget.RecyclerView;\nimport android.view.LayoutInflater;\nimport android.view.ViewGroup;\nimport android.widget.ImageView;\nimport android.widget.TextView;\n\nimport com.bumptech.glide.Glide;\nimport com.example.android.unsplash.data.model.Photo;\nimport com.example.android.unsplash.base.R;\nimport com.example.android.unsplash.ui.ImageSize;\n\nimport java.util.ArrayList;\n\npublic class PhotoAdapter extends RecyclerView.Adapter<PhotoViewHolder> {\n\n    private final ArrayList<Photo> photos;\n    private final int requestedPhotoWidth;\n    private final LayoutInflater layoutInflater;\n    private final String authorTransitionFormat;\n    private final String photoTransitionFormat;\n\n    public PhotoAdapter(@NonNull Context context, @NonNull ArrayList<Photo> photos) {\n        this.photos = photos;\n        requestedPhotoWidth = context.getResources().getDisplayMetrics().widthPixels;\n        authorTransitionFormat = context.getResources().getString(R.string.transition_author);\n        photoTransitionFormat = context.getResources().getString(R.string.transition_photo);\n        layoutInflater = LayoutInflater.from(context);\n    }\n\n    @Override\n    public PhotoViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {\n        return new PhotoViewHolder(layoutInflater.inflate(R.layout.photo_item, parent, false));\n    }\n\n    @Override\n    public void onBindViewHolder(final PhotoViewHolder holder, final int position) {\n        Photo data = photos.get(position);\n        TextView authorview = holder.itemView.findViewById(R.id.author);\n        ImageView photoview = holder.itemView.findViewById(R.id.photo);\n        holder.setAuthor(data.author);\n        photoview.setTransitionName(String.format(photoTransitionFormat, data.id));\n        authorview.setText(data.author);\n        authorview.setTransitionName(String.format(authorTransitionFormat, data.id));\n        holder.setId(data.id);\n        Glide.with(layoutInflater.getContext())\n                .load(data.getPhotoUrl(requestedPhotoWidth))\n                .placeholder(R.color.placeholder)\n                .override(ImageSize.NORMAL[0], ImageSize.NORMAL[1])\n                .into((ImageView) holder.itemView.findViewById(R.id.photo));\n    }\n\n    @Override\n    public int getItemCount() {\n        return photos.size();\n    }\n\n    @Override\n    public long getItemId(int position) {\n        return photos.get(position).id;\n    }\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/ui/grid/PhotoViewHolder.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash.ui.grid;\n\nimport android.support.v7.widget.RecyclerView;\nimport android.view.View;\n\nimport com.example.android.unsplash.data.model.Photo;\n\npublic class PhotoViewHolder extends RecyclerView.ViewHolder {\n\n    private String author;\n    private long id;\n\n    public PhotoViewHolder(View view, Photo photo) {\n        super(view);\n        author = photo.author;\n        id = photo.id;\n    }\n\n    public PhotoViewHolder(View view) {\n        super(view);\n        author = \"\";\n        id = 0;\n    }\n\n    public String getAuthor() {\n        return author;\n    }\n\n    public void setAuthor(String author) {\n        this.author = author;\n    }\n\n    public long getId() {\n        return id;\n    }\n\n    public void setId(long id) {\n        this.id = id;\n    }\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/java/com/example/android/unsplash/ui/pager/DetailViewPagerAdapter.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash.ui.pager;\n\nimport android.app.Activity;\nimport android.support.annotation.NonNull;\nimport android.support.v4.view.PagerAdapter;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.ImageView;\nimport android.widget.TextView;\n\nimport com.bumptech.glide.Glide;\nimport com.example.android.unsplash.base.R;\nimport com.example.android.unsplash.data.model.Photo;\nimport com.example.android.unsplash.ui.DetailSharedElementEnterCallback;\nimport com.example.android.unsplash.ui.ImageSize;\nimport com.example.android.unsplash.ui.ThreeTwoImageView;\n\nimport java.util.List;\n\n/**\n * Adapter for paging detail views.\n */\n\npublic class DetailViewPagerAdapter extends PagerAdapter {\n\n    private final List<Photo> allPhotos;\n    private final LayoutInflater layoutInflater;\n    private final int photoWidth;\n    private final Activity host;\n    private DetailSharedElementEnterCallback sharedElementCallback;\n    private final String authorTransitionFormat;\n    private final String photoTransitionFormat;\n\n    public DetailViewPagerAdapter(@NonNull Activity activity, @NonNull List<Photo> photos,\n                                  @NonNull DetailSharedElementEnterCallback callback) {\n        layoutInflater = LayoutInflater.from(activity);\n        allPhotos = photos;\n        photoWidth = activity.getResources().getDisplayMetrics().widthPixels;\n        host = activity;\n        sharedElementCallback = callback;\n        authorTransitionFormat = activity.getResources().getString(R.string.transition_author);\n        photoTransitionFormat = activity.getResources().getString(R.string.transition_photo);\n    }\n\n    @Override\n    public int getCount() {\n        return allPhotos.size();\n    }\n\n    @Override\n    public Object instantiateItem(ViewGroup container, int position) {\n        View view = layoutInflater.inflate(R.layout.detail_view, container, false);\n        ThreeTwoImageView photoview = view.findViewById(R.id.photo);\n        TextView authorview = view.findViewById(R.id.author);\n        Photo photo = allPhotos.get(position);\n        photoview.setTransitionName(String.format(photoTransitionFormat, photo.id));\n        authorview.setText(photo.author);\n        authorview.setTransitionName(String.format(authorTransitionFormat, photo.id));\n        onViewBound(photoview, photo);\n        container.addView(view);\n        return view;\n    }\n\n    private void onViewBound(ImageView imageView, Photo photo) {\n        Glide.with(host)\n                .load(photo.getPhotoUrl(photoWidth))\n                .placeholder(R.color.placeholder)\n                .override(ImageSize.NORMAL[0], ImageSize.NORMAL[1])\n                .into(imageView);\n    }\n\n    @Override\n    public void setPrimaryItem(ViewGroup container, int position, Object object) {\n        if (object instanceof View) {\n            int widthSpec = View.MeasureSpec.makeMeasureSpec(((View) object).getWidth(),\n                    View.MeasureSpec.EXACTLY);\n            int heightSpec = View.MeasureSpec.makeMeasureSpec(((View) object).getHeight(),\n                    View.MeasureSpec.EXACTLY);\n            ((View) object).measure(widthSpec, heightSpec);\n            sharedElementCallback.setView((View) object);\n        }\n    }\n\n    @Override\n    public boolean isViewFromObject(View view, Object object) {\n        return view.equals(object);\n    }\n\n    @Override\n    public void destroyItem(ViewGroup container, int position, Object object) {\n        container.removeView((View) object);\n    }\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/res/animator/raise.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item\n        android:state_enabled=\"true\"\n        android:state_pressed=\"true\">\n        <objectAnimator\n            android:duration=\"@android:integer/config_shortAnimTime\"\n            android:propertyName=\"translationZ\"\n            android:valueTo=\"6dp\" />\n    </item>\n    <item>\n        <objectAnimator\n            android:duration=\"@android:integer/config_shortAnimTime\"\n            android:propertyName=\"translationZ\"\n            android:valueTo=\"0dp\" />\n    </item>\n</selector>"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/res/drawable/grey_ripple.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<ripple\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:color=\"@color/grey_ripple\" />"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/res/drawable/ic_arrow_back.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"48\"\n        android:viewportHeight=\"48\">\n    <path\n        android:pathData=\"M40,22H15.7l11.2-11.2L24,8L8,24l16,16l2.8-2.8L15.7,26H40V22z\"\n        android:fillColor=\"@android:color/white\"/>\n</vector>\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/res/layout/detail_view.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<ScrollView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:clipToPadding=\"false\"\n        android:orientation=\"vertical\"\n        android:paddingBottom=\"@dimen/padding_small\">\n\n        <com.example.android.unsplash.ui.ThreeTwoImageView\n            android:id=\"@+id/photo\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:scaleType=\"centerCrop\" />\n\n        <LinearLayout\n            android:id=\"@+id/description\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"vertical\"\n            android:transitionGroup=\"false\">\n\n            <TextView\n                android:id=\"@+id/author\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:paddingEnd=\"@dimen/padding_normal\"\n                android:paddingStart=\"@dimen/padding_normal\"\n                android:paddingTop=\"@dimen/padding_large\"\n                android:textAppearance=\"@android:style/TextAppearance.Material.Headline\"\n                android:textColor=\"?android:textColorPrimary\" />\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:lineSpacingMultiplier=\"1.26315789474\"\n                android:paddingEnd=\"@dimen/padding_normal\"\n                android:paddingStart=\"@dimen/padding_normal\"\n                android:paddingTop=\"@dimen/padding_normal\"\n                android:text=\"@string/lorum_ipsum\"\n                android:textAppearance=\"@android:style/TextAppearance.Material.Subhead\"\n                android:textColor=\"?android:textColorSecondary\" />\n\n        </LinearLayout>\n\n    </LinearLayout>\n\n</ScrollView>\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/res/layout/photo_item.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"@dimen/image_height\"\n    android:foreground=\"@drawable/grey_ripple\"\n    android:stateListAnimator=\"@animator/raise\"\n    android:transitionGroup=\"true\">\n\n    <ImageView\n        android:id=\"@+id/photo\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:scaleType=\"centerCrop\" />\n\n    <TextView\n        android:id=\"@+id/author\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom|end\"\n        android:background=\"@color/author_background\"\n        android:lines=\"1\"\n        android:paddingBottom=\"@dimen/padding_small\"\n        android:paddingEnd=\"@dimen/padding_normal\"\n        android:paddingStart=\"@dimen/padding_normal\"\n        android:paddingTop=\"@dimen/padding_small\"\n        android:textColor=\"@color/placeholder\" />\n</FrameLayout>\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/res/transition/grid_exit.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<explode />"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/res/transition/grid_reenter.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<slide\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:slideEdge=\"top\"\n    android:duration=\"300\"\n    android:interpolator=\"@android:interpolator/linear_out_slow_in\">\n</slide>\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/res/transition/shared_main_detail.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<transitionSet xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <transitionSet>\n        <targets>\n            <target android:targetId=\"@id/photo\" />\n        </targets>\n        <changeBounds>\n            <arcMotion android:maximumAngle=\"50\"/>\n        </changeBounds>\n        <changeTransform />\n        <changeClipBounds />\n        <changeImageTransform />\n    </transitionSet>\n    <transitionSet>\n        <targets>\n            <target android:targetId=\"@id/author\" />\n        </targets>\n        <transition class=\"com.example.android.unsplash.transition.TextResize\" />\n        <changeBounds />\n    </transitionSet>\n    <recolor>\n        <targets>\n            <target android:targetId=\"@android:id/statusBarBackground\" />\n            <target android:targetId=\"@android:id/navigationBarBackground\" />\n        </targets>\n    </recolor>\n</transitionSet>\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/res/values/attrs_foreground_view.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<resources>\n\n    <declare-styleable name=\"ForegroundView\">\n        <attr name=\"android:foreground\" />\n        <attr name=\"foregroundInsidePadding\" />\n        <attr name=\"android:foregroundGravity\" />\n    </declare-styleable>\n\n</resources>"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/res/values/colors.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<resources>\n\n    <color name=\"primary\">#00BCD4</color>\n    <!--<color name=\"primary_dark\">#00ACC1</color>-->\n    <color name=\"primary_dark\">#333</color>\n    <color name=\"accent\">#FFFF00</color>\n    <color name=\"placeholder\">#ddd</color>\n    <color name=\"grey_ripple\">#8ddd</color>\n    <color name=\"author_background\">#66000000</color>\n    <color name=\"page_margin\">#eee</color>\n\n</resources>"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/res/values/dimens.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<resources>\n    <dimen name=\"padding_mini\">4dp</dimen>\n    <dimen name=\"padding_small\">8dp</dimen>\n    <dimen name=\"padding_normal\">16dp</dimen>\n    <dimen name=\"padding_large\">24dp</dimen>\n    <dimen name=\"image_height\">200dp</dimen>\n    <dimen name=\"grid_item_spacing\">2dp</dimen>\n</resources>\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/res/values/ids.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<resources>\n    <item name=\"requestCode\" type=\"id\" />\n</resources>"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/res/values/strings.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<resources>\n    <string name=\"app_name\">Multi feature sample</string>\n    <string name=\"lorum_ipsum\">Artisan pickled freegan keytar High Life, roof party slow-carb Thundercats post-ironic. Bespoke sriracha taxidermy skateboard, yr PBRB jean shorts keytar post-ironic direct trade Banksy locavore selvage Vice four dollar toast. Wolf cardigan ugh gastropub. Pinterest Williamsburg Echo Park before they sold out tattooed. Tousled sriracha narwhal sustainable. Kale chips four dollar toast mumblecore gastropub Thundercats Brooklyn High Life, messenger bag tofu actually. Freegan drinking vinegar pug selfies gentrify.\\n\\nPolaroid photo booth Wes Anderson, wolf plaid tilde lo-fi. Godard Wes Anderson PBRB normcore. Pop-up mustache meh, wayfarers yr Odd Future food truck skateboard. Sriracha meggings next level VHS, gluten-free chia lumbersexual messenger bag art party Thundercats listicle. Pour-over heirloom cornhole direct trade fingerstache, disrupt Thundercats next level semiotics Banksy listicle narwhal Odd Future pork belly fixie. Squid Intelligentsia Bushwick disrupt direct trade +1, artisan photo booth meditation forage you probably haven\\'t heard of them cray. Salvia lo-fi scenester banh mi, Schlitz irony vegan XOXO fashion axe street art bicycle rights keytar polaroid disrupt farm-to-table.\\n\\nForage Thundercats vegan, whatever synth tote bag lomo wayfarers locavore drinking vinegar Odd Future YOLO you probably haven\\'t heard of them PBR. Shabby chic hella hoodie, lumbersexual keytar iPhone viral Vice gentrify seitan. You probably haven\\'t heard of them asymmetrical flannel, Pinterest fanny pack Wes Anderson readymade typewriter post-ironic single-origin coffee Shoreditch biodiesel leggings. Twee mumblecore lo-fi, synth lomo gluten-free McSweeney\\'s Pitchfork gastropub American Apparel. Gluten-free small batch tilde PBR occupy. Fashion axe yr meh, gentrify lo-fi chambray lomo drinking vinegar fap salvia irony tilde health goth trust fund. Authentic Intelligentsia YOLO, Blue Bottle McSweeney\\'s yr fashion axe butcher Williamsburg.\\n\\nSustainable actually fashion axe slow-carb, whatever Intelligentsia sartorial PBRB bespoke 90\\'s cold-pressed. Disrupt slow-carb church-key, Banksy four loko hashtag sartorial tote bag. Gastropub banh mi twee, four loko kogi distillery plaid yr. Fixie Neutra chillwave bicycle rights, readymade art party 90\\'s Bushwick salvia pickled McSweeney\\'s. XOXO gastropub tote bag, meggings Pinterest locavore roof party. Try-hard before they sold out mlkshk wayfarers pop-up Truffaut. Asymmetrical actually fixie, sartorial raw denim brunch mixtape.</string>\n    <string name=\"transition_photo\">transition_photo%1$d</string>\n    <string name=\"transition_author\">transition_author%1$d</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/base/src/main/res/values/styles.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<resources>\n\n    <style name=\"App\" parent=\"@android:style/Theme.Material.Light.NoActionBar\">\n        <item name=\"android:colorPrimary\">@color/primary</item>\n        <item name=\"android:colorPrimaryDark\">@color/primary_dark</item>\n        <item name=\"android:colorAccent\">@color/accent</item>\n    </style>\n\n    <style name=\"App.Detail\">\n        <item name=\"android:windowSharedElementEnterTransition\">\n            @transition/shared_main_detail\n        </item>\n    </style>\n\n    <style name=\"App.Home\">\n        <item name=\"android:windowExitTransition\">@transition/grid_exit</item>\n        <item name=\"android:windowReenterTransition\">@transition/grid_reenter</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/build.gradle",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\next {\n    buildTools = '27.0.2'\n    compileSdk = 27\n    targetSdk = 27\n    minSdk = 21\n    minSdkInstant = 21\n    versionCode = 1\n    versionName = \"1.0\"\n    supportLib = '27.0.1'\n    glide = \"3.7.0\"\n    retrofit = \"1.9.0\"\n\n    espressoVersion = \"3.0.1\"\n    androidTestVersion = \"1.0.1\"\n    hamcrestVersion = \"1.3\"\n}\n\nbuildscript {\n    repositories {\n        jcenter()\n        google()\n//        maven {\n//            url \"http://mvnrepo.alibaba-inc.com/mvn/repository\"\n//////            url \"http://maven.aliyun.com/nexus/content/groups/public\"\n//        }\n    }\n    dependencies {\n        classpath 'com.taobao.android:atlasplugin:3.0.1-rc21'\n\n    }\n}\nallprojects {\n    repositories {\n        google()\n        jcenter()\n//        maven {\n//            url \"http://mvnrepo.alibaba-inc.com/mvn/repository\"\n//////            url \"http://maven.aliyun.com/nexus/content/groups/public\"\n//        }\n    }\n\n//    configurations {\n//        compileProject.extendsFrom compile, archives\n//        runtimeProject.extendsFrom runtime, archives\n////        runtimeProjectOnly.extendsFrom compile,android-manifest\n//\n////        compileOnlyProject.extendsFrom compileOnly, archives\n//\n//    }\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/detail/build.gradle",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\napply plugin: 'com.taobao.atlas.feature'\n\nandroid {\n    compileSdkVersion rootProject.compileSdk\n    buildToolsVersion rootProject.buildTools\n\n    defaultConfig {\n        minSdkVersion rootProject.minSdk\n        targetSdkVersion rootProject.targetSdk\n        versionCode rootProject.versionCode\n        versionName rootProject.versionName\n\n        testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'\n    }\n\n    // Switch between test types by swapping commented out state\n    testBuildType /* 'debug' */  'minified'\n\n    buildTypes {\n        minified {\n            debuggable true\n            minifyEnabled true\n            signingConfig signingConfigs.debug\n        }\n        debug {}\n    }\n\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n}\n\ndependencies {\n    implementation project(':base')\n    api \"com.android.support:appcompat-v7:$supportLib\"\n    api 'com.taobao.android:atlas_core:5.0.8.0@aar'\n    androidTestImplementation \"com.android.support.test.espresso:espresso-core:$espressoVersion\"\n    androidTestImplementation \"com.android.support.test.espresso:espresso-contrib:$espressoVersion\"\n    androidTestImplementation \"com.android.support.test:rules:$androidTestVersion\"\n    androidTestImplementation \"com.android.support.test:runner:$androidTestVersion\"\n    androidTestImplementation \"org.hamcrest:hamcrest-core:$hamcrestVersion\"\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/detail/src/androidTest/java/com/example/android/unsplash/DetailActivityTest.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash;\n\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.support.annotation.NonNull;\nimport android.support.test.rule.ActivityTestRule;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport com.example.android.unsplash.feature.detail.R;\n\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static android.support.test.espresso.Espresso.onView;\nimport static android.support.test.espresso.assertion.ViewAssertions.matches;\nimport static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;\nimport static android.support.test.espresso.matcher.ViewMatchers.withId;\n\n@RunWith(AndroidJUnit4.class)\npublic class DetailActivityTest {\n\n    @Rule\n    public ActivityTestRule<DetailActivity> testRule =\n            new ActivityTestRule<DetailActivity>(DetailActivity.class, true) {\n                @Override\n                protected Intent getActivityIntent() {\n                    return new Intent()\n                            .addCategory(Intent.CATEGORY_BROWSABLE)\n                            .setAction(Intent.ACTION_VIEW)\n                            .setData(Uri\n                                    .parse(\"https://multi-feature.instantappsample.com/detail/1\"));\n                }\n            };\n\n    /**\n     * Tests whether the Activity can be launched via its registered URL.\n     */\n    @Test\n    public void isAddressableViaUrl() {\n        onView(withId(R.id.pager)).check(matches(isDisplayed()));\n    }\n}"
  },
  {
    "path": "atlas-demo/multi-feature-module/detail/src/main/AndroidManifest.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    package=\"com.example.android.unsplash.feature.detail\">\n\n    <application>\n        <activity\n            android:name=\"com.example.android.unsplash.DetailActivity\"\n            android:label=\"@string/app_name\"\n            android:parentActivityName=\"com.example.android.unsplash.MainActivity\"\n            android:theme=\"@style/App.Detail\">\n\n            <intent-filter\n                android:autoVerify=\"true\"\n                android:order=\"2\">\n                <action android:name=\"android.intent.action.VIEW\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data android:host=\"multi-feature.instantappsample.com\" />\n                <data android:pathPrefix=\"/detail\" />\n                <data android:scheme=\"https\" />\n                <data android:scheme=\"http\" />\n            </intent-filter>\n\n        </activity>\n    </application>\n</manifest>\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/detail/src/main/java/com/example/android/unsplash/DetailActivity.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport android.transition.Fade;\nimport android.transition.Slide;\nimport android.transition.TransitionSet;\nimport android.view.Gravity;\nimport android.view.View;\nimport android.view.animation.AnimationUtils;\nimport android.widget.Toolbar;\n\nimport com.example.android.unsplash.data.PhotoService;\nimport com.example.android.unsplash.data.model.Photo;\nimport com.example.android.unsplash.feature.detail.R;\nimport com.example.android.unsplash.ui.DetailSharedElementEnterCallback;\nimport com.example.android.unsplash.ui.pager.DetailViewPagerAdapter;\n\nimport java.util.ArrayList;\n\npublic class DetailActivity extends Activity {\n\n    private static final String STATE_INITIAL_ITEM = \"initial\";\n    private ViewPager viewPager;\n    private int initialItem;\n    private final View.OnClickListener navigationOnClickListener =\n            new View.OnClickListener() {\n                @Override\n                public void onClick(View v) {\n                    finishAfterTransition();\n                }\n            };\n    private DetailSharedElementEnterCallback sharedElementCallback;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        setContentView(R.layout.activity_detail);\n\n        postponeEnterTransition();\n\n        TransitionSet transitions = new TransitionSet();\n        Slide slide = new Slide(Gravity.BOTTOM);\n        slide.setInterpolator(AnimationUtils.loadInterpolator(this,\n                android.R.interpolator.linear_out_slow_in));\n        slide.setDuration(getResources().getInteger(android.R.integer.config_shortAnimTime));\n        transitions.addTransition(slide);\n        transitions.addTransition(new Fade());\n        getWindow().setEnterTransition(transitions);\n\n        Intent intent = getIntent();\n        sharedElementCallback = new DetailSharedElementEnterCallback(intent);\n        setEnterSharedElementCallback(sharedElementCallback);\n        try {\n            initialItem = Integer.parseInt(intent.getData().getLastPathSegment());\n        } catch (NumberFormatException e) {\n            initialItem = 0;\n        }\n        PhotoService.getInstance().getPhotosAsync(new PhotoService.PhotoCallback() {\n            @Override\n            public void success(ArrayList<Photo> photos) {\n                setUpViewPager(photos);\n                findViewById(android.R.id.empty).setVisibility(View.GONE);\n            }\n\n            @Override\n            public void error() {\n                finishAfterTransition();\n            }\n        });\n\n        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);\n        toolbar.setNavigationOnClickListener(navigationOnClickListener);\n\n        super.onCreate(savedInstanceState);\n    }\n\n    private void setUpViewPager(ArrayList<Photo> photos) {\n        viewPager = (ViewPager) findViewById(R.id.pager);\n        viewPager.setAdapter(new DetailViewPagerAdapter(this, photos, sharedElementCallback));\n        viewPager.setCurrentItem(initialItem);\n\n        viewPager.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {\n            @Override\n            public void onLayoutChange(View v, int left, int top, int right, int bottom,\n                                       int oldLeft, int oldTop, int oldRight, int oldBottom) {\n                if (viewPager.getChildCount() > 0) {\n                    viewPager.removeOnLayoutChangeListener(this);\n                    startPostponedEnterTransition();\n                }\n            }\n        });\n\n        viewPager.setPageMargin(getResources().getDimensionPixelSize(\n                com.example.android.unsplash.base.R.dimen.padding_mini));\n        viewPager.setPageMarginDrawable(R.drawable.page_margin);\n    }\n\n    @Override\n    protected void onSaveInstanceState(Bundle outState) {\n        outState.putInt(STATE_INITIAL_ITEM, initialItem);\n        super.onSaveInstanceState(outState);\n    }\n\n    @Override\n    protected void onRestoreInstanceState(Bundle savedInstanceState) {\n        initialItem = savedInstanceState.getInt(STATE_INITIAL_ITEM, 0);\n        super.onRestoreInstanceState(savedInstanceState);\n    }\n\n    @Override\n    public void onBackPressed() {\n        setActivityResult();\n        super.onBackPressed();\n    }\n\n    @Override\n    public void finishAfterTransition() {\n        setActivityResult();\n        super.finishAfterTransition();\n    }\n\n    private void setActivityResult() {\n        if (initialItem == viewPager.getCurrentItem()) {\n            setResult(RESULT_OK);\n            return;\n        }\n        Intent intent = new Intent();\n        intent.putExtra(IntentUtil.INSTANCE.getSELECTED_ITEM_POSITION(), viewPager.getCurrentItem());\n        setResult(RESULT_OK, intent);\n    }\n\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/detail/src/main/res/drawable/page_margin.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <solid android:color=\"@color/page_margin\" />\n</shape>"
  },
  {
    "path": "atlas-demo/multi-feature-module/detail/src/main/res/layout/activity_detail.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n             android:layout_width=\"match_parent\"\n             android:layout_height=\"match_parent\">\n    <android.support.v4.view.ViewPager android:id=\"@+id/pager\"\n                                       android:layout_width=\"match_parent\"\n                                       android:layout_height=\"match_parent\" />\n    <Toolbar android:id=\"@+id/toolbar\"\n             android:layout_width=\"match_parent\"\n             android:layout_height=\"?android:actionBarSize\"\n             android:navigationIcon=\"@drawable/ic_arrow_back\" />\n\n    <ProgressBar\n            android:id=\"@android:id/empty\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:indeterminate=\"true\"\n            android:indeterminateTint=\"@color/placeholder\"\n            android:indeterminateTintMode=\"src_in\" />\n</FrameLayout>\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Mon Jan 15 14:40:24 CST 2018\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.1-all.zip\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/gradle.properties",
    "content": "#\n# Copyright 2017 Google Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\n# Default value: -Xmx10248m -XX:MaxPermSize=256m\n# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\n\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\nandroid.enableAapt2=true\norg.gradle.jvmargs=-Xmx1536M"
  },
  {
    "path": "atlas-demo/multi-feature-module/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/installed/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/installed/build.gradle",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\napply plugin: 'com.android.application'\napply plugin: 'com.taobao.atlas'\n\nandroid {\n    compileSdkVersion rootProject.compileSdk\n    buildToolsVersion rootProject.buildTools\n\n    defaultConfig {\n        applicationId \"com.example.android.unsplash\"\n        minSdkVersion rootProject.minSdk\n        targetSdkVersion rootProject.targetSdk\n        versionCode rootProject.versionCode\n        versionName rootProject.versionName\n    }\n\n    // Switch between test types by swapping commented out state\n    testBuildType /* 'debug' */  'minified'\n\n    buildTypes {\n        minified {\n            debuggable true\n            minifyEnabled true\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), '../proguard.pro'\n            signingConfig signingConfigs.debug\n        }\n        debug {}\n    }\n}\n\natlas{\n    atlasEnabled true\n}\n\ndependencies {\n    implementation project(\":base\")\n    implementation project(\":main\")\n    implementation project(\":detail\")\n}\n\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/installed/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--\n  ~ Using a temporary package name to avoid name clash with base feature.\n  ~ Application ID is set in apk/build.gradle file.\n  -->\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.example.android.unsplash\" />\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/instant/build.gradle",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\napply plugin: 'com.android.instantapp'\n\nandroid {\n    compileSdkVersion rootProject.compileSdk\n    buildToolsVersion rootProject.buildTools\n\n    defaultConfig {\n        minSdkVersion rootProject.minSdkInstant\n        targetSdkVersion rootProject.targetSdk\n        versionCode rootProject.versionCode\n        versionName rootProject.versionName\n    }\n\n    buildTypes {\n        minified {}\n        debug {}\n    }\n}\n\ndependencies {\n    implementation project(\":base\")\n    implementation project(\":main\")\n    implementation project(\":detail\")\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/main/build.gradle",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\napply plugin: 'com.taobao.atlas.feature'\n\nandroid {\n    compileSdkVersion rootProject.compileSdk\n    buildToolsVersion rootProject.buildTools\n\n    defaultConfig {\n        minSdkVersion rootProject.minSdk\n        targetSdkVersion rootProject.targetSdk\n        versionCode rootProject.versionCode\n        versionName rootProject.versionName\n\n        testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'\n    }\n\n    // Switch between test types by swapping commented out state\n    testBuildType /* 'debug' */  'minified'\n\n    buildTypes {\n        minified {\n            debuggable true\n            minifyEnabled true\n            signingConfig signingConfigs.debug\n        }\n        debug {}\n    }\n\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n}\n\ndependencies {\n    implementation project(':base')\n    androidTestImplementation \"com.android.support.test.espresso:espresso-core:$espressoVersion\"\n    androidTestImplementation \"com.android.support.test.espresso:espresso-contrib:$espressoVersion\"\n    androidTestImplementation \"com.android.support.test.espresso:espresso-intents:$espressoVersion\"\n    androidTestImplementation \"com.android.support.test:rules:$androidTestVersion\"\n    androidTestImplementation \"com.android.support.test:runner:$androidTestVersion\"\n    androidTestImplementation \"org.hamcrest:hamcrest-core:$hamcrestVersion\"\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/main/src/androidTest/java/com/example/android/unsplash/MainActivityTest.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash;\n\n\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.support.annotation.NonNull;\nimport android.support.test.rule.ActivityTestRule;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport com.example.android.unsplash.feature.main.R;\n\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static android.support.test.espresso.Espresso.onView;\nimport static android.support.test.espresso.assertion.ViewAssertions.matches;\nimport static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;\nimport static android.support.test.espresso.matcher.ViewMatchers.withId;\n\n@RunWith(AndroidJUnit4.class)\npublic class MainActivityTest {\n\n    @Rule\n    public ActivityTestRule<MainActivity> testRule =\n            new ActivityTestRule<MainActivity>(MainActivity.class, true) {\n                @Override\n                protected Intent getActivityIntent() {\n                    return new Intent()\n                            .addCategory(Intent.CATEGORY_BROWSABLE)\n                            .setAction(Intent.ACTION_VIEW)\n                            .setData(Uri.parse(\"https://multi-feature.instantappsample.com/main\"));\n                }\n            };\n\n    /**\n     * Tests whether the Activity can be launched via its registered URL.\n     */\n    @Test\n    public void isAddressableViaUrl() {\n        onView(withId(R.id.image_grid)).check(matches(isDisplayed()));\n    }\n}"
  },
  {
    "path": "atlas-demo/multi-feature-module/main/src/main/AndroidManifest.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.example.android.unsplash.feature.main\" >\n\n    <application>\n        <activity\n            android:name=\"com.example.android.unsplash.MainActivity\"\n            android:label=\"@string/app_name\"\n            android:theme=\"@style/App.Home\">\n\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n\n            <intent-filter\n                android:autoVerify=\"true\"\n                android:order=\"1\">\n                <action android:name=\"android.intent.action.VIEW\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data android:host=\"multi-feature.instantappsample.com\" />\n                <data android:pathPrefix=\"/main\" />\n                <data android:scheme=\"https\" />\n                <data android:scheme=\"http\" />\n\n            </intent-filter>\n            <meta-data\n                android:name=\"default-url\"\n                android:value=\"https://multi-feature.instantappsample.com/main\" />\n        </activity>\n    </application>\n</manifest>\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/main/src/main/java/com/example/android/unsplash/MainActivity.java",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example.android.unsplash;\n\nimport android.app.Activity;\nimport android.app.ActivityOptions;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.graphics.Rect;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.support.annotation.NonNull;\nimport android.support.v7.widget.GridLayoutManager;\nimport android.support.v7.widget.RecyclerView;\nimport android.transition.Transition;\nimport android.util.Log;\nimport android.util.Pair;\nimport android.view.View;\nimport android.view.ViewTreeObserver;\nimport android.widget.ImageView;\nimport android.widget.ProgressBar;\nimport android.widget.TextView;\n\nimport com.example.android.unsplash.data.PhotoService;\nimport com.example.android.unsplash.data.model.Photo;\nimport com.example.android.unsplash.feature.main.R;\nimport com.example.android.unsplash.ui.DetailSharedElementEnterCallback;\nimport com.example.android.unsplash.ui.TransitionCallback;\nimport com.example.android.unsplash.ui.grid.GridMarginDecoration;\nimport com.example.android.unsplash.ui.grid.OnItemSelectedListener;\nimport com.example.android.unsplash.ui.grid.PhotoAdapter;\nimport com.example.android.unsplash.ui.grid.PhotoViewHolder;\n\nimport java.util.ArrayList;\n\npublic class MainActivity extends Activity {\n\n    private static final String TAG = \"MainActivity\";\n\n    private final Transition.TransitionListener sharedExitListener =\n            new TransitionCallback() {\n                @Override\n                public void onTransitionEnd(Transition transition) {\n                    setExitSharedElementCallback(null);\n                }\n            };\n\n    private RecyclerView grid;\n    private ProgressBar empty;\n    private ArrayList<Photo> relevantPhotos;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n        postponeEnterTransition();\n        // Listener to reset shared element exit transition callbacks.\n        getWindow().getSharedElementExitTransition().addListener(sharedExitListener);\n\n        grid = (RecyclerView) findViewById(R.id.image_grid);\n        empty = (ProgressBar) findViewById(android.R.id.empty);\n\n        setupRecyclerView();\n\n        if (savedInstanceState != null) {\n            relevantPhotos = savedInstanceState.getParcelableArrayList(IntentUtil.INSTANCE.getRELEVANT_PHOTOS());\n        }\n        displayData();\n    }\n\n    private void displayData() {\n        if (relevantPhotos != null) {\n            populateGrid();\n        } else {\n            PhotoService.getInstance().getPhotosAsync(new PhotoService.PhotoCallback() {\n                @Override\n                public void success(ArrayList<Photo> photos) {\n                    relevantPhotos = photos;\n                    populateGrid();\n                }\n\n                @Override\n                public void error() {\n                    // no-op\n                }\n            });\n        }\n    }\n\n    private void populateGrid() {\n        grid.setAdapter(new PhotoAdapter(this, relevantPhotos));\n        grid.addOnItemTouchListener(new OnItemSelectedListener(MainActivity.this) {\n            public void onItemSelected(RecyclerView.ViewHolder holder, int position) {\n                if (!(holder instanceof PhotoViewHolder)) {\n                    return;\n                }\n                MainActivity activity = MainActivity.this;\n                PhotoViewHolder pvh = (PhotoViewHolder) holder;\n                final Intent intent = getDetailActivityStartIntent(\n                        activity, position, pvh);\n                final ActivityOptions activityOptions = getActivityOptions(pvh);\n\n                activity.startActivityForResult(\n                        intent, IntentUtil.INSTANCE.getREQUEST_CODE(), activityOptions.toBundle());\n            }\n        });\n        empty.setVisibility(View.GONE);\n    }\n\n    @Override\n    protected void onSaveInstanceState(Bundle outState) {\n        outState.putParcelableArrayList(IntentUtil.INSTANCE.getRELEVANT_PHOTOS(), relevantPhotos);\n        super.onSaveInstanceState(outState);\n    }\n\n    @Override\n    public void onActivityReenter(int resultCode, Intent data) {\n        postponeEnterTransition();\n        // Start the postponed transition when the recycler view is ready to be drawn.\n        grid.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {\n            @Override\n            public boolean onPreDraw() {\n                grid.getViewTreeObserver().removeOnPreDrawListener(this);\n                startPostponedEnterTransition();\n                return true;\n            }\n        });\n\n        if (data == null) {\n            return;\n        }\n\n        final int selectedItem = data.getIntExtra(IntentUtil.INSTANCE.getSELECTED_ITEM_POSITION(), 0);\n        grid.scrollToPosition(selectedItem);\n\n        PhotoViewHolder holder = (PhotoViewHolder) grid.\n                findViewHolderForAdapterPosition(selectedItem);\n        if (holder == null) {\n            Log.w(TAG, \"onActivityReenter: Holder is null, remapping cancelled.\");\n            return;\n        }\n\n        DetailSharedElementEnterCallback callback =\n                new DetailSharedElementEnterCallback(getIntent());\n        callback.setView(holder.itemView);\n        setExitSharedElementCallback(callback);\n\n    }\n\n    private void setupRecyclerView() {\n        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);\n        grid.setLayoutManager(gridLayoutManager);\n        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {\n            @Override\n            public int getSpanSize(int position) {\n                /* emulating https://material-design.storage.googleapis.com/publish/material_v_4/material_ext_publish/0B6Okdz75tqQsck9lUkgxNVZza1U/style_imagery_integration_scale1.png */\n                switch (position % 6) {\n                    case 5:\n                        return 3;\n                    case 3:\n                        return 2;\n                    default:\n                        return 1;\n                }\n            }\n        });\n        grid.addItemDecoration(new GridMarginDecoration(\n                getResources().getDimensionPixelSize(\n                        com.example.android.unsplash.base.R.dimen.grid_item_spacing)));\n        grid.setHasFixedSize(true);\n\n    }\n\n    @NonNull\n    private static Intent getDetailActivityStartIntent(Context context,\n                                                       int position,\n                                                       PhotoViewHolder holder) {\n        final Intent intent = new Intent(Intent.ACTION_VIEW,\n                Uri.parse(\"https://multi-feature.instantappsample.com/detail/\" + position));\n        intent.setPackage(context.getPackageName());\n        intent.addCategory(Intent.CATEGORY_BROWSABLE);\n\n        TextView author =\n                holder.itemView.findViewById(com.example.android.unsplash.base.R.id.author);\n\n        // Working around unboxing issues with multiple dex files on platforms prior to N.\n        intent.putExtra(IntentUtil.INSTANCE.getSELECTED_ITEM_POSITION(), position);\n        intent.putExtra(IntentUtil.INSTANCE.getFONT_SIZE(), author.getTextSize());\n        intent.putExtra(IntentUtil.INSTANCE.getPADDING(),\n                new Rect(author.getPaddingLeft(),\n                        author.getPaddingTop(),\n                        author.getPaddingRight(),\n                        author.getPaddingBottom()));\n        intent.putExtra(IntentUtil.INSTANCE.getTEXT_COLOR(), author.getCurrentTextColor());\n        return intent;\n    }\n\n    private ActivityOptions getActivityOptions(PhotoViewHolder holder) {\n        TextView author =\n                holder.itemView.findViewById(com.example.android.unsplash.base.R.id.author);\n        ImageView photo =\n                holder.itemView.findViewById(com.example.android.unsplash.base.R.id.photo);\n        Pair authorPair = Pair.create(author, author.getTransitionName());\n        Pair photoPair = Pair.create(photo, photo.getTransitionName());\n        View decorView = getWindow().getDecorView();\n        View statusBackground = decorView.findViewById(android.R.id.statusBarBackground);\n        View navBackground = decorView.findViewById(android.R.id.navigationBarBackground);\n        Pair statusPair = Pair.create(statusBackground,\n                statusBackground.getTransitionName());\n\n        final ActivityOptions options;\n        if (navBackground == null) {\n            options = ActivityOptions.makeSceneTransitionAnimation(this,\n                    authorPair, photoPair, statusPair);\n        } else {\n            Pair navPair = Pair.create(navBackground, navBackground.getTransitionName());\n            options = ActivityOptions.makeSceneTransitionAnimation(this,\n                    authorPair, photoPair, statusPair, navPair);\n        }\n        return options;\n    }\n\n    @Override\n    protected void onResume() {\n        super.onResume();\n    }\n\n    @Override\n    protected void onActivityResult(int requestCode, int resultCode, Intent data) {\n        super.onActivityResult(requestCode, resultCode, data);\n    }\n}\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/main/src/main/res/layout/activity_main.xml",
    "content": "<!--\n  ~ Copyright 2017 Google Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ you may not use this file except in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~      http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<FrameLayout\n        xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n    <ProgressBar\n            android:id=\"@android:id/empty\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:indeterminate=\"true\"\n            android:indeterminateTint=\"@color/placeholder\"\n            android:indeterminateTintMode=\"src_in\" />\n\n    <android.support.v7.widget.RecyclerView\n            android:id=\"@+id/image_grid\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:padding=\"@dimen/grid_item_spacing\"\n            android:clipToPadding=\"false\"\n            android:scrollbars=\"vertical\"\n            android:scrollbarStyle=\"insideOverlay\"\n            android:orientation=\"vertical\" />\n\n</FrameLayout>\n"
  },
  {
    "path": "atlas-demo/multi-feature-module/proguard.pro",
    "content": "-keep class com.example.android.unsplash.transition.TextResize {\n  public protected *;\n}\n-keep public class com.example.android.unsplash.ui.grid.GridMarginDecoration {\n  public protected *;\n}\n-keep public class com.example.android.unsplash.ui.grid.PhotoAdapter {\n  public protected *;\n}\n-keep public class com.example.android.unsplash.ui.grid.OnItemSelectedListener {\n  public protected *;\n}\n-keep public class com.example.android.unsplash.ui.grid.PhotoViewHolder {\n  public protected *;\n}\n-keep public class com.example.android.unsplash.ui.DetailSharedElementEnterCallback {\n  public protected *;\n}\n-keep public class com.example.android.unsplash.ui.pager.DetailViewPagerAdapter {\n  public protected *;\n}\n-keep public class com.example.android.unsplash.ui.TransitionCallback {\n  public protected *;\n}\n-keep, includedescriptorclasses public class com.example.android.unsplash.data.PhotoService** {\n  public protected *;\n}\n-keep, includedescriptorclasses public class android.support.v4.view.ViewPager {\n  public protected *;\n}\n-keep public class android.support.v4.view.PagerAdapter {\n  public protected *;\n}\n-keep public class android.support.v7.widget.RecyclerView** {\n  public protected *;\n}\n-keep, includedescriptorclasses class android.support.v7.widget.GridLayoutManager {\n  public protected *;\n}\n\n-keepattributes *Annotation*,Signature\n\n-dontwarn com.google.appengine.api.urlfetch.**\n-dontwarn com.squareup.okhttp.**\n-dontwarn okio.BufferedSink\n-dontwarn rx.**\n\n-keep public class com.google.gson.** {\n  public protected *;\n}\n-keep class retrofit.** { *; }"
  },
  {
    "path": "atlas-demo/multi-feature-module/settings.gradle",
    "content": "/*\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ninclude ':instant', ':installed', ':base', ':detail', ':main'\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/FirstBundle/build.gradle",
    "content": "buildscript {\n    repositories {\n        mavenLocal()\n        jcenter()\n    }\n    configurations.all {\n        resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds'\n        resolutionStrategy.cacheChangingModulesFor 0, 'seconds'\n    }\n    dependencies {\n        classpath \"com.taobao.android:atlasplugin:2.3.1.beta55\"\n        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'\n        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'\n    }\n}\n\napply plugin: 'com.android.library'\napply plugin: 'com.taobao.atlas'\napply plugin: 'maven-publish'\n\n\ngroup = 'com.taobao.android'\nversion = '1.0.0'\n\ntasks.withType(JavaCompile) {\n    sourceCompatibility = 1.7\n    targetCompatibility = 1.7\n}\n\nandroid {\n    compileSdkVersion 24\n    buildToolsVersion \"25.0.2\"\n    lintOptions {\n        checkReleaseBuilds false\n        abortOnError false\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_7\n        targetCompatibility JavaVersion.VERSION_1_7\n    }\n\n    defaultConfig {\n        versionName version\n    }\n}\n\napply plugin: 'com.github.dcendents.android-maven'\napply plugin: 'com.jfrog.bintray'\n\natlas.bundleConfig.awbBundle = true\n\ndef siteUrl = 'https://github.com/alibaba/atlas'\n// 项目的主页\ndef gitUrl = 'https://github.com/alibaba/atlas'\n// Git仓库的url\ninstall {\n    repositories.mavenInstaller {\n        // This generates POM.xml with proper parameters\n        pom {\n            project {\n                packaging 'awb'\n                // Add your description here\n                name 'firstbundle' //项目描述\n                // Set your license\n                licenses {\n                    license {\n                        name 'The Apache Software License, Version 2.0'\n                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'\n                    }\n                }\n                developers {\n                    developer {\n                        id 'alibabaatlas' //填写的一些基本信息\n                        name project.name\n                        email 'alibabaatlasframework@gmail.com'\n                    }\n                }\n                scm {\n                    connection gitUrl\n                    developerConnection gitUrl\n                    url siteUrl\n                }\n            }\n        }\n    }\n}\n\nProperties properties = new Properties()\ndef file = project.rootProject.file('local.properties')\nif (file.exists()) {\n    properties.load(file.newDataInputStream())\n}\nbintray {\n    user = properties.getProperty(\"bintray.user\")\n    key = properties.getProperty(\"bintray.apikey\")\n//    configurations = ['archives']\n    publications = ['maven']\n    pkg {\n        repo = \"maven\"\n        name = project.name\t//发布到JCenter上的项目名字\n        websiteUrl = \"atlas.alibaba.net\"\n        vcsUrl = gitUrl\n        licenses = [\"Apache-2.0\"]\n        publish = true\n    }\n}\n\ntask sourcesJar(type: Jar) {\n    from('src/main/java') {\n        include '**'\n    }\n    classifier = 'sources'\n}\n\npublishing {\n    publications {\n        maven(MavenPublication) {\n            artifact \"${project.buildDir}/outputs/awb/${project.name}-release.awb\"\n            artifact sourcesJar\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/FirstBundle/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Wed Dec 21 10:55:15 CST 2016\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=http\\://services.gradle.org/distributions/gradle-3.3-all.zip\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/FirstBundle/gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/FirstBundle/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windows variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\ngoto execute\n\n:4NT_args\n@rem Get arguments from the 4NT Shell from JP Software\nset CMD_LINE_ARGS=%$\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/FirstBundle/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n          package=\"com.taobao.firstbundle\"\n          android:versionCode=\"1\"\n          android:versionName=\"1.0\">\n    <uses-sdk android:minSdkVersion=\"14\"/>\n    <application android:name=\"com.taobao.firstbundle.FirstBundleApplication\">\n        <activity android:name=\"com.taobao.firstbundle.FirstBundleActivity\"\n            >\n        </activity>\n    </application>\n</manifest>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/FirstBundle/src/main/java/com/taobao/firstbundle/FirstBundleActivity.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\npackage com.taobao.firstbundle;\n\nimport android.app.Activity;\nimport android.os.Bundle;\nimport android.widget.TextView;\n\npublic class FirstBundleActivity extends Activity {\n    /**\n     * Called when the activity is first created.\n     */\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n\n        super.onCreate(savedInstanceState);\n\n        setContentView(R.layout.first_main);\n\n        TextView textView = (TextView) findViewById(R.id.xxxxx);\n\n        textView.setText(\"[base version] this bundle version \" + BuildConfig.VERSION_NAME);\n\n    }\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/FirstBundle/src/main/java/com/taobao/firstbundle/FirstBundleApplication.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\npackage com.taobao.firstbundle;\n\nimport android.app.Application;\nimport android.util.Log;\n\n\n/**\n * Created by wuzhong on 16/7/12.\n */\npublic class FirstBundleApplication extends Application {\n    @Override\n    public void onCreate() {\n        super.onCreate();\n\n        Log.e(\"APP\",\"FirstBundleApplication on create\");\n\n    }\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/FirstBundle/src/main/res/layout/first_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n              xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n              android:orientation=\"vertical\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"fill_parent\"\n        >\n    <TextView\n            android:layout_width=\"fill_parent\"\n            android:layout_height=\"fill_parent\"\n            android:id=\"@+id/xxxxx\"\n            android:text=\"abcd\"\n            />\n\n</LinearLayout>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/FirstBundle/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"app_name_firstbundle\">FirstBundle</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/README.md",
    "content": "## Project Structure\n\nfirstbundle :\n\nBusiness component, the bundle module in the atlas, type is the awb which structure similar to aar\n\napp:\n\nApk project, contain atlas and update function, integrates the above business components(first bundle)\n\n\n## APK build\n\nSpecific reference `buildApk.sh`\n\nGeneral steps are as follows:\n1. The first release bundle version1 to the repository\n2. App dependency on bundle versin1, execute ./gradlew assembleDebug\n3. Installation\n\n\n## Building patch package\n\nSpecific reference `buildTpatch.sh`\n\nGeneral steps are as follows:\n\n1. release bundle version2 to the repository\n2. The app dependency on bundle version2,\n3. Modify the app project source and depend on the version of the component (optional)\n4. Modify the app versionCode, and release (required)\n5. ./gradlew clean assembleDebug -DapVersion=1.0 build patch\n6. Push the patch files to the app cache directory\n7. Calls the update patch installation on the phone\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/README.zh_cn.md",
    "content": "## 工程结构\n\nfirstbundle :\n\n    业务组件，atlas里的bundle模块， 类型是awb，结构和aar相似\n\napp:\n\n    apk工程， 包含 atlas 和 更新功能， 集成了 上面的业务组件\n\n\n## apk 构建\n\n具体参考 `buildApk.sh`\n\n大致步骤如下：\n\n1. 先发布bundle version1 到仓库\n2. app 依赖 bundle versin1， 执行 ./gradlew assembleDebug\n3. 安装\n\n\n## 构建patch包\n\n具体参考 `buildTpatch.sh`\n\n大致步骤如下：\n\n1. 先发布bundle version2 到仓库\n2. app 依赖 bundle versin2，\n3. 修改app工程的源码和依赖的组件版本（可选）\n4. 修改app的 versionCode ， 和发布版本（必选）\n5. ./gradlew clean assembleDebug -DapVersion=1.0 构建patch\n6. 把patch文件上传到手机app的cache目录\n7. 在手机上调用update做patch的安装\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/activitygroupdelegate/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/activitygroupdelegate/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion \"25.0.2\"\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {\n        exclude group: 'com.android.support', module: 'support-annotations'\n    })\n    compile 'com.android.support:appcompat-v7:25.1.0'\n    testCompile 'junit:junit:4.12'\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/activitygroupdelegate/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/activitygroupdelegate/src/androidTest/java/com/taoboa/activitygroupdelegate/ExampleInstrumentedTest.java",
    "content": "package com.taoboa.activitygroupdelegate;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() throws Exception {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.taoboa.activitygroupdelegate.test\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/activitygroupdelegate/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\n    package=\"com.taoboa.activitygroupdelegate\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\">\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/activitygroupdelegate/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">ActivityGroupDelegateCompat</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/activitygroupdelegate/src/test/java/com/taoboa/activitygroupdelegate/ExampleUnitTest.java",
    "content": "package com.taoboa.activitygroupdelegate;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/build.gradle",
    "content": "buildscript {\n    repositories {\n        mavenLocal()\n        jcenter()\n    }\n    dependencies {\n        classpath \"com.taobao.android:atlasplugin:2.3.1.beta55\"\n    }\n}\n\ngroup = 'com.taobao.android.atlasdemo'\nversion = getEnvValue(\"versionName\",\"1.0.0\");\ndef apVersion = getEnvValue(\"apVersion\",\"\");\n\napply plugin: 'com.taobao.atlas.application'\n\n\n//TODO do this in plugin\nconfigurations {\n    providedCompile\n    all*.exclude group: 'com.android.support', module: 'multidex'\n}\n\nrepositories {\n    mavenLocal()\n    jcenter()\n}\n\ndependencies {\n\n    compile('com.android.support:appcompat-v7:23.1.0')\n\n    compile('com.taobao.android:atlas_core:5.0.6@aar') {\n        transitive = true\n    }\n\n    compile(\"com.taobao.android:firstbundle:${version}@awb\")\n\n    compile 'com.taobao.android:atlasupdate:1.1.4.2@aar'\n\n    compile 'com.alibaba:fastjson:1.1.45.android@jar'\n\n}\n\n\nconfigurations.all {\n\n    resolutionStrategy {\n        cacheChangingModulesFor(0, 'SECONDS')\n        force \"com.google.android:support-v4:21.0.2\";\n    }\n}\n\nandroid {\n    compileSdkVersion 24\n    buildToolsVersion \"25.0.2\"\n\n    compileOptions.encoding = 'UTF-8'\n\n    defaultConfig {\n        versionName version\n        multiDexEnabled true\n\n        ndk {\n            abiFilters \"x86\", \"armeabi\"  //默认只启用x86,armeabi\n        }\n\n        resConfigs \"en\", \"fr\"\n    }\n\n    dexOptions {\n        jumboMode = true\n        preDexLibraries = true\n        // javaMaxHeapSize = '2048m'\n    }\n\n    buildTypes {\n        debug {\n            // debug模式\n            multiDexEnabled true\n        }\n\n        release {\n            multiDexEnabled true\n            shrinkResources false\n            // 是否进行混淆\n            minifyEnabled true\n            proguardFile 'proguard.cfg'\n        }\n    }\n\n    lintOptions {\n        checkReleaseBuilds false\n        // Or, if you prefer, you can continue to check for errors in release builds,\n        // but continue the build even when errors are found:\n        abortOnError false\n    }\n\n}\n\natlas {\n\n    atlasEnabled true\n\n    tBuildConfig {\n        autoStartBundles = ['com.taobao.firstbundle'] //自启动bundle配置\n    }\n\n\n    patchConfigs{\n        debug {\n            createTPatch true\n        }\n    }\n\n\n    buildTypes {\n        debug {\n            if (apVersion){\n                baseApDependency   \"com.taobao.android.atlasdemo:AP-debug:${apVersion}@ap\"\n                patchConfig    patchConfigs.debug\n            }\n        }\n    }\n\n}\n\ntask wrapper(type: Wrapper) {\n    gradleVersion = '2.12'\n    distributionUrl = 'http://services.gradle.org/distributions/gradle-2.12-all.zip'\n}\n\napply plugin: 'maven'\napply plugin: 'maven-publish'\n\npublishing {\n    repositories {\n        mavenLocal()\n    }\n}\n\npublishing {\n    publications {\n        maven(MavenPublication) {\n            artifact \"${project.buildDir}/outputs/apk/${project.name}-debug.ap\"\n            artifactId \"AP-debug\"\n        }\n    }\n}\n\nString getEnvValue(key, defValue){\n    def val = System.getProperty(key);\n    if(null != val){\n        return val;\n    }\n    val = System.getenv(key);\n    if(null != val){\n        return val;\n    }\n    return defValue;\n}\n\ntasks.whenTaskAdded { task ->\n    if (task.name.contains(\"DebugAndroidTest\")) {\n        task.setEnabled(false);\n    }\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/buildApk.sh",
    "content": "#!/bin/bash\n\n\necho \"(1) 构建app， 生成 apk 和 ap， 同时把 ap 文件发布到本地仓库\"\n\n./gradlew clean assembleDebug publish\ncat build/publications/maven/pom-default.xml\n\necho \"ap 模块发布到本地仓库成功\"\ncd ../\n\necho \"(3) 安装基线apk\"\necho \"adb install -r build/outputs/apk/app-debug.apk\"\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/buildTpatch.sh",
    "content": "#!/bin/bash\n\necho \"(1) 修改依赖的源码和版本\"\necho \"    修改App工程源码\"\necho \"    修改versionName\"\n\n\necho \"(2)  重新构建apk， 生成patch 包\"\n\n./gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.1\n\n\necho \"(3) 上传 tpatch\"\nadb push build/outputs/tpatch-debug/update.json /sdcard/Android/data/com.taobao.demo/cache/update.json\nadb push build/outputs/tpatch-debug/patch-*.tpatch /sdcard/Android/data/com.taobao.demo/cache\n\necho \"(4) 点击动态部署完成安装 \"\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/build.gradle",
    "content": "apply plugin: 'com.taobao.atlas.library'\napply plugin: 'maven-publish'\n\ngroup = 'com.taobao.android'\nversion = '1.0.0'\n\natlas.bundleConfig.awbBundle = true\n\nbuildscript {\n    repositories {\n        mavenLocal()\n        jcenter()\n    }\n    dependencies {\n        classpath \"com.taobao.android:atlasplugin:2.2.3.rc+\"\n        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'\n        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'\n    }\n}\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion \"25.0.2\"\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile 'com.android.support:appcompat-v7:25.1.0'\n    compile 'com.android.support:design:25.1.0'\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/src/androidTest/java/com/taobao/firstbundle/ExampleInstrumentedTest.java",
    "content": "package com.taobao.firstbundle;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() throws Exception {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.taobao.firstbundle\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.taobao.firstbundle\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity\n            android:name=\".MainActivity\"\n            android:label=\"@string/app_name\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/src/main/java/com/taobao/firstbundle/MainActivity.java",
    "content": "package com.taobao.firstbundle;\n\nimport android.os.Bundle;\nimport android.support.annotation.NonNull;\nimport android.support.design.widget.BottomNavigationView;\nimport android.support.v7.app.AppCompatActivity;\nimport android.view.MenuItem;\nimport android.widget.TextView;\n\npublic class MainActivity extends AppCompatActivity {\n\n    private TextView mTextMessage;\n\n    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener\n            = new BottomNavigationView.OnNavigationItemSelectedListener() {\n\n        @Override\n        public boolean onNavigationItemSelected(@NonNull MenuItem item) {\n\n            if (item.getItemId() == R.id.navigation_home){\n                mTextMessage.setText(R.string.title_home);\n                return true;\n            }else if(item.getItemId() == R.id.navigation_dashboard){\n                mTextMessage.setText(R.string.title_dashboard);\n                return true;\n            }else if(item.getItemId() == R.id.navigation_notifications){\n                mTextMessage.setText(R.string.title_notifications);\n                return true;\n            }\n            return false;\n        }\n\n    };\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n\n        mTextMessage = (TextView) findViewById(R.id.message);\n        BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);\n        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);\n    }\n\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/src/main/res/drawable/ic_dashboard_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z\" />\n</vector>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/src/main/res/drawable/ic_home_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z\" />\n</vector>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/src/main/res/drawable/ic_notifications_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z\" />\n</vector>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/container\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\"\n    tools:context=\"com.taobao.firstbundle.MainActivity\">\n\n    <FrameLayout\n        android:id=\"@+id/content\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\">\n\n        <TextView\n            android:id=\"@+id/message\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginBottom=\"@dimen/activity_vertical_margin\"\n            android:layout_marginLeft=\"@dimen/activity_horizontal_margin\"\n            android:layout_marginRight=\"@dimen/activity_horizontal_margin\"\n            android:layout_marginTop=\"@dimen/activity_vertical_margin\"\n            android:text=\"@string/title_home\" />\n\n    </FrameLayout>\n\n    <android.support.design.widget.BottomNavigationView\n        android:id=\"@+id/navigation\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom\"\n        android:background=\"?android:attr/windowBackground\"\n        app:menu=\"@menu/navigation\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/src/main/res/menu/navigation.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item\n        android:id=\"@+id/navigation_home\"\n        android:icon=\"@drawable/ic_home_black_24dp\"\n        android:title=\"@string/title_home\" />\n\n    <item\n        android:id=\"@+id/navigation_dashboard\"\n        android:icon=\"@drawable/ic_dashboard_black_24dp\"\n        android:title=\"@string/title_dashboard\" />\n\n    <item\n        android:id=\"@+id/navigation_notifications\"\n        android:icon=\"@drawable/ic_notifications_black_24dp\"\n        android:title=\"@string/title_notifications\" />\n\n</menu>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">FirstBundle</string>\n    <string name=\"title_home\">Home</string>\n    <string name=\"title_dashboard\">Dashboard</string>\n    <string name=\"title_notifications\">Notifications</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/firstbundle/src/test/java/com/taobao/firstbundle/ExampleUnitTest.java",
    "content": "package com.taobao.firstbundle;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Mon Dec 28 10:00:20 PST 2015\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-3.3-all.zip\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/gradle.properties",
    "content": "android.useDeprecatedNdk=true\norg.gradle.parallel=true\norg.gradle.parallel.intra=true\nandroid.enableBuildCache=false\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windowz variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\ngoto execute\n\n:4NT_args\n@rem Get arguments from the 4NT Shell from JP Software\nset CMD_LINE_ARGS=%$\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/proguard.cfg",
    "content": "-dontpreverify\n-dontusemixedcaseclassnames\n#-optimizations code/removal/simple,code/removal/advanced,method/removal/parameter,method/inlining/short,method/inlining/tailrecursion\n-optimizations  code/removal/simple,code/removal/advanced,code/removal/variable,code/removal/exception,code/simplification/branch,code/simplification/field\n,code/simplification/cast,code/simplification/arithmetic,code/simplification/variable\n#-dontobfuscate\n#-dontoptimize\n#-dontshrink\n-keepattributes Exceptions,InnerClasses,Signature,SourceFile,LineNumberTable,*Annotation*\n-renamesourcefileattribute Taobao\n#-keepattributes Exceptions,InnerClasses,Signature,LineNumberTable,*Annotation*\n#-repackageclasses 'com.taobao.taobao'\n-allowaccessmodification\n#-printmapping map.txt\n#-applymapping mapping.txt\n-optimizationpasses 1\n-target 1.6\n\n\n#-verbose\n-dontskipnonpubliclibraryclasses\n-dontskipnonpubliclibraryclassmembers\n\n-dontwarn org.mozilla.javascript.**\n-dontwarn org.mozilla.classfile.**\n-dontwarn java.awt.**\n-dontwarn com.taobao.**\n-dontwarn com.google.android.maps.**\n-dontwarn android.support.v7.widget.**\n-dontwarn android.support.v4.**\n-dontwarn com.tencent.mm.sdk.**\n-dontwarn org.android.agoo.**\n-dontwarn com.amap.api.**\n-dontwarn com.autonavi.amap.**\n-dontwarn com.ut.**\n-dontwarn com.robotium.**\n-dontwarn com.alibaba.fastjson.**\n-dontwarn android.taobao.**\n-dontwarn com.alibaba.mobileim.**\n-dontwarn com.autonavi.**\n-dontwarn com.amap.**\n-dontwarn ***\n\n-keep class com.google.inject.Binder\n-keepclassmembers class * {\n    @com.google.inject.Inject <init>(...);\n}\n# There's no way to keep all @Observes methods, so use the On*Event convention to identify event handlers\n-keepclassmembers class * {\n    void *(**On*Event);\n}\n-keep public class * extends android.view.View {\n    public <init>(android.content.Context);\n    public <init>(android.content.Context, android.util.AttributeSet);\n    public <init>(android.content.Context, android.util.AttributeSet, int);\n    public void set*(...);\n}\n-keep public class roboguice.**\n\n-keep class rx.**{*;}\n\n## 手淘项目公共的混淆keep选项\n# 为了atlas注入\n-keepclassmembers class ** {\n    private <init>(...);\n    public <init>(...);\n    <init>(...);\n}\n\n-keepclassmembernames class **.R$* {*;}\n-keepclassmembernames class **.R {*;}\n-keepclassmembers class **{\n    public static final <fields>;\n}\n\n-keep  class * extends android.app.Application\n-keep  class * extends android.app.Activity\n-keep  class * extends android.app.Service"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/secondbundle/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/secondbundle/build.gradle",
    "content": "apply plugin: 'com.taobao.atlas.library'\napply plugin: 'maven-publish'\n\ngroup = 'com.taobao.android'\nversion = '1.0.0'\n\natlas.bundleConfig.awbBundle = true\n\nbuildscript {\n    repositories {\n        mavenLocal()\n        jcenter()\n    }\n    dependencies {\n        classpath \"com.taobao.android:atlasplugin:2.2.3.rc+\"\n        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'\n        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'\n    }\n}\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion \"25.0.2\"\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile 'com.android.support:appcompat-v7:25.1.0'\n    compile 'com.android.support:design:25.1.0'\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/secondbundle/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/secondbundle/src/androidTest/java/com/taobao/secondbundle/ExampleInstrumentedTest.java",
    "content": "package com.taobao.secondbundle;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() throws Exception {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.taobao.secondbundle\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/secondbundle/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.taobao.secondbundle\">\n\n    <!-- To auto-complete the email text field in the login form with the user's emails -->\n    <uses-permission android:name=\"android.permission.GET_ACCOUNTS\" />\n    <uses-permission android:name=\"android.permission.READ_PROFILE\" />\n    <uses-permission android:name=\"android.permission.READ_CONTACTS\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity\n            android:name=\".LoginActivity\"\n            android:label=\"@string/app_name\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/secondbundle/src/main/java/com/taobao/secondbundle/LoginActivity.java",
    "content": "package com.taobao.secondbundle;\n\nimport android.animation.Animator;\nimport android.animation.AnimatorListenerAdapter;\nimport android.annotation.TargetApi;\nimport android.content.pm.PackageManager;\nimport android.support.annotation.NonNull;\nimport android.support.design.widget.Snackbar;\nimport android.support.v7.app.AppCompatActivity;\nimport android.app.LoaderManager.LoaderCallbacks;\n\nimport android.content.CursorLoader;\nimport android.content.Loader;\nimport android.database.Cursor;\nimport android.net.Uri;\nimport android.os.AsyncTask;\n\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.provider.ContactsContract;\nimport android.text.TextUtils;\nimport android.view.KeyEvent;\nimport android.view.View;\nimport android.view.View.OnClickListener;\nimport android.view.inputmethod.EditorInfo;\nimport android.widget.ArrayAdapter;\nimport android.widget.AutoCompleteTextView;\nimport android.widget.Button;\nimport android.widget.EditText;\nimport android.widget.TextView;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static android.Manifest.permission.READ_CONTACTS;\n\n/**\n * A login screen that offers login via email/password.\n */\npublic class LoginActivity extends AppCompatActivity implements LoaderCallbacks<Cursor> {\n\n    /**\n     * Id to identity READ_CONTACTS permission request.\n     */\n    private static final int REQUEST_READ_CONTACTS = 0;\n\n    /**\n     * A dummy authentication store containing known user names and passwords.\n     * TODO: remove after connecting to a real authentication system.\n     */\n    private static final String[] DUMMY_CREDENTIALS = new String[]{\n            \"foo@example.com:hello\", \"bar@example.com:world\"\n    };\n    /**\n     * Keep track of the login task to ensure we can cancel it if requested.\n     */\n    private UserLoginTask mAuthTask = null;\n\n    // UI references.\n    private AutoCompleteTextView mEmailView;\n    private EditText mPasswordView;\n    private View mProgressView;\n    private View mLoginFormView;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_login);\n        // Set up the login form.\n        mEmailView = (AutoCompleteTextView) findViewById(R.id.email);\n        populateAutoComplete();\n\n        mPasswordView = (EditText) findViewById(R.id.password);\n        mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {\n            @Override\n            public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {\n                if (id == R.id.login || id == EditorInfo.IME_NULL) {\n                    attemptLogin();\n                    return true;\n                }\n                return false;\n            }\n        });\n\n        Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);\n        mEmailSignInButton.setOnClickListener(new OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                attemptLogin();\n            }\n        });\n\n        mLoginFormView = findViewById(R.id.login_form);\n        mProgressView = findViewById(R.id.login_progress);\n    }\n\n    private void populateAutoComplete() {\n        if (!mayRequestContacts()) {\n            return;\n        }\n\n        getLoaderManager().initLoader(0, null, this);\n    }\n\n    private boolean mayRequestContacts() {\n        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {\n            return true;\n        }\n        if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {\n            return true;\n        }\n        if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {\n            Snackbar.make(mEmailView, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)\n                    .setAction(android.R.string.ok, new View.OnClickListener() {\n                        @Override\n                        @TargetApi(Build.VERSION_CODES.M)\n                        public void onClick(View v) {\n                            requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);\n                        }\n                    });\n        } else {\n            requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);\n        }\n        return false;\n    }\n\n    /**\n     * Callback received when a permissions request has been completed.\n     */\n    @Override\n    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,\n                                           @NonNull int[] grantResults) {\n        if (requestCode == REQUEST_READ_CONTACTS) {\n            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {\n                populateAutoComplete();\n            }\n        }\n    }\n\n\n    /**\n     * Attempts to sign in or register the account specified by the login form.\n     * If there are form errors (invalid email, missing fields, etc.), the\n     * errors are presented and no actual login attempt is made.\n     */\n    private void attemptLogin() {\n        if (mAuthTask != null) {\n            return;\n        }\n\n        // Reset errors.\n        mEmailView.setError(null);\n        mPasswordView.setError(null);\n\n        // Store values at the time of the login attempt.\n        String email = mEmailView.getText().toString();\n        String password = mPasswordView.getText().toString();\n\n        boolean cancel = false;\n        View focusView = null;\n\n        // Check for a valid password, if the user entered one.\n        if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) {\n            mPasswordView.setError(getString(R.string.error_invalid_password));\n            focusView = mPasswordView;\n            cancel = true;\n        }\n\n        // Check for a valid email address.\n        if (TextUtils.isEmpty(email)) {\n            mEmailView.setError(getString(R.string.error_field_required));\n            focusView = mEmailView;\n            cancel = true;\n        } else if (!isEmailValid(email)) {\n            mEmailView.setError(getString(R.string.error_invalid_email));\n            focusView = mEmailView;\n            cancel = true;\n        }\n\n        if (cancel) {\n            // There was an error; don't attempt login and focus the first\n            // form field with an error.\n            focusView.requestFocus();\n        } else {\n            // Show a progress spinner, and kick off a background task to\n            // perform the user login attempt.\n            showProgress(true);\n            mAuthTask = new UserLoginTask(email, password);\n            mAuthTask.execute((Void) null);\n        }\n    }\n\n    private boolean isEmailValid(String email) {\n        //TODO: Replace this with your own logic\n        return email.contains(\"@\");\n    }\n\n    private boolean isPasswordValid(String password) {\n        //TODO: Replace this with your own logic\n        return password.length() > 4;\n    }\n\n    /**\n     * Shows the progress UI and hides the login form.\n     */\n    @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)\n    private void showProgress(final boolean show) {\n        // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow\n        // for very easy animations. If available, use these APIs to fade-in\n        // the progress spinner.\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {\n            int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);\n\n            mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);\n            mLoginFormView.animate().setDuration(shortAnimTime).alpha(\n                    show ? 0 : 1).setListener(new AnimatorListenerAdapter() {\n                @Override\n                public void onAnimationEnd(Animator animation) {\n                    mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);\n                }\n            });\n\n            mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);\n            mProgressView.animate().setDuration(shortAnimTime).alpha(\n                    show ? 1 : 0).setListener(new AnimatorListenerAdapter() {\n                @Override\n                public void onAnimationEnd(Animator animation) {\n                    mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);\n                }\n            });\n        } else {\n            // The ViewPropertyAnimator APIs are not available, so simply show\n            // and hide the relevant UI components.\n            mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);\n            mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);\n        }\n    }\n\n    @Override\n    public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {\n        return new CursorLoader(this,\n                // Retrieve data rows for the device user's 'profile' contact.\n                Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI,\n                        ContactsContract.Contacts.Data.CONTENT_DIRECTORY), ProfileQuery.PROJECTION,\n\n                // Select only email addresses.\n                ContactsContract.Contacts.Data.MIMETYPE +\n                        \" = ?\", new String[]{ContactsContract.CommonDataKinds.Email\n                .CONTENT_ITEM_TYPE},\n\n                // Show primary email addresses first. Note that there won't be\n                // a primary email address if the user hasn't specified one.\n                ContactsContract.Contacts.Data.IS_PRIMARY + \" DESC\");\n    }\n\n    @Override\n    public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {\n        List<String> emails = new ArrayList<>();\n        cursor.moveToFirst();\n        while (!cursor.isAfterLast()) {\n            emails.add(cursor.getString(ProfileQuery.ADDRESS));\n            cursor.moveToNext();\n        }\n\n        addEmailsToAutoComplete(emails);\n    }\n\n    @Override\n    public void onLoaderReset(Loader<Cursor> cursorLoader) {\n\n    }\n\n    private void addEmailsToAutoComplete(List<String> emailAddressCollection) {\n        //Create adapter to tell the AutoCompleteTextView what to show in its dropdown list.\n        ArrayAdapter<String> adapter =\n                new ArrayAdapter<>(LoginActivity.this,\n                        android.R.layout.simple_dropdown_item_1line, emailAddressCollection);\n\n        mEmailView.setAdapter(adapter);\n    }\n\n\n    private interface ProfileQuery {\n        String[] PROJECTION = {\n                ContactsContract.CommonDataKinds.Email.ADDRESS,\n                ContactsContract.CommonDataKinds.Email.IS_PRIMARY,\n        };\n\n        int ADDRESS = 0;\n        int IS_PRIMARY = 1;\n    }\n\n    /**\n     * Represents an asynchronous login/registration task used to authenticate\n     * the user.\n     */\n    public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {\n\n        private final String mEmail;\n        private final String mPassword;\n\n        UserLoginTask(String email, String password) {\n            mEmail = email;\n            mPassword = password;\n        }\n\n        @Override\n        protected Boolean doInBackground(Void... params) {\n            // TODO: attempt authentication against a network service.\n\n            try {\n                // Simulate network access.\n                Thread.sleep(2000);\n            } catch (InterruptedException e) {\n                return false;\n            }\n\n            for (String credential : DUMMY_CREDENTIALS) {\n                String[] pieces = credential.split(\":\");\n                if (pieces[0].equals(mEmail)) {\n                    // Account exists, return true if the password matches.\n                    return pieces[1].equals(mPassword);\n                }\n            }\n\n            // TODO: register the new account here.\n            return true;\n        }\n\n        @Override\n        protected void onPostExecute(final Boolean success) {\n            mAuthTask = null;\n            showProgress(false);\n\n            if (success) {\n                finish();\n            } else {\n                mPasswordView.setError(getString(R.string.error_incorrect_password));\n                mPasswordView.requestFocus();\n            }\n        }\n\n        @Override\n        protected void onCancelled() {\n            mAuthTask = null;\n            showProgress(false);\n        }\n    }\n}\n\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/secondbundle/src/main/res/layout/activity_login.xml",
    "content": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:gravity=\"center_horizontal\"\n    android:orientation=\"vertical\"\n    android:paddingBottom=\"@dimen/activity_vertical_margin\"\n    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n    android:paddingRight=\"@dimen/activity_horizontal_margin\"\n    android:paddingTop=\"@dimen/activity_vertical_margin\"\n    tools:context=\"com.taobao.secondbundle.LoginActivity\">\n\n    <!-- Login progress -->\n    <ProgressBar\n        android:id=\"@+id/login_progress\"\n        style=\"?android:attr/progressBarStyleLarge\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginBottom=\"8dp\"\n        android:visibility=\"gone\" />\n\n    <ScrollView\n        android:id=\"@+id/login_form\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <LinearLayout\n            android:id=\"@+id/email_login_form\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"vertical\">\n\n            <android.support.design.widget.TextInputLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\">\n\n                <AutoCompleteTextView\n                    android:id=\"@+id/email\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:hint=\"@string/prompt_email\"\n                    android:inputType=\"textEmailAddress\"\n                    android:maxLines=\"1\"\n                    android:singleLine=\"true\" />\n\n            </android.support.design.widget.TextInputLayout>\n\n            <android.support.design.widget.TextInputLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\">\n\n                <EditText\n                    android:id=\"@+id/password\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:hint=\"@string/prompt_password\"\n                    android:imeActionId=\"@+id/login\"\n                    android:imeActionLabel=\"@string/action_sign_in_short\"\n                    android:imeOptions=\"actionUnspecified\"\n                    android:inputType=\"textPassword\"\n                    android:maxLines=\"1\"\n                    android:singleLine=\"true\" />\n\n            </android.support.design.widget.TextInputLayout>\n\n            <Button\n                android:id=\"@+id/email_sign_in_button\"\n                style=\"?android:textAppearanceSmall\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginTop=\"16dp\"\n                android:text=\"@string/action_sign_in\"\n                android:textStyle=\"bold\" />\n\n        </LinearLayout>\n    </ScrollView>\n</LinearLayout>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/secondbundle/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/secondbundle/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/secondbundle/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">SecondBundle</string>\n\n    <!-- Strings related to login -->\n    <string name=\"prompt_email\">Email</string>\n    <string name=\"prompt_password\">Password (optional)</string>\n    <string name=\"action_sign_in\">Sign in or register</string>\n    <string name=\"action_sign_in_short\">Sign in</string>\n    <string name=\"error_invalid_email\">This email address is invalid</string>\n    <string name=\"error_invalid_password\">This password is too short</string>\n    <string name=\"error_incorrect_password\">This password is incorrect</string>\n    <string name=\"error_field_required\">This field is required</string>\n    <string name=\"permission_rationale\">\"Contacts permissions are needed for providing email\n        completions.\"\n    </string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/secondbundle/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/secondbundle/src/test/java/com/taobao/secondbundle/ExampleUnitTest.java",
    "content": "package com.taobao.secondbundle;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/settings.gradle",
    "content": "include ':sharedlibrary', ':firstbundle', ':secondbundle'"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/sharebundle/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/sharebundle/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion \"25.0.2\"\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {\n        exclude group: 'com.android.support', module: 'support-annotations'\n    })\n    compile 'com.android.support:appcompat-v7:25.1.0'\n    testCompile 'junit:junit:4.12'\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/sharebundle/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/sharebundle/src/androidTest/java/com/taobao/sharebundle/ExampleInstrumentedTest.java",
    "content": "package com.taobao.sharebundle;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() throws Exception {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.taobao.sharebundle.test\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/sharebundle/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\n    package=\"com.taobao.sharebundle\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\">\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/sharebundle/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">ShareBundle</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/sharebundle/src/test/java/com/taobao/sharebundle/ExampleUnitTest.java",
    "content": "package com.taobao.sharebundle;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/sharedlibrary/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/sharedlibrary/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion \"25.0.2\"\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 25\n        versionCode 1\n        versionName \"1.0\"\n\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile 'com.android.support:appcompat-v7:25.1.0'\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/sharedlibrary/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/guanjie/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/sharedlibrary/src/androidTest/java/taobao/sharedlibrary/ExampleInstrumentedTest.java",
    "content": "package taobao.sharedlibrary;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() throws Exception {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"taobao.sharedlibrary.test\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/sharedlibrary/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\n    package=\"taobao.sharedlibrary\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\">\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/sharedlibrary/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">SharedLibrary</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/sharedlibrary/src/test/java/taobao/sharedlibrary/ExampleUnitTest.java",
    "content": "package taobao.sharedlibrary;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n          package=\"com.taobao.demo\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n          android:versionCode=\"1\"\n          android:versionName=\"1\">\n\n    <uses-sdk android:minSdkVersion=\"14\" android:targetSdkVersion=\"23\"/>\n\n    <application tools:replace=\"android:name\" android:label=\"@string/app_name\" android:icon=\"@drawable/app_launcher\"\n        android:theme=\"@style/AppTheme\"\n        android:name=\"com.taobao.demo.DemoApplication\" >\n\n        <activity android:name=\"com.taobao.demo.WelcomActivity\"\n\n                  android:label=\"AtlasDemo\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\"/>\n                <category android:name=\"android.intent.category.LAUNCHER\"/>\n            </intent-filter>\n        </activity>\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/src/main/java/com/taobao/demo/DemoApplication.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\npackage com.taobao.demo;\n\nimport android.app.Application;\nimport android.util.Log;\n\n/**\n * Created by guanjie on 15/8/20.\n */\npublic class DemoApplication extends Application {\n\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        Log.e(\"APP\",\"DemoApplication on create\");\n    }\n\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/src/main/java/com/taobao/demo/WelcomActivity.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\npackage com.taobao.demo;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.view.View;\nimport android.widget.TextView;\n\nimport com.taobao.demo.update.Updater;\n\n// import com.taobao.share.ShareUtils;\n\n\npublic class WelcomActivity extends Activity {\n    /**\n     * Called when the activity is first created.\n     */\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.main);\n        TextView textView = (TextView) findViewById(R.id.textView);\n\n//        textView.setText(getString(R.string.ttid) + \".\" + new DuplicateClazz().dup() + \"_tpatch\");\n        textView.setText(\" welcome activity \" + BuildConfig.VERSION_NAME);\n\n        findViewById(R.id.goto_bundle).setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                Intent intent = new Intent();\n                intent.setClassName(WelcomActivity.this, \"com.taobao.firstbundle.FirstBundleActivity\");\n                startActivity(intent);\n            }\n        });\n\n        final Context context = this;\n        findViewById(R.id.update).setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n\n                new Thread(new Runnable() {\n                    @Override\n                    public void run() {\n                        Updater.update(context);\n                    }\n                }).start();\n\n            }\n        });\n\n    }\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/src/main/java/com/taobao/demo/update/Updater.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\npackage com.taobao.demo.update;\n\nimport android.content.Context;\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.util.Log;\nimport android.widget.Toast;\nimport com.alibaba.fastjson.JSON;\nimport com.taobao.atlas.dex.util.FileUtils;\nimport com.taobao.atlas.dexmerge.MergeCallback;\nimport com.taobao.atlas.update.model.UpdateInfo;\nimport com.taobao.atlas.update.util.PatchInstaller;\nimport com.taobao.atlas.update.util.PatchMerger;\n\nimport java.io.File;\nimport java.io.IOException;\n\n/**\n * Created by wuzhong on 2016/12/20.\n */\n\npublic class Updater {\n\n    public static void update(final Context context) {\n\n        File updateInfo = new File(context.getExternalCacheDir(), \"update.json\");\n\n        if (!updateInfo.exists()) {\n            Log.e(\"update\", \"更新信息不存在，请先 执行 buildTpatch.sh\");\n            toast(\"更新信息不存在，请先 执行 buildTpatch.sh\", context);\n            return;\n        }\n\n        String jsonStr = new String(FileUtils.readFile(updateInfo));\n        UpdateInfo info = JSON.parseObject(jsonStr, UpdateInfo.class);\n\n        File patchFile = new File(context.getExternalCacheDir(), \"patch-\" + info.updateVersion + \"@\" + info.baseVersion + \".tpatch\");\n\n        try {\n//            AtlasUpdater.update(info, patchFile);\n\n            PatchMerger patchMerger = new PatchMerger(info, patchFile, new MergeCallback() {\n                @Override\n                public void onMergeResult(boolean result, String bundleName) {\n                    if (result) {\n                        toast(bundleName + \"merge success!\", context);\n                    }else {\n                        toast(bundleName + \"merge failed!\", context);\n\n                    }\n                }\n            });\n\n            try {\n                patchMerger.merge();\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n            Log.e(\"mergeOutputs:\",String.valueOf(patchMerger.mergeOutputs.size()));\n            PatchInstaller patchInstaller = new PatchInstaller(patchMerger.mergeOutputs, info);\n\n            patchInstaller.install();\n\n            Log.e(\"update\", \"update success\");\n            toast(\"更新成功，请重启app\", context);\n        } catch (Throwable e) {\n            e.printStackTrace();\n            toast(\"更新失败, \" + e.getMessage(), context);\n        }\n\n\n    }\n\n    private static void toast(final String msg, final Context context) {\n        new Handler(Looper.getMainLooper()).post(new Runnable() {\n            @Override\n            public void run() {\n                Toast.makeText(context, msg, Toast.LENGTH_LONG).show();\n            }\n        });\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/src/main/res/layout/main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n              android:orientation=\"vertical\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"fill_parent\"\n        >\n    <Button\n            android:id=\"@+id/goto_bundle\"\n            android:layout_width=\"fill_parent\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"go to bundleActivity\"\n            />\n\n    <Button\n        android:id=\"@+id/update\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"动态部署\"\n        />\n\n    <TextView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:textAppearance=\"?android:attr/textAppearanceLarge\"\n        android:text=\"version\"\n        android:id=\"@+id/textView\"\n        android:layout_gravity=\"center_horizontal\" />\n</LinearLayout>\n\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"app_name\">MainBuilder</string>\n    <string name=\"test\">test</string>\n    <string name=\"ttid\">600002222033</string>\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    repositories {\n        jcenter()\n    }\n    dependencies {\n        classpath \"com.taobao.android:atlasplugin:2.3.1.beta55\"\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        jcenter()\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Mon Dec 28 10:00:20 PST 2015\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-3.3-all.zip\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windowz variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\ngoto execute\n\n:4NT_args\n@rem Get arguments from the 4NT Shell from JP Software\nset CMD_LINE_ARGS=%$\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "atlas-demo/基于版本打包的demo/settings.gradle",
    "content": "include ':app'\ninclude ':FirstBundle'\n"
  },
  {
    "path": "atlas-docs/.gitignore",
    "content": "target\n"
  },
  {
    "path": "atlas-docs/.si.yml",
    "content": "before_deploy:\n  - gitbook install\n  - gitbook build .\noptions:\n  dist: '_book'\ncname: 'atlas.alibaba.net'\n"
  },
  {
    "path": "atlas-docs/README.md",
    "content": "\n#Atlas   [Browse this in English ](en/index.html)\n\n[<img src='https://render.alipay.com/p/s/taobaonpm_click/atlas_aliyun_logo' align='right' style=' width:360px;height:120 px'/>](https://render.alipay.com/p/s/taobaonpm_click/atlas_aliyun_logo_click) \n<img src='dingtalk.png' align='left' style=' width:130px;height:130 px'/>\n<br>扫码加入atlas钉钉交流群</br>  \n<br />\n<br />\n<br />\n<br />\n<br />\n \n## 简介\nAtlas是伴随着手机淘宝的不断发展而衍生出来的一个运行于Android系统上的一个容器化框架，我们也叫动态组件化(Dynamic Bundle)框架。它主要提供了解耦化、组件化、动态性的支持。覆盖了工程师的工程编码期、Apk运行期以及后续运维期的各种问题。\n\nAtlas对app的划分如下图所示:\n\n![][relation]\n\n|拆分|定位|说明|\n|:---|:---|:---|\n|host|基础支持|包含独立的中间件，以及一个Base的工程，里面可能包含应用的Application，应用icon等基础性内容|\n|bundle|业务层基本单位|__运行期按需动态加载__。bundle可以调用host的代码和资源，同时bundle之间允许存在依赖关系。|\n\n\n> 与插件化框架不同的是，Atlas是一个组件框架，Atlas不是一个多进程的框架，他主要完成的就是在运行环境中按需地去完成各个bundle的安装，加载类和资源。\n\n## Atlas提供哪些功能\n\n__从app的开发期--运行期--上线后的运维期，Atlas提供了一整套完整的支持__\n\n|周期|说明|\n|:---|:---|\n|工程期|实现host、bundle独立开发、调试的功能，bundle独立|\n|运行期|实现完整的组件生命周期的映射，类隔离、资源共享等机制|\n|运维期|增量更新修复能力，提供对class、so以及资源的增量更新修复能力，快速升级|\n\n以一个app的开发的生命周期为例，参见 [demo][demo]\n\n### 开发期\n\n提供gradle插件，简化开发者接入的负担。\n\n需要说明的是，gradle插件不会侵入正常的开发流程，host和bundle都可以独立的进行开发和调试。\n\n|plugin|说明|\n|:---|:---|\n|com.taobao.atlas|用于host工程，用于设置对bundle的依赖和其它atlas的功能|\n|com.taobao.atlas.library|对应bundle工程，用于将module转化成atlas所需要的bundle依赖，不会侵入正常的开发环境|\n\n\n### 运行期\n\n|功能|说明|\n|:---|:---|\n|四大组件支持|支持运行bundle中的四大组件|\n|共享代码资源|bundle可以直接使用host中的代码和资源|\n|bundle按需加载|业务需要时，才会去加载对应bundle中的代码和资源|\n|远程bundle|减少包体积。不常用的bundle放在云端，需要时按需下载。当用户设备空间紧张时,可以清理掉一些长期不用的组件|\n|解释执行|为了降低用户等待时间，Atlas框架在dalivk系统上首次使用bundle时关闭了verify，在ART系统上首次使用时关闭了dex2oat走解释执行。同时后台通过异步任务走原生的dexopt过程，为下次使用做好准备|\n\n\n### 运维期 \n\n__动态部署__ 是容器一个最重要的功能。基于此:\n\n- 业务可以灵活发布自己的需求\n- 有故障的业务可以及时修复或者回滚\n- 同时动态部署的快速覆盖能力在灰度等场景下可以更快地收到所需的效果。\n\n| 功能 | 说明 |\n|:---|:---|\n|动态部署|构建时会与之前版本的dex进行字节码级别的diff，生成tpatch包。最终下发到用户手机的patch仅包含变化class组成的dex和更改或者新增的资源文件|\n|dexpatch|以动态部署技术方案为基础，可以看作是动态部署的子集，专注于单个bundle的故障修复。由于做的事小而精，所以编译构建速度、线上生效速度都是远远快于动态部署|\n\n## 如何接入\n\n我们比较倾向于用一个比较干净的壳子工程来作为容器架构下的打包工程,称之为__main_builder__，__main_builder__建议只存在AndroidManifest.xml、构建文件及部分资源内容。\n\n- manifest：文件用于单独管理apk的icon，版本号，versioncode等；\n- gradle：用于配置主apk的依赖及控制构建参数\n\n以 [demo][demo] 为例\n\n1. 引用Atlas插件及依赖仓库，修改工程gradle文件\n\n\t```\n\tbuildscript {\n\t\trepositories { jcenter()}\n\t\tdependencies {\n\t\t\tclasspath \"com.taobao.android:atlasplugin:2.3.3.beta2\"\n\t\t}\n\t}\n\t```\n2. bundle接入，修改bundle的gradle，参见[demo][demo]中的firstbundle配置\n\t\n\t```\n\tapply plugin: 'com.taobao.atlas.library'\n\n\tatlas {\n\t\t//声明为awb 即bundle工程\n    \tbundleConfig { awbBundle true }\n\t}\n\t```\n3. 容器接入，修改app模块的gradle文件\n\n\t```\n\tapply plugin: 'com.taobao.atlas.application'\n\tdependencies {\n\t\t//核心sdk\n    \tcompile('com.taobao.android:atlas_core:5.0.0@aar') {\n     \t\ttransitive = true\n \t\t}\n \t\t//如果不需要用到atlas的动态部署功能，不需要依赖atlasupdate\n \t\tcompile 'com.taobao.android:atlasupdate:1.0.8@aar'\n \t\t\n \t\t//设置bundle依赖\n \t\tbundleCompile project(':firstbundle')\n \t}\n \tatlas {\n      atlasEnabled true\n      //...\n   }\n\t```\n\n至此，接入完成，不需要接入方调用任何初始化函数，详细的文档参 [接入文档][atlas_doc_guide_use]，\n\n## Support\n\n支持版本 4.0 to 7.0. \n\nRuntime | Android Version | Support\n------  | --------------- | --------\nDalvik  | 2.2             | Not Test\nDalvik  | 2.3             | Not Test\nDalvik  | 3.0             | Not Test\nDalvik  | 4.0-4.4         | Yes\nART     | 5.0             | Yes\nART     | 5.1             | Yes\nART     | M               | Yes\nART     | N               | Yes\n\t\n## 其它\n\n- [FAQ][faq] \n- [文档][atlas_doc]\n- [Atlas-手淘组件化框架的前世今生和未来的路][atlas_histroy]\n\n[relation]: img/relation.png\n[demo]: https://github.com/alibaba/atlas/blob/master/atlas-demo/AtlasDemo\n[atlas_histroy]: https://mp.weixin.qq.com/s?__biz=MzAxNDEwNjk5OQ==&mid=2650400348&idx=1&sn=99bc1bce932c5b9000d5b54afa2de70e\n[atlas_doc_guide_use]: https://alibaba.github.io/atlas/guide-for-use/guide_for_build.html\n[atlas_doc]: https://alibaba.github.io/atlas/\n[faq]: https://alibaba.github.io/atlas/faq/question.html\n[atlas_dev]: img/atlas_dev.svg\n[atlas_runtime_maintenance]: img/atlas_runtime_maintenance.svg\n"
  },
  {
    "path": "atlas-docs/SUMMARY.md",
    "content": "# Summary\n\n* [Introduction](README.md)\n* 原理解析\n    * [框架原理](principle-intro/Runtime_principle.md)\n    * [名词解释](principle-intro/Project_architectured.md)\n    * [APK结构](principle-intro/Apk_architecture.md)\n    * [运行期文件结构](principle-intro/File_architecture_runtime.md)\n* [接入指引](guide-for-use/README.md)\n    * [容器接入](guide-for-use/guide_for_build.md)\n    * [bundle拆分|新建](guide-for-use/guide_for_bundle.md)\n    * [awo编译](guide-for-use/guide_for_compile.md)\n    * [跨bundle的代码重用和通信](guide-for-use/bundleCommunicate.md)\n* [动态部署](update/README.md)\n    * [技术原理](update/principle.md)\n    * [dexpatch](update/dexpatch.md)\n    * [dexpatch使用教程](update/dexpatch_use_guide.md)\n    * [一些限制](update/guide.md)\n* FAQ\n    * [问答](faq/question.md)\n    * [故障排查](faq/help.md)\n    * [构建定制包](faq/variant.md)\n    * [动态部署失败排查指南](faq/dynamic_failed_help.md)\n* 源码分析\n    * [Atlas之Gradle配置](code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.md)\n    * [Atlas之启动过程(一)](code_read/atlas_start/atlas_start_1.md)\n    * [Atlas之启动过程(二)](code_read/atlas_start/atlas_start_2.md)\n    * [Atlas之Bundle加载过程](code_read/atlas_bundle_load/atlas_bundle_load.md)\n\n"
  },
  {
    "path": "atlas-docs/_book/.gitignore",
    "content": "target\n"
  },
  {
    "path": "atlas-docs/_book/.si.yml",
    "content": "before_deploy:\n  - gitbook install\n  - gitbook build .\noptions:\n  dist: '_book'\ncname: 'atlas.alibaba.net'\n"
  },
  {
    "path": "atlas-docs/_book/code_read/atlas_bundle_load/atlas_bundle_load.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>Atlas之Bundle加载过程 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    \n    <link rel=\"prev\" href=\"../atlas_start/atlas_start_2.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../../\">\n            \n                <a href=\"../../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../../guide-for-use/\">\n            \n                <a href=\"../../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../../update/\">\n            \n                <a href=\"../../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../../update/principle.html\">\n            \n                <a href=\"../../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../../update/dexpatch.html\">\n            \n                <a href=\"../../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../../update/guide.html\">\n            \n                <a href=\"../../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../../faq/question.html\">\n            \n                <a href=\"../../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../../faq/help.html\">\n            \n                <a href=\"../../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../../faq/variant.html\">\n            \n                <a href=\"../../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.6.4\" data-path=\"atlas_bundle_load.html\">\n            \n                <a href=\"atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"../..\" >Atlas之Bundle加载过程</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"&#x6982;&#x8FF0;\">&#x6982;&#x8FF0;</h1>\n<p>atals&#x4E2D;bundle&#x52A0;&#x8F7D;&#x8FC7;&#x7A0B;</p>\n<ul>\n<li>class</li>\n<li>resource</li>\n</ul>\n<p><img src=\"bundle_load_img.svg\" alt=\"\"></p>\n<p><strong>&#x6CE8;&#x610F;&#x56FE;&#x4E2D;&#x7684;&#x7BAD;&#x5934;</strong></p>\n<ul>\n<li>&#x5B9E;&#x7EBF;&#x7BAD;&#x5934;&#x8868;&#x793A;&#x8FD0;&#x884C;&#x5728;&#x4E3B;&#x7EBF;&#x7A0B;</li>\n<li>&#x865A;&#x7EBF;&#x7BAD;&#x5934;&#x8868;&#x793A;&#x8FD0;&#x884C;&#x5728;HandlerThread&#x4E2D;</li>\n</ul>\n<p>&#x5C06;&#x6D41;&#x7A0B;&#x5206;&#x4E3A;&#x4E09;&#x5927;&#x90E8;&#x5206;</p>\n<table>\n<thead>\n<tr>\n<th>&#x90E8;&#x5206;</th>\n<th>&#x8BF4;&#x660E;</th>\n<th>&#x5BF9;&#x5E94;&#x6B65;&#x9AA4;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>&#x7B2C;&#x4E00;&#x90E8;&#x5206;</td>\n<td>&#x52A0;&#x8F7D;&#x65F6;&#x673A;&#x7684;&#x89E6;&#x53D1;&#x903B;&#x8F91;</td>\n<td>1-7</td>\n</tr>\n<tr>\n<td>&#x7B2C;&#x4E8C;&#x90E8;&#x5206;</td>\n<td>bundle&#x52A0;&#x8F7D;&#x8FC7;&#x7A0B;</td>\n<td>8-15</td>\n</tr>\n<tr>\n<td>&#x7B2C;&#x4E09;&#x90E8;&#x5206;</td>\n<td>bundle&#x4EE3;&#x7801;&#x521D;&#x59CB;&#x5316;</td>\n<td>16-19</td>\n</tr>\n</tbody>\n</table>\n<h1 id=\"&#x7B2C;&#x4E00;&#x90E8;&#x5206;-&#x89E6;&#x53D1;&#x65F6;&#x673A;\">&#x7B2C;&#x4E00;&#x90E8;&#x5206; &#x89E6;&#x53D1;&#x65F6;&#x673A;</h1>\n<h2 id=\"&#x5165;&#x53E3;\">&#x5165;&#x53E3;</h2>\n<p>&#x4EE5;&#x5728;MainActivity&#x4E2D;&#x70B9;&#x51FB;secondebundle&#x4E3A;&#x4F8B;</p>\n<p>MainActivity.java</p>\n<pre><code>case R.id.navigation_dashboard:\n    switchToActivity(&quot;second&quot;,&quot;com.taobao.secondbundle.SecondBundleActivity&quot;)\n</code></pre><p>switchActivity &#x8F97;&#x8C03;&#x7528;&#xFF0C;&#x4F1A;&#x6267;&#x884C;&#x5230;&#x7B2C;2&#x6B65;<code>execStartChildActivityInternal</code>&#x65B9;&#x6CD5;&#x4E2D;</p>\n<h2 id=\"execstartchildactivityinternal\">execStartChildActivityInternal</h2>\n<p>ActivityGroupDelegate.java</p>\n<pre><code>public void execStartChildActivityInternal(ViewGroup container,String key, Intent intent){\n    String bundleName = AtlasBundleInfoManager.instance().getBundleForComponet(componentName);\n    if(!TextUtils.isEmpty(bundleName)){\n        BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(bundleName);\n        if(impl!=null&amp;&amp;impl.checkValidate()) {    }else {\n        //...\n        asyncStartActivity(container,key,bundleName,intent);\n    }\n}\n</code></pre><ul>\n<li>&#x9996;&#x5148;&#xFF0C;&#x6839;&#x636E;componentName&#x5373;<code>com.taobao.secondbundle.SecondBundleActivity</code>,&#x67E5;&#x8BE2;bundle&#x7684;&#x540D;&#x79F0;&#x3002;&#x5728;<a href=\"../atlas_start/atlas_start_2.html\">atlas&#x542F;&#x52A8;&#x8FC7;&#x7A0B;(&#x4E0B;)</a>&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x77E5;&#x9053;AtlasBundleInfoManager&#x4E2D;&#x5B58;&#x50A8;&#x4E86;&#x51E0;&#x4E4E;&#x6240;&#x6709;bundle&#x7684;&#x4FE1;&#x606F;&#xFF0C;&#x6240;&#x4EE5;&#x8FD4;&#x56DE; bundleName &#x5C31;&#x662F; <code>com.taobao.secondbundle</code>&#x3002;</li>\n<li>&#x7136;&#x540E;&#xFF0C;&#x6839;&#x636E;bundlename&#xFF0C;&#x53BB;&#x67E5;&#x8BE2;bundle&#x52A0;&#x8F7D;&#x540E;&#x7684;&#x7ED3;&#x6784;&#x4F53;- <code>BundleImpl</code>&#x3002;&#x7531;&#x4E8E;secondbundle&#x4E4B;&#x524D;&#x5E76;&#x6CA1;&#x6709;&#x52A0;&#x8F7D;&#x8FDB;&#x6765;&#xFF0C;&#x6240;&#x4EE5;&#x4F1A;&#x6267;&#x884C;&#x5230;&#x7B2C;3&#x6B65;<code>asyncStartActivity</code>&#x65B9;&#x6CD5;&#x3002;</li>\n</ul>\n<p>asyncStartActivity&#x6700;&#x7EC8;&#x8C03;&#x7528;&#x4E86;BundleUtil&#x7684;&#x65B9;&#x6CD5;&#xFF0C;&#x6211;&#x4EEC;&#x76F4;&#x63A5;&#x770B;&#x7B2C;4&#x6B65; <code>checkBundleStateAsync</code></p>\n<h2 id=\"checkbundlestateasync\">checkBundleStateAsync</h2>\n<p>BundleUtil.java</p>\n<pre><code>public static boolean checkBundleArrayStateAsync(final String[] bundlesName, final Runnable bundleActivated, final Runnable bundleDisabled){\n    BundleInstaller installer = BundleInstallerFetcher.obtainInstaller();\n    installer.installTransitivelyAsync(bundlesName, new BundleInstaller.InstallListener() {\n        @Override\n        public void onFinished() {\n            boolean success = true;\n            BundleImpl tmp;\n            for(String bundleName : bundlesName){\n                if((tmp=((BundleImpl) Atlas.getInstance().getBundle(bundleName)))==null || !tmp.checkValidate()){\n                    success = false;\n                }else{\n                    tmp.startBundle();\n                }\n          }\n       });\n    return true;\n}\n</code></pre><p>&#x5728;&#x8FD9;&#x4E00;&#x6B65;&#x4E2D;&#xFF0C;&#x5F00;&#x59CB;&#x5F02;&#x6B65;&#x52A0;&#x8F7D;bundle&#xFF0C;&#x6210;&#x529F;&#x540E;&#xFF0C;&#x5728;&#x4E3B;&#x7EBF;&#x7A0B;&#x4E2D;&#x56DE;&#x8C03;<code>onFinished</code>(&#x540E;&#x9762;&#x4F1A;&#x63D0;&#x53CA;),&#x8C03;&#x7528;BundleImpl&#x5BF9;&#x8C61;&#x7684;startBundl&#x65B9;&#x6CD5;&#xFF0C;&#x5F00;&#x59CB; <strong>&#x7B2C;&#x4E09;&#x90E8;&#x5206;</strong> &#x7684;&#x521D;&#x59CB;&#x5316;&#x8FC7;&#x7A0B;&#x3002; </p>\n<h2 id=\"deliverytask\">deliveryTask</h2>\n<p>&#x7B2C;5&#x3001;6&#x6B65;&#xFF0C;&#x4E3B;&#x8981;&#x662F;&#x5404;&#x79CD;&#x903B;&#x8F91;&#x5224;&#x65AD;&#xFF0C;&#x4E4B;&#x540E;&#x8F97;&#x8F6C;&#x8C03;&#x7528;&#x5230;7&#x6B65;&#x3002;&#x76F4;&#x63A5;&#x770B;&#x7B2C;7&#x6B65;<code>deliveryTask</code>&#x7684;&#x51FD;&#x6570;&#x5B9E;&#x73B0;&#x3002;</p>\n<p>BundleUtil.java</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">private</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">deliveryTask</span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">boolean</span> sync)</span></span>{\n    Runnable installTask = <span class=\"hljs-keyword\">new</span> Runnable() {\n        <span class=\"hljs-meta\">@Override</span>\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">run</span><span class=\"hljs-params\">()</span> </span>{\n            <span class=\"hljs-keyword\">synchronized</span> (BundleInstaller.<span class=\"hljs-keyword\">this</span>) {\n                 <span class=\"hljs-keyword\">try</span>{\n                     call();\n                 } <span class=\"hljs-keyword\">catch</span> (Throwable e) {\n                     e.printStackTrace();\n                 } <span class=\"hljs-keyword\">finally</span> {\n                     <span class=\"hljs-keyword\">if</span> (mListener != <span class=\"hljs-keyword\">null</span>) {\n                         <span class=\"hljs-keyword\">new</span> Handler(Looper.getMainLooper()).post(<span class=\"hljs-keyword\">new</span> Runnable() {\n                             <span class=\"hljs-meta\">@Override</span>\n                             <span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">run</span><span class=\"hljs-params\">()</span> </span>{\n                                 mListener.onFinished();\n                             }\n                 <span class=\"hljs-comment\">//..</span>\n        };\n        sBundleHandler.post(installTask);\n\n    }\n}\n</code></pre>\n<p>&#x51FD;&#x6570;&#x9996;&#x5148;&#x521B;&#x5EFA;&#x4E86;&#x4E00;&#x4E2A;&#x5F02;&#x6B65;&#x4EFB;&#x52A1; <code>installTask</code>,&#x4E4B;&#x540E;&#x5C06;&#x4EFB;&#x52A1;&#x63D0;&#x4EA4;&#x7ED9;<code>sBundleHandler</code>&#x3002;&#x800C;<code>sBundleHandler</code>&#x5B9E;&#x9645;&#x4E0A;&#x5173;&#x8054;&#x7684;&#x662F;&#x4E00;&#x4E2A;HandlerThread,&#x6240;&#x4EE5;&#xFF0C;<code>installTask</code>&#x662F;&#x8FD0;&#x884C;&#x5728;&#x5355;&#x72EC;&#x7684;&#x7EBF;&#x7A0B;&#x4E2D;&#x7684;&#x3002;</p>\n<p>&#x5728; <code>installTask</code> &#x4E2D;</p>\n<ul>\n<li>&#x8C03;&#x7528;&#x4E86;<code>call</code>&#x51FD;&#x6570;</li>\n<li>&#x5411;ui&#x7EBF;&#x7A0B;&#x63D0;&#x4EA4;&#x4E00;&#x4E2A;&#x4EFB;&#x52A1;&#xFF0C;&#x7528;&#x4E8E;&#x56DE;&#x8C03;<code>onFinished</code></li>\n</ul>\n<p>&#x5230;&#x76EE;&#x524D;&#x4E3A;&#x6B62;&#xFF0C;&#x7B2C;&#x4E00;&#x90E8;&#x5206;&#x5206;&#x6790;&#x5B8C;&#x6BD5;&#xFF0C;&#x6211;&#x4EEC;&#x8FDB;&#x5165;&#x7B2C;&#x4E8C;&#x90E8;&#x5206; <strong>&#x52A0;&#x8F7D;&#x8FC7;&#x7A0B;</strong> </p>\n<h1 id=\"&#x7B2C;&#x4E8C;&#x90E8;&#x5206;-&#x52A0;&#x8F7D;&#x8FC7;&#x7A0B;\">&#x7B2C;&#x4E8C;&#x90E8;&#x5206; &#x52A0;&#x8F7D;&#x8FC7;&#x7A0B;</h1>\n<p>&#x9700;&#x8981;&#x6CE8;&#x610F;&#x7684;&#x662F;&#xFF0C;<strong>&#x7B2C;&#x4E8C;&#x90E8;&#x5206;&#x6574;&#x4F53;&#x662F;&#x8FD0;&#x884C;&#x5728; HandlerThread &#x4E2D;&#x7684;&#x3002;</strong></p>\n<p>&#x56DE;&#x987E;&#x4E00;&#x4E0B;&#x7B2C;&#x4E8C;&#x90E8;&#x5206;&#x7684;&#x8FD0;&#x884C;&#x65F6;&#x5E8F;</p>\n<p><img src=\"bundle_load_part_2_img.svg\" alt=\"\"></p>\n<h2 id=\"call\">call</h2>\n<pre><code>call(){\n    //...\n    if (FileUtils.getUsableSpace(Environment.getDataDirectory()) &gt;= 5) {\n        //has enough space\n        if(AtlasBundleInfoManager.instance().isInternalBundle(bundleName)) {\n            bundle = installBundleFromApk(bundleName);\n            if (bundle != null) {\n                ((BundleImpl) bundle).optDexFile();\n            }\n        }\n    } else {\n        throw new LowDiskException(&quot;no enough space&quot;);\n    }\n    //...\n}\n</code></pre><p>&#x8FD9;&#x91CC;&#x6709;&#x4E24;&#x4E2A;&#x5224;&#x65AD;&#x6761;&#x4EF6;</p>\n<ul>\n<li>&#x5269;&#x4F59;&#x5B58;&#x50A8;&#x7A7A;&#x95F4;&#x6EE1;&#x8DB3;</li>\n<li>&#x662F;&#x5185;&#x7F6E;bundle</li>\n</ul>\n<p>&#x5F53;&#x4E24;&#x4E2A;&#x6761;&#x4EF6;&#x90FD;&#x6EE1;&#x8DB3;&#x65F6;&#xFF0C;&#x6267;&#x884C;bundle&#x7684;&#x5B89;&#x88C5;&#x548C;optDexFile&#x64CD;&#x4F5C;&#x3002;</p>\n<p>installBundleFromApk &#x53C8;&#x8C03;&#x7528;&#x4E86; installNewBundle&#x65B9;&#x6CD5;&#xFF0C;&#x76F4;&#x63A5;&#x770B;&#x7B2C;9&#x6B65; - installNewBundle &#x7684;&#x5B9E;&#x73B0;&#x3002;</p>\n<h2 id=\"installnewbundle\">installNewBundle</h2>\n<p>Framework.java</p>\n<pre><code>static BundleImpl installNewBundle(final String location, final InputStream in)throws BundleException {\n    //...\n    BundleListing.BundleInfo info = AtlasBundleInfoManager.instance().getBundleInfo(location);\n    BundleImpl bundle = new BundleImpl(bundleDir, location, new BundleContext(), null, file,version,true,-1);\n    return bundle;\n}\n</code></pre><p>&#x51FD;&#x6570;&#x5F88;&#x7B80;&#x5355;&#xFF0C;&#x83B7;&#x53D6;bundle&#x7684;&#x4FE1;&#x606F;&#xFF0C;&#x4E4B;&#x540E;&#x6784;&#x9020;&#x4E00;&#x4E2A;BundleImpl&#x5BF9;&#x8C61;&#x3002;</p>\n<p>&#x6709;&#x4E24;&#x4E2A;&#x53C2;&#x6570;&#x9700;&#x8981;&#x6CE8;&#x610F;&#x4E00;&#x4E0B;</p>\n<table>\n<thead>\n<tr>\n<th>&#x53C2;&#x6570;</th>\n<th>&#x8BF4;&#x660E;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>bundleDir</td>\n<td>/data/data/com.taobao.demo/files/storage/com.taobao.secondbundle</td>\n</tr>\n<tr>\n<td>in</td>\n<td>&#x6307;&#x5411; lib/armeabi/libcom_taobao_secondbundle.so</td>\n</tr>\n</tbody>\n</table>\n<h2 id=\"bundleimpl\">BundleImpl</h2>\n<p>&#x6765;&#x770B;BundleImpl&#x7684;&#x6784;&#x9020;&#x51FD;&#x6570;</p>\n<p>BundleImpl.java</p>\n<pre><code>BundleImpl(final File bundleDir, final String location, final BundleContext context, final InputStream stream,...) throws BundleException, IOException{\n        if (stream != null) {\n            this.archive = new BundleArchive(location,bundleDir, stream,version, dexPatchVersion);\n        } \n\n        if (autoload) {\n            resolveBundle();\n            Framework.bundles.put(location, this);\n        }\n}\n</code></pre><p>&#x9996;&#x5148;&#x521B;&#x5EFA;&#x4E86;&#x4E00;&#x4E2A;BundleArchive&#x5BF9;&#x8C61;&#xFF0C;bundleArchive&#x6301;&#x6709;bundleDir&#x548C;InputStream&#x7684;&#x5F15;&#x7528;&#xFF0C;&#x7528;&#x6765;&#x505A;dexOpt&#x7684;( <strong>? todo</strong> )&#xFF0C;&#x6682;&#x65F6;&#x4E0D;&#x5173;&#x6CE8;&#xFF0C;&#x5F80;&#x4E0B;&#x8D70;</p>\n<h2 id=\"resolvebundle\">resolveBundle</h2>\n<p>BundleImpl.java</p>\n<pre><code class=\"lang-java\">\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">private</span> <span class=\"hljs-keyword\">synchronized</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">resolveBundle</span><span class=\"hljs-params\">()</span> <span class=\"hljs-keyword\">throws</span> BundleException </span>{\n        <span class=\"hljs-comment\">//...</span>\n        <span class=\"hljs-keyword\">if</span> ( <span class=\"hljs-keyword\">this</span>.classloader == <span class=\"hljs-keyword\">null</span>){\n            <span class=\"hljs-comment\">// create the bundle classloader</span>\n            List&lt;String&gt; dependencies = AtlasBundleInfoManager.instance().getDependencyForBundle(location);\n            String nativeLibDir = getArchive().getCurrentRevision().getRevisionDir().getAbsolutePath()+<span class=\"hljs-string\">&quot;/lib&quot;</span>+<span class=\"hljs-string\">&quot;:&quot;</span>\n                    + RuntimeVariables.androidApplication.getApplicationInfo().nativeLibraryDir+<span class=\"hljs-string\">&quot;:&quot;</span>\n                    +System.getProperty(<span class=\"hljs-string\">&quot;java.library.path&quot;</span>);\n            <span class=\"hljs-keyword\">if</span>(dependencies!=<span class=\"hljs-keyword\">null</span>) {\n                <span class=\"hljs-keyword\">for</span> (String str : dependencies) {\n                    BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(str);\n                    <span class=\"hljs-keyword\">if</span> (impl != <span class=\"hljs-keyword\">null</span>) {\n                        nativeLibDir += <span class=\"hljs-string\">&quot;:&quot;</span>;\n                        File dependencyLibDir = <span class=\"hljs-keyword\">new</span> File(impl.getArchive().getCurrentRevision().getRevisionDir(), <span class=\"hljs-string\">&quot;lib&quot;</span>);\n                        nativeLibDir += dependencyLibDir;\n                    }\n                }\n            }\n            <span class=\"hljs-keyword\">this</span>.classloader = <span class=\"hljs-keyword\">new</span> BundleClassLoader(<span class=\"hljs-keyword\">this</span>,dependencies,nativeLibDir);\n        }\n\n        <span class=\"hljs-comment\">// notify the listeners</span>\n        Framework.notifyBundleListeners(<span class=\"hljs-number\">0</span> <span class=\"hljs-comment\">/*LOADED*/</span>, <span class=\"hljs-keyword\">this</span>);\n    }\n</code></pre>\n<p>&#x4E3A;bundle&#x521B;&#x5EFA;&#x4E00;&#x4E2A;classloader&#xFF0C;&#x5728;&#x521B;&#x5EFA;classloader&#x7684;&#x8FC7;&#x7A0B;&#x4E2D;</p>\n<ul>\n<li>&#x6307;&#x5B9A;bundle&#x81EA;&#x8EAB;&#x4F9D;&#x8D56;so&#x7684;&#x8DEF;&#x5F84;</li>\n<li>&#x6307;&#x5B9A;&#x4F9D;&#x8D56;bundle&#x6240;&#x4F9D;&#x8D56;so&#x7684;&#x8DEF;&#x5F84;</li>\n</ul>\n<p>&#x6BD4;&#x5982;&#x5728;demo&#x4E2D; &#xFF0C;nativeLibDir&#x7684; &#x503C;&#x4E3A; /data/user/0/com.taobao.demo/files/storage/com.taobao.secondbundle/version.1/lib:/data/app/com.taobao.demo-1/lib/x86:/vendor/lib:/system/lib</p>\n<p>&#x521B;&#x5EFA;&#x5B8C;BundlerClassLoader&#x540E;&#xFF0C;&#x5728;&#x6700;&#x540E;&#x4E00;&#x884C;&#x8FDB;&#x884C;&#x56DE;&#x8C03;&#xFF0C;&#x8FD9;&#x91CC;&#x7684;&#x56DE;&#x8C03;&#x5B9E;&#x73B0;&#x7C7B;&#x662F; BundleLifecycleHandler</p>\n<p>BundleLifecycleHandler.java</p>\n<pre><code> public void bundleChanged(final BundleEvent event){\n        switch (event.getType()) {\n            case 0:/* LOADED */\n                loaded(event.getBundle());\n}\n</code></pre><h2 id=\"loaded\">loaded</h2>\n<pre><code>private void loaded(Bundle bundle) { long time = System.currentTimeMillis();\n        BundleImpl b = (BundleImpl) bundle;\n        DelegateResources.addBundleResources(\n            b.getArchive().getArchiveFile().getAbsolutePath()\n        );\n}\n</code></pre><p><strong>todo</strong> &#x8D44;&#x6E90;&#x5904;&#x7406;&#x5B9E;&#x73B0;&#x8BF4;&#x660E;</p>\n<p>&#x56DE;&#x5230;&#x7B2C;10&#x6B65;</p>\n<p>BundleImpl.java</p>\n<pre><code>BundleImpl(final File bundleDir, final String location...) {\n    //...\n    resolveBundle();\n    Framework.bundles.put(location, this);    \n}\n</code></pre><p>&#x5728;resolveBundle&#x51FD;&#x6570;&#x6267;&#x884C;&#x5468;&#x671F;&#x5185;&#xFF0C;&#x4E3B;&#x8981;&#x5B8C;&#x6210;&#x4E86;&#x4E24;&#x4EF6;&#x4E8B;</p>\n<ul>\n<li>&#x4E3A;bundle&#x521B;&#x5EFA;&#x4E86;&#x72EC;&#x7ACB;&#x7684;ClassLoader</li>\n<li>&#x5C06;bundle&#x4E2D;&#x7684;&#x8D44;&#x6E90;&#x6DFB;&#x52A0;&#x5230;Resource&#x4E0A;</li>\n</ul>\n<p>&#x7B2C;&#x4E8C;&#x884C;&#x51FD;&#x6570;&#x5C06;bundle&#x7684;&#x4FE1;&#x606F;&#x52A0;&#x5165;&#x5230;&#x5DF2;&#x52A0;&#x8F7D;&#x7684;&#x5217;&#x8868;&#x4E2D;&#x3002;</p>\n<p>&#x5B8C;&#x6210;&#x4E4B;&#x540E;&#xFF0C;&#x56DE;&#x5230;&#x7B2C;8&#x6B65;&#xFF0C;&#x6267;&#x884C;optDexFile&#x65B9;&#x6CD5;&#x3002;</p>\n<h3 id=\"optdexfile\">optDexFile</h3>\n<p>&#x3002;&#x3002;&#x3002;</p>\n<h1 id=\"&#x7B2C;&#x4E09;&#x90E8;&#x5206;-&#x521D;&#x59CB;&#x5316;&#x8FC7;&#x7A0B;\">&#x7B2C;&#x4E09;&#x90E8;&#x5206; &#x521D;&#x59CB;&#x5316;&#x8FC7;&#x7A0B;</h1>\n<p><strong>&#x6574;&#x4E2A;&#x7B2C;&#x4E09;&#x90E8;&#x5206;&#x8FD0;&#x884C;&#x5728; UI &#x7EBF;&#x7A0B;&#x4E2D;</strong></p>\n<p>bundle&#x52A0;&#x8F7D;&#x5B8C;&#x6210;&#x540E;&#xFF0C;&#x7B2C;7&#x6B65;&#xFF0C;&#x5728;UI&#x7EBF;&#x7A0B;&#x4E2D;&#x56DE;&#x8C03;&#x4E86;&#x5B8C;&#x6210;&#x7684;&#x63A5;&#x53E3;&#xFF0C;&#x8C03;&#x7528;&#x4E86;<code>startbundle</code>&#x65B9;&#x6CD5;&#x53C8;&#x7ECF;&#x8FC7;&#x8F97;&#x8F6C;&#x8C03;&#x7528;&#xFF0C;&#x5230;&#x4E86;BundleLifecycleHandler&#x7684;<code>startd</code>&#x65B9;&#x6CD5;&#x4E2D;&#x3002;</p>\n<p>BundleLifecycleHandler.java</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">private</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">started</span><span class=\"hljs-params\">(Bundle bundle)</span></span>{\n    BundleImpl b = (BundleImpl) bundle;\n    BundleListing.BundleInfo info = AtlasBundleInfoManager.instance().getBundleInfo(b.getLocation());\n    <span class=\"hljs-comment\">//...</span>\n    String appClassName = info.getApplicationName();\n    Application app = newApplication(appClassName, b.getClassLoader());\n    app.onCreate();\n}\n</code></pre>\n<p>&#x5728;&#x7B2C;6&#x884C;&#x6784;&#x9020;&#x51FA;bundle&#x4E2D;&#x6CE8;&#x518C;&#x7684;application&#x5BF9;&#x8C61;&#xFF0C;&#x4E4B;&#x540E;&#x6267;&#x884C;application&#x7684;onCreate&#x65B9;&#x6CD5;&#x3002;&#x5BF9;&#x4E8E;appliation&#x6765;&#x8BF4;&#xFF0C;&#x4F3C;&#x4E4E;&#x8FD8;&#x5DEE;&#x4E00;&#x4E2A;&#x5173;&#x952E;&#x7684;<code>attachBaseContext</code>&#x7684;&#x5165;&#x53E3;&#x51FD;&#x6570;&#x8C03;&#x7528;&#xFF0C;&#x6211;&#x4EEC;&#x63A5;&#x7740;&#x770B;&#x6784;&#x9020;&#x8FC7;&#x7A0B;&#x3002;</p>\n<p>BundleLifecycleHandler.java</p>\n<pre><code>protected static Application newApplication(String applicationClassName, ClassLoader cl) throws ApplicationInitException {\n    final Class&lt;?&gt; applicationClass = cl.loadClass(applicationClassName);\n    Application app = (Application) applicationClass.newInstance();\n    AtlasHacks.Application_attach.invoke(app, RuntimeVariables.androidApplication);\n    return app;  \n}\n</code></pre><p>&#x9996;&#x5148;&#xFF0C;&#x6839;&#x636E;&#x7C7B;&#x540D;&#x52A0;&#x8F7D;&#x5BF9;&#x5E94;&#x7684;class&#xFF0C;&#x4E4B;&#x540E;&#x53CD;&#x5C04;&#x6267;&#x884C;applciation&#x7684;attach&#x65B9;&#x6CD5;&#x3002;</p>\n<p>&#x5728;<a href=\"../atlas_start/atlas_start_2.html\">Atlas&#x4E4B;&#x542F;&#x52A8;&#x8FC7;&#x7A0B;(&#x4E8C;)</a>&#x4E0B;&#x4E2D;&#xFF0C;&#x89E3;&#x91CA;&#x8FC7;&#xFF0C;application&#x7684;attach&#x65B9;&#x6CD5;&#x6700;&#x7EC8;&#x4F1A;&#x8C03;&#x7528;&#x5230;<code>attachBaseContext</code>&#x65B9;&#x6CD5;&#x3002;</p>\n<p>&#x6700;&#x540E;&#xFF0C;&#x5927;&#x6982;&#x770B;&#x4E00;&#x4E0B;DelegateClassLoader&#x52A0;&#x8F7D;bundle&#x4E2D;class&#x7684;&#x8FC7;&#x7A0B;&#x3002;</p>\n<p>DelegateClassLoader.java</p>\n<pre><code>protected Class&lt;?&gt; findClass(String className) throws ClassNotFoundException {\n    Class&lt;?&gt; clazz = loadFromInstalledBundles(className,false);\n    //...\n    return clazz;\n}\n\nstatic Class&lt;?&gt; loadFromInstalledBundles(String className,boolean safe)\n            throws ClassNotFoundException {\n    String bundleName = AtlasBundleInfoManager.instance().getBundleForComponet(className);\n    BundleImpl bundle = (BundleImpl) Atlas.getInstance().getBundle(bundleName);\n    //...\n    ClassLoader classloader = bundle.getClassLoader();\n    Class&lt;?&gt;  clazz = classloader.loadClass(className);\n    return clazz;\n}\n</code></pre><p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;classloader&#x5148;&#x4ECE;bundle&#x4E0A;&#x53BB;&#x627E;&#x7684;&#x3002;&#x800C;<code>loadFromInstalledBundles</code>&#x903B;&#x8F91;&#x5982;&#x4E0B;:</p>\n<ol>\n<li>&#x4ECE;<code>AtlasBundleInfoManager</code>&#x4E0A;&#x5DF2;&#x52A0;&#x8F7D;&#x7684;&#x5217;&#x8868;&#x4E2D;&#x627E;&#x5230;&#x5BF9;&#x5E94;bunde(&#x5728;&#x7B2C;&#x5728;&#x7B2C;10&#x6B65;&#x4E2D;&#x6DFB;&#x52A0;)</li>\n<li>&#x4ECE;&#x5BF9;&#x5E94;bundle&#x4E0A;&#x7684;classloader&#x4E0A;&#x52A0;&#x8F7D;&#x5BF9;&#x5E94;&#x7684;class&#x3002;</li>\n</ol>\n<hr>\n<p>&#x5230;&#x8FD9;&#x91CC;&#x4E3A;&#x6B62;&#xFF0C;&#x6574;&#x4E2A;bundle&#x7684;&#x52A0;&#x8F7D;&#x3001;&#x521D;&#x59CB;&#x5316;&#x8FC7;&#x7A0B;&#x5206;&#x6790;&#x5B8C;&#x6BD5;&#x3002;</p>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"../atlas_start/atlas_start_2.html\" class=\"navigation navigation-prev navigation-unique\" aria-label=\"Previous page: Atlas之启动过程(二)\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"Atlas之Bundle加载过程\",\"time\":\"2017-05-05T10:00:00.000Z\",\"level\":\"1.6.4\",\"depth\":2,\"previous\":{\"title\":\"Atlas之启动过程(二)\",\"level\":\"1.6.3\",\"depth\":2,\"path\":\"code_read/atlas_start/atlas_start_2.md\",\"ref\":\"code_read/atlas_start/atlas_start_2.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"code_read/atlas_bundle_load/atlas_bundle_load.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"../..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../../gitbook/gitbook.js\"></script>\n    <script src=\"../../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/code_read/atlas_bundle_load/bundle_load.uml",
    "content": "@startuml\nautonumber\n\n-> ActivityGroupDelegate : startChildActivity\nActivityGroupDelegate -> ActivityGroupDelegate : execStartChild\\nActivityInternal\nActivityGroupDelegate -> ActivityGroupDelegate : asyncStartActivity\n\nActivityGroupDelegate -> BundleUtil : checkBundleArray\\nStateAsync\n\nBundleUtil -> BundleInstaller : installTransitively\\nAsync\nBundleInstaller -> BundleInstaller : installBundleInternal\nBundleInstaller -> BundleInstaller : deliveryTask\nBundleInstaller --> BundleInstaller : call\n\nBundleInstaller --> Framework : installNewBundle\n\nFramework --> BundleImpl : new\nBundleImpl --> BundleImpl : resolveBundle \n\nBundleImpl --> BundleClassLoader : new \nBundleImpl --> BundleLifecycleHandler : loaded\nBundleLifecycleHandler --> DelegateResources : addBundleResources\n\nFramework --> BundleImpl : optDexFile\n\nBundleInstaller -> BundleImpl : startBundle\nBundleImpl -> BundleLifecycleHandler : started\nBundleLifecycleHandler -> Application : attach\nBundleLifecycleHandler -> Application : onCreate\n\n\n@enduml\n"
  },
  {
    "path": "atlas-docs/_book/code_read/atlas_bundle_load/bundle_load_part_2.uml",
    "content": "@startuml\nautonumber 8\n\n\nBundleInstaller --> BundleInstaller : call\n\nBundleInstaller --> Framework : installNewBundle\n\nFramework --> BundleImpl : new\nBundleImpl --> BundleImpl : resolveBundle \n\nBundleImpl --> BundleClassLoader : new \nBundleImpl --> BundleLifecycleHandler : loaded\nBundleLifecycleHandler --> DelegateResources : addBundleResources\n\nFramework --> BundleImpl : optDexFile\n\n@enduml\n"
  },
  {
    "path": "atlas-docs/_book/code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>Atlas之Gradle配置 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"../atlas_start/atlas_start_1.html\" />\n    \n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../../\">\n            \n                <a href=\"../../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../../guide-for-use/\">\n            \n                <a href=\"../../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../../update/\">\n            \n                <a href=\"../../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../../update/principle.html\">\n            \n                <a href=\"../../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../../update/dexpatch.html\">\n            \n                <a href=\"../../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../../update/guide.html\">\n            \n                <a href=\"../../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../../faq/question.html\">\n            \n                <a href=\"../../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../../faq/help.html\">\n            \n                <a href=\"../../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../../faq/variant.html\">\n            \n                <a href=\"../../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter active\" data-level=\"1.6.1\" data-path=\"atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"../..\" >Atlas之Gradle配置</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"&#x6982;&#x8FF0;\">&#x6982;&#x8FF0;</h1>\n<p>Atlas&#x4E00;&#x4E2A;&#x8FD0;&#x884C;&#x4E8E;Android&#x7CFB;&#x7EDF;&#x4E0A;&#x7684;&#x4E00;&#x4E2A;&#x5BB9;&#x5668;&#x5316;&#x6846;&#x67B6;&#x3002;&#x4E3A;&#x4E86;&#x5B9E;&#x73B0;&#x8FD9;&#x4E00;&#x76EE;&#x6807;&#xFF0C;&#x5728;&#x7F16;&#x8BD1;&#x5668;&#x548C;&#x8FD0;&#x884C;&#x671F;&#xFF0C;Atlas&#x90FD;&#x505A;&#x4E86;&#x5F88;&#x591A;&#x5DE5;&#x4F5C;&#x3002;&#x672C;&#x6587;&#x662F;&#x4E00;&#x4E2A;&#x5165;&#x95E8;&#x7EA7;&#x522B;&#x7684;&#x6587;&#x7AE0;&#xFF0C;&#x68B3;&#x7406;&#x4ECE;gradle&#x914D;&#x7F6E;&#x5230;&#x751F;&#x6210;&#x6700;&#x7EC8;apk&#x7684;&#x671F;&#x95F4;&#xFF0C;Atlas&#x6846;&#x67B6;&#x5230;&#x5E95;&#x641E;&#x4E86;&#x54EA;&#x4E9B;&#x4E8B;&#x60C5;&#x3002;</p>\n<p>&#x4EE3;&#x7801;&#x4EE5; <a href=\"https://github.com/alibaba/atlas/tree/master/atlas-demo\" target=\"_blank\">&#x5B98;&#x65B9;demo</a> &#x4E3A;&#x4F8B;&#x3002;</p>\n<h1 id=\"gradle&#x5206;&#x6790;\">gradle&#x5206;&#x6790;</h1>\n<p>gradle&#x90E8;&#x5206;&#xFF0C;&#x6211;&#x4EEC;&#x53EA;&#x7528;&#x770B;&#x4E3B;&#x5DE5;&#x7A0B;app&#x548C;bundle&#x7684;&#x914D;&#x7F6E;&#x5C31;&#x53EF;&#x4EE5;&#x4E86;&#x3002;</p>\n<h2 id=\"app\">app</h2>\n<p>build.gradle</p>\n<pre><code class=\"lang-gradle\"># &#x7B2C;&#x4E00;&#x90E8;&#x5206;\nandroid {\n    <span class=\"hljs-comment\">//...</span>\n}\n\n# &#x7B2C;&#x4E8C;&#x90E8;&#x5206;\natlas {\n    <span class=\"hljs-comment\">//...</span>\n}\n\n# &#x7B2C;&#x4E09;&#x90E8;&#x5206;\n<span class=\"hljs-keyword\">dependencies</span> {\n    <span class=\"hljs-keyword\">compile</span> xxx\n    bundleCompile xxx\n}\n</code></pre>\n<p>&#x53EF;&#x4EE5;&#x5F88;&#x6E05;&#x695A;&#x7684;&#x770B;&#x5230;&#xFF0C;gradle&#x7684;&#x914D;&#x7F6E;&#x4E3B;&#x8981;&#x5206;&#x4E3A;&#x4E09;&#x5927;&#x5757;&#xFF0C;&#x4F9D;&#x6B21;&#x662F;&#x6807;&#x51C6;&#x7684;android&#x63D2;&#x4EF6;&#x914D;&#x7F6E;&#x3001;atlas&#x63D2;&#x4EF6;&#x7684;&#x914D;&#x7F6E;&#xFF0C;&#x4EE5;&#x53CA;&#x4F9D;&#x8D56;&#x7BA1;&#x7406;&#x90E8;&#x5206;&#x3002;&#x6211;&#x4EEC;&#x91CD;&#x70B9;&#x770B;&#x6700;&#x540E;&#x4E24;&#x4E2A;&#x90E8;&#x5206;&#x3002;</p>\n<h3 id=\"atlas&#x63D2;&#x4EF6;&#x914D;&#x7F6E;\">Atlas&#x63D2;&#x4EF6;&#x914D;&#x7F6E;</h3>\n<p>atlas&#x63D2;&#x4EF6;&#x6709;&#x5F88;&#x591A;&#x53C2;&#x6570;&#xFF0C;&#x8FD9;&#x91CC;&#x53EA;&#x5173;&#x6CE8;demo&#x4E2D;&#x51FA;&#x73B0;&#x7684;&#x91CD;&#x70B9;&#x53C2;&#x6570;&#xFF0C;&#x5176;&#x5B83;&#x8BBE;&#x7F6E;&#x5927;&#x5BB6;&#x53EF;&#x4EE5;&#x67E5;&#x770B;<a href=\"http://atlas.taobao.org/docs/guide-for-use/guide_for_build.html\" target=\"_blank\">&#x5B98;&#x65B9;&#x6587;&#x6863;</a>&#x3002;</p>\n<pre><code>atlas {\n    atlasEnabled true\n    tBuildConfig {\n        autoStartBundles = [&apos;com.taobao.firstbundle&apos;] \n        outOfApkBundles = [&apos;remotebundle&apos;]\n        preLaunch = &apos;com.taobao.demo.DemoPreLaunch&apos;\n    }\n}\n</code></pre><p><strong>atlasEnabled</strong>  &#x5F00;&#x542F;atlas&#x63D2;&#x4EF6;&#x7684;&#x5F00;&#x5173;&#xFF0C;&#x5728;&#x7F16;&#x8BD1;&#x671F;&#x4F1A;&#x505A;&#x5F88;&#x591A;&#x4E8B;&#x60C5;</p>\n<ul>\n<li>merge&#x5404;&#x4E2A;bundle&#x7684;manifest&#x5230;app&#x4E2D;</li>\n<li>&#x5C06;bunde&#x7684;&#x8D44;&#x6E90;&#x8FDB;&#x884C;&#x5206;&#x6BB5;</li>\n<li>&#x4E3A;&#x56DB;&#x5927;&#x7EC4;&#x4EF6;&#x9884;&#x7559;&#x4E00;&#x4E9B;&#x5751;&#x4F4D;</li>\n<li>&#x751F;&#x6210;&#x4E00;&#x4E9B;class&#xFF0C;&#x8BB0;&#x5F55;bundle&#x7684;&#x5173;&#x952E;&#x4FE1;&#x606F; </li>\n<li>&#x6253;&#x5305;bundle&#x7B49;&#x7B49;</li>\n</ul>\n<p><strong>autoStartBundles</strong> &#x6307;&#x5B9A;&#x7B2C;&#x4E00;&#x4E2A;&#x9700;&#x8981;&#x542F;&#x52A8;&#x7684;bundle&#xFF0C;&#x5728;Atlas&#x6846;&#x67B6;&#x521D;&#x59CB;&#x5316;&#x5B8C;&#x6BD5;&#x540E;&#xFF0C;&#x4F1A;&#x6267;&#x884C;&#x8FD9;&#x91CC;&#x8FD9;&#x91CC;&#x914D;&#x7F6E;bundle&#x7684;&#x4EE3;&#x7801;&#x3002;</p>\n<p><strong>preLaunch</strong> &#x81EA;&#x5B9A;&#x4E49;&#x521D;&#x59CB;&#x5316;&#x5165;&#x53E3;&#xFF0C;&#x8FD9;&#x4E2A;&#x7C7B;&#x9700;&#x8981;&#x5B9E;&#x73B0;<code>AtlasPreLauncher</code>&#x63A5;&#x53E3;&#xFF0C;&#x56DE;&#x8C03;&#x65F6;&#x673A;&#x662F;&#x5728;atlas&#x5BF9;&#x7CFB;&#x7EDF;&#x8FDB;&#x884C;hack&#x4E4B;&#x540E;&#xFF0C;atlas&#x6846;&#x67B6;&#x5F00;&#x59CB;&#x521D;&#x59CB;&#x5316;&#x4E4B;&#x524D;&#x3002;</p>\n<h3 id=\"&#x4F9D;&#x8D56;&#x7BA1;&#x7406;&#x914D;&#x7F6E;\">&#x4F9D;&#x8D56;&#x7BA1;&#x7406;&#x914D;&#x7F6E;</h3>\n<p>&#x63A5;&#x7740;&#x770B;&#x4F9D;&#x8D56;&#x914D;&#x7F6E;&#x90E8;&#x5206;</p>\n<pre><code>atlas {\n    tBuildConfig {\n        outOfApkBundles = [&apos;remotebundle&apos;]\n    }\n}\n\ndependencies {\n    compile fileTree(dir: &apos;libs&apos;, include: [&apos;*.jar&apos;])\n    compile(&apos;com.taobao.android:atlas_core:5.0.7@aar&apos;) {\n        transitive = true\n    }\n\n    compile project(&apos;:middlewarelibrary&apos;)\n    compile project(&apos;:splashscreen&apos;)\n    compile project(&apos;:activitygroupcompat&apos;)\n\n    bundleCompile project(&apos;:firstbundle&apos;)\n    bundleCompile project(&apos;:secondbundle&apos;)\n    bundleCompile project(&apos;:remotebundle&apos;)\n    bundleCompile project(&apos;:publicbundle&apos;)\n\n    compile &apos;com.android.support:appcompat-v7:25.1.0&apos;\n}\n</code></pre><p><code>dependencies</code>&#x4E3B;&#x8981;&#x5206;&#x4E3A;&#x4E09;&#x4E2A;&#x90E8;&#x5206;</p>\n<ul>\n<li>comile xxx     </li>\n<li>bundleCompile xxx</li>\n<li>outOfApkBundles =[&apos;xxx&apos;]</li>\n</ul>\n<p><strong>compile</strong> : &#x5E38;&#x89C4;&#x7684;&#x6253;&#x5305;&#x914D;&#x7F6E;&#xFF0C;&#x4F1A;&#x5C06;&#x4F9D;&#x8D56;&#x4EE3;&#x7801;&#x6253;&#x5165;&#x5230;dex&#x4E2D;&#x53BB;</p>\n<p><strong>bundleCompile</strong> : atlas &#x7684;&#x914D;&#x7F6E;&#x9879;&#xFF0C;&#x8868;&#x793A;apk&#x7684;bunde&#x4F9D;&#x8D56;&#xFF0C;&#x5373;apk&#x662F;&#x7531;&#x8FD9;&#x4E9B;bundle&#x5171;&#x540C;&#x7EC4;&#x6210;&#x3002;</p>\n<blockquote>\n<p>bundle&#x4E2D;&#x7684;&#x4EE3;&#x7801;&#x4E0D;&#x4F1A;&#x6253;&#x5165;dex&#x4E2D;&#x53BB;&#xFF0C;bundle&#x5C06;&#x4EE5;libxxx.so&#x6587;&#x4EF6;&#x7684;&#x5F62;&#x5F0F;&#xFF0C;&#x653E;&#x5728;apk&#x7684;lib&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x968F;&#x5305;&#x53D1;&#x5E03;</p>\n</blockquote>\n<p><strong>outOfApkBundles</strong> : &#x6307;&#x5B9A;&#x8FDC;&#x7A0B;bundle </p>\n<blockquote>\n<p>&#x6BD4;&#x5982;&#x5728;demo&#x4E2D;&#xFF0C;firstbundle&#x3001;secondbundle&#x3001;publicbundle &#x4F1A;&#x6253;&#x5165;apk&#x4E2D;&#xFF0C;&#x800C;remotebundle&#x4E0D;&#x4F1A;</p>\n</blockquote>\n<h3 id=\"&#x5C0F;&#x7ED3;\">&#x5C0F;&#x7ED3;</h3>\n<p><strong>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x5728;atlas&#x6846;&#x67B6;&#x4E2D;&#xFF0C;&#x4E3B;app&#x53EA;&#x662F;&#x4E00;&#x4E2A;&#x58F3;&#x5B50;&#xFF0C;&#x53EA;&#x662F;&#x7528;&#x6765;&#x914D;&#x7F6E;&#x6253;&#x5305;&#x53C2;&#x6570;&#x7684;</strong></p>\n<p>&#x6BD4;&#x5982;&#x5728;demo&#x4E2D;&#xFF0C;&#x914D;&#x7F6E;&#x4E86;&#x4EE5;&#x4E0B;&#x6253;&#x5305;&#x8BBE;&#x7F6E;</p>\n<ul>\n<li>app&#x7684;&#x5305;&#x540D;&#x3001;&#x7248;&#x672C;&#x53F7;...</li>\n<li>&#x9700;&#x8981;&#x6253;&#x5165;dex&#x7684;&#x4EE3;&#x7801; (appcompat...)</li>\n<li>&#x968F;&#x5305;&#x53D1;&#x5E03;&#x4F46;&#x662F;&#x4E0D;&#x6253;&#x5165;dex&#x7684;&#x4EE3;&#x7801; (firstbundle&#x3001;secondbundle&#x3001;publicbundle)</li>\n<li>&#x72EC;&#x7ACB;&#x6253;&#x5305;&#xFF0C;&#x7528;&#x4E8E;&#x540E;&#x7EED;&#x7684;&#x52A8;&#x6001;&#x4E0B;&#x53D1; (remotebundle)&#x3002;</li>\n</ul>\n<p>&#x76D7;&#x7528;&#x4E00;&#x5F20;&#x8001;&#x5927;&#x7684;&#x56FE;\n<img src=\"http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/fdb39a090aa3604aa999704eec1348eb.png\" alt=\"\"></p>\n<h2 id=\"bundle\">bundle</h2>\n<p>&#x4EE5;secondbundle&#x4E3A;&#x4F8B;&#xFF0C;&#x770B;&#x4E00;&#x4E0B;bundle&#x4E2D;gradle&#x7684;&#x914D;&#x7F6E;</p>\n<pre><code>apply plugin: &apos;com.android.library&apos;\napply plugin: &apos;com.taobao.atlas&apos;\n\natlas {\n    bundleConfig{\n        awbBundle true\n    }\n}\n\nandroid {\n    //...\n}\n\ndependencies {\n    compile fileTree(dir: &apos;libs&apos;, include: [&apos;*.jar&apos;])\n    compile project(&quot;:secondbundlelibrary&quot;);\n    providedCompile &apos;com.android.support:appcompat-v7:25.1.0&apos;\n    providedCompile &apos;com.android.support:support-v4:25.3.0&apos;\n    providedCompile &apos;com.android.support.constraint:constraint-layout:1.0.0-alpha8&apos;\n    providedCompile project(&apos;:middlewarelibrary&apos;)\n}\n</code></pre><p>&#x9996;&#x5148;<code>apply plugin: &apos;com.taobao.atlas&apos;</code>&#x548C;<code>awbBundle true</code>&#x8868;&#x660E;&#x542F;&#x7528;&#x4E86;atlas&#x63D2;&#x4EF6;&#xFF0C;&#x5E76;&#x5C06;&#x5F53;&#x524D;&#x6A21;&#x5757;&#x7F16;&#x8BD1;&#x6210;awb&#x5F62;&#x5F0F;&#x7684;bundle&#x4F9B;&#x4E3B;apk&#x4F7F;&#x7528;&#x3002;</p>\n<p>&#x800C;&#x5728; <code>dependencies</code> &#x4E2D;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x6709;&#x4E24;&#x79CD;&#x5F62;&#x5F0F;&#x7684;&#x4F9D;&#x8D56;</p>\n<table>\n<thead>\n<tr>\n<th>&#x4F9D;&#x8D56;&#x65B9;&#x5F0F;</th>\n<th>&#x8BF4;&#x660E;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>providedCompile</td>\n<td>&#x4E3B;dex&#x4E2D;&#x5DF2;&#x7ECF;&#x6253;&#x5165;&#x4E86;&#x5FC5;&#x8981;&#x7684;&#x516C;&#x7528;&#x4EE3;&#x7801;(appcompat&#x3001;middlewarelibrary)&#xFF0C;&#x5728;runtime&#x65F6;&#xFF0C;atlas&#x6846;&#x67B6;&#x4F1A;&#x81EA;&#x52A8;&#x627E;&#x5230;&#x4E3B;dex&#x4E2D;&#x7684;class&#x4F7F;&#x7528;&#xFF0C;&#x6240;&#x4EE5;secondbundl&#x5C31;&#x4E0D;&#x9700;&#x8981;&#x5728;&#x91CD;&#x590D;&#x6253;&#x5165;</td>\n</tr>\n<tr>\n<td>compile</td>\n<td>secondbundlelibrary&#x4E4B;&#x524D;&#x5E76;&#x6CA1;&#x6709;&#x6253;&#x5165;&#x4E3B;dex&#x4E2D;&#xFF0C;&#x56E0;&#x4E3A;&#x8FD9;&#x53EA;&#x662F;secondbundle&#x6240;&#x9700;&#x8981;&#x7684;&#x4F9D;&#x8D56;&#x3002;&#x6700;&#x7EC8;&#x4F1A;&#x5C06;secondbundle&#x548C;secondbundlelibrary&#x7684;&#x6253;&#x5728;&#x4E00;&#x4E2A;&#x540C;&#x4E00;&#x4E2A;dex&#x4E2D;&#xFF0C;&#x52A0;&#x4E0A;&#x4E24;&#x8005;&#x7684;&#x8D44;&#x6E90;&#xFF0C;&#x6210;&#x4E3A;&#x4E00;&#x4E2A;bundle</td>\n</tr>\n</tbody>\n</table>\n<h1 id=\"apk&#x7ED3;&#x6784;&#x5206;&#x6790;\">apk&#x7ED3;&#x6784;&#x5206;&#x6790;</h1>\n<p>&#x5728;&#x770B;&#x5B8C;gradle&#x7684;&#x914D;&#x7F6E;&#x4E4B;&#x540E;&#xFF0C;&#x6211;&#x4EEC;&#x53CD;&#x7F16;&#x8BD1;demo&#x7684;apk&#xFF0C;&#x770B;&#x4E00;&#x4E0B;&#x6700;&#x7EC8;&#x751F;&#x6210;&#x7684;&#x7ED3;&#x6784;&#x3002;</p>\n<h2 id=\"host\">host</h2>\n<h3 id=\"manifest\">manifest</h3>\n<p>&#x9996;&#x5148;&#xFF0C;&#x8D34;&#x4E00;&#x5F20;&#x53CD;&#x7F16;&#x8BD1;&#x540E;&#x7684;manifest</p>\n<p><img src=\"http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/d32dfd32381f11d4f64ce13ab772f9e4.png\" alt=\"\"></p>\n<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;manifest&#x4E2D;&#x7684;&#x5185;&#x5BB9;&#x5927;&#x6982;&#x5206;&#x4E3A;&#x4E09;&#x5927;&#x5757;</p>\n<ul>\n<li>host &#x7684;manifest&#x90E8;&#x5206;</li>\n<li>bunde &#x7684;&#x7684;manifet&#x90E8;&#x5206;</li>\n<li>&#x989D;&#x5916;&#x7684;&#x914D;&#x7F6E;</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>manifest</th>\n<th>&#x8BF4;&#x660E;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>host</td>\n<td>&#x5E38;&#x89C4;&#x7F16;&#x8BD1;&#x4EA7;&#x751F;&#x7684;&#x6E05;&#x5355;&#x6570;&#x636E;&#xFF0C;&#x5305;&#x62EC;app&#x5DE5;&#x7A0B;&#x81EA;&#x8EAB;&#x7684;&#x4EE3;&#x7801;&#x548C;compile&#x4F9D;&#x8D56;&#x7684;&#x4EE3;&#x7801;</td>\n</tr>\n<tr>\n<td>bundle</td>\n<td>bundle&#x90E8;&#x5206;&#x7684;&#x6E05;&#x5355;&#x6570;&#x636E;&#xFF0C;&#x5305;&#x62EC;&#x5728;app&#x5DE5;&#x7A0B;&#x4E2D;bundleCompile&#x7684;&#x4F9D;&#x8D56;&#x4EE3;&#x7801;&#x548C;bundle&#x81EA;&#x8EAB;compile&#x7684;&#x4F9D;&#x8D56;&#x4EE3;&#x7801;</td>\n</tr>\n<tr>\n<td>&#x914D;&#x7F6E;</td>\n<td>atlas&#x63D2;&#x4EF6;&#x5728;&#x7F16;&#x8BD1;&#x671F;&#x751F;&#x6210;&#x7684;&#x914D;&#x7F6E;&#x4FE1;&#x606F;&#x3002;&#x6BD4;&#x5982;&#x5728;gradle&#x4E2D;&#x914D;&#x7F6E;&#x4E86; <code>autoStartBundles = [&apos;com.taobao.firstbundle&apos;]</code>&#xFF0C;&#x7F16;&#x8BD1;&#x65F6;&#xFF0C;&#x4F1A;&#x5C06;firstbundle&#x4E2D;application&#x8DEF;&#x5F84;&#x5199;&#x5165;manifest&#x3002;&#x7A0B;&#x5E8F;&#x8FD0;&#x884C;&#x65F6;&#xFF0C;atlas&#x4F1A;&#x7B2C;&#x4E00;&#x4E2A;&#x6267;&#x884C;firstbundle&#x4E2D;DemoApplication&#x4E2D;&#x7684;&#x4EE3;&#x7801;</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"&#x4E3B;dex\">&#x4E3B;dex</h3>\n<p>&#x5206;&#x6790;&#x5B8C;manifest&#x4E4B;&#x540E;&#xFF0C;&#x6211;&#x4EEC;&#x770B;&#x4E00;&#x770B;host&#x7684;dex&#x6587;&#x4EF6;&#xFF0C;&#x770B;&#x4E00;&#x770B;&#x6709;&#x6CA1;&#x6709;&#x5BF9;java&#x4EE3;&#x7801;&#x52A8;&#x624B;&#x811A;&#x3002;</p>\n<p><img src=\"http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/51bc1436339313814e40bedfb466f53f.png\" alt=\"\"></p>\n<p>&#x4E4D;&#x770B;&#x4E4B;&#x4E0B;&#xFF0C;&#x4F3C;&#x4E4E;&#x5E76;&#x6CA1;&#x6709;&#x4EC0;&#x4E48;&#x4E0D;&#x59A5;&#x3002;&#x4F46;&#x662F;&#xFF0C;&#x7EC6;&#x5FC3;&#x7684;&#x540C;&#x5B66;&#x53EF;&#x80FD;&#x53D1;&#x73B0;&#x4E86;&#xFF0C;&#x5C11;&#x4E86;bundle&#x90E8;&#x5206;&#x7684;&#x4EE3;&#x7801;&#x3002;</p>\n<p>&#x7ED3;&#x5408;app&#x5DE5;&#x7A0B;gradle&#x7684;&#x914D;&#x7F6E;&#xFF0C;&#x6211;&#x4EEC;&#x53D1;&#x73B0;&#x4EE5;compile&#x5F00;&#x5934;&#x7684;&#x4F9D;&#x8D56;(middleware&#x3001;utils&#x3001;update),&#x90FD;&#x662F;&#x6B63;&#x5E38;&#x5C06;java&#x4EE3;&#x7801;&#x6253;&#x5165;dex&#x4E2D;&#x3002;&#x800C;&#x4EE5;budleCompile&#x5F00;&#x5934;&#x7684;&#x4F9D;&#x8D56;(firstbundle&#x3001;secondbundle)&#xFF0C;&#x4ED6;&#x4EEC;&#x7684;&#x4EE3;&#x7801;&#x5E76;&#x6CA1;&#x6709;&#x5728;dex&#x4E2D;&#x3002;</p>\n<p><strong>&#x90A3;&#x4E48;&#xFF0C;bundle&#x7684;&#x4EE3;&#x7801;&#x5728;&#x54EA;&#x91CC;&#x5462;&#xFF1F;</strong> &#x6211;&#x4EEC;&#x63A5;&#x7740;&#x5F80;&#x4E0B;&#x770B;</p>\n<h2 id=\"bundle\">bundle</h2>\n<p>bundle&#x7684;&#x5B58;&#x653E;&#x4F4D;&#x7F6E;</p>\n<p><img src=\"http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/ea15cdcaac2a617e7e1c7f76eade1edc.png\" alt=\"\"></p>\n<p>bundle&#x7684;&#x4EE3;&#x7801;&#x548C;&#x8D44;&#x6E90;&#x5176;&#x5B9E;&#x72EC;&#x7ACB;&#x6253;&#x6210;&#x4E86;&#x4E00;&#x4E2A;apk&#xFF0C;&#x653E;&#x5728;&#x4E86;apk&#x7684;lib&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x5728;&#x8FD0;&#x884C;&#x65F6;&#x8FDB;&#x884C;&#x52A8;&#x6001;&#x52A0;&#x8F7D;&#x3002;</p>\n<h3 id=\"manifest\">manifest</h3>\n<p><strong>bundle&#x4E2D;&#x7684;manifest&#x4E2D;&#x6CA1;&#x6709;&#x4EFB;&#x4F55;&#x4E1C;&#x897F;&#xFF0C;</strong> &#x611F;&#x5174;&#x8DA3;&#x7684;&#x540C;&#x5B66;&#x53EF;&#x4EE5;&#x81EA;&#x884C;&#x9A8C;&#x8BC1;&#x3002;</p>\n<blockquote>\n<p>&#x8FD9;&#x90E8;&#x5206;&#x5185;&#x5BB9;&#x5728;&#x7F16;&#x8BD1;&#x671F;&#x5DF2;&#x7ECF;&#x5199;&#x5230;app&#x7684;manifest&#x4E2D;&#x4E86;&#xFF0C;&#x8FD9;&#x4E5F;&#x662F; <strong>&#x7EC4;&#x4EF6;&#x5316;&#x548C;&#x63D2;&#x4EF6;&#x5316;</strong> &#x7684;&#x533A;&#x522B;&#x4E4B;&#x4E00;</p>\n</blockquote>\n<h3 id=\"dex\">dex</h3>\n<p>&#x6700;&#x540E;&#x786E;&#x8BA4;&#x4E00;&#x4E0B;&#x4EE5;secondbundle&#x7684;&#x4EE3;&#x7801;&#xFF0C;</p>\n<p><img src=\"http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/96fcb2aabba52a13f2e0abf6768cf1bf.png\" alt=\"\"></p>\n<p>&#x679C;&#x7136;&#xFF0C;&#x6BCF;&#x4E2A;bundle&#x7684;&#x4EE3;&#x7801;&#x90FD;&#x662F;&#x5404;&#x81EA;&#x6253;&#x5305;&#x7684;&#x3002;</p>\n<h1 id=\"&#x603B;&#x7ED3;\">&#x603B;&#x7ED3;</h1>\n<p>atlas&#x5C06;&#x4E00;&#x4E2A;apk&#x5206;&#x4E3A;host&#x548C;bundle&#x4E24;&#x5927;&#x90E8;&#x5206;</p>\n<ul>\n<li>host&#x4E3A;&#x5171;&#x7528;&#x4EE3;&#x7801;&#x8D44;&#x6E90;&#x548C;&#x5404;&#x4E2A;bundle&#x7684;manifest&#x4FE1;&#x606F;</li>\n<li>bundle&#x72EC;&#x7ACB;&#x6253;&#x5305;&#xFF0C;&#x62E5;&#x6709;&#x72EC;&#x7ACB;&#x7684;dex&#x548C;&#x8D44;&#x6E90;</li>\n<li>&#x50CF;&#x642D;&#x79EF;&#x6728;&#x4E00;&#x6837;&#xFF0C;host&#x548C;&#x4E0D;&#x540C;&#x7684;bundle&#x7EC4;&#x5408;&#x7F16;&#x8BD1;&#x6210;&#x4E00;&#x4E2A;apk</li>\n</ul>\n<hr>\n<p>&#x53C2;&#x8003;</p>\n<ul>\n<li><a href=\"http://atlas.taobao.org/docs\" target=\"_blank\">&#x5B98;&#x65B9;&#x6587;&#x6863;</a></li>\n<li><a href=\"https://github.com/alibaba/atlas/tree/master/atlas-demo\" target=\"_blank\">demo</a></li>\n</ul>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                \n                <a href=\"../atlas_start/atlas_start_1.html\" class=\"navigation navigation-next navigation-unique\" aria-label=\"Next page: Atlas之启动过程(一)\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"Atlas之Gradle配置\",\"level\":\"1.6.1\",\"depth\":2,\"next\":{\"title\":\"Atlas之启动过程(一)\",\"level\":\"1.6.2\",\"depth\":2,\"path\":\"code_read/atlas_start/atlas_start_1.md\",\"ref\":\"code_read/atlas_start/atlas_start_1.md\",\"articles\":[]},\"previous\":{\"title\":\"源码分析\",\"level\":\"1.6\",\"depth\":1,\"ref\":\"\",\"articles\":[{\"title\":\"Atlas之Gradle配置\",\"level\":\"1.6.1\",\"depth\":2,\"path\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.md\",\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.md\",\"articles\":[]},{\"title\":\"Atlas之启动过程(一)\",\"level\":\"1.6.2\",\"depth\":2,\"path\":\"code_read/atlas_start/atlas_start_1.md\",\"ref\":\"code_read/atlas_start/atlas_start_1.md\",\"articles\":[]},{\"title\":\"Atlas之启动过程(二)\",\"level\":\"1.6.3\",\"depth\":2,\"path\":\"code_read/atlas_start/atlas_start_2.md\",\"ref\":\"code_read/atlas_start/atlas_start_2.md\",\"articles\":[]},{\"title\":\"Atlas之Bundle加载过程\",\"level\":\"1.6.4\",\"depth\":2,\"path\":\"code_read/atlas_bundle_load/atlas_bundle_load.md\",\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.md\",\"articles\":[]}]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"../..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../../gitbook/gitbook.js\"></script>\n    <script src=\"../../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/code_read/atlas_start/atlas_core_start.uml",
    "content": "@startuml\nautoNumber\n\n-> AtlasBridgeApplication : attachBaseContext\nAtlasBridgeApplication -> BridgeApplicationDelegate : attachBaseContext\nBridgeApplicationDelegate ->AtlasHacks : defineAndVerify\nBridgeApplicationDelegate -> DemoPreLaunch : preLaunch\nBridgeApplicationDelegate -> Atlas : init\n-> AtlasBridgeApplication : onCreate\nAtlasBridgeApplication -> BridgeApplicationDelegate : onCreate\n‘BridgeApplicationDelegate -> AdditionalActivityManagerProxy : startRegisterReceivers’\nBridgeApplicationDelegate -> DemoApplication : attach\nBridgeApplicationDelegate  -> Atlas : startup\nBridgeApplicationDelegate -> DemoApplication : onCreate\n@enduml"
  },
  {
    "path": "atlas-docs/_book/code_read/atlas_start/atlas_core_start_callback.uml",
    "content": "@startuml\n\nnode “dev” {\n   [code]-> [gradle]\t\n}\n\nnode “atlas compile” {\n   [gradle]->[FrameworkProperties]\n   [FrameworkProperties]->[dex]\n} \n\nnode “runtime”{\n   [dex]->[getFrameworkProperty]\n}\n@enduml"
  },
  {
    "path": "atlas-docs/_book/code_read/atlas_start/atlas_core_start_provider.uml",
    "content": "@startuml\n\nautonumber\n\nActivityThread -> LoadedApk : makeApplication\nLoadedApk -> Instrumentation : Instrumentation\nInstrumentation -> Application : attach\nApplication -> Application :attachBaseContext\nActivityThread -> ActivityThread : installContentProviders\nActivityThread -> Instrumentation : callApplicationOnCreate\nInstrumentation -> Application : onCreate\n\n@enduml"
  },
  {
    "path": "atlas-docs/_book/code_read/atlas_start/atlas_java_startup.uml",
    "content": "@startuml\nautonumber\n\n-> Atlas : startup\nAtlas -> DexLoadBooster : init\nDexLoadBooster -> AndroidRuntime : init\nDexLoadBooster -> DalvikPatch : patchIfPossible\nAtlas -> Framework : startup\nFramework -> AtlasBundleInfoManager : getBundleInfo\nAtlasBundleInfoManager -> AtlasBundleInfoManager : InitBundleInfo\\nByVersionIfNeed\n\nFramework-> Framework : startup\nFramework -> FrameworkLifecycleHandler : started\n\nFrameworkLifecycleHandler -> BundleInstalller : installBundleInternal\nFrameworkLifecycleHandler --> BundleImpl : start\n\n@enduml"
  },
  {
    "path": "atlas-docs/_book/code_read/atlas_start/atlas_start_1.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>Atlas之启动过程(一) · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"atlas_start_2.html\" />\n    \n    \n    <link rel=\"prev\" href=\"../atlas_gradle_apk/atlas_atlas_gradle_apk.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../../\">\n            \n                <a href=\"../../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../../guide-for-use/\">\n            \n                <a href=\"../../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../../update/\">\n            \n                <a href=\"../../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../../update/principle.html\">\n            \n                <a href=\"../../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../../update/dexpatch.html\">\n            \n                <a href=\"../../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../../update/guide.html\">\n            \n                <a href=\"../../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../../faq/question.html\">\n            \n                <a href=\"../../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../../faq/help.html\">\n            \n                <a href=\"../../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../../faq/variant.html\">\n            \n                <a href=\"../../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.6.2\" data-path=\"atlas_start_1.html\">\n            \n                <a href=\"atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"atlas_start_2.html\">\n            \n                <a href=\"atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"../..\" >Atlas之启动过程(一)</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"&#x6982;&#x8FF0;\">&#x6982;&#x8FF0;</h1>\n<p>Atlas&#x6574;&#x4E2A;&#x542F;&#x52A8;&#x8FC7;&#x7A0B;&#x7684;&#x65F6;&#x5E8F;&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;&#xFF0C;&#x672C;&#x7BC7;&#x53EA;&#x5173;&#x6CE8;&#x4E0B;&#x56FE;&#x4E2D;&#x7684;1-5&#x6B65;&#x3002;</p>\n<p><img src=\"atlas_core_start_img.svg\" alt=\"\"></p>\n<h1 id=\"&#x5165;&#x53E3;\">&#x5165;&#x53E3;</h1>\n<p>&#x6211;&#x4EEC;&#x90FD;&#x77E5;&#x9053;&#xFF0C;app&#x7684;&#x5165;&#x53E3;&#x662F;application&#xFF0C;&#x90A3;&#x4E48;atlas&#x7684;&#x5165;&#x53E3;application&#x662F;&#x4EC0;&#x4E48;&#x5462;&#xFF0C;&#x770B;&#x4E00;&#x4E0B;app&#x6A21;&#x5757;&#x4E2D;manifest&#x4E2D;&#x7684;&#x5B9A;&#x4E49;</p>\n<p><img src=\"atlas_application_demo.png\" alt=\"\"></p>\n<p>&#x770B;&#x6837;&#x5B50;&#xFF0C;&#x662F;DemoApplication<br>\n&#x771F;&#x7684;&#x662F;&#x8FD9;&#x6837;&#x7684;&#x5417;&#xFF1F;<br>\n<strong>&#x5F53;&#x7136;&#x4E0D;&#x662F;</strong></p>\n<p>&#x6211;&#x4EEC;&#x770B;&#x4E00;&#x4E0B;&#x53CD;&#x7F16;&#x8BD1;&#x540E;&#x7684;manifest</p>\n<p><img src=\"atlas_manifest_application.png\" alt=\"\"></p>\n<p>&#x4E3A;&#x4EC0;&#x4E48;&#x4F1A;&#x662F;AtlasBridgeApplication&#x5462;&#xFF0C;manifest&#x4E2D;&#x660E;&#x660E;&#x5199;&#x7684;&#x5F88;&#x6E05;&#x695A; : DemoApplication&#x3002;<br>\n&#x4E8B;&#x5B9E;&#x4E0A;&#x4E3A;&#x4E86;&#x63A5;&#x5165;&#x7684;&#x65B9;&#x4FBF;&#xFF0C;Atlas&#x5728;&#x7F16;&#x8BD1;&#x671F;&#x5C31;&#x66FF;&#x6362;&#x4E86;&#x5165;&#x53E3;application&#x3002;&#x4E0D;&#x8FC7;&#xFF0C;Atlas&#x4FDD;&#x8BC1;&#x5728;&#x8FD0;&#x884C;&#x671F;&#x65F6;&#x4F1A;&#x8C03;&#x7528;DemoApplication&#x7684;&#x76F8;&#x5173;&#x65B9;&#x6CD5;&#x3002;</p>\n<h1 id=\"1-atlasbridgeapplicationattachbasecontext\">1. AtlasBridgeApplication.attachBaseContext</h1>\n<p>&#x6211;&#x4EEC;&#x770B;&#x4E00;&#x4E0B;AtlasBridgeApplication&#x4E2D;&#x7684;&#x76F8;&#x5173;&#x65B9;&#x6CD5;</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-meta\">@Override</span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">protected</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">attachBaseContext</span><span class=\"hljs-params\">(Context base)</span> </span>{\n    <span class=\"hljs-keyword\">super</span>.attachBaseContext(base);\n    <span class=\"hljs-comment\">//...&#x4E00;&#x4E9B;&#x903B;&#x8F91;</span>\n\n    <span class=\"hljs-comment\">//1. &#x6784;&#x9020;BridgeApplicationDelegate&#x5BF9;&#x8C61;</span>\n    Class BridgeApplicationDelegateClazz = getBaseContext().getClassLoader().loadClass(<span class=\"hljs-string\">&quot;android.taobao.atlas.bridge.BridgeApplicationDelegate&quot;</span>);\n    Constructor&lt;?&gt; con = BridgeApplicationDelegateClazz.getConstructor(parTypes);\n    mBridgeApplicationDelegate = con.newInstance(<span class=\"hljs-keyword\">this</span>,getProcessName(...);\n\n    <span class=\"hljs-comment\">//2. &#x6267;&#x884C;BridgeApplicationDelegate&#x7684;attachBaseContext&#x65B9;&#x6CD5;</span>\n    Method method = BridgeApplicationDelegateClazz.getDeclaredMethod(<span class=\"hljs-string\">&quot;attachBaseContext&quot;</span>);\n    method.invoke(mBridgeApplicationDelegate);\n}\n</code></pre>\n<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x4EE3;&#x7801;&#x867D;&#x957F;&#xFF0C;&#x4F46;&#x5176;&#x5B9E;&#x5C31;&#x53EA;&#x5E72;&#x4E86;&#x4E24;&#x4EF6;&#x4E8B;&#x3002;</p>\n<ul>\n<li>&#x53CD;&#x5C04;&#x5E76;&#x6784;&#x9020;BridgeApplicationDelegate&#x7684;&#x5B9E;&#x4F8B;</li>\n<li>&#x6267;&#x884C;BridgeApplicationDelegate&#x7684;attachBaseContext&#x65B9;&#x6CD5;&#x3002;</li>\n</ul>\n<p>&#x5148;&#x770B;BridgeApplicationDelegate&#x7684;&#x6784;&#x9020;&#x65B9;&#x6CD5;&#x3002;</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-comment\">//BridgeApplicationDelegate.java</span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-title\">BridgeApplicationDelegate</span><span class=\"hljs-params\">(Application rawApplication...)</span></span>{\n    mRawApplication = rawApplication;\n    PackageManagerDelegate.delegatepackageManager(\n        rawApplication.getBaseContext()\n    );\n}\n</code></pre>\n<p>&#x6CA1;&#x4EC0;&#x4E48;&#x5185;&#x5BB9;&#xFF0C;&#x76F4;&#x63A5;&#x8DDF;&#x8FDB;<code>delegatepackageManager</code>&#x7684;&#x51FD;&#x6570;&#x5B9E;&#x73B0;</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-comment\">//PackageManagerDelegate.java</span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">static</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">delegatepackageManager</span><span class=\"hljs-params\">(Context context)</span></span>{\n      mBaseContext = context;\n      <span class=\"hljs-comment\">//1. &#x53CD;&#x5C04;pm</span>\n      PackageManager manager = mBaseContext.getPackageManager();\n      Class ApplicationPackageManager = Class.forName(<span class=\"hljs-string\">&quot;android.app.ApplicationPackageManager&quot;</span>);\n      Field field = ApplicationPackageManager.getDeclaredField(<span class=\"hljs-string\">&quot;mPM&quot;</span>);\n      field.setAccessible(<span class=\"hljs-keyword\">true</span>);\n      Object rawPm = field.get(manager);\n      <span class=\"hljs-comment\">//2. &#x52A8;&#x6001;&#x4EE3;&#x7406;pm</span>\n      Class IPackageManagerClass = Class.forName(<span class=\"hljs-string\">&quot;android.content.pm.IPackageManager&quot;</span>);\n      mPackageManagerProxyhandler = <span class=\"hljs-keyword\">new</span> PackageManagerProxyhandler(rawPm);            \n      mProxyPm = Proxy.newProxyInstance(mBaseContext.getClassLoader(), <span class=\"hljs-keyword\">new</span> Class[]{IPackageManagerClass}, mPackageManagerProxyhandler);\n      <span class=\"hljs-comment\">//3. &#x66FF;&#x6362;pm</span>\n      field.set(manager, mProxyPm);\n}\n</code></pre>\n<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x8FD9;&#x6BB5;&#x4EE3;&#x7801;&#x7684;&#x6838;&#x5FC3;&#x601D;&#x60F3;&#x5C31;&#x662F;&#x5C06;&#x7CFB;&#x7EDF;&#x7684;pm&#xFF0C;&#x66FF;&#x6362;&#x4E3A;&#x6211;&#x4EEC;&#x5B9E;&#x73B0;&#x7684;PackageManagerProxyhandler&#x3002;&#x6211;&#x4EEC;&#x5148;&#x4E0D;&#x5173;&#x6CE8;PackageManagerProxyhandler&#x7684;&#x5B9E;&#x73B0;&#xFF0C;&#x63A5;&#x7740;&#x770B;<code>BridgeApplicationDelegate</code>&#x4E2D;&#x51FD;&#x6570;attachBaseContext&#x7684;&#x5B9E;&#x73B0;&#x3002;</p>\n<h1 id=\"2-bridgeapplicationdelegate-attachbasecontext\">2. BridgeApplicationDelegate. attachBaseContext</h1>\n<p>BridgeApplicationDelegate.java</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">attachBaseContext</span><span class=\"hljs-params\">()</span></span>{\n    <span class=\"hljs-comment\">//2.1 hook&#x4E4B;&#x524D;&#x51C6;&#x5907;&#x5DE5;&#x4F5C;</span>\n    AtlasHacks.defineAndVerify();\n\n    <span class=\"hljs-comment\">//2.2 &#x56DE;&#x8C03;&#x9884;&#x7559;&#x63A5;&#x53E3;</span>\n   launcher.initBeforeAtlas(mRawApplication.getBaseContext());\n\n   <span class=\"hljs-comment\">//2.3 &#x521D;&#x59CB;&#x5316;atlas     </span>\n   Atlas.getInstance().init(mRawApplication, mIsUpdated);\n\n   <span class=\"hljs-comment\">//2.4 &#x5904;&#x7406;provider    </span>\n    AtlasHacks.ActivityThread$AppBindData_providers.set(mBoundApplication,<span class=\"hljs-keyword\">null</span>);\n}\n</code></pre>\n<p>&#x51FD;&#x6570;&#x5B9E;&#x73B0;&#x5927;&#x6982;&#x5206;&#x4E3A;&#x56DB;&#x4E2A;&#x90E8;&#x5206;&#xFF0C;&#x4E5F;&#x662F;&#x672C;&#x7BC7;&#x6587;&#x7AE0;&#x7684;&#x91CD;&#x70B9;&#x5173;&#x6CE8;&#x90E8;&#x5206;</p>\n<ul>\n<li>hook&#x4E4B;&#x524D;&#x7684;&#x51C6;&#x5907;&#x5DE5;&#x4F5C;</li>\n<li>&#x56DE;&#x8C03;&#x9884;&#x7559;&#x63A5;&#x53E3;</li>\n<li>&#x521D;&#x59CB;&#x5316;atlas</li>\n<li>&#x5904;&#x7406;provider</li>\n</ul>\n<p>&#x6211;&#x4EEC;&#x4E5F;&#x4E00;&#x4E2A;&#x6765;&#x770B;&#x3002;</p>\n<h1 id=\"3-atlashacksdefineandverify\">3. AtlasHacks.defineAndVerify</h1>\n<p>&#x5728;&#x5F00;&#x59CB;&#x5206;&#x6790;&#x4E4B;&#x524D;&#xFF0C;&#x6211;&#x4EEC;&#x8981;&#x77E5;&#x9053;&#xFF0C;Android&#x4E0A;&#x52A8;&#x6001;&#x52A0;&#x8F7D;&#x65B9;&#x6848;&#xFF0C;&#x59CB;&#x7EC8;&#x90FD;&#x7ED5;&#x4E0D;&#x8FC7;&#x4E09;&#x4E2A;&#x5173;&#x952E;&#x7684;&#x70B9;:</p>\n<ul>\n<li><strong>&#x52A8;&#x6001;&#x52A0;&#x8F7D;class</strong> </li>\n<li><strong>&#x52A8;&#x6001;&#x52A0;&#x8F7D;&#x8D44;&#x6E90;</strong> </li>\n<li><strong>&#x5904;&#x7406;&#x56DB;&#x5927;&#x7EC4;&#x4EF6;</strong> &#x80FD;&#x591F;&#x8BA9;&#x52A8;&#x6001;&#x4EE3;&#x7801;&#x4E2D;&#x7684;&#x56DB;&#x5927;&#x7EC4;&#x4EF6;&#x5728;Android&#x4E0A;&#x6B63;&#x5E38;&#x8DD1;&#x8D77;&#x6765;</li>\n</ul>\n<p>&#x4E3A;&#x4E86;&#x5B9E;&#x73B0;&#x8FD9;&#x4E09;&#x4E2A;&#x76EE;&#x6807;&#xFF0C;&#x4F1A;&#x5728;&#x7CFB;&#x7EDF;&#x5173;&#x952E;&#x8C03;&#x7528;&#x7684;&#x5730;&#x65B9;&#x8FDB;&#x884C;Hook&#x3002;&#x6BD4;&#x5982;&#xFF0C;&#x4E3A;&#x4E86;&#x80FD;&#x591F;&#x52A8;&#x6001;&#x52A0;&#x8F7D;class&#xFF0C;&#x901A;&#x5E38;&#x90FD;&#x4F1A;&#x5BF9;classloader&#x4E0A;&#x52A8;&#x4E00;&#x4E9B;&#x624B;&#x811A;&#xFF0C;resource&#x4E5F;&#x662F;&#x7C7B;&#x4F3C;&#x3002;</p>\n<p>&#x8FD9;&#x91CC;&#x591A;&#x63D0;&#x4E00;&#x53E5;&#xFF0C;&#x5728;&#x56DB;&#x5927;&#x7EC4;&#x4EF6;&#x7684;&#x5904;&#x7406;&#x4E0A;&#xFF0C;atals&#x4E0E;&#x63D2;&#x4EF6;&#x5316;&#x6709;&#x7740;&#x5F88;&#x5927;&#x7684;&#x5DEE;&#x5F02;&#x3002;</p>\n<ul>\n<li>&#x63D2;&#x4EF6;&#x5316;&#x7684;&#x6838;&#x5FC3;&#x601D;&#x60F3;&#x5176;&#x5B9E;&#x662F;&#x57CB;&#x5751;&#x673A;&#x5236;+&#x501F;&#x5C38;&#x8FD8;&#x9B42; &#xFF1A;&#x901A;&#x8FC7;&#x9884;&#x5148;&#x5728;manifest&#x4E2D;&#x9884;&#x7559;N&#x4E2A;&#x7EC4;&#x4EF6;&#x5751;&#xFF0C;&#x5728;runtime&#x65F6;&#xFF0C;&#x901A;&#x8FC7;&#x201C;&#x501F;&#x5C38;&#x8FD8;&#x9B42;&#x201D;&#x5B9E;&#x73B0;&#x56DB;&#x5927;&#x7EC4;&#x4EF6;&#x7684;&#x8FD0;&#x884C;&#x3002;</li>\n<li>atlas&#x4E0D;&#x4E00;&#x6837;&#xFF0C;&#x5B83;&#x662F;&#x5728;&#x7F16;&#x8BD1;&#x671F;&#x5C31;&#x5DF2;&#x7ECF;&#x5404;&#x4E2A;bundle&#x7684;manifest&#x5199;&#x5165;&#x5230;apk&#x4E2D;&#x3002;&#x6240;&#x4EE5;&#x8FD0;&#x884C;&#x65F6;&#xFF0C;bundle&#x4E2D;&#x7684;&#x7EC4;&#x4EF6;&#x53EF;&#x4EE5;&#x548C;&#x5E38;&#x89C4;&#x58F0;&#x660E;&#x7684;&#x7EC4;&#x4EF6;&#x4E00;&#x6837;&#x6B63;&#x5E38;&#x8FD0;&#x884C;&#xFF0C;&#x4E0D;&#x7528;&#x518D;&#x505A;&#x989D;&#x5916;&#x7684;&#x5904;&#x7406;&#x3002;</li>\n</ul>\n<p>&#x56DE;&#x8FC7;&#x5934;&#x6765;&#xFF0C;&#x6211;&#x4EEC;&#x770B;&#x770B;atlas&#x4E3A;&#x4E86;&#x5B9E;&#x73B0;&#x4E0A;&#x8FF0;&#x76EE;&#x7684;&#xFF0C;&#x505A;&#x4E86;&#x54EA;&#x4E9B;&#x51C6;&#x5907;&#x5DE5;&#x4F5C;&#x3002;&#x5728;&#x8DDF;&#x8FDB;<code>defineAndVerify</code>&#x51FD;&#x6570;&#x7684;&#x5B9E;&#x73B0;&#x4E4B;&#x524D;&#xFF0C;&#x5148;&#x770B;&#x4E00;&#x4E0B;AtlasHacks&#x7C7B;&#x4E2D;&#x5B9A;&#x4E49;&#x7684;&#x5B57;&#x6BB5;</p>\n<pre><code>//AtlasHacks.java\n\n     // Classes\n    public static HackedClass&lt;Object&gt;                           LoadedApk;\n    public static HackedClass&lt;Object&gt;                           ActivityThread;\n    public static HackedClass&lt;android.content.res.Resources&gt;    Resources;\n\n    // Fields\n    public static HackedField&lt;Object, Instrumentation&gt;          ActivityThread_mInstrumentation;\n    public static HackedField&lt;Object, Application&gt;              LoadedApk_mApplication;\n    public static HackedField&lt;Object, Resources&gt;                LoadedApk_mResources;\n\n    // Methods\n    public static HackedMethod                                  ActivityThread_currentActivityThread;\n    public static HackedMethod                                  AssetManager_addAssetPath;\n    public static HackedMethod                                  Application_attach;\n    public static HackedField&lt;Object, ClassLoader&gt;              LoadedApk_mClassLoader;\n\n    // Constructor\n    public static Hack.HackedConstructor                        PackageParser_constructor;\n</code></pre><p>&#x7ED9;&#x8FD9;&#x6BB5;&#x4EE3;&#x7801;&#x70B9;&#x4E2A;&#x8D5E;&#xFF0C;&#x975E;&#x5E38;&#x7684;&#x5E72;&#x51C0;&#x548C;&#x6E05;&#x6670;&#x3002;&#x4EE3;&#x7801;&#x5B9A;&#x4E49;&#x4E86;atlas&#x6846;&#x67B6;&#x6240;&#x9700;&#x8981;hook&#x7684;&#x6240;&#x6709;&#x7684;&#x7C7B;&#x3001;&#x65B9;&#x6CD5;&#x3001;&#x5C5E;&#x6027;&#x7B49;&#x7B49;&#x5B57;&#x6BB5;&#x3002;</p>\n<ul>\n<li>&#x5904;&#x7406;&#x8D44;&#x6E90;&#xFF0C;hook Resources</li>\n<li>&#x5904;&#x7406;class&#xFF0C;hook LoadedApk_mClassLoader</li>\n<li>...</li>\n</ul>\n<p>&#x73B0;&#x5728;&#xFF0C;&#x5728;&#x770B;<code>defineAndVerify</code>&#x51FD;&#x6570;&#x7684;&#x5B9E;&#x73B0;</p>\n<pre><code>//AtlasHacks.java\npublic static boolean defineAndVerify() throws AssertionArrayException {\n     allClasses();\n     allConstructors();\n     allFields();\n     allMethods();\n}\n</code></pre><p>&#x5B9E;&#x9645;&#x4E0A;&#x8FD9;&#x56DB;&#x4E2A;&#x7EA7;&#x522B;&#x7684;&#x51FD;&#x6570;&#x8C03;&#x7528;&#xFF0C;&#x5BF9;&#x5E94;&#x4E4B;&#x524D;&#x5B9A;&#x4E49;&#x7684;&#x5B57;&#x6BB5;&#xFF0C;&#x4E3A;&#x8FD9;&#x4E9B;&#x5B57;&#x6BB5;&#x8FDB;&#x884C;&#x8D4B;&#x503C;&#x3002;</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-comment\">//AtlasHacks.java</span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">static</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">allClasses</span><span class=\"hljs-params\">()</span> <span class=\"hljs-keyword\">throws</span> HackAssertionException </span>{\n    LoadedApk = Hack.into(<span class=\"hljs-string\">&quot;android.app.LoadedApk&quot;</span>);\n    ActivityThread = Hack.into(<span class=\"hljs-string\">&quot;android.app.ActivityThread&quot;</span>);\n    Resources = Hack.into(Resources.class);\n    ActivityManager = Hack.into(<span class=\"hljs-string\">&quot;android.app.ActivityManager&quot;</span>);\n    <span class=\"hljs-comment\">//...</span>\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">static</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">allFields</span><span class=\"hljs-params\">()</span> <span class=\"hljs-keyword\">throws</span> HackAssertionException </span>{\n    ActivityThread_mInstrumentation = ActivityThread.field(<span class=\"hljs-string\">&quot;mInstrumentation&quot;</span>).ofType(Instrumentation.class);\n    ActivityThread_mAllApplications = ActivityThread.field(<span class=\"hljs-string\">&quot;mAllApplications&quot;</span>).ofGenericType(ArrayList.class);\n}\n\n<span class=\"hljs-comment\">//...</span>\n</code></pre>\n<p>&#x8FD9;&#x51E0;&#x4E2A;&#x51FD;&#x6570;&#x7684;&#x4EE3;&#x7801;&#x5E76;&#x4E0D;&#x590D;&#x6742;&#xFF0C;&#x662F;&#x5BF9;&#x5B9A;&#x4E49;&#x7684;Class&#x3001;Field&#x3001;Method&#x548C;Contructor &#x8FD9;&#x4E9B;&#x5B57;&#x6BB5;&#x8FDB;&#x884C;&#x521D;&#x59CB;&#x5316;&#x8D4B;&#x503C;&#x5DE5;&#x4F5C;&#x3002;</p>\n<p>&#x6267;&#x884C;&#x5230;&#x8FD9;&#x91CC;&#x65F6;&#xFF0C;atlas&#x6846;&#x67B6;&#x7684;&#x51C6;&#x5907;&#x5DE5;&#x4F5C;&#x5B8C;&#x6210;&#xFF0C;&#x63A5;&#x4E0B;&#x6765;&#xFF0C;&#x5C31;&#x662F;&#x6574;&#x4E2A;&#x6846;&#x67B6;&#x7684;&#x521D;&#x59CB;&#x5316;&#x4E86;&#x3002;</p>\n<h1 id=\"4-&#x56DE;&#x8C03;&#x9884;&#x7559;&#x63A5;&#x53E3;\">4 &#x56DE;&#x8C03;&#x9884;&#x7559;&#x63A5;&#x53E3;</h1>\n<p>&#x65F6;&#x5E8F;&#x56FE;&#x4E2D;&#x7684;&#x7B2C;4&#x6B65;&#xFF0C;&#x5373;<code>BridgeApplicationDelegate</code>&#x7684;<code>attachBaseContext</code>&#x65B9;&#x6CD5;&#x4E2D;&#xFF0C;&#xFF0C;&#x505A;&#x4E86;&#x4E00;&#x4E2A;&#x63A5;&#x53E3;&#x56DE;&#x8C03;&#x3002;</p>\n<p>BridgeApplicationDelegate.java</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">attachBaseContext</span><span class=\"hljs-params\">()</span></span>{\n   String preLaunchStr = (String) RuntimeVariables.getFrameworkProperty(<span class=\"hljs-string\">&quot;preLaunch&quot;</span>);\n   AtlasPreLauncher launcher = (AtlasPreLauncher) Class.forName(preLaunchStr).newInstance();\n   launcher.initBeforeAtlas(mRawApplication.getBaseContext());\n   <span class=\"hljs-comment\">//...</span>\n}\n</code></pre>\n<p>&#x51FD;&#x6570;&#x901A;&#x8FC7;&#x201C;preLaunch&#x201D;&#x5B57;&#x6BB5;&#x8BFB;&#x53D6;&#x4E00;&#x4E2A;&#x7C7B;&#x540D;&#xFF0C;&#x53CD;&#x5C04;&#x8BE5;&#x7C7B;&#x4E0A;&#x7684;<code>initBeforeAtlas</code>&#x65B9;&#x6CD5;&#x3002;<br>\n<code>AtlasPreLauncher</code>&#x5B9E;&#x9645;&#x4E0A;&#x662F;&#x4E00;&#x4E2A;&#x63A5;&#x53E3;&#xFF0C;&#x4F9B;&#x63A5;&#x5165;&#x8005;&#x4F7F;&#x7528;&#x3002;&#x5728;&#x8FD9;&#x4E2A;&#x70B9;&#xFF0C;atlas&#x8FD8;&#x6CA1;&#x6709;&#x5F00;&#x59CB;&#x5BF9;&#x7CFB;&#x7EDF;&#x8FDB;&#x884C;hook&#xFF0C;&#x4ECD;&#x7136;&#x662F;Android&#x539F;&#x751F;&#x6001;&#x7684;&#x8FD0;&#x884C;&#x65F6;&#x73AF;&#x5883;&#x3002;</p>\n<p>&#x90A3;&#x4E48;&#x8FD9;&#x4E2A;preLaunch&#x7684;&#x5B57;&#x6BB5;&#x5728;&#x54EA;&#x91CC;&#x5B9A;&#x4E49;&#x7684;&#x5462;&#xFF0C;&#x6211;&#x4EEC;&#x53CD;&#x63A8;&#x4E00;&#x4E0B;&#x3002;</p>\n<p>RuntimeVariables.java</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">static</span> Object <span class=\"hljs-title\">getFrameworkProperty</span><span class=\"hljs-params\">(String fieldName)</span></span>{\n    <span class=\"hljs-comment\">//...</span>\n    Field field = FrameworkPropertiesClazz.getDeclaredField(fieldName);\n    <span class=\"hljs-keyword\">return</span> field.get(FrameworkPropertiesClazz);\n}\n</code></pre>\n<p>&#x5B9E;&#x73B0;&#x5F88;&#x7B80;&#x5355;&#xFF0C;&#x8BFB;&#x53D6;<code>FrameworkProperties</code>&#x4E0A;&#x7684;&#x9759;&#x6001;&#x5C5E;&#x6027;&#x5B57;&#x6BB5;&#xFF0C;&#x63A5;&#x7740;&#x8DDF;&#x8FDB;&#x3002;</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">FrameworkProperties</span> </span>{\n}\n</code></pre>\n<p>&#x4EC0;&#x4E48;&#x60C5;&#x51B5;&#xFF0C;&#x600E;&#x4E48;&#x4EC0;&#x4E48;&#x90FD;&#x6CA1;&#x6709;? &#x6240;&#x8C13;&#x53CD;&#x5E38;&#x5373;&#x4E3A;&#x1F48A;&#xFF0C;&#x76F4;&#x63A5;&#x770B;&#x53CD;&#x7F16;&#x8BD1;&#x540E;&#x7684;&#x4EE3;&#x7801;</p>\n<p>FrameworkProperties.java</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">FrameworkProperties</span></span>{\n  <span class=\"hljs-comment\">//...</span>\n  <span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">static</span> String autoStartBundles;\n  <span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">static</span> String preLaunch;\n\n  <span class=\"hljs-keyword\">static</span>{\n    autoStartBundles = <span class=\"hljs-string\">&quot;com.taobao.firstbundle&quot;</span>;\n    preLaunch = <span class=\"hljs-string\">&quot;com.taobao.demo.DemoPreLaunch&quot;</span>;\n  }\n}\n</code></pre>\n<p>&#x4ECE;&#x53CD;&#x7F16;&#x8BD1;&#x540E;&#x7684;&#x4EE3;&#x7801;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&quot;prelaunch&quot;&#x5BF9;&#x5E94;&#x7684;&#x5185;&#x5BB9;&#x662F;<code>com.taobao.demo.DemoPreLaunch</code>,&#x90A3;&#x4E48;&#x8FD9;&#x4E2A;&#x503C;&#x662F;&#x5728; <strong>&#x4EC0;&#x4E48;&#x65F6;&#x5019;&#x5199;&#x5165;&#x53C8;&#x662F;&#x5728;&#x54EA;&#x91CC;&#x914D;&#x7F6E;</strong> &#x7684;&#x5462;&#xFF1F;</p>\n<p>&#x5927;&#x5BB6;&#x56DE;&#x60F3;&#x4E00;&#x4E0B;&#xFF0C;&#x5728;&#x4E4B;&#x524D;<a href=\"../atlas_gradle_apk/atlas_atlas_gradle_apk.html\">Atlas&#x4E4B;Gradle&#x914D;&#x7F6E;</a>&#x4E2D;&#x63D0;&#x5230;&#x8FC7;&#xFF0C;atlas&#x7684;gradle&#x63D2;&#x4EF6;&#x5728;&#x7F16;&#x8BD1;&#x671F;&#x641E;&#x4E86;&#x5F88;&#x591A;&#x4E8B;&#x60C5;&#xFF0C;&#x6211;&#x4EEC;&#x770B;gradle&#x4E2D;&#x7684;&#x8BBE;&#x7F6E;</p>\n<pre><code class=\"lang-gradle\">atlas{\n     tBuildConfig {\n        autoStartBundles = [<span class=\"hljs-string\">&apos;com.taobao.firstbundle&apos;</span>]\n        preLaunch = <span class=\"hljs-string\">&apos;com.taobao.demo.DemoPreLaunch&apos;</span>\n    }\n}\n</code></pre>\n<p>&#x548C;<code>FrameworkProperties</code>&#x4E2D;&#x7684;&#x5B57;&#x6BB5;&#x5B8C;&#x7F8E;&#x5BF9;&#x5E94;&#x3002;</p>\n<p>&#x8FD9;&#x4E2A;&#x90E8;&#x5206;&#x7275;&#x6D89;&#x5F00;&#x53D1;-&#x7F16;&#x8BD1;-&#x8FD0;&#x884C;&#x4E09;&#x4E2A;&#x9636;&#x6BB5;&#xFF0C;&#x653E;&#x4E00;&#x5F20;&#x56FE;&#x634B;&#x4E00;&#x4E0B;&#x5173;&#x7CFB;&#x3002;</p>\n<p><img src=\"atlas_framework_property.svg\" alt=\"\"></p>\n<h1 id=\"5-atlasinit\">5 atlas.init</h1>\n<p>&#x51C6;&#x5907;&#x5DE5;&#x4F5C;&#x505A;&#x597D;&#x4E4B;&#x540E;&#xFF0C;&#x5C31;&#x662F;&#x521D;&#x59CB;&#x5316;&#x4E86;&#x3002;</p>\n<p>Atlas.java</p>\n<pre><code>public void init(Application application,boolean reset) {\n    //&#x8BFB;&#x53D6;&#x914D;&#x7F6E;&#x9879;\n    ApplicationInfo appInfo = mRawApplication.get...;\n    mRealApplicationName = appInfo.metaData.getString(&quot;REAL_APPLICATION&quot;);\n    boolean multidexEnable = appInfo.metaData.getBoolean(&quot;multidex_enable&quot;);\n\n    if(multidexEnable){\n      MultiDex.install(mRawApplication);\n   }\n    //...   \n}\n</code></pre><p>&#x9996;&#x5148;&#x662F;&#x8BFB;&#x53D6;manifest&#x4E2D;&#x7684;&#x914D;&#x7F6E;&#x6570;&#x636E;<code>multidexEnable</code>&#x548C;<code>mRealApplicationName</code>&#xFF0C;&#x8FD9;&#x4E24;&#x4E2A;&#x6570;&#x636E;&#x4E5F;&#x662F;&#x5728;&#x7F16;&#x8BD1;&#x671F;&#x7531;atlas&#x63D2;&#x4EF6;&#x5199;&#x5230;manifest&#x4E2D;&#x7684;&#x3002;</p>\n<p><img src=\"atlas_meta_data.png\" alt=\"\"></p>\n<p>multidexEnable &#x662F;true&#xFF0C;&#x8FD9;&#x4E2A;&#x5728;gradle&#x4E2D;&#x53EF;&#x914D;<br>\nmRealApplicationName &#x5B9E;&#x9645;&#x4E0A;&#x662F;DemoApplication,&#x5373;app&#x5DE5;&#x7A0B;&#x5728;manifest&#x4E2D;&#x6307;&#x5B9A;&#x7684;&#x542F;&#x52A8;&#x8DEF;&#x5F84;&#x3002;</p>\n<p>&#x634B;&#x6E05;&#x695A;&#x8FD9;&#x51E0;&#x4E2A;&#x53C2;&#x6570;&#x4E4B;&#x540E;&#xFF0C;&#x5F80;&#x4E0B;&#x770B;Atlas&#x6846;&#x67B6;&#x521D;&#x59CB;&#x5316;&#x5B9E;&#x73B0;</p>\n<p>Atlas.java</p>\n<pre><code>public void init(Application application,boolean reset) {\n   //...\n   Atlas.getInstance().init(mRawApplication, mIsUpdated);\n}\n\npublic void init(Application application,boolean reset) throws AssertionArrayException, Exception {\n     //...\n\n     //1. &#x6362;classloader \n     AndroidHack.injectClassLoader(packageName, newClassLoader);\n     //2. &#x6362;Instrumentatio\n     AndroidHack.injectInstrumentationHook(new InstrumentationHook(AndroidHack.getInstrumentation(), application.getBaseContext()));\n     //3. hook ams\n     try {\n         ActivityManagerDelegate activityManagerProxy = new ActivityManagerDelegate();\n         Object gDefault = null;\n         if(Build.VERSION.SDK_INT&gt;25 || (Build.VERSION.SDK_INT==25&amp;&amp;Build.VERSION.PREVIEW_SDK_INT&gt;0)){\n             gDefault=AtlasHacks.ActivityManager_IActivityManagerSingleton.get(AtlasHacks.ActivityManager.getmClass());\n         }else{\n               gDefault=AtlasHacks.ActivityManagerNative_gDefault.get(AtlasHacks.ActivityManagerNative.getmClass());\n         }\n         AtlasHacks.Singleton_mInstance.hijack(gDefault, activityManagerProxy);\n      }catch(Throwable e){}\n      //4. hook H\n      AndroidHack.hackH();\n}\n</code></pre><p>&#x8FD9;&#x6BB5;&#x4EE3;&#x7801;&#xFF0C;&#x5C31;&#x662F;&#x5BF9;&#x7CFB;&#x7EDF;&#x5173;&#x952E;&#x8282;&#x70B9;&#x8FDB;&#x884C;&#x4E86;hook&#xFF0C;&#x5177;&#x4F53;&#x7684;hook&#x5B9E;&#x73B0;&#x8FD9;&#x91CC;&#x5C31;&#x4E0D;&#x8D34;&#x51FA;&#x4E86;&#xFF0C;&#x5982;&#x679C;&#x611F;&#x5174;&#x8DA3;&#xFF0C;&#x53EF;&#x4EE5;&#x53C2;&#x8003;<a href=\"https://github.com/alibaba/atlas\" target=\"_blank\">demo&#x6E90;&#x7801;</a>&#x4EE5;&#x53CA;<a href=\"http://weishu.me/\" target=\"_blank\">&#x7530;&#x7EF4;&#x672F;&#x7684;blog</a>&#xFF0C;&#x5982;&#x4F55;hook&#xFF0C;&#x4EE5;&#x53CA;&#x4E3A;&#x4EC0;&#x4E48;&#x5728;&#x8FD9;&#x91CC;hook&#xFF0C;&#x5728;&#x6587;&#x7AE0;&#x4E2D;&#x90FD;&#x8BB2;&#x7684;&#x975E;&#x5E38;&#x6E05;&#x695A;&#x3002;</p>\n<p>&#x51FD;&#x6570;&#x4E2D;&#x7684;hook&#x70B9;</p>\n<table>\n<thead>\n<tr>\n<th>hook&#x70B9;</th>\n<th>&#x5B9E;&#x4F8B;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>ActivityThread.mLoadedApk.mClassLoader</td>\n<td>DelegateClassLoader</td>\n</tr>\n<tr>\n<td>ActivityThread.mInstrumentation</td>\n<td>InstrumentationHook</td>\n</tr>\n<tr>\n<td>ActivityManagerNative.gDefault.get</td>\n<td>ActivityManagerDelegate</td>\n</tr>\n<tr>\n<td>android.app.ActivityThread$H.mCallback</td>\n<td>ActivityThreadHook</td>\n</tr>\n</tbody>\n</table>\n<h1 id=\"6-&#x5904;&#x7406;provider\">6. &#x5904;&#x7406;provider</h1>\n<p>&#x5728;&#x7B2C;2&#x6B65;&#x7684;2.4&#x90E8;&#x5206;&#xFF0C;&#x5BF9;provider&#x8FDB;&#x884C;&#x4E86;&#x5904;&#x7406;</p>\n<p>BridgeApplicationDelegate.java</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">attachBaseContext</span><span class=\"hljs-params\">()</span></span>{\n    <span class=\"hljs-comment\">//...</span>\n\n   <span class=\"hljs-comment\">//2.4 &#x5904;&#x7406;provider</span>\n   Object mBoundApplication = AtlasHacks.ActivityThread_mBoundApplication.get(activityThread);\n   mBoundApplication_provider = AtlasHacks.ActivityThread$AppBindData_providers.get(mBoundApplication);\n   <span class=\"hljs-keyword\">if</span>(mBoundApplication_provider!=<span class=\"hljs-keyword\">null</span> &amp;&amp; mBoundApplication_provider.size()&gt;<span class=\"hljs-number\">0</span>){\n           AtlasHacks.ActivityThread$AppBindData_providers.set(mBoundApplication,<span class=\"hljs-keyword\">null</span>);\n    }\n}\n</code></pre>\n<p>&#x7B2C;4&#x884C;&#x4EE3;&#x7801;&#x8BFB;&#x53D6;provider&#x6570;&#x636E;&#xFF0C;&#x5982;&#x679C;&#x6709;provider&#x4FE1;&#x606F;&#x7684;&#x8BDD;&#xFF0C;&#x5219;&#x5728;&#x7B2C;6&#x884C;&#x4ECE;&#x7CFB;&#x7EDF;&#x5220;&#x9664;&#xFF0C;&#x8BA9;&#x7CFB;&#x7EDF;&#x8BA4;&#x4E3A;apk&#x5E76;&#x6CA1;&#x6709;&#x7533;&#x8BF7;&#x4EFB;&#x4F55;provider&#x3002;</p>\n<p>&#x4E3A;&#x4EC0;&#x4E48;&#x8FD9;&#x4E48;&#x505A;?&#x56DE;&#x987E;&#x4E00;&#x4E0B;app&#x542F;&#x52A8;&#x7684;&#x6D41;&#x7A0B;</p>\n<p><img src=\"atlas_core_start_provider_img.svg\" alt=\"\"></p>\n<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x5728;&#x7B2C;4&#x6B65;&#x548C;&#x7B2C;7&#x6B65;&#x4E24;&#x4E2A;&#x5173;&#x952E;&#x8C03;&#x7528;&#x4E4B;&#x95F4;&#xFF0C;&#x7B2C;5&#x6B65;&#x8C03;&#x7528;&#x4E86;&#x51FD;&#x6570;<code>installContentProviders</code>,&#x8DDF;&#x8FDB;&#x53BB;&#x770B;&#x4E00;&#x4E0B;&#x3002;</p>\n<pre><code>private void installContentProviders(Context context, List&lt;ProviderInfo&gt; providers) {\n    for (ProviderInfo cpi : providers) {\n        installProvider(context, null, cpi,...);\n    }\n}\n</code></pre><p>&#x6536;&#x96C6;&#x4E86;&#x6240;&#x6709;provider&#x7684;&#x4FE1;&#x606F;&#xFF0C;&#x7136;&#x540E;&#x8C03;&#x7528;installProvider&#x51FD;&#x6570;</p>\n<pre><code>private IActivityManager.ContentProviderHolder installProvider(Context context,IActivityManager.ContentProviderHolder holder, ProviderInfo info,...) {\n    final java.lang.ClassLoader cl = c.getClassLoader();\n   localProvider = (ContentProvider)cl.loadClass(info.name).newInstance();\n   //...\n}\n</code></pre><p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x51FD;&#x6570;&#x662F;&#x6839;&#x636E;&#x5728;manifest&#x4E2D;&#x767B;&#x8BB0;&#x7684;provider&#x4FE1;&#x606F;&#xFF0C;&#x5B9E;&#x4F8B;&#x5316;&#x5BF9;&#x8C61;&#x3002;<br>\n<strong>&#x90A3;&#x4E48;&#x95EE;&#x9898;&#x6765;&#x4E86;</strong>&#xFF0C;&#x6709;&#x4E9B;provider&#x662F;&#x5B58;&#x5728;&#x4E8E;bundle&#x4E2D;&#x7684;&#xFF0C;&#x4E3B;dex&#x4E2D;&#x5E76;&#x4E0D;&#x5B58;&#x5728;&#x3002;&#x5982;&#x679C;&#x4E0D;&#x5904;&#x7406;&#xFF0C;&#x5728;&#x8FD9;&#x91CC;&#x7A0B;&#x5E8F;&#x4F1A;&#x56E0;&#x4E3A;<code>ClassNotFind</code>&#x5D29;&#x6E83;&#x3002;&#x6240;&#x4EE5;&#x8FD9;&#x91CC;&#x8981;&#x5148;&#x6E05;&#x9664;&#x6389;provier&#x7684;&#x4FE1;&#x606F;&#xFF0C;&#x5EF6;&#x8FDF;&#x52A0;&#x8F7D;&#x3002;</p>\n<hr>\n<p>&#x4E0A;&#x7BC7;&#x5148;&#x5230;&#x8FD9;&#x91CC;&#xFF0C;&#x5404;&#x4F4D;&#x5148;&#x559D;&#x53E3;&#x6C34;&#xFF0C;&#x518D;&#x6765;&#x4E0B;&#x7BC7;&#x7684;&#x5206;&#x6790;&#x3002;</p>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"../atlas_gradle_apk/atlas_atlas_gradle_apk.html\" class=\"navigation navigation-prev \" aria-label=\"Previous page: Atlas之Gradle配置\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"atlas_start_2.html\" class=\"navigation navigation-next \" aria-label=\"Next page: Atlas之启动过程(二)\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"Atlas之启动过程(一)\",\"date\":\"2017-05-02T15:00:00.000Z\",\"level\":\"1.6.2\",\"depth\":2,\"next\":{\"title\":\"Atlas之启动过程(二)\",\"level\":\"1.6.3\",\"depth\":2,\"path\":\"code_read/atlas_start/atlas_start_2.md\",\"ref\":\"code_read/atlas_start/atlas_start_2.md\",\"articles\":[]},\"previous\":{\"title\":\"Atlas之Gradle配置\",\"level\":\"1.6.1\",\"depth\":2,\"path\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.md\",\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"code_read/atlas_start/atlas_start_1.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"../..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../../gitbook/gitbook.js\"></script>\n    <script src=\"../../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/code_read/atlas_start/atlas_start_2.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>Atlas之启动过程(二) · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"../atlas_bundle_load/atlas_bundle_load.html\" />\n    \n    \n    <link rel=\"prev\" href=\"atlas_start_1.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../../\">\n            \n                <a href=\"../../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../../guide-for-use/\">\n            \n                <a href=\"../../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../../update/\">\n            \n                <a href=\"../../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../../update/principle.html\">\n            \n                <a href=\"../../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../../update/dexpatch.html\">\n            \n                <a href=\"../../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../../update/guide.html\">\n            \n                <a href=\"../../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../../faq/question.html\">\n            \n                <a href=\"../../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../../faq/help.html\">\n            \n                <a href=\"../../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../../faq/variant.html\">\n            \n                <a href=\"../../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"atlas_start_1.html\">\n            \n                <a href=\"atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.6.3\" data-path=\"atlas_start_2.html\">\n            \n                <a href=\"atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"../..\" >Atlas之启动过程(二)</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"&#x6982;&#x8FF0;\">&#x6982;&#x8FF0;</h1>\n<p>&#x63A5;&#x4E0A;&#x7BC7; <a href=\"atlas_start_1.html\">Atlasz&#x4E4B;&#x542F;&#x52A8;&#x8FC7;&#x7A0B;(&#x4E00;)</a> ,&#x7EE7;&#x7EED; 6-10 &#x6B65;&#x7684;&#x542F;&#x52A8;&#x8FC7;&#x7A0B;&#x3002;</p>\n<p><img src=\"atlas_core_start_img.svg\" alt=\"\"></p>\n<h1 id=\"6-oncreate\">6. onCreate</h1>\n<p>AtlasBridgeApplication.java</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-meta\">@Override</span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">onCreate</span><span class=\"hljs-params\">()</span> </span>{\n    <span class=\"hljs-keyword\">super</span>.onCreate();\n    Method method = mBridgeApplicationDelegate.getClass().getDeclaredMethod(<span class=\"hljs-string\">&quot;onCreate&quot;</span>);\n    method.invoke(mBridgeApplicationDelegate);       \n}\n</code></pre>\n<p>&#x76F4;&#x63A5;&#x53CD;&#x5C04;&#x8C03;&#x7528;<code>mBridgeApplicationDelegate</code>&#x7684;<code>onCreate</code>&#x65B9;&#x6CD5;.</p>\n<h1 id=\"7-bridgeapplicationdelegateoncreate\">7. BridgeApplicationDelegate.onCreate</h1>\n<p>BridgeApplicationDelegate.java</p>\n<pre><code>public void onCreate(){\n   // 7.1 &#x5B9E;&#x4F8B;application\n    mRealApplication = (Application) mRawApplication.getBaseContext()\n        .getClassLoader().loadClass(mRealApplicationName).newInstance();\n\n    //7.2 replace xxx\n    AtlasHacks.ContextImpl_setOuterContext.invoke(\n        mRawApplication.getBaseContext(), mRealApplication);\n    //...\n\n    //7.3 mRealApplication.attach\n    AtlasHacks.Application_attach\n           .invoke(mRealApplication,mRawApplication.getBaseContext());\n\n    //7.4 install content providers\n    Object mBoundApplication = AtlasHacks.ActivityThread_mBoundApplication.get(activityThread);\n    AtlasHacks.ActivityThread$AppBindData_providers.set(mBoundApplication,mBoundApplication_provider);\n    AtlasHacks.ActivityThread_installContentProviders.invoke(activityThread,mRealApplication,mBoundApplication_provider);\n\n    //7.5. startup\n    Atlas.getInstance().startup(mRealApplication,mIsUpdated);\n\n    //7.6 onCreate\n    mRealApplication.onCreate();\n}\n</code></pre><p>&#x51FD;&#x6570;&#x6709;&#x70B9;&#x957F;&#xFF0C;&#x4E0D;&#x8FC7;&#x5185;&#x5BB9;&#x5927;&#x6982;&#x5206;&#x4E3A;6&#x5757;</p>\n<ol>\n<li>&#x5B9E;&#x4F8B;&#x5316;app&#x5DE5;&#x7A0B;&#x4E2D;&#x6307;&#x5B9A;&#x7684;mRealApplication</li>\n<li>&#x66FF;&#x6362;application</li>\n<li>&#x53CD;&#x5C04;&#x6267;&#x884C;mRealApplication&#x7684;attach&#x65B9;&#x6CD5;</li>\n<li>&#x52A0;&#x8F7D;provider</li>\n<li>Atlas.startup</li>\n<li>&#x8C03;&#x7528;mRealApplication.onCreate&#x65B9;&#x6CD5;</li>\n</ol>\n<h2 id=\"71-&#x5B9E;&#x4F8B;application\">7.1 &#x5B9E;&#x4F8B;application</h2>\n<pre><code class=\"lang-java\">mRealApplication = (Application) mRawApplication.getBaseContext()\n        .getClassLoader().loadClass(mRealApplicationName).newInstance();\n</code></pre>\n<p><code>mRealApplicationName</code>&#x5B9E;&#x9645;&#x4E0A;&#x662F;&#x6307;<code>com.taobao.demo.DemoApplication</code>&#x3002;&#x5728;&#x8FD9;&#x91CC;&#xFF0C;&#x6784;&#x9020;&#x51FA;&#x4E86;app&#x5DE5;&#x7A0B;&#x4E2D;&#x6307;&#x5B9A;application&#x7684;&#x5BF9;&#x8C61;&#x5B9E;&#x4F8B;&#x3002;</p>\n<h2 id=\"72-&#x66FF;&#x6362;application\">7.2 &#x66FF;&#x6362;application</h2>\n<pre><code class=\"lang-java\"><span class=\"hljs-comment\">//replace baseContext.mOuterContext</span>\nAtlasHacks.ContextImpl_setOuterContext.invoke(mRawApplication.getBaseContext(), mRealApplication);\n\n<span class=\"hljs-comment\">//replace baseContext.mPackageInfo.mApplication</span>\nObject mPackageInfo = AtlasHacks.ContextImpl_mPackageInfo.get(mRawApplication.getBaseContext());\n\n<span class=\"hljs-comment\">//...</span>\n</code></pre>\n<p>7.2&#x90E8;&#x5206;&#xFF0C;&#x4E3A;&#x4E86;&#x4FDD;&#x8BC1;DemoApplication&#x80FD;&#x591F;&#x50CF;&#x6B63;&#x5E38;&#x58F0;&#x660E;&#x7684;application&#x4E00;&#x6837;&#x6B63;&#x5E38;&#x5DE5;&#x4F5C;&#xFF0C;&#x505A;&#x4E86;&#x5927;&#x91CF;&#x7684;hook&#x3002;&#x8FD9;&#x91CC;&#x4E0D;&#x5173;&#x6CE8;&#x5177;&#x4F53;hook&#x5B9E;&#x73B0;&#xFF0C;&#x53EA;&#x7ED9;&#x51FA;hook&#x540E;&#x7684;&#x6620;&#x5C04;&#xFF0C;&#x611F;&#x5174;&#x8DA3;&#x7684;&#x7AE5;&#x978B;&#x53EF;&#x4EE5;&#x81EA;&#x884C;&#x7814;&#x7A76;&#x3002;</p>\n<table>\n<thead>\n<tr>\n<th>&#x66FF;&#x6362;&#x70B9;</th>\n<th>&#x5B9E;&#x73B0;&#x7C7B;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>ContextImpl.mOuterContextt</td>\n<td>DemoApplication</td>\n</tr>\n<tr>\n<td>ContextImp.mPackageInfo</td>\n<td>DemoApplication</td>\n</tr>\n<tr>\n<td>ActivityThread.mInitialApplication</td>\n<td>DemoApplication</td>\n</tr>\n<tr>\n<td>ActivityThread.mAllApplications</td>\n<td>DemoApplication</td>\n</tr>\n</tbody>\n</table>\n<h2 id=\"73-applicationattach\">7.3 Application.attach</h2>\n<pre><code class=\"lang-java\">AtlasHacks.Application_attach.invoke(mRealApplication,mRawApplication.getBaseContext());\n</code></pre>\n<p>mRealApplication&#x5B9E;&#x9645;&#x4E0A;&#x5C31;&#x662F;DemoApplication,&#x53CD;&#x5C04;&#x6267;&#x884C;application&#x7684;attach&#x65B9;&#x6CD5;,&#x5373;&#x7B2C;8&#x6B65;&#x3002;</p>\n<h2 id=\"74-&#x52A0;&#x8F7D;provider\">7.4 &#x52A0;&#x8F7D;provider</h2>\n<pre><code class=\"lang-java\">Object mBoundApplication = AtlasHacks.ActivityThread_mBoundApplication.get(activityThread);\n\nAtlasHacks.ActivityThread$AppBindData_providers.set(mBoundApplication,mBoundApplication_provider);\n\nAtlasHacks.ActivityThread_installContentProviders.invoke(activityThread,mRealApplication,mBoundApplication_provider);\n</code></pre>\n<p>&#x5728;<a href=\"atlas_start_1.html\">Atlas&#x542F;&#x52A8;&#x8FC7;&#x7A0B;(&#x4E0A;)</a>&#x7684;2.4&#x5C0F;&#x8282;&#x4E2D;&#xFF0C;&#x4E3A;&#x4E86;&#x9632;&#x6B62;&#x5728;&#x4E3B;dex&#x4E2D;&#x627E;&#x4E0D;&#x5230;bundle&#x4E2D;&#x7684;class,&#x4E0D;&#x5F97;&#x5DF2;&#x5EF6;&#x8FDF;&#x4E86;&#x5BF9;provider&#x7684;&#x52A0;&#x8F7D;&#x3002;&#x800C;&#x5728;&#x7B2C;5&#x6B65;&#x4E2D;&#xFF0C;atlas&#x5B8C;&#x6210;&#x4E86;&#x5BF9;classloader&#x7B49;&#x5173;&#x952E;&#x5730;&#x65B9;&#x7684;hook&#x3002;&#x7531;&#x4E8E;DelegateClassLoader&#x7684;&#x5B58;&#x5728;&#xFF0C;&#x6B64;&#x65F6;&#x8FDB;&#x884C;&#x52A0;&#x8F7D;provider&#xFF0C;&#x662F;&#x4E0D;&#x4F1A;&#x51FA;&#x73B0;&#x95EE;&#x9898;&#x7684;&#x3002;</p>\n<h1 id=\"8-demoapplicationattach\">8. DemoApplication.attach</h1>\n<p>DemoApplication.java</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">final</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">attach</span><span class=\"hljs-params\">(Context context)</span> </span>{\n    attachBaseContext(context);\n    mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;\n}\n</code></pre>\n<p>&#x7531;7.3&#x53EF;&#x77E5;&#xFF0C;mRealApplication&#x5B9E;&#x9645;&#x4E0A;&#x5C31;&#x662F;<code>DemoApplication</code></p>\n<ul>\n<li>&#x8C03;&#x7528;DemoApplication&#x7684;attachBaseContext&#x65B9;&#x6CD5;</li>\n<li>&#x4E3A;DemoApplication&#x521B;&#x5EFA;&#x4E00;&#x4E2A;LoadedApk&#x5BF9;&#x8C61;</li>\n</ul>\n<h1 id=\"9-startup\">9. startUp</h1>\n<p><img src=\"atlas_java_startup_img.svg\" alt=\"\"></p>\n<p>&#x5728;startup&#x6574;&#x4E2A;&#x51FD;&#x6570;&#x5468;&#x671F;&#x5185;&#xFF0C;&#x505A;&#x7684;&#x4E8B;&#x60C5;&#x975E;&#x5E38;&#x4E4B;&#x591A;&#xFF0C;&#x91CD;&#x8981;&#x7684;&#x662F;&#x7B2C;3&#x3001;4&#x3001;6&#x3001;7&#x548C;8&#x6B65;&#x3002;</p>\n<h2 id=\"93\">9.3</h2>\n<pre><code>public void init(Context context, boolean hookedJavaVM) {\n    if(VMUtil.IS_VM_ART) {\n        success = Boolean.valueOf(ARTUtils.init(context, hookedJavaVM));\n    } else {\n       success = Boolean.valueOf(DalvikUtils.init());\n   }\n}\n</code></pre><p>&#x770B;&#x51FD;&#x6570;&#x540D;&#xFF0C;&#x662F;&#x9488;&#x5BF9;art&#x548C;dalvik&#x5DE5;&#x5177;&#x7C7B;&#x8FDB;&#x884C;&#x521D;&#x59CB;&#x5316;&#x3002; </p>\n<pre><code>//DalvikUtils.java\npublic static boolean init() {\n    System.loadLibrary(&quot;dalvikhack&quot;);\n    nativeInit();\n}\n\n//ARTUtils.java\npublic static boolean init(Context context, boolean hookedJavaVM) {\n    System.loadLibrary(&quot;dexinterpret&quot;);\n    nativeInit(...);\n}\n</code></pre><h2 id=\"94\">9.4</h2>\n<pre><code>public static int patchIfPossible() {\n    System.loadLibrary(&quot;dalvikpatch&quot;);\n    if(isDalvik()) {\n           int ingored = adjustLinearAlloc();\n    }\n    return 0;\n}\n</code></pre><p>&#x9996;&#x5148;&#x52A0;&#x8F7D;<code>dalvikpatch</code>so,&#x7528;&#x9014;&#xFF1A; <strong>todo</strong> <br>\n&#x63A5;&#x7740;&#x6267;&#x884C; <code>adjustLinearAlloc</code>&#x65B9;&#x6CD5; &#xFF0C;&#x7528;&#x9014; <strong>todo</strong></p>\n<h2 id=\"97\">9.7</h2>\n<pre><code>private synchronized void InitBundleInfoByVersionIfNeed(){\n    String bundleInfoStr = (String)RuntimeVariables.getFrameworkProperty(&quot;bundleInfo&quot;);\n    if(!TextUtils.isEmpty(bundleInfoStr)) {\n        LinkedHashMap&lt;String,BundleListing.BundleInfo&gt; infos = BundleListingUtil.parseArray(bundleInfoStr);\n        BundleListing listing = new BundleListing();\n        listing.setBundles(infos);\n        mCurrentBundleListing = listing;\n    }\n}\n</code></pre><p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x51FD;&#x6570;&#x662F;&#x4ECE;<code>RuntimeVariables</code>&#x8BFB;&#x53D6;&#x5B57;&#x7B26;&#x4E32;&#xFF0C;&#x4E4B;&#x540E;&#x89E3;&#x6790;&#x6210;&#x5BF9;&#x8C61;&#x5B58;&#x50A8;&#x3002;&#x5F88;&#x660E;&#x663E;&#xFF0C;&#x8FD9;&#x4E2A;&#x5B57;&#x7B26;&#x4E32;&#x5E94;&#x8BE5;&#x662F;&#x914D;&#x7F6E;&#x4E4B;&#x7C7B;&#x7684;&#x4FE1;&#x606F;&#x3002;&#x5728;<a href=\"atlas_gradle_apk.md\">atals&#x4ECE;gradle&#x5230;apk</a>&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x63D0;&#x5230;&#x8FC7;&#xFF0C;atlas&#x4F1A;&#x5728;&#x7F16;&#x8BD1;&#x671F;&#x95F4;&#x4F1A;&#x5206;&#x6790;bundle&#x548C;gradle&#x914D;&#x7F6E;&#xFF0C;&#x5C06;&#x4E00;&#x4E9B;&#x914D;&#x7F6E;&#x5199;&#x5165;RuntimeVariables&#x4E2D;&#x3002;</p>\n<pre><code>package android.taobao.atlas.framework;\n\npublic class FrameworkProperties\n{\n  public static String autoStartBundles;\n  public static String bundleInfo = &quot;[{\\&quot;activities\\&quot;:[\\&quot;com.taobao.firstbundle.FirstBundleActivity\\&quot;],\\&quot;contentProviders\\&quot;:[],\\&quot;dependency\\&quot;:[],\\&quot;isInternal\\&quot;:true,\\&quot;pkgName\\&quot;:\\&quot;com.taobao.firstbundle\\&quot;,\\&quot;receivers\\&quot;:[],\\&quot;services\\&quot;:[\\&quot;com.taobao.firstbundle.FirstBundleService\\&quot;],\\&quot;version\\&quot;:\\&quot;1.0.0@unspecified\\&quot;},{\\&quot;activities\\&quot;:[\\&quot;com.taobao.secondbundle.SecondBundleActivity\\&quot;,\\&quot;com.taobao.secondbundlelibrary.SecondbundleShareActivity\\&quot;],\\&quot;contentProviders\\&quot;:[],\\&quot;dependency\\&quot;:[],\\&quot;isInternal\\&quot;:true,\\&quot;pkgName\\&quot;:\\&quot;com.taobao.secondbundle\\&quot;,\\&quot;receivers\\&quot;:[],\\&quot;services\\&quot;:[],\\&quot;version\\&quot;:\\&quot;1.0.0@unspecified\\&quot;},{\\&quot;activities\\&quot;:[\\&quot;com.taobao.remotebunle.RemoteBundleActivity\\&quot;],\\&quot;contentProviders\\&quot;:[],\\&quot;dependency\\&quot;:[],\\&quot;isInternal\\&quot;:false,\\&quot;pkgName\\&quot;:\\&quot;com.taobao.remotebunle\\&quot;,\\&quot;receivers\\&quot;:[],\\&quot;services\\&quot;:[],\\&quot;version\\&quot;:\\&quot;1.0.0@unspecified\\&quot;},{\\&quot;activities\\&quot;:[],\\&quot;contentProviders\\&quot;:[],\\&quot;dependency\\&quot;:[],\\&quot;isInternal\\&quot;:true,\\&quot;pkgName\\&quot;:\\&quot;com.taobao.publicBundle\\&quot;,\\&quot;receivers\\&quot;:[],\\&quot;services\\&quot;:[],\\&quot;version\\&quot;:\\&quot;1.0.0@unspecified\\&quot;}]&quot;;\n\n  static\n  {\n    autoStartBundles = &quot;com.taobao.firstbundle&quot;;\n  }\n}\n</code></pre><p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;<code>bundleInfo</code> &#x5B57;&#x6BB5;&#x662F;&#x4E00;&#x5806;json&#x5B57;&#x6BB5;&#xFF0C;&#x89E3;&#x6790;&#x540E;&#x683C;&#x5F0F;BundleInfo,&#x4FDD;&#x5B58;&#x7740;bundle&#x7684;&#x4FE1;&#x606F;&#x3002;</p>\n<pre><code>public static class BundleInfo{\n    private String pkgName;\n    private String applicationName&#xFF1B;\n    private List&lt;String&gt; dependency;\n    private HashMap&lt;String,Boolean&gt; activities;\n    private HashMap&lt;String,Boolean&gt; services;\n    private HashMap&lt;String,Boolean&gt; receivers;\n    private HashMap&lt;String,Boolean&gt; contentProviders;\n    //...\n}\n</code></pre><p>&#x4E5F;&#x5C31;&#x662F;&#x8BF4;&#xFF0C;&#x5728;&#x8FD9;&#x4E00;&#x6B65;&#xFF0C; <strong>atlas&#x83B7;&#x5F97;&#x4E86;&#x6240;&#x6709;bundle&#x7684;&#x4FE1;&#x606F;</strong> &#x3002;</p>\n<h2 id=\"98\">9.8</h2>\n<pre><code>private void started(){\n    //&#x8BFB;&#x53D6;&#x914D;&#x7F6E;\n    String autoStartBundle = (String) RuntimeVariables.getFrameworkProperty(&quot;autoStartBundles&quot;);\n    String[] bundles = autoStartBundle.split(&quot;,&quot;);\n\n    //&#x5F02;&#x6B65;&#x5B89;&#x88C5;bundle\n    for (int x = 0; x &lt; bundles.length; x++) {\n        final String bundleName = bundles[x];\n        BundleInstaller.startDelayInstall(bundleName, ...);\n    }                        \n}\n</code></pre><p>&#x7B80;&#x5316;&#x4E86;&#x5927;&#x90E8;&#x5206;&#x4EE3;&#x7801;&#xFF0C;&#x53EA;&#x5173;&#x6CE8;&#x6838;&#x5FC3;&#x903B;&#x8F91;&#x3002;&#x4EE3;&#x7801;&#x8BFB;&#x53D6;<code>RuntimeVariables</code>&#x4E0A;&#x7684;&#x5B57;&#x6BB5;<code>autoStartBundles</code>,&#x8FD9;&#x4E2A;&#x503C;&#x662F;&#x5728;gradle&#x4E2D;&#x914D;&#x7F6E;&#x7684;<code>com.taobao.firstbundle</code>&#xFF0C;&#x7136;&#x540E;&#x5F00;&#x59CB;&#x5F02;&#x6B65;&#x52A0;&#x8F7D;firstbundle</p>\n<p>bundle&#x7684;&#x52A0;&#x8F7D;&#x8FC7;&#x7A0B;&#x548C;&#x52A0;&#x8F7D;&#x89E6;&#x53D1;&#x65F6;&#x673A;&#x8BF7;&#x53C2;&#x8003; <a href=\"../atlas_bundle_load/atlas_bundle_load.html\">Atlas&#x4E4B;bundle&#x52A0;&#x8F7D;&#x8FC7;&#x7A0B;</a>&#xFF0C;&#x8FD9;&#x91CC;&#x4E0D;&#x5728;&#x8BA8;&#x8BBA;&#x3002;</p>\n<h1 id=\"10-demoapplicationoncreate\">10. DemoApplication.onCreate</h1>\n<p>DemoApplication.java</p>\n<pre><code class=\"lang-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">onCreate</span><span class=\"hljs-params\">()</span> </span>{\n    <span class=\"hljs-keyword\">super</span>.onCreate();\n    <span class=\"hljs-comment\">//...</span>\n}\n</code></pre>\n<p>&#x6267;&#x884C;app&#x5DE5;&#x7A0B;&#x5B9A;&#x4E49;&#x7684;DemoApplication&#x7684;onCreate&#x65B9;&#x6CD5;&#x3002;</p>\n<hr>\n<p>&#x81F3;&#x6B64;&#xFF0C;Atlas&#x542F;&#x52A8;&#x8FC7;&#x7A0B;&#x7684;&#x5206;&#x6790;&#x5B8C;&#x6210;&#x3002;</p>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"atlas_start_1.html\" class=\"navigation navigation-prev \" aria-label=\"Previous page: Atlas之启动过程(一)\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"../atlas_bundle_load/atlas_bundle_load.html\" class=\"navigation navigation-next \" aria-label=\"Next page: Atlas之Bundle加载过程\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"Atlas之启动过程(二)\",\"date\":\"2017-05-03T15:00:00.000Z\",\"level\":\"1.6.3\",\"depth\":2,\"next\":{\"title\":\"Atlas之Bundle加载过程\",\"level\":\"1.6.4\",\"depth\":2,\"path\":\"code_read/atlas_bundle_load/atlas_bundle_load.md\",\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.md\",\"articles\":[]},\"previous\":{\"title\":\"Atlas之启动过程(一)\",\"level\":\"1.6.2\",\"depth\":2,\"path\":\"code_read/atlas_start/atlas_start_1.md\",\"ref\":\"code_read/atlas_start/atlas_start_1.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"code_read/atlas_start/atlas_start_2.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"../..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../../gitbook/gitbook.js\"></script>\n    <script src=\"../../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/faq/dynamic_failed_help.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>动态部署失败排查指南 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    \n    <link rel=\"prev\" href=\"variant.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../guide-for-use/\">\n            \n                <a href=\"../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../update/\">\n            \n                <a href=\"../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../update/principle.html\">\n            \n                <a href=\"../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../update/dexpatch.html\">\n            \n                <a href=\"../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../update/guide.html\">\n            \n                <a href=\"../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"question.html\">\n            \n                <a href=\"question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"help.html\">\n            \n                <a href=\"help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"variant.html\">\n            \n                <a href=\"variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.5.4\" data-path=\"dynamic_failed_help.html\">\n            \n                <a href=\"dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >动态部署失败排查指南</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <p>title: &#x52A8;&#x6001;&#x90E8;&#x7F72;&#x6392;&#x67E5;&#x7ECF;&#x9A8C;\ndate: 2014-12-22 12:39:04</p>\n<h1 id=\"&#x6982;&#x8FF0;\">&#x6982;&#x8FF0;</h1>\n<p>&#x7ECF;&#x5E38;&#x6709;&#x540C;&#x5B66;&#x5728;&#x7B54;&#x7591;&#x7FA4;&#x4E0A;&#x63D0;&#x51FA;&#x7591;&#x95EE;<code>&#x4E3A;&#x4EC0;&#x4E48;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x4E0D;&#x751F;&#x6548;&#xFF1F;</code>&#xFF0C;&#x7136;&#x540E;&#x5C31;&#x662F;&#x4E00;&#x901A;&#x6392;&#x67E5;&#x3002;&#x7531;&#x4E8E;&#x662F;&#x8FDC;&#x7A0B;&#x4EA4;&#x6D41;&#xFF0C;&#x4EE3;&#x4EF7;&#x5B9E;&#x5728;&#x662F;&#x592A;&#x9AD8;&#x3002;&#x8FD9;&#x7BC7;&#x6587;&#x7AE0;&#x4E3B;&#x8981;&#x662F;&#x548C;&#x5927;&#x5BB6;&#x5206;&#x4EAB;&#x4E00;&#x4E0B;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x6392;&#x67E5;&#x7684;&#x4E00;&#x4E9B;&#x7ECF;&#x9A8C;&#xFF0C;&#x5E0C;&#x671B;&#x80FD;&#x591F;&#x5E2E;&#x52A9;&#x5927;&#x5BB6;&#x5FEB;&#x901F;&#x5B9A;&#x4F4D;&#x3001;&#x89E3;&#x51B3;&#x95EE;&#x9898;&#x3002;</p>\n<p>&#x53E6;&#x5916;&#xFF0C;&#x6839;&#x636E;&#x5386;&#x53F2;&#x7ECF;&#x9A8C;&#xFF0C;&#x5927;&#x90E8;&#x5206;&#x90FD;&#x662F;&#x4F7F;&#x7528;&#x4E0D;&#x89C4;&#x8303;&#x9020;&#x6210;&#x7684;&#xFF0C;&#x4E3A;&#x4E86;&#x907F;&#x514D;&#x8FD9;&#x4E9B;&#x5947;&#x5947;&#x602A;&#x602A;&#x7684;&#x95EE;&#x9898;&#xFF0C;&#x5927;&#x5BB6;&#x6700;&#x597D;&#x6309;&#x7167;<a href=\"https://alibaba.github.io/atlas/\" target=\"_blank\">Atlas&#x5DE5;&#x7A0B;&#x7ED3;&#x6784;&#x6307;&#x5357;</a>&#x4EE5;&#x53CA;<a href=\"https://alibaba.github.io/atlas/guide-for-use/guide_for_build.html\" target=\"_blank\">&#x5BB9;&#x5668;&#x63A5;&#x5165;</a> &#x8FD9;&#x4E24;&#x7BC7;&#x6587;&#x7AE0;&#x63D0;&#x5230;&#x7684;&#x89C4;&#x8303;&#xFF0C;&#x6765;&#x7EC4;&#x7EC7;&#x5DE5;&#x7A0B;&#x7ED3;&#x6784;&#x3002;</p>\n<h1 id=\"&#x5FEB;&#x901F;&#x6392;&#x67E5;&#x4E09;&#x8FDE;\">&#x5FEB;&#x901F;&#x6392;&#x67E5;&#x4E09;&#x8FDE;</h1>\n<p>&#x4ECE;demo&#x4E2D;&#x4E00;&#x4E2A;&#x4F8B;&#x5B50;&#x5F00;&#x59CB;&#xFF0C;&#x5047;&#x8BBE;&#x6211;&#x4EEC;&#x53D1;&#x4E86;1.0.0&#x7684;Ap,&#x4E4B;&#x540E;&#x4FEE;&#x6539;&#x4E86;splashscreen&#x548C;firstbundle&#x4E24;&#x4E2A;&#x5730;&#x65B9;&#x7684;&#x4EE3;&#x7801;,<strong>&#x5E76;&#x4E14;&#x4FEE;&#x6539;&#x4E86;&#x5BF9;&#x5E94;&#x7684;&#x7248;&#x672C;&#x53F7;</strong></p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\"></th>\n<th style=\"text-align:left\">&#x57FA;&#x7EBF;&#x7248;&#x672C;</th>\n<th style=\"text-align:left\">&#x65B0;&#x7248;&#x672C;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">&#x6574;&#x5305;(apk)</td>\n<td style=\"text-align:left\">1.0.0</td>\n<td style=\"text-align:left\">1.0.1</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">splashscreen&#xFF08;maindex&#xFF09;</td>\n<td style=\"text-align:left\">1.0.0</td>\n<td style=\"text-align:left\">1.0.1</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">firstbundle&#xFF08;bundle&#xFF09;</td>\n<td style=\"text-align:left\">1.0.1</td>\n<td style=\"text-align:left\">1.0.2</td>\n</tr>\n</tbody>\n</table>\n<h2 id=\"1-&#x6253;&#x5305;&#x4EA7;&#x7269;&#x68C0;&#x67E5;\">1. &#x6253;&#x5305;&#x4EA7;&#x7269;&#x68C0;&#x67E5;</h2>\n<p>&#x9996;&#x5148;&#x68C0;&#x67E5;&#x6253;&#x5305;&#x7684;&#x4EA7;&#x7269;&#xFF0C;&#x6309;&#x7167;&#x5386;&#x53F2;&#x7ECF;&#x9A8C;&#xFF0C;90%&#x7684;&#x95EE;&#x9898;&#x90FD;&#x662F;&#x56E0;&#x4E3A;&#x6253;&#x5305;&#x4EA7;&#x7269;&#x4E0D;&#x5BF9;&#x9020;&#x6210;&#x7684;&#x3002;</p>\n<h3 id=\"&#x7B2C;&#x4E00;&#x70B9;&#xFF0C;&#x4F9D;&#x8D56;&#x53D8;&#x52A8;\">&#x7B2C;&#x4E00;&#x70B9;&#xFF0C;&#x4F9D;&#x8D56;&#x53D8;&#x52A8;</h3>\n<p>&#x6253;&#x5F00;&#x4EA7;&#x7269;&#x4E2D;&#x7684;<code>dependencyDiff.json</code>&#x7684;&#x6587;&#x4EF6;&#xFF0C;&#x8FD9;&#x4E2A;&#x6587;&#x4EF6;&#x8BB0;&#x5F55;&#x4E86;&#x672C;&#x6B21;&#x6539;&#x52A8;&#x76F8;&#x5BF9;<code>AP</code>&#x7684;&#x4F9D;&#x8D56;&#x53D8;&#x5316;&#x4FE1;&#x606F;</p>\n<pre><code>{\n    &quot;awbDiffs&quot;:[&quot;com.atlas.demo:firstbundle&quot;],\n    &quot;mainDexDiffs&quot;:[&quot;com.atlas.demo:splashscreen(1.0.0@aar=&gt;1.0.1@aar)&quot;],\n    &quot;modifyLines&quot;:[\n        &quot;com.atlas.demo:firstbundle(1.0.1=&gt;1.0.2)&quot;\n    ],\n    &quot;newAwbs&quot;:[]\n}\n</code></pre><p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;firstbundle &#x548C; splashscreen &#x7684;&#x7248;&#x672C;&#x53D8;&#x5316;&#x548C;&#x6539;&#x52A8;&#x4E00;&#x81F4;&#xFF0C;&#x6CA1;&#x6709;&#x95EE;&#x9898;&#x3002;</p>\n<p>&#x5982;&#x679C;&#x5BF9;&#x4E0D;&#x4E0A;&#xFF0C;&#x8BF4;&#x660E;&#x6253;&#x5305;&#x4EA7;&#x7269;&#x9519;&#x8BEF;&#xFF0C;&#x4E0B;&#x9762;&#x662F;&#x4E24;&#x4E2A;&#x5E38;&#x89C1;&#x7684;&#x539F;&#x56E0;&#xFF0C;&#x9700;&#x8981;&#x540C;&#x5B66;&#x4EEC;&#x81EA;&#x5DF1;&#x505A;&#x4E00;&#x4E0B;&#x6392;&#x67E5;&#x3002;</p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">&#x6839;&#x672C;&#x539F;&#x56E0;</th>\n<th style=\"text-align:left\">&#x53EF;&#x80FD;&#x7684;&#x9519;&#x8BEF;&#x64CD;&#x4F5C;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">&#x4FEE;&#x6539;&#x5F15;&#x5165;&#x4E86;&#x5176;&#x5B83;&#x9690;&#x542B;&#x7684;&#x6539;&#x52A8;</td>\n<td style=\"text-align:left\">&#x5728;&#x53D1;&#x5E03;lib/bundle&#x7248;&#x672C;&#x65F6;&#xFF0C;&#x5E26;&#x52A8;&#x4E86;&#x5176;&#x5B83;lib&#xFF0F;bundle&#x7684;&#x7248;&#x672C;&#x53D8;&#x5316;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">AP&#x4E0D;&#x5BF9;,mvn&#x4ED3;&#x5E93;&#x4E2D;&#x7684;AP&#xFF0C;&#x548C;&#x9884;&#x671F;&#x7684;&#x4E0D;&#x662F;&#x540C;&#x4E00;&#x4E2A;</td>\n<td style=\"text-align:left\">1.&#x91CD;&#x65B0;publish&#x4E86;AP,&#x8001;AP&#x88AB;&#x8986;&#x76D6;&#x4E86;<br>2.gradle&#x5728;&#x672C;&#x5730;&#x4ED3;&#x5E93;&#x505A;&#x4E86;&#x4E00;&#x4EFD;cache&#xFF0C;&#x662F;&#x5426;&#x548C;&#x8FDC;&#x7A0B;&#x4ED3;&#x5E93;&#x4E2D;&#x7684;&#x4E00;&#x81F4;</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"&#x7B2C;&#x4E8C;&#x70B9;&#xFF0C;&#x9A8C;&#x8BC1;&#x914D;&#x7F6E;&#x6587;&#x4EF6;\">&#x7B2C;&#x4E8C;&#x70B9;&#xFF0C;&#x9A8C;&#x8BC1;&#x914D;&#x7F6E;&#x6587;&#x4EF6;</h3>\n<p>&#x6253;&#x5F00;<code>update-1.0.0.json</code></p>\n<pre><code>{\n    //&#x57FA;&#x7EBF;&#x7248;&#x672C;\n    &quot;baseVersion&quot;:&quot;1.0.0&quot;,\n    &quot;updateBundles&quot;:[\n        {\n            &quot;dependency&quot;:[\n                &quot;com.taobao.publicBundle&quot;\n            ],\n            &quot;isMainDex&quot;:false,\n            &quot;name&quot;:&quot;com.taobao.firstbundle&quot;,\n            //&#x57FA;&#x7EBF;&#x4F9D;&#x8D56;1.0.0&#x4E2D;&#x7684;&#x552F;&#x4E00;tag\n            &quot;srcUnitTag&quot;:&quot;1lxlheevwoeeg&quot;,\n            //&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7248;&#x672C;1.0.1&#x7684;tag\n            &quot;unitTag&quot;:&quot;1x6r8iuzs90ff&quot;,\n            &quot;version&quot;:&quot;1.0.0@1.0.2&quot;\n        },\n        {\n            &quot;isMainDex&quot;:true,\n            &quot;name&quot;:&quot;com.taobao.maindex&quot;,\n            &quot;srcUnitTag&quot;:&quot;1nf3phs9djbuj&quot;,\n            &quot;unitTag&quot;:&quot;31jv86qvt1gc&quot;,\n            &quot;version&quot;:&quot;1.0.0@1.0.1&quot;\n        }\n    ],\n    //&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x66F4;&#x65B0;&#x7248;&#x672C;\n    &quot;updateVersion&quot;:&quot;1.0.1&quot;\n}\n</code></pre><ol>\n<li><p>&#x6D89;&#x53CA;&#x6539;&#x52A8;&#x786E;&#x8BA4;&#xFF0C;&#x914D;&#x7F6E;&#x4E2D;&#x7684;diff&#x4FE1;&#x606F;&#x548C;&#x6211;&#x4EEC;&#x7684;&#x6539;&#x52A8;&#x4E00;&#x81F4;&#xFF08;&#x4E24;&#x4E2A;&#x90E8;&#x5206;&#xFF0C;firstbundle&#x548C;maindex&#xFF09;</p>\n</li>\n<li><p>&#x6D89;&#x53CA;&#x7248;&#x672C;&#x786E;&#x8BA4;&#xFF0C;<code>baseVersion</code>(1.0.0), <code>updateVersion</code>(1.0.1),&#x5206;&#x522B;&#x5BF9;&#x5E94;&#x6253;&#x5305;&#x547D;&#x4EE4;&#x7684;<code>apVersion</code>&#x548C;<code>versionName</code>,&#x8868;&#x660E;&#x662F;1.0.0-&gt;1.0.1&#x7684;diff&#x4FE1;&#x606F;&#x3002;</p>\n</li>\n<li>srcUnitTag &#x548C; unittag&#x786E;&#x8BA4;&#x3002;&#xFF08;&#x5982;&#x679C;&#x540C;&#x5B66;&#x4EEC;&#x6CA1;&#x6709;&#x6309;&#x7167;&#x89C4;&#x8303;&#x6765;&#xFF0C;&#x8FD9;&#x4E2A;&#x5730;&#x65B9;&#x5F88;&#x5BB9;&#x6613;&#x51FA;&#x9519;&#xFF0C;&#x5BFC;&#x81F4;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x5931;&#x8D25;&#xFF09;</li>\n</ol>\n<p>&#x5173;&#x4E8E;&#x7B2C;&#x4E09;&#x4E2A;&#xFF0C;&#x6211;&#x4EEC;&#x4EE5;firstbundle&#x4E3A;&#x4F8B;&#xFF0C;&#x8BE6;&#x7EC6;&#x8BF4;&#x660E;&#x3002;&#x9996;&#x5148;&#xFF0C;&#x770B;&#x4E0B;&#x5728;&#x914D;&#x7F6E;&#x6587;&#x4EF6;<code>update-1.0.0.json</code>&#x4E2D;&#x7684;&#x503C;:</p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">key</th>\n<th style=\"text-align:left\">val</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">srcUnitTag</td>\n<td style=\"text-align:left\">1lxlheevwoeeg</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">unitTag</td>\n<td style=\"text-align:left\">1x6r8iuzs90ff</td>\n</tr>\n</tbody>\n</table>\n<p>ok,&#x6211;&#x4EEC;&#x518D;&#x89E3;&#x538B;1.0.0&#x7684;ap&#x6587;&#x4EF6;&#xFF0C;&#x6253;&#x5F00;<code>atlasFrameworkProperties.json</code>&#x6587;&#x4EF6;&#xFF0C;&#x5173;&#x952E;&#x5B57;&#x641C;&#x7D22;<code>com.taobao.firstbundle</code></p>\n<pre><code>{\n    &quot;bundleInfo&quot;:[\n        {\n            &quot;pkgName&quot;:&quot;com.taobao.firstbundle&quot;,\n            &quot;unique_tag&quot;:&quot;1lxlheevwoeeg&quot;,\n            &quot;version&quot;:&quot;1.0.0@1.0.1&quot;\n        },\n        //...\n    ]\n}\n</code></pre><p>&#x5404;&#x4F4D;&#xFF0C;&#x6709;&#x6CA1;&#x6709;&#x7075;&#x5149;&#x4E00;&#x95EA;&#xFF1F;&#x662F;&#x7684;&#xFF0C;unittag&#x548C;srcunittag&#x662F;&#x6709;&#x8054;&#x7CFB;&#x7684;&#xFF0C;&#x5BA2;&#x6237;&#x7AEF;&#x7528;&#x6765;&#x9A8C;&#x8BC1;patch&#x7684;&#x5408;&#x6CD5;&#x6027;&#xFF0C;&#x770B;&#x56FE;:</p>\n<p><img src=\"dynamic_help_img/unit_tag_list.png\" alt=\"\"></p>\n<p>&#x4EE5;&#x4E0A;&#x662F;&#x6B63;&#x786E;&#x7684;&#x4F7F;&#x7528;&#x59FF;&#x52BF;&#xFF0C;&#x4E0B;&#x9762;&#x662F;&#x5E38;&#x89C1;&#x7684;&#x4E00;&#x4E9B;&#x5E38;&#x89C1;&#x7684;&#x9519;&#x8BEF;</p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">&#x9519;&#x8BEF;</th>\n<th style=\"text-align:left\">&#x539F;&#x56E0;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\"><code>update-xxx.json</code>&#x4E2D;bundle&#x7684;srcUnittag&#x548C;<code>AP</code>&#x4E2D;&#x7684;unitttag&#x4E0D;&#x4E00;&#x6837;</td>\n<td style=\"text-align:left\">AP&#x4E0D;&#x5BF9;&#xFF0C;&#x6BD4;&#x5BF9;&#x7684;AP&#x548C;&#x9884;&#x60F3;&#x7684;&#x4E0D;&#x662F;&#x540C;&#x4E00;&#x4E2A;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">&#x5728;update-xxx.json&#x6587;&#x4EF6;&#x4E2D;&#xFF0C;&#x67D0;&#x4E2A;bundle&#x7684;srcUnittag&#x548C;unittag&#x4E00;&#x6837;</td>\n<td style=\"text-align:left\">&#x901A;&#x5E38;&#x6765;&#x8BF4;&#x90FD;&#x662F;&#x6539;&#x4E86;&#x4EE3;&#x7801;&#xFF0C;&#x4F46;&#x662F;&#x6CA1;&#x6709;&#x53D8;&#x66F4;&#x4F9D;&#x8D56;lib/bundle&#x7684;&#x7248;&#x672C;&#x53F7;</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"&#x7B2C;&#x4E09;&#x70B9;&#xFF0C;diff&#x4EE3;&#x7801;&#x9A8C;&#x8BC1;\">&#x7B2C;&#x4E09;&#x70B9;&#xFF0C;diff&#x4EE3;&#x7801;&#x9A8C;&#x8BC1;</h3>\n<p>&#x89E3;&#x538B;tpatch</p>\n<pre><code>&#x2514;&#x2500;&#x2500; patch-1.0.1@1.0.0\n    &#x251C;&#x2500;&#x2500; libcom_taobao_firstbundle\n    &#x2502;   &#x2514;&#x2500;&#x2500; classes.dex\n    &#x2514;&#x2500;&#x2500; libcom_taobao_maindex.so\n</code></pre><p>&#x53CD;&#x7F16;&#x8BD1;Dex&#xFF0C;&#x67E5;&#x770B;patch&#x51FA;&#x6765;&#x7684;&#x4EE3;&#x7801;&#x548C;&#x4FEE;&#x6539;&#x7684;&#x662F;&#x5426;&#x4E00;&#x81F4;&#x3002;</p>\n<p>&#x6BD4;&#x5982;&#x4FEE;&#x6539;&#x4E86;firstbundle &#x4E2D;&#x7684;<code>first.java</code>&#x548C;splashscreen&#x4E2D;&#x7684;<code>maindex.java</code>,diff&#x51FA;&#x6765;&#x7684;&#x4EA7;&#x7269;&#x5C31;&#x4E00;&#x5B9A;&#x5982;&#x4E0A;&#x56FE;&#x6240;&#x793A;:</p>\n<ul>\n<li>libcom_taobao_firstbundle&#xFF0C;&#x53CD;&#x7F16;&#x8BD1;classes.dex&#xFF0C;&#x6709;&#x4E14;&#x53EA;&#x6709;<code>first.class</code>&#x8FD9;&#x4E2A;diff</li>\n<li>libcom_taobao_maindex.so&#xFF0C;&#x89E3;&#x538B;&#x53CD;&#x7F16;&#x8BD1;classes.dex&#xFF0C;&#x6709;&#x4E14;&#x53EA;&#x6709;<code>maindex.class</code>&#x8FD9;&#x4E2A;diff</li>\n<li>&#x6539;&#x4E86;&#x51E0;&#x4E2A;&#x7C7B;&#x8FD9;&#x91CC;&#x5C31;&#x4F1A;&#x5BF9;&#x5E94;diff&#x51FA;&#x51E0;&#x4E2A;&#xFF0C;<strong>&#x4E0D;&#x4F1A;&#x591A;&#x4E5F;&#x4E0D;&#x4F1A;&#x5C11;</strong>&#x3002;</li>\n</ul>\n<p>&#x5982;&#x679C;&#x6709;&#x5F02;&#x5E38;&#xFF0C;&#x548C;&#x7B2C;&#x4E0A;&#x9762;&#x4E00;&#x6837;</p>\n<ul>\n<li>&#x8FD8;&#x662F;AP&#x6709;&#x95EE;&#x9898;</li>\n<li>&#x6216;&#x8005;&#x672C;&#x6B21;&#x4FEE;&#x6539;&#x9690;&#x542B;&#x5E26;&#x5165;&#x4E86;&#x5176;&#x5B83;&#x6539;&#x52A8;&#x3002;</li>\n</ul>\n<h2 id=\"2-&#x5BA2;&#x6237;&#x7AEF;&#x68C0;&#x67E5;\">2. &#x5BA2;&#x6237;&#x7AEF;&#x68C0;&#x67E5;</h2>\n<p>&#x901A;&#x5E38;&#x6765;&#x8BF4;&#xFF0C;&#x5982;&#x679C;&#x6253;&#x5305;&#x4EA7;&#x7269;&#x5982;&#x679C;&#x6CA1;&#x6709;&#x95EE;&#x9898;&#xFF0C;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x4E00;&#x822C;&#x90FD;&#x662F;&#x53EF;&#x4EE5;&#x6B63;&#x5E38;&#x751F;&#x6548;&#x7684;&#x3002;</p>\n<p>&#x9996;&#x5148;&#xFF0C;<strong>&#x786E;&#x4FDD;&#x624B;&#x673A;&#x5B58;&#x50A8;&#x5361;&#x5BB9;&#x91CF;&#x8DB3;&#x591F;(&#x81F3;&#x5C11;100m&#x5427;)</strong>&#xFF0C;&#x7136;&#x540E;&#x5728;&#x8FDB;&#x884C;&#x4E0B;&#x9762;&#x7684;&#x6392;&#x67E5;&#x6B65;&#x9AA4;&#x3002;</p>\n<p>&#x6309;&#x7167;&#x6587;&#x6863;&#xFF0C;&#x89E6;&#x53D1;patch&#x66F4;&#x65B0;&#x64CD;&#x4F5C;&#xFF0C;&#x89C2;&#x5BDF;&#x672C;&#x5730;&#x4E0A;&#x4E24;&#x4E2A;&#x5730;&#x65B9;</p>\n<pre><code>/data/data/\\${pkg}/files/bundleBaseline/updateinfo\n/data/data/pkg/files/storage/\\${bundle\\_pkg\\_name}/bundle.zip\n</code></pre><p>pkg&#x4E3A;app&#x7684;&#x5305;&#x540D;</p>\n<p>&#x5982;&#x679C;&#x540C;&#x65F6;&#x5B58;&#x5728;<code>updateinfo</code>&#x548C;<code>updateinfo_new</code>&#x4E24;&#x4E2A;&#x6587;&#x4EF6;,&#x4EE5;<code>updateinfo_new</code>&#x4E3A;&#x51C6;</p>\n<p>bundle_pkg_name&#x4E3A;bundle&#x7684;&#x5305;&#x540D;&#xFF0C;maindex&#x7684;&#x5305;&#x540D;&#x4E3A;<code>com.taobao.maindex</code></p>\n<h3 id=\"&#x91CD;&#x542F;&#x524D;\">&#x91CD;&#x542F;&#x524D;</h3>\n<p>&#x5728;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x63D0;&#x793A;&#x91CD;&#x542F;&#x524D;&#xFF0C;&#x6267;&#x884C; <code>cat updateInfo</code> &#x547D;&#x4EE4;</p>\n<pre><code>1.0.1Ecom.taobao.maindex@31jv86qvt1gc;com.taobao.firstbundle@1x6r8iuzs90ff;\n</code></pre><p>&#x683C;&#x5F0F;&#x5F88;&#x7B80;&#x5355;</p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7248;&#x672C;</th>\n<th style=\"text-align:left\">maindex tag</th>\n<th style=\"text-align:left\">firstbudnle tag</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">1.0.1</td>\n<td style=\"text-align:left\">31jv86qvt1gc</td>\n<td style=\"text-align:left\">1x6r8iuzs90ff</td>\n</tr>\n</tbody>\n</table>\n<p>&#x5BF9;&#x5E94;&#x524D;&#x9762;&#x6253;&#x5305;&#x4EA7;&#x7269;<code>update-1.0.0.json</code>&#x4E2D;&#x7684;&#x8BB0;&#x5F55;&#x7684;unittag&#xFF0C;&#x6570;&#x636E;&#x6CA1;&#x6709;&#x95EE;&#x9898;&#x3002;</p>\n<p>&#x67E5;&#x770B;merge&#x7684;&#x4EA7;&#x7269;&#x662F;&#x5426;&#x5B58;&#x5728;&#xFF0C;&#x4EE5;firstbundle&#x4E3A;&#x4F8B;&#xFF0C;maindex&#x540C;&#x7406;&#x3002;</p>\n<p>cd&#x5230;&#x548C;<code>/data/data/com.taobao.demo/files/storage/com.taobao.firstbundle</code></p>\n<pre><code>bullhead:/data/data/com.taobao.demo/files/storage/com.taobao.firstbundle # ls\n1x6r8iuzs90ff lock\n</code></pre><p>&#x76EE;&#x5F55;&#x540D;&#x4E3A;&#x8BB0;&#x5F55;&#x7684;tag<code>1x6r8iuzs90ff</code>,cd &#x8FDB;&#x53BB;</p>\n<pre><code>bullhead:/data/data/com.taobao.demo/files/storage/com.taobao.firstbundle/1x6r8iuzs90ff # ls\nbundle.dex bundle.zip lock meta\n</code></pre><p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x4EA7;&#x7269;merge&#x6210;&#x529F;&#x4E86;&#xFF0C;&#x53CD;&#x7F16;&#x8BD1;budnle.zip&#xFF08;apk&#xFF09;&#xFF0C;&#x53EF;&#x4EE5;&#x9A8C;&#x8BC1;&#x6539;&#x52A8;</p>\n<h3 id=\"&#x91CD;&#x542F;&#x540E;\">&#x91CD;&#x542F;&#x540E;</h3>\n<p>&#x8FD8;&#x662F;&#x67E5;&#x770B;&#x8FD9;&#x4E24;&#x4E2A;&#x6587;&#x4EF6;&#xFF0C;updateinfo&#x7684;&#x5185;&#x5BB9;&#x6709;&#x6CA1;&#x6709;&#x53D8;&#xFF0C;&#x6216;&#x8005;storage&#x4E0B;merge&#x540E;bundle&#x7684;&#x4EA7;&#x7269;&#x662F;&#x5426;&#x5B58;&#x5728;</p>\n<pre><code>/data/data/\\${pkg}/files/bundleBaseline/updateinfo\n/data/data/pkg/files/storage/\\${bundle\\_pkg\\_name}/bundle.zip\n</code></pre><p>&#x6CA1;&#x6709;&#x5F02;&#x5E38;&#xFF0C;&#x8BF4;&#x660E;&#x672C;&#x6B21;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x751F;&#x6548;&#x3002;</p>\n<p>&#x5982;&#x679C;&#x6709;&#x5F02;&#x5E38;&#xFF0C;&#x8FD4;&#x56DE;&#x68C0;&#x67E5;&#x7B2C;&#x4E00;&#x6B65;&#x7684;&#x4EA7;&#x7269;&#x3002;</p>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"variant.html\" class=\"navigation navigation-prev navigation-unique\" aria-label=\"Previous page: 构建定制包\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"动态部署失败排查指南\",\"level\":\"1.5.4\",\"depth\":2,\"next\":{\"title\":\"源码分析\",\"level\":\"1.6\",\"depth\":1,\"ref\":\"\",\"articles\":[{\"title\":\"Atlas之Gradle配置\",\"level\":\"1.6.1\",\"depth\":2,\"path\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.md\",\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.md\",\"articles\":[]},{\"title\":\"Atlas之启动过程(一)\",\"level\":\"1.6.2\",\"depth\":2,\"path\":\"code_read/atlas_start/atlas_start_1.md\",\"ref\":\"code_read/atlas_start/atlas_start_1.md\",\"articles\":[]},{\"title\":\"Atlas之启动过程(二)\",\"level\":\"1.6.3\",\"depth\":2,\"path\":\"code_read/atlas_start/atlas_start_2.md\",\"ref\":\"code_read/atlas_start/atlas_start_2.md\",\"articles\":[]},{\"title\":\"Atlas之Bundle加载过程\",\"level\":\"1.6.4\",\"depth\":2,\"path\":\"code_read/atlas_bundle_load/atlas_bundle_load.md\",\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.md\",\"articles\":[]}]},\"previous\":{\"title\":\"构建定制包\",\"level\":\"1.5.3\",\"depth\":2,\"path\":\"faq/variant.md\",\"ref\":\"faq/variant.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"faq/dynamic_failed_help.md\",\"mtime\":\"2017-11-27T09:41:52.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/faq/help.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>故障排查 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"variant.html\" />\n    \n    \n    <link rel=\"prev\" href=\"question.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../guide-for-use/\">\n            \n                <a href=\"../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../update/\">\n            \n                <a href=\"../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../update/principle.html\">\n            \n                <a href=\"../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../update/dexpatch.html\">\n            \n                <a href=\"../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../update/guide.html\">\n            \n                <a href=\"../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"question.html\">\n            \n                <a href=\"question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.5.2\" data-path=\"help.html\">\n            \n                <a href=\"help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"variant.html\">\n            \n                <a href=\"variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"dynamic_failed_help.html\">\n            \n                <a href=\"dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >故障排查</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"&#x5E38;&#x89C1;&#x95EE;&#x9898;\">&#x5E38;&#x89C1;&#x95EE;&#x9898;</h1>\n<p><strong>&#x6709;&#x4EFB;&#x4F55;&#x7684;&#x5EFA;&#x8BAE;&#x548C;&#x95EE;&#x9898;&#x8BF7;&#x5728;github&#x4E0A;&#x63D0;issue&#x7ED9;&#x6211;&#x4EEC;&#xFF0C;&#x6211;&#x4EEC;&#x4F1A;&#x5C3D;&#x5FEB;&#x56DE;&#x590D;&#xFF0C;&#x540C;&#x65F6;&#x9AD8;&#x9891;&#x7684;&#x4F1A;&#x66F4;&#x65B0;&#x7684;FAQ&#x6587;&#x6863;&#x4E2D;</strong></p>\n<ul>\n<li><p><strong>&#x9700;&#x8981;&#x53BB;&#x9664;&#x7684;&#x539F;&#x751F;multidex&#x521D;&#x59CB;&#x5316;</strong></p>\n<p> Atlas&#x5BB9;&#x5668;&#x5185;&#x90E8;&#x96C6;&#x6210;&#x4E86;multidex&#x7684;dex&#x5B89;&#x88C5;&#x529F;&#x80FD;&#xFF0C;&#x6240;&#x4EE5;&#x539F;&#x5148;multidex&#x7684;&#x521D;&#x59CB;&#x5316;&#x4EE3;&#x7801;&#x53EF;&#x4EE5;&#x7701;&#x7565;&#xFF0C;&#x4E5F;&#x4E0D;&#x9700;&#x8981;&#x6DFB;&#x52A0;multidex&#x7684;&#x4E09;&#x65B9;&#x5E93;&#x4F9D;&#x8D56;&#xFF0C;&#x9700;&#x8981;&#x4F7F;&#x7528;multidex&#x7684;&#x53EA;&#x9700;&#x8981;build.gradle&#x5185;&#x90E8;&#x5C06;multidex&#x7F6E;&#x4E3A;enable&#x5373;&#x53EF;&#xFF08;Atlas&#x5185;&#x90E8;&#x96C6;&#x6210;&#x8BE5;&#x5185;&#x5BB9;&#x4E00;&#x65B9;&#x9762;&#x662F;&#x4FBF;&#x4E8E;&#x548C;&#x5BB9;&#x5668;&#x7684;&#x517C;&#x5BB9;&#xFF0C;&#x53E6;&#x4E00;&#x65B9;&#x9762;&#x540E;&#x7EED;&#x5BB9;&#x5668;&#x4F1A;&#x4F18;&#x5316;&#x539F;&#x751F;multidex&#x5728;dalvik&#x4E0A;&#x9762;&#x7684;&#x6027;&#x80FD;&#xFF09;</p>\n</li>\n</ul>\n<p>&gt;\n<img src=\"help_img/multidex.png\" alt=\"MacDown Screenshot\"></p>\n<ul>\n<li><p><strong>ClassNotFoundException</strong></p>\n<ol>\n<li>Bundle&#x5982;&#x679C;&#x76F8;&#x4E92;&#x4F9D;&#x8D56;&#xFF0C;&#x5219;&#x6784;&#x5EFA;&#x8D77;&#x9700;&#x8981;&#x914D;&#x7F6E;dependency&#xFF0C;&#x5426;&#x5219;&#x8FD0;&#x884C;&#x671F;&#x4F1A;&#x65E0;&#x6CD5;&#x627E;&#x5230;&#x88AB;&#x4F9D;&#x8D56;bundle&#x5185;&#x7684;class&#xFF0C;&#x4E14;&#x4E0D;&#x652F;&#x6301;&#x4E3A;&#x4E86;&#x67E5;&#x627E;&#x6027;&#x80FD;&#xFF0C;&#x76EE;&#x524D;&#x4E0D;&#x652F;&#x6301;&#x4E8C;&#x7EA7;&#x4F9D;&#x8D56;&#xFF1A;&#x6BD4;&#x5982;A-&gt;B-&gt;C,&#x5982;&#x679C;A&#x6CA1;&#x6709;&#x663E;&#x5F0F;&#x58F0;&#x660E;&#x4F9D;&#x8D56;C&#xFF0C;&#x5219;A bundle&#x91CC;&#x9762;&#x65E0;&#x6CD5;&#x76F4;&#x63A5;&#x4F7F;&#x7528;bundle C&#x91CC;&#x9762;&#x7684;Class&#xFF0C;&#x68C0;&#x67E5;bundle&#x4F9D;&#x8D56;&#x662F;&#x5426;&#x6210;&#x529F;&#x914D;&#x7F6E;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x53CD;&#x7F16;&#x8BD1;Apk&#x7684;&#x4E3B;dex &#x67E5;&#x770B;<strong>android.taobao.atlas.framework.FrameworkProperties</strong>&#x7684;field bundleInfo&#x7684;&#x5185;&#x5BB9;&#xFF0C;&#x91CC;&#x9762;&#x8BB0;&#x5F55;&#x4E86;&#x6240;&#x6709;bundle&#x7684;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;</li>\n<li>&#x901A;&#x8FC7;LayoutInflater &#x81A8;&#x5316;xml&#xFF0C;&#x5219;xml&#x91CC;&#x9762;&#x5982;&#x679C;&#x6709;richview&#xFF0C;&#x5219;&#x52A1;&#x5FC5;&#x786E;&#x4FDD;LayoutInflater&#x6301;&#x6709;&#x7684;context&#x7684;classloader&#x53EF;&#x4EE5;load&#x5230;&#x8BE5;richview&#xFF0C;&#x5047;&#x8BBE;context&#x6765;&#x81EA;&#x4E8E;A bundle&#x7684;Activity&#xFF0C;&#x800C;xml&#x6765;&#x81EA;&#x4E8E;B bundle&#xFF0C;&#x5982;&#x679C;A&#x548C;B&#x6CA1;&#x6709;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#xFF0C;&#x90A3;&#x4E48;&#x52A0;&#x8F7D;&#x4E5F;&#x80AF;&#x5B9A;&#x5931;&#x8D25;</li>\n</ol>\n</li>\n<li><p><strong>NoClassDefFoundError</strong></p>\n<p>&#x9020;&#x6210;&#x8BE5;&#x95EE;&#x9898;&#x7684;&#x539F;&#x56E0;&#x6BD4;&#x8F83;&#x591A;&#xFF0C;&#x6392;&#x67E5;&#x6B65;&#x9AA4;&#x7B2C;&#x4E00;&#x4E2A;&#x5148;&#x68C0;&#x67E5;Exception&#x7684;&#x6E90;&#x5934;&#x662F;&#x4E0D;&#x662F;ClassNotFoundException&#xFF0C;&#x7136;&#x540E;&#x53CD;&#x7F16;&#x8BD1;&#x6392;&#x67E5;&#x7C7B;&#x786E;&#x5B9E;&#x662F;&#x5426;&#x5B58;&#x5728;&#xFF1B;</p>\n<p>&#x5982;&#x679C;&#x7C7B;&#x672C;&#x8EAB;&#x5B58;&#x5728;&#xFF0C;&#x9700;&#x8981;&#x5F80;&#x524D;&#x6392;&#x67E5;&#x7CFB;&#x7EDF;&#x7684;&#x8B66;&#x544A;&#x4FE1;&#x606F;&#xFF0C;&#x6BD4;&#x5982;&#x5728;Art&#x7684;&#x8BBE;&#x5907;&#x4E0A;&#x4F1A;&#x6709;class&#x88AB;reject&#x7684;warning&#x4FE1;&#x606F;&#xFF1A;\n  &gt;\n<img src=\"help_img/reject.png\" alt=\"MacDown Screenshot\"></p>\n<p> &#x5728;dalvik&#x7684;&#x7CFB;&#x7EDF;&#x4E0A;&#xFF0C;&#x5219;&#x4F1A;&#x5E26;&#x6709;VFY tag&#x7684;&#x8B66;&#x544A;&#x4FE1;&#x606F;&#xFF1A;</p>\n<pre><code> &gt;\n</code></pre><p><img src=\"help_img/vfy.png\" alt=\"MacDown Screenshot\"></p>\n<p>&#x4E00;&#x822C;&#x6765;&#x8BF4;&#xFF0C;&#x7531;&#x4E8E;ART&#x8BBE;&#x5907;&#x8B66;&#x544A;&#x7684;&#x4FE1;&#x606F;&#x62A5;&#x5728;dex2oat&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x6240;&#x4EE5;&#x5F80;&#x5F80;&#x4E0E;&#x53D1;&#x751F;crash&#x65F6;&#x7684;Exception&#x4FE1;&#x606F;&#x76F8;&#x9694;&#x6BD4;&#x8F83;&#x8FDC;&#xFF0C;&#x6240;&#x4EE5;&#x901A;&#x5E38;&#x9047;&#x5230;&#x8BE5;&#x7C7B;&#x95EE;&#x9898;&#xFF0C;dalivk&#x7684;&#x8BBE;&#x5907;&#x62FF;&#x6765;&#x6392;&#x67E5;&#x53EF;&#x80FD;&#x66F4;&#x80FD;&#x53D1;&#x73B0;&#x95EE;&#x9898;&#x7684;&#x539F;&#x56E0;&#x3002;&#x53E6;&#x5916;noclassdef&#x9020;&#x6210;&#x7684;&#x539F;&#x6709;&#x63A5;&#x53E3;&#x7C7B;&#x627E;&#x4E0D;&#x5230;&#xFF0C;&#x65B9;&#x6CD5;&#x4E22;&#x5931;&#xFF0C;&#x65B9;&#x6CD5;&#x53C2;&#x6570;&#x4E0D;&#x5339;&#x914D;&#xFF0C;&#x65B9;&#x6CD5;&#x5C5E;&#x6027;&#x53D8;&#x66F4;&#xFF0C;&#x6DF7;&#x6DC6;&#x7B49;&#xFF0C;&#x6240;&#x4EE5;&#x5177;&#x4F53;&#x539F;&#x56E0;&#x9700;&#x8981;&#x5229;&#x7528;&#x4E0A;&#x8FF0;warning&#x4FE1;&#x606F;&#x5E76;&#x5BF9;&#x7167;&#x53CD;&#x7F16;&#x8BD1;&#x7684;&#x4EE3;&#x7801;&#x53BB;&#x6392;&#x67E5;&#x6839;&#x672C;&#x7684;&#x539F;&#x56E0;   </p>\n</li>\n</ul>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"question.html\" class=\"navigation navigation-prev \" aria-label=\"Previous page: 问答\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"variant.html\" class=\"navigation navigation-next \" aria-label=\"Next page: 构建定制包\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"故障排查\",\"level\":\"1.5.2\",\"depth\":2,\"next\":{\"title\":\"构建定制包\",\"level\":\"1.5.3\",\"depth\":2,\"path\":\"faq/variant.md\",\"ref\":\"faq/variant.md\",\"articles\":[]},\"previous\":{\"title\":\"问答\",\"level\":\"1.5.1\",\"depth\":2,\"path\":\"faq/question.md\",\"ref\":\"faq/question.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"faq/help.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/faq/question.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>问答 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"help.html\" />\n    \n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../guide-for-use/\">\n            \n                <a href=\"../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../update/\">\n            \n                <a href=\"../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../update/principle.html\">\n            \n                <a href=\"../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../update/dexpatch.html\">\n            \n                <a href=\"../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../update/guide.html\">\n            \n                <a href=\"../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter active\" data-level=\"1.5.1\" data-path=\"question.html\">\n            \n                <a href=\"question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"help.html\">\n            \n                <a href=\"help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"variant.html\">\n            \n                <a href=\"variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"dynamic_failed_help.html\">\n            \n                <a href=\"dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >问答</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <p><strong>Q1: &#x5173;&#x4E8E;bundle&#x4E2D;&#x7684;application&#x7C7B;&#xFF0C;&#x5B83;&#x4EC0;&#x4E48;&#x65F6;&#x5019;&#x88AB;&#x8C03;&#x7528;&#xFF0C;&#x5176;&#x4E2D;&#x7684;&#x81EA;&#x5B9A;&#x4E49;&#x65B9;&#x6CD5;&#x600E;&#x4E48;&#x5728;bundle&#x4E2D;&#x8C03;&#x7528;&#xFF1F;&#x5728;bundle&#x4E2D;&#x8C03;&#x7528;getApplication&#x65B9;&#x6CD5;&#xFF0C;&#x5F97;&#x5230;&#x7684;&#x662F;&#x4E3B;&#x5E94;&#x7528;&#x7684;application&#x5BF9;&#x8C61;&#xFF0C;&#x4E0D;&#x662F;bundle&#x4E2D;&#x5B9A;&#x4E49;&#x7684;&#x3002;</strong></p>\n<p>A: &#x9996;&#x5148;&#x8981;&#x660E;&#x786E;&#x4E00;&#x70B9;&#xFF0C;bundle&#x4E2D;&#x7684;application&#x4E0D;&#x662F;&#x6700;&#x7EC8;&#x5728;android&#x7CFB;&#x7EDF;&#x4E0A;&#x6267;&#x884C;&#x7684;application&#x3002;&#x6211;&#x4EEC;&#x4E4B;&#x6240;&#x4EE5;&#x4FDD;&#x7559;bundle application&#x7684;&#x8BBE;&#x8BA1;&#x662F;&#x4E3A;&#x4E86;&#x5C3D;&#x6700;&#x5927;&#x53EF;&#x80FD;&#x4FDD;&#x7559;&#x5927;&#x5BB6;android&#x7684;&#x5F00;&#x53D1;&#x4E60;&#x60EF;&#x3002;</p>\n<p>bundle&#x4E2D;&#x7684;application&#x7C7B;&#xFF0C;&#x662F;&#x5728;bundle&#x7B2C;&#x4E00;&#x6B21;&#x5B89;&#x88C5;&#x7684;&#x65F6;&#x5019;&#xFF0C;atlas&#x4F1A;&#x8C03;&#x7528;application&#x7684;onCreate()&#x51FD;&#x6570;&#xFF0C;&#x53EF;&#x4EE5;&#x5728;&#x91CC;&#x9762;&#x5199;&#x4E00;&#x4E9B;&#x81EA;&#x5DF1;bundle&#x9700;&#x8981;&#x7528;&#x5230;&#x7684;&#x521D;&#x59CB;&#x5316;&#x4EE3;&#x7801;&#x3002;&#x6CE8;&#x610F;&#x4E0D;&#x8981;bundle application&#x91CC;&#x7528;this&#x8FD9;&#x79CD;&#x4EE3;&#x7801;&#xFF0C;&#x56E0;&#x4E3A;&#x662F;&#x4E0D;&#x751F;&#x6548;&#x7684;&#x3002;</p>\n<p>bundle&#x4E2D;&#x7684;application&#x7C7B;&#x7684;&#x81EA;&#x5B9A;&#x4E49;&#x65B9;&#x6CD5;&#xFF0C;&#x6211;&#x4EEC;&#x5EFA;&#x8BAE;&#x4E0D;&#x8981;&#x8FD9;&#x4E48;&#x4F7F;&#x7528;&#x3002;&#x53EF;&#x4EE5;&#x62BD;&#x79BB;&#x51FA;&#x516C;&#x5171;&#x7684;&#x65B9;&#x6CD5;&#xFF0C;&#x653E;&#x5728;&#x5176;&#x4ED6;&#x5730;&#x65B9;&#x4F9B;&#x8C03;&#x7528;&#x3002; &#x76EE;&#x524D;&#x662F;&#x6709;&#x8FD9;&#x4E2A;&#x9650;&#x5236;&#x3002;&#x5982;&#x679C;&#x975E;&#x5F97;&#x5728;&#x91CC;&#x9762;&#x8C03;&#x7528;&#xFF0C;&#x5EFA;&#x8BAE;&#x6539;&#x4E3A;static&#x65B9;&#x6CD5;&#x3002;</p>\n<p><strong>Q2: &#x96C6;&#x6210;&#x6846;&#x67B6;&#x540E;&#x5C31;&#x53EA;&#x6709;uses-permission&#xFF0C;&#x5C0F;&#x7C73;&#x63A8;&#x9001;&#x9700;&#x8981;permission&#x5C31;&#x63D0;&#x793A;&#x7F3A;&#x5C11;&#x6743;&#x9650;&#x58F0;&#x660E;&#x3002;</strong></p>\n<p>A: &#x8FD9;&#x662F;&#x56E0;&#x4E3A;&#x6253;&#x5305;&#x63D2;&#x4EF6;&#x9ED8;&#x8BA4;&#x5F00;&#x542F;&#x4E86;&#x53BB;&#x9664;&#x81EA;&#x5B9A;&#x4E49;&#x6743;&#x9650;&#x3002; &#x53EF;&#x901A;&#x8FC7;&#x5C5E;&#x6027;&#x5F00;&#x5173;&#x5173;&#x95ED;&#x3002; &#x5C5E;&#x6027;&#x5F00;&#x5173;&#x662F;atlas.manifestOptions.removeCustomPermission = false</p>\n<p><strong>Q3: proguard-rules.pro&#x76F4;&#x63A5;&#x5B9A;&#x4E49;&#x5728;&#x5BBF;&#x4E3B;app&#x91CC;&#x9762;&#x5C31;&#x53EF;&#x4EE5;&#x4E86;&#x5417;&#xFF0C;&#x4E0D;&#x9700;&#x8981;&#x6BCF;&#x4E2A;bundle&#x90FD;&#x4F7F;&#x7528;&#x5427;&#xFF1F;</strong></p>\n<p>A: &#x5728;&#x5BBF;&#x4E3B;app&#x91CC;&#x8FB9;&#x5B9A;&#x4E49;&#x5C31;&#x597D;&#x4E86;</p>\n<p><strong>Q4: &#x8BF7;&#x95EE; &#x5BA2;&#x6237;&#x7AEF;&#x62FF;&#x4EC0;&#x4E48;&#x5C5E;&#x6027; &#x8DDF;&#x670D;&#x52A1;&#x5668;&#x6BD4;&#x5BF9;&#x83B7;&#x53D6;&#x8865;&#x4E01;&#xFF1F;</strong></p>\n<p>A: &#x6BCF;&#x4E00;&#x6B21;&#x8865;&#x4E01;&#x7684;&#x53D1;&#x5E03;&#x90FD;&#x662F;&#x76F8;&#x5F53;&#x4E8E;&#x4E00;&#x6B21;&#x7248;&#x672C;&#x7684;&#x5347;&#x7EA7;&#xFF0C;&#x901A;&#x8FC7;&#x7248;&#x672C;&#x53F7;&#x7684;&#x53D8;&#x66F4;&#x6765;&#x51B3;&#x7B56;&#x8865;&#x4E01;&#x7684;&#x4E0B;&#x53D1;</p>\n<p><strong>Q5: bundle&#x4E2D;&#x7684;9patch&#x56FE;&#x663E;&#x793A;&#x6709;&#x95EE;&#x9898;&#xFF0C;&#x4E0D;&#x80FD;&#x62C9;&#x4F38;&#x4E86;&#x3002;&#x662F;&#x9700;&#x8981;&#x6709;&#x7279;&#x6B8A;&#x8BBE;&#x7F6E;&#x4E48;&#xFF1F;</strong></p>\n<p>A: alpha11&#x7248;&#x672C;&#x53D1;&#x5E03;&#x89E3;&#x51B3;&#x4E86;&#x3002;</p>\n<p><strong>Q6: &#x5BF9;&#x4E8E;gradle 2.3.1&#x7248;&#x672C;&#x662F;&#x4E0D;&#x662F;&#x652F;&#x6301;&#xFF1F;</strong></p>\n<p>A: &#x662F;&#x7684;&#xFF0C;&#x652F;&#x6301;2.3.x</p>\n<p><strong>Q7: &#x5BFC;&#x5165;demo&#x540E;&#xFF0C;Android Studio&#x7F16;&#x8BD1;&#x6309;&#x94AE;&#x7F16;&#x8BD1;&#x5931;&#x8D25;&#x3002;</strong></p>\n<p>A: &#x5173;&#x95ED;InstantRun&#x53EF;&#x4EE5;&#x6B63;&#x5E38;&#x5DE5;&#x4F5C;&#x3002;InstantRun&#x652F;&#x6301;&#x6B63;&#x5728;&#x5F00;&#x53D1;&#x4E2D;&#x3002;</p>\n<p><strong>Q8: Unable to delete file E:\\GitHub\\atlas\\atlas-demo\\AtlasDemo\\app\\build\\intermediates\\exploded-aar\\com.android.support\\animated-vector-drawable\\25.3.0\\jars\\classes.jar</strong></p>\n<p>A: 1. &#x6740;&#x6389;java.exe&#x8FDB;&#x7A0B;&#x91CD;&#x65B0;&#x7F16;&#x8BD1;&#xFF08;Windows &#x7CFB;&#x7EDF;&#x8FDB;&#x7A0B;&#x51FA;&#x73B0;&#xFF09;cmd:taskkill /F /IM java.exe 2. &#x5173;&#x95ED;&#x6389;as run on demand &#x5F00;&#x5173;</p>\n<p><strong>Q9. atlas &#x7684;&#x80FD;&#x529B;&#x95EE;&#x9898;&#xFF0C; &#x53CA;&#x4E0E; andfix &#x7684;&#x5173;&#x7CFB;</strong></p>\n<p>A: 1. atlas&#x652F;&#x6301;&#x6240;&#x6709;&#x7684;&#x4EE3;&#x7801;&#x53CA;&#x8D44;&#x6E90;&#x66F4;&#x65B0;&#xFF0C;&#x6682;&#x65F6;&#x4E0D;&#x652F;&#x6301;&#x65B0;&#x589E;4&#x5927;&#x7EC4;&#x4EF6;&#xFF0C;&#x4E0B;&#x4E2A;&#x5927;&#x7248;&#x672C;&#x652F;&#x6301; 2. andfix&#x53EA;&#x8981;&#x7528;&#x4E8E;&#x4FEE;&#x590D;java&#x4EE3;&#x7801;&#xFF0C;&#x4E0D;&#x91CD;&#x542F;&#x751F;&#x6548;&#x3002; atlas&#x80FD;&#x529B;&#x66F4;&#x5F3A;&#xFF0C;&#x4FEE;&#x590D;&#x53EA;&#x662F;&#x5176;&#x4E2D;&#x4E00;&#x90E8;&#x5206;&#x80FD;&#x529B;</p>\n<p><strong>Q10. AS &#x4E0A;&#x91CD;&#x65B0;&#x7F16;&#x8BD1;&#x5B89;&#x88C5;&#x4E0D;&#x751F;&#x6548;&#x7684;&#x95EE;&#x9898;</strong></p>\n<p>A: atlas &#x5728;&#x8986;&#x76D6;&#x5B89;&#x88C5;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x7531;&#x4E8E;bundle&#x7684;&#x7248;&#x672C;&#x53F7;&#x6CA1;&#x53D8;&#x5316;&#xFF0C;&#x6CA1;&#x505A;&#x6E05;&#x7406;&#xFF0C; &#x4E0B;&#x4E2A;&#x7248;&#x672C;&#x4F1A;&#x6E05;&#x7406;bundle</p>\n<p><strong>Q11. &#x52A8;&#x6001;&#x90E8;&#x7F72;&#x4E0D;&#x751F;&#x6548;&#x7684;&#x95EE;&#x9898;</strong></p>\n<p>A: &#x4E0D;&#x751F;&#x6548;&#x8981;&#x770B;&#x63D0;&#x793A;log&#x518D;&#x67E5;&#xFF0C;&#x76EE;&#x524D;&#x5DF2;&#x77E5;&#x7684;&#x5DF2;&#x7ECF;&#x4FEE;&#x590D;&#xFF0C;&#x4E4B;&#x524D;&#x662F;&#x7531;&#x4E8E;windows&#x53E5;&#x67C4;&#x6CA1;&#x5173;&#x95ED;&#xFF0C;&#x5BFC;&#x81F4;tpatch&#x4E2D;&#x5305;&#x542B;&#x4E00;&#x4E9B;&#x7A7A;&#x6587;&#x4EF6;&#xFF0C;&#x5728;dexmerge&#x7684;&#x65F6;&#x5019;&#x5931;&#x8D25;&#x4E86;</p>\n<p><strong>Q12. &#x6DF7;&#x6DC6;&#x540E;atlas&#x8FDB;&#x5EA6;&#x6761;&#x6D88;&#x5931;</strong></p>\n<p>A&#xFF1A; keep &#x89C4;&#x5219;&#x5C11;&#x4E86;</p>\n<p><strong>Q13. &#x81EA;&#x542F;&#x52A8;&#x7684;bundle&#x662F;&#x5728;&#x54EA;&#x4E2A;&#x7EBF;&#x7A0B;&#x4E2D;&#x554A;&#xFF0C;&#x4E0D;&#x662F;&#x4E3B;&#x7EBF;&#x7A0B;&#x5417;&#xFF1F;</strong></p>\n<p>A: &#x81EA;&#x542F;&#x52A8;bundle&#x53EF;&#x4EE5;&#x5728;&#x4EFB;&#x4F55;&#x7EBF;&#x7A0B;&#x4E2D;&#x6267;&#x884C;&#xFF0C;&#x4E0D;&#x8FC7;bundle&#x7684;application onCreate&#x65B9;&#x6CD5;&#x3001;Activity&#x7684;onCreate&#x65B9;&#x6CD5;&#x7B49;&#x90FD;&#x662F;&#x5728;&#x4E3B;&#x7EBF;&#x7A0B;&#x56DE;&#x8C03;&#x7684;</p>\n<p><strong>Q14. &#x5728;&#x5176;&#x4ED6;&#x8FDB;&#x7A0B;&#x91CC;&#x8FD0;&#x884C;&#x7684;&#x63D2;&#x4EF6;&#xFF0C;&#x9700;&#x8981;&#x5728;&#x4EC0;&#x4E48;&#x65F6;&#x5019;&#x5B89;&#x88C5;&#xFF1F;&#x53EF;&#x4E0D;&#x53EF;&#x624B;&#x52A8;&#x63A7;&#x5236;&#x5B89;&#x88C5;&#x7684;&#x65F6;&#x673A;&#xFF1F;</strong></p>\n<p>A: &#x5728;&#x9700;&#x8981;&#x7684;&#x65F6;&#x5019;&#x6309;&#x9700;&#x5B89;&#x88C5;&#xFF0C;&#x4F8B;&#x5982;&#x4E00;&#x4E2A;Service&#x662F;&#x5728;&#x5355;&#x72EC;&#x7684;&#x8FDB;&#x7A0B;&#x4E2D;&#xFF0C;&#x53EA;&#x8981;&#x9700;&#x8981;&#x7684;&#x65F6;&#x5019;&#x53BB;bind&#x5C31;&#x4F1A;&#x89E6;&#x53D1;&#x8FD9;&#x4E2A;bundle&#x7684;&#x5B89;&#x88C5;&#x3002;&#x53EF;&#x4EE5;&#x624B;&#x52A8;&#x63A7;&#x5236;&#x5B89;&#x88C5;&#x65F6;&#x673A;&#xFF0C;&#x6309;&#x9700;&#x5C31;&#x597D;&#x3002;</p>\n<p><strong>Q15. &#x7EC4;&#x4EF6;&#x4E2D;&#x6709;jar&#x5305;&#x548C;so&#x4F9D;&#x8D56;&#xFF0C;awb&#x7684;&#x4EA7;&#x7269;&#x4E2D;&#x4E5F;&#x6709;&#xFF0C;&#x4E3A;&#x4EC0;&#x4E48;&#x5728;&#x5BBF;&#x4E3B;&#x4E2D;&#x751F;&#x6210;&#x7684;so&#x4EA7;&#x7269;&#x89E3;&#x538B;&#x5C31;&#x6CA1;&#x6709;&#x4E86;&#x5462;&#xFF1F;</strong></p>\n<p>A: &#x5728;&#x6253;&#x6574;&#x5305;&#x7684;&#x65F6;&#x5019;&#x9700;&#x8981;&#x914D;&#x7F6E;&#x8FC7;&#x6EE4;&#x7684;&#x53C2;&#x6570;&#xFF0C;&#x628A;so&#x7684;&#x67B6;&#x6784;&#x7C7B;&#x578B;&#x6307;&#x5B9A;&#x6E05;&#x695A;&#xFF0C;&#x8981;&#x4E0D;&#x7136;&#x5C31;&#x4F1A;&#x88AB;&#x88C1;&#x51CF;&#x6389;&#x3002;&#x5177;&#x4F53;&#x53EF;&#x4EE5;&#x53C2;&#x8003; &#xFF1A; <a href=\"https://github.com/alibaba/atlas/issues/68\" target=\"_blank\">https://github.com/alibaba/atlas/issues/68</a></p>\n<p><strong>Q16. app&#x6709;&#x591A;&#x4E2A;&#x8FDB;&#x7A0B;&#xFF0C;&#x5728;&#x4E00;&#x4E2A;&#x8FDB;&#x7A0B;&#x4E2D;&#x51FA;&#x73B0;&#x4E86;host&#x4E2D;&#x7684;&#x4E00;&#x4E2A;&#x7C7B;&#x88AB;pathClassloader&#x52A0;&#x8F7D;&#x4E86;&#xFF0C;&#x4E4B;&#x540E;&#x5728;&#x8BE5;&#x7C7B;&#x4E2D;&#x8C03;&#x7528;Class.forName&#x52A0;&#x8F7D;&#x63D2;&#x4EF6;&#x91CC;&#x7684;&#x4E00;&#x4E2A;&#x7C7B;&#xFF0C;&#x56E0;&#x4E3A;classloader&#x662F;PathClassLoader,&#x6240;&#x4EE5;&#x62A5;&#x4E86;classnotfound,&#x7406;&#x8BBA;&#x4E0A;host&#x4E2D;&#x9664;&#x4E86;atlas&#x76F8;&#x5173;&#x7684;&#x7C7B;&#x5916;&#x6240;&#x6709;&#x7684;class&#x90FD;&#x5E94;&#x8BE5;&#x662F;&#x88AB;DelegateClassLoader&#x52A0;&#x8F7D;&#x5427;&#xFF1F;</strong></p>\n<p>A: &#x8FD9;&#x79CD;&#x95EE;&#x9898;&#x5C5E;&#x4E8E;&#x5BBF;&#x4E3B;&#x4E2D;&#x7684;class&#x5F15;&#x7528;&#x4E86;bundle&#x4E2D;&#x7684;class&#xFF0C;&#x7406;&#x8BBA;&#x4E0A;&#x662F;&#x53EF;&#x4EE5;&#x652F;&#x6301;&#x7684;&#xFF0C;&#x4F46;&#x662F;&#x5728;Atlas&#x7684;&#x6846;&#x67B6;&#x4E2D;&#x662F;&#x4E0D;&#x63A8;&#x8350;(&#x4E5F;&#x6CA1;&#x4E0D;&#x652F;&#x6301;)&#x8FD9;&#x79CD;&#x53CD;&#x5411;&#x7684;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#x3002;</p>\n<p><strong>Q17. altas&#x662F;&#x4E0D;&#x662F;&#x4E0D;&#x5EFA;&#x8BAE;bundle&#x4E4B;&#x95F4;&#x76F8;&#x4E92;&#x8C03;&#x7528;&#x8D44;&#x6E90;&#x6216;&#x8C03;&#x7528;&#x5BBF;&#x4E3B;&#x7684;&#x8D44;&#x6E90;?</strong></p>\n<p>A: Atlas&#x6846;&#x67B6;&#x5EFA;&#x8BAE;bundle&#x8C03;&#x7528;&#x5BBF;&#x4E3B;&#x7684;&#x8D44;&#x6E90;&#xFF0C;&#x800C;&#x4E0D;&#x5EFA;&#x8BAE;bundle&#x4E4B;&#x95F4;&#x8D44;&#x6E90;&#x7684;&#x76F8;&#x4E92;&#x8C03;&#x7528;&#x3002;</p>\n<p><strong>Q18. &#x5BBF;&#x4E3B;&#x548C;bundle&#x7684;&#x5173;&#x7CFB;&#xFF1F;</strong></p>\n<p>A: &#x5BBF;&#x4E3B;&#x5C31;&#x76F8;&#x5F53;&#x4E8E;Android Framework&#xFF0C;&#x6B63;&#x5E38;&#x7684;Android&#x4EE3;&#x7801;&#x4E2D;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x8C03;&#x7528;Framework&#x4E2D;&#x7684;&#x63A5;&#x53E3;&#x4EE5;&#x53CA;&#x4F7F;&#x7528;&#x5176;&#x5305;&#x542B;&#x7684;&#x8D44;&#x6E90;&#xFF0C;&#x5BBF;&#x4E3B;&#x5BF9;&#x4E8E;bundle&#x800C;&#x8A00;&#x4E5F;&#x662F;&#x8FD9;&#x4E2A;&#x6837;&#x5B50;&#x7684;&#xFF0C;&#x5047;&#x5982;&#x591A;&#x4E2A;bundle&#x4F7F;&#x7528;&#x540C;&#x4E00;&#x4E2A;&#x8D44;&#x6E90;&#xFF0C;&#x90A3;&#x4E48;&#x8FD9;&#x4E2A;&#x8D44;&#x6E90;&#x53EF;&#x4EE5;&#x653E;&#x5728;&#x5BBF;&#x4E3B;&#x91CC;&#x8FB9;&#xFF0C;&#x591A;&#x4E2A;bundle&#x540C;&#x65F6;&#x4F9D;&#x8D56;&#x8FD9;&#x4E2A;&#x5BBF;&#x4E3B;&#xFF0C;&#x8FD9;&#x6837;&#x907F;&#x514D;&#x4E86;&#x8D44;&#x6E90;&#x7684;&#x91CD;&#x590D;&#x3002;(&#x751A;&#x81F3;&#x53EF;&#x4EE5;&#x628A;&#x5BBF;&#x4E3B;&#x770B;&#x6210;&#x4E00;&#x4E2A;AAR&#xFF0C;&#x8FD9;&#x4E2A;AAR&#x7684;&#x5185;&#x5BB9;&#x662F;&#x6253;&#x5305;&#x5728;&#x4E3B;dex&#x4E2D;&#x7684;)</p>\n<p><strong>Q19. Atlas&#x9879;&#x76EE;&#x4E2D;&#xFF1A;AtlasDemo&#x548C;&#x57FA;&#x4E8E;&#x7248;&#x672C;&#x6253;&#x5305;&#x7684;demo&#x8FD9;&#x4E24;&#x4E2A;&#x9879;&#x76EE;&#x6709;&#x4EC0;&#x4E48;&#x533A;&#x522B;&#xFF1F;</strong></p>\n<p>A: &#x4E00;&#x4E2A;&#x662F;&#x57FA;&#x4E8E;&#x6E90;&#x7801;&#x9879;&#x76EE;&#xFF0C;&#x4E00;&#x4E2A;&#x662F;&#x57FA;&#x4E8E;&#x4ED3;&#x5E93;&#x7248;&#x672C;&#x4F9D;&#x8D56;&#x7684;&#x3002;&#x524D;&#x671F;&#x7814;&#x7A76;&#x53EF;&#x4EE5;&#x57FA;&#x4E8E;&#x6E90;&#x7801;&#x6765;&#xFF0C;&#x540E;&#x7EED;&#x5DE5;&#x7A0B;&#x5316;&#x5B9E;&#x8DF5;&#x63A8;&#x8350;&#x4F7F;&#x7528;&#x540E;&#x8005;&#xFF0C;&#x624B;&#x6DD8;&#x5185;&#x90E8;&#x5C31;&#x662F;&#x4F7F;&#x7528;&#x540E;&#x8005;&#x7684;&#x3002;</p>\n<p><strong>Q20.  awb&#x662F;&#x4EC0;&#x4E48;&#xFF1F;</strong></p>\n<p>A: awb&#x662F;&#x6211;&#x4EEC;&#x53D1;&#x660E;&#x7684;&#x683C;&#x5F0F;&#xFF0C;&#x5176;&#x5185;&#x90E8;&#x7ED3;&#x6784;&#x548C;aar&#x4E00;&#x6837;&#x3002; awb&#x5BF9;&#x5E94;&#x4E8E;bundle&#xFF0C;&#x7F16;&#x8BD1;&#x6700;&#x540E;&#x7684;&#x4EA7;&#x7269;&#x662F;&#x751F;&#x6210;&#x5230;&#x6700;&#x540E;&#x6574;&#x5305;&#x7684;so&#x4E2D;&#x3002;&#x5177;&#x4F53;&#x8BF7;&#x53C2;&#x7167; <a href=\"http://atlas.taobao.org/docs/principle-intro/Project_architectured.html\" target=\"_blank\">http://atlas.taobao.org/docs/principle-intro/Project_architectured.html</a></p>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                \n                <a href=\"help.html\" class=\"navigation navigation-next navigation-unique\" aria-label=\"Next page: 故障排查\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"问答\",\"level\":\"1.5.1\",\"depth\":2,\"next\":{\"title\":\"故障排查\",\"level\":\"1.5.2\",\"depth\":2,\"path\":\"faq/help.md\",\"ref\":\"faq/help.md\",\"articles\":[]},\"previous\":{\"title\":\"FAQ\",\"level\":\"1.5\",\"depth\":1,\"ref\":\"\",\"articles\":[{\"title\":\"问答\",\"level\":\"1.5.1\",\"depth\":2,\"path\":\"faq/question.md\",\"ref\":\"faq/question.md\",\"articles\":[]},{\"title\":\"故障排查\",\"level\":\"1.5.2\",\"depth\":2,\"path\":\"faq/help.md\",\"ref\":\"faq/help.md\",\"articles\":[]},{\"title\":\"构建定制包\",\"level\":\"1.5.3\",\"depth\":2,\"path\":\"faq/variant.md\",\"ref\":\"faq/variant.md\",\"articles\":[]},{\"title\":\"动态部署失败排查指南\",\"level\":\"1.5.4\",\"depth\":2,\"path\":\"faq/dynamic_failed_help.md\",\"ref\":\"faq/dynamic_failed_help.md\",\"articles\":[]}]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"faq/question.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/faq/variant.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>构建定制包 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"dynamic_failed_help.html\" />\n    \n    \n    <link rel=\"prev\" href=\"help.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../guide-for-use/\">\n            \n                <a href=\"../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../update/\">\n            \n                <a href=\"../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../update/principle.html\">\n            \n                <a href=\"../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../update/dexpatch.html\">\n            \n                <a href=\"../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../update/guide.html\">\n            \n                <a href=\"../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"question.html\">\n            \n                <a href=\"question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"help.html\">\n            \n                <a href=\"help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.5.3\" data-path=\"variant.html\">\n            \n                <a href=\"variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"dynamic_failed_help.html\">\n            \n                <a href=\"dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >构建定制包</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h2 id=\"&#x5982;&#x4F55;&#x6784;&#x5EFA;&#x4E0D;&#x540C;&#x7684;&#x5305;\">&#x5982;&#x4F55;&#x6784;&#x5EFA;&#x4E0D;&#x540C;&#x7684;&#x5305;</h2>\n<p>google&#x63D2;&#x4EF6;&#x5BF9;&#x5E94;&#x7684;&#x6587;&#x6863;&#x5730;&#x5740;&#xFF1A; <a href=\"https://developer.android.com/studio/build/build-variants.html?hl=zh-cn\" target=\"_blank\">https://developer.android.com/studio/build/build-variants.html?hl=zh-cn</a> &#xFF0C; &#x539F;&#x751F;&#x662F;&#x652F;&#x6301;&#x914D;&#x7F6E;&#x4E0D;&#x540C;&#x7684;buildType &#x4EE5;&#x53CA; flavor &#x7684;&#xFF0C; &#x5148;&#x770B;&#x4E00;&#x4E0B;&#x529F;&#x80FD;&#x5BF9;&#x6BD4;&#xFF1A;</p>\n<h3 id=\"&#x5F53;&#x524D;&#x7684;&#x652F;&#x6301;&#x5EA6;\">&#x5F53;&#x524D;&#x7684;&#x652F;&#x6301;&#x5EA6;</h3>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">&#x63D2;&#x4EF6;</th>\n<th style=\"text-align:center\">falvor</th>\n<th style=\"text-align:right\">&#x81EA;&#x5B9A;&#x4E49;buildType</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">google&#x63D2;&#x4EF6;</td>\n<td style=\"text-align:center\">&#x652F;&#x6301;</td>\n<td style=\"text-align:right\">&#x652F;&#x6301;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">atlasplugin &#x6784;&#x5EFA;apk</td>\n<td style=\"text-align:center\">&#x652F;&#x6301;</td>\n<td style=\"text-align:right\">&#x4E0D;&#x652F;&#x6301;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">atlasplugin &#x6784;&#x5EFA;&#x52A8;&#x6001;&#x90E8;&#x7F72;</td>\n<td style=\"text-align:center\">&#x4E0D;&#x652F;&#x6301;</td>\n<td style=\"text-align:right\">&#x4E0D;&#x652F;&#x6301;</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"&#x4E3A;&#x4EC0;&#x4E48;&#x6CA1;&#x6709;&#x53BB;&#x5B8C;&#x5168;&#x9002;&#x914D;\">&#x4E3A;&#x4EC0;&#x4E48;&#x6CA1;&#x6709;&#x53BB;&#x5B8C;&#x5168;&#x9002;&#x914D;</h3>\n<ol>\n<li>Atlas&#x662F;&#x9762;&#x5411;&#x591A;&#x4EBA;&#x534F;&#x4F5C;&#x7684;&#x8F83;&#x5927;&#x5DE5;&#x7A0B;&#x7684;&#xFF0C;&#x914D;&#x7F6E;&#x4E0D;&#x540C;&#x7684;buildtype&#x548C;flavor&#x4E2D;&#x4E5F;&#x4F1A;&#x5E26;&#x6765;&#x521B;&#x5EFA;&#x66F4;&#x591A;&#x7684;&#x4EFB;&#x52A1;&#xFF0C;&#x5E76;&#x4E14;&#x5982;&#x679C;&#x6267;&#x884C;assembleDebug &#x4E4B;&#x7C7B;&#x4F1A;&#x6784;&#x5EFA;&#x6240;&#x6709;&#x7684;&#x4F9D;&#x8D56;&#x53D8;&#x79CD;&#xFF0C;&#x5BFC;&#x81F4;&#x6574;&#x4F53;&#x6784;&#x5EFA;&#x6548;&#x7387;&#x5927;&#x5927;&#x964D;&#x4F4E;&#x3002;</li>\n<li>&#x5F00;&#x53D1;&#x7CBE;&#x529B;&#x6240;&#x9650;&#xFF0C;&#x56E0;&#x4E3A;&#x6211;&#x4EEC;&#x7684;&#x6DD8;&#x5B9D;app&#x5C31;&#x662F;&#x6CA1;&#x6709;&#x53D8;&#x79CD;&#x7684;&#x67B6;&#x6784;&#xFF0C;&#x989D;&#x5916;&#x7684;&#x529F;&#x80FD;&#x4F1A;&#x5E26;&#x6765;&#x5F88;&#x591A;&#x9002;&#x914D;&#x7684;&#x9EBB;&#x70E6;&#x548C;&#x98CE;&#x9669;</li>\n<li>&#x5F00;&#x53D1;&#x671F;&#x6211;&#x4EEC;&#x671F;&#x671B;&#x6211;&#x4EEC;&#x7684;&#x57FA;&#x7EBF;&#x8DB3;&#x591F;&#x7A33;&#x5B9A;&#xFF0C;&#x8FD9;&#x6837;&#x53EF;&#x4EE5;&#x907F;&#x514D;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x57FA;&#x7EBF;&#x4E0D;&#x517C;&#x5BB9;&#x7684;&#x95EE;&#x9898;</li>\n</ol>\n<h3 id=\"&#x5F53;&#x524D;&#x63D2;&#x4EF6;&#x4E0B;&#x7684;&#x5B9E;&#x8DF5;\">&#x5F53;&#x524D;&#x63D2;&#x4EF6;&#x4E0B;&#x7684;&#x5B9E;&#x8DF5;</h3>\n<p>&#x56E0;&#x4E3A;build.gradle &#x91CC;&#x53EF;&#x4EE5;&#x5199;&#x5F88;&#x591A;&#x7684;&#x903B;&#x8F91;&#xFF0C;&#x6240;&#x4EE5;&#x914D;&#x7F6E;&#x4E5F;&#x53EF;&#x4EE5;&#x53D8;&#x7684;&#x5F88;&#x7075;&#x6D3B;&#x3002; &#x6211;&#x4EEC;&#x4E00;&#x822C;&#x7684;&#x505A;&#x6CD5;&#x5C31;&#x662F;&#x901A;&#x8FC7;&#x6253;&#x5305;&#x53C2;&#x6570;&#x6765;&#x63A7;&#x5236;&#x4E0D;&#x540C;&#x7684;&#x53C2;&#x6570;&#x503C;&#xFF0C; &#x5177;&#x4F53;&#x7684;demo&#x53EF;&#x4EE5;&#x770B;&#x4E0B;&#x4E0B;&#x9762;&#x7684;&#x4ECB;&#x7ECD;&#xFF0C;&#x81F3;&#x4E8E;&#x5177;&#x4F53;&#x7684;&#x5176;&#x4ED6;&#x5B9E;&#x73B0;&#xFF0C;&#x5927;&#x5BB6;&#x4E5F;&#x53EF;&#x4EE5;&#x81EA;&#x884C;&#x6269;&#x5C55;</p>\n<h4 id=\"&#x5927;&#x81F4;&#x6B65;&#x9AA4;\">&#x5927;&#x81F4;&#x6B65;&#x9AA4;</h4>\n<ol>\n<li><p>&#x5728;build.gradle&#x91CC;&#x5B9A;&#x4E49;&#x4E00;&#x4E9B;&#x57FA;&#x7840;&#x7684;&#x53D8;&#x91CF;&#xFF0C;&#x6BD4;&#x5982;&#xFF1A;</p>\n<pre><code> //&#x901A;&#x8FC7;&#x589E;&#x52A0;&#x5224;&#x65AD;&#x903B;&#x8F91;&#xFF0C;&#x6253;&#x51FA;&#x4E0D;&#x540C;&#x7C7B;&#x578B;&#x7684;&#x5B9A;&#x5236;&#x5305;\n def appId = &quot;com.taobao.demo&quot;\n def minVersion = 14\n</code></pre></li>\n</ol>\n<ol>\n<li>&#x589E;&#x52A0;&#x4E00;&#x5C42;&#x903B;&#x8F91;&#x63A7;&#x5236;&#x6839;&#x636E;&#x4E0D;&#x540C;&#x7684;&#x53C2;&#x6570;&#x6765;&#x4FEE;&#x6539;&#x4E4B;&#x524D;&#x5B9A;&#x4E49;&#x53D8;&#x91CF;&#x7684;&#x503C; &#xFF0C; &#x8FD9;&#x6837;&#x5982;&#x679C;&#x6211;&#x4EEC;&#x6253;&#x5305;&#x52A0;&#x4E86; -Pbeta, &#x5C31;&#x4F1A;&#x4F7F;&#x7528;&#x65B0;&#x7684;&#x503C;&#x4E86;</li>\n</ol>\n<pre><code>    if (project.hasProperty(&quot;beta&quot;)) {\n        appId = &quot;com.taobao.atlas.beta&quot;\n        minVersion = 21\n    }\n</code></pre><ol>\n<li>&#x6216;&#x8005;&#x76F4;&#x63A5;&#x5728;&#x914D;&#x7F6E;&#x7684;&#x5730;&#x65B9;&#x52A0;&#x4E0A;&#x5224;&#x65AD;&#x903B;&#x8F91;&#xFF0C;&#x4F7F;&#x7528;&#x7279;&#x6B8A;&#x7684;&#x914D;&#x7F6E;</li>\n</ol>\n<pre><code>    android {\n        defaultConfig {\n            //&#x901A;&#x8FC7;&#x589E;&#x52A0;&#x5224;&#x65AD;&#x903B;&#x8F91;&#xFF0C;&#x6253;&#x51FA;&#x4E0D;&#x540C;&#x7C7B;&#x578B;&#x7684;&#x5B9A;&#x5236;&#x5305;\n            if (project.hasProperty(&quot;beta&quot;)) {\n                buildConfigField &quot;boolean&quot;, &quot;API_ENV&quot;, &quot;false&quot;\n            }else{\n                buildConfigField &quot;boolean&quot;, &quot;API_ENV&quot;, &quot;false&quot;\n            }\n        }\n</code></pre><ol>\n<li><p>&#x4EE5;&#x4E0A;build.gradle &#x91CC;&#x7684;&#x914D;&#x7F6E;&#x57FA;&#x672C;&#x5B8C;&#x6210;&#x3002; &#x540E;&#x7EED;&#x5982;&#x679C;&#x8981;&#x6253;&#x7279;&#x6B8A;&#x5305;&#x5C31;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4FEE;&#x6539;&#x914D;&#x7F6E;&#x7684;&#x6784;&#x5EFA;&#x53C2;&#x6570;&#x6765;&#x63A7;&#x5236;&#x6253;&#x5177;&#x4F53;&#x7684;&#x5305;&#x4E86;&#xFF0C;&#x5982;&#xFF1A;</p>\n<pre><code>    ./gradlew clean assembleDebug :  &#x6784;&#x5EFA;&#x6807;&#x51C6;&#x5305;\n    ./gradlew clean assembleDebug -Pbeta &#xFF1A; &#x6784;&#x5EFA;&#x7279;&#x6B8A;&#x5305;\n</code></pre></li>\n</ol>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"help.html\" class=\"navigation navigation-prev \" aria-label=\"Previous page: 故障排查\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"dynamic_failed_help.html\" class=\"navigation navigation-next \" aria-label=\"Next page: 动态部署失败排查指南\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"构建定制包\",\"level\":\"1.5.3\",\"depth\":2,\"next\":{\"title\":\"动态部署失败排查指南\",\"level\":\"1.5.4\",\"depth\":2,\"path\":\"faq/dynamic_failed_help.md\",\"ref\":\"faq/dynamic_failed_help.md\",\"articles\":[]},\"previous\":{\"title\":\"故障排查\",\"level\":\"1.5.2\",\"depth\":2,\"path\":\"faq/help.md\",\"ref\":\"faq/help.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"faq/variant.md\",\"mtime\":\"2017-11-27T09:41:28.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/gitbook/gitbook-plugin-fontsettings/fontsettings.js",
    "content": "require(['gitbook', 'jquery'], function(gitbook, $) {\n    // Configuration\n    var MAX_SIZE       = 4,\n        MIN_SIZE       = 0,\n        BUTTON_ID;\n\n    // Current fontsettings state\n    var fontState;\n\n    // Default themes\n    var THEMES = [\n        {\n            config: 'white',\n            text: 'White',\n            id: 0\n        },\n        {\n            config: 'sepia',\n            text: 'Sepia',\n            id: 1\n        },\n        {\n            config: 'night',\n            text: 'Night',\n            id: 2\n        }\n    ];\n\n    // Default font families\n    var FAMILIES = [\n        {\n            config: 'serif',\n            text: 'Serif',\n            id: 0\n        },\n        {\n            config: 'sans',\n            text: 'Sans',\n            id: 1\n        }\n    ];\n\n    // Return configured themes\n    function getThemes() {\n        return THEMES;\n    }\n\n    // Modify configured themes\n    function setThemes(themes) {\n        THEMES = themes;\n        updateButtons();\n    }\n\n    // Return configured font families\n    function getFamilies() {\n        return FAMILIES;\n    }\n\n    // Modify configured font families\n    function setFamilies(families) {\n        FAMILIES = families;\n        updateButtons();\n    }\n\n    // Save current font settings\n    function saveFontSettings() {\n        gitbook.storage.set('fontState', fontState);\n        update();\n    }\n\n    // Increase font size\n    function enlargeFontSize(e) {\n        e.preventDefault();\n        if (fontState.size >= MAX_SIZE) return;\n\n        fontState.size++;\n        saveFontSettings();\n    }\n\n    // Decrease font size\n    function reduceFontSize(e) {\n        e.preventDefault();\n        if (fontState.size <= MIN_SIZE) return;\n\n        fontState.size--;\n        saveFontSettings();\n    }\n\n    // Change font family\n    function changeFontFamily(configName, e) {\n        if (e && e instanceof Event) {\n            e.preventDefault();\n        }\n\n        var familyId = getFontFamilyId(configName);\n        fontState.family = familyId;\n        saveFontSettings();\n    }\n\n    // Change type of color theme\n    function changeColorTheme(configName, e) {\n        if (e && e instanceof Event) {\n            e.preventDefault();\n        }\n\n        var $book = gitbook.state.$book;\n\n        // Remove currently applied color theme\n        if (fontState.theme !== 0)\n            $book.removeClass('color-theme-'+fontState.theme);\n\n        // Set new color theme\n        var themeId = getThemeId(configName);\n        fontState.theme = themeId;\n        if (fontState.theme !== 0)\n            $book.addClass('color-theme-'+fontState.theme);\n\n        saveFontSettings();\n    }\n\n    // Return the correct id for a font-family config key\n    // Default to first font-family\n    function getFontFamilyId(configName) {\n        // Search for plugin configured font family\n        var configFamily = $.grep(FAMILIES, function(family) {\n            return family.config == configName;\n        })[0];\n        // Fallback to default font family\n        return (!!configFamily)? configFamily.id : 0;\n    }\n\n    // Return the correct id for a theme config key\n    // Default to first theme\n    function getThemeId(configName) {\n        // Search for plugin configured theme\n        var configTheme = $.grep(THEMES, function(theme) {\n            return theme.config == configName;\n        })[0];\n        // Fallback to default theme\n        return (!!configTheme)? configTheme.id : 0;\n    }\n\n    function update() {\n        var $book = gitbook.state.$book;\n\n        $('.font-settings .font-family-list li').removeClass('active');\n        $('.font-settings .font-family-list li:nth-child('+(fontState.family+1)+')').addClass('active');\n\n        $book[0].className = $book[0].className.replace(/\\bfont-\\S+/g, '');\n        $book.addClass('font-size-'+fontState.size);\n        $book.addClass('font-family-'+fontState.family);\n\n        if(fontState.theme !== 0) {\n            $book[0].className = $book[0].className.replace(/\\bcolor-theme-\\S+/g, '');\n            $book.addClass('color-theme-'+fontState.theme);\n        }\n    }\n\n    function init(config) {\n        // Search for plugin configured font family\n        var configFamily = getFontFamilyId(config.family),\n            configTheme = getThemeId(config.theme);\n\n        // Instantiate font state object\n        fontState = gitbook.storage.get('fontState', {\n            size:   config.size || 2,\n            family: configFamily,\n            theme:  configTheme\n        });\n\n        update();\n    }\n\n    function updateButtons() {\n        // Remove existing fontsettings buttons\n        if (!!BUTTON_ID) {\n            gitbook.toolbar.removeButton(BUTTON_ID);\n        }\n\n        // Create buttons in toolbar\n        BUTTON_ID = gitbook.toolbar.createButton({\n            icon: 'fa fa-font',\n            label: 'Font Settings',\n            className: 'font-settings',\n            dropdown: [\n                [\n                    {\n                        text: 'A',\n                        className: 'font-reduce',\n                        onClick: reduceFontSize\n                    },\n                    {\n                        text: 'A',\n                        className: 'font-enlarge',\n                        onClick: enlargeFontSize\n                    }\n                ],\n                $.map(FAMILIES, function(family) {\n                    family.onClick = function(e) {\n                        return changeFontFamily(family.config, e);\n                    };\n\n                    return family;\n                }),\n                $.map(THEMES, function(theme) {\n                    theme.onClick = function(e) {\n                        return changeColorTheme(theme.config, e);\n                    };\n\n                    return theme;\n                })\n            ]\n        });\n    }\n\n    // Init configuration at start\n    gitbook.events.bind('start', function(e, config) {\n        var opts = config.fontsettings;\n\n        // Generate buttons at start\n        updateButtons();\n\n        // Init current settings\n        init(opts);\n    });\n\n    // Expose API\n    gitbook.fontsettings = {\n        enlargeFontSize: enlargeFontSize,\n        reduceFontSize:  reduceFontSize,\n        setTheme:        changeColorTheme,\n        setFamily:       changeFontFamily,\n        getThemes:       getThemes,\n        setThemes:       setThemes,\n        getFamilies:     getFamilies,\n        setFamilies:     setFamilies\n    };\n});\n\n\n"
  },
  {
    "path": "atlas-docs/_book/gitbook/gitbook-plugin-fontsettings/website.css",
    "content": "/*\n * Theme 1\n */\n.color-theme-1 .dropdown-menu {\n  background-color: #111111;\n  border-color: #7e888b;\n}\n.color-theme-1 .dropdown-menu .dropdown-caret .caret-inner {\n  border-bottom: 9px solid #111111;\n}\n.color-theme-1 .dropdown-menu .buttons {\n  border-color: #7e888b;\n}\n.color-theme-1 .dropdown-menu .button {\n  color: #afa790;\n}\n.color-theme-1 .dropdown-menu .button:hover {\n  color: #73553c;\n}\n/*\n * Theme 2\n */\n.color-theme-2 .dropdown-menu {\n  background-color: #2d3143;\n  border-color: #272a3a;\n}\n.color-theme-2 .dropdown-menu .dropdown-caret .caret-inner {\n  border-bottom: 9px solid #2d3143;\n}\n.color-theme-2 .dropdown-menu .buttons {\n  border-color: #272a3a;\n}\n.color-theme-2 .dropdown-menu .button {\n  color: #62677f;\n}\n.color-theme-2 .dropdown-menu .button:hover {\n  color: #f4f4f5;\n}\n.book .book-header .font-settings .font-enlarge {\n  line-height: 30px;\n  font-size: 1.4em;\n}\n.book .book-header .font-settings .font-reduce {\n  line-height: 30px;\n  font-size: 1em;\n}\n.book.color-theme-1 .book-body {\n  color: #704214;\n  background: #f3eacb;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section {\n  background: #f3eacb;\n}\n.book.color-theme-2 .book-body {\n  color: #bdcadb;\n  background: #1c1f2b;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section {\n  background: #1c1f2b;\n}\n.book.font-size-0 .book-body .page-inner section {\n  font-size: 1.2rem;\n}\n.book.font-size-1 .book-body .page-inner section {\n  font-size: 1.4rem;\n}\n.book.font-size-2 .book-body .page-inner section {\n  font-size: 1.6rem;\n}\n.book.font-size-3 .book-body .page-inner section {\n  font-size: 2.2rem;\n}\n.book.font-size-4 .book-body .page-inner section {\n  font-size: 4rem;\n}\n.book.font-family-0 {\n  font-family: Georgia, serif;\n}\n.book.font-family-1 {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal {\n  color: #704214;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal a {\n  color: inherit;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h1,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h2,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h3,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h4,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h5,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h6 {\n  color: inherit;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h1,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h2 {\n  border-color: inherit;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h6 {\n  color: inherit;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal hr {\n  background-color: inherit;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal blockquote {\n  border-color: inherit;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code {\n  background: #fdf6e3;\n  color: #657b83;\n  border-color: #f8df9c;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal .highlight {\n  background-color: inherit;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table th,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table td {\n  border-color: #f5d06c;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table tr {\n  color: inherit;\n  background-color: #fdf6e3;\n  border-color: #444444;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n) {\n  background-color: #fbeecb;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal {\n  color: #bdcadb;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal a {\n  color: #3eb1d0;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h1,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h2,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h3,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h4,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h5,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h6 {\n  color: #fffffa;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h1,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h2 {\n  border-color: #373b4e;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h6 {\n  color: #373b4e;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal hr {\n  background-color: #373b4e;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal blockquote {\n  border-color: #373b4e;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code {\n  color: #9dbed8;\n  background: #2d3143;\n  border-color: #2d3143;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal .highlight {\n  background-color: #282a39;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table th,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table td {\n  border-color: #3b3f54;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table tr {\n  color: #b6c2d2;\n  background-color: #2d3143;\n  border-color: #3b3f54;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n) {\n  background-color: #35394b;\n}\n.book.color-theme-1 .book-header {\n  color: #afa790;\n  background: transparent;\n}\n.book.color-theme-1 .book-header .btn {\n  color: #afa790;\n}\n.book.color-theme-1 .book-header .btn:hover {\n  color: #73553c;\n  background: none;\n}\n.book.color-theme-1 .book-header h1 {\n  color: #704214;\n}\n.book.color-theme-2 .book-header {\n  color: #7e888b;\n  background: transparent;\n}\n.book.color-theme-2 .book-header .btn {\n  color: #3b3f54;\n}\n.book.color-theme-2 .book-header .btn:hover {\n  color: #fffff5;\n  background: none;\n}\n.book.color-theme-2 .book-header h1 {\n  color: #bdcadb;\n}\n.book.color-theme-1 .book-body .navigation {\n  color: #afa790;\n}\n.book.color-theme-1 .book-body .navigation:hover {\n  color: #73553c;\n}\n.book.color-theme-2 .book-body .navigation {\n  color: #383f52;\n}\n.book.color-theme-2 .book-body .navigation:hover {\n  color: #fffff5;\n}\n/*\n * Theme 1\n */\n.book.color-theme-1 .book-summary {\n  color: #afa790;\n  background: #111111;\n  border-right: 1px solid rgba(0, 0, 0, 0.07);\n}\n.book.color-theme-1 .book-summary .book-search {\n  background: transparent;\n}\n.book.color-theme-1 .book-summary .book-search input,\n.book.color-theme-1 .book-summary .book-search input:focus {\n  border: 1px solid transparent;\n}\n.book.color-theme-1 .book-summary ul.summary li.divider {\n  background: #7e888b;\n  box-shadow: none;\n}\n.book.color-theme-1 .book-summary ul.summary li i.fa-check {\n  color: #33cc33;\n}\n.book.color-theme-1 .book-summary ul.summary li.done > a {\n  color: #877f6a;\n}\n.book.color-theme-1 .book-summary ul.summary li a,\n.book.color-theme-1 .book-summary ul.summary li span {\n  color: #877f6a;\n  background: transparent;\n  font-weight: normal;\n}\n.book.color-theme-1 .book-summary ul.summary li.active > a,\n.book.color-theme-1 .book-summary ul.summary li a:hover {\n  color: #704214;\n  background: transparent;\n  font-weight: normal;\n}\n/*\n * Theme 2\n */\n.book.color-theme-2 .book-summary {\n  color: #bcc1d2;\n  background: #2d3143;\n  border-right: none;\n}\n.book.color-theme-2 .book-summary .book-search {\n  background: transparent;\n}\n.book.color-theme-2 .book-summary .book-search input,\n.book.color-theme-2 .book-summary .book-search input:focus {\n  border: 1px solid transparent;\n}\n.book.color-theme-2 .book-summary ul.summary li.divider {\n  background: #272a3a;\n  box-shadow: none;\n}\n.book.color-theme-2 .book-summary ul.summary li i.fa-check {\n  color: #33cc33;\n}\n.book.color-theme-2 .book-summary ul.summary li.done > a {\n  color: #62687f;\n}\n.book.color-theme-2 .book-summary ul.summary li a,\n.book.color-theme-2 .book-summary ul.summary li span {\n  color: #c1c6d7;\n  background: transparent;\n  font-weight: 600;\n}\n.book.color-theme-2 .book-summary ul.summary li.active > a,\n.book.color-theme-2 .book-summary ul.summary li a:hover {\n  color: #f4f4f5;\n  background: #252737;\n  font-weight: 600;\n}\n"
  },
  {
    "path": "atlas-docs/_book/gitbook/gitbook-plugin-highlight/ebook.css",
    "content": "pre,\ncode {\n  /* http://jmblog.github.io/color-themes-for-highlightjs */\n  /* Tomorrow Comment */\n  /* Tomorrow Red */\n  /* Tomorrow Orange */\n  /* Tomorrow Yellow */\n  /* Tomorrow Green */\n  /* Tomorrow Aqua */\n  /* Tomorrow Blue */\n  /* Tomorrow Purple */\n}\npre .hljs-comment,\ncode .hljs-comment,\npre .hljs-title,\ncode .hljs-title {\n  color: #8e908c;\n}\npre .hljs-variable,\ncode .hljs-variable,\npre .hljs-attribute,\ncode .hljs-attribute,\npre .hljs-tag,\ncode .hljs-tag,\npre .hljs-regexp,\ncode .hljs-regexp,\npre .hljs-deletion,\ncode .hljs-deletion,\npre .ruby .hljs-constant,\ncode .ruby .hljs-constant,\npre .xml .hljs-tag .hljs-title,\ncode .xml .hljs-tag .hljs-title,\npre .xml .hljs-pi,\ncode .xml .hljs-pi,\npre .xml .hljs-doctype,\ncode .xml .hljs-doctype,\npre .html .hljs-doctype,\ncode .html .hljs-doctype,\npre .css .hljs-id,\ncode .css .hljs-id,\npre .css .hljs-class,\ncode .css .hljs-class,\npre .css .hljs-pseudo,\ncode .css .hljs-pseudo {\n  color: #c82829;\n}\npre .hljs-number,\ncode .hljs-number,\npre .hljs-preprocessor,\ncode .hljs-preprocessor,\npre .hljs-pragma,\ncode .hljs-pragma,\npre .hljs-built_in,\ncode .hljs-built_in,\npre .hljs-literal,\ncode .hljs-literal,\npre .hljs-params,\ncode .hljs-params,\npre .hljs-constant,\ncode .hljs-constant {\n  color: #f5871f;\n}\npre .ruby .hljs-class .hljs-title,\ncode .ruby .hljs-class .hljs-title,\npre .css .hljs-rules .hljs-attribute,\ncode .css .hljs-rules .hljs-attribute {\n  color: #eab700;\n}\npre .hljs-string,\ncode .hljs-string,\npre .hljs-value,\ncode .hljs-value,\npre .hljs-inheritance,\ncode .hljs-inheritance,\npre .hljs-header,\ncode .hljs-header,\npre .hljs-addition,\ncode .hljs-addition,\npre .ruby .hljs-symbol,\ncode .ruby .hljs-symbol,\npre .xml .hljs-cdata,\ncode .xml .hljs-cdata {\n  color: #718c00;\n}\npre .css .hljs-hexcolor,\ncode .css .hljs-hexcolor {\n  color: #3e999f;\n}\npre .hljs-function,\ncode .hljs-function,\npre .python .hljs-decorator,\ncode .python .hljs-decorator,\npre .python .hljs-title,\ncode .python .hljs-title,\npre .ruby .hljs-function .hljs-title,\ncode .ruby .hljs-function .hljs-title,\npre .ruby .hljs-title .hljs-keyword,\ncode .ruby .hljs-title .hljs-keyword,\npre .perl .hljs-sub,\ncode .perl .hljs-sub,\npre .javascript .hljs-title,\ncode .javascript .hljs-title,\npre .coffeescript .hljs-title,\ncode .coffeescript .hljs-title {\n  color: #4271ae;\n}\npre .hljs-keyword,\ncode .hljs-keyword,\npre .javascript .hljs-function,\ncode .javascript .hljs-function {\n  color: #8959a8;\n}\npre .hljs,\ncode .hljs {\n  display: block;\n  background: white;\n  color: #4d4d4c;\n  padding: 0.5em;\n}\npre .coffeescript .javascript,\ncode .coffeescript .javascript,\npre .javascript .xml,\ncode .javascript .xml,\npre .tex .hljs-formula,\ncode .tex .hljs-formula,\npre .xml .javascript,\ncode .xml .javascript,\npre .xml .vbscript,\ncode .xml .vbscript,\npre .xml .css,\ncode .xml .css,\npre .xml .hljs-cdata,\ncode .xml .hljs-cdata {\n  opacity: 0.5;\n}\n"
  },
  {
    "path": "atlas-docs/_book/gitbook/gitbook-plugin-highlight/website.css",
    "content": ".book .book-body .page-wrapper .page-inner section.normal pre,\n.book .book-body .page-wrapper .page-inner section.normal code {\n  /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */\n  /* Tomorrow Comment */\n  /* Tomorrow Red */\n  /* Tomorrow Orange */\n  /* Tomorrow Yellow */\n  /* Tomorrow Green */\n  /* Tomorrow Aqua */\n  /* Tomorrow Blue */\n  /* Tomorrow Purple */\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-comment,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-comment,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-title {\n  color: #8e908c;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-variable,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-variable,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-attribute,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-tag,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-tag,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-regexp,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-deletion,\n.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-constant,\n.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-constant,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-tag .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-tag .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-pi,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-pi,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-doctype,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-doctype,\n.book .book-body .page-wrapper .page-inner section.normal pre .html .hljs-doctype,\n.book .book-body .page-wrapper .page-inner section.normal code .html .hljs-doctype,\n.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-id,\n.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-id,\n.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-class,\n.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-class,\n.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo,\n.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo {\n  color: #c82829;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-number,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-number,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-pragma,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-built_in,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-literal,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-literal,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-params,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-params,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-constant,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-constant {\n  color: #f5871f;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-class .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-class .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-rules .hljs-attribute,\n.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-rules .hljs-attribute {\n  color: #eab700;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-string,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-string,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-value,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-value,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-inheritance,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-inheritance,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-header,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-header,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-addition,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-addition,\n.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-symbol,\n.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-symbol,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata {\n  color: #718c00;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-hexcolor,\n.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-hexcolor {\n  color: #3e999f;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-function,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-function,\n.book .book-body .page-wrapper .page-inner section.normal pre .python .hljs-decorator,\n.book .book-body .page-wrapper .page-inner section.normal code .python .hljs-decorator,\n.book .book-body .page-wrapper .page-inner section.normal pre .python .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal code .python .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-function .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-function .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-title .hljs-keyword,\n.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-title .hljs-keyword,\n.book .book-body .page-wrapper .page-inner section.normal pre .perl .hljs-sub,\n.book .book-body .page-wrapper .page-inner section.normal code .perl .hljs-sub,\n.book .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal pre .coffeescript .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal code .coffeescript .hljs-title {\n  color: #4271ae;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-keyword,\n.book .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-function,\n.book .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-function {\n  color: #8959a8;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs {\n  display: block;\n  background: white;\n  color: #4d4d4c;\n  padding: 0.5em;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .coffeescript .javascript,\n.book .book-body .page-wrapper .page-inner section.normal code .coffeescript .javascript,\n.book .book-body .page-wrapper .page-inner section.normal pre .javascript .xml,\n.book .book-body .page-wrapper .page-inner section.normal code .javascript .xml,\n.book .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula,\n.book .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .javascript,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .javascript,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .vbscript,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .vbscript,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .css,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .css,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata {\n  opacity: 0.5;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code {\n  /*\n\nOrginal Style from ethanschoonover.com/solarized (c) Jeremy Hull <sourdrums@gmail.com>\n\n*/\n  /* Solarized Green */\n  /* Solarized Cyan */\n  /* Solarized Blue */\n  /* Solarized Yellow */\n  /* Solarized Orange */\n  /* Solarized Red */\n  /* Solarized Violet */\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs {\n  display: block;\n  padding: 0.5em;\n  background: #fdf6e3;\n  color: #657b83;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-comment,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-comment,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-template_comment,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-template_comment,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .diff .hljs-header,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .diff .hljs-header,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-doctype,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-doctype,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-pi,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-pi,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .lisp .hljs-string,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .lisp .hljs-string,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-javadoc,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-javadoc {\n  color: #93a1a1;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-keyword,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-winutils,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-winutils,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .method,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .method,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-addition,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-addition,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-tag,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-tag,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-request,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-request,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-status,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-status,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .nginx .hljs-title,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .nginx .hljs-title {\n  color: #859900;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-number,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-number,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-command,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-command,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-string,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-string,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-tag .hljs-value,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-tag .hljs-value,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-rules .hljs-value,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-rules .hljs-value,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-phpdoc,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-phpdoc,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-regexp,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-hexcolor,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-hexcolor,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_url,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_url {\n  color: #2aa198;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-title,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-title,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-localvars,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-localvars,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-chunk,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-chunk,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-decorator,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-decorator,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-built_in,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-identifier,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-identifier,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .vhdl .hljs-literal,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .vhdl .hljs-literal,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-id,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-id,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-function,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-function {\n  color: #268bd2;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-attribute,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-variable,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-variable,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .lisp .hljs-body,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .lisp .hljs-body,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .smalltalk .hljs-number,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .smalltalk .hljs-number,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-constant,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-constant,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-class .hljs-title,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-class .hljs-title,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-parent,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-parent,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .haskell .hljs-type,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .haskell .hljs-type,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_reference,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_reference {\n  color: #b58900;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor .hljs-keyword,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor .hljs-keyword,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-pragma,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-shebang,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-shebang,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-symbol,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-symbol,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-symbol .hljs-string,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-symbol .hljs-string,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .diff .hljs-change,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .diff .hljs-change,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-special,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-special,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-attr_selector,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-attr_selector,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-subst,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-subst,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-cdata,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-cdata,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .clojure .hljs-title,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .clojure .hljs-title,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-header,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-header {\n  color: #cb4b16;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-deletion,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-important,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-important {\n  color: #dc322f;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_label,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_label {\n  color: #6c71c4;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula {\n  background: #eee8d5;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code {\n  /* Tomorrow Night Bright Theme */\n  /* Original theme - https://github.com/chriskempson/tomorrow-theme */\n  /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */\n  /* Tomorrow Comment */\n  /* Tomorrow Red */\n  /* Tomorrow Orange */\n  /* Tomorrow Yellow */\n  /* Tomorrow Green */\n  /* Tomorrow Aqua */\n  /* Tomorrow Blue */\n  /* Tomorrow Purple */\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-comment,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-comment,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-title {\n  color: #969896;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-variable,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-variable,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-attribute,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-tag,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-tag,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-regexp,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-deletion,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-constant,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-constant,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-tag .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-tag .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-pi,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-pi,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-doctype,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-doctype,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .html .hljs-doctype,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .html .hljs-doctype,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-id,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-id,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-class,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-class,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo {\n  color: #d54e53;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-number,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-number,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-pragma,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-built_in,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-literal,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-literal,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-params,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-params,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-constant,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-constant {\n  color: #e78c45;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-class .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-class .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-rules .hljs-attribute,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-rules .hljs-attribute {\n  color: #e7c547;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-string,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-string,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-value,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-value,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-inheritance,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-inheritance,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-header,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-header,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-addition,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-addition,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-symbol,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-symbol,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata {\n  color: #b9ca4a;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-hexcolor,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-hexcolor {\n  color: #70c0b1;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-function,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-function,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .python .hljs-decorator,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .python .hljs-decorator,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .python .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .python .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-function .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-function .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-title .hljs-keyword,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-title .hljs-keyword,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .perl .hljs-sub,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .perl .hljs-sub,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .coffeescript .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .coffeescript .hljs-title {\n  color: #7aa6da;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-keyword,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-function,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-function {\n  color: #c397d8;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs {\n  display: block;\n  background: black;\n  color: #eaeaea;\n  padding: 0.5em;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .coffeescript .javascript,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .coffeescript .javascript,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .xml,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .xml,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .javascript,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .javascript,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .vbscript,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .vbscript,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .css,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .css,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata {\n  opacity: 0.5;\n}\n"
  },
  {
    "path": "atlas-docs/_book/gitbook/gitbook-plugin-livereload/plugin.js",
    "content": "(function() {\n  var newEl = document.createElement('script'),\n      firstScriptTag = document.getElementsByTagName('script')[0];\n\n  if (firstScriptTag) {\n    newEl.async = 1;\n    newEl.src = '//' + window.location.hostname + ':35729/livereload.js';\n    firstScriptTag.parentNode.insertBefore(newEl, firstScriptTag);\n  }\n\n})();\n"
  },
  {
    "path": "atlas-docs/_book/gitbook/gitbook-plugin-lunr/search-lunr.js",
    "content": "require([\n    'gitbook',\n    'jquery'\n], function(gitbook, $) {\n    // Define global search engine\n    function LunrSearchEngine() {\n        this.index = null;\n        this.store = {};\n        this.name = 'LunrSearchEngine';\n    }\n\n    // Initialize lunr by fetching the search index\n    LunrSearchEngine.prototype.init = function() {\n        var that = this;\n        var d = $.Deferred();\n\n        $.getJSON(gitbook.state.basePath+'/search_index.json')\n        .then(function(data) {\n            // eslint-disable-next-line no-undef\n            that.index = lunr.Index.load(data.index);\n            that.store = data.store;\n            d.resolve();\n        });\n\n        return d.promise();\n    };\n\n    // Search for a term and return results\n    LunrSearchEngine.prototype.search = function(q, offset, length) {\n        var that = this;\n        var results = [];\n\n        if (this.index) {\n            results = $.map(this.index.search(q), function(result) {\n                var doc = that.store[result.ref];\n\n                return {\n                    title: doc.title,\n                    url: doc.url,\n                    body: doc.summary || doc.body\n                };\n            });\n        }\n\n        return $.Deferred().resolve({\n            query: q,\n            results: results.slice(0, length),\n            count: results.length\n        }).promise();\n    };\n\n    // Set gitbook research\n    gitbook.events.bind('start', function(e, config) {\n        var engine = gitbook.search.getEngine();\n        if (!engine) {\n            gitbook.search.setEngine(LunrSearchEngine, config);\n        }\n    });\n});\n"
  },
  {
    "path": "atlas-docs/_book/gitbook/gitbook-plugin-search/search-engine.js",
    "content": "require([\n    'gitbook',\n    'jquery'\n], function(gitbook, $) {\n    // Global search objects\n    var engine      = null;\n    var initialized = false;\n\n    // Set a new search engine\n    function setEngine(Engine, config) {\n        initialized = false;\n        engine      = new Engine(config);\n\n        init(config);\n    }\n\n    // Initialize search engine with config\n    function init(config) {\n        if (!engine) throw new Error('No engine set for research. Set an engine using gitbook.research.setEngine(Engine).');\n\n        return engine.init(config)\n        .then(function() {\n            initialized = true;\n            gitbook.events.trigger('search.ready');\n        });\n    }\n\n    // Launch search for query q\n    function query(q, offset, length) {\n        if (!initialized) throw new Error('Search has not been initialized');\n        return engine.search(q, offset, length);\n    }\n\n    // Get stats about search\n    function getEngine() {\n        return engine? engine.name : null;\n    }\n\n    function isInitialized() {\n        return initialized;\n    }\n\n    // Initialize gitbook.search\n    gitbook.search = {\n        setEngine:     setEngine,\n        getEngine:     getEngine,\n        query:         query,\n        isInitialized: isInitialized\n    };\n});"
  },
  {
    "path": "atlas-docs/_book/gitbook/gitbook-plugin-search/search.css",
    "content": "/*\n    This CSS only styled the search results section, not the search input\n    It defines the basic interraction to hide content when displaying results, etc\n*/\n#book-search-results .search-results {\n  display: none;\n}\n#book-search-results .search-results ul.search-results-list {\n  list-style-type: none;\n  padding-left: 0;\n}\n#book-search-results .search-results ul.search-results-list li {\n  margin-bottom: 1.5rem;\n  padding-bottom: 0.5rem;\n  /* Highlight results */\n}\n#book-search-results .search-results ul.search-results-list li p em {\n  background-color: rgba(255, 220, 0, 0.4);\n  font-style: normal;\n}\n#book-search-results .search-results .no-results {\n  display: none;\n}\n#book-search-results.open .search-results {\n  display: block;\n}\n#book-search-results.open .search-noresults {\n  display: none;\n}\n#book-search-results.no-results .search-results .has-results {\n  display: none;\n}\n#book-search-results.no-results .search-results .no-results {\n  display: block;\n}\n"
  },
  {
    "path": "atlas-docs/_book/gitbook/gitbook-plugin-search/search.js",
    "content": "require([\n    'gitbook',\n    'jquery'\n], function(gitbook, $) {\n    var MAX_RESULTS = 15;\n    var MAX_DESCRIPTION_SIZE = 500;\n\n    var usePushState = (typeof history.pushState !== 'undefined');\n\n    // DOM Elements\n    var $body = $('body');\n    var $bookSearchResults;\n    var $searchInput;\n    var $searchList;\n    var $searchTitle;\n    var $searchResultsCount;\n    var $searchQuery;\n\n    // Throttle search\n    function throttle(fn, wait) {\n        var timeout;\n\n        return function() {\n            var ctx = this, args = arguments;\n            if (!timeout) {\n                timeout = setTimeout(function() {\n                    timeout = null;\n                    fn.apply(ctx, args);\n                }, wait);\n            }\n        };\n    }\n\n    function displayResults(res) {\n        $bookSearchResults.addClass('open');\n\n        var noResults = res.count == 0;\n        $bookSearchResults.toggleClass('no-results', noResults);\n\n        // Clear old results\n        $searchList.empty();\n\n        // Display title for research\n        $searchResultsCount.text(res.count);\n        $searchQuery.text(res.query);\n\n        // Create an <li> element for each result\n        res.results.forEach(function(res) {\n            var $li = $('<li>', {\n                'class': 'search-results-item'\n            });\n\n            var $title = $('<h3>');\n\n            var $link = $('<a>', {\n                'href': gitbook.state.basePath + '/' + res.url,\n                'text': res.title\n            });\n\n            var content = res.body.trim();\n            if (content.length > MAX_DESCRIPTION_SIZE) {\n                content = content.slice(0, MAX_DESCRIPTION_SIZE).trim()+'...';\n            }\n            var $content = $('<p>').html(content);\n\n            $link.appendTo($title);\n            $title.appendTo($li);\n            $content.appendTo($li);\n            $li.appendTo($searchList);\n        });\n    }\n\n    function launchSearch(q) {\n        // Add class for loading\n        $body.addClass('with-search');\n        $body.addClass('search-loading');\n\n        // Launch search query\n        throttle(gitbook.search.query(q, 0, MAX_RESULTS)\n        .then(function(results) {\n            displayResults(results);\n        })\n        .always(function() {\n            $body.removeClass('search-loading');\n        }), 1000);\n    }\n\n    function closeSearch() {\n        $body.removeClass('with-search');\n        $bookSearchResults.removeClass('open');\n    }\n\n    function launchSearchFromQueryString() {\n        var q = getParameterByName('q');\n        if (q && q.length > 0) {\n            // Update search input\n            $searchInput.val(q);\n\n            // Launch search\n            launchSearch(q);\n        }\n    }\n\n    function bindSearch() {\n        // Bind DOM\n        $searchInput        = $('#book-search-input input');\n        $bookSearchResults  = $('#book-search-results');\n        $searchList         = $bookSearchResults.find('.search-results-list');\n        $searchTitle        = $bookSearchResults.find('.search-results-title');\n        $searchResultsCount = $searchTitle.find('.search-results-count');\n        $searchQuery        = $searchTitle.find('.search-query');\n\n        // Launch query based on input content\n        function handleUpdate() {\n            var q = $searchInput.val();\n\n            if (q.length == 0) {\n                closeSearch();\n            }\n            else {\n                launchSearch(q);\n            }\n        }\n\n        // Detect true content change in search input\n        // Workaround for IE < 9\n        var propertyChangeUnbound = false;\n        $searchInput.on('propertychange', function(e) {\n            if (e.originalEvent.propertyName == 'value') {\n                handleUpdate();\n            }\n        });\n\n        // HTML5 (IE9 & others)\n        $searchInput.on('input', function(e) {\n            // Unbind propertychange event for IE9+\n            if (!propertyChangeUnbound) {\n                $(this).unbind('propertychange');\n                propertyChangeUnbound = true;\n            }\n\n            handleUpdate();\n        });\n\n        // Push to history on blur\n        $searchInput.on('blur', function(e) {\n            // Update history state\n            if (usePushState) {\n                var uri = updateQueryString('q', $(this).val());\n                history.pushState({ path: uri }, null, uri);\n            }\n        });\n    }\n\n    gitbook.events.on('page.change', function() {\n        bindSearch();\n        closeSearch();\n\n        // Launch search based on query parameter\n        if (gitbook.search.isInitialized()) {\n            launchSearchFromQueryString();\n        }\n    });\n\n    gitbook.events.on('search.ready', function() {\n        bindSearch();\n\n        // Launch search from query param at start\n        launchSearchFromQueryString();\n    });\n\n    function getParameterByName(name) {\n        var url = window.location.href;\n        name = name.replace(/[\\[\\]]/g, '\\\\$&');\n        var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)', 'i'),\n            results = regex.exec(url);\n        if (!results) return null;\n        if (!results[2]) return '';\n        return decodeURIComponent(results[2].replace(/\\+/g, ' '));\n    }\n\n    function updateQueryString(key, value) {\n        value = encodeURIComponent(value);\n\n        var url = window.location.href;\n        var re = new RegExp('([?&])' + key + '=.*?(&|#|$)(.*)', 'gi'),\n            hash;\n\n        if (re.test(url)) {\n            if (typeof value !== 'undefined' && value !== null)\n                return url.replace(re, '$1' + key + '=' + value + '$2$3');\n            else {\n                hash = url.split('#');\n                url = hash[0].replace(re, '$1$3').replace(/(&|\\?)$/, '');\n                if (typeof hash[1] !== 'undefined' && hash[1] !== null)\n                    url += '#' + hash[1];\n                return url;\n            }\n        }\n        else {\n            if (typeof value !== 'undefined' && value !== null) {\n                var separator = url.indexOf('?') !== -1 ? '&' : '?';\n                hash = url.split('#');\n                url = hash[0] + separator + key + '=' + value;\n                if (typeof hash[1] !== 'undefined' && hash[1] !== null)\n                    url += '#' + hash[1];\n                return url;\n            }\n            else\n                return url;\n        }\n    }\n});\n"
  },
  {
    "path": "atlas-docs/_book/gitbook/gitbook-plugin-sharing/buttons.js",
    "content": "require(['gitbook', 'jquery'], function(gitbook, $) {\n    var SITES = {\n        'facebook': {\n            'label': 'Facebook',\n            'icon': 'fa fa-facebook',\n            'onClick': function(e) {\n                e.preventDefault();\n                window.open('http://www.facebook.com/sharer/sharer.php?s=100&p[url]='+encodeURIComponent(location.href));\n            }\n        },\n        'twitter': {\n            'label': 'Twitter',\n            'icon': 'fa fa-twitter',\n            'onClick': function(e) {\n                e.preventDefault();\n                window.open('http://twitter.com/home?status='+encodeURIComponent(document.title+' '+location.href));\n            }\n        },\n        'google': {\n            'label': 'Google+',\n            'icon': 'fa fa-google-plus',\n            'onClick': function(e) {\n                e.preventDefault();\n                window.open('https://plus.google.com/share?url='+encodeURIComponent(location.href));\n            }\n        },\n        'weibo': {\n            'label': 'Weibo',\n            'icon': 'fa fa-weibo',\n            'onClick': function(e) {\n                e.preventDefault();\n                window.open('http://service.weibo.com/share/share.php?content=utf-8&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title));\n            }\n        },\n        'instapaper': {\n            'label': 'Instapaper',\n            'icon': 'fa fa-instapaper',\n            'onClick': function(e) {\n                e.preventDefault();\n                window.open('http://www.instapaper.com/text?u='+encodeURIComponent(location.href));\n            }\n        },\n        'vk': {\n            'label': 'VK',\n            'icon': 'fa fa-vk',\n            'onClick': function(e) {\n                e.preventDefault();\n                window.open('http://vkontakte.ru/share.php?url='+encodeURIComponent(location.href));\n            }\n        }\n    };\n\n\n\n    gitbook.events.bind('start', function(e, config) {\n        var opts = config.sharing;\n\n        // Create dropdown menu\n        var menu = $.map(opts.all, function(id) {\n            var site = SITES[id];\n\n            return {\n                text: site.label,\n                onClick: site.onClick\n            };\n        });\n\n        // Create main button with dropdown\n        if (menu.length > 0) {\n            gitbook.toolbar.createButton({\n                icon: 'fa fa-share-alt',\n                label: 'Share',\n                position: 'right',\n                dropdown: [menu]\n            });\n        }\n\n        // Direct actions to share\n        $.each(SITES, function(sideId, site) {\n            if (!opts[sideId]) return;\n\n            gitbook.toolbar.createButton({\n                icon: site.icon,\n                label: site.text,\n                position: 'right',\n                onClick: site.onClick\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "atlas-docs/_book/gitbook/gitbook.js",
    "content": "!function e(t,n,r){function o(s,a){if(!n[s]){if(!t[s]){var u=\"function\"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var c=new Error(\"Cannot find module '\"+s+\"'\");throw c.code=\"MODULE_NOT_FOUND\",c}var l=n[s]={exports:{}};t[s][0].call(l.exports,function(e){var n=t[s][1][e];return o(n?n:e)},l,l.exports,e,t,n,r)}return n[s].exports}for(var i=\"function\"==typeof require&&require,s=0;s<r.length;s++)o(r[s]);return o}({1:[function(e,t,n){!function(e,n){\"use strict\";\"object\"==typeof t&&\"object\"==typeof t.exports?t.exports=e.document?n(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return n(e)}:n(e)}(\"undefined\"!=typeof window?window:this,function(e,t){\"use strict\";function n(e,t){t=t||te;var n=t.createElement(\"script\");n.text=e,t.head.appendChild(n).parentNode.removeChild(n)}function r(e){var t=!!e&&\"length\"in e&&e.length,n=de.type(e);return\"function\"!==n&&!de.isWindow(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&t>0&&t-1 in e)}function o(e,t,n){return de.isFunction(t)?de.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?de.grep(e,function(e){return e===t!==n}):\"string\"!=typeof t?de.grep(e,function(e){return se.call(t,e)>-1!==n}):je.test(t)?de.filter(t,e,n):(t=de.filter(t,e),de.grep(e,function(e){return se.call(t,e)>-1!==n&&1===e.nodeType}))}function i(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function s(e){var t={};return de.each(e.match(qe)||[],function(e,n){t[n]=!0}),t}function a(e){return e}function u(e){throw e}function c(e,t,n){var r;try{e&&de.isFunction(r=e.promise)?r.call(e).done(t).fail(n):e&&de.isFunction(r=e.then)?r.call(e,t,n):t.call(void 0,e)}catch(e){n.call(void 0,e)}}function l(){te.removeEventListener(\"DOMContentLoaded\",l),e.removeEventListener(\"load\",l),de.ready()}function f(){this.expando=de.expando+f.uid++}function p(e){return\"true\"===e||\"false\"!==e&&(\"null\"===e?null:e===+e+\"\"?+e:Ie.test(e)?JSON.parse(e):e)}function h(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r=\"data-\"+t.replace(Pe,\"-$&\").toLowerCase(),n=e.getAttribute(r),\"string\"==typeof n){try{n=p(n)}catch(e){}Re.set(e,t,n)}else n=void 0;return n}function d(e,t,n,r){var o,i=1,s=20,a=r?function(){return r.cur()}:function(){return de.css(e,t,\"\")},u=a(),c=n&&n[3]||(de.cssNumber[t]?\"\":\"px\"),l=(de.cssNumber[t]||\"px\"!==c&&+u)&&$e.exec(de.css(e,t));if(l&&l[3]!==c){c=c||l[3],n=n||[],l=+u||1;do i=i||\".5\",l/=i,de.style(e,t,l+c);while(i!==(i=a()/u)&&1!==i&&--s)}return n&&(l=+l||+u||0,o=n[1]?l+(n[1]+1)*n[2]:+n[2],r&&(r.unit=c,r.start=l,r.end=o)),o}function g(e){var t,n=e.ownerDocument,r=e.nodeName,o=Ue[r];return o?o:(t=n.body.appendChild(n.createElement(r)),o=de.css(t,\"display\"),t.parentNode.removeChild(t),\"none\"===o&&(o=\"block\"),Ue[r]=o,o)}function m(e,t){for(var n,r,o=[],i=0,s=e.length;i<s;i++)r=e[i],r.style&&(n=r.style.display,t?(\"none\"===n&&(o[i]=Fe.get(r,\"display\")||null,o[i]||(r.style.display=\"\")),\"\"===r.style.display&&Be(r)&&(o[i]=g(r))):\"none\"!==n&&(o[i]=\"none\",Fe.set(r,\"display\",n)));for(i=0;i<s;i++)null!=o[i]&&(e[i].style.display=o[i]);return e}function v(e,t){var n;return n=\"undefined\"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):\"undefined\"!=typeof e.querySelectorAll?e.querySelectorAll(t||\"*\"):[],void 0===t||t&&de.nodeName(e,t)?de.merge([e],n):n}function y(e,t){for(var n=0,r=e.length;n<r;n++)Fe.set(e[n],\"globalEval\",!t||Fe.get(t[n],\"globalEval\"))}function x(e,t,n,r,o){for(var i,s,a,u,c,l,f=t.createDocumentFragment(),p=[],h=0,d=e.length;h<d;h++)if(i=e[h],i||0===i)if(\"object\"===de.type(i))de.merge(p,i.nodeType?[i]:i);else if(Ye.test(i)){for(s=s||f.appendChild(t.createElement(\"div\")),a=(Xe.exec(i)||[\"\",\"\"])[1].toLowerCase(),u=Ge[a]||Ge._default,s.innerHTML=u[1]+de.htmlPrefilter(i)+u[2],l=u[0];l--;)s=s.lastChild;de.merge(p,s.childNodes),s=f.firstChild,s.textContent=\"\"}else p.push(t.createTextNode(i));for(f.textContent=\"\",h=0;i=p[h++];)if(r&&de.inArray(i,r)>-1)o&&o.push(i);else if(c=de.contains(i.ownerDocument,i),s=v(f.appendChild(i),\"script\"),c&&y(s),n)for(l=0;i=s[l++];)Ve.test(i.type||\"\")&&n.push(i);return f}function b(){return!0}function w(){return!1}function T(){try{return te.activeElement}catch(e){}}function C(e,t,n,r,o,i){var s,a;if(\"object\"==typeof t){\"string\"!=typeof n&&(r=r||n,n=void 0);for(a in t)C(e,a,n,r,t[a],i);return e}if(null==r&&null==o?(o=n,r=n=void 0):null==o&&(\"string\"==typeof n?(o=r,r=void 0):(o=r,r=n,n=void 0)),o===!1)o=w;else if(!o)return e;return 1===i&&(s=o,o=function(e){return de().off(e),s.apply(this,arguments)},o.guid=s.guid||(s.guid=de.guid++)),e.each(function(){de.event.add(this,t,o,r,n)})}function j(e,t){return de.nodeName(e,\"table\")&&de.nodeName(11!==t.nodeType?t:t.firstChild,\"tr\")?e.getElementsByTagName(\"tbody\")[0]||e:e}function k(e){return e.type=(null!==e.getAttribute(\"type\"))+\"/\"+e.type,e}function E(e){var t=rt.exec(e.type);return t?e.type=t[1]:e.removeAttribute(\"type\"),e}function S(e,t){var n,r,o,i,s,a,u,c;if(1===t.nodeType){if(Fe.hasData(e)&&(i=Fe.access(e),s=Fe.set(t,i),c=i.events)){delete s.handle,s.events={};for(o in c)for(n=0,r=c[o].length;n<r;n++)de.event.add(t,o,c[o][n])}Re.hasData(e)&&(a=Re.access(e),u=de.extend({},a),Re.set(t,u))}}function N(e,t){var n=t.nodeName.toLowerCase();\"input\"===n&&ze.test(e.type)?t.checked=e.checked:\"input\"!==n&&\"textarea\"!==n||(t.defaultValue=e.defaultValue)}function A(e,t,r,o){t=oe.apply([],t);var i,s,a,u,c,l,f=0,p=e.length,h=p-1,d=t[0],g=de.isFunction(d);if(g||p>1&&\"string\"==typeof d&&!pe.checkClone&&nt.test(d))return e.each(function(n){var i=e.eq(n);g&&(t[0]=d.call(this,n,i.html())),A(i,t,r,o)});if(p&&(i=x(t,e[0].ownerDocument,!1,e,o),s=i.firstChild,1===i.childNodes.length&&(i=s),s||o)){for(a=de.map(v(i,\"script\"),k),u=a.length;f<p;f++)c=i,f!==h&&(c=de.clone(c,!0,!0),u&&de.merge(a,v(c,\"script\"))),r.call(e[f],c,f);if(u)for(l=a[a.length-1].ownerDocument,de.map(a,E),f=0;f<u;f++)c=a[f],Ve.test(c.type||\"\")&&!Fe.access(c,\"globalEval\")&&de.contains(l,c)&&(c.src?de._evalUrl&&de._evalUrl(c.src):n(c.textContent.replace(ot,\"\"),l))}return e}function q(e,t,n){for(var r,o=t?de.filter(t,e):e,i=0;null!=(r=o[i]);i++)n||1!==r.nodeType||de.cleanData(v(r)),r.parentNode&&(n&&de.contains(r.ownerDocument,r)&&y(v(r,\"script\")),r.parentNode.removeChild(r));return e}function D(e,t,n){var r,o,i,s,a=e.style;return n=n||at(e),n&&(s=n.getPropertyValue(t)||n[t],\"\"!==s||de.contains(e.ownerDocument,e)||(s=de.style(e,t)),!pe.pixelMarginRight()&&st.test(s)&&it.test(t)&&(r=a.width,o=a.minWidth,i=a.maxWidth,a.minWidth=a.maxWidth=a.width=s,s=n.width,a.width=r,a.minWidth=o,a.maxWidth=i)),void 0!==s?s+\"\":s}function O(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function L(e){if(e in pt)return e;for(var t=e[0].toUpperCase()+e.slice(1),n=ft.length;n--;)if(e=ft[n]+t,e in pt)return e}function H(e,t,n){var r=$e.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||\"px\"):t}function F(e,t,n,r,o){var i,s=0;for(i=n===(r?\"border\":\"content\")?4:\"width\"===t?1:0;i<4;i+=2)\"margin\"===n&&(s+=de.css(e,n+We[i],!0,o)),r?(\"content\"===n&&(s-=de.css(e,\"padding\"+We[i],!0,o)),\"margin\"!==n&&(s-=de.css(e,\"border\"+We[i]+\"Width\",!0,o))):(s+=de.css(e,\"padding\"+We[i],!0,o),\"padding\"!==n&&(s+=de.css(e,\"border\"+We[i]+\"Width\",!0,o)));return s}function R(e,t,n){var r,o=!0,i=at(e),s=\"border-box\"===de.css(e,\"boxSizing\",!1,i);if(e.getClientRects().length&&(r=e.getBoundingClientRect()[t]),r<=0||null==r){if(r=D(e,t,i),(r<0||null==r)&&(r=e.style[t]),st.test(r))return r;o=s&&(pe.boxSizingReliable()||r===e.style[t]),r=parseFloat(r)||0}return r+F(e,t,n||(s?\"border\":\"content\"),o,i)+\"px\"}function I(e,t,n,r,o){return new I.prototype.init(e,t,n,r,o)}function P(){dt&&(e.requestAnimationFrame(P),de.fx.tick())}function M(){return e.setTimeout(function(){ht=void 0}),ht=de.now()}function $(e,t){var n,r=0,o={height:e};for(t=t?1:0;r<4;r+=2-t)n=We[r],o[\"margin\"+n]=o[\"padding\"+n]=e;return t&&(o.opacity=o.width=e),o}function W(e,t,n){for(var r,o=(U.tweeners[t]||[]).concat(U.tweeners[\"*\"]),i=0,s=o.length;i<s;i++)if(r=o[i].call(n,t,e))return r}function B(e,t,n){var r,o,i,s,a,u,c,l,f=\"width\"in t||\"height\"in t,p=this,h={},d=e.style,g=e.nodeType&&Be(e),v=Fe.get(e,\"fxshow\");n.queue||(s=de._queueHooks(e,\"fx\"),null==s.unqueued&&(s.unqueued=0,a=s.empty.fire,s.empty.fire=function(){s.unqueued||a()}),s.unqueued++,p.always(function(){p.always(function(){s.unqueued--,de.queue(e,\"fx\").length||s.empty.fire()})}));for(r in t)if(o=t[r],gt.test(o)){if(delete t[r],i=i||\"toggle\"===o,o===(g?\"hide\":\"show\")){if(\"show\"!==o||!v||void 0===v[r])continue;g=!0}h[r]=v&&v[r]||de.style(e,r)}if(u=!de.isEmptyObject(t),u||!de.isEmptyObject(h)){f&&1===e.nodeType&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],c=v&&v.display,null==c&&(c=Fe.get(e,\"display\")),l=de.css(e,\"display\"),\"none\"===l&&(c?l=c:(m([e],!0),c=e.style.display||c,l=de.css(e,\"display\"),m([e]))),(\"inline\"===l||\"inline-block\"===l&&null!=c)&&\"none\"===de.css(e,\"float\")&&(u||(p.done(function(){d.display=c}),null==c&&(l=d.display,c=\"none\"===l?\"\":l)),d.display=\"inline-block\")),n.overflow&&(d.overflow=\"hidden\",p.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]})),u=!1;for(r in h)u||(v?\"hidden\"in v&&(g=v.hidden):v=Fe.access(e,\"fxshow\",{display:c}),i&&(v.hidden=!g),g&&m([e],!0),p.done(function(){g||m([e]),Fe.remove(e,\"fxshow\");for(r in h)de.style(e,r,h[r])})),u=W(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}}function _(e,t){var n,r,o,i,s;for(n in e)if(r=de.camelCase(n),o=t[r],i=e[n],de.isArray(i)&&(o=i[1],i=e[n]=i[0]),n!==r&&(e[r]=i,delete e[n]),s=de.cssHooks[r],s&&\"expand\"in s){i=s.expand(i),delete e[r];for(n in i)n in e||(e[n]=i[n],t[n]=o)}else t[r]=o}function U(e,t,n){var r,o,i=0,s=U.prefilters.length,a=de.Deferred().always(function(){delete u.elem}),u=function(){if(o)return!1;for(var t=ht||M(),n=Math.max(0,c.startTime+c.duration-t),r=n/c.duration||0,i=1-r,s=0,u=c.tweens.length;s<u;s++)c.tweens[s].run(i);return a.notifyWith(e,[c,i,n]),i<1&&u?n:(a.resolveWith(e,[c]),!1)},c=a.promise({elem:e,props:de.extend({},t),opts:de.extend(!0,{specialEasing:{},easing:de.easing._default},n),originalProperties:t,originalOptions:n,startTime:ht||M(),duration:n.duration,tweens:[],createTween:function(t,n){var r=de.Tween(e,c.opts,t,n,c.opts.specialEasing[t]||c.opts.easing);return c.tweens.push(r),r},stop:function(t){var n=0,r=t?c.tweens.length:0;if(o)return this;for(o=!0;n<r;n++)c.tweens[n].run(1);return t?(a.notifyWith(e,[c,1,0]),a.resolveWith(e,[c,t])):a.rejectWith(e,[c,t]),this}}),l=c.props;for(_(l,c.opts.specialEasing);i<s;i++)if(r=U.prefilters[i].call(c,e,l,c.opts))return de.isFunction(r.stop)&&(de._queueHooks(c.elem,c.opts.queue).stop=de.proxy(r.stop,r)),r;return de.map(l,W,c),de.isFunction(c.opts.start)&&c.opts.start.call(e,c),de.fx.timer(de.extend(u,{elem:e,anim:c,queue:c.opts.queue})),c.progress(c.opts.progress).done(c.opts.done,c.opts.complete).fail(c.opts.fail).always(c.opts.always)}function z(e){var t=e.match(qe)||[];return t.join(\" \")}function X(e){return e.getAttribute&&e.getAttribute(\"class\")||\"\"}function V(e,t,n,r){var o;if(de.isArray(t))de.each(t,function(t,o){n||Et.test(e)?r(e,o):V(e+\"[\"+(\"object\"==typeof o&&null!=o?t:\"\")+\"]\",o,n,r)});else if(n||\"object\"!==de.type(t))r(e,t);else for(o in t)V(e+\"[\"+o+\"]\",t[o],n,r)}function G(e){return function(t,n){\"string\"!=typeof t&&(n=t,t=\"*\");var r,o=0,i=t.toLowerCase().match(qe)||[];if(de.isFunction(n))for(;r=i[o++];)\"+\"===r[0]?(r=r.slice(1)||\"*\",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function Y(e,t,n,r){function o(a){var u;return i[a]=!0,de.each(e[a]||[],function(e,a){var c=a(t,n,r);return\"string\"!=typeof c||s||i[c]?s?!(u=c):void 0:(t.dataTypes.unshift(c),o(c),!1)}),u}var i={},s=e===Pt;return o(t.dataTypes[0])||!i[\"*\"]&&o(\"*\")}function Q(e,t){var n,r,o=de.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((o[n]?e:r||(r={}))[n]=t[n]);return r&&de.extend(!0,e,r),e}function J(e,t,n){for(var r,o,i,s,a=e.contents,u=e.dataTypes;\"*\"===u[0];)u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader(\"Content-Type\"));if(r)for(o in a)if(a[o]&&a[o].test(r)){u.unshift(o);break}if(u[0]in n)i=u[0];else{for(o in n){if(!u[0]||e.converters[o+\" \"+u[0]]){i=o;break}s||(s=o)}i=i||s}if(i)return i!==u[0]&&u.unshift(i),n[i]}function K(e,t,n,r){var o,i,s,a,u,c={},l=e.dataTypes.slice();if(l[1])for(s in e.converters)c[s.toLowerCase()]=e.converters[s];for(i=l.shift();i;)if(e.responseFields[i]&&(n[e.responseFields[i]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=i,i=l.shift())if(\"*\"===i)i=u;else if(\"*\"!==u&&u!==i){if(s=c[u+\" \"+i]||c[\"* \"+i],!s)for(o in c)if(a=o.split(\" \"),a[1]===i&&(s=c[u+\" \"+a[0]]||c[\"* \"+a[0]])){s===!0?s=c[o]:c[o]!==!0&&(i=a[0],l.unshift(a[1]));break}if(s!==!0)if(s&&e.throws)t=s(t);else try{t=s(t)}catch(e){return{state:\"parsererror\",error:s?e:\"No conversion from \"+u+\" to \"+i}}}return{state:\"success\",data:t}}function Z(e){return de.isWindow(e)?e:9===e.nodeType&&e.defaultView}var ee=[],te=e.document,ne=Object.getPrototypeOf,re=ee.slice,oe=ee.concat,ie=ee.push,se=ee.indexOf,ae={},ue=ae.toString,ce=ae.hasOwnProperty,le=ce.toString,fe=le.call(Object),pe={},he=\"3.1.1\",de=function(e,t){return new de.fn.init(e,t)},ge=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,me=/^-ms-/,ve=/-([a-z])/g,ye=function(e,t){return t.toUpperCase()};de.fn=de.prototype={jquery:he,constructor:de,length:0,toArray:function(){return re.call(this)},get:function(e){return null==e?re.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=de.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return de.each(this,e)},map:function(e){return this.pushStack(de.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(re.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:ie,sort:ee.sort,splice:ee.splice},de.extend=de.fn.extend=function(){var e,t,n,r,o,i,s=arguments[0]||{},a=1,u=arguments.length,c=!1;for(\"boolean\"==typeof s&&(c=s,s=arguments[a]||{},a++),\"object\"==typeof s||de.isFunction(s)||(s={}),a===u&&(s=this,a--);a<u;a++)if(null!=(e=arguments[a]))for(t in e)n=s[t],r=e[t],s!==r&&(c&&r&&(de.isPlainObject(r)||(o=de.isArray(r)))?(o?(o=!1,i=n&&de.isArray(n)?n:[]):i=n&&de.isPlainObject(n)?n:{},s[t]=de.extend(c,i,r)):void 0!==r&&(s[t]=r));return s},de.extend({expando:\"jQuery\"+(he+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isFunction:function(e){return\"function\"===de.type(e)},isArray:Array.isArray,isWindow:function(e){return null!=e&&e===e.window},isNumeric:function(e){var t=de.type(e);return(\"number\"===t||\"string\"===t)&&!isNaN(e-parseFloat(e))},isPlainObject:function(e){var t,n;return!(!e||\"[object Object]\"!==ue.call(e))&&(!(t=ne(e))||(n=ce.call(t,\"constructor\")&&t.constructor,\"function\"==typeof n&&le.call(n)===fe))},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},type:function(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?ae[ue.call(e)]||\"object\":typeof e},globalEval:function(e){n(e)},camelCase:function(e){return e.replace(me,\"ms-\").replace(ve,ye)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var n,o=0;if(r(e))for(n=e.length;o<n&&t.call(e[o],o,e[o])!==!1;o++);else for(o in e)if(t.call(e[o],o,e[o])===!1)break;return e},trim:function(e){return null==e?\"\":(e+\"\").replace(ge,\"\")},makeArray:function(e,t){var n=t||[];return null!=e&&(r(Object(e))?de.merge(n,\"string\"==typeof e?[e]:e):ie.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:se.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,o=e.length;r<n;r++)e[o++]=t[r];return e.length=o,e},grep:function(e,t,n){for(var r,o=[],i=0,s=e.length,a=!n;i<s;i++)r=!t(e[i],i),r!==a&&o.push(e[i]);return o},map:function(e,t,n){var o,i,s=0,a=[];if(r(e))for(o=e.length;s<o;s++)i=t(e[s],s,n),null!=i&&a.push(i);else for(s in e)i=t(e[s],s,n),null!=i&&a.push(i);return oe.apply([],a)},guid:1,proxy:function(e,t){var n,r,o;if(\"string\"==typeof t&&(n=e[t],t=e,e=n),de.isFunction(e))return r=re.call(arguments,2),o=function(){return e.apply(t||this,r.concat(re.call(arguments)))},o.guid=e.guid=e.guid||de.guid++,o},now:Date.now,support:pe}),\"function\"==typeof Symbol&&(de.fn[Symbol.iterator]=ee[Symbol.iterator]),de.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(e,t){ae[\"[object \"+t+\"]\"]=t.toLowerCase()});var xe=function(e){function t(e,t,n,r){var o,i,s,a,u,c,l,p=t&&t.ownerDocument,d=t?t.nodeType:9;if(n=n||[],\"string\"!=typeof e||!e||1!==d&&9!==d&&11!==d)return n;if(!r&&((t?t.ownerDocument||t:W)!==L&&O(t),t=t||L,F)){if(11!==d&&(u=ve.exec(e)))if(o=u[1]){if(9===d){if(!(s=t.getElementById(o)))return n;if(s.id===o)return n.push(s),n}else if(p&&(s=p.getElementById(o))&&M(t,s)&&s.id===o)return n.push(s),n}else{if(u[2])return K.apply(n,t.getElementsByTagName(e)),n;if((o=u[3])&&T.getElementsByClassName&&t.getElementsByClassName)return K.apply(n,t.getElementsByClassName(o)),n}if(T.qsa&&!X[e+\" \"]&&(!R||!R.test(e))){if(1!==d)p=t,l=e;else if(\"object\"!==t.nodeName.toLowerCase()){for((a=t.getAttribute(\"id\"))?a=a.replace(we,Te):t.setAttribute(\"id\",a=$),c=E(e),i=c.length;i--;)c[i]=\"#\"+a+\" \"+h(c[i]);l=c.join(\",\"),p=ye.test(e)&&f(t.parentNode)||t}if(l)try{return K.apply(n,p.querySelectorAll(l)),n}catch(e){}finally{a===$&&t.removeAttribute(\"id\")}}}return N(e.replace(ae,\"$1\"),t,n,r)}function n(){function e(n,r){return t.push(n+\" \")>C.cacheLength&&delete e[t.shift()],e[n+\" \"]=r}var t=[];return e}function r(e){return e[$]=!0,e}function o(e){var t=L.createElement(\"fieldset\");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function i(e,t){for(var n=e.split(\"|\"),r=n.length;r--;)C.attrHandle[n[r]]=t}function s(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function a(e){return function(t){var n=t.nodeName.toLowerCase();return\"input\"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return(\"input\"===n||\"button\"===n)&&t.type===e}}function c(e){return function(t){return\"form\"in t?t.parentNode&&t.disabled===!1?\"label\"in t?\"label\"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&je(t)===e:t.disabled===e:\"label\"in t&&t.disabled===e}}function l(e){return r(function(t){return t=+t,r(function(n,r){for(var o,i=e([],n.length,t),s=i.length;s--;)n[o=i[s]]&&(n[o]=!(r[o]=n[o]))})})}function f(e){return e&&\"undefined\"!=typeof e.getElementsByTagName&&e}function p(){}function h(e){for(var t=0,n=e.length,r=\"\";t<n;t++)r+=e[t].value;return r}function d(e,t,n){var r=t.dir,o=t.next,i=o||r,s=n&&\"parentNode\"===i,a=_++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||s)return e(t,n,o);return!1}:function(t,n,u){var c,l,f,p=[B,a];if(u){for(;t=t[r];)if((1===t.nodeType||s)&&e(t,n,u))return!0}else for(;t=t[r];)if(1===t.nodeType||s)if(f=t[$]||(t[$]={}),l=f[t.uniqueID]||(f[t.uniqueID]={}),o&&o===t.nodeName.toLowerCase())t=t[r]||t;else{if((c=l[i])&&c[0]===B&&c[1]===a)return p[2]=c[2];if(l[i]=p,p[2]=e(t,n,u))return!0}return!1}}function g(e){return e.length>1?function(t,n,r){for(var o=e.length;o--;)if(!e[o](t,n,r))return!1;return!0}:e[0]}function m(e,n,r){for(var o=0,i=n.length;o<i;o++)t(e,n[o],r);return r}function v(e,t,n,r,o){for(var i,s=[],a=0,u=e.length,c=null!=t;a<u;a++)(i=e[a])&&(n&&!n(i,r,o)||(s.push(i),c&&t.push(a)));return s}function y(e,t,n,o,i,s){return o&&!o[$]&&(o=y(o)),i&&!i[$]&&(i=y(i,s)),r(function(r,s,a,u){var c,l,f,p=[],h=[],d=s.length,g=r||m(t||\"*\",a.nodeType?[a]:a,[]),y=!e||!r&&t?g:v(g,p,e,a,u),x=n?i||(r?e:d||o)?[]:s:y;if(n&&n(y,x,a,u),o)for(c=v(x,h),o(c,[],a,u),l=c.length;l--;)(f=c[l])&&(x[h[l]]=!(y[h[l]]=f));if(r){if(i||e){if(i){for(c=[],l=x.length;l--;)(f=x[l])&&c.push(y[l]=f);i(null,x=[],c,u)}for(l=x.length;l--;)(f=x[l])&&(c=i?ee(r,f):p[l])>-1&&(r[c]=!(s[c]=f))}}else x=v(x===s?x.splice(d,x.length):x),i?i(null,s,x,u):K.apply(s,x)})}function x(e){for(var t,n,r,o=e.length,i=C.relative[e[0].type],s=i||C.relative[\" \"],a=i?1:0,u=d(function(e){return e===t},s,!0),c=d(function(e){return ee(t,e)>-1},s,!0),l=[function(e,n,r){var o=!i&&(r||n!==A)||((t=n).nodeType?u(e,n,r):c(e,n,r));return t=null,o}];a<o;a++)if(n=C.relative[e[a].type])l=[d(g(l),n)];else{if(n=C.filter[e[a].type].apply(null,e[a].matches),n[$]){for(r=++a;r<o&&!C.relative[e[r].type];r++);return y(a>1&&g(l),a>1&&h(e.slice(0,a-1).concat({value:\" \"===e[a-2].type?\"*\":\"\"})).replace(ae,\"$1\"),n,a<r&&x(e.slice(a,r)),r<o&&x(e=e.slice(r)),r<o&&h(e))}l.push(n)}return g(l)}function b(e,n){var o=n.length>0,i=e.length>0,s=function(r,s,a,u,c){var l,f,p,h=0,d=\"0\",g=r&&[],m=[],y=A,x=r||i&&C.find.TAG(\"*\",c),b=B+=null==y?1:Math.random()||.1,w=x.length;for(c&&(A=s===L||s||c);d!==w&&null!=(l=x[d]);d++){if(i&&l){for(f=0,s||l.ownerDocument===L||(O(l),a=!F);p=e[f++];)if(p(l,s||L,a)){u.push(l);break}c&&(B=b)}o&&((l=!p&&l)&&h--,r&&g.push(l))}if(h+=d,o&&d!==h){for(f=0;p=n[f++];)p(g,m,s,a);if(r){if(h>0)for(;d--;)g[d]||m[d]||(m[d]=Q.call(u));m=v(m)}K.apply(u,m),c&&!r&&m.length>0&&h+n.length>1&&t.uniqueSort(u)}return c&&(B=b,A=y),g};return o?r(s):s}var w,T,C,j,k,E,S,N,A,q,D,O,L,H,F,R,I,P,M,$=\"sizzle\"+1*new Date,W=e.document,B=0,_=0,U=n(),z=n(),X=n(),V=function(e,t){return e===t&&(D=!0),0},G={}.hasOwnProperty,Y=[],Q=Y.pop,J=Y.push,K=Y.push,Z=Y.slice,ee=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},te=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",ne=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",re=\"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",oe=\"\\\\[\"+ne+\"*(\"+re+\")(?:\"+ne+\"*([*^$|!~]?=)\"+ne+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+re+\"))|)\"+ne+\"*\\\\]\",ie=\":(\"+re+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+oe+\")*)|.*)\\\\)|)\",se=new RegExp(ne+\"+\",\"g\"),ae=new RegExp(\"^\"+ne+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+ne+\"+$\",\"g\"),ue=new RegExp(\"^\"+ne+\"*,\"+ne+\"*\"),ce=new RegExp(\"^\"+ne+\"*([>+~]|\"+ne+\")\"+ne+\"*\"),le=new RegExp(\"=\"+ne+\"*([^\\\\]'\\\"]*?)\"+ne+\"*\\\\]\",\"g\"),fe=new RegExp(ie),pe=new RegExp(\"^\"+re+\"$\"),he={ID:new RegExp(\"^#(\"+re+\")\"),CLASS:new RegExp(\"^\\\\.(\"+re+\")\"),TAG:new RegExp(\"^(\"+re+\"|[*])\"),ATTR:new RegExp(\"^\"+oe),PSEUDO:new RegExp(\"^\"+ie),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+ne+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+ne+\"*(?:([+-]|)\"+ne+\"*(\\\\d+)|))\"+ne+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+te+\")$\",\"i\"),needsContext:new RegExp(\"^\"+ne+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+ne+\"*((?:-\\\\d)?\\\\d*)\"+ne+\"*\\\\)|)(?=[^-]|$)\",\"i\")},de=/^(?:input|select|textarea|button)$/i,ge=/^h\\d$/i,me=/^[^{]+\\{\\s*\\[native \\w/,ve=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ye=/[+~]/,xe=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+ne+\"?|(\"+ne+\")|.)\",\"ig\"),be=function(e,t,n){var r=\"0x\"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},we=/([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,Te=function(e,t){return t?\"\\0\"===e?\"�\":e.slice(0,-1)+\"\\\\\"+e.charCodeAt(e.length-1).toString(16)+\" \":\"\\\\\"+e},Ce=function(){O()},je=d(function(e){return e.disabled===!0&&(\"form\"in e||\"label\"in e)},{dir:\"parentNode\",next:\"legend\"});try{K.apply(Y=Z.call(W.childNodes),W.childNodes),Y[W.childNodes.length].nodeType}catch(e){K={apply:Y.length?function(e,t){J.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}T=t.support={},k=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&\"HTML\"!==t.nodeName},O=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:W;return r!==L&&9===r.nodeType&&r.documentElement?(L=r,H=L.documentElement,F=!k(L),W!==L&&(n=L.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener(\"unload\",Ce,!1):n.attachEvent&&n.attachEvent(\"onunload\",Ce)),T.attributes=o(function(e){return e.className=\"i\",!e.getAttribute(\"className\")}),T.getElementsByTagName=o(function(e){return e.appendChild(L.createComment(\"\")),!e.getElementsByTagName(\"*\").length}),T.getElementsByClassName=me.test(L.getElementsByClassName),T.getById=o(function(e){return H.appendChild(e).id=$,!L.getElementsByName||!L.getElementsByName($).length}),T.getById?(C.filter.ID=function(e){var t=e.replace(xe,be);return function(e){return e.getAttribute(\"id\")===t}},C.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&F){var n=t.getElementById(e);return n?[n]:[]}}):(C.filter.ID=function(e){var t=e.replace(xe,be);return function(e){var n=\"undefined\"!=typeof e.getAttributeNode&&e.getAttributeNode(\"id\");return n&&n.value===t}},C.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&F){var n,r,o,i=t.getElementById(e);if(i){if(n=i.getAttributeNode(\"id\"),n&&n.value===e)return[i];for(o=t.getElementsByName(e),r=0;i=o[r++];)if(n=i.getAttributeNode(\"id\"),n&&n.value===e)return[i]}return[]}}),C.find.TAG=T.getElementsByTagName?function(e,t){return\"undefined\"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):T.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],o=0,i=t.getElementsByTagName(e);if(\"*\"===e){for(;n=i[o++];)1===n.nodeType&&r.push(n);return r}return i},C.find.CLASS=T.getElementsByClassName&&function(e,t){if(\"undefined\"!=typeof t.getElementsByClassName&&F)return t.getElementsByClassName(e)},I=[],R=[],(T.qsa=me.test(L.querySelectorAll))&&(o(function(e){H.appendChild(e).innerHTML=\"<a id='\"+$+\"'></a><select id='\"+$+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",e.querySelectorAll(\"[msallowcapture^='']\").length&&R.push(\"[*^$]=\"+ne+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\"[selected]\").length||R.push(\"\\\\[\"+ne+\"*(?:value|\"+te+\")\"),e.querySelectorAll(\"[id~=\"+$+\"-]\").length||R.push(\"~=\"),e.querySelectorAll(\":checked\").length||R.push(\":checked\"),e.querySelectorAll(\"a#\"+$+\"+*\").length||R.push(\".#.+[+~]\")}),o(function(e){e.innerHTML=\"<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>\";var t=L.createElement(\"input\");t.setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),e.querySelectorAll(\"[name=d]\").length&&R.push(\"name\"+ne+\"*[*^$|!~]?=\"),2!==e.querySelectorAll(\":enabled\").length&&R.push(\":enabled\",\":disabled\"),H.appendChild(e).disabled=!0,2!==e.querySelectorAll(\":disabled\").length&&R.push(\":enabled\",\":disabled\"),e.querySelectorAll(\"*,:x\"),R.push(\",.*:\")})),(T.matchesSelector=me.test(P=H.matches||H.webkitMatchesSelector||H.mozMatchesSelector||H.oMatchesSelector||H.msMatchesSelector))&&o(function(e){T.disconnectedMatch=P.call(e,\"*\"),P.call(e,\"[s!='']:x\"),I.push(\"!=\",ie)}),R=R.length&&new RegExp(R.join(\"|\")),I=I.length&&new RegExp(I.join(\"|\")),t=me.test(H.compareDocumentPosition),M=t||me.test(H.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},V=t?function(e,t){if(e===t)return D=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!T.sortDetached&&t.compareDocumentPosition(e)===n?e===L||e.ownerDocument===W&&M(W,e)?-1:t===L||t.ownerDocument===W&&M(W,t)?1:q?ee(q,e)-ee(q,t):0:4&n?-1:1)}:function(e,t){if(e===t)return D=!0,0;var n,r=0,o=e.parentNode,i=t.parentNode,a=[e],u=[t];if(!o||!i)return e===L?-1:t===L?1:o?-1:i?1:q?ee(q,e)-ee(q,t):0;if(o===i)return s(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;a[r]===u[r];)r++;return r?s(a[r],u[r]):a[r]===W?-1:u[r]===W?1:0},L):L},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==L&&O(e),n=n.replace(le,\"='$1']\"),T.matchesSelector&&F&&!X[n+\" \"]&&(!I||!I.test(n))&&(!R||!R.test(n)))try{var r=P.call(e,n);if(r||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return t(n,L,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==L&&O(e),M(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==L&&O(e);var n=C.attrHandle[t.toLowerCase()],r=n&&G.call(C.attrHandle,t.toLowerCase())?n(e,t,!F):void 0;return void 0!==r?r:T.attributes||!F?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.escape=function(e){return(e+\"\").replace(we,Te)},t.error=function(e){throw new Error(\"Syntax error, unrecognized expression: \"+e)},t.uniqueSort=function(e){var t,n=[],r=0,o=0;if(D=!T.detectDuplicates,q=!T.sortStable&&e.slice(0),e.sort(V),D){for(;t=e[o++];)t===e[o]&&(r=n.push(o));for(;r--;)e.splice(n[r],1)}return q=null,e},j=t.getText=function(e){var t,n=\"\",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if(\"string\"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=j(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[r++];)n+=j(t);return n},C=t.selectors={cacheLength:50,createPseudo:r,match:he,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(xe,be),e[3]=(e[3]||e[4]||e[5]||\"\").replace(xe,be),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return he.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&fe.test(n)&&(t=E(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(xe,be).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=U[e+\" \"];return t||(t=new RegExp(\"(^|\"+ne+\")\"+e+\"(\"+ne+\"|$)\"))&&U(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||\"undefined\"!=typeof e.getAttribute&&e.getAttribute(\"class\")||\"\")})},ATTR:function(e,n,r){return function(o){var i=t.attr(o,e);return null==i?\"!=\"===n:!n||(i+=\"\",\"=\"===n?i===r:\"!=\"===n?i!==r:\"^=\"===n?r&&0===i.indexOf(r):\"*=\"===n?r&&i.indexOf(r)>-1:\"$=\"===n?r&&i.slice(-r.length)===r:\"~=\"===n?(\" \"+i.replace(se,\" \")+\" \").indexOf(r)>-1:\"|=\"===n&&(i===r||i.slice(0,r.length+1)===r+\"-\"))}},CHILD:function(e,t,n,r,o){var i=\"nth\"!==e.slice(0,3),s=\"last\"!==e.slice(-4),a=\"of-type\"===t;return 1===r&&0===o?function(e){return!!e.parentNode}:function(t,n,u){var c,l,f,p,h,d,g=i!==s?\"nextSibling\":\"previousSibling\",m=t.parentNode,v=a&&t.nodeName.toLowerCase(),y=!u&&!a,x=!1;if(m){if(i){for(;g;){for(p=t;p=p[g];)if(a?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;d=g=\"only\"===e&&!d&&\"nextSibling\"}return!0}if(d=[s?m.firstChild:m.lastChild],s&&y){for(p=m,f=p[$]||(p[$]={}),l=f[p.uniqueID]||(f[p.uniqueID]={}),c=l[e]||[],h=c[0]===B&&c[1],x=h&&c[2],p=h&&m.childNodes[h];p=++h&&p&&p[g]||(x=h=0)||d.pop();)if(1===p.nodeType&&++x&&p===t){l[e]=[B,h,x];break}}else if(y&&(p=t,f=p[$]||(p[$]={}),l=f[p.uniqueID]||(f[p.uniqueID]={}),c=l[e]||[],h=c[0]===B&&c[1],x=h),x===!1)for(;(p=++h&&p&&p[g]||(x=h=0)||d.pop())&&((a?p.nodeName.toLowerCase()!==v:1!==p.nodeType)||!++x||(y&&(f=p[$]||(p[$]={}),l=f[p.uniqueID]||(f[p.uniqueID]={}),l[e]=[B,x]),p!==t)););return x-=o,x===r||x%r===0&&x/r>=0}}},PSEUDO:function(e,n){var o,i=C.pseudos[e]||C.setFilters[e.toLowerCase()]||t.error(\"unsupported pseudo: \"+e);return i[$]?i(n):i.length>1?(o=[e,e,\"\",n],C.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,o=i(e,n),s=o.length;s--;)r=ee(e,o[s]),e[r]=!(t[r]=o[s])}):function(e){return i(e,0,o)}):i}},pseudos:{not:r(function(e){var t=[],n=[],o=S(e.replace(ae,\"$1\"));return o[$]?r(function(e,t,n,r){for(var i,s=o(e,null,r,[]),a=e.length;a--;)(i=s[a])&&(e[a]=!(t[a]=i))}):function(e,r,i){return t[0]=e,o(t,null,i,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){\nreturn t(e,n).length>0}}),contains:r(function(e){return e=e.replace(xe,be),function(t){return(t.textContent||t.innerText||j(t)).indexOf(e)>-1}}),lang:r(function(e){return pe.test(e||\"\")||t.error(\"unsupported lang: \"+e),e=e.replace(xe,be).toLowerCase(),function(t){var n;do if(n=F?t.lang:t.getAttribute(\"xml:lang\")||t.getAttribute(\"lang\"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+\"-\");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===H},focus:function(e){return e===L.activeElement&&(!L.hasFocus||L.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:c(!1),disabled:c(!0),checked:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&!!e.checked||\"option\"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!C.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return de.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&\"button\"===e.type||\"button\"===t},text:function(e){var t;return\"input\"===e.nodeName.toLowerCase()&&\"text\"===e.type&&(null==(t=e.getAttribute(\"type\"))||\"text\"===t.toLowerCase())},first:l(function(){return[0]}),last:l(function(e,t){return[t-1]}),eq:l(function(e,t,n){return[n<0?n+t:n]}),even:l(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:l(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:l(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:l(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},C.pseudos.nth=C.pseudos.eq;for(w in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})C.pseudos[w]=a(w);for(w in{submit:!0,reset:!0})C.pseudos[w]=u(w);return p.prototype=C.filters=C.pseudos,C.setFilters=new p,E=t.tokenize=function(e,n){var r,o,i,s,a,u,c,l=z[e+\" \"];if(l)return n?0:l.slice(0);for(a=e,u=[],c=C.preFilter;a;){r&&!(o=ue.exec(a))||(o&&(a=a.slice(o[0].length)||a),u.push(i=[])),r=!1,(o=ce.exec(a))&&(r=o.shift(),i.push({value:r,type:o[0].replace(ae,\" \")}),a=a.slice(r.length));for(s in C.filter)!(o=he[s].exec(a))||c[s]&&!(o=c[s](o))||(r=o.shift(),i.push({value:r,type:s,matches:o}),a=a.slice(r.length));if(!r)break}return n?a.length:a?t.error(e):z(e,u).slice(0)},S=t.compile=function(e,t){var n,r=[],o=[],i=X[e+\" \"];if(!i){for(t||(t=E(e)),n=t.length;n--;)i=x(t[n]),i[$]?r.push(i):o.push(i);i=X(e,b(o,r)),i.selector=e}return i},N=t.select=function(e,t,n,r){var o,i,s,a,u,c=\"function\"==typeof e&&e,l=!r&&E(e=c.selector||e);if(n=n||[],1===l.length){if(i=l[0]=l[0].slice(0),i.length>2&&\"ID\"===(s=i[0]).type&&9===t.nodeType&&F&&C.relative[i[1].type]){if(t=(C.find.ID(s.matches[0].replace(xe,be),t)||[])[0],!t)return n;c&&(t=t.parentNode),e=e.slice(i.shift().value.length)}for(o=he.needsContext.test(e)?0:i.length;o--&&(s=i[o],!C.relative[a=s.type]);)if((u=C.find[a])&&(r=u(s.matches[0].replace(xe,be),ye.test(i[0].type)&&f(t.parentNode)||t))){if(i.splice(o,1),e=r.length&&h(i),!e)return K.apply(n,r),n;break}}return(c||S(e,l))(r,t,!F,n,!t||ye.test(e)&&f(t.parentNode)||t),n},T.sortStable=$.split(\"\").sort(V).join(\"\")===$,T.detectDuplicates=!!D,O(),T.sortDetached=o(function(e){return 1&e.compareDocumentPosition(L.createElement(\"fieldset\"))}),o(function(e){return e.innerHTML=\"<a href='#'></a>\",\"#\"===e.firstChild.getAttribute(\"href\")})||i(\"type|href|height|width\",function(e,t,n){if(!n)return e.getAttribute(t,\"type\"===t.toLowerCase()?1:2)}),T.attributes&&o(function(e){return e.innerHTML=\"<input/>\",e.firstChild.setAttribute(\"value\",\"\"),\"\"===e.firstChild.getAttribute(\"value\")})||i(\"value\",function(e,t,n){if(!n&&\"input\"===e.nodeName.toLowerCase())return e.defaultValue}),o(function(e){return null==e.getAttribute(\"disabled\")})||i(te,function(e,t,n){var r;if(!n)return e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);de.find=xe,de.expr=xe.selectors,de.expr[\":\"]=de.expr.pseudos,de.uniqueSort=de.unique=xe.uniqueSort,de.text=xe.getText,de.isXMLDoc=xe.isXML,de.contains=xe.contains,de.escapeSelector=xe.escape;var be=function(e,t,n){for(var r=[],o=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(o&&de(e).is(n))break;r.push(e)}return r},we=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},Te=de.expr.match.needsContext,Ce=/^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i,je=/^.[^:#\\[\\.,]*$/;de.filter=function(e,t,n){var r=t[0];return n&&(e=\":not(\"+e+\")\"),1===t.length&&1===r.nodeType?de.find.matchesSelector(r,e)?[r]:[]:de.find.matches(e,de.grep(t,function(e){return 1===e.nodeType}))},de.fn.extend({find:function(e){var t,n,r=this.length,o=this;if(\"string\"!=typeof e)return this.pushStack(de(e).filter(function(){for(t=0;t<r;t++)if(de.contains(o[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)de.find(e,o[t],n);return r>1?de.uniqueSort(n):n},filter:function(e){return this.pushStack(o(this,e||[],!1))},not:function(e){return this.pushStack(o(this,e||[],!0))},is:function(e){return!!o(this,\"string\"==typeof e&&Te.test(e)?de(e):e||[],!1).length}});var ke,Ee=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,Se=de.fn.init=function(e,t,n){var r,o;if(!e)return this;if(n=n||ke,\"string\"==typeof e){if(r=\"<\"===e[0]&&\">\"===e[e.length-1]&&e.length>=3?[null,e,null]:Ee.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof de?t[0]:t,de.merge(this,de.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:te,!0)),Ce.test(r[1])&&de.isPlainObject(t))for(r in t)de.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return o=te.getElementById(r[2]),o&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):de.isFunction(e)?void 0!==n.ready?n.ready(e):e(de):de.makeArray(e,this)};Se.prototype=de.fn,ke=de(te);var Ne=/^(?:parents|prev(?:Until|All))/,Ae={children:!0,contents:!0,next:!0,prev:!0};de.fn.extend({has:function(e){var t=de(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(de.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,o=this.length,i=[],s=\"string\"!=typeof e&&de(e);if(!Te.test(e))for(;r<o;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(s?s.index(n)>-1:1===n.nodeType&&de.find.matchesSelector(n,e))){i.push(n);break}return this.pushStack(i.length>1?de.uniqueSort(i):i)},index:function(e){return e?\"string\"==typeof e?se.call(de(e),this[0]):se.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(de.uniqueSort(de.merge(this.get(),de(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),de.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return be(e,\"parentNode\")},parentsUntil:function(e,t,n){return be(e,\"parentNode\",n)},next:function(e){return i(e,\"nextSibling\")},prev:function(e){return i(e,\"previousSibling\")},nextAll:function(e){return be(e,\"nextSibling\")},prevAll:function(e){return be(e,\"previousSibling\")},nextUntil:function(e,t,n){return be(e,\"nextSibling\",n)},prevUntil:function(e,t,n){return be(e,\"previousSibling\",n)},siblings:function(e){return we((e.parentNode||{}).firstChild,e)},children:function(e){return we(e.firstChild)},contents:function(e){return e.contentDocument||de.merge([],e.childNodes)}},function(e,t){de.fn[e]=function(n,r){var o=de.map(this,t,n);return\"Until\"!==e.slice(-5)&&(r=n),r&&\"string\"==typeof r&&(o=de.filter(r,o)),this.length>1&&(Ae[e]||de.uniqueSort(o),Ne.test(e)&&o.reverse()),this.pushStack(o)}});var qe=/[^\\x20\\t\\r\\n\\f]+/g;de.Callbacks=function(e){e=\"string\"==typeof e?s(e):de.extend({},e);var t,n,r,o,i=[],a=[],u=-1,c=function(){for(o=e.once,r=t=!0;a.length;u=-1)for(n=a.shift();++u<i.length;)i[u].apply(n[0],n[1])===!1&&e.stopOnFalse&&(u=i.length,n=!1);e.memory||(n=!1),t=!1,o&&(i=n?[]:\"\")},l={add:function(){return i&&(n&&!t&&(u=i.length-1,a.push(n)),function t(n){de.each(n,function(n,r){de.isFunction(r)?e.unique&&l.has(r)||i.push(r):r&&r.length&&\"string\"!==de.type(r)&&t(r)})}(arguments),n&&!t&&c()),this},remove:function(){return de.each(arguments,function(e,t){for(var n;(n=de.inArray(t,i,n))>-1;)i.splice(n,1),n<=u&&u--}),this},has:function(e){return e?de.inArray(e,i)>-1:i.length>0},empty:function(){return i&&(i=[]),this},disable:function(){return o=a=[],i=n=\"\",this},disabled:function(){return!i},lock:function(){return o=a=[],n||t||(i=n=\"\"),this},locked:function(){return!!o},fireWith:function(e,n){return o||(n=n||[],n=[e,n.slice?n.slice():n],a.push(n),t||c()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l},de.extend({Deferred:function(t){var n=[[\"notify\",\"progress\",de.Callbacks(\"memory\"),de.Callbacks(\"memory\"),2],[\"resolve\",\"done\",de.Callbacks(\"once memory\"),de.Callbacks(\"once memory\"),0,\"resolved\"],[\"reject\",\"fail\",de.Callbacks(\"once memory\"),de.Callbacks(\"once memory\"),1,\"rejected\"]],r=\"pending\",o={state:function(){return r},always:function(){return i.done(arguments).fail(arguments),this},catch:function(e){return o.then(null,e)},pipe:function(){var e=arguments;return de.Deferred(function(t){de.each(n,function(n,r){var o=de.isFunction(e[r[4]])&&e[r[4]];i[r[1]](function(){var e=o&&o.apply(this,arguments);e&&de.isFunction(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+\"With\"](this,o?[e]:arguments)})}),e=null}).promise()},then:function(t,r,o){function i(t,n,r,o){return function(){var c=this,l=arguments,f=function(){var e,f;if(!(t<s)){if(e=r.apply(c,l),e===n.promise())throw new TypeError(\"Thenable self-resolution\");f=e&&(\"object\"==typeof e||\"function\"==typeof e)&&e.then,de.isFunction(f)?o?f.call(e,i(s,n,a,o),i(s,n,u,o)):(s++,f.call(e,i(s,n,a,o),i(s,n,u,o),i(s,n,a,n.notifyWith))):(r!==a&&(c=void 0,l=[e]),(o||n.resolveWith)(c,l))}},p=o?f:function(){try{f()}catch(e){de.Deferred.exceptionHook&&de.Deferred.exceptionHook(e,p.stackTrace),t+1>=s&&(r!==u&&(c=void 0,l=[e]),n.rejectWith(c,l))}};t?p():(de.Deferred.getStackHook&&(p.stackTrace=de.Deferred.getStackHook()),e.setTimeout(p))}}var s=0;return de.Deferred(function(e){n[0][3].add(i(0,e,de.isFunction(o)?o:a,e.notifyWith)),n[1][3].add(i(0,e,de.isFunction(t)?t:a)),n[2][3].add(i(0,e,de.isFunction(r)?r:u))}).promise()},promise:function(e){return null!=e?de.extend(e,o):o}},i={};return de.each(n,function(e,t){var s=t[2],a=t[5];o[t[1]]=s.add,a&&s.add(function(){r=a},n[3-e][2].disable,n[0][2].lock),s.add(t[3].fire),i[t[0]]=function(){return i[t[0]+\"With\"](this===i?void 0:this,arguments),this},i[t[0]+\"With\"]=s.fireWith}),o.promise(i),t&&t.call(i,i),i},when:function(e){var t=arguments.length,n=t,r=Array(n),o=re.call(arguments),i=de.Deferred(),s=function(e){return function(n){r[e]=this,o[e]=arguments.length>1?re.call(arguments):n,--t||i.resolveWith(r,o)}};if(t<=1&&(c(e,i.done(s(n)).resolve,i.reject),\"pending\"===i.state()||de.isFunction(o[n]&&o[n].then)))return i.then();for(;n--;)c(o[n],s(n),i.reject);return i.promise()}});var De=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;de.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&De.test(t.name)&&e.console.warn(\"jQuery.Deferred exception: \"+t.message,t.stack,n)},de.readyException=function(t){e.setTimeout(function(){throw t})};var Oe=de.Deferred();de.fn.ready=function(e){return Oe.then(e).catch(function(e){de.readyException(e)}),this},de.extend({isReady:!1,readyWait:1,holdReady:function(e){e?de.readyWait++:de.ready(!0)},ready:function(e){(e===!0?--de.readyWait:de.isReady)||(de.isReady=!0,e!==!0&&--de.readyWait>0||Oe.resolveWith(te,[de]))}}),de.ready.then=Oe.then,\"complete\"===te.readyState||\"loading\"!==te.readyState&&!te.documentElement.doScroll?e.setTimeout(de.ready):(te.addEventListener(\"DOMContentLoaded\",l),e.addEventListener(\"load\",l));var Le=function(e,t,n,r,o,i,s){var a=0,u=e.length,c=null==n;if(\"object\"===de.type(n)){o=!0;for(a in n)Le(e,t,a,n[a],!0,i,s)}else if(void 0!==r&&(o=!0,de.isFunction(r)||(s=!0),c&&(s?(t.call(e,r),t=null):(c=t,t=function(e,t,n){return c.call(de(e),n)})),t))for(;a<u;a++)t(e[a],n,s?r:r.call(e[a],a,t(e[a],n)));return o?e:c?t.call(e):u?t(e[0],n):i},He=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};f.uid=1,f.prototype={cache:function(e){var t=e[this.expando];return t||(t={},He(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,o=this.cache(e);if(\"string\"==typeof t)o[de.camelCase(t)]=n;else for(r in t)o[de.camelCase(r)]=t[r];return o},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][de.camelCase(t)]},access:function(e,t,n){return void 0===t||t&&\"string\"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){de.isArray(t)?t=t.map(de.camelCase):(t=de.camelCase(t),t=t in r?[t]:t.match(qe)||[]),n=t.length;for(;n--;)delete r[t[n]]}(void 0===t||de.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!de.isEmptyObject(t)}};var Fe=new f,Re=new f,Ie=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,Pe=/[A-Z]/g;de.extend({hasData:function(e){return Re.hasData(e)||Fe.hasData(e)},data:function(e,t,n){return Re.access(e,t,n)},removeData:function(e,t){Re.remove(e,t)},_data:function(e,t,n){return Fe.access(e,t,n)},_removeData:function(e,t){Fe.remove(e,t)}}),de.fn.extend({data:function(e,t){var n,r,o,i=this[0],s=i&&i.attributes;if(void 0===e){if(this.length&&(o=Re.get(i),1===i.nodeType&&!Fe.get(i,\"hasDataAttrs\"))){for(n=s.length;n--;)s[n]&&(r=s[n].name,0===r.indexOf(\"data-\")&&(r=de.camelCase(r.slice(5)),h(i,r,o[r])));Fe.set(i,\"hasDataAttrs\",!0)}return o}return\"object\"==typeof e?this.each(function(){Re.set(this,e)}):Le(this,function(t){var n;if(i&&void 0===t){if(n=Re.get(i,e),void 0!==n)return n;if(n=h(i,e),void 0!==n)return n}else this.each(function(){Re.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){Re.remove(this,e)})}}),de.extend({queue:function(e,t,n){var r;if(e)return t=(t||\"fx\")+\"queue\",r=Fe.get(e,t),n&&(!r||de.isArray(n)?r=Fe.access(e,t,de.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||\"fx\";var n=de.queue(e,t),r=n.length,o=n.shift(),i=de._queueHooks(e,t),s=function(){de.dequeue(e,t)};\"inprogress\"===o&&(o=n.shift(),r--),o&&(\"fx\"===t&&n.unshift(\"inprogress\"),delete i.stop,o.call(e,s,i)),!r&&i&&i.empty.fire()},_queueHooks:function(e,t){var n=t+\"queueHooks\";return Fe.get(e,n)||Fe.access(e,n,{empty:de.Callbacks(\"once memory\").add(function(){Fe.remove(e,[t+\"queue\",n])})})}}),de.fn.extend({queue:function(e,t){var n=2;return\"string\"!=typeof e&&(t=e,e=\"fx\",n--),arguments.length<n?de.queue(this[0],e):void 0===t?this:this.each(function(){var n=de.queue(this,e,t);de._queueHooks(this,e),\"fx\"===e&&\"inprogress\"!==n[0]&&de.dequeue(this,e)})},dequeue:function(e){return this.each(function(){de.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||\"fx\",[])},promise:function(e,t){var n,r=1,o=de.Deferred(),i=this,s=this.length,a=function(){--r||o.resolveWith(i,[i])};for(\"string\"!=typeof e&&(t=e,e=void 0),e=e||\"fx\";s--;)n=Fe.get(i[s],e+\"queueHooks\"),n&&n.empty&&(r++,n.empty.add(a));return a(),o.promise(t)}});var Me=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,$e=new RegExp(\"^(?:([+-])=|)(\"+Me+\")([a-z%]*)$\",\"i\"),We=[\"Top\",\"Right\",\"Bottom\",\"Left\"],Be=function(e,t){return e=t||e,\"none\"===e.style.display||\"\"===e.style.display&&de.contains(e.ownerDocument,e)&&\"none\"===de.css(e,\"display\")},_e=function(e,t,n,r){var o,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];o=n.apply(e,r||[]);for(i in t)e.style[i]=s[i];return o},Ue={};de.fn.extend({show:function(){return m(this,!0)},hide:function(){return m(this)},toggle:function(e){return\"boolean\"==typeof e?e?this.show():this.hide():this.each(function(){Be(this)?de(this).show():de(this).hide()})}});var ze=/^(?:checkbox|radio)$/i,Xe=/<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]+)/i,Ve=/^$|\\/(?:java|ecma)script/i,Ge={option:[1,\"<select multiple='multiple'>\",\"</select>\"],thead:[1,\"<table>\",\"</table>\"],col:[2,\"<table><colgroup>\",\"</colgroup></table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:[0,\"\",\"\"]};Ge.optgroup=Ge.option,Ge.tbody=Ge.tfoot=Ge.colgroup=Ge.caption=Ge.thead,Ge.th=Ge.td;var Ye=/<|&#?\\w+;/;!function(){var e=te.createDocumentFragment(),t=e.appendChild(te.createElement(\"div\")),n=te.createElement(\"input\");n.setAttribute(\"type\",\"radio\"),n.setAttribute(\"checked\",\"checked\"),n.setAttribute(\"name\",\"t\"),t.appendChild(n),pe.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML=\"<textarea>x</textarea>\",pe.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var Qe=te.documentElement,Je=/^key/,Ke=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ze=/^([^.]*)(?:\\.(.+)|)/;de.event={global:{},add:function(e,t,n,r,o){var i,s,a,u,c,l,f,p,h,d,g,m=Fe.get(e);if(m)for(n.handler&&(i=n,n=i.handler,o=i.selector),o&&de.find.matchesSelector(Qe,o),n.guid||(n.guid=de.guid++),(u=m.events)||(u=m.events={}),(s=m.handle)||(s=m.handle=function(t){return\"undefined\"!=typeof de&&de.event.triggered!==t.type?de.event.dispatch.apply(e,arguments):void 0}),t=(t||\"\").match(qe)||[\"\"],c=t.length;c--;)a=Ze.exec(t[c])||[],h=g=a[1],d=(a[2]||\"\").split(\".\").sort(),h&&(f=de.event.special[h]||{},h=(o?f.delegateType:f.bindType)||h,f=de.event.special[h]||{},l=de.extend({type:h,origType:g,data:r,handler:n,guid:n.guid,selector:o,needsContext:o&&de.expr.match.needsContext.test(o),namespace:d.join(\".\")},i),(p=u[h])||(p=u[h]=[],p.delegateCount=0,f.setup&&f.setup.call(e,r,d,s)!==!1||e.addEventListener&&e.addEventListener(h,s)),f.add&&(f.add.call(e,l),l.handler.guid||(l.handler.guid=n.guid)),o?p.splice(p.delegateCount++,0,l):p.push(l),de.event.global[h]=!0)},remove:function(e,t,n,r,o){var i,s,a,u,c,l,f,p,h,d,g,m=Fe.hasData(e)&&Fe.get(e);if(m&&(u=m.events)){for(t=(t||\"\").match(qe)||[\"\"],c=t.length;c--;)if(a=Ze.exec(t[c])||[],h=g=a[1],d=(a[2]||\"\").split(\".\").sort(),h){for(f=de.event.special[h]||{},h=(r?f.delegateType:f.bindType)||h,p=u[h]||[],a=a[2]&&new RegExp(\"(^|\\\\.)\"+d.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),s=i=p.length;i--;)l=p[i],!o&&g!==l.origType||n&&n.guid!==l.guid||a&&!a.test(l.namespace)||r&&r!==l.selector&&(\"**\"!==r||!l.selector)||(p.splice(i,1),l.selector&&p.delegateCount--,f.remove&&f.remove.call(e,l));s&&!p.length&&(f.teardown&&f.teardown.call(e,d,m.handle)!==!1||de.removeEvent(e,h,m.handle),delete u[h])}else for(h in u)de.event.remove(e,h+t[c],n,r,!0);de.isEmptyObject(u)&&Fe.remove(e,\"handle events\")}},dispatch:function(e){var t,n,r,o,i,s,a=de.event.fix(e),u=new Array(arguments.length),c=(Fe.get(this,\"events\")||{})[a.type]||[],l=de.event.special[a.type]||{};for(u[0]=a,t=1;t<arguments.length;t++)u[t]=arguments[t];if(a.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,a)!==!1){for(s=de.event.handlers.call(this,a,c),t=0;(o=s[t++])&&!a.isPropagationStopped();)for(a.currentTarget=o.elem,n=0;(i=o.handlers[n++])&&!a.isImmediatePropagationStopped();)a.rnamespace&&!a.rnamespace.test(i.namespace)||(a.handleObj=i,a.data=i.data,r=((de.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),void 0!==r&&(a.result=r)===!1&&(a.preventDefault(),a.stopPropagation()));return l.postDispatch&&l.postDispatch.call(this,a),a.result}},handlers:function(e,t){var n,r,o,i,s,a=[],u=t.delegateCount,c=e.target;if(u&&c.nodeType&&!(\"click\"===e.type&&e.button>=1))for(;c!==this;c=c.parentNode||this)if(1===c.nodeType&&(\"click\"!==e.type||c.disabled!==!0)){for(i=[],s={},n=0;n<u;n++)r=t[n],o=r.selector+\" \",void 0===s[o]&&(s[o]=r.needsContext?de(o,this).index(c)>-1:de.find(o,this,null,[c]).length),s[o]&&i.push(r);i.length&&a.push({elem:c,handlers:i})}return c=this,u<t.length&&a.push({elem:c,handlers:t.slice(u)}),a},addProp:function(e,t){Object.defineProperty(de.Event.prototype,e,{enumerable:!0,configurable:!0,get:de.isFunction(t)?function(){if(this.originalEvent)return t(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[e]},set:function(t){Object.defineProperty(this,e,{enumerable:!0,configurable:!0,writable:!0,value:t})}})},fix:function(e){return e[de.expando]?e:new de.Event(e)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==T()&&this.focus)return this.focus(),!1},delegateType:\"focusin\"},blur:{trigger:function(){if(this===T()&&this.blur)return this.blur(),!1},delegateType:\"focusout\"},click:{trigger:function(){if(\"checkbox\"===this.type&&this.click&&de.nodeName(this,\"input\"))return this.click(),!1},_default:function(e){return de.nodeName(e.target,\"a\")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},de.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},de.Event=function(e,t){return this instanceof de.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&e.returnValue===!1?b:w,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&de.extend(this,t),this.timeStamp=e&&e.timeStamp||de.now(),void(this[de.expando]=!0)):new de.Event(e,t)},de.Event.prototype={constructor:de.Event,isDefaultPrevented:w,isPropagationStopped:w,isImmediatePropagationStopped:w,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=b,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=b,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=b,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},de.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,char:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&Je.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&Ke.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},de.event.addProp),de.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(e,t){de.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,o=e.relatedTarget,i=e.handleObj;return o&&(o===r||de.contains(r,o))||(e.type=i.origType,n=i.handler.apply(this,arguments),e.type=t),n}}}),de.fn.extend({on:function(e,t,n,r){return C(this,e,t,n,r)},one:function(e,t,n,r){return C(this,e,t,n,r,1)},off:function(e,t,n){var r,o;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,de(e.delegateTarget).off(r.namespace?r.origType+\".\"+r.namespace:r.origType,r.selector,r.handler),this;if(\"object\"==typeof e){for(o in e)this.off(o,t,e[o]);return this}return t!==!1&&\"function\"!=typeof t||(n=t,t=void 0),n===!1&&(n=w),this.each(function(){de.event.remove(this,e,n,t)})}});var et=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,tt=/<script|<style|<link/i,nt=/checked\\s*(?:[^=]|=\\s*.checked.)/i,rt=/^true\\/(.*)/,ot=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;de.extend({htmlPrefilter:function(e){return e.replace(et,\"<$1></$2>\")},clone:function(e,t,n){var r,o,i,s,a=e.cloneNode(!0),u=de.contains(e.ownerDocument,e);if(!(pe.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||de.isXMLDoc(e)))for(s=v(a),i=v(e),r=0,o=i.length;r<o;r++)N(i[r],s[r]);if(t)if(n)for(i=i||v(e),s=s||v(a),r=0,o=i.length;r<o;r++)S(i[r],s[r]);else S(e,a);return s=v(a,\"script\"),s.length>0&&y(s,!u&&v(e,\"script\")),a},cleanData:function(e){for(var t,n,r,o=de.event.special,i=0;void 0!==(n=e[i]);i++)if(He(n)){if(t=n[Fe.expando]){if(t.events)for(r in t.events)o[r]?de.event.remove(n,r):de.removeEvent(n,r,t.handle);n[Fe.expando]=void 0}n[Re.expando]&&(n[Re.expando]=void 0)}}}),de.fn.extend({detach:function(e){return q(this,e,!0)},remove:function(e){return q(this,e)},text:function(e){return Le(this,function(e){return void 0===e?de.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return A(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=j(this,e);t.appendChild(e)}})},prepend:function(){return A(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=j(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return A(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return A(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(de.cleanData(v(e,!1)),e.textContent=\"\");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return de.clone(this,e,t)})},html:function(e){return Le(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if(\"string\"==typeof e&&!tt.test(e)&&!Ge[(Xe.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=de.htmlPrefilter(e);try{for(;n<r;n++)t=this[n]||{},1===t.nodeType&&(de.cleanData(v(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return A(this,arguments,function(t){var n=this.parentNode;de.inArray(this,e)<0&&(de.cleanData(v(this)),n&&n.replaceChild(t,this))},e)}}),de.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(e,t){de.fn[e]=function(e){for(var n,r=[],o=de(e),i=o.length-1,s=0;s<=i;s++)n=s===i?this:this.clone(!0),de(o[s])[t](n),ie.apply(r,n.get());return this.pushStack(r)}});var it=/^margin/,st=new RegExp(\"^(\"+Me+\")(?!px)[a-z%]+$\",\"i\"),at=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)};!function(){function t(){if(a){a.style.cssText=\"box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%\",a.innerHTML=\"\",Qe.appendChild(s);var t=e.getComputedStyle(a);n=\"1%\"!==t.top,i=\"2px\"===t.marginLeft,r=\"4px\"===t.width,a.style.marginRight=\"50%\",o=\"4px\"===t.marginRight,Qe.removeChild(s),a=null}}var n,r,o,i,s=te.createElement(\"div\"),a=te.createElement(\"div\");a.style&&(a.style.backgroundClip=\"content-box\",a.cloneNode(!0).style.backgroundClip=\"\",pe.clearCloneStyle=\"content-box\"===a.style.backgroundClip,s.style.cssText=\"border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute\",s.appendChild(a),de.extend(pe,{pixelPosition:function(){return t(),n},boxSizingReliable:function(){return t(),r},pixelMarginRight:function(){return t(),o},reliableMarginLeft:function(){return t(),i}}))}();var ut=/^(none|table(?!-c[ea]).+)/,ct={position:\"absolute\",visibility:\"hidden\",display:\"block\"},lt={letterSpacing:\"0\",fontWeight:\"400\"},ft=[\"Webkit\",\"Moz\",\"ms\"],pt=te.createElement(\"div\").style;de.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=D(e,\"opacity\");return\"\"===n?\"1\":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{float:\"cssFloat\"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,i,s,a=de.camelCase(t),u=e.style;return t=de.cssProps[a]||(de.cssProps[a]=L(a)||a),s=de.cssHooks[t]||de.cssHooks[a],void 0===n?s&&\"get\"in s&&void 0!==(o=s.get(e,!1,r))?o:u[t]:(i=typeof n,\"string\"===i&&(o=$e.exec(n))&&o[1]&&(n=d(e,t,o),i=\"number\"),null!=n&&n===n&&(\"number\"===i&&(n+=o&&o[3]||(de.cssNumber[a]?\"\":\"px\")),pe.clearCloneStyle||\"\"!==n||0!==t.indexOf(\"background\")||(u[t]=\"inherit\"),s&&\"set\"in s&&void 0===(n=s.set(e,n,r))||(u[t]=n)),void 0)}},css:function(e,t,n,r){var o,i,s,a=de.camelCase(t);return t=de.cssProps[a]||(de.cssProps[a]=L(a)||a),s=de.cssHooks[t]||de.cssHooks[a],s&&\"get\"in s&&(o=s.get(e,!0,n)),void 0===o&&(o=D(e,t,r)),\"normal\"===o&&t in lt&&(o=lt[t]),\"\"===n||n?(i=parseFloat(o),n===!0||isFinite(i)?i||0:o):o}}),de.each([\"height\",\"width\"],function(e,t){de.cssHooks[t]={get:function(e,n,r){if(n)return!ut.test(de.css(e,\"display\"))||e.getClientRects().length&&e.getBoundingClientRect().width?R(e,t,r):_e(e,ct,function(){return R(e,t,r)})},set:function(e,n,r){var o,i=r&&at(e),s=r&&F(e,t,r,\"border-box\"===de.css(e,\"boxSizing\",!1,i),i);return s&&(o=$e.exec(n))&&\"px\"!==(o[3]||\"px\")&&(e.style[t]=n,n=de.css(e,t)),H(e,n,s)}}}),de.cssHooks.marginLeft=O(pe.reliableMarginLeft,function(e,t){if(t)return(parseFloat(D(e,\"marginLeft\"))||e.getBoundingClientRect().left-_e(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+\"px\"}),de.each({margin:\"\",padding:\"\",border:\"Width\"},function(e,t){de.cssHooks[e+t]={expand:function(n){for(var r=0,o={},i=\"string\"==typeof n?n.split(\" \"):[n];r<4;r++)o[e+We[r]+t]=i[r]||i[r-2]||i[0];return o}},it.test(e)||(de.cssHooks[e+t].set=H)}),de.fn.extend({css:function(e,t){return Le(this,function(e,t,n){var r,o,i={},s=0;if(de.isArray(t)){for(r=at(e),o=t.length;s<o;s++)i[t[s]]=de.css(e,t[s],!1,r);return i}return void 0!==n?de.style(e,t,n):de.css(e,t)},e,t,arguments.length>1)}}),de.Tween=I,I.prototype={constructor:I,init:function(e,t,n,r,o,i){this.elem=e,this.prop=n,this.easing=o||de.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=i||(de.cssNumber[n]?\"\":\"px\")},cur:function(){var e=I.propHooks[this.prop];return e&&e.get?e.get(this):I.propHooks._default.get(this)},run:function(e){var t,n=I.propHooks[this.prop];return this.options.duration?this.pos=t=de.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):I.propHooks._default.set(this),this}},I.prototype.init.prototype=I.prototype,I.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=de.css(e.elem,e.prop,\"\"),t&&\"auto\"!==t?t:0)},set:function(e){de.fx.step[e.prop]?de.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[de.cssProps[e.prop]]&&!de.cssHooks[e.prop]?e.elem[e.prop]=e.now:de.style(e.elem,e.prop,e.now+e.unit)}}},I.propHooks.scrollTop=I.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},de.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:\"swing\"},de.fx=I.prototype.init,de.fx.step={};var ht,dt,gt=/^(?:toggle|show|hide)$/,mt=/queueHooks$/;de.Animation=de.extend(U,{tweeners:{\"*\":[function(e,t){var n=this.createTween(e,t);return d(n.elem,e,$e.exec(t),n),n}]},tweener:function(e,t){de.isFunction(e)?(t=e,e=[\"*\"]):e=e.match(qe);for(var n,r=0,o=e.length;r<o;r++)n=e[r],U.tweeners[n]=U.tweeners[n]||[],U.tweeners[n].unshift(t)},prefilters:[B],prefilter:function(e,t){t?U.prefilters.unshift(e):U.prefilters.push(e)}}),de.speed=function(e,t,n){var r=e&&\"object\"==typeof e?de.extend({},e):{complete:n||!n&&t||de.isFunction(e)&&e,duration:e,easing:n&&t||t&&!de.isFunction(t)&&t};return de.fx.off||te.hidden?r.duration=0:\"number\"!=typeof r.duration&&(r.duration in de.fx.speeds?r.duration=de.fx.speeds[r.duration]:r.duration=de.fx.speeds._default),null!=r.queue&&r.queue!==!0||(r.queue=\"fx\"),r.old=r.complete,r.complete=function(){de.isFunction(r.old)&&r.old.call(this),r.queue&&de.dequeue(this,r.queue)},r},de.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Be).css(\"opacity\",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){\nvar o=de.isEmptyObject(e),i=de.speed(t,n,r),s=function(){var t=U(this,de.extend({},e),i);(o||Fe.get(this,\"finish\"))&&t.stop(!0)};return s.finish=s,o||i.queue===!1?this.each(s):this.queue(i.queue,s)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return\"string\"!=typeof e&&(n=t,t=e,e=void 0),t&&e!==!1&&this.queue(e||\"fx\",[]),this.each(function(){var t=!0,o=null!=e&&e+\"queueHooks\",i=de.timers,s=Fe.get(this);if(o)s[o]&&s[o].stop&&r(s[o]);else for(o in s)s[o]&&s[o].stop&&mt.test(o)&&r(s[o]);for(o=i.length;o--;)i[o].elem!==this||null!=e&&i[o].queue!==e||(i[o].anim.stop(n),t=!1,i.splice(o,1));!t&&n||de.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||\"fx\"),this.each(function(){var t,n=Fe.get(this),r=n[e+\"queue\"],o=n[e+\"queueHooks\"],i=de.timers,s=r?r.length:0;for(n.finish=!0,de.queue(this,e,[]),o&&o.stop&&o.stop.call(this,!0),t=i.length;t--;)i[t].elem===this&&i[t].queue===e&&(i[t].anim.stop(!0),i.splice(t,1));for(t=0;t<s;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),de.each([\"toggle\",\"show\",\"hide\"],function(e,t){var n=de.fn[t];de.fn[t]=function(e,r,o){return null==e||\"boolean\"==typeof e?n.apply(this,arguments):this.animate($(t,!0),e,r,o)}}),de.each({slideDown:$(\"show\"),slideUp:$(\"hide\"),slideToggle:$(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(e,t){de.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),de.timers=[],de.fx.tick=function(){var e,t=0,n=de.timers;for(ht=de.now();t<n.length;t++)e=n[t],e()||n[t]!==e||n.splice(t--,1);n.length||de.fx.stop(),ht=void 0},de.fx.timer=function(e){de.timers.push(e),e()?de.fx.start():de.timers.pop()},de.fx.interval=13,de.fx.start=function(){dt||(dt=e.requestAnimationFrame?e.requestAnimationFrame(P):e.setInterval(de.fx.tick,de.fx.interval))},de.fx.stop=function(){e.cancelAnimationFrame?e.cancelAnimationFrame(dt):e.clearInterval(dt),dt=null},de.fx.speeds={slow:600,fast:200,_default:400},de.fn.delay=function(t,n){return t=de.fx?de.fx.speeds[t]||t:t,n=n||\"fx\",this.queue(n,function(n,r){var o=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(o)}})},function(){var e=te.createElement(\"input\"),t=te.createElement(\"select\"),n=t.appendChild(te.createElement(\"option\"));e.type=\"checkbox\",pe.checkOn=\"\"!==e.value,pe.optSelected=n.selected,e=te.createElement(\"input\"),e.value=\"t\",e.type=\"radio\",pe.radioValue=\"t\"===e.value}();var vt,yt=de.expr.attrHandle;de.fn.extend({attr:function(e,t){return Le(this,de.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){de.removeAttr(this,e)})}}),de.extend({attr:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return\"undefined\"==typeof e.getAttribute?de.prop(e,t,n):(1===i&&de.isXMLDoc(e)||(o=de.attrHooks[t.toLowerCase()]||(de.expr.match.bool.test(t)?vt:void 0)),void 0!==n?null===n?void de.removeAttr(e,t):o&&\"set\"in o&&void 0!==(r=o.set(e,n,t))?r:(e.setAttribute(t,n+\"\"),n):o&&\"get\"in o&&null!==(r=o.get(e,t))?r:(r=de.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!pe.radioValue&&\"radio\"===t&&de.nodeName(e,\"input\")){var n=e.value;return e.setAttribute(\"type\",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,o=t&&t.match(qe);if(o&&1===e.nodeType)for(;n=o[r++];)e.removeAttribute(n)}}),vt={set:function(e,t,n){return t===!1?de.removeAttr(e,n):e.setAttribute(n,n),n}},de.each(de.expr.match.bool.source.match(/\\w+/g),function(e,t){var n=yt[t]||de.find.attr;yt[t]=function(e,t,r){var o,i,s=t.toLowerCase();return r||(i=yt[s],yt[s]=o,o=null!=n(e,t,r)?s:null,yt[s]=i),o}});var xt=/^(?:input|select|textarea|button)$/i,bt=/^(?:a|area)$/i;de.fn.extend({prop:function(e,t){return Le(this,de.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[de.propFix[e]||e]})}}),de.extend({prop:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return 1===i&&de.isXMLDoc(e)||(t=de.propFix[t]||t,o=de.propHooks[t]),void 0!==n?o&&\"set\"in o&&void 0!==(r=o.set(e,n,t))?r:e[t]=n:o&&\"get\"in o&&null!==(r=o.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=de.find.attr(e,\"tabindex\");return t?parseInt(t,10):xt.test(e.nodeName)||bt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:\"htmlFor\",class:\"className\"}}),pe.optSelected||(de.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),de.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){de.propFix[this.toLowerCase()]=this}),de.fn.extend({addClass:function(e){var t,n,r,o,i,s,a,u=0;if(de.isFunction(e))return this.each(function(t){de(this).addClass(e.call(this,t,X(this)))});if(\"string\"==typeof e&&e)for(t=e.match(qe)||[];n=this[u++];)if(o=X(n),r=1===n.nodeType&&\" \"+z(o)+\" \"){for(s=0;i=t[s++];)r.indexOf(\" \"+i+\" \")<0&&(r+=i+\" \");a=z(r),o!==a&&n.setAttribute(\"class\",a)}return this},removeClass:function(e){var t,n,r,o,i,s,a,u=0;if(de.isFunction(e))return this.each(function(t){de(this).removeClass(e.call(this,t,X(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if(\"string\"==typeof e&&e)for(t=e.match(qe)||[];n=this[u++];)if(o=X(n),r=1===n.nodeType&&\" \"+z(o)+\" \"){for(s=0;i=t[s++];)for(;r.indexOf(\" \"+i+\" \")>-1;)r=r.replace(\" \"+i+\" \",\" \");a=z(r),o!==a&&n.setAttribute(\"class\",a)}return this},toggleClass:function(e,t){var n=typeof e;return\"boolean\"==typeof t&&\"string\"===n?t?this.addClass(e):this.removeClass(e):de.isFunction(e)?this.each(function(n){de(this).toggleClass(e.call(this,n,X(this),t),t)}):this.each(function(){var t,r,o,i;if(\"string\"===n)for(r=0,o=de(this),i=e.match(qe)||[];t=i[r++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&\"boolean\"!==n||(t=X(this),t&&Fe.set(this,\"__className__\",t),this.setAttribute&&this.setAttribute(\"class\",t||e===!1?\"\":Fe.get(this,\"__className__\")||\"\"))})},hasClass:function(e){var t,n,r=0;for(t=\" \"+e+\" \";n=this[r++];)if(1===n.nodeType&&(\" \"+z(X(n))+\" \").indexOf(t)>-1)return!0;return!1}});var wt=/\\r/g;de.fn.extend({val:function(e){var t,n,r,o=this[0];{if(arguments.length)return r=de.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=r?e.call(this,n,de(this).val()):e,null==o?o=\"\":\"number\"==typeof o?o+=\"\":de.isArray(o)&&(o=de.map(o,function(e){return null==e?\"\":e+\"\"})),t=de.valHooks[this.type]||de.valHooks[this.nodeName.toLowerCase()],t&&\"set\"in t&&void 0!==t.set(this,o,\"value\")||(this.value=o))});if(o)return t=de.valHooks[o.type]||de.valHooks[o.nodeName.toLowerCase()],t&&\"get\"in t&&void 0!==(n=t.get(o,\"value\"))?n:(n=o.value,\"string\"==typeof n?n.replace(wt,\"\"):null==n?\"\":n)}}}),de.extend({valHooks:{option:{get:function(e){var t=de.find.attr(e,\"value\");return null!=t?t:z(de.text(e))}},select:{get:function(e){var t,n,r,o=e.options,i=e.selectedIndex,s=\"select-one\"===e.type,a=s?null:[],u=s?i+1:o.length;for(r=i<0?u:s?i:0;r<u;r++)if(n=o[r],(n.selected||r===i)&&!n.disabled&&(!n.parentNode.disabled||!de.nodeName(n.parentNode,\"optgroup\"))){if(t=de(n).val(),s)return t;a.push(t)}return a},set:function(e,t){for(var n,r,o=e.options,i=de.makeArray(t),s=o.length;s--;)r=o[s],(r.selected=de.inArray(de.valHooks.option.get(r),i)>-1)&&(n=!0);return n||(e.selectedIndex=-1),i}}}}),de.each([\"radio\",\"checkbox\"],function(){de.valHooks[this]={set:function(e,t){if(de.isArray(t))return e.checked=de.inArray(de(e).val(),t)>-1}},pe.checkOn||(de.valHooks[this].get=function(e){return null===e.getAttribute(\"value\")?\"on\":e.value})});var Tt=/^(?:focusinfocus|focusoutblur)$/;de.extend(de.event,{trigger:function(t,n,r,o){var i,s,a,u,c,l,f,p=[r||te],h=ce.call(t,\"type\")?t.type:t,d=ce.call(t,\"namespace\")?t.namespace.split(\".\"):[];if(s=a=r=r||te,3!==r.nodeType&&8!==r.nodeType&&!Tt.test(h+de.event.triggered)&&(h.indexOf(\".\")>-1&&(d=h.split(\".\"),h=d.shift(),d.sort()),c=h.indexOf(\":\")<0&&\"on\"+h,t=t[de.expando]?t:new de.Event(h,\"object\"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=d.join(\".\"),t.rnamespace=t.namespace?new RegExp(\"(^|\\\\.)\"+d.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:de.makeArray(n,[t]),f=de.event.special[h]||{},o||!f.trigger||f.trigger.apply(r,n)!==!1)){if(!o&&!f.noBubble&&!de.isWindow(r)){for(u=f.delegateType||h,Tt.test(u+h)||(s=s.parentNode);s;s=s.parentNode)p.push(s),a=s;a===(r.ownerDocument||te)&&p.push(a.defaultView||a.parentWindow||e)}for(i=0;(s=p[i++])&&!t.isPropagationStopped();)t.type=i>1?u:f.bindType||h,l=(Fe.get(s,\"events\")||{})[t.type]&&Fe.get(s,\"handle\"),l&&l.apply(s,n),l=c&&s[c],l&&l.apply&&He(s)&&(t.result=l.apply(s,n),t.result===!1&&t.preventDefault());return t.type=h,o||t.isDefaultPrevented()||f._default&&f._default.apply(p.pop(),n)!==!1||!He(r)||c&&de.isFunction(r[h])&&!de.isWindow(r)&&(a=r[c],a&&(r[c]=null),de.event.triggered=h,r[h](),de.event.triggered=void 0,a&&(r[c]=a)),t.result}},simulate:function(e,t,n){var r=de.extend(new de.Event,n,{type:e,isSimulated:!0});de.event.trigger(r,null,t)}}),de.fn.extend({trigger:function(e,t){return this.each(function(){de.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return de.event.trigger(e,t,n,!0)}}),de.each(\"blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu\".split(\" \"),function(e,t){de.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),de.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),pe.focusin=\"onfocusin\"in e,pe.focusin||de.each({focus:\"focusin\",blur:\"focusout\"},function(e,t){var n=function(e){de.event.simulate(t,e.target,de.event.fix(e))};de.event.special[t]={setup:function(){var r=this.ownerDocument||this,o=Fe.access(r,t);o||r.addEventListener(e,n,!0),Fe.access(r,t,(o||0)+1)},teardown:function(){var r=this.ownerDocument||this,o=Fe.access(r,t)-1;o?Fe.access(r,t,o):(r.removeEventListener(e,n,!0),Fe.remove(r,t))}}});var Ct=e.location,jt=de.now(),kt=/\\?/;de.parseXML=function(t){var n;if(!t||\"string\"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,\"text/xml\")}catch(e){n=void 0}return n&&!n.getElementsByTagName(\"parsererror\").length||de.error(\"Invalid XML: \"+t),n};var Et=/\\[\\]$/,St=/\\r?\\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;de.param=function(e,t){var n,r=[],o=function(e,t){var n=de.isFunction(t)?t():t;r[r.length]=encodeURIComponent(e)+\"=\"+encodeURIComponent(null==n?\"\":n)};if(de.isArray(e)||e.jquery&&!de.isPlainObject(e))de.each(e,function(){o(this.name,this.value)});else for(n in e)V(n,e[n],t,o);return r.join(\"&\")},de.fn.extend({serialize:function(){return de.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=de.prop(this,\"elements\");return e?de.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!de(this).is(\":disabled\")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!ze.test(e))}).map(function(e,t){var n=de(this).val();return null==n?null:de.isArray(n)?de.map(n,function(e){return{name:t.name,value:e.replace(St,\"\\r\\n\")}}):{name:t.name,value:n.replace(St,\"\\r\\n\")}}).get()}});var qt=/%20/g,Dt=/#.*$/,Ot=/([?&])_=[^&]*/,Lt=/^(.*?):[ \\t]*([^\\r\\n]*)$/gm,Ht=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ft=/^(?:GET|HEAD)$/,Rt=/^\\/\\//,It={},Pt={},Mt=\"*/\".concat(\"*\"),$t=te.createElement(\"a\");$t.href=Ct.href,de.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:\"GET\",isLocal:Ht.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Mt,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":JSON.parse,\"text xml\":de.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Q(Q(e,de.ajaxSettings),t):Q(de.ajaxSettings,e)},ajaxPrefilter:G(It),ajaxTransport:G(Pt),ajax:function(t,n){function r(t,n,r,a){var c,p,h,b,w,T=n;l||(l=!0,u&&e.clearTimeout(u),o=void 0,s=a||\"\",C.readyState=t>0?4:0,c=t>=200&&t<300||304===t,r&&(b=J(d,C,r)),b=K(d,b,C,c),c?(d.ifModified&&(w=C.getResponseHeader(\"Last-Modified\"),w&&(de.lastModified[i]=w),w=C.getResponseHeader(\"etag\"),w&&(de.etag[i]=w)),204===t||\"HEAD\"===d.type?T=\"nocontent\":304===t?T=\"notmodified\":(T=b.state,p=b.data,h=b.error,c=!h)):(h=T,!t&&T||(T=\"error\",t<0&&(t=0))),C.status=t,C.statusText=(n||T)+\"\",c?v.resolveWith(g,[p,T,C]):v.rejectWith(g,[C,T,h]),C.statusCode(x),x=void 0,f&&m.trigger(c?\"ajaxSuccess\":\"ajaxError\",[C,d,c?p:h]),y.fireWith(g,[C,T]),f&&(m.trigger(\"ajaxComplete\",[C,d]),--de.active||de.event.trigger(\"ajaxStop\")))}\"object\"==typeof t&&(n=t,t=void 0),n=n||{};var o,i,s,a,u,c,l,f,p,h,d=de.ajaxSetup({},n),g=d.context||d,m=d.context&&(g.nodeType||g.jquery)?de(g):de.event,v=de.Deferred(),y=de.Callbacks(\"once memory\"),x=d.statusCode||{},b={},w={},T=\"canceled\",C={readyState:0,getResponseHeader:function(e){var t;if(l){if(!a)for(a={};t=Lt.exec(s);)a[t[1].toLowerCase()]=t[2];t=a[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return l?s:null},setRequestHeader:function(e,t){return null==l&&(e=w[e.toLowerCase()]=w[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==l&&(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(l)C.always(e[C.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||T;return o&&o.abort(t),r(0,t),this}};if(v.promise(C),d.url=((t||d.url||Ct.href)+\"\").replace(Rt,Ct.protocol+\"//\"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=(d.dataType||\"*\").toLowerCase().match(qe)||[\"\"],null==d.crossDomain){c=te.createElement(\"a\");try{c.href=d.url,c.href=c.href,d.crossDomain=$t.protocol+\"//\"+$t.host!=c.protocol+\"//\"+c.host}catch(e){d.crossDomain=!0}}if(d.data&&d.processData&&\"string\"!=typeof d.data&&(d.data=de.param(d.data,d.traditional)),Y(It,d,n,C),l)return C;f=de.event&&d.global,f&&0===de.active++&&de.event.trigger(\"ajaxStart\"),d.type=d.type.toUpperCase(),d.hasContent=!Ft.test(d.type),i=d.url.replace(Dt,\"\"),d.hasContent?d.data&&d.processData&&0===(d.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&(d.data=d.data.replace(qt,\"+\")):(h=d.url.slice(i.length),d.data&&(i+=(kt.test(i)?\"&\":\"?\")+d.data,delete d.data),d.cache===!1&&(i=i.replace(Ot,\"$1\"),h=(kt.test(i)?\"&\":\"?\")+\"_=\"+jt++ +h),d.url=i+h),d.ifModified&&(de.lastModified[i]&&C.setRequestHeader(\"If-Modified-Since\",de.lastModified[i]),de.etag[i]&&C.setRequestHeader(\"If-None-Match\",de.etag[i])),(d.data&&d.hasContent&&d.contentType!==!1||n.contentType)&&C.setRequestHeader(\"Content-Type\",d.contentType),C.setRequestHeader(\"Accept\",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(\"*\"!==d.dataTypes[0]?\", \"+Mt+\"; q=0.01\":\"\"):d.accepts[\"*\"]);for(p in d.headers)C.setRequestHeader(p,d.headers[p]);if(d.beforeSend&&(d.beforeSend.call(g,C,d)===!1||l))return C.abort();if(T=\"abort\",y.add(d.complete),C.done(d.success),C.fail(d.error),o=Y(Pt,d,n,C)){if(C.readyState=1,f&&m.trigger(\"ajaxSend\",[C,d]),l)return C;d.async&&d.timeout>0&&(u=e.setTimeout(function(){C.abort(\"timeout\")},d.timeout));try{l=!1,o.send(b,r)}catch(e){if(l)throw e;r(-1,e)}}else r(-1,\"No Transport\");return C},getJSON:function(e,t,n){return de.get(e,t,n,\"json\")},getScript:function(e,t){return de.get(e,void 0,t,\"script\")}}),de.each([\"get\",\"post\"],function(e,t){de[t]=function(e,n,r,o){return de.isFunction(n)&&(o=o||r,r=n,n=void 0),de.ajax(de.extend({url:e,type:t,dataType:o,data:n,success:r},de.isPlainObject(e)&&e))}}),de._evalUrl=function(e){return de.ajax({url:e,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,throws:!0})},de.fn.extend({wrapAll:function(e){var t;return this[0]&&(de.isFunction(e)&&(e=e.call(this[0])),t=de(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return de.isFunction(e)?this.each(function(t){de(this).wrapInner(e.call(this,t))}):this.each(function(){var t=de(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=de.isFunction(e);return this.each(function(n){de(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not(\"body\").each(function(){de(this).replaceWith(this.childNodes)}),this}}),de.expr.pseudos.hidden=function(e){return!de.expr.pseudos.visible(e)},de.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},de.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Wt={0:200,1223:204},Bt=de.ajaxSettings.xhr();pe.cors=!!Bt&&\"withCredentials\"in Bt,pe.ajax=Bt=!!Bt,de.ajaxTransport(function(t){var n,r;if(pe.cors||Bt&&!t.crossDomain)return{send:function(o,i){var s,a=t.xhr();if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(s in t.xhrFields)a[s]=t.xhrFields[s];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||o[\"X-Requested-With\"]||(o[\"X-Requested-With\"]=\"XMLHttpRequest\");for(s in o)a.setRequestHeader(s,o[s]);n=function(e){return function(){n&&(n=r=a.onload=a.onerror=a.onabort=a.onreadystatechange=null,\"abort\"===e?a.abort():\"error\"===e?\"number\"!=typeof a.status?i(0,\"error\"):i(a.status,a.statusText):i(Wt[a.status]||a.status,a.statusText,\"text\"!==(a.responseType||\"text\")||\"string\"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=n(),r=a.onerror=n(\"error\"),void 0!==a.onabort?a.onabort=r:a.onreadystatechange=function(){4===a.readyState&&e.setTimeout(function(){n&&r()})},n=n(\"abort\");try{a.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),de.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),de.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(e){return de.globalEval(e),e}}}),de.ajaxPrefilter(\"script\",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type=\"GET\")}),de.ajaxTransport(\"script\",function(e){if(e.crossDomain){var t,n;return{send:function(r,o){t=de(\"<script>\").prop({charset:e.scriptCharset,src:e.url}).on(\"load error\",n=function(e){t.remove(),n=null,e&&o(\"error\"===e.type?404:200,e.type)}),te.head.appendChild(t[0])},abort:function(){n&&n()}}}});var _t=[],Ut=/(=)\\?(?=&|$)|\\?\\?/;de.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var e=_t.pop()||de.expando+\"_\"+jt++;return this[e]=!0,e}}),de.ajaxPrefilter(\"json jsonp\",function(t,n,r){var o,i,s,a=t.jsonp!==!1&&(Ut.test(t.url)?\"url\":\"string\"==typeof t.data&&0===(t.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&Ut.test(t.data)&&\"data\");if(a||\"jsonp\"===t.dataTypes[0])return o=t.jsonpCallback=de.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,a?t[a]=t[a].replace(Ut,\"$1\"+o):t.jsonp!==!1&&(t.url+=(kt.test(t.url)?\"&\":\"?\")+t.jsonp+\"=\"+o),t.converters[\"script json\"]=function(){return s||de.error(o+\" was not called\"),s[0]},t.dataTypes[0]=\"json\",i=e[o],e[o]=function(){s=arguments},r.always(function(){void 0===i?de(e).removeProp(o):e[o]=i,t[o]&&(t.jsonpCallback=n.jsonpCallback,_t.push(o)),s&&de.isFunction(i)&&i(s[0]),s=i=void 0}),\"script\"}),pe.createHTMLDocument=function(){var e=te.implementation.createHTMLDocument(\"\").body;return e.innerHTML=\"<form></form><form></form>\",2===e.childNodes.length}(),de.parseHTML=function(e,t,n){if(\"string\"!=typeof e)return[];\"boolean\"==typeof t&&(n=t,t=!1);var r,o,i;return t||(pe.createHTMLDocument?(t=te.implementation.createHTMLDocument(\"\"),r=t.createElement(\"base\"),r.href=te.location.href,t.head.appendChild(r)):t=te),o=Ce.exec(e),i=!n&&[],o?[t.createElement(o[1])]:(o=x([e],t,i),i&&i.length&&de(i).remove(),de.merge([],o.childNodes))},de.fn.load=function(e,t,n){var r,o,i,s=this,a=e.indexOf(\" \");return a>-1&&(r=z(e.slice(a)),e=e.slice(0,a)),de.isFunction(t)?(n=t,t=void 0):t&&\"object\"==typeof t&&(o=\"POST\"),s.length>0&&de.ajax({url:e,type:o||\"GET\",dataType:\"html\",data:t}).done(function(e){i=arguments,s.html(r?de(\"<div>\").append(de.parseHTML(e)).find(r):e)}).always(n&&function(e,t){s.each(function(){n.apply(this,i||[e.responseText,t,e])})}),this},de.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(e,t){de.fn[t]=function(e){return this.on(t,e)}}),de.expr.pseudos.animated=function(e){return de.grep(de.timers,function(t){return e===t.elem}).length},de.offset={setOffset:function(e,t,n){var r,o,i,s,a,u,c,l=de.css(e,\"position\"),f=de(e),p={};\"static\"===l&&(e.style.position=\"relative\"),a=f.offset(),i=de.css(e,\"top\"),u=de.css(e,\"left\"),c=(\"absolute\"===l||\"fixed\"===l)&&(i+u).indexOf(\"auto\")>-1,c?(r=f.position(),s=r.top,o=r.left):(s=parseFloat(i)||0,o=parseFloat(u)||0),de.isFunction(t)&&(t=t.call(e,n,de.extend({},a))),null!=t.top&&(p.top=t.top-a.top+s),null!=t.left&&(p.left=t.left-a.left+o),\"using\"in t?t.using.call(e,p):f.css(p)}},de.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){de.offset.setOffset(this,e,t)});var t,n,r,o,i=this[0];if(i)return i.getClientRects().length?(r=i.getBoundingClientRect(),r.width||r.height?(o=i.ownerDocument,n=Z(o),t=o.documentElement,{top:r.top+n.pageYOffset-t.clientTop,left:r.left+n.pageXOffset-t.clientLeft}):r):{top:0,left:0}},position:function(){if(this[0]){var e,t,n=this[0],r={top:0,left:0};return\"fixed\"===de.css(n,\"position\")?t=n.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),de.nodeName(e[0],\"html\")||(r=e.offset()),r={top:r.top+de.css(e[0],\"borderTopWidth\",!0),left:r.left+de.css(e[0],\"borderLeftWidth\",!0)}),{top:t.top-r.top-de.css(n,\"marginTop\",!0),left:t.left-r.left-de.css(n,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&\"static\"===de.css(e,\"position\");)e=e.offsetParent;return e||Qe})}}),de.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(e,t){var n=\"pageYOffset\"===t;de.fn[e]=function(r){return Le(this,function(e,r,o){var i=Z(e);return void 0===o?i?i[t]:e[r]:void(i?i.scrollTo(n?i.pageXOffset:o,n?o:i.pageYOffset):e[r]=o)},e,r,arguments.length)}}),de.each([\"top\",\"left\"],function(e,t){de.cssHooks[t]=O(pe.pixelPosition,function(e,n){if(n)return n=D(e,t),st.test(n)?de(e).position()[t]+\"px\":n})}),de.each({Height:\"height\",Width:\"width\"},function(e,t){de.each({padding:\"inner\"+e,content:t,\"\":\"outer\"+e},function(n,r){de.fn[r]=function(o,i){var s=arguments.length&&(n||\"boolean\"!=typeof o),a=n||(o===!0||i===!0?\"margin\":\"border\");return Le(this,function(t,n,o){var i;return de.isWindow(t)?0===r.indexOf(\"outer\")?t[\"inner\"+e]:t.document.documentElement[\"client\"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body[\"scroll\"+e],i[\"scroll\"+e],t.body[\"offset\"+e],i[\"offset\"+e],i[\"client\"+e])):void 0===o?de.css(t,n,a):de.style(t,n,o,a)},t,s?o:void 0,s)}})}),de.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)}}),de.parseJSON=JSON.parse,\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return de});var zt=e.jQuery,Xt=e.$;return de.noConflict=function(t){return e.$===de&&(e.$=Xt),t&&e.jQuery===de&&(e.jQuery=zt),de},t||(e.jQuery=e.$=de),de})},{}],2:[function(e,t,n){(function(e){function t(e,t){for(var n=0,r=e.length-1;r>=0;r--){var o=e[r];\".\"===o?e.splice(r,1):\"..\"===o?(e.splice(r,1),n++):n&&(e.splice(r,1),n--)}if(t)for(;n--;n)e.unshift(\"..\");return e}function r(e,t){if(e.filter)return e.filter(t);for(var n=[],r=0;r<e.length;r++)t(e[r],r,e)&&n.push(e[r]);return n}var o=/^(\\/?|)([\\s\\S]*?)((?:\\.{1,2}|[^\\/]+?|)(\\.[^.\\/]*|))(?:[\\/]*)$/,i=function(e){return o.exec(e).slice(1)};n.resolve=function(){for(var n=\"\",o=!1,i=arguments.length-1;i>=-1&&!o;i--){var s=i>=0?arguments[i]:e.cwd();if(\"string\"!=typeof s)throw new TypeError(\"Arguments to path.resolve must be strings\");s&&(n=s+\"/\"+n,o=\"/\"===s.charAt(0))}return n=t(r(n.split(\"/\"),function(e){return!!e}),!o).join(\"/\"),(o?\"/\":\"\")+n||\".\"},n.normalize=function(e){var o=n.isAbsolute(e),i=\"/\"===s(e,-1);return e=t(r(e.split(\"/\"),function(e){return!!e}),!o).join(\"/\"),e||o||(e=\".\"),e&&i&&(e+=\"/\"),(o?\"/\":\"\")+e},n.isAbsolute=function(e){return\"/\"===e.charAt(0)},n.join=function(){var e=Array.prototype.slice.call(arguments,0);return n.normalize(r(e,function(e,t){if(\"string\"!=typeof e)throw new TypeError(\"Arguments to path.join must be strings\");return e}).join(\"/\"))},n.relative=function(e,t){function r(e){for(var t=0;t<e.length&&\"\"===e[t];t++);for(var n=e.length-1;n>=0&&\"\"===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=n.resolve(e).substr(1),t=n.resolve(t).substr(1);for(var o=r(e.split(\"/\")),i=r(t.split(\"/\")),s=Math.min(o.length,i.length),a=s,u=0;u<s;u++)if(o[u]!==i[u]){a=u;break}for(var c=[],u=a;u<o.length;u++)c.push(\"..\");return c=c.concat(i.slice(a)),c.join(\"/\")},n.sep=\"/\",n.delimiter=\":\",n.dirname=function(e){var t=i(e),n=t[0],r=t[1];return n||r?(r&&(r=r.substr(0,r.length-1)),n+r):\".\"},n.basename=function(e,t){var n=i(e)[2];return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},n.extname=function(e){return i(e)[3]};var s=\"b\"===\"ab\".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)}}).call(this,e(\"_process\"))},{_process:3}],3:[function(e,t,n){function r(){throw new Error(\"setTimeout has not been defined\")}function o(){throw new Error(\"clearTimeout has not been defined\")}function i(e){if(f===setTimeout)return setTimeout(e,0);if((f===r||!f)&&setTimeout)return f=setTimeout,setTimeout(e,0);try{return f(e,0)}catch(t){try{return f.call(null,e,0)}catch(t){return f.call(this,e,0)}}}function s(e){if(p===clearTimeout)return clearTimeout(e);if((p===o||!p)&&clearTimeout)return p=clearTimeout,clearTimeout(e);try{return p(e)}catch(t){try{return p.call(null,e)}catch(t){return p.call(this,e)}}}function a(){m&&d&&(m=!1,d.length?g=d.concat(g):v=-1,g.length&&u())}function u(){if(!m){var e=i(a);m=!0;for(var t=g.length;t;){for(d=g,g=[];++v<t;)d&&d[v].run();v=-1,t=g.length}d=null,m=!1,s(e)}}function c(e,t){this.fun=e,this.array=t}function l(){}var f,p,h=t.exports={};!function(){try{f=\"function\"==typeof setTimeout?setTimeout:r}catch(e){f=r}try{p=\"function\"==typeof clearTimeout?clearTimeout:o}catch(e){p=o}}();var d,g=[],m=!1,v=-1;h.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];g.push(new c(e,t)),1!==g.length||m||i(u)},c.prototype.run=function(){this.fun.apply(null,this.array)},h.title=\"browser\",h.browser=!0,h.env={},h.argv=[],h.version=\"\",h.versions={},h.on=l,h.addListener=l,h.once=l,h.off=l,h.removeListener=l,h.removeAllListeners=l,h.emit=l,h.binding=function(e){throw new Error(\"process.binding is not supported\")},h.cwd=function(){return\"/\"},h.chdir=function(e){throw new Error(\"process.chdir is not supported\")},h.umask=function(){return 0}},{}],4:[function(e,t,n){(function(e){!function(r){function o(e){throw new RangeError(L[e])}function i(e,t){for(var n=e.length,r=[];n--;)r[n]=t(e[n]);return r}function s(e,t){var n=e.split(\"@\"),r=\"\";n.length>1&&(r=n[0]+\"@\",e=n[1]),e=e.replace(O,\".\");var o=e.split(\".\"),s=i(o,t).join(\".\");return r+s}function a(e){for(var t,n,r=[],o=0,i=e.length;o<i;)t=e.charCodeAt(o++),t>=55296&&t<=56319&&o<i?(n=e.charCodeAt(o++),56320==(64512&n)?r.push(((1023&t)<<10)+(1023&n)+65536):(r.push(t),o--)):r.push(t);return r}function u(e){return i(e,function(e){var t=\"\";return e>65535&&(e-=65536,t+=R(e>>>10&1023|55296),e=56320|1023&e),t+=R(e)}).join(\"\")}function c(e){return e-48<10?e-22:e-65<26?e-65:e-97<26?e-97:T}function l(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function f(e,t,n){var r=0;for(e=n?F(e/E):e>>1,e+=F(e/t);e>H*j>>1;r+=T)e=F(e/H);return F(r+(H+1)*e/(e+k))}function p(e){var t,n,r,i,s,a,l,p,h,d,g=[],m=e.length,v=0,y=N,x=S;for(n=e.lastIndexOf(A),n<0&&(n=0),r=0;r<n;++r)e.charCodeAt(r)>=128&&o(\"not-basic\"),g.push(e.charCodeAt(r));for(i=n>0?n+1:0;i<m;){for(s=v,a=1,l=T;i>=m&&o(\"invalid-input\"),p=c(e.charCodeAt(i++)),(p>=T||p>F((w-v)/a))&&o(\"overflow\"),v+=p*a,h=l<=x?C:l>=x+j?j:l-x,!(p<h);l+=T)d=T-h,a>F(w/d)&&o(\"overflow\"),a*=d;t=g.length+1,x=f(v-s,t,0==s),F(v/t)>w-y&&o(\"overflow\"),y+=F(v/t),v%=t,g.splice(v++,0,y)}return u(g)}function h(e){var t,n,r,i,s,u,c,p,h,d,g,m,v,y,x,b=[];for(e=a(e),m=e.length,t=N,n=0,s=S,u=0;u<m;++u)g=e[u],g<128&&b.push(R(g));for(r=i=b.length,i&&b.push(A);r<m;){for(c=w,u=0;u<m;++u)g=e[u],g>=t&&g<c&&(c=g);for(v=r+1,c-t>F((w-n)/v)&&o(\"overflow\"),n+=(c-t)*v,t=c,u=0;u<m;++u)if(g=e[u],g<t&&++n>w&&o(\"overflow\"),g==t){for(p=n,h=T;d=h<=s?C:h>=s+j?j:h-s,!(p<d);h+=T)x=p-d,y=T-d,b.push(R(l(d+x%y,0))),p=F(x/y);b.push(R(l(p,0))),s=f(n,v,r==i),n=0,++r}++n,++t}return b.join(\"\")}function d(e){return s(e,function(e){return q.test(e)?p(e.slice(4).toLowerCase()):e})}function g(e){return s(e,function(e){return D.test(e)?\"xn--\"+h(e):e})}var m=\"object\"==typeof n&&n&&!n.nodeType&&n,v=\"object\"==typeof t&&t&&!t.nodeType&&t,y=\"object\"==typeof e&&e;y.global!==y&&y.window!==y&&y.self!==y||(r=y);var x,b,w=2147483647,T=36,C=1,j=26,k=38,E=700,S=72,N=128,A=\"-\",q=/^xn--/,D=/[^\\x20-\\x7E]/,O=/[\\x2E\\u3002\\uFF0E\\uFF61]/g,L={overflow:\"Overflow: input needs wider integers to process\",\"not-basic\":\"Illegal input >= 0x80 (not a basic code point)\",\"invalid-input\":\"Invalid input\"},H=T-C,F=Math.floor,R=String.fromCharCode;if(x={version:\"1.4.1\",ucs2:{decode:a,encode:u},decode:p,encode:h,toASCII:g,toUnicode:d},\"function\"==typeof define&&\"object\"==typeof define.amd&&define.amd)define(\"punycode\",function(){return x});else if(m&&v)if(t.exports==m)v.exports=x;else for(b in x)x.hasOwnProperty(b)&&(m[b]=x[b]);else r.punycode=x}(this)}).call(this,\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{})},{}],5:[function(e,t,n){\"use strict\";function r(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.exports=function(e,t,n,i){t=t||\"&\",n=n||\"=\";var s={};if(\"string\"!=typeof e||0===e.length)return s;var a=/\\+/g;e=e.split(t);var u=1e3;i&&\"number\"==typeof i.maxKeys&&(u=i.maxKeys);var c=e.length;u>0&&c>u&&(c=u);for(var l=0;l<c;++l){var f,p,h,d,g=e[l].replace(a,\"%20\"),m=g.indexOf(n);m>=0?(f=g.substr(0,m),p=g.substr(m+1)):(f=g,p=\"\"),h=decodeURIComponent(f),d=decodeURIComponent(p),r(s,h)?o(s[h])?s[h].push(d):s[h]=[s[h],d]:s[h]=d}return s};var o=Array.isArray||function(e){return\"[object Array]\"===Object.prototype.toString.call(e)}},{}],6:[function(e,t,n){\"use strict\";function r(e,t){if(e.map)return e.map(t);for(var n=[],r=0;r<e.length;r++)n.push(t(e[r],r));return n}var o=function(e){switch(typeof e){case\"string\":return e;case\"boolean\":return e?\"true\":\"false\";case\"number\":return isFinite(e)?e:\"\";default:return\"\"}};t.exports=function(e,t,n,a){return t=t||\"&\",n=n||\"=\",null===e&&(e=void 0),\"object\"==typeof e?r(s(e),function(s){var a=encodeURIComponent(o(s))+n;return i(e[s])?r(e[s],function(e){return a+encodeURIComponent(o(e))}).join(t):a+encodeURIComponent(o(e[s]))}).join(t):a?encodeURIComponent(o(a))+n+encodeURIComponent(o(e)):\"\"};var i=Array.isArray||function(e){return\"[object Array]\"===Object.prototype.toString.call(e)},s=Object.keys||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.push(n);return t}},{}],7:[function(e,t,n){\"use strict\";n.decode=n.parse=e(\"./decode\"),n.encode=n.stringify=e(\"./encode\")},{\"./decode\":5,\"./encode\":6}],8:[function(e,t,n){\"use strict\";function r(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}function o(e,t,n){if(e&&c.isObject(e)&&e instanceof r)return e;var o=new r;return o.parse(e,t,n),\no}function i(e){return c.isString(e)&&(e=o(e)),e instanceof r?e.format():r.prototype.format.call(e)}function s(e,t){return o(e,!1,!0).resolve(t)}function a(e,t){return e?o(e,!1,!0).resolveObject(t):t}var u=e(\"punycode\"),c=e(\"./util\");n.parse=o,n.resolve=s,n.resolveObject=a,n.format=i,n.Url=r;var l=/^([a-z0-9.+-]+:)/i,f=/:[0-9]*$/,p=/^(\\/\\/?(?!\\/)[^\\?\\s]*)(\\?[^\\s]*)?$/,h=[\"<\",\">\",'\"',\"`\",\" \",\"\\r\",\"\\n\",\"\\t\"],d=[\"{\",\"}\",\"|\",\"\\\\\",\"^\",\"`\"].concat(h),g=[\"'\"].concat(d),m=[\"%\",\"/\",\"?\",\";\",\"#\"].concat(g),v=[\"/\",\"?\",\"#\"],y=255,x=/^[+a-z0-9A-Z_-]{0,63}$/,b=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,w={javascript:!0,\"javascript:\":!0},T={javascript:!0,\"javascript:\":!0},C={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,\"http:\":!0,\"https:\":!0,\"ftp:\":!0,\"gopher:\":!0,\"file:\":!0},j=e(\"querystring\");r.prototype.parse=function(e,t,n){if(!c.isString(e))throw new TypeError(\"Parameter 'url' must be a string, not \"+typeof e);var r=e.indexOf(\"?\"),o=r!==-1&&r<e.indexOf(\"#\")?\"?\":\"#\",i=e.split(o),s=/\\\\/g;i[0]=i[0].replace(s,\"/\"),e=i.join(o);var a=e;if(a=a.trim(),!n&&1===e.split(\"#\").length){var f=p.exec(a);if(f)return this.path=a,this.href=a,this.pathname=f[1],f[2]?(this.search=f[2],t?this.query=j.parse(this.search.substr(1)):this.query=this.search.substr(1)):t&&(this.search=\"\",this.query={}),this}var h=l.exec(a);if(h){h=h[0];var d=h.toLowerCase();this.protocol=d,a=a.substr(h.length)}if(n||h||a.match(/^\\/\\/[^@\\/]+@[^@\\/]+/)){var k=\"//\"===a.substr(0,2);!k||h&&T[h]||(a=a.substr(2),this.slashes=!0)}if(!T[h]&&(k||h&&!C[h])){for(var E=-1,S=0;S<v.length;S++){var N=a.indexOf(v[S]);N!==-1&&(E===-1||N<E)&&(E=N)}var A,q;q=E===-1?a.lastIndexOf(\"@\"):a.lastIndexOf(\"@\",E),q!==-1&&(A=a.slice(0,q),a=a.slice(q+1),this.auth=decodeURIComponent(A)),E=-1;for(var S=0;S<m.length;S++){var N=a.indexOf(m[S]);N!==-1&&(E===-1||N<E)&&(E=N)}E===-1&&(E=a.length),this.host=a.slice(0,E),a=a.slice(E),this.parseHost(),this.hostname=this.hostname||\"\";var D=\"[\"===this.hostname[0]&&\"]\"===this.hostname[this.hostname.length-1];if(!D)for(var O=this.hostname.split(/\\./),S=0,L=O.length;S<L;S++){var H=O[S];if(H&&!H.match(x)){for(var F=\"\",R=0,I=H.length;R<I;R++)F+=H.charCodeAt(R)>127?\"x\":H[R];if(!F.match(x)){var P=O.slice(0,S),M=O.slice(S+1),$=H.match(b);$&&(P.push($[1]),M.unshift($[2])),M.length&&(a=\"/\"+M.join(\".\")+a),this.hostname=P.join(\".\");break}}}this.hostname.length>y?this.hostname=\"\":this.hostname=this.hostname.toLowerCase(),D||(this.hostname=u.toASCII(this.hostname));var W=this.port?\":\"+this.port:\"\",B=this.hostname||\"\";this.host=B+W,this.href+=this.host,D&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),\"/\"!==a[0]&&(a=\"/\"+a))}if(!w[d])for(var S=0,L=g.length;S<L;S++){var _=g[S];if(a.indexOf(_)!==-1){var U=encodeURIComponent(_);U===_&&(U=escape(_)),a=a.split(_).join(U)}}var z=a.indexOf(\"#\");z!==-1&&(this.hash=a.substr(z),a=a.slice(0,z));var X=a.indexOf(\"?\");if(X!==-1?(this.search=a.substr(X),this.query=a.substr(X+1),t&&(this.query=j.parse(this.query)),a=a.slice(0,X)):t&&(this.search=\"\",this.query={}),a&&(this.pathname=a),C[d]&&this.hostname&&!this.pathname&&(this.pathname=\"/\"),this.pathname||this.search){var W=this.pathname||\"\",V=this.search||\"\";this.path=W+V}return this.href=this.format(),this},r.prototype.format=function(){var e=this.auth||\"\";e&&(e=encodeURIComponent(e),e=e.replace(/%3A/i,\":\"),e+=\"@\");var t=this.protocol||\"\",n=this.pathname||\"\",r=this.hash||\"\",o=!1,i=\"\";this.host?o=e+this.host:this.hostname&&(o=e+(this.hostname.indexOf(\":\")===-1?this.hostname:\"[\"+this.hostname+\"]\"),this.port&&(o+=\":\"+this.port)),this.query&&c.isObject(this.query)&&Object.keys(this.query).length&&(i=j.stringify(this.query));var s=this.search||i&&\"?\"+i||\"\";return t&&\":\"!==t.substr(-1)&&(t+=\":\"),this.slashes||(!t||C[t])&&o!==!1?(o=\"//\"+(o||\"\"),n&&\"/\"!==n.charAt(0)&&(n=\"/\"+n)):o||(o=\"\"),r&&\"#\"!==r.charAt(0)&&(r=\"#\"+r),s&&\"?\"!==s.charAt(0)&&(s=\"?\"+s),n=n.replace(/[?#]/g,function(e){return encodeURIComponent(e)}),s=s.replace(\"#\",\"%23\"),t+o+n+s+r},r.prototype.resolve=function(e){return this.resolveObject(o(e,!1,!0)).format()},r.prototype.resolveObject=function(e){if(c.isString(e)){var t=new r;t.parse(e,!1,!0),e=t}for(var n=new r,o=Object.keys(this),i=0;i<o.length;i++){var s=o[i];n[s]=this[s]}if(n.hash=e.hash,\"\"===e.href)return n.href=n.format(),n;if(e.slashes&&!e.protocol){for(var a=Object.keys(e),u=0;u<a.length;u++){var l=a[u];\"protocol\"!==l&&(n[l]=e[l])}return C[n.protocol]&&n.hostname&&!n.pathname&&(n.path=n.pathname=\"/\"),n.href=n.format(),n}if(e.protocol&&e.protocol!==n.protocol){if(!C[e.protocol]){for(var f=Object.keys(e),p=0;p<f.length;p++){var h=f[p];n[h]=e[h]}return n.href=n.format(),n}if(n.protocol=e.protocol,e.host||T[e.protocol])n.pathname=e.pathname;else{for(var d=(e.pathname||\"\").split(\"/\");d.length&&!(e.host=d.shift()););e.host||(e.host=\"\"),e.hostname||(e.hostname=\"\"),\"\"!==d[0]&&d.unshift(\"\"),d.length<2&&d.unshift(\"\"),n.pathname=d.join(\"/\")}if(n.search=e.search,n.query=e.query,n.host=e.host||\"\",n.auth=e.auth,n.hostname=e.hostname||e.host,n.port=e.port,n.pathname||n.search){var g=n.pathname||\"\",m=n.search||\"\";n.path=g+m}return n.slashes=n.slashes||e.slashes,n.href=n.format(),n}var v=n.pathname&&\"/\"===n.pathname.charAt(0),y=e.host||e.pathname&&\"/\"===e.pathname.charAt(0),x=y||v||n.host&&e.pathname,b=x,w=n.pathname&&n.pathname.split(\"/\")||[],d=e.pathname&&e.pathname.split(\"/\")||[],j=n.protocol&&!C[n.protocol];if(j&&(n.hostname=\"\",n.port=null,n.host&&(\"\"===w[0]?w[0]=n.host:w.unshift(n.host)),n.host=\"\",e.protocol&&(e.hostname=null,e.port=null,e.host&&(\"\"===d[0]?d[0]=e.host:d.unshift(e.host)),e.host=null),x=x&&(\"\"===d[0]||\"\"===w[0])),y)n.host=e.host||\"\"===e.host?e.host:n.host,n.hostname=e.hostname||\"\"===e.hostname?e.hostname:n.hostname,n.search=e.search,n.query=e.query,w=d;else if(d.length)w||(w=[]),w.pop(),w=w.concat(d),n.search=e.search,n.query=e.query;else if(!c.isNullOrUndefined(e.search)){if(j){n.hostname=n.host=w.shift();var k=!!(n.host&&n.host.indexOf(\"@\")>0)&&n.host.split(\"@\");k&&(n.auth=k.shift(),n.host=n.hostname=k.shift())}return n.search=e.search,n.query=e.query,c.isNull(n.pathname)&&c.isNull(n.search)||(n.path=(n.pathname?n.pathname:\"\")+(n.search?n.search:\"\")),n.href=n.format(),n}if(!w.length)return n.pathname=null,n.search?n.path=\"/\"+n.search:n.path=null,n.href=n.format(),n;for(var E=w.slice(-1)[0],S=(n.host||e.host||w.length>1)&&(\".\"===E||\"..\"===E)||\"\"===E,N=0,A=w.length;A>=0;A--)E=w[A],\".\"===E?w.splice(A,1):\"..\"===E?(w.splice(A,1),N++):N&&(w.splice(A,1),N--);if(!x&&!b)for(;N--;N)w.unshift(\"..\");!x||\"\"===w[0]||w[0]&&\"/\"===w[0].charAt(0)||w.unshift(\"\"),S&&\"/\"!==w.join(\"/\").substr(-1)&&w.push(\"\");var q=\"\"===w[0]||w[0]&&\"/\"===w[0].charAt(0);if(j){n.hostname=n.host=q?\"\":w.length?w.shift():\"\";var k=!!(n.host&&n.host.indexOf(\"@\")>0)&&n.host.split(\"@\");k&&(n.auth=k.shift(),n.host=n.hostname=k.shift())}return x=x||n.host&&w.length,x&&!q&&w.unshift(\"\"),w.length?n.pathname=w.join(\"/\"):(n.pathname=null,n.path=null),c.isNull(n.pathname)&&c.isNull(n.search)||(n.path=(n.pathname?n.pathname:\"\")+(n.search?n.search:\"\")),n.auth=e.auth||n.auth,n.slashes=n.slashes||e.slashes,n.href=n.format(),n},r.prototype.parseHost=function(){var e=this.host,t=f.exec(e);t&&(t=t[0],\":\"!==t&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)}},{\"./util\":9,punycode:4,querystring:7}],9:[function(e,t,n){\"use strict\";t.exports={isString:function(e){return\"string\"==typeof e},isObject:function(e){return\"object\"==typeof e&&null!==e},isNull:function(e){return null===e},isNullOrUndefined:function(e){return null==e}}},{}],10:[function(e,t,n){var r=e(\"jquery\");t.exports=r({})},{jquery:1}],11:[function(e,t,n){var r=e(\"jquery\"),o=e(\"./events\"),i=e(\"./storage\"),s=e(\"./page\"),a=!1,u=window.gitbook||[],c={events:o,page:s,state:s.getState(),storage:i,push:function(e){a?e():u.push(e)}},l={gitbook:c,jquery:r};window.gitbook=c,window.$=r,window.jQuery=r,window.require=function(e,t){e=e.map(function(e){if(e=e.toLowerCase(),!l[e])throw new Error(\"GitBook module \"+e+\" doesn't exist\");return l[e]}),t.apply(null,e)},r(document).ready(function(){a=!0,r.each(u,function(e,t){t()})})},{\"./events\":10,\"./page\":12,\"./storage\":13,jquery:1}],12:[function(e,t,n){function r(e){console.log(\"page has changed\",e),o(e),l||(l=!0,c.trigger(\"start\",e.config.pluginsConfig)),c.trigger(\"page.change\")}function o(e){f.page=e.page,f.file=e.file,f.gitbook=e.gitbook,f.config=e.config,f.basePath=e.basePath,f.book=e.book,f.$book=s(\".book\"),f.revision=f.gitbook.time,f.level=f.page.level,f.filepath=f.file.path,f.chapterTitle=f.page.title,f.innerLanguage=f.book.language||\"\",f.root=a.resolve(location.protocol+\"//\"+location.host,u.dirname(u.resolve(location.pathname.replace(/\\/$/,\"/index.html\"),f.basePath))).replace(/\\/?$/,\"/\"),f.bookRoot=f.innerLanguage?a.resolve(f.root,\"..\"):f.root}function i(){return f}var s=e(\"jquery\"),a=e(\"url\"),u=e(\"path\"),c=e(\"./events\"),l=!1,f={};t.exports={hasChanged:r,setState:o,getState:i}},{\"./events\":10,jquery:1,path:2,url:8}],13:[function(e,t,n){var r=\"\";t.exports={setBaseKey:function(e){r=e},set:function(e,t){e=r+\":\"+e;try{localStorage[e]=JSON.stringify(t)}catch(e){}},get:function(e,t){var n;e=r+\":\"+e;try{n=localStorage[e]}catch(e){}if(void 0===n)return t;try{var o=JSON.parse(n);return null==o?t:o}catch(e){return n||t}},remove:function(e){e=r+\":\"+e;try{localStorage.removeItem(e)}catch(e){}}}},{}]},{},[11]);\n"
  },
  {
    "path": "atlas-docs/_book/gitbook/style.css",
    "content": "/*! normalize.css v2.1.0 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:\"\\201C\" \"\\201D\" \"\\2018\" \"\\2019\"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}.link-inherit{color:inherit}.link-inherit:focus,.link-inherit:hover{color:inherit}.hidden{display:none}.alert{padding:15px;margin-bottom:20px;color:#444;background:#eee;border-bottom:5px solid #ddd}.alert-success{background:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-info{background:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-danger{background:#f2dede;border-color:#ebccd1;color:#a94442}.alert-warning{background:#fcf8e3;border-color:#faebcc;color:#8a6d3b}/*!\n *  Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome/fontawesome-webfont.eot?v=4.6.3);src:url(fonts/fontawesome/fontawesome-webfont.eot?#iefix&v=4.6.3) format('embedded-opentype'),url(fonts/fontawesome/fontawesome-webfont.woff2?v=4.6.3) format('woff2'),url(fonts/fontawesome/fontawesome-webfont.woff?v=4.6.3) format('woff'),url(fonts/fontawesome/fontawesome-webfont.ttf?v=4.6.3) format('truetype'),url(fonts/fontawesome/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular) format('svg');font-weight:400;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:\"\\f000\"}.fa-music:before{content:\"\\f001\"}.fa-search:before{content:\"\\f002\"}.fa-envelope-o:before{content:\"\\f003\"}.fa-heart:before{content:\"\\f004\"}.fa-star:before{content:\"\\f005\"}.fa-star-o:before{content:\"\\f006\"}.fa-user:before{content:\"\\f007\"}.fa-film:before{content:\"\\f008\"}.fa-th-large:before{content:\"\\f009\"}.fa-th:before{content:\"\\f00a\"}.fa-th-list:before{content:\"\\f00b\"}.fa-check:before{content:\"\\f00c\"}.fa-close:before,.fa-remove:before,.fa-times:before{content:\"\\f00d\"}.fa-search-plus:before{content:\"\\f00e\"}.fa-search-minus:before{content:\"\\f010\"}.fa-power-off:before{content:\"\\f011\"}.fa-signal:before{content:\"\\f012\"}.fa-cog:before,.fa-gear:before{content:\"\\f013\"}.fa-trash-o:before{content:\"\\f014\"}.fa-home:before{content:\"\\f015\"}.fa-file-o:before{content:\"\\f016\"}.fa-clock-o:before{content:\"\\f017\"}.fa-road:before{content:\"\\f018\"}.fa-download:before{content:\"\\f019\"}.fa-arrow-circle-o-down:before{content:\"\\f01a\"}.fa-arrow-circle-o-up:before{content:\"\\f01b\"}.fa-inbox:before{content:\"\\f01c\"}.fa-play-circle-o:before{content:\"\\f01d\"}.fa-repeat:before,.fa-rotate-right:before{content:\"\\f01e\"}.fa-refresh:before{content:\"\\f021\"}.fa-list-alt:before{content:\"\\f022\"}.fa-lock:before{content:\"\\f023\"}.fa-flag:before{content:\"\\f024\"}.fa-headphones:before{content:\"\\f025\"}.fa-volume-off:before{content:\"\\f026\"}.fa-volume-down:before{content:\"\\f027\"}.fa-volume-up:before{content:\"\\f028\"}.fa-qrcode:before{content:\"\\f029\"}.fa-barcode:before{content:\"\\f02a\"}.fa-tag:before{content:\"\\f02b\"}.fa-tags:before{content:\"\\f02c\"}.fa-book:before{content:\"\\f02d\"}.fa-bookmark:before{content:\"\\f02e\"}.fa-print:before{content:\"\\f02f\"}.fa-camera:before{content:\"\\f030\"}.fa-font:before{content:\"\\f031\"}.fa-bold:before{content:\"\\f032\"}.fa-italic:before{content:\"\\f033\"}.fa-text-height:before{content:\"\\f034\"}.fa-text-width:before{content:\"\\f035\"}.fa-align-left:before{content:\"\\f036\"}.fa-align-center:before{content:\"\\f037\"}.fa-align-right:before{content:\"\\f038\"}.fa-align-justify:before{content:\"\\f039\"}.fa-list:before{content:\"\\f03a\"}.fa-dedent:before,.fa-outdent:before{content:\"\\f03b\"}.fa-indent:before{content:\"\\f03c\"}.fa-video-camera:before{content:\"\\f03d\"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:\"\\f03e\"}.fa-pencil:before{content:\"\\f040\"}.fa-map-marker:before{content:\"\\f041\"}.fa-adjust:before{content:\"\\f042\"}.fa-tint:before{content:\"\\f043\"}.fa-edit:before,.fa-pencil-square-o:before{content:\"\\f044\"}.fa-share-square-o:before{content:\"\\f045\"}.fa-check-square-o:before{content:\"\\f046\"}.fa-arrows:before{content:\"\\f047\"}.fa-step-backward:before{content:\"\\f048\"}.fa-fast-backward:before{content:\"\\f049\"}.fa-backward:before{content:\"\\f04a\"}.fa-play:before{content:\"\\f04b\"}.fa-pause:before{content:\"\\f04c\"}.fa-stop:before{content:\"\\f04d\"}.fa-forward:before{content:\"\\f04e\"}.fa-fast-forward:before{content:\"\\f050\"}.fa-step-forward:before{content:\"\\f051\"}.fa-eject:before{content:\"\\f052\"}.fa-chevron-left:before{content:\"\\f053\"}.fa-chevron-right:before{content:\"\\f054\"}.fa-plus-circle:before{content:\"\\f055\"}.fa-minus-circle:before{content:\"\\f056\"}.fa-times-circle:before{content:\"\\f057\"}.fa-check-circle:before{content:\"\\f058\"}.fa-question-circle:before{content:\"\\f059\"}.fa-info-circle:before{content:\"\\f05a\"}.fa-crosshairs:before{content:\"\\f05b\"}.fa-times-circle-o:before{content:\"\\f05c\"}.fa-check-circle-o:before{content:\"\\f05d\"}.fa-ban:before{content:\"\\f05e\"}.fa-arrow-left:before{content:\"\\f060\"}.fa-arrow-right:before{content:\"\\f061\"}.fa-arrow-up:before{content:\"\\f062\"}.fa-arrow-down:before{content:\"\\f063\"}.fa-mail-forward:before,.fa-share:before{content:\"\\f064\"}.fa-expand:before{content:\"\\f065\"}.fa-compress:before{content:\"\\f066\"}.fa-plus:before{content:\"\\f067\"}.fa-minus:before{content:\"\\f068\"}.fa-asterisk:before{content:\"\\f069\"}.fa-exclamation-circle:before{content:\"\\f06a\"}.fa-gift:before{content:\"\\f06b\"}.fa-leaf:before{content:\"\\f06c\"}.fa-fire:before{content:\"\\f06d\"}.fa-eye:before{content:\"\\f06e\"}.fa-eye-slash:before{content:\"\\f070\"}.fa-exclamation-triangle:before,.fa-warning:before{content:\"\\f071\"}.fa-plane:before{content:\"\\f072\"}.fa-calendar:before{content:\"\\f073\"}.fa-random:before{content:\"\\f074\"}.fa-comment:before{content:\"\\f075\"}.fa-magnet:before{content:\"\\f076\"}.fa-chevron-up:before{content:\"\\f077\"}.fa-chevron-down:before{content:\"\\f078\"}.fa-retweet:before{content:\"\\f079\"}.fa-shopping-cart:before{content:\"\\f07a\"}.fa-folder:before{content:\"\\f07b\"}.fa-folder-open:before{content:\"\\f07c\"}.fa-arrows-v:before{content:\"\\f07d\"}.fa-arrows-h:before{content:\"\\f07e\"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:\"\\f080\"}.fa-twitter-square:before{content:\"\\f081\"}.fa-facebook-square:before{content:\"\\f082\"}.fa-camera-retro:before{content:\"\\f083\"}.fa-key:before{content:\"\\f084\"}.fa-cogs:before,.fa-gears:before{content:\"\\f085\"}.fa-comments:before{content:\"\\f086\"}.fa-thumbs-o-up:before{content:\"\\f087\"}.fa-thumbs-o-down:before{content:\"\\f088\"}.fa-star-half:before{content:\"\\f089\"}.fa-heart-o:before{content:\"\\f08a\"}.fa-sign-out:before{content:\"\\f08b\"}.fa-linkedin-square:before{content:\"\\f08c\"}.fa-thumb-tack:before{content:\"\\f08d\"}.fa-external-link:before{content:\"\\f08e\"}.fa-sign-in:before{content:\"\\f090\"}.fa-trophy:before{content:\"\\f091\"}.fa-github-square:before{content:\"\\f092\"}.fa-upload:before{content:\"\\f093\"}.fa-lemon-o:before{content:\"\\f094\"}.fa-phone:before{content:\"\\f095\"}.fa-square-o:before{content:\"\\f096\"}.fa-bookmark-o:before{content:\"\\f097\"}.fa-phone-square:before{content:\"\\f098\"}.fa-twitter:before{content:\"\\f099\"}.fa-facebook-f:before,.fa-facebook:before{content:\"\\f09a\"}.fa-github:before{content:\"\\f09b\"}.fa-unlock:before{content:\"\\f09c\"}.fa-credit-card:before{content:\"\\f09d\"}.fa-feed:before,.fa-rss:before{content:\"\\f09e\"}.fa-hdd-o:before{content:\"\\f0a0\"}.fa-bullhorn:before{content:\"\\f0a1\"}.fa-bell:before{content:\"\\f0f3\"}.fa-certificate:before{content:\"\\f0a3\"}.fa-hand-o-right:before{content:\"\\f0a4\"}.fa-hand-o-left:before{content:\"\\f0a5\"}.fa-hand-o-up:before{content:\"\\f0a6\"}.fa-hand-o-down:before{content:\"\\f0a7\"}.fa-arrow-circle-left:before{content:\"\\f0a8\"}.fa-arrow-circle-right:before{content:\"\\f0a9\"}.fa-arrow-circle-up:before{content:\"\\f0aa\"}.fa-arrow-circle-down:before{content:\"\\f0ab\"}.fa-globe:before{content:\"\\f0ac\"}.fa-wrench:before{content:\"\\f0ad\"}.fa-tasks:before{content:\"\\f0ae\"}.fa-filter:before{content:\"\\f0b0\"}.fa-briefcase:before{content:\"\\f0b1\"}.fa-arrows-alt:before{content:\"\\f0b2\"}.fa-group:before,.fa-users:before{content:\"\\f0c0\"}.fa-chain:before,.fa-link:before{content:\"\\f0c1\"}.fa-cloud:before{content:\"\\f0c2\"}.fa-flask:before{content:\"\\f0c3\"}.fa-cut:before,.fa-scissors:before{content:\"\\f0c4\"}.fa-copy:before,.fa-files-o:before{content:\"\\f0c5\"}.fa-paperclip:before{content:\"\\f0c6\"}.fa-floppy-o:before,.fa-save:before{content:\"\\f0c7\"}.fa-square:before{content:\"\\f0c8\"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:\"\\f0c9\"}.fa-list-ul:before{content:\"\\f0ca\"}.fa-list-ol:before{content:\"\\f0cb\"}.fa-strikethrough:before{content:\"\\f0cc\"}.fa-underline:before{content:\"\\f0cd\"}.fa-table:before{content:\"\\f0ce\"}.fa-magic:before{content:\"\\f0d0\"}.fa-truck:before{content:\"\\f0d1\"}.fa-pinterest:before{content:\"\\f0d2\"}.fa-pinterest-square:before{content:\"\\f0d3\"}.fa-google-plus-square:before{content:\"\\f0d4\"}.fa-google-plus:before{content:\"\\f0d5\"}.fa-money:before{content:\"\\f0d6\"}.fa-caret-down:before{content:\"\\f0d7\"}.fa-caret-up:before{content:\"\\f0d8\"}.fa-caret-left:before{content:\"\\f0d9\"}.fa-caret-right:before{content:\"\\f0da\"}.fa-columns:before{content:\"\\f0db\"}.fa-sort:before,.fa-unsorted:before{content:\"\\f0dc\"}.fa-sort-desc:before,.fa-sort-down:before{content:\"\\f0dd\"}.fa-sort-asc:before,.fa-sort-up:before{content:\"\\f0de\"}.fa-envelope:before{content:\"\\f0e0\"}.fa-linkedin:before{content:\"\\f0e1\"}.fa-rotate-left:before,.fa-undo:before{content:\"\\f0e2\"}.fa-gavel:before,.fa-legal:before{content:\"\\f0e3\"}.fa-dashboard:before,.fa-tachometer:before{content:\"\\f0e4\"}.fa-comment-o:before{content:\"\\f0e5\"}.fa-comments-o:before{content:\"\\f0e6\"}.fa-bolt:before,.fa-flash:before{content:\"\\f0e7\"}.fa-sitemap:before{content:\"\\f0e8\"}.fa-umbrella:before{content:\"\\f0e9\"}.fa-clipboard:before,.fa-paste:before{content:\"\\f0ea\"}.fa-lightbulb-o:before{content:\"\\f0eb\"}.fa-exchange:before{content:\"\\f0ec\"}.fa-cloud-download:before{content:\"\\f0ed\"}.fa-cloud-upload:before{content:\"\\f0ee\"}.fa-user-md:before{content:\"\\f0f0\"}.fa-stethoscope:before{content:\"\\f0f1\"}.fa-suitcase:before{content:\"\\f0f2\"}.fa-bell-o:before{content:\"\\f0a2\"}.fa-coffee:before{content:\"\\f0f4\"}.fa-cutlery:before{content:\"\\f0f5\"}.fa-file-text-o:before{content:\"\\f0f6\"}.fa-building-o:before{content:\"\\f0f7\"}.fa-hospital-o:before{content:\"\\f0f8\"}.fa-ambulance:before{content:\"\\f0f9\"}.fa-medkit:before{content:\"\\f0fa\"}.fa-fighter-jet:before{content:\"\\f0fb\"}.fa-beer:before{content:\"\\f0fc\"}.fa-h-square:before{content:\"\\f0fd\"}.fa-plus-square:before{content:\"\\f0fe\"}.fa-angle-double-left:before{content:\"\\f100\"}.fa-angle-double-right:before{content:\"\\f101\"}.fa-angle-double-up:before{content:\"\\f102\"}.fa-angle-double-down:before{content:\"\\f103\"}.fa-angle-left:before{content:\"\\f104\"}.fa-angle-right:before{content:\"\\f105\"}.fa-angle-up:before{content:\"\\f106\"}.fa-angle-down:before{content:\"\\f107\"}.fa-desktop:before{content:\"\\f108\"}.fa-laptop:before{content:\"\\f109\"}.fa-tablet:before{content:\"\\f10a\"}.fa-mobile-phone:before,.fa-mobile:before{content:\"\\f10b\"}.fa-circle-o:before{content:\"\\f10c\"}.fa-quote-left:before{content:\"\\f10d\"}.fa-quote-right:before{content:\"\\f10e\"}.fa-spinner:before{content:\"\\f110\"}.fa-circle:before{content:\"\\f111\"}.fa-mail-reply:before,.fa-reply:before{content:\"\\f112\"}.fa-github-alt:before{content:\"\\f113\"}.fa-folder-o:before{content:\"\\f114\"}.fa-folder-open-o:before{content:\"\\f115\"}.fa-smile-o:before{content:\"\\f118\"}.fa-frown-o:before{content:\"\\f119\"}.fa-meh-o:before{content:\"\\f11a\"}.fa-gamepad:before{content:\"\\f11b\"}.fa-keyboard-o:before{content:\"\\f11c\"}.fa-flag-o:before{content:\"\\f11d\"}.fa-flag-checkered:before{content:\"\\f11e\"}.fa-terminal:before{content:\"\\f120\"}.fa-code:before{content:\"\\f121\"}.fa-mail-reply-all:before,.fa-reply-all:before{content:\"\\f122\"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:\"\\f123\"}.fa-location-arrow:before{content:\"\\f124\"}.fa-crop:before{content:\"\\f125\"}.fa-code-fork:before{content:\"\\f126\"}.fa-chain-broken:before,.fa-unlink:before{content:\"\\f127\"}.fa-question:before{content:\"\\f128\"}.fa-info:before{content:\"\\f129\"}.fa-exclamation:before{content:\"\\f12a\"}.fa-superscript:before{content:\"\\f12b\"}.fa-subscript:before{content:\"\\f12c\"}.fa-eraser:before{content:\"\\f12d\"}.fa-puzzle-piece:before{content:\"\\f12e\"}.fa-microphone:before{content:\"\\f130\"}.fa-microphone-slash:before{content:\"\\f131\"}.fa-shield:before{content:\"\\f132\"}.fa-calendar-o:before{content:\"\\f133\"}.fa-fire-extinguisher:before{content:\"\\f134\"}.fa-rocket:before{content:\"\\f135\"}.fa-maxcdn:before{content:\"\\f136\"}.fa-chevron-circle-left:before{content:\"\\f137\"}.fa-chevron-circle-right:before{content:\"\\f138\"}.fa-chevron-circle-up:before{content:\"\\f139\"}.fa-chevron-circle-down:before{content:\"\\f13a\"}.fa-html5:before{content:\"\\f13b\"}.fa-css3:before{content:\"\\f13c\"}.fa-anchor:before{content:\"\\f13d\"}.fa-unlock-alt:before{content:\"\\f13e\"}.fa-bullseye:before{content:\"\\f140\"}.fa-ellipsis-h:before{content:\"\\f141\"}.fa-ellipsis-v:before{content:\"\\f142\"}.fa-rss-square:before{content:\"\\f143\"}.fa-play-circle:before{content:\"\\f144\"}.fa-ticket:before{content:\"\\f145\"}.fa-minus-square:before{content:\"\\f146\"}.fa-minus-square-o:before{content:\"\\f147\"}.fa-level-up:before{content:\"\\f148\"}.fa-level-down:before{content:\"\\f149\"}.fa-check-square:before{content:\"\\f14a\"}.fa-pencil-square:before{content:\"\\f14b\"}.fa-external-link-square:before{content:\"\\f14c\"}.fa-share-square:before{content:\"\\f14d\"}.fa-compass:before{content:\"\\f14e\"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:\"\\f150\"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:\"\\f151\"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:\"\\f152\"}.fa-eur:before,.fa-euro:before{content:\"\\f153\"}.fa-gbp:before{content:\"\\f154\"}.fa-dollar:before,.fa-usd:before{content:\"\\f155\"}.fa-inr:before,.fa-rupee:before{content:\"\\f156\"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:\"\\f157\"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:\"\\f158\"}.fa-krw:before,.fa-won:before{content:\"\\f159\"}.fa-bitcoin:before,.fa-btc:before{content:\"\\f15a\"}.fa-file:before{content:\"\\f15b\"}.fa-file-text:before{content:\"\\f15c\"}.fa-sort-alpha-asc:before{content:\"\\f15d\"}.fa-sort-alpha-desc:before{content:\"\\f15e\"}.fa-sort-amount-asc:before{content:\"\\f160\"}.fa-sort-amount-desc:before{content:\"\\f161\"}.fa-sort-numeric-asc:before{content:\"\\f162\"}.fa-sort-numeric-desc:before{content:\"\\f163\"}.fa-thumbs-up:before{content:\"\\f164\"}.fa-thumbs-down:before{content:\"\\f165\"}.fa-youtube-square:before{content:\"\\f166\"}.fa-youtube:before{content:\"\\f167\"}.fa-xing:before{content:\"\\f168\"}.fa-xing-square:before{content:\"\\f169\"}.fa-youtube-play:before{content:\"\\f16a\"}.fa-dropbox:before{content:\"\\f16b\"}.fa-stack-overflow:before{content:\"\\f16c\"}.fa-instagram:before{content:\"\\f16d\"}.fa-flickr:before{content:\"\\f16e\"}.fa-adn:before{content:\"\\f170\"}.fa-bitbucket:before{content:\"\\f171\"}.fa-bitbucket-square:before{content:\"\\f172\"}.fa-tumblr:before{content:\"\\f173\"}.fa-tumblr-square:before{content:\"\\f174\"}.fa-long-arrow-down:before{content:\"\\f175\"}.fa-long-arrow-up:before{content:\"\\f176\"}.fa-long-arrow-left:before{content:\"\\f177\"}.fa-long-arrow-right:before{content:\"\\f178\"}.fa-apple:before{content:\"\\f179\"}.fa-windows:before{content:\"\\f17a\"}.fa-android:before{content:\"\\f17b\"}.fa-linux:before{content:\"\\f17c\"}.fa-dribbble:before{content:\"\\f17d\"}.fa-skype:before{content:\"\\f17e\"}.fa-foursquare:before{content:\"\\f180\"}.fa-trello:before{content:\"\\f181\"}.fa-female:before{content:\"\\f182\"}.fa-male:before{content:\"\\f183\"}.fa-gittip:before,.fa-gratipay:before{content:\"\\f184\"}.fa-sun-o:before{content:\"\\f185\"}.fa-moon-o:before{content:\"\\f186\"}.fa-archive:before{content:\"\\f187\"}.fa-bug:before{content:\"\\f188\"}.fa-vk:before{content:\"\\f189\"}.fa-weibo:before{content:\"\\f18a\"}.fa-renren:before{content:\"\\f18b\"}.fa-pagelines:before{content:\"\\f18c\"}.fa-stack-exchange:before{content:\"\\f18d\"}.fa-arrow-circle-o-right:before{content:\"\\f18e\"}.fa-arrow-circle-o-left:before{content:\"\\f190\"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:\"\\f191\"}.fa-dot-circle-o:before{content:\"\\f192\"}.fa-wheelchair:before{content:\"\\f193\"}.fa-vimeo-square:before{content:\"\\f194\"}.fa-try:before,.fa-turkish-lira:before{content:\"\\f195\"}.fa-plus-square-o:before{content:\"\\f196\"}.fa-space-shuttle:before{content:\"\\f197\"}.fa-slack:before{content:\"\\f198\"}.fa-envelope-square:before{content:\"\\f199\"}.fa-wordpress:before{content:\"\\f19a\"}.fa-openid:before{content:\"\\f19b\"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:\"\\f19c\"}.fa-graduation-cap:before,.fa-mortar-board:before{content:\"\\f19d\"}.fa-yahoo:before{content:\"\\f19e\"}.fa-google:before{content:\"\\f1a0\"}.fa-reddit:before{content:\"\\f1a1\"}.fa-reddit-square:before{content:\"\\f1a2\"}.fa-stumbleupon-circle:before{content:\"\\f1a3\"}.fa-stumbleupon:before{content:\"\\f1a4\"}.fa-delicious:before{content:\"\\f1a5\"}.fa-digg:before{content:\"\\f1a6\"}.fa-pied-piper-pp:before{content:\"\\f1a7\"}.fa-pied-piper-alt:before{content:\"\\f1a8\"}.fa-drupal:before{content:\"\\f1a9\"}.fa-joomla:before{content:\"\\f1aa\"}.fa-language:before{content:\"\\f1ab\"}.fa-fax:before{content:\"\\f1ac\"}.fa-building:before{content:\"\\f1ad\"}.fa-child:before{content:\"\\f1ae\"}.fa-paw:before{content:\"\\f1b0\"}.fa-spoon:before{content:\"\\f1b1\"}.fa-cube:before{content:\"\\f1b2\"}.fa-cubes:before{content:\"\\f1b3\"}.fa-behance:before{content:\"\\f1b4\"}.fa-behance-square:before{content:\"\\f1b5\"}.fa-steam:before{content:\"\\f1b6\"}.fa-steam-square:before{content:\"\\f1b7\"}.fa-recycle:before{content:\"\\f1b8\"}.fa-automobile:before,.fa-car:before{content:\"\\f1b9\"}.fa-cab:before,.fa-taxi:before{content:\"\\f1ba\"}.fa-tree:before{content:\"\\f1bb\"}.fa-spotify:before{content:\"\\f1bc\"}.fa-deviantart:before{content:\"\\f1bd\"}.fa-soundcloud:before{content:\"\\f1be\"}.fa-database:before{content:\"\\f1c0\"}.fa-file-pdf-o:before{content:\"\\f1c1\"}.fa-file-word-o:before{content:\"\\f1c2\"}.fa-file-excel-o:before{content:\"\\f1c3\"}.fa-file-powerpoint-o:before{content:\"\\f1c4\"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:\"\\f1c5\"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:\"\\f1c6\"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:\"\\f1c7\"}.fa-file-movie-o:before,.fa-file-video-o:before{content:\"\\f1c8\"}.fa-file-code-o:before{content:\"\\f1c9\"}.fa-vine:before{content:\"\\f1ca\"}.fa-codepen:before{content:\"\\f1cb\"}.fa-jsfiddle:before{content:\"\\f1cc\"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:\"\\f1cd\"}.fa-circle-o-notch:before{content:\"\\f1ce\"}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:\"\\f1d0\"}.fa-empire:before,.fa-ge:before{content:\"\\f1d1\"}.fa-git-square:before{content:\"\\f1d2\"}.fa-git:before{content:\"\\f1d3\"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:\"\\f1d4\"}.fa-tencent-weibo:before{content:\"\\f1d5\"}.fa-qq:before{content:\"\\f1d6\"}.fa-wechat:before,.fa-weixin:before{content:\"\\f1d7\"}.fa-paper-plane:before,.fa-send:before{content:\"\\f1d8\"}.fa-paper-plane-o:before,.fa-send-o:before{content:\"\\f1d9\"}.fa-history:before{content:\"\\f1da\"}.fa-circle-thin:before{content:\"\\f1db\"}.fa-header:before{content:\"\\f1dc\"}.fa-paragraph:before{content:\"\\f1dd\"}.fa-sliders:before{content:\"\\f1de\"}.fa-share-alt:before{content:\"\\f1e0\"}.fa-share-alt-square:before{content:\"\\f1e1\"}.fa-bomb:before{content:\"\\f1e2\"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:\"\\f1e3\"}.fa-tty:before{content:\"\\f1e4\"}.fa-binoculars:before{content:\"\\f1e5\"}.fa-plug:before{content:\"\\f1e6\"}.fa-slideshare:before{content:\"\\f1e7\"}.fa-twitch:before{content:\"\\f1e8\"}.fa-yelp:before{content:\"\\f1e9\"}.fa-newspaper-o:before{content:\"\\f1ea\"}.fa-wifi:before{content:\"\\f1eb\"}.fa-calculator:before{content:\"\\f1ec\"}.fa-paypal:before{content:\"\\f1ed\"}.fa-google-wallet:before{content:\"\\f1ee\"}.fa-cc-visa:before{content:\"\\f1f0\"}.fa-cc-mastercard:before{content:\"\\f1f1\"}.fa-cc-discover:before{content:\"\\f1f2\"}.fa-cc-amex:before{content:\"\\f1f3\"}.fa-cc-paypal:before{content:\"\\f1f4\"}.fa-cc-stripe:before{content:\"\\f1f5\"}.fa-bell-slash:before{content:\"\\f1f6\"}.fa-bell-slash-o:before{content:\"\\f1f7\"}.fa-trash:before{content:\"\\f1f8\"}.fa-copyright:before{content:\"\\f1f9\"}.fa-at:before{content:\"\\f1fa\"}.fa-eyedropper:before{content:\"\\f1fb\"}.fa-paint-brush:before{content:\"\\f1fc\"}.fa-birthday-cake:before{content:\"\\f1fd\"}.fa-area-chart:before{content:\"\\f1fe\"}.fa-pie-chart:before{content:\"\\f200\"}.fa-line-chart:before{content:\"\\f201\"}.fa-lastfm:before{content:\"\\f202\"}.fa-lastfm-square:before{content:\"\\f203\"}.fa-toggle-off:before{content:\"\\f204\"}.fa-toggle-on:before{content:\"\\f205\"}.fa-bicycle:before{content:\"\\f206\"}.fa-bus:before{content:\"\\f207\"}.fa-ioxhost:before{content:\"\\f208\"}.fa-angellist:before{content:\"\\f209\"}.fa-cc:before{content:\"\\f20a\"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:\"\\f20b\"}.fa-meanpath:before{content:\"\\f20c\"}.fa-buysellads:before{content:\"\\f20d\"}.fa-connectdevelop:before{content:\"\\f20e\"}.fa-dashcube:before{content:\"\\f210\"}.fa-forumbee:before{content:\"\\f211\"}.fa-leanpub:before{content:\"\\f212\"}.fa-sellsy:before{content:\"\\f213\"}.fa-shirtsinbulk:before{content:\"\\f214\"}.fa-simplybuilt:before{content:\"\\f215\"}.fa-skyatlas:before{content:\"\\f216\"}.fa-cart-plus:before{content:\"\\f217\"}.fa-cart-arrow-down:before{content:\"\\f218\"}.fa-diamond:before{content:\"\\f219\"}.fa-ship:before{content:\"\\f21a\"}.fa-user-secret:before{content:\"\\f21b\"}.fa-motorcycle:before{content:\"\\f21c\"}.fa-street-view:before{content:\"\\f21d\"}.fa-heartbeat:before{content:\"\\f21e\"}.fa-venus:before{content:\"\\f221\"}.fa-mars:before{content:\"\\f222\"}.fa-mercury:before{content:\"\\f223\"}.fa-intersex:before,.fa-transgender:before{content:\"\\f224\"}.fa-transgender-alt:before{content:\"\\f225\"}.fa-venus-double:before{content:\"\\f226\"}.fa-mars-double:before{content:\"\\f227\"}.fa-venus-mars:before{content:\"\\f228\"}.fa-mars-stroke:before{content:\"\\f229\"}.fa-mars-stroke-v:before{content:\"\\f22a\"}.fa-mars-stroke-h:before{content:\"\\f22b\"}.fa-neuter:before{content:\"\\f22c\"}.fa-genderless:before{content:\"\\f22d\"}.fa-facebook-official:before{content:\"\\f230\"}.fa-pinterest-p:before{content:\"\\f231\"}.fa-whatsapp:before{content:\"\\f232\"}.fa-server:before{content:\"\\f233\"}.fa-user-plus:before{content:\"\\f234\"}.fa-user-times:before{content:\"\\f235\"}.fa-bed:before,.fa-hotel:before{content:\"\\f236\"}.fa-viacoin:before{content:\"\\f237\"}.fa-train:before{content:\"\\f238\"}.fa-subway:before{content:\"\\f239\"}.fa-medium:before{content:\"\\f23a\"}.fa-y-combinator:before,.fa-yc:before{content:\"\\f23b\"}.fa-optin-monster:before{content:\"\\f23c\"}.fa-opencart:before{content:\"\\f23d\"}.fa-expeditedssl:before{content:\"\\f23e\"}.fa-battery-4:before,.fa-battery-full:before{content:\"\\f240\"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:\"\\f241\"}.fa-battery-2:before,.fa-battery-half:before{content:\"\\f242\"}.fa-battery-1:before,.fa-battery-quarter:before{content:\"\\f243\"}.fa-battery-0:before,.fa-battery-empty:before{content:\"\\f244\"}.fa-mouse-pointer:before{content:\"\\f245\"}.fa-i-cursor:before{content:\"\\f246\"}.fa-object-group:before{content:\"\\f247\"}.fa-object-ungroup:before{content:\"\\f248\"}.fa-sticky-note:before{content:\"\\f249\"}.fa-sticky-note-o:before{content:\"\\f24a\"}.fa-cc-jcb:before{content:\"\\f24b\"}.fa-cc-diners-club:before{content:\"\\f24c\"}.fa-clone:before{content:\"\\f24d\"}.fa-balance-scale:before{content:\"\\f24e\"}.fa-hourglass-o:before{content:\"\\f250\"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:\"\\f251\"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:\"\\f252\"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:\"\\f253\"}.fa-hourglass:before{content:\"\\f254\"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:\"\\f255\"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:\"\\f256\"}.fa-hand-scissors-o:before{content:\"\\f257\"}.fa-hand-lizard-o:before{content:\"\\f258\"}.fa-hand-spock-o:before{content:\"\\f259\"}.fa-hand-pointer-o:before{content:\"\\f25a\"}.fa-hand-peace-o:before{content:\"\\f25b\"}.fa-trademark:before{content:\"\\f25c\"}.fa-registered:before{content:\"\\f25d\"}.fa-creative-commons:before{content:\"\\f25e\"}.fa-gg:before{content:\"\\f260\"}.fa-gg-circle:before{content:\"\\f261\"}.fa-tripadvisor:before{content:\"\\f262\"}.fa-odnoklassniki:before{content:\"\\f263\"}.fa-odnoklassniki-square:before{content:\"\\f264\"}.fa-get-pocket:before{content:\"\\f265\"}.fa-wikipedia-w:before{content:\"\\f266\"}.fa-safari:before{content:\"\\f267\"}.fa-chrome:before{content:\"\\f268\"}.fa-firefox:before{content:\"\\f269\"}.fa-opera:before{content:\"\\f26a\"}.fa-internet-explorer:before{content:\"\\f26b\"}.fa-television:before,.fa-tv:before{content:\"\\f26c\"}.fa-contao:before{content:\"\\f26d\"}.fa-500px:before{content:\"\\f26e\"}.fa-amazon:before{content:\"\\f270\"}.fa-calendar-plus-o:before{content:\"\\f271\"}.fa-calendar-minus-o:before{content:\"\\f272\"}.fa-calendar-times-o:before{content:\"\\f273\"}.fa-calendar-check-o:before{content:\"\\f274\"}.fa-industry:before{content:\"\\f275\"}.fa-map-pin:before{content:\"\\f276\"}.fa-map-signs:before{content:\"\\f277\"}.fa-map-o:before{content:\"\\f278\"}.fa-map:before{content:\"\\f279\"}.fa-commenting:before{content:\"\\f27a\"}.fa-commenting-o:before{content:\"\\f27b\"}.fa-houzz:before{content:\"\\f27c\"}.fa-vimeo:before{content:\"\\f27d\"}.fa-black-tie:before{content:\"\\f27e\"}.fa-fonticons:before{content:\"\\f280\"}.fa-reddit-alien:before{content:\"\\f281\"}.fa-edge:before{content:\"\\f282\"}.fa-credit-card-alt:before{content:\"\\f283\"}.fa-codiepie:before{content:\"\\f284\"}.fa-modx:before{content:\"\\f285\"}.fa-fort-awesome:before{content:\"\\f286\"}.fa-usb:before{content:\"\\f287\"}.fa-product-hunt:before{content:\"\\f288\"}.fa-mixcloud:before{content:\"\\f289\"}.fa-scribd:before{content:\"\\f28a\"}.fa-pause-circle:before{content:\"\\f28b\"}.fa-pause-circle-o:before{content:\"\\f28c\"}.fa-stop-circle:before{content:\"\\f28d\"}.fa-stop-circle-o:before{content:\"\\f28e\"}.fa-shopping-bag:before{content:\"\\f290\"}.fa-shopping-basket:before{content:\"\\f291\"}.fa-hashtag:before{content:\"\\f292\"}.fa-bluetooth:before{content:\"\\f293\"}.fa-bluetooth-b:before{content:\"\\f294\"}.fa-percent:before{content:\"\\f295\"}.fa-gitlab:before{content:\"\\f296\"}.fa-wpbeginner:before{content:\"\\f297\"}.fa-wpforms:before{content:\"\\f298\"}.fa-envira:before{content:\"\\f299\"}.fa-universal-access:before{content:\"\\f29a\"}.fa-wheelchair-alt:before{content:\"\\f29b\"}.fa-question-circle-o:before{content:\"\\f29c\"}.fa-blind:before{content:\"\\f29d\"}.fa-audio-description:before{content:\"\\f29e\"}.fa-volume-control-phone:before{content:\"\\f2a0\"}.fa-braille:before{content:\"\\f2a1\"}.fa-assistive-listening-systems:before{content:\"\\f2a2\"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:\"\\f2a3\"}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:\"\\f2a4\"}.fa-glide:before{content:\"\\f2a5\"}.fa-glide-g:before{content:\"\\f2a6\"}.fa-sign-language:before,.fa-signing:before{content:\"\\f2a7\"}.fa-low-vision:before{content:\"\\f2a8\"}.fa-viadeo:before{content:\"\\f2a9\"}.fa-viadeo-square:before{content:\"\\f2aa\"}.fa-snapchat:before{content:\"\\f2ab\"}.fa-snapchat-ghost:before{content:\"\\f2ac\"}.fa-snapchat-square:before{content:\"\\f2ad\"}.fa-pied-piper:before{content:\"\\f2ae\"}.fa-first-order:before{content:\"\\f2b0\"}.fa-yoast:before{content:\"\\f2b1\"}.fa-themeisle:before{content:\"\\f2b2\"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:\"\\f2b3\"}.fa-fa:before,.fa-font-awesome:before{content:\"\\f2b4\"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}/*!\n * Preboot v2\n *\n * Open sourced under MIT license by @mdo.\n * Some variables and mixins from Bootstrap (Apache 2 license).\n */.book-langs-index{width:100%;height:100%;padding:40px 0;margin:0;overflow:auto}@media (max-width:600px){.book-langs-index{padding:0}}.book-langs-index .inner{max-width:600px;width:100%;margin:0 auto;padding:30px;background:#fff;border-radius:3px}.book-langs-index .inner h3{margin:0}.book-langs-index .inner .languages{list-style:none;padding:20px 30px;margin-top:20px;border-top:1px solid #eee}.book-langs-index .inner .languages:after,.book-langs-index .inner .languages:before{content:\" \";display:table;line-height:0}.book-langs-index .inner .languages:after{clear:both}.book-langs-index .inner .languages li{width:50%;float:left;padding:10px 5px;font-size:16px}@media (max-width:600px){.book-langs-index .inner .languages li{width:100%;max-width:100%}}.book-header{font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;overflow:visible;height:50px;padding:0 8px;z-index:2;font-size:.85em;color:#7e888b;background:0 0}.book-header .btn{display:block;height:50px;padding:0 15px;border-bottom:none;color:#ccc;text-transform:uppercase;line-height:50px;-webkit-box-shadow:none!important;box-shadow:none!important;position:relative;font-size:14px}.book-header .btn:hover{position:relative;text-decoration:none;color:#444;background:0 0}.book-header .btn:focus{outline:0}.book-header h1{margin:0;font-size:20px;font-weight:200;text-align:center;line-height:50px;opacity:0;-webkit-transition:opacity ease .4s;-moz-transition:opacity ease .4s;-o-transition:opacity ease .4s;transition:opacity ease .4s;padding-left:200px;padding-right:200px;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;-o-transition:opacity .2s ease;transition:opacity .2s ease;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.book-header h1 a,.book-header h1 a:hover{color:inherit;text-decoration:none}@media (max-width:1000px){.book-header h1{display:none}}.book-header h1 i{display:none}.book-header:hover h1{opacity:1}.book.is-loading .book-header h1 i{display:inline-block}.book.is-loading .book-header h1 a{display:none}.dropdown{position:relative}.dropdown-menu{position:absolute;top:100%;left:0;z-index:100;display:none;float:left;min-width:160px;padding:0;margin:2px 0 0;list-style:none;font-size:14px;background-color:#fafafa;border:1px solid rgba(0,0,0,.07);border-radius:1px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu.open{display:block}.dropdown-menu.dropdown-left{left:auto;right:4%}.dropdown-menu.dropdown-left .dropdown-caret{right:14px;left:auto}.dropdown-menu .dropdown-caret{position:absolute;top:-8px;left:14px;width:18px;height:10px;float:left;overflow:hidden}.dropdown-menu .dropdown-caret .caret-outer{position:absolute;border-left:9px solid transparent;border-right:9px solid transparent;border-bottom:9px solid rgba(0,0,0,.1);height:auto;left:0;top:0;width:auto;display:inline-block;margin-left:-1px}.dropdown-menu .dropdown-caret .caret-inner{position:absolute;display:inline-block;margin-top:-1px;top:0;top:1px;border-left:9px solid transparent;border-right:9px solid transparent;border-bottom:9px solid #fafafa}.dropdown-menu .buttons{border-bottom:1px solid rgba(0,0,0,.07)}.dropdown-menu .buttons:after,.dropdown-menu .buttons:before{content:\" \";display:table;line-height:0}.dropdown-menu .buttons:after{clear:both}.dropdown-menu .buttons:last-child{border-bottom:none}.dropdown-menu .buttons .button{border:0;background-color:transparent;color:#a6a6a6;width:100%;text-align:center;float:left;line-height:1.42857143;padding:8px 4px}.dropdown-menu .buttons .button:hover{color:#444}.dropdown-menu .buttons .button:focus,.dropdown-menu .buttons .button:hover{outline:0}.dropdown-menu .buttons .button.size-2{width:50%}.dropdown-menu .buttons .button.size-3{width:33%}.book-summary{font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;position:absolute;top:0;left:-300px;bottom:0;z-index:1;overflow-y:auto;width:300px;color:#364149;background:#fafafa;border-right:1px solid rgba(0,0,0,.07);-webkit-transition:left 250ms ease;-moz-transition:left 250ms ease;-o-transition:left 250ms ease;transition:left 250ms ease}.book-summary ul.summary{list-style:none;margin:0;padding:0;-webkit-transition:top .5s ease;-moz-transition:top .5s ease;-o-transition:top .5s ease;transition:top .5s ease}.book-summary ul.summary li{list-style:none}.book-summary ul.summary li.header{padding:10px 15px;padding-top:20px;text-transform:uppercase;color:#939da3}.book-summary ul.summary li.divider{height:1px;margin:7px 0;overflow:hidden;background:rgba(0,0,0,.07)}.book-summary ul.summary li i.fa-check{display:none;position:absolute;right:9px;top:16px;font-size:9px;color:#3c3}.book-summary ul.summary li.done>a{color:#364149;font-weight:400}.book-summary ul.summary li.done>a i{display:inline}.book-summary ul.summary li a,.book-summary ul.summary li span{display:block;padding:10px 15px;border-bottom:none;color:#364149;background:0 0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;position:relative}.book-summary ul.summary li a:hover{text-decoration:underline}.book-summary ul.summary li a:focus{outline:0}.book-summary ul.summary li.active>a{color:#008cff;background:0 0;text-decoration:none}.book-summary ul.summary li ul{padding-left:20px}@media (max-width:600px){.book-summary{width:calc(100% - 60px);bottom:0;left:-100%}}.book.with-summary .book-summary{left:0}.book.without-animation .book-summary{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;transition:none!important}.book{position:relative;width:100%;height:100%}@media (min-width:600px){.book.with-summary .book-body{left:300px}}@media (max-width:600px){.book.with-summary{overflow:hidden}.book.with-summary .book-body{-webkit-transform:translate(calc(100% - 60px),0);-moz-transform:translate(calc(100% - 60px),0);-ms-transform:translate(calc(100% - 60px),0);-o-transform:translate(calc(100% - 60px),0);transform:translate(calc(100% - 60px),0)}}.book.without-animation .book-body{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;transition:none!important}.book-body{position:absolute;top:0;right:0;left:0;bottom:0;overflow-y:auto;color:#000;background:#fff;-webkit-transition:left 250ms ease;-moz-transition:left 250ms ease;-o-transition:left 250ms ease;transition:left 250ms ease}.book-body .body-inner{position:absolute;top:0;right:0;left:0;bottom:0;overflow-y:auto}@media (max-width:1240px){.book-body{-webkit-transition:-webkit-transform 250ms ease;-moz-transition:-moz-transform 250ms ease;-o-transition:-o-transform 250ms ease;transition:transform 250ms ease;padding-bottom:20px}.book-body .body-inner{position:static;min-height:calc(100% - 50px)}}.page-wrapper{position:relative;outline:0}.page-inner{position:relative;max-width:800px;margin:0 auto;padding:20px 15px 40px 15px}.page-inner .btn-group .btn{border-radius:0;background:#eee;border:0}.buttons:after,.buttons:before{content:\" \";display:table;line-height:0}.buttons:after{clear:both}.button{border:0;background-color:transparent;background:#eee;color:#666;width:100%;text-align:center;float:left;line-height:1.42857143;padding:8px 4px}.button:hover{color:#444}.button:focus,.button:hover{outline:0}.button.size-2{width:50%}.button.size-3{width:33%}.markdown-section{display:block;word-wrap:break-word;overflow:hidden;color:#333;line-height:1.7;text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%}.markdown-section *{box-sizing:border-box;-webkit-box-sizing:border-box;font-size:inherit}.markdown-section>:first-child{margin-top:0!important}.markdown-section>:last-child{margin-bottom:0!important}.markdown-section blockquote,.markdown-section code,.markdown-section figure,.markdown-section img,.markdown-section pre,.markdown-section table,.markdown-section tr{page-break-inside:avoid}.markdown-section h2,.markdown-section h3,.markdown-section h4,.markdown-section h5,.markdown-section p{orphans:3;widows:3}.markdown-section h1,.markdown-section h2,.markdown-section h3,.markdown-section h4,.markdown-section h5{page-break-after:avoid}.markdown-section b,.markdown-section strong{font-weight:700}.markdown-section em{font-style:italic}.markdown-section blockquote,.markdown-section dl,.markdown-section ol,.markdown-section p,.markdown-section table,.markdown-section ul{margin-top:0;margin-bottom:.85em}.markdown-section a{color:#4183c4;text-decoration:none;background:0 0}.markdown-section a:active,.markdown-section a:focus,.markdown-section a:hover{outline:0;text-decoration:underline}.markdown-section img{border:0;max-width:100%}.markdown-section hr{height:4px;padding:0;margin:1.7em 0;overflow:hidden;background-color:#e7e7e7;border:none}.markdown-section hr:after,.markdown-section hr:before{display:table;content:\" \"}.markdown-section hr:after{clear:both}.markdown-section h1,.markdown-section h2,.markdown-section h3,.markdown-section h4,.markdown-section h5,.markdown-section h6{margin-top:1.275em;margin-bottom:.85em;font-weight:700}.markdown-section h1{font-size:2em}.markdown-section h2{font-size:1.75em}.markdown-section h3{font-size:1.5em}.markdown-section h4{font-size:1.25em}.markdown-section h5{font-size:1em}.markdown-section h6{font-size:1em;color:#777}.markdown-section code,.markdown-section pre{font-family:Consolas,\"Liberation Mono\",Menlo,Courier,monospace;direction:ltr;margin:0;padding:0;border:none;color:inherit}.markdown-section pre{overflow:auto;word-wrap:normal;margin:0;padding:.85em 1em;margin-bottom:1.275em;background:#f7f7f7}.markdown-section pre>code{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;font-size:.85em;white-space:pre;background:0 0}.markdown-section pre>code:after,.markdown-section pre>code:before{content:normal}.markdown-section code{padding:.2em;margin:0;font-size:.85em;background-color:#f7f7f7}.markdown-section code:after,.markdown-section code:before{letter-spacing:-.2em;content:\"\\00a0\"}.markdown-section table{display:table;width:100%;border-collapse:collapse;border-spacing:0;overflow:auto}.markdown-section table td,.markdown-section table th{padding:6px 13px;border:1px solid #ddd}.markdown-section table tr{background-color:#fff;border-top:1px solid #ccc}.markdown-section table tr:nth-child(2n){background-color:#f8f8f8}.markdown-section table th{font-weight:700}.markdown-section ol,.markdown-section ul{padding:0;margin:0;margin-bottom:.85em;padding-left:2em}.markdown-section ol ol,.markdown-section ol ul,.markdown-section ul ol,.markdown-section ul ul{margin-top:0;margin-bottom:0}.markdown-section ol ol{list-style-type:lower-roman}.markdown-section blockquote{margin:0;margin-bottom:.85em;padding:0 15px;color:#858585;border-left:4px solid #e5e5e5}.markdown-section blockquote:first-child{margin-top:0}.markdown-section blockquote:last-child{margin-bottom:0}.markdown-section dl{padding:0}.markdown-section dl dt{padding:0;margin-top:.85em;font-style:italic;font-weight:700}.markdown-section dl dd{padding:0 .85em;margin-bottom:.85em}.markdown-section dd{margin-left:0}.markdown-section .glossary-term{cursor:help;text-decoration:underline}.navigation{position:absolute;top:50px;bottom:0;margin:0;max-width:150px;min-width:90px;display:flex;justify-content:center;align-content:center;flex-direction:column;font-size:40px;color:#ccc;text-align:center;-webkit-transition:all 350ms ease;-moz-transition:all 350ms ease;-o-transition:all 350ms ease;transition:all 350ms ease}.navigation:hover{text-decoration:none;color:#444}.navigation.navigation-next{right:0}.navigation.navigation-prev{left:0}@media (max-width:1240px){.navigation{position:static;top:auto;max-width:50%;width:50%;display:inline-block;float:left}.navigation.navigation-unique{max-width:100%;width:100%}}#book-search-input{padding:6px;background:0 0;transition:top .5s ease;background:#fff;border-bottom:1px solid rgba(0,0,0,.07);border-top:1px solid rgba(0,0,0,.07);margin-bottom:10px;margin-top:-1px}#book-search-input input,#book-search-input input:focus,#book-search-input input:hover{width:100%;background:0 0;border:1px solid transparent;box-shadow:none;outline:0;line-height:22px;padding:7px 7px;color:inherit}#book-search-results{opacity:1}#book-search-results .search-results .search-results-title{text-transform:uppercase;text-align:center;font-weight:200;margin-bottom:35px;opacity:.6}#book-search-results .search-results .has-results .search-results-item{display:block;word-wrap:break-word;overflow:hidden;color:#333;line-height:1.7;text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%}#book-search-results .search-results .has-results .search-results-item *{box-sizing:border-box;-webkit-box-sizing:border-box;font-size:inherit}#book-search-results .search-results .has-results .search-results-item>:first-child{margin-top:0!important}#book-search-results .search-results .has-results .search-results-item>:last-child{margin-bottom:0!important}#book-search-results .search-results .has-results .search-results-item blockquote,#book-search-results .search-results .has-results .search-results-item code,#book-search-results .search-results .has-results .search-results-item figure,#book-search-results .search-results .has-results .search-results-item img,#book-search-results .search-results .has-results .search-results-item pre,#book-search-results .search-results .has-results .search-results-item table,#book-search-results .search-results .has-results .search-results-item tr{page-break-inside:avoid}#book-search-results .search-results .has-results .search-results-item h2,#book-search-results .search-results .has-results .search-results-item h3,#book-search-results .search-results .has-results .search-results-item h4,#book-search-results .search-results .has-results .search-results-item h5,#book-search-results .search-results .has-results .search-results-item p{orphans:3;widows:3}#book-search-results .search-results .has-results .search-results-item h1,#book-search-results .search-results .has-results .search-results-item h2,#book-search-results .search-results .has-results .search-results-item h3,#book-search-results .search-results .has-results .search-results-item h4,#book-search-results .search-results .has-results .search-results-item h5{page-break-after:avoid}#book-search-results .search-results .has-results .search-results-item b,#book-search-results .search-results .has-results .search-results-item strong{font-weight:700}#book-search-results .search-results .has-results .search-results-item em{font-style:italic}#book-search-results .search-results .has-results .search-results-item blockquote,#book-search-results .search-results .has-results .search-results-item dl,#book-search-results .search-results .has-results .search-results-item ol,#book-search-results .search-results .has-results .search-results-item p,#book-search-results .search-results .has-results .search-results-item table,#book-search-results .search-results .has-results .search-results-item ul{margin-top:0;margin-bottom:.85em}#book-search-results .search-results .has-results .search-results-item a{color:#4183c4;text-decoration:none;background:0 0}#book-search-results .search-results .has-results .search-results-item a:active,#book-search-results .search-results .has-results .search-results-item a:focus,#book-search-results .search-results .has-results .search-results-item a:hover{outline:0;text-decoration:underline}#book-search-results .search-results .has-results .search-results-item img{border:0;max-width:100%}#book-search-results .search-results .has-results .search-results-item hr{height:4px;padding:0;margin:1.7em 0;overflow:hidden;background-color:#e7e7e7;border:none}#book-search-results .search-results .has-results .search-results-item hr:after,#book-search-results .search-results .has-results .search-results-item hr:before{display:table;content:\" \"}#book-search-results .search-results .has-results .search-results-item hr:after{clear:both}#book-search-results .search-results .has-results .search-results-item h1,#book-search-results .search-results .has-results .search-results-item h2,#book-search-results .search-results .has-results .search-results-item h3,#book-search-results .search-results .has-results .search-results-item h4,#book-search-results .search-results .has-results .search-results-item h5,#book-search-results .search-results .has-results .search-results-item h6{margin-top:1.275em;margin-bottom:.85em;font-weight:700}#book-search-results .search-results .has-results .search-results-item h1{font-size:2em}#book-search-results .search-results .has-results .search-results-item h2{font-size:1.75em}#book-search-results .search-results .has-results .search-results-item h3{font-size:1.5em}#book-search-results .search-results .has-results .search-results-item h4{font-size:1.25em}#book-search-results .search-results .has-results .search-results-item h5{font-size:1em}#book-search-results .search-results .has-results .search-results-item h6{font-size:1em;color:#777}#book-search-results .search-results .has-results .search-results-item code,#book-search-results .search-results .has-results .search-results-item pre{font-family:Consolas,\"Liberation Mono\",Menlo,Courier,monospace;direction:ltr;margin:0;padding:0;border:none;color:inherit}#book-search-results .search-results .has-results .search-results-item pre{overflow:auto;word-wrap:normal;margin:0;padding:.85em 1em;margin-bottom:1.275em;background:#f7f7f7}#book-search-results .search-results .has-results .search-results-item pre>code{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;font-size:.85em;white-space:pre;background:0 0}#book-search-results .search-results .has-results .search-results-item pre>code:after,#book-search-results .search-results .has-results .search-results-item pre>code:before{content:normal}#book-search-results .search-results .has-results .search-results-item code{padding:.2em;margin:0;font-size:.85em;background-color:#f7f7f7}#book-search-results .search-results .has-results .search-results-item code:after,#book-search-results .search-results .has-results .search-results-item code:before{letter-spacing:-.2em;content:\"\\00a0\"}#book-search-results .search-results .has-results .search-results-item table{display:table;width:100%;border-collapse:collapse;border-spacing:0;overflow:auto}#book-search-results .search-results .has-results .search-results-item table td,#book-search-results .search-results .has-results .search-results-item table th{padding:6px 13px;border:1px solid #ddd}#book-search-results .search-results .has-results .search-results-item table tr{background-color:#fff;border-top:1px solid #ccc}#book-search-results .search-results .has-results .search-results-item table tr:nth-child(2n){background-color:#f8f8f8}#book-search-results .search-results .has-results .search-results-item table th{font-weight:700}#book-search-results .search-results .has-results .search-results-item ol,#book-search-results .search-results .has-results .search-results-item ul{padding:0;margin:0;margin-bottom:.85em;padding-left:2em}#book-search-results .search-results .has-results .search-results-item ol ol,#book-search-results .search-results .has-results .search-results-item ol ul,#book-search-results .search-results .has-results .search-results-item ul ol,#book-search-results .search-results .has-results .search-results-item ul ul{margin-top:0;margin-bottom:0}#book-search-results .search-results .has-results .search-results-item ol ol{list-style-type:lower-roman}#book-search-results .search-results .has-results .search-results-item blockquote{margin:0;margin-bottom:.85em;padding:0 15px;color:#858585;border-left:4px solid #e5e5e5}#book-search-results .search-results .has-results .search-results-item blockquote:first-child{margin-top:0}#book-search-results .search-results .has-results .search-results-item blockquote:last-child{margin-bottom:0}#book-search-results .search-results .has-results .search-results-item dl{padding:0}#book-search-results .search-results .has-results .search-results-item dl dt{padding:0;margin-top:.85em;font-style:italic;font-weight:700}#book-search-results .search-results .has-results .search-results-item dl dd{padding:0 .85em;margin-bottom:.85em}#book-search-results .search-results .has-results .search-results-item dd{margin-left:0}#book-search-results .search-results .has-results .search-results-item h3{margin-top:0;margin-bottom:0}#book-search-results .search-results .no-results{padding:40px 0}body.search-loading #book-search-results{opacity:.3}body.with-search .navigation{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:none;-webkit-touch-callout:none;-webkit-font-smoothing:antialiased}a{text-decoration:none}body,html{height:100%}html{font-size:62.5%}body{text-rendering:optimizeLegibility;font-smoothing:antialiased;font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:.2px;text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}"
  },
  {
    "path": "atlas-docs/_book/gitbook/theme.js",
    "content": "!function e(t,n,r){function o(a,s){if(!n[a]){if(!t[a]){var u=\"function\"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);var l=new Error(\"Cannot find module '\"+a+\"'\");throw l.code=\"MODULE_NOT_FOUND\",l}var c=n[a]={exports:{}};t[a][0].call(c.exports,function(e){var n=t[a][1][e];return o(n?n:e)},c,c.exports,e,t,n,r)}return n[a].exports}for(var i=\"function\"==typeof require&&require,a=0;a<r.length;a++)o(r[a]);return o}({1:[function(e,t,n){!function(e,n){\"use strict\";\"object\"==typeof t&&\"object\"==typeof t.exports?t.exports=e.document?n(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return n(e)}:n(e)}(\"undefined\"!=typeof window?window:this,function(e,t){\"use strict\";function n(e,t){t=t||te;var n=t.createElement(\"script\");n.text=e,t.head.appendChild(n).parentNode.removeChild(n)}function r(e){var t=!!e&&\"length\"in e&&e.length,n=de.type(e);return\"function\"!==n&&!de.isWindow(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&t>0&&t-1 in e)}function o(e,t,n){return de.isFunction(t)?de.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?de.grep(e,function(e){return e===t!==n}):\"string\"!=typeof t?de.grep(e,function(e){return ae.call(t,e)>-1!==n}):ke.test(t)?de.filter(t,e,n):(t=de.filter(t,e),de.grep(e,function(e){return ae.call(t,e)>-1!==n&&1===e.nodeType}))}function i(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function a(e){var t={};return de.each(e.match(qe)||[],function(e,n){t[n]=!0}),t}function s(e){return e}function u(e){throw e}function l(e,t,n){var r;try{e&&de.isFunction(r=e.promise)?r.call(e).done(t).fail(n):e&&de.isFunction(r=e.then)?r.call(e,t,n):t.call(void 0,e)}catch(e){n.call(void 0,e)}}function c(){te.removeEventListener(\"DOMContentLoaded\",c),e.removeEventListener(\"load\",c),de.ready()}function f(){this.expando=de.expando+f.uid++}function p(e){return\"true\"===e||\"false\"!==e&&(\"null\"===e?null:e===+e+\"\"?+e:Ie.test(e)?JSON.parse(e):e)}function h(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r=\"data-\"+t.replace(Re,\"-$&\").toLowerCase(),n=e.getAttribute(r),\"string\"==typeof n){try{n=p(n)}catch(e){}Pe.set(e,t,n)}else n=void 0;return n}function d(e,t,n,r){var o,i=1,a=20,s=r?function(){return r.cur()}:function(){return de.css(e,t,\"\")},u=s(),l=n&&n[3]||(de.cssNumber[t]?\"\":\"px\"),c=(de.cssNumber[t]||\"px\"!==l&&+u)&&$e.exec(de.css(e,t));if(c&&c[3]!==l){l=l||c[3],n=n||[],c=+u||1;do i=i||\".5\",c/=i,de.style(e,t,c+l);while(i!==(i=s()/u)&&1!==i&&--a)}return n&&(c=+c||+u||0,o=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=o)),o}function g(e){var t,n=e.ownerDocument,r=e.nodeName,o=Ue[r];return o?o:(t=n.body.appendChild(n.createElement(r)),o=de.css(t,\"display\"),t.parentNode.removeChild(t),\"none\"===o&&(o=\"block\"),Ue[r]=o,o)}function m(e,t){for(var n,r,o=[],i=0,a=e.length;i<a;i++)r=e[i],r.style&&(n=r.style.display,t?(\"none\"===n&&(o[i]=Fe.get(r,\"display\")||null,o[i]||(r.style.display=\"\")),\"\"===r.style.display&&We(r)&&(o[i]=g(r))):\"none\"!==n&&(o[i]=\"none\",Fe.set(r,\"display\",n)));for(i=0;i<a;i++)null!=o[i]&&(e[i].style.display=o[i]);return e}function v(e,t){var n;return n=\"undefined\"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):\"undefined\"!=typeof e.querySelectorAll?e.querySelectorAll(t||\"*\"):[],void 0===t||t&&de.nodeName(e,t)?de.merge([e],n):n}function y(e,t){for(var n=0,r=e.length;n<r;n++)Fe.set(e[n],\"globalEval\",!t||Fe.get(t[n],\"globalEval\"))}function b(e,t,n,r,o){for(var i,a,s,u,l,c,f=t.createDocumentFragment(),p=[],h=0,d=e.length;h<d;h++)if(i=e[h],i||0===i)if(\"object\"===de.type(i))de.merge(p,i.nodeType?[i]:i);else if(Ge.test(i)){for(a=a||f.appendChild(t.createElement(\"div\")),s=(Xe.exec(i)||[\"\",\"\"])[1].toLowerCase(),u=Ve[s]||Ve._default,a.innerHTML=u[1]+de.htmlPrefilter(i)+u[2],c=u[0];c--;)a=a.lastChild;de.merge(p,a.childNodes),a=f.firstChild,a.textContent=\"\"}else p.push(t.createTextNode(i));for(f.textContent=\"\",h=0;i=p[h++];)if(r&&de.inArray(i,r)>-1)o&&o.push(i);else if(l=de.contains(i.ownerDocument,i),a=v(f.appendChild(i),\"script\"),l&&y(a),n)for(c=0;i=a[c++];)Ke.test(i.type||\"\")&&n.push(i);return f}function x(){return!0}function w(){return!1}function C(){try{return te.activeElement}catch(e){}}function T(e,t,n,r,o,i){var a,s;if(\"object\"==typeof t){\"string\"!=typeof n&&(r=r||n,n=void 0);for(s in t)T(e,s,n,r,t[s],i);return e}if(null==r&&null==o?(o=n,r=n=void 0):null==o&&(\"string\"==typeof n?(o=r,r=void 0):(o=r,r=n,n=void 0)),o===!1)o=w;else if(!o)return e;return 1===i&&(a=o,o=function(e){return de().off(e),a.apply(this,arguments)},o.guid=a.guid||(a.guid=de.guid++)),e.each(function(){de.event.add(this,t,o,r,n)})}function k(e,t){return de.nodeName(e,\"table\")&&de.nodeName(11!==t.nodeType?t:t.firstChild,\"tr\")?e.getElementsByTagName(\"tbody\")[0]||e:e}function j(e){return e.type=(null!==e.getAttribute(\"type\"))+\"/\"+e.type,e}function E(e){var t=rt.exec(e.type);return t?e.type=t[1]:e.removeAttribute(\"type\"),e}function N(e,t){var n,r,o,i,a,s,u,l;if(1===t.nodeType){if(Fe.hasData(e)&&(i=Fe.access(e),a=Fe.set(t,i),l=i.events)){delete a.handle,a.events={};for(o in l)for(n=0,r=l[o].length;n<r;n++)de.event.add(t,o,l[o][n])}Pe.hasData(e)&&(s=Pe.access(e),u=de.extend({},s),Pe.set(t,u))}}function S(e,t){var n=t.nodeName.toLowerCase();\"input\"===n&&ze.test(e.type)?t.checked=e.checked:\"input\"!==n&&\"textarea\"!==n||(t.defaultValue=e.defaultValue)}function A(e,t,r,o){t=oe.apply([],t);var i,a,s,u,l,c,f=0,p=e.length,h=p-1,d=t[0],g=de.isFunction(d);if(g||p>1&&\"string\"==typeof d&&!pe.checkClone&&nt.test(d))return e.each(function(n){var i=e.eq(n);g&&(t[0]=d.call(this,n,i.html())),A(i,t,r,o)});if(p&&(i=b(t,e[0].ownerDocument,!1,e,o),a=i.firstChild,1===i.childNodes.length&&(i=a),a||o)){for(s=de.map(v(i,\"script\"),j),u=s.length;f<p;f++)l=i,f!==h&&(l=de.clone(l,!0,!0),u&&de.merge(s,v(l,\"script\"))),r.call(e[f],l,f);if(u)for(c=s[s.length-1].ownerDocument,de.map(s,E),f=0;f<u;f++)l=s[f],Ke.test(l.type||\"\")&&!Fe.access(l,\"globalEval\")&&de.contains(c,l)&&(l.src?de._evalUrl&&de._evalUrl(l.src):n(l.textContent.replace(ot,\"\"),c))}return e}function q(e,t,n){for(var r,o=t?de.filter(t,e):e,i=0;null!=(r=o[i]);i++)n||1!==r.nodeType||de.cleanData(v(r)),r.parentNode&&(n&&de.contains(r.ownerDocument,r)&&y(v(r,\"script\")),r.parentNode.removeChild(r));return e}function D(e,t,n){var r,o,i,a,s=e.style;return n=n||st(e),n&&(a=n.getPropertyValue(t)||n[t],\"\"!==a||de.contains(e.ownerDocument,e)||(a=de.style(e,t)),!pe.pixelMarginRight()&&at.test(a)&&it.test(t)&&(r=s.width,o=s.minWidth,i=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=o,s.maxWidth=i)),void 0!==a?a+\"\":a}function O(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function L(e){if(e in pt)return e;for(var t=e[0].toUpperCase()+e.slice(1),n=ft.length;n--;)if(e=ft[n]+t,e in pt)return e}function H(e,t,n){var r=$e.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||\"px\"):t}function F(e,t,n,r,o){var i,a=0;for(i=n===(r?\"border\":\"content\")?4:\"width\"===t?1:0;i<4;i+=2)\"margin\"===n&&(a+=de.css(e,n+_e[i],!0,o)),r?(\"content\"===n&&(a-=de.css(e,\"padding\"+_e[i],!0,o)),\"margin\"!==n&&(a-=de.css(e,\"border\"+_e[i]+\"Width\",!0,o))):(a+=de.css(e,\"padding\"+_e[i],!0,o),\"padding\"!==n&&(a+=de.css(e,\"border\"+_e[i]+\"Width\",!0,o)));return a}function P(e,t,n){var r,o=!0,i=st(e),a=\"border-box\"===de.css(e,\"boxSizing\",!1,i);if(e.getClientRects().length&&(r=e.getBoundingClientRect()[t]),r<=0||null==r){if(r=D(e,t,i),(r<0||null==r)&&(r=e.style[t]),at.test(r))return r;o=a&&(pe.boxSizingReliable()||r===e.style[t]),r=parseFloat(r)||0}return r+F(e,t,n||(a?\"border\":\"content\"),o,i)+\"px\"}function I(e,t,n,r,o){return new I.prototype.init(e,t,n,r,o)}function R(){dt&&(e.requestAnimationFrame(R),de.fx.tick())}function M(){return e.setTimeout(function(){ht=void 0}),ht=de.now()}function $(e,t){var n,r=0,o={height:e};for(t=t?1:0;r<4;r+=2-t)n=_e[r],o[\"margin\"+n]=o[\"padding\"+n]=e;return t&&(o.opacity=o.width=e),o}function _(e,t,n){for(var r,o=(U.tweeners[t]||[]).concat(U.tweeners[\"*\"]),i=0,a=o.length;i<a;i++)if(r=o[i].call(n,t,e))return r}function W(e,t,n){var r,o,i,a,s,u,l,c,f=\"width\"in t||\"height\"in t,p=this,h={},d=e.style,g=e.nodeType&&We(e),v=Fe.get(e,\"fxshow\");n.queue||(a=de._queueHooks(e,\"fx\"),null==a.unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,de.queue(e,\"fx\").length||a.empty.fire()})}));for(r in t)if(o=t[r],gt.test(o)){if(delete t[r],i=i||\"toggle\"===o,o===(g?\"hide\":\"show\")){if(\"show\"!==o||!v||void 0===v[r])continue;g=!0}h[r]=v&&v[r]||de.style(e,r)}if(u=!de.isEmptyObject(t),u||!de.isEmptyObject(h)){f&&1===e.nodeType&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],l=v&&v.display,null==l&&(l=Fe.get(e,\"display\")),c=de.css(e,\"display\"),\"none\"===c&&(l?c=l:(m([e],!0),l=e.style.display||l,c=de.css(e,\"display\"),m([e]))),(\"inline\"===c||\"inline-block\"===c&&null!=l)&&\"none\"===de.css(e,\"float\")&&(u||(p.done(function(){d.display=l}),null==l&&(c=d.display,l=\"none\"===c?\"\":c)),d.display=\"inline-block\")),n.overflow&&(d.overflow=\"hidden\",p.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]})),u=!1;for(r in h)u||(v?\"hidden\"in v&&(g=v.hidden):v=Fe.access(e,\"fxshow\",{display:l}),i&&(v.hidden=!g),g&&m([e],!0),p.done(function(){g||m([e]),Fe.remove(e,\"fxshow\");for(r in h)de.style(e,r,h[r])})),u=_(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}}function B(e,t){var n,r,o,i,a;for(n in e)if(r=de.camelCase(n),o=t[r],i=e[n],de.isArray(i)&&(o=i[1],i=e[n]=i[0]),n!==r&&(e[r]=i,delete e[n]),a=de.cssHooks[r],a&&\"expand\"in a){i=a.expand(i),delete e[r];for(n in i)n in e||(e[n]=i[n],t[n]=o)}else t[r]=o}function U(e,t,n){var r,o,i=0,a=U.prefilters.length,s=de.Deferred().always(function(){delete u.elem}),u=function(){if(o)return!1;for(var t=ht||M(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,i=1-r,a=0,u=l.tweens.length;a<u;a++)l.tweens[a].run(i);return s.notifyWith(e,[l,i,n]),i<1&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:de.extend({},t),opts:de.extend(!0,{specialEasing:{},easing:de.easing._default},n),originalProperties:t,originalOptions:n,startTime:ht||M(),duration:n.duration,tweens:[],createTween:function(t,n){var r=de.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(o)return this;for(o=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(B(c,l.opts.specialEasing);i<a;i++)if(r=U.prefilters[i].call(l,e,c,l.opts))return de.isFunction(r.stop)&&(de._queueHooks(l.elem,l.opts.queue).stop=de.proxy(r.stop,r)),r;return de.map(c,_,l),de.isFunction(l.opts.start)&&l.opts.start.call(e,l),de.fx.timer(de.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function z(e){var t=e.match(qe)||[];return t.join(\" \")}function X(e){return e.getAttribute&&e.getAttribute(\"class\")||\"\"}function K(e,t,n,r){var o;if(de.isArray(t))de.each(t,function(t,o){n||Et.test(e)?r(e,o):K(e+\"[\"+(\"object\"==typeof o&&null!=o?t:\"\")+\"]\",o,n,r)});else if(n||\"object\"!==de.type(t))r(e,t);else for(o in t)K(e+\"[\"+o+\"]\",t[o],n,r)}function V(e){return function(t,n){\"string\"!=typeof t&&(n=t,t=\"*\");var r,o=0,i=t.toLowerCase().match(qe)||[];if(de.isFunction(n))for(;r=i[o++];)\"+\"===r[0]?(r=r.slice(1)||\"*\",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function G(e,t,n,r){function o(s){var u;return i[s]=!0,de.each(e[s]||[],function(e,s){var l=s(t,n,r);return\"string\"!=typeof l||a||i[l]?a?!(u=l):void 0:(t.dataTypes.unshift(l),o(l),!1)}),u}var i={},a=e===Rt;return o(t.dataTypes[0])||!i[\"*\"]&&o(\"*\")}function Y(e,t){var n,r,o=de.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((o[n]?e:r||(r={}))[n]=t[n]);return r&&de.extend(!0,e,r),e}function Q(e,t,n){for(var r,o,i,a,s=e.contents,u=e.dataTypes;\"*\"===u[0];)u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader(\"Content-Type\"));if(r)for(o in s)if(s[o]&&s[o].test(r)){u.unshift(o);break}if(u[0]in n)i=u[0];else{for(o in n){if(!u[0]||e.converters[o+\" \"+u[0]]){i=o;break}a||(a=o)}i=i||a}if(i)return i!==u[0]&&u.unshift(i),n[i]}function J(e,t,n,r){var o,i,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(i=c.shift();i;)if(e.responseFields[i]&&(n[e.responseFields[i]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=i,i=c.shift())if(\"*\"===i)i=u;else if(\"*\"!==u&&u!==i){if(a=l[u+\" \"+i]||l[\"* \"+i],!a)for(o in l)if(s=o.split(\" \"),s[1]===i&&(a=l[u+\" \"+s[0]]||l[\"* \"+s[0]])){a===!0?a=l[o]:l[o]!==!0&&(i=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:\"parsererror\",error:a?e:\"No conversion from \"+u+\" to \"+i}}}return{state:\"success\",data:t}}function Z(e){return de.isWindow(e)?e:9===e.nodeType&&e.defaultView}var ee=[],te=e.document,ne=Object.getPrototypeOf,re=ee.slice,oe=ee.concat,ie=ee.push,ae=ee.indexOf,se={},ue=se.toString,le=se.hasOwnProperty,ce=le.toString,fe=ce.call(Object),pe={},he=\"3.1.1\",de=function(e,t){return new de.fn.init(e,t)},ge=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,me=/^-ms-/,ve=/-([a-z])/g,ye=function(e,t){return t.toUpperCase()};de.fn=de.prototype={jquery:he,constructor:de,length:0,toArray:function(){return re.call(this)},get:function(e){return null==e?re.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=de.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return de.each(this,e)},map:function(e){return this.pushStack(de.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(re.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:ie,sort:ee.sort,splice:ee.splice},de.extend=de.fn.extend=function(){var e,t,n,r,o,i,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for(\"boolean\"==typeof a&&(l=a,a=arguments[s]||{},s++),\"object\"==typeof a||de.isFunction(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],r=e[t],a!==r&&(l&&r&&(de.isPlainObject(r)||(o=de.isArray(r)))?(o?(o=!1,i=n&&de.isArray(n)?n:[]):i=n&&de.isPlainObject(n)?n:{},a[t]=de.extend(l,i,r)):void 0!==r&&(a[t]=r));return a},de.extend({expando:\"jQuery\"+(he+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isFunction:function(e){return\"function\"===de.type(e)},isArray:Array.isArray,isWindow:function(e){return null!=e&&e===e.window},isNumeric:function(e){var t=de.type(e);return(\"number\"===t||\"string\"===t)&&!isNaN(e-parseFloat(e))},isPlainObject:function(e){var t,n;return!(!e||\"[object Object]\"!==ue.call(e))&&(!(t=ne(e))||(n=le.call(t,\"constructor\")&&t.constructor,\"function\"==typeof n&&ce.call(n)===fe))},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},type:function(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?se[ue.call(e)]||\"object\":typeof e},globalEval:function(e){n(e)},camelCase:function(e){return e.replace(me,\"ms-\").replace(ve,ye)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var n,o=0;if(r(e))for(n=e.length;o<n&&t.call(e[o],o,e[o])!==!1;o++);else for(o in e)if(t.call(e[o],o,e[o])===!1)break;return e},trim:function(e){return null==e?\"\":(e+\"\").replace(ge,\"\")},makeArray:function(e,t){var n=t||[];return null!=e&&(r(Object(e))?de.merge(n,\"string\"==typeof e?[e]:e):ie.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:ae.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,o=e.length;r<n;r++)e[o++]=t[r];return e.length=o,e},grep:function(e,t,n){for(var r,o=[],i=0,a=e.length,s=!n;i<a;i++)r=!t(e[i],i),r!==s&&o.push(e[i]);return o},map:function(e,t,n){var o,i,a=0,s=[];if(r(e))for(o=e.length;a<o;a++)i=t(e[a],a,n),null!=i&&s.push(i);else for(a in e)i=t(e[a],a,n),null!=i&&s.push(i);return oe.apply([],s)},guid:1,proxy:function(e,t){var n,r,o;if(\"string\"==typeof t&&(n=e[t],t=e,e=n),de.isFunction(e))return r=re.call(arguments,2),o=function(){return e.apply(t||this,r.concat(re.call(arguments)))},o.guid=e.guid=e.guid||de.guid++,o},now:Date.now,support:pe}),\"function\"==typeof Symbol&&(de.fn[Symbol.iterator]=ee[Symbol.iterator]),de.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(e,t){se[\"[object \"+t+\"]\"]=t.toLowerCase()});var be=function(e){function t(e,t,n,r){var o,i,a,s,u,l,c,p=t&&t.ownerDocument,d=t?t.nodeType:9;if(n=n||[],\"string\"!=typeof e||!e||1!==d&&9!==d&&11!==d)return n;if(!r&&((t?t.ownerDocument||t:_)!==L&&O(t),t=t||L,F)){if(11!==d&&(u=ve.exec(e)))if(o=u[1]){if(9===d){if(!(a=t.getElementById(o)))return n;if(a.id===o)return n.push(a),n}else if(p&&(a=p.getElementById(o))&&M(t,a)&&a.id===o)return n.push(a),n}else{if(u[2])return J.apply(n,t.getElementsByTagName(e)),n;if((o=u[3])&&C.getElementsByClassName&&t.getElementsByClassName)return J.apply(n,t.getElementsByClassName(o)),n}if(C.qsa&&!X[e+\" \"]&&(!P||!P.test(e))){if(1!==d)p=t,c=e;else if(\"object\"!==t.nodeName.toLowerCase()){for((s=t.getAttribute(\"id\"))?s=s.replace(we,Ce):t.setAttribute(\"id\",s=$),l=E(e),i=l.length;i--;)l[i]=\"#\"+s+\" \"+h(l[i]);c=l.join(\",\"),p=ye.test(e)&&f(t.parentNode)||t}if(c)try{return J.apply(n,p.querySelectorAll(c)),n}catch(e){}finally{s===$&&t.removeAttribute(\"id\")}}}return S(e.replace(se,\"$1\"),t,n,r)}function n(){function e(n,r){return t.push(n+\" \")>T.cacheLength&&delete e[t.shift()],e[n+\" \"]=r}var t=[];return e}function r(e){return e[$]=!0,e}function o(e){var t=L.createElement(\"fieldset\");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function i(e,t){for(var n=e.split(\"|\"),r=n.length;r--;)T.attrHandle[n[r]]=t}function a(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){var n=t.nodeName.toLowerCase();return\"input\"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return(\"input\"===n||\"button\"===n)&&t.type===e}}function l(e){return function(t){return\"form\"in t?t.parentNode&&t.disabled===!1?\"label\"in t?\"label\"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ke(t)===e:t.disabled===e:\"label\"in t&&t.disabled===e}}function c(e){return r(function(t){return t=+t,r(function(n,r){for(var o,i=e([],n.length,t),a=i.length;a--;)n[o=i[a]]&&(n[o]=!(r[o]=n[o]))})})}function f(e){return e&&\"undefined\"!=typeof e.getElementsByTagName&&e}function p(){}function h(e){for(var t=0,n=e.length,r=\"\";t<n;t++)r+=e[t].value;return r}function d(e,t,n){var r=t.dir,o=t.next,i=o||r,a=n&&\"parentNode\"===i,s=B++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||a)return e(t,n,o);return!1}:function(t,n,u){var l,c,f,p=[W,s];if(u){for(;t=t[r];)if((1===t.nodeType||a)&&e(t,n,u))return!0}else for(;t=t[r];)if(1===t.nodeType||a)if(f=t[$]||(t[$]={}),c=f[t.uniqueID]||(f[t.uniqueID]={}),o&&o===t.nodeName.toLowerCase())t=t[r]||t;else{if((l=c[i])&&l[0]===W&&l[1]===s)return p[2]=l[2];if(c[i]=p,p[2]=e(t,n,u))return!0}return!1}}function g(e){return e.length>1?function(t,n,r){for(var o=e.length;o--;)if(!e[o](t,n,r))return!1;return!0}:e[0]}function m(e,n,r){for(var o=0,i=n.length;o<i;o++)t(e,n[o],r);return r}function v(e,t,n,r,o){for(var i,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(i=e[s])&&(n&&!n(i,r,o)||(a.push(i),l&&t.push(s)));return a}function y(e,t,n,o,i,a){return o&&!o[$]&&(o=y(o)),i&&!i[$]&&(i=y(i,a)),r(function(r,a,s,u){var l,c,f,p=[],h=[],d=a.length,g=r||m(t||\"*\",s.nodeType?[s]:s,[]),y=!e||!r&&t?g:v(g,p,e,s,u),b=n?i||(r?e:d||o)?[]:a:y;if(n&&n(y,b,s,u),o)for(l=v(b,h),o(l,[],s,u),c=l.length;c--;)(f=l[c])&&(b[h[c]]=!(y[h[c]]=f));if(r){if(i||e){if(i){for(l=[],c=b.length;c--;)(f=b[c])&&l.push(y[c]=f);i(null,b=[],l,u)}for(c=b.length;c--;)(f=b[c])&&(l=i?ee(r,f):p[c])>-1&&(r[l]=!(a[l]=f))}}else b=v(b===a?b.splice(d,b.length):b),i?i(null,a,b,u):J.apply(a,b)})}function b(e){for(var t,n,r,o=e.length,i=T.relative[e[0].type],a=i||T.relative[\" \"],s=i?1:0,u=d(function(e){return e===t},a,!0),l=d(function(e){return ee(t,e)>-1},a,!0),c=[function(e,n,r){var o=!i&&(r||n!==A)||((t=n).nodeType?u(e,n,r):l(e,n,r));return t=null,o}];s<o;s++)if(n=T.relative[e[s].type])c=[d(g(c),n)];else{if(n=T.filter[e[s].type].apply(null,e[s].matches),n[$]){for(r=++s;r<o&&!T.relative[e[r].type];r++);return y(s>1&&g(c),s>1&&h(e.slice(0,s-1).concat({value:\" \"===e[s-2].type?\"*\":\"\"})).replace(se,\"$1\"),n,s<r&&b(e.slice(s,r)),r<o&&b(e=e.slice(r)),r<o&&h(e))}c.push(n)}return g(c)}function x(e,n){var o=n.length>0,i=e.length>0,a=function(r,a,s,u,l){var c,f,p,h=0,d=\"0\",g=r&&[],m=[],y=A,b=r||i&&T.find.TAG(\"*\",l),x=W+=null==y?1:Math.random()||.1,w=b.length;for(l&&(A=a===L||a||l);d!==w&&null!=(c=b[d]);d++){if(i&&c){for(f=0,a||c.ownerDocument===L||(O(c),s=!F);p=e[f++];)if(p(c,a||L,s)){u.push(c);break}l&&(W=x)}o&&((c=!p&&c)&&h--,r&&g.push(c))}if(h+=d,o&&d!==h){for(f=0;p=n[f++];)p(g,m,a,s);if(r){if(h>0)for(;d--;)g[d]||m[d]||(m[d]=Y.call(u));m=v(m)}J.apply(u,m),l&&!r&&m.length>0&&h+n.length>1&&t.uniqueSort(u)}return l&&(W=x,A=y),g};return o?r(a):a}var w,C,T,k,j,E,N,S,A,q,D,O,L,H,F,P,I,R,M,$=\"sizzle\"+1*new Date,_=e.document,W=0,B=0,U=n(),z=n(),X=n(),K=function(e,t){return e===t&&(D=!0),0},V={}.hasOwnProperty,G=[],Y=G.pop,Q=G.push,J=G.push,Z=G.slice,ee=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},te=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",ne=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",re=\"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",oe=\"\\\\[\"+ne+\"*(\"+re+\")(?:\"+ne+\"*([*^$|!~]?=)\"+ne+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+re+\"))|)\"+ne+\"*\\\\]\",ie=\":(\"+re+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+oe+\")*)|.*)\\\\)|)\",ae=new RegExp(ne+\"+\",\"g\"),se=new RegExp(\"^\"+ne+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+ne+\"+$\",\"g\"),ue=new RegExp(\"^\"+ne+\"*,\"+ne+\"*\"),le=new RegExp(\"^\"+ne+\"*([>+~]|\"+ne+\")\"+ne+\"*\"),ce=new RegExp(\"=\"+ne+\"*([^\\\\]'\\\"]*?)\"+ne+\"*\\\\]\",\"g\"),fe=new RegExp(ie),pe=new RegExp(\"^\"+re+\"$\"),he={ID:new RegExp(\"^#(\"+re+\")\"),CLASS:new RegExp(\"^\\\\.(\"+re+\")\"),TAG:new RegExp(\"^(\"+re+\"|[*])\"),ATTR:new RegExp(\"^\"+oe),PSEUDO:new RegExp(\"^\"+ie),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+ne+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+ne+\"*(?:([+-]|)\"+ne+\"*(\\\\d+)|))\"+ne+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+te+\")$\",\"i\"),needsContext:new RegExp(\"^\"+ne+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+ne+\"*((?:-\\\\d)?\\\\d*)\"+ne+\"*\\\\)|)(?=[^-]|$)\",\"i\")},de=/^(?:input|select|textarea|button)$/i,ge=/^h\\d$/i,me=/^[^{]+\\{\\s*\\[native \\w/,ve=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ye=/[+~]/,be=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+ne+\"?|(\"+ne+\")|.)\",\"ig\"),xe=function(e,t,n){var r=\"0x\"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},we=/([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,Ce=function(e,t){return t?\"\\0\"===e?\"�\":e.slice(0,-1)+\"\\\\\"+e.charCodeAt(e.length-1).toString(16)+\" \":\"\\\\\"+e},Te=function(){O()},ke=d(function(e){return e.disabled===!0&&(\"form\"in e||\"label\"in e)},{dir:\"parentNode\",next:\"legend\"});try{J.apply(G=Z.call(_.childNodes),_.childNodes),G[_.childNodes.length].nodeType}catch(e){J={apply:G.length?function(e,t){Q.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}C=t.support={},j=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&\"HTML\"!==t.nodeName},O=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:_;return r!==L&&9===r.nodeType&&r.documentElement?(L=r,H=L.documentElement,F=!j(L),_!==L&&(n=L.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener(\"unload\",Te,!1):n.attachEvent&&n.attachEvent(\"onunload\",Te)),C.attributes=o(function(e){return e.className=\"i\",!e.getAttribute(\"className\")}),C.getElementsByTagName=o(function(e){return e.appendChild(L.createComment(\"\")),!e.getElementsByTagName(\"*\").length}),C.getElementsByClassName=me.test(L.getElementsByClassName),C.getById=o(function(e){return H.appendChild(e).id=$,!L.getElementsByName||!L.getElementsByName($).length}),C.getById?(T.filter.ID=function(e){var t=e.replace(be,xe);return function(e){return e.getAttribute(\"id\")===t}},T.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&F){var n=t.getElementById(e);return n?[n]:[]}}):(T.filter.ID=function(e){var t=e.replace(be,xe);return function(e){var n=\"undefined\"!=typeof e.getAttributeNode&&e.getAttributeNode(\"id\");return n&&n.value===t}},T.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&F){var n,r,o,i=t.getElementById(e);if(i){if(n=i.getAttributeNode(\"id\"),n&&n.value===e)return[i];for(o=t.getElementsByName(e),r=0;i=o[r++];)if(n=i.getAttributeNode(\"id\"),n&&n.value===e)return[i]}return[]}}),T.find.TAG=C.getElementsByTagName?function(e,t){return\"undefined\"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):C.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],o=0,i=t.getElementsByTagName(e);if(\"*\"===e){for(;n=i[o++];)1===n.nodeType&&r.push(n);return r}return i},T.find.CLASS=C.getElementsByClassName&&function(e,t){if(\"undefined\"!=typeof t.getElementsByClassName&&F)return t.getElementsByClassName(e)},I=[],P=[],(C.qsa=me.test(L.querySelectorAll))&&(o(function(e){H.appendChild(e).innerHTML=\"<a id='\"+$+\"'></a><select id='\"+$+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",e.querySelectorAll(\"[msallowcapture^='']\").length&&P.push(\"[*^$]=\"+ne+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\"[selected]\").length||P.push(\"\\\\[\"+ne+\"*(?:value|\"+te+\")\"),e.querySelectorAll(\"[id~=\"+$+\"-]\").length||P.push(\"~=\"),e.querySelectorAll(\":checked\").length||P.push(\":checked\"),e.querySelectorAll(\"a#\"+$+\"+*\").length||P.push(\".#.+[+~]\")}),o(function(e){e.innerHTML=\"<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>\";var t=L.createElement(\"input\");t.setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),e.querySelectorAll(\"[name=d]\").length&&P.push(\"name\"+ne+\"*[*^$|!~]?=\"),2!==e.querySelectorAll(\":enabled\").length&&P.push(\":enabled\",\":disabled\"),H.appendChild(e).disabled=!0,2!==e.querySelectorAll(\":disabled\").length&&P.push(\":enabled\",\":disabled\"),e.querySelectorAll(\"*,:x\"),P.push(\",.*:\")})),(C.matchesSelector=me.test(R=H.matches||H.webkitMatchesSelector||H.mozMatchesSelector||H.oMatchesSelector||H.msMatchesSelector))&&o(function(e){C.disconnectedMatch=R.call(e,\"*\"),R.call(e,\"[s!='']:x\"),I.push(\"!=\",ie)}),P=P.length&&new RegExp(P.join(\"|\")),I=I.length&&new RegExp(I.join(\"|\")),t=me.test(H.compareDocumentPosition),M=t||me.test(H.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},K=t?function(e,t){if(e===t)return D=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!C.sortDetached&&t.compareDocumentPosition(e)===n?e===L||e.ownerDocument===_&&M(_,e)?-1:t===L||t.ownerDocument===_&&M(_,t)?1:q?ee(q,e)-ee(q,t):0:4&n?-1:1)}:function(e,t){if(e===t)return D=!0,0;var n,r=0,o=e.parentNode,i=t.parentNode,s=[e],u=[t];if(!o||!i)return e===L?-1:t===L?1:o?-1:i?1:q?ee(q,e)-ee(q,t):0;if(o===i)return a(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;s[r]===u[r];)r++;return r?a(s[r],u[r]):s[r]===_?-1:u[r]===_?1:0},L):L},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==L&&O(e),n=n.replace(ce,\"='$1']\"),C.matchesSelector&&F&&!X[n+\" \"]&&(!I||!I.test(n))&&(!P||!P.test(n)))try{var r=R.call(e,n);if(r||C.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return t(n,L,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==L&&O(e),M(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==L&&O(e);var n=T.attrHandle[t.toLowerCase()],r=n&&V.call(T.attrHandle,t.toLowerCase())?n(e,t,!F):void 0;return void 0!==r?r:C.attributes||!F?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.escape=function(e){return(e+\"\").replace(we,Ce)},t.error=function(e){throw new Error(\"Syntax error, unrecognized expression: \"+e)},t.uniqueSort=function(e){var t,n=[],r=0,o=0;if(D=!C.detectDuplicates,q=!C.sortStable&&e.slice(0),e.sort(K),D){for(;t=e[o++];)t===e[o]&&(r=n.push(o));for(;r--;)e.splice(n[r],1)}return q=null,e},k=t.getText=function(e){var t,n=\"\",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if(\"string\"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=k(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[r++];)n+=k(t);return n},T=t.selectors={cacheLength:50,createPseudo:r,match:he,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(be,xe),e[3]=(e[3]||e[4]||e[5]||\"\").replace(be,xe),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return he.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&fe.test(n)&&(t=E(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(be,xe).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=U[e+\" \"];return t||(t=new RegExp(\"(^|\"+ne+\")\"+e+\"(\"+ne+\"|$)\"))&&U(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||\"undefined\"!=typeof e.getAttribute&&e.getAttribute(\"class\")||\"\")})},ATTR:function(e,n,r){return function(o){var i=t.attr(o,e);return null==i?\"!=\"===n:!n||(i+=\"\",\"=\"===n?i===r:\"!=\"===n?i!==r:\"^=\"===n?r&&0===i.indexOf(r):\"*=\"===n?r&&i.indexOf(r)>-1:\"$=\"===n?r&&i.slice(-r.length)===r:\"~=\"===n?(\" \"+i.replace(ae,\" \")+\" \").indexOf(r)>-1:\"|=\"===n&&(i===r||i.slice(0,r.length+1)===r+\"-\"))}},CHILD:function(e,t,n,r,o){var i=\"nth\"!==e.slice(0,3),a=\"last\"!==e.slice(-4),s=\"of-type\"===t;return 1===r&&0===o?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,h,d,g=i!==a?\"nextSibling\":\"previousSibling\",m=t.parentNode,v=s&&t.nodeName.toLowerCase(),y=!u&&!s,b=!1;if(m){if(i){for(;g;){for(p=t;p=p[g];)if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;d=g=\"only\"===e&&!d&&\"nextSibling\"}return!0}if(d=[a?m.firstChild:m.lastChild],a&&y){for(p=m,f=p[$]||(p[$]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),l=c[e]||[],h=l[0]===W&&l[1],b=h&&l[2],p=h&&m.childNodes[h];p=++h&&p&&p[g]||(b=h=0)||d.pop();)if(1===p.nodeType&&++b&&p===t){c[e]=[W,h,b];break}}else if(y&&(p=t,f=p[$]||(p[$]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),l=c[e]||[],h=l[0]===W&&l[1],b=h),b===!1)for(;(p=++h&&p&&p[g]||(b=h=0)||d.pop())&&((s?p.nodeName.toLowerCase()!==v:1!==p.nodeType)||!++b||(y&&(f=p[$]||(p[$]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),c[e]=[W,b]),p!==t)););return b-=o,b===r||b%r===0&&b/r>=0}}},PSEUDO:function(e,n){var o,i=T.pseudos[e]||T.setFilters[e.toLowerCase()]||t.error(\"unsupported pseudo: \"+e);return i[$]?i(n):i.length>1?(o=[e,e,\"\",n],T.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,o=i(e,n),a=o.length;a--;)r=ee(e,o[a]),e[r]=!(t[r]=o[a])}):function(e){return i(e,0,o)}):i}},pseudos:{not:r(function(e){var t=[],n=[],o=N(e.replace(se,\"$1\"));return o[$]?r(function(e,t,n,r){for(var i,a=o(e,null,r,[]),s=e.length;s--;)(i=a[s])&&(e[s]=!(t[s]=i))}):function(e,r,i){return t[0]=e,o(t,null,i,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){\nreturn t(e,n).length>0}}),contains:r(function(e){return e=e.replace(be,xe),function(t){return(t.textContent||t.innerText||k(t)).indexOf(e)>-1}}),lang:r(function(e){return pe.test(e||\"\")||t.error(\"unsupported lang: \"+e),e=e.replace(be,xe).toLowerCase(),function(t){var n;do if(n=F?t.lang:t.getAttribute(\"xml:lang\")||t.getAttribute(\"lang\"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+\"-\");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===H},focus:function(e){return e===L.activeElement&&(!L.hasFocus||L.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:l(!1),disabled:l(!0),checked:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&!!e.checked||\"option\"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!T.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return de.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&\"button\"===e.type||\"button\"===t},text:function(e){var t;return\"input\"===e.nodeName.toLowerCase()&&\"text\"===e.type&&(null==(t=e.getAttribute(\"type\"))||\"text\"===t.toLowerCase())},first:c(function(){return[0]}),last:c(function(e,t){return[t-1]}),eq:c(function(e,t,n){return[n<0?n+t:n]}),even:c(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:c(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:c(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:c(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},T.pseudos.nth=T.pseudos.eq;for(w in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})T.pseudos[w]=s(w);for(w in{submit:!0,reset:!0})T.pseudos[w]=u(w);return p.prototype=T.filters=T.pseudos,T.setFilters=new p,E=t.tokenize=function(e,n){var r,o,i,a,s,u,l,c=z[e+\" \"];if(c)return n?0:c.slice(0);for(s=e,u=[],l=T.preFilter;s;){r&&!(o=ue.exec(s))||(o&&(s=s.slice(o[0].length)||s),u.push(i=[])),r=!1,(o=le.exec(s))&&(r=o.shift(),i.push({value:r,type:o[0].replace(se,\" \")}),s=s.slice(r.length));for(a in T.filter)!(o=he[a].exec(s))||l[a]&&!(o=l[a](o))||(r=o.shift(),i.push({value:r,type:a,matches:o}),s=s.slice(r.length));if(!r)break}return n?s.length:s?t.error(e):z(e,u).slice(0)},N=t.compile=function(e,t){var n,r=[],o=[],i=X[e+\" \"];if(!i){for(t||(t=E(e)),n=t.length;n--;)i=b(t[n]),i[$]?r.push(i):o.push(i);i=X(e,x(o,r)),i.selector=e}return i},S=t.select=function(e,t,n,r){var o,i,a,s,u,l=\"function\"==typeof e&&e,c=!r&&E(e=l.selector||e);if(n=n||[],1===c.length){if(i=c[0]=c[0].slice(0),i.length>2&&\"ID\"===(a=i[0]).type&&9===t.nodeType&&F&&T.relative[i[1].type]){if(t=(T.find.ID(a.matches[0].replace(be,xe),t)||[])[0],!t)return n;l&&(t=t.parentNode),e=e.slice(i.shift().value.length)}for(o=he.needsContext.test(e)?0:i.length;o--&&(a=i[o],!T.relative[s=a.type]);)if((u=T.find[s])&&(r=u(a.matches[0].replace(be,xe),ye.test(i[0].type)&&f(t.parentNode)||t))){if(i.splice(o,1),e=r.length&&h(i),!e)return J.apply(n,r),n;break}}return(l||N(e,c))(r,t,!F,n,!t||ye.test(e)&&f(t.parentNode)||t),n},C.sortStable=$.split(\"\").sort(K).join(\"\")===$,C.detectDuplicates=!!D,O(),C.sortDetached=o(function(e){return 1&e.compareDocumentPosition(L.createElement(\"fieldset\"))}),o(function(e){return e.innerHTML=\"<a href='#'></a>\",\"#\"===e.firstChild.getAttribute(\"href\")})||i(\"type|href|height|width\",function(e,t,n){if(!n)return e.getAttribute(t,\"type\"===t.toLowerCase()?1:2)}),C.attributes&&o(function(e){return e.innerHTML=\"<input/>\",e.firstChild.setAttribute(\"value\",\"\"),\"\"===e.firstChild.getAttribute(\"value\")})||i(\"value\",function(e,t,n){if(!n&&\"input\"===e.nodeName.toLowerCase())return e.defaultValue}),o(function(e){return null==e.getAttribute(\"disabled\")})||i(te,function(e,t,n){var r;if(!n)return e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);de.find=be,de.expr=be.selectors,de.expr[\":\"]=de.expr.pseudos,de.uniqueSort=de.unique=be.uniqueSort,de.text=be.getText,de.isXMLDoc=be.isXML,de.contains=be.contains,de.escapeSelector=be.escape;var xe=function(e,t,n){for(var r=[],o=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(o&&de(e).is(n))break;r.push(e)}return r},we=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},Ce=de.expr.match.needsContext,Te=/^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i,ke=/^.[^:#\\[\\.,]*$/;de.filter=function(e,t,n){var r=t[0];return n&&(e=\":not(\"+e+\")\"),1===t.length&&1===r.nodeType?de.find.matchesSelector(r,e)?[r]:[]:de.find.matches(e,de.grep(t,function(e){return 1===e.nodeType}))},de.fn.extend({find:function(e){var t,n,r=this.length,o=this;if(\"string\"!=typeof e)return this.pushStack(de(e).filter(function(){for(t=0;t<r;t++)if(de.contains(o[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)de.find(e,o[t],n);return r>1?de.uniqueSort(n):n},filter:function(e){return this.pushStack(o(this,e||[],!1))},not:function(e){return this.pushStack(o(this,e||[],!0))},is:function(e){return!!o(this,\"string\"==typeof e&&Ce.test(e)?de(e):e||[],!1).length}});var je,Ee=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,Ne=de.fn.init=function(e,t,n){var r,o;if(!e)return this;if(n=n||je,\"string\"==typeof e){if(r=\"<\"===e[0]&&\">\"===e[e.length-1]&&e.length>=3?[null,e,null]:Ee.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof de?t[0]:t,de.merge(this,de.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:te,!0)),Te.test(r[1])&&de.isPlainObject(t))for(r in t)de.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return o=te.getElementById(r[2]),o&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):de.isFunction(e)?void 0!==n.ready?n.ready(e):e(de):de.makeArray(e,this)};Ne.prototype=de.fn,je=de(te);var Se=/^(?:parents|prev(?:Until|All))/,Ae={children:!0,contents:!0,next:!0,prev:!0};de.fn.extend({has:function(e){var t=de(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(de.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,o=this.length,i=[],a=\"string\"!=typeof e&&de(e);if(!Ce.test(e))for(;r<o;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&de.find.matchesSelector(n,e))){i.push(n);break}return this.pushStack(i.length>1?de.uniqueSort(i):i)},index:function(e){return e?\"string\"==typeof e?ae.call(de(e),this[0]):ae.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(de.uniqueSort(de.merge(this.get(),de(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),de.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return xe(e,\"parentNode\")},parentsUntil:function(e,t,n){return xe(e,\"parentNode\",n)},next:function(e){return i(e,\"nextSibling\")},prev:function(e){return i(e,\"previousSibling\")},nextAll:function(e){return xe(e,\"nextSibling\")},prevAll:function(e){return xe(e,\"previousSibling\")},nextUntil:function(e,t,n){return xe(e,\"nextSibling\",n)},prevUntil:function(e,t,n){return xe(e,\"previousSibling\",n)},siblings:function(e){return we((e.parentNode||{}).firstChild,e)},children:function(e){return we(e.firstChild)},contents:function(e){return e.contentDocument||de.merge([],e.childNodes)}},function(e,t){de.fn[e]=function(n,r){var o=de.map(this,t,n);return\"Until\"!==e.slice(-5)&&(r=n),r&&\"string\"==typeof r&&(o=de.filter(r,o)),this.length>1&&(Ae[e]||de.uniqueSort(o),Se.test(e)&&o.reverse()),this.pushStack(o)}});var qe=/[^\\x20\\t\\r\\n\\f]+/g;de.Callbacks=function(e){e=\"string\"==typeof e?a(e):de.extend({},e);var t,n,r,o,i=[],s=[],u=-1,l=function(){for(o=e.once,r=t=!0;s.length;u=-1)for(n=s.shift();++u<i.length;)i[u].apply(n[0],n[1])===!1&&e.stopOnFalse&&(u=i.length,n=!1);e.memory||(n=!1),t=!1,o&&(i=n?[]:\"\")},c={add:function(){return i&&(n&&!t&&(u=i.length-1,s.push(n)),function t(n){de.each(n,function(n,r){de.isFunction(r)?e.unique&&c.has(r)||i.push(r):r&&r.length&&\"string\"!==de.type(r)&&t(r)})}(arguments),n&&!t&&l()),this},remove:function(){return de.each(arguments,function(e,t){for(var n;(n=de.inArray(t,i,n))>-1;)i.splice(n,1),n<=u&&u--}),this},has:function(e){return e?de.inArray(e,i)>-1:i.length>0},empty:function(){return i&&(i=[]),this},disable:function(){return o=s=[],i=n=\"\",this},disabled:function(){return!i},lock:function(){return o=s=[],n||t||(i=n=\"\"),this},locked:function(){return!!o},fireWith:function(e,n){return o||(n=n||[],n=[e,n.slice?n.slice():n],s.push(n),t||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},de.extend({Deferred:function(t){var n=[[\"notify\",\"progress\",de.Callbacks(\"memory\"),de.Callbacks(\"memory\"),2],[\"resolve\",\"done\",de.Callbacks(\"once memory\"),de.Callbacks(\"once memory\"),0,\"resolved\"],[\"reject\",\"fail\",de.Callbacks(\"once memory\"),de.Callbacks(\"once memory\"),1,\"rejected\"]],r=\"pending\",o={state:function(){return r},always:function(){return i.done(arguments).fail(arguments),this},catch:function(e){return o.then(null,e)},pipe:function(){var e=arguments;return de.Deferred(function(t){de.each(n,function(n,r){var o=de.isFunction(e[r[4]])&&e[r[4]];i[r[1]](function(){var e=o&&o.apply(this,arguments);e&&de.isFunction(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+\"With\"](this,o?[e]:arguments)})}),e=null}).promise()},then:function(t,r,o){function i(t,n,r,o){return function(){var l=this,c=arguments,f=function(){var e,f;if(!(t<a)){if(e=r.apply(l,c),e===n.promise())throw new TypeError(\"Thenable self-resolution\");f=e&&(\"object\"==typeof e||\"function\"==typeof e)&&e.then,de.isFunction(f)?o?f.call(e,i(a,n,s,o),i(a,n,u,o)):(a++,f.call(e,i(a,n,s,o),i(a,n,u,o),i(a,n,s,n.notifyWith))):(r!==s&&(l=void 0,c=[e]),(o||n.resolveWith)(l,c))}},p=o?f:function(){try{f()}catch(e){de.Deferred.exceptionHook&&de.Deferred.exceptionHook(e,p.stackTrace),t+1>=a&&(r!==u&&(l=void 0,c=[e]),n.rejectWith(l,c))}};t?p():(de.Deferred.getStackHook&&(p.stackTrace=de.Deferred.getStackHook()),e.setTimeout(p))}}var a=0;return de.Deferred(function(e){n[0][3].add(i(0,e,de.isFunction(o)?o:s,e.notifyWith)),n[1][3].add(i(0,e,de.isFunction(t)?t:s)),n[2][3].add(i(0,e,de.isFunction(r)?r:u))}).promise()},promise:function(e){return null!=e?de.extend(e,o):o}},i={};return de.each(n,function(e,t){var a=t[2],s=t[5];o[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[0][2].lock),a.add(t[3].fire),i[t[0]]=function(){return i[t[0]+\"With\"](this===i?void 0:this,arguments),this},i[t[0]+\"With\"]=a.fireWith}),o.promise(i),t&&t.call(i,i),i},when:function(e){var t=arguments.length,n=t,r=Array(n),o=re.call(arguments),i=de.Deferred(),a=function(e){return function(n){r[e]=this,o[e]=arguments.length>1?re.call(arguments):n,--t||i.resolveWith(r,o)}};if(t<=1&&(l(e,i.done(a(n)).resolve,i.reject),\"pending\"===i.state()||de.isFunction(o[n]&&o[n].then)))return i.then();for(;n--;)l(o[n],a(n),i.reject);return i.promise()}});var De=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;de.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&De.test(t.name)&&e.console.warn(\"jQuery.Deferred exception: \"+t.message,t.stack,n)},de.readyException=function(t){e.setTimeout(function(){throw t})};var Oe=de.Deferred();de.fn.ready=function(e){return Oe.then(e).catch(function(e){de.readyException(e)}),this},de.extend({isReady:!1,readyWait:1,holdReady:function(e){e?de.readyWait++:de.ready(!0)},ready:function(e){(e===!0?--de.readyWait:de.isReady)||(de.isReady=!0,e!==!0&&--de.readyWait>0||Oe.resolveWith(te,[de]))}}),de.ready.then=Oe.then,\"complete\"===te.readyState||\"loading\"!==te.readyState&&!te.documentElement.doScroll?e.setTimeout(de.ready):(te.addEventListener(\"DOMContentLoaded\",c),e.addEventListener(\"load\",c));var Le=function(e,t,n,r,o,i,a){var s=0,u=e.length,l=null==n;if(\"object\"===de.type(n)){o=!0;for(s in n)Le(e,t,s,n[s],!0,i,a)}else if(void 0!==r&&(o=!0,de.isFunction(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(de(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return o?e:l?t.call(e):u?t(e[0],n):i},He=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};f.uid=1,f.prototype={cache:function(e){var t=e[this.expando];return t||(t={},He(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,o=this.cache(e);if(\"string\"==typeof t)o[de.camelCase(t)]=n;else for(r in t)o[de.camelCase(r)]=t[r];return o},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][de.camelCase(t)]},access:function(e,t,n){return void 0===t||t&&\"string\"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){de.isArray(t)?t=t.map(de.camelCase):(t=de.camelCase(t),t=t in r?[t]:t.match(qe)||[]),n=t.length;for(;n--;)delete r[t[n]]}(void 0===t||de.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!de.isEmptyObject(t)}};var Fe=new f,Pe=new f,Ie=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,Re=/[A-Z]/g;de.extend({hasData:function(e){return Pe.hasData(e)||Fe.hasData(e)},data:function(e,t,n){return Pe.access(e,t,n)},removeData:function(e,t){Pe.remove(e,t)},_data:function(e,t,n){return Fe.access(e,t,n)},_removeData:function(e,t){Fe.remove(e,t)}}),de.fn.extend({data:function(e,t){var n,r,o,i=this[0],a=i&&i.attributes;if(void 0===e){if(this.length&&(o=Pe.get(i),1===i.nodeType&&!Fe.get(i,\"hasDataAttrs\"))){for(n=a.length;n--;)a[n]&&(r=a[n].name,0===r.indexOf(\"data-\")&&(r=de.camelCase(r.slice(5)),h(i,r,o[r])));Fe.set(i,\"hasDataAttrs\",!0)}return o}return\"object\"==typeof e?this.each(function(){Pe.set(this,e)}):Le(this,function(t){var n;if(i&&void 0===t){if(n=Pe.get(i,e),void 0!==n)return n;if(n=h(i,e),void 0!==n)return n}else this.each(function(){Pe.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){Pe.remove(this,e)})}}),de.extend({queue:function(e,t,n){var r;if(e)return t=(t||\"fx\")+\"queue\",r=Fe.get(e,t),n&&(!r||de.isArray(n)?r=Fe.access(e,t,de.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||\"fx\";var n=de.queue(e,t),r=n.length,o=n.shift(),i=de._queueHooks(e,t),a=function(){de.dequeue(e,t)};\"inprogress\"===o&&(o=n.shift(),r--),o&&(\"fx\"===t&&n.unshift(\"inprogress\"),delete i.stop,o.call(e,a,i)),!r&&i&&i.empty.fire()},_queueHooks:function(e,t){var n=t+\"queueHooks\";return Fe.get(e,n)||Fe.access(e,n,{empty:de.Callbacks(\"once memory\").add(function(){Fe.remove(e,[t+\"queue\",n])})})}}),de.fn.extend({queue:function(e,t){var n=2;return\"string\"!=typeof e&&(t=e,e=\"fx\",n--),arguments.length<n?de.queue(this[0],e):void 0===t?this:this.each(function(){var n=de.queue(this,e,t);de._queueHooks(this,e),\"fx\"===e&&\"inprogress\"!==n[0]&&de.dequeue(this,e)})},dequeue:function(e){return this.each(function(){de.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||\"fx\",[])},promise:function(e,t){var n,r=1,o=de.Deferred(),i=this,a=this.length,s=function(){--r||o.resolveWith(i,[i])};for(\"string\"!=typeof e&&(t=e,e=void 0),e=e||\"fx\";a--;)n=Fe.get(i[a],e+\"queueHooks\"),n&&n.empty&&(r++,n.empty.add(s));return s(),o.promise(t)}});var Me=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,$e=new RegExp(\"^(?:([+-])=|)(\"+Me+\")([a-z%]*)$\",\"i\"),_e=[\"Top\",\"Right\",\"Bottom\",\"Left\"],We=function(e,t){return e=t||e,\"none\"===e.style.display||\"\"===e.style.display&&de.contains(e.ownerDocument,e)&&\"none\"===de.css(e,\"display\")},Be=function(e,t,n,r){var o,i,a={};for(i in t)a[i]=e.style[i],e.style[i]=t[i];o=n.apply(e,r||[]);for(i in t)e.style[i]=a[i];return o},Ue={};de.fn.extend({show:function(){return m(this,!0)},hide:function(){return m(this)},toggle:function(e){return\"boolean\"==typeof e?e?this.show():this.hide():this.each(function(){We(this)?de(this).show():de(this).hide()})}});var ze=/^(?:checkbox|radio)$/i,Xe=/<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]+)/i,Ke=/^$|\\/(?:java|ecma)script/i,Ve={option:[1,\"<select multiple='multiple'>\",\"</select>\"],thead:[1,\"<table>\",\"</table>\"],col:[2,\"<table><colgroup>\",\"</colgroup></table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:[0,\"\",\"\"]};Ve.optgroup=Ve.option,Ve.tbody=Ve.tfoot=Ve.colgroup=Ve.caption=Ve.thead,Ve.th=Ve.td;var Ge=/<|&#?\\w+;/;!function(){var e=te.createDocumentFragment(),t=e.appendChild(te.createElement(\"div\")),n=te.createElement(\"input\");n.setAttribute(\"type\",\"radio\"),n.setAttribute(\"checked\",\"checked\"),n.setAttribute(\"name\",\"t\"),t.appendChild(n),pe.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML=\"<textarea>x</textarea>\",pe.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var Ye=te.documentElement,Qe=/^key/,Je=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ze=/^([^.]*)(?:\\.(.+)|)/;de.event={global:{},add:function(e,t,n,r,o){var i,a,s,u,l,c,f,p,h,d,g,m=Fe.get(e);if(m)for(n.handler&&(i=n,n=i.handler,o=i.selector),o&&de.find.matchesSelector(Ye,o),n.guid||(n.guid=de.guid++),(u=m.events)||(u=m.events={}),(a=m.handle)||(a=m.handle=function(t){return\"undefined\"!=typeof de&&de.event.triggered!==t.type?de.event.dispatch.apply(e,arguments):void 0}),t=(t||\"\").match(qe)||[\"\"],l=t.length;l--;)s=Ze.exec(t[l])||[],h=g=s[1],d=(s[2]||\"\").split(\".\").sort(),h&&(f=de.event.special[h]||{},h=(o?f.delegateType:f.bindType)||h,f=de.event.special[h]||{},c=de.extend({type:h,origType:g,data:r,handler:n,guid:n.guid,selector:o,needsContext:o&&de.expr.match.needsContext.test(o),namespace:d.join(\".\")},i),(p=u[h])||(p=u[h]=[],p.delegateCount=0,f.setup&&f.setup.call(e,r,d,a)!==!1||e.addEventListener&&e.addEventListener(h,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),o?p.splice(p.delegateCount++,0,c):p.push(c),de.event.global[h]=!0)},remove:function(e,t,n,r,o){var i,a,s,u,l,c,f,p,h,d,g,m=Fe.hasData(e)&&Fe.get(e);if(m&&(u=m.events)){for(t=(t||\"\").match(qe)||[\"\"],l=t.length;l--;)if(s=Ze.exec(t[l])||[],h=g=s[1],d=(s[2]||\"\").split(\".\").sort(),h){for(f=de.event.special[h]||{},h=(r?f.delegateType:f.bindType)||h,p=u[h]||[],s=s[2]&&new RegExp(\"(^|\\\\.)\"+d.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),a=i=p.length;i--;)c=p[i],!o&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&(\"**\"!==r||!c.selector)||(p.splice(i,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&f.teardown.call(e,d,m.handle)!==!1||de.removeEvent(e,h,m.handle),delete u[h])}else for(h in u)de.event.remove(e,h+t[l],n,r,!0);de.isEmptyObject(u)&&Fe.remove(e,\"handle events\")}},dispatch:function(e){var t,n,r,o,i,a,s=de.event.fix(e),u=new Array(arguments.length),l=(Fe.get(this,\"events\")||{})[s.type]||[],c=de.event.special[s.type]||{};for(u[0]=s,t=1;t<arguments.length;t++)u[t]=arguments[t];if(s.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,s)!==!1){for(a=de.event.handlers.call(this,s,l),t=0;(o=a[t++])&&!s.isPropagationStopped();)for(s.currentTarget=o.elem,n=0;(i=o.handlers[n++])&&!s.isImmediatePropagationStopped();)s.rnamespace&&!s.rnamespace.test(i.namespace)||(s.handleObj=i,s.data=i.data,r=((de.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),void 0!==r&&(s.result=r)===!1&&(s.preventDefault(),s.stopPropagation()));return c.postDispatch&&c.postDispatch.call(this,s),s.result}},handlers:function(e,t){var n,r,o,i,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!(\"click\"===e.type&&e.button>=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&(\"click\"!==e.type||l.disabled!==!0)){for(i=[],a={},n=0;n<u;n++)r=t[n],o=r.selector+\" \",void 0===a[o]&&(a[o]=r.needsContext?de(o,this).index(l)>-1:de.find(o,this,null,[l]).length),a[o]&&i.push(r);i.length&&s.push({elem:l,handlers:i})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(e,t){Object.defineProperty(de.Event.prototype,e,{enumerable:!0,configurable:!0,get:de.isFunction(t)?function(){if(this.originalEvent)return t(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[e]},set:function(t){Object.defineProperty(this,e,{enumerable:!0,configurable:!0,writable:!0,value:t})}})},fix:function(e){return e[de.expando]?e:new de.Event(e)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==C()&&this.focus)return this.focus(),!1},delegateType:\"focusin\"},blur:{trigger:function(){if(this===C()&&this.blur)return this.blur(),!1},delegateType:\"focusout\"},click:{trigger:function(){if(\"checkbox\"===this.type&&this.click&&de.nodeName(this,\"input\"))return this.click(),!1},_default:function(e){return de.nodeName(e.target,\"a\")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},de.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},de.Event=function(e,t){return this instanceof de.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&e.returnValue===!1?x:w,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&de.extend(this,t),this.timeStamp=e&&e.timeStamp||de.now(),void(this[de.expando]=!0)):new de.Event(e,t)},de.Event.prototype={constructor:de.Event,isDefaultPrevented:w,isPropagationStopped:w,isImmediatePropagationStopped:w,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=x,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=x,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=x,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},de.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,char:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&Qe.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&Je.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},de.event.addProp),de.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(e,t){de.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,o=e.relatedTarget,i=e.handleObj;return o&&(o===r||de.contains(r,o))||(e.type=i.origType,n=i.handler.apply(this,arguments),e.type=t),n}}}),de.fn.extend({on:function(e,t,n,r){return T(this,e,t,n,r)},one:function(e,t,n,r){return T(this,e,t,n,r,1)},off:function(e,t,n){var r,o;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,de(e.delegateTarget).off(r.namespace?r.origType+\".\"+r.namespace:r.origType,r.selector,r.handler),this;if(\"object\"==typeof e){for(o in e)this.off(o,t,e[o]);return this}return t!==!1&&\"function\"!=typeof t||(n=t,t=void 0),n===!1&&(n=w),this.each(function(){de.event.remove(this,e,n,t)})}});var et=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,tt=/<script|<style|<link/i,nt=/checked\\s*(?:[^=]|=\\s*.checked.)/i,rt=/^true\\/(.*)/,ot=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;de.extend({htmlPrefilter:function(e){return e.replace(et,\"<$1></$2>\")},clone:function(e,t,n){var r,o,i,a,s=e.cloneNode(!0),u=de.contains(e.ownerDocument,e);if(!(pe.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||de.isXMLDoc(e)))for(a=v(s),i=v(e),r=0,o=i.length;r<o;r++)S(i[r],a[r]);if(t)if(n)for(i=i||v(e),a=a||v(s),r=0,o=i.length;r<o;r++)N(i[r],a[r]);else N(e,s);return a=v(s,\"script\"),a.length>0&&y(a,!u&&v(e,\"script\")),s},cleanData:function(e){for(var t,n,r,o=de.event.special,i=0;void 0!==(n=e[i]);i++)if(He(n)){if(t=n[Fe.expando]){if(t.events)for(r in t.events)o[r]?de.event.remove(n,r):de.removeEvent(n,r,t.handle);n[Fe.expando]=void 0}n[Pe.expando]&&(n[Pe.expando]=void 0)}}}),de.fn.extend({detach:function(e){return q(this,e,!0)},remove:function(e){return q(this,e)},text:function(e){return Le(this,function(e){return void 0===e?de.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return A(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=k(this,e);t.appendChild(e)}})},prepend:function(){return A(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=k(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return A(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return A(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(de.cleanData(v(e,!1)),e.textContent=\"\");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return de.clone(this,e,t)})},html:function(e){return Le(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if(\"string\"==typeof e&&!tt.test(e)&&!Ve[(Xe.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=de.htmlPrefilter(e);try{for(;n<r;n++)t=this[n]||{},1===t.nodeType&&(de.cleanData(v(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return A(this,arguments,function(t){var n=this.parentNode;de.inArray(this,e)<0&&(de.cleanData(v(this)),n&&n.replaceChild(t,this))},e)}}),de.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(e,t){de.fn[e]=function(e){for(var n,r=[],o=de(e),i=o.length-1,a=0;a<=i;a++)n=a===i?this:this.clone(!0),de(o[a])[t](n),ie.apply(r,n.get());return this.pushStack(r)}});var it=/^margin/,at=new RegExp(\"^(\"+Me+\")(?!px)[a-z%]+$\",\"i\"),st=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)};!function(){function t(){if(s){s.style.cssText=\"box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%\",s.innerHTML=\"\",Ye.appendChild(a);var t=e.getComputedStyle(s);n=\"1%\"!==t.top,i=\"2px\"===t.marginLeft,r=\"4px\"===t.width,s.style.marginRight=\"50%\",o=\"4px\"===t.marginRight,Ye.removeChild(a),s=null}}var n,r,o,i,a=te.createElement(\"div\"),s=te.createElement(\"div\");s.style&&(s.style.backgroundClip=\"content-box\",s.cloneNode(!0).style.backgroundClip=\"\",pe.clearCloneStyle=\"content-box\"===s.style.backgroundClip,a.style.cssText=\"border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute\",a.appendChild(s),de.extend(pe,{pixelPosition:function(){return t(),n},boxSizingReliable:function(){return t(),r},pixelMarginRight:function(){return t(),o},reliableMarginLeft:function(){return t(),i}}))}();var ut=/^(none|table(?!-c[ea]).+)/,lt={position:\"absolute\",visibility:\"hidden\",display:\"block\"},ct={letterSpacing:\"0\",fontWeight:\"400\"},ft=[\"Webkit\",\"Moz\",\"ms\"],pt=te.createElement(\"div\").style;de.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=D(e,\"opacity\");return\"\"===n?\"1\":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{float:\"cssFloat\"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,i,a,s=de.camelCase(t),u=e.style;return t=de.cssProps[s]||(de.cssProps[s]=L(s)||s),a=de.cssHooks[t]||de.cssHooks[s],void 0===n?a&&\"get\"in a&&void 0!==(o=a.get(e,!1,r))?o:u[t]:(i=typeof n,\"string\"===i&&(o=$e.exec(n))&&o[1]&&(n=d(e,t,o),i=\"number\"),null!=n&&n===n&&(\"number\"===i&&(n+=o&&o[3]||(de.cssNumber[s]?\"\":\"px\")),pe.clearCloneStyle||\"\"!==n||0!==t.indexOf(\"background\")||(u[t]=\"inherit\"),a&&\"set\"in a&&void 0===(n=a.set(e,n,r))||(u[t]=n)),void 0)}},css:function(e,t,n,r){var o,i,a,s=de.camelCase(t);return t=de.cssProps[s]||(de.cssProps[s]=L(s)||s),a=de.cssHooks[t]||de.cssHooks[s],a&&\"get\"in a&&(o=a.get(e,!0,n)),void 0===o&&(o=D(e,t,r)),\"normal\"===o&&t in ct&&(o=ct[t]),\"\"===n||n?(i=parseFloat(o),n===!0||isFinite(i)?i||0:o):o}}),de.each([\"height\",\"width\"],function(e,t){de.cssHooks[t]={get:function(e,n,r){if(n)return!ut.test(de.css(e,\"display\"))||e.getClientRects().length&&e.getBoundingClientRect().width?P(e,t,r):Be(e,lt,function(){return P(e,t,r)})},set:function(e,n,r){var o,i=r&&st(e),a=r&&F(e,t,r,\"border-box\"===de.css(e,\"boxSizing\",!1,i),i);return a&&(o=$e.exec(n))&&\"px\"!==(o[3]||\"px\")&&(e.style[t]=n,n=de.css(e,t)),H(e,n,a)}}}),de.cssHooks.marginLeft=O(pe.reliableMarginLeft,function(e,t){if(t)return(parseFloat(D(e,\"marginLeft\"))||e.getBoundingClientRect().left-Be(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+\"px\"}),de.each({margin:\"\",padding:\"\",border:\"Width\"},function(e,t){de.cssHooks[e+t]={expand:function(n){for(var r=0,o={},i=\"string\"==typeof n?n.split(\" \"):[n];r<4;r++)o[e+_e[r]+t]=i[r]||i[r-2]||i[0];return o}},it.test(e)||(de.cssHooks[e+t].set=H)}),de.fn.extend({css:function(e,t){return Le(this,function(e,t,n){var r,o,i={},a=0;if(de.isArray(t)){for(r=st(e),o=t.length;a<o;a++)i[t[a]]=de.css(e,t[a],!1,r);return i}return void 0!==n?de.style(e,t,n):de.css(e,t)},e,t,arguments.length>1)}}),de.Tween=I,I.prototype={constructor:I,init:function(e,t,n,r,o,i){this.elem=e,this.prop=n,this.easing=o||de.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=i||(de.cssNumber[n]?\"\":\"px\")},cur:function(){var e=I.propHooks[this.prop];return e&&e.get?e.get(this):I.propHooks._default.get(this)},run:function(e){var t,n=I.propHooks[this.prop];return this.options.duration?this.pos=t=de.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):I.propHooks._default.set(this),this}},I.prototype.init.prototype=I.prototype,I.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=de.css(e.elem,e.prop,\"\"),t&&\"auto\"!==t?t:0)},set:function(e){de.fx.step[e.prop]?de.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[de.cssProps[e.prop]]&&!de.cssHooks[e.prop]?e.elem[e.prop]=e.now:de.style(e.elem,e.prop,e.now+e.unit)}}},I.propHooks.scrollTop=I.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},de.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:\"swing\"},de.fx=I.prototype.init,de.fx.step={};var ht,dt,gt=/^(?:toggle|show|hide)$/,mt=/queueHooks$/;de.Animation=de.extend(U,{tweeners:{\"*\":[function(e,t){var n=this.createTween(e,t);return d(n.elem,e,$e.exec(t),n),n}]},tweener:function(e,t){de.isFunction(e)?(t=e,e=[\"*\"]):e=e.match(qe);for(var n,r=0,o=e.length;r<o;r++)n=e[r],U.tweeners[n]=U.tweeners[n]||[],U.tweeners[n].unshift(t)},prefilters:[W],prefilter:function(e,t){t?U.prefilters.unshift(e):U.prefilters.push(e)}}),de.speed=function(e,t,n){var r=e&&\"object\"==typeof e?de.extend({},e):{complete:n||!n&&t||de.isFunction(e)&&e,duration:e,easing:n&&t||t&&!de.isFunction(t)&&t};return de.fx.off||te.hidden?r.duration=0:\"number\"!=typeof r.duration&&(r.duration in de.fx.speeds?r.duration=de.fx.speeds[r.duration]:r.duration=de.fx.speeds._default),null!=r.queue&&r.queue!==!0||(r.queue=\"fx\"),r.old=r.complete,r.complete=function(){de.isFunction(r.old)&&r.old.call(this),r.queue&&de.dequeue(this,r.queue)},r},de.fn.extend({fadeTo:function(e,t,n,r){return this.filter(We).css(\"opacity\",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){\nvar o=de.isEmptyObject(e),i=de.speed(t,n,r),a=function(){var t=U(this,de.extend({},e),i);(o||Fe.get(this,\"finish\"))&&t.stop(!0)};return a.finish=a,o||i.queue===!1?this.each(a):this.queue(i.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return\"string\"!=typeof e&&(n=t,t=e,e=void 0),t&&e!==!1&&this.queue(e||\"fx\",[]),this.each(function(){var t=!0,o=null!=e&&e+\"queueHooks\",i=de.timers,a=Fe.get(this);if(o)a[o]&&a[o].stop&&r(a[o]);else for(o in a)a[o]&&a[o].stop&&mt.test(o)&&r(a[o]);for(o=i.length;o--;)i[o].elem!==this||null!=e&&i[o].queue!==e||(i[o].anim.stop(n),t=!1,i.splice(o,1));!t&&n||de.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||\"fx\"),this.each(function(){var t,n=Fe.get(this),r=n[e+\"queue\"],o=n[e+\"queueHooks\"],i=de.timers,a=r?r.length:0;for(n.finish=!0,de.queue(this,e,[]),o&&o.stop&&o.stop.call(this,!0),t=i.length;t--;)i[t].elem===this&&i[t].queue===e&&(i[t].anim.stop(!0),i.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),de.each([\"toggle\",\"show\",\"hide\"],function(e,t){var n=de.fn[t];de.fn[t]=function(e,r,o){return null==e||\"boolean\"==typeof e?n.apply(this,arguments):this.animate($(t,!0),e,r,o)}}),de.each({slideDown:$(\"show\"),slideUp:$(\"hide\"),slideToggle:$(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(e,t){de.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),de.timers=[],de.fx.tick=function(){var e,t=0,n=de.timers;for(ht=de.now();t<n.length;t++)e=n[t],e()||n[t]!==e||n.splice(t--,1);n.length||de.fx.stop(),ht=void 0},de.fx.timer=function(e){de.timers.push(e),e()?de.fx.start():de.timers.pop()},de.fx.interval=13,de.fx.start=function(){dt||(dt=e.requestAnimationFrame?e.requestAnimationFrame(R):e.setInterval(de.fx.tick,de.fx.interval))},de.fx.stop=function(){e.cancelAnimationFrame?e.cancelAnimationFrame(dt):e.clearInterval(dt),dt=null},de.fx.speeds={slow:600,fast:200,_default:400},de.fn.delay=function(t,n){return t=de.fx?de.fx.speeds[t]||t:t,n=n||\"fx\",this.queue(n,function(n,r){var o=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(o)}})},function(){var e=te.createElement(\"input\"),t=te.createElement(\"select\"),n=t.appendChild(te.createElement(\"option\"));e.type=\"checkbox\",pe.checkOn=\"\"!==e.value,pe.optSelected=n.selected,e=te.createElement(\"input\"),e.value=\"t\",e.type=\"radio\",pe.radioValue=\"t\"===e.value}();var vt,yt=de.expr.attrHandle;de.fn.extend({attr:function(e,t){return Le(this,de.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){de.removeAttr(this,e)})}}),de.extend({attr:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return\"undefined\"==typeof e.getAttribute?de.prop(e,t,n):(1===i&&de.isXMLDoc(e)||(o=de.attrHooks[t.toLowerCase()]||(de.expr.match.bool.test(t)?vt:void 0)),void 0!==n?null===n?void de.removeAttr(e,t):o&&\"set\"in o&&void 0!==(r=o.set(e,n,t))?r:(e.setAttribute(t,n+\"\"),n):o&&\"get\"in o&&null!==(r=o.get(e,t))?r:(r=de.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!pe.radioValue&&\"radio\"===t&&de.nodeName(e,\"input\")){var n=e.value;return e.setAttribute(\"type\",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,o=t&&t.match(qe);if(o&&1===e.nodeType)for(;n=o[r++];)e.removeAttribute(n)}}),vt={set:function(e,t,n){return t===!1?de.removeAttr(e,n):e.setAttribute(n,n),n}},de.each(de.expr.match.bool.source.match(/\\w+/g),function(e,t){var n=yt[t]||de.find.attr;yt[t]=function(e,t,r){var o,i,a=t.toLowerCase();return r||(i=yt[a],yt[a]=o,o=null!=n(e,t,r)?a:null,yt[a]=i),o}});var bt=/^(?:input|select|textarea|button)$/i,xt=/^(?:a|area)$/i;de.fn.extend({prop:function(e,t){return Le(this,de.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[de.propFix[e]||e]})}}),de.extend({prop:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return 1===i&&de.isXMLDoc(e)||(t=de.propFix[t]||t,o=de.propHooks[t]),void 0!==n?o&&\"set\"in o&&void 0!==(r=o.set(e,n,t))?r:e[t]=n:o&&\"get\"in o&&null!==(r=o.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=de.find.attr(e,\"tabindex\");return t?parseInt(t,10):bt.test(e.nodeName)||xt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:\"htmlFor\",class:\"className\"}}),pe.optSelected||(de.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),de.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){de.propFix[this.toLowerCase()]=this}),de.fn.extend({addClass:function(e){var t,n,r,o,i,a,s,u=0;if(de.isFunction(e))return this.each(function(t){de(this).addClass(e.call(this,t,X(this)))});if(\"string\"==typeof e&&e)for(t=e.match(qe)||[];n=this[u++];)if(o=X(n),r=1===n.nodeType&&\" \"+z(o)+\" \"){for(a=0;i=t[a++];)r.indexOf(\" \"+i+\" \")<0&&(r+=i+\" \");s=z(r),o!==s&&n.setAttribute(\"class\",s)}return this},removeClass:function(e){var t,n,r,o,i,a,s,u=0;if(de.isFunction(e))return this.each(function(t){de(this).removeClass(e.call(this,t,X(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if(\"string\"==typeof e&&e)for(t=e.match(qe)||[];n=this[u++];)if(o=X(n),r=1===n.nodeType&&\" \"+z(o)+\" \"){for(a=0;i=t[a++];)for(;r.indexOf(\" \"+i+\" \")>-1;)r=r.replace(\" \"+i+\" \",\" \");s=z(r),o!==s&&n.setAttribute(\"class\",s)}return this},toggleClass:function(e,t){var n=typeof e;return\"boolean\"==typeof t&&\"string\"===n?t?this.addClass(e):this.removeClass(e):de.isFunction(e)?this.each(function(n){de(this).toggleClass(e.call(this,n,X(this),t),t)}):this.each(function(){var t,r,o,i;if(\"string\"===n)for(r=0,o=de(this),i=e.match(qe)||[];t=i[r++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&\"boolean\"!==n||(t=X(this),t&&Fe.set(this,\"__className__\",t),this.setAttribute&&this.setAttribute(\"class\",t||e===!1?\"\":Fe.get(this,\"__className__\")||\"\"))})},hasClass:function(e){var t,n,r=0;for(t=\" \"+e+\" \";n=this[r++];)if(1===n.nodeType&&(\" \"+z(X(n))+\" \").indexOf(t)>-1)return!0;return!1}});var wt=/\\r/g;de.fn.extend({val:function(e){var t,n,r,o=this[0];{if(arguments.length)return r=de.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=r?e.call(this,n,de(this).val()):e,null==o?o=\"\":\"number\"==typeof o?o+=\"\":de.isArray(o)&&(o=de.map(o,function(e){return null==e?\"\":e+\"\"})),t=de.valHooks[this.type]||de.valHooks[this.nodeName.toLowerCase()],t&&\"set\"in t&&void 0!==t.set(this,o,\"value\")||(this.value=o))});if(o)return t=de.valHooks[o.type]||de.valHooks[o.nodeName.toLowerCase()],t&&\"get\"in t&&void 0!==(n=t.get(o,\"value\"))?n:(n=o.value,\"string\"==typeof n?n.replace(wt,\"\"):null==n?\"\":n)}}}),de.extend({valHooks:{option:{get:function(e){var t=de.find.attr(e,\"value\");return null!=t?t:z(de.text(e))}},select:{get:function(e){var t,n,r,o=e.options,i=e.selectedIndex,a=\"select-one\"===e.type,s=a?null:[],u=a?i+1:o.length;for(r=i<0?u:a?i:0;r<u;r++)if(n=o[r],(n.selected||r===i)&&!n.disabled&&(!n.parentNode.disabled||!de.nodeName(n.parentNode,\"optgroup\"))){if(t=de(n).val(),a)return t;s.push(t)}return s},set:function(e,t){for(var n,r,o=e.options,i=de.makeArray(t),a=o.length;a--;)r=o[a],(r.selected=de.inArray(de.valHooks.option.get(r),i)>-1)&&(n=!0);return n||(e.selectedIndex=-1),i}}}}),de.each([\"radio\",\"checkbox\"],function(){de.valHooks[this]={set:function(e,t){if(de.isArray(t))return e.checked=de.inArray(de(e).val(),t)>-1}},pe.checkOn||(de.valHooks[this].get=function(e){return null===e.getAttribute(\"value\")?\"on\":e.value})});var Ct=/^(?:focusinfocus|focusoutblur)$/;de.extend(de.event,{trigger:function(t,n,r,o){var i,a,s,u,l,c,f,p=[r||te],h=le.call(t,\"type\")?t.type:t,d=le.call(t,\"namespace\")?t.namespace.split(\".\"):[];if(a=s=r=r||te,3!==r.nodeType&&8!==r.nodeType&&!Ct.test(h+de.event.triggered)&&(h.indexOf(\".\")>-1&&(d=h.split(\".\"),h=d.shift(),d.sort()),l=h.indexOf(\":\")<0&&\"on\"+h,t=t[de.expando]?t:new de.Event(h,\"object\"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=d.join(\".\"),t.rnamespace=t.namespace?new RegExp(\"(^|\\\\.)\"+d.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:de.makeArray(n,[t]),f=de.event.special[h]||{},o||!f.trigger||f.trigger.apply(r,n)!==!1)){if(!o&&!f.noBubble&&!de.isWindow(r)){for(u=f.delegateType||h,Ct.test(u+h)||(a=a.parentNode);a;a=a.parentNode)p.push(a),s=a;s===(r.ownerDocument||te)&&p.push(s.defaultView||s.parentWindow||e)}for(i=0;(a=p[i++])&&!t.isPropagationStopped();)t.type=i>1?u:f.bindType||h,c=(Fe.get(a,\"events\")||{})[t.type]&&Fe.get(a,\"handle\"),c&&c.apply(a,n),c=l&&a[l],c&&c.apply&&He(a)&&(t.result=c.apply(a,n),t.result===!1&&t.preventDefault());return t.type=h,o||t.isDefaultPrevented()||f._default&&f._default.apply(p.pop(),n)!==!1||!He(r)||l&&de.isFunction(r[h])&&!de.isWindow(r)&&(s=r[l],s&&(r[l]=null),de.event.triggered=h,r[h](),de.event.triggered=void 0,s&&(r[l]=s)),t.result}},simulate:function(e,t,n){var r=de.extend(new de.Event,n,{type:e,isSimulated:!0});de.event.trigger(r,null,t)}}),de.fn.extend({trigger:function(e,t){return this.each(function(){de.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return de.event.trigger(e,t,n,!0)}}),de.each(\"blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu\".split(\" \"),function(e,t){de.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),de.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),pe.focusin=\"onfocusin\"in e,pe.focusin||de.each({focus:\"focusin\",blur:\"focusout\"},function(e,t){var n=function(e){de.event.simulate(t,e.target,de.event.fix(e))};de.event.special[t]={setup:function(){var r=this.ownerDocument||this,o=Fe.access(r,t);o||r.addEventListener(e,n,!0),Fe.access(r,t,(o||0)+1)},teardown:function(){var r=this.ownerDocument||this,o=Fe.access(r,t)-1;o?Fe.access(r,t,o):(r.removeEventListener(e,n,!0),Fe.remove(r,t))}}});var Tt=e.location,kt=de.now(),jt=/\\?/;de.parseXML=function(t){var n;if(!t||\"string\"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,\"text/xml\")}catch(e){n=void 0}return n&&!n.getElementsByTagName(\"parsererror\").length||de.error(\"Invalid XML: \"+t),n};var Et=/\\[\\]$/,Nt=/\\r?\\n/g,St=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;de.param=function(e,t){var n,r=[],o=function(e,t){var n=de.isFunction(t)?t():t;r[r.length]=encodeURIComponent(e)+\"=\"+encodeURIComponent(null==n?\"\":n)};if(de.isArray(e)||e.jquery&&!de.isPlainObject(e))de.each(e,function(){o(this.name,this.value)});else for(n in e)K(n,e[n],t,o);return r.join(\"&\")},de.fn.extend({serialize:function(){return de.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=de.prop(this,\"elements\");return e?de.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!de(this).is(\":disabled\")&&At.test(this.nodeName)&&!St.test(e)&&(this.checked||!ze.test(e))}).map(function(e,t){var n=de(this).val();return null==n?null:de.isArray(n)?de.map(n,function(e){return{name:t.name,value:e.replace(Nt,\"\\r\\n\")}}):{name:t.name,value:n.replace(Nt,\"\\r\\n\")}}).get()}});var qt=/%20/g,Dt=/#.*$/,Ot=/([?&])_=[^&]*/,Lt=/^(.*?):[ \\t]*([^\\r\\n]*)$/gm,Ht=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ft=/^(?:GET|HEAD)$/,Pt=/^\\/\\//,It={},Rt={},Mt=\"*/\".concat(\"*\"),$t=te.createElement(\"a\");$t.href=Tt.href,de.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Tt.href,type:\"GET\",isLocal:Ht.test(Tt.protocol),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Mt,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":JSON.parse,\"text xml\":de.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Y(Y(e,de.ajaxSettings),t):Y(de.ajaxSettings,e)},ajaxPrefilter:V(It),ajaxTransport:V(Rt),ajax:function(t,n){function r(t,n,r,s){var l,p,h,x,w,C=n;c||(c=!0,u&&e.clearTimeout(u),o=void 0,a=s||\"\",T.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(x=Q(d,T,r)),x=J(d,x,T,l),l?(d.ifModified&&(w=T.getResponseHeader(\"Last-Modified\"),w&&(de.lastModified[i]=w),w=T.getResponseHeader(\"etag\"),w&&(de.etag[i]=w)),204===t||\"HEAD\"===d.type?C=\"nocontent\":304===t?C=\"notmodified\":(C=x.state,p=x.data,h=x.error,l=!h)):(h=C,!t&&C||(C=\"error\",t<0&&(t=0))),T.status=t,T.statusText=(n||C)+\"\",l?v.resolveWith(g,[p,C,T]):v.rejectWith(g,[T,C,h]),T.statusCode(b),b=void 0,f&&m.trigger(l?\"ajaxSuccess\":\"ajaxError\",[T,d,l?p:h]),y.fireWith(g,[T,C]),f&&(m.trigger(\"ajaxComplete\",[T,d]),--de.active||de.event.trigger(\"ajaxStop\")))}\"object\"==typeof t&&(n=t,t=void 0),n=n||{};var o,i,a,s,u,l,c,f,p,h,d=de.ajaxSetup({},n),g=d.context||d,m=d.context&&(g.nodeType||g.jquery)?de(g):de.event,v=de.Deferred(),y=de.Callbacks(\"once memory\"),b=d.statusCode||{},x={},w={},C=\"canceled\",T={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s)for(s={};t=Lt.exec(a);)s[t[1].toLowerCase()]=t[2];t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=w[e.toLowerCase()]=w[e.toLowerCase()]||e,x[e]=t),this},overrideMimeType:function(e){return null==c&&(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)T.always(e[T.status]);else for(t in e)b[t]=[b[t],e[t]];return this},abort:function(e){var t=e||C;return o&&o.abort(t),r(0,t),this}};if(v.promise(T),d.url=((t||d.url||Tt.href)+\"\").replace(Pt,Tt.protocol+\"//\"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=(d.dataType||\"*\").toLowerCase().match(qe)||[\"\"],null==d.crossDomain){l=te.createElement(\"a\");try{l.href=d.url,l.href=l.href,d.crossDomain=$t.protocol+\"//\"+$t.host!=l.protocol+\"//\"+l.host}catch(e){d.crossDomain=!0}}if(d.data&&d.processData&&\"string\"!=typeof d.data&&(d.data=de.param(d.data,d.traditional)),G(It,d,n,T),c)return T;f=de.event&&d.global,f&&0===de.active++&&de.event.trigger(\"ajaxStart\"),d.type=d.type.toUpperCase(),d.hasContent=!Ft.test(d.type),i=d.url.replace(Dt,\"\"),d.hasContent?d.data&&d.processData&&0===(d.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&(d.data=d.data.replace(qt,\"+\")):(h=d.url.slice(i.length),d.data&&(i+=(jt.test(i)?\"&\":\"?\")+d.data,delete d.data),d.cache===!1&&(i=i.replace(Ot,\"$1\"),h=(jt.test(i)?\"&\":\"?\")+\"_=\"+kt++ +h),d.url=i+h),d.ifModified&&(de.lastModified[i]&&T.setRequestHeader(\"If-Modified-Since\",de.lastModified[i]),de.etag[i]&&T.setRequestHeader(\"If-None-Match\",de.etag[i])),(d.data&&d.hasContent&&d.contentType!==!1||n.contentType)&&T.setRequestHeader(\"Content-Type\",d.contentType),T.setRequestHeader(\"Accept\",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(\"*\"!==d.dataTypes[0]?\", \"+Mt+\"; q=0.01\":\"\"):d.accepts[\"*\"]);for(p in d.headers)T.setRequestHeader(p,d.headers[p]);if(d.beforeSend&&(d.beforeSend.call(g,T,d)===!1||c))return T.abort();if(C=\"abort\",y.add(d.complete),T.done(d.success),T.fail(d.error),o=G(Rt,d,n,T)){if(T.readyState=1,f&&m.trigger(\"ajaxSend\",[T,d]),c)return T;d.async&&d.timeout>0&&(u=e.setTimeout(function(){T.abort(\"timeout\")},d.timeout));try{c=!1,o.send(x,r)}catch(e){if(c)throw e;r(-1,e)}}else r(-1,\"No Transport\");return T},getJSON:function(e,t,n){return de.get(e,t,n,\"json\")},getScript:function(e,t){return de.get(e,void 0,t,\"script\")}}),de.each([\"get\",\"post\"],function(e,t){de[t]=function(e,n,r,o){return de.isFunction(n)&&(o=o||r,r=n,n=void 0),de.ajax(de.extend({url:e,type:t,dataType:o,data:n,success:r},de.isPlainObject(e)&&e))}}),de._evalUrl=function(e){return de.ajax({url:e,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,throws:!0})},de.fn.extend({wrapAll:function(e){var t;return this[0]&&(de.isFunction(e)&&(e=e.call(this[0])),t=de(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return de.isFunction(e)?this.each(function(t){de(this).wrapInner(e.call(this,t))}):this.each(function(){var t=de(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=de.isFunction(e);return this.each(function(n){de(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not(\"body\").each(function(){de(this).replaceWith(this.childNodes)}),this}}),de.expr.pseudos.hidden=function(e){return!de.expr.pseudos.visible(e)},de.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},de.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var _t={0:200,1223:204},Wt=de.ajaxSettings.xhr();pe.cors=!!Wt&&\"withCredentials\"in Wt,pe.ajax=Wt=!!Wt,de.ajaxTransport(function(t){var n,r;if(pe.cors||Wt&&!t.crossDomain)return{send:function(o,i){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||o[\"X-Requested-With\"]||(o[\"X-Requested-With\"]=\"XMLHttpRequest\");for(a in o)s.setRequestHeader(a,o[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.onreadystatechange=null,\"abort\"===e?s.abort():\"error\"===e?\"number\"!=typeof s.status?i(0,\"error\"):i(s.status,s.statusText):i(_t[s.status]||s.status,s.statusText,\"text\"!==(s.responseType||\"text\")||\"string\"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=n(\"error\"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n(\"abort\");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),de.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),de.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(e){return de.globalEval(e),e}}}),de.ajaxPrefilter(\"script\",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type=\"GET\")}),de.ajaxTransport(\"script\",function(e){if(e.crossDomain){var t,n;return{send:function(r,o){t=de(\"<script>\").prop({charset:e.scriptCharset,src:e.url}).on(\"load error\",n=function(e){t.remove(),n=null,e&&o(\"error\"===e.type?404:200,e.type)}),te.head.appendChild(t[0])},abort:function(){n&&n()}}}});var Bt=[],Ut=/(=)\\?(?=&|$)|\\?\\?/;de.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var e=Bt.pop()||de.expando+\"_\"+kt++;return this[e]=!0,e}}),de.ajaxPrefilter(\"json jsonp\",function(t,n,r){var o,i,a,s=t.jsonp!==!1&&(Ut.test(t.url)?\"url\":\"string\"==typeof t.data&&0===(t.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&Ut.test(t.data)&&\"data\");if(s||\"jsonp\"===t.dataTypes[0])return o=t.jsonpCallback=de.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(Ut,\"$1\"+o):t.jsonp!==!1&&(t.url+=(jt.test(t.url)?\"&\":\"?\")+t.jsonp+\"=\"+o),t.converters[\"script json\"]=function(){return a||de.error(o+\" was not called\"),a[0]},t.dataTypes[0]=\"json\",i=e[o],e[o]=function(){a=arguments},r.always(function(){void 0===i?de(e).removeProp(o):e[o]=i,t[o]&&(t.jsonpCallback=n.jsonpCallback,Bt.push(o)),a&&de.isFunction(i)&&i(a[0]),a=i=void 0}),\"script\"}),pe.createHTMLDocument=function(){var e=te.implementation.createHTMLDocument(\"\").body;return e.innerHTML=\"<form></form><form></form>\",2===e.childNodes.length}(),de.parseHTML=function(e,t,n){if(\"string\"!=typeof e)return[];\"boolean\"==typeof t&&(n=t,t=!1);var r,o,i;return t||(pe.createHTMLDocument?(t=te.implementation.createHTMLDocument(\"\"),r=t.createElement(\"base\"),r.href=te.location.href,t.head.appendChild(r)):t=te),o=Te.exec(e),i=!n&&[],o?[t.createElement(o[1])]:(o=b([e],t,i),i&&i.length&&de(i).remove(),de.merge([],o.childNodes))},de.fn.load=function(e,t,n){var r,o,i,a=this,s=e.indexOf(\" \");return s>-1&&(r=z(e.slice(s)),e=e.slice(0,s)),de.isFunction(t)?(n=t,t=void 0):t&&\"object\"==typeof t&&(o=\"POST\"),a.length>0&&de.ajax({url:e,type:o||\"GET\",dataType:\"html\",data:t}).done(function(e){i=arguments,a.html(r?de(\"<div>\").append(de.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,i||[e.responseText,t,e])})}),this},de.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(e,t){de.fn[t]=function(e){return this.on(t,e)}}),de.expr.pseudos.animated=function(e){return de.grep(de.timers,function(t){return e===t.elem}).length},de.offset={setOffset:function(e,t,n){var r,o,i,a,s,u,l,c=de.css(e,\"position\"),f=de(e),p={};\"static\"===c&&(e.style.position=\"relative\"),s=f.offset(),i=de.css(e,\"top\"),u=de.css(e,\"left\"),l=(\"absolute\"===c||\"fixed\"===c)&&(i+u).indexOf(\"auto\")>-1,l?(r=f.position(),a=r.top,o=r.left):(a=parseFloat(i)||0,o=parseFloat(u)||0),de.isFunction(t)&&(t=t.call(e,n,de.extend({},s))),null!=t.top&&(p.top=t.top-s.top+a),null!=t.left&&(p.left=t.left-s.left+o),\"using\"in t?t.using.call(e,p):f.css(p)}},de.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){de.offset.setOffset(this,e,t)});var t,n,r,o,i=this[0];if(i)return i.getClientRects().length?(r=i.getBoundingClientRect(),r.width||r.height?(o=i.ownerDocument,n=Z(o),t=o.documentElement,{top:r.top+n.pageYOffset-t.clientTop,left:r.left+n.pageXOffset-t.clientLeft}):r):{top:0,left:0}},position:function(){if(this[0]){var e,t,n=this[0],r={top:0,left:0};return\"fixed\"===de.css(n,\"position\")?t=n.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),de.nodeName(e[0],\"html\")||(r=e.offset()),r={top:r.top+de.css(e[0],\"borderTopWidth\",!0),left:r.left+de.css(e[0],\"borderLeftWidth\",!0)}),{top:t.top-r.top-de.css(n,\"marginTop\",!0),left:t.left-r.left-de.css(n,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&\"static\"===de.css(e,\"position\");)e=e.offsetParent;return e||Ye})}}),de.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(e,t){var n=\"pageYOffset\"===t;de.fn[e]=function(r){return Le(this,function(e,r,o){var i=Z(e);return void 0===o?i?i[t]:e[r]:void(i?i.scrollTo(n?i.pageXOffset:o,n?o:i.pageYOffset):e[r]=o)},e,r,arguments.length)}}),de.each([\"top\",\"left\"],function(e,t){de.cssHooks[t]=O(pe.pixelPosition,function(e,n){if(n)return n=D(e,t),at.test(n)?de(e).position()[t]+\"px\":n})}),de.each({Height:\"height\",Width:\"width\"},function(e,t){de.each({padding:\"inner\"+e,content:t,\"\":\"outer\"+e},function(n,r){de.fn[r]=function(o,i){var a=arguments.length&&(n||\"boolean\"!=typeof o),s=n||(o===!0||i===!0?\"margin\":\"border\");return Le(this,function(t,n,o){var i;return de.isWindow(t)?0===r.indexOf(\"outer\")?t[\"inner\"+e]:t.document.documentElement[\"client\"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body[\"scroll\"+e],i[\"scroll\"+e],t.body[\"offset\"+e],i[\"offset\"+e],i[\"client\"+e])):void 0===o?de.css(t,n,s):de.style(t,n,o,s)},t,a?o:void 0,a)}})}),de.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)}}),de.parseJSON=JSON.parse,\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return de});var zt=e.jQuery,Xt=e.$;return de.noConflict=function(t){return e.$===de&&(e.$=Xt),t&&e.jQuery===de&&(e.jQuery=zt),de},t||(e.jQuery=e.$=de),de})},{}],2:[function(e,t,n){!function(e,n,r){function o(e,t,n){return e.addEventListener?void e.addEventListener(t,n,!1):void e.attachEvent(\"on\"+t,n)}function i(e){if(\"keypress\"==e.type){var t=String.fromCharCode(e.which);return e.shiftKey||(t=t.toLowerCase()),t}return y[e.which]?y[e.which]:b[e.which]?b[e.which]:String.fromCharCode(e.which).toLowerCase()}function a(e,t){return e.sort().join(\",\")===t.sort().join(\",\")}function s(e){var t=[];return e.shiftKey&&t.push(\"shift\"),e.altKey&&t.push(\"alt\"),e.ctrlKey&&t.push(\"ctrl\"),e.metaKey&&t.push(\"meta\"),t}function u(e){return e.preventDefault?void e.preventDefault():void(e.returnValue=!1)}function l(e){return e.stopPropagation?void e.stopPropagation():void(e.cancelBubble=!0)}function c(e){return\"shift\"==e||\"ctrl\"==e||\"alt\"==e||\"meta\"==e}function f(){if(!v){v={};for(var e in y)e>95&&e<112||y.hasOwnProperty(e)&&(v[y[e]]=e)}return v}function p(e,t,n){return n||(n=f()[e]?\"keydown\":\"keypress\"),\"keypress\"==n&&t.length&&(n=\"keydown\"),n}function h(e){return\"+\"===e?[\"+\"]:(e=e.replace(/\\+{2}/g,\"+plus\"),e.split(\"+\"))}function d(e,t){var n,r,o,i=[];for(n=h(e),o=0;o<n.length;++o)r=n[o],w[r]&&(r=w[r]),t&&\"keypress\"!=t&&x[r]&&(r=x[r],i.push(\"shift\")),c(r)&&i.push(r);return t=p(r,i,t),{key:r,modifiers:i,action:t}}function g(e,t){return null!==e&&e!==n&&(e===t||g(e.parentNode,t))}function m(e){function t(e){e=e||{};var t,n=!1;for(t in x)e[t]?n=!0:x[t]=0;n||(T=!1)}function r(e,t,n,r,o,i){var s,u,l=[],f=n.type;if(!y._callbacks[e])return[];for(\"keyup\"==f&&c(e)&&(t=[e]),s=0;s<y._callbacks[e].length;++s)if(u=y._callbacks[e][s],(r||!u.seq||x[u.seq]==u.level)&&f==u.action&&(\"keypress\"==f&&!n.metaKey&&!n.ctrlKey||a(t,u.modifiers))){var p=!r&&u.combo==o,h=r&&u.seq==r&&u.level==i;(p||h)&&y._callbacks[e].splice(s,1),l.push(u)}return l}function f(e,t,n,r){y.stopCallback(t,t.target||t.srcElement,n,r)||e(t,n)===!1&&(u(t),l(t))}function p(e){\"number\"!=typeof e.which&&(e.which=e.keyCode);var t=i(e);if(t)return\"keyup\"==e.type&&w===t?void(w=!1):void y.handleKey(t,s(e),e)}function h(){clearTimeout(b),b=setTimeout(t,1e3)}function g(e,n,r,o){function a(t){return function(){T=t,++x[e],h()}}function s(n){f(r,n,e),\"keyup\"!==o&&(w=i(n)),setTimeout(t,10)}x[e]=0;for(var u=0;u<n.length;++u){var l=u+1===n.length,c=l?s:a(o||d(n[u+1]).action);v(n[u],c,o,e,u)}}function v(e,t,n,o,i){y._directMap[e+\":\"+n]=t,e=e.replace(/\\s+/g,\" \");var a,s=e.split(\" \");return s.length>1?void g(e,s,t,n):(a=d(e,n),y._callbacks[a.key]=y._callbacks[a.key]||[],r(a.key,a.modifiers,{type:a.action},o,e,i),void y._callbacks[a.key][o?\"unshift\":\"push\"]({callback:t,modifiers:a.modifiers,action:a.action,seq:o,level:i,combo:e}))}var y=this;if(e=e||n,!(y instanceof m))return new m(e);y.target=e,y._callbacks={},y._directMap={};var b,x={},w=!1,C=!1,T=!1;y._handleKey=function(e,n,o){var i,a=r(e,n,o),s={},u=0,l=!1;for(i=0;i<a.length;++i)a[i].seq&&(u=Math.max(u,a[i].level));for(i=0;i<a.length;++i)if(a[i].seq){if(a[i].level!=u)continue;l=!0,s[a[i].seq]=1,f(a[i].callback,o,a[i].combo,a[i].seq)}else l||f(a[i].callback,o,a[i].combo);var p=\"keypress\"==o.type&&C;o.type!=T||c(e)||p||t(s),C=l&&\"keydown\"==o.type},y._bindMultiple=function(e,t,n){for(var r=0;r<e.length;++r)v(e[r],t,n)},o(e,\"keypress\",p),o(e,\"keydown\",p),o(e,\"keyup\",p)}if(e){for(var v,y={8:\"backspace\",9:\"tab\",13:\"enter\",16:\"shift\",17:\"ctrl\",18:\"alt\",20:\"capslock\",27:\"esc\",32:\"space\",33:\"pageup\",34:\"pagedown\",35:\"end\",36:\"home\",37:\"left\",38:\"up\",39:\"right\",40:\"down\",45:\"ins\",46:\"del\",91:\"meta\",93:\"meta\",224:\"meta\"},b={106:\"*\",107:\"+\",109:\"-\",110:\".\",111:\"/\",186:\";\",187:\"=\",188:\",\",189:\"-\",190:\".\",191:\"/\",192:\"`\",219:\"[\",220:\"\\\\\",221:\"]\",222:\"'\"},x={\"~\":\"`\",\"!\":\"1\",\"@\":\"2\",\"#\":\"3\",$:\"4\",\"%\":\"5\",\"^\":\"6\",\"&\":\"7\",\"*\":\"8\",\"(\":\"9\",\")\":\"0\",_:\"-\",\"+\":\"=\",\":\":\";\",'\"':\"'\",\"<\":\",\",\">\":\".\",\"?\":\"/\",\"|\":\"\\\\\"},w={option:\"alt\",command:\"meta\",return:\"enter\",escape:\"esc\",plus:\"+\",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?\"meta\":\"ctrl\"},C=1;C<20;++C)y[111+C]=\"f\"+C;for(C=0;C<=9;++C)y[C+96]=C;m.prototype.bind=function(e,t,n){var r=this;return e=e instanceof Array?e:[e],r._bindMultiple.call(r,e,t,n),r},m.prototype.unbind=function(e,t){var n=this;return n.bind.call(n,e,function(){},t)},m.prototype.trigger=function(e,t){var n=this;return n._directMap[e+\":\"+t]&&n._directMap[e+\":\"+t]({},e),n},m.prototype.reset=function(){var e=this;return e._callbacks={},e._directMap={},e},m.prototype.stopCallback=function(e,t){var n=this;return!((\" \"+t.className+\" \").indexOf(\" mousetrap \")>-1)&&(!g(t,n.target)&&(\"INPUT\"==t.tagName||\"SELECT\"==t.tagName||\"TEXTAREA\"==t.tagName||t.isContentEditable))},m.prototype.handleKey=function(){var e=this;return e._handleKey.apply(e,arguments)},m.addKeycodes=function(e){for(var t in e)e.hasOwnProperty(t)&&(y[t]=e[t]);v=null},m.init=function(){var e=m(n);for(var t in e)\"_\"!==t.charAt(0)&&(m[t]=function(t){return function(){return e[t].apply(e,arguments)}}(t))},m.init(),e.Mousetrap=m,\"undefined\"!=typeof t&&t.exports&&(t.exports=m),\"function\"==typeof define&&define.amd&&define(function(){return m})}}(\"undefined\"!=typeof window?window:null,\"undefined\"!=typeof window?document:null)},{}],3:[function(e,t,n){(function(e){!function(r){function o(e){throw new RangeError(L[e])}function i(e,t){for(var n=e.length,r=[];n--;)r[n]=t(e[n]);return r}function a(e,t){var n=e.split(\"@\"),r=\"\";n.length>1&&(r=n[0]+\"@\",e=n[1]),e=e.replace(O,\".\");var o=e.split(\".\"),a=i(o,t).join(\".\");return r+a}function s(e){for(var t,n,r=[],o=0,i=e.length;o<i;)t=e.charCodeAt(o++),t>=55296&&t<=56319&&o<i?(n=e.charCodeAt(o++),56320==(64512&n)?r.push(((1023&t)<<10)+(1023&n)+65536):(r.push(t),o--)):r.push(t);return r}function u(e){return i(e,function(e){var t=\"\";return e>65535&&(e-=65536,t+=P(e>>>10&1023|55296),e=56320|1023&e),t+=P(e)}).join(\"\")}function l(e){return e-48<10?e-22:e-65<26?e-65:e-97<26?e-97:C}function c(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function f(e,t,n){var r=0;for(e=n?F(e/E):e>>1,e+=F(e/t);e>H*k>>1;r+=C)e=F(e/H);return F(r+(H+1)*e/(e+j))}function p(e){var t,n,r,i,a,s,c,p,h,d,g=[],m=e.length,v=0,y=S,b=N;for(n=e.lastIndexOf(A),n<0&&(n=0),r=0;r<n;++r)e.charCodeAt(r)>=128&&o(\"not-basic\"),g.push(e.charCodeAt(r));for(i=n>0?n+1:0;i<m;){for(a=v,s=1,c=C;i>=m&&o(\"invalid-input\"),p=l(e.charCodeAt(i++)),(p>=C||p>F((w-v)/s))&&o(\"overflow\"),v+=p*s,h=c<=b?T:c>=b+k?k:c-b,!(p<h);c+=C)d=C-h,s>F(w/d)&&o(\"overflow\"),s*=d;t=g.length+1,b=f(v-a,t,0==a),F(v/t)>w-y&&o(\"overflow\"),y+=F(v/t),v%=t,g.splice(v++,0,y)}return u(g)}function h(e){var t,n,r,i,a,u,l,p,h,d,g,m,v,y,b,x=[];for(e=s(e),m=e.length,t=S,n=0,a=N,u=0;u<m;++u)g=e[u],g<128&&x.push(P(g));for(r=i=x.length,i&&x.push(A);r<m;){for(l=w,u=0;u<m;++u)g=e[u],g>=t&&g<l&&(l=g);for(v=r+1,l-t>F((w-n)/v)&&o(\"overflow\"),n+=(l-t)*v,t=l,u=0;u<m;++u)if(g=e[u],g<t&&++n>w&&o(\"overflow\"),g==t){for(p=n,h=C;d=h<=a?T:h>=a+k?k:h-a,!(p<d);h+=C)b=p-d,y=C-d,x.push(P(c(d+b%y,0))),p=F(b/y);x.push(P(c(p,0))),a=f(n,v,r==i),n=0,++r}++n,++t}return x.join(\"\")}function d(e){return a(e,function(e){return q.test(e)?p(e.slice(4).toLowerCase()):e})}function g(e){return a(e,function(e){return D.test(e)?\"xn--\"+h(e):e})}var m=\"object\"==typeof n&&n&&!n.nodeType&&n,v=\"object\"==typeof t&&t&&!t.nodeType&&t,y=\"object\"==typeof e&&e;y.global!==y&&y.window!==y&&y.self!==y||(r=y);var b,x,w=2147483647,C=36,T=1,k=26,j=38,E=700,N=72,S=128,A=\"-\",q=/^xn--/,D=/[^\\x20-\\x7E]/,O=/[\\x2E\\u3002\\uFF0E\\uFF61]/g,L={overflow:\"Overflow: input needs wider integers to process\",\"not-basic\":\"Illegal input >= 0x80 (not a basic code point)\",\"invalid-input\":\"Invalid input\"},H=C-T,F=Math.floor,P=String.fromCharCode;if(b={version:\"1.4.1\",ucs2:{decode:s,encode:u},decode:p,encode:h,toASCII:g,toUnicode:d},\"function\"==typeof define&&\"object\"==typeof define.amd&&define.amd)define(\"punycode\",function(){return b});else if(m&&v)if(t.exports==m)v.exports=b;else for(x in b)b.hasOwnProperty(x)&&(m[x]=b[x]);else r.punycode=b}(this)}).call(this,\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{})},{}],4:[function(e,t,n){\"use strict\";function r(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.exports=function(e,t,n,i){t=t||\"&\",n=n||\"=\";var a={};if(\"string\"!=typeof e||0===e.length)return a;var s=/\\+/g;e=e.split(t);var u=1e3;i&&\"number\"==typeof i.maxKeys&&(u=i.maxKeys);var l=e.length;u>0&&l>u&&(l=u);for(var c=0;c<l;++c){var f,p,h,d,g=e[c].replace(s,\"%20\"),m=g.indexOf(n);m>=0?(f=g.substr(0,m),p=g.substr(m+1)):(f=g,p=\"\"),h=decodeURIComponent(f),d=decodeURIComponent(p),\nr(a,h)?o(a[h])?a[h].push(d):a[h]=[a[h],d]:a[h]=d}return a};var o=Array.isArray||function(e){return\"[object Array]\"===Object.prototype.toString.call(e)}},{}],5:[function(e,t,n){\"use strict\";function r(e,t){if(e.map)return e.map(t);for(var n=[],r=0;r<e.length;r++)n.push(t(e[r],r));return n}var o=function(e){switch(typeof e){case\"string\":return e;case\"boolean\":return e?\"true\":\"false\";case\"number\":return isFinite(e)?e:\"\";default:return\"\"}};t.exports=function(e,t,n,s){return t=t||\"&\",n=n||\"=\",null===e&&(e=void 0),\"object\"==typeof e?r(a(e),function(a){var s=encodeURIComponent(o(a))+n;return i(e[a])?r(e[a],function(e){return s+encodeURIComponent(o(e))}).join(t):s+encodeURIComponent(o(e[a]))}).join(t):s?encodeURIComponent(o(s))+n+encodeURIComponent(o(e)):\"\"};var i=Array.isArray||function(e){return\"[object Array]\"===Object.prototype.toString.call(e)},a=Object.keys||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.push(n);return t}},{}],6:[function(e,t,n){\"use strict\";n.decode=n.parse=e(\"./decode\"),n.encode=n.stringify=e(\"./encode\")},{\"./decode\":4,\"./encode\":5}],7:[function(e,t,n){\"use strict\";function r(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}function o(e,t,n){if(e&&l.isObject(e)&&e instanceof r)return e;var o=new r;return o.parse(e,t,n),o}function i(e){return l.isString(e)&&(e=o(e)),e instanceof r?e.format():r.prototype.format.call(e)}function a(e,t){return o(e,!1,!0).resolve(t)}function s(e,t){return e?o(e,!1,!0).resolveObject(t):t}var u=e(\"punycode\"),l=e(\"./util\");n.parse=o,n.resolve=a,n.resolveObject=s,n.format=i,n.Url=r;var c=/^([a-z0-9.+-]+:)/i,f=/:[0-9]*$/,p=/^(\\/\\/?(?!\\/)[^\\?\\s]*)(\\?[^\\s]*)?$/,h=[\"<\",\">\",'\"',\"`\",\" \",\"\\r\",\"\\n\",\"\\t\"],d=[\"{\",\"}\",\"|\",\"\\\\\",\"^\",\"`\"].concat(h),g=[\"'\"].concat(d),m=[\"%\",\"/\",\"?\",\";\",\"#\"].concat(g),v=[\"/\",\"?\",\"#\"],y=255,b=/^[+a-z0-9A-Z_-]{0,63}$/,x=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,w={javascript:!0,\"javascript:\":!0},C={javascript:!0,\"javascript:\":!0},T={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,\"http:\":!0,\"https:\":!0,\"ftp:\":!0,\"gopher:\":!0,\"file:\":!0},k=e(\"querystring\");r.prototype.parse=function(e,t,n){if(!l.isString(e))throw new TypeError(\"Parameter 'url' must be a string, not \"+typeof e);var r=e.indexOf(\"?\"),o=r!==-1&&r<e.indexOf(\"#\")?\"?\":\"#\",i=e.split(o),a=/\\\\/g;i[0]=i[0].replace(a,\"/\"),e=i.join(o);var s=e;if(s=s.trim(),!n&&1===e.split(\"#\").length){var f=p.exec(s);if(f)return this.path=s,this.href=s,this.pathname=f[1],f[2]?(this.search=f[2],t?this.query=k.parse(this.search.substr(1)):this.query=this.search.substr(1)):t&&(this.search=\"\",this.query={}),this}var h=c.exec(s);if(h){h=h[0];var d=h.toLowerCase();this.protocol=d,s=s.substr(h.length)}if(n||h||s.match(/^\\/\\/[^@\\/]+@[^@\\/]+/)){var j=\"//\"===s.substr(0,2);!j||h&&C[h]||(s=s.substr(2),this.slashes=!0)}if(!C[h]&&(j||h&&!T[h])){for(var E=-1,N=0;N<v.length;N++){var S=s.indexOf(v[N]);S!==-1&&(E===-1||S<E)&&(E=S)}var A,q;q=E===-1?s.lastIndexOf(\"@\"):s.lastIndexOf(\"@\",E),q!==-1&&(A=s.slice(0,q),s=s.slice(q+1),this.auth=decodeURIComponent(A)),E=-1;for(var N=0;N<m.length;N++){var S=s.indexOf(m[N]);S!==-1&&(E===-1||S<E)&&(E=S)}E===-1&&(E=s.length),this.host=s.slice(0,E),s=s.slice(E),this.parseHost(),this.hostname=this.hostname||\"\";var D=\"[\"===this.hostname[0]&&\"]\"===this.hostname[this.hostname.length-1];if(!D)for(var O=this.hostname.split(/\\./),N=0,L=O.length;N<L;N++){var H=O[N];if(H&&!H.match(b)){for(var F=\"\",P=0,I=H.length;P<I;P++)F+=H.charCodeAt(P)>127?\"x\":H[P];if(!F.match(b)){var R=O.slice(0,N),M=O.slice(N+1),$=H.match(x);$&&(R.push($[1]),M.unshift($[2])),M.length&&(s=\"/\"+M.join(\".\")+s),this.hostname=R.join(\".\");break}}}this.hostname.length>y?this.hostname=\"\":this.hostname=this.hostname.toLowerCase(),D||(this.hostname=u.toASCII(this.hostname));var _=this.port?\":\"+this.port:\"\",W=this.hostname||\"\";this.host=W+_,this.href+=this.host,D&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),\"/\"!==s[0]&&(s=\"/\"+s))}if(!w[d])for(var N=0,L=g.length;N<L;N++){var B=g[N];if(s.indexOf(B)!==-1){var U=encodeURIComponent(B);U===B&&(U=escape(B)),s=s.split(B).join(U)}}var z=s.indexOf(\"#\");z!==-1&&(this.hash=s.substr(z),s=s.slice(0,z));var X=s.indexOf(\"?\");if(X!==-1?(this.search=s.substr(X),this.query=s.substr(X+1),t&&(this.query=k.parse(this.query)),s=s.slice(0,X)):t&&(this.search=\"\",this.query={}),s&&(this.pathname=s),T[d]&&this.hostname&&!this.pathname&&(this.pathname=\"/\"),this.pathname||this.search){var _=this.pathname||\"\",K=this.search||\"\";this.path=_+K}return this.href=this.format(),this},r.prototype.format=function(){var e=this.auth||\"\";e&&(e=encodeURIComponent(e),e=e.replace(/%3A/i,\":\"),e+=\"@\");var t=this.protocol||\"\",n=this.pathname||\"\",r=this.hash||\"\",o=!1,i=\"\";this.host?o=e+this.host:this.hostname&&(o=e+(this.hostname.indexOf(\":\")===-1?this.hostname:\"[\"+this.hostname+\"]\"),this.port&&(o+=\":\"+this.port)),this.query&&l.isObject(this.query)&&Object.keys(this.query).length&&(i=k.stringify(this.query));var a=this.search||i&&\"?\"+i||\"\";return t&&\":\"!==t.substr(-1)&&(t+=\":\"),this.slashes||(!t||T[t])&&o!==!1?(o=\"//\"+(o||\"\"),n&&\"/\"!==n.charAt(0)&&(n=\"/\"+n)):o||(o=\"\"),r&&\"#\"!==r.charAt(0)&&(r=\"#\"+r),a&&\"?\"!==a.charAt(0)&&(a=\"?\"+a),n=n.replace(/[?#]/g,function(e){return encodeURIComponent(e)}),a=a.replace(\"#\",\"%23\"),t+o+n+a+r},r.prototype.resolve=function(e){return this.resolveObject(o(e,!1,!0)).format()},r.prototype.resolveObject=function(e){if(l.isString(e)){var t=new r;t.parse(e,!1,!0),e=t}for(var n=new r,o=Object.keys(this),i=0;i<o.length;i++){var a=o[i];n[a]=this[a]}if(n.hash=e.hash,\"\"===e.href)return n.href=n.format(),n;if(e.slashes&&!e.protocol){for(var s=Object.keys(e),u=0;u<s.length;u++){var c=s[u];\"protocol\"!==c&&(n[c]=e[c])}return T[n.protocol]&&n.hostname&&!n.pathname&&(n.path=n.pathname=\"/\"),n.href=n.format(),n}if(e.protocol&&e.protocol!==n.protocol){if(!T[e.protocol]){for(var f=Object.keys(e),p=0;p<f.length;p++){var h=f[p];n[h]=e[h]}return n.href=n.format(),n}if(n.protocol=e.protocol,e.host||C[e.protocol])n.pathname=e.pathname;else{for(var d=(e.pathname||\"\").split(\"/\");d.length&&!(e.host=d.shift()););e.host||(e.host=\"\"),e.hostname||(e.hostname=\"\"),\"\"!==d[0]&&d.unshift(\"\"),d.length<2&&d.unshift(\"\"),n.pathname=d.join(\"/\")}if(n.search=e.search,n.query=e.query,n.host=e.host||\"\",n.auth=e.auth,n.hostname=e.hostname||e.host,n.port=e.port,n.pathname||n.search){var g=n.pathname||\"\",m=n.search||\"\";n.path=g+m}return n.slashes=n.slashes||e.slashes,n.href=n.format(),n}var v=n.pathname&&\"/\"===n.pathname.charAt(0),y=e.host||e.pathname&&\"/\"===e.pathname.charAt(0),b=y||v||n.host&&e.pathname,x=b,w=n.pathname&&n.pathname.split(\"/\")||[],d=e.pathname&&e.pathname.split(\"/\")||[],k=n.protocol&&!T[n.protocol];if(k&&(n.hostname=\"\",n.port=null,n.host&&(\"\"===w[0]?w[0]=n.host:w.unshift(n.host)),n.host=\"\",e.protocol&&(e.hostname=null,e.port=null,e.host&&(\"\"===d[0]?d[0]=e.host:d.unshift(e.host)),e.host=null),b=b&&(\"\"===d[0]||\"\"===w[0])),y)n.host=e.host||\"\"===e.host?e.host:n.host,n.hostname=e.hostname||\"\"===e.hostname?e.hostname:n.hostname,n.search=e.search,n.query=e.query,w=d;else if(d.length)w||(w=[]),w.pop(),w=w.concat(d),n.search=e.search,n.query=e.query;else if(!l.isNullOrUndefined(e.search)){if(k){n.hostname=n.host=w.shift();var j=!!(n.host&&n.host.indexOf(\"@\")>0)&&n.host.split(\"@\");j&&(n.auth=j.shift(),n.host=n.hostname=j.shift())}return n.search=e.search,n.query=e.query,l.isNull(n.pathname)&&l.isNull(n.search)||(n.path=(n.pathname?n.pathname:\"\")+(n.search?n.search:\"\")),n.href=n.format(),n}if(!w.length)return n.pathname=null,n.search?n.path=\"/\"+n.search:n.path=null,n.href=n.format(),n;for(var E=w.slice(-1)[0],N=(n.host||e.host||w.length>1)&&(\".\"===E||\"..\"===E)||\"\"===E,S=0,A=w.length;A>=0;A--)E=w[A],\".\"===E?w.splice(A,1):\"..\"===E?(w.splice(A,1),S++):S&&(w.splice(A,1),S--);if(!b&&!x)for(;S--;S)w.unshift(\"..\");!b||\"\"===w[0]||w[0]&&\"/\"===w[0].charAt(0)||w.unshift(\"\"),N&&\"/\"!==w.join(\"/\").substr(-1)&&w.push(\"\");var q=\"\"===w[0]||w[0]&&\"/\"===w[0].charAt(0);if(k){n.hostname=n.host=q?\"\":w.length?w.shift():\"\";var j=!!(n.host&&n.host.indexOf(\"@\")>0)&&n.host.split(\"@\");j&&(n.auth=j.shift(),n.host=n.hostname=j.shift())}return b=b||n.host&&w.length,b&&!q&&w.unshift(\"\"),w.length?n.pathname=w.join(\"/\"):(n.pathname=null,n.path=null),l.isNull(n.pathname)&&l.isNull(n.search)||(n.path=(n.pathname?n.pathname:\"\")+(n.search?n.search:\"\")),n.auth=e.auth||n.auth,n.slashes=n.slashes||e.slashes,n.href=n.format(),n},r.prototype.parseHost=function(){var e=this.host,t=f.exec(e);t&&(t=t[0],\":\"!==t&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)}},{\"./util\":8,punycode:3,querystring:6}],8:[function(e,t,n){\"use strict\";t.exports={isString:function(e){return\"string\"==typeof e},isObject:function(e){return\"object\"==typeof e&&null!==e},isNull:function(e){return null===e},isNullOrUndefined:function(e){return null==e}}},{}],9:[function(e,t,n){function r(e){var t=a(e.currentTarget).parent().find(\".dropdown-menu\");t.toggleClass(\"open\"),e.stopPropagation(),e.preventDefault()}function o(e){a(\".dropdown-menu\").removeClass(\"open\")}function i(){a(document).on(\"click\",\".toggle-dropdown\",r),a(document).on(\"click\",\".dropdown-menu\",function(e){e.stopPropagation()}),a(document).on(\"click\",o)}var a=e(\"jquery\");t.exports={init:i}},{jquery:1}],10:[function(e,t,n){function r(){s.init(),i.init(),o.init(),a.init(),u.createButton({index:0,icon:\"fa fa-align-justify\",onClick:function(e){e.preventDefault(),s.toggle()}})}var o=e(\"./dropdown\"),i=e(\"./keyboard\"),a=e(\"./navigation\"),s=e(\"./sidebar\"),u=e(\"./toolbar\"),l=window.gitbook;l.events.on(\"start\",r),l.keyboard=i,l.navigation=a,l.sidebar=s,l.toolbar=u},{\"./dropdown\":9,\"./keyboard\":11,\"./navigation\":13,\"./sidebar\":15,\"./toolbar\":16}],11:[function(e,t,n){function r(e,t){i.bind(e,function(e){return t(),!1})}function o(){r([\"right\"],function(e){a.goNext()}),r([\"left\"],function(e){a.goPrev()}),r([\"s\"],function(e){s.toggle()})}var i=e(\"mousetrap\"),a=e(\"./navigation\"),s=e(\"./sidebar\");t.exports={init:o,bind:r}},{\"./navigation\":13,\"./sidebar\":15,mousetrap:2}],12:[function(e,t,n){function r(e){return o.state.$book.addClass(\"is-loading\"),e.always(function(){o.state.$book.removeClass(\"is-loading\")}),e}var o=window.gitbook;t.exports={show:r}},{}],13:[function(e,t,n){function r(){return w(k.isSmallScreen()?\".book-body\":\".body-inner\")}function o(e){var t=r(),n=0;i(e)&&(e&&(n=a(e)),t.unbind(\"scroll\"),t.animate({scrollTop:n},800,\"swing\",function(){t.scroll(l)}),s(null,e))}function i(e){var t=r(),n=t.find(e);return!!n.length}function a(e){var t=r(),n=t.find(\".page-inner\"),o=t.find(e),i=o.offsetParent(),a=0;for(a=o.position().top;!i.is(n);)o=i,a+=o.position().top,i=o.offsetParent();return Math.floor(a)}function s(e,t){if(e||t||(e=b.first()),t&&(e=b.length>1?b.filter(function(){var e=u(w(this));return e==t}).first():b.first()),!e.is(x)){x=e,b.removeClass(\"active\"),e.addClass(\"active\"),t=u(e);var n=window.location.pathname+window.location.hash,r=window.location.pathname+t;r!=n&&history.replaceState({path:r},null,r)}}function u(e){var t=e.children(\"a\"),n=t.attr(\"href\").split(\"#\")[1];return n&&(n=\"#\"+n),n?n:\"\"}function l(){var e=r(),t=e.scrollTop(),n=e.prop(\"scrollHeight\"),o=e.prop(\"clientHeight\"),i=b.length,l=null;w(b.get().reverse()).each(function(e){var n,r=u(w(this));r&&!l&&(n=a(r),t>=n&&(l=w(this))),e!=i-1||l||(l=w(this))}),l||t||(l=b.first()),t&&n-t==o&&(l=b.last()),s(l)}function c(e,t){var n=C.parse(N),r=C.resolve(window.location.pathname,e),i=C.parse(r),a=i.hash,s=i.pathname!==n.pathname,u=Boolean(i.hostname);if(!E||u)return void(location.href=e);if(!s)return t&&history.pushState({path:r},null,r),o(a);N=r;var l=w.Deferred(function(e){w.ajax({type:\"GET\",url:r,cache:!0,headers:{\"Access-Control-Expose-Headers\":\"X-Current-Location\"},success:function(n,i,s){var u=s.getResponseHeader(\"X-Current-Location\")||r;n=n.replace(/<(\\/?)(html|head|body)([^>]*)>/gi,function(e,t,n,r){return\"<\"+t+\"div\"+(t?\"\":' data-element=\"'+n+'\"')+r+\">\"});var l,c=w(n),f=c.find(\".book\");if(0===f.length){var h=new Error(\"Invalid gitbook page, redirecting...\");return e.reject(h)}t&&history.pushState({path:u},null,u),c=w(n),l=c.find(\"[data-element=head]\"),f=c.find(\".book\"),document.title=l.find(\"title\").text();var d=w(\"head\");d.find(\"link[rel=prev]\").remove(),d.find(\"link[rel=next]\").remove(),d.append(l.find(\"link[rel=prev]\")),d.append(l.find(\"link[rel=next]\"));var g=w(\".book\").attr(\"class\"),m=w(\".book-summary\").scrollTop();f.toggleClass(\"with-summary\",w(\".book\").hasClass(\"with-summary\")),w(\".book\").replaceWith(f),w(\".book\").attr(\"class\",g),w(\".book-summary\").scrollTop(m),j.state.$book=w(\".book\"),p(!a),a&&o(a),e.resolve()}})}).promise();return T.show(l.fail(function(e){console.log(e)}))}function f(){var e,t;e=parseInt(w(\".body-inner\").css(\"width\"),10),t=parseInt(w(\".page-wrapper\").css(\"width\"),10),w(\".navigation-next\").css(\"margin-right\",e-t+\"px\");var n=r();n.unbind(\"scroll\"),n.scroll(l)}function p(e){var t=w(\".book-body\"),n=t.find(\".body-inner\"),o=n.find(\".page-wrapper\");f(),o.focus();var i=r();e!==!1&&i.scrollTop(0),b=w(\".book-summary .summary .chapter\").filter(function(){var e=w(this).children(\"a\"),t=null;if(!e.length)return!1;t=e.attr(\"href\").split(\"#\")[0];var n=C.resolve(window.location.pathname,t);return window.location.pathname==n}),b.length>1?i.scroll(l):x=b.first()}function h(e){return 0===e.button}function d(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function g(e){var t=w(this),n=t.attr(\"target\");if(!d(e)&&h(e)&&!n){e.stopPropagation(),e.preventDefault();var r=t.attr(\"href\");r&&c(r,!0)}}function m(){var e=w(\".navigation-next\").attr(\"href\");e&&c(e,!0)}function v(){var e=w(\".navigation-prev\").attr(\"href\");e&&c(e,!0)}function y(){w.ajaxSetup({cache:!1}),history.replaceState({path:window.location.href},\"\"),window.onpopstate=function(e){if(null!==e.state)return c(e.state.path,!1)},w(document).on(\"click\",\".navigation-prev\",g),w(document).on(\"click\",\".navigation-next\",g),w(document).on(\"click\",\".summary [data-path] a\",g),w(document).on(\"click\",\".page-inner a\",g),w(window).resize(f),p(!1)}var b,x,w=e(\"jquery\"),C=e(\"url\"),T=e(\"./loading\"),k=e(\"./platform\"),j=window.gitbook,E=\"undefined\"!=typeof history.pushState,N=location.href;t.exports={init:y,goNext:m,goPrev:v}},{\"./loading\":12,\"./platform\":14,jquery:1,url:7}],14:[function(e,t,n){var r=e(\"jquery\");t.exports={isMobile:function(){return r(document).width()<=600},isSmallScreen:function(){return r(document).width()<=1240}}},{jquery:1}],15:[function(e,t,n){function r(e,t){null!=l.state&&o()==e||(null==t&&(t=!0),l.state.$book.toggleClass(\"without-animation\",!t),l.state.$book.toggleClass(\"with-summary\",e),l.storage.set(\"sidebar\",o()))}function o(){return l.state.$book.hasClass(\"with-summary\")}function i(){u.isMobile()||r(l.storage.get(\"sidebar\",!0),!1),s(document).on(\"click\",\".book-summary li.chapter a\",function(e){u.isMobile()&&r(!1,!1)})}function a(e){var t=s(\".book-summary\");t.find(\"li\").each(function(){var t=s(this).data(\"path\"),n=null==e||e.indexOf(t)!==-1;s(this).toggle(n),n&&s(this).parents(\"li\").show()})}var s=e(\"jquery\"),u=e(\"./platform\"),l=window.gitbook;t.exports={init:i,isOpen:o,toggle:r,filter:a}},{\"./platform\":14,jquery:1}],16:[function(e,t,n){function r(){return\"btn-\"+g++}function o(e,t,n,r){var o=e.children(t).length;n<0&&(n=Math.max(0,o+1+n)),e.append(r),n<o&&e.children(t).eq(n).before(e.children(t).last())}function i(e){e.preventDefault()}function a(e){var t=p(\"<div>\",{class:\"dropdown-menu\",html:'<div class=\"dropdown-caret\"><span class=\"caret-outer\"></span><span class=\"caret-inner\"></span></div>'});if(\"string\"==typeof e)t.append(e);else{var n=e.map(function(e){return p.isArray(e)?e:[e]});n.forEach(function(e){var n=p(\"<div>\",{class:\"buttons\"}),r=\"size-\"+e.length;e.forEach(function(e){e=p.extend({text:\"\",className:\"\",onClick:i},e||{});var t=p(\"<button>\",{class:\"button \"+r+\" \"+e.className,text:e.text});t.click(e.onClick),n.append(t)}),t.append(n)})}return t}function s(e){return e=p.extend({label:\"\",icon:\"\",text:\"\",position:\"left\",className:\"\",onClick:i,dropdown:null,index:null,id:r()},e||{}),d.push(e),u(e),e.id}function u(e){var t,n=p(\".book-header\"),r=n.find(\"h1\"),i=\"pull-\"+e.position,s=p(\"<a>\",{class:\"btn\",text:e.text?\" \"+e.text:\"\",\"aria-label\":e.label,href:\"#\"});if(s.click(e.onClick),e.icon&&p(\"<i>\",{class:e.icon}).prependTo(s),e.dropdown){var u=p(\"<div>\",{class:\"dropdown \"+i+\" \"+e.className});s.addClass(\"toggle-dropdown\"),u.append(s);var l=a(e.dropdown);l.addClass(\"dropdown-\"+(\"right\"==e.position?\"left\":\"right\")),u.append(l),t=u}else s.addClass(i),s.addClass(e.className),t=s;t.addClass(\"js-toolbar-action\"),p.isNumeric(e.index)&&e.index>=0?o(n,\".btn, .dropdown, h1\",e.index,t):t.insertBefore(r)}function l(){p(\".js-toolbar-action\").remove(),d.forEach(u)}function c(e){d=p.grep(d,function(t){return t.id!=e}),l()}function f(e){d=p.grep(d,function(t){return e.indexOf(t.id)==-1}),l()}var p=e(\"jquery\"),h=window.gitbook,d=[],g=0;h.events.on(\"page.change\",function(){l()}),t.exports={createButton:s,removeButton:c,removeButtons:f}},{jquery:1}]},{},[10]);\n"
  },
  {
    "path": "atlas-docs/_book/guide-for-use/bundleCommunicate.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>跨bundle的代码重用和通信 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"../update/\" />\n    \n    \n    <link rel=\"prev\" href=\"guide_for_compile.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"./\">\n            \n                <a href=\"./\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"guide_for_build.html\">\n            \n                <a href=\"guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"guide_for_bundle.html\">\n            \n                <a href=\"guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"guide_for_compile.html\">\n            \n                <a href=\"guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.3.4\" data-path=\"bundleCommunicate.html\">\n            \n                <a href=\"bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../update/\">\n            \n                <a href=\"../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../update/principle.html\">\n            \n                <a href=\"../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../update/dexpatch.html\">\n            \n                <a href=\"../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../update/guide.html\">\n            \n                <a href=\"../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../faq/question.html\">\n            \n                <a href=\"../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../faq/help.html\">\n            \n                <a href=\"../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../faq/variant.html\">\n            \n                <a href=\"../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >跨bundle的代码重用和通信</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"android&#x8DE8;classloader&#x7684;&#x6A21;&#x5757;&#x4E4B;&#x95F4;&#x4E92;&#x76F8;&#x901A;&#x4FE1;&#x7684;&#x51E0;&#x79CD;&#x65B9;&#x5F0F;\">Android&#x8DE8;ClassLoader&#x7684;&#x6A21;&#x5757;&#x4E4B;&#x95F4;&#x4E92;&#x76F8;&#x901A;&#x4FE1;&#x7684;&#x51E0;&#x79CD;&#x65B9;&#x5F0F;</h1>\n<h2 id=\"&#x73B0;&#x72B6;\">&#x73B0;&#x72B6;</h2>\n<p>Atlas&#x4F5C;&#x4E3A;java&#x5C42;&#x4EE5;OSGI&#x89C4;&#x8303;&#x8FDB;&#x884C;&#x7EC4;&#x4EF6;&#x5316;&#x89E3;&#x8026;&#x7684;&#x5BB9;&#x5668;&#x3002;&#x5728;&#x4E00;&#x5B9A;&#x5C42;&#x5EA6;&#x4E0A;&#x6E05;&#x6670;&#x4E86;&#x5404;&#x4E2A;&#x6A21;&#x5757;&#x4E4B;&#x95F4;&#x7684;&#x8FB9;&#x754C;&#xFF0C;&#x4FBF;&#x4E8E;&#x5404;&#x4E2A;&#x4E1A;&#x52A1;&#x4EE5;&#x5185;&#x805A;&#x7684;&#x65B9;&#x5F0F;&#x4E0D;&#x65AD;&#x7684;&#x6F14;&#x5316;&#x66F4;&#x65B0;&#x3002;</p>\n<p>&#x4F46;&#x662F;&#x5728;&#x590D;&#x6742;&#x7684;App&#x6BD4;&#x5982;&#x624B;&#x6DD8;&#x8FD9;&#x79CD;&#x65E0;&#x6570;&#x4E2A;&#x4E1A;&#x52A1;&#x4EA4;&#x7EC7;&#x7684;&#x573A;&#x666F;&#x4E0B;&#xFF0C;&#x5B8C;&#x5168;&#x7684;&#x9694;&#x79BB;&#x4E5F;&#x7ED9;&#x4E1A;&#x52A1;&#x7684;&#x5F00;&#x53D1;&#x9020;&#x6210;&#x4E86;&#x4E0D;&#x5C0F;&#x7684;&#x6210;&#x672C;&#x3002;&#x9488;&#x5BF9;&#x8FD9;&#x79CD;&#x95EE;&#x9898;&#xFF0C;&#x76EE;&#x524D;&#x4E3B;&#x8981;&#x89E3;&#x51B3;&#x7684;&#x65B9;&#x6848;&#x6709;&#xFF1A;</p>\n<ol>\n<li>&#x53C2;&#x7167;&#x591A;&#x4E2A;App&#x4E4B;&#x95F4;&#x901A;&#x4FE1;&#x7684;&#x65B9;&#x5F0F;&#xFF0C;&#x4F7F;&#x7528;AIDL&#x53EF;&#x4EE5;&#x4F5C;&#x4E3A;&#x7EC4;&#x4EF6;&#x4E4B;&#x95F4;&#x8FDB;&#x884C;&#x4E00;&#x5B9A;&#x5C42;&#x5EA6;&#x901A;&#x4FE1;&#x7684;&#x65B9;&#x5F0F;&#x3002;</li>\n<li>&#x4F7F;&#x7528;&#x57FA;&#x4E8E;&#x5BB9;&#x5668;&#x7684;&#x5B9E;&#x73B0;&#x5F00;&#x53D1;&#x7684;ServiceHub&#xFF0C;&#x8DDF;AIDL&#x4E00;&#x6837;&#x5C06;&#x63A5;&#x53E3;&#x653E;&#x5230;&#x516C;&#x5171;Library&#xFF0C;&#x7136;&#x540E;ServiceHub&#x4E2D;&#x5199;&#x5165;&#x63A5;&#x53E3;&#x548C;&#x5B9E;&#x73B0;&#x7684;&#x5BF9;&#x5E94;&#x5173;&#x7CFB;&#x3002;&#x4F7F;&#x7528;&#x65B9;&#x901A;&#x8FC7;ServiceHub&#x5F97;&#x5230;&#x63A5;&#x53E3;&#x5B9E;&#x73B0;&#x8FDB;&#x884C;&#x4F7F;&#x7528;&#x3002;</li>\n</ol>\n<h2 id=\"&#x7F3A;&#x9677;\">&#x7F3A;&#x9677;</h2>\n<p>AIDL&#x3001;ServiceHub&#x89E3;&#x51B3;&#x4E86;&#x90E8;&#x5206;bundle&#x4E4B;&#x95F4;&#x901A;&#x4FE1;&#x6216;&#x8005;&#x4EE3;&#x7801;&#x590D;&#x7528;&#x7684;&#x95EE;&#x9898;&#x3002;&#x4F46;&#x662F;&#x8FD9;&#x4E24;&#x8005;&#x4E5F;&#x5B58;&#x5728;&#x7740;&#x5F88;&#x5927;&#x7684;&#x4E0D;&#x8DB3;&#x3002;&#x4E00;&#x65B9;&#x9762;AIDL&#x9650;&#x5236;&#x4E86;&#x53EA;&#x80FD;&#x4F20;&#x9012;parcel&#x4EE5;&#x53CA;&#x7B80;&#x5355;&#x5BF9;&#x8C61;&#xFF0C;&#x5BF9;&#x4E8E;UI&#x590D;&#x7528;&#x6BD4;&#x5982;&#x8BF4;Richview&#x7684;&#x91CD;&#x7528;&#x5219;&#x5B8C;&#x5168;&#x884C;&#x4E0D;&#x901A;&#xFF0C;&#x540C;&#x65F6;&#x4F7F;&#x7528;&#x6210;&#x672C;&#x4E5F;&#x662F;ServiceHub&#x7684;&#x673A;&#x5236;&#x7684;&#x4E00;&#x4E2A;&#x75DB;&#x70B9;&#xFF0C;&#x4E1A;&#x52A1;&#x65B9;&#x9700;&#x8981;&#x63D0;&#x524D;&#x5C06;&#x65B0;&#x7684;&#x63A5;&#x53E3;&#x63D0;&#x524D;&#x6CE8;&#x518C;&#x5230;ServiceHub&#x3002;</p>\n<h2 id=\"&#x65B0;&#x7684;&#x673A;&#x5236;\">&#x65B0;&#x7684;&#x673A;&#x5236;</h2>\n<p>&#x65B0;&#x7684;&#x7EC4;&#x4EF6;&#x4E4B;&#x95F4;&#x7684;&#x91CD;&#x7528;&#x53CA;&#x901A;&#x4FE1;&#x7B56;&#x7565;&#x5EF6;&#x7EED;&#x4E86;AIDL&#x514D;&#x6CE8;&#x518C;&#x7684;&#x65B9;&#x5F0F;&#xFF0C;&#x540C;&#x65F6;&#x89E3;&#x51B3;&#x4E86;&#x8DE8;classloader&#x60C5;&#x51B5;&#x4E0B;UI&#x590D;&#x7528;&#x7684;&#x95EE;&#x9898;&#x3002;&#x65B0;&#x7684;&#x65B9;&#x5F0F;&#x5C06;&#x91CD;&#x7528;&#x7C7B;&#x578B;&#x5F52;&#x4E3A;RemoteFragment&#x3001;RemoteView&#x3001;RemoteTransaction&#x4E09;&#x79CD;&#x7C7B;&#x578B;&#x3002;</p>\n<h3 id=\"remotefragment\">RemoteFragment</h3>\n<p>RemoteFragment&#x9002;&#x7528;&#x4E8E;&#x67D0;&#x4E2A;Bundle&#x4E2D;&#x6709;&#x516C;&#x5171;&#x7684;Fragment&#x8981;&#x63D0;&#x4F9B;&#x7ED9;&#x4E00;&#x4E2A;&#x6216;&#x8005;&#x591A;&#x4E2A;&#x5176;&#x4ED6;&#x4E1A;&#x52A1;bundle&#x4F7F;&#x7528;&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x6BD4;&#x5982;&#x8BF4;&#x5728;&#x624B;&#x6DD8;&#x91CC;&#x9762;&#xFF0C;SkuFragment(sku&#x9009;&#x62E9;&#x754C;&#x9762;)&#x53EF;&#x80FD;&#x4F1A;&#x63D0;&#x4F9B;&#x7ED9;&#x8BE6;&#x60C5;&#xFF0C;&#x8D2D;&#x7269;&#x8F66;&#xFF0C;&#x805A;&#x5212;&#x7B97;&#x7B49;&#x591A;&#x4E2A;&#x4E1A;&#x52A1;&#x4F7F;&#x7528;&#xFF1B;&#x6216;&#x8005;&#x5728;&#x67D0;&#x4E9B;App&#x91CC;&#x9762;&#xFF0C;&#x767B;&#x5F55;&#x754C;&#x9762;&#x4E5F;&#x4EE5;LoginFragment&#x7684;&#x65B9;&#x5F0F;&#x63D0;&#x4F9B;&#x7ED9;Bundle&#x6309;&#x9700;&#x4F7F;&#x7528;&#x3002;</p>\n<ol>\n<li><p>&#x4F7F;&#x7528;&#x65B9;&#x5F0F;</p>\n<ol>\n<li><p>&#x4EE3;&#x7801;&#x6539;&#x52A8;&#xFF1A;&#x4EE5;LoginFragment&#x4E3A;&#x4F8B;&#xFF0C;LoginBundle&#x9700;&#x8981;&#x5728;&#x81EA;&#x5DF1;&#x7684;LoginFragment&#x505A;&#x4E00;&#x5B9A;&#x7684;&#x6539;&#x52A8;</p>\n<p>```\npublic class LoginFragment extends Fragment implements IRemote{</p>\n</li>\n</ol>\n</li>\n</ol>\n<pre><code>        @Override\n        public Bundle call(String commandName, Bundle args, IResponse callback) {\n            return null;\n        }\n\n        @Override\n        public &lt;T&gt; T getRemoteInterface(Class&lt;T&gt; interfaceClass,Bundle args) {\n            return null;\n        }\n</code></pre><p>}</p>\n<pre><code>\n        LoginFragment &#x9700;&#x8981;&#x5728;&#x539F;&#x6765;&#x7684;&#x57FA;&#x7840;&#x4E0A;&#x5B9E;&#x73B0;IRemote&#x63A5;&#x53E3;&#xFF0C;IRemote&#x6765;&#x81EA;Atlas&#x5BB9;&#x5668;&#x7684;&#x5185;&#x90E8;&#x5B9E;&#x73B0;&#xFF0C;&#x6682;&#x65F6;&#x8FD8;&#x672A;&#x4ECE;&#x5BB9;&#x5668;&#x4E2D;&#x62C6;&#x5206;&#x51FA;&#x5DEE;&#xFF0C;&#x8FD9;&#x4E5F;&#x610F;&#x5473;&#x7740;&#x4E1A;&#x52A1;&#x65B9;&#x9700;&#x8981;&#x589E;&#x52A0;&#x5BF9;atlas&#x7684;&#x4F9D;&#x8D56;&#x3002;**IRemote&#x5B9E;&#x73B0;&#x7684;&#x4E24;&#x4E2A;&#x63A5;&#x53E3;&#x4F1A;&#x5728;&#x6587;&#x7AE0;&#x540E;&#x9762;&#x89E3;&#x91CA;**\n\n\n\n       2. Bundle&#x7684;AndroidManifest.xml&#x4E2D;&#x8FDB;&#x884C;&#x6CE8;&#x518C;\n</code></pre><pre><code>       &lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;\n    package=&quot;com.taobao.login&quot;&gt;\n        &lt;application&gt;\n               &lt;meta-data android:name=&quot;atlas.fragment.intent.action.LOGIN&quot;\n                    android:value=&quot;com.taobao.login.LoginFragment&quot; /&gt;\n        &lt;/application&gt;\n    &lt;/manifest&gt;\n       ```\nRemote&#x7EC4;&#x4EF6;&#x53C2;&#x7167;AIDL&#x7684;&#x65B9;&#x5F0F;&#x5728;manifest&#x4E2D;&#x8FDB;&#x884C;&#x6CE8;&#x518C;&#x3002;&#x67E5;&#x627E;&#x65F6;&#x4EE5;meta-data&#x7684;name&#x505A;key&#x8FDB;&#x884C;&#x67E5;&#x627E;&#xFF0C;RemoteFragment&#x7684;key&#x5FC5;&#x987B;&#x4EE5;**atlas.fragment.intent.action.**&#x5F00;&#x5934;&#x3002;\n\n3. &#x4F7F;&#x7528;&#x65B9;&#x5982;&#x4F55;&#x8C03;&#x7528;RemoteFragment\n\n    ```\n    public class SampleActivity extends FragmentActivity{\n        public void doLogin(){\n            Intent loginIntent = new Intent(&quot;atlas.fragment.intent.action.LOGIN&quot;);\n            RemoteFactory.requestRemote(RemoteFragment.class,loginIntent, \n                new RemoteFactory.OnRemoteStateListener&lt;RemoteFragment&gt;() {\n                @Override\n                public void onRemotePrepared(RemoteFragment fragment) {\n                    getSupportFragmentManager().beginTransaction().add(R.id.container,fragment).commit();\n                }\n                @Override\n                public void onFailed(String errorInfo) {\n                    // Redirect to h5 login or downgrade\n                }\n            });\n        }\n</code></pre><p>}</p>\n<pre><code>    ```\n    &#x4E1A;&#x52A1;&#x4F7F;&#x7528;&#x65B9;&#x8C03;&#x7528;Atlas&#x7684;RemoteFactory&#x7684;&#x63A5;&#x53E3;&#x8FDB;&#x884C;request&#xFF0C;&#x7531;&#x4E8E;&#x671F;&#x95F4;&#x53EF;&#x80FD;&#x6D89;&#x53CA;&#x5230;bundle&#x7684;&#x5B89;&#x88C5;&#xFF0C;&#x6240;&#x4EE5;&#x6574;&#x4E2A;&#x8FC7;&#x7A0B;&#x91C7;&#x7528;callback&#x7684;&#x65B9;&#x5F0F;&#x3002;&#x83B7;&#x53D6;&#x5230;RemoteFragment&#x7684;&#x53E5;&#x67C4;&#x540E;&#x76F4;&#x63A5;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;&#x5373;&#x53EF;&#x3002;**&#x5EFA;&#x8BAE;Fragment&#x91CC;&#x9762;&#x6D89;&#x53CA;&#x5230;&#x7684;&#x4EA4;&#x4E92;&#x529F;&#x80FD;&#x7B49;&#x7684;&#x4EE3;&#x7801;&#x5C01;&#x88C5;&#x5728;Fragment&#x5185;&#x90E8;**&#xFF0C;&#x6BD4;&#x5982;&#x8BF4;LoginFragment&#x91CC;&#x9762;&#x6240;&#x6709;&#x6309;&#x94AE;&#x7684;&#x70B9;&#x51FB;&#x4EE5;&#x53CA;&#x5F02;&#x5E38;&#x5904;&#x7406;&#x5168;&#x90FD;Fragment&#x5185;&#x90E8;&#x8FDB;&#x884C;&#x5B9E;&#x73B0;&#x3002;&#x8FD9;&#x6837;&#x7684;&#x8BDD;&#x4E24;&#x4E2A;Bundle&#x4E4B;&#x95F4;&#x7684;&#x8FB9;&#x754C;&#x4E5F;&#x66F4;&#x6E05;&#x6670;&#x3002;\n</code></pre><blockquote>\n<p>&#x95EE;&#x9898;&#xFF1A;RemoteFragment &#x5982;&#x4F55;&#x901A;&#x77E5;&#x5916;&#x90E8;&#x767B;&#x5F55;&#x6210;&#x529F;&#x6216;&#x8005;&#x5931;&#x8D25;&#xFF0C;&#x9664;&#x4E86;&#x7528;&#x7CFB;&#x7EDF;&#x7684;&#x5E7F;&#x64AD;&#x7B49;&#x673A;&#x5236;&#xFF0C;&#x80FD;&#x5426;&#x57FA;&#x4E8E;Remote&#x7684;&#x673A;&#x5236;&#x66F4;&#x76F4;&#x63A5;&#x5730;&#x65B9;&#x4FBF;&#x5730;&#x5B9E;&#x73B0;&#x8BE5;&#x529F;&#x80FD;&#x5462;&#xFF1F;&#x540E;&#x7EED;RemoteTransaction&#x4E2D;&#x4F1A;&#x9610;&#x8FF0;&#x5177;&#x4F53;&#x7684;&#x7528;&#x6CD5;&#x3002;</p>\n</blockquote>\n<ol>\n<li><p>&#x5B9E;&#x73B0;&#x7684;&#x673A;&#x5236;\n &#x5148;&#x9644;&#x4E00;&#x5F20;Fragment&#x542F;&#x52A8;&#x56FE;&#xFF0C;&#x4E0D;&#x6E05;&#x695A;&#x7684;&#x540C;&#x5B66;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8FD9;&#x4E2A;&#x5927;&#x81F4;&#x4E86;&#x89E3;&#x6574;&#x4E2A;Fragment&#x542F;&#x52A8;&#x7684;&#x4E00;&#x4E9B;&#x65B9;&#x6CD5;&#x8C03;&#x7528;&#xFF0C;&#x7406;&#x6E05;Fragment&#x548C;Activity&#x5728;&#x542F;&#x52A8;&#x65F6;&#x7684;&#x4E00;&#x4E9B;&#x4EA4;&#x7EC7;&#x7684;&#x5173;&#x7CFB;(&#x56FE;&#x7247;&#x53EF;&#x80FD;&#x9700;&#x8981;&#x4E0B;&#x8F7D;&#x653E;&#x5927;&#x4E86;&#x89C2;&#x770B;)&#x3002;\n <img src=\"fragment-start.png\" alt=\"\">\n RemoteFragment&#x672C;&#x8EAB;&#x4E5F;&#x662F;&#x771F;&#x6B63;&#x610F;&#x4E49;&#x4E0A;&#x7684;Fragment&#xFF0C;&#x6240;&#x4EE5;&#x53EF;&#x4EE5;&#x7528;&#x6765;&#x76F4;&#x63A5;&#x88AB;FragmentManager&#x6216;&#x8005;FragmentTransaction&#x76F4;&#x63A5;&#x8FDB;&#x884C;&#x7BA1;&#x7406;&#xFF1B;&#x540C;&#x65F6;&#x5B83;&#x4E5F;&#x662F;&#x771F;&#x6B63;&#x7684;LoginFragment&#x7684;&#x5728;&#x4F7F;&#x7528;&#x65B9;&#x7684;&#x4EE3;&#x7406;&#x3002;&#x4ED6;&#x4EEC;&#x4E4B;&#x95F4;&#x7684;&#x5173;&#x7CFB;&#x5982;&#x4E0B;&#xFF1A;</p>\n<pre><code> ![](fragment-relation.png)\n</code></pre><p> &#x4F7F;&#x7528;&#x8005;&#x5E94;&#x8BE5;&#x4E86;&#x89E3;RemoteFragment&#x673A;&#x5236;&#x7684;&#x4EE5;&#x4E0B;&#x51E0;&#x4E2A;&#x7279;&#x70B9;&#xFF0C;&#x660E;&#x767D;&#x5176;&#x5185;&#x90E8;&#x5B9E;&#x73B0;&#x7684;&#x4E3B;&#x8981;&#x673A;&#x5236;&#xFF1A;</p>\n<ul>\n<li>RemoteFragment&#x7684;&#x4F7F;&#x7528;&#x65B9;&#x62FF;&#x5230;&#x7684;&#x4EC5;&#x4EC5;&#x662F;&#x76EE;&#x6807;fragment&#x7684;&#x4EE3;&#x7406;&#xFF0C;&#x6240;&#x4EE5;&#x771F;&#x6B63;&#x7684;&#x5B9E;&#x73B0;&#x5BF9;&#x4F7F;&#x7528;&#x65B9;&#x6765;&#x8BF4;&#x662F;&#x4E0D;&#x53EF;&#x89C1;&#x7684;&#x3002;&#x5982;&#x679C;&#x9664;&#x4E86;&#x62FF;&#x5230;Fragment&#x5C55;&#x793A;&#x4E4B;&#x5916;&#x8FD8;&#x6709;&#x5176;&#x4ED6;&#x7684;&#x63A5;&#x53E3;&#x9700;&#x8981;&#x66B4;&#x9732;&#x7ED9;&#x4F7F;&#x7528;&#x8005;&#xFF0C;&#x5219;&#x9700;&#x8981;&#x8D70;<strong>Remote&#x7684;&#x901A;&#x4FE1;&#x673A;&#x5236;</strong>&#x3002;</li>\n<li><p>EmbeddActivity&#x624D;&#x662F;&#x771F;&#x6B63;&#x76EE;&#x6807;Fragment&#x5B9E;&#x4F8B;&#x5316;&#x6240;&#x9700;&#x8981;&#x7684;context&#xFF0C;EmbeddActivity&#x662F;&#x7531;RemoteFragment&#x521D;&#x59CB;&#x5316;&#x65F6;&#x521B;&#x5EFA;&#x7684;Activity&#xFF0C;&#x7528;&#x4E8E;&#x7ED9;&#x76EE;&#x6807;Fragment&#x521D;&#x59CB;&#x5316;UI&#xFF0C;&#x5B83;&#x662F;&#x771F;&#x6B63;&#x7684;Activity&#xFF0C;&#x4F46;&#x662F;&#x6CA1;&#x6709;&#x754C;&#x9762;&#xFF0C;&#x540C;&#x65F6;&#x4E5F;&#x6CA1;&#x6709;&#x6709;&#x6548;&#x7684;WindowManager&#xFF0C;&#x6D89;&#x53CA;&#x5230;Window&#x64CD;&#x4F5C;&#x7684;&#x4F1A;&#x81EA;&#x52A8;&#x8F6C;&#x4EA4;&#x7ED9;SampleActivity&#x8FDB;&#x884C;&#x5904;&#x7406;&#x3002;EmbeddActivity&#x662F;bundle&#x4E4B;&#x95F4;&#x4E0D;&#x9700;&#x8981;&#x4F9D;&#x8D56;&#x76F4;&#x63A5;&#x4F7F;&#x7528;UI&#x6700;&#x6839;&#x672C;&#x7684;&#x4FDD;&#x8BC1;&#x3002;</p>\n<blockquote>\n<p>&#x8BBE;&#x60F3;&#x4E00;&#x4E0B;&#xFF0C;&#x5982;&#x679C;&#x4E00;&#x4E2A;Activity&#x5F15;&#x7528;&#x4E86;5&#x4E2A;&#x6765;&#x81EA;&#x4E0D;&#x540C;Bundle&#x7684;RemoteFragment&#xFF0C;&#x90A3;&#x4E48;&#x76F8;&#x5F53;&#x4E8E;&#x8FD9;&#x4E2A;Activity&#x5185;&#x5D4C;&#x4E86;5&#x4E2A;EmbeddActivity&#xFF1B;&#x90A3;&#x5982;&#x679C;&#x5F15;&#x7528;&#x4E86;5&#x4E2A;&#x6765;&#x81EA;&#x540C;&#x4E00;&#x4E2A;Bundle&#x7684;RemoteFragment&#x5462;&#xFF1F;</p>\n</blockquote>\n</li>\n<li><p>&#x76EE;&#x6807;Fragment&#x4E0E;SampleActivity&#x4E4B;&#x95F4;&#x8FD8;&#x662F;&#x4FDD;&#x6301;&#x5B8C;&#x6574;&#x7684;&#x9694;&#x79BB;&#xFF0C;&#x6240;&#x4EE5;&#x76EE;&#x6807;Fragment&#x4E5F;&#x65E0;&#x6CD5;&#x83B7;&#x53D6;&#x5BBF;&#x4E3B;&#x7684;&#x5F15;&#x7528;&#xFF0C;&#x6240;&#x4EE5;&#x5982;&#x679C;&#x76EE;&#x6807;Fragment&#x9700;&#x8981;&#x4E0E;SampleActivity&#x53D1;&#x751F;&#x901A;&#x4FE1;&#xFF0C;&#x5219;&#x4E5F;&#x8981;&#x9075;&#x5FAA;<strong>Remote&#x7684;&#x901A;&#x4FE1;&#x673A;&#x5236;</strong></p>\n</li>\n</ul>\n</li>\n</ol>\n<h3 id=\"remoteview\">RemoteView</h3>\n<p>&#x4E0E;RemoteFragment &#x7C7B;&#x4F3C;&#xFF0C;RemoteView&#x63D0;&#x4F9B;&#x66F4;&#x7EC6;&#x7C92;&#x5EA6;&#x7684;bundle&#x95F4;&#x7684;UI&#x590D;&#x7528;&#x3002;</p>\n<ol>\n<li><p>&#x4F7F;&#x7528;&#x65B9;&#x5F0F;</p>\n<ol>\n<li><p>&#x4EE3;&#x7801;&#x6539;&#x52A8;</p>\n<pre><code> public class SampleRichView extends FrameLayout implements IRemote{\n     @Override\n     public Bundle call(String commandName, Bundle args, IResponse callback) {\n         return null;\n     }\n     @Override\n     public &lt;T&gt; T getRemoteInterface(Class&lt;T&gt; interfaceClass,Bundle args) {\n         return null;\n     }\n}\n</code></pre></li>\n<li><p>AndroidManifest&#x4FEE;&#x6539;&#xFF0C;RemoteView&#x7684;key&#x4EE5;<strong>atlas.view.intent.action.</strong>&#x5F00;&#x5934;</p>\n<pre><code>    &lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;\n         package=&quot;com.taobao.sample&quot;&gt;\n     &lt;application&gt;\n            &lt;meta-data android:name=&quot;atlas.fragment.intent.action.SAMPLE_RICH&quot;\n                 android:value=&quot;com.taobao.sample.SampleRichView&quot; /&gt;\n     &lt;/application&gt;\n &lt;/manifest&gt;\n</code></pre><ol>\n<li><p>&#x4F7F;&#x7528;&#x65B9;&#x5982;&#x4F55;&#x8C03;&#x7528;RemoteView</p>\n<pre><code>public class SampleActivity extends Activity{\n  public void inflateRemoteView(FrameLayout container){\n      Intent sIntent = new Intent(&quot;atlas.view.intent.action.SAMPLE_RICH&quot;);\n      RemoteFactory.requestRemote(RemoteView.class, sIntent, \n          new RemoteFactory.OnRemoteStateListener&lt;RemoteView&gt;() {\n          @Override\n          public void onRemotePrepared(RemoteView remoteView) {\n              ViewGroup.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);\n              container.addView(remoteView,params);\n          }\n          @Override\n          public void onFailed(String errorInfo) {\n              // downgrade\n          }\n      });\n  }\n}\n</code></pre></li>\n</ol>\n</li>\n</ol>\n</li>\n<li><p>&#x5B9E;&#x73B0;&#x673A;&#x5236;</p>\n<p> RemoteView&#x4E0E;RemoteFragment&#x5B9E;&#x73B0;&#x57FA;&#x672C;&#x4E00;&#x81F4;&#xFF0C;&#x9700;&#x8981;EmbeddedActivity&#x4F5C;&#x4E3A;&#x771F;&#x6B63;View&#x81A8;&#x5316;&#x7684;&#x57FA;&#x672C;&#x6761;&#x4EF6;&#xFF0C;RemoteView&#x672C;&#x8EAB;&#x53EA;&#x662F;&#x4E00;&#x4E2A;FrameLayout&#xFF0C;&#x5C31;&#x50CF;DecorView&#xFF0C;&#x76EE;&#x6807;View&#x4F5C;&#x4E3A;&#x5B50;View&#x6DFB;&#x52A0;&#x5728;&#x91CC;&#x9762;&#x3002;&#x5F53;&#x7136;&#x8FD9;&#x4E2A;&#x673A;&#x5236;&#x4E5F;&#x6709;&#x4E00;&#x5B9A;&#x7684;&#x9690;&#x60A3;&#xFF0C;<strong>&#x4F7F;&#x7528;&#x65B9;&#x4E0D;&#x8981;&#x901A;&#x8FC7;findViewByID&#x6216;&#x8005;getChildAt&#x7B49;viewGroup&#x7684;public &#x65B9;&#x6CD5;&#x5C1D;&#x8BD5;&#x83B7;&#x53D6;&#x76EE;&#x6807;view&#x5E76;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;&#xFF0C;RemoteView&#x5E94;&#x8BE5;&#x88AB;&#x5F53;&#x505A;View&#x800C;&#x4E0D;&#x662F;ViewGroup&#xFF0C;&#x4E0E;&#x76EE;&#x6807;View&#x7684;&#x901A;&#x4FE1;&#x5E94;&#x8BE5;&#x901A;&#x8FC7;Remote&#x7684;&#x673A;&#x5236;&#x8FDB;&#x884C;</strong></p>\n</li>\n</ol>\n<h3 id=\"remotetransact\">RemoteTransact</h3>\n<p>RemoteTransact&#x76F8;&#x5F53;&#x4E8E;&#x662F;RemoteView&#x6216;&#x8005;RemoteFragment&#x7684;&#x7B80;&#x5316;&#x7248;&#xFF0C;&#x4EC5;&#x4EC5;&#x4E3A;&#x4E86;bundle&#x548C;bundle&#x4E4B;&#x95F4;&#x7684;&#x901A;&#x4FE1;&#x800C;&#x5B58;&#x5728;&#xFF0C;&#x5B83;&#x548C;RemoteView&#xFF0C;RemoteFragment&#x90FD;&#x5B9E;&#x73B0;&#x4E86;IRemoteTransact&#x63A5;&#x53E3;&#x3002;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4E0B;&#x9762;&#x7684;&#x8349;&#x56FE;&#x4E86;&#x89E3;&#x5927;&#x81F4;&#x7684;&#x5173;&#x7CFB;&#xFF1A;\n<img src=\"class-relation.png\" alt=\"\">\n&#x4EE5;RemoteTransactor&#x4E3A;&#x4F8B;&#xFF0C;&#x4ED6;&#x548C;&#x76EE;&#x6807;Transactor&#x7C7B;&#x90FD;&#x5B9E;&#x73B0;&#x4E86;IRemoteTransactor&#xFF0C;&#x6240;&#x4EE5;&#x5F53;&#x4F7F;&#x7528;&#x65B9;&#x8C03;&#x7528;IRemoteTransactor&#x7684;&#x63A5;&#x53E3;&#x65F6;&#x5019;&#xFF0C;Remote&#x5BF9;&#x8C61;&#x5C06;&#x65B9;&#x6CD5;&#x8DEF;&#x7531;&#x5230;&#x76EE;&#x6807;&#x5BF9;&#x8C61;&#x7684;&#x65B9;&#x6CD5;&#x4E0A;&#x3002;</p>\n<p>&#x4F7F;&#x7528;&#x8005;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8FD9;&#x4E24;&#x4E2A;&#x65B9;&#x6CD5;&#x4E0E;&#x771F;&#x6B63;&#x7684;&#x8FDC;&#x7AEF;&#x5BF9;&#x8C61;&#x8FDB;&#x884C;&#x901A;&#x4FE1;&#xFF1A;</p>\n<pre><code>public Bundle call(String commandName, Bundle args, IResponse callback)\n</code></pre><ul>\n<li>&#x4EE5;&#x547D;&#x4EE4;&#x7684;&#x65B9;&#x5F0F;&#x901A;&#x77E5;&#x76EE;&#x6807;&#x5BF9;&#x8C61;&#xFF0C;&#x5982;&#x679C;&#x662F;&#x5F02;&#x6B65;&#x8FD4;&#x56DE;&#xFF0C;&#x5219;&#x8FDC;&#x7AEF;&#x901A;&#x8FC7;&#x4F20;&#x5165;&#x7684;callback&#x63A5;&#x53E3;&#x8FDB;&#x884C;&#x56DE;&#x8C03;&#xFF0C;&#x5982;&#x679C;&#x4E0D;&#x662F;&#xFF0C;&#x5219;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;&#xFF0C;&#x9002;&#x7528;&#x4E8E;&#x4F7F;&#x7528;&#x65B9;&#x548C;&#x8FDC;&#x7AEF;&#x5B58;&#x5728;&#x7B80;&#x5355;&#x901A;&#x4FE1;&#x7684;&#x60C5;&#x51B5;&#x3002;</li>\n</ul>\n<pre><code>public &lt;T&gt; T getRemoteInterface(Class&lt;T&gt; interfaceClass,Bundle args)\n</code></pre><ul>\n<li>&#x8FDC;&#x7AEF;&#x672C;&#x8EAB;&#x5DF2;&#x7ECF;&#x6709;&#x5C01;&#x88C5;&#x8FC7;&#x5177;&#x4F53;&#x7684;&#x63A5;&#x53E3;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x5B9E;&#x73B0;getRemoteInterface&#x8FD4;&#x56DE;&#x5177;&#x4F53;&#x7684;&#x63A5;&#x53E3;&#x7684;&#x5B9E;&#x73B0;&#x3002;&#x8FD9;&#x79CD;&#x65B9;&#x5F0F;&#x7C7B;&#x4F3C;&#x4E4B;&#x524D;&#x7684;AIDL&#x7684;&#x65B9;&#x5F0F;&#xFF0C;&#x524D;&#x63D0;&#x662F;interface &#x7C7B;&#x9700;&#x8981;&#x5728;&#x4E24;&#x4E2A;bundle&#x5747;&#x53EF;&#x8BBF;&#x95EE;&#x7684;&#x4E3B;apk&#x6216;&#x8005;&#x516C;&#x5171;bundle&#x4E2D;&#x3002;</li>\n</ul>\n<p>&#x8FD9;&#x79CD;&#x4F7F;&#x7528;&#x65B9;&#x5F0F;&#x9002;&#x7528;&#x4E8E;&#x672C;&#x8EAB;&#x5177;&#x6709;&#x7279;&#x5B9A;&#x63A5;&#x53E3;&#x5B9A;&#x4E49;&#x7684;SDK&#x4E2D;&#xFF0C;&#x6BD4;&#x5982;&#x5728;&#x624B;&#x6DD8;&#x91CC;&#x9762;&#x7684;windvane&#x548C;weex&#x3002;</p>\n<p>&#x4EE5;windvane&#x4E3A;&#x4F8B;&#xFF08;sample&#x91CC;&#x9762;windvane&#x7684;&#x63A5;&#x53E3;&#x53EA;&#x505A;&#x8303;&#x4F8B;&#xFF0C;&#x4E0E;&#x771F;&#x5B9E;&#x7684;&#x4F7F;&#x7528;&#x63A5;&#x53E3;&#x53EF;&#x80FD;&#x5B58;&#x5728;&#x5DEE;&#x5F02;&#xFF09;&#xFF1A;&#x5B58;&#x5728;&#x5F88;&#x591A;Bundle&#x9700;&#x8981;&#x63D0;&#x4F9B;JSPlugin&#x7684;&#x573A;&#x666F;&#x3002;&#x539F;&#x751F;&#x7684;Windvane&#x9700;&#x8981;&#x63D0;&#x524D;&#x6CE8;&#x518C;JSPlugin&#xFF0C;&#x8FD9;&#x79CD;&#x65B9;&#x5F0F;&#x5BF9;bundle&#x800C;&#x8A00;&#x5F00;&#x9500;&#x8F83;&#x5927;&#x3002;&#x9700;&#x8981;bundle&#x63D0;&#x524D;&#x542F;&#x52A8;&#x6CE8;&#x518C;&#x4EE5;&#x907F;&#x514D;&#x540E;&#x671F;&#x8FD0;&#x884C;&#x65F6;&#x65E0;&#x6CD5;&#x627E;&#x5230;js&#x51FD;&#x6570;&#x5BF9;&#x5E94;&#x7684;native&#x65B9;&#x6CD5;&#x3002;\n&#x5047;&#x8BBE;&#x5728;Remote&#x673A;&#x5236;&#x4E0B;&#x5219;Windvane&#x9488;&#x5BF9;&#x975E;&#x5185;&#x90E8;&#x7684;common native&#x65B9;&#x6CD5;&#x6709;&#x4E00;&#x4E2A;ExternalJSMethodExecuter&#xFF0C;&#x5F53;&#x9700;&#x8981;&#x6267;&#x884C;&#x975E;&#x5185;&#x90E8;&#x7684;js&#x65B9;&#x6CD5;&#x65F6;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;externalJSMethodExecuter.execute()&#x67E5;&#x627E;&#x5916;&#x90E8;&#x7684;method&#x3002;&#xFF08;&#x8FD9;&#x79CD;&#x4E5F;&#x9002;&#x7528;&#x4E8E;Weex&#x7B49;SDK&#x5728;&#x975E;&#x5E38;&#x89C4;&#x7684;Apk&#x5185;&#x7531;&#x5916;&#x90E8;&#x5B9E;&#x73B0;&#x5B9A;&#x5236;&#x7684;&#x9002;&#x914D;&#x5668;&#xFF09;</p>\n<p>&#x5047;&#x8BBE;bundle A&#x6709;&#x82E5;&#x5E72;&#x4E2A;native&#x65B9;&#x6CD5;&#xFF0C;&#x9700;&#x8981;&#x63D0;&#x4F9B;&#x7ED9;JS&#x4F7F;&#x7528;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x5199;&#x6210;</p>\n<pre><code>public class MyJSPluginManager implements IRemote{\n    @Override\n    public Bundle call(String commandName, Bundle args, IResponse callback) {\n        return null;\n    }\n\n    @Override\n    public &lt;T&gt; T getRemoteInterface(Class&lt;T&gt; interfaceClass,Bundle args) {\n        if(interfaceClass == WVApiPlugin.class){\n            if(args.getString(&quot;js_method&quot;).equals(&quot;funA&quot;)){\n                return new FunAPlugin();\n            }else if(args.getString(&quot;js_method&quot;).equals(funB)){\n                return new FunBPlugin();\n            }else{\n                //unknow error\n            }\n        }\n        return null;\n    }\n}\n</code></pre><p>&#x540C;&#x65F6;&#x5728;Manifest&#x4E2D;&#x589E;&#x52A0;&#x5982;&#x4E0B;&#x914D;&#x7F6E;&#xFF1A;</p>\n<pre><code>&lt;meta-data android:name=&quot;atlas.transaction.intent.action.funA&quot; android:value=&quot;com.taobao.sample.MyJSPluginManager&quot; /&gt;\n&lt;meta-data android:name=&quot;atlas.transaction.intent.action.funB&quot; android:value=&quot;com.taobao.sample.MyJSPluginManager&quot; /&gt;\n</code></pre><p>&#x5BF9;&#x4E8E;JS&#x65B9;&#x6CD5;&#x7684;&#x8C03;&#x7528;&#x65B9;&#xFF0C;&#x5219;&#x901A;&#x8FC7;&#x5982;&#x4E0B;&#x65B9;&#x6CD5;&#x5B9E;&#x73B0;&#xFF1A;</p>\n<pre><code>    public void execute(Activity activity, final String jsMethodName){\n        RemoteFactory.requestRemote(RemoteTransactor.class,activity,new Intent(jsMethodName),new RemoteFactory.OnRemoteStateListener&lt;RemoteTransactor&gt;() {\n            @Override\n            public void onRemotePrepared(RemoteTransactor remote) {\n                Bundle b = new Bundle();\n                b.putString(&quot;js_method&quot;,jsMethodName);\n                WVApiPlugin plugin  = remote.getRemoteInterface(WVApiPlugin.class,b);\n                if(plugin!=null){\n                    //&#x65B9;&#x6CD5;&#x4EC5;&#x4F9B;&#x793A;&#x4F8B;&#xFF0C;&#x4E0E;&#x5B9E;&#x9645;&#x60C5;&#x51B5;&#x53EF;&#x80FD;&#x5B58;&#x5728;&#x5DEE;&#x5F02;\n                    plugin.execute(jsMethodName,...);\n                }\n            }\n            @Override\n            public void onFailed(String errorInfo) {\n\n            }\n        });\n    }\n</code></pre><blockquote>\n<p>&#x8FD9;&#x91CC;requestRemote&#x91CC;&#x9762;&#x76F4;&#x63A5;&#x4F20;&#x5165;RemoteTransactor&#x53EF;&#x80FD;&#x5BF9;&#x5F00;&#x53D1;&#x8005;&#x6765;&#x8BF4;&#x8FD8;&#x6709;&#x70B9;&#x6666;&#x6DA9;&#xFF0C;SDK&#x5F00;&#x53D1;&#x8005;&#x4E5F;&#x53EF;&#x4EE5;&#x5C1D;&#x8BD5;&#x76F4;&#x63A5;&#x5BF9;RemoteTransactor&#x4EE5;&#x53CA;IRemote&#x8FDB;&#x884C;&#x5C01;&#x88C5;&#xFF0C;&#x6BD4;&#x5982;&#x6539;&#x9020;&#x6210;&#x66F4;&#x4E3A;&#x76F4;&#x89C2;&#x7684;BaseJSManager&#x548C;BaseJSPlugin</p>\n</blockquote>\n<p>&#x540C;&#x6837;&#x7684;&#xFF0C;&#x5176;&#x4ED6;&#x7684;SDK&#xFF08;&#x6BD4;&#x5982;weex&#xFF09;&#x4E5F;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x7C7B;&#x4F3C;&#x65B9;&#x6848;&#x5728;&#x591A;classloader&#x7684;APK&#x5185;&#x90E8;&#x5B9E;&#x73B0;&#x81EA;&#x5DF1;&#x5B9A;&#x5236;&#x7684;&#x9002;&#x914D;&#x5668;&#xFF0C;&#x89C4;&#x907F;&#x6240;&#x6709;&#x7684;&#x63A5;&#x53E3;&#x5B9E;&#x73B0;&#x9700;&#x8981;&#x9884;&#x5148;&#x6CE8;&#x518C;&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x540C;&#x65F6;&#x4E5F;&#x5BF9;&#x6574;&#x4F53;&#x5E94;&#x7528;&#x7684;&#x6027;&#x80FD;&#x5E26;&#x6765;&#x5E2E;&#x52A9;&#x3002;</p>\n<h3 id=\"&#x8FDC;&#x7AEF;&#x5982;&#x4F55;&#x4E3B;&#x52A8;&#x8C03;&#x7528;&#x4F7F;&#x7528;&#x65B9;&#x7684;&#x63A5;&#x53E3;\">&#x8FDC;&#x7AEF;&#x5982;&#x4F55;&#x4E3B;&#x52A8;&#x8C03;&#x7528;&#x4F7F;&#x7528;&#x65B9;&#x7684;&#x63A5;&#x53E3;</h3>\n<p>&#x6211;&#x4EEC;&#x4E5F;&#x5B58;&#x5728;&#x88AB;&#x4F7F;&#x7528;&#x65B9;&#x5728;&#x67D0;&#x4E9B;&#x573A;&#x666F;&#x4E0B;&#x9700;&#x8981;&#x4E3B;&#x52A8;&#x8C03;&#x7528;&#x6216;&#x8005;&#x6309;&#x89C4;&#x5F8B;&#x5B9A;&#x671F;callback&#x5BBF;&#x4E3B;&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x4E00;&#x79CD;&#x65B9;&#x5F0F;&#x662F;&#x4F7F;&#x7528;&#x5BBF;&#x4E3B;&#x6389;&#x7528;&#x8FDC;&#x7AEF;&#x65F6;&#x4F20;&#x8FDB;&#x6765;&#x7684;IResponse&#x63A5;&#x53E3;&#x591A;&#x6B21;&#x56DE;&#x8C03;&#xFF0C;&#x4F46;&#x662F;&#x5982;&#x679C;&#x6D89;&#x53CA;&#x5230;&#x590D;&#x6742;&#x7684;&#x60C5;&#x51B5;&#x5C31;&#x9700;&#x8981;&#x7528;&#x5230;&#x4E0B;&#x9762;&#x7684;&#x65B9;&#x6CD5;&#xFF1A;</p>\n<p>&#x5BBF;&#x4E3B;&#x672C;&#x8EAB;&#x5BF9;&#x4E8E;&#x88AB;&#x8C03;&#x7528;&#x65B9;&#x6765;&#x8BF4;&#x4E5F;&#x662F;&#x4E00;&#x4E2A;&#x8FDC;&#x7AEF;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x6240;&#x4EE5;&#x5BBF;&#x4E3B;&#x81EA;&#x5DF1;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;IRemote&#xFF0C;&#x540C;&#x65F6;&#x5C06;&#x81EA;&#x5DF1;&#x6CE8;&#x518C;&#x7ED9;Remote&#x5BF9;&#x8C61;&#xFF0C;RemoteFragment&#x3001;RemoteView&#x3001;RemoteTransactor&#x7684;&#x57FA;&#x7C7B;IRemoteContext&#x5B9E;&#x73B0;&#x4E86;&#x63D0;&#x4F9B;&#x4E86;registerHostTransactor&#x63A5;&#x53E3;&#xFF0C;&#x5728;RemoteFactory&#x56DE;&#x8C03;&#x65F6;&#x5C06;&#x81EA;&#x8EAB;&#x7684;IRemote&#x5B9E;&#x73B0;&#x6CE8;&#x518C;&#x8FDB;&#x53BB;</p>\n<pre><code>    void registerHostTransactor(IRemote transactor);\n</code></pre><p>&#x90A3;&#x4E48;&#x5728;&#x8FDC;&#x7AEF;&#x9700;&#x8981;&#x4F7F;&#x7528;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;HostTransactor&#xFF08;&#x524D;&#x9762;&#x56FE;&#x4E2D;&#x672A;&#x6807;&#x51FA;&#xFF09;&#x5F97;&#x5230;&#x5BBF;&#x4E3B;&#x7684;IRemote&#x7684;&#x5B9E;&#x73B0;&#x5E76;&#x4F20;&#x9012;&#x76F8;&#x5E94;&#x7684;&#x4FE1;&#x606F;&#x3002;</p>\n<pre><code>    public static HostTransactor get(IRemote remoteItem)\n</code></pre><h3 id=\"remote&#x673A;&#x5236;&#x7684;&#x7279;&#x70B9;&#x548C;&#x4E0D;&#x8DB3;\">Remote&#x673A;&#x5236;&#x7684;&#x7279;&#x70B9;&#x548C;&#x4E0D;&#x8DB3;</h3>\n<p>Remote&#x673A;&#x5236;&#x672C;&#x8EAB;&#x5F3A;&#x70C8;&#x4F9D;&#x6258;&#x4E8E;&#x7EC4;&#x4EF6;&#x5316;&#x62C6;&#x5206;&#x7684;&#x65B9;&#x6848;&#x3002;&#x5B83;&#x7684;&#x89E3;&#x8026;&#x5C42;&#x5EA6;&#x4ECB;&#x4E8E;AIDL&#x548C;&#x76F4;&#x63A5;&#x4F9D;&#x8D56;&#x4E4B;&#x95F4;&#x3002;&#x76F8;&#x6BD4;AIDL&#x7075;&#x6D3B;&#x5C42;&#x5EA6;&#x66F4;&#x9AD8;&#x3002;&#x4E0D;&#x8FC7;&#x4EE3;&#x7406;&#x7684;&#x65B9;&#x5F0F;&#x5E76;&#x4E0D;&#x80FD;&#x5B8C;&#x5168;&#x675C;&#x7EDD;&#x901A;&#x8FC7;&#x975E;&#x5E38;&#x89C4;&#x65B9;&#x6CD5;&#x6765;&#x83B7;&#x53D6;&#x8FDC;&#x7AEF;&#x76EE;&#x6807;&#x5BF9;&#x8C61;&#x6765;&#x8FDB;&#x884C;&#x4F7F;&#x7528;&#xFF0C;&#x53E6;&#x5916;&#x4E5F;&#x53EF;&#x80FD;&#x5B58;&#x5728;&#x67D0;&#x4E9B;&#x8FB9;&#x7F18;&#x65B9;&#x6CD5;&#x65E0;&#x975E;&#x88AB;&#x5B8C;&#x5168;&#x4EE3;&#x7406;&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x8FD9;&#x4E5F;&#x9700;&#x8981;&#x5728;&#x4EE5;&#x540E;&#x7684;&#x8FED;&#x4EE3;&#x4E2D;&#x8FDB;&#x884C;&#x4F18;&#x5316;&#xFF0C;&#x5BF9;&#x4E8E;&#x975E;Atlas&#x5BB9;&#x5668;&#x5316;&#x4F46;&#x662F;&#x4F7F;&#x7528;&#x4E86;&#x7EC4;&#x4EF6;&#x5316;&#x62C6;&#x89E3;&#x65B9;&#x6848;&#x7684;App&#xFF0C;&#x8FD9;&#x79CD;&#x601D;&#x8DEF;&#x4E5F;&#x662F;&#x540C;&#x6837;&#x9002;&#x7528;&#x7684;&#x3002;</p>\n<h2 id=\"&#x73B0;&#x5728;&#x8FD8;&#x53EF;&#x4EE5;&#x9009;&#x62E9;&#x7684;bundle&#x95F4;&#x4EE3;&#x7801;&#x590D;&#x7528;&#x7684;&#x65B9;&#x6848;\">&#x73B0;&#x5728;&#x8FD8;&#x53EF;&#x4EE5;&#x9009;&#x62E9;&#x7684;bundle&#x95F4;&#x4EE3;&#x7801;&#x590D;&#x7528;&#x7684;&#x65B9;&#x6848;</h2>\n<p>&#x5BF9;&#x4E8E;AIDL&#x3001;serviceHub&#x4EE5;&#x53CA;Remote&#x7684;&#x673A;&#x5236;&#xFF0C;&#x53EF;&#x80FD;&#x8FD8;&#x5B58;&#x5728;&#x4E34;&#x65F6;&#x65E0;&#x6CD5;&#x6309;&#x7167;&#x89C4;&#x8303;&#x8FDB;&#x884C;&#x89E3;&#x8026;&#x7684;&#x60C5;&#x51B5;&#x3002;&#x76EE;&#x524D;&#x9664;&#x4E86;&#x9759;&#x6001;&#x4F9D;&#x8D56;&#x5916;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x8003;&#x8651;&#x4F7F;&#x7528;&#x52A8;&#x6001;&#x4F9D;&#x8D56;&#x7684;&#x65B9;&#x5F0F;,&#x7528;&#x6765;&#x89E3;&#x51B3;&#x5728;&#x5177;&#x4F53;&#x4F7F;&#x7528;&#x5230;&#x67D0;&#x4E2A;&#x529F;&#x80FD;&#x65F6;&#x5019;&#x518D;&#x53BB;&#x6302;&#x8F7D;&#x76F8;&#x5E94;&#x7684;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#xFF0C;&#x4E0D;&#x8FC7;<strong>bundle&#x4F9D;&#x8D56;&#x59CB;&#x7EC8;&#x6253;&#x7834;&#x4E86;bundle&#x4E4B;&#x95F4;&#x7684;&#x8FB9;&#x754C;&#xFF0C;&#x9700;&#x8981;&#x8C28;&#x614E;&#x4F7F;&#x7528;</strong></p>\n<pre><code>    /**\n     * &#x8BBE;&#x7F6E;bundle&#x8FD0;&#x884C;&#x65F6;&#x4F9D;&#x8D56;\n     * @param source  &#x9700;&#x8981;&#x6DFB;&#x52A0;&#x4F9D;&#x8D56;&#x7684;bundle\n     * @param dependencyBundle &#x88AB;&#x4F9D;&#x8D56;&#x7684;bundle&#x7684;packagename\n     * @param resourceDependencyNeed &#x662F;&#x5426;&#x9700;&#x8981;&#x4F7F;&#x7528;&#x88AB;&#x4F9D;&#x8D56;bundle&#x7684;&#x8D44;&#x6E90;\n     * @throws BundleException\n     */\n    public void requestRuntimeDependency(ClassLoader source,String dependencyBundle,boolean resourceDependencyNeed) throws BundleException{\n</code></pre><h2 id=\"&#x5176;&#x4ED6;&#xFF1A;&#x7531;&#x4E8E;native-so&#x7684;&#x76F8;&#x4E92;&#x8C03;&#x7528;&#x5BFC;&#x81F4;&#x7684;bundle&#x4F9D;&#x8D56;\">&#x5176;&#x4ED6;&#xFF1A;&#x7531;&#x4E8E;native so&#x7684;&#x76F8;&#x4E92;&#x8C03;&#x7528;&#x5BFC;&#x81F4;&#x7684;bundle&#x4F9D;&#x8D56;</h2>\n<p>Native Library &#x5728;&#x591A;classloader&#x8FD0;&#x884C;&#x673A;&#x5236;&#x4E0B;&#xFF0C;&#x9700;&#x8981;&#x4E8B;&#x5148;&#x4E86;&#x89E3;&#x51E0;&#x4E2A;&#x8981;&#x70B9;&#xFF1A;</p>\n<ol>\n<li>&#x5B9A;&#x4E49;&#x540C;&#x4E00;&#x4E2A;So&#x7684;&#x4F9D;&#x636E;&#x662F;&#x5168;&#x8DEF;&#x5F84;&#x5B8C;&#x5168;&#x76F8;&#x540C;&#x4E14;so&#x5185;&#x5BB9;&#x76F8;&#x540C;</li>\n<li><p>&#x8C03;&#x7528;LoadLibrary(&#x6216;&#x8005;load)&#x5728;native&#x771F;&#x6B63;dlopen library&#x4E4B;&#x524D;java&#x5C42;&#x4F1A;&#x5148;findLibrary&#xFF0C;&#x5982;&#x679C;&#x662F;&#x7CFB;&#x7EDF;&#x5E93;&#xFF0C;&#x5219;&#x5728;&#x7CFB;&#x7EDF;&#x73AF;&#x5883;&#x53D8;&#x91CF;&#x91CC;&#x9762;&#x5305;&#x542B;&#x7684;&#x8DEF;&#x5F84;&#x5185;&#xFF0C;&#x5982;&#x679C;&#x662F;&#x5916;&#x90E8;&#x5F15;&#x5165;&#x7684;&#xFF0C;&#x5219;&#x901A;&#x8FC7;ClassLoader.findLibrary&#x8FDB;&#x884C;&#x67E5;&#x627E;&#xFF0C;BundleClassLoader&#x7684;&#x67E5;&#x627E;&#x903B;&#x8F91;&#x662F;&#x5148;&#x627E;&#x81EA;&#x8EAB;bundle&#x5B89;&#x88C5;&#x76EE;&#x5F55;&#x4E0B;&#x7684;&#xFF0C;&#x627E;&#x4E0D;&#x5230;&#x63A5;&#x7740;&#x627E;&#x4F9D;&#x8D56;bundle&#x5185;&#x7684;&#xFF0C;&#x6700;&#x540E;&#x53BB;&#x627E;&#x4E3B;dex&#x4E5F;&#x5C31;&#x662F;PatchClassLoader&#x7684;findLibrary&#x53BB;&#x67E5;&#x627E;&#x3002;</p>\n<p> &#x5982;&#x679C;&#x662F;&#x76F4;&#x63A5;&#x4F7F;&#x7528;dlopen bundle&#x5185;&#x7684;so&#xFF0C;&#x5219;&#x9700;&#x8981;&#x4F20;&#x5165;so&#x7684;&#x5168;&#x8DEF;&#x5F84;&#xFF08;&#x6BD4;&#x5982;&#x8BF4;&#x901A;&#x8FC7;java&#x5C42;&#x83B7;&#x53D6;&#xFF09;&#xFF0C;&#x5426;&#x5219;&#x53EF;&#x80FD;&#x51FA;&#x73B0;so &#x627E;&#x4E0D;&#x5230;&#x3002;</p>\n</li>\n<li><p>native so load&#x65F6;&#x4E0E;load&#x8BE5;so&#x7684;&#x7C7B;&#x6240;&#x5728;&#x7684;classloader&#x5B58;&#x5728;&#x7ED1;&#x5B9A;&#x5173;&#x7CFB;&#xFF0C;&#x5982;&#x679C;&#x5B58;&#x5728;native&#x53CD;&#x8C03;java&#x5C42;&#x4EE3;&#x7801;&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x5219;&#x53EA;&#x80FD;&#x8C03;&#x7528;&#x5230;&#x591F;&#x627E;&#x5230;&#x8BE5;classloader&#x53EF;&#x4EE5;&#x627E;&#x5230;&#x7684;java&#x7C7B;&#x7684;&#x65B9;&#x6CD5;</p>\n</li>\n<li>&#x5728;android 7.0&#x7248;&#x672C;&#x4E4B;&#x524D;native so load&#x540C;&#x4E00;&#x4E2A;&#x8FDB;&#x7A0B;&#x7A7A;&#x95F4;&#x4E0B;&#x53EA;&#x53EF;load&#x4E00;&#x6B21;&#xFF0C;&#x5982;&#x679C;&#x540C;&#x4E00;&#x4E2A;classloder&#x7B2C;&#x4E8C;&#x6B21;&#x53BB;load&#x5219;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;&#x6210;&#x529F;&#xFF0C;&#x5982;&#x679C;&#x4E0D;&#x540C;&#x7684;classloader&#x53BB;load&#x5219;&#x4F1A;&#x5931;&#x8D25;&#xFF1B;android 7.0&#x4EE5;&#x540E;ClassLoader&#x901A;&#x8FC7;namespace&#x5404;&#x81EA;&#x72EC;&#x7ACB;&#xFF0C;&#x4E0D;&#x540C;&#x7684;ClassLoader&#x53EF;&#x4EE5;&#x53BB;load&#x540C;&#x4E00;&#x4E2A;so&#xFF0C;&#x5206;&#x522B;&#x4F1A;&#x5728;&#x5404;&#x81EA;&#x7684;namespace&#x6709;&#x5404;&#x81EA;&#x7684;mmap&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;/proc/pid/maps &#x67E5;&#x770B;&#x5404;&#x81EA;&#x7684;map&#x4FE1;&#x606F;</li>\n</ol>\n<h3 id=\"native&#x7279;&#x6B8A;&#x4F7F;&#x7528;&#x60C5;&#x51B5;&#x53CA;&#x5EFA;&#x8BAE;\">native&#x7279;&#x6B8A;&#x4F7F;&#x7528;&#x60C5;&#x51B5;&#x53CA;&#x5EFA;&#x8BAE;</h3>\n<ol>\n<li><p>&#x7531;&#x4E8E;&#x4E0D;&#x540C;bundle&#x7684;java&#x4EE3;&#x7801;&#x4F7F;&#x7528;&#x76F8;&#x540C;&#x7684;So&#x5BFC;&#x81F4;&#x7684;&#x4F9D;&#x8D56;&#xFF1A;</p>\n<p> &#x5EFA;&#x8BAE;&#x628A;&#x8C03;&#x7528;&#x76F8;&#x5173;&#x7684;&#x8C03;&#x7528;So&#x7684;&#x4EE3;&#x7801;&#x548C;So&#x672C;&#x8EAB;&#x5355;&#x72EC;&#x5C01;&#x88C5;&#x6210;&#x4E00;&#x4E2A;&#x516C;&#x5171;&#x7684;&#x6A21;&#x5757;&#xFF0C;&#x5426;&#x5219;&#x5982;&#x679C;&#x5B58;&#x5728;So&#x53CD;&#x8C03;java&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x5219;&#x53EA;&#x80FD;&#x8C03;&#x7528;&#x5230;loadLibrary&#x7684;ClassLoader&#x8303;&#x56F4;&#x5185;&#x7684;java&#x7C7B;&#x7684;&#x4EE3;&#x7801;</p>\n</li>\n<li><p>&#x7531;&#x4E8E;native so&#x4F9D;&#x8D56;&#x6216;&#x8005;dlopen&#x516C;&#x5171;native So&#x7684;&#x60C5;&#x51B5;&#xFF1A;\n &#x4F7F;&#x7528;&#x65B9;&#x6848;&#xFF1A;</p>\n<ol>\n<li>&#x516C;&#x5171;so&#x4E0B;&#x5C42;&#x5230;&#x516C;&#x5171;&#x6A21;&#x5757;&#xFF0C;&#x540C;&#x65F6;&#x63D0;&#x524D;load&#xFF08;&#x89C4;&#x907F;7.0&#x7248;&#x672C;&#x5F00;&#x59CB;&#x533A;&#x5206;namespace&#x9694;&#x79BB;&#x7684;&#x60C5;&#x51B5;&#xFF09;&#xFF0C;bundle&#x7684;so&#x4F7F;&#x7528;&#x7684;&#x65F6;&#x5019;&#x4E0D;&#x80FD;&#x4F7F;&#x7528;&#x5B98;&#x65B9;&#x7684;dlopen&#x63A5;&#x53E3;&#xFF0C;&#x9700;&#x8981;&#x6839;&#x636E;mapping&#x67E5;&#x627E;&#x5DF2;load so&#x7684;&#x5BFC;&#x51FA;&#x51FD;&#x6570;&#x8FDB;&#x884C;&#x4F7F;&#x7528;,&#x89C4;&#x907F;&#x56E0;&#x4E3A;namespace&#x4E0D;&#x4E00;&#x81F4;&#x5BFC;&#x81F4;&#x591A;&#x4EFD;mmap&#x7684;&#x60C5;&#x51B5;&#x3002;&#x5177;&#x4F53;&#x53C2;&#x8003;&#xFF1A;<a href=\"http://gitlab.alibaba-inc.com/zeduo.szd/savedlopen/tree/master\" target=\"_blank\">http://gitlab.alibaba-inc.com/zeduo.szd/savedlopen/tree/master</a> </li>\n</ol>\n</li>\n</ol>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"guide_for_compile.html\" class=\"navigation navigation-prev \" aria-label=\"Previous page: awo编译\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"../update/\" class=\"navigation navigation-next \" aria-label=\"Next page: 动态部署\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"跨bundle的代码重用和通信\",\"level\":\"1.3.4\",\"depth\":2,\"next\":{\"title\":\"动态部署\",\"level\":\"1.4\",\"depth\":1,\"path\":\"update/README.md\",\"ref\":\"update/README.md\",\"articles\":[{\"title\":\"技术原理\",\"level\":\"1.4.1\",\"depth\":2,\"path\":\"update/principle.md\",\"ref\":\"update/principle.md\",\"articles\":[]},{\"title\":\"dexpatch\",\"level\":\"1.4.2\",\"depth\":2,\"path\":\"update/dexpatch.md\",\"ref\":\"update/dexpatch.md\",\"articles\":[]},{\"title\":\"dexpatch使用教程\",\"level\":\"1.4.3\",\"depth\":2,\"path\":\"update/dexpatch_use_guide.md\",\"ref\":\"update/dexpatch_use_guide.md\",\"articles\":[]},{\"title\":\"一些限制\",\"level\":\"1.4.4\",\"depth\":2,\"path\":\"update/guide.md\",\"ref\":\"update/guide.md\",\"articles\":[]}]},\"previous\":{\"title\":\"awo编译\",\"level\":\"1.3.3\",\"depth\":2,\"path\":\"guide-for-use/guide_for_compile.md\",\"ref\":\"guide-for-use/guide_for_compile.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"guide-for-use/bundleCommunicate.md\",\"mtime\":\"2017-11-24T12:08:57.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/guide-for-use/guide_for_build.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>容器接入 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"guide_for_bundle.html\" />\n    \n    \n    <link rel=\"prev\" href=\"./\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"./\">\n            \n                <a href=\"./\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter active\" data-level=\"1.3.1\" data-path=\"guide_for_build.html\">\n            \n                <a href=\"guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"guide_for_bundle.html\">\n            \n                <a href=\"guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"guide_for_compile.html\">\n            \n                <a href=\"guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"bundleCommunicate.html\">\n            \n                <a href=\"bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../update/\">\n            \n                <a href=\"../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../update/principle.html\">\n            \n                <a href=\"../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../update/dexpatch.html\">\n            \n                <a href=\"../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../update/guide.html\">\n            \n                <a href=\"../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../faq/question.html\">\n            \n                <a href=\"../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../faq/help.html\">\n            \n                <a href=\"../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../faq/variant.html\">\n            \n                <a href=\"../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >容器接入</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <pre><code># &#x4E3B;&#x5DE5;&#x7A0B;&#x5BB9;&#x5668;&#x63A5;&#x5165;\n</code></pre><p>Atlas&#x5F00;&#x6E90;&#x7684;&#x4EE3;&#x7801;&#x5185;&#x5BB9;&#x4E3B;&#x8981;&#x5305;&#x62EC;&#x4EE5;&#x4E0B;&#x51E0;&#x4E2A;&#x6A21;&#x5757;&#xFF1A;</p>\n<ol>\n<li>&#x57FA;&#x4E8E;gradle&#x7684;&#x6784;&#x5EFA;&#x63D2;&#x4EF6;&#xFF08;&#x5305;&#x62EC;&#x4FEE;&#x6539;&#x8FC7;&#x7684;aapt&#x5185;&#x5BB9;&#xFF09;&#xFF1B;</li>\n<li>android&#x7AEF;&#x6D4B;&#x5BB9;&#x5668;&#x8FD0;&#x884C;&#x5E93;atlas_core&#xFF1B;</li>\n<li>&#x57FA;&#x4E8E;&#x5BB9;&#x5668;&#x63D0;&#x4F9B;&#x66F4;&#x65B0;&#x80FD;&#x529B;&#x7684;&#x5E93;atlas_update;</li>\n</ol>\n<p>&#x6211;&#x4EEC;&#x6BD4;&#x8F83;&#x503E;&#x5411;&#x4E8E;&#x7528;&#x4E00;&#x4E2A;&#x6BD4;&#x8F83;&#x5E72;&#x51C0;&#x7684;&#x58F3;&#x5B50;&#x5DE5;&#x7A0B;&#x6765;&#x4F5C;&#x4E3A;&#x5BB9;&#x5668;&#x67B6;&#x6784;&#x4E0B;&#x7684;&#x6253;&#x5305;&#x5DE5;&#x7A0B;&#xFF0C;&#x8FD9;&#x4E2A;&#x5DE5;&#x7A0B;&#x5EFA;&#x8BAE;&#x53EA;&#x5B58;&#x5728;AndroidManifest.xml&#x548C;&#x6784;&#x5EFA;&#x7684;&#x6587;&#x4EF6;&#x53CA;&#x90E8;&#x5206;&#x8D44;&#x6E90;&#x5185;&#x5BB9;&#xFF0C;manifest&#x6587;&#x4EF6;&#x7528;&#x4E8E;&#x5355;&#x72EC;&#x7BA1;&#x7406;apk&#x7684;icon&#xFF0C;&#x7248;&#x672C;&#x53F7;&#xFF0C;versioncode&#x7B49;&#xFF1B;&#x6784;&#x5EFA;&#x6587;&#x4EF6;&#x7BA1;&#x7406;&#x7248;&#x672C;&#x4F9D;&#x8D56;&#xFF1B;&#x8FD9;&#x91CC;&#x6211;&#x4EEC;&#x53D6;&#x540D;&#x6253;&#x5305;&#x5DE5;&#x7A0B;&#x7B49;&#x540D;&#x5B57;&#x4E3A;apk_builder;\n&#x901A;&#x5E38;&#x60C5;&#x51B5;&#x4E0B;Apk_builder&#x9664;&#x4E86;&#x4E3B;Apk&#x7684;AndroidManifest.xml&#x4E4B;&#x5916;&#xFF0C;&#x63A5;&#x5165;Atlas&#x540E;&#xFF0C;Main_builder&#x5C06;&#x4F1A;&#x5305;&#x542B;&#x4EE5;&#x4E0B;&#x5185;&#x5BB9;&#xFF1A;</p>\n<ol>\n<li><strong>build.gradle</strong> : &#x7528;&#x4E8E;&#x914D;&#x7F6E;&#x4E3B;apk&#x7684;&#x4F9D;&#x8D56;&#x53CA;&#x63A7;&#x5236;&#x6784;&#x5EFA;&#x53C2;&#x6570;</li>\n<li><strong>packageIdFile.properties</strong>: &#x914D;&#x7F6E;bundle&#x7684;packageId,&#x4EE5;&#x4FDD;&#x8BC1;&#x8D44;&#x6E90;&#x6BB5;&#x72EC;&#x7ACB;&#xFF08;&#x4E5F;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;mtl.tBuildConfig.autoPackageId&#x8BBE;&#x7F6E;&#x81EA;&#x52A8;&#x5206;&#x914D;packageID&#xFF09;</li>\n<li><strong>bundleBaseInfoFile.json</strong>: &#x914D;&#x7F6E;bundle&#x7684;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;</li>\n</ol>\n<p>&#x4E0B;&#x9762;&#x4F1A;&#x9010;&#x4E2A;&#x8BF4;&#x660E;&#x6BCF;&#x4E2A;&#x6587;&#x4EF6;&#x7684;&#x4F7F;&#x7528;&#x548C;&#x6CE8;&#x610F;&#x8981;&#x70B9;</p>\n<h2 id=\"buildgradleatlasgradleplugin\">build.gradle(AtlasGradlePlugin)</h2>\n<p>&#x652F;&#x6301; atlas &#x5DE5;&#x7A0B;&#x6253;&#x5305;&#x7684;gradle &#x63D2;&#x4EF6;&#xFF0C; &#x57FA;&#x4E8E; google &#x5B98;&#x65B9;&#x7684; android builder &#xFF08;2.0.0~2.1.0&#xFF09;</p>\n<ol>\n<li><p>&#x5F15;&#x7528;&#x63D2;&#x4EF6;&#x53CA;&#x4F9D;&#x8D56;&#x4ED3;&#x5E93;</p>\n<pre><code> buildscript {\n     repositories {\n         mavenLocal()\n         jcenter()\n     }\n     dependencies {\n         classpath &quot;com.taobao.android:atlasplugin:1.0.1&quot;\n     }\n }\n repositories {\n     jcenter()\n }\n</code></pre><p> &#x6CE8;&#x610F;&#x5C3D;&#x91CF;&#x4E0D;&#x8981;&#x6307;&#x5B9A; classpath &quot;com.android.tools.build:gradle&quot;&#x7684;&#x7248;&#x672C;&#xFF0C;&#x9ED8;&#x8BA4;&#x4F7F;&#x7528;&#x7684;&#x662F; 2.1</p>\n</li>\n<li><p>&#x5E94;&#x7528;plugin</p>\n<pre><code> apply plugin: &apos;com.taobao.atlas.application&apos;\n //&#x6CE8;&#x610F;&#x4E0D;&#x80FD;&#x540C;&#x65F6; apply com.android.application\n</code></pre></li>\n<li><p>&#x6DFB;&#x52A0;&#x8FD0;&#x884C;&#x5E93;&#x4F9D;&#x8D56;    </p>\n<pre><code> dependencies {\n    compile(&apos;com.taobao.android:atlas_core:5.0.0@aar&apos;) {\n     transitive = true\n }\n compile &apos;com.taobao.android:atlasupdate:1.0.8@aar&apos;\n</code></pre><p> <strong>&#x5982;&#x679C;&#x4E0D;&#x9700;&#x8981;&#x7528;&#x5230;atlas&#x7684;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x529F;&#x80FD;&#xFF0C;&#x4E0D;&#x9700;&#x8981;&#x4F9D;&#x8D56;atlasupdate</strong>    </p>\n</li>\n<li><p>&#x5F00;&#x542F;atlas&#x5BB9;&#x5668;&#x529F;&#x80FD;</p>\n<pre><code>  atlas {\n      atlasEnabled true\n    tBuildConfig {\n         autoStartBundles =[&apos;com.taobao.firstbundle&apos;] //&#x81EA;&#x542F;&#x52A8;bundle&#x914D;&#x7F6E;\n     }\n\n      patchConfigs{\n         debug {\n         createTPatch true\n         }\n         }\n         buildTypes {\n         debug {\n             if (apVersion){\n                     baseApDependency  &quot;com.taobao.android.atlasdemo:AP-debug:${apVersion}@ap&quot;\n                 patchConfig    patchConfigs.debug\n                 }\n             }\n          }\n     }   \n</code></pre><p> <strong>atlasEnable&#x5B57;&#x6BB5;&#x9700;&#x8981;&#x6307;&#x5B9A;&#x4E3A;true&#x624D;&#x80FD;&#x5F00;&#x542F;&#x6253;&#x5305;&#x9636;&#x6BB5;&#x7684;&#x57FA;&#x4E8E;&#x5BB9;&#x5668;&#x6269;&#x5C55;&#x7684;task</strong>    </p>\n<p><strong>&#x540E;&#x7EED;&#x4E24;&#x4E2A;&#x8BBE;&#x7F6E;&#x7528;&#x8BED;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x6253;&#x5305;&#x65F6;&#x7684;&#x5F00;&#x5173;&#x8BBE;&#x7F6E;&#xFF0C;&#x5176;&#x4F59;&#x5B57;&#x6BB5;&#x53C2;&#x8003;&#x914D;&#x7F6E;&#x5217;&#x8868;&#x4E2D;&#x7684;&#x4F7F;&#x7528;&#x65B9;&#x5F0F;</strong></p>\n</li>\n</ol>\n<ol>\n<li><p>&#x6784;&#x5EFA;</p>\n<ol>\n<li><p>APK&#x6784;&#x5EFA; <strong>./gradlew assembleDebug &#x6216;&#x8005; assembleRelease</strong></p>\n<p> &#x6784;&#x5EFA;&#x4EA7;&#x7269;&#xFF1A;</p>\n<ol>\n<li>build/outputs/apk/xx.apk , &#x6784;&#x5EFA;&#x7684;&#x4EA7;&#x7269;apk   </li>\n<li>build/outputs/apk/xx.ap , &#x6784;&#x5EFA;&#x7684;&#x57FA;&#x7EBF;&#x5305;&#xFF0C; &#x91CC;&#x9762;&#x5305;&#x542B; apk &#x548C;&#x5176;&#x4ED6;&#x7684;&#x6253;&#x5305;&#x4E2D;&#x95F4;&#x914D;&#x7F6E;</li>\n<li>build/outputs/dependencyTree-debug.json , &#x6574;&#x4E2A;&#x5DE5;&#x7A0B;&#x7684;&#x4F9D;&#x8D56;&#x6811;</li>\n<li>build/outputs/atlasConfig.json , &#x6574;&#x4E2A;&#x6253;&#x5305;&#x7684; atlas &#x914D;&#x7F6E;&#x53C2;&#x6570;</li>\n</ol>\n</li>\n<li><p>TPatch&#x6784;&#x5EFA; <strong>./gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.1</strong></p>\n<p> apVersion&#x8868;&#x793A;&#x88AB;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x5E94;&#x7528;&#x7684;&#x57FA;&#x7EBF;&#x7248;&#x672C;&#xFF0C;versionName&#x8868;&#x793A;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x540E;&#x65B0;&#x7684;versionName</p>\n<p> &#x6784;&#x5EFA;&#x4EA7;&#x7269;&#xFF1A;\n &#x9664;&#x4E86;&#x4F9D;&#x8D56;&#x6811;&#x548C;&#x914D;&#x7F6E;&#x53C2;&#x6570;&#x4E4B;&#x5916;&#xFF0C;&#x989D;&#x5916;&#x7684;&#x4EA7;&#x7269;&#x6709;&#xFF1A;</p>\n<ol>\n<li>build/outputs/tpatch-debug , debug &#x5305; patch&#x4EA7;&#x7269;</li>\n<li>build/outputs/tpatch-release , release &#x5305; patch&#x4EA7;&#x7269;</li>\n</ol>\n</li>\n</ol>\n</li>\n</ol>\n<h3 id=\"&#x914D;&#x7F6E;\">&#x914D;&#x7F6E;</h3>\n<h4 id=\"&#x914D;&#x7F6E;&#x5217;&#x8868;\">&#x914D;&#x7F6E;&#x5217;&#x8868;</h4>\n<table>\n<thead>\n<tr>\n<th>&#x529F;&#x80FD;</th>\n<th>&#x914D;&#x7F6E;&#x540D;&#x79F0;</th>\n<th>&#x7C7B;&#x578B;</th>\n<th>&#x503C;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>&#x662F;&#x5426;&#x542F;&#x7528;atlas</td>\n<td>mtl.atlasEnabled</td>\n<td>boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td>&#x81EA;&#x52A8;&#x751F;&#x6210;bundle&#x7684;packageId</td>\n<td>mtl.tBuildConfig.autoPackageId</td>\n<td>boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td>&#x9884;&#x5904;&#x7406;manifest&#xFF0C; &#x5982;&#x679C;&#x5F00;&#x542F;atlas&#xFF0C;&#x5FC5;&#x987B;&#x4E3A;true</td>\n<td>mtl.tBuildConfig.preProcessManifest</td>\n<td>Boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td>&#x4F7F;&#x7528;&#x81EA;&#x5B9A;&#x4E49;&#x7684;aapt&#xFF0C; &#x5982;&#x679C;&#x5F00;&#x542F;atlas&#xFF0C;&#x5FC5;&#x987B;&#x4E3A;true</td>\n<td>mtl.tBuildConfig.useCustomAapt</td>\n<td>Boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td>aapt&#x8F93;&#x51FA;&#x7684;R&#x4E3A;&#x5E38;&#x91CF;, &#x5EFA;&#x8BAE;&#x503C;&#x8BBE;&#x7F6E;&#x4E3A;false&#xFF0C; &#x53EF;&#x4EE5;&#x51CF;&#x5C11;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;patch&#x5305;&#x5927;&#x5C0F;</td>\n<td>mtl.tBuildConfig.aaptConstantId</td>\n<td>Boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td>&#x5408;&#x5E76;jar&#x4E2D;&#x7684;&#x8D44;&#x6E90;&#x6587;&#x4EF6;</td>\n<td>mtl.tBuildConfig.mergeJavaRes</td>\n<td>Boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td>&#x6784;&#x5EFA;&#x57FA;&#x7EBF;&#x5305;&#xFF0C;&#x5EFA;&#x8BAE;&#x5F00;&#x542F;&#xFF0C;&#x5426;&#x5219;&#x540E;&#x9762;&#x7684;patch&#x5305;&#x65E0;&#x6CD5;&#x8FDB;&#x884C;</td>\n<td>mtl.tBuildConfig.createAP</td>\n<td>Boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td>&#x5408;&#x5E76;bundle jar&#x4E2D;&#x7684;&#x8D44;&#x6E90;&#x6587;&#x4EF6;</td>\n<td>mtl.tBuildConfig.mergeAwbJavaRes</td>\n<td>Boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td>&#x81EA;&#x542F;&#x52A8;&#x7684;bundle&#x5217;&#x8868;&#xFF0C; &#x503C;&#x662F; packageName</td>\n<td>mtl.tBuildConfig.autoStartBundles</td>\n<td>List</td>\n<td>[com.taobao.firstbundle]</td>\n</tr>\n<tr>\n<td>&#x63D0;&#x524D;&#x6267;&#x884C;&#x7684;&#x65B9;&#x6CD5;&#xFF0C;&#x683C;&#x5F0F;&#x662F; className:methodName</td>\n<td>className2:methodName2 &#xFF0C; &#x6CE8;&#x610F;class&#x548C;methodname&#x90FD;&#x4E0D;&#x80FD;&#x6DF7;&#x6DC6;&#xFF0C;&#x4E14;&#x65B9;&#x6CD5;&#x5B9E;&#x73B0;&#x662F; class.method(Context)</td>\n<td>mtl.tBuildConfig.preLaunch</td>\n<td>String</td>\n<td></td>\n</tr>\n<tr>\n<td> &#x57FA;&#x7EBF;&#x7684;&#x4F9D;&#x8D56;&#x5750;&#x6807;&#xFF0C; &#x5982;&#xFF1A; com.taobao.android:taobao-android-release:6.3.0-SNAPSHOT@ap</td>\n<td>mtl.buildTypes.debug.baseApDependency</td>\n<td>String</td>\n<td>null</td>\n</tr>\n<tr>\n<td> &#x57FA;&#x7EBF;&#x7684;&#x4F9D;&#x8D56;&#x5750;&#x6807;&#xFF0C; &#x5982;&#xFF1A; com.taobao.android:taobao-android-release:6.3.0-SNAPSHOT@ap</td>\n<td>mtl.buildTypes.release.baseApDependency</td>\n<td>String</td>\n<td>null</td>\n</tr>\n<tr>\n<td>&#x4F7F;&#x7528;atlas&#x7684;application&#xFF0C;&#x5305;&#x542B; atlas&#x57FA;&#x7840;&#x521D;&#x59CB;&#x5316;&#x53CA;multidex&#x903B;&#x8F91;</td>\n<td>mtl.manifestOptions.replaceApplication</td>\n<td>boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td> &#x6253;andfix patch &#x5305;</td>\n<td>mtl.patchConfigs.debug.createAPatch</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td> &#x6253;&#x52A8;&#x6001;&#x90E8;&#x7F72; patch &#x5305;</td>\n<td>mtl.patchConfigs.debug.createTPatch</td>\n<td>boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td> andfix &#x6253;&#x5305;&#x8FC7;&#x6EE4; class &#x5217;&#x8868;&#x6587;&#x4EF6;</td>\n<td>mtl.patchConfigs.debug.filterFile</td>\n<td>File</td>\n<td>null</td>\n</tr>\n<tr>\n<td> andfix &#x6253;&#x5305;&#x8FC7;&#x6EE4; class &#x5217;&#x8868;&#x6587;&#x4EF6;</td>\n<td>mtl.patchConfigs.debug.filterClasses</td>\n<td>Set</td>\n<td>[]</td>\n</tr>\n<tr>\n<td> &#x6253;andfix patch &#x5305;</td>\n<td>mtl.patchConfigs.release.createAPatch</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td> &#x6253;&#x52A8;&#x6001;&#x90E8;&#x7F72; patch &#x5305;</td>\n<td>mtl.patchConfigs.release.createTPatch</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td> andfix &#x6253;&#x5305;&#x8FC7;&#x6EE4; class &#x5217;&#x8868;&#x6587;&#x4EF6;</td>\n<td>mtl.patchConfigs.release.filterFile</td>\n<td>File</td>\n<td>null</td>\n</tr>\n<tr>\n<td> andfix &#x6253;&#x5305;&#x8FC7;&#x6EE4; class &#x5217;&#x8868;&#x6587;&#x4EF6;</td>\n<td>mtl.patchConfigs.release.filterClasses</td>\n<td>Set</td>\n<td>[]</td>\n</tr>\n</tbody>\n</table>\n<h4 id=\"&#x6700;&#x7B80;&#x914D;&#x7F6E;\">&#x6700;&#x7B80;&#x914D;&#x7F6E;</h4>\n<pre><code>atlas {\n    atlasEnabled true\n}\n</code></pre><p>&#x5177;&#x4F53;&#x53C2;&#x8003; <code>atlas-demo/app/build.gradle</code></p>\n<h2 id=\"packageidfileproperties\">packageIdFile.properties</h2>\n<p>&#x6BCF;&#x4E2A;bundle&#x5728;&#x751F;&#x6210;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x9700;&#x8981;&#x4E3A;&#x5176;&#x5206;&#x914D;&#x72EC;&#x7ACB;&#x7684;packageId&#xFF0C;&#x7528;&#x4EE5;&#x4F7F;&#x5176;&#x4FDD;&#x8BC1;&#x6BCF;&#x4E2A;bundle&#x7684;&#x8D44;&#x6E90;ID&#x5168;&#x5C40;&#x552F;&#x4E00;&#xFF1B;&#x8D44;&#x6E90;ID&#x7684;&#x53EF;&#x5206;&#x914D;&#x533A;&#x95F4;&#x4E3A;<strong>[0x21,0x7f)</strong>,0x1x&#x4E3A;&#x7CFB;&#x7EDF;&#x4FDD;&#x7559;&#xFF0C;0x7f&#x4E3A;&#x4E3B;apk&#x4F7F;&#x7528;&#xFF0C;0x20&#x4E4B;&#x524D;&#x7684;&#x53D1;&#x73B0;miui&#x91CC;&#x9762;&#x5185;&#x90E8;&#x5DF2;&#x4F7F;&#x7528;&#xFF0C;&#x6240;&#x4EE5;&#x76EE;&#x524D;&#x6211;&#x6CA1;&#x9009;&#x62E9;&#x8FD9;&#x4E2A;&#x533A;&#x95F4;&#x4F5C;&#x4E3A;bundle&#x7684;packageId&#x5206;&#x914D;&#x533A;&#x95F4;\n&#x4E66;&#x5199;&#x7684;&#x683C;&#x5F0F;&#x4E3A;&#xFF1A;<strong>groupId:artificatId=XX</strong>&#xFF08;&#x5982;&#x4E0B;&#x56FE;&#xFF09;</p>\n<h2 id=\"bundlebaseinfofilejson\">bundleBaseInfoFile.json</h2>\n<p>bundleBaseInfoFile &#x662F;&#x4E00;&#x4E2A;JSON&#x683C;&#x5F0F;&#x7684;&#x6587;&#x4EF6;&#xFF0C;&#x91CC;&#x9762;&#x8BB0;&#x5F55;bundle&#x7684;&#x4FE1;&#x606F;&#x4EE5;&#x53CA;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#xFF0C;<strong>dependency</strong>&#x5B57;&#x6BB5;&#x7528;&#x4E8E;&#x6807;&#x8BC6;&#x8BE5;bundle&#x6240;&#x4F9D;&#x8D56;&#x7684;bundle&#xFF0C;&#x5982;&#x679C;A&#x4F9D;&#x8D56;B&#xFF0C;B&#x4F9D;&#x8D56;C&#xFF0C;&#x5219;&#x89E6;&#x53D1;&#x7684;Abundle&#x5B89;&#x88C5;&#x65F6;&#xFF0C;&#x5B9E;&#x9645;&#x7684;&#x5B89;&#x88C5;&#x987A;&#x5E8F;&#x4E3A;C-&gt;B-&gt;A,<strong>JSONArrary&#x4E2D;&#x6BCF;&#x4E2A;item&#x7684;key&#x4E3A;&#x8BE5;bundle&#x7684;artificatID,dependency&#x91CC;&#x9762;&#x7684;item&#x4E3A;&#x88AB;&#x4F9D;&#x8D56;&#x7684;bundle&#x7684;packageName</strong>\n&gt;\n<img src=\"guide_img/bundlebaseinfo.png\" alt=\"MacDown Screenshot\"></p>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"./\" class=\"navigation navigation-prev \" aria-label=\"Previous page: 接入指引\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"guide_for_bundle.html\" class=\"navigation navigation-next \" aria-label=\"Next page: bundle拆分|新建\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"容器接入\",\"level\":\"1.3.1\",\"depth\":2,\"next\":{\"title\":\"bundle拆分|新建\",\"level\":\"1.3.2\",\"depth\":2,\"path\":\"guide-for-use/guide_for_bundle.md\",\"ref\":\"guide-for-use/guide_for_bundle.md\",\"articles\":[]},\"previous\":{\"title\":\"接入指引\",\"level\":\"1.3\",\"depth\":1,\"path\":\"guide-for-use/README.md\",\"ref\":\"guide-for-use/README.md\",\"articles\":[{\"title\":\"容器接入\",\"level\":\"1.3.1\",\"depth\":2,\"path\":\"guide-for-use/guide_for_build.md\",\"ref\":\"guide-for-use/guide_for_build.md\",\"articles\":[]},{\"title\":\"bundle拆分|新建\",\"level\":\"1.3.2\",\"depth\":2,\"path\":\"guide-for-use/guide_for_bundle.md\",\"ref\":\"guide-for-use/guide_for_bundle.md\",\"articles\":[]},{\"title\":\"awo编译\",\"level\":\"1.3.3\",\"depth\":2,\"path\":\"guide-for-use/guide_for_compile.md\",\"ref\":\"guide-for-use/guide_for_compile.md\",\"articles\":[]},{\"title\":\"跨bundle的代码重用和通信\",\"level\":\"1.3.4\",\"depth\":2,\"path\":\"guide-for-use/bundleCommunicate.md\",\"ref\":\"guide-for-use/bundleCommunicate.md\",\"articles\":[]}]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"guide-for-use/guide_for_build.md\",\"mtime\":\"2017-11-27T09:41:52.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/guide-for-use/guide_for_bundle.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>bundle拆分|新建 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"guide_for_compile.html\" />\n    \n    \n    <link rel=\"prev\" href=\"guide_for_build.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"./\">\n            \n                <a href=\"./\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"guide_for_build.html\">\n            \n                <a href=\"guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.3.2\" data-path=\"guide_for_bundle.html\">\n            \n                <a href=\"guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"guide_for_compile.html\">\n            \n                <a href=\"guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"bundleCommunicate.html\">\n            \n                <a href=\"bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../update/\">\n            \n                <a href=\"../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../update/principle.html\">\n            \n                <a href=\"../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../update/dexpatch.html\">\n            \n                <a href=\"../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../update/guide.html\">\n            \n                <a href=\"../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../faq/question.html\">\n            \n                <a href=\"../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../faq/help.html\">\n            \n                <a href=\"../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../faq/variant.html\">\n            \n                <a href=\"../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >bundle拆分|新建</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h2 id=\"&#x5982;&#x4F55;&#x6B63;&#x786E;&#x4F7F;&#x7528;bundle\">&#x5982;&#x4F55;&#x6B63;&#x786E;&#x4F7F;&#x7528;Bundle</h2>\n<h3 id=\"bundle&#x7684;&#x5DE5;&#x7A0B;&#x914D;&#x7F6E;\">bundle&#x7684;&#x5DE5;&#x7A0B;&#x914D;&#x7F6E;</h3>\n<ol>\n<li><p>bundle&#x81EA;&#x8EAB;&#x5DE5;&#x7A0B;build.gradle&#x91CC;&#x9762;&#x9700;&#x8981;&#x58F0;&#x660E;&#x4E3A;awb:</p>\n<pre><code> atlas.bundleConfig.awbBundle = true\n</code></pre></li>\n<li><p>&#x5EFA;&#x8BAE;&#x4FEE;&#x6539;plugin&#xFF0C;&#x66F4;&#x597D;&#x7684;&#x652F;&#x6301;aar&#x4F20;&#x9012;&#x4F9D;&#x8D56;&#x7B49;&#x95EE;&#x9898;&#xFF08;&#x53EF;&#x4EE5;&#x91C7;&#x7528;&#x539F;&#x751F;com.android.library&#xFF09;</p>\n<pre><code> apply plugin: &apos;com.taobao.atlas.library&apos;\n buildscript {\n    repositories {\n        mavenLocal()\n        jcenter()\n    }\n    dependencies {\n        classpath &quot;com.android.tools.build:gradle:2.1&quot;\n        classpath &quot;com.taobao.android:atlasplugin:1.0.0&quot; //&#x4F7F;&#x7528;com.taobao.atlas.library&#x65F6;&#x9700;&#x8981;&#x914D;&#x7F6E;atlasplugin&#x7B49;classpath\n    }\n}\n</code></pre></li>\n</ol>\n<ol>\n<li><p>&#x5916;&#x90E8;&#x914D;&#x7F6E;</p>\n<ol>\n<li><p>&#x5728;&#x4E3B;&#x5BA2;&#x5DE5;&#x7A0B;&#x7684;packageId.properties&#x4E2D;&#x58F0;&#x660E;&#x8D44;&#x6E90;&#x6BB5;&#xFF08;&#x4E5F;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;mtl.tBuildConfig.autoPackageId&#x8BBE;&#x7F6E;&#x81EA;&#x52A8;&#x5206;&#x914D;packageID&#xFF09;</p>\n<pre><code> com.taobao.android:firstbundle=34//groupId:artifactId=NUM\n</code></pre></li>\n<li><p>&#x5728;&#x4E3B;&#x5BA2;&#x5DE5;&#x7A0B;&#x7684;build.gradle&#x4E2D;&#x6DFB;&#x52A0;awb&#x4F9D;&#x8D56;</p>\n<pre><code> compile(&quot;com.taobao.android:firstbundle:1.0.0@awb&quot;)\n</code></pre></li>\n</ol>\n</li>\n</ol>\n<h3 id=\"bundle&#x7684;&#x6CE8;&#x610F;&#x70B9;\">bundle&#x7684;&#x6CE8;&#x610F;&#x70B9;</h3>\n<p>&#x9075;&#x5FAA;&#x4EE3;&#x7801;&#x89C4;&#x8303;&#x53EF;&#x4EE5;&#x6709;&#x6548;&#x907F;&#x514D;&#x5728;&#x8FD0;&#x884C;&#x65F6;&#x9047;&#x5230;&#x96BE;&#x4EE5;&#x6392;&#x67E5;&#x7684;&#x95EE;&#x9898;&#x3002;</p>\n<ol>\n<li>Bundle&#x7684;AndroidManifest&#x4E2D;&#x4E0D;&#x80FD;&#x6709;&#x5BF9;bundle&#x5185;&#x7684;&#x8D44;&#x6E90;&#x7684;&#x5F15;&#x7528;&#xFF1B;&#x6BD4;&#x5982;Activity&#x7684;Theme&#xFF0C;&#x9700;&#x8981;&#x58F0;&#x660E;&#x5728;&#x4E3B;apk&#x4E2D;&#x3002;Bundle&#x7684;Manifest&#x4F1A;&#x5408;&#x5E76;&#x8FDB;&#x4E3B;Manifest&#xFF0C;&#x5982;&#x679C;&#x6709;bundle&#x7684;&#x8D44;&#x6E90;&#x5F15;&#x7528;&#x4F1A;&#x76F4;&#x63A5;&#x5F15;&#x53D1;&#x6784;&#x5EFA;&#x51FA;&#x9519;&#xFF1B;&#x53E6;&#x5916;&#x53EF;&#x4EE5;&#x9009;&#x62E9;&#x7684;&#x65B9;&#x5F0F;&#x662F;AndroidManifest&#x91CC;&#x9762;&#x4E0D;&#x52A0;Theme&#xFF0C;&#x6539;&#x7528;&#x5728;Activity&#x7684;onCreate&#x65B9;&#x6CD5;&#x91CC;&#x9762;&#x8C03;&#x7528;setTheme&#x7684;&#x65B9;&#x5F0F;</li>\n<li>Activity&#x901A;&#x8FC7;overridePendingTransition&#x4F7F;&#x7528;&#x7684;&#x5207;&#x6362;&#x52A8;&#x753B;&#x7684;&#x6587;&#x4EF6;&#x8981;&#x653E;&#x5728;&#x4E3B;apk&#x4E2D;&#xFF1B;</li>\n<li>Bundle&#x5185;&#x7684;Class&#x6700;&#x597D;&#x4EE5;&#x7279;&#x5B9A;&#x7684;packageName&#x5F00;&#x5934;&#xFF0C;resource&#x6587;&#x4EF6;&#x80FD;&#x591F;&#x5E26;&#x6709;&#x7279;&#x5B9A;&#x7684;&#x524D;&#x7F00;&#x3002;&#x8FD9;&#x6837;&#x4E00;&#x6765;&#x53EF;&#x4EE5;&#x907F;&#x514D;&#x8D44;&#x6E90;&#x6216;&#x8005;&#x7C7B;&#x540D;&#x91CD;&#x590D;&#x800C;&#x5F15;&#x8D77;&#x7684;&#x8986;&#x76D6;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x5728;&#x51FA;&#x73B0;&#x95EE;&#x9898;&#x7684;&#x65F6;&#x5019;&#x53CA;&#x65F6;&#x5B9A;&#x4F4D;&#x5230;&#x51FA;&#x95EE;&#x9898;&#x7684;&#x6A21;&#x5757;</li>\n<li>Bundle&#x5185;&#x5982;&#x679C;&#x6709;&#x7528;&#x5230;&#x81EA;&#x5B9A;&#x4E49;style,&#x90A3;&#x4E48;style&#x7684;parent&#x5982;&#x679C;&#x4E5F;&#x662F;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x8BDD;&#xFF0C;parent&#x7684;&#x5B9A;&#x4E49;&#x5FC5;&#x987B;&#x4F4D;&#x4E8E;&#x4E3B;apk&#x4E2D;&#xFF0C;&#x8FD9;&#x662F;&#x7531;&#x4E8E;5.0&#x4EE5;&#x540E;&#x7CFB;&#x7EDF;&#x5185;style&#x67E5;&#x627E;&#x7684;&#x56FA;&#x6709;&#x903B;&#x8F91;&#x5BFC;&#x81F4;&#x7684;&#xFF0C;&#x5BB9;&#x5668;&#x5185;&#x6682;&#x4E0D;&#x80FD;&#x5B8C;&#x5168;&#x517C;&#x5BB9;</li>\n<li><p>Bundle&#x5185;&#x90E8;&#x5982;&#x679C;&#x6709;so&#xFF0C;&#x5219;&#x5B89;&#x88C5;&#x65F6;so&#x7531;&#x4E8E;&#x65E0;&#x6CD5;&#x89E3;&#x538B;&#x5230;apk lib&#x76EE;&#x5F55;&#x4E2D;&#xFF0C;&#x5BF9;&#x4E8E;&#x76F4;&#x63A5;&#x901A;&#x8FC7;native&#x5C42;&#x4F7F;&#x7528;dlopen&#x6765;&#x4F7F;&#x7528;so&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x4F1A;&#x5B58;&#x5728;&#x4E00;&#x5B9A;&#x9650;&#x5236;&#xFF0C;&#x4E14;&#x4F1A;&#x5F71;&#x54CD;&#x540E;&#x7EED;so&#x52A8;&#x6001;&#x90E8;&#x7F72;&#xFF0C;&#x6240;&#x4EE5;&#x76EE;&#x524D;bundle&#x5185;so&#x4E0D;&#x5EFA;&#x8BAE;&#x4F7F;&#x7528;dlopen&#x7684;&#x65B9;&#x5F0F;&#x6765;&#x4F7F;&#x7528;</p>\n</li>\n<li><p>Bundle&#x5185;&#x6709;&#x4F7F;&#x7528;&#x4E3B;&#x8FDB;&#x7A0B;&#x7684;contentProvider,&#x5219;Bundle&#x7684;AndroidManifest&#x7684;contentprovider&#x58F0;&#x660E;&#x4E2D;&#x6700;&#x597D;&#x5E26;&#x4E0A;</p>\n</li>\n</ol>\n<pre><code>    android:multiprocess=&quot;true&quot;\n    android:process=&quot;:XX&quot;\n</code></pre><p>&#x8FD9;&#x6837;&#x53EF;&#x4EE5;&#x907F;&#x514D;&#x4E3B;&#x8FDB;&#x7A0B;&#x4E00;&#x8D77;&#x6765;&#x5C31;&#x53BB;startBundle&#x5BFC;&#x81F4;&#x542F;&#x52A8;&#x65F6;&#x95F4;&#x8FC7;&#x957F;</p>\n<h3 id=\"&#x521D;&#x59CB;&#x5316;bundle\">&#x521D;&#x59CB;&#x5316;Bundle</h3>\n<p>bundle&#x53EF;&#x4EE5;&#x88AB;&#x8BA4;&#x4E3A;&#x662F;&#x4E00;&#x4E2A;&#x5C0F;&#x578B;&#x7684;apk&#xFF0C;&#x56E0;&#x6B64;&#x6BCF;&#x4E2A;bundle&#x7684;&#x521D;&#x59CB;&#x5316;&#x90FD;&#x662F;&#x4ECE;Bundle&#x7684;Application&#x5F00;&#x59CB;&#x7684;&#x3002;Application&#x88AB;&#x58F0;&#x660E;&#x5728;bundle&#x7684;AndroidManifest.xml&#x91CC;&#x9762;</p>\n<p><strong>&#x6CE8;&#x610F;&#x70B9;&#xFF1A;</strong>&#x867D;&#x7136;&#x542F;&#x52A8;&#x65B9;&#x5F0F;&#x7C7B;&#x4F3C;&#x4E0E;&#x666E;&#x901A;app&#xFF0C;&#x5148;&#x6267;&#x884C;attachBaseContext&#xFF0C;&#x518D;&#x6267;&#x884C;onCreate&#xFF0C;&#x4E0D;&#x8FC7;&#x6709;&#x4E24;&#x4E2A;&#x4E0D;&#x540C;&#x70B9;&#x9700;&#x8981;&#x5F15;&#x8D77;&#x6CE8;&#x610F;&#xFF1A;</p>\n<ol>\n<li><p>Application &#x521D;&#x59CB;&#x5316;&#x7684;&#x7EBF;&#x7A0B;&#x57FA;&#x4E8E;start bundle&#x65F6;&#x7684;&#x7EBF;&#x7A0B;&#xFF0C;&#x8FD9;&#x6837;&#x5BFC;&#x81F4;&#x4E86;bundle&#x53EF;&#x80FD;&#x4F1A;&#x8FD0;&#x884C;&#x5728;&#x4E3B;&#x7EBF;&#x7A0B;&#xFF0C;&#x4E5F;&#x53EF;&#x80FD;&#x662F;&#x5728;&#x5B50;&#x7EBF;&#x7A0B;&#xFF0C;&#x6240;&#x4EE5;&#x521D;&#x59CB;&#x5316;&#x7684;&#x4EE3;&#x7801;&#x5982;&#x679C;&#x5BF9;&#x7EBF;&#x7A0B;&#x654F;&#x611F;&#x7684;&#x9700;&#x8981;&#x6CE8;&#x610F;&#xFF1A;&#x5982;&#x679C;&#x9700;&#x8981;&#x5F3A;&#x5236;&#x4E3B;&#x7EBF;&#x7A0B;&#x7684;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;new Handler(Looper.getMainLooper()).post &#x53BB;&#x521D;&#x59CB;&#x5316;</p>\n</li>\n<li><p>bundle&#x7684;Application&#x5E76;&#x4E0D;&#x662F;&#x88AB;&#x7CFB;&#x7EDF;&#x771F;&#x6B63;&#x8BA4;&#x53EF;&#x7684;Application&#xFF0C;&#x6240;&#x4EE5;&#x9700;&#x8981;Application&#x4F5C;&#x4E3A;&#x53C2;&#x6570;&#x8FDB;&#x884C;&#x521D;&#x59CB;&#x5316;&#x7684;&#x65B9;&#x6CD5;&#x53EF;&#x4EE5;&#x4F20;&#x5165;getBaseContext()&#xFF0C;Bundle Application&#x7684;mBase&#x5B9E;&#x9645;&#x4E0A;&#x5C31;&#x662F;apk&#x771F;&#x6B63;&#x7684;application&#xFF0C;&#x6700;&#x597D;&#x4E0D;&#x8981;&#x76F4;&#x63A5;&#x4F20;&#x5165;bundle&#x7684;Application&#x672C;&#x8EAB;&#x8FDB;&#x884C;&#x521D;&#x59CB;&#x5316;&#xFF0C;&#x4F1A;&#x5B58;&#x5728;&#x6F5C;&#x5728;&#x7684;&#x98CE;&#x9669;&#x3002;</p>\n</li>\n</ol>\n<h3 id=\"bundle&#x5982;&#x4F55;&#x63D0;&#x4F9B;&#x670D;&#x52A1;&#x7ED9;&#x5176;&#x4ED6;bundle\">Bundle&#x5982;&#x4F55;&#x63D0;&#x4F9B;&#x670D;&#x52A1;&#x7ED9;&#x5176;&#x4ED6;Bundle</h3>\n<p><strong>Bundle&#x867D;&#x7136;&#x63D0;&#x4F9B;&#x4E86;&#x4F9D;&#x8D56;&#x7684;&#x65B9;&#x5F0F;&#xFF0C;&#x4F46;&#x662F;&#x8FD9;&#x79CD;&#x65B9;&#x5F0F;&#x5982;&#x679C;&#x4F7F;&#x7528;&#x4E0D;&#x5F53;&#x53CD;&#x800C;&#x4F1A;&#x5E26;&#x6765;&#x9690;&#x60A3;&#xFF0C;&#x4E14;&#x4E0E;bundle&#x672C;&#x8EAB;&#x7684;&#x5C01;&#x88C5;&#x6027;&#x76F8;&#x8FDD;&#x80CC;&#x3002;</strong>&#x901A;&#x5E38;&#x5982;&#x679C;&#x67D0;&#x4E2A;&#x4E2D;&#x95F4;&#x4EF6;&#x662F;&#x4EE5;bundle&#x7684;&#x5F62;&#x5F0F;&#x5B58;&#x5728;&#xFF0C;&#x90A3;&#x58F0;&#x660E;&#x4F9D;&#x8D56;&#x662F;&#x53EF;&#x884C;&#x7684;&#x3002;&#x5982;&#x679C;&#x4E24;&#x4E2A;&#x672C;&#x8EAB;&#x76F8;&#x5BF9;&#x72EC;&#x7ACB;&#x7684;&#x4E1A;&#x52A1;bundle&#x5B58;&#x5728;&#x67D0;&#x51E0;&#x4E2A;&#x529F;&#x80FD;&#x63A5;&#x53E3;&#x7684;&#x4F9D;&#x8D56;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x670D;&#x52A1;&#x7684;&#x65B9;&#x5F0F;&#xFF0C;&#x670D;&#x52A1;&#x63D0;&#x4F9B;&#x65B9;&#x63D0;&#x4F9B;aidl&#x7684;&#x63A5;&#x53E3;&#xFF0C;&#x88AB;&#x4F7F;&#x7528;&#x65B9;&#x6216;&#x8005;&#x4E3B;apk&#x4F9D;&#x8D56;&#xFF1B;&#x540C;&#x65F6;&#x81EA;&#x5DF1;bundle&#x5185;&#x90E8;&#x5B9E;&#x73B0;service&#x7684;&#x529F;&#x80FD;&#x3002;</p>\n<h3 id=\"&#x4E3B;&#x52A8;&#x542F;&#x52A8;bundle\">&#x4E3B;&#x52A8;&#x542F;&#x52A8;Bundle</h3>\n<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Bundle&#x53EA;&#x5F80;&#x5916;&#x66B4;&#x9732;&#x4E86;android&#x539F;&#x751F;&#x7684;component,&#x8FD0;&#x884C;&#x671F;&#x6309;&#x9700;&#x52A0;&#x8F7D;&#x3002;&#x67D0;&#x4E9B;&#x7279;&#x6B8A;&#x7684;bundle&#xFF08;&#x6BD4;&#x5982;&#x8BF4;&#x76D1;&#x63A7;&#x6027;&#x8D28;&#x7684;&#xFF09;&#x672C;&#x8EAB;&#x4E0E;&#x5176;&#x4ED6;&#x4EE3;&#x7801;&#x5B8C;&#x5168;&#x72EC;&#x7ACB;&#xFF0C;&#x4E14;&#x53C8;&#x9700;&#x8981;&#x5728;&#x67D0;&#x4E2A;&#x65F6;&#x95F4;&#x70B9;&#x542F;&#x52A8;&#x8FD0;&#x884C;&#x7684;&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5982;&#x4E0B;&#x65B9;&#x5F0F;&#x53BB;&#x542F;&#x52A8;&#xFF1A;\n&#x52A0;&#x4E0A;Bundle&#x7684;PackageName&#x4E3A;&#xFF1A;com.sample.bundleA</p>\n<p>```</p>\n<pre><code>    Atlas.getInstance().installBundleTransitivelyAsync(\n    new String[]{&quot;com.sample.bundleA&quot;}, \n            new BundleInstaller.InstallListener() {\n        @Override\n        public void onFinished() {\n            BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(&quot;com.sample.bundleA&quot;);\n            if(impl!=null){\n                try {\n                    impl.start();\n                } catch (BundleException e) {\n                    e.printStackTrace();\n                }\n            }\n        }\n    });\n</code></pre>\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"guide_for_build.html\" class=\"navigation navigation-prev \" aria-label=\"Previous page: 容器接入\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"guide_for_compile.html\" class=\"navigation navigation-next \" aria-label=\"Next page: awo编译\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"bundle拆分|新建\",\"level\":\"1.3.2\",\"depth\":2,\"next\":{\"title\":\"awo编译\",\"level\":\"1.3.3\",\"depth\":2,\"path\":\"guide-for-use/guide_for_compile.md\",\"ref\":\"guide-for-use/guide_for_compile.md\",\"articles\":[]},\"previous\":{\"title\":\"容器接入\",\"level\":\"1.3.1\",\"depth\":2,\"path\":\"guide-for-use/guide_for_build.md\",\"ref\":\"guide-for-use/guide_for_build.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"guide-for-use/guide_for_bundle.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/guide-for-use/guide_for_compile.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>awo编译 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"bundleCommunicate.html\" />\n    \n    \n    <link rel=\"prev\" href=\"guide_for_bundle.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"./\">\n            \n                <a href=\"./\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"guide_for_build.html\">\n            \n                <a href=\"guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"guide_for_bundle.html\">\n            \n                <a href=\"guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.3.3\" data-path=\"guide_for_compile.html\">\n            \n                <a href=\"guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"bundleCommunicate.html\">\n            \n                <a href=\"bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../update/\">\n            \n                <a href=\"../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../update/principle.html\">\n            \n                <a href=\"../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../update/dexpatch.html\">\n            \n                <a href=\"../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../update/guide.html\">\n            \n                <a href=\"../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../faq/question.html\">\n            \n                <a href=\"../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../faq/help.html\">\n            \n                <a href=\"../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../faq/variant.html\">\n            \n                <a href=\"../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >awo编译</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h3 id=\"&#x5F85;&#x66F4;&#x65B0;\">&#x5F85;&#x66F4;&#x65B0;</h3>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"guide_for_bundle.html\" class=\"navigation navigation-prev \" aria-label=\"Previous page: bundle拆分|新建\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"bundleCommunicate.html\" class=\"navigation navigation-next \" aria-label=\"Next page: 跨bundle的代码重用和通信\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"awo编译\",\"level\":\"1.3.3\",\"depth\":2,\"next\":{\"title\":\"跨bundle的代码重用和通信\",\"level\":\"1.3.4\",\"depth\":2,\"path\":\"guide-for-use/bundleCommunicate.md\",\"ref\":\"guide-for-use/bundleCommunicate.md\",\"articles\":[]},\"previous\":{\"title\":\"bundle拆分|新建\",\"level\":\"1.3.2\",\"depth\":2,\"path\":\"guide-for-use/guide_for_bundle.md\",\"ref\":\"guide-for-use/guide_for_bundle.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"guide-for-use/guide_for_compile.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/guide-for-use/index.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>接入指引 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"guide_for_build.html\" />\n    \n    \n    <link rel=\"prev\" href=\"../principle-intro/File_architecture_runtime.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.3\" data-path=\"./\">\n            \n                <a href=\"./\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"guide_for_build.html\">\n            \n                <a href=\"guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"guide_for_bundle.html\">\n            \n                <a href=\"guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"guide_for_compile.html\">\n            \n                <a href=\"guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"bundleCommunicate.html\">\n            \n                <a href=\"bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../update/\">\n            \n                <a href=\"../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../update/principle.html\">\n            \n                <a href=\"../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../update/dexpatch.html\">\n            \n                <a href=\"../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../update/guide.html\">\n            \n                <a href=\"../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../faq/question.html\">\n            \n                <a href=\"../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../faq/help.html\">\n            \n                <a href=\"../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../faq/variant.html\">\n            \n                <a href=\"../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >接入指引</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"&#x63A5;&#x5165;&#x6307;&#x5F15;\">&#x63A5;&#x5165;&#x6307;&#x5F15;</h1>\n<p>&#x8BF7;&#x63A5;&#x5165;&#x524D;&#x4ED4;&#x7EC6;&#x9605;&#x8BFB;&#x63A5;&#x5165;&#x6587;&#x6863;.</p>\n<p>&#x63A5;&#x5165;&#x53EF;&#x53C2;&#x8003;<a href=\"https://github.com/alibaba/atlas/tree/master/atlas-demo\" target=\"_blank\">atlas-demo</a></p>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"../principle-intro/File_architecture_runtime.html\" class=\"navigation navigation-prev \" aria-label=\"Previous page: 运行期文件结构\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"guide_for_build.html\" class=\"navigation navigation-next \" aria-label=\"Next page: 容器接入\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"接入指引\",\"level\":\"1.3\",\"depth\":1,\"next\":{\"title\":\"容器接入\",\"level\":\"1.3.1\",\"depth\":2,\"path\":\"guide-for-use/guide_for_build.md\",\"ref\":\"guide-for-use/guide_for_build.md\",\"articles\":[]},\"previous\":{\"title\":\"运行期文件结构\",\"level\":\"1.2.4\",\"depth\":2,\"path\":\"principle-intro/File_architecture_runtime.md\",\"ref\":\"principle-intro/File_architecture_runtime.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"guide-for-use/README.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/index.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>Introduction · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter active\" data-level=\"1.1\" data-path=\"./\">\n            \n                <a href=\"./\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"principle-intro/Runtime_principle.html\">\n            \n                <a href=\"principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"principle-intro/Project_architectured.html\">\n            \n                <a href=\"principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"principle-intro/Apk_architecture.html\">\n            \n                <a href=\"principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"guide-for-use/\">\n            \n                <a href=\"guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"guide-for-use/guide_for_build.html\">\n            \n                <a href=\"guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"update/\">\n            \n                <a href=\"update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"update/principle.html\">\n            \n                <a href=\"update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"update/dexpatch.html\">\n            \n                <a href=\"update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"update/dexpatch_use_guide.html\">\n            \n                <a href=\"update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"update/guide.html\">\n            \n                <a href=\"update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"faq/question.html\">\n            \n                <a href=\"faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"faq/help.html\">\n            \n                <a href=\"faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"faq/variant.html\">\n            \n                <a href=\"faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"faq/dynamic_failed_help.html\">\n            \n                <a href=\"faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\".\" >Introduction</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"atlas---browse-this-in-english-\">Atlas   <a href=\"en/index.html\">Browse this in English </a></h1>\n<p><a href=\"https://render.alipay.com/p/s/taobaonpm_click/atlas_aliyun_logo_click\" target=\"_blank\"><img src=\"https://render.alipay.com/p/s/taobaonpm_click/atlas_aliyun_logo\" align=\"right\" style=\" width:360px;height:120 px\"></a> \n<img src=\"dingtalk.png\" align=\"left\" style=\" width:130px;height:130 px\">\n<br>&#x626B;&#x7801;&#x52A0;&#x5165;atlas&#x9489;&#x9489;&#x4EA4;&#x6D41;&#x7FA4;<br><br><br>\n<br>\n<br>\n<br>\n<br></p>\n<h2 id=\"&#x7B80;&#x4ECB;\">&#x7B80;&#x4ECB;</h2>\n<p>Atlas&#x662F;&#x4F34;&#x968F;&#x7740;&#x624B;&#x673A;&#x6DD8;&#x5B9D;&#x7684;&#x4E0D;&#x65AD;&#x53D1;&#x5C55;&#x800C;&#x884D;&#x751F;&#x51FA;&#x6765;&#x7684;&#x4E00;&#x4E2A;&#x8FD0;&#x884C;&#x4E8E;Android&#x7CFB;&#x7EDF;&#x4E0A;&#x7684;&#x4E00;&#x4E2A;&#x5BB9;&#x5668;&#x5316;&#x6846;&#x67B6;&#xFF0C;&#x6211;&#x4EEC;&#x4E5F;&#x53EB;&#x52A8;&#x6001;&#x7EC4;&#x4EF6;&#x5316;(Dynamic Bundle)&#x6846;&#x67B6;&#x3002;&#x5B83;&#x4E3B;&#x8981;&#x63D0;&#x4F9B;&#x4E86;&#x89E3;&#x8026;&#x5316;&#x3001;&#x7EC4;&#x4EF6;&#x5316;&#x3001;&#x52A8;&#x6001;&#x6027;&#x7684;&#x652F;&#x6301;&#x3002;&#x8986;&#x76D6;&#x4E86;&#x5DE5;&#x7A0B;&#x5E08;&#x7684;&#x5DE5;&#x7A0B;&#x7F16;&#x7801;&#x671F;&#x3001;Apk&#x8FD0;&#x884C;&#x671F;&#x4EE5;&#x53CA;&#x540E;&#x7EED;&#x8FD0;&#x7EF4;&#x671F;&#x7684;&#x5404;&#x79CD;&#x95EE;&#x9898;&#x3002;</p>\n<p>Atlas&#x5BF9;app&#x7684;&#x5212;&#x5206;&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;:</p>\n<p><img src=\"img/relation.png\" alt=\"\"></p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">&#x62C6;&#x5206;</th>\n<th style=\"text-align:left\">&#x5B9A;&#x4F4D;</th>\n<th style=\"text-align:left\">&#x8BF4;&#x660E;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">host</td>\n<td style=\"text-align:left\">&#x57FA;&#x7840;&#x652F;&#x6301;</td>\n<td style=\"text-align:left\">&#x5305;&#x542B;&#x72EC;&#x7ACB;&#x7684;&#x4E2D;&#x95F4;&#x4EF6;&#xFF0C;&#x4EE5;&#x53CA;&#x4E00;&#x4E2A;Base&#x7684;&#x5DE5;&#x7A0B;&#xFF0C;&#x91CC;&#x9762;&#x53EF;&#x80FD;&#x5305;&#x542B;&#x5E94;&#x7528;&#x7684;Application&#xFF0C;&#x5E94;&#x7528;icon&#x7B49;&#x57FA;&#x7840;&#x6027;&#x5185;&#x5BB9;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">bundle</td>\n<td style=\"text-align:left\">&#x4E1A;&#x52A1;&#x5C42;&#x57FA;&#x672C;&#x5355;&#x4F4D;</td>\n<td style=\"text-align:left\"><strong>&#x8FD0;&#x884C;&#x671F;&#x6309;&#x9700;&#x52A8;&#x6001;&#x52A0;&#x8F7D;</strong>&#x3002;bundle&#x53EF;&#x4EE5;&#x8C03;&#x7528;host&#x7684;&#x4EE3;&#x7801;&#x548C;&#x8D44;&#x6E90;&#xFF0C;&#x540C;&#x65F6;bundle&#x4E4B;&#x95F4;&#x5141;&#x8BB8;&#x5B58;&#x5728;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#x3002;</td>\n</tr>\n</tbody>\n</table>\n<blockquote>\n<p>&#x4E0E;&#x63D2;&#x4EF6;&#x5316;&#x6846;&#x67B6;&#x4E0D;&#x540C;&#x7684;&#x662F;&#xFF0C;Atlas&#x662F;&#x4E00;&#x4E2A;&#x7EC4;&#x4EF6;&#x6846;&#x67B6;&#xFF0C;Atlas&#x4E0D;&#x662F;&#x4E00;&#x4E2A;&#x591A;&#x8FDB;&#x7A0B;&#x7684;&#x6846;&#x67B6;&#xFF0C;&#x4ED6;&#x4E3B;&#x8981;&#x5B8C;&#x6210;&#x7684;&#x5C31;&#x662F;&#x5728;&#x8FD0;&#x884C;&#x73AF;&#x5883;&#x4E2D;&#x6309;&#x9700;&#x5730;&#x53BB;&#x5B8C;&#x6210;&#x5404;&#x4E2A;bundle&#x7684;&#x5B89;&#x88C5;&#xFF0C;&#x52A0;&#x8F7D;&#x7C7B;&#x548C;&#x8D44;&#x6E90;&#x3002;</p>\n</blockquote>\n<h2 id=\"atlas&#x63D0;&#x4F9B;&#x54EA;&#x4E9B;&#x529F;&#x80FD;\">Atlas&#x63D0;&#x4F9B;&#x54EA;&#x4E9B;&#x529F;&#x80FD;</h2>\n<p><strong>&#x4ECE;app&#x7684;&#x5F00;&#x53D1;&#x671F;--&#x8FD0;&#x884C;&#x671F;--&#x4E0A;&#x7EBF;&#x540E;&#x7684;&#x8FD0;&#x7EF4;&#x671F;&#xFF0C;Atlas&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x6574;&#x5957;&#x5B8C;&#x6574;&#x7684;&#x652F;&#x6301;</strong></p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">&#x5468;&#x671F;</th>\n<th style=\"text-align:left\">&#x8BF4;&#x660E;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">&#x5DE5;&#x7A0B;&#x671F;</td>\n<td style=\"text-align:left\">&#x5B9E;&#x73B0;host&#x3001;bundle&#x72EC;&#x7ACB;&#x5F00;&#x53D1;&#x3001;&#x8C03;&#x8BD5;&#x7684;&#x529F;&#x80FD;&#xFF0C;bundle&#x72EC;&#x7ACB;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">&#x8FD0;&#x884C;&#x671F;</td>\n<td style=\"text-align:left\">&#x5B9E;&#x73B0;&#x5B8C;&#x6574;&#x7684;&#x7EC4;&#x4EF6;&#x751F;&#x547D;&#x5468;&#x671F;&#x7684;&#x6620;&#x5C04;&#xFF0C;&#x7C7B;&#x9694;&#x79BB;&#x3001;&#x8D44;&#x6E90;&#x5171;&#x4EAB;&#x7B49;&#x673A;&#x5236;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">&#x8FD0;&#x7EF4;&#x671F;</td>\n<td style=\"text-align:left\">&#x589E;&#x91CF;&#x66F4;&#x65B0;&#x4FEE;&#x590D;&#x80FD;&#x529B;&#xFF0C;&#x63D0;&#x4F9B;&#x5BF9;class&#x3001;so&#x4EE5;&#x53CA;&#x8D44;&#x6E90;&#x7684;&#x589E;&#x91CF;&#x66F4;&#x65B0;&#x4FEE;&#x590D;&#x80FD;&#x529B;&#xFF0C;&#x5FEB;&#x901F;&#x5347;&#x7EA7;</td>\n</tr>\n</tbody>\n</table>\n<p>&#x4EE5;&#x4E00;&#x4E2A;app&#x7684;&#x5F00;&#x53D1;&#x7684;&#x751F;&#x547D;&#x5468;&#x671F;&#x4E3A;&#x4F8B;&#xFF0C;&#x53C2;&#x89C1; <a href=\"https://github.com/alibaba/atlas/blob/master/atlas-demo/AtlasDemo\" target=\"_blank\">demo</a></p>\n<h3 id=\"&#x5F00;&#x53D1;&#x671F;\">&#x5F00;&#x53D1;&#x671F;</h3>\n<p>&#x63D0;&#x4F9B;gradle&#x63D2;&#x4EF6;&#xFF0C;&#x7B80;&#x5316;&#x5F00;&#x53D1;&#x8005;&#x63A5;&#x5165;&#x7684;&#x8D1F;&#x62C5;&#x3002;</p>\n<p>&#x9700;&#x8981;&#x8BF4;&#x660E;&#x7684;&#x662F;&#xFF0C;gradle&#x63D2;&#x4EF6;&#x4E0D;&#x4F1A;&#x4FB5;&#x5165;&#x6B63;&#x5E38;&#x7684;&#x5F00;&#x53D1;&#x6D41;&#x7A0B;&#xFF0C;host&#x548C;bundle&#x90FD;&#x53EF;&#x4EE5;&#x72EC;&#x7ACB;&#x7684;&#x8FDB;&#x884C;&#x5F00;&#x53D1;&#x548C;&#x8C03;&#x8BD5;&#x3002;</p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">plugin</th>\n<th style=\"text-align:left\">&#x8BF4;&#x660E;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">com.taobao.atlas</td>\n<td style=\"text-align:left\">&#x7528;&#x4E8E;host&#x5DE5;&#x7A0B;&#xFF0C;&#x7528;&#x4E8E;&#x8BBE;&#x7F6E;&#x5BF9;bundle&#x7684;&#x4F9D;&#x8D56;&#x548C;&#x5176;&#x5B83;atlas&#x7684;&#x529F;&#x80FD;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">com.taobao.atlas.library</td>\n<td style=\"text-align:left\">&#x5BF9;&#x5E94;bundle&#x5DE5;&#x7A0B;&#xFF0C;&#x7528;&#x4E8E;&#x5C06;module&#x8F6C;&#x5316;&#x6210;atlas&#x6240;&#x9700;&#x8981;&#x7684;bundle&#x4F9D;&#x8D56;&#xFF0C;&#x4E0D;&#x4F1A;&#x4FB5;&#x5165;&#x6B63;&#x5E38;&#x7684;&#x5F00;&#x53D1;&#x73AF;&#x5883;</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"&#x8FD0;&#x884C;&#x671F;\">&#x8FD0;&#x884C;&#x671F;</h3>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">&#x529F;&#x80FD;</th>\n<th style=\"text-align:left\">&#x8BF4;&#x660E;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">&#x56DB;&#x5927;&#x7EC4;&#x4EF6;&#x652F;&#x6301;</td>\n<td style=\"text-align:left\">&#x652F;&#x6301;&#x8FD0;&#x884C;bundle&#x4E2D;&#x7684;&#x56DB;&#x5927;&#x7EC4;&#x4EF6;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">&#x5171;&#x4EAB;&#x4EE3;&#x7801;&#x8D44;&#x6E90;</td>\n<td style=\"text-align:left\">bundle&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x4F7F;&#x7528;host&#x4E2D;&#x7684;&#x4EE3;&#x7801;&#x548C;&#x8D44;&#x6E90;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">bundle&#x6309;&#x9700;&#x52A0;&#x8F7D;</td>\n<td style=\"text-align:left\">&#x4E1A;&#x52A1;&#x9700;&#x8981;&#x65F6;&#xFF0C;&#x624D;&#x4F1A;&#x53BB;&#x52A0;&#x8F7D;&#x5BF9;&#x5E94;bundle&#x4E2D;&#x7684;&#x4EE3;&#x7801;&#x548C;&#x8D44;&#x6E90;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">&#x8FDC;&#x7A0B;bundle</td>\n<td style=\"text-align:left\">&#x51CF;&#x5C11;&#x5305;&#x4F53;&#x79EF;&#x3002;&#x4E0D;&#x5E38;&#x7528;&#x7684;bundle&#x653E;&#x5728;&#x4E91;&#x7AEF;&#xFF0C;&#x9700;&#x8981;&#x65F6;&#x6309;&#x9700;&#x4E0B;&#x8F7D;&#x3002;&#x5F53;&#x7528;&#x6237;&#x8BBE;&#x5907;&#x7A7A;&#x95F4;&#x7D27;&#x5F20;&#x65F6;,&#x53EF;&#x4EE5;&#x6E05;&#x7406;&#x6389;&#x4E00;&#x4E9B;&#x957F;&#x671F;&#x4E0D;&#x7528;&#x7684;&#x7EC4;&#x4EF6;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">&#x89E3;&#x91CA;&#x6267;&#x884C;</td>\n<td style=\"text-align:left\">&#x4E3A;&#x4E86;&#x964D;&#x4F4E;&#x7528;&#x6237;&#x7B49;&#x5F85;&#x65F6;&#x95F4;&#xFF0C;Atlas&#x6846;&#x67B6;&#x5728;dalivk&#x7CFB;&#x7EDF;&#x4E0A;&#x9996;&#x6B21;&#x4F7F;&#x7528;bundle&#x65F6;&#x5173;&#x95ED;&#x4E86;verify&#xFF0C;&#x5728;ART&#x7CFB;&#x7EDF;&#x4E0A;&#x9996;&#x6B21;&#x4F7F;&#x7528;&#x65F6;&#x5173;&#x95ED;&#x4E86;dex2oat&#x8D70;&#x89E3;&#x91CA;&#x6267;&#x884C;&#x3002;&#x540C;&#x65F6;&#x540E;&#x53F0;&#x901A;&#x8FC7;&#x5F02;&#x6B65;&#x4EFB;&#x52A1;&#x8D70;&#x539F;&#x751F;&#x7684;dexopt&#x8FC7;&#x7A0B;&#xFF0C;&#x4E3A;&#x4E0B;&#x6B21;&#x4F7F;&#x7528;&#x505A;&#x597D;&#x51C6;&#x5907;</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"&#x8FD0;&#x7EF4;&#x671F;\">&#x8FD0;&#x7EF4;&#x671F;</h3>\n<p><strong>&#x52A8;&#x6001;&#x90E8;&#x7F72;</strong> &#x662F;&#x5BB9;&#x5668;&#x4E00;&#x4E2A;&#x6700;&#x91CD;&#x8981;&#x7684;&#x529F;&#x80FD;&#x3002;&#x57FA;&#x4E8E;&#x6B64;:</p>\n<ul>\n<li>&#x4E1A;&#x52A1;&#x53EF;&#x4EE5;&#x7075;&#x6D3B;&#x53D1;&#x5E03;&#x81EA;&#x5DF1;&#x7684;&#x9700;&#x6C42;</li>\n<li>&#x6709;&#x6545;&#x969C;&#x7684;&#x4E1A;&#x52A1;&#x53EF;&#x4EE5;&#x53CA;&#x65F6;&#x4FEE;&#x590D;&#x6216;&#x8005;&#x56DE;&#x6EDA;</li>\n<li>&#x540C;&#x65F6;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x5FEB;&#x901F;&#x8986;&#x76D6;&#x80FD;&#x529B;&#x5728;&#x7070;&#x5EA6;&#x7B49;&#x573A;&#x666F;&#x4E0B;&#x53EF;&#x4EE5;&#x66F4;&#x5FEB;&#x5730;&#x6536;&#x5230;&#x6240;&#x9700;&#x7684;&#x6548;&#x679C;&#x3002;</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">&#x529F;&#x80FD;</th>\n<th style=\"text-align:left\">&#x8BF4;&#x660E;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">&#x52A8;&#x6001;&#x90E8;&#x7F72;</td>\n<td style=\"text-align:left\">&#x6784;&#x5EFA;&#x65F6;&#x4F1A;&#x4E0E;&#x4E4B;&#x524D;&#x7248;&#x672C;&#x7684;dex&#x8FDB;&#x884C;&#x5B57;&#x8282;&#x7801;&#x7EA7;&#x522B;&#x7684;diff&#xFF0C;&#x751F;&#x6210;tpatch&#x5305;&#x3002;&#x6700;&#x7EC8;&#x4E0B;&#x53D1;&#x5230;&#x7528;&#x6237;&#x624B;&#x673A;&#x7684;patch&#x4EC5;&#x5305;&#x542B;&#x53D8;&#x5316;class&#x7EC4;&#x6210;&#x7684;dex&#x548C;&#x66F4;&#x6539;&#x6216;&#x8005;&#x65B0;&#x589E;&#x7684;&#x8D44;&#x6E90;&#x6587;&#x4EF6;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">dexpatch</td>\n<td style=\"text-align:left\">&#x4EE5;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x6280;&#x672F;&#x65B9;&#x6848;&#x4E3A;&#x57FA;&#x7840;&#xFF0C;&#x53EF;&#x4EE5;&#x770B;&#x4F5C;&#x662F;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x5B50;&#x96C6;&#xFF0C;&#x4E13;&#x6CE8;&#x4E8E;&#x5355;&#x4E2A;bundle&#x7684;&#x6545;&#x969C;&#x4FEE;&#x590D;&#x3002;&#x7531;&#x4E8E;&#x505A;&#x7684;&#x4E8B;&#x5C0F;&#x800C;&#x7CBE;&#xFF0C;&#x6240;&#x4EE5;&#x7F16;&#x8BD1;&#x6784;&#x5EFA;&#x901F;&#x5EA6;&#x3001;&#x7EBF;&#x4E0A;&#x751F;&#x6548;&#x901F;&#x5EA6;&#x90FD;&#x662F;&#x8FDC;&#x8FDC;&#x5FEB;&#x4E8E;&#x52A8;&#x6001;&#x90E8;&#x7F72;</td>\n</tr>\n</tbody>\n</table>\n<h2 id=\"&#x5982;&#x4F55;&#x63A5;&#x5165;\">&#x5982;&#x4F55;&#x63A5;&#x5165;</h2>\n<p>&#x6211;&#x4EEC;&#x6BD4;&#x8F83;&#x503E;&#x5411;&#x4E8E;&#x7528;&#x4E00;&#x4E2A;&#x6BD4;&#x8F83;&#x5E72;&#x51C0;&#x7684;&#x58F3;&#x5B50;&#x5DE5;&#x7A0B;&#x6765;&#x4F5C;&#x4E3A;&#x5BB9;&#x5668;&#x67B6;&#x6784;&#x4E0B;&#x7684;&#x6253;&#x5305;&#x5DE5;&#x7A0B;,&#x79F0;&#x4E4B;&#x4E3A;<strong>main_builder</strong>&#xFF0C;<strong>main_builder</strong>&#x5EFA;&#x8BAE;&#x53EA;&#x5B58;&#x5728;AndroidManifest.xml&#x3001;&#x6784;&#x5EFA;&#x6587;&#x4EF6;&#x53CA;&#x90E8;&#x5206;&#x8D44;&#x6E90;&#x5185;&#x5BB9;&#x3002;</p>\n<ul>\n<li>manifest&#xFF1A;&#x6587;&#x4EF6;&#x7528;&#x4E8E;&#x5355;&#x72EC;&#x7BA1;&#x7406;apk&#x7684;icon&#xFF0C;&#x7248;&#x672C;&#x53F7;&#xFF0C;versioncode&#x7B49;&#xFF1B;</li>\n<li>gradle&#xFF1A;&#x7528;&#x4E8E;&#x914D;&#x7F6E;&#x4E3B;apk&#x7684;&#x4F9D;&#x8D56;&#x53CA;&#x63A7;&#x5236;&#x6784;&#x5EFA;&#x53C2;&#x6570;</li>\n</ul>\n<p>&#x4EE5; <a href=\"https://github.com/alibaba/atlas/blob/master/atlas-demo/AtlasDemo\" target=\"_blank\">demo</a> &#x4E3A;&#x4F8B;</p>\n<ol>\n<li><p>&#x5F15;&#x7528;Atlas&#x63D2;&#x4EF6;&#x53CA;&#x4F9D;&#x8D56;&#x4ED3;&#x5E93;&#xFF0C;&#x4FEE;&#x6539;&#x5DE5;&#x7A0B;gradle&#x6587;&#x4EF6;</p>\n<pre><code> buildscript {\n     repositories { jcenter()}\n     dependencies {\n         classpath &quot;com.taobao.android:atlasplugin:2.3.3.beta2&quot;\n     }\n }\n</code></pre></li>\n<li><p>bundle&#x63A5;&#x5165;&#xFF0C;&#x4FEE;&#x6539;bundle&#x7684;gradle&#xFF0C;&#x53C2;&#x89C1;<a href=\"https://github.com/alibaba/atlas/blob/master/atlas-demo/AtlasDemo\" target=\"_blank\">demo</a>&#x4E2D;&#x7684;firstbundle&#x914D;&#x7F6E;</p>\n<pre><code> apply plugin: &apos;com.taobao.atlas.library&apos;\n\n atlas {\n     //&#x58F0;&#x660E;&#x4E3A;awb &#x5373;bundle&#x5DE5;&#x7A0B;\n     bundleConfig { awbBundle true }\n }\n</code></pre></li>\n<li><p>&#x5BB9;&#x5668;&#x63A5;&#x5165;&#xFF0C;&#x4FEE;&#x6539;app&#x6A21;&#x5757;&#x7684;gradle&#x6587;&#x4EF6;</p>\n<pre><code> apply plugin: &apos;com.taobao.atlas.application&apos;\n dependencies {\n     //&#x6838;&#x5FC3;sdk\n     compile(&apos;com.taobao.android:atlas_core:5.0.0@aar&apos;) {\n          transitive = true\n      }\n      //&#x5982;&#x679C;&#x4E0D;&#x9700;&#x8981;&#x7528;&#x5230;atlas&#x7684;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x529F;&#x80FD;&#xFF0C;&#x4E0D;&#x9700;&#x8981;&#x4F9D;&#x8D56;atlasupdate\n      compile &apos;com.taobao.android:atlasupdate:1.0.8@aar&apos;\n\n      //&#x8BBE;&#x7F6E;bundle&#x4F9D;&#x8D56;\n      bundleCompile project(&apos;:firstbundle&apos;)\n  }\n  atlas {\n   atlasEnabled true\n   //...\n}\n</code></pre></li>\n</ol>\n<p>&#x81F3;&#x6B64;&#xFF0C;&#x63A5;&#x5165;&#x5B8C;&#x6210;&#xFF0C;&#x4E0D;&#x9700;&#x8981;&#x63A5;&#x5165;&#x65B9;&#x8C03;&#x7528;&#x4EFB;&#x4F55;&#x521D;&#x59CB;&#x5316;&#x51FD;&#x6570;&#xFF0C;&#x8BE6;&#x7EC6;&#x7684;&#x6587;&#x6863;&#x53C2; <a href=\"https://alibaba.github.io/atlas/guide-for-use/guide_for_build.html\" target=\"_blank\">&#x63A5;&#x5165;&#x6587;&#x6863;</a>&#xFF0C;</p>\n<h2 id=\"support\">Support</h2>\n<p>&#x652F;&#x6301;&#x7248;&#x672C; 4.0 to 7.0. </p>\n<table>\n<thead>\n<tr>\n<th>Runtime</th>\n<th>Android Version</th>\n<th>Support</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Dalvik</td>\n<td>2.2</td>\n<td>Not Test</td>\n</tr>\n<tr>\n<td>Dalvik</td>\n<td>2.3</td>\n<td>Not Test</td>\n</tr>\n<tr>\n<td>Dalvik</td>\n<td>3.0</td>\n<td>Not Test</td>\n</tr>\n<tr>\n<td>Dalvik</td>\n<td>4.0-4.4</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td>ART</td>\n<td>5.0</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td>ART</td>\n<td>5.1</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td>ART</td>\n<td>M</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td>ART</td>\n<td>N</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n<h2 id=\"&#x5176;&#x5B83;\">&#x5176;&#x5B83;</h2>\n<ul>\n<li><a href=\"https://alibaba.github.io/atlas/faq/question.html\" target=\"_blank\">FAQ</a> </li>\n<li><a href=\"https://alibaba.github.io/atlas/\" target=\"_blank\">&#x6587;&#x6863;</a></li>\n<li><a href=\"https://mp.weixin.qq.com/s?__biz=MzAxNDEwNjk5OQ==&amp;mid=2650400348&amp;idx=1&amp;sn=99bc1bce932c5b9000d5b54afa2de70e\" target=\"_blank\">Atlas-&#x624B;&#x6DD8;&#x7EC4;&#x4EF6;&#x5316;&#x6846;&#x67B6;&#x7684;&#x524D;&#x4E16;&#x4ECA;&#x751F;&#x548C;&#x672A;&#x6765;&#x7684;&#x8DEF;</a></li>\n</ul>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"Introduction\",\"level\":\"1.1\",\"depth\":1,\"next\":{\"title\":\"原理解析\",\"level\":\"1.2\",\"depth\":1,\"ref\":\"\",\"articles\":[{\"title\":\"框架原理\",\"level\":\"1.2.1\",\"depth\":2,\"path\":\"principle-intro/Runtime_principle.md\",\"ref\":\"principle-intro/Runtime_principle.md\",\"articles\":[]},{\"title\":\"名词解释\",\"level\":\"1.2.2\",\"depth\":2,\"path\":\"principle-intro/Project_architectured.md\",\"ref\":\"principle-intro/Project_architectured.md\",\"articles\":[]},{\"title\":\"APK结构\",\"level\":\"1.2.3\",\"depth\":2,\"path\":\"principle-intro/Apk_architecture.md\",\"ref\":\"principle-intro/Apk_architecture.md\",\"articles\":[]},{\"title\":\"运行期文件结构\",\"level\":\"1.2.4\",\"depth\":2,\"path\":\"principle-intro/File_architecture_runtime.md\",\"ref\":\"principle-intro/File_architecture_runtime.md\",\"articles\":[]}]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"README.md\",\"mtime\":\"2017-11-27T09:41:28.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\".\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"gitbook/gitbook.js\"></script>\n    <script src=\"gitbook/theme.js\"></script>\n    \n        \n        <script src=\"gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/principle-intro/Apk_architecture.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>APK结构 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"File_architecture_runtime.html\" />\n    \n    \n    <link rel=\"prev\" href=\"Project_architectured.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"Runtime_principle.html\">\n            \n                <a href=\"Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"Project_architectured.html\">\n            \n                <a href=\"Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.2.3\" data-path=\"Apk_architecture.html\">\n            \n                <a href=\"Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"File_architecture_runtime.html\">\n            \n                <a href=\"File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../guide-for-use/\">\n            \n                <a href=\"../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../update/\">\n            \n                <a href=\"../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../update/principle.html\">\n            \n                <a href=\"../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../update/dexpatch.html\">\n            \n                <a href=\"../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../update/guide.html\">\n            \n                <a href=\"../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../faq/question.html\">\n            \n                <a href=\"../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../faq/help.html\">\n            \n                <a href=\"../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../faq/variant.html\">\n            \n                <a href=\"../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >APK结构</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"apk&#x7ED3;&#x6784;\">APK&#x7ED3;&#x6784;</h1>\n<p>&#x57FA;&#x4E8E;Atlas&#x6784;&#x5EFA;&#x540E;&#x7684;APK&#x7ED3;&#x6784;&#x5982;&#x4E0B;&#x56FE;&#xFF0C;host&#x4E0E;&#x666E;&#x901A;Apk&#x65E0;&#x5F02;&#xFF0C;&#x4F46;&#x662F;Manifest&#x548C;assets&#x4F1A;&#x6DFB;&#x52A0;&#x4E00;&#x4E9B;&#x989D;&#x5916;&#x7684;&#x5185;&#x5BB9;&#xFF0C;&#x540C;&#x65F6;&#x5728;armeabi&#x76EE;&#x5F55;&#x4E2D;&#x4F1A;&#x589E;&#x52A0;&#x82E5;&#x5E72;&#x4E2A;bundle&#x6784;&#x5EFA;&#x7684;&#x4EA7;&#x7269;&#xFF0C;&#x53D6;&#x540D;&#x4E3A;String.format(lib%s.so,packagename.replace(&quot;.&quot;,&quot;_&quot;))&#xFF1B;packagename&#x4E3A;bundle&#x7684;AndroidManifest&#x4E2D;&#x7684;packagename,&#x8FD9;&#x4E9B;so&#x90FD;&#x662F;&#x6B63;&#x5E38;&#x7684;apk&#x7ED3;&#x6784;&#xFF0C;&#x6539;&#x4E3A;so&#x653E;&#x5165;lib&#x76EE;&#x5F55;&#x53EA;&#x662F;&#x4E3A;&#x4E86;&#x5B89;&#x88C5;&#x65F6;&#x501F;&#x7528;&#x7CFB;&#x7EDF;&#x7684;&#x80FD;&#x529B;&#x4ECE;apk&#x4E2D;&#x89E3;&#x538B;&#x51FA;&#x6765;&#xFF0C;&#x65B9;&#x4FBF;&#x540E;&#x7EED;&#x5B89;&#x88C5;\n&gt;\n<img src=\"Project_architectured_img/apk_struct.png\" alt=\"MacDown Screenshot\"></p>\n<h2 id=\"assetsbundleinfo-versionjson\">assets/bundleinfo-version.json</h2>\n<p>&#x6784;&#x5EFA;&#x5B8C;&#x7684;apk&#x5728;host&#x7684;assets&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x4F1A;&#x6709;&#x4E2A;bundleinfo-verison.json&#x7684;&#x6587;&#x4EF6;&#xFF0C;&#x5176;&#x4E2D;version&#x4E3A;manifest&#x4E2D;&#x7684;versinonname&#xFF0C;&#x91CC;&#x9762;&#x8BB0;&#x5F55;&#x4E86;&#x6BCF;&#x4E2A;bundle&#x5927;&#x5C0F;&#xFF0C;&#x7248;&#x672C;&#xFF0C;&#x540D;&#x5B57;&#x4EE5;&#x53CA;&#x91CC;&#x9762;&#x6240;&#x6709;&#x7684;component&#x4FE1;&#x606F;&#xFF0C;&#x8FD9;&#x4E9B;&#x5185;&#x5BB9;&#x5728;&#x6784;&#x5EFA;&#x7684;&#x65F6;&#x5019;&#x751F;&#x6210;&#xFF0C;&#x57FA;&#x4E8E;&#x8FD9;&#x4E9B;&#x4FE1;&#x606F;&#x6BCF;&#x4E2A;bundle&#x53EF;&#x4EE5;&#x5728;component&#x88AB;&#x89E6;&#x53D1;&#x7684;&#x65F6;&#x5019;&#x53BB;&#x6309;&#x9700;&#x7684;&#x8FDB;&#x884C;&#x5B89;&#x88C5;&#xFF0C;&#x6574;&#x4E2A;&#x8FC7;&#x7A0B;&#x5BF9;&#x5F00;&#x53D1;&#x8005;&#x900F;&#x660E;&#xFF08;&#x4ECE;&#x4E2D;&#x4E5F;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;bundle&#x5BF9;&#x5916;&#x66B4;&#x9732;&#x7684;&#x53EA;&#x662F;&#x57FA;&#x4E8E;Android&#x539F;&#x751F;&#x7684;Activity&#xFF0C;service&#xFF0C;receiver&#x7B49;component&#xFF09;&#x3002;\n&gt;\n<img src=\"Project_architectured_img/bundleinfo.png\" alt=\"MacDown Screenshot\"></p>\n<h2 id=\"androidmanifest\">AndroidManifest</h2>\n<p>bundleinfo&#x7684;&#x4FE1;&#x606F;&#x540C;&#x65F6;&#x4E5F;&#x4F1A;&#x5728;&#x6784;&#x5EFA;&#x540E;&#x7684;&#x4E3B;manifest&#x91CC;&#x9762;&#x4F53;&#x73B0;&#xFF0C;&#x5982;&#x7EBF;&#x6846;1&#x3001;2&#x6240;&#x793A;&#xFF0C;&#x6BCF;&#x4E2A;component&#x4E0B;&#x9762;meta-datal&#x91CC;&#x9762;&#x8BB0;&#x5F55;&#x8BE5;component&#x6240;&#x5728;&#x7684;meta-data,&#x540C;&#x65F6;bundle&#x67D0;&#x4E9B;&#x7279;&#x6709;&#x7684;&#x4FE1;&#x606F;&#x4F1A;&#x8BB0;&#x5F55;&#x5728;application&#x7EA7;&#x522B;&#x7684;meta-data&#x91CC;&#x9762;&#x3002;\n&gt;\n<img src=\"Project_architectured_img/manifest.png\" alt=\"MacDown Screenshot\"></p>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"Project_architectured.html\" class=\"navigation navigation-prev \" aria-label=\"Previous page: 名词解释\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"File_architecture_runtime.html\" class=\"navigation navigation-next \" aria-label=\"Next page: 运行期文件结构\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"APK结构\",\"level\":\"1.2.3\",\"depth\":2,\"next\":{\"title\":\"运行期文件结构\",\"level\":\"1.2.4\",\"depth\":2,\"path\":\"principle-intro/File_architecture_runtime.md\",\"ref\":\"principle-intro/File_architecture_runtime.md\",\"articles\":[]},\"previous\":{\"title\":\"名词解释\",\"level\":\"1.2.2\",\"depth\":2,\"path\":\"principle-intro/Project_architectured.md\",\"ref\":\"principle-intro/Project_architectured.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"principle-intro/Apk_architecture.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/principle-intro/File_architecture_runtime.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>运行期文件结构 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"../guide-for-use/\" />\n    \n    \n    <link rel=\"prev\" href=\"Apk_architecture.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"Runtime_principle.html\">\n            \n                <a href=\"Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"Project_architectured.html\">\n            \n                <a href=\"Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"Apk_architecture.html\">\n            \n                <a href=\"Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.2.4\" data-path=\"File_architecture_runtime.html\">\n            \n                <a href=\"File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../guide-for-use/\">\n            \n                <a href=\"../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../update/\">\n            \n                <a href=\"../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../update/principle.html\">\n            \n                <a href=\"../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../update/dexpatch.html\">\n            \n                <a href=\"../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../update/guide.html\">\n            \n                <a href=\"../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../faq/question.html\">\n            \n                <a href=\"../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../faq/help.html\">\n            \n                <a href=\"../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../faq/variant.html\">\n            \n                <a href=\"../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >运行期文件结构</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"&#x8FD0;&#x884C;&#x671F;&#x6587;&#x4EF6;&#x7ED3;&#x6784;\">&#x8FD0;&#x884C;&#x671F;&#x6587;&#x4EF6;&#x7ED3;&#x6784;</h1>\n<ol>\n<li><p>/data/data/pkgname/files/bundlelisting</p>\n<p>&#x4E4B;&#x524D;&#x6253;&#x5305;&#x6784;&#x5EFA;&#x65F6;&#x8BB0;&#x5F55;&#x7684;bundleinfo&#x4FE1;&#x606F;&#xFF08;&#x53D1;&#x751F;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x6536;&#x6587;&#x4EF6;&#x4F1A;&#x8FDB;&#x884C;&#x66F4;&#x65B0;&#xFF09;</p>\n</li>\n<li><p>/data/data/pkgname/files/baselineinfo</p>\n<p> &#x5B58;&#x653E;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x540E;&#x7684;&#x7248;&#x672C;&#x53D8;&#x5316;&#x5185;&#x5BB9;&#xFF0C;&#x4EE5;&#x53CA;&#x6BCF;&#x6B21;&#x90E8;&#x7F72;&#x53D1;&#x751F;&#x66F4;&#x65B0;&#x7684;bundle&#x7684;&#x7248;&#x672C;&#xFF0C;&#x4F9D;&#x8D56;&#x7B49;&#x4FE1;&#x606F;</p>\n</li>\n<li><p>/data/data/pkgname/files/storage</p>\n<p> storage&#x76EE;&#x5F55;&#x662F;bundle&#x5B89;&#x88C5;&#x7684;&#x76EE;&#x5F55;&#xFF0C;&#x6BCF;&#x4E2A;bundle&#x7684;&#x5B89;&#x88C5;&#x76EE;&#x5F55;&#x4EE5;bundle&#x7684;packagename&#x4E3A;&#x6587;&#x4EF6;&#x5939;&#x540D;&#xFF0C;&#x9996;&#x6B21;&#x542F;&#x52A8;&#x540E;&#x4F1A;&#x5B89;&#x88C5;&#x5230;version.1&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x76EE;&#x5F55;&#x4E2D;&#x53EF;&#x80FD;&#x542B;&#x6709;bundle&#x7684;zip&#x6587;&#x4EF6;&#xFF0C;dex&#x6587;&#x4EF6;&#x4EE5;&#x53CA;native so&#x7B49;&#x5185;&#x5BB9;&#x3002;&#x5982;&#x679C;bundle&#x53D1;&#x751F;&#x66F4;&#x65B0;&#xFF0C;&#x5219;&#x53EF;&#x80FD;&#x4F1A;&#x6709;version.2&#x3001;version.3 &#x7B49;&#x76EE;&#x5F55;&#xFF0C;&#x6BCF;&#x6B21;&#x52A0;&#x8F7D;bundle&#x7684;&#x65F6;&#x5019;&#x9009;&#x53D6;&#x6700;&#x9AD8;&#x53EF;&#x7528;&#x7248;&#x672C;&#x8FDB;&#x884C;&#x8F7D;&#x5165;&#x3002;&#x8003;&#x8651;bundle&#x7684;&#x56DE;&#x6EDA;&#x529F;&#x80FD;&#x548C;&#x5BF9;&#x7A7A;&#x95F4;&#x5360;&#x7528;&#x7684;&#x5F71;&#x54CD;&#xFF0C;&#x76EE;&#x524D;&#x5BB9;&#x5668;&#x5185;&#x6700;&#x591A;&#x4FDD;&#x7559;&#x4E24;&#x4E2A;&#x6700;&#x8FD1;&#x53EF;&#x7528;&#x7248;&#x672C;&#x3002;\n&gt;\n<img src=\"Project_architectured_img/runtime.png\" alt=\"MacDown Screenshot\"></p>\n</li>\n</ol>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"Apk_architecture.html\" class=\"navigation navigation-prev \" aria-label=\"Previous page: APK结构\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"../guide-for-use/\" class=\"navigation navigation-next \" aria-label=\"Next page: 接入指引\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"运行期文件结构\",\"level\":\"1.2.4\",\"depth\":2,\"next\":{\"title\":\"接入指引\",\"level\":\"1.3\",\"depth\":1,\"path\":\"guide-for-use/README.md\",\"ref\":\"guide-for-use/README.md\",\"articles\":[{\"title\":\"容器接入\",\"level\":\"1.3.1\",\"depth\":2,\"path\":\"guide-for-use/guide_for_build.md\",\"ref\":\"guide-for-use/guide_for_build.md\",\"articles\":[]},{\"title\":\"bundle拆分|新建\",\"level\":\"1.3.2\",\"depth\":2,\"path\":\"guide-for-use/guide_for_bundle.md\",\"ref\":\"guide-for-use/guide_for_bundle.md\",\"articles\":[]},{\"title\":\"awo编译\",\"level\":\"1.3.3\",\"depth\":2,\"path\":\"guide-for-use/guide_for_compile.md\",\"ref\":\"guide-for-use/guide_for_compile.md\",\"articles\":[]},{\"title\":\"跨bundle的代码重用和通信\",\"level\":\"1.3.4\",\"depth\":2,\"path\":\"guide-for-use/bundleCommunicate.md\",\"ref\":\"guide-for-use/bundleCommunicate.md\",\"articles\":[]}]},\"previous\":{\"title\":\"APK结构\",\"level\":\"1.2.3\",\"depth\":2,\"path\":\"principle-intro/Apk_architecture.md\",\"ref\":\"principle-intro/Apk_architecture.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"principle-intro/File_architecture_runtime.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/principle-intro/Project_architectured.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>名词解释 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"Apk_architecture.html\" />\n    \n    \n    <link rel=\"prev\" href=\"Runtime_principle.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"Runtime_principle.html\">\n            \n                <a href=\"Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.2.2\" data-path=\"Project_architectured.html\">\n            \n                <a href=\"Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"Apk_architecture.html\">\n            \n                <a href=\"Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"File_architecture_runtime.html\">\n            \n                <a href=\"File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../guide-for-use/\">\n            \n                <a href=\"../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../update/\">\n            \n                <a href=\"../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../update/principle.html\">\n            \n                <a href=\"../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../update/dexpatch.html\">\n            \n                <a href=\"../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../update/guide.html\">\n            \n                <a href=\"../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../faq/question.html\">\n            \n                <a href=\"../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../faq/help.html\">\n            \n                <a href=\"../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../faq/variant.html\">\n            \n                <a href=\"../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >名词解释</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"&#x540D;&#x8BCD;&#x89E3;&#x91CA;\">&#x540D;&#x8BCD;&#x89E3;&#x91CA;</h1>\n<p><strong>Bundle:</strong> &#x7C7B;&#x4F3C;OSGI&#x89C4;&#x8303;&#x91CC;&#x9762;bundle&#xFF08;&#x7EC4;&#x4EF6;&#xFF09;&#x7684;&#x6982;&#x5FF5;&#xFF0C;&#x6BCF;&#x4E2A;bundle&#x6709;&#x81EA;&#x5DF1;&#x7684;classloader&#xFF0C;&#x4E0E;&#x5176;&#x4ED6;bundle&#x76F8;&#x9694;&#x79BB;&#xFF0C;&#x540C;&#x65F6;Atlas&#x6846;&#x67B6;&#x4E0B;bundle&#x6709;&#x81EA;&#x8EAB;&#x7684;&#x8D44;&#x6E90;&#x6BB5;&#xFF08;PackageID&#xFF0C;&#x6253;&#x5305;&#x65F6;AAPT&#x6307;&#x5B9A;&#xFF09;&#xFF1B;&#x53E6;&#x5916;&#x4E0E;&#x539F;&#x6709;OSGI&#x6240;&#x5B9A;&#x4E49;&#x7684;service&#x683C;&#x5F0F;&#x4E0D;&#x540C;&#x4E4B;&#x5904;&#x662F;Atlas&#x91CC;&#x9762;Bundle&#x900F;&#x51FA;&#x6240;&#x6709;&#x5B9A;&#x4E49;&#x5728;Manifest&#x91CC;&#x9762;&#x7684;component&#xFF0C;&#x968F;&#x7740;service&#xFF0C;activity&#x7684;&#x89E6;&#x53D1;&#x6267;&#x884C;bundle&#x7684;&#x5B89;&#x88C5;&#xFF0C;&#x8FD0;&#x884C;&#x3002;</p>\n<p><strong>awb&#xFF1A;</strong> android wireless bundle&#x7684;&#x7F29;&#x5199;&#xFF0C;&#x5B9E;&#x9645;&#x4E0A;&#x540C;AAR&#x7C7B;&#x4F3C;&#xFF0C;&#x662F;&#x6700;&#x7EC8;&#x6784;&#x5EFA;&#x6574;&#x5305;&#x524D;&#x7684;&#x4E2D;&#x95F4;&#x4EA7;&#x7269;&#x3002;&#x6BCF;&#x4E2A;awb&#x6700;&#x7EC8;&#x4F1A;&#x6253;&#x6210;&#x4E00;&#x4E2A;bundle&#x3002;awb&#x4E0E;aar&#x7684;&#x552F;&#x4E00;&#x4E0D;&#x540C;&#x4E4B;&#x5904;&#x662F;awb&#x4E0E;&#x4E4B;&#x5BF9;&#x5E94;&#x6709;&#x4E2A;packageId&#x7684;&#x5B9A;&#x4E49;&#x3002;</p>\n<p><strong>host:</strong> &#x5BBF;&#x4E3B;&#x7684;&#x6982;&#x5FF5;&#xFF0C;&#x6240;&#x6709;&#x7684;bundle&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x8C03;&#x7528;host&#x5185;&#x7684;&#x4EE3;&#x7801;&#x548C;&#x8D44;&#x6E90;&#xFF0C;&#x6240;&#x4EE5;host&#x5E38;&#x5E38;&#x96C6;&#x5408;&#x4E86;&#x516C;&#x5171;&#x7684;&#x4E2D;&#x95F4;&#x4EF6;&#xFF0C;UI&#x8D44;&#x6E90;&#x7B49;&#x3002;host&#x548C;bundle&#x7684;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;&#xFF1A;</p>\n<p>&gt;\n<img src=\"Project_architectured_img/relation.png\" alt=\"MacDown Screenshot\"></p>\n<p>&#x4ECE;&#x4E0A;&#x56FE;&#x4E5F;&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#x57FA;&#x4E8E;Atlas&#x6784;&#x5EFA;&#x540E;&#x5927;&#x81F4;&#x5DE5;&#x7A0B;&#x7684;&#x7ED3;&#x6784;&#xFF1A;</p>\n<ol>\n<li>&#x9996;&#x5148;&#x6709;&#x4E2A;&#x6784;&#x5EFA;&#x6574;&#x4F53;APK&#x5DE5;&#x7A0B;Apk_builder,&#x91CC;&#x9762;&#x7BA1;&#x7406;&#x7740;&#x6240;&#x6709;&#x7684;&#x4F9D;&#x8D56;&#xFF08;&#x5305;&#x62EC;atlas&#xFF09;&#x53CA;&#x5176;&#x7248;&#x672C;&#xFF0C;Apk_builder&#x672C;&#x8EAB;&#x53EF;&#x80FD;&#x4E0D;&#x5305;&#x542B;&#x4EFB;&#x4F55;&#x4EE3;&#x7801;&#xFF0C;&#x53EA;&#x8D1F;&#x8D23;&#x6784;&#x5EFA;&#x4F7F;&#x7528;</li>\n<li>host&#x5185;&#x90E8;&#x5305;&#x542B;&#x72EC;&#x7ACB;&#x7684;&#x4E2D;&#x95F4;&#x4EF6;&#xFF0C;&#x4EE5;&#x53CA;&#x4E00;&#x4E2A;Base&#x7684;&#x5DE5;&#x7A0B;&#xFF0C;&#x91CC;&#x9762;&#x53EF;&#x80FD;&#x5305;&#x542B;&#x5E94;&#x7528;&#x7684;Application&#xFF0C;&#x5E94;&#x7528;icon&#x7B49;&#x57FA;&#x7840;&#x6027;&#x5185;&#x5BB9;&#xFF08;&#x5982;&#x679C;&#x8DB3;&#x591F;&#x72EC;&#x7ACB;&#xFF0C;application&#x4E5F;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x653E;&#x5728;apk_builder&#x5185;&#xFF09;&#xFF1B;</li>\n<li>&#x4E1A;&#x52A1;&#x5C42;&#x57FA;&#x672C;&#x4E0A;&#x4EE5;bundle&#x4E3A;&#x8FB9;&#x754C;&#x81EA;&#x4E0A;&#x800C;&#x4E0B;&#x4E0E;host&#x53D1;&#x751F;&#x8C03;&#x7528;&#xFF0C;&#x540C;&#x65F6;bundle&#x4E4B;&#x95F4;&#x5141;&#x8BB8;&#x5B58;&#x5728;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#xFF1B;&#x76F8;&#x5BF9;&#x4E1A;&#x52A1;&#x72EC;&#x7ACB;&#x7684;bundle&#x5982;&#x679C;&#x5B58;&#x5728;&#x63A5;&#x53E3;&#x8026;&#x5408;&#x5EFA;&#x8BAE;&#x5C01;&#x88C5;&#x6210;aidl service&#x7684;&#x65B9;&#x5F0F;&#x4FDD;&#x8BC1;&#x81EA;&#x8EAB;&#x5C01;&#x88C5;&#x6027;&#xFF1B;&#x540C;&#x65F6;&#x67D0;&#x4E9B;&#x4E2D;&#x95F4;&#x4EF6;&#x5982;&#x679C;&#x53EA;&#x5B58;&#x5728;&#x82E5;&#x5E72;bundle&#x4F7F;&#x7528;&#x7684;&#x4E5F;&#x53EF;&#x4EE5;&#x5C01;&#x88C5;bundle&#x7684;&#x65B9;&#x5F0F;&#x63D0;&#x4F9B;&#x51FA;&#x6765;&#xFF0C;&#x4EE5;&#x4FDD;&#x8BC1;host&#x5185;&#x5BB9;&#x7CBE;&#x7B80;</li>\n</ol>\n<p><strong>remote bundle&#xFF1A;</strong> &#x8FDC;&#x7A0B;bundle&#xFF0C;&#x8FDC;&#x7A0B;bundle&#x53EA;&#x662F;apk&#x6784;&#x5EFA;&#x65F6;&#x5E76;&#x672A;&#x6253;&#x5230;apk&#x5185;&#x90E8;&#xFF0C;&#x800C;&#x662F;&#x5355;&#x72EC;&#x653E;&#x5728;&#x4E86;&#x4E91;&#x7AEF;&#xFF1B;&#x540C;&#x65F6;&#x8FDC;&#x7A0B;bundle&#x7684;&#x9650;&#x5236;&#x6761;&#x4EF6;&#x662F;&#x7B2C;&#x4E00;&#x6B21;&#x88AB;&#x89E6;&#x53D1;&#x7684;&#x524D;&#x63D0;&#x662F;bundle&#x5185;&#x7684;Activity&#x9700;&#x8981;&#x88AB;start&#xFF0C;&#x6B64;&#x65F6;&#x57FA;&#x4E8E;Atlas&#x5185;&#x7684;ClassNotFoundInterceptorCallback&#x53EF;&#x4EE5;&#x8FDB;&#x884C;&#x8DF3;&#x8F6C;&#x7684;&#x91CD;&#x5B9A;&#x5411;&#xFF0C;&#x63D0;&#x793A;&#x7528;&#x6237;&#x4E0B;&#x8F7D;&#x5177;&#x4F53;bundle&#xFF0C;&#x5F85;&#x7528;&#x6237;&#x786E;&#x5B9A;&#x540E;&#x8FDB;&#x884C;&#x5F02;&#x6B65;&#x4E0B;&#x8F7D;&#x540C;&#x65F6;&#x5B8C;&#x6210;&#x540E;&#x518D;&#x8DF3;&#x8F6C;&#x5230;&#x76EE;&#x6807;bundle&#xFF08;&#x6B64;&#x90E8;&#x5206;&#x4EE3;&#x7801;&#x7531;&#x4E8E;&#x6D89;&#x53CA;&#x4E0B;&#x8F7D;&#x53CA;UI&#x5C55;&#x793A;&#x7B49;&#x5185;&#x5BB9;&#x5E76;&#x672A;&#x5305;&#x542B;&#x5728;&#x5F00;&#x6E90;&#x4ED3;&#x5E93;&#x4E2D;&#xFF0C;&#x6709;&#x9700;&#x8981;&#x53EF;&#x4EE5;&#x6839;&#x636E;ClassNotFoundInterceptorCallback&#x81EA;&#x884C;&#x5B9E;&#x73B0;&#xFF09;</p>\n<p><strong>&#x52A8;&#x6001;&#x90E8;&#x7F72;&#xFF1A;</strong> &#x57FA;&#x4E8E;Atlas&#x7684;installorUpdate&#x548C;atlas-update&#x5E93;&#x53CA;&#x6784;&#x5EFA;&#x63D2;&#x4EF6;&#xFF0C;&#x53EF;&#x4EE5;&#x751F;&#x6210;&#x4E0E;&#x4E4B;&#x524D;&#x53D1;&#x5E03;&#x7684;apk diff&#x751F;&#x6210;&#x7684;&#x5DEE;&#x5F02;&#x6587;&#x4EF6;&#xFF0C;&#x5728;&#x66F4;&#x65B0;&#x65F6;&#x62C9;&#x53D6;&#x540C;&#x65F6;&#x9759;&#x9ED8;&#x66F4;&#x65B0;&#x5230;&#x8BBE;&#x5907;&#x4E0A;&#xFF0C;&#x5728;&#x7528;&#x6237;&#x4E0B;&#x6B21;&#x542F;&#x52A8;&#x4E4B;&#x540E;&#x751F;&#x6548;&#x65B0;&#x4EE3;&#x7801;&#xFF0C;&#x5177;&#x4F53;&#x539F;&#x7406;&#x53EF;&#x4EE5;&#x53C2;&#x8003;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7AE0;&#x8282;&#x7684;&#x89E3;&#x6790;</p>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"Runtime_principle.html\" class=\"navigation navigation-prev \" aria-label=\"Previous page: 框架原理\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"Apk_architecture.html\" class=\"navigation navigation-next \" aria-label=\"Next page: APK结构\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"名词解释\",\"level\":\"1.2.2\",\"depth\":2,\"next\":{\"title\":\"APK结构\",\"level\":\"1.2.3\",\"depth\":2,\"path\":\"principle-intro/Apk_architecture.md\",\"ref\":\"principle-intro/Apk_architecture.md\",\"articles\":[]},\"previous\":{\"title\":\"框架原理\",\"level\":\"1.2.1\",\"depth\":2,\"path\":\"principle-intro/Runtime_principle.md\",\"ref\":\"principle-intro/Runtime_principle.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"principle-intro/Project_architectured.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/principle-intro/Runtime_principle.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>框架原理 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"Project_architectured.html\" />\n    \n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter active\" data-level=\"1.2.1\" data-path=\"Runtime_principle.html\">\n            \n                <a href=\"Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"Project_architectured.html\">\n            \n                <a href=\"Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"Apk_architecture.html\">\n            \n                <a href=\"Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"File_architecture_runtime.html\">\n            \n                <a href=\"File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../guide-for-use/\">\n            \n                <a href=\"../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"../update/\">\n            \n                <a href=\"../update/\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"../update/principle.html\">\n            \n                <a href=\"../update/principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"../update/dexpatch.html\">\n            \n                <a href=\"../update/dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"../update/dexpatch_use_guide.html\">\n            \n                <a href=\"../update/dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"../update/guide.html\">\n            \n                <a href=\"../update/guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../faq/question.html\">\n            \n                <a href=\"../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../faq/help.html\">\n            \n                <a href=\"../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../faq/variant.html\">\n            \n                <a href=\"../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >框架原理</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h2 id=\"&#x5BB9;&#x5668;&#x6846;&#x67B6;\">&#x5BB9;&#x5668;&#x6846;&#x67B6;</h2>\n<p>&gt;\n<img src=\"Project_architectured_img/runtime_struct.png\" alt=\"MacDown Screenshot\"></p>\n<p>&#x5982;&#x4E0A;&#x56FE;&#x6240;&#x793A;&#xFF0C;atlas&#x4E3B;&#x8981;&#x5206;&#x4E3A;&#x4EE5;&#x4E0B;&#x51E0;&#x4E2A;&#x5C42;&#x7EA7;&#xFF1A;</p>\n<ol>\n<li><p>&#x6700;&#x5E95;&#x4E0B;&#x7684;hack&#x5DE5;&#x5177;&#x5C42;&#xFF1A;\n&#x5305;&#x62EC;&#x4E86;&#x5BB9;&#x5668;&#x6240;&#x9700;&#x7684;&#x6240;&#x6709;&#x7CFB;&#x7EDF;&#x5C42;&#x9762;&#x7684;&#x6CE8;&#x5165;&#x548C;hack&#x7684;&#x5DE5;&#x5177;&#x7C7B;&#x521D;&#x59CB;&#x5316;&#x548C;&#x6821;&#x9A8C;&#xFF0C;&#x5BB9;&#x5668;&#x542F;&#x52A8;&#x65F6;&#x5148;&#x6821;&#x9A8C;&#x8BBE;&#x5907;&#x662F;&#x5426;&#x652F;&#x6301;&#x5BB9;&#x5668;&#x8FD0;&#x884C;&#xFF0C;&#x4E0D;&#x652F;&#x6301;&#x5219;&#x91C7;&#x53D6;&#x964D;&#x7EA7;&#x5E76;&#x8BB0;&#x5F55;&#x539F;&#x56E0;&#xFF1B; </p>\n</li>\n<li><p>Bundle Framework &#x8D1F;&#x8D23;bundle&#x7684;&#x5B89;&#x88C5; &#x66F4;&#x65B0; &#x64CD;&#x4F5C;&#x4EE5;&#x53CA;&#x7BA1;&#x7406;&#x6574;&#x4E2A;bundle&#x7684;&#x751F;&#x547D;&#x5468;&#x671F;&#xFF1B;</p>\n</li>\n<li><p>runtime&#x5C42;&#xFF1A;&#x4E3B;&#x8981;&#x5305;&#x62EC;&#x6E05;&#x5355;&#x7BA1;&#x7406;&#x3001;&#x7248;&#x672C;&#x7BA1;&#x7406;&#x3001;&#x4EE5;&#x53CA;&#x7CFB;&#x7EDF;&#x4EE3;&#x7406;&#x4E09;&#x5927;&#x5757;&#xFF0C;&#x57FA;&#x4E8E;&#x4E0D;&#x540C;&#x7684;&#x89E6;&#x53D1;&#x70B9;&#x6309;&#x9700;&#x6267;&#x884C;bundle&#x7684;&#x5B89;&#x88C5;&#x548C;&#x52A0;&#x8F7D;&#xFF1B;runtime&#x5C42;&#x540C;&#x65F6;&#x63D0;&#x4F9B;&#x4E86;&#x5F00;&#x53D1;&#x671F;&#x5FEB;&#x901F;debug&#x652F;&#x6301;&#x548C;&#x76D1;&#x63A7;&#x4E24;&#x4E2A;&#x529F;&#x80FD;&#x6A21;&#x5757;&#x3002;&#x4ECE;Delegate&#x5C42;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x6700;&#x6838;&#x5FC3;&#x7684;&#x4E24;&#x4E2A;&#x4EE3;&#x7406;&#x70B9;&#xFF1A;&#x4E00;&#x4E2A;&#x662F;DelegateClassLoader&#xFF1A;&#x8D1F;&#x8D23;&#x8DEF;&#x7531;class&#x52A0;&#x8F7D;&#x5230;&#x5404;&#x4E2A;bundle&#x5185;&#x90E8;&#xFF0C;&#x7B2C;&#x4E8C;&#x4E2A;&#x662F;DelegateResource&#xFF1A;&#x8D1F;&#x8D23;&#x8D44;&#x6E90;&#x67E5;&#x627E;&#x65F6;&#x80FD;&#x591F;&#x627E;&#x5230;bundle&#x5185;&#x7684;&#x8D44;&#x6E90;&#xFF1B;&#x8FD9;&#x662F;bundle&#x80FD;&#x591F;&#x771F;&#x6B63;&#x8FD0;&#x884C;&#x8D77;&#x6765;&#x7684;&#x6839;&#x672C;&#xFF1B;&#x5176;&#x4F59;&#x7684;&#x4EE3;&#x7406;&#x70B9;&#x5747;&#x662F;&#x4E3A;&#x4E86;&#x4FDD;&#x8BC1;&#x5728;&#x5FC5;&#x8981;&#x7684;&#x65F6;&#x673A;&#x6309;&#x9700;&#x52A0;&#x8F7D;&#x8D77;&#x6765;&#x76EE;&#x6807;bundle&#xFF0C;&#x8BA9;&#x5176;&#x53EF;&#x4EE5;&#x88AB;DelegateClassloader&#x548C;DelegateResource&#x4F7F;&#x7528;</p>\n</li>\n<li><p>&#x5BF9;&#x5916;&#x63A5;&#x5165;&#x5C42;:AtlasBridgeApplication&#x662F;atlas&#x6846;&#x67B6;&#x4E0B;apk&#x7684;&#x771F;&#x6B63;Application&#xFF0C;&#x5728;&#x57FA;&#x4E8E;Atlas&#x6846;&#x67B6;&#x6784;&#x5EFA;&#x7684;&#x8FC7;&#x7A0B;&#x4E2D;&#x4F1A;&#x66FF;&#x6362;&#x539F;&#x6709;manifest&#x4E2D;&#x7684;application&#xFF0C;&#x6240;&#x4EE5;Atlas&#x6CA1;&#x5165;&#x7684;&#x63A5;&#x5165;&#x5E76;&#x4E0D;&#x5B58;&#x5728;&#x4EFB;&#x4F55;&#x521D;&#x59CB;&#x5316;&#x4EE3;&#x7801;&#xFF0C;&#x6784;&#x5EFA;&#x811A;&#x672C;&#x5B8C;&#x6210;&#x4E86;&#x63A5;&#x5165;&#x7684;&#x8FC7;&#x7A0B;&#x3002;AtlasBridgeApplication&#x91CC;&#x9762;&#x9664;&#x4E86;&#x5B8C;&#x6210;&#x4E86;Atlas&#x7684;&#x521D;&#x59CB;&#x5316;&#x529F;&#x80FD;&#xFF0C;&#x540C;&#x65F6;<strong>&#x5185;&#x7F6E;&#x4E86;multidex&#x7684;&#x529F;&#x80FD;</strong>&#xFF0C;&#x8FD9;&#x6837;&#x505A;&#x7684;&#x539F;&#x56E0;&#x6709;&#x4E24;&#x4E2A;&#xFF1A;</p>\n<ol>\n<li>&#x5F88;&#x591A;&#x5927;&#x578B;&#x7684;app&#x4E0D;&#x5408;&#x7406;&#x7684;&#x521D;&#x59CB;&#x5316;&#x5BFC;&#x81F4;&#x7528;multidex&#x5206;&#x5305;&#x903B;&#x8F91;&#x62C6;&#x5206;&#x7684;&#x65F6;&#x5019;&#x4E3B;dex&#x7684;&#x4EE3;&#x7801;&#x5C31;&#x6709;&#x53EF;&#x80FD;&#x65B9;&#x6CD5;&#x6570;&#x8D85;&#x8FC7;65536&#xFF0C;\u0002AtlasBridgeApplication&#x4E0E;&#x4E1A;&#x52A1;&#x4EE3;&#x7801;&#x5B8C;&#x5168;&#x89E3;&#x8026;&#xFF0C;&#x6240;&#x4EE5;&#x62C6;&#x5206;&#x4E0A;&#x9762;&#x53EA;&#x8981;&#x4FDD;&#x8BC1;atlas&#x6846;&#x67B6;&#x5728;&#x4E3B;dex&#xFF0C;&#x5176;&#x4ED6;&#x4EE3;&#x7801;&#x65E0;&#x8BBA;&#x600E;&#x4E48;&#x62C6;&#x5206;&#x90FD;&#x4E0D;&#x4F1A;&#x6709;&#x95EE;&#x9898;&#xFF1B;</li>\n<li>&#x5982;&#x679C;&#x4E0D;&#x66FF;&#x6362;Application&#xFF0C;&#x90A3;&#x4E48;atlas&#x7684;&#x521D;&#x59CB;&#x5316;&#x5C31;&#x4F1A;&#x5728;application&#x91CC;&#x9762;&#xFF0C;&#x7531;&#x4E8E;&#x57FA;&#x4E8E;Atlas&#x7684;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x5B9E;&#x9645;&#x4E0A;&#x662F;&#x7C7B;&#x66FF;&#x6362;&#x7684;&#x673A;&#x5236;&#xFF0C;&#x90A3;&#x4E48;&#x8FD9;&#x79CD;&#x673A;&#x5236;&#x5C31;&#x4F1A;&#x5FC5;&#x7136;&#x5B58;&#x5728;&#x5305;&#x62EC;Application&#x53CA;&#x5176;import&#x7684;class&#x7B49;&#x90E8;&#x5206;&#x4EE3;&#x7801;&#x5728;dalvik&#x4E0D;&#x652F;&#x6301;&#x90E8;&#x7F72;&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x8FD9;&#x4E2A;&#x5728;&#x4F7F;&#x7528;&#x8FC7;&#x7A0B;&#x4E2D;&#x9020;&#x6210;&#x4E00;&#x5B9A;&#x6210;&#x672C;&#xFF0C;&#x9700;&#x8981;&#x5C0F;&#x5FC3;&#x7684;&#x4F7F;&#x7528;&#x4EE5;&#x907F;&#x514D;dalivk&#x5185;&#x90E8;class resolve&#x673A;&#x5236;&#x5BFC;&#x81F4;&#x90E8;&#x5206;class&#x6CA1;&#x6210;&#x529F;&#xFF0C;&#x66FF;&#x6362;&#x4EE5;&#x540E;&#x8BE5;&#x95EE;&#x9898;&#x5F97;&#x5230;&#x6700;&#x597D;&#x7684;&#x89E3;&#x51B3;&#xFF0C;&#x9664;atlas&#x672C;&#x8EAB;&#x4EE5;&#x5916;&#xFF0C;&#x6240;&#x6709;&#x4E1A;&#x52A1;&#x4EE3;&#x7801;&#x5747;&#x53EF;&#x4EE5;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#xFF1B;</li>\n</ol>\n</li>\n</ol>\n<p>&#x53E6;&#x5916;&#x5185;&#x7F6E;&#x7684;&#x539F;&#x751F;&#x7684;multidex&#x5728;dalvik&#x4E0A;&#x9762;&#x6027;&#x80FD;&#x5E76;&#x4E0D;&#x597D;&#xFF0C;atlas&#x5185;&#x90E8;&#x5BF9;&#x5176;&#x8FDB;&#x884C;&#x4E86;&#x4F18;&#x5316;&#x63D0;&#x9AD8;&#x4E86;&#x5728;dalvik&#x4E0A;&#x9762;&#x7684;&#x4F53;&#x9A8C;&#x3002;</p>\n<p>&#x9664;AtlasBridgeApplication&#x4E4B;&#x5916;&#xFF0C;&#x63A5;&#x5165;&#x5C42;&#x5BF9;&#x5916;&#x63D0;&#x4F9B;&#x4E86;&#x90E8;&#x5206;&#x5DE5;&#x5177;&#x7C7B;&#xFF0C;&#x5305;&#x62EC;&#x4E3B;&#x52A8;install bundle&#xFF0C;start bundle&#xFF0C;&#x4EE5;&#x53CA;&#x83B7;&#x53D6;&#x5168;&#x5C40;&#x7684;application&#x7B49;&#x5404;&#x79CD;&#x529F;&#x80FD;&#x3002;</p>\n<h2 id=\"bundle&#x751F;&#x547D;&#x5468;&#x671F;\">Bundle&#x751F;&#x547D;&#x5468;&#x671F;</h2>\n<p>&#x6BCF;&#x4E2A;bundle&#x7684;&#x751F;&#x547D;&#x5468;&#x671F;&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;&#xFF1A;\n&gt;\n<img src=\"Project_architectured_img/bundle_cycle.png\" alt=\"MacDown Screenshot\"></p>\n<p><strong>Installed</strong>    bundle&#x88AB;&#x5B89;&#x88C5;&#x5230;storage&#x76EE;&#x5F55;</p>\n<p><strong>Resolved</strong>  classloader&#x88AB;&#x521B;&#x5EFA;&#xFF0C;assetpatch&#x6CE8;&#x5165;DelegateResoucces</p>\n<p><strong>Active</strong>     bundle&#x7684;&#x5B89;&#x5168;&#x6821;&#x9A8C;&#x901A;&#x8FC7;&#xFF1B;bundle&#x7684;dex&#x68C0;&#x6D4B;&#x5DF2;&#x7ECF;&#x6210;&#x529F;dexopt(or dex2oat)&#xFF0C;resource&#x5DF2;&#x7ECF;&#x6210;&#x529F;&#x6CE8;&#x5165;</p>\n<p><strong>Started</strong>  bundle&#x5F00;&#x59CB;&#x8FD0;&#x884C;&#xFF0C;bundle application&#x7684;onCreate&#x65B9;&#x6CD5;&#x88AB;&#x8C03;&#x7528;</p>\n<h2 id=\"&#x7C7B;&#x52A0;&#x8F7D;&#x673A;&#x5236;\">&#x7C7B;&#x52A0;&#x8F7D;&#x673A;&#x5236;</h2>\n<p>Atlas&#x91CC;&#x9762;&#x901A;&#x5E38;&#x4F1A;&#x521B;&#x5EFA;&#x4E86;&#x4E24;&#x79CD;classLoader,&#x7B2C;&#x4E00;&#x4E2A;&#x662F;DelegateClassLoader&#xFF0C;&#x4ED6;&#x4F5C;&#x4E3A;&#x7C7B;&#x67E5;&#x627E;&#x7684;&#x4E00;&#x4E2A;&#x8DEF;&#x7531;&#x5668;&#x800C;&#x5B58;&#x5728;&#xFF0C;&#x672C;&#x8EAB;&#x5E76;&#x4E0D;&#x8D1F;&#x8D23;&#x771F;&#x6B63;&#x7C7B;&#x7684;&#x52A0;&#x8F7D;&#xFF1B;DelegateClassLoader&#x542F;&#x52A8;&#x65F6;&#x88AB;atlas&#x6CE8;&#x5165;LoadedApk&#x4E2D;&#xFF0C;&#x66FF;&#x6362;&#x539F;&#x6709;&#x7684;PathClassLoader&#xFF1B;&#x7B2C;&#x4E8C;&#x4E2A;&#x662F;BundleClassLoader&#xFF0C;&#x53C2;&#x8003;OSGI&#x7684;&#x5B9E;&#x73B0;&#xFF0C;&#x6BCF;&#x4E2A;bundle resolve&#x65F6;&#x4F1A;&#x5206;&#x914D;&#x4E00;&#x4E2A;BundleClassLoader&#xFF0C;&#x8D1F;&#x8D23;&#x8BE5;bundle&#x7684;&#x7C7B;&#x52A0;&#x8F7D;&#x3002;&#x5173;&#x7CFB;&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;&#xFF1A;\n<strong>DelegateClassLoader&#x4EE5;PathClassLoader&#x4E3A;parent&#xFF0C;&#x540C;&#x65F6;&#x5728;&#x8DEF;&#x7531;&#x8FC7;&#x7A0B;&#x4E2D;&#x80FD;&#x591F;&#x627E;&#x5230;&#x6240;&#x6709;bundle&#x7684;classloader&#xFF1B;</strong></p>\n<p><strong>BundleClassLoader&#x4EE5;BootClassLoader&#x4E3A;parent&#xFF0C;&#x540C;&#x65F6;&#x5F15;&#x7528;PathClassLoader,BundleClassLoader&#x81EA;&#x8EAB;findClass&#x7684;&#x987A;&#x5E8F;&#x4E3A;</strong></p>\n<p>  <strong>1. findOwn&#xFF1A; &#x67E5;&#x627E;bundle dex &#x81EA;&#x8EAB;&#x5185;&#x90E8;&#x7684;class</strong></p>\n<p>  <strong>2. findDependency: &#x67E5;&#x627E;bundle&#x4F9D;&#x8D56;&#x7684;bundle&#x5185;&#x7684;class</strong></p>\n<p>  <strong>3. findPath&#xFF1A; &#x67E5;&#x627E;&#x4E3B;apk&#x4E2D;&#x7684;class</strong></p>\n<p>&gt;\n<img src=\"Project_architectured_img/classloader.png\" alt=\"MacDown Screenshot\"></p>\n<h4 id=\"&#x8303;&#x4F8B;\">&#x8303;&#x4F8B;</h4>\n<p>&#x4E0B;&#x56FE;&#x662F;&#x5BB9;&#x5668;&#x4E2D;&#x7C7B;&#x52A0;&#x8F7D;&#x7684;&#x5927;&#x81F4;&#x987A;&#x5E8F;&#xFF1B;\n&#x53EF;&#x4EE5;&#x8BA4;&#x4E3A;&#x662F;&#x4E00;&#x4E2A;Bundle&#x7684;Activity&#x542F;&#x52A8;&#x7684;&#x7C7B;&#x52A0;&#x8F7D;&#x8FC7;&#x7A0B;&#x6765;&#x5E2E;&#x52A9;&#x7406;&#x89E3;&#xFF08;&#x5047;&#x8BBE;Activity&#x6240;&#x5728;&#x7684;bundle&#x5DF2;&#x7ECF;&#x5B89;&#x88C5;&#xFF09;&#xFF1B;</p>\n<ol>\n<li>ActivityThread&#x4ECE;LoadedApk&#x4E2D;&#x83B7;&#x53D6;classloader&#x53BB;load Activity Class&#xFF1B;</li>\n<li>&#x6839;&#x636E;&#x4E0A;&#x9762;&#x7684;classloader&#x5173;&#x7CFB;&#xFF0C;&#x5148;&#x53BB;parent&#x91CC;&#x9762;&#x52A0;&#x8F7D;class&#xFF1B;</li>\n<li>&#x7531;&#x4E8E;class&#x5728;bundle&#x91CC;&#x9762;&#xFF0C;&#x6240;&#x4EE5;pathclassloader&#x5185;&#x67E5;&#x627E;&#x5931;&#x8D25;&#xFF0C;&#x63A5;&#x7740;delegateclassloader&#x6839;&#x636E;bundleinfo&#x4FE1;&#x606F;&#x67E5;&#x627E;&#x5230;classloader&#x5728;bundle&#x4E2D;&#xFF08;&#x5047;&#x8BBE;&#x4E3A;bundleA&#xFF09;&#xFF1B;</li>\n<li>&#x4ECE;bundleA&#x4E2D;&#x52A0;&#x8F7D;class&#xFF0C;&#x5E76;&#x4E14;&#x521B;&#x5EFA;class&#xFF1B;</li>\n<li>&#x540E;&#x9762;&#x5728;Activity&#x8D77;&#x6765;&#x540E;&#xFF0C;&#x5982;&#x679C;bundleA&#x5BF9;bundleB&#x6709;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#xFF0C;&#x90A3;&#x4E48;&#x5982;&#x679C;&#x7528;&#x5230;&#x4E86;bundleB&#x7684;class&#xFF0C;&#x53C8;&#x4F1A;&#x6839;&#x636E;bundlA&#x7684;bundleClassloader&#x7684;dependency&#x53BB;&#x83B7;&#x53D6;bundleB&#x7684;classloader&#x53BB;&#x52A0;&#x8F7D;&#xFF1B;\n<img src=\"Project_architectured_img/class_find.png\" alt=\"MacDown Screenshot\"></li>\n</ol>\n<h2 id=\"&#x8D44;&#x6E90;&#x52A0;&#x8F7D;&#x673A;&#x5236;\">&#x8D44;&#x6E90;&#x52A0;&#x8F7D;&#x673A;&#x5236;</h2>\n<p>&gt;\n<img src=\"Project_architectured_img/resources.png\" alt=\"MacDown Screenshot\"></p>\n<p>&#x7C7B;&#x4F3C;ClassLoader&#xFF0C;LoadedApk&#x4E2D;&#x7684;Resources&#x88AB;&#x66FF;&#x6362;&#x6210;Atlas&#x5185;&#x90E8;&#x7684;DelegateResources,&#x540C;&#x65F6;&#x5728;&#x6BCF;&#x4E2A;Bundle&#x5B89;&#x88C5;&#x7684;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x6BCF;&#x4E2A;bundle&#x7684;assetspath&#x4F1A;&#x88AB;&#x66F4;&#x65B0;&#x5230;DelegateResources&#x7684;AssetsManager&#x4E2D;&#xFF1B;&#x6BCF;&#x4E2A;bundle&#x7684;&#x8D44;&#x6E90;&#x7279;&#x5F81;&#x5982;&#x56FE;&#x53EF;&#x77E5;&#xFF1A;</p>\n<ol>\n<li>bundle&#x6784;&#x5EFA;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x6BCF;&#x4E2A;bundle&#x4F1A;&#x88AB;&#x72EC;&#x7ACB;&#x8FDB;&#x884C;&#x5206;&#x533A;&#xFF0C;packageId&#x4FDD;&#x8BC1;&#x5168;&#x5C40;&#x552F;&#x4E00;&#xFF0C;packageID&#x5728;host&#x7684;&#x6784;&#x5EFA;&#x5DE5;&#x7A0B;&#x5185;&#x4F1A;&#x6709;&#x4E2A;<strong>packageIdFile.properties</strong>&#x8FDB;&#x884C;&#x7EDF;&#x4E00;&#x5206;&#x914D;&#xFF1B;</li>\n<li>&#x867D;&#x7136;&#x6BCF;&#x4E2A;bundle&#x7684;manifest&#x90FD;&#x58F0;&#x660E;&#x4E86;&#x81EA;&#x5DF1;&#x7684;packagename&#xFF0C;&#x4F46;&#x662F;&#x5728;aapt&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;arsc&#x6587;&#x4EF6;&#x91CC;&#x9762;&#x6240;&#x6709;bundle&#x7684;packagename&#x5747;&#x88AB;&#x7EDF;&#x4E00;&#x4E3A;hostApk&#x7684;package&#xFF0C;&#x6BD4;&#x5982;&#x5728;&#x624B;&#x6DD8;&#x5185;&#x5C31;&#x90FD;&#x662F;com.taobao.taobao&#xFF1B;&#x8FD9;&#x6837;&#x6539;&#x7684;&#x76EE;&#x7684;&#x662F;&#x4E3A;&#x4E86;&#x89E3;&#x51B3;&#x5728;&#x8D44;&#x6E90;&#x67E5;&#x627E;&#x4E2D;&#x4E00;&#x4E9B;&#x517C;&#x5BB9;&#x6027;&#x95EE;&#x9898;&#xFF1B; </li>\n</ol>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                \n                <a href=\"Project_architectured.html\" class=\"navigation navigation-next navigation-unique\" aria-label=\"Next page: 名词解释\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"框架原理\",\"level\":\"1.2.1\",\"depth\":2,\"next\":{\"title\":\"名词解释\",\"level\":\"1.2.2\",\"depth\":2,\"path\":\"principle-intro/Project_architectured.md\",\"ref\":\"principle-intro/Project_architectured.md\",\"articles\":[]},\"previous\":{\"title\":\"原理解析\",\"level\":\"1.2\",\"depth\":1,\"ref\":\"\",\"articles\":[{\"title\":\"框架原理\",\"level\":\"1.2.1\",\"depth\":2,\"path\":\"principle-intro/Runtime_principle.md\",\"ref\":\"principle-intro/Runtime_principle.md\",\"articles\":[]},{\"title\":\"名词解释\",\"level\":\"1.2.2\",\"depth\":2,\"path\":\"principle-intro/Project_architectured.md\",\"ref\":\"principle-intro/Project_architectured.md\",\"articles\":[]},{\"title\":\"APK结构\",\"level\":\"1.2.3\",\"depth\":2,\"path\":\"principle-intro/Apk_architecture.md\",\"ref\":\"principle-intro/Apk_architecture.md\",\"articles\":[]},{\"title\":\"运行期文件结构\",\"level\":\"1.2.4\",\"depth\":2,\"path\":\"principle-intro/File_architecture_runtime.md\",\"ref\":\"principle-intro/File_architecture_runtime.md\",\"articles\":[]}]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"principle-intro/Runtime_principle.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/search_index.json",
    "content": "{\"index\":{\"version\":\"0.5.12\",\"fields\":[{\"name\":\"title\",\"boost\":10},{\"name\":\"keywords\",\"boost\":15},{\"name\":\"body\",\"boost\":1}],\"ref\":\"url\",\"documentStore\":{\"store\":{\"./\":[\"\\\"com.taobao.android:atlasplugin:2.3.3.beta2\\\"\",\"'com.taobao.android:atlasupdate:1.0.8@aar'\",\"'com.taobao.atlas.application'\",\"'com.taobao.atlas.library'\",\"//...\",\"//声明为awb\",\"//如果不需要用到atlas的动态部署功能，不需要依赖atlasupd\",\"//核心sdk\",\"//设置bundle依赖\",\"2.2\",\"2.3\",\"3.0\",\"4.0\",\"4.4\",\"5.0\",\"5.1\",\"7.0.\",\"=\",\"android\",\"appli\",\"art\",\"atla\",\"atlasen\",\"atlas对app的划分如下图所示:\",\"atlas提供哪些功能\",\"atlas是伴随着手机淘宝的不断发展而衍生出来的一个运行于android系统上的一个容器化框架，我们也叫动态组件化(dynam\",\"awbbundl\",\"brows\",\"buildscript\",\"bundl\",\"bundle)框架。它主要提供了解耦化、组件化、动态性的支持。覆盖了工程师的工程编码期、apk运行期以及后续运维期的各种问题。\",\"bundlecompil\",\"bundleconfig\",\"bundle可以直接使用host中的代码和资源\",\"bundle按需加载\",\"bundle接入，修改bundle的gradle，参见demo中的firstbundle配置\",\"classpath\",\"com.taobao.atla\",\"com.taobao.atlas.librari\",\"compil\",\"compile('com.taobao.android:atlas_core:5.0.0@aar')\",\"dalvik\",\"demo\",\"depend\",\"dexpatch\",\"english\",\"faq\",\"gradle：用于配置主apk的依赖及控制构建参数\",\"host\",\"introduct\",\"jcenter()}\",\"m\",\"manifest：文件用于单独管理apk的icon，版本号，versioncode等；\",\"n\",\"plugin\",\"plugin:\",\"project(':firstbundle')\",\"repositori\",\"runtim\",\"support\",\"test\",\"transit\",\"true\",\"version\",\"ye\",\"{\",\"}\",\"上线后的运维期，atlas提供了一整套完整的支持\",\"与插件化框架不同的是，atlas是一个组件框架，atlas不是一个多进程的框架，他主要完成的就是在运行环境中按需地去完成各个bundle的安装，加载类和资源。\",\"业务可以灵活发布自己的需求\",\"业务层基本单位\",\"业务需要时，才会去加载对应bundle中的代码和资源\",\"为了降低用户等待时间，atlas框架在dalivk系统上首次使用bundle时关闭了verify，在art系统上首次使用时关闭了dex2oat走解释执行。同时后台通过异步任务走原生的dexopt过程，为下次使用做好准备\",\"为例\",\"从app的开发期\",\"以\",\"以一个app的开发的生命周期为例，参见\",\"以动态部署技术方案为基础，可以看作是动态部署的子集，专注于单个bundle的故障修复。由于做的事小而精，所以编译构建速度、线上生效速度都是远远快于动态部署\",\"共享代码资源\",\"其它\",\"减少包体积。不常用的bundle放在云端，需要时按需下载。当用户设备空间紧张时,可以清理掉一些长期不用的组件\",\"功能\",\"动态部署\",\"包含独立的中间件，以及一个base的工程，里面可能包含应用的application，应用icon等基础性内容\",\"即bundle工程\",\"同时动态部署的快速覆盖能力在灰度等场景下可以更快地收到所需的效果。\",\"周期\",\"四大组件支持\",\"基础支持\",\"增量更新修复能力，提供对class、so以及资源的增量更新修复能力，快速升级\",\"如何接入\",\"定位\",\"实现host、bundle独立开发、调试的功能，bundle独立\",\"实现完整的组件生命周期的映射，类隔离、资源共享等机制\",\"容器接入，修改app模块的gradle文件\",\"对应bundle工程，用于将module转化成atlas所需要的bundle依赖，不会侵入正常的开发环境\",\"工程期\",\"开发期\",\"引用atlas插件及依赖仓库，修改工程gradle文件\",\"我们比较倾向于用一个比较干净的壳子工程来作为容器架构下的打包工程,称之为main_builder，main_builder建议只存在androidmanifest.xml、构建文件及部分资源内容。\",\"手淘组件化框架的前世今生和未来的路\",\"扫码加入atlas钉钉交流群\",\"拆分\",\"接入文档，\",\"提供gradle插件，简化开发者接入的负担。\",\"支持版本\",\"支持运行bundle中的四大组件\",\"文档\",\"是容器一个最重要的功能。基于此:\",\"有故障的业务可以及时修复或者回滚\",\"构建时会与之前版本的dex进行字节码级别的diff，生成tpatch包。最终下发到用户手机的patch仅包含变化class组成的dex和更改或者新增的资源文件\",\"用于host工程，用于设置对bundle的依赖和其它atlas的功能\",\"简介\",\"至此，接入完成，不需要接入方调用任何初始化函数，详细的文档参\",\"解释执行\",\"说明\",\"运维期\",\"运行期\",\"运行期按需动态加载。bundle可以调用host的代码和资源，同时bundle之间允许存在依赖关系。\",\"远程bundl\",\"需要说明的是，gradle插件不会侵入正常的开发流程，host和bundle都可以独立的进行开发和调试。\"],\"principle-intro/Runtime_principle.html\":[\"1.\",\"2.\",\"3.\",\">\",\"activ\",\"activitythread从loadedapk中获取classloader去load\",\"application的oncreate方法被调用\",\"atlas里面通常会创建了两种classloader,第一个是delegateclassloader，他作为类查找的一个路由器而存在，本身并不负责真正类的加载；delegateclassloader启动时被atlas注入loadedapk中，替换原有的pathclassloader；第二个是bundleclassloader，参考osgi的实现，每个bundl\",\"bundl\",\"bundleclassloader以bootclassloader为parent，同时引用pathclassloader,bundleclassloader自身findclass的顺序为\",\"bundle开始运行，bundl\",\"bundle构建过程中，每个bundle会被独立进行分区，packageid保证全局唯一，packageid在host的构建工程内会有个packageidfile.properties进行统一分配；\",\"bundle生命周期\",\"bundle的安全校验通过；bundle的dex检测已经成功dexopt(or\",\"bundle被安装到storage目录\",\"bundle，start\",\"bundle，以及获取全局的application等各种功能。\",\"classloader被创建，assetpatch注入delegateresoucc\",\"class；\",\"delegateclassloader以pathclassloader为parent，同时在路由过程中能够找到所有bundle的classloader；\",\"dex\",\"dex2oat)，resource已经成功注入\",\"finddependency:\",\"findown：\",\"findpath：\",\"framework\",\"instal\",\"resolv\",\"resolve时会分配一个bundleclassloader，负责该bundle的类加载。关系如下图所示：\",\"resolve机制导致部分class没成功，替换以后该问题得到最好的解决，除atlas本身以外，所有业务代码均可以动态部署；\",\"runtime层：主要包括清单管理、版本管理、以及系统代理三大块，基于不同的触发点按需执行bundle的安装和加载；runtime层同时提供了开发期快速debug支持和监控两个功能模块。从delegate层可以看到，最核心的两个代理点：一个是delegateclassloader：负责路由class加载到各个bundle内部，第二个是delegateresource：负责资源查找时能够找到bundle内的资源；这是bundle能够真正运行起来的根本；其余的代理点均是为了保证在必要的时机按需加载起来目标bundle，让其可以被delegateclassloader和delegateresource使用\",\"start\",\"下图是容器中类加载的大致顺序；\",\"从bundlea中加载class，并且创建class；\",\"包括了容器所需的所有系统层面的注入和hack的工具类初始化和校验，容器启动时先校验设备是否支持容器运行，不支持则采取降级并记录原因；\",\"另外内置的原生的multidex在dalvik上面性能并不好，atlas内部对其进行了优化提高了在dalvik上面的体验。\",\"可以认为是一个bundle的activity启动的类加载过程来帮助理解（假设activity所在的bundle已经安装）；\",\"后面在activity起来后，如果bundlea对bundleb有依赖关系，那么如果用到了bundleb的class，又会根据bundla的bundleclassloader的dependency去获取bundleb的classloader去加载；\",\"如上图所示，atlas主要分为以下几个层级：\",\"如果不替换application，那么atlas的初始化就会在application里面，由于基于atlas的动态部署实际上是类替换的机制，那么这种机制就会必然存在包括application及其import的class等部分代码在dalvik不支持部署的情况，这个在使用过程中造成一定成本，需要小心的使用以避免dalivk内部class\",\"容器框架\",\"对外接入层:atlasbridgeapplication是atlas框架下apk的真正application，在基于atlas框架构建的过程中会替换原有manifest中的application，所以atlas没入的接入并不存在任何初始化代码，构建脚本完成了接入的过程。atlasbridgeapplication里面除了完成了atlas的初始化功能，同时内置了multidex的功能，这样做的原因有两个：\",\"很多大型的app不合理的初始化导致用multidex分包逻辑拆分的时候主dex的代码就有可能方法数超过65536，\\u0002atlasbridgeapplication与业务代码完全解耦，所以拆分上面只要保证atlas框架在主dex，其他代码无论怎么拆分都不会有问题；\",\"操作以及管理整个bundle的生命周期；\",\"更新\",\"最底下的hack工具层：\",\"查找bundl\",\"查找bundle依赖的bundle内的class\",\"查找主apk中的class\",\"根据上面的classloader关系，先去parent里面加载class；\",\"框架原理\",\"每个bundle的生命周期如下图所示：\",\"由于class在bundle里面，所以pathclassloader内查找失败，接着delegateclassloader根据bundleinfo信息查找到classloader在bundle中（假设为bundlea）；\",\"类似classloader，loadedapk中的resources被替换成atlas内部的delegateresources,同时在每个bundle安装的过程中，每个bundle的assetspath会被更新到delegateresources的assetsmanager中；每个bundle的资源特征如图可知：\",\"类加载机制\",\"自身内部的class\",\"范例\",\"虽然每个bundle的manifest都声明了自己的packagename，但是在aapt过程中，arsc文件里面所有bundle的packagename均被统一为hostapk的package，比如在手淘内就都是com.taobao.taobao；这样改的目的是为了解决在资源查找中一些兼容性问题；\",\"负责bundle的安装\",\"资源加载机制\",\"除atlasbridgeapplication之外，接入层对外提供了部分工具类，包括主动instal\"],\"principle-intro/Project_architectured.html\":[\">\",\"android\",\"awb：\",\"bundle:\",\"bundle的缩写，实际上同aar类似，是最终构建整包前的中间产物。每个awb最终会打成一个bundle。awb与aar的唯一不同之处是awb与之对应有个packageid的定义。\",\"bundle：\",\"diff生成的差异文件，在更新时拉取同时静默更新到设备上，在用户下次启动之后生效新代码，具体原理可以参考动态部署章节的解析\",\"host:\",\"host内部包含独立的中间件，以及一个base的工程，里面可能包含应用的application，应用icon等基础性内容（如果足够独立，application也可以直接放在apk_builder内）；\",\"remot\",\"service的方式保证自身封装性；同时某些中间件如果只存在若干bundle使用的也可以封装bundle的方式提供出来，以保证host内容精简\",\"update库及构建插件，可以生成与之前发布的apk\",\"wireless\",\"业务层基本上以bundle为边界自上而下与host发生调用，同时bundle之间允许存在依赖关系；相对业务独立的bundle如果存在接口耦合建议封装成aidl\",\"从上图也可以看出基于atlas构建后大致工程的结构：\",\"动态部署：\",\"名词解释\",\"基于atlas的installorupdate和atla\",\"宿主的概念，所有的bundle可以直接调用host内的代码和资源，所以host常常集合了公共的中间件，ui资源等。host和bundle的依赖关系如下图所示：\",\"类似osgi规范里面bundle（组件）的概念，每个bundle有自己的classloader，与其他bundle相隔离，同时atlas框架下bundle有自身的资源段（packageid，打包时aapt指定）；另外与原有osgi所定义的service格式不同之处是atlas里面bundle透出所有定义在manifest里面的component，随着service，activity的触发执行bundle的安装，运行。\",\"远程bundle，远程bundle只是apk构建时并未打到apk内部，而是单独放在了云端；同时远程bundle的限制条件是第一次被触发的前提是bundle内的activity需要被start，此时基于atlas内的classnotfoundinterceptorcallback可以进行跳转的重定向，提示用户下载具体bundle，待用户确定后进行异步下载同时完成后再跳转到目标bundle（此部分代码由于涉及下载及ui展示等内容并未包含在开源仓库中，有需要可以根据classnotfoundinterceptorcallback自行实现）\",\"首先有个构建整体apk工程apk_builder,里面管理着所有的依赖（包括atlas）及其版本，apk_builder本身可能不包含任何代码，只负责构建使用\"],\"principle-intro/Apk_architecture.html\":[\">\",\"androidmanifest\",\"apk结构\",\"assets/bundleinfo\",\"bundleinfo的信息同时也会在构建后的主manifest里面体现，如线框1、2所示，每个component下面meta\",\"data,同时bundle某些特有的信息会记录在application级别的meta\",\"datal里面记录该component所在的meta\",\"data里面。\",\"verison.json的文件，其中version为manifest中的versinonname，里面记录了每个bundle大小，版本，名字以及里面所有的component信息，这些内容在构建的时候生成，基于这些信息每个bundle可以在component被触发的时候去按需的进行安装，整个过程对开发者透明（从中也可以看到默认情况下bundle对外暴露的只是基于android原生的activity，service，receiver等component）。\",\"version.json\",\"基于atlas构建后的apk结构如下图，host与普通apk无异，但是manifest和assets会添加一些额外的内容，同时在armeabi目录中会增加若干个bundle构建的产物，取名为string.format(lib%s.so,packagename.replace(\\\".\\\",\\\"_\\\"))；packagename为bundle的androidmanifest中的packagename,这些so都是正常的apk结构，改为so放入lib目录只是为了安装时借用系统的能力从apk中解压出来，方便后续安装\",\"构建完的apk在host的assets目录下，会有个bundleinfo\"],\"principle-intro/File_architecture_runtime.html\":[\"/data/data/pkgname/files/baselineinfo\",\"/data/data/pkgname/files/bundlelist\",\"/data/data/pkgname/files/storag\",\">\",\"so等内容。如果bundle发生更新，则可能会有version.2、version.3\",\"storage目录是bundle安装的目录，每个bundle的安装目录以bundle的packagename为文件夹名，首次启动后会安装到version.1目录下，目录中可能含有bundle的zip文件，dex文件以及n\",\"之前打包构建时记录的bundleinfo信息（发生动态部署收文件会进行更新）\",\"存放动态部署后的版本变化内容，以及每次部署发生更新的bundle的版本，依赖等信息\",\"等目录，每次加载bundle的时候选取最高可用版本进行载入。考虑bundle的回滚功能和对空间占用的影响，目前容器内最多保留两个最近可用版本。\",\"运行期文件结构\"],\"guide-for-use/\":[\"demo\",\"接入可参考atla\",\"接入指引\",\"请接入前仔细阅读接入文档.\"],\"guide-for-use/guide_for_build.html\":[\"\\\"com.android.tools.build:gradle\\\"的版本，默认使用的是\",\"\\\"com.taobao.android.atlasdemo:ap\",\"\\\"com.taobao.android:atlasplugin:1.0.1\\\"\",\"#\",\"'com.taobao.android:atlasupdate:1.0.8@aar'\",\"'com.taobao.atlas.application'\",\"(apversion){\",\",\",\"./gradlew\",\"//注意不能同时\",\"//自启动bundle配置\",\"2.1\",\":\",\"=\",\"=['com.taobao.firstbundle']\",\">\",\">a,jsonarrary中每个item的key为该bundle的artificatid,dependency里面的item为被依赖的bundle的packagenam\",\">b\",\"[]\",\"[com.taobao.firstbundle]\",\"aapt输出的r为常量,\",\"andfix\",\"android\",\"android端测容器运行库atlas_core；\",\"apk\",\"apk构建\",\"appli\",\"apversion表示被动态部署应用的基线版本，versionname表示动态部署后新的versionnam\",\"assembledebug\",\"assemblereleas\",\"atla\",\"atlasen\",\"atlasenable字段需要指定为true才能开启打包阶段的基于容器扩展的task\",\"atlas基础初始化及multidex逻辑\",\"atlas开源的代码内容主要包括以下几个模块：\",\"autostartbundl\",\"baseapdepend\",\"boolean\",\"build.gradl\",\"build.gradle(atlasgradleplugin)\",\"build/outputs/apk/xx.ap\",\"build/outputs/apk/xx.apk\",\"build/outputs/atlasconfig.json\",\"build/outputs/dependencytre\",\"build/outputs/tpatch\",\"builder\",\"buildscript\",\"buildtyp\",\"bundlebaseinfofil\",\"bundlebaseinfofile.json\",\"bundlebaseinfofile.json:\",\"class\",\"class.method(context)\",\"classname2:methodname2\",\"classname:methodnam\",\"classpath\",\"clean\",\"com.android.appl\",\"com.taobao.android:taobao\",\"compil\",\"compile('com.taobao.android:atlas_core:5.0.0@aar')\",\"createtpatch\",\"dapversion=1.0.0\",\"debug\",\"debug.json\",\"debug:${apversion}@ap\\\"\",\"demo/app/build.gradl\",\"depend\",\"dversionname=1.0.1\",\"fals\",\"file\",\"googl\",\"jar中的资源文件\",\"jcenter()\",\"list\",\"mavenlocal()\",\"mtl.atlasen\",\"mtl.buildtypes.debug.baseapdepend\",\"mtl.buildtypes.release.baseapdepend\",\"mtl.manifestoptions.replaceappl\",\"mtl.patchconfigs.debug.createapatch\",\"mtl.patchconfigs.debug.createtpatch\",\"mtl.patchconfigs.debug.filterclass\",\"mtl.patchconfigs.debug.filterfil\",\"mtl.patchconfigs.release.createapatch\",\"mtl.patchconfigs.release.createtpatch\",\"mtl.patchconfigs.release.filterclass\",\"mtl.patchconfigs.release.filterfil\",\"mtl.tbuildconfig.aaptconstantid\",\"mtl.tbuildconfig.autopackageid\",\"mtl.tbuildconfig.autostartbundl\",\"mtl.tbuildconfig.createap\",\"mtl.tbuildconfig.mergeawbjavar\",\"mtl.tbuildconfig.mergejavar\",\"mtl.tbuildconfig.prelaunch\",\"mtl.tbuildconfig.preprocessmanifest\",\"mtl.tbuildconfig.usecustomaapt\",\"null\",\"packageidfile.properti\",\"packageidfile.properties:\",\"packagenam\",\"patch\",\"patchconfig\",\"patchconfigs.debug\",\"patchconfigs{\",\"patch产物\",\"plugin:\",\"releas\",\"release:6.3.0\",\"repositori\",\"set\",\"snapshot@ap\",\"string\",\"tbuildconfig\",\"tpatch构建\",\"transit\",\"true\",\"{\",\"}\",\"下面会逐个说明每个文件的使用和注意要点\",\"主工程容器接入\",\"书写的格式为：groupid:artificatid=xx（如下图）\",\"使用atlas的application，包含\",\"使用自定义的aapt，\",\"值\",\"值是\",\"具体参考\",\"列表文件\",\"功能\",\"包\",\"可以减少动态部署的patch包大小\",\"合并bundl\",\"合并jar中的资源文件\",\"后续两个设置用语动态部署打包时的开关设置，其余字段参考配置列表中的使用方式\",\"和其他的打包中间配置\",\"基于\",\"基于gradle的构建插件（包括修改过的aapt内容）；\",\"基于容器提供更新能力的库atlas_update;\",\"基线的依赖坐标，\",\"如果不需要用到atlas的动态部署功能，不需要依赖atlasupd\",\"如果开启atlas，必须为tru\",\"如：\",\"官方的\",\"容器接入\",\"工程打包的gradl\",\"应用plugin\",\"建议值设置为false，\",\"开启atlas容器功能\",\"引用插件及依赖仓库\",\"我们比较倾向于用一个比较干净的壳子工程来作为容器架构下的打包工程，这个工程建议只存在androidmanifest.xml和构建的文件及部分资源内容，manifest文件用于单独管理apk的icon，版本号，versioncode等；构建文件管理版本依赖；这里我们取名打包工程等名字为apk_builder;\",\"或者\",\"打andfix\",\"打动态部署\",\"打包过滤\",\"提前执行的方法，格式是\",\"插件，\",\"支持\",\"整个工程的依赖树\",\"整个打包的\",\"是一个json格式的文件，里面记录bundle的信息以及依赖关系，dependency字段用于标识该bundle所依赖的bundle，如果a依赖b，b依赖c，则触发的abundle安装时，实际的安装顺序为c\",\"是否启用atla\",\"最简配置\",\"构建\",\"构建产物：\",\"构建基线包，建议开启，否则后面的patch包无法进行\",\"构建的产物apk\",\"构建的基线包，\",\"每个bundle在生成的时候，需要为其分配独立的packageid，用以使其保证每个bundle的资源id全局唯一；资源id的可分配区间为[0x21,0x7f),0x1x为系统保留，0x7f为主apk使用，0x20之前的发现miui里面内部已使用，所以目前我没选择这个区间作为bundle的packageid分配区间\",\"注意class和methodname都不能混淆，且方法实现是\",\"注意尽量不要指定\",\"添加运行库依赖\",\"用于配置主apk的依赖及控制构建参数\",\"类型\",\"自动生成bundle的packageid\",\"自启动的bundle列表，\",\"通常情况下apk_builder除了主apk的androidmanifest.xml之外，接入atlas后，main_builder将会包含以下内容：\",\"配置\",\"配置bundle的packageid,以保证资源段独立（也可以通过mtl.tbuildconfig.autopackageid设置自动分配packageid）\",\"配置bundle的依赖关系\",\"配置列表\",\"配置参数\",\"配置名称\",\"里面包含\",\"除了依赖树和配置参数之外，额外的产物有：\",\"预处理manifest，\",\"（2.0.0~2.1.0）\",\"，\"],\"guide-for-use/guide_for_bundle.html\":[\"\\\"com.android.tools.build:gradle:2.1\\\"\",\"\\\"com.taobao.android:atlasplugin:1.0.0\\\"\",\"'com.taobao.atlas.library'\",\"(bundleexcept\",\"(bundleimpl)\",\"//使用com.taobao.atlas.library时需要配置atlasplugin等classpath\",\"=\",\"@overrid\",\"```\",\"activity通过overridependingtransition使用的切换动画的文件要放在主apk中；\",\"android:multiprocess=\\\"true\\\"\",\"android:process=\\\":xx\\\"\",\"appli\",\"applic\",\"application的mbase实际上就是apk真正的application，最好不要直接传入bundle的application本身进行初始化，会存在潜在的风险。\",\"atlas.bundleconfig.awbbundl\",\"atlas.getinstance().getbundle(\\\"com.sample.bundlea\\\");\",\"atlas.getinstance().installbundletransitivelyasync(\",\"buildscript\",\"bundleimpl\",\"bundleinstaller.installlistener()\",\"bundle内如果有用到自定义style,那么style的parent如果也是自定义的话，parent的定义必须位于主apk中，这是由于5.0以后系统内style查找的固有逻辑导致的，容器内暂不能完全兼容\",\"bundle内有使用主进程的contentprovider,则bundle的androidmanifest的contentprovider声明中最好带上\",\"bundle内的class最好以特定的packagename开头，resource文件能够带有特定的前缀。这样一来可以避免资源或者类名重复而引起的覆盖，也可以在出现问题的时候及时定位到出问题的模块\",\"bundle内部如果有so，则安装时so由于无法解压到apk\",\"bundle可以被认为是一个小型的apk，因此每个bundle的初始化都是从bundle的application开始的。application被声明在bundle的androidmanifest.xml里面\",\"bundle如何提供服务给其他bundl\",\"bundle拆分|新建\",\"bundle时的线程，这样导致了bundle可能会运行在主线程，也可能是在子线程，所以初始化的代码如果对线程敏感的需要注意：如果需要强制主线程的可以通过new\",\"bundle的androidmanifest中不能有对bundle内的资源的引用；比如activity的theme，需要声明在主apk中。bundle的manifest会合并进主manifest，如果有bundle的资源引用会直接引发构建出错；另外可以选择的方式是androidmanifest里面不加theme，改用在activity的oncreate方法里面调用settheme的方式\",\"bundle的application并不是被系统真正认可的application，所以需要application作为参数进行初始化的方法可以传入getbasecontext()，bundl\",\"bundle的工程配置\",\"bundle的注意点\",\"bundle自身工程build.gradle里面需要声明为awb:\",\"bundle虽然提供了依赖的方式，但是这种方式如果使用不当反而会带来隐患，且与bundle本身的封装性相违背。通常如果某个中间件是以bundle的形式存在，那声明依赖是可行的。如果两个本身相对独立的业务bundle存在某几个功能接口的依赖，则可以通过服务的方式，服务提供方提供aidl的接口，被使用方或者主apk依赖；同时自己bundle内部实现service的功能。\",\"catch\",\"classpath\",\"com.taobao.android:firstbundle=34//groupid:artifactid=num\",\"compile(\\\"com.taobao.android:firstbundle:1.0.0@awb\\\")\",\"depend\",\"e)\",\"e.printstacktrace();\",\"handler(looper.getmainlooper()).post\",\"if(impl!=null){\",\"impl\",\"impl.start();\",\"jcenter()\",\"lib目录中，对于直接通过native层使用dlopen来使用so的情况，会存在一定限制，且会影响后续so动态部署，所以目前bundle内so不建议使用dlopen的方式来使用\",\"mavenlocal()\",\"new\",\"onfinished()\",\"plugin:\",\"public\",\"repositori\",\"string[]{\\\"com.sample.bundlea\\\"},\",\"tri\",\"true\",\"void\",\"{\",\"}\",\"});\",\"主动启动bundl\",\"初始化bundl\",\"初始化的线程基于start\",\"加上bundle的packagename为：com.sample.bundlea\",\"去初始化\",\"在主客工程的build.gradle中添加awb依赖\",\"在主客工程的packageid.properties中声明资源段（也可以通过mtl.tbuildconfig.autopackageid设置自动分配packageid）\",\"外部配置\",\"如何正确使用bundl\",\"建议修改plugin，更好的支持aar传递依赖等问题（可以采用原生com.android.library）\",\"注意点：虽然启动方式类似与普通app，先执行attachbasecontext，再执行oncreate，不过有两个不同点需要引起注意：\",\"这样可以避免主进程一起来就去startbundle导致启动时间过长\",\"遵循代码规范可以有效避免在运行时遇到难以排查的问题。\",\"默认情况下，bundle只往外暴露了android原生的component,运行期按需加载。某些特殊的bundle（比如说监控性质的）本身与其他代码完全独立，且又需要在某个时间点启动运行的，可以通过如下方式去启动：\"],\"guide-for-use/guide_for_compile.html\":[\"awo编译\",\"待更新\"],\"guide-for-use/bundleCommunicate.html\":[\"![](fragment\",\"*\",\"*/\",\"/**\",\"//\",\"//unknow\",\"//方法仅供示例，与实际情况可能存在差异\",\"2.\",\"3.\",\"7.0以后classloader通过namespace各自独立，不同的classloader可以去load同一个so，分别会在各自的namespace有各自的mmap，可以通过/proc/pid/map\",\"7.0版本之前nativ\",\"=\",\"==\",\"@overrid\",\"@param\",\"@throw\",\"```\",\"activity,\",\"activity{\",\"aidl、servicehub解决了部分bundle之间通信或者代码复用的问题。但是这两者也存在着很大的不足。一方面aidl限制了只能传递parcel以及简单对象，对于ui复用比如说richview的重用则完全行不通，同时使用成本也是servicehub的机制的一个痛点，业务方需要提前将新的接口提前注册到servicehub。\",\"androidmanifest修改，remoteview的key以atlas.view.intent.action.开头\",\"android跨classloader的模块之间互相通信的几种方式\",\"args)\",\"args,\",\"atlas作为java层以osgi规范进行组件化解耦的容器。在一定层度上清晰了各个模块之间的边界，便于各个业务以内聚的方式不断的演化更新。\",\"a有若干个native方法，需要提供给js使用，则可以写成\",\"b\",\"b.putstring(\\\"js_method\\\",jsmethodname);\",\"bundl\",\"bundle();\",\"bundleexcept\",\"bundleexception{\",\"bundle内的so，则需要传入so的全路径（比如说通过java层获取），否则可能出现so\",\"bundle的androidmanifest.xml中进行注册\",\"call(str\",\"callback)\",\"class\",\"commandname,\",\"container){\",\"container.addview(remoteview,params);\",\"data的name做key进行查找，remotefragment的key必须以**atlas.fragment.intent.action.**开头。\",\"dependencybundl\",\"dependencybundle,boolean\",\"dologin(){\",\"downgrad\",\"embeddactivity才是真正目标fragment实例化所需要的context，embeddactivity是由remotefragment初始化时创建的activity，用于给目标fragment初始化ui，它是真正的activity，但是没有界面，同时也没有有效的windowmanager，涉及到window操作的会自动转交给sampleactivity进行处理。embeddactivity是bundle之间不需要依赖直接使用ui最根本的保证。\",\"error\",\"errorinfo)\",\"execute(act\",\"extend\",\"final\",\"fragment\",\"fragment)\",\"fragmentactivity{\",\"framelayout\",\"framelayout.layoutparams(viewgroup.layoutparams.wrap_content,viewgroup.layoutparams.wrap_content);\",\"funaplugin();\",\"funbplugin();\",\"get(iremot\",\"getremoteinterface(class\",\"getsupportfragmentmanager().begintransaction().add(r.id.container,fragment).commit();\",\"h5\",\"hosttransactor\",\"if(args.getstring(\\\"js_method\\\").equals(\\\"funa\\\")){\",\"if(args.getstring(\\\"js_method\\\").equals(funb)){\",\"if(interfaceclass\",\"if(plugin!=null){\",\"implement\",\"inc.com/zeduo.szd/savedlopen/tree/mast\",\"inflateremoteview(framelayout\",\"intent\",\"intent(\\\"atlas.fragment.intent.action.login\\\");\",\"intent(\\\"atlas.view.intent.action.sample_rich\\\");\",\"intent(jsmethodname),new\",\"interfaceclass,bundl\",\"iremote{\",\"irespons\",\"jsmethodname){\",\"librari\",\"library之前java层会先findlibrary，如果是系统库，则在系统环境变量里面包含的路径内，如果是外部引入的，则通过classloader.findlibrary进行查找，bundleclassloader的查找逻辑是先找自身bundle安装目录下的，找不到接着找依赖bundle内的，最后去找主dex也就是patchclassloader的findlibrary去查找。\",\"load同一个进程空间下只可load一次，如果同一个classloder第二次去load则直接返回成功，如果不同的classloader去load则会失败；android\",\"load时与load该so的类所在的classloader存在绑定关系，如果存在native反调java层代码的情况，则只能调用到够找到该classloader可以找到的java类的方法\",\"login\",\"loginfrag\",\"loginint\",\"myjspluginmanag\",\"nativ\",\"native方法有一个externaljsmethodexecuter，当需要执行非内部的js方法时，则可以通过externaljsmethodexecuter.execute()查找外部的method。（这种也适用于weex等sdk在非常规的apk内由外部实现定制的适配器）\",\"native特殊使用情况及建议\",\"new\",\"null;\",\"onfailed(str\",\"onremoteprepared(remotefrag\",\"onremoteprepared(remotetransactor\",\"onremoteprepared(remoteview\",\"param\",\"plugin\",\"plugin.execute(jsmethodname,...);\",\"public\",\"redirect\",\"registerhosttransactor(iremot\",\"relation.png)\",\"remote)\",\"remote.getremoteinterface(wvapiplugin.class,b);\",\"remotefactory.onremotestatelistener()\",\"remotefactory.requestremote(remotefragment.class,loginintent,\",\"remotefactory.requestremote(remotetransactor.class,activity,new\",\"remotefactory.requestremote(remoteview.class,\",\"remotefrag\",\"remotefragment本身也是真正意义上的fragment，所以可以用来直接被fragmentmanager或者fragmenttransaction直接进行管理；同时它也是真正的loginfragment的在使用方的代理。他们之间的关系如下：\",\"remotefragment的使用方拿到的仅仅是目标fragment的代理，所以真正的实现对使用方来说是不可见的。如果除了拿到fragment展示之外还有其他的接口需要暴露给使用者，则需要走remote的通信机制。\",\"remotefragment适用于某个bundle中有公共的fragment要提供给一个或者多个其他业务bundle使用的情况，比如说在手淘里面，skufragment(sku选择界面)可能会提供给详情，购物车，聚划算等多个业务使用；或者在某些app里面，登录界面也以loginfragment的方式提供给bundle按需使用。\",\"remoteitem)\",\"remotetransact\",\"remotetransact相当于是remoteview或者remotefragment的简化版，仅仅为了bundle和bundle之间的通信而存在，它和remoteview，remotefragment都实现了iremotetransact接口。可以通过下面的草图了解大致的关系：\",\"remoteview\",\"remoteview)\",\"remoteview与remotefragment实现基本一致，需要embeddedactivity作为真正view膨化的基本条件，remoteview本身只是一个framelayout，就像decorview，目标view作为子view添加在里面。当然这个机制也有一定的隐患，使用方不要通过findviewbyid或者getchildat等viewgroup的publ\",\"remote机制本身强烈依托于组件化拆分的方案。它的解耦层度介于aidl和直接依赖之间。相比aidl灵活层度更高。不过代理的方式并不能完全杜绝通过非常规方法来获取远端目标对象来进行使用，另外也可能存在某些边缘方法无非被完全代理的情况，这也需要在以后的迭代中进行优化，对于非atlas容器化但是使用了组件化拆解方案的app，这种思路也是同样适用的。\",\"remote机制的特点和不足\",\"remote组件参照aidl的方式在manifest中进行注册。查找时以meta\",\"requestruntimedependency(classload\",\"resourcedependencyne\",\"resourcedependencyneed)\",\"return\",\"sampleact\",\"samplerichview\",\"sintent\",\"sintent,\",\"sourc\",\"source,str\",\"so依赖或者dlopen公共n\",\"so的导出函数进行使用,规避因为namespace不一致导致多份mmap的情况。具体参考：http://gitlab.alibaba\",\"so的情况：\",\"so的相互调用导致的bundle依赖\",\"static\",\"string\",\"t\",\"throw\",\"transactor);\",\"viewgroup.layoutparam\",\"void\",\"wvapiplugin\",\"wvapiplugin.class){\",\"{\",\"}\",\"});\",\"}els\",\"}else{\",\"与remotefrag\",\"业务使用方调用atlas的remotefactory的接口进行request，由于期间可能涉及到bundle的安装，所以整个过程采用callback的方式。获取到remotefragment的句柄后直接进行操作即可。**建议fragment里面涉及到的交互功能等的代码封装在fragment内部**，比如说loginfragment里面所有按钮的点击以及异常处理全都fragment内部进行实现。这样的话两个bundle之间的边界也更清晰。\",\"代码改动\",\"代码改动：以loginfragment为例，loginbundle需要在自己的loginfragment做一定的改动\",\"以remotetransactor为例，他和目标transactor类都实现了iremotetransactor，所以当使用方调用iremotetransactor的接口时候，remote对象将方法路由到目标对象的方法上。\",\"以windvane为例（sample里面windvane的接口只做范例，与真实的使用接口可能存在差异）：存在很多bundle需要提供jsplugin的场景。原生的windvane需要提前注册jsplugin，这种方式对bundle而言开销较大。需要bundle提前启动注册以避免后期运行时无法找到js函数对应的native方法。\",\"以命令的方式通知目标对象，如果是异步返回，则远端通过传入的callback接口进行回调，如果不是，则直接返回，适用于使用方和远端存在简单通信的情况。\",\"但是在复杂的app比如手淘这种无数个业务交织的场景下，完全的隔离也给业务的开发造成了不小的成本。针对这种问题，目前主要解决的方案有：\",\"使用基于容器的实现开发的servicehub，跟aidl一样将接口放到公共library，然后servicehub中写入接口和实现的对应关系。使用方通过servicehub得到接口实现进行使用。\",\"使用方如何调用remotefrag\",\"使用方如何调用remoteview\",\"使用方式\",\"使用方案：\",\"使用者可以通过这两个方法与真正的远端对象进行通信：\",\"使用者应该了解remotefragment机制的以下几个特点，明白其内部实现的主要机制：\",\"假设bundl\",\"假设在remote机制下则windvane针对非内部的common\",\"先附一张fragment启动图，不清楚的同学可以通过这个大致了解整个fragment启动的一些方法调用，理清fragment和activity在启动时的一些交织的关系(图片可能需要下载放大了观看)。\",\"公共so下层到公共模块，同时提前load（规避7.0版本开始区分namespace隔离的情况），bundle的so使用的时候不能使用官方的dlopen接口，需要根据mapping查找已load\",\"其他：由于nativ\",\"参照多个app之间通信的方式，使用aidl可以作为组件之间进行一定层度通信的方式。\",\"同时在manifest中增加如下配置：\",\"同样的，其他的sdk（比如weex）也可以通过类似方案在多classloader的apk内部实现自己定制的适配器，规避所有的接口实现需要预先注册的情况，同时也对整体应用的性能带来帮助。\",\"在android\",\"在多classloader运行机制下，需要事先了解几个要点：\",\"如何通知外部登录成功或者失败，除了用系统的广播等机制，能否基于remote的机制更直接地方便地实现该功能呢？后续remotetransaction中会阐述具体的用法。\",\"如果是直接使用dlopen\",\"定义同一个so的依据是全路径完全相同且so内容相同\",\"实现机制\",\"实现的机制\",\"宿主本身对于被调用方来说也是一个远端的对象，所以宿主自己可以使用iremote，同时将自己注册给remote对象，remotefragment、remoteview、remotetransactor的基类iremotecontext实现了提供了registerhosttransactor接口，在remotefactory回调时将自身的iremote实现注册进去\",\"对于aidl、servicehub以及remote的机制，可能还存在临时无法按照规范进行解耦的情况。目前除了静态依赖外，也可以考虑使用动态依赖的方式,用来解决在具体使用到某个功能时候再去挂载相应的依赖模块，不过bundle依赖始终打破了bundle之间的边界，需要谨慎使用\",\"对于js方法的调用方，则通过如下方法实现：\",\"建议把调用相关的调用so的代码和so本身单独封装成一个公共的模块，否则如果存在so反调java的情况，则只能调用到loadlibrary的classloader范围内的java类的代码\",\"我们也存在被使用方在某些场景下需要主动调用或者按规律定期callback宿主的情况，一种方式是使用宿主掉用远端时传进来的iresponse接口多次回调，但是如果涉及到复杂的情况就需要用到下面的方法：\",\"找不到。\",\"新的机制\",\"新的组件之间的重用及通信策略延续了aidl免注册的方式，同时解决了跨classloader情况下ui复用的问题。新的方式将重用类型归为remotefragment、remoteview、remotetransaction三种类型。\",\"方法尝试获取目标view并进行操作，remoteview应该被当做view而不是viewgroup，与目标view的通信应该通过remote的机制进行\",\"是否需要使用被依赖bundle的资源\",\"查看各自的map信息\",\"现在还可以选择的bundle间代码复用的方案\",\"现状\",\"由于nativ\",\"由于不同bundle的java代码使用相同的so导致的依赖：\",\"目标fragment与sampleactivity之间还是保持完整的隔离，所以目标fragment也无法获取宿主的引用，所以如果目标fragment需要与sampleactivity发生通信，则也要遵循remote的通信机制\",\"类似，remoteview提供更细粒度的bundle间的ui复用。\",\"类需要在两个bundle均可访问的主apk或者公共bundle中。\",\"缺陷\",\"被依赖的bundle的packagenam\",\"设想一下，如果一个activity引用了5个来自不同bundle的remotefragment，那么相当于这个activity内嵌了5个embeddactivity；那如果引用了5个来自同一个bundle的remotefragment呢？\",\"设置bundle运行时依赖\",\"调用loadlibrary(或者load)在native真正dlopen\",\"跨bundle的代码重用和通信\",\"这种使用方式适用于本身具有特定接口定义的sdk中，比如在手淘里面的windvane和weex。\",\"这里requestremote里面直接传入remotetransactor可能对开发者来说还有点晦涩，sdk开发者也可以尝试直接对remotetransactor以及iremote进行封装，比如改造成更为直观的basejsmanager和basejsplugin\",\"远端如何主动调用使用方的接口\",\"远端本身已经有封装过具体的接口，则可以实现getremoteinterface返回具体的接口的实现。这种方式类似之前的aidl的方式，前提是interfac\",\"那么在远端需要使用的时候，则可以通过hosttransactor（前面图中未标出）得到宿主的iremote的实现并传递相应的信息。\",\"问题：remotefrag\",\"需要在原来的基础上实现iremote接口，iremote来自atlas容器的内部实现，暂时还未从容器中拆分出差，这也意味着业务方需要增加对atlas的依赖。**iremote实现的两个接口会在文章后面解释**\",\"需要添加依赖的bundl\"],\"update/\":[\"业务灰度新的sdk，快速测试效果，同时有问题可以及时回滚\",\"动态修复线上故障\",\"动态部署\",\"动态部署与原有的apk更新策略相比是一种相对比较轻量化的更新策略，不需要用户下载整个apk，只需要下载仅仅差量部分的内容来达到更新效果；同时也可以静默的完成更新过程，两者相结合可以使动态更新的生效率远高于普通的升级策略。\",\"动态部署适合用来解决下面等需求：\",\"及时上线新需求，快速生效。\"],\"update/principle.html\":[\"6.2.1@6.2.0.tpatch\",\">\",\">classes2.dex,classes2.dex\",\">classes3.dex）,如下图所示：\",\">安装\",\">生效，与之相对应，动态部署也可以分为三个过程：\",\"aapt的修改，dalvik上我们是基于res的overlay机制去修改资源，这个机制并不支持新增资源，在overlay的包里面如果读到了一个资源，dalvik系统会去校验该资源id在base中值，如果不存在则抛错，所以动态部署为了利用这一特性同时支持新增资源的需求，在打基线包的时候就在每个不同的type里面预留了128个资源id供后续动态部署使用；同时打动态部署的patch时会以之前的id分配的内容作为输入，保证已有的资源分配到的id保持不变，同时如果资源没有发生变更，则剔除该资源，所以aapt\",\"arsc和androidmanifest直接使用patch包中的内容\",\"art设备上我们会根据source的apk（主apk的merge永远是基于基线版本）把classes.dex\",\"bootclassloader负责framework\",\"bundl\",\"bundle的merge主要以下几个过程(如下图)\",\"bundle的运行期加载策略：\",\"bundle，只是在需要去load前版本选择上会使用最高的可用版本\",\"class|so\",\"dexpathlist最终通过dexfile去loadclass，dexpathlist可以理解为持有者dexfile以及nativelibrary目录，再查找的时候遍历这些对象，直到找到需要的类或者c库，那么动态部署的方式就是把新修改的内容添加到这些对象的最前面，从而使得查找的过程中新修改的内容能够提前找到从而替换原有的（如下图）\",\"dex的逻辑。（patchdex\",\"dump\",\"merg\",\"merge安装成功后，会将bundleinfo的信息更新到baselineinfo的目录中，并在下次启动的最早时间替换掉原有的baselineinfo信息；里面的内容记录了更新的bundle的name，version以及部署成功以后的版本号等信息。\",\"merge完以后接下去安装就是容器的逻辑了，如果没有安装过则在bundle目录下生成version.1目录进行安装，如果安装过则生成新的版本目录\",\"merge完以后，当前的应用处于一个等待生效的状态，会在合适的时机选择进程重启来生效此次的动态部署，且在生效前不会再接收新的动态部署行为，进程重启以后表示一次完整的动态部署过程结束\",\"merge过程在下载到tpatch且校验通过后在线程中进行，由之前atlas容器安装目录介绍可知，假设当前bundle的版本在文件系统上为version.1,则merge成功后新的bundle会安装在version.2目录下，并在后续新的动态部署中版本号逐步往后追加，同时鉴于空间占用的考虑，目前的策略是会保留上一个版本（鉴于回滚的考虑）；\",\"oat的限制:android到art后原有的dexopt会改为dex2oat，运行时代码由原来的解释执行改为直接运行native代码，之前的使用过程中发现单纯得往前面追加patch的dex并不能完全解决动态部署的问题，dex2oat的过程优化了class的执行代码，比如说内敛，虚函数的校验等。就有可能在运行过程中直接在native层执行老的优化过的class代码而不是从新patch的dex中load新的class去使用。所以art上目前的策略是把patchdex，sourcedex参考multidex的机制放入一个zip，然后合并在一起做一遍dex2oat，这样能使新的class覆盖老的class参与dex2oat并完成优化的过程，所以art上的真正的执行过程实际上在patch的dex中已经包含了所有主apk的代码，基本不会走到old\",\"patch\",\"patch文件解压后一级目录如下图：\",\"patch的时候我们看到的invalid\",\"pathclassload\",\"pathclassloader本身也是一个class，继承了basedexclassloader（同dexclassloader），里面查找过程在dexpathlist里面实现（如下图）\",\"preverify:\",\"resource|asset\",\"res和asset\",\"sdk的内容的查找。\",\"targetversion@sourceversion.tpatch\",\"type\",\"zip包，classes.dex来自于source中的classes.dex和patch包中的classes.dex通过dexmerge合并新的classes.dex\",\"下载到tpatch文件后，动态部署sdk会在后台完成merge到安装的过程，整个过程对用户透明\",\"下面对每个过程展开讲解下，以便更好理解整个动态部署的机制\",\"下面展开介绍下在新bundle（假设主apk当做是一个特殊的bundle）安装成功前merge的过程中bundle和主apk在merge过程中的差异点：\",\"不同于apk更新产物就是一个完整的apk，动态部署的构建产物是一个后缀为tpatch格式的文件\",\"与bundle以包名为文件夹存放类似，主apk更新存放的文件夹以com.taobao.maindex为名字，里面的版本管理与bundle一致，不同点是com.taobao.maindex只在发生过动态部署以后才会有，version.1意味着已经发生一次动态部署；bundle通常情况下动态部署从version.2开始（未安装过的bundle除外）\",\"与tpatch文件相对于的，接口会返回该次动态部署的修改内容，数据结构如下：\",\"主apk为了支持在resource能够动态部署实际上同preverify的机制类似，在基线包构建的时候就已经做了处理:基于atlas打出来的apk的资源列表中有如下内容：\",\"主apk动态部署后的加载策略\",\"主apk的merg\",\"主apk的merge在dalvik和art上使用的机制有所不同，dalvik设备上没有任何merge过程，直接把libcom_taobao_maindex.so以bundle的形式安装到com.taobao.maindex目录下\",\"了解主apk的加载策略之前，先分别介绍下主apk动态部署得以成功的技术基础再阐述生效的方式：\",\"会进行合并，如果文件没有变更（patch中没有，source中有），则直接使用source中的内容，如果有文件新增或者发生了变更（patch中有，source中有或者没有），则从patch中读取放到新的bundle包中\",\"例如手淘6.2.0部署到6.2.1的动态部署的tpatch文件为：\",\"创建新的bundl\",\"前面容器的技术原理里面介绍了pathclassloader的父子关系，pathclassloader自身负责主apk的类和c库的查找路口；其par\",\"动态部署成功后，会在下次进程重启后去resolve新的bundle，resolve的策略是按版本号从高到低回溯，选择最高可用的版本使用。\",\"动态部署构建的产物为tpatch为后缀的一个压缩文件\",\"在打包对资源做了一系列处理以后，运行期资源的加载只是在启动加载资源时根据系统读取资源的先后书序把patch包插入到assetsmanager的合适的位置中，assets由于没有资源id，不需要预留，插入assetsmanager的方式类似res的处理，这里不再展开\",\"如果有bundle更新，则一级目录下以bundle为粒度有多个文件夹，每个文件夹下包含差量的classes.dex，res等\",\"如果有主apk的更新，则会有com_taobao_maindex.so存在，so中包含差量的classes.dex、res等\",\"我们取一个动态部署的tpatch包，能够看到如下内容：\",\"技术原理\",\"提取出来以多dex的方式追加到libcom_taobao_maindex.so中，如果本身是多dex机制的，那么会将多个子dex全部追加进去，patch里面的classes.dex保持不变，source里面的dex的序列号往后偏移一位（classes.dex\",\"插入前执行的代码除外）\",\"数据中可以看出bundle动态部署过程bundle的依赖关系允许发生变更，同时动态部署也有一定的限制，这个会在后面单独进行说明\",\"文件名为\",\"普通apk的更新的过程为构建\",\"构建\",\"注意点：主apk的差量与bundle的差量目前采取不同的策略，主apk永远是与基线版本做差量；而bundle是更上一个版本做差量：比如从6.1动态部署到6.2再动态部署到6.3，则6.3中主apk的差量是6.3主apk的集成内容和基线（6.1）主apk中的内容diff出差量；6.3中bundle的差量则是与上一个版本进行diff，如果是6.2的版本去请求动态部署的tpatch，则tpatch中的bundle的差量是6.3与6.2的bundle进行diff所得，如果是6.1版本去请求6.3的动态部署的tpatch，则bundle的差量是6.3与6.1的bundle进行diff所得\",\"生效\",\"由之前的容器的运行机制可以得知，bundle动态部署后对容器来说没有任何变化，还是按需的load\",\"的资源段没有发生变更的资源，如果有发生了变更，且之前有这个资源，就会在原有的资源id分配过去，同时新的资源文件打入patch包或者新的资源文本写入arsc，如果是新增的资源，则使用预留的资源段进行分配。整个替换过程如下图所示：\",\"经过手淘打包插件构建以后，主apk里面的所有class，interface都插入了一段代码：类似下图。原因是android构建的时候会有preverify的过程，如果class所引用到的class均和class自己在同一个dex内部，则会被打上preverify的标记。然后在运行期的时候如果打上这个标记的class，在载入时不需要经过verify已提高加载效率，但是运行到方法时会校验依赖的class是否跟构建时一致和class自身处于同一个dex，如果不一致则会抛出preverify的错误。而手淘的动态部署策略必然会新生成一个dex，那么如果遇到是preverify的class的时候就会出错。所以目前手淘的策略是在编译期给每个class引用到一个不存在的class以解除preverify的限制（具体preverify的校验过程可以阅读android源码）\",\"获取merge的数据源：patch信息来自于bundle在下载的tpatch包中的内容，用于merge的source来自于当前设备的文件系统中，可能来自于已经安装过的bundle（storage），可能还没有安装（apk或者lib目录下）\",\"运行期\",\"这些是基于我们atla\",\"这里有两个注意点提及一下以加深理解：\",\"这里粗略介绍下普通apk（也就是主apk）class，so库加载入口\"],\"update/dexpatch.html\":[\">\",\"dexpatch\",\"dexpatch不存在回滚，每个dexpatch发布后，直接覆盖之前的dexpatch的。每个dexpatch有下线的能力\",\"dexpatch作为动态部署的补充，两者相辅相成。可以针对任何一个大版本或者动态部署版本发布dexpatch，无论一个版本号对应的bundle是否有被dexpatch，当一个新的动态部署发生时，它们又都会被收敛到一个新动态部署版本上面。\",\"dexpatch是以动态部署技术方案为基础，以快速解决线上故障为唯一目的的动态化方案。\",\"dexpatch由于其修改的原子性（向前兼容性的保证以及不存在关联修改），同时容器按需加载的特性，使得未被载入的bundle可以不需要进程重启即可生效，同时，已经载入的bundle后期也会进行生命周期的监控，一旦所有component退出，则也可以进行热替换，使得dexpatch相比动态部署的生效速度可以进一步提高\",\"dexpatch的特点和优势\",\"下发的dexpatch总包内的patch各自生效，不需要所有bundle的patch全部安装成功，这是由于之前patch的修改是向前兼容做了保证。\",\"为什么不用动态部署\",\"什么是dexpatch\",\"优势\",\"动态部署允许宿主，bundle内部发生更新，也允许bundle之间的依赖关系等发生变更，这就导致了一次动态部署成功必须依赖于tpatch内的所有bundle和宿主全部更新成功，否则就可能会导致依赖不一致而引发crash。从以往的动态部署tpatch可知，每次的变更通常都有十几个甚至几十个bundle发生变更，而在低空间或者某些读写能力较差的设备上，io失败很容易影响整个patch的成功率。\",\"动态部署内有代码的变更，so，资源等。灵活性导致一个动态部署等体积往往比较大，而在运营商网络下，对用户大的流量消耗不是我们希望看到的，所以往往这种情况下只在wifi下的生效策略很能影响生效率。\",\"动态部署的出发点立足于需求的快速迭代，替换普通的apk升级。所以在动态部署的演进过程中灵活性成为我们不断去追求的目标。希望不断缩小动态部署的限制以达到完全替换apk更新的能力。\",\"另外\",\"同时dexpatch不修改整个apk版本号，每个bundle提供额外的dexpatch版本号进行监控。\",\"回顾手淘之前的一些故障问题的修复，不管是动态部署还是andfix，其实我们发现几乎所有的故障都可以通过java代码就行修复或者降级，也基本都可以在一个模块内的修改就把某个对应的故障修复掉。因此，以动态部署的技术作为基础，称之为dexpatch的方案应运而生。\",\"因为是apk升级的替代方案，动态部署替换版本号的方式就使得是否使用的是动态部署还是apk升级对业务来说完全透明，可以继续按版本号进行逻辑处理，降级等。数据统计以及监控等可以完全兼容。但是如果在故障修复中去贸然升级版本号，虽然直观上可以清楚看到问题修复的覆盖率，但是之前优势就荡然无存了。\",\"在每个需求迭代过程中，考虑需求的复杂性和每次周期性迭代管理的成本，动态部署参考apk迭代的方式通过统一的集成区进行管理，所以在构建上动态部署tpatch实际上是先有整包构建，再diff出差异的方式，这样的方式规避了混淆、内联等带来的复杂性的问题处理，保证patch对之前版本的完全适用，但是这种方式同时也必不可少的影响patch的构建速度，在对紧急的问题进行修复的关键时期，这个时间可能会是不可接受的。\",\"如何发布dexpatch:\",\"构建速度：\",\"正是因为其比较全面的能力，我们发现动态部署在故障修复方面存在其不足的地方：\",\"每个bundle基于自身的问题进行dexpatch的发布，构建速度相比原来的方式有了大幅度提高，只需要针对单个bundle进行构建从而diff出差异即可。\",\"每个dexpatch只能修改一个bundle(主dex整个算一个bundle)，且修改的代码必须向前兼容。（不如说主dex被bundle依赖，则主dex的dexpatch修改不能引起原来bundle的方法调用出现问题）\",\"每个业务按照各自的故障情况进行dexpatch的构建，产出对应的patch产物和json信息，发布时平台应该汇总对应版本当前release的所有patch内容，整合json信息，进行下发\",\"版本号：\",\"生效速度：\",\"那么现在理想中的版本迭代的情况应该是如下这种：\",\"限制：\"],\"update/dexpatch_use_guide.html\":[\"\\\"1.0.0\\\"\",\"\\\"1.0.0\\\",\",\"\\\"1.0.0@1.0.0.tpatch\\\",\",\"\\\"1.0.1\\\"\",\"\\\"14\\\",\",\"\\\"6b3973d9d6592d15601017edabc8b31b\\\",\",\"\\\"baseversion\\\":\",\"\\\"bundles\\\":\",\"\\\"com.taobao.firstbundle\\\",\",\"\\\"com.taobao.publicbundle\\\"\",\"\\\"dependency\\\":\",\"\\\"dependency\\\":[],\",\"\\\"dexpatch\\\",成功~\",\"\\\"dexpatch\\\":\",\"\\\"dexpatchversion\\\":\",\"\\\"diffbundledex\\\":\",\"\\\"e857557cc924f503a7304218469733a2\\\",\",\"\\\"filename\\\":\",\"\\\"ismaindex\\\":\",\"\\\"name\\\":\",\"\\\"patches\\\":\",\"\\\"patchversion\\\":\",\"\\\"pkgname\\\":\",\"\\\"reset\\\":\",\"\\\"srcunittag\\\":\",\"\\\"targetversion\\\":\",\"\\\"unittag\\\":\",\"\\\"version\\\":\",\"'1.0.1'\",\"(gradle中配置)\",\"+1\",\"...\",\"./gradlew\",\"//重要\",\"/sdcard/android/data/com.taobao.demo/cache/，并将上述两个文件push到上述路径中\",\"1\",\"1.0.0.json\",\"1.0.0@1.0.0.tpatch\",\"1.1.4.11\",\"2.3.3.rc12\",\"5.0.7.41\",\"=\",\"[\",\"]\",\"],\",\"`./gradlew\",\"apk动态升级\",\"apk范围\",\"app/build/outputs下，检查是否存在两个文件\",\"assembledebug\",\"atlas_cor\",\"atlasplugin\",\"atlasupd\",\"bundle级别，代码动态修复\",\"bundle自身内聚\",\"clean\",\"dapversion=1.0.0\",\"demo中测试入口\",\"demo说明\",\"dexpatch\",\"dexpatchvers\",\"dexpatch与动态部署异同\",\"dexpatch介绍\",\"dexpatch使用教程\",\"dexpatch使用示例\",\"dexpatch是以动态部署技术方案为基础，以快速解决线上故障为唯一目的的动态化方案。\",\"dexpatch需要一个ap版本作为参照，和现在的代码比对做diff。假设当前版本为1.0.0\",\"dversionname=1.0.0\",\"false,\",\"java\",\"patchs.json\",\"path.json\",\"ps:\",\"publish\",\"reset\",\"resourc\",\"true,\",\"version@version.tpatch\",\"versionnam\",\"x\",\"xxx.json\",\"{\",\"}\",\"一般\",\"上述代码diff的配套json，描述了本次diff的结果:\",\"不同点\",\"不改\",\"主界面点开侧边栏，点击dexpatch\",\"产物说明\",\"依赖\",\"修改依赖版本，将firbundle中grddle的verion改为vers\",\"修改范围\",\"动态部署\",\"包装后的产物字端如下,大部分内容直接copy自patch.json,需要关心的只有几个字端\",\"区分配置是动态部署还是\",\"发布ap到仓库中\",\"发布版本\",\"各个bundle随时下发\",\"回滚标志，该bundle会回滚到dexpatch前的版本\",\"场景定位\",\"基于ap所属的版本(1.0.0)，修改代码,以firstbundle为例，将\\\"origin\\\"修改为\\\"dexpatch\\\"\",\"如果之前发布过ap版本，可以跳过此节。假设从未发布过ap，按照如下步骤，发布1.0.0的ap\",\"字段\",\"字段解释\",\"客户端可以识别的接口，对打包产物包装处理过的配置\",\"客户端并不能直接识别打包产生的\",\"当前代码和参考ap(1.0.0)diff的产物，是个zip文件，解压开就是diff的代码。\",\"很快\",\"快\",\"打patch\",\"打包\",\"指定参照的版本，生成dexpatch包\",\"支持\",\"改动模块信息\",\"文件，需要服务端做一些包装。\",\"构建速度\",\"每个模块有一个dexpatchversion的概念客户端会判断bundle的dexpatchversion,判断该bundle是否需要做merge通常由服务端进行管理\",\"比对版本\",\"清空\",\"灵活度\",\"版本\",\"生成基线版本\",\"生成的patch文件在\",\"生效速度\",\"由于demo没有服务端，所以在app/dexpatchwraper.gradle中，对patch.json内容做了一个包装，简单模拟服务端的逻辑。\",\"简单来说，动态部署是针对apk级别的动态升级，dexpatch是针对bundle级别的动态修复(主dex可以认为是一个bundle)\",\"简单起见，只是每次都把dexpatchversion+1，版本号缓存在根目录下的dexpatch.verion文件中。\",\"详细介绍参照\",\"说明\",\"这里也可以修改firbundle依赖的某个aar的版本。一句话，你要通过版本号告诉编译器，我这个bundle的代码变了\",\"这里要强调一下，代码的修改要内聚。假设a依赖b,修改时，只改a或b自身的代码，不支持修改a与b之间的接口。\",\"进入app目录下\",\"部署patch\",\"重启应用,toash显示\",\"集成升级\"],\"update/guide.html\":[\"activity切换的动画文件、通知栏使用的logo等如果修改了也不会生效，不过不会产生问题，使用的还是原来的样式\",\"androidmanifest\",\"window级别使用的资源保持不变\",\"一些限制\",\"动态部署的限制\",\"已有activity的manifest信息暂时不支持更改\"],\"faq/question.html\":[\"/f\",\"/im\",\"1.\",\"2.\",\"2.3.1版本是不是支持？\",\"=\",\"a:\",\"aar\\\\com.android.support\\\\anim\",\"alpha11版本发布解决了。\",\"altas是不是不建议bundle之间相互调用资源或调用宿主的资源?\",\"andfix\",\"andfix只要用于修复java代码，不重启生效。\",\"application的设计是为了尽最大可能保留大家android的开发习惯。\",\"application里用this这种代码，因为是不生效的。\",\"app有多个进程，在一个进程中出现了host中的一个类被pathclassloader加载了，之后在该类中调用class.forname加载插件里的一个类，因为classloader是pathclassloader,所以报了classnotfound,理论上host中除了atlas相关的类外所有的class都应该是被delegateclassloader加载吧？\",\"atla\",\"atlas支持所有的代码及资源更新，暂时不支持新增4大组件，下个大版本支持\",\"atlas框架建议bundle调用宿主的资源，而不建议bundle之间资源的相互调用。\",\"atlas能力更强，修复只是其中一部分能力\",\"atlas项目中：atlasdemo和基于版本打包的demo这两个项目有什么区别？\",\"awb对应于bundle，编译最后的产物是生成到最后整包的so中。具体请参照\",\"awb是什么？\",\"awb是我们发明的格式，其内部结构和aar一样。\",\"a：\",\"bundle中的9patch图显示有问题，不能拉伸了。是需要有特殊设置么？\",\"bundle中的application类的自定义方法，我们建议不要这么使用。可以抽离出公共的方法，放在其他地方供调用。\",\"bundle中的application类，是在bundle第一次安装的时候，atlas会调用application的oncreate()函数，可以在里面写一些自己bundle需要用到的初始化代码。注意不要bundl\",\"delet\",\"demand\",\"demo\\\\atlasdemo\\\\app\\\\build\\\\intermediates\\\\explod\",\"drawable\\\\25.3.0\\\\jars\\\\classes.jar\",\"e:\\\\github\\\\atlas\\\\atla\",\"fals\",\"file\",\"framework，正常的android代码中我们可以调用framework中的接口以及使用其包含的资源，宿主对于bundle而言也是这个样子的，假如多个bundle使用同一个资源，那么这个资源可以放在宿主里边，多个bundle同时依赖这个宿主，这样避免了资源的重复。(甚至可以把宿主看成一个aar，这个aar的内容是打包在主dex中的)\",\"http://atlas.taobao.org/docs/principl\",\"https://github.com/alibaba/atlas/issues/68\",\"intro/project_architectured.html\",\"java.ex\",\"keep\",\"oncreate方法、activity的oncreate方法等都是在主线程回调的\",\"permission，小米推送需要permission就提示缺少权限声明。\",\"proguard\",\"q10.\",\"q11.\",\"q12.\",\"q13.\",\"q14.\",\"q15.\",\"q16.\",\"q17.\",\"q18.\",\"q19.\",\"q1:\",\"q20.\",\"q2:\",\"q3:\",\"q4:\",\"q5:\",\"q6:\",\"q7:\",\"q8:\",\"q9.\",\"rules.pro直接定义在宿主app里面就可以了吗，不需要每个bundle都使用吧？\",\"run\",\"studio编译按钮编译失败。\",\"unabl\",\"vector\",\"一个是基于源码项目，一个是基于仓库版本依赖的。前期研究可以基于源码来，后续工程化实践推荐使用后者，手淘内部就是使用后者的。\",\"上重新编译安装不生效的问题\",\"下个版本会清理bundl\",\"不生效要看提示log再查，目前已知的已经修复，之前是由于windows句柄没关闭，导致tpatch中包含一些空文件，在dexmerge的时候失败了\",\"关于bundle中的application类，它什么时候被调用，其中的自定义方法怎么在bundle中调用？在bundle中调用getapplication方法，得到的是主应用的application对象，不是bundle中定义的。\",\"关闭instantrun可以正常工作。instantrun支持正在开发中。\",\"关闭掉a\",\"动态部署不生效的问题\",\"及与\",\"可通过属性开关关闭。\",\"在其他进程里运行的插件，需要在什么时候安装？可不可手动控制安装的时机？\",\"在宿主app里边定义就好了\",\"在打整包的时候需要配置过滤的参数，把so的架构类型指定清楚，要不然就会被裁减掉。具体可以参考\",\"在覆盖安装的时候，由于bundle的版本号没变化，没做清理，\",\"在需要的时候按需安装，例如一个service是在单独的进程中，只要需要的时候去bind就会触发这个bundle的安装。可以手动控制安装时机，按需就好。\",\"客户端拿什么属性\",\"宿主和bundle的关系？\",\"宿主就相当于android\",\"对于gradl\",\"导入demo后，android\",\"属性开关是atlas.manifestoptions.removecustompermiss\",\"开关\",\"是的，支持2.3.x\",\"杀掉java.exe进程重新编译（window\",\"每一次补丁的发布都是相当于一次版本的升级，通过版本号的变更来决策补丁的下发\",\"混淆后atlas进度条消失\",\"的关系\",\"的能力问题，\",\"目前是有这个限制。如果非得在里面调用，建议改为static方法。\",\"系统进程出现）cmd:taskkil\",\"组件中有jar包和so依赖，awb的产物中也有，为什么在宿主中生成的so产物解压就没有了呢？\",\"自启动bundle可以在任何线程中执行，不过bundle的appl\",\"自启动的bundle是在哪个线程中啊，不是主线程吗？\",\"规则少了\",\"请问\",\"跟服务器比对获取补丁？\",\"这是因为打包插件默认开启了去除自定义权限。\",\"这种问题属于宿主中的class引用了bundle中的class，理论上是可以支持的，但是在atlas的框架中是不推荐(也没不支持)这种反向的依赖关系。\",\"问答\",\"集成框架后就只有use\",\"首先要明确一点，bundle中的application不是最终在android系统上执行的application。我们之所以保留bundl\",\"：\"],\"faq/help.html\":[\">\",\">b\",\">c,如果a没有显式声明依赖c，则a\",\"atlas容器内部集成了multidex的dex安装功能，所以原先multidex的初始化代码可以省略，也不需要添加multidex的三方库依赖，需要使用multidex的只需要build.gradle内部将multidex置为enable即可（atlas内部集成该内容一方面是便于和容器的兼容，另一方面后续容器会优化原生multidex在dalvik上面的性能）\",\"bundleinfo的内容，里面记录了所有bundle的依赖关系\",\"bundle如果相互依赖，则构建起需要配置dependency，否则运行期会无法找到被依赖bundle内的class，且不支持为了查找性能，目前不支持二级依赖：比如a\",\"bundle的activity，而xml来自于b\",\"bundle里面无法直接使用bundl\",\"bundle，如果a和b没有依赖关系，那么加载也肯定失败\",\"classnotfoundexcept\",\"c里面的class，检查bundle依赖是否成功配置可以通过反编译apk的主dex\",\"noclassdeffounderror\",\"tag的警告信息：\",\"一般来说，由于art设备警告的信息报在dex2oat的时候，所以往往与发生crash时的exception信息相隔比较远，所以通常遇到该类问题，dalivk的设备拿来排查可能更能发现问题的原因。另外noclassdef造成的原有接口类找不到，方法丢失，方法参数不匹配，方法属性变更，混淆等，所以具体原因需要利用上述warning信息并对照反编译的代码去排查根本的原因\",\"在dalvik的系统上，则会带有vfi\",\"如果类本身存在，需要往前排查系统的警告信息，比如在art的设备上会有class被reject的warning信息：\",\"常见问题\",\"故障排查\",\"有任何的建议和问题请在github上提issue给我们，我们会尽快回复，同时高频的会更新的faq文档中\",\"查看android.taobao.atlas.framework.frameworkproperties的field\",\"膨化xml，则xml里面如果有richview，则务必确保layoutinflater持有的context的classloader可以load到该richview，假设context来自于a\",\"通过layoutinflat\",\"造成该问题的原因比较多，排查步骤第一个先检查exception的源头是不是classnotfoundexception，然后反编译排查类确实是否存在；\",\"需要去除的原生multidex初始化\"],\"faq/variant.html\":[\"\\\"api_env\\\",\",\"\\\"boolean\\\",\",\"\\\"com.taobao.atlas.beta\\\"\",\"\\\"com.taobao.demo\\\"\",\"\\\"false\\\"\",\"(project.hasproperty(\\\"beta\\\"))\",\"./gradlew\",\"//通过增加判断逻辑，打出不同类型的定制包\",\"14\",\"21\",\":\",\"=\",\"android\",\"appid\",\"assembledebug\",\"atlasplugin\",\"atlas是面向多人协作的较大工程的，配置不同的buildtype和flavor中也会带来创建更多的任务，并且如果执行assembledebug\",\"buildconfigfield\",\"clean\",\"cn\",\"def\",\"defaultconfig\",\"falvor\",\"flavor\",\"google插件\",\"google插件对应的文档地址：\",\"https://developer.android.com/studio/build/build\",\"minvers\",\"pbeta\",\"pbeta,\",\"variants.html?hl=zh\",\"{\",\"}\",\"}else{\",\"不支持\",\"为什么没有去完全适配\",\"之类会构建所有的依赖变种，导致整体构建效率大大降低。\",\"以上build.gradl\",\"以及\",\"先看一下功能对比：\",\"具体的demo可以看下下面的介绍，至于具体的其他实现，大家也可以自行扩展\",\"原生是支持配置不同的buildtyp\",\"后续如果要打特殊包就可以通过修改配置的构建参数来控制打具体的包了，如：\",\"因为build.gradl\",\"在build.gradle里定义一些基础的变量，比如：\",\"增加一层逻辑控制根据不同的参数来修改之前定义变量的值\",\"大致步骤\",\"如何构建不同的包\",\"就会使用新的值了\",\"开发期我们期望我们的基线足够稳定，这样可以避免动态部署基线不兼容的问题\",\"开发精力所限，因为我们的淘宝app就是没有变种的架构，额外的功能会带来很多适配的麻烦和风险\",\"当前插件下的实践\",\"当前的支持度\",\"我们一般的做法就是通过打包参数来控制不同的参数值，\",\"或者直接在配置的地方加上判断逻辑，使用特殊的配置\",\"插件\",\"支持\",\"构建apk\",\"构建动态部署\",\"构建定制包\",\"构建标准包\",\"构建特殊包\",\"的，\",\"自定义buildtyp\",\"这样如果我们打包加了\",\"里可以写很多的逻辑，所以配置也可以变的很灵活。\",\"里的配置基本完成。\",\"，\",\"：\"],\"faq/dynamic_failed_help.html\":[\"\\\"awbdiffs\\\":[\\\"com.atlas.demo:firstbundle\\\"],\",\"\\\"baseversion\\\":\\\"1.0.0\\\",\",\"\\\"bundleinfo\\\":[\",\"\\\"com.atlas.demo:firstbundle(1.0.1=>1.0.2)\\\"\",\"\\\"com.taobao.publicbundle\\\"\",\"\\\"dependency\\\":[\",\"\\\"ismaindex\\\":false,\",\"\\\"ismaindex\\\":true,\",\"\\\"maindexdiffs\\\":[\\\"com.atlas.demo:splashscreen(1.0.0@aar=>1.0.1@aar)\\\"],\",\"\\\"modifylines\\\":[\",\"\\\"name\\\":\\\"com.taobao.firstbundle\\\",\",\"\\\"name\\\":\\\"com.taobao.maindex\\\",\",\"\\\"newawbs\\\":[]\",\"\\\"pkgname\\\":\\\"com.taobao.firstbundle\\\",\",\"\\\"srcunittag\\\":\\\"1lxlheevwoeeg\\\",\",\"\\\"srcunittag\\\":\\\"1nf3phs9djbuj\\\",\",\"\\\"unique_tag\\\":\\\"1lxlheevwoeeg\\\",\",\"\\\"unittag\\\":\\\"1x6r8iuzs90ff\\\",\",\"\\\"unittag\\\":\\\"31jv86qvt1gc\\\",\",\"\\\"updatebundles\\\":[\",\"\\\"updateversion\\\":\\\"1.0.1\\\"\",\"\\\"version\\\":\\\"1.0.0@1.0.1\\\"\",\"\\\"version\\\":\\\"1.0.0@1.0.2\\\"\",\"#\",\"//...\",\"//动态部署更新版本\",\"//动态部署版本1.0.1的tag\",\"//基线依赖1.0.0中的唯一tag\",\"//基线版本\",\"/data/data/\\\\${pkg}/files/bundlebaseline/updateinfo\",\"/data/data/pkg/files/storage/\\\\${bundle\\\\_pkg\\\\_name}/bundle.zip\",\"1.\",\"1.0.0\",\"1.0.0.json\",\"1.0.0.json中的值:\",\"1.0.0.json中的记录的unittag，数据没有问题。\",\"1.0.1\",\"1.0.1@1.0.0\",\"1.0.1ecom.taobao.maindex@31jv86qvt1gc;com.taobao.firstbundle@1x6r8iuzs90ff;\",\"1.0.2\",\"1.重新publish了ap,老ap被覆盖了2.gradle在本地仓库做了一份cache，是否和远程仓库中的一致\",\"12\",\"12:39:04\",\"1lxlheevwoeeg\",\"1x6r8iuzs90ff\",\"2.\",\"2014\",\"22\",\"31jv86qvt1gc\",\">1.0.1的diff信息。\",\"]\",\"],\",\"ap不对,mvn仓库中的ap，和预期的不是同一个\",\"ap不对，比对的ap和预想的不是同一个\",\"bullhead:/data/data/com.taobao.demo/files/storage/com.taobao.firstbundl\",\"bullhead:/data/data/com.taobao.demo/files/storage/com.taobao.firstbundle/1x6r8iuzs90ff\",\"bundle.dex\",\"bundle.zip\",\"bundle_pkg_name为bundle的包名，maindex的包名为com.taobao.maindex\",\"cat\",\"cd到和/data/data/com.taobao.demo/files/storage/com.taobao.firstbundl\",\"classes.dex\",\"date:\",\"firstbudnl\",\"firstbundle（bundle）\",\"key\",\"libcom_taobao_firstbundl\",\"libcom_taobao_firstbundle，反编译classes.dex，有且只有first.class这个diff\",\"libcom_taobao_maindex.so\",\"libcom_taobao_maindex.so，解压反编译classes.dex，有且只有maindex.class这个diff\",\"lock\",\"ls\",\"maindex\",\"meta\",\"ok,我们再解压1.0.0的ap文件，打开atlasframeworkproperties.json文件，关键字搜索com.taobao.firstbundl\",\"patch\",\"pkg为app的包名\",\"splashscreen\",\"splashscreen（maindex）\",\"srcunittag\",\"tag\",\"title:\",\"unittag\",\"unittag确认。（如果同学们没有按照规范来，这个地方很容易出错，导致动态部署失败）\",\"updat\",\"updateinfo\",\"updateversion(1.0.1),分别对应打包命令的apversion和versionname,表明是1.0.0\",\"val\",\"xxx.json中bundle的srcunittag和ap中的unitttag不一样\",\"xxx.json文件中，某个bundle的srcunittag和unittag一样\",\"{\",\"}\",\"},\",\"│\",\"└──\",\"├──\",\"中的first.java和splashscreen中的maindex.java,diff出来的产物就一定如上图所示:\",\"从demo中一个例子开始，假设我们发了1.0.0的ap,之后修改了splashscreen和firstbundle两个地方的代码,并且修改了对应的版本号\",\"以上是正确的使用姿势，下面是常见的一些常见的错误\",\"修改引入了其它隐含的改动\",\"关于第三个，我们以firstbundle为例，详细说明。首先，看下在配置文件upd\",\"动态部署失败排查指南\",\"动态部署排查经验\",\"动态部署版本\",\"原因\",\"反编译dex，查看patch出来的代码和修改的是否一致。\",\"另外，根据历史经验，大部分都是使用不规范造成的，为了避免这些奇奇怪怪的问题，大家最好按照atlas工程结构指南以及容器接入\",\"可以看到产物merge成功了，反编译budnle.zip（apk），可以验证改动\",\"可以看到，firstbundl\",\"可能的错误操作\",\"各位，有没有灵光一闪？是的，unittag和srcunittag是有联系的，客户端用来验证patch的合法性，看图:\",\"命令\",\"和\",\"在updat\",\"在动态部署提示重启前，执行\",\"在发布lib/bundle版本时，带动了其它lib／bundle的版本变化\",\"基线版本\",\"如果同时存在updateinfo和updateinfo_new两个文件,以updateinfo_new为准\",\"如果对不上，说明打包产物错误，下面是两个常见的原因，需要同学们自己做一下排查。\",\"如果有异常，和第上面一样\",\"如果有异常，返回检查第一步的产物。\",\"客户端检查\",\"对应前面打包产物updat\",\"快速排查三连\",\"或者本次修改隐含带入了其它改动。\",\"打包产物检查\",\"打开updat\",\"打开产物中的dependencydiff.json的文件，这个文件记录了本次改动相对ap的依赖变化信息\",\"按照文档，触发patch更新操作，观察本地上两个地方\",\"改了几个类这里就会对应diff出几个，不会多也不会少。\",\"整包(apk)\",\"新版本\",\"查看merge的产物是否存在，以firstbundle为例，maindex同理。\",\"根本原因\",\"格式很简单\",\"概述\",\"比如修改了firstbundl\",\"没有异常，说明本次动态部署生效。\",\"涉及改动确认，配置中的diff信息和我们的改动一致（两个部分，firstbundle和maindex）\",\"涉及版本确认，baseversion(1.0.0),\",\"的版本变化和改动一致，没有问题。\",\"目录名为记录的tag1x6r8iuzs90ff,cd\",\"第一点，依赖变动\",\"第三点，diff代码验证\",\"第二点，验证配置文件\",\"经常有同学在答疑群上提出疑问为什么动态部署不生效？，然后就是一通排查。由于是远程交流，代价实在是太高。这篇文章主要是和大家分享一下动态部署排查的一些经验，希望能够帮助大家快速定位、解决问题。\",\"解压tpatch\",\"还是ap有问题\",\"还是查看这两个文件，updateinfo的内容有没有变，或者storage下merge后bundle的产物是否存在\",\"这两篇文章提到的规范，来组织工程结构。\",\"进去\",\"通常来说都是改了代码，但是没有变更依赖lib/bundle的版本号\",\"通常来说，如果打包产物如果没有问题，动态部署一般都是可以正常生效的。\",\"重启前\",\"重启后\",\"错误\",\"首先检查打包的产物，按照历史经验，90%的问题都是因为打包产物不对造成的。\",\"首先，确保手机存储卡容量足够(至少100m吧)，然后在进行下面的排查步骤。\"],\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":[\"#\",\"'com.android.library'\",\"'com.android.support.constraint:constraint\",\"'com.android.support:appcompat\",\"'com.android.support:support\",\"'com.taobao.atlas'\",\"'com.taobao.atlas'和awbbundl\",\"'com.taobao.demo.demoprelaunch'\",\"'libs',\",\"(appcompat...)\",\"(firstbundle、secondbundle、publicbundle)\",\"(remotebundle)。\",\"//...\",\":\",\"=\",\"=['xxx']\",\"['*.jar'])\",\"['com.taobao.firstbundle']\",\"['com.taobao.firstbundle']，编译时，会将firstbundle中application路径写入manifest。程序运行时，atlas会第一个执行firstbundle中demoapplication中的代码\",\"['remotebundle']\",\"alpha8'\",\"android\",\"apk结构分析\",\"app\",\"appli\",\"app的包名、版本号...\",\"atla\",\"atlasen\",\"atlas一个运行于android系统上的一个容器化框架。为了实现这一目标，在编译器和运行期，atlas都做了很多工作。本文是一个入门级别的文章，梳理从gradle配置到生成最终apk的期间，atlas框架到底搞了哪些事情。\",\"atlas之gradle配置\",\"atlas将一个apk分为host和bundle两大部分\",\"atlas插件在编译期生成的配置信息。比如在gradle中配置了\",\"atlas插件有很多参数，这里只关注demo中出现的重点参数，其它设置大家可以查看官方文档。\",\"atlas插件配置\",\"autostartbundl\",\"awbbundl\",\"build.gradl\",\"bund\",\"bundl\",\"bundlecompil\",\"bundleconfig{\",\"bundle中的manifest中没有任何东西，\",\"bundle中的代码不会打入dex中去，bundle将以libxxx.so文件的形式，放在apk的lib目录下，随包发布\",\"bundle独立打包，拥有独立的dex和资源\",\"bundle的代码和资源其实独立打成了一个apk，放在了apk的lib目录下，在运行时进行动态加载。\",\"bundle的存放位置\",\"bundle部分的清单数据，包括在app工程中bundlecompile的依赖代码和bundle自身compile的依赖代码\",\"comil\",\"compil\",\"compile('com.taobao.android:atlas_core:5.0.7@aar')\",\"demo\",\"depend\",\"dependencies主要分为三个部分\",\"dex\",\"filetree(dir:\",\"gradle分析\",\"gradle部分，我们只用看主工程app和bundle的配置就可以了。\",\"host\",\"host为共用代码资源和各个bundle的manifest信息\",\"include:\",\"layout:1.0.0\",\"manifest\",\"merge各个bundle的manifest到app中\",\"outofapkbundl\",\"plugin:\",\"prelaunch\",\"project(\\\":secondbundlelibrary\\\");\",\"project(':activitygroupcompat')\",\"project(':firstbundle')\",\"project(':middlewarelibrary')\",\"project(':publicbundle')\",\"project(':remotebundle')\",\"project(':secondbundle')\",\"project(':splashscreen')\",\"providedcompil\",\"secondbundlelibrary之前并没有打入主dex中，因为这只是secondbundle所需要的依赖。最终会将secondbundle和secondbundlelibrary的打在一个同一个dex中，加上两者的资源，成为一个bundl\",\"tbuildconfig\",\"transit\",\"true\",\"true表明启用了atlas插件，并将当前模块编译成awb形式的bundle供主apk使用。\",\"v4:25.3.0'\",\"v7:25.1.0'\",\"xxx\",\"{\",\"}\",\"中可以看到有两种形式的依赖\",\"为例。\",\"为四大组件预留一些坑位\",\"主dex\",\"主dex中已经打入了必要的公用代码(appcompat、middlewarelibrary)，在runtime时，atlas框架会自动找到主dex中的class使用，所以secondbundl就不需要在重复打入\",\"乍看之下，似乎并没有什么不妥。但是，细心的同学可能发现了，少了bundle部分的代码。\",\"代码以\",\"以secondbundle为例，看一下bundle中gradle的配置\",\"会打入apk中，而remotebundle不会\",\"依赖方式\",\"依赖管理配置\",\"像搭积木一样，host和不同的bundle组合编译成一个apk\",\"分析完manifest之后，我们看一看host的dex文件，看一看有没有对java代码动手脚。\",\"参考\",\"可以很清楚的看到，gradle的配置主要分为三大块，依次是标准的android插件配置、atlas插件的配置，以及依赖管理部分。我们重点看最后两个部分。\",\"可以看到，manifest中的内容大概分为三大块\",\"可以看到，在atlas框架中，主app只是一个壳子，只是用来配置打包参数的\",\"在看完gradle的配置之后，我们反编译demo的apk，看一下最终生成的结构。\",\"官方demo\",\"官方文档\",\"将bunde的资源进行分段\",\"小结\",\"常规的打包配置，会将依赖代码打入到dex中去\",\"常规编译产生的清单数据，包括app工程自身的代码和compile依赖的代码\",\"开启atlas插件的开关，在编译期会做很多事情\",\"总结\",\"感兴趣的同学可以自行验证。\",\"我们接着往下看\",\"打包bundle等等\",\"指定第一个需要启动的bundle，在atlas框架初始化完毕后，会执行这里这里配置bundle的代码。\",\"指定远程bundl\",\"接着看依赖配置部分\",\"最后确认一下以secondbundle的代码，\",\"果然，每个bundle的代码都是各自打包的。\",\"概述\",\"比如在demo中，firstbundle、secondbundle、publicbundl\",\"比如在demo中，配置了以下打包设置\",\"独立打包，用于后续的动态下发\",\"生成一些class，记录bundle的关键信息\",\"的manifest部分\",\"的区别之一\",\"的的manifet部分\",\"的配置项，表示apk的bunde依赖，即apk是由这些bundle共同组成。\",\"盗用一张老大的图\",\"第一部分\",\"第三部分\",\"第二部分\",\"组件化和插件化\",\"结合app工程gradle的配置，我们发现以compile开头的依赖(middleware、utils、update),都是正常将java代码打入dex中。而以budlecompile开头的依赖(firstbundle、secondbundle)，他们的代码并没有在dex中。\",\"而在\",\"自定义初始化入口，这个类需要实现atlasprelauncher接口，回调时机是在atlas对系统进行hack之后，atlas框架开始初始化之前。\",\"说明\",\"这部分内容在编译期已经写到app的manifest中了，这也是\",\"那么，bundle的代码在哪里呢？\",\"配置\",\"随包发布但是不打入dex的代码\",\"需要打入dex的代码\",\"额外的配置\",\"首先appli\",\"首先，贴一张反编译后的manifest\"],\"code_read/atlas_start/atlas_start_1.html\":[\"\\\"com.taobao.demo.demoprelaunch\\\";\",\"\\\"com.taobao.firstbundle\\\";\",\"&&\",\"'com.taobao.demo.demoprelaunch'\",\"(atlasprelauncher)\",\"(build.version.sdk_int==25&&build.version.preview_sdk_int>0)){\",\"(contentprovider)cl.loadclass(info.name).newinstance();\",\"(providerinfo\",\"(string)\",\");\",\"...\",\"//\",\"//...\",\"//...一些逻辑\",\"//1.\",\"//2.\",\"//2.1\",\"//2.2\",\"//2.3\",\"//2.4\",\"//3.\",\"//4.\",\"//atlashacks.java\",\"//bridgeapplicationdelegate.java\",\"//packagemanagerdelegate.java\",\"//读取配置项\",\"1.\",\"2.\",\"3.\",\"4\",\"5\",\"5步。\",\"6.\",\":\",\"=\",\"@overrid\",\"['com.taobao.firstbundle']\",\"activitymanag\",\"activitymanagerdeleg\",\"activitymanagerdelegate();\",\"activitymanagernative.gdefault.get\",\"activitymanagerproxi\",\"activitymanagerproxy);\",\"activitythread\",\"activitythread.field(\\\"mallapplications\\\").ofgenerictype(arraylist.class);\",\"activitythread.field(\\\"minstrumentation\\\").oftype(instrumentation.class);\",\"activitythread.minstrument\",\"activitythread.mloadedapk.mclassload\",\"activitythread;\",\"activitythread_currentactivitythread;\",\"activitythread_mallappl\",\"activitythread_minstrument\",\"activitythread_minstrumentation;\",\"activitythreadhook\",\"allclasses()\",\"allclasses();\",\"allconstructors();\",\"allfields()\",\"allfields();\",\"allmethods();\",\"am\",\"android.app.activitythread$h.mcallback\",\"androidhack.hackh();\",\"androidhack.injectclassloader(packagename,\",\"androidhack.injectinstrumentationhook(new\",\"appinfo\",\"appinfo.metadata.getboolean(\\\"multidex_enable\\\");\",\"appinfo.metadata.getstring(\\\"real_application\\\");\",\"application,boolean\",\"application.getbasecontext()));\",\"application_attach;\",\"applicationinfo\",\"applicationpackagemanag\",\"applicationpackagemanager.getdeclaredfield(\\\"mpm\\\");\",\"assertionarrayexcept\",\"assertionarrayexception,\",\"assetmanager_addassetpath;\",\"atlas.getinstance().init(mrawapplication,\",\"atlas.init\",\"atlas.java\",\"atlasbridgeapplication.attachbasecontext\",\"atlashacks.activitythread$appbinddata_providers.get(mboundapplication);\",\"atlashacks.activitythread$appbinddata_providers.set(mboundapplication,null);\",\"atlashacks.activitythread_mboundapplication.get(activitythread);\",\"atlashacks.defineandverifi\",\"atlashacks.defineandverify();\",\"atlashacks.singleton_minstance.hijack(gdefault,\",\"atlasprelaunch\",\"atlasprelauncher实际上是一个接口，供接入者使用。在这个点，atlas还没有开始对系统进行hook，仍然是android原生态的运行时环境。\",\"atlas{\",\"atlas不一样，它是在编译期就已经各个bundle的manifest写入到apk中。所以运行时，bundle中的组件可以和常规声明的组件一样正常运行，不用再做额外的处理。\",\"atlas之启动过程(一)\",\"atlas整个启动过程的时序如下图所示，本篇只关注下图中的1\",\"attachbasecontext\",\"attachbasecontext(){\",\"attachbasecontext(context\",\"autostartbundl\",\"autostartbundles;\",\"base)\",\"boolean\",\"bridgeapplicationdelegate(appl\",\"bridgeapplicationdelegate.\",\"bridgeapplicationdelegate.java\",\"bridgeapplicationdelegateclazz\",\"bridgeapplicationdelegateclazz.getconstructor(partypes);\",\"bridgeapplicationdelegateclazz.getdeclaredmethod(\\\"attachbasecontext\\\");\",\"c.getclassloader();\",\"cl\",\"class\",\"class.forname(\\\"android.app.applicationpackagemanager\\\");\",\"class.forname(\\\"android.content.pm.ipackagemanager\\\");\",\"class.forname(prelaunchstr).newinstance();\",\"class[]{ipackagemanagerclass},\",\"con\",\"con.newinstance(this,getprocessname(...);\",\"constructor\",\"context){\",\"context,\",\"context,iactivitymanager.contentproviderhold\",\"context;\",\"cpi\",\"cpi,...);\",\"defineandverify()\",\"delegateclassload\",\"delegatepackagemanager(context\",\"demoapplication。\",\"e){}\",\"except\",\"field\",\"field.get(frameworkpropertiesclazz);\",\"field.get(manager);\",\"field.set(manager,\",\"field.setaccessible(true);\",\"fieldname){\",\"final\",\"frameworkproperti\",\"frameworkproperties.java\",\"frameworkpropertiesclazz.getdeclaredfield(fieldname);\",\"frameworkproperties{\",\"gdefault\",\"gdefault=atlashacks.activitymanager_iactivitymanagersingleton.get(atlashacks.activitymanager.getmclass());\",\"gdefault=atlashacks.activitymanagernative_gdefault.get(atlashacks.activitymanagernative.getmclass());\",\"getbasecontext().getclassloader().loadclass(\\\"android.taobao.atlas.bridge.bridgeapplicationdelegate\\\");\",\"getframeworkproperty(str\",\"h\",\"hack.hackedconstructor\",\"hack.into(\\\"android.app.activitymanager\\\");\",\"hack.into(\\\"android.app.activitythread\\\");\",\"hack.into(\\\"android.app.loadedapk\\\");\",\"hack.into(resources.class);\",\"hackassertionexcept\",\"hackedclass\",\"hackedfield\",\"hackedmethod\",\"holder,\",\"hook\",\"hook之前准备工作\",\"hook之前的准备工作\",\"hook点\",\"iactivitymanager.contentproviderhold\",\"if(build.version.sdk_int>25\",\"if(mboundapplication_provider!=nul\",\"if(multidexenable){\",\"info,...)\",\"init(appl\",\"installcontentproviders(context\",\"installprovider(context\",\"installprovider(context,\",\"instrumentationhook\",\"instrumentationhook(androidhack.getinstrumentation(),\",\"ipackagemanagerclass\",\"java.lang.classload\",\"launcher\",\"launcher.initbeforeatlas(mrawapplication.getbasecontext());\",\"list\",\"loadedapk\",\"loadedapk;\",\"loadedapk_mapplication;\",\"loadedapk_mclassload\",\"loadedapk_mclassloader;\",\"loadedapk_mresources;\",\"localprovid\",\"manag\",\"mbasecontext\",\"mbasecontext.getpackagemanager();\",\"mboundappl\",\"mboundapplication_provid\",\"mboundapplication_provider.size()>0){\",\"mbridgeapplicationdeleg\",\"method\",\"method.invoke(mbridgeapplicationdelegate);\",\"misupdated);\",\"mpackagemanagerproxyhandl\",\"mpackagemanagerproxyhandler);\",\"mproxypm\",\"mproxypm);\",\"mrawappl\",\"mrawapplication.get...;\",\"mrealapplicationnam\",\"multidex.install(mrawapplication);\",\"multidexen\",\"new\",\"newclassloader);\",\"null,\",\"null;\",\"object\",\"packagemanag\",\"packagemanagerdelegate.delegatepackagemanager(\",\"packagemanagerproxyhandler(rawpm);\",\"packageparser_constructor;\",\"prelaunch\",\"prelaunch;\",\"prelaunchstr\",\"privat\",\"protect\",\"providerinfo\",\"providers)\",\"proxy.newproxyinstance(mbasecontext.getclassloader(),\",\"public\",\"rawapplication...){\",\"rawapplication.getbasecontext()\",\"rawapplication;\",\"rawpm\",\"reset)\",\"resourc\",\"resources;\",\"return\",\"runtimevariables.getframeworkproperty(\\\"prelaunch\\\");\",\"runtimevariables.java\",\"static\",\"static{\",\"string\",\"super.attachbasecontext(base);\",\"tbuildconfig\",\"throw\",\"tri\",\"void\",\"{\",\"||\",\"}\",\"}catch(throw\",\"}else{\",\"上篇先到这里，各位先喝口水，再来下篇的分析。\",\"为了实现这三个目标，会在系统关键调用的地方进行hook。比如，为了能够动态加载class，通常都会对classloader上动一些手脚，resource也是类似。\",\"为什么会是atlasbridgeapplication呢，manifest中明明写的很清楚\",\"为什么这么做?回顾一下app启动的流程\",\"事实上为了接入的方便，atlas在编译期就替换了入口application。不过，atlas保证在运行期时会调用demoapplication的相关方法。\",\"什么情况，怎么什么都没有?\",\"什么时候写入又是在哪里配置\",\"从反编译后的代码可以看到，\\\"prelaunch\\\"对应的内容是com.taobao.demo.demoprelaunch,那么这个值是在\",\"先看bridgeapplicationdelegate的构造方法。\",\"入口\",\"准备工作做好之后，就是初始化了。\",\"函数中的hook点\",\"函数实现大概分为四个部分，也是本篇文章的重点关注部分\",\"函数通过“prelaunch”字段读取一个类名，反射该类上的initbeforeatlas方法。\",\"初始化atla\",\"动态代理pm\",\"动态加载class\",\"动态加载资源\",\"反射pm\",\"反射并构造bridgeapplicationdelegate的实例\",\"可以看到，代码虽长，但其实就只干了两件事。\",\"可以看到，函数是根据在manifest中登记的provider信息，实例化对象。\",\"可以看到，在第4步和第7步两个关键调用之间，第5步调用了函数installcontentproviders,跟进去看一下。\",\"可以看到，这段代码的核心思想就是将系统的pm，替换为我们实现的packagemanagerproxyhandler。我们先不关注packagemanagerproxyhandler的实现，接着看bridgeapplicationdelegate中函数attachbasecontext的实现。\",\"和frameworkproperties中的字段完美对应。\",\"回调预留接口\",\"回过头来，我们看看atlas为了实现上述目的，做了哪些准备工作。在跟进defineandverify函数的实现之前，先看一下atlashacks类中定义的字段\",\"在开始分析之前，我们要知道，android上动态加载方案，始终都绕不过三个关键的点:\",\"在第2步的2.4部分，对provider进行了处理\",\"处理class，hook\",\"处理provid\",\"处理四大组件\",\"处理资源，hook\",\"大家回想一下，在之前atlas之gradle配置中提到过，atlas的gradle插件在编译期搞了很多事情，我们看gradle中的设置\",\"实例\",\"实现很简单，读取frameworkproperties上的静态属性字段，接着跟进。\",\"实际上是demoapplication,即app工程在manifest中指定的启动路径。\",\"实际上这四个级别的函数调用，对应之前定义的字段，为这些字段进行赋值。\",\"当然不是\",\"我们也一个来看。\",\"我们看一下atlasbridgeapplication中的相关方法\",\"我们看一下反编译后的manifest\",\"我们都知道，app的入口是application，那么atlas的入口application是什么呢，看一下app模块中manifest中的定义\",\"所谓反常即为💊，直接看反编译后的代码\",\"执行bridgeapplicationdelegate的attachbasecontext方法\",\"执行bridgeapplicationdelegate的attachbasecontext方法。\",\"执行到这里时，atlas框架的准备工作完成，接下来，就是整个框架的初始化了。\",\"捋清楚这几个参数之后，往下看atlas框架初始化实现\",\"换classload\",\"换instrumentatio\",\"插件化的核心思想其实是埋坑机制+借尸还魂\",\"收集了所有provider的信息，然后调用installprovider函数\",\"时序图中的第4步，即bridgeapplicationdelegate的attachbasecontext方法中，，做了一个接口回调。\",\"是true，这个在gradle中可配\",\"替换pm\",\"构造bridgeapplicationdelegate对象\",\"概述\",\"没什么内容，直接跟进delegatepackagemanager的函数实现\",\"现在，在看defineandverify函数的实现\",\"的呢？\",\"看样子，是demoappl\",\"真的是这样的吗？\",\"第4行代码读取provider数据，如果有provider信息的话，则在第6行从系统删除，让系统认为apk并没有申请任何provider。\",\"给这段代码点个赞，非常的干净和清晰。代码定义了atlas框架所需要hook的所有的类、方法、属性等等字段。\",\"编译\",\"能够让动态代码中的四大组件在android上正常跑起来\",\"运行三个阶段，放一张图捋一下关系。\",\"这个部分牵涉开发\",\"这些字段进行初始化赋值工作。\",\"这几个函数的代码并不复杂，是对定义的class、field、method和contructor\",\"这段代码，就是对系统关键节点进行了hook，具体的hook实现这里就不贴出了，如果感兴趣，可以参考demo源码以及田维术的blog，如何hook，以及为什么在这里hook，在文章中都讲的非常清楚。\",\"这里多提一句，在四大组件的处理上，atals与插件化有着很大的差异。\",\"那么这个prelaunch的字段在哪里定义的呢，我们反推一下。\",\"那么问题来了，有些provider是存在于bundle中的，主dex中并不存在。如果不处理，在这里程序会因为classnotfind崩溃。所以这里要先清除掉provier的信息，延迟加载。\",\"首先是读取manifest中的配置数据multidexenable和mrealapplicationname，这两个数据也是在编译期由atlas插件写到manifest中的。\",\"：通过预先在manifest中预留n个组件坑，在runtime时，通过“借尸还魂”实现四大组件的运行。\"],\"code_read/atlas_start/atlas_start_2.html\":[\"\\\"[{\\\\\\\"activities\\\\\\\":[\\\\\\\"com.taobao.firstbundle.firstbundleactivity\\\\\\\"],\\\\\\\"contentproviders\\\\\\\":[],\\\\\\\"dependency\\\\\\\":[],\\\\\\\"isinternal\\\\\\\":true,\\\\\\\"pkgname\\\\\\\":\\\\\\\"com.taobao.firstbundle\\\\\\\",\\\\\\\"receivers\\\\\\\":[],\\\\\\\"services\\\\\\\":[\\\\\\\"com.taobao.firstbundle.firstbundleservice\\\\\\\"],\\\\\\\"version\\\\\\\":\\\\\\\"1.0.0@unspecified\\\\\\\"},{\\\\\\\"activities\\\\\\\":[\\\\\\\"com.taobao.secondbundle.secondbundleactivity\\\\\\\",\\\\\\\"com.taobao.secondbundlelibrary.secondbundleshareactivity\\\\\\\"],\\\\\\\"contentproviders\\\\\\\":[],\\\\\\\"dependency\\\\\\\":[],\\\\\\\"isinternal\\\\\\\":true,\\\\\\\"pkgname\\\\\\\":\\\\\\\"com.taobao.secondbundle\\\\\\\",\\\\\\\"receivers\\\\\\\":[],\\\\\\\"services\\\\\\\":[],\\\\\\\"version\\\\\\\":\\\\\\\"1.0.0@unspecified\\\\\\\"},{\\\\\\\"activities\\\\\\\":[\\\\\\\"com.taobao.remotebunle.remotebundleactivity\\\\\\\"],\\\\\\\"contentproviders\\\\\\\":[],\\\\\\\"dependency\\\\\\\":[],\\\\\\\"isinternal\\\\\\\":false,\\\\\\\"pkgname\\\\\\\":\\\\\\\"com.taobao.remotebunle\\\\\\\",\\\\\\\"receivers\\\\\\\":[],\\\\\\\"services\\\\\\\":[],\\\\\\\"version\\\\\\\":\\\\\\\"1.0.0@unspecified\\\\\\\"},{\\\\\\\"activities\\\\\\\":[],\\\\\\\"contentproviders\\\\\\\":[],\\\\\\\"dependency\\\\\\\":[],\\\\\\\"isinternal\\\\\\\":true,\\\\\\\"pkgname\\\\\\\":\\\\\\\"com.taobao.publicbundle\\\\\\\",\\\\\\\"receivers\\\\\\\":[],\\\\\\\"services\\\\\\\":[],\\\\\\\"version\\\\\\\":\\\\\\\"1.0.0@unspecified\\\\\\\"}]\\\";\",\"\\\"com.taobao.firstbundle\\\";\",\"(application)\",\"(int\",\"(string)\",\"(string)runtimevariables.getframeworkproperty(\\\"bundleinfo\\\");\",\",继续\",\".getclassloader().loadclass(mrealapplicationname).newinstance();\",\".invoke(mrealapplication,mrawapplication.getbasecontext());\",\"//\",\"//...\",\"//7.2\",\"//7.3\",\"//7.4\",\"//7.5.\",\"//7.6\",\"//artutils.java\",\"//dalvikutils.java\",\"//replac\",\"//异步安装bundl\",\"//读取配置\",\"0;\",\"10\",\"10.\",\"6\",\"6.\",\"7.\",\"7.1\",\"7.2\",\"7.2部分，为了保证demoapplication能够像正常声明的application一样正常工作，做了大量的hook。这里不关注具体hook实现，只给出hook后的映射，感兴趣的童鞋可以自行研究。\",\"7.3\",\"7.4\",\"8.\",\"9.\",\"9.3\",\"9.4\",\"9.7\",\"9.8\",\"=\",\"@overrid\",\"activities;\",\"activitythread.mallappl\",\"activitythread.minitialappl\",\"adjustlinearalloc();\",\"adjustlinearalloc方法\",\"android.taobao.atlas.framework;\",\"application.attach\",\"applicationname；\",\"atlas.getinstance().startup(mrealapplication,misupdated);\",\"atlas.startup\",\"atlasbridgeapplication.java\",\"atlashacks.activitythread$appbinddata_providers.set(mboundapplication,mboundapplication_provider);\",\"atlashacks.activitythread_installcontentproviders.invoke(activitythread,mrealapplication,mboundapplication_provider);\",\"atlashacks.activitythread_mboundapplication.get(activitythread);\",\"atlashacks.application_attach\",\"atlashacks.application_attach.invoke(mrealapplication,mrawapplication.getbasecontext());\",\"atlashacks.contextimpl_mpackageinfo.get(mrawapplication.getbasecontext());\",\"atlashacks.contextimpl_setoutercontext.invoke(\",\"atlashacks.contextimpl_setoutercontext.invoke(mrawapplication.getbasecontext(),\",\"atlasz之启动过程(一)\",\"atlas之bundle加载过程，这里不在讨论。\",\"atlas之启动过程(二)\",\"atlas获得了所有bundle的信息\",\"attach(context\",\"attachbasecontext(context);\",\"autostartbundl\",\"autostartbundle.split(\\\",\\\");\",\"autostartbundles;\",\"basecontext.moutercontext\",\"basecontext.mpackageinfo.mappl\",\"boolean\",\"boolean.valueof(artutils.init(context,\",\"boolean.valueof(dalvikutils.init());\",\"bridgeapplicationdelegate.java\",\"bridgeapplicationdelegate.oncr\",\"bundl\",\"bundleinfo\",\"bundleinfostr\",\"bundleinfo{\",\"bundlelist\",\"bundlelisting();\",\"bundlelistingutil.parsearray(bundleinfostr);\",\"bundle的加载过程和加载触发时机请参考\",\"class\",\"content\",\"contentproviders;\",\"context)\",\"context,\",\"contextimp.mpackageinfo\",\"contextimpl.getimpl(context).mpackageinfo;\",\"contextimpl.moutercontextt\",\"demoappl\",\"demoapplication.attach\",\"demoapplication.java\",\"demoapplication.oncr\",\"dependency;\",\"final\",\"frameworkproperti\",\"hashmap\",\"hookedjavavm)\",\"hookedjavavm));\",\"if(!textutils.isempty(bundleinfostr))\",\"if(isdalvik())\",\"if(vmutil.is_vm_art)\",\"info\",\"ingor\",\"init()\",\"init(context\",\"initbundleinfobyversionifneed(){\",\"instal\",\"int\",\"linkedhashmap\",\"list\",\"listing.setbundles(infos);\",\"listing;\",\"mboundappl\",\"mbridgeapplicationdelegate.getclass().getdeclaredmethod(\\\"oncreate\\\");\",\"mcurrentbundlelist\",\"method\",\"method.invoke(mbridgeapplicationdelegate);\",\"mloadedapk\",\"mpackageinfo\",\"mrawapplication.getbasecontext()\",\"mrawapplication.getbasecontext(),\",\"mrealappl\",\"mrealapplication);\",\"mrealapplication.attach\",\"mrealapplication.oncreate();\",\"mrealapplicationname实际上是指com.taobao.demo.demoapplication。在这里，构造出了app工程中指定application的对象实例。\",\"mrealapplication实际上就是demoapplication,反射执行application的attach方法,即第8步。\",\"nativeinit();\",\"nativeinit(...);\",\"new\",\"object\",\"oncreat\",\"oncreate()\",\"oncreate(){\",\"packag\",\"patchifpossible()\",\"pkgname;\",\"privat\",\"provid\",\"public\",\"receivers;\",\"replac\",\"return\",\"runtimevariables.getframeworkproperty(\\\"autostartbundles\\\");\",\"services;\",\"started(){\",\"startup\",\"static\",\"string\",\"string[]\",\"success\",\"super.oncreate();\",\"synchron\",\"system.loadlibrary(\\\"dalvikhack\\\");\",\"system.loadlibrary(\\\"dalvikpatch\\\");\",\"system.loadlibrary(\\\"dexinterpret\\\");\",\"todo\",\"void\",\"x\",\"xxx\",\"{\",\"}\",\"。\",\"为demoapplication创建一个loadedapk对象\",\"也就是说，在这一步，\",\"函数有点长，不过内容大概分为6块\",\"加载provid\",\"反射执行mrealapplication的attach方法\",\"可以看到，bundleinfo\",\"可以看到，函数是从runtimevariables读取字符串，之后解析成对象存储。很明显，这个字符串应该是配置之类的信息。在atals从gradle到apk中，我们提到过，atlas会在编译期间会分析bundle和gradle配置，将一些配置写入runtimevariables中。\",\"在atlas启动过程(上)的2.4小节中，为了防止在主dex中找不到bundle中的class,不得已延迟了对provider的加载。而在第5步中，atlas完成了对classloader等关键地方的hook。由于delegateclassloader的存在，此时进行加载provider，是不会出现问题的。\",\"在startup整个函数周期内，做的事情非常之多，重要的是第3、4、6、7和8步。\",\"字段是一堆json字段，解析后格式bundleinfo,保存着bundle的信息。\",\"实例applic\",\"实例化app工程中指定的mrealappl\",\"实现类\",\"执行app工程定义的demoapplication的oncreate方法。\",\"接上篇\",\"接着执行\",\"替换applic\",\"替换点\",\"概述\",\"步的启动过程。\",\"由7.3可知，mrealapplication实际上就是demoappl\",\"直接反射调用mbridgeapplicationdelegate的oncreate方法.\",\"看函数名，是针对art和dalvik工具类进行初始化。\",\"简化了大部分代码，只关注核心逻辑。代码读取runtimevariables上的字段autostartbundles,这个值是在gradle中配置的com.taobao.firstbundle，然后开始异步加载firstbundl\",\"至此，atlas启动过程的分析完成。\",\"调用demoapplication的attachbasecontext方法\",\"调用mrealapplication.oncreate方法\",\"首先加载dalvikpatchso,用途：\",\"，用途\"],\"code_read/atlas_bundle_load/atlas_bundle_load.html\":[\"!=\",\"!tmp.checkvalidate()){\",\"\\\":\\\";\",\"\\\"lib\\\");\",\"(\",\"((bundleimpl)\",\"(application)\",\"(autoload)\",\"(bundl\",\"(bundleimpl)\",\"(bundleinstaller.this)\",\"(event.gettype())\",\"(fileutils.getusablespace(environment.getdatadirectory())\",\"(impl\",\"(mlisten\",\"(stream\",\"(string\",\"(throwabl\",\");\",\")，暂时不关注，往下走\",\"*/\",\"+\",\"+=\",\"+system.getproperty(\\\"java.library.path\\\");\",\"/*loaded*/,\",\"//\",\"//..\",\"//...\",\"//ha\",\"/data/data/com.taobao.demo/files/storage/com.taobao.secondbundl\",\"/data/user/0/com.taobao.demo/files/storage/com.taobao.secondbundle/version.1/lib:/data/app/com.taobao.demo\",\"0:/*\",\"1\",\"1);\",\"1/lib/x86:/vendor/lib:/system/lib\",\"15\",\"16\",\"19\",\"5)\",\"7\",\"8\",\":\",\"=\",\"==\",\">=\",\"?\",\"@overrid\",\"activitygroupdelegate.java\",\"app\",\"app.oncreate();\",\"app;\",\"appclassnam\",\"applic\",\"applicationclass\",\"applicationclass.newinstance();\",\"applicationclassname,\",\"applicationinitexcept\",\"asyncstartactivity(container,key,bundlename,intent);\",\"asyncstartactivity最终调用了bundleutil的方法，我们直接看第4步\",\"atals中bundle加载过程\",\"atlas.getinstance().getbundle(bundlename)))==nul\",\"atlas.getinstance().getbundle(bundlename);\",\"atlas.getinstance().getbundle(str);\",\"atlasbundleinfomanager.instance().getbundleforcomponet(classname);\",\"atlasbundleinfomanager.instance().getbundleforcomponet(componentname);\",\"atlasbundleinfomanager.instance().getbundleinfo(b.getlocation());\",\"atlasbundleinfomanager.instance().getbundleinfo(location);\",\"atlasbundleinfomanager.instance().getdependencyforbundle(location);\",\"atlashacks.application_attach.invoke(app,\",\"atlas之bundle加载过程\",\"b\",\"b.getarchive().getarchivefile().getabsolutepath()\",\"b.getclassloader());\",\"boolean\",\"bundl\",\"bundle)\",\"bundle).optdexfile();\",\"bundle){\",\"bundle.getclassloader();\",\"bundle;\",\"bundleactivated,\",\"bundlearchive(location,bundledir,\",\"bundlechanged(fin\",\"bundleclassloader(this,dependencies,nativelibdir);\",\"bundlecontext\",\"bundlecontext(),\",\"bundledir\",\"bundledir,\",\"bundledisabled){\",\"bundleev\",\"bundleexcept\",\"bundleexception,\",\"bundleimpl\",\"bundleimpl(bundledir,\",\"bundleimpl(fin\",\"bundleimpl.java\",\"bundleimpl。由于secondbundle之前并没有加载进来，所以会执行到第3步asyncstartactivity方法。\",\"bundleinstal\",\"bundleinstaller.installlistener()\",\"bundleinstallerfetcher.obtaininstaller();\",\"bundlelifecyclehandl\",\"bundlelifecyclehandler.java\",\"bundlelisting.bundleinfo\",\"bundlenam\",\"bundlesname){\",\"bundlesname,\",\"bundleutil.java\",\"bundle代码初始化\",\"bundle加载完成后，第7步，在ui线程中回调了完成的接口，调用了startbundle方法又经过辗转调用，到了bundlelifecyclehandler的startd方法中。\",\"bundle加载过程\",\"call\",\"call();\",\"call(){\",\"case\",\"catch\",\"checkbundlearraystateasync(fin\",\"checkbundlestateasync\",\"cl)\",\"cl.loadclass(applicationclassname);\",\"class\",\"classload\",\"classloader.loadclass(classname);\",\"classname)\",\"classname,boolean\",\"classnotfoundexcept\",\"clazz\",\"clazz;\",\"com.taobao.secondbundle。\",\"container,str\",\"context,\",\"creat\",\"delegateclassloader.java\",\"delegateresources.addbundleresources(\",\"deliverytask\",\"deliverytask(boolean\",\"depend\",\"dependencies)\",\"dependencylibdir\",\"dependencylibdir;\",\"dexpatchversion);\",\"e)\",\"e.printstacktrace();\",\"enough\",\"event){\",\"execstartchildactivityintern\",\"execstartchildactivityinternal(viewgroup\",\"false;\",\"file\",\"file(impl.getarchive().getcurrentrevision().getrevisiondir(),\",\"file,version,true,\",\"final\",\"findclass(str\",\"for(str\",\"framework.bundles.put(location,\",\"framework.java\",\"framework.notifybundlelisteners(0\",\"getarchive().getcurrentrevision().getrevisiondir().getabsolutepath()+\\\"/lib\\\"+\\\":\\\"\",\"handler(looper.getmainlooper()).post(new\",\"handlerthread\",\"if(!textutils.isempty(bundlename)){\",\"if((tmp=((bundleimpl)\",\"if(atlasbundleinfomanager.instance().isinternalbundle(bundlename))\",\"if(dependencies!=null)\",\"if(impl!=null&&impl.checkvalidate())\",\"impl\",\"in)throw\",\"info\",\"info.getapplicationname();\",\"inputstream\",\"instal\",\"installbundlefromapk\",\"installbundlefromapk(bundlename);\",\"installer.installtransitivelyasync(bundlesname,\",\"installnewbundl\",\"installnewbundle(fin\",\"installnewbundle方法，直接看第9步\",\"installtask\",\"installtask,之后将任务提交给sbundlehandler。而sbundlehandler实际上关联的是一个handlerthread,所以，installtask是运行在单独的线程中的。\",\"intent\",\"intent){\",\"ioexception{\",\"key,\",\"lib/armeabi/libcom_taobao_secondbundle.so\",\"list\",\"listen\",\"load\",\"loaded(bundl\",\"loaded(event.getbundle());\",\"loadfrominstalledbundles(classname,false);\",\"loadfrominstalledbundles(str\",\"location,\",\"location...)\",\"long\",\"lowdiskexception(\\\"no\",\"mainactivity.java\",\"mlistener.onfinished();\",\"nativelibdir\",\"new\",\"newapplication(appclassname,\",\"newapplication(str\",\"notifi\",\"null)\",\"null){\",\"null,\",\"onfinished()\",\"optdexfil\",\"privat\",\"protect\",\"public\",\"r.id.navigation_dashboard:\",\"resolvebundl\",\"resolvebundle()\",\"resolvebundle();\",\"resourc\",\"return\",\"run()\",\"runnabl\",\"runnable()\",\"runtimevariables.androidapplication);\",\"runtimevariables.androidapplication.getapplicationinfo().nativelibrarydir+\\\":\\\"\",\"safe)\",\"sbundlehandler.post(installtask);\",\"space\",\"space\\\");\",\"started(bundl\",\"static\",\"str\",\"stream,...)\",\"stream,version,\",\"string\",\"string[]\",\"success\",\"switch\",\"switchact\",\"switchtoactivity(\\\"second\\\",\\\"com.taobao.secondbundle.secondbundleactivity\\\")\",\"sync){\",\"synchron\",\"system.currenttimemillis();\",\"this);\",\"this.arch\",\"this.classload\",\"throw\",\"time\",\"tmp.startbundle();\",\"tmp;\",\"todo\",\"true;\",\"try{\",\"ui\",\"void\",\"{\",\"||\",\"}\",\"});\",\"};\",\"}els\",\"}else{\",\"。。。\",\"中\",\"中的。\",\"为bundle创建一个classloader，在创建classloader的过程中\",\"为bundle创建了独立的classload\",\"从atlasbundleinfomanager上已加载的列表中找到对应bunde(在第在第10步中添加)\",\"从对应bundle上的classloader上加载对应的class。\",\"以在mainactivity中点击secondebundle为例\",\"值为\",\"入口\",\"函数很简单，获取bundle的信息，之后构造一个bundleimpl对象。\",\"函数首先创建了一个异步任务\",\"创建完bundlerclassloader后，在最后一行进行回调，这里的回调实现类是\",\"初始化过程\",\"到目前为止，第一部分分析完毕，我们进入第二部分\",\"到这里为止，整个bundle的加载、初始化过程分析完毕。\",\"剩余存储空间满足\",\"加载时机的触发逻辑\",\"加载过程\",\"参数\",\"又调用了\",\"可以看到，classloader先从bundle上去找的。而loadfrominstalledbundles逻辑如下:\",\"向ui线程提交一个任务，用于回调onfinish\",\"回到第10步\",\"回顾一下第二部分的运行时序\",\"在\",\"在atlas之启动过程(二)下中，解释过，application的attach方法最终会调用到attachbasecontext方法。\",\"在resolvebundle函数执行周期内，主要完成了两件事\",\"在第6行构造出bundle中注册的application对象，之后执行application的oncreate方法。对于appliation来说，似乎还差一个关键的attachbasecontext的入口函数调用，我们接着看构造过程。\",\"在这一步中，开始异步加载bundle，成功后，在主线程中回调onfinished(后面会提及),调用bundleimpl对象的startbundl方法，开始\",\"完成之后，回到第8步，执行optdexfile方法。\",\"实线箭头表示运行在主线程\",\"对应步骤\",\"将bundle中的资源添加到resource上\",\"将流程分为三大部分\",\"就是\",\"当两个条件都满足时，执行bundle的安装和optdexfile操作。\",\"指向\",\"指定bundle自身依赖so的路径\",\"指定依赖bundle所依赖so的路径\",\"整个第三部分运行在\",\"是内置bundl\",\"最后，大概看一下delegateclassloader加载bundle中class的过程。\",\"有两个参数需要注意一下\",\"来看bundleimpl的构造函数\",\"概述\",\"比如在demo中\",\"注意图中的箭头\",\"然后，根据bundlename，去查询bundle加载后的结构体\",\"的初始化过程。\",\"的实现。\",\"第5、6步，主要是各种逻辑判断，之后辗转调用到7步。直接看第7步deliverytask的函数实现。\",\"第一部分\",\"第三部分\",\"第二行函数将bundle的信息加入到已加载的列表中。\",\"第二部分\",\"线程中\",\"虚线箭头表示运行在handlerthread中\",\"触发时机\",\"说明\",\"调用了call函数\",\"资源处理实现说明\",\"辗调用，会执行到第2步execstartchildactivityinternal方法中\",\"这里有两个判断条件\",\"部分\",\"需要注意的是，第二部分整体是运行在\",\"首先创建了一个bundlearchive对象，bundlearchive持有bundledir和inputstream的引用，用来做dexopt的(\",\"首先，根据componentname即com.taobao.secondbundle.secondbundleactivity,查询bundle的名称。在atlas启动过程(下)中，我们知道atlasbundleinfomanager中存储了几乎所有bundle的信息，所以返回\",\"首先，根据类名加载对应的class，之后反射执行applciation的attach方法。\",\"，nativelibdir的\"]},\"length\":23},\"tokenStore\":{\"root\":{\"0\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}},\":\":{\"docs\":{},\"/\":{\"docs\":{},\"*\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"1\":{\"0\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\".\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}},\"2\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}},\":\":{\"3\":{\"9\":{\"docs\":{},\":\":{\"0\":{\"4\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}},\"docs\":{}},\"docs\":{}}},\"docs\":{}},\"docs\":{}}},\"4\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}},\"5\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}},\"6\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}},\"9\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}},\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.010810810810810811}},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602},\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"值\":{\"docs\":{},\":\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}},\"记\":{\"docs\":{},\"录\":{\"docs\":{},\"的\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"，\":{\"docs\":{},\"数\":{\"docs\":{},\"据\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}},\"@\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"1\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.021621621621621623}},\"@\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"@\":{\"3\":{\"1\":{\"docs\":{},\"j\":{\"docs\":{},\"v\":{\"8\":{\"6\":{\"docs\":{},\"q\":{\"docs\":{},\"v\":{\"docs\":{},\"t\":{\"1\":{\"docs\":{},\"g\":{\"docs\":{},\"c\":{\"docs\":{},\";\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"@\":{\"1\":{\"docs\":{},\"x\":{\"6\":{\"docs\":{},\"r\":{\"8\":{\"docs\":{},\"i\":{\"docs\":{},\"u\":{\"docs\":{},\"z\":{\"docs\":{},\"s\":{\"9\":{\"0\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\";\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}},\"docs\":{}},\"docs\":{}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}},\"docs\":{}},\"docs\":{}}}},\"docs\":{}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}},\"2\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}},\"docs\":{}}},\"1\":{\"docs\":{},\".\":{\"4\":{\"docs\":{},\".\":{\"1\":{\"1\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}},\"docs\":{}},\"docs\":{}}},\"docs\":{}}},\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625},\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.015384615384615385},\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"重\":{\"docs\":{},\"新\":{\"docs\":{},\"p\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"了\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\",\":{\"docs\":{},\"老\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"被\":{\"docs\":{},\"覆\":{\"docs\":{},\"盖\":{\"docs\":{},\"了\":{\"2\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"在\":{\"docs\":{},\"本\":{\"docs\":{},\"地\":{\"docs\":{},\"仓\":{\"docs\":{},\"库\":{\"docs\":{},\"做\":{\"docs\":{},\"了\":{\"docs\":{},\"一\":{\"docs\":{},\"份\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"是\":{\"docs\":{},\"否\":{\"docs\":{},\"和\":{\"docs\":{},\"远\":{\"docs\":{},\"程\":{\"docs\":{},\"仓\":{\"docs\":{},\"库\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"一\":{\"docs\":{},\"致\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"x\":{\"docs\":{},\"l\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}},\"x\":{\"6\":{\"docs\":{},\"r\":{\"8\":{\"docs\":{},\"i\":{\"docs\":{},\"u\":{\"docs\":{},\"z\":{\"docs\":{},\"s\":{\"9\":{\"0\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.016216216216216217}}}}},\"docs\":{}},\"docs\":{}}}}}},\"docs\":{}}},\"docs\":{}},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"/\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"/\":{\"docs\":{},\"x\":{\"8\":{\"6\":{\"docs\":{},\":\":{\"docs\":{},\"/\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"/\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\":\":{\"docs\":{},\"/\":{\"docs\":{},\"s\":{\"docs\":{},\"y\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"/\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}},\"docs\":{}}}}}}}},\"2\":{\"0\":{\"1\":{\"4\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}},\"docs\":{}},\"docs\":{}},\"1\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}},\"2\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}},\"docs\":{},\".\":{\"1\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}},\"2\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}},\"3\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}},\".\":{\"1\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"是\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"？\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}},\"3\":{\"docs\":{},\".\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"1\":{\"2\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}},\"docs\":{}},\"docs\":{}}}}},\"docs\":{}}},\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533},\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.015384615384615385},\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}},\"3\":{\"1\":{\"docs\":{},\"j\":{\"docs\":{},\"v\":{\"8\":{\"6\":{\"docs\":{},\"q\":{\"docs\":{},\"v\":{\"docs\":{},\"t\":{\"1\":{\"docs\":{},\"g\":{\"docs\":{},\"c\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}},\"docs\":{}}}}},\"docs\":{}},\"docs\":{}}}},\"docs\":{},\".\":{\"0\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}},\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}},\"4\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\".\":{\"0\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.012121212121212121}}},\"4\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}},\"docs\":{}}},\"5\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\".\":{\"0\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}},\".\":{\"7\":{\"docs\":{},\".\":{\"4\":{\"1\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}},\"docs\":{}},\"docs\":{}}},\"docs\":{}}},\"1\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}},\"docs\":{}},\"步\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"6\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\".\":{\"2\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"@\":{\"6\":{\"docs\":{},\".\":{\"2\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}},\"7\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\".\":{\"0\":{\"docs\":{},\".\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}},\"以\":{\"docs\":{},\"后\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"各\":{\"docs\":{},\"自\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"去\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"同\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"，\":{\"docs\":{},\"分\":{\"docs\":{},\"别\":{\"docs\":{},\"会\":{\"docs\":{},\"在\":{\"docs\":{},\"各\":{\"docs\":{},\"自\":{\"docs\":{},\"的\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"有\":{\"docs\":{},\"各\":{\"docs\":{},\"自\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"，\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"/\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"/\":{\"docs\":{},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"/\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}},\"1\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}},\"2\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"，\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"保\":{\"docs\":{},\"证\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"能\":{\"docs\":{},\"够\":{\"docs\":{},\"像\":{\"docs\":{},\"正\":{\"docs\":{},\"常\":{\"docs\":{},\"声\":{\"docs\":{},\"明\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"一\":{\"docs\":{},\"样\":{\"docs\":{},\"正\":{\"docs\":{},\"常\":{\"docs\":{},\"工\":{\"docs\":{},\"作\":{\"docs\":{},\"，\":{\"docs\":{},\"做\":{\"docs\":{},\"了\":{\"docs\":{},\"大\":{\"docs\":{},\"量\":{\"docs\":{},\"的\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"。\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"不\":{\"docs\":{},\"关\":{\"docs\":{},\"注\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"，\":{\"docs\":{},\"只\":{\"docs\":{},\"给\":{\"docs\":{},\"出\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"映\":{\"docs\":{},\"射\":{\"docs\":{},\"，\":{\"docs\":{},\"感\":{\"docs\":{},\"兴\":{\"docs\":{},\"趣\":{\"docs\":{},\"的\":{\"docs\":{},\"童\":{\"docs\":{},\"鞋\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"自\":{\"docs\":{},\"行\":{\"docs\":{},\"研\":{\"docs\":{},\"究\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"3\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}},\"4\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}},\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}},\"8\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\".\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}},\"9\":{\"docs\":{},\".\":{\"3\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}},\"4\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}},\"7\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}},\"8\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}},\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}},\"docs\":{},\"\\\"\":{\"1\":{\"4\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}},\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"\\\"\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\",\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.012422360248447204}}}},\"@\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"1\":{\"docs\":{},\"\\\"\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}},\"docs\":{}}},\"docs\":{}}},\"6\":{\"docs\":{},\"b\":{\"3\":{\"9\":{\"7\":{\"3\":{\"docs\":{},\"d\":{\"9\":{\"docs\":{},\"d\":{\"6\":{\"5\":{\"9\":{\"2\":{\"docs\":{},\"d\":{\"1\":{\"5\":{\"6\":{\"0\":{\"1\":{\"0\":{\"1\":{\"7\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"c\":{\"8\":{\"docs\":{},\"b\":{\"3\":{\"1\":{\"docs\":{},\"b\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}},\"docs\":{}},\"docs\":{}}},\"docs\":{}}}}}}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}}},\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\":\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\":\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"\\\"\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}},\"1\":{\"docs\":{},\"\\\"\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}},\"docs\":{}}},\"docs\":{}}},\"2\":{\"docs\":{},\".\":{\"3\":{\"docs\":{},\".\":{\"3\":{\"docs\":{},\".\":{\"docs\":{},\"b\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"2\":{\"docs\":{},\"\\\"\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}},\"docs\":{}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\":\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"b\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"\\\"\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.012422360248447204}}},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\"\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602},\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"\\\"\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"\\\"\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\":\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"，\":{\"docs\":{},\"默\":{\"docs\":{},\"认\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"是\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}},\":\":{\"2\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"\\\"\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\":\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"=\":{\"docs\":{},\">\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"2\":{\"docs\":{},\")\":{\"docs\":{},\"\\\"\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"\\\"\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.02127659574468085}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"[\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}},\"]\":{\"docs\":{},\",\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"~\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}},\"e\":{\"8\":{\"5\":{\"7\":{\"5\":{\"5\":{\"7\":{\"docs\":{},\"c\":{\"docs\":{},\"c\":{\"9\":{\"2\":{\"4\":{\"docs\":{},\"f\":{\"5\":{\"0\":{\"3\":{\"docs\":{},\"a\":{\"7\":{\"3\":{\"0\":{\"4\":{\"2\":{\"1\":{\"8\":{\"4\":{\"6\":{\"9\":{\"7\":{\"3\":{\"3\":{\"docs\":{},\"a\":{\"2\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}},\"docs\":{}}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}}},\"docs\":{}},\"docs\":{}},\"docs\":{}}},\"docs\":{}},\"docs\":{}},\"docs\":{}}}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\"\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.02127659574468085}}}}}}}},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}},\"k\":{\"docs\":{},\"g\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}},\"s\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"\\\"\":{\"1\":{\"docs\":{},\"l\":{\"docs\":{},\"x\":{\"docs\":{},\"l\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"f\":{\"3\":{\"docs\":{},\"p\":{\"docs\":{},\"h\":{\"docs\":{},\"s\":{\"9\":{\"docs\":{},\"d\":{\"docs\":{},\"j\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"j\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}},\"docs\":{}}}}},\"docs\":{}}}},\"docs\":{}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"\\\"\":{\"1\":{\"docs\":{},\"x\":{\"6\":{\"docs\":{},\"r\":{\"8\":{\"docs\":{},\"i\":{\"docs\":{},\"u\":{\"docs\":{},\"z\":{\"docs\":{},\"s\":{\"9\":{\"0\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}},\"docs\":{}},\"docs\":{}}}}}},\"docs\":{}}},\"docs\":{}}},\"3\":{\"1\":{\"docs\":{},\"j\":{\"docs\":{},\"v\":{\"8\":{\"6\":{\"docs\":{},\"q\":{\"docs\":{},\"v\":{\"docs\":{},\"t\":{\"1\":{\"docs\":{},\"g\":{\"docs\":{},\"c\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}},\"docs\":{}}}}},\"docs\":{}},\"docs\":{}}}},\"docs\":{}},\"docs\":{}}}}}}}},\"q\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\"_\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"\\\"\":{\"1\":{\"docs\":{},\"l\":{\"docs\":{},\"x\":{\"docs\":{},\"l\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"\\\"\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"\\\"\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"\\\"\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"@\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"\\\"\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.010810810810810811}}}},\"2\":{\"docs\":{},\"\\\"\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"_\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"v\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.02127659574468085}}}}}}}}}},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\":\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\":\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"s\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"(\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"@\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"=\":{\"docs\":{},\">\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"@\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}},\"[\":{\"docs\":{},\"{\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"g\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"@\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"}\":{\"docs\":{},\",\":{\"docs\":{},\"{\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"g\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"@\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"}\":{\"docs\":{},\",\":{\"docs\":{},\"{\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"g\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"@\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"}\":{\"docs\":{},\",\":{\"docs\":{},\"{\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"g\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\",\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"@\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"}\":{\"docs\":{},\"]\":{\"docs\":{},\"\\\"\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\":\":{\"docs\":{},\"\\\"\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}},\"'\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"'\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\":\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\":\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"8\":{\"docs\":{},\"@\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"'\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"'\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"'\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}},\"'\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}},\"和\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"'\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"'\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}},\"s\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\":\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}},\":\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00847457627118644}}}}}}}}}}},\"s\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"s\":{\"docs\":{},\"'\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00847457627118644}}}}}}}}},\"/\":{\"docs\":{},\"/\":{\"1\":{\"docs\":{},\".\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.005758157389635317}}}},\"2\":{\"docs\":{},\".\":{\"1\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"2\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"3\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"4\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}}},\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.005758157389635317}}}},\"3\":{\"docs\":{},\".\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}}}},\"4\":{\"docs\":{},\".\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}},\"7\":{\"docs\":{},\".\":{\"2\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}},\"3\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}},\"4\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}},\"5\":{\"docs\":{},\".\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}},\"6\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}},\"docs\":{}}},\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.005221932114882507},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.007677543186180422},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}},\".\":{\"docs\":{},\".\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\".\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.012711864406779662},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.019193857965451054},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.012539184952978056},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.016042780748663103}},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}},\"声\":{\"docs\":{},\"明\":{\"docs\":{},\"为\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"不\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"用\":{\"docs\":{},\"到\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"核\":{\"docs\":{},\"心\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"k\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}},\"设\":{\"docs\":{},\"置\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}},\"注\":{\"docs\":{},\"意\":{\"docs\":{},\"不\":{\"docs\":{},\"能\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}},\"自\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"时\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"等\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"k\":{\"docs\":{},\"n\":{\"docs\":{},\"o\":{\"docs\":{},\"w\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"仅\":{\"docs\":{},\"供\":{\"docs\":{},\"示\":{\"docs\":{},\"例\":{\"docs\":{},\"，\":{\"docs\":{},\"与\":{\"docs\":{},\"实\":{\"docs\":{},\"际\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"差\":{\"docs\":{},\"异\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}},\"重\":{\"docs\":{},\"要\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.018633540372670808}}}},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"增\":{\"docs\":{},\"加\":{\"docs\":{},\"判\":{\"docs\":{},\"断\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{},\"，\":{\"docs\":{},\"打\":{\"docs\":{},\"出\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"类\":{\"docs\":{},\"型\":{\"docs\":{},\"的\":{\"docs\":{},\"定\":{\"docs\":{},\"制\":{\"docs\":{},\"包\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.02127659574468085}}}}}}}}}}}}}}}}}}}}},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}},\"版\":{\"docs\":{},\"本\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"的\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}},\"基\":{\"docs\":{},\"线\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"唯\":{\"docs\":{},\"一\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"版\":{\"docs\":{},\"本\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.005758157389635317}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"读\":{\"docs\":{},\"取\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\"项\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}}}}}}},\"异\":{\"docs\":{},\"步\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}},\"h\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"/\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"/\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"g\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"/\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"/\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{\"principle-intro/File_architecture_runtime.html\":{\"ref\":\"principle-intro/File_architecture_runtime.html\",\"tf\":0.1}}}}}}}}}}}}},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{\"principle-intro/File_architecture_runtime.html\":{\"ref\":\"principle-intro/File_architecture_runtime.html\",\"tf\":0.1}}}}}}}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"principle-intro/File_architecture_runtime.html\":{\"ref\":\"principle-intro/File_architecture_runtime.html\",\"tf\":0.1}}}}}}}}}}}}}}}}}}},\"/\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"/\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"/\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"$\":{\"docs\":{},\"{\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"_\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"g\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"_\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"}\":{\"docs\":{},\"/\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"z\":{\"docs\":{},\"i\":{\"docs\":{},\"p\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.010810810810810811}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"\\\\\":{\"docs\":{},\"$\":{\"docs\":{},\"{\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"g\":{\"docs\":{},\"}\":{\"docs\":{},\"/\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"/\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"/\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.010810810810810811}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"/\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"/\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"/\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"/\":{\"0\":{\"docs\":{},\"/\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"/\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"/\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"/\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"/\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"/\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\":\":{\"docs\":{},\"/\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"/\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"/\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}},\"*\":{\"docs\":{},\"*\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"*\":{\"docs\":{},\"/\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"d\":{\"docs\":{},\"/\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"/\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"/\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"/\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"/\":{\"docs\":{},\"，\":{\"docs\":{},\"并\":{\"docs\":{},\"将\":{\"docs\":{},\"上\":{\"docs\":{},\"述\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"p\":{\"docs\":{},\"u\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"到\":{\"docs\":{},\"上\":{\"docs\":{},\"述\":{\"docs\":{},\"路\":{\"docs\":{},\"径\":{\"docs\":{},\"中\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"f\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}},\"i\":{\"docs\":{},\"m\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}},\"=\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.02247191011235955},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.013054830287206266},\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602},\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693},\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.0425531914893617},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.025423728813559324},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0671785028790787},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.05956112852664577},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.049910873440285206}},\"[\":{\"docs\":{},\"'\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"'\":{\"docs\":{},\"]\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}},\"x\":{\"docs\":{},\"x\":{\"docs\":{},\"x\":{\"docs\":{},\"'\":{\"docs\":{},\"]\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}},\"=\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.010067114093959731},\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00847457627118644}},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{\"principle-intro/Apk_architecture.html\":{\"ref\":\"principle-intro/Apk_architecture.html\",\"tf\":0.07142857142857142},\"update/guide.html\":{\"ref\":\"update/guide.html\",\"tf\":0.2}},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"，\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"的\":{\"docs\":{},\"k\":{\"docs\":{},\"e\":{\"docs\":{},\"y\":{\"docs\":{},\"以\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"开\":{\"docs\":{},\"头\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"端\":{\"docs\":{},\"测\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"库\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"_\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"；\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}},\":\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"=\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\"\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"=\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"x\":{\"docs\":{},\"x\":{\"docs\":{},\"\\\"\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}},\"跨\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"模\":{\"docs\":{},\"块\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"互\":{\"docs\":{},\"相\":{\"docs\":{},\"通\":{\"docs\":{},\"信\":{\"docs\":{},\"的\":{\"docs\":{},\"几\":{\"docs\":{},\"种\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"$\":{\"docs\":{},\"h\":{\"docs\":{},\".\":{\"docs\":{},\"m\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"k\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\".\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"h\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"j\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"(\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"x\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.013422818791946308},\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}},\"只\":{\"docs\":{},\"要\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"重\":{\"docs\":{},\"启\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"p\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}},\"l\":{\"docs\":{},\"i\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.012121212121212121},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154},\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00847457627118644}},\"c\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0053475935828877}},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"被\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"实\":{\"docs\":{},\"际\":{\"docs\":{},\"上\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"真\":{\"docs\":{},\"正\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"最\":{\"docs\":{},\"好\":{\"docs\":{},\"不\":{\"docs\":{},\"要\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"传\":{\"docs\":{},\"入\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"，\":{\"docs\":{},\"会\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"潜\":{\"docs\":{},\"在\":{\"docs\":{},\"的\":{\"docs\":{},\"风\":{\"docs\":{},\"险\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"设\":{\"docs\":{},\"计\":{\"docs\":{},\"是\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"尽\":{\"docs\":{},\"最\":{\"docs\":{},\"大\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"保\":{\"docs\":{},\"留\":{\"docs\":{},\"大\":{\"docs\":{},\"家\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"的\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"习\":{\"docs\":{},\"惯\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"里\":{\"docs\":{},\"用\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"这\":{\"docs\":{},\"种\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"，\":{\"docs\":{},\"因\":{\"docs\":{},\"为\":{\"docs\":{},\"是\":{\"docs\":{},\"不\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}},\",\":{\"docs\":{},\"b\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.005758157389635317}}}}}}}}}},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}},\"_\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"m\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"；\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\".\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}},\"/\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"/\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"检\":{\"docs\":{},\"查\":{\"docs\":{},\"是\":{\"docs\":{},\"否\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"有\":{\"docs\":{},\"多\":{\"docs\":{},\"个\":{\"docs\":{},\"进\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"进\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"出\":{\"docs\":{},\"现\":{\"docs\":{},\"了\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"类\":{\"docs\":{},\"被\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"了\":{\"docs\":{},\"，\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"在\":{\"docs\":{},\"该\":{\"docs\":{},\"类\":{\"docs\":{},\"中\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"里\":{\"docs\":{},\"的\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"类\":{\"docs\":{},\"，\":{\"docs\":{},\"因\":{\"docs\":{},\"为\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"是\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\",\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"报\":{\"docs\":{},\"了\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"n\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\",\":{\"docs\":{},\"理\":{\"docs\":{},\"论\":{\"docs\":{},\"上\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"除\":{\"docs\":{},\"了\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"相\":{\"docs\":{},\"关\":{\"docs\":{},\"的\":{\"docs\":{},\"类\":{\"docs\":{},\"外\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"都\":{\"docs\":{},\"应\":{\"docs\":{},\"该\":{\"docs\":{},\"是\":{\"docs\":{},\"被\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"吧\":{\"docs\":{},\"？\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.02127659574468085}}},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\".\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"_\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"_\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"的\":{\"docs\":{},\"包\":{\"docs\":{},\"名\":{\"docs\":{},\"、\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}},\".\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}},\"k\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}},\"结\":{\"docs\":{},\"构\":{\"docs\":{\"principle-intro/Apk_architecture.html\":{\"ref\":\"principle-intro/Apk_architecture.html\",\"tf\":10.071428571428571}},\"分\":{\"docs\":{},\"析\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}},\"构\":{\"docs\":{},\"建\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"升\":{\"docs\":{},\"级\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}},\"范\":{\"docs\":{},\"围\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"表\":{\"docs\":{},\"示\":{\"docs\":{},\"被\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"应\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"基\":{\"docs\":{},\"线\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"，\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"表\":{\"docs\":{},\"示\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"后\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"不\":{\"docs\":{},\"对\":{\"docs\":{},\",\":{\"docs\":{},\"m\":{\"docs\":{},\"v\":{\"docs\":{},\"n\":{\"docs\":{},\"仓\":{\"docs\":{},\"库\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"，\":{\"docs\":{},\"和\":{\"docs\":{},\"预\":{\"docs\":{},\"期\":{\"docs\":{},\"的\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{},\"同\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}},\"，\":{\"docs\":{},\"比\":{\"docs\":{},\"对\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"和\":{\"docs\":{},\"预\":{\"docs\":{},\"想\":{\"docs\":{},\"的\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{},\"同\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"t\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.024242424242424242}},\"设\":{\"docs\":{},\"备\":{\"docs\":{},\"上\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"会\":{\"docs\":{},\"根\":{\"docs\":{},\"据\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"（\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"永\":{\"docs\":{},\"远\":{\"docs\":{},\"是\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"基\":{\"docs\":{},\"线\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"）\":{\"docs\":{},\"把\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"g\":{\"docs\":{},\"s\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.010443864229765013}}},\",\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.010443864229765013}}}}},\"s\":{\"docs\":{},\"c\":{\"docs\":{},\"和\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"包\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.024242424242424242},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.016778523489932886},\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.015384615384615385},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.0211864406779661}},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00847457627118644}},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"字\":{\"docs\":{},\"段\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"指\":{\"docs\":{},\"定\":{\"docs\":{},\"为\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\"才\":{\"docs\":{},\"能\":{\"docs\":{},\"开\":{\"docs\":{},\"启\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"阶\":{\"docs\":{},\"段\":{\"docs\":{},\"的\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"扩\":{\"docs\":{},\"展\":{\"docs\":{},\"的\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"k\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"对\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"的\":{\"docs\":{},\"划\":{\"docs\":{},\"分\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"所\":{\"docs\":{},\"示\":{\"docs\":{},\":\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"哪\":{\"docs\":{},\"些\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}},\"是\":{\"docs\":{},\"伴\":{\"docs\":{},\"随\":{\"docs\":{},\"着\":{\"docs\":{},\"手\":{\"docs\":{},\"机\":{\"docs\":{},\"淘\":{\"docs\":{},\"宝\":{\"docs\":{},\"的\":{\"docs\":{},\"不\":{\"docs\":{},\"断\":{\"docs\":{},\"发\":{\"docs\":{},\"展\":{\"docs\":{},\"而\":{\"docs\":{},\"衍\":{\"docs\":{},\"生\":{\"docs\":{},\"出\":{\"docs\":{},\"来\":{\"docs\":{},\"的\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"于\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"上\":{\"docs\":{},\"的\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"化\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"也\":{\"docs\":{},\"叫\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"化\":{\"docs\":{},\"(\":{\"docs\":{},\"d\":{\"docs\":{},\"y\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"面\":{\"docs\":{},\"向\":{\"docs\":{},\"多\":{\"docs\":{},\"人\":{\"docs\":{},\"协\":{\"docs\":{},\"作\":{\"docs\":{},\"的\":{\"docs\":{},\"较\":{\"docs\":{},\"大\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"和\":{\"docs\":{},\"f\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"中\":{\"docs\":{},\"也\":{\"docs\":{},\"会\":{\"docs\":{},\"带\":{\"docs\":{},\"来\":{\"docs\":{},\"创\":{\"docs\":{},\"建\":{\"docs\":{},\"更\":{\"docs\":{},\"多\":{\"docs\":{},\"的\":{\"docs\":{},\"任\":{\"docs\":{},\"务\":{\"docs\":{},\"，\":{\"docs\":{},\"并\":{\"docs\":{},\"且\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"通\":{\"docs\":{},\"常\":{\"docs\":{},\"会\":{\"docs\":{},\"创\":{\"docs\":{},\"建\":{\"docs\":{},\"了\":{\"docs\":{},\"两\":{\"docs\":{},\"种\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\",\":{\"docs\":{},\"第\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"是\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"，\":{\"docs\":{},\"他\":{\"docs\":{},\"作\":{\"docs\":{},\"为\":{\"docs\":{},\"类\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"的\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"路\":{\"docs\":{},\"由\":{\"docs\":{},\"器\":{\"docs\":{},\"而\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"，\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"并\":{\"docs\":{},\"不\":{\"docs\":{},\"负\":{\"docs\":{},\"责\":{\"docs\":{},\"真\":{\"docs\":{},\"正\":{\"docs\":{},\"类\":{\"docs\":{},\"的\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"；\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"时\":{\"docs\":{},\"被\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"注\":{\"docs\":{},\"入\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"原\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"；\":{\"docs\":{},\"第\":{\"docs\":{},\"二\":{\"docs\":{},\"个\":{\"docs\":{},\"是\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"，\":{\"docs\":{},\"参\":{\"docs\":{},\"考\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"的\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"，\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"基\":{\"docs\":{},\"础\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"及\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}},\"开\":{\"docs\":{},\"源\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"主\":{\"docs\":{},\"要\":{\"docs\":{},\"包\":{\"docs\":{},\"括\":{\"docs\":{},\"以\":{\"docs\":{},\"下\":{\"docs\":{},\"几\":{\"docs\":{},\"个\":{\"docs\":{},\"模\":{\"docs\":{},\"块\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}},\".\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"g\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\"=\":{\"docs\":{},\"=\":{\"docs\":{},\"n\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"y\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"y\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"(\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}}}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"(\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{},\"m\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}},\"作\":{\"docs\":{},\"为\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"层\":{\"docs\":{},\"以\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"规\":{\"docs\":{},\"范\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"化\":{\"docs\":{},\"解\":{\"docs\":{},\"耦\":{\"docs\":{},\"的\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"。\":{\"docs\":{},\"在\":{\"docs\":{},\"一\":{\"docs\":{},\"定\":{\"docs\":{},\"层\":{\"docs\":{},\"度\":{\"docs\":{},\"上\":{\"docs\":{},\"清\":{\"docs\":{},\"晰\":{\"docs\":{},\"了\":{\"docs\":{},\"各\":{\"docs\":{},\"个\":{\"docs\":{},\"模\":{\"docs\":{},\"块\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"的\":{\"docs\":{},\"边\":{\"docs\":{},\"界\":{\"docs\":{},\"，\":{\"docs\":{},\"便\":{\"docs\":{},\"于\":{\"docs\":{},\"各\":{\"docs\":{},\"个\":{\"docs\":{},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"以\":{\"docs\":{},\"内\":{\"docs\":{},\"聚\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"不\":{\"docs\":{},\"断\":{\"docs\":{},\"的\":{\"docs\":{},\"演\":{\"docs\":{},\"化\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"_\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602},\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.02127659574468085}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"实\":{\"docs\":{},\"际\":{\"docs\":{},\"上\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"，\":{\"docs\":{},\"供\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"者\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"。\":{\"docs\":{},\"在\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"点\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"还\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"开\":{\"docs\":{},\"始\":{\"docs\":{},\"对\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"，\":{\"docs\":{},\"仍\":{\"docs\":{},\"然\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"原\":{\"docs\":{},\"生\":{\"docs\":{},\"态\":{\"docs\":{},\"的\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"时\":{\"docs\":{},\"环\":{\"docs\":{},\"境\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"及\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"，\":{\"docs\":{},\"暂\":{\"docs\":{},\"时\":{\"docs\":{},\"不\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"新\":{\"docs\":{},\"增\":{\"4\":{\"docs\":{},\"大\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"下\":{\"docs\":{},\"个\":{\"docs\":{},\"大\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"建\":{\"docs\":{},\"议\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"，\":{\"docs\":{},\"而\":{\"docs\":{},\"不\":{\"docs\":{},\"建\":{\"docs\":{},\"议\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"的\":{\"docs\":{},\"相\":{\"docs\":{},\"互\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"能\":{\"docs\":{},\"力\":{\"docs\":{},\"更\":{\"docs\":{},\"强\":{\"docs\":{},\"，\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"只\":{\"docs\":{},\"是\":{\"docs\":{},\"其\":{\"docs\":{},\"中\":{\"docs\":{},\"一\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"能\":{\"docs\":{},\"力\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}},\"项\":{\"docs\":{},\"目\":{\"docs\":{},\"中\":{\"docs\":{},\"：\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"和\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"这\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"项\":{\"docs\":{},\"目\":{\"docs\":{},\"有\":{\"docs\":{},\"什\":{\"docs\":{},\"么\":{\"docs\":{},\"区\":{\"docs\":{},\"别\":{\"docs\":{},\"？\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"集\":{\"docs\":{},\"成\":{\"docs\":{},\"了\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"原\":{\"docs\":{},\"先\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"的\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"省\":{\"docs\":{},\"略\":{\"docs\":{},\"，\":{\"docs\":{},\"也\":{\"docs\":{},\"不\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"添\":{\"docs\":{},\"加\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"的\":{\"docs\":{},\"三\":{\"docs\":{},\"方\":{\"docs\":{},\"库\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"，\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"的\":{\"docs\":{},\"只\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"将\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"置\":{\"docs\":{},\"为\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"即\":{\"docs\":{},\"可\":{\"docs\":{},\"（\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"集\":{\"docs\":{},\"成\":{\"docs\":{},\"该\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"一\":{\"docs\":{},\"方\":{\"docs\":{},\"面\":{\"docs\":{},\"是\":{\"docs\":{},\"便\":{\"docs\":{},\"于\":{\"docs\":{},\"和\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"的\":{\"docs\":{},\"兼\":{\"docs\":{},\"容\":{\"docs\":{},\"，\":{\"docs\":{},\"另\":{\"docs\":{},\"一\":{\"docs\":{},\"方\":{\"docs\":{},\"面\":{\"docs\":{},\"后\":{\"docs\":{},\"续\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"会\":{\"docs\":{},\"优\":{\"docs\":{},\"化\":{\"docs\":{},\"原\":{\"docs\":{},\"生\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"在\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"上\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"性\":{\"docs\":{},\"能\":{\"docs\":{},\"）\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"于\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"上\":{\"docs\":{},\"的\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"化\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"。\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"这\":{\"docs\":{},\"一\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"器\":{\"docs\":{},\"和\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"期\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"都\":{\"docs\":{},\"做\":{\"docs\":{},\"了\":{\"docs\":{},\"很\":{\"docs\":{},\"多\":{\"docs\":{},\"工\":{\"docs\":{},\"作\":{\"docs\":{},\"。\":{\"docs\":{},\"本\":{\"docs\":{},\"文\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"入\":{\"docs\":{},\"门\":{\"docs\":{},\"级\":{\"docs\":{},\"别\":{\"docs\":{},\"的\":{\"docs\":{},\"文\":{\"docs\":{},\"章\":{\"docs\":{},\"，\":{\"docs\":{},\"梳\":{\"docs\":{},\"理\":{\"docs\":{},\"从\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"到\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"最\":{\"docs\":{},\"终\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"期\":{\"docs\":{},\"间\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"到\":{\"docs\":{},\"底\":{\"docs\":{},\"搞\":{\"docs\":{},\"了\":{\"docs\":{},\"哪\":{\"docs\":{},\"些\":{\"docs\":{},\"事\":{\"docs\":{},\"情\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"之\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":10}}}}}}}}}},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"(\":{\"docs\":{},\"一\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":10}}}},\"二\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":10}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":10}},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"不\":{\"docs\":{},\"在\":{\"docs\":{},\"讨\":{\"docs\":{},\"论\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}},\"将\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"分\":{\"docs\":{},\"为\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"和\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"两\":{\"docs\":{},\"大\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"在\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"期\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"的\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"。\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"在\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"了\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}},\"有\":{\"docs\":{},\"很\":{\"docs\":{},\"多\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"只\":{\"docs\":{},\"关\":{\"docs\":{},\"注\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"中\":{\"docs\":{},\"出\":{\"docs\":{},\"现\":{\"docs\":{},\"的\":{\"docs\":{},\"重\":{\"docs\":{},\"点\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{},\"，\":{\"docs\":{},\"其\":{\"docs\":{},\"它\":{\"docs\":{},\"设\":{\"docs\":{},\"置\":{\"docs\":{},\"大\":{\"docs\":{},\"家\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"查\":{\"docs\":{},\"看\":{\"docs\":{},\"官\":{\"docs\":{},\"方\":{\"docs\":{},\"文\":{\"docs\":{},\"档\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"(\":{\"docs\":{},\"b\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"$\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"b\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"_\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{},\"n\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}}}}}}}},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"_\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"_\":{\"docs\":{},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"v\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\",\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"_\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"_\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"v\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"_\":{\"docs\":{},\"m\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"(\":{\"docs\":{},\"g\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"_\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"v\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"{\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"不\":{\"docs\":{},\"一\":{\"docs\":{},\"样\":{\"docs\":{},\"，\":{\"docs\":{},\"它\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"期\":{\"docs\":{},\"就\":{\"docs\":{},\"已\":{\"docs\":{},\"经\":{\"docs\":{},\"各\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"写\":{\"docs\":{},\"入\":{\"docs\":{},\"到\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"中\":{\"docs\":{},\"。\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"时\":{\"docs\":{},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"和\":{\"docs\":{},\"常\":{\"docs\":{},\"规\":{\"docs\":{},\"声\":{\"docs\":{},\"明\":{\"docs\":{},\"的\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"一\":{\"docs\":{},\"样\":{\"docs\":{},\"正\":{\"docs\":{},\"常\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"用\":{\"docs\":{},\"再\":{\"docs\":{},\"做\":{\"docs\":{},\"额\":{\"docs\":{},\"外\":{\"docs\":{},\"的\":{\"docs\":{},\"处\":{\"docs\":{},\"理\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"序\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"所\":{\"docs\":{},\"示\":{\"docs\":{},\"，\":{\"docs\":{},\"本\":{\"docs\":{},\"篇\":{\"docs\":{},\"只\":{\"docs\":{},\"关\":{\"docs\":{},\"注\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"1\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}},\"z\":{\"docs\":{},\"之\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"(\":{\"docs\":{},\"一\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}},\"获\":{\"docs\":{},\"得\":{\"docs\":{},\"了\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"(\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.005758157389635317}}}},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}},\"(\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\"中\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}},\"：\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"于\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"最\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"是\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"到\":{\"docs\":{},\"最\":{\"docs\":{},\"后\":{\"docs\":{},\"整\":{\"docs\":{},\"包\":{\"docs\":{},\"的\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"中\":{\"docs\":{},\"。\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"请\":{\"docs\":{},\"参\":{\"docs\":{},\"照\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"是\":{\"docs\":{},\"什\":{\"docs\":{},\"么\":{\"docs\":{},\"？\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"发\":{\"docs\":{},\"明\":{\"docs\":{},\"的\":{\"docs\":{},\"格\":{\"docs\":{},\"式\":{\"docs\":{},\"，\":{\"docs\":{},\"其\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"结\":{\"docs\":{},\"构\":{\"docs\":{},\"和\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"一\":{\"docs\":{},\"样\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}},\"o\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{\"guide-for-use/guide_for_compile.html\":{\"ref\":\"guide-for-use/guide_for_compile.html\",\"tf\":10}}}}}},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.03125}},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"从\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"中\":{\"docs\":{},\"获\":{\"docs\":{},\"取\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"去\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"o\":{\"docs\":{},\"f\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"o\":{\"docs\":{},\"f\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\".\":{\"docs\":{},\"m\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"_\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"切\":{\"docs\":{},\"换\":{\"docs\":{},\"动\":{\"docs\":{},\"画\":{\"docs\":{},\"的\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"要\":{\"docs\":{},\"放\":{\"docs\":{},\"在\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"中\":{\"docs\":{},\"；\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\",\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}},\"{\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}},\"切\":{\"docs\":{},\"换\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"画\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"、\":{\"docs\":{},\"通\":{\"docs\":{},\"知\":{\"docs\":{},\"栏\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"g\":{\"docs\":{},\"o\":{\"docs\":{},\"等\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"了\":{\"docs\":{},\"也\":{\"docs\":{},\"不\":{\"docs\":{},\"会\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"过\":{\"docs\":{},\"不\":{\"docs\":{},\"会\":{\"docs\":{},\"产\":{\"docs\":{},\"生\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"，\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"还\":{\"docs\":{},\"是\":{\"docs\":{},\"原\":{\"docs\":{},\"来\":{\"docs\":{},\"的\":{\"docs\":{},\"样\":{\"docs\":{},\"式\":{\"docs\":{\"update/guide.html\":{\"ref\":\"update/guide.html\",\"tf\":0.2}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"x\":{\"docs\":{},\"i\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"y\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"/\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{\"principle-intro/Apk_architecture.html\":{\"ref\":\"principle-intro/Apk_architecture.html\",\"tf\":0.07142857142857142}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"_\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154},\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.012422360248447204},\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.02127659574468085}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}},\"y\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\",\":{\"docs\":{},\"k\":{\"docs\":{},\"e\":{\"docs\":{},\"y\":{\"docs\":{},\",\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"最\":{\"docs\":{},\"终\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"了\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"看\":{\"docs\":{},\"第\":{\"4\":{\"docs\":{},\"步\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"输\":{\"docs\":{},\"出\":{\"docs\":{},\"的\":{\"docs\":{},\"r\":{\"docs\":{},\"为\":{\"docs\":{},\"常\":{\"docs\":{},\"量\":{\"docs\":{},\",\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}},\"的\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"，\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"上\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"是\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"去\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"并\":{\"docs\":{},\"不\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"新\":{\"docs\":{},\"增\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"包\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"读\":{\"docs\":{},\"到\":{\"docs\":{},\"了\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"，\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"会\":{\"docs\":{},\"去\":{\"docs\":{},\"校\":{\"docs\":{},\"验\":{\"docs\":{},\"该\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"在\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"值\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"不\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"则\":{\"docs\":{},\"抛\":{\"docs\":{},\"错\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"利\":{\"docs\":{},\"用\":{\"docs\":{},\"这\":{\"docs\":{},\"一\":{\"docs\":{},\"特\":{\"docs\":{},\"性\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"新\":{\"docs\":{},\"增\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"的\":{\"docs\":{},\"需\":{\"docs\":{},\"求\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"打\":{\"docs\":{},\"基\":{\"docs\":{},\"线\":{\"docs\":{},\"包\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"就\":{\"docs\":{},\"在\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"的\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"预\":{\"docs\":{},\"留\":{\"docs\":{},\"了\":{\"1\":{\"2\":{\"8\":{\"docs\":{},\"个\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"供\":{\"docs\":{},\"后\":{\"docs\":{},\"续\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"；\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"打\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"时\":{\"docs\":{},\"会\":{\"docs\":{},\"以\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"的\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"分\":{\"docs\":{},\"配\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"作\":{\"docs\":{},\"为\":{\"docs\":{},\"输\":{\"docs\":{},\"入\":{\"docs\":{},\"，\":{\"docs\":{},\"保\":{\"docs\":{},\"证\":{\"docs\":{},\"已\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"分\":{\"docs\":{},\"配\":{\"docs\":{},\"到\":{\"docs\":{},\"的\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"保\":{\"docs\":{},\"持\":{\"docs\":{},\"不\":{\"docs\":{},\"变\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"变\":{\"docs\":{},\"更\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"剔\":{\"docs\":{},\"除\":{\"docs\":{},\"该\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}},\"docs\":{}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.012711864406779662},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"、\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"h\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"解\":{\"docs\":{},\"决\":{\"docs\":{},\"了\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"通\":{\"docs\":{},\"信\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"复\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"。\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"这\":{\"docs\":{},\"两\":{\"docs\":{},\"者\":{\"docs\":{},\"也\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"着\":{\"docs\":{},\"很\":{\"docs\":{},\"大\":{\"docs\":{},\"的\":{\"docs\":{},\"不\":{\"docs\":{},\"足\":{\"docs\":{},\"。\":{\"docs\":{},\"一\":{\"docs\":{},\"方\":{\"docs\":{},\"面\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"限\":{\"docs\":{},\"制\":{\"docs\":{},\"了\":{\"docs\":{},\"只\":{\"docs\":{},\"能\":{\"docs\":{},\"传\":{\"docs\":{},\"递\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"简\":{\"docs\":{},\"单\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"，\":{\"docs\":{},\"对\":{\"docs\":{},\"于\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"复\":{\"docs\":{},\"用\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"说\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"的\":{\"docs\":{},\"重\":{\"docs\":{},\"用\":{\"docs\":{},\"则\":{\"docs\":{},\"完\":{\"docs\":{},\"全\":{\"docs\":{},\"行\":{\"docs\":{},\"不\":{\"docs\":{},\"通\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"成\":{\"docs\":{},\"本\":{\"docs\":{},\"也\":{\"docs\":{},\"是\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"h\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"的\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"的\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"痛\":{\"docs\":{},\"点\":{\"docs\":{},\"，\":{\"docs\":{},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"方\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"提\":{\"docs\":{},\"前\":{\"docs\":{},\"将\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"提\":{\"docs\":{},\"前\":{\"docs\":{},\"注\":{\"docs\":{},\"册\":{\"docs\":{},\"到\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"h\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"有\":{\"docs\":{},\"若\":{\"docs\":{},\"干\":{\"docs\":{},\"个\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"，\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"给\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"写\":{\"docs\":{},\"成\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\":\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.14615384615384616}}},\"l\":{\"docs\":{},\"p\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"1\":{\"1\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"发\":{\"docs\":{},\"布\":{\"docs\":{},\"解\":{\"docs\":{},\"决\":{\"docs\":{},\"了\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}},\"docs\":{}},\"8\":{\"docs\":{},\"'\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}},\"docs\":{}}}},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"是\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{},\"不\":{\"docs\":{},\"建\":{\"docs\":{},\"议\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"相\":{\"docs\":{},\"互\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"或\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"?\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}},\"：\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}},\"m\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"d\":{\"docs\":{},\"j\":{\"docs\":{},\"u\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}},\"方\":{\"docs\":{},\"法\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"w\":{\"docs\":{},\"s\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}},\".\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.005758157389635317},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"z\":{\"docs\":{},\"z\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"s\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"/\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"/\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"/\":{\"docs\":{},\"x\":{\"docs\":{},\"x\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}},\"k\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"g\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154}}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"r\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"p\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"g\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.02127659574468085}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}},\"l\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.02349869451697128},\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.012711864406779662},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0071301247771836}},\"e\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"。\":{\"docs\":{},\"它\":{\"docs\":{},\"主\":{\"docs\":{},\"要\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"了\":{\"docs\":{},\"解\":{\"docs\":{},\"耦\":{\"docs\":{},\"化\":{\"docs\":{},\"、\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"化\":{\"docs\":{},\"、\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"性\":{\"docs\":{},\"的\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"。\":{\"docs\":{},\"覆\":{\"docs\":{},\"盖\":{\"docs\":{},\"了\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"师\":{\"docs\":{},\"的\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"编\":{\"docs\":{},\"码\":{\"docs\":{},\"期\":{\"docs\":{},\"、\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"期\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"后\":{\"docs\":{},\"续\":{\"docs\":{},\"运\":{\"docs\":{},\"维\":{\"docs\":{},\"期\":{\"docs\":{},\"的\":{\"docs\":{},\"各\":{\"docs\":{},\"种\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"。\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\".\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}},\"{\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.029661016949152543}}}}}},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"g\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}},\"{\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"(\":{\"docs\":{},\")\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"以\":{\"docs\":{},\"b\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"为\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"引\":{\"docs\":{},\"用\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\",\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"自\":{\"docs\":{},\"身\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"顺\":{\"docs\":{},\"序\":{\"docs\":{},\"为\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"(\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\",\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\",\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"和\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}},\"被\":{\"docs\":{},\"认\":{\"docs\":{},\"为\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"小\":{\"docs\":{},\"型\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"，\":{\"docs\":{},\"因\":{\"docs\":{},\"此\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"都\":{\"docs\":{},\"是\":{\"docs\":{},\"从\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"开\":{\"docs\":{},\"始\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"被\":{\"docs\":{},\"声\":{\"docs\":{},\"明\":{\"docs\":{},\"在\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"x\":{\"docs\":{},\"m\":{\"docs\":{},\"l\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"按\":{\"docs\":{},\"需\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"，\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"参\":{\"docs\":{},\"见\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"开\":{\"docs\":{},\"始\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"会\":{\"docs\":{},\"被\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"分\":{\"docs\":{},\"区\":{\"docs\":{},\"，\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"保\":{\"docs\":{},\"证\":{\"docs\":{},\"全\":{\"docs\":{},\"局\":{\"docs\":{},\"唯\":{\"docs\":{},\"一\":{\"docs\":{},\"，\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"在\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"内\":{\"docs\":{},\"会\":{\"docs\":{},\"有\":{\"docs\":{},\"个\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"统\":{\"docs\":{},\"一\":{\"docs\":{},\"分\":{\"docs\":{},\"配\":{\"docs\":{},\"；\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"生\":{\"docs\":{},\"命\":{\"docs\":{},\"周\":{\"docs\":{},\"期\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}},\"的\":{\"docs\":{},\"安\":{\"docs\":{},\"全\":{\"docs\":{},\"校\":{\"docs\":{},\"验\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"；\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"检\":{\"docs\":{},\"测\":{\"docs\":{},\"已\":{\"docs\":{},\"经\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"缩\":{\"docs\":{},\"写\":{\"docs\":{},\"，\":{\"docs\":{},\"实\":{\"docs\":{},\"际\":{\"docs\":{},\"上\":{\"docs\":{},\"同\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"类\":{\"docs\":{},\"似\":{\"docs\":{},\"，\":{\"docs\":{},\"是\":{\"docs\":{},\"最\":{\"docs\":{},\"终\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"整\":{\"docs\":{},\"包\":{\"docs\":{},\"前\":{\"docs\":{},\"的\":{\"docs\":{},\"中\":{\"docs\":{},\"间\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"。\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"最\":{\"docs\":{},\"终\":{\"docs\":{},\"会\":{\"docs\":{},\"打\":{\"docs\":{},\"成\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"。\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"与\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"唯\":{\"docs\":{},\"一\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"之\":{\"docs\":{},\"处\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"与\":{\"docs\":{},\"之\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"有\":{\"docs\":{},\"个\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"的\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"。\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"不\":{\"docs\":{},\"能\":{\"docs\":{},\"有\":{\"docs\":{},\"对\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"内\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"的\":{\"docs\":{},\"引\":{\"docs\":{},\"用\":{\"docs\":{},\"；\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"声\":{\"docs\":{},\"明\":{\"docs\":{},\"在\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"中\":{\"docs\":{},\"。\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"会\":{\"docs\":{},\"合\":{\"docs\":{},\"并\":{\"docs\":{},\"进\":{\"docs\":{},\"主\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"有\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"引\":{\"docs\":{},\"用\":{\"docs\":{},\"会\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"引\":{\"docs\":{},\"发\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"出\":{\"docs\":{},\"错\":{\"docs\":{},\"；\":{\"docs\":{},\"另\":{\"docs\":{},\"外\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"选\":{\"docs\":{},\"择\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"不\":{\"docs\":{},\"加\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"改\":{\"docs\":{},\"用\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\".\":{\"docs\":{},\"x\":{\"docs\":{},\"m\":{\"docs\":{},\"l\":{\"docs\":{},\"中\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"注\":{\"docs\":{},\"册\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"并\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{},\"被\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"真\":{\"docs\":{},\"正\":{\"docs\":{},\"认\":{\"docs\":{},\"可\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"作\":{\"docs\":{},\"为\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"传\":{\"docs\":{},\"入\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"，\":{\"docs\":{},\"而\":{\"docs\":{},\"x\":{\"docs\":{},\"m\":{\"docs\":{},\"l\":{\"docs\":{},\"来\":{\"docs\":{},\"自\":{\"docs\":{},\"于\":{\"docs\":{},\"b\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}},\"注\":{\"docs\":{},\"意\":{\"docs\":{},\"点\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"主\":{\"docs\":{},\"要\":{\"docs\":{},\"以\":{\"docs\":{},\"下\":{\"docs\":{},\"几\":{\"docs\":{},\"个\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"(\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\")\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"期\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"策\":{\"docs\":{},\"略\":{\"docs\":{},\"：\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"和\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"其\":{\"docs\":{},\"实\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"打\":{\"docs\":{},\"成\":{\"docs\":{},\"了\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"，\":{\"docs\":{},\"放\":{\"docs\":{},\"在\":{\"docs\":{},\"了\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"时\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"存\":{\"docs\":{},\"放\":{\"docs\":{},\"位\":{\"docs\":{},\"置\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"和\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"触\":{\"docs\":{},\"发\":{\"docs\":{},\"时\":{\"docs\":{},\"机\":{\"docs\":{},\"请\":{\"docs\":{},\"参\":{\"docs\":{},\"考\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}},\"被\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"到\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}},\"，\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"获\":{\"docs\":{},\"取\":{\"docs\":{},\"全\":{\"docs\":{},\"局\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"等\":{\"docs\":{},\"各\":{\"docs\":{},\"种\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"。\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}},\"只\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"去\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"前\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"选\":{\"docs\":{},\"择\":{\"docs\":{},\"上\":{\"docs\":{},\"会\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"最\":{\"docs\":{},\"高\":{\"docs\":{},\"的\":{\"docs\":{},\"可\":{\"docs\":{},\"用\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"a\":{\"docs\":{},\"和\":{\"docs\":{},\"b\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"，\":{\"docs\":{},\"那\":{\"docs\":{},\"么\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"也\":{\"docs\":{},\"肯\":{\"docs\":{},\"定\":{\"docs\":{},\"失\":{\"docs\":{},\"败\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}}}}}}},\":\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}},\"：\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\"的\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"也\":{\"docs\":{},\"会\":{\"docs\":{},\"在\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"主\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"体\":{\"docs\":{},\"现\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"线\":{\"docs\":{},\"框\":{\"1\":{\"docs\":{},\"、\":{\"2\":{\"docs\":{},\"所\":{\"docs\":{},\"示\":{\"docs\":{},\"，\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"下\":{\"docs\":{},\"面\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{\"principle-intro/Apk_architecture.html\":{\"ref\":\"principle-intro/Apk_architecture.html\",\"tf\":0.07142857142857142}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"，\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"记\":{\"docs\":{},\"录\":{\"docs\":{},\"了\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}},\"{\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.016042780748663103}},\"(\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0053475935828877}}}}}}},\"。\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"并\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"进\":{\"docs\":{},\"来\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"会\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"到\":{\"docs\":{},\"第\":{\"3\":{\"docs\":{},\"步\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"y\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}},\":\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}},\"内\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"有\":{\"docs\":{},\"用\":{\"docs\":{},\"到\":{\"docs\":{},\"自\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{},\"那\":{\"docs\":{},\"么\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"也\":{\"docs\":{},\"是\":{\"docs\":{},\"自\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"的\":{\"docs\":{},\"话\":{\"docs\":{},\"，\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"必\":{\"docs\":{},\"须\":{\"docs\":{},\"位\":{\"docs\":{},\"于\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"是\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"5\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"以\":{\"docs\":{},\"后\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"内\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"的\":{\"docs\":{},\"固\":{\"docs\":{},\"有\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{},\"导\":{\"docs\":{},\"致\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"内\":{\"docs\":{},\"暂\":{\"docs\":{},\"不\":{\"docs\":{},\"能\":{\"docs\":{},\"完\":{\"docs\":{},\"全\":{\"docs\":{},\"兼\":{\"docs\":{},\"容\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"有\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"主\":{\"docs\":{},\"进\":{\"docs\":{},\"程\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\",\":{\"docs\":{},\"则\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"声\":{\"docs\":{},\"明\":{\"docs\":{},\"中\":{\"docs\":{},\"最\":{\"docs\":{},\"好\":{\"docs\":{},\"带\":{\"docs\":{},\"上\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"最\":{\"docs\":{},\"好\":{\"docs\":{},\"以\":{\"docs\":{},\"特\":{\"docs\":{},\"定\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"开\":{\"docs\":{},\"头\":{\"docs\":{},\"，\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"能\":{\"docs\":{},\"够\":{\"docs\":{},\"带\":{\"docs\":{},\"有\":{\"docs\":{},\"特\":{\"docs\":{},\"定\":{\"docs\":{},\"的\":{\"docs\":{},\"前\":{\"docs\":{},\"缀\":{\"docs\":{},\"。\":{\"docs\":{},\"这\":{\"docs\":{},\"样\":{\"docs\":{},\"一\":{\"docs\":{},\"来\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"避\":{\"docs\":{},\"免\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"类\":{\"docs\":{},\"名\":{\"docs\":{},\"重\":{\"docs\":{},\"复\":{\"docs\":{},\"而\":{\"docs\":{},\"引\":{\"docs\":{},\"起\":{\"docs\":{},\"的\":{\"docs\":{},\"覆\":{\"docs\":{},\"盖\":{\"docs\":{},\"，\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"在\":{\"docs\":{},\"出\":{\"docs\":{},\"现\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"及\":{\"docs\":{},\"时\":{\"docs\":{},\"定\":{\"docs\":{},\"位\":{\"docs\":{},\"到\":{\"docs\":{},\"出\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"的\":{\"docs\":{},\"模\":{\"docs\":{},\"块\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"传\":{\"docs\":{},\"入\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"的\":{\"docs\":{},\"全\":{\"docs\":{},\"路\":{\"docs\":{},\"径\":{\"docs\":{},\"（\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"说\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"层\":{\"docs\":{},\"获\":{\"docs\":{},\"取\":{\"docs\":{},\"）\":{\"docs\":{},\"，\":{\"docs\":{},\"否\":{\"docs\":{},\"则\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"出\":{\"docs\":{},\"现\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"部\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"有\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"时\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"无\":{\"docs\":{},\"法\":{\"docs\":{},\"解\":{\"docs\":{},\"压\":{\"docs\":{},\"到\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}},\"如\":{\"docs\":{},\"何\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"服\":{\"docs\":{},\"务\":{\"docs\":{},\"给\":{\"docs\":{},\"其\":{\"docs\":{},\"他\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}},\"果\":{\"docs\":{},\"相\":{\"docs\":{},\"互\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"起\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"，\":{\"docs\":{},\"否\":{\"docs\":{},\"则\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"期\":{\"docs\":{},\"会\":{\"docs\":{},\"无\":{\"docs\":{},\"法\":{\"docs\":{},\"找\":{\"docs\":{},\"到\":{\"docs\":{},\"被\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"内\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"且\":{\"docs\":{},\"不\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"性\":{\"docs\":{},\"能\":{\"docs\":{},\"，\":{\"docs\":{},\"目\":{\"docs\":{},\"前\":{\"docs\":{},\"不\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"二\":{\"docs\":{},\"级\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"：\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"a\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"拆\":{\"docs\":{},\"分\":{\"docs\":{},\"|\":{\"docs\":{},\"新\":{\"docs\":{},\"建\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":10}}}}}}},\"时\":{\"docs\":{},\"的\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"样\":{\"docs\":{},\"导\":{\"docs\":{},\"致\":{\"docs\":{},\"了\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"会\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"在\":{\"docs\":{},\"主\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"子\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"对\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"敏\":{\"docs\":{},\"感\":{\"docs\":{},\"的\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"注\":{\"docs\":{},\"意\":{\"docs\":{},\"：\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"强\":{\"docs\":{},\"制\":{\"docs\":{},\"主\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"的\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"自\":{\"docs\":{},\"身\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"声\":{\"docs\":{},\"明\":{\"docs\":{},\"为\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\":\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}},\"内\":{\"docs\":{},\"聚\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}},\"虽\":{\"docs\":{},\"然\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"了\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"，\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"这\":{\"docs\":{},\"种\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"不\":{\"docs\":{},\"当\":{\"docs\":{},\"反\":{\"docs\":{},\"而\":{\"docs\":{},\"会\":{\"docs\":{},\"带\":{\"docs\":{},\"来\":{\"docs\":{},\"隐\":{\"docs\":{},\"患\":{\"docs\":{},\"，\":{\"docs\":{},\"且\":{\"docs\":{},\"与\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"的\":{\"docs\":{},\"封\":{\"docs\":{},\"装\":{\"docs\":{},\"性\":{\"docs\":{},\"相\":{\"docs\":{},\"违\":{\"docs\":{},\"背\":{\"docs\":{},\"。\":{\"docs\":{},\"通\":{\"docs\":{},\"常\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"某\":{\"docs\":{},\"个\":{\"docs\":{},\"中\":{\"docs\":{},\"间\":{\"docs\":{},\"件\":{\"docs\":{},\"是\":{\"docs\":{},\"以\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"形\":{\"docs\":{},\"式\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"，\":{\"docs\":{},\"那\":{\"docs\":{},\"声\":{\"docs\":{},\"明\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"是\":{\"docs\":{},\"可\":{\"docs\":{},\"行\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"相\":{\"docs\":{},\"对\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"的\":{\"docs\":{},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"某\":{\"docs\":{},\"几\":{\"docs\":{},\"个\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"服\":{\"docs\":{},\"务\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"，\":{\"docs\":{},\"服\":{\"docs\":{},\"务\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"方\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"，\":{\"docs\":{},\"被\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"；\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"自\":{\"docs\":{},\"己\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"{\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}},\"v\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"级\":{\"docs\":{},\"别\":{\"docs\":{},\"，\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}},\"中\":{\"docs\":{},\"的\":{\"9\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"图\":{\"docs\":{},\"显\":{\"docs\":{},\"示\":{\"docs\":{},\"有\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"能\":{\"docs\":{},\"拉\":{\"docs\":{},\"伸\":{\"docs\":{},\"了\":{\"docs\":{},\"。\":{\"docs\":{},\"是\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"有\":{\"docs\":{},\"特\":{\"docs\":{},\"殊\":{\"docs\":{},\"设\":{\"docs\":{},\"置\":{\"docs\":{},\"么\":{\"docs\":{},\"？\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"类\":{\"docs\":{},\"的\":{\"docs\":{},\"自\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"建\":{\"docs\":{},\"议\":{\"docs\":{},\"不\":{\"docs\":{},\"要\":{\"docs\":{},\"这\":{\"docs\":{},\"么\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"。\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"抽\":{\"docs\":{},\"离\":{\"docs\":{},\"出\":{\"docs\":{},\"公\":{\"docs\":{},\"共\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"，\":{\"docs\":{},\"放\":{\"docs\":{},\"在\":{\"docs\":{},\"其\":{\"docs\":{},\"他\":{\"docs\":{},\"地\":{\"docs\":{},\"方\":{\"docs\":{},\"供\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"，\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"第\":{\"docs\":{},\"一\":{\"docs\":{},\"次\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"会\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"，\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"在\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"写\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"自\":{\"docs\":{},\"己\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"用\":{\"docs\":{},\"到\":{\"docs\":{},\"的\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"。\":{\"docs\":{},\"注\":{\"docs\":{},\"意\":{\"docs\":{},\"不\":{\"docs\":{},\"要\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"任\":{\"docs\":{},\"何\":{\"docs\":{},\"东\":{\"docs\":{},\"西\":{\"docs\":{},\"，\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"不\":{\"docs\":{},\"会\":{\"docs\":{},\"打\":{\"docs\":{},\"入\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"中\":{\"docs\":{},\"去\":{\"docs\":{},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"将\":{\"docs\":{},\"以\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"x\":{\"docs\":{},\"x\":{\"docs\":{},\"x\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"的\":{\"docs\":{},\"形\":{\"docs\":{},\"式\":{\"docs\":{},\"，\":{\"docs\":{},\"放\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"随\":{\"docs\":{},\"包\":{\"docs\":{},\"发\":{\"docs\":{},\"布\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"无\":{\"docs\":{},\"法\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}},\"z\":{\"docs\":{},\"i\":{\"docs\":{},\"p\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}},\"_\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"g\":{\"docs\":{},\"_\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"为\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"包\":{\"docs\":{},\"名\":{\"docs\":{},\"，\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"的\":{\"docs\":{},\"包\":{\"docs\":{},\"名\":{\"docs\":{},\"为\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"，\":{\"docs\":{},\"拥\":{\"docs\":{},\"有\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"和\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"的\":{\"docs\":{},\"清\":{\"docs\":{},\"单\":{\"docs\":{},\"数\":{\"docs\":{},\"据\":{\"docs\":{},\"，\":{\"docs\":{},\"包\":{\"docs\":{},\"括\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"和\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"自\":{\"docs\":{},\"身\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\".\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}}}}}}}}}}}}}},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0053475935828877}}}}}}}}}}}}}}}}}}}}}}},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0053475935828877}}},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0071301247771836}}}}},\"s\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}}}}}}},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"第\":{\"7\":{\"docs\":{},\"步\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"回\":{\"docs\":{},\"调\":{\"docs\":{},\"了\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"，\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"了\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"又\":{\"docs\":{},\"经\":{\"docs\":{},\"过\":{\"docs\":{},\"辗\":{\"docs\":{},\"转\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"到\":{\"docs\":{},\"了\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"d\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"中\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}},\"过\":{\"docs\":{},\"程\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\":\":{\"docs\":{},\"/\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"/\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"/\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"/\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"/\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"/\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}},\"e\":{\"docs\":{},\"/\":{\"1\":{\"docs\":{},\"x\":{\"6\":{\"docs\":{},\"r\":{\"8\":{\"docs\":{},\"i\":{\"docs\":{},\"u\":{\"docs\":{},\"z\":{\"docs\":{},\"s\":{\"9\":{\"0\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}},\"docs\":{}},\"docs\":{}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.0436241610738255},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.012539184952978056},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}},\".\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\"o\":{\"docs\":{},\"f\":{\"docs\":{},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"负\":{\"docs\":{},\"责\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"k\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"_\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}},\"c\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.013422818791946308},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.013054830287206266},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.011516314779270634},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0106951871657754}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154},\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.02247191011235955}}}}}},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0071301247771836}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"被\":{\"docs\":{},\"创\":{\"docs\":{},\"建\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"注\":{\"docs\":{},\"入\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"c\":{\"docs\":{},\"c\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"；\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}},\".\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"2\":{\"docs\":{},\":\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"2\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}},\"docs\":{}}}}}}}}}}}}},\"docs\":{},\":\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}},\",\":{\"docs\":{},\"b\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}}}}}}}}}}}},\"|\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\"{\":{\"docs\":{},\"i\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"}\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"z\":{\"docs\":{},\"z\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.012422360248447204},\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.02127659574468085}}}}},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\":\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154}}}}}}}},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"=\":{\"3\":{\"4\":{\"docs\":{},\"/\":{\"docs\":{},\"/\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\":\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"=\":{\"docs\":{},\"n\":{\"docs\":{},\"u\":{\"docs\":{},\"m\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}},\"docs\":{}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.0423728813559322}},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"'\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\":\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"_\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\":\":{\"5\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"@\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"'\":{\"docs\":{},\")\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}},\"7\":{\"docs\":{},\"@\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"'\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\":\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\":\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"@\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.010443864229765013}}}}}}}}}}},\"i\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}},\"n\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"(\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\",\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"s\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\",\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\"{\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"i\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\".\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"(\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}},\".\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\",\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}},\"a\":{\"docs\":{},\"t\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}},\"l\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"(\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.010443864229765013}}}}},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}},\"{\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.010443864229765013}}}}}}}}},\"s\":{\"docs\":{},\"e\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"检\":{\"docs\":{},\"查\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"是\":{\"docs\":{},\"否\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"反\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"主\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}},\"d\":{\"docs\":{},\"到\":{\"docs\":{},\"和\":{\"docs\":{},\"/\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"/\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"/\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"/\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"/\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"/\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"i\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\",\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"y\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"(\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"y\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.024242424242424242}}}}}},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\",\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"某\":{\"docs\":{},\"些\":{\"docs\":{},\"特\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"会\":{\"docs\":{},\"记\":{\"docs\":{},\"录\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"级\":{\"docs\":{},\"别\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{\"principle-intro/Apk_architecture.html\":{\"ref\":\"principle-intro/Apk_architecture.html\",\"tf\":0.07142857142857142}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"记\":{\"docs\":{},\"录\":{\"docs\":{},\"该\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"所\":{\"docs\":{},\"在\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{\"principle-intro/Apk_architecture.html\":{\"ref\":\"principle-intro/Apk_architecture.html\",\"tf\":0.07142857142857142}}}}}}}}}}}}}}}}}}}}}}}},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"。\":{\"docs\":{\"principle-intro/Apk_architecture.html\":{\"ref\":\"principle-intro/Apk_architecture.html\",\"tf\":0.07142857142857142}}}}},\"的\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"做\":{\"docs\":{},\"k\":{\"docs\":{},\"e\":{\"docs\":{},\"y\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"，\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"k\":{\"docs\":{},\"e\":{\"docs\":{},\"y\":{\"docs\":{},\"必\":{\"docs\":{},\"须\":{\"docs\":{},\"以\":{\"docs\":{},\"*\":{\"docs\":{},\"*\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"*\":{\"docs\":{},\"*\":{\"docs\":{},\"开\":{\"docs\":{},\"头\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\":\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}},\"p\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"=\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.012121212121212121},\"guide-for-use/\":{\"ref\":\"guide-for-use/\",\"tf\":0.25},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}},\"/\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"/\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}},\"中\":{\"docs\":{},\"测\":{\"docs\":{},\"试\":{\"docs\":{},\"入\":{\"docs\":{},\"口\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}},\"说\":{\"docs\":{},\"明\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}},\"\\\\\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.012539184952978056}},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}}}}},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.012121212121212121},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154},\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.01694915254237288},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}},\"e\":{\"docs\":{},\",\":{\"docs\":{},\"b\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"主\":{\"docs\":{},\"要\":{\"docs\":{},\"分\":{\"docs\":{},\"为\":{\"docs\":{},\"三\":{\"docs\":{},\"个\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}},\"x\":{\"2\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\")\":{\"docs\":{},\"，\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"已\":{\"docs\":{},\"经\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"注\":{\"docs\":{},\"入\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}},\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":10},\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.031055900621118012}},\"不\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"回\":{\"docs\":{},\"滚\":{\"docs\":{},\"，\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"发\":{\"docs\":{},\"布\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"覆\":{\"docs\":{},\"盖\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"有\":{\"docs\":{},\"下\":{\"docs\":{},\"线\":{\"docs\":{},\"的\":{\"docs\":{},\"能\":{\"docs\":{},\"力\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"作\":{\"docs\":{},\"为\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"补\":{\"docs\":{},\"充\":{\"docs\":{},\"，\":{\"docs\":{},\"两\":{\"docs\":{},\"者\":{\"docs\":{},\"相\":{\"docs\":{},\"辅\":{\"docs\":{},\"相\":{\"docs\":{},\"成\":{\"docs\":{},\"。\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"针\":{\"docs\":{},\"对\":{\"docs\":{},\"任\":{\"docs\":{},\"何\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"大\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"发\":{\"docs\":{},\"布\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"，\":{\"docs\":{},\"无\":{\"docs\":{},\"论\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"是\":{\"docs\":{},\"否\":{\"docs\":{},\"有\":{\"docs\":{},\"被\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"，\":{\"docs\":{},\"当\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"时\":{\"docs\":{},\"，\":{\"docs\":{},\"它\":{\"docs\":{},\"们\":{\"docs\":{},\"又\":{\"docs\":{},\"都\":{\"docs\":{},\"会\":{\"docs\":{},\"被\":{\"docs\":{},\"收\":{\"docs\":{},\"敛\":{\"docs\":{},\"到\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"新\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"上\":{\"docs\":{},\"面\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"是\":{\"docs\":{},\"以\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"技\":{\"docs\":{},\"术\":{\"docs\":{},\"方\":{\"docs\":{},\"案\":{\"docs\":{},\"为\":{\"docs\":{},\"基\":{\"docs\":{},\"础\":{\"docs\":{},\"，\":{\"docs\":{},\"以\":{\"docs\":{},\"快\":{\"docs\":{},\"速\":{\"docs\":{},\"解\":{\"docs\":{},\"决\":{\"docs\":{},\"线\":{\"docs\":{},\"上\":{\"docs\":{},\"故\":{\"docs\":{},\"障\":{\"docs\":{},\"为\":{\"docs\":{},\"唯\":{\"docs\":{},\"一\":{\"docs\":{},\"目\":{\"docs\":{},\"的\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"化\":{\"docs\":{},\"方\":{\"docs\":{},\"案\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571},\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"其\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"的\":{\"docs\":{},\"原\":{\"docs\":{},\"子\":{\"docs\":{},\"性\":{\"docs\":{},\"（\":{\"docs\":{},\"向\":{\"docs\":{},\"前\":{\"docs\":{},\"兼\":{\"docs\":{},\"容\":{\"docs\":{},\"性\":{\"docs\":{},\"的\":{\"docs\":{},\"保\":{\"docs\":{},\"证\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"不\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"关\":{\"docs\":{},\"联\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"）\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"按\":{\"docs\":{},\"需\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"的\":{\"docs\":{},\"特\":{\"docs\":{},\"性\":{\"docs\":{},\"，\":{\"docs\":{},\"使\":{\"docs\":{},\"得\":{\"docs\":{},\"未\":{\"docs\":{},\"被\":{\"docs\":{},\"载\":{\"docs\":{},\"入\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"不\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"进\":{\"docs\":{},\"程\":{\"docs\":{},\"重\":{\"docs\":{},\"启\":{\"docs\":{},\"即\":{\"docs\":{},\"可\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"，\":{\"docs\":{},\"已\":{\"docs\":{},\"经\":{\"docs\":{},\"载\":{\"docs\":{},\"入\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"后\":{\"docs\":{},\"期\":{\"docs\":{},\"也\":{\"docs\":{},\"会\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"生\":{\"docs\":{},\"命\":{\"docs\":{},\"周\":{\"docs\":{},\"期\":{\"docs\":{},\"的\":{\"docs\":{},\"监\":{\"docs\":{},\"控\":{\"docs\":{},\"，\":{\"docs\":{},\"一\":{\"docs\":{},\"旦\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"退\":{\"docs\":{},\"出\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"热\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"，\":{\"docs\":{},\"使\":{\"docs\":{},\"得\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"相\":{\"docs\":{},\"比\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"速\":{\"docs\":{},\"度\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"进\":{\"docs\":{},\"一\":{\"docs\":{},\"步\":{\"docs\":{},\"提\":{\"docs\":{},\"高\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"的\":{\"docs\":{},\"特\":{\"docs\":{},\"点\":{\"docs\":{},\"和\":{\"docs\":{},\"优\":{\"docs\":{},\"势\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}},\"与\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"异\":{\"docs\":{},\"同\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}},\"介\":{\"docs\":{},\"绍\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"教\":{\"docs\":{},\"程\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":10}}}},\"示\":{\"docs\":{},\"例\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"作\":{\"docs\":{},\"为\":{\"docs\":{},\"参\":{\"docs\":{},\"照\":{\"docs\":{},\"，\":{\"docs\":{},\"和\":{\"docs\":{},\"现\":{\"docs\":{},\"在\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"比\":{\"docs\":{},\"对\":{\"docs\":{},\"做\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"。\":{\"docs\":{},\"假\":{\"docs\":{},\"设\":{\"docs\":{},\"当\":{\"docs\":{},\"前\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"为\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"h\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"最\":{\"docs\":{},\"终\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"去\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"理\":{\"docs\":{},\"解\":{\"docs\":{},\"为\":{\"docs\":{},\"持\":{\"docs\":{},\"有\":{\"docs\":{},\"者\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"，\":{\"docs\":{},\"再\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"遍\":{\"docs\":{},\"历\":{\"docs\":{},\"这\":{\"docs\":{},\"些\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"，\":{\"docs\":{},\"直\":{\"docs\":{},\"到\":{\"docs\":{},\"找\":{\"docs\":{},\"到\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"的\":{\"docs\":{},\"类\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"c\":{\"docs\":{},\"库\":{\"docs\":{},\"，\":{\"docs\":{},\"那\":{\"docs\":{},\"么\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"把\":{\"docs\":{},\"新\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"添\":{\"docs\":{},\"加\":{\"docs\":{},\"到\":{\"docs\":{},\"这\":{\"docs\":{},\"些\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"的\":{\"docs\":{},\"最\":{\"docs\":{},\"前\":{\"docs\":{},\"面\":{\"docs\":{},\"，\":{\"docs\":{},\"从\":{\"docs\":{},\"而\":{\"docs\":{},\"使\":{\"docs\":{},\"得\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"的\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"新\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"能\":{\"docs\":{},\"够\":{\"docs\":{},\"提\":{\"docs\":{},\"前\":{\"docs\":{},\"找\":{\"docs\":{},\"到\":{\"docs\":{},\"从\":{\"docs\":{},\"而\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"原\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"（\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"）\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"的\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{},\"。\":{\"docs\":{},\"（\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"以\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"为\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"在\":{\"docs\":{},\"路\":{\"docs\":{},\"由\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"能\":{\"docs\":{},\"够\":{\"docs\":{},\"找\":{\"docs\":{},\"到\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"；\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"k\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"(\":{\"docs\":{},\"b\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.013422818791946308}},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}},\":\":{\"docs\":{},\"$\":{\"docs\":{},\"{\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"}\":{\"docs\":{},\"@\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"\\\"\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}},\"f\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.02127659574468085}},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"g\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"的\":{\"docs\":{},\"差\":{\"docs\":{},\"异\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"时\":{\"docs\":{},\"拉\":{\"docs\":{},\"取\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"静\":{\"docs\":{},\"默\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"到\":{\"docs\":{},\"设\":{\"docs\":{},\"备\":{\"docs\":{},\"上\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"用\":{\"docs\":{},\"户\":{\"docs\":{},\"下\":{\"docs\":{},\"次\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"新\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"，\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"原\":{\"docs\":{},\"理\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"参\":{\"docs\":{},\"考\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"章\":{\"docs\":{},\"节\":{\"docs\":{},\"的\":{\"docs\":{},\"解\":{\"docs\":{},\"析\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"=\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}},\"1\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}},\"w\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.005221932114882507}}}}}}}}},\"u\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\\\":{\"2\":{\"5\":{\"docs\":{},\".\":{\"3\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}},\"docs\":{}}}}}}}}}},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"h\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}}},\")\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"{\":{\"docs\":{},\"}\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"才\":{\"docs\":{},\"是\":{\"docs\":{},\"真\":{\"docs\":{},\"正\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"实\":{\"docs\":{},\"例\":{\"docs\":{},\"化\":{\"docs\":{},\"所\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"是\":{\"docs\":{},\"由\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"时\":{\"docs\":{},\"创\":{\"docs\":{},\"建\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"，\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"给\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"，\":{\"docs\":{},\"它\":{\"docs\":{},\"是\":{\"docs\":{},\"真\":{\"docs\":{},\"正\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"，\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"界\":{\"docs\":{},\"面\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"也\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"有\":{\"docs\":{},\"效\":{\"docs\":{},\"的\":{\"docs\":{},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"o\":{\"docs\":{},\"w\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"，\":{\"docs\":{},\"涉\":{\"docs\":{},\"及\":{\"docs\":{},\"到\":{\"docs\":{},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"o\":{\"docs\":{},\"w\":{\"docs\":{},\"操\":{\"docs\":{},\"作\":{\"docs\":{},\"的\":{\"docs\":{},\"会\":{\"docs\":{},\"自\":{\"docs\":{},\"动\":{\"docs\":{},\"转\":{\"docs\":{},\"交\":{\"docs\":{},\"给\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"处\":{\"docs\":{},\"理\":{\"docs\":{},\"。\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"是\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"不\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"最\":{\"docs\":{},\"根\":{\"docs\":{},\"本\":{\"docs\":{},\"的\":{\"docs\":{},\"保\":{\"docs\":{},\"证\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.007832898172323759}}}}}}}}}}},\"x\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"(\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.010443864229765013}}}}}},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}},\":\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\\\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"q\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}},\"l\":{\"docs\":{},\"s\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.020134228187919462},\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}},\"e\":{\"docs\":{},\",\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.012422360248447204}}},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}},\"v\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\":\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}},\"o\":{\"docs\":{},\"w\":{\"docs\":{},\"n\":{\"docs\":{},\"：\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"：\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}},\"a\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.016042780748663103}}}}},\"l\":{\"docs\":{},\"e\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154},\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0053475935828877}},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\":\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00847457627118644}}}}}}}}}}},\"(\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\",\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"d\":{\"docs\":{},\"n\":{\"docs\":{},\"l\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"（\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"）\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.009596928982725527}},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"k\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"z\":{\"docs\":{},\"z\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"k\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}},\"，\":{\"docs\":{},\"正\":{\"docs\":{},\"常\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"中\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"k\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"其\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"，\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"对\":{\"docs\":{},\"于\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"而\":{\"docs\":{},\"言\":{\"docs\":{},\"也\":{\"docs\":{},\"是\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"样\":{\"docs\":{},\"子\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"假\":{\"docs\":{},\"如\":{\"docs\":{},\"多\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"同\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"，\":{\"docs\":{},\"那\":{\"docs\":{},\"么\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"放\":{\"docs\":{},\"在\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"里\":{\"docs\":{},\"边\":{\"docs\":{},\"，\":{\"docs\":{},\"多\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"样\":{\"docs\":{},\"避\":{\"docs\":{},\"免\":{\"docs\":{},\"了\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"的\":{\"docs\":{},\"重\":{\"docs\":{},\"复\":{\"docs\":{},\"。\":{\"docs\":{},\"(\":{\"docs\":{},\"甚\":{\"docs\":{},\"至\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"把\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"看\":{\"docs\":{},\"成\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"是\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"在\":{\"docs\":{},\"主\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\")\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"z\":{\"docs\":{},\"z\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"{\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}},\".\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}}}}}}}}}}}}}}}}}}},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"n\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"0\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"w\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"_\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\",\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"w\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"_\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}},\")\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"{\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}},\"b\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"：\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"及\":{\"docs\":{},\"控\":{\"docs\":{},\"制\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}},\"分\":{\"docs\":{},\"析\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"只\":{\"docs\":{},\"用\":{\"docs\":{},\"看\":{\"docs\":{},\"主\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"和\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"就\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"了\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"g\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}},\"e\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"的\":{\"docs\":{},\"文\":{\"docs\":{},\"档\":{\"docs\":{},\"地\":{\"docs\":{},\"址\":{\"docs\":{},\"：\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.010443864229765013}}}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"b\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\",\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"m\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"k\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\"+\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"/\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"+\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"\\\"\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"=\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"_\":{\"docs\":{},\"i\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"m\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"_\":{\"docs\":{},\"g\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"m\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"h\":{\"5\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}},\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.012711864406779662}},\":\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"的\":{\"docs\":{},\"中\":{\"docs\":{},\"间\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{},\"应\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"应\":{\"docs\":{},\"用\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"等\":{\"docs\":{},\"基\":{\"docs\":{},\"础\":{\"docs\":{},\"性\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"（\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"足\":{\"docs\":{},\"够\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"放\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"_\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"内\":{\"docs\":{},\"）\":{\"docs\":{},\"；\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}},\"为\":{\"docs\":{},\"共\":{\"docs\":{},\"用\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"和\":{\"docs\":{},\"各\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}},\"o\":{\"docs\":{},\"k\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"准\":{\"docs\":{},\"备\":{\"docs\":{},\"工\":{\"docs\":{},\"作\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}},\"的\":{\"docs\":{},\"准\":{\"docs\":{},\"备\":{\"docs\":{},\"工\":{\"docs\":{},\"作\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}},\"点\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"m\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}},\"(\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\".\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.005758157389635317}}}}}}},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.007677543186180422}}}}}}},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.005758157389635317}}}}}}}}}}}},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.012539184952978056}}}}}}}},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\":\":{\"docs\":{},\"/\":{\"docs\":{},\"/\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"/\":{\"docs\":{},\"d\":{\"docs\":{},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"s\":{\"docs\":{},\"/\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"i\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\":\":{\"docs\":{},\"/\":{\"docs\":{},\"/\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"/\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"/\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"/\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"/\":{\"6\":{\"8\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}},\"docs\":{}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"/\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"u\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"/\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"/\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"u\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":10}}}}}},\"/\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"j\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"_\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"h\":{\"docs\":{},\"t\":{\"docs\":{},\"m\":{\"docs\":{},\"l\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.005221932114882507},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"_\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\",\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"r\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\",\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.010443864229765013}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"l\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"(\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"y\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"y\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"(\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"，\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"看\":{\"docs\":{},\"第\":{\"9\":{\"docs\":{},\"步\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"docs\":{}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"k\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}},\",\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"将\":{\"docs\":{},\"任\":{\"docs\":{},\"务\":{\"docs\":{},\"提\":{\"docs\":{},\"交\":{\"docs\":{},\"给\":{\"docs\":{},\"s\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"。\":{\"docs\":{},\"而\":{\"docs\":{},\"s\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"实\":{\"docs\":{},\"际\":{\"docs\":{},\"上\":{\"docs\":{},\"关\":{\"docs\":{},\"联\":{\"docs\":{},\"的\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\",\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"，\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"k\":{\"docs\":{},\"是\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"在\":{\"docs\":{},\"单\":{\"docs\":{},\"独\":{\"docs\":{},\"的\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"c\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"/\":{\"docs\":{},\"z\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"u\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"z\":{\"docs\":{},\"d\":{\"docs\":{},\"/\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"/\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"/\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\":\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00847457627118644}}}}}}}},\"f\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"(\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"o\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}},\",\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.005758157389635317}}}}}},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"y\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"g\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}},\")\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"w\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}},\"p\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}}}}}}}},\"f\":{\"docs\":{},\"(\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"!\":{\"docs\":{},\"=\":{\"docs\":{},\"n\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}},\"&\":{\"docs\":{},\"&\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"_\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"e\":{\"docs\":{},\"q\":{\"docs\":{},\"u\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"f\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}},\"f\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"b\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"!\":{\"docs\":{},\"=\":{\"docs\":{},\"n\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"k\":{\"docs\":{},\"_\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\">\":{\"2\":{\"5\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"docs\":{}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"_\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"!\":{\"docs\":{},\"=\":{\"docs\":{},\"n\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}},\"!\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"v\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"_\":{\"docs\":{},\"v\":{\"docs\":{},\"m\":{\"docs\":{},\"_\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}},\"(\":{\"docs\":{},\"t\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"=\":{\"docs\":{},\"(\":{\"docs\":{},\"(\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"!\":{\"docs\":{},\"=\":{\"docs\":{},\"n\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.007832898172323759}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"{\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.007832898172323759}}}}}}},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.010443864229765013}}}}}}}}},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}},\"o\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}},\"j\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154},\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}},\"}\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\".\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}},\"m\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.012711864406779662}},\"：\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"单\":{\"docs\":{},\"独\":{\"docs\":{},\"管\":{\"docs\":{},\"理\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"，\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"等\":{\"docs\":{},\"；\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\".\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"g\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"g\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"y\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.03529411764705882}},\"e\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"会\":{\"docs\":{},\"将\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"的\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"到\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"的\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"并\":{\"docs\":{},\"在\":{\"docs\":{},\"下\":{\"docs\":{},\"次\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"的\":{\"docs\":{},\"最\":{\"docs\":{},\"早\":{\"docs\":{},\"时\":{\"docs\":{},\"间\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"掉\":{\"docs\":{},\"原\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"；\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"记\":{\"docs\":{},\"录\":{\"docs\":{},\"了\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"以\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"等\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"。\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"完\":{\"docs\":{},\"以\":{\"docs\":{},\"后\":{\"docs\":{},\"接\":{\"docs\":{},\"下\":{\"docs\":{},\"去\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"的\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{},\"了\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"过\":{\"docs\":{},\"则\":{\"docs\":{},\"在\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"下\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"过\":{\"docs\":{},\"则\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"，\":{\"docs\":{},\"当\":{\"docs\":{},\"前\":{\"docs\":{},\"的\":{\"docs\":{},\"应\":{\"docs\":{},\"用\":{\"docs\":{},\"处\":{\"docs\":{},\"于\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"等\":{\"docs\":{},\"待\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"的\":{\"docs\":{},\"状\":{\"docs\":{},\"态\":{\"docs\":{},\"，\":{\"docs\":{},\"会\":{\"docs\":{},\"在\":{\"docs\":{},\"合\":{\"docs\":{},\"适\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"机\":{\"docs\":{},\"选\":{\"docs\":{},\"择\":{\"docs\":{},\"进\":{\"docs\":{},\"程\":{\"docs\":{},\"重\":{\"docs\":{},\"启\":{\"docs\":{},\"来\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"此\":{\"docs\":{},\"次\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"，\":{\"docs\":{},\"且\":{\"docs\":{},\"在\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"前\":{\"docs\":{},\"不\":{\"docs\":{},\"会\":{\"docs\":{},\"再\":{\"docs\":{},\"接\":{\"docs\":{},\"收\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"行\":{\"docs\":{},\"为\":{\"docs\":{},\"，\":{\"docs\":{},\"进\":{\"docs\":{},\"程\":{\"docs\":{},\"重\":{\"docs\":{},\"启\":{\"docs\":{},\"以\":{\"docs\":{},\"后\":{\"docs\":{},\"表\":{\"docs\":{},\"示\":{\"docs\":{},\"一\":{\"docs\":{},\"次\":{\"docs\":{},\"完\":{\"docs\":{},\"整\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"结\":{\"docs\":{},\"束\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"在\":{\"docs\":{},\"下\":{\"docs\":{},\"载\":{\"docs\":{},\"到\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"且\":{\"docs\":{},\"校\":{\"docs\":{},\"验\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"后\":{\"docs\":{},\"在\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"，\":{\"docs\":{},\"由\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"介\":{\"docs\":{},\"绍\":{\"docs\":{},\"可\":{\"docs\":{},\"知\":{\"docs\":{},\"，\":{\"docs\":{},\"假\":{\"docs\":{},\"设\":{\"docs\":{},\"当\":{\"docs\":{},\"前\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"在\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"上\":{\"docs\":{},\"为\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\",\":{\"docs\":{},\"则\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"后\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"会\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"在\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"2\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"并\":{\"docs\":{},\"在\":{\"docs\":{},\"后\":{\"docs\":{},\"续\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"中\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"逐\":{\"docs\":{},\"步\":{\"docs\":{},\"往\":{\"docs\":{},\"后\":{\"docs\":{},\"追\":{\"docs\":{},\"加\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"鉴\":{\"docs\":{},\"于\":{\"docs\":{},\"空\":{\"docs\":{},\"间\":{\"docs\":{},\"占\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"考\":{\"docs\":{},\"虑\":{\"docs\":{},\"，\":{\"docs\":{},\"目\":{\"docs\":{},\"前\":{\"docs\":{},\"的\":{\"docs\":{},\"策\":{\"docs\":{},\"略\":{\"docs\":{},\"是\":{\"docs\":{},\"会\":{\"docs\":{},\"保\":{\"docs\":{},\"留\":{\"docs\":{},\"上\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"（\":{\"docs\":{},\"鉴\":{\"docs\":{},\"于\":{\"docs\":{},\"回\":{\"docs\":{},\"滚\":{\"docs\":{},\"的\":{\"docs\":{},\"考\":{\"docs\":{},\"虑\":{\"docs\":{},\"）\":{\"docs\":{},\"；\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"各\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"到\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"中\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"a\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.005758157389635317},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"v\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.02127659574468085}}}}}}},\"s\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}}}}}}}}}}}}},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"_\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"z\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\">\":{\"0\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"x\":{\"docs\":{},\"y\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"x\":{\"docs\":{},\"y\":{\"docs\":{},\"p\":{\"docs\":{},\"m\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}},\"e\":{\"docs\":{},\"实\":{\"docs\":{},\"际\":{\"docs\":{},\"上\":{\"docs\":{},\"是\":{\"docs\":{},\"指\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"。\":{\"docs\":{},\"在\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"，\":{\"docs\":{},\"构\":{\"docs\":{},\"造\":{\"docs\":{},\"出\":{\"docs\":{},\"了\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"指\":{\"docs\":{},\"定\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"实\":{\"docs\":{},\"例\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}}},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}},\"实\":{\"docs\":{},\"际\":{\"docs\":{},\"上\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{},\"反\":{\"docs\":{},\"射\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\",\":{\"docs\":{},\"即\":{\"docs\":{},\"第\":{\"8\":{\"docs\":{},\"步\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"(\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"n\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}}}}}}}}}}},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.013422818791946308}},\";\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.015665796344647518},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0071301247771836}},\"{\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}},\"e\":{\"docs\":{},\"w\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.02247191011235955},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.020887728459530026},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.005758157389635317},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.016042780748663103}},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.005221932114882507}},\"e\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"有\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"，\":{\"docs\":{},\"当\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"非\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"的\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"时\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"外\":{\"docs\":{},\"部\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"。\":{\"docs\":{},\"（\":{\"docs\":{},\"这\":{\"docs\":{},\"种\":{\"docs\":{},\"也\":{\"docs\":{},\"适\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"w\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"等\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"k\":{\"docs\":{},\"在\":{\"docs\":{},\"非\":{\"docs\":{},\"常\":{\"docs\":{},\"规\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"内\":{\"docs\":{},\"由\":{\"docs\":{},\"外\":{\"docs\":{},\"部\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"定\":{\"docs\":{},\"制\":{\"docs\":{},\"的\":{\"docs\":{},\"适\":{\"docs\":{},\"配\":{\"docs\":{},\"器\":{\"docs\":{},\"）\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"特\":{\"docs\":{},\"殊\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"及\":{\"docs\":{},\"建\":{\"docs\":{},\"议\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}},\".\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0053475935828877}}}}}}}}}}}}},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}},\":\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.012121212121212121},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.012711864406779662}}},\".\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"j\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"'\":{\"docs\":{},\":\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"'\":{\"docs\":{},\")\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"'\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"'\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00847457627118644}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"'\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"'\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"'\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"s\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"'\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"g\":{\"docs\":{},\"u\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"d\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.0211864406779661}}}}}}}}},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}},\"s\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}}}}}}}}},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}},\"x\":{\"docs\":{},\"y\":{\"docs\":{},\".\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"x\":{\"docs\":{},\"y\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\":\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00847457627118644},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.02821316614420063},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0071301247771836}}}}}}},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\":\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"x\":{\"docs\":{},\"y\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"p\":{\"docs\":{},\"m\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"_\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.013422818791946308},\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.023529411764705882},\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"g\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}},\"{\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}},\"产\":{\"docs\":{},\"物\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154}}}},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"解\":{\"docs\":{},\"压\":{\"docs\":{},\"后\":{\"docs\":{},\"一\":{\"docs\":{},\"级\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"：\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"看\":{\"docs\":{},\"到\":{\"docs\":{},\"的\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}},\"h\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"也\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"继\":{\"docs\":{},\"承\":{\"docs\":{},\"了\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"（\":{\"docs\":{},\"同\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"）\":{\"docs\":{},\"，\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"在\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"（\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"）\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.06266318537859007},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.05182341650671785},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.034482758620689655},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0106951871657754}}},\"s\":{\"docs\":{},\"h\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}},\"s\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"m\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"小\":{\"docs\":{},\"米\":{\"docs\":{},\"推\":{\"docs\":{},\"送\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"m\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"就\":{\"docs\":{},\"提\":{\"docs\":{},\"示\":{\"docs\":{},\"缺\":{\"docs\":{},\"少\":{\"docs\":{},\"权\":{\"docs\":{},\"限\":{\"docs\":{},\"声\":{\"docs\":{},\"明\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}},\",\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}},\"k\":{\"docs\":{},\"g\":{\"docs\":{},\"为\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"的\":{\"docs\":{},\"包\":{\"docs\":{},\"名\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154},\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}},\"e\":{\"docs\":{},\"时\":{\"docs\":{},\"会\":{\"docs\":{},\"分\":{\"docs\":{},\"配\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"，\":{\"docs\":{},\"负\":{\"docs\":{},\"责\":{\"docs\":{},\"该\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"类\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"。\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"所\":{\"docs\":{},\"示\":{\"docs\":{},\"：\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"导\":{\"docs\":{},\"致\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"没\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"，\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"以\":{\"docs\":{},\"后\":{\"docs\":{},\"该\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"得\":{\"docs\":{},\"到\":{\"docs\":{},\"最\":{\"docs\":{},\"好\":{\"docs\":{},\"的\":{\"docs\":{},\"解\":{\"docs\":{},\"决\":{\"docs\":{},\"，\":{\"docs\":{},\"除\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"以\":{\"docs\":{},\"外\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"均\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"；\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}},\"|\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}},\"s\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}},\"和\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}},\"e\":{\"docs\":{},\"t\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.005758157389635317}}}}}},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}},\"e\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"w\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\",\":{\"docs\":{},\"b\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\".\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.007832898172323759}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"q\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\",\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\",\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\",\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\",\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\",\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"也\":{\"docs\":{},\"是\":{\"docs\":{},\"真\":{\"docs\":{},\"正\":{\"docs\":{},\"意\":{\"docs\":{},\"义\":{\"docs\":{},\"上\":{\"docs\":{},\"的\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"用\":{\"docs\":{},\"来\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"被\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"管\":{\"docs\":{},\"理\":{\"docs\":{},\"；\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"它\":{\"docs\":{},\"也\":{\"docs\":{},\"是\":{\"docs\":{},\"真\":{\"docs\":{},\"正\":{\"docs\":{},\"的\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"在\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"理\":{\"docs\":{},\"。\":{\"docs\":{},\"他\":{\"docs\":{},\"们\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"的\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"的\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"拿\":{\"docs\":{},\"到\":{\"docs\":{},\"的\":{\"docs\":{},\"仅\":{\"docs\":{},\"仅\":{\"docs\":{},\"是\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"理\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"真\":{\"docs\":{},\"正\":{\"docs\":{},\"的\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"对\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"来\":{\"docs\":{},\"说\":{\"docs\":{},\"是\":{\"docs\":{},\"不\":{\"docs\":{},\"可\":{\"docs\":{},\"见\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"除\":{\"docs\":{},\"了\":{\"docs\":{},\"拿\":{\"docs\":{},\"到\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"展\":{\"docs\":{},\"示\":{\"docs\":{},\"之\":{\"docs\":{},\"外\":{\"docs\":{},\"还\":{\"docs\":{},\"有\":{\"docs\":{},\"其\":{\"docs\":{},\"他\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"暴\":{\"docs\":{},\"露\":{\"docs\":{},\"给\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"者\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"走\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"通\":{\"docs\":{},\"信\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"适\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"某\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"有\":{\"docs\":{},\"公\":{\"docs\":{},\"共\":{\"docs\":{},\"的\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"要\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"给\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"多\":{\"docs\":{},\"个\":{\"docs\":{},\"其\":{\"docs\":{},\"他\":{\"docs\":{},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"，\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"说\":{\"docs\":{},\"在\":{\"docs\":{},\"手\":{\"docs\":{},\"淘\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"，\":{\"docs\":{},\"s\":{\"docs\":{},\"k\":{\"docs\":{},\"u\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"s\":{\"docs\":{},\"k\":{\"docs\":{},\"u\":{\"docs\":{},\"选\":{\"docs\":{},\"择\":{\"docs\":{},\"界\":{\"docs\":{},\"面\":{\"docs\":{},\")\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"会\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"给\":{\"docs\":{},\"详\":{\"docs\":{},\"情\":{\"docs\":{},\"，\":{\"docs\":{},\"购\":{\"docs\":{},\"物\":{\"docs\":{},\"车\":{\"docs\":{},\"，\":{\"docs\":{},\"聚\":{\"docs\":{},\"划\":{\"docs\":{},\"算\":{\"docs\":{},\"等\":{\"docs\":{},\"多\":{\"docs\":{},\"个\":{\"docs\":{},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"；\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"在\":{\"docs\":{},\"某\":{\"docs\":{},\"些\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"，\":{\"docs\":{},\"登\":{\"docs\":{},\"录\":{\"docs\":{},\"界\":{\"docs\":{},\"面\":{\"docs\":{},\"也\":{\"docs\":{},\"以\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"给\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"按\":{\"docs\":{},\"需\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}},\"相\":{\"docs\":{},\"当\":{\"docs\":{},\"于\":{\"docs\":{},\"是\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"简\":{\"docs\":{},\"化\":{\"docs\":{},\"版\":{\"docs\":{},\"，\":{\"docs\":{},\"仅\":{\"docs\":{},\"仅\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"和\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"的\":{\"docs\":{},\"通\":{\"docs\":{},\"信\":{\"docs\":{},\"而\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"，\":{\"docs\":{},\"它\":{\"docs\":{},\"和\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"，\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"都\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"了\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"。\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"下\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"草\":{\"docs\":{},\"图\":{\"docs\":{},\"了\":{\"docs\":{},\"解\":{\"docs\":{},\"大\":{\"docs\":{},\"致\":{\"docs\":{},\"的\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}},\")\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}},\"与\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"基\":{\"docs\":{},\"本\":{\"docs\":{},\"一\":{\"docs\":{},\"致\":{\"docs\":{},\"，\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"作\":{\"docs\":{},\"为\":{\"docs\":{},\"真\":{\"docs\":{},\"正\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"膨\":{\"docs\":{},\"化\":{\"docs\":{},\"的\":{\"docs\":{},\"基\":{\"docs\":{},\"本\":{\"docs\":{},\"条\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"只\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{},\"就\":{\"docs\":{},\"像\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"，\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"作\":{\"docs\":{},\"为\":{\"docs\":{},\"子\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"添\":{\"docs\":{},\"加\":{\"docs\":{},\"在\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"。\":{\"docs\":{},\"当\":{\"docs\":{},\"然\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"也\":{\"docs\":{},\"有\":{\"docs\":{},\"一\":{\"docs\":{},\"定\":{\"docs\":{},\"的\":{\"docs\":{},\"隐\":{\"docs\":{},\"患\":{\"docs\":{},\"，\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"不\":{\"docs\":{},\"要\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"y\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"等\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"强\":{\"docs\":{},\"烈\":{\"docs\":{},\"依\":{\"docs\":{},\"托\":{\"docs\":{},\"于\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"化\":{\"docs\":{},\"拆\":{\"docs\":{},\"分\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"案\":{\"docs\":{},\"。\":{\"docs\":{},\"它\":{\"docs\":{},\"的\":{\"docs\":{},\"解\":{\"docs\":{},\"耦\":{\"docs\":{},\"层\":{\"docs\":{},\"度\":{\"docs\":{},\"介\":{\"docs\":{},\"于\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"和\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"。\":{\"docs\":{},\"相\":{\"docs\":{},\"比\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"灵\":{\"docs\":{},\"活\":{\"docs\":{},\"层\":{\"docs\":{},\"度\":{\"docs\":{},\"更\":{\"docs\":{},\"高\":{\"docs\":{},\"。\":{\"docs\":{},\"不\":{\"docs\":{},\"过\":{\"docs\":{},\"代\":{\"docs\":{},\"理\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"并\":{\"docs\":{},\"不\":{\"docs\":{},\"能\":{\"docs\":{},\"完\":{\"docs\":{},\"全\":{\"docs\":{},\"杜\":{\"docs\":{},\"绝\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"非\":{\"docs\":{},\"常\":{\"docs\":{},\"规\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"来\":{\"docs\":{},\"获\":{\"docs\":{},\"取\":{\"docs\":{},\"远\":{\"docs\":{},\"端\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"来\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"另\":{\"docs\":{},\"外\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"某\":{\"docs\":{},\"些\":{\"docs\":{},\"边\":{\"docs\":{},\"缘\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"无\":{\"docs\":{},\"非\":{\"docs\":{},\"被\":{\"docs\":{},\"完\":{\"docs\":{},\"全\":{\"docs\":{},\"代\":{\"docs\":{},\"理\":{\"docs\":{},\"的\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"也\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"在\":{\"docs\":{},\"以\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"迭\":{\"docs\":{},\"代\":{\"docs\":{},\"中\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"优\":{\"docs\":{},\"化\":{\"docs\":{},\"，\":{\"docs\":{},\"对\":{\"docs\":{},\"于\":{\"docs\":{},\"非\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"化\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"了\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"化\":{\"docs\":{},\"拆\":{\"docs\":{},\"解\":{\"docs\":{},\"方\":{\"docs\":{},\"案\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"种\":{\"docs\":{},\"思\":{\"docs\":{},\"路\":{\"docs\":{},\"也\":{\"docs\":{},\"是\":{\"docs\":{},\"同\":{\"docs\":{},\"样\":{\"docs\":{},\"适\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"的\":{\"docs\":{},\"特\":{\"docs\":{},\"点\":{\"docs\":{},\"和\":{\"docs\":{},\"不\":{\"docs\":{},\"足\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"参\":{\"docs\":{},\"照\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"在\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"注\":{\"docs\":{},\"册\":{\"docs\":{},\"。\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"时\":{\"docs\":{},\"以\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154}},\"e\":{\"docs\":{},\":\":{\"6\":{\"docs\":{},\".\":{\"3\":{\"docs\":{},\".\":{\"0\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"q\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.020887728459530026},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.008912655971479501}}}}}},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}},\"u\":{\"docs\":{},\"n\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}},\"e\":{\"docs\":{},\"层\":{\"docs\":{},\"：\":{\"docs\":{},\"主\":{\"docs\":{},\"要\":{\"docs\":{},\"包\":{\"docs\":{},\"括\":{\"docs\":{},\"清\":{\"docs\":{},\"单\":{\"docs\":{},\"管\":{\"docs\":{},\"理\":{\"docs\":{},\"、\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"管\":{\"docs\":{},\"理\":{\"docs\":{},\"、\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"代\":{\"docs\":{},\"理\":{\"docs\":{},\"三\":{\"docs\":{},\"大\":{\"docs\":{},\"块\":{\"docs\":{},\"，\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"的\":{\"docs\":{},\"触\":{\"docs\":{},\"发\":{\"docs\":{},\"点\":{\"docs\":{},\"按\":{\"docs\":{},\"需\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"和\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"；\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"层\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"了\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"期\":{\"docs\":{},\"快\":{\"docs\":{},\"速\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"和\":{\"docs\":{},\"监\":{\"docs\":{},\"控\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"模\":{\"docs\":{},\"块\":{\"docs\":{},\"。\":{\"docs\":{},\"从\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"层\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"看\":{\"docs\":{},\"到\":{\"docs\":{},\"，\":{\"docs\":{},\"最\":{\"docs\":{},\"核\":{\"docs\":{},\"心\":{\"docs\":{},\"的\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"代\":{\"docs\":{},\"理\":{\"docs\":{},\"点\":{\"docs\":{},\"：\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"是\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"：\":{\"docs\":{},\"负\":{\"docs\":{},\"责\":{\"docs\":{},\"路\":{\"docs\":{},\"由\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"到\":{\"docs\":{},\"各\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"，\":{\"docs\":{},\"第\":{\"docs\":{},\"二\":{\"docs\":{},\"个\":{\"docs\":{},\"是\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"：\":{\"docs\":{},\"负\":{\"docs\":{},\"责\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"时\":{\"docs\":{},\"能\":{\"docs\":{},\"够\":{\"docs\":{},\"找\":{\"docs\":{},\"到\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"内\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"；\":{\"docs\":{},\"这\":{\"docs\":{},\"是\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"能\":{\"docs\":{},\"够\":{\"docs\":{},\"真\":{\"docs\":{},\"正\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"起\":{\"docs\":{},\"来\":{\"docs\":{},\"的\":{\"docs\":{},\"根\":{\"docs\":{},\"本\":{\"docs\":{},\"；\":{\"docs\":{},\"其\":{\"docs\":{},\"余\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"理\":{\"docs\":{},\"点\":{\"docs\":{},\"均\":{\"docs\":{},\"是\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"保\":{\"docs\":{},\"证\":{\"docs\":{},\"在\":{\"docs\":{},\"必\":{\"docs\":{},\"要\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"机\":{\"docs\":{},\"按\":{\"docs\":{},\"需\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"起\":{\"docs\":{},\"来\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"让\":{\"docs\":{},\"其\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"被\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"和\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"k\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"+\":{\"docs\":{},\"\\\"\":{\"docs\":{},\":\":{\"docs\":{},\"\\\"\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"(\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0053475935828877}},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}}}}}},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"在\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"就\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"了\":{\"docs\":{},\"吗\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"都\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"吧\":{\"docs\":{},\"？\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"m\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"_\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"b\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"d\":{\"docs\":{},\":\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.012121212121212121}}}}}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}}}}}}}}}}}}}}}},\"c\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}}}},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}},\"u\":{\"docs\":{},\"p\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}}}}},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0345489443378119},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.0219435736677116},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0071301247771836}},\"{\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"是\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"的\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"，\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"以\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"为\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"夹\":{\"docs\":{},\"名\":{\"docs\":{},\"，\":{\"docs\":{},\"首\":{\"docs\":{},\"次\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"后\":{\"docs\":{},\"会\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"到\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"中\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"含\":{\"docs\":{},\"有\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"z\":{\"docs\":{},\"i\":{\"docs\":{},\"p\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"n\":{\"docs\":{\"principle-intro/File_architecture_runtime.html\":{\"ref\":\"principle-intro/File_architecture_runtime.html\",\"tf\":0.1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.010067114093959731},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.005758157389635317},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.018808777429467086},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.012477718360071301}},\"[\":{\"docs\":{},\"]\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"{\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"}\":{\"docs\":{},\",\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\",\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"按\":{\"docs\":{},\"钮\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"失\":{\"docs\":{},\"败\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"保\":{\"docs\":{},\"证\":{\"docs\":{},\"自\":{\"docs\":{},\"身\":{\"docs\":{},\"封\":{\"docs\":{},\"装\":{\"docs\":{},\"性\":{\"docs\":{},\"；\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"某\":{\"docs\":{},\"些\":{\"docs\":{},\"中\":{\"docs\":{},\"间\":{\"docs\":{},\"件\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"只\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"若\":{\"docs\":{},\"干\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"封\":{\"docs\":{},\"装\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"出\":{\"docs\":{},\"来\":{\"docs\":{},\"，\":{\"docs\":{},\"以\":{\"docs\":{},\"保\":{\"docs\":{},\"证\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"精\":{\"docs\":{},\"简\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}},\"t\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154}}},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"并\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"打\":{\"docs\":{},\"入\":{\"docs\":{},\"主\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"因\":{\"docs\":{},\"为\":{\"docs\":{},\"这\":{\"docs\":{},\"只\":{\"docs\":{},\"是\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"所\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"。\":{\"docs\":{},\"最\":{\"docs\":{},\"终\":{\"docs\":{},\"会\":{\"docs\":{},\"将\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"和\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"打\":{\"docs\":{},\"在\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"同\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"加\":{\"docs\":{},\"上\":{\"docs\":{},\"两\":{\"docs\":{},\"者\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"，\":{\"docs\":{},\"成\":{\"docs\":{},\"为\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"o\":{\"docs\":{},\"等\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"。\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"会\":{\"docs\":{},\"有\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"2\":{\"docs\":{},\"、\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"3\":{\"docs\":{\"principle-intro/File_architecture_runtime.html\":{\"ref\":\"principle-intro/File_architecture_runtime.html\",\"tf\":0.1}}},\"docs\":{}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}},\"e\":{\"docs\":{},\",\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"公\":{\"docs\":{},\"共\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}},\"的\":{\"docs\":{},\"导\":{\"docs\":{},\"出\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\",\":{\"docs\":{},\"规\":{\"docs\":{},\"避\":{\"docs\":{},\"因\":{\"docs\":{},\"为\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"不\":{\"docs\":{},\"一\":{\"docs\":{},\"致\":{\"docs\":{},\"导\":{\"docs\":{},\"致\":{\"docs\":{},\"多\":{\"docs\":{},\"份\":{\"docs\":{},\"m\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"的\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"。\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"参\":{\"docs\":{},\"考\":{\"docs\":{},\"：\":{\"docs\":{},\"h\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\":\":{\"docs\":{},\"/\":{\"docs\":{},\"/\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}},\"相\":{\"docs\":{},\"互\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"导\":{\"docs\":{},\"致\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"@\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154}}}}}}}}}}}},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.005221932114882507}}}}},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}},\",\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}},\"d\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"的\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"。\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"s\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}},\"（\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"）\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.010810810810810811}}}}}}}}}}},\"y\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"k\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.010443864229765013}},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.01818181818181818}}}}},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}},\"u\":{\"docs\":{},\"e\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.01818181818181818},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.03691275167785235},\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.012711864406779662}},\",\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.012422360248447204}}},\"表\":{\"docs\":{},\"明\":{\"docs\":{},\"启\":{\"docs\":{},\"用\":{\"docs\":{},\"了\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"并\":{\"docs\":{},\"将\":{\"docs\":{},\"当\":{\"docs\":{},\"前\":{\"docs\":{},\"模\":{\"docs\":{},\"块\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"成\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"形\":{\"docs\":{},\"式\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"供\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}},\"i\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"y\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"g\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00847457627118644},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"w\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.007677543186180422},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0106951871657754}}}}},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0053475935828877}}}},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"@\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"g\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.010810810810810811}},\"的\":{\"docs\":{},\"警\":{\"docs\":{},\"告\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"：\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}},\"y\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\":\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}},\"m\":{\"docs\":{},\"e\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"v\":{\"4\":{\"docs\":{},\":\":{\"2\":{\"5\":{\"docs\":{},\".\":{\"3\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"'\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}},\"docs\":{}}},\"7\":{\"docs\":{},\":\":{\"2\":{\"5\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"'\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00847457627118644}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}},\"docs\":{}}},\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{\"principle-intro/Apk_architecture.html\":{\"ref\":\"principle-intro/Apk_architecture.html\",\"tf\":0.07142857142857142}}}}}}},\"@\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"其\":{\"docs\":{},\"中\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"为\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"记\":{\"docs\":{},\"录\":{\"docs\":{},\"了\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"大\":{\"docs\":{},\"小\":{\"docs\":{},\"，\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"，\":{\"docs\":{},\"名\":{\"docs\":{},\"字\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"些\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"在\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"，\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"这\":{\"docs\":{},\"些\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"在\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"被\":{\"docs\":{},\"触\":{\"docs\":{},\"发\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"去\":{\"docs\":{},\"按\":{\"docs\":{},\"需\":{\"docs\":{},\"的\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"，\":{\"docs\":{},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"对\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"者\":{\"docs\":{},\"透\":{\"docs\":{},\"明\":{\"docs\":{},\"（\":{\"docs\":{},\"从\":{\"docs\":{},\"中\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"看\":{\"docs\":{},\"到\":{\"docs\":{},\"默\":{\"docs\":{},\"认\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"下\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"对\":{\"docs\":{},\"外\":{\"docs\":{},\"暴\":{\"docs\":{},\"露\":{\"docs\":{},\"的\":{\"docs\":{},\"只\":{\"docs\":{},\"是\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"原\":{\"docs\":{},\"生\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"，\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"等\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"）\":{\"docs\":{},\"。\":{\"docs\":{\"principle-intro/Apk_architecture.html\":{\"ref\":\"principle-intro/Apk_architecture.html\",\"tf\":0.07142857142857142}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.028720626631853787},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.02111324376199616},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.0219435736677116},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.016042780748663103}}}}},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"h\":{\"docs\":{},\"t\":{\"docs\":{},\"m\":{\"docs\":{},\"l\":{\"docs\":{},\"?\":{\"docs\":{},\"h\":{\"docs\":{},\"l\":{\"docs\":{},\"=\":{\"docs\":{},\"z\":{\"docs\":{},\"h\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}},\"y\":{\"docs\":{},\"e\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.030303030303030304}}}},\"{\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.048484848484848485},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.040268456375838924},\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.07865168539325842},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0391644908616188},\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.018633540372670808},\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.0425531914893617},\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.032432432432432434},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.05084745762711865},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.02495201535508637},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.04075235109717868},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.05169340463458111}}},\"}\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.04242424242424243},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.0436241610738255},\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.07865168539325842},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.06005221932114883},\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.018633540372670808},\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.031914893617021274},\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.021621621621621623},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.05508474576271186},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.046065259117082535},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.050156739811912224},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.05525846702317291}},\")\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.007832898172323759},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"e\":{\"docs\":{},\"{\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533},\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.010810810810810811}}},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"(\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"w\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"上\":{\"docs\":{},\"线\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"运\":{\"docs\":{},\"维\":{\"docs\":{},\"期\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"了\":{\"docs\":{},\"一\":{\"docs\":{},\"整\":{\"docs\":{},\"套\":{\"docs\":{},\"完\":{\"docs\":{},\"整\":{\"docs\":{},\"的\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}},\"述\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"的\":{\"docs\":{},\"配\":{\"docs\":{},\"套\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"描\":{\"docs\":{},\"述\":{\"docs\":{},\"了\":{\"docs\":{},\"本\":{\"docs\":{},\"次\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"的\":{\"docs\":{},\"结\":{\"docs\":{},\"果\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"重\":{\"docs\":{},\"新\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"不\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"的\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}},\"篇\":{\"docs\":{},\"先\":{\"docs\":{},\"到\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"，\":{\"docs\":{},\"各\":{\"docs\":{},\"位\":{\"docs\":{},\"先\":{\"docs\":{},\"喝\":{\"docs\":{},\"口\":{\"docs\":{},\"水\":{\"docs\":{},\"，\":{\"docs\":{},\"再\":{\"docs\":{},\"来\":{\"docs\":{},\"下\":{\"docs\":{},\"篇\":{\"docs\":{},\"的\":{\"docs\":{},\"分\":{\"docs\":{},\"析\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}},\"与\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"化\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"的\":{\"docs\":{},\"是\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"多\":{\"docs\":{},\"进\":{\"docs\":{},\"程\":{\"docs\":{},\"的\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"，\":{\"docs\":{},\"他\":{\"docs\":{},\"主\":{\"docs\":{},\"要\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"的\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"环\":{\"docs\":{},\"境\":{\"docs\":{},\"中\":{\"docs\":{},\"按\":{\"docs\":{},\"需\":{\"docs\":{},\"地\":{\"docs\":{},\"去\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"各\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"，\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"类\":{\"docs\":{},\"和\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"。\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"以\":{\"docs\":{},\"包\":{\"docs\":{},\"名\":{\"docs\":{},\"为\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"夹\":{\"docs\":{},\"存\":{\"docs\":{},\"放\":{\"docs\":{},\"类\":{\"docs\":{},\"似\":{\"docs\":{},\"，\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"存\":{\"docs\":{},\"放\":{\"docs\":{},\"的\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"夹\":{\"docs\":{},\"以\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"为\":{\"docs\":{},\"名\":{\"docs\":{},\"字\":{\"docs\":{},\"，\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"管\":{\"docs\":{},\"理\":{\"docs\":{},\"与\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"一\":{\"docs\":{},\"致\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"点\":{\"docs\":{},\"是\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"只\":{\"docs\":{},\"在\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"过\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"以\":{\"docs\":{},\"后\":{\"docs\":{},\"才\":{\"docs\":{},\"会\":{\"docs\":{},\"有\":{\"docs\":{},\"，\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"意\":{\"docs\":{},\"味\":{\"docs\":{},\"着\":{\"docs\":{},\"已\":{\"docs\":{},\"经\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"一\":{\"docs\":{},\"次\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"；\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"通\":{\"docs\":{},\"常\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"下\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"从\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"2\":{\"docs\":{},\"开\":{\"docs\":{},\"始\":{\"docs\":{},\"（\":{\"docs\":{},\"未\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"过\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"除\":{\"docs\":{},\"外\":{\"docs\":{},\"）\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"相\":{\"docs\":{},\"对\":{\"docs\":{},\"于\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"会\":{\"docs\":{},\"返\":{\"docs\":{},\"回\":{\"docs\":{},\"该\":{\"docs\":{},\"次\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"，\":{\"docs\":{},\"数\":{\"docs\":{},\"据\":{\"docs\":{},\"结\":{\"docs\":{},\"构\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"：\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"灵\":{\"docs\":{},\"活\":{\"docs\":{},\"发\":{\"docs\":{},\"布\":{\"docs\":{},\"自\":{\"docs\":{},\"己\":{\"docs\":{},\"的\":{\"docs\":{},\"需\":{\"docs\":{},\"求\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}},\"层\":{\"docs\":{},\"基\":{\"docs\":{},\"本\":{\"docs\":{},\"单\":{\"docs\":{},\"位\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}},\"上\":{\"docs\":{},\"以\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"为\":{\"docs\":{},\"边\":{\"docs\":{},\"界\":{\"docs\":{},\"自\":{\"docs\":{},\"上\":{\"docs\":{},\"而\":{\"docs\":{},\"下\":{\"docs\":{},\"与\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"允\":{\"docs\":{},\"许\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"；\":{\"docs\":{},\"相\":{\"docs\":{},\"对\":{\"docs\":{},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"耦\":{\"docs\":{},\"合\":{\"docs\":{},\"建\":{\"docs\":{},\"议\":{\"docs\":{},\"封\":{\"docs\":{},\"装\":{\"docs\":{},\"成\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"时\":{\"docs\":{},\"，\":{\"docs\":{},\"才\":{\"docs\":{},\"会\":{\"docs\":{},\"去\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"和\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"q\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"期\":{\"docs\":{},\"间\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"涉\":{\"docs\":{},\"及\":{\"docs\":{},\"到\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"采\":{\"docs\":{},\"用\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"。\":{\"docs\":{},\"获\":{\"docs\":{},\"取\":{\"docs\":{},\"到\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"句\":{\"docs\":{},\"柄\":{\"docs\":{},\"后\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"操\":{\"docs\":{},\"作\":{\"docs\":{},\"即\":{\"docs\":{},\"可\":{\"docs\":{},\"。\":{\"docs\":{},\"*\":{\"docs\":{},\"*\":{\"docs\":{},\"建\":{\"docs\":{},\"议\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"涉\":{\"docs\":{},\"及\":{\"docs\":{},\"到\":{\"docs\":{},\"的\":{\"docs\":{},\"交\":{\"docs\":{},\"互\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"等\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"封\":{\"docs\":{},\"装\":{\"docs\":{},\"在\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"*\":{\"docs\":{},\"*\":{\"docs\":{},\"，\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"说\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"按\":{\"docs\":{},\"钮\":{\"docs\":{},\"的\":{\"docs\":{},\"点\":{\"docs\":{},\"击\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"异\":{\"docs\":{},\"常\":{\"docs\":{},\"处\":{\"docs\":{},\"理\":{\"docs\":{},\"全\":{\"docs\":{},\"都\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"。\":{\"docs\":{},\"这\":{\"docs\":{},\"样\":{\"docs\":{},\"的\":{\"docs\":{},\"话\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"的\":{\"docs\":{},\"边\":{\"docs\":{},\"界\":{\"docs\":{},\"也\":{\"docs\":{},\"更\":{\"docs\":{},\"清\":{\"docs\":{},\"晰\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"灰\":{\"docs\":{},\"度\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"k\":{\"docs\":{},\"，\":{\"docs\":{},\"快\":{\"docs\":{},\"速\":{\"docs\":{},\"测\":{\"docs\":{},\"试\":{\"docs\":{},\"效\":{\"docs\":{},\"果\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"有\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"时\":{\"docs\":{},\"回\":{\"docs\":{},\"滚\":{\"docs\":{\"update/\":{\"ref\":\"update/\",\"tf\":0.16666666666666666}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"降\":{\"docs\":{},\"低\":{\"docs\":{},\"用\":{\"docs\":{},\"户\":{\"docs\":{},\"等\":{\"docs\":{},\"待\":{\"docs\":{},\"时\":{\"docs\":{},\"间\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"在\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"k\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"上\":{\"docs\":{},\"首\":{\"docs\":{},\"次\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"时\":{\"docs\":{},\"关\":{\"docs\":{},\"闭\":{\"docs\":{},\"了\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"上\":{\"docs\":{},\"首\":{\"docs\":{},\"次\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"时\":{\"docs\":{},\"关\":{\"docs\":{},\"闭\":{\"docs\":{},\"了\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"2\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"走\":{\"docs\":{},\"解\":{\"docs\":{},\"释\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"。\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"后\":{\"docs\":{},\"台\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"异\":{\"docs\":{},\"步\":{\"docs\":{},\"任\":{\"docs\":{},\"务\":{\"docs\":{},\"走\":{\"docs\":{},\"原\":{\"docs\":{},\"生\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"为\":{\"docs\":{},\"下\":{\"docs\":{},\"次\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"做\":{\"docs\":{},\"好\":{\"docs\":{},\"准\":{\"docs\":{},\"备\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"这\":{\"docs\":{},\"三\":{\"docs\":{},\"个\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"，\":{\"docs\":{},\"会\":{\"docs\":{},\"在\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"关\":{\"docs\":{},\"键\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"地\":{\"docs\":{},\"方\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"。\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"，\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"能\":{\"docs\":{},\"够\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"通\":{\"docs\":{},\"常\":{\"docs\":{},\"都\":{\"docs\":{},\"会\":{\"docs\":{},\"对\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"上\":{\"docs\":{},\"动\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"手\":{\"docs\":{},\"脚\":{\"docs\":{},\"，\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"也\":{\"docs\":{},\"是\":{\"docs\":{},\"类\":{\"docs\":{},\"似\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"例\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}},\"什\":{\"docs\":{},\"么\":{\"docs\":{},\"不\":{\"docs\":{},\"用\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"去\":{\"docs\":{},\"完\":{\"docs\":{},\"全\":{\"docs\":{},\"适\":{\"docs\":{},\"配\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}},\"会\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"呢\":{\"docs\":{},\"，\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"明\":{\"docs\":{},\"明\":{\"docs\":{},\"写\":{\"docs\":{},\"的\":{\"docs\":{},\"很\":{\"docs\":{},\"清\":{\"docs\":{},\"楚\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"这\":{\"docs\":{},\"么\":{\"docs\":{},\"做\":{\"docs\":{},\"?\":{\"docs\":{},\"回\":{\"docs\":{},\"顾\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"的\":{\"docs\":{},\"流\":{\"docs\":{},\"程\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}},\"四\":{\"docs\":{},\"大\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"预\":{\"docs\":{},\"留\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"坑\":{\"docs\":{},\"位\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"创\":{\"docs\":{},\"建\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"创\":{\"docs\":{},\"建\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"创\":{\"docs\":{},\"建\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"了\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}},\"从\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"的\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"期\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"上\":{\"docs\":{},\"已\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"的\":{\"docs\":{},\"列\":{\"docs\":{},\"表\":{\"docs\":{},\"中\":{\"docs\":{},\"找\":{\"docs\":{},\"到\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"在\":{\"docs\":{},\"第\":{\"docs\":{},\"在\":{\"docs\":{},\"第\":{\"1\":{\"0\":{\"docs\":{},\"步\":{\"docs\":{},\"中\":{\"docs\":{},\"添\":{\"docs\":{},\"加\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}},\"docs\":{}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"中\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"并\":{\"docs\":{},\"且\":{\"docs\":{},\"创\":{\"docs\":{},\"建\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"；\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"上\":{\"docs\":{},\"图\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"看\":{\"docs\":{},\"出\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"后\":{\"docs\":{},\"大\":{\"docs\":{},\"致\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"的\":{\"docs\":{},\"结\":{\"docs\":{},\"构\":{\"docs\":{},\"：\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}}}}}}}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"中\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"例\":{\"docs\":{},\"子\":{\"docs\":{},\"开\":{\"docs\":{},\"始\":{\"docs\":{},\"，\":{\"docs\":{},\"假\":{\"docs\":{},\"设\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"发\":{\"docs\":{},\"了\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\",\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"了\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"s\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"和\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"地\":{\"docs\":{},\"方\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\",\":{\"docs\":{},\"并\":{\"docs\":{},\"且\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"了\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}},\"反\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"看\":{\"docs\":{},\"到\":{\"docs\":{},\"，\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"是\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\",\":{\"docs\":{},\"那\":{\"docs\":{},\"么\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"值\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"上\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"上\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"以\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"的\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"的\":{\"docs\":{},\"生\":{\"docs\":{},\"命\":{\"docs\":{},\"周\":{\"docs\":{},\"期\":{\"docs\":{},\"为\":{\"docs\":{},\"例\":{\"docs\":{},\"，\":{\"docs\":{},\"参\":{\"docs\":{},\"见\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"技\":{\"docs\":{},\"术\":{\"docs\":{},\"方\":{\"docs\":{},\"案\":{\"docs\":{},\"为\":{\"docs\":{},\"基\":{\"docs\":{},\"础\":{\"docs\":{},\"，\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"看\":{\"docs\":{},\"作\":{\"docs\":{},\"是\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"子\":{\"docs\":{},\"集\":{\"docs\":{},\"，\":{\"docs\":{},\"专\":{\"docs\":{},\"注\":{\"docs\":{},\"于\":{\"docs\":{},\"单\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"故\":{\"docs\":{},\"障\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"。\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"做\":{\"docs\":{},\"的\":{\"docs\":{},\"事\":{\"docs\":{},\"小\":{\"docs\":{},\"而\":{\"docs\":{},\"精\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"速\":{\"docs\":{},\"度\":{\"docs\":{},\"、\":{\"docs\":{},\"线\":{\"docs\":{},\"上\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"速\":{\"docs\":{},\"度\":{\"docs\":{},\"都\":{\"docs\":{},\"是\":{\"docs\":{},\"远\":{\"docs\":{},\"远\":{\"docs\":{},\"快\":{\"docs\":{},\"于\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"为\":{\"docs\":{},\"例\":{\"docs\":{},\"，\":{\"docs\":{},\"他\":{\"docs\":{},\"和\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"类\":{\"docs\":{},\"都\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"了\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"当\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"，\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"将\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"路\":{\"docs\":{},\"由\":{\"docs\":{},\"到\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"上\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"为\":{\"docs\":{},\"例\":{\"docs\":{},\"（\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"只\":{\"docs\":{},\"做\":{\"docs\":{},\"范\":{\"docs\":{},\"例\":{\"docs\":{},\"，\":{\"docs\":{},\"与\":{\"docs\":{},\"真\":{\"docs\":{},\"实\":{\"docs\":{},\"的\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"差\":{\"docs\":{},\"异\":{\"docs\":{},\"）\":{\"docs\":{},\"：\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"很\":{\"docs\":{},\"多\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"场\":{\"docs\":{},\"景\":{\"docs\":{},\"。\":{\"docs\":{},\"原\":{\"docs\":{},\"生\":{\"docs\":{},\"的\":{\"docs\":{},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"提\":{\"docs\":{},\"前\":{\"docs\":{},\"注\":{\"docs\":{},\"册\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"种\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"对\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"而\":{\"docs\":{},\"言\":{\"docs\":{},\"开\":{\"docs\":{},\"销\":{\"docs\":{},\"较\":{\"docs\":{},\"大\":{\"docs\":{},\"。\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"提\":{\"docs\":{},\"前\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"注\":{\"docs\":{},\"册\":{\"docs\":{},\"以\":{\"docs\":{},\"避\":{\"docs\":{},\"免\":{\"docs\":{},\"后\":{\"docs\":{},\"期\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"时\":{\"docs\":{},\"无\":{\"docs\":{},\"法\":{\"docs\":{},\"找\":{\"docs\":{},\"到\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"的\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"命\":{\"docs\":{},\"令\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"通\":{\"docs\":{},\"知\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"是\":{\"docs\":{},\"异\":{\"docs\":{},\"步\":{\"docs\":{},\"返\":{\"docs\":{},\"回\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"远\":{\"docs\":{},\"端\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"传\":{\"docs\":{},\"入\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"回\":{\"docs\":{},\"调\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"返\":{\"docs\":{},\"回\":{\"docs\":{},\"，\":{\"docs\":{},\"适\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"和\":{\"docs\":{},\"远\":{\"docs\":{},\"端\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"简\":{\"docs\":{},\"单\":{\"docs\":{},\"通\":{\"docs\":{},\"信\":{\"docs\":{},\"的\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"上\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}},\"是\":{\"docs\":{},\"正\":{\"docs\":{},\"确\":{\"docs\":{},\"的\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"姿\":{\"docs\":{},\"势\":{\"docs\":{},\"，\":{\"docs\":{},\"下\":{\"docs\":{},\"面\":{\"docs\":{},\"是\":{\"docs\":{},\"常\":{\"docs\":{},\"见\":{\"docs\":{},\"的\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"常\":{\"docs\":{},\"见\":{\"docs\":{},\"的\":{\"docs\":{},\"错\":{\"docs\":{},\"误\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}},\"及\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"为\":{\"docs\":{},\"例\":{\"docs\":{},\"，\":{\"docs\":{},\"看\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"在\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"中\":{\"docs\":{},\"点\":{\"docs\":{},\"击\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"为\":{\"docs\":{},\"例\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"共\":{\"docs\":{},\"享\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}},\"其\":{\"docs\":{},\"它\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}},\"他\":{\"docs\":{},\"：\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}},\"减\":{\"docs\":{},\"少\":{\"docs\":{},\"包\":{\"docs\":{},\"体\":{\"docs\":{},\"积\":{\"docs\":{},\"。\":{\"docs\":{},\"不\":{\"docs\":{},\"常\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"放\":{\"docs\":{},\"在\":{\"docs\":{},\"云\":{\"docs\":{},\"端\":{\"docs\":{},\"，\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"时\":{\"docs\":{},\"按\":{\"docs\":{},\"需\":{\"docs\":{},\"下\":{\"docs\":{},\"载\":{\"docs\":{},\"。\":{\"docs\":{},\"当\":{\"docs\":{},\"用\":{\"docs\":{},\"户\":{\"docs\":{},\"设\":{\"docs\":{},\"备\":{\"docs\":{},\"空\":{\"docs\":{},\"间\":{\"docs\":{},\"紧\":{\"docs\":{},\"张\":{\"docs\":{},\"时\":{\"docs\":{},\",\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"清\":{\"docs\":{},\"理\":{\"docs\":{},\"掉\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"长\":{\"docs\":{},\"期\":{\"docs\":{},\"不\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"功\":{\"docs\":{},\"能\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.012121212121212121},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.012121212121212121},\"update/\":{\"ref\":\"update/\",\"tf\":10.166666666666666},\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"：\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}},\"与\":{\"docs\":{},\"原\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"策\":{\"docs\":{},\"略\":{\"docs\":{},\"相\":{\"docs\":{},\"比\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"种\":{\"docs\":{},\"相\":{\"docs\":{},\"对\":{\"docs\":{},\"比\":{\"docs\":{},\"较\":{\"docs\":{},\"轻\":{\"docs\":{},\"量\":{\"docs\":{},\"化\":{\"docs\":{},\"的\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"策\":{\"docs\":{},\"略\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"用\":{\"docs\":{},\"户\":{\"docs\":{},\"下\":{\"docs\":{},\"载\":{\"docs\":{},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"，\":{\"docs\":{},\"只\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"下\":{\"docs\":{},\"载\":{\"docs\":{},\"仅\":{\"docs\":{},\"仅\":{\"docs\":{},\"差\":{\"docs\":{},\"量\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"来\":{\"docs\":{},\"达\":{\"docs\":{},\"到\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"效\":{\"docs\":{},\"果\":{\"docs\":{},\"；\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"静\":{\"docs\":{},\"默\":{\"docs\":{},\"的\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"两\":{\"docs\":{},\"者\":{\"docs\":{},\"相\":{\"docs\":{},\"结\":{\"docs\":{},\"合\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"使\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"率\":{\"docs\":{},\"远\":{\"docs\":{},\"高\":{\"docs\":{},\"于\":{\"docs\":{},\"普\":{\"docs\":{},\"通\":{\"docs\":{},\"的\":{\"docs\":{},\"升\":{\"docs\":{},\"级\":{\"docs\":{},\"策\":{\"docs\":{},\"略\":{\"docs\":{},\"。\":{\"docs\":{\"update/\":{\"ref\":\"update/\",\"tf\":0.16666666666666666}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"适\":{\"docs\":{},\"合\":{\"docs\":{},\"用\":{\"docs\":{},\"来\":{\"docs\":{},\"解\":{\"docs\":{},\"决\":{\"docs\":{},\"下\":{\"docs\":{},\"面\":{\"docs\":{},\"等\":{\"docs\":{},\"需\":{\"docs\":{},\"求\":{\"docs\":{},\"：\":{\"docs\":{\"update/\":{\"ref\":\"update/\",\"tf\":0.16666666666666666}}}}}}}}}}}}}},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"会\":{\"docs\":{},\"在\":{\"docs\":{},\"下\":{\"docs\":{},\"次\":{\"docs\":{},\"进\":{\"docs\":{},\"程\":{\"docs\":{},\"重\":{\"docs\":{},\"启\":{\"docs\":{},\"后\":{\"docs\":{},\"去\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"策\":{\"docs\":{},\"略\":{\"docs\":{},\"是\":{\"docs\":{},\"按\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"从\":{\"docs\":{},\"高\":{\"docs\":{},\"到\":{\"docs\":{},\"低\":{\"docs\":{},\"回\":{\"docs\":{},\"溯\":{\"docs\":{},\"，\":{\"docs\":{},\"选\":{\"docs\":{},\"择\":{\"docs\":{},\"最\":{\"docs\":{},\"高\":{\"docs\":{},\"可\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"。\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"的\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"为\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"为\":{\"docs\":{},\"后\":{\"docs\":{},\"缀\":{\"docs\":{},\"的\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"压\":{\"docs\":{},\"缩\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}},\"允\":{\"docs\":{},\"许\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"，\":{\"docs\":{},\"也\":{\"docs\":{},\"允\":{\"docs\":{},\"许\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"等\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"变\":{\"docs\":{},\"更\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"就\":{\"docs\":{},\"导\":{\"docs\":{},\"致\":{\"docs\":{},\"了\":{\"docs\":{},\"一\":{\"docs\":{},\"次\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"必\":{\"docs\":{},\"须\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"于\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"内\":{\"docs\":{},\"的\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"和\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"全\":{\"docs\":{},\"部\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"，\":{\"docs\":{},\"否\":{\"docs\":{},\"则\":{\"docs\":{},\"就\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"会\":{\"docs\":{},\"导\":{\"docs\":{},\"致\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"不\":{\"docs\":{},\"一\":{\"docs\":{},\"致\":{\"docs\":{},\"而\":{\"docs\":{},\"引\":{\"docs\":{},\"发\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"。\":{\"docs\":{},\"从\":{\"docs\":{},\"以\":{\"docs\":{},\"往\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"可\":{\"docs\":{},\"知\":{\"docs\":{},\"，\":{\"docs\":{},\"每\":{\"docs\":{},\"次\":{\"docs\":{},\"的\":{\"docs\":{},\"变\":{\"docs\":{},\"更\":{\"docs\":{},\"通\":{\"docs\":{},\"常\":{\"docs\":{},\"都\":{\"docs\":{},\"有\":{\"docs\":{},\"十\":{\"docs\":{},\"几\":{\"docs\":{},\"个\":{\"docs\":{},\"甚\":{\"docs\":{},\"至\":{\"docs\":{},\"几\":{\"docs\":{},\"十\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"变\":{\"docs\":{},\"更\":{\"docs\":{},\"，\":{\"docs\":{},\"而\":{\"docs\":{},\"在\":{\"docs\":{},\"低\":{\"docs\":{},\"空\":{\"docs\":{},\"间\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"某\":{\"docs\":{},\"些\":{\"docs\":{},\"读\":{\"docs\":{},\"写\":{\"docs\":{},\"能\":{\"docs\":{},\"力\":{\"docs\":{},\"较\":{\"docs\":{},\"差\":{\"docs\":{},\"的\":{\"docs\":{},\"设\":{\"docs\":{},\"备\":{\"docs\":{},\"上\":{\"docs\":{},\"，\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"失\":{\"docs\":{},\"败\":{\"docs\":{},\"很\":{\"docs\":{},\"容\":{\"docs\":{},\"易\":{\"docs\":{},\"影\":{\"docs\":{},\"响\":{\"docs\":{},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"的\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"率\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"内\":{\"docs\":{},\"有\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"的\":{\"docs\":{},\"变\":{\"docs\":{},\"更\":{\"docs\":{},\"，\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"，\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"等\":{\"docs\":{},\"。\":{\"docs\":{},\"灵\":{\"docs\":{},\"活\":{\"docs\":{},\"性\":{\"docs\":{},\"导\":{\"docs\":{},\"致\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"等\":{\"docs\":{},\"体\":{\"docs\":{},\"积\":{\"docs\":{},\"往\":{\"docs\":{},\"往\":{\"docs\":{},\"比\":{\"docs\":{},\"较\":{\"docs\":{},\"大\":{\"docs\":{},\"，\":{\"docs\":{},\"而\":{\"docs\":{},\"在\":{\"docs\":{},\"运\":{\"docs\":{},\"营\":{\"docs\":{},\"商\":{\"docs\":{},\"网\":{\"docs\":{},\"络\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"对\":{\"docs\":{},\"用\":{\"docs\":{},\"户\":{\"docs\":{},\"大\":{\"docs\":{},\"的\":{\"docs\":{},\"流\":{\"docs\":{},\"量\":{\"docs\":{},\"消\":{\"docs\":{},\"耗\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"希\":{\"docs\":{},\"望\":{\"docs\":{},\"看\":{\"docs\":{},\"到\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"往\":{\"docs\":{},\"往\":{\"docs\":{},\"这\":{\"docs\":{},\"种\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"下\":{\"docs\":{},\"只\":{\"docs\":{},\"在\":{\"docs\":{},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"下\":{\"docs\":{},\"的\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"策\":{\"docs\":{},\"略\":{\"docs\":{},\"很\":{\"docs\":{},\"能\":{\"docs\":{},\"影\":{\"docs\":{},\"响\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"率\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"的\":{\"docs\":{},\"出\":{\"docs\":{},\"发\":{\"docs\":{},\"点\":{\"docs\":{},\"立\":{\"docs\":{},\"足\":{\"docs\":{},\"于\":{\"docs\":{},\"需\":{\"docs\":{},\"求\":{\"docs\":{},\"的\":{\"docs\":{},\"快\":{\"docs\":{},\"速\":{\"docs\":{},\"迭\":{\"docs\":{},\"代\":{\"docs\":{},\"，\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"普\":{\"docs\":{},\"通\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"升\":{\"docs\":{},\"级\":{\"docs\":{},\"。\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"在\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"演\":{\"docs\":{},\"进\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"灵\":{\"docs\":{},\"活\":{\"docs\":{},\"性\":{\"docs\":{},\"成\":{\"docs\":{},\"为\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"不\":{\"docs\":{},\"断\":{\"docs\":{},\"去\":{\"docs\":{},\"追\":{\"docs\":{},\"求\":{\"docs\":{},\"的\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"。\":{\"docs\":{},\"希\":{\"docs\":{},\"望\":{\"docs\":{},\"不\":{\"docs\":{},\"断\":{\"docs\":{},\"缩\":{\"docs\":{},\"小\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"限\":{\"docs\":{},\"制\":{\"docs\":{},\"以\":{\"docs\":{},\"达\":{\"docs\":{},\"到\":{\"docs\":{},\"完\":{\"docs\":{},\"全\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"能\":{\"docs\":{},\"力\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"限\":{\"docs\":{},\"制\":{\"docs\":{\"update/guide.html\":{\"ref\":\"update/guide.html\",\"tf\":0.2}}}}},\"不\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"的\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}},\"失\":{\"docs\":{},\"败\":{\"docs\":{},\"排\":{\"docs\":{},\"查\":{\"docs\":{},\"指\":{\"docs\":{},\"南\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":10}}}}}}}},\"排\":{\"docs\":{},\"查\":{\"docs\":{},\"经\":{\"docs\":{},\"验\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}},\"版\":{\"docs\":{},\"本\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"线\":{\"docs\":{},\"上\":{\"docs\":{},\"故\":{\"docs\":{},\"障\":{\"docs\":{\"update/\":{\"ref\":\"update/\",\"tf\":0.16666666666666666}}}}}}}},\"代\":{\"docs\":{},\"理\":{\"docs\":{},\"p\":{\"docs\":{},\"m\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}},\"资\":{\"docs\":{},\"源\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}},\"包\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.020134228187919462}},\"含\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"的\":{\"docs\":{},\"中\":{\"docs\":{},\"间\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{},\"应\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"应\":{\"docs\":{},\"用\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"等\":{\"docs\":{},\"基\":{\"docs\":{},\"础\":{\"docs\":{},\"性\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"括\":{\"docs\":{},\"了\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"所\":{\"docs\":{},\"需\":{\"docs\":{},\"的\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"层\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"注\":{\"docs\":{},\"入\":{\"docs\":{},\"和\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"工\":{\"docs\":{},\"具\":{\"docs\":{},\"类\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"和\":{\"docs\":{},\"校\":{\"docs\":{},\"验\":{\"docs\":{},\"，\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"时\":{\"docs\":{},\"先\":{\"docs\":{},\"校\":{\"docs\":{},\"验\":{\"docs\":{},\"设\":{\"docs\":{},\"备\":{\"docs\":{},\"是\":{\"docs\":{},\"否\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"则\":{\"docs\":{},\"采\":{\"docs\":{},\"取\":{\"docs\":{},\"降\":{\"docs\":{},\"级\":{\"docs\":{},\"并\":{\"docs\":{},\"记\":{\"docs\":{},\"录\":{\"docs\":{},\"原\":{\"docs\":{},\"因\":{\"docs\":{},\"；\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"装\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"字\":{\"docs\":{},\"端\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\",\":{\"docs\":{},\"大\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"y\":{\"docs\":{},\"自\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"关\":{\"docs\":{},\"心\":{\"docs\":{},\"的\":{\"docs\":{},\"只\":{\"docs\":{},\"有\":{\"docs\":{},\"几\":{\"docs\":{},\"个\":{\"docs\":{},\"字\":{\"docs\":{},\"端\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"即\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"快\":{\"docs\":{},\"速\":{\"docs\":{},\"覆\":{\"docs\":{},\"盖\":{\"docs\":{},\"能\":{\"docs\":{},\"力\":{\"docs\":{},\"在\":{\"docs\":{},\"灰\":{\"docs\":{},\"度\":{\"docs\":{},\"等\":{\"docs\":{},\"场\":{\"docs\":{},\"景\":{\"docs\":{},\"下\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"更\":{\"docs\":{},\"快\":{\"docs\":{},\"地\":{\"docs\":{},\"收\":{\"docs\":{},\"到\":{\"docs\":{},\"所\":{\"docs\":{},\"需\":{\"docs\":{},\"的\":{\"docs\":{},\"效\":{\"docs\":{},\"果\":{\"docs\":{},\"。\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"在\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"增\":{\"docs\":{},\"加\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"不\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"，\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"额\":{\"docs\":{},\"外\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"监\":{\"docs\":{},\"控\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"样\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"其\":{\"docs\":{},\"他\":{\"docs\":{},\"的\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"k\":{\"docs\":{},\"（\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"w\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"）\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"类\":{\"docs\":{},\"似\":{\"docs\":{},\"方\":{\"docs\":{},\"案\":{\"docs\":{},\"在\":{\"docs\":{},\"多\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"自\":{\"docs\":{},\"己\":{\"docs\":{},\"定\":{\"docs\":{},\"制\":{\"docs\":{},\"的\":{\"docs\":{},\"适\":{\"docs\":{},\"配\":{\"docs\":{},\"器\":{\"docs\":{},\"，\":{\"docs\":{},\"规\":{\"docs\":{},\"避\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"预\":{\"docs\":{},\"先\":{\"docs\":{},\"注\":{\"docs\":{},\"册\":{\"docs\":{},\"的\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"也\":{\"docs\":{},\"对\":{\"docs\":{},\"整\":{\"docs\":{},\"体\":{\"docs\":{},\"应\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"性\":{\"docs\":{},\"能\":{\"docs\":{},\"带\":{\"docs\":{},\"来\":{\"docs\":{},\"帮\":{\"docs\":{},\"助\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"周\":{\"docs\":{},\"期\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}},\"四\":{\"docs\":{},\"大\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}},\"基\":{\"docs\":{},\"础\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}},\"于\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"和\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}}}}}}}}}}}}}}}}}}}}}},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"结\":{\"docs\":{},\"构\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"，\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"与\":{\"docs\":{},\"普\":{\"docs\":{},\"通\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"无\":{\"docs\":{},\"异\":{\"docs\":{},\"，\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"和\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"会\":{\"docs\":{},\"添\":{\"docs\":{},\"加\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"额\":{\"docs\":{},\"外\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"i\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"中\":{\"docs\":{},\"会\":{\"docs\":{},\"增\":{\"docs\":{},\"加\":{\"docs\":{},\"若\":{\"docs\":{},\"干\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"的\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"，\":{\"docs\":{},\"取\":{\"docs\":{},\"名\":{\"docs\":{},\"为\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"%\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\",\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\".\":{\"docs\":{},\"\\\"\":{\"docs\":{},\",\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"_\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\"；\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"为\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{},\"这\":{\"docs\":{},\"些\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"都\":{\"docs\":{},\"是\":{\"docs\":{},\"正\":{\"docs\":{},\"常\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"结\":{\"docs\":{},\"构\":{\"docs\":{},\"，\":{\"docs\":{},\"改\":{\"docs\":{},\"为\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"放\":{\"docs\":{},\"入\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"只\":{\"docs\":{},\"是\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"时\":{\"docs\":{},\"借\":{\"docs\":{},\"用\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"的\":{\"docs\":{},\"能\":{\"docs\":{},\"力\":{\"docs\":{},\"从\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"中\":{\"docs\":{},\"解\":{\"docs\":{},\"压\":{\"docs\":{},\"出\":{\"docs\":{},\"来\":{\"docs\":{},\"，\":{\"docs\":{},\"方\":{\"docs\":{},\"便\":{\"docs\":{},\"后\":{\"docs\":{},\"续\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{\"principle-intro/Apk_architecture.html\":{\"ref\":\"principle-intro/Apk_architecture.html\",\"tf\":0.07142857142857142}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"所\":{\"docs\":{},\"属\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"(\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\")\":{\"docs\":{},\"，\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\",\":{\"docs\":{},\"以\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"为\":{\"docs\":{},\"例\":{\"docs\":{},\"，\":{\"docs\":{},\"将\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"为\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"\\\"\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"（\":{\"docs\":{},\"包\":{\"docs\":{},\"括\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"过\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"）\":{\"docs\":{},\"；\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"能\":{\"docs\":{},\"力\":{\"docs\":{},\"的\":{\"docs\":{},\"库\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"_\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}},\"线\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"坐\":{\"docs\":{},\"标\":{\"docs\":{},\"，\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154}}}}}}}},\"版\":{\"docs\":{},\"本\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}},\"增\":{\"docs\":{},\"量\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"能\":{\"docs\":{},\"力\":{\"docs\":{},\"，\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"对\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"、\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"的\":{\"docs\":{},\"增\":{\"docs\":{},\"量\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"能\":{\"docs\":{},\"力\":{\"docs\":{},\"，\":{\"docs\":{},\"快\":{\"docs\":{},\"速\":{\"docs\":{},\"升\":{\"docs\":{},\"级\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"加\":{\"docs\":{},\"一\":{\"docs\":{},\"层\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{},\"控\":{\"docs\":{},\"制\":{\"docs\":{},\"根\":{\"docs\":{},\"据\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"的\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{},\"来\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"变\":{\"docs\":{},\"量\":{\"docs\":{},\"的\":{\"docs\":{},\"值\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"如\":{\"docs\":{},\"何\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}},\"正\":{\"docs\":{},\"确\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}},\"通\":{\"docs\":{},\"知\":{\"docs\":{},\"外\":{\"docs\":{},\"部\":{\"docs\":{},\"登\":{\"docs\":{},\"录\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"失\":{\"docs\":{},\"败\":{\"docs\":{},\"，\":{\"docs\":{},\"除\":{\"docs\":{},\"了\":{\"docs\":{},\"用\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"的\":{\"docs\":{},\"广\":{\"docs\":{},\"播\":{\"docs\":{},\"等\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"，\":{\"docs\":{},\"能\":{\"docs\":{},\"否\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"更\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"地\":{\"docs\":{},\"方\":{\"docs\":{},\"便\":{\"docs\":{},\"地\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"该\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"呢\":{\"docs\":{},\"？\":{\"docs\":{},\"后\":{\"docs\":{},\"续\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"中\":{\"docs\":{},\"会\":{\"docs\":{},\"阐\":{\"docs\":{},\"述\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"的\":{\"docs\":{},\"用\":{\"docs\":{},\"法\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"发\":{\"docs\":{},\"布\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\":\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"的\":{\"docs\":{},\"包\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}},\"上\":{\"docs\":{},\"图\":{\"docs\":{},\"所\":{\"docs\":{},\"示\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"主\":{\"docs\":{},\"要\":{\"docs\":{},\"分\":{\"docs\":{},\"为\":{\"docs\":{},\"以\":{\"docs\":{},\"下\":{\"docs\":{},\"几\":{\"docs\":{},\"个\":{\"docs\":{},\"层\":{\"docs\":{},\"级\":{\"docs\":{},\"：\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}},\"果\":{\"docs\":{},\"不\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"那\":{\"docs\":{},\"么\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"就\":{\"docs\":{},\"会\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"，\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"实\":{\"docs\":{},\"际\":{\"docs\":{},\"上\":{\"docs\":{},\"是\":{\"docs\":{},\"类\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"的\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"，\":{\"docs\":{},\"那\":{\"docs\":{},\"么\":{\"docs\":{},\"这\":{\"docs\":{},\"种\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"就\":{\"docs\":{},\"会\":{\"docs\":{},\"必\":{\"docs\":{},\"然\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"包\":{\"docs\":{},\"括\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"及\":{\"docs\":{},\"其\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"等\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"在\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"不\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"在\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"造\":{\"docs\":{},\"成\":{\"docs\":{},\"一\":{\"docs\":{},\"定\":{\"docs\":{},\"成\":{\"docs\":{},\"本\":{\"docs\":{},\"，\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"小\":{\"docs\":{},\"心\":{\"docs\":{},\"的\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"以\":{\"docs\":{},\"避\":{\"docs\":{},\"免\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"k\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"用\":{\"docs\":{},\"到\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"开\":{\"docs\":{},\"启\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"必\":{\"docs\":{},\"须\":{\"docs\":{},\"为\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154}}}}}}}}}}}}}}}},\"是\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}},\"有\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"一\":{\"docs\":{},\"级\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"下\":{\"docs\":{},\"以\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"为\":{\"docs\":{},\"粒\":{\"docs\":{},\"度\":{\"docs\":{},\"有\":{\"docs\":{},\"多\":{\"docs\":{},\"个\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"夹\":{\"docs\":{},\"，\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"夹\":{\"docs\":{},\"下\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{},\"差\":{\"docs\":{},\"量\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"，\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"等\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"会\":{\"docs\":{},\"有\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"_\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"_\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"，\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"中\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{},\"差\":{\"docs\":{},\"量\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"、\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"等\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"异\":{\"docs\":{},\"常\":{\"docs\":{},\"，\":{\"docs\":{},\"和\":{\"docs\":{},\"第\":{\"docs\":{},\"上\":{\"docs\":{},\"面\":{\"docs\":{},\"一\":{\"docs\":{},\"样\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}},\"返\":{\"docs\":{},\"回\":{\"docs\":{},\"检\":{\"docs\":{},\"查\":{\"docs\":{},\"第\":{\"docs\":{},\"一\":{\"docs\":{},\"步\":{\"docs\":{},\"的\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"发\":{\"docs\":{},\"布\":{\"docs\":{},\"过\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"，\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"跳\":{\"docs\":{},\"过\":{\"docs\":{},\"此\":{\"docs\":{},\"节\":{\"docs\":{},\"。\":{\"docs\":{},\"假\":{\"docs\":{},\"设\":{\"docs\":{},\"从\":{\"docs\":{},\"未\":{\"docs\":{},\"发\":{\"docs\":{},\"布\":{\"docs\":{},\"过\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"，\":{\"docs\":{},\"按\":{\"docs\":{},\"照\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"步\":{\"docs\":{},\"骤\":{\"docs\":{},\"，\":{\"docs\":{},\"发\":{\"docs\":{},\"布\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"类\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"，\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"往\":{\"docs\":{},\"前\":{\"docs\":{},\"排\":{\"docs\":{},\"查\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"的\":{\"docs\":{},\"警\":{\"docs\":{},\"告\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"，\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"设\":{\"docs\":{},\"备\":{\"docs\":{},\"上\":{\"docs\":{},\"会\":{\"docs\":{},\"有\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"被\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"j\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"：\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"和\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"_\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\",\":{\"docs\":{},\"以\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"_\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"为\":{\"docs\":{},\"准\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"对\":{\"docs\":{},\"不\":{\"docs\":{},\"上\":{\"docs\":{},\"，\":{\"docs\":{},\"说\":{\"docs\":{},\"明\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"错\":{\"docs\":{},\"误\":{\"docs\":{},\"，\":{\"docs\":{},\"下\":{\"docs\":{},\"面\":{\"docs\":{},\"是\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"常\":{\"docs\":{},\"见\":{\"docs\":{},\"的\":{\"docs\":{},\"原\":{\"docs\":{},\"因\":{\"docs\":{},\"，\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"同\":{\"docs\":{},\"学\":{\"docs\":{},\"们\":{\"docs\":{},\"自\":{\"docs\":{},\"己\":{\"docs\":{},\"做\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"排\":{\"docs\":{},\"查\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"：\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154}}}},\"定\":{\"docs\":{},\"位\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}},\"义\":{\"docs\":{},\"同\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"据\":{\"docs\":{},\"是\":{\"docs\":{},\"全\":{\"docs\":{},\"路\":{\"docs\":{},\"径\":{\"docs\":{},\"完\":{\"docs\":{},\"全\":{\"docs\":{},\"相\":{\"docs\":{},\"同\":{\"docs\":{},\"且\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"相\":{\"docs\":{},\"同\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"、\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"、\":{\"docs\":{},\"调\":{\"docs\":{},\"试\":{\"docs\":{},\"的\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"完\":{\"docs\":{},\"整\":{\"docs\":{},\"的\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"生\":{\"docs\":{},\"命\":{\"docs\":{},\"周\":{\"docs\":{},\"期\":{\"docs\":{},\"的\":{\"docs\":{},\"映\":{\"docs\":{},\"射\":{\"docs\":{},\"，\":{\"docs\":{},\"类\":{\"docs\":{},\"隔\":{\"docs\":{},\"离\":{\"docs\":{},\"、\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"共\":{\"docs\":{},\"享\":{\"docs\":{},\"等\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}},\"机\":{\"docs\":{},\"制\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}},\"的\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}},\"很\":{\"docs\":{},\"简\":{\"docs\":{},\"单\":{\"docs\":{},\"，\":{\"docs\":{},\"读\":{\"docs\":{},\"取\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"k\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"上\":{\"docs\":{},\"的\":{\"docs\":{},\"静\":{\"docs\":{},\"态\":{\"docs\":{},\"属\":{\"docs\":{},\"性\":{\"docs\":{},\"字\":{\"docs\":{},\"段\":{\"docs\":{},\"，\":{\"docs\":{},\"接\":{\"docs\":{},\"着\":{\"docs\":{},\"跟\":{\"docs\":{},\"进\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"类\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}},\"例\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}}}}}}},\"化\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"指\":{\"docs\":{},\"定\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}},\"际\":{\"docs\":{},\"上\":{\"docs\":{},\"是\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{},\"即\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"在\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"指\":{\"docs\":{},\"定\":{\"docs\":{},\"的\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"路\":{\"docs\":{},\"径\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"这\":{\"docs\":{},\"四\":{\"docs\":{},\"个\":{\"docs\":{},\"级\":{\"docs\":{},\"别\":{\"docs\":{},\"的\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"的\":{\"docs\":{},\"字\":{\"docs\":{},\"段\":{\"docs\":{},\"，\":{\"docs\":{},\"为\":{\"docs\":{},\"这\":{\"docs\":{},\"些\":{\"docs\":{},\"字\":{\"docs\":{},\"段\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"赋\":{\"docs\":{},\"值\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"线\":{\"docs\":{},\"箭\":{\"docs\":{},\"头\":{\"docs\":{},\"表\":{\"docs\":{},\"示\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"在\":{\"docs\":{},\"主\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":10}},\"，\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"模\":{\"docs\":{},\"块\":{\"docs\":{},\"的\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}},\"框\":{\"docs\":{},\"架\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"将\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"转\":{\"docs\":{},\"化\":{\"docs\":{},\"成\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"所\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"会\":{\"docs\":{},\"侵\":{\"docs\":{},\"入\":{\"docs\":{},\"正\":{\"docs\":{},\"常\":{\"docs\":{},\"的\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"环\":{\"docs\":{},\"境\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"前\":{\"docs\":{},\"面\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}},\"步\":{\"docs\":{},\"骤\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}},\"外\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"层\":{\"docs\":{},\":\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"下\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"真\":{\"docs\":{},\"正\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"的\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"会\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"原\":{\"docs\":{},\"有\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"没\":{\"docs\":{},\"入\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"并\":{\"docs\":{},\"不\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"任\":{\"docs\":{},\"何\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"，\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"脚\":{\"docs\":{},\"本\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"了\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"的\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"。\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"除\":{\"docs\":{},\"了\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"了\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"内\":{\"docs\":{},\"置\":{\"docs\":{},\"了\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"的\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"样\":{\"docs\":{},\"做\":{\"docs\":{},\"的\":{\"docs\":{},\"原\":{\"docs\":{},\"因\":{\"docs\":{},\"有\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"：\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"于\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"、\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"h\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"，\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"还\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"临\":{\"docs\":{},\"时\":{\"docs\":{},\"无\":{\"docs\":{},\"法\":{\"docs\":{},\"按\":{\"docs\":{},\"照\":{\"docs\":{},\"规\":{\"docs\":{},\"范\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"解\":{\"docs\":{},\"耦\":{\"docs\":{},\"的\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"。\":{\"docs\":{},\"目\":{\"docs\":{},\"前\":{\"docs\":{},\"除\":{\"docs\":{},\"了\":{\"docs\":{},\"静\":{\"docs\":{},\"态\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"外\":{\"docs\":{},\"，\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"考\":{\"docs\":{},\"虑\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\",\":{\"docs\":{},\"用\":{\"docs\":{},\"来\":{\"docs\":{},\"解\":{\"docs\":{},\"决\":{\"docs\":{},\"在\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"到\":{\"docs\":{},\"某\":{\"docs\":{},\"个\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"再\":{\"docs\":{},\"去\":{\"docs\":{},\"挂\":{\"docs\":{},\"载\":{\"docs\":{},\"相\":{\"docs\":{},\"应\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"模\":{\"docs\":{},\"块\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"过\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"始\":{\"docs\":{},\"终\":{\"docs\":{},\"打\":{\"docs\":{},\"破\":{\"docs\":{},\"了\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"的\":{\"docs\":{},\"边\":{\"docs\":{},\"界\":{\"docs\":{},\"，\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"谨\":{\"docs\":{},\"慎\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"的\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"期\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"的\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"期\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"期\":{\"docs\":{},\"望\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"的\":{\"docs\":{},\"基\":{\"docs\":{},\"线\":{\"docs\":{},\"足\":{\"docs\":{},\"够\":{\"docs\":{},\"稳\":{\"docs\":{},\"定\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"样\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"避\":{\"docs\":{},\"免\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"基\":{\"docs\":{},\"线\":{\"docs\":{},\"不\":{\"docs\":{},\"兼\":{\"docs\":{},\"容\":{\"docs\":{},\"的\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"精\":{\"docs\":{},\"力\":{\"docs\":{},\"所\":{\"docs\":{},\"限\":{\"docs\":{},\"，\":{\"docs\":{},\"因\":{\"docs\":{},\"为\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"的\":{\"docs\":{},\"淘\":{\"docs\":{},\"宝\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"变\":{\"docs\":{},\"种\":{\"docs\":{},\"的\":{\"docs\":{},\"架\":{\"docs\":{},\"构\":{\"docs\":{},\"，\":{\"docs\":{},\"额\":{\"docs\":{},\"外\":{\"docs\":{},\"的\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"会\":{\"docs\":{},\"带\":{\"docs\":{},\"来\":{\"docs\":{},\"很\":{\"docs\":{},\"多\":{\"docs\":{},\"适\":{\"docs\":{},\"配\":{\"docs\":{},\"的\":{\"docs\":{},\"麻\":{\"docs\":{},\"烦\":{\"docs\":{},\"和\":{\"docs\":{},\"风\":{\"docs\":{},\"险\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"启\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"的\":{\"docs\":{},\"开\":{\"docs\":{},\"关\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"期\":{\"docs\":{},\"会\":{\"docs\":{},\"做\":{\"docs\":{},\"很\":{\"docs\":{},\"多\":{\"docs\":{},\"事\":{\"docs\":{},\"情\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}},\"关\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"引\":{\"docs\":{},\"用\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"及\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"仓\":{\"docs\":{},\"库\":{\"docs\":{},\"，\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"及\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"仓\":{\"docs\":{},\"库\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"比\":{\"docs\":{},\"较\":{\"docs\":{},\"倾\":{\"docs\":{},\"向\":{\"docs\":{},\"于\":{\"docs\":{},\"用\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"比\":{\"docs\":{},\"较\":{\"docs\":{},\"干\":{\"docs\":{},\"净\":{\"docs\":{},\"的\":{\"docs\":{},\"壳\":{\"docs\":{},\"子\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"来\":{\"docs\":{},\"作\":{\"docs\":{},\"为\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"架\":{\"docs\":{},\"构\":{\"docs\":{},\"下\":{\"docs\":{},\"的\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\",\":{\"docs\":{},\"称\":{\"docs\":{},\"之\":{\"docs\":{},\"为\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"_\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"，\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"_\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"建\":{\"docs\":{},\"议\":{\"docs\":{},\"只\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"x\":{\"docs\":{},\"m\":{\"docs\":{},\"l\":{\"docs\":{},\"、\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"及\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"。\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"建\":{\"docs\":{},\"议\":{\"docs\":{},\"只\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"x\":{\"docs\":{},\"m\":{\"docs\":{},\"l\":{\"docs\":{},\"和\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"的\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"及\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"，\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"单\":{\"docs\":{},\"独\":{\"docs\":{},\"管\":{\"docs\":{},\"理\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"，\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"等\":{\"docs\":{},\"；\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"管\":{\"docs\":{},\"理\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"；\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"取\":{\"docs\":{},\"名\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"等\":{\"docs\":{},\"名\":{\"docs\":{},\"字\":{\"docs\":{},\"为\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"_\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\";\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"也\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"被\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"在\":{\"docs\":{},\"某\":{\"docs\":{},\"些\":{\"docs\":{},\"场\":{\"docs\":{},\"景\":{\"docs\":{},\"下\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"主\":{\"docs\":{},\"动\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"按\":{\"docs\":{},\"规\":{\"docs\":{},\"律\":{\"docs\":{},\"定\":{\"docs\":{},\"期\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"的\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"，\":{\"docs\":{},\"一\":{\"docs\":{},\"种\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"是\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"掉\":{\"docs\":{},\"用\":{\"docs\":{},\"远\":{\"docs\":{},\"端\":{\"docs\":{},\"时\":{\"docs\":{},\"传\":{\"docs\":{},\"进\":{\"docs\":{},\"来\":{\"docs\":{},\"的\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"多\":{\"docs\":{},\"次\":{\"docs\":{},\"回\":{\"docs\":{},\"调\":{\"docs\":{},\"，\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"涉\":{\"docs\":{},\"及\":{\"docs\":{},\"到\":{\"docs\":{},\"复\":{\"docs\":{},\"杂\":{\"docs\":{},\"的\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"就\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"用\":{\"docs\":{},\"到\":{\"docs\":{},\"下\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"来\":{\"docs\":{},\"看\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}},\"取\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"包\":{\"docs\":{},\"，\":{\"docs\":{},\"能\":{\"docs\":{},\"够\":{\"docs\":{},\"看\":{\"docs\":{},\"到\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"：\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}},\"一\":{\"docs\":{},\"般\":{\"docs\":{},\"的\":{\"docs\":{},\"做\":{\"docs\":{},\"法\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{},\"来\":{\"docs\":{},\"控\":{\"docs\":{},\"制\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"的\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{},\"值\":{\"docs\":{},\"，\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}}}}}}}}}},\"接\":{\"docs\":{},\"着\":{\"docs\":{},\"往\":{\"docs\":{},\"下\":{\"docs\":{},\"看\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}},\"看\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"相\":{\"docs\":{},\"关\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"反\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}},\"都\":{\"docs\":{},\"知\":{\"docs\":{},\"道\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"的\":{\"docs\":{},\"入\":{\"docs\":{},\"口\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"那\":{\"docs\":{},\"么\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"入\":{\"docs\":{},\"口\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"是\":{\"docs\":{},\"什\":{\"docs\":{},\"么\":{\"docs\":{},\"呢\":{\"docs\":{},\"，\":{\"docs\":{},\"看\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"模\":{\"docs\":{},\"块\":{\"docs\":{},\"中\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"手\":{\"docs\":{},\"淘\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"化\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"的\":{\"docs\":{},\"前\":{\"docs\":{},\"世\":{\"docs\":{},\"今\":{\"docs\":{},\"生\":{\"docs\":{},\"和\":{\"docs\":{},\"未\":{\"docs\":{},\"来\":{\"docs\":{},\"的\":{\"docs\":{},\"路\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}},\"扫\":{\"docs\":{},\"码\":{\"docs\":{},\"加\":{\"docs\":{},\"入\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"钉\":{\"docs\":{},\"钉\":{\"docs\":{},\"交\":{\"docs\":{},\"流\":{\"docs\":{},\"群\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}},\"拆\":{\"docs\":{},\"分\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"文\":{\"docs\":{},\"档\":{\"docs\":{},\"，\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}},\"可\":{\"docs\":{},\"参\":{\"docs\":{},\"考\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{\"guide-for-use/\":{\"ref\":\"guide-for-use/\",\"tf\":0.25}}}}}}}}},\"指\":{\"docs\":{},\"引\":{\"docs\":{\"guide-for-use/\":{\"ref\":\"guide-for-use/\",\"tf\":10.25}}}}},\"着\":{\"docs\":{},\"看\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}},\"执\":{\"docs\":{},\"行\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}},\"上\":{\"docs\":{},\"篇\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"简\":{\"docs\":{},\"化\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"者\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"的\":{\"docs\":{},\"负\":{\"docs\":{},\"担\":{\"docs\":{},\"。\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}},\"前\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"，\":{\"docs\":{},\"格\":{\"docs\":{},\"式\":{\"docs\":{},\"是\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}},\"取\":{\"docs\":{},\"出\":{\"docs\":{},\"来\":{\"docs\":{},\"以\":{\"docs\":{},\"多\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"追\":{\"docs\":{},\"加\":{\"docs\":{},\"到\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"_\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"_\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"是\":{\"docs\":{},\"多\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"那\":{\"docs\":{},\"么\":{\"docs\":{},\"会\":{\"docs\":{},\"将\":{\"docs\":{},\"多\":{\"docs\":{},\"个\":{\"docs\":{},\"子\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"全\":{\"docs\":{},\"部\":{\"docs\":{},\"追\":{\"docs\":{},\"加\":{\"docs\":{},\"进\":{\"docs\":{},\"去\":{\"docs\":{},\"，\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"保\":{\"docs\":{},\"持\":{\"docs\":{},\"不\":{\"docs\":{},\"变\":{\"docs\":{},\"，\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"的\":{\"docs\":{},\"序\":{\"docs\":{},\"列\":{\"docs\":{},\"号\":{\"docs\":{},\"往\":{\"docs\":{},\"后\":{\"docs\":{},\"偏\":{\"docs\":{},\"移\":{\"docs\":{},\"一\":{\"docs\":{},\"位\":{\"docs\":{},\"（\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"支\":{\"docs\":{},\"持\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.024844720496894408},\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.031914893617021274}},\"版\":{\"docs\":{},\"本\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"四\":{\"docs\":{},\"大\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}},\"文\":{\"docs\":{},\"档\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}},\"件\":{\"docs\":{},\"名\":{\"docs\":{},\"为\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}},\"，\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"服\":{\"docs\":{},\"务\":{\"docs\":{},\"端\":{\"docs\":{},\"做\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"包\":{\"docs\":{},\"装\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}},\"是\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"最\":{\"docs\":{},\"重\":{\"docs\":{},\"要\":{\"docs\":{},\"的\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"。\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"此\":{\"docs\":{},\":\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"格\":{\"docs\":{},\"式\":{\"docs\":{},\"的\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"记\":{\"docs\":{},\"录\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"，\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"字\":{\"docs\":{},\"段\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"标\":{\"docs\":{},\"识\":{\"docs\":{},\"该\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"所\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"a\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"b\":{\"docs\":{},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"c\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"触\":{\"docs\":{},\"发\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"时\":{\"docs\":{},\"，\":{\"docs\":{},\"实\":{\"docs\":{},\"际\":{\"docs\":{},\"的\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"顺\":{\"docs\":{},\"序\":{\"docs\":{},\"为\":{\"docs\":{},\"c\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"否\":{\"docs\":{},\"启\":{\"docs\":{},\"用\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"被\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"2\":{\"docs\":{},\".\":{\"3\":{\"docs\":{},\".\":{\"docs\":{},\"x\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}},\"docs\":{}}},\"docs\":{}}}}},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"在\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"可\":{\"docs\":{},\"配\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}},\"内\":{\"docs\":{},\"置\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}},\"有\":{\"docs\":{},\"故\":{\"docs\":{},\"障\":{\"docs\":{},\"的\":{\"docs\":{},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"时\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"回\":{\"docs\":{},\"滚\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}},\"任\":{\"docs\":{},\"何\":{\"docs\":{},\"的\":{\"docs\":{},\"建\":{\"docs\":{},\"议\":{\"docs\":{},\"和\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"请\":{\"docs\":{},\"在\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"上\":{\"docs\":{},\"提\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\"给\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"会\":{\"docs\":{},\"尽\":{\"docs\":{},\"快\":{\"docs\":{},\"回\":{\"docs\":{},\"复\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"高\":{\"docs\":{},\"频\":{\"docs\":{},\"的\":{\"docs\":{},\"会\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"q\":{\"docs\":{},\"文\":{\"docs\":{},\"档\":{\"docs\":{},\"中\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"注\":{\"docs\":{},\"意\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}},\"构\":{\"docs\":{},\"建\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.023529411764705882}},\"时\":{\"docs\":{},\"会\":{\"docs\":{},\"与\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"字\":{\"docs\":{},\"节\":{\"docs\":{},\"码\":{\"docs\":{},\"级\":{\"docs\":{},\"别\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"，\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"包\":{\"docs\":{},\"。\":{\"docs\":{},\"最\":{\"docs\":{},\"终\":{\"docs\":{},\"下\":{\"docs\":{},\"发\":{\"docs\":{},\"到\":{\"docs\":{},\"用\":{\"docs\":{},\"户\":{\"docs\":{},\"手\":{\"docs\":{},\"机\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"仅\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{},\"变\":{\"docs\":{},\"化\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"组\":{\"docs\":{},\"成\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"和\":{\"docs\":{},\"更\":{\"docs\":{},\"改\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"新\":{\"docs\":{},\"增\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"完\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"在\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"会\":{\"docs\":{},\"有\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{\"principle-intro/Apk_architecture.html\":{\"ref\":\"principle-intro/Apk_architecture.html\",\"tf\":0.07142857142857142}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154}}}}},\"基\":{\"docs\":{},\"线\":{\"docs\":{},\"包\":{\"docs\":{},\"，\":{\"docs\":{},\"建\":{\"docs\":{},\"议\":{\"docs\":{},\"开\":{\"docs\":{},\"启\":{\"docs\":{},\"，\":{\"docs\":{},\"否\":{\"docs\":{},\"则\":{\"docs\":{},\"后\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"包\":{\"docs\":{},\"无\":{\"docs\":{},\"法\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}},\"的\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}},\"基\":{\"docs\":{},\"线\":{\"docs\":{},\"包\":{\"docs\":{},\"，\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}},\"速\":{\"docs\":{},\"度\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"：\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}},\"定\":{\"docs\":{},\"制\":{\"docs\":{},\"包\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":10}}}}},\"标\":{\"docs\":{},\"准\":{\"docs\":{},\"包\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}},\"特\":{\"docs\":{},\"殊\":{\"docs\":{},\"包\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}},\"造\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"设\":{\"docs\":{},\"置\":{\"docs\":{},\"对\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"和\":{\"docs\":{},\"其\":{\"docs\":{},\"它\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"及\":{\"docs\":{},\"控\":{\"docs\":{},\"制\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}},\"简\":{\"docs\":{},\"介\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}},\"单\":{\"docs\":{},\"来\":{\"docs\":{},\"说\":{\"docs\":{},\"，\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"是\":{\"docs\":{},\"针\":{\"docs\":{},\"对\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"级\":{\"docs\":{},\"别\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"升\":{\"docs\":{},\"级\":{\"docs\":{},\"，\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"是\":{\"docs\":{},\"针\":{\"docs\":{},\"对\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"级\":{\"docs\":{},\"别\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"(\":{\"docs\":{},\"主\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"认\":{\"docs\":{},\"为\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"起\":{\"docs\":{},\"见\":{\"docs\":{},\"，\":{\"docs\":{},\"只\":{\"docs\":{},\"是\":{\"docs\":{},\"每\":{\"docs\":{},\"次\":{\"docs\":{},\"都\":{\"docs\":{},\"把\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"+\":{\"1\":{\"docs\":{},\"，\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"缓\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"根\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"下\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\".\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"中\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}},\"化\":{\"docs\":{},\"了\":{\"docs\":{},\"大\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"，\":{\"docs\":{},\"只\":{\"docs\":{},\"关\":{\"docs\":{},\"注\":{\"docs\":{},\"核\":{\"docs\":{},\"心\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{},\"。\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"读\":{\"docs\":{},\"取\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"上\":{\"docs\":{},\"的\":{\"docs\":{},\"字\":{\"docs\":{},\"段\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\",\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"值\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"然\":{\"docs\":{},\"后\":{\"docs\":{},\"开\":{\"docs\":{},\"始\":{\"docs\":{},\"异\":{\"docs\":{},\"步\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"至\":{\"docs\":{},\"此\":{\"docs\":{},\"，\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"方\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"任\":{\"docs\":{},\"何\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"，\":{\"docs\":{},\"详\":{\"docs\":{},\"细\":{\"docs\":{},\"的\":{\"docs\":{},\"文\":{\"docs\":{},\"档\":{\"docs\":{},\"参\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"的\":{\"docs\":{},\"分\":{\"docs\":{},\"析\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}},\"解\":{\"docs\":{},\"释\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}},\"压\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}},\"说\":{\"docs\":{},\"明\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.030303030303030304},\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.012422360248447204},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00847457627118644},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}},\"运\":{\"docs\":{},\"维\":{\"docs\":{},\"期\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.012121212121212121}}}},\"行\":{\"docs\":{},\"期\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.01818181818181818},\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}},\"按\":{\"docs\":{},\"需\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"。\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"和\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"允\":{\"docs\":{},\"许\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"。\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"结\":{\"docs\":{},\"构\":{\"docs\":{\"principle-intro/File_architecture_runtime.html\":{\"ref\":\"principle-intro/File_architecture_runtime.html\",\"tf\":10.1}}}}}}},\"三\":{\"docs\":{},\"个\":{\"docs\":{},\"阶\":{\"docs\":{},\"段\":{\"docs\":{},\"，\":{\"docs\":{},\"放\":{\"docs\":{},\"一\":{\"docs\":{},\"张\":{\"docs\":{},\"图\":{\"docs\":{},\"捋\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}},\"远\":{\"docs\":{},\"程\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"远\":{\"docs\":{},\"程\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"只\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"时\":{\"docs\":{},\"并\":{\"docs\":{},\"未\":{\"docs\":{},\"打\":{\"docs\":{},\"到\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"，\":{\"docs\":{},\"而\":{\"docs\":{},\"是\":{\"docs\":{},\"单\":{\"docs\":{},\"独\":{\"docs\":{},\"放\":{\"docs\":{},\"在\":{\"docs\":{},\"了\":{\"docs\":{},\"云\":{\"docs\":{},\"端\":{\"docs\":{},\"；\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"远\":{\"docs\":{},\"程\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"限\":{\"docs\":{},\"制\":{\"docs\":{},\"条\":{\"docs\":{},\"件\":{\"docs\":{},\"是\":{\"docs\":{},\"第\":{\"docs\":{},\"一\":{\"docs\":{},\"次\":{\"docs\":{},\"被\":{\"docs\":{},\"触\":{\"docs\":{},\"发\":{\"docs\":{},\"的\":{\"docs\":{},\"前\":{\"docs\":{},\"提\":{\"docs\":{},\"是\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"内\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"被\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{},\"此\":{\"docs\":{},\"时\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"内\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"n\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"跳\":{\"docs\":{},\"转\":{\"docs\":{},\"的\":{\"docs\":{},\"重\":{\"docs\":{},\"定\":{\"docs\":{},\"向\":{\"docs\":{},\"，\":{\"docs\":{},\"提\":{\"docs\":{},\"示\":{\"docs\":{},\"用\":{\"docs\":{},\"户\":{\"docs\":{},\"下\":{\"docs\":{},\"载\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"待\":{\"docs\":{},\"用\":{\"docs\":{},\"户\":{\"docs\":{},\"确\":{\"docs\":{},\"定\":{\"docs\":{},\"后\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"异\":{\"docs\":{},\"步\":{\"docs\":{},\"下\":{\"docs\":{},\"载\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"后\":{\"docs\":{},\"再\":{\"docs\":{},\"跳\":{\"docs\":{},\"转\":{\"docs\":{},\"到\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"（\":{\"docs\":{},\"此\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"涉\":{\"docs\":{},\"及\":{\"docs\":{},\"下\":{\"docs\":{},\"载\":{\"docs\":{},\"及\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"展\":{\"docs\":{},\"示\":{\"docs\":{},\"等\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"并\":{\"docs\":{},\"未\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{},\"在\":{\"docs\":{},\"开\":{\"docs\":{},\"源\":{\"docs\":{},\"仓\":{\"docs\":{},\"库\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"有\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"根\":{\"docs\":{},\"据\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"n\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"自\":{\"docs\":{},\"行\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"）\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"端\":{\"docs\":{},\"如\":{\"docs\":{},\"何\":{\"docs\":{},\"主\":{\"docs\":{},\"动\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"已\":{\"docs\":{},\"经\":{\"docs\":{},\"有\":{\"docs\":{},\"封\":{\"docs\":{},\"装\":{\"docs\":{},\"过\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"返\":{\"docs\":{},\"回\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"的\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"。\":{\"docs\":{},\"这\":{\"docs\":{},\"种\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"类\":{\"docs\":{},\"似\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"，\":{\"docs\":{},\"前\":{\"docs\":{},\"提\":{\"docs\":{},\"是\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"说\":{\"docs\":{},\"明\":{\"docs\":{},\"的\":{\"docs\":{},\"是\":{\"docs\":{},\"，\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"不\":{\"docs\":{},\"会\":{\"docs\":{},\"侵\":{\"docs\":{},\"入\":{\"docs\":{},\"正\":{\"docs\":{},\"常\":{\"docs\":{},\"的\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"流\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"和\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"都\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"的\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"和\":{\"docs\":{},\"调\":{\"docs\":{},\"试\":{\"docs\":{},\"。\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.006060606060606061}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"在\":{\"docs\":{},\"原\":{\"docs\":{},\"来\":{\"docs\":{},\"的\":{\"docs\":{},\"基\":{\"docs\":{},\"础\":{\"docs\":{},\"上\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"，\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"来\":{\"docs\":{},\"自\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"，\":{\"docs\":{},\"暂\":{\"docs\":{},\"时\":{\"docs\":{},\"还\":{\"docs\":{},\"未\":{\"docs\":{},\"从\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"中\":{\"docs\":{},\"拆\":{\"docs\":{},\"分\":{\"docs\":{},\"出\":{\"docs\":{},\"差\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"也\":{\"docs\":{},\"意\":{\"docs\":{},\"味\":{\"docs\":{},\"着\":{\"docs\":{},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"方\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"增\":{\"docs\":{},\"加\":{\"docs\":{},\"对\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"。\":{\"docs\":{},\"*\":{\"docs\":{},\"*\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"的\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"会\":{\"docs\":{},\"在\":{\"docs\":{},\"文\":{\"docs\":{},\"章\":{\"docs\":{},\"后\":{\"docs\":{},\"面\":{\"docs\":{},\"解\":{\"docs\":{},\"释\":{\"docs\":{},\"*\":{\"docs\":{},\"*\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"添\":{\"docs\":{},\"加\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}},\"去\":{\"docs\":{},\"除\":{\"docs\":{},\"的\":{\"docs\":{},\"原\":{\"docs\":{},\"生\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}},\"打\":{\"docs\":{},\"入\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}},\"注\":{\"docs\":{},\"意\":{\"docs\":{},\"的\":{\"docs\":{},\"是\":{\"docs\":{},\"，\":{\"docs\":{},\"第\":{\"docs\":{},\"二\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"整\":{\"docs\":{},\"体\":{\"docs\":{},\"是\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"在\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}},\">\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.0625},\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456},\"principle-intro/Apk_architecture.html\":{\"ref\":\"principle-intro/Apk_architecture.html\",\"tf\":0.21428571428571427},\"principle-intro/File_architecture_runtime.html\":{\"ref\":\"principle-intro/File_architecture_runtime.html\",\"tf\":0.1},\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.09411764705882353},\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571},\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.12}},\"a\":{\"docs\":{},\",\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"中\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"的\":{\"docs\":{},\"k\":{\"docs\":{},\"e\":{\"docs\":{},\"y\":{\"docs\":{},\"为\":{\"docs\":{},\"该\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\",\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"为\":{\"docs\":{},\"被\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"2\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\",\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"2\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}},\"docs\":{}}}}}}}}}}}}}},\"3\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"）\":{\"docs\":{},\",\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"所\":{\"docs\":{},\"示\":{\"docs\":{},\"：\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}},\"docs\":{}}}}}}},\",\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"a\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"显\":{\"docs\":{},\"式\":{\"docs\":{},\"声\":{\"docs\":{},\"明\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"c\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"a\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}},\"安\":{\"docs\":{},\"装\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"，\":{\"docs\":{},\"与\":{\"docs\":{},\"之\":{\"docs\":{},\"相\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"，\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"分\":{\"docs\":{},\"为\":{\"docs\":{},\"三\":{\"docs\":{},\"个\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"：\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}},\"=\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"是\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"中\":{\"docs\":{},\"类\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"的\":{\"docs\":{},\"大\":{\"docs\":{},\"致\":{\"docs\":{},\"顺\":{\"docs\":{},\"序\":{\"docs\":{},\"；\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}},\"面\":{\"docs\":{},\"会\":{\"docs\":{},\"逐\":{\"docs\":{},\"个\":{\"docs\":{},\"说\":{\"docs\":{},\"明\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"的\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"和\":{\"docs\":{},\"注\":{\"docs\":{},\"意\":{\"docs\":{},\"要\":{\"docs\":{},\"点\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}},\"对\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"展\":{\"docs\":{},\"开\":{\"docs\":{},\"讲\":{\"docs\":{},\"解\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"以\":{\"docs\":{},\"便\":{\"docs\":{},\"更\":{\"docs\":{},\"好\":{\"docs\":{},\"理\":{\"docs\":{},\"解\":{\"docs\":{},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"展\":{\"docs\":{},\"开\":{\"docs\":{},\"介\":{\"docs\":{},\"绍\":{\"docs\":{},\"下\":{\"docs\":{},\"在\":{\"docs\":{},\"新\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"（\":{\"docs\":{},\"假\":{\"docs\":{},\"设\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"当\":{\"docs\":{},\"做\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"特\":{\"docs\":{},\"殊\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"）\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"前\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"和\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"在\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"差\":{\"docs\":{},\"异\":{\"docs\":{},\"点\":{\"docs\":{},\"：\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"载\":{\"docs\":{},\"到\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"k\":{\"docs\":{},\"会\":{\"docs\":{},\"在\":{\"docs\":{},\"后\":{\"docs\":{},\"台\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"到\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"的\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"对\":{\"docs\":{},\"用\":{\"docs\":{},\"户\":{\"docs\":{},\"透\":{\"docs\":{},\"明\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"发\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"总\":{\"docs\":{},\"包\":{\"docs\":{},\"内\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"各\":{\"docs\":{},\"自\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"全\":{\"docs\":{},\"部\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"是\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"的\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"是\":{\"docs\":{},\"向\":{\"docs\":{},\"前\":{\"docs\":{},\"兼\":{\"docs\":{},\"容\":{\"docs\":{},\"做\":{\"docs\":{},\"了\":{\"docs\":{},\"保\":{\"docs\":{},\"证\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"个\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"会\":{\"docs\":{},\"清\":{\"docs\":{},\"理\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}},\"另\":{\"docs\":{},\"外\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}},\"内\":{\"docs\":{},\"置\":{\"docs\":{},\"的\":{\"docs\":{},\"原\":{\"docs\":{},\"生\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"在\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"上\":{\"docs\":{},\"面\":{\"docs\":{},\"性\":{\"docs\":{},\"能\":{\"docs\":{},\"并\":{\"docs\":{},\"不\":{\"docs\":{},\"好\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"对\":{\"docs\":{},\"其\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"了\":{\"docs\":{},\"优\":{\"docs\":{},\"化\":{\"docs\":{},\"提\":{\"docs\":{},\"高\":{\"docs\":{},\"了\":{\"docs\":{},\"在\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"上\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"体\":{\"docs\":{},\"验\":{\"docs\":{},\"。\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"，\":{\"docs\":{},\"根\":{\"docs\":{},\"据\":{\"docs\":{},\"历\":{\"docs\":{},\"史\":{\"docs\":{},\"经\":{\"docs\":{},\"验\":{\"docs\":{},\"，\":{\"docs\":{},\"大\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"都\":{\"docs\":{},\"是\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"不\":{\"docs\":{},\"规\":{\"docs\":{},\"范\":{\"docs\":{},\"造\":{\"docs\":{},\"成\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"避\":{\"docs\":{},\"免\":{\"docs\":{},\"这\":{\"docs\":{},\"些\":{\"docs\":{},\"奇\":{\"docs\":{},\"奇\":{\"docs\":{},\"怪\":{\"docs\":{},\"怪\":{\"docs\":{},\"的\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"，\":{\"docs\":{},\"大\":{\"docs\":{},\"家\":{\"docs\":{},\"最\":{\"docs\":{},\"好\":{\"docs\":{},\"按\":{\"docs\":{},\"照\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"结\":{\"docs\":{},\"构\":{\"docs\":{},\"指\":{\"docs\":{},\"南\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"认\":{\"docs\":{},\"为\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"的\":{\"docs\":{},\"类\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"来\":{\"docs\":{},\"帮\":{\"docs\":{},\"助\":{\"docs\":{},\"理\":{\"docs\":{},\"解\":{\"docs\":{},\"（\":{\"docs\":{},\"假\":{\"docs\":{},\"设\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"所\":{\"docs\":{},\"在\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"已\":{\"docs\":{},\"经\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"）\":{\"docs\":{},\"；\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"减\":{\"docs\":{},\"少\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"包\":{\"docs\":{},\"大\":{\"docs\":{},\"小\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}},\"看\":{\"docs\":{},\"到\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"了\":{\"docs\":{},\"，\":{\"docs\":{},\"反\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"d\":{\"docs\":{},\"n\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"z\":{\"docs\":{},\"i\":{\"docs\":{},\"p\":{\"docs\":{},\"（\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"）\":{\"docs\":{},\"，\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"验\":{\"docs\":{},\"证\":{\"docs\":{},\"改\":{\"docs\":{},\"动\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"，\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"大\":{\"docs\":{},\"概\":{\"docs\":{},\"分\":{\"docs\":{},\"为\":{\"docs\":{},\"三\":{\"docs\":{},\"大\":{\"docs\":{},\"块\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"只\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"壳\":{\"docs\":{},\"子\":{\"docs\":{},\"，\":{\"docs\":{},\"只\":{\"docs\":{},\"是\":{\"docs\":{},\"用\":{\"docs\":{},\"来\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{},\"的\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"第\":{\"4\":{\"docs\":{},\"步\":{\"docs\":{},\"和\":{\"docs\":{},\"第\":{\"7\":{\"docs\":{},\"步\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"关\":{\"docs\":{},\"键\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"，\":{\"docs\":{},\"第\":{\"5\":{\"docs\":{},\"步\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"了\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\",\":{\"docs\":{},\"跟\":{\"docs\":{},\"进\":{\"docs\":{},\"去\":{\"docs\":{},\"看\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}},\"docs\":{}}}}},\"docs\":{}}},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"虽\":{\"docs\":{},\"长\":{\"docs\":{},\"，\":{\"docs\":{},\"但\":{\"docs\":{},\"其\":{\"docs\":{},\"实\":{\"docs\":{},\"就\":{\"docs\":{},\"只\":{\"docs\":{},\"干\":{\"docs\":{},\"了\":{\"docs\":{},\"两\":{\"docs\":{},\"件\":{\"docs\":{},\"事\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"是\":{\"docs\":{},\"根\":{\"docs\":{},\"据\":{\"docs\":{},\"在\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"登\":{\"docs\":{},\"记\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"，\":{\"docs\":{},\"实\":{\"docs\":{},\"例\":{\"docs\":{},\"化\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"从\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"读\":{\"docs\":{},\"取\":{\"docs\":{},\"字\":{\"docs\":{},\"符\":{\"docs\":{},\"串\":{\"docs\":{},\"，\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"解\":{\"docs\":{},\"析\":{\"docs\":{},\"成\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"存\":{\"docs\":{},\"储\":{\"docs\":{},\"。\":{\"docs\":{},\"很\":{\"docs\":{},\"明\":{\"docs\":{},\"显\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"字\":{\"docs\":{},\"符\":{\"docs\":{},\"串\":{\"docs\":{},\"应\":{\"docs\":{},\"该\":{\"docs\":{},\"是\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"之\":{\"docs\":{},\"类\":{\"docs\":{},\"的\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"。\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\"从\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"到\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"提\":{\"docs\":{},\"到\":{\"docs\":{},\"过\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"会\":{\"docs\":{},\"在\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"期\":{\"docs\":{},\"间\":{\"docs\":{},\"会\":{\"docs\":{},\"分\":{\"docs\":{},\"析\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"和\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"，\":{\"docs\":{},\"将\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"写\":{\"docs\":{},\"入\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"中\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"这\":{\"docs\":{},\"段\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"的\":{\"docs\":{},\"核\":{\"docs\":{},\"心\":{\"docs\":{},\"思\":{\"docs\":{},\"想\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"将\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"m\":{\"docs\":{},\"，\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"为\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"x\":{\"docs\":{},\"y\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"。\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"先\":{\"docs\":{},\"不\":{\"docs\":{},\"关\":{\"docs\":{},\"注\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"x\":{\"docs\":{},\"y\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"，\":{\"docs\":{},\"接\":{\"docs\":{},\"着\":{\"docs\":{},\"看\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"先\":{\"docs\":{},\"从\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"上\":{\"docs\":{},\"去\":{\"docs\":{},\"找\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{},\"而\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\":\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"很\":{\"docs\":{},\"清\":{\"docs\":{},\"楚\":{\"docs\":{},\"的\":{\"docs\":{},\"看\":{\"docs\":{},\"到\":{\"docs\":{},\"，\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"主\":{\"docs\":{},\"要\":{\"docs\":{},\"分\":{\"docs\":{},\"为\":{\"docs\":{},\"三\":{\"docs\":{},\"大\":{\"docs\":{},\"块\":{\"docs\":{},\"，\":{\"docs\":{},\"依\":{\"docs\":{},\"次\":{\"docs\":{},\"是\":{\"docs\":{},\"标\":{\"docs\":{},\"准\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"、\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"的\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"，\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"管\":{\"docs\":{},\"理\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"。\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"重\":{\"docs\":{},\"点\":{\"docs\":{},\"看\":{\"docs\":{},\"最\":{\"docs\":{},\"后\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"属\":{\"docs\":{},\"性\":{\"docs\":{},\"开\":{\"docs\":{},\"关\":{\"docs\":{},\"关\":{\"docs\":{},\"闭\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}},\"能\":{\"docs\":{},\"的\":{\"docs\":{},\"错\":{\"docs\":{},\"误\":{\"docs\":{},\"操\":{\"docs\":{},\"作\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}},\"后\":{\"docs\":{},\"面\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"起\":{\"docs\":{},\"来\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"对\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"有\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"，\":{\"docs\":{},\"那\":{\"docs\":{},\"么\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"用\":{\"docs\":{},\"到\":{\"docs\":{},\"了\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"又\":{\"docs\":{},\"会\":{\"docs\":{},\"根\":{\"docs\":{},\"据\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"去\":{\"docs\":{},\"获\":{\"docs\":{},\"取\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"去\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"；\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"续\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"设\":{\"docs\":{},\"置\":{\"docs\":{},\"用\":{\"docs\":{},\"语\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"时\":{\"docs\":{},\"的\":{\"docs\":{},\"开\":{\"docs\":{},\"关\":{\"docs\":{},\"设\":{\"docs\":{},\"置\":{\"docs\":{},\"，\":{\"docs\":{},\"其\":{\"docs\":{},\"余\":{\"docs\":{},\"字\":{\"docs\":{},\"段\":{\"docs\":{},\"参\":{\"docs\":{},\"考\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"列\":{\"docs\":{},\"表\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"要\":{\"docs\":{},\"打\":{\"docs\":{},\"特\":{\"docs\":{},\"殊\":{\"docs\":{},\"包\":{\"docs\":{},\"就\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"的\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{},\"来\":{\"docs\":{},\"控\":{\"docs\":{},\"制\":{\"docs\":{},\"打\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"的\":{\"docs\":{},\"包\":{\"docs\":{},\"了\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"：\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"很\":{\"docs\":{},\"多\":{\"docs\":{},\"大\":{\"docs\":{},\"型\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"不\":{\"docs\":{},\"合\":{\"docs\":{},\"理\":{\"docs\":{},\"的\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"导\":{\"docs\":{},\"致\":{\"docs\":{},\"用\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"分\":{\"docs\":{},\"包\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{},\"拆\":{\"docs\":{},\"分\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"主\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"就\":{\"docs\":{},\"有\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"数\":{\"docs\":{},\"超\":{\"docs\":{},\"过\":{\"6\":{\"5\":{\"5\":{\"3\":{\"6\":{\"docs\":{},\"，\":{\"docs\":{},\"\\u0002\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"与\":{\"docs\":{},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"完\":{\"docs\":{},\"全\":{\"docs\":{},\"解\":{\"docs\":{},\"耦\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"拆\":{\"docs\":{},\"分\":{\"docs\":{},\"上\":{\"docs\":{},\"面\":{\"docs\":{},\"只\":{\"docs\":{},\"要\":{\"docs\":{},\"保\":{\"docs\":{},\"证\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"在\":{\"docs\":{},\"主\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"，\":{\"docs\":{},\"其\":{\"docs\":{},\"他\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"无\":{\"docs\":{},\"论\":{\"docs\":{},\"怎\":{\"docs\":{},\"么\":{\"docs\":{},\"拆\":{\"docs\":{},\"分\":{\"docs\":{},\"都\":{\"docs\":{},\"不\":{\"docs\":{},\"会\":{\"docs\":{},\"有\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"；\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"快\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}},\"操\":{\"docs\":{},\"作\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"管\":{\"docs\":{},\"理\":{\"docs\":{},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"生\":{\"docs\":{},\"命\":{\"docs\":{},\"周\":{\"docs\":{},\"期\":{\"docs\":{},\"；\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}},\"更\":{\"docs\":{},\"新\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}},\"最\":{\"docs\":{},\"底\":{\"docs\":{},\"下\":{\"docs\":{},\"的\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"工\":{\"docs\":{},\"具\":{\"docs\":{},\"层\":{\"docs\":{},\"：\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}},\"简\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}},\"后\":{\"docs\":{},\"确\":{\"docs\":{},\"认\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"以\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"，\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}},\"，\":{\"docs\":{},\"大\":{\"docs\":{},\"概\":{\"docs\":{},\"看\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}},\"e\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"内\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}},\"看\":{\"docs\":{},\"各\":{\"docs\":{},\"自\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"k\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"k\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"是\":{\"docs\":{},\"否\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"，\":{\"docs\":{},\"以\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"为\":{\"docs\":{},\"例\":{\"docs\":{},\"，\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"同\":{\"docs\":{},\"理\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"根\":{\"docs\":{},\"据\":{\"docs\":{},\"上\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"，\":{\"docs\":{},\"先\":{\"docs\":{},\"去\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"；\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"本\":{\"docs\":{},\"原\":{\"docs\":{},\"因\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"原\":{\"docs\":{},\"理\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":10}}}}}},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"生\":{\"docs\":{},\"命\":{\"docs\":{},\"周\":{\"docs\":{},\"期\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"所\":{\"docs\":{},\"示\":{\"docs\":{},\"：\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}},\"在\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"，\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"为\":{\"docs\":{},\"其\":{\"docs\":{},\"分\":{\"docs\":{},\"配\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"，\":{\"docs\":{},\"用\":{\"docs\":{},\"以\":{\"docs\":{},\"使\":{\"docs\":{},\"其\":{\"docs\":{},\"保\":{\"docs\":{},\"证\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"全\":{\"docs\":{},\"局\":{\"docs\":{},\"唯\":{\"docs\":{},\"一\":{\"docs\":{},\"；\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"的\":{\"docs\":{},\"可\":{\"docs\":{},\"分\":{\"docs\":{},\"配\":{\"docs\":{},\"区\":{\"docs\":{},\"间\":{\"docs\":{},\"为\":{\"docs\":{},\"[\":{\"0\":{\"docs\":{},\"x\":{\"2\":{\"1\":{\"docs\":{},\",\":{\"0\":{\"docs\":{},\"x\":{\"7\":{\"docs\":{},\"f\":{\"docs\":{},\")\":{\"docs\":{},\",\":{\"0\":{\"docs\":{},\"x\":{\"1\":{\"docs\":{},\"x\":{\"docs\":{},\"为\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"保\":{\"docs\":{},\"留\":{\"docs\":{},\"，\":{\"0\":{\"docs\":{},\"x\":{\"7\":{\"docs\":{},\"f\":{\"docs\":{},\"为\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"0\":{\"docs\":{},\"x\":{\"2\":{\"0\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"的\":{\"docs\":{},\"发\":{\"docs\":{},\"现\":{\"docs\":{},\"m\":{\"docs\":{},\"i\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"已\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"目\":{\"docs\":{},\"前\":{\"docs\":{},\"我\":{\"docs\":{},\"没\":{\"docs\":{},\"选\":{\"docs\":{},\"择\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"区\":{\"docs\":{},\"间\":{\"docs\":{},\"作\":{\"docs\":{},\"为\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"分\":{\"docs\":{},\"配\":{\"docs\":{},\"区\":{\"docs\":{},\"间\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}},\"docs\":{}}},\"docs\":{}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}}}}}}}},\"docs\":{}}},\"docs\":{}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"自\":{\"docs\":{},\"身\":{\"docs\":{},\"的\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"的\":{\"docs\":{},\"发\":{\"docs\":{},\"布\":{\"docs\":{},\"，\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"速\":{\"docs\":{},\"度\":{\"docs\":{},\"相\":{\"docs\":{},\"比\":{\"docs\":{},\"原\":{\"docs\":{},\"来\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"有\":{\"docs\":{},\"了\":{\"docs\":{},\"大\":{\"docs\":{},\"幅\":{\"docs\":{},\"度\":{\"docs\":{},\"提\":{\"docs\":{},\"高\":{\"docs\":{},\"，\":{\"docs\":{},\"只\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"针\":{\"docs\":{},\"对\":{\"docs\":{},\"单\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"从\":{\"docs\":{},\"而\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"出\":{\"docs\":{},\"差\":{\"docs\":{},\"异\":{\"docs\":{},\"即\":{\"docs\":{},\"可\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"只\":{\"docs\":{},\"能\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"主\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"算\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\"，\":{\"docs\":{},\"且\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"必\":{\"docs\":{},\"须\":{\"docs\":{},\"向\":{\"docs\":{},\"前\":{\"docs\":{},\"兼\":{\"docs\":{},\"容\":{\"docs\":{},\"。\":{\"docs\":{},\"（\":{\"docs\":{},\"不\":{\"docs\":{},\"如\":{\"docs\":{},\"说\":{\"docs\":{},\"主\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"被\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"主\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"不\":{\"docs\":{},\"能\":{\"docs\":{},\"引\":{\"docs\":{},\"起\":{\"docs\":{},\"原\":{\"docs\":{},\"来\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"出\":{\"docs\":{},\"现\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"）\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"按\":{\"docs\":{},\"照\":{\"docs\":{},\"各\":{\"docs\":{},\"自\":{\"docs\":{},\"的\":{\"docs\":{},\"故\":{\"docs\":{},\"障\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"的\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"，\":{\"docs\":{},\"产\":{\"docs\":{},\"出\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"和\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"，\":{\"docs\":{},\"发\":{\"docs\":{},\"布\":{\"docs\":{},\"时\":{\"docs\":{},\"平\":{\"docs\":{},\"台\":{\"docs\":{},\"应\":{\"docs\":{},\"该\":{\"docs\":{},\"汇\":{\"docs\":{},\"总\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"当\":{\"docs\":{},\"前\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"，\":{\"docs\":{},\"整\":{\"docs\":{},\"合\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"，\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"下\":{\"docs\":{},\"发\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"模\":{\"docs\":{},\"块\":{\"docs\":{},\"有\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"概\":{\"docs\":{},\"念\":{\"docs\":{},\"客\":{\"docs\":{},\"户\":{\"docs\":{},\"端\":{\"docs\":{},\"会\":{\"docs\":{},\"判\":{\"docs\":{},\"断\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{},\"判\":{\"docs\":{},\"断\":{\"docs\":{},\"该\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"是\":{\"docs\":{},\"否\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"做\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"通\":{\"docs\":{},\"常\":{\"docs\":{},\"由\":{\"docs\":{},\"服\":{\"docs\":{},\"务\":{\"docs\":{},\"端\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"管\":{\"docs\":{},\"理\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"一\":{\"docs\":{},\"次\":{\"docs\":{},\"补\":{\"docs\":{},\"丁\":{\"docs\":{},\"的\":{\"docs\":{},\"发\":{\"docs\":{},\"布\":{\"docs\":{},\"都\":{\"docs\":{},\"是\":{\"docs\":{},\"相\":{\"docs\":{},\"当\":{\"docs\":{},\"于\":{\"docs\":{},\"一\":{\"docs\":{},\"次\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"的\":{\"docs\":{},\"升\":{\"docs\":{},\"级\":{\"docs\":{},\"，\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"的\":{\"docs\":{},\"变\":{\"docs\":{},\"更\":{\"docs\":{},\"来\":{\"docs\":{},\"决\":{\"docs\":{},\"策\":{\"docs\":{},\"补\":{\"docs\":{},\"丁\":{\"docs\":{},\"的\":{\"docs\":{},\"下\":{\"docs\":{},\"发\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"由\":{\"7\":{\"docs\":{},\".\":{\"3\":{\"docs\":{},\"可\":{\"docs\":{},\"知\":{\"docs\":{},\"，\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"实\":{\"docs\":{},\"际\":{\"docs\":{},\"上\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{},\"于\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"在\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"内\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"失\":{\"docs\":{},\"败\":{\"docs\":{},\"，\":{\"docs\":{},\"接\":{\"docs\":{},\"着\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"根\":{\"docs\":{},\"据\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"到\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"在\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"（\":{\"docs\":{},\"假\":{\"docs\":{},\"设\":{\"docs\":{},\"为\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"）\":{\"docs\":{},\"；\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"相\":{\"docs\":{},\"同\":{\"docs\":{},\"的\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"导\":{\"docs\":{},\"致\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"服\":{\"docs\":{},\"务\":{\"docs\":{},\"端\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"/\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"w\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"对\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"做\":{\"docs\":{},\"了\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"包\":{\"docs\":{},\"装\":{\"docs\":{},\"，\":{\"docs\":{},\"简\":{\"docs\":{},\"单\":{\"docs\":{},\"模\":{\"docs\":{},\"拟\":{\"docs\":{},\"服\":{\"docs\":{},\"务\":{\"docs\":{},\"端\":{\"docs\":{},\"的\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"的\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"的\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"得\":{\"docs\":{},\"知\":{\"docs\":{},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"后\":{\"docs\":{},\"对\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"来\":{\"docs\":{},\"说\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"任\":{\"docs\":{},\"何\":{\"docs\":{},\"变\":{\"docs\":{},\"化\":{\"docs\":{},\"，\":{\"docs\":{},\"还\":{\"docs\":{},\"是\":{\"docs\":{},\"按\":{\"docs\":{},\"需\":{\"docs\":{},\"的\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"类\":{\"docs\":{},\"似\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"，\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"被\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"成\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\",\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"在\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"的\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"会\":{\"docs\":{},\"被\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"到\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"中\":{\"docs\":{},\"；\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"特\":{\"docs\":{},\"征\":{\"docs\":{},\"如\":{\"docs\":{},\"图\":{\"docs\":{},\"可\":{\"docs\":{},\"知\":{\"docs\":{},\"：\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"规\":{\"docs\":{},\"范\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"（\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"）\":{\"docs\":{},\"的\":{\"docs\":{},\"概\":{\"docs\":{},\"念\":{\"docs\":{},\"，\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"有\":{\"docs\":{},\"自\":{\"docs\":{},\"己\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"，\":{\"docs\":{},\"与\":{\"docs\":{},\"其\":{\"docs\":{},\"他\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"相\":{\"docs\":{},\"隔\":{\"docs\":{},\"离\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"下\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"有\":{\"docs\":{},\"自\":{\"docs\":{},\"身\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"段\":{\"docs\":{},\"（\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"，\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"时\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"指\":{\"docs\":{},\"定\":{\"docs\":{},\"）\":{\"docs\":{},\"；\":{\"docs\":{},\"另\":{\"docs\":{},\"外\":{\"docs\":{},\"与\":{\"docs\":{},\"原\":{\"docs\":{},\"有\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"所\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"的\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"格\":{\"docs\":{},\"式\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"之\":{\"docs\":{},\"处\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"透\":{\"docs\":{},\"出\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"在\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{},\"随\":{\"docs\":{},\"着\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"触\":{\"docs\":{},\"发\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"，\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"。\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"，\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"更\":{\"docs\":{},\"细\":{\"docs\":{},\"粒\":{\"docs\":{},\"度\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"间\":{\"docs\":{},\"的\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"复\":{\"docs\":{},\"用\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}},\"型\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"在\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"均\":{\"docs\":{},\"可\":{\"docs\":{},\"访\":{\"docs\":{},\"问\":{\"docs\":{},\"的\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"公\":{\"docs\":{},\"共\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"自\":{\"docs\":{},\"身\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}},\"动\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"列\":{\"docs\":{},\"表\":{\"docs\":{},\"，\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"哪\":{\"docs\":{},\"个\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"啊\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{},\"主\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"吗\":{\"docs\":{},\"？\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"在\":{\"docs\":{},\"任\":{\"docs\":{},\"何\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"过\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"p\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"入\":{\"docs\":{},\"口\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"类\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"，\":{\"docs\":{},\"回\":{\"docs\":{},\"调\":{\"docs\":{},\"时\":{\"docs\":{},\"机\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"对\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"开\":{\"docs\":{},\"始\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"范\":{\"docs\":{},\"例\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}},\"虽\":{\"docs\":{},\"然\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"都\":{\"docs\":{},\"声\":{\"docs\":{},\"明\":{\"docs\":{},\"了\":{\"docs\":{},\"自\":{\"docs\":{},\"己\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"c\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"均\":{\"docs\":{},\"被\":{\"docs\":{},\"统\":{\"docs\":{},\"一\":{\"docs\":{},\"为\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"在\":{\"docs\":{},\"手\":{\"docs\":{},\"淘\":{\"docs\":{},\"内\":{\"docs\":{},\"就\":{\"docs\":{},\"都\":{\"docs\":{},\"是\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"；\":{\"docs\":{},\"这\":{\"docs\":{},\"样\":{\"docs\":{},\"改\":{\"docs\":{},\"的\":{\"docs\":{},\"目\":{\"docs\":{},\"的\":{\"docs\":{},\"是\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"解\":{\"docs\":{},\"决\":{\"docs\":{},\"在\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"中\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"兼\":{\"docs\":{},\"容\":{\"docs\":{},\"性\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"；\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"负\":{\"docs\":{},\"责\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}},\"处\":{\"docs\":{},\"理\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"说\":{\"docs\":{},\"明\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}},\"除\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"之\":{\"docs\":{},\"外\":{\"docs\":{},\"，\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"层\":{\"docs\":{},\"对\":{\"docs\":{},\"外\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"了\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"工\":{\"docs\":{},\"具\":{\"docs\":{},\"类\":{\"docs\":{},\"，\":{\"docs\":{},\"包\":{\"docs\":{},\"括\":{\"docs\":{},\"主\":{\"docs\":{},\"动\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{\"principle-intro/Runtime_principle.html\":{\"ref\":\"principle-intro/Runtime_principle.html\",\"tf\":0.015625}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"了\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"树\":{\"docs\":{},\"和\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{},\"之\":{\"docs\":{},\"外\":{\"docs\":{},\"，\":{\"docs\":{},\"额\":{\"docs\":{},\"外\":{\"docs\":{},\"的\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"有\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}},\"e\":{\"docs\":{},\"库\":{\"docs\":{},\"及\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"与\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"发\":{\"docs\":{},\"布\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"(\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\")\":{\"docs\":{},\",\":{\"docs\":{},\"分\":{\"docs\":{},\"别\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"命\":{\"docs\":{},\"令\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"和\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{},\"表\":{\"docs\":{},\"明\":{\"docs\":{},\"是\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}},\"确\":{\"docs\":{},\"认\":{\"docs\":{},\"。\":{\"docs\":{},\"（\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"同\":{\"docs\":{},\"学\":{\"docs\":{},\"们\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"按\":{\"docs\":{},\"照\":{\"docs\":{},\"规\":{\"docs\":{},\"范\":{\"docs\":{},\"来\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"地\":{\"docs\":{},\"方\":{\"docs\":{},\"很\":{\"docs\":{},\"容\":{\"docs\":{},\"易\":{\"docs\":{},\"出\":{\"docs\":{},\"错\":{\"docs\":{},\"，\":{\"docs\":{},\"导\":{\"docs\":{},\"致\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"失\":{\"docs\":{},\"败\":{\"docs\":{},\"）\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}}}}}}},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"o\":{\"docs\":{},\"w\":{\"docs\":{},\"级\":{\"docs\":{},\"别\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"保\":{\"docs\":{},\"持\":{\"docs\":{},\"不\":{\"docs\":{},\"变\":{\"docs\":{\"update/guide.html\":{\"ref\":\"update/guide.html\",\"tf\":0.2}}}}}}}}}}}}}}}}}},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}},\"名\":{\"docs\":{},\"词\":{\"docs\":{},\"解\":{\"docs\":{},\"释\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":10.045454545454545}}}}}},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"的\":{\"docs\":{},\"概\":{\"docs\":{},\"念\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"内\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"和\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"常\":{\"docs\":{},\"常\":{\"docs\":{},\"集\":{\"docs\":{},\"合\":{\"docs\":{},\"了\":{\"docs\":{},\"公\":{\"docs\":{},\"共\":{\"docs\":{},\"的\":{\"docs\":{},\"中\":{\"docs\":{},\"间\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"等\":{\"docs\":{},\"。\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"和\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"所\":{\"docs\":{},\"示\":{\"docs\":{},\"：\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"对\":{\"docs\":{},\"于\":{\"docs\":{},\"被\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"来\":{\"docs\":{},\"说\":{\"docs\":{},\"也\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"远\":{\"docs\":{},\"端\":{\"docs\":{},\"的\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"自\":{\"docs\":{},\"己\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"将\":{\"docs\":{},\"自\":{\"docs\":{},\"己\":{\"docs\":{},\"注\":{\"docs\":{},\"册\":{\"docs\":{},\"给\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"，\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"、\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"、\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"基\":{\"docs\":{},\"类\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"了\":{\"docs\":{},\"提\":{\"docs\":{},\"供\":{\"docs\":{},\"了\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"回\":{\"docs\":{},\"调\":{\"docs\":{},\"时\":{\"docs\":{},\"将\":{\"docs\":{},\"自\":{\"docs\":{},\"身\":{\"docs\":{},\"的\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"注\":{\"docs\":{},\"册\":{\"docs\":{},\"进\":{\"docs\":{},\"去\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"和\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"？\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}},\"就\":{\"docs\":{},\"相\":{\"docs\":{},\"当\":{\"docs\":{},\"于\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}},\"首\":{\"docs\":{},\"先\":{\"docs\":{},\"有\":{\"docs\":{},\"个\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"整\":{\"docs\":{},\"体\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"_\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\",\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"管\":{\"docs\":{},\"理\":{\"docs\":{},\"着\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"（\":{\"docs\":{},\"包\":{\"docs\":{},\"括\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"）\":{\"docs\":{},\"及\":{\"docs\":{},\"其\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"_\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"不\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{},\"任\":{\"docs\":{},\"何\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"，\":{\"docs\":{},\"只\":{\"docs\":{},\"负\":{\"docs\":{},\"责\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{\"principle-intro/Project_architectured.html\":{\"ref\":\"principle-intro/Project_architectured.html\",\"tf\":0.045454545454545456}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"要\":{\"docs\":{},\"明\":{\"docs\":{},\"确\":{\"docs\":{},\"一\":{\"docs\":{},\"点\":{\"docs\":{},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{},\"最\":{\"docs\":{},\"终\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"上\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"。\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"之\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"保\":{\"docs\":{},\"留\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"检\":{\"docs\":{},\"查\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"的\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"，\":{\"docs\":{},\"按\":{\"docs\":{},\"照\":{\"docs\":{},\"历\":{\"docs\":{},\"史\":{\"docs\":{},\"经\":{\"docs\":{},\"验\":{\"docs\":{},\"，\":{\"9\":{\"0\":{\"docs\":{},\"%\":{\"docs\":{},\"的\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"都\":{\"docs\":{},\"是\":{\"docs\":{},\"因\":{\"docs\":{},\"为\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"不\":{\"docs\":{},\"对\":{\"docs\":{},\"造\":{\"docs\":{},\"成\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}},\"docs\":{}},\"docs\":{}}}}}}}}}}}}}}}},\"，\":{\"docs\":{},\"确\":{\"docs\":{},\"保\":{\"docs\":{},\"手\":{\"docs\":{},\"机\":{\"docs\":{},\"存\":{\"docs\":{},\"储\":{\"docs\":{},\"卡\":{\"docs\":{},\"容\":{\"docs\":{},\"量\":{\"docs\":{},\"足\":{\"docs\":{},\"够\":{\"docs\":{},\"(\":{\"docs\":{},\"至\":{\"docs\":{},\"少\":{\"1\":{\"0\":{\"0\":{\"docs\":{},\"m\":{\"docs\":{},\"吧\":{\"docs\":{},\")\":{\"docs\":{},\"，\":{\"docs\":{},\"然\":{\"docs\":{},\"后\":{\"docs\":{},\"在\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"下\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"排\":{\"docs\":{},\"查\":{\"docs\":{},\"步\":{\"docs\":{},\"骤\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}},\"docs\":{}},\"docs\":{}},\"docs\":{}}}}}}}}}}}}}}},\"贴\":{\"docs\":{},\"一\":{\"docs\":{},\"张\":{\"docs\":{},\"反\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}},\"根\":{\"docs\":{},\"据\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"即\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\",\":{\"docs\":{},\"查\":{\"docs\":{},\"询\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"名\":{\"docs\":{},\"称\":{\"docs\":{},\"。\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"(\":{\"docs\":{},\"下\":{\"docs\":{},\")\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"知\":{\"docs\":{},\"道\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"中\":{\"docs\":{},\"存\":{\"docs\":{},\"储\":{\"docs\":{},\"了\":{\"docs\":{},\"几\":{\"docs\":{},\"乎\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"返\":{\"docs\":{},\"回\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"类\":{\"docs\":{},\"名\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"反\":{\"docs\":{},\"射\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"c\":{\"docs\":{},\"i\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}},\"是\":{\"docs\":{},\"读\":{\"docs\":{},\"取\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"数\":{\"docs\":{},\"据\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"和\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"数\":{\"docs\":{},\"据\":{\"docs\":{},\"也\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"期\":{\"docs\":{},\"由\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"写\":{\"docs\":{},\"到\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\",\":{\"docs\":{},\"用\":{\"docs\":{},\"途\":{\"docs\":{},\"：\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}},\"创\":{\"docs\":{},\"建\":{\"docs\":{},\"了\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"持\":{\"docs\":{},\"有\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"和\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"p\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"的\":{\"docs\":{},\"引\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"用\":{\"docs\":{},\"来\":{\"docs\":{},\"做\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"(\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"时\":{\"docs\":{},\"记\":{\"docs\":{},\"录\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"（\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"收\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"会\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"）\":{\"docs\":{\"principle-intro/File_architecture_runtime.html\":{\"ref\":\"principle-intro/File_architecture_runtime.html\",\"tf\":0.1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"类\":{\"docs\":{},\"会\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"变\":{\"docs\":{},\"种\":{\"docs\":{},\"，\":{\"docs\":{},\"导\":{\"docs\":{},\"致\":{\"docs\":{},\"整\":{\"docs\":{},\"体\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"效\":{\"docs\":{},\"率\":{\"docs\":{},\"大\":{\"docs\":{},\"大\":{\"docs\":{},\"降\":{\"docs\":{},\"低\":{\"docs\":{},\"。\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"存\":{\"docs\":{},\"放\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"变\":{\"docs\":{},\"化\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"，\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"每\":{\"docs\":{},\"次\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"，\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"等\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{\"principle-intro/File_architecture_runtime.html\":{\"ref\":\"principle-intro/File_architecture_runtime.html\",\"tf\":0.1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"等\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"，\":{\"docs\":{},\"每\":{\"docs\":{},\"次\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"选\":{\"docs\":{},\"取\":{\"docs\":{},\"最\":{\"docs\":{},\"高\":{\"docs\":{},\"可\":{\"docs\":{},\"用\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"载\":{\"docs\":{},\"入\":{\"docs\":{},\"。\":{\"docs\":{},\"考\":{\"docs\":{},\"虑\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"回\":{\"docs\":{},\"滚\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"和\":{\"docs\":{},\"对\":{\"docs\":{},\"空\":{\"docs\":{},\"间\":{\"docs\":{},\"占\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"影\":{\"docs\":{},\"响\":{\"docs\":{},\"，\":{\"docs\":{},\"目\":{\"docs\":{},\"前\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"内\":{\"docs\":{},\"最\":{\"docs\":{},\"多\":{\"docs\":{},\"保\":{\"docs\":{},\"留\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"最\":{\"docs\":{},\"近\":{\"docs\":{},\"可\":{\"docs\":{},\"用\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"。\":{\"docs\":{\"principle-intro/File_architecture_runtime.html\":{\"ref\":\"principle-intro/File_architecture_runtime.html\",\"tf\":0.1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"请\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"前\":{\"docs\":{},\"仔\":{\"docs\":{},\"细\":{\"docs\":{},\"阅\":{\"docs\":{},\"读\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"文\":{\"docs\":{},\"档\":{\"docs\":{},\".\":{\"docs\":{\"guide-for-use/\":{\"ref\":\"guide-for-use/\",\"tf\":0.25}}}}}}}}}}}}}},\"问\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"#\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.010810810810810811},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.012711864406779662}}},\"(\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}},\"p\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.008912655971479501}}}}}},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"k\":{\"docs\":{},\"_\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"=\":{\"docs\":{},\"=\":{\"2\":{\"5\":{\"docs\":{},\"&\":{\"docs\":{},\"&\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"_\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"k\":{\"docs\":{},\"_\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\">\":{\"0\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\")\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"j\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"b\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.02127659574468085}}}}}}}}}}}}}}}}}}}}}}}}}}},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"、\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"、\":{\"docs\":{},\"p\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"u\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\")\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"k\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"(\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}},\",\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.020134228187919462}},\"继\":{\"docs\":{},\"续\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}},\".\":{\"docs\":{},\"/\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154},\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.012422360248447204},\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.02127659574468085}}}}}}}}}},\".\":{\"docs\":{},\".\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\".\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"v\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\":\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.012711864406779662},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}},\"[\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.018633540372670808}},\"]\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154}}},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"]\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}},\"'\":{\"docs\":{},\"*\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"'\":{\"docs\":{},\"]\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00847457627118644}}}}}}}}}},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"'\":{\"docs\":{},\"]\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"，\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"时\":{\"docs\":{},\"，\":{\"docs\":{},\"会\":{\"docs\":{},\"将\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"路\":{\"docs\":{},\"径\":{\"docs\":{},\"写\":{\"docs\":{},\"入\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"。\":{\"docs\":{},\"程\":{\"docs\":{},\"序\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"时\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"会\":{\"docs\":{},\"第\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"'\":{\"docs\":{},\"]\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00847457627118644}}}}}}}}}}}}}}}}}},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}},\"e\":{\"docs\":{},\"n\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"b\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"对\":{\"docs\":{},\"于\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"层\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"来\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"的\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"，\":{\"docs\":{},\"会\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"一\":{\"docs\":{},\"定\":{\"docs\":{},\"限\":{\"docs\":{},\"制\":{\"docs\":{},\"，\":{\"docs\":{},\"且\":{\"docs\":{},\"会\":{\"docs\":{},\"影\":{\"docs\":{},\"响\":{\"docs\":{},\"后\":{\"docs\":{},\"续\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"目\":{\"docs\":{},\"前\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"内\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"不\":{\"docs\":{},\"建\":{\"docs\":{},\"议\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"来\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}},\"y\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"层\":{\"docs\":{},\"会\":{\"docs\":{},\"先\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"是\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"库\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"在\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"环\":{\"docs\":{},\"境\":{\"docs\":{},\"变\":{\"docs\":{},\"量\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{},\"的\":{\"docs\":{},\"路\":{\"docs\":{},\"径\":{\"docs\":{},\"内\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"是\":{\"docs\":{},\"外\":{\"docs\":{},\"部\":{\"docs\":{},\"引\":{\"docs\":{},\"入\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{},\"是\":{\"docs\":{},\"先\":{\"docs\":{},\"找\":{\"docs\":{},\"自\":{\"docs\":{},\"身\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"下\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"找\":{\"docs\":{},\"不\":{\"docs\":{},\"到\":{\"docs\":{},\"接\":{\"docs\":{},\"着\":{\"docs\":{},\"找\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"内\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"最\":{\"docs\":{},\"后\":{\"docs\":{},\"去\":{\"docs\":{},\"找\":{\"docs\":{},\"主\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"也\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"去\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"_\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"_\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"反\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"，\":{\"docs\":{},\"有\":{\"docs\":{},\"且\":{\"docs\":{},\"只\":{\"docs\":{},\"有\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}},\"，\":{\"docs\":{},\"解\":{\"docs\":{},\"压\":{\"docs\":{},\"反\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"，\":{\"docs\":{},\"有\":{\"docs\":{},\"且\":{\"docs\":{},\"只\":{\"docs\":{},\"有\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"/\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"b\":{\"docs\":{},\"i\":{\"docs\":{},\"/\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"_\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"_\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"n\":{\"docs\":{},\"k\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}},\"同\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"进\":{\"docs\":{},\"程\":{\"docs\":{},\"空\":{\"docs\":{},\"间\":{\"docs\":{},\"下\":{\"docs\":{},\"只\":{\"docs\":{},\"可\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"一\":{\"docs\":{},\"次\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"同\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"第\":{\"docs\":{},\"二\":{\"docs\":{},\"次\":{\"docs\":{},\"去\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"则\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"返\":{\"docs\":{},\"回\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"去\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"则\":{\"docs\":{},\"会\":{\"docs\":{},\"失\":{\"docs\":{},\"败\":{\"docs\":{},\"；\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"时\":{\"docs\":{},\"与\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"该\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"的\":{\"docs\":{},\"类\":{\"docs\":{},\"所\":{\"docs\":{},\"在\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"绑\":{\"docs\":{},\"定\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"反\":{\"docs\":{},\"调\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"层\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"的\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"只\":{\"docs\":{},\"能\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"到\":{\"docs\":{},\"够\":{\"docs\":{},\"找\":{\"docs\":{},\"到\":{\"docs\":{},\"该\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"找\":{\"docs\":{},\"到\":{\"docs\":{},\"的\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"类\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}},\"_\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}},\"(\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\",\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.005221932114882507}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}},\"c\":{\"docs\":{},\"k\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.010810810810810811}}},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0053475935828877}}},\".\":{\"docs\":{},\".\":{\"docs\":{},\".\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}},\"n\":{\"docs\":{},\"g\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"w\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"k\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"n\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}},\"s\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.010810810810810811}}},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\":\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\".\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"(\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"主\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}},\"动\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"在\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"能\":{\"docs\":{},\"够\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"实\":{\"docs\":{},\"际\":{\"docs\":{},\"上\":{\"docs\":{},\"同\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"类\":{\"docs\":{},\"似\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"基\":{\"docs\":{},\"线\":{\"docs\":{},\"包\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"就\":{\"docs\":{},\"已\":{\"docs\":{},\"经\":{\"docs\":{},\"做\":{\"docs\":{},\"了\":{\"docs\":{},\"处\":{\"docs\":{},\"理\":{\"docs\":{},\":\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"打\":{\"docs\":{},\"出\":{\"docs\":{},\"来\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"列\":{\"docs\":{},\"表\":{\"docs\":{},\"中\":{\"docs\":{},\"有\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"：\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"策\":{\"docs\":{},\"略\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}},\"e\":{\"docs\":{},\"在\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"和\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"上\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"有\":{\"docs\":{},\"所\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"，\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"设\":{\"docs\":{},\"备\":{\"docs\":{},\"上\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"任\":{\"docs\":{},\"何\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"把\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"_\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"_\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"以\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"形\":{\"docs\":{},\"式\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"到\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"下\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"界\":{\"docs\":{},\"面\":{\"docs\":{},\"点\":{\"docs\":{},\"开\":{\"docs\":{},\"侧\":{\"docs\":{},\"边\":{\"docs\":{},\"栏\":{\"docs\":{},\"，\":{\"docs\":{},\"点\":{\"docs\":{},\"击\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}},\"中\":{\"docs\":{},\"已\":{\"docs\":{},\"经\":{\"docs\":{},\"打\":{\"docs\":{},\"入\":{\"docs\":{},\"了\":{\"docs\":{},\"必\":{\"docs\":{},\"要\":{\"docs\":{},\"的\":{\"docs\":{},\"公\":{\"docs\":{},\"用\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"、\":{\"docs\":{},\"m\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\")\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"时\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"会\":{\"docs\":{},\"自\":{\"docs\":{},\"动\":{\"docs\":{},\"找\":{\"docs\":{},\"到\":{\"docs\":{},\"主\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"就\":{\"docs\":{},\"不\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"在\":{\"docs\":{},\"重\":{\"docs\":{},\"复\":{\"docs\":{},\"打\":{\"docs\":{},\"入\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"书\":{\"docs\":{},\"写\":{\"docs\":{},\"的\":{\"docs\":{},\"格\":{\"docs\":{},\"式\":{\"docs\":{},\"为\":{\"docs\":{},\"：\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\":\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"=\":{\"docs\":{},\"x\":{\"docs\":{},\"x\":{\"docs\":{},\"（\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"）\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}},\"自\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"的\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"的\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"h\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"，\":{\"docs\":{},\"跟\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"一\":{\"docs\":{},\"样\":{\"docs\":{},\"将\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"放\":{\"docs\":{},\"到\":{\"docs\":{},\"公\":{\"docs\":{},\"共\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"，\":{\"docs\":{},\"然\":{\"docs\":{},\"后\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"h\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"中\":{\"docs\":{},\"写\":{\"docs\":{},\"入\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"和\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"的\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"。\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"h\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"得\":{\"docs\":{},\"到\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"方\":{\"docs\":{},\"如\":{\"docs\":{},\"何\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}},\"式\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.005221932114882507}}},\"案\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}},\"者\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"这\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"与\":{\"docs\":{},\"真\":{\"docs\":{},\"正\":{\"docs\":{},\"的\":{\"docs\":{},\"远\":{\"docs\":{},\"端\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"通\":{\"docs\":{},\"信\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}},\"应\":{\"docs\":{},\"该\":{\"docs\":{},\"了\":{\"docs\":{},\"解\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"的\":{\"docs\":{},\"以\":{\"docs\":{},\"下\":{\"docs\":{},\"几\":{\"docs\":{},\"个\":{\"docs\":{},\"特\":{\"docs\":{},\"点\":{\"docs\":{},\"，\":{\"docs\":{},\"明\":{\"docs\":{},\"白\":{\"docs\":{},\"其\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"的\":{\"docs\":{},\"主\":{\"docs\":{},\"要\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"值\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}},\"是\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}},\"为\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"参\":{\"docs\":{},\"考\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"看\":{\"docs\":{},\"下\":{\"docs\":{},\"下\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"介\":{\"docs\":{},\"绍\":{\"docs\":{},\"，\":{\"docs\":{},\"至\":{\"docs\":{},\"于\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"的\":{\"docs\":{},\"其\":{\"docs\":{},\"他\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"，\":{\"docs\":{},\"大\":{\"docs\":{},\"家\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"自\":{\"docs\":{},\"行\":{\"docs\":{},\"扩\":{\"docs\":{},\"展\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"列\":{\"docs\":{},\"表\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.013422818791946308}}}}}},\"合\":{\"docs\":{},\"并\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}},\"和\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.010810810810810811}},\"其\":{\"docs\":{},\"他\":{\"docs\":{},\"的\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"中\":{\"docs\":{},\"间\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"k\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"字\":{\"docs\":{},\"段\":{\"docs\":{},\"完\":{\"docs\":{},\"美\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"官\":{\"docs\":{},\"方\":{\"docs\":{},\"的\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}},\"文\":{\"docs\":{},\"档\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}},\"应\":{\"docs\":{},\"用\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}},\"建\":{\"docs\":{},\"议\":{\"docs\":{},\"值\":{\"docs\":{},\"设\":{\"docs\":{},\"置\":{\"docs\":{},\"为\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"更\":{\"docs\":{},\"好\":{\"docs\":{},\"的\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"传\":{\"docs\":{},\"递\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"等\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"（\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"采\":{\"docs\":{},\"用\":{\"docs\":{},\"原\":{\"docs\":{},\"生\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"）\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"把\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"相\":{\"docs\":{},\"关\":{\"docs\":{},\"的\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"和\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"单\":{\"docs\":{},\"独\":{\"docs\":{},\"封\":{\"docs\":{},\"装\":{\"docs\":{},\"成\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"公\":{\"docs\":{},\"共\":{\"docs\":{},\"的\":{\"docs\":{},\"模\":{\"docs\":{},\"块\":{\"docs\":{},\"，\":{\"docs\":{},\"否\":{\"docs\":{},\"则\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"反\":{\"docs\":{},\"调\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"的\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"只\":{\"docs\":{},\"能\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"到\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"范\":{\"docs\":{},\"围\":{\"docs\":{},\"内\":{\"docs\":{},\"的\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"类\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"或\":{\"docs\":{},\"者\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"在\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"的\":{\"docs\":{},\"地\":{\"docs\":{},\"方\":{\"docs\":{},\"加\":{\"docs\":{},\"上\":{\"docs\":{},\"判\":{\"docs\":{},\"断\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{},\"，\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"特\":{\"docs\":{},\"殊\":{\"docs\":{},\"的\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}}}}}}}}},\"本\":{\"docs\":{},\"次\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"隐\":{\"docs\":{},\"含\":{\"docs\":{},\"带\":{\"docs\":{},\"入\":{\"docs\":{},\"了\":{\"docs\":{},\"其\":{\"docs\":{},\"它\":{\"docs\":{},\"改\":{\"docs\":{},\"动\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}},\"打\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"x\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154}}}}}}}},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.006711409395973154}}}}}},\"包\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"过\":{\"docs\":{},\"滤\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.013422818791946308}}}},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"检\":{\"docs\":{},\"查\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"等\":{\"docs\":{},\"等\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}},\"开\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"y\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"记\":{\"docs\":{},\"录\":{\"docs\":{},\"了\":{\"docs\":{},\"本\":{\"docs\":{},\"次\":{\"docs\":{},\"改\":{\"docs\":{},\"动\":{\"docs\":{},\"相\":{\"docs\":{},\"对\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"变\":{\"docs\":{},\"化\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"插\":{\"docs\":{},\"件\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}},\"，\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}},\"化\":{\"docs\":{},\"的\":{\"docs\":{},\"核\":{\"docs\":{},\"心\":{\"docs\":{},\"思\":{\"docs\":{},\"想\":{\"docs\":{},\"其\":{\"docs\":{},\"实\":{\"docs\":{},\"是\":{\"docs\":{},\"埋\":{\"docs\":{},\"坑\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"+\":{\"docs\":{},\"借\":{\"docs\":{},\"尸\":{\"docs\":{},\"还\":{\"docs\":{},\"魂\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}},\"入\":{\"docs\":{},\"前\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"除\":{\"docs\":{},\"外\":{\"docs\":{},\"）\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"树\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"的\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}},\"第\":{\"docs\":{},\"三\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"在\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}},\"包\":{\"docs\":{},\"(\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\")\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}},\"注\":{\"docs\":{},\"意\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"和\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"都\":{\"docs\":{},\"不\":{\"docs\":{},\"能\":{\"docs\":{},\"混\":{\"docs\":{},\"淆\":{\"docs\":{},\"，\":{\"docs\":{},\"且\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"是\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"尽\":{\"docs\":{},\"量\":{\"docs\":{},\"不\":{\"docs\":{},\"要\":{\"docs\":{},\"指\":{\"docs\":{},\"定\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}},\"点\":{\"docs\":{},\"：\":{\"docs\":{},\"虽\":{\"docs\":{},\"然\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"类\":{\"docs\":{},\"似\":{\"docs\":{},\"与\":{\"docs\":{},\"普\":{\"docs\":{},\"通\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"，\":{\"docs\":{},\"先\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{},\"再\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"过\":{\"docs\":{},\"有\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"点\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"引\":{\"docs\":{},\"起\":{\"docs\":{},\"注\":{\"docs\":{},\"意\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"差\":{\"docs\":{},\"量\":{\"docs\":{},\"与\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"差\":{\"docs\":{},\"量\":{\"docs\":{},\"目\":{\"docs\":{},\"前\":{\"docs\":{},\"采\":{\"docs\":{},\"取\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"的\":{\"docs\":{},\"策\":{\"docs\":{},\"略\":{\"docs\":{},\"，\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"永\":{\"docs\":{},\"远\":{\"docs\":{},\"是\":{\"docs\":{},\"与\":{\"docs\":{},\"基\":{\"docs\":{},\"线\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"做\":{\"docs\":{},\"差\":{\"docs\":{},\"量\":{\"docs\":{},\"；\":{\"docs\":{},\"而\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"是\":{\"docs\":{},\"更\":{\"docs\":{},\"上\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"做\":{\"docs\":{},\"差\":{\"docs\":{},\"量\":{\"docs\":{},\"：\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"从\":{\"6\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"到\":{\"6\":{\"docs\":{},\".\":{\"2\":{\"docs\":{},\"再\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"到\":{\"6\":{\"docs\":{},\".\":{\"3\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"6\":{\"docs\":{},\".\":{\"3\":{\"docs\":{},\"中\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"差\":{\"docs\":{},\"量\":{\"docs\":{},\"是\":{\"6\":{\"docs\":{},\".\":{\"3\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"集\":{\"docs\":{},\"成\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"和\":{\"docs\":{},\"基\":{\"docs\":{},\"线\":{\"docs\":{},\"（\":{\"6\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"）\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"出\":{\"docs\":{},\"差\":{\"docs\":{},\"量\":{\"docs\":{},\"；\":{\"6\":{\"docs\":{},\".\":{\"3\":{\"docs\":{},\"中\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"差\":{\"docs\":{},\"量\":{\"docs\":{},\"则\":{\"docs\":{},\"是\":{\"docs\":{},\"与\":{\"docs\":{},\"上\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"是\":{\"6\":{\"docs\":{},\".\":{\"2\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"去\":{\"docs\":{},\"请\":{\"docs\":{},\"求\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"差\":{\"docs\":{},\"量\":{\"docs\":{},\"是\":{\"6\":{\"docs\":{},\".\":{\"3\":{\"docs\":{},\"与\":{\"6\":{\"docs\":{},\".\":{\"2\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"所\":{\"docs\":{},\"得\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"是\":{\"6\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"去\":{\"docs\":{},\"请\":{\"docs\":{},\"求\":{\"6\":{\"docs\":{},\".\":{\"3\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"差\":{\"docs\":{},\"量\":{\"docs\":{},\"是\":{\"6\":{\"docs\":{},\".\":{\"3\":{\"docs\":{},\"与\":{\"6\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"所\":{\"docs\":{},\"得\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}}}}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}}},\"docs\":{}}},\"docs\":{}}}}}}}},\"docs\":{}}},\"docs\":{}}}}}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"图\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"箭\":{\"docs\":{},\"头\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}},\"添\":{\"docs\":{},\"加\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"库\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}},\"通\":{\"docs\":{},\"常\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"下\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"_\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"除\":{\"docs\":{},\"了\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"x\":{\"docs\":{},\"m\":{\"docs\":{},\"l\":{\"docs\":{},\"之\":{\"docs\":{},\"外\":{\"docs\":{},\"，\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"_\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"将\":{\"docs\":{},\"会\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{},\"以\":{\"docs\":{},\"下\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"来\":{\"docs\":{},\"说\":{\"docs\":{},\"都\":{\"docs\":{},\"是\":{\"docs\":{},\"改\":{\"docs\":{},\"了\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"，\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"变\":{\"docs\":{},\"更\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"/\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"，\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"一\":{\"docs\":{},\"般\":{\"docs\":{},\"都\":{\"docs\":{},\"是\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"正\":{\"docs\":{},\"常\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"过\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\",\":{\"docs\":{},\"以\":{\"docs\":{},\"保\":{\"docs\":{},\"证\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"段\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"（\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"m\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"g\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"设\":{\"docs\":{},\"置\":{\"docs\":{},\"自\":{\"docs\":{},\"动\":{\"docs\":{},\"分\":{\"docs\":{},\"配\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"）\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}},\"列\":{\"docs\":{},\"表\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}},\"参\":{\"docs\":{},\"数\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}},\"名\":{\"docs\":{},\"称\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"写\":{\"docs\":{},\"很\":{\"docs\":{},\"多\":{\"docs\":{},\"的\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"变\":{\"docs\":{},\"的\":{\"docs\":{},\"很\":{\"docs\":{},\"灵\":{\"docs\":{},\"活\":{\"docs\":{},\"。\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}}}}}}}}},\"的\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"基\":{\"docs\":{},\"本\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"。\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}},\"预\":{\"docs\":{},\"处\":{\"docs\":{},\"理\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}}}}}}}}}}}},\"（\":{\"2\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"~\":{\"2\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"）\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}},\"，\":{\"docs\":{\"guide-for-use/guide_for_build.html\":{\"ref\":\"guide-for-use/guide_for_build.html\",\"tf\":0.003355704697986577},\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.02127659574468085}},\"用\":{\"docs\":{},\"途\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}},\"@\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.031331592689295036},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0053475935828877}}}}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.007832898172323759}}}}}}},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"w\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}},\"`\":{\"docs\":{},\"`\":{\"docs\":{},\"`\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.010443864229765013}}}},\".\":{\"docs\":{},\"/\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.007832898172323759}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}},\"e\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"、\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"等\":{\"docs\":{},\"都\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"主\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"回\":{\"docs\":{},\"调\":{\"docs\":{},\"的\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"(\":{\"docs\":{},\")\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}},\"{\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"限\":{\"docs\":{},\"制\":{\"docs\":{},\":\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"到\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"后\":{\"docs\":{},\"原\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"会\":{\"docs\":{},\"改\":{\"docs\":{},\"为\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"2\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"时\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"由\":{\"docs\":{},\"原\":{\"docs\":{},\"来\":{\"docs\":{},\"的\":{\"docs\":{},\"解\":{\"docs\":{},\"释\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"改\":{\"docs\":{},\"为\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"，\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"的\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"发\":{\"docs\":{},\"现\":{\"docs\":{},\"单\":{\"docs\":{},\"纯\":{\"docs\":{},\"得\":{\"docs\":{},\"往\":{\"docs\":{},\"前\":{\"docs\":{},\"面\":{\"docs\":{},\"追\":{\"docs\":{},\"加\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"并\":{\"docs\":{},\"不\":{\"docs\":{},\"能\":{\"docs\":{},\"完\":{\"docs\":{},\"全\":{\"docs\":{},\"解\":{\"docs\":{},\"决\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"，\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"2\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"优\":{\"docs\":{},\"化\":{\"docs\":{},\"了\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"，\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"说\":{\"docs\":{},\"内\":{\"docs\":{},\"敛\":{\"docs\":{},\"，\":{\"docs\":{},\"虚\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"的\":{\"docs\":{},\"校\":{\"docs\":{},\"验\":{\"docs\":{},\"等\":{\"docs\":{},\"。\":{\"docs\":{},\"就\":{\"docs\":{},\"有\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"在\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"在\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"层\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"老\":{\"docs\":{},\"的\":{\"docs\":{},\"优\":{\"docs\":{},\"化\":{\"docs\":{},\"过\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"而\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{},\"从\":{\"docs\":{},\"新\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"中\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"去\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"。\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"上\":{\"docs\":{},\"目\":{\"docs\":{},\"前\":{\"docs\":{},\"的\":{\"docs\":{},\"策\":{\"docs\":{},\"略\":{\"docs\":{},\"是\":{\"docs\":{},\"把\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"，\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"参\":{\"docs\":{},\"考\":{\"docs\":{},\"m\":{\"docs\":{},\"u\":{\"docs\":{},\"l\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"的\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"放\":{\"docs\":{},\"入\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"z\":{\"docs\":{},\"i\":{\"docs\":{},\"p\":{\"docs\":{},\"，\":{\"docs\":{},\"然\":{\"docs\":{},\"后\":{\"docs\":{},\"合\":{\"docs\":{},\"并\":{\"docs\":{},\"在\":{\"docs\":{},\"一\":{\"docs\":{},\"起\":{\"docs\":{},\"做\":{\"docs\":{},\"一\":{\"docs\":{},\"遍\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"2\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"样\":{\"docs\":{},\"能\":{\"docs\":{},\"使\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"覆\":{\"docs\":{},\"盖\":{\"docs\":{},\"老\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"参\":{\"docs\":{},\"与\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"2\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"并\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"优\":{\"docs\":{},\"化\":{\"docs\":{},\"的\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"上\":{\"docs\":{},\"的\":{\"docs\":{},\"真\":{\"docs\":{},\"正\":{\"docs\":{},\"的\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"实\":{\"docs\":{},\"际\":{\"docs\":{},\"上\":{\"docs\":{},\"在\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"中\":{\"docs\":{},\"已\":{\"docs\":{},\"经\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{},\"了\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"，\":{\"docs\":{},\"基\":{\"docs\":{},\"本\":{\"docs\":{},\"不\":{\"docs\":{},\"会\":{\"docs\":{},\"走\":{\"docs\":{},\"到\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"k\":{\"docs\":{},\",\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"再\":{\"docs\":{},\"解\":{\"docs\":{},\"压\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"打\":{\"docs\":{},\"开\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"k\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"关\":{\"docs\":{},\"键\":{\"docs\":{},\"字\":{\"docs\":{},\"搜\":{\"docs\":{},\"索\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"o\":{\"docs\":{},\".\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.01694915254237288}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"j\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.007677543186180422},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.009404388714733543}}}}}}},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}},\"的\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.003838771593090211}}}}}},\"过\":{\"docs\":{},\"程\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}},\"加\":{\"docs\":{},\"上\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"为\":{\"docs\":{},\"：\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\".\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"载\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}}}}}}},\"时\":{\"docs\":{},\"机\":{\"docs\":{},\"的\":{\"docs\":{},\"触\":{\"docs\":{},\"发\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}},\"过\":{\"docs\":{},\"程\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}}},\"去\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}},\"在\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"主\":{\"docs\":{},\"客\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"添\":{\"docs\":{},\"加\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"中\":{\"docs\":{},\"声\":{\"docs\":{},\"明\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"段\":{\"docs\":{},\"（\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"m\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\".\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"g\":{\"docs\":{},\".\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"设\":{\"docs\":{},\"置\":{\"docs\":{},\"自\":{\"docs\":{},\"动\":{\"docs\":{},\"分\":{\"docs\":{},\"配\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"）\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"(\":{\"docs\":{},\"上\":{\"docs\":{},\")\":{\"docs\":{},\"的\":{\"2\":{\"docs\":{},\".\":{\"4\":{\"docs\":{},\"小\":{\"docs\":{},\"节\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"防\":{\"docs\":{},\"止\":{\"docs\":{},\"在\":{\"docs\":{},\"主\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"中\":{\"docs\":{},\"找\":{\"docs\":{},\"不\":{\"docs\":{},\"到\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\",\":{\"docs\":{},\"不\":{\"docs\":{},\"得\":{\"docs\":{},\"已\":{\"docs\":{},\"延\":{\"docs\":{},\"迟\":{\"docs\":{},\"了\":{\"docs\":{},\"对\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"。\":{\"docs\":{},\"而\":{\"docs\":{},\"在\":{\"docs\":{},\"第\":{\"5\":{\"docs\":{},\"步\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"了\":{\"docs\":{},\"对\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"等\":{\"docs\":{},\"关\":{\"docs\":{},\"键\":{\"docs\":{},\"地\":{\"docs\":{},\"方\":{\"docs\":{},\"的\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"。\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"，\":{\"docs\":{},\"此\":{\"docs\":{},\"时\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"，\":{\"docs\":{},\"是\":{\"docs\":{},\"不\":{\"docs\":{},\"会\":{\"docs\":{},\"出\":{\"docs\":{},\"现\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}}}}}}}},\"之\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"(\":{\"docs\":{},\"二\":{\"docs\":{},\")\":{\"docs\":{},\"下\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"解\":{\"docs\":{},\"释\":{\"docs\":{},\"过\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"最\":{\"docs\":{},\"终\":{\"docs\":{},\"会\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"到\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"多\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"事\":{\"docs\":{},\"先\":{\"docs\":{},\"了\":{\"docs\":{},\"解\":{\"docs\":{},\"几\":{\"docs\":{},\"个\":{\"docs\":{},\"要\":{\"docs\":{},\"点\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"对\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"做\":{\"docs\":{},\"了\":{\"docs\":{},\"一\":{\"docs\":{},\"系\":{\"docs\":{},\"列\":{\"docs\":{},\"处\":{\"docs\":{},\"理\":{\"docs\":{},\"以\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"期\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"的\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"只\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"时\":{\"docs\":{},\"根\":{\"docs\":{},\"据\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"读\":{\"docs\":{},\"取\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"的\":{\"docs\":{},\"先\":{\"docs\":{},\"后\":{\"docs\":{},\"书\":{\"docs\":{},\"序\":{\"docs\":{},\"把\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"包\":{\"docs\":{},\"插\":{\"docs\":{},\"入\":{\"docs\":{},\"到\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"合\":{\"docs\":{},\"适\":{\"docs\":{},\"的\":{\"docs\":{},\"位\":{\"docs\":{},\"置\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"预\":{\"docs\":{},\"留\":{\"docs\":{},\"，\":{\"docs\":{},\"插\":{\"docs\":{},\"入\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"s\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"类\":{\"docs\":{},\"似\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"处\":{\"docs\":{},\"理\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"不\":{\"docs\":{},\"再\":{\"docs\":{},\"展\":{\"docs\":{},\"开\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"整\":{\"docs\":{},\"包\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"过\":{\"docs\":{},\"滤\":{\"docs\":{},\"的\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{},\"，\":{\"docs\":{},\"把\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"的\":{\"docs\":{},\"架\":{\"docs\":{},\"构\":{\"docs\":{},\"类\":{\"docs\":{},\"型\":{\"docs\":{},\"指\":{\"docs\":{},\"定\":{\"docs\":{},\"清\":{\"docs\":{},\"楚\":{\"docs\":{},\"，\":{\"docs\":{},\"要\":{\"docs\":{},\"不\":{\"docs\":{},\"然\":{\"docs\":{},\"就\":{\"docs\":{},\"会\":{\"docs\":{},\"被\":{\"docs\":{},\"裁\":{\"docs\":{},\"减\":{\"docs\":{},\"掉\":{\"docs\":{},\"。\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"参\":{\"docs\":{},\"考\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"需\":{\"docs\":{},\"求\":{\"docs\":{},\"迭\":{\"docs\":{},\"代\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"考\":{\"docs\":{},\"虑\":{\"docs\":{},\"需\":{\"docs\":{},\"求\":{\"docs\":{},\"的\":{\"docs\":{},\"复\":{\"docs\":{},\"杂\":{\"docs\":{},\"性\":{\"docs\":{},\"和\":{\"docs\":{},\"每\":{\"docs\":{},\"次\":{\"docs\":{},\"周\":{\"docs\":{},\"期\":{\"docs\":{},\"性\":{\"docs\":{},\"迭\":{\"docs\":{},\"代\":{\"docs\":{},\"管\":{\"docs\":{},\"理\":{\"docs\":{},\"的\":{\"docs\":{},\"成\":{\"docs\":{},\"本\":{\"docs\":{},\"，\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"参\":{\"docs\":{},\"考\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"迭\":{\"docs\":{},\"代\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"统\":{\"docs\":{},\"一\":{\"docs\":{},\"的\":{\"docs\":{},\"集\":{\"docs\":{},\"成\":{\"docs\":{},\"区\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"管\":{\"docs\":{},\"理\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"在\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"上\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"实\":{\"docs\":{},\"际\":{\"docs\":{},\"上\":{\"docs\":{},\"是\":{\"docs\":{},\"先\":{\"docs\":{},\"有\":{\"docs\":{},\"整\":{\"docs\":{},\"包\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"，\":{\"docs\":{},\"再\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"出\":{\"docs\":{},\"差\":{\"docs\":{},\"异\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"样\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"规\":{\"docs\":{},\"避\":{\"docs\":{},\"了\":{\"docs\":{},\"混\":{\"docs\":{},\"淆\":{\"docs\":{},\"、\":{\"docs\":{},\"内\":{\"docs\":{},\"联\":{\"docs\":{},\"等\":{\"docs\":{},\"带\":{\"docs\":{},\"来\":{\"docs\":{},\"的\":{\"docs\":{},\"复\":{\"docs\":{},\"杂\":{\"docs\":{},\"性\":{\"docs\":{},\"的\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"处\":{\"docs\":{},\"理\":{\"docs\":{},\"，\":{\"docs\":{},\"保\":{\"docs\":{},\"证\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"对\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"的\":{\"docs\":{},\"完\":{\"docs\":{},\"全\":{\"docs\":{},\"适\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"这\":{\"docs\":{},\"种\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"也\":{\"docs\":{},\"必\":{\"docs\":{},\"不\":{\"docs\":{},\"可\":{\"docs\":{},\"少\":{\"docs\":{},\"的\":{\"docs\":{},\"影\":{\"docs\":{},\"响\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"的\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"速\":{\"docs\":{},\"度\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"对\":{\"docs\":{},\"紧\":{\"docs\":{},\"急\":{\"docs\":{},\"的\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"的\":{\"docs\":{},\"关\":{\"docs\":{},\"键\":{\"docs\":{},\"时\":{\"docs\":{},\"期\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"时\":{\"docs\":{},\"间\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"会\":{\"docs\":{},\"是\":{\"docs\":{},\"不\":{\"docs\":{},\"可\":{\"docs\":{},\"接\":{\"docs\":{},\"受\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"其\":{\"docs\":{},\"他\":{\"docs\":{},\"进\":{\"docs\":{},\"程\":{\"docs\":{},\"里\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"的\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"在\":{\"docs\":{},\"什\":{\"docs\":{},\"么\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"？\":{\"docs\":{},\"可\":{\"docs\":{},\"不\":{\"docs\":{},\"可\":{\"docs\":{},\"手\":{\"docs\":{},\"动\":{\"docs\":{},\"控\":{\"docs\":{},\"制\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"机\":{\"docs\":{},\"？\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"里\":{\"docs\":{},\"边\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"就\":{\"docs\":{},\"好\":{\"docs\":{},\"了\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}},\"覆\":{\"docs\":{},\"盖\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"，\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"没\":{\"docs\":{},\"变\":{\"docs\":{},\"化\":{\"docs\":{},\"，\":{\"docs\":{},\"没\":{\"docs\":{},\"做\":{\"docs\":{},\"清\":{\"docs\":{},\"理\":{\"docs\":{},\"，\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"按\":{\"docs\":{},\"需\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"，\":{\"docs\":{},\"例\":{\"docs\":{},\"如\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"单\":{\"docs\":{},\"独\":{\"docs\":{},\"的\":{\"docs\":{},\"进\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"只\":{\"docs\":{},\"要\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"去\":{\"docs\":{},\"b\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"就\":{\"docs\":{},\"会\":{\"docs\":{},\"触\":{\"docs\":{},\"发\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"。\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"手\":{\"docs\":{},\"动\":{\"docs\":{},\"控\":{\"docs\":{},\"制\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"时\":{\"docs\":{},\"机\":{\"docs\":{},\"，\":{\"docs\":{},\"按\":{\"docs\":{},\"需\":{\"docs\":{},\"就\":{\"docs\":{},\"好\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"上\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"会\":{\"docs\":{},\"带\":{\"docs\":{},\"有\":{\"docs\":{},\"v\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"里\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"基\":{\"docs\":{},\"础\":{\"docs\":{},\"的\":{\"docs\":{},\"变\":{\"docs\":{},\"量\":{\"docs\":{},\"，\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"：\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"提\":{\"docs\":{},\"示\":{\"docs\":{},\"重\":{\"docs\":{},\"启\":{\"docs\":{},\"前\":{\"docs\":{},\"，\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}},\"发\":{\"docs\":{},\"布\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"/\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"时\":{\"docs\":{},\"，\":{\"docs\":{},\"带\":{\"docs\":{},\"动\":{\"docs\":{},\"了\":{\"docs\":{},\"其\":{\"docs\":{},\"它\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"／\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"变\":{\"docs\":{},\"化\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"看\":{\"docs\":{},\"完\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"反\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"，\":{\"docs\":{},\"看\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"最\":{\"docs\":{},\"终\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"的\":{\"docs\":{},\"结\":{\"docs\":{},\"构\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"开\":{\"docs\":{},\"始\":{\"docs\":{},\"分\":{\"docs\":{},\"析\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"要\":{\"docs\":{},\"知\":{\"docs\":{},\"道\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"上\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"方\":{\"docs\":{},\"案\":{\"docs\":{},\"，\":{\"docs\":{},\"始\":{\"docs\":{},\"终\":{\"docs\":{},\"都\":{\"docs\":{},\"绕\":{\"docs\":{},\"不\":{\"docs\":{},\"过\":{\"docs\":{},\"三\":{\"docs\":{},\"个\":{\"docs\":{},\"关\":{\"docs\":{},\"键\":{\"docs\":{},\"的\":{\"docs\":{},\"点\":{\"docs\":{},\":\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"第\":{\"2\":{\"docs\":{},\"步\":{\"docs\":{},\"的\":{\"2\":{\"docs\":{},\".\":{\"4\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"，\":{\"docs\":{},\"对\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"了\":{\"docs\":{},\"处\":{\"docs\":{},\"理\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}}},\"6\":{\"docs\":{},\"行\":{\"docs\":{},\"构\":{\"docs\":{},\"造\":{\"docs\":{},\"出\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"注\":{\"docs\":{},\"册\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"，\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"。\":{\"docs\":{},\"对\":{\"docs\":{},\"于\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"来\":{\"docs\":{},\"说\":{\"docs\":{},\"，\":{\"docs\":{},\"似\":{\"docs\":{},\"乎\":{\"docs\":{},\"还\":{\"docs\":{},\"差\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"关\":{\"docs\":{},\"键\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"入\":{\"docs\":{},\"口\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"接\":{\"docs\":{},\"着\":{\"docs\":{},\"看\":{\"docs\":{},\"构\":{\"docs\":{},\"造\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"周\":{\"docs\":{},\"期\":{\"docs\":{},\"内\":{\"docs\":{},\"，\":{\"docs\":{},\"做\":{\"docs\":{},\"的\":{\"docs\":{},\"事\":{\"docs\":{},\"情\":{\"docs\":{},\"非\":{\"docs\":{},\"常\":{\"docs\":{},\"之\":{\"docs\":{},\"多\":{\"docs\":{},\"，\":{\"docs\":{},\"重\":{\"docs\":{},\"要\":{\"docs\":{},\"的\":{\"docs\":{},\"是\":{\"docs\":{},\"第\":{\"3\":{\"docs\":{},\"、\":{\"4\":{\"docs\":{},\"、\":{\"6\":{\"docs\":{},\"、\":{\"7\":{\"docs\":{},\"和\":{\"8\":{\"docs\":{},\"步\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"周\":{\"docs\":{},\"期\":{\"docs\":{},\"内\":{\"docs\":{},\"，\":{\"docs\":{},\"主\":{\"docs\":{},\"要\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"了\":{\"docs\":{},\"两\":{\"docs\":{},\"件\":{\"docs\":{},\"事\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"这\":{\"docs\":{},\"一\":{\"docs\":{},\"步\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"开\":{\"docs\":{},\"始\":{\"docs\":{},\"异\":{\"docs\":{},\"步\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"主\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{},\"回\":{\"docs\":{},\"调\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"(\":{\"docs\":{},\"后\":{\"docs\":{},\"面\":{\"docs\":{},\"会\":{\"docs\":{},\"提\":{\"docs\":{},\"及\":{\"docs\":{},\")\":{\"docs\":{},\",\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"的\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"，\":{\"docs\":{},\"开\":{\"docs\":{},\"始\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"外\":{\"docs\":{},\"部\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}},\"这\":{\"docs\":{},\"样\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"避\":{\"docs\":{},\"免\":{\"docs\":{},\"主\":{\"docs\":{},\"进\":{\"docs\":{},\"程\":{\"docs\":{},\"一\":{\"docs\":{},\"起\":{\"docs\":{},\"来\":{\"docs\":{},\"就\":{\"docs\":{},\"去\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"导\":{\"docs\":{},\"致\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"时\":{\"docs\":{},\"间\":{\"docs\":{},\"过\":{\"docs\":{},\"长\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"加\":{\"docs\":{},\"了\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}},\"种\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"适\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"具\":{\"docs\":{},\"有\":{\"docs\":{},\"特\":{\"docs\":{},\"定\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"的\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"k\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"在\":{\"docs\":{},\"手\":{\"docs\":{},\"淘\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"和\":{\"docs\":{},\"w\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"属\":{\"docs\":{},\"于\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"引\":{\"docs\":{},\"用\":{\"docs\":{},\"了\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"理\":{\"docs\":{},\"论\":{\"docs\":{},\"上\":{\"docs\":{},\"是\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"中\":{\"docs\":{},\"是\":{\"docs\":{},\"不\":{\"docs\":{},\"推\":{\"docs\":{},\"荐\":{\"docs\":{},\"(\":{\"docs\":{},\"也\":{\"docs\":{},\"没\":{\"docs\":{},\"不\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\")\":{\"docs\":{},\"这\":{\"docs\":{},\"种\":{\"docs\":{},\"反\":{\"docs\":{},\"向\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"里\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"q\":{\"docs\":{},\"u\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"传\":{\"docs\":{},\"入\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"对\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"者\":{\"docs\":{},\"来\":{\"docs\":{},\"说\":{\"docs\":{},\"还\":{\"docs\":{},\"有\":{\"docs\":{},\"点\":{\"docs\":{},\"晦\":{\"docs\":{},\"涩\":{\"docs\":{},\"，\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"k\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"者\":{\"docs\":{},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"尝\":{\"docs\":{},\"试\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"对\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"封\":{\"docs\":{},\"装\":{\"docs\":{},\"，\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"改\":{\"docs\":{},\"造\":{\"docs\":{},\"成\":{\"docs\":{},\"更\":{\"docs\":{},\"为\":{\"docs\":{},\"直\":{\"docs\":{},\"观\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"和\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"u\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"有\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"注\":{\"docs\":{},\"意\":{\"docs\":{},\"点\":{\"docs\":{},\"提\":{\"docs\":{},\"及\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"以\":{\"docs\":{},\"加\":{\"docs\":{},\"深\":{\"docs\":{},\"理\":{\"docs\":{},\"解\":{\"docs\":{},\"：\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}},\"判\":{\"docs\":{},\"断\":{\"docs\":{},\"条\":{\"docs\":{},\"件\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}},\"粗\":{\"docs\":{},\"略\":{\"docs\":{},\"介\":{\"docs\":{},\"绍\":{\"docs\":{},\"下\":{\"docs\":{},\"普\":{\"docs\":{},\"通\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"（\":{\"docs\":{},\"也\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"）\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"库\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"入\":{\"docs\":{},\"口\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"也\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"的\":{\"docs\":{},\"某\":{\"docs\":{},\"个\":{\"docs\":{},\"a\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"。\":{\"docs\":{},\"一\":{\"docs\":{},\"句\":{\"docs\":{},\"话\":{\"docs\":{},\"，\":{\"docs\":{},\"你\":{\"docs\":{},\"要\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"告\":{\"docs\":{},\"诉\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"器\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"变\":{\"docs\":{},\"了\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"要\":{\"docs\":{},\"强\":{\"docs\":{},\"调\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"的\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"要\":{\"docs\":{},\"内\":{\"docs\":{},\"聚\":{\"docs\":{},\"。\":{\"docs\":{},\"假\":{\"docs\":{},\"设\":{\"docs\":{},\"a\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"b\":{\"docs\":{},\",\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"时\":{\"docs\":{},\"，\":{\"docs\":{},\"只\":{\"docs\":{},\"改\":{\"docs\":{},\"a\":{\"docs\":{},\"或\":{\"docs\":{},\"b\":{\"docs\":{},\"自\":{\"docs\":{},\"身\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"a\":{\"docs\":{},\"与\":{\"docs\":{},\"b\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"多\":{\"docs\":{},\"提\":{\"docs\":{},\"一\":{\"docs\":{},\"句\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"四\":{\"docs\":{},\"大\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"的\":{\"docs\":{},\"处\":{\"docs\":{},\"理\":{\"docs\":{},\"上\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\"与\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"化\":{\"docs\":{},\"有\":{\"docs\":{},\"着\":{\"docs\":{},\"很\":{\"docs\":{},\"大\":{\"docs\":{},\"的\":{\"docs\":{},\"差\":{\"docs\":{},\"异\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"些\":{\"docs\":{},\"是\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}},\"字\":{\"docs\":{},\"段\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"赋\":{\"docs\":{},\"值\":{\"docs\":{},\"工\":{\"docs\":{},\"作\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}},\"是\":{\"docs\":{},\"因\":{\"docs\":{},\"为\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"默\":{\"docs\":{},\"认\":{\"docs\":{},\"开\":{\"docs\":{},\"启\":{\"docs\":{},\"了\":{\"docs\":{},\"去\":{\"docs\":{},\"除\":{\"docs\":{},\"自\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"权\":{\"docs\":{},\"限\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}},\"两\":{\"docs\":{},\"篇\":{\"docs\":{},\"文\":{\"docs\":{},\"章\":{\"docs\":{},\"提\":{\"docs\":{},\"到\":{\"docs\":{},\"的\":{\"docs\":{},\"规\":{\"docs\":{},\"范\":{\"docs\":{},\"，\":{\"docs\":{},\"来\":{\"docs\":{},\"组\":{\"docs\":{},\"织\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"结\":{\"docs\":{},\"构\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"在\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"期\":{\"docs\":{},\"已\":{\"docs\":{},\"经\":{\"docs\":{},\"写\":{\"docs\":{},\"到\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"了\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"也\":{\"docs\":{},\"是\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"个\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"牵\":{\"docs\":{},\"涉\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}},\"几\":{\"docs\":{},\"个\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"并\":{\"docs\":{},\"不\":{\"docs\":{},\"复\":{\"docs\":{},\"杂\":{\"docs\":{},\"，\":{\"docs\":{},\"是\":{\"docs\":{},\"对\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"、\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"、\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"和\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"段\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"，\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"对\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"关\":{\"docs\":{},\"键\":{\"docs\":{},\"节\":{\"docs\":{},\"点\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"了\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"，\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"的\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"就\":{\"docs\":{},\"不\":{\"docs\":{},\"贴\":{\"docs\":{},\"出\":{\"docs\":{},\"了\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"感\":{\"docs\":{},\"兴\":{\"docs\":{},\"趣\":{\"docs\":{},\"，\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"参\":{\"docs\":{},\"考\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"源\":{\"docs\":{},\"码\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"田\":{\"docs\":{},\"维\":{\"docs\":{},\"术\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"g\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"何\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"，\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"为\":{\"docs\":{},\"什\":{\"docs\":{},\"么\":{\"docs\":{},\"在\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"文\":{\"docs\":{},\"章\":{\"docs\":{},\"中\":{\"docs\":{},\"都\":{\"docs\":{},\"讲\":{\"docs\":{},\"的\":{\"docs\":{},\"非\":{\"docs\":{},\"常\":{\"docs\":{},\"清\":{\"docs\":{},\"楚\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"遵\":{\"docs\":{},\"循\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"规\":{\"docs\":{},\"范\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"有\":{\"docs\":{},\"效\":{\"docs\":{},\"避\":{\"docs\":{},\"免\":{\"docs\":{},\"在\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"时\":{\"docs\":{},\"遇\":{\"docs\":{},\"到\":{\"docs\":{},\"难\":{\"docs\":{},\"以\":{\"docs\":{},\"排\":{\"docs\":{},\"查\":{\"docs\":{},\"的\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"默\":{\"docs\":{},\"认\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"只\":{\"docs\":{},\"往\":{\"docs\":{},\"外\":{\"docs\":{},\"暴\":{\"docs\":{},\"露\":{\"docs\":{},\"了\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"原\":{\"docs\":{},\"生\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\",\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"期\":{\"docs\":{},\"按\":{\"docs\":{},\"需\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"。\":{\"docs\":{},\"某\":{\"docs\":{},\"些\":{\"docs\":{},\"特\":{\"docs\":{},\"殊\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"（\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"说\":{\"docs\":{},\"监\":{\"docs\":{},\"控\":{\"docs\":{},\"性\":{\"docs\":{},\"质\":{\"docs\":{},\"的\":{\"docs\":{},\"）\":{\"docs\":{},\"本\":{\"docs\":{},\"身\":{\"docs\":{},\"与\":{\"docs\":{},\"其\":{\"docs\":{},\"他\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"完\":{\"docs\":{},\"全\":{\"docs\":{},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"，\":{\"docs\":{},\"且\":{\"docs\":{},\"又\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"在\":{\"docs\":{},\"某\":{\"docs\":{},\"个\":{\"docs\":{},\"时\":{\"docs\":{},\"间\":{\"docs\":{},\"点\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"去\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/guide_for_bundle.html\":{\"ref\":\"guide-for-use/guide_for_bundle.html\",\"tf\":0.011235955056179775}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"待\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{\"guide-for-use/guide_for_compile.html\":{\"ref\":\"guide-for-use/guide_for_compile.html\",\"tf\":1}}}}},\"!\":{\"docs\":{},\"[\":{\"docs\":{},\"]\":{\"docs\":{},\"(\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}},\"=\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0071301247771836}}},\"t\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\".\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"(\":{\"docs\":{},\")\":{\"docs\":{},\")\":{\"docs\":{},\"{\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}},\"*\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.013054830287206266}},\"/\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"改\":{\"docs\":{},\"动\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}},\"：\":{\"docs\":{},\"以\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"为\":{\"docs\":{},\"例\":{\"docs\":{},\"，\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"在\":{\"docs\":{},\"自\":{\"docs\":{},\"己\":{\"docs\":{},\"的\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"g\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"做\":{\"docs\":{},\"一\":{\"docs\":{},\"定\":{\"docs\":{},\"的\":{\"docs\":{},\"改\":{\"docs\":{},\"动\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"以\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"复\":{\"docs\":{},\"杂\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"比\":{\"docs\":{},\"如\":{\"docs\":{},\"手\":{\"docs\":{},\"淘\":{\"docs\":{},\"这\":{\"docs\":{},\"种\":{\"docs\":{},\"无\":{\"docs\":{},\"数\":{\"docs\":{},\"个\":{\"docs\":{},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"交\":{\"docs\":{},\"织\":{\"docs\":{},\"的\":{\"docs\":{},\"场\":{\"docs\":{},\"景\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"完\":{\"docs\":{},\"全\":{\"docs\":{},\"的\":{\"docs\":{},\"隔\":{\"docs\":{},\"离\":{\"docs\":{},\"也\":{\"docs\":{},\"给\":{\"docs\":{},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"的\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"造\":{\"docs\":{},\"成\":{\"docs\":{},\"了\":{\"docs\":{},\"不\":{\"docs\":{},\"小\":{\"docs\":{},\"的\":{\"docs\":{},\"成\":{\"docs\":{},\"本\":{\"docs\":{},\"。\":{\"docs\":{},\"针\":{\"docs\":{},\"对\":{\"docs\":{},\"这\":{\"docs\":{},\"种\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"，\":{\"docs\":{},\"目\":{\"docs\":{},\"前\":{\"docs\":{},\"主\":{\"docs\":{},\"要\":{\"docs\":{},\"解\":{\"docs\":{},\"决\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"案\":{\"docs\":{},\"有\":{\"docs\":{},\"：\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"假\":{\"docs\":{},\"设\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}},\"在\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"下\":{\"docs\":{},\"则\":{\"docs\":{},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"针\":{\"docs\":{},\"对\":{\"docs\":{},\"非\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"先\":{\"docs\":{},\"附\":{\"docs\":{},\"一\":{\"docs\":{},\"张\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"图\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"清\":{\"docs\":{},\"楚\":{\"docs\":{},\"的\":{\"docs\":{},\"同\":{\"docs\":{},\"学\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"大\":{\"docs\":{},\"致\":{\"docs\":{},\"了\":{\"docs\":{},\"解\":{\"docs\":{},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"的\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"理\":{\"docs\":{},\"清\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"和\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"在\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"时\":{\"docs\":{},\"的\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"交\":{\"docs\":{},\"织\":{\"docs\":{},\"的\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"(\":{\"docs\":{},\"图\":{\"docs\":{},\"片\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"下\":{\"docs\":{},\"载\":{\"docs\":{},\"放\":{\"docs\":{},\"大\":{\"docs\":{},\"了\":{\"docs\":{},\"观\":{\"docs\":{},\"看\":{\"docs\":{},\")\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"看\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"功\":{\"docs\":{},\"能\":{\"docs\":{},\"对\":{\"docs\":{},\"比\":{\"docs\":{},\"：\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"构\":{\"docs\":{},\"造\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"公\":{\"docs\":{},\"共\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"下\":{\"docs\":{},\"层\":{\"docs\":{},\"到\":{\"docs\":{},\"公\":{\"docs\":{},\"共\":{\"docs\":{},\"模\":{\"docs\":{},\"块\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"提\":{\"docs\":{},\"前\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"（\":{\"docs\":{},\"规\":{\"docs\":{},\"避\":{\"7\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"开\":{\"docs\":{},\"始\":{\"docs\":{},\"区\":{\"docs\":{},\"分\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"隔\":{\"docs\":{},\"离\":{\"docs\":{},\"的\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"）\":{\"docs\":{},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"不\":{\"docs\":{},\"能\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"官\":{\"docs\":{},\"方\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"，\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"根\":{\"docs\":{},\"据\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"已\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}},\"参\":{\"docs\":{},\"照\":{\"docs\":{},\"多\":{\"docs\":{},\"个\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"通\":{\"docs\":{},\"信\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"，\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"作\":{\"docs\":{},\"为\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"一\":{\"docs\":{},\"定\":{\"docs\":{},\"层\":{\"docs\":{},\"度\":{\"docs\":{},\"通\":{\"docs\":{},\"信\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"考\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}},\"数\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"找\":{\"docs\":{},\"不\":{\"docs\":{},\"到\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"的\":{\"docs\":{},\"重\":{\"docs\":{},\"用\":{\"docs\":{},\"及\":{\"docs\":{},\"通\":{\"docs\":{},\"信\":{\"docs\":{},\"策\":{\"docs\":{},\"略\":{\"docs\":{},\"延\":{\"docs\":{},\"续\":{\"docs\":{},\"了\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"免\":{\"docs\":{},\"注\":{\"docs\":{},\"册\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"解\":{\"docs\":{},\"决\":{\"docs\":{},\"了\":{\"docs\":{},\"跨\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"下\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"复\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"。\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"将\":{\"docs\":{},\"重\":{\"docs\":{},\"用\":{\"docs\":{},\"类\":{\"docs\":{},\"型\":{\"docs\":{},\"归\":{\"docs\":{},\"为\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"、\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"、\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"三\":{\"docs\":{},\"种\":{\"docs\":{},\"类\":{\"docs\":{},\"型\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"版\":{\"docs\":{},\"本\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"尝\":{\"docs\":{},\"试\":{\"docs\":{},\"获\":{\"docs\":{},\"取\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"并\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"操\":{\"docs\":{},\"作\":{\"docs\":{},\"，\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"应\":{\"docs\":{},\"该\":{\"docs\":{},\"被\":{\"docs\":{},\"当\":{\"docs\":{},\"做\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"而\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"，\":{\"docs\":{},\"与\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"的\":{\"docs\":{},\"通\":{\"docs\":{},\"信\":{\"docs\":{},\"应\":{\"docs\":{},\"该\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"现\":{\"docs\":{},\"在\":{\"docs\":{},\"还\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"选\":{\"docs\":{},\"择\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"间\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"复\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"案\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"看\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"的\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}},\"状\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"与\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"之\":{\"docs\":{},\"间\":{\"docs\":{},\"还\":{\"docs\":{},\"是\":{\"docs\":{},\"保\":{\"docs\":{},\"持\":{\"docs\":{},\"完\":{\"docs\":{},\"整\":{\"docs\":{},\"的\":{\"docs\":{},\"隔\":{\"docs\":{},\"离\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"也\":{\"docs\":{},\"无\":{\"docs\":{},\"法\":{\"docs\":{},\"获\":{\"docs\":{},\"取\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"的\":{\"docs\":{},\"引\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"目\":{\"docs\":{},\"标\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"与\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"通\":{\"docs\":{},\"信\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"也\":{\"docs\":{},\"要\":{\"docs\":{},\"遵\":{\"docs\":{},\"循\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"通\":{\"docs\":{},\"信\":{\"docs\":{},\"机\":{\"docs\":{},\"制\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"前\":{\"docs\":{},\"是\":{\"docs\":{},\"有\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"限\":{\"docs\":{},\"制\":{\"docs\":{},\"。\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"非\":{\"docs\":{},\"得\":{\"docs\":{},\"在\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"建\":{\"docs\":{},\"议\":{\"docs\":{},\"改\":{\"docs\":{},\"为\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"录\":{\"docs\":{},\"名\":{\"docs\":{},\"为\":{\"docs\":{},\"记\":{\"docs\":{},\"录\":{\"docs\":{},\"的\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"1\":{\"docs\":{},\"x\":{\"6\":{\"docs\":{},\"r\":{\"8\":{\"docs\":{},\"i\":{\"docs\":{},\"u\":{\"docs\":{},\"z\":{\"docs\":{},\"s\":{\"9\":{\"0\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\",\":{\"docs\":{},\"c\":{\"docs\":{},\"d\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}},\"docs\":{}},\"docs\":{}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}},\"缺\":{\"docs\":{},\"陷\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}},\"被\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}},\"设\":{\"docs\":{},\"想\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"引\":{\"docs\":{},\"用\":{\"docs\":{},\"了\":{\"5\":{\"docs\":{},\"个\":{\"docs\":{},\"来\":{\"docs\":{},\"自\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"，\":{\"docs\":{},\"那\":{\"docs\":{},\"么\":{\"docs\":{},\"相\":{\"docs\":{},\"当\":{\"docs\":{},\"于\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"内\":{\"docs\":{},\"嵌\":{\"docs\":{},\"了\":{\"5\":{\"docs\":{},\"个\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"e\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"；\":{\"docs\":{},\"那\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"引\":{\"docs\":{},\"用\":{\"docs\":{},\"了\":{\"5\":{\"docs\":{},\"个\":{\"docs\":{},\"来\":{\"docs\":{},\"自\":{\"docs\":{},\"同\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"呢\":{\"docs\":{},\"？\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}},\"置\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"时\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\")\":{\"docs\":{},\"在\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"真\":{\"docs\":{},\"正\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\".\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"了\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}},\"跨\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"重\":{\"docs\":{},\"用\":{\"docs\":{},\"和\":{\"docs\":{},\"通\":{\"docs\":{},\"信\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":10}}}}}}}}}}}}}}}}},\"那\":{\"docs\":{},\"么\":{\"docs\":{},\"在\":{\"docs\":{},\"远\":{\"docs\":{},\"端\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"（\":{\"docs\":{},\"前\":{\"docs\":{},\"面\":{\"docs\":{},\"图\":{\"docs\":{},\"中\":{\"docs\":{},\"未\":{\"docs\":{},\"标\":{\"docs\":{},\"出\":{\"docs\":{},\"）\":{\"docs\":{},\"得\":{\"docs\":{},\"到\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"的\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"并\":{\"docs\":{},\"传\":{\"docs\":{},\"递\":{\"docs\":{},\"相\":{\"docs\":{},\"应\":{\"docs\":{},\"的\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"。\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"现\":{\"docs\":{},\"在\":{\"docs\":{},\"理\":{\"docs\":{},\"想\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"迭\":{\"docs\":{},\"代\":{\"docs\":{},\"的\":{\"docs\":{},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"应\":{\"docs\":{},\"该\":{\"docs\":{},\"是\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"这\":{\"docs\":{},\"种\":{\"docs\":{},\"：\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"在\":{\"docs\":{},\"哪\":{\"docs\":{},\"里\":{\"docs\":{},\"呢\":{\"docs\":{},\"？\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"的\":{\"docs\":{},\"字\":{\"docs\":{},\"段\":{\"docs\":{},\"在\":{\"docs\":{},\"哪\":{\"docs\":{},\"里\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"的\":{\"docs\":{},\"呢\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"反\":{\"docs\":{},\"推\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"来\":{\"docs\":{},\"了\":{\"docs\":{},\"，\":{\"docs\":{},\"有\":{\"docs\":{},\"些\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"是\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"于\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"主\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"中\":{\"docs\":{},\"并\":{\"docs\":{},\"不\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"。\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"不\":{\"docs\":{},\"处\":{\"docs\":{},\"理\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"程\":{\"docs\":{},\"序\":{\"docs\":{},\"会\":{\"docs\":{},\"因\":{\"docs\":{},\"为\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"n\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"崩\":{\"docs\":{},\"溃\":{\"docs\":{},\"。\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"要\":{\"docs\":{},\"先\":{\"docs\":{},\"清\":{\"docs\":{},\"除\":{\"docs\":{},\"掉\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"，\":{\"docs\":{},\"延\":{\"docs\":{},\"迟\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"：\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{\"guide-for-use/bundleCommunicate.html\":{\"ref\":\"guide-for-use/bundleCommunicate.html\",\"tf\":0.0026109660574412533}}}}}}}}}}}}}},\"答\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":10}}}},\"及\":{\"docs\":{},\"时\":{\"docs\":{},\"上\":{\"docs\":{},\"线\":{\"docs\":{},\"新\":{\"docs\":{},\"需\":{\"docs\":{},\"求\":{\"docs\":{},\"，\":{\"docs\":{},\"快\":{\"docs\":{},\"速\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"。\":{\"docs\":{\"update/\":{\"ref\":\"update/\",\"tf\":0.16666666666666666}}}}}}}}}}}}}},\"与\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"z\":{\"docs\":{},\"i\":{\"docs\":{},\"p\":{\"docs\":{},\"包\":{\"docs\":{},\"，\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"来\":{\"docs\":{},\"自\":{\"docs\":{},\"于\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"和\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"包\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"合\":{\"docs\":{},\"并\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"于\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"完\":{\"docs\":{},\"整\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"，\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"后\":{\"docs\":{},\"缀\":{\"docs\":{},\"为\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"格\":{\"docs\":{},\"式\":{\"docs\":{},\"的\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"点\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}},\"改\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"要\":{\"docs\":{},\"看\":{\"docs\":{},\"提\":{\"docs\":{},\"示\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"g\":{\"docs\":{},\"再\":{\"docs\":{},\"查\":{\"docs\":{},\"，\":{\"docs\":{},\"目\":{\"docs\":{},\"前\":{\"docs\":{},\"已\":{\"docs\":{},\"知\":{\"docs\":{},\"的\":{\"docs\":{},\"已\":{\"docs\":{},\"经\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"，\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"是\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"o\":{\"docs\":{},\"w\":{\"docs\":{},\"s\":{\"docs\":{},\"句\":{\"docs\":{},\"柄\":{\"docs\":{},\"没\":{\"docs\":{},\"关\":{\"docs\":{},\"闭\":{\"docs\":{},\"，\":{\"docs\":{},\"导\":{\"docs\":{},\"致\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"中\":{\"docs\":{},\"包\":{\"docs\":{},\"含\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"空\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"失\":{\"docs\":{},\"败\":{\"docs\":{},\"了\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"支\":{\"docs\":{},\"持\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.031914893617021274}}}}},\"了\":{\"docs\":{},\"解\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"策\":{\"docs\":{},\"略\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"，\":{\"docs\":{},\"先\":{\"docs\":{},\"分\":{\"docs\":{},\"别\":{\"docs\":{},\"介\":{\"docs\":{},\"绍\":{\"docs\":{},\"下\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"得\":{\"docs\":{},\"以\":{\"docs\":{},\"成\":{\"docs\":{},\"功\":{\"docs\":{},\"的\":{\"docs\":{},\"技\":{\"docs\":{},\"术\":{\"docs\":{},\"基\":{\"docs\":{},\"础\":{\"docs\":{},\"再\":{\"docs\":{},\"阐\":{\"docs\":{},\"述\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"：\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"会\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"合\":{\"docs\":{},\"并\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"变\":{\"docs\":{},\"更\":{\"docs\":{},\"（\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"中\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"，\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"有\":{\"docs\":{},\"）\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"有\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"新\":{\"docs\":{},\"增\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"了\":{\"docs\":{},\"变\":{\"docs\":{},\"更\":{\"docs\":{},\"（\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"中\":{\"docs\":{},\"有\":{\"docs\":{},\"，\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"有\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"）\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"从\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"中\":{\"docs\":{},\"读\":{\"docs\":{},\"取\":{\"docs\":{},\"放\":{\"docs\":{},\"到\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"包\":{\"docs\":{},\"中\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"打\":{\"docs\":{},\"入\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"而\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"不\":{\"docs\":{},\"会\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}},\"例\":{\"docs\":{},\"如\":{\"docs\":{},\"手\":{\"docs\":{},\"淘\":{\"6\":{\"docs\":{},\".\":{\"2\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"到\":{\"6\":{\"docs\":{},\".\":{\"2\":{\"docs\":{},\".\":{\"1\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"为\":{\"docs\":{},\"：\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}},\"创\":{\"docs\":{},\"建\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}},\"完\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"最\":{\"docs\":{},\"后\":{\"docs\":{},\"一\":{\"docs\":{},\"行\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"回\":{\"docs\":{},\"调\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"的\":{\"docs\":{},\"回\":{\"docs\":{},\"调\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"类\":{\"docs\":{},\"是\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"前\":{\"docs\":{},\"面\":{\"docs\":{},\"容\":{\"docs\":{},\"器\":{\"docs\":{},\"的\":{\"docs\":{},\"技\":{\"docs\":{},\"术\":{\"docs\":{},\"原\":{\"docs\":{},\"理\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"介\":{\"docs\":{},\"绍\":{\"docs\":{},\"了\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"父\":{\"docs\":{},\"子\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"，\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"自\":{\"docs\":{},\"身\":{\"docs\":{},\"负\":{\"docs\":{},\"责\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"类\":{\"docs\":{},\"和\":{\"docs\":{},\"c\":{\"docs\":{},\"库\":{\"docs\":{},\"的\":{\"docs\":{},\"查\":{\"docs\":{},\"找\":{\"docs\":{},\"路\":{\"docs\":{},\"口\":{\"docs\":{},\"；\":{\"docs\":{},\"其\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"技\":{\"docs\":{},\"术\":{\"docs\":{},\"原\":{\"docs\":{},\"理\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":10.011764705882353}}}}}},\"数\":{\"docs\":{},\"据\":{\"docs\":{},\"中\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"看\":{\"docs\":{},\"出\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"关\":{\"docs\":{},\"系\":{\"docs\":{},\"允\":{\"docs\":{},\"许\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"变\":{\"docs\":{},\"更\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"也\":{\"docs\":{},\"有\":{\"docs\":{},\"一\":{\"docs\":{},\"定\":{\"docs\":{},\"的\":{\"docs\":{},\"限\":{\"docs\":{},\"制\":{\"docs\":{},\"，\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"会\":{\"docs\":{},\"在\":{\"docs\":{},\"后\":{\"docs\":{},\"面\":{\"docs\":{},\"单\":{\"docs\":{},\"独\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"说\":{\"docs\":{},\"明\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"普\":{\"docs\":{},\"通\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"为\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}},\"生\":{\"docs\":{},\"效\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}},\"速\":{\"docs\":{},\"度\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"：\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}},\"成\":{\"docs\":{},\"基\":{\"docs\":{},\"线\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}},\"的\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"在\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"记\":{\"docs\":{},\"录\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"关\":{\"docs\":{},\"键\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"段\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"变\":{\"docs\":{},\"更\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"有\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"了\":{\"docs\":{},\"变\":{\"docs\":{},\"更\":{\"docs\":{},\"，\":{\"docs\":{},\"且\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"有\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"，\":{\"docs\":{},\"就\":{\"docs\":{},\"会\":{\"docs\":{},\"在\":{\"docs\":{},\"原\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"分\":{\"docs\":{},\"配\":{\"docs\":{},\"过\":{\"docs\":{},\"去\":{\"docs\":{},\"，\":{\"docs\":{},\"同\":{\"docs\":{},\"时\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"打\":{\"docs\":{},\"入\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"包\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"文\":{\"docs\":{},\"本\":{\"docs\":{},\"写\":{\"docs\":{},\"入\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"c\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"是\":{\"docs\":{},\"新\":{\"docs\":{},\"增\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"预\":{\"docs\":{},\"留\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"段\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"分\":{\"docs\":{},\"配\":{\"docs\":{},\"。\":{\"docs\":{},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"如\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"所\":{\"docs\":{},\"示\":{\"docs\":{},\"：\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"关\":{\"docs\":{},\"系\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"能\":{\"docs\":{},\"力\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"，\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}},\"，\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"变\":{\"docs\":{},\"化\":{\"docs\":{},\"和\":{\"docs\":{},\"改\":{\"docs\":{},\"动\":{\"docs\":{},\"一\":{\"docs\":{},\"致\":{\"docs\":{},\"，\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}},\"区\":{\"docs\":{},\"别\":{\"docs\":{},\"之\":{\"docs\":{},\"一\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"项\":{\"docs\":{},\"，\":{\"docs\":{},\"表\":{\"docs\":{},\"示\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"，\":{\"docs\":{},\"即\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"是\":{\"docs\":{},\"由\":{\"docs\":{},\"这\":{\"docs\":{},\"些\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"共\":{\"docs\":{},\"同\":{\"docs\":{},\"组\":{\"docs\":{},\"成\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"呢\":{\"docs\":{},\"？\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"经\":{\"docs\":{},\"过\":{\"docs\":{},\"手\":{\"docs\":{},\"淘\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"以\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"主\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"f\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"都\":{\"docs\":{},\"插\":{\"docs\":{},\"入\":{\"docs\":{},\"了\":{\"docs\":{},\"一\":{\"docs\":{},\"段\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"：\":{\"docs\":{},\"类\":{\"docs\":{},\"似\":{\"docs\":{},\"下\":{\"docs\":{},\"图\":{\"docs\":{},\"。\":{\"docs\":{},\"原\":{\"docs\":{},\"因\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"会\":{\"docs\":{},\"有\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"所\":{\"docs\":{},\"引\":{\"docs\":{},\"用\":{\"docs\":{},\"到\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"均\":{\"docs\":{},\"和\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"自\":{\"docs\":{},\"己\":{\"docs\":{},\"在\":{\"docs\":{},\"同\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"会\":{\"docs\":{},\"被\":{\"docs\":{},\"打\":{\"docs\":{},\"上\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"标\":{\"docs\":{},\"记\":{\"docs\":{},\"。\":{\"docs\":{},\"然\":{\"docs\":{},\"后\":{\"docs\":{},\"在\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"期\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"打\":{\"docs\":{},\"上\":{\"docs\":{},\"这\":{\"docs\":{},\"个\":{\"docs\":{},\"标\":{\"docs\":{},\"记\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"载\":{\"docs\":{},\"入\":{\"docs\":{},\"时\":{\"docs\":{},\"不\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"经\":{\"docs\":{},\"过\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\"已\":{\"docs\":{},\"提\":{\"docs\":{},\"高\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"效\":{\"docs\":{},\"率\":{\"docs\":{},\"，\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"到\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"时\":{\"docs\":{},\"会\":{\"docs\":{},\"校\":{\"docs\":{},\"验\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"是\":{\"docs\":{},\"否\":{\"docs\":{},\"跟\":{\"docs\":{},\"构\":{\"docs\":{},\"建\":{\"docs\":{},\"时\":{\"docs\":{},\"一\":{\"docs\":{},\"致\":{\"docs\":{},\"和\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"自\":{\"docs\":{},\"身\":{\"docs\":{},\"处\":{\"docs\":{},\"于\":{\"docs\":{},\"同\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"不\":{\"docs\":{},\"一\":{\"docs\":{},\"致\":{\"docs\":{},\"则\":{\"docs\":{},\"会\":{\"docs\":{},\"抛\":{\"docs\":{},\"出\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"错\":{\"docs\":{},\"误\":{\"docs\":{},\"。\":{\"docs\":{},\"而\":{\"docs\":{},\"手\":{\"docs\":{},\"淘\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"策\":{\"docs\":{},\"略\":{\"docs\":{},\"必\":{\"docs\":{},\"然\":{\"docs\":{},\"会\":{\"docs\":{},\"新\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"，\":{\"docs\":{},\"那\":{\"docs\":{},\"么\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"遇\":{\"docs\":{},\"到\":{\"docs\":{},\"是\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"就\":{\"docs\":{},\"会\":{\"docs\":{},\"出\":{\"docs\":{},\"错\":{\"docs\":{},\"。\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"目\":{\"docs\":{},\"前\":{\"docs\":{},\"手\":{\"docs\":{},\"淘\":{\"docs\":{},\"的\":{\"docs\":{},\"策\":{\"docs\":{},\"略\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"期\":{\"docs\":{},\"给\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"引\":{\"docs\":{},\"用\":{\"docs\":{},\"到\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"不\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"以\":{\"docs\":{},\"解\":{\"docs\":{},\"除\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"限\":{\"docs\":{},\"制\":{\"docs\":{},\"（\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"校\":{\"docs\":{},\"验\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"阅\":{\"docs\":{},\"读\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"源\":{\"docs\":{},\"码\":{\"docs\":{},\"）\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"常\":{\"docs\":{},\"有\":{\"docs\":{},\"同\":{\"docs\":{},\"学\":{\"docs\":{},\"在\":{\"docs\":{},\"答\":{\"docs\":{},\"疑\":{\"docs\":{},\"群\":{\"docs\":{},\"上\":{\"docs\":{},\"提\":{\"docs\":{},\"出\":{\"docs\":{},\"疑\":{\"docs\":{},\"问\":{\"docs\":{},\"为\":{\"docs\":{},\"什\":{\"docs\":{},\"么\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"不\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"？\":{\"docs\":{},\"，\":{\"docs\":{},\"然\":{\"docs\":{},\"后\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"通\":{\"docs\":{},\"排\":{\"docs\":{},\"查\":{\"docs\":{},\"。\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"是\":{\"docs\":{},\"远\":{\"docs\":{},\"程\":{\"docs\":{},\"交\":{\"docs\":{},\"流\":{\"docs\":{},\"，\":{\"docs\":{},\"代\":{\"docs\":{},\"价\":{\"docs\":{},\"实\":{\"docs\":{},\"在\":{\"docs\":{},\"是\":{\"docs\":{},\"太\":{\"docs\":{},\"高\":{\"docs\":{},\"。\":{\"docs\":{},\"这\":{\"docs\":{},\"篇\":{\"docs\":{},\"文\":{\"docs\":{},\"章\":{\"docs\":{},\"主\":{\"docs\":{},\"要\":{\"docs\":{},\"是\":{\"docs\":{},\"和\":{\"docs\":{},\"大\":{\"docs\":{},\"家\":{\"docs\":{},\"分\":{\"docs\":{},\"享\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"排\":{\"docs\":{},\"查\":{\"docs\":{},\"的\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"经\":{\"docs\":{},\"验\":{\"docs\":{},\"，\":{\"docs\":{},\"希\":{\"docs\":{},\"望\":{\"docs\":{},\"能\":{\"docs\":{},\"够\":{\"docs\":{},\"帮\":{\"docs\":{},\"助\":{\"docs\":{},\"大\":{\"docs\":{},\"家\":{\"docs\":{},\"快\":{\"docs\":{},\"速\":{\"docs\":{},\"定\":{\"docs\":{},\"位\":{\"docs\":{},\"、\":{\"docs\":{},\"解\":{\"docs\":{},\"决\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"获\":{\"docs\":{},\"取\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"数\":{\"docs\":{},\"据\":{\"docs\":{},\"源\":{\"docs\":{},\"：\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"来\":{\"docs\":{},\"自\":{\"docs\":{},\"于\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"在\":{\"docs\":{},\"下\":{\"docs\":{},\"载\":{\"docs\":{},\"的\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"包\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"，\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"来\":{\"docs\":{},\"自\":{\"docs\":{},\"于\":{\"docs\":{},\"当\":{\"docs\":{},\"前\":{\"docs\":{},\"设\":{\"docs\":{},\"备\":{\"docs\":{},\"的\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"来\":{\"docs\":{},\"自\":{\"docs\":{},\"于\":{\"docs\":{},\"已\":{\"docs\":{},\"经\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"过\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"（\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"）\":{\"docs\":{},\"，\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"还\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"（\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"下\":{\"docs\":{},\"）\":{\"docs\":{\"update/principle.html\":{\"ref\":\"update/principle.html\",\"tf\":0.011764705882352941}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"什\":{\"docs\":{},\"么\":{\"docs\":{},\"是\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}},\"情\":{\"docs\":{},\"况\":{\"docs\":{},\"，\":{\"docs\":{},\"怎\":{\"docs\":{},\"么\":{\"docs\":{},\"什\":{\"docs\":{},\"么\":{\"docs\":{},\"都\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"?\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"写\":{\"docs\":{},\"入\":{\"docs\":{},\"又\":{\"docs\":{},\"是\":{\"docs\":{},\"在\":{\"docs\":{},\"哪\":{\"docs\":{},\"里\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}},\"优\":{\"docs\":{},\"势\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}},\"回\":{\"docs\":{},\"顾\":{\"docs\":{},\"手\":{\"docs\":{},\"淘\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"的\":{\"docs\":{},\"一\":{\"docs\":{},\"些\":{\"docs\":{},\"故\":{\"docs\":{},\"障\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"的\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"管\":{\"docs\":{},\"是\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"还\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"x\":{\"docs\":{},\"，\":{\"docs\":{},\"其\":{\"docs\":{},\"实\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"发\":{\"docs\":{},\"现\":{\"docs\":{},\"几\":{\"docs\":{},\"乎\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"故\":{\"docs\":{},\"障\":{\"docs\":{},\"都\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"就\":{\"docs\":{},\"行\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"降\":{\"docs\":{},\"级\":{\"docs\":{},\"，\":{\"docs\":{},\"也\":{\"docs\":{},\"基\":{\"docs\":{},\"本\":{\"docs\":{},\"都\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"在\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"模\":{\"docs\":{},\"块\":{\"docs\":{},\"内\":{\"docs\":{},\"的\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"就\":{\"docs\":{},\"把\":{\"docs\":{},\"某\":{\"docs\":{},\"个\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"的\":{\"docs\":{},\"故\":{\"docs\":{},\"障\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"掉\":{\"docs\":{},\"。\":{\"docs\":{},\"因\":{\"docs\":{},\"此\":{\"docs\":{},\"，\":{\"docs\":{},\"以\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"的\":{\"docs\":{},\"技\":{\"docs\":{},\"术\":{\"docs\":{},\"作\":{\"docs\":{},\"为\":{\"docs\":{},\"基\":{\"docs\":{},\"础\":{\"docs\":{},\"，\":{\"docs\":{},\"称\":{\"docs\":{},\"之\":{\"docs\":{},\"为\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"案\":{\"docs\":{},\"应\":{\"docs\":{},\"运\":{\"docs\":{},\"而\":{\"docs\":{},\"生\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"第\":{\"docs\":{},\"二\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"的\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"时\":{\"docs\":{},\"序\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}},\"滚\":{\"docs\":{},\"标\":{\"docs\":{},\"志\":{\"docs\":{},\"，\":{\"docs\":{},\"该\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"会\":{\"docs\":{},\"回\":{\"docs\":{},\"滚\":{\"docs\":{},\"到\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"前\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"调\":{\"docs\":{},\"预\":{\"docs\":{},\"留\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.005758157389635317}}}}}}},\"过\":{\"docs\":{},\"头\":{\"docs\":{},\"来\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"看\":{\"docs\":{},\"看\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"上\":{\"docs\":{},\"述\":{\"docs\":{},\"目\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"做\":{\"docs\":{},\"了\":{\"docs\":{},\"哪\":{\"docs\":{},\"些\":{\"docs\":{},\"准\":{\"docs\":{},\"备\":{\"docs\":{},\"工\":{\"docs\":{},\"作\":{\"docs\":{},\"。\":{\"docs\":{},\"在\":{\"docs\":{},\"跟\":{\"docs\":{},\"进\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"y\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"的\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"，\":{\"docs\":{},\"先\":{\"docs\":{},\"看\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"s\":{\"docs\":{},\"类\":{\"docs\":{},\"中\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"的\":{\"docs\":{},\"字\":{\"docs\":{},\"段\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"到\":{\"docs\":{},\"第\":{\"1\":{\"0\":{\"docs\":{},\"步\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"docs\":{}},\"docs\":{}}}},\"因\":{\"docs\":{},\"为\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"升\":{\"docs\":{},\"级\":{\"docs\":{},\"的\":{\"docs\":{},\"替\":{\"docs\":{},\"代\":{\"docs\":{},\"方\":{\"docs\":{},\"案\":{\"docs\":{},\"，\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"式\":{\"docs\":{},\"就\":{\"docs\":{},\"使\":{\"docs\":{},\"得\":{\"docs\":{},\"是\":{\"docs\":{},\"否\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"是\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"还\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"升\":{\"docs\":{},\"级\":{\"docs\":{},\"对\":{\"docs\":{},\"业\":{\"docs\":{},\"务\":{\"docs\":{},\"来\":{\"docs\":{},\"说\":{\"docs\":{},\"完\":{\"docs\":{},\"全\":{\"docs\":{},\"透\":{\"docs\":{},\"明\":{\"docs\":{},\"，\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"继\":{\"docs\":{},\"续\":{\"docs\":{},\"按\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{},\"处\":{\"docs\":{},\"理\":{\"docs\":{},\"，\":{\"docs\":{},\"降\":{\"docs\":{},\"级\":{\"docs\":{},\"等\":{\"docs\":{},\"。\":{\"docs\":{},\"数\":{\"docs\":{},\"据\":{\"docs\":{},\"统\":{\"docs\":{},\"计\":{\"docs\":{},\"以\":{\"docs\":{},\"及\":{\"docs\":{},\"监\":{\"docs\":{},\"控\":{\"docs\":{},\"等\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"完\":{\"docs\":{},\"全\":{\"docs\":{},\"兼\":{\"docs\":{},\"容\":{\"docs\":{},\"。\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"在\":{\"docs\":{},\"故\":{\"docs\":{},\"障\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"中\":{\"docs\":{},\"去\":{\"docs\":{},\"贸\":{\"docs\":{},\"然\":{\"docs\":{},\"升\":{\"docs\":{},\"级\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"号\":{\"docs\":{},\"，\":{\"docs\":{},\"虽\":{\"docs\":{},\"然\":{\"docs\":{},\"直\":{\"docs\":{},\"观\":{\"docs\":{},\"上\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"清\":{\"docs\":{},\"楚\":{\"docs\":{},\"看\":{\"docs\":{},\"到\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"的\":{\"docs\":{},\"覆\":{\"docs\":{},\"盖\":{\"docs\":{},\"率\":{\"docs\":{},\"，\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"优\":{\"docs\":{},\"势\":{\"docs\":{},\"就\":{\"docs\":{},\"荡\":{\"docs\":{},\"然\":{\"docs\":{},\"无\":{\"docs\":{},\"存\":{\"docs\":{},\"了\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}},\"正\":{\"docs\":{},\"是\":{\"docs\":{},\"因\":{\"docs\":{},\"为\":{\"docs\":{},\"其\":{\"docs\":{},\"比\":{\"docs\":{},\"较\":{\"docs\":{},\"全\":{\"docs\":{},\"面\":{\"docs\":{},\"的\":{\"docs\":{},\"能\":{\"docs\":{},\"力\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"发\":{\"docs\":{},\"现\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"在\":{\"docs\":{},\"故\":{\"docs\":{},\"障\":{\"docs\":{},\"修\":{\"docs\":{},\"复\":{\"docs\":{},\"方\":{\"docs\":{},\"面\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"其\":{\"docs\":{},\"不\":{\"docs\":{},\"足\":{\"docs\":{},\"的\":{\"docs\":{},\"地\":{\"docs\":{},\"方\":{\"docs\":{},\"：\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"版\":{\"docs\":{},\"本\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.012422360248447204}},\"号\":{\"docs\":{},\"：\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}}},\"限\":{\"docs\":{},\"制\":{\"docs\":{},\"：\":{\"docs\":{\"update/dexpatch.html\":{\"ref\":\"update/dexpatch.html\",\"tf\":0.03571428571428571}}}}},\"+\":{\"1\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}},\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"=\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}},\"s\":{\"docs\":{},\"y\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\".\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"(\":{\"docs\":{},\"\\\"\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\".\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\".\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"\\\"\":{\"docs\":{},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"]\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602},\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}},\",\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.012422360248447204},\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.016216216216216217}}}},\"x\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.012422360248447204},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}},\"x\":{\"docs\":{},\"x\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.01694915254237288},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"中\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"s\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"和\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"不\":{\"docs\":{},\"一\":{\"docs\":{},\"样\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"某\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"s\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"和\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"一\":{\"docs\":{},\"样\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"一\":{\"docs\":{},\"般\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.012422360248447204}},\"来\":{\"docs\":{},\"说\":{\"docs\":{},\"，\":{\"docs\":{},\"由\":{\"docs\":{},\"于\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"设\":{\"docs\":{},\"备\":{\"docs\":{},\"警\":{\"docs\":{},\"告\":{\"docs\":{},\"的\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"报\":{\"docs\":{},\"在\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"2\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"往\":{\"docs\":{},\"往\":{\"docs\":{},\"与\":{\"docs\":{},\"发\":{\"docs\":{},\"生\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"时\":{\"docs\":{},\"的\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"相\":{\"docs\":{},\"隔\":{\"docs\":{},\"比\":{\"docs\":{},\"较\":{\"docs\":{},\"远\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"通\":{\"docs\":{},\"常\":{\"docs\":{},\"遇\":{\"docs\":{},\"到\":{\"docs\":{},\"该\":{\"docs\":{},\"类\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"，\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"设\":{\"docs\":{},\"备\":{\"docs\":{},\"拿\":{\"docs\":{},\"来\":{\"docs\":{},\"排\":{\"docs\":{},\"查\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"更\":{\"docs\":{},\"能\":{\"docs\":{},\"发\":{\"docs\":{},\"现\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"的\":{\"docs\":{},\"原\":{\"docs\":{},\"因\":{\"docs\":{},\"。\":{\"docs\":{},\"另\":{\"docs\":{},\"外\":{\"docs\":{},\"n\":{\"docs\":{},\"o\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"造\":{\"docs\":{},\"成\":{\"docs\":{},\"的\":{\"docs\":{},\"原\":{\"docs\":{},\"有\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"类\":{\"docs\":{},\"找\":{\"docs\":{},\"不\":{\"docs\":{},\"到\":{\"docs\":{},\"，\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"丢\":{\"docs\":{},\"失\":{\"docs\":{},\"，\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{},\"不\":{\"docs\":{},\"匹\":{\"docs\":{},\"配\":{\"docs\":{},\"，\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"属\":{\"docs\":{},\"性\":{\"docs\":{},\"变\":{\"docs\":{},\"更\":{\"docs\":{},\"，\":{\"docs\":{},\"混\":{\"docs\":{},\"淆\":{\"docs\":{},\"等\":{\"docs\":{},\"，\":{\"docs\":{},\"所\":{\"docs\":{},\"以\":{\"docs\":{},\"具\":{\"docs\":{},\"体\":{\"docs\":{},\"原\":{\"docs\":{},\"因\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"利\":{\"docs\":{},\"用\":{\"docs\":{},\"上\":{\"docs\":{},\"述\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"g\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"并\":{\"docs\":{},\"对\":{\"docs\":{},\"照\":{\"docs\":{},\"反\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"去\":{\"docs\":{},\"排\":{\"docs\":{},\"查\":{\"docs\":{},\"根\":{\"docs\":{},\"本\":{\"docs\":{},\"的\":{\"docs\":{},\"原\":{\"docs\":{},\"因\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}},\"些\":{\"docs\":{},\"限\":{\"docs\":{},\"制\":{\"docs\":{\"update/guide.html\":{\"ref\":\"update/guide.html\",\"tf\":10}}}}},\"个\":{\"docs\":{},\"是\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"源\":{\"docs\":{},\"码\":{\"docs\":{},\"项\":{\"docs\":{},\"目\":{\"docs\":{},\"，\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"是\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"仓\":{\"docs\":{},\"库\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{},\"前\":{\"docs\":{},\"期\":{\"docs\":{},\"研\":{\"docs\":{},\"究\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"基\":{\"docs\":{},\"于\":{\"docs\":{},\"源\":{\"docs\":{},\"码\":{\"docs\":{},\"来\":{\"docs\":{},\"，\":{\"docs\":{},\"后\":{\"docs\":{},\"续\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"化\":{\"docs\":{},\"实\":{\"docs\":{},\"践\":{\"docs\":{},\"推\":{\"docs\":{},\"荐\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"后\":{\"docs\":{},\"者\":{\"docs\":{},\"，\":{\"docs\":{},\"手\":{\"docs\":{},\"淘\":{\"docs\":{},\"内\":{\"docs\":{},\"部\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"后\":{\"docs\":{},\"者\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"说\":{\"docs\":{},\"明\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}},\"依\":{\"docs\":{},\"赖\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"方\":{\"docs\":{},\"式\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}},\"管\":{\"docs\":{},\"理\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"，\":{\"docs\":{},\"将\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"改\":{\"docs\":{},\"为\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"范\":{\"docs\":{},\"围\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}},\"引\":{\"docs\":{},\"入\":{\"docs\":{},\"了\":{\"docs\":{},\"其\":{\"docs\":{},\"它\":{\"docs\":{},\"隐\":{\"docs\":{},\"含\":{\"docs\":{},\"的\":{\"docs\":{},\"改\":{\"docs\":{},\"动\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}},\"区\":{\"docs\":{},\"分\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"是\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"还\":{\"docs\":{},\"是\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}},\"发\":{\"docs\":{},\"布\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"到\":{\"docs\":{},\"仓\":{\"docs\":{},\"库\":{\"docs\":{},\"中\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}},\"版\":{\"docs\":{},\"本\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}},\"各\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"随\":{\"docs\":{},\"时\":{\"docs\":{},\"下\":{\"docs\":{},\"发\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}},\"位\":{\"docs\":{},\"，\":{\"docs\":{},\"有\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"灵\":{\"docs\":{},\"光\":{\"docs\":{},\"一\":{\"docs\":{},\"闪\":{\"docs\":{},\"？\":{\"docs\":{},\"是\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"和\":{\"docs\":{},\"s\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"是\":{\"docs\":{},\"有\":{\"docs\":{},\"联\":{\"docs\":{},\"系\":{\"docs\":{},\"的\":{\"docs\":{},\"，\":{\"docs\":{},\"客\":{\"docs\":{},\"户\":{\"docs\":{},\"端\":{\"docs\":{},\"用\":{\"docs\":{},\"来\":{\"docs\":{},\"验\":{\"docs\":{},\"证\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"的\":{\"docs\":{},\"合\":{\"docs\":{},\"法\":{\"docs\":{},\"性\":{\"docs\":{},\"，\":{\"docs\":{},\"看\":{\"docs\":{},\"图\":{\"docs\":{},\":\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"场\":{\"docs\":{},\"景\":{\"docs\":{},\"定\":{\"docs\":{},\"位\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}},\"字\":{\"docs\":{},\"段\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"解\":{\"docs\":{},\"释\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}},\"是\":{\"docs\":{},\"一\":{\"docs\":{},\"堆\":{\"docs\":{},\"j\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"字\":{\"docs\":{},\"段\":{\"docs\":{},\"，\":{\"docs\":{},\"解\":{\"docs\":{},\"析\":{\"docs\":{},\"后\":{\"docs\":{},\"格\":{\"docs\":{},\"式\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\",\":{\"docs\":{},\"保\":{\"docs\":{},\"存\":{\"docs\":{},\"着\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"客\":{\"docs\":{},\"户\":{\"docs\":{},\"端\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"识\":{\"docs\":{},\"别\":{\"docs\":{},\"的\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"，\":{\"docs\":{},\"对\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"包\":{\"docs\":{},\"装\":{\"docs\":{},\"处\":{\"docs\":{},\"理\":{\"docs\":{},\"过\":{\"docs\":{},\"的\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}},\"并\":{\"docs\":{},\"不\":{\"docs\":{},\"能\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"识\":{\"docs\":{},\"别\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"产\":{\"docs\":{},\"生\":{\"docs\":{},\"的\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}},\"拿\":{\"docs\":{},\"什\":{\"docs\":{},\"么\":{\"docs\":{},\"属\":{\"docs\":{},\"性\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}},\"检\":{\"docs\":{},\"查\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}},\"当\":{\"docs\":{},\"前\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"和\":{\"docs\":{},\"参\":{\"docs\":{},\"考\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"(\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\")\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"的\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"，\":{\"docs\":{},\"是\":{\"docs\":{},\"个\":{\"docs\":{},\"z\":{\"docs\":{},\"i\":{\"docs\":{},\"p\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"解\":{\"docs\":{},\"压\":{\"docs\":{},\"开\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"。\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"下\":{\"docs\":{},\"的\":{\"docs\":{},\"实\":{\"docs\":{},\"践\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}},\"的\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"度\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}},\"然\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"条\":{\"docs\":{},\"件\":{\"docs\":{},\"都\":{\"docs\":{},\"满\":{\"docs\":{},\"足\":{\"docs\":{},\"时\":{\"docs\":{},\"，\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"安\":{\"docs\":{},\"装\":{\"docs\":{},\"和\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"操\":{\"docs\":{},\"作\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"快\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}},\"速\":{\"docs\":{},\"排\":{\"docs\":{},\"查\":{\"docs\":{},\"三\":{\"docs\":{},\"连\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}},\"指\":{\"docs\":{},\"定\":{\"docs\":{},\"参\":{\"docs\":{},\"照\":{\"docs\":{},\"的\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"，\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"包\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}}}}}}}}},\"第\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"完\":{\"docs\":{},\"毕\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"会\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"远\":{\"docs\":{},\"程\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"自\":{\"docs\":{},\"身\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"的\":{\"docs\":{},\"路\":{\"docs\":{},\"径\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"所\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"的\":{\"docs\":{},\"路\":{\"docs\":{},\"径\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}},\"向\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"改\":{\"docs\":{},\"动\":{\"docs\":{},\"模\":{\"docs\":{},\"块\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}},\"了\":{\"docs\":{},\"几\":{\"docs\":{},\"个\":{\"docs\":{},\"类\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"就\":{\"docs\":{},\"会\":{\"docs\":{},\"对\":{\"docs\":{},\"应\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"出\":{\"docs\":{},\"几\":{\"docs\":{},\"个\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"会\":{\"docs\":{},\"多\":{\"docs\":{},\"也\":{\"docs\":{},\"不\":{\"docs\":{},\"会\":{\"docs\":{},\"少\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"比\":{\"docs\":{},\"对\":{\"docs\":{},\"版\":{\"docs\":{},\"本\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}},\"如\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"了\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}},\"在\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"中\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"，\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"、\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"、\":{\"docs\":{},\"p\":{\"docs\":{},\"u\":{\"docs\":{},\"b\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"了\":{\"docs\":{},\"以\":{\"docs\":{},\"下\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"设\":{\"docs\":{},\"置\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}},\"清\":{\"docs\":{},\"空\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}},\"灵\":{\"docs\":{},\"活\":{\"docs\":{},\"度\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}},\"详\":{\"docs\":{},\"细\":{\"docs\":{},\"介\":{\"docs\":{},\"绍\":{\"docs\":{},\"参\":{\"docs\":{},\"照\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}},\"进\":{\"docs\":{},\"入\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"目\":{\"docs\":{},\"录\":{\"docs\":{},\"下\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}},\"去\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}},\"分\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"重\":{\"docs\":{},\"启\":{\"docs\":{},\"应\":{\"docs\":{},\"用\":{\"docs\":{},\",\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"显\":{\"docs\":{},\"示\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}}}}}}}}}},\"前\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}},\"后\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}},\"集\":{\"docs\":{},\"成\":{\"docs\":{},\"升\":{\"docs\":{},\"级\":{\"docs\":{\"update/dexpatch_use_guide.html\":{\"ref\":\"update/dexpatch_use_guide.html\",\"tf\":0.006211180124223602}}}},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"后\":{\"docs\":{},\"就\":{\"docs\":{},\"只\":{\"docs\":{},\"有\":{\"docs\":{},\"u\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}},\"已\":{\"docs\":{},\"有\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"暂\":{\"docs\":{},\"时\":{\"docs\":{},\"不\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"更\":{\"docs\":{},\"改\":{\"docs\":{\"update/guide.html\":{\"ref\":\"update/guide.html\",\"tf\":0.2}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"k\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"y\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}},\",\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"q\":{\"1\":{\"0\":{\"docs\":{},\".\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"1\":{\"docs\":{},\".\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"2\":{\"docs\":{},\".\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"3\":{\"docs\":{},\".\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"4\":{\"docs\":{},\".\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"5\":{\"docs\":{},\".\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"6\":{\"docs\":{},\".\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"7\":{\"docs\":{},\".\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"8\":{\"docs\":{},\".\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"9\":{\"docs\":{},\".\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"docs\":{},\":\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"2\":{\"0\":{\"docs\":{},\".\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"docs\":{},\":\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"3\":{\"docs\":{},\":\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"4\":{\"docs\":{},\":\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"5\":{\"docs\":{},\":\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"6\":{\"docs\":{},\":\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"7\":{\"docs\":{},\":\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"8\":{\"docs\":{},\":\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"9\":{\"docs\":{},\".\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}},\"docs\":{}},\"关\":{\"docs\":{},\"于\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"类\":{\"docs\":{},\"，\":{\"docs\":{},\"它\":{\"docs\":{},\"什\":{\"docs\":{},\"么\":{\"docs\":{},\"时\":{\"docs\":{},\"候\":{\"docs\":{},\"被\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"其\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"自\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"怎\":{\"docs\":{},\"么\":{\"docs\":{},\"在\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"？\":{\"docs\":{},\"在\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"，\":{\"docs\":{},\"得\":{\"docs\":{},\"到\":{\"docs\":{},\"的\":{\"docs\":{},\"是\":{\"docs\":{},\"主\":{\"docs\":{},\"应\":{\"docs\":{},\"用\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"第\":{\"docs\":{},\"三\":{\"docs\":{},\"个\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"以\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"为\":{\"docs\":{},\"例\":{\"docs\":{},\"，\":{\"docs\":{},\"详\":{\"docs\":{},\"细\":{\"docs\":{},\"说\":{\"docs\":{},\"明\":{\"docs\":{},\"。\":{\"docs\":{},\"首\":{\"docs\":{},\"先\":{\"docs\":{},\"，\":{\"docs\":{},\"看\":{\"docs\":{},\"下\":{\"docs\":{},\"在\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"闭\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"正\":{\"docs\":{},\"常\":{\"docs\":{},\"工\":{\"docs\":{},\"作\":{\"docs\":{},\"。\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"正\":{\"docs\":{},\"在\":{\"docs\":{},\"开\":{\"docs\":{},\"发\":{\"docs\":{},\"中\":{\"docs\":{},\"。\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"掉\":{\"docs\":{},\"a\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}},\"导\":{\"docs\":{},\"入\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}},\"属\":{\"docs\":{},\"性\":{\"docs\":{},\"开\":{\"docs\":{},\"关\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\".\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"u\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"m\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"杀\":{\"docs\":{},\"掉\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\".\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"e\":{\"docs\":{},\"进\":{\"docs\":{},\"程\":{\"docs\":{},\"重\":{\"docs\":{},\"新\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"（\":{\"docs\":{},\"w\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"o\":{\"docs\":{},\"w\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}},\"混\":{\"docs\":{},\"淆\":{\"docs\":{},\"后\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"进\":{\"docs\":{},\"度\":{\"docs\":{},\"条\":{\"docs\":{},\"消\":{\"docs\":{},\"失\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"进\":{\"docs\":{},\"程\":{\"docs\":{},\"出\":{\"docs\":{},\"现\":{\"docs\":{},\"）\":{\"docs\":{},\"c\":{\"docs\":{},\"m\":{\"docs\":{},\"d\":{\"docs\":{},\":\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"k\":{\"docs\":{},\"k\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"中\":{\"docs\":{},\"有\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"包\":{\"docs\":{},\"和\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"w\":{\"docs\":{},\"b\":{\"docs\":{},\"的\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"中\":{\"docs\":{},\"也\":{\"docs\":{},\"有\":{\"docs\":{},\"，\":{\"docs\":{},\"为\":{\"docs\":{},\"什\":{\"docs\":{},\"么\":{\"docs\":{},\"在\":{\"docs\":{},\"宿\":{\"docs\":{},\"主\":{\"docs\":{},\"中\":{\"docs\":{},\"生\":{\"docs\":{},\"成\":{\"docs\":{},\"的\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"解\":{\"docs\":{},\"压\":{\"docs\":{},\"就\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"了\":{\"docs\":{},\"呢\":{\"docs\":{},\"？\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"化\":{\"docs\":{},\"和\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"化\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}},\"规\":{\"docs\":{},\"则\":{\"docs\":{},\"少\":{\"docs\":{},\"了\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}},\"跟\":{\"docs\":{},\"服\":{\"docs\":{},\"务\":{\"docs\":{},\"器\":{\"docs\":{},\"比\":{\"docs\":{},\"对\":{\"docs\":{},\"获\":{\"docs\":{},\"取\":{\"docs\":{},\"补\":{\"docs\":{},\"丁\":{\"docs\":{},\"？\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693}}}}}}}}}}}}},\"：\":{\"docs\":{\"faq/question.html\":{\"ref\":\"faq/question.html\",\"tf\":0.007692307692307693},\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"预\":{\"docs\":{},\"先\":{\"docs\":{},\"在\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"中\":{\"docs\":{},\"预\":{\"docs\":{},\"留\":{\"docs\":{},\"n\":{\"docs\":{},\"个\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"坑\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"时\":{\"docs\":{},\"，\":{\"docs\":{},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"“\":{\"docs\":{},\"借\":{\"docs\":{},\"尸\":{\"docs\":{},\"还\":{\"docs\":{},\"魂\":{\"docs\":{},\"”\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"四\":{\"docs\":{},\"大\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"的\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"常\":{\"docs\":{},\"见\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}},\"规\":{\"docs\":{},\"的\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"，\":{\"docs\":{},\"会\":{\"docs\":{},\"将\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"打\":{\"docs\":{},\"入\":{\"docs\":{},\"到\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"中\":{\"docs\":{},\"去\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"产\":{\"docs\":{},\"生\":{\"docs\":{},\"的\":{\"docs\":{},\"清\":{\"docs\":{},\"单\":{\"docs\":{},\"数\":{\"docs\":{},\"据\":{\"docs\":{},\"，\":{\"docs\":{},\"包\":{\"docs\":{},\"括\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"自\":{\"docs\":{},\"身\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"和\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"故\":{\"docs\":{},\"障\":{\"docs\":{},\"排\":{\"docs\":{},\"查\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":10}}}}}},\"膨\":{\"docs\":{},\"化\":{\"docs\":{},\"x\":{\"docs\":{},\"m\":{\"docs\":{},\"l\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"x\":{\"docs\":{},\"m\":{\"docs\":{},\"l\":{\"docs\":{},\"里\":{\"docs\":{},\"面\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"有\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"务\":{\"docs\":{},\"必\":{\"docs\":{},\"确\":{\"docs\":{},\"保\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"y\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"持\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"到\":{\"docs\":{},\"该\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"，\":{\"docs\":{},\"假\":{\"docs\":{},\"设\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"来\":{\"docs\":{},\"自\":{\"docs\":{},\"于\":{\"docs\":{},\"a\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"造\":{\"docs\":{},\"成\":{\"docs\":{},\"该\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{},\"的\":{\"docs\":{},\"原\":{\"docs\":{},\"因\":{\"docs\":{},\"比\":{\"docs\":{},\"较\":{\"docs\":{},\"多\":{\"docs\":{},\"，\":{\"docs\":{},\"排\":{\"docs\":{},\"查\":{\"docs\":{},\"步\":{\"docs\":{},\"骤\":{\"docs\":{},\"第\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"先\":{\"docs\":{},\"检\":{\"docs\":{},\"查\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"源\":{\"docs\":{},\"头\":{\"docs\":{},\"是\":{\"docs\":{},\"不\":{\"docs\":{},\"是\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"n\":{\"docs\":{},\"o\":{\"docs\":{},\"t\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"，\":{\"docs\":{},\"然\":{\"docs\":{},\"后\":{\"docs\":{},\"反\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"排\":{\"docs\":{},\"查\":{\"docs\":{},\"类\":{\"docs\":{},\"确\":{\"docs\":{},\"实\":{\"docs\":{},\"是\":{\"docs\":{},\"否\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{},\"；\":{\"docs\":{\"faq/help.html\":{\"ref\":\"faq/help.html\",\"tf\":0.04}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"原\":{\"docs\":{},\"生\":{\"docs\":{},\"是\":{\"docs\":{},\"支\":{\"docs\":{},\"持\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"p\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}}}}}}}}}}}},\"因\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}},\"大\":{\"docs\":{},\"致\":{\"docs\":{},\"步\":{\"docs\":{},\"骤\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}},\"家\":{\"docs\":{},\"回\":{\"docs\":{},\"想\":{\"docs\":{},\"一\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"之\":{\"docs\":{},\"前\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"之\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"中\":{\"docs\":{},\"提\":{\"docs\":{},\"到\":{\"docs\":{},\"过\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"的\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"插\":{\"docs\":{},\"件\":{\"docs\":{},\"在\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"期\":{\"docs\":{},\"搞\":{\"docs\":{},\"了\":{\"docs\":{},\"很\":{\"docs\":{},\"多\":{\"docs\":{},\"事\":{\"docs\":{},\"情\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"看\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"设\":{\"docs\":{},\"置\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"就\":{\"docs\":{},\"会\":{\"docs\":{},\"使\":{\"docs\":{},\"用\":{\"docs\":{},\"新\":{\"docs\":{},\"的\":{\"docs\":{},\"值\":{\"docs\":{},\"了\":{\"docs\":{\"faq/variant.html\":{\"ref\":\"faq/variant.html\",\"tf\":0.010638297872340425}}}}}}}}},\"是\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"│\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}},\"└\":{\"docs\":{},\"─\":{\"docs\":{},\"─\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.016216216216216217}}}}},\"├\":{\"docs\":{},\"─\":{\"docs\":{},\"─\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}},\"中\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}},\"的\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"和\":{\"docs\":{},\"s\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{},\"s\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\".\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\",\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"出\":{\"docs\":{},\"来\":{\"docs\":{},\"的\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"就\":{\"docs\":{},\"一\":{\"docs\":{},\"定\":{\"docs\":{},\"如\":{\"docs\":{},\"上\":{\"docs\":{},\"图\":{\"docs\":{},\"所\":{\"docs\":{},\"示\":{\"docs\":{},\":\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"看\":{\"docs\":{},\"到\":{\"docs\":{},\"有\":{\"docs\":{},\"两\":{\"docs\":{},\"种\":{\"docs\":{},\"形\":{\"docs\":{},\"式\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}},\"反\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"，\":{\"docs\":{},\"查\":{\"docs\":{},\"看\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"出\":{\"docs\":{},\"来\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"和\":{\"docs\":{},\"修\":{\"docs\":{},\"改\":{\"docs\":{},\"的\":{\"docs\":{},\"是\":{\"docs\":{},\"否\":{\"docs\":{},\"一\":{\"docs\":{},\"致\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"射\":{\"docs\":{},\"p\":{\"docs\":{},\"m\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}},\"并\":{\"docs\":{},\"构\":{\"docs\":{},\"造\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"实\":{\"docs\":{},\"例\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"m\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"命\":{\"docs\":{},\"令\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}},\"按\":{\"docs\":{},\"照\":{\"docs\":{},\"文\":{\"docs\":{},\"档\":{\"docs\":{},\"，\":{\"docs\":{},\"触\":{\"docs\":{},\"发\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"更\":{\"docs\":{},\"新\":{\"docs\":{},\"操\":{\"docs\":{},\"作\":{\"docs\":{},\"，\":{\"docs\":{},\"观\":{\"docs\":{},\"察\":{\"docs\":{},\"本\":{\"docs\":{},\"地\":{\"docs\":{},\"上\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"地\":{\"docs\":{},\"方\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"格\":{\"docs\":{},\"式\":{\"docs\":{},\"很\":{\"docs\":{},\"简\":{\"docs\":{},\"单\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}},\"概\":{\"docs\":{},\"述\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322},\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"异\":{\"docs\":{},\"常\":{\"docs\":{},\"，\":{\"docs\":{},\"说\":{\"docs\":{},\"明\":{\"docs\":{},\"本\":{\"docs\":{},\"次\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"部\":{\"docs\":{},\"署\":{\"docs\":{},\"生\":{\"docs\":{},\"效\":{\"docs\":{},\"。\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}},\"什\":{\"docs\":{},\"么\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"，\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"跟\":{\"docs\":{},\"进\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"p\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"k\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"涉\":{\"docs\":{},\"及\":{\"docs\":{},\"改\":{\"docs\":{},\"动\":{\"docs\":{},\"确\":{\"docs\":{},\"认\":{\"docs\":{},\"，\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"和\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"的\":{\"docs\":{},\"改\":{\"docs\":{},\"动\":{\"docs\":{},\"一\":{\"docs\":{},\"致\":{\"docs\":{},\"（\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"，\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"和\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"）\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"版\":{\"docs\":{},\"本\":{\"docs\":{},\"确\":{\"docs\":{},\"认\":{\"docs\":{},\"，\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"(\":{\"1\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\".\":{\"0\":{\"docs\":{},\")\":{\"docs\":{},\",\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}},\"docs\":{}}},\"docs\":{}}},\"docs\":{}}}}}}}}}}}}}}}}}}}},\"第\":{\"4\":{\"docs\":{},\"行\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"读\":{\"docs\":{},\"取\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"数\":{\"docs\":{},\"据\":{\"docs\":{},\"，\":{\"docs\":{},\"如\":{\"docs\":{},\"果\":{\"docs\":{},\"有\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"的\":{\"docs\":{},\"话\":{\"docs\":{},\"，\":{\"docs\":{},\"则\":{\"docs\":{},\"在\":{\"docs\":{},\"第\":{\"6\":{\"docs\":{},\"行\":{\"docs\":{},\"从\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"删\":{\"docs\":{},\"除\":{\"docs\":{},\"，\":{\"docs\":{},\"让\":{\"docs\":{},\"系\":{\"docs\":{},\"统\":{\"docs\":{},\"认\":{\"docs\":{},\"为\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{},\"并\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"申\":{\"docs\":{},\"请\":{\"docs\":{},\"任\":{\"docs\":{},\"何\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"5\":{\"docs\":{},\"、\":{\"6\":{\"docs\":{},\"步\":{\"docs\":{},\"，\":{\"docs\":{},\"主\":{\"docs\":{},\"要\":{\"docs\":{},\"是\":{\"docs\":{},\"各\":{\"docs\":{},\"种\":{\"docs\":{},\"逻\":{\"docs\":{},\"辑\":{\"docs\":{},\"判\":{\"docs\":{},\"断\":{\"docs\":{},\"，\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"辗\":{\"docs\":{},\"转\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"到\":{\"7\":{\"docs\":{},\"步\":{\"docs\":{},\"。\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"看\":{\"docs\":{},\"第\":{\"7\":{\"docs\":{},\"步\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"y\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}},\"docs\":{}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}},\"docs\":{},\"一\":{\"docs\":{},\"点\":{\"docs\":{},\"，\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"变\":{\"docs\":{},\"动\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}},\"部\":{\"docs\":{},\"分\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}}},\"三\":{\"docs\":{},\"点\":{\"docs\":{},\"，\":{\"docs\":{},\"d\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"f\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"验\":{\"docs\":{},\"证\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}},\"部\":{\"docs\":{},\"分\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0053475935828877}}}}},\"二\":{\"docs\":{},\"点\":{\"docs\":{},\"，\":{\"docs\":{},\"验\":{\"docs\":{},\"证\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}},\"部\":{\"docs\":{},\"分\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0035650623885918}}}},\"行\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"将\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"加\":{\"docs\":{},\"入\":{\"docs\":{},\"到\":{\"docs\":{},\"已\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"的\":{\"docs\":{},\"列\":{\"docs\":{},\"表\":{\"docs\":{},\"中\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"还\":{\"docs\":{},\"是\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"有\":{\"docs\":{},\"问\":{\"docs\":{},\"题\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}},\"查\":{\"docs\":{},\"看\":{\"docs\":{},\"这\":{\"docs\":{},\"两\":{\"docs\":{},\"个\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"的\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"有\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"变\":{\"docs\":{},\"，\":{\"docs\":{},\"或\":{\"docs\":{},\"者\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"下\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"后\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"产\":{\"docs\":{},\"物\":{\"docs\":{},\"是\":{\"docs\":{},\"否\":{\"docs\":{},\"存\":{\"docs\":{},\"在\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"错\":{\"docs\":{},\"误\":{\"docs\":{\"faq/dynamic_failed_help.html\":{\"ref\":\"faq/dynamic_failed_help.html\",\"tf\":0.005405405405405406}}}},\"乍\":{\"docs\":{},\"看\":{\"docs\":{},\"之\":{\"docs\":{},\"下\":{\"docs\":{},\"，\":{\"docs\":{},\"似\":{\"docs\":{},\"乎\":{\"docs\":{},\"并\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"什\":{\"docs\":{},\"么\":{\"docs\":{},\"不\":{\"docs\":{},\"妥\":{\"docs\":{},\"。\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"，\":{\"docs\":{},\"细\":{\"docs\":{},\"心\":{\"docs\":{},\"的\":{\"docs\":{},\"同\":{\"docs\":{},\"学\":{\"docs\":{},\"可\":{\"docs\":{},\"能\":{\"docs\":{},\"发\":{\"docs\":{},\"现\":{\"docs\":{},\"了\":{\"docs\":{},\"，\":{\"docs\":{},\"少\":{\"docs\":{},\"了\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"像\":{\"docs\":{},\"搭\":{\"docs\":{},\"积\":{\"docs\":{},\"木\":{\"docs\":{},\"一\":{\"docs\":{},\"样\":{\"docs\":{},\"，\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"和\":{\"docs\":{},\"不\":{\"docs\":{},\"同\":{\"docs\":{},\"的\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"组\":{\"docs\":{},\"合\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"成\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"k\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"分\":{\"docs\":{},\"析\":{\"docs\":{},\"完\":{\"docs\":{},\"m\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"f\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"看\":{\"docs\":{},\"一\":{\"docs\":{},\"看\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"文\":{\"docs\":{},\"件\":{\"docs\":{},\"，\":{\"docs\":{},\"看\":{\"docs\":{},\"一\":{\"docs\":{},\"看\":{\"docs\":{},\"有\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"对\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"动\":{\"docs\":{},\"手\":{\"docs\":{},\"脚\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"将\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"分\":{\"docs\":{},\"段\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"添\":{\"docs\":{},\"加\":{\"docs\":{},\"到\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"s\":{\"docs\":{},\"o\":{\"docs\":{},\"u\":{\"docs\":{},\"r\":{\"docs\":{},\"c\":{\"docs\":{},\"e\":{\"docs\":{},\"上\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}},\"流\":{\"docs\":{},\"程\":{\"docs\":{},\"分\":{\"docs\":{},\"为\":{\"docs\":{},\"三\":{\"docs\":{},\"大\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}},\"小\":{\"docs\":{},\"结\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}},\"总\":{\"docs\":{},\"结\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}},\"感\":{\"docs\":{},\"兴\":{\"docs\":{},\"趣\":{\"docs\":{},\"的\":{\"docs\":{},\"同\":{\"docs\":{},\"学\":{\"docs\":{},\"可\":{\"docs\":{},\"以\":{\"docs\":{},\"自\":{\"docs\":{},\"行\":{\"docs\":{},\"验\":{\"docs\":{},\"证\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}},\"果\":{\"docs\":{},\"然\":{\"docs\":{},\"，\":{\"docs\":{},\"每\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"都\":{\"docs\":{},\"是\":{\"docs\":{},\"各\":{\"docs\":{},\"自\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"的\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}},\"独\":{\"docs\":{},\"立\":{\"docs\":{},\"打\":{\"docs\":{},\"包\":{\"docs\":{},\"，\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"后\":{\"docs\":{},\"续\":{\"docs\":{},\"的\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"下\":{\"docs\":{},\"发\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}},\"盗\":{\"docs\":{},\"用\":{\"docs\":{},\"一\":{\"docs\":{},\"张\":{\"docs\":{},\"老\":{\"docs\":{},\"大\":{\"docs\":{},\"的\":{\"docs\":{},\"图\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}},\"结\":{\"docs\":{},\"合\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"g\":{\"docs\":{},\"r\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"发\":{\"docs\":{},\"现\":{\"docs\":{},\"以\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"开\":{\"docs\":{},\"头\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"(\":{\"docs\":{},\"m\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"w\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"、\":{\"docs\":{},\"u\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"s\":{\"docs\":{},\"、\":{\"docs\":{},\"u\":{\"docs\":{},\"p\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\",\":{\"docs\":{},\"都\":{\"docs\":{},\"是\":{\"docs\":{},\"正\":{\"docs\":{},\"常\":{\"docs\":{},\"将\":{\"docs\":{},\"j\":{\"docs\":{},\"a\":{\"docs\":{},\"v\":{\"docs\":{},\"a\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"打\":{\"docs\":{},\"入\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"中\":{\"docs\":{},\"。\":{\"docs\":{},\"而\":{\"docs\":{},\"以\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"开\":{\"docs\":{},\"头\":{\"docs\":{},\"的\":{\"docs\":{},\"依\":{\"docs\":{},\"赖\":{\"docs\":{},\"(\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"r\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"、\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\")\":{\"docs\":{},\"，\":{\"docs\":{},\"他\":{\"docs\":{},\"们\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"并\":{\"docs\":{},\"没\":{\"docs\":{},\"有\":{\"docs\":{},\"在\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"中\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"而\":{\"docs\":{},\"在\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}},\"随\":{\"docs\":{},\"包\":{\"docs\":{},\"发\":{\"docs\":{},\"布\":{\"docs\":{},\"但\":{\"docs\":{},\"是\":{\"docs\":{},\"不\":{\"docs\":{},\"打\":{\"docs\":{},\"入\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}}}}}}}}}}}},\"额\":{\"docs\":{},\"外\":{\"docs\":{},\"的\":{\"docs\":{},\"配\":{\"docs\":{},\"置\":{\"docs\":{\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"ref\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"tf\":0.00423728813559322}}}}}}},\"&\":{\"docs\":{},\"&\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}},\")\":{\"docs\":{},\";\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}},\"，\":{\"docs\":{},\"暂\":{\"docs\":{},\"时\":{\"docs\":{},\"不\":{\"docs\":{},\"关\":{\"docs\":{},\"注\":{\"docs\":{},\"，\":{\"docs\":{},\"往\":{\"docs\":{},\"下\":{\"docs\":{},\"走\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}},\"|\":{\"docs\":{},\"|\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"事\":{\"docs\":{},\"实\":{\"docs\":{},\"上\":{\"docs\":{},\"为\":{\"docs\":{},\"了\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"的\":{\"docs\":{},\"方\":{\"docs\":{},\"便\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"在\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"期\":{\"docs\":{},\"就\":{\"docs\":{},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"了\":{\"docs\":{},\"入\":{\"docs\":{},\"口\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"。\":{\"docs\":{},\"不\":{\"docs\":{},\"过\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"保\":{\"docs\":{},\"证\":{\"docs\":{},\"在\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"期\":{\"docs\":{},\"时\":{\"docs\":{},\"会\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"相\":{\"docs\":{},\"关\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"入\":{\"docs\":{},\"口\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}},\"准\":{\"docs\":{},\"备\":{\"docs\":{},\"工\":{\"docs\":{},\"作\":{\"docs\":{},\"做\":{\"docs\":{},\"好\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"了\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"点\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}},\"实\":{\"docs\":{},\"现\":{\"docs\":{},\"大\":{\"docs\":{},\"概\":{\"docs\":{},\"分\":{\"docs\":{},\"为\":{\"docs\":{},\"四\":{\"docs\":{},\"个\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"，\":{\"docs\":{},\"也\":{\"docs\":{},\"是\":{\"docs\":{},\"本\":{\"docs\":{},\"篇\":{\"docs\":{},\"文\":{\"docs\":{},\"章\":{\"docs\":{},\"的\":{\"docs\":{},\"重\":{\"docs\":{},\"点\":{\"docs\":{},\"关\":{\"docs\":{},\"注\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}},\"通\":{\"docs\":{},\"过\":{\"docs\":{},\"“\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"”\":{\"docs\":{},\"字\":{\"docs\":{},\"段\":{\"docs\":{},\"读\":{\"docs\":{},\"取\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"类\":{\"docs\":{},\"名\":{\"docs\":{},\"，\":{\"docs\":{},\"反\":{\"docs\":{},\"射\":{\"docs\":{},\"该\":{\"docs\":{},\"类\":{\"docs\":{},\"上\":{\"docs\":{},\"的\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"b\":{\"docs\":{},\"e\":{\"docs\":{},\"f\":{\"docs\":{},\"o\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"有\":{\"docs\":{},\"点\":{\"docs\":{},\"长\":{\"docs\":{},\"，\":{\"docs\":{},\"不\":{\"docs\":{},\"过\":{\"docs\":{},\"内\":{\"docs\":{},\"容\":{\"docs\":{},\"大\":{\"docs\":{},\"概\":{\"docs\":{},\"分\":{\"docs\":{},\"为\":{\"6\":{\"docs\":{},\"块\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}},\"docs\":{}}}}}}}}}}}}},\"很\":{\"docs\":{},\"简\":{\"docs\":{},\"单\":{\"docs\":{},\"，\":{\"docs\":{},\"获\":{\"docs\":{},\"取\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"，\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"构\":{\"docs\":{},\"造\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"对\":{\"docs\":{},\"象\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"首\":{\"docs\":{},\"先\":{\"docs\":{},\"创\":{\"docs\":{},\"建\":{\"docs\":{},\"了\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"异\":{\"docs\":{},\"步\":{\"docs\":{},\"任\":{\"docs\":{},\"务\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}},\"处\":{\"docs\":{},\"理\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"，\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.007677543186180422}}}}}}}},\"四\":{\"docs\":{},\"大\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}},\"资\":{\"docs\":{},\"源\":{\"docs\":{},\"，\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}},\"所\":{\"docs\":{},\"谓\":{\"docs\":{},\"反\":{\"docs\":{},\"常\":{\"docs\":{},\"即\":{\"docs\":{},\"为\":{\"docs\":{},\"�\":{\"docs\":{},\"�\":{\"docs\":{},\"，\":{\"docs\":{},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"看\":{\"docs\":{},\"反\":{\"docs\":{},\"编\":{\"docs\":{},\"译\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"到\":{\"docs\":{},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"时\":{\"docs\":{},\"，\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"的\":{\"docs\":{},\"准\":{\"docs\":{},\"备\":{\"docs\":{},\"工\":{\"docs\":{},\"作\":{\"docs\":{},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"，\":{\"docs\":{},\"接\":{\"docs\":{},\"下\":{\"docs\":{},\"来\":{\"docs\":{},\"，\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"的\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"了\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"工\":{\"docs\":{},\"程\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"的\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"的\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"捋\":{\"docs\":{},\"清\":{\"docs\":{},\"楚\":{\"docs\":{},\"这\":{\"docs\":{},\"几\":{\"docs\":{},\"个\":{\"docs\":{},\"参\":{\"docs\":{},\"数\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"往\":{\"docs\":{},\"下\":{\"docs\":{},\"看\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"实\":{\"docs\":{},\"现\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"换\":{\"docs\":{},\"c\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"s\":{\"docs\":{},\"l\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"u\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}},\"收\":{\"docs\":{},\"集\":{\"docs\":{},\"了\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"的\":{\"docs\":{},\"信\":{\"docs\":{},\"息\":{\"docs\":{},\"，\":{\"docs\":{},\"然\":{\"docs\":{},\"后\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"l\":{\"docs\":{},\"p\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"时\":{\"docs\":{},\"序\":{\"docs\":{},\"图\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"第\":{\"4\":{\"docs\":{},\"步\":{\"docs\":{},\"，\":{\"docs\":{},\"即\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"b\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"t\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"中\":{\"docs\":{},\"，\":{\"docs\":{},\"，\":{\"docs\":{},\"做\":{\"docs\":{},\"了\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"接\":{\"docs\":{},\"口\":{\"docs\":{},\"回\":{\"docs\":{},\"调\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}},\"替\":{\"docs\":{},\"换\":{\"docs\":{},\"p\":{\"docs\":{},\"m\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.006269592476489028}}}}}}}},\"点\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}},\"看\":{\"docs\":{},\"样\":{\"docs\":{},\"子\":{\"docs\":{},\"，\":{\"docs\":{},\"是\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}},\"函\":{\"docs\":{},\"数\":{\"docs\":{},\"名\":{\"docs\":{},\"，\":{\"docs\":{},\"是\":{\"docs\":{},\"针\":{\"docs\":{},\"对\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"和\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"k\":{\"docs\":{},\"工\":{\"docs\":{},\"具\":{\"docs\":{},\"类\":{\"docs\":{},\"进\":{\"docs\":{},\"行\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"真\":{\"docs\":{},\"的\":{\"docs\":{},\"是\":{\"docs\":{},\"这\":{\"docs\":{},\"样\":{\"docs\":{},\"的\":{\"docs\":{},\"吗\":{\"docs\":{},\"？\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}},\"给\":{\"docs\":{},\"这\":{\"docs\":{},\"段\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"点\":{\"docs\":{},\"个\":{\"docs\":{},\"赞\":{\"docs\":{},\"，\":{\"docs\":{},\"非\":{\"docs\":{},\"常\":{\"docs\":{},\"的\":{\"docs\":{},\"干\":{\"docs\":{},\"净\":{\"docs\":{},\"和\":{\"docs\":{},\"清\":{\"docs\":{},\"晰\":{\"docs\":{},\"。\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"定\":{\"docs\":{},\"义\":{\"docs\":{},\"了\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{},\"s\":{\"docs\":{},\"框\":{\"docs\":{},\"架\":{\"docs\":{},\"所\":{\"docs\":{},\"需\":{\"docs\":{},\"要\":{\"docs\":{},\"h\":{\"docs\":{},\"o\":{\"docs\":{},\"o\":{\"docs\":{},\"k\":{\"docs\":{},\"的\":{\"docs\":{},\"所\":{\"docs\":{},\"有\":{\"docs\":{},\"的\":{\"docs\":{},\"类\":{\"docs\":{},\"、\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"、\":{\"docs\":{},\"属\":{\"docs\":{},\"性\":{\"docs\":{},\"等\":{\"docs\":{},\"等\":{\"docs\":{},\"字\":{\"docs\":{},\"段\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"编\":{\"docs\":{},\"译\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}},\"能\":{\"docs\":{},\"够\":{\"docs\":{},\"让\":{\"docs\":{},\"动\":{\"docs\":{},\"态\":{\"docs\":{},\"代\":{\"docs\":{},\"码\":{\"docs\":{},\"中\":{\"docs\":{},\"的\":{\"docs\":{},\"四\":{\"docs\":{},\"大\":{\"docs\":{},\"组\":{\"docs\":{},\"件\":{\"docs\":{},\"在\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"上\":{\"docs\":{},\"正\":{\"docs\":{},\"常\":{\"docs\":{},\"跑\":{\"docs\":{},\"起\":{\"docs\":{},\"来\":{\"docs\":{\"code_read/atlas_start/atlas_start_1.html\":{\"ref\":\"code_read/atlas_start/atlas_start_1.html\",\"tf\":0.0019193857965451055}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}},\"。\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}},\"也\":{\"docs\":{},\"就\":{\"docs\":{},\"是\":{\"docs\":{},\"说\":{\"docs\":{},\"，\":{\"docs\":{},\"在\":{\"docs\":{},\"这\":{\"docs\":{},\"一\":{\"docs\":{},\"步\":{\"docs\":{},\"，\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}},\"步\":{\"docs\":{},\"的\":{\"docs\":{},\"启\":{\"docs\":{},\"动\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}},\"直\":{\"docs\":{},\"接\":{\"docs\":{},\"反\":{\"docs\":{},\"射\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"m\":{\"docs\":{},\"b\":{\"docs\":{},\"r\":{\"docs\":{},\"i\":{\"docs\":{},\"d\":{\"docs\":{},\"g\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"p\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"i\":{\"docs\":{},\"c\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"g\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"c\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\".\":{\"docs\":{\"code_read/atlas_start/atlas_start_2.html\":{\"ref\":\"code_read/atlas_start/atlas_start_2.html\",\"tf\":0.003134796238244514}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"?\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}},\"到\":{\"docs\":{},\"目\":{\"docs\":{},\"前\":{\"docs\":{},\"为\":{\"docs\":{},\"止\":{\"docs\":{},\"，\":{\"docs\":{},\"第\":{\"docs\":{},\"一\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{},\"分\":{\"docs\":{},\"析\":{\"docs\":{},\"完\":{\"docs\":{},\"毕\":{\"docs\":{},\"，\":{\"docs\":{},\"我\":{\"docs\":{},\"们\":{\"docs\":{},\"进\":{\"docs\":{},\"入\":{\"docs\":{},\"第\":{\"docs\":{},\"二\":{\"docs\":{},\"部\":{\"docs\":{},\"分\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}},\"这\":{\"docs\":{},\"里\":{\"docs\":{},\"为\":{\"docs\":{},\"止\":{\"docs\":{},\"，\":{\"docs\":{},\"整\":{\"docs\":{},\"个\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"的\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"、\":{\"docs\":{},\"初\":{\"docs\":{},\"始\":{\"docs\":{},\"化\":{\"docs\":{},\"过\":{\"docs\":{},\"程\":{\"docs\":{},\"分\":{\"docs\":{},\"析\":{\"docs\":{},\"完\":{\"docs\":{},\"毕\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"剩\":{\"docs\":{},\"余\":{\"docs\":{},\"存\":{\"docs\":{},\"储\":{\"docs\":{},\"空\":{\"docs\":{},\"间\":{\"docs\":{},\"满\":{\"docs\":{},\"足\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}},\"又\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"了\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"向\":{\"docs\":{},\"u\":{\"docs\":{},\"i\":{\"docs\":{},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"提\":{\"docs\":{},\"交\":{\"docs\":{},\"一\":{\"docs\":{},\"个\":{\"docs\":{},\"任\":{\"docs\":{},\"务\":{\"docs\":{},\"，\":{\"docs\":{},\"用\":{\"docs\":{},\"于\":{\"docs\":{},\"回\":{\"docs\":{},\"调\":{\"docs\":{},\"o\":{\"docs\":{},\"n\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"i\":{\"docs\":{},\"s\":{\"docs\":{},\"h\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}},\"完\":{\"docs\":{},\"成\":{\"docs\":{},\"之\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"回\":{\"docs\":{},\"到\":{\"docs\":{},\"第\":{\"8\":{\"docs\":{},\"步\":{\"docs\":{},\"，\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"o\":{\"docs\":{},\"p\":{\"docs\":{},\"t\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"f\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"。\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}},\"来\":{\"docs\":{},\"看\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"i\":{\"docs\":{},\"m\":{\"docs\":{},\"p\":{\"docs\":{},\"l\":{\"docs\":{},\"的\":{\"docs\":{},\"构\":{\"docs\":{},\"造\":{\"docs\":{},\"函\":{\"docs\":{},\"数\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}},\"然\":{\"docs\":{},\"后\":{\"docs\":{},\"，\":{\"docs\":{},\"根\":{\"docs\":{},\"据\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"m\":{\"docs\":{},\"e\":{\"docs\":{},\"，\":{\"docs\":{},\"去\":{\"docs\":{},\"查\":{\"docs\":{},\"询\":{\"docs\":{},\"b\":{\"docs\":{},\"u\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"加\":{\"docs\":{},\"载\":{\"docs\":{},\"后\":{\"docs\":{},\"的\":{\"docs\":{},\"结\":{\"docs\":{},\"构\":{\"docs\":{},\"体\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"线\":{\"docs\":{},\"程\":{\"docs\":{},\"中\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}},\"虚\":{\"docs\":{},\"线\":{\"docs\":{},\"箭\":{\"docs\":{},\"头\":{\"docs\":{},\"表\":{\"docs\":{},\"示\":{\"docs\":{},\"运\":{\"docs\":{},\"行\":{\"docs\":{},\"在\":{\"docs\":{},\"h\":{\"docs\":{},\"a\":{\"docs\":{},\"n\":{\"docs\":{},\"d\":{\"docs\":{},\"l\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"h\":{\"docs\":{},\"r\":{\"docs\":{},\"e\":{\"docs\":{},\"a\":{\"docs\":{},\"d\":{\"docs\":{},\"中\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}},\"触\":{\"docs\":{},\"发\":{\"docs\":{},\"时\":{\"docs\":{},\"机\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}},\"辗\":{\"docs\":{},\"调\":{\"docs\":{},\"用\":{\"docs\":{},\"，\":{\"docs\":{},\"会\":{\"docs\":{},\"执\":{\"docs\":{},\"行\":{\"docs\":{},\"到\":{\"docs\":{},\"第\":{\"2\":{\"docs\":{},\"步\":{\"docs\":{},\"e\":{\"docs\":{},\"x\":{\"docs\":{},\"e\":{\"docs\":{},\"c\":{\"docs\":{},\"s\":{\"docs\":{},\"t\":{\"docs\":{},\"a\":{\"docs\":{},\"r\":{\"docs\":{},\"t\":{\"docs\":{},\"c\":{\"docs\":{},\"h\":{\"docs\":{},\"i\":{\"docs\":{},\"l\":{\"docs\":{},\"d\":{\"docs\":{},\"a\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{},\"i\":{\"docs\":{},\"v\":{\"docs\":{},\"i\":{\"docs\":{},\"t\":{\"docs\":{},\"y\":{\"docs\":{},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"e\":{\"docs\":{},\"r\":{\"docs\":{},\"n\":{\"docs\":{},\"a\":{\"docs\":{},\"l\":{\"docs\":{},\"方\":{\"docs\":{},\"法\":{\"docs\":{},\"中\":{\"docs\":{\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"ref\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"tf\":0.0017825311942959}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},\"docs\":{}}}}}}}}}}},\"length\":2301},\"corpusTokens\":[\"!=\",\"![](fragment\",\"!tmp.checkvalidate()){\",\"\\\"1.0.0\\\"\",\"\\\"1.0.0\\\",\",\"\\\"1.0.0@1.0.0.tpatch\\\",\",\"\\\"1.0.1\\\"\",\"\\\"14\\\",\",\"\\\"6b3973d9d6592d15601017edabc8b31b\\\",\",\"\\\":\\\";\",\"\\\"[{\\\\\\\"activities\\\\\\\":[\\\\\\\"com.taobao.firstbundle.firstbundleactivity\\\\\\\"],\\\\\\\"contentproviders\\\\\\\":[],\\\\\\\"dependency\\\\\\\":[],\\\\\\\"isinternal\\\\\\\":true,\\\\\\\"pkgname\\\\\\\":\\\\\\\"com.taobao.firstbundle\\\\\\\",\\\\\\\"receivers\\\\\\\":[],\\\\\\\"services\\\\\\\":[\\\\\\\"com.taobao.firstbundle.firstbundleservice\\\\\\\"],\\\\\\\"version\\\\\\\":\\\\\\\"1.0.0@unspecified\\\\\\\"},{\\\\\\\"activities\\\\\\\":[\\\\\\\"com.taobao.secondbundle.secondbundleactivity\\\\\\\",\\\\\\\"com.taobao.secondbundlelibrary.secondbundleshareactivity\\\\\\\"],\\\\\\\"contentproviders\\\\\\\":[],\\\\\\\"dependency\\\\\\\":[],\\\\\\\"isinternal\\\\\\\":true,\\\\\\\"pkgname\\\\\\\":\\\\\\\"com.taobao.secondbundle\\\\\\\",\\\\\\\"receivers\\\\\\\":[],\\\\\\\"services\\\\\\\":[],\\\\\\\"version\\\\\\\":\\\\\\\"1.0.0@unspecified\\\\\\\"},{\\\\\\\"activities\\\\\\\":[\\\\\\\"com.taobao.remotebunle.remotebundleactivity\\\\\\\"],\\\\\\\"contentproviders\\\\\\\":[],\\\\\\\"dependency\\\\\\\":[],\\\\\\\"isinternal\\\\\\\":false,\\\\\\\"pkgname\\\\\\\":\\\\\\\"com.taobao.remotebunle\\\\\\\",\\\\\\\"receivers\\\\\\\":[],\\\\\\\"services\\\\\\\":[],\\\\\\\"version\\\\\\\":\\\\\\\"1.0.0@unspecified\\\\\\\"},{\\\\\\\"activities\\\\\\\":[],\\\\\\\"contentproviders\\\\\\\":[],\\\\\\\"dependency\\\\\\\":[],\\\\\\\"isinternal\\\\\\\":true,\\\\\\\"pkgname\\\\\\\":\\\\\\\"com.taobao.publicbundle\\\\\\\",\\\\\\\"receivers\\\\\\\":[],\\\\\\\"services\\\\\\\":[],\\\\\\\"version\\\\\\\":\\\\\\\"1.0.0@unspecified\\\\\\\"}]\\\";\",\"\\\"api_env\\\",\",\"\\\"awbdiffs\\\":[\\\"com.atlas.demo:firstbundle\\\"],\",\"\\\"baseversion\\\":\",\"\\\"baseversion\\\":\\\"1.0.0\\\",\",\"\\\"boolean\\\",\",\"\\\"bundleinfo\\\":[\",\"\\\"bundles\\\":\",\"\\\"com.android.tools.build:gradle\\\"的版本，默认使用的是\",\"\\\"com.android.tools.build:gradle:2.1\\\"\",\"\\\"com.atlas.demo:firstbundle(1.0.1=>1.0.2)\\\"\",\"\\\"com.taobao.android.atlasdemo:ap\",\"\\\"com.taobao.android:atlasplugin:1.0.0\\\"\",\"\\\"com.taobao.android:atlasplugin:1.0.1\\\"\",\"\\\"com.taobao.android:atlasplugin:2.3.3.beta2\\\"\",\"\\\"com.taobao.atlas.beta\\\"\",\"\\\"com.taobao.demo\\\"\",\"\\\"com.taobao.demo.demoprelaunch\\\";\",\"\\\"com.taobao.firstbundle\\\",\",\"\\\"com.taobao.firstbundle\\\";\",\"\\\"com.taobao.publicbundle\\\"\",\"\\\"dependency\\\":\",\"\\\"dependency\\\":[\",\"\\\"dependency\\\":[],\",\"\\\"dexpatch\\\",成功~\",\"\\\"dexpatch\\\":\",\"\\\"dexpatchversion\\\":\",\"\\\"diffbundledex\\\":\",\"\\\"e857557cc924f503a7304218469733a2\\\",\",\"\\\"false\\\"\",\"\\\"filename\\\":\",\"\\\"ismaindex\\\":\",\"\\\"ismaindex\\\":false,\",\"\\\"ismaindex\\\":true,\",\"\\\"lib\\\");\",\"\\\"maindexdiffs\\\":[\\\"com.atlas.demo:splashscreen(1.0.0@aar=>1.0.1@aar)\\\"],\",\"\\\"modifylines\\\":[\",\"\\\"name\\\":\",\"\\\"name\\\":\\\"com.taobao.firstbundle\\\",\",\"\\\"name\\\":\\\"com.taobao.maindex\\\",\",\"\\\"newawbs\\\":[]\",\"\\\"patches\\\":\",\"\\\"patchversion\\\":\",\"\\\"pkgname\\\":\",\"\\\"pkgname\\\":\\\"com.taobao.firstbundle\\\",\",\"\\\"reset\\\":\",\"\\\"srcunittag\\\":\",\"\\\"srcunittag\\\":\\\"1lxlheevwoeeg\\\",\",\"\\\"srcunittag\\\":\\\"1nf3phs9djbuj\\\",\",\"\\\"targetversion\\\":\",\"\\\"unique_tag\\\":\\\"1lxlheevwoeeg\\\",\",\"\\\"unittag\\\":\",\"\\\"unittag\\\":\\\"1x6r8iuzs90ff\\\",\",\"\\\"unittag\\\":\\\"31jv86qvt1gc\\\",\",\"\\\"updatebundles\\\":[\",\"\\\"updateversion\\\":\\\"1.0.1\\\"\",\"\\\"version\\\":\",\"\\\"version\\\":\\\"1.0.0@1.0.1\\\"\",\"\\\"version\\\":\\\"1.0.0@1.0.2\\\"\",\"#\",\"&&\",\"'1.0.1'\",\"'com.android.library'\",\"'com.android.support.constraint:constraint\",\"'com.android.support:appcompat\",\"'com.android.support:support\",\"'com.taobao.android:atlasupdate:1.0.8@aar'\",\"'com.taobao.atlas'\",\"'com.taobao.atlas'和awbbundl\",\"'com.taobao.atlas.application'\",\"'com.taobao.atlas.library'\",\"'com.taobao.demo.demoprelaunch'\",\"'libs',\",\"(\",\"((bundleimpl)\",\"(appcompat...)\",\"(application)\",\"(apversion){\",\"(atlasprelauncher)\",\"(autoload)\",\"(build.version.sdk_int==25&&build.version.preview_sdk_int>0)){\",\"(bundl\",\"(bundleexcept\",\"(bundleimpl)\",\"(bundleinstaller.this)\",\"(contentprovider)cl.loadclass(info.name).newinstance();\",\"(event.gettype())\",\"(fileutils.getusablespace(environment.getdatadirectory())\",\"(firstbundle、secondbundle、publicbundle)\",\"(gradle中配置)\",\"(impl\",\"(int\",\"(mlisten\",\"(project.hasproperty(\\\"beta\\\"))\",\"(providerinfo\",\"(remotebundle)。\",\"(stream\",\"(string\",\"(string)\",\"(string)runtimevariables.getframeworkproperty(\\\"bundleinfo\\\");\",\"(throwabl\",\");\",\")，暂时不关注，往下走\",\"*\",\"*/\",\"+\",\"+1\",\"+=\",\"+system.getproperty(\\\"java.library.path\\\");\",\",\",\",继续\",\"...\",\"./gradlew\",\".getclassloader().loadclass(mrealapplicationname).newinstance();\",\".invoke(mrealapplication,mrawapplication.getbasecontext());\",\"/**\",\"/*loaded*/,\",\"//\",\"//..\",\"//...\",\"//...一些逻辑\",\"//1.\",\"//2.\",\"//2.1\",\"//2.2\",\"//2.3\",\"//2.4\",\"//3.\",\"//4.\",\"//7.2\",\"//7.3\",\"//7.4\",\"//7.5.\",\"//7.6\",\"//artutils.java\",\"//atlashacks.java\",\"//bridgeapplicationdelegate.java\",\"//dalvikutils.java\",\"//ha\",\"//packagemanagerdelegate.java\",\"//replac\",\"//unknow\",\"//使用com.taobao.atlas.library时需要配置atlasplugin等classpath\",\"//动态部署更新版本\",\"//动态部署版本1.0.1的tag\",\"//基线依赖1.0.0中的唯一tag\",\"//基线版本\",\"//声明为awb\",\"//如果不需要用到atlas的动态部署功能，不需要依赖atlasupd\",\"//异步安装bundl\",\"//方法仅供示例，与实际情况可能存在差异\",\"//核心sdk\",\"//注意不能同时\",\"//自启动bundle配置\",\"//设置bundle依赖\",\"//读取配置\",\"//读取配置项\",\"//通过增加判断逻辑，打出不同类型的定制包\",\"//重要\",\"/data/data/\\\\${pkg}/files/bundlebaseline/updateinfo\",\"/data/data/com.taobao.demo/files/storage/com.taobao.secondbundl\",\"/data/data/pkg/files/storage/\\\\${bundle\\\\_pkg\\\\_name}/bundle.zip\",\"/data/data/pkgname/files/baselineinfo\",\"/data/data/pkgname/files/bundlelist\",\"/data/data/pkgname/files/storag\",\"/data/user/0/com.taobao.demo/files/storage/com.taobao.secondbundle/version.1/lib:/data/app/com.taobao.demo\",\"/f\",\"/im\",\"/sdcard/android/data/com.taobao.demo/cache/，并将上述两个文件push到上述路径中\",\"0:/*\",\"0;\",\"1\",\"1);\",\"1.\",\"1.0.0\",\"1.0.0.json\",\"1.0.0.json中的值:\",\"1.0.0.json中的记录的unittag，数据没有问题。\",\"1.0.0@1.0.0.tpatch\",\"1.0.1\",\"1.0.1@1.0.0\",\"1.0.1ecom.taobao.maindex@31jv86qvt1gc;com.taobao.firstbundle@1x6r8iuzs90ff;\",\"1.0.2\",\"1.1.4.11\",\"1.重新publish了ap,老ap被覆盖了2.gradle在本地仓库做了一份cache，是否和远程仓库中的一致\",\"1/lib/x86:/vendor/lib:/system/lib\",\"10\",\"10.\",\"12\",\"12:39:04\",\"14\",\"15\",\"16\",\"19\",\"1lxlheevwoeeg\",\"1x6r8iuzs90ff\",\"2.\",\"2.1\",\"2.2\",\"2.3\",\"2.3.1版本是不是支持？\",\"2.3.3.rc12\",\"2014\",\"21\",\"22\",\"3.\",\"3.0\",\"31jv86qvt1gc\",\"4\",\"4.0\",\"4.4\",\"5\",\"5)\",\"5.0\",\"5.0.7.41\",\"5.1\",\"5步。\",\"6\",\"6.\",\"6.2.1@6.2.0.tpatch\",\"7\",\"7.\",\"7.0.\",\"7.0以后classloader通过namespace各自独立，不同的classloader可以去load同一个so，分别会在各自的namespace有各自的mmap，可以通过/proc/pid/map\",\"7.0版本之前nativ\",\"7.1\",\"7.2\",\"7.2部分，为了保证demoapplication能够像正常声明的application一样正常工作，做了大量的hook。这里不关注具体hook实现，只给出hook后的映射，感兴趣的童鞋可以自行研究。\",\"7.3\",\"7.4\",\"8\",\"8.\",\"9.\",\"9.3\",\"9.4\",\"9.7\",\"9.8\",\":\",\"=\",\"==\",\"=['com.taobao.firstbundle']\",\"=['xxx']\",\">\",\">1.0.1的diff信息。\",\">=\",\">a,jsonarrary中每个item的key为该bundle的artificatid,dependency里面的item为被依赖的bundle的packagenam\",\">b\",\">c,如果a没有显式声明依赖c，则a\",\">classes2.dex,classes2.dex\",\">classes3.dex）,如下图所示：\",\">安装\",\">生效，与之相对应，动态部署也可以分为三个过程：\",\"?\",\"@overrid\",\"@param\",\"@throw\",\"[\",\"['*.jar'])\",\"['com.taobao.firstbundle']\",\"['com.taobao.firstbundle']，编译时，会将firstbundle中application路径写入manifest。程序运行时，atlas会第一个执行firstbundle中demoapplication中的代码\",\"['remotebundle']\",\"[]\",\"[com.taobao.firstbundle]\",\"]\",\"],\",\"`./gradlew\",\"```\",\"a:\",\"aapt的修改，dalvik上我们是基于res的overlay机制去修改资源，这个机制并不支持新增资源，在overlay的包里面如果读到了一个资源，dalvik系统会去校验该资源id在base中值，如果不存在则抛错，所以动态部署为了利用这一特性同时支持新增资源的需求，在打基线包的时候就在每个不同的type里面预留了128个资源id供后续动态部署使用；同时打动态部署的patch时会以之前的id分配的内容作为输入，保证已有的资源分配到的id保持不变，同时如果资源没有发生变更，则剔除该资源，所以aapt\",\"aapt输出的r为常量,\",\"aar\\\\com.android.support\\\\anim\",\"activ\",\"activities;\",\"activity,\",\"activitygroupdelegate.java\",\"activitymanag\",\"activitymanagerdeleg\",\"activitymanagerdelegate();\",\"activitymanagernative.gdefault.get\",\"activitymanagerproxi\",\"activitymanagerproxy);\",\"activitythread\",\"activitythread.field(\\\"mallapplications\\\").ofgenerictype(arraylist.class);\",\"activitythread.field(\\\"minstrumentation\\\").oftype(instrumentation.class);\",\"activitythread.mallappl\",\"activitythread.minitialappl\",\"activitythread.minstrument\",\"activitythread.mloadedapk.mclassload\",\"activitythread;\",\"activitythread_currentactivitythread;\",\"activitythread_mallappl\",\"activitythread_minstrument\",\"activitythread_minstrumentation;\",\"activitythreadhook\",\"activitythread从loadedapk中获取classloader去load\",\"activity{\",\"activity切换的动画文件、通知栏使用的logo等如果修改了也不会生效，不过不会产生问题，使用的还是原来的样式\",\"activity通过overridependingtransition使用的切换动画的文件要放在主apk中；\",\"adjustlinearalloc();\",\"adjustlinearalloc方法\",\"aidl、servicehub解决了部分bundle之间通信或者代码复用的问题。但是这两者也存在着很大的不足。一方面aidl限制了只能传递parcel以及简单对象，对于ui复用比如说richview的重用则完全行不通，同时使用成本也是servicehub的机制的一个痛点，业务方需要提前将新的接口提前注册到servicehub。\",\"allclasses()\",\"allclasses();\",\"allconstructors();\",\"allfields()\",\"allfields();\",\"allmethods();\",\"alpha11版本发布解决了。\",\"alpha8'\",\"altas是不是不建议bundle之间相互调用资源或调用宿主的资源?\",\"am\",\"andfix\",\"andfix只要用于修复java代码，不重启生效。\",\"android\",\"android.app.activitythread$h.mcallback\",\"android.taobao.atlas.framework;\",\"android:multiprocess=\\\"true\\\"\",\"android:process=\\\":xx\\\"\",\"androidhack.hackh();\",\"androidhack.injectclassloader(packagename,\",\"androidhack.injectinstrumentationhook(new\",\"androidmanifest\",\"androidmanifest修改，remoteview的key以atlas.view.intent.action.开头\",\"android端测容器运行库atlas_core；\",\"android跨classloader的模块之间互相通信的几种方式\",\"apk\",\"apk动态升级\",\"apk构建\",\"apk结构\",\"apk结构分析\",\"apk范围\",\"app\",\"app.oncreate();\",\"app/build/outputs下，检查是否存在两个文件\",\"app;\",\"appclassnam\",\"appid\",\"appinfo\",\"appinfo.metadata.getboolean(\\\"multidex_enable\\\");\",\"appinfo.metadata.getstring(\\\"real_application\\\");\",\"appli\",\"applic\",\"application,boolean\",\"application.attach\",\"application.getbasecontext()));\",\"application_attach;\",\"applicationclass\",\"applicationclass.newinstance();\",\"applicationclassname,\",\"applicationinfo\",\"applicationinitexcept\",\"applicationname；\",\"applicationpackagemanag\",\"applicationpackagemanager.getdeclaredfield(\\\"mpm\\\");\",\"application的mbase实际上就是apk真正的application，最好不要直接传入bundle的application本身进行初始化，会存在潜在的风险。\",\"application的oncreate方法被调用\",\"application的设计是为了尽最大可能保留大家android的开发习惯。\",\"application里用this这种代码，因为是不生效的。\",\"app有多个进程，在一个进程中出现了host中的一个类被pathclassloader加载了，之后在该类中调用class.forname加载插件里的一个类，因为classloader是pathclassloader,所以报了classnotfound,理论上host中除了atlas相关的类外所有的class都应该是被delegateclassloader加载吧？\",\"app的包名、版本号...\",\"apversion表示被动态部署应用的基线版本，versionname表示动态部署后新的versionnam\",\"ap不对,mvn仓库中的ap，和预期的不是同一个\",\"ap不对，比对的ap和预想的不是同一个\",\"args)\",\"args,\",\"arsc和androidmanifest直接使用patch包中的内容\",\"art\",\"art设备上我们会根据source的apk（主apk的merge永远是基于基线版本）把classes.dex\",\"assembledebug\",\"assemblereleas\",\"assertionarrayexcept\",\"assertionarrayexception,\",\"assetmanager_addassetpath;\",\"assets/bundleinfo\",\"asyncstartactivity(container,key,bundlename,intent);\",\"asyncstartactivity最终调用了bundleutil的方法，我们直接看第4步\",\"atals中bundle加载过程\",\"atla\",\"atlas.bundleconfig.awbbundl\",\"atlas.getinstance().getbundle(\\\"com.sample.bundlea\\\");\",\"atlas.getinstance().getbundle(bundlename)))==nul\",\"atlas.getinstance().getbundle(bundlename);\",\"atlas.getinstance().getbundle(str);\",\"atlas.getinstance().init(mrawapplication,\",\"atlas.getinstance().installbundletransitivelyasync(\",\"atlas.getinstance().startup(mrealapplication,misupdated);\",\"atlas.init\",\"atlas.java\",\"atlas.startup\",\"atlas_cor\",\"atlasbridgeapplication.attachbasecontext\",\"atlasbridgeapplication.java\",\"atlasbundleinfomanager.instance().getbundleforcomponet(classname);\",\"atlasbundleinfomanager.instance().getbundleforcomponet(componentname);\",\"atlasbundleinfomanager.instance().getbundleinfo(b.getlocation());\",\"atlasbundleinfomanager.instance().getbundleinfo(location);\",\"atlasbundleinfomanager.instance().getdependencyforbundle(location);\",\"atlasen\",\"atlasenable字段需要指定为true才能开启打包阶段的基于容器扩展的task\",\"atlashacks.activitythread$appbinddata_providers.get(mboundapplication);\",\"atlashacks.activitythread$appbinddata_providers.set(mboundapplication,mboundapplication_provider);\",\"atlashacks.activitythread$appbinddata_providers.set(mboundapplication,null);\",\"atlashacks.activitythread_installcontentproviders.invoke(activitythread,mrealapplication,mboundapplication_provider);\",\"atlashacks.activitythread_mboundapplication.get(activitythread);\",\"atlashacks.application_attach\",\"atlashacks.application_attach.invoke(app,\",\"atlashacks.application_attach.invoke(mrealapplication,mrawapplication.getbasecontext());\",\"atlashacks.contextimpl_mpackageinfo.get(mrawapplication.getbasecontext());\",\"atlashacks.contextimpl_setoutercontext.invoke(\",\"atlashacks.contextimpl_setoutercontext.invoke(mrawapplication.getbasecontext(),\",\"atlashacks.defineandverifi\",\"atlashacks.defineandverify();\",\"atlashacks.singleton_minstance.hijack(gdefault,\",\"atlasplugin\",\"atlasprelaunch\",\"atlasprelauncher实际上是一个接口，供接入者使用。在这个点，atlas还没有开始对系统进行hook，仍然是android原生态的运行时环境。\",\"atlasupd\",\"atlasz之启动过程(一)\",\"atlas{\",\"atlas一个运行于android系统上的一个容器化框架。为了实现这一目标，在编译器和运行期，atlas都做了很多工作。本文是一个入门级别的文章，梳理从gradle配置到生成最终apk的期间，atlas框架到底搞了哪些事情。\",\"atlas不一样，它是在编译期就已经各个bundle的manifest写入到apk中。所以运行时，bundle中的组件可以和常规声明的组件一样正常运行，不用再做额外的处理。\",\"atlas之bundle加载过程\",\"atlas之bundle加载过程，这里不在讨论。\",\"atlas之gradle配置\",\"atlas之启动过程(一)\",\"atlas之启动过程(二)\",\"atlas作为java层以osgi规范进行组件化解耦的容器。在一定层度上清晰了各个模块之间的边界，便于各个业务以内聚的方式不断的演化更新。\",\"atlas基础初始化及multidex逻辑\",\"atlas容器内部集成了multidex的dex安装功能，所以原先multidex的初始化代码可以省略，也不需要添加multidex的三方库依赖，需要使用multidex的只需要build.gradle内部将multidex置为enable即可（atlas内部集成该内容一方面是便于和容器的兼容，另一方面后续容器会优化原生multidex在dalvik上面的性能）\",\"atlas对app的划分如下图所示:\",\"atlas将一个apk分为host和bundle两大部分\",\"atlas开源的代码内容主要包括以下几个模块：\",\"atlas提供哪些功能\",\"atlas插件在编译期生成的配置信息。比如在gradle中配置了\",\"atlas插件有很多参数，这里只关注demo中出现的重点参数，其它设置大家可以查看官方文档。\",\"atlas插件配置\",\"atlas支持所有的代码及资源更新，暂时不支持新增4大组件，下个大版本支持\",\"atlas整个启动过程的时序如下图所示，本篇只关注下图中的1\",\"atlas是伴随着手机淘宝的不断发展而衍生出来的一个运行于android系统上的一个容器化框架，我们也叫动态组件化(dynam\",\"atlas是面向多人协作的较大工程的，配置不同的buildtype和flavor中也会带来创建更多的任务，并且如果执行assembledebug\",\"atlas框架建议bundle调用宿主的资源，而不建议bundle之间资源的相互调用。\",\"atlas能力更强，修复只是其中一部分能力\",\"atlas获得了所有bundle的信息\",\"atlas里面通常会创建了两种classloader,第一个是delegateclassloader，他作为类查找的一个路由器而存在，本身并不负责真正类的加载；delegateclassloader启动时被atlas注入loadedapk中，替换原有的pathclassloader；第二个是bundleclassloader，参考osgi的实现，每个bundl\",\"atlas项目中：atlasdemo和基于版本打包的demo这两个项目有什么区别？\",\"attach(context\",\"attachbasecontext\",\"attachbasecontext(){\",\"attachbasecontext(context\",\"attachbasecontext(context);\",\"autostartbundl\",\"autostartbundle.split(\\\",\\\");\",\"autostartbundles;\",\"awbbundl\",\"awb对应于bundle，编译最后的产物是生成到最后整包的so中。具体请参照\",\"awb是什么？\",\"awb是我们发明的格式，其内部结构和aar一样。\",\"awb：\",\"awo编译\",\"a有若干个native方法，需要提供给js使用，则可以写成\",\"a：\",\"b\",\"b.getarchive().getarchivefile().getabsolutepath()\",\"b.getclassloader());\",\"b.putstring(\\\"js_method\\\",jsmethodname);\",\"base)\",\"baseapdepend\",\"basecontext.moutercontext\",\"basecontext.mpackageinfo.mappl\",\"boolean\",\"boolean.valueof(artutils.init(context,\",\"boolean.valueof(dalvikutils.init());\",\"bootclassloader负责framework\",\"bridgeapplicationdelegate(appl\",\"bridgeapplicationdelegate.\",\"bridgeapplicationdelegate.java\",\"bridgeapplicationdelegate.oncr\",\"bridgeapplicationdelegateclazz\",\"bridgeapplicationdelegateclazz.getconstructor(partypes);\",\"bridgeapplicationdelegateclazz.getdeclaredmethod(\\\"attachbasecontext\\\");\",\"brows\",\"build.gradl\",\"build.gradle(atlasgradleplugin)\",\"build/outputs/apk/xx.ap\",\"build/outputs/apk/xx.apk\",\"build/outputs/atlasconfig.json\",\"build/outputs/dependencytre\",\"build/outputs/tpatch\",\"buildconfigfield\",\"builder\",\"buildscript\",\"buildtyp\",\"bullhead:/data/data/com.taobao.demo/files/storage/com.taobao.firstbundl\",\"bullhead:/data/data/com.taobao.demo/files/storage/com.taobao.firstbundle/1x6r8iuzs90ff\",\"bund\",\"bundl\",\"bundle();\",\"bundle)\",\"bundle).optdexfile();\",\"bundle){\",\"bundle)框架。它主要提供了解耦化、组件化、动态性的支持。覆盖了工程师的工程编码期、apk运行期以及后续运维期的各种问题。\",\"bundle.dex\",\"bundle.getclassloader();\",\"bundle.zip\",\"bundle:\",\"bundle;\",\"bundle_pkg_name为bundle的包名，maindex的包名为com.taobao.maindex\",\"bundleactivated,\",\"bundlearchive(location,bundledir,\",\"bundlebaseinfofil\",\"bundlebaseinfofile.json\",\"bundlebaseinfofile.json:\",\"bundlechanged(fin\",\"bundleclassloader(this,dependencies,nativelibdir);\",\"bundleclassloader以bootclassloader为parent，同时引用pathclassloader,bundleclassloader自身findclass的顺序为\",\"bundlecompil\",\"bundleconfig\",\"bundleconfig{\",\"bundlecontext\",\"bundlecontext(),\",\"bundledir\",\"bundledir,\",\"bundledisabled){\",\"bundleev\",\"bundleexcept\",\"bundleexception,\",\"bundleexception{\",\"bundleimpl\",\"bundleimpl(bundledir,\",\"bundleimpl(fin\",\"bundleimpl.java\",\"bundleimpl。由于secondbundle之前并没有加载进来，所以会执行到第3步asyncstartactivity方法。\",\"bundleinfo\",\"bundleinfostr\",\"bundleinfo{\",\"bundleinfo的信息同时也会在构建后的主manifest里面体现，如线框1、2所示，每个component下面meta\",\"bundleinfo的内容，里面记录了所有bundle的依赖关系\",\"bundleinstal\",\"bundleinstaller.installlistener()\",\"bundleinstallerfetcher.obtaininstaller();\",\"bundlelifecyclehandl\",\"bundlelifecyclehandler.java\",\"bundlelist\",\"bundlelisting();\",\"bundlelisting.bundleinfo\",\"bundlelistingutil.parsearray(bundleinfostr);\",\"bundlenam\",\"bundlesname){\",\"bundlesname,\",\"bundleutil.java\",\"bundle中的9patch图显示有问题，不能拉伸了。是需要有特殊设置么？\",\"bundle中的application类的自定义方法，我们建议不要这么使用。可以抽离出公共的方法，放在其他地方供调用。\",\"bundle中的application类，是在bundle第一次安装的时候，atlas会调用application的oncreate()函数，可以在里面写一些自己bundle需要用到的初始化代码。注意不要bundl\",\"bundle中的manifest中没有任何东西，\",\"bundle中的代码不会打入dex中去，bundle将以libxxx.so文件的形式，放在apk的lib目录下，随包发布\",\"bundle代码初始化\",\"bundle内如果有用到自定义style,那么style的parent如果也是自定义的话，parent的定义必须位于主apk中，这是由于5.0以后系统内style查找的固有逻辑导致的，容器内暂不能完全兼容\",\"bundle内有使用主进程的contentprovider,则bundle的androidmanifest的contentprovider声明中最好带上\",\"bundle内的class最好以特定的packagename开头，resource文件能够带有特定的前缀。这样一来可以避免资源或者类名重复而引起的覆盖，也可以在出现问题的时候及时定位到出问题的模块\",\"bundle内的so，则需要传入so的全路径（比如说通过java层获取），否则可能出现so\",\"bundle内部如果有so，则安装时so由于无法解压到apk\",\"bundle加载完成后，第7步，在ui线程中回调了完成的接口，调用了startbundle方法又经过辗转调用，到了bundlelifecyclehandler的startd方法中。\",\"bundle加载过程\",\"bundle可以直接使用host中的代码和资源\",\"bundle可以被认为是一个小型的apk，因此每个bundle的初始化都是从bundle的application开始的。application被声明在bundle的androidmanifest.xml里面\",\"bundle如何提供服务给其他bundl\",\"bundle如果相互依赖，则构建起需要配置dependency，否则运行期会无法找到被依赖bundle内的class，且不支持为了查找性能，目前不支持二级依赖：比如a\",\"bundle开始运行，bundl\",\"bundle拆分|新建\",\"bundle按需加载\",\"bundle接入，修改bundle的gradle，参见demo中的firstbundle配置\",\"bundle时的线程，这样导致了bundle可能会运行在主线程，也可能是在子线程，所以初始化的代码如果对线程敏感的需要注意：如果需要强制主线程的可以通过new\",\"bundle构建过程中，每个bundle会被独立进行分区，packageid保证全局唯一，packageid在host的构建工程内会有个packageidfile.properties进行统一分配；\",\"bundle独立打包，拥有独立的dex和资源\",\"bundle生命周期\",\"bundle的activity，而xml来自于b\",\"bundle的androidmanifest.xml中进行注册\",\"bundle的androidmanifest中不能有对bundle内的资源的引用；比如activity的theme，需要声明在主apk中。bundle的manifest会合并进主manifest，如果有bundle的资源引用会直接引发构建出错；另外可以选择的方式是androidmanifest里面不加theme，改用在activity的oncreate方法里面调用settheme的方式\",\"bundle的application并不是被系统真正认可的application，所以需要application作为参数进行初始化的方法可以传入getbasecontext()，bundl\",\"bundle的merge主要以下几个过程(如下图)\",\"bundle的代码和资源其实独立打成了一个apk，放在了apk的lib目录下，在运行时进行动态加载。\",\"bundle的加载过程和加载触发时机请参考\",\"bundle的存放位置\",\"bundle的安全校验通过；bundle的dex检测已经成功dexopt(or\",\"bundle的工程配置\",\"bundle的注意点\",\"bundle的缩写，实际上同aar类似，是最终构建整包前的中间产物。每个awb最终会打成一个bundle。awb与aar的唯一不同之处是awb与之对应有个packageid的定义。\",\"bundle的运行期加载策略：\",\"bundle级别，代码动态修复\",\"bundle自身内聚\",\"bundle自身工程build.gradle里面需要声明为awb:\",\"bundle虽然提供了依赖的方式，但是这种方式如果使用不当反而会带来隐患，且与bundle本身的封装性相违背。通常如果某个中间件是以bundle的形式存在，那声明依赖是可行的。如果两个本身相对独立的业务bundle存在某几个功能接口的依赖，则可以通过服务的方式，服务提供方提供aidl的接口，被使用方或者主apk依赖；同时自己bundle内部实现service的功能。\",\"bundle被安装到storage目录\",\"bundle部分的清单数据，包括在app工程中bundlecompile的依赖代码和bundle自身compile的依赖代码\",\"bundle里面无法直接使用bundl\",\"bundle，start\",\"bundle，以及获取全局的application等各种功能。\",\"bundle，只是在需要去load前版本选择上会使用最高的可用版本\",\"bundle，如果a和b没有依赖关系，那么加载也肯定失败\",\"bundle：\",\"c.getclassloader();\",\"call\",\"call();\",\"call(){\",\"call(str\",\"callback)\",\"case\",\"cat\",\"catch\",\"cd到和/data/data/com.taobao.demo/files/storage/com.taobao.firstbundl\",\"checkbundlearraystateasync(fin\",\"checkbundlestateasync\",\"cl\",\"cl)\",\"cl.loadclass(applicationclassname);\",\"class\",\"class.forname(\\\"android.app.applicationpackagemanager\\\");\",\"class.forname(\\\"android.content.pm.ipackagemanager\\\");\",\"class.forname(prelaunchstr).newinstance();\",\"class.method(context)\",\"class[]{ipackagemanagerclass},\",\"classes.dex\",\"classload\",\"classloader.loadclass(classname);\",\"classloader被创建，assetpatch注入delegateresoucc\",\"classname)\",\"classname,boolean\",\"classname2:methodname2\",\"classname:methodnam\",\"classnotfoundexcept\",\"classpath\",\"class|so\",\"class；\",\"clazz\",\"clazz;\",\"clean\",\"cn\",\"com.android.appl\",\"com.taobao.android:firstbundle=34//groupid:artifactid=num\",\"com.taobao.android:taobao\",\"com.taobao.atla\",\"com.taobao.atlas.librari\",\"com.taobao.secondbundle。\",\"comil\",\"commandname,\",\"compil\",\"compile(\\\"com.taobao.android:firstbundle:1.0.0@awb\\\")\",\"compile('com.taobao.android:atlas_core:5.0.0@aar')\",\"compile('com.taobao.android:atlas_core:5.0.7@aar')\",\"con\",\"con.newinstance(this,getprocessname(...);\",\"constructor\",\"container){\",\"container,str\",\"container.addview(remoteview,params);\",\"content\",\"contentproviders;\",\"context)\",\"context){\",\"context,\",\"context,iactivitymanager.contentproviderhold\",\"context;\",\"contextimp.mpackageinfo\",\"contextimpl.getimpl(context).mpackageinfo;\",\"contextimpl.moutercontextt\",\"cpi\",\"cpi,...);\",\"creat\",\"createtpatch\",\"c里面的class，检查bundle依赖是否成功配置可以通过反编译apk的主dex\",\"dalvik\",\"dapversion=1.0.0\",\"data,同时bundle某些特有的信息会记录在application级别的meta\",\"datal里面记录该component所在的meta\",\"data的name做key进行查找，remotefragment的key必须以**atlas.fragment.intent.action.**开头。\",\"data里面。\",\"date:\",\"debug\",\"debug.json\",\"debug:${apversion}@ap\\\"\",\"def\",\"defaultconfig\",\"defineandverify()\",\"delegateclassload\",\"delegateclassloader.java\",\"delegateclassloader以pathclassloader为parent，同时在路由过程中能够找到所有bundle的classloader；\",\"delegatepackagemanager(context\",\"delegateresources.addbundleresources(\",\"delet\",\"deliverytask\",\"deliverytask(boolean\",\"demand\",\"demo\",\"demo/app/build.gradl\",\"demo\\\\atlasdemo\\\\app\\\\build\\\\intermediates\\\\explod\",\"demoappl\",\"demoapplication.attach\",\"demoapplication.java\",\"demoapplication.oncr\",\"demoapplication。\",\"demo中测试入口\",\"demo说明\",\"depend\",\"dependencies)\",\"dependencies主要分为三个部分\",\"dependency;\",\"dependencybundl\",\"dependencybundle,boolean\",\"dependencylibdir\",\"dependencylibdir;\",\"dex\",\"dex2oat)，resource已经成功注入\",\"dexpatch\",\"dexpatchvers\",\"dexpatchversion);\",\"dexpatch不存在回滚，每个dexpatch发布后，直接覆盖之前的dexpatch的。每个dexpatch有下线的能力\",\"dexpatch与动态部署异同\",\"dexpatch介绍\",\"dexpatch作为动态部署的补充，两者相辅相成。可以针对任何一个大版本或者动态部署版本发布dexpatch，无论一个版本号对应的bundle是否有被dexpatch，当一个新的动态部署发生时，它们又都会被收敛到一个新动态部署版本上面。\",\"dexpatch使用教程\",\"dexpatch使用示例\",\"dexpatch是以动态部署技术方案为基础，以快速解决线上故障为唯一目的的动态化方案。\",\"dexpatch由于其修改的原子性（向前兼容性的保证以及不存在关联修改），同时容器按需加载的特性，使得未被载入的bundle可以不需要进程重启即可生效，同时，已经载入的bundle后期也会进行生命周期的监控，一旦所有component退出，则也可以进行热替换，使得dexpatch相比动态部署的生效速度可以进一步提高\",\"dexpatch的特点和优势\",\"dexpatch需要一个ap版本作为参照，和现在的代码比对做diff。假设当前版本为1.0.0\",\"dexpathlist最终通过dexfile去loadclass，dexpathlist可以理解为持有者dexfile以及nativelibrary目录，再查找的时候遍历这些对象，直到找到需要的类或者c库，那么动态部署的方式就是把新修改的内容添加到这些对象的最前面，从而使得查找的过程中新修改的内容能够提前找到从而替换原有的（如下图）\",\"dex的逻辑。（patchdex\",\"diff生成的差异文件，在更新时拉取同时静默更新到设备上，在用户下次启动之后生效新代码，具体原理可以参考动态部署章节的解析\",\"dologin(){\",\"downgrad\",\"drawable\\\\25.3.0\\\\jars\\\\classes.jar\",\"dump\",\"dversionname=1.0.0\",\"dversionname=1.0.1\",\"e)\",\"e){}\",\"e.printstacktrace();\",\"e:\\\\github\\\\atlas\\\\atla\",\"embeddactivity才是真正目标fragment实例化所需要的context，embeddactivity是由remotefragment初始化时创建的activity，用于给目标fragment初始化ui，它是真正的activity，但是没有界面，同时也没有有效的windowmanager，涉及到window操作的会自动转交给sampleactivity进行处理。embeddactivity是bundle之间不需要依赖直接使用ui最根本的保证。\",\"english\",\"enough\",\"error\",\"errorinfo)\",\"event){\",\"except\",\"execstartchildactivityintern\",\"execstartchildactivityinternal(viewgroup\",\"execute(act\",\"extend\",\"fals\",\"false,\",\"false;\",\"falvor\",\"faq\",\"field\",\"field.get(frameworkpropertiesclazz);\",\"field.get(manager);\",\"field.set(manager,\",\"field.setaccessible(true);\",\"fieldname){\",\"file\",\"file(impl.getarchive().getcurrentrevision().getrevisiondir(),\",\"file,version,true,\",\"filetree(dir:\",\"final\",\"findclass(str\",\"finddependency:\",\"findown：\",\"findpath：\",\"firstbudnl\",\"firstbundle（bundle）\",\"flavor\",\"for(str\",\"fragment\",\"fragment)\",\"fragmentactivity{\",\"framelayout\",\"framelayout.layoutparams(viewgroup.layoutparams.wrap_content,viewgroup.layoutparams.wrap_content);\",\"framework\",\"framework.bundles.put(location,\",\"framework.java\",\"framework.notifybundlelisteners(0\",\"frameworkproperti\",\"frameworkproperties.java\",\"frameworkpropertiesclazz.getdeclaredfield(fieldname);\",\"frameworkproperties{\",\"framework，正常的android代码中我们可以调用framework中的接口以及使用其包含的资源，宿主对于bundle而言也是这个样子的，假如多个bundle使用同一个资源，那么这个资源可以放在宿主里边，多个bundle同时依赖这个宿主，这样避免了资源的重复。(甚至可以把宿主看成一个aar，这个aar的内容是打包在主dex中的)\",\"funaplugin();\",\"funbplugin();\",\"gdefault\",\"gdefault=atlashacks.activitymanager_iactivitymanagersingleton.get(atlashacks.activitymanager.getmclass());\",\"gdefault=atlashacks.activitymanagernative_gdefault.get(atlashacks.activitymanagernative.getmclass());\",\"get(iremot\",\"getarchive().getcurrentrevision().getrevisiondir().getabsolutepath()+\\\"/lib\\\"+\\\":\\\"\",\"getbasecontext().getclassloader().loadclass(\\\"android.taobao.atlas.bridge.bridgeapplicationdelegate\\\");\",\"getframeworkproperty(str\",\"getremoteinterface(class\",\"getsupportfragmentmanager().begintransaction().add(r.id.container,fragment).commit();\",\"googl\",\"google插件\",\"google插件对应的文档地址：\",\"gradle分析\",\"gradle部分，我们只用看主工程app和bundle的配置就可以了。\",\"gradle：用于配置主apk的依赖及控制构建参数\",\"h\",\"h5\",\"hack.hackedconstructor\",\"hack.into(\\\"android.app.activitymanager\\\");\",\"hack.into(\\\"android.app.activitythread\\\");\",\"hack.into(\\\"android.app.loadedapk\\\");\",\"hack.into(resources.class);\",\"hackassertionexcept\",\"hackedclass\",\"hackedfield\",\"hackedmethod\",\"handler(looper.getmainlooper()).post\",\"handler(looper.getmainlooper()).post(new\",\"handlerthread\",\"hashmap\",\"holder,\",\"hook\",\"hookedjavavm)\",\"hookedjavavm));\",\"hook之前准备工作\",\"hook之前的准备工作\",\"hook点\",\"host\",\"host:\",\"hosttransactor\",\"host为共用代码资源和各个bundle的manifest信息\",\"host内部包含独立的中间件，以及一个base的工程，里面可能包含应用的application，应用icon等基础性内容（如果足够独立，application也可以直接放在apk_builder内）；\",\"http://atlas.taobao.org/docs/principl\",\"https://developer.android.com/studio/build/build\",\"https://github.com/alibaba/atlas/issues/68\",\"iactivitymanager.contentproviderhold\",\"if(!textutils.isempty(bundleinfostr))\",\"if(!textutils.isempty(bundlename)){\",\"if((tmp=((bundleimpl)\",\"if(args.getstring(\\\"js_method\\\").equals(\\\"funa\\\")){\",\"if(args.getstring(\\\"js_method\\\").equals(funb)){\",\"if(atlasbundleinfomanager.instance().isinternalbundle(bundlename))\",\"if(build.version.sdk_int>25\",\"if(dependencies!=null)\",\"if(impl!=null&&impl.checkvalidate())\",\"if(impl!=null){\",\"if(interfaceclass\",\"if(isdalvik())\",\"if(mboundapplication_provider!=nul\",\"if(multidexenable){\",\"if(plugin!=null){\",\"if(vmutil.is_vm_art)\",\"impl\",\"impl.start();\",\"implement\",\"in)throw\",\"inc.com/zeduo.szd/savedlopen/tree/mast\",\"include:\",\"inflateremoteview(framelayout\",\"info\",\"info,...)\",\"info.getapplicationname();\",\"ingor\",\"init()\",\"init(appl\",\"init(context\",\"initbundleinfobyversionifneed(){\",\"inputstream\",\"instal\",\"installbundlefromapk\",\"installbundlefromapk(bundlename);\",\"installcontentproviders(context\",\"installer.installtransitivelyasync(bundlesname,\",\"installnewbundl\",\"installnewbundle(fin\",\"installnewbundle方法，直接看第9步\",\"installprovider(context\",\"installprovider(context,\",\"installtask\",\"installtask,之后将任务提交给sbundlehandler。而sbundlehandler实际上关联的是一个handlerthread,所以，installtask是运行在单独的线程中的。\",\"instrumentationhook\",\"instrumentationhook(androidhack.getinstrumentation(),\",\"int\",\"intent\",\"intent(\\\"atlas.fragment.intent.action.login\\\");\",\"intent(\\\"atlas.view.intent.action.sample_rich\\\");\",\"intent(jsmethodname),new\",\"intent){\",\"interfaceclass,bundl\",\"intro/project_architectured.html\",\"introduct\",\"ioexception{\",\"ipackagemanagerclass\",\"iremote{\",\"irespons\",\"jar中的资源文件\",\"java\",\"java.ex\",\"java.lang.classload\",\"jcenter()\",\"jcenter()}\",\"jsmethodname){\",\"keep\",\"key\",\"key,\",\"launcher\",\"launcher.initbeforeatlas(mrawapplication.getbasecontext());\",\"layout:1.0.0\",\"lib/armeabi/libcom_taobao_secondbundle.so\",\"libcom_taobao_firstbundl\",\"libcom_taobao_firstbundle，反编译classes.dex，有且只有first.class这个diff\",\"libcom_taobao_maindex.so\",\"libcom_taobao_maindex.so，解压反编译classes.dex，有且只有maindex.class这个diff\",\"librari\",\"library之前java层会先findlibrary，如果是系统库，则在系统环境变量里面包含的路径内，如果是外部引入的，则通过classloader.findlibrary进行查找，bundleclassloader的查找逻辑是先找自身bundle安装目录下的，找不到接着找依赖bundle内的，最后去找主dex也就是patchclassloader的findlibrary去查找。\",\"lib目录中，对于直接通过native层使用dlopen来使用so的情况，会存在一定限制，且会影响后续so动态部署，所以目前bundle内so不建议使用dlopen的方式来使用\",\"linkedhashmap\",\"list\",\"listen\",\"listing.setbundles(infos);\",\"listing;\",\"load\",\"loaded(bundl\",\"loaded(event.getbundle());\",\"loadedapk\",\"loadedapk;\",\"loadedapk_mapplication;\",\"loadedapk_mclassload\",\"loadedapk_mclassloader;\",\"loadedapk_mresources;\",\"loadfrominstalledbundles(classname,false);\",\"loadfrominstalledbundles(str\",\"load同一个进程空间下只可load一次，如果同一个classloder第二次去load则直接返回成功，如果不同的classloader去load则会失败；android\",\"load时与load该so的类所在的classloader存在绑定关系，如果存在native反调java层代码的情况，则只能调用到够找到该classloader可以找到的java类的方法\",\"localprovid\",\"location,\",\"location...)\",\"lock\",\"login\",\"loginfrag\",\"loginint\",\"long\",\"lowdiskexception(\\\"no\",\"ls\",\"m\",\"mainactivity.java\",\"maindex\",\"manag\",\"manifest\",\"manifest：文件用于单独管理apk的icon，版本号，versioncode等；\",\"mavenlocal()\",\"mbasecontext\",\"mbasecontext.getpackagemanager();\",\"mboundappl\",\"mboundapplication_provid\",\"mboundapplication_provider.size()>0){\",\"mbridgeapplicationdeleg\",\"mbridgeapplicationdelegate.getclass().getdeclaredmethod(\\\"oncreate\\\");\",\"mcurrentbundlelist\",\"merg\",\"merge各个bundle的manifest到app中\",\"merge安装成功后，会将bundleinfo的信息更新到baselineinfo的目录中，并在下次启动的最早时间替换掉原有的baselineinfo信息；里面的内容记录了更新的bundle的name，version以及部署成功以后的版本号等信息。\",\"merge完以后接下去安装就是容器的逻辑了，如果没有安装过则在bundle目录下生成version.1目录进行安装，如果安装过则生成新的版本目录\",\"merge完以后，当前的应用处于一个等待生效的状态，会在合适的时机选择进程重启来生效此次的动态部署，且在生效前不会再接收新的动态部署行为，进程重启以后表示一次完整的动态部署过程结束\",\"merge过程在下载到tpatch且校验通过后在线程中进行，由之前atlas容器安装目录介绍可知，假设当前bundle的版本在文件系统上为version.1,则merge成功后新的bundle会安装在version.2目录下，并在后续新的动态部署中版本号逐步往后追加，同时鉴于空间占用的考虑，目前的策略是会保留上一个版本（鉴于回滚的考虑）；\",\"meta\",\"method\",\"method.invoke(mbridgeapplicationdelegate);\",\"minvers\",\"misupdated);\",\"mlistener.onfinished();\",\"mloadedapk\",\"mpackageinfo\",\"mpackagemanagerproxyhandl\",\"mpackagemanagerproxyhandler);\",\"mproxypm\",\"mproxypm);\",\"mrawappl\",\"mrawapplication.get...;\",\"mrawapplication.getbasecontext()\",\"mrawapplication.getbasecontext(),\",\"mrealappl\",\"mrealapplication);\",\"mrealapplication.attach\",\"mrealapplication.oncreate();\",\"mrealapplicationnam\",\"mrealapplicationname实际上是指com.taobao.demo.demoapplication。在这里，构造出了app工程中指定application的对象实例。\",\"mrealapplication实际上就是demoapplication,反射执行application的attach方法,即第8步。\",\"mtl.atlasen\",\"mtl.buildtypes.debug.baseapdepend\",\"mtl.buildtypes.release.baseapdepend\",\"mtl.manifestoptions.replaceappl\",\"mtl.patchconfigs.debug.createapatch\",\"mtl.patchconfigs.debug.createtpatch\",\"mtl.patchconfigs.debug.filterclass\",\"mtl.patchconfigs.debug.filterfil\",\"mtl.patchconfigs.release.createapatch\",\"mtl.patchconfigs.release.createtpatch\",\"mtl.patchconfigs.release.filterclass\",\"mtl.patchconfigs.release.filterfil\",\"mtl.tbuildconfig.aaptconstantid\",\"mtl.tbuildconfig.autopackageid\",\"mtl.tbuildconfig.autostartbundl\",\"mtl.tbuildconfig.createap\",\"mtl.tbuildconfig.mergeawbjavar\",\"mtl.tbuildconfig.mergejavar\",\"mtl.tbuildconfig.prelaunch\",\"mtl.tbuildconfig.preprocessmanifest\",\"mtl.tbuildconfig.usecustomaapt\",\"multidex.install(mrawapplication);\",\"multidexen\",\"myjspluginmanag\",\"n\",\"nativ\",\"nativeinit();\",\"nativeinit(...);\",\"nativelibdir\",\"native方法有一个externaljsmethodexecuter，当需要执行非内部的js方法时，则可以通过externaljsmethodexecuter.execute()查找外部的method。（这种也适用于weex等sdk在非常规的apk内由外部实现定制的适配器）\",\"native特殊使用情况及建议\",\"new\",\"newapplication(appclassname,\",\"newapplication(str\",\"newclassloader);\",\"noclassdeffounderror\",\"notifi\",\"null\",\"null)\",\"null){\",\"null,\",\"null;\",\"oat的限制:android到art后原有的dexopt会改为dex2oat，运行时代码由原来的解释执行改为直接运行native代码，之前的使用过程中发现单纯得往前面追加patch的dex并不能完全解决动态部署的问题，dex2oat的过程优化了class的执行代码，比如说内敛，虚函数的校验等。就有可能在运行过程中直接在native层执行老的优化过的class代码而不是从新patch的dex中load新的class去使用。所以art上目前的策略是把patchdex，sourcedex参考multidex的机制放入一个zip，然后合并在一起做一遍dex2oat，这样能使新的class覆盖老的class参与dex2oat并完成优化的过程，所以art上的真正的执行过程实际上在patch的dex中已经包含了所有主apk的代码，基本不会走到old\",\"object\",\"ok,我们再解压1.0.0的ap文件，打开atlasframeworkproperties.json文件，关键字搜索com.taobao.firstbundl\",\"oncreat\",\"oncreate()\",\"oncreate(){\",\"oncreate方法、activity的oncreate方法等都是在主线程回调的\",\"onfailed(str\",\"onfinished()\",\"onremoteprepared(remotefrag\",\"onremoteprepared(remotetransactor\",\"onremoteprepared(remoteview\",\"optdexfil\",\"outofapkbundl\",\"packag\",\"packageidfile.properti\",\"packageidfile.properties:\",\"packagemanag\",\"packagemanagerdelegate.delegatepackagemanager(\",\"packagemanagerproxyhandler(rawpm);\",\"packagenam\",\"packageparser_constructor;\",\"param\",\"patch\",\"patchconfig\",\"patchconfigs.debug\",\"patchconfigs{\",\"patchifpossible()\",\"patchs.json\",\"patch产物\",\"patch文件解压后一级目录如下图：\",\"patch的时候我们看到的invalid\",\"path.json\",\"pathclassload\",\"pathclassloader本身也是一个class，继承了basedexclassloader（同dexclassloader），里面查找过程在dexpathlist里面实现（如下图）\",\"pbeta\",\"pbeta,\",\"permission，小米推送需要permission就提示缺少权限声明。\",\"pkgname;\",\"pkg为app的包名\",\"plugin\",\"plugin.execute(jsmethodname,...);\",\"plugin:\",\"prelaunch\",\"prelaunch;\",\"prelaunchstr\",\"preverify:\",\"privat\",\"proguard\",\"project(\\\":secondbundlelibrary\\\");\",\"project(':activitygroupcompat')\",\"project(':firstbundle')\",\"project(':middlewarelibrary')\",\"project(':publicbundle')\",\"project(':remotebundle')\",\"project(':secondbundle')\",\"project(':splashscreen')\",\"protect\",\"provid\",\"providedcompil\",\"providerinfo\",\"providers)\",\"proxy.newproxyinstance(mbasecontext.getclassloader(),\",\"ps:\",\"public\",\"publish\",\"q10.\",\"q11.\",\"q12.\",\"q13.\",\"q14.\",\"q15.\",\"q16.\",\"q17.\",\"q18.\",\"q19.\",\"q1:\",\"q20.\",\"q2:\",\"q3:\",\"q4:\",\"q5:\",\"q6:\",\"q7:\",\"q8:\",\"q9.\",\"r.id.navigation_dashboard:\",\"rawapplication...){\",\"rawapplication.getbasecontext()\",\"rawapplication;\",\"rawpm\",\"receivers;\",\"redirect\",\"registerhosttransactor(iremot\",\"relation.png)\",\"releas\",\"release:6.3.0\",\"remot\",\"remote)\",\"remote.getremoteinterface(wvapiplugin.class,b);\",\"remotefactory.onremotestatelistener()\",\"remotefactory.requestremote(remotefragment.class,loginintent,\",\"remotefactory.requestremote(remotetransactor.class,activity,new\",\"remotefactory.requestremote(remoteview.class,\",\"remotefrag\",\"remotefragment本身也是真正意义上的fragment，所以可以用来直接被fragmentmanager或者fragmenttransaction直接进行管理；同时它也是真正的loginfragment的在使用方的代理。他们之间的关系如下：\",\"remotefragment的使用方拿到的仅仅是目标fragment的代理，所以真正的实现对使用方来说是不可见的。如果除了拿到fragment展示之外还有其他的接口需要暴露给使用者，则需要走remote的通信机制。\",\"remotefragment适用于某个bundle中有公共的fragment要提供给一个或者多个其他业务bundle使用的情况，比如说在手淘里面，skufragment(sku选择界面)可能会提供给详情，购物车，聚划算等多个业务使用；或者在某些app里面，登录界面也以loginfragment的方式提供给bundle按需使用。\",\"remoteitem)\",\"remotetransact\",\"remotetransact相当于是remoteview或者remotefragment的简化版，仅仅为了bundle和bundle之间的通信而存在，它和remoteview，remotefragment都实现了iremotetransact接口。可以通过下面的草图了解大致的关系：\",\"remoteview\",\"remoteview)\",\"remoteview与remotefragment实现基本一致，需要embeddedactivity作为真正view膨化的基本条件，remoteview本身只是一个framelayout，就像decorview，目标view作为子view添加在里面。当然这个机制也有一定的隐患，使用方不要通过findviewbyid或者getchildat等viewgroup的publ\",\"remote机制本身强烈依托于组件化拆分的方案。它的解耦层度介于aidl和直接依赖之间。相比aidl灵活层度更高。不过代理的方式并不能完全杜绝通过非常规方法来获取远端目标对象来进行使用，另外也可能存在某些边缘方法无非被完全代理的情况，这也需要在以后的迭代中进行优化，对于非atlas容器化但是使用了组件化拆解方案的app，这种思路也是同样适用的。\",\"remote机制的特点和不足\",\"remote组件参照aidl的方式在manifest中进行注册。查找时以meta\",\"replac\",\"repositori\",\"requestruntimedependency(classload\",\"reset\",\"reset)\",\"resolv\",\"resolvebundl\",\"resolvebundle()\",\"resolvebundle();\",\"resolve时会分配一个bundleclassloader，负责该bundle的类加载。关系如下图所示：\",\"resolve机制导致部分class没成功，替换以后该问题得到最好的解决，除atlas本身以外，所有业务代码均可以动态部署；\",\"resourc\",\"resourcedependencyne\",\"resourcedependencyneed)\",\"resources;\",\"resource|asset\",\"res和asset\",\"return\",\"rules.pro直接定义在宿主app里面就可以了吗，不需要每个bundle都使用吧？\",\"run\",\"run()\",\"runnabl\",\"runnable()\",\"runtim\",\"runtimevariables.androidapplication);\",\"runtimevariables.androidapplication.getapplicationinfo().nativelibrarydir+\\\":\\\"\",\"runtimevariables.getframeworkproperty(\\\"autostartbundles\\\");\",\"runtimevariables.getframeworkproperty(\\\"prelaunch\\\");\",\"runtimevariables.java\",\"runtime层：主要包括清单管理、版本管理、以及系统代理三大块，基于不同的触发点按需执行bundle的安装和加载；runtime层同时提供了开发期快速debug支持和监控两个功能模块。从delegate层可以看到，最核心的两个代理点：一个是delegateclassloader：负责路由class加载到各个bundle内部，第二个是delegateresource：负责资源查找时能够找到bundle内的资源；这是bundle能够真正运行起来的根本；其余的代理点均是为了保证在必要的时机按需加载起来目标bundle，让其可以被delegateclassloader和delegateresource使用\",\"safe)\",\"sampleact\",\"samplerichview\",\"sbundlehandler.post(installtask);\",\"sdk的内容的查找。\",\"secondbundlelibrary之前并没有打入主dex中，因为这只是secondbundle所需要的依赖。最终会将secondbundle和secondbundlelibrary的打在一个同一个dex中，加上两者的资源，成为一个bundl\",\"services;\",\"service的方式保证自身封装性；同时某些中间件如果只存在若干bundle使用的也可以封装bundle的方式提供出来，以保证host内容精简\",\"set\",\"sintent\",\"sintent,\",\"snapshot@ap\",\"sourc\",\"source,str\",\"so依赖或者dlopen公共n\",\"so的导出函数进行使用,规避因为namespace不一致导致多份mmap的情况。具体参考：http://gitlab.alibaba\",\"so的情况：\",\"so的相互调用导致的bundle依赖\",\"so等内容。如果bundle发生更新，则可能会有version.2、version.3\",\"space\",\"space\\\");\",\"splashscreen\",\"splashscreen（maindex）\",\"srcunittag\",\"start\",\"started(){\",\"started(bundl\",\"startup\",\"static\",\"static{\",\"storage目录是bundle安装的目录，每个bundle的安装目录以bundle的packagename为文件夹名，首次启动后会安装到version.1目录下，目录中可能含有bundle的zip文件，dex文件以及n\",\"str\",\"stream,...)\",\"stream,version,\",\"string\",\"string[]\",\"string[]{\\\"com.sample.bundlea\\\"},\",\"studio编译按钮编译失败。\",\"success\",\"super.attachbasecontext(base);\",\"super.oncreate();\",\"support\",\"switch\",\"switchact\",\"switchtoactivity(\\\"second\\\",\\\"com.taobao.secondbundle.secondbundleactivity\\\")\",\"sync){\",\"synchron\",\"system.currenttimemillis();\",\"system.loadlibrary(\\\"dalvikhack\\\");\",\"system.loadlibrary(\\\"dalvikpatch\\\");\",\"system.loadlibrary(\\\"dexinterpret\\\");\",\"t\",\"tag\",\"tag的警告信息：\",\"targetversion@sourceversion.tpatch\",\"tbuildconfig\",\"test\",\"this);\",\"this.arch\",\"this.classload\",\"throw\",\"time\",\"title:\",\"tmp.startbundle();\",\"tmp;\",\"todo\",\"tpatch构建\",\"transactor);\",\"transit\",\"tri\",\"true\",\"true,\",\"true;\",\"true表明启用了atlas插件，并将当前模块编译成awb形式的bundle供主apk使用。\",\"try{\",\"type\",\"ui\",\"unabl\",\"unittag\",\"unittag确认。（如果同学们没有按照规范来，这个地方很容易出错，导致动态部署失败）\",\"updat\",\"updateinfo\",\"updateversion(1.0.1),分别对应打包命令的apversion和versionname,表明是1.0.0\",\"update库及构建插件，可以生成与之前发布的apk\",\"v4:25.3.0'\",\"v7:25.1.0'\",\"val\",\"variants.html?hl=zh\",\"vector\",\"verison.json的文件，其中version为manifest中的versinonname，里面记录了每个bundle大小，版本，名字以及里面所有的component信息，这些内容在构建的时候生成，基于这些信息每个bundle可以在component被触发的时候去按需的进行安装，整个过程对开发者透明（从中也可以看到默认情况下bundle对外暴露的只是基于android原生的activity，service，receiver等component）。\",\"version\",\"version.json\",\"version@version.tpatch\",\"versionnam\",\"viewgroup.layoutparam\",\"void\",\"window级别使用的资源保持不变\",\"wireless\",\"wvapiplugin\",\"wvapiplugin.class){\",\"x\",\"xxx\",\"xxx.json\",\"xxx.json中bundle的srcunittag和ap中的unitttag不一样\",\"xxx.json文件中，某个bundle的srcunittag和unittag一样\",\"ye\",\"zip包，classes.dex来自于source中的classes.dex和patch包中的classes.dex通过dexmerge合并新的classes.dex\",\"{\",\"||\",\"}\",\"});\",\"},\",\"};\",\"}catch(throw\",\"}els\",\"}else{\",\"│\",\"└──\",\"├──\",\"。\",\"。。。\",\"一个是基于源码项目，一个是基于仓库版本依赖的。前期研究可以基于源码来，后续工程化实践推荐使用后者，手淘内部就是使用后者的。\",\"一些限制\",\"一般\",\"一般来说，由于art设备警告的信息报在dex2oat的时候，所以往往与发生crash时的exception信息相隔比较远，所以通常遇到该类问题，dalivk的设备拿来排查可能更能发现问题的原因。另外noclassdef造成的原有接口类找不到，方法丢失，方法参数不匹配，方法属性变更，混淆等，所以具体原因需要利用上述warning信息并对照反编译的代码去排查根本的原因\",\"上篇先到这里，各位先喝口水，再来下篇的分析。\",\"上线后的运维期，atlas提供了一整套完整的支持\",\"上述代码diff的配套json，描述了本次diff的结果:\",\"上重新编译安装不生效的问题\",\"下个版本会清理bundl\",\"下发的dexpatch总包内的patch各自生效，不需要所有bundle的patch全部安装成功，这是由于之前patch的修改是向前兼容做了保证。\",\"下图是容器中类加载的大致顺序；\",\"下载到tpatch文件后，动态部署sdk会在后台完成merge到安装的过程，整个过程对用户透明\",\"下面会逐个说明每个文件的使用和注意要点\",\"下面对每个过程展开讲解下，以便更好理解整个动态部署的机制\",\"下面展开介绍下在新bundle（假设主apk当做是一个特殊的bundle）安装成功前merge的过程中bundle和主apk在merge过程中的差异点：\",\"不同于apk更新产物就是一个完整的apk，动态部署的构建产物是一个后缀为tpatch格式的文件\",\"不同点\",\"不支持\",\"不改\",\"不生效要看提示log再查，目前已知的已经修复，之前是由于windows句柄没关闭，导致tpatch中包含一些空文件，在dexmerge的时候失败了\",\"与bundle以包名为文件夹存放类似，主apk更新存放的文件夹以com.taobao.maindex为名字，里面的版本管理与bundle一致，不同点是com.taobao.maindex只在发生过动态部署以后才会有，version.1意味着已经发生一次动态部署；bundle通常情况下动态部署从version.2开始（未安装过的bundle除外）\",\"与remotefrag\",\"与tpatch文件相对于的，接口会返回该次动态部署的修改内容，数据结构如下：\",\"与插件化框架不同的是，atlas是一个组件框架，atlas不是一个多进程的框架，他主要完成的就是在运行环境中按需地去完成各个bundle的安装，加载类和资源。\",\"业务使用方调用atlas的remotefactory的接口进行request，由于期间可能涉及到bundle的安装，所以整个过程采用callback的方式。获取到remotefragment的句柄后直接进行操作即可。**建议fragment里面涉及到的交互功能等的代码封装在fragment内部**，比如说loginfragment里面所有按钮的点击以及异常处理全都fragment内部进行实现。这样的话两个bundle之间的边界也更清晰。\",\"业务可以灵活发布自己的需求\",\"业务层基本上以bundle为边界自上而下与host发生调用，同时bundle之间允许存在依赖关系；相对业务独立的bundle如果存在接口耦合建议封装成aidl\",\"业务层基本单位\",\"业务灰度新的sdk，快速测试效果，同时有问题可以及时回滚\",\"业务需要时，才会去加载对应bundle中的代码和资源\",\"中\",\"中可以看到有两种形式的依赖\",\"中的first.java和splashscreen中的maindex.java,diff出来的产物就一定如上图所示:\",\"中的。\",\"为bundle创建一个classloader，在创建classloader的过程中\",\"为bundle创建了独立的classload\",\"为demoapplication创建一个loadedapk对象\",\"为了实现这三个目标，会在系统关键调用的地方进行hook。比如，为了能够动态加载class，通常都会对classloader上动一些手脚，resource也是类似。\",\"为了降低用户等待时间，atlas框架在dalivk系统上首次使用bundle时关闭了verify，在art系统上首次使用时关闭了dex2oat走解释执行。同时后台通过异步任务走原生的dexopt过程，为下次使用做好准备\",\"为什么不用动态部署\",\"为什么会是atlasbridgeapplication呢，manifest中明明写的很清楚\",\"为什么没有去完全适配\",\"为什么这么做?回顾一下app启动的流程\",\"为例\",\"为例。\",\"为四大组件预留一些坑位\",\"主apk为了支持在resource能够动态部署实际上同preverify的机制类似，在基线包构建的时候就已经做了处理:基于atlas打出来的apk的资源列表中有如下内容：\",\"主apk动态部署后的加载策略\",\"主apk的merg\",\"主apk的merge在dalvik和art上使用的机制有所不同，dalvik设备上没有任何merge过程，直接把libcom_taobao_maindex.so以bundle的形式安装到com.taobao.maindex目录下\",\"主dex\",\"主dex中已经打入了必要的公用代码(appcompat、middlewarelibrary)，在runtime时，atlas框架会自动找到主dex中的class使用，所以secondbundl就不需要在重复打入\",\"主动启动bundl\",\"主工程容器接入\",\"主界面点开侧边栏，点击dexpatch\",\"之前打包构建时记录的bundleinfo信息（发生动态部署收文件会进行更新）\",\"之类会构建所有的依赖变种，导致整体构建效率大大降低。\",\"乍看之下，似乎并没有什么不妥。但是，细心的同学可能发现了，少了bundle部分的代码。\",\"也就是说，在这一步，\",\"书写的格式为：groupid:artificatid=xx（如下图）\",\"了解主apk的加载策略之前，先分别介绍下主apk动态部署得以成功的技术基础再阐述生效的方式：\",\"事实上为了接入的方便，atlas在编译期就替换了入口application。不过，atlas保证在运行期时会调用demoapplication的相关方法。\",\"产物说明\",\"什么情况，怎么什么都没有?\",\"什么时候写入又是在哪里配置\",\"什么是dexpatch\",\"从app的开发期\",\"从atlasbundleinfomanager上已加载的列表中找到对应bunde(在第在第10步中添加)\",\"从bundlea中加载class，并且创建class；\",\"从demo中一个例子开始，假设我们发了1.0.0的ap,之后修改了splashscreen和firstbundle两个地方的代码,并且修改了对应的版本号\",\"从上图也可以看出基于atlas构建后大致工程的结构：\",\"从反编译后的代码可以看到，\\\"prelaunch\\\"对应的内容是com.taobao.demo.demoprelaunch,那么这个值是在\",\"从对应bundle上的classloader上加载对应的class。\",\"代码以\",\"代码改动\",\"代码改动：以loginfragment为例，loginbundle需要在自己的loginfragment做一定的改动\",\"以\",\"以remotetransactor为例，他和目标transactor类都实现了iremotetransactor，所以当使用方调用iremotetransactor的接口时候，remote对象将方法路由到目标对象的方法上。\",\"以secondbundle为例，看一下bundle中gradle的配置\",\"以windvane为例（sample里面windvane的接口只做范例，与真实的使用接口可能存在差异）：存在很多bundle需要提供jsplugin的场景。原生的windvane需要提前注册jsplugin，这种方式对bundle而言开销较大。需要bundle提前启动注册以避免后期运行时无法找到js函数对应的native方法。\",\"以一个app的开发的生命周期为例，参见\",\"以上build.gradl\",\"以上是正确的使用姿势，下面是常见的一些常见的错误\",\"以动态部署技术方案为基础，可以看作是动态部署的子集，专注于单个bundle的故障修复。由于做的事小而精，所以编译构建速度、线上生效速度都是远远快于动态部署\",\"以及\",\"以命令的方式通知目标对象，如果是异步返回，则远端通过传入的callback接口进行回调，如果不是，则直接返回，适用于使用方和远端存在简单通信的情况。\",\"以在mainactivity中点击secondebundle为例\",\"优势\",\"会打入apk中，而remotebundle不会\",\"会进行合并，如果文件没有变更（patch中没有，source中有），则直接使用source中的内容，如果有文件新增或者发生了变更（patch中有，source中有或者没有），则从patch中读取放到新的bundle包中\",\"但是在复杂的app比如手淘这种无数个业务交织的场景下，完全的隔离也给业务的开发造成了不小的成本。针对这种问题，目前主要解决的方案有：\",\"使用atlas的application，包含\",\"使用基于容器的实现开发的servicehub，跟aidl一样将接口放到公共library，然后servicehub中写入接口和实现的对应关系。使用方通过servicehub得到接口实现进行使用。\",\"使用方如何调用remotefrag\",\"使用方如何调用remoteview\",\"使用方式\",\"使用方案：\",\"使用者可以通过这两个方法与真正的远端对象进行通信：\",\"使用者应该了解remotefragment机制的以下几个特点，明白其内部实现的主要机制：\",\"使用自定义的aapt，\",\"例如手淘6.2.0部署到6.2.1的动态部署的tpatch文件为：\",\"依赖\",\"依赖方式\",\"依赖管理配置\",\"修改依赖版本，将firbundle中grddle的verion改为vers\",\"修改引入了其它隐含的改动\",\"修改范围\",\"值\",\"值为\",\"值是\",\"假设bundl\",\"假设在remote机制下则windvane针对非内部的common\",\"像搭积木一样，host和不同的bundle组合编译成一个apk\",\"先看bridgeapplicationdelegate的构造方法。\",\"先看一下功能对比：\",\"先附一张fragment启动图，不清楚的同学可以通过这个大致了解整个fragment启动的一些方法调用，理清fragment和activity在启动时的一些交织的关系(图片可能需要下载放大了观看)。\",\"入口\",\"公共so下层到公共模块，同时提前load（规避7.0版本开始区分namespace隔离的情况），bundle的so使用的时候不能使用官方的dlopen接口，需要根据mapping查找已load\",\"共享代码资源\",\"关于bundle中的application类，它什么时候被调用，其中的自定义方法怎么在bundle中调用？在bundle中调用getapplication方法，得到的是主应用的application对象，不是bundle中定义的。\",\"关于第三个，我们以firstbundle为例，详细说明。首先，看下在配置文件upd\",\"关闭instantrun可以正常工作。instantrun支持正在开发中。\",\"关闭掉a\",\"其他：由于nativ\",\"其它\",\"具体参考\",\"具体的demo可以看下下面的介绍，至于具体的其他实现，大家也可以自行扩展\",\"准备工作做好之后，就是初始化了。\",\"减少包体积。不常用的bundle放在云端，需要时按需下载。当用户设备空间紧张时,可以清理掉一些长期不用的组件\",\"函数中的hook点\",\"函数实现大概分为四个部分，也是本篇文章的重点关注部分\",\"函数很简单，获取bundle的信息，之后构造一个bundleimpl对象。\",\"函数有点长，不过内容大概分为6块\",\"函数通过“prelaunch”字段读取一个类名，反射该类上的initbeforeatlas方法。\",\"函数首先创建了一个异步任务\",\"分析完manifest之后，我们看一看host的dex文件，看一看有没有对java代码动手脚。\",\"列表文件\",\"创建完bundlerclassloader后，在最后一行进行回调，这里的回调实现类是\",\"创建新的bundl\",\"初始化atla\",\"初始化bundl\",\"初始化的线程基于start\",\"初始化过程\",\"到目前为止，第一部分分析完毕，我们进入第二部分\",\"到这里为止，整个bundle的加载、初始化过程分析完毕。\",\"前面容器的技术原理里面介绍了pathclassloader的父子关系，pathclassloader自身负责主apk的类和c库的查找路口；其par\",\"剩余存储空间满足\",\"功能\",\"加上bundle的packagename为：com.sample.bundlea\",\"加载provid\",\"加载时机的触发逻辑\",\"加载过程\",\"动态代理pm\",\"动态修复线上故障\",\"动态加载class\",\"动态加载资源\",\"动态部署\",\"动态部署不生效的问题\",\"动态部署与原有的apk更新策略相比是一种相对比较轻量化的更新策略，不需要用户下载整个apk，只需要下载仅仅差量部分的内容来达到更新效果；同时也可以静默的完成更新过程，两者相结合可以使动态更新的生效率远高于普通的升级策略。\",\"动态部署允许宿主，bundle内部发生更新，也允许bundle之间的依赖关系等发生变更，这就导致了一次动态部署成功必须依赖于tpatch内的所有bundle和宿主全部更新成功，否则就可能会导致依赖不一致而引发crash。从以往的动态部署tpatch可知，每次的变更通常都有十几个甚至几十个bundle发生变更，而在低空间或者某些读写能力较差的设备上，io失败很容易影响整个patch的成功率。\",\"动态部署内有代码的变更，so，资源等。灵活性导致一个动态部署等体积往往比较大，而在运营商网络下，对用户大的流量消耗不是我们希望看到的，所以往往这种情况下只在wifi下的生效策略很能影响生效率。\",\"动态部署失败排查指南\",\"动态部署成功后，会在下次进程重启后去resolve新的bundle，resolve的策略是按版本号从高到低回溯，选择最高可用的版本使用。\",\"动态部署排查经验\",\"动态部署构建的产物为tpatch为后缀的一个压缩文件\",\"动态部署版本\",\"动态部署的出发点立足于需求的快速迭代，替换普通的apk升级。所以在动态部署的演进过程中灵活性成为我们不断去追求的目标。希望不断缩小动态部署的限制以达到完全替换apk更新的能力。\",\"动态部署的限制\",\"动态部署适合用来解决下面等需求：\",\"动态部署：\",\"包\",\"包含独立的中间件，以及一个base的工程，里面可能包含应用的application，应用icon等基础性内容\",\"包括了容器所需的所有系统层面的注入和hack的工具类初始化和校验，容器启动时先校验设备是否支持容器运行，不支持则采取降级并记录原因；\",\"包装后的产物字端如下,大部分内容直接copy自patch.json,需要关心的只有几个字端\",\"区分配置是动态部署还是\",\"即bundle工程\",\"原因\",\"原生是支持配置不同的buildtyp\",\"去初始化\",\"参数\",\"参照多个app之间通信的方式，使用aidl可以作为组件之间进行一定层度通信的方式。\",\"参考\",\"又调用了\",\"及与\",\"及时上线新需求，快速生效。\",\"反射pm\",\"反射并构造bridgeapplicationdelegate的实例\",\"反射执行mrealapplication的attach方法\",\"反编译dex，查看patch出来的代码和修改的是否一致。\",\"发布ap到仓库中\",\"发布版本\",\"另外\",\"另外内置的原生的multidex在dalvik上面性能并不好，atlas内部对其进行了优化提高了在dalvik上面的体验。\",\"另外，根据历史经验，大部分都是使用不规范造成的，为了避免这些奇奇怪怪的问题，大家最好按照atlas工程结构指南以及容器接入\",\"可以减少动态部署的patch包大小\",\"可以很清楚的看到，gradle的配置主要分为三大块，依次是标准的android插件配置、atlas插件的配置，以及依赖管理部分。我们重点看最后两个部分。\",\"可以看到产物merge成功了，反编译budnle.zip（apk），可以验证改动\",\"可以看到，bundleinfo\",\"可以看到，classloader先从bundle上去找的。而loadfrominstalledbundles逻辑如下:\",\"可以看到，firstbundl\",\"可以看到，manifest中的内容大概分为三大块\",\"可以看到，代码虽长，但其实就只干了两件事。\",\"可以看到，函数是从runtimevariables读取字符串，之后解析成对象存储。很明显，这个字符串应该是配置之类的信息。在atals从gradle到apk中，我们提到过，atlas会在编译期间会分析bundle和gradle配置，将一些配置写入runtimevariables中。\",\"可以看到，函数是根据在manifest中登记的provider信息，实例化对象。\",\"可以看到，在atlas框架中，主app只是一个壳子，只是用来配置打包参数的\",\"可以看到，在第4步和第7步两个关键调用之间，第5步调用了函数installcontentproviders,跟进去看一下。\",\"可以看到，这段代码的核心思想就是将系统的pm，替换为我们实现的packagemanagerproxyhandler。我们先不关注packagemanagerproxyhandler的实现，接着看bridgeapplicationdelegate中函数attachbasecontext的实现。\",\"可以认为是一个bundle的activity启动的类加载过程来帮助理解（假设activity所在的bundle已经安装）；\",\"可能的错误操作\",\"可通过属性开关关闭。\",\"各个bundle随时下发\",\"各位，有没有灵光一闪？是的，unittag和srcunittag是有联系的，客户端用来验证patch的合法性，看图:\",\"合并bundl\",\"合并jar中的资源文件\",\"同时dexpatch不修改整个apk版本号，每个bundle提供额外的dexpatch版本号进行监控。\",\"同时动态部署的快速覆盖能力在灰度等场景下可以更快地收到所需的效果。\",\"同时在manifest中增加如下配置：\",\"同样的，其他的sdk（比如weex）也可以通过类似方案在多classloader的apk内部实现自己定制的适配器，规避所有的接口实现需要预先注册的情况，同时也对整体应用的性能带来帮助。\",\"名词解释\",\"后续两个设置用语动态部署打包时的开关设置，其余字段参考配置列表中的使用方式\",\"后续如果要打特殊包就可以通过修改配置的构建参数来控制打具体的包了，如：\",\"后面在activity起来后，如果bundlea对bundleb有依赖关系，那么如果用到了bundleb的class，又会根据bundla的bundleclassloader的dependency去获取bundleb的classloader去加载；\",\"向ui线程提交一个任务，用于回调onfinish\",\"周期\",\"命令\",\"和\",\"和frameworkproperties中的字段完美对应。\",\"和其他的打包中间配置\",\"四大组件支持\",\"回到第10步\",\"回滚标志，该bundle会回滚到dexpatch前的版本\",\"回调预留接口\",\"回过头来，我们看看atlas为了实现上述目的，做了哪些准备工作。在跟进defineandverify函数的实现之前，先看一下atlashacks类中定义的字段\",\"回顾一下第二部分的运行时序\",\"回顾手淘之前的一些故障问题的修复，不管是动态部署还是andfix，其实我们发现几乎所有的故障都可以通过java代码就行修复或者降级，也基本都可以在一个模块内的修改就把某个对应的故障修复掉。因此，以动态部署的技术作为基础，称之为dexpatch的方案应运而生。\",\"因为build.gradl\",\"因为是apk升级的替代方案，动态部署替换版本号的方式就使得是否使用的是动态部署还是apk升级对业务来说完全透明，可以继续按版本号进行逻辑处理，降级等。数据统计以及监控等可以完全兼容。但是如果在故障修复中去贸然升级版本号，虽然直观上可以清楚看到问题修复的覆盖率，但是之前优势就荡然无存了。\",\"在\",\"在android\",\"在atlas之启动过程(二)下中，解释过，application的attach方法最终会调用到attachbasecontext方法。\",\"在atlas启动过程(上)的2.4小节中，为了防止在主dex中找不到bundle中的class,不得已延迟了对provider的加载。而在第5步中，atlas完成了对classloader等关键地方的hook。由于delegateclassloader的存在，此时进行加载provider，是不会出现问题的。\",\"在build.gradle里定义一些基础的变量，比如：\",\"在dalvik的系统上，则会带有vfi\",\"在resolvebundle函数执行周期内，主要完成了两件事\",\"在startup整个函数周期内，做的事情非常之多，重要的是第3、4、6、7和8步。\",\"在updat\",\"在主客工程的build.gradle中添加awb依赖\",\"在主客工程的packageid.properties中声明资源段（也可以通过mtl.tbuildconfig.autopackageid设置自动分配packageid）\",\"在其他进程里运行的插件，需要在什么时候安装？可不可手动控制安装的时机？\",\"在动态部署提示重启前，执行\",\"在发布lib/bundle版本时，带动了其它lib／bundle的版本变化\",\"在多classloader运行机制下，需要事先了解几个要点：\",\"在宿主app里边定义就好了\",\"在开始分析之前，我们要知道，android上动态加载方案，始终都绕不过三个关键的点:\",\"在打包对资源做了一系列处理以后，运行期资源的加载只是在启动加载资源时根据系统读取资源的先后书序把patch包插入到assetsmanager的合适的位置中，assets由于没有资源id，不需要预留，插入assetsmanager的方式类似res的处理，这里不再展开\",\"在打整包的时候需要配置过滤的参数，把so的架构类型指定清楚，要不然就会被裁减掉。具体可以参考\",\"在每个需求迭代过程中，考虑需求的复杂性和每次周期性迭代管理的成本，动态部署参考apk迭代的方式通过统一的集成区进行管理，所以在构建上动态部署tpatch实际上是先有整包构建，再diff出差异的方式，这样的方式规避了混淆、内联等带来的复杂性的问题处理，保证patch对之前版本的完全适用，但是这种方式同时也必不可少的影响patch的构建速度，在对紧急的问题进行修复的关键时期，这个时间可能会是不可接受的。\",\"在看完gradle的配置之后，我们反编译demo的apk，看一下最终生成的结构。\",\"在第2步的2.4部分，对provider进行了处理\",\"在第6行构造出bundle中注册的application对象，之后执行application的oncreate方法。对于appliation来说，似乎还差一个关键的attachbasecontext的入口函数调用，我们接着看构造过程。\",\"在覆盖安装的时候，由于bundle的版本号没变化，没做清理，\",\"在这一步中，开始异步加载bundle，成功后，在主线程中回调onfinished(后面会提及),调用bundleimpl对象的startbundl方法，开始\",\"在需要的时候按需安装，例如一个service是在单独的进程中，只要需要的时候去bind就会触发这个bundle的安装。可以手动控制安装时机，按需就好。\",\"场景定位\",\"基于\",\"基于ap所属的版本(1.0.0)，修改代码,以firstbundle为例，将\\\"origin\\\"修改为\\\"dexpatch\\\"\",\"基于atlas构建后的apk结构如下图，host与普通apk无异，但是manifest和assets会添加一些额外的内容，同时在armeabi目录中会增加若干个bundle构建的产物，取名为string.format(lib%s.so,packagename.replace(\\\".\\\",\\\"_\\\"))；packagename为bundle的androidmanifest中的packagename,这些so都是正常的apk结构，改为so放入lib目录只是为了安装时借用系统的能力从apk中解压出来，方便后续安装\",\"基于atlas的installorupdate和atla\",\"基于gradle的构建插件（包括修改过的aapt内容）；\",\"基于容器提供更新能力的库atlas_update;\",\"基础支持\",\"基线版本\",\"基线的依赖坐标，\",\"增加一层逻辑控制根据不同的参数来修改之前定义变量的值\",\"增量更新修复能力，提供对class、so以及资源的增量更新修复能力，快速升级\",\"处理class，hook\",\"处理provid\",\"处理四大组件\",\"处理资源，hook\",\"外部配置\",\"大家回想一下，在之前atlas之gradle配置中提到过，atlas的gradle插件在编译期搞了很多事情，我们看gradle中的设置\",\"大致步骤\",\"如上图所示，atlas主要分为以下几个层级：\",\"如何发布dexpatch:\",\"如何接入\",\"如何构建不同的包\",\"如何正确使用bundl\",\"如何通知外部登录成功或者失败，除了用系统的广播等机制，能否基于remote的机制更直接地方便地实现该功能呢？后续remotetransaction中会阐述具体的用法。\",\"如果不替换application，那么atlas的初始化就会在application里面，由于基于atlas的动态部署实际上是类替换的机制，那么这种机制就会必然存在包括application及其import的class等部分代码在dalvik不支持部署的情况，这个在使用过程中造成一定成本，需要小心的使用以避免dalivk内部class\",\"如果不需要用到atlas的动态部署功能，不需要依赖atlasupd\",\"如果之前发布过ap版本，可以跳过此节。假设从未发布过ap，按照如下步骤，发布1.0.0的ap\",\"如果同时存在updateinfo和updateinfo_new两个文件,以updateinfo_new为准\",\"如果对不上，说明打包产物错误，下面是两个常见的原因，需要同学们自己做一下排查。\",\"如果开启atlas，必须为tru\",\"如果是直接使用dlopen\",\"如果有bundle更新，则一级目录下以bundle为粒度有多个文件夹，每个文件夹下包含差量的classes.dex，res等\",\"如果有主apk的更新，则会有com_taobao_maindex.so存在，so中包含差量的classes.dex、res等\",\"如果有异常，和第上面一样\",\"如果有异常，返回检查第一步的产物。\",\"如果类本身存在，需要往前排查系统的警告信息，比如在art的设备上会有class被reject的warning信息：\",\"如：\",\"字段\",\"字段是一堆json字段，解析后格式bundleinfo,保存着bundle的信息。\",\"字段解释\",\"存放动态部署后的版本变化内容，以及每次部署发生更新的bundle的版本，依赖等信息\",\"完成之后，回到第8步，执行optdexfile方法。\",\"官方demo\",\"官方文档\",\"官方的\",\"定义同一个so的依据是全路径完全相同且so内容相同\",\"定位\",\"实例\",\"实例applic\",\"实例化app工程中指定的mrealappl\",\"实现host、bundle独立开发、调试的功能，bundle独立\",\"实现完整的组件生命周期的映射，类隔离、资源共享等机制\",\"实现很简单，读取frameworkproperties上的静态属性字段，接着跟进。\",\"实现机制\",\"实现的机制\",\"实现类\",\"实线箭头表示运行在主线程\",\"实际上是demoapplication,即app工程在manifest中指定的启动路径。\",\"实际上这四个级别的函数调用，对应之前定义的字段，为这些字段进行赋值。\",\"客户端可以识别的接口，对打包产物包装处理过的配置\",\"客户端并不能直接识别打包产生的\",\"客户端拿什么属性\",\"客户端检查\",\"容器接入\",\"容器接入，修改app模块的gradle文件\",\"容器框架\",\"宿主和bundle的关系？\",\"宿主就相当于android\",\"宿主本身对于被调用方来说也是一个远端的对象，所以宿主自己可以使用iremote，同时将自己注册给remote对象，remotefragment、remoteview、remotetransactor的基类iremotecontext实现了提供了registerhosttransactor接口，在remotefactory回调时将自身的iremote实现注册进去\",\"宿主的概念，所有的bundle可以直接调用host内的代码和资源，所以host常常集合了公共的中间件，ui资源等。host和bundle的依赖关系如下图所示：\",\"对于aidl、servicehub以及remote的机制，可能还存在临时无法按照规范进行解耦的情况。目前除了静态依赖外，也可以考虑使用动态依赖的方式,用来解决在具体使用到某个功能时候再去挂载相应的依赖模块，不过bundle依赖始终打破了bundle之间的边界，需要谨慎使用\",\"对于gradl\",\"对于js方法的调用方，则通过如下方法实现：\",\"对外接入层:atlasbridgeapplication是atlas框架下apk的真正application，在基于atlas框架构建的过程中会替换原有manifest中的application，所以atlas没入的接入并不存在任何初始化代码，构建脚本完成了接入的过程。atlasbridgeapplication里面除了完成了atlas的初始化功能，同时内置了multidex的功能，这样做的原因有两个：\",\"对应bundle工程，用于将module转化成atlas所需要的bundle依赖，不会侵入正常的开发环境\",\"对应前面打包产物updat\",\"对应步骤\",\"导入demo后，android\",\"将bunde的资源进行分段\",\"将bundle中的资源添加到resource上\",\"将流程分为三大部分\",\"小结\",\"就会使用新的值了\",\"就是\",\"属性开关是atlas.manifestoptions.removecustompermiss\",\"工程打包的gradl\",\"工程期\",\"已有activity的manifest信息暂时不支持更改\",\"常见问题\",\"常规的打包配置，会将依赖代码打入到dex中去\",\"常规编译产生的清单数据，包括app工程自身的代码和compile依赖的代码\",\"应用plugin\",\"建议修改plugin，更好的支持aar传递依赖等问题（可以采用原生com.android.library）\",\"建议值设置为false，\",\"建议把调用相关的调用so的代码和so本身单独封装成一个公共的模块，否则如果存在so反调java的情况，则只能调用到loadlibrary的classloader范围内的java类的代码\",\"开关\",\"开发期\",\"开发期我们期望我们的基线足够稳定，这样可以避免动态部署基线不兼容的问题\",\"开发精力所限，因为我们的淘宝app就是没有变种的架构，额外的功能会带来很多适配的麻烦和风险\",\"开启atlas容器功能\",\"开启atlas插件的开关，在编译期会做很多事情\",\"引用atlas插件及依赖仓库，修改工程gradle文件\",\"引用插件及依赖仓库\",\"当两个条件都满足时，执行bundle的安装和optdexfile操作。\",\"当前代码和参考ap(1.0.0)diff的产物，是个zip文件，解压开就是diff的代码。\",\"当前插件下的实践\",\"当前的支持度\",\"当然不是\",\"待更新\",\"很多大型的app不合理的初始化导致用multidex分包逻辑拆分的时候主dex的代码就有可能方法数超过65536，\\u0002atlasbridgeapplication与业务代码完全解耦，所以拆分上面只要保证atlas框架在主dex，其他代码无论怎么拆分都不会有问题；\",\"很快\",\"快\",\"快速排查三连\",\"总结\",\"感兴趣的同学可以自行验证。\",\"我们一般的做法就是通过打包参数来控制不同的参数值，\",\"我们也一个来看。\",\"我们也存在被使用方在某些场景下需要主动调用或者按规律定期callback宿主的情况，一种方式是使用宿主掉用远端时传进来的iresponse接口多次回调，但是如果涉及到复杂的情况就需要用到下面的方法：\",\"我们取一个动态部署的tpatch包，能够看到如下内容：\",\"我们接着往下看\",\"我们比较倾向于用一个比较干净的壳子工程来作为容器架构下的打包工程,称之为main_builder，main_builder建议只存在androidmanifest.xml、构建文件及部分资源内容。\",\"我们比较倾向于用一个比较干净的壳子工程来作为容器架构下的打包工程，这个工程建议只存在androidmanifest.xml和构建的文件及部分资源内容，manifest文件用于单独管理apk的icon，版本号，versioncode等；构建文件管理版本依赖；这里我们取名打包工程等名字为apk_builder;\",\"我们看一下atlasbridgeapplication中的相关方法\",\"我们看一下反编译后的manifest\",\"我们都知道，app的入口是application，那么atlas的入口application是什么呢，看一下app模块中manifest中的定义\",\"或者\",\"或者本次修改隐含带入了其它改动。\",\"或者直接在配置的地方加上判断逻辑，使用特殊的配置\",\"所谓反常即为💊，直接看反编译后的代码\",\"手淘组件化框架的前世今生和未来的路\",\"打andfix\",\"打patch\",\"打动态部署\",\"打包\",\"打包bundle等等\",\"打包产物检查\",\"打包过滤\",\"打开updat\",\"打开产物中的dependencydiff.json的文件，这个文件记录了本次改动相对ap的依赖变化信息\",\"执行app工程定义的demoapplication的oncreate方法。\",\"执行bridgeapplicationdelegate的attachbasecontext方法\",\"执行bridgeapplicationdelegate的attachbasecontext方法。\",\"执行到这里时，atlas框架的准备工作完成，接下来，就是整个框架的初始化了。\",\"扫码加入atlas钉钉交流群\",\"找不到。\",\"技术原理\",\"拆分\",\"指向\",\"指定bundle自身依赖so的路径\",\"指定依赖bundle所依赖so的路径\",\"指定参照的版本，生成dexpatch包\",\"指定第一个需要启动的bundle，在atlas框架初始化完毕后，会执行这里这里配置bundle的代码。\",\"指定远程bundl\",\"按照文档，触发patch更新操作，观察本地上两个地方\",\"捋清楚这几个参数之后，往下看atlas框架初始化实现\",\"换classload\",\"换instrumentatio\",\"接上篇\",\"接入可参考atla\",\"接入指引\",\"接入文档，\",\"接着执行\",\"接着看依赖配置部分\",\"提供gradle插件，简化开发者接入的负担。\",\"提前执行的方法，格式是\",\"提取出来以多dex的方式追加到libcom_taobao_maindex.so中，如果本身是多dex机制的，那么会将多个子dex全部追加进去，patch里面的classes.dex保持不变，source里面的dex的序列号往后偏移一位（classes.dex\",\"插件\",\"插件化的核心思想其实是埋坑机制+借尸还魂\",\"插件，\",\"插入前执行的代码除外）\",\"操作以及管理整个bundle的生命周期；\",\"支持\",\"支持版本\",\"支持运行bundle中的四大组件\",\"收集了所有provider的信息，然后调用installprovider函数\",\"改了几个类这里就会对应diff出几个，不会多也不会少。\",\"改动模块信息\",\"故障排查\",\"数据中可以看出bundle动态部署过程bundle的依赖关系允许发生变更，同时动态部署也有一定的限制，这个会在后面单独进行说明\",\"整个工程的依赖树\",\"整个打包的\",\"整个第三部分运行在\",\"整包(apk)\",\"文件名为\",\"文件，需要服务端做一些包装。\",\"文档\",\"新版本\",\"新的机制\",\"新的组件之间的重用及通信策略延续了aidl免注册的方式，同时解决了跨classloader情况下ui复用的问题。新的方式将重用类型归为remotefragment、remoteview、remotetransaction三种类型。\",\"方法尝试获取目标view并进行操作，remoteview应该被当做view而不是viewgroup，与目标view的通信应该通过remote的机制进行\",\"时序图中的第4步，即bridgeapplicationdelegate的attachbasecontext方法中，，做了一个接口回调。\",\"是true，这个在gradle中可配\",\"是一个json格式的文件，里面记录bundle的信息以及依赖关系，dependency字段用于标识该bundle所依赖的bundle，如果a依赖b，b依赖c，则触发的abundle安装时，实际的安装顺序为c\",\"是内置bundl\",\"是否启用atla\",\"是否需要使用被依赖bundle的资源\",\"是容器一个最重要的功能。基于此:\",\"是的，支持2.3.x\",\"普通apk的更新的过程为构建\",\"更新\",\"替换applic\",\"替换pm\",\"替换点\",\"最后确认一下以secondbundle的代码，\",\"最后，大概看一下delegateclassloader加载bundle中class的过程。\",\"最底下的hack工具层：\",\"最简配置\",\"有两个参数需要注意一下\",\"有任何的建议和问题请在github上提issue给我们，我们会尽快回复，同时高频的会更新的faq文档中\",\"有故障的业务可以及时修复或者回滚\",\"杀掉java.exe进程重新编译（window\",\"来看bundleimpl的构造函数\",\"构建\",\"构建apk\",\"构建产物：\",\"构建动态部署\",\"构建基线包，建议开启，否则后面的patch包无法进行\",\"构建完的apk在host的assets目录下，会有个bundleinfo\",\"构建定制包\",\"构建时会与之前版本的dex进行字节码级别的diff，生成tpatch包。最终下发到用户手机的patch仅包含变化class组成的dex和更改或者新增的资源文件\",\"构建标准包\",\"构建特殊包\",\"构建的产物apk\",\"构建的基线包，\",\"构建速度\",\"构建速度：\",\"构造bridgeapplicationdelegate对象\",\"果然，每个bundle的代码都是各自打包的。\",\"查找bundl\",\"查找bundle依赖的bundle内的class\",\"查找主apk中的class\",\"查看android.taobao.atlas.framework.frameworkproperties的field\",\"查看merge的产物是否存在，以firstbundle为例，maindex同理。\",\"查看各自的map信息\",\"根据上面的classloader关系，先去parent里面加载class；\",\"根本原因\",\"格式很简单\",\"框架原理\",\"概述\",\"正是因为其比较全面的能力，我们发现动态部署在故障修复方面存在其不足的地方：\",\"步的启动过程。\",\"每一次补丁的发布都是相当于一次版本的升级，通过版本号的变更来决策补丁的下发\",\"每个bundle在生成的时候，需要为其分配独立的packageid，用以使其保证每个bundle的资源id全局唯一；资源id的可分配区间为[0x21,0x7f),0x1x为系统保留，0x7f为主apk使用，0x20之前的发现miui里面内部已使用，所以目前我没选择这个区间作为bundle的packageid分配区间\",\"每个bundle基于自身的问题进行dexpatch的发布，构建速度相比原来的方式有了大幅度提高，只需要针对单个bundle进行构建从而diff出差异即可。\",\"每个bundle的生命周期如下图所示：\",\"每个dexpatch只能修改一个bundle(主dex整个算一个bundle)，且修改的代码必须向前兼容。（不如说主dex被bundle依赖，则主dex的dexpatch修改不能引起原来bundle的方法调用出现问题）\",\"每个业务按照各自的故障情况进行dexpatch的构建，产出对应的patch产物和json信息，发布时平台应该汇总对应版本当前release的所有patch内容，整合json信息，进行下发\",\"每个模块有一个dexpatchversion的概念客户端会判断bundle的dexpatchversion,判断该bundle是否需要做merge通常由服务端进行管理\",\"比如修改了firstbundl\",\"比如在demo中\",\"比如在demo中，firstbundle、secondbundle、publicbundl\",\"比如在demo中，配置了以下打包设置\",\"比对版本\",\"没什么内容，直接跟进delegatepackagemanager的函数实现\",\"没有异常，说明本次动态部署生效。\",\"注意class和methodname都不能混淆，且方法实现是\",\"注意图中的箭头\",\"注意尽量不要指定\",\"注意点：主apk的差量与bundle的差量目前采取不同的策略，主apk永远是与基线版本做差量；而bundle是更上一个版本做差量：比如从6.1动态部署到6.2再动态部署到6.3，则6.3中主apk的差量是6.3主apk的集成内容和基线（6.1）主apk中的内容diff出差量；6.3中bundle的差量则是与上一个版本进行diff，如果是6.2的版本去请求动态部署的tpatch，则tpatch中的bundle的差量是6.3与6.2的bundle进行diff所得，如果是6.1版本去请求6.3的动态部署的tpatch，则bundle的差量是6.3与6.1的bundle进行diff所得\",\"注意点：虽然启动方式类似与普通app，先执行attachbasecontext，再执行oncreate，不过有两个不同点需要引起注意：\",\"涉及改动确认，配置中的diff信息和我们的改动一致（两个部分，firstbundle和maindex）\",\"涉及版本确认，baseversion(1.0.0),\",\"混淆后atlas进度条消失\",\"添加运行库依赖\",\"清空\",\"灵活度\",\"然后，根据bundlename，去查询bundle加载后的结构体\",\"版本\",\"版本号：\",\"独立打包，用于后续的动态下发\",\"现在还可以选择的bundle间代码复用的方案\",\"现在，在看defineandverify函数的实现\",\"现状\",\"生成一些class，记录bundle的关键信息\",\"生成基线版本\",\"生成的patch文件在\",\"生效\",\"生效速度\",\"生效速度：\",\"用于host工程，用于设置对bundle的依赖和其它atlas的功能\",\"用于配置主apk的依赖及控制构建参数\",\"由7.3可知，mrealapplication实际上就是demoappl\",\"由之前的容器的运行机制可以得知，bundle动态部署后对容器来说没有任何变化，还是按需的load\",\"由于class在bundle里面，所以pathclassloader内查找失败，接着delegateclassloader根据bundleinfo信息查找到classloader在bundle中（假设为bundlea）；\",\"由于demo没有服务端，所以在app/dexpatchwraper.gradle中，对patch.json内容做了一个包装，简单模拟服务端的逻辑。\",\"由于nativ\",\"由于不同bundle的java代码使用相同的so导致的依赖：\",\"的manifest部分\",\"的关系\",\"的初始化过程。\",\"的区别之一\",\"的呢？\",\"的实现。\",\"的版本变化和改动一致，没有问题。\",\"的的manifet部分\",\"的能力问题，\",\"的资源段没有发生变更的资源，如果有发生了变更，且之前有这个资源，就会在原有的资源id分配过去，同时新的资源文件打入patch包或者新的资源文本写入arsc，如果是新增的资源，则使用预留的资源段进行分配。整个替换过程如下图所示：\",\"的配置项，表示apk的bunde依赖，即apk是由这些bundle共同组成。\",\"的，\",\"盗用一张老大的图\",\"目前是有这个限制。如果非得在里面调用，建议改为static方法。\",\"目录名为记录的tag1x6r8iuzs90ff,cd\",\"目标fragment与sampleactivity之间还是保持完整的隔离，所以目标fragment也无法获取宿主的引用，所以如果目标fragment需要与sampleactivity发生通信，则也要遵循remote的通信机制\",\"直接反射调用mbridgeapplicationdelegate的oncreate方法.\",\"看函数名，是针对art和dalvik工具类进行初始化。\",\"看样子，是demoappl\",\"真的是这样的吗？\",\"第4行代码读取provider数据，如果有provider信息的话，则在第6行从系统删除，让系统认为apk并没有申请任何provider。\",\"第5、6步，主要是各种逻辑判断，之后辗转调用到7步。直接看第7步deliverytask的函数实现。\",\"第一点，依赖变动\",\"第一部分\",\"第三点，diff代码验证\",\"第三部分\",\"第二点，验证配置文件\",\"第二行函数将bundle的信息加入到已加载的列表中。\",\"第二部分\",\"等目录，每次加载bundle的时候选取最高可用版本进行载入。考虑bundle的回滚功能和对空间占用的影响，目前容器内最多保留两个最近可用版本。\",\"简介\",\"简化了大部分代码，只关注核心逻辑。代码读取runtimevariables上的字段autostartbundles,这个值是在gradle中配置的com.taobao.firstbundle，然后开始异步加载firstbundl\",\"简单来说，动态部署是针对apk级别的动态升级，dexpatch是针对bundle级别的动态修复(主dex可以认为是一个bundle)\",\"简单起见，只是每次都把dexpatchversion+1，版本号缓存在根目录下的dexpatch.verion文件中。\",\"类似classloader，loadedapk中的resources被替换成atlas内部的delegateresources,同时在每个bundle安装的过程中，每个bundle的assetspath会被更新到delegateresources的assetsmanager中；每个bundle的资源特征如图可知：\",\"类似osgi规范里面bundle（组件）的概念，每个bundle有自己的classloader，与其他bundle相隔离，同时atlas框架下bundle有自身的资源段（packageid，打包时aapt指定）；另外与原有osgi所定义的service格式不同之处是atlas里面bundle透出所有定义在manifest里面的component，随着service，activity的触发执行bundle的安装，运行。\",\"类似，remoteview提供更细粒度的bundle间的ui复用。\",\"类加载机制\",\"类型\",\"类需要在两个bundle均可访问的主apk或者公共bundle中。\",\"系统进程出现）cmd:taskkil\",\"线程中\",\"组件中有jar包和so依赖，awb的产物中也有，为什么在宿主中生成的so产物解压就没有了呢？\",\"组件化和插件化\",\"经常有同学在答疑群上提出疑问为什么动态部署不生效？，然后就是一通排查。由于是远程交流，代价实在是太高。这篇文章主要是和大家分享一下动态部署排查的一些经验，希望能够帮助大家快速定位、解决问题。\",\"经过手淘打包插件构建以后，主apk里面的所有class，interface都插入了一段代码：类似下图。原因是android构建的时候会有preverify的过程，如果class所引用到的class均和class自己在同一个dex内部，则会被打上preverify的标记。然后在运行期的时候如果打上这个标记的class，在载入时不需要经过verify已提高加载效率，但是运行到方法时会校验依赖的class是否跟构建时一致和class自身处于同一个dex，如果不一致则会抛出preverify的错误。而手淘的动态部署策略必然会新生成一个dex，那么如果遇到是preverify的class的时候就会出错。所以目前手淘的策略是在编译期给每个class引用到一个不存在的class以解除preverify的限制（具体preverify的校验过程可以阅读android源码）\",\"结合app工程gradle的配置，我们发现以compile开头的依赖(middleware、utils、update),都是正常将java代码打入dex中。而以budlecompile开头的依赖(firstbundle、secondbundle)，他们的代码并没有在dex中。\",\"给这段代码点个赞，非常的干净和清晰。代码定义了atlas框架所需要hook的所有的类、方法、属性等等字段。\",\"编译\",\"缺陷\",\"而在\",\"能够让动态代码中的四大组件在android上正常跑起来\",\"膨化xml，则xml里面如果有richview，则务必确保layoutinflater持有的context的classloader可以load到该richview，假设context来自于a\",\"自动生成bundle的packageid\",\"自启动bundle可以在任何线程中执行，不过bundle的appl\",\"自启动的bundle列表，\",\"自启动的bundle是在哪个线程中啊，不是主线程吗？\",\"自定义buildtyp\",\"自定义初始化入口，这个类需要实现atlasprelauncher接口，回调时机是在atlas对系统进行hack之后，atlas框架开始初始化之前。\",\"自身内部的class\",\"至此，atlas启动过程的分析完成。\",\"至此，接入完成，不需要接入方调用任何初始化函数，详细的文档参\",\"范例\",\"获取merge的数据源：patch信息来自于bundle在下载的tpatch包中的内容，用于merge的source来自于当前设备的文件系统中，可能来自于已经安装过的bundle（storage），可能还没有安装（apk或者lib目录下）\",\"虚线箭头表示运行在handlerthread中\",\"虽然每个bundle的manifest都声明了自己的packagename，但是在aapt过程中，arsc文件里面所有bundle的packagename均被统一为hostapk的package，比如在手淘内就都是com.taobao.taobao；这样改的目的是为了解决在资源查找中一些兼容性问题；\",\"被依赖的bundle的packagenam\",\"规则少了\",\"解压tpatch\",\"解释执行\",\"触发时机\",\"设想一下，如果一个activity引用了5个来自不同bundle的remotefragment，那么相当于这个activity内嵌了5个embeddactivity；那如果引用了5个来自同一个bundle的remotefragment呢？\",\"设置bundle运行时依赖\",\"详细介绍参照\",\"说明\",\"请接入前仔细阅读接入文档.\",\"请问\",\"调用demoapplication的attachbasecontext方法\",\"调用loadlibrary(或者load)在native真正dlopen\",\"调用mrealapplication.oncreate方法\",\"调用了call函数\",\"负责bundle的安装\",\"资源加载机制\",\"资源处理实现说明\",\"跟服务器比对获取补丁？\",\"跨bundle的代码重用和通信\",\"辗调用，会执行到第2步execstartchildactivityinternal方法中\",\"运维期\",\"运行三个阶段，放一张图捋一下关系。\",\"运行期\",\"运行期按需动态加载。bundle可以调用host的代码和资源，同时bundle之间允许存在依赖关系。\",\"运行期文件结构\",\"还是ap有问题\",\"还是查看这两个文件，updateinfo的内容有没有变，或者storage下merge后bundle的产物是否存在\",\"这两篇文章提到的规范，来组织工程结构。\",\"这个部分牵涉开发\",\"这些字段进行初始化赋值工作。\",\"这些是基于我们atla\",\"这几个函数的代码并不复杂，是对定义的class、field、method和contructor\",\"这是因为打包插件默认开启了去除自定义权限。\",\"这样可以避免主进程一起来就去startbundle导致启动时间过长\",\"这样如果我们打包加了\",\"这段代码，就是对系统关键节点进行了hook，具体的hook实现这里就不贴出了，如果感兴趣，可以参考demo源码以及田维术的blog，如何hook，以及为什么在这里hook，在文章中都讲的非常清楚。\",\"这种使用方式适用于本身具有特定接口定义的sdk中，比如在手淘里面的windvane和weex。\",\"这种问题属于宿主中的class引用了bundle中的class，理论上是可以支持的，但是在atlas的框架中是不推荐(也没不支持)这种反向的依赖关系。\",\"这部分内容在编译期已经写到app的manifest中了，这也是\",\"这里requestremote里面直接传入remotetransactor可能对开发者来说还有点晦涩，sdk开发者也可以尝试直接对remotetransactor以及iremote进行封装，比如改造成更为直观的basejsmanager和basejsplugin\",\"这里也可以修改firbundle依赖的某个aar的版本。一句话，你要通过版本号告诉编译器，我这个bundle的代码变了\",\"这里多提一句，在四大组件的处理上，atals与插件化有着很大的差异。\",\"这里有两个判断条件\",\"这里有两个注意点提及一下以加深理解：\",\"这里粗略介绍下普通apk（也就是主apk）class，so库加载入口\",\"这里要强调一下，代码的修改要内聚。假设a依赖b,修改时，只改a或b自身的代码，不支持修改a与b之间的接口。\",\"进入app目录下\",\"进去\",\"远程bundl\",\"远程bundle，远程bundle只是apk构建时并未打到apk内部，而是单独放在了云端；同时远程bundle的限制条件是第一次被触发的前提是bundle内的activity需要被start，此时基于atlas内的classnotfoundinterceptorcallback可以进行跳转的重定向，提示用户下载具体bundle，待用户确定后进行异步下载同时完成后再跳转到目标bundle（此部分代码由于涉及下载及ui展示等内容并未包含在开源仓库中，有需要可以根据classnotfoundinterceptorcallback自行实现）\",\"远端如何主动调用使用方的接口\",\"远端本身已经有封装过具体的接口，则可以实现getremoteinterface返回具体的接口的实现。这种方式类似之前的aidl的方式，前提是interfac\",\"通常情况下apk_builder除了主apk的androidmanifest.xml之外，接入atlas后，main_builder将会包含以下内容：\",\"通常来说都是改了代码，但是没有变更依赖lib/bundle的版本号\",\"通常来说，如果打包产物如果没有问题，动态部署一般都是可以正常生效的。\",\"通过layoutinflat\",\"造成该问题的原因比较多，排查步骤第一个先检查exception的源头是不是classnotfoundexception，然后反编译排查类确实是否存在；\",\"遵循代码规范可以有效避免在运行时遇到难以排查的问题。\",\"那么在远端需要使用的时候，则可以通过hosttransactor（前面图中未标出）得到宿主的iremote的实现并传递相应的信息。\",\"那么现在理想中的版本迭代的情况应该是如下这种：\",\"那么这个prelaunch的字段在哪里定义的呢，我们反推一下。\",\"那么问题来了，有些provider是存在于bundle中的，主dex中并不存在。如果不处理，在这里程序会因为classnotfind崩溃。所以这里要先清除掉provier的信息，延迟加载。\",\"那么，bundle的代码在哪里呢？\",\"部分\",\"部署patch\",\"配置\",\"配置bundle的packageid,以保证资源段独立（也可以通过mtl.tbuildconfig.autopackageid设置自动分配packageid）\",\"配置bundle的依赖关系\",\"配置列表\",\"配置参数\",\"配置名称\",\"里可以写很多的逻辑，所以配置也可以变的很灵活。\",\"里的配置基本完成。\",\"里面包含\",\"重启前\",\"重启后\",\"重启应用,toash显示\",\"错误\",\"问答\",\"问题：remotefrag\",\"限制：\",\"除atlasbridgeapplication之外，接入层对外提供了部分工具类，包括主动instal\",\"除了依赖树和配置参数之外，额外的产物有：\",\"随包发布但是不打入dex的代码\",\"集成升级\",\"集成框架后就只有use\",\"需要去除的原生multidex初始化\",\"需要在原来的基础上实现iremote接口，iremote来自atlas容器的内部实现，暂时还未从容器中拆分出差，这也意味着业务方需要增加对atlas的依赖。**iremote实现的两个接口会在文章后面解释**\",\"需要打入dex的代码\",\"需要注意的是，第二部分整体是运行在\",\"需要添加依赖的bundl\",\"需要说明的是，gradle插件不会侵入正常的开发流程，host和bundle都可以独立的进行开发和调试。\",\"预处理manifest，\",\"额外的配置\",\"首先appli\",\"首先创建了一个bundlearchive对象，bundlearchive持有bundledir和inputstream的引用，用来做dexopt的(\",\"首先加载dalvikpatchso,用途：\",\"首先是读取manifest中的配置数据multidexenable和mrealapplicationname，这两个数据也是在编译期由atlas插件写到manifest中的。\",\"首先有个构建整体apk工程apk_builder,里面管理着所有的依赖（包括atlas）及其版本，apk_builder本身可能不包含任何代码，只负责构建使用\",\"首先检查打包的产物，按照历史经验，90%的问题都是因为打包产物不对造成的。\",\"首先要明确一点，bundle中的application不是最终在android系统上执行的application。我们之所以保留bundl\",\"首先，根据componentname即com.taobao.secondbundle.secondbundleactivity,查询bundle的名称。在atlas启动过程(下)中，我们知道atlasbundleinfomanager中存储了几乎所有bundle的信息，所以返回\",\"首先，根据类名加载对应的class，之后反射执行applciation的attach方法。\",\"首先，确保手机存储卡容量足够(至少100m吧)，然后在进行下面的排查步骤。\",\"首先，贴一张反编译后的manifest\",\"默认情况下，bundle只往外暴露了android原生的component,运行期按需加载。某些特殊的bundle（比如说监控性质的）本身与其他代码完全独立，且又需要在某个时间点启动运行的，可以通过如下方式去启动：\",\"（2.0.0~2.1.0）\",\"，\",\"，nativelibdir的\",\"，用途\",\"：\",\"：通过预先在manifest中预留n个组件坑，在runtime时，通过“借尸还魂”实现四大组件的运行。\"],\"pipeline\":[\"stopWordFilter\",\"stemmer\"]},\"store\":{\"./\":{\"url\":\"./\",\"title\":\"Introduction\",\"keywords\":\"\",\"body\":\"Atlas   Browse this in English \\n \\n\\n扫码加入atlas钉钉交流群\\n\\n\\n\\n\\n简介\\nAtlas是伴随着手机淘宝的不断发展而衍生出来的一个运行于Android系统上的一个容器化框架，我们也叫动态组件化(Dynamic Bundle)框架。它主要提供了解耦化、组件化、动态性的支持。覆盖了工程师的工程编码期、Apk运行期以及后续运维期的各种问题。\\nAtlas对app的划分如下图所示:\\n\\n\\n\\n\\n拆分\\n定位\\n说明\\n\\n\\n\\n\\nhost\\n基础支持\\n包含独立的中间件，以及一个Base的工程，里面可能包含应用的Application，应用icon等基础性内容\\n\\n\\nbundle\\n业务层基本单位\\n运行期按需动态加载。bundle可以调用host的代码和资源，同时bundle之间允许存在依赖关系。\\n\\n\\n\\n\\n与插件化框架不同的是，Atlas是一个组件框架，Atlas不是一个多进程的框架，他主要完成的就是在运行环境中按需地去完成各个bundle的安装，加载类和资源。\\n\\nAtlas提供哪些功能\\n从app的开发期--运行期--上线后的运维期，Atlas提供了一整套完整的支持\\n\\n\\n\\n周期\\n说明\\n\\n\\n\\n\\n工程期\\n实现host、bundle独立开发、调试的功能，bundle独立\\n\\n\\n运行期\\n实现完整的组件生命周期的映射，类隔离、资源共享等机制\\n\\n\\n运维期\\n增量更新修复能力，提供对class、so以及资源的增量更新修复能力，快速升级\\n\\n\\n\\n以一个app的开发的生命周期为例，参见 demo\\n开发期\\n提供gradle插件，简化开发者接入的负担。\\n需要说明的是，gradle插件不会侵入正常的开发流程，host和bundle都可以独立的进行开发和调试。\\n\\n\\n\\nplugin\\n说明\\n\\n\\n\\n\\ncom.taobao.atlas\\n用于host工程，用于设置对bundle的依赖和其它atlas的功能\\n\\n\\ncom.taobao.atlas.library\\n对应bundle工程，用于将module转化成atlas所需要的bundle依赖，不会侵入正常的开发环境\\n\\n\\n\\n运行期\\n\\n\\n\\n功能\\n说明\\n\\n\\n\\n\\n四大组件支持\\n支持运行bundle中的四大组件\\n\\n\\n共享代码资源\\nbundle可以直接使用host中的代码和资源\\n\\n\\nbundle按需加载\\n业务需要时，才会去加载对应bundle中的代码和资源\\n\\n\\n远程bundle\\n减少包体积。不常用的bundle放在云端，需要时按需下载。当用户设备空间紧张时,可以清理掉一些长期不用的组件\\n\\n\\n解释执行\\n为了降低用户等待时间，Atlas框架在dalivk系统上首次使用bundle时关闭了verify，在ART系统上首次使用时关闭了dex2oat走解释执行。同时后台通过异步任务走原生的dexopt过程，为下次使用做好准备\\n\\n\\n\\n运维期\\n动态部署 是容器一个最重要的功能。基于此:\\n\\n业务可以灵活发布自己的需求\\n有故障的业务可以及时修复或者回滚\\n同时动态部署的快速覆盖能力在灰度等场景下可以更快地收到所需的效果。\\n\\n\\n\\n\\n功能\\n说明\\n\\n\\n\\n\\n动态部署\\n构建时会与之前版本的dex进行字节码级别的diff，生成tpatch包。最终下发到用户手机的patch仅包含变化class组成的dex和更改或者新增的资源文件\\n\\n\\ndexpatch\\n以动态部署技术方案为基础，可以看作是动态部署的子集，专注于单个bundle的故障修复。由于做的事小而精，所以编译构建速度、线上生效速度都是远远快于动态部署\\n\\n\\n\\n如何接入\\n我们比较倾向于用一个比较干净的壳子工程来作为容器架构下的打包工程,称之为main_builder，main_builder建议只存在AndroidManifest.xml、构建文件及部分资源内容。\\n\\nmanifest：文件用于单独管理apk的icon，版本号，versioncode等；\\ngradle：用于配置主apk的依赖及控制构建参数\\n\\n以 demo 为例\\n\\n引用Atlas插件及依赖仓库，修改工程gradle文件\\n buildscript {\\n     repositories { jcenter()}\\n     dependencies {\\n         classpath \\\"com.taobao.android:atlasplugin:2.3.3.beta2\\\"\\n     }\\n }\\n\\nbundle接入，修改bundle的gradle，参见demo中的firstbundle配置\\n apply plugin: 'com.taobao.atlas.library'\\n\\n atlas {\\n     //声明为awb 即bundle工程\\n     bundleConfig { awbBundle true }\\n }\\n\\n容器接入，修改app模块的gradle文件\\n apply plugin: 'com.taobao.atlas.application'\\n dependencies {\\n     //核心sdk\\n     compile('com.taobao.android:atlas_core:5.0.0@aar') {\\n          transitive = true\\n      }\\n      //如果不需要用到atlas的动态部署功能，不需要依赖atlasupdate\\n      compile 'com.taobao.android:atlasupdate:1.0.8@aar'\\n\\n      //设置bundle依赖\\n      bundleCompile project(':firstbundle')\\n  }\\n  atlas {\\n   atlasEnabled true\\n   //...\\n}\\n\\n\\n至此，接入完成，不需要接入方调用任何初始化函数，详细的文档参 接入文档，\\nSupport\\n支持版本 4.0 to 7.0. \\n\\n\\n\\nRuntime\\nAndroid Version\\nSupport\\n\\n\\n\\n\\nDalvik\\n2.2\\nNot Test\\n\\n\\nDalvik\\n2.3\\nNot Test\\n\\n\\nDalvik\\n3.0\\nNot Test\\n\\n\\nDalvik\\n4.0-4.4\\nYes\\n\\n\\nART\\n5.0\\nYes\\n\\n\\nART\\n5.1\\nYes\\n\\n\\nART\\nM\\nYes\\n\\n\\nART\\nN\\nYes\\n\\n\\n\\n其它\\n\\nFAQ \\n文档\\nAtlas-手淘组件化框架的前世今生和未来的路\\n\\n\"},\"principle-intro/Runtime_principle.html\":{\"url\":\"principle-intro/Runtime_principle.html\",\"title\":\"框架原理\",\"keywords\":\"\",\"body\":\"容器框架\\n>\\n\\n如上图所示，atlas主要分为以下几个层级：\\n\\n最底下的hack工具层：\\n包括了容器所需的所有系统层面的注入和hack的工具类初始化和校验，容器启动时先校验设备是否支持容器运行，不支持则采取降级并记录原因； \\n\\nBundle Framework 负责bundle的安装 更新 操作以及管理整个bundle的生命周期；\\n\\nruntime层：主要包括清单管理、版本管理、以及系统代理三大块，基于不同的触发点按需执行bundle的安装和加载；runtime层同时提供了开发期快速debug支持和监控两个功能模块。从Delegate层可以看到，最核心的两个代理点：一个是DelegateClassLoader：负责路由class加载到各个bundle内部，第二个是DelegateResource：负责资源查找时能够找到bundle内的资源；这是bundle能够真正运行起来的根本；其余的代理点均是为了保证在必要的时机按需加载起来目标bundle，让其可以被DelegateClassloader和DelegateResource使用\\n\\n对外接入层:AtlasBridgeApplication是atlas框架下apk的真正Application，在基于Atlas框架构建的过程中会替换原有manifest中的application，所以Atlas没入的接入并不存在任何初始化代码，构建脚本完成了接入的过程。AtlasBridgeApplication里面除了完成了Atlas的初始化功能，同时内置了multidex的功能，这样做的原因有两个：\\n\\n很多大型的app不合理的初始化导致用multidex分包逻辑拆分的时候主dex的代码就有可能方法数超过65536，\\u0002AtlasBridgeApplication与业务代码完全解耦，所以拆分上面只要保证atlas框架在主dex，其他代码无论怎么拆分都不会有问题；\\n如果不替换Application，那么atlas的初始化就会在application里面，由于基于Atlas的动态部署实际上是类替换的机制，那么这种机制就会必然存在包括Application及其import的class等部分代码在dalvik不支持部署的情况，这个在使用过程中造成一定成本，需要小心的使用以避免dalivk内部class resolve机制导致部分class没成功，替换以后该问题得到最好的解决，除atlas本身以外，所有业务代码均可以动态部署；\\n\\n\\n\\n另外内置的原生的multidex在dalvik上面性能并不好，atlas内部对其进行了优化提高了在dalvik上面的体验。\\n除AtlasBridgeApplication之外，接入层对外提供了部分工具类，包括主动install bundle，start bundle，以及获取全局的application等各种功能。\\nBundle生命周期\\n每个bundle的生命周期如下图所示：\\n>\\n\\nInstalled    bundle被安装到storage目录\\nResolved  classloader被创建，assetpatch注入DelegateResoucces\\nActive     bundle的安全校验通过；bundle的dex检测已经成功dexopt(or dex2oat)，resource已经成功注入\\nStarted  bundle开始运行，bundle application的onCreate方法被调用\\n类加载机制\\nAtlas里面通常会创建了两种classLoader,第一个是DelegateClassLoader，他作为类查找的一个路由器而存在，本身并不负责真正类的加载；DelegateClassLoader启动时被atlas注入LoadedApk中，替换原有的PathClassLoader；第二个是BundleClassLoader，参考OSGI的实现，每个bundle resolve时会分配一个BundleClassLoader，负责该bundle的类加载。关系如下图所示：\\nDelegateClassLoader以PathClassLoader为parent，同时在路由过程中能够找到所有bundle的classloader；\\nBundleClassLoader以BootClassLoader为parent，同时引用PathClassLoader,BundleClassLoader自身findClass的顺序为\\n  1. findOwn： 查找bundle dex 自身内部的class\\n  2. findDependency: 查找bundle依赖的bundle内的class\\n  3. findPath： 查找主apk中的class\\n>\\n\\n范例\\n下图是容器中类加载的大致顺序；\\n可以认为是一个Bundle的Activity启动的类加载过程来帮助理解（假设Activity所在的bundle已经安装）；\\n\\nActivityThread从LoadedApk中获取classloader去load Activity Class；\\n根据上面的classloader关系，先去parent里面加载class；\\n由于class在bundle里面，所以pathclassloader内查找失败，接着delegateclassloader根据bundleinfo信息查找到classloader在bundle中（假设为bundleA）；\\n从bundleA中加载class，并且创建class；\\n后面在Activity起来后，如果bundleA对bundleB有依赖关系，那么如果用到了bundleB的class，又会根据bundlA的bundleClassloader的dependency去获取bundleB的classloader去加载；\\n\\n\\n资源加载机制\\n>\\n\\n类似ClassLoader，LoadedApk中的Resources被替换成Atlas内部的DelegateResources,同时在每个Bundle安装的过程中，每个bundle的assetspath会被更新到DelegateResources的AssetsManager中；每个bundle的资源特征如图可知：\\n\\nbundle构建过程中，每个bundle会被独立进行分区，packageId保证全局唯一，packageID在host的构建工程内会有个packageIdFile.properties进行统一分配；\\n虽然每个bundle的manifest都声明了自己的packagename，但是在aapt过程中，arsc文件里面所有bundle的packagename均被统一为hostApk的package，比如在手淘内就都是com.taobao.taobao；这样改的目的是为了解决在资源查找中一些兼容性问题； \\n\\n\"},\"principle-intro/Project_architectured.html\":{\"url\":\"principle-intro/Project_architectured.html\",\"title\":\"名词解释\",\"keywords\":\"\",\"body\":\"名词解释\\nBundle: 类似OSGI规范里面bundle（组件）的概念，每个bundle有自己的classloader，与其他bundle相隔离，同时Atlas框架下bundle有自身的资源段（PackageID，打包时AAPT指定）；另外与原有OSGI所定义的service格式不同之处是Atlas里面Bundle透出所有定义在Manifest里面的component，随着service，activity的触发执行bundle的安装，运行。\\nawb： android wireless bundle的缩写，实际上同AAR类似，是最终构建整包前的中间产物。每个awb最终会打成一个bundle。awb与aar的唯一不同之处是awb与之对应有个packageId的定义。\\nhost: 宿主的概念，所有的bundle可以直接调用host内的代码和资源，所以host常常集合了公共的中间件，UI资源等。host和bundle的依赖关系如下图所示：\\n>\\n\\n从上图也可以看出基于Atlas构建后大致工程的结构：\\n\\n首先有个构建整体APK工程Apk_builder,里面管理着所有的依赖（包括atlas）及其版本，Apk_builder本身可能不包含任何代码，只负责构建使用\\nhost内部包含独立的中间件，以及一个Base的工程，里面可能包含应用的Application，应用icon等基础性内容（如果足够独立，application也可以直接放在apk_builder内）；\\n业务层基本上以bundle为边界自上而下与host发生调用，同时bundle之间允许存在依赖关系；相对业务独立的bundle如果存在接口耦合建议封装成aidl service的方式保证自身封装性；同时某些中间件如果只存在若干bundle使用的也可以封装bundle的方式提供出来，以保证host内容精简\\n\\nremote bundle： 远程bundle，远程bundle只是apk构建时并未打到apk内部，而是单独放在了云端；同时远程bundle的限制条件是第一次被触发的前提是bundle内的Activity需要被start，此时基于Atlas内的ClassNotFoundInterceptorCallback可以进行跳转的重定向，提示用户下载具体bundle，待用户确定后进行异步下载同时完成后再跳转到目标bundle（此部分代码由于涉及下载及UI展示等内容并未包含在开源仓库中，有需要可以根据ClassNotFoundInterceptorCallback自行实现）\\n动态部署： 基于Atlas的installorUpdate和atlas-update库及构建插件，可以生成与之前发布的apk diff生成的差异文件，在更新时拉取同时静默更新到设备上，在用户下次启动之后生效新代码，具体原理可以参考动态部署章节的解析\\n\"},\"principle-intro/Apk_architecture.html\":{\"url\":\"principle-intro/Apk_architecture.html\",\"title\":\"APK结构\",\"keywords\":\"\",\"body\":\"APK结构\\n基于Atlas构建后的APK结构如下图，host与普通Apk无异，但是Manifest和assets会添加一些额外的内容，同时在armeabi目录中会增加若干个bundle构建的产物，取名为String.format(lib%s.so,packagename.replace(\\\".\\\",\\\"_\\\"))；packagename为bundle的AndroidManifest中的packagename,这些so都是正常的apk结构，改为so放入lib目录只是为了安装时借用系统的能力从apk中解压出来，方便后续安装\\n>\\n\\nassets/bundleinfo-version.json\\n构建完的apk在host的assets目录下，会有个bundleinfo-verison.json的文件，其中version为manifest中的versinonname，里面记录了每个bundle大小，版本，名字以及里面所有的component信息，这些内容在构建的时候生成，基于这些信息每个bundle可以在component被触发的时候去按需的进行安装，整个过程对开发者透明（从中也可以看到默认情况下bundle对外暴露的只是基于Android原生的Activity，service，receiver等component）。\\n>\\n\\nAndroidManifest\\nbundleinfo的信息同时也会在构建后的主manifest里面体现，如线框1、2所示，每个component下面meta-datal里面记录该component所在的meta-data,同时bundle某些特有的信息会记录在application级别的meta-data里面。\\n>\\n\\n\"},\"principle-intro/File_architecture_runtime.html\":{\"url\":\"principle-intro/File_architecture_runtime.html\",\"title\":\"运行期文件结构\",\"keywords\":\"\",\"body\":\"运行期文件结构\\n\\n/data/data/pkgname/files/bundlelisting\\n之前打包构建时记录的bundleinfo信息（发生动态部署收文件会进行更新）\\n\\n/data/data/pkgname/files/baselineinfo\\n 存放动态部署后的版本变化内容，以及每次部署发生更新的bundle的版本，依赖等信息\\n\\n/data/data/pkgname/files/storage\\n storage目录是bundle安装的目录，每个bundle的安装目录以bundle的packagename为文件夹名，首次启动后会安装到version.1目录下，目录中可能含有bundle的zip文件，dex文件以及native so等内容。如果bundle发生更新，则可能会有version.2、version.3 等目录，每次加载bundle的时候选取最高可用版本进行载入。考虑bundle的回滚功能和对空间占用的影响，目前容器内最多保留两个最近可用版本。\\n>\\n\\n\\n\\n\"},\"guide-for-use/\":{\"url\":\"guide-for-use/\",\"title\":\"接入指引\",\"keywords\":\"\",\"body\":\"接入指引\\n请接入前仔细阅读接入文档.\\n接入可参考atlas-demo\\n\"},\"guide-for-use/guide_for_build.html\":{\"url\":\"guide-for-use/guide_for_build.html\",\"title\":\"容器接入\",\"keywords\":\"\",\"body\":\"# 主工程容器接入\\nAtlas开源的代码内容主要包括以下几个模块：\\n\\n基于gradle的构建插件（包括修改过的aapt内容）；\\nandroid端测容器运行库atlas_core；\\n基于容器提供更新能力的库atlas_update;\\n\\n我们比较倾向于用一个比较干净的壳子工程来作为容器架构下的打包工程，这个工程建议只存在AndroidManifest.xml和构建的文件及部分资源内容，manifest文件用于单独管理apk的icon，版本号，versioncode等；构建文件管理版本依赖；这里我们取名打包工程等名字为apk_builder;\\n通常情况下Apk_builder除了主Apk的AndroidManifest.xml之外，接入Atlas后，Main_builder将会包含以下内容：\\n\\nbuild.gradle : 用于配置主apk的依赖及控制构建参数\\npackageIdFile.properties: 配置bundle的packageId,以保证资源段独立（也可以通过mtl.tBuildConfig.autoPackageId设置自动分配packageID）\\nbundleBaseInfoFile.json: 配置bundle的依赖关系\\n\\n下面会逐个说明每个文件的使用和注意要点\\nbuild.gradle(AtlasGradlePlugin)\\n支持 atlas 工程打包的gradle 插件， 基于 google 官方的 android builder （2.0.0~2.1.0）\\n\\n引用插件及依赖仓库\\n buildscript {\\n     repositories {\\n         mavenLocal()\\n         jcenter()\\n     }\\n     dependencies {\\n         classpath \\\"com.taobao.android:atlasplugin:1.0.1\\\"\\n     }\\n }\\n repositories {\\n     jcenter()\\n }\\n 注意尽量不要指定 classpath \\\"com.android.tools.build:gradle\\\"的版本，默认使用的是 2.1\\n\\n应用plugin\\n apply plugin: 'com.taobao.atlas.application'\\n //注意不能同时 apply com.android.application\\n\\n添加运行库依赖    \\n dependencies {\\n    compile('com.taobao.android:atlas_core:5.0.0@aar') {\\n     transitive = true\\n }\\n compile 'com.taobao.android:atlasupdate:1.0.8@aar'\\n 如果不需要用到atlas的动态部署功能，不需要依赖atlasupdate    \\n\\n开启atlas容器功能\\n  atlas {\\n      atlasEnabled true\\n    tBuildConfig {\\n         autoStartBundles =['com.taobao.firstbundle'] //自启动bundle配置\\n     }\\n\\n      patchConfigs{\\n         debug {\\n         createTPatch true\\n         }\\n         }\\n         buildTypes {\\n         debug {\\n             if (apVersion){\\n                     baseApDependency  \\\"com.taobao.android.atlasdemo:AP-debug:${apVersion}@ap\\\"\\n                 patchConfig    patchConfigs.debug\\n                 }\\n             }\\n          }\\n     }   \\n atlasEnable字段需要指定为true才能开启打包阶段的基于容器扩展的task    \\n后续两个设置用语动态部署打包时的开关设置，其余字段参考配置列表中的使用方式\\n\\n\\n\\n构建\\n\\nAPK构建 ./gradlew assembleDebug 或者 assembleRelease\\n 构建产物：\\n\\nbuild/outputs/apk/xx.apk , 构建的产物apk   \\nbuild/outputs/apk/xx.ap , 构建的基线包， 里面包含 apk 和其他的打包中间配置\\nbuild/outputs/dependencyTree-debug.json , 整个工程的依赖树\\nbuild/outputs/atlasConfig.json , 整个打包的 atlas 配置参数\\n\\n\\nTPatch构建 ./gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.1\\n apVersion表示被动态部署应用的基线版本，versionName表示动态部署后新的versionName\\n 构建产物：\\n 除了依赖树和配置参数之外，额外的产物有：\\n\\nbuild/outputs/tpatch-debug , debug 包 patch产物\\nbuild/outputs/tpatch-release , release 包 patch产物\\n\\n\\n\\n\\n\\n配置\\n配置列表\\n\\n\\n\\n功能\\n配置名称\\n类型\\n值\\n\\n\\n\\n\\n是否启用atlas\\nmtl.atlasEnabled\\nboolean\\ntrue\\n\\n\\n自动生成bundle的packageId\\nmtl.tBuildConfig.autoPackageId\\nboolean\\ntrue\\n\\n\\n预处理manifest， 如果开启atlas，必须为true\\nmtl.tBuildConfig.preProcessManifest\\nBoolean\\ntrue\\n\\n\\n使用自定义的aapt， 如果开启atlas，必须为true\\nmtl.tBuildConfig.useCustomAapt\\nBoolean\\ntrue\\n\\n\\naapt输出的R为常量, 建议值设置为false， 可以减少动态部署的patch包大小\\nmtl.tBuildConfig.aaptConstantId\\nBoolean\\nfalse\\n\\n\\n合并jar中的资源文件\\nmtl.tBuildConfig.mergeJavaRes\\nBoolean\\nfalse\\n\\n\\n构建基线包，建议开启，否则后面的patch包无法进行\\nmtl.tBuildConfig.createAP\\nBoolean\\ntrue\\n\\n\\n合并bundle jar中的资源文件\\nmtl.tBuildConfig.mergeAwbJavaRes\\nBoolean\\nfalse\\n\\n\\n自启动的bundle列表， 值是 packageName\\nmtl.tBuildConfig.autoStartBundles\\nList\\n[com.taobao.firstbundle]\\n\\n\\n提前执行的方法，格式是 className:methodName\\nclassName2:methodName2 ， 注意class和methodname都不能混淆，且方法实现是 class.method(Context)\\nmtl.tBuildConfig.preLaunch\\nString\\n\\n\\n\\n 基线的依赖坐标， 如： com.taobao.android:taobao-android-release:6.3.0-SNAPSHOT@ap\\nmtl.buildTypes.debug.baseApDependency\\nString\\nnull\\n\\n\\n 基线的依赖坐标， 如： com.taobao.android:taobao-android-release:6.3.0-SNAPSHOT@ap\\nmtl.buildTypes.release.baseApDependency\\nString\\nnull\\n\\n\\n使用atlas的application，包含 atlas基础初始化及multidex逻辑\\nmtl.manifestOptions.replaceApplication\\nboolean\\ntrue\\n\\n\\n 打andfix patch 包\\nmtl.patchConfigs.debug.createAPatch\\nboolean\\nfalse\\n\\n\\n 打动态部署 patch 包\\nmtl.patchConfigs.debug.createTPatch\\nboolean\\ntrue\\n\\n\\n andfix 打包过滤 class 列表文件\\nmtl.patchConfigs.debug.filterFile\\nFile\\nnull\\n\\n\\n andfix 打包过滤 class 列表文件\\nmtl.patchConfigs.debug.filterClasses\\nSet\\n[]\\n\\n\\n 打andfix patch 包\\nmtl.patchConfigs.release.createAPatch\\nboolean\\nfalse\\n\\n\\n 打动态部署 patch 包\\nmtl.patchConfigs.release.createTPatch\\nboolean\\nfalse\\n\\n\\n andfix 打包过滤 class 列表文件\\nmtl.patchConfigs.release.filterFile\\nFile\\nnull\\n\\n\\n andfix 打包过滤 class 列表文件\\nmtl.patchConfigs.release.filterClasses\\nSet\\n[]\\n\\n\\n\\n最简配置\\natlas {\\n    atlasEnabled true\\n}\\n具体参考 atlas-demo/app/build.gradle\\npackageIdFile.properties\\n每个bundle在生成的时候，需要为其分配独立的packageId，用以使其保证每个bundle的资源ID全局唯一；资源ID的可分配区间为[0x21,0x7f),0x1x为系统保留，0x7f为主apk使用，0x20之前的发现miui里面内部已使用，所以目前我没选择这个区间作为bundle的packageId分配区间\\n书写的格式为：groupId:artificatId=XX（如下图）\\nbundleBaseInfoFile.json\\nbundleBaseInfoFile 是一个JSON格式的文件，里面记录bundle的信息以及依赖关系，dependency字段用于标识该bundle所依赖的bundle，如果A依赖B，B依赖C，则触发的Abundle安装时，实际的安装顺序为C->B->A,JSONArrary中每个item的key为该bundle的artificatID,dependency里面的item为被依赖的bundle的packageName\\n>\\n\\n\"},\"guide-for-use/guide_for_bundle.html\":{\"url\":\"guide-for-use/guide_for_bundle.html\",\"title\":\"bundle拆分|新建\",\"keywords\":\"\",\"body\":\"如何正确使用Bundle\\nbundle的工程配置\\n\\nbundle自身工程build.gradle里面需要声明为awb:\\n atlas.bundleConfig.awbBundle = true\\n\\n建议修改plugin，更好的支持aar传递依赖等问题（可以采用原生com.android.library）\\n apply plugin: 'com.taobao.atlas.library'\\n buildscript {\\n    repositories {\\n        mavenLocal()\\n        jcenter()\\n    }\\n    dependencies {\\n        classpath \\\"com.android.tools.build:gradle:2.1\\\"\\n        classpath \\\"com.taobao.android:atlasplugin:1.0.0\\\" //使用com.taobao.atlas.library时需要配置atlasplugin等classpath\\n    }\\n}\\n\\n\\n\\n外部配置\\n\\n在主客工程的packageId.properties中声明资源段（也可以通过mtl.tBuildConfig.autoPackageId设置自动分配packageID）\\n com.taobao.android:firstbundle=34//groupId:artifactId=NUM\\n\\n在主客工程的build.gradle中添加awb依赖\\n compile(\\\"com.taobao.android:firstbundle:1.0.0@awb\\\")\\n\\n\\n\\n\\nbundle的注意点\\n遵循代码规范可以有效避免在运行时遇到难以排查的问题。\\n\\nBundle的AndroidManifest中不能有对bundle内的资源的引用；比如Activity的Theme，需要声明在主apk中。Bundle的Manifest会合并进主Manifest，如果有bundle的资源引用会直接引发构建出错；另外可以选择的方式是AndroidManifest里面不加Theme，改用在Activity的onCreate方法里面调用setTheme的方式\\nActivity通过overridePendingTransition使用的切换动画的文件要放在主apk中；\\nBundle内的Class最好以特定的packageName开头，resource文件能够带有特定的前缀。这样一来可以避免资源或者类名重复而引起的覆盖，也可以在出现问题的时候及时定位到出问题的模块\\nBundle内如果有用到自定义style,那么style的parent如果也是自定义的话，parent的定义必须位于主apk中，这是由于5.0以后系统内style查找的固有逻辑导致的，容器内暂不能完全兼容\\nBundle内部如果有so，则安装时so由于无法解压到apk lib目录中，对于直接通过native层使用dlopen来使用so的情况，会存在一定限制，且会影响后续so动态部署，所以目前bundle内so不建议使用dlopen的方式来使用\\n\\nBundle内有使用主进程的contentProvider,则Bundle的AndroidManifest的contentprovider声明中最好带上\\n\\n\\n    android:multiprocess=\\\"true\\\"\\n    android:process=\\\":XX\\\"\\n这样可以避免主进程一起来就去startBundle导致启动时间过长\\n初始化Bundle\\nbundle可以被认为是一个小型的apk，因此每个bundle的初始化都是从Bundle的Application开始的。Application被声明在bundle的AndroidManifest.xml里面\\n注意点：虽然启动方式类似与普通app，先执行attachBaseContext，再执行onCreate，不过有两个不同点需要引起注意：\\n\\nApplication 初始化的线程基于start bundle时的线程，这样导致了bundle可能会运行在主线程，也可能是在子线程，所以初始化的代码如果对线程敏感的需要注意：如果需要强制主线程的可以通过new Handler(Looper.getMainLooper()).post 去初始化\\n\\nbundle的Application并不是被系统真正认可的Application，所以需要Application作为参数进行初始化的方法可以传入getBaseContext()，Bundle Application的mBase实际上就是apk真正的application，最好不要直接传入bundle的Application本身进行初始化，会存在潜在的风险。\\n\\n\\nBundle如何提供服务给其他Bundle\\nBundle虽然提供了依赖的方式，但是这种方式如果使用不当反而会带来隐患，且与bundle本身的封装性相违背。通常如果某个中间件是以bundle的形式存在，那声明依赖是可行的。如果两个本身相对独立的业务bundle存在某几个功能接口的依赖，则可以通过服务的方式，服务提供方提供aidl的接口，被使用方或者主apk依赖；同时自己bundle内部实现service的功能。\\n主动启动Bundle\\n默认情况下，Bundle只往外暴露了android原生的component,运行期按需加载。某些特殊的bundle（比如说监控性质的）本身与其他代码完全独立，且又需要在某个时间点启动运行的，可以通过如下方式去启动：\\n加上Bundle的PackageName为：com.sample.bundleA\\n```\\n    Atlas.getInstance().installBundleTransitivelyAsync(\\n    new String[]{\\\"com.sample.bundleA\\\"}, \\n            new BundleInstaller.InstallListener() {\\n        @Override\\n        public void onFinished() {\\n            BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(\\\"com.sample.bundleA\\\");\\n            if(impl!=null){\\n                try {\\n                    impl.start();\\n                } catch (BundleException e) {\\n                    e.printStackTrace();\\n                }\\n            }\\n        }\\n    });\\n\"},\"guide-for-use/guide_for_compile.html\":{\"url\":\"guide-for-use/guide_for_compile.html\",\"title\":\"awo编译\",\"keywords\":\"\",\"body\":\"待更新\\n\"},\"guide-for-use/bundleCommunicate.html\":{\"url\":\"guide-for-use/bundleCommunicate.html\",\"title\":\"跨bundle的代码重用和通信\",\"keywords\":\"\",\"body\":\"Android跨ClassLoader的模块之间互相通信的几种方式\\n现状\\nAtlas作为java层以OSGI规范进行组件化解耦的容器。在一定层度上清晰了各个模块之间的边界，便于各个业务以内聚的方式不断的演化更新。\\n但是在复杂的App比如手淘这种无数个业务交织的场景下，完全的隔离也给业务的开发造成了不小的成本。针对这种问题，目前主要解决的方案有：\\n\\n参照多个App之间通信的方式，使用AIDL可以作为组件之间进行一定层度通信的方式。\\n使用基于容器的实现开发的ServiceHub，跟AIDL一样将接口放到公共Library，然后ServiceHub中写入接口和实现的对应关系。使用方通过ServiceHub得到接口实现进行使用。\\n\\n缺陷\\nAIDL、ServiceHub解决了部分bundle之间通信或者代码复用的问题。但是这两者也存在着很大的不足。一方面AIDL限制了只能传递parcel以及简单对象，对于UI复用比如说Richview的重用则完全行不通，同时使用成本也是ServiceHub的机制的一个痛点，业务方需要提前将新的接口提前注册到ServiceHub。\\n新的机制\\n新的组件之间的重用及通信策略延续了AIDL免注册的方式，同时解决了跨classloader情况下UI复用的问题。新的方式将重用类型归为RemoteFragment、RemoteView、RemoteTransaction三种类型。\\nRemoteFragment\\nRemoteFragment适用于某个Bundle中有公共的Fragment要提供给一个或者多个其他业务bundle使用的情况，比如说在手淘里面，SkuFragment(sku选择界面)可能会提供给详情，购物车，聚划算等多个业务使用；或者在某些App里面，登录界面也以LoginFragment的方式提供给Bundle按需使用。\\n\\n使用方式\\n\\n代码改动：以LoginFragment为例，LoginBundle需要在自己的LoginFragment做一定的改动\\n```\\npublic class LoginFragment extends Fragment implements IRemote{\\n\\n\\n\\n\\n        @Override\\n        public Bundle call(String commandName, Bundle args, IResponse callback) {\\n            return null;\\n        }\\n\\n        @Override\\n        public  T getRemoteInterface(Class interfaceClass,Bundle args) {\\n            return null;\\n        }\\n}\\n\\n        LoginFragment 需要在原来的基础上实现IRemote接口，IRemote来自Atlas容器的内部实现，暂时还未从容器中拆分出差，这也意味着业务方需要增加对atlas的依赖。**IRemote实现的两个接口会在文章后面解释**\\n\\n\\n\\n       2. Bundle的AndroidManifest.xml中进行注册\\n       \\n        \\n               \\n        \\n    \\n       ```\\nRemote组件参照AIDL的方式在manifest中进行注册。查找时以meta-data的name做key进行查找，RemoteFragment的key必须以**atlas.fragment.intent.action.**开头。\\n\\n3. 使用方如何调用RemoteFragment\\n\\n    ```\\n    public class SampleActivity extends FragmentActivity{\\n        public void doLogin(){\\n            Intent loginIntent = new Intent(\\\"atlas.fragment.intent.action.LOGIN\\\");\\n            RemoteFactory.requestRemote(RemoteFragment.class,loginIntent, \\n                new RemoteFactory.OnRemoteStateListener() {\\n                @Override\\n                public void onRemotePrepared(RemoteFragment fragment) {\\n                    getSupportFragmentManager().beginTransaction().add(R.id.container,fragment).commit();\\n                }\\n                @Override\\n                public void onFailed(String errorInfo) {\\n                    // Redirect to h5 login or downgrade\\n                }\\n            });\\n        }\\n}\\n    ```\\n    业务使用方调用Atlas的RemoteFactory的接口进行request，由于期间可能涉及到bundle的安装，所以整个过程采用callback的方式。获取到RemoteFragment的句柄后直接进行操作即可。**建议Fragment里面涉及到的交互功能等的代码封装在Fragment内部**，比如说LoginFragment里面所有按钮的点击以及异常处理全都Fragment内部进行实现。这样的话两个Bundle之间的边界也更清晰。\\n\\n问题：RemoteFragment 如何通知外部登录成功或者失败，除了用系统的广播等机制，能否基于Remote的机制更直接地方便地实现该功能呢？后续RemoteTransaction中会阐述具体的用法。\\n\\n\\n实现的机制\\n 先附一张Fragment启动图，不清楚的同学可以通过这个大致了解整个Fragment启动的一些方法调用，理清Fragment和Activity在启动时的一些交织的关系(图片可能需要下载放大了观看)。\\n \\n RemoteFragment本身也是真正意义上的Fragment，所以可以用来直接被FragmentManager或者FragmentTransaction直接进行管理；同时它也是真正的LoginFragment的在使用方的代理。他们之间的关系如下：\\n ![](fragment-relation.png)\\n 使用者应该了解RemoteFragment机制的以下几个特点，明白其内部实现的主要机制：\\n\\nRemoteFragment的使用方拿到的仅仅是目标fragment的代理，所以真正的实现对使用方来说是不可见的。如果除了拿到Fragment展示之外还有其他的接口需要暴露给使用者，则需要走Remote的通信机制。\\nEmbeddActivity才是真正目标Fragment实例化所需要的context，EmbeddActivity是由RemoteFragment初始化时创建的Activity，用于给目标Fragment初始化UI，它是真正的Activity，但是没有界面，同时也没有有效的WindowManager，涉及到Window操作的会自动转交给SampleActivity进行处理。EmbeddActivity是bundle之间不需要依赖直接使用UI最根本的保证。\\n\\n设想一下，如果一个Activity引用了5个来自不同Bundle的RemoteFragment，那么相当于这个Activity内嵌了5个EmbeddActivity；那如果引用了5个来自同一个Bundle的RemoteFragment呢？\\n\\n\\n目标Fragment与SampleActivity之间还是保持完整的隔离，所以目标Fragment也无法获取宿主的引用，所以如果目标Fragment需要与SampleActivity发生通信，则也要遵循Remote的通信机制\\n\\n\\n\\n\\nRemoteView\\n与RemoteFragment 类似，RemoteView提供更细粒度的bundle间的UI复用。\\n\\n使用方式\\n\\n代码改动\\n public class SampleRichView extends FrameLayout implements IRemote{\\n     @Override\\n     public Bundle call(String commandName, Bundle args, IResponse callback) {\\n         return null;\\n     }\\n     @Override\\n     public  T getRemoteInterface(Class interfaceClass,Bundle args) {\\n         return null;\\n     }\\n}\\n\\nAndroidManifest修改，RemoteView的key以atlas.view.intent.action.开头\\n    \\n     \\n            \\n     \\n \\n\\n使用方如何调用RemoteView\\npublic class SampleActivity extends Activity{\\n  public void inflateRemoteView(FrameLayout container){\\n      Intent sIntent = new Intent(\\\"atlas.view.intent.action.SAMPLE_RICH\\\");\\n      RemoteFactory.requestRemote(RemoteView.class, sIntent, \\n          new RemoteFactory.OnRemoteStateListener() {\\n          @Override\\n          public void onRemotePrepared(RemoteView remoteView) {\\n              ViewGroup.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);\\n              container.addView(remoteView,params);\\n          }\\n          @Override\\n          public void onFailed(String errorInfo) {\\n              // downgrade\\n          }\\n      });\\n  }\\n}\\n\\n\\n\\n\\n\\n实现机制\\n RemoteView与RemoteFragment实现基本一致，需要EmbeddedActivity作为真正View膨化的基本条件，RemoteView本身只是一个FrameLayout，就像DecorView，目标View作为子View添加在里面。当然这个机制也有一定的隐患，使用方不要通过findViewByID或者getChildAt等viewGroup的public 方法尝试获取目标view并进行操作，RemoteView应该被当做View而不是ViewGroup，与目标View的通信应该通过Remote的机制进行\\n\\n\\nRemoteTransact\\nRemoteTransact相当于是RemoteView或者RemoteFragment的简化版，仅仅为了bundle和bundle之间的通信而存在，它和RemoteView，RemoteFragment都实现了IRemoteTransact接口。可以通过下面的草图了解大致的关系：\\n\\n以RemoteTransactor为例，他和目标Transactor类都实现了IRemoteTransactor，所以当使用方调用IRemoteTransactor的接口时候，Remote对象将方法路由到目标对象的方法上。\\n使用者可以通过这两个方法与真正的远端对象进行通信：\\npublic Bundle call(String commandName, Bundle args, IResponse callback)\\n\\n以命令的方式通知目标对象，如果是异步返回，则远端通过传入的callback接口进行回调，如果不是，则直接返回，适用于使用方和远端存在简单通信的情况。\\n\\npublic  T getRemoteInterface(Class interfaceClass,Bundle args)\\n\\n远端本身已经有封装过具体的接口，则可以实现getRemoteInterface返回具体的接口的实现。这种方式类似之前的AIDL的方式，前提是interface 类需要在两个bundle均可访问的主apk或者公共bundle中。\\n\\n这种使用方式适用于本身具有特定接口定义的SDK中，比如在手淘里面的windvane和weex。\\n以windvane为例（sample里面windvane的接口只做范例，与真实的使用接口可能存在差异）：存在很多Bundle需要提供JSPlugin的场景。原生的Windvane需要提前注册JSPlugin，这种方式对bundle而言开销较大。需要bundle提前启动注册以避免后期运行时无法找到js函数对应的native方法。\\n假设在Remote机制下则Windvane针对非内部的common native方法有一个ExternalJSMethodExecuter，当需要执行非内部的js方法时，则可以通过externalJSMethodExecuter.execute()查找外部的method。（这种也适用于Weex等SDK在非常规的Apk内由外部实现定制的适配器）\\n假设bundle A有若干个native方法，需要提供给JS使用，则可以写成\\npublic class MyJSPluginManager implements IRemote{\\n    @Override\\n    public Bundle call(String commandName, Bundle args, IResponse callback) {\\n        return null;\\n    }\\n\\n    @Override\\n    public  T getRemoteInterface(Class interfaceClass,Bundle args) {\\n        if(interfaceClass == WVApiPlugin.class){\\n            if(args.getString(\\\"js_method\\\").equals(\\\"funA\\\")){\\n                return new FunAPlugin();\\n            }else if(args.getString(\\\"js_method\\\").equals(funB)){\\n                return new FunBPlugin();\\n            }else{\\n                //unknow error\\n            }\\n        }\\n        return null;\\n    }\\n}\\n同时在Manifest中增加如下配置：\\n\\n\\n对于JS方法的调用方，则通过如下方法实现：\\n    public void execute(Activity activity, final String jsMethodName){\\n        RemoteFactory.requestRemote(RemoteTransactor.class,activity,new Intent(jsMethodName),new RemoteFactory.OnRemoteStateListener() {\\n            @Override\\n            public void onRemotePrepared(RemoteTransactor remote) {\\n                Bundle b = new Bundle();\\n                b.putString(\\\"js_method\\\",jsMethodName);\\n                WVApiPlugin plugin  = remote.getRemoteInterface(WVApiPlugin.class,b);\\n                if(plugin!=null){\\n                    //方法仅供示例，与实际情况可能存在差异\\n                    plugin.execute(jsMethodName,...);\\n                }\\n            }\\n            @Override\\n            public void onFailed(String errorInfo) {\\n\\n            }\\n        });\\n    }\\n\\n这里requestRemote里面直接传入RemoteTransactor可能对开发者来说还有点晦涩，SDK开发者也可以尝试直接对RemoteTransactor以及IRemote进行封装，比如改造成更为直观的BaseJSManager和BaseJSPlugin\\n\\n同样的，其他的SDK（比如weex）也可以通过类似方案在多classloader的APK内部实现自己定制的适配器，规避所有的接口实现需要预先注册的情况，同时也对整体应用的性能带来帮助。\\n远端如何主动调用使用方的接口\\n我们也存在被使用方在某些场景下需要主动调用或者按规律定期callback宿主的情况，一种方式是使用宿主掉用远端时传进来的IResponse接口多次回调，但是如果涉及到复杂的情况就需要用到下面的方法：\\n宿主本身对于被调用方来说也是一个远端的对象，所以宿主自己可以使用IRemote，同时将自己注册给Remote对象，RemoteFragment、RemoteView、RemoteTransactor的基类IRemoteContext实现了提供了registerHostTransactor接口，在RemoteFactory回调时将自身的IRemote实现注册进去\\n    void registerHostTransactor(IRemote transactor);\\n那么在远端需要使用的时候，则可以通过HostTransactor（前面图中未标出）得到宿主的IRemote的实现并传递相应的信息。\\n    public static HostTransactor get(IRemote remoteItem)\\nRemote机制的特点和不足\\nRemote机制本身强烈依托于组件化拆分的方案。它的解耦层度介于AIDL和直接依赖之间。相比AIDL灵活层度更高。不过代理的方式并不能完全杜绝通过非常规方法来获取远端目标对象来进行使用，另外也可能存在某些边缘方法无非被完全代理的情况，这也需要在以后的迭代中进行优化，对于非Atlas容器化但是使用了组件化拆解方案的App，这种思路也是同样适用的。\\n现在还可以选择的bundle间代码复用的方案\\n对于AIDL、serviceHub以及Remote的机制，可能还存在临时无法按照规范进行解耦的情况。目前除了静态依赖外，也可以考虑使用动态依赖的方式,用来解决在具体使用到某个功能时候再去挂载相应的依赖模块，不过bundle依赖始终打破了bundle之间的边界，需要谨慎使用\\n    /**\\n     * 设置bundle运行时依赖\\n     * @param source  需要添加依赖的bundle\\n     * @param dependencyBundle 被依赖的bundle的packagename\\n     * @param resourceDependencyNeed 是否需要使用被依赖bundle的资源\\n     * @throws BundleException\\n     */\\n    public void requestRuntimeDependency(ClassLoader source,String dependencyBundle,boolean resourceDependencyNeed) throws BundleException{\\n其他：由于native so的相互调用导致的bundle依赖\\nNative Library 在多classloader运行机制下，需要事先了解几个要点：\\n\\n定义同一个So的依据是全路径完全相同且so内容相同\\n调用LoadLibrary(或者load)在native真正dlopen library之前java层会先findLibrary，如果是系统库，则在系统环境变量里面包含的路径内，如果是外部引入的，则通过ClassLoader.findLibrary进行查找，BundleClassLoader的查找逻辑是先找自身bundle安装目录下的，找不到接着找依赖bundle内的，最后去找主dex也就是PatchClassLoader的findLibrary去查找。\\n 如果是直接使用dlopen bundle内的so，则需要传入so的全路径（比如说通过java层获取），否则可能出现so 找不到。\\n\\nnative so load时与load该so的类所在的classloader存在绑定关系，如果存在native反调java层代码的情况，则只能调用到够找到该classloader可以找到的java类的方法\\n\\n在android 7.0版本之前native so load同一个进程空间下只可load一次，如果同一个classloder第二次去load则直接返回成功，如果不同的classloader去load则会失败；android 7.0以后ClassLoader通过namespace各自独立，不同的ClassLoader可以去load同一个so，分别会在各自的namespace有各自的mmap，可以通过/proc/pid/maps 查看各自的map信息\\n\\nnative特殊使用情况及建议\\n\\n由于不同bundle的java代码使用相同的So导致的依赖：\\n 建议把调用相关的调用So的代码和So本身单独封装成一个公共的模块，否则如果存在So反调java的情况，则只能调用到loadLibrary的ClassLoader范围内的java类的代码\\n\\n由于native so依赖或者dlopen公共native So的情况：\\n 使用方案：\\n\\n公共so下层到公共模块，同时提前load（规避7.0版本开始区分namespace隔离的情况），bundle的so使用的时候不能使用官方的dlopen接口，需要根据mapping查找已load so的导出函数进行使用,规避因为namespace不一致导致多份mmap的情况。具体参考：http://gitlab.alibaba-inc.com/zeduo.szd/savedlopen/tree/master \\n\\n\\n\\n\"},\"update/\":{\"url\":\"update/\",\"title\":\"动态部署\",\"keywords\":\"\",\"body\":\"动态部署\\n动态部署与原有的Apk更新策略相比是一种相对比较轻量化的更新策略，不需要用户下载整个Apk，只需要下载仅仅差量部分的内容来达到更新效果；同时也可以静默的完成更新过程，两者相结合可以使动态更新的生效率远高于普通的升级策略。\\n动态部署适合用来解决下面等需求：\\n\\n及时上线新需求，快速生效。\\n业务灰度新的sdk，快速测试效果，同时有问题可以及时回滚\\n动态修复线上故障\\n\\n\"},\"update/principle.html\":{\"url\":\"update/principle.html\",\"title\":\"技术原理\",\"keywords\":\"\",\"body\":\"技术原理\\n普通Apk的更新的过程为构建->安装->生效，与之相对应，动态部署也可以分为三个过程：\\n\\n构建  不同于Apk更新产物就是一个完整的Apk，动态部署的构建产物是一个后缀为tpatch格式的文件\\nmerge 下载到tpatch文件后，动态部署sdk会在后台完成merge到安装的过程，整个过程对用户透明\\n生效  merge完以后，当前的应用处于一个等待生效的状态，会在合适的时机选择进程重启来生效此次的动态部署，且在生效前不会再接收新的动态部署行为，进程重启以后表示一次完整的动态部署过程结束\\n\\n下面对每个过程展开讲解下，以便更好理解整个动态部署的机制\\n构建\\n动态部署构建的产物为tpatch为后缀的一个压缩文件--文件名为\\npatch-targetVersion@sourceVersion.tpatch\\n例如手淘6.2.0部署到6.2.1的动态部署的tpatch文件为：\\npatch-6.2.1@6.2.0.tpatch\\npatch文件解压后一级目录如下图：\\n\\n如果有主apk的更新，则会有com_taobao_maindex.so存在，so中包含差量的classes.dex、res等\\n如果有bundle更新，则一级目录下以bundle为粒度有多个文件夹，每个文件夹下包含差量的classes.dex，res等\\n\\n注意点：主Apk的差量与bundle的差量目前采取不同的策略，主Apk永远是与基线版本做差量；而bundle是更上一个版本做差量：比如从6.1动态部署到6.2再动态部署到6.3，则6.3中主apk的差量是6.3主apk的集成内容和基线（6.1）主apk中的内容diff出差量；6.3中bundle的差量则是与上一个版本进行diff，如果是6.2的版本去请求动态部署的tpatch，则tpatch中的bundle的差量是6.3与6.2的bundle进行diff所得，如果是6.1版本去请求6.3的动态部署的tpatch，则bundle的差量是6.3与6.1的bundle进行diff所得\\n>\\n\\n与tpatch文件相对于的，接口会返回该次动态部署的修改内容，数据结构如下：\\n\\n数据中可以看出bundle动态部署过程bundle的依赖关系允许发生变更，同时动态部署也有一定的限制，这个会在后面单独进行说明\\nMerge\\nmerge过程在下载到tpatch且校验通过后在线程中进行，由之前Atlas容器安装目录介绍可知，假设当前bundle的版本在文件系统上为Version.1,则merge成功后新的bundle会安装在Version.2目录下，并在后续新的动态部署中版本号逐步往后追加，同时鉴于空间占用的考虑，目前的策略是会保留上一个版本（鉴于回滚的考虑）；\\n与bundle以包名为文件夹存放类似，主Apk更新存放的文件夹以com.taobao.maindex为名字，里面的版本管理与bundle一致，不同点是com.taobao.maindex只在发生过动态部署以后才会有，Version.1意味着已经发生一次动态部署；bundle通常情况下动态部署从Version.2开始（未安装过的bundle除外）\\n动态部署成功后，会在下次进程重启后去resolve新的bundle，resolve的策略是按版本号从高到低回溯，选择最高可用的版本使用。\\n下面展开介绍下在新bundle（假设主Apk当做是一个特殊的bundle）安装成功前merge的过程中bundle和主Apk在merge过程中的差异点：\\nbundle Merge\\nbundle的merge主要以下几个过程(如下图)\\n\\n获取merge的数据源：patch信息来自于bundle在下载的tpatch包中的内容，用于merge的source来自于当前设备的文件系统中，可能来自于已经安装过的bundle（storage），可能还没有安装（apk或者lib目录下）\\n创建新的bundle zip包，classes.dex来自于source中的classes.dex和patch包中的classes.dex通过Dexmerge合并新的classes.dex\\narsc和AndroidManifest直接使用patch包中的内容 \\nres和assets 会进行合并，如果文件没有变更（patch中没有，source中有），则直接使用source中的内容，如果有文件新增或者发生了变更（patch中有，source中有或者没有），则从patch中读取放到新的bundle包中\\n\\n\\nmerge完以后接下去安装就是容器的逻辑了，如果没有安装过则在bundle目录下生成Version.1目录进行安装，如果安装过则生成新的版本目录\\n主Apk的Merge\\n主Apk的Merge在dalvik和art上使用的机制有所不同，dalvik设备上没有任何merge过程，直接把libcom_taobao_maindex.so以bundle的形式安装到com.taobao.maindex目录下\\nArt设备上我们会根据source的apk（主apk的merge永远是基于基线版本）把classes.dex 提取出来以多dex的方式追加到libcom_taobao_maindex.so中，如果本身是多dex机制的，那么会将多个子dex全部追加进去，patch里面的classes.dex保持不变，source里面的dex的序列号往后偏移一位（classes.dex->classes2.dex,classes2.dex->classes3.dex）,如下图所示：\\n>\\n\\nMerge安装成功后，会将bundleinfo的信息更新到baselineinfo的目录中，并在下次启动的最早时间替换掉原有的baselineinfo信息；里面的内容记录了更新的bundle的name，version以及部署成功以后的版本号等信息。\\n运行期\\nbundle的运行期加载策略：\\n由之前的容器的运行机制可以得知，bundle动态部署后对容器来说没有任何变化，还是按需的load bundle，只是在需要去load前版本选择上会使用最高的可用版本\\n主apk动态部署后的加载策略\\n了解主Apk的加载策略之前，先分别介绍下主Apk动态部署得以成功的技术基础再阐述生效的方式：\\nclass|so\\n这里粗略介绍下普通apk（也就是主Apk）class，so库加载入口--PathClassLoader\\n前面容器的技术原理里面介绍了PathClassLoader的父子关系，PathClassLoader自身负责主Apk的类和c库的查找路口；其parent BootClassloader负责framework sdk的内容的查找。\\nPathClassLoader本身也是一个class，继承了BaseDexClassLoader（同DexClassLoader），里面查找过程在DexPathList里面实现（如下图）\\n>\\n\\nDexPathList最终通过DexFile去loadClass，DexPathList可以理解为持有者DexFile以及nativeLibrary目录，再查找的时候遍历这些对象，直到找到需要的类或者c库，那么动态部署的方式就是把新修改的内容添加到这些对象的最前面，从而使得查找的过程中新修改的内容能够提前找到从而替换原有的（如下图）\\n>\\n\\n这里有两个注意点提及一下以加深理解：\\n\\nPREVERIFY: 经过手淘打包插件构建以后，主apk里面的所有class，interface都插入了一段代码：类似下图。原因是android构建的时候会有PREVERIFY的过程，如果Class所引用到的Class均和Class自己在同一个dex内部，则会被打上PREVERIFY的标记。然后在运行期的时候如果打上这个标记的class，在载入时不需要经过verify已提高加载效率，但是运行到方法时会校验依赖的class是否跟构建时一致和Class自身处于同一个dex，如果不一致则会抛出PREVERIFY的错误。而手淘的动态部署策略必然会新生成一个dex，那么如果遇到是PREVERIFY的class的时候就会出错。所以目前手淘的策略是在编译期给每个class引用到一个不存在的class以解除PREVERIFY的限制（具体PREVERIFY的校验过程可以阅读Android源码）\\n>\\n\\n\\nOAT的限制:android到art后原有的dexopt会改为dex2oat，运行时代码由原来的解释执行改为直接运行native代码，之前的使用过程中发现单纯得往前面追加patch的dex并不能完全解决动态部署的问题，dex2oat的过程优化了class的执行代码，比如说内敛，虚函数的校验等。就有可能在运行过程中直接在native层执行老的优化过的class代码而不是从新patch的dex中load新的class去使用。所以art上目前的策略是把patchdex，sourcedex参考multidex的机制放入一个zip，然后合并在一起做一遍dex2oat，这样能使新的class覆盖老的class参与dex2oat并完成优化的过程，所以art上的真正的执行过程实际上在patch的dex中已经包含了所有主apk的代码，基本不会走到old dex的逻辑。（patchdex 插入前执行的代码除外） \\n\\n\\nresource|assets\\n主Apk为了支持在Resource能够动态部署实际上同PREVERIFY的机制类似，在基线包构建的时候就已经做了处理:基于Atlas打出来的apk的资源列表中有如下内容：\\n>\\n\\n我们取一个动态部署的tpatch包，能够看到如下内容：\\n>\\n\\n这些是基于我们atlas-aapt的修改，dalvik上我们是基于res的overlay机制去修改资源，这个机制并不支持新增资源，在overlay的包里面如果读到了一个资源，dalvik系统会去校验该资源ID在base中值，如果不存在则抛错，所以动态部署为了利用这一特性同时支持新增资源的需求，在打基线包的时候就在每个不同的type里面预留了128个资源ID供后续动态部署使用；同时打动态部署的patch时会以之前的ID分配的内容作为输入，保证已有的资源分配到的ID保持不变，同时如果资源没有发生变更，则剔除该资源，所以aapt dump patch的时候我们看到的INVALID TYPE 的资源段没有发生变更的资源，如果有发生了变更，且之前有这个资源，就会在原有的资源ID分配过去，同时新的资源文件打入patch包或者新的资源文本写入arsc，如果是新增的资源，则使用预留的资源段进行分配。整个替换过程如下图所示：\\n>\\n\\n在打包对资源做了一系列处理以后，运行期资源的加载只是在启动加载资源时根据系统读取资源的先后书序把patch包插入到AssetsManager的合适的位置中，assets由于没有资源ID，不需要预留，插入AssetsManager的方式类似res的处理，这里不再展开\\n\"},\"update/dexpatch.html\":{\"url\":\"update/dexpatch.html\",\"title\":\"dexpatch\",\"keywords\":\"\",\"body\":\"什么是Dexpatch\\nDexPatch是以动态部署技术方案为基础，以快速解决线上故障为唯一目的的动态化方案。\\n为什么不用动态部署\\n动态部署的出发点立足于需求的快速迭代，替换普通的apk升级。所以在动态部署的演进过程中灵活性成为我们不断去追求的目标。希望不断缩小动态部署的限制以达到完全替换APK更新的能力。\\n正是因为其比较全面的能力，我们发现动态部署在故障修复方面存在其不足的地方：\\n\\n构建速度：\\n在每个需求迭代过程中，考虑需求的复杂性和每次周期性迭代管理的成本，动态部署参考APK迭代的方式通过统一的集成区进行管理，所以在构建上动态部署tpatch实际上是先有整包构建，再DIFF出差异的方式，这样的方式规避了混淆、内联等带来的复杂性的问题处理，保证patch对之前版本的完全适用，但是这种方式同时也必不可少的影响patch的构建速度，在对紧急的问题进行修复的关键时期，这个时间可能会是不可接受的。\\n\\n生效速度：\\n\\n动态部署内有代码的变更，so，资源等。灵活性导致一个动态部署等体积往往比较大，而在运营商网络下，对用户大的流量消耗不是我们希望看到的，所以往往这种情况下只在WIFI下的生效策略很能影响生效率。\\n动态部署允许宿主，bundle内部发生更新，也允许bundle之间的依赖关系等发生变更，这就导致了一次动态部署成功必须依赖于tpatch内的所有bundle和宿主全部更新成功，否则就可能会导致依赖不一致而引发crash。从以往的动态部署tpatch可知，每次的变更通常都有十几个甚至几十个bundle发生变更，而在低空间或者某些读写能力较差的设备上，IO失败很容易影响整个patch的成功率。\\n\\n\\n版本号：\\n因为是APk升级的替代方案，动态部署替换版本号的方式就使得是否使用的是动态部署还是apk升级对业务来说完全透明，可以继续按版本号进行逻辑处理，降级等。数据统计以及监控等可以完全兼容。但是如果在故障修复中去贸然升级版本号，虽然直观上可以清楚看到问题修复的覆盖率，但是之前优势就荡然无存了。\\n\\n\\n回顾手淘之前的一些故障问题的修复，不管是动态部署还是andfix，其实我们发现几乎所有的故障都可以通过java代码就行修复或者降级，也基本都可以在一个模块内的修改就把某个对应的故障修复掉。因此，以动态部署的技术作为基础，称之为Dexpatch的方案应运而生。\\nDexpatch的特点和优势\\n限制： \\n每个dexpatch只能修改一个bundle(主dex整个算一个bundle)，且修改的代码必须向前兼容。（不如说主dex被bundle依赖，则主dex的dexpatch修改不能引起原来bundle的方法调用出现问题）\\n如何发布Dexpatch:\\n每个业务按照各自的故障情况进行dexpatch的构建，产出对应的patch产物和json信息，发布时平台应该汇总对应版本当前release的所有patch内容，整合json信息，进行下发\\ndexpatch不存在回滚，每个dexpatch发布后，直接覆盖之前的dexpatch的。每个dexpatch有下线的能力\\n优势\\n\\n每个bundle基于自身的问题进行dexpatch的发布，构建速度相比原来的方式有了大幅度提高，只需要针对单个bundle进行构建从而diff出差异即可。\\n下发的dexpatch总包内的patch各自生效，不需要所有bundle的patch全部安装成功，这是由于之前patch的修改是向前兼容做了保证。\\n\\ndexpatch由于其修改的原子性（向前兼容性的保证以及不存在关联修改），同时容器按需加载的特性，使得未被载入的bundle可以不需要进程重启即可生效，同时，已经载入的bundle后期也会进行生命周期的监控，一旦所有component退出，则也可以进行热替换，使得dexpatch相比动态部署的生效速度可以进一步提高\\n\\n\\n同时dexpatch不修改整个apk版本号，每个bundle提供额外的dexpatch版本号进行监控。\\n另外 dexpatch作为动态部署的补充，两者相辅相成。可以针对任何一个大版本或者动态部署版本发布dexpatch，无论一个版本号对应的bundle是否有被dexpatch，当一个新的动态部署发生时，它们又都会被收敛到一个新动态部署版本上面。\\n那么现在理想中的版本迭代的情况应该是如下这种：\\n>\\n\\n\"},\"update/dexpatch_use_guide.html\":{\"url\":\"update/dexpatch_use_guide.html\",\"title\":\"dexpatch使用教程\",\"keywords\":\"\",\"body\":\"DexPatch使用示例\\nDexPatch是以动态部署技术方案为基础，以快速解决线上故障为唯一目的的动态化方案。\\n简单来说，动态部署是针对apk级别的动态升级，DexPatch是针对Bundle级别的动态修复(主dex可以认为是一个Bundle)\\n详细介绍参照 DexPatch介绍 \\nDexPatch与动态部署异同\\n\\n\\n\\n不同点\\nDexPatch\\n动态部署\\n\\n\\n\\n\\n场景定位\\nbundle级别，代码动态修复\\napk动态升级\\n\\n\\n灵活度\\n各个bundle随时下发\\n集成升级\\n\\n\\n构建速度\\n很快\\n一般\\n\\n\\n生效速度\\n快\\n一般\\n\\n\\n修改范围\\nbundle自身内聚\\napk范围\\n\\n\\nversionName\\n不改\\n+1\\n\\n\\njava\\n支持\\n支持\\n\\n\\nso\\nx\\n支持\\n\\n\\nresource\\nx\\n支持\\n\\n\\n\\n版本\\n\\n\\n\\n依赖\\n版本\\n\\n\\n\\n\\natlasplugin\\n2.3.3.rc12-1\\n\\n\\natlas_core\\n5.0.7.41\\n\\n\\natlasupdate\\n1.1.4.11\\n\\n\\n\\n打包\\nDexpatch需要一个ap版本作为参照，和现在的代码比对做diff。假设当前版本为1.0.0 (gradle中配置)\\n发布版本\\n如果之前发布过ap版本，可以跳过此节。假设从未发布过ap，按照如下步骤，发布1.0.0的ap\\n\\n进入app目录下\\n生成基线版本 ./gradlew clean assembleDebug\\n发布ap到仓库中 `./gradlew publish\\n\\n打patch\\n\\n基于ap所属的版本(1.0.0)，修改代码,以firstbundle为例，将\\\"origin\\\"修改为\\\"dexpatch\\\"\\n  \\n\\n修改依赖版本，将firbundle中grddle的verion改为version = '1.0.1'\\n\\n这里也可以修改firbundle依赖的某个aar的版本。一句话，你要通过版本号告诉编译器，我这个bundle的代码变了\\n\\n\\n指定参照的版本，生成dexPatch包 ./gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.0\\n\\nPS: \\n\\n这里要强调一下，代码的修改要内聚。假设A依赖B,修改时，只改A或B自身的代码，不支持修改A与B之间的接口。\\n\\n部署Patch\\n生成的patch文件在 app/build/outputs下，检查是否存在两个文件\\n\\n1.0.0@1.0.0.tpatch\\ndexpatch-1.0.0.json\\n\\n清空 /sdcard/Android/data/com.taobao.demo/cache/，并将上述两个文件push到上述路径中\\ndemo中测试入口\\n主界面点开侧边栏，点击dexpatch\\n\\n重启应用,Toash显示 \\\"dexpatch\\\",成功~\\n\\n产物说明\\n\\nversion@version.tpatch\\n当前代码和参考ap(1.0.0)diff的产物，是个zip文件，解压开就是diff的代码。\\npatchs.json\\n上述代码diff的配套json，描述了本次diff的结果:\\n\\n改动模块信息\\n比对版本\\n...\\n\\ndexpatch-xxx.json\\n说明\\n客户端可以识别的接口，对打包产物包装处理过的配置\\n客户端并不能直接识别打包产生的 path.json 文件，需要服务端做一些包装。\\nDemo说明\\n由于demo没有服务端，所以在app/dexPatchWraper.gradle中，对patch.json内容做了一个包装，简单模拟服务端的逻辑。\\n\\n简单起见，只是每次都把dexPatchVersion+1，版本号缓存在根目录下的dexPatch.verion文件中。\\n\\n字段解释\\n包装后的产物字端如下,大部分内容直接copy自patch.json,需要关心的只有几个字端\\n{\\n  \\\"baseVersion\\\": \\\"1.0.0\\\",\\n  \\\"diffBundleDex\\\": true,\\n  \\\"patches\\\": [\\n    {\\n      \\\"bundles\\\": [\\n        {\\n          \\\"dependency\\\": [\\n            \\\"com.taobao.publicBundle\\\"\\n          ],\\n          //重要\\n          \\\"dexpatchVersion\\\": \\\"14\\\",\\n          \\\"isMainDex\\\": false,\\n          \\\"name\\\": \\\"com.taobao.firstbundle\\\",\\n          \\\"pkgName\\\": \\\"com.taobao.firstbundle\\\",\\n          \\\"dependency\\\":[],\\n          //重要\\n          \\\"reset\\\": false,\\n          \\\"srcUnitTag\\\": \\\"6b3973d9d6592d15601017edabc8b31b\\\",\\n          \\\"unitTag\\\": \\\"e857557cc924f503a7304218469733a2\\\",\\n          \\\"version\\\": \\\"1.0.1\\\"\\n        }\\n      ],\\n      //重要\\n      \\\"dexPatch\\\": true,\\n      \\\"fileName\\\": \\\"1.0.0@1.0.0.tpatch\\\",\\n      \\\"patchVersion\\\": \\\"1.0.0\\\",\\n      \\\"targetVersion\\\": \\\"1.0.0\\\"\\n    }\\n  ]\\n}\\n\\n\\n\\n\\n字段\\n说明\\n\\n\\n\\n\\ndexpatchVersion\\n每个模块有一个dexPatchVersion的概念客户端会判断bundle的dexPatchVersion,判断该bundle是否需要做merge通常由服务端进行管理\\n\\n\\nreset\\n回滚标志，该bundle会回滚到dexpatch前的版本\\n\\n\\ndexPatch\\n区分配置是动态部署还是 dexpatch\\n\\n\\n\\n\"},\"update/guide.html\":{\"url\":\"update/guide.html\",\"title\":\"一些限制\",\"keywords\":\"\",\"body\":\"动态部署的限制\\n\\nAndroidManifest\\n  已有Activity的manifest信息暂时不支持更改\\n\\nwindow级别使用的资源保持不变\\n Activity切换的动画文件、通知栏使用的logo等如果修改了也不会生效，不过不会产生问题，使用的还是原来的样式\\n\\n\\n\"},\"faq/question.html\":{\"url\":\"faq/question.html\",\"title\":\"问答\",\"keywords\":\"\",\"body\":\"Q1: 关于bundle中的application类，它什么时候被调用，其中的自定义方法怎么在bundle中调用？在bundle中调用getApplication方法，得到的是主应用的application对象，不是bundle中定义的。\\nA: 首先要明确一点，bundle中的application不是最终在android系统上执行的application。我们之所以保留bundle application的设计是为了尽最大可能保留大家android的开发习惯。\\nbundle中的application类，是在bundle第一次安装的时候，atlas会调用application的onCreate()函数，可以在里面写一些自己bundle需要用到的初始化代码。注意不要bundle application里用this这种代码，因为是不生效的。\\nbundle中的application类的自定义方法，我们建议不要这么使用。可以抽离出公共的方法，放在其他地方供调用。 目前是有这个限制。如果非得在里面调用，建议改为static方法。\\nQ2: 集成框架后就只有uses-permission，小米推送需要permission就提示缺少权限声明。\\nA: 这是因为打包插件默认开启了去除自定义权限。 可通过属性开关关闭。 属性开关是atlas.manifestOptions.removeCustomPermission = false\\nQ3: proguard-rules.pro直接定义在宿主app里面就可以了吗，不需要每个bundle都使用吧？\\nA: 在宿主app里边定义就好了\\nQ4: 请问 客户端拿什么属性 跟服务器比对获取补丁？\\nA: 每一次补丁的发布都是相当于一次版本的升级，通过版本号的变更来决策补丁的下发\\nQ5: bundle中的9patch图显示有问题，不能拉伸了。是需要有特殊设置么？\\nA: alpha11版本发布解决了。\\nQ6: 对于gradle 2.3.1版本是不是支持？\\nA: 是的，支持2.3.x\\nQ7: 导入demo后，Android Studio编译按钮编译失败。\\nA: 关闭InstantRun可以正常工作。InstantRun支持正在开发中。\\nQ8: Unable to delete file E:\\\\GitHub\\\\atlas\\\\atlas-demo\\\\AtlasDemo\\\\app\\\\build\\\\intermediates\\\\exploded-aar\\\\com.android.support\\\\animated-vector-drawable\\\\25.3.0\\\\jars\\\\classes.jar\\nA: 1. 杀掉java.exe进程重新编译（Windows 系统进程出现）cmd:taskkill /F /IM java.exe 2. 关闭掉as run on demand 开关\\nQ9. atlas 的能力问题， 及与 andfix 的关系\\nA: 1. atlas支持所有的代码及资源更新，暂时不支持新增4大组件，下个大版本支持 2. andfix只要用于修复java代码，不重启生效。 atlas能力更强，修复只是其中一部分能力\\nQ10. AS 上重新编译安装不生效的问题\\nA: atlas 在覆盖安装的时候，由于bundle的版本号没变化，没做清理， 下个版本会清理bundle\\nQ11. 动态部署不生效的问题\\nA: 不生效要看提示log再查，目前已知的已经修复，之前是由于windows句柄没关闭，导致tpatch中包含一些空文件，在dexmerge的时候失败了\\nQ12. 混淆后atlas进度条消失\\nA： keep 规则少了\\nQ13. 自启动的bundle是在哪个线程中啊，不是主线程吗？\\nA: 自启动bundle可以在任何线程中执行，不过bundle的application onCreate方法、Activity的onCreate方法等都是在主线程回调的\\nQ14. 在其他进程里运行的插件，需要在什么时候安装？可不可手动控制安装的时机？\\nA: 在需要的时候按需安装，例如一个Service是在单独的进程中，只要需要的时候去bind就会触发这个bundle的安装。可以手动控制安装时机，按需就好。\\nQ15. 组件中有jar包和so依赖，awb的产物中也有，为什么在宿主中生成的so产物解压就没有了呢？\\nA: 在打整包的时候需要配置过滤的参数，把so的架构类型指定清楚，要不然就会被裁减掉。具体可以参考 ： https://github.com/alibaba/atlas/issues/68\\nQ16. app有多个进程，在一个进程中出现了host中的一个类被pathClassloader加载了，之后在该类中调用Class.forName加载插件里的一个类，因为classloader是PathClassLoader,所以报了classnotfound,理论上host中除了atlas相关的类外所有的class都应该是被DelegateClassLoader加载吧？\\nA: 这种问题属于宿主中的class引用了bundle中的class，理论上是可以支持的，但是在Atlas的框架中是不推荐(也没不支持)这种反向的依赖关系。\\nQ17. altas是不是不建议bundle之间相互调用资源或调用宿主的资源?\\nA: Atlas框架建议bundle调用宿主的资源，而不建议bundle之间资源的相互调用。\\nQ18. 宿主和bundle的关系？\\nA: 宿主就相当于Android Framework，正常的Android代码中我们可以调用Framework中的接口以及使用其包含的资源，宿主对于bundle而言也是这个样子的，假如多个bundle使用同一个资源，那么这个资源可以放在宿主里边，多个bundle同时依赖这个宿主，这样避免了资源的重复。(甚至可以把宿主看成一个AAR，这个AAR的内容是打包在主dex中的)\\nQ19. Atlas项目中：AtlasDemo和基于版本打包的demo这两个项目有什么区别？\\nA: 一个是基于源码项目，一个是基于仓库版本依赖的。前期研究可以基于源码来，后续工程化实践推荐使用后者，手淘内部就是使用后者的。\\nQ20.  awb是什么？\\nA: awb是我们发明的格式，其内部结构和aar一样。 awb对应于bundle，编译最后的产物是生成到最后整包的so中。具体请参照 http://atlas.taobao.org/docs/principle-intro/Project_architectured.html\\n\"},\"faq/help.html\":{\"url\":\"faq/help.html\",\"title\":\"故障排查\",\"keywords\":\"\",\"body\":\"常见问题\\n有任何的建议和问题请在github上提issue给我们，我们会尽快回复，同时高频的会更新的FAQ文档中\\n\\n需要去除的原生multidex初始化\\n Atlas容器内部集成了multidex的dex安装功能，所以原先multidex的初始化代码可以省略，也不需要添加multidex的三方库依赖，需要使用multidex的只需要build.gradle内部将multidex置为enable即可（Atlas内部集成该内容一方面是便于和容器的兼容，另一方面后续容器会优化原生multidex在dalvik上面的性能）\\n\\n\\n>\\n\\n\\nClassNotFoundException\\n\\nBundle如果相互依赖，则构建起需要配置dependency，否则运行期会无法找到被依赖bundle内的class，且不支持为了查找性能，目前不支持二级依赖：比如A->B->C,如果A没有显式声明依赖C，则A bundle里面无法直接使用bundle C里面的Class，检查bundle依赖是否成功配置可以通过反编译Apk的主dex 查看android.taobao.atlas.framework.FrameworkProperties的field bundleInfo的内容，里面记录了所有bundle的依赖关系\\n通过LayoutInflater 膨化xml，则xml里面如果有richview，则务必确保LayoutInflater持有的context的classloader可以load到该richview，假设context来自于A bundle的Activity，而xml来自于B bundle，如果A和B没有依赖关系，那么加载也肯定失败\\n\\n\\nNoClassDefFoundError\\n造成该问题的原因比较多，排查步骤第一个先检查Exception的源头是不是ClassNotFoundException，然后反编译排查类确实是否存在；\\n如果类本身存在，需要往前排查系统的警告信息，比如在Art的设备上会有class被reject的warning信息：\\n  >\\n\\n 在dalvik的系统上，则会带有VFY tag的警告信息：\\n >\\n\\n一般来说，由于ART设备警告的信息报在dex2oat的时候，所以往往与发生crash时的Exception信息相隔比较远，所以通常遇到该类问题，dalivk的设备拿来排查可能更能发现问题的原因。另外noclassdef造成的原有接口类找不到，方法丢失，方法参数不匹配，方法属性变更，混淆等，所以具体原因需要利用上述warning信息并对照反编译的代码去排查根本的原因   \\n\\n\\n\"},\"faq/variant.html\":{\"url\":\"faq/variant.html\",\"title\":\"构建定制包\",\"keywords\":\"\",\"body\":\"如何构建不同的包\\ngoogle插件对应的文档地址： https://developer.android.com/studio/build/build-variants.html?hl=zh-cn ， 原生是支持配置不同的buildType 以及 flavor 的， 先看一下功能对比：\\n当前的支持度\\n\\n\\n\\n插件\\nfalvor\\n自定义buildType\\n\\n\\n\\n\\ngoogle插件\\n支持\\n支持\\n\\n\\natlasplugin 构建apk\\n支持\\n不支持\\n\\n\\natlasplugin 构建动态部署\\n不支持\\n不支持\\n\\n\\n\\n为什么没有去完全适配\\n\\nAtlas是面向多人协作的较大工程的，配置不同的buildtype和flavor中也会带来创建更多的任务，并且如果执行assembleDebug 之类会构建所有的依赖变种，导致整体构建效率大大降低。\\n开发精力所限，因为我们的淘宝app就是没有变种的架构，额外的功能会带来很多适配的麻烦和风险\\n开发期我们期望我们的基线足够稳定，这样可以避免动态部署基线不兼容的问题\\n\\n当前插件下的实践\\n因为build.gradle 里可以写很多的逻辑，所以配置也可以变的很灵活。 我们一般的做法就是通过打包参数来控制不同的参数值， 具体的demo可以看下下面的介绍，至于具体的其他实现，大家也可以自行扩展\\n大致步骤\\n\\n在build.gradle里定义一些基础的变量，比如：\\n //通过增加判断逻辑，打出不同类型的定制包\\n def appId = \\\"com.taobao.demo\\\"\\n def minVersion = 14\\n\\n\\n\\n增加一层逻辑控制根据不同的参数来修改之前定义变量的值 ， 这样如果我们打包加了 -Pbeta, 就会使用新的值了\\n\\n    if (project.hasProperty(\\\"beta\\\")) {\\n        appId = \\\"com.taobao.atlas.beta\\\"\\n        minVersion = 21\\n    }\\n\\n或者直接在配置的地方加上判断逻辑，使用特殊的配置\\n\\n    android {\\n        defaultConfig {\\n            //通过增加判断逻辑，打出不同类型的定制包\\n            if (project.hasProperty(\\\"beta\\\")) {\\n                buildConfigField \\\"boolean\\\", \\\"API_ENV\\\", \\\"false\\\"\\n            }else{\\n                buildConfigField \\\"boolean\\\", \\\"API_ENV\\\", \\\"false\\\"\\n            }\\n        }\\n\\n以上build.gradle 里的配置基本完成。 后续如果要打特殊包就可以通过修改配置的构建参数来控制打具体的包了，如：\\n    ./gradlew clean assembleDebug :  构建标准包\\n    ./gradlew clean assembleDebug -Pbeta ： 构建特殊包\\n\\n\\n\"},\"faq/dynamic_failed_help.html\":{\"url\":\"faq/dynamic_failed_help.html\",\"title\":\"动态部署失败排查指南\",\"keywords\":\"\",\"body\":\"title: 动态部署排查经验\\ndate: 2014-12-22 12:39:04\\n概述\\n经常有同学在答疑群上提出疑问为什么动态部署不生效？，然后就是一通排查。由于是远程交流，代价实在是太高。这篇文章主要是和大家分享一下动态部署排查的一些经验，希望能够帮助大家快速定位、解决问题。\\n另外，根据历史经验，大部分都是使用不规范造成的，为了避免这些奇奇怪怪的问题，大家最好按照Atlas工程结构指南以及容器接入 这两篇文章提到的规范，来组织工程结构。\\n快速排查三连\\n从demo中一个例子开始，假设我们发了1.0.0的Ap,之后修改了splashscreen和firstbundle两个地方的代码,并且修改了对应的版本号\\n\\n\\n\\n\\n基线版本\\n新版本\\n\\n\\n\\n\\n整包(apk)\\n1.0.0\\n1.0.1\\n\\n\\nsplashscreen（maindex）\\n1.0.0\\n1.0.1\\n\\n\\nfirstbundle（bundle）\\n1.0.1\\n1.0.2\\n\\n\\n\\n1. 打包产物检查\\n首先检查打包的产物，按照历史经验，90%的问题都是因为打包产物不对造成的。\\n第一点，依赖变动\\n打开产物中的dependencyDiff.json的文件，这个文件记录了本次改动相对AP的依赖变化信息\\n{\\n    \\\"awbDiffs\\\":[\\\"com.atlas.demo:firstbundle\\\"],\\n    \\\"mainDexDiffs\\\":[\\\"com.atlas.demo:splashscreen(1.0.0@aar=>1.0.1@aar)\\\"],\\n    \\\"modifyLines\\\":[\\n        \\\"com.atlas.demo:firstbundle(1.0.1=>1.0.2)\\\"\\n    ],\\n    \\\"newAwbs\\\":[]\\n}\\n可以看到，firstbundle 和 splashscreen 的版本变化和改动一致，没有问题。\\n如果对不上，说明打包产物错误，下面是两个常见的原因，需要同学们自己做一下排查。\\n\\n\\n\\n根本原因\\n可能的错误操作\\n\\n\\n\\n\\n修改引入了其它隐含的改动\\n在发布lib/bundle版本时，带动了其它lib／bundle的版本变化\\n\\n\\nAP不对,mvn仓库中的AP，和预期的不是同一个\\n1.重新publish了AP,老AP被覆盖了2.gradle在本地仓库做了一份cache，是否和远程仓库中的一致\\n\\n\\n\\n第二点，验证配置文件\\n打开update-1.0.0.json\\n{\\n    //基线版本\\n    \\\"baseVersion\\\":\\\"1.0.0\\\",\\n    \\\"updateBundles\\\":[\\n        {\\n            \\\"dependency\\\":[\\n                \\\"com.taobao.publicBundle\\\"\\n            ],\\n            \\\"isMainDex\\\":false,\\n            \\\"name\\\":\\\"com.taobao.firstbundle\\\",\\n            //基线依赖1.0.0中的唯一tag\\n            \\\"srcUnitTag\\\":\\\"1lxlheevwoeeg\\\",\\n            //动态部署版本1.0.1的tag\\n            \\\"unitTag\\\":\\\"1x6r8iuzs90ff\\\",\\n            \\\"version\\\":\\\"1.0.0@1.0.2\\\"\\n        },\\n        {\\n            \\\"isMainDex\\\":true,\\n            \\\"name\\\":\\\"com.taobao.maindex\\\",\\n            \\\"srcUnitTag\\\":\\\"1nf3phs9djbuj\\\",\\n            \\\"unitTag\\\":\\\"31jv86qvt1gc\\\",\\n            \\\"version\\\":\\\"1.0.0@1.0.1\\\"\\n        }\\n    ],\\n    //动态部署更新版本\\n    \\\"updateVersion\\\":\\\"1.0.1\\\"\\n}\\n\\n涉及改动确认，配置中的diff信息和我们的改动一致（两个部分，firstbundle和maindex）\\n\\n涉及版本确认，baseVersion(1.0.0), updateVersion(1.0.1),分别对应打包命令的apVersion和versionName,表明是1.0.0->1.0.1的diff信息。\\n\\nsrcUnitTag 和 unittag确认。（如果同学们没有按照规范来，这个地方很容易出错，导致动态部署失败）\\n\\n关于第三个，我们以firstbundle为例，详细说明。首先，看下在配置文件update-1.0.0.json中的值:\\n\\n\\n\\nkey\\nval\\n\\n\\n\\n\\nsrcUnitTag\\n1lxlheevwoeeg\\n\\n\\nunitTag\\n1x6r8iuzs90ff\\n\\n\\n\\nok,我们再解压1.0.0的ap文件，打开atlasFrameworkProperties.json文件，关键字搜索com.taobao.firstbundle\\n{\\n    \\\"bundleInfo\\\":[\\n        {\\n            \\\"pkgName\\\":\\\"com.taobao.firstbundle\\\",\\n            \\\"unique_tag\\\":\\\"1lxlheevwoeeg\\\",\\n            \\\"version\\\":\\\"1.0.0@1.0.1\\\"\\n        },\\n        //...\\n    ]\\n}\\n各位，有没有灵光一闪？是的，unittag和srcunittag是有联系的，客户端用来验证patch的合法性，看图:\\n\\n以上是正确的使用姿势，下面是常见的一些常见的错误\\n\\n\\n\\n错误\\n原因\\n\\n\\n\\n\\nupdate-xxx.json中bundle的srcUnittag和AP中的unitttag不一样\\nAP不对，比对的AP和预想的不是同一个\\n\\n\\n在update-xxx.json文件中，某个bundle的srcUnittag和unittag一样\\n通常来说都是改了代码，但是没有变更依赖lib/bundle的版本号\\n\\n\\n\\n第三点，diff代码验证\\n解压tpatch\\n└── patch-1.0.1@1.0.0\\n    ├── libcom_taobao_firstbundle\\n    │   └── classes.dex\\n    └── libcom_taobao_maindex.so\\n反编译Dex，查看patch出来的代码和修改的是否一致。\\n比如修改了firstbundle 中的first.java和splashscreen中的maindex.java,diff出来的产物就一定如上图所示:\\n\\nlibcom_taobao_firstbundle，反编译classes.dex，有且只有first.class这个diff\\nlibcom_taobao_maindex.so，解压反编译classes.dex，有且只有maindex.class这个diff\\n改了几个类这里就会对应diff出几个，不会多也不会少。\\n\\n如果有异常，和第上面一样\\n\\n还是AP有问题\\n或者本次修改隐含带入了其它改动。\\n\\n2. 客户端检查\\n通常来说，如果打包产物如果没有问题，动态部署一般都是可以正常生效的。\\n首先，确保手机存储卡容量足够(至少100m吧)，然后在进行下面的排查步骤。\\n按照文档，触发patch更新操作，观察本地上两个地方\\n/data/data/\\\\${pkg}/files/bundleBaseline/updateinfo\\n/data/data/pkg/files/storage/\\\\${bundle\\\\_pkg\\\\_name}/bundle.zip\\npkg为app的包名\\n如果同时存在updateinfo和updateinfo_new两个文件,以updateinfo_new为准\\nbundle_pkg_name为bundle的包名，maindex的包名为com.taobao.maindex\\n重启前\\n在动态部署提示重启前，执行 cat updateInfo 命令\\n1.0.1Ecom.taobao.maindex@31jv86qvt1gc;com.taobao.firstbundle@1x6r8iuzs90ff;\\n格式很简单\\n\\n\\n\\n动态部署版本\\nmaindex tag\\nfirstbudnle tag\\n\\n\\n\\n\\n1.0.1\\n31jv86qvt1gc\\n1x6r8iuzs90ff\\n\\n\\n\\n对应前面打包产物update-1.0.0.json中的记录的unittag，数据没有问题。\\n查看merge的产物是否存在，以firstbundle为例，maindex同理。\\ncd到和/data/data/com.taobao.demo/files/storage/com.taobao.firstbundle\\nbullhead:/data/data/com.taobao.demo/files/storage/com.taobao.firstbundle # ls\\n1x6r8iuzs90ff lock\\n目录名为记录的tag1x6r8iuzs90ff,cd 进去\\nbullhead:/data/data/com.taobao.demo/files/storage/com.taobao.firstbundle/1x6r8iuzs90ff # ls\\nbundle.dex bundle.zip lock meta\\n可以看到产物merge成功了，反编译budnle.zip（apk），可以验证改动\\n重启后\\n还是查看这两个文件，updateinfo的内容有没有变，或者storage下merge后bundle的产物是否存在\\n/data/data/\\\\${pkg}/files/bundleBaseline/updateinfo\\n/data/data/pkg/files/storage/\\\\${bundle\\\\_pkg\\\\_name}/bundle.zip\\n没有异常，说明本次动态部署生效。\\n如果有异常，返回检查第一步的产物。\\n\"},\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\":{\"url\":\"code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\",\"title\":\"Atlas之Gradle配置\",\"keywords\":\"\",\"body\":\"概述\\nAtlas一个运行于Android系统上的一个容器化框架。为了实现这一目标，在编译器和运行期，Atlas都做了很多工作。本文是一个入门级别的文章，梳理从gradle配置到生成最终apk的期间，Atlas框架到底搞了哪些事情。\\n代码以 官方demo 为例。\\ngradle分析\\ngradle部分，我们只用看主工程app和bundle的配置就可以了。\\napp\\nbuild.gradle\\n# 第一部分\\nandroid {\\n    //...\\n}\\n\\n# 第二部分\\natlas {\\n    //...\\n}\\n\\n# 第三部分\\ndependencies {\\n    compile xxx\\n    bundleCompile xxx\\n}\\n\\n可以很清楚的看到，gradle的配置主要分为三大块，依次是标准的android插件配置、atlas插件的配置，以及依赖管理部分。我们重点看最后两个部分。\\nAtlas插件配置\\natlas插件有很多参数，这里只关注demo中出现的重点参数，其它设置大家可以查看官方文档。\\natlas {\\n    atlasEnabled true\\n    tBuildConfig {\\n        autoStartBundles = ['com.taobao.firstbundle'] \\n        outOfApkBundles = ['remotebundle']\\n        preLaunch = 'com.taobao.demo.DemoPreLaunch'\\n    }\\n}\\natlasEnabled  开启atlas插件的开关，在编译期会做很多事情\\n\\nmerge各个bundle的manifest到app中\\n将bunde的资源进行分段\\n为四大组件预留一些坑位\\n生成一些class，记录bundle的关键信息 \\n打包bundle等等\\n\\nautoStartBundles 指定第一个需要启动的bundle，在Atlas框架初始化完毕后，会执行这里这里配置bundle的代码。\\npreLaunch 自定义初始化入口，这个类需要实现AtlasPreLauncher接口，回调时机是在atlas对系统进行hack之后，atlas框架开始初始化之前。\\n依赖管理配置\\n接着看依赖配置部分\\natlas {\\n    tBuildConfig {\\n        outOfApkBundles = ['remotebundle']\\n    }\\n}\\n\\ndependencies {\\n    compile fileTree(dir: 'libs', include: ['*.jar'])\\n    compile('com.taobao.android:atlas_core:5.0.7@aar') {\\n        transitive = true\\n    }\\n\\n    compile project(':middlewarelibrary')\\n    compile project(':splashscreen')\\n    compile project(':activitygroupcompat')\\n\\n    bundleCompile project(':firstbundle')\\n    bundleCompile project(':secondbundle')\\n    bundleCompile project(':remotebundle')\\n    bundleCompile project(':publicbundle')\\n\\n    compile 'com.android.support:appcompat-v7:25.1.0'\\n}\\ndependencies主要分为三个部分\\n\\ncomile xxx     \\nbundleCompile xxx\\noutOfApkBundles =['xxx']\\n\\ncompile : 常规的打包配置，会将依赖代码打入到dex中去\\nbundleCompile : atlas 的配置项，表示apk的bunde依赖，即apk是由这些bundle共同组成。\\n\\nbundle中的代码不会打入dex中去，bundle将以libxxx.so文件的形式，放在apk的lib目录下，随包发布\\n\\noutOfApkBundles : 指定远程bundle \\n\\n比如在demo中，firstbundle、secondbundle、publicbundle 会打入apk中，而remotebundle不会\\n\\n小结\\n可以看到，在atlas框架中，主app只是一个壳子，只是用来配置打包参数的\\n比如在demo中，配置了以下打包设置\\n\\napp的包名、版本号...\\n需要打入dex的代码 (appcompat...)\\n随包发布但是不打入dex的代码 (firstbundle、secondbundle、publicbundle)\\n独立打包，用于后续的动态下发 (remotebundle)。\\n\\n盗用一张老大的图\\n\\nbundle\\n以secondbundle为例，看一下bundle中gradle的配置\\napply plugin: 'com.android.library'\\napply plugin: 'com.taobao.atlas'\\n\\natlas {\\n    bundleConfig{\\n        awbBundle true\\n    }\\n}\\n\\nandroid {\\n    //...\\n}\\n\\ndependencies {\\n    compile fileTree(dir: 'libs', include: ['*.jar'])\\n    compile project(\\\":secondbundlelibrary\\\");\\n    providedCompile 'com.android.support:appcompat-v7:25.1.0'\\n    providedCompile 'com.android.support:support-v4:25.3.0'\\n    providedCompile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8'\\n    providedCompile project(':middlewarelibrary')\\n}\\n首先apply plugin: 'com.taobao.atlas'和awbBundle true表明启用了atlas插件，并将当前模块编译成awb形式的bundle供主apk使用。\\n而在 dependencies 中可以看到有两种形式的依赖\\n\\n\\n\\n依赖方式\\n说明\\n\\n\\n\\n\\nprovidedCompile\\n主dex中已经打入了必要的公用代码(appcompat、middlewarelibrary)，在runtime时，atlas框架会自动找到主dex中的class使用，所以secondbundl就不需要在重复打入\\n\\n\\ncompile\\nsecondbundlelibrary之前并没有打入主dex中，因为这只是secondbundle所需要的依赖。最终会将secondbundle和secondbundlelibrary的打在一个同一个dex中，加上两者的资源，成为一个bundle\\n\\n\\n\\napk结构分析\\n在看完gradle的配置之后，我们反编译demo的apk，看一下最终生成的结构。\\nhost\\nmanifest\\n首先，贴一张反编译后的manifest\\n\\n可以看到，manifest中的内容大概分为三大块\\n\\nhost 的manifest部分\\nbunde 的的manifet部分\\n额外的配置\\n\\n\\n\\n\\nmanifest\\n说明\\n\\n\\n\\n\\nhost\\n常规编译产生的清单数据，包括app工程自身的代码和compile依赖的代码\\n\\n\\nbundle\\nbundle部分的清单数据，包括在app工程中bundleCompile的依赖代码和bundle自身compile的依赖代码\\n\\n\\n配置\\natlas插件在编译期生成的配置信息。比如在gradle中配置了 autoStartBundles = ['com.taobao.firstbundle']，编译时，会将firstbundle中application路径写入manifest。程序运行时，atlas会第一个执行firstbundle中DemoApplication中的代码\\n\\n\\n\\n主dex\\n分析完manifest之后，我们看一看host的dex文件，看一看有没有对java代码动手脚。\\n\\n乍看之下，似乎并没有什么不妥。但是，细心的同学可能发现了，少了bundle部分的代码。\\n结合app工程gradle的配置，我们发现以compile开头的依赖(middleware、utils、update),都是正常将java代码打入dex中。而以budleCompile开头的依赖(firstbundle、secondbundle)，他们的代码并没有在dex中。\\n那么，bundle的代码在哪里呢？ 我们接着往下看\\nbundle\\nbundle的存放位置\\n\\nbundle的代码和资源其实独立打成了一个apk，放在了apk的lib目录下，在运行时进行动态加载。\\nmanifest\\nbundle中的manifest中没有任何东西， 感兴趣的同学可以自行验证。\\n\\n这部分内容在编译期已经写到app的manifest中了，这也是 组件化和插件化 的区别之一\\n\\ndex\\n最后确认一下以secondbundle的代码，\\n\\n果然，每个bundle的代码都是各自打包的。\\n总结\\natlas将一个apk分为host和bundle两大部分\\n\\nhost为共用代码资源和各个bundle的manifest信息\\nbundle独立打包，拥有独立的dex和资源\\n像搭积木一样，host和不同的bundle组合编译成一个apk\\n\\n\\n参考\\n\\n官方文档\\ndemo\\n\\n\"},\"code_read/atlas_start/atlas_start_1.html\":{\"url\":\"code_read/atlas_start/atlas_start_1.html\",\"title\":\"Atlas之启动过程(一)\",\"keywords\":\"\",\"body\":\"概述\\nAtlas整个启动过程的时序如下图所示，本篇只关注下图中的1-5步。\\n\\n入口\\n我们都知道，app的入口是application，那么atlas的入口application是什么呢，看一下app模块中manifest中的定义\\n\\n看样子，是DemoApplication\\n真的是这样的吗？\\n当然不是\\n我们看一下反编译后的manifest\\n\\n为什么会是AtlasBridgeApplication呢，manifest中明明写的很清楚 : DemoApplication。\\n事实上为了接入的方便，Atlas在编译期就替换了入口application。不过，Atlas保证在运行期时会调用DemoApplication的相关方法。\\n1. AtlasBridgeApplication.attachBaseContext\\n我们看一下AtlasBridgeApplication中的相关方法\\n@Override\\nprotected void attachBaseContext(Context base) {\\n    super.attachBaseContext(base);\\n    //...一些逻辑\\n\\n    //1. 构造BridgeApplicationDelegate对象\\n    Class BridgeApplicationDelegateClazz = getBaseContext().getClassLoader().loadClass(\\\"android.taobao.atlas.bridge.BridgeApplicationDelegate\\\");\\n    Constructor con = BridgeApplicationDelegateClazz.getConstructor(parTypes);\\n    mBridgeApplicationDelegate = con.newInstance(this,getProcessName(...);\\n\\n    //2. 执行BridgeApplicationDelegate的attachBaseContext方法\\n    Method method = BridgeApplicationDelegateClazz.getDeclaredMethod(\\\"attachBaseContext\\\");\\n    method.invoke(mBridgeApplicationDelegate);\\n}\\n\\n可以看到，代码虽长，但其实就只干了两件事。\\n\\n反射并构造BridgeApplicationDelegate的实例\\n执行BridgeApplicationDelegate的attachBaseContext方法。\\n\\n先看BridgeApplicationDelegate的构造方法。\\n//BridgeApplicationDelegate.java\\npublic BridgeApplicationDelegate(Application rawApplication...){\\n    mRawApplication = rawApplication;\\n    PackageManagerDelegate.delegatepackageManager(\\n        rawApplication.getBaseContext()\\n    );\\n}\\n\\n没什么内容，直接跟进delegatepackageManager的函数实现\\n//PackageManagerDelegate.java\\npublic static void delegatepackageManager(Context context){\\n      mBaseContext = context;\\n      //1. 反射pm\\n      PackageManager manager = mBaseContext.getPackageManager();\\n      Class ApplicationPackageManager = Class.forName(\\\"android.app.ApplicationPackageManager\\\");\\n      Field field = ApplicationPackageManager.getDeclaredField(\\\"mPM\\\");\\n      field.setAccessible(true);\\n      Object rawPm = field.get(manager);\\n      //2. 动态代理pm\\n      Class IPackageManagerClass = Class.forName(\\\"android.content.pm.IPackageManager\\\");\\n      mPackageManagerProxyhandler = new PackageManagerProxyhandler(rawPm);            \\n      mProxyPm = Proxy.newProxyInstance(mBaseContext.getClassLoader(), new Class[]{IPackageManagerClass}, mPackageManagerProxyhandler);\\n      //3. 替换pm\\n      field.set(manager, mProxyPm);\\n}\\n\\n可以看到，这段代码的核心思想就是将系统的pm，替换为我们实现的PackageManagerProxyhandler。我们先不关注PackageManagerProxyhandler的实现，接着看BridgeApplicationDelegate中函数attachBaseContext的实现。\\n2. BridgeApplicationDelegate. attachBaseContext\\nBridgeApplicationDelegate.java\\npublic void attachBaseContext(){\\n    //2.1 hook之前准备工作\\n    AtlasHacks.defineAndVerify();\\n\\n    //2.2 回调预留接口\\n   launcher.initBeforeAtlas(mRawApplication.getBaseContext());\\n\\n   //2.3 初始化atlas     \\n   Atlas.getInstance().init(mRawApplication, mIsUpdated);\\n\\n   //2.4 处理provider    \\n    AtlasHacks.ActivityThread$AppBindData_providers.set(mBoundApplication,null);\\n}\\n\\n函数实现大概分为四个部分，也是本篇文章的重点关注部分\\n\\nhook之前的准备工作\\n回调预留接口\\n初始化atlas\\n处理provider\\n\\n我们也一个来看。\\n3. AtlasHacks.defineAndVerify\\n在开始分析之前，我们要知道，Android上动态加载方案，始终都绕不过三个关键的点:\\n\\n动态加载class \\n动态加载资源 \\n处理四大组件 能够让动态代码中的四大组件在Android上正常跑起来\\n\\n为了实现这三个目标，会在系统关键调用的地方进行Hook。比如，为了能够动态加载class，通常都会对classloader上动一些手脚，resource也是类似。\\n这里多提一句，在四大组件的处理上，atals与插件化有着很大的差异。\\n\\n插件化的核心思想其实是埋坑机制+借尸还魂 ：通过预先在manifest中预留N个组件坑，在runtime时，通过“借尸还魂”实现四大组件的运行。\\natlas不一样，它是在编译期就已经各个bundle的manifest写入到apk中。所以运行时，bundle中的组件可以和常规声明的组件一样正常运行，不用再做额外的处理。\\n\\n回过头来，我们看看atlas为了实现上述目的，做了哪些准备工作。在跟进defineAndVerify函数的实现之前，先看一下AtlasHacks类中定义的字段\\n//AtlasHacks.java\\n\\n     // Classes\\n    public static HackedClass                           LoadedApk;\\n    public static HackedClass                           ActivityThread;\\n    public static HackedClass    Resources;\\n\\n    // Fields\\n    public static HackedField          ActivityThread_mInstrumentation;\\n    public static HackedField              LoadedApk_mApplication;\\n    public static HackedField                LoadedApk_mResources;\\n\\n    // Methods\\n    public static HackedMethod                                  ActivityThread_currentActivityThread;\\n    public static HackedMethod                                  AssetManager_addAssetPath;\\n    public static HackedMethod                                  Application_attach;\\n    public static HackedField              LoadedApk_mClassLoader;\\n\\n    // Constructor\\n    public static Hack.HackedConstructor                        PackageParser_constructor;\\n给这段代码点个赞，非常的干净和清晰。代码定义了atlas框架所需要hook的所有的类、方法、属性等等字段。\\n\\n处理资源，hook Resources\\n处理class，hook LoadedApk_mClassLoader\\n...\\n\\n现在，在看defineAndVerify函数的实现\\n//AtlasHacks.java\\npublic static boolean defineAndVerify() throws AssertionArrayException {\\n     allClasses();\\n     allConstructors();\\n     allFields();\\n     allMethods();\\n}\\n实际上这四个级别的函数调用，对应之前定义的字段，为这些字段进行赋值。\\n//AtlasHacks.java\\npublic static void allClasses() throws HackAssertionException {\\n    LoadedApk = Hack.into(\\\"android.app.LoadedApk\\\");\\n    ActivityThread = Hack.into(\\\"android.app.ActivityThread\\\");\\n    Resources = Hack.into(Resources.class);\\n    ActivityManager = Hack.into(\\\"android.app.ActivityManager\\\");\\n    //...\\n}\\n\\npublic static void allFields() throws HackAssertionException {\\n    ActivityThread_mInstrumentation = ActivityThread.field(\\\"mInstrumentation\\\").ofType(Instrumentation.class);\\n    ActivityThread_mAllApplications = ActivityThread.field(\\\"mAllApplications\\\").ofGenericType(ArrayList.class);\\n}\\n\\n//...\\n\\n这几个函数的代码并不复杂，是对定义的Class、Field、Method和Contructor 这些字段进行初始化赋值工作。\\n执行到这里时，atlas框架的准备工作完成，接下来，就是整个框架的初始化了。\\n4 回调预留接口\\n时序图中的第4步，即BridgeApplicationDelegate的attachBaseContext方法中，，做了一个接口回调。\\nBridgeApplicationDelegate.java\\npublic void attachBaseContext(){\\n   String preLaunchStr = (String) RuntimeVariables.getFrameworkProperty(\\\"preLaunch\\\");\\n   AtlasPreLauncher launcher = (AtlasPreLauncher) Class.forName(preLaunchStr).newInstance();\\n   launcher.initBeforeAtlas(mRawApplication.getBaseContext());\\n   //...\\n}\\n\\n函数通过“preLaunch”字段读取一个类名，反射该类上的initBeforeAtlas方法。\\nAtlasPreLauncher实际上是一个接口，供接入者使用。在这个点，atlas还没有开始对系统进行hook，仍然是Android原生态的运行时环境。\\n那么这个preLaunch的字段在哪里定义的呢，我们反推一下。\\nRuntimeVariables.java\\npublic static Object getFrameworkProperty(String fieldName){\\n    //...\\n    Field field = FrameworkPropertiesClazz.getDeclaredField(fieldName);\\n    return field.get(FrameworkPropertiesClazz);\\n}\\n\\n实现很简单，读取FrameworkProperties上的静态属性字段，接着跟进。\\npublic class FrameworkProperties {\\n}\\n\\n什么情况，怎么什么都没有? 所谓反常即为💊，直接看反编译后的代码\\nFrameworkProperties.java\\npublic class FrameworkProperties{\\n  //...\\n  public static String autoStartBundles;\\n  public static String preLaunch;\\n\\n  static{\\n    autoStartBundles = \\\"com.taobao.firstbundle\\\";\\n    preLaunch = \\\"com.taobao.demo.DemoPreLaunch\\\";\\n  }\\n}\\n\\n从反编译后的代码可以看到，\\\"prelaunch\\\"对应的内容是com.taobao.demo.DemoPreLaunch,那么这个值是在 什么时候写入又是在哪里配置 的呢？\\n大家回想一下，在之前Atlas之Gradle配置中提到过，atlas的gradle插件在编译期搞了很多事情，我们看gradle中的设置\\natlas{\\n     tBuildConfig {\\n        autoStartBundles = ['com.taobao.firstbundle']\\n        preLaunch = 'com.taobao.demo.DemoPreLaunch'\\n    }\\n}\\n\\n和FrameworkProperties中的字段完美对应。\\n这个部分牵涉开发-编译-运行三个阶段，放一张图捋一下关系。\\n\\n5 atlas.init\\n准备工作做好之后，就是初始化了。\\nAtlas.java\\npublic void init(Application application,boolean reset) {\\n    //读取配置项\\n    ApplicationInfo appInfo = mRawApplication.get...;\\n    mRealApplicationName = appInfo.metaData.getString(\\\"REAL_APPLICATION\\\");\\n    boolean multidexEnable = appInfo.metaData.getBoolean(\\\"multidex_enable\\\");\\n\\n    if(multidexEnable){\\n      MultiDex.install(mRawApplication);\\n   }\\n    //...   \\n}\\n首先是读取manifest中的配置数据multidexEnable和mRealApplicationName，这两个数据也是在编译期由atlas插件写到manifest中的。\\n\\nmultidexEnable 是true，这个在gradle中可配\\nmRealApplicationName 实际上是DemoApplication,即app工程在manifest中指定的启动路径。\\n捋清楚这几个参数之后，往下看Atlas框架初始化实现\\nAtlas.java\\npublic void init(Application application,boolean reset) {\\n   //...\\n   Atlas.getInstance().init(mRawApplication, mIsUpdated);\\n}\\n\\npublic void init(Application application,boolean reset) throws AssertionArrayException, Exception {\\n     //...\\n\\n     //1. 换classloader \\n     AndroidHack.injectClassLoader(packageName, newClassLoader);\\n     //2. 换Instrumentatio\\n     AndroidHack.injectInstrumentationHook(new InstrumentationHook(AndroidHack.getInstrumentation(), application.getBaseContext()));\\n     //3. hook ams\\n     try {\\n         ActivityManagerDelegate activityManagerProxy = new ActivityManagerDelegate();\\n         Object gDefault = null;\\n         if(Build.VERSION.SDK_INT>25 || (Build.VERSION.SDK_INT==25&&Build.VERSION.PREVIEW_SDK_INT>0)){\\n             gDefault=AtlasHacks.ActivityManager_IActivityManagerSingleton.get(AtlasHacks.ActivityManager.getmClass());\\n         }else{\\n               gDefault=AtlasHacks.ActivityManagerNative_gDefault.get(AtlasHacks.ActivityManagerNative.getmClass());\\n         }\\n         AtlasHacks.Singleton_mInstance.hijack(gDefault, activityManagerProxy);\\n      }catch(Throwable e){}\\n      //4. hook H\\n      AndroidHack.hackH();\\n}\\n这段代码，就是对系统关键节点进行了hook，具体的hook实现这里就不贴出了，如果感兴趣，可以参考demo源码以及田维术的blog，如何hook，以及为什么在这里hook，在文章中都讲的非常清楚。\\n函数中的hook点\\n\\n\\n\\nhook点\\n实例\\n\\n\\n\\n\\nActivityThread.mLoadedApk.mClassLoader\\nDelegateClassLoader\\n\\n\\nActivityThread.mInstrumentation\\nInstrumentationHook\\n\\n\\nActivityManagerNative.gDefault.get\\nActivityManagerDelegate\\n\\n\\nandroid.app.ActivityThread$H.mCallback\\nActivityThreadHook\\n\\n\\n\\n6. 处理provider\\n在第2步的2.4部分，对provider进行了处理\\nBridgeApplicationDelegate.java\\npublic void attachBaseContext(){\\n    //...\\n\\n   //2.4 处理provider\\n   Object mBoundApplication = AtlasHacks.ActivityThread_mBoundApplication.get(activityThread);\\n   mBoundApplication_provider = AtlasHacks.ActivityThread$AppBindData_providers.get(mBoundApplication);\\n   if(mBoundApplication_provider!=null && mBoundApplication_provider.size()>0){\\n           AtlasHacks.ActivityThread$AppBindData_providers.set(mBoundApplication,null);\\n    }\\n}\\n\\n第4行代码读取provider数据，如果有provider信息的话，则在第6行从系统删除，让系统认为apk并没有申请任何provider。\\n为什么这么做?回顾一下app启动的流程\\n\\n可以看到，在第4步和第7步两个关键调用之间，第5步调用了函数installContentProviders,跟进去看一下。\\nprivate void installContentProviders(Context context, List providers) {\\n    for (ProviderInfo cpi : providers) {\\n        installProvider(context, null, cpi,...);\\n    }\\n}\\n收集了所有provider的信息，然后调用installProvider函数\\nprivate IActivityManager.ContentProviderHolder installProvider(Context context,IActivityManager.ContentProviderHolder holder, ProviderInfo info,...) {\\n    final java.lang.ClassLoader cl = c.getClassLoader();\\n   localProvider = (ContentProvider)cl.loadClass(info.name).newInstance();\\n   //...\\n}\\n可以看到，函数是根据在manifest中登记的provider信息，实例化对象。\\n那么问题来了，有些provider是存在于bundle中的，主dex中并不存在。如果不处理，在这里程序会因为ClassNotFind崩溃。所以这里要先清除掉provier的信息，延迟加载。\\n\\n上篇先到这里，各位先喝口水，再来下篇的分析。\\n\"},\"code_read/atlas_start/atlas_start_2.html\":{\"url\":\"code_read/atlas_start/atlas_start_2.html\",\"title\":\"Atlas之启动过程(二)\",\"keywords\":\"\",\"body\":\"概述\\n接上篇 Atlasz之启动过程(一) ,继续 6-10 步的启动过程。\\n\\n6. onCreate\\nAtlasBridgeApplication.java\\n@Override\\npublic void onCreate() {\\n    super.onCreate();\\n    Method method = mBridgeApplicationDelegate.getClass().getDeclaredMethod(\\\"onCreate\\\");\\n    method.invoke(mBridgeApplicationDelegate);       \\n}\\n\\n直接反射调用mBridgeApplicationDelegate的onCreate方法.\\n7. BridgeApplicationDelegate.onCreate\\nBridgeApplicationDelegate.java\\npublic void onCreate(){\\n   // 7.1 实例application\\n    mRealApplication = (Application) mRawApplication.getBaseContext()\\n        .getClassLoader().loadClass(mRealApplicationName).newInstance();\\n\\n    //7.2 replace xxx\\n    AtlasHacks.ContextImpl_setOuterContext.invoke(\\n        mRawApplication.getBaseContext(), mRealApplication);\\n    //...\\n\\n    //7.3 mRealApplication.attach\\n    AtlasHacks.Application_attach\\n           .invoke(mRealApplication,mRawApplication.getBaseContext());\\n\\n    //7.4 install content providers\\n    Object mBoundApplication = AtlasHacks.ActivityThread_mBoundApplication.get(activityThread);\\n    AtlasHacks.ActivityThread$AppBindData_providers.set(mBoundApplication,mBoundApplication_provider);\\n    AtlasHacks.ActivityThread_installContentProviders.invoke(activityThread,mRealApplication,mBoundApplication_provider);\\n\\n    //7.5. startup\\n    Atlas.getInstance().startup(mRealApplication,mIsUpdated);\\n\\n    //7.6 onCreate\\n    mRealApplication.onCreate();\\n}\\n函数有点长，不过内容大概分为6块\\n\\n实例化app工程中指定的mRealApplication\\n替换application\\n反射执行mRealApplication的attach方法\\n加载provider\\nAtlas.startup\\n调用mRealApplication.onCreate方法\\n\\n7.1 实例application\\nmRealApplication = (Application) mRawApplication.getBaseContext()\\n        .getClassLoader().loadClass(mRealApplicationName).newInstance();\\n\\nmRealApplicationName实际上是指com.taobao.demo.DemoApplication。在这里，构造出了app工程中指定application的对象实例。\\n7.2 替换application\\n//replace baseContext.mOuterContext\\nAtlasHacks.ContextImpl_setOuterContext.invoke(mRawApplication.getBaseContext(), mRealApplication);\\n\\n//replace baseContext.mPackageInfo.mApplication\\nObject mPackageInfo = AtlasHacks.ContextImpl_mPackageInfo.get(mRawApplication.getBaseContext());\\n\\n//...\\n\\n7.2部分，为了保证DemoApplication能够像正常声明的application一样正常工作，做了大量的hook。这里不关注具体hook实现，只给出hook后的映射，感兴趣的童鞋可以自行研究。\\n\\n\\n\\n替换点\\n实现类\\n\\n\\n\\n\\nContextImpl.mOuterContextt\\nDemoApplication\\n\\n\\nContextImp.mPackageInfo\\nDemoApplication\\n\\n\\nActivityThread.mInitialApplication\\nDemoApplication\\n\\n\\nActivityThread.mAllApplications\\nDemoApplication\\n\\n\\n\\n7.3 Application.attach\\nAtlasHacks.Application_attach.invoke(mRealApplication,mRawApplication.getBaseContext());\\n\\nmRealApplication实际上就是DemoApplication,反射执行application的attach方法,即第8步。\\n7.4 加载provider\\nObject mBoundApplication = AtlasHacks.ActivityThread_mBoundApplication.get(activityThread);\\n\\nAtlasHacks.ActivityThread$AppBindData_providers.set(mBoundApplication,mBoundApplication_provider);\\n\\nAtlasHacks.ActivityThread_installContentProviders.invoke(activityThread,mRealApplication,mBoundApplication_provider);\\n\\n在Atlas启动过程(上)的2.4小节中，为了防止在主dex中找不到bundle中的class,不得已延迟了对provider的加载。而在第5步中，atlas完成了对classloader等关键地方的hook。由于DelegateClassLoader的存在，此时进行加载provider，是不会出现问题的。\\n8. DemoApplication.attach\\nDemoApplication.java\\nfinal void attach(Context context) {\\n    attachBaseContext(context);\\n    mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;\\n}\\n\\n由7.3可知，mRealApplication实际上就是DemoApplication\\n\\n调用DemoApplication的attachBaseContext方法\\n为DemoApplication创建一个LoadedApk对象\\n\\n9. startUp\\n\\n在startup整个函数周期内，做的事情非常之多，重要的是第3、4、6、7和8步。\\n9.3\\npublic void init(Context context, boolean hookedJavaVM) {\\n    if(VMUtil.IS_VM_ART) {\\n        success = Boolean.valueOf(ARTUtils.init(context, hookedJavaVM));\\n    } else {\\n       success = Boolean.valueOf(DalvikUtils.init());\\n   }\\n}\\n看函数名，是针对art和dalvik工具类进行初始化。 \\n//DalvikUtils.java\\npublic static boolean init() {\\n    System.loadLibrary(\\\"dalvikhack\\\");\\n    nativeInit();\\n}\\n\\n//ARTUtils.java\\npublic static boolean init(Context context, boolean hookedJavaVM) {\\n    System.loadLibrary(\\\"dexinterpret\\\");\\n    nativeInit(...);\\n}\\n9.4\\npublic static int patchIfPossible() {\\n    System.loadLibrary(\\\"dalvikpatch\\\");\\n    if(isDalvik()) {\\n           int ingored = adjustLinearAlloc();\\n    }\\n    return 0;\\n}\\n首先加载dalvikpatchso,用途： todo \\n接着执行 adjustLinearAlloc方法 ，用途 todo\\n9.7\\nprivate synchronized void InitBundleInfoByVersionIfNeed(){\\n    String bundleInfoStr = (String)RuntimeVariables.getFrameworkProperty(\\\"bundleInfo\\\");\\n    if(!TextUtils.isEmpty(bundleInfoStr)) {\\n        LinkedHashMap infos = BundleListingUtil.parseArray(bundleInfoStr);\\n        BundleListing listing = new BundleListing();\\n        listing.setBundles(infos);\\n        mCurrentBundleListing = listing;\\n    }\\n}\\n可以看到，函数是从RuntimeVariables读取字符串，之后解析成对象存储。很明显，这个字符串应该是配置之类的信息。在atals从gradle到apk中，我们提到过，atlas会在编译期间会分析bundle和gradle配置，将一些配置写入RuntimeVariables中。\\npackage android.taobao.atlas.framework;\\n\\npublic class FrameworkProperties\\n{\\n  public static String autoStartBundles;\\n  public static String bundleInfo = \\\"[{\\\\\\\"activities\\\\\\\":[\\\\\\\"com.taobao.firstbundle.FirstBundleActivity\\\\\\\"],\\\\\\\"contentProviders\\\\\\\":[],\\\\\\\"dependency\\\\\\\":[],\\\\\\\"isInternal\\\\\\\":true,\\\\\\\"pkgName\\\\\\\":\\\\\\\"com.taobao.firstbundle\\\\\\\",\\\\\\\"receivers\\\\\\\":[],\\\\\\\"services\\\\\\\":[\\\\\\\"com.taobao.firstbundle.FirstBundleService\\\\\\\"],\\\\\\\"version\\\\\\\":\\\\\\\"1.0.0@unspecified\\\\\\\"},{\\\\\\\"activities\\\\\\\":[\\\\\\\"com.taobao.secondbundle.SecondBundleActivity\\\\\\\",\\\\\\\"com.taobao.secondbundlelibrary.SecondbundleShareActivity\\\\\\\"],\\\\\\\"contentProviders\\\\\\\":[],\\\\\\\"dependency\\\\\\\":[],\\\\\\\"isInternal\\\\\\\":true,\\\\\\\"pkgName\\\\\\\":\\\\\\\"com.taobao.secondbundle\\\\\\\",\\\\\\\"receivers\\\\\\\":[],\\\\\\\"services\\\\\\\":[],\\\\\\\"version\\\\\\\":\\\\\\\"1.0.0@unspecified\\\\\\\"},{\\\\\\\"activities\\\\\\\":[\\\\\\\"com.taobao.remotebunle.RemoteBundleActivity\\\\\\\"],\\\\\\\"contentProviders\\\\\\\":[],\\\\\\\"dependency\\\\\\\":[],\\\\\\\"isInternal\\\\\\\":false,\\\\\\\"pkgName\\\\\\\":\\\\\\\"com.taobao.remotebunle\\\\\\\",\\\\\\\"receivers\\\\\\\":[],\\\\\\\"services\\\\\\\":[],\\\\\\\"version\\\\\\\":\\\\\\\"1.0.0@unspecified\\\\\\\"},{\\\\\\\"activities\\\\\\\":[],\\\\\\\"contentProviders\\\\\\\":[],\\\\\\\"dependency\\\\\\\":[],\\\\\\\"isInternal\\\\\\\":true,\\\\\\\"pkgName\\\\\\\":\\\\\\\"com.taobao.publicBundle\\\\\\\",\\\\\\\"receivers\\\\\\\":[],\\\\\\\"services\\\\\\\":[],\\\\\\\"version\\\\\\\":\\\\\\\"1.0.0@unspecified\\\\\\\"}]\\\";\\n\\n  static\\n  {\\n    autoStartBundles = \\\"com.taobao.firstbundle\\\";\\n  }\\n}\\n可以看到，bundleInfo 字段是一堆json字段，解析后格式BundleInfo,保存着bundle的信息。\\npublic static class BundleInfo{\\n    private String pkgName;\\n    private String applicationName；\\n    private List dependency;\\n    private HashMap activities;\\n    private HashMap services;\\n    private HashMap receivers;\\n    private HashMap contentProviders;\\n    //...\\n}\\n也就是说，在这一步， atlas获得了所有bundle的信息 。\\n9.8\\nprivate void started(){\\n    //读取配置\\n    String autoStartBundle = (String) RuntimeVariables.getFrameworkProperty(\\\"autoStartBundles\\\");\\n    String[] bundles = autoStartBundle.split(\\\",\\\");\\n\\n    //异步安装bundle\\n    for (int x = 0; x 简化了大部分代码，只关注核心逻辑。代码读取RuntimeVariables上的字段autoStartBundles,这个值是在gradle中配置的com.taobao.firstbundle，然后开始异步加载firstbundle\\nbundle的加载过程和加载触发时机请参考 Atlas之bundle加载过程，这里不在讨论。\\n10. DemoApplication.onCreate\\nDemoApplication.java\\npublic void onCreate() {\\n    super.onCreate();\\n    //...\\n}\\n\\n执行app工程定义的DemoApplication的onCreate方法。\\n\\n至此，Atlas启动过程的分析完成。\\n\"},\"code_read/atlas_bundle_load/atlas_bundle_load.html\":{\"url\":\"code_read/atlas_bundle_load/atlas_bundle_load.html\",\"title\":\"Atlas之Bundle加载过程\",\"keywords\":\"\",\"body\":\"概述\\natals中bundle加载过程\\n\\nclass\\nresource\\n\\n\\n注意图中的箭头\\n\\n实线箭头表示运行在主线程\\n虚线箭头表示运行在HandlerThread中\\n\\n将流程分为三大部分\\n\\n\\n\\n部分\\n说明\\n对应步骤\\n\\n\\n\\n\\n第一部分\\n加载时机的触发逻辑\\n1-7\\n\\n\\n第二部分\\nbundle加载过程\\n8-15\\n\\n\\n第三部分\\nbundle代码初始化\\n16-19\\n\\n\\n\\n第一部分 触发时机\\n入口\\n以在MainActivity中点击secondebundle为例\\nMainActivity.java\\ncase R.id.navigation_dashboard:\\n    switchToActivity(\\\"second\\\",\\\"com.taobao.secondbundle.SecondBundleActivity\\\")\\nswitchActivity 辗调用，会执行到第2步execStartChildActivityInternal方法中\\nexecStartChildActivityInternal\\nActivityGroupDelegate.java\\npublic void execStartChildActivityInternal(ViewGroup container,String key, Intent intent){\\n    String bundleName = AtlasBundleInfoManager.instance().getBundleForComponet(componentName);\\n    if(!TextUtils.isEmpty(bundleName)){\\n        BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(bundleName);\\n        if(impl!=null&&impl.checkValidate()) {    }else {\\n        //...\\n        asyncStartActivity(container,key,bundleName,intent);\\n    }\\n}\\n\\n首先，根据componentName即com.taobao.secondbundle.SecondBundleActivity,查询bundle的名称。在atlas启动过程(下)中，我们知道AtlasBundleInfoManager中存储了几乎所有bundle的信息，所以返回 bundleName 就是 com.taobao.secondbundle。\\n然后，根据bundlename，去查询bundle加载后的结构体- BundleImpl。由于secondbundle之前并没有加载进来，所以会执行到第3步asyncStartActivity方法。\\n\\nasyncStartActivity最终调用了BundleUtil的方法，我们直接看第4步 checkBundleStateAsync\\ncheckBundleStateAsync\\nBundleUtil.java\\npublic static boolean checkBundleArrayStateAsync(final String[] bundlesName, final Runnable bundleActivated, final Runnable bundleDisabled){\\n    BundleInstaller installer = BundleInstallerFetcher.obtainInstaller();\\n    installer.installTransitivelyAsync(bundlesName, new BundleInstaller.InstallListener() {\\n        @Override\\n        public void onFinished() {\\n            boolean success = true;\\n            BundleImpl tmp;\\n            for(String bundleName : bundlesName){\\n                if((tmp=((BundleImpl) Atlas.getInstance().getBundle(bundleName)))==null || !tmp.checkValidate()){\\n                    success = false;\\n                }else{\\n                    tmp.startBundle();\\n                }\\n          }\\n       });\\n    return true;\\n}\\n在这一步中，开始异步加载bundle，成功后，在主线程中回调onFinished(后面会提及),调用BundleImpl对象的startBundl方法，开始 第三部分 的初始化过程。 \\ndeliveryTask\\n第5、6步，主要是各种逻辑判断，之后辗转调用到7步。直接看第7步deliveryTask的函数实现。\\nBundleUtil.java\\nprivate void deliveryTask(boolean sync){\\n    Runnable installTask = new Runnable() {\\n        @Override\\n        public void run() {\\n            synchronized (BundleInstaller.this) {\\n                 try{\\n                     call();\\n                 } catch (Throwable e) {\\n                     e.printStackTrace();\\n                 } finally {\\n                     if (mListener != null) {\\n                         new Handler(Looper.getMainLooper()).post(new Runnable() {\\n                             @Override\\n                             public void run() {\\n                                 mListener.onFinished();\\n                             }\\n                 //..\\n        };\\n        sBundleHandler.post(installTask);\\n\\n    }\\n}\\n\\n函数首先创建了一个异步任务 installTask,之后将任务提交给sBundleHandler。而sBundleHandler实际上关联的是一个HandlerThread,所以，installTask是运行在单独的线程中的。\\n在 installTask 中\\n\\n调用了call函数\\n向ui线程提交一个任务，用于回调onFinished\\n\\n到目前为止，第一部分分析完毕，我们进入第二部分 加载过程 \\n第二部分 加载过程\\n需要注意的是，第二部分整体是运行在 HandlerThread 中的。\\n回顾一下第二部分的运行时序\\n\\ncall\\ncall(){\\n    //...\\n    if (FileUtils.getUsableSpace(Environment.getDataDirectory()) >= 5) {\\n        //has enough space\\n        if(AtlasBundleInfoManager.instance().isInternalBundle(bundleName)) {\\n            bundle = installBundleFromApk(bundleName);\\n            if (bundle != null) {\\n                ((BundleImpl) bundle).optDexFile();\\n            }\\n        }\\n    } else {\\n        throw new LowDiskException(\\\"no enough space\\\");\\n    }\\n    //...\\n}\\n这里有两个判断条件\\n\\n剩余存储空间满足\\n是内置bundle\\n\\n当两个条件都满足时，执行bundle的安装和optDexFile操作。\\ninstallBundleFromApk 又调用了 installNewBundle方法，直接看第9步 - installNewBundle 的实现。\\ninstallNewBundle\\nFramework.java\\nstatic BundleImpl installNewBundle(final String location, final InputStream in)throws BundleException {\\n    //...\\n    BundleListing.BundleInfo info = AtlasBundleInfoManager.instance().getBundleInfo(location);\\n    BundleImpl bundle = new BundleImpl(bundleDir, location, new BundleContext(), null, file,version,true,-1);\\n    return bundle;\\n}\\n函数很简单，获取bundle的信息，之后构造一个BundleImpl对象。\\n有两个参数需要注意一下\\n\\n\\n\\n参数\\n说明\\n\\n\\n\\n\\nbundleDir\\n/data/data/com.taobao.demo/files/storage/com.taobao.secondbundle\\n\\n\\nin\\n指向 lib/armeabi/libcom_taobao_secondbundle.so\\n\\n\\n\\nBundleImpl\\n来看BundleImpl的构造函数\\nBundleImpl.java\\nBundleImpl(final File bundleDir, final String location, final BundleContext context, final InputStream stream,...) throws BundleException, IOException{\\n        if (stream != null) {\\n            this.archive = new BundleArchive(location,bundleDir, stream,version, dexPatchVersion);\\n        } \\n\\n        if (autoload) {\\n            resolveBundle();\\n            Framework.bundles.put(location, this);\\n        }\\n}\\n首先创建了一个BundleArchive对象，bundleArchive持有bundleDir和InputStream的引用，用来做dexOpt的( ? todo )，暂时不关注，往下走\\nresolveBundle\\nBundleImpl.java\\n\\n    private synchronized void resolveBundle() throws BundleException {\\n        //...\\n        if ( this.classloader == null){\\n            // create the bundle classloader\\n            List dependencies = AtlasBundleInfoManager.instance().getDependencyForBundle(location);\\n            String nativeLibDir = getArchive().getCurrentRevision().getRevisionDir().getAbsolutePath()+\\\"/lib\\\"+\\\":\\\"\\n                    + RuntimeVariables.androidApplication.getApplicationInfo().nativeLibraryDir+\\\":\\\"\\n                    +System.getProperty(\\\"java.library.path\\\");\\n            if(dependencies!=null) {\\n                for (String str : dependencies) {\\n                    BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(str);\\n                    if (impl != null) {\\n                        nativeLibDir += \\\":\\\";\\n                        File dependencyLibDir = new File(impl.getArchive().getCurrentRevision().getRevisionDir(), \\\"lib\\\");\\n                        nativeLibDir += dependencyLibDir;\\n                    }\\n                }\\n            }\\n            this.classloader = new BundleClassLoader(this,dependencies,nativeLibDir);\\n        }\\n\\n        // notify the listeners\\n        Framework.notifyBundleListeners(0 /*LOADED*/, this);\\n    }\\n\\n为bundle创建一个classloader，在创建classloader的过程中\\n\\n指定bundle自身依赖so的路径\\n指定依赖bundle所依赖so的路径\\n\\n比如在demo中 ，nativeLibDir的 值为 /data/user/0/com.taobao.demo/files/storage/com.taobao.secondbundle/version.1/lib:/data/app/com.taobao.demo-1/lib/x86:/vendor/lib:/system/lib\\n创建完BundlerClassLoader后，在最后一行进行回调，这里的回调实现类是 BundleLifecycleHandler\\nBundleLifecycleHandler.java\\n public void bundleChanged(final BundleEvent event){\\n        switch (event.getType()) {\\n            case 0:/* LOADED */\\n                loaded(event.getBundle());\\n}\\nloaded\\nprivate void loaded(Bundle bundle) { long time = System.currentTimeMillis();\\n        BundleImpl b = (BundleImpl) bundle;\\n        DelegateResources.addBundleResources(\\n            b.getArchive().getArchiveFile().getAbsolutePath()\\n        );\\n}\\ntodo 资源处理实现说明\\n回到第10步\\nBundleImpl.java\\nBundleImpl(final File bundleDir, final String location...) {\\n    //...\\n    resolveBundle();\\n    Framework.bundles.put(location, this);    \\n}\\n在resolveBundle函数执行周期内，主要完成了两件事\\n\\n为bundle创建了独立的ClassLoader\\n将bundle中的资源添加到Resource上\\n\\n第二行函数将bundle的信息加入到已加载的列表中。\\n完成之后，回到第8步，执行optDexFile方法。\\noptDexFile\\n。。。\\n第三部分 初始化过程\\n整个第三部分运行在 UI 线程中\\nbundle加载完成后，第7步，在UI线程中回调了完成的接口，调用了startbundle方法又经过辗转调用，到了BundleLifecycleHandler的startd方法中。\\nBundleLifecycleHandler.java\\nprivate void started(Bundle bundle){\\n    BundleImpl b = (BundleImpl) bundle;\\n    BundleListing.BundleInfo info = AtlasBundleInfoManager.instance().getBundleInfo(b.getLocation());\\n    //...\\n    String appClassName = info.getApplicationName();\\n    Application app = newApplication(appClassName, b.getClassLoader());\\n    app.onCreate();\\n}\\n\\n在第6行构造出bundle中注册的application对象，之后执行application的onCreate方法。对于appliation来说，似乎还差一个关键的attachBaseContext的入口函数调用，我们接着看构造过程。\\nBundleLifecycleHandler.java\\nprotected static Application newApplication(String applicationClassName, ClassLoader cl) throws ApplicationInitException {\\n    final Class applicationClass = cl.loadClass(applicationClassName);\\n    Application app = (Application) applicationClass.newInstance();\\n    AtlasHacks.Application_attach.invoke(app, RuntimeVariables.androidApplication);\\n    return app;  \\n}\\n首先，根据类名加载对应的class，之后反射执行applciation的attach方法。\\n在Atlas之启动过程(二)下中，解释过，application的attach方法最终会调用到attachBaseContext方法。\\n最后，大概看一下DelegateClassLoader加载bundle中class的过程。\\nDelegateClassLoader.java\\nprotected Class findClass(String className) throws ClassNotFoundException {\\n    Class clazz = loadFromInstalledBundles(className,false);\\n    //...\\n    return clazz;\\n}\\n\\nstatic Class loadFromInstalledBundles(String className,boolean safe)\\n            throws ClassNotFoundException {\\n    String bundleName = AtlasBundleInfoManager.instance().getBundleForComponet(className);\\n    BundleImpl bundle = (BundleImpl) Atlas.getInstance().getBundle(bundleName);\\n    //...\\n    ClassLoader classloader = bundle.getClassLoader();\\n    Class  clazz = classloader.loadClass(className);\\n    return clazz;\\n}\\n可以看到，classloader先从bundle上去找的。而loadFromInstalledBundles逻辑如下:\\n\\n从AtlasBundleInfoManager上已加载的列表中找到对应bunde(在第在第10步中添加)\\n从对应bundle上的classloader上加载对应的class。\\n\\n\\n到这里为止，整个bundle的加载、初始化过程分析完毕。\\n\"}}}"
  },
  {
    "path": "atlas-docs/_book/update/dexpatch.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>dexpatch · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"dexpatch_use_guide.html\" />\n    \n    \n    <link rel=\"prev\" href=\"principle.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../guide-for-use/\">\n            \n                <a href=\"../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"./\">\n            \n                <a href=\"./\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"principle.html\">\n            \n                <a href=\"principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.4.2\" data-path=\"dexpatch.html\">\n            \n                <a href=\"dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"dexpatch_use_guide.html\">\n            \n                <a href=\"dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"guide.html\">\n            \n                <a href=\"guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../faq/question.html\">\n            \n                <a href=\"../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../faq/help.html\">\n            \n                <a href=\"../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../faq/variant.html\">\n            \n                <a href=\"../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >dexpatch</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"&#x4EC0;&#x4E48;&#x662F;dexpatch\">&#x4EC0;&#x4E48;&#x662F;Dexpatch</h1>\n<p>DexPatch&#x662F;&#x4EE5;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x6280;&#x672F;&#x65B9;&#x6848;&#x4E3A;&#x57FA;&#x7840;&#xFF0C;&#x4EE5;&#x5FEB;&#x901F;&#x89E3;&#x51B3;&#x7EBF;&#x4E0A;&#x6545;&#x969C;&#x4E3A;&#x552F;&#x4E00;&#x76EE;&#x7684;&#x7684;&#x52A8;&#x6001;&#x5316;&#x65B9;&#x6848;&#x3002;</p>\n<h2 id=\"&#x4E3A;&#x4EC0;&#x4E48;&#x4E0D;&#x7528;&#x52A8;&#x6001;&#x90E8;&#x7F72;\">&#x4E3A;&#x4EC0;&#x4E48;&#x4E0D;&#x7528;&#x52A8;&#x6001;&#x90E8;&#x7F72;</h2>\n<p>&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x51FA;&#x53D1;&#x70B9;&#x7ACB;&#x8DB3;&#x4E8E;&#x9700;&#x6C42;&#x7684;&#x5FEB;&#x901F;&#x8FED;&#x4EE3;&#xFF0C;&#x66FF;&#x6362;&#x666E;&#x901A;&#x7684;apk&#x5347;&#x7EA7;&#x3002;&#x6240;&#x4EE5;&#x5728;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x6F14;&#x8FDB;&#x8FC7;&#x7A0B;&#x4E2D;&#x7075;&#x6D3B;&#x6027;&#x6210;&#x4E3A;&#x6211;&#x4EEC;&#x4E0D;&#x65AD;&#x53BB;&#x8FFD;&#x6C42;&#x7684;&#x76EE;&#x6807;&#x3002;&#x5E0C;&#x671B;&#x4E0D;&#x65AD;&#x7F29;&#x5C0F;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x9650;&#x5236;&#x4EE5;&#x8FBE;&#x5230;&#x5B8C;&#x5168;&#x66FF;&#x6362;APK&#x66F4;&#x65B0;&#x7684;&#x80FD;&#x529B;&#x3002;\n&#x6B63;&#x662F;&#x56E0;&#x4E3A;&#x5176;&#x6BD4;&#x8F83;&#x5168;&#x9762;&#x7684;&#x80FD;&#x529B;&#xFF0C;&#x6211;&#x4EEC;&#x53D1;&#x73B0;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x5728;&#x6545;&#x969C;&#x4FEE;&#x590D;&#x65B9;&#x9762;&#x5B58;&#x5728;&#x5176;&#x4E0D;&#x8DB3;&#x7684;&#x5730;&#x65B9;&#xFF1A;</p>\n<ol>\n<li><p><strong>&#x6784;&#x5EFA;&#x901F;&#x5EA6;&#xFF1A;</strong>\n&#x5728;&#x6BCF;&#x4E2A;&#x9700;&#x6C42;&#x8FED;&#x4EE3;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x8003;&#x8651;&#x9700;&#x6C42;&#x7684;&#x590D;&#x6742;&#x6027;&#x548C;&#x6BCF;&#x6B21;&#x5468;&#x671F;&#x6027;&#x8FED;&#x4EE3;&#x7BA1;&#x7406;&#x7684;&#x6210;&#x672C;&#xFF0C;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x53C2;&#x8003;APK&#x8FED;&#x4EE3;&#x7684;&#x65B9;&#x5F0F;&#x901A;&#x8FC7;&#x7EDF;&#x4E00;&#x7684;&#x96C6;&#x6210;&#x533A;&#x8FDB;&#x884C;&#x7BA1;&#x7406;&#xFF0C;&#x6240;&#x4EE5;&#x5728;&#x6784;&#x5EFA;&#x4E0A;&#x52A8;&#x6001;&#x90E8;&#x7F72;tpatch&#x5B9E;&#x9645;&#x4E0A;&#x662F;&#x5148;&#x6709;&#x6574;&#x5305;&#x6784;&#x5EFA;&#xFF0C;&#x518D;DIFF&#x51FA;&#x5DEE;&#x5F02;&#x7684;&#x65B9;&#x5F0F;&#xFF0C;&#x8FD9;&#x6837;&#x7684;&#x65B9;&#x5F0F;&#x89C4;&#x907F;&#x4E86;&#x6DF7;&#x6DC6;&#x3001;&#x5185;&#x8054;&#x7B49;&#x5E26;&#x6765;&#x7684;&#x590D;&#x6742;&#x6027;&#x7684;&#x95EE;&#x9898;&#x5904;&#x7406;&#xFF0C;&#x4FDD;&#x8BC1;patch&#x5BF9;&#x4E4B;&#x524D;&#x7248;&#x672C;&#x7684;&#x5B8C;&#x5168;&#x9002;&#x7528;&#xFF0C;&#x4F46;&#x662F;&#x8FD9;&#x79CD;&#x65B9;&#x5F0F;&#x540C;&#x65F6;&#x4E5F;&#x5FC5;&#x4E0D;&#x53EF;&#x5C11;&#x7684;&#x5F71;&#x54CD;patch&#x7684;&#x6784;&#x5EFA;&#x901F;&#x5EA6;&#xFF0C;&#x5728;&#x5BF9;&#x7D27;&#x6025;&#x7684;&#x95EE;&#x9898;&#x8FDB;&#x884C;&#x4FEE;&#x590D;&#x7684;&#x5173;&#x952E;&#x65F6;&#x671F;&#xFF0C;&#x8FD9;&#x4E2A;&#x65F6;&#x95F4;&#x53EF;&#x80FD;&#x4F1A;&#x662F;&#x4E0D;&#x53EF;&#x63A5;&#x53D7;&#x7684;&#x3002;</p>\n</li>\n<li><p><strong>&#x751F;&#x6548;&#x901F;&#x5EA6;&#xFF1A;</strong></p>\n<ol>\n<li>&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x5185;&#x6709;&#x4EE3;&#x7801;&#x7684;&#x53D8;&#x66F4;&#xFF0C;so&#xFF0C;&#x8D44;&#x6E90;&#x7B49;&#x3002;&#x7075;&#x6D3B;&#x6027;&#x5BFC;&#x81F4;&#x4E00;&#x4E2A;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7B49;&#x4F53;&#x79EF;&#x5F80;&#x5F80;&#x6BD4;&#x8F83;&#x5927;&#xFF0C;&#x800C;&#x5728;&#x8FD0;&#x8425;&#x5546;&#x7F51;&#x7EDC;&#x4E0B;&#xFF0C;&#x5BF9;&#x7528;&#x6237;&#x5927;&#x7684;&#x6D41;&#x91CF;&#x6D88;&#x8017;&#x4E0D;&#x662F;&#x6211;&#x4EEC;&#x5E0C;&#x671B;&#x770B;&#x5230;&#x7684;&#xFF0C;&#x6240;&#x4EE5;&#x5F80;&#x5F80;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#x53EA;&#x5728;WIFI&#x4E0B;&#x7684;&#x751F;&#x6548;&#x7B56;&#x7565;&#x5F88;&#x80FD;&#x5F71;&#x54CD;&#x751F;&#x6548;&#x7387;&#x3002;</li>\n<li>&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x5141;&#x8BB8;&#x5BBF;&#x4E3B;&#xFF0C;bundle&#x5185;&#x90E8;&#x53D1;&#x751F;&#x66F4;&#x65B0;&#xFF0C;&#x4E5F;&#x5141;&#x8BB8;bundle&#x4E4B;&#x95F4;&#x7684;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#x7B49;&#x53D1;&#x751F;&#x53D8;&#x66F4;&#xFF0C;&#x8FD9;&#x5C31;&#x5BFC;&#x81F4;&#x4E86;&#x4E00;&#x6B21;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x6210;&#x529F;&#x5FC5;&#x987B;&#x4F9D;&#x8D56;&#x4E8E;tpatch&#x5185;&#x7684;&#x6240;&#x6709;bundle&#x548C;&#x5BBF;&#x4E3B;&#x5168;&#x90E8;&#x66F4;&#x65B0;&#x6210;&#x529F;&#xFF0C;&#x5426;&#x5219;&#x5C31;&#x53EF;&#x80FD;&#x4F1A;&#x5BFC;&#x81F4;&#x4F9D;&#x8D56;&#x4E0D;&#x4E00;&#x81F4;&#x800C;&#x5F15;&#x53D1;crash&#x3002;&#x4ECE;&#x4EE5;&#x5F80;&#x7684;&#x52A8;&#x6001;&#x90E8;&#x7F72;tpatch&#x53EF;&#x77E5;&#xFF0C;&#x6BCF;&#x6B21;&#x7684;&#x53D8;&#x66F4;&#x901A;&#x5E38;&#x90FD;&#x6709;&#x5341;&#x51E0;&#x4E2A;&#x751A;&#x81F3;&#x51E0;&#x5341;&#x4E2A;bundle&#x53D1;&#x751F;&#x53D8;&#x66F4;&#xFF0C;&#x800C;&#x5728;&#x4F4E;&#x7A7A;&#x95F4;&#x6216;&#x8005;&#x67D0;&#x4E9B;&#x8BFB;&#x5199;&#x80FD;&#x529B;&#x8F83;&#x5DEE;&#x7684;&#x8BBE;&#x5907;&#x4E0A;&#xFF0C;IO&#x5931;&#x8D25;&#x5F88;&#x5BB9;&#x6613;&#x5F71;&#x54CD;&#x6574;&#x4E2A;patch&#x7684;&#x6210;&#x529F;&#x7387;&#x3002;</li>\n</ol>\n</li>\n<li><p><strong>&#x7248;&#x672C;&#x53F7;&#xFF1A;</strong>\n&#x56E0;&#x4E3A;&#x662F;APk&#x5347;&#x7EA7;&#x7684;&#x66FF;&#x4EE3;&#x65B9;&#x6848;&#xFF0C;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x66FF;&#x6362;&#x7248;&#x672C;&#x53F7;&#x7684;&#x65B9;&#x5F0F;&#x5C31;&#x4F7F;&#x5F97;&#x662F;&#x5426;&#x4F7F;&#x7528;&#x7684;&#x662F;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x8FD8;&#x662F;apk&#x5347;&#x7EA7;&#x5BF9;&#x4E1A;&#x52A1;&#x6765;&#x8BF4;&#x5B8C;&#x5168;&#x900F;&#x660E;&#xFF0C;&#x53EF;&#x4EE5;&#x7EE7;&#x7EED;&#x6309;&#x7248;&#x672C;&#x53F7;&#x8FDB;&#x884C;&#x903B;&#x8F91;&#x5904;&#x7406;&#xFF0C;&#x964D;&#x7EA7;&#x7B49;&#x3002;&#x6570;&#x636E;&#x7EDF;&#x8BA1;&#x4EE5;&#x53CA;&#x76D1;&#x63A7;&#x7B49;&#x53EF;&#x4EE5;&#x5B8C;&#x5168;&#x517C;&#x5BB9;&#x3002;&#x4F46;&#x662F;&#x5982;&#x679C;&#x5728;&#x6545;&#x969C;&#x4FEE;&#x590D;&#x4E2D;&#x53BB;&#x8D38;&#x7136;&#x5347;&#x7EA7;&#x7248;&#x672C;&#x53F7;&#xFF0C;&#x867D;&#x7136;&#x76F4;&#x89C2;&#x4E0A;&#x53EF;&#x4EE5;&#x6E05;&#x695A;&#x770B;&#x5230;&#x95EE;&#x9898;&#x4FEE;&#x590D;&#x7684;&#x8986;&#x76D6;&#x7387;&#xFF0C;&#x4F46;&#x662F;&#x4E4B;&#x524D;&#x4F18;&#x52BF;&#x5C31;&#x8361;&#x7136;&#x65E0;&#x5B58;&#x4E86;&#x3002;</p>\n</li>\n</ol>\n<p>&#x56DE;&#x987E;&#x624B;&#x6DD8;&#x4E4B;&#x524D;&#x7684;&#x4E00;&#x4E9B;&#x6545;&#x969C;&#x95EE;&#x9898;&#x7684;&#x4FEE;&#x590D;&#xFF0C;&#x4E0D;&#x7BA1;&#x662F;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x8FD8;&#x662F;andfix&#xFF0C;&#x5176;&#x5B9E;&#x6211;&#x4EEC;&#x53D1;&#x73B0;&#x51E0;&#x4E4E;&#x6240;&#x6709;&#x7684;&#x6545;&#x969C;&#x90FD;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;java&#x4EE3;&#x7801;&#x5C31;&#x884C;&#x4FEE;&#x590D;&#x6216;&#x8005;&#x964D;&#x7EA7;&#xFF0C;&#x4E5F;&#x57FA;&#x672C;&#x90FD;&#x53EF;&#x4EE5;&#x5728;&#x4E00;&#x4E2A;&#x6A21;&#x5757;&#x5185;&#x7684;&#x4FEE;&#x6539;&#x5C31;&#x628A;&#x67D0;&#x4E2A;&#x5BF9;&#x5E94;&#x7684;&#x6545;&#x969C;&#x4FEE;&#x590D;&#x6389;&#x3002;&#x56E0;&#x6B64;&#xFF0C;&#x4EE5;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x6280;&#x672F;&#x4F5C;&#x4E3A;&#x57FA;&#x7840;&#xFF0C;&#x79F0;&#x4E4B;&#x4E3A;<strong>Dexpatch</strong>&#x7684;&#x65B9;&#x6848;&#x5E94;&#x8FD0;&#x800C;&#x751F;&#x3002;</p>\n<h2 id=\"dexpatch&#x7684;&#x7279;&#x70B9;&#x548C;&#x4F18;&#x52BF;\">Dexpatch&#x7684;&#x7279;&#x70B9;&#x548C;&#x4F18;&#x52BF;</h2>\n<p><strong>&#x9650;&#x5236;&#xFF1A;</strong> </p>\n<p>&#x6BCF;&#x4E2A;dexpatch&#x53EA;&#x80FD;&#x4FEE;&#x6539;&#x4E00;&#x4E2A;bundle(&#x4E3B;dex&#x6574;&#x4E2A;&#x7B97;&#x4E00;&#x4E2A;bundle)&#xFF0C;&#x4E14;&#x4FEE;&#x6539;&#x7684;&#x4EE3;&#x7801;&#x5FC5;&#x987B;&#x5411;&#x524D;&#x517C;&#x5BB9;&#x3002;&#xFF08;&#x4E0D;&#x5982;&#x8BF4;&#x4E3B;dex&#x88AB;bundle&#x4F9D;&#x8D56;&#xFF0C;&#x5219;&#x4E3B;dex&#x7684;dexpatch&#x4FEE;&#x6539;&#x4E0D;&#x80FD;&#x5F15;&#x8D77;&#x539F;&#x6765;bundle&#x7684;&#x65B9;&#x6CD5;&#x8C03;&#x7528;&#x51FA;&#x73B0;&#x95EE;&#x9898;&#xFF09;</p>\n<p><strong>&#x5982;&#x4F55;&#x53D1;&#x5E03;Dexpatch:</strong></p>\n<p>&#x6BCF;&#x4E2A;&#x4E1A;&#x52A1;&#x6309;&#x7167;&#x5404;&#x81EA;&#x7684;&#x6545;&#x969C;&#x60C5;&#x51B5;&#x8FDB;&#x884C;dexpatch&#x7684;&#x6784;&#x5EFA;&#xFF0C;&#x4EA7;&#x51FA;&#x5BF9;&#x5E94;&#x7684;patch&#x4EA7;&#x7269;&#x548C;json&#x4FE1;&#x606F;&#xFF0C;&#x53D1;&#x5E03;&#x65F6;&#x5E73;&#x53F0;&#x5E94;&#x8BE5;&#x6C47;&#x603B;&#x5BF9;&#x5E94;&#x7248;&#x672C;&#x5F53;&#x524D;release&#x7684;&#x6240;&#x6709;patch&#x5185;&#x5BB9;&#xFF0C;&#x6574;&#x5408;json&#x4FE1;&#x606F;&#xFF0C;&#x8FDB;&#x884C;&#x4E0B;&#x53D1;</p>\n<p>dexpatch&#x4E0D;&#x5B58;&#x5728;&#x56DE;&#x6EDA;&#xFF0C;&#x6BCF;&#x4E2A;dexpatch&#x53D1;&#x5E03;&#x540E;&#xFF0C;&#x76F4;&#x63A5;&#x8986;&#x76D6;&#x4E4B;&#x524D;&#x7684;dexpatch&#x7684;&#x3002;&#x6BCF;&#x4E2A;dexpatch&#x6709;&#x4E0B;&#x7EBF;&#x7684;&#x80FD;&#x529B;</p>\n<p><strong>&#x4F18;&#x52BF;</strong></p>\n<ol>\n<li>&#x6BCF;&#x4E2A;bundle&#x57FA;&#x4E8E;&#x81EA;&#x8EAB;&#x7684;&#x95EE;&#x9898;&#x8FDB;&#x884C;dexpatch&#x7684;&#x53D1;&#x5E03;&#xFF0C;&#x6784;&#x5EFA;&#x901F;&#x5EA6;&#x76F8;&#x6BD4;&#x539F;&#x6765;&#x7684;&#x65B9;&#x5F0F;&#x6709;&#x4E86;&#x5927;&#x5E45;&#x5EA6;&#x63D0;&#x9AD8;&#xFF0C;&#x53EA;&#x9700;&#x8981;&#x9488;&#x5BF9;&#x5355;&#x4E2A;bundle&#x8FDB;&#x884C;&#x6784;&#x5EFA;&#x4ECE;&#x800C;diff&#x51FA;&#x5DEE;&#x5F02;&#x5373;&#x53EF;&#x3002;</li>\n<li><p>&#x4E0B;&#x53D1;&#x7684;dexpatch&#x603B;&#x5305;&#x5185;&#x7684;patch&#x5404;&#x81EA;&#x751F;&#x6548;&#xFF0C;&#x4E0D;&#x9700;&#x8981;&#x6240;&#x6709;bundle&#x7684;patch&#x5168;&#x90E8;&#x5B89;&#x88C5;&#x6210;&#x529F;&#xFF0C;&#x8FD9;&#x662F;&#x7531;&#x4E8E;&#x4E4B;&#x524D;patch&#x7684;&#x4FEE;&#x6539;&#x662F;&#x5411;&#x524D;&#x517C;&#x5BB9;&#x505A;&#x4E86;&#x4FDD;&#x8BC1;&#x3002;</p>\n</li>\n<li><p>dexpatch&#x7531;&#x4E8E;&#x5176;&#x4FEE;&#x6539;&#x7684;&#x539F;&#x5B50;&#x6027;&#xFF08;&#x5411;&#x524D;&#x517C;&#x5BB9;&#x6027;&#x7684;&#x4FDD;&#x8BC1;&#x4EE5;&#x53CA;&#x4E0D;&#x5B58;&#x5728;&#x5173;&#x8054;&#x4FEE;&#x6539;&#xFF09;&#xFF0C;&#x540C;&#x65F6;&#x5BB9;&#x5668;&#x6309;&#x9700;&#x52A0;&#x8F7D;&#x7684;&#x7279;&#x6027;&#xFF0C;&#x4F7F;&#x5F97;&#x672A;&#x88AB;&#x8F7D;&#x5165;&#x7684;bundle&#x53EF;&#x4EE5;&#x4E0D;&#x9700;&#x8981;&#x8FDB;&#x7A0B;&#x91CD;&#x542F;&#x5373;&#x53EF;&#x751F;&#x6548;&#xFF0C;&#x540C;&#x65F6;&#xFF0C;&#x5DF2;&#x7ECF;&#x8F7D;&#x5165;&#x7684;bundle&#x540E;&#x671F;&#x4E5F;&#x4F1A;&#x8FDB;&#x884C;&#x751F;&#x547D;&#x5468;&#x671F;&#x7684;&#x76D1;&#x63A7;&#xFF0C;&#x4E00;&#x65E6;&#x6240;&#x6709;component&#x9000;&#x51FA;&#xFF0C;&#x5219;&#x4E5F;&#x53EF;&#x4EE5;&#x8FDB;&#x884C;&#x70ED;&#x66FF;&#x6362;&#xFF0C;&#x4F7F;&#x5F97;dexpatch&#x76F8;&#x6BD4;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x751F;&#x6548;&#x901F;&#x5EA6;&#x53EF;&#x4EE5;&#x8FDB;&#x4E00;&#x6B65;&#x63D0;&#x9AD8;</p>\n</li>\n</ol>\n<p>&#x540C;&#x65F6;dexpatch&#x4E0D;&#x4FEE;&#x6539;&#x6574;&#x4E2A;apk&#x7248;&#x672C;&#x53F7;&#xFF0C;&#x6BCF;&#x4E2A;bundle&#x63D0;&#x4F9B;&#x989D;&#x5916;&#x7684;dexpatch&#x7248;&#x672C;&#x53F7;&#x8FDB;&#x884C;&#x76D1;&#x63A7;&#x3002;</p>\n<p>&#x53E6;&#x5916; dexpatch&#x4F5C;&#x4E3A;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x8865;&#x5145;&#xFF0C;&#x4E24;&#x8005;&#x76F8;&#x8F85;&#x76F8;&#x6210;&#x3002;&#x53EF;&#x4EE5;&#x9488;&#x5BF9;&#x4EFB;&#x4F55;&#x4E00;&#x4E2A;&#x5927;&#x7248;&#x672C;&#x6216;&#x8005;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7248;&#x672C;&#x53D1;&#x5E03;dexpatch&#xFF0C;&#x65E0;&#x8BBA;&#x4E00;&#x4E2A;&#x7248;&#x672C;&#x53F7;&#x5BF9;&#x5E94;&#x7684;bundle&#x662F;&#x5426;&#x6709;&#x88AB;dexpatch&#xFF0C;&#x5F53;&#x4E00;&#x4E2A;&#x65B0;&#x7684;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x53D1;&#x751F;&#x65F6;&#xFF0C;&#x5B83;&#x4EEC;&#x53C8;&#x90FD;&#x4F1A;&#x88AB;&#x6536;&#x655B;&#x5230;&#x4E00;&#x4E2A;&#x65B0;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7248;&#x672C;&#x4E0A;&#x9762;&#x3002;\n&#x90A3;&#x4E48;&#x73B0;&#x5728;&#x7406;&#x60F3;&#x4E2D;&#x7684;&#x7248;&#x672C;&#x8FED;&#x4EE3;&#x7684;&#x60C5;&#x51B5;&#x5E94;&#x8BE5;&#x662F;&#x5982;&#x4E0B;&#x8FD9;&#x79CD;&#xFF1A;\n&gt;\n<img src=\"img/dexpatch.png\" alt=\"MacDown Screenshot\"></p>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"principle.html\" class=\"navigation navigation-prev \" aria-label=\"Previous page: 技术原理\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"dexpatch_use_guide.html\" class=\"navigation navigation-next \" aria-label=\"Next page: dexpatch使用教程\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"dexpatch\",\"level\":\"1.4.2\",\"depth\":2,\"next\":{\"title\":\"dexpatch使用教程\",\"level\":\"1.4.3\",\"depth\":2,\"path\":\"update/dexpatch_use_guide.md\",\"ref\":\"update/dexpatch_use_guide.md\",\"articles\":[]},\"previous\":{\"title\":\"技术原理\",\"level\":\"1.4.1\",\"depth\":2,\"path\":\"update/principle.md\",\"ref\":\"update/principle.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"update/dexpatch.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/update/dexpatch_use_guide.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>dexpatch使用教程 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"guide.html\" />\n    \n    \n    <link rel=\"prev\" href=\"dexpatch.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../guide-for-use/\">\n            \n                <a href=\"../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"./\">\n            \n                <a href=\"./\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"principle.html\">\n            \n                <a href=\"principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"dexpatch.html\">\n            \n                <a href=\"dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.4.3\" data-path=\"dexpatch_use_guide.html\">\n            \n                <a href=\"dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"guide.html\">\n            \n                <a href=\"guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../faq/question.html\">\n            \n                <a href=\"../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../faq/help.html\">\n            \n                <a href=\"../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../faq/variant.html\">\n            \n                <a href=\"../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >dexpatch使用教程</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"dexpatch&#x4F7F;&#x7528;&#x793A;&#x4F8B;\">DexPatch&#x4F7F;&#x7528;&#x793A;&#x4F8B;</h1>\n<p>DexPatch&#x662F;&#x4EE5;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x6280;&#x672F;&#x65B9;&#x6848;&#x4E3A;&#x57FA;&#x7840;&#xFF0C;&#x4EE5;&#x5FEB;&#x901F;&#x89E3;&#x51B3;&#x7EBF;&#x4E0A;&#x6545;&#x969C;&#x4E3A;&#x552F;&#x4E00;&#x76EE;&#x7684;&#x7684;&#x52A8;&#x6001;&#x5316;&#x65B9;&#x6848;&#x3002;</p>\n<p>&#x7B80;&#x5355;&#x6765;&#x8BF4;&#xFF0C;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x662F;&#x9488;&#x5BF9;apk&#x7EA7;&#x522B;&#x7684;&#x52A8;&#x6001;&#x5347;&#x7EA7;&#xFF0C;DexPatch&#x662F;&#x9488;&#x5BF9;Bundle&#x7EA7;&#x522B;&#x7684;&#x52A8;&#x6001;&#x4FEE;&#x590D;(&#x4E3B;dex&#x53EF;&#x4EE5;&#x8BA4;&#x4E3A;&#x662F;&#x4E00;&#x4E2A;Bundle)</p>\n<p>&#x8BE6;&#x7EC6;&#x4ECB;&#x7ECD;&#x53C2;&#x7167; <a href=\"https://alibaba.github.io/atlas/update/dexpatch.html\" target=\"_blank\">DexPatch&#x4ECB;&#x7ECD; </a></p>\n<h1 id=\"dexpatch&#x4E0E;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x5F02;&#x540C;\">DexPatch&#x4E0E;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x5F02;&#x540C;</h1>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">&#x4E0D;&#x540C;&#x70B9;</th>\n<th style=\"text-align:left\">DexPatch</th>\n<th style=\"text-align:left\">&#x52A8;&#x6001;&#x90E8;&#x7F72;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">&#x573A;&#x666F;&#x5B9A;&#x4F4D;</td>\n<td style=\"text-align:left\">bundle&#x7EA7;&#x522B;&#xFF0C;&#x4EE3;&#x7801;&#x52A8;&#x6001;&#x4FEE;&#x590D;</td>\n<td style=\"text-align:left\">apk&#x52A8;&#x6001;&#x5347;&#x7EA7;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">&#x7075;&#x6D3B;&#x5EA6;</td>\n<td style=\"text-align:left\">&#x5404;&#x4E2A;bundle&#x968F;&#x65F6;&#x4E0B;&#x53D1;</td>\n<td style=\"text-align:left\">&#x96C6;&#x6210;&#x5347;&#x7EA7;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">&#x6784;&#x5EFA;&#x901F;&#x5EA6;</td>\n<td style=\"text-align:left\">&#x5F88;&#x5FEB;</td>\n<td style=\"text-align:left\">&#x4E00;&#x822C;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">&#x751F;&#x6548;&#x901F;&#x5EA6;</td>\n<td style=\"text-align:left\">&#x5FEB;</td>\n<td style=\"text-align:left\">&#x4E00;&#x822C;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">&#x4FEE;&#x6539;&#x8303;&#x56F4;</td>\n<td style=\"text-align:left\">bundle&#x81EA;&#x8EAB;&#x5185;&#x805A;</td>\n<td style=\"text-align:left\">apk&#x8303;&#x56F4;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">versionName</td>\n<td style=\"text-align:left\">&#x4E0D;&#x6539;</td>\n<td style=\"text-align:left\">+1</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">java</td>\n<td style=\"text-align:left\">&#x652F;&#x6301;</td>\n<td style=\"text-align:left\">&#x652F;&#x6301;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">so</td>\n<td style=\"text-align:left\">x</td>\n<td style=\"text-align:left\">&#x652F;&#x6301;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">resource</td>\n<td style=\"text-align:left\">x</td>\n<td style=\"text-align:left\">&#x652F;&#x6301;</td>\n</tr>\n</tbody>\n</table>\n<h1 id=\"&#x7248;&#x672C;\">&#x7248;&#x672C;</h1>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">&#x4F9D;&#x8D56;</th>\n<th style=\"text-align:left\">&#x7248;&#x672C;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">atlasplugin</td>\n<td style=\"text-align:left\">2.3.3.rc12-1</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">atlas_core</td>\n<td style=\"text-align:left\">5.0.7.41</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">atlasupdate</td>\n<td style=\"text-align:left\">1.1.4.11</td>\n</tr>\n</tbody>\n</table>\n<h1 id=\"&#x6253;&#x5305;\">&#x6253;&#x5305;</h1>\n<p>Dexpatch&#x9700;&#x8981;&#x4E00;&#x4E2A;ap&#x7248;&#x672C;&#x4F5C;&#x4E3A;&#x53C2;&#x7167;&#xFF0C;&#x548C;&#x73B0;&#x5728;&#x7684;&#x4EE3;&#x7801;&#x6BD4;&#x5BF9;&#x505A;diff&#x3002;&#x5047;&#x8BBE;&#x5F53;&#x524D;&#x7248;&#x672C;&#x4E3A;1.0.0 (gradle&#x4E2D;&#x914D;&#x7F6E;)</p>\n<h2 id=\"&#x53D1;&#x5E03;&#x7248;&#x672C;\">&#x53D1;&#x5E03;&#x7248;&#x672C;</h2>\n<p>&#x5982;&#x679C;&#x4E4B;&#x524D;&#x53D1;&#x5E03;&#x8FC7;ap&#x7248;&#x672C;&#xFF0C;&#x53EF;&#x4EE5;&#x8DF3;&#x8FC7;&#x6B64;&#x8282;&#x3002;&#x5047;&#x8BBE;&#x4ECE;&#x672A;&#x53D1;&#x5E03;&#x8FC7;ap&#xFF0C;&#x6309;&#x7167;&#x5982;&#x4E0B;&#x6B65;&#x9AA4;&#xFF0C;&#x53D1;&#x5E03;1.0.0&#x7684;ap</p>\n<ol>\n<li>&#x8FDB;&#x5165;app&#x76EE;&#x5F55;&#x4E0B;</li>\n<li>&#x751F;&#x6210;&#x57FA;&#x7EBF;&#x7248;&#x672C; <code>./gradlew clean assembleDebug</code></li>\n<li>&#x53D1;&#x5E03;ap&#x5230;&#x4ED3;&#x5E93;&#x4E2D; `./gradlew publish</li>\n</ol>\n<h2 id=\"&#x6253;patch\">&#x6253;patch</h2>\n<ol>\n<li><p>&#x57FA;&#x4E8E;ap&#x6240;&#x5C5E;&#x7684;&#x7248;&#x672C;(1.0.0)&#xFF0C;&#x4FEE;&#x6539;&#x4EE3;&#x7801;,&#x4EE5;firstbundle&#x4E3A;&#x4F8B;&#xFF0C;&#x5C06;&quot;origin&quot;&#x4FEE;&#x6539;&#x4E3A;&quot;dexpatch&quot;</p>\n<p> <img src=\"img/dex_patch_edit.png\" alt=\"\"> </p>\n</li>\n<li><p>&#x4FEE;&#x6539;&#x4F9D;&#x8D56;&#x7248;&#x672C;&#xFF0C;&#x5C06;firbundle&#x4E2D;grddle&#x7684;verion&#x6539;&#x4E3A;<code>version = &apos;1.0.1&apos;</code></p>\n<blockquote>\n<p>&#x8FD9;&#x91CC;&#x4E5F;&#x53EF;&#x4EE5;&#x4FEE;&#x6539;firbundle&#x4F9D;&#x8D56;&#x7684;&#x67D0;&#x4E2A;aar&#x7684;&#x7248;&#x672C;&#x3002;&#x4E00;&#x53E5;&#x8BDD;&#xFF0C;&#x4F60;&#x8981;&#x901A;&#x8FC7;&#x7248;&#x672C;&#x53F7;&#x544A;&#x8BC9;&#x7F16;&#x8BD1;&#x5668;&#xFF0C;&#x6211;&#x8FD9;&#x4E2A;bundle&#x7684;&#x4EE3;&#x7801;&#x53D8;&#x4E86;</p>\n</blockquote>\n</li>\n<li>&#x6307;&#x5B9A;&#x53C2;&#x7167;&#x7684;&#x7248;&#x672C;&#xFF0C;&#x751F;&#x6210;dexPatch&#x5305;<br> <code>./gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.0</code></li>\n</ol>\n<p>PS: </p>\n<blockquote>\n<p>&#x8FD9;&#x91CC;&#x8981;&#x5F3A;&#x8C03;&#x4E00;&#x4E0B;&#xFF0C;&#x4EE3;&#x7801;&#x7684;&#x4FEE;&#x6539;&#x8981;&#x5185;&#x805A;&#x3002;<br>&#x5047;&#x8BBE;A&#x4F9D;&#x8D56;B,&#x4FEE;&#x6539;&#x65F6;&#xFF0C;&#x53EA;&#x6539;A&#x6216;B&#x81EA;&#x8EAB;&#x7684;&#x4EE3;&#x7801;&#xFF0C;&#x4E0D;&#x652F;&#x6301;&#x4FEE;&#x6539;A&#x4E0E;B&#x4E4B;&#x95F4;&#x7684;&#x63A5;&#x53E3;&#x3002;</p>\n</blockquote>\n<h1 id=\"&#x90E8;&#x7F72;patch\">&#x90E8;&#x7F72;Patch</h1>\n<p>&#x751F;&#x6210;&#x7684;patch&#x6587;&#x4EF6;&#x5728; <code>app/build/outputs</code>&#x4E0B;&#xFF0C;&#x68C0;&#x67E5;&#x662F;&#x5426;&#x5B58;&#x5728;&#x4E24;&#x4E2A;&#x6587;&#x4EF6;</p>\n<ul>\n<li>1.0.0@1.0.0.tpatch</li>\n<li>dexpatch-1.0.0.json</li>\n</ul>\n<p>&#x6E05;&#x7A7A; <code>/sdcard/Android/data/com.taobao.demo/cache/</code>&#xFF0C;&#x5E76;&#x5C06;&#x4E0A;&#x8FF0;&#x4E24;&#x4E2A;&#x6587;&#x4EF6;push&#x5230;&#x4E0A;&#x8FF0;&#x8DEF;&#x5F84;&#x4E2D;</p>\n<h1 id=\"demo&#x4E2D;&#x6D4B;&#x8BD5;&#x5165;&#x53E3;\">demo&#x4E2D;&#x6D4B;&#x8BD5;&#x5165;&#x53E3;</h1>\n<p>&#x4E3B;&#x754C;&#x9762;&#x70B9;&#x5F00;&#x4FA7;&#x8FB9;&#x680F;&#xFF0C;&#x70B9;&#x51FB;dexpatch</p>\n<p><img src=\"img/dexpatch_ui_click.png\" alt=\"\"></p>\n<p>&#x91CD;&#x542F;&#x5E94;&#x7528;,Toash&#x663E;&#x793A; &quot;dexpatch&quot;,&#x6210;&#x529F;~</p>\n<p><img src=\"img/dexpatch_result.png\" alt=\"\"></p>\n<h1 id=\"&#x4EA7;&#x7269;&#x8BF4;&#x660E;\">&#x4EA7;&#x7269;&#x8BF4;&#x660E;</h1>\n<p><img src=\"img/dexpatch_build_output.png\" alt=\"\"></p>\n<h2 id=\"versionversiontpatch\">version@version.tpatch</h2>\n<p>&#x5F53;&#x524D;&#x4EE3;&#x7801;&#x548C;&#x53C2;&#x8003;ap(1.0.0)diff&#x7684;&#x4EA7;&#x7269;&#xFF0C;&#x662F;&#x4E2A;zip&#x6587;&#x4EF6;&#xFF0C;&#x89E3;&#x538B;&#x5F00;&#x5C31;&#x662F;diff&#x7684;&#x4EE3;&#x7801;&#x3002;</p>\n<h2 id=\"patchsjson\">patchs.json</h2>\n<p>&#x4E0A;&#x8FF0;&#x4EE3;&#x7801;diff&#x7684;&#x914D;&#x5957;json&#xFF0C;&#x63CF;&#x8FF0;&#x4E86;&#x672C;&#x6B21;diff&#x7684;&#x7ED3;&#x679C;:</p>\n<ul>\n<li>&#x6539;&#x52A8;&#x6A21;&#x5757;&#x4FE1;&#x606F;</li>\n<li>&#x6BD4;&#x5BF9;&#x7248;&#x672C;</li>\n<li>...</li>\n</ul>\n<h2 id=\"dexpatch-xxxjson\">dexpatch-xxx.json</h2>\n<h2 id=\"&#x8BF4;&#x660E;\">&#x8BF4;&#x660E;</h2>\n<p><strong>&#x5BA2;&#x6237;&#x7AEF;&#x53EF;&#x4EE5;&#x8BC6;&#x522B;&#x7684;&#x63A5;&#x53E3;&#xFF0C;&#x5BF9;&#x6253;&#x5305;&#x4EA7;&#x7269;&#x5305;&#x88C5;&#x5904;&#x7406;&#x8FC7;&#x7684;&#x914D;&#x7F6E;</strong></p>\n<p>&#x5BA2;&#x6237;&#x7AEF;&#x5E76;&#x4E0D;&#x80FD;&#x76F4;&#x63A5;&#x8BC6;&#x522B;&#x6253;&#x5305;&#x4EA7;&#x751F;&#x7684; <code>path.json</code> &#x6587;&#x4EF6;&#xFF0C;&#x9700;&#x8981;&#x670D;&#x52A1;&#x7AEF;&#x505A;&#x4E00;&#x4E9B;&#x5305;&#x88C5;&#x3002;</p>\n<h2 id=\"demo&#x8BF4;&#x660E;\">Demo&#x8BF4;&#x660E;</h2>\n<p>&#x7531;&#x4E8E;demo&#x6CA1;&#x6709;&#x670D;&#x52A1;&#x7AEF;&#xFF0C;&#x6240;&#x4EE5;&#x5728;<code>app/dexPatchWraper.gradle</code>&#x4E2D;&#xFF0C;&#x5BF9;patch.json&#x5185;&#x5BB9;&#x505A;&#x4E86;&#x4E00;&#x4E2A;&#x5305;&#x88C5;&#xFF0C;&#x7B80;&#x5355;&#x6A21;&#x62DF;&#x670D;&#x52A1;&#x7AEF;&#x7684;&#x903B;&#x8F91;&#x3002;</p>\n<blockquote>\n<p>&#x7B80;&#x5355;&#x8D77;&#x89C1;&#xFF0C;&#x53EA;&#x662F;&#x6BCF;&#x6B21;&#x90FD;&#x628A;dexPatchVersion+1&#xFF0C;&#x7248;&#x672C;&#x53F7;&#x7F13;&#x5B58;&#x5728;&#x6839;&#x76EE;&#x5F55;&#x4E0B;&#x7684;<code>dexPatch.verion</code>&#x6587;&#x4EF6;&#x4E2D;&#x3002;</p>\n</blockquote>\n<h2 id=\"&#x5B57;&#x6BB5;&#x89E3;&#x91CA;\">&#x5B57;&#x6BB5;&#x89E3;&#x91CA;</h2>\n<p>&#x5305;&#x88C5;&#x540E;&#x7684;&#x4EA7;&#x7269;&#x5B57;&#x7AEF;&#x5982;&#x4E0B;,&#x5927;&#x90E8;&#x5206;&#x5185;&#x5BB9;&#x76F4;&#x63A5;copy&#x81EA;<code>patch.json</code>,&#x9700;&#x8981;&#x5173;&#x5FC3;&#x7684;&#x53EA;&#x6709;&#x51E0;&#x4E2A;&#x5B57;&#x7AEF;</p>\n<pre><code class=\"lang-json\">{\n  <span class=\"hljs-string\">&quot;baseVersion&quot;</span>: <span class=\"hljs-string\">&quot;1.0.0&quot;</span>,\n  <span class=\"hljs-string\">&quot;diffBundleDex&quot;</span>: <span class=\"hljs-literal\">true</span>,\n  <span class=\"hljs-string\">&quot;patches&quot;</span>: [\n    {\n      <span class=\"hljs-string\">&quot;bundles&quot;</span>: [\n        {\n          <span class=\"hljs-string\">&quot;dependency&quot;</span>: [\n            <span class=\"hljs-string\">&quot;com.taobao.publicBundle&quot;</span>\n          ],\n          <span class=\"hljs-comment\">//&#x91CD;&#x8981;</span>\n          <span class=\"hljs-string\">&quot;dexpatchVersion&quot;</span>: <span class=\"hljs-string\">&quot;14&quot;</span>,\n          <span class=\"hljs-string\">&quot;isMainDex&quot;</span>: <span class=\"hljs-literal\">false</span>,\n          <span class=\"hljs-string\">&quot;name&quot;</span>: <span class=\"hljs-string\">&quot;com.taobao.firstbundle&quot;</span>,\n          <span class=\"hljs-string\">&quot;pkgName&quot;</span>: <span class=\"hljs-string\">&quot;com.taobao.firstbundle&quot;</span>,\n          <span class=\"hljs-string\">&quot;dependency&quot;</span>:[],\n          <span class=\"hljs-comment\">//&#x91CD;&#x8981;</span>\n          <span class=\"hljs-string\">&quot;reset&quot;</span>: <span class=\"hljs-literal\">false</span>,\n          <span class=\"hljs-string\">&quot;srcUnitTag&quot;</span>: <span class=\"hljs-string\">&quot;6b3973d9d6592d15601017edabc8b31b&quot;</span>,\n          <span class=\"hljs-string\">&quot;unitTag&quot;</span>: <span class=\"hljs-string\">&quot;e857557cc924f503a7304218469733a2&quot;</span>,\n          <span class=\"hljs-string\">&quot;version&quot;</span>: <span class=\"hljs-string\">&quot;1.0.1&quot;</span>\n        }\n      ],\n      <span class=\"hljs-comment\">//&#x91CD;&#x8981;</span>\n      <span class=\"hljs-string\">&quot;dexPatch&quot;</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-string\">&quot;fileName&quot;</span>: <span class=\"hljs-string\">&quot;1.0.0@1.0.0.tpatch&quot;</span>,\n      <span class=\"hljs-string\">&quot;patchVersion&quot;</span>: <span class=\"hljs-string\">&quot;1.0.0&quot;</span>,\n      <span class=\"hljs-string\">&quot;targetVersion&quot;</span>: <span class=\"hljs-string\">&quot;1.0.0&quot;</span>\n    }\n  ]\n}\n</code></pre>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">&#x5B57;&#x6BB5;</th>\n<th style=\"text-align:left\">&#x8BF4;&#x660E;</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">dexpatchVersion</td>\n<td style=\"text-align:left\">&#x6BCF;&#x4E2A;&#x6A21;&#x5757;&#x6709;&#x4E00;&#x4E2A;dexPatchVersion&#x7684;&#x6982;&#x5FF5;<br>&#x5BA2;&#x6237;&#x7AEF;&#x4F1A;&#x5224;&#x65AD;bundle&#x7684;dexPatchVersion,&#x5224;&#x65AD;&#x8BE5;bundle&#x662F;&#x5426;&#x9700;&#x8981;&#x505A;merge<br>&#x901A;&#x5E38;&#x7531;&#x670D;&#x52A1;&#x7AEF;&#x8FDB;&#x884C;&#x7BA1;&#x7406;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">reset</td>\n<td style=\"text-align:left\">&#x56DE;&#x6EDA;&#x6807;&#x5FD7;&#xFF0C;&#x8BE5;bundle&#x4F1A;&#x56DE;&#x6EDA;&#x5230;dexpatch&#x524D;&#x7684;&#x7248;&#x672C;</td>\n</tr>\n<tr>\n<td style=\"text-align:left\">dexPatch</td>\n<td style=\"text-align:left\">&#x533A;&#x5206;&#x914D;&#x7F6E;&#x662F;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x8FD8;&#x662F; dexpatch</td>\n</tr>\n</tbody>\n</table>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"dexpatch.html\" class=\"navigation navigation-prev \" aria-label=\"Previous page: dexpatch\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"guide.html\" class=\"navigation navigation-next \" aria-label=\"Next page: 一些限制\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"dexpatch使用教程\",\"level\":\"1.4.3\",\"depth\":2,\"next\":{\"title\":\"一些限制\",\"level\":\"1.4.4\",\"depth\":2,\"path\":\"update/guide.md\",\"ref\":\"update/guide.md\",\"articles\":[]},\"previous\":{\"title\":\"dexpatch\",\"level\":\"1.4.2\",\"depth\":2,\"path\":\"update/dexpatch.md\",\"ref\":\"update/dexpatch.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"update/dexpatch_use_guide.md\",\"mtime\":\"2017-11-27T09:41:52.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/update/guide.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>一些限制 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    \n    <link rel=\"prev\" href=\"dexpatch_use_guide.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../guide-for-use/\">\n            \n                <a href=\"../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"./\">\n            \n                <a href=\"./\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"principle.html\">\n            \n                <a href=\"principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"dexpatch.html\">\n            \n                <a href=\"dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"dexpatch_use_guide.html\">\n            \n                <a href=\"dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.4.4\" data-path=\"guide.html\">\n            \n                <a href=\"guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../faq/question.html\">\n            \n                <a href=\"../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../faq/help.html\">\n            \n                <a href=\"../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../faq/variant.html\">\n            \n                <a href=\"../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >一些限制</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h4 id=\"&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x9650;&#x5236;\">&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x9650;&#x5236;</h4>\n<ol>\n<li><p><strong>AndroidManifest</strong>\n  &#x5DF2;&#x6709;Activity&#x7684;manifest&#x4FE1;&#x606F;&#x6682;&#x65F6;&#x4E0D;&#x652F;&#x6301;&#x66F4;&#x6539;</p>\n</li>\n<li><p><strong>window&#x7EA7;&#x522B;&#x4F7F;&#x7528;&#x7684;&#x8D44;&#x6E90;&#x4FDD;&#x6301;&#x4E0D;&#x53D8;</strong>\n Activity&#x5207;&#x6362;&#x7684;&#x52A8;&#x753B;&#x6587;&#x4EF6;&#x3001;&#x901A;&#x77E5;&#x680F;&#x4F7F;&#x7528;&#x7684;logo&#x7B49;&#x5982;&#x679C;&#x4FEE;&#x6539;&#x4E86;&#x4E5F;&#x4E0D;&#x4F1A;&#x751F;&#x6548;&#xFF0C;&#x4E0D;&#x8FC7;&#x4E0D;&#x4F1A;&#x4EA7;&#x751F;&#x95EE;&#x9898;&#xFF0C;&#x4F7F;&#x7528;&#x7684;&#x8FD8;&#x662F;&#x539F;&#x6765;&#x7684;&#x6837;&#x5F0F;</p>\n</li>\n</ol>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"dexpatch_use_guide.html\" class=\"navigation navigation-prev navigation-unique\" aria-label=\"Previous page: dexpatch使用教程\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"一些限制\",\"level\":\"1.4.4\",\"depth\":2,\"next\":{\"title\":\"FAQ\",\"level\":\"1.5\",\"depth\":1,\"ref\":\"\",\"articles\":[{\"title\":\"问答\",\"level\":\"1.5.1\",\"depth\":2,\"path\":\"faq/question.md\",\"ref\":\"faq/question.md\",\"articles\":[]},{\"title\":\"故障排查\",\"level\":\"1.5.2\",\"depth\":2,\"path\":\"faq/help.md\",\"ref\":\"faq/help.md\",\"articles\":[]},{\"title\":\"构建定制包\",\"level\":\"1.5.3\",\"depth\":2,\"path\":\"faq/variant.md\",\"ref\":\"faq/variant.md\",\"articles\":[]},{\"title\":\"动态部署失败排查指南\",\"level\":\"1.5.4\",\"depth\":2,\"path\":\"faq/dynamic_failed_help.md\",\"ref\":\"faq/dynamic_failed_help.md\",\"articles\":[]}]},\"previous\":{\"title\":\"dexpatch使用教程\",\"level\":\"1.4.3\",\"depth\":2,\"path\":\"update/dexpatch_use_guide.md\",\"ref\":\"update/dexpatch_use_guide.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"update/guide.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/update/index.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>动态部署 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"principle.html\" />\n    \n    \n    <link rel=\"prev\" href=\"../guide-for-use/bundleCommunicate.html\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../guide-for-use/\">\n            \n                <a href=\"../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter active\" data-level=\"1.4\" data-path=\"./\">\n            \n                <a href=\"./\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.4.1\" data-path=\"principle.html\">\n            \n                <a href=\"principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"dexpatch.html\">\n            \n                <a href=\"dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"dexpatch_use_guide.html\">\n            \n                <a href=\"dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"guide.html\">\n            \n                <a href=\"guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../faq/question.html\">\n            \n                <a href=\"../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../faq/help.html\">\n            \n                <a href=\"../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../faq/variant.html\">\n            \n                <a href=\"../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >动态部署</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"&#x52A8;&#x6001;&#x90E8;&#x7F72;\">&#x52A8;&#x6001;&#x90E8;&#x7F72;</h1>\n<p>&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x4E0E;&#x539F;&#x6709;&#x7684;Apk&#x66F4;&#x65B0;&#x7B56;&#x7565;&#x76F8;&#x6BD4;&#x662F;&#x4E00;&#x79CD;&#x76F8;&#x5BF9;&#x6BD4;&#x8F83;&#x8F7B;&#x91CF;&#x5316;&#x7684;&#x66F4;&#x65B0;&#x7B56;&#x7565;&#xFF0C;&#x4E0D;&#x9700;&#x8981;&#x7528;&#x6237;&#x4E0B;&#x8F7D;&#x6574;&#x4E2A;Apk&#xFF0C;&#x53EA;&#x9700;&#x8981;&#x4E0B;&#x8F7D;&#x4EC5;&#x4EC5;&#x5DEE;&#x91CF;&#x90E8;&#x5206;&#x7684;&#x5185;&#x5BB9;&#x6765;&#x8FBE;&#x5230;&#x66F4;&#x65B0;&#x6548;&#x679C;&#xFF1B;&#x540C;&#x65F6;&#x4E5F;&#x53EF;&#x4EE5;&#x9759;&#x9ED8;&#x7684;&#x5B8C;&#x6210;&#x66F4;&#x65B0;&#x8FC7;&#x7A0B;&#xFF0C;&#x4E24;&#x8005;&#x76F8;&#x7ED3;&#x5408;&#x53EF;&#x4EE5;&#x4F7F;&#x52A8;&#x6001;&#x66F4;&#x65B0;&#x7684;&#x751F;&#x6548;&#x7387;&#x8FDC;&#x9AD8;&#x4E8E;&#x666E;&#x901A;&#x7684;&#x5347;&#x7EA7;&#x7B56;&#x7565;&#x3002;</p>\n<p>&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x9002;&#x5408;&#x7528;&#x6765;&#x89E3;&#x51B3;&#x4E0B;&#x9762;&#x7B49;&#x9700;&#x6C42;&#xFF1A;</p>\n<ol>\n<li>&#x53CA;&#x65F6;&#x4E0A;&#x7EBF;&#x65B0;&#x9700;&#x6C42;&#xFF0C;&#x5FEB;&#x901F;&#x751F;&#x6548;&#x3002;</li>\n<li>&#x4E1A;&#x52A1;&#x7070;&#x5EA6;&#x65B0;&#x7684;sdk&#xFF0C;&#x5FEB;&#x901F;&#x6D4B;&#x8BD5;&#x6548;&#x679C;&#xFF0C;&#x540C;&#x65F6;&#x6709;&#x95EE;&#x9898;&#x53EF;&#x4EE5;&#x53CA;&#x65F6;&#x56DE;&#x6EDA;</li>\n<li>&#x52A8;&#x6001;&#x4FEE;&#x590D;&#x7EBF;&#x4E0A;&#x6545;&#x969C;</li>\n</ol>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"../guide-for-use/bundleCommunicate.html\" class=\"navigation navigation-prev \" aria-label=\"Previous page: 跨bundle的代码重用和通信\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"principle.html\" class=\"navigation navigation-next \" aria-label=\"Next page: 技术原理\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"动态部署\",\"level\":\"1.4\",\"depth\":1,\"next\":{\"title\":\"技术原理\",\"level\":\"1.4.1\",\"depth\":2,\"path\":\"update/principle.md\",\"ref\":\"update/principle.md\",\"articles\":[]},\"previous\":{\"title\":\"跨bundle的代码重用和通信\",\"level\":\"1.3.4\",\"depth\":2,\"path\":\"guide-for-use/bundleCommunicate.md\",\"ref\":\"guide-for-use/bundleCommunicate.md\",\"articles\":[]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"update/README.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/_book/update/principle.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>技术原理 · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"../gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"../gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"../gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"../gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    <link rel=\"next\" href=\"dexpatch.html\" />\n    \n    \n    <link rel=\"prev\" href=\"./\" />\n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter \" data-level=\"1.1\" data-path=\"../\">\n            \n                <a href=\"../\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2\" >\n            \n                <span>\n            \n                    \n                    原理解析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.2.1\" data-path=\"../principle-intro/Runtime_principle.html\">\n            \n                <a href=\"../principle-intro/Runtime_principle.html\">\n            \n                    \n                    框架原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.2\" data-path=\"../principle-intro/Project_architectured.html\">\n            \n                <a href=\"../principle-intro/Project_architectured.html\">\n            \n                    \n                    名词解释\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.3\" data-path=\"../principle-intro/Apk_architecture.html\">\n            \n                <a href=\"../principle-intro/Apk_architecture.html\">\n            \n                    \n                    APK结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.2.4\" data-path=\"../principle-intro/File_architecture_runtime.html\">\n            \n                <a href=\"../principle-intro/File_architecture_runtime.html\">\n            \n                    \n                    运行期文件结构\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3\" data-path=\"../guide-for-use/\">\n            \n                <a href=\"../guide-for-use/\">\n            \n                    \n                    接入指引\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.3.1\" data-path=\"../guide-for-use/guide_for_build.html\">\n            \n                <a href=\"../guide-for-use/guide_for_build.html\">\n            \n                    \n                    容器接入\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.2\" data-path=\"../guide-for-use/guide_for_bundle.html\">\n            \n                <a href=\"../guide-for-use/guide_for_bundle.html\">\n            \n                    \n                    bundle拆分|新建\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.3\" data-path=\"../guide-for-use/guide_for_compile.html\">\n            \n                <a href=\"../guide-for-use/guide_for_compile.html\">\n            \n                    \n                    awo编译\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.3.4\" data-path=\"../guide-for-use/bundleCommunicate.html\">\n            \n                <a href=\"../guide-for-use/bundleCommunicate.html\">\n            \n                    \n                    跨bundle的代码重用和通信\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4\" data-path=\"./\">\n            \n                <a href=\"./\">\n            \n                    \n                    动态部署\n            \n                </a>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter active\" data-level=\"1.4.1\" data-path=\"principle.html\">\n            \n                <a href=\"principle.html\">\n            \n                    \n                    技术原理\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.2\" data-path=\"dexpatch.html\">\n            \n                <a href=\"dexpatch.html\">\n            \n                    \n                    dexpatch\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.3\" data-path=\"dexpatch_use_guide.html\">\n            \n                <a href=\"dexpatch_use_guide.html\">\n            \n                    \n                    dexpatch使用教程\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.4.4\" data-path=\"guide.html\">\n            \n                <a href=\"guide.html\">\n            \n                    \n                    一些限制\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5\" >\n            \n                <span>\n            \n                    \n                    FAQ\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.5.1\" data-path=\"../faq/question.html\">\n            \n                <a href=\"../faq/question.html\">\n            \n                    \n                    问答\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.2\" data-path=\"../faq/help.html\">\n            \n                <a href=\"../faq/help.html\">\n            \n                    \n                    故障排查\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.3\" data-path=\"../faq/variant.html\">\n            \n                <a href=\"../faq/variant.html\">\n            \n                    \n                    构建定制包\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.5.4\" data-path=\"../faq/dynamic_failed_help.html\">\n            \n                <a href=\"../faq/dynamic_failed_help.html\">\n            \n                    \n                    动态部署失败排查指南\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6\" >\n            \n                <span>\n            \n                    \n                    源码分析\n            \n                </span>\n            \n\n            \n            <ul class=\"articles\">\n                \n    \n        <li class=\"chapter \" data-level=\"1.6.1\" data-path=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                <a href=\"../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.html\">\n            \n                    \n                    Atlas之Gradle配置\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.2\" data-path=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_1.html\">\n            \n                    \n                    Atlas之启动过程(一)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.3\" data-path=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                <a href=\"../code_read/atlas_start/atlas_start_2.html\">\n            \n                    \n                    Atlas之启动过程(二)\n            \n                </a>\n            \n\n            \n        </li>\n    \n        <li class=\"chapter \" data-level=\"1.6.4\" data-path=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                <a href=\"../code_read/atlas_bundle_load/atlas_bundle_load.html\">\n            \n                    \n                    Atlas之Bundle加载过程\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n            </ul>\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\"..\" >技术原理</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"&#x6280;&#x672F;&#x539F;&#x7406;\">&#x6280;&#x672F;&#x539F;&#x7406;</h1>\n<p>&#x666E;&#x901A;Apk&#x7684;&#x66F4;&#x65B0;&#x7684;&#x8FC7;&#x7A0B;&#x4E3A;&#x6784;&#x5EFA;-&gt;&#x5B89;&#x88C5;-&gt;&#x751F;&#x6548;&#xFF0C;&#x4E0E;&#x4E4B;&#x76F8;&#x5BF9;&#x5E94;&#xFF0C;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x4E5F;&#x53EF;&#x4EE5;&#x5206;&#x4E3A;&#x4E09;&#x4E2A;&#x8FC7;&#x7A0B;&#xFF1A;</p>\n<ol>\n<li><strong>&#x6784;&#x5EFA;</strong>  &#x4E0D;&#x540C;&#x4E8E;Apk&#x66F4;&#x65B0;&#x4EA7;&#x7269;&#x5C31;&#x662F;&#x4E00;&#x4E2A;&#x5B8C;&#x6574;&#x7684;Apk&#xFF0C;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x6784;&#x5EFA;&#x4EA7;&#x7269;&#x662F;&#x4E00;&#x4E2A;&#x540E;&#x7F00;&#x4E3A;tpatch&#x683C;&#x5F0F;&#x7684;&#x6587;&#x4EF6;</li>\n<li><strong>merge</strong> &#x4E0B;&#x8F7D;&#x5230;tpatch&#x6587;&#x4EF6;&#x540E;&#xFF0C;&#x52A8;&#x6001;&#x90E8;&#x7F72;sdk&#x4F1A;&#x5728;&#x540E;&#x53F0;&#x5B8C;&#x6210;merge&#x5230;&#x5B89;&#x88C5;&#x7684;&#x8FC7;&#x7A0B;&#xFF0C;&#x6574;&#x4E2A;&#x8FC7;&#x7A0B;&#x5BF9;&#x7528;&#x6237;&#x900F;&#x660E;</li>\n<li><strong>&#x751F;&#x6548;</strong>  merge&#x5B8C;&#x4EE5;&#x540E;&#xFF0C;&#x5F53;&#x524D;&#x7684;&#x5E94;&#x7528;&#x5904;&#x4E8E;&#x4E00;&#x4E2A;&#x7B49;&#x5F85;&#x751F;&#x6548;&#x7684;&#x72B6;&#x6001;&#xFF0C;&#x4F1A;&#x5728;&#x5408;&#x9002;&#x7684;&#x65F6;&#x673A;&#x9009;&#x62E9;&#x8FDB;&#x7A0B;&#x91CD;&#x542F;&#x6765;&#x751F;&#x6548;&#x6B64;&#x6B21;&#x7684;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#xFF0C;&#x4E14;&#x5728;&#x751F;&#x6548;&#x524D;&#x4E0D;&#x4F1A;&#x518D;&#x63A5;&#x6536;&#x65B0;&#x7684;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x884C;&#x4E3A;&#xFF0C;&#x8FDB;&#x7A0B;&#x91CD;&#x542F;&#x4EE5;&#x540E;&#x8868;&#x793A;&#x4E00;&#x6B21;&#x5B8C;&#x6574;&#x7684;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x8FC7;&#x7A0B;&#x7ED3;&#x675F;</li>\n</ol>\n<p>&#x4E0B;&#x9762;&#x5BF9;&#x6BCF;&#x4E2A;&#x8FC7;&#x7A0B;&#x5C55;&#x5F00;&#x8BB2;&#x89E3;&#x4E0B;&#xFF0C;&#x4EE5;&#x4FBF;&#x66F4;&#x597D;&#x7406;&#x89E3;&#x6574;&#x4E2A;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x673A;&#x5236;</p>\n<h3 id=\"&#x6784;&#x5EFA;\">&#x6784;&#x5EFA;</h3>\n<p>&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x6784;&#x5EFA;&#x7684;&#x4EA7;&#x7269;&#x4E3A;tpatch&#x4E3A;&#x540E;&#x7F00;&#x7684;&#x4E00;&#x4E2A;&#x538B;&#x7F29;&#x6587;&#x4EF6;--&#x6587;&#x4EF6;&#x540D;&#x4E3A;</p>\n<p><strong>patch-targetVersion@sourceVersion.tpatch</strong></p>\n<p>&#x4F8B;&#x5982;&#x624B;&#x6DD8;6.2.0&#x90E8;&#x7F72;&#x5230;6.2.1&#x7684;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;tpatch&#x6587;&#x4EF6;&#x4E3A;&#xFF1A;\npatch-6.2.1@6.2.0.tpatch</p>\n<p>patch&#x6587;&#x4EF6;&#x89E3;&#x538B;&#x540E;&#x4E00;&#x7EA7;&#x76EE;&#x5F55;&#x5982;&#x4E0B;&#x56FE;&#xFF1A;</p>\n<ol>\n<li>&#x5982;&#x679C;&#x6709;&#x4E3B;apk&#x7684;&#x66F4;&#x65B0;&#xFF0C;&#x5219;&#x4F1A;&#x6709;com_taobao_maindex.so&#x5B58;&#x5728;&#xFF0C;so&#x4E2D;&#x5305;&#x542B;&#x5DEE;&#x91CF;&#x7684;classes.dex&#x3001;res&#x7B49;</li>\n<li>&#x5982;&#x679C;&#x6709;bundle&#x66F4;&#x65B0;&#xFF0C;&#x5219;&#x4E00;&#x7EA7;&#x76EE;&#x5F55;&#x4E0B;&#x4EE5;bundle&#x4E3A;&#x7C92;&#x5EA6;&#x6709;&#x591A;&#x4E2A;&#x6587;&#x4EF6;&#x5939;&#xFF0C;&#x6BCF;&#x4E2A;&#x6587;&#x4EF6;&#x5939;&#x4E0B;&#x5305;&#x542B;&#x5DEE;&#x91CF;&#x7684;classes.dex&#xFF0C;res&#x7B49;</li>\n</ol>\n<p><strong>&#x6CE8;&#x610F;&#x70B9;&#xFF1A;&#x4E3B;Apk&#x7684;&#x5DEE;&#x91CF;&#x4E0E;bundle&#x7684;&#x5DEE;&#x91CF;&#x76EE;&#x524D;&#x91C7;&#x53D6;&#x4E0D;&#x540C;&#x7684;&#x7B56;&#x7565;&#xFF0C;&#x4E3B;Apk&#x6C38;&#x8FDC;&#x662F;&#x4E0E;&#x57FA;&#x7EBF;&#x7248;&#x672C;&#x505A;&#x5DEE;&#x91CF;&#xFF1B;&#x800C;bundle&#x662F;&#x66F4;&#x4E0A;&#x4E00;&#x4E2A;&#x7248;&#x672C;&#x505A;&#x5DEE;&#x91CF;&#xFF1A;&#x6BD4;&#x5982;&#x4ECE;6.1&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x5230;6.2&#x518D;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x5230;6.3&#xFF0C;&#x5219;6.3&#x4E2D;&#x4E3B;apk&#x7684;&#x5DEE;&#x91CF;&#x662F;6.3&#x4E3B;apk&#x7684;&#x96C6;&#x6210;&#x5185;&#x5BB9;&#x548C;&#x57FA;&#x7EBF;&#xFF08;6.1&#xFF09;&#x4E3B;apk&#x4E2D;&#x7684;&#x5185;&#x5BB9;diff&#x51FA;&#x5DEE;&#x91CF;&#xFF1B;6.3&#x4E2D;bundle&#x7684;&#x5DEE;&#x91CF;&#x5219;&#x662F;&#x4E0E;&#x4E0A;&#x4E00;&#x4E2A;&#x7248;&#x672C;&#x8FDB;&#x884C;diff&#xFF0C;&#x5982;&#x679C;&#x662F;6.2&#x7684;&#x7248;&#x672C;&#x53BB;&#x8BF7;&#x6C42;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;tpatch&#xFF0C;&#x5219;tpatch&#x4E2D;&#x7684;bundle&#x7684;&#x5DEE;&#x91CF;&#x662F;6.3&#x4E0E;6.2&#x7684;bundle&#x8FDB;&#x884C;diff&#x6240;&#x5F97;&#xFF0C;&#x5982;&#x679C;&#x662F;6.1&#x7248;&#x672C;&#x53BB;&#x8BF7;&#x6C42;6.3&#x7684;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;tpatch&#xFF0C;&#x5219;bundle&#x7684;&#x5DEE;&#x91CF;&#x662F;6.3&#x4E0E;6.1&#x7684;bundle&#x8FDB;&#x884C;diff&#x6240;&#x5F97;</strong>\n&gt;\n<img src=\"img/patch_file.png\" alt=\"MacDown Screenshot\"></p>\n<p>&#x4E0E;tpatch&#x6587;&#x4EF6;&#x76F8;&#x5BF9;&#x4E8E;&#x7684;&#xFF0C;&#x63A5;&#x53E3;&#x4F1A;&#x8FD4;&#x56DE;&#x8BE5;&#x6B21;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x4FEE;&#x6539;&#x5185;&#x5BB9;&#xFF0C;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x5982;&#x4E0B;&#xFF1A;\n<img src=\"img/patch_json.png\" alt=\"MacDown Screenshot\"></p>\n<p>&#x6570;&#x636E;&#x4E2D;&#x53EF;&#x4EE5;&#x770B;&#x51FA;bundle&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x8FC7;&#x7A0B;bundle&#x7684;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#x5141;&#x8BB8;&#x53D1;&#x751F;&#x53D8;&#x66F4;&#xFF0C;&#x540C;&#x65F6;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x4E5F;&#x6709;&#x4E00;&#x5B9A;&#x7684;&#x9650;&#x5236;&#xFF0C;&#x8FD9;&#x4E2A;&#x4F1A;&#x5728;&#x540E;&#x9762;&#x5355;&#x72EC;&#x8FDB;&#x884C;&#x8BF4;&#x660E;</p>\n<h3 id=\"merge\">Merge</h3>\n<p>merge&#x8FC7;&#x7A0B;&#x5728;&#x4E0B;&#x8F7D;&#x5230;tpatch&#x4E14;&#x6821;&#x9A8C;&#x901A;&#x8FC7;&#x540E;&#x5728;&#x7EBF;&#x7A0B;&#x4E2D;&#x8FDB;&#x884C;&#xFF0C;&#x7531;&#x4E4B;&#x524D;Atlas&#x5BB9;&#x5668;&#x5B89;&#x88C5;&#x76EE;&#x5F55;&#x4ECB;&#x7ECD;&#x53EF;&#x77E5;&#xFF0C;&#x5047;&#x8BBE;&#x5F53;&#x524D;bundle&#x7684;&#x7248;&#x672C;&#x5728;&#x6587;&#x4EF6;&#x7CFB;&#x7EDF;&#x4E0A;&#x4E3A;Version.1,&#x5219;merge&#x6210;&#x529F;&#x540E;&#x65B0;&#x7684;bundle&#x4F1A;&#x5B89;&#x88C5;&#x5728;Version.2&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x5E76;&#x5728;&#x540E;&#x7EED;&#x65B0;&#x7684;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x4E2D;&#x7248;&#x672C;&#x53F7;&#x9010;&#x6B65;&#x5F80;&#x540E;&#x8FFD;&#x52A0;&#xFF0C;&#x540C;&#x65F6;&#x9274;&#x4E8E;&#x7A7A;&#x95F4;&#x5360;&#x7528;&#x7684;&#x8003;&#x8651;&#xFF0C;&#x76EE;&#x524D;&#x7684;&#x7B56;&#x7565;&#x662F;&#x4F1A;&#x4FDD;&#x7559;&#x4E0A;&#x4E00;&#x4E2A;&#x7248;&#x672C;&#xFF08;&#x9274;&#x4E8E;&#x56DE;&#x6EDA;&#x7684;&#x8003;&#x8651;&#xFF09;&#xFF1B;</p>\n<p>&#x4E0E;bundle&#x4EE5;&#x5305;&#x540D;&#x4E3A;&#x6587;&#x4EF6;&#x5939;&#x5B58;&#x653E;&#x7C7B;&#x4F3C;&#xFF0C;&#x4E3B;Apk&#x66F4;&#x65B0;&#x5B58;&#x653E;&#x7684;&#x6587;&#x4EF6;&#x5939;&#x4EE5;<strong>com.taobao.maindex</strong>&#x4E3A;&#x540D;&#x5B57;&#xFF0C;&#x91CC;&#x9762;&#x7684;&#x7248;&#x672C;&#x7BA1;&#x7406;&#x4E0E;bundle&#x4E00;&#x81F4;&#xFF0C;&#x4E0D;&#x540C;&#x70B9;&#x662F;com.taobao.maindex&#x53EA;&#x5728;&#x53D1;&#x751F;&#x8FC7;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x4EE5;&#x540E;&#x624D;&#x4F1A;&#x6709;&#xFF0C;Version.1&#x610F;&#x5473;&#x7740;&#x5DF2;&#x7ECF;&#x53D1;&#x751F;&#x4E00;&#x6B21;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#xFF1B;bundle&#x901A;&#x5E38;&#x60C5;&#x51B5;&#x4E0B;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x4ECE;Version.2&#x5F00;&#x59CB;&#xFF08;&#x672A;&#x5B89;&#x88C5;&#x8FC7;&#x7684;bundle&#x9664;&#x5916;&#xFF09;</p>\n<p>&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x6210;&#x529F;&#x540E;&#xFF0C;&#x4F1A;&#x5728;&#x4E0B;&#x6B21;&#x8FDB;&#x7A0B;&#x91CD;&#x542F;&#x540E;&#x53BB;resolve&#x65B0;&#x7684;bundle&#xFF0C;resolve&#x7684;&#x7B56;&#x7565;&#x662F;&#x6309;&#x7248;&#x672C;&#x53F7;&#x4ECE;&#x9AD8;&#x5230;&#x4F4E;&#x56DE;&#x6EAF;&#xFF0C;&#x9009;&#x62E9;&#x6700;&#x9AD8;&#x53EF;&#x7528;&#x7684;&#x7248;&#x672C;&#x4F7F;&#x7528;&#x3002;</p>\n<p>&#x4E0B;&#x9762;&#x5C55;&#x5F00;&#x4ECB;&#x7ECD;&#x4E0B;&#x5728;&#x65B0;bundle&#xFF08;&#x5047;&#x8BBE;&#x4E3B;Apk&#x5F53;&#x505A;&#x662F;&#x4E00;&#x4E2A;&#x7279;&#x6B8A;&#x7684;bundle&#xFF09;&#x5B89;&#x88C5;&#x6210;&#x529F;&#x524D;merge&#x7684;&#x8FC7;&#x7A0B;&#x4E2D;bundle&#x548C;&#x4E3B;Apk&#x5728;merge&#x8FC7;&#x7A0B;&#x4E2D;&#x7684;&#x5DEE;&#x5F02;&#x70B9;&#xFF1A;</p>\n<h4 id=\"bundle-merge\">bundle Merge</h4>\n<p>bundle&#x7684;merge&#x4E3B;&#x8981;&#x4EE5;&#x4E0B;&#x51E0;&#x4E2A;&#x8FC7;&#x7A0B;(&#x5982;&#x4E0B;&#x56FE;)</p>\n<ol>\n<li>&#x83B7;&#x53D6;merge&#x7684;&#x6570;&#x636E;&#x6E90;&#xFF1A;patch&#x4FE1;&#x606F;&#x6765;&#x81EA;&#x4E8E;bundle&#x5728;&#x4E0B;&#x8F7D;&#x7684;tpatch&#x5305;&#x4E2D;&#x7684;&#x5185;&#x5BB9;&#xFF0C;&#x7528;&#x4E8E;merge&#x7684;source&#x6765;&#x81EA;&#x4E8E;&#x5F53;&#x524D;&#x8BBE;&#x5907;&#x7684;&#x6587;&#x4EF6;&#x7CFB;&#x7EDF;&#x4E2D;&#xFF0C;&#x53EF;&#x80FD;&#x6765;&#x81EA;&#x4E8E;&#x5DF2;&#x7ECF;&#x5B89;&#x88C5;&#x8FC7;&#x7684;bundle&#xFF08;storage&#xFF09;&#xFF0C;&#x53EF;&#x80FD;&#x8FD8;&#x6CA1;&#x6709;&#x5B89;&#x88C5;&#xFF08;apk&#x6216;&#x8005;lib&#x76EE;&#x5F55;&#x4E0B;&#xFF09;</li>\n<li>&#x521B;&#x5EFA;&#x65B0;&#x7684;bundle zip&#x5305;&#xFF0C;classes.dex&#x6765;&#x81EA;&#x4E8E;source&#x4E2D;&#x7684;classes.dex&#x548C;patch&#x5305;&#x4E2D;&#x7684;classes.dex&#x901A;&#x8FC7;Dexmerge&#x5408;&#x5E76;&#x65B0;&#x7684;classes.dex</li>\n<li>arsc&#x548C;AndroidManifest&#x76F4;&#x63A5;&#x4F7F;&#x7528;patch&#x5305;&#x4E2D;&#x7684;&#x5185;&#x5BB9; </li>\n<li>res&#x548C;assets &#x4F1A;&#x8FDB;&#x884C;&#x5408;&#x5E76;&#xFF0C;&#x5982;&#x679C;&#x6587;&#x4EF6;&#x6CA1;&#x6709;&#x53D8;&#x66F4;&#xFF08;patch&#x4E2D;&#x6CA1;&#x6709;&#xFF0C;source&#x4E2D;&#x6709;&#xFF09;&#xFF0C;&#x5219;&#x76F4;&#x63A5;&#x4F7F;&#x7528;source&#x4E2D;&#x7684;&#x5185;&#x5BB9;&#xFF0C;&#x5982;&#x679C;&#x6709;&#x6587;&#x4EF6;&#x65B0;&#x589E;&#x6216;&#x8005;&#x53D1;&#x751F;&#x4E86;&#x53D8;&#x66F4;&#xFF08;patch&#x4E2D;&#x6709;&#xFF0C;source&#x4E2D;&#x6709;&#x6216;&#x8005;&#x6CA1;&#x6709;&#xFF09;&#xFF0C;&#x5219;&#x4ECE;patch&#x4E2D;&#x8BFB;&#x53D6;&#x653E;&#x5230;&#x65B0;&#x7684;bundle&#x5305;&#x4E2D;\n<img src=\"img/bundle_merge.png\" alt=\"MacDown Screenshot\"></li>\n</ol>\n<p>merge&#x5B8C;&#x4EE5;&#x540E;&#x63A5;&#x4E0B;&#x53BB;&#x5B89;&#x88C5;&#x5C31;&#x662F;&#x5BB9;&#x5668;&#x7684;&#x903B;&#x8F91;&#x4E86;&#xFF0C;&#x5982;&#x679C;&#x6CA1;&#x6709;&#x5B89;&#x88C5;&#x8FC7;&#x5219;&#x5728;bundle&#x76EE;&#x5F55;&#x4E0B;&#x751F;&#x6210;Version.1&#x76EE;&#x5F55;&#x8FDB;&#x884C;&#x5B89;&#x88C5;&#xFF0C;&#x5982;&#x679C;&#x5B89;&#x88C5;&#x8FC7;&#x5219;&#x751F;&#x6210;&#x65B0;&#x7684;&#x7248;&#x672C;&#x76EE;&#x5F55;</p>\n<h4 id=\"&#x4E3B;apk&#x7684;merge\">&#x4E3B;Apk&#x7684;Merge</h4>\n<p>&#x4E3B;Apk&#x7684;Merge&#x5728;dalvik&#x548C;art&#x4E0A;&#x4F7F;&#x7528;&#x7684;&#x673A;&#x5236;&#x6709;&#x6240;&#x4E0D;&#x540C;&#xFF0C;dalvik&#x8BBE;&#x5907;&#x4E0A;&#x6CA1;&#x6709;&#x4EFB;&#x4F55;merge&#x8FC7;&#x7A0B;&#xFF0C;&#x76F4;&#x63A5;&#x628A;libcom_taobao_maindex.so&#x4EE5;bundle&#x7684;&#x5F62;&#x5F0F;&#x5B89;&#x88C5;&#x5230;com.taobao.maindex&#x76EE;&#x5F55;&#x4E0B;\nArt&#x8BBE;&#x5907;&#x4E0A;&#x6211;&#x4EEC;&#x4F1A;&#x6839;&#x636E;source&#x7684;apk&#xFF08;&#x4E3B;apk&#x7684;merge&#x6C38;&#x8FDC;&#x662F;&#x57FA;&#x4E8E;&#x57FA;&#x7EBF;&#x7248;&#x672C;&#xFF09;&#x628A;classes.dex &#x63D0;&#x53D6;&#x51FA;&#x6765;&#x4EE5;&#x591A;dex&#x7684;&#x65B9;&#x5F0F;&#x8FFD;&#x52A0;&#x5230;libcom_taobao_maindex.so&#x4E2D;&#xFF0C;&#x5982;&#x679C;&#x672C;&#x8EAB;&#x662F;&#x591A;dex&#x673A;&#x5236;&#x7684;&#xFF0C;&#x90A3;&#x4E48;&#x4F1A;&#x5C06;&#x591A;&#x4E2A;&#x5B50;dex&#x5168;&#x90E8;&#x8FFD;&#x52A0;&#x8FDB;&#x53BB;&#xFF0C;patch&#x91CC;&#x9762;&#x7684;classes.dex&#x4FDD;&#x6301;&#x4E0D;&#x53D8;&#xFF0C;source&#x91CC;&#x9762;&#x7684;dex&#x7684;&#x5E8F;&#x5217;&#x53F7;&#x5F80;&#x540E;&#x504F;&#x79FB;&#x4E00;&#x4F4D;&#xFF08;classes.dex-&gt;classes2.dex,classes2.dex-&gt;classes3.dex&#xFF09;,&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;&#xFF1A;\n&gt;\n<img src=\"img/art_maindex_merge.png\" alt=\"MacDown Screenshot\"></p>\n<p>Merge&#x5B89;&#x88C5;&#x6210;&#x529F;&#x540E;&#xFF0C;&#x4F1A;&#x5C06;bundleinfo&#x7684;&#x4FE1;&#x606F;&#x66F4;&#x65B0;&#x5230;baselineinfo&#x7684;&#x76EE;&#x5F55;&#x4E2D;&#xFF0C;&#x5E76;&#x5728;&#x4E0B;&#x6B21;&#x542F;&#x52A8;&#x7684;&#x6700;&#x65E9;&#x65F6;&#x95F4;&#x66FF;&#x6362;&#x6389;&#x539F;&#x6709;&#x7684;baselineinfo&#x4FE1;&#x606F;&#xFF1B;&#x91CC;&#x9762;&#x7684;&#x5185;&#x5BB9;&#x8BB0;&#x5F55;&#x4E86;&#x66F4;&#x65B0;&#x7684;bundle&#x7684;name&#xFF0C;version&#x4EE5;&#x53CA;&#x90E8;&#x7F72;&#x6210;&#x529F;&#x4EE5;&#x540E;&#x7684;&#x7248;&#x672C;&#x53F7;&#x7B49;&#x4FE1;&#x606F;&#x3002;</p>\n<h3 id=\"&#x8FD0;&#x884C;&#x671F;\">&#x8FD0;&#x884C;&#x671F;</h3>\n<h4 id=\"bundle&#x7684;&#x8FD0;&#x884C;&#x671F;&#x52A0;&#x8F7D;&#x7B56;&#x7565;&#xFF1A;\">bundle&#x7684;&#x8FD0;&#x884C;&#x671F;&#x52A0;&#x8F7D;&#x7B56;&#x7565;&#xFF1A;</h4>\n<p>&#x7531;&#x4E4B;&#x524D;&#x7684;&#x5BB9;&#x5668;&#x7684;&#x8FD0;&#x884C;&#x673A;&#x5236;&#x53EF;&#x4EE5;&#x5F97;&#x77E5;&#xFF0C;bundle&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x540E;&#x5BF9;&#x5BB9;&#x5668;&#x6765;&#x8BF4;&#x6CA1;&#x6709;&#x4EFB;&#x4F55;&#x53D8;&#x5316;&#xFF0C;&#x8FD8;&#x662F;&#x6309;&#x9700;&#x7684;load bundle&#xFF0C;&#x53EA;&#x662F;&#x5728;&#x9700;&#x8981;&#x53BB;load&#x524D;&#x7248;&#x672C;&#x9009;&#x62E9;&#x4E0A;&#x4F1A;&#x4F7F;&#x7528;&#x6700;&#x9AD8;&#x7684;&#x53EF;&#x7528;&#x7248;&#x672C;</p>\n<h4 id=\"&#x4E3B;apk&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x540E;&#x7684;&#x52A0;&#x8F7D;&#x7B56;&#x7565;\">&#x4E3B;apk&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x540E;&#x7684;&#x52A0;&#x8F7D;&#x7B56;&#x7565;</h4>\n<p>&#x4E86;&#x89E3;&#x4E3B;Apk&#x7684;&#x52A0;&#x8F7D;&#x7B56;&#x7565;&#x4E4B;&#x524D;&#xFF0C;&#x5148;&#x5206;&#x522B;&#x4ECB;&#x7ECD;&#x4E0B;&#x4E3B;Apk&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x5F97;&#x4EE5;&#x6210;&#x529F;&#x7684;&#x6280;&#x672F;&#x57FA;&#x7840;&#x518D;&#x9610;&#x8FF0;&#x751F;&#x6548;&#x7684;&#x65B9;&#x5F0F;&#xFF1A;</p>\n<h5 id=\"classso\">class|so</h5>\n<p>&#x8FD9;&#x91CC;&#x7C97;&#x7565;&#x4ECB;&#x7ECD;&#x4E0B;&#x666E;&#x901A;apk&#xFF08;&#x4E5F;&#x5C31;&#x662F;&#x4E3B;Apk&#xFF09;class&#xFF0C;so&#x5E93;&#x52A0;&#x8F7D;&#x5165;&#x53E3;--<strong>PathClassLoader</strong>\n&#x524D;&#x9762;&#x5BB9;&#x5668;&#x7684;&#x6280;&#x672F;&#x539F;&#x7406;&#x91CC;&#x9762;&#x4ECB;&#x7ECD;&#x4E86;PathClassLoader&#x7684;&#x7236;&#x5B50;&#x5173;&#x7CFB;&#xFF0C;PathClassLoader&#x81EA;&#x8EAB;&#x8D1F;&#x8D23;&#x4E3B;Apk&#x7684;&#x7C7B;&#x548C;c&#x5E93;&#x7684;&#x67E5;&#x627E;&#x8DEF;&#x53E3;&#xFF1B;&#x5176;parent BootClassloader&#x8D1F;&#x8D23;framework sdk&#x7684;&#x5185;&#x5BB9;&#x7684;&#x67E5;&#x627E;&#x3002;</p>\n<p>PathClassLoader&#x672C;&#x8EAB;&#x4E5F;&#x662F;&#x4E00;&#x4E2A;class&#xFF0C;&#x7EE7;&#x627F;&#x4E86;BaseDexClassLoader&#xFF08;&#x540C;DexClassLoader&#xFF09;&#xFF0C;&#x91CC;&#x9762;&#x67E5;&#x627E;&#x8FC7;&#x7A0B;&#x5728;DexPathList&#x91CC;&#x9762;&#x5B9E;&#x73B0;&#xFF08;&#x5982;&#x4E0B;&#x56FE;&#xFF09;\n&gt;\n<img src=\"img/pathclassloader.png\" alt=\"MacDown Screenshot\"></p>\n<p>DexPathList&#x6700;&#x7EC8;&#x901A;&#x8FC7;DexFile&#x53BB;loadClass&#xFF0C;DexPathList&#x53EF;&#x4EE5;&#x7406;&#x89E3;&#x4E3A;&#x6301;&#x6709;&#x8005;DexFile&#x4EE5;&#x53CA;nativeLibrary&#x76EE;&#x5F55;&#xFF0C;&#x518D;&#x67E5;&#x627E;&#x7684;&#x65F6;&#x5019;&#x904D;&#x5386;&#x8FD9;&#x4E9B;&#x5BF9;&#x8C61;&#xFF0C;&#x76F4;&#x5230;&#x627E;&#x5230;&#x9700;&#x8981;&#x7684;&#x7C7B;&#x6216;&#x8005;c&#x5E93;&#xFF0C;&#x90A3;&#x4E48;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x65B9;&#x5F0F;&#x5C31;&#x662F;&#x628A;&#x65B0;&#x4FEE;&#x6539;&#x7684;&#x5185;&#x5BB9;&#x6DFB;&#x52A0;&#x5230;&#x8FD9;&#x4E9B;&#x5BF9;&#x8C61;&#x7684;&#x6700;&#x524D;&#x9762;&#xFF0C;&#x4ECE;&#x800C;&#x4F7F;&#x5F97;&#x67E5;&#x627E;&#x7684;&#x8FC7;&#x7A0B;&#x4E2D;&#x65B0;&#x4FEE;&#x6539;&#x7684;&#x5185;&#x5BB9;&#x80FD;&#x591F;&#x63D0;&#x524D;&#x627E;&#x5230;&#x4ECE;&#x800C;&#x66FF;&#x6362;&#x539F;&#x6709;&#x7684;&#xFF08;&#x5982;&#x4E0B;&#x56FE;&#xFF09;</p>\n<p>&gt;\n<img src=\"img/maindex_load.png\" alt=\"MacDown Screenshot\"></p>\n<p>&#x8FD9;&#x91CC;&#x6709;&#x4E24;&#x4E2A;&#x6CE8;&#x610F;&#x70B9;&#x63D0;&#x53CA;&#x4E00;&#x4E0B;&#x4EE5;&#x52A0;&#x6DF1;&#x7406;&#x89E3;&#xFF1A;</p>\n<ol>\n<li><p><strong>PREVERIFY:</strong> &#x7ECF;&#x8FC7;&#x624B;&#x6DD8;&#x6253;&#x5305;&#x63D2;&#x4EF6;&#x6784;&#x5EFA;&#x4EE5;&#x540E;&#xFF0C;&#x4E3B;apk&#x91CC;&#x9762;&#x7684;&#x6240;&#x6709;class&#xFF0C;interface&#x90FD;&#x63D2;&#x5165;&#x4E86;&#x4E00;&#x6BB5;&#x4EE3;&#x7801;&#xFF1A;&#x7C7B;&#x4F3C;&#x4E0B;&#x56FE;&#x3002;&#x539F;&#x56E0;&#x662F;android&#x6784;&#x5EFA;&#x7684;&#x65F6;&#x5019;&#x4F1A;&#x6709;PREVERIFY&#x7684;&#x8FC7;&#x7A0B;&#xFF0C;&#x5982;&#x679C;Class&#x6240;&#x5F15;&#x7528;&#x5230;&#x7684;Class&#x5747;&#x548C;Class&#x81EA;&#x5DF1;&#x5728;&#x540C;&#x4E00;&#x4E2A;dex&#x5185;&#x90E8;&#xFF0C;&#x5219;&#x4F1A;&#x88AB;&#x6253;&#x4E0A;PREVERIFY&#x7684;&#x6807;&#x8BB0;&#x3002;&#x7136;&#x540E;&#x5728;&#x8FD0;&#x884C;&#x671F;&#x7684;&#x65F6;&#x5019;&#x5982;&#x679C;&#x6253;&#x4E0A;&#x8FD9;&#x4E2A;&#x6807;&#x8BB0;&#x7684;class&#xFF0C;&#x5728;&#x8F7D;&#x5165;&#x65F6;&#x4E0D;&#x9700;&#x8981;&#x7ECF;&#x8FC7;verify&#x5DF2;&#x63D0;&#x9AD8;&#x52A0;&#x8F7D;&#x6548;&#x7387;&#xFF0C;&#x4F46;&#x662F;&#x8FD0;&#x884C;&#x5230;&#x65B9;&#x6CD5;&#x65F6;&#x4F1A;&#x6821;&#x9A8C;&#x4F9D;&#x8D56;&#x7684;class&#x662F;&#x5426;&#x8DDF;&#x6784;&#x5EFA;&#x65F6;&#x4E00;&#x81F4;&#x548C;Class&#x81EA;&#x8EAB;&#x5904;&#x4E8E;&#x540C;&#x4E00;&#x4E2A;dex&#xFF0C;&#x5982;&#x679C;&#x4E0D;&#x4E00;&#x81F4;&#x5219;&#x4F1A;&#x629B;&#x51FA;PREVERIFY&#x7684;&#x9519;&#x8BEF;&#x3002;&#x800C;&#x624B;&#x6DD8;&#x7684;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7B56;&#x7565;&#x5FC5;&#x7136;&#x4F1A;&#x65B0;&#x751F;&#x6210;&#x4E00;&#x4E2A;dex&#xFF0C;&#x90A3;&#x4E48;&#x5982;&#x679C;&#x9047;&#x5230;&#x662F;PREVERIFY&#x7684;class&#x7684;&#x65F6;&#x5019;&#x5C31;&#x4F1A;&#x51FA;&#x9519;&#x3002;&#x6240;&#x4EE5;&#x76EE;&#x524D;&#x624B;&#x6DD8;&#x7684;&#x7B56;&#x7565;&#x662F;&#x5728;&#x7F16;&#x8BD1;&#x671F;&#x7ED9;&#x6BCF;&#x4E2A;class&#x5F15;&#x7528;&#x5230;&#x4E00;&#x4E2A;&#x4E0D;&#x5B58;&#x5728;&#x7684;class&#x4EE5;&#x89E3;&#x9664;PREVERIFY&#x7684;&#x9650;&#x5236;&#xFF08;&#x5177;&#x4F53;PREVERIFY&#x7684;&#x6821;&#x9A8C;&#x8FC7;&#x7A0B;&#x53EF;&#x4EE5;&#x9605;&#x8BFB;Android&#x6E90;&#x7801;&#xFF09;\n&gt;\n<img src=\"img/verify.png\" alt=\"MacDown Screenshot\"></p>\n</li>\n<li><p><strong>OAT&#x7684;&#x9650;&#x5236;:</strong>android&#x5230;art&#x540E;&#x539F;&#x6709;&#x7684;dexopt&#x4F1A;&#x6539;&#x4E3A;dex2oat&#xFF0C;&#x8FD0;&#x884C;&#x65F6;&#x4EE3;&#x7801;&#x7531;&#x539F;&#x6765;&#x7684;&#x89E3;&#x91CA;&#x6267;&#x884C;&#x6539;&#x4E3A;&#x76F4;&#x63A5;&#x8FD0;&#x884C;native&#x4EE3;&#x7801;&#xFF0C;&#x4E4B;&#x524D;&#x7684;&#x4F7F;&#x7528;&#x8FC7;&#x7A0B;&#x4E2D;&#x53D1;&#x73B0;&#x5355;&#x7EAF;&#x5F97;&#x5F80;&#x524D;&#x9762;&#x8FFD;&#x52A0;patch&#x7684;dex&#x5E76;&#x4E0D;&#x80FD;&#x5B8C;&#x5168;&#x89E3;&#x51B3;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;&#x95EE;&#x9898;&#xFF0C;dex2oat&#x7684;&#x8FC7;&#x7A0B;&#x4F18;&#x5316;&#x4E86;class&#x7684;&#x6267;&#x884C;&#x4EE3;&#x7801;&#xFF0C;&#x6BD4;&#x5982;&#x8BF4;&#x5185;&#x655B;&#xFF0C;&#x865A;&#x51FD;&#x6570;&#x7684;&#x6821;&#x9A8C;&#x7B49;&#x3002;&#x5C31;&#x6709;&#x53EF;&#x80FD;&#x5728;&#x8FD0;&#x884C;&#x8FC7;&#x7A0B;&#x4E2D;&#x76F4;&#x63A5;&#x5728;native&#x5C42;&#x6267;&#x884C;&#x8001;&#x7684;&#x4F18;&#x5316;&#x8FC7;&#x7684;class&#x4EE3;&#x7801;&#x800C;&#x4E0D;&#x662F;&#x4ECE;&#x65B0;patch&#x7684;dex&#x4E2D;load&#x65B0;&#x7684;class&#x53BB;&#x4F7F;&#x7528;&#x3002;&#x6240;&#x4EE5;art&#x4E0A;&#x76EE;&#x524D;&#x7684;&#x7B56;&#x7565;&#x662F;&#x628A;patchdex&#xFF0C;sourcedex&#x53C2;&#x8003;multidex&#x7684;&#x673A;&#x5236;&#x653E;&#x5165;&#x4E00;&#x4E2A;zip&#xFF0C;&#x7136;&#x540E;&#x5408;&#x5E76;&#x5728;&#x4E00;&#x8D77;&#x505A;&#x4E00;&#x904D;dex2oat&#xFF0C;&#x8FD9;&#x6837;&#x80FD;&#x4F7F;&#x65B0;&#x7684;class&#x8986;&#x76D6;&#x8001;&#x7684;class&#x53C2;&#x4E0E;dex2oat&#x5E76;&#x5B8C;&#x6210;&#x4F18;&#x5316;&#x7684;&#x8FC7;&#x7A0B;&#xFF0C;&#x6240;&#x4EE5;art&#x4E0A;&#x7684;&#x771F;&#x6B63;&#x7684;&#x6267;&#x884C;&#x8FC7;&#x7A0B;&#x5B9E;&#x9645;&#x4E0A;&#x5728;patch&#x7684;dex&#x4E2D;&#x5DF2;&#x7ECF;&#x5305;&#x542B;&#x4E86;&#x6240;&#x6709;&#x4E3B;apk&#x7684;&#x4EE3;&#x7801;&#xFF0C;&#x57FA;&#x672C;&#x4E0D;&#x4F1A;&#x8D70;&#x5230;old dex&#x7684;&#x903B;&#x8F91;&#x3002;&#xFF08;patchdex &#x63D2;&#x5165;&#x524D;&#x6267;&#x884C;&#x7684;&#x4EE3;&#x7801;&#x9664;&#x5916;&#xFF09; </p>\n</li>\n</ol>\n<h5 id=\"resourceassets\">resource|assets</h5>\n<p>&#x4E3B;Apk&#x4E3A;&#x4E86;&#x652F;&#x6301;&#x5728;Resource&#x80FD;&#x591F;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x5B9E;&#x9645;&#x4E0A;&#x540C;PREVERIFY&#x7684;&#x673A;&#x5236;&#x7C7B;&#x4F3C;&#xFF0C;&#x5728;&#x57FA;&#x7EBF;&#x5305;&#x6784;&#x5EFA;&#x7684;&#x65F6;&#x5019;&#x5C31;&#x5DF2;&#x7ECF;&#x505A;&#x4E86;&#x5904;&#x7406;:&#x57FA;&#x4E8E;Atlas&#x6253;&#x51FA;&#x6765;&#x7684;apk&#x7684;&#x8D44;&#x6E90;&#x5217;&#x8868;&#x4E2D;&#x6709;&#x5982;&#x4E0B;&#x5185;&#x5BB9;&#xFF1A;</p>\n<p>&gt;\n<img src=\"img/base_dump.png\" alt=\"MacDown Screenshot\"></p>\n<p>&#x6211;&#x4EEC;&#x53D6;&#x4E00;&#x4E2A;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;tpatch&#x5305;&#xFF0C;&#x80FD;&#x591F;&#x770B;&#x5230;&#x5982;&#x4E0B;&#x5185;&#x5BB9;&#xFF1A;\n&gt;\n<img src=\"img/patch_dump.png\" alt=\"MacDown Screenshot\"></p>\n<p>&#x8FD9;&#x4E9B;&#x662F;&#x57FA;&#x4E8E;&#x6211;&#x4EEC;atlas-aapt&#x7684;&#x4FEE;&#x6539;&#xFF0C;dalvik&#x4E0A;&#x6211;&#x4EEC;&#x662F;&#x57FA;&#x4E8E;res&#x7684;overlay&#x673A;&#x5236;&#x53BB;&#x4FEE;&#x6539;&#x8D44;&#x6E90;&#xFF0C;&#x8FD9;&#x4E2A;&#x673A;&#x5236;&#x5E76;&#x4E0D;&#x652F;&#x6301;&#x65B0;&#x589E;&#x8D44;&#x6E90;&#xFF0C;&#x5728;overlay&#x7684;&#x5305;&#x91CC;&#x9762;&#x5982;&#x679C;&#x8BFB;&#x5230;&#x4E86;&#x4E00;&#x4E2A;&#x8D44;&#x6E90;&#xFF0C;dalvik&#x7CFB;&#x7EDF;&#x4F1A;&#x53BB;&#x6821;&#x9A8C;&#x8BE5;&#x8D44;&#x6E90;ID&#x5728;base&#x4E2D;&#x503C;&#xFF0C;&#x5982;&#x679C;&#x4E0D;&#x5B58;&#x5728;&#x5219;&#x629B;&#x9519;&#xFF0C;&#x6240;&#x4EE5;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x4E3A;&#x4E86;&#x5229;&#x7528;&#x8FD9;&#x4E00;&#x7279;&#x6027;&#x540C;&#x65F6;&#x652F;&#x6301;&#x65B0;&#x589E;&#x8D44;&#x6E90;&#x7684;&#x9700;&#x6C42;&#xFF0C;&#x5728;&#x6253;&#x57FA;&#x7EBF;&#x5305;&#x7684;&#x65F6;&#x5019;&#x5C31;&#x5728;&#x6BCF;&#x4E2A;&#x4E0D;&#x540C;&#x7684;type&#x91CC;&#x9762;&#x9884;&#x7559;&#x4E86;128&#x4E2A;&#x8D44;&#x6E90;ID&#x4F9B;&#x540E;&#x7EED;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x4F7F;&#x7528;&#xFF1B;&#x540C;&#x65F6;&#x6253;&#x52A8;&#x6001;&#x90E8;&#x7F72;&#x7684;patch&#x65F6;&#x4F1A;&#x4EE5;&#x4E4B;&#x524D;&#x7684;ID&#x5206;&#x914D;&#x7684;&#x5185;&#x5BB9;&#x4F5C;&#x4E3A;&#x8F93;&#x5165;&#xFF0C;&#x4FDD;&#x8BC1;&#x5DF2;&#x6709;&#x7684;&#x8D44;&#x6E90;&#x5206;&#x914D;&#x5230;&#x7684;ID&#x4FDD;&#x6301;&#x4E0D;&#x53D8;&#xFF0C;&#x540C;&#x65F6;&#x5982;&#x679C;&#x8D44;&#x6E90;&#x6CA1;&#x6709;&#x53D1;&#x751F;&#x53D8;&#x66F4;&#xFF0C;&#x5219;&#x5254;&#x9664;&#x8BE5;&#x8D44;&#x6E90;&#xFF0C;&#x6240;&#x4EE5;aapt dump patch&#x7684;&#x65F6;&#x5019;&#x6211;&#x4EEC;&#x770B;&#x5230;&#x7684;INVALID TYPE &#x7684;&#x8D44;&#x6E90;&#x6BB5;&#x6CA1;&#x6709;&#x53D1;&#x751F;&#x53D8;&#x66F4;&#x7684;&#x8D44;&#x6E90;&#xFF0C;&#x5982;&#x679C;&#x6709;&#x53D1;&#x751F;&#x4E86;&#x53D8;&#x66F4;&#xFF0C;&#x4E14;&#x4E4B;&#x524D;&#x6709;&#x8FD9;&#x4E2A;&#x8D44;&#x6E90;&#xFF0C;&#x5C31;&#x4F1A;&#x5728;&#x539F;&#x6709;&#x7684;&#x8D44;&#x6E90;ID&#x5206;&#x914D;&#x8FC7;&#x53BB;&#xFF0C;&#x540C;&#x65F6;&#x65B0;&#x7684;&#x8D44;&#x6E90;&#x6587;&#x4EF6;&#x6253;&#x5165;patch&#x5305;&#x6216;&#x8005;&#x65B0;&#x7684;&#x8D44;&#x6E90;&#x6587;&#x672C;&#x5199;&#x5165;arsc&#xFF0C;&#x5982;&#x679C;&#x662F;&#x65B0;&#x589E;&#x7684;&#x8D44;&#x6E90;&#xFF0C;&#x5219;&#x4F7F;&#x7528;&#x9884;&#x7559;&#x7684;&#x8D44;&#x6E90;&#x6BB5;&#x8FDB;&#x884C;&#x5206;&#x914D;&#x3002;&#x6574;&#x4E2A;&#x66FF;&#x6362;&#x8FC7;&#x7A0B;&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;&#xFF1A;\n&gt;\n<img src=\"img/res_patch.png\" alt=\"MacDown Screenshot\"></p>\n<p>&#x5728;&#x6253;&#x5305;&#x5BF9;&#x8D44;&#x6E90;&#x505A;&#x4E86;&#x4E00;&#x7CFB;&#x5217;&#x5904;&#x7406;&#x4EE5;&#x540E;&#xFF0C;&#x8FD0;&#x884C;&#x671F;&#x8D44;&#x6E90;&#x7684;&#x52A0;&#x8F7D;&#x53EA;&#x662F;&#x5728;&#x542F;&#x52A8;&#x52A0;&#x8F7D;&#x8D44;&#x6E90;&#x65F6;&#x6839;&#x636E;&#x7CFB;&#x7EDF;&#x8BFB;&#x53D6;&#x8D44;&#x6E90;&#x7684;&#x5148;&#x540E;&#x4E66;&#x5E8F;&#x628A;patch&#x5305;&#x63D2;&#x5165;&#x5230;AssetsManager&#x7684;&#x5408;&#x9002;&#x7684;&#x4F4D;&#x7F6E;&#x4E2D;&#xFF0C;assets&#x7531;&#x4E8E;&#x6CA1;&#x6709;&#x8D44;&#x6E90;ID&#xFF0C;&#x4E0D;&#x9700;&#x8981;&#x9884;&#x7559;&#xFF0C;&#x63D2;&#x5165;AssetsManager&#x7684;&#x65B9;&#x5F0F;&#x7C7B;&#x4F3C;res&#x7684;&#x5904;&#x7406;&#xFF0C;&#x8FD9;&#x91CC;&#x4E0D;&#x518D;&#x5C55;&#x5F00;</p>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                <a href=\"./\" class=\"navigation navigation-prev \" aria-label=\"Previous page: 动态部署\">\n                    <i class=\"fa fa-angle-left\"></i>\n                </a>\n                \n                \n                <a href=\"dexpatch.html\" class=\"navigation navigation-next \" aria-label=\"Next page: dexpatch\">\n                    <i class=\"fa fa-angle-right\"></i>\n                </a>\n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"技术原理\",\"level\":\"1.4.1\",\"depth\":2,\"next\":{\"title\":\"dexpatch\",\"level\":\"1.4.2\",\"depth\":2,\"path\":\"update/dexpatch.md\",\"ref\":\"update/dexpatch.md\",\"articles\":[]},\"previous\":{\"title\":\"动态部署\",\"level\":\"1.4\",\"depth\":1,\"path\":\"update/README.md\",\"ref\":\"update/README.md\",\"articles\":[{\"title\":\"技术原理\",\"level\":\"1.4.1\",\"depth\":2,\"path\":\"update/principle.md\",\"ref\":\"update/principle.md\",\"articles\":[]},{\"title\":\"dexpatch\",\"level\":\"1.4.2\",\"depth\":2,\"path\":\"update/dexpatch.md\",\"ref\":\"update/dexpatch.md\",\"articles\":[]},{\"title\":\"dexpatch使用教程\",\"level\":\"1.4.3\",\"depth\":2,\"path\":\"update/dexpatch_use_guide.md\",\"ref\":\"update/dexpatch_use_guide.md\",\"articles\":[]},{\"title\":\"一些限制\",\"level\":\"1.4.4\",\"depth\":2,\"path\":\"update/guide.md\",\"ref\":\"update/guide.md\",\"articles\":[]}]},\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"update/principle.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:00:49.012Z\"},\"basePath\":\"..\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"../gitbook/gitbook.js\"></script>\n    <script src=\"../gitbook/theme.js\"></script>\n    \n        \n        <script src=\"../gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"../gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/code_read/atlas_bundle_load/atlas_bundle_load.md",
    "content": "---\ntitle : Atlas之bundle加载过程\ntime : 2017-05-05 10:00:00\n---\n\n# 概述\n\natals中bundle加载过程\n\n- class\n- resource\n\n![][bundle_load_img]\n\n__注意图中的箭头__\n\n- 实线箭头表示运行在主线程\n- 虚线箭头表示运行在HandlerThread中\n\n将流程分为三大部分\n\n|部分|说明|对应步骤|\n|---|---|---|\n|第一部分|加载时机的触发逻辑|1-7|\n|第二部分|bundle加载过程|8-15|\n|第三部分|bundle代码初始化|16-19|\n\n# 第一部分 触发时机\n\n## 入口\n\n以在MainActivity中点击secondebundle为例\n\nMainActivity.java\n\n```\ncase R.id.navigation_dashboard:\n\tswitchToActivity(\"second\",\"com.taobao.secondbundle.SecondBundleActivity\")\n```\n\nswitchActivity 辗调用，会执行到第2步`execStartChildActivityInternal`方法中\n\n## execStartChildActivityInternal\n\nActivityGroupDelegate.java\n\n```\npublic void execStartChildActivityInternal(ViewGroup container,String key, Intent intent){\n\tString bundleName = AtlasBundleInfoManager.instance().getBundleForComponet(componentName);\n\tif(!TextUtils.isEmpty(bundleName)){\n\t\tBundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(bundleName);\n\t\tif(impl!=null&&impl.checkValidate()) {\t}else {\n\t\t//...\n\t\tasyncStartActivity(container,key,bundleName,intent);\n\t}\n}\n```\n\n- 首先，根据componentName即`com.taobao.secondbundle.SecondBundleActivity`,查询bundle的名称。在[atlas启动过程(下)][atlas_start_2]中，我们知道AtlasBundleInfoManager中存储了几乎所有bundle的信息，所以返回 bundleName 就是 `com.taobao.secondbundle`。\n- 然后，根据bundlename，去查询bundle加载后的结构体- `BundleImpl`。由于secondbundle之前并没有加载进来，所以会执行到第3步`asyncStartActivity`方法。\n\nasyncStartActivity最终调用了BundleUtil的方法，我们直接看第4步 `checkBundleStateAsync`\n\n## checkBundleStateAsync\n\nBundleUtil.java\n\n```\npublic static boolean checkBundleArrayStateAsync(final String[] bundlesName, final Runnable bundleActivated, final Runnable bundleDisabled){\n\tBundleInstaller installer = BundleInstallerFetcher.obtainInstaller();\n\tinstaller.installTransitivelyAsync(bundlesName, new BundleInstaller.InstallListener() {\n\t\t@Override\n\t\tpublic void onFinished() {\n\t\t\tboolean success = true;\n\t\t\tBundleImpl tmp;\n\t\t\tfor(String bundleName : bundlesName){\n\t\t\t\tif((tmp=((BundleImpl) Atlas.getInstance().getBundle(bundleName)))==null || !tmp.checkValidate()){\n\t\t\t\t\tsuccess = false;\n\t\t\t\t}else{\n\t\t\t\t\ttmp.startBundle();\n\t\t\t\t}\n          }\n       });\n\treturn true;\n}\n```\n\n在这一步中，开始异步加载bundle，成功后，在主线程中回调`onFinished`(后面会提及),调用BundleImpl对象的startBundl方法，开始 __第三部分__ 的初始化过程。 \n\n## deliveryTask\n\n第5、6步，主要是各种逻辑判断，之后辗转调用到7步。直接看第7步`deliveryTask`的函数实现。\n\nBundleUtil.java\n\n\n```java\nprivate void deliveryTask(boolean sync){\n\tRunnable installTask = new Runnable() {\n\t\t@Override\n\t\tpublic void run() {\n\t\t\tsynchronized (BundleInstaller.this) {\n             \ttry{\n             \t\tcall();\n             \t} catch (Throwable e) {\n             \t\te.printStackTrace();\n             \t} finally {\n             \t\tif (mListener != null) {\n             \t\t\tnew Handler(Looper.getMainLooper()).post(new Runnable() {\n             \t\t\t\t@Override\n             \t\t\t\tpublic void run() {\n             \t\t\t\t\tmListener.onFinished();\n             \t\t\t\t}\n         \t\t//..\n        };\n        sBundleHandler.post(installTask);\n\n    }\n}\n```\n\n函数首先创建了一个异步任务 `installTask`,之后将任务提交给`sBundleHandler`。而`sBundleHandler`实际上关联的是一个HandlerThread,所以，`installTask `是运行在单独的线程中的。\n\n在 `installTask` 中\n\n- 调用了`call`函数\n- 向ui线程提交一个任务，用于回调`onFinished`\n\n到目前为止，第一部分分析完毕，我们进入第二部分 __加载过程__ \n\n\n# 第二部分 加载过程\n\n需要注意的是，__第二部分整体是运行在 HandlerThread 中的。__\n\n回顾一下第二部分的运行时序\n\n![][bundle_load_part_2]\n\n\n## call\n\n```\ncall(){\n\t//...\n\tif (FileUtils.getUsableSpace(Environment.getDataDirectory()) >= 5) {\n\t\t//has enough space\n\t\tif(AtlasBundleInfoManager.instance().isInternalBundle(bundleName)) {\n\t\t\tbundle = installBundleFromApk(bundleName);\n\t\t\tif (bundle != null) {\n\t\t\t\t((BundleImpl) bundle).optDexFile();\n\t\t\t}\n\t\t}\n\t} else {\n\t\tthrow new LowDiskException(\"no enough space\");\n\t}\n\t//...\n}\n```\n\n这里有两个判断条件\n\n- 剩余存储空间满足\n- 是内置bundle\n\n当两个条件都满足时，执行bundle的安装和optDexFile操作。\n\ninstallBundleFromApk 又调用了 installNewBundle方法，直接看第9步 - installNewBundle 的实现。\n\n## installNewBundle\n\nFramework.java\n\n```\nstatic BundleImpl installNewBundle(final String location, final InputStream in)throws BundleException {\n\t//...\n\tBundleListing.BundleInfo info = AtlasBundleInfoManager.instance().getBundleInfo(location);\n\tBundleImpl bundle = new BundleImpl(bundleDir, location, new BundleContext(), null, file,version,true,-1);\n\treturn bundle;\n}\n```\n\n函数很简单，获取bundle的信息，之后构造一个BundleImpl对象。\n\n有两个参数需要注意一下\n\n|参数|说明|\n|---|---|\n| bundleDir |/data/data/com.taobao.demo/files/storage/com.taobao.secondbundle|\n|in|指向 lib/armeabi/libcom_taobao_secondbundle.so|\n\n## BundleImpl\n\n来看BundleImpl的构造函数\n\nBundleImpl.java\n\n```\nBundleImpl(final File bundleDir, final String location, final BundleContext context, final InputStream stream,...) throws BundleException, IOException{\n\t\tif (stream != null) {\n            this.archive = new BundleArchive(location,bundleDir, stream,version, dexPatchVersion);\n        } \n        \n        if (autoload) {\n            resolveBundle();\n            Framework.bundles.put(location, this);\n        }\n}\n```\n\n首先创建了一个BundleArchive对象，bundleArchive持有bundleDir和InputStream的引用，用来做dexOpt的( __? todo__ )，暂时不关注，往下走\n\n## resolveBundle\n\nBundleImpl.java\n\n```java\n\n    private synchronized void resolveBundle() throws BundleException {\n    \t//...\n    \tif ( this.classloader == null){\n\t        // create the bundle classloader\n            List<String> dependencies = AtlasBundleInfoManager.instance().getDependencyForBundle(location);\n            String nativeLibDir = getArchive().getCurrentRevision().getRevisionDir().getAbsolutePath()+\"/lib\"+\":\"\n                    + RuntimeVariables.androidApplication.getApplicationInfo().nativeLibraryDir+\":\"\n                    +System.getProperty(\"java.library.path\");\n            if(dependencies!=null) {\n                for (String str : dependencies) {\n                    BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(str);\n                    if (impl != null) {\n                        nativeLibDir += \":\";\n                        File dependencyLibDir = new File(impl.getArchive().getCurrentRevision().getRevisionDir(), \"lib\");\n                        nativeLibDir += dependencyLibDir;\n                    }\n                }\n            }\n\t        this.classloader = new BundleClassLoader(this,dependencies,nativeLibDir);\n    \t}\n      \n        // notify the listeners\n        Framework.notifyBundleListeners(0 /*LOADED*/, this);\n    }\n```\n\n为bundle创建一个classloader，在创建classloader的过程中\n\n- 指定bundle自身依赖so的路径\n- 指定依赖bundle所依赖so的路径\n\n比如在demo中 ，nativeLibDir的 值为 /data/user/0/com.taobao.demo/files/storage/com.taobao.secondbundle/version.1/lib:/data/app/com.taobao.demo-1/lib/x86:/vendor/lib:/system/lib\n\n创建完BundlerClassLoader后，在最后一行进行回调，这里的回调实现类是 BundleLifecycleHandler\n\nBundleLifecycleHandler.java\n\n```\n public void bundleChanged(final BundleEvent event){\n        switch (event.getType()) {\n            case 0:/* LOADED */\n                loaded(event.getBundle());\n}\n```\n\n## loaded\n\n```\nprivate void loaded(Bundle bundle) { long time = System.currentTimeMillis();\n        BundleImpl b = (BundleImpl) bundle;\n        DelegateResources.addBundleResources(\n        \tb.getArchive().getArchiveFile().getAbsolutePath()\n        );\n}\n```\n\n__todo__ 资源处理实现说明\n\n回到第10步\n\nBundleImpl.java\n\n```\nBundleImpl(final File bundleDir, final String location...) {\n\t//...\n\tresolveBundle();\n\tFramework.bundles.put(location, this);    \n}\n```\n\n在resolveBundle函数执行周期内，主要完成了两件事\n\n- 为bundle创建了独立的ClassLoader\n- 将bundle中的资源添加到Resource上\n\n\n第二行函数将bundle的信息加入到已加载的列表中。\n\n完成之后，回到第8步，执行optDexFile方法。\n\n### optDexFile\n\n。。。\n\n# 第三部分 初始化过程\n\n__整个第三部分运行在 UI 线程中__\n\nbundle加载完成后，第7步，在UI线程中回调了完成的接口，调用了`startbundle`方法又经过辗转调用，到了BundleLifecycleHandler的`startd`方法中。\n\nBundleLifecycleHandler.java\n\n```java\nprivate void started(Bundle bundle){\n\tBundleImpl b = (BundleImpl) bundle;\n\tBundleListing.BundleInfo info = AtlasBundleInfoManager.instance().getBundleInfo(b.getLocation());\n\t//...\n\tString appClassName = info.getApplicationName();\n\tApplication app = newApplication(appClassName, b.getClassLoader());\n\tapp.onCreate();\n}\n```\n\n在第6行构造出bundle中注册的application对象，之后执行application的onCreate方法。对于appliation来说，似乎还差一个关键的`attachBaseContext`的入口函数调用，我们接着看构造过程。\n\nBundleLifecycleHandler.java\n\n```\nprotected static Application newApplication(String applicationClassName, ClassLoader cl) throws ApplicationInitException {\n\tfinal Class<?> applicationClass = cl.loadClass(applicationClassName);\n\tApplication app = (Application) applicationClass.newInstance();\n\tAtlasHacks.Application_attach.invoke(app, RuntimeVariables.androidApplication);\n\treturn app;  \n}\n```\n\n首先，根据类名加载对应的class，之后反射执行applciation的attach方法。\n\n在[Atlas之启动过程(二)][atlas_start_2]下中，解释过，application的attach方法最终会调用到`attachBaseContext`方法。\n\n最后，大概看一下DelegateClassLoader加载bundle中class的过程。\n\nDelegateClassLoader.java\n\n```\nprotected Class<?> findClass(String className) throws ClassNotFoundException {\n\tClass<?> clazz = loadFromInstalledBundles(className,false);\n\t//...\n\treturn clazz;\n}\n\nstatic Class<?> loadFromInstalledBundles(String className,boolean safe)\n            throws ClassNotFoundException {\n\tString bundleName = AtlasBundleInfoManager.instance().getBundleForComponet(className);\n\tBundleImpl bundle = (BundleImpl) Atlas.getInstance().getBundle(bundleName);\n\t//...\n\tClassLoader classloader = bundle.getClassLoader();\n\tClass<?>  clazz = classloader.loadClass(className);\n\treturn clazz;\n}\n```\n\n可以看到，classloader先从bundle上去找的。而`loadFromInstalledBundles`逻辑如下:\n\n1. 从`AtlasBundleInfoManager`上已加载的列表中找到对应bunde(在第在第10步中添加)\n2. 从对应bundle上的classloader上加载对应的class。\n\n\n----\n\n到这里为止，整个bundle的加载、初始化过程分析完毕。\n\n[bundle_load_img]: bundle_load_img.svg\n[atlas_start_2]: ../../code_read/atlas_start/atlas_start_2.md\n[bundle_load_part_2]: bundle_load_part_2_img.svg\n"
  },
  {
    "path": "atlas-docs/code_read/atlas_bundle_load/bundle_load.uml",
    "content": "@startuml\nautonumber\n\n-> ActivityGroupDelegate : startChildActivity\nActivityGroupDelegate -> ActivityGroupDelegate : execStartChild\\nActivityInternal\nActivityGroupDelegate -> ActivityGroupDelegate : asyncStartActivity\n\nActivityGroupDelegate -> BundleUtil : checkBundleArray\\nStateAsync\n\nBundleUtil -> BundleInstaller : installTransitively\\nAsync\nBundleInstaller -> BundleInstaller : installBundleInternal\nBundleInstaller -> BundleInstaller : deliveryTask\nBundleInstaller --> BundleInstaller : call\n\nBundleInstaller --> Framework : installNewBundle\n\nFramework --> BundleImpl : new\nBundleImpl --> BundleImpl : resolveBundle \n\nBundleImpl --> BundleClassLoader : new \nBundleImpl --> BundleLifecycleHandler : loaded\nBundleLifecycleHandler --> DelegateResources : addBundleResources\n\nFramework --> BundleImpl : optDexFile\n\nBundleInstaller -> BundleImpl : startBundle\nBundleImpl -> BundleLifecycleHandler : started\nBundleLifecycleHandler -> Application : attach\nBundleLifecycleHandler -> Application : onCreate\n\n\n@enduml\n"
  },
  {
    "path": "atlas-docs/code_read/atlas_bundle_load/bundle_load_part_2.uml",
    "content": "@startuml\nautonumber 8\n\n\nBundleInstaller --> BundleInstaller : call\n\nBundleInstaller --> Framework : installNewBundle\n\nFramework --> BundleImpl : new\nBundleImpl --> BundleImpl : resolveBundle \n\nBundleImpl --> BundleClassLoader : new \nBundleImpl --> BundleLifecycleHandler : loaded\nBundleLifecycleHandler --> DelegateResources : addBundleResources\n\nFramework --> BundleImpl : optDexFile\n\n@enduml\n"
  },
  {
    "path": "atlas-docs/code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.md",
    "content": "---\ntitle: Atlas之Gradle配置\n---\n\n# 概述\n\nAtlas一个运行于Android系统上的一个容器化框架。为了实现这一目标，在编译器和运行期，Atlas都做了很多工作。本文是一个入门级别的文章，梳理从gradle配置到生成最终apk的期间，Atlas框架到底搞了哪些事情。\n\n代码以 [官方demo][atlas_demo] 为例。\n\n# gradle分析\n\ngradle部分，我们只用看主工程app和bundle的配置就可以了。\n\n\n## app\n\nbuild.gradle\n\n```gradle\n# 第一部分\nandroid {\n    //...\n}\n\n# 第二部分\natlas {\n\t//...\n}\n\n# 第三部分\ndependencies {\n    compile xxx\n    bundleCompile xxx\n}\n```\n\n可以很清楚的看到，gradle的配置主要分为三大块，依次是标准的android插件配置、atlas插件的配置，以及依赖管理部分。我们重点看最后两个部分。\n\n\n### Atlas插件配置\n\natlas插件有很多参数，这里只关注demo中出现的重点参数，其它设置大家可以查看[官方文档][atlas_gradle_doc]。\n\n```\natlas {\n    atlasEnabled true\n    tBuildConfig {\n        autoStartBundles = ['com.taobao.firstbundle'] \n        outOfApkBundles = ['remotebundle']\n        preLaunch = 'com.taobao.demo.DemoPreLaunch'\n    }\n}\n```\n__atlasEnabled__  开启atlas插件的开关，在编译期会做很多事情\n\n- merge各个bundle的manifest到app中\n- 将bunde的资源进行分段\n- 为四大组件预留一些坑位\n- 生成一些class，记录bundle的关键信息 \n- 打包bundle等等\n\n__autoStartBundles__ 指定第一个需要启动的bundle，在Atlas框架初始化完毕后，会执行这里这里配置bundle的代码。\n\n__preLaunch__ 自定义初始化入口，这个类需要实现`AtlasPreLauncher`接口，回调时机是在atlas对系统进行hack之后，atlas框架开始初始化之前。\n\n### 依赖管理配置\n\n接着看依赖配置部分\n\n```\natlas {\n    tBuildConfig {\n        outOfApkBundles = ['remotebundle']\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile('com.taobao.android:atlas_core:5.0.7@aar') {\n        transitive = true\n    }\n\n    compile project(':middlewarelibrary')\n    compile project(':splashscreen')\n    compile project(':activitygroupcompat')\n\n    bundleCompile project(':firstbundle')\n    bundleCompile project(':secondbundle')\n    bundleCompile project(':remotebundle')\n    bundleCompile project(':publicbundle')\n\n    compile 'com.android.support:appcompat-v7:25.1.0'\n}\n\n```\n`dependencies `主要分为三个部分\n\n- comile xxx \t\n- bundleCompile xxx\n- outOfApkBundles =['xxx']\n\n__compile__ : 常规的打包配置，会将依赖代码打入到dex中去\n\n__bundleCompile__ : atlas 的配置项，表示apk的bunde依赖，即apk是由这些bundle共同组成。\n> bundle中的代码不会打入dex中去，bundle将以libxxx.so文件的形式，放在apk的lib目录下，随包发布\n\n__outOfApkBundles__ : 指定远程bundle \n>比如在demo中，firstbundle、secondbundle、publicbundle 会打入apk中，而remotebundle不会\n\n### 小结\n\n__可以看到，在atlas框架中，主app只是一个壳子，只是用来配置打包参数的__\n\n比如在demo中，配置了以下打包设置\n\n- app的包名、版本号...\n- 需要打入dex的代码 (appcompat...)\n- 随包发布但是不打入dex的代码 (firstbundle、secondbundle、publicbundle)\n- 独立打包，用于后续的动态下发 (remotebundle)。\n\n盗用一张老大的图\n![][atlas_apk_gradle]\n\n## bundle\n\n以secondbundle为例，看一下bundle中gradle的配置\n\n```\napply plugin: 'com.android.library'\napply plugin: 'com.taobao.atlas'\n\natlas {\n    bundleConfig{\n        awbBundle true\n    }\n}\n\nandroid {\n\t//...\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile project(\":secondbundlelibrary\");\n    providedCompile 'com.android.support:appcompat-v7:25.1.0'\n    providedCompile 'com.android.support:support-v4:25.3.0'\n    providedCompile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8'\n    providedCompile project(':middlewarelibrary')\n}\n\n```\n首先`apply plugin: 'com.taobao.atlas'`和`awbBundle true`表明启用了atlas插件，并将当前模块编译成awb形式的bundle供主apk使用。\n\n而在 `dependencies` 中可以看到有两种形式的依赖\n\n|依赖方式|说明|\n|---|---|\n|providedCompile|主dex中已经打入了必要的公用代码(appcompat、middlewarelibrary)，在runtime时，atlas框架会自动找到主dex中的class使用，所以secondbundl就不需要在重复打入|\n|compile|secondbundlelibrary之前并没有打入主dex中，因为这只是secondbundle所需要的依赖。最终会将secondbundle和secondbundlelibrary的打在一个同一个dex中，加上两者的资源，成为一个bundle|\n\n\n# apk结构分析\n\n在看完gradle的配置之后，我们反编译demo的apk，看一下最终生成的结构。\n\n## host\n\n### manifest\n\n首先，贴一张反编译后的manifest\n\n![][atlas_manifest]\n\n可以看到，manifest中的内容大概分为三大块\n\n- host 的manifest部分\n- bunde 的的manifet部分\n- 额外的配置\n\n|manifest|说明|\n|---|---|\n|host|常规编译产生的清单数据，包括app工程自身的代码和compile依赖的代码|\n|bundle|bundle部分的清单数据，包括在app工程中bundleCompile的依赖代码和bundle自身compile的依赖代码|\n|配置|atlas插件在编译期生成的配置信息。比如在gradle中配置了 `autoStartBundles = ['com.taobao.firstbundle']`，编译时，会将firstbundle中application路径写入manifest。程序运行时，atlas会第一个执行firstbundle中DemoApplication中的代码|\n\n### 主dex\n分析完manifest之后，我们看一看host的dex文件，看一看有没有对java代码动手脚。\n\n![][atlas_dex_pkg]\n\n乍看之下，似乎并没有什么不妥。但是，细心的同学可能发现了，少了bundle部分的代码。\n\n结合app工程gradle的配置，我们发现以compile开头的依赖(middleware、utils、update),都是正常将java代码打入dex中。而以budleCompile开头的依赖(firstbundle、secondbundle)，他们的代码并没有在dex中。\n\n__那么，bundle的代码在哪里呢？__ 我们接着往下看\n\n\n## bundle\n\nbundle的存放位置\n\n![][atlas_bundle_position]\n\nbundle的代码和资源其实独立打成了一个apk，放在了apk的lib目录下，在运行时进行动态加载。\n\n### manifest\n\n__bundle中的manifest中没有任何东西，__ 感兴趣的同学可以自行验证。\n> 这部分内容在编译期已经写到app的manifest中了，这也是 __组件化和插件化__ 的区别之一\n\n### dex\n\n最后确认一下以secondbundle的代码，\n\n![][atlas_dex_secondbundle]\n\n果然，每个bundle的代码都是各自打包的。\n\n# 总结\n\natlas将一个apk分为host和bundle两大部分\n\n- host为共用代码资源和各个bundle的manifest信息\n- bundle独立打包，拥有独立的dex和资源\n- 像搭积木一样，host和不同的bundle组合编译成一个apk\n\n---\n参考\n\n- [官方文档][atlas_doc]\n- [demo][atlas_demo]\n\n[atlas_doc]: http://atlas.taobao.org/docs\n[atlas_gradle_doc]: http://atlas.taobao.org/docs/guide-for-use/guide_for_build.html\n[atlas_demo]: https://github.com/alibaba/atlas/tree/master/atlas-demo\n[atlas_dex_pkg]: http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/51bc1436339313814e40bedfb466f53f.png\n[atlas_manifest]: http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/d32dfd32381f11d4f64ce13ab772f9e4.png\n[atlas_apk_gradle]: http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/fdb39a090aa3604aa999704eec1348eb.png\n[atlas_dex_secondbundle]: http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/96fcb2aabba52a13f2e0abf6768cf1bf.png\n[atlas_bundle_position]: http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/ea15cdcaac2a617e7e1c7f76eade1edc.png\n[atlas_apk_gradle]: http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/fdb39a090aa3604aa999704eec1348eb.png\n"
  },
  {
    "path": "atlas-docs/code_read/atlas_start/atlas_core_start.uml",
    "content": "@startuml\nautoNumber\n\n-> AtlasBridgeApplication : attachBaseContext\nAtlasBridgeApplication -> BridgeApplicationDelegate : attachBaseContext\nBridgeApplicationDelegate ->AtlasHacks : defineAndVerify\nBridgeApplicationDelegate -> DemoPreLaunch : preLaunch\nBridgeApplicationDelegate -> Atlas : init\n-> AtlasBridgeApplication : onCreate\nAtlasBridgeApplication -> BridgeApplicationDelegate : onCreate\n‘BridgeApplicationDelegate -> AdditionalActivityManagerProxy : startRegisterReceivers’\nBridgeApplicationDelegate -> DemoApplication : attach\nBridgeApplicationDelegate  -> Atlas : startup\nBridgeApplicationDelegate -> DemoApplication : onCreate\n@enduml"
  },
  {
    "path": "atlas-docs/code_read/atlas_start/atlas_core_start_callback.uml",
    "content": "@startuml\n\nnode “dev” {\n   [code]-> [gradle]\t\n}\n\nnode “atlas compile” {\n   [gradle]->[FrameworkProperties]\n   [FrameworkProperties]->[dex]\n} \n\nnode “runtime”{\n   [dex]->[getFrameworkProperty]\n}\n@enduml"
  },
  {
    "path": "atlas-docs/code_read/atlas_start/atlas_core_start_provider.uml",
    "content": "@startuml\n\nautonumber\n\nActivityThread -> LoadedApk : makeApplication\nLoadedApk -> Instrumentation : Instrumentation\nInstrumentation -> Application : attach\nApplication -> Application :attachBaseContext\nActivityThread -> ActivityThread : installContentProviders\nActivityThread -> Instrumentation : callApplicationOnCreate\nInstrumentation -> Application : onCreate\n\n@enduml"
  },
  {
    "path": "atlas-docs/code_read/atlas_start/atlas_java_startup.uml",
    "content": "@startuml\nautonumber\n\n-> Atlas : startup\nAtlas -> DexLoadBooster : init\nDexLoadBooster -> AndroidRuntime : init\nDexLoadBooster -> DalvikPatch : patchIfPossible\nAtlas -> Framework : startup\nFramework -> AtlasBundleInfoManager : getBundleInfo\nAtlasBundleInfoManager -> AtlasBundleInfoManager : InitBundleInfo\\nByVersionIfNeed\n\nFramework-> Framework : startup\nFramework -> FrameworkLifecycleHandler : started\n\nFrameworkLifecycleHandler -> BundleInstalller : installBundleInternal\nFrameworkLifecycleHandler --> BundleImpl : start\n\n@enduml"
  },
  {
    "path": "atlas-docs/code_read/atlas_start/atlas_start_1.md",
    "content": "---\ntitle: Atlas之启动过程(一)\ndate: 2017-05-02 15:00:00\n---\n\n# 概述\n\nAtlas整个启动过程的时序如下图所示，本篇只关注下图中的1-5步。\n\n![][atlas_core_start_img]\n\n# 入口\n\n我们都知道，app的入口是application，那么atlas的入口application是什么呢，看一下app模块中manifest中的定义\n\n![][atlas_application_demo]\n\n看样子，是DemoApplication<br>\n真的是这样的吗？<br>\n__当然不是__\n\n我们看一下反编译后的manifest\n\n![][atlas_manifest_application]\n\n为什么会是AtlasBridgeApplication呢，manifest中明明写的很清楚 : DemoApplication。<br>\n事实上为了接入的方便，Atlas在编译期就替换了入口application。不过，Atlas保证在运行期时会调用DemoApplication的相关方法。\n\n# 1. AtlasBridgeApplication.attachBaseContext\n\n我们看一下AtlasBridgeApplication中的相关方法\n\n```java\n@Override\nprotected void attachBaseContext(Context base) {\n\tsuper.attachBaseContext(base);\n\t//...一些逻辑\n\t\n\t//1. 构造BridgeApplicationDelegate对象\n\tClass BridgeApplicationDelegateClazz = getBaseContext().getClassLoader().loadClass(\"android.taobao.atlas.bridge.BridgeApplicationDelegate\");\n\tConstructor<?> con = BridgeApplicationDelegateClazz.getConstructor(parTypes);\n\tmBridgeApplicationDelegate = con.newInstance(this,getProcessName(...);\n\t\n\t//2. 执行BridgeApplicationDelegate的attachBaseContext方法\n\tMethod method = BridgeApplicationDelegateClazz.getDeclaredMethod(\"attachBaseContext\");\n\tmethod.invoke(mBridgeApplicationDelegate);\n}\n```\n可以看到，代码虽长，但其实就只干了两件事。\n\n- 反射并构造BridgeApplicationDelegate的实例\n- 执行BridgeApplicationDelegate的attachBaseContext方法。\n\n先看BridgeApplicationDelegate的构造方法。\n\n```java\n//BridgeApplicationDelegate.java\npublic BridgeApplicationDelegate(Application rawApplication...){\n\tmRawApplication = rawApplication;\n\tPackageManagerDelegate.delegatepackageManager(\n\t\trawApplication.getBaseContext()\n\t);\n}\n```\n\n没什么内容，直接跟进`delegatepackageManager`的函数实现\n\n```java\n//PackageManagerDelegate.java\npublic static void delegatepackageManager(Context context){\n      mBaseContext = context;\n      //1. 反射pm\n      PackageManager manager = mBaseContext.getPackageManager();\n      Class ApplicationPackageManager = Class.forName(\"android.app.ApplicationPackageManager\");\n      Field field = ApplicationPackageManager.getDeclaredField(\"mPM\");\n      field.setAccessible(true);\n      Object rawPm = field.get(manager);\n      //2. 动态代理pm\n      Class IPackageManagerClass = Class.forName(\"android.content.pm.IPackageManager\");\n      mPackageManagerProxyhandler = new PackageManagerProxyhandler(rawPm);            \n      mProxyPm = Proxy.newProxyInstance(mBaseContext.getClassLoader(), new Class[]{IPackageManagerClass}, mPackageManagerProxyhandler);\n      //3. 替换pm\n      field.set(manager, mProxyPm);\n}\n```\n可以看到，这段代码的核心思想就是将系统的pm，替换为我们实现的PackageManagerProxyhandler。我们先不关注PackageManagerProxyhandler的实现，接着看`BridgeApplicationDelegate`中函数attachBaseContext的实现。\n\n# 2. BridgeApplicationDelegate. attachBaseContext\n\nBridgeApplicationDelegate.java\n\n```java\npublic void attachBaseContext(){\n\t//2.1 hook之前准备工作\n\tAtlasHacks.defineAndVerify();\n\n\t//2.2 回调预留接口\n   launcher.initBeforeAtlas(mRawApplication.getBaseContext());\n                \n   //2.3 初始化atlas     \n   Atlas.getInstance().init(mRawApplication, mIsUpdated);\n     \n   //2.4 处理provider    \n\tAtlasHacks.ActivityThread$AppBindData_providers.set(mBoundApplication,null);\n}\n```\n\n函数实现大概分为四个部分，也是本篇文章的重点关注部分\n\n- hook之前的准备工作\n- 回调预留接口\n- 初始化atlas\n- 处理provider\n\n我们也一个来看。\n\n#3. AtlasHacks.defineAndVerify\n\n在开始分析之前，我们要知道，Android上动态加载方案，始终都绕不过三个关键的点:\n\n- __动态加载class__ \n- __动态加载资源__ \n- __处理四大组件__ 能够让动态代码中的四大组件在Android上正常跑起来\n\t\n为了实现这三个目标，会在系统关键调用的地方进行Hook。比如，为了能够动态加载class，通常都会对classloader上动一些手脚，resource也是类似。\n\n这里多提一句，在四大组件的处理上，atals与插件化有着很大的差异。\n\n- 插件化的核心思想其实是埋坑机制+借尸还魂 ：通过预先在manifest中预留N个组件坑，在runtime时，通过“借尸还魂”实现四大组件的运行。\n- atlas不一样，它是在编译期就已经各个bundle的manifest写入到apk中。所以运行时，bundle中的组件可以和常规声明的组件一样正常运行，不用再做额外的处理。\n\n回过头来，我们看看atlas为了实现上述目的，做了哪些准备工作。在跟进`defineAndVerify`函数的实现之前，先看一下AtlasHacks类中定义的字段\n\n```\n//AtlasHacks.java\n\n \t// Classes\n    public static HackedClass<Object>                           LoadedApk;\n    public static HackedClass<Object>                           ActivityThread;\n    public static HackedClass<android.content.res.Resources>    Resources;\n    \n    // Fields\n    public static HackedField<Object, Instrumentation>          ActivityThread_mInstrumentation;\n    public static HackedField<Object, Application>              LoadedApk_mApplication;\n    public static HackedField<Object, Resources>                LoadedApk_mResources;\n    \n    // Methods\n    public static HackedMethod                                  ActivityThread_currentActivityThread;\n    public static HackedMethod                                  AssetManager_addAssetPath;\n    public static HackedMethod                                  Application_attach;\n    public static HackedField<Object, ClassLoader>              LoadedApk_mClassLoader;\n    \n    // Constructor\n    public static Hack.HackedConstructor                        PackageParser_constructor;\n```\n\n给这段代码点个赞，非常的干净和清晰。代码定义了atlas框架所需要hook的所有的类、方法、属性等等字段。\n\n- 处理资源，hook Resources\n- 处理class，hook LoadedApk_mClassLoader\n- ...\n\n现在，在看`defineAndVerify`函数的实现\n\n```\n//AtlasHacks.java\npublic static boolean defineAndVerify() throws AssertionArrayException {\n     allClasses();\n     allConstructors();\n     allFields();\n     allMethods();\n}\n```\n\n实际上这四个级别的函数调用，对应之前定义的字段，为这些字段进行赋值。\n\n```java\n//AtlasHacks.java\npublic static void allClasses() throws HackAssertionException {\n\tLoadedApk = Hack.into(\"android.app.LoadedApk\");\n\tActivityThread = Hack.into(\"android.app.ActivityThread\");\n\tResources = Hack.into(Resources.class);\n\tActivityManager = Hack.into(\"android.app.ActivityManager\");\n\t//...\n}\n\npublic static void allFields() throws HackAssertionException {\n\tActivityThread_mInstrumentation = ActivityThread.field(\"mInstrumentation\").ofType(Instrumentation.class);\n\tActivityThread_mAllApplications = ActivityThread.field(\"mAllApplications\").ofGenericType(ArrayList.class);\n}\n\n//...\n```\n\n这几个函数的代码并不复杂，是对定义的Class、Field、Method和Contructor 这些字段进行初始化赋值工作。\n\n执行到这里时，atlas框架的准备工作完成，接下来，就是整个框架的初始化了。\n\n\n#4 回调预留接口\n\n时序图中的第4步，即`BridgeApplicationDelegate`的`attachBaseContext`方法中，，做了一个接口回调。\n\nBridgeApplicationDelegate.java\n\n```java\npublic void attachBaseContext(){\n   String preLaunchStr = (String) RuntimeVariables.getFrameworkProperty(\"preLaunch\");\n   AtlasPreLauncher launcher = (AtlasPreLauncher) Class.forName(preLaunchStr).newInstance();\n   launcher.initBeforeAtlas(mRawApplication.getBaseContext());\n   //...\n}\n```\n\n函数通过“preLaunch”字段读取一个类名，反射该类上的`initBeforeAtlas`方法。<br>\n`AtlasPreLauncher`实际上是一个接口，供接入者使用。在这个点，atlas还没有开始对系统进行hook，仍然是Android原生态的运行时环境。\n\n那么这个preLaunch的字段在哪里定义的呢，我们反推一下。\n\nRuntimeVariables.java\n\n```java\npublic static Object getFrameworkProperty(String fieldName){\n\t//...\n\tField field = FrameworkPropertiesClazz.getDeclaredField(fieldName);\n\treturn field.get(FrameworkPropertiesClazz);\n}\n```\n实现很简单，读取`FrameworkProperties`上的静态属性字段，接着跟进。\n\n\n\n```java\npublic class FrameworkProperties {\n}\n```\n\n什么情况，怎么什么都没有? 所谓反常即为💊，直接看反编译后的代码\n\nFrameworkProperties.java\n\n```java\npublic class FrameworkProperties{\n  //...\n  public static String autoStartBundles;\n  public static String preLaunch;\n  \n  static{\n    autoStartBundles = \"com.taobao.firstbundle\";\n    preLaunch = \"com.taobao.demo.DemoPreLaunch\";\n  }\n}\n```\n\n从反编译后的代码可以看到，\"prelaunch\"对应的内容是`com.taobao.demo.DemoPreLaunch`,那么这个值是在 __什么时候写入又是在哪里配置__ 的呢？\n\n大家回想一下，在之前[Atlas之Gradle配置][atlas_gradle_apk]中提到过，atlas的gradle插件在编译期搞了很多事情，我们看gradle中的设置\n\n```gradle\natlas{\n\t tBuildConfig {\n        autoStartBundles = ['com.taobao.firstbundle']\n        preLaunch = 'com.taobao.demo.DemoPreLaunch'\n    }\n}\n```\n\n和`FrameworkProperties`中的字段完美对应。\n\n这个部分牵涉开发-编译-运行三个阶段，放一张图捋一下关系。\n\n![][atlas_framework_property]\n\n#5 atlas.init\n\n准备工作做好之后，就是初始化了。\n\nAtlas.java\n\n```\npublic void init(Application application,boolean reset) {\n\t//读取配置项\n\tApplicationInfo appInfo = mRawApplication.get...;\n\tmRealApplicationName = appInfo.metaData.getString(\"REAL_APPLICATION\");\n\tboolean multidexEnable = appInfo.metaData.getBoolean(\"multidex_enable\");\n\t\n\tif(multidexEnable){\n      MultiDex.install(mRawApplication);\n   }\n\t//...   \n}\n```\n\n首先是读取manifest中的配置数据`multidexEnable`和`mRealApplicationName`，这两个数据也是在编译期由atlas插件写到manifest中的。\n\n![][atlas_meta_data]\n\nmultidexEnable 是true，这个在gradle中可配<br>\nmRealApplicationName 实际上是DemoApplication,即app工程在manifest中指定的启动路径。\n\n捋清楚这几个参数之后，往下看Atlas框架初始化实现\n\nAtlas.java\n\n```\npublic void init(Application application,boolean reset) {\n   //...\n   Atlas.getInstance().init(mRawApplication, mIsUpdated);\n}\n\npublic void init(Application application,boolean reset) throws AssertionArrayException, Exception {\n     //...\n        \n     //1. 换classloader \n     AndroidHack.injectClassLoader(packageName, newClassLoader);\n     //2. 换Instrumentatio\n     AndroidHack.injectInstrumentationHook(new InstrumentationHook(AndroidHack.getInstrumentation(), application.getBaseContext()));\n     //3. hook ams\n     try {\n         ActivityManagerDelegate activityManagerProxy = new ActivityManagerDelegate();\n         Object gDefault = null;\n         if(Build.VERSION.SDK_INT>25 || (Build.VERSION.SDK_INT==25&&Build.VERSION.PREVIEW_SDK_INT>0)){\n             gDefault=AtlasHacks.ActivityManager_IActivityManagerSingleton.get(AtlasHacks.ActivityManager.getmClass());\n         }else{\n               gDefault=AtlasHacks.ActivityManagerNative_gDefault.get(AtlasHacks.ActivityManagerNative.getmClass());\n         }\n         AtlasHacks.Singleton_mInstance.hijack(gDefault, activityManagerProxy);\n      }catch(Throwable e){}\n      //4. hook H\n      AndroidHack.hackH();\n}\n```\n\n这段代码，就是对系统关键节点进行了hook，具体的hook实现这里就不贴出了，如果感兴趣，可以参考[demo源码][demo_github]以及[田维术的blog][tianweishu_note]，如何hook，以及为什么在这里hook，在文章中都讲的非常清楚。\n\n函数中的hook点\n\n|hook点|实例|\n|---|---|\n|ActivityThread.mLoadedApk.mClassLoader|DelegateClassLoader|\n|ActivityThread.mInstrumentation|InstrumentationHook|\n|ActivityManagerNative.gDefault.get|ActivityManagerDelegate|\n|android.app.ActivityThread\\$H.mCallback|ActivityThreadHook|\n\n\n# 6. 处理provider\n\n在第2步的2.4部分，对provider进行了处理\n\nBridgeApplicationDelegate.java\n\n```java\npublic void attachBaseContext(){\n\t//...\n     \n   //2.4 处理provider\n   Object mBoundApplication = AtlasHacks.ActivityThread_mBoundApplication.get(activityThread);\n   mBoundApplication_provider = AtlasHacks.ActivityThread$AppBindData_providers.get(mBoundApplication);\n   if(mBoundApplication_provider!=null && mBoundApplication_provider.size()>0){\n   \t\tAtlasHacks.ActivityThread$AppBindData_providers.set(mBoundApplication,null);\n\t}\n}\n```\n\n第4行代码读取provider数据，如果有provider信息的话，则在第6行从系统删除，让系统认为apk并没有申请任何provider。\n\n为什么这么做?回顾一下app启动的流程\n\n![](atlas_core_start_provider_img.svg)\n\n可以看到，在第4步和第7步两个关键调用之间，第5步调用了函数`installContentProviders`,跟进去看一下。\n\n```\nprivate void installContentProviders(Context context, List<ProviderInfo> providers) {\n    for (ProviderInfo cpi : providers) {\n    \tinstallProvider(context, null, cpi,...);\n    }\n}\n```\n收集了所有provider的信息，然后调用installProvider函数\n\n```\nprivate IActivityManager.ContentProviderHolder installProvider(Context context,IActivityManager.ContentProviderHolder holder, ProviderInfo info,...) {\n\tfinal java.lang.ClassLoader cl = c.getClassLoader();\n   localProvider = (ContentProvider)cl.loadClass(info.name).newInstance();\n   //...\n}\n```\n可以看到，函数是根据在manifest中登记的provider信息，实例化对象。<br>\n__那么问题来了__，有些provider是存在于bundle中的，主dex中并不存在。如果不处理，在这里程序会因为`ClassNotFind`崩溃。所以这里要先清除掉provier的信息，延迟加载。\n\n---\n\n上篇先到这里，各位先喝口水，再来下篇的分析。\n\n[tianweishu_note]: http://weishu.me/\n[atlas_gradle_apk]: ../../code_read/atlas_gradle_apk/atlas_atlas_gradle_apk.md\n[demo_github]: https://github.com/alibaba/atlas\n[atlas_framework_property]: atlas_framework_property.svg\n[atlas_meta_data]: atlas_meta_data.png\n[atlas_manifest_application]: atlas_manifest_application.png\n[atlas_application_demo]: atlas_application_demo.png\n[atlas_core_start_img]: atlas_core_start_img.svg"
  },
  {
    "path": "atlas-docs/code_read/atlas_start/atlas_start_2.md",
    "content": "---\ntitle: Atlas之启动过程(二)\ndate: 2017-05-03 15:00:00\n---\n\n# 概述\n\n接上篇 [Atlasz之启动过程(一)][atlas_start_1] ,继续 6-10 步的启动过程。\n\n![][atlas_core_start_img]\n\n# 6. onCreate\n\nAtlasBridgeApplication.java\n\n```java\n@Override\npublic void onCreate() {\n\tsuper.onCreate();\n\tMethod method = mBridgeApplicationDelegate.getClass().getDeclaredMethod(\"onCreate\");\n\tmethod.invoke(mBridgeApplicationDelegate);       \n}\n```\n\n直接反射调用`mBridgeApplicationDelegate`的`onCreate`方法.\n\n# 7. BridgeApplicationDelegate.onCreate\n\nBridgeApplicationDelegate.java\n\n```\npublic void onCreate(){\n   // 7.1 实例application\n\tmRealApplication = (Application) mRawApplication.getBaseContext()\n\t\t.getClassLoader().loadClass(mRealApplicationName).newInstance();\n    \n    //7.2 replace xxx\n    AtlasHacks.ContextImpl_setOuterContext.invoke(\n    \tmRawApplication.getBaseContext(), mRealApplication);\n    //...\n    \n    //7.3 mRealApplication.attach\n    AtlasHacks.Application_attach\n   \t\t.invoke(mRealApplication,mRawApplication.getBaseContext());\n   \n    //7.4 install content providers\n    Object mBoundApplication = AtlasHacks.ActivityThread_mBoundApplication.get(activityThread);\n    AtlasHacks.ActivityThread$AppBindData_providers.set(mBoundApplication,mBoundApplication_provider);\n    AtlasHacks.ActivityThread_installContentProviders.invoke(activityThread,mRealApplication,mBoundApplication_provider);\n    \n    //7.5. startup\n    Atlas.getInstance().startup(mRealApplication,mIsUpdated);\n    \n    //7.6 onCreate\n    mRealApplication.onCreate();\n}\n```\n\n函数有点长，不过内容大概分为6块\n\n1. 实例化app工程中指定的mRealApplication\n2. 替换application\n3. 反射执行mRealApplication的attach方法\n4. 加载provider\n5. Atlas.startup\n6. 调用mRealApplication.onCreate方法\n\n\n##7.1 实例application\n\n```java\nmRealApplication = (Application) mRawApplication.getBaseContext()\n\t\t.getClassLoader().loadClass(mRealApplicationName).newInstance();\n```\n`mRealApplicationName`实际上是指`com.taobao.demo.DemoApplication`。在这里，构造出了app工程中指定application的对象实例。\n\n##7.2 替换application\n\n```java\n//replace baseContext.mOuterContext\nAtlasHacks.ContextImpl_setOuterContext.invoke(mRawApplication.getBaseContext(), mRealApplication);\n\n//replace baseContext.mPackageInfo.mApplication\nObject mPackageInfo = AtlasHacks.ContextImpl_mPackageInfo.get(mRawApplication.getBaseContext());\n\n//...\n\n```\n7.2部分，为了保证DemoApplication能够像正常声明的application一样正常工作，做了大量的hook。这里不关注具体hook实现，只给出hook后的映射，感兴趣的童鞋可以自行研究。\n\n|替换点|实现类|\n|---|---|\n|ContextImpl.mOuterContextt|DemoApplication|\n|ContextImp.mPackageInfo|DemoApplication|\n|ActivityThread.mInitialApplication| DemoApplication |\n|ActivityThread.mAllApplications| DemoApplication|\n\n##7.3 Application.attach\n\n```java\nAtlasHacks.Application_attach.invoke(mRealApplication,mRawApplication.getBaseContext());\n```\n\nmRealApplication实际上就是DemoApplication,反射执行application的attach方法,即第8步。\n\n##7.4 加载provider\n\n```java\nObject mBoundApplication = AtlasHacks.ActivityThread_mBoundApplication.get(activityThread);\n\nAtlasHacks.ActivityThread$AppBindData_providers.set(mBoundApplication,mBoundApplication_provider);\n\nAtlasHacks.ActivityThread_installContentProviders.invoke(activityThread,mRealApplication,mBoundApplication_provider);\n\n```\n\n在[Atlas启动过程(上)][atlas_start_1]的2.4小节中，为了防止在主dex中找不到bundle中的class,不得已延迟了对provider的加载。而在第5步中，atlas完成了对classloader等关键地方的hook。由于DelegateClassLoader的存在，此时进行加载provider，是不会出现问题的。\n\n\n#8. DemoApplication.attach\n\nDemoApplication.java\n\n```java\nfinal void attach(Context context) {\n\tattachBaseContext(context);\n\tmLoadedApk = ContextImpl.getImpl(context).mPackageInfo;\n}\n```\n由7.3可知，mRealApplication实际上就是`DemoApplication`\n\n- 调用DemoApplication的attachBaseContext方法\n- 为DemoApplication创建一个LoadedApk对象\n\n#9. startUp\n\n![][atlas_java_startup_img]\n\n在startup整个函数周期内，做的事情非常之多，重要的是第3、4、6、7和8步。\n\n##9.3 \n\n```\npublic void init(Context context, boolean hookedJavaVM) {\n\tif(VMUtil.IS_VM_ART) {\n\t\tsuccess = Boolean.valueOf(ARTUtils.init(context, hookedJavaVM));\n\t} else {\n       success = Boolean.valueOf(DalvikUtils.init());\n   }\n}\n```\n\n看函数名，是针对art和dalvik工具类进行初始化。 \n\n```\n//DalvikUtils.java\npublic static boolean init() {\n\tSystem.loadLibrary(\"dalvikhack\");\n\tnativeInit();\n}\n    \n//ARTUtils.java\npublic static boolean init(Context context, boolean hookedJavaVM) {\n\tSystem.loadLibrary(\"dexinterpret\");\n\tnativeInit(...);\n}\n```\n\n## 9.4 \n\n```\npublic static int patchIfPossible() {\n\tSystem.loadLibrary(\"dalvikpatch\");\n\tif(isDalvik()) {\n   \t\tint ingored = adjustLinearAlloc();\n    }\n    return 0;\n}\n```\n首先加载`dalvikpatch`so,用途： __todo__ <br>\n接着执行 `adjustLinearAlloc`方法 ，用途 __todo__\n\n\n## 9.7 \n\n```\nprivate synchronized void InitBundleInfoByVersionIfNeed(){\n\tString bundleInfoStr = (String)RuntimeVariables.getFrameworkProperty(\"bundleInfo\");\n\tif(!TextUtils.isEmpty(bundleInfoStr)) {\n\t\tLinkedHashMap<String,BundleListing.BundleInfo> infos = BundleListingUtil.parseArray(bundleInfoStr);\n\t\tBundleListing listing = new BundleListing();\n\t\tlisting.setBundles(infos);\n\t\tmCurrentBundleListing = listing;\n    }\n}\n```\n\n可以看到，函数是从`RuntimeVariables`读取字符串，之后解析成对象存储。很明显，这个字符串应该是配置之类的信息。在[atals从gradle到apk][atlas_gradle_apk]中，我们提到过，atlas会在编译期间会分析bundle和gradle配置，将一些配置写入RuntimeVariables中。\n\n```\npackage android.taobao.atlas.framework;\n\npublic class FrameworkProperties\n{\n  public static String autoStartBundles;\n  public static String bundleInfo = \"[{\\\"activities\\\":[\\\"com.taobao.firstbundle.FirstBundleActivity\\\"],\\\"contentProviders\\\":[],\\\"dependency\\\":[],\\\"isInternal\\\":true,\\\"pkgName\\\":\\\"com.taobao.firstbundle\\\",\\\"receivers\\\":[],\\\"services\\\":[\\\"com.taobao.firstbundle.FirstBundleService\\\"],\\\"version\\\":\\\"1.0.0@unspecified\\\"},{\\\"activities\\\":[\\\"com.taobao.secondbundle.SecondBundleActivity\\\",\\\"com.taobao.secondbundlelibrary.SecondbundleShareActivity\\\"],\\\"contentProviders\\\":[],\\\"dependency\\\":[],\\\"isInternal\\\":true,\\\"pkgName\\\":\\\"com.taobao.secondbundle\\\",\\\"receivers\\\":[],\\\"services\\\":[],\\\"version\\\":\\\"1.0.0@unspecified\\\"},{\\\"activities\\\":[\\\"com.taobao.remotebunle.RemoteBundleActivity\\\"],\\\"contentProviders\\\":[],\\\"dependency\\\":[],\\\"isInternal\\\":false,\\\"pkgName\\\":\\\"com.taobao.remotebunle\\\",\\\"receivers\\\":[],\\\"services\\\":[],\\\"version\\\":\\\"1.0.0@unspecified\\\"},{\\\"activities\\\":[],\\\"contentProviders\\\":[],\\\"dependency\\\":[],\\\"isInternal\\\":true,\\\"pkgName\\\":\\\"com.taobao.publicBundle\\\",\\\"receivers\\\":[],\\\"services\\\":[],\\\"version\\\":\\\"1.0.0@unspecified\\\"}]\";\n \n  static\n  {\n    autoStartBundles = \"com.taobao.firstbundle\";\n  }\n}\n\n```\n可以看到，`bundleInfo` 字段是一堆json字段，解析后格式BundleInfo,保存着bundle的信息。\n\n```\npublic static class BundleInfo{\n\tprivate String pkgName;\n\tprivate String applicationName；\n\tprivate List<String> dependency;\n\tprivate HashMap<String,Boolean> activities;\n\tprivate HashMap<String,Boolean> services;\n\tprivate HashMap<String,Boolean> receivers;\n\tprivate HashMap<String,Boolean> contentProviders;\n\t//...\n}\n```\n\n也就是说，在这一步， __atlas获得了所有bundle的信息__ 。\n\n## 9.8\n\n```\nprivate void started(){\n\t//读取配置\n\tString autoStartBundle = (String) RuntimeVariables.getFrameworkProperty(\"autoStartBundles\");\n\tString[] bundles = autoStartBundle.split(\",\");\n\t\n\t//异步安装bundle\n\tfor (int x = 0; x < bundles.length; x++) {\n\t\tfinal String bundleName = bundles[x];\n\t\tBundleInstaller.startDelayInstall(bundleName, ...);\n\t}                        \n}\n```\n简化了大部分代码，只关注核心逻辑。代码读取`RuntimeVariables`上的字段`autoStartBundles`,这个值是在gradle中配置的`com.taobao.firstbundle`，然后开始异步加载firstbundle\n\nbundle的加载过程和加载触发时机请参考 [Atlas之bundle加载过程][atals_bundle_load]，这里不在讨论。\n\n# 10. DemoApplication.onCreate\n\nDemoApplication.java\n\n```java\npublic void onCreate() {\n\tsuper.onCreate();\n\t//...\n}\n```\n\n执行app工程定义的DemoApplication的onCreate方法。\n\n---\n\n至此，Atlas启动过程的分析完成。\n\n[atlas_start_1]: atlas_start_1.md\n[atlas_gradle_apk]: atlas_gradle_apk.md\n[atals_bundle_load]: ../../code_read/atlas_bundle_load/atlas_bundle_load.md\n\n[atlas_core_start_img]: atlas_core_start_img.svg\n[atlas_java_startup_img]: atlas_java_startup_img.svg"
  },
  {
    "path": "atlas-docs/faq/dynamic_failed_help.md",
    "content": "title: 动态部署排查经验\ndate: 2014-12-22 12:39:04\n\n\n\n# 概述\n\n经常有同学在答疑群上提出疑问`为什么动态部署不生效？`，然后就是一通排查。由于是远程交流，代价实在是太高。这篇文章主要是和大家分享一下动态部署排查的一些经验，希望能够帮助大家快速定位、解决问题。\n\n另外，根据历史经验，大部分都是使用不规范造成的，为了避免这些奇奇怪怪的问题，大家最好按照[Atlas工程结构指南][atlas_use_guid]以及[容器接入][guide_for_build] 这两篇文章提到的规范，来组织工程结构。\n\n\n# 快速排查三连\n\n\n从demo中一个例子开始，假设我们发了1.0.0的Ap,之后修改了splashscreen和firstbundle两个地方的代码,__并且修改了对应的版本号__\n\n||基线版本|新版本|\n|:---|:---|:---|\n|整包(apk)|1.0.0|1.0.1|\n|splashscreen（maindex）|1.0.0|1.0.1|\n|firstbundle（bundle）|1.0.1|1.0.2|\n\n\n## 1. 打包产物检查\n\n首先检查打包的产物，按照历史经验，90%的问题都是因为打包产物不对造成的。\n\n\n### 第一点，依赖变动\n\n打开产物中的`dependencyDiff.json`的文件，这个文件记录了本次改动相对`AP`的依赖变化信息\n\n```\n{\n\t\"awbDiffs\":[\"com.atlas.demo:firstbundle\"],\n\t\"mainDexDiffs\":[\"com.atlas.demo:splashscreen(1.0.0@aar=>1.0.1@aar)\"],\n\t\"modifyLines\":[\n\t\t\"com.atlas.demo:firstbundle(1.0.1=>1.0.2)\"\n\t],\n\t\"newAwbs\":[]\n}\n```\n\n可以看到，firstbundle 和 splashscreen 的版本变化和改动一致，没有问题。\n\n如果对不上，说明打包产物错误，下面是两个常见的原因，需要同学们自己做一下排查。\n\n|根本原因|可能的错误操作|\n|:---|:---|\n|修改引入了其它隐含的改动|在发布lib/bundle版本时，带动了其它lib／bundle的版本变化|\n|AP不对,mvn仓库中的AP，和预期的不是同一个|1.重新publish了AP,老AP被覆盖了<br>2.gradle在本地仓库做了一份cache，是否和远程仓库中的一致|\n\n\n\n\n\n### 第二点，验证配置文件\n\n打开`update-1.0.0.json`\n\n```\n{\n\t//基线版本\n\t\"baseVersion\":\"1.0.0\",\n\t\"updateBundles\":[\n\t\t{\n\t\t\t\"dependency\":[\n\t\t\t\t\"com.taobao.publicBundle\"\n\t\t\t],\n\t\t\t\"isMainDex\":false,\n\t\t\t\"name\":\"com.taobao.firstbundle\",\n\t\t\t//基线依赖1.0.0中的唯一tag\n\t\t\t\"srcUnitTag\":\"1lxlheevwoeeg\",\n\t\t\t//动态部署版本1.0.1的tag\n\t\t\t\"unitTag\":\"1x6r8iuzs90ff\",\n\t\t\t\"version\":\"1.0.0@1.0.2\"\n\t\t},\n\t\t{\n\t\t\t\"isMainDex\":true,\n\t\t\t\"name\":\"com.taobao.maindex\",\n\t\t\t\"srcUnitTag\":\"1nf3phs9djbuj\",\n\t\t\t\"unitTag\":\"31jv86qvt1gc\",\n\t\t\t\"version\":\"1.0.0@1.0.1\"\n\t\t}\n\t],\n\t//动态部署更新版本\n\t\"updateVersion\":\"1.0.1\"\n}\n```\n\n1. 涉及改动确认，配置中的diff信息和我们的改动一致（两个部分，firstbundle和maindex）\n\n2. 涉及版本确认，`baseVersion`(1.0.0), `updateVersion`(1.0.1),分别对应打包命令的`apVersion`和`versionName`,表明是1.0.0->1.0.1的diff信息。\n3. srcUnitTag 和 unittag确认。（如果同学们没有按照规范来，这个地方很容易出错，导致动态部署失败）\n\n关于第三个，我们以firstbundle为例，详细说明。首先，看下在配置文件`update-1.0.0.json`中的值:\n\n|key|val|\n|:---|:---|\n| srcUnitTag | 1lxlheevwoeeg |\n| unitTag | 1x6r8iuzs90ff |\n\nok,我们再解压1.0.0的ap文件，打开`atlasFrameworkProperties.json`文件，关键字搜索`com.taobao.firstbundle`\n\n```\n{\n\t\"bundleInfo\":[\n\t\t{\n\t\t\t\"pkgName\":\"com.taobao.firstbundle\",\n\t\t\t\"unique_tag\":\"1lxlheevwoeeg\",\n\t\t\t\"version\":\"1.0.0@1.0.1\"\n\t\t},\n\t\t//...\n\t]\n}\n```\n\n各位，有没有灵光一闪？是的，unittag和srcunittag是有联系的，客户端用来验证patch的合法性，看图:\n\n![][img_unit_tag_list]\n\n以上是正确的使用姿势，下面是常见的一些常见的错误\n\n|错误|原因|\n|:---|:---|\n|`update-xxx.json`中bundle的srcUnittag和`AP`中的unitttag不一样|AP不对，比对的AP和预想的不是同一个|\n|在update-xxx.json文件中，某个bundle的srcUnittag和unittag一样|通常来说都是改了代码，但是没有变更依赖lib/bundle的版本号|\n\n\t\n\n### 第三点，diff代码验证\n\n解压tpatch\n\n```\n└── patch-1.0.1@1.0.0\n    ├── libcom_taobao_firstbundle\n    │   └── classes.dex\n    └── libcom_taobao_maindex.so\n```\n\n反编译Dex，查看patch出来的代码和修改的是否一致。\n\n\n比如修改了firstbundle 中的`first.java`和splashscreen中的`maindex.java`,diff出来的产物就一定如上图所示:\n\n- libcom\\_taobao\\_firstbundle，反编译classes.dex，有且只有`first.class`这个diff\n- libcom\\_taobao\\_maindex.so，解压反编译classes.dex，有且只有`maindex.class`这个diff\n- 改了几个类这里就会对应diff出几个，__不会多也不会少__。\n\n\n如果有异常，和第上面一样\n\n- 还是AP有问题\n- 或者本次修改隐含带入了其它改动。\n\n\n## 2. 客户端检查\n\n通常来说，如果打包产物如果没有问题，动态部署一般都是可以正常生效的。\n\n首先，__确保手机存储卡容量足够(至少100m吧)__，然后在进行下面的排查步骤。\n\n按照文档，触发patch更新操作，观察本地上两个地方\n\n```\n/data/data/\\${pkg}/files/bundleBaseline/updateinfo\n/data/data/pkg/files/storage/\\${bundle\\_pkg\\_name}/bundle.zip\n```\n\npkg为app的包名\n\n如果同时存在`updateinfo`和`updateinfo_new`两个文件,以`updateinfo_new`为准\n\nbundle\\_pkg\\_name为bundle的包名，maindex的包名为`com.taobao.maindex`\n\n### 重启前\n\n在动态部署提示重启前，执行 `cat updateInfo` 命令\n\n```\n1.0.1Ecom.taobao.maindex@31jv86qvt1gc;com.taobao.firstbundle@1x6r8iuzs90ff;\n```\n格式很简单\n\n|动态部署版本|maindex tag|firstbudnle tag|\n|:---|:---|:---|\n|1.0.1|31jv86qvt1gc|1x6r8iuzs90ff|\n\n对应前面打包产物`update-1.0.0.json`中的记录的unittag，数据没有问题。\n\n查看merge的产物是否存在，以firstbundle为例，maindex同理。\n\ncd到和`/data/data/com.taobao.demo/files/storage/com.taobao.firstbundle`\n\n```\nbullhead:/data/data/com.taobao.demo/files/storage/com.taobao.firstbundle # ls\n1x6r8iuzs90ff lock \n```\n目录名为记录的tag`1x6r8iuzs90ff`,cd 进去\n\n```\nbullhead:/data/data/com.taobao.demo/files/storage/com.taobao.firstbundle/1x6r8iuzs90ff # ls\nbundle.dex bundle.zip lock meta\n```\n可以看到产物merge成功了，反编译budnle.zip（apk），可以验证改动\n\n\n\n### 重启后\n\n还是查看这两个文件，updateinfo的内容有没有变，或者storage下merge后bundle的产物是否存在\n\n```\n/data/data/\\${pkg}/files/bundleBaseline/updateinfo\n/data/data/pkg/files/storage/\\${bundle\\_pkg\\_name}/bundle.zip\n```\n\n没有异常，说明本次动态部署生效。\n\n如果有异常，返回检查第一步的产物。\n\n\n\n\n\n\n\n[atlas_use_guid]: https://alibaba.github.io/atlas/\n[guide_for_build]: https://alibaba.github.io/atlas/guide-for-use/guide_for_build.html\n[img_unit_tag_list]: dynamic_help_img/unit_tag_list.png\n\n"
  },
  {
    "path": "atlas-docs/faq/help.md",
    "content": "# 常见问题\n**有任何的建议和问题请在github上提issue给我们，我们会尽快回复，同时高频的会更新的FAQ文档中**\n\n* **需要去除的原生multidex初始化**\n   \n   Atlas容器内部集成了multidex的dex安装功能，所以原先multidex的初始化代码可以省略，也不需要添加multidex的三方库依赖，需要使用multidex的只需要build.gradle内部将multidex置为enable即可（Atlas内部集成该内容一方面是便于和容器的兼容，另一方面后续容器会优化原生multidex在dalvik上面的性能）\n\n>\n![MacDown Screenshot](help_img/multidex.png)\n\n\n* **ClassNotFoundException**\n  \n  1. Bundle如果相互依赖，则构建起需要配置dependency，否则运行期会无法找到被依赖bundle内的class，且不支持为了查找性能，目前不支持二级依赖：比如A->B->C,如果A没有显式声明依赖C，则A bundle里面无法直接使用bundle C里面的Class，检查bundle依赖是否成功配置可以通过反编译Apk的主dex 查看**android.taobao.atlas.framework.FrameworkProperties**的field bundleInfo的内容，里面记录了所有bundle的依赖关系\n  2. 通过LayoutInflater 膨化xml，则xml里面如果有richview，则务必确保LayoutInflater持有的context的classloader可以load到该richview，假设context来自于A bundle的Activity，而xml来自于B bundle，如果A和B没有依赖关系，那么加载也肯定失败\n\n* **NoClassDefFoundError**\n  \n  造成该问题的原因比较多，排查步骤第一个先检查Exception的源头是不是ClassNotFoundException，然后反编译排查类确实是否存在；\n  \n  如果类本身存在，需要往前排查系统的警告信息，比如在Art的设备上会有class被reject的warning信息：\n    >\n![MacDown Screenshot](help_img/reject.png)\n\n   在dalvik的系统上，则会带有VFY tag的警告信息：\n       >\n![MacDown Screenshot](help_img/vfy.png)\n\n 一般来说，由于ART设备警告的信息报在dex2oat的时候，所以往往与发生crash时的Exception信息相隔比较远，所以通常遇到该类问题，dalivk的设备拿来排查可能更能发现问题的原因。另外noclassdef造成的原有接口类找不到，方法丢失，方法参数不匹配，方法属性变更，混淆等，所以具体原因需要利用上述warning信息并对照反编译的代码去排查根本的原因   \n"
  },
  {
    "path": "atlas-docs/faq/question.md",
    "content": "**Q1: 关于bundle中的application类，它什么时候被调用，其中的自定义方法怎么在bundle中调用？在bundle中调用getApplication方法，得到的是主应用的application对象，不是bundle中定义的。**\n\nA: 首先要明确一点，bundle中的application不是最终在android系统上执行的application。我们之所以保留bundle application的设计是为了尽最大可能保留大家android的开发习惯。\n\nbundle中的application类，是在bundle第一次安装的时候，atlas会调用application的onCreate()函数，可以在里面写一些自己bundle需要用到的初始化代码。注意不要bundle application里用this这种代码，因为是不生效的。\n\nbundle中的application类的自定义方法，我们建议不要这么使用。可以抽离出公共的方法，放在其他地方供调用。 目前是有这个限制。如果非得在里面调用，建议改为static方法。\n\n**Q2: 集成框架后就只有uses-permission，小米推送需要permission就提示缺少权限声明。**\n\nA: 这是因为打包插件默认开启了去除自定义权限。 可通过属性开关关闭。 属性开关是atlas.manifestOptions.removeCustomPermission = false\n\n**Q3: proguard-rules.pro直接定义在宿主app里面就可以了吗，不需要每个bundle都使用吧？**\n\nA: 在宿主app里边定义就好了\n\n**Q4: 请问 客户端拿什么属性 跟服务器比对获取补丁？**\n\nA: 每一次补丁的发布都是相当于一次版本的升级，通过版本号的变更来决策补丁的下发\n\n**Q5: bundle中的9patch图显示有问题，不能拉伸了。是需要有特殊设置么？**\n\nA: alpha11版本发布解决了。\n\n**Q6: 对于gradle 2.3.1版本是不是支持？**\n\nA: 是的，支持2.3.x\n\n**Q7: 导入demo后，Android Studio编译按钮编译失败。**\n\nA: 关闭InstantRun可以正常工作。InstantRun支持正在开发中。\n\n**Q8: Unable to delete file E:\\GitHub\\atlas\\atlas-demo\\AtlasDemo\\app\\build\\intermediates\\exploded-aar\\com.android.support\\animated-vector-drawable\\25.3.0\\jars\\classes.jar**\n\nA: 1. 杀掉java.exe进程重新编译（Windows 系统进程出现）cmd:taskkill /F /IM java.exe 2. 关闭掉as run on demand 开关\n\n**Q9. atlas 的能力问题， 及与 andfix 的关系**\n\nA: 1. atlas支持所有的代码及资源更新，暂时不支持新增4大组件，下个大版本支持 2. andfix只要用于修复java代码，不重启生效。 atlas能力更强，修复只是其中一部分能力\n\n**Q10. AS 上重新编译安装不生效的问题**\n\nA: atlas 在覆盖安装的时候，由于bundle的版本号没变化，没做清理， 下个版本会清理bundle\n\n**Q11. 动态部署不生效的问题**\n\nA: 不生效要看提示log再查，目前已知的已经修复，之前是由于windows句柄没关闭，导致tpatch中包含一些空文件，在dexmerge的时候失败了\n\n**Q12. 混淆后atlas进度条消失**\n\nA： keep 规则少了\n\n**Q13. 自启动的bundle是在哪个线程中啊，不是主线程吗？**\n\nA: 自启动bundle可以在任何线程中执行，不过bundle的application onCreate方法、Activity的onCreate方法等都是在主线程回调的\n\n**Q14. 在其他进程里运行的插件，需要在什么时候安装？可不可手动控制安装的时机？**\n\nA: 在需要的时候按需安装，例如一个Service是在单独的进程中，只要需要的时候去bind就会触发这个bundle的安装。可以手动控制安装时机，按需就好。\n\n**Q15. 组件中有jar包和so依赖，awb的产物中也有，为什么在宿主中生成的so产物解压就没有了呢？**\n\nA: 在打整包的时候需要配置过滤的参数，把so的架构类型指定清楚，要不然就会被裁减掉。具体可以参考 ： https://github.com/alibaba/atlas/issues/68\n\n**Q16. app有多个进程，在一个进程中出现了host中的一个类被pathClassloader加载了，之后在该类中调用Class.forName加载插件里的一个类，因为classloader是PathClassLoader,所以报了classnotfound,理论上host中除了atlas相关的类外所有的class都应该是被DelegateClassLoader加载吧？**\n\nA: 这种问题属于宿主中的class引用了bundle中的class，理论上是可以支持的，但是在Atlas的框架中是不推荐(也没不支持)这种反向的依赖关系。\n\n**Q17. altas是不是不建议bundle之间相互调用资源或调用宿主的资源?**\n\nA: Atlas框架建议bundle调用宿主的资源，而不建议bundle之间资源的相互调用。\n\n**Q18. 宿主和bundle的关系？**\n\nA: 宿主就相当于Android Framework，正常的Android代码中我们可以调用Framework中的接口以及使用其包含的资源，宿主对于bundle而言也是这个样子的，假如多个bundle使用同一个资源，那么这个资源可以放在宿主里边，多个bundle同时依赖这个宿主，这样避免了资源的重复。(甚至可以把宿主看成一个AAR，这个AAR的内容是打包在主dex中的)\n\n**Q19. Atlas项目中：AtlasDemo和基于版本打包的demo这两个项目有什么区别？**\n\nA: 一个是基于源码项目，一个是基于仓库版本依赖的。前期研究可以基于源码来，后续工程化实践推荐使用后者，手淘内部就是使用后者的。\n\n**Q20.  awb是什么？**\n\nA: awb是我们发明的格式，其内部结构和aar一样。 awb对应于bundle，编译最后的产物是生成到最后整包的so中。具体请参照 http://atlas.taobao.org/docs/principle-intro/Project_architectured.html"
  },
  {
    "path": "atlas-docs/faq/variant.md",
    "content": "## 如何构建不同的包\n\ngoogle插件对应的文档地址： https://developer.android.com/studio/build/build-variants.html?hl=zh-cn ， 原生是支持配置不同的buildType 以及 flavor 的， 先看一下功能对比：\n\n\n### 当前的支持度\n\n\n| 插件  | falvor  | 自定义buildType |\n|:------------- |:---------------:| -------------:|\n| google插件      | 支持 |         支持 |\n| atlasplugin 构建apk      | 支持        |       不支持 |\n| atlasplugin 构建动态部署   | 不支持        |     不支持   |\n\n\n### 为什么没有去完全适配\n\n1. Atlas是面向多人协作的较大工程的，配置不同的buildtype和flavor中也会带来创建更多的任务，并且如果执行assembleDebug 之类会构建所有的依赖变种，导致整体构建效率大大降低。\n2. 开发精力所限，因为我们的淘宝app就是没有变种的架构，额外的功能会带来很多适配的麻烦和风险\n3. 开发期我们期望我们的基线足够稳定，这样可以避免动态部署基线不兼容的问题\n\n\n### 当前插件下的实践\n\n因为build.gradle 里可以写很多的逻辑，所以配置也可以变的很灵活。 我们一般的做法就是通过打包参数来控制不同的参数值， 具体的demo可以看下下面的介绍，至于具体的其他实现，大家也可以自行扩展\n\n\n#### 大致步骤\n\n1. 在build.gradle里定义一些基础的变量，比如：\n\n\t\t//通过增加判断逻辑，打出不同类型的定制包\n\t\tdef appId = \"com.taobao.demo\"\n\t\tdef minVersion = 14\n\t\n\t\n2. 增加一层逻辑控制根据不同的参数来修改之前定义变量的值 ， 这样如果我们打包加了 -Pbeta, 就会使用新的值了\n\n\t\n\t\tif (project.hasProperty(\"beta\")) {\n\t\t\tappId = \"com.taobao.atlas.beta\"\n\t\t\tminVersion = 21\n\t\t}\n\t\n3. 或者直接在配置的地方加上判断逻辑，使用特殊的配置\n\t\n\t\n\t\tandroid {\n\t\t    defaultConfig {\n\t\t        //通过增加判断逻辑，打出不同类型的定制包\n\t\t        if (project.hasProperty(\"beta\")) {\n\t\t            buildConfigField \"boolean\", \"API_ENV\", \"false\"\n\t\t        }else{\n\t\t        \tbuildConfigField \"boolean\", \"API_ENV\", \"false\"\n\t\t        }\n\t\t    }\n\t\n4. 以上build.gradle 里的配置基本完成。 后续如果要打特殊包就可以通过修改配置的构建参数来控制打具体的包了，如：\n\n\t\t   ./gradlew clean assembleDebug :  构建标准包\n\t\t   ./gradlew clean assembleDebug -Pbeta ： 构建特殊包\n\n"
  },
  {
    "path": "atlas-docs/guide-for-use/README.md",
    "content": "#接入指引\n\n请接入前仔细阅读接入文档.\n\n接入可参考[atlas-demo](https://github.com/alibaba/atlas/tree/master/atlas-demo)\n\n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/bundleCommunicate.md",
    "content": "# Android跨ClassLoader的模块之间互相通信的几种方式\n\n## 现状\nAtlas作为java层以OSGI规范进行组件化解耦的容器。在一定层度上清晰了各个模块之间的边界，便于各个业务以内聚的方式不断的演化更新。\n\n但是在复杂的App比如手淘这种无数个业务交织的场景下，完全的隔离也给业务的开发造成了不小的成本。针对这种问题，目前主要解决的方案有：\n\n1. 参照多个App之间通信的方式，使用AIDL可以作为组件之间进行一定层度通信的方式。\n2. 使用基于容器的实现开发的ServiceHub，跟AIDL一样将接口放到公共Library，然后ServiceHub中写入接口和实现的对应关系。使用方通过ServiceHub得到接口实现进行使用。\n\n## 缺陷\nAIDL、ServiceHub解决了部分bundle之间通信或者代码复用的问题。但是这两者也存在着很大的不足。一方面AIDL限制了只能传递parcel以及简单对象，对于UI复用比如说Richview的重用则完全行不通，同时使用成本也是ServiceHub的机制的一个痛点，业务方需要提前将新的接口提前注册到ServiceHub。\n## 新的机制\n新的组件之间的重用及通信策略延续了AIDL免注册的方式，同时解决了跨classloader情况下UI复用的问题。新的方式将重用类型归为RemoteFragment、RemoteView、RemoteTransaction三种类型。\n\n### RemoteFragment\nRemoteFragment适用于某个Bundle中有公共的Fragment要提供给一个或者多个其他业务bundle使用的情况，比如说在手淘里面，SkuFragment(sku选择界面)可能会提供给详情，购物车，聚划算等多个业务使用；或者在某些App里面，登录界面也以LoginFragment的方式提供给Bundle按需使用。\n\n1. 使用方式\n 1. 代码改动：以LoginFragment为例，LoginBundle需要在自己的LoginFragment做一定的改动\n\t  \t  \n\t ```\n\t public class LoginFragment extends Fragment implements IRemote{\n\n\n\t\t    @Override\n\t\t    public Bundle call(String commandName, Bundle args, IResponse callback) {\n\t\t        return null;\n\t\t    }\n\t\t\n\t\t    @Override\n\t\t    public <T> T getRemoteInterface(Class<T> interfaceClass,Bundle args) {\n\t\t        return null;\n\t\t    }\n}\n```\n\t\n\t\tLoginFragment 需要在原来的基础上实现IRemote接口，IRemote来自Atlas容器的内部实现，暂时还未从容器中拆分出差，这也意味着业务方需要增加对atlas的依赖。**IRemote实现的两个接口会在文章后面解释**\n\n\n \n   \t2. Bundle的AndroidManifest.xml中进行注册\n   \t\n   \t\t```\n   \t\t<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    \tpackage=\"com.taobao.login\">\n\t\t\t<application>\n\t       \t\t<meta-data android:name=\"atlas.fragment.intent.action.LOGIN\"\n\t       \t\t \tandroid:value=\"com.taobao.login.LoginFragment\" />\n\t\t\t</application>\n\t\t</manifest>\n   \t\t```\n\tRemote组件参照AIDL的方式在manifest中进行注册。查找时以meta-data的name做key进行查找，RemoteFragment的key必须以**atlas.fragment.intent.action.**开头。\n\n\t3. 使用方如何调用RemoteFragment\n\t\t\n\t\t```\n\t\tpublic class SampleActivity extends FragmentActivity{\n\t\t\tpublic void doLogin(){\n\t\t        Intent loginIntent = new Intent(\"atlas.fragment.intent.action.LOGIN\");\n\t\t        RemoteFactory.requestRemote(RemoteFragment.class,loginIntent, \n\t\t        \tnew RemoteFactory.OnRemoteStateListener<RemoteFragment>() {\n\t\t            @Override\n\t\t            public void onRemotePrepared(RemoteFragment fragment) {\n\t\t                getSupportFragmentManager().beginTransaction().add(R.id.container,fragment).commit();\n\t\t            }\n\t\t\t\t\t@Override\n\t\t            public void onFailed(String errorInfo) {\n\t\t                // Redirect to h5 login or downgrade\n\t\t            }\n\t\t        });\n\t\t    }\n}\n\t\t```\n\t\t业务使用方调用Atlas的RemoteFactory的接口进行request，由于期间可能涉及到bundle的安装，所以整个过程采用callback的方式。获取到RemoteFragment的句柄后直接进行操作即可。**建议Fragment里面涉及到的交互功能等的代码封装在Fragment内部**，比如说LoginFragment里面所有按钮的点击以及异常处理全都Fragment内部进行实现。这样的话两个Bundle之间的边界也更清晰。\n> 问题：RemoteFragment 如何通知外部登录成功或者失败，除了用系统的广播等机制，能否基于Remote的机制更直接地方便地实现该功能呢？后续RemoteTransaction中会阐述具体的用法。\n\n2. 实现的机制\n\t先附一张网上摘录的Fragment启动图，不清楚的同学可以通过这个大致了解整个Fragment启动的一些方法调用，理清Fragment和Activity在启动时的一些交织的关系(图片可能需要下载放大了观看)。\n\t![](fragment-start.png)\n\tRemoteFragment本身也是真正意义上的Fragment，所以可以用来直接被FragmentManager或者FragmentTransaction直接进行管理；同时它也是真正的LoginFragment的在使用方的代理。他们之间的关系如下：\n\t\t![](fragment-relation.png)\n\t使用者应该了解RemoteFragment机制的以下几个特点，明白其内部实现的主要机制：\n\t\t\n\t* RemoteFragment的使用方拿到的仅仅是目标fragment的代理，所以真正的实现对使用方来说是不可见的。如果除了拿到Fragment展示之外还有其他的接口需要暴露给使用者，则需要走**Remote的通信机制**。\n\t* EmbeddActivity才是真正目标Fragment实例化所需要的context，EmbeddActivity是由RemoteFragment初始化时创建的Activity，用于给目标Fragment初始化UI，它是真正的Activity，但是没有界面，同时也没有有效的WindowManager，涉及到Window操作的会自动转交给SampleActivity进行处理。EmbeddActivity是bundle之间不需要依赖直接使用UI最根本的保证。\n\t\n\t  >设想一下，如果一个Activity引用了5个来自不同Bundle的RemoteFragment，那么相当于这个Activity内嵌了5个EmbeddActivity；那如果引用了5个来自同一个Bundle的RemoteFragment呢？\n\t\n\t* 目标Fragment与SampleActivity之间还是保持完整的隔离，所以目标Fragment也无法获取宿主的引用，所以如果目标Fragment需要与SampleActivity发生通信，则也要遵循**Remote的通信机制**\n\t\n\t\n### RemoteView\n与RemoteFragment 类似，RemoteView提供更细粒度的bundle间的UI复用。\n\n1. 使用方式\n\t1. 代码改动\n\t\n\t\t```\n\t\tpublic class SampleRichView extends FrameLayout implements IRemote{\n\t\t\t@Override\n\t\t    public Bundle call(String commandName, Bundle args, IResponse callback) {\n\t\t        return null;\n\t\t    }\n\t\t\t@Override\n\t\t    public <T> T getRemoteInterface(Class<T> interfaceClass,Bundle args) {\n\t\t        return null;\n\t\t    }\n}\n\t\t```\n\t2. AndroidManifest修改，RemoteView的key以**atlas.view.intent.action.**开头\n\n\t\t```\n   \t\t<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\t\t\t\tpackage=\"com.taobao.sample\">\n\t\t\t<application>\n\t       \t\t<meta-data android:name=\"atlas.fragment.intent.action.SAMPLE_RICH\"\n\t       \t\t \tandroid:value=\"com.taobao.sample.SampleRichView\" />\n\t\t\t</application>\n\t\t</manifest>\n   \t\t```\n   \t3. 使用方如何调用RemoteView\n   \t\t\n   \t\t```\n\t\tpublic class SampleActivity extends Activity{\n\t\t\tpublic void inflateRemoteView(FrameLayout container){\n\t\t        Intent sIntent = new Intent(\"atlas.view.intent.action.SAMPLE_RICH\");\n\t\t        RemoteFactory.requestRemote(RemoteView.class, sIntent, \n\t\t        \tnew RemoteFactory.OnRemoteStateListener<RemoteView>() {\n\t\t            @Override\n\t\t            public void onRemotePrepared(RemoteView remoteView) {\n\t\t                ViewGroup.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);\n\t\t                container.addView(remoteView,params);\n\t\t            }\n\t\t\t\t\t@Override\n\t\t            public void onFailed(String errorInfo) {\n\t\t                // downgrade\n\t\t            }\n\t\t        });\n\t\t    }\n}\n\t\t```\n2. 实现机制\n\n\tRemoteView与RemoteFragment实现基本一致，需要EmbeddedActivity作为真正View膨化的基本条件，RemoteView本身只是一个FrameLayout，就像DecorView，目标View作为子View添加在里面。当然这个机制也有一定的隐患，**使用方不要通过findViewByID或者getChildAt等viewGroup的public 方法尝试获取目标view并进行操作，RemoteView应该被当做View而不是ViewGroup，与目标View的通信应该通过Remote的机制进行**\n\t\n###RemoteTransact\nRemoteTransact相当于是RemoteView或者RemoteFragment的简化版，仅仅为了bundle和bundle之间的通信而存在，它和RemoteView，RemoteFragment都实现了IRemoteTransact接口。可以通过下面的草图了解大致的关系：\n![](class-relation.png)\n以RemoteTransactor为例，他和目标Transactor类都实现了IRemoteTransactor，所以当使用方调用IRemoteTransactor的接口时候，Remote对象将方法路由到目标对象的方法上。\n\n使用者可以通过这两个方法与真正的远端对象进行通信：\n\n```\npublic Bundle call(String commandName, Bundle args, IResponse callback)\n```\n* 以命令的方式通知目标对象，如果是异步返回，则远端通过传入的callback接口进行回调，如果不是，则直接返回，适用于使用方和远端存在简单通信的情况。\n\n```\npublic <T> T getRemoteInterface(Class<T> interfaceClass,Bundle args)\n```\n* 远端本身已经有封装过具体的接口，则可以实现getRemoteInterface返回具体的接口的实现。这种方式类似之前的AIDL的方式，前提是interface 类需要在两个bundle均可访问的主apk或者公共bundle中。\n\n这种使用方式适用于本身具有特定接口定义的SDK中，比如在手淘里面的windvane和weex。\n\n以windvane为例（sample里面windvane的接口只做范例，与真实的使用接口可能存在差异）：存在很多Bundle需要提供JSPlugin的场景。原生的Windvane需要提前注册JSPlugin，这种方式对bundle而言开销较大。需要bundle提前启动注册以避免后期运行时无法找到js函数对应的native方法。\n假设在Remote机制下则Windvane针对非内部的common native方法有一个ExternalJSMethodExecuter，当需要执行非内部的js方法时，则可以通过externalJSMethodExecuter.execute()查找外部的method。（这种也适用于Weex等SDK在非常规的Apk内由外部实现定制的适配器）\n\n假设bundle A有若干个native方法，需要提供给JS使用，则可以写成\n\n```\npublic class MyJSPluginManager implements IRemote{\n    @Override\n    public Bundle call(String commandName, Bundle args, IResponse callback) {\n        return null;\n    }\n\n    @Override\n    public <T> T getRemoteInterface(Class<T> interfaceClass,Bundle args) {\n        if(interfaceClass == WVApiPlugin.class){\n            if(args.getString(\"js_method\").equals(\"funA\")){\n                return new FunAPlugin();\n            }else if(args.getString(\"js_method\").equals(funB)){\n                return new FunBPlugin();\n            }else{\n                //unknow error\n            }\n        }\n        return null;\n    }\n}\n```\n同时在Manifest中增加如下配置：\n\n```\n<meta-data android:name=\"atlas.transaction.intent.action.funA\" android:value=\"com.taobao.sample.MyJSPluginManager\" />\n<meta-data android:name=\"atlas.transaction.intent.action.funB\" android:value=\"com.taobao.sample.MyJSPluginManager\" />\n```\n对于JS方法的调用方，则通过如下方法实现：\n\n```\n    public void execute(Activity activity, final String jsMethodName){\n        RemoteFactory.requestRemote(RemoteTransactor.class,activity,new Intent(jsMethodName),new RemoteFactory.OnRemoteStateListener<RemoteTransactor>() {\n            @Override\n            public void onRemotePrepared(RemoteTransactor remote) {\n                Bundle b = new Bundle();\n                b.putString(\"js_method\",jsMethodName);\n                WVApiPlugin plugin  = remote.getRemoteInterface(WVApiPlugin.class,b);\n                if(plugin!=null){\n                    //方法仅供示例，与实际情况可能存在差异\n                    plugin.execute(jsMethodName,...);\n                }\n            }\n            @Override\n            public void onFailed(String errorInfo) {\n\n            }\n        });\n    }\n```\n> 这里requestRemote里面直接传入RemoteTransactor可能对开发者来说还有点晦涩，SDK开发者也可以尝试直接对RemoteTransactor以及IRemote进行封装，比如改造成更为直观的BaseJSManager和BaseJSPlugin\n\n同样的，其他的SDK（比如weex）也可以通过类似方案在多classloader的APK内部实现自己定制的适配器，规避所有的接口实现需要预先注册的情况，同时也对整体应用的性能带来帮助。\n\n###远端如何主动调用使用方的接口\n我们也存在被使用方在某些场景下需要主动调用或者按规律定期callback宿主的情况，一种方式是使用宿主掉用远端时传进来的IResponse接口多次回调，但是如果涉及到复杂的情况就需要用到下面的方法：\n\n宿主本身对于被调用方来说也是一个远端的对象，所以宿主自己可以使用IRemote，同时将自己注册给Remote对象，RemoteFragment、RemoteView、RemoteTransactor的基类IRemoteContext实现了提供了registerHostTransactor接口，在RemoteFactory回调时将自身的IRemote实现注册进去\n\n```\n    void registerHostTransactor(IRemote transactor);\n```\n那么在远端需要使用的时候，则可以通过HostTransactor（前面图中未标出）得到宿主的IRemote的实现并传递相应的信息。\n\n```\n\tpublic static HostTransactor get(IRemote remoteItem)\n```\n\n###Remote机制的特点和不足\nRemote机制本身强烈依托于组件化拆分的方案。它的解耦层度介于AIDL和直接依赖之间。相比AIDL灵活层度更高。不过代理的方式并不能完全杜绝通过非常规方法来获取远端目标对象来进行使用，另外也可能存在某些边缘方法无非被完全代理的情况，这也需要在以后的迭代中进行优化，对于非Atlas容器化但是使用了组件化拆解方案的App，这种思路也是同样适用的。\n\n## 现在还可以选择的bundle间代码复用的方案\n对于AIDL、serviceHub以及Remote的机制，可能还存在临时无法按照规范进行解耦的情况。目前除了静态依赖外，也可以考虑使用动态依赖的方式,用来解决在具体使用到某个功能时候再去挂载相应的依赖模块，不过**bundle依赖始终打破了bundle之间的边界，需要谨慎使用**\n\n```\n    /**\n     * 设置bundle运行时依赖\n     * @param source  需要添加依赖的bundle\n     * @param dependencyBundle 被依赖的bundle的packagename\n     * @param resourceDependencyNeed 是否需要使用被依赖bundle的资源\n     * @throws BundleException\n     */\n    public void requestRuntimeDependency(ClassLoader source,String dependencyBundle,boolean resourceDependencyNeed) throws BundleException{\n```\n\n\n##其他：由于native so的相互调用导致的bundle依赖\nNative Library 在多classloader运行机制下，需要事先了解几个要点：\n\n1. 定义同一个So的依据是全路径完全相同且so内容相同\n2. 调用LoadLibrary(或者load)在native真正dlopen library之前java层会先findLibrary，如果是系统库，则在系统环境变量里面包含的路径内，如果是外部引入的，则通过ClassLoader.findLibrary进行查找，BundleClassLoader的查找逻辑是先找自身bundle安装目录下的，找不到接着找依赖bundle内的，最后去找主dex也就是PatchClassLoader的findLibrary去查找。\n\n\t如果是直接使用dlopen bundle内的so，则需要传入so的全路径（比如说通过java层获取），否则可能出现so 找不到。\n\n3. native so load时与load该so的类所在的classloader存在绑定关系，如果存在native反调java层代码的情况，则只能调用到够找到该classloader可以找到的java类的方法\n4. 在android 7.0版本之前native so load同一个进程空间下只可load一次，如果同一个classloder第二次去load则直接返回成功，如果不同的classloader去load则会失败；android 7.0以后ClassLoader通过namespace各自独立，不同的ClassLoader可以去load同一个so，分别会在各自的namespace有各自的mmap，可以通过/proc/pid/maps 查看各自的map信息\n\n### native特殊使用情况及建议 \n1. 由于不同bundle的java代码使用相同的So导致的依赖：\n\n\t建议把调用相关的调用So的代码和So本身单独封装成一个公共的模块，否则如果存在So反调java的情况，则只能调用到loadLibrary的ClassLoader范围内的java类的代码\n\t\n2. 由于native so依赖或者dlopen公共native So的情况：\n\t使用方案：\n\t\n\t1. 公共so下层到公共模块，同时提前load（规避7.0版本开始区分namespace隔离的情况），bundle的so使用的时候不能使用官方的dlopen接口，需要根据mapping查找已load so的导出函数进行使用,规避因为namespace不一致导致多份mmap的情况。 \n\t         \n\t\n\n \n\n\t"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/gitbook/gitbook-plugin-fontsettings/fontsettings.js",
    "content": "require(['gitbook', 'jquery'], function(gitbook, $) {\n    // Configuration\n    var MAX_SIZE       = 4,\n        MIN_SIZE       = 0,\n        BUTTON_ID;\n\n    // Current fontsettings state\n    var fontState;\n\n    // Default themes\n    var THEMES = [\n        {\n            config: 'white',\n            text: 'White',\n            id: 0\n        },\n        {\n            config: 'sepia',\n            text: 'Sepia',\n            id: 1\n        },\n        {\n            config: 'night',\n            text: 'Night',\n            id: 2\n        }\n    ];\n\n    // Default font families\n    var FAMILIES = [\n        {\n            config: 'serif',\n            text: 'Serif',\n            id: 0\n        },\n        {\n            config: 'sans',\n            text: 'Sans',\n            id: 1\n        }\n    ];\n\n    // Return configured themes\n    function getThemes() {\n        return THEMES;\n    }\n\n    // Modify configured themes\n    function setThemes(themes) {\n        THEMES = themes;\n        updateButtons();\n    }\n\n    // Return configured font families\n    function getFamilies() {\n        return FAMILIES;\n    }\n\n    // Modify configured font families\n    function setFamilies(families) {\n        FAMILIES = families;\n        updateButtons();\n    }\n\n    // Save current font settings\n    function saveFontSettings() {\n        gitbook.storage.set('fontState', fontState);\n        update();\n    }\n\n    // Increase font size\n    function enlargeFontSize(e) {\n        e.preventDefault();\n        if (fontState.size >= MAX_SIZE) return;\n\n        fontState.size++;\n        saveFontSettings();\n    }\n\n    // Decrease font size\n    function reduceFontSize(e) {\n        e.preventDefault();\n        if (fontState.size <= MIN_SIZE) return;\n\n        fontState.size--;\n        saveFontSettings();\n    }\n\n    // Change font family\n    function changeFontFamily(configName, e) {\n        if (e && e instanceof Event) {\n            e.preventDefault();\n        }\n\n        var familyId = getFontFamilyId(configName);\n        fontState.family = familyId;\n        saveFontSettings();\n    }\n\n    // Change type of color theme\n    function changeColorTheme(configName, e) {\n        if (e && e instanceof Event) {\n            e.preventDefault();\n        }\n\n        var $book = gitbook.state.$book;\n\n        // Remove currently applied color theme\n        if (fontState.theme !== 0)\n            $book.removeClass('color-theme-'+fontState.theme);\n\n        // Set new color theme\n        var themeId = getThemeId(configName);\n        fontState.theme = themeId;\n        if (fontState.theme !== 0)\n            $book.addClass('color-theme-'+fontState.theme);\n\n        saveFontSettings();\n    }\n\n    // Return the correct id for a font-family config key\n    // Default to first font-family\n    function getFontFamilyId(configName) {\n        // Search for plugin configured font family\n        var configFamily = $.grep(FAMILIES, function(family) {\n            return family.config == configName;\n        })[0];\n        // Fallback to default font family\n        return (!!configFamily)? configFamily.id : 0;\n    }\n\n    // Return the correct id for a theme config key\n    // Default to first theme\n    function getThemeId(configName) {\n        // Search for plugin configured theme\n        var configTheme = $.grep(THEMES, function(theme) {\n            return theme.config == configName;\n        })[0];\n        // Fallback to default theme\n        return (!!configTheme)? configTheme.id : 0;\n    }\n\n    function update() {\n        var $book = gitbook.state.$book;\n\n        $('.font-settings .font-family-list li').removeClass('active');\n        $('.font-settings .font-family-list li:nth-child('+(fontState.family+1)+')').addClass('active');\n\n        $book[0].className = $book[0].className.replace(/\\bfont-\\S+/g, '');\n        $book.addClass('font-size-'+fontState.size);\n        $book.addClass('font-family-'+fontState.family);\n\n        if(fontState.theme !== 0) {\n            $book[0].className = $book[0].className.replace(/\\bcolor-theme-\\S+/g, '');\n            $book.addClass('color-theme-'+fontState.theme);\n        }\n    }\n\n    function init(config) {\n        // Search for plugin configured font family\n        var configFamily = getFontFamilyId(config.family),\n            configTheme = getThemeId(config.theme);\n\n        // Instantiate font state object\n        fontState = gitbook.storage.get('fontState', {\n            size:   config.size || 2,\n            family: configFamily,\n            theme:  configTheme\n        });\n\n        update();\n    }\n\n    function updateButtons() {\n        // Remove existing fontsettings buttons\n        if (!!BUTTON_ID) {\n            gitbook.toolbar.removeButton(BUTTON_ID);\n        }\n\n        // Create buttons in toolbar\n        BUTTON_ID = gitbook.toolbar.createButton({\n            icon: 'fa fa-font',\n            label: 'Font Settings',\n            className: 'font-settings',\n            dropdown: [\n                [\n                    {\n                        text: 'A',\n                        className: 'font-reduce',\n                        onClick: reduceFontSize\n                    },\n                    {\n                        text: 'A',\n                        className: 'font-enlarge',\n                        onClick: enlargeFontSize\n                    }\n                ],\n                $.map(FAMILIES, function(family) {\n                    family.onClick = function(e) {\n                        return changeFontFamily(family.config, e);\n                    };\n\n                    return family;\n                }),\n                $.map(THEMES, function(theme) {\n                    theme.onClick = function(e) {\n                        return changeColorTheme(theme.config, e);\n                    };\n\n                    return theme;\n                })\n            ]\n        });\n    }\n\n    // Init configuration at start\n    gitbook.events.bind('start', function(e, config) {\n        var opts = config.fontsettings;\n\n        // Generate buttons at start\n        updateButtons();\n\n        // Init current settings\n        init(opts);\n    });\n\n    // Expose API\n    gitbook.fontsettings = {\n        enlargeFontSize: enlargeFontSize,\n        reduceFontSize:  reduceFontSize,\n        setTheme:        changeColorTheme,\n        setFamily:       changeFontFamily,\n        getThemes:       getThemes,\n        setThemes:       setThemes,\n        getFamilies:     getFamilies,\n        setFamilies:     setFamilies\n    };\n});\n\n\n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/gitbook/gitbook-plugin-fontsettings/website.css",
    "content": "/*\n * Theme 1\n */\n.color-theme-1 .dropdown-menu {\n  background-color: #111111;\n  border-color: #7e888b;\n}\n.color-theme-1 .dropdown-menu .dropdown-caret .caret-inner {\n  border-bottom: 9px solid #111111;\n}\n.color-theme-1 .dropdown-menu .buttons {\n  border-color: #7e888b;\n}\n.color-theme-1 .dropdown-menu .button {\n  color: #afa790;\n}\n.color-theme-1 .dropdown-menu .button:hover {\n  color: #73553c;\n}\n/*\n * Theme 2\n */\n.color-theme-2 .dropdown-menu {\n  background-color: #2d3143;\n  border-color: #272a3a;\n}\n.color-theme-2 .dropdown-menu .dropdown-caret .caret-inner {\n  border-bottom: 9px solid #2d3143;\n}\n.color-theme-2 .dropdown-menu .buttons {\n  border-color: #272a3a;\n}\n.color-theme-2 .dropdown-menu .button {\n  color: #62677f;\n}\n.color-theme-2 .dropdown-menu .button:hover {\n  color: #f4f4f5;\n}\n.book .book-header .font-settings .font-enlarge {\n  line-height: 30px;\n  font-size: 1.4em;\n}\n.book .book-header .font-settings .font-reduce {\n  line-height: 30px;\n  font-size: 1em;\n}\n.book.color-theme-1 .book-body {\n  color: #704214;\n  background: #f3eacb;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section {\n  background: #f3eacb;\n}\n.book.color-theme-2 .book-body {\n  color: #bdcadb;\n  background: #1c1f2b;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section {\n  background: #1c1f2b;\n}\n.book.font-size-0 .book-body .page-inner section {\n  font-size: 1.2rem;\n}\n.book.font-size-1 .book-body .page-inner section {\n  font-size: 1.4rem;\n}\n.book.font-size-2 .book-body .page-inner section {\n  font-size: 1.6rem;\n}\n.book.font-size-3 .book-body .page-inner section {\n  font-size: 2.2rem;\n}\n.book.font-size-4 .book-body .page-inner section {\n  font-size: 4rem;\n}\n.book.font-family-0 {\n  font-family: Georgia, serif;\n}\n.book.font-family-1 {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal {\n  color: #704214;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal a {\n  color: inherit;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h1,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h2,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h3,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h4,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h5,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h6 {\n  color: inherit;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h1,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h2 {\n  border-color: inherit;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h6 {\n  color: inherit;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal hr {\n  background-color: inherit;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal blockquote {\n  border-color: inherit;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code {\n  background: #fdf6e3;\n  color: #657b83;\n  border-color: #f8df9c;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal .highlight {\n  background-color: inherit;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table th,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table td {\n  border-color: #f5d06c;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table tr {\n  color: inherit;\n  background-color: #fdf6e3;\n  border-color: #444444;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n) {\n  background-color: #fbeecb;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal {\n  color: #bdcadb;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal a {\n  color: #3eb1d0;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h1,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h2,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h3,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h4,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h5,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h6 {\n  color: #fffffa;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h1,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h2 {\n  border-color: #373b4e;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h6 {\n  color: #373b4e;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal hr {\n  background-color: #373b4e;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal blockquote {\n  border-color: #373b4e;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code {\n  color: #9dbed8;\n  background: #2d3143;\n  border-color: #2d3143;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal .highlight {\n  background-color: #282a39;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table th,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table td {\n  border-color: #3b3f54;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table tr {\n  color: #b6c2d2;\n  background-color: #2d3143;\n  border-color: #3b3f54;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n) {\n  background-color: #35394b;\n}\n.book.color-theme-1 .book-header {\n  color: #afa790;\n  background: transparent;\n}\n.book.color-theme-1 .book-header .btn {\n  color: #afa790;\n}\n.book.color-theme-1 .book-header .btn:hover {\n  color: #73553c;\n  background: none;\n}\n.book.color-theme-1 .book-header h1 {\n  color: #704214;\n}\n.book.color-theme-2 .book-header {\n  color: #7e888b;\n  background: transparent;\n}\n.book.color-theme-2 .book-header .btn {\n  color: #3b3f54;\n}\n.book.color-theme-2 .book-header .btn:hover {\n  color: #fffff5;\n  background: none;\n}\n.book.color-theme-2 .book-header h1 {\n  color: #bdcadb;\n}\n.book.color-theme-1 .book-body .navigation {\n  color: #afa790;\n}\n.book.color-theme-1 .book-body .navigation:hover {\n  color: #73553c;\n}\n.book.color-theme-2 .book-body .navigation {\n  color: #383f52;\n}\n.book.color-theme-2 .book-body .navigation:hover {\n  color: #fffff5;\n}\n/*\n * Theme 1\n */\n.book.color-theme-1 .book-summary {\n  color: #afa790;\n  background: #111111;\n  border-right: 1px solid rgba(0, 0, 0, 0.07);\n}\n.book.color-theme-1 .book-summary .book-search {\n  background: transparent;\n}\n.book.color-theme-1 .book-summary .book-search input,\n.book.color-theme-1 .book-summary .book-search input:focus {\n  border: 1px solid transparent;\n}\n.book.color-theme-1 .book-summary ul.summary li.divider {\n  background: #7e888b;\n  box-shadow: none;\n}\n.book.color-theme-1 .book-summary ul.summary li i.fa-check {\n  color: #33cc33;\n}\n.book.color-theme-1 .book-summary ul.summary li.done > a {\n  color: #877f6a;\n}\n.book.color-theme-1 .book-summary ul.summary li a,\n.book.color-theme-1 .book-summary ul.summary li span {\n  color: #877f6a;\n  background: transparent;\n  font-weight: normal;\n}\n.book.color-theme-1 .book-summary ul.summary li.active > a,\n.book.color-theme-1 .book-summary ul.summary li a:hover {\n  color: #704214;\n  background: transparent;\n  font-weight: normal;\n}\n/*\n * Theme 2\n */\n.book.color-theme-2 .book-summary {\n  color: #bcc1d2;\n  background: #2d3143;\n  border-right: none;\n}\n.book.color-theme-2 .book-summary .book-search {\n  background: transparent;\n}\n.book.color-theme-2 .book-summary .book-search input,\n.book.color-theme-2 .book-summary .book-search input:focus {\n  border: 1px solid transparent;\n}\n.book.color-theme-2 .book-summary ul.summary li.divider {\n  background: #272a3a;\n  box-shadow: none;\n}\n.book.color-theme-2 .book-summary ul.summary li i.fa-check {\n  color: #33cc33;\n}\n.book.color-theme-2 .book-summary ul.summary li.done > a {\n  color: #62687f;\n}\n.book.color-theme-2 .book-summary ul.summary li a,\n.book.color-theme-2 .book-summary ul.summary li span {\n  color: #c1c6d7;\n  background: transparent;\n  font-weight: 600;\n}\n.book.color-theme-2 .book-summary ul.summary li.active > a,\n.book.color-theme-2 .book-summary ul.summary li a:hover {\n  color: #f4f4f5;\n  background: #252737;\n  font-weight: 600;\n}\n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/gitbook/gitbook-plugin-highlight/ebook.css",
    "content": "pre,\ncode {\n  /* http://jmblog.github.io/color-themes-for-highlightjs */\n  /* Tomorrow Comment */\n  /* Tomorrow Red */\n  /* Tomorrow Orange */\n  /* Tomorrow Yellow */\n  /* Tomorrow Green */\n  /* Tomorrow Aqua */\n  /* Tomorrow Blue */\n  /* Tomorrow Purple */\n}\npre .hljs-comment,\ncode .hljs-comment,\npre .hljs-title,\ncode .hljs-title {\n  color: #8e908c;\n}\npre .hljs-variable,\ncode .hljs-variable,\npre .hljs-attribute,\ncode .hljs-attribute,\npre .hljs-tag,\ncode .hljs-tag,\npre .hljs-regexp,\ncode .hljs-regexp,\npre .hljs-deletion,\ncode .hljs-deletion,\npre .ruby .hljs-constant,\ncode .ruby .hljs-constant,\npre .xml .hljs-tag .hljs-title,\ncode .xml .hljs-tag .hljs-title,\npre .xml .hljs-pi,\ncode .xml .hljs-pi,\npre .xml .hljs-doctype,\ncode .xml .hljs-doctype,\npre .html .hljs-doctype,\ncode .html .hljs-doctype,\npre .css .hljs-id,\ncode .css .hljs-id,\npre .css .hljs-class,\ncode .css .hljs-class,\npre .css .hljs-pseudo,\ncode .css .hljs-pseudo {\n  color: #c82829;\n}\npre .hljs-number,\ncode .hljs-number,\npre .hljs-preprocessor,\ncode .hljs-preprocessor,\npre .hljs-pragma,\ncode .hljs-pragma,\npre .hljs-built_in,\ncode .hljs-built_in,\npre .hljs-literal,\ncode .hljs-literal,\npre .hljs-params,\ncode .hljs-params,\npre .hljs-constant,\ncode .hljs-constant {\n  color: #f5871f;\n}\npre .ruby .hljs-class .hljs-title,\ncode .ruby .hljs-class .hljs-title,\npre .css .hljs-rules .hljs-attribute,\ncode .css .hljs-rules .hljs-attribute {\n  color: #eab700;\n}\npre .hljs-string,\ncode .hljs-string,\npre .hljs-value,\ncode .hljs-value,\npre .hljs-inheritance,\ncode .hljs-inheritance,\npre .hljs-header,\ncode .hljs-header,\npre .hljs-addition,\ncode .hljs-addition,\npre .ruby .hljs-symbol,\ncode .ruby .hljs-symbol,\npre .xml .hljs-cdata,\ncode .xml .hljs-cdata {\n  color: #718c00;\n}\npre .css .hljs-hexcolor,\ncode .css .hljs-hexcolor {\n  color: #3e999f;\n}\npre .hljs-function,\ncode .hljs-function,\npre .python .hljs-decorator,\ncode .python .hljs-decorator,\npre .python .hljs-title,\ncode .python .hljs-title,\npre .ruby .hljs-function .hljs-title,\ncode .ruby .hljs-function .hljs-title,\npre .ruby .hljs-title .hljs-keyword,\ncode .ruby .hljs-title .hljs-keyword,\npre .perl .hljs-sub,\ncode .perl .hljs-sub,\npre .javascript .hljs-title,\ncode .javascript .hljs-title,\npre .coffeescript .hljs-title,\ncode .coffeescript .hljs-title {\n  color: #4271ae;\n}\npre .hljs-keyword,\ncode .hljs-keyword,\npre .javascript .hljs-function,\ncode .javascript .hljs-function {\n  color: #8959a8;\n}\npre .hljs,\ncode .hljs {\n  display: block;\n  background: white;\n  color: #4d4d4c;\n  padding: 0.5em;\n}\npre .coffeescript .javascript,\ncode .coffeescript .javascript,\npre .javascript .xml,\ncode .javascript .xml,\npre .tex .hljs-formula,\ncode .tex .hljs-formula,\npre .xml .javascript,\ncode .xml .javascript,\npre .xml .vbscript,\ncode .xml .vbscript,\npre .xml .css,\ncode .xml .css,\npre .xml .hljs-cdata,\ncode .xml .hljs-cdata {\n  opacity: 0.5;\n}\n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/gitbook/gitbook-plugin-highlight/website.css",
    "content": ".book .book-body .page-wrapper .page-inner section.normal pre,\n.book .book-body .page-wrapper .page-inner section.normal code {\n  /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */\n  /* Tomorrow Comment */\n  /* Tomorrow Red */\n  /* Tomorrow Orange */\n  /* Tomorrow Yellow */\n  /* Tomorrow Green */\n  /* Tomorrow Aqua */\n  /* Tomorrow Blue */\n  /* Tomorrow Purple */\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-comment,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-comment,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-title {\n  color: #8e908c;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-variable,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-variable,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-attribute,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-tag,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-tag,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-regexp,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-deletion,\n.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-constant,\n.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-constant,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-tag .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-tag .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-pi,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-pi,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-doctype,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-doctype,\n.book .book-body .page-wrapper .page-inner section.normal pre .html .hljs-doctype,\n.book .book-body .page-wrapper .page-inner section.normal code .html .hljs-doctype,\n.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-id,\n.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-id,\n.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-class,\n.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-class,\n.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo,\n.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo {\n  color: #c82829;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-number,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-number,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-pragma,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-built_in,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-literal,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-literal,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-params,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-params,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-constant,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-constant {\n  color: #f5871f;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-class .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-class .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-rules .hljs-attribute,\n.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-rules .hljs-attribute {\n  color: #eab700;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-string,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-string,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-value,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-value,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-inheritance,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-inheritance,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-header,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-header,\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-addition,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-addition,\n.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-symbol,\n.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-symbol,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata {\n  color: #718c00;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-hexcolor,\n.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-hexcolor {\n  color: #3e999f;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-function,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-function,\n.book .book-body .page-wrapper .page-inner section.normal pre .python .hljs-decorator,\n.book .book-body .page-wrapper .page-inner section.normal code .python .hljs-decorator,\n.book .book-body .page-wrapper .page-inner section.normal pre .python .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal code .python .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-function .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-function .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-title .hljs-keyword,\n.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-title .hljs-keyword,\n.book .book-body .page-wrapper .page-inner section.normal pre .perl .hljs-sub,\n.book .book-body .page-wrapper .page-inner section.normal code .perl .hljs-sub,\n.book .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal pre .coffeescript .hljs-title,\n.book .book-body .page-wrapper .page-inner section.normal code .coffeescript .hljs-title {\n  color: #4271ae;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs-keyword,\n.book .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-function,\n.book .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-function {\n  color: #8959a8;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .hljs,\n.book .book-body .page-wrapper .page-inner section.normal code .hljs {\n  display: block;\n  background: white;\n  color: #4d4d4c;\n  padding: 0.5em;\n}\n.book .book-body .page-wrapper .page-inner section.normal pre .coffeescript .javascript,\n.book .book-body .page-wrapper .page-inner section.normal code .coffeescript .javascript,\n.book .book-body .page-wrapper .page-inner section.normal pre .javascript .xml,\n.book .book-body .page-wrapper .page-inner section.normal code .javascript .xml,\n.book .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula,\n.book .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .javascript,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .javascript,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .vbscript,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .vbscript,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .css,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .css,\n.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata,\n.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata {\n  opacity: 0.5;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code {\n  /*\n\nOrginal Style from ethanschoonover.com/solarized (c) Jeremy Hull <sourdrums@gmail.com>\n\n*/\n  /* Solarized Green */\n  /* Solarized Cyan */\n  /* Solarized Blue */\n  /* Solarized Yellow */\n  /* Solarized Orange */\n  /* Solarized Red */\n  /* Solarized Violet */\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs {\n  display: block;\n  padding: 0.5em;\n  background: #fdf6e3;\n  color: #657b83;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-comment,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-comment,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-template_comment,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-template_comment,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .diff .hljs-header,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .diff .hljs-header,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-doctype,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-doctype,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-pi,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-pi,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .lisp .hljs-string,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .lisp .hljs-string,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-javadoc,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-javadoc {\n  color: #93a1a1;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-keyword,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-winutils,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-winutils,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .method,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .method,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-addition,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-addition,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-tag,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-tag,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-request,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-request,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-status,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-status,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .nginx .hljs-title,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .nginx .hljs-title {\n  color: #859900;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-number,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-number,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-command,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-command,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-string,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-string,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-tag .hljs-value,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-tag .hljs-value,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-rules .hljs-value,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-rules .hljs-value,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-phpdoc,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-phpdoc,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-regexp,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-hexcolor,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-hexcolor,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_url,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_url {\n  color: #2aa198;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-title,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-title,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-localvars,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-localvars,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-chunk,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-chunk,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-decorator,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-decorator,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-built_in,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-identifier,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-identifier,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .vhdl .hljs-literal,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .vhdl .hljs-literal,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-id,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-id,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-function,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-function {\n  color: #268bd2;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-attribute,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-variable,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-variable,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .lisp .hljs-body,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .lisp .hljs-body,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .smalltalk .hljs-number,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .smalltalk .hljs-number,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-constant,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-constant,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-class .hljs-title,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-class .hljs-title,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-parent,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-parent,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .haskell .hljs-type,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .haskell .hljs-type,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_reference,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_reference {\n  color: #b58900;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor .hljs-keyword,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor .hljs-keyword,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-pragma,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-shebang,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-shebang,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-symbol,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-symbol,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-symbol .hljs-string,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-symbol .hljs-string,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .diff .hljs-change,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .diff .hljs-change,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-special,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-special,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-attr_selector,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-attr_selector,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-subst,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-subst,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-cdata,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-cdata,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .clojure .hljs-title,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .clojure .hljs-title,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-header,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-header {\n  color: #cb4b16;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-deletion,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-important,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-important {\n  color: #dc322f;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_label,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_label {\n  color: #6c71c4;\n}\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula,\n.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula {\n  background: #eee8d5;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code {\n  /* Tomorrow Night Bright Theme */\n  /* Original theme - https://github.com/chriskempson/tomorrow-theme */\n  /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */\n  /* Tomorrow Comment */\n  /* Tomorrow Red */\n  /* Tomorrow Orange */\n  /* Tomorrow Yellow */\n  /* Tomorrow Green */\n  /* Tomorrow Aqua */\n  /* Tomorrow Blue */\n  /* Tomorrow Purple */\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-comment,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-comment,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-title {\n  color: #969896;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-variable,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-variable,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-attribute,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-tag,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-tag,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-regexp,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-deletion,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-constant,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-constant,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-tag .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-tag .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-pi,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-pi,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-doctype,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-doctype,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .html .hljs-doctype,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .html .hljs-doctype,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-id,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-id,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-class,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-class,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo {\n  color: #d54e53;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-number,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-number,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-pragma,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-built_in,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-literal,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-literal,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-params,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-params,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-constant,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-constant {\n  color: #e78c45;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-class .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-class .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-rules .hljs-attribute,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-rules .hljs-attribute {\n  color: #e7c547;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-string,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-string,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-value,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-value,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-inheritance,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-inheritance,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-header,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-header,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-addition,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-addition,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-symbol,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-symbol,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata {\n  color: #b9ca4a;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-hexcolor,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-hexcolor {\n  color: #70c0b1;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-function,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-function,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .python .hljs-decorator,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .python .hljs-decorator,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .python .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .python .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-function .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-function .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-title .hljs-keyword,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-title .hljs-keyword,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .perl .hljs-sub,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .perl .hljs-sub,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .coffeescript .hljs-title,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .coffeescript .hljs-title {\n  color: #7aa6da;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-keyword,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-function,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-function {\n  color: #c397d8;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs {\n  display: block;\n  background: black;\n  color: #eaeaea;\n  padding: 0.5em;\n}\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .coffeescript .javascript,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .coffeescript .javascript,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .xml,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .xml,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .javascript,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .javascript,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .vbscript,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .vbscript,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .css,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .css,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata,\n.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata {\n  opacity: 0.5;\n}\n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/gitbook/gitbook-plugin-livereload/plugin.js",
    "content": "(function() {\n  var newEl = document.createElement('script'),\n      firstScriptTag = document.getElementsByTagName('script')[0];\n\n  if (firstScriptTag) {\n    newEl.async = 1;\n    newEl.src = '//' + window.location.hostname + ':35729/livereload.js';\n    firstScriptTag.parentNode.insertBefore(newEl, firstScriptTag);\n  }\n\n})();\n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/gitbook/gitbook-plugin-lunr/search-lunr.js",
    "content": "require([\n    'gitbook',\n    'jquery'\n], function(gitbook, $) {\n    // Define global search engine\n    function LunrSearchEngine() {\n        this.index = null;\n        this.store = {};\n        this.name = 'LunrSearchEngine';\n    }\n\n    // Initialize lunr by fetching the search index\n    LunrSearchEngine.prototype.init = function() {\n        var that = this;\n        var d = $.Deferred();\n\n        $.getJSON(gitbook.state.basePath+'/search_index.json')\n        .then(function(data) {\n            // eslint-disable-next-line no-undef\n            that.index = lunr.Index.load(data.index);\n            that.store = data.store;\n            d.resolve();\n        });\n\n        return d.promise();\n    };\n\n    // Search for a term and return results\n    LunrSearchEngine.prototype.search = function(q, offset, length) {\n        var that = this;\n        var results = [];\n\n        if (this.index) {\n            results = $.map(this.index.search(q), function(result) {\n                var doc = that.store[result.ref];\n\n                return {\n                    title: doc.title,\n                    url: doc.url,\n                    body: doc.summary || doc.body\n                };\n            });\n        }\n\n        return $.Deferred().resolve({\n            query: q,\n            results: results.slice(0, length),\n            count: results.length\n        }).promise();\n    };\n\n    // Set gitbook research\n    gitbook.events.bind('start', function(e, config) {\n        var engine = gitbook.search.getEngine();\n        if (!engine) {\n            gitbook.search.setEngine(LunrSearchEngine, config);\n        }\n    });\n});\n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/gitbook/gitbook-plugin-search/search-engine.js",
    "content": "require([\n    'gitbook',\n    'jquery'\n], function(gitbook, $) {\n    // Global search objects\n    var engine      = null;\n    var initialized = false;\n\n    // Set a new search engine\n    function setEngine(Engine, config) {\n        initialized = false;\n        engine      = new Engine(config);\n\n        init(config);\n    }\n\n    // Initialize search engine with config\n    function init(config) {\n        if (!engine) throw new Error('No engine set for research. Set an engine using gitbook.research.setEngine(Engine).');\n\n        return engine.init(config)\n        .then(function() {\n            initialized = true;\n            gitbook.events.trigger('search.ready');\n        });\n    }\n\n    // Launch search for query q\n    function query(q, offset, length) {\n        if (!initialized) throw new Error('Search has not been initialized');\n        return engine.search(q, offset, length);\n    }\n\n    // Get stats about search\n    function getEngine() {\n        return engine? engine.name : null;\n    }\n\n    function isInitialized() {\n        return initialized;\n    }\n\n    // Initialize gitbook.search\n    gitbook.search = {\n        setEngine:     setEngine,\n        getEngine:     getEngine,\n        query:         query,\n        isInitialized: isInitialized\n    };\n});"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/gitbook/gitbook-plugin-search/search.css",
    "content": "/*\n    This CSS only styled the search results section, not the search input\n    It defines the basic interraction to hide content when displaying results, etc\n*/\n#book-search-results .search-results {\n  display: none;\n}\n#book-search-results .search-results ul.search-results-list {\n  list-style-type: none;\n  padding-left: 0;\n}\n#book-search-results .search-results ul.search-results-list li {\n  margin-bottom: 1.5rem;\n  padding-bottom: 0.5rem;\n  /* Highlight results */\n}\n#book-search-results .search-results ul.search-results-list li p em {\n  background-color: rgba(255, 220, 0, 0.4);\n  font-style: normal;\n}\n#book-search-results .search-results .no-results {\n  display: none;\n}\n#book-search-results.open .search-results {\n  display: block;\n}\n#book-search-results.open .search-noresults {\n  display: none;\n}\n#book-search-results.no-results .search-results .has-results {\n  display: none;\n}\n#book-search-results.no-results .search-results .no-results {\n  display: block;\n}\n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/gitbook/gitbook-plugin-search/search.js",
    "content": "require([\n    'gitbook',\n    'jquery'\n], function(gitbook, $) {\n    var MAX_RESULTS = 15;\n    var MAX_DESCRIPTION_SIZE = 500;\n\n    var usePushState = (typeof history.pushState !== 'undefined');\n\n    // DOM Elements\n    var $body = $('body');\n    var $bookSearchResults;\n    var $searchInput;\n    var $searchList;\n    var $searchTitle;\n    var $searchResultsCount;\n    var $searchQuery;\n\n    // Throttle search\n    function throttle(fn, wait) {\n        var timeout;\n\n        return function() {\n            var ctx = this, args = arguments;\n            if (!timeout) {\n                timeout = setTimeout(function() {\n                    timeout = null;\n                    fn.apply(ctx, args);\n                }, wait);\n            }\n        };\n    }\n\n    function displayResults(res) {\n        $bookSearchResults.addClass('open');\n\n        var noResults = res.count == 0;\n        $bookSearchResults.toggleClass('no-results', noResults);\n\n        // Clear old results\n        $searchList.empty();\n\n        // Display title for research\n        $searchResultsCount.text(res.count);\n        $searchQuery.text(res.query);\n\n        // Create an <li> element for each result\n        res.results.forEach(function(res) {\n            var $li = $('<li>', {\n                'class': 'search-results-item'\n            });\n\n            var $title = $('<h3>');\n\n            var $link = $('<a>', {\n                'href': gitbook.state.basePath + '/' + res.url,\n                'text': res.title\n            });\n\n            var content = res.body.trim();\n            if (content.length > MAX_DESCRIPTION_SIZE) {\n                content = content.slice(0, MAX_DESCRIPTION_SIZE).trim()+'...';\n            }\n            var $content = $('<p>').html(content);\n\n            $link.appendTo($title);\n            $title.appendTo($li);\n            $content.appendTo($li);\n            $li.appendTo($searchList);\n        });\n    }\n\n    function launchSearch(q) {\n        // Add class for loading\n        $body.addClass('with-search');\n        $body.addClass('search-loading');\n\n        // Launch search query\n        throttle(gitbook.search.query(q, 0, MAX_RESULTS)\n        .then(function(results) {\n            displayResults(results);\n        })\n        .always(function() {\n            $body.removeClass('search-loading');\n        }), 1000);\n    }\n\n    function closeSearch() {\n        $body.removeClass('with-search');\n        $bookSearchResults.removeClass('open');\n    }\n\n    function launchSearchFromQueryString() {\n        var q = getParameterByName('q');\n        if (q && q.length > 0) {\n            // Update search input\n            $searchInput.val(q);\n\n            // Launch search\n            launchSearch(q);\n        }\n    }\n\n    function bindSearch() {\n        // Bind DOM\n        $searchInput        = $('#book-search-input input');\n        $bookSearchResults  = $('#book-search-results');\n        $searchList         = $bookSearchResults.find('.search-results-list');\n        $searchTitle        = $bookSearchResults.find('.search-results-title');\n        $searchResultsCount = $searchTitle.find('.search-results-count');\n        $searchQuery        = $searchTitle.find('.search-query');\n\n        // Launch query based on input content\n        function handleUpdate() {\n            var q = $searchInput.val();\n\n            if (q.length == 0) {\n                closeSearch();\n            }\n            else {\n                launchSearch(q);\n            }\n        }\n\n        // Detect true content change in search input\n        // Workaround for IE < 9\n        var propertyChangeUnbound = false;\n        $searchInput.on('propertychange', function(e) {\n            if (e.originalEvent.propertyName == 'value') {\n                handleUpdate();\n            }\n        });\n\n        // HTML5 (IE9 & others)\n        $searchInput.on('input', function(e) {\n            // Unbind propertychange event for IE9+\n            if (!propertyChangeUnbound) {\n                $(this).unbind('propertychange');\n                propertyChangeUnbound = true;\n            }\n\n            handleUpdate();\n        });\n\n        // Push to history on blur\n        $searchInput.on('blur', function(e) {\n            // Update history state\n            if (usePushState) {\n                var uri = updateQueryString('q', $(this).val());\n                history.pushState({ path: uri }, null, uri);\n            }\n        });\n    }\n\n    gitbook.events.on('page.change', function() {\n        bindSearch();\n        closeSearch();\n\n        // Launch search based on query parameter\n        if (gitbook.search.isInitialized()) {\n            launchSearchFromQueryString();\n        }\n    });\n\n    gitbook.events.on('search.ready', function() {\n        bindSearch();\n\n        // Launch search from query param at start\n        launchSearchFromQueryString();\n    });\n\n    function getParameterByName(name) {\n        var url = window.location.href;\n        name = name.replace(/[\\[\\]]/g, '\\\\$&');\n        var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)', 'i'),\n            results = regex.exec(url);\n        if (!results) return null;\n        if (!results[2]) return '';\n        return decodeURIComponent(results[2].replace(/\\+/g, ' '));\n    }\n\n    function updateQueryString(key, value) {\n        value = encodeURIComponent(value);\n\n        var url = window.location.href;\n        var re = new RegExp('([?&])' + key + '=.*?(&|#|$)(.*)', 'gi'),\n            hash;\n\n        if (re.test(url)) {\n            if (typeof value !== 'undefined' && value !== null)\n                return url.replace(re, '$1' + key + '=' + value + '$2$3');\n            else {\n                hash = url.split('#');\n                url = hash[0].replace(re, '$1$3').replace(/(&|\\?)$/, '');\n                if (typeof hash[1] !== 'undefined' && hash[1] !== null)\n                    url += '#' + hash[1];\n                return url;\n            }\n        }\n        else {\n            if (typeof value !== 'undefined' && value !== null) {\n                var separator = url.indexOf('?') !== -1 ? '&' : '?';\n                hash = url.split('#');\n                url = hash[0] + separator + key + '=' + value;\n                if (typeof hash[1] !== 'undefined' && hash[1] !== null)\n                    url += '#' + hash[1];\n                return url;\n            }\n            else\n                return url;\n        }\n    }\n});\n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/gitbook/gitbook-plugin-sharing/buttons.js",
    "content": "require(['gitbook', 'jquery'], function(gitbook, $) {\n    var SITES = {\n        'facebook': {\n            'label': 'Facebook',\n            'icon': 'fa fa-facebook',\n            'onClick': function(e) {\n                e.preventDefault();\n                window.open('http://www.facebook.com/sharer/sharer.php?s=100&p[url]='+encodeURIComponent(location.href));\n            }\n        },\n        'twitter': {\n            'label': 'Twitter',\n            'icon': 'fa fa-twitter',\n            'onClick': function(e) {\n                e.preventDefault();\n                window.open('http://twitter.com/home?status='+encodeURIComponent(document.title+' '+location.href));\n            }\n        },\n        'google': {\n            'label': 'Google+',\n            'icon': 'fa fa-google-plus',\n            'onClick': function(e) {\n                e.preventDefault();\n                window.open('https://plus.google.com/share?url='+encodeURIComponent(location.href));\n            }\n        },\n        'weibo': {\n            'label': 'Weibo',\n            'icon': 'fa fa-weibo',\n            'onClick': function(e) {\n                e.preventDefault();\n                window.open('http://service.weibo.com/share/share.php?content=utf-8&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title));\n            }\n        },\n        'instapaper': {\n            'label': 'Instapaper',\n            'icon': 'fa fa-instapaper',\n            'onClick': function(e) {\n                e.preventDefault();\n                window.open('http://www.instapaper.com/text?u='+encodeURIComponent(location.href));\n            }\n        },\n        'vk': {\n            'label': 'VK',\n            'icon': 'fa fa-vk',\n            'onClick': function(e) {\n                e.preventDefault();\n                window.open('http://vkontakte.ru/share.php?url='+encodeURIComponent(location.href));\n            }\n        }\n    };\n\n\n\n    gitbook.events.bind('start', function(e, config) {\n        var opts = config.sharing;\n\n        // Create dropdown menu\n        var menu = $.map(opts.all, function(id) {\n            var site = SITES[id];\n\n            return {\n                text: site.label,\n                onClick: site.onClick\n            };\n        });\n\n        // Create main button with dropdown\n        if (menu.length > 0) {\n            gitbook.toolbar.createButton({\n                icon: 'fa fa-share-alt',\n                label: 'Share',\n                position: 'right',\n                dropdown: [menu]\n            });\n        }\n\n        // Direct actions to share\n        $.each(SITES, function(sideId, site) {\n            if (!opts[sideId]) return;\n\n            gitbook.toolbar.createButton({\n                icon: site.icon,\n                label: site.text,\n                position: 'right',\n                onClick: site.onClick\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/gitbook/gitbook.js",
    "content": "!function e(t,n,r){function o(s,a){if(!n[s]){if(!t[s]){var u=\"function\"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var c=new Error(\"Cannot find module '\"+s+\"'\");throw c.code=\"MODULE_NOT_FOUND\",c}var l=n[s]={exports:{}};t[s][0].call(l.exports,function(e){var n=t[s][1][e];return o(n?n:e)},l,l.exports,e,t,n,r)}return n[s].exports}for(var i=\"function\"==typeof require&&require,s=0;s<r.length;s++)o(r[s]);return o}({1:[function(e,t,n){!function(e,n){\"use strict\";\"object\"==typeof t&&\"object\"==typeof t.exports?t.exports=e.document?n(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return n(e)}:n(e)}(\"undefined\"!=typeof window?window:this,function(e,t){\"use strict\";function n(e,t){t=t||te;var n=t.createElement(\"script\");n.text=e,t.head.appendChild(n).parentNode.removeChild(n)}function r(e){var t=!!e&&\"length\"in e&&e.length,n=de.type(e);return\"function\"!==n&&!de.isWindow(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&t>0&&t-1 in e)}function o(e,t,n){return de.isFunction(t)?de.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?de.grep(e,function(e){return e===t!==n}):\"string\"!=typeof t?de.grep(e,function(e){return se.call(t,e)>-1!==n}):je.test(t)?de.filter(t,e,n):(t=de.filter(t,e),de.grep(e,function(e){return se.call(t,e)>-1!==n&&1===e.nodeType}))}function i(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function s(e){var t={};return de.each(e.match(qe)||[],function(e,n){t[n]=!0}),t}function a(e){return e}function u(e){throw e}function c(e,t,n){var r;try{e&&de.isFunction(r=e.promise)?r.call(e).done(t).fail(n):e&&de.isFunction(r=e.then)?r.call(e,t,n):t.call(void 0,e)}catch(e){n.call(void 0,e)}}function l(){te.removeEventListener(\"DOMContentLoaded\",l),e.removeEventListener(\"load\",l),de.ready()}function f(){this.expando=de.expando+f.uid++}function p(e){return\"true\"===e||\"false\"!==e&&(\"null\"===e?null:e===+e+\"\"?+e:Ie.test(e)?JSON.parse(e):e)}function h(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r=\"data-\"+t.replace(Pe,\"-$&\").toLowerCase(),n=e.getAttribute(r),\"string\"==typeof n){try{n=p(n)}catch(e){}Re.set(e,t,n)}else n=void 0;return n}function d(e,t,n,r){var o,i=1,s=20,a=r?function(){return r.cur()}:function(){return de.css(e,t,\"\")},u=a(),c=n&&n[3]||(de.cssNumber[t]?\"\":\"px\"),l=(de.cssNumber[t]||\"px\"!==c&&+u)&&$e.exec(de.css(e,t));if(l&&l[3]!==c){c=c||l[3],n=n||[],l=+u||1;do i=i||\".5\",l/=i,de.style(e,t,l+c);while(i!==(i=a()/u)&&1!==i&&--s)}return n&&(l=+l||+u||0,o=n[1]?l+(n[1]+1)*n[2]:+n[2],r&&(r.unit=c,r.start=l,r.end=o)),o}function g(e){var t,n=e.ownerDocument,r=e.nodeName,o=Ue[r];return o?o:(t=n.body.appendChild(n.createElement(r)),o=de.css(t,\"display\"),t.parentNode.removeChild(t),\"none\"===o&&(o=\"block\"),Ue[r]=o,o)}function m(e,t){for(var n,r,o=[],i=0,s=e.length;i<s;i++)r=e[i],r.style&&(n=r.style.display,t?(\"none\"===n&&(o[i]=Fe.get(r,\"display\")||null,o[i]||(r.style.display=\"\")),\"\"===r.style.display&&Be(r)&&(o[i]=g(r))):\"none\"!==n&&(o[i]=\"none\",Fe.set(r,\"display\",n)));for(i=0;i<s;i++)null!=o[i]&&(e[i].style.display=o[i]);return e}function v(e,t){var n;return n=\"undefined\"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):\"undefined\"!=typeof e.querySelectorAll?e.querySelectorAll(t||\"*\"):[],void 0===t||t&&de.nodeName(e,t)?de.merge([e],n):n}function y(e,t){for(var n=0,r=e.length;n<r;n++)Fe.set(e[n],\"globalEval\",!t||Fe.get(t[n],\"globalEval\"))}function x(e,t,n,r,o){for(var i,s,a,u,c,l,f=t.createDocumentFragment(),p=[],h=0,d=e.length;h<d;h++)if(i=e[h],i||0===i)if(\"object\"===de.type(i))de.merge(p,i.nodeType?[i]:i);else if(Ye.test(i)){for(s=s||f.appendChild(t.createElement(\"div\")),a=(Xe.exec(i)||[\"\",\"\"])[1].toLowerCase(),u=Ge[a]||Ge._default,s.innerHTML=u[1]+de.htmlPrefilter(i)+u[2],l=u[0];l--;)s=s.lastChild;de.merge(p,s.childNodes),s=f.firstChild,s.textContent=\"\"}else p.push(t.createTextNode(i));for(f.textContent=\"\",h=0;i=p[h++];)if(r&&de.inArray(i,r)>-1)o&&o.push(i);else if(c=de.contains(i.ownerDocument,i),s=v(f.appendChild(i),\"script\"),c&&y(s),n)for(l=0;i=s[l++];)Ve.test(i.type||\"\")&&n.push(i);return f}function b(){return!0}function w(){return!1}function T(){try{return te.activeElement}catch(e){}}function C(e,t,n,r,o,i){var s,a;if(\"object\"==typeof t){\"string\"!=typeof n&&(r=r||n,n=void 0);for(a in t)C(e,a,n,r,t[a],i);return e}if(null==r&&null==o?(o=n,r=n=void 0):null==o&&(\"string\"==typeof n?(o=r,r=void 0):(o=r,r=n,n=void 0)),o===!1)o=w;else if(!o)return e;return 1===i&&(s=o,o=function(e){return de().off(e),s.apply(this,arguments)},o.guid=s.guid||(s.guid=de.guid++)),e.each(function(){de.event.add(this,t,o,r,n)})}function j(e,t){return de.nodeName(e,\"table\")&&de.nodeName(11!==t.nodeType?t:t.firstChild,\"tr\")?e.getElementsByTagName(\"tbody\")[0]||e:e}function k(e){return e.type=(null!==e.getAttribute(\"type\"))+\"/\"+e.type,e}function E(e){var t=rt.exec(e.type);return t?e.type=t[1]:e.removeAttribute(\"type\"),e}function S(e,t){var n,r,o,i,s,a,u,c;if(1===t.nodeType){if(Fe.hasData(e)&&(i=Fe.access(e),s=Fe.set(t,i),c=i.events)){delete s.handle,s.events={};for(o in c)for(n=0,r=c[o].length;n<r;n++)de.event.add(t,o,c[o][n])}Re.hasData(e)&&(a=Re.access(e),u=de.extend({},a),Re.set(t,u))}}function N(e,t){var n=t.nodeName.toLowerCase();\"input\"===n&&ze.test(e.type)?t.checked=e.checked:\"input\"!==n&&\"textarea\"!==n||(t.defaultValue=e.defaultValue)}function A(e,t,r,o){t=oe.apply([],t);var i,s,a,u,c,l,f=0,p=e.length,h=p-1,d=t[0],g=de.isFunction(d);if(g||p>1&&\"string\"==typeof d&&!pe.checkClone&&nt.test(d))return e.each(function(n){var i=e.eq(n);g&&(t[0]=d.call(this,n,i.html())),A(i,t,r,o)});if(p&&(i=x(t,e[0].ownerDocument,!1,e,o),s=i.firstChild,1===i.childNodes.length&&(i=s),s||o)){for(a=de.map(v(i,\"script\"),k),u=a.length;f<p;f++)c=i,f!==h&&(c=de.clone(c,!0,!0),u&&de.merge(a,v(c,\"script\"))),r.call(e[f],c,f);if(u)for(l=a[a.length-1].ownerDocument,de.map(a,E),f=0;f<u;f++)c=a[f],Ve.test(c.type||\"\")&&!Fe.access(c,\"globalEval\")&&de.contains(l,c)&&(c.src?de._evalUrl&&de._evalUrl(c.src):n(c.textContent.replace(ot,\"\"),l))}return e}function q(e,t,n){for(var r,o=t?de.filter(t,e):e,i=0;null!=(r=o[i]);i++)n||1!==r.nodeType||de.cleanData(v(r)),r.parentNode&&(n&&de.contains(r.ownerDocument,r)&&y(v(r,\"script\")),r.parentNode.removeChild(r));return e}function D(e,t,n){var r,o,i,s,a=e.style;return n=n||at(e),n&&(s=n.getPropertyValue(t)||n[t],\"\"!==s||de.contains(e.ownerDocument,e)||(s=de.style(e,t)),!pe.pixelMarginRight()&&st.test(s)&&it.test(t)&&(r=a.width,o=a.minWidth,i=a.maxWidth,a.minWidth=a.maxWidth=a.width=s,s=n.width,a.width=r,a.minWidth=o,a.maxWidth=i)),void 0!==s?s+\"\":s}function O(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function L(e){if(e in pt)return e;for(var t=e[0].toUpperCase()+e.slice(1),n=ft.length;n--;)if(e=ft[n]+t,e in pt)return e}function H(e,t,n){var r=$e.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||\"px\"):t}function F(e,t,n,r,o){var i,s=0;for(i=n===(r?\"border\":\"content\")?4:\"width\"===t?1:0;i<4;i+=2)\"margin\"===n&&(s+=de.css(e,n+We[i],!0,o)),r?(\"content\"===n&&(s-=de.css(e,\"padding\"+We[i],!0,o)),\"margin\"!==n&&(s-=de.css(e,\"border\"+We[i]+\"Width\",!0,o))):(s+=de.css(e,\"padding\"+We[i],!0,o),\"padding\"!==n&&(s+=de.css(e,\"border\"+We[i]+\"Width\",!0,o)));return s}function R(e,t,n){var r,o=!0,i=at(e),s=\"border-box\"===de.css(e,\"boxSizing\",!1,i);if(e.getClientRects().length&&(r=e.getBoundingClientRect()[t]),r<=0||null==r){if(r=D(e,t,i),(r<0||null==r)&&(r=e.style[t]),st.test(r))return r;o=s&&(pe.boxSizingReliable()||r===e.style[t]),r=parseFloat(r)||0}return r+F(e,t,n||(s?\"border\":\"content\"),o,i)+\"px\"}function I(e,t,n,r,o){return new I.prototype.init(e,t,n,r,o)}function P(){dt&&(e.requestAnimationFrame(P),de.fx.tick())}function M(){return e.setTimeout(function(){ht=void 0}),ht=de.now()}function $(e,t){var n,r=0,o={height:e};for(t=t?1:0;r<4;r+=2-t)n=We[r],o[\"margin\"+n]=o[\"padding\"+n]=e;return t&&(o.opacity=o.width=e),o}function W(e,t,n){for(var r,o=(U.tweeners[t]||[]).concat(U.tweeners[\"*\"]),i=0,s=o.length;i<s;i++)if(r=o[i].call(n,t,e))return r}function B(e,t,n){var r,o,i,s,a,u,c,l,f=\"width\"in t||\"height\"in t,p=this,h={},d=e.style,g=e.nodeType&&Be(e),v=Fe.get(e,\"fxshow\");n.queue||(s=de._queueHooks(e,\"fx\"),null==s.unqueued&&(s.unqueued=0,a=s.empty.fire,s.empty.fire=function(){s.unqueued||a()}),s.unqueued++,p.always(function(){p.always(function(){s.unqueued--,de.queue(e,\"fx\").length||s.empty.fire()})}));for(r in t)if(o=t[r],gt.test(o)){if(delete t[r],i=i||\"toggle\"===o,o===(g?\"hide\":\"show\")){if(\"show\"!==o||!v||void 0===v[r])continue;g=!0}h[r]=v&&v[r]||de.style(e,r)}if(u=!de.isEmptyObject(t),u||!de.isEmptyObject(h)){f&&1===e.nodeType&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],c=v&&v.display,null==c&&(c=Fe.get(e,\"display\")),l=de.css(e,\"display\"),\"none\"===l&&(c?l=c:(m([e],!0),c=e.style.display||c,l=de.css(e,\"display\"),m([e]))),(\"inline\"===l||\"inline-block\"===l&&null!=c)&&\"none\"===de.css(e,\"float\")&&(u||(p.done(function(){d.display=c}),null==c&&(l=d.display,c=\"none\"===l?\"\":l)),d.display=\"inline-block\")),n.overflow&&(d.overflow=\"hidden\",p.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]})),u=!1;for(r in h)u||(v?\"hidden\"in v&&(g=v.hidden):v=Fe.access(e,\"fxshow\",{display:c}),i&&(v.hidden=!g),g&&m([e],!0),p.done(function(){g||m([e]),Fe.remove(e,\"fxshow\");for(r in h)de.style(e,r,h[r])})),u=W(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}}function _(e,t){var n,r,o,i,s;for(n in e)if(r=de.camelCase(n),o=t[r],i=e[n],de.isArray(i)&&(o=i[1],i=e[n]=i[0]),n!==r&&(e[r]=i,delete e[n]),s=de.cssHooks[r],s&&\"expand\"in s){i=s.expand(i),delete e[r];for(n in i)n in e||(e[n]=i[n],t[n]=o)}else t[r]=o}function U(e,t,n){var r,o,i=0,s=U.prefilters.length,a=de.Deferred().always(function(){delete u.elem}),u=function(){if(o)return!1;for(var t=ht||M(),n=Math.max(0,c.startTime+c.duration-t),r=n/c.duration||0,i=1-r,s=0,u=c.tweens.length;s<u;s++)c.tweens[s].run(i);return a.notifyWith(e,[c,i,n]),i<1&&u?n:(a.resolveWith(e,[c]),!1)},c=a.promise({elem:e,props:de.extend({},t),opts:de.extend(!0,{specialEasing:{},easing:de.easing._default},n),originalProperties:t,originalOptions:n,startTime:ht||M(),duration:n.duration,tweens:[],createTween:function(t,n){var r=de.Tween(e,c.opts,t,n,c.opts.specialEasing[t]||c.opts.easing);return c.tweens.push(r),r},stop:function(t){var n=0,r=t?c.tweens.length:0;if(o)return this;for(o=!0;n<r;n++)c.tweens[n].run(1);return t?(a.notifyWith(e,[c,1,0]),a.resolveWith(e,[c,t])):a.rejectWith(e,[c,t]),this}}),l=c.props;for(_(l,c.opts.specialEasing);i<s;i++)if(r=U.prefilters[i].call(c,e,l,c.opts))return de.isFunction(r.stop)&&(de._queueHooks(c.elem,c.opts.queue).stop=de.proxy(r.stop,r)),r;return de.map(l,W,c),de.isFunction(c.opts.start)&&c.opts.start.call(e,c),de.fx.timer(de.extend(u,{elem:e,anim:c,queue:c.opts.queue})),c.progress(c.opts.progress).done(c.opts.done,c.opts.complete).fail(c.opts.fail).always(c.opts.always)}function z(e){var t=e.match(qe)||[];return t.join(\" \")}function X(e){return e.getAttribute&&e.getAttribute(\"class\")||\"\"}function V(e,t,n,r){var o;if(de.isArray(t))de.each(t,function(t,o){n||Et.test(e)?r(e,o):V(e+\"[\"+(\"object\"==typeof o&&null!=o?t:\"\")+\"]\",o,n,r)});else if(n||\"object\"!==de.type(t))r(e,t);else for(o in t)V(e+\"[\"+o+\"]\",t[o],n,r)}function G(e){return function(t,n){\"string\"!=typeof t&&(n=t,t=\"*\");var r,o=0,i=t.toLowerCase().match(qe)||[];if(de.isFunction(n))for(;r=i[o++];)\"+\"===r[0]?(r=r.slice(1)||\"*\",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function Y(e,t,n,r){function o(a){var u;return i[a]=!0,de.each(e[a]||[],function(e,a){var c=a(t,n,r);return\"string\"!=typeof c||s||i[c]?s?!(u=c):void 0:(t.dataTypes.unshift(c),o(c),!1)}),u}var i={},s=e===Pt;return o(t.dataTypes[0])||!i[\"*\"]&&o(\"*\")}function Q(e,t){var n,r,o=de.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((o[n]?e:r||(r={}))[n]=t[n]);return r&&de.extend(!0,e,r),e}function J(e,t,n){for(var r,o,i,s,a=e.contents,u=e.dataTypes;\"*\"===u[0];)u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader(\"Content-Type\"));if(r)for(o in a)if(a[o]&&a[o].test(r)){u.unshift(o);break}if(u[0]in n)i=u[0];else{for(o in n){if(!u[0]||e.converters[o+\" \"+u[0]]){i=o;break}s||(s=o)}i=i||s}if(i)return i!==u[0]&&u.unshift(i),n[i]}function K(e,t,n,r){var o,i,s,a,u,c={},l=e.dataTypes.slice();if(l[1])for(s in e.converters)c[s.toLowerCase()]=e.converters[s];for(i=l.shift();i;)if(e.responseFields[i]&&(n[e.responseFields[i]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=i,i=l.shift())if(\"*\"===i)i=u;else if(\"*\"!==u&&u!==i){if(s=c[u+\" \"+i]||c[\"* \"+i],!s)for(o in c)if(a=o.split(\" \"),a[1]===i&&(s=c[u+\" \"+a[0]]||c[\"* \"+a[0]])){s===!0?s=c[o]:c[o]!==!0&&(i=a[0],l.unshift(a[1]));break}if(s!==!0)if(s&&e.throws)t=s(t);else try{t=s(t)}catch(e){return{state:\"parsererror\",error:s?e:\"No conversion from \"+u+\" to \"+i}}}return{state:\"success\",data:t}}function Z(e){return de.isWindow(e)?e:9===e.nodeType&&e.defaultView}var ee=[],te=e.document,ne=Object.getPrototypeOf,re=ee.slice,oe=ee.concat,ie=ee.push,se=ee.indexOf,ae={},ue=ae.toString,ce=ae.hasOwnProperty,le=ce.toString,fe=le.call(Object),pe={},he=\"3.1.1\",de=function(e,t){return new de.fn.init(e,t)},ge=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,me=/^-ms-/,ve=/-([a-z])/g,ye=function(e,t){return t.toUpperCase()};de.fn=de.prototype={jquery:he,constructor:de,length:0,toArray:function(){return re.call(this)},get:function(e){return null==e?re.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=de.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return de.each(this,e)},map:function(e){return this.pushStack(de.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(re.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:ie,sort:ee.sort,splice:ee.splice},de.extend=de.fn.extend=function(){var e,t,n,r,o,i,s=arguments[0]||{},a=1,u=arguments.length,c=!1;for(\"boolean\"==typeof s&&(c=s,s=arguments[a]||{},a++),\"object\"==typeof s||de.isFunction(s)||(s={}),a===u&&(s=this,a--);a<u;a++)if(null!=(e=arguments[a]))for(t in e)n=s[t],r=e[t],s!==r&&(c&&r&&(de.isPlainObject(r)||(o=de.isArray(r)))?(o?(o=!1,i=n&&de.isArray(n)?n:[]):i=n&&de.isPlainObject(n)?n:{},s[t]=de.extend(c,i,r)):void 0!==r&&(s[t]=r));return s},de.extend({expando:\"jQuery\"+(he+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isFunction:function(e){return\"function\"===de.type(e)},isArray:Array.isArray,isWindow:function(e){return null!=e&&e===e.window},isNumeric:function(e){var t=de.type(e);return(\"number\"===t||\"string\"===t)&&!isNaN(e-parseFloat(e))},isPlainObject:function(e){var t,n;return!(!e||\"[object Object]\"!==ue.call(e))&&(!(t=ne(e))||(n=ce.call(t,\"constructor\")&&t.constructor,\"function\"==typeof n&&le.call(n)===fe))},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},type:function(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?ae[ue.call(e)]||\"object\":typeof e},globalEval:function(e){n(e)},camelCase:function(e){return e.replace(me,\"ms-\").replace(ve,ye)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var n,o=0;if(r(e))for(n=e.length;o<n&&t.call(e[o],o,e[o])!==!1;o++);else for(o in e)if(t.call(e[o],o,e[o])===!1)break;return e},trim:function(e){return null==e?\"\":(e+\"\").replace(ge,\"\")},makeArray:function(e,t){var n=t||[];return null!=e&&(r(Object(e))?de.merge(n,\"string\"==typeof e?[e]:e):ie.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:se.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,o=e.length;r<n;r++)e[o++]=t[r];return e.length=o,e},grep:function(e,t,n){for(var r,o=[],i=0,s=e.length,a=!n;i<s;i++)r=!t(e[i],i),r!==a&&o.push(e[i]);return o},map:function(e,t,n){var o,i,s=0,a=[];if(r(e))for(o=e.length;s<o;s++)i=t(e[s],s,n),null!=i&&a.push(i);else for(s in e)i=t(e[s],s,n),null!=i&&a.push(i);return oe.apply([],a)},guid:1,proxy:function(e,t){var n,r,o;if(\"string\"==typeof t&&(n=e[t],t=e,e=n),de.isFunction(e))return r=re.call(arguments,2),o=function(){return e.apply(t||this,r.concat(re.call(arguments)))},o.guid=e.guid=e.guid||de.guid++,o},now:Date.now,support:pe}),\"function\"==typeof Symbol&&(de.fn[Symbol.iterator]=ee[Symbol.iterator]),de.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(e,t){ae[\"[object \"+t+\"]\"]=t.toLowerCase()});var xe=function(e){function t(e,t,n,r){var o,i,s,a,u,c,l,p=t&&t.ownerDocument,d=t?t.nodeType:9;if(n=n||[],\"string\"!=typeof e||!e||1!==d&&9!==d&&11!==d)return n;if(!r&&((t?t.ownerDocument||t:W)!==L&&O(t),t=t||L,F)){if(11!==d&&(u=ve.exec(e)))if(o=u[1]){if(9===d){if(!(s=t.getElementById(o)))return n;if(s.id===o)return n.push(s),n}else if(p&&(s=p.getElementById(o))&&M(t,s)&&s.id===o)return n.push(s),n}else{if(u[2])return K.apply(n,t.getElementsByTagName(e)),n;if((o=u[3])&&T.getElementsByClassName&&t.getElementsByClassName)return K.apply(n,t.getElementsByClassName(o)),n}if(T.qsa&&!X[e+\" \"]&&(!R||!R.test(e))){if(1!==d)p=t,l=e;else if(\"object\"!==t.nodeName.toLowerCase()){for((a=t.getAttribute(\"id\"))?a=a.replace(we,Te):t.setAttribute(\"id\",a=$),c=E(e),i=c.length;i--;)c[i]=\"#\"+a+\" \"+h(c[i]);l=c.join(\",\"),p=ye.test(e)&&f(t.parentNode)||t}if(l)try{return K.apply(n,p.querySelectorAll(l)),n}catch(e){}finally{a===$&&t.removeAttribute(\"id\")}}}return N(e.replace(ae,\"$1\"),t,n,r)}function n(){function e(n,r){return t.push(n+\" \")>C.cacheLength&&delete e[t.shift()],e[n+\" \"]=r}var t=[];return e}function r(e){return e[$]=!0,e}function o(e){var t=L.createElement(\"fieldset\");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function i(e,t){for(var n=e.split(\"|\"),r=n.length;r--;)C.attrHandle[n[r]]=t}function s(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function a(e){return function(t){var n=t.nodeName.toLowerCase();return\"input\"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return(\"input\"===n||\"button\"===n)&&t.type===e}}function c(e){return function(t){return\"form\"in t?t.parentNode&&t.disabled===!1?\"label\"in t?\"label\"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&je(t)===e:t.disabled===e:\"label\"in t&&t.disabled===e}}function l(e){return r(function(t){return t=+t,r(function(n,r){for(var o,i=e([],n.length,t),s=i.length;s--;)n[o=i[s]]&&(n[o]=!(r[o]=n[o]))})})}function f(e){return e&&\"undefined\"!=typeof e.getElementsByTagName&&e}function p(){}function h(e){for(var t=0,n=e.length,r=\"\";t<n;t++)r+=e[t].value;return r}function d(e,t,n){var r=t.dir,o=t.next,i=o||r,s=n&&\"parentNode\"===i,a=_++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||s)return e(t,n,o);return!1}:function(t,n,u){var c,l,f,p=[B,a];if(u){for(;t=t[r];)if((1===t.nodeType||s)&&e(t,n,u))return!0}else for(;t=t[r];)if(1===t.nodeType||s)if(f=t[$]||(t[$]={}),l=f[t.uniqueID]||(f[t.uniqueID]={}),o&&o===t.nodeName.toLowerCase())t=t[r]||t;else{if((c=l[i])&&c[0]===B&&c[1]===a)return p[2]=c[2];if(l[i]=p,p[2]=e(t,n,u))return!0}return!1}}function g(e){return e.length>1?function(t,n,r){for(var o=e.length;o--;)if(!e[o](t,n,r))return!1;return!0}:e[0]}function m(e,n,r){for(var o=0,i=n.length;o<i;o++)t(e,n[o],r);return r}function v(e,t,n,r,o){for(var i,s=[],a=0,u=e.length,c=null!=t;a<u;a++)(i=e[a])&&(n&&!n(i,r,o)||(s.push(i),c&&t.push(a)));return s}function y(e,t,n,o,i,s){return o&&!o[$]&&(o=y(o)),i&&!i[$]&&(i=y(i,s)),r(function(r,s,a,u){var c,l,f,p=[],h=[],d=s.length,g=r||m(t||\"*\",a.nodeType?[a]:a,[]),y=!e||!r&&t?g:v(g,p,e,a,u),x=n?i||(r?e:d||o)?[]:s:y;if(n&&n(y,x,a,u),o)for(c=v(x,h),o(c,[],a,u),l=c.length;l--;)(f=c[l])&&(x[h[l]]=!(y[h[l]]=f));if(r){if(i||e){if(i){for(c=[],l=x.length;l--;)(f=x[l])&&c.push(y[l]=f);i(null,x=[],c,u)}for(l=x.length;l--;)(f=x[l])&&(c=i?ee(r,f):p[l])>-1&&(r[c]=!(s[c]=f))}}else x=v(x===s?x.splice(d,x.length):x),i?i(null,s,x,u):K.apply(s,x)})}function x(e){for(var t,n,r,o=e.length,i=C.relative[e[0].type],s=i||C.relative[\" \"],a=i?1:0,u=d(function(e){return e===t},s,!0),c=d(function(e){return ee(t,e)>-1},s,!0),l=[function(e,n,r){var o=!i&&(r||n!==A)||((t=n).nodeType?u(e,n,r):c(e,n,r));return t=null,o}];a<o;a++)if(n=C.relative[e[a].type])l=[d(g(l),n)];else{if(n=C.filter[e[a].type].apply(null,e[a].matches),n[$]){for(r=++a;r<o&&!C.relative[e[r].type];r++);return y(a>1&&g(l),a>1&&h(e.slice(0,a-1).concat({value:\" \"===e[a-2].type?\"*\":\"\"})).replace(ae,\"$1\"),n,a<r&&x(e.slice(a,r)),r<o&&x(e=e.slice(r)),r<o&&h(e))}l.push(n)}return g(l)}function b(e,n){var o=n.length>0,i=e.length>0,s=function(r,s,a,u,c){var l,f,p,h=0,d=\"0\",g=r&&[],m=[],y=A,x=r||i&&C.find.TAG(\"*\",c),b=B+=null==y?1:Math.random()||.1,w=x.length;for(c&&(A=s===L||s||c);d!==w&&null!=(l=x[d]);d++){if(i&&l){for(f=0,s||l.ownerDocument===L||(O(l),a=!F);p=e[f++];)if(p(l,s||L,a)){u.push(l);break}c&&(B=b)}o&&((l=!p&&l)&&h--,r&&g.push(l))}if(h+=d,o&&d!==h){for(f=0;p=n[f++];)p(g,m,s,a);if(r){if(h>0)for(;d--;)g[d]||m[d]||(m[d]=Q.call(u));m=v(m)}K.apply(u,m),c&&!r&&m.length>0&&h+n.length>1&&t.uniqueSort(u)}return c&&(B=b,A=y),g};return o?r(s):s}var w,T,C,j,k,E,S,N,A,q,D,O,L,H,F,R,I,P,M,$=\"sizzle\"+1*new Date,W=e.document,B=0,_=0,U=n(),z=n(),X=n(),V=function(e,t){return e===t&&(D=!0),0},G={}.hasOwnProperty,Y=[],Q=Y.pop,J=Y.push,K=Y.push,Z=Y.slice,ee=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},te=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",ne=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",re=\"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",oe=\"\\\\[\"+ne+\"*(\"+re+\")(?:\"+ne+\"*([*^$|!~]?=)\"+ne+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+re+\"))|)\"+ne+\"*\\\\]\",ie=\":(\"+re+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+oe+\")*)|.*)\\\\)|)\",se=new RegExp(ne+\"+\",\"g\"),ae=new RegExp(\"^\"+ne+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+ne+\"+$\",\"g\"),ue=new RegExp(\"^\"+ne+\"*,\"+ne+\"*\"),ce=new RegExp(\"^\"+ne+\"*([>+~]|\"+ne+\")\"+ne+\"*\"),le=new RegExp(\"=\"+ne+\"*([^\\\\]'\\\"]*?)\"+ne+\"*\\\\]\",\"g\"),fe=new RegExp(ie),pe=new RegExp(\"^\"+re+\"$\"),he={ID:new RegExp(\"^#(\"+re+\")\"),CLASS:new RegExp(\"^\\\\.(\"+re+\")\"),TAG:new RegExp(\"^(\"+re+\"|[*])\"),ATTR:new RegExp(\"^\"+oe),PSEUDO:new RegExp(\"^\"+ie),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+ne+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+ne+\"*(?:([+-]|)\"+ne+\"*(\\\\d+)|))\"+ne+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+te+\")$\",\"i\"),needsContext:new RegExp(\"^\"+ne+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+ne+\"*((?:-\\\\d)?\\\\d*)\"+ne+\"*\\\\)|)(?=[^-]|$)\",\"i\")},de=/^(?:input|select|textarea|button)$/i,ge=/^h\\d$/i,me=/^[^{]+\\{\\s*\\[native \\w/,ve=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ye=/[+~]/,xe=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+ne+\"?|(\"+ne+\")|.)\",\"ig\"),be=function(e,t,n){var r=\"0x\"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},we=/([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,Te=function(e,t){return t?\"\\0\"===e?\"�\":e.slice(0,-1)+\"\\\\\"+e.charCodeAt(e.length-1).toString(16)+\" \":\"\\\\\"+e},Ce=function(){O()},je=d(function(e){return e.disabled===!0&&(\"form\"in e||\"label\"in e)},{dir:\"parentNode\",next:\"legend\"});try{K.apply(Y=Z.call(W.childNodes),W.childNodes),Y[W.childNodes.length].nodeType}catch(e){K={apply:Y.length?function(e,t){J.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}T=t.support={},k=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&\"HTML\"!==t.nodeName},O=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:W;return r!==L&&9===r.nodeType&&r.documentElement?(L=r,H=L.documentElement,F=!k(L),W!==L&&(n=L.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener(\"unload\",Ce,!1):n.attachEvent&&n.attachEvent(\"onunload\",Ce)),T.attributes=o(function(e){return e.className=\"i\",!e.getAttribute(\"className\")}),T.getElementsByTagName=o(function(e){return e.appendChild(L.createComment(\"\")),!e.getElementsByTagName(\"*\").length}),T.getElementsByClassName=me.test(L.getElementsByClassName),T.getById=o(function(e){return H.appendChild(e).id=$,!L.getElementsByName||!L.getElementsByName($).length}),T.getById?(C.filter.ID=function(e){var t=e.replace(xe,be);return function(e){return e.getAttribute(\"id\")===t}},C.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&F){var n=t.getElementById(e);return n?[n]:[]}}):(C.filter.ID=function(e){var t=e.replace(xe,be);return function(e){var n=\"undefined\"!=typeof e.getAttributeNode&&e.getAttributeNode(\"id\");return n&&n.value===t}},C.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&F){var n,r,o,i=t.getElementById(e);if(i){if(n=i.getAttributeNode(\"id\"),n&&n.value===e)return[i];for(o=t.getElementsByName(e),r=0;i=o[r++];)if(n=i.getAttributeNode(\"id\"),n&&n.value===e)return[i]}return[]}}),C.find.TAG=T.getElementsByTagName?function(e,t){return\"undefined\"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):T.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],o=0,i=t.getElementsByTagName(e);if(\"*\"===e){for(;n=i[o++];)1===n.nodeType&&r.push(n);return r}return i},C.find.CLASS=T.getElementsByClassName&&function(e,t){if(\"undefined\"!=typeof t.getElementsByClassName&&F)return t.getElementsByClassName(e)},I=[],R=[],(T.qsa=me.test(L.querySelectorAll))&&(o(function(e){H.appendChild(e).innerHTML=\"<a id='\"+$+\"'></a><select id='\"+$+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",e.querySelectorAll(\"[msallowcapture^='']\").length&&R.push(\"[*^$]=\"+ne+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\"[selected]\").length||R.push(\"\\\\[\"+ne+\"*(?:value|\"+te+\")\"),e.querySelectorAll(\"[id~=\"+$+\"-]\").length||R.push(\"~=\"),e.querySelectorAll(\":checked\").length||R.push(\":checked\"),e.querySelectorAll(\"a#\"+$+\"+*\").length||R.push(\".#.+[+~]\")}),o(function(e){e.innerHTML=\"<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>\";var t=L.createElement(\"input\");t.setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),e.querySelectorAll(\"[name=d]\").length&&R.push(\"name\"+ne+\"*[*^$|!~]?=\"),2!==e.querySelectorAll(\":enabled\").length&&R.push(\":enabled\",\":disabled\"),H.appendChild(e).disabled=!0,2!==e.querySelectorAll(\":disabled\").length&&R.push(\":enabled\",\":disabled\"),e.querySelectorAll(\"*,:x\"),R.push(\",.*:\")})),(T.matchesSelector=me.test(P=H.matches||H.webkitMatchesSelector||H.mozMatchesSelector||H.oMatchesSelector||H.msMatchesSelector))&&o(function(e){T.disconnectedMatch=P.call(e,\"*\"),P.call(e,\"[s!='']:x\"),I.push(\"!=\",ie)}),R=R.length&&new RegExp(R.join(\"|\")),I=I.length&&new RegExp(I.join(\"|\")),t=me.test(H.compareDocumentPosition),M=t||me.test(H.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},V=t?function(e,t){if(e===t)return D=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!T.sortDetached&&t.compareDocumentPosition(e)===n?e===L||e.ownerDocument===W&&M(W,e)?-1:t===L||t.ownerDocument===W&&M(W,t)?1:q?ee(q,e)-ee(q,t):0:4&n?-1:1)}:function(e,t){if(e===t)return D=!0,0;var n,r=0,o=e.parentNode,i=t.parentNode,a=[e],u=[t];if(!o||!i)return e===L?-1:t===L?1:o?-1:i?1:q?ee(q,e)-ee(q,t):0;if(o===i)return s(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;a[r]===u[r];)r++;return r?s(a[r],u[r]):a[r]===W?-1:u[r]===W?1:0},L):L},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==L&&O(e),n=n.replace(le,\"='$1']\"),T.matchesSelector&&F&&!X[n+\" \"]&&(!I||!I.test(n))&&(!R||!R.test(n)))try{var r=P.call(e,n);if(r||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return t(n,L,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==L&&O(e),M(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==L&&O(e);var n=C.attrHandle[t.toLowerCase()],r=n&&G.call(C.attrHandle,t.toLowerCase())?n(e,t,!F):void 0;return void 0!==r?r:T.attributes||!F?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.escape=function(e){return(e+\"\").replace(we,Te)},t.error=function(e){throw new Error(\"Syntax error, unrecognized expression: \"+e)},t.uniqueSort=function(e){var t,n=[],r=0,o=0;if(D=!T.detectDuplicates,q=!T.sortStable&&e.slice(0),e.sort(V),D){for(;t=e[o++];)t===e[o]&&(r=n.push(o));for(;r--;)e.splice(n[r],1)}return q=null,e},j=t.getText=function(e){var t,n=\"\",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if(\"string\"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=j(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[r++];)n+=j(t);return n},C=t.selectors={cacheLength:50,createPseudo:r,match:he,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(xe,be),e[3]=(e[3]||e[4]||e[5]||\"\").replace(xe,be),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return he.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&fe.test(n)&&(t=E(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(xe,be).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=U[e+\" \"];return t||(t=new RegExp(\"(^|\"+ne+\")\"+e+\"(\"+ne+\"|$)\"))&&U(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||\"undefined\"!=typeof e.getAttribute&&e.getAttribute(\"class\")||\"\")})},ATTR:function(e,n,r){return function(o){var i=t.attr(o,e);return null==i?\"!=\"===n:!n||(i+=\"\",\"=\"===n?i===r:\"!=\"===n?i!==r:\"^=\"===n?r&&0===i.indexOf(r):\"*=\"===n?r&&i.indexOf(r)>-1:\"$=\"===n?r&&i.slice(-r.length)===r:\"~=\"===n?(\" \"+i.replace(se,\" \")+\" \").indexOf(r)>-1:\"|=\"===n&&(i===r||i.slice(0,r.length+1)===r+\"-\"))}},CHILD:function(e,t,n,r,o){var i=\"nth\"!==e.slice(0,3),s=\"last\"!==e.slice(-4),a=\"of-type\"===t;return 1===r&&0===o?function(e){return!!e.parentNode}:function(t,n,u){var c,l,f,p,h,d,g=i!==s?\"nextSibling\":\"previousSibling\",m=t.parentNode,v=a&&t.nodeName.toLowerCase(),y=!u&&!a,x=!1;if(m){if(i){for(;g;){for(p=t;p=p[g];)if(a?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;d=g=\"only\"===e&&!d&&\"nextSibling\"}return!0}if(d=[s?m.firstChild:m.lastChild],s&&y){for(p=m,f=p[$]||(p[$]={}),l=f[p.uniqueID]||(f[p.uniqueID]={}),c=l[e]||[],h=c[0]===B&&c[1],x=h&&c[2],p=h&&m.childNodes[h];p=++h&&p&&p[g]||(x=h=0)||d.pop();)if(1===p.nodeType&&++x&&p===t){l[e]=[B,h,x];break}}else if(y&&(p=t,f=p[$]||(p[$]={}),l=f[p.uniqueID]||(f[p.uniqueID]={}),c=l[e]||[],h=c[0]===B&&c[1],x=h),x===!1)for(;(p=++h&&p&&p[g]||(x=h=0)||d.pop())&&((a?p.nodeName.toLowerCase()!==v:1!==p.nodeType)||!++x||(y&&(f=p[$]||(p[$]={}),l=f[p.uniqueID]||(f[p.uniqueID]={}),l[e]=[B,x]),p!==t)););return x-=o,x===r||x%r===0&&x/r>=0}}},PSEUDO:function(e,n){var o,i=C.pseudos[e]||C.setFilters[e.toLowerCase()]||t.error(\"unsupported pseudo: \"+e);return i[$]?i(n):i.length>1?(o=[e,e,\"\",n],C.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,o=i(e,n),s=o.length;s--;)r=ee(e,o[s]),e[r]=!(t[r]=o[s])}):function(e){return i(e,0,o)}):i}},pseudos:{not:r(function(e){var t=[],n=[],o=S(e.replace(ae,\"$1\"));return o[$]?r(function(e,t,n,r){for(var i,s=o(e,null,r,[]),a=e.length;a--;)(i=s[a])&&(e[a]=!(t[a]=i))}):function(e,r,i){return t[0]=e,o(t,null,i,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){\nreturn t(e,n).length>0}}),contains:r(function(e){return e=e.replace(xe,be),function(t){return(t.textContent||t.innerText||j(t)).indexOf(e)>-1}}),lang:r(function(e){return pe.test(e||\"\")||t.error(\"unsupported lang: \"+e),e=e.replace(xe,be).toLowerCase(),function(t){var n;do if(n=F?t.lang:t.getAttribute(\"xml:lang\")||t.getAttribute(\"lang\"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+\"-\");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===H},focus:function(e){return e===L.activeElement&&(!L.hasFocus||L.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:c(!1),disabled:c(!0),checked:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&!!e.checked||\"option\"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!C.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return de.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&\"button\"===e.type||\"button\"===t},text:function(e){var t;return\"input\"===e.nodeName.toLowerCase()&&\"text\"===e.type&&(null==(t=e.getAttribute(\"type\"))||\"text\"===t.toLowerCase())},first:l(function(){return[0]}),last:l(function(e,t){return[t-1]}),eq:l(function(e,t,n){return[n<0?n+t:n]}),even:l(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:l(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:l(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:l(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},C.pseudos.nth=C.pseudos.eq;for(w in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})C.pseudos[w]=a(w);for(w in{submit:!0,reset:!0})C.pseudos[w]=u(w);return p.prototype=C.filters=C.pseudos,C.setFilters=new p,E=t.tokenize=function(e,n){var r,o,i,s,a,u,c,l=z[e+\" \"];if(l)return n?0:l.slice(0);for(a=e,u=[],c=C.preFilter;a;){r&&!(o=ue.exec(a))||(o&&(a=a.slice(o[0].length)||a),u.push(i=[])),r=!1,(o=ce.exec(a))&&(r=o.shift(),i.push({value:r,type:o[0].replace(ae,\" \")}),a=a.slice(r.length));for(s in C.filter)!(o=he[s].exec(a))||c[s]&&!(o=c[s](o))||(r=o.shift(),i.push({value:r,type:s,matches:o}),a=a.slice(r.length));if(!r)break}return n?a.length:a?t.error(e):z(e,u).slice(0)},S=t.compile=function(e,t){var n,r=[],o=[],i=X[e+\" \"];if(!i){for(t||(t=E(e)),n=t.length;n--;)i=x(t[n]),i[$]?r.push(i):o.push(i);i=X(e,b(o,r)),i.selector=e}return i},N=t.select=function(e,t,n,r){var o,i,s,a,u,c=\"function\"==typeof e&&e,l=!r&&E(e=c.selector||e);if(n=n||[],1===l.length){if(i=l[0]=l[0].slice(0),i.length>2&&\"ID\"===(s=i[0]).type&&9===t.nodeType&&F&&C.relative[i[1].type]){if(t=(C.find.ID(s.matches[0].replace(xe,be),t)||[])[0],!t)return n;c&&(t=t.parentNode),e=e.slice(i.shift().value.length)}for(o=he.needsContext.test(e)?0:i.length;o--&&(s=i[o],!C.relative[a=s.type]);)if((u=C.find[a])&&(r=u(s.matches[0].replace(xe,be),ye.test(i[0].type)&&f(t.parentNode)||t))){if(i.splice(o,1),e=r.length&&h(i),!e)return K.apply(n,r),n;break}}return(c||S(e,l))(r,t,!F,n,!t||ye.test(e)&&f(t.parentNode)||t),n},T.sortStable=$.split(\"\").sort(V).join(\"\")===$,T.detectDuplicates=!!D,O(),T.sortDetached=o(function(e){return 1&e.compareDocumentPosition(L.createElement(\"fieldset\"))}),o(function(e){return e.innerHTML=\"<a href='#'></a>\",\"#\"===e.firstChild.getAttribute(\"href\")})||i(\"type|href|height|width\",function(e,t,n){if(!n)return e.getAttribute(t,\"type\"===t.toLowerCase()?1:2)}),T.attributes&&o(function(e){return e.innerHTML=\"<input/>\",e.firstChild.setAttribute(\"value\",\"\"),\"\"===e.firstChild.getAttribute(\"value\")})||i(\"value\",function(e,t,n){if(!n&&\"input\"===e.nodeName.toLowerCase())return e.defaultValue}),o(function(e){return null==e.getAttribute(\"disabled\")})||i(te,function(e,t,n){var r;if(!n)return e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);de.find=xe,de.expr=xe.selectors,de.expr[\":\"]=de.expr.pseudos,de.uniqueSort=de.unique=xe.uniqueSort,de.text=xe.getText,de.isXMLDoc=xe.isXML,de.contains=xe.contains,de.escapeSelector=xe.escape;var be=function(e,t,n){for(var r=[],o=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(o&&de(e).is(n))break;r.push(e)}return r},we=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},Te=de.expr.match.needsContext,Ce=/^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i,je=/^.[^:#\\[\\.,]*$/;de.filter=function(e,t,n){var r=t[0];return n&&(e=\":not(\"+e+\")\"),1===t.length&&1===r.nodeType?de.find.matchesSelector(r,e)?[r]:[]:de.find.matches(e,de.grep(t,function(e){return 1===e.nodeType}))},de.fn.extend({find:function(e){var t,n,r=this.length,o=this;if(\"string\"!=typeof e)return this.pushStack(de(e).filter(function(){for(t=0;t<r;t++)if(de.contains(o[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)de.find(e,o[t],n);return r>1?de.uniqueSort(n):n},filter:function(e){return this.pushStack(o(this,e||[],!1))},not:function(e){return this.pushStack(o(this,e||[],!0))},is:function(e){return!!o(this,\"string\"==typeof e&&Te.test(e)?de(e):e||[],!1).length}});var ke,Ee=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,Se=de.fn.init=function(e,t,n){var r,o;if(!e)return this;if(n=n||ke,\"string\"==typeof e){if(r=\"<\"===e[0]&&\">\"===e[e.length-1]&&e.length>=3?[null,e,null]:Ee.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof de?t[0]:t,de.merge(this,de.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:te,!0)),Ce.test(r[1])&&de.isPlainObject(t))for(r in t)de.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return o=te.getElementById(r[2]),o&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):de.isFunction(e)?void 0!==n.ready?n.ready(e):e(de):de.makeArray(e,this)};Se.prototype=de.fn,ke=de(te);var Ne=/^(?:parents|prev(?:Until|All))/,Ae={children:!0,contents:!0,next:!0,prev:!0};de.fn.extend({has:function(e){var t=de(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(de.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,o=this.length,i=[],s=\"string\"!=typeof e&&de(e);if(!Te.test(e))for(;r<o;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(s?s.index(n)>-1:1===n.nodeType&&de.find.matchesSelector(n,e))){i.push(n);break}return this.pushStack(i.length>1?de.uniqueSort(i):i)},index:function(e){return e?\"string\"==typeof e?se.call(de(e),this[0]):se.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(de.uniqueSort(de.merge(this.get(),de(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),de.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return be(e,\"parentNode\")},parentsUntil:function(e,t,n){return be(e,\"parentNode\",n)},next:function(e){return i(e,\"nextSibling\")},prev:function(e){return i(e,\"previousSibling\")},nextAll:function(e){return be(e,\"nextSibling\")},prevAll:function(e){return be(e,\"previousSibling\")},nextUntil:function(e,t,n){return be(e,\"nextSibling\",n)},prevUntil:function(e,t,n){return be(e,\"previousSibling\",n)},siblings:function(e){return we((e.parentNode||{}).firstChild,e)},children:function(e){return we(e.firstChild)},contents:function(e){return e.contentDocument||de.merge([],e.childNodes)}},function(e,t){de.fn[e]=function(n,r){var o=de.map(this,t,n);return\"Until\"!==e.slice(-5)&&(r=n),r&&\"string\"==typeof r&&(o=de.filter(r,o)),this.length>1&&(Ae[e]||de.uniqueSort(o),Ne.test(e)&&o.reverse()),this.pushStack(o)}});var qe=/[^\\x20\\t\\r\\n\\f]+/g;de.Callbacks=function(e){e=\"string\"==typeof e?s(e):de.extend({},e);var t,n,r,o,i=[],a=[],u=-1,c=function(){for(o=e.once,r=t=!0;a.length;u=-1)for(n=a.shift();++u<i.length;)i[u].apply(n[0],n[1])===!1&&e.stopOnFalse&&(u=i.length,n=!1);e.memory||(n=!1),t=!1,o&&(i=n?[]:\"\")},l={add:function(){return i&&(n&&!t&&(u=i.length-1,a.push(n)),function t(n){de.each(n,function(n,r){de.isFunction(r)?e.unique&&l.has(r)||i.push(r):r&&r.length&&\"string\"!==de.type(r)&&t(r)})}(arguments),n&&!t&&c()),this},remove:function(){return de.each(arguments,function(e,t){for(var n;(n=de.inArray(t,i,n))>-1;)i.splice(n,1),n<=u&&u--}),this},has:function(e){return e?de.inArray(e,i)>-1:i.length>0},empty:function(){return i&&(i=[]),this},disable:function(){return o=a=[],i=n=\"\",this},disabled:function(){return!i},lock:function(){return o=a=[],n||t||(i=n=\"\"),this},locked:function(){return!!o},fireWith:function(e,n){return o||(n=n||[],n=[e,n.slice?n.slice():n],a.push(n),t||c()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l},de.extend({Deferred:function(t){var n=[[\"notify\",\"progress\",de.Callbacks(\"memory\"),de.Callbacks(\"memory\"),2],[\"resolve\",\"done\",de.Callbacks(\"once memory\"),de.Callbacks(\"once memory\"),0,\"resolved\"],[\"reject\",\"fail\",de.Callbacks(\"once memory\"),de.Callbacks(\"once memory\"),1,\"rejected\"]],r=\"pending\",o={state:function(){return r},always:function(){return i.done(arguments).fail(arguments),this},catch:function(e){return o.then(null,e)},pipe:function(){var e=arguments;return de.Deferred(function(t){de.each(n,function(n,r){var o=de.isFunction(e[r[4]])&&e[r[4]];i[r[1]](function(){var e=o&&o.apply(this,arguments);e&&de.isFunction(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+\"With\"](this,o?[e]:arguments)})}),e=null}).promise()},then:function(t,r,o){function i(t,n,r,o){return function(){var c=this,l=arguments,f=function(){var e,f;if(!(t<s)){if(e=r.apply(c,l),e===n.promise())throw new TypeError(\"Thenable self-resolution\");f=e&&(\"object\"==typeof e||\"function\"==typeof e)&&e.then,de.isFunction(f)?o?f.call(e,i(s,n,a,o),i(s,n,u,o)):(s++,f.call(e,i(s,n,a,o),i(s,n,u,o),i(s,n,a,n.notifyWith))):(r!==a&&(c=void 0,l=[e]),(o||n.resolveWith)(c,l))}},p=o?f:function(){try{f()}catch(e){de.Deferred.exceptionHook&&de.Deferred.exceptionHook(e,p.stackTrace),t+1>=s&&(r!==u&&(c=void 0,l=[e]),n.rejectWith(c,l))}};t?p():(de.Deferred.getStackHook&&(p.stackTrace=de.Deferred.getStackHook()),e.setTimeout(p))}}var s=0;return de.Deferred(function(e){n[0][3].add(i(0,e,de.isFunction(o)?o:a,e.notifyWith)),n[1][3].add(i(0,e,de.isFunction(t)?t:a)),n[2][3].add(i(0,e,de.isFunction(r)?r:u))}).promise()},promise:function(e){return null!=e?de.extend(e,o):o}},i={};return de.each(n,function(e,t){var s=t[2],a=t[5];o[t[1]]=s.add,a&&s.add(function(){r=a},n[3-e][2].disable,n[0][2].lock),s.add(t[3].fire),i[t[0]]=function(){return i[t[0]+\"With\"](this===i?void 0:this,arguments),this},i[t[0]+\"With\"]=s.fireWith}),o.promise(i),t&&t.call(i,i),i},when:function(e){var t=arguments.length,n=t,r=Array(n),o=re.call(arguments),i=de.Deferred(),s=function(e){return function(n){r[e]=this,o[e]=arguments.length>1?re.call(arguments):n,--t||i.resolveWith(r,o)}};if(t<=1&&(c(e,i.done(s(n)).resolve,i.reject),\"pending\"===i.state()||de.isFunction(o[n]&&o[n].then)))return i.then();for(;n--;)c(o[n],s(n),i.reject);return i.promise()}});var De=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;de.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&De.test(t.name)&&e.console.warn(\"jQuery.Deferred exception: \"+t.message,t.stack,n)},de.readyException=function(t){e.setTimeout(function(){throw t})};var Oe=de.Deferred();de.fn.ready=function(e){return Oe.then(e).catch(function(e){de.readyException(e)}),this},de.extend({isReady:!1,readyWait:1,holdReady:function(e){e?de.readyWait++:de.ready(!0)},ready:function(e){(e===!0?--de.readyWait:de.isReady)||(de.isReady=!0,e!==!0&&--de.readyWait>0||Oe.resolveWith(te,[de]))}}),de.ready.then=Oe.then,\"complete\"===te.readyState||\"loading\"!==te.readyState&&!te.documentElement.doScroll?e.setTimeout(de.ready):(te.addEventListener(\"DOMContentLoaded\",l),e.addEventListener(\"load\",l));var Le=function(e,t,n,r,o,i,s){var a=0,u=e.length,c=null==n;if(\"object\"===de.type(n)){o=!0;for(a in n)Le(e,t,a,n[a],!0,i,s)}else if(void 0!==r&&(o=!0,de.isFunction(r)||(s=!0),c&&(s?(t.call(e,r),t=null):(c=t,t=function(e,t,n){return c.call(de(e),n)})),t))for(;a<u;a++)t(e[a],n,s?r:r.call(e[a],a,t(e[a],n)));return o?e:c?t.call(e):u?t(e[0],n):i},He=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};f.uid=1,f.prototype={cache:function(e){var t=e[this.expando];return t||(t={},He(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,o=this.cache(e);if(\"string\"==typeof t)o[de.camelCase(t)]=n;else for(r in t)o[de.camelCase(r)]=t[r];return o},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][de.camelCase(t)]},access:function(e,t,n){return void 0===t||t&&\"string\"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){de.isArray(t)?t=t.map(de.camelCase):(t=de.camelCase(t),t=t in r?[t]:t.match(qe)||[]),n=t.length;for(;n--;)delete r[t[n]]}(void 0===t||de.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!de.isEmptyObject(t)}};var Fe=new f,Re=new f,Ie=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,Pe=/[A-Z]/g;de.extend({hasData:function(e){return Re.hasData(e)||Fe.hasData(e)},data:function(e,t,n){return Re.access(e,t,n)},removeData:function(e,t){Re.remove(e,t)},_data:function(e,t,n){return Fe.access(e,t,n)},_removeData:function(e,t){Fe.remove(e,t)}}),de.fn.extend({data:function(e,t){var n,r,o,i=this[0],s=i&&i.attributes;if(void 0===e){if(this.length&&(o=Re.get(i),1===i.nodeType&&!Fe.get(i,\"hasDataAttrs\"))){for(n=s.length;n--;)s[n]&&(r=s[n].name,0===r.indexOf(\"data-\")&&(r=de.camelCase(r.slice(5)),h(i,r,o[r])));Fe.set(i,\"hasDataAttrs\",!0)}return o}return\"object\"==typeof e?this.each(function(){Re.set(this,e)}):Le(this,function(t){var n;if(i&&void 0===t){if(n=Re.get(i,e),void 0!==n)return n;if(n=h(i,e),void 0!==n)return n}else this.each(function(){Re.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){Re.remove(this,e)})}}),de.extend({queue:function(e,t,n){var r;if(e)return t=(t||\"fx\")+\"queue\",r=Fe.get(e,t),n&&(!r||de.isArray(n)?r=Fe.access(e,t,de.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||\"fx\";var n=de.queue(e,t),r=n.length,o=n.shift(),i=de._queueHooks(e,t),s=function(){de.dequeue(e,t)};\"inprogress\"===o&&(o=n.shift(),r--),o&&(\"fx\"===t&&n.unshift(\"inprogress\"),delete i.stop,o.call(e,s,i)),!r&&i&&i.empty.fire()},_queueHooks:function(e,t){var n=t+\"queueHooks\";return Fe.get(e,n)||Fe.access(e,n,{empty:de.Callbacks(\"once memory\").add(function(){Fe.remove(e,[t+\"queue\",n])})})}}),de.fn.extend({queue:function(e,t){var n=2;return\"string\"!=typeof e&&(t=e,e=\"fx\",n--),arguments.length<n?de.queue(this[0],e):void 0===t?this:this.each(function(){var n=de.queue(this,e,t);de._queueHooks(this,e),\"fx\"===e&&\"inprogress\"!==n[0]&&de.dequeue(this,e)})},dequeue:function(e){return this.each(function(){de.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||\"fx\",[])},promise:function(e,t){var n,r=1,o=de.Deferred(),i=this,s=this.length,a=function(){--r||o.resolveWith(i,[i])};for(\"string\"!=typeof e&&(t=e,e=void 0),e=e||\"fx\";s--;)n=Fe.get(i[s],e+\"queueHooks\"),n&&n.empty&&(r++,n.empty.add(a));return a(),o.promise(t)}});var Me=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,$e=new RegExp(\"^(?:([+-])=|)(\"+Me+\")([a-z%]*)$\",\"i\"),We=[\"Top\",\"Right\",\"Bottom\",\"Left\"],Be=function(e,t){return e=t||e,\"none\"===e.style.display||\"\"===e.style.display&&de.contains(e.ownerDocument,e)&&\"none\"===de.css(e,\"display\")},_e=function(e,t,n,r){var o,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];o=n.apply(e,r||[]);for(i in t)e.style[i]=s[i];return o},Ue={};de.fn.extend({show:function(){return m(this,!0)},hide:function(){return m(this)},toggle:function(e){return\"boolean\"==typeof e?e?this.show():this.hide():this.each(function(){Be(this)?de(this).show():de(this).hide()})}});var ze=/^(?:checkbox|radio)$/i,Xe=/<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]+)/i,Ve=/^$|\\/(?:java|ecma)script/i,Ge={option:[1,\"<select multiple='multiple'>\",\"</select>\"],thead:[1,\"<table>\",\"</table>\"],col:[2,\"<table><colgroup>\",\"</colgroup></table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:[0,\"\",\"\"]};Ge.optgroup=Ge.option,Ge.tbody=Ge.tfoot=Ge.colgroup=Ge.caption=Ge.thead,Ge.th=Ge.td;var Ye=/<|&#?\\w+;/;!function(){var e=te.createDocumentFragment(),t=e.appendChild(te.createElement(\"div\")),n=te.createElement(\"input\");n.setAttribute(\"type\",\"radio\"),n.setAttribute(\"checked\",\"checked\"),n.setAttribute(\"name\",\"t\"),t.appendChild(n),pe.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML=\"<textarea>x</textarea>\",pe.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var Qe=te.documentElement,Je=/^key/,Ke=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ze=/^([^.]*)(?:\\.(.+)|)/;de.event={global:{},add:function(e,t,n,r,o){var i,s,a,u,c,l,f,p,h,d,g,m=Fe.get(e);if(m)for(n.handler&&(i=n,n=i.handler,o=i.selector),o&&de.find.matchesSelector(Qe,o),n.guid||(n.guid=de.guid++),(u=m.events)||(u=m.events={}),(s=m.handle)||(s=m.handle=function(t){return\"undefined\"!=typeof de&&de.event.triggered!==t.type?de.event.dispatch.apply(e,arguments):void 0}),t=(t||\"\").match(qe)||[\"\"],c=t.length;c--;)a=Ze.exec(t[c])||[],h=g=a[1],d=(a[2]||\"\").split(\".\").sort(),h&&(f=de.event.special[h]||{},h=(o?f.delegateType:f.bindType)||h,f=de.event.special[h]||{},l=de.extend({type:h,origType:g,data:r,handler:n,guid:n.guid,selector:o,needsContext:o&&de.expr.match.needsContext.test(o),namespace:d.join(\".\")},i),(p=u[h])||(p=u[h]=[],p.delegateCount=0,f.setup&&f.setup.call(e,r,d,s)!==!1||e.addEventListener&&e.addEventListener(h,s)),f.add&&(f.add.call(e,l),l.handler.guid||(l.handler.guid=n.guid)),o?p.splice(p.delegateCount++,0,l):p.push(l),de.event.global[h]=!0)},remove:function(e,t,n,r,o){var i,s,a,u,c,l,f,p,h,d,g,m=Fe.hasData(e)&&Fe.get(e);if(m&&(u=m.events)){for(t=(t||\"\").match(qe)||[\"\"],c=t.length;c--;)if(a=Ze.exec(t[c])||[],h=g=a[1],d=(a[2]||\"\").split(\".\").sort(),h){for(f=de.event.special[h]||{},h=(r?f.delegateType:f.bindType)||h,p=u[h]||[],a=a[2]&&new RegExp(\"(^|\\\\.)\"+d.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),s=i=p.length;i--;)l=p[i],!o&&g!==l.origType||n&&n.guid!==l.guid||a&&!a.test(l.namespace)||r&&r!==l.selector&&(\"**\"!==r||!l.selector)||(p.splice(i,1),l.selector&&p.delegateCount--,f.remove&&f.remove.call(e,l));s&&!p.length&&(f.teardown&&f.teardown.call(e,d,m.handle)!==!1||de.removeEvent(e,h,m.handle),delete u[h])}else for(h in u)de.event.remove(e,h+t[c],n,r,!0);de.isEmptyObject(u)&&Fe.remove(e,\"handle events\")}},dispatch:function(e){var t,n,r,o,i,s,a=de.event.fix(e),u=new Array(arguments.length),c=(Fe.get(this,\"events\")||{})[a.type]||[],l=de.event.special[a.type]||{};for(u[0]=a,t=1;t<arguments.length;t++)u[t]=arguments[t];if(a.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,a)!==!1){for(s=de.event.handlers.call(this,a,c),t=0;(o=s[t++])&&!a.isPropagationStopped();)for(a.currentTarget=o.elem,n=0;(i=o.handlers[n++])&&!a.isImmediatePropagationStopped();)a.rnamespace&&!a.rnamespace.test(i.namespace)||(a.handleObj=i,a.data=i.data,r=((de.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),void 0!==r&&(a.result=r)===!1&&(a.preventDefault(),a.stopPropagation()));return l.postDispatch&&l.postDispatch.call(this,a),a.result}},handlers:function(e,t){var n,r,o,i,s,a=[],u=t.delegateCount,c=e.target;if(u&&c.nodeType&&!(\"click\"===e.type&&e.button>=1))for(;c!==this;c=c.parentNode||this)if(1===c.nodeType&&(\"click\"!==e.type||c.disabled!==!0)){for(i=[],s={},n=0;n<u;n++)r=t[n],o=r.selector+\" \",void 0===s[o]&&(s[o]=r.needsContext?de(o,this).index(c)>-1:de.find(o,this,null,[c]).length),s[o]&&i.push(r);i.length&&a.push({elem:c,handlers:i})}return c=this,u<t.length&&a.push({elem:c,handlers:t.slice(u)}),a},addProp:function(e,t){Object.defineProperty(de.Event.prototype,e,{enumerable:!0,configurable:!0,get:de.isFunction(t)?function(){if(this.originalEvent)return t(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[e]},set:function(t){Object.defineProperty(this,e,{enumerable:!0,configurable:!0,writable:!0,value:t})}})},fix:function(e){return e[de.expando]?e:new de.Event(e)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==T()&&this.focus)return this.focus(),!1},delegateType:\"focusin\"},blur:{trigger:function(){if(this===T()&&this.blur)return this.blur(),!1},delegateType:\"focusout\"},click:{trigger:function(){if(\"checkbox\"===this.type&&this.click&&de.nodeName(this,\"input\"))return this.click(),!1},_default:function(e){return de.nodeName(e.target,\"a\")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},de.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},de.Event=function(e,t){return this instanceof de.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&e.returnValue===!1?b:w,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&de.extend(this,t),this.timeStamp=e&&e.timeStamp||de.now(),void(this[de.expando]=!0)):new de.Event(e,t)},de.Event.prototype={constructor:de.Event,isDefaultPrevented:w,isPropagationStopped:w,isImmediatePropagationStopped:w,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=b,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=b,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=b,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},de.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,char:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&Je.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&Ke.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},de.event.addProp),de.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(e,t){de.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,o=e.relatedTarget,i=e.handleObj;return o&&(o===r||de.contains(r,o))||(e.type=i.origType,n=i.handler.apply(this,arguments),e.type=t),n}}}),de.fn.extend({on:function(e,t,n,r){return C(this,e,t,n,r)},one:function(e,t,n,r){return C(this,e,t,n,r,1)},off:function(e,t,n){var r,o;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,de(e.delegateTarget).off(r.namespace?r.origType+\".\"+r.namespace:r.origType,r.selector,r.handler),this;if(\"object\"==typeof e){for(o in e)this.off(o,t,e[o]);return this}return t!==!1&&\"function\"!=typeof t||(n=t,t=void 0),n===!1&&(n=w),this.each(function(){de.event.remove(this,e,n,t)})}});var et=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,tt=/<script|<style|<link/i,nt=/checked\\s*(?:[^=]|=\\s*.checked.)/i,rt=/^true\\/(.*)/,ot=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;de.extend({htmlPrefilter:function(e){return e.replace(et,\"<$1></$2>\")},clone:function(e,t,n){var r,o,i,s,a=e.cloneNode(!0),u=de.contains(e.ownerDocument,e);if(!(pe.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||de.isXMLDoc(e)))for(s=v(a),i=v(e),r=0,o=i.length;r<o;r++)N(i[r],s[r]);if(t)if(n)for(i=i||v(e),s=s||v(a),r=0,o=i.length;r<o;r++)S(i[r],s[r]);else S(e,a);return s=v(a,\"script\"),s.length>0&&y(s,!u&&v(e,\"script\")),a},cleanData:function(e){for(var t,n,r,o=de.event.special,i=0;void 0!==(n=e[i]);i++)if(He(n)){if(t=n[Fe.expando]){if(t.events)for(r in t.events)o[r]?de.event.remove(n,r):de.removeEvent(n,r,t.handle);n[Fe.expando]=void 0}n[Re.expando]&&(n[Re.expando]=void 0)}}}),de.fn.extend({detach:function(e){return q(this,e,!0)},remove:function(e){return q(this,e)},text:function(e){return Le(this,function(e){return void 0===e?de.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return A(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=j(this,e);t.appendChild(e)}})},prepend:function(){return A(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=j(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return A(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return A(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(de.cleanData(v(e,!1)),e.textContent=\"\");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return de.clone(this,e,t)})},html:function(e){return Le(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if(\"string\"==typeof e&&!tt.test(e)&&!Ge[(Xe.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=de.htmlPrefilter(e);try{for(;n<r;n++)t=this[n]||{},1===t.nodeType&&(de.cleanData(v(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return A(this,arguments,function(t){var n=this.parentNode;de.inArray(this,e)<0&&(de.cleanData(v(this)),n&&n.replaceChild(t,this))},e)}}),de.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(e,t){de.fn[e]=function(e){for(var n,r=[],o=de(e),i=o.length-1,s=0;s<=i;s++)n=s===i?this:this.clone(!0),de(o[s])[t](n),ie.apply(r,n.get());return this.pushStack(r)}});var it=/^margin/,st=new RegExp(\"^(\"+Me+\")(?!px)[a-z%]+$\",\"i\"),at=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)};!function(){function t(){if(a){a.style.cssText=\"box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%\",a.innerHTML=\"\",Qe.appendChild(s);var t=e.getComputedStyle(a);n=\"1%\"!==t.top,i=\"2px\"===t.marginLeft,r=\"4px\"===t.width,a.style.marginRight=\"50%\",o=\"4px\"===t.marginRight,Qe.removeChild(s),a=null}}var n,r,o,i,s=te.createElement(\"div\"),a=te.createElement(\"div\");a.style&&(a.style.backgroundClip=\"content-box\",a.cloneNode(!0).style.backgroundClip=\"\",pe.clearCloneStyle=\"content-box\"===a.style.backgroundClip,s.style.cssText=\"border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute\",s.appendChild(a),de.extend(pe,{pixelPosition:function(){return t(),n},boxSizingReliable:function(){return t(),r},pixelMarginRight:function(){return t(),o},reliableMarginLeft:function(){return t(),i}}))}();var ut=/^(none|table(?!-c[ea]).+)/,ct={position:\"absolute\",visibility:\"hidden\",display:\"block\"},lt={letterSpacing:\"0\",fontWeight:\"400\"},ft=[\"Webkit\",\"Moz\",\"ms\"],pt=te.createElement(\"div\").style;de.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=D(e,\"opacity\");return\"\"===n?\"1\":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{float:\"cssFloat\"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,i,s,a=de.camelCase(t),u=e.style;return t=de.cssProps[a]||(de.cssProps[a]=L(a)||a),s=de.cssHooks[t]||de.cssHooks[a],void 0===n?s&&\"get\"in s&&void 0!==(o=s.get(e,!1,r))?o:u[t]:(i=typeof n,\"string\"===i&&(o=$e.exec(n))&&o[1]&&(n=d(e,t,o),i=\"number\"),null!=n&&n===n&&(\"number\"===i&&(n+=o&&o[3]||(de.cssNumber[a]?\"\":\"px\")),pe.clearCloneStyle||\"\"!==n||0!==t.indexOf(\"background\")||(u[t]=\"inherit\"),s&&\"set\"in s&&void 0===(n=s.set(e,n,r))||(u[t]=n)),void 0)}},css:function(e,t,n,r){var o,i,s,a=de.camelCase(t);return t=de.cssProps[a]||(de.cssProps[a]=L(a)||a),s=de.cssHooks[t]||de.cssHooks[a],s&&\"get\"in s&&(o=s.get(e,!0,n)),void 0===o&&(o=D(e,t,r)),\"normal\"===o&&t in lt&&(o=lt[t]),\"\"===n||n?(i=parseFloat(o),n===!0||isFinite(i)?i||0:o):o}}),de.each([\"height\",\"width\"],function(e,t){de.cssHooks[t]={get:function(e,n,r){if(n)return!ut.test(de.css(e,\"display\"))||e.getClientRects().length&&e.getBoundingClientRect().width?R(e,t,r):_e(e,ct,function(){return R(e,t,r)})},set:function(e,n,r){var o,i=r&&at(e),s=r&&F(e,t,r,\"border-box\"===de.css(e,\"boxSizing\",!1,i),i);return s&&(o=$e.exec(n))&&\"px\"!==(o[3]||\"px\")&&(e.style[t]=n,n=de.css(e,t)),H(e,n,s)}}}),de.cssHooks.marginLeft=O(pe.reliableMarginLeft,function(e,t){if(t)return(parseFloat(D(e,\"marginLeft\"))||e.getBoundingClientRect().left-_e(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+\"px\"}),de.each({margin:\"\",padding:\"\",border:\"Width\"},function(e,t){de.cssHooks[e+t]={expand:function(n){for(var r=0,o={},i=\"string\"==typeof n?n.split(\" \"):[n];r<4;r++)o[e+We[r]+t]=i[r]||i[r-2]||i[0];return o}},it.test(e)||(de.cssHooks[e+t].set=H)}),de.fn.extend({css:function(e,t){return Le(this,function(e,t,n){var r,o,i={},s=0;if(de.isArray(t)){for(r=at(e),o=t.length;s<o;s++)i[t[s]]=de.css(e,t[s],!1,r);return i}return void 0!==n?de.style(e,t,n):de.css(e,t)},e,t,arguments.length>1)}}),de.Tween=I,I.prototype={constructor:I,init:function(e,t,n,r,o,i){this.elem=e,this.prop=n,this.easing=o||de.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=i||(de.cssNumber[n]?\"\":\"px\")},cur:function(){var e=I.propHooks[this.prop];return e&&e.get?e.get(this):I.propHooks._default.get(this)},run:function(e){var t,n=I.propHooks[this.prop];return this.options.duration?this.pos=t=de.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):I.propHooks._default.set(this),this}},I.prototype.init.prototype=I.prototype,I.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=de.css(e.elem,e.prop,\"\"),t&&\"auto\"!==t?t:0)},set:function(e){de.fx.step[e.prop]?de.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[de.cssProps[e.prop]]&&!de.cssHooks[e.prop]?e.elem[e.prop]=e.now:de.style(e.elem,e.prop,e.now+e.unit)}}},I.propHooks.scrollTop=I.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},de.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:\"swing\"},de.fx=I.prototype.init,de.fx.step={};var ht,dt,gt=/^(?:toggle|show|hide)$/,mt=/queueHooks$/;de.Animation=de.extend(U,{tweeners:{\"*\":[function(e,t){var n=this.createTween(e,t);return d(n.elem,e,$e.exec(t),n),n}]},tweener:function(e,t){de.isFunction(e)?(t=e,e=[\"*\"]):e=e.match(qe);for(var n,r=0,o=e.length;r<o;r++)n=e[r],U.tweeners[n]=U.tweeners[n]||[],U.tweeners[n].unshift(t)},prefilters:[B],prefilter:function(e,t){t?U.prefilters.unshift(e):U.prefilters.push(e)}}),de.speed=function(e,t,n){var r=e&&\"object\"==typeof e?de.extend({},e):{complete:n||!n&&t||de.isFunction(e)&&e,duration:e,easing:n&&t||t&&!de.isFunction(t)&&t};return de.fx.off||te.hidden?r.duration=0:\"number\"!=typeof r.duration&&(r.duration in de.fx.speeds?r.duration=de.fx.speeds[r.duration]:r.duration=de.fx.speeds._default),null!=r.queue&&r.queue!==!0||(r.queue=\"fx\"),r.old=r.complete,r.complete=function(){de.isFunction(r.old)&&r.old.call(this),r.queue&&de.dequeue(this,r.queue)},r},de.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Be).css(\"opacity\",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){\nvar o=de.isEmptyObject(e),i=de.speed(t,n,r),s=function(){var t=U(this,de.extend({},e),i);(o||Fe.get(this,\"finish\"))&&t.stop(!0)};return s.finish=s,o||i.queue===!1?this.each(s):this.queue(i.queue,s)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return\"string\"!=typeof e&&(n=t,t=e,e=void 0),t&&e!==!1&&this.queue(e||\"fx\",[]),this.each(function(){var t=!0,o=null!=e&&e+\"queueHooks\",i=de.timers,s=Fe.get(this);if(o)s[o]&&s[o].stop&&r(s[o]);else for(o in s)s[o]&&s[o].stop&&mt.test(o)&&r(s[o]);for(o=i.length;o--;)i[o].elem!==this||null!=e&&i[o].queue!==e||(i[o].anim.stop(n),t=!1,i.splice(o,1));!t&&n||de.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||\"fx\"),this.each(function(){var t,n=Fe.get(this),r=n[e+\"queue\"],o=n[e+\"queueHooks\"],i=de.timers,s=r?r.length:0;for(n.finish=!0,de.queue(this,e,[]),o&&o.stop&&o.stop.call(this,!0),t=i.length;t--;)i[t].elem===this&&i[t].queue===e&&(i[t].anim.stop(!0),i.splice(t,1));for(t=0;t<s;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),de.each([\"toggle\",\"show\",\"hide\"],function(e,t){var n=de.fn[t];de.fn[t]=function(e,r,o){return null==e||\"boolean\"==typeof e?n.apply(this,arguments):this.animate($(t,!0),e,r,o)}}),de.each({slideDown:$(\"show\"),slideUp:$(\"hide\"),slideToggle:$(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(e,t){de.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),de.timers=[],de.fx.tick=function(){var e,t=0,n=de.timers;for(ht=de.now();t<n.length;t++)e=n[t],e()||n[t]!==e||n.splice(t--,1);n.length||de.fx.stop(),ht=void 0},de.fx.timer=function(e){de.timers.push(e),e()?de.fx.start():de.timers.pop()},de.fx.interval=13,de.fx.start=function(){dt||(dt=e.requestAnimationFrame?e.requestAnimationFrame(P):e.setInterval(de.fx.tick,de.fx.interval))},de.fx.stop=function(){e.cancelAnimationFrame?e.cancelAnimationFrame(dt):e.clearInterval(dt),dt=null},de.fx.speeds={slow:600,fast:200,_default:400},de.fn.delay=function(t,n){return t=de.fx?de.fx.speeds[t]||t:t,n=n||\"fx\",this.queue(n,function(n,r){var o=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(o)}})},function(){var e=te.createElement(\"input\"),t=te.createElement(\"select\"),n=t.appendChild(te.createElement(\"option\"));e.type=\"checkbox\",pe.checkOn=\"\"!==e.value,pe.optSelected=n.selected,e=te.createElement(\"input\"),e.value=\"t\",e.type=\"radio\",pe.radioValue=\"t\"===e.value}();var vt,yt=de.expr.attrHandle;de.fn.extend({attr:function(e,t){return Le(this,de.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){de.removeAttr(this,e)})}}),de.extend({attr:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return\"undefined\"==typeof e.getAttribute?de.prop(e,t,n):(1===i&&de.isXMLDoc(e)||(o=de.attrHooks[t.toLowerCase()]||(de.expr.match.bool.test(t)?vt:void 0)),void 0!==n?null===n?void de.removeAttr(e,t):o&&\"set\"in o&&void 0!==(r=o.set(e,n,t))?r:(e.setAttribute(t,n+\"\"),n):o&&\"get\"in o&&null!==(r=o.get(e,t))?r:(r=de.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!pe.radioValue&&\"radio\"===t&&de.nodeName(e,\"input\")){var n=e.value;return e.setAttribute(\"type\",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,o=t&&t.match(qe);if(o&&1===e.nodeType)for(;n=o[r++];)e.removeAttribute(n)}}),vt={set:function(e,t,n){return t===!1?de.removeAttr(e,n):e.setAttribute(n,n),n}},de.each(de.expr.match.bool.source.match(/\\w+/g),function(e,t){var n=yt[t]||de.find.attr;yt[t]=function(e,t,r){var o,i,s=t.toLowerCase();return r||(i=yt[s],yt[s]=o,o=null!=n(e,t,r)?s:null,yt[s]=i),o}});var xt=/^(?:input|select|textarea|button)$/i,bt=/^(?:a|area)$/i;de.fn.extend({prop:function(e,t){return Le(this,de.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[de.propFix[e]||e]})}}),de.extend({prop:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return 1===i&&de.isXMLDoc(e)||(t=de.propFix[t]||t,o=de.propHooks[t]),void 0!==n?o&&\"set\"in o&&void 0!==(r=o.set(e,n,t))?r:e[t]=n:o&&\"get\"in o&&null!==(r=o.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=de.find.attr(e,\"tabindex\");return t?parseInt(t,10):xt.test(e.nodeName)||bt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:\"htmlFor\",class:\"className\"}}),pe.optSelected||(de.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),de.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){de.propFix[this.toLowerCase()]=this}),de.fn.extend({addClass:function(e){var t,n,r,o,i,s,a,u=0;if(de.isFunction(e))return this.each(function(t){de(this).addClass(e.call(this,t,X(this)))});if(\"string\"==typeof e&&e)for(t=e.match(qe)||[];n=this[u++];)if(o=X(n),r=1===n.nodeType&&\" \"+z(o)+\" \"){for(s=0;i=t[s++];)r.indexOf(\" \"+i+\" \")<0&&(r+=i+\" \");a=z(r),o!==a&&n.setAttribute(\"class\",a)}return this},removeClass:function(e){var t,n,r,o,i,s,a,u=0;if(de.isFunction(e))return this.each(function(t){de(this).removeClass(e.call(this,t,X(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if(\"string\"==typeof e&&e)for(t=e.match(qe)||[];n=this[u++];)if(o=X(n),r=1===n.nodeType&&\" \"+z(o)+\" \"){for(s=0;i=t[s++];)for(;r.indexOf(\" \"+i+\" \")>-1;)r=r.replace(\" \"+i+\" \",\" \");a=z(r),o!==a&&n.setAttribute(\"class\",a)}return this},toggleClass:function(e,t){var n=typeof e;return\"boolean\"==typeof t&&\"string\"===n?t?this.addClass(e):this.removeClass(e):de.isFunction(e)?this.each(function(n){de(this).toggleClass(e.call(this,n,X(this),t),t)}):this.each(function(){var t,r,o,i;if(\"string\"===n)for(r=0,o=de(this),i=e.match(qe)||[];t=i[r++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&\"boolean\"!==n||(t=X(this),t&&Fe.set(this,\"__className__\",t),this.setAttribute&&this.setAttribute(\"class\",t||e===!1?\"\":Fe.get(this,\"__className__\")||\"\"))})},hasClass:function(e){var t,n,r=0;for(t=\" \"+e+\" \";n=this[r++];)if(1===n.nodeType&&(\" \"+z(X(n))+\" \").indexOf(t)>-1)return!0;return!1}});var wt=/\\r/g;de.fn.extend({val:function(e){var t,n,r,o=this[0];{if(arguments.length)return r=de.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=r?e.call(this,n,de(this).val()):e,null==o?o=\"\":\"number\"==typeof o?o+=\"\":de.isArray(o)&&(o=de.map(o,function(e){return null==e?\"\":e+\"\"})),t=de.valHooks[this.type]||de.valHooks[this.nodeName.toLowerCase()],t&&\"set\"in t&&void 0!==t.set(this,o,\"value\")||(this.value=o))});if(o)return t=de.valHooks[o.type]||de.valHooks[o.nodeName.toLowerCase()],t&&\"get\"in t&&void 0!==(n=t.get(o,\"value\"))?n:(n=o.value,\"string\"==typeof n?n.replace(wt,\"\"):null==n?\"\":n)}}}),de.extend({valHooks:{option:{get:function(e){var t=de.find.attr(e,\"value\");return null!=t?t:z(de.text(e))}},select:{get:function(e){var t,n,r,o=e.options,i=e.selectedIndex,s=\"select-one\"===e.type,a=s?null:[],u=s?i+1:o.length;for(r=i<0?u:s?i:0;r<u;r++)if(n=o[r],(n.selected||r===i)&&!n.disabled&&(!n.parentNode.disabled||!de.nodeName(n.parentNode,\"optgroup\"))){if(t=de(n).val(),s)return t;a.push(t)}return a},set:function(e,t){for(var n,r,o=e.options,i=de.makeArray(t),s=o.length;s--;)r=o[s],(r.selected=de.inArray(de.valHooks.option.get(r),i)>-1)&&(n=!0);return n||(e.selectedIndex=-1),i}}}}),de.each([\"radio\",\"checkbox\"],function(){de.valHooks[this]={set:function(e,t){if(de.isArray(t))return e.checked=de.inArray(de(e).val(),t)>-1}},pe.checkOn||(de.valHooks[this].get=function(e){return null===e.getAttribute(\"value\")?\"on\":e.value})});var Tt=/^(?:focusinfocus|focusoutblur)$/;de.extend(de.event,{trigger:function(t,n,r,o){var i,s,a,u,c,l,f,p=[r||te],h=ce.call(t,\"type\")?t.type:t,d=ce.call(t,\"namespace\")?t.namespace.split(\".\"):[];if(s=a=r=r||te,3!==r.nodeType&&8!==r.nodeType&&!Tt.test(h+de.event.triggered)&&(h.indexOf(\".\")>-1&&(d=h.split(\".\"),h=d.shift(),d.sort()),c=h.indexOf(\":\")<0&&\"on\"+h,t=t[de.expando]?t:new de.Event(h,\"object\"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=d.join(\".\"),t.rnamespace=t.namespace?new RegExp(\"(^|\\\\.)\"+d.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:de.makeArray(n,[t]),f=de.event.special[h]||{},o||!f.trigger||f.trigger.apply(r,n)!==!1)){if(!o&&!f.noBubble&&!de.isWindow(r)){for(u=f.delegateType||h,Tt.test(u+h)||(s=s.parentNode);s;s=s.parentNode)p.push(s),a=s;a===(r.ownerDocument||te)&&p.push(a.defaultView||a.parentWindow||e)}for(i=0;(s=p[i++])&&!t.isPropagationStopped();)t.type=i>1?u:f.bindType||h,l=(Fe.get(s,\"events\")||{})[t.type]&&Fe.get(s,\"handle\"),l&&l.apply(s,n),l=c&&s[c],l&&l.apply&&He(s)&&(t.result=l.apply(s,n),t.result===!1&&t.preventDefault());return t.type=h,o||t.isDefaultPrevented()||f._default&&f._default.apply(p.pop(),n)!==!1||!He(r)||c&&de.isFunction(r[h])&&!de.isWindow(r)&&(a=r[c],a&&(r[c]=null),de.event.triggered=h,r[h](),de.event.triggered=void 0,a&&(r[c]=a)),t.result}},simulate:function(e,t,n){var r=de.extend(new de.Event,n,{type:e,isSimulated:!0});de.event.trigger(r,null,t)}}),de.fn.extend({trigger:function(e,t){return this.each(function(){de.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return de.event.trigger(e,t,n,!0)}}),de.each(\"blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu\".split(\" \"),function(e,t){de.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),de.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),pe.focusin=\"onfocusin\"in e,pe.focusin||de.each({focus:\"focusin\",blur:\"focusout\"},function(e,t){var n=function(e){de.event.simulate(t,e.target,de.event.fix(e))};de.event.special[t]={setup:function(){var r=this.ownerDocument||this,o=Fe.access(r,t);o||r.addEventListener(e,n,!0),Fe.access(r,t,(o||0)+1)},teardown:function(){var r=this.ownerDocument||this,o=Fe.access(r,t)-1;o?Fe.access(r,t,o):(r.removeEventListener(e,n,!0),Fe.remove(r,t))}}});var Ct=e.location,jt=de.now(),kt=/\\?/;de.parseXML=function(t){var n;if(!t||\"string\"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,\"text/xml\")}catch(e){n=void 0}return n&&!n.getElementsByTagName(\"parsererror\").length||de.error(\"Invalid XML: \"+t),n};var Et=/\\[\\]$/,St=/\\r?\\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;de.param=function(e,t){var n,r=[],o=function(e,t){var n=de.isFunction(t)?t():t;r[r.length]=encodeURIComponent(e)+\"=\"+encodeURIComponent(null==n?\"\":n)};if(de.isArray(e)||e.jquery&&!de.isPlainObject(e))de.each(e,function(){o(this.name,this.value)});else for(n in e)V(n,e[n],t,o);return r.join(\"&\")},de.fn.extend({serialize:function(){return de.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=de.prop(this,\"elements\");return e?de.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!de(this).is(\":disabled\")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!ze.test(e))}).map(function(e,t){var n=de(this).val();return null==n?null:de.isArray(n)?de.map(n,function(e){return{name:t.name,value:e.replace(St,\"\\r\\n\")}}):{name:t.name,value:n.replace(St,\"\\r\\n\")}}).get()}});var qt=/%20/g,Dt=/#.*$/,Ot=/([?&])_=[^&]*/,Lt=/^(.*?):[ \\t]*([^\\r\\n]*)$/gm,Ht=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ft=/^(?:GET|HEAD)$/,Rt=/^\\/\\//,It={},Pt={},Mt=\"*/\".concat(\"*\"),$t=te.createElement(\"a\");$t.href=Ct.href,de.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:\"GET\",isLocal:Ht.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Mt,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":JSON.parse,\"text xml\":de.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Q(Q(e,de.ajaxSettings),t):Q(de.ajaxSettings,e)},ajaxPrefilter:G(It),ajaxTransport:G(Pt),ajax:function(t,n){function r(t,n,r,a){var c,p,h,b,w,T=n;l||(l=!0,u&&e.clearTimeout(u),o=void 0,s=a||\"\",C.readyState=t>0?4:0,c=t>=200&&t<300||304===t,r&&(b=J(d,C,r)),b=K(d,b,C,c),c?(d.ifModified&&(w=C.getResponseHeader(\"Last-Modified\"),w&&(de.lastModified[i]=w),w=C.getResponseHeader(\"etag\"),w&&(de.etag[i]=w)),204===t||\"HEAD\"===d.type?T=\"nocontent\":304===t?T=\"notmodified\":(T=b.state,p=b.data,h=b.error,c=!h)):(h=T,!t&&T||(T=\"error\",t<0&&(t=0))),C.status=t,C.statusText=(n||T)+\"\",c?v.resolveWith(g,[p,T,C]):v.rejectWith(g,[C,T,h]),C.statusCode(x),x=void 0,f&&m.trigger(c?\"ajaxSuccess\":\"ajaxError\",[C,d,c?p:h]),y.fireWith(g,[C,T]),f&&(m.trigger(\"ajaxComplete\",[C,d]),--de.active||de.event.trigger(\"ajaxStop\")))}\"object\"==typeof t&&(n=t,t=void 0),n=n||{};var o,i,s,a,u,c,l,f,p,h,d=de.ajaxSetup({},n),g=d.context||d,m=d.context&&(g.nodeType||g.jquery)?de(g):de.event,v=de.Deferred(),y=de.Callbacks(\"once memory\"),x=d.statusCode||{},b={},w={},T=\"canceled\",C={readyState:0,getResponseHeader:function(e){var t;if(l){if(!a)for(a={};t=Lt.exec(s);)a[t[1].toLowerCase()]=t[2];t=a[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return l?s:null},setRequestHeader:function(e,t){return null==l&&(e=w[e.toLowerCase()]=w[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==l&&(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(l)C.always(e[C.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||T;return o&&o.abort(t),r(0,t),this}};if(v.promise(C),d.url=((t||d.url||Ct.href)+\"\").replace(Rt,Ct.protocol+\"//\"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=(d.dataType||\"*\").toLowerCase().match(qe)||[\"\"],null==d.crossDomain){c=te.createElement(\"a\");try{c.href=d.url,c.href=c.href,d.crossDomain=$t.protocol+\"//\"+$t.host!=c.protocol+\"//\"+c.host}catch(e){d.crossDomain=!0}}if(d.data&&d.processData&&\"string\"!=typeof d.data&&(d.data=de.param(d.data,d.traditional)),Y(It,d,n,C),l)return C;f=de.event&&d.global,f&&0===de.active++&&de.event.trigger(\"ajaxStart\"),d.type=d.type.toUpperCase(),d.hasContent=!Ft.test(d.type),i=d.url.replace(Dt,\"\"),d.hasContent?d.data&&d.processData&&0===(d.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&(d.data=d.data.replace(qt,\"+\")):(h=d.url.slice(i.length),d.data&&(i+=(kt.test(i)?\"&\":\"?\")+d.data,delete d.data),d.cache===!1&&(i=i.replace(Ot,\"$1\"),h=(kt.test(i)?\"&\":\"?\")+\"_=\"+jt++ +h),d.url=i+h),d.ifModified&&(de.lastModified[i]&&C.setRequestHeader(\"If-Modified-Since\",de.lastModified[i]),de.etag[i]&&C.setRequestHeader(\"If-None-Match\",de.etag[i])),(d.data&&d.hasContent&&d.contentType!==!1||n.contentType)&&C.setRequestHeader(\"Content-Type\",d.contentType),C.setRequestHeader(\"Accept\",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(\"*\"!==d.dataTypes[0]?\", \"+Mt+\"; q=0.01\":\"\"):d.accepts[\"*\"]);for(p in d.headers)C.setRequestHeader(p,d.headers[p]);if(d.beforeSend&&(d.beforeSend.call(g,C,d)===!1||l))return C.abort();if(T=\"abort\",y.add(d.complete),C.done(d.success),C.fail(d.error),o=Y(Pt,d,n,C)){if(C.readyState=1,f&&m.trigger(\"ajaxSend\",[C,d]),l)return C;d.async&&d.timeout>0&&(u=e.setTimeout(function(){C.abort(\"timeout\")},d.timeout));try{l=!1,o.send(b,r)}catch(e){if(l)throw e;r(-1,e)}}else r(-1,\"No Transport\");return C},getJSON:function(e,t,n){return de.get(e,t,n,\"json\")},getScript:function(e,t){return de.get(e,void 0,t,\"script\")}}),de.each([\"get\",\"post\"],function(e,t){de[t]=function(e,n,r,o){return de.isFunction(n)&&(o=o||r,r=n,n=void 0),de.ajax(de.extend({url:e,type:t,dataType:o,data:n,success:r},de.isPlainObject(e)&&e))}}),de._evalUrl=function(e){return de.ajax({url:e,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,throws:!0})},de.fn.extend({wrapAll:function(e){var t;return this[0]&&(de.isFunction(e)&&(e=e.call(this[0])),t=de(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return de.isFunction(e)?this.each(function(t){de(this).wrapInner(e.call(this,t))}):this.each(function(){var t=de(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=de.isFunction(e);return this.each(function(n){de(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not(\"body\").each(function(){de(this).replaceWith(this.childNodes)}),this}}),de.expr.pseudos.hidden=function(e){return!de.expr.pseudos.visible(e)},de.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},de.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Wt={0:200,1223:204},Bt=de.ajaxSettings.xhr();pe.cors=!!Bt&&\"withCredentials\"in Bt,pe.ajax=Bt=!!Bt,de.ajaxTransport(function(t){var n,r;if(pe.cors||Bt&&!t.crossDomain)return{send:function(o,i){var s,a=t.xhr();if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(s in t.xhrFields)a[s]=t.xhrFields[s];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||o[\"X-Requested-With\"]||(o[\"X-Requested-With\"]=\"XMLHttpRequest\");for(s in o)a.setRequestHeader(s,o[s]);n=function(e){return function(){n&&(n=r=a.onload=a.onerror=a.onabort=a.onreadystatechange=null,\"abort\"===e?a.abort():\"error\"===e?\"number\"!=typeof a.status?i(0,\"error\"):i(a.status,a.statusText):i(Wt[a.status]||a.status,a.statusText,\"text\"!==(a.responseType||\"text\")||\"string\"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=n(),r=a.onerror=n(\"error\"),void 0!==a.onabort?a.onabort=r:a.onreadystatechange=function(){4===a.readyState&&e.setTimeout(function(){n&&r()})},n=n(\"abort\");try{a.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),de.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),de.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(e){return de.globalEval(e),e}}}),de.ajaxPrefilter(\"script\",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type=\"GET\")}),de.ajaxTransport(\"script\",function(e){if(e.crossDomain){var t,n;return{send:function(r,o){t=de(\"<script>\").prop({charset:e.scriptCharset,src:e.url}).on(\"load error\",n=function(e){t.remove(),n=null,e&&o(\"error\"===e.type?404:200,e.type)}),te.head.appendChild(t[0])},abort:function(){n&&n()}}}});var _t=[],Ut=/(=)\\?(?=&|$)|\\?\\?/;de.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var e=_t.pop()||de.expando+\"_\"+jt++;return this[e]=!0,e}}),de.ajaxPrefilter(\"json jsonp\",function(t,n,r){var o,i,s,a=t.jsonp!==!1&&(Ut.test(t.url)?\"url\":\"string\"==typeof t.data&&0===(t.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&Ut.test(t.data)&&\"data\");if(a||\"jsonp\"===t.dataTypes[0])return o=t.jsonpCallback=de.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,a?t[a]=t[a].replace(Ut,\"$1\"+o):t.jsonp!==!1&&(t.url+=(kt.test(t.url)?\"&\":\"?\")+t.jsonp+\"=\"+o),t.converters[\"script json\"]=function(){return s||de.error(o+\" was not called\"),s[0]},t.dataTypes[0]=\"json\",i=e[o],e[o]=function(){s=arguments},r.always(function(){void 0===i?de(e).removeProp(o):e[o]=i,t[o]&&(t.jsonpCallback=n.jsonpCallback,_t.push(o)),s&&de.isFunction(i)&&i(s[0]),s=i=void 0}),\"script\"}),pe.createHTMLDocument=function(){var e=te.implementation.createHTMLDocument(\"\").body;return e.innerHTML=\"<form></form><form></form>\",2===e.childNodes.length}(),de.parseHTML=function(e,t,n){if(\"string\"!=typeof e)return[];\"boolean\"==typeof t&&(n=t,t=!1);var r,o,i;return t||(pe.createHTMLDocument?(t=te.implementation.createHTMLDocument(\"\"),r=t.createElement(\"base\"),r.href=te.location.href,t.head.appendChild(r)):t=te),o=Ce.exec(e),i=!n&&[],o?[t.createElement(o[1])]:(o=x([e],t,i),i&&i.length&&de(i).remove(),de.merge([],o.childNodes))},de.fn.load=function(e,t,n){var r,o,i,s=this,a=e.indexOf(\" \");return a>-1&&(r=z(e.slice(a)),e=e.slice(0,a)),de.isFunction(t)?(n=t,t=void 0):t&&\"object\"==typeof t&&(o=\"POST\"),s.length>0&&de.ajax({url:e,type:o||\"GET\",dataType:\"html\",data:t}).done(function(e){i=arguments,s.html(r?de(\"<div>\").append(de.parseHTML(e)).find(r):e)}).always(n&&function(e,t){s.each(function(){n.apply(this,i||[e.responseText,t,e])})}),this},de.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(e,t){de.fn[t]=function(e){return this.on(t,e)}}),de.expr.pseudos.animated=function(e){return de.grep(de.timers,function(t){return e===t.elem}).length},de.offset={setOffset:function(e,t,n){var r,o,i,s,a,u,c,l=de.css(e,\"position\"),f=de(e),p={};\"static\"===l&&(e.style.position=\"relative\"),a=f.offset(),i=de.css(e,\"top\"),u=de.css(e,\"left\"),c=(\"absolute\"===l||\"fixed\"===l)&&(i+u).indexOf(\"auto\")>-1,c?(r=f.position(),s=r.top,o=r.left):(s=parseFloat(i)||0,o=parseFloat(u)||0),de.isFunction(t)&&(t=t.call(e,n,de.extend({},a))),null!=t.top&&(p.top=t.top-a.top+s),null!=t.left&&(p.left=t.left-a.left+o),\"using\"in t?t.using.call(e,p):f.css(p)}},de.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){de.offset.setOffset(this,e,t)});var t,n,r,o,i=this[0];if(i)return i.getClientRects().length?(r=i.getBoundingClientRect(),r.width||r.height?(o=i.ownerDocument,n=Z(o),t=o.documentElement,{top:r.top+n.pageYOffset-t.clientTop,left:r.left+n.pageXOffset-t.clientLeft}):r):{top:0,left:0}},position:function(){if(this[0]){var e,t,n=this[0],r={top:0,left:0};return\"fixed\"===de.css(n,\"position\")?t=n.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),de.nodeName(e[0],\"html\")||(r=e.offset()),r={top:r.top+de.css(e[0],\"borderTopWidth\",!0),left:r.left+de.css(e[0],\"borderLeftWidth\",!0)}),{top:t.top-r.top-de.css(n,\"marginTop\",!0),left:t.left-r.left-de.css(n,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&\"static\"===de.css(e,\"position\");)e=e.offsetParent;return e||Qe})}}),de.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(e,t){var n=\"pageYOffset\"===t;de.fn[e]=function(r){return Le(this,function(e,r,o){var i=Z(e);return void 0===o?i?i[t]:e[r]:void(i?i.scrollTo(n?i.pageXOffset:o,n?o:i.pageYOffset):e[r]=o)},e,r,arguments.length)}}),de.each([\"top\",\"left\"],function(e,t){de.cssHooks[t]=O(pe.pixelPosition,function(e,n){if(n)return n=D(e,t),st.test(n)?de(e).position()[t]+\"px\":n})}),de.each({Height:\"height\",Width:\"width\"},function(e,t){de.each({padding:\"inner\"+e,content:t,\"\":\"outer\"+e},function(n,r){de.fn[r]=function(o,i){var s=arguments.length&&(n||\"boolean\"!=typeof o),a=n||(o===!0||i===!0?\"margin\":\"border\");return Le(this,function(t,n,o){var i;return de.isWindow(t)?0===r.indexOf(\"outer\")?t[\"inner\"+e]:t.document.documentElement[\"client\"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body[\"scroll\"+e],i[\"scroll\"+e],t.body[\"offset\"+e],i[\"offset\"+e],i[\"client\"+e])):void 0===o?de.css(t,n,a):de.style(t,n,o,a)},t,s?o:void 0,s)}})}),de.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)}}),de.parseJSON=JSON.parse,\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return de});var zt=e.jQuery,Xt=e.$;return de.noConflict=function(t){return e.$===de&&(e.$=Xt),t&&e.jQuery===de&&(e.jQuery=zt),de},t||(e.jQuery=e.$=de),de})},{}],2:[function(e,t,n){(function(e){function t(e,t){for(var n=0,r=e.length-1;r>=0;r--){var o=e[r];\".\"===o?e.splice(r,1):\"..\"===o?(e.splice(r,1),n++):n&&(e.splice(r,1),n--)}if(t)for(;n--;n)e.unshift(\"..\");return e}function r(e,t){if(e.filter)return e.filter(t);for(var n=[],r=0;r<e.length;r++)t(e[r],r,e)&&n.push(e[r]);return n}var o=/^(\\/?|)([\\s\\S]*?)((?:\\.{1,2}|[^\\/]+?|)(\\.[^.\\/]*|))(?:[\\/]*)$/,i=function(e){return o.exec(e).slice(1)};n.resolve=function(){for(var n=\"\",o=!1,i=arguments.length-1;i>=-1&&!o;i--){var s=i>=0?arguments[i]:e.cwd();if(\"string\"!=typeof s)throw new TypeError(\"Arguments to path.resolve must be strings\");s&&(n=s+\"/\"+n,o=\"/\"===s.charAt(0))}return n=t(r(n.split(\"/\"),function(e){return!!e}),!o).join(\"/\"),(o?\"/\":\"\")+n||\".\"},n.normalize=function(e){var o=n.isAbsolute(e),i=\"/\"===s(e,-1);return e=t(r(e.split(\"/\"),function(e){return!!e}),!o).join(\"/\"),e||o||(e=\".\"),e&&i&&(e+=\"/\"),(o?\"/\":\"\")+e},n.isAbsolute=function(e){return\"/\"===e.charAt(0)},n.join=function(){var e=Array.prototype.slice.call(arguments,0);return n.normalize(r(e,function(e,t){if(\"string\"!=typeof e)throw new TypeError(\"Arguments to path.join must be strings\");return e}).join(\"/\"))},n.relative=function(e,t){function r(e){for(var t=0;t<e.length&&\"\"===e[t];t++);for(var n=e.length-1;n>=0&&\"\"===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=n.resolve(e).substr(1),t=n.resolve(t).substr(1);for(var o=r(e.split(\"/\")),i=r(t.split(\"/\")),s=Math.min(o.length,i.length),a=s,u=0;u<s;u++)if(o[u]!==i[u]){a=u;break}for(var c=[],u=a;u<o.length;u++)c.push(\"..\");return c=c.concat(i.slice(a)),c.join(\"/\")},n.sep=\"/\",n.delimiter=\":\",n.dirname=function(e){var t=i(e),n=t[0],r=t[1];return n||r?(r&&(r=r.substr(0,r.length-1)),n+r):\".\"},n.basename=function(e,t){var n=i(e)[2];return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},n.extname=function(e){return i(e)[3]};var s=\"b\"===\"ab\".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)}}).call(this,e(\"_process\"))},{_process:3}],3:[function(e,t,n){function r(){throw new Error(\"setTimeout has not been defined\")}function o(){throw new Error(\"clearTimeout has not been defined\")}function i(e){if(f===setTimeout)return setTimeout(e,0);if((f===r||!f)&&setTimeout)return f=setTimeout,setTimeout(e,0);try{return f(e,0)}catch(t){try{return f.call(null,e,0)}catch(t){return f.call(this,e,0)}}}function s(e){if(p===clearTimeout)return clearTimeout(e);if((p===o||!p)&&clearTimeout)return p=clearTimeout,clearTimeout(e);try{return p(e)}catch(t){try{return p.call(null,e)}catch(t){return p.call(this,e)}}}function a(){m&&d&&(m=!1,d.length?g=d.concat(g):v=-1,g.length&&u())}function u(){if(!m){var e=i(a);m=!0;for(var t=g.length;t;){for(d=g,g=[];++v<t;)d&&d[v].run();v=-1,t=g.length}d=null,m=!1,s(e)}}function c(e,t){this.fun=e,this.array=t}function l(){}var f,p,h=t.exports={};!function(){try{f=\"function\"==typeof setTimeout?setTimeout:r}catch(e){f=r}try{p=\"function\"==typeof clearTimeout?clearTimeout:o}catch(e){p=o}}();var d,g=[],m=!1,v=-1;h.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];g.push(new c(e,t)),1!==g.length||m||i(u)},c.prototype.run=function(){this.fun.apply(null,this.array)},h.title=\"browser\",h.browser=!0,h.env={},h.argv=[],h.version=\"\",h.versions={},h.on=l,h.addListener=l,h.once=l,h.off=l,h.removeListener=l,h.removeAllListeners=l,h.emit=l,h.binding=function(e){throw new Error(\"process.binding is not supported\")},h.cwd=function(){return\"/\"},h.chdir=function(e){throw new Error(\"process.chdir is not supported\")},h.umask=function(){return 0}},{}],4:[function(e,t,n){(function(e){!function(r){function o(e){throw new RangeError(L[e])}function i(e,t){for(var n=e.length,r=[];n--;)r[n]=t(e[n]);return r}function s(e,t){var n=e.split(\"@\"),r=\"\";n.length>1&&(r=n[0]+\"@\",e=n[1]),e=e.replace(O,\".\");var o=e.split(\".\"),s=i(o,t).join(\".\");return r+s}function a(e){for(var t,n,r=[],o=0,i=e.length;o<i;)t=e.charCodeAt(o++),t>=55296&&t<=56319&&o<i?(n=e.charCodeAt(o++),56320==(64512&n)?r.push(((1023&t)<<10)+(1023&n)+65536):(r.push(t),o--)):r.push(t);return r}function u(e){return i(e,function(e){var t=\"\";return e>65535&&(e-=65536,t+=R(e>>>10&1023|55296),e=56320|1023&e),t+=R(e)}).join(\"\")}function c(e){return e-48<10?e-22:e-65<26?e-65:e-97<26?e-97:T}function l(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function f(e,t,n){var r=0;for(e=n?F(e/E):e>>1,e+=F(e/t);e>H*j>>1;r+=T)e=F(e/H);return F(r+(H+1)*e/(e+k))}function p(e){var t,n,r,i,s,a,l,p,h,d,g=[],m=e.length,v=0,y=N,x=S;for(n=e.lastIndexOf(A),n<0&&(n=0),r=0;r<n;++r)e.charCodeAt(r)>=128&&o(\"not-basic\"),g.push(e.charCodeAt(r));for(i=n>0?n+1:0;i<m;){for(s=v,a=1,l=T;i>=m&&o(\"invalid-input\"),p=c(e.charCodeAt(i++)),(p>=T||p>F((w-v)/a))&&o(\"overflow\"),v+=p*a,h=l<=x?C:l>=x+j?j:l-x,!(p<h);l+=T)d=T-h,a>F(w/d)&&o(\"overflow\"),a*=d;t=g.length+1,x=f(v-s,t,0==s),F(v/t)>w-y&&o(\"overflow\"),y+=F(v/t),v%=t,g.splice(v++,0,y)}return u(g)}function h(e){var t,n,r,i,s,u,c,p,h,d,g,m,v,y,x,b=[];for(e=a(e),m=e.length,t=N,n=0,s=S,u=0;u<m;++u)g=e[u],g<128&&b.push(R(g));for(r=i=b.length,i&&b.push(A);r<m;){for(c=w,u=0;u<m;++u)g=e[u],g>=t&&g<c&&(c=g);for(v=r+1,c-t>F((w-n)/v)&&o(\"overflow\"),n+=(c-t)*v,t=c,u=0;u<m;++u)if(g=e[u],g<t&&++n>w&&o(\"overflow\"),g==t){for(p=n,h=T;d=h<=s?C:h>=s+j?j:h-s,!(p<d);h+=T)x=p-d,y=T-d,b.push(R(l(d+x%y,0))),p=F(x/y);b.push(R(l(p,0))),s=f(n,v,r==i),n=0,++r}++n,++t}return b.join(\"\")}function d(e){return s(e,function(e){return q.test(e)?p(e.slice(4).toLowerCase()):e})}function g(e){return s(e,function(e){return D.test(e)?\"xn--\"+h(e):e})}var m=\"object\"==typeof n&&n&&!n.nodeType&&n,v=\"object\"==typeof t&&t&&!t.nodeType&&t,y=\"object\"==typeof e&&e;y.global!==y&&y.window!==y&&y.self!==y||(r=y);var x,b,w=2147483647,T=36,C=1,j=26,k=38,E=700,S=72,N=128,A=\"-\",q=/^xn--/,D=/[^\\x20-\\x7E]/,O=/[\\x2E\\u3002\\uFF0E\\uFF61]/g,L={overflow:\"Overflow: input needs wider integers to process\",\"not-basic\":\"Illegal input >= 0x80 (not a basic code point)\",\"invalid-input\":\"Invalid input\"},H=T-C,F=Math.floor,R=String.fromCharCode;if(x={version:\"1.4.1\",ucs2:{decode:a,encode:u},decode:p,encode:h,toASCII:g,toUnicode:d},\"function\"==typeof define&&\"object\"==typeof define.amd&&define.amd)define(\"punycode\",function(){return x});else if(m&&v)if(t.exports==m)v.exports=x;else for(b in x)x.hasOwnProperty(b)&&(m[b]=x[b]);else r.punycode=x}(this)}).call(this,\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{})},{}],5:[function(e,t,n){\"use strict\";function r(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.exports=function(e,t,n,i){t=t||\"&\",n=n||\"=\";var s={};if(\"string\"!=typeof e||0===e.length)return s;var a=/\\+/g;e=e.split(t);var u=1e3;i&&\"number\"==typeof i.maxKeys&&(u=i.maxKeys);var c=e.length;u>0&&c>u&&(c=u);for(var l=0;l<c;++l){var f,p,h,d,g=e[l].replace(a,\"%20\"),m=g.indexOf(n);m>=0?(f=g.substr(0,m),p=g.substr(m+1)):(f=g,p=\"\"),h=decodeURIComponent(f),d=decodeURIComponent(p),r(s,h)?o(s[h])?s[h].push(d):s[h]=[s[h],d]:s[h]=d}return s};var o=Array.isArray||function(e){return\"[object Array]\"===Object.prototype.toString.call(e)}},{}],6:[function(e,t,n){\"use strict\";function r(e,t){if(e.map)return e.map(t);for(var n=[],r=0;r<e.length;r++)n.push(t(e[r],r));return n}var o=function(e){switch(typeof e){case\"string\":return e;case\"boolean\":return e?\"true\":\"false\";case\"number\":return isFinite(e)?e:\"\";default:return\"\"}};t.exports=function(e,t,n,a){return t=t||\"&\",n=n||\"=\",null===e&&(e=void 0),\"object\"==typeof e?r(s(e),function(s){var a=encodeURIComponent(o(s))+n;return i(e[s])?r(e[s],function(e){return a+encodeURIComponent(o(e))}).join(t):a+encodeURIComponent(o(e[s]))}).join(t):a?encodeURIComponent(o(a))+n+encodeURIComponent(o(e)):\"\"};var i=Array.isArray||function(e){return\"[object Array]\"===Object.prototype.toString.call(e)},s=Object.keys||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.push(n);return t}},{}],7:[function(e,t,n){\"use strict\";n.decode=n.parse=e(\"./decode\"),n.encode=n.stringify=e(\"./encode\")},{\"./decode\":5,\"./encode\":6}],8:[function(e,t,n){\"use strict\";function r(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}function o(e,t,n){if(e&&c.isObject(e)&&e instanceof r)return e;var o=new r;return o.parse(e,t,n),\no}function i(e){return c.isString(e)&&(e=o(e)),e instanceof r?e.format():r.prototype.format.call(e)}function s(e,t){return o(e,!1,!0).resolve(t)}function a(e,t){return e?o(e,!1,!0).resolveObject(t):t}var u=e(\"punycode\"),c=e(\"./util\");n.parse=o,n.resolve=s,n.resolveObject=a,n.format=i,n.Url=r;var l=/^([a-z0-9.+-]+:)/i,f=/:[0-9]*$/,p=/^(\\/\\/?(?!\\/)[^\\?\\s]*)(\\?[^\\s]*)?$/,h=[\"<\",\">\",'\"',\"`\",\" \",\"\\r\",\"\\n\",\"\\t\"],d=[\"{\",\"}\",\"|\",\"\\\\\",\"^\",\"`\"].concat(h),g=[\"'\"].concat(d),m=[\"%\",\"/\",\"?\",\";\",\"#\"].concat(g),v=[\"/\",\"?\",\"#\"],y=255,x=/^[+a-z0-9A-Z_-]{0,63}$/,b=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,w={javascript:!0,\"javascript:\":!0},T={javascript:!0,\"javascript:\":!0},C={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,\"http:\":!0,\"https:\":!0,\"ftp:\":!0,\"gopher:\":!0,\"file:\":!0},j=e(\"querystring\");r.prototype.parse=function(e,t,n){if(!c.isString(e))throw new TypeError(\"Parameter 'url' must be a string, not \"+typeof e);var r=e.indexOf(\"?\"),o=r!==-1&&r<e.indexOf(\"#\")?\"?\":\"#\",i=e.split(o),s=/\\\\/g;i[0]=i[0].replace(s,\"/\"),e=i.join(o);var a=e;if(a=a.trim(),!n&&1===e.split(\"#\").length){var f=p.exec(a);if(f)return this.path=a,this.href=a,this.pathname=f[1],f[2]?(this.search=f[2],t?this.query=j.parse(this.search.substr(1)):this.query=this.search.substr(1)):t&&(this.search=\"\",this.query={}),this}var h=l.exec(a);if(h){h=h[0];var d=h.toLowerCase();this.protocol=d,a=a.substr(h.length)}if(n||h||a.match(/^\\/\\/[^@\\/]+@[^@\\/]+/)){var k=\"//\"===a.substr(0,2);!k||h&&T[h]||(a=a.substr(2),this.slashes=!0)}if(!T[h]&&(k||h&&!C[h])){for(var E=-1,S=0;S<v.length;S++){var N=a.indexOf(v[S]);N!==-1&&(E===-1||N<E)&&(E=N)}var A,q;q=E===-1?a.lastIndexOf(\"@\"):a.lastIndexOf(\"@\",E),q!==-1&&(A=a.slice(0,q),a=a.slice(q+1),this.auth=decodeURIComponent(A)),E=-1;for(var S=0;S<m.length;S++){var N=a.indexOf(m[S]);N!==-1&&(E===-1||N<E)&&(E=N)}E===-1&&(E=a.length),this.host=a.slice(0,E),a=a.slice(E),this.parseHost(),this.hostname=this.hostname||\"\";var D=\"[\"===this.hostname[0]&&\"]\"===this.hostname[this.hostname.length-1];if(!D)for(var O=this.hostname.split(/\\./),S=0,L=O.length;S<L;S++){var H=O[S];if(H&&!H.match(x)){for(var F=\"\",R=0,I=H.length;R<I;R++)F+=H.charCodeAt(R)>127?\"x\":H[R];if(!F.match(x)){var P=O.slice(0,S),M=O.slice(S+1),$=H.match(b);$&&(P.push($[1]),M.unshift($[2])),M.length&&(a=\"/\"+M.join(\".\")+a),this.hostname=P.join(\".\");break}}}this.hostname.length>y?this.hostname=\"\":this.hostname=this.hostname.toLowerCase(),D||(this.hostname=u.toASCII(this.hostname));var W=this.port?\":\"+this.port:\"\",B=this.hostname||\"\";this.host=B+W,this.href+=this.host,D&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),\"/\"!==a[0]&&(a=\"/\"+a))}if(!w[d])for(var S=0,L=g.length;S<L;S++){var _=g[S];if(a.indexOf(_)!==-1){var U=encodeURIComponent(_);U===_&&(U=escape(_)),a=a.split(_).join(U)}}var z=a.indexOf(\"#\");z!==-1&&(this.hash=a.substr(z),a=a.slice(0,z));var X=a.indexOf(\"?\");if(X!==-1?(this.search=a.substr(X),this.query=a.substr(X+1),t&&(this.query=j.parse(this.query)),a=a.slice(0,X)):t&&(this.search=\"\",this.query={}),a&&(this.pathname=a),C[d]&&this.hostname&&!this.pathname&&(this.pathname=\"/\"),this.pathname||this.search){var W=this.pathname||\"\",V=this.search||\"\";this.path=W+V}return this.href=this.format(),this},r.prototype.format=function(){var e=this.auth||\"\";e&&(e=encodeURIComponent(e),e=e.replace(/%3A/i,\":\"),e+=\"@\");var t=this.protocol||\"\",n=this.pathname||\"\",r=this.hash||\"\",o=!1,i=\"\";this.host?o=e+this.host:this.hostname&&(o=e+(this.hostname.indexOf(\":\")===-1?this.hostname:\"[\"+this.hostname+\"]\"),this.port&&(o+=\":\"+this.port)),this.query&&c.isObject(this.query)&&Object.keys(this.query).length&&(i=j.stringify(this.query));var s=this.search||i&&\"?\"+i||\"\";return t&&\":\"!==t.substr(-1)&&(t+=\":\"),this.slashes||(!t||C[t])&&o!==!1?(o=\"//\"+(o||\"\"),n&&\"/\"!==n.charAt(0)&&(n=\"/\"+n)):o||(o=\"\"),r&&\"#\"!==r.charAt(0)&&(r=\"#\"+r),s&&\"?\"!==s.charAt(0)&&(s=\"?\"+s),n=n.replace(/[?#]/g,function(e){return encodeURIComponent(e)}),s=s.replace(\"#\",\"%23\"),t+o+n+s+r},r.prototype.resolve=function(e){return this.resolveObject(o(e,!1,!0)).format()},r.prototype.resolveObject=function(e){if(c.isString(e)){var t=new r;t.parse(e,!1,!0),e=t}for(var n=new r,o=Object.keys(this),i=0;i<o.length;i++){var s=o[i];n[s]=this[s]}if(n.hash=e.hash,\"\"===e.href)return n.href=n.format(),n;if(e.slashes&&!e.protocol){for(var a=Object.keys(e),u=0;u<a.length;u++){var l=a[u];\"protocol\"!==l&&(n[l]=e[l])}return C[n.protocol]&&n.hostname&&!n.pathname&&(n.path=n.pathname=\"/\"),n.href=n.format(),n}if(e.protocol&&e.protocol!==n.protocol){if(!C[e.protocol]){for(var f=Object.keys(e),p=0;p<f.length;p++){var h=f[p];n[h]=e[h]}return n.href=n.format(),n}if(n.protocol=e.protocol,e.host||T[e.protocol])n.pathname=e.pathname;else{for(var d=(e.pathname||\"\").split(\"/\");d.length&&!(e.host=d.shift()););e.host||(e.host=\"\"),e.hostname||(e.hostname=\"\"),\"\"!==d[0]&&d.unshift(\"\"),d.length<2&&d.unshift(\"\"),n.pathname=d.join(\"/\")}if(n.search=e.search,n.query=e.query,n.host=e.host||\"\",n.auth=e.auth,n.hostname=e.hostname||e.host,n.port=e.port,n.pathname||n.search){var g=n.pathname||\"\",m=n.search||\"\";n.path=g+m}return n.slashes=n.slashes||e.slashes,n.href=n.format(),n}var v=n.pathname&&\"/\"===n.pathname.charAt(0),y=e.host||e.pathname&&\"/\"===e.pathname.charAt(0),x=y||v||n.host&&e.pathname,b=x,w=n.pathname&&n.pathname.split(\"/\")||[],d=e.pathname&&e.pathname.split(\"/\")||[],j=n.protocol&&!C[n.protocol];if(j&&(n.hostname=\"\",n.port=null,n.host&&(\"\"===w[0]?w[0]=n.host:w.unshift(n.host)),n.host=\"\",e.protocol&&(e.hostname=null,e.port=null,e.host&&(\"\"===d[0]?d[0]=e.host:d.unshift(e.host)),e.host=null),x=x&&(\"\"===d[0]||\"\"===w[0])),y)n.host=e.host||\"\"===e.host?e.host:n.host,n.hostname=e.hostname||\"\"===e.hostname?e.hostname:n.hostname,n.search=e.search,n.query=e.query,w=d;else if(d.length)w||(w=[]),w.pop(),w=w.concat(d),n.search=e.search,n.query=e.query;else if(!c.isNullOrUndefined(e.search)){if(j){n.hostname=n.host=w.shift();var k=!!(n.host&&n.host.indexOf(\"@\")>0)&&n.host.split(\"@\");k&&(n.auth=k.shift(),n.host=n.hostname=k.shift())}return n.search=e.search,n.query=e.query,c.isNull(n.pathname)&&c.isNull(n.search)||(n.path=(n.pathname?n.pathname:\"\")+(n.search?n.search:\"\")),n.href=n.format(),n}if(!w.length)return n.pathname=null,n.search?n.path=\"/\"+n.search:n.path=null,n.href=n.format(),n;for(var E=w.slice(-1)[0],S=(n.host||e.host||w.length>1)&&(\".\"===E||\"..\"===E)||\"\"===E,N=0,A=w.length;A>=0;A--)E=w[A],\".\"===E?w.splice(A,1):\"..\"===E?(w.splice(A,1),N++):N&&(w.splice(A,1),N--);if(!x&&!b)for(;N--;N)w.unshift(\"..\");!x||\"\"===w[0]||w[0]&&\"/\"===w[0].charAt(0)||w.unshift(\"\"),S&&\"/\"!==w.join(\"/\").substr(-1)&&w.push(\"\");var q=\"\"===w[0]||w[0]&&\"/\"===w[0].charAt(0);if(j){n.hostname=n.host=q?\"\":w.length?w.shift():\"\";var k=!!(n.host&&n.host.indexOf(\"@\")>0)&&n.host.split(\"@\");k&&(n.auth=k.shift(),n.host=n.hostname=k.shift())}return x=x||n.host&&w.length,x&&!q&&w.unshift(\"\"),w.length?n.pathname=w.join(\"/\"):(n.pathname=null,n.path=null),c.isNull(n.pathname)&&c.isNull(n.search)||(n.path=(n.pathname?n.pathname:\"\")+(n.search?n.search:\"\")),n.auth=e.auth||n.auth,n.slashes=n.slashes||e.slashes,n.href=n.format(),n},r.prototype.parseHost=function(){var e=this.host,t=f.exec(e);t&&(t=t[0],\":\"!==t&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)}},{\"./util\":9,punycode:4,querystring:7}],9:[function(e,t,n){\"use strict\";t.exports={isString:function(e){return\"string\"==typeof e},isObject:function(e){return\"object\"==typeof e&&null!==e},isNull:function(e){return null===e},isNullOrUndefined:function(e){return null==e}}},{}],10:[function(e,t,n){var r=e(\"jquery\");t.exports=r({})},{jquery:1}],11:[function(e,t,n){var r=e(\"jquery\"),o=e(\"./events\"),i=e(\"./storage\"),s=e(\"./page\"),a=!1,u=window.gitbook||[],c={events:o,page:s,state:s.getState(),storage:i,push:function(e){a?e():u.push(e)}},l={gitbook:c,jquery:r};window.gitbook=c,window.$=r,window.jQuery=r,window.require=function(e,t){e=e.map(function(e){if(e=e.toLowerCase(),!l[e])throw new Error(\"GitBook module \"+e+\" doesn't exist\");return l[e]}),t.apply(null,e)},r(document).ready(function(){a=!0,r.each(u,function(e,t){t()})})},{\"./events\":10,\"./page\":12,\"./storage\":13,jquery:1}],12:[function(e,t,n){function r(e){console.log(\"page has changed\",e),o(e),l||(l=!0,c.trigger(\"start\",e.config.pluginsConfig)),c.trigger(\"page.change\")}function o(e){f.page=e.page,f.file=e.file,f.gitbook=e.gitbook,f.config=e.config,f.basePath=e.basePath,f.book=e.book,f.$book=s(\".book\"),f.revision=f.gitbook.time,f.level=f.page.level,f.filepath=f.file.path,f.chapterTitle=f.page.title,f.innerLanguage=f.book.language||\"\",f.root=a.resolve(location.protocol+\"//\"+location.host,u.dirname(u.resolve(location.pathname.replace(/\\/$/,\"/index.html\"),f.basePath))).replace(/\\/?$/,\"/\"),f.bookRoot=f.innerLanguage?a.resolve(f.root,\"..\"):f.root}function i(){return f}var s=e(\"jquery\"),a=e(\"url\"),u=e(\"path\"),c=e(\"./events\"),l=!1,f={};t.exports={hasChanged:r,setState:o,getState:i}},{\"./events\":10,jquery:1,path:2,url:8}],13:[function(e,t,n){var r=\"\";t.exports={setBaseKey:function(e){r=e},set:function(e,t){e=r+\":\"+e;try{localStorage[e]=JSON.stringify(t)}catch(e){}},get:function(e,t){var n;e=r+\":\"+e;try{n=localStorage[e]}catch(e){}if(void 0===n)return t;try{var o=JSON.parse(n);return null==o?t:o}catch(e){return n||t}},remove:function(e){e=r+\":\"+e;try{localStorage.removeItem(e)}catch(e){}}}},{}]},{},[11]);\n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/gitbook/style.css",
    "content": "/*! normalize.css v2.1.0 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:\"\\201C\" \"\\201D\" \"\\2018\" \"\\2019\"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}.link-inherit{color:inherit}.link-inherit:focus,.link-inherit:hover{color:inherit}.hidden{display:none}.alert{padding:15px;margin-bottom:20px;color:#444;background:#eee;border-bottom:5px solid #ddd}.alert-success{background:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-info{background:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-danger{background:#f2dede;border-color:#ebccd1;color:#a94442}.alert-warning{background:#fcf8e3;border-color:#faebcc;color:#8a6d3b}/*!\n *  Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome/fontawesome-webfont.eot?v=4.6.3);src:url(fonts/fontawesome/fontawesome-webfont.eot?#iefix&v=4.6.3) format('embedded-opentype'),url(fonts/fontawesome/fontawesome-webfont.woff2?v=4.6.3) format('woff2'),url(fonts/fontawesome/fontawesome-webfont.woff?v=4.6.3) format('woff'),url(fonts/fontawesome/fontawesome-webfont.ttf?v=4.6.3) format('truetype'),url(fonts/fontawesome/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular) format('svg');font-weight:400;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:\"\\f000\"}.fa-music:before{content:\"\\f001\"}.fa-search:before{content:\"\\f002\"}.fa-envelope-o:before{content:\"\\f003\"}.fa-heart:before{content:\"\\f004\"}.fa-star:before{content:\"\\f005\"}.fa-star-o:before{content:\"\\f006\"}.fa-user:before{content:\"\\f007\"}.fa-film:before{content:\"\\f008\"}.fa-th-large:before{content:\"\\f009\"}.fa-th:before{content:\"\\f00a\"}.fa-th-list:before{content:\"\\f00b\"}.fa-check:before{content:\"\\f00c\"}.fa-close:before,.fa-remove:before,.fa-times:before{content:\"\\f00d\"}.fa-search-plus:before{content:\"\\f00e\"}.fa-search-minus:before{content:\"\\f010\"}.fa-power-off:before{content:\"\\f011\"}.fa-signal:before{content:\"\\f012\"}.fa-cog:before,.fa-gear:before{content:\"\\f013\"}.fa-trash-o:before{content:\"\\f014\"}.fa-home:before{content:\"\\f015\"}.fa-file-o:before{content:\"\\f016\"}.fa-clock-o:before{content:\"\\f017\"}.fa-road:before{content:\"\\f018\"}.fa-download:before{content:\"\\f019\"}.fa-arrow-circle-o-down:before{content:\"\\f01a\"}.fa-arrow-circle-o-up:before{content:\"\\f01b\"}.fa-inbox:before{content:\"\\f01c\"}.fa-play-circle-o:before{content:\"\\f01d\"}.fa-repeat:before,.fa-rotate-right:before{content:\"\\f01e\"}.fa-refresh:before{content:\"\\f021\"}.fa-list-alt:before{content:\"\\f022\"}.fa-lock:before{content:\"\\f023\"}.fa-flag:before{content:\"\\f024\"}.fa-headphones:before{content:\"\\f025\"}.fa-volume-off:before{content:\"\\f026\"}.fa-volume-down:before{content:\"\\f027\"}.fa-volume-up:before{content:\"\\f028\"}.fa-qrcode:before{content:\"\\f029\"}.fa-barcode:before{content:\"\\f02a\"}.fa-tag:before{content:\"\\f02b\"}.fa-tags:before{content:\"\\f02c\"}.fa-book:before{content:\"\\f02d\"}.fa-bookmark:before{content:\"\\f02e\"}.fa-print:before{content:\"\\f02f\"}.fa-camera:before{content:\"\\f030\"}.fa-font:before{content:\"\\f031\"}.fa-bold:before{content:\"\\f032\"}.fa-italic:before{content:\"\\f033\"}.fa-text-height:before{content:\"\\f034\"}.fa-text-width:before{content:\"\\f035\"}.fa-align-left:before{content:\"\\f036\"}.fa-align-center:before{content:\"\\f037\"}.fa-align-right:before{content:\"\\f038\"}.fa-align-justify:before{content:\"\\f039\"}.fa-list:before{content:\"\\f03a\"}.fa-dedent:before,.fa-outdent:before{content:\"\\f03b\"}.fa-indent:before{content:\"\\f03c\"}.fa-video-camera:before{content:\"\\f03d\"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:\"\\f03e\"}.fa-pencil:before{content:\"\\f040\"}.fa-map-marker:before{content:\"\\f041\"}.fa-adjust:before{content:\"\\f042\"}.fa-tint:before{content:\"\\f043\"}.fa-edit:before,.fa-pencil-square-o:before{content:\"\\f044\"}.fa-share-square-o:before{content:\"\\f045\"}.fa-check-square-o:before{content:\"\\f046\"}.fa-arrows:before{content:\"\\f047\"}.fa-step-backward:before{content:\"\\f048\"}.fa-fast-backward:before{content:\"\\f049\"}.fa-backward:before{content:\"\\f04a\"}.fa-play:before{content:\"\\f04b\"}.fa-pause:before{content:\"\\f04c\"}.fa-stop:before{content:\"\\f04d\"}.fa-forward:before{content:\"\\f04e\"}.fa-fast-forward:before{content:\"\\f050\"}.fa-step-forward:before{content:\"\\f051\"}.fa-eject:before{content:\"\\f052\"}.fa-chevron-left:before{content:\"\\f053\"}.fa-chevron-right:before{content:\"\\f054\"}.fa-plus-circle:before{content:\"\\f055\"}.fa-minus-circle:before{content:\"\\f056\"}.fa-times-circle:before{content:\"\\f057\"}.fa-check-circle:before{content:\"\\f058\"}.fa-question-circle:before{content:\"\\f059\"}.fa-info-circle:before{content:\"\\f05a\"}.fa-crosshairs:before{content:\"\\f05b\"}.fa-times-circle-o:before{content:\"\\f05c\"}.fa-check-circle-o:before{content:\"\\f05d\"}.fa-ban:before{content:\"\\f05e\"}.fa-arrow-left:before{content:\"\\f060\"}.fa-arrow-right:before{content:\"\\f061\"}.fa-arrow-up:before{content:\"\\f062\"}.fa-arrow-down:before{content:\"\\f063\"}.fa-mail-forward:before,.fa-share:before{content:\"\\f064\"}.fa-expand:before{content:\"\\f065\"}.fa-compress:before{content:\"\\f066\"}.fa-plus:before{content:\"\\f067\"}.fa-minus:before{content:\"\\f068\"}.fa-asterisk:before{content:\"\\f069\"}.fa-exclamation-circle:before{content:\"\\f06a\"}.fa-gift:before{content:\"\\f06b\"}.fa-leaf:before{content:\"\\f06c\"}.fa-fire:before{content:\"\\f06d\"}.fa-eye:before{content:\"\\f06e\"}.fa-eye-slash:before{content:\"\\f070\"}.fa-exclamation-triangle:before,.fa-warning:before{content:\"\\f071\"}.fa-plane:before{content:\"\\f072\"}.fa-calendar:before{content:\"\\f073\"}.fa-random:before{content:\"\\f074\"}.fa-comment:before{content:\"\\f075\"}.fa-magnet:before{content:\"\\f076\"}.fa-chevron-up:before{content:\"\\f077\"}.fa-chevron-down:before{content:\"\\f078\"}.fa-retweet:before{content:\"\\f079\"}.fa-shopping-cart:before{content:\"\\f07a\"}.fa-folder:before{content:\"\\f07b\"}.fa-folder-open:before{content:\"\\f07c\"}.fa-arrows-v:before{content:\"\\f07d\"}.fa-arrows-h:before{content:\"\\f07e\"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:\"\\f080\"}.fa-twitter-square:before{content:\"\\f081\"}.fa-facebook-square:before{content:\"\\f082\"}.fa-camera-retro:before{content:\"\\f083\"}.fa-key:before{content:\"\\f084\"}.fa-cogs:before,.fa-gears:before{content:\"\\f085\"}.fa-comments:before{content:\"\\f086\"}.fa-thumbs-o-up:before{content:\"\\f087\"}.fa-thumbs-o-down:before{content:\"\\f088\"}.fa-star-half:before{content:\"\\f089\"}.fa-heart-o:before{content:\"\\f08a\"}.fa-sign-out:before{content:\"\\f08b\"}.fa-linkedin-square:before{content:\"\\f08c\"}.fa-thumb-tack:before{content:\"\\f08d\"}.fa-external-link:before{content:\"\\f08e\"}.fa-sign-in:before{content:\"\\f090\"}.fa-trophy:before{content:\"\\f091\"}.fa-github-square:before{content:\"\\f092\"}.fa-upload:before{content:\"\\f093\"}.fa-lemon-o:before{content:\"\\f094\"}.fa-phone:before{content:\"\\f095\"}.fa-square-o:before{content:\"\\f096\"}.fa-bookmark-o:before{content:\"\\f097\"}.fa-phone-square:before{content:\"\\f098\"}.fa-twitter:before{content:\"\\f099\"}.fa-facebook-f:before,.fa-facebook:before{content:\"\\f09a\"}.fa-github:before{content:\"\\f09b\"}.fa-unlock:before{content:\"\\f09c\"}.fa-credit-card:before{content:\"\\f09d\"}.fa-feed:before,.fa-rss:before{content:\"\\f09e\"}.fa-hdd-o:before{content:\"\\f0a0\"}.fa-bullhorn:before{content:\"\\f0a1\"}.fa-bell:before{content:\"\\f0f3\"}.fa-certificate:before{content:\"\\f0a3\"}.fa-hand-o-right:before{content:\"\\f0a4\"}.fa-hand-o-left:before{content:\"\\f0a5\"}.fa-hand-o-up:before{content:\"\\f0a6\"}.fa-hand-o-down:before{content:\"\\f0a7\"}.fa-arrow-circle-left:before{content:\"\\f0a8\"}.fa-arrow-circle-right:before{content:\"\\f0a9\"}.fa-arrow-circle-up:before{content:\"\\f0aa\"}.fa-arrow-circle-down:before{content:\"\\f0ab\"}.fa-globe:before{content:\"\\f0ac\"}.fa-wrench:before{content:\"\\f0ad\"}.fa-tasks:before{content:\"\\f0ae\"}.fa-filter:before{content:\"\\f0b0\"}.fa-briefcase:before{content:\"\\f0b1\"}.fa-arrows-alt:before{content:\"\\f0b2\"}.fa-group:before,.fa-users:before{content:\"\\f0c0\"}.fa-chain:before,.fa-link:before{content:\"\\f0c1\"}.fa-cloud:before{content:\"\\f0c2\"}.fa-flask:before{content:\"\\f0c3\"}.fa-cut:before,.fa-scissors:before{content:\"\\f0c4\"}.fa-copy:before,.fa-files-o:before{content:\"\\f0c5\"}.fa-paperclip:before{content:\"\\f0c6\"}.fa-floppy-o:before,.fa-save:before{content:\"\\f0c7\"}.fa-square:before{content:\"\\f0c8\"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:\"\\f0c9\"}.fa-list-ul:before{content:\"\\f0ca\"}.fa-list-ol:before{content:\"\\f0cb\"}.fa-strikethrough:before{content:\"\\f0cc\"}.fa-underline:before{content:\"\\f0cd\"}.fa-table:before{content:\"\\f0ce\"}.fa-magic:before{content:\"\\f0d0\"}.fa-truck:before{content:\"\\f0d1\"}.fa-pinterest:before{content:\"\\f0d2\"}.fa-pinterest-square:before{content:\"\\f0d3\"}.fa-google-plus-square:before{content:\"\\f0d4\"}.fa-google-plus:before{content:\"\\f0d5\"}.fa-money:before{content:\"\\f0d6\"}.fa-caret-down:before{content:\"\\f0d7\"}.fa-caret-up:before{content:\"\\f0d8\"}.fa-caret-left:before{content:\"\\f0d9\"}.fa-caret-right:before{content:\"\\f0da\"}.fa-columns:before{content:\"\\f0db\"}.fa-sort:before,.fa-unsorted:before{content:\"\\f0dc\"}.fa-sort-desc:before,.fa-sort-down:before{content:\"\\f0dd\"}.fa-sort-asc:before,.fa-sort-up:before{content:\"\\f0de\"}.fa-envelope:before{content:\"\\f0e0\"}.fa-linkedin:before{content:\"\\f0e1\"}.fa-rotate-left:before,.fa-undo:before{content:\"\\f0e2\"}.fa-gavel:before,.fa-legal:before{content:\"\\f0e3\"}.fa-dashboard:before,.fa-tachometer:before{content:\"\\f0e4\"}.fa-comment-o:before{content:\"\\f0e5\"}.fa-comments-o:before{content:\"\\f0e6\"}.fa-bolt:before,.fa-flash:before{content:\"\\f0e7\"}.fa-sitemap:before{content:\"\\f0e8\"}.fa-umbrella:before{content:\"\\f0e9\"}.fa-clipboard:before,.fa-paste:before{content:\"\\f0ea\"}.fa-lightbulb-o:before{content:\"\\f0eb\"}.fa-exchange:before{content:\"\\f0ec\"}.fa-cloud-download:before{content:\"\\f0ed\"}.fa-cloud-upload:before{content:\"\\f0ee\"}.fa-user-md:before{content:\"\\f0f0\"}.fa-stethoscope:before{content:\"\\f0f1\"}.fa-suitcase:before{content:\"\\f0f2\"}.fa-bell-o:before{content:\"\\f0a2\"}.fa-coffee:before{content:\"\\f0f4\"}.fa-cutlery:before{content:\"\\f0f5\"}.fa-file-text-o:before{content:\"\\f0f6\"}.fa-building-o:before{content:\"\\f0f7\"}.fa-hospital-o:before{content:\"\\f0f8\"}.fa-ambulance:before{content:\"\\f0f9\"}.fa-medkit:before{content:\"\\f0fa\"}.fa-fighter-jet:before{content:\"\\f0fb\"}.fa-beer:before{content:\"\\f0fc\"}.fa-h-square:before{content:\"\\f0fd\"}.fa-plus-square:before{content:\"\\f0fe\"}.fa-angle-double-left:before{content:\"\\f100\"}.fa-angle-double-right:before{content:\"\\f101\"}.fa-angle-double-up:before{content:\"\\f102\"}.fa-angle-double-down:before{content:\"\\f103\"}.fa-angle-left:before{content:\"\\f104\"}.fa-angle-right:before{content:\"\\f105\"}.fa-angle-up:before{content:\"\\f106\"}.fa-angle-down:before{content:\"\\f107\"}.fa-desktop:before{content:\"\\f108\"}.fa-laptop:before{content:\"\\f109\"}.fa-tablet:before{content:\"\\f10a\"}.fa-mobile-phone:before,.fa-mobile:before{content:\"\\f10b\"}.fa-circle-o:before{content:\"\\f10c\"}.fa-quote-left:before{content:\"\\f10d\"}.fa-quote-right:before{content:\"\\f10e\"}.fa-spinner:before{content:\"\\f110\"}.fa-circle:before{content:\"\\f111\"}.fa-mail-reply:before,.fa-reply:before{content:\"\\f112\"}.fa-github-alt:before{content:\"\\f113\"}.fa-folder-o:before{content:\"\\f114\"}.fa-folder-open-o:before{content:\"\\f115\"}.fa-smile-o:before{content:\"\\f118\"}.fa-frown-o:before{content:\"\\f119\"}.fa-meh-o:before{content:\"\\f11a\"}.fa-gamepad:before{content:\"\\f11b\"}.fa-keyboard-o:before{content:\"\\f11c\"}.fa-flag-o:before{content:\"\\f11d\"}.fa-flag-checkered:before{content:\"\\f11e\"}.fa-terminal:before{content:\"\\f120\"}.fa-code:before{content:\"\\f121\"}.fa-mail-reply-all:before,.fa-reply-all:before{content:\"\\f122\"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:\"\\f123\"}.fa-location-arrow:before{content:\"\\f124\"}.fa-crop:before{content:\"\\f125\"}.fa-code-fork:before{content:\"\\f126\"}.fa-chain-broken:before,.fa-unlink:before{content:\"\\f127\"}.fa-question:before{content:\"\\f128\"}.fa-info:before{content:\"\\f129\"}.fa-exclamation:before{content:\"\\f12a\"}.fa-superscript:before{content:\"\\f12b\"}.fa-subscript:before{content:\"\\f12c\"}.fa-eraser:before{content:\"\\f12d\"}.fa-puzzle-piece:before{content:\"\\f12e\"}.fa-microphone:before{content:\"\\f130\"}.fa-microphone-slash:before{content:\"\\f131\"}.fa-shield:before{content:\"\\f132\"}.fa-calendar-o:before{content:\"\\f133\"}.fa-fire-extinguisher:before{content:\"\\f134\"}.fa-rocket:before{content:\"\\f135\"}.fa-maxcdn:before{content:\"\\f136\"}.fa-chevron-circle-left:before{content:\"\\f137\"}.fa-chevron-circle-right:before{content:\"\\f138\"}.fa-chevron-circle-up:before{content:\"\\f139\"}.fa-chevron-circle-down:before{content:\"\\f13a\"}.fa-html5:before{content:\"\\f13b\"}.fa-css3:before{content:\"\\f13c\"}.fa-anchor:before{content:\"\\f13d\"}.fa-unlock-alt:before{content:\"\\f13e\"}.fa-bullseye:before{content:\"\\f140\"}.fa-ellipsis-h:before{content:\"\\f141\"}.fa-ellipsis-v:before{content:\"\\f142\"}.fa-rss-square:before{content:\"\\f143\"}.fa-play-circle:before{content:\"\\f144\"}.fa-ticket:before{content:\"\\f145\"}.fa-minus-square:before{content:\"\\f146\"}.fa-minus-square-o:before{content:\"\\f147\"}.fa-level-up:before{content:\"\\f148\"}.fa-level-down:before{content:\"\\f149\"}.fa-check-square:before{content:\"\\f14a\"}.fa-pencil-square:before{content:\"\\f14b\"}.fa-external-link-square:before{content:\"\\f14c\"}.fa-share-square:before{content:\"\\f14d\"}.fa-compass:before{content:\"\\f14e\"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:\"\\f150\"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:\"\\f151\"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:\"\\f152\"}.fa-eur:before,.fa-euro:before{content:\"\\f153\"}.fa-gbp:before{content:\"\\f154\"}.fa-dollar:before,.fa-usd:before{content:\"\\f155\"}.fa-inr:before,.fa-rupee:before{content:\"\\f156\"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:\"\\f157\"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:\"\\f158\"}.fa-krw:before,.fa-won:before{content:\"\\f159\"}.fa-bitcoin:before,.fa-btc:before{content:\"\\f15a\"}.fa-file:before{content:\"\\f15b\"}.fa-file-text:before{content:\"\\f15c\"}.fa-sort-alpha-asc:before{content:\"\\f15d\"}.fa-sort-alpha-desc:before{content:\"\\f15e\"}.fa-sort-amount-asc:before{content:\"\\f160\"}.fa-sort-amount-desc:before{content:\"\\f161\"}.fa-sort-numeric-asc:before{content:\"\\f162\"}.fa-sort-numeric-desc:before{content:\"\\f163\"}.fa-thumbs-up:before{content:\"\\f164\"}.fa-thumbs-down:before{content:\"\\f165\"}.fa-youtube-square:before{content:\"\\f166\"}.fa-youtube:before{content:\"\\f167\"}.fa-xing:before{content:\"\\f168\"}.fa-xing-square:before{content:\"\\f169\"}.fa-youtube-play:before{content:\"\\f16a\"}.fa-dropbox:before{content:\"\\f16b\"}.fa-stack-overflow:before{content:\"\\f16c\"}.fa-instagram:before{content:\"\\f16d\"}.fa-flickr:before{content:\"\\f16e\"}.fa-adn:before{content:\"\\f170\"}.fa-bitbucket:before{content:\"\\f171\"}.fa-bitbucket-square:before{content:\"\\f172\"}.fa-tumblr:before{content:\"\\f173\"}.fa-tumblr-square:before{content:\"\\f174\"}.fa-long-arrow-down:before{content:\"\\f175\"}.fa-long-arrow-up:before{content:\"\\f176\"}.fa-long-arrow-left:before{content:\"\\f177\"}.fa-long-arrow-right:before{content:\"\\f178\"}.fa-apple:before{content:\"\\f179\"}.fa-windows:before{content:\"\\f17a\"}.fa-android:before{content:\"\\f17b\"}.fa-linux:before{content:\"\\f17c\"}.fa-dribbble:before{content:\"\\f17d\"}.fa-skype:before{content:\"\\f17e\"}.fa-foursquare:before{content:\"\\f180\"}.fa-trello:before{content:\"\\f181\"}.fa-female:before{content:\"\\f182\"}.fa-male:before{content:\"\\f183\"}.fa-gittip:before,.fa-gratipay:before{content:\"\\f184\"}.fa-sun-o:before{content:\"\\f185\"}.fa-moon-o:before{content:\"\\f186\"}.fa-archive:before{content:\"\\f187\"}.fa-bug:before{content:\"\\f188\"}.fa-vk:before{content:\"\\f189\"}.fa-weibo:before{content:\"\\f18a\"}.fa-renren:before{content:\"\\f18b\"}.fa-pagelines:before{content:\"\\f18c\"}.fa-stack-exchange:before{content:\"\\f18d\"}.fa-arrow-circle-o-right:before{content:\"\\f18e\"}.fa-arrow-circle-o-left:before{content:\"\\f190\"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:\"\\f191\"}.fa-dot-circle-o:before{content:\"\\f192\"}.fa-wheelchair:before{content:\"\\f193\"}.fa-vimeo-square:before{content:\"\\f194\"}.fa-try:before,.fa-turkish-lira:before{content:\"\\f195\"}.fa-plus-square-o:before{content:\"\\f196\"}.fa-space-shuttle:before{content:\"\\f197\"}.fa-slack:before{content:\"\\f198\"}.fa-envelope-square:before{content:\"\\f199\"}.fa-wordpress:before{content:\"\\f19a\"}.fa-openid:before{content:\"\\f19b\"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:\"\\f19c\"}.fa-graduation-cap:before,.fa-mortar-board:before{content:\"\\f19d\"}.fa-yahoo:before{content:\"\\f19e\"}.fa-google:before{content:\"\\f1a0\"}.fa-reddit:before{content:\"\\f1a1\"}.fa-reddit-square:before{content:\"\\f1a2\"}.fa-stumbleupon-circle:before{content:\"\\f1a3\"}.fa-stumbleupon:before{content:\"\\f1a4\"}.fa-delicious:before{content:\"\\f1a5\"}.fa-digg:before{content:\"\\f1a6\"}.fa-pied-piper-pp:before{content:\"\\f1a7\"}.fa-pied-piper-alt:before{content:\"\\f1a8\"}.fa-drupal:before{content:\"\\f1a9\"}.fa-joomla:before{content:\"\\f1aa\"}.fa-language:before{content:\"\\f1ab\"}.fa-fax:before{content:\"\\f1ac\"}.fa-building:before{content:\"\\f1ad\"}.fa-child:before{content:\"\\f1ae\"}.fa-paw:before{content:\"\\f1b0\"}.fa-spoon:before{content:\"\\f1b1\"}.fa-cube:before{content:\"\\f1b2\"}.fa-cubes:before{content:\"\\f1b3\"}.fa-behance:before{content:\"\\f1b4\"}.fa-behance-square:before{content:\"\\f1b5\"}.fa-steam:before{content:\"\\f1b6\"}.fa-steam-square:before{content:\"\\f1b7\"}.fa-recycle:before{content:\"\\f1b8\"}.fa-automobile:before,.fa-car:before{content:\"\\f1b9\"}.fa-cab:before,.fa-taxi:before{content:\"\\f1ba\"}.fa-tree:before{content:\"\\f1bb\"}.fa-spotify:before{content:\"\\f1bc\"}.fa-deviantart:before{content:\"\\f1bd\"}.fa-soundcloud:before{content:\"\\f1be\"}.fa-database:before{content:\"\\f1c0\"}.fa-file-pdf-o:before{content:\"\\f1c1\"}.fa-file-word-o:before{content:\"\\f1c2\"}.fa-file-excel-o:before{content:\"\\f1c3\"}.fa-file-powerpoint-o:before{content:\"\\f1c4\"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:\"\\f1c5\"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:\"\\f1c6\"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:\"\\f1c7\"}.fa-file-movie-o:before,.fa-file-video-o:before{content:\"\\f1c8\"}.fa-file-code-o:before{content:\"\\f1c9\"}.fa-vine:before{content:\"\\f1ca\"}.fa-codepen:before{content:\"\\f1cb\"}.fa-jsfiddle:before{content:\"\\f1cc\"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:\"\\f1cd\"}.fa-circle-o-notch:before{content:\"\\f1ce\"}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:\"\\f1d0\"}.fa-empire:before,.fa-ge:before{content:\"\\f1d1\"}.fa-git-square:before{content:\"\\f1d2\"}.fa-git:before{content:\"\\f1d3\"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:\"\\f1d4\"}.fa-tencent-weibo:before{content:\"\\f1d5\"}.fa-qq:before{content:\"\\f1d6\"}.fa-wechat:before,.fa-weixin:before{content:\"\\f1d7\"}.fa-paper-plane:before,.fa-send:before{content:\"\\f1d8\"}.fa-paper-plane-o:before,.fa-send-o:before{content:\"\\f1d9\"}.fa-history:before{content:\"\\f1da\"}.fa-circle-thin:before{content:\"\\f1db\"}.fa-header:before{content:\"\\f1dc\"}.fa-paragraph:before{content:\"\\f1dd\"}.fa-sliders:before{content:\"\\f1de\"}.fa-share-alt:before{content:\"\\f1e0\"}.fa-share-alt-square:before{content:\"\\f1e1\"}.fa-bomb:before{content:\"\\f1e2\"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:\"\\f1e3\"}.fa-tty:before{content:\"\\f1e4\"}.fa-binoculars:before{content:\"\\f1e5\"}.fa-plug:before{content:\"\\f1e6\"}.fa-slideshare:before{content:\"\\f1e7\"}.fa-twitch:before{content:\"\\f1e8\"}.fa-yelp:before{content:\"\\f1e9\"}.fa-newspaper-o:before{content:\"\\f1ea\"}.fa-wifi:before{content:\"\\f1eb\"}.fa-calculator:before{content:\"\\f1ec\"}.fa-paypal:before{content:\"\\f1ed\"}.fa-google-wallet:before{content:\"\\f1ee\"}.fa-cc-visa:before{content:\"\\f1f0\"}.fa-cc-mastercard:before{content:\"\\f1f1\"}.fa-cc-discover:before{content:\"\\f1f2\"}.fa-cc-amex:before{content:\"\\f1f3\"}.fa-cc-paypal:before{content:\"\\f1f4\"}.fa-cc-stripe:before{content:\"\\f1f5\"}.fa-bell-slash:before{content:\"\\f1f6\"}.fa-bell-slash-o:before{content:\"\\f1f7\"}.fa-trash:before{content:\"\\f1f8\"}.fa-copyright:before{content:\"\\f1f9\"}.fa-at:before{content:\"\\f1fa\"}.fa-eyedropper:before{content:\"\\f1fb\"}.fa-paint-brush:before{content:\"\\f1fc\"}.fa-birthday-cake:before{content:\"\\f1fd\"}.fa-area-chart:before{content:\"\\f1fe\"}.fa-pie-chart:before{content:\"\\f200\"}.fa-line-chart:before{content:\"\\f201\"}.fa-lastfm:before{content:\"\\f202\"}.fa-lastfm-square:before{content:\"\\f203\"}.fa-toggle-off:before{content:\"\\f204\"}.fa-toggle-on:before{content:\"\\f205\"}.fa-bicycle:before{content:\"\\f206\"}.fa-bus:before{content:\"\\f207\"}.fa-ioxhost:before{content:\"\\f208\"}.fa-angellist:before{content:\"\\f209\"}.fa-cc:before{content:\"\\f20a\"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:\"\\f20b\"}.fa-meanpath:before{content:\"\\f20c\"}.fa-buysellads:before{content:\"\\f20d\"}.fa-connectdevelop:before{content:\"\\f20e\"}.fa-dashcube:before{content:\"\\f210\"}.fa-forumbee:before{content:\"\\f211\"}.fa-leanpub:before{content:\"\\f212\"}.fa-sellsy:before{content:\"\\f213\"}.fa-shirtsinbulk:before{content:\"\\f214\"}.fa-simplybuilt:before{content:\"\\f215\"}.fa-skyatlas:before{content:\"\\f216\"}.fa-cart-plus:before{content:\"\\f217\"}.fa-cart-arrow-down:before{content:\"\\f218\"}.fa-diamond:before{content:\"\\f219\"}.fa-ship:before{content:\"\\f21a\"}.fa-user-secret:before{content:\"\\f21b\"}.fa-motorcycle:before{content:\"\\f21c\"}.fa-street-view:before{content:\"\\f21d\"}.fa-heartbeat:before{content:\"\\f21e\"}.fa-venus:before{content:\"\\f221\"}.fa-mars:before{content:\"\\f222\"}.fa-mercury:before{content:\"\\f223\"}.fa-intersex:before,.fa-transgender:before{content:\"\\f224\"}.fa-transgender-alt:before{content:\"\\f225\"}.fa-venus-double:before{content:\"\\f226\"}.fa-mars-double:before{content:\"\\f227\"}.fa-venus-mars:before{content:\"\\f228\"}.fa-mars-stroke:before{content:\"\\f229\"}.fa-mars-stroke-v:before{content:\"\\f22a\"}.fa-mars-stroke-h:before{content:\"\\f22b\"}.fa-neuter:before{content:\"\\f22c\"}.fa-genderless:before{content:\"\\f22d\"}.fa-facebook-official:before{content:\"\\f230\"}.fa-pinterest-p:before{content:\"\\f231\"}.fa-whatsapp:before{content:\"\\f232\"}.fa-server:before{content:\"\\f233\"}.fa-user-plus:before{content:\"\\f234\"}.fa-user-times:before{content:\"\\f235\"}.fa-bed:before,.fa-hotel:before{content:\"\\f236\"}.fa-viacoin:before{content:\"\\f237\"}.fa-train:before{content:\"\\f238\"}.fa-subway:before{content:\"\\f239\"}.fa-medium:before{content:\"\\f23a\"}.fa-y-combinator:before,.fa-yc:before{content:\"\\f23b\"}.fa-optin-monster:before{content:\"\\f23c\"}.fa-opencart:before{content:\"\\f23d\"}.fa-expeditedssl:before{content:\"\\f23e\"}.fa-battery-4:before,.fa-battery-full:before{content:\"\\f240\"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:\"\\f241\"}.fa-battery-2:before,.fa-battery-half:before{content:\"\\f242\"}.fa-battery-1:before,.fa-battery-quarter:before{content:\"\\f243\"}.fa-battery-0:before,.fa-battery-empty:before{content:\"\\f244\"}.fa-mouse-pointer:before{content:\"\\f245\"}.fa-i-cursor:before{content:\"\\f246\"}.fa-object-group:before{content:\"\\f247\"}.fa-object-ungroup:before{content:\"\\f248\"}.fa-sticky-note:before{content:\"\\f249\"}.fa-sticky-note-o:before{content:\"\\f24a\"}.fa-cc-jcb:before{content:\"\\f24b\"}.fa-cc-diners-club:before{content:\"\\f24c\"}.fa-clone:before{content:\"\\f24d\"}.fa-balance-scale:before{content:\"\\f24e\"}.fa-hourglass-o:before{content:\"\\f250\"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:\"\\f251\"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:\"\\f252\"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:\"\\f253\"}.fa-hourglass:before{content:\"\\f254\"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:\"\\f255\"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:\"\\f256\"}.fa-hand-scissors-o:before{content:\"\\f257\"}.fa-hand-lizard-o:before{content:\"\\f258\"}.fa-hand-spock-o:before{content:\"\\f259\"}.fa-hand-pointer-o:before{content:\"\\f25a\"}.fa-hand-peace-o:before{content:\"\\f25b\"}.fa-trademark:before{content:\"\\f25c\"}.fa-registered:before{content:\"\\f25d\"}.fa-creative-commons:before{content:\"\\f25e\"}.fa-gg:before{content:\"\\f260\"}.fa-gg-circle:before{content:\"\\f261\"}.fa-tripadvisor:before{content:\"\\f262\"}.fa-odnoklassniki:before{content:\"\\f263\"}.fa-odnoklassniki-square:before{content:\"\\f264\"}.fa-get-pocket:before{content:\"\\f265\"}.fa-wikipedia-w:before{content:\"\\f266\"}.fa-safari:before{content:\"\\f267\"}.fa-chrome:before{content:\"\\f268\"}.fa-firefox:before{content:\"\\f269\"}.fa-opera:before{content:\"\\f26a\"}.fa-internet-explorer:before{content:\"\\f26b\"}.fa-television:before,.fa-tv:before{content:\"\\f26c\"}.fa-contao:before{content:\"\\f26d\"}.fa-500px:before{content:\"\\f26e\"}.fa-amazon:before{content:\"\\f270\"}.fa-calendar-plus-o:before{content:\"\\f271\"}.fa-calendar-minus-o:before{content:\"\\f272\"}.fa-calendar-times-o:before{content:\"\\f273\"}.fa-calendar-check-o:before{content:\"\\f274\"}.fa-industry:before{content:\"\\f275\"}.fa-map-pin:before{content:\"\\f276\"}.fa-map-signs:before{content:\"\\f277\"}.fa-map-o:before{content:\"\\f278\"}.fa-map:before{content:\"\\f279\"}.fa-commenting:before{content:\"\\f27a\"}.fa-commenting-o:before{content:\"\\f27b\"}.fa-houzz:before{content:\"\\f27c\"}.fa-vimeo:before{content:\"\\f27d\"}.fa-black-tie:before{content:\"\\f27e\"}.fa-fonticons:before{content:\"\\f280\"}.fa-reddit-alien:before{content:\"\\f281\"}.fa-edge:before{content:\"\\f282\"}.fa-credit-card-alt:before{content:\"\\f283\"}.fa-codiepie:before{content:\"\\f284\"}.fa-modx:before{content:\"\\f285\"}.fa-fort-awesome:before{content:\"\\f286\"}.fa-usb:before{content:\"\\f287\"}.fa-product-hunt:before{content:\"\\f288\"}.fa-mixcloud:before{content:\"\\f289\"}.fa-scribd:before{content:\"\\f28a\"}.fa-pause-circle:before{content:\"\\f28b\"}.fa-pause-circle-o:before{content:\"\\f28c\"}.fa-stop-circle:before{content:\"\\f28d\"}.fa-stop-circle-o:before{content:\"\\f28e\"}.fa-shopping-bag:before{content:\"\\f290\"}.fa-shopping-basket:before{content:\"\\f291\"}.fa-hashtag:before{content:\"\\f292\"}.fa-bluetooth:before{content:\"\\f293\"}.fa-bluetooth-b:before{content:\"\\f294\"}.fa-percent:before{content:\"\\f295\"}.fa-gitlab:before{content:\"\\f296\"}.fa-wpbeginner:before{content:\"\\f297\"}.fa-wpforms:before{content:\"\\f298\"}.fa-envira:before{content:\"\\f299\"}.fa-universal-access:before{content:\"\\f29a\"}.fa-wheelchair-alt:before{content:\"\\f29b\"}.fa-question-circle-o:before{content:\"\\f29c\"}.fa-blind:before{content:\"\\f29d\"}.fa-audio-description:before{content:\"\\f29e\"}.fa-volume-control-phone:before{content:\"\\f2a0\"}.fa-braille:before{content:\"\\f2a1\"}.fa-assistive-listening-systems:before{content:\"\\f2a2\"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:\"\\f2a3\"}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:\"\\f2a4\"}.fa-glide:before{content:\"\\f2a5\"}.fa-glide-g:before{content:\"\\f2a6\"}.fa-sign-language:before,.fa-signing:before{content:\"\\f2a7\"}.fa-low-vision:before{content:\"\\f2a8\"}.fa-viadeo:before{content:\"\\f2a9\"}.fa-viadeo-square:before{content:\"\\f2aa\"}.fa-snapchat:before{content:\"\\f2ab\"}.fa-snapchat-ghost:before{content:\"\\f2ac\"}.fa-snapchat-square:before{content:\"\\f2ad\"}.fa-pied-piper:before{content:\"\\f2ae\"}.fa-first-order:before{content:\"\\f2b0\"}.fa-yoast:before{content:\"\\f2b1\"}.fa-themeisle:before{content:\"\\f2b2\"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:\"\\f2b3\"}.fa-fa:before,.fa-font-awesome:before{content:\"\\f2b4\"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}/*!\n * Preboot v2\n *\n * Open sourced under MIT license by @mdo.\n * Some variables and mixins from Bootstrap (Apache 2 license).\n */.book-langs-index{width:100%;height:100%;padding:40px 0;margin:0;overflow:auto}@media (max-width:600px){.book-langs-index{padding:0}}.book-langs-index .inner{max-width:600px;width:100%;margin:0 auto;padding:30px;background:#fff;border-radius:3px}.book-langs-index .inner h3{margin:0}.book-langs-index .inner .languages{list-style:none;padding:20px 30px;margin-top:20px;border-top:1px solid #eee}.book-langs-index .inner .languages:after,.book-langs-index .inner .languages:before{content:\" \";display:table;line-height:0}.book-langs-index .inner .languages:after{clear:both}.book-langs-index .inner .languages li{width:50%;float:left;padding:10px 5px;font-size:16px}@media (max-width:600px){.book-langs-index .inner .languages li{width:100%;max-width:100%}}.book-header{font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;overflow:visible;height:50px;padding:0 8px;z-index:2;font-size:.85em;color:#7e888b;background:0 0}.book-header .btn{display:block;height:50px;padding:0 15px;border-bottom:none;color:#ccc;text-transform:uppercase;line-height:50px;-webkit-box-shadow:none!important;box-shadow:none!important;position:relative;font-size:14px}.book-header .btn:hover{position:relative;text-decoration:none;color:#444;background:0 0}.book-header .btn:focus{outline:0}.book-header h1{margin:0;font-size:20px;font-weight:200;text-align:center;line-height:50px;opacity:0;-webkit-transition:opacity ease .4s;-moz-transition:opacity ease .4s;-o-transition:opacity ease .4s;transition:opacity ease .4s;padding-left:200px;padding-right:200px;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;-o-transition:opacity .2s ease;transition:opacity .2s ease;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.book-header h1 a,.book-header h1 a:hover{color:inherit;text-decoration:none}@media (max-width:1000px){.book-header h1{display:none}}.book-header h1 i{display:none}.book-header:hover h1{opacity:1}.book.is-loading .book-header h1 i{display:inline-block}.book.is-loading .book-header h1 a{display:none}.dropdown{position:relative}.dropdown-menu{position:absolute;top:100%;left:0;z-index:100;display:none;float:left;min-width:160px;padding:0;margin:2px 0 0;list-style:none;font-size:14px;background-color:#fafafa;border:1px solid rgba(0,0,0,.07);border-radius:1px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu.open{display:block}.dropdown-menu.dropdown-left{left:auto;right:4%}.dropdown-menu.dropdown-left .dropdown-caret{right:14px;left:auto}.dropdown-menu .dropdown-caret{position:absolute;top:-8px;left:14px;width:18px;height:10px;float:left;overflow:hidden}.dropdown-menu .dropdown-caret .caret-outer{position:absolute;border-left:9px solid transparent;border-right:9px solid transparent;border-bottom:9px solid rgba(0,0,0,.1);height:auto;left:0;top:0;width:auto;display:inline-block;margin-left:-1px}.dropdown-menu .dropdown-caret .caret-inner{position:absolute;display:inline-block;margin-top:-1px;top:0;top:1px;border-left:9px solid transparent;border-right:9px solid transparent;border-bottom:9px solid #fafafa}.dropdown-menu .buttons{border-bottom:1px solid rgba(0,0,0,.07)}.dropdown-menu .buttons:after,.dropdown-menu .buttons:before{content:\" \";display:table;line-height:0}.dropdown-menu .buttons:after{clear:both}.dropdown-menu .buttons:last-child{border-bottom:none}.dropdown-menu .buttons .button{border:0;background-color:transparent;color:#a6a6a6;width:100%;text-align:center;float:left;line-height:1.42857143;padding:8px 4px}.dropdown-menu .buttons .button:hover{color:#444}.dropdown-menu .buttons .button:focus,.dropdown-menu .buttons .button:hover{outline:0}.dropdown-menu .buttons .button.size-2{width:50%}.dropdown-menu .buttons .button.size-3{width:33%}.book-summary{font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;position:absolute;top:0;left:-300px;bottom:0;z-index:1;overflow-y:auto;width:300px;color:#364149;background:#fafafa;border-right:1px solid rgba(0,0,0,.07);-webkit-transition:left 250ms ease;-moz-transition:left 250ms ease;-o-transition:left 250ms ease;transition:left 250ms ease}.book-summary ul.summary{list-style:none;margin:0;padding:0;-webkit-transition:top .5s ease;-moz-transition:top .5s ease;-o-transition:top .5s ease;transition:top .5s ease}.book-summary ul.summary li{list-style:none}.book-summary ul.summary li.header{padding:10px 15px;padding-top:20px;text-transform:uppercase;color:#939da3}.book-summary ul.summary li.divider{height:1px;margin:7px 0;overflow:hidden;background:rgba(0,0,0,.07)}.book-summary ul.summary li i.fa-check{display:none;position:absolute;right:9px;top:16px;font-size:9px;color:#3c3}.book-summary ul.summary li.done>a{color:#364149;font-weight:400}.book-summary ul.summary li.done>a i{display:inline}.book-summary ul.summary li a,.book-summary ul.summary li span{display:block;padding:10px 15px;border-bottom:none;color:#364149;background:0 0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;position:relative}.book-summary ul.summary li a:hover{text-decoration:underline}.book-summary ul.summary li a:focus{outline:0}.book-summary ul.summary li.active>a{color:#008cff;background:0 0;text-decoration:none}.book-summary ul.summary li ul{padding-left:20px}@media (max-width:600px){.book-summary{width:calc(100% - 60px);bottom:0;left:-100%}}.book.with-summary .book-summary{left:0}.book.without-animation .book-summary{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;transition:none!important}.book{position:relative;width:100%;height:100%}@media (min-width:600px){.book.with-summary .book-body{left:300px}}@media (max-width:600px){.book.with-summary{overflow:hidden}.book.with-summary .book-body{-webkit-transform:translate(calc(100% - 60px),0);-moz-transform:translate(calc(100% - 60px),0);-ms-transform:translate(calc(100% - 60px),0);-o-transform:translate(calc(100% - 60px),0);transform:translate(calc(100% - 60px),0)}}.book.without-animation .book-body{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;transition:none!important}.book-body{position:absolute;top:0;right:0;left:0;bottom:0;overflow-y:auto;color:#000;background:#fff;-webkit-transition:left 250ms ease;-moz-transition:left 250ms ease;-o-transition:left 250ms ease;transition:left 250ms ease}.book-body .body-inner{position:absolute;top:0;right:0;left:0;bottom:0;overflow-y:auto}@media (max-width:1240px){.book-body{-webkit-transition:-webkit-transform 250ms ease;-moz-transition:-moz-transform 250ms ease;-o-transition:-o-transform 250ms ease;transition:transform 250ms ease;padding-bottom:20px}.book-body .body-inner{position:static;min-height:calc(100% - 50px)}}.page-wrapper{position:relative;outline:0}.page-inner{position:relative;max-width:800px;margin:0 auto;padding:20px 15px 40px 15px}.page-inner .btn-group .btn{border-radius:0;background:#eee;border:0}.buttons:after,.buttons:before{content:\" \";display:table;line-height:0}.buttons:after{clear:both}.button{border:0;background-color:transparent;background:#eee;color:#666;width:100%;text-align:center;float:left;line-height:1.42857143;padding:8px 4px}.button:hover{color:#444}.button:focus,.button:hover{outline:0}.button.size-2{width:50%}.button.size-3{width:33%}.markdown-section{display:block;word-wrap:break-word;overflow:hidden;color:#333;line-height:1.7;text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%}.markdown-section *{box-sizing:border-box;-webkit-box-sizing:border-box;font-size:inherit}.markdown-section>:first-child{margin-top:0!important}.markdown-section>:last-child{margin-bottom:0!important}.markdown-section blockquote,.markdown-section code,.markdown-section figure,.markdown-section img,.markdown-section pre,.markdown-section table,.markdown-section tr{page-break-inside:avoid}.markdown-section h2,.markdown-section h3,.markdown-section h4,.markdown-section h5,.markdown-section p{orphans:3;widows:3}.markdown-section h1,.markdown-section h2,.markdown-section h3,.markdown-section h4,.markdown-section h5{page-break-after:avoid}.markdown-section b,.markdown-section strong{font-weight:700}.markdown-section em{font-style:italic}.markdown-section blockquote,.markdown-section dl,.markdown-section ol,.markdown-section p,.markdown-section table,.markdown-section ul{margin-top:0;margin-bottom:.85em}.markdown-section a{color:#4183c4;text-decoration:none;background:0 0}.markdown-section a:active,.markdown-section a:focus,.markdown-section a:hover{outline:0;text-decoration:underline}.markdown-section img{border:0;max-width:100%}.markdown-section hr{height:4px;padding:0;margin:1.7em 0;overflow:hidden;background-color:#e7e7e7;border:none}.markdown-section hr:after,.markdown-section hr:before{display:table;content:\" \"}.markdown-section hr:after{clear:both}.markdown-section h1,.markdown-section h2,.markdown-section h3,.markdown-section h4,.markdown-section h5,.markdown-section h6{margin-top:1.275em;margin-bottom:.85em;font-weight:700}.markdown-section h1{font-size:2em}.markdown-section h2{font-size:1.75em}.markdown-section h3{font-size:1.5em}.markdown-section h4{font-size:1.25em}.markdown-section h5{font-size:1em}.markdown-section h6{font-size:1em;color:#777}.markdown-section code,.markdown-section pre{font-family:Consolas,\"Liberation Mono\",Menlo,Courier,monospace;direction:ltr;margin:0;padding:0;border:none;color:inherit}.markdown-section pre{overflow:auto;word-wrap:normal;margin:0;padding:.85em 1em;margin-bottom:1.275em;background:#f7f7f7}.markdown-section pre>code{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;font-size:.85em;white-space:pre;background:0 0}.markdown-section pre>code:after,.markdown-section pre>code:before{content:normal}.markdown-section code{padding:.2em;margin:0;font-size:.85em;background-color:#f7f7f7}.markdown-section code:after,.markdown-section code:before{letter-spacing:-.2em;content:\"\\00a0\"}.markdown-section table{display:table;width:100%;border-collapse:collapse;border-spacing:0;overflow:auto}.markdown-section table td,.markdown-section table th{padding:6px 13px;border:1px solid #ddd}.markdown-section table tr{background-color:#fff;border-top:1px solid #ccc}.markdown-section table tr:nth-child(2n){background-color:#f8f8f8}.markdown-section table th{font-weight:700}.markdown-section ol,.markdown-section ul{padding:0;margin:0;margin-bottom:.85em;padding-left:2em}.markdown-section ol ol,.markdown-section ol ul,.markdown-section ul ol,.markdown-section ul ul{margin-top:0;margin-bottom:0}.markdown-section ol ol{list-style-type:lower-roman}.markdown-section blockquote{margin:0;margin-bottom:.85em;padding:0 15px;color:#858585;border-left:4px solid #e5e5e5}.markdown-section blockquote:first-child{margin-top:0}.markdown-section blockquote:last-child{margin-bottom:0}.markdown-section dl{padding:0}.markdown-section dl dt{padding:0;margin-top:.85em;font-style:italic;font-weight:700}.markdown-section dl dd{padding:0 .85em;margin-bottom:.85em}.markdown-section dd{margin-left:0}.markdown-section .glossary-term{cursor:help;text-decoration:underline}.navigation{position:absolute;top:50px;bottom:0;margin:0;max-width:150px;min-width:90px;display:flex;justify-content:center;align-content:center;flex-direction:column;font-size:40px;color:#ccc;text-align:center;-webkit-transition:all 350ms ease;-moz-transition:all 350ms ease;-o-transition:all 350ms ease;transition:all 350ms ease}.navigation:hover{text-decoration:none;color:#444}.navigation.navigation-next{right:0}.navigation.navigation-prev{left:0}@media (max-width:1240px){.navigation{position:static;top:auto;max-width:50%;width:50%;display:inline-block;float:left}.navigation.navigation-unique{max-width:100%;width:100%}}#book-search-input{padding:6px;background:0 0;transition:top .5s ease;background:#fff;border-bottom:1px solid rgba(0,0,0,.07);border-top:1px solid rgba(0,0,0,.07);margin-bottom:10px;margin-top:-1px}#book-search-input input,#book-search-input input:focus,#book-search-input input:hover{width:100%;background:0 0;border:1px solid transparent;box-shadow:none;outline:0;line-height:22px;padding:7px 7px;color:inherit}#book-search-results{opacity:1}#book-search-results .search-results .search-results-title{text-transform:uppercase;text-align:center;font-weight:200;margin-bottom:35px;opacity:.6}#book-search-results .search-results .has-results .search-results-item{display:block;word-wrap:break-word;overflow:hidden;color:#333;line-height:1.7;text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%}#book-search-results .search-results .has-results .search-results-item *{box-sizing:border-box;-webkit-box-sizing:border-box;font-size:inherit}#book-search-results .search-results .has-results .search-results-item>:first-child{margin-top:0!important}#book-search-results .search-results .has-results .search-results-item>:last-child{margin-bottom:0!important}#book-search-results .search-results .has-results .search-results-item blockquote,#book-search-results .search-results .has-results .search-results-item code,#book-search-results .search-results .has-results .search-results-item figure,#book-search-results .search-results .has-results .search-results-item img,#book-search-results .search-results .has-results .search-results-item pre,#book-search-results .search-results .has-results .search-results-item table,#book-search-results .search-results .has-results .search-results-item tr{page-break-inside:avoid}#book-search-results .search-results .has-results .search-results-item h2,#book-search-results .search-results .has-results .search-results-item h3,#book-search-results .search-results .has-results .search-results-item h4,#book-search-results .search-results .has-results .search-results-item h5,#book-search-results .search-results .has-results .search-results-item p{orphans:3;widows:3}#book-search-results .search-results .has-results .search-results-item h1,#book-search-results .search-results .has-results .search-results-item h2,#book-search-results .search-results .has-results .search-results-item h3,#book-search-results .search-results .has-results .search-results-item h4,#book-search-results .search-results .has-results .search-results-item h5{page-break-after:avoid}#book-search-results .search-results .has-results .search-results-item b,#book-search-results .search-results .has-results .search-results-item strong{font-weight:700}#book-search-results .search-results .has-results .search-results-item em{font-style:italic}#book-search-results .search-results .has-results .search-results-item blockquote,#book-search-results .search-results .has-results .search-results-item dl,#book-search-results .search-results .has-results .search-results-item ol,#book-search-results .search-results .has-results .search-results-item p,#book-search-results .search-results .has-results .search-results-item table,#book-search-results .search-results .has-results .search-results-item ul{margin-top:0;margin-bottom:.85em}#book-search-results .search-results .has-results .search-results-item a{color:#4183c4;text-decoration:none;background:0 0}#book-search-results .search-results .has-results .search-results-item a:active,#book-search-results .search-results .has-results .search-results-item a:focus,#book-search-results .search-results .has-results .search-results-item a:hover{outline:0;text-decoration:underline}#book-search-results .search-results .has-results .search-results-item img{border:0;max-width:100%}#book-search-results .search-results .has-results .search-results-item hr{height:4px;padding:0;margin:1.7em 0;overflow:hidden;background-color:#e7e7e7;border:none}#book-search-results .search-results .has-results .search-results-item hr:after,#book-search-results .search-results .has-results .search-results-item hr:before{display:table;content:\" \"}#book-search-results .search-results .has-results .search-results-item hr:after{clear:both}#book-search-results .search-results .has-results .search-results-item h1,#book-search-results .search-results .has-results .search-results-item h2,#book-search-results .search-results .has-results .search-results-item h3,#book-search-results .search-results .has-results .search-results-item h4,#book-search-results .search-results .has-results .search-results-item h5,#book-search-results .search-results .has-results .search-results-item h6{margin-top:1.275em;margin-bottom:.85em;font-weight:700}#book-search-results .search-results .has-results .search-results-item h1{font-size:2em}#book-search-results .search-results .has-results .search-results-item h2{font-size:1.75em}#book-search-results .search-results .has-results .search-results-item h3{font-size:1.5em}#book-search-results .search-results .has-results .search-results-item h4{font-size:1.25em}#book-search-results .search-results .has-results .search-results-item h5{font-size:1em}#book-search-results .search-results .has-results .search-results-item h6{font-size:1em;color:#777}#book-search-results .search-results .has-results .search-results-item code,#book-search-results .search-results .has-results .search-results-item pre{font-family:Consolas,\"Liberation Mono\",Menlo,Courier,monospace;direction:ltr;margin:0;padding:0;border:none;color:inherit}#book-search-results .search-results .has-results .search-results-item pre{overflow:auto;word-wrap:normal;margin:0;padding:.85em 1em;margin-bottom:1.275em;background:#f7f7f7}#book-search-results .search-results .has-results .search-results-item pre>code{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;font-size:.85em;white-space:pre;background:0 0}#book-search-results .search-results .has-results .search-results-item pre>code:after,#book-search-results .search-results .has-results .search-results-item pre>code:before{content:normal}#book-search-results .search-results .has-results .search-results-item code{padding:.2em;margin:0;font-size:.85em;background-color:#f7f7f7}#book-search-results .search-results .has-results .search-results-item code:after,#book-search-results .search-results .has-results .search-results-item code:before{letter-spacing:-.2em;content:\"\\00a0\"}#book-search-results .search-results .has-results .search-results-item table{display:table;width:100%;border-collapse:collapse;border-spacing:0;overflow:auto}#book-search-results .search-results .has-results .search-results-item table td,#book-search-results .search-results .has-results .search-results-item table th{padding:6px 13px;border:1px solid #ddd}#book-search-results .search-results .has-results .search-results-item table tr{background-color:#fff;border-top:1px solid #ccc}#book-search-results .search-results .has-results .search-results-item table tr:nth-child(2n){background-color:#f8f8f8}#book-search-results .search-results .has-results .search-results-item table th{font-weight:700}#book-search-results .search-results .has-results .search-results-item ol,#book-search-results .search-results .has-results .search-results-item ul{padding:0;margin:0;margin-bottom:.85em;padding-left:2em}#book-search-results .search-results .has-results .search-results-item ol ol,#book-search-results .search-results .has-results .search-results-item ol ul,#book-search-results .search-results .has-results .search-results-item ul ol,#book-search-results .search-results .has-results .search-results-item ul ul{margin-top:0;margin-bottom:0}#book-search-results .search-results .has-results .search-results-item ol ol{list-style-type:lower-roman}#book-search-results .search-results .has-results .search-results-item blockquote{margin:0;margin-bottom:.85em;padding:0 15px;color:#858585;border-left:4px solid #e5e5e5}#book-search-results .search-results .has-results .search-results-item blockquote:first-child{margin-top:0}#book-search-results .search-results .has-results .search-results-item blockquote:last-child{margin-bottom:0}#book-search-results .search-results .has-results .search-results-item dl{padding:0}#book-search-results .search-results .has-results .search-results-item dl dt{padding:0;margin-top:.85em;font-style:italic;font-weight:700}#book-search-results .search-results .has-results .search-results-item dl dd{padding:0 .85em;margin-bottom:.85em}#book-search-results .search-results .has-results .search-results-item dd{margin-left:0}#book-search-results .search-results .has-results .search-results-item h3{margin-top:0;margin-bottom:0}#book-search-results .search-results .no-results{padding:40px 0}body.search-loading #book-search-results{opacity:.3}body.with-search .navigation{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:none;-webkit-touch-callout:none;-webkit-font-smoothing:antialiased}a{text-decoration:none}body,html{height:100%}html{font-size:62.5%}body{text-rendering:optimizeLegibility;font-smoothing:antialiased;font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:.2px;text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/gitbook/theme.js",
    "content": "!function e(t,n,r){function o(a,s){if(!n[a]){if(!t[a]){var u=\"function\"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);var l=new Error(\"Cannot find module '\"+a+\"'\");throw l.code=\"MODULE_NOT_FOUND\",l}var c=n[a]={exports:{}};t[a][0].call(c.exports,function(e){var n=t[a][1][e];return o(n?n:e)},c,c.exports,e,t,n,r)}return n[a].exports}for(var i=\"function\"==typeof require&&require,a=0;a<r.length;a++)o(r[a]);return o}({1:[function(e,t,n){!function(e,n){\"use strict\";\"object\"==typeof t&&\"object\"==typeof t.exports?t.exports=e.document?n(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return n(e)}:n(e)}(\"undefined\"!=typeof window?window:this,function(e,t){\"use strict\";function n(e,t){t=t||te;var n=t.createElement(\"script\");n.text=e,t.head.appendChild(n).parentNode.removeChild(n)}function r(e){var t=!!e&&\"length\"in e&&e.length,n=de.type(e);return\"function\"!==n&&!de.isWindow(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&t>0&&t-1 in e)}function o(e,t,n){return de.isFunction(t)?de.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?de.grep(e,function(e){return e===t!==n}):\"string\"!=typeof t?de.grep(e,function(e){return ae.call(t,e)>-1!==n}):ke.test(t)?de.filter(t,e,n):(t=de.filter(t,e),de.grep(e,function(e){return ae.call(t,e)>-1!==n&&1===e.nodeType}))}function i(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function a(e){var t={};return de.each(e.match(qe)||[],function(e,n){t[n]=!0}),t}function s(e){return e}function u(e){throw e}function l(e,t,n){var r;try{e&&de.isFunction(r=e.promise)?r.call(e).done(t).fail(n):e&&de.isFunction(r=e.then)?r.call(e,t,n):t.call(void 0,e)}catch(e){n.call(void 0,e)}}function c(){te.removeEventListener(\"DOMContentLoaded\",c),e.removeEventListener(\"load\",c),de.ready()}function f(){this.expando=de.expando+f.uid++}function p(e){return\"true\"===e||\"false\"!==e&&(\"null\"===e?null:e===+e+\"\"?+e:Ie.test(e)?JSON.parse(e):e)}function h(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r=\"data-\"+t.replace(Re,\"-$&\").toLowerCase(),n=e.getAttribute(r),\"string\"==typeof n){try{n=p(n)}catch(e){}Pe.set(e,t,n)}else n=void 0;return n}function d(e,t,n,r){var o,i=1,a=20,s=r?function(){return r.cur()}:function(){return de.css(e,t,\"\")},u=s(),l=n&&n[3]||(de.cssNumber[t]?\"\":\"px\"),c=(de.cssNumber[t]||\"px\"!==l&&+u)&&$e.exec(de.css(e,t));if(c&&c[3]!==l){l=l||c[3],n=n||[],c=+u||1;do i=i||\".5\",c/=i,de.style(e,t,c+l);while(i!==(i=s()/u)&&1!==i&&--a)}return n&&(c=+c||+u||0,o=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=o)),o}function g(e){var t,n=e.ownerDocument,r=e.nodeName,o=Ue[r];return o?o:(t=n.body.appendChild(n.createElement(r)),o=de.css(t,\"display\"),t.parentNode.removeChild(t),\"none\"===o&&(o=\"block\"),Ue[r]=o,o)}function m(e,t){for(var n,r,o=[],i=0,a=e.length;i<a;i++)r=e[i],r.style&&(n=r.style.display,t?(\"none\"===n&&(o[i]=Fe.get(r,\"display\")||null,o[i]||(r.style.display=\"\")),\"\"===r.style.display&&We(r)&&(o[i]=g(r))):\"none\"!==n&&(o[i]=\"none\",Fe.set(r,\"display\",n)));for(i=0;i<a;i++)null!=o[i]&&(e[i].style.display=o[i]);return e}function v(e,t){var n;return n=\"undefined\"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):\"undefined\"!=typeof e.querySelectorAll?e.querySelectorAll(t||\"*\"):[],void 0===t||t&&de.nodeName(e,t)?de.merge([e],n):n}function y(e,t){for(var n=0,r=e.length;n<r;n++)Fe.set(e[n],\"globalEval\",!t||Fe.get(t[n],\"globalEval\"))}function b(e,t,n,r,o){for(var i,a,s,u,l,c,f=t.createDocumentFragment(),p=[],h=0,d=e.length;h<d;h++)if(i=e[h],i||0===i)if(\"object\"===de.type(i))de.merge(p,i.nodeType?[i]:i);else if(Ge.test(i)){for(a=a||f.appendChild(t.createElement(\"div\")),s=(Xe.exec(i)||[\"\",\"\"])[1].toLowerCase(),u=Ve[s]||Ve._default,a.innerHTML=u[1]+de.htmlPrefilter(i)+u[2],c=u[0];c--;)a=a.lastChild;de.merge(p,a.childNodes),a=f.firstChild,a.textContent=\"\"}else p.push(t.createTextNode(i));for(f.textContent=\"\",h=0;i=p[h++];)if(r&&de.inArray(i,r)>-1)o&&o.push(i);else if(l=de.contains(i.ownerDocument,i),a=v(f.appendChild(i),\"script\"),l&&y(a),n)for(c=0;i=a[c++];)Ke.test(i.type||\"\")&&n.push(i);return f}function x(){return!0}function w(){return!1}function C(){try{return te.activeElement}catch(e){}}function T(e,t,n,r,o,i){var a,s;if(\"object\"==typeof t){\"string\"!=typeof n&&(r=r||n,n=void 0);for(s in t)T(e,s,n,r,t[s],i);return e}if(null==r&&null==o?(o=n,r=n=void 0):null==o&&(\"string\"==typeof n?(o=r,r=void 0):(o=r,r=n,n=void 0)),o===!1)o=w;else if(!o)return e;return 1===i&&(a=o,o=function(e){return de().off(e),a.apply(this,arguments)},o.guid=a.guid||(a.guid=de.guid++)),e.each(function(){de.event.add(this,t,o,r,n)})}function k(e,t){return de.nodeName(e,\"table\")&&de.nodeName(11!==t.nodeType?t:t.firstChild,\"tr\")?e.getElementsByTagName(\"tbody\")[0]||e:e}function j(e){return e.type=(null!==e.getAttribute(\"type\"))+\"/\"+e.type,e}function E(e){var t=rt.exec(e.type);return t?e.type=t[1]:e.removeAttribute(\"type\"),e}function N(e,t){var n,r,o,i,a,s,u,l;if(1===t.nodeType){if(Fe.hasData(e)&&(i=Fe.access(e),a=Fe.set(t,i),l=i.events)){delete a.handle,a.events={};for(o in l)for(n=0,r=l[o].length;n<r;n++)de.event.add(t,o,l[o][n])}Pe.hasData(e)&&(s=Pe.access(e),u=de.extend({},s),Pe.set(t,u))}}function S(e,t){var n=t.nodeName.toLowerCase();\"input\"===n&&ze.test(e.type)?t.checked=e.checked:\"input\"!==n&&\"textarea\"!==n||(t.defaultValue=e.defaultValue)}function A(e,t,r,o){t=oe.apply([],t);var i,a,s,u,l,c,f=0,p=e.length,h=p-1,d=t[0],g=de.isFunction(d);if(g||p>1&&\"string\"==typeof d&&!pe.checkClone&&nt.test(d))return e.each(function(n){var i=e.eq(n);g&&(t[0]=d.call(this,n,i.html())),A(i,t,r,o)});if(p&&(i=b(t,e[0].ownerDocument,!1,e,o),a=i.firstChild,1===i.childNodes.length&&(i=a),a||o)){for(s=de.map(v(i,\"script\"),j),u=s.length;f<p;f++)l=i,f!==h&&(l=de.clone(l,!0,!0),u&&de.merge(s,v(l,\"script\"))),r.call(e[f],l,f);if(u)for(c=s[s.length-1].ownerDocument,de.map(s,E),f=0;f<u;f++)l=s[f],Ke.test(l.type||\"\")&&!Fe.access(l,\"globalEval\")&&de.contains(c,l)&&(l.src?de._evalUrl&&de._evalUrl(l.src):n(l.textContent.replace(ot,\"\"),c))}return e}function q(e,t,n){for(var r,o=t?de.filter(t,e):e,i=0;null!=(r=o[i]);i++)n||1!==r.nodeType||de.cleanData(v(r)),r.parentNode&&(n&&de.contains(r.ownerDocument,r)&&y(v(r,\"script\")),r.parentNode.removeChild(r));return e}function D(e,t,n){var r,o,i,a,s=e.style;return n=n||st(e),n&&(a=n.getPropertyValue(t)||n[t],\"\"!==a||de.contains(e.ownerDocument,e)||(a=de.style(e,t)),!pe.pixelMarginRight()&&at.test(a)&&it.test(t)&&(r=s.width,o=s.minWidth,i=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=o,s.maxWidth=i)),void 0!==a?a+\"\":a}function O(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function L(e){if(e in pt)return e;for(var t=e[0].toUpperCase()+e.slice(1),n=ft.length;n--;)if(e=ft[n]+t,e in pt)return e}function H(e,t,n){var r=$e.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||\"px\"):t}function F(e,t,n,r,o){var i,a=0;for(i=n===(r?\"border\":\"content\")?4:\"width\"===t?1:0;i<4;i+=2)\"margin\"===n&&(a+=de.css(e,n+_e[i],!0,o)),r?(\"content\"===n&&(a-=de.css(e,\"padding\"+_e[i],!0,o)),\"margin\"!==n&&(a-=de.css(e,\"border\"+_e[i]+\"Width\",!0,o))):(a+=de.css(e,\"padding\"+_e[i],!0,o),\"padding\"!==n&&(a+=de.css(e,\"border\"+_e[i]+\"Width\",!0,o)));return a}function P(e,t,n){var r,o=!0,i=st(e),a=\"border-box\"===de.css(e,\"boxSizing\",!1,i);if(e.getClientRects().length&&(r=e.getBoundingClientRect()[t]),r<=0||null==r){if(r=D(e,t,i),(r<0||null==r)&&(r=e.style[t]),at.test(r))return r;o=a&&(pe.boxSizingReliable()||r===e.style[t]),r=parseFloat(r)||0}return r+F(e,t,n||(a?\"border\":\"content\"),o,i)+\"px\"}function I(e,t,n,r,o){return new I.prototype.init(e,t,n,r,o)}function R(){dt&&(e.requestAnimationFrame(R),de.fx.tick())}function M(){return e.setTimeout(function(){ht=void 0}),ht=de.now()}function $(e,t){var n,r=0,o={height:e};for(t=t?1:0;r<4;r+=2-t)n=_e[r],o[\"margin\"+n]=o[\"padding\"+n]=e;return t&&(o.opacity=o.width=e),o}function _(e,t,n){for(var r,o=(U.tweeners[t]||[]).concat(U.tweeners[\"*\"]),i=0,a=o.length;i<a;i++)if(r=o[i].call(n,t,e))return r}function W(e,t,n){var r,o,i,a,s,u,l,c,f=\"width\"in t||\"height\"in t,p=this,h={},d=e.style,g=e.nodeType&&We(e),v=Fe.get(e,\"fxshow\");n.queue||(a=de._queueHooks(e,\"fx\"),null==a.unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,de.queue(e,\"fx\").length||a.empty.fire()})}));for(r in t)if(o=t[r],gt.test(o)){if(delete t[r],i=i||\"toggle\"===o,o===(g?\"hide\":\"show\")){if(\"show\"!==o||!v||void 0===v[r])continue;g=!0}h[r]=v&&v[r]||de.style(e,r)}if(u=!de.isEmptyObject(t),u||!de.isEmptyObject(h)){f&&1===e.nodeType&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],l=v&&v.display,null==l&&(l=Fe.get(e,\"display\")),c=de.css(e,\"display\"),\"none\"===c&&(l?c=l:(m([e],!0),l=e.style.display||l,c=de.css(e,\"display\"),m([e]))),(\"inline\"===c||\"inline-block\"===c&&null!=l)&&\"none\"===de.css(e,\"float\")&&(u||(p.done(function(){d.display=l}),null==l&&(c=d.display,l=\"none\"===c?\"\":c)),d.display=\"inline-block\")),n.overflow&&(d.overflow=\"hidden\",p.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]})),u=!1;for(r in h)u||(v?\"hidden\"in v&&(g=v.hidden):v=Fe.access(e,\"fxshow\",{display:l}),i&&(v.hidden=!g),g&&m([e],!0),p.done(function(){g||m([e]),Fe.remove(e,\"fxshow\");for(r in h)de.style(e,r,h[r])})),u=_(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}}function B(e,t){var n,r,o,i,a;for(n in e)if(r=de.camelCase(n),o=t[r],i=e[n],de.isArray(i)&&(o=i[1],i=e[n]=i[0]),n!==r&&(e[r]=i,delete e[n]),a=de.cssHooks[r],a&&\"expand\"in a){i=a.expand(i),delete e[r];for(n in i)n in e||(e[n]=i[n],t[n]=o)}else t[r]=o}function U(e,t,n){var r,o,i=0,a=U.prefilters.length,s=de.Deferred().always(function(){delete u.elem}),u=function(){if(o)return!1;for(var t=ht||M(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,i=1-r,a=0,u=l.tweens.length;a<u;a++)l.tweens[a].run(i);return s.notifyWith(e,[l,i,n]),i<1&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:de.extend({},t),opts:de.extend(!0,{specialEasing:{},easing:de.easing._default},n),originalProperties:t,originalOptions:n,startTime:ht||M(),duration:n.duration,tweens:[],createTween:function(t,n){var r=de.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(o)return this;for(o=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(B(c,l.opts.specialEasing);i<a;i++)if(r=U.prefilters[i].call(l,e,c,l.opts))return de.isFunction(r.stop)&&(de._queueHooks(l.elem,l.opts.queue).stop=de.proxy(r.stop,r)),r;return de.map(c,_,l),de.isFunction(l.opts.start)&&l.opts.start.call(e,l),de.fx.timer(de.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function z(e){var t=e.match(qe)||[];return t.join(\" \")}function X(e){return e.getAttribute&&e.getAttribute(\"class\")||\"\"}function K(e,t,n,r){var o;if(de.isArray(t))de.each(t,function(t,o){n||Et.test(e)?r(e,o):K(e+\"[\"+(\"object\"==typeof o&&null!=o?t:\"\")+\"]\",o,n,r)});else if(n||\"object\"!==de.type(t))r(e,t);else for(o in t)K(e+\"[\"+o+\"]\",t[o],n,r)}function V(e){return function(t,n){\"string\"!=typeof t&&(n=t,t=\"*\");var r,o=0,i=t.toLowerCase().match(qe)||[];if(de.isFunction(n))for(;r=i[o++];)\"+\"===r[0]?(r=r.slice(1)||\"*\",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function G(e,t,n,r){function o(s){var u;return i[s]=!0,de.each(e[s]||[],function(e,s){var l=s(t,n,r);return\"string\"!=typeof l||a||i[l]?a?!(u=l):void 0:(t.dataTypes.unshift(l),o(l),!1)}),u}var i={},a=e===Rt;return o(t.dataTypes[0])||!i[\"*\"]&&o(\"*\")}function Y(e,t){var n,r,o=de.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((o[n]?e:r||(r={}))[n]=t[n]);return r&&de.extend(!0,e,r),e}function Q(e,t,n){for(var r,o,i,a,s=e.contents,u=e.dataTypes;\"*\"===u[0];)u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader(\"Content-Type\"));if(r)for(o in s)if(s[o]&&s[o].test(r)){u.unshift(o);break}if(u[0]in n)i=u[0];else{for(o in n){if(!u[0]||e.converters[o+\" \"+u[0]]){i=o;break}a||(a=o)}i=i||a}if(i)return i!==u[0]&&u.unshift(i),n[i]}function J(e,t,n,r){var o,i,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(i=c.shift();i;)if(e.responseFields[i]&&(n[e.responseFields[i]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=i,i=c.shift())if(\"*\"===i)i=u;else if(\"*\"!==u&&u!==i){if(a=l[u+\" \"+i]||l[\"* \"+i],!a)for(o in l)if(s=o.split(\" \"),s[1]===i&&(a=l[u+\" \"+s[0]]||l[\"* \"+s[0]])){a===!0?a=l[o]:l[o]!==!0&&(i=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:\"parsererror\",error:a?e:\"No conversion from \"+u+\" to \"+i}}}return{state:\"success\",data:t}}function Z(e){return de.isWindow(e)?e:9===e.nodeType&&e.defaultView}var ee=[],te=e.document,ne=Object.getPrototypeOf,re=ee.slice,oe=ee.concat,ie=ee.push,ae=ee.indexOf,se={},ue=se.toString,le=se.hasOwnProperty,ce=le.toString,fe=ce.call(Object),pe={},he=\"3.1.1\",de=function(e,t){return new de.fn.init(e,t)},ge=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,me=/^-ms-/,ve=/-([a-z])/g,ye=function(e,t){return t.toUpperCase()};de.fn=de.prototype={jquery:he,constructor:de,length:0,toArray:function(){return re.call(this)},get:function(e){return null==e?re.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=de.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return de.each(this,e)},map:function(e){return this.pushStack(de.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(re.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:ie,sort:ee.sort,splice:ee.splice},de.extend=de.fn.extend=function(){var e,t,n,r,o,i,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for(\"boolean\"==typeof a&&(l=a,a=arguments[s]||{},s++),\"object\"==typeof a||de.isFunction(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],r=e[t],a!==r&&(l&&r&&(de.isPlainObject(r)||(o=de.isArray(r)))?(o?(o=!1,i=n&&de.isArray(n)?n:[]):i=n&&de.isPlainObject(n)?n:{},a[t]=de.extend(l,i,r)):void 0!==r&&(a[t]=r));return a},de.extend({expando:\"jQuery\"+(he+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isFunction:function(e){return\"function\"===de.type(e)},isArray:Array.isArray,isWindow:function(e){return null!=e&&e===e.window},isNumeric:function(e){var t=de.type(e);return(\"number\"===t||\"string\"===t)&&!isNaN(e-parseFloat(e))},isPlainObject:function(e){var t,n;return!(!e||\"[object Object]\"!==ue.call(e))&&(!(t=ne(e))||(n=le.call(t,\"constructor\")&&t.constructor,\"function\"==typeof n&&ce.call(n)===fe))},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},type:function(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?se[ue.call(e)]||\"object\":typeof e},globalEval:function(e){n(e)},camelCase:function(e){return e.replace(me,\"ms-\").replace(ve,ye)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var n,o=0;if(r(e))for(n=e.length;o<n&&t.call(e[o],o,e[o])!==!1;o++);else for(o in e)if(t.call(e[o],o,e[o])===!1)break;return e},trim:function(e){return null==e?\"\":(e+\"\").replace(ge,\"\")},makeArray:function(e,t){var n=t||[];return null!=e&&(r(Object(e))?de.merge(n,\"string\"==typeof e?[e]:e):ie.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:ae.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,o=e.length;r<n;r++)e[o++]=t[r];return e.length=o,e},grep:function(e,t,n){for(var r,o=[],i=0,a=e.length,s=!n;i<a;i++)r=!t(e[i],i),r!==s&&o.push(e[i]);return o},map:function(e,t,n){var o,i,a=0,s=[];if(r(e))for(o=e.length;a<o;a++)i=t(e[a],a,n),null!=i&&s.push(i);else for(a in e)i=t(e[a],a,n),null!=i&&s.push(i);return oe.apply([],s)},guid:1,proxy:function(e,t){var n,r,o;if(\"string\"==typeof t&&(n=e[t],t=e,e=n),de.isFunction(e))return r=re.call(arguments,2),o=function(){return e.apply(t||this,r.concat(re.call(arguments)))},o.guid=e.guid=e.guid||de.guid++,o},now:Date.now,support:pe}),\"function\"==typeof Symbol&&(de.fn[Symbol.iterator]=ee[Symbol.iterator]),de.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(e,t){se[\"[object \"+t+\"]\"]=t.toLowerCase()});var be=function(e){function t(e,t,n,r){var o,i,a,s,u,l,c,p=t&&t.ownerDocument,d=t?t.nodeType:9;if(n=n||[],\"string\"!=typeof e||!e||1!==d&&9!==d&&11!==d)return n;if(!r&&((t?t.ownerDocument||t:_)!==L&&O(t),t=t||L,F)){if(11!==d&&(u=ve.exec(e)))if(o=u[1]){if(9===d){if(!(a=t.getElementById(o)))return n;if(a.id===o)return n.push(a),n}else if(p&&(a=p.getElementById(o))&&M(t,a)&&a.id===o)return n.push(a),n}else{if(u[2])return J.apply(n,t.getElementsByTagName(e)),n;if((o=u[3])&&C.getElementsByClassName&&t.getElementsByClassName)return J.apply(n,t.getElementsByClassName(o)),n}if(C.qsa&&!X[e+\" \"]&&(!P||!P.test(e))){if(1!==d)p=t,c=e;else if(\"object\"!==t.nodeName.toLowerCase()){for((s=t.getAttribute(\"id\"))?s=s.replace(we,Ce):t.setAttribute(\"id\",s=$),l=E(e),i=l.length;i--;)l[i]=\"#\"+s+\" \"+h(l[i]);c=l.join(\",\"),p=ye.test(e)&&f(t.parentNode)||t}if(c)try{return J.apply(n,p.querySelectorAll(c)),n}catch(e){}finally{s===$&&t.removeAttribute(\"id\")}}}return S(e.replace(se,\"$1\"),t,n,r)}function n(){function e(n,r){return t.push(n+\" \")>T.cacheLength&&delete e[t.shift()],e[n+\" \"]=r}var t=[];return e}function r(e){return e[$]=!0,e}function o(e){var t=L.createElement(\"fieldset\");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function i(e,t){for(var n=e.split(\"|\"),r=n.length;r--;)T.attrHandle[n[r]]=t}function a(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){var n=t.nodeName.toLowerCase();return\"input\"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return(\"input\"===n||\"button\"===n)&&t.type===e}}function l(e){return function(t){return\"form\"in t?t.parentNode&&t.disabled===!1?\"label\"in t?\"label\"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ke(t)===e:t.disabled===e:\"label\"in t&&t.disabled===e}}function c(e){return r(function(t){return t=+t,r(function(n,r){for(var o,i=e([],n.length,t),a=i.length;a--;)n[o=i[a]]&&(n[o]=!(r[o]=n[o]))})})}function f(e){return e&&\"undefined\"!=typeof e.getElementsByTagName&&e}function p(){}function h(e){for(var t=0,n=e.length,r=\"\";t<n;t++)r+=e[t].value;return r}function d(e,t,n){var r=t.dir,o=t.next,i=o||r,a=n&&\"parentNode\"===i,s=B++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||a)return e(t,n,o);return!1}:function(t,n,u){var l,c,f,p=[W,s];if(u){for(;t=t[r];)if((1===t.nodeType||a)&&e(t,n,u))return!0}else for(;t=t[r];)if(1===t.nodeType||a)if(f=t[$]||(t[$]={}),c=f[t.uniqueID]||(f[t.uniqueID]={}),o&&o===t.nodeName.toLowerCase())t=t[r]||t;else{if((l=c[i])&&l[0]===W&&l[1]===s)return p[2]=l[2];if(c[i]=p,p[2]=e(t,n,u))return!0}return!1}}function g(e){return e.length>1?function(t,n,r){for(var o=e.length;o--;)if(!e[o](t,n,r))return!1;return!0}:e[0]}function m(e,n,r){for(var o=0,i=n.length;o<i;o++)t(e,n[o],r);return r}function v(e,t,n,r,o){for(var i,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(i=e[s])&&(n&&!n(i,r,o)||(a.push(i),l&&t.push(s)));return a}function y(e,t,n,o,i,a){return o&&!o[$]&&(o=y(o)),i&&!i[$]&&(i=y(i,a)),r(function(r,a,s,u){var l,c,f,p=[],h=[],d=a.length,g=r||m(t||\"*\",s.nodeType?[s]:s,[]),y=!e||!r&&t?g:v(g,p,e,s,u),b=n?i||(r?e:d||o)?[]:a:y;if(n&&n(y,b,s,u),o)for(l=v(b,h),o(l,[],s,u),c=l.length;c--;)(f=l[c])&&(b[h[c]]=!(y[h[c]]=f));if(r){if(i||e){if(i){for(l=[],c=b.length;c--;)(f=b[c])&&l.push(y[c]=f);i(null,b=[],l,u)}for(c=b.length;c--;)(f=b[c])&&(l=i?ee(r,f):p[c])>-1&&(r[l]=!(a[l]=f))}}else b=v(b===a?b.splice(d,b.length):b),i?i(null,a,b,u):J.apply(a,b)})}function b(e){for(var t,n,r,o=e.length,i=T.relative[e[0].type],a=i||T.relative[\" \"],s=i?1:0,u=d(function(e){return e===t},a,!0),l=d(function(e){return ee(t,e)>-1},a,!0),c=[function(e,n,r){var o=!i&&(r||n!==A)||((t=n).nodeType?u(e,n,r):l(e,n,r));return t=null,o}];s<o;s++)if(n=T.relative[e[s].type])c=[d(g(c),n)];else{if(n=T.filter[e[s].type].apply(null,e[s].matches),n[$]){for(r=++s;r<o&&!T.relative[e[r].type];r++);return y(s>1&&g(c),s>1&&h(e.slice(0,s-1).concat({value:\" \"===e[s-2].type?\"*\":\"\"})).replace(se,\"$1\"),n,s<r&&b(e.slice(s,r)),r<o&&b(e=e.slice(r)),r<o&&h(e))}c.push(n)}return g(c)}function x(e,n){var o=n.length>0,i=e.length>0,a=function(r,a,s,u,l){var c,f,p,h=0,d=\"0\",g=r&&[],m=[],y=A,b=r||i&&T.find.TAG(\"*\",l),x=W+=null==y?1:Math.random()||.1,w=b.length;for(l&&(A=a===L||a||l);d!==w&&null!=(c=b[d]);d++){if(i&&c){for(f=0,a||c.ownerDocument===L||(O(c),s=!F);p=e[f++];)if(p(c,a||L,s)){u.push(c);break}l&&(W=x)}o&&((c=!p&&c)&&h--,r&&g.push(c))}if(h+=d,o&&d!==h){for(f=0;p=n[f++];)p(g,m,a,s);if(r){if(h>0)for(;d--;)g[d]||m[d]||(m[d]=Y.call(u));m=v(m)}J.apply(u,m),l&&!r&&m.length>0&&h+n.length>1&&t.uniqueSort(u)}return l&&(W=x,A=y),g};return o?r(a):a}var w,C,T,k,j,E,N,S,A,q,D,O,L,H,F,P,I,R,M,$=\"sizzle\"+1*new Date,_=e.document,W=0,B=0,U=n(),z=n(),X=n(),K=function(e,t){return e===t&&(D=!0),0},V={}.hasOwnProperty,G=[],Y=G.pop,Q=G.push,J=G.push,Z=G.slice,ee=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},te=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",ne=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",re=\"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",oe=\"\\\\[\"+ne+\"*(\"+re+\")(?:\"+ne+\"*([*^$|!~]?=)\"+ne+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+re+\"))|)\"+ne+\"*\\\\]\",ie=\":(\"+re+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+oe+\")*)|.*)\\\\)|)\",ae=new RegExp(ne+\"+\",\"g\"),se=new RegExp(\"^\"+ne+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+ne+\"+$\",\"g\"),ue=new RegExp(\"^\"+ne+\"*,\"+ne+\"*\"),le=new RegExp(\"^\"+ne+\"*([>+~]|\"+ne+\")\"+ne+\"*\"),ce=new RegExp(\"=\"+ne+\"*([^\\\\]'\\\"]*?)\"+ne+\"*\\\\]\",\"g\"),fe=new RegExp(ie),pe=new RegExp(\"^\"+re+\"$\"),he={ID:new RegExp(\"^#(\"+re+\")\"),CLASS:new RegExp(\"^\\\\.(\"+re+\")\"),TAG:new RegExp(\"^(\"+re+\"|[*])\"),ATTR:new RegExp(\"^\"+oe),PSEUDO:new RegExp(\"^\"+ie),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+ne+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+ne+\"*(?:([+-]|)\"+ne+\"*(\\\\d+)|))\"+ne+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+te+\")$\",\"i\"),needsContext:new RegExp(\"^\"+ne+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+ne+\"*((?:-\\\\d)?\\\\d*)\"+ne+\"*\\\\)|)(?=[^-]|$)\",\"i\")},de=/^(?:input|select|textarea|button)$/i,ge=/^h\\d$/i,me=/^[^{]+\\{\\s*\\[native \\w/,ve=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ye=/[+~]/,be=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+ne+\"?|(\"+ne+\")|.)\",\"ig\"),xe=function(e,t,n){var r=\"0x\"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},we=/([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,Ce=function(e,t){return t?\"\\0\"===e?\"�\":e.slice(0,-1)+\"\\\\\"+e.charCodeAt(e.length-1).toString(16)+\" \":\"\\\\\"+e},Te=function(){O()},ke=d(function(e){return e.disabled===!0&&(\"form\"in e||\"label\"in e)},{dir:\"parentNode\",next:\"legend\"});try{J.apply(G=Z.call(_.childNodes),_.childNodes),G[_.childNodes.length].nodeType}catch(e){J={apply:G.length?function(e,t){Q.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}C=t.support={},j=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&\"HTML\"!==t.nodeName},O=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:_;return r!==L&&9===r.nodeType&&r.documentElement?(L=r,H=L.documentElement,F=!j(L),_!==L&&(n=L.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener(\"unload\",Te,!1):n.attachEvent&&n.attachEvent(\"onunload\",Te)),C.attributes=o(function(e){return e.className=\"i\",!e.getAttribute(\"className\")}),C.getElementsByTagName=o(function(e){return e.appendChild(L.createComment(\"\")),!e.getElementsByTagName(\"*\").length}),C.getElementsByClassName=me.test(L.getElementsByClassName),C.getById=o(function(e){return H.appendChild(e).id=$,!L.getElementsByName||!L.getElementsByName($).length}),C.getById?(T.filter.ID=function(e){var t=e.replace(be,xe);return function(e){return e.getAttribute(\"id\")===t}},T.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&F){var n=t.getElementById(e);return n?[n]:[]}}):(T.filter.ID=function(e){var t=e.replace(be,xe);return function(e){var n=\"undefined\"!=typeof e.getAttributeNode&&e.getAttributeNode(\"id\");return n&&n.value===t}},T.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&F){var n,r,o,i=t.getElementById(e);if(i){if(n=i.getAttributeNode(\"id\"),n&&n.value===e)return[i];for(o=t.getElementsByName(e),r=0;i=o[r++];)if(n=i.getAttributeNode(\"id\"),n&&n.value===e)return[i]}return[]}}),T.find.TAG=C.getElementsByTagName?function(e,t){return\"undefined\"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):C.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],o=0,i=t.getElementsByTagName(e);if(\"*\"===e){for(;n=i[o++];)1===n.nodeType&&r.push(n);return r}return i},T.find.CLASS=C.getElementsByClassName&&function(e,t){if(\"undefined\"!=typeof t.getElementsByClassName&&F)return t.getElementsByClassName(e)},I=[],P=[],(C.qsa=me.test(L.querySelectorAll))&&(o(function(e){H.appendChild(e).innerHTML=\"<a id='\"+$+\"'></a><select id='\"+$+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",e.querySelectorAll(\"[msallowcapture^='']\").length&&P.push(\"[*^$]=\"+ne+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\"[selected]\").length||P.push(\"\\\\[\"+ne+\"*(?:value|\"+te+\")\"),e.querySelectorAll(\"[id~=\"+$+\"-]\").length||P.push(\"~=\"),e.querySelectorAll(\":checked\").length||P.push(\":checked\"),e.querySelectorAll(\"a#\"+$+\"+*\").length||P.push(\".#.+[+~]\")}),o(function(e){e.innerHTML=\"<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>\";var t=L.createElement(\"input\");t.setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),e.querySelectorAll(\"[name=d]\").length&&P.push(\"name\"+ne+\"*[*^$|!~]?=\"),2!==e.querySelectorAll(\":enabled\").length&&P.push(\":enabled\",\":disabled\"),H.appendChild(e).disabled=!0,2!==e.querySelectorAll(\":disabled\").length&&P.push(\":enabled\",\":disabled\"),e.querySelectorAll(\"*,:x\"),P.push(\",.*:\")})),(C.matchesSelector=me.test(R=H.matches||H.webkitMatchesSelector||H.mozMatchesSelector||H.oMatchesSelector||H.msMatchesSelector))&&o(function(e){C.disconnectedMatch=R.call(e,\"*\"),R.call(e,\"[s!='']:x\"),I.push(\"!=\",ie)}),P=P.length&&new RegExp(P.join(\"|\")),I=I.length&&new RegExp(I.join(\"|\")),t=me.test(H.compareDocumentPosition),M=t||me.test(H.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},K=t?function(e,t){if(e===t)return D=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!C.sortDetached&&t.compareDocumentPosition(e)===n?e===L||e.ownerDocument===_&&M(_,e)?-1:t===L||t.ownerDocument===_&&M(_,t)?1:q?ee(q,e)-ee(q,t):0:4&n?-1:1)}:function(e,t){if(e===t)return D=!0,0;var n,r=0,o=e.parentNode,i=t.parentNode,s=[e],u=[t];if(!o||!i)return e===L?-1:t===L?1:o?-1:i?1:q?ee(q,e)-ee(q,t):0;if(o===i)return a(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;s[r]===u[r];)r++;return r?a(s[r],u[r]):s[r]===_?-1:u[r]===_?1:0},L):L},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==L&&O(e),n=n.replace(ce,\"='$1']\"),C.matchesSelector&&F&&!X[n+\" \"]&&(!I||!I.test(n))&&(!P||!P.test(n)))try{var r=R.call(e,n);if(r||C.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return t(n,L,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==L&&O(e),M(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==L&&O(e);var n=T.attrHandle[t.toLowerCase()],r=n&&V.call(T.attrHandle,t.toLowerCase())?n(e,t,!F):void 0;return void 0!==r?r:C.attributes||!F?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.escape=function(e){return(e+\"\").replace(we,Ce)},t.error=function(e){throw new Error(\"Syntax error, unrecognized expression: \"+e)},t.uniqueSort=function(e){var t,n=[],r=0,o=0;if(D=!C.detectDuplicates,q=!C.sortStable&&e.slice(0),e.sort(K),D){for(;t=e[o++];)t===e[o]&&(r=n.push(o));for(;r--;)e.splice(n[r],1)}return q=null,e},k=t.getText=function(e){var t,n=\"\",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if(\"string\"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=k(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[r++];)n+=k(t);return n},T=t.selectors={cacheLength:50,createPseudo:r,match:he,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(be,xe),e[3]=(e[3]||e[4]||e[5]||\"\").replace(be,xe),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return he.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&fe.test(n)&&(t=E(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(be,xe).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=U[e+\" \"];return t||(t=new RegExp(\"(^|\"+ne+\")\"+e+\"(\"+ne+\"|$)\"))&&U(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||\"undefined\"!=typeof e.getAttribute&&e.getAttribute(\"class\")||\"\")})},ATTR:function(e,n,r){return function(o){var i=t.attr(o,e);return null==i?\"!=\"===n:!n||(i+=\"\",\"=\"===n?i===r:\"!=\"===n?i!==r:\"^=\"===n?r&&0===i.indexOf(r):\"*=\"===n?r&&i.indexOf(r)>-1:\"$=\"===n?r&&i.slice(-r.length)===r:\"~=\"===n?(\" \"+i.replace(ae,\" \")+\" \").indexOf(r)>-1:\"|=\"===n&&(i===r||i.slice(0,r.length+1)===r+\"-\"))}},CHILD:function(e,t,n,r,o){var i=\"nth\"!==e.slice(0,3),a=\"last\"!==e.slice(-4),s=\"of-type\"===t;return 1===r&&0===o?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,h,d,g=i!==a?\"nextSibling\":\"previousSibling\",m=t.parentNode,v=s&&t.nodeName.toLowerCase(),y=!u&&!s,b=!1;if(m){if(i){for(;g;){for(p=t;p=p[g];)if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;d=g=\"only\"===e&&!d&&\"nextSibling\"}return!0}if(d=[a?m.firstChild:m.lastChild],a&&y){for(p=m,f=p[$]||(p[$]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),l=c[e]||[],h=l[0]===W&&l[1],b=h&&l[2],p=h&&m.childNodes[h];p=++h&&p&&p[g]||(b=h=0)||d.pop();)if(1===p.nodeType&&++b&&p===t){c[e]=[W,h,b];break}}else if(y&&(p=t,f=p[$]||(p[$]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),l=c[e]||[],h=l[0]===W&&l[1],b=h),b===!1)for(;(p=++h&&p&&p[g]||(b=h=0)||d.pop())&&((s?p.nodeName.toLowerCase()!==v:1!==p.nodeType)||!++b||(y&&(f=p[$]||(p[$]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),c[e]=[W,b]),p!==t)););return b-=o,b===r||b%r===0&&b/r>=0}}},PSEUDO:function(e,n){var o,i=T.pseudos[e]||T.setFilters[e.toLowerCase()]||t.error(\"unsupported pseudo: \"+e);return i[$]?i(n):i.length>1?(o=[e,e,\"\",n],T.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,o=i(e,n),a=o.length;a--;)r=ee(e,o[a]),e[r]=!(t[r]=o[a])}):function(e){return i(e,0,o)}):i}},pseudos:{not:r(function(e){var t=[],n=[],o=N(e.replace(se,\"$1\"));return o[$]?r(function(e,t,n,r){for(var i,a=o(e,null,r,[]),s=e.length;s--;)(i=a[s])&&(e[s]=!(t[s]=i))}):function(e,r,i){return t[0]=e,o(t,null,i,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){\nreturn t(e,n).length>0}}),contains:r(function(e){return e=e.replace(be,xe),function(t){return(t.textContent||t.innerText||k(t)).indexOf(e)>-1}}),lang:r(function(e){return pe.test(e||\"\")||t.error(\"unsupported lang: \"+e),e=e.replace(be,xe).toLowerCase(),function(t){var n;do if(n=F?t.lang:t.getAttribute(\"xml:lang\")||t.getAttribute(\"lang\"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+\"-\");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===H},focus:function(e){return e===L.activeElement&&(!L.hasFocus||L.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:l(!1),disabled:l(!0),checked:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&!!e.checked||\"option\"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!T.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return de.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&\"button\"===e.type||\"button\"===t},text:function(e){var t;return\"input\"===e.nodeName.toLowerCase()&&\"text\"===e.type&&(null==(t=e.getAttribute(\"type\"))||\"text\"===t.toLowerCase())},first:c(function(){return[0]}),last:c(function(e,t){return[t-1]}),eq:c(function(e,t,n){return[n<0?n+t:n]}),even:c(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:c(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:c(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:c(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},T.pseudos.nth=T.pseudos.eq;for(w in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})T.pseudos[w]=s(w);for(w in{submit:!0,reset:!0})T.pseudos[w]=u(w);return p.prototype=T.filters=T.pseudos,T.setFilters=new p,E=t.tokenize=function(e,n){var r,o,i,a,s,u,l,c=z[e+\" \"];if(c)return n?0:c.slice(0);for(s=e,u=[],l=T.preFilter;s;){r&&!(o=ue.exec(s))||(o&&(s=s.slice(o[0].length)||s),u.push(i=[])),r=!1,(o=le.exec(s))&&(r=o.shift(),i.push({value:r,type:o[0].replace(se,\" \")}),s=s.slice(r.length));for(a in T.filter)!(o=he[a].exec(s))||l[a]&&!(o=l[a](o))||(r=o.shift(),i.push({value:r,type:a,matches:o}),s=s.slice(r.length));if(!r)break}return n?s.length:s?t.error(e):z(e,u).slice(0)},N=t.compile=function(e,t){var n,r=[],o=[],i=X[e+\" \"];if(!i){for(t||(t=E(e)),n=t.length;n--;)i=b(t[n]),i[$]?r.push(i):o.push(i);i=X(e,x(o,r)),i.selector=e}return i},S=t.select=function(e,t,n,r){var o,i,a,s,u,l=\"function\"==typeof e&&e,c=!r&&E(e=l.selector||e);if(n=n||[],1===c.length){if(i=c[0]=c[0].slice(0),i.length>2&&\"ID\"===(a=i[0]).type&&9===t.nodeType&&F&&T.relative[i[1].type]){if(t=(T.find.ID(a.matches[0].replace(be,xe),t)||[])[0],!t)return n;l&&(t=t.parentNode),e=e.slice(i.shift().value.length)}for(o=he.needsContext.test(e)?0:i.length;o--&&(a=i[o],!T.relative[s=a.type]);)if((u=T.find[s])&&(r=u(a.matches[0].replace(be,xe),ye.test(i[0].type)&&f(t.parentNode)||t))){if(i.splice(o,1),e=r.length&&h(i),!e)return J.apply(n,r),n;break}}return(l||N(e,c))(r,t,!F,n,!t||ye.test(e)&&f(t.parentNode)||t),n},C.sortStable=$.split(\"\").sort(K).join(\"\")===$,C.detectDuplicates=!!D,O(),C.sortDetached=o(function(e){return 1&e.compareDocumentPosition(L.createElement(\"fieldset\"))}),o(function(e){return e.innerHTML=\"<a href='#'></a>\",\"#\"===e.firstChild.getAttribute(\"href\")})||i(\"type|href|height|width\",function(e,t,n){if(!n)return e.getAttribute(t,\"type\"===t.toLowerCase()?1:2)}),C.attributes&&o(function(e){return e.innerHTML=\"<input/>\",e.firstChild.setAttribute(\"value\",\"\"),\"\"===e.firstChild.getAttribute(\"value\")})||i(\"value\",function(e,t,n){if(!n&&\"input\"===e.nodeName.toLowerCase())return e.defaultValue}),o(function(e){return null==e.getAttribute(\"disabled\")})||i(te,function(e,t,n){var r;if(!n)return e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);de.find=be,de.expr=be.selectors,de.expr[\":\"]=de.expr.pseudos,de.uniqueSort=de.unique=be.uniqueSort,de.text=be.getText,de.isXMLDoc=be.isXML,de.contains=be.contains,de.escapeSelector=be.escape;var xe=function(e,t,n){for(var r=[],o=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(o&&de(e).is(n))break;r.push(e)}return r},we=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},Ce=de.expr.match.needsContext,Te=/^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i,ke=/^.[^:#\\[\\.,]*$/;de.filter=function(e,t,n){var r=t[0];return n&&(e=\":not(\"+e+\")\"),1===t.length&&1===r.nodeType?de.find.matchesSelector(r,e)?[r]:[]:de.find.matches(e,de.grep(t,function(e){return 1===e.nodeType}))},de.fn.extend({find:function(e){var t,n,r=this.length,o=this;if(\"string\"!=typeof e)return this.pushStack(de(e).filter(function(){for(t=0;t<r;t++)if(de.contains(o[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)de.find(e,o[t],n);return r>1?de.uniqueSort(n):n},filter:function(e){return this.pushStack(o(this,e||[],!1))},not:function(e){return this.pushStack(o(this,e||[],!0))},is:function(e){return!!o(this,\"string\"==typeof e&&Ce.test(e)?de(e):e||[],!1).length}});var je,Ee=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,Ne=de.fn.init=function(e,t,n){var r,o;if(!e)return this;if(n=n||je,\"string\"==typeof e){if(r=\"<\"===e[0]&&\">\"===e[e.length-1]&&e.length>=3?[null,e,null]:Ee.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof de?t[0]:t,de.merge(this,de.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:te,!0)),Te.test(r[1])&&de.isPlainObject(t))for(r in t)de.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return o=te.getElementById(r[2]),o&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):de.isFunction(e)?void 0!==n.ready?n.ready(e):e(de):de.makeArray(e,this)};Ne.prototype=de.fn,je=de(te);var Se=/^(?:parents|prev(?:Until|All))/,Ae={children:!0,contents:!0,next:!0,prev:!0};de.fn.extend({has:function(e){var t=de(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(de.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,o=this.length,i=[],a=\"string\"!=typeof e&&de(e);if(!Ce.test(e))for(;r<o;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&de.find.matchesSelector(n,e))){i.push(n);break}return this.pushStack(i.length>1?de.uniqueSort(i):i)},index:function(e){return e?\"string\"==typeof e?ae.call(de(e),this[0]):ae.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(de.uniqueSort(de.merge(this.get(),de(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),de.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return xe(e,\"parentNode\")},parentsUntil:function(e,t,n){return xe(e,\"parentNode\",n)},next:function(e){return i(e,\"nextSibling\")},prev:function(e){return i(e,\"previousSibling\")},nextAll:function(e){return xe(e,\"nextSibling\")},prevAll:function(e){return xe(e,\"previousSibling\")},nextUntil:function(e,t,n){return xe(e,\"nextSibling\",n)},prevUntil:function(e,t,n){return xe(e,\"previousSibling\",n)},siblings:function(e){return we((e.parentNode||{}).firstChild,e)},children:function(e){return we(e.firstChild)},contents:function(e){return e.contentDocument||de.merge([],e.childNodes)}},function(e,t){de.fn[e]=function(n,r){var o=de.map(this,t,n);return\"Until\"!==e.slice(-5)&&(r=n),r&&\"string\"==typeof r&&(o=de.filter(r,o)),this.length>1&&(Ae[e]||de.uniqueSort(o),Se.test(e)&&o.reverse()),this.pushStack(o)}});var qe=/[^\\x20\\t\\r\\n\\f]+/g;de.Callbacks=function(e){e=\"string\"==typeof e?a(e):de.extend({},e);var t,n,r,o,i=[],s=[],u=-1,l=function(){for(o=e.once,r=t=!0;s.length;u=-1)for(n=s.shift();++u<i.length;)i[u].apply(n[0],n[1])===!1&&e.stopOnFalse&&(u=i.length,n=!1);e.memory||(n=!1),t=!1,o&&(i=n?[]:\"\")},c={add:function(){return i&&(n&&!t&&(u=i.length-1,s.push(n)),function t(n){de.each(n,function(n,r){de.isFunction(r)?e.unique&&c.has(r)||i.push(r):r&&r.length&&\"string\"!==de.type(r)&&t(r)})}(arguments),n&&!t&&l()),this},remove:function(){return de.each(arguments,function(e,t){for(var n;(n=de.inArray(t,i,n))>-1;)i.splice(n,1),n<=u&&u--}),this},has:function(e){return e?de.inArray(e,i)>-1:i.length>0},empty:function(){return i&&(i=[]),this},disable:function(){return o=s=[],i=n=\"\",this},disabled:function(){return!i},lock:function(){return o=s=[],n||t||(i=n=\"\"),this},locked:function(){return!!o},fireWith:function(e,n){return o||(n=n||[],n=[e,n.slice?n.slice():n],s.push(n),t||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},de.extend({Deferred:function(t){var n=[[\"notify\",\"progress\",de.Callbacks(\"memory\"),de.Callbacks(\"memory\"),2],[\"resolve\",\"done\",de.Callbacks(\"once memory\"),de.Callbacks(\"once memory\"),0,\"resolved\"],[\"reject\",\"fail\",de.Callbacks(\"once memory\"),de.Callbacks(\"once memory\"),1,\"rejected\"]],r=\"pending\",o={state:function(){return r},always:function(){return i.done(arguments).fail(arguments),this},catch:function(e){return o.then(null,e)},pipe:function(){var e=arguments;return de.Deferred(function(t){de.each(n,function(n,r){var o=de.isFunction(e[r[4]])&&e[r[4]];i[r[1]](function(){var e=o&&o.apply(this,arguments);e&&de.isFunction(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+\"With\"](this,o?[e]:arguments)})}),e=null}).promise()},then:function(t,r,o){function i(t,n,r,o){return function(){var l=this,c=arguments,f=function(){var e,f;if(!(t<a)){if(e=r.apply(l,c),e===n.promise())throw new TypeError(\"Thenable self-resolution\");f=e&&(\"object\"==typeof e||\"function\"==typeof e)&&e.then,de.isFunction(f)?o?f.call(e,i(a,n,s,o),i(a,n,u,o)):(a++,f.call(e,i(a,n,s,o),i(a,n,u,o),i(a,n,s,n.notifyWith))):(r!==s&&(l=void 0,c=[e]),(o||n.resolveWith)(l,c))}},p=o?f:function(){try{f()}catch(e){de.Deferred.exceptionHook&&de.Deferred.exceptionHook(e,p.stackTrace),t+1>=a&&(r!==u&&(l=void 0,c=[e]),n.rejectWith(l,c))}};t?p():(de.Deferred.getStackHook&&(p.stackTrace=de.Deferred.getStackHook()),e.setTimeout(p))}}var a=0;return de.Deferred(function(e){n[0][3].add(i(0,e,de.isFunction(o)?o:s,e.notifyWith)),n[1][3].add(i(0,e,de.isFunction(t)?t:s)),n[2][3].add(i(0,e,de.isFunction(r)?r:u))}).promise()},promise:function(e){return null!=e?de.extend(e,o):o}},i={};return de.each(n,function(e,t){var a=t[2],s=t[5];o[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[0][2].lock),a.add(t[3].fire),i[t[0]]=function(){return i[t[0]+\"With\"](this===i?void 0:this,arguments),this},i[t[0]+\"With\"]=a.fireWith}),o.promise(i),t&&t.call(i,i),i},when:function(e){var t=arguments.length,n=t,r=Array(n),o=re.call(arguments),i=de.Deferred(),a=function(e){return function(n){r[e]=this,o[e]=arguments.length>1?re.call(arguments):n,--t||i.resolveWith(r,o)}};if(t<=1&&(l(e,i.done(a(n)).resolve,i.reject),\"pending\"===i.state()||de.isFunction(o[n]&&o[n].then)))return i.then();for(;n--;)l(o[n],a(n),i.reject);return i.promise()}});var De=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;de.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&De.test(t.name)&&e.console.warn(\"jQuery.Deferred exception: \"+t.message,t.stack,n)},de.readyException=function(t){e.setTimeout(function(){throw t})};var Oe=de.Deferred();de.fn.ready=function(e){return Oe.then(e).catch(function(e){de.readyException(e)}),this},de.extend({isReady:!1,readyWait:1,holdReady:function(e){e?de.readyWait++:de.ready(!0)},ready:function(e){(e===!0?--de.readyWait:de.isReady)||(de.isReady=!0,e!==!0&&--de.readyWait>0||Oe.resolveWith(te,[de]))}}),de.ready.then=Oe.then,\"complete\"===te.readyState||\"loading\"!==te.readyState&&!te.documentElement.doScroll?e.setTimeout(de.ready):(te.addEventListener(\"DOMContentLoaded\",c),e.addEventListener(\"load\",c));var Le=function(e,t,n,r,o,i,a){var s=0,u=e.length,l=null==n;if(\"object\"===de.type(n)){o=!0;for(s in n)Le(e,t,s,n[s],!0,i,a)}else if(void 0!==r&&(o=!0,de.isFunction(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(de(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return o?e:l?t.call(e):u?t(e[0],n):i},He=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};f.uid=1,f.prototype={cache:function(e){var t=e[this.expando];return t||(t={},He(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,o=this.cache(e);if(\"string\"==typeof t)o[de.camelCase(t)]=n;else for(r in t)o[de.camelCase(r)]=t[r];return o},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][de.camelCase(t)]},access:function(e,t,n){return void 0===t||t&&\"string\"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){de.isArray(t)?t=t.map(de.camelCase):(t=de.camelCase(t),t=t in r?[t]:t.match(qe)||[]),n=t.length;for(;n--;)delete r[t[n]]}(void 0===t||de.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!de.isEmptyObject(t)}};var Fe=new f,Pe=new f,Ie=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,Re=/[A-Z]/g;de.extend({hasData:function(e){return Pe.hasData(e)||Fe.hasData(e)},data:function(e,t,n){return Pe.access(e,t,n)},removeData:function(e,t){Pe.remove(e,t)},_data:function(e,t,n){return Fe.access(e,t,n)},_removeData:function(e,t){Fe.remove(e,t)}}),de.fn.extend({data:function(e,t){var n,r,o,i=this[0],a=i&&i.attributes;if(void 0===e){if(this.length&&(o=Pe.get(i),1===i.nodeType&&!Fe.get(i,\"hasDataAttrs\"))){for(n=a.length;n--;)a[n]&&(r=a[n].name,0===r.indexOf(\"data-\")&&(r=de.camelCase(r.slice(5)),h(i,r,o[r])));Fe.set(i,\"hasDataAttrs\",!0)}return o}return\"object\"==typeof e?this.each(function(){Pe.set(this,e)}):Le(this,function(t){var n;if(i&&void 0===t){if(n=Pe.get(i,e),void 0!==n)return n;if(n=h(i,e),void 0!==n)return n}else this.each(function(){Pe.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){Pe.remove(this,e)})}}),de.extend({queue:function(e,t,n){var r;if(e)return t=(t||\"fx\")+\"queue\",r=Fe.get(e,t),n&&(!r||de.isArray(n)?r=Fe.access(e,t,de.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||\"fx\";var n=de.queue(e,t),r=n.length,o=n.shift(),i=de._queueHooks(e,t),a=function(){de.dequeue(e,t)};\"inprogress\"===o&&(o=n.shift(),r--),o&&(\"fx\"===t&&n.unshift(\"inprogress\"),delete i.stop,o.call(e,a,i)),!r&&i&&i.empty.fire()},_queueHooks:function(e,t){var n=t+\"queueHooks\";return Fe.get(e,n)||Fe.access(e,n,{empty:de.Callbacks(\"once memory\").add(function(){Fe.remove(e,[t+\"queue\",n])})})}}),de.fn.extend({queue:function(e,t){var n=2;return\"string\"!=typeof e&&(t=e,e=\"fx\",n--),arguments.length<n?de.queue(this[0],e):void 0===t?this:this.each(function(){var n=de.queue(this,e,t);de._queueHooks(this,e),\"fx\"===e&&\"inprogress\"!==n[0]&&de.dequeue(this,e)})},dequeue:function(e){return this.each(function(){de.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||\"fx\",[])},promise:function(e,t){var n,r=1,o=de.Deferred(),i=this,a=this.length,s=function(){--r||o.resolveWith(i,[i])};for(\"string\"!=typeof e&&(t=e,e=void 0),e=e||\"fx\";a--;)n=Fe.get(i[a],e+\"queueHooks\"),n&&n.empty&&(r++,n.empty.add(s));return s(),o.promise(t)}});var Me=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,$e=new RegExp(\"^(?:([+-])=|)(\"+Me+\")([a-z%]*)$\",\"i\"),_e=[\"Top\",\"Right\",\"Bottom\",\"Left\"],We=function(e,t){return e=t||e,\"none\"===e.style.display||\"\"===e.style.display&&de.contains(e.ownerDocument,e)&&\"none\"===de.css(e,\"display\")},Be=function(e,t,n,r){var o,i,a={};for(i in t)a[i]=e.style[i],e.style[i]=t[i];o=n.apply(e,r||[]);for(i in t)e.style[i]=a[i];return o},Ue={};de.fn.extend({show:function(){return m(this,!0)},hide:function(){return m(this)},toggle:function(e){return\"boolean\"==typeof e?e?this.show():this.hide():this.each(function(){We(this)?de(this).show():de(this).hide()})}});var ze=/^(?:checkbox|radio)$/i,Xe=/<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]+)/i,Ke=/^$|\\/(?:java|ecma)script/i,Ve={option:[1,\"<select multiple='multiple'>\",\"</select>\"],thead:[1,\"<table>\",\"</table>\"],col:[2,\"<table><colgroup>\",\"</colgroup></table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:[0,\"\",\"\"]};Ve.optgroup=Ve.option,Ve.tbody=Ve.tfoot=Ve.colgroup=Ve.caption=Ve.thead,Ve.th=Ve.td;var Ge=/<|&#?\\w+;/;!function(){var e=te.createDocumentFragment(),t=e.appendChild(te.createElement(\"div\")),n=te.createElement(\"input\");n.setAttribute(\"type\",\"radio\"),n.setAttribute(\"checked\",\"checked\"),n.setAttribute(\"name\",\"t\"),t.appendChild(n),pe.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML=\"<textarea>x</textarea>\",pe.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var Ye=te.documentElement,Qe=/^key/,Je=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ze=/^([^.]*)(?:\\.(.+)|)/;de.event={global:{},add:function(e,t,n,r,o){var i,a,s,u,l,c,f,p,h,d,g,m=Fe.get(e);if(m)for(n.handler&&(i=n,n=i.handler,o=i.selector),o&&de.find.matchesSelector(Ye,o),n.guid||(n.guid=de.guid++),(u=m.events)||(u=m.events={}),(a=m.handle)||(a=m.handle=function(t){return\"undefined\"!=typeof de&&de.event.triggered!==t.type?de.event.dispatch.apply(e,arguments):void 0}),t=(t||\"\").match(qe)||[\"\"],l=t.length;l--;)s=Ze.exec(t[l])||[],h=g=s[1],d=(s[2]||\"\").split(\".\").sort(),h&&(f=de.event.special[h]||{},h=(o?f.delegateType:f.bindType)||h,f=de.event.special[h]||{},c=de.extend({type:h,origType:g,data:r,handler:n,guid:n.guid,selector:o,needsContext:o&&de.expr.match.needsContext.test(o),namespace:d.join(\".\")},i),(p=u[h])||(p=u[h]=[],p.delegateCount=0,f.setup&&f.setup.call(e,r,d,a)!==!1||e.addEventListener&&e.addEventListener(h,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),o?p.splice(p.delegateCount++,0,c):p.push(c),de.event.global[h]=!0)},remove:function(e,t,n,r,o){var i,a,s,u,l,c,f,p,h,d,g,m=Fe.hasData(e)&&Fe.get(e);if(m&&(u=m.events)){for(t=(t||\"\").match(qe)||[\"\"],l=t.length;l--;)if(s=Ze.exec(t[l])||[],h=g=s[1],d=(s[2]||\"\").split(\".\").sort(),h){for(f=de.event.special[h]||{},h=(r?f.delegateType:f.bindType)||h,p=u[h]||[],s=s[2]&&new RegExp(\"(^|\\\\.)\"+d.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),a=i=p.length;i--;)c=p[i],!o&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&(\"**\"!==r||!c.selector)||(p.splice(i,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&f.teardown.call(e,d,m.handle)!==!1||de.removeEvent(e,h,m.handle),delete u[h])}else for(h in u)de.event.remove(e,h+t[l],n,r,!0);de.isEmptyObject(u)&&Fe.remove(e,\"handle events\")}},dispatch:function(e){var t,n,r,o,i,a,s=de.event.fix(e),u=new Array(arguments.length),l=(Fe.get(this,\"events\")||{})[s.type]||[],c=de.event.special[s.type]||{};for(u[0]=s,t=1;t<arguments.length;t++)u[t]=arguments[t];if(s.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,s)!==!1){for(a=de.event.handlers.call(this,s,l),t=0;(o=a[t++])&&!s.isPropagationStopped();)for(s.currentTarget=o.elem,n=0;(i=o.handlers[n++])&&!s.isImmediatePropagationStopped();)s.rnamespace&&!s.rnamespace.test(i.namespace)||(s.handleObj=i,s.data=i.data,r=((de.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),void 0!==r&&(s.result=r)===!1&&(s.preventDefault(),s.stopPropagation()));return c.postDispatch&&c.postDispatch.call(this,s),s.result}},handlers:function(e,t){var n,r,o,i,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!(\"click\"===e.type&&e.button>=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&(\"click\"!==e.type||l.disabled!==!0)){for(i=[],a={},n=0;n<u;n++)r=t[n],o=r.selector+\" \",void 0===a[o]&&(a[o]=r.needsContext?de(o,this).index(l)>-1:de.find(o,this,null,[l]).length),a[o]&&i.push(r);i.length&&s.push({elem:l,handlers:i})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(e,t){Object.defineProperty(de.Event.prototype,e,{enumerable:!0,configurable:!0,get:de.isFunction(t)?function(){if(this.originalEvent)return t(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[e]},set:function(t){Object.defineProperty(this,e,{enumerable:!0,configurable:!0,writable:!0,value:t})}})},fix:function(e){return e[de.expando]?e:new de.Event(e)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==C()&&this.focus)return this.focus(),!1},delegateType:\"focusin\"},blur:{trigger:function(){if(this===C()&&this.blur)return this.blur(),!1},delegateType:\"focusout\"},click:{trigger:function(){if(\"checkbox\"===this.type&&this.click&&de.nodeName(this,\"input\"))return this.click(),!1},_default:function(e){return de.nodeName(e.target,\"a\")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},de.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},de.Event=function(e,t){return this instanceof de.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&e.returnValue===!1?x:w,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&de.extend(this,t),this.timeStamp=e&&e.timeStamp||de.now(),void(this[de.expando]=!0)):new de.Event(e,t)},de.Event.prototype={constructor:de.Event,isDefaultPrevented:w,isPropagationStopped:w,isImmediatePropagationStopped:w,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=x,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=x,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=x,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},de.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,char:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&Qe.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&Je.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},de.event.addProp),de.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(e,t){de.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,o=e.relatedTarget,i=e.handleObj;return o&&(o===r||de.contains(r,o))||(e.type=i.origType,n=i.handler.apply(this,arguments),e.type=t),n}}}),de.fn.extend({on:function(e,t,n,r){return T(this,e,t,n,r)},one:function(e,t,n,r){return T(this,e,t,n,r,1)},off:function(e,t,n){var r,o;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,de(e.delegateTarget).off(r.namespace?r.origType+\".\"+r.namespace:r.origType,r.selector,r.handler),this;if(\"object\"==typeof e){for(o in e)this.off(o,t,e[o]);return this}return t!==!1&&\"function\"!=typeof t||(n=t,t=void 0),n===!1&&(n=w),this.each(function(){de.event.remove(this,e,n,t)})}});var et=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,tt=/<script|<style|<link/i,nt=/checked\\s*(?:[^=]|=\\s*.checked.)/i,rt=/^true\\/(.*)/,ot=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;de.extend({htmlPrefilter:function(e){return e.replace(et,\"<$1></$2>\")},clone:function(e,t,n){var r,o,i,a,s=e.cloneNode(!0),u=de.contains(e.ownerDocument,e);if(!(pe.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||de.isXMLDoc(e)))for(a=v(s),i=v(e),r=0,o=i.length;r<o;r++)S(i[r],a[r]);if(t)if(n)for(i=i||v(e),a=a||v(s),r=0,o=i.length;r<o;r++)N(i[r],a[r]);else N(e,s);return a=v(s,\"script\"),a.length>0&&y(a,!u&&v(e,\"script\")),s},cleanData:function(e){for(var t,n,r,o=de.event.special,i=0;void 0!==(n=e[i]);i++)if(He(n)){if(t=n[Fe.expando]){if(t.events)for(r in t.events)o[r]?de.event.remove(n,r):de.removeEvent(n,r,t.handle);n[Fe.expando]=void 0}n[Pe.expando]&&(n[Pe.expando]=void 0)}}}),de.fn.extend({detach:function(e){return q(this,e,!0)},remove:function(e){return q(this,e)},text:function(e){return Le(this,function(e){return void 0===e?de.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return A(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=k(this,e);t.appendChild(e)}})},prepend:function(){return A(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=k(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return A(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return A(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(de.cleanData(v(e,!1)),e.textContent=\"\");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return de.clone(this,e,t)})},html:function(e){return Le(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if(\"string\"==typeof e&&!tt.test(e)&&!Ve[(Xe.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=de.htmlPrefilter(e);try{for(;n<r;n++)t=this[n]||{},1===t.nodeType&&(de.cleanData(v(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return A(this,arguments,function(t){var n=this.parentNode;de.inArray(this,e)<0&&(de.cleanData(v(this)),n&&n.replaceChild(t,this))},e)}}),de.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(e,t){de.fn[e]=function(e){for(var n,r=[],o=de(e),i=o.length-1,a=0;a<=i;a++)n=a===i?this:this.clone(!0),de(o[a])[t](n),ie.apply(r,n.get());return this.pushStack(r)}});var it=/^margin/,at=new RegExp(\"^(\"+Me+\")(?!px)[a-z%]+$\",\"i\"),st=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)};!function(){function t(){if(s){s.style.cssText=\"box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%\",s.innerHTML=\"\",Ye.appendChild(a);var t=e.getComputedStyle(s);n=\"1%\"!==t.top,i=\"2px\"===t.marginLeft,r=\"4px\"===t.width,s.style.marginRight=\"50%\",o=\"4px\"===t.marginRight,Ye.removeChild(a),s=null}}var n,r,o,i,a=te.createElement(\"div\"),s=te.createElement(\"div\");s.style&&(s.style.backgroundClip=\"content-box\",s.cloneNode(!0).style.backgroundClip=\"\",pe.clearCloneStyle=\"content-box\"===s.style.backgroundClip,a.style.cssText=\"border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute\",a.appendChild(s),de.extend(pe,{pixelPosition:function(){return t(),n},boxSizingReliable:function(){return t(),r},pixelMarginRight:function(){return t(),o},reliableMarginLeft:function(){return t(),i}}))}();var ut=/^(none|table(?!-c[ea]).+)/,lt={position:\"absolute\",visibility:\"hidden\",display:\"block\"},ct={letterSpacing:\"0\",fontWeight:\"400\"},ft=[\"Webkit\",\"Moz\",\"ms\"],pt=te.createElement(\"div\").style;de.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=D(e,\"opacity\");return\"\"===n?\"1\":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{float:\"cssFloat\"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,i,a,s=de.camelCase(t),u=e.style;return t=de.cssProps[s]||(de.cssProps[s]=L(s)||s),a=de.cssHooks[t]||de.cssHooks[s],void 0===n?a&&\"get\"in a&&void 0!==(o=a.get(e,!1,r))?o:u[t]:(i=typeof n,\"string\"===i&&(o=$e.exec(n))&&o[1]&&(n=d(e,t,o),i=\"number\"),null!=n&&n===n&&(\"number\"===i&&(n+=o&&o[3]||(de.cssNumber[s]?\"\":\"px\")),pe.clearCloneStyle||\"\"!==n||0!==t.indexOf(\"background\")||(u[t]=\"inherit\"),a&&\"set\"in a&&void 0===(n=a.set(e,n,r))||(u[t]=n)),void 0)}},css:function(e,t,n,r){var o,i,a,s=de.camelCase(t);return t=de.cssProps[s]||(de.cssProps[s]=L(s)||s),a=de.cssHooks[t]||de.cssHooks[s],a&&\"get\"in a&&(o=a.get(e,!0,n)),void 0===o&&(o=D(e,t,r)),\"normal\"===o&&t in ct&&(o=ct[t]),\"\"===n||n?(i=parseFloat(o),n===!0||isFinite(i)?i||0:o):o}}),de.each([\"height\",\"width\"],function(e,t){de.cssHooks[t]={get:function(e,n,r){if(n)return!ut.test(de.css(e,\"display\"))||e.getClientRects().length&&e.getBoundingClientRect().width?P(e,t,r):Be(e,lt,function(){return P(e,t,r)})},set:function(e,n,r){var o,i=r&&st(e),a=r&&F(e,t,r,\"border-box\"===de.css(e,\"boxSizing\",!1,i),i);return a&&(o=$e.exec(n))&&\"px\"!==(o[3]||\"px\")&&(e.style[t]=n,n=de.css(e,t)),H(e,n,a)}}}),de.cssHooks.marginLeft=O(pe.reliableMarginLeft,function(e,t){if(t)return(parseFloat(D(e,\"marginLeft\"))||e.getBoundingClientRect().left-Be(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+\"px\"}),de.each({margin:\"\",padding:\"\",border:\"Width\"},function(e,t){de.cssHooks[e+t]={expand:function(n){for(var r=0,o={},i=\"string\"==typeof n?n.split(\" \"):[n];r<4;r++)o[e+_e[r]+t]=i[r]||i[r-2]||i[0];return o}},it.test(e)||(de.cssHooks[e+t].set=H)}),de.fn.extend({css:function(e,t){return Le(this,function(e,t,n){var r,o,i={},a=0;if(de.isArray(t)){for(r=st(e),o=t.length;a<o;a++)i[t[a]]=de.css(e,t[a],!1,r);return i}return void 0!==n?de.style(e,t,n):de.css(e,t)},e,t,arguments.length>1)}}),de.Tween=I,I.prototype={constructor:I,init:function(e,t,n,r,o,i){this.elem=e,this.prop=n,this.easing=o||de.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=i||(de.cssNumber[n]?\"\":\"px\")},cur:function(){var e=I.propHooks[this.prop];return e&&e.get?e.get(this):I.propHooks._default.get(this)},run:function(e){var t,n=I.propHooks[this.prop];return this.options.duration?this.pos=t=de.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):I.propHooks._default.set(this),this}},I.prototype.init.prototype=I.prototype,I.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=de.css(e.elem,e.prop,\"\"),t&&\"auto\"!==t?t:0)},set:function(e){de.fx.step[e.prop]?de.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[de.cssProps[e.prop]]&&!de.cssHooks[e.prop]?e.elem[e.prop]=e.now:de.style(e.elem,e.prop,e.now+e.unit)}}},I.propHooks.scrollTop=I.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},de.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:\"swing\"},de.fx=I.prototype.init,de.fx.step={};var ht,dt,gt=/^(?:toggle|show|hide)$/,mt=/queueHooks$/;de.Animation=de.extend(U,{tweeners:{\"*\":[function(e,t){var n=this.createTween(e,t);return d(n.elem,e,$e.exec(t),n),n}]},tweener:function(e,t){de.isFunction(e)?(t=e,e=[\"*\"]):e=e.match(qe);for(var n,r=0,o=e.length;r<o;r++)n=e[r],U.tweeners[n]=U.tweeners[n]||[],U.tweeners[n].unshift(t)},prefilters:[W],prefilter:function(e,t){t?U.prefilters.unshift(e):U.prefilters.push(e)}}),de.speed=function(e,t,n){var r=e&&\"object\"==typeof e?de.extend({},e):{complete:n||!n&&t||de.isFunction(e)&&e,duration:e,easing:n&&t||t&&!de.isFunction(t)&&t};return de.fx.off||te.hidden?r.duration=0:\"number\"!=typeof r.duration&&(r.duration in de.fx.speeds?r.duration=de.fx.speeds[r.duration]:r.duration=de.fx.speeds._default),null!=r.queue&&r.queue!==!0||(r.queue=\"fx\"),r.old=r.complete,r.complete=function(){de.isFunction(r.old)&&r.old.call(this),r.queue&&de.dequeue(this,r.queue)},r},de.fn.extend({fadeTo:function(e,t,n,r){return this.filter(We).css(\"opacity\",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){\nvar o=de.isEmptyObject(e),i=de.speed(t,n,r),a=function(){var t=U(this,de.extend({},e),i);(o||Fe.get(this,\"finish\"))&&t.stop(!0)};return a.finish=a,o||i.queue===!1?this.each(a):this.queue(i.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return\"string\"!=typeof e&&(n=t,t=e,e=void 0),t&&e!==!1&&this.queue(e||\"fx\",[]),this.each(function(){var t=!0,o=null!=e&&e+\"queueHooks\",i=de.timers,a=Fe.get(this);if(o)a[o]&&a[o].stop&&r(a[o]);else for(o in a)a[o]&&a[o].stop&&mt.test(o)&&r(a[o]);for(o=i.length;o--;)i[o].elem!==this||null!=e&&i[o].queue!==e||(i[o].anim.stop(n),t=!1,i.splice(o,1));!t&&n||de.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||\"fx\"),this.each(function(){var t,n=Fe.get(this),r=n[e+\"queue\"],o=n[e+\"queueHooks\"],i=de.timers,a=r?r.length:0;for(n.finish=!0,de.queue(this,e,[]),o&&o.stop&&o.stop.call(this,!0),t=i.length;t--;)i[t].elem===this&&i[t].queue===e&&(i[t].anim.stop(!0),i.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),de.each([\"toggle\",\"show\",\"hide\"],function(e,t){var n=de.fn[t];de.fn[t]=function(e,r,o){return null==e||\"boolean\"==typeof e?n.apply(this,arguments):this.animate($(t,!0),e,r,o)}}),de.each({slideDown:$(\"show\"),slideUp:$(\"hide\"),slideToggle:$(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(e,t){de.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),de.timers=[],de.fx.tick=function(){var e,t=0,n=de.timers;for(ht=de.now();t<n.length;t++)e=n[t],e()||n[t]!==e||n.splice(t--,1);n.length||de.fx.stop(),ht=void 0},de.fx.timer=function(e){de.timers.push(e),e()?de.fx.start():de.timers.pop()},de.fx.interval=13,de.fx.start=function(){dt||(dt=e.requestAnimationFrame?e.requestAnimationFrame(R):e.setInterval(de.fx.tick,de.fx.interval))},de.fx.stop=function(){e.cancelAnimationFrame?e.cancelAnimationFrame(dt):e.clearInterval(dt),dt=null},de.fx.speeds={slow:600,fast:200,_default:400},de.fn.delay=function(t,n){return t=de.fx?de.fx.speeds[t]||t:t,n=n||\"fx\",this.queue(n,function(n,r){var o=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(o)}})},function(){var e=te.createElement(\"input\"),t=te.createElement(\"select\"),n=t.appendChild(te.createElement(\"option\"));e.type=\"checkbox\",pe.checkOn=\"\"!==e.value,pe.optSelected=n.selected,e=te.createElement(\"input\"),e.value=\"t\",e.type=\"radio\",pe.radioValue=\"t\"===e.value}();var vt,yt=de.expr.attrHandle;de.fn.extend({attr:function(e,t){return Le(this,de.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){de.removeAttr(this,e)})}}),de.extend({attr:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return\"undefined\"==typeof e.getAttribute?de.prop(e,t,n):(1===i&&de.isXMLDoc(e)||(o=de.attrHooks[t.toLowerCase()]||(de.expr.match.bool.test(t)?vt:void 0)),void 0!==n?null===n?void de.removeAttr(e,t):o&&\"set\"in o&&void 0!==(r=o.set(e,n,t))?r:(e.setAttribute(t,n+\"\"),n):o&&\"get\"in o&&null!==(r=o.get(e,t))?r:(r=de.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!pe.radioValue&&\"radio\"===t&&de.nodeName(e,\"input\")){var n=e.value;return e.setAttribute(\"type\",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,o=t&&t.match(qe);if(o&&1===e.nodeType)for(;n=o[r++];)e.removeAttribute(n)}}),vt={set:function(e,t,n){return t===!1?de.removeAttr(e,n):e.setAttribute(n,n),n}},de.each(de.expr.match.bool.source.match(/\\w+/g),function(e,t){var n=yt[t]||de.find.attr;yt[t]=function(e,t,r){var o,i,a=t.toLowerCase();return r||(i=yt[a],yt[a]=o,o=null!=n(e,t,r)?a:null,yt[a]=i),o}});var bt=/^(?:input|select|textarea|button)$/i,xt=/^(?:a|area)$/i;de.fn.extend({prop:function(e,t){return Le(this,de.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[de.propFix[e]||e]})}}),de.extend({prop:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return 1===i&&de.isXMLDoc(e)||(t=de.propFix[t]||t,o=de.propHooks[t]),void 0!==n?o&&\"set\"in o&&void 0!==(r=o.set(e,n,t))?r:e[t]=n:o&&\"get\"in o&&null!==(r=o.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=de.find.attr(e,\"tabindex\");return t?parseInt(t,10):bt.test(e.nodeName)||xt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:\"htmlFor\",class:\"className\"}}),pe.optSelected||(de.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),de.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){de.propFix[this.toLowerCase()]=this}),de.fn.extend({addClass:function(e){var t,n,r,o,i,a,s,u=0;if(de.isFunction(e))return this.each(function(t){de(this).addClass(e.call(this,t,X(this)))});if(\"string\"==typeof e&&e)for(t=e.match(qe)||[];n=this[u++];)if(o=X(n),r=1===n.nodeType&&\" \"+z(o)+\" \"){for(a=0;i=t[a++];)r.indexOf(\" \"+i+\" \")<0&&(r+=i+\" \");s=z(r),o!==s&&n.setAttribute(\"class\",s)}return this},removeClass:function(e){var t,n,r,o,i,a,s,u=0;if(de.isFunction(e))return this.each(function(t){de(this).removeClass(e.call(this,t,X(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if(\"string\"==typeof e&&e)for(t=e.match(qe)||[];n=this[u++];)if(o=X(n),r=1===n.nodeType&&\" \"+z(o)+\" \"){for(a=0;i=t[a++];)for(;r.indexOf(\" \"+i+\" \")>-1;)r=r.replace(\" \"+i+\" \",\" \");s=z(r),o!==s&&n.setAttribute(\"class\",s)}return this},toggleClass:function(e,t){var n=typeof e;return\"boolean\"==typeof t&&\"string\"===n?t?this.addClass(e):this.removeClass(e):de.isFunction(e)?this.each(function(n){de(this).toggleClass(e.call(this,n,X(this),t),t)}):this.each(function(){var t,r,o,i;if(\"string\"===n)for(r=0,o=de(this),i=e.match(qe)||[];t=i[r++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&\"boolean\"!==n||(t=X(this),t&&Fe.set(this,\"__className__\",t),this.setAttribute&&this.setAttribute(\"class\",t||e===!1?\"\":Fe.get(this,\"__className__\")||\"\"))})},hasClass:function(e){var t,n,r=0;for(t=\" \"+e+\" \";n=this[r++];)if(1===n.nodeType&&(\" \"+z(X(n))+\" \").indexOf(t)>-1)return!0;return!1}});var wt=/\\r/g;de.fn.extend({val:function(e){var t,n,r,o=this[0];{if(arguments.length)return r=de.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=r?e.call(this,n,de(this).val()):e,null==o?o=\"\":\"number\"==typeof o?o+=\"\":de.isArray(o)&&(o=de.map(o,function(e){return null==e?\"\":e+\"\"})),t=de.valHooks[this.type]||de.valHooks[this.nodeName.toLowerCase()],t&&\"set\"in t&&void 0!==t.set(this,o,\"value\")||(this.value=o))});if(o)return t=de.valHooks[o.type]||de.valHooks[o.nodeName.toLowerCase()],t&&\"get\"in t&&void 0!==(n=t.get(o,\"value\"))?n:(n=o.value,\"string\"==typeof n?n.replace(wt,\"\"):null==n?\"\":n)}}}),de.extend({valHooks:{option:{get:function(e){var t=de.find.attr(e,\"value\");return null!=t?t:z(de.text(e))}},select:{get:function(e){var t,n,r,o=e.options,i=e.selectedIndex,a=\"select-one\"===e.type,s=a?null:[],u=a?i+1:o.length;for(r=i<0?u:a?i:0;r<u;r++)if(n=o[r],(n.selected||r===i)&&!n.disabled&&(!n.parentNode.disabled||!de.nodeName(n.parentNode,\"optgroup\"))){if(t=de(n).val(),a)return t;s.push(t)}return s},set:function(e,t){for(var n,r,o=e.options,i=de.makeArray(t),a=o.length;a--;)r=o[a],(r.selected=de.inArray(de.valHooks.option.get(r),i)>-1)&&(n=!0);return n||(e.selectedIndex=-1),i}}}}),de.each([\"radio\",\"checkbox\"],function(){de.valHooks[this]={set:function(e,t){if(de.isArray(t))return e.checked=de.inArray(de(e).val(),t)>-1}},pe.checkOn||(de.valHooks[this].get=function(e){return null===e.getAttribute(\"value\")?\"on\":e.value})});var Ct=/^(?:focusinfocus|focusoutblur)$/;de.extend(de.event,{trigger:function(t,n,r,o){var i,a,s,u,l,c,f,p=[r||te],h=le.call(t,\"type\")?t.type:t,d=le.call(t,\"namespace\")?t.namespace.split(\".\"):[];if(a=s=r=r||te,3!==r.nodeType&&8!==r.nodeType&&!Ct.test(h+de.event.triggered)&&(h.indexOf(\".\")>-1&&(d=h.split(\".\"),h=d.shift(),d.sort()),l=h.indexOf(\":\")<0&&\"on\"+h,t=t[de.expando]?t:new de.Event(h,\"object\"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=d.join(\".\"),t.rnamespace=t.namespace?new RegExp(\"(^|\\\\.)\"+d.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:de.makeArray(n,[t]),f=de.event.special[h]||{},o||!f.trigger||f.trigger.apply(r,n)!==!1)){if(!o&&!f.noBubble&&!de.isWindow(r)){for(u=f.delegateType||h,Ct.test(u+h)||(a=a.parentNode);a;a=a.parentNode)p.push(a),s=a;s===(r.ownerDocument||te)&&p.push(s.defaultView||s.parentWindow||e)}for(i=0;(a=p[i++])&&!t.isPropagationStopped();)t.type=i>1?u:f.bindType||h,c=(Fe.get(a,\"events\")||{})[t.type]&&Fe.get(a,\"handle\"),c&&c.apply(a,n),c=l&&a[l],c&&c.apply&&He(a)&&(t.result=c.apply(a,n),t.result===!1&&t.preventDefault());return t.type=h,o||t.isDefaultPrevented()||f._default&&f._default.apply(p.pop(),n)!==!1||!He(r)||l&&de.isFunction(r[h])&&!de.isWindow(r)&&(s=r[l],s&&(r[l]=null),de.event.triggered=h,r[h](),de.event.triggered=void 0,s&&(r[l]=s)),t.result}},simulate:function(e,t,n){var r=de.extend(new de.Event,n,{type:e,isSimulated:!0});de.event.trigger(r,null,t)}}),de.fn.extend({trigger:function(e,t){return this.each(function(){de.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return de.event.trigger(e,t,n,!0)}}),de.each(\"blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu\".split(\" \"),function(e,t){de.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),de.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),pe.focusin=\"onfocusin\"in e,pe.focusin||de.each({focus:\"focusin\",blur:\"focusout\"},function(e,t){var n=function(e){de.event.simulate(t,e.target,de.event.fix(e))};de.event.special[t]={setup:function(){var r=this.ownerDocument||this,o=Fe.access(r,t);o||r.addEventListener(e,n,!0),Fe.access(r,t,(o||0)+1)},teardown:function(){var r=this.ownerDocument||this,o=Fe.access(r,t)-1;o?Fe.access(r,t,o):(r.removeEventListener(e,n,!0),Fe.remove(r,t))}}});var Tt=e.location,kt=de.now(),jt=/\\?/;de.parseXML=function(t){var n;if(!t||\"string\"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,\"text/xml\")}catch(e){n=void 0}return n&&!n.getElementsByTagName(\"parsererror\").length||de.error(\"Invalid XML: \"+t),n};var Et=/\\[\\]$/,Nt=/\\r?\\n/g,St=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;de.param=function(e,t){var n,r=[],o=function(e,t){var n=de.isFunction(t)?t():t;r[r.length]=encodeURIComponent(e)+\"=\"+encodeURIComponent(null==n?\"\":n)};if(de.isArray(e)||e.jquery&&!de.isPlainObject(e))de.each(e,function(){o(this.name,this.value)});else for(n in e)K(n,e[n],t,o);return r.join(\"&\")},de.fn.extend({serialize:function(){return de.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=de.prop(this,\"elements\");return e?de.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!de(this).is(\":disabled\")&&At.test(this.nodeName)&&!St.test(e)&&(this.checked||!ze.test(e))}).map(function(e,t){var n=de(this).val();return null==n?null:de.isArray(n)?de.map(n,function(e){return{name:t.name,value:e.replace(Nt,\"\\r\\n\")}}):{name:t.name,value:n.replace(Nt,\"\\r\\n\")}}).get()}});var qt=/%20/g,Dt=/#.*$/,Ot=/([?&])_=[^&]*/,Lt=/^(.*?):[ \\t]*([^\\r\\n]*)$/gm,Ht=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ft=/^(?:GET|HEAD)$/,Pt=/^\\/\\//,It={},Rt={},Mt=\"*/\".concat(\"*\"),$t=te.createElement(\"a\");$t.href=Tt.href,de.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Tt.href,type:\"GET\",isLocal:Ht.test(Tt.protocol),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Mt,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":JSON.parse,\"text xml\":de.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Y(Y(e,de.ajaxSettings),t):Y(de.ajaxSettings,e)},ajaxPrefilter:V(It),ajaxTransport:V(Rt),ajax:function(t,n){function r(t,n,r,s){var l,p,h,x,w,C=n;c||(c=!0,u&&e.clearTimeout(u),o=void 0,a=s||\"\",T.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(x=Q(d,T,r)),x=J(d,x,T,l),l?(d.ifModified&&(w=T.getResponseHeader(\"Last-Modified\"),w&&(de.lastModified[i]=w),w=T.getResponseHeader(\"etag\"),w&&(de.etag[i]=w)),204===t||\"HEAD\"===d.type?C=\"nocontent\":304===t?C=\"notmodified\":(C=x.state,p=x.data,h=x.error,l=!h)):(h=C,!t&&C||(C=\"error\",t<0&&(t=0))),T.status=t,T.statusText=(n||C)+\"\",l?v.resolveWith(g,[p,C,T]):v.rejectWith(g,[T,C,h]),T.statusCode(b),b=void 0,f&&m.trigger(l?\"ajaxSuccess\":\"ajaxError\",[T,d,l?p:h]),y.fireWith(g,[T,C]),f&&(m.trigger(\"ajaxComplete\",[T,d]),--de.active||de.event.trigger(\"ajaxStop\")))}\"object\"==typeof t&&(n=t,t=void 0),n=n||{};var o,i,a,s,u,l,c,f,p,h,d=de.ajaxSetup({},n),g=d.context||d,m=d.context&&(g.nodeType||g.jquery)?de(g):de.event,v=de.Deferred(),y=de.Callbacks(\"once memory\"),b=d.statusCode||{},x={},w={},C=\"canceled\",T={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s)for(s={};t=Lt.exec(a);)s[t[1].toLowerCase()]=t[2];t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=w[e.toLowerCase()]=w[e.toLowerCase()]||e,x[e]=t),this},overrideMimeType:function(e){return null==c&&(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)T.always(e[T.status]);else for(t in e)b[t]=[b[t],e[t]];return this},abort:function(e){var t=e||C;return o&&o.abort(t),r(0,t),this}};if(v.promise(T),d.url=((t||d.url||Tt.href)+\"\").replace(Pt,Tt.protocol+\"//\"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=(d.dataType||\"*\").toLowerCase().match(qe)||[\"\"],null==d.crossDomain){l=te.createElement(\"a\");try{l.href=d.url,l.href=l.href,d.crossDomain=$t.protocol+\"//\"+$t.host!=l.protocol+\"//\"+l.host}catch(e){d.crossDomain=!0}}if(d.data&&d.processData&&\"string\"!=typeof d.data&&(d.data=de.param(d.data,d.traditional)),G(It,d,n,T),c)return T;f=de.event&&d.global,f&&0===de.active++&&de.event.trigger(\"ajaxStart\"),d.type=d.type.toUpperCase(),d.hasContent=!Ft.test(d.type),i=d.url.replace(Dt,\"\"),d.hasContent?d.data&&d.processData&&0===(d.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&(d.data=d.data.replace(qt,\"+\")):(h=d.url.slice(i.length),d.data&&(i+=(jt.test(i)?\"&\":\"?\")+d.data,delete d.data),d.cache===!1&&(i=i.replace(Ot,\"$1\"),h=(jt.test(i)?\"&\":\"?\")+\"_=\"+kt++ +h),d.url=i+h),d.ifModified&&(de.lastModified[i]&&T.setRequestHeader(\"If-Modified-Since\",de.lastModified[i]),de.etag[i]&&T.setRequestHeader(\"If-None-Match\",de.etag[i])),(d.data&&d.hasContent&&d.contentType!==!1||n.contentType)&&T.setRequestHeader(\"Content-Type\",d.contentType),T.setRequestHeader(\"Accept\",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(\"*\"!==d.dataTypes[0]?\", \"+Mt+\"; q=0.01\":\"\"):d.accepts[\"*\"]);for(p in d.headers)T.setRequestHeader(p,d.headers[p]);if(d.beforeSend&&(d.beforeSend.call(g,T,d)===!1||c))return T.abort();if(C=\"abort\",y.add(d.complete),T.done(d.success),T.fail(d.error),o=G(Rt,d,n,T)){if(T.readyState=1,f&&m.trigger(\"ajaxSend\",[T,d]),c)return T;d.async&&d.timeout>0&&(u=e.setTimeout(function(){T.abort(\"timeout\")},d.timeout));try{c=!1,o.send(x,r)}catch(e){if(c)throw e;r(-1,e)}}else r(-1,\"No Transport\");return T},getJSON:function(e,t,n){return de.get(e,t,n,\"json\")},getScript:function(e,t){return de.get(e,void 0,t,\"script\")}}),de.each([\"get\",\"post\"],function(e,t){de[t]=function(e,n,r,o){return de.isFunction(n)&&(o=o||r,r=n,n=void 0),de.ajax(de.extend({url:e,type:t,dataType:o,data:n,success:r},de.isPlainObject(e)&&e))}}),de._evalUrl=function(e){return de.ajax({url:e,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,throws:!0})},de.fn.extend({wrapAll:function(e){var t;return this[0]&&(de.isFunction(e)&&(e=e.call(this[0])),t=de(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return de.isFunction(e)?this.each(function(t){de(this).wrapInner(e.call(this,t))}):this.each(function(){var t=de(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=de.isFunction(e);return this.each(function(n){de(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not(\"body\").each(function(){de(this).replaceWith(this.childNodes)}),this}}),de.expr.pseudos.hidden=function(e){return!de.expr.pseudos.visible(e)},de.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},de.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var _t={0:200,1223:204},Wt=de.ajaxSettings.xhr();pe.cors=!!Wt&&\"withCredentials\"in Wt,pe.ajax=Wt=!!Wt,de.ajaxTransport(function(t){var n,r;if(pe.cors||Wt&&!t.crossDomain)return{send:function(o,i){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||o[\"X-Requested-With\"]||(o[\"X-Requested-With\"]=\"XMLHttpRequest\");for(a in o)s.setRequestHeader(a,o[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.onreadystatechange=null,\"abort\"===e?s.abort():\"error\"===e?\"number\"!=typeof s.status?i(0,\"error\"):i(s.status,s.statusText):i(_t[s.status]||s.status,s.statusText,\"text\"!==(s.responseType||\"text\")||\"string\"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=n(\"error\"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n(\"abort\");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),de.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),de.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(e){return de.globalEval(e),e}}}),de.ajaxPrefilter(\"script\",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type=\"GET\")}),de.ajaxTransport(\"script\",function(e){if(e.crossDomain){var t,n;return{send:function(r,o){t=de(\"<script>\").prop({charset:e.scriptCharset,src:e.url}).on(\"load error\",n=function(e){t.remove(),n=null,e&&o(\"error\"===e.type?404:200,e.type)}),te.head.appendChild(t[0])},abort:function(){n&&n()}}}});var Bt=[],Ut=/(=)\\?(?=&|$)|\\?\\?/;de.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var e=Bt.pop()||de.expando+\"_\"+kt++;return this[e]=!0,e}}),de.ajaxPrefilter(\"json jsonp\",function(t,n,r){var o,i,a,s=t.jsonp!==!1&&(Ut.test(t.url)?\"url\":\"string\"==typeof t.data&&0===(t.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&Ut.test(t.data)&&\"data\");if(s||\"jsonp\"===t.dataTypes[0])return o=t.jsonpCallback=de.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(Ut,\"$1\"+o):t.jsonp!==!1&&(t.url+=(jt.test(t.url)?\"&\":\"?\")+t.jsonp+\"=\"+o),t.converters[\"script json\"]=function(){return a||de.error(o+\" was not called\"),a[0]},t.dataTypes[0]=\"json\",i=e[o],e[o]=function(){a=arguments},r.always(function(){void 0===i?de(e).removeProp(o):e[o]=i,t[o]&&(t.jsonpCallback=n.jsonpCallback,Bt.push(o)),a&&de.isFunction(i)&&i(a[0]),a=i=void 0}),\"script\"}),pe.createHTMLDocument=function(){var e=te.implementation.createHTMLDocument(\"\").body;return e.innerHTML=\"<form></form><form></form>\",2===e.childNodes.length}(),de.parseHTML=function(e,t,n){if(\"string\"!=typeof e)return[];\"boolean\"==typeof t&&(n=t,t=!1);var r,o,i;return t||(pe.createHTMLDocument?(t=te.implementation.createHTMLDocument(\"\"),r=t.createElement(\"base\"),r.href=te.location.href,t.head.appendChild(r)):t=te),o=Te.exec(e),i=!n&&[],o?[t.createElement(o[1])]:(o=b([e],t,i),i&&i.length&&de(i).remove(),de.merge([],o.childNodes))},de.fn.load=function(e,t,n){var r,o,i,a=this,s=e.indexOf(\" \");return s>-1&&(r=z(e.slice(s)),e=e.slice(0,s)),de.isFunction(t)?(n=t,t=void 0):t&&\"object\"==typeof t&&(o=\"POST\"),a.length>0&&de.ajax({url:e,type:o||\"GET\",dataType:\"html\",data:t}).done(function(e){i=arguments,a.html(r?de(\"<div>\").append(de.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,i||[e.responseText,t,e])})}),this},de.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(e,t){de.fn[t]=function(e){return this.on(t,e)}}),de.expr.pseudos.animated=function(e){return de.grep(de.timers,function(t){return e===t.elem}).length},de.offset={setOffset:function(e,t,n){var r,o,i,a,s,u,l,c=de.css(e,\"position\"),f=de(e),p={};\"static\"===c&&(e.style.position=\"relative\"),s=f.offset(),i=de.css(e,\"top\"),u=de.css(e,\"left\"),l=(\"absolute\"===c||\"fixed\"===c)&&(i+u).indexOf(\"auto\")>-1,l?(r=f.position(),a=r.top,o=r.left):(a=parseFloat(i)||0,o=parseFloat(u)||0),de.isFunction(t)&&(t=t.call(e,n,de.extend({},s))),null!=t.top&&(p.top=t.top-s.top+a),null!=t.left&&(p.left=t.left-s.left+o),\"using\"in t?t.using.call(e,p):f.css(p)}},de.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){de.offset.setOffset(this,e,t)});var t,n,r,o,i=this[0];if(i)return i.getClientRects().length?(r=i.getBoundingClientRect(),r.width||r.height?(o=i.ownerDocument,n=Z(o),t=o.documentElement,{top:r.top+n.pageYOffset-t.clientTop,left:r.left+n.pageXOffset-t.clientLeft}):r):{top:0,left:0}},position:function(){if(this[0]){var e,t,n=this[0],r={top:0,left:0};return\"fixed\"===de.css(n,\"position\")?t=n.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),de.nodeName(e[0],\"html\")||(r=e.offset()),r={top:r.top+de.css(e[0],\"borderTopWidth\",!0),left:r.left+de.css(e[0],\"borderLeftWidth\",!0)}),{top:t.top-r.top-de.css(n,\"marginTop\",!0),left:t.left-r.left-de.css(n,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&\"static\"===de.css(e,\"position\");)e=e.offsetParent;return e||Ye})}}),de.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(e,t){var n=\"pageYOffset\"===t;de.fn[e]=function(r){return Le(this,function(e,r,o){var i=Z(e);return void 0===o?i?i[t]:e[r]:void(i?i.scrollTo(n?i.pageXOffset:o,n?o:i.pageYOffset):e[r]=o)},e,r,arguments.length)}}),de.each([\"top\",\"left\"],function(e,t){de.cssHooks[t]=O(pe.pixelPosition,function(e,n){if(n)return n=D(e,t),at.test(n)?de(e).position()[t]+\"px\":n})}),de.each({Height:\"height\",Width:\"width\"},function(e,t){de.each({padding:\"inner\"+e,content:t,\"\":\"outer\"+e},function(n,r){de.fn[r]=function(o,i){var a=arguments.length&&(n||\"boolean\"!=typeof o),s=n||(o===!0||i===!0?\"margin\":\"border\");return Le(this,function(t,n,o){var i;return de.isWindow(t)?0===r.indexOf(\"outer\")?t[\"inner\"+e]:t.document.documentElement[\"client\"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body[\"scroll\"+e],i[\"scroll\"+e],t.body[\"offset\"+e],i[\"offset\"+e],i[\"client\"+e])):void 0===o?de.css(t,n,s):de.style(t,n,o,s)},t,a?o:void 0,a)}})}),de.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)}}),de.parseJSON=JSON.parse,\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return de});var zt=e.jQuery,Xt=e.$;return de.noConflict=function(t){return e.$===de&&(e.$=Xt),t&&e.jQuery===de&&(e.jQuery=zt),de},t||(e.jQuery=e.$=de),de})},{}],2:[function(e,t,n){!function(e,n,r){function o(e,t,n){return e.addEventListener?void e.addEventListener(t,n,!1):void e.attachEvent(\"on\"+t,n)}function i(e){if(\"keypress\"==e.type){var t=String.fromCharCode(e.which);return e.shiftKey||(t=t.toLowerCase()),t}return y[e.which]?y[e.which]:b[e.which]?b[e.which]:String.fromCharCode(e.which).toLowerCase()}function a(e,t){return e.sort().join(\",\")===t.sort().join(\",\")}function s(e){var t=[];return e.shiftKey&&t.push(\"shift\"),e.altKey&&t.push(\"alt\"),e.ctrlKey&&t.push(\"ctrl\"),e.metaKey&&t.push(\"meta\"),t}function u(e){return e.preventDefault?void e.preventDefault():void(e.returnValue=!1)}function l(e){return e.stopPropagation?void e.stopPropagation():void(e.cancelBubble=!0)}function c(e){return\"shift\"==e||\"ctrl\"==e||\"alt\"==e||\"meta\"==e}function f(){if(!v){v={};for(var e in y)e>95&&e<112||y.hasOwnProperty(e)&&(v[y[e]]=e)}return v}function p(e,t,n){return n||(n=f()[e]?\"keydown\":\"keypress\"),\"keypress\"==n&&t.length&&(n=\"keydown\"),n}function h(e){return\"+\"===e?[\"+\"]:(e=e.replace(/\\+{2}/g,\"+plus\"),e.split(\"+\"))}function d(e,t){var n,r,o,i=[];for(n=h(e),o=0;o<n.length;++o)r=n[o],w[r]&&(r=w[r]),t&&\"keypress\"!=t&&x[r]&&(r=x[r],i.push(\"shift\")),c(r)&&i.push(r);return t=p(r,i,t),{key:r,modifiers:i,action:t}}function g(e,t){return null!==e&&e!==n&&(e===t||g(e.parentNode,t))}function m(e){function t(e){e=e||{};var t,n=!1;for(t in x)e[t]?n=!0:x[t]=0;n||(T=!1)}function r(e,t,n,r,o,i){var s,u,l=[],f=n.type;if(!y._callbacks[e])return[];for(\"keyup\"==f&&c(e)&&(t=[e]),s=0;s<y._callbacks[e].length;++s)if(u=y._callbacks[e][s],(r||!u.seq||x[u.seq]==u.level)&&f==u.action&&(\"keypress\"==f&&!n.metaKey&&!n.ctrlKey||a(t,u.modifiers))){var p=!r&&u.combo==o,h=r&&u.seq==r&&u.level==i;(p||h)&&y._callbacks[e].splice(s,1),l.push(u)}return l}function f(e,t,n,r){y.stopCallback(t,t.target||t.srcElement,n,r)||e(t,n)===!1&&(u(t),l(t))}function p(e){\"number\"!=typeof e.which&&(e.which=e.keyCode);var t=i(e);if(t)return\"keyup\"==e.type&&w===t?void(w=!1):void y.handleKey(t,s(e),e)}function h(){clearTimeout(b),b=setTimeout(t,1e3)}function g(e,n,r,o){function a(t){return function(){T=t,++x[e],h()}}function s(n){f(r,n,e),\"keyup\"!==o&&(w=i(n)),setTimeout(t,10)}x[e]=0;for(var u=0;u<n.length;++u){var l=u+1===n.length,c=l?s:a(o||d(n[u+1]).action);v(n[u],c,o,e,u)}}function v(e,t,n,o,i){y._directMap[e+\":\"+n]=t,e=e.replace(/\\s+/g,\" \");var a,s=e.split(\" \");return s.length>1?void g(e,s,t,n):(a=d(e,n),y._callbacks[a.key]=y._callbacks[a.key]||[],r(a.key,a.modifiers,{type:a.action},o,e,i),void y._callbacks[a.key][o?\"unshift\":\"push\"]({callback:t,modifiers:a.modifiers,action:a.action,seq:o,level:i,combo:e}))}var y=this;if(e=e||n,!(y instanceof m))return new m(e);y.target=e,y._callbacks={},y._directMap={};var b,x={},w=!1,C=!1,T=!1;y._handleKey=function(e,n,o){var i,a=r(e,n,o),s={},u=0,l=!1;for(i=0;i<a.length;++i)a[i].seq&&(u=Math.max(u,a[i].level));for(i=0;i<a.length;++i)if(a[i].seq){if(a[i].level!=u)continue;l=!0,s[a[i].seq]=1,f(a[i].callback,o,a[i].combo,a[i].seq)}else l||f(a[i].callback,o,a[i].combo);var p=\"keypress\"==o.type&&C;o.type!=T||c(e)||p||t(s),C=l&&\"keydown\"==o.type},y._bindMultiple=function(e,t,n){for(var r=0;r<e.length;++r)v(e[r],t,n)},o(e,\"keypress\",p),o(e,\"keydown\",p),o(e,\"keyup\",p)}if(e){for(var v,y={8:\"backspace\",9:\"tab\",13:\"enter\",16:\"shift\",17:\"ctrl\",18:\"alt\",20:\"capslock\",27:\"esc\",32:\"space\",33:\"pageup\",34:\"pagedown\",35:\"end\",36:\"home\",37:\"left\",38:\"up\",39:\"right\",40:\"down\",45:\"ins\",46:\"del\",91:\"meta\",93:\"meta\",224:\"meta\"},b={106:\"*\",107:\"+\",109:\"-\",110:\".\",111:\"/\",186:\";\",187:\"=\",188:\",\",189:\"-\",190:\".\",191:\"/\",192:\"`\",219:\"[\",220:\"\\\\\",221:\"]\",222:\"'\"},x={\"~\":\"`\",\"!\":\"1\",\"@\":\"2\",\"#\":\"3\",$:\"4\",\"%\":\"5\",\"^\":\"6\",\"&\":\"7\",\"*\":\"8\",\"(\":\"9\",\")\":\"0\",_:\"-\",\"+\":\"=\",\":\":\";\",'\"':\"'\",\"<\":\",\",\">\":\".\",\"?\":\"/\",\"|\":\"\\\\\"},w={option:\"alt\",command:\"meta\",return:\"enter\",escape:\"esc\",plus:\"+\",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?\"meta\":\"ctrl\"},C=1;C<20;++C)y[111+C]=\"f\"+C;for(C=0;C<=9;++C)y[C+96]=C;m.prototype.bind=function(e,t,n){var r=this;return e=e instanceof Array?e:[e],r._bindMultiple.call(r,e,t,n),r},m.prototype.unbind=function(e,t){var n=this;return n.bind.call(n,e,function(){},t)},m.prototype.trigger=function(e,t){var n=this;return n._directMap[e+\":\"+t]&&n._directMap[e+\":\"+t]({},e),n},m.prototype.reset=function(){var e=this;return e._callbacks={},e._directMap={},e},m.prototype.stopCallback=function(e,t){var n=this;return!((\" \"+t.className+\" \").indexOf(\" mousetrap \")>-1)&&(!g(t,n.target)&&(\"INPUT\"==t.tagName||\"SELECT\"==t.tagName||\"TEXTAREA\"==t.tagName||t.isContentEditable))},m.prototype.handleKey=function(){var e=this;return e._handleKey.apply(e,arguments)},m.addKeycodes=function(e){for(var t in e)e.hasOwnProperty(t)&&(y[t]=e[t]);v=null},m.init=function(){var e=m(n);for(var t in e)\"_\"!==t.charAt(0)&&(m[t]=function(t){return function(){return e[t].apply(e,arguments)}}(t))},m.init(),e.Mousetrap=m,\"undefined\"!=typeof t&&t.exports&&(t.exports=m),\"function\"==typeof define&&define.amd&&define(function(){return m})}}(\"undefined\"!=typeof window?window:null,\"undefined\"!=typeof window?document:null)},{}],3:[function(e,t,n){(function(e){!function(r){function o(e){throw new RangeError(L[e])}function i(e,t){for(var n=e.length,r=[];n--;)r[n]=t(e[n]);return r}function a(e,t){var n=e.split(\"@\"),r=\"\";n.length>1&&(r=n[0]+\"@\",e=n[1]),e=e.replace(O,\".\");var o=e.split(\".\"),a=i(o,t).join(\".\");return r+a}function s(e){for(var t,n,r=[],o=0,i=e.length;o<i;)t=e.charCodeAt(o++),t>=55296&&t<=56319&&o<i?(n=e.charCodeAt(o++),56320==(64512&n)?r.push(((1023&t)<<10)+(1023&n)+65536):(r.push(t),o--)):r.push(t);return r}function u(e){return i(e,function(e){var t=\"\";return e>65535&&(e-=65536,t+=P(e>>>10&1023|55296),e=56320|1023&e),t+=P(e)}).join(\"\")}function l(e){return e-48<10?e-22:e-65<26?e-65:e-97<26?e-97:C}function c(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function f(e,t,n){var r=0;for(e=n?F(e/E):e>>1,e+=F(e/t);e>H*k>>1;r+=C)e=F(e/H);return F(r+(H+1)*e/(e+j))}function p(e){var t,n,r,i,a,s,c,p,h,d,g=[],m=e.length,v=0,y=S,b=N;for(n=e.lastIndexOf(A),n<0&&(n=0),r=0;r<n;++r)e.charCodeAt(r)>=128&&o(\"not-basic\"),g.push(e.charCodeAt(r));for(i=n>0?n+1:0;i<m;){for(a=v,s=1,c=C;i>=m&&o(\"invalid-input\"),p=l(e.charCodeAt(i++)),(p>=C||p>F((w-v)/s))&&o(\"overflow\"),v+=p*s,h=c<=b?T:c>=b+k?k:c-b,!(p<h);c+=C)d=C-h,s>F(w/d)&&o(\"overflow\"),s*=d;t=g.length+1,b=f(v-a,t,0==a),F(v/t)>w-y&&o(\"overflow\"),y+=F(v/t),v%=t,g.splice(v++,0,y)}return u(g)}function h(e){var t,n,r,i,a,u,l,p,h,d,g,m,v,y,b,x=[];for(e=s(e),m=e.length,t=S,n=0,a=N,u=0;u<m;++u)g=e[u],g<128&&x.push(P(g));for(r=i=x.length,i&&x.push(A);r<m;){for(l=w,u=0;u<m;++u)g=e[u],g>=t&&g<l&&(l=g);for(v=r+1,l-t>F((w-n)/v)&&o(\"overflow\"),n+=(l-t)*v,t=l,u=0;u<m;++u)if(g=e[u],g<t&&++n>w&&o(\"overflow\"),g==t){for(p=n,h=C;d=h<=a?T:h>=a+k?k:h-a,!(p<d);h+=C)b=p-d,y=C-d,x.push(P(c(d+b%y,0))),p=F(b/y);x.push(P(c(p,0))),a=f(n,v,r==i),n=0,++r}++n,++t}return x.join(\"\")}function d(e){return a(e,function(e){return q.test(e)?p(e.slice(4).toLowerCase()):e})}function g(e){return a(e,function(e){return D.test(e)?\"xn--\"+h(e):e})}var m=\"object\"==typeof n&&n&&!n.nodeType&&n,v=\"object\"==typeof t&&t&&!t.nodeType&&t,y=\"object\"==typeof e&&e;y.global!==y&&y.window!==y&&y.self!==y||(r=y);var b,x,w=2147483647,C=36,T=1,k=26,j=38,E=700,N=72,S=128,A=\"-\",q=/^xn--/,D=/[^\\x20-\\x7E]/,O=/[\\x2E\\u3002\\uFF0E\\uFF61]/g,L={overflow:\"Overflow: input needs wider integers to process\",\"not-basic\":\"Illegal input >= 0x80 (not a basic code point)\",\"invalid-input\":\"Invalid input\"},H=C-T,F=Math.floor,P=String.fromCharCode;if(b={version:\"1.4.1\",ucs2:{decode:s,encode:u},decode:p,encode:h,toASCII:g,toUnicode:d},\"function\"==typeof define&&\"object\"==typeof define.amd&&define.amd)define(\"punycode\",function(){return b});else if(m&&v)if(t.exports==m)v.exports=b;else for(x in b)b.hasOwnProperty(x)&&(m[x]=b[x]);else r.punycode=b}(this)}).call(this,\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{})},{}],4:[function(e,t,n){\"use strict\";function r(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.exports=function(e,t,n,i){t=t||\"&\",n=n||\"=\";var a={};if(\"string\"!=typeof e||0===e.length)return a;var s=/\\+/g;e=e.split(t);var u=1e3;i&&\"number\"==typeof i.maxKeys&&(u=i.maxKeys);var l=e.length;u>0&&l>u&&(l=u);for(var c=0;c<l;++c){var f,p,h,d,g=e[c].replace(s,\"%20\"),m=g.indexOf(n);m>=0?(f=g.substr(0,m),p=g.substr(m+1)):(f=g,p=\"\"),h=decodeURIComponent(f),d=decodeURIComponent(p),\nr(a,h)?o(a[h])?a[h].push(d):a[h]=[a[h],d]:a[h]=d}return a};var o=Array.isArray||function(e){return\"[object Array]\"===Object.prototype.toString.call(e)}},{}],5:[function(e,t,n){\"use strict\";function r(e,t){if(e.map)return e.map(t);for(var n=[],r=0;r<e.length;r++)n.push(t(e[r],r));return n}var o=function(e){switch(typeof e){case\"string\":return e;case\"boolean\":return e?\"true\":\"false\";case\"number\":return isFinite(e)?e:\"\";default:return\"\"}};t.exports=function(e,t,n,s){return t=t||\"&\",n=n||\"=\",null===e&&(e=void 0),\"object\"==typeof e?r(a(e),function(a){var s=encodeURIComponent(o(a))+n;return i(e[a])?r(e[a],function(e){return s+encodeURIComponent(o(e))}).join(t):s+encodeURIComponent(o(e[a]))}).join(t):s?encodeURIComponent(o(s))+n+encodeURIComponent(o(e)):\"\"};var i=Array.isArray||function(e){return\"[object Array]\"===Object.prototype.toString.call(e)},a=Object.keys||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.push(n);return t}},{}],6:[function(e,t,n){\"use strict\";n.decode=n.parse=e(\"./decode\"),n.encode=n.stringify=e(\"./encode\")},{\"./decode\":4,\"./encode\":5}],7:[function(e,t,n){\"use strict\";function r(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}function o(e,t,n){if(e&&l.isObject(e)&&e instanceof r)return e;var o=new r;return o.parse(e,t,n),o}function i(e){return l.isString(e)&&(e=o(e)),e instanceof r?e.format():r.prototype.format.call(e)}function a(e,t){return o(e,!1,!0).resolve(t)}function s(e,t){return e?o(e,!1,!0).resolveObject(t):t}var u=e(\"punycode\"),l=e(\"./util\");n.parse=o,n.resolve=a,n.resolveObject=s,n.format=i,n.Url=r;var c=/^([a-z0-9.+-]+:)/i,f=/:[0-9]*$/,p=/^(\\/\\/?(?!\\/)[^\\?\\s]*)(\\?[^\\s]*)?$/,h=[\"<\",\">\",'\"',\"`\",\" \",\"\\r\",\"\\n\",\"\\t\"],d=[\"{\",\"}\",\"|\",\"\\\\\",\"^\",\"`\"].concat(h),g=[\"'\"].concat(d),m=[\"%\",\"/\",\"?\",\";\",\"#\"].concat(g),v=[\"/\",\"?\",\"#\"],y=255,b=/^[+a-z0-9A-Z_-]{0,63}$/,x=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,w={javascript:!0,\"javascript:\":!0},C={javascript:!0,\"javascript:\":!0},T={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,\"http:\":!0,\"https:\":!0,\"ftp:\":!0,\"gopher:\":!0,\"file:\":!0},k=e(\"querystring\");r.prototype.parse=function(e,t,n){if(!l.isString(e))throw new TypeError(\"Parameter 'url' must be a string, not \"+typeof e);var r=e.indexOf(\"?\"),o=r!==-1&&r<e.indexOf(\"#\")?\"?\":\"#\",i=e.split(o),a=/\\\\/g;i[0]=i[0].replace(a,\"/\"),e=i.join(o);var s=e;if(s=s.trim(),!n&&1===e.split(\"#\").length){var f=p.exec(s);if(f)return this.path=s,this.href=s,this.pathname=f[1],f[2]?(this.search=f[2],t?this.query=k.parse(this.search.substr(1)):this.query=this.search.substr(1)):t&&(this.search=\"\",this.query={}),this}var h=c.exec(s);if(h){h=h[0];var d=h.toLowerCase();this.protocol=d,s=s.substr(h.length)}if(n||h||s.match(/^\\/\\/[^@\\/]+@[^@\\/]+/)){var j=\"//\"===s.substr(0,2);!j||h&&C[h]||(s=s.substr(2),this.slashes=!0)}if(!C[h]&&(j||h&&!T[h])){for(var E=-1,N=0;N<v.length;N++){var S=s.indexOf(v[N]);S!==-1&&(E===-1||S<E)&&(E=S)}var A,q;q=E===-1?s.lastIndexOf(\"@\"):s.lastIndexOf(\"@\",E),q!==-1&&(A=s.slice(0,q),s=s.slice(q+1),this.auth=decodeURIComponent(A)),E=-1;for(var N=0;N<m.length;N++){var S=s.indexOf(m[N]);S!==-1&&(E===-1||S<E)&&(E=S)}E===-1&&(E=s.length),this.host=s.slice(0,E),s=s.slice(E),this.parseHost(),this.hostname=this.hostname||\"\";var D=\"[\"===this.hostname[0]&&\"]\"===this.hostname[this.hostname.length-1];if(!D)for(var O=this.hostname.split(/\\./),N=0,L=O.length;N<L;N++){var H=O[N];if(H&&!H.match(b)){for(var F=\"\",P=0,I=H.length;P<I;P++)F+=H.charCodeAt(P)>127?\"x\":H[P];if(!F.match(b)){var R=O.slice(0,N),M=O.slice(N+1),$=H.match(x);$&&(R.push($[1]),M.unshift($[2])),M.length&&(s=\"/\"+M.join(\".\")+s),this.hostname=R.join(\".\");break}}}this.hostname.length>y?this.hostname=\"\":this.hostname=this.hostname.toLowerCase(),D||(this.hostname=u.toASCII(this.hostname));var _=this.port?\":\"+this.port:\"\",W=this.hostname||\"\";this.host=W+_,this.href+=this.host,D&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),\"/\"!==s[0]&&(s=\"/\"+s))}if(!w[d])for(var N=0,L=g.length;N<L;N++){var B=g[N];if(s.indexOf(B)!==-1){var U=encodeURIComponent(B);U===B&&(U=escape(B)),s=s.split(B).join(U)}}var z=s.indexOf(\"#\");z!==-1&&(this.hash=s.substr(z),s=s.slice(0,z));var X=s.indexOf(\"?\");if(X!==-1?(this.search=s.substr(X),this.query=s.substr(X+1),t&&(this.query=k.parse(this.query)),s=s.slice(0,X)):t&&(this.search=\"\",this.query={}),s&&(this.pathname=s),T[d]&&this.hostname&&!this.pathname&&(this.pathname=\"/\"),this.pathname||this.search){var _=this.pathname||\"\",K=this.search||\"\";this.path=_+K}return this.href=this.format(),this},r.prototype.format=function(){var e=this.auth||\"\";e&&(e=encodeURIComponent(e),e=e.replace(/%3A/i,\":\"),e+=\"@\");var t=this.protocol||\"\",n=this.pathname||\"\",r=this.hash||\"\",o=!1,i=\"\";this.host?o=e+this.host:this.hostname&&(o=e+(this.hostname.indexOf(\":\")===-1?this.hostname:\"[\"+this.hostname+\"]\"),this.port&&(o+=\":\"+this.port)),this.query&&l.isObject(this.query)&&Object.keys(this.query).length&&(i=k.stringify(this.query));var a=this.search||i&&\"?\"+i||\"\";return t&&\":\"!==t.substr(-1)&&(t+=\":\"),this.slashes||(!t||T[t])&&o!==!1?(o=\"//\"+(o||\"\"),n&&\"/\"!==n.charAt(0)&&(n=\"/\"+n)):o||(o=\"\"),r&&\"#\"!==r.charAt(0)&&(r=\"#\"+r),a&&\"?\"!==a.charAt(0)&&(a=\"?\"+a),n=n.replace(/[?#]/g,function(e){return encodeURIComponent(e)}),a=a.replace(\"#\",\"%23\"),t+o+n+a+r},r.prototype.resolve=function(e){return this.resolveObject(o(e,!1,!0)).format()},r.prototype.resolveObject=function(e){if(l.isString(e)){var t=new r;t.parse(e,!1,!0),e=t}for(var n=new r,o=Object.keys(this),i=0;i<o.length;i++){var a=o[i];n[a]=this[a]}if(n.hash=e.hash,\"\"===e.href)return n.href=n.format(),n;if(e.slashes&&!e.protocol){for(var s=Object.keys(e),u=0;u<s.length;u++){var c=s[u];\"protocol\"!==c&&(n[c]=e[c])}return T[n.protocol]&&n.hostname&&!n.pathname&&(n.path=n.pathname=\"/\"),n.href=n.format(),n}if(e.protocol&&e.protocol!==n.protocol){if(!T[e.protocol]){for(var f=Object.keys(e),p=0;p<f.length;p++){var h=f[p];n[h]=e[h]}return n.href=n.format(),n}if(n.protocol=e.protocol,e.host||C[e.protocol])n.pathname=e.pathname;else{for(var d=(e.pathname||\"\").split(\"/\");d.length&&!(e.host=d.shift()););e.host||(e.host=\"\"),e.hostname||(e.hostname=\"\"),\"\"!==d[0]&&d.unshift(\"\"),d.length<2&&d.unshift(\"\"),n.pathname=d.join(\"/\")}if(n.search=e.search,n.query=e.query,n.host=e.host||\"\",n.auth=e.auth,n.hostname=e.hostname||e.host,n.port=e.port,n.pathname||n.search){var g=n.pathname||\"\",m=n.search||\"\";n.path=g+m}return n.slashes=n.slashes||e.slashes,n.href=n.format(),n}var v=n.pathname&&\"/\"===n.pathname.charAt(0),y=e.host||e.pathname&&\"/\"===e.pathname.charAt(0),b=y||v||n.host&&e.pathname,x=b,w=n.pathname&&n.pathname.split(\"/\")||[],d=e.pathname&&e.pathname.split(\"/\")||[],k=n.protocol&&!T[n.protocol];if(k&&(n.hostname=\"\",n.port=null,n.host&&(\"\"===w[0]?w[0]=n.host:w.unshift(n.host)),n.host=\"\",e.protocol&&(e.hostname=null,e.port=null,e.host&&(\"\"===d[0]?d[0]=e.host:d.unshift(e.host)),e.host=null),b=b&&(\"\"===d[0]||\"\"===w[0])),y)n.host=e.host||\"\"===e.host?e.host:n.host,n.hostname=e.hostname||\"\"===e.hostname?e.hostname:n.hostname,n.search=e.search,n.query=e.query,w=d;else if(d.length)w||(w=[]),w.pop(),w=w.concat(d),n.search=e.search,n.query=e.query;else if(!l.isNullOrUndefined(e.search)){if(k){n.hostname=n.host=w.shift();var j=!!(n.host&&n.host.indexOf(\"@\")>0)&&n.host.split(\"@\");j&&(n.auth=j.shift(),n.host=n.hostname=j.shift())}return n.search=e.search,n.query=e.query,l.isNull(n.pathname)&&l.isNull(n.search)||(n.path=(n.pathname?n.pathname:\"\")+(n.search?n.search:\"\")),n.href=n.format(),n}if(!w.length)return n.pathname=null,n.search?n.path=\"/\"+n.search:n.path=null,n.href=n.format(),n;for(var E=w.slice(-1)[0],N=(n.host||e.host||w.length>1)&&(\".\"===E||\"..\"===E)||\"\"===E,S=0,A=w.length;A>=0;A--)E=w[A],\".\"===E?w.splice(A,1):\"..\"===E?(w.splice(A,1),S++):S&&(w.splice(A,1),S--);if(!b&&!x)for(;S--;S)w.unshift(\"..\");!b||\"\"===w[0]||w[0]&&\"/\"===w[0].charAt(0)||w.unshift(\"\"),N&&\"/\"!==w.join(\"/\").substr(-1)&&w.push(\"\");var q=\"\"===w[0]||w[0]&&\"/\"===w[0].charAt(0);if(k){n.hostname=n.host=q?\"\":w.length?w.shift():\"\";var j=!!(n.host&&n.host.indexOf(\"@\")>0)&&n.host.split(\"@\");j&&(n.auth=j.shift(),n.host=n.hostname=j.shift())}return b=b||n.host&&w.length,b&&!q&&w.unshift(\"\"),w.length?n.pathname=w.join(\"/\"):(n.pathname=null,n.path=null),l.isNull(n.pathname)&&l.isNull(n.search)||(n.path=(n.pathname?n.pathname:\"\")+(n.search?n.search:\"\")),n.auth=e.auth||n.auth,n.slashes=n.slashes||e.slashes,n.href=n.format(),n},r.prototype.parseHost=function(){var e=this.host,t=f.exec(e);t&&(t=t[0],\":\"!==t&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)}},{\"./util\":8,punycode:3,querystring:6}],8:[function(e,t,n){\"use strict\";t.exports={isString:function(e){return\"string\"==typeof e},isObject:function(e){return\"object\"==typeof e&&null!==e},isNull:function(e){return null===e},isNullOrUndefined:function(e){return null==e}}},{}],9:[function(e,t,n){function r(e){var t=a(e.currentTarget).parent().find(\".dropdown-menu\");t.toggleClass(\"open\"),e.stopPropagation(),e.preventDefault()}function o(e){a(\".dropdown-menu\").removeClass(\"open\")}function i(){a(document).on(\"click\",\".toggle-dropdown\",r),a(document).on(\"click\",\".dropdown-menu\",function(e){e.stopPropagation()}),a(document).on(\"click\",o)}var a=e(\"jquery\");t.exports={init:i}},{jquery:1}],10:[function(e,t,n){function r(){s.init(),i.init(),o.init(),a.init(),u.createButton({index:0,icon:\"fa fa-align-justify\",onClick:function(e){e.preventDefault(),s.toggle()}})}var o=e(\"./dropdown\"),i=e(\"./keyboard\"),a=e(\"./navigation\"),s=e(\"./sidebar\"),u=e(\"./toolbar\"),l=window.gitbook;l.events.on(\"start\",r),l.keyboard=i,l.navigation=a,l.sidebar=s,l.toolbar=u},{\"./dropdown\":9,\"./keyboard\":11,\"./navigation\":13,\"./sidebar\":15,\"./toolbar\":16}],11:[function(e,t,n){function r(e,t){i.bind(e,function(e){return t(),!1})}function o(){r([\"right\"],function(e){a.goNext()}),r([\"left\"],function(e){a.goPrev()}),r([\"s\"],function(e){s.toggle()})}var i=e(\"mousetrap\"),a=e(\"./navigation\"),s=e(\"./sidebar\");t.exports={init:o,bind:r}},{\"./navigation\":13,\"./sidebar\":15,mousetrap:2}],12:[function(e,t,n){function r(e){return o.state.$book.addClass(\"is-loading\"),e.always(function(){o.state.$book.removeClass(\"is-loading\")}),e}var o=window.gitbook;t.exports={show:r}},{}],13:[function(e,t,n){function r(){return w(k.isSmallScreen()?\".book-body\":\".body-inner\")}function o(e){var t=r(),n=0;i(e)&&(e&&(n=a(e)),t.unbind(\"scroll\"),t.animate({scrollTop:n},800,\"swing\",function(){t.scroll(l)}),s(null,e))}function i(e){var t=r(),n=t.find(e);return!!n.length}function a(e){var t=r(),n=t.find(\".page-inner\"),o=t.find(e),i=o.offsetParent(),a=0;for(a=o.position().top;!i.is(n);)o=i,a+=o.position().top,i=o.offsetParent();return Math.floor(a)}function s(e,t){if(e||t||(e=b.first()),t&&(e=b.length>1?b.filter(function(){var e=u(w(this));return e==t}).first():b.first()),!e.is(x)){x=e,b.removeClass(\"active\"),e.addClass(\"active\"),t=u(e);var n=window.location.pathname+window.location.hash,r=window.location.pathname+t;r!=n&&history.replaceState({path:r},null,r)}}function u(e){var t=e.children(\"a\"),n=t.attr(\"href\").split(\"#\")[1];return n&&(n=\"#\"+n),n?n:\"\"}function l(){var e=r(),t=e.scrollTop(),n=e.prop(\"scrollHeight\"),o=e.prop(\"clientHeight\"),i=b.length,l=null;w(b.get().reverse()).each(function(e){var n,r=u(w(this));r&&!l&&(n=a(r),t>=n&&(l=w(this))),e!=i-1||l||(l=w(this))}),l||t||(l=b.first()),t&&n-t==o&&(l=b.last()),s(l)}function c(e,t){var n=C.parse(N),r=C.resolve(window.location.pathname,e),i=C.parse(r),a=i.hash,s=i.pathname!==n.pathname,u=Boolean(i.hostname);if(!E||u)return void(location.href=e);if(!s)return t&&history.pushState({path:r},null,r),o(a);N=r;var l=w.Deferred(function(e){w.ajax({type:\"GET\",url:r,cache:!0,headers:{\"Access-Control-Expose-Headers\":\"X-Current-Location\"},success:function(n,i,s){var u=s.getResponseHeader(\"X-Current-Location\")||r;n=n.replace(/<(\\/?)(html|head|body)([^>]*)>/gi,function(e,t,n,r){return\"<\"+t+\"div\"+(t?\"\":' data-element=\"'+n+'\"')+r+\">\"});var l,c=w(n),f=c.find(\".book\");if(0===f.length){var h=new Error(\"Invalid gitbook page, redirecting...\");return e.reject(h)}t&&history.pushState({path:u},null,u),c=w(n),l=c.find(\"[data-element=head]\"),f=c.find(\".book\"),document.title=l.find(\"title\").text();var d=w(\"head\");d.find(\"link[rel=prev]\").remove(),d.find(\"link[rel=next]\").remove(),d.append(l.find(\"link[rel=prev]\")),d.append(l.find(\"link[rel=next]\"));var g=w(\".book\").attr(\"class\"),m=w(\".book-summary\").scrollTop();f.toggleClass(\"with-summary\",w(\".book\").hasClass(\"with-summary\")),w(\".book\").replaceWith(f),w(\".book\").attr(\"class\",g),w(\".book-summary\").scrollTop(m),j.state.$book=w(\".book\"),p(!a),a&&o(a),e.resolve()}})}).promise();return T.show(l.fail(function(e){console.log(e)}))}function f(){var e,t;e=parseInt(w(\".body-inner\").css(\"width\"),10),t=parseInt(w(\".page-wrapper\").css(\"width\"),10),w(\".navigation-next\").css(\"margin-right\",e-t+\"px\");var n=r();n.unbind(\"scroll\"),n.scroll(l)}function p(e){var t=w(\".book-body\"),n=t.find(\".body-inner\"),o=n.find(\".page-wrapper\");f(),o.focus();var i=r();e!==!1&&i.scrollTop(0),b=w(\".book-summary .summary .chapter\").filter(function(){var e=w(this).children(\"a\"),t=null;if(!e.length)return!1;t=e.attr(\"href\").split(\"#\")[0];var n=C.resolve(window.location.pathname,t);return window.location.pathname==n}),b.length>1?i.scroll(l):x=b.first()}function h(e){return 0===e.button}function d(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function g(e){var t=w(this),n=t.attr(\"target\");if(!d(e)&&h(e)&&!n){e.stopPropagation(),e.preventDefault();var r=t.attr(\"href\");r&&c(r,!0)}}function m(){var e=w(\".navigation-next\").attr(\"href\");e&&c(e,!0)}function v(){var e=w(\".navigation-prev\").attr(\"href\");e&&c(e,!0)}function y(){w.ajaxSetup({cache:!1}),history.replaceState({path:window.location.href},\"\"),window.onpopstate=function(e){if(null!==e.state)return c(e.state.path,!1)},w(document).on(\"click\",\".navigation-prev\",g),w(document).on(\"click\",\".navigation-next\",g),w(document).on(\"click\",\".summary [data-path] a\",g),w(document).on(\"click\",\".page-inner a\",g),w(window).resize(f),p(!1)}var b,x,w=e(\"jquery\"),C=e(\"url\"),T=e(\"./loading\"),k=e(\"./platform\"),j=window.gitbook,E=\"undefined\"!=typeof history.pushState,N=location.href;t.exports={init:y,goNext:m,goPrev:v}},{\"./loading\":12,\"./platform\":14,jquery:1,url:7}],14:[function(e,t,n){var r=e(\"jquery\");t.exports={isMobile:function(){return r(document).width()<=600},isSmallScreen:function(){return r(document).width()<=1240}}},{jquery:1}],15:[function(e,t,n){function r(e,t){null!=l.state&&o()==e||(null==t&&(t=!0),l.state.$book.toggleClass(\"without-animation\",!t),l.state.$book.toggleClass(\"with-summary\",e),l.storage.set(\"sidebar\",o()))}function o(){return l.state.$book.hasClass(\"with-summary\")}function i(){u.isMobile()||r(l.storage.get(\"sidebar\",!0),!1),s(document).on(\"click\",\".book-summary li.chapter a\",function(e){u.isMobile()&&r(!1,!1)})}function a(e){var t=s(\".book-summary\");t.find(\"li\").each(function(){var t=s(this).data(\"path\"),n=null==e||e.indexOf(t)!==-1;s(this).toggle(n),n&&s(this).parents(\"li\").show()})}var s=e(\"jquery\"),u=e(\"./platform\"),l=window.gitbook;t.exports={init:i,isOpen:o,toggle:r,filter:a}},{\"./platform\":14,jquery:1}],16:[function(e,t,n){function r(){return\"btn-\"+g++}function o(e,t,n,r){var o=e.children(t).length;n<0&&(n=Math.max(0,o+1+n)),e.append(r),n<o&&e.children(t).eq(n).before(e.children(t).last())}function i(e){e.preventDefault()}function a(e){var t=p(\"<div>\",{class:\"dropdown-menu\",html:'<div class=\"dropdown-caret\"><span class=\"caret-outer\"></span><span class=\"caret-inner\"></span></div>'});if(\"string\"==typeof e)t.append(e);else{var n=e.map(function(e){return p.isArray(e)?e:[e]});n.forEach(function(e){var n=p(\"<div>\",{class:\"buttons\"}),r=\"size-\"+e.length;e.forEach(function(e){e=p.extend({text:\"\",className:\"\",onClick:i},e||{});var t=p(\"<button>\",{class:\"button \"+r+\" \"+e.className,text:e.text});t.click(e.onClick),n.append(t)}),t.append(n)})}return t}function s(e){return e=p.extend({label:\"\",icon:\"\",text:\"\",position:\"left\",className:\"\",onClick:i,dropdown:null,index:null,id:r()},e||{}),d.push(e),u(e),e.id}function u(e){var t,n=p(\".book-header\"),r=n.find(\"h1\"),i=\"pull-\"+e.position,s=p(\"<a>\",{class:\"btn\",text:e.text?\" \"+e.text:\"\",\"aria-label\":e.label,href:\"#\"});if(s.click(e.onClick),e.icon&&p(\"<i>\",{class:e.icon}).prependTo(s),e.dropdown){var u=p(\"<div>\",{class:\"dropdown \"+i+\" \"+e.className});s.addClass(\"toggle-dropdown\"),u.append(s);var l=a(e.dropdown);l.addClass(\"dropdown-\"+(\"right\"==e.position?\"left\":\"right\")),u.append(l),t=u}else s.addClass(i),s.addClass(e.className),t=s;t.addClass(\"js-toolbar-action\"),p.isNumeric(e.index)&&e.index>=0?o(n,\".btn, .dropdown, h1\",e.index,t):t.insertBefore(r)}function l(){p(\".js-toolbar-action\").remove(),d.forEach(u)}function c(e){d=p.grep(d,function(t){return t.id!=e}),l()}function f(e){d=p.grep(d,function(t){return e.indexOf(t.id)==-1}),l()}var p=e(\"jquery\"),h=window.gitbook,d=[],g=0;h.events.on(\"page.change\",function(){l()}),t.exports={createButton:s,removeButton:c,removeButtons:f}},{jquery:1}]},{},[10]);\n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/guide_for_build.md",
    "content": "    # 主工程容器接入\nAtlas开源的代码内容主要包括以下几个模块：\n\n1. 基于gradle的构建插件（包括修改过的aapt内容）；\n2.\tandroid端测容器运行库atlas_core；\n3. 基于容器提供更新能力的库atlas_update;\n\n我们比较倾向于用一个比较干净的壳子工程来作为容器架构下的打包工程，这个工程建议只存在AndroidManifest.xml和构建的文件及部分资源内容，manifest文件用于单独管理apk的icon，版本号，versioncode等；构建文件管理版本依赖；这里我们取名打包工程等名字为apk_builder;\n通常情况下Apk_builder除了主Apk的AndroidManifest.xml之外，接入Atlas后，Main_builder将会包含以下内容：\n\n1. **build.gradle** : 用于配置主apk的依赖及控制构建参数\n2. **packageIdFile.properties**: 配置bundle的packageId,以保证资源段独立（也可以通过mtl.tBuildConfig.autoPackageId设置自动分配packageID）\n3. **bundleBaseInfoFile.json**: 配置bundle的依赖关系\n\n下面会逐个说明每个文件的使用和注意要点\n\n## build.gradle(AtlasGradlePlugin)\n支持 atlas 工程打包的gradle 插件， 基于 google 官方的 android builder （2.0.0~2.1.0）\n\n\n1. 引用插件及依赖仓库\n\n\t\tbuildscript {\n\t\t    repositories {\n\t\t        mavenLocal()\n\t\t        jcenter()\n\t\t    }\n\t\t    dependencies {\n\t\t        classpath \"com.taobao.android:atlasplugin:1.0.1\"\n\t\t    }\n\t\t}\n\t\trepositories {\n    \t\tjcenter()\n\t\t}\n\t\t\n\t注意尽量不要指定 classpath \"com.android.tools.build:gradle\"的版本，默认使用的是 2.1\n\n2. 应用plugin\n\n\t\tapply plugin: 'com.taobao.atlas.application'\n\t\t//注意不能同时 apply com.android.application\n\n3. 添加运行库依赖\t\n\t    \n\t    dependencies {\n       \tcompile('com.taobao.android:atlas_core:5.0.0@aar') {\n        \ttransitive = true\n    \t}\n        compile 'com.taobao.android:atlasupdate:1.0.8@aar'\n        \n\t**如果不需要用到atlas的动态部署功能，不需要依赖atlasupdate**    \n\t\n4. 开启atlas容器功能\n    \n         atlas {\n         \tatlasEnabled true\n    \t   tBuildConfig {\n        \t\tautoStartBundles =['com.taobao.firstbundle'] //自启动bundle配置\n\t\t\t}\n\n         \tpatchConfigs{\n        \t\tdebug {\n            \tcreateTPatch true\n        \t\t}\n  \t\t  \t}\n       \t\t buildTypes {\n        \t\tdebug {\n            \t\tif (apVersion){\n          \t\t  \t\tbaseApDependency  \"com.taobao.android.atlasdemo:AP-debug:${apVersion}@ap\"\n            \t\t\tpatchConfig    patchConfigs.debug\n            \t\t\t}\n        \t\t\t}\n\t \t\t\t}\n  \t\t  }   \n\n\t**atlasEnable字段需要指定为true才能开启打包阶段的基于容器扩展的task**    \n\t\n   **后续两个设置用语动态部署打包时的开关设置，其余字段参考配置列表中的使用方式**\n\n\n5. 构建\n\t1. APK构建 **./gradlew assembleDebug 或者 assembleRelease**\n\t\n    \t构建产物：\n\n\t\t1. build/outputs/apk/xx.apk , 构建的产物apk   \n\t\t2. build/outputs/apk/xx.ap , 构建的基线包， 里面包含 apk 和其他的打包中间配置\n\t\t3. build/outputs/dependencyTree-debug.json , 整个工程的依赖树\n\t\t4. build/outputs/atlasConfig.json , 整个打包的 atlas 配置参数\n\t2. TPatch构建 **./gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.1**\n\t\n\t\tapVersion表示被动态部署应用的基线版本，versionName表示动态部署后新的versionName\n\n\t\t构建产物：\n\t\t除了依赖树和配置参数之外，额外的产物有：\n\t\t1. build/outputs/tpatch-debug , debug 包 patch产物\n\t\t2. build/outputs/tpatch-release , release 包 patch产物\n\t\n\n### 配置\n\n#### 配置列表\n\n 功能  | 配置名称 |  类型 | 值\n ------------- | ------------- | ------------- | -------------\n是否启用atlas  | mtl.atlasEnabled | boolean  | true\n自动生成bundle的packageId  | mtl.tBuildConfig.autoPackageId | boolean  | true\n预处理manifest， 如果开启atlas，必须为true  | mtl.tBuildConfig.preProcessManifest | Boolean  | true\n使用自定义的aapt， 如果开启atlas，必须为true  | mtl.tBuildConfig.useCustomAapt | Boolean  | true\naapt输出的R为常量, 建议值设置为false， 可以减少动态部署的patch包大小  | mtl.tBuildConfig.aaptConstantId | Boolean  | false\n合并jar中的资源文件  | mtl.tBuildConfig.mergeJavaRes | Boolean  | false\n构建基线包，建议开启，否则后面的patch包无法进行  | mtl.tBuildConfig.createAP | Boolean  | true\n合并bundle jar中的资源文件  | mtl.tBuildConfig.mergeAwbJavaRes | Boolean  | false\n自启动的bundle列表， 值是 packageName  | mtl.tBuildConfig.autoStartBundles | List  | [com.taobao.firstbundle]\n提前执行的方法，格式是 className:methodName|className2:methodName2 ， 注意class和methodname都不能混淆，且方法实现是 class.method(Context)  | mtl.tBuildConfig.preLaunch | String  |\n 基线的依赖坐标， 如： com.taobao.android:taobao-android-release:6.3.0-SNAPSHOT@ap   | mtl.buildTypes.debug.baseApDependency | String  | null\n 基线的依赖坐标， 如： com.taobao.android:taobao-android-release:6.3.0-SNAPSHOT@ap   | mtl.buildTypes.release.baseApDependency | String  | null\n使用atlas的application，包含 atlas基础初始化及multidex逻辑  | mtl.manifestOptions.replaceApplication | boolean  | true\n 打andfix patch 包   | mtl.patchConfigs.debug.createAPatch | boolean  | false\n 打动态部署 patch 包   | mtl.patchConfigs.debug.createTPatch | boolean  | true\n andfix 打包过滤 class 列表文件   | mtl.patchConfigs.debug.filterFile | File  | null\n andfix 打包过滤 class 列表文件   | mtl.patchConfigs.debug.filterClasses | Set  | []\n 打andfix patch 包   | mtl.patchConfigs.release.createAPatch | boolean  | false\n 打动态部署 patch 包   | mtl.patchConfigs.release.createTPatch | boolean  | false\n andfix 打包过滤 class 列表文件   | mtl.patchConfigs.release.filterFile | File  | null\n andfix 打包过滤 class 列表文件   | mtl.patchConfigs.release.filterClasses | Set  | []\n\n\n####  最简配置\n\n    atlas {\n        atlasEnabled true\n    }\n\n\n\n\n具体参考 `atlas-demo/app/build.gradle`\n\n\n## packageIdFile.properties\n每个bundle在生成的时候，需要为其分配独立的packageId，用以使其保证每个bundle的资源ID全局唯一；资源ID的可分配区间为**[0x21,0x7f)**,0x1x为系统保留，0x7f为主apk使用，0x20之前的发现miui里面内部已使用，所以目前我没选择这个区间作为bundle的packageId分配区间\n书写的格式为：**groupId:artificatId=XX**（如下图）\n\n\n## bundleBaseInfoFile.json\nbundleBaseInfoFile 是一个JSON格式的文件，里面记录bundle的信息以及依赖关系，**dependency**字段用于标识该bundle所依赖的bundle，如果A依赖B，B依赖C，则触发的Abundle安装时，实际的安装顺序为C->B->A,**JSONArrary中每个item的key为该bundle的artificatID,dependency里面的item为被依赖的bundle的packageName**\n>\n![MacDown Screenshot](guide_img/bundlebaseinfo.png)\n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/guide_for_bundle.md",
    "content": "## 如何正确使用Bundle\n### bundle的工程配置\n 1. bundle自身工程build.gradle里面需要声明为awb:\n \t\n \t    atlas.bundleConfig.awbBundle = true\n\n 2. 建议修改plugin，更好的支持aar传递依赖等问题（可以采用原生com.android.library）\n \t    \n \t    apply plugin: 'com.taobao.atlas.library'\n \t    buildscript {\n\t\t    repositories {\n\t\t        mavenLocal()\n\t\t        jcenter()\n\t\t    }\n\t\t    dependencies {\n\t\t        classpath \"com.android.tools.build:gradle:2.1\"\n\t\t        classpath \"com.taobao.android:atlasplugin:1.0.0\" //使用com.taobao.atlas.library时需要配置atlasplugin等classpath\n\t\t    }\n\t\t}\n\n3. 外部配置\n\t1. 在主客工程的packageId.properties中声明资源段（也可以通过mtl.tBuildConfig.autoPackageId设置自动分配packageID）\n\t\n\t        com.taobao.android:firstbundle=34//groupId:artifactId=NUM\n\t2. 在主客工程的build.gradle中添加awb依赖\n\n            compile(\"com.taobao.android:firstbundle:1.0.0@awb\")\n\n###  bundle的注意点\n遵循代码规范可以有效避免在运行时遇到难以排查的问题。\n\n1. Bundle的AndroidManifest中不能有对bundle内的资源的引用；比如Activity的Theme，需要声明在主apk中。Bundle的Manifest会合并进主Manifest，如果有bundle的资源引用会直接引发构建出错；另外可以选择的方式是AndroidManifest里面不加Theme，改用在Activity的onCreate方法里面调用setTheme的方式\n2. Activity通过overridePendingTransition使用的切换动画的文件要放在主apk中；\n3. Bundle内的Class最好以特定的packageName开头，resource文件能够带有特定的前缀。这样一来可以避免资源或者类名重复而引起的覆盖，也可以在出现问题的时候及时定位到出问题的模块\n4. Bundle内如果有用到自定义style,那么style的parent如果也是自定义的话，parent的定义必须位于主apk中，这是由于5.0以后系统内style查找的固有逻辑导致的，容器内暂不能完全兼容\n5. Bundle内部如果有so，则安装时so由于无法解压到apk lib目录中，对于直接通过native层使用dlopen来使用so的情况，会存在一定限制，且会影响后续so动态部署，所以目前bundle内so不建议使用dlopen的方式来使用\n \n6. Bundle内有使用主进程的contentProvider,则Bundle的AndroidManifest的contentprovider声明中最好带上\n\n```\n\tandroid:multiprocess=\"true\"\n\tandroid:process=\":XX\"\n```\n这样可以避免主进程一起来就去startBundle导致启动时间过长\n\n### 初始化Bundle\nbundle可以被认为是一个小型的apk，因此每个bundle的初始化都是从Bundle的Application开始的。Application被声明在bundle的AndroidManifest.xml里面\n\n**注意点：**虽然启动方式类似与普通app，先执行attachBaseContext，再执行onCreate，不过有两个不同点需要引起注意：\n\n1. Application 初始化的线程基于start bundle时的线程，这样导致了bundle可能会运行在主线程，也可能是在子线程，所以初始化的代码如果对线程敏感的需要注意：如果需要强制主线程的可以通过new Handler(Looper.getMainLooper()).post 去初始化\n\n2. bundle的Application并不是被系统真正认可的Application，所以需要Application作为参数进行初始化的方法可以传入getBaseContext()，Bundle Application的mBase实际上就是apk真正的application，最好不要直接传入bundle的Application本身进行初始化，会存在潜在的风险。\n\n### Bundle如何提供服务给其他Bundle\n**Bundle虽然提供了依赖的方式，但是这种方式如果使用不当反而会带来隐患，且与bundle本身的封装性相违背。**通常如果某个中间件是以bundle的形式存在，那声明依赖是可行的。如果两个本身相对独立的业务bundle存在某几个功能接口的依赖，则可以通过服务的方式，服务提供方提供aidl的接口，被使用方或者主apk依赖；同时自己bundle内部实现service的功能。\n\n### 主动启动Bundle\n默认情况下，Bundle只往外暴露了android原生的component,运行期按需加载。某些特殊的bundle（比如说监控性质的）本身与其他代码完全独立，且又需要在某个时间点启动运行的，可以通过如下方式去启动：\n加上Bundle的PackageName为：com.sample.bundleA\n\n```\n\n        Atlas.getInstance().installBundleTransitivelyAsync(\n        new String[]{\"com.sample.bundleA\"}, \n                new BundleInstaller.InstallListener() {\n            @Override\n            public void onFinished() {\n                BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(\"com.sample.bundleA\");\n                if(impl!=null){\n                    try {\n                        impl.start();\n                    } catch (BundleException e) {\n                        e.printStackTrace();\n                    }\n                }\n            }\n        });\n        \n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/guide_for_compile.md",
    "content": "###待更新"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/index.html",
    "content": "\n<!DOCTYPE HTML>\n<html lang=\"\" >\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n        <title>Introduction · GitBook</title>\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta name=\"description\" content=\"\">\n        <meta name=\"generator\" content=\"GitBook 3.2.2\">\n        \n        \n        \n    \n    <link rel=\"stylesheet\" href=\"gitbook/style.css\">\n\n    \n            \n                \n                <link rel=\"stylesheet\" href=\"gitbook/gitbook-plugin-highlight/website.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"gitbook/gitbook-plugin-search/search.css\">\n                \n            \n                \n                <link rel=\"stylesheet\" href=\"gitbook/gitbook-plugin-fontsettings/website.css\">\n                \n            \n        \n\n    \n\n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n        \n    \n\n        \n    \n    \n    <meta name=\"HandheldFriendly\" content=\"true\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n    <link rel=\"apple-touch-icon-precomposed\" sizes=\"152x152\" href=\"gitbook/images/apple-touch-icon-precomposed-152.png\">\n    <link rel=\"shortcut icon\" href=\"gitbook/images/favicon.ico\" type=\"image/x-icon\">\n\n    \n    \n\n    </head>\n    <body>\n        \n<div class=\"book\">\n    <div class=\"book-summary\">\n        \n            \n<div id=\"book-search-input\" role=\"search\">\n    <input type=\"text\" placeholder=\"Type to search\" />\n</div>\n\n            \n                <nav role=\"navigation\">\n                \n\n\n<ul class=\"summary\">\n    \n    \n\n    \n\n    \n        \n        \n    \n        <li class=\"chapter active\" data-level=\"1.1\" data-path=\"./\">\n            \n                <a href=\"./\">\n            \n                    \n                    Introduction\n            \n                </a>\n            \n\n            \n        </li>\n    \n\n    \n\n    <li class=\"divider\"></li>\n\n    <li>\n        <a href=\"https://www.gitbook.com\" target=\"blank\" class=\"gitbook-link\">\n            Published with GitBook\n        </a>\n    </li>\n</ul>\n\n\n                </nav>\n            \n        \n    </div>\n\n    <div class=\"book-body\">\n        \n            <div class=\"body-inner\">\n                \n                    \n\n<div class=\"book-header\" role=\"navigation\">\n    \n\n    <!-- Title -->\n    <h1>\n        <i class=\"fa fa-circle-o-notch fa-spin\"></i>\n        <a href=\".\" >Introduction</a>\n    </h1>\n</div>\n\n\n\n\n                    <div class=\"page-wrapper\" tabindex=\"-1\" role=\"main\">\n                        <div class=\"page-inner\">\n                            \n<div id=\"book-search-results\">\n    <div class=\"search-noresults\">\n    \n                                <section class=\"normal markdown-section\">\n                                \n                                <h1 id=\"&#x63A5;&#x5165;&#x6307;&#x5F15;\">&#x63A5;&#x5165;&#x6307;&#x5F15;</h1>\n<p>&#x8BF7;&#x63A5;&#x5165;&#x524D;&#x4ED4;&#x7EC6;&#x9605;&#x8BFB;&#x63A5;&#x5165;&#x6587;&#x6863;.</p>\n<p>&#x63A5;&#x5165;&#x53EF;&#x53C2;&#x8003;<a href=\"https://github.com/alibaba/atlas/tree/master/atlas-demo\" target=\"_blank\">atlas-demo</a></p>\n\n                                \n                                </section>\n                            \n    </div>\n    <div class=\"search-results\">\n        <div class=\"has-results\">\n            \n            <h1 class=\"search-results-title\"><span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"</h1>\n            <ul class=\"search-results-list\"></ul>\n            \n        </div>\n        <div class=\"no-results\">\n            \n            <h1 class=\"search-results-title\">No results matching \"<span class='search-query'></span>\"</h1>\n            \n        </div>\n    </div>\n</div>\n\n                        </div>\n                    </div>\n                \n            </div>\n\n            \n                \n                \n            \n        \n    </div>\n\n    <script>\n        var gitbook = gitbook || [];\n        gitbook.push(function() {\n            gitbook.page.hasChanged({\"page\":{\"title\":\"Introduction\",\"level\":\"1.1\",\"depth\":1,\"dir\":\"ltr\"},\"config\":{\"gitbook\":\"*\",\"theme\":\"default\",\"variables\":{},\"plugins\":[\"livereload\"],\"pluginsConfig\":{\"livereload\":{},\"highlight\":{},\"search\":{},\"lunr\":{\"maxIndexSize\":1000000,\"ignoreSpecialCharacters\":false},\"sharing\":{\"facebook\":true,\"twitter\":true,\"google\":false,\"weibo\":false,\"instapaper\":false,\"vk\":false,\"all\":[\"facebook\",\"google\",\"twitter\",\"weibo\",\"instapaper\"]},\"fontsettings\":{\"theme\":\"white\",\"family\":\"sans\",\"size\":2},\"theme-default\":{\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"},\"showLevel\":false}},\"structure\":{\"langs\":\"LANGS.md\",\"readme\":\"README.md\",\"glossary\":\"GLOSSARY.md\",\"summary\":\"SUMMARY.md\"},\"pdf\":{\"pageNumbers\":true,\"fontSize\":12,\"fontFamily\":\"Arial\",\"paperSize\":\"a4\",\"chapterMark\":\"pagebreak\",\"pageBreaksBefore\":\"/\",\"margin\":{\"right\":62,\"left\":62,\"top\":56,\"bottom\":56}},\"styles\":{\"website\":\"styles/website.css\",\"pdf\":\"styles/pdf.css\",\"epub\":\"styles/epub.css\",\"mobi\":\"styles/mobi.css\",\"ebook\":\"styles/ebook.css\",\"print\":\"styles/print.css\"}},\"file\":{\"path\":\"README.md\",\"mtime\":\"2017-09-12T02:32:41.000Z\",\"type\":\"markdown\"},\"gitbook\":{\"version\":\"3.2.2\",\"time\":\"2017-11-27T10:03:07.426Z\"},\"basePath\":\".\",\"book\":{\"language\":\"\"}});\n        });\n    </script>\n</div>\n\n        \n    <script src=\"gitbook/gitbook.js\"></script>\n    <script src=\"gitbook/theme.js\"></script>\n    \n        \n        <script src=\"gitbook/gitbook-plugin-livereload/plugin.js\"></script>\n        \n    \n        \n        <script src=\"gitbook/gitbook-plugin-search/search-engine.js\"></script>\n        \n    \n        \n        <script src=\"gitbook/gitbook-plugin-search/search.js\"></script>\n        \n    \n        \n        <script src=\"gitbook/gitbook-plugin-lunr/lunr.min.js\"></script>\n        \n    \n        \n        <script src=\"gitbook/gitbook-plugin-lunr/search-lunr.js\"></script>\n        \n    \n        \n        <script src=\"gitbook/gitbook-plugin-sharing/buttons.js\"></script>\n        \n    \n        \n        <script src=\"gitbook/gitbook-plugin-fontsettings/fontsettings.js\"></script>\n        \n    \n\n    </body>\n</html>\n\n"
  },
  {
    "path": "atlas-docs/guide-for-use/_book/search_index.json",
    "content": "{\"index\":{\"version\":\"0.5.12\",\"fields\":[{\"name\":\"title\",\"boost\":10},{\"name\":\"keywords\",\"boost\":15},{\"name\":\"body\",\"boost\":1}],\"ref\":\"url\",\"documentStore\":{\"store\":{\"./\":[\"demo\",\"introduct\",\"接入可参考atla\",\"接入指引\",\"请接入前仔细阅读接入文档.\"]},\"length\":1},\"tokenStore\":{\"root\":{\"docs\":{},\"d\":{\"docs\":{},\"e\":{\"docs\":{},\"m\":{\"docs\":{},\"o\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.25}}}}}},\"i\":{\"docs\":{},\"n\":{\"docs\":{},\"t\":{\"docs\":{},\"r\":{\"docs\":{},\"o\":{\"docs\":{},\"d\":{\"docs\":{},\"u\":{\"docs\":{},\"c\":{\"docs\":{},\"t\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":10}}}}}}}}}}},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"可\":{\"docs\":{},\"参\":{\"docs\":{},\"考\":{\"docs\":{},\"a\":{\"docs\":{},\"t\":{\"docs\":{},\"l\":{\"docs\":{},\"a\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.25}}}}}}}}},\"指\":{\"docs\":{},\"引\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.25}}}}}},\"请\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"前\":{\"docs\":{},\"仔\":{\"docs\":{},\"细\":{\"docs\":{},\"阅\":{\"docs\":{},\"读\":{\"docs\":{},\"接\":{\"docs\":{},\"入\":{\"docs\":{},\"文\":{\"docs\":{},\"档\":{\"docs\":{},\".\":{\"docs\":{\"./\":{\"ref\":\"./\",\"tf\":0.25}}}}}}}}}}}}}}}},\"length\":5},\"corpusTokens\":[\"demo\",\"introduct\",\"接入可参考atla\",\"接入指引\",\"请接入前仔细阅读接入文档.\"],\"pipeline\":[\"stopWordFilter\",\"stemmer\"]},\"store\":{\"./\":{\"url\":\"./\",\"title\":\"Introduction\",\"keywords\":\"\",\"body\":\"接入指引\\n请接入前仔细阅读接入文档.\\n接入可参考atlas-demo\\n\"}}}"
  },
  {
    "path": "atlas-docs/guide-for-use/bundleCommunicate.md",
    "content": "# Android跨ClassLoader的模块之间互相通信的几种方式\n\n## 现状\nAtlas作为java层以OSGI规范进行组件化解耦的容器。在一定层度上清晰了各个模块之间的边界，便于各个业务以内聚的方式不断的演化更新。\n\n但是在复杂的App比如手淘这种无数个业务交织的场景下，完全的隔离也给业务的开发造成了不小的成本。针对这种问题，目前主要解决的方案有：\n\n1. 参照多个App之间通信的方式，使用AIDL可以作为组件之间进行一定层度通信的方式。\n2. 使用基于容器的实现开发的ServiceHub，跟AIDL一样将接口放到公共Library，然后ServiceHub中写入接口和实现的对应关系。使用方通过ServiceHub得到接口实现进行使用。\n\n## 缺陷\nAIDL、ServiceHub解决了部分bundle之间通信或者代码复用的问题。但是这两者也存在着很大的不足。一方面AIDL限制了只能传递parcel以及简单对象，对于UI复用比如说Richview的重用则完全行不通，同时使用成本也是ServiceHub的机制的一个痛点，业务方需要提前将新的接口提前注册到ServiceHub。\n## 新的机制\n新的组件之间的重用及通信策略延续了AIDL免注册的方式，同时解决了跨classloader情况下UI复用的问题。新的方式将重用类型归为RemoteFragment、RemoteView、RemoteTransaction三种类型。\n\n### RemoteFragment\nRemoteFragment适用于某个Bundle中有公共的Fragment要提供给一个或者多个其他业务bundle使用的情况，比如说在手淘里面，SkuFragment(sku选择界面)可能会提供给详情，购物车，聚划算等多个业务使用；或者在某些App里面，登录界面也以LoginFragment的方式提供给Bundle按需使用。\n\n1. 使用方式\n 1. 代码改动：以LoginFragment为例，LoginBundle需要在自己的LoginFragment做一定的改动\n\t  \t  \n\t ```\n\t public class LoginFragment extends Fragment implements IRemote{\n\n\n\t\t    @Override\n\t\t    public Bundle call(String commandName, Bundle args, IResponse callback) {\n\t\t        return null;\n\t\t    }\n\t\t\n\t\t    @Override\n\t\t    public <T> T getRemoteInterface(Class<T> interfaceClass,Bundle args) {\n\t\t        return null;\n\t\t    }\n}\n```\n\t\n\t\tLoginFragment 需要在原来的基础上实现IRemote接口，IRemote来自Atlas容器的内部实现，暂时还未从容器中拆分出差，这也意味着业务方需要增加对atlas的依赖。**IRemote实现的两个接口会在文章后面解释**\n\n\n \n   \t2. Bundle的AndroidManifest.xml中进行注册\n   \t\n   \t\t```\n   \t\t<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    \tpackage=\"com.taobao.login\">\n\t\t\t<application>\n\t       \t\t<meta-data android:name=\"atlas.fragment.intent.action.LOGIN\"\n\t       \t\t \tandroid:value=\"com.taobao.login.LoginFragment\" />\n\t\t\t</application>\n\t\t</manifest>\n   \t\t```\n\tRemote组件参照AIDL的方式在manifest中进行注册。查找时以meta-data的name做key进行查找，RemoteFragment的key必须以**atlas.fragment.intent.action.**开头。\n\n\t3. 使用方如何调用RemoteFragment\n\t\t\n\t\t```\n\t\tpublic class SampleActivity extends FragmentActivity{\n\t\t\tpublic void doLogin(){\n\t\t        Intent loginIntent = new Intent(\"atlas.fragment.intent.action.LOGIN\");\n\t\t        RemoteFactory.requestRemote(RemoteFragment.class,loginIntent, \n\t\t        \tnew RemoteFactory.OnRemoteStateListener<RemoteFragment>() {\n\t\t            @Override\n\t\t            public void onRemotePrepared(RemoteFragment fragment) {\n\t\t                getSupportFragmentManager().beginTransaction().add(R.id.container,fragment).commit();\n\t\t            }\n\t\t\t\t\t@Override\n\t\t            public void onFailed(String errorInfo) {\n\t\t                // Redirect to h5 login or downgrade\n\t\t            }\n\t\t        });\n\t\t    }\n}\n\t\t```\n\t\t业务使用方调用Atlas的RemoteFactory的接口进行request，由于期间可能涉及到bundle的安装，所以整个过程采用callback的方式。获取到RemoteFragment的句柄后直接进行操作即可。**建议Fragment里面涉及到的交互功能等的代码封装在Fragment内部**，比如说LoginFragment里面所有按钮的点击以及异常处理全都Fragment内部进行实现。这样的话两个Bundle之间的边界也更清晰。\n> 问题：RemoteFragment 如何通知外部登录成功或者失败，除了用系统的广播等机制，能否基于Remote的机制更直接地方便地实现该功能呢？后续RemoteTransaction中会阐述具体的用法。\n\n2. 实现的机制\n\t先附一张网上摘录的Fragment启动图，不清楚的同学可以通过这个大致了解整个Fragment启动的一些方法调用，理清Fragment和Activity在启动时的一些交织的关系(图片可能需要下载放大了观看)。\n\t![](fragment-start.png)\n\tRemoteFragment本身也是真正意义上的Fragment，所以可以用来直接被FragmentManager或者FragmentTransaction直接进行管理；同时它也是真正的LoginFragment的在使用方的代理。他们之间的关系如下：\n\t\t![](fragment-relation.png)\n\t使用者应该了解RemoteFragment机制的以下几个特点，明白其内部实现的主要机制：\n\t\t\n\t* RemoteFragment的使用方拿到的仅仅是目标fragment的代理，所以真正的实现对使用方来说是不可见的。如果除了拿到Fragment展示之外还有其他的接口需要暴露给使用者，则需要走**Remote的通信机制**。\n\t* EmbeddActivity才是真正目标Fragment实例化所需要的context，EmbeddActivity是由RemoteFragment初始化时创建的Activity，用于给目标Fragment初始化UI，它是真正的Activity，但是没有界面，同时也没有有效的WindowManager，涉及到Window操作的会自动转交给SampleActivity进行处理。EmbeddActivity是bundle之间不需要依赖直接使用UI最根本的保证。\n\t\n\t  >设想一下，如果一个Activity引用了5个来自不同Bundle的RemoteFragment，那么相当于这个Activity内嵌了5个EmbeddActivity；那如果引用了5个来自同一个Bundle的RemoteFragment呢？\n\t\n\t* 目标Fragment与SampleActivity之间还是保持完整的隔离，所以目标Fragment也无法获取宿主的引用，所以如果目标Fragment需要与SampleActivity发生通信，则也要遵循**Remote的通信机制**\n\t\n\t\n### RemoteView\n与RemoteFragment 类似，RemoteView提供更细粒度的bundle间的UI复用。\n\n1. 使用方式\n\t1. 代码改动\n\t\n\t\t```\n\t\tpublic class SampleRichView extends FrameLayout implements IRemote{\n\t\t\t@Override\n\t\t    public Bundle call(String commandName, Bundle args, IResponse callback) {\n\t\t        return null;\n\t\t    }\n\t\t\t@Override\n\t\t    public <T> T getRemoteInterface(Class<T> interfaceClass,Bundle args) {\n\t\t        return null;\n\t\t    }\n}\n\t\t```\n\t2. AndroidManifest修改，RemoteView的key以**atlas.view.intent.action.**开头\n\n\t\t```\n   \t\t<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\t\t\t\tpackage=\"com.taobao.sample\">\n\t\t\t<application>\n\t       \t\t<meta-data android:name=\"atlas.fragment.intent.action.SAMPLE_RICH\"\n\t       \t\t \tandroid:value=\"com.taobao.sample.SampleRichView\" />\n\t\t\t</application>\n\t\t</manifest>\n   \t\t```\n   \t3. 使用方如何调用RemoteView\n   \t\t\n   \t\t```\n\t\tpublic class SampleActivity extends Activity{\n\t\t\tpublic void inflateRemoteView(FrameLayout container){\n\t\t        Intent sIntent = new Intent(\"atlas.view.intent.action.SAMPLE_RICH\");\n\t\t        RemoteFactory.requestRemote(RemoteView.class, sIntent, \n\t\t        \tnew RemoteFactory.OnRemoteStateListener<RemoteView>() {\n\t\t            @Override\n\t\t            public void onRemotePrepared(RemoteView remoteView) {\n\t\t                ViewGroup.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);\n\t\t                container.addView(remoteView,params);\n\t\t            }\n\t\t\t\t\t@Override\n\t\t            public void onFailed(String errorInfo) {\n\t\t                // downgrade\n\t\t            }\n\t\t        });\n\t\t    }\n}\n\t\t```\n2. 实现机制\n\n\tRemoteView与RemoteFragment实现基本一致，需要EmbeddedActivity作为真正View膨化的基本条件，RemoteView本身只是一个FrameLayout，就像DecorView，目标View作为子View添加在里面。当然这个机制也有一定的隐患，**使用方不要通过findViewByID或者getChildAt等viewGroup的public 方法尝试获取目标view并进行操作，RemoteView应该被当做View而不是ViewGroup，与目标View的通信应该通过Remote的机制进行**\n\t\n###RemoteTransact\nRemoteTransact相当于是RemoteView或者RemoteFragment的简化版，仅仅为了bundle和bundle之间的通信而存在，它和RemoteView，RemoteFragment都实现了IRemoteTransact接口。可以通过下面的草图了解大致的关系：\n![](class-relation.png)\n以RemoteTransactor为例，他和目标Transactor类都实现了IRemoteTransactor，所以当使用方调用IRemoteTransactor的接口时候，Remote对象将方法路由到目标对象的方法上。\n\n使用者可以通过这两个方法与真正的远端对象进行通信：\n\n```\npublic Bundle call(String commandName, Bundle args, IResponse callback)\n```\n* 以命令的方式通知目标对象，如果是异步返回，则远端通过传入的callback接口进行回调，如果不是，则直接返回，适用于使用方和远端存在简单通信的情况。\n\n```\npublic <T> T getRemoteInterface(Class<T> interfaceClass,Bundle args)\n```\n* 远端本身已经有封装过具体的接口，则可以实现getRemoteInterface返回具体的接口的实现。这种方式类似之前的AIDL的方式，前提是interface 类需要在两个bundle均可访问的主apk或者公共bundle中。\n\n这种使用方式适用于本身具有特定接口定义的SDK中，比如在手淘里面的windvane和weex。\n\n以windvane为例（sample里面windvane的接口只做范例，与真实的使用接口可能存在差异）：存在很多Bundle需要提供JSPlugin的场景。原生的Windvane需要提前注册JSPlugin，这种方式对bundle而言开销较大。需要bundle提前启动注册以避免后期运行时无法找到js函数对应的native方法。\n假设在Remote机制下则Windvane针对非内部的common native方法有一个ExternalJSMethodExecuter，当需要执行非内部的js方法时，则可以通过externalJSMethodExecuter.execute()查找外部的method。（这种也适用于Weex等SDK在非常规的Apk内由外部实现定制的适配器）\n\n假设bundle A有若干个native方法，需要提供给JS使用，则可以写成\n\n```\npublic class MyJSPluginManager implements IRemote{\n    @Override\n    public Bundle call(String commandName, Bundle args, IResponse callback) {\n        return null;\n    }\n\n    @Override\n    public <T> T getRemoteInterface(Class<T> interfaceClass,Bundle args) {\n        if(interfaceClass == WVApiPlugin.class){\n            if(args.getString(\"js_method\").equals(\"funA\")){\n                return new FunAPlugin();\n            }else if(args.getString(\"js_method\").equals(funB)){\n                return new FunBPlugin();\n            }else{\n                //unknow error\n            }\n        }\n        return null;\n    }\n}\n```\n同时在Manifest中增加如下配置：\n\n```\n<meta-data android:name=\"atlas.transaction.intent.action.funA\" android:value=\"com.taobao.sample.MyJSPluginManager\" />\n<meta-data android:name=\"atlas.transaction.intent.action.funB\" android:value=\"com.taobao.sample.MyJSPluginManager\" />\n```\n对于JS方法的调用方，则通过如下方法实现：\n\n```\n    public void execute(Activity activity, final String jsMethodName){\n        RemoteFactory.requestRemote(RemoteTransactor.class,activity,new Intent(jsMethodName),new RemoteFactory.OnRemoteStateListener<RemoteTransactor>() {\n            @Override\n            public void onRemotePrepared(RemoteTransactor remote) {\n                Bundle b = new Bundle();\n                b.putString(\"js_method\",jsMethodName);\n                WVApiPlugin plugin  = remote.getRemoteInterface(WVApiPlugin.class,b);\n                if(plugin!=null){\n                    //方法仅供示例，与实际情况可能存在差异\n                    plugin.execute(jsMethodName,...);\n                }\n            }\n            @Override\n            public void onFailed(String errorInfo) {\n\n            }\n        });\n    }\n```\n> 这里requestRemote里面直接传入RemoteTransactor可能对开发者来说还有点晦涩，SDK开发者也可以尝试直接对RemoteTransactor以及IRemote进行封装，比如改造成更为直观的BaseJSManager和BaseJSPlugin\n\n同样的，其他的SDK（比如weex）也可以通过类似方案在多classloader的APK内部实现自己定制的适配器，规避所有的接口实现需要预先注册的情况，同时也对整体应用的性能带来帮助。\n\n###远端如何主动调用使用方的接口\n我们也存在被使用方在某些场景下需要主动调用或者按规律定期callback宿主的情况，一种方式是使用宿主掉用远端时传进来的IResponse接口多次回调，但是如果涉及到复杂的情况就需要用到下面的方法：\n\n宿主本身对于被调用方来说也是一个远端的对象，所以宿主自己可以使用IRemote，同时将自己注册给Remote对象，RemoteFragment、RemoteView、RemoteTransactor的基类IRemoteContext实现了提供了registerHostTransactor接口，在RemoteFactory回调时将自身的IRemote实现注册进去\n\n```\n    void registerHostTransactor(IRemote transactor);\n```\n那么在远端需要使用的时候，则可以通过HostTransactor（前面图中未标出）得到宿主的IRemote的实现并传递相应的信息。\n\n```\n\tpublic static HostTransactor get(IRemote remoteItem)\n```\n\n###Remote机制的特点和不足\nRemote机制本身强烈依托于组件化拆分的方案。它的解耦层度介于AIDL和直接依赖之间。相比AIDL灵活层度更高。不过代理的方式并不能完全杜绝通过非常规方法来获取远端目标对象来进行使用，另外也可能存在某些边缘方法无非被完全代理的情况，这也需要在以后的迭代中进行优化，对于非Atlas容器化但是使用了组件化拆解方案的App，这种思路也是同样适用的。\n\n## 现在还可以选择的bundle间代码复用的方案\n对于AIDL、serviceHub以及Remote的机制，可能还存在临时无法按照规范进行解耦的情况。目前除了静态依赖外，也可以考虑使用动态依赖的方式,用来解决在具体使用到某个功能时候再去挂载相应的依赖模块，不过**bundle依赖始终打破了bundle之间的边界，需要谨慎使用**\n\n```\n    /**\n     * 设置bundle运行时依赖\n     * @param source  需要添加依赖的bundle\n     * @param dependencyBundle 被依赖的bundle的packagename\n     * @param resourceDependencyNeed 是否需要使用被依赖bundle的资源\n     * @throws BundleException\n     */\n    public void requestRuntimeDependency(ClassLoader source,String dependencyBundle,boolean resourceDependencyNeed) throws BundleException{\n```\n\n\n##其他：由于native so的相互调用导致的bundle依赖\nNative Library 在多classloader运行机制下，需要事先了解几个要点：\n\n1. 定义同一个So的依据是全路径完全相同且so内容相同\n2. 调用LoadLibrary(或者load)在native真正dlopen library之前java层会先findLibrary，如果是系统库，则在系统环境变量里面包含的路径内，如果是外部引入的，则通过ClassLoader.findLibrary进行查找，BundleClassLoader的查找逻辑是先找自身bundle安装目录下的，找不到接着找依赖bundle内的，最后去找主dex也就是PatchClassLoader的findLibrary去查找。\n\n\t如果是直接使用dlopen bundle内的so，则需要传入so的全路径（比如说通过java层获取），否则可能出现so 找不到。\n\n3. native so load时与load该so的类所在的classloader存在绑定关系，如果存在native反调java层代码的情况，则只能调用到够找到该classloader可以找到的java类的方法\n4. 在android 7.0版本之前native so load同一个进程空间下只可load一次，如果同一个classloder第二次去load则直接返回成功，如果不同的classloader去load则会失败；android 7.0以后ClassLoader通过namespace各自独立，不同的ClassLoader可以去load同一个so，分别会在各自的namespace有各自的mmap，可以通过/proc/pid/maps 查看各自的map信息\n\n### native特殊使用情况及建议 \n1. 由于不同bundle的java代码使用相同的So导致的依赖：\n\n\t建议把调用相关的调用So的代码和So本身单独封装成一个公共的模块，否则如果存在So反调java的情况，则只能调用到loadLibrary的ClassLoader范围内的java类的代码\n\t\n2. 由于native so依赖或者dlopen公共native So的情况：\n\t使用方案：\n\t\n\t1. 公共so下层到公共模块，同时提前load（规避7.0版本开始区分namespace隔离的情况），bundle的so使用的时候不能使用官方的dlopen接口，需要根据mapping查找已load so的导出函数进行使用,规避因为namespace不一致导致多份mmap的情况。 \n\t         \n\t\n\n \n\n\t"
  },
  {
    "path": "atlas-docs/guide-for-use/guide_for_build.md",
    "content": "    # 主工程容器接入\nAtlas开源的代码内容主要包括以下几个模块：\n\n1. 基于gradle的构建插件（包括修改过的aapt内容）；\n2.\tandroid端测容器运行库atlas_core；\n3. 基于容器提供更新能力的库atlas_update;\n\n我们比较倾向于用一个比较干净的壳子工程来作为容器架构下的打包工程，这个工程建议只存在AndroidManifest.xml和构建的文件及部分资源内容，manifest文件用于单独管理apk的icon，版本号，versioncode等；构建文件管理版本依赖；这里我们取名打包工程等名字为apk_builder;\n通常情况下Apk_builder除了主Apk的AndroidManifest.xml之外，接入Atlas后，Main_builder将会包含以下内容：\n\n1. **build.gradle** : 用于配置主apk的依赖及控制构建参数\n2. **packageIdFile.properties**: 配置bundle的packageId,以保证资源段独立（也可以通过mtl.tBuildConfig.autoPackageId设置自动分配packageID）\n3. **bundleBaseInfoFile.json**: 配置bundle的依赖关系\n\n下面会逐个说明每个文件的使用和注意要点\n\n## build.gradle(AtlasGradlePlugin)\n支持 atlas 工程打包的gradle 插件， 基于 google 官方的 android builder （2.0.0~2.1.0）\n\n\n1. 引用插件及依赖仓库\n\n\t\tbuildscript {\n\t\t    repositories {\n\t\t        mavenLocal()\n\t\t        jcenter()\n\t\t    }\n\t\t    dependencies {\n\t\t        classpath \"com.taobao.android:atlasplugin:1.0.1\"\n\t\t    }\n\t\t}\n\t\trepositories {\n    \t\tjcenter()\n\t\t}\n\t\t\n\t注意尽量不要指定 classpath \"com.android.tools.build:gradle\"的版本，默认使用的是 2.1\n\n2. 应用plugin\n\n\t\tapply plugin: 'com.taobao.atlas.application'\n\t\t//注意不能同时 apply com.android.application\n\n3. 添加运行库依赖\t\n\t    \n\t    dependencies {\n       \tcompile('com.taobao.android:atlas_core:5.0.0@aar') {\n        \ttransitive = true\n    \t}\n        compile 'com.taobao.android:atlasupdate:1.0.8@aar'\n        \n\t**如果不需要用到atlas的动态部署功能，不需要依赖atlasupdate**    \n\t\n4. 开启atlas容器功能\n    \n         atlas {\n         \tatlasEnabled true\n    \t   tBuildConfig {\n        \t\tautoStartBundles =['com.taobao.firstbundle'] //自启动bundle配置\n\t\t\t}\n\n         \tpatchConfigs{\n        \t\tdebug {\n            \tcreateTPatch true\n        \t\t}\n  \t\t  \t}\n       \t\t buildTypes {\n        \t\tdebug {\n            \t\tif (apVersion){\n          \t\t  \t\tbaseApDependency  \"com.taobao.android.atlasdemo:AP-debug:${apVersion}@ap\"\n            \t\t\tpatchConfig    patchConfigs.debug\n            \t\t\t}\n        \t\t\t}\n\t \t\t\t}\n  \t\t  }   \n\n\t**atlasEnable字段需要指定为true才能开启打包阶段的基于容器扩展的task**    \n\t\n   **后续两个设置用语动态部署打包时的开关设置，其余字段参考配置列表中的使用方式**\n\n\n5. 构建\n\t1. APK构建 **./gradlew assembleDebug 或者 assembleRelease**\n\t\n    \t构建产物：\n\n\t\t1. build/outputs/apk/xx.apk , 构建的产物apk   \n\t\t2. build/outputs/apk/xx.ap , 构建的基线包， 里面包含 apk 和其他的打包中间配置\n\t\t3. build/outputs/dependencyTree-debug.json , 整个工程的依赖树\n\t\t4. build/outputs/atlasConfig.json , 整个打包的 atlas 配置参数\n\t2. TPatch构建 **./gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.1**\n\t\n\t\tapVersion表示被动态部署应用的基线版本，versionName表示动态部署后新的versionName\n\n\t\t构建产物：\n\t\t除了依赖树和配置参数之外，额外的产物有：\n\t\t1. build/outputs/tpatch-debug , debug 包 patch产物\n\t\t2. build/outputs/tpatch-release , release 包 patch产物\n\t\n\n### 配置\n\n#### 配置列表\n\n 功能  | 配置名称 |  类型 | 值\n ------------- | ------------- | ------------- | -------------\n是否启用atlas  | mtl.atlasEnabled | boolean  | true\n自动生成bundle的packageId  | mtl.tBuildConfig.autoPackageId | boolean  | true\n预处理manifest， 如果开启atlas，必须为true  | mtl.tBuildConfig.preProcessManifest | Boolean  | true\n使用自定义的aapt， 如果开启atlas，必须为true  | mtl.tBuildConfig.useCustomAapt | Boolean  | true\naapt输出的R为常量, 建议值设置为false， 可以减少动态部署的patch包大小  | mtl.tBuildConfig.aaptConstantId | Boolean  | false\n合并jar中的资源文件  | mtl.tBuildConfig.mergeJavaRes | Boolean  | false\n构建基线包，建议开启，否则后面的patch包无法进行  | mtl.tBuildConfig.createAP | Boolean  | true\n合并bundle jar中的资源文件  | mtl.tBuildConfig.mergeAwbJavaRes | Boolean  | false\n自启动的bundle列表， 值是 packageName  | mtl.tBuildConfig.autoStartBundles | List  | [com.taobao.firstbundle]\n提前执行的方法，格式是 className:methodName|className2:methodName2 ， 注意class和methodname都不能混淆，且方法实现是 class.method(Context)  | mtl.tBuildConfig.preLaunch | String  |\n 基线的依赖坐标， 如： com.taobao.android:taobao-android-release:6.3.0-SNAPSHOT@ap   | mtl.buildTypes.debug.baseApDependency | String  | null\n 基线的依赖坐标， 如： com.taobao.android:taobao-android-release:6.3.0-SNAPSHOT@ap   | mtl.buildTypes.release.baseApDependency | String  | null\n使用atlas的application，包含 atlas基础初始化及multidex逻辑  | mtl.manifestOptions.replaceApplication | boolean  | true\n 打andfix patch 包   | mtl.patchConfigs.debug.createAPatch | boolean  | false\n 打动态部署 patch 包   | mtl.patchConfigs.debug.createTPatch | boolean  | true\n andfix 打包过滤 class 列表文件   | mtl.patchConfigs.debug.filterFile | File  | null\n andfix 打包过滤 class 列表文件   | mtl.patchConfigs.debug.filterClasses | Set  | []\n 打andfix patch 包   | mtl.patchConfigs.release.createAPatch | boolean  | false\n 打动态部署 patch 包   | mtl.patchConfigs.release.createTPatch | boolean  | false\n andfix 打包过滤 class 列表文件   | mtl.patchConfigs.release.filterFile | File  | null\n andfix 打包过滤 class 列表文件   | mtl.patchConfigs.release.filterClasses | Set  | []\n\n\n####  最简配置\n\n    atlas {\n        atlasEnabled true\n    }\n\n\n\n\n具体参考 `atlas-demo/app/build.gradle`\n\n\n## packageIdFile.properties\n每个bundle在生成的时候，需要为其分配独立的packageId，用以使其保证每个bundle的资源ID全局唯一；资源ID的可分配区间为**[0x21,0x7f)**,0x1x为系统保留，0x7f为主apk使用，0x20之前的发现miui里面内部已使用，所以目前我没选择这个区间作为bundle的packageId分配区间\n书写的格式为：**groupId:artificatId=XX**（如下图）\n\n\n## bundleBaseInfoFile.json\nbundleBaseInfoFile 是一个JSON格式的文件，里面记录bundle的信息以及依赖关系，**dependency**字段用于标识该bundle所依赖的bundle，如果A依赖B，B依赖C，则触发的Abundle安装时，实际的安装顺序为C->B->A,**JSONArrary中每个item的key为该bundle的artificatID,dependency里面的item为被依赖的bundle的packageName**\n>\n![MacDown Screenshot](guide_img/bundlebaseinfo.png)\n"
  },
  {
    "path": "atlas-docs/guide-for-use/guide_for_bundle.md",
    "content": "## 如何正确使用Bundle\n### bundle的工程配置\n 1. bundle自身工程build.gradle里面需要声明为awb:\n \t\n \t    atlas.bundleConfig.awbBundle = true\n\n 2. 建议修改plugin，更好的支持aar传递依赖等问题（可以采用原生com.android.library）\n \t    \n \t    apply plugin: 'com.taobao.atlas.library'\n \t    buildscript {\n\t\t    repositories {\n\t\t        mavenLocal()\n\t\t        jcenter()\n\t\t    }\n\t\t    dependencies {\n\t\t        classpath \"com.android.tools.build:gradle:2.1\"\n\t\t        classpath \"com.taobao.android:atlasplugin:1.0.0\" //使用com.taobao.atlas.library时需要配置atlasplugin等classpath\n\t\t    }\n\t\t}\n\n3. 外部配置\n\t1. 在主客工程的packageId.properties中声明资源段（也可以通过mtl.tBuildConfig.autoPackageId设置自动分配packageID）\n\t\n\t        com.taobao.android:firstbundle=34//groupId:artifactId=NUM\n\t2. 在主客工程的build.gradle中添加awb依赖\n\n            compile(\"com.taobao.android:firstbundle:1.0.0@awb\")\n\n###  bundle的注意点\n遵循代码规范可以有效避免在运行时遇到难以排查的问题。\n\n1. Bundle的AndroidManifest中不能有对bundle内的资源的引用；比如Activity的Theme，需要声明在主apk中。Bundle的Manifest会合并进主Manifest，如果有bundle的资源引用会直接引发构建出错；另外可以选择的方式是AndroidManifest里面不加Theme，改用在Activity的onCreate方法里面调用setTheme的方式\n2. Activity通过overridePendingTransition使用的切换动画的文件要放在主apk中；\n3. Bundle内的Class最好以特定的packageName开头，resource文件能够带有特定的前缀。这样一来可以避免资源或者类名重复而引起的覆盖，也可以在出现问题的时候及时定位到出问题的模块\n4. Bundle内如果有用到自定义style,那么style的parent如果也是自定义的话，parent的定义必须位于主apk中，这是由于5.0以后系统内style查找的固有逻辑导致的，容器内暂不能完全兼容\n5. Bundle内部如果有so，则安装时so由于无法解压到apk lib目录中，对于直接通过native层使用dlopen来使用so的情况，会存在一定限制，且会影响后续so动态部署，所以目前bundle内so不建议使用dlopen的方式来使用\n \n6. Bundle内有使用主进程的contentProvider,则Bundle的AndroidManifest的contentprovider声明中最好带上\n\n```\n\tandroid:multiprocess=\"true\"\n\tandroid:process=\":XX\"\n```\n这样可以避免主进程一起来就去startBundle导致启动时间过长\n\n### 初始化Bundle\nbundle可以被认为是一个小型的apk，因此每个bundle的初始化都是从Bundle的Application开始的。Application被声明在bundle的AndroidManifest.xml里面\n\n**注意点：**虽然启动方式类似与普通app，先执行attachBaseContext，再执行onCreate，不过有两个不同点需要引起注意：\n\n1. Application 初始化的线程基于start bundle时的线程，这样导致了bundle可能会运行在主线程，也可能是在子线程，所以初始化的代码如果对线程敏感的需要注意：如果需要强制主线程的可以通过new Handler(Looper.getMainLooper()).post 去初始化\n\n2. bundle的Application并不是被系统真正认可的Application，所以需要Application作为参数进行初始化的方法可以传入getBaseContext()，Bundle Application的mBase实际上就是apk真正的application，最好不要直接传入bundle的Application本身进行初始化，会存在潜在的风险。\n\n### Bundle如何提供服务给其他Bundle\n**Bundle虽然提供了依赖的方式，但是这种方式如果使用不当反而会带来隐患，且与bundle本身的封装性相违背。**通常如果某个中间件是以bundle的形式存在，那声明依赖是可行的。如果两个本身相对独立的业务bundle存在某几个功能接口的依赖，则可以通过服务的方式，服务提供方提供aidl的接口，被使用方或者主apk依赖；同时自己bundle内部实现service的功能。\n\n### 主动启动Bundle\n默认情况下，Bundle只往外暴露了android原生的component,运行期按需加载。某些特殊的bundle（比如说监控性质的）本身与其他代码完全独立，且又需要在某个时间点启动运行的，可以通过如下方式去启动：\n加上Bundle的PackageName为：com.sample.bundleA\n\n```\n\n        Atlas.getInstance().installBundleTransitivelyAsync(\n        new String[]{\"com.sample.bundleA\"}, \n                new BundleInstaller.InstallListener() {\n            @Override\n            public void onFinished() {\n                BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(\"com.sample.bundleA\");\n                if(impl!=null){\n                    try {\n                        impl.start();\n                    } catch (BundleException e) {\n                        e.printStackTrace();\n                    }\n                }\n            }\n        });\n        \n"
  },
  {
    "path": "atlas-docs/guide-for-use/guide_for_compile.md",
    "content": "###待更新"
  },
  {
    "path": "atlas-docs/guide-for-use/guide_for_progurad.md",
    "content": "## 如何在自己的Library中定义ProGuard规则\n\n在Library的`build.gradle`中声明ProGuard规则文件，可以通过consumerProguardFiles选项声明ProGuard规则文件的路径：\n\n```\ndefaultConfig {\n    minSdkVersion 16\n    targetSdkVersion 25\n    consumerProguardFiles 'proguard-rules.pro' // 也可以是一个数组，声明多个\n}\n```\n\n然后在打包Library的时候，Android plugin会把声明的ProGuard规则文件给合并到一个文件中去，最终合并的文件路径是到：`build/intermediates/bundles/debug/proguard.txt`，最终`proguard.txt`会被打包到`aar`中。\n\n备注：可以解压`aar`根目录下的`proguard.txt`验证混淆规则是否是符合预期的。\n\n最后在编译整包的时候，Android plugin会把`aar`的`proguard.txt`文件给解压出来，在混淆的时候使用。\n\n\n## 扩展\n\nProGuard规则文件不仅仅可以在defaultConfig中声明，也可以在`BuildType`中同时声明：\n\n```\nbuildTypes {\n    debug {\n        consumerProguardFiles 'proguard-debug-rules.pro'\n    }\n    release {\n        consumerProguardFiles 'proguard-release-rules.pro'\n    }\n}\n```\n\n也可以在`Flavor`中同时声明：\n\n```\nproductFlavors {\n    demo {\n        consumerProguardFiles 'proguard-demo-rules.pro'\n    }\n    full {\n        consumerProguardFiles 'proguard-full-rules.pro'\n    }\n}\n```\n最终在不同的`BuildType`中和`Flavor`中声明的ProGuard规则文件，会根据编译的命令，把ProGuard规则给合并到一个文件中去，也就是我们上面说的`build/intermediates/bundles/debug/proguard.txt`。\n\n比如你执行的是`assembleDebug`，那么最终：\n\n```\nproguard.txt = proguard-rules.pro(defaultConfig) + proguard-debug-rules.pro(buildTypes[debug])\n```\n\n## 实现原理\n\n\n可以通过查看`com.android.build.gradle.internal.tasks.MergeProguardFilesConfigAction`这个类来看他的实现原理。\n\n## 安全混淆用户请注意\n\n由于`consumerProguardFiles`是对Android plugin的Proguard起作用，但是接入了安全混淆以后，我们在Android plugin的Proguard阶段已经**不做类名混淆了**，**只做无用方法**的裁剪，所以`consumerProguardFiles`定义的规则已经不起作用了，需要在main_builder下的`mtlplugin/blackmap.dat`文件中进行配置才可以。\n\n"
  },
  {
    "path": "atlas-docs/principle-intro/Apk_architecture.md",
    "content": "# APK结构\n\n基于Atlas构建后的APK结构如下图，host与普通Apk无异，但是Manifest和assets会添加一些额外的内容，同时在armeabi目录中会增加若干个bundle构建的产物，取名为String.format(lib%s.so,packagename.replace(\".\",\"_\"))；packagename为bundle的AndroidManifest中的packagename,这些so都是正常的apk结构，改为so放入lib目录只是为了安装时借用系统的能力从apk中解压出来，方便后续安装\n>\n![MacDown Screenshot](Project_architectured_img/apk_struct.png)\n\n##assets/bundleinfo-version.json\n构建完的apk在host的assets目录下，会有个bundleinfo-verison.json的文件，其中version为manifest中的versinonname，里面记录了每个bundle大小，版本，名字以及里面所有的component信息，这些内容在构建的时候生成，基于这些信息每个bundle可以在component被触发的时候去按需的进行安装，整个过程对开发者透明（从中也可以看到默认情况下bundle对外暴露的只是基于Android原生的Activity，service，receiver等component）。\n>\n![MacDown Screenshot](Project_architectured_img/bundleinfo.png)\n\n##AndroidManifest\nbundleinfo的信息同时也会在构建后的主manifest里面体现，如线框1、2所示，每个component下面meta-datal里面记录该component所在的meta-data,同时bundle某些特有的信息会记录在application级别的meta-data里面。\n>\n![MacDown Screenshot](Project_architectured_img/manifest.png)\n\n"
  },
  {
    "path": "atlas-docs/principle-intro/File_architecture_runtime.md",
    "content": "#运行期文件结构\n\n1. /data/data/pkgname/files/bundlelisting\n   \n   之前打包构建时记录的bundleinfo信息（发生动态部署收文件会进行更新）\n   \n2. /data/data/pkgname/files/baselineinfo\n\n\t存放动态部署后的版本变化内容，以及每次部署发生更新的bundle的版本，依赖等信息\n3. /data/data/pkgname/files/storage\n\t\n\tstorage目录是bundle安装的目录，每个bundle的安装目录以bundle的packagename为文件夹名，首次启动后会安装到version.1目录下，目录中可能含有bundle的zip文件，dex文件以及native so等内容。如果bundle发生更新，则可能会有version.2、version.3 等目录，每次加载bundle的时候选取最高可用版本进行载入。考虑bundle的回滚功能和对空间占用的影响，目前容器内最多保留两个最近可用版本。\n>\n![MacDown Screenshot](Project_architectured_img/runtime.png)\n"
  },
  {
    "path": "atlas-docs/principle-intro/Project_architectured.md",
    "content": "\n#名词解释\n\n**Bundle:** 类似OSGI规范里面bundle（组件）的概念，每个bundle有自己的classloader，与其他bundle相隔离，同时Atlas框架下bundle有自身的资源段（PackageID，打包时AAPT指定）；另外与原有OSGI所定义的service格式不同之处是Atlas里面Bundle透出所有定义在Manifest里面的component，随着service，activity的触发执行bundle的安装，运行。\n\n**awb：** android wireless bundle的缩写，实际上同AAR类似，是最终构建整包前的中间产物。每个awb最终会打成一个bundle。awb与aar的唯一不同之处是awb与之对应有个packageId的定义。\n\n**host:** 宿主的概念，所有的bundle可以直接调用host内的代码和资源，所以host常常集合了公共的中间件，UI资源等。host和bundle的依赖关系如下图所示：\n\n>\n![MacDown Screenshot](Project_architectured_img/relation.png)\n\n从上图也可以看出基于Atlas构建后大致工程的结构：\n\n1. 首先有个构建整体APK工程Apk_builder,里面管理着所有的依赖（包括atlas）及其版本，Apk_builder本身可能不包含任何代码，只负责构建使用\n2. host内部包含独立的中间件，以及一个Base的工程，里面可能包含应用的Application，应用icon等基础性内容（如果足够独立，application也可以直接放在apk_builder内）；\n3. 业务层基本上以bundle为边界自上而下与host发生调用，同时bundle之间允许存在依赖关系；相对业务独立的bundle如果存在接口耦合建议封装成aidl service的方式保证自身封装性；同时某些中间件如果只存在若干bundle使用的也可以封装bundle的方式提供出来，以保证host内容精简\n\n\n**remote bundle：** 远程bundle，远程bundle只是apk构建时并未打到apk内部，而是单独放在了云端；同时远程bundle的限制条件是第一次被触发的前提是bundle内的Activity需要被start，此时基于Atlas内的ClassNotFoundInterceptorCallback可以进行跳转的重定向，提示用户下载具体bundle，待用户确定后进行异步下载同时完成后再跳转到目标bundle（此部分代码由于涉及下载及UI展示等内容并未包含在开源仓库中，有需要可以根据ClassNotFoundInterceptorCallback自行实现）\n\n**动态部署：** 基于Atlas的installorUpdate和atlas-update库及构建插件，可以生成与之前发布的apk diff生成的差异文件，在更新时拉取同时静默更新到设备上，在用户下次启动之后生效新代码，具体原理可以参考动态部署章节的解析\n"
  },
  {
    "path": "atlas-docs/principle-intro/Runtime_principle.md",
    "content": "## 容器框架\n\n>\n![MacDown Screenshot](Project_architectured_img/runtime_struct.png)\n\n如上图所示，atlas主要分为以下几个层级：\n\n1. 最底下的hack工具层：\n   包括了容器所需的所有系统层面的注入和hack的工具类初始化和校验，容器启动时先校验设备是否支持容器运行，不支持则采取降级并记录原因； \n\n2. Bundle Framework 负责bundle的安装 更新 操作以及管理整个bundle的生命周期；\n\n3. runtime层：主要包括清单管理、版本管理、以及系统代理三大块，基于不同的触发点按需执行bundle的安装和加载；runtime层同时提供了开发期快速debug支持和监控两个功能模块。从Delegate层可以看到，最核心的两个代理点：一个是DelegateClassLoader：负责路由class加载到各个bundle内部，第二个是DelegateResource：负责资源查找时能够找到bundle内的资源；这是bundle能够真正运行起来的根本；其余的代理点均是为了保证在必要的时机按需加载起来目标bundle，让其可以被DelegateClassloader和DelegateResource使用\n\n4. 对外接入层:AtlasBridgeApplication是atlas框架下apk的真正Application，在基于Atlas框架构建的过程中会替换原有manifest中的application，所以Atlas的接入并不存在任何初始化代码，构建脚本完成了接入的过程。AtlasBridgeApplication里面除了完成了Atlas的初始化功能，同时**内置了multidex的功能**，这样做的原因有两个：\n   1. 很多大型的app不合理的初始化导致用multidex分包逻辑拆分的时候主dex的代码就有可能方法数超过65536，\u0002AtlasBridgeApplication与业务代码完全解耦，所以拆分上面只要保证atlas框架在主dex，其他代码无论怎么拆分都不会有问题；\n   2. 如果不替换Application，那么atlas的初始化就会在application里面，由于基于Atlas的动态部署实际上是类替换的机制，那么这种机制就会必然存在包括Application及其import的class等部分代码在dalvik不支持部署的情况，这个在使用过程中造成一定成本，需要小心的使用以避免dalivk内部class resolve机制导致部分class没成功，替换以后该问题得到最好的解决，除atlas本身以外，所有业务代码均可以动态部署；\n   \n另外内置的原生的multidex在dalvik上面性能并不好，atlas内部对其进行了优化提高了在dalvik上面的体验。\n\n除AtlasBridgeApplication之外，接入层对外提供了部分工具类，包括主动install bundle，start bundle，以及获取全局的application等各种功能。\n\n## Bundle生命周期\n每个bundle的生命周期如下图所示：\n>\n![MacDown Screenshot](Project_architectured_img/bundle_cycle.png)\n\n**Installed**\tbundle被安装到storage目录\n\n**Resolved**  classloader被创建，assetpatch注入DelegateResoucces\n\n**Active**     bundle的安全校验通过；bundle的dex检测已经成功dexopt(or dex2oat)，resource已经成功注入\n\n**Started**  bundle开始运行，bundle application的onCreate方法被调用\n\n\n##  类加载机制\n\nAtlas里面通常会创建了两种classLoader,第一个是DelegateClassLoader，他作为类查找的一个路由器而存在，本身并不负责真正类的加载；DelegateClassLoader启动时被atlas注入LoadedApk中，替换原有的PathClassLoader；第二个是BundleClassLoader，参考OSGI的实现，每个bundle resolve时会分配一个BundleClassLoader，负责该bundle的类加载。关系如下图所示：\n**DelegateClassLoader以PathClassLoader为parent，同时在路由过程中能够找到所有bundle的classloader；**\n\n**BundleClassLoader以BootClassLoader为parent，同时引用PathClassLoader,BundleClassLoader自身findClass的顺序为**\n  \n  **1. findOwn： 查找bundle dex 自身内部的class**\n  \n  **2. findDependency: 查找bundle依赖的bundle内的class**\n  \n  **3. findPath： 查找主apk中的class**\n\n>\n![MacDown Screenshot](Project_architectured_img/classloader.png)\n\n#### 范例\n下图是容器中类加载的大致顺序；\n可以认为是一个Bundle的Activity启动的类加载过程来帮助理解（假设Activity所在的bundle已经安装）；\n\n1. ActivityThread从LoadedApk中获取classloader去load Activity Class；\n2. 根据上面的classloader关系，先去parent里面加载class；\n3. 由于class在bundle里面，所以pathclassloader内查找失败，接着delegateclassloader根据bundleinfo信息查找到classloader在bundle中（假设为bundleA）；\n4. 从bundleA中加载class，并且创建class；\n5. 后面在Activity起来后，如果bundleA对bundleB有依赖关系，那么如果用到了bundleB的class，又会根据bundlA的bundleClassloader的dependency去获取bundleB的classloader去加载；\n![MacDown Screenshot](Project_architectured_img/class_find.png)\n\n##  资源加载机制\n>\n![MacDown Screenshot](Project_architectured_img/resources.png)\n\n类似ClassLoader，LoadedApk中的Resources被替换成Atlas内部的DelegateResources,同时在每个Bundle安装的过程中，每个bundle的assetspath会被更新到DelegateResources的AssetsManager中；每个bundle的资源特征如图可知：\n\n1. bundle构建过程中，每个bundle会被独立进行分区，packageId保证全局唯一，packageID在host的构建工程内会有个**packageIdFile.properties**进行统一分配；\n2. 虽然每个bundle的manifest都声明了自己的packagename，但是在aapt过程中，arsc文件里面所有bundle的packagename均被统一为hostApk的package，比如在手淘内就都是com.taobao.taobao；这样改的目的是为了解决在资源查找中一些兼容性问题； \n"
  },
  {
    "path": "atlas-docs/update/README.md",
    "content": "#动态部署\n\n动态部署与原有的Apk更新策略相比是一种相对比较轻量化的更新策略，不需要用户下载整个Apk，只需要下载仅仅差量部分的内容来达到更新效果；同时也可以静默的完成更新过程，两者相结合可以使动态更新的生效率远高于普通的升级策略。\n   \n动态部署适合用来解决下面等需求：\n\n1.  及时上线新需求，快速生效。\n2.  业务灰度新的sdk，快速测试效果，同时有问题可以及时回滚\n3.  动态修复线上故障"
  },
  {
    "path": "atlas-docs/update/dexpatch.md",
    "content": "#什么是Dexpatch\nDexPatch是以动态部署技术方案为基础，以快速解决线上故障为唯一目的的动态化方案。\n\n\n## 为什么不用动态部署\n动态部署的出发点立足于需求的快速迭代，替换普通的apk升级。所以在动态部署的演进过程中灵活性成为我们不断去追求的目标。希望不断缩小动态部署的限制以达到完全替换APK更新的能力。\n正是因为其比较全面的能力，我们发现动态部署在故障修复方面存在其不足的地方：\n\n1. **构建速度：**\n在每个需求迭代过程中，考虑需求的复杂性和每次周期性迭代管理的成本，动态部署参考APK迭代的方式通过统一的集成区进行管理，所以在构建上动态部署tpatch实际上是先有整包构建，再DIFF出差异的方式，这样的方式规避了混淆、内联等带来的复杂性的问题处理，保证patch对之前版本的完全适用，但是这种方式同时也必不可少的影响patch的构建速度，在对紧急的问题进行修复的关键时期，这个时间可能会是不可接受的。\n\n2. **生效速度：**\n   1. 动态部署内有代码的变更，so，资源等。灵活性导致一个动态部署等体积往往比较大，而在运营商网络下，对用户大的流量消耗不是我们希望看到的，所以往往这种情况下只在WIFI下的生效策略很能影响生效率。\n   2. 动态部署允许宿主，bundle内部发生更新，也允许bundle之间的依赖关系等发生变更，这就导致了一次动态部署成功必须依赖于tpatch内的所有bundle和宿主全部更新成功，否则就可能会导致依赖不一致而引发crash。从以往的动态部署tpatch可知，每次的变更通常都有十几个甚至几十个bundle发生变更，而在低空间或者某些读写能力较差的设备上，IO失败很容易影响整个patch的成功率。\n\n3. **版本号：**\n   因为是APk升级的替代方案，动态部署替换版本号的方式就使得是否使用的是动态部署还是apk升级对业务来说完全透明，可以继续按版本号进行逻辑处理，降级等。数据统计以及监控等可以完全兼容。但是如果在故障修复中去贸然升级版本号，虽然直观上可以清楚看到问题修复的覆盖率，但是之前优势就荡然无存了。\n   \n回顾手淘之前的一些故障问题的修复，不管是动态部署还是andfix，其实我们发现几乎所有的故障都可以通过java代码就行修复或者降级，也基本都可以在一个模块内的修改就把某个对应的故障修复掉。因此，以动态部署的技术作为基础，称之为**Dexpatch**的方案应运而生。\n\n## Dexpatch的特点和优势\n**限制：** \n\n每个dexpatch只能修改一个bundle(主dex整个算一个bundle)，且修改的代码必须向前兼容。（不如说主dex被bundle依赖，则主dex的dexpatch修改不能引起原来bundle的方法调用出现问题）\n\n**如何发布Dexpatch:**\n\n每个业务按照各自的故障情况进行dexpatch的构建，产出对应的patch产物和json信息，发布时平台应该汇总对应版本当前release的所有patch内容，整合json信息，进行下发\n\ndexpatch不存在回滚，每个dexpatch发布后，直接覆盖之前的dexpatch的。每个dexpatch有下线的能力\n\n**优势**\n\n1. 每个bundle基于自身的问题进行dexpatch的发布，构建速度相比原来的方式有了大幅度提高，只需要针对单个bundle进行构建从而diff出差异即可。\n2. 下发的dexpatch总包内的patch各自生效，不需要所有bundle的patch全部安装成功，这是由于之前patch的修改是向前兼容做了保证。\n\n3. dexpatch由于其修改的原子性（向前兼容性的保证以及不存在关联修改），同时容器按需加载的特性，使得未被载入的bundle可以不需要进程重启即可生效，同时，已经载入的bundle后期也会进行生命周期的监控，一旦所有component退出，则也可以进行热替换，使得dexpatch相比动态部署的生效速度可以进一步提高\n\n同时dexpatch不修改整个apk版本号，每个bundle提供额外的dexpatch版本号进行监控。\n\n另外 dexpatch作为动态部署的补充，两者相辅相成。可以针对任何一个大版本或者动态部署版本发布dexpatch，无论一个版本号对应的bundle是否有被dexpatch，当一个新的动态部署发生时，它们又都会被收敛到一个新动态部署版本上面。\n那么现在理想中的版本迭代的情况应该是如下这种：\n>\n![MacDown Screenshot](img/dexpatch.png)\n\n\n"
  },
  {
    "path": "atlas-docs/update/dexpatch_use_guide.md",
    "content": "# DexPatch使用示例\n\nDexPatch是以动态部署技术方案为基础，以快速解决线上故障为唯一目的的动态化方案。\n\n简单来说，动态部署是针对apk级别的动态升级，DexPatch是针对Bundle级别的动态修复(主dex可以认为是一个Bundle)\n\n详细介绍参照 [DexPatch介绍 ][dexpatch_guide]\n\n# DexPatch与动态部署异同\n\n|不同点| DexPatch|动态部署|\n|:----|:----|:---|\n|场景定位|bundle级别，代码动态修复|apk动态升级|\n|灵活度|各个bundle随时下发|集成升级|\n|构建速度|很快|一般|\n|生效速度|快|一般|\n|修改范围|bundle自身内聚|apk范围|\n|versionName|不改| +1|\n|java| 支持 |支持|\n|so|x|支持|\n|resource|x|支持|\n\n# 版本\n\n|依赖|版本|\n|:---|:---|\n| atlasplugin |2.3.3.rc12-1|\n|atlas_core|5.0.7.41|\n|atlasupdate|1.1.4.11|\n\n\n# 打包\n\nDexpatch需要一个ap版本作为参照，和现在的代码比对做diff。假设当前版本为1.0.0 (gradle中配置)\n\n## 发布版本\n\n如果之前发布过ap版本，可以跳过此节。假设从未发布过ap，按照如下步骤，发布1.0.0的ap\n\n1. 进入app目录下\n2. 生成基线版本 `./gradlew clean assembleDebug`\n3. 发布ap到仓库中 `./gradlew publish\n\n## 打patch\n\n\n1. 基于ap所属的版本(1.0.0)，修改代码,以firstbundle为例，将\"origin\"修改为\"dexpatch\"\n\n\t![][img_dexpatch_edit] \n2. 修改依赖版本，将firbundle中grddle的verion改为`version = '1.0.1'`\n\t\n\t> 这里也可以修改firbundle依赖的某个aar的版本。一句话，你要通过版本号告诉编译器，我这个bundle的代码变了\n4. 指定参照的版本，生成dexPatch包<br> `./gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.0`\n\nPS: \n> 这里要强调一下，代码的修改要内聚。<br>假设A依赖B,修改时，只改A或B自身的代码，不支持修改A与B之间的接口。\n\n\n# 部署Patch\n\n生成的patch文件在 `app/build/outputs`下，检查是否存在两个文件\n\n- 1.0.0@1.0.0.tpatch\n- dexpatch-1.0.0.json\n\n\n清空 `/sdcard/Android/data/com.taobao.demo/cache/`，并将上述两个文件push到上述路径中\n\n\n# demo中测试入口\n\n主界面点开侧边栏，点击dexpatch\n\n![][img_dexpatch_click]\n\n重启应用,Toash显示 \"dexpatch\",成功~\n\n![][img_dexpatch_result]\n\n\n# 产物说明\n\n![][img_dexpatch_out]\n\n## version@version.tpatch\n\n当前代码和参考ap(1.0.0)diff的产物，是个zip文件，解压开就是diff的代码。\n\n## patchs.json\n\n上述代码diff的配套json，描述了本次diff的结果:\n\n- 改动模块信息\n- 比对版本\n- ...\n\n## dexpatch-xxx.json\n\n## 说明\n\n__客户端可以识别的接口，对打包产物包装处理过的配置__\n\n客户端并不能直接识别打包产生的 `path.json` 文件，需要服务端做一些包装。\n\n## Demo说明\n\n由于demo没有服务端，所以在`app/dexPatchWraper.gradle`中，对patch.json内容做了一个包装，简单模拟服务端的逻辑。\n> 简单起见，只是每次都把dexPatchVersion+1，版本号缓存在根目录下的`dexPatch.verion`文件中。\n\n## 字段解释\n\n包装后的产物字端如下,大部分内容直接copy自`patch.json`,需要关心的只有几个字端\n\n\n```json\n{\n  \"baseVersion\": \"1.0.0\",\n  \"diffBundleDex\": true,\n  \"patches\": [\n    {\n      \"bundles\": [\n        {\n          \"dependency\": [\n            \"com.taobao.publicBundle\"\n          ],\n          //重要\n          \"dexpatchVersion\": \"14\",\n          \"isMainDex\": false,\n          \"name\": \"com.taobao.firstbundle\",\n          \"pkgName\": \"com.taobao.firstbundle\",\n          \"dependency\":[],\n          //重要\n          \"reset\": false,\n          \"srcUnitTag\": \"6b3973d9d6592d15601017edabc8b31b\",\n          \"unitTag\": \"e857557cc924f503a7304218469733a2\",\n          \"version\": \"1.0.1\"\n        }\n      ],\n      //重要\n      \"dexPatch\": true,\n      \"fileName\": \"1.0.0@1.0.0.tpatch\",\n      \"patchVersion\": \"1.0.0\",\n      \"targetVersion\": \"1.0.0\"\n    }\n  ]\n}\n```\n\n|字段|说明|\n|:---|:---|\n|dexpatchVersion|每个模块有一个dexPatchVersion的概念<br>客户端会判断bundle的dexPatchVersion,判断该bundle是否需要做merge<br>通常由服务端进行管理|\n|reset|回滚标志，该bundle会回滚到dexpatch前的版本|\n|dexPatch |区分配置是动态部署还是 dexpatch|\n\n\n\n[dexpatch_guide]: https://alibaba.github.io/atlas/update/dexpatch.html  \n[img_dexpatch_result]: img/dexpatch_result.png\n[img_dexpatch_click]: img/dexpatch_ui_click.png\n[img_dexpatch_edit]: img/dex_patch_edit.png\n[img_dexpatch_out]: img/dexpatch_build_output.png"
  },
  {
    "path": "atlas-docs/update/guide.md",
    "content": "####动态部署的限制\n1. **AndroidManifest**\n \t已有Activity的manifest信息暂时不支持更改\n \t\n2. **window级别使用的资源保持不变**\n\tActivity切换的动画文件、通知栏使用的logo等如果修改了也不会生效，不过不会产生问题，使用的还是原来的样式\n   "
  },
  {
    "path": "atlas-docs/update/principle.md",
    "content": "#技术原理\n\n普通Apk的更新的过程为构建->安装->生效，与之相对应，动态部署也可以分为三个过程：\n\n1. **构建**  不同于Apk更新产物就是一个完整的Apk，动态部署的构建产物是一个后缀为tpatch格式的文件\n2. **merge** 下载到tpatch文件后，动态部署sdk会在后台完成merge到安装的过程，整个过程对用户透明\n3. **生效**  merge完以后，当前的应用处于一个等待生效的状态，会在合适的时机选择进程重启来生效此次的动态部署，且在生效前不会再接收新的动态部署行为，进程重启以后表示一次完整的动态部署过程结束\n\n下面对每个过程展开讲解下，以便更好理解整个动态部署的机制\n###  构建\n动态部署构建的产物为tpatch为后缀的一个压缩文件--文件名为\n\n**patch-targetVersion@sourceVersion.tpatch**\n\n例如手淘6.2.0部署到6.2.1的动态部署的tpatch文件为：\npatch-6.2.1@6.2.0.tpatch\n\npatch文件解压后一级目录如下图：\n\n1. 如果有主apk的更新，则会有com_taobao_maindex.so存在，so中包含差量的classes.dex、res等\n2. 如果有bundle更新，则一级目录下以bundle为粒度有多个文件夹，每个文件夹下包含差量的classes.dex，res等\n\n**注意点：主Apk的差量与bundle的差量目前采取不同的策略，主Apk永远是与基线版本做差量；而bundle是更上一个版本做差量：比如从6.1动态部署到6.2再动态部署到6.3，则6.3中主apk的差量是6.3主apk的集成内容和基线（6.1）主apk中的内容diff出差量；6.3中bundle的差量则是与上一个版本进行diff，如果是6.2的版本去请求动态部署的tpatch，则tpatch中的bundle的差量是6.3与6.2的bundle进行diff所得，如果是6.1版本去请求6.3的动态部署的tpatch，则bundle的差量是6.3与6.1的bundle进行diff所得**\n>\n![MacDown Screenshot](img/patch_file.png)\n\n与tpatch文件相对于的，接口会返回该次动态部署的修改内容，数据结构如下：\n![MacDown Screenshot](img/patch_json.png)\n\n数据中可以看出bundle动态部署过程bundle的依赖关系允许发生变更，同时动态部署也有一定的限制，这个会在后面单独进行说明\n\n### Merge\nmerge过程在下载到tpatch且校验通过后在线程中进行，由之前Atlas容器安装目录介绍可知，假设当前bundle的版本在文件系统上为Version.1,则merge成功后新的bundle会安装在Version.2目录下，并在后续新的动态部署中版本号逐步往后追加，同时鉴于空间占用的考虑，目前的策略是会保留上一个版本（鉴于回滚的考虑）；\n\n与bundle以包名为文件夹存放类似，主Apk更新存放的文件夹以**com.taobao.maindex**为名字，里面的版本管理与bundle一致，不同点是com.taobao.maindex只在发生过动态部署以后才会有，Version.1意味着已经发生一次动态部署；bundle通常情况下动态部署从Version.2开始（未安装过的bundle除外）\n\n动态部署成功后，会在下次进程重启后去resolve新的bundle，resolve的策略是按版本号从高到低回溯，选择最高可用的版本使用。\n\n下面展开介绍下在新bundle（假设主Apk当做是一个特殊的bundle）安装成功前merge的过程中bundle和主Apk在merge过程中的差异点：\n#### bundle Merge\nbundle的merge主要以下几个过程(如下图)\n\n1. 获取merge的数据源：patch信息来自于bundle在下载的tpatch包中的内容，用于merge的source来自于当前设备的文件系统中，可能来自于已经安装过的bundle（storage），可能还没有安装（apk或者lib目录下）\n2. 创建新的bundle zip包，classes.dex来自于source中的classes.dex和patch包中的classes.dex通过Dexmerge合并新的classes.dex\n3. arsc和AndroidManifest直接使用patch包中的内容 \n4. res和assets 会进行合并，如果文件没有变更（patch中没有，source中有），则直接使用source中的内容，如果有文件新增或者发生了变更（patch中有，source中有或者没有），则从patch中读取放到新的bundle包中\n![MacDown Screenshot](img/bundle_merge.png)\n\nmerge完以后接下去安装就是容器的逻辑了，如果没有安装过则在bundle目录下生成Version.1目录进行安装，如果安装过则生成新的版本目录\n\n#### 主Apk的Merge\n主Apk的Merge在dalvik和art上使用的机制有所不同，dalvik设备上没有任何merge过程，直接把libcom_taobao_maindex.so以bundle的形式安装到com.taobao.maindex目录下\nArt设备上我们会根据source的apk（主apk的merge永远是基于基线版本）把classes.dex 提取出来以多dex的方式追加到libcom_taobao_maindex.so中，如果本身是多dex机制的，那么会将多个子dex全部追加进去，patch里面的classes.dex保持不变，source里面的dex的序列号往后偏移一位（classes.dex->classes2.dex,classes2.dex->classes3.dex）,如下图所示：\n>\n![MacDown Screenshot](img/art_maindex_merge.png)\n\nMerge安装成功后，会将bundleinfo的信息更新到baselineinfo的目录中，并在下次启动的最早时间替换掉原有的baselineinfo信息；里面的内容记录了更新的bundle的name，version以及部署成功以后的版本号等信息。\n### 运行期\n#### bundle的运行期加载策略：\n由之前的容器的运行机制可以得知，bundle动态部署后对容器来说没有任何变化，还是按需的load bundle，只是在需要去load前版本选择上会使用最高的可用版本\n\n#### 主apk动态部署后的加载策略\n\n了解主Apk的加载策略之前，先分别介绍下主Apk动态部署得以成功的技术基础再阐述生效的方式：\n##### class|so\n这里粗略介绍下普通apk（也就是主Apk）class，so库加载入口--**PathClassLoader**\n前面容器的技术原理里面介绍了PathClassLoader的父子关系，PathClassLoader自身负责主Apk的类和c库的查找路口；其parent BootClassloader负责framework sdk的内容的查找。\n\nPathClassLoader本身也是一个class，继承了BaseDexClassLoader（同DexClassLoader），里面查找过程在DexPathList里面实现（如下图）\n>\n![MacDown Screenshot](img/pathclassloader.png)\n\nDexPathList最终通过DexFile去loadClass，DexPathList可以理解为持有者DexFile以及nativeLibrary目录，再查找的时候遍历这些对象，直到找到需要的类或者c库，那么动态部署的方式就是把新修改的内容添加到这些对象的最前面，从而使得查找的过程中新修改的内容能够提前找到从而替换原有的（如下图）\n\n>\n![MacDown Screenshot](img/maindex_load.png)\n\n这里有两个注意点提及一下以加深理解：\n\n1. **PREVERIFY:** 经过手淘打包插件构建以后，主apk里面的所有class，interface都插入了一段代码：类似下图。原因是android构建的时候会有PREVERIFY的过程，如果Class所引用到的Class均和Class自己在同一个dex内部，则会被打上PREVERIFY的标记。然后在运行期的时候如果打上这个标记的class，在载入时不需要经过verify已提高加载效率，但是运行到方法时会校验依赖的class是否跟构建时一致和Class自身处于同一个dex，如果不一致则会抛出PREVERIFY的错误。而手淘的动态部署策略必然会新生成一个dex，那么如果遇到是PREVERIFY的class的时候就会出错。所以目前手淘的策略是在编译期给每个class引用到一个不存在的class以解除PREVERIFY的限制（具体PREVERIFY的校验过程可以阅读Android源码）\n>\n![MacDown Screenshot](img/verify.png)\n\n2. **OAT的限制:**android到art后原有的dexopt会改为dex2oat，运行时代码由原来的解释执行改为直接运行native代码，之前的使用过程中发现单纯得往前面追加patch的dex并不能完全解决动态部署的问题，dex2oat的过程优化了class的执行代码，比如说内敛，虚函数的校验等。就有可能在运行过程中直接在native层执行老的优化过的class代码而不是从新patch的dex中load新的class去使用。所以art上目前的策略是把patchdex，sourcedex参考multidex的机制放入一个zip，然后合并在一起做一遍dex2oat，这样能使新的class覆盖老的class参与dex2oat并完成优化的过程，所以art上的真正的执行过程实际上在patch的dex中已经包含了所有主apk的代码，基本不会走到old dex的逻辑。（patchdex 插入前执行的代码除外） \n\n##### resource|assets\n\n主Apk为了支持在Resource能够动态部署实际上同PREVERIFY的机制类似，在基线包构建的时候就已经做了处理:基于Atlas打出来的apk的资源列表中有如下内容：\n\n>\n![MacDown Screenshot](img/base_dump.png)\n\n我们取一个动态部署的tpatch包，能够看到如下内容：\n>\n![MacDown Screenshot](img/patch_dump.png)\n\n这些是基于我们atlas-aapt的修改，dalvik上我们是基于res的overlay机制去修改资源，这个机制并不支持新增资源，在overlay的包里面如果读到了一个资源，dalvik系统会去校验该资源ID在base中值，如果不存在则抛错，所以动态部署为了利用这一特性同时支持新增资源的需求，在打基线包的时候就在每个不同的type里面预留了128个资源ID供后续动态部署使用；同时打动态部署的patch时会以之前的ID分配的内容作为输入，保证已有的资源分配到的ID保持不变，同时如果资源没有发生变更，则剔除该资源，所以aapt dump patch的时候我们看到的INVALID TYPE 的资源段没有发生变更的资源，如果有发生了变更，且之前有这个资源，就会在原有的资源ID分配过去，同时新的资源文件打入patch包或者新的资源文本写入arsc，如果是新增的资源，则使用预留的资源段进行分配。整个替换过程如下图所示：\n>\n![MacDown Screenshot](img/res_patch.png)\n\n在打包对资源做了一系列处理以后，运行期资源的加载只是在启动加载资源时根据系统读取资源的先后书序把patch包插入到AssetsManager的合适的位置中，assets由于没有资源ID，不需要预留，插入AssetsManager的方式类似res的处理，这里不再展开"
  },
  {
    "path": "atlas-gradle-plugin/README.md",
    "content": "# atlasplugin\n\n## changelog\n\n### 2.3.3.beta1\n\n0. 升级android builder 到 2.3.3版本\n1. unit tag 非 diff bundle 保持 不变\n2. tBuildConfig.minPackageId 可设置最小的自动分配packageId，默认35（10进制）开始\n3. 加强对插件配置使用的校验\n      1. 不推荐在atlasplugin之前添加google官方的插件，推荐让atlasplugin自动依赖传递进来\n      2. bundle之前的依赖推荐使用bundleCompile， 如果使用compile awb，会有警告日志\n      3. awb 之间允许使用 providedCompile 依赖\n4. databinding优化，后续bundle的databinding需要独立配置是否启用\n\n        tBuildConfig.dataBindingBundles \n        配置值为 bundle 的packageName \n        类型为 Set<String>\n        代码： com.taobao.android.builder.extension.TBuildConfig.dataBindingBundles\n\n\n### 2.3.1.rc15\n\n1. bundleInfo 增加unique_tag\n2. 增加fastMultiDex功能，该功能需要关闭android里的multidexEnabled，充分利用predex和dexcache。配置开关 `atlas.multiDexConfigs.debug.fastMultiDex=true`\n\n### 2.3.1.rc11\n\n1. 支持bundle配置proguard规则，仅支持keep和dontwarn\n\n### 2.3.0.alpha15\n\n1. 支持手淘灰度版本\n2. 升级aapt\n3. 增加atlasMultiDex功能,默认关闭，mtl.tBuildConfig.atlasMultiDex=true\n\n### 2.3.0.alpha11\n\n1. processManifest 修复 无 application ， 替换的不对\n2. awb 增加 process resource 逻辑\n3. butterknife 支持 \n\n\n### 2.3.0.alpha10\n\n1. 修复postprocessmanifest\n2. data-bind支持\n3. 升级dex_patch，支持远程bundle patch\n\n### 2.3.0.alpha7\n1. 修复某些场景下buildcache导致的构建失败\n2. 修复 awo 快速调试\n3. 升级 dex_patch ,兼容windows ，版本 1.1+\n4. 依赖解析优化，避免递归循环\n\n### 2.3.0.alpha4\n1. 支持google的最新插件，builder ： 2.3.0 ， gradle ： 3.3  ， buildTools ：25.0.0+\n2. 优化atlas插件对官方插件的侵入，允许推荐使用 ：\n\n        apply plugin: 'com.android.application'\n        apply plugin: 'com.taobao.atlas'       \n3. 对多模块更好的支持，回归原本的本地开发模式\n4. 新增2种依赖关系\n\n        providedCompile ： bundle定义运行时依赖，编译运行可见， 最终不会打到bundle的so中\n        bundleCompile :  在app中定义bundle的依赖\n5. 远程bundle支持\n\n支持 atlas 工程打包的gradle 插件， 基于 google 官方的 android builder （2.2.3）\n\n### 基本概念\n\n1. atlasplugin : 支持atlas的gradle打包插件，支持打 apk 和 awb\n2. awb ： 包结构上和 aar 一致， 在 atlas 里每一个 awb 被认为是一个独立的业务模块，有独立的application， awb 之前默认是不能相互依赖 ， 具体参考  `atlas-demo/firstbundle`\n3. ap : 基线包， 里面包含该版本对应的 apk 产物及其他打包过程中的中间产物， 是打 patch 包的必要条件\n\n### 主要功能\n\n1. 支持 awb 类型依赖\n2. 支持 bundle 的package\n3. 支持 动态部署\n\n\n### 接入\n\n1. 引用插件\n\n\t\tbuildscript {\n\t\t    repositories {\n\t\t        mavenLocal()\n\t\t        jcenter()\n\t\t    }\n\t\t    dependencies {\n\t\t        classpath \"com.taobao.android:atlasplugin:2.2.3.alpha+\"\n\t\t    }\n\t\t}\n\n\t注意尽量不要指定 classpath \"com.android.tools.build:gradle\"的版本，默认使用的是 2.2.3\n\n2. 应用plugin\n\n\t\t apply plugin: 'com.android.application'\n         apply plugin: 'com.taobao.atlas'\n\n3. 配置打包参数， ./gradlew atlasList,  具体见 `配置`\n\n4. 执行构建 ./gradlew assembleDebug 或者 assembleRelease\n\n5. 构建产物：\n\n\t1. build/outputs/apk/xx.apk , 构建的产物apk   \n\t2. build/outputs/apk/xx.ap , 构建的基线包， 里面包含 apk 和其他的打包中间配置\n\t3. build/outputs/dependencyTree-debug.json , 整个工程的依赖树\n\t4. build/outputs/atlasConfig.json , 整个打包的 atlas 配置参数\n\t5. build/outputs/packageIdFile.properties , 每个bundle对应的packageId 列表\n\t6. build/outputs/tpatch-debug , debug 包 patch产物\n\t7. build/outputs/tpatch-release , release 包 patch产物\n\n\n### 配置\n\n#### 配置列表\n\n 功能  | 配置名称 |  类型 | 值\n ------------- | ------------- | ------------- | -------------\n是否启用atlas  | atlas.atlasEnabled | boolean  | true\n自动生成bundle的packageId  | atlas.tBuildConfig.autoPackageId | boolean  | true\n预处理manifest， 如果开启atlas，必须为true  | atlas.tBuildConfig.preProcessManifest | Boolean  | true\n使用自定义的aapt， 如果开启atlas，必须为true  | atlas.tBuildConfig.useCustomAapt | Boolean  | true\naapt输出的R为常量, 建议值设置为false， 可以减少动态部署的patch包大小  | atlas.tBuildConfig.aaptConstantId | Boolean  | true\n合并jar中的资源文件  | atlas.tBuildConfig.mergeJavaRes | Boolean  | false\n构建基线包，建议开启，否则后面的patch包无法进行  | atlas.tBuildConfig.createAP | Boolean  | true\n合并bundle jar中的资源文件  | atlas.tBuildConfig.mergeAwbJavaRes | Boolean  | false\n是否依赖冲突终止打包  | atlas.tBuildConfig.abortIfDependencyConflict | boolean  | false\n是否类冲突终止打包  | atlas.tBuildConfig.abortIfClassConflict | boolean  | false\n自启动的bundle列表， 值是 packageName  | atlas.tBuildConfig.autoStartBundles | List  | [com.taobao.firstbundle]\n提前执行的方法，格式是 className:methodName|className2:methodName2 ， 注意class和methodname都不能混淆，且方法实现是 class.method(Context)  | atlas.tBuildConfig.preLaunch | String  |\n 基线的依赖坐标， 如： com.taobao.android:taobao-android-release:6.3.0-SNAPSHOT@ap   | atlas.buildTypes.debug.baseApDependency | String  | null\n 基线的依赖坐标， 如： com.taobao.android:taobao-android-release:6.3.0-SNAPSHOT@ap   | atlas.buildTypes.release.baseApDependency | String  | null\n使用atlas的application，包含 atlas基础初始化及multidex逻辑  | atlas.manifestOptions.replaceApplication | boolean  | true\n 打动态部署 patch 包   | atlas.patchConfigs.debug.createTPatch | boolean  | true\n 打动态部署 patch 包   | atlas.patchConfigs.release.createTPatch | boolean  | false\n\n\n####  最简配置\n\n    atlas {\n        atlasEnabled true\n    }\n\n\n\n\n具体参考 `atlas-demo/AtlasDemo/app/build.gradle`\n"
  },
  {
    "path": "atlas-gradle-plugin/aapt/build.gradle",
    "content": "apply plugin: 'groovy'\napply plugin: 'java'\n\nrepositories {\n    //本地库，local repository(${user.home}/.m2/repository)\n    mavenLocal()\n    jcenter()\n}\n\nsourceSets {\n    main {\n        groovy.srcDirs = ['src/main/groovy']\n        java.srcDirs = ['src/main/java']\n        resources.srcDirs = ['src/main/resources']\n    }\n}\n\ndependencies {\n}\n\n\nversion = '2.3.1.rc4'\n\n"
  },
  {
    "path": "atlas-gradle-plugin/aapt/src/main/java/com/taobao/android/AaptLib.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android;\n\n/**\n * Created by wuzhong on 2017/6/11.\n */\npublic class AaptLib {\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/.gradletasknamecache",
    "content": "\n\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/build/resources/main/META-INF/gradle-plugins/com.taobao.atlas.feature.properties",
    "content": "implementation-class=com.taobao.android.builder.AtlasFeaturePlugin"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/build/resources/main/META-INF/gradle-plugins/com.taobao.atlas.instantapp.properties",
    "content": "implementation-class=com.taobao.android.builder.AtlasDexPatchPlugin"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/build.gradle",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\napply plugin: 'groovy'\napply plugin: 'java'\n\nrepositories {\n    //本地库，local repository(${user.home}/.m2/repository)\n    mavenLocal()\n    jcenter()\n    google()\n}\n\nsourceSets {\n    main {\n        groovy.srcDirs = ['src/main/groovy']\n        java.srcDirs = ['src/main/java']\n        resources.srcDirs = ['src/main/resources']\n    }\n}\n\n\ntasks.findByName(\"test\").enabled = false\n\n\ndependencies {\n    compile localGroovy()\n    compile gradleApi()\n\n    compile \"com.taobao.android:dex_patch:3.0.0-rc16\"\n    compile \"com.android.tools.build:gradle:3.0.1\"\n    compile \"org.apache.commons:commons-lang3:3.4\"\n    compile \"commons-lang:commons-lang:2.6\"\n    compile \"com.alibaba:fastjson:1.2.6\"\n    compile 'org.dom4j:dom4j:2.0.0'\n    compile 'jaxen:jaxen:1.1.6'\n    compile 'commons-beanutils:commons-beanutils:1.9.0'\n    compile 'org.javassist:javassist:3.19.0-GA'\n    compile \"com.taobao.android:preverify:1.0.0\"\n    compile \"org.codehaus.plexus:plexus-utils:3.0.24\"\n    compile \"com.taobao.android:aapt:2.3.1.rc4\"\n    compile \"com.google.inject:guice:4.0\"\n    compile \"com.google.auto.value:auto-value:1.0\"\n    compile \"org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.41\"\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n\n    testCompile \"junit:junit:4.11\"\n}\njar {\n    from zipTree(\"libs/libarsc.jar\")\n}\n\n\nversion = '3.0.1-rc88-fix2'\n\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/increment.sh",
    "content": "cd ../../atlas-demo/AtlasDemo/\n./gradlew clean assembleDebug --stacktrace\n./gradlew  assembleDebug --stacktrace\ncd ../../atlas-gradle-plugin/atlas-plugin"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/publish.sh",
    "content": "../gradlew clean build bintray"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/android/aapt/pb/internal/ResourcesInternal.java",
    "content": "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n// source: frameworks/base/tools/aapt2/ResourcesInternal.proto\n\npackage android.aapt.pb.internal;\n\npublic final class ResourcesInternal {\n    private ResourcesInternal() {\n    }\n\n    public static void registerAllExtensions(com.google.protobuf.ExtensionRegistryLite registry) {\n    }\n\n    public interface CompiledFileOrBuilder extends\n        // @@protoc_insertion_point(interface_extends:aapt.pb.internal.CompiledFile)\n        com.google.protobuf.MessageLiteOrBuilder {\n\n        /**\n         * <pre>\n         * The name of the resource (in the form package:type/name).\n         * </pre>\n         *\n         * <code>optional string resource_name = 1;</code>\n         */\n        boolean hasResourceName();\n\n        /**\n         * <pre>\n         * The name of the resource (in the form package:type/name).\n         * </pre>\n         *\n         * <code>optional string resource_name = 1;</code>\n         */\n        String getResourceName();\n\n        /**\n         * <pre>\n         * The name of the resource (in the form package:type/name).\n         * </pre>\n         *\n         * <code>optional string resource_name = 1;</code>\n         */\n        com.google.protobuf.ByteString getResourceNameBytes();\n\n        /**\n         * <pre>\n         * The configuration for which the resource is defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.ConfigDescription config = 2;</code>\n         */\n        boolean hasConfig();\n\n        /**\n         * <pre>\n         * The configuration for which the resource is defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.ConfigDescription config = 2;</code>\n         */\n        com.android.aapt.Resources.ConfigDescription getConfig();\n\n        /**\n         * <pre>\n         * The filesystem path to where the source file originated.\n         * Mainly used to display helpful error messages.\n         * </pre>\n         *\n         * <code>optional string source_path = 3;</code>\n         */\n        boolean hasSourcePath();\n\n        /**\n         * <pre>\n         * The filesystem path to where the source file originated.\n         * Mainly used to display helpful error messages.\n         * </pre>\n         *\n         * <code>optional string source_path = 3;</code>\n         */\n        String getSourcePath();\n\n        /**\n         * <pre>\n         * The filesystem path to where the source file originated.\n         * Mainly used to display helpful error messages.\n         * </pre>\n         *\n         * <code>optional string source_path = 3;</code>\n         */\n        com.google.protobuf.ByteString getSourcePathBytes();\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        java.util.List<CompiledFile.Symbol> getExportedSymbolList();\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        CompiledFile.Symbol getExportedSymbol(int index);\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        int getExportedSymbolCount();\n\n        /**\n         * <pre>\n         * If this is a compiled XML file, this is the root node.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.XmlNode xml_root = 5;</code>\n         */\n        boolean hasXmlRoot();\n\n        /**\n         * <pre>\n         * If this is a compiled XML file, this is the root node.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.XmlNode xml_root = 5;</code>\n         */\n        com.android.aapt.Resources.XmlNode getXmlRoot();\n    }\n\n    /**\n     * <pre>\n     * The top level message representing an external resource file (layout XML, PNG, etc).\n     * This is used to represent a compiled file before it is linked. Only useful to aapt2.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.internal.CompiledFile}\n     */\n    public static final class CompiledFile\n        extends com.google.protobuf.GeneratedMessageLite<CompiledFile, CompiledFile.Builder> implements\n        // @@protoc_insertion_point(message_implements:aapt.pb.internal.CompiledFile)\n        CompiledFileOrBuilder {\n        private CompiledFile() {\n            resourceName_ = \"\";\n            sourcePath_ = \"\";\n            exportedSymbol_ = emptyProtobufList();\n        }\n\n        public interface SymbolOrBuilder extends\n            // @@protoc_insertion_point(interface_extends:aapt.pb.internal.CompiledFile.Symbol)\n            com.google.protobuf.MessageLiteOrBuilder {\n\n            /**\n             * <pre>\n             * The name of the symbol (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            boolean hasResourceName();\n\n            /**\n             * <pre>\n             * The name of the symbol (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            String getResourceName();\n\n            /**\n             * <pre>\n             * The name of the symbol (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            com.google.protobuf.ByteString getResourceNameBytes();\n\n            /**\n             * <pre>\n             * The position in the file at which this symbol is defined. For debug use.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.SourcePosition source = 2;</code>\n             */\n            boolean hasSource();\n\n            /**\n             * <pre>\n             * The position in the file at which this symbol is defined. For debug use.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.SourcePosition source = 2;</code>\n             */\n            com.android.aapt.Resources.SourcePosition getSource();\n        }\n\n        /**\n         * Protobuf type {@code aapt.pb.internal.CompiledFile.Symbol}\n         */\n        public static final class Symbol extends com.google.protobuf.GeneratedMessageLite<Symbol, Symbol.Builder>\n            implements\n            // @@protoc_insertion_point(message_implements:aapt.pb.internal.CompiledFile.Symbol)\n            SymbolOrBuilder {\n            private Symbol() {\n                resourceName_ = \"\";\n            }\n\n            private int bitField0_;\n\n            public static final int RESOURCE_NAME_FIELD_NUMBER = 1;\n\n            private String resourceName_;\n\n            /**\n             * <pre>\n             * The name of the symbol (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            @Override\n            public boolean hasResourceName() {\n                return ((bitField0_ & 0x00000001) == 0x00000001);\n            }\n\n            /**\n             * <pre>\n             * The name of the symbol (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            @Override\n            public String getResourceName() {\n                return resourceName_;\n            }\n\n            /**\n             * <pre>\n             * The name of the symbol (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            @Override\n            public com.google.protobuf.ByteString getResourceNameBytes() {\n                return com.google.protobuf.ByteString.copyFromUtf8(resourceName_);\n            }\n\n            /**\n             * <pre>\n             * The name of the symbol (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            private void setResourceName(String value) {\n                if (value == null) {\n                    throw new NullPointerException();\n                }\n                bitField0_ |= 0x00000001;\n                resourceName_ = value;\n            }\n\n            /**\n             * <pre>\n             * The name of the symbol (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            private void clearResourceName() {\n                bitField0_ = (bitField0_ & ~0x00000001);\n                resourceName_ = getDefaultInstance().getResourceName();\n            }\n\n            /**\n             * <pre>\n             * The name of the symbol (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            private void setResourceNameBytes(com.google.protobuf.ByteString value) {\n                if (value == null) {\n                    throw new NullPointerException();\n                }\n                bitField0_ |= 0x00000001;\n                resourceName_ = value.toStringUtf8();\n            }\n\n            public static final int SOURCE_FIELD_NUMBER = 2;\n\n            private com.android.aapt.Resources.SourcePosition source_;\n\n            /**\n             * <pre>\n             * The position in the file at which this symbol is defined. For debug use.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.SourcePosition source = 2;</code>\n             */\n            @Override\n            public boolean hasSource() {\n                return ((bitField0_ & 0x00000002) == 0x00000002);\n            }\n\n            /**\n             * <pre>\n             * The position in the file at which this symbol is defined. For debug use.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.SourcePosition source = 2;</code>\n             */\n            @Override\n            public com.android.aapt.Resources.SourcePosition getSource() {\n                return source_ == null ? com.android.aapt.Resources.SourcePosition.getDefaultInstance() : source_;\n            }\n\n            /**\n             * <pre>\n             * The position in the file at which this symbol is defined. For debug use.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.SourcePosition source = 2;</code>\n             */\n            private void setSource(com.android.aapt.Resources.SourcePosition value) {\n                if (value == null) {\n                    throw new NullPointerException();\n                }\n                source_ = value;\n                bitField0_ |= 0x00000002;\n            }\n\n            /**\n             * <pre>\n             * The position in the file at which this symbol is defined. For debug use.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.SourcePosition source = 2;</code>\n             */\n            private void setSource(com.android.aapt.Resources.SourcePosition.Builder builderForValue) {\n                source_ = builderForValue.build();\n                bitField0_ |= 0x00000002;\n            }\n\n            /**\n             * <pre>\n             * The position in the file at which this symbol is defined. For debug use.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.SourcePosition source = 2;</code>\n             */\n            private void mergeSource(com.android.aapt.Resources.SourcePosition value) {\n                if (source_ != null && source_ != com.android.aapt.Resources.SourcePosition.getDefaultInstance()) {\n                    source_ = com.android.aapt.Resources.SourcePosition.newBuilder(source_)\n                        .mergeFrom(value)\n                        .buildPartial();\n                } else {\n                    source_ = value;\n                }\n                bitField0_ |= 0x00000002;\n            }\n\n            /**\n             * <pre>\n             * The position in the file at which this symbol is defined. For debug use.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.SourcePosition source = 2;</code>\n             */\n            private void clearSource() {\n                source_ = null;\n                bitField0_ = (bitField0_ & ~0x00000002);\n            }\n\n            @Override\n            public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {\n                if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                    output.writeString(1, getResourceName());\n                }\n                if (((bitField0_ & 0x00000002) == 0x00000002)) {\n                    output.writeMessage(2, getSource());\n                }\n                unknownFields.writeTo(output);\n            }\n\n            @Override\n            public int getSerializedSize() {\n                int size = memoizedSerializedSize;\n                if (size != -1) {\n                    return size;\n                }\n\n                size = 0;\n                if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                    size += com.google.protobuf.CodedOutputStream.computeStringSize(1, getResourceName());\n                }\n                if (((bitField0_ & 0x00000002) == 0x00000002)) {\n                    size += com.google.protobuf.CodedOutputStream.computeMessageSize(2, getSource());\n                }\n                size += unknownFields.getSerializedSize();\n                memoizedSerializedSize = size;\n                return size;\n            }\n\n            public static Symbol parseFrom(com.google.protobuf.ByteString data)\n                throws com.google.protobuf.InvalidProtocolBufferException {\n                return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, data);\n            }\n\n            public static Symbol parseFrom(com.google.protobuf.ByteString data,\n                                           com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n                throws com.google.protobuf.InvalidProtocolBufferException {\n                return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, data, extensionRegistry);\n            }\n\n            public static Symbol parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException {\n                return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, data);\n            }\n\n            public static Symbol parseFrom(byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n                throws com.google.protobuf.InvalidProtocolBufferException {\n                return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, data, extensionRegistry);\n            }\n\n            public static Symbol parseFrom(java.io.InputStream input) throws java.io.IOException {\n                return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, input);\n            }\n\n            public static Symbol parseFrom(java.io.InputStream input,\n                                           com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n                throws java.io.IOException {\n                return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n            }\n\n            public static Symbol parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException {\n                return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n            }\n\n            public static Symbol parseDelimitedFrom(java.io.InputStream input,\n                                                    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n                throws java.io.IOException {\n                return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n            }\n\n            public static Symbol parseFrom(com.google.protobuf.CodedInputStream input) throws java.io.IOException {\n                return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, input);\n            }\n\n            public static Symbol parseFrom(com.google.protobuf.CodedInputStream input,\n                                           com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n                throws java.io.IOException {\n                return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n            }\n\n            public static Builder newBuilder() {\n                return DEFAULT_INSTANCE.toBuilder();\n            }\n\n            public static Builder newBuilder(Symbol prototype) {\n                return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n            }\n\n            /**\n             * Protobuf type {@code aapt.pb.internal.CompiledFile.Symbol}\n             */\n            public static final class Builder extends com.google.protobuf.GeneratedMessageLite.Builder<Symbol, Builder>\n                implements\n                // @@protoc_insertion_point(builder_implements:aapt.pb.internal.CompiledFile.Symbol)\n                SymbolOrBuilder {\n                // Construct using android.aapt.pb.internal.ResourcesInternal.CompiledFile.Symbol.newBuilder()\n                private Builder() {\n                    super(DEFAULT_INSTANCE);\n                }\n\n                /**\n                 * <pre>\n                 * The name of the symbol (in the form package:type/name).\n                 * </pre>\n                 *\n                 * <code>optional string resource_name = 1;</code>\n                 */\n                @Override\n                public boolean hasResourceName() {\n                    return instance.hasResourceName();\n                }\n\n                /**\n                 * <pre>\n                 * The name of the symbol (in the form package:type/name).\n                 * </pre>\n                 *\n                 * <code>optional string resource_name = 1;</code>\n                 */\n                @Override\n                public String getResourceName() {\n                    return instance.getResourceName();\n                }\n\n                /**\n                 * <pre>\n                 * The name of the symbol (in the form package:type/name).\n                 * </pre>\n                 *\n                 * <code>optional string resource_name = 1;</code>\n                 */\n                @Override\n                public com.google.protobuf.ByteString getResourceNameBytes() {\n                    return instance.getResourceNameBytes();\n                }\n\n                /**\n                 * <pre>\n                 * The name of the symbol (in the form package:type/name).\n                 * </pre>\n                 *\n                 * <code>optional string resource_name = 1;</code>\n                 */\n                public Builder setResourceName(String value) {\n                    copyOnWrite();\n                    instance.setResourceName(value);\n                    return this;\n                }\n\n                /**\n                 * <pre>\n                 * The name of the symbol (in the form package:type/name).\n                 * </pre>\n                 *\n                 * <code>optional string resource_name = 1;</code>\n                 */\n                public Builder clearResourceName() {\n                    copyOnWrite();\n                    instance.clearResourceName();\n                    return this;\n                }\n\n                /**\n                 * <pre>\n                 * The name of the symbol (in the form package:type/name).\n                 * </pre>\n                 *\n                 * <code>optional string resource_name = 1;</code>\n                 */\n                public Builder setResourceNameBytes(com.google.protobuf.ByteString value) {\n                    copyOnWrite();\n                    instance.setResourceNameBytes(value);\n                    return this;\n                }\n\n                /**\n                 * <pre>\n                 * The position in the file at which this symbol is defined. For debug use.\n                 * </pre>\n                 *\n                 * <code>optional .aapt.pb.SourcePosition source = 2;</code>\n                 */\n                @Override\n                public boolean hasSource() {\n                    return instance.hasSource();\n                }\n\n                /**\n                 * <pre>\n                 * The position in the file at which this symbol is defined. For debug use.\n                 * </pre>\n                 *\n                 * <code>optional .aapt.pb.SourcePosition source = 2;</code>\n                 */\n                @Override\n                public com.android.aapt.Resources.SourcePosition getSource() {\n                    return instance.getSource();\n                }\n\n                /**\n                 * <pre>\n                 * The position in the file at which this symbol is defined. For debug use.\n                 * </pre>\n                 *\n                 * <code>optional .aapt.pb.SourcePosition source = 2;</code>\n                 */\n                public Builder setSource(com.android.aapt.Resources.SourcePosition value) {\n                    copyOnWrite();\n                    instance.setSource(value);\n                    return this;\n                }\n\n                /**\n                 * <pre>\n                 * The position in the file at which this symbol is defined. For debug use.\n                 * </pre>\n                 *\n                 * <code>optional .aapt.pb.SourcePosition source = 2;</code>\n                 */\n                public Builder setSource(com.android.aapt.Resources.SourcePosition.Builder builderForValue) {\n                    copyOnWrite();\n                    instance.setSource(builderForValue);\n                    return this;\n                }\n\n                /**\n                 * <pre>\n                 * The position in the file at which this symbol is defined. For debug use.\n                 * </pre>\n                 *\n                 * <code>optional .aapt.pb.SourcePosition source = 2;</code>\n                 */\n                public Builder mergeSource(com.android.aapt.Resources.SourcePosition value) {\n                    copyOnWrite();\n                    instance.mergeSource(value);\n                    return this;\n                }\n\n                /**\n                 * <pre>\n                 * The position in the file at which this symbol is defined. For debug use.\n                 * </pre>\n                 *\n                 * <code>optional .aapt.pb.SourcePosition source = 2;</code>\n                 */\n                public Builder clearSource() {\n                    copyOnWrite();\n                    instance.clearSource();\n                    return this;\n                }\n\n                // @@protoc_insertion_point(builder_scope:aapt.pb.internal.CompiledFile.Symbol)\n            }\n\n            @Override\n            protected final Object dynamicMethod(MethodToInvoke method, Object arg0, Object arg1) {\n                switch (method) {\n                    case NEW_MUTABLE_INSTANCE: {\n                        return new Symbol();\n                    }\n                    case IS_INITIALIZED: {\n                        return DEFAULT_INSTANCE;\n                    }\n                    case MAKE_IMMUTABLE: {\n                        return null;\n                    }\n                    case NEW_BUILDER: {\n                        return new Builder();\n                    }\n                    case VISIT: {\n                        Visitor visitor = (Visitor)arg0;\n                        Symbol other = (Symbol)arg1;\n                        resourceName_ = visitor.visitString(hasResourceName(),\n                            resourceName_,\n                            other.hasResourceName(),\n                            other.resourceName_);\n                        source_ = visitor.visitMessage(source_, other.source_);\n                        if (visitor == MergeFromVisitor.INSTANCE) {\n                            bitField0_ |= other.bitField0_;\n                        }\n                        return this;\n                    }\n                    case MERGE_FROM_STREAM: {\n                        com.google.protobuf.CodedInputStream input = (com.google.protobuf.CodedInputStream)arg0;\n                        com.google.protobuf.ExtensionRegistryLite extensionRegistry\n                            = (com.google.protobuf.ExtensionRegistryLite)arg1;\n                        try {\n                            boolean done = false;\n                            while (!done) {\n                                int tag = input.readTag();\n                                switch (tag) {\n                                    case 0:\n                                        done = true;\n                                        break;\n                                    default: {\n                                        if (!parseUnknownField(tag, input)) {\n                                            done = true;\n                                        }\n                                        break;\n                                    }\n                                    case 10: {\n                                        String s = input.readString();\n                                        bitField0_ |= 0x00000001;\n                                        resourceName_ = s;\n                                        break;\n                                    }\n                                    case 18: {\n                                        com.android.aapt.Resources.SourcePosition.Builder subBuilder = null;\n                                        if (((bitField0_ & 0x00000002) == 0x00000002)) {\n                                            subBuilder = source_.toBuilder();\n                                        }\n                                        source_ = input.readMessage(com.android.aapt.Resources.SourcePosition.parser(),\n                                            extensionRegistry);\n                                        if (subBuilder != null) {\n                                            subBuilder.mergeFrom(source_);\n                                            source_ = subBuilder.buildPartial();\n                                        }\n                                        bitField0_ |= 0x00000002;\n                                        break;\n                                    }\n                                }\n                            }\n                        } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n                            throw new RuntimeException(e.setUnfinishedMessage(this));\n                        } catch (java.io.IOException e) {\n                            throw new RuntimeException(new com.google.protobuf.InvalidProtocolBufferException(e.getMessage())\n                                .setUnfinishedMessage(this));\n                        } finally {\n                        }\n                    }\n                    case GET_DEFAULT_INSTANCE: {\n                        return DEFAULT_INSTANCE;\n                    }\n                    case GET_PARSER: {\n                        if (PARSER == null) {\n                            synchronized (Symbol.class) {\n                                if (PARSER == null) {\n                                    PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n                                }\n                            }\n                        }\n                        return PARSER;\n                    }\n                }\n                throw new UnsupportedOperationException();\n            }\n\n            // @@protoc_insertion_point(class_scope:aapt.pb.internal.CompiledFile.Symbol)\n            private static final Symbol DEFAULT_INSTANCE;\n\n            static {\n                DEFAULT_INSTANCE = new Symbol();\n                DEFAULT_INSTANCE.makeImmutable();\n            }\n\n            public static Symbol getDefaultInstance() {\n                return DEFAULT_INSTANCE;\n            }\n\n            private static volatile com.google.protobuf.Parser<Symbol> PARSER;\n\n            public static com.google.protobuf.Parser<Symbol> parser() {\n                return DEFAULT_INSTANCE.getParserForType();\n            }\n        }\n\n        private int bitField0_;\n\n        public static final int RESOURCE_NAME_FIELD_NUMBER = 1;\n\n        private String resourceName_;\n\n        /**\n         * <pre>\n         * The name of the resource (in the form package:type/name).\n         * </pre>\n         *\n         * <code>optional string resource_name = 1;</code>\n         */\n        @Override\n        public boolean hasResourceName() {\n            return ((bitField0_ & 0x00000001) == 0x00000001);\n        }\n\n        /**\n         * <pre>\n         * The name of the resource (in the form package:type/name).\n         * </pre>\n         *\n         * <code>optional string resource_name = 1;</code>\n         */\n        @Override\n        public String getResourceName() {\n            return resourceName_;\n        }\n\n        /**\n         * <pre>\n         * The name of the resource (in the form package:type/name).\n         * </pre>\n         *\n         * <code>optional string resource_name = 1;</code>\n         */\n        @Override\n        public com.google.protobuf.ByteString getResourceNameBytes() {\n            return com.google.protobuf.ByteString.copyFromUtf8(resourceName_);\n        }\n\n        /**\n         * <pre>\n         * The name of the resource (in the form package:type/name).\n         * </pre>\n         *\n         * <code>optional string resource_name = 1;</code>\n         */\n        private void setResourceName(String value) {\n            if (value == null) {\n                throw new NullPointerException();\n            }\n            bitField0_ |= 0x00000001;\n            resourceName_ = value;\n        }\n\n        /**\n         * <pre>\n         * The name of the resource (in the form package:type/name).\n         * </pre>\n         *\n         * <code>optional string resource_name = 1;</code>\n         */\n        private void clearResourceName() {\n            bitField0_ = (bitField0_ & ~0x00000001);\n            resourceName_ = getDefaultInstance().getResourceName();\n        }\n\n        /**\n         * <pre>\n         * The name of the resource (in the form package:type/name).\n         * </pre>\n         *\n         * <code>optional string resource_name = 1;</code>\n         */\n        private void setResourceNameBytes(com.google.protobuf.ByteString value) {\n            if (value == null) {\n                throw new NullPointerException();\n            }\n            bitField0_ |= 0x00000001;\n            resourceName_ = value.toStringUtf8();\n        }\n\n        public static final int CONFIG_FIELD_NUMBER = 2;\n\n        private com.android.aapt.Resources.ConfigDescription config_;\n\n        /**\n         * <pre>\n         * The configuration for which the resource is defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.ConfigDescription config = 2;</code>\n         */\n        @Override\n        public boolean hasConfig() {\n            return ((bitField0_ & 0x00000002) == 0x00000002);\n        }\n\n        /**\n         * <pre>\n         * The configuration for which the resource is defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.ConfigDescription config = 2;</code>\n         */\n        @Override\n        public com.android.aapt.Resources.ConfigDescription getConfig() {\n            return config_ == null ? com.android.aapt.Resources.ConfigDescription.getDefaultInstance() : config_;\n        }\n\n        /**\n         * <pre>\n         * The configuration for which the resource is defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.ConfigDescription config = 2;</code>\n         */\n        private void setConfig(com.android.aapt.Resources.ConfigDescription value) {\n            if (value == null) {\n                throw new NullPointerException();\n            }\n            config_ = value;\n            bitField0_ |= 0x00000002;\n        }\n\n        /**\n         * <pre>\n         * The configuration for which the resource is defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.ConfigDescription config = 2;</code>\n         */\n        private void setConfig(com.android.aapt.Resources.ConfigDescription.Builder builderForValue) {\n            config_ = builderForValue.build();\n            bitField0_ |= 0x00000002;\n        }\n\n        /**\n         * <pre>\n         * The configuration for which the resource is defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.ConfigDescription config = 2;</code>\n         */\n        private void mergeConfig(com.android.aapt.Resources.ConfigDescription value) {\n            if (config_ != null && config_ != com.android.aapt.Resources.ConfigDescription.getDefaultInstance()) {\n                config_ = com.android.aapt.Resources.ConfigDescription.newBuilder(config_)\n                    .mergeFrom(value)\n                    .buildPartial();\n            } else {\n                config_ = value;\n            }\n            bitField0_ |= 0x00000002;\n        }\n\n        /**\n         * <pre>\n         * The configuration for which the resource is defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.ConfigDescription config = 2;</code>\n         */\n        private void clearConfig() {\n            config_ = null;\n            bitField0_ = (bitField0_ & ~0x00000002);\n        }\n\n        public static final int SOURCE_PATH_FIELD_NUMBER = 3;\n\n        private String sourcePath_;\n\n        /**\n         * <pre>\n         * The filesystem path to where the source file originated.\n         * Mainly used to display helpful error messages.\n         * </pre>\n         *\n         * <code>optional string source_path = 3;</code>\n         */\n        @Override\n        public boolean hasSourcePath() {\n            return ((bitField0_ & 0x00000004) == 0x00000004);\n        }\n\n        /**\n         * <pre>\n         * The filesystem path to where the source file originated.\n         * Mainly used to display helpful error messages.\n         * </pre>\n         *\n         * <code>optional string source_path = 3;</code>\n         */\n        @Override\n        public String getSourcePath() {\n            return sourcePath_;\n        }\n\n        /**\n         * <pre>\n         * The filesystem path to where the source file originated.\n         * Mainly used to display helpful error messages.\n         * </pre>\n         *\n         * <code>optional string source_path = 3;</code>\n         */\n        @Override\n        public com.google.protobuf.ByteString getSourcePathBytes() {\n            return com.google.protobuf.ByteString.copyFromUtf8(sourcePath_);\n        }\n\n        /**\n         * <pre>\n         * The filesystem path to where the source file originated.\n         * Mainly used to display helpful error messages.\n         * </pre>\n         *\n         * <code>optional string source_path = 3;</code>\n         */\n        private void setSourcePath(String value) {\n            if (value == null) {\n                throw new NullPointerException();\n            }\n            bitField0_ |= 0x00000004;\n            sourcePath_ = value;\n        }\n\n        /**\n         * <pre>\n         * The filesystem path to where the source file originated.\n         * Mainly used to display helpful error messages.\n         * </pre>\n         *\n         * <code>optional string source_path = 3;</code>\n         */\n        private void clearSourcePath() {\n            bitField0_ = (bitField0_ & ~0x00000004);\n            sourcePath_ = getDefaultInstance().getSourcePath();\n        }\n\n        /**\n         * <pre>\n         * The filesystem path to where the source file originated.\n         * Mainly used to display helpful error messages.\n         * </pre>\n         *\n         * <code>optional string source_path = 3;</code>\n         */\n        private void setSourcePathBytes(com.google.protobuf.ByteString value) {\n            if (value == null) {\n                throw new NullPointerException();\n            }\n            bitField0_ |= 0x00000004;\n            sourcePath_ = value.toStringUtf8();\n        }\n\n        public static final int EXPORTED_SYMBOL_FIELD_NUMBER = 4;\n\n        private com.google.protobuf.Internal.ProtobufList<Symbol> exportedSymbol_;\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        @Override\n        public java.util.List<Symbol> getExportedSymbolList() {\n            return exportedSymbol_;\n        }\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        public java.util.List<? extends SymbolOrBuilder> getExportedSymbolOrBuilderList() {\n            return exportedSymbol_;\n        }\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        @Override\n        public int getExportedSymbolCount() {\n            return exportedSymbol_.size();\n        }\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        @Override\n        public Symbol getExportedSymbol(int index) {\n            return exportedSymbol_.get(index);\n        }\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        public SymbolOrBuilder getExportedSymbolOrBuilder(int index) {\n            return exportedSymbol_.get(index);\n        }\n\n        private void ensureExportedSymbolIsMutable() {\n            if (!exportedSymbol_.isModifiable()) {\n                exportedSymbol_ = com.google.protobuf.GeneratedMessageLite.mutableCopy(exportedSymbol_);\n            }\n        }\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        private void setExportedSymbol(int index, Symbol value) {\n            if (value == null) {\n                throw new NullPointerException();\n            }\n            ensureExportedSymbolIsMutable();\n            exportedSymbol_.set(index, value);\n        }\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        private void setExportedSymbol(int index, Symbol.Builder builderForValue) {\n            ensureExportedSymbolIsMutable();\n            exportedSymbol_.set(index, builderForValue.build());\n        }\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        private void addExportedSymbol(Symbol value) {\n            if (value == null) {\n                throw new NullPointerException();\n            }\n            ensureExportedSymbolIsMutable();\n            exportedSymbol_.add(value);\n        }\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        private void addExportedSymbol(int index, Symbol value) {\n            if (value == null) {\n                throw new NullPointerException();\n            }\n            ensureExportedSymbolIsMutable();\n            exportedSymbol_.add(index, value);\n        }\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        private void addExportedSymbol(Symbol.Builder builderForValue) {\n            ensureExportedSymbolIsMutable();\n            exportedSymbol_.add(builderForValue.build());\n        }\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        private void addExportedSymbol(int index, Symbol.Builder builderForValue) {\n            ensureExportedSymbolIsMutable();\n            exportedSymbol_.add(index, builderForValue.build());\n        }\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        private void addAllExportedSymbol(Iterable<? extends Symbol> values) {\n            ensureExportedSymbolIsMutable();\n            com.google.protobuf.AbstractMessageLite.addAll(values, exportedSymbol_);\n        }\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        private void clearExportedSymbol() {\n            exportedSymbol_ = emptyProtobufList();\n        }\n\n        /**\n         * <pre>\n         * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n         * </pre>\n         *\n         * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n         */\n        private void removeExportedSymbol(int index) {\n            ensureExportedSymbolIsMutable();\n            exportedSymbol_.remove(index);\n        }\n\n        public static final int XML_ROOT_FIELD_NUMBER = 5;\n\n        private com.android.aapt.Resources.XmlNode xmlRoot_;\n\n        /**\n         * <pre>\n         * If this is a compiled XML file, this is the root node.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.XmlNode xml_root = 5;</code>\n         */\n        @Override\n        public boolean hasXmlRoot() {\n            return ((bitField0_ & 0x00000008) == 0x00000008);\n        }\n\n        /**\n         * <pre>\n         * If this is a compiled XML file, this is the root node.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.XmlNode xml_root = 5;</code>\n         */\n        @Override\n        public com.android.aapt.Resources.XmlNode getXmlRoot() {\n            return xmlRoot_ == null ? com.android.aapt.Resources.XmlNode.getDefaultInstance() : xmlRoot_;\n        }\n\n        /**\n         * <pre>\n         * If this is a compiled XML file, this is the root node.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.XmlNode xml_root = 5;</code>\n         */\n        private void setXmlRoot(com.android.aapt.Resources.XmlNode value) {\n            if (value == null) {\n                throw new NullPointerException();\n            }\n            xmlRoot_ = value;\n            bitField0_ |= 0x00000008;\n        }\n\n        /**\n         * <pre>\n         * If this is a compiled XML file, this is the root node.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.XmlNode xml_root = 5;</code>\n         */\n        private void setXmlRoot(com.android.aapt.Resources.XmlNode.Builder builderForValue) {\n            xmlRoot_ = builderForValue.build();\n            bitField0_ |= 0x00000008;\n        }\n\n        /**\n         * <pre>\n         * If this is a compiled XML file, this is the root node.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.XmlNode xml_root = 5;</code>\n         */\n        private void mergeXmlRoot(com.android.aapt.Resources.XmlNode value) {\n            if (xmlRoot_ != null && xmlRoot_ != com.android.aapt.Resources.XmlNode.getDefaultInstance()) {\n                xmlRoot_ = com.android.aapt.Resources.XmlNode.newBuilder(xmlRoot_).mergeFrom(value).buildPartial();\n            } else {\n                xmlRoot_ = value;\n            }\n            bitField0_ |= 0x00000008;\n        }\n\n        /**\n         * <pre>\n         * If this is a compiled XML file, this is the root node.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.XmlNode xml_root = 5;</code>\n         */\n        private void clearXmlRoot() {\n            xmlRoot_ = null;\n            bitField0_ = (bitField0_ & ~0x00000008);\n        }\n\n        @Override\n        public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {\n            if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                output.writeString(1, getResourceName());\n            }\n            if (((bitField0_ & 0x00000002) == 0x00000002)) {\n                output.writeMessage(2, getConfig());\n            }\n            if (((bitField0_ & 0x00000004) == 0x00000004)) {\n                output.writeString(3, getSourcePath());\n            }\n            for (int i = 0; i < exportedSymbol_.size(); i++) {\n                output.writeMessage(4, exportedSymbol_.get(i));\n            }\n            if (((bitField0_ & 0x00000008) == 0x00000008)) {\n                output.writeMessage(5, getXmlRoot());\n            }\n            unknownFields.writeTo(output);\n        }\n\n        @Override\n        public int getSerializedSize() {\n            int size = memoizedSerializedSize;\n            if (size != -1) {\n                return size;\n            }\n\n            size = 0;\n            if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                size += com.google.protobuf.CodedOutputStream.computeStringSize(1, getResourceName());\n            }\n            if (((bitField0_ & 0x00000002) == 0x00000002)) {\n                size += com.google.protobuf.CodedOutputStream.computeMessageSize(2, getConfig());\n            }\n            if (((bitField0_ & 0x00000004) == 0x00000004)) {\n                size += com.google.protobuf.CodedOutputStream.computeStringSize(3, getSourcePath());\n            }\n            for (int i = 0; i < exportedSymbol_.size(); i++) {\n                size += com.google.protobuf.CodedOutputStream.computeMessageSize(4, exportedSymbol_.get(i));\n            }\n            if (((bitField0_ & 0x00000008) == 0x00000008)) {\n                size += com.google.protobuf.CodedOutputStream.computeMessageSize(5, getXmlRoot());\n            }\n            size += unknownFields.getSerializedSize();\n            memoizedSerializedSize = size;\n            return size;\n        }\n\n        public static CompiledFile parseFrom(com.google.protobuf.ByteString data)\n            throws com.google.protobuf.InvalidProtocolBufferException {\n            return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, data);\n        }\n\n        public static CompiledFile parseFrom(com.google.protobuf.ByteString data,\n                                             com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n            throws com.google.protobuf.InvalidProtocolBufferException {\n            return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, data, extensionRegistry);\n        }\n\n        public static CompiledFile parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException {\n            return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, data);\n        }\n\n        public static CompiledFile parseFrom(byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n            throws com.google.protobuf.InvalidProtocolBufferException {\n            return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, data, extensionRegistry);\n        }\n\n        public static CompiledFile parseFrom(java.io.InputStream input) throws java.io.IOException {\n            return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, input);\n        }\n\n        public static CompiledFile parseFrom(java.io.InputStream input,\n                                             com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n            throws java.io.IOException {\n            return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n        }\n\n        public static CompiledFile parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException {\n            return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n        }\n\n        public static CompiledFile parseDelimitedFrom(java.io.InputStream input,\n                                                      com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n            throws java.io.IOException {\n            return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n        }\n\n        public static CompiledFile parseFrom(com.google.protobuf.CodedInputStream input) throws java.io.IOException {\n            return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, input);\n        }\n\n        public static CompiledFile parseFrom(com.google.protobuf.CodedInputStream input,\n                                             com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n            throws java.io.IOException {\n            return com.google.protobuf.GeneratedMessageLite.parseFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n        }\n\n        public static Builder newBuilder() {\n            return DEFAULT_INSTANCE.toBuilder();\n        }\n\n        public static Builder newBuilder(CompiledFile prototype) {\n            return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n        }\n\n        /**\n         * <pre>\n         * The top level message representing an external resource file (layout XML, PNG, etc).\n         * This is used to represent a compiled file before it is linked. Only useful to aapt2.\n         * </pre>\n         *\n         * Protobuf type {@code aapt.pb.internal.CompiledFile}\n         */\n        public static final class Builder\n            extends com.google.protobuf.GeneratedMessageLite.Builder<CompiledFile, Builder> implements\n            // @@protoc_insertion_point(builder_implements:aapt.pb.internal.CompiledFile)\n            CompiledFileOrBuilder {\n            // Construct using android.aapt.pb.internal.ResourcesInternal.CompiledFile.newBuilder()\n            private Builder() {\n                super(DEFAULT_INSTANCE);\n            }\n\n            /**\n             * <pre>\n             * The name of the resource (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            @Override\n            public boolean hasResourceName() {\n                return instance.hasResourceName();\n            }\n\n            /**\n             * <pre>\n             * The name of the resource (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            @Override\n            public String getResourceName() {\n                return instance.getResourceName();\n            }\n\n            /**\n             * <pre>\n             * The name of the resource (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            @Override\n            public com.google.protobuf.ByteString getResourceNameBytes() {\n                return instance.getResourceNameBytes();\n            }\n\n            /**\n             * <pre>\n             * The name of the resource (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            public Builder setResourceName(String value) {\n                copyOnWrite();\n                instance.setResourceName(value);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * The name of the resource (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            public Builder clearResourceName() {\n                copyOnWrite();\n                instance.clearResourceName();\n                return this;\n            }\n\n            /**\n             * <pre>\n             * The name of the resource (in the form package:type/name).\n             * </pre>\n             *\n             * <code>optional string resource_name = 1;</code>\n             */\n            public Builder setResourceNameBytes(com.google.protobuf.ByteString value) {\n                copyOnWrite();\n                instance.setResourceNameBytes(value);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * The configuration for which the resource is defined.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.ConfigDescription config = 2;</code>\n             */\n            @Override\n            public boolean hasConfig() {\n                return instance.hasConfig();\n            }\n\n            /**\n             * <pre>\n             * The configuration for which the resource is defined.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.ConfigDescription config = 2;</code>\n             */\n            @Override\n            public com.android.aapt.Resources.ConfigDescription getConfig() {\n                return instance.getConfig();\n            }\n\n            /**\n             * <pre>\n             * The configuration for which the resource is defined.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.ConfigDescription config = 2;</code>\n             */\n            public Builder setConfig(com.android.aapt.Resources.ConfigDescription value) {\n                copyOnWrite();\n                instance.setConfig(value);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * The configuration for which the resource is defined.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.ConfigDescription config = 2;</code>\n             */\n            public Builder setConfig(com.android.aapt.Resources.ConfigDescription.Builder builderForValue) {\n                copyOnWrite();\n                instance.setConfig(builderForValue);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * The configuration for which the resource is defined.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.ConfigDescription config = 2;</code>\n             */\n            public Builder mergeConfig(com.android.aapt.Resources.ConfigDescription value) {\n                copyOnWrite();\n                instance.mergeConfig(value);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * The configuration for which the resource is defined.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.ConfigDescription config = 2;</code>\n             */\n            public Builder clearConfig() {\n                copyOnWrite();\n                instance.clearConfig();\n                return this;\n            }\n\n            /**\n             * <pre>\n             * The filesystem path to where the source file originated.\n             * Mainly used to display helpful error messages.\n             * </pre>\n             *\n             * <code>optional string source_path = 3;</code>\n             */\n            @Override\n            public boolean hasSourcePath() {\n                return instance.hasSourcePath();\n            }\n\n            /**\n             * <pre>\n             * The filesystem path to where the source file originated.\n             * Mainly used to display helpful error messages.\n             * </pre>\n             *\n             * <code>optional string source_path = 3;</code>\n             */\n            @Override\n            public String getSourcePath() {\n                return instance.getSourcePath();\n            }\n\n            /**\n             * <pre>\n             * The filesystem path to where the source file originated.\n             * Mainly used to display helpful error messages.\n             * </pre>\n             *\n             * <code>optional string source_path = 3;</code>\n             */\n            @Override\n            public com.google.protobuf.ByteString getSourcePathBytes() {\n                return instance.getSourcePathBytes();\n            }\n\n            /**\n             * <pre>\n             * The filesystem path to where the source file originated.\n             * Mainly used to display helpful error messages.\n             * </pre>\n             *\n             * <code>optional string source_path = 3;</code>\n             */\n            public Builder setSourcePath(String value) {\n                copyOnWrite();\n                instance.setSourcePath(value);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * The filesystem path to where the source file originated.\n             * Mainly used to display helpful error messages.\n             * </pre>\n             *\n             * <code>optional string source_path = 3;</code>\n             */\n            public Builder clearSourcePath() {\n                copyOnWrite();\n                instance.clearSourcePath();\n                return this;\n            }\n\n            /**\n             * <pre>\n             * The filesystem path to where the source file originated.\n             * Mainly used to display helpful error messages.\n             * </pre>\n             *\n             * <code>optional string source_path = 3;</code>\n             */\n            public Builder setSourcePathBytes(com.google.protobuf.ByteString value) {\n                copyOnWrite();\n                instance.setSourcePathBytes(value);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n             * </pre>\n             *\n             * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n             */\n            @Override\n            public java.util.List<Symbol> getExportedSymbolList() {\n                return java.util.Collections.unmodifiableList(instance.getExportedSymbolList());\n            }\n\n            /**\n             * <pre>\n             * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n             * </pre>\n             *\n             * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n             */\n            @Override\n            public int getExportedSymbolCount() {\n                return instance.getExportedSymbolCount();\n            }\n\n            /**\n             * <pre>\n             * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n             * </pre>\n             *\n             * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n             */\n            @Override\n            public Symbol getExportedSymbol(int index) {\n                return instance.getExportedSymbol(index);\n            }\n\n            /**\n             * <pre>\n             * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n             * </pre>\n             *\n             * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n             */\n            public Builder setExportedSymbol(int index, Symbol value) {\n                copyOnWrite();\n                instance.setExportedSymbol(index, value);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n             * </pre>\n             *\n             * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n             */\n            public Builder setExportedSymbol(int index, Symbol.Builder builderForValue) {\n                copyOnWrite();\n                instance.setExportedSymbol(index, builderForValue);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n             * </pre>\n             *\n             * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n             */\n            public Builder addExportedSymbol(Symbol value) {\n                copyOnWrite();\n                instance.addExportedSymbol(value);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n             * </pre>\n             *\n             * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n             */\n            public Builder addExportedSymbol(int index, Symbol value) {\n                copyOnWrite();\n                instance.addExportedSymbol(index, value);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n             * </pre>\n             *\n             * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n             */\n            public Builder addExportedSymbol(Symbol.Builder builderForValue) {\n                copyOnWrite();\n                instance.addExportedSymbol(builderForValue);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n             * </pre>\n             *\n             * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n             */\n            public Builder addExportedSymbol(int index, Symbol.Builder builderForValue) {\n                copyOnWrite();\n                instance.addExportedSymbol(index, builderForValue);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n             * </pre>\n             *\n             * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n             */\n            public Builder addAllExportedSymbol(Iterable<? extends Symbol> values) {\n                copyOnWrite();\n                instance.addAllExportedSymbol(values);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n             * </pre>\n             *\n             * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n             */\n            public Builder clearExportedSymbol() {\n                copyOnWrite();\n                instance.clearExportedSymbol();\n                return this;\n            }\n\n            /**\n             * <pre>\n             * Any symbols this file auto-generates/exports (eg. &#64;+id/foo in an XML file).\n             * </pre>\n             *\n             * <code>repeated .aapt.pb.internal.CompiledFile.Symbol exported_symbol = 4;</code>\n             */\n            public Builder removeExportedSymbol(int index) {\n                copyOnWrite();\n                instance.removeExportedSymbol(index);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * If this is a compiled XML file, this is the root node.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.XmlNode xml_root = 5;</code>\n             */\n            @Override\n            public boolean hasXmlRoot() {\n                return instance.hasXmlRoot();\n            }\n\n            /**\n             * <pre>\n             * If this is a compiled XML file, this is the root node.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.XmlNode xml_root = 5;</code>\n             */\n            @Override\n            public com.android.aapt.Resources.XmlNode getXmlRoot() {\n                return instance.getXmlRoot();\n            }\n\n            /**\n             * <pre>\n             * If this is a compiled XML file, this is the root node.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.XmlNode xml_root = 5;</code>\n             */\n            public Builder setXmlRoot(com.android.aapt.Resources.XmlNode value) {\n                copyOnWrite();\n                instance.setXmlRoot(value);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * If this is a compiled XML file, this is the root node.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.XmlNode xml_root = 5;</code>\n             */\n            public Builder setXmlRoot(com.android.aapt.Resources.XmlNode.Builder builderForValue) {\n                copyOnWrite();\n                instance.setXmlRoot(builderForValue);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * If this is a compiled XML file, this is the root node.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.XmlNode xml_root = 5;</code>\n             */\n            public Builder mergeXmlRoot(com.android.aapt.Resources.XmlNode value) {\n                copyOnWrite();\n                instance.mergeXmlRoot(value);\n                return this;\n            }\n\n            /**\n             * <pre>\n             * If this is a compiled XML file, this is the root node.\n             * </pre>\n             *\n             * <code>optional .aapt.pb.XmlNode xml_root = 5;</code>\n             */\n            public Builder clearXmlRoot() {\n                copyOnWrite();\n                instance.clearXmlRoot();\n                return this;\n            }\n\n            // @@protoc_insertion_point(builder_scope:aapt.pb.internal.CompiledFile)\n        }\n\n        @Override\n        protected final Object dynamicMethod(MethodToInvoke method, Object arg0, Object arg1) {\n            switch (method) {\n                case NEW_MUTABLE_INSTANCE: {\n                    return new CompiledFile();\n                }\n                case IS_INITIALIZED: {\n                    return DEFAULT_INSTANCE;\n                }\n                case MAKE_IMMUTABLE: {\n                    exportedSymbol_.makeImmutable();\n                    return null;\n                }\n                case NEW_BUILDER: {\n                    return new Builder();\n                }\n                case VISIT: {\n                    Visitor visitor = (Visitor)arg0;\n                    CompiledFile other = (CompiledFile)arg1;\n                    resourceName_ = visitor.visitString(hasResourceName(),\n                        resourceName_,\n                        other.hasResourceName(),\n                        other.resourceName_);\n                    config_ = visitor.visitMessage(config_, other.config_);\n                    sourcePath_ = visitor.visitString(hasSourcePath(),\n                        sourcePath_,\n                        other.hasSourcePath(),\n                        other.sourcePath_);\n                    exportedSymbol_ = visitor.visitList(exportedSymbol_, other.exportedSymbol_);\n                    xmlRoot_ = visitor.visitMessage(xmlRoot_, other.xmlRoot_);\n                    if (visitor == MergeFromVisitor.INSTANCE) {\n                        bitField0_ |= other.bitField0_;\n                    }\n                    return this;\n                }\n                case MERGE_FROM_STREAM: {\n                    com.google.protobuf.CodedInputStream input = (com.google.protobuf.CodedInputStream)arg0;\n                    com.google.protobuf.ExtensionRegistryLite extensionRegistry\n                        = (com.google.protobuf.ExtensionRegistryLite)arg1;\n                    try {\n                        boolean done = false;\n                        while (!done) {\n                            int tag = input.readTag();\n                            switch (tag) {\n                                case 0:\n                                    done = true;\n                                    break;\n                                default: {\n                                    if (!parseUnknownField(tag, input)) {\n                                        done = true;\n                                    }\n                                    break;\n                                }\n                                case 10: {\n                                    String s = input.readString();\n                                    bitField0_ |= 0x00000001;\n                                    resourceName_ = s;\n                                    break;\n                                }\n                                case 18: {\n                                    com.android.aapt.Resources.ConfigDescription.Builder subBuilder = null;\n                                    if (((bitField0_ & 0x00000002) == 0x00000002)) {\n                                        subBuilder = config_.toBuilder();\n                                    }\n                                    config_ = input.readMessage(com.android.aapt.Resources.ConfigDescription.parser(),\n                                        extensionRegistry);\n                                    if (subBuilder != null) {\n                                        subBuilder.mergeFrom(config_);\n                                        config_ = subBuilder.buildPartial();\n                                    }\n                                    bitField0_ |= 0x00000002;\n                                    break;\n                                }\n                                case 26: {\n                                    String s = input.readString();\n                                    bitField0_ |= 0x00000004;\n                                    sourcePath_ = s;\n                                    break;\n                                }\n                                case 34: {\n                                    if (!exportedSymbol_.isModifiable()) {\n                                        exportedSymbol_ = com.google.protobuf.GeneratedMessageLite.mutableCopy(\n                                            exportedSymbol_);\n                                    }\n                                    exportedSymbol_.add(input.readMessage(Symbol.parser(), extensionRegistry));\n                                    break;\n                                }\n                                case 42: {\n                                    com.android.aapt.Resources.XmlNode.Builder subBuilder = null;\n                                    if (((bitField0_ & 0x00000008) == 0x00000008)) {\n                                        subBuilder = xmlRoot_.toBuilder();\n                                    }\n                                    xmlRoot_ = input.readMessage(com.android.aapt.Resources.XmlNode.parser(),\n                                        extensionRegistry);\n                                    if (subBuilder != null) {\n                                        subBuilder.mergeFrom(xmlRoot_);\n                                        xmlRoot_ = subBuilder.buildPartial();\n                                    }\n                                    bitField0_ |= 0x00000008;\n                                    break;\n                                }\n                            }\n                        }\n                    } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n                        throw new RuntimeException(e.setUnfinishedMessage(this));\n                    } catch (java.io.IOException e) {\n                        throw new RuntimeException(new com.google.protobuf.InvalidProtocolBufferException(e.getMessage())\n                            .setUnfinishedMessage(this));\n                    } finally {\n                    }\n                }\n                case GET_DEFAULT_INSTANCE: {\n                    return DEFAULT_INSTANCE;\n                }\n                case GET_PARSER: {\n                    if (PARSER == null) {\n                        synchronized (CompiledFile.class) {\n                            if (PARSER == null) {\n                                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n                            }\n                        }\n                    }\n                    return PARSER;\n                }\n            }\n            throw new UnsupportedOperationException();\n        }\n\n        // @@protoc_insertion_point(class_scope:aapt.pb.internal.CompiledFile)\n        private static final CompiledFile DEFAULT_INSTANCE;\n\n        static {\n            DEFAULT_INSTANCE = new CompiledFile();\n            DEFAULT_INSTANCE.makeImmutable();\n        }\n\n        public static CompiledFile getDefaultInstance() {\n            return DEFAULT_INSTANCE;\n        }\n\n        private static volatile com.google.protobuf.Parser<CompiledFile> PARSER;\n\n        public static com.google.protobuf.Parser<CompiledFile> parser() {\n            return DEFAULT_INSTANCE.getParserForType();\n        }\n    }\n\n    static {\n    }\n\n    // @@protoc_insertion_point(outer_class_scope)\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/aapt/Resources.java",
    "content": "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n// source: frameworks/base/tools/aapt2/Resources.proto\n\npackage com.android.aapt;\n\npublic final class Resources {\n  private Resources() {}\n  public static void registerAllExtensions(\n      com.google.protobuf.ExtensionRegistryLite registry) {\n  }\n  public interface ConfigDescriptionOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.ConfigDescription)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <code>optional bytes data = 1;</code>\n     */\n    boolean hasData();\n    /**\n     * <code>optional bytes data = 1;</code>\n     */\n    com.google.protobuf.ByteString getData();\n\n    /**\n     * <code>optional string product = 2;</code>\n     */\n    boolean hasProduct();\n    /**\n     * <code>optional string product = 2;</code>\n     */\n    java.lang.String getProduct();\n    /**\n     * <code>optional string product = 2;</code>\n     */\n    com.google.protobuf.ByteString\n        getProductBytes();\n  }\n  /**\n   * <pre>\n   * A configuration description that wraps the binary form of the C++ class\n   * aapt::ConfigDescription, with an added product definition.\n   * TODO(adamlesinski): Flesh this out to be represented in proto.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.ConfigDescription}\n   */\n  public  static final class ConfigDescription extends\n      com.google.protobuf.GeneratedMessageLite<\n          ConfigDescription, ConfigDescription.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.ConfigDescription)\n      ConfigDescriptionOrBuilder {\n    private ConfigDescription() {\n      data_ = com.google.protobuf.ByteString.EMPTY;\n      product_ = \"\";\n    }\n    private int bitField0_;\n    public static final int DATA_FIELD_NUMBER = 1;\n    private com.google.protobuf.ByteString data_;\n    /**\n     * <code>optional bytes data = 1;</code>\n     */\n    public boolean hasData() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <code>optional bytes data = 1;</code>\n     */\n    public com.google.protobuf.ByteString getData() {\n      return data_;\n    }\n    /**\n     * <code>optional bytes data = 1;</code>\n     */\n    private void setData(com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      data_ = value;\n    }\n    /**\n     * <code>optional bytes data = 1;</code>\n     */\n    private void clearData() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      data_ = getDefaultInstance().getData();\n    }\n\n    public static final int PRODUCT_FIELD_NUMBER = 2;\n    private java.lang.String product_;\n    /**\n     * <code>optional string product = 2;</code>\n     */\n    public boolean hasProduct() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <code>optional string product = 2;</code>\n     */\n    public java.lang.String getProduct() {\n      return product_;\n    }\n    /**\n     * <code>optional string product = 2;</code>\n     */\n    public com.google.protobuf.ByteString\n        getProductBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(product_);\n    }\n    /**\n     * <code>optional string product = 2;</code>\n     */\n    private void setProduct(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      product_ = value;\n    }\n    /**\n     * <code>optional string product = 2;</code>\n     */\n    private void clearProduct() {\n      bitField0_ = (bitField0_ & ~0x00000002);\n      product_ = getDefaultInstance().getProduct();\n    }\n    /**\n     * <code>optional string product = 2;</code>\n     */\n    private void setProductBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      product_ = value.toStringUtf8();\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeBytes(1, data_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeString(2, getProduct());\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeBytesSize(1, data_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(2, getProduct());\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.ConfigDescription parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.ConfigDescription parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.ConfigDescription parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.ConfigDescription parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.ConfigDescription parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.ConfigDescription parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.ConfigDescription parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.ConfigDescription parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.ConfigDescription parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.ConfigDescription parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.ConfigDescription prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A configuration description that wraps the binary form of the C++ class\n     * aapt::ConfigDescription, with an added product definition.\n     * TODO(adamlesinski): Flesh this out to be represented in proto.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.ConfigDescription}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.ConfigDescription, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.ConfigDescription)\n        com.android.aapt.Resources.ConfigDescriptionOrBuilder {\n      // Construct using com.android.aapt.Resources.ConfigDescription.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <code>optional bytes data = 1;</code>\n       */\n      public boolean hasData() {\n        return instance.hasData();\n      }\n      /**\n       * <code>optional bytes data = 1;</code>\n       */\n      public com.google.protobuf.ByteString getData() {\n        return instance.getData();\n      }\n      /**\n       * <code>optional bytes data = 1;</code>\n       */\n      public Builder setData(com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setData(value);\n        return this;\n      }\n      /**\n       * <code>optional bytes data = 1;</code>\n       */\n      public Builder clearData() {\n        copyOnWrite();\n        instance.clearData();\n        return this;\n      }\n\n      /**\n       * <code>optional string product = 2;</code>\n       */\n      public boolean hasProduct() {\n        return instance.hasProduct();\n      }\n      /**\n       * <code>optional string product = 2;</code>\n       */\n      public java.lang.String getProduct() {\n        return instance.getProduct();\n      }\n      /**\n       * <code>optional string product = 2;</code>\n       */\n      public com.google.protobuf.ByteString\n          getProductBytes() {\n        return instance.getProductBytes();\n      }\n      /**\n       * <code>optional string product = 2;</code>\n       */\n      public Builder setProduct(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setProduct(value);\n        return this;\n      }\n      /**\n       * <code>optional string product = 2;</code>\n       */\n      public Builder clearProduct() {\n        copyOnWrite();\n        instance.clearProduct();\n        return this;\n      }\n      /**\n       * <code>optional string product = 2;</code>\n       */\n      public Builder setProductBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setProductBytes(value);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.ConfigDescription)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.ConfigDescription();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.ConfigDescription other = (com.android.aapt.Resources.ConfigDescription) arg1;\n          data_ = visitor.visitByteString(\n              hasData(), data_,\n              other.hasData(), other.data_);\n          product_ = visitor.visitString(\n              hasProduct(), product_,\n              other.hasProduct(), other.product_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  bitField0_ |= 0x00000001;\n                  data_ = input.readBytes();\n                  break;\n                }\n                case 18: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000002;\n                  product_ = s;\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.ConfigDescription.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.ConfigDescription)\n    private static final com.android.aapt.Resources.ConfigDescription DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new ConfigDescription();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.ConfigDescription getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<ConfigDescription> PARSER;\n\n    public static com.google.protobuf.Parser<ConfigDescription> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface StringPoolOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.StringPool)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <code>optional bytes data = 1;</code>\n     */\n    boolean hasData();\n    /**\n     * <code>optional bytes data = 1;</code>\n     */\n    com.google.protobuf.ByteString getData();\n  }\n  /**\n   * <pre>\n   * A string pool that wraps the binary form of the C++ class android::ResStringPool.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.StringPool}\n   */\n  public  static final class StringPool extends\n      com.google.protobuf.GeneratedMessageLite<\n          StringPool, StringPool.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.StringPool)\n      StringPoolOrBuilder {\n    private StringPool() {\n      data_ = com.google.protobuf.ByteString.EMPTY;\n    }\n    private int bitField0_;\n    public static final int DATA_FIELD_NUMBER = 1;\n    private com.google.protobuf.ByteString data_;\n    /**\n     * <code>optional bytes data = 1;</code>\n     */\n    public boolean hasData() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <code>optional bytes data = 1;</code>\n     */\n    public com.google.protobuf.ByteString getData() {\n      return data_;\n    }\n    /**\n     * <code>optional bytes data = 1;</code>\n     */\n    private void setData(com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      data_ = value;\n    }\n    /**\n     * <code>optional bytes data = 1;</code>\n     */\n    private void clearData() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      data_ = getDefaultInstance().getData();\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeBytes(1, data_);\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeBytesSize(1, data_);\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.StringPool parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.StringPool parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.StringPool parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.StringPool parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.StringPool parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.StringPool parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.StringPool parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.StringPool parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.StringPool parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.StringPool parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.StringPool prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A string pool that wraps the binary form of the C++ class android::ResStringPool.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.StringPool}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.StringPool, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.StringPool)\n        com.android.aapt.Resources.StringPoolOrBuilder {\n      // Construct using com.android.aapt.Resources.StringPool.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <code>optional bytes data = 1;</code>\n       */\n      public boolean hasData() {\n        return instance.hasData();\n      }\n      /**\n       * <code>optional bytes data = 1;</code>\n       */\n      public com.google.protobuf.ByteString getData() {\n        return instance.getData();\n      }\n      /**\n       * <code>optional bytes data = 1;</code>\n       */\n      public Builder setData(com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setData(value);\n        return this;\n      }\n      /**\n       * <code>optional bytes data = 1;</code>\n       */\n      public Builder clearData() {\n        copyOnWrite();\n        instance.clearData();\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.StringPool)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.StringPool();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.StringPool other = (com.android.aapt.Resources.StringPool) arg1;\n          data_ = visitor.visitByteString(\n              hasData(), data_,\n              other.hasData(), other.data_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  bitField0_ |= 0x00000001;\n                  data_ = input.readBytes();\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.StringPool.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.StringPool)\n    private static final com.android.aapt.Resources.StringPool DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new StringPool();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.StringPool getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<StringPool> PARSER;\n\n    public static com.google.protobuf.Parser<StringPool> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface SourcePositionOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.SourcePosition)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <code>optional uint32 line_number = 1;</code>\n     */\n    boolean hasLineNumber();\n    /**\n     * <code>optional uint32 line_number = 1;</code>\n     */\n    int getLineNumber();\n\n    /**\n     * <code>optional uint32 column_number = 2;</code>\n     */\n    boolean hasColumnNumber();\n    /**\n     * <code>optional uint32 column_number = 2;</code>\n     */\n    int getColumnNumber();\n  }\n  /**\n   * <pre>\n   * The position of a declared entity within a file.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.SourcePosition}\n   */\n  public  static final class SourcePosition extends\n      com.google.protobuf.GeneratedMessageLite<\n          SourcePosition, SourcePosition.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.SourcePosition)\n      SourcePositionOrBuilder {\n    private SourcePosition() {\n    }\n    private int bitField0_;\n    public static final int LINE_NUMBER_FIELD_NUMBER = 1;\n    private int lineNumber_;\n    /**\n     * <code>optional uint32 line_number = 1;</code>\n     */\n    public boolean hasLineNumber() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <code>optional uint32 line_number = 1;</code>\n     */\n    public int getLineNumber() {\n      return lineNumber_;\n    }\n    /**\n     * <code>optional uint32 line_number = 1;</code>\n     */\n    private void setLineNumber(int value) {\n      bitField0_ |= 0x00000001;\n      lineNumber_ = value;\n    }\n    /**\n     * <code>optional uint32 line_number = 1;</code>\n     */\n    private void clearLineNumber() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      lineNumber_ = 0;\n    }\n\n    public static final int COLUMN_NUMBER_FIELD_NUMBER = 2;\n    private int columnNumber_;\n    /**\n     * <code>optional uint32 column_number = 2;</code>\n     */\n    public boolean hasColumnNumber() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <code>optional uint32 column_number = 2;</code>\n     */\n    public int getColumnNumber() {\n      return columnNumber_;\n    }\n    /**\n     * <code>optional uint32 column_number = 2;</code>\n     */\n    private void setColumnNumber(int value) {\n      bitField0_ |= 0x00000002;\n      columnNumber_ = value;\n    }\n    /**\n     * <code>optional uint32 column_number = 2;</code>\n     */\n    private void clearColumnNumber() {\n      bitField0_ = (bitField0_ & ~0x00000002);\n      columnNumber_ = 0;\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeUInt32(1, lineNumber_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeUInt32(2, columnNumber_);\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeUInt32Size(1, lineNumber_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeUInt32Size(2, columnNumber_);\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.SourcePosition parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.SourcePosition parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.SourcePosition parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.SourcePosition parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.SourcePosition parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.SourcePosition parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.SourcePosition parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.SourcePosition parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.SourcePosition parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.SourcePosition parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.SourcePosition prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * The position of a declared entity within a file.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.SourcePosition}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.SourcePosition, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.SourcePosition)\n        com.android.aapt.Resources.SourcePositionOrBuilder {\n      // Construct using com.android.aapt.Resources.SourcePosition.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <code>optional uint32 line_number = 1;</code>\n       */\n      public boolean hasLineNumber() {\n        return instance.hasLineNumber();\n      }\n      /**\n       * <code>optional uint32 line_number = 1;</code>\n       */\n      public int getLineNumber() {\n        return instance.getLineNumber();\n      }\n      /**\n       * <code>optional uint32 line_number = 1;</code>\n       */\n      public Builder setLineNumber(int value) {\n        copyOnWrite();\n        instance.setLineNumber(value);\n        return this;\n      }\n      /**\n       * <code>optional uint32 line_number = 1;</code>\n       */\n      public Builder clearLineNumber() {\n        copyOnWrite();\n        instance.clearLineNumber();\n        return this;\n      }\n\n      /**\n       * <code>optional uint32 column_number = 2;</code>\n       */\n      public boolean hasColumnNumber() {\n        return instance.hasColumnNumber();\n      }\n      /**\n       * <code>optional uint32 column_number = 2;</code>\n       */\n      public int getColumnNumber() {\n        return instance.getColumnNumber();\n      }\n      /**\n       * <code>optional uint32 column_number = 2;</code>\n       */\n      public Builder setColumnNumber(int value) {\n        copyOnWrite();\n        instance.setColumnNumber(value);\n        return this;\n      }\n      /**\n       * <code>optional uint32 column_number = 2;</code>\n       */\n      public Builder clearColumnNumber() {\n        copyOnWrite();\n        instance.clearColumnNumber();\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.SourcePosition)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.SourcePosition();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.SourcePosition other = (com.android.aapt.Resources.SourcePosition) arg1;\n          lineNumber_ = visitor.visitInt(\n              hasLineNumber(), lineNumber_,\n              other.hasLineNumber(), other.lineNumber_);\n          columnNumber_ = visitor.visitInt(\n              hasColumnNumber(), columnNumber_,\n              other.hasColumnNumber(), other.columnNumber_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 8: {\n                  bitField0_ |= 0x00000001;\n                  lineNumber_ = input.readUInt32();\n                  break;\n                }\n                case 16: {\n                  bitField0_ |= 0x00000002;\n                  columnNumber_ = input.readUInt32();\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.SourcePosition.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.SourcePosition)\n    private static final com.android.aapt.Resources.SourcePosition DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new SourcePosition();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.SourcePosition getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<SourcePosition> PARSER;\n\n    public static com.google.protobuf.Parser<SourcePosition> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface SourceOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.Source)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * The index of the string path within the source string pool of a ResourceTable.\n     * </pre>\n     *\n     * <code>optional uint32 path_idx = 1;</code>\n     */\n    boolean hasPathIdx();\n    /**\n     * <pre>\n     * The index of the string path within the source string pool of a ResourceTable.\n     * </pre>\n     *\n     * <code>optional uint32 path_idx = 1;</code>\n     */\n    int getPathIdx();\n\n    /**\n     * <code>optional .aapt.pb.SourcePosition position = 2;</code>\n     */\n    boolean hasPosition();\n    /**\n     * <code>optional .aapt.pb.SourcePosition position = 2;</code>\n     */\n    com.android.aapt.Resources.SourcePosition getPosition();\n  }\n  /**\n   * <pre>\n   * Developer friendly source file information for an entity in the resource table.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.Source}\n   */\n  public  static final class Source extends\n      com.google.protobuf.GeneratedMessageLite<\n          Source, Source.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.Source)\n      SourceOrBuilder {\n    private Source() {\n    }\n    private int bitField0_;\n    public static final int PATH_IDX_FIELD_NUMBER = 1;\n    private int pathIdx_;\n    /**\n     * <pre>\n     * The index of the string path within the source string pool of a ResourceTable.\n     * </pre>\n     *\n     * <code>optional uint32 path_idx = 1;</code>\n     */\n    public boolean hasPathIdx() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <pre>\n     * The index of the string path within the source string pool of a ResourceTable.\n     * </pre>\n     *\n     * <code>optional uint32 path_idx = 1;</code>\n     */\n    public int getPathIdx() {\n      return pathIdx_;\n    }\n    /**\n     * <pre>\n     * The index of the string path within the source string pool of a ResourceTable.\n     * </pre>\n     *\n     * <code>optional uint32 path_idx = 1;</code>\n     */\n    private void setPathIdx(int value) {\n      bitField0_ |= 0x00000001;\n      pathIdx_ = value;\n    }\n    /**\n     * <pre>\n     * The index of the string path within the source string pool of a ResourceTable.\n     * </pre>\n     *\n     * <code>optional uint32 path_idx = 1;</code>\n     */\n    private void clearPathIdx() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      pathIdx_ = 0;\n    }\n\n    public static final int POSITION_FIELD_NUMBER = 2;\n    private com.android.aapt.Resources.SourcePosition position_;\n    /**\n     * <code>optional .aapt.pb.SourcePosition position = 2;</code>\n     */\n    public boolean hasPosition() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <code>optional .aapt.pb.SourcePosition position = 2;</code>\n     */\n    public com.android.aapt.Resources.SourcePosition getPosition() {\n      return position_ == null ? com.android.aapt.Resources.SourcePosition.getDefaultInstance() : position_;\n    }\n    /**\n     * <code>optional .aapt.pb.SourcePosition position = 2;</code>\n     */\n    private void setPosition(com.android.aapt.Resources.SourcePosition value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      position_ = value;\n      bitField0_ |= 0x00000002;\n      }\n    /**\n     * <code>optional .aapt.pb.SourcePosition position = 2;</code>\n     */\n    private void setPosition(\n        com.android.aapt.Resources.SourcePosition.Builder builderForValue) {\n      position_ = builderForValue.build();\n      bitField0_ |= 0x00000002;\n    }\n    /**\n     * <code>optional .aapt.pb.SourcePosition position = 2;</code>\n     */\n    private void mergePosition(com.android.aapt.Resources.SourcePosition value) {\n      if (position_ != null &&\n          position_ != com.android.aapt.Resources.SourcePosition.getDefaultInstance()) {\n        position_ =\n          com.android.aapt.Resources.SourcePosition.newBuilder(position_).mergeFrom(value).buildPartial();\n      } else {\n        position_ = value;\n      }\n      bitField0_ |= 0x00000002;\n    }\n    /**\n     * <code>optional .aapt.pb.SourcePosition position = 2;</code>\n     */\n    private void clearPosition() {  position_ = null;\n      bitField0_ = (bitField0_ & ~0x00000002);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeUInt32(1, pathIdx_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeMessage(2, getPosition());\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeUInt32Size(1, pathIdx_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(2, getPosition());\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.Source parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Source parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Source parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Source parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Source parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Source parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Source parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Source parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Source parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Source parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.Source prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * Developer friendly source file information for an entity in the resource table.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Source}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.Source, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.Source)\n        com.android.aapt.Resources.SourceOrBuilder {\n      // Construct using com.android.aapt.Resources.Source.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * The index of the string path within the source string pool of a ResourceTable.\n       * </pre>\n       *\n       * <code>optional uint32 path_idx = 1;</code>\n       */\n      public boolean hasPathIdx() {\n        return instance.hasPathIdx();\n      }\n      /**\n       * <pre>\n       * The index of the string path within the source string pool of a ResourceTable.\n       * </pre>\n       *\n       * <code>optional uint32 path_idx = 1;</code>\n       */\n      public int getPathIdx() {\n        return instance.getPathIdx();\n      }\n      /**\n       * <pre>\n       * The index of the string path within the source string pool of a ResourceTable.\n       * </pre>\n       *\n       * <code>optional uint32 path_idx = 1;</code>\n       */\n      public Builder setPathIdx(int value) {\n        copyOnWrite();\n        instance.setPathIdx(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The index of the string path within the source string pool of a ResourceTable.\n       * </pre>\n       *\n       * <code>optional uint32 path_idx = 1;</code>\n       */\n      public Builder clearPathIdx() {\n        copyOnWrite();\n        instance.clearPathIdx();\n        return this;\n      }\n\n      /**\n       * <code>optional .aapt.pb.SourcePosition position = 2;</code>\n       */\n      public boolean hasPosition() {\n        return instance.hasPosition();\n      }\n      /**\n       * <code>optional .aapt.pb.SourcePosition position = 2;</code>\n       */\n      public com.android.aapt.Resources.SourcePosition getPosition() {\n        return instance.getPosition();\n      }\n      /**\n       * <code>optional .aapt.pb.SourcePosition position = 2;</code>\n       */\n      public Builder setPosition(com.android.aapt.Resources.SourcePosition value) {\n        copyOnWrite();\n        instance.setPosition(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.SourcePosition position = 2;</code>\n       */\n      public Builder setPosition(\n          com.android.aapt.Resources.SourcePosition.Builder builderForValue) {\n        copyOnWrite();\n        instance.setPosition(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.SourcePosition position = 2;</code>\n       */\n      public Builder mergePosition(com.android.aapt.Resources.SourcePosition value) {\n        copyOnWrite();\n        instance.mergePosition(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.SourcePosition position = 2;</code>\n       */\n      public Builder clearPosition() {  copyOnWrite();\n        instance.clearPosition();\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.Source)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.Source();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.Source other = (com.android.aapt.Resources.Source) arg1;\n          pathIdx_ = visitor.visitInt(\n              hasPathIdx(), pathIdx_,\n              other.hasPathIdx(), other.pathIdx_);\n          position_ = visitor.visitMessage(position_, other.position_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 8: {\n                  bitField0_ |= 0x00000001;\n                  pathIdx_ = input.readUInt32();\n                  break;\n                }\n                case 18: {\n                  com.android.aapt.Resources.SourcePosition.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000002) == 0x00000002)) {\n                    subBuilder = position_.toBuilder();\n                  }\n                  position_ = input.readMessage(com.android.aapt.Resources.SourcePosition.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(position_);\n                    position_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000002;\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.Source.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.Source)\n    private static final com.android.aapt.Resources.Source DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new Source();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.Source getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<Source> PARSER;\n\n    public static com.google.protobuf.Parser<Source> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface ResourceTableOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.ResourceTable)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * The string pool containing source paths referenced throughout the resource table. This does\n     * not end up in the final binary ARSC file.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.StringPool source_pool = 1;</code>\n     */\n    boolean hasSourcePool();\n    /**\n     * <pre>\n     * The string pool containing source paths referenced throughout the resource table. This does\n     * not end up in the final binary ARSC file.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.StringPool source_pool = 1;</code>\n     */\n    com.android.aapt.Resources.StringPool getSourcePool();\n\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    java.util.List<com.android.aapt.Resources.Package> \n        getPackageList();\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    com.android.aapt.Resources.Package getPackage(int index);\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    int getPackageCount();\n  }\n  /**\n   * <pre>\n   * Top level message representing a resource table.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.ResourceTable}\n   */\n  public  static final class ResourceTable extends\n      com.google.protobuf.GeneratedMessageLite<\n          ResourceTable, ResourceTable.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.ResourceTable)\n      ResourceTableOrBuilder {\n    private ResourceTable() {\n      package_ = emptyProtobufList();\n    }\n    private int bitField0_;\n    public static final int SOURCE_POOL_FIELD_NUMBER = 1;\n    private com.android.aapt.Resources.StringPool sourcePool_;\n    /**\n     * <pre>\n     * The string pool containing source paths referenced throughout the resource table. This does\n     * not end up in the final binary ARSC file.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.StringPool source_pool = 1;</code>\n     */\n    public boolean hasSourcePool() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <pre>\n     * The string pool containing source paths referenced throughout the resource table. This does\n     * not end up in the final binary ARSC file.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.StringPool source_pool = 1;</code>\n     */\n    public com.android.aapt.Resources.StringPool getSourcePool() {\n      return sourcePool_ == null ? com.android.aapt.Resources.StringPool.getDefaultInstance() : sourcePool_;\n    }\n    /**\n     * <pre>\n     * The string pool containing source paths referenced throughout the resource table. This does\n     * not end up in the final binary ARSC file.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.StringPool source_pool = 1;</code>\n     */\n    private void setSourcePool(com.android.aapt.Resources.StringPool value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      sourcePool_ = value;\n      bitField0_ |= 0x00000001;\n      }\n    /**\n     * <pre>\n     * The string pool containing source paths referenced throughout the resource table. This does\n     * not end up in the final binary ARSC file.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.StringPool source_pool = 1;</code>\n     */\n    private void setSourcePool(\n        com.android.aapt.Resources.StringPool.Builder builderForValue) {\n      sourcePool_ = builderForValue.build();\n      bitField0_ |= 0x00000001;\n    }\n    /**\n     * <pre>\n     * The string pool containing source paths referenced throughout the resource table. This does\n     * not end up in the final binary ARSC file.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.StringPool source_pool = 1;</code>\n     */\n    private void mergeSourcePool(com.android.aapt.Resources.StringPool value) {\n      if (sourcePool_ != null &&\n          sourcePool_ != com.android.aapt.Resources.StringPool.getDefaultInstance()) {\n        sourcePool_ =\n          com.android.aapt.Resources.StringPool.newBuilder(sourcePool_).mergeFrom(value).buildPartial();\n      } else {\n        sourcePool_ = value;\n      }\n      bitField0_ |= 0x00000001;\n    }\n    /**\n     * <pre>\n     * The string pool containing source paths referenced throughout the resource table. This does\n     * not end up in the final binary ARSC file.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.StringPool source_pool = 1;</code>\n     */\n    private void clearSourcePool() {  sourcePool_ = null;\n      bitField0_ = (bitField0_ & ~0x00000001);\n    }\n\n    public static final int PACKAGE_FIELD_NUMBER = 2;\n    private com.google.protobuf.Internal.ProtobufList<com.android.aapt.Resources.Package> package_;\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    public java.util.List<com.android.aapt.Resources.Package> getPackageList() {\n      return package_;\n    }\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    public java.util.List<? extends com.android.aapt.Resources.PackageOrBuilder> \n        getPackageOrBuilderList() {\n      return package_;\n    }\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    public int getPackageCount() {\n      return package_.size();\n    }\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    public com.android.aapt.Resources.Package getPackage(int index) {\n      return package_.get(index);\n    }\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    public com.android.aapt.Resources.PackageOrBuilder getPackageOrBuilder(\n        int index) {\n      return package_.get(index);\n    }\n    private void ensurePackageIsMutable() {\n      if (!package_.isModifiable()) {\n        package_ =\n            com.google.protobuf.GeneratedMessageLite.mutableCopy(package_);\n       }\n    }\n\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    private void setPackage(\n        int index, com.android.aapt.Resources.Package value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensurePackageIsMutable();\n      package_.set(index, value);\n    }\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    private void setPackage(\n        int index, com.android.aapt.Resources.Package.Builder builderForValue) {\n      ensurePackageIsMutable();\n      package_.set(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    private void addPackage(com.android.aapt.Resources.Package value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensurePackageIsMutable();\n      package_.add(value);\n    }\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    private void addPackage(\n        int index, com.android.aapt.Resources.Package value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensurePackageIsMutable();\n      package_.add(index, value);\n    }\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    private void addPackage(\n        com.android.aapt.Resources.Package.Builder builderForValue) {\n      ensurePackageIsMutable();\n      package_.add(builderForValue.build());\n    }\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    private void addPackage(\n        int index, com.android.aapt.Resources.Package.Builder builderForValue) {\n      ensurePackageIsMutable();\n      package_.add(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    private void addAllPackage(\n        java.lang.Iterable<? extends com.android.aapt.Resources.Package> values) {\n      ensurePackageIsMutable();\n      com.google.protobuf.AbstractMessageLite.addAll(\n          values, package_);\n    }\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    private void clearPackage() {\n      package_ = emptyProtobufList();\n    }\n    /**\n     * <pre>\n     * Resource definitions corresponding to an Android package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Package package = 2;</code>\n     */\n    private void removePackage(int index) {\n      ensurePackageIsMutable();\n      package_.remove(index);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeMessage(1, getSourcePool());\n      }\n      for (int i = 0; i < package_.size(); i++) {\n        output.writeMessage(2, package_.get(i));\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(1, getSourcePool());\n      }\n      for (int i = 0; i < package_.size(); i++) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(2, package_.get(i));\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.ResourceTable parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.ResourceTable parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.ResourceTable parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.ResourceTable parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.ResourceTable parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.ResourceTable parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.ResourceTable parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.ResourceTable parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.ResourceTable parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.ResourceTable parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.ResourceTable prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * Top level message representing a resource table.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.ResourceTable}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.ResourceTable, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.ResourceTable)\n        com.android.aapt.Resources.ResourceTableOrBuilder {\n      // Construct using com.android.aapt.Resources.ResourceTable.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * The string pool containing source paths referenced throughout the resource table. This does\n       * not end up in the final binary ARSC file.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.StringPool source_pool = 1;</code>\n       */\n      public boolean hasSourcePool() {\n        return instance.hasSourcePool();\n      }\n      /**\n       * <pre>\n       * The string pool containing source paths referenced throughout the resource table. This does\n       * not end up in the final binary ARSC file.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.StringPool source_pool = 1;</code>\n       */\n      public com.android.aapt.Resources.StringPool getSourcePool() {\n        return instance.getSourcePool();\n      }\n      /**\n       * <pre>\n       * The string pool containing source paths referenced throughout the resource table. This does\n       * not end up in the final binary ARSC file.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.StringPool source_pool = 1;</code>\n       */\n      public Builder setSourcePool(com.android.aapt.Resources.StringPool value) {\n        copyOnWrite();\n        instance.setSourcePool(value);\n        return this;\n        }\n      /**\n       * <pre>\n       * The string pool containing source paths referenced throughout the resource table. This does\n       * not end up in the final binary ARSC file.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.StringPool source_pool = 1;</code>\n       */\n      public Builder setSourcePool(\n          com.android.aapt.Resources.StringPool.Builder builderForValue) {\n        copyOnWrite();\n        instance.setSourcePool(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The string pool containing source paths referenced throughout the resource table. This does\n       * not end up in the final binary ARSC file.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.StringPool source_pool = 1;</code>\n       */\n      public Builder mergeSourcePool(com.android.aapt.Resources.StringPool value) {\n        copyOnWrite();\n        instance.mergeSourcePool(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The string pool containing source paths referenced throughout the resource table. This does\n       * not end up in the final binary ARSC file.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.StringPool source_pool = 1;</code>\n       */\n      public Builder clearSourcePool() {  copyOnWrite();\n        instance.clearSourcePool();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * Resource definitions corresponding to an Android package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Package package = 2;</code>\n       */\n      public java.util.List<com.android.aapt.Resources.Package> getPackageList() {\n        return java.util.Collections.unmodifiableList(\n            instance.getPackageList());\n      }\n      /**\n       * <pre>\n       * Resource definitions corresponding to an Android package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Package package = 2;</code>\n       */\n      public int getPackageCount() {\n        return instance.getPackageCount();\n      }/**\n       * <pre>\n       * Resource definitions corresponding to an Android package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Package package = 2;</code>\n       */\n      public com.android.aapt.Resources.Package getPackage(int index) {\n        return instance.getPackage(index);\n      }\n      /**\n       * <pre>\n       * Resource definitions corresponding to an Android package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Package package = 2;</code>\n       */\n      public Builder setPackage(\n          int index, com.android.aapt.Resources.Package value) {\n        copyOnWrite();\n        instance.setPackage(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Resource definitions corresponding to an Android package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Package package = 2;</code>\n       */\n      public Builder setPackage(\n          int index, com.android.aapt.Resources.Package.Builder builderForValue) {\n        copyOnWrite();\n        instance.setPackage(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * Resource definitions corresponding to an Android package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Package package = 2;</code>\n       */\n      public Builder addPackage(com.android.aapt.Resources.Package value) {\n        copyOnWrite();\n        instance.addPackage(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Resource definitions corresponding to an Android package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Package package = 2;</code>\n       */\n      public Builder addPackage(\n          int index, com.android.aapt.Resources.Package value) {\n        copyOnWrite();\n        instance.addPackage(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Resource definitions corresponding to an Android package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Package package = 2;</code>\n       */\n      public Builder addPackage(\n          com.android.aapt.Resources.Package.Builder builderForValue) {\n        copyOnWrite();\n        instance.addPackage(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * Resource definitions corresponding to an Android package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Package package = 2;</code>\n       */\n      public Builder addPackage(\n          int index, com.android.aapt.Resources.Package.Builder builderForValue) {\n        copyOnWrite();\n        instance.addPackage(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * Resource definitions corresponding to an Android package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Package package = 2;</code>\n       */\n      public Builder addAllPackage(\n          java.lang.Iterable<? extends com.android.aapt.Resources.Package> values) {\n        copyOnWrite();\n        instance.addAllPackage(values);\n        return this;\n      }\n      /**\n       * <pre>\n       * Resource definitions corresponding to an Android package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Package package = 2;</code>\n       */\n      public Builder clearPackage() {\n        copyOnWrite();\n        instance.clearPackage();\n        return this;\n      }\n      /**\n       * <pre>\n       * Resource definitions corresponding to an Android package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Package package = 2;</code>\n       */\n      public Builder removePackage(int index) {\n        copyOnWrite();\n        instance.removePackage(index);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.ResourceTable)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.ResourceTable();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          package_.makeImmutable();\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.ResourceTable other = (com.android.aapt.Resources.ResourceTable) arg1;\n          sourcePool_ = visitor.visitMessage(sourcePool_, other.sourcePool_);\n          package_= visitor.visitList(package_, other.package_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  com.android.aapt.Resources.StringPool.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                    subBuilder = sourcePool_.toBuilder();\n                  }\n                  sourcePool_ = input.readMessage(com.android.aapt.Resources.StringPool.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(sourcePool_);\n                    sourcePool_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000001;\n                  break;\n                }\n                case 18: {\n                  if (!package_.isModifiable()) {\n                    package_ =\n                        com.google.protobuf.GeneratedMessageLite.mutableCopy(package_);\n                  }\n                  package_.add(\n                      input.readMessage(com.android.aapt.Resources.Package.parser(), extensionRegistry));\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.ResourceTable.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.ResourceTable)\n    private static final com.android.aapt.Resources.ResourceTable DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new ResourceTable();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.ResourceTable getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<ResourceTable> PARSER;\n\n    public static com.google.protobuf.Parser<ResourceTable> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface PackageOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.Package)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * The package ID of this package, in the range [0x00, 0xff].\n     * The ID 0x00 is reserved for shared libraries, or when the ID is assigned at run-time.\n     * The ID 0x01 is reserved for the 'android' package (framework).\n     * The ID range [0x02, 0x7f) is reserved for auto-assignment to shared libraries at run-time.\n     * The ID 0x7f is reserved for the application package.\n     * IDs &gt; 0x7f are reserved for the application as well and are treated as feature splits.\n     * </pre>\n     *\n     * <code>optional uint32 package_id = 1;</code>\n     */\n    boolean hasPackageId();\n    /**\n     * <pre>\n     * The package ID of this package, in the range [0x00, 0xff].\n     * The ID 0x00 is reserved for shared libraries, or when the ID is assigned at run-time.\n     * The ID 0x01 is reserved for the 'android' package (framework).\n     * The ID range [0x02, 0x7f) is reserved for auto-assignment to shared libraries at run-time.\n     * The ID 0x7f is reserved for the application package.\n     * IDs &gt; 0x7f are reserved for the application as well and are treated as feature splits.\n     * </pre>\n     *\n     * <code>optional uint32 package_id = 1;</code>\n     */\n    int getPackageId();\n\n    /**\n     * <pre>\n     * The Java compatible Android package name of the app.\n     * </pre>\n     *\n     * <code>optional string package_name = 2;</code>\n     */\n    boolean hasPackageName();\n    /**\n     * <pre>\n     * The Java compatible Android package name of the app.\n     * </pre>\n     *\n     * <code>optional string package_name = 2;</code>\n     */\n    java.lang.String getPackageName();\n    /**\n     * <pre>\n     * The Java compatible Android package name of the app.\n     * </pre>\n     *\n     * <code>optional string package_name = 2;</code>\n     */\n    com.google.protobuf.ByteString\n        getPackageNameBytes();\n\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    java.util.List<com.android.aapt.Resources.Type> \n        getTypeList();\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    com.android.aapt.Resources.Type getType(int index);\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    int getTypeCount();\n  }\n  /**\n   * <pre>\n   * Defines resources for an Android package.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.Package}\n   */\n  public  static final class Package extends\n      com.google.protobuf.GeneratedMessageLite<\n          Package, Package.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.Package)\n      PackageOrBuilder {\n    private Package() {\n      packageName_ = \"\";\n      type_ = emptyProtobufList();\n    }\n    private int bitField0_;\n    public static final int PACKAGE_ID_FIELD_NUMBER = 1;\n    private int packageId_;\n    /**\n     * <pre>\n     * The package ID of this package, in the range [0x00, 0xff].\n     * The ID 0x00 is reserved for shared libraries, or when the ID is assigned at run-time.\n     * The ID 0x01 is reserved for the 'android' package (framework).\n     * The ID range [0x02, 0x7f) is reserved for auto-assignment to shared libraries at run-time.\n     * The ID 0x7f is reserved for the application package.\n     * IDs &gt; 0x7f are reserved for the application as well and are treated as feature splits.\n     * </pre>\n     *\n     * <code>optional uint32 package_id = 1;</code>\n     */\n    public boolean hasPackageId() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <pre>\n     * The package ID of this package, in the range [0x00, 0xff].\n     * The ID 0x00 is reserved for shared libraries, or when the ID is assigned at run-time.\n     * The ID 0x01 is reserved for the 'android' package (framework).\n     * The ID range [0x02, 0x7f) is reserved for auto-assignment to shared libraries at run-time.\n     * The ID 0x7f is reserved for the application package.\n     * IDs &gt; 0x7f are reserved for the application as well and are treated as feature splits.\n     * </pre>\n     *\n     * <code>optional uint32 package_id = 1;</code>\n     */\n    public int getPackageId() {\n      return packageId_;\n    }\n    /**\n     * <pre>\n     * The package ID of this package, in the range [0x00, 0xff].\n     * The ID 0x00 is reserved for shared libraries, or when the ID is assigned at run-time.\n     * The ID 0x01 is reserved for the 'android' package (framework).\n     * The ID range [0x02, 0x7f) is reserved for auto-assignment to shared libraries at run-time.\n     * The ID 0x7f is reserved for the application package.\n     * IDs &gt; 0x7f are reserved for the application as well and are treated as feature splits.\n     * </pre>\n     *\n     * <code>optional uint32 package_id = 1;</code>\n     */\n    private void setPackageId(int value) {\n      bitField0_ |= 0x00000001;\n      packageId_ = value;\n    }\n    /**\n     * <pre>\n     * The package ID of this package, in the range [0x00, 0xff].\n     * The ID 0x00 is reserved for shared libraries, or when the ID is assigned at run-time.\n     * The ID 0x01 is reserved for the 'android' package (framework).\n     * The ID range [0x02, 0x7f) is reserved for auto-assignment to shared libraries at run-time.\n     * The ID 0x7f is reserved for the application package.\n     * IDs &gt; 0x7f are reserved for the application as well and are treated as feature splits.\n     * </pre>\n     *\n     * <code>optional uint32 package_id = 1;</code>\n     */\n    private void clearPackageId() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      packageId_ = 0;\n    }\n\n    public static final int PACKAGE_NAME_FIELD_NUMBER = 2;\n    private java.lang.String packageName_;\n    /**\n     * <pre>\n     * The Java compatible Android package name of the app.\n     * </pre>\n     *\n     * <code>optional string package_name = 2;</code>\n     */\n    public boolean hasPackageName() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <pre>\n     * The Java compatible Android package name of the app.\n     * </pre>\n     *\n     * <code>optional string package_name = 2;</code>\n     */\n    public java.lang.String getPackageName() {\n      return packageName_;\n    }\n    /**\n     * <pre>\n     * The Java compatible Android package name of the app.\n     * </pre>\n     *\n     * <code>optional string package_name = 2;</code>\n     */\n    public com.google.protobuf.ByteString\n        getPackageNameBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(packageName_);\n    }\n    /**\n     * <pre>\n     * The Java compatible Android package name of the app.\n     * </pre>\n     *\n     * <code>optional string package_name = 2;</code>\n     */\n    private void setPackageName(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      packageName_ = value;\n    }\n    /**\n     * <pre>\n     * The Java compatible Android package name of the app.\n     * </pre>\n     *\n     * <code>optional string package_name = 2;</code>\n     */\n    private void clearPackageName() {\n      bitField0_ = (bitField0_ & ~0x00000002);\n      packageName_ = getDefaultInstance().getPackageName();\n    }\n    /**\n     * <pre>\n     * The Java compatible Android package name of the app.\n     * </pre>\n     *\n     * <code>optional string package_name = 2;</code>\n     */\n    private void setPackageNameBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      packageName_ = value.toStringUtf8();\n    }\n\n    public static final int TYPE_FIELD_NUMBER = 3;\n    private com.google.protobuf.Internal.ProtobufList<com.android.aapt.Resources.Type> type_;\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    public java.util.List<com.android.aapt.Resources.Type> getTypeList() {\n      return type_;\n    }\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    public java.util.List<? extends com.android.aapt.Resources.TypeOrBuilder> \n        getTypeOrBuilderList() {\n      return type_;\n    }\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    public int getTypeCount() {\n      return type_.size();\n    }\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    public com.android.aapt.Resources.Type getType(int index) {\n      return type_.get(index);\n    }\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    public com.android.aapt.Resources.TypeOrBuilder getTypeOrBuilder(\n        int index) {\n      return type_.get(index);\n    }\n    private void ensureTypeIsMutable() {\n      if (!type_.isModifiable()) {\n        type_ =\n            com.google.protobuf.GeneratedMessageLite.mutableCopy(type_);\n       }\n    }\n\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    private void setType(\n        int index, com.android.aapt.Resources.Type value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureTypeIsMutable();\n      type_.set(index, value);\n    }\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    private void setType(\n        int index, com.android.aapt.Resources.Type.Builder builderForValue) {\n      ensureTypeIsMutable();\n      type_.set(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    private void addType(com.android.aapt.Resources.Type value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureTypeIsMutable();\n      type_.add(value);\n    }\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    private void addType(\n        int index, com.android.aapt.Resources.Type value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureTypeIsMutable();\n      type_.add(index, value);\n    }\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    private void addType(\n        com.android.aapt.Resources.Type.Builder builderForValue) {\n      ensureTypeIsMutable();\n      type_.add(builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    private void addType(\n        int index, com.android.aapt.Resources.Type.Builder builderForValue) {\n      ensureTypeIsMutable();\n      type_.add(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    private void addAllType(\n        java.lang.Iterable<? extends com.android.aapt.Resources.Type> values) {\n      ensureTypeIsMutable();\n      com.google.protobuf.AbstractMessageLite.addAll(\n          values, type_);\n    }\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    private void clearType() {\n      type_ = emptyProtobufList();\n    }\n    /**\n     * <pre>\n     * The series of types defined by the package.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Type type = 3;</code>\n     */\n    private void removeType(int index) {\n      ensureTypeIsMutable();\n      type_.remove(index);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeUInt32(1, packageId_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeString(2, getPackageName());\n      }\n      for (int i = 0; i < type_.size(); i++) {\n        output.writeMessage(3, type_.get(i));\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeUInt32Size(1, packageId_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(2, getPackageName());\n      }\n      for (int i = 0; i < type_.size(); i++) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(3, type_.get(i));\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.Package parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Package parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Package parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Package parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Package parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Package parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Package parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Package parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Package parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Package parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.Package prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * Defines resources for an Android package.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Package}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.Package, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.Package)\n        com.android.aapt.Resources.PackageOrBuilder {\n      // Construct using com.android.aapt.Resources.Package.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * The package ID of this package, in the range [0x00, 0xff].\n       * The ID 0x00 is reserved for shared libraries, or when the ID is assigned at run-time.\n       * The ID 0x01 is reserved for the 'android' package (framework).\n       * The ID range [0x02, 0x7f) is reserved for auto-assignment to shared libraries at run-time.\n       * The ID 0x7f is reserved for the application package.\n       * IDs &gt; 0x7f are reserved for the application as well and are treated as feature splits.\n       * </pre>\n       *\n       * <code>optional uint32 package_id = 1;</code>\n       */\n      public boolean hasPackageId() {\n        return instance.hasPackageId();\n      }\n      /**\n       * <pre>\n       * The package ID of this package, in the range [0x00, 0xff].\n       * The ID 0x00 is reserved for shared libraries, or when the ID is assigned at run-time.\n       * The ID 0x01 is reserved for the 'android' package (framework).\n       * The ID range [0x02, 0x7f) is reserved for auto-assignment to shared libraries at run-time.\n       * The ID 0x7f is reserved for the application package.\n       * IDs &gt; 0x7f are reserved for the application as well and are treated as feature splits.\n       * </pre>\n       *\n       * <code>optional uint32 package_id = 1;</code>\n       */\n      public int getPackageId() {\n        return instance.getPackageId();\n      }\n      /**\n       * <pre>\n       * The package ID of this package, in the range [0x00, 0xff].\n       * The ID 0x00 is reserved for shared libraries, or when the ID is assigned at run-time.\n       * The ID 0x01 is reserved for the 'android' package (framework).\n       * The ID range [0x02, 0x7f) is reserved for auto-assignment to shared libraries at run-time.\n       * The ID 0x7f is reserved for the application package.\n       * IDs &gt; 0x7f are reserved for the application as well and are treated as feature splits.\n       * </pre>\n       *\n       * <code>optional uint32 package_id = 1;</code>\n       */\n      public Builder setPackageId(int value) {\n        copyOnWrite();\n        instance.setPackageId(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The package ID of this package, in the range [0x00, 0xff].\n       * The ID 0x00 is reserved for shared libraries, or when the ID is assigned at run-time.\n       * The ID 0x01 is reserved for the 'android' package (framework).\n       * The ID range [0x02, 0x7f) is reserved for auto-assignment to shared libraries at run-time.\n       * The ID 0x7f is reserved for the application package.\n       * IDs &gt; 0x7f are reserved for the application as well and are treated as feature splits.\n       * </pre>\n       *\n       * <code>optional uint32 package_id = 1;</code>\n       */\n      public Builder clearPackageId() {\n        copyOnWrite();\n        instance.clearPackageId();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The Java compatible Android package name of the app.\n       * </pre>\n       *\n       * <code>optional string package_name = 2;</code>\n       */\n      public boolean hasPackageName() {\n        return instance.hasPackageName();\n      }\n      /**\n       * <pre>\n       * The Java compatible Android package name of the app.\n       * </pre>\n       *\n       * <code>optional string package_name = 2;</code>\n       */\n      public java.lang.String getPackageName() {\n        return instance.getPackageName();\n      }\n      /**\n       * <pre>\n       * The Java compatible Android package name of the app.\n       * </pre>\n       *\n       * <code>optional string package_name = 2;</code>\n       */\n      public com.google.protobuf.ByteString\n          getPackageNameBytes() {\n        return instance.getPackageNameBytes();\n      }\n      /**\n       * <pre>\n       * The Java compatible Android package name of the app.\n       * </pre>\n       *\n       * <code>optional string package_name = 2;</code>\n       */\n      public Builder setPackageName(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setPackageName(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The Java compatible Android package name of the app.\n       * </pre>\n       *\n       * <code>optional string package_name = 2;</code>\n       */\n      public Builder clearPackageName() {\n        copyOnWrite();\n        instance.clearPackageName();\n        return this;\n      }\n      /**\n       * <pre>\n       * The Java compatible Android package name of the app.\n       * </pre>\n       *\n       * <code>optional string package_name = 2;</code>\n       */\n      public Builder setPackageNameBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setPackageNameBytes(value);\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The series of types defined by the package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Type type = 3;</code>\n       */\n      public java.util.List<com.android.aapt.Resources.Type> getTypeList() {\n        return java.util.Collections.unmodifiableList(\n            instance.getTypeList());\n      }\n      /**\n       * <pre>\n       * The series of types defined by the package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Type type = 3;</code>\n       */\n      public int getTypeCount() {\n        return instance.getTypeCount();\n      }/**\n       * <pre>\n       * The series of types defined by the package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Type type = 3;</code>\n       */\n      public com.android.aapt.Resources.Type getType(int index) {\n        return instance.getType(index);\n      }\n      /**\n       * <pre>\n       * The series of types defined by the package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Type type = 3;</code>\n       */\n      public Builder setType(\n          int index, com.android.aapt.Resources.Type value) {\n        copyOnWrite();\n        instance.setType(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The series of types defined by the package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Type type = 3;</code>\n       */\n      public Builder setType(\n          int index, com.android.aapt.Resources.Type.Builder builderForValue) {\n        copyOnWrite();\n        instance.setType(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The series of types defined by the package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Type type = 3;</code>\n       */\n      public Builder addType(com.android.aapt.Resources.Type value) {\n        copyOnWrite();\n        instance.addType(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The series of types defined by the package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Type type = 3;</code>\n       */\n      public Builder addType(\n          int index, com.android.aapt.Resources.Type value) {\n        copyOnWrite();\n        instance.addType(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The series of types defined by the package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Type type = 3;</code>\n       */\n      public Builder addType(\n          com.android.aapt.Resources.Type.Builder builderForValue) {\n        copyOnWrite();\n        instance.addType(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The series of types defined by the package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Type type = 3;</code>\n       */\n      public Builder addType(\n          int index, com.android.aapt.Resources.Type.Builder builderForValue) {\n        copyOnWrite();\n        instance.addType(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The series of types defined by the package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Type type = 3;</code>\n       */\n      public Builder addAllType(\n          java.lang.Iterable<? extends com.android.aapt.Resources.Type> values) {\n        copyOnWrite();\n        instance.addAllType(values);\n        return this;\n      }\n      /**\n       * <pre>\n       * The series of types defined by the package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Type type = 3;</code>\n       */\n      public Builder clearType() {\n        copyOnWrite();\n        instance.clearType();\n        return this;\n      }\n      /**\n       * <pre>\n       * The series of types defined by the package.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Type type = 3;</code>\n       */\n      public Builder removeType(int index) {\n        copyOnWrite();\n        instance.removeType(index);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.Package)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.Package();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          type_.makeImmutable();\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.Package other = (com.android.aapt.Resources.Package) arg1;\n          packageId_ = visitor.visitInt(\n              hasPackageId(), packageId_,\n              other.hasPackageId(), other.packageId_);\n          packageName_ = visitor.visitString(\n              hasPackageName(), packageName_,\n              other.hasPackageName(), other.packageName_);\n          type_= visitor.visitList(type_, other.type_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 8: {\n                  bitField0_ |= 0x00000001;\n                  packageId_ = input.readUInt32();\n                  break;\n                }\n                case 18: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000002;\n                  packageName_ = s;\n                  break;\n                }\n                case 26: {\n                  if (!type_.isModifiable()) {\n                    type_ =\n                        com.google.protobuf.GeneratedMessageLite.mutableCopy(type_);\n                  }\n                  type_.add(\n                      input.readMessage(com.android.aapt.Resources.Type.parser(), extensionRegistry));\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.Package.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.Package)\n    private static final com.android.aapt.Resources.Package DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new Package();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.Package getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<Package> PARSER;\n\n    public static com.google.protobuf.Parser<Package> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface TypeOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.Type)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * The ID of the type. This may be 0, which indicates no ID is set.\n     * </pre>\n     *\n     * <code>optional uint32 id = 1;</code>\n     */\n    boolean hasId();\n    /**\n     * <pre>\n     * The ID of the type. This may be 0, which indicates no ID is set.\n     * </pre>\n     *\n     * <code>optional uint32 id = 1;</code>\n     */\n    int getId();\n\n    /**\n     * <pre>\n     * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n     * package:type/entry. The set of legal type names is listed in Resource.cpp.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    boolean hasName();\n    /**\n     * <pre>\n     * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n     * package:type/entry. The set of legal type names is listed in Resource.cpp.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    java.lang.String getName();\n    /**\n     * <pre>\n     * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n     * package:type/entry. The set of legal type names is listed in Resource.cpp.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    com.google.protobuf.ByteString\n        getNameBytes();\n\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    java.util.List<com.android.aapt.Resources.Entry> \n        getEntryList();\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    com.android.aapt.Resources.Entry getEntry(int index);\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    int getEntryCount();\n  }\n  /**\n   * <pre>\n   * A set of resources grouped under a common type. Such types include string, layout, xml, dimen,\n   * attr, etc. This maps to the second part of a resource identifier in Java (R.type.entry).\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.Type}\n   */\n  public  static final class Type extends\n      com.google.protobuf.GeneratedMessageLite<\n          Type, Type.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.Type)\n      TypeOrBuilder {\n    private Type() {\n      name_ = \"\";\n      entry_ = emptyProtobufList();\n    }\n    private int bitField0_;\n    public static final int ID_FIELD_NUMBER = 1;\n    private int id_;\n    /**\n     * <pre>\n     * The ID of the type. This may be 0, which indicates no ID is set.\n     * </pre>\n     *\n     * <code>optional uint32 id = 1;</code>\n     */\n    public boolean hasId() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <pre>\n     * The ID of the type. This may be 0, which indicates no ID is set.\n     * </pre>\n     *\n     * <code>optional uint32 id = 1;</code>\n     */\n    public int getId() {\n      return id_;\n    }\n    /**\n     * <pre>\n     * The ID of the type. This may be 0, which indicates no ID is set.\n     * </pre>\n     *\n     * <code>optional uint32 id = 1;</code>\n     */\n    private void setId(int value) {\n      bitField0_ |= 0x00000001;\n      id_ = value;\n    }\n    /**\n     * <pre>\n     * The ID of the type. This may be 0, which indicates no ID is set.\n     * </pre>\n     *\n     * <code>optional uint32 id = 1;</code>\n     */\n    private void clearId() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      id_ = 0;\n    }\n\n    public static final int NAME_FIELD_NUMBER = 2;\n    private java.lang.String name_;\n    /**\n     * <pre>\n     * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n     * package:type/entry. The set of legal type names is listed in Resource.cpp.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    public boolean hasName() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <pre>\n     * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n     * package:type/entry. The set of legal type names is listed in Resource.cpp.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    public java.lang.String getName() {\n      return name_;\n    }\n    /**\n     * <pre>\n     * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n     * package:type/entry. The set of legal type names is listed in Resource.cpp.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    public com.google.protobuf.ByteString\n        getNameBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(name_);\n    }\n    /**\n     * <pre>\n     * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n     * package:type/entry. The set of legal type names is listed in Resource.cpp.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    private void setName(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      name_ = value;\n    }\n    /**\n     * <pre>\n     * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n     * package:type/entry. The set of legal type names is listed in Resource.cpp.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    private void clearName() {\n      bitField0_ = (bitField0_ & ~0x00000002);\n      name_ = getDefaultInstance().getName();\n    }\n    /**\n     * <pre>\n     * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n     * package:type/entry. The set of legal type names is listed in Resource.cpp.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    private void setNameBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      name_ = value.toStringUtf8();\n    }\n\n    public static final int ENTRY_FIELD_NUMBER = 3;\n    private com.google.protobuf.Internal.ProtobufList<com.android.aapt.Resources.Entry> entry_;\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    public java.util.List<com.android.aapt.Resources.Entry> getEntryList() {\n      return entry_;\n    }\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    public java.util.List<? extends com.android.aapt.Resources.EntryOrBuilder> \n        getEntryOrBuilderList() {\n      return entry_;\n    }\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    public int getEntryCount() {\n      return entry_.size();\n    }\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    public com.android.aapt.Resources.Entry getEntry(int index) {\n      return entry_.get(index);\n    }\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    public com.android.aapt.Resources.EntryOrBuilder getEntryOrBuilder(\n        int index) {\n      return entry_.get(index);\n    }\n    private void ensureEntryIsMutable() {\n      if (!entry_.isModifiable()) {\n        entry_ =\n            com.google.protobuf.GeneratedMessageLite.mutableCopy(entry_);\n       }\n    }\n\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    private void setEntry(\n        int index, com.android.aapt.Resources.Entry value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureEntryIsMutable();\n      entry_.set(index, value);\n    }\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    private void setEntry(\n        int index, com.android.aapt.Resources.Entry.Builder builderForValue) {\n      ensureEntryIsMutable();\n      entry_.set(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    private void addEntry(com.android.aapt.Resources.Entry value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureEntryIsMutable();\n      entry_.add(value);\n    }\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    private void addEntry(\n        int index, com.android.aapt.Resources.Entry value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureEntryIsMutable();\n      entry_.add(index, value);\n    }\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    private void addEntry(\n        com.android.aapt.Resources.Entry.Builder builderForValue) {\n      ensureEntryIsMutable();\n      entry_.add(builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    private void addEntry(\n        int index, com.android.aapt.Resources.Entry.Builder builderForValue) {\n      ensureEntryIsMutable();\n      entry_.add(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    private void addAllEntry(\n        java.lang.Iterable<? extends com.android.aapt.Resources.Entry> values) {\n      ensureEntryIsMutable();\n      com.google.protobuf.AbstractMessageLite.addAll(\n          values, entry_);\n    }\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    private void clearEntry() {\n      entry_ = emptyProtobufList();\n    }\n    /**\n     * <pre>\n     * The entries defined for this type.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Entry entry = 3;</code>\n     */\n    private void removeEntry(int index) {\n      ensureEntryIsMutable();\n      entry_.remove(index);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeUInt32(1, id_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeString(2, getName());\n      }\n      for (int i = 0; i < entry_.size(); i++) {\n        output.writeMessage(3, entry_.get(i));\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeUInt32Size(1, id_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(2, getName());\n      }\n      for (int i = 0; i < entry_.size(); i++) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(3, entry_.get(i));\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.Type parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Type parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Type parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Type parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Type parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Type parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Type parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Type parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Type parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Type parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.Type prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A set of resources grouped under a common type. Such types include string, layout, xml, dimen,\n     * attr, etc. This maps to the second part of a resource identifier in Java (R.type.entry).\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Type}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.Type, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.Type)\n        com.android.aapt.Resources.TypeOrBuilder {\n      // Construct using com.android.aapt.Resources.Type.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * The ID of the type. This may be 0, which indicates no ID is set.\n       * </pre>\n       *\n       * <code>optional uint32 id = 1;</code>\n       */\n      public boolean hasId() {\n        return instance.hasId();\n      }\n      /**\n       * <pre>\n       * The ID of the type. This may be 0, which indicates no ID is set.\n       * </pre>\n       *\n       * <code>optional uint32 id = 1;</code>\n       */\n      public int getId() {\n        return instance.getId();\n      }\n      /**\n       * <pre>\n       * The ID of the type. This may be 0, which indicates no ID is set.\n       * </pre>\n       *\n       * <code>optional uint32 id = 1;</code>\n       */\n      public Builder setId(int value) {\n        copyOnWrite();\n        instance.setId(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The ID of the type. This may be 0, which indicates no ID is set.\n       * </pre>\n       *\n       * <code>optional uint32 id = 1;</code>\n       */\n      public Builder clearId() {\n        copyOnWrite();\n        instance.clearId();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n       * package:type/entry. The set of legal type names is listed in Resource.cpp.\n       * </pre>\n       *\n       * <code>optional string name = 2;</code>\n       */\n      public boolean hasName() {\n        return instance.hasName();\n      }\n      /**\n       * <pre>\n       * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n       * package:type/entry. The set of legal type names is listed in Resource.cpp.\n       * </pre>\n       *\n       * <code>optional string name = 2;</code>\n       */\n      public java.lang.String getName() {\n        return instance.getName();\n      }\n      /**\n       * <pre>\n       * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n       * package:type/entry. The set of legal type names is listed in Resource.cpp.\n       * </pre>\n       *\n       * <code>optional string name = 2;</code>\n       */\n      public com.google.protobuf.ByteString\n          getNameBytes() {\n        return instance.getNameBytes();\n      }\n      /**\n       * <pre>\n       * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n       * package:type/entry. The set of legal type names is listed in Resource.cpp.\n       * </pre>\n       *\n       * <code>optional string name = 2;</code>\n       */\n      public Builder setName(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setName(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n       * package:type/entry. The set of legal type names is listed in Resource.cpp.\n       * </pre>\n       *\n       * <code>optional string name = 2;</code>\n       */\n      public Builder clearName() {\n        copyOnWrite();\n        instance.clearName();\n        return this;\n      }\n      /**\n       * <pre>\n       * The name of the type. This corresponds to the 'type' part of a full resource name of the form\n       * package:type/entry. The set of legal type names is listed in Resource.cpp.\n       * </pre>\n       *\n       * <code>optional string name = 2;</code>\n       */\n      public Builder setNameBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setNameBytes(value);\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The entries defined for this type.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Entry entry = 3;</code>\n       */\n      public java.util.List<com.android.aapt.Resources.Entry> getEntryList() {\n        return java.util.Collections.unmodifiableList(\n            instance.getEntryList());\n      }\n      /**\n       * <pre>\n       * The entries defined for this type.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Entry entry = 3;</code>\n       */\n      public int getEntryCount() {\n        return instance.getEntryCount();\n      }/**\n       * <pre>\n       * The entries defined for this type.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Entry entry = 3;</code>\n       */\n      public com.android.aapt.Resources.Entry getEntry(int index) {\n        return instance.getEntry(index);\n      }\n      /**\n       * <pre>\n       * The entries defined for this type.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Entry entry = 3;</code>\n       */\n      public Builder setEntry(\n          int index, com.android.aapt.Resources.Entry value) {\n        copyOnWrite();\n        instance.setEntry(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The entries defined for this type.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Entry entry = 3;</code>\n       */\n      public Builder setEntry(\n          int index, com.android.aapt.Resources.Entry.Builder builderForValue) {\n        copyOnWrite();\n        instance.setEntry(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The entries defined for this type.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Entry entry = 3;</code>\n       */\n      public Builder addEntry(com.android.aapt.Resources.Entry value) {\n        copyOnWrite();\n        instance.addEntry(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The entries defined for this type.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Entry entry = 3;</code>\n       */\n      public Builder addEntry(\n          int index, com.android.aapt.Resources.Entry value) {\n        copyOnWrite();\n        instance.addEntry(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The entries defined for this type.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Entry entry = 3;</code>\n       */\n      public Builder addEntry(\n          com.android.aapt.Resources.Entry.Builder builderForValue) {\n        copyOnWrite();\n        instance.addEntry(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The entries defined for this type.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Entry entry = 3;</code>\n       */\n      public Builder addEntry(\n          int index, com.android.aapt.Resources.Entry.Builder builderForValue) {\n        copyOnWrite();\n        instance.addEntry(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The entries defined for this type.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Entry entry = 3;</code>\n       */\n      public Builder addAllEntry(\n          java.lang.Iterable<? extends com.android.aapt.Resources.Entry> values) {\n        copyOnWrite();\n        instance.addAllEntry(values);\n        return this;\n      }\n      /**\n       * <pre>\n       * The entries defined for this type.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Entry entry = 3;</code>\n       */\n      public Builder clearEntry() {\n        copyOnWrite();\n        instance.clearEntry();\n        return this;\n      }\n      /**\n       * <pre>\n       * The entries defined for this type.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Entry entry = 3;</code>\n       */\n      public Builder removeEntry(int index) {\n        copyOnWrite();\n        instance.removeEntry(index);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.Type)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.Type();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          entry_.makeImmutable();\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.Type other = (com.android.aapt.Resources.Type) arg1;\n          id_ = visitor.visitInt(\n              hasId(), id_,\n              other.hasId(), other.id_);\n          name_ = visitor.visitString(\n              hasName(), name_,\n              other.hasName(), other.name_);\n          entry_= visitor.visitList(entry_, other.entry_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 8: {\n                  bitField0_ |= 0x00000001;\n                  id_ = input.readUInt32();\n                  break;\n                }\n                case 18: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000002;\n                  name_ = s;\n                  break;\n                }\n                case 26: {\n                  if (!entry_.isModifiable()) {\n                    entry_ =\n                        com.google.protobuf.GeneratedMessageLite.mutableCopy(entry_);\n                  }\n                  entry_.add(\n                      input.readMessage(com.android.aapt.Resources.Entry.parser(), extensionRegistry));\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.Type.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.Type)\n    private static final com.android.aapt.Resources.Type DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new Type();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.Type getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<Type> PARSER;\n\n    public static com.google.protobuf.Parser<Type> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface SymbolStatusOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.SymbolStatus)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <code>optional .aapt.pb.SymbolStatus.Visibility visibility = 1;</code>\n     */\n    boolean hasVisibility();\n    /**\n     * <code>optional .aapt.pb.SymbolStatus.Visibility visibility = 1;</code>\n     */\n    com.android.aapt.Resources.SymbolStatus.Visibility getVisibility();\n\n    /**\n     * <pre>\n     * The path at which this entry's visibility was defined (eg. public.xml).\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 2;</code>\n     */\n    boolean hasSource();\n    /**\n     * <pre>\n     * The path at which this entry's visibility was defined (eg. public.xml).\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 2;</code>\n     */\n    com.android.aapt.Resources.Source getSource();\n\n    /**\n     * <pre>\n     * The comment associated with the &lt;public&gt; tag.\n     * </pre>\n     *\n     * <code>optional string comment = 3;</code>\n     */\n    boolean hasComment();\n    /**\n     * <pre>\n     * The comment associated with the &lt;public&gt; tag.\n     * </pre>\n     *\n     * <code>optional string comment = 3;</code>\n     */\n    java.lang.String getComment();\n    /**\n     * <pre>\n     * The comment associated with the &lt;public&gt; tag.\n     * </pre>\n     *\n     * <code>optional string comment = 3;</code>\n     */\n    com.google.protobuf.ByteString\n        getCommentBytes();\n\n    /**\n     * <pre>\n     * Whether the symbol can be merged into another resource table without there being an existing\n     * definition to override. Used for overlays and set to true when &lt;add-resource&gt; is specified.\n     * </pre>\n     *\n     * <code>optional bool allow_new = 4;</code>\n     */\n    boolean hasAllowNew();\n    /**\n     * <pre>\n     * Whether the symbol can be merged into another resource table without there being an existing\n     * definition to override. Used for overlays and set to true when &lt;add-resource&gt; is specified.\n     * </pre>\n     *\n     * <code>optional bool allow_new = 4;</code>\n     */\n    boolean getAllowNew();\n  }\n  /**\n   * <pre>\n   * The status of a symbol/entry. This contains information like visibility (public/private),\n   * comments, and whether the entry can be overridden.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.SymbolStatus}\n   */\n  public  static final class SymbolStatus extends\n      com.google.protobuf.GeneratedMessageLite<\n          SymbolStatus, SymbolStatus.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.SymbolStatus)\n      SymbolStatusOrBuilder {\n    private SymbolStatus() {\n      comment_ = \"\";\n    }\n    /**\n     * <pre>\n     * The visibility of the resource outside of its package.\n     * </pre>\n     *\n     * Protobuf enum {@code aapt.pb.SymbolStatus.Visibility}\n     */\n    public enum Visibility\n        implements com.google.protobuf.Internal.EnumLite {\n      /**\n       * <pre>\n       * No visibility was explicitly specified. This is typically treated as private.\n       * The distinction is important when two separate R.java files are generated: a public and\n       * private one. An unknown visibility, in this case, would cause the resource to be omitted\n       * from either R.java.\n       * </pre>\n       *\n       * <code>UNKNOWN = 0;</code>\n       */\n      UNKNOWN(0),\n      /**\n       * <pre>\n       * A resource was explicitly marked as private. This means the resource can not be accessed\n       * outside of its package unless the &#64;*package:type/entry notation is used (the asterisk being\n       * the private accessor). If two R.java files are generated (private + public), the resource\n       * will only be emitted to the private R.java file.\n       * </pre>\n       *\n       * <code>PRIVATE = 1;</code>\n       */\n      PRIVATE(1),\n      /**\n       * <pre>\n       * A resource was explicitly marked as public. This means the resource can be accessed\n       * from any package, and is emitted into all R.java files, public and private.\n       * </pre>\n       *\n       * <code>PUBLIC = 2;</code>\n       */\n      PUBLIC(2),\n      ;\n\n      /**\n       * <pre>\n       * No visibility was explicitly specified. This is typically treated as private.\n       * The distinction is important when two separate R.java files are generated: a public and\n       * private one. An unknown visibility, in this case, would cause the resource to be omitted\n       * from either R.java.\n       * </pre>\n       *\n       * <code>UNKNOWN = 0;</code>\n       */\n      public static final int UNKNOWN_VALUE = 0;\n      /**\n       * <pre>\n       * A resource was explicitly marked as private. This means the resource can not be accessed\n       * outside of its package unless the &#64;*package:type/entry notation is used (the asterisk being\n       * the private accessor). If two R.java files are generated (private + public), the resource\n       * will only be emitted to the private R.java file.\n       * </pre>\n       *\n       * <code>PRIVATE = 1;</code>\n       */\n      public static final int PRIVATE_VALUE = 1;\n      /**\n       * <pre>\n       * A resource was explicitly marked as public. This means the resource can be accessed\n       * from any package, and is emitted into all R.java files, public and private.\n       * </pre>\n       *\n       * <code>PUBLIC = 2;</code>\n       */\n      public static final int PUBLIC_VALUE = 2;\n\n\n      public final int getNumber() {\n        return value;\n      }\n\n      /**\n       * @deprecated Use {@link #forNumber(int)} instead.\n       */\n      @java.lang.Deprecated\n      public static Visibility valueOf(int value) {\n        return forNumber(value);\n      }\n\n      public static Visibility forNumber(int value) {\n        switch (value) {\n          case 0: return UNKNOWN;\n          case 1: return PRIVATE;\n          case 2: return PUBLIC;\n          default: return null;\n        }\n      }\n\n      public static com.google.protobuf.Internal.EnumLiteMap<Visibility>\n          internalGetValueMap() {\n        return internalValueMap;\n      }\n      private static final com.google.protobuf.Internal.EnumLiteMap<\n          Visibility> internalValueMap =\n            new com.google.protobuf.Internal.EnumLiteMap<Visibility>() {\n              public Visibility findValueByNumber(int number) {\n                return Visibility.forNumber(number);\n              }\n            };\n\n      private final int value;\n\n      private Visibility(int value) {\n        this.value = value;\n      }\n\n      // @@protoc_insertion_point(enum_scope:aapt.pb.SymbolStatus.Visibility)\n    }\n\n    private int bitField0_;\n    public static final int VISIBILITY_FIELD_NUMBER = 1;\n    private int visibility_;\n    /**\n     * <code>optional .aapt.pb.SymbolStatus.Visibility visibility = 1;</code>\n     */\n    public boolean hasVisibility() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <code>optional .aapt.pb.SymbolStatus.Visibility visibility = 1;</code>\n     */\n    public com.android.aapt.Resources.SymbolStatus.Visibility getVisibility() {\n      com.android.aapt.Resources.SymbolStatus.Visibility result = com.android.aapt.Resources.SymbolStatus.Visibility.forNumber(visibility_);\n      return result == null ? com.android.aapt.Resources.SymbolStatus.Visibility.UNKNOWN : result;\n    }\n    /**\n     * <code>optional .aapt.pb.SymbolStatus.Visibility visibility = 1;</code>\n     */\n    private void setVisibility(com.android.aapt.Resources.SymbolStatus.Visibility value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      bitField0_ |= 0x00000001;\n      visibility_ = value.getNumber();\n    }\n    /**\n     * <code>optional .aapt.pb.SymbolStatus.Visibility visibility = 1;</code>\n     */\n    private void clearVisibility() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      visibility_ = 0;\n    }\n\n    public static final int SOURCE_FIELD_NUMBER = 2;\n    private com.android.aapt.Resources.Source source_;\n    /**\n     * <pre>\n     * The path at which this entry's visibility was defined (eg. public.xml).\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 2;</code>\n     */\n    public boolean hasSource() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <pre>\n     * The path at which this entry's visibility was defined (eg. public.xml).\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 2;</code>\n     */\n    public com.android.aapt.Resources.Source getSource() {\n      return source_ == null ? com.android.aapt.Resources.Source.getDefaultInstance() : source_;\n    }\n    /**\n     * <pre>\n     * The path at which this entry's visibility was defined (eg. public.xml).\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 2;</code>\n     */\n    private void setSource(com.android.aapt.Resources.Source value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      source_ = value;\n      bitField0_ |= 0x00000002;\n      }\n    /**\n     * <pre>\n     * The path at which this entry's visibility was defined (eg. public.xml).\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 2;</code>\n     */\n    private void setSource(\n        com.android.aapt.Resources.Source.Builder builderForValue) {\n      source_ = builderForValue.build();\n      bitField0_ |= 0x00000002;\n    }\n    /**\n     * <pre>\n     * The path at which this entry's visibility was defined (eg. public.xml).\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 2;</code>\n     */\n    private void mergeSource(com.android.aapt.Resources.Source value) {\n      if (source_ != null &&\n          source_ != com.android.aapt.Resources.Source.getDefaultInstance()) {\n        source_ =\n          com.android.aapt.Resources.Source.newBuilder(source_).mergeFrom(value).buildPartial();\n      } else {\n        source_ = value;\n      }\n      bitField0_ |= 0x00000002;\n    }\n    /**\n     * <pre>\n     * The path at which this entry's visibility was defined (eg. public.xml).\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 2;</code>\n     */\n    private void clearSource() {  source_ = null;\n      bitField0_ = (bitField0_ & ~0x00000002);\n    }\n\n    public static final int COMMENT_FIELD_NUMBER = 3;\n    private java.lang.String comment_;\n    /**\n     * <pre>\n     * The comment associated with the &lt;public&gt; tag.\n     * </pre>\n     *\n     * <code>optional string comment = 3;</code>\n     */\n    public boolean hasComment() {\n      return ((bitField0_ & 0x00000004) == 0x00000004);\n    }\n    /**\n     * <pre>\n     * The comment associated with the &lt;public&gt; tag.\n     * </pre>\n     *\n     * <code>optional string comment = 3;</code>\n     */\n    public java.lang.String getComment() {\n      return comment_;\n    }\n    /**\n     * <pre>\n     * The comment associated with the &lt;public&gt; tag.\n     * </pre>\n     *\n     * <code>optional string comment = 3;</code>\n     */\n    public com.google.protobuf.ByteString\n        getCommentBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(comment_);\n    }\n    /**\n     * <pre>\n     * The comment associated with the &lt;public&gt; tag.\n     * </pre>\n     *\n     * <code>optional string comment = 3;</code>\n     */\n    private void setComment(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000004;\n      comment_ = value;\n    }\n    /**\n     * <pre>\n     * The comment associated with the &lt;public&gt; tag.\n     * </pre>\n     *\n     * <code>optional string comment = 3;</code>\n     */\n    private void clearComment() {\n      bitField0_ = (bitField0_ & ~0x00000004);\n      comment_ = getDefaultInstance().getComment();\n    }\n    /**\n     * <pre>\n     * The comment associated with the &lt;public&gt; tag.\n     * </pre>\n     *\n     * <code>optional string comment = 3;</code>\n     */\n    private void setCommentBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000004;\n      comment_ = value.toStringUtf8();\n    }\n\n    public static final int ALLOW_NEW_FIELD_NUMBER = 4;\n    private boolean allowNew_;\n    /**\n     * <pre>\n     * Whether the symbol can be merged into another resource table without there being an existing\n     * definition to override. Used for overlays and set to true when &lt;add-resource&gt; is specified.\n     * </pre>\n     *\n     * <code>optional bool allow_new = 4;</code>\n     */\n    public boolean hasAllowNew() {\n      return ((bitField0_ & 0x00000008) == 0x00000008);\n    }\n    /**\n     * <pre>\n     * Whether the symbol can be merged into another resource table without there being an existing\n     * definition to override. Used for overlays and set to true when &lt;add-resource&gt; is specified.\n     * </pre>\n     *\n     * <code>optional bool allow_new = 4;</code>\n     */\n    public boolean getAllowNew() {\n      return allowNew_;\n    }\n    /**\n     * <pre>\n     * Whether the symbol can be merged into another resource table without there being an existing\n     * definition to override. Used for overlays and set to true when &lt;add-resource&gt; is specified.\n     * </pre>\n     *\n     * <code>optional bool allow_new = 4;</code>\n     */\n    private void setAllowNew(boolean value) {\n      bitField0_ |= 0x00000008;\n      allowNew_ = value;\n    }\n    /**\n     * <pre>\n     * Whether the symbol can be merged into another resource table without there being an existing\n     * definition to override. Used for overlays and set to true when &lt;add-resource&gt; is specified.\n     * </pre>\n     *\n     * <code>optional bool allow_new = 4;</code>\n     */\n    private void clearAllowNew() {\n      bitField0_ = (bitField0_ & ~0x00000008);\n      allowNew_ = false;\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeEnum(1, visibility_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeMessage(2, getSource());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        output.writeString(3, getComment());\n      }\n      if (((bitField0_ & 0x00000008) == 0x00000008)) {\n        output.writeBool(4, allowNew_);\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeEnumSize(1, visibility_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(2, getSource());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(3, getComment());\n      }\n      if (((bitField0_ & 0x00000008) == 0x00000008)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeBoolSize(4, allowNew_);\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.SymbolStatus parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.SymbolStatus parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.SymbolStatus parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.SymbolStatus parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.SymbolStatus parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.SymbolStatus parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.SymbolStatus parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.SymbolStatus parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.SymbolStatus parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.SymbolStatus parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.SymbolStatus prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * The status of a symbol/entry. This contains information like visibility (public/private),\n     * comments, and whether the entry can be overridden.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.SymbolStatus}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.SymbolStatus, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.SymbolStatus)\n        com.android.aapt.Resources.SymbolStatusOrBuilder {\n      // Construct using com.android.aapt.Resources.SymbolStatus.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <code>optional .aapt.pb.SymbolStatus.Visibility visibility = 1;</code>\n       */\n      public boolean hasVisibility() {\n        return instance.hasVisibility();\n      }\n      /**\n       * <code>optional .aapt.pb.SymbolStatus.Visibility visibility = 1;</code>\n       */\n      public com.android.aapt.Resources.SymbolStatus.Visibility getVisibility() {\n        return instance.getVisibility();\n      }\n      /**\n       * <code>optional .aapt.pb.SymbolStatus.Visibility visibility = 1;</code>\n       */\n      public Builder setVisibility(com.android.aapt.Resources.SymbolStatus.Visibility value) {\n        copyOnWrite();\n        instance.setVisibility(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.SymbolStatus.Visibility visibility = 1;</code>\n       */\n      public Builder clearVisibility() {\n        copyOnWrite();\n        instance.clearVisibility();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The path at which this entry's visibility was defined (eg. public.xml).\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 2;</code>\n       */\n      public boolean hasSource() {\n        return instance.hasSource();\n      }\n      /**\n       * <pre>\n       * The path at which this entry's visibility was defined (eg. public.xml).\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 2;</code>\n       */\n      public com.android.aapt.Resources.Source getSource() {\n        return instance.getSource();\n      }\n      /**\n       * <pre>\n       * The path at which this entry's visibility was defined (eg. public.xml).\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 2;</code>\n       */\n      public Builder setSource(com.android.aapt.Resources.Source value) {\n        copyOnWrite();\n        instance.setSource(value);\n        return this;\n        }\n      /**\n       * <pre>\n       * The path at which this entry's visibility was defined (eg. public.xml).\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 2;</code>\n       */\n      public Builder setSource(\n          com.android.aapt.Resources.Source.Builder builderForValue) {\n        copyOnWrite();\n        instance.setSource(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The path at which this entry's visibility was defined (eg. public.xml).\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 2;</code>\n       */\n      public Builder mergeSource(com.android.aapt.Resources.Source value) {\n        copyOnWrite();\n        instance.mergeSource(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The path at which this entry's visibility was defined (eg. public.xml).\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 2;</code>\n       */\n      public Builder clearSource() {  copyOnWrite();\n        instance.clearSource();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The comment associated with the &lt;public&gt; tag.\n       * </pre>\n       *\n       * <code>optional string comment = 3;</code>\n       */\n      public boolean hasComment() {\n        return instance.hasComment();\n      }\n      /**\n       * <pre>\n       * The comment associated with the &lt;public&gt; tag.\n       * </pre>\n       *\n       * <code>optional string comment = 3;</code>\n       */\n      public java.lang.String getComment() {\n        return instance.getComment();\n      }\n      /**\n       * <pre>\n       * The comment associated with the &lt;public&gt; tag.\n       * </pre>\n       *\n       * <code>optional string comment = 3;</code>\n       */\n      public com.google.protobuf.ByteString\n          getCommentBytes() {\n        return instance.getCommentBytes();\n      }\n      /**\n       * <pre>\n       * The comment associated with the &lt;public&gt; tag.\n       * </pre>\n       *\n       * <code>optional string comment = 3;</code>\n       */\n      public Builder setComment(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setComment(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The comment associated with the &lt;public&gt; tag.\n       * </pre>\n       *\n       * <code>optional string comment = 3;</code>\n       */\n      public Builder clearComment() {\n        copyOnWrite();\n        instance.clearComment();\n        return this;\n      }\n      /**\n       * <pre>\n       * The comment associated with the &lt;public&gt; tag.\n       * </pre>\n       *\n       * <code>optional string comment = 3;</code>\n       */\n      public Builder setCommentBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setCommentBytes(value);\n        return this;\n      }\n\n      /**\n       * <pre>\n       * Whether the symbol can be merged into another resource table without there being an existing\n       * definition to override. Used for overlays and set to true when &lt;add-resource&gt; is specified.\n       * </pre>\n       *\n       * <code>optional bool allow_new = 4;</code>\n       */\n      public boolean hasAllowNew() {\n        return instance.hasAllowNew();\n      }\n      /**\n       * <pre>\n       * Whether the symbol can be merged into another resource table without there being an existing\n       * definition to override. Used for overlays and set to true when &lt;add-resource&gt; is specified.\n       * </pre>\n       *\n       * <code>optional bool allow_new = 4;</code>\n       */\n      public boolean getAllowNew() {\n        return instance.getAllowNew();\n      }\n      /**\n       * <pre>\n       * Whether the symbol can be merged into another resource table without there being an existing\n       * definition to override. Used for overlays and set to true when &lt;add-resource&gt; is specified.\n       * </pre>\n       *\n       * <code>optional bool allow_new = 4;</code>\n       */\n      public Builder setAllowNew(boolean value) {\n        copyOnWrite();\n        instance.setAllowNew(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Whether the symbol can be merged into another resource table without there being an existing\n       * definition to override. Used for overlays and set to true when &lt;add-resource&gt; is specified.\n       * </pre>\n       *\n       * <code>optional bool allow_new = 4;</code>\n       */\n      public Builder clearAllowNew() {\n        copyOnWrite();\n        instance.clearAllowNew();\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.SymbolStatus)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.SymbolStatus();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.SymbolStatus other = (com.android.aapt.Resources.SymbolStatus) arg1;\n          visibility_ = visitor.visitInt(hasVisibility(), visibility_,\n              other.hasVisibility(), other.visibility_);\n          source_ = visitor.visitMessage(source_, other.source_);\n          comment_ = visitor.visitString(\n              hasComment(), comment_,\n              other.hasComment(), other.comment_);\n          allowNew_ = visitor.visitBoolean(\n              hasAllowNew(), allowNew_,\n              other.hasAllowNew(), other.allowNew_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 8: {\n                  int rawValue = input.readEnum();\n                  com.android.aapt.Resources.SymbolStatus.Visibility value = com.android.aapt.Resources.SymbolStatus.Visibility.forNumber(rawValue);\n                  if (value == null) {\n                    super.mergeVarintField(1, rawValue);\n                  } else {\n                    bitField0_ |= 0x00000001;\n                    visibility_ = rawValue;\n                  }\n                  break;\n                }\n                case 18: {\n                  com.android.aapt.Resources.Source.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000002) == 0x00000002)) {\n                    subBuilder = source_.toBuilder();\n                  }\n                  source_ = input.readMessage(com.android.aapt.Resources.Source.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(source_);\n                    source_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000002;\n                  break;\n                }\n                case 26: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000004;\n                  comment_ = s;\n                  break;\n                }\n                case 32: {\n                  bitField0_ |= 0x00000008;\n                  allowNew_ = input.readBool();\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.SymbolStatus.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.SymbolStatus)\n    private static final com.android.aapt.Resources.SymbolStatus DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new SymbolStatus();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.SymbolStatus getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<SymbolStatus> PARSER;\n\n    public static com.google.protobuf.Parser<SymbolStatus> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface EntryOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.Entry)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * The ID of this entry. Together with the package ID and type ID, this forms a full resource ID\n     * of the form 0xPPTTEEEE, where PP is the package ID, TT is the type ID, and EEEE is the entry\n     * ID.\n     * </pre>\n     *\n     * <code>optional uint32 id = 1;</code>\n     */\n    boolean hasId();\n    /**\n     * <pre>\n     * The ID of this entry. Together with the package ID and type ID, this forms a full resource ID\n     * of the form 0xPPTTEEEE, where PP is the package ID, TT is the type ID, and EEEE is the entry\n     * ID.\n     * </pre>\n     *\n     * <code>optional uint32 id = 1;</code>\n     */\n    int getId();\n\n    /**\n     * <pre>\n     * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n     * form package:type/entry.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    boolean hasName();\n    /**\n     * <pre>\n     * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n     * form package:type/entry.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    java.lang.String getName();\n    /**\n     * <pre>\n     * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n     * form package:type/entry.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    com.google.protobuf.ByteString\n        getNameBytes();\n\n    /**\n     * <pre>\n     * The symbol status of this entry, which includes visibility information.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SymbolStatus symbol_status = 3;</code>\n     */\n    boolean hasSymbolStatus();\n    /**\n     * <pre>\n     * The symbol status of this entry, which includes visibility information.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SymbolStatus symbol_status = 3;</code>\n     */\n    com.android.aapt.Resources.SymbolStatus getSymbolStatus();\n\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    java.util.List<com.android.aapt.Resources.ConfigValue> \n        getConfigValueList();\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    com.android.aapt.Resources.ConfigValue getConfigValue(int index);\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    int getConfigValueCount();\n  }\n  /**\n   * <pre>\n   * An entry declaration. An entry has a full resource ID that is the combination of package ID,\n   * type ID, and its own entry ID. An entry on its own has no value, but values are defined for\n   * various configurations/variants.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.Entry}\n   */\n  public  static final class Entry extends\n      com.google.protobuf.GeneratedMessageLite<\n          Entry, Entry.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.Entry)\n      EntryOrBuilder {\n    private Entry() {\n      name_ = \"\";\n      configValue_ = emptyProtobufList();\n    }\n    private int bitField0_;\n    public static final int ID_FIELD_NUMBER = 1;\n    private int id_;\n    /**\n     * <pre>\n     * The ID of this entry. Together with the package ID and type ID, this forms a full resource ID\n     * of the form 0xPPTTEEEE, where PP is the package ID, TT is the type ID, and EEEE is the entry\n     * ID.\n     * </pre>\n     *\n     * <code>optional uint32 id = 1;</code>\n     */\n    public boolean hasId() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <pre>\n     * The ID of this entry. Together with the package ID and type ID, this forms a full resource ID\n     * of the form 0xPPTTEEEE, where PP is the package ID, TT is the type ID, and EEEE is the entry\n     * ID.\n     * </pre>\n     *\n     * <code>optional uint32 id = 1;</code>\n     */\n    public int getId() {\n      return id_;\n    }\n    /**\n     * <pre>\n     * The ID of this entry. Together with the package ID and type ID, this forms a full resource ID\n     * of the form 0xPPTTEEEE, where PP is the package ID, TT is the type ID, and EEEE is the entry\n     * ID.\n     * </pre>\n     *\n     * <code>optional uint32 id = 1;</code>\n     */\n    private void setId(int value) {\n      bitField0_ |= 0x00000001;\n      id_ = value;\n    }\n    /**\n     * <pre>\n     * The ID of this entry. Together with the package ID and type ID, this forms a full resource ID\n     * of the form 0xPPTTEEEE, where PP is the package ID, TT is the type ID, and EEEE is the entry\n     * ID.\n     * </pre>\n     *\n     * <code>optional uint32 id = 1;</code>\n     */\n    private void clearId() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      id_ = 0;\n    }\n\n    public static final int NAME_FIELD_NUMBER = 2;\n    private java.lang.String name_;\n    /**\n     * <pre>\n     * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n     * form package:type/entry.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    public boolean hasName() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <pre>\n     * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n     * form package:type/entry.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    public java.lang.String getName() {\n      return name_;\n    }\n    /**\n     * <pre>\n     * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n     * form package:type/entry.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    public com.google.protobuf.ByteString\n        getNameBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(name_);\n    }\n    /**\n     * <pre>\n     * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n     * form package:type/entry.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    private void setName(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      name_ = value;\n    }\n    /**\n     * <pre>\n     * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n     * form package:type/entry.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    private void clearName() {\n      bitField0_ = (bitField0_ & ~0x00000002);\n      name_ = getDefaultInstance().getName();\n    }\n    /**\n     * <pre>\n     * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n     * form package:type/entry.\n     * </pre>\n     *\n     * <code>optional string name = 2;</code>\n     */\n    private void setNameBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      name_ = value.toStringUtf8();\n    }\n\n    public static final int SYMBOL_STATUS_FIELD_NUMBER = 3;\n    private com.android.aapt.Resources.SymbolStatus symbolStatus_;\n    /**\n     * <pre>\n     * The symbol status of this entry, which includes visibility information.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SymbolStatus symbol_status = 3;</code>\n     */\n    public boolean hasSymbolStatus() {\n      return ((bitField0_ & 0x00000004) == 0x00000004);\n    }\n    /**\n     * <pre>\n     * The symbol status of this entry, which includes visibility information.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SymbolStatus symbol_status = 3;</code>\n     */\n    public com.android.aapt.Resources.SymbolStatus getSymbolStatus() {\n      return symbolStatus_ == null ? com.android.aapt.Resources.SymbolStatus.getDefaultInstance() : symbolStatus_;\n    }\n    /**\n     * <pre>\n     * The symbol status of this entry, which includes visibility information.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SymbolStatus symbol_status = 3;</code>\n     */\n    private void setSymbolStatus(com.android.aapt.Resources.SymbolStatus value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      symbolStatus_ = value;\n      bitField0_ |= 0x00000004;\n      }\n    /**\n     * <pre>\n     * The symbol status of this entry, which includes visibility information.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SymbolStatus symbol_status = 3;</code>\n     */\n    private void setSymbolStatus(\n        com.android.aapt.Resources.SymbolStatus.Builder builderForValue) {\n      symbolStatus_ = builderForValue.build();\n      bitField0_ |= 0x00000004;\n    }\n    /**\n     * <pre>\n     * The symbol status of this entry, which includes visibility information.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SymbolStatus symbol_status = 3;</code>\n     */\n    private void mergeSymbolStatus(com.android.aapt.Resources.SymbolStatus value) {\n      if (symbolStatus_ != null &&\n          symbolStatus_ != com.android.aapt.Resources.SymbolStatus.getDefaultInstance()) {\n        symbolStatus_ =\n          com.android.aapt.Resources.SymbolStatus.newBuilder(symbolStatus_).mergeFrom(value).buildPartial();\n      } else {\n        symbolStatus_ = value;\n      }\n      bitField0_ |= 0x00000004;\n    }\n    /**\n     * <pre>\n     * The symbol status of this entry, which includes visibility information.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SymbolStatus symbol_status = 3;</code>\n     */\n    private void clearSymbolStatus() {  symbolStatus_ = null;\n      bitField0_ = (bitField0_ & ~0x00000004);\n    }\n\n    public static final int CONFIG_VALUE_FIELD_NUMBER = 4;\n    private com.google.protobuf.Internal.ProtobufList<com.android.aapt.Resources.ConfigValue> configValue_;\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    public java.util.List<com.android.aapt.Resources.ConfigValue> getConfigValueList() {\n      return configValue_;\n    }\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    public java.util.List<? extends com.android.aapt.Resources.ConfigValueOrBuilder> \n        getConfigValueOrBuilderList() {\n      return configValue_;\n    }\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    public int getConfigValueCount() {\n      return configValue_.size();\n    }\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    public com.android.aapt.Resources.ConfigValue getConfigValue(int index) {\n      return configValue_.get(index);\n    }\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    public com.android.aapt.Resources.ConfigValueOrBuilder getConfigValueOrBuilder(\n        int index) {\n      return configValue_.get(index);\n    }\n    private void ensureConfigValueIsMutable() {\n      if (!configValue_.isModifiable()) {\n        configValue_ =\n            com.google.protobuf.GeneratedMessageLite.mutableCopy(configValue_);\n       }\n    }\n\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    private void setConfigValue(\n        int index, com.android.aapt.Resources.ConfigValue value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureConfigValueIsMutable();\n      configValue_.set(index, value);\n    }\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    private void setConfigValue(\n        int index, com.android.aapt.Resources.ConfigValue.Builder builderForValue) {\n      ensureConfigValueIsMutable();\n      configValue_.set(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    private void addConfigValue(com.android.aapt.Resources.ConfigValue value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureConfigValueIsMutable();\n      configValue_.add(value);\n    }\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    private void addConfigValue(\n        int index, com.android.aapt.Resources.ConfigValue value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureConfigValueIsMutable();\n      configValue_.add(index, value);\n    }\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    private void addConfigValue(\n        com.android.aapt.Resources.ConfigValue.Builder builderForValue) {\n      ensureConfigValueIsMutable();\n      configValue_.add(builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    private void addConfigValue(\n        int index, com.android.aapt.Resources.ConfigValue.Builder builderForValue) {\n      ensureConfigValueIsMutable();\n      configValue_.add(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    private void addAllConfigValue(\n        java.lang.Iterable<? extends com.android.aapt.Resources.ConfigValue> values) {\n      ensureConfigValueIsMutable();\n      com.google.protobuf.AbstractMessageLite.addAll(\n          values, configValue_);\n    }\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    private void clearConfigValue() {\n      configValue_ = emptyProtobufList();\n    }\n    /**\n     * <pre>\n     * The set of values defined for this entry, each corresponding to a different\n     * configuration/variant.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n     */\n    private void removeConfigValue(int index) {\n      ensureConfigValueIsMutable();\n      configValue_.remove(index);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeUInt32(1, id_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeString(2, getName());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        output.writeMessage(3, getSymbolStatus());\n      }\n      for (int i = 0; i < configValue_.size(); i++) {\n        output.writeMessage(4, configValue_.get(i));\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeUInt32Size(1, id_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(2, getName());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(3, getSymbolStatus());\n      }\n      for (int i = 0; i < configValue_.size(); i++) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(4, configValue_.get(i));\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.Entry parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Entry parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Entry parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Entry parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Entry parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Entry parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Entry parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Entry parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Entry parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Entry parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.Entry prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * An entry declaration. An entry has a full resource ID that is the combination of package ID,\n     * type ID, and its own entry ID. An entry on its own has no value, but values are defined for\n     * various configurations/variants.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Entry}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.Entry, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.Entry)\n        com.android.aapt.Resources.EntryOrBuilder {\n      // Construct using com.android.aapt.Resources.Entry.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * The ID of this entry. Together with the package ID and type ID, this forms a full resource ID\n       * of the form 0xPPTTEEEE, where PP is the package ID, TT is the type ID, and EEEE is the entry\n       * ID.\n       * </pre>\n       *\n       * <code>optional uint32 id = 1;</code>\n       */\n      public boolean hasId() {\n        return instance.hasId();\n      }\n      /**\n       * <pre>\n       * The ID of this entry. Together with the package ID and type ID, this forms a full resource ID\n       * of the form 0xPPTTEEEE, where PP is the package ID, TT is the type ID, and EEEE is the entry\n       * ID.\n       * </pre>\n       *\n       * <code>optional uint32 id = 1;</code>\n       */\n      public int getId() {\n        return instance.getId();\n      }\n      /**\n       * <pre>\n       * The ID of this entry. Together with the package ID and type ID, this forms a full resource ID\n       * of the form 0xPPTTEEEE, where PP is the package ID, TT is the type ID, and EEEE is the entry\n       * ID.\n       * </pre>\n       *\n       * <code>optional uint32 id = 1;</code>\n       */\n      public Builder setId(int value) {\n        copyOnWrite();\n        instance.setId(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The ID of this entry. Together with the package ID and type ID, this forms a full resource ID\n       * of the form 0xPPTTEEEE, where PP is the package ID, TT is the type ID, and EEEE is the entry\n       * ID.\n       * </pre>\n       *\n       * <code>optional uint32 id = 1;</code>\n       */\n      public Builder clearId() {\n        copyOnWrite();\n        instance.clearId();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n       * form package:type/entry.\n       * </pre>\n       *\n       * <code>optional string name = 2;</code>\n       */\n      public boolean hasName() {\n        return instance.hasName();\n      }\n      /**\n       * <pre>\n       * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n       * form package:type/entry.\n       * </pre>\n       *\n       * <code>optional string name = 2;</code>\n       */\n      public java.lang.String getName() {\n        return instance.getName();\n      }\n      /**\n       * <pre>\n       * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n       * form package:type/entry.\n       * </pre>\n       *\n       * <code>optional string name = 2;</code>\n       */\n      public com.google.protobuf.ByteString\n          getNameBytes() {\n        return instance.getNameBytes();\n      }\n      /**\n       * <pre>\n       * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n       * form package:type/entry.\n       * </pre>\n       *\n       * <code>optional string name = 2;</code>\n       */\n      public Builder setName(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setName(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n       * form package:type/entry.\n       * </pre>\n       *\n       * <code>optional string name = 2;</code>\n       */\n      public Builder clearName() {\n        copyOnWrite();\n        instance.clearName();\n        return this;\n      }\n      /**\n       * <pre>\n       * The name of this entry. This corresponds to the 'entry' part of a full resource name of the\n       * form package:type/entry.\n       * </pre>\n       *\n       * <code>optional string name = 2;</code>\n       */\n      public Builder setNameBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setNameBytes(value);\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The symbol status of this entry, which includes visibility information.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SymbolStatus symbol_status = 3;</code>\n       */\n      public boolean hasSymbolStatus() {\n        return instance.hasSymbolStatus();\n      }\n      /**\n       * <pre>\n       * The symbol status of this entry, which includes visibility information.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SymbolStatus symbol_status = 3;</code>\n       */\n      public com.android.aapt.Resources.SymbolStatus getSymbolStatus() {\n        return instance.getSymbolStatus();\n      }\n      /**\n       * <pre>\n       * The symbol status of this entry, which includes visibility information.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SymbolStatus symbol_status = 3;</code>\n       */\n      public Builder setSymbolStatus(com.android.aapt.Resources.SymbolStatus value) {\n        copyOnWrite();\n        instance.setSymbolStatus(value);\n        return this;\n        }\n      /**\n       * <pre>\n       * The symbol status of this entry, which includes visibility information.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SymbolStatus symbol_status = 3;</code>\n       */\n      public Builder setSymbolStatus(\n          com.android.aapt.Resources.SymbolStatus.Builder builderForValue) {\n        copyOnWrite();\n        instance.setSymbolStatus(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The symbol status of this entry, which includes visibility information.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SymbolStatus symbol_status = 3;</code>\n       */\n      public Builder mergeSymbolStatus(com.android.aapt.Resources.SymbolStatus value) {\n        copyOnWrite();\n        instance.mergeSymbolStatus(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The symbol status of this entry, which includes visibility information.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SymbolStatus symbol_status = 3;</code>\n       */\n      public Builder clearSymbolStatus() {  copyOnWrite();\n        instance.clearSymbolStatus();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The set of values defined for this entry, each corresponding to a different\n       * configuration/variant.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n       */\n      public java.util.List<com.android.aapt.Resources.ConfigValue> getConfigValueList() {\n        return java.util.Collections.unmodifiableList(\n            instance.getConfigValueList());\n      }\n      /**\n       * <pre>\n       * The set of values defined for this entry, each corresponding to a different\n       * configuration/variant.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n       */\n      public int getConfigValueCount() {\n        return instance.getConfigValueCount();\n      }/**\n       * <pre>\n       * The set of values defined for this entry, each corresponding to a different\n       * configuration/variant.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n       */\n      public com.android.aapt.Resources.ConfigValue getConfigValue(int index) {\n        return instance.getConfigValue(index);\n      }\n      /**\n       * <pre>\n       * The set of values defined for this entry, each corresponding to a different\n       * configuration/variant.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n       */\n      public Builder setConfigValue(\n          int index, com.android.aapt.Resources.ConfigValue value) {\n        copyOnWrite();\n        instance.setConfigValue(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of values defined for this entry, each corresponding to a different\n       * configuration/variant.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n       */\n      public Builder setConfigValue(\n          int index, com.android.aapt.Resources.ConfigValue.Builder builderForValue) {\n        copyOnWrite();\n        instance.setConfigValue(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of values defined for this entry, each corresponding to a different\n       * configuration/variant.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n       */\n      public Builder addConfigValue(com.android.aapt.Resources.ConfigValue value) {\n        copyOnWrite();\n        instance.addConfigValue(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of values defined for this entry, each corresponding to a different\n       * configuration/variant.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n       */\n      public Builder addConfigValue(\n          int index, com.android.aapt.Resources.ConfigValue value) {\n        copyOnWrite();\n        instance.addConfigValue(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of values defined for this entry, each corresponding to a different\n       * configuration/variant.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n       */\n      public Builder addConfigValue(\n          com.android.aapt.Resources.ConfigValue.Builder builderForValue) {\n        copyOnWrite();\n        instance.addConfigValue(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of values defined for this entry, each corresponding to a different\n       * configuration/variant.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n       */\n      public Builder addConfigValue(\n          int index, com.android.aapt.Resources.ConfigValue.Builder builderForValue) {\n        copyOnWrite();\n        instance.addConfigValue(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of values defined for this entry, each corresponding to a different\n       * configuration/variant.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n       */\n      public Builder addAllConfigValue(\n          java.lang.Iterable<? extends com.android.aapt.Resources.ConfigValue> values) {\n        copyOnWrite();\n        instance.addAllConfigValue(values);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of values defined for this entry, each corresponding to a different\n       * configuration/variant.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n       */\n      public Builder clearConfigValue() {\n        copyOnWrite();\n        instance.clearConfigValue();\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of values defined for this entry, each corresponding to a different\n       * configuration/variant.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.ConfigValue config_value = 4;</code>\n       */\n      public Builder removeConfigValue(int index) {\n        copyOnWrite();\n        instance.removeConfigValue(index);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.Entry)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.Entry();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          configValue_.makeImmutable();\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.Entry other = (com.android.aapt.Resources.Entry) arg1;\n          id_ = visitor.visitInt(\n              hasId(), id_,\n              other.hasId(), other.id_);\n          name_ = visitor.visitString(\n              hasName(), name_,\n              other.hasName(), other.name_);\n          symbolStatus_ = visitor.visitMessage(symbolStatus_, other.symbolStatus_);\n          configValue_= visitor.visitList(configValue_, other.configValue_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 8: {\n                  bitField0_ |= 0x00000001;\n                  id_ = input.readUInt32();\n                  break;\n                }\n                case 18: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000002;\n                  name_ = s;\n                  break;\n                }\n                case 26: {\n                  com.android.aapt.Resources.SymbolStatus.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000004) == 0x00000004)) {\n                    subBuilder = symbolStatus_.toBuilder();\n                  }\n                  symbolStatus_ = input.readMessage(com.android.aapt.Resources.SymbolStatus.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(symbolStatus_);\n                    symbolStatus_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000004;\n                  break;\n                }\n                case 34: {\n                  if (!configValue_.isModifiable()) {\n                    configValue_ =\n                        com.google.protobuf.GeneratedMessageLite.mutableCopy(configValue_);\n                  }\n                  configValue_.add(\n                      input.readMessage(com.android.aapt.Resources.ConfigValue.parser(), extensionRegistry));\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.Entry.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.Entry)\n    private static final com.android.aapt.Resources.Entry DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new Entry();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.Entry getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<Entry> PARSER;\n\n    public static com.google.protobuf.Parser<Entry> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface ConfigValueOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.ConfigValue)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <code>optional .aapt.pb.ConfigDescription config = 1;</code>\n     */\n    boolean hasConfig();\n    /**\n     * <code>optional .aapt.pb.ConfigDescription config = 1;</code>\n     */\n    com.android.aapt.Resources.ConfigDescription getConfig();\n\n    /**\n     * <code>optional .aapt.pb.Value value = 2;</code>\n     */\n    boolean hasValue();\n    /**\n     * <code>optional .aapt.pb.Value value = 2;</code>\n     */\n    com.android.aapt.Resources.Value getValue();\n  }\n  /**\n   * <pre>\n   * A Configuration/Value pair.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.ConfigValue}\n   */\n  public  static final class ConfigValue extends\n      com.google.protobuf.GeneratedMessageLite<\n          ConfigValue, ConfigValue.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.ConfigValue)\n      ConfigValueOrBuilder {\n    private ConfigValue() {\n    }\n    private int bitField0_;\n    public static final int CONFIG_FIELD_NUMBER = 1;\n    private com.android.aapt.Resources.ConfigDescription config_;\n    /**\n     * <code>optional .aapt.pb.ConfigDescription config = 1;</code>\n     */\n    public boolean hasConfig() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <code>optional .aapt.pb.ConfigDescription config = 1;</code>\n     */\n    public com.android.aapt.Resources.ConfigDescription getConfig() {\n      return config_ == null ? com.android.aapt.Resources.ConfigDescription.getDefaultInstance() : config_;\n    }\n    /**\n     * <code>optional .aapt.pb.ConfigDescription config = 1;</code>\n     */\n    private void setConfig(com.android.aapt.Resources.ConfigDescription value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      config_ = value;\n      bitField0_ |= 0x00000001;\n      }\n    /**\n     * <code>optional .aapt.pb.ConfigDescription config = 1;</code>\n     */\n    private void setConfig(\n        com.android.aapt.Resources.ConfigDescription.Builder builderForValue) {\n      config_ = builderForValue.build();\n      bitField0_ |= 0x00000001;\n    }\n    /**\n     * <code>optional .aapt.pb.ConfigDescription config = 1;</code>\n     */\n    private void mergeConfig(com.android.aapt.Resources.ConfigDescription value) {\n      if (config_ != null &&\n          config_ != com.android.aapt.Resources.ConfigDescription.getDefaultInstance()) {\n        config_ =\n          com.android.aapt.Resources.ConfigDescription.newBuilder(config_).mergeFrom(value).buildPartial();\n      } else {\n        config_ = value;\n      }\n      bitField0_ |= 0x00000001;\n    }\n    /**\n     * <code>optional .aapt.pb.ConfigDescription config = 1;</code>\n     */\n    private void clearConfig() {  config_ = null;\n      bitField0_ = (bitField0_ & ~0x00000001);\n    }\n\n    public static final int VALUE_FIELD_NUMBER = 2;\n    private com.android.aapt.Resources.Value value_;\n    /**\n     * <code>optional .aapt.pb.Value value = 2;</code>\n     */\n    public boolean hasValue() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <code>optional .aapt.pb.Value value = 2;</code>\n     */\n    public com.android.aapt.Resources.Value getValue() {\n      return value_ == null ? com.android.aapt.Resources.Value.getDefaultInstance() : value_;\n    }\n    /**\n     * <code>optional .aapt.pb.Value value = 2;</code>\n     */\n    private void setValue(com.android.aapt.Resources.Value value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      value_ = value;\n      bitField0_ |= 0x00000002;\n      }\n    /**\n     * <code>optional .aapt.pb.Value value = 2;</code>\n     */\n    private void setValue(\n        com.android.aapt.Resources.Value.Builder builderForValue) {\n      value_ = builderForValue.build();\n      bitField0_ |= 0x00000002;\n    }\n    /**\n     * <code>optional .aapt.pb.Value value = 2;</code>\n     */\n    private void mergeValue(com.android.aapt.Resources.Value value) {\n      if (value_ != null &&\n          value_ != com.android.aapt.Resources.Value.getDefaultInstance()) {\n        value_ =\n          com.android.aapt.Resources.Value.newBuilder(value_).mergeFrom(value).buildPartial();\n      } else {\n        value_ = value;\n      }\n      bitField0_ |= 0x00000002;\n    }\n    /**\n     * <code>optional .aapt.pb.Value value = 2;</code>\n     */\n    private void clearValue() {  value_ = null;\n      bitField0_ = (bitField0_ & ~0x00000002);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeMessage(1, getConfig());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeMessage(2, getValue());\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(1, getConfig());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(2, getValue());\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.ConfigValue parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.ConfigValue parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.ConfigValue parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.ConfigValue parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.ConfigValue parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.ConfigValue parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.ConfigValue parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.ConfigValue parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.ConfigValue parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.ConfigValue parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.ConfigValue prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A Configuration/Value pair.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.ConfigValue}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.ConfigValue, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.ConfigValue)\n        com.android.aapt.Resources.ConfigValueOrBuilder {\n      // Construct using com.android.aapt.Resources.ConfigValue.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <code>optional .aapt.pb.ConfigDescription config = 1;</code>\n       */\n      public boolean hasConfig() {\n        return instance.hasConfig();\n      }\n      /**\n       * <code>optional .aapt.pb.ConfigDescription config = 1;</code>\n       */\n      public com.android.aapt.Resources.ConfigDescription getConfig() {\n        return instance.getConfig();\n      }\n      /**\n       * <code>optional .aapt.pb.ConfigDescription config = 1;</code>\n       */\n      public Builder setConfig(com.android.aapt.Resources.ConfigDescription value) {\n        copyOnWrite();\n        instance.setConfig(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.ConfigDescription config = 1;</code>\n       */\n      public Builder setConfig(\n          com.android.aapt.Resources.ConfigDescription.Builder builderForValue) {\n        copyOnWrite();\n        instance.setConfig(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.ConfigDescription config = 1;</code>\n       */\n      public Builder mergeConfig(com.android.aapt.Resources.ConfigDescription value) {\n        copyOnWrite();\n        instance.mergeConfig(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.ConfigDescription config = 1;</code>\n       */\n      public Builder clearConfig() {  copyOnWrite();\n        instance.clearConfig();\n        return this;\n      }\n\n      /**\n       * <code>optional .aapt.pb.Value value = 2;</code>\n       */\n      public boolean hasValue() {\n        return instance.hasValue();\n      }\n      /**\n       * <code>optional .aapt.pb.Value value = 2;</code>\n       */\n      public com.android.aapt.Resources.Value getValue() {\n        return instance.getValue();\n      }\n      /**\n       * <code>optional .aapt.pb.Value value = 2;</code>\n       */\n      public Builder setValue(com.android.aapt.Resources.Value value) {\n        copyOnWrite();\n        instance.setValue(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.Value value = 2;</code>\n       */\n      public Builder setValue(\n          com.android.aapt.Resources.Value.Builder builderForValue) {\n        copyOnWrite();\n        instance.setValue(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Value value = 2;</code>\n       */\n      public Builder mergeValue(com.android.aapt.Resources.Value value) {\n        copyOnWrite();\n        instance.mergeValue(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Value value = 2;</code>\n       */\n      public Builder clearValue() {  copyOnWrite();\n        instance.clearValue();\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.ConfigValue)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.ConfigValue();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.ConfigValue other = (com.android.aapt.Resources.ConfigValue) arg1;\n          config_ = visitor.visitMessage(config_, other.config_);\n          value_ = visitor.visitMessage(value_, other.value_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  com.android.aapt.Resources.ConfigDescription.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                    subBuilder = config_.toBuilder();\n                  }\n                  config_ = input.readMessage(com.android.aapt.Resources.ConfigDescription.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(config_);\n                    config_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000001;\n                  break;\n                }\n                case 18: {\n                  com.android.aapt.Resources.Value.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000002) == 0x00000002)) {\n                    subBuilder = value_.toBuilder();\n                  }\n                  value_ = input.readMessage(com.android.aapt.Resources.Value.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(value_);\n                    value_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000002;\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.ConfigValue.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.ConfigValue)\n    private static final com.android.aapt.Resources.ConfigValue DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new ConfigValue();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.ConfigValue getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<ConfigValue> PARSER;\n\n    public static com.google.protobuf.Parser<ConfigValue> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface ValueOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.Value)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * Where the value was defined.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 1;</code>\n     */\n    boolean hasSource();\n    /**\n     * <pre>\n     * Where the value was defined.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 1;</code>\n     */\n    com.android.aapt.Resources.Source getSource();\n\n    /**\n     * <pre>\n     * Any comment associated with the value.\n     * </pre>\n     *\n     * <code>optional string comment = 2;</code>\n     */\n    boolean hasComment();\n    /**\n     * <pre>\n     * Any comment associated with the value.\n     * </pre>\n     *\n     * <code>optional string comment = 2;</code>\n     */\n    java.lang.String getComment();\n    /**\n     * <pre>\n     * Any comment associated with the value.\n     * </pre>\n     *\n     * <code>optional string comment = 2;</code>\n     */\n    com.google.protobuf.ByteString\n        getCommentBytes();\n\n    /**\n     * <pre>\n     * Whether the value can be overridden.\n     * </pre>\n     *\n     * <code>optional bool weak = 3;</code>\n     */\n    boolean hasWeak();\n    /**\n     * <pre>\n     * Whether the value can be overridden.\n     * </pre>\n     *\n     * <code>optional bool weak = 3;</code>\n     */\n    boolean getWeak();\n\n    /**\n     * <pre>\n     * If the value is an Item, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item item = 4;</code>\n     */\n    boolean hasItem();\n    /**\n     * <pre>\n     * If the value is an Item, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item item = 4;</code>\n     */\n    com.android.aapt.Resources.Item getItem();\n\n    /**\n     * <pre>\n     * If the value is a CompoundValue, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.CompoundValue compound_value = 5;</code>\n     */\n    boolean hasCompoundValue();\n    /**\n     * <pre>\n     * If the value is a CompoundValue, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.CompoundValue compound_value = 5;</code>\n     */\n    com.android.aapt.Resources.CompoundValue getCompoundValue();\n  }\n  /**\n   * <pre>\n   * The generic meta-data for every value in a resource table.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.Value}\n   */\n  public  static final class Value extends\n      com.google.protobuf.GeneratedMessageLite<\n          Value, Value.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.Value)\n      ValueOrBuilder {\n    private Value() {\n      comment_ = \"\";\n    }\n    private int bitField0_;\n    public static final int SOURCE_FIELD_NUMBER = 1;\n    private com.android.aapt.Resources.Source source_;\n    /**\n     * <pre>\n     * Where the value was defined.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 1;</code>\n     */\n    public boolean hasSource() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <pre>\n     * Where the value was defined.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 1;</code>\n     */\n    public com.android.aapt.Resources.Source getSource() {\n      return source_ == null ? com.android.aapt.Resources.Source.getDefaultInstance() : source_;\n    }\n    /**\n     * <pre>\n     * Where the value was defined.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 1;</code>\n     */\n    private void setSource(com.android.aapt.Resources.Source value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      source_ = value;\n      bitField0_ |= 0x00000001;\n      }\n    /**\n     * <pre>\n     * Where the value was defined.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 1;</code>\n     */\n    private void setSource(\n        com.android.aapt.Resources.Source.Builder builderForValue) {\n      source_ = builderForValue.build();\n      bitField0_ |= 0x00000001;\n    }\n    /**\n     * <pre>\n     * Where the value was defined.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 1;</code>\n     */\n    private void mergeSource(com.android.aapt.Resources.Source value) {\n      if (source_ != null &&\n          source_ != com.android.aapt.Resources.Source.getDefaultInstance()) {\n        source_ =\n          com.android.aapt.Resources.Source.newBuilder(source_).mergeFrom(value).buildPartial();\n      } else {\n        source_ = value;\n      }\n      bitField0_ |= 0x00000001;\n    }\n    /**\n     * <pre>\n     * Where the value was defined.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source source = 1;</code>\n     */\n    private void clearSource() {  source_ = null;\n      bitField0_ = (bitField0_ & ~0x00000001);\n    }\n\n    public static final int COMMENT_FIELD_NUMBER = 2;\n    private java.lang.String comment_;\n    /**\n     * <pre>\n     * Any comment associated with the value.\n     * </pre>\n     *\n     * <code>optional string comment = 2;</code>\n     */\n    public boolean hasComment() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <pre>\n     * Any comment associated with the value.\n     * </pre>\n     *\n     * <code>optional string comment = 2;</code>\n     */\n    public java.lang.String getComment() {\n      return comment_;\n    }\n    /**\n     * <pre>\n     * Any comment associated with the value.\n     * </pre>\n     *\n     * <code>optional string comment = 2;</code>\n     */\n    public com.google.protobuf.ByteString\n        getCommentBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(comment_);\n    }\n    /**\n     * <pre>\n     * Any comment associated with the value.\n     * </pre>\n     *\n     * <code>optional string comment = 2;</code>\n     */\n    private void setComment(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      comment_ = value;\n    }\n    /**\n     * <pre>\n     * Any comment associated with the value.\n     * </pre>\n     *\n     * <code>optional string comment = 2;</code>\n     */\n    private void clearComment() {\n      bitField0_ = (bitField0_ & ~0x00000002);\n      comment_ = getDefaultInstance().getComment();\n    }\n    /**\n     * <pre>\n     * Any comment associated with the value.\n     * </pre>\n     *\n     * <code>optional string comment = 2;</code>\n     */\n    private void setCommentBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      comment_ = value.toStringUtf8();\n    }\n\n    public static final int WEAK_FIELD_NUMBER = 3;\n    private boolean weak_;\n    /**\n     * <pre>\n     * Whether the value can be overridden.\n     * </pre>\n     *\n     * <code>optional bool weak = 3;</code>\n     */\n    public boolean hasWeak() {\n      return ((bitField0_ & 0x00000004) == 0x00000004);\n    }\n    /**\n     * <pre>\n     * Whether the value can be overridden.\n     * </pre>\n     *\n     * <code>optional bool weak = 3;</code>\n     */\n    public boolean getWeak() {\n      return weak_;\n    }\n    /**\n     * <pre>\n     * Whether the value can be overridden.\n     * </pre>\n     *\n     * <code>optional bool weak = 3;</code>\n     */\n    private void setWeak(boolean value) {\n      bitField0_ |= 0x00000004;\n      weak_ = value;\n    }\n    /**\n     * <pre>\n     * Whether the value can be overridden.\n     * </pre>\n     *\n     * <code>optional bool weak = 3;</code>\n     */\n    private void clearWeak() {\n      bitField0_ = (bitField0_ & ~0x00000004);\n      weak_ = false;\n    }\n\n    public static final int ITEM_FIELD_NUMBER = 4;\n    private com.android.aapt.Resources.Item item_;\n    /**\n     * <pre>\n     * If the value is an Item, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item item = 4;</code>\n     */\n    public boolean hasItem() {\n      return ((bitField0_ & 0x00000008) == 0x00000008);\n    }\n    /**\n     * <pre>\n     * If the value is an Item, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item item = 4;</code>\n     */\n    public com.android.aapt.Resources.Item getItem() {\n      return item_ == null ? com.android.aapt.Resources.Item.getDefaultInstance() : item_;\n    }\n    /**\n     * <pre>\n     * If the value is an Item, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item item = 4;</code>\n     */\n    private void setItem(com.android.aapt.Resources.Item value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      item_ = value;\n      bitField0_ |= 0x00000008;\n      }\n    /**\n     * <pre>\n     * If the value is an Item, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item item = 4;</code>\n     */\n    private void setItem(\n        com.android.aapt.Resources.Item.Builder builderForValue) {\n      item_ = builderForValue.build();\n      bitField0_ |= 0x00000008;\n    }\n    /**\n     * <pre>\n     * If the value is an Item, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item item = 4;</code>\n     */\n    private void mergeItem(com.android.aapt.Resources.Item value) {\n      if (item_ != null &&\n          item_ != com.android.aapt.Resources.Item.getDefaultInstance()) {\n        item_ =\n          com.android.aapt.Resources.Item.newBuilder(item_).mergeFrom(value).buildPartial();\n      } else {\n        item_ = value;\n      }\n      bitField0_ |= 0x00000008;\n    }\n    /**\n     * <pre>\n     * If the value is an Item, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item item = 4;</code>\n     */\n    private void clearItem() {  item_ = null;\n      bitField0_ = (bitField0_ & ~0x00000008);\n    }\n\n    public static final int COMPOUND_VALUE_FIELD_NUMBER = 5;\n    private com.android.aapt.Resources.CompoundValue compoundValue_;\n    /**\n     * <pre>\n     * If the value is a CompoundValue, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.CompoundValue compound_value = 5;</code>\n     */\n    public boolean hasCompoundValue() {\n      return ((bitField0_ & 0x00000010) == 0x00000010);\n    }\n    /**\n     * <pre>\n     * If the value is a CompoundValue, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.CompoundValue compound_value = 5;</code>\n     */\n    public com.android.aapt.Resources.CompoundValue getCompoundValue() {\n      return compoundValue_ == null ? com.android.aapt.Resources.CompoundValue.getDefaultInstance() : compoundValue_;\n    }\n    /**\n     * <pre>\n     * If the value is a CompoundValue, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.CompoundValue compound_value = 5;</code>\n     */\n    private void setCompoundValue(com.android.aapt.Resources.CompoundValue value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      compoundValue_ = value;\n      bitField0_ |= 0x00000010;\n      }\n    /**\n     * <pre>\n     * If the value is a CompoundValue, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.CompoundValue compound_value = 5;</code>\n     */\n    private void setCompoundValue(\n        com.android.aapt.Resources.CompoundValue.Builder builderForValue) {\n      compoundValue_ = builderForValue.build();\n      bitField0_ |= 0x00000010;\n    }\n    /**\n     * <pre>\n     * If the value is a CompoundValue, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.CompoundValue compound_value = 5;</code>\n     */\n    private void mergeCompoundValue(com.android.aapt.Resources.CompoundValue value) {\n      if (compoundValue_ != null &&\n          compoundValue_ != com.android.aapt.Resources.CompoundValue.getDefaultInstance()) {\n        compoundValue_ =\n          com.android.aapt.Resources.CompoundValue.newBuilder(compoundValue_).mergeFrom(value).buildPartial();\n      } else {\n        compoundValue_ = value;\n      }\n      bitField0_ |= 0x00000010;\n    }\n    /**\n     * <pre>\n     * If the value is a CompoundValue, this is set.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.CompoundValue compound_value = 5;</code>\n     */\n    private void clearCompoundValue() {  compoundValue_ = null;\n      bitField0_ = (bitField0_ & ~0x00000010);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeMessage(1, getSource());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeString(2, getComment());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        output.writeBool(3, weak_);\n      }\n      if (((bitField0_ & 0x00000008) == 0x00000008)) {\n        output.writeMessage(4, getItem());\n      }\n      if (((bitField0_ & 0x00000010) == 0x00000010)) {\n        output.writeMessage(5, getCompoundValue());\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(1, getSource());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(2, getComment());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeBoolSize(3, weak_);\n      }\n      if (((bitField0_ & 0x00000008) == 0x00000008)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(4, getItem());\n      }\n      if (((bitField0_ & 0x00000010) == 0x00000010)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(5, getCompoundValue());\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.Value parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Value parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Value parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Value parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Value parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Value parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Value parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Value parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Value parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Value parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.Value prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * The generic meta-data for every value in a resource table.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Value}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.Value, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.Value)\n        com.android.aapt.Resources.ValueOrBuilder {\n      // Construct using com.android.aapt.Resources.Value.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * Where the value was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public boolean hasSource() {\n        return instance.hasSource();\n      }\n      /**\n       * <pre>\n       * Where the value was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public com.android.aapt.Resources.Source getSource() {\n        return instance.getSource();\n      }\n      /**\n       * <pre>\n       * Where the value was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public Builder setSource(com.android.aapt.Resources.Source value) {\n        copyOnWrite();\n        instance.setSource(value);\n        return this;\n        }\n      /**\n       * <pre>\n       * Where the value was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public Builder setSource(\n          com.android.aapt.Resources.Source.Builder builderForValue) {\n        copyOnWrite();\n        instance.setSource(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * Where the value was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public Builder mergeSource(com.android.aapt.Resources.Source value) {\n        copyOnWrite();\n        instance.mergeSource(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Where the value was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public Builder clearSource() {  copyOnWrite();\n        instance.clearSource();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * Any comment associated with the value.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public boolean hasComment() {\n        return instance.hasComment();\n      }\n      /**\n       * <pre>\n       * Any comment associated with the value.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public java.lang.String getComment() {\n        return instance.getComment();\n      }\n      /**\n       * <pre>\n       * Any comment associated with the value.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public com.google.protobuf.ByteString\n          getCommentBytes() {\n        return instance.getCommentBytes();\n      }\n      /**\n       * <pre>\n       * Any comment associated with the value.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public Builder setComment(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setComment(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Any comment associated with the value.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public Builder clearComment() {\n        copyOnWrite();\n        instance.clearComment();\n        return this;\n      }\n      /**\n       * <pre>\n       * Any comment associated with the value.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public Builder setCommentBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setCommentBytes(value);\n        return this;\n      }\n\n      /**\n       * <pre>\n       * Whether the value can be overridden.\n       * </pre>\n       *\n       * <code>optional bool weak = 3;</code>\n       */\n      public boolean hasWeak() {\n        return instance.hasWeak();\n      }\n      /**\n       * <pre>\n       * Whether the value can be overridden.\n       * </pre>\n       *\n       * <code>optional bool weak = 3;</code>\n       */\n      public boolean getWeak() {\n        return instance.getWeak();\n      }\n      /**\n       * <pre>\n       * Whether the value can be overridden.\n       * </pre>\n       *\n       * <code>optional bool weak = 3;</code>\n       */\n      public Builder setWeak(boolean value) {\n        copyOnWrite();\n        instance.setWeak(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Whether the value can be overridden.\n       * </pre>\n       *\n       * <code>optional bool weak = 3;</code>\n       */\n      public Builder clearWeak() {\n        copyOnWrite();\n        instance.clearWeak();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * If the value is an Item, this is set.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      public boolean hasItem() {\n        return instance.hasItem();\n      }\n      /**\n       * <pre>\n       * If the value is an Item, this is set.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      public com.android.aapt.Resources.Item getItem() {\n        return instance.getItem();\n      }\n      /**\n       * <pre>\n       * If the value is an Item, this is set.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      public Builder setItem(com.android.aapt.Resources.Item value) {\n        copyOnWrite();\n        instance.setItem(value);\n        return this;\n        }\n      /**\n       * <pre>\n       * If the value is an Item, this is set.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      public Builder setItem(\n          com.android.aapt.Resources.Item.Builder builderForValue) {\n        copyOnWrite();\n        instance.setItem(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * If the value is an Item, this is set.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      public Builder mergeItem(com.android.aapt.Resources.Item value) {\n        copyOnWrite();\n        instance.mergeItem(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * If the value is an Item, this is set.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      public Builder clearItem() {  copyOnWrite();\n        instance.clearItem();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * If the value is a CompoundValue, this is set.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.CompoundValue compound_value = 5;</code>\n       */\n      public boolean hasCompoundValue() {\n        return instance.hasCompoundValue();\n      }\n      /**\n       * <pre>\n       * If the value is a CompoundValue, this is set.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.CompoundValue compound_value = 5;</code>\n       */\n      public com.android.aapt.Resources.CompoundValue getCompoundValue() {\n        return instance.getCompoundValue();\n      }\n      /**\n       * <pre>\n       * If the value is a CompoundValue, this is set.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.CompoundValue compound_value = 5;</code>\n       */\n      public Builder setCompoundValue(com.android.aapt.Resources.CompoundValue value) {\n        copyOnWrite();\n        instance.setCompoundValue(value);\n        return this;\n        }\n      /**\n       * <pre>\n       * If the value is a CompoundValue, this is set.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.CompoundValue compound_value = 5;</code>\n       */\n      public Builder setCompoundValue(\n          com.android.aapt.Resources.CompoundValue.Builder builderForValue) {\n        copyOnWrite();\n        instance.setCompoundValue(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * If the value is a CompoundValue, this is set.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.CompoundValue compound_value = 5;</code>\n       */\n      public Builder mergeCompoundValue(com.android.aapt.Resources.CompoundValue value) {\n        copyOnWrite();\n        instance.mergeCompoundValue(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * If the value is a CompoundValue, this is set.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.CompoundValue compound_value = 5;</code>\n       */\n      public Builder clearCompoundValue() {  copyOnWrite();\n        instance.clearCompoundValue();\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.Value)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.Value();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.Value other = (com.android.aapt.Resources.Value) arg1;\n          source_ = visitor.visitMessage(source_, other.source_);\n          comment_ = visitor.visitString(\n              hasComment(), comment_,\n              other.hasComment(), other.comment_);\n          weak_ = visitor.visitBoolean(\n              hasWeak(), weak_,\n              other.hasWeak(), other.weak_);\n          item_ = visitor.visitMessage(item_, other.item_);\n          compoundValue_ = visitor.visitMessage(compoundValue_, other.compoundValue_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  com.android.aapt.Resources.Source.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                    subBuilder = source_.toBuilder();\n                  }\n                  source_ = input.readMessage(com.android.aapt.Resources.Source.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(source_);\n                    source_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000001;\n                  break;\n                }\n                case 18: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000002;\n                  comment_ = s;\n                  break;\n                }\n                case 24: {\n                  bitField0_ |= 0x00000004;\n                  weak_ = input.readBool();\n                  break;\n                }\n                case 34: {\n                  com.android.aapt.Resources.Item.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000008) == 0x00000008)) {\n                    subBuilder = item_.toBuilder();\n                  }\n                  item_ = input.readMessage(com.android.aapt.Resources.Item.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(item_);\n                    item_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000008;\n                  break;\n                }\n                case 42: {\n                  com.android.aapt.Resources.CompoundValue.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000010) == 0x00000010)) {\n                    subBuilder = compoundValue_.toBuilder();\n                  }\n                  compoundValue_ = input.readMessage(com.android.aapt.Resources.CompoundValue.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(compoundValue_);\n                    compoundValue_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000010;\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.Value.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.Value)\n    private static final com.android.aapt.Resources.Value DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new Value();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.Value getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<Value> PARSER;\n\n    public static com.google.protobuf.Parser<Value> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface ItemOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.Item)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <code>optional .aapt.pb.Reference ref = 1;</code>\n     */\n    boolean hasRef();\n    /**\n     * <code>optional .aapt.pb.Reference ref = 1;</code>\n     */\n    com.android.aapt.Resources.Reference getRef();\n\n    /**\n     * <code>optional .aapt.pb.String str = 2;</code>\n     */\n    boolean hasStr();\n    /**\n     * <code>optional .aapt.pb.String str = 2;</code>\n     */\n    com.android.aapt.Resources.String getStr();\n\n    /**\n     * <code>optional .aapt.pb.RawString raw_str = 3;</code>\n     */\n    boolean hasRawStr();\n    /**\n     * <code>optional .aapt.pb.RawString raw_str = 3;</code>\n     */\n    com.android.aapt.Resources.RawString getRawStr();\n\n    /**\n     * <code>optional .aapt.pb.StyledString styled_str = 4;</code>\n     */\n    boolean hasStyledStr();\n    /**\n     * <code>optional .aapt.pb.StyledString styled_str = 4;</code>\n     */\n    com.android.aapt.Resources.StyledString getStyledStr();\n\n    /**\n     * <code>optional .aapt.pb.FileReference file = 5;</code>\n     */\n    boolean hasFile();\n    /**\n     * <code>optional .aapt.pb.FileReference file = 5;</code>\n     */\n    com.android.aapt.Resources.FileReference getFile();\n\n    /**\n     * <code>optional .aapt.pb.Id id = 6;</code>\n     */\n    boolean hasId();\n    /**\n     * <code>optional .aapt.pb.Id id = 6;</code>\n     */\n    com.android.aapt.Resources.Id getId();\n\n    /**\n     * <code>optional .aapt.pb.Primitive prim = 7;</code>\n     */\n    boolean hasPrim();\n    /**\n     * <code>optional .aapt.pb.Primitive prim = 7;</code>\n     */\n    com.android.aapt.Resources.Primitive getPrim();\n  }\n  /**\n   * <pre>\n   * An Item is an abstract type. It represents a value that can appear inline in many places, such\n   * as XML attribute values or on the right hand side of style attribute definitions. The concrete\n   * type is one of the types below. Only one can be set.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.Item}\n   */\n  public  static final class Item extends\n      com.google.protobuf.GeneratedMessageLite<\n          Item, Item.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.Item)\n      ItemOrBuilder {\n    private Item() {\n    }\n    private int bitField0_;\n    public static final int REF_FIELD_NUMBER = 1;\n    private com.android.aapt.Resources.Reference ref_;\n    /**\n     * <code>optional .aapt.pb.Reference ref = 1;</code>\n     */\n    public boolean hasRef() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <code>optional .aapt.pb.Reference ref = 1;</code>\n     */\n    public com.android.aapt.Resources.Reference getRef() {\n      return ref_ == null ? com.android.aapt.Resources.Reference.getDefaultInstance() : ref_;\n    }\n    /**\n     * <code>optional .aapt.pb.Reference ref = 1;</code>\n     */\n    private void setRef(com.android.aapt.Resources.Reference value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ref_ = value;\n      bitField0_ |= 0x00000001;\n      }\n    /**\n     * <code>optional .aapt.pb.Reference ref = 1;</code>\n     */\n    private void setRef(\n        com.android.aapt.Resources.Reference.Builder builderForValue) {\n      ref_ = builderForValue.build();\n      bitField0_ |= 0x00000001;\n    }\n    /**\n     * <code>optional .aapt.pb.Reference ref = 1;</code>\n     */\n    private void mergeRef(com.android.aapt.Resources.Reference value) {\n      if (ref_ != null &&\n          ref_ != com.android.aapt.Resources.Reference.getDefaultInstance()) {\n        ref_ =\n          com.android.aapt.Resources.Reference.newBuilder(ref_).mergeFrom(value).buildPartial();\n      } else {\n        ref_ = value;\n      }\n      bitField0_ |= 0x00000001;\n    }\n    /**\n     * <code>optional .aapt.pb.Reference ref = 1;</code>\n     */\n    private void clearRef() {  ref_ = null;\n      bitField0_ = (bitField0_ & ~0x00000001);\n    }\n\n    public static final int STR_FIELD_NUMBER = 2;\n    private com.android.aapt.Resources.String str_;\n    /**\n     * <code>optional .aapt.pb.String str = 2;</code>\n     */\n    public boolean hasStr() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <code>optional .aapt.pb.String str = 2;</code>\n     */\n    public com.android.aapt.Resources.String getStr() {\n      return str_ == null ? com.android.aapt.Resources.String.getDefaultInstance() : str_;\n    }\n    /**\n     * <code>optional .aapt.pb.String str = 2;</code>\n     */\n    private void setStr(com.android.aapt.Resources.String value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      str_ = value;\n      bitField0_ |= 0x00000002;\n      }\n    /**\n     * <code>optional .aapt.pb.String str = 2;</code>\n     */\n    private void setStr(\n        com.android.aapt.Resources.String.Builder builderForValue) {\n      str_ = builderForValue.build();\n      bitField0_ |= 0x00000002;\n    }\n    /**\n     * <code>optional .aapt.pb.String str = 2;</code>\n     */\n    private void mergeStr(com.android.aapt.Resources.String value) {\n      if (str_ != null &&\n          str_ != com.android.aapt.Resources.String.getDefaultInstance()) {\n        str_ =\n          com.android.aapt.Resources.String.newBuilder(str_).mergeFrom(value).buildPartial();\n      } else {\n        str_ = value;\n      }\n      bitField0_ |= 0x00000002;\n    }\n    /**\n     * <code>optional .aapt.pb.String str = 2;</code>\n     */\n    private void clearStr() {  str_ = null;\n      bitField0_ = (bitField0_ & ~0x00000002);\n    }\n\n    public static final int RAW_STR_FIELD_NUMBER = 3;\n    private com.android.aapt.Resources.RawString rawStr_;\n    /**\n     * <code>optional .aapt.pb.RawString raw_str = 3;</code>\n     */\n    public boolean hasRawStr() {\n      return ((bitField0_ & 0x00000004) == 0x00000004);\n    }\n    /**\n     * <code>optional .aapt.pb.RawString raw_str = 3;</code>\n     */\n    public com.android.aapt.Resources.RawString getRawStr() {\n      return rawStr_ == null ? com.android.aapt.Resources.RawString.getDefaultInstance() : rawStr_;\n    }\n    /**\n     * <code>optional .aapt.pb.RawString raw_str = 3;</code>\n     */\n    private void setRawStr(com.android.aapt.Resources.RawString value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      rawStr_ = value;\n      bitField0_ |= 0x00000004;\n      }\n    /**\n     * <code>optional .aapt.pb.RawString raw_str = 3;</code>\n     */\n    private void setRawStr(\n        com.android.aapt.Resources.RawString.Builder builderForValue) {\n      rawStr_ = builderForValue.build();\n      bitField0_ |= 0x00000004;\n    }\n    /**\n     * <code>optional .aapt.pb.RawString raw_str = 3;</code>\n     */\n    private void mergeRawStr(com.android.aapt.Resources.RawString value) {\n      if (rawStr_ != null &&\n          rawStr_ != com.android.aapt.Resources.RawString.getDefaultInstance()) {\n        rawStr_ =\n          com.android.aapt.Resources.RawString.newBuilder(rawStr_).mergeFrom(value).buildPartial();\n      } else {\n        rawStr_ = value;\n      }\n      bitField0_ |= 0x00000004;\n    }\n    /**\n     * <code>optional .aapt.pb.RawString raw_str = 3;</code>\n     */\n    private void clearRawStr() {  rawStr_ = null;\n      bitField0_ = (bitField0_ & ~0x00000004);\n    }\n\n    public static final int STYLED_STR_FIELD_NUMBER = 4;\n    private com.android.aapt.Resources.StyledString styledStr_;\n    /**\n     * <code>optional .aapt.pb.StyledString styled_str = 4;</code>\n     */\n    public boolean hasStyledStr() {\n      return ((bitField0_ & 0x00000008) == 0x00000008);\n    }\n    /**\n     * <code>optional .aapt.pb.StyledString styled_str = 4;</code>\n     */\n    public com.android.aapt.Resources.StyledString getStyledStr() {\n      return styledStr_ == null ? com.android.aapt.Resources.StyledString.getDefaultInstance() : styledStr_;\n    }\n    /**\n     * <code>optional .aapt.pb.StyledString styled_str = 4;</code>\n     */\n    private void setStyledStr(com.android.aapt.Resources.StyledString value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      styledStr_ = value;\n      bitField0_ |= 0x00000008;\n      }\n    /**\n     * <code>optional .aapt.pb.StyledString styled_str = 4;</code>\n     */\n    private void setStyledStr(\n        com.android.aapt.Resources.StyledString.Builder builderForValue) {\n      styledStr_ = builderForValue.build();\n      bitField0_ |= 0x00000008;\n    }\n    /**\n     * <code>optional .aapt.pb.StyledString styled_str = 4;</code>\n     */\n    private void mergeStyledStr(com.android.aapt.Resources.StyledString value) {\n      if (styledStr_ != null &&\n          styledStr_ != com.android.aapt.Resources.StyledString.getDefaultInstance()) {\n        styledStr_ =\n          com.android.aapt.Resources.StyledString.newBuilder(styledStr_).mergeFrom(value).buildPartial();\n      } else {\n        styledStr_ = value;\n      }\n      bitField0_ |= 0x00000008;\n    }\n    /**\n     * <code>optional .aapt.pb.StyledString styled_str = 4;</code>\n     */\n    private void clearStyledStr() {  styledStr_ = null;\n      bitField0_ = (bitField0_ & ~0x00000008);\n    }\n\n    public static final int FILE_FIELD_NUMBER = 5;\n    private com.android.aapt.Resources.FileReference file_;\n    /**\n     * <code>optional .aapt.pb.FileReference file = 5;</code>\n     */\n    public boolean hasFile() {\n      return ((bitField0_ & 0x00000010) == 0x00000010);\n    }\n    /**\n     * <code>optional .aapt.pb.FileReference file = 5;</code>\n     */\n    public com.android.aapt.Resources.FileReference getFile() {\n      return file_ == null ? com.android.aapt.Resources.FileReference.getDefaultInstance() : file_;\n    }\n    /**\n     * <code>optional .aapt.pb.FileReference file = 5;</code>\n     */\n    private void setFile(com.android.aapt.Resources.FileReference value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      file_ = value;\n      bitField0_ |= 0x00000010;\n      }\n    /**\n     * <code>optional .aapt.pb.FileReference file = 5;</code>\n     */\n    private void setFile(\n        com.android.aapt.Resources.FileReference.Builder builderForValue) {\n      file_ = builderForValue.build();\n      bitField0_ |= 0x00000010;\n    }\n    /**\n     * <code>optional .aapt.pb.FileReference file = 5;</code>\n     */\n    private void mergeFile(com.android.aapt.Resources.FileReference value) {\n      if (file_ != null &&\n          file_ != com.android.aapt.Resources.FileReference.getDefaultInstance()) {\n        file_ =\n          com.android.aapt.Resources.FileReference.newBuilder(file_).mergeFrom(value).buildPartial();\n      } else {\n        file_ = value;\n      }\n      bitField0_ |= 0x00000010;\n    }\n    /**\n     * <code>optional .aapt.pb.FileReference file = 5;</code>\n     */\n    private void clearFile() {  file_ = null;\n      bitField0_ = (bitField0_ & ~0x00000010);\n    }\n\n    public static final int ID_FIELD_NUMBER = 6;\n    private com.android.aapt.Resources.Id id_;\n    /**\n     * <code>optional .aapt.pb.Id id = 6;</code>\n     */\n    public boolean hasId() {\n      return ((bitField0_ & 0x00000020) == 0x00000020);\n    }\n    /**\n     * <code>optional .aapt.pb.Id id = 6;</code>\n     */\n    public com.android.aapt.Resources.Id getId() {\n      return id_ == null ? com.android.aapt.Resources.Id.getDefaultInstance() : id_;\n    }\n    /**\n     * <code>optional .aapt.pb.Id id = 6;</code>\n     */\n    private void setId(com.android.aapt.Resources.Id value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      id_ = value;\n      bitField0_ |= 0x00000020;\n      }\n    /**\n     * <code>optional .aapt.pb.Id id = 6;</code>\n     */\n    private void setId(\n        com.android.aapt.Resources.Id.Builder builderForValue) {\n      id_ = builderForValue.build();\n      bitField0_ |= 0x00000020;\n    }\n    /**\n     * <code>optional .aapt.pb.Id id = 6;</code>\n     */\n    private void mergeId(com.android.aapt.Resources.Id value) {\n      if (id_ != null &&\n          id_ != com.android.aapt.Resources.Id.getDefaultInstance()) {\n        id_ =\n          com.android.aapt.Resources.Id.newBuilder(id_).mergeFrom(value).buildPartial();\n      } else {\n        id_ = value;\n      }\n      bitField0_ |= 0x00000020;\n    }\n    /**\n     * <code>optional .aapt.pb.Id id = 6;</code>\n     */\n    private void clearId() {  id_ = null;\n      bitField0_ = (bitField0_ & ~0x00000020);\n    }\n\n    public static final int PRIM_FIELD_NUMBER = 7;\n    private com.android.aapt.Resources.Primitive prim_;\n    /**\n     * <code>optional .aapt.pb.Primitive prim = 7;</code>\n     */\n    public boolean hasPrim() {\n      return ((bitField0_ & 0x00000040) == 0x00000040);\n    }\n    /**\n     * <code>optional .aapt.pb.Primitive prim = 7;</code>\n     */\n    public com.android.aapt.Resources.Primitive getPrim() {\n      return prim_ == null ? com.android.aapt.Resources.Primitive.getDefaultInstance() : prim_;\n    }\n    /**\n     * <code>optional .aapt.pb.Primitive prim = 7;</code>\n     */\n    private void setPrim(com.android.aapt.Resources.Primitive value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      prim_ = value;\n      bitField0_ |= 0x00000040;\n      }\n    /**\n     * <code>optional .aapt.pb.Primitive prim = 7;</code>\n     */\n    private void setPrim(\n        com.android.aapt.Resources.Primitive.Builder builderForValue) {\n      prim_ = builderForValue.build();\n      bitField0_ |= 0x00000040;\n    }\n    /**\n     * <code>optional .aapt.pb.Primitive prim = 7;</code>\n     */\n    private void mergePrim(com.android.aapt.Resources.Primitive value) {\n      if (prim_ != null &&\n          prim_ != com.android.aapt.Resources.Primitive.getDefaultInstance()) {\n        prim_ =\n          com.android.aapt.Resources.Primitive.newBuilder(prim_).mergeFrom(value).buildPartial();\n      } else {\n        prim_ = value;\n      }\n      bitField0_ |= 0x00000040;\n    }\n    /**\n     * <code>optional .aapt.pb.Primitive prim = 7;</code>\n     */\n    private void clearPrim() {  prim_ = null;\n      bitField0_ = (bitField0_ & ~0x00000040);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeMessage(1, getRef());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeMessage(2, getStr());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        output.writeMessage(3, getRawStr());\n      }\n      if (((bitField0_ & 0x00000008) == 0x00000008)) {\n        output.writeMessage(4, getStyledStr());\n      }\n      if (((bitField0_ & 0x00000010) == 0x00000010)) {\n        output.writeMessage(5, getFile());\n      }\n      if (((bitField0_ & 0x00000020) == 0x00000020)) {\n        output.writeMessage(6, getId());\n      }\n      if (((bitField0_ & 0x00000040) == 0x00000040)) {\n        output.writeMessage(7, getPrim());\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(1, getRef());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(2, getStr());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(3, getRawStr());\n      }\n      if (((bitField0_ & 0x00000008) == 0x00000008)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(4, getStyledStr());\n      }\n      if (((bitField0_ & 0x00000010) == 0x00000010)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(5, getFile());\n      }\n      if (((bitField0_ & 0x00000020) == 0x00000020)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(6, getId());\n      }\n      if (((bitField0_ & 0x00000040) == 0x00000040)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(7, getPrim());\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.Item parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Item parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Item parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Item parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Item parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Item parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Item parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Item parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Item parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Item parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.Item prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * An Item is an abstract type. It represents a value that can appear inline in many places, such\n     * as XML attribute values or on the right hand side of style attribute definitions. The concrete\n     * type is one of the types below. Only one can be set.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Item}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.Item, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.Item)\n        com.android.aapt.Resources.ItemOrBuilder {\n      // Construct using com.android.aapt.Resources.Item.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <code>optional .aapt.pb.Reference ref = 1;</code>\n       */\n      public boolean hasRef() {\n        return instance.hasRef();\n      }\n      /**\n       * <code>optional .aapt.pb.Reference ref = 1;</code>\n       */\n      public com.android.aapt.Resources.Reference getRef() {\n        return instance.getRef();\n      }\n      /**\n       * <code>optional .aapt.pb.Reference ref = 1;</code>\n       */\n      public Builder setRef(com.android.aapt.Resources.Reference value) {\n        copyOnWrite();\n        instance.setRef(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.Reference ref = 1;</code>\n       */\n      public Builder setRef(\n          com.android.aapt.Resources.Reference.Builder builderForValue) {\n        copyOnWrite();\n        instance.setRef(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Reference ref = 1;</code>\n       */\n      public Builder mergeRef(com.android.aapt.Resources.Reference value) {\n        copyOnWrite();\n        instance.mergeRef(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Reference ref = 1;</code>\n       */\n      public Builder clearRef() {  copyOnWrite();\n        instance.clearRef();\n        return this;\n      }\n\n      /**\n       * <code>optional .aapt.pb.String str = 2;</code>\n       */\n      public boolean hasStr() {\n        return instance.hasStr();\n      }\n      /**\n       * <code>optional .aapt.pb.String str = 2;</code>\n       */\n      public com.android.aapt.Resources.String getStr() {\n        return instance.getStr();\n      }\n      /**\n       * <code>optional .aapt.pb.String str = 2;</code>\n       */\n      public Builder setStr(com.android.aapt.Resources.String value) {\n        copyOnWrite();\n        instance.setStr(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.String str = 2;</code>\n       */\n      public Builder setStr(\n          com.android.aapt.Resources.String.Builder builderForValue) {\n        copyOnWrite();\n        instance.setStr(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.String str = 2;</code>\n       */\n      public Builder mergeStr(com.android.aapt.Resources.String value) {\n        copyOnWrite();\n        instance.mergeStr(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.String str = 2;</code>\n       */\n      public Builder clearStr() {  copyOnWrite();\n        instance.clearStr();\n        return this;\n      }\n\n      /**\n       * <code>optional .aapt.pb.RawString raw_str = 3;</code>\n       */\n      public boolean hasRawStr() {\n        return instance.hasRawStr();\n      }\n      /**\n       * <code>optional .aapt.pb.RawString raw_str = 3;</code>\n       */\n      public com.android.aapt.Resources.RawString getRawStr() {\n        return instance.getRawStr();\n      }\n      /**\n       * <code>optional .aapt.pb.RawString raw_str = 3;</code>\n       */\n      public Builder setRawStr(com.android.aapt.Resources.RawString value) {\n        copyOnWrite();\n        instance.setRawStr(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.RawString raw_str = 3;</code>\n       */\n      public Builder setRawStr(\n          com.android.aapt.Resources.RawString.Builder builderForValue) {\n        copyOnWrite();\n        instance.setRawStr(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.RawString raw_str = 3;</code>\n       */\n      public Builder mergeRawStr(com.android.aapt.Resources.RawString value) {\n        copyOnWrite();\n        instance.mergeRawStr(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.RawString raw_str = 3;</code>\n       */\n      public Builder clearRawStr() {  copyOnWrite();\n        instance.clearRawStr();\n        return this;\n      }\n\n      /**\n       * <code>optional .aapt.pb.StyledString styled_str = 4;</code>\n       */\n      public boolean hasStyledStr() {\n        return instance.hasStyledStr();\n      }\n      /**\n       * <code>optional .aapt.pb.StyledString styled_str = 4;</code>\n       */\n      public com.android.aapt.Resources.StyledString getStyledStr() {\n        return instance.getStyledStr();\n      }\n      /**\n       * <code>optional .aapt.pb.StyledString styled_str = 4;</code>\n       */\n      public Builder setStyledStr(com.android.aapt.Resources.StyledString value) {\n        copyOnWrite();\n        instance.setStyledStr(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.StyledString styled_str = 4;</code>\n       */\n      public Builder setStyledStr(\n          com.android.aapt.Resources.StyledString.Builder builderForValue) {\n        copyOnWrite();\n        instance.setStyledStr(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.StyledString styled_str = 4;</code>\n       */\n      public Builder mergeStyledStr(com.android.aapt.Resources.StyledString value) {\n        copyOnWrite();\n        instance.mergeStyledStr(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.StyledString styled_str = 4;</code>\n       */\n      public Builder clearStyledStr() {  copyOnWrite();\n        instance.clearStyledStr();\n        return this;\n      }\n\n      /**\n       * <code>optional .aapt.pb.FileReference file = 5;</code>\n       */\n      public boolean hasFile() {\n        return instance.hasFile();\n      }\n      /**\n       * <code>optional .aapt.pb.FileReference file = 5;</code>\n       */\n      public com.android.aapt.Resources.FileReference getFile() {\n        return instance.getFile();\n      }\n      /**\n       * <code>optional .aapt.pb.FileReference file = 5;</code>\n       */\n      public Builder setFile(com.android.aapt.Resources.FileReference value) {\n        copyOnWrite();\n        instance.setFile(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.FileReference file = 5;</code>\n       */\n      public Builder setFile(\n          com.android.aapt.Resources.FileReference.Builder builderForValue) {\n        copyOnWrite();\n        instance.setFile(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.FileReference file = 5;</code>\n       */\n      public Builder mergeFile(com.android.aapt.Resources.FileReference value) {\n        copyOnWrite();\n        instance.mergeFile(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.FileReference file = 5;</code>\n       */\n      public Builder clearFile() {  copyOnWrite();\n        instance.clearFile();\n        return this;\n      }\n\n      /**\n       * <code>optional .aapt.pb.Id id = 6;</code>\n       */\n      public boolean hasId() {\n        return instance.hasId();\n      }\n      /**\n       * <code>optional .aapt.pb.Id id = 6;</code>\n       */\n      public com.android.aapt.Resources.Id getId() {\n        return instance.getId();\n      }\n      /**\n       * <code>optional .aapt.pb.Id id = 6;</code>\n       */\n      public Builder setId(com.android.aapt.Resources.Id value) {\n        copyOnWrite();\n        instance.setId(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.Id id = 6;</code>\n       */\n      public Builder setId(\n          com.android.aapt.Resources.Id.Builder builderForValue) {\n        copyOnWrite();\n        instance.setId(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Id id = 6;</code>\n       */\n      public Builder mergeId(com.android.aapt.Resources.Id value) {\n        copyOnWrite();\n        instance.mergeId(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Id id = 6;</code>\n       */\n      public Builder clearId() {  copyOnWrite();\n        instance.clearId();\n        return this;\n      }\n\n      /**\n       * <code>optional .aapt.pb.Primitive prim = 7;</code>\n       */\n      public boolean hasPrim() {\n        return instance.hasPrim();\n      }\n      /**\n       * <code>optional .aapt.pb.Primitive prim = 7;</code>\n       */\n      public com.android.aapt.Resources.Primitive getPrim() {\n        return instance.getPrim();\n      }\n      /**\n       * <code>optional .aapt.pb.Primitive prim = 7;</code>\n       */\n      public Builder setPrim(com.android.aapt.Resources.Primitive value) {\n        copyOnWrite();\n        instance.setPrim(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.Primitive prim = 7;</code>\n       */\n      public Builder setPrim(\n          com.android.aapt.Resources.Primitive.Builder builderForValue) {\n        copyOnWrite();\n        instance.setPrim(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Primitive prim = 7;</code>\n       */\n      public Builder mergePrim(com.android.aapt.Resources.Primitive value) {\n        copyOnWrite();\n        instance.mergePrim(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Primitive prim = 7;</code>\n       */\n      public Builder clearPrim() {  copyOnWrite();\n        instance.clearPrim();\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.Item)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.Item();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.Item other = (com.android.aapt.Resources.Item) arg1;\n          ref_ = visitor.visitMessage(ref_, other.ref_);\n          str_ = visitor.visitMessage(str_, other.str_);\n          rawStr_ = visitor.visitMessage(rawStr_, other.rawStr_);\n          styledStr_ = visitor.visitMessage(styledStr_, other.styledStr_);\n          file_ = visitor.visitMessage(file_, other.file_);\n          id_ = visitor.visitMessage(id_, other.id_);\n          prim_ = visitor.visitMessage(prim_, other.prim_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  com.android.aapt.Resources.Reference.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                    subBuilder = ref_.toBuilder();\n                  }\n                  ref_ = input.readMessage(com.android.aapt.Resources.Reference.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(ref_);\n                    ref_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000001;\n                  break;\n                }\n                case 18: {\n                  com.android.aapt.Resources.String.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000002) == 0x00000002)) {\n                    subBuilder = str_.toBuilder();\n                  }\n                  str_ = input.readMessage(com.android.aapt.Resources.String.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(str_);\n                    str_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000002;\n                  break;\n                }\n                case 26: {\n                  com.android.aapt.Resources.RawString.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000004) == 0x00000004)) {\n                    subBuilder = rawStr_.toBuilder();\n                  }\n                  rawStr_ = input.readMessage(com.android.aapt.Resources.RawString.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(rawStr_);\n                    rawStr_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000004;\n                  break;\n                }\n                case 34: {\n                  com.android.aapt.Resources.StyledString.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000008) == 0x00000008)) {\n                    subBuilder = styledStr_.toBuilder();\n                  }\n                  styledStr_ = input.readMessage(com.android.aapt.Resources.StyledString.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(styledStr_);\n                    styledStr_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000008;\n                  break;\n                }\n                case 42: {\n                  com.android.aapt.Resources.FileReference.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000010) == 0x00000010)) {\n                    subBuilder = file_.toBuilder();\n                  }\n                  file_ = input.readMessage(com.android.aapt.Resources.FileReference.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(file_);\n                    file_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000010;\n                  break;\n                }\n                case 50: {\n                  com.android.aapt.Resources.Id.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000020) == 0x00000020)) {\n                    subBuilder = id_.toBuilder();\n                  }\n                  id_ = input.readMessage(com.android.aapt.Resources.Id.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(id_);\n                    id_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000020;\n                  break;\n                }\n                case 58: {\n                  com.android.aapt.Resources.Primitive.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000040) == 0x00000040)) {\n                    subBuilder = prim_.toBuilder();\n                  }\n                  prim_ = input.readMessage(com.android.aapt.Resources.Primitive.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(prim_);\n                    prim_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000040;\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.Item.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.Item)\n    private static final com.android.aapt.Resources.Item DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new Item();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.Item getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<Item> PARSER;\n\n    public static com.google.protobuf.Parser<Item> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface CompoundValueOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.CompoundValue)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <code>optional .aapt.pb.Attribute attr = 1;</code>\n     */\n    boolean hasAttr();\n    /**\n     * <code>optional .aapt.pb.Attribute attr = 1;</code>\n     */\n    com.android.aapt.Resources.Attribute getAttr();\n\n    /**\n     * <code>optional .aapt.pb.Style style = 2;</code>\n     */\n    boolean hasStyle();\n    /**\n     * <code>optional .aapt.pb.Style style = 2;</code>\n     */\n    com.android.aapt.Resources.Style getStyle();\n\n    /**\n     * <code>optional .aapt.pb.Styleable styleable = 3;</code>\n     */\n    boolean hasStyleable();\n    /**\n     * <code>optional .aapt.pb.Styleable styleable = 3;</code>\n     */\n    com.android.aapt.Resources.Styleable getStyleable();\n\n    /**\n     * <code>optional .aapt.pb.Array array = 4;</code>\n     */\n    boolean hasArray();\n    /**\n     * <code>optional .aapt.pb.Array array = 4;</code>\n     */\n    com.android.aapt.Resources.Array getArray();\n\n    /**\n     * <code>optional .aapt.pb.Plural plural = 5;</code>\n     */\n    boolean hasPlural();\n    /**\n     * <code>optional .aapt.pb.Plural plural = 5;</code>\n     */\n    com.android.aapt.Resources.Plural getPlural();\n  }\n  /**\n   * <pre>\n   * A CompoundValue is an abstract type. It represents a value that is a made of other values.\n   * These can only usually appear as top-level resources. The concrete type is one of the types\n   * below. Only one can be set.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.CompoundValue}\n   */\n  public  static final class CompoundValue extends\n      com.google.protobuf.GeneratedMessageLite<\n          CompoundValue, CompoundValue.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.CompoundValue)\n      CompoundValueOrBuilder {\n    private CompoundValue() {\n    }\n    private int bitField0_;\n    public static final int ATTR_FIELD_NUMBER = 1;\n    private com.android.aapt.Resources.Attribute attr_;\n    /**\n     * <code>optional .aapt.pb.Attribute attr = 1;</code>\n     */\n    public boolean hasAttr() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <code>optional .aapt.pb.Attribute attr = 1;</code>\n     */\n    public com.android.aapt.Resources.Attribute getAttr() {\n      return attr_ == null ? com.android.aapt.Resources.Attribute.getDefaultInstance() : attr_;\n    }\n    /**\n     * <code>optional .aapt.pb.Attribute attr = 1;</code>\n     */\n    private void setAttr(com.android.aapt.Resources.Attribute value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      attr_ = value;\n      bitField0_ |= 0x00000001;\n      }\n    /**\n     * <code>optional .aapt.pb.Attribute attr = 1;</code>\n     */\n    private void setAttr(\n        com.android.aapt.Resources.Attribute.Builder builderForValue) {\n      attr_ = builderForValue.build();\n      bitField0_ |= 0x00000001;\n    }\n    /**\n     * <code>optional .aapt.pb.Attribute attr = 1;</code>\n     */\n    private void mergeAttr(com.android.aapt.Resources.Attribute value) {\n      if (attr_ != null &&\n          attr_ != com.android.aapt.Resources.Attribute.getDefaultInstance()) {\n        attr_ =\n          com.android.aapt.Resources.Attribute.newBuilder(attr_).mergeFrom(value).buildPartial();\n      } else {\n        attr_ = value;\n      }\n      bitField0_ |= 0x00000001;\n    }\n    /**\n     * <code>optional .aapt.pb.Attribute attr = 1;</code>\n     */\n    private void clearAttr() {  attr_ = null;\n      bitField0_ = (bitField0_ & ~0x00000001);\n    }\n\n    public static final int STYLE_FIELD_NUMBER = 2;\n    private com.android.aapt.Resources.Style style_;\n    /**\n     * <code>optional .aapt.pb.Style style = 2;</code>\n     */\n    public boolean hasStyle() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <code>optional .aapt.pb.Style style = 2;</code>\n     */\n    public com.android.aapt.Resources.Style getStyle() {\n      return style_ == null ? com.android.aapt.Resources.Style.getDefaultInstance() : style_;\n    }\n    /**\n     * <code>optional .aapt.pb.Style style = 2;</code>\n     */\n    private void setStyle(com.android.aapt.Resources.Style value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      style_ = value;\n      bitField0_ |= 0x00000002;\n      }\n    /**\n     * <code>optional .aapt.pb.Style style = 2;</code>\n     */\n    private void setStyle(\n        com.android.aapt.Resources.Style.Builder builderForValue) {\n      style_ = builderForValue.build();\n      bitField0_ |= 0x00000002;\n    }\n    /**\n     * <code>optional .aapt.pb.Style style = 2;</code>\n     */\n    private void mergeStyle(com.android.aapt.Resources.Style value) {\n      if (style_ != null &&\n          style_ != com.android.aapt.Resources.Style.getDefaultInstance()) {\n        style_ =\n          com.android.aapt.Resources.Style.newBuilder(style_).mergeFrom(value).buildPartial();\n      } else {\n        style_ = value;\n      }\n      bitField0_ |= 0x00000002;\n    }\n    /**\n     * <code>optional .aapt.pb.Style style = 2;</code>\n     */\n    private void clearStyle() {  style_ = null;\n      bitField0_ = (bitField0_ & ~0x00000002);\n    }\n\n    public static final int STYLEABLE_FIELD_NUMBER = 3;\n    private com.android.aapt.Resources.Styleable styleable_;\n    /**\n     * <code>optional .aapt.pb.Styleable styleable = 3;</code>\n     */\n    public boolean hasStyleable() {\n      return ((bitField0_ & 0x00000004) == 0x00000004);\n    }\n    /**\n     * <code>optional .aapt.pb.Styleable styleable = 3;</code>\n     */\n    public com.android.aapt.Resources.Styleable getStyleable() {\n      return styleable_ == null ? com.android.aapt.Resources.Styleable.getDefaultInstance() : styleable_;\n    }\n    /**\n     * <code>optional .aapt.pb.Styleable styleable = 3;</code>\n     */\n    private void setStyleable(com.android.aapt.Resources.Styleable value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      styleable_ = value;\n      bitField0_ |= 0x00000004;\n      }\n    /**\n     * <code>optional .aapt.pb.Styleable styleable = 3;</code>\n     */\n    private void setStyleable(\n        com.android.aapt.Resources.Styleable.Builder builderForValue) {\n      styleable_ = builderForValue.build();\n      bitField0_ |= 0x00000004;\n    }\n    /**\n     * <code>optional .aapt.pb.Styleable styleable = 3;</code>\n     */\n    private void mergeStyleable(com.android.aapt.Resources.Styleable value) {\n      if (styleable_ != null &&\n          styleable_ != com.android.aapt.Resources.Styleable.getDefaultInstance()) {\n        styleable_ =\n          com.android.aapt.Resources.Styleable.newBuilder(styleable_).mergeFrom(value).buildPartial();\n      } else {\n        styleable_ = value;\n      }\n      bitField0_ |= 0x00000004;\n    }\n    /**\n     * <code>optional .aapt.pb.Styleable styleable = 3;</code>\n     */\n    private void clearStyleable() {  styleable_ = null;\n      bitField0_ = (bitField0_ & ~0x00000004);\n    }\n\n    public static final int ARRAY_FIELD_NUMBER = 4;\n    private com.android.aapt.Resources.Array array_;\n    /**\n     * <code>optional .aapt.pb.Array array = 4;</code>\n     */\n    public boolean hasArray() {\n      return ((bitField0_ & 0x00000008) == 0x00000008);\n    }\n    /**\n     * <code>optional .aapt.pb.Array array = 4;</code>\n     */\n    public com.android.aapt.Resources.Array getArray() {\n      return array_ == null ? com.android.aapt.Resources.Array.getDefaultInstance() : array_;\n    }\n    /**\n     * <code>optional .aapt.pb.Array array = 4;</code>\n     */\n    private void setArray(com.android.aapt.Resources.Array value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      array_ = value;\n      bitField0_ |= 0x00000008;\n      }\n    /**\n     * <code>optional .aapt.pb.Array array = 4;</code>\n     */\n    private void setArray(\n        com.android.aapt.Resources.Array.Builder builderForValue) {\n      array_ = builderForValue.build();\n      bitField0_ |= 0x00000008;\n    }\n    /**\n     * <code>optional .aapt.pb.Array array = 4;</code>\n     */\n    private void mergeArray(com.android.aapt.Resources.Array value) {\n      if (array_ != null &&\n          array_ != com.android.aapt.Resources.Array.getDefaultInstance()) {\n        array_ =\n          com.android.aapt.Resources.Array.newBuilder(array_).mergeFrom(value).buildPartial();\n      } else {\n        array_ = value;\n      }\n      bitField0_ |= 0x00000008;\n    }\n    /**\n     * <code>optional .aapt.pb.Array array = 4;</code>\n     */\n    private void clearArray() {  array_ = null;\n      bitField0_ = (bitField0_ & ~0x00000008);\n    }\n\n    public static final int PLURAL_FIELD_NUMBER = 5;\n    private com.android.aapt.Resources.Plural plural_;\n    /**\n     * <code>optional .aapt.pb.Plural plural = 5;</code>\n     */\n    public boolean hasPlural() {\n      return ((bitField0_ & 0x00000010) == 0x00000010);\n    }\n    /**\n     * <code>optional .aapt.pb.Plural plural = 5;</code>\n     */\n    public com.android.aapt.Resources.Plural getPlural() {\n      return plural_ == null ? com.android.aapt.Resources.Plural.getDefaultInstance() : plural_;\n    }\n    /**\n     * <code>optional .aapt.pb.Plural plural = 5;</code>\n     */\n    private void setPlural(com.android.aapt.Resources.Plural value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      plural_ = value;\n      bitField0_ |= 0x00000010;\n      }\n    /**\n     * <code>optional .aapt.pb.Plural plural = 5;</code>\n     */\n    private void setPlural(\n        com.android.aapt.Resources.Plural.Builder builderForValue) {\n      plural_ = builderForValue.build();\n      bitField0_ |= 0x00000010;\n    }\n    /**\n     * <code>optional .aapt.pb.Plural plural = 5;</code>\n     */\n    private void mergePlural(com.android.aapt.Resources.Plural value) {\n      if (plural_ != null &&\n          plural_ != com.android.aapt.Resources.Plural.getDefaultInstance()) {\n        plural_ =\n          com.android.aapt.Resources.Plural.newBuilder(plural_).mergeFrom(value).buildPartial();\n      } else {\n        plural_ = value;\n      }\n      bitField0_ |= 0x00000010;\n    }\n    /**\n     * <code>optional .aapt.pb.Plural plural = 5;</code>\n     */\n    private void clearPlural() {  plural_ = null;\n      bitField0_ = (bitField0_ & ~0x00000010);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeMessage(1, getAttr());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeMessage(2, getStyle());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        output.writeMessage(3, getStyleable());\n      }\n      if (((bitField0_ & 0x00000008) == 0x00000008)) {\n        output.writeMessage(4, getArray());\n      }\n      if (((bitField0_ & 0x00000010) == 0x00000010)) {\n        output.writeMessage(5, getPlural());\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(1, getAttr());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(2, getStyle());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(3, getStyleable());\n      }\n      if (((bitField0_ & 0x00000008) == 0x00000008)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(4, getArray());\n      }\n      if (((bitField0_ & 0x00000010) == 0x00000010)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(5, getPlural());\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.CompoundValue parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.CompoundValue parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.CompoundValue parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.CompoundValue parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.CompoundValue parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.CompoundValue parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.CompoundValue parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.CompoundValue parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.CompoundValue parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.CompoundValue parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.CompoundValue prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A CompoundValue is an abstract type. It represents a value that is a made of other values.\n     * These can only usually appear as top-level resources. The concrete type is one of the types\n     * below. Only one can be set.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.CompoundValue}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.CompoundValue, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.CompoundValue)\n        com.android.aapt.Resources.CompoundValueOrBuilder {\n      // Construct using com.android.aapt.Resources.CompoundValue.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <code>optional .aapt.pb.Attribute attr = 1;</code>\n       */\n      public boolean hasAttr() {\n        return instance.hasAttr();\n      }\n      /**\n       * <code>optional .aapt.pb.Attribute attr = 1;</code>\n       */\n      public com.android.aapt.Resources.Attribute getAttr() {\n        return instance.getAttr();\n      }\n      /**\n       * <code>optional .aapt.pb.Attribute attr = 1;</code>\n       */\n      public Builder setAttr(com.android.aapt.Resources.Attribute value) {\n        copyOnWrite();\n        instance.setAttr(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.Attribute attr = 1;</code>\n       */\n      public Builder setAttr(\n          com.android.aapt.Resources.Attribute.Builder builderForValue) {\n        copyOnWrite();\n        instance.setAttr(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Attribute attr = 1;</code>\n       */\n      public Builder mergeAttr(com.android.aapt.Resources.Attribute value) {\n        copyOnWrite();\n        instance.mergeAttr(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Attribute attr = 1;</code>\n       */\n      public Builder clearAttr() {  copyOnWrite();\n        instance.clearAttr();\n        return this;\n      }\n\n      /**\n       * <code>optional .aapt.pb.Style style = 2;</code>\n       */\n      public boolean hasStyle() {\n        return instance.hasStyle();\n      }\n      /**\n       * <code>optional .aapt.pb.Style style = 2;</code>\n       */\n      public com.android.aapt.Resources.Style getStyle() {\n        return instance.getStyle();\n      }\n      /**\n       * <code>optional .aapt.pb.Style style = 2;</code>\n       */\n      public Builder setStyle(com.android.aapt.Resources.Style value) {\n        copyOnWrite();\n        instance.setStyle(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.Style style = 2;</code>\n       */\n      public Builder setStyle(\n          com.android.aapt.Resources.Style.Builder builderForValue) {\n        copyOnWrite();\n        instance.setStyle(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Style style = 2;</code>\n       */\n      public Builder mergeStyle(com.android.aapt.Resources.Style value) {\n        copyOnWrite();\n        instance.mergeStyle(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Style style = 2;</code>\n       */\n      public Builder clearStyle() {  copyOnWrite();\n        instance.clearStyle();\n        return this;\n      }\n\n      /**\n       * <code>optional .aapt.pb.Styleable styleable = 3;</code>\n       */\n      public boolean hasStyleable() {\n        return instance.hasStyleable();\n      }\n      /**\n       * <code>optional .aapt.pb.Styleable styleable = 3;</code>\n       */\n      public com.android.aapt.Resources.Styleable getStyleable() {\n        return instance.getStyleable();\n      }\n      /**\n       * <code>optional .aapt.pb.Styleable styleable = 3;</code>\n       */\n      public Builder setStyleable(com.android.aapt.Resources.Styleable value) {\n        copyOnWrite();\n        instance.setStyleable(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.Styleable styleable = 3;</code>\n       */\n      public Builder setStyleable(\n          com.android.aapt.Resources.Styleable.Builder builderForValue) {\n        copyOnWrite();\n        instance.setStyleable(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Styleable styleable = 3;</code>\n       */\n      public Builder mergeStyleable(com.android.aapt.Resources.Styleable value) {\n        copyOnWrite();\n        instance.mergeStyleable(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Styleable styleable = 3;</code>\n       */\n      public Builder clearStyleable() {  copyOnWrite();\n        instance.clearStyleable();\n        return this;\n      }\n\n      /**\n       * <code>optional .aapt.pb.Array array = 4;</code>\n       */\n      public boolean hasArray() {\n        return instance.hasArray();\n      }\n      /**\n       * <code>optional .aapt.pb.Array array = 4;</code>\n       */\n      public com.android.aapt.Resources.Array getArray() {\n        return instance.getArray();\n      }\n      /**\n       * <code>optional .aapt.pb.Array array = 4;</code>\n       */\n      public Builder setArray(com.android.aapt.Resources.Array value) {\n        copyOnWrite();\n        instance.setArray(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.Array array = 4;</code>\n       */\n      public Builder setArray(\n          com.android.aapt.Resources.Array.Builder builderForValue) {\n        copyOnWrite();\n        instance.setArray(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Array array = 4;</code>\n       */\n      public Builder mergeArray(com.android.aapt.Resources.Array value) {\n        copyOnWrite();\n        instance.mergeArray(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Array array = 4;</code>\n       */\n      public Builder clearArray() {  copyOnWrite();\n        instance.clearArray();\n        return this;\n      }\n\n      /**\n       * <code>optional .aapt.pb.Plural plural = 5;</code>\n       */\n      public boolean hasPlural() {\n        return instance.hasPlural();\n      }\n      /**\n       * <code>optional .aapt.pb.Plural plural = 5;</code>\n       */\n      public com.android.aapt.Resources.Plural getPlural() {\n        return instance.getPlural();\n      }\n      /**\n       * <code>optional .aapt.pb.Plural plural = 5;</code>\n       */\n      public Builder setPlural(com.android.aapt.Resources.Plural value) {\n        copyOnWrite();\n        instance.setPlural(value);\n        return this;\n        }\n      /**\n       * <code>optional .aapt.pb.Plural plural = 5;</code>\n       */\n      public Builder setPlural(\n          com.android.aapt.Resources.Plural.Builder builderForValue) {\n        copyOnWrite();\n        instance.setPlural(builderForValue);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Plural plural = 5;</code>\n       */\n      public Builder mergePlural(com.android.aapt.Resources.Plural value) {\n        copyOnWrite();\n        instance.mergePlural(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Plural plural = 5;</code>\n       */\n      public Builder clearPlural() {  copyOnWrite();\n        instance.clearPlural();\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.CompoundValue)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.CompoundValue();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.CompoundValue other = (com.android.aapt.Resources.CompoundValue) arg1;\n          attr_ = visitor.visitMessage(attr_, other.attr_);\n          style_ = visitor.visitMessage(style_, other.style_);\n          styleable_ = visitor.visitMessage(styleable_, other.styleable_);\n          array_ = visitor.visitMessage(array_, other.array_);\n          plural_ = visitor.visitMessage(plural_, other.plural_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  com.android.aapt.Resources.Attribute.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                    subBuilder = attr_.toBuilder();\n                  }\n                  attr_ = input.readMessage(com.android.aapt.Resources.Attribute.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(attr_);\n                    attr_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000001;\n                  break;\n                }\n                case 18: {\n                  com.android.aapt.Resources.Style.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000002) == 0x00000002)) {\n                    subBuilder = style_.toBuilder();\n                  }\n                  style_ = input.readMessage(com.android.aapt.Resources.Style.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(style_);\n                    style_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000002;\n                  break;\n                }\n                case 26: {\n                  com.android.aapt.Resources.Styleable.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000004) == 0x00000004)) {\n                    subBuilder = styleable_.toBuilder();\n                  }\n                  styleable_ = input.readMessage(com.android.aapt.Resources.Styleable.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(styleable_);\n                    styleable_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000004;\n                  break;\n                }\n                case 34: {\n                  com.android.aapt.Resources.Array.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000008) == 0x00000008)) {\n                    subBuilder = array_.toBuilder();\n                  }\n                  array_ = input.readMessage(com.android.aapt.Resources.Array.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(array_);\n                    array_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000008;\n                  break;\n                }\n                case 42: {\n                  com.android.aapt.Resources.Plural.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000010) == 0x00000010)) {\n                    subBuilder = plural_.toBuilder();\n                  }\n                  plural_ = input.readMessage(com.android.aapt.Resources.Plural.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(plural_);\n                    plural_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000010;\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.CompoundValue.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.CompoundValue)\n    private static final com.android.aapt.Resources.CompoundValue DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new CompoundValue();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.CompoundValue getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<CompoundValue> PARSER;\n\n    public static com.google.protobuf.Parser<CompoundValue> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface ReferenceOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.Reference)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <code>optional .aapt.pb.Reference.Type type = 1;</code>\n     */\n    boolean hasType();\n    /**\n     * <code>optional .aapt.pb.Reference.Type type = 1;</code>\n     */\n    com.android.aapt.Resources.Reference.Type getType();\n\n    /**\n     * <pre>\n     * The resource ID (0xPPTTEEEE) of the resource being referred.\n     * </pre>\n     *\n     * <code>optional uint32 id = 2;</code>\n     */\n    boolean hasId();\n    /**\n     * <pre>\n     * The resource ID (0xPPTTEEEE) of the resource being referred.\n     * </pre>\n     *\n     * <code>optional uint32 id = 2;</code>\n     */\n    int getId();\n\n    /**\n     * <pre>\n     * The optional resource name.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    boolean hasName();\n    /**\n     * <pre>\n     * The optional resource name.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    java.lang.String getName();\n    /**\n     * <pre>\n     * The optional resource name.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    com.google.protobuf.ByteString\n        getNameBytes();\n\n    /**\n     * <pre>\n     * Whether this reference is referencing a private resource (&#64;*package:type/entry).\n     * </pre>\n     *\n     * <code>optional bool private = 4;</code>\n     */\n    boolean hasPrivate();\n    /**\n     * <pre>\n     * Whether this reference is referencing a private resource (&#64;*package:type/entry).\n     * </pre>\n     *\n     * <code>optional bool private = 4;</code>\n     */\n    boolean getPrivate();\n  }\n  /**\n   * <pre>\n   * A value that is a reference to another resource. This reference can be by name or resource ID.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.Reference}\n   */\n  public  static final class Reference extends\n      com.google.protobuf.GeneratedMessageLite<\n          Reference, Reference.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.Reference)\n      ReferenceOrBuilder {\n    private Reference() {\n      name_ = \"\";\n    }\n    /**\n     * Protobuf enum {@code aapt.pb.Reference.Type}\n     */\n    public enum Type\n        implements com.google.protobuf.Internal.EnumLite {\n      /**\n       * <pre>\n       * A plain reference (&#64;package:type/entry).\n       * </pre>\n       *\n       * <code>REFERENCE = 0;</code>\n       */\n      REFERENCE(0),\n      /**\n       * <pre>\n       * A reference to a theme attribute (?package:type/entry).\n       * </pre>\n       *\n       * <code>ATTRIBUTE = 1;</code>\n       */\n      ATTRIBUTE(1),\n      ;\n\n      /**\n       * <pre>\n       * A plain reference (&#64;package:type/entry).\n       * </pre>\n       *\n       * <code>REFERENCE = 0;</code>\n       */\n      public static final int REFERENCE_VALUE = 0;\n      /**\n       * <pre>\n       * A reference to a theme attribute (?package:type/entry).\n       * </pre>\n       *\n       * <code>ATTRIBUTE = 1;</code>\n       */\n      public static final int ATTRIBUTE_VALUE = 1;\n\n\n      public final int getNumber() {\n        return value;\n      }\n\n      /**\n       * @deprecated Use {@link #forNumber(int)} instead.\n       */\n      @java.lang.Deprecated\n      public static Type valueOf(int value) {\n        return forNumber(value);\n      }\n\n      public static Type forNumber(int value) {\n        switch (value) {\n          case 0: return REFERENCE;\n          case 1: return ATTRIBUTE;\n          default: return null;\n        }\n      }\n\n      public static com.google.protobuf.Internal.EnumLiteMap<Type>\n          internalGetValueMap() {\n        return internalValueMap;\n      }\n      private static final com.google.protobuf.Internal.EnumLiteMap<\n          Type> internalValueMap =\n            new com.google.protobuf.Internal.EnumLiteMap<Type>() {\n              public Type findValueByNumber(int number) {\n                return Type.forNumber(number);\n              }\n            };\n\n      private final int value;\n\n      private Type(int value) {\n        this.value = value;\n      }\n\n      // @@protoc_insertion_point(enum_scope:aapt.pb.Reference.Type)\n    }\n\n    private int bitField0_;\n    public static final int TYPE_FIELD_NUMBER = 1;\n    private int type_;\n    /**\n     * <code>optional .aapt.pb.Reference.Type type = 1;</code>\n     */\n    public boolean hasType() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <code>optional .aapt.pb.Reference.Type type = 1;</code>\n     */\n    public com.android.aapt.Resources.Reference.Type getType() {\n      com.android.aapt.Resources.Reference.Type result = com.android.aapt.Resources.Reference.Type.forNumber(type_);\n      return result == null ? com.android.aapt.Resources.Reference.Type.REFERENCE : result;\n    }\n    /**\n     * <code>optional .aapt.pb.Reference.Type type = 1;</code>\n     */\n    private void setType(com.android.aapt.Resources.Reference.Type value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      bitField0_ |= 0x00000001;\n      type_ = value.getNumber();\n    }\n    /**\n     * <code>optional .aapt.pb.Reference.Type type = 1;</code>\n     */\n    private void clearType() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      type_ = 0;\n    }\n\n    public static final int ID_FIELD_NUMBER = 2;\n    private int id_;\n    /**\n     * <pre>\n     * The resource ID (0xPPTTEEEE) of the resource being referred.\n     * </pre>\n     *\n     * <code>optional uint32 id = 2;</code>\n     */\n    public boolean hasId() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <pre>\n     * The resource ID (0xPPTTEEEE) of the resource being referred.\n     * </pre>\n     *\n     * <code>optional uint32 id = 2;</code>\n     */\n    public int getId() {\n      return id_;\n    }\n    /**\n     * <pre>\n     * The resource ID (0xPPTTEEEE) of the resource being referred.\n     * </pre>\n     *\n     * <code>optional uint32 id = 2;</code>\n     */\n    private void setId(int value) {\n      bitField0_ |= 0x00000002;\n      id_ = value;\n    }\n    /**\n     * <pre>\n     * The resource ID (0xPPTTEEEE) of the resource being referred.\n     * </pre>\n     *\n     * <code>optional uint32 id = 2;</code>\n     */\n    private void clearId() {\n      bitField0_ = (bitField0_ & ~0x00000002);\n      id_ = 0;\n    }\n\n    public static final int NAME_FIELD_NUMBER = 3;\n    private java.lang.String name_;\n    /**\n     * <pre>\n     * The optional resource name.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    public boolean hasName() {\n      return ((bitField0_ & 0x00000004) == 0x00000004);\n    }\n    /**\n     * <pre>\n     * The optional resource name.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    public java.lang.String getName() {\n      return name_;\n    }\n    /**\n     * <pre>\n     * The optional resource name.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    public com.google.protobuf.ByteString\n        getNameBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(name_);\n    }\n    /**\n     * <pre>\n     * The optional resource name.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    private void setName(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000004;\n      name_ = value;\n    }\n    /**\n     * <pre>\n     * The optional resource name.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    private void clearName() {\n      bitField0_ = (bitField0_ & ~0x00000004);\n      name_ = getDefaultInstance().getName();\n    }\n    /**\n     * <pre>\n     * The optional resource name.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    private void setNameBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000004;\n      name_ = value.toStringUtf8();\n    }\n\n    public static final int PRIVATE_FIELD_NUMBER = 4;\n    private boolean private_;\n    /**\n     * <pre>\n     * Whether this reference is referencing a private resource (&#64;*package:type/entry).\n     * </pre>\n     *\n     * <code>optional bool private = 4;</code>\n     */\n    public boolean hasPrivate() {\n      return ((bitField0_ & 0x00000008) == 0x00000008);\n    }\n    /**\n     * <pre>\n     * Whether this reference is referencing a private resource (&#64;*package:type/entry).\n     * </pre>\n     *\n     * <code>optional bool private = 4;</code>\n     */\n    public boolean getPrivate() {\n      return private_;\n    }\n    /**\n     * <pre>\n     * Whether this reference is referencing a private resource (&#64;*package:type/entry).\n     * </pre>\n     *\n     * <code>optional bool private = 4;</code>\n     */\n    private void setPrivate(boolean value) {\n      bitField0_ |= 0x00000008;\n      private_ = value;\n    }\n    /**\n     * <pre>\n     * Whether this reference is referencing a private resource (&#64;*package:type/entry).\n     * </pre>\n     *\n     * <code>optional bool private = 4;</code>\n     */\n    private void clearPrivate() {\n      bitField0_ = (bitField0_ & ~0x00000008);\n      private_ = false;\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeEnum(1, type_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeUInt32(2, id_);\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        output.writeString(3, getName());\n      }\n      if (((bitField0_ & 0x00000008) == 0x00000008)) {\n        output.writeBool(4, private_);\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeEnumSize(1, type_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeUInt32Size(2, id_);\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(3, getName());\n      }\n      if (((bitField0_ & 0x00000008) == 0x00000008)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeBoolSize(4, private_);\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.Reference parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Reference parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Reference parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Reference parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Reference parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Reference parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Reference parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Reference parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Reference parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Reference parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.Reference prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A value that is a reference to another resource. This reference can be by name or resource ID.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Reference}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.Reference, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.Reference)\n        com.android.aapt.Resources.ReferenceOrBuilder {\n      // Construct using com.android.aapt.Resources.Reference.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <code>optional .aapt.pb.Reference.Type type = 1;</code>\n       */\n      public boolean hasType() {\n        return instance.hasType();\n      }\n      /**\n       * <code>optional .aapt.pb.Reference.Type type = 1;</code>\n       */\n      public com.android.aapt.Resources.Reference.Type getType() {\n        return instance.getType();\n      }\n      /**\n       * <code>optional .aapt.pb.Reference.Type type = 1;</code>\n       */\n      public Builder setType(com.android.aapt.Resources.Reference.Type value) {\n        copyOnWrite();\n        instance.setType(value);\n        return this;\n      }\n      /**\n       * <code>optional .aapt.pb.Reference.Type type = 1;</code>\n       */\n      public Builder clearType() {\n        copyOnWrite();\n        instance.clearType();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The resource ID (0xPPTTEEEE) of the resource being referred.\n       * </pre>\n       *\n       * <code>optional uint32 id = 2;</code>\n       */\n      public boolean hasId() {\n        return instance.hasId();\n      }\n      /**\n       * <pre>\n       * The resource ID (0xPPTTEEEE) of the resource being referred.\n       * </pre>\n       *\n       * <code>optional uint32 id = 2;</code>\n       */\n      public int getId() {\n        return instance.getId();\n      }\n      /**\n       * <pre>\n       * The resource ID (0xPPTTEEEE) of the resource being referred.\n       * </pre>\n       *\n       * <code>optional uint32 id = 2;</code>\n       */\n      public Builder setId(int value) {\n        copyOnWrite();\n        instance.setId(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The resource ID (0xPPTTEEEE) of the resource being referred.\n       * </pre>\n       *\n       * <code>optional uint32 id = 2;</code>\n       */\n      public Builder clearId() {\n        copyOnWrite();\n        instance.clearId();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The optional resource name.\n       * </pre>\n       *\n       * <code>optional string name = 3;</code>\n       */\n      public boolean hasName() {\n        return instance.hasName();\n      }\n      /**\n       * <pre>\n       * The optional resource name.\n       * </pre>\n       *\n       * <code>optional string name = 3;</code>\n       */\n      public java.lang.String getName() {\n        return instance.getName();\n      }\n      /**\n       * <pre>\n       * The optional resource name.\n       * </pre>\n       *\n       * <code>optional string name = 3;</code>\n       */\n      public com.google.protobuf.ByteString\n          getNameBytes() {\n        return instance.getNameBytes();\n      }\n      /**\n       * <pre>\n       * The optional resource name.\n       * </pre>\n       *\n       * <code>optional string name = 3;</code>\n       */\n      public Builder setName(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setName(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The optional resource name.\n       * </pre>\n       *\n       * <code>optional string name = 3;</code>\n       */\n      public Builder clearName() {\n        copyOnWrite();\n        instance.clearName();\n        return this;\n      }\n      /**\n       * <pre>\n       * The optional resource name.\n       * </pre>\n       *\n       * <code>optional string name = 3;</code>\n       */\n      public Builder setNameBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setNameBytes(value);\n        return this;\n      }\n\n      /**\n       * <pre>\n       * Whether this reference is referencing a private resource (&#64;*package:type/entry).\n       * </pre>\n       *\n       * <code>optional bool private = 4;</code>\n       */\n      public boolean hasPrivate() {\n        return instance.hasPrivate();\n      }\n      /**\n       * <pre>\n       * Whether this reference is referencing a private resource (&#64;*package:type/entry).\n       * </pre>\n       *\n       * <code>optional bool private = 4;</code>\n       */\n      public boolean getPrivate() {\n        return instance.getPrivate();\n      }\n      /**\n       * <pre>\n       * Whether this reference is referencing a private resource (&#64;*package:type/entry).\n       * </pre>\n       *\n       * <code>optional bool private = 4;</code>\n       */\n      public Builder setPrivate(boolean value) {\n        copyOnWrite();\n        instance.setPrivate(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Whether this reference is referencing a private resource (&#64;*package:type/entry).\n       * </pre>\n       *\n       * <code>optional bool private = 4;</code>\n       */\n      public Builder clearPrivate() {\n        copyOnWrite();\n        instance.clearPrivate();\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.Reference)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.Reference();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.Reference other = (com.android.aapt.Resources.Reference) arg1;\n          type_ = visitor.visitInt(hasType(), type_,\n              other.hasType(), other.type_);\n          id_ = visitor.visitInt(\n              hasId(), id_,\n              other.hasId(), other.id_);\n          name_ = visitor.visitString(\n              hasName(), name_,\n              other.hasName(), other.name_);\n          private_ = visitor.visitBoolean(\n              hasPrivate(), private_,\n              other.hasPrivate(), other.private_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 8: {\n                  int rawValue = input.readEnum();\n                  com.android.aapt.Resources.Reference.Type value = com.android.aapt.Resources.Reference.Type.forNumber(rawValue);\n                  if (value == null) {\n                    super.mergeVarintField(1, rawValue);\n                  } else {\n                    bitField0_ |= 0x00000001;\n                    type_ = rawValue;\n                  }\n                  break;\n                }\n                case 16: {\n                  bitField0_ |= 0x00000002;\n                  id_ = input.readUInt32();\n                  break;\n                }\n                case 26: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000004;\n                  name_ = s;\n                  break;\n                }\n                case 32: {\n                  bitField0_ |= 0x00000008;\n                  private_ = input.readBool();\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.Reference.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.Reference)\n    private static final com.android.aapt.Resources.Reference DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new Reference();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.Reference getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<Reference> PARSER;\n\n    public static com.google.protobuf.Parser<Reference> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface IdOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.Id)\n      com.google.protobuf.MessageLiteOrBuilder {\n  }\n  /**\n   * <pre>\n   * A value that represents an ID. This is just a placeholder, as ID values are used to occupy a\n   * resource ID (0xPPTTEEEE) as a unique identifier. Their value is unimportant.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.Id}\n   */\n  public  static final class Id extends\n      com.google.protobuf.GeneratedMessageLite<\n          Id, Id.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.Id)\n      IdOrBuilder {\n    private Id() {\n    }\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.Id parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Id parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Id parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Id parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Id parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Id parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Id parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Id parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Id parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Id parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.Id prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A value that represents an ID. This is just a placeholder, as ID values are used to occupy a\n     * resource ID (0xPPTTEEEE) as a unique identifier. Their value is unimportant.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Id}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.Id, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.Id)\n        com.android.aapt.Resources.IdOrBuilder {\n      // Construct using com.android.aapt.Resources.Id.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.Id)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.Id();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.Id other = (com.android.aapt.Resources.Id) arg1;\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.Id.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.Id)\n    private static final com.android.aapt.Resources.Id DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new Id();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.Id getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<Id> PARSER;\n\n    public static com.google.protobuf.Parser<Id> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface StringOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.String)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    boolean hasValue();\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    java.lang.String getValue();\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    com.google.protobuf.ByteString\n        getValueBytes();\n  }\n  /**\n   * <pre>\n   * A value that is a string.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.String}\n   */\n  public  static final class String extends\n      com.google.protobuf.GeneratedMessageLite<\n          String, String.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.String)\n      StringOrBuilder {\n    private String() {\n      value_ = \"\";\n    }\n    private int bitField0_;\n    public static final int VALUE_FIELD_NUMBER = 1;\n    private java.lang.String value_;\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    public boolean hasValue() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    public java.lang.String getValue() {\n      return value_;\n    }\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    public com.google.protobuf.ByteString\n        getValueBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(value_);\n    }\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    private void setValue(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      value_ = value;\n    }\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    private void clearValue() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      value_ = getDefaultInstance().getValue();\n    }\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    private void setValueBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      value_ = value.toStringUtf8();\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeString(1, getValue());\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(1, getValue());\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.String parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.String parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.String parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.String parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.String parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.String parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.String parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.String parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.String parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.String parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.String prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A value that is a string.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.String}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.String, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.String)\n        com.android.aapt.Resources.StringOrBuilder {\n      // Construct using com.android.aapt.Resources.String.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <code>optional string value = 1;</code>\n       */\n      public boolean hasValue() {\n        return instance.hasValue();\n      }\n      /**\n       * <code>optional string value = 1;</code>\n       */\n      public java.lang.String getValue() {\n        return instance.getValue();\n      }\n      /**\n       * <code>optional string value = 1;</code>\n       */\n      public com.google.protobuf.ByteString\n          getValueBytes() {\n        return instance.getValueBytes();\n      }\n      /**\n       * <code>optional string value = 1;</code>\n       */\n      public Builder setValue(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setValue(value);\n        return this;\n      }\n      /**\n       * <code>optional string value = 1;</code>\n       */\n      public Builder clearValue() {\n        copyOnWrite();\n        instance.clearValue();\n        return this;\n      }\n      /**\n       * <code>optional string value = 1;</code>\n       */\n      public Builder setValueBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setValueBytes(value);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.String)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.String();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.String other = (com.android.aapt.Resources.String) arg1;\n          value_ = visitor.visitString(\n              hasValue(), value_,\n              other.hasValue(), other.value_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000001;\n                  value_ = s;\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.String.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.String)\n    private static final com.android.aapt.Resources.String DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new String();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.String getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<String> PARSER;\n\n    public static com.google.protobuf.Parser<String> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface RawStringOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.RawString)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    boolean hasValue();\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    java.lang.String getValue();\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    com.google.protobuf.ByteString\n        getValueBytes();\n  }\n  /**\n   * <pre>\n   * A value that is a raw string, which is unescaped/uninterpreted. This is typically used to\n   * represent the value of a style attribute before the attribute is compiled and the set of\n   * allowed values is known.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.RawString}\n   */\n  public  static final class RawString extends\n      com.google.protobuf.GeneratedMessageLite<\n          RawString, RawString.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.RawString)\n      RawStringOrBuilder {\n    private RawString() {\n      value_ = \"\";\n    }\n    private int bitField0_;\n    public static final int VALUE_FIELD_NUMBER = 1;\n    private java.lang.String value_;\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    public boolean hasValue() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    public java.lang.String getValue() {\n      return value_;\n    }\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    public com.google.protobuf.ByteString\n        getValueBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(value_);\n    }\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    private void setValue(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      value_ = value;\n    }\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    private void clearValue() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      value_ = getDefaultInstance().getValue();\n    }\n    /**\n     * <code>optional string value = 1;</code>\n     */\n    private void setValueBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      value_ = value.toStringUtf8();\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeString(1, getValue());\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(1, getValue());\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.RawString parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.RawString parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.RawString parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.RawString parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.RawString parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.RawString parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.RawString parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.RawString parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.RawString parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.RawString parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.RawString prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A value that is a raw string, which is unescaped/uninterpreted. This is typically used to\n     * represent the value of a style attribute before the attribute is compiled and the set of\n     * allowed values is known.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.RawString}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.RawString, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.RawString)\n        com.android.aapt.Resources.RawStringOrBuilder {\n      // Construct using com.android.aapt.Resources.RawString.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <code>optional string value = 1;</code>\n       */\n      public boolean hasValue() {\n        return instance.hasValue();\n      }\n      /**\n       * <code>optional string value = 1;</code>\n       */\n      public java.lang.String getValue() {\n        return instance.getValue();\n      }\n      /**\n       * <code>optional string value = 1;</code>\n       */\n      public com.google.protobuf.ByteString\n          getValueBytes() {\n        return instance.getValueBytes();\n      }\n      /**\n       * <code>optional string value = 1;</code>\n       */\n      public Builder setValue(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setValue(value);\n        return this;\n      }\n      /**\n       * <code>optional string value = 1;</code>\n       */\n      public Builder clearValue() {\n        copyOnWrite();\n        instance.clearValue();\n        return this;\n      }\n      /**\n       * <code>optional string value = 1;</code>\n       */\n      public Builder setValueBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setValueBytes(value);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.RawString)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.RawString();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.RawString other = (com.android.aapt.Resources.RawString) arg1;\n          value_ = visitor.visitString(\n              hasValue(), value_,\n              other.hasValue(), other.value_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000001;\n                  value_ = s;\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.RawString.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.RawString)\n    private static final com.android.aapt.Resources.RawString DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new RawString();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.RawString getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<RawString> PARSER;\n\n    public static com.google.protobuf.Parser<RawString> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface StyledStringOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.StyledString)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * The raw text of the string.\n     * </pre>\n     *\n     * <code>optional string value = 1;</code>\n     */\n    boolean hasValue();\n    /**\n     * <pre>\n     * The raw text of the string.\n     * </pre>\n     *\n     * <code>optional string value = 1;</code>\n     */\n    java.lang.String getValue();\n    /**\n     * <pre>\n     * The raw text of the string.\n     * </pre>\n     *\n     * <code>optional string value = 1;</code>\n     */\n    com.google.protobuf.ByteString\n        getValueBytes();\n\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    java.util.List<com.android.aapt.Resources.StyledString.Span> \n        getSpanList();\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    com.android.aapt.Resources.StyledString.Span getSpan(int index);\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    int getSpanCount();\n  }\n  /**\n   * <pre>\n   * A string with styling information, like html tags that specify boldness, italics, etc.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.StyledString}\n   */\n  public  static final class StyledString extends\n      com.google.protobuf.GeneratedMessageLite<\n          StyledString, StyledString.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.StyledString)\n      StyledStringOrBuilder {\n    private StyledString() {\n      value_ = \"\";\n      span_ = emptyProtobufList();\n    }\n    public interface SpanOrBuilder extends\n        // @@protoc_insertion_point(interface_extends:aapt.pb.StyledString.Span)\n        com.google.protobuf.MessageLiteOrBuilder {\n\n      /**\n       * <pre>\n       * The name of the tag, and its attributes, encoded as follows:\n       * tag_name;attr1=value1;attr2=value2;[...]\n       * </pre>\n       *\n       * <code>optional string tag = 1;</code>\n       */\n      boolean hasTag();\n      /**\n       * <pre>\n       * The name of the tag, and its attributes, encoded as follows:\n       * tag_name;attr1=value1;attr2=value2;[...]\n       * </pre>\n       *\n       * <code>optional string tag = 1;</code>\n       */\n      java.lang.String getTag();\n      /**\n       * <pre>\n       * The name of the tag, and its attributes, encoded as follows:\n       * tag_name;attr1=value1;attr2=value2;[...]\n       * </pre>\n       *\n       * <code>optional string tag = 1;</code>\n       */\n      com.google.protobuf.ByteString\n          getTagBytes();\n\n      /**\n       * <pre>\n       * The first character position this span applies to, in UTF-16 offset.\n       * </pre>\n       *\n       * <code>optional uint32 first_char = 2;</code>\n       */\n      boolean hasFirstChar();\n      /**\n       * <pre>\n       * The first character position this span applies to, in UTF-16 offset.\n       * </pre>\n       *\n       * <code>optional uint32 first_char = 2;</code>\n       */\n      int getFirstChar();\n\n      /**\n       * <pre>\n       * The last character position this span applies to, in UTF-16 offset.\n       * </pre>\n       *\n       * <code>optional uint32 last_char = 3;</code>\n       */\n      boolean hasLastChar();\n      /**\n       * <pre>\n       * The last character position this span applies to, in UTF-16 offset.\n       * </pre>\n       *\n       * <code>optional uint32 last_char = 3;</code>\n       */\n      int getLastChar();\n    }\n    /**\n     * <pre>\n     * A Span marks a region of the string text that is styled.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.StyledString.Span}\n     */\n    public  static final class Span extends\n        com.google.protobuf.GeneratedMessageLite<\n            Span, Span.Builder> implements\n        // @@protoc_insertion_point(message_implements:aapt.pb.StyledString.Span)\n        SpanOrBuilder {\n      private Span() {\n        tag_ = \"\";\n      }\n      private int bitField0_;\n      public static final int TAG_FIELD_NUMBER = 1;\n      private java.lang.String tag_;\n      /**\n       * <pre>\n       * The name of the tag, and its attributes, encoded as follows:\n       * tag_name;attr1=value1;attr2=value2;[...]\n       * </pre>\n       *\n       * <code>optional string tag = 1;</code>\n       */\n      public boolean hasTag() {\n        return ((bitField0_ & 0x00000001) == 0x00000001);\n      }\n      /**\n       * <pre>\n       * The name of the tag, and its attributes, encoded as follows:\n       * tag_name;attr1=value1;attr2=value2;[...]\n       * </pre>\n       *\n       * <code>optional string tag = 1;</code>\n       */\n      public java.lang.String getTag() {\n        return tag_;\n      }\n      /**\n       * <pre>\n       * The name of the tag, and its attributes, encoded as follows:\n       * tag_name;attr1=value1;attr2=value2;[...]\n       * </pre>\n       *\n       * <code>optional string tag = 1;</code>\n       */\n      public com.google.protobuf.ByteString\n          getTagBytes() {\n        return com.google.protobuf.ByteString.copyFromUtf8(tag_);\n      }\n      /**\n       * <pre>\n       * The name of the tag, and its attributes, encoded as follows:\n       * tag_name;attr1=value1;attr2=value2;[...]\n       * </pre>\n       *\n       * <code>optional string tag = 1;</code>\n       */\n      private void setTag(\n          java.lang.String value) {\n        if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n        tag_ = value;\n      }\n      /**\n       * <pre>\n       * The name of the tag, and its attributes, encoded as follows:\n       * tag_name;attr1=value1;attr2=value2;[...]\n       * </pre>\n       *\n       * <code>optional string tag = 1;</code>\n       */\n      private void clearTag() {\n        bitField0_ = (bitField0_ & ~0x00000001);\n        tag_ = getDefaultInstance().getTag();\n      }\n      /**\n       * <pre>\n       * The name of the tag, and its attributes, encoded as follows:\n       * tag_name;attr1=value1;attr2=value2;[...]\n       * </pre>\n       *\n       * <code>optional string tag = 1;</code>\n       */\n      private void setTagBytes(\n          com.google.protobuf.ByteString value) {\n        if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n        tag_ = value.toStringUtf8();\n      }\n\n      public static final int FIRST_CHAR_FIELD_NUMBER = 2;\n      private int firstChar_;\n      /**\n       * <pre>\n       * The first character position this span applies to, in UTF-16 offset.\n       * </pre>\n       *\n       * <code>optional uint32 first_char = 2;</code>\n       */\n      public boolean hasFirstChar() {\n        return ((bitField0_ & 0x00000002) == 0x00000002);\n      }\n      /**\n       * <pre>\n       * The first character position this span applies to, in UTF-16 offset.\n       * </pre>\n       *\n       * <code>optional uint32 first_char = 2;</code>\n       */\n      public int getFirstChar() {\n        return firstChar_;\n      }\n      /**\n       * <pre>\n       * The first character position this span applies to, in UTF-16 offset.\n       * </pre>\n       *\n       * <code>optional uint32 first_char = 2;</code>\n       */\n      private void setFirstChar(int value) {\n        bitField0_ |= 0x00000002;\n        firstChar_ = value;\n      }\n      /**\n       * <pre>\n       * The first character position this span applies to, in UTF-16 offset.\n       * </pre>\n       *\n       * <code>optional uint32 first_char = 2;</code>\n       */\n      private void clearFirstChar() {\n        bitField0_ = (bitField0_ & ~0x00000002);\n        firstChar_ = 0;\n      }\n\n      public static final int LAST_CHAR_FIELD_NUMBER = 3;\n      private int lastChar_;\n      /**\n       * <pre>\n       * The last character position this span applies to, in UTF-16 offset.\n       * </pre>\n       *\n       * <code>optional uint32 last_char = 3;</code>\n       */\n      public boolean hasLastChar() {\n        return ((bitField0_ & 0x00000004) == 0x00000004);\n      }\n      /**\n       * <pre>\n       * The last character position this span applies to, in UTF-16 offset.\n       * </pre>\n       *\n       * <code>optional uint32 last_char = 3;</code>\n       */\n      public int getLastChar() {\n        return lastChar_;\n      }\n      /**\n       * <pre>\n       * The last character position this span applies to, in UTF-16 offset.\n       * </pre>\n       *\n       * <code>optional uint32 last_char = 3;</code>\n       */\n      private void setLastChar(int value) {\n        bitField0_ |= 0x00000004;\n        lastChar_ = value;\n      }\n      /**\n       * <pre>\n       * The last character position this span applies to, in UTF-16 offset.\n       * </pre>\n       *\n       * <code>optional uint32 last_char = 3;</code>\n       */\n      private void clearLastChar() {\n        bitField0_ = (bitField0_ & ~0x00000004);\n        lastChar_ = 0;\n      }\n\n      public void writeTo(com.google.protobuf.CodedOutputStream output)\n                          throws java.io.IOException {\n        if (((bitField0_ & 0x00000001) == 0x00000001)) {\n          output.writeString(1, getTag());\n        }\n        if (((bitField0_ & 0x00000002) == 0x00000002)) {\n          output.writeUInt32(2, firstChar_);\n        }\n        if (((bitField0_ & 0x00000004) == 0x00000004)) {\n          output.writeUInt32(3, lastChar_);\n        }\n        unknownFields.writeTo(output);\n      }\n\n      public int getSerializedSize() {\n        int size = memoizedSerializedSize;\n        if (size != -1) return size;\n\n        size = 0;\n        if (((bitField0_ & 0x00000001) == 0x00000001)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeStringSize(1, getTag());\n        }\n        if (((bitField0_ & 0x00000002) == 0x00000002)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeUInt32Size(2, firstChar_);\n        }\n        if (((bitField0_ & 0x00000004) == 0x00000004)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeUInt32Size(3, lastChar_);\n        }\n        size += unknownFields.getSerializedSize();\n        memoizedSerializedSize = size;\n        return size;\n      }\n\n      public static com.android.aapt.Resources.StyledString.Span parseFrom(\n          com.google.protobuf.ByteString data)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data);\n      }\n      public static com.android.aapt.Resources.StyledString.Span parseFrom(\n          com.google.protobuf.ByteString data,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.StyledString.Span parseFrom(byte[] data)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data);\n      }\n      public static com.android.aapt.Resources.StyledString.Span parseFrom(\n          byte[] data,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.StyledString.Span parseFrom(java.io.InputStream input)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.StyledString.Span parseFrom(\n          java.io.InputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.StyledString.Span parseDelimitedFrom(java.io.InputStream input)\n          throws java.io.IOException {\n        return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.StyledString.Span parseDelimitedFrom(\n          java.io.InputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.StyledString.Span parseFrom(\n          com.google.protobuf.CodedInputStream input)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.StyledString.Span parseFrom(\n          com.google.protobuf.CodedInputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n\n      public static Builder newBuilder() {\n        return DEFAULT_INSTANCE.toBuilder();\n      }\n      public static Builder newBuilder(com.android.aapt.Resources.StyledString.Span prototype) {\n        return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n      }\n\n      /**\n       * <pre>\n       * A Span marks a region of the string text that is styled.\n       * </pre>\n       *\n       * Protobuf type {@code aapt.pb.StyledString.Span}\n       */\n      public static final class Builder extends\n          com.google.protobuf.GeneratedMessageLite.Builder<\n            com.android.aapt.Resources.StyledString.Span, Builder> implements\n          // @@protoc_insertion_point(builder_implements:aapt.pb.StyledString.Span)\n          com.android.aapt.Resources.StyledString.SpanOrBuilder {\n        // Construct using com.android.aapt.Resources.StyledString.Span.newBuilder()\n        private Builder() {\n          super(DEFAULT_INSTANCE);\n        }\n\n\n        /**\n         * <pre>\n         * The name of the tag, and its attributes, encoded as follows:\n         * tag_name;attr1=value1;attr2=value2;[...]\n         * </pre>\n         *\n         * <code>optional string tag = 1;</code>\n         */\n        public boolean hasTag() {\n          return instance.hasTag();\n        }\n        /**\n         * <pre>\n         * The name of the tag, and its attributes, encoded as follows:\n         * tag_name;attr1=value1;attr2=value2;[...]\n         * </pre>\n         *\n         * <code>optional string tag = 1;</code>\n         */\n        public java.lang.String getTag() {\n          return instance.getTag();\n        }\n        /**\n         * <pre>\n         * The name of the tag, and its attributes, encoded as follows:\n         * tag_name;attr1=value1;attr2=value2;[...]\n         * </pre>\n         *\n         * <code>optional string tag = 1;</code>\n         */\n        public com.google.protobuf.ByteString\n            getTagBytes() {\n          return instance.getTagBytes();\n        }\n        /**\n         * <pre>\n         * The name of the tag, and its attributes, encoded as follows:\n         * tag_name;attr1=value1;attr2=value2;[...]\n         * </pre>\n         *\n         * <code>optional string tag = 1;</code>\n         */\n        public Builder setTag(\n            java.lang.String value) {\n          copyOnWrite();\n          instance.setTag(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * The name of the tag, and its attributes, encoded as follows:\n         * tag_name;attr1=value1;attr2=value2;[...]\n         * </pre>\n         *\n         * <code>optional string tag = 1;</code>\n         */\n        public Builder clearTag() {\n          copyOnWrite();\n          instance.clearTag();\n          return this;\n        }\n        /**\n         * <pre>\n         * The name of the tag, and its attributes, encoded as follows:\n         * tag_name;attr1=value1;attr2=value2;[...]\n         * </pre>\n         *\n         * <code>optional string tag = 1;</code>\n         */\n        public Builder setTagBytes(\n            com.google.protobuf.ByteString value) {\n          copyOnWrite();\n          instance.setTagBytes(value);\n          return this;\n        }\n\n        /**\n         * <pre>\n         * The first character position this span applies to, in UTF-16 offset.\n         * </pre>\n         *\n         * <code>optional uint32 first_char = 2;</code>\n         */\n        public boolean hasFirstChar() {\n          return instance.hasFirstChar();\n        }\n        /**\n         * <pre>\n         * The first character position this span applies to, in UTF-16 offset.\n         * </pre>\n         *\n         * <code>optional uint32 first_char = 2;</code>\n         */\n        public int getFirstChar() {\n          return instance.getFirstChar();\n        }\n        /**\n         * <pre>\n         * The first character position this span applies to, in UTF-16 offset.\n         * </pre>\n         *\n         * <code>optional uint32 first_char = 2;</code>\n         */\n        public Builder setFirstChar(int value) {\n          copyOnWrite();\n          instance.setFirstChar(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * The first character position this span applies to, in UTF-16 offset.\n         * </pre>\n         *\n         * <code>optional uint32 first_char = 2;</code>\n         */\n        public Builder clearFirstChar() {\n          copyOnWrite();\n          instance.clearFirstChar();\n          return this;\n        }\n\n        /**\n         * <pre>\n         * The last character position this span applies to, in UTF-16 offset.\n         * </pre>\n         *\n         * <code>optional uint32 last_char = 3;</code>\n         */\n        public boolean hasLastChar() {\n          return instance.hasLastChar();\n        }\n        /**\n         * <pre>\n         * The last character position this span applies to, in UTF-16 offset.\n         * </pre>\n         *\n         * <code>optional uint32 last_char = 3;</code>\n         */\n        public int getLastChar() {\n          return instance.getLastChar();\n        }\n        /**\n         * <pre>\n         * The last character position this span applies to, in UTF-16 offset.\n         * </pre>\n         *\n         * <code>optional uint32 last_char = 3;</code>\n         */\n        public Builder setLastChar(int value) {\n          copyOnWrite();\n          instance.setLastChar(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * The last character position this span applies to, in UTF-16 offset.\n         * </pre>\n         *\n         * <code>optional uint32 last_char = 3;</code>\n         */\n        public Builder clearLastChar() {\n          copyOnWrite();\n          instance.clearLastChar();\n          return this;\n        }\n\n        // @@protoc_insertion_point(builder_scope:aapt.pb.StyledString.Span)\n      }\n      protected final Object dynamicMethod(\n          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n          Object arg0, Object arg1) {\n        switch (method) {\n          case NEW_MUTABLE_INSTANCE: {\n            return new com.android.aapt.Resources.StyledString.Span();\n          }\n          case IS_INITIALIZED: {\n            return DEFAULT_INSTANCE;\n          }\n          case MAKE_IMMUTABLE: {\n            return null;\n          }\n          case NEW_BUILDER: {\n            return new Builder();\n          }\n          case VISIT: {\n            Visitor visitor = (Visitor) arg0;\n            com.android.aapt.Resources.StyledString.Span other = (com.android.aapt.Resources.StyledString.Span) arg1;\n            tag_ = visitor.visitString(\n                hasTag(), tag_,\n                other.hasTag(), other.tag_);\n            firstChar_ = visitor.visitInt(\n                hasFirstChar(), firstChar_,\n                other.hasFirstChar(), other.firstChar_);\n            lastChar_ = visitor.visitInt(\n                hasLastChar(), lastChar_,\n                other.hasLastChar(), other.lastChar_);\n            if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n                .INSTANCE) {\n              bitField0_ |= other.bitField0_;\n            }\n            return this;\n          }\n          case MERGE_FROM_STREAM: {\n            com.google.protobuf.CodedInputStream input =\n                (com.google.protobuf.CodedInputStream) arg0;\n            com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n                (com.google.protobuf.ExtensionRegistryLite) arg1;\n            try {\n              boolean done = false;\n              while (!done) {\n                int tag = input.readTag();\n                switch (tag) {\n                  case 0:\n                    done = true;\n                    break;\n                  default: {\n                    if (!parseUnknownField(tag, input)) {\n                      done = true;\n                    }\n                    break;\n                  }\n                  case 10: {\n                    java.lang.String s = input.readString();\n                    bitField0_ |= 0x00000001;\n                    tag_ = s;\n                    break;\n                  }\n                  case 16: {\n                    bitField0_ |= 0x00000002;\n                    firstChar_ = input.readUInt32();\n                    break;\n                  }\n                  case 24: {\n                    bitField0_ |= 0x00000004;\n                    lastChar_ = input.readUInt32();\n                    break;\n                  }\n                }\n              }\n            } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n              throw new RuntimeException(e.setUnfinishedMessage(this));\n            } catch (java.io.IOException e) {\n              throw new RuntimeException(\n                  new com.google.protobuf.InvalidProtocolBufferException(\n                      e.getMessage()).setUnfinishedMessage(this));\n            } finally {\n            }\n          }\n          case GET_DEFAULT_INSTANCE: {\n            return DEFAULT_INSTANCE;\n          }\n          case GET_PARSER: {\n            if (PARSER == null) {    synchronized (com.android.aapt.Resources.StyledString.Span.class) {\n                if (PARSER == null) {\n                  PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n                }\n              }\n            }\n            return PARSER;\n          }\n        }\n        throw new UnsupportedOperationException();\n      }\n\n\n      // @@protoc_insertion_point(class_scope:aapt.pb.StyledString.Span)\n      private static final com.android.aapt.Resources.StyledString.Span DEFAULT_INSTANCE;\n      static {\n        DEFAULT_INSTANCE = new Span();\n        DEFAULT_INSTANCE.makeImmutable();\n      }\n\n      public static com.android.aapt.Resources.StyledString.Span getDefaultInstance() {\n        return DEFAULT_INSTANCE;\n      }\n\n      private static volatile com.google.protobuf.Parser<Span> PARSER;\n\n      public static com.google.protobuf.Parser<Span> parser() {\n        return DEFAULT_INSTANCE.getParserForType();\n      }\n    }\n\n    private int bitField0_;\n    public static final int VALUE_FIELD_NUMBER = 1;\n    private java.lang.String value_;\n    /**\n     * <pre>\n     * The raw text of the string.\n     * </pre>\n     *\n     * <code>optional string value = 1;</code>\n     */\n    public boolean hasValue() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <pre>\n     * The raw text of the string.\n     * </pre>\n     *\n     * <code>optional string value = 1;</code>\n     */\n    public java.lang.String getValue() {\n      return value_;\n    }\n    /**\n     * <pre>\n     * The raw text of the string.\n     * </pre>\n     *\n     * <code>optional string value = 1;</code>\n     */\n    public com.google.protobuf.ByteString\n        getValueBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(value_);\n    }\n    /**\n     * <pre>\n     * The raw text of the string.\n     * </pre>\n     *\n     * <code>optional string value = 1;</code>\n     */\n    private void setValue(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      value_ = value;\n    }\n    /**\n     * <pre>\n     * The raw text of the string.\n     * </pre>\n     *\n     * <code>optional string value = 1;</code>\n     */\n    private void clearValue() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      value_ = getDefaultInstance().getValue();\n    }\n    /**\n     * <pre>\n     * The raw text of the string.\n     * </pre>\n     *\n     * <code>optional string value = 1;</code>\n     */\n    private void setValueBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      value_ = value.toStringUtf8();\n    }\n\n    public static final int SPAN_FIELD_NUMBER = 2;\n    private com.google.protobuf.Internal.ProtobufList<com.android.aapt.Resources.StyledString.Span> span_;\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    public java.util.List<com.android.aapt.Resources.StyledString.Span> getSpanList() {\n      return span_;\n    }\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    public java.util.List<? extends com.android.aapt.Resources.StyledString.SpanOrBuilder> \n        getSpanOrBuilderList() {\n      return span_;\n    }\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    public int getSpanCount() {\n      return span_.size();\n    }\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    public com.android.aapt.Resources.StyledString.Span getSpan(int index) {\n      return span_.get(index);\n    }\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    public com.android.aapt.Resources.StyledString.SpanOrBuilder getSpanOrBuilder(\n        int index) {\n      return span_.get(index);\n    }\n    private void ensureSpanIsMutable() {\n      if (!span_.isModifiable()) {\n        span_ =\n            com.google.protobuf.GeneratedMessageLite.mutableCopy(span_);\n       }\n    }\n\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    private void setSpan(\n        int index, com.android.aapt.Resources.StyledString.Span value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureSpanIsMutable();\n      span_.set(index, value);\n    }\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    private void setSpan(\n        int index, com.android.aapt.Resources.StyledString.Span.Builder builderForValue) {\n      ensureSpanIsMutable();\n      span_.set(index, builderForValue.build());\n    }\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    private void addSpan(com.android.aapt.Resources.StyledString.Span value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureSpanIsMutable();\n      span_.add(value);\n    }\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    private void addSpan(\n        int index, com.android.aapt.Resources.StyledString.Span value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureSpanIsMutable();\n      span_.add(index, value);\n    }\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    private void addSpan(\n        com.android.aapt.Resources.StyledString.Span.Builder builderForValue) {\n      ensureSpanIsMutable();\n      span_.add(builderForValue.build());\n    }\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    private void addSpan(\n        int index, com.android.aapt.Resources.StyledString.Span.Builder builderForValue) {\n      ensureSpanIsMutable();\n      span_.add(index, builderForValue.build());\n    }\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    private void addAllSpan(\n        java.lang.Iterable<? extends com.android.aapt.Resources.StyledString.Span> values) {\n      ensureSpanIsMutable();\n      com.google.protobuf.AbstractMessageLite.addAll(\n          values, span_);\n    }\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    private void clearSpan() {\n      span_ = emptyProtobufList();\n    }\n    /**\n     * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n     */\n    private void removeSpan(int index) {\n      ensureSpanIsMutable();\n      span_.remove(index);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeString(1, getValue());\n      }\n      for (int i = 0; i < span_.size(); i++) {\n        output.writeMessage(2, span_.get(i));\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(1, getValue());\n      }\n      for (int i = 0; i < span_.size(); i++) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(2, span_.get(i));\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.StyledString parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.StyledString parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.StyledString parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.StyledString parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.StyledString parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.StyledString parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.StyledString parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.StyledString parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.StyledString parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.StyledString parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.StyledString prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A string with styling information, like html tags that specify boldness, italics, etc.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.StyledString}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.StyledString, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.StyledString)\n        com.android.aapt.Resources.StyledStringOrBuilder {\n      // Construct using com.android.aapt.Resources.StyledString.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * The raw text of the string.\n       * </pre>\n       *\n       * <code>optional string value = 1;</code>\n       */\n      public boolean hasValue() {\n        return instance.hasValue();\n      }\n      /**\n       * <pre>\n       * The raw text of the string.\n       * </pre>\n       *\n       * <code>optional string value = 1;</code>\n       */\n      public java.lang.String getValue() {\n        return instance.getValue();\n      }\n      /**\n       * <pre>\n       * The raw text of the string.\n       * </pre>\n       *\n       * <code>optional string value = 1;</code>\n       */\n      public com.google.protobuf.ByteString\n          getValueBytes() {\n        return instance.getValueBytes();\n      }\n      /**\n       * <pre>\n       * The raw text of the string.\n       * </pre>\n       *\n       * <code>optional string value = 1;</code>\n       */\n      public Builder setValue(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setValue(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The raw text of the string.\n       * </pre>\n       *\n       * <code>optional string value = 1;</code>\n       */\n      public Builder clearValue() {\n        copyOnWrite();\n        instance.clearValue();\n        return this;\n      }\n      /**\n       * <pre>\n       * The raw text of the string.\n       * </pre>\n       *\n       * <code>optional string value = 1;</code>\n       */\n      public Builder setValueBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setValueBytes(value);\n        return this;\n      }\n\n      /**\n       * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n       */\n      public java.util.List<com.android.aapt.Resources.StyledString.Span> getSpanList() {\n        return java.util.Collections.unmodifiableList(\n            instance.getSpanList());\n      }\n      /**\n       * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n       */\n      public int getSpanCount() {\n        return instance.getSpanCount();\n      }/**\n       * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n       */\n      public com.android.aapt.Resources.StyledString.Span getSpan(int index) {\n        return instance.getSpan(index);\n      }\n      /**\n       * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n       */\n      public Builder setSpan(\n          int index, com.android.aapt.Resources.StyledString.Span value) {\n        copyOnWrite();\n        instance.setSpan(index, value);\n        return this;\n      }\n      /**\n       * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n       */\n      public Builder setSpan(\n          int index, com.android.aapt.Resources.StyledString.Span.Builder builderForValue) {\n        copyOnWrite();\n        instance.setSpan(index, builderForValue);\n        return this;\n      }\n      /**\n       * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n       */\n      public Builder addSpan(com.android.aapt.Resources.StyledString.Span value) {\n        copyOnWrite();\n        instance.addSpan(value);\n        return this;\n      }\n      /**\n       * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n       */\n      public Builder addSpan(\n          int index, com.android.aapt.Resources.StyledString.Span value) {\n        copyOnWrite();\n        instance.addSpan(index, value);\n        return this;\n      }\n      /**\n       * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n       */\n      public Builder addSpan(\n          com.android.aapt.Resources.StyledString.Span.Builder builderForValue) {\n        copyOnWrite();\n        instance.addSpan(builderForValue);\n        return this;\n      }\n      /**\n       * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n       */\n      public Builder addSpan(\n          int index, com.android.aapt.Resources.StyledString.Span.Builder builderForValue) {\n        copyOnWrite();\n        instance.addSpan(index, builderForValue);\n        return this;\n      }\n      /**\n       * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n       */\n      public Builder addAllSpan(\n          java.lang.Iterable<? extends com.android.aapt.Resources.StyledString.Span> values) {\n        copyOnWrite();\n        instance.addAllSpan(values);\n        return this;\n      }\n      /**\n       * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n       */\n      public Builder clearSpan() {\n        copyOnWrite();\n        instance.clearSpan();\n        return this;\n      }\n      /**\n       * <code>repeated .aapt.pb.StyledString.Span span = 2;</code>\n       */\n      public Builder removeSpan(int index) {\n        copyOnWrite();\n        instance.removeSpan(index);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.StyledString)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.StyledString();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          span_.makeImmutable();\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.StyledString other = (com.android.aapt.Resources.StyledString) arg1;\n          value_ = visitor.visitString(\n              hasValue(), value_,\n              other.hasValue(), other.value_);\n          span_= visitor.visitList(span_, other.span_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000001;\n                  value_ = s;\n                  break;\n                }\n                case 18: {\n                  if (!span_.isModifiable()) {\n                    span_ =\n                        com.google.protobuf.GeneratedMessageLite.mutableCopy(span_);\n                  }\n                  span_.add(\n                      input.readMessage(com.android.aapt.Resources.StyledString.Span.parser(), extensionRegistry));\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.StyledString.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.StyledString)\n    private static final com.android.aapt.Resources.StyledString DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new StyledString();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.StyledString getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<StyledString> PARSER;\n\n    public static com.google.protobuf.Parser<StyledString> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface FileReferenceOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.FileReference)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * Path to a file within the APK (typically res/type-config/entry.ext).\n     * </pre>\n     *\n     * <code>optional string path = 1;</code>\n     */\n    boolean hasPath();\n    /**\n     * <pre>\n     * Path to a file within the APK (typically res/type-config/entry.ext).\n     * </pre>\n     *\n     * <code>optional string path = 1;</code>\n     */\n    java.lang.String getPath();\n    /**\n     * <pre>\n     * Path to a file within the APK (typically res/type-config/entry.ext).\n     * </pre>\n     *\n     * <code>optional string path = 1;</code>\n     */\n    com.google.protobuf.ByteString\n        getPathBytes();\n  }\n  /**\n   * <pre>\n   * A value that is a reference to an external entity, like an XML file or a PNG.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.FileReference}\n   */\n  public  static final class FileReference extends\n      com.google.protobuf.GeneratedMessageLite<\n          FileReference, FileReference.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.FileReference)\n      FileReferenceOrBuilder {\n    private FileReference() {\n      path_ = \"\";\n    }\n    private int bitField0_;\n    public static final int PATH_FIELD_NUMBER = 1;\n    private java.lang.String path_;\n    /**\n     * <pre>\n     * Path to a file within the APK (typically res/type-config/entry.ext).\n     * </pre>\n     *\n     * <code>optional string path = 1;</code>\n     */\n    public boolean hasPath() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <pre>\n     * Path to a file within the APK (typically res/type-config/entry.ext).\n     * </pre>\n     *\n     * <code>optional string path = 1;</code>\n     */\n    public java.lang.String getPath() {\n      return path_;\n    }\n    /**\n     * <pre>\n     * Path to a file within the APK (typically res/type-config/entry.ext).\n     * </pre>\n     *\n     * <code>optional string path = 1;</code>\n     */\n    public com.google.protobuf.ByteString\n        getPathBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(path_);\n    }\n    /**\n     * <pre>\n     * Path to a file within the APK (typically res/type-config/entry.ext).\n     * </pre>\n     *\n     * <code>optional string path = 1;</code>\n     */\n    private void setPath(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      path_ = value;\n    }\n    /**\n     * <pre>\n     * Path to a file within the APK (typically res/type-config/entry.ext).\n     * </pre>\n     *\n     * <code>optional string path = 1;</code>\n     */\n    private void clearPath() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      path_ = getDefaultInstance().getPath();\n    }\n    /**\n     * <pre>\n     * Path to a file within the APK (typically res/type-config/entry.ext).\n     * </pre>\n     *\n     * <code>optional string path = 1;</code>\n     */\n    private void setPathBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      path_ = value.toStringUtf8();\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeString(1, getPath());\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(1, getPath());\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.FileReference parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.FileReference parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.FileReference parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.FileReference parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.FileReference parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.FileReference parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.FileReference parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.FileReference parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.FileReference parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.FileReference parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.FileReference prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A value that is a reference to an external entity, like an XML file or a PNG.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.FileReference}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.FileReference, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.FileReference)\n        com.android.aapt.Resources.FileReferenceOrBuilder {\n      // Construct using com.android.aapt.Resources.FileReference.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * Path to a file within the APK (typically res/type-config/entry.ext).\n       * </pre>\n       *\n       * <code>optional string path = 1;</code>\n       */\n      public boolean hasPath() {\n        return instance.hasPath();\n      }\n      /**\n       * <pre>\n       * Path to a file within the APK (typically res/type-config/entry.ext).\n       * </pre>\n       *\n       * <code>optional string path = 1;</code>\n       */\n      public java.lang.String getPath() {\n        return instance.getPath();\n      }\n      /**\n       * <pre>\n       * Path to a file within the APK (typically res/type-config/entry.ext).\n       * </pre>\n       *\n       * <code>optional string path = 1;</code>\n       */\n      public com.google.protobuf.ByteString\n          getPathBytes() {\n        return instance.getPathBytes();\n      }\n      /**\n       * <pre>\n       * Path to a file within the APK (typically res/type-config/entry.ext).\n       * </pre>\n       *\n       * <code>optional string path = 1;</code>\n       */\n      public Builder setPath(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setPath(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Path to a file within the APK (typically res/type-config/entry.ext).\n       * </pre>\n       *\n       * <code>optional string path = 1;</code>\n       */\n      public Builder clearPath() {\n        copyOnWrite();\n        instance.clearPath();\n        return this;\n      }\n      /**\n       * <pre>\n       * Path to a file within the APK (typically res/type-config/entry.ext).\n       * </pre>\n       *\n       * <code>optional string path = 1;</code>\n       */\n      public Builder setPathBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setPathBytes(value);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.FileReference)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.FileReference();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.FileReference other = (com.android.aapt.Resources.FileReference) arg1;\n          path_ = visitor.visitString(\n              hasPath(), path_,\n              other.hasPath(), other.path_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000001;\n                  path_ = s;\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.FileReference.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.FileReference)\n    private static final com.android.aapt.Resources.FileReference DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new FileReference();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.FileReference getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<FileReference> PARSER;\n\n    public static com.google.protobuf.Parser<FileReference> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface PrimitiveOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.Primitive)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <code>optional uint32 type = 1;</code>\n     */\n    boolean hasType();\n    /**\n     * <code>optional uint32 type = 1;</code>\n     */\n    int getType();\n\n    /**\n     * <code>optional uint32 data = 2;</code>\n     */\n    boolean hasData();\n    /**\n     * <code>optional uint32 data = 2;</code>\n     */\n    int getData();\n  }\n  /**\n   * <pre>\n   * A value that represents a primitive data type (float, int, boolean, etc.).\n   * Corresponds to the fields (type/data) of the C struct android::Res_value.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.Primitive}\n   */\n  public  static final class Primitive extends\n      com.google.protobuf.GeneratedMessageLite<\n          Primitive, Primitive.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.Primitive)\n      PrimitiveOrBuilder {\n    private Primitive() {\n    }\n    private int bitField0_;\n    public static final int TYPE_FIELD_NUMBER = 1;\n    private int type_;\n    /**\n     * <code>optional uint32 type = 1;</code>\n     */\n    public boolean hasType() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <code>optional uint32 type = 1;</code>\n     */\n    public int getType() {\n      return type_;\n    }\n    /**\n     * <code>optional uint32 type = 1;</code>\n     */\n    private void setType(int value) {\n      bitField0_ |= 0x00000001;\n      type_ = value;\n    }\n    /**\n     * <code>optional uint32 type = 1;</code>\n     */\n    private void clearType() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      type_ = 0;\n    }\n\n    public static final int DATA_FIELD_NUMBER = 2;\n    private int data_;\n    /**\n     * <code>optional uint32 data = 2;</code>\n     */\n    public boolean hasData() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <code>optional uint32 data = 2;</code>\n     */\n    public int getData() {\n      return data_;\n    }\n    /**\n     * <code>optional uint32 data = 2;</code>\n     */\n    private void setData(int value) {\n      bitField0_ |= 0x00000002;\n      data_ = value;\n    }\n    /**\n     * <code>optional uint32 data = 2;</code>\n     */\n    private void clearData() {\n      bitField0_ = (bitField0_ & ~0x00000002);\n      data_ = 0;\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeUInt32(1, type_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeUInt32(2, data_);\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeUInt32Size(1, type_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeUInt32Size(2, data_);\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.Primitive parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Primitive parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Primitive parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Primitive parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Primitive parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Primitive parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Primitive parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Primitive parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Primitive parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Primitive parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.Primitive prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A value that represents a primitive data type (float, int, boolean, etc.).\n     * Corresponds to the fields (type/data) of the C struct android::Res_value.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Primitive}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.Primitive, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.Primitive)\n        com.android.aapt.Resources.PrimitiveOrBuilder {\n      // Construct using com.android.aapt.Resources.Primitive.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <code>optional uint32 type = 1;</code>\n       */\n      public boolean hasType() {\n        return instance.hasType();\n      }\n      /**\n       * <code>optional uint32 type = 1;</code>\n       */\n      public int getType() {\n        return instance.getType();\n      }\n      /**\n       * <code>optional uint32 type = 1;</code>\n       */\n      public Builder setType(int value) {\n        copyOnWrite();\n        instance.setType(value);\n        return this;\n      }\n      /**\n       * <code>optional uint32 type = 1;</code>\n       */\n      public Builder clearType() {\n        copyOnWrite();\n        instance.clearType();\n        return this;\n      }\n\n      /**\n       * <code>optional uint32 data = 2;</code>\n       */\n      public boolean hasData() {\n        return instance.hasData();\n      }\n      /**\n       * <code>optional uint32 data = 2;</code>\n       */\n      public int getData() {\n        return instance.getData();\n      }\n      /**\n       * <code>optional uint32 data = 2;</code>\n       */\n      public Builder setData(int value) {\n        copyOnWrite();\n        instance.setData(value);\n        return this;\n      }\n      /**\n       * <code>optional uint32 data = 2;</code>\n       */\n      public Builder clearData() {\n        copyOnWrite();\n        instance.clearData();\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.Primitive)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.Primitive();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.Primitive other = (com.android.aapt.Resources.Primitive) arg1;\n          type_ = visitor.visitInt(\n              hasType(), type_,\n              other.hasType(), other.type_);\n          data_ = visitor.visitInt(\n              hasData(), data_,\n              other.hasData(), other.data_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 8: {\n                  bitField0_ |= 0x00000001;\n                  type_ = input.readUInt32();\n                  break;\n                }\n                case 16: {\n                  bitField0_ |= 0x00000002;\n                  data_ = input.readUInt32();\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.Primitive.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.Primitive)\n    private static final com.android.aapt.Resources.Primitive DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new Primitive();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.Primitive getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<Primitive> PARSER;\n\n    public static com.google.protobuf.Parser<Primitive> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface AttributeOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.Attribute)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * A bitmask of types that this XML attribute accepts. Corresponds to the flags in the\n     * enum FormatFlags.\n     * </pre>\n     *\n     * <code>optional uint32 format_flags = 1;</code>\n     */\n    boolean hasFormatFlags();\n    /**\n     * <pre>\n     * A bitmask of types that this XML attribute accepts. Corresponds to the flags in the\n     * enum FormatFlags.\n     * </pre>\n     *\n     * <code>optional uint32 format_flags = 1;</code>\n     */\n    int getFormatFlags();\n\n    /**\n     * <pre>\n     * The smallest integer allowed for this XML attribute. Only makes sense if the format includes\n     * FormatFlags::INTEGER.\n     * </pre>\n     *\n     * <code>optional int32 min_int = 2;</code>\n     */\n    boolean hasMinInt();\n    /**\n     * <pre>\n     * The smallest integer allowed for this XML attribute. Only makes sense if the format includes\n     * FormatFlags::INTEGER.\n     * </pre>\n     *\n     * <code>optional int32 min_int = 2;</code>\n     */\n    int getMinInt();\n\n    /**\n     * <pre>\n     * The largest integer allowed for this XML attribute. Only makes sense if the format includes\n     * FormatFlags::INTEGER.\n     * </pre>\n     *\n     * <code>optional int32 max_int = 3;</code>\n     */\n    boolean hasMaxInt();\n    /**\n     * <pre>\n     * The largest integer allowed for this XML attribute. Only makes sense if the format includes\n     * FormatFlags::INTEGER.\n     * </pre>\n     *\n     * <code>optional int32 max_int = 3;</code>\n     */\n    int getMaxInt();\n\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    java.util.List<com.android.aapt.Resources.Attribute.Symbol> \n        getSymbolList();\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    com.android.aapt.Resources.Attribute.Symbol getSymbol(int index);\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    int getSymbolCount();\n  }\n  /**\n   * <pre>\n   * A value that represents an XML attribute and what values it accepts.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.Attribute}\n   */\n  public  static final class Attribute extends\n      com.google.protobuf.GeneratedMessageLite<\n          Attribute, Attribute.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.Attribute)\n      AttributeOrBuilder {\n    private Attribute() {\n      symbol_ = emptyProtobufList();\n    }\n    /**\n     * <pre>\n     * Bitmask of formats allowed for an attribute.\n     * </pre>\n     *\n     * Protobuf enum {@code aapt.pb.Attribute.FormatFlags}\n     */\n    public enum FormatFlags\n        implements com.google.protobuf.Internal.EnumLite {\n      /**\n       * <pre>\n       * Allows any type except ENUM and FLAGS.\n       * </pre>\n       *\n       * <code>ANY = 65535;</code>\n       */\n      ANY(65535),\n      /**\n       * <pre>\n       * Allows Reference values.\n       * </pre>\n       *\n       * <code>REFERENCE = 1;</code>\n       */\n      REFERENCE(1),\n      /**\n       * <pre>\n       * Allows String/StyledString values.\n       * </pre>\n       *\n       * <code>STRING = 2;</code>\n       */\n      STRING(2),\n      /**\n       * <pre>\n       * Allows any integer BinaryPrimitive values.\n       * </pre>\n       *\n       * <code>INTEGER = 4;</code>\n       */\n      INTEGER(4),\n      /**\n       * <pre>\n       * Allows any boolean BinaryPrimitive values.\n       * </pre>\n       *\n       * <code>BOOLEAN = 8;</code>\n       */\n      BOOLEAN(8),\n      /**\n       * <pre>\n       * Allows any color BinaryPrimitive values.\n       * </pre>\n       *\n       * <code>COLOR = 16;</code>\n       */\n      COLOR(16),\n      /**\n       * <pre>\n       * Allows any float BinaryPrimitive values.\n       * </pre>\n       *\n       * <code>FLOAT = 32;</code>\n       */\n      FLOAT(32),\n      /**\n       * <pre>\n       * Allows any dimension BinaryPrimitive values.\n       * </pre>\n       *\n       * <code>DIMENSION = 64;</code>\n       */\n      DIMENSION(64),\n      /**\n       * <pre>\n       * Allows any fraction BinaryPrimitive values.\n       * </pre>\n       *\n       * <code>FRACTION = 128;</code>\n       */\n      FRACTION(128),\n      /**\n       * <pre>\n       * Allows enums that are defined in the Attribute's symbols.\n       * </pre>\n       *\n       * <code>ENUM = 65536;</code>\n       */\n      ENUM(65536),\n      /**\n       * <pre>\n       * ENUM and FLAGS cannot BOTH be set.\n       * </pre>\n       *\n       * <code>FLAGS = 131072;</code>\n       */\n      FLAGS(131072),\n      ;\n\n      /**\n       * <pre>\n       * Allows any type except ENUM and FLAGS.\n       * </pre>\n       *\n       * <code>ANY = 65535;</code>\n       */\n      public static final int ANY_VALUE = 65535;\n      /**\n       * <pre>\n       * Allows Reference values.\n       * </pre>\n       *\n       * <code>REFERENCE = 1;</code>\n       */\n      public static final int REFERENCE_VALUE = 1;\n      /**\n       * <pre>\n       * Allows String/StyledString values.\n       * </pre>\n       *\n       * <code>STRING = 2;</code>\n       */\n      public static final int STRING_VALUE = 2;\n      /**\n       * <pre>\n       * Allows any integer BinaryPrimitive values.\n       * </pre>\n       *\n       * <code>INTEGER = 4;</code>\n       */\n      public static final int INTEGER_VALUE = 4;\n      /**\n       * <pre>\n       * Allows any boolean BinaryPrimitive values.\n       * </pre>\n       *\n       * <code>BOOLEAN = 8;</code>\n       */\n      public static final int BOOLEAN_VALUE = 8;\n      /**\n       * <pre>\n       * Allows any color BinaryPrimitive values.\n       * </pre>\n       *\n       * <code>COLOR = 16;</code>\n       */\n      public static final int COLOR_VALUE = 16;\n      /**\n       * <pre>\n       * Allows any float BinaryPrimitive values.\n       * </pre>\n       *\n       * <code>FLOAT = 32;</code>\n       */\n      public static final int FLOAT_VALUE = 32;\n      /**\n       * <pre>\n       * Allows any dimension BinaryPrimitive values.\n       * </pre>\n       *\n       * <code>DIMENSION = 64;</code>\n       */\n      public static final int DIMENSION_VALUE = 64;\n      /**\n       * <pre>\n       * Allows any fraction BinaryPrimitive values.\n       * </pre>\n       *\n       * <code>FRACTION = 128;</code>\n       */\n      public static final int FRACTION_VALUE = 128;\n      /**\n       * <pre>\n       * Allows enums that are defined in the Attribute's symbols.\n       * </pre>\n       *\n       * <code>ENUM = 65536;</code>\n       */\n      public static final int ENUM_VALUE = 65536;\n      /**\n       * <pre>\n       * ENUM and FLAGS cannot BOTH be set.\n       * </pre>\n       *\n       * <code>FLAGS = 131072;</code>\n       */\n      public static final int FLAGS_VALUE = 131072;\n\n\n      public final int getNumber() {\n        return value;\n      }\n\n      /**\n       * @deprecated Use {@link #forNumber(int)} instead.\n       */\n      @java.lang.Deprecated\n      public static FormatFlags valueOf(int value) {\n        return forNumber(value);\n      }\n\n      public static FormatFlags forNumber(int value) {\n        switch (value) {\n          case 65535: return ANY;\n          case 1: return REFERENCE;\n          case 2: return STRING;\n          case 4: return INTEGER;\n          case 8: return BOOLEAN;\n          case 16: return COLOR;\n          case 32: return FLOAT;\n          case 64: return DIMENSION;\n          case 128: return FRACTION;\n          case 65536: return ENUM;\n          case 131072: return FLAGS;\n          default: return null;\n        }\n      }\n\n      public static com.google.protobuf.Internal.EnumLiteMap<FormatFlags>\n          internalGetValueMap() {\n        return internalValueMap;\n      }\n      private static final com.google.protobuf.Internal.EnumLiteMap<\n          FormatFlags> internalValueMap =\n            new com.google.protobuf.Internal.EnumLiteMap<FormatFlags>() {\n              public FormatFlags findValueByNumber(int number) {\n                return FormatFlags.forNumber(number);\n              }\n            };\n\n      private final int value;\n\n      private FormatFlags(int value) {\n        this.value = value;\n      }\n\n      // @@protoc_insertion_point(enum_scope:aapt.pb.Attribute.FormatFlags)\n    }\n\n    public interface SymbolOrBuilder extends\n        // @@protoc_insertion_point(interface_extends:aapt.pb.Attribute.Symbol)\n        com.google.protobuf.MessageLiteOrBuilder {\n\n      /**\n       * <pre>\n       * Where the enum/flag item was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      boolean hasSource();\n      /**\n       * <pre>\n       * Where the enum/flag item was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      com.android.aapt.Resources.Source getSource();\n\n      /**\n       * <pre>\n       * Any comments associated with the enum or flag.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      boolean hasComment();\n      /**\n       * <pre>\n       * Any comments associated with the enum or flag.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      java.lang.String getComment();\n      /**\n       * <pre>\n       * Any comments associated with the enum or flag.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      com.google.protobuf.ByteString\n          getCommentBytes();\n\n      /**\n       * <pre>\n       * The name of the enum/flag as a reference. Enums/flag items are generated as ID resource\n       * values.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference name = 3;</code>\n       */\n      boolean hasName();\n      /**\n       * <pre>\n       * The name of the enum/flag as a reference. Enums/flag items are generated as ID resource\n       * values.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference name = 3;</code>\n       */\n      com.android.aapt.Resources.Reference getName();\n\n      /**\n       * <pre>\n       * The value of the enum/flag.\n       * </pre>\n       *\n       * <code>optional uint32 value = 4;</code>\n       */\n      boolean hasValue();\n      /**\n       * <pre>\n       * The value of the enum/flag.\n       * </pre>\n       *\n       * <code>optional uint32 value = 4;</code>\n       */\n      int getValue();\n    }\n    /**\n     * <pre>\n     * A Symbol used to represent an enum or a flag.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Attribute.Symbol}\n     */\n    public  static final class Symbol extends\n        com.google.protobuf.GeneratedMessageLite<\n            Symbol, Symbol.Builder> implements\n        // @@protoc_insertion_point(message_implements:aapt.pb.Attribute.Symbol)\n        SymbolOrBuilder {\n      private Symbol() {\n        comment_ = \"\";\n      }\n      private int bitField0_;\n      public static final int SOURCE_FIELD_NUMBER = 1;\n      private com.android.aapt.Resources.Source source_;\n      /**\n       * <pre>\n       * Where the enum/flag item was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public boolean hasSource() {\n        return ((bitField0_ & 0x00000001) == 0x00000001);\n      }\n      /**\n       * <pre>\n       * Where the enum/flag item was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public com.android.aapt.Resources.Source getSource() {\n        return source_ == null ? com.android.aapt.Resources.Source.getDefaultInstance() : source_;\n      }\n      /**\n       * <pre>\n       * Where the enum/flag item was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void setSource(com.android.aapt.Resources.Source value) {\n        if (value == null) {\n          throw new NullPointerException();\n        }\n        source_ = value;\n        bitField0_ |= 0x00000001;\n        }\n      /**\n       * <pre>\n       * Where the enum/flag item was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void setSource(\n          com.android.aapt.Resources.Source.Builder builderForValue) {\n        source_ = builderForValue.build();\n        bitField0_ |= 0x00000001;\n      }\n      /**\n       * <pre>\n       * Where the enum/flag item was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void mergeSource(com.android.aapt.Resources.Source value) {\n        if (source_ != null &&\n            source_ != com.android.aapt.Resources.Source.getDefaultInstance()) {\n          source_ =\n            com.android.aapt.Resources.Source.newBuilder(source_).mergeFrom(value).buildPartial();\n        } else {\n          source_ = value;\n        }\n        bitField0_ |= 0x00000001;\n      }\n      /**\n       * <pre>\n       * Where the enum/flag item was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void clearSource() {  source_ = null;\n        bitField0_ = (bitField0_ & ~0x00000001);\n      }\n\n      public static final int COMMENT_FIELD_NUMBER = 2;\n      private java.lang.String comment_;\n      /**\n       * <pre>\n       * Any comments associated with the enum or flag.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public boolean hasComment() {\n        return ((bitField0_ & 0x00000002) == 0x00000002);\n      }\n      /**\n       * <pre>\n       * Any comments associated with the enum or flag.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public java.lang.String getComment() {\n        return comment_;\n      }\n      /**\n       * <pre>\n       * Any comments associated with the enum or flag.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public com.google.protobuf.ByteString\n          getCommentBytes() {\n        return com.google.protobuf.ByteString.copyFromUtf8(comment_);\n      }\n      /**\n       * <pre>\n       * Any comments associated with the enum or flag.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void setComment(\n          java.lang.String value) {\n        if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n        comment_ = value;\n      }\n      /**\n       * <pre>\n       * Any comments associated with the enum or flag.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void clearComment() {\n        bitField0_ = (bitField0_ & ~0x00000002);\n        comment_ = getDefaultInstance().getComment();\n      }\n      /**\n       * <pre>\n       * Any comments associated with the enum or flag.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void setCommentBytes(\n          com.google.protobuf.ByteString value) {\n        if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n        comment_ = value.toStringUtf8();\n      }\n\n      public static final int NAME_FIELD_NUMBER = 3;\n      private com.android.aapt.Resources.Reference name_;\n      /**\n       * <pre>\n       * The name of the enum/flag as a reference. Enums/flag items are generated as ID resource\n       * values.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference name = 3;</code>\n       */\n      public boolean hasName() {\n        return ((bitField0_ & 0x00000004) == 0x00000004);\n      }\n      /**\n       * <pre>\n       * The name of the enum/flag as a reference. Enums/flag items are generated as ID resource\n       * values.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference name = 3;</code>\n       */\n      public com.android.aapt.Resources.Reference getName() {\n        return name_ == null ? com.android.aapt.Resources.Reference.getDefaultInstance() : name_;\n      }\n      /**\n       * <pre>\n       * The name of the enum/flag as a reference. Enums/flag items are generated as ID resource\n       * values.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference name = 3;</code>\n       */\n      private void setName(com.android.aapt.Resources.Reference value) {\n        if (value == null) {\n          throw new NullPointerException();\n        }\n        name_ = value;\n        bitField0_ |= 0x00000004;\n        }\n      /**\n       * <pre>\n       * The name of the enum/flag as a reference. Enums/flag items are generated as ID resource\n       * values.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference name = 3;</code>\n       */\n      private void setName(\n          com.android.aapt.Resources.Reference.Builder builderForValue) {\n        name_ = builderForValue.build();\n        bitField0_ |= 0x00000004;\n      }\n      /**\n       * <pre>\n       * The name of the enum/flag as a reference. Enums/flag items are generated as ID resource\n       * values.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference name = 3;</code>\n       */\n      private void mergeName(com.android.aapt.Resources.Reference value) {\n        if (name_ != null &&\n            name_ != com.android.aapt.Resources.Reference.getDefaultInstance()) {\n          name_ =\n            com.android.aapt.Resources.Reference.newBuilder(name_).mergeFrom(value).buildPartial();\n        } else {\n          name_ = value;\n        }\n        bitField0_ |= 0x00000004;\n      }\n      /**\n       * <pre>\n       * The name of the enum/flag as a reference. Enums/flag items are generated as ID resource\n       * values.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference name = 3;</code>\n       */\n      private void clearName() {  name_ = null;\n        bitField0_ = (bitField0_ & ~0x00000004);\n      }\n\n      public static final int VALUE_FIELD_NUMBER = 4;\n      private int value_;\n      /**\n       * <pre>\n       * The value of the enum/flag.\n       * </pre>\n       *\n       * <code>optional uint32 value = 4;</code>\n       */\n      public boolean hasValue() {\n        return ((bitField0_ & 0x00000008) == 0x00000008);\n      }\n      /**\n       * <pre>\n       * The value of the enum/flag.\n       * </pre>\n       *\n       * <code>optional uint32 value = 4;</code>\n       */\n      public int getValue() {\n        return value_;\n      }\n      /**\n       * <pre>\n       * The value of the enum/flag.\n       * </pre>\n       *\n       * <code>optional uint32 value = 4;</code>\n       */\n      private void setValue(int value) {\n        bitField0_ |= 0x00000008;\n        value_ = value;\n      }\n      /**\n       * <pre>\n       * The value of the enum/flag.\n       * </pre>\n       *\n       * <code>optional uint32 value = 4;</code>\n       */\n      private void clearValue() {\n        bitField0_ = (bitField0_ & ~0x00000008);\n        value_ = 0;\n      }\n\n      public void writeTo(com.google.protobuf.CodedOutputStream output)\n                          throws java.io.IOException {\n        if (((bitField0_ & 0x00000001) == 0x00000001)) {\n          output.writeMessage(1, getSource());\n        }\n        if (((bitField0_ & 0x00000002) == 0x00000002)) {\n          output.writeString(2, getComment());\n        }\n        if (((bitField0_ & 0x00000004) == 0x00000004)) {\n          output.writeMessage(3, getName());\n        }\n        if (((bitField0_ & 0x00000008) == 0x00000008)) {\n          output.writeUInt32(4, value_);\n        }\n        unknownFields.writeTo(output);\n      }\n\n      public int getSerializedSize() {\n        int size = memoizedSerializedSize;\n        if (size != -1) return size;\n\n        size = 0;\n        if (((bitField0_ & 0x00000001) == 0x00000001)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeMessageSize(1, getSource());\n        }\n        if (((bitField0_ & 0x00000002) == 0x00000002)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeStringSize(2, getComment());\n        }\n        if (((bitField0_ & 0x00000004) == 0x00000004)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeMessageSize(3, getName());\n        }\n        if (((bitField0_ & 0x00000008) == 0x00000008)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeUInt32Size(4, value_);\n        }\n        size += unknownFields.getSerializedSize();\n        memoizedSerializedSize = size;\n        return size;\n      }\n\n      public static com.android.aapt.Resources.Attribute.Symbol parseFrom(\n          com.google.protobuf.ByteString data)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data);\n      }\n      public static com.android.aapt.Resources.Attribute.Symbol parseFrom(\n          com.google.protobuf.ByteString data,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Attribute.Symbol parseFrom(byte[] data)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data);\n      }\n      public static com.android.aapt.Resources.Attribute.Symbol parseFrom(\n          byte[] data,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Attribute.Symbol parseFrom(java.io.InputStream input)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Attribute.Symbol parseFrom(\n          java.io.InputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Attribute.Symbol parseDelimitedFrom(java.io.InputStream input)\n          throws java.io.IOException {\n        return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Attribute.Symbol parseDelimitedFrom(\n          java.io.InputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Attribute.Symbol parseFrom(\n          com.google.protobuf.CodedInputStream input)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Attribute.Symbol parseFrom(\n          com.google.protobuf.CodedInputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n\n      public static Builder newBuilder() {\n        return DEFAULT_INSTANCE.toBuilder();\n      }\n      public static Builder newBuilder(com.android.aapt.Resources.Attribute.Symbol prototype) {\n        return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n      }\n\n      /**\n       * <pre>\n       * A Symbol used to represent an enum or a flag.\n       * </pre>\n       *\n       * Protobuf type {@code aapt.pb.Attribute.Symbol}\n       */\n      public static final class Builder extends\n          com.google.protobuf.GeneratedMessageLite.Builder<\n            com.android.aapt.Resources.Attribute.Symbol, Builder> implements\n          // @@protoc_insertion_point(builder_implements:aapt.pb.Attribute.Symbol)\n          com.android.aapt.Resources.Attribute.SymbolOrBuilder {\n        // Construct using com.android.aapt.Resources.Attribute.Symbol.newBuilder()\n        private Builder() {\n          super(DEFAULT_INSTANCE);\n        }\n\n\n        /**\n         * <pre>\n         * Where the enum/flag item was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public boolean hasSource() {\n          return instance.hasSource();\n        }\n        /**\n         * <pre>\n         * Where the enum/flag item was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public com.android.aapt.Resources.Source getSource() {\n          return instance.getSource();\n        }\n        /**\n         * <pre>\n         * Where the enum/flag item was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder setSource(com.android.aapt.Resources.Source value) {\n          copyOnWrite();\n          instance.setSource(value);\n          return this;\n          }\n        /**\n         * <pre>\n         * Where the enum/flag item was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder setSource(\n            com.android.aapt.Resources.Source.Builder builderForValue) {\n          copyOnWrite();\n          instance.setSource(builderForValue);\n          return this;\n        }\n        /**\n         * <pre>\n         * Where the enum/flag item was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder mergeSource(com.android.aapt.Resources.Source value) {\n          copyOnWrite();\n          instance.mergeSource(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * Where the enum/flag item was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder clearSource() {  copyOnWrite();\n          instance.clearSource();\n          return this;\n        }\n\n        /**\n         * <pre>\n         * Any comments associated with the enum or flag.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public boolean hasComment() {\n          return instance.hasComment();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the enum or flag.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public java.lang.String getComment() {\n          return instance.getComment();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the enum or flag.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public com.google.protobuf.ByteString\n            getCommentBytes() {\n          return instance.getCommentBytes();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the enum or flag.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder setComment(\n            java.lang.String value) {\n          copyOnWrite();\n          instance.setComment(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * Any comments associated with the enum or flag.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder clearComment() {\n          copyOnWrite();\n          instance.clearComment();\n          return this;\n        }\n        /**\n         * <pre>\n         * Any comments associated with the enum or flag.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder setCommentBytes(\n            com.google.protobuf.ByteString value) {\n          copyOnWrite();\n          instance.setCommentBytes(value);\n          return this;\n        }\n\n        /**\n         * <pre>\n         * The name of the enum/flag as a reference. Enums/flag items are generated as ID resource\n         * values.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference name = 3;</code>\n         */\n        public boolean hasName() {\n          return instance.hasName();\n        }\n        /**\n         * <pre>\n         * The name of the enum/flag as a reference. Enums/flag items are generated as ID resource\n         * values.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference name = 3;</code>\n         */\n        public com.android.aapt.Resources.Reference getName() {\n          return instance.getName();\n        }\n        /**\n         * <pre>\n         * The name of the enum/flag as a reference. Enums/flag items are generated as ID resource\n         * values.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference name = 3;</code>\n         */\n        public Builder setName(com.android.aapt.Resources.Reference value) {\n          copyOnWrite();\n          instance.setName(value);\n          return this;\n          }\n        /**\n         * <pre>\n         * The name of the enum/flag as a reference. Enums/flag items are generated as ID resource\n         * values.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference name = 3;</code>\n         */\n        public Builder setName(\n            com.android.aapt.Resources.Reference.Builder builderForValue) {\n          copyOnWrite();\n          instance.setName(builderForValue);\n          return this;\n        }\n        /**\n         * <pre>\n         * The name of the enum/flag as a reference. Enums/flag items are generated as ID resource\n         * values.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference name = 3;</code>\n         */\n        public Builder mergeName(com.android.aapt.Resources.Reference value) {\n          copyOnWrite();\n          instance.mergeName(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * The name of the enum/flag as a reference. Enums/flag items are generated as ID resource\n         * values.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference name = 3;</code>\n         */\n        public Builder clearName() {  copyOnWrite();\n          instance.clearName();\n          return this;\n        }\n\n        /**\n         * <pre>\n         * The value of the enum/flag.\n         * </pre>\n         *\n         * <code>optional uint32 value = 4;</code>\n         */\n        public boolean hasValue() {\n          return instance.hasValue();\n        }\n        /**\n         * <pre>\n         * The value of the enum/flag.\n         * </pre>\n         *\n         * <code>optional uint32 value = 4;</code>\n         */\n        public int getValue() {\n          return instance.getValue();\n        }\n        /**\n         * <pre>\n         * The value of the enum/flag.\n         * </pre>\n         *\n         * <code>optional uint32 value = 4;</code>\n         */\n        public Builder setValue(int value) {\n          copyOnWrite();\n          instance.setValue(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * The value of the enum/flag.\n         * </pre>\n         *\n         * <code>optional uint32 value = 4;</code>\n         */\n        public Builder clearValue() {\n          copyOnWrite();\n          instance.clearValue();\n          return this;\n        }\n\n        // @@protoc_insertion_point(builder_scope:aapt.pb.Attribute.Symbol)\n      }\n      protected final Object dynamicMethod(\n          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n          Object arg0, Object arg1) {\n        switch (method) {\n          case NEW_MUTABLE_INSTANCE: {\n            return new com.android.aapt.Resources.Attribute.Symbol();\n          }\n          case IS_INITIALIZED: {\n            return DEFAULT_INSTANCE;\n          }\n          case MAKE_IMMUTABLE: {\n            return null;\n          }\n          case NEW_BUILDER: {\n            return new Builder();\n          }\n          case VISIT: {\n            Visitor visitor = (Visitor) arg0;\n            com.android.aapt.Resources.Attribute.Symbol other = (com.android.aapt.Resources.Attribute.Symbol) arg1;\n            source_ = visitor.visitMessage(source_, other.source_);\n            comment_ = visitor.visitString(\n                hasComment(), comment_,\n                other.hasComment(), other.comment_);\n            name_ = visitor.visitMessage(name_, other.name_);\n            value_ = visitor.visitInt(\n                hasValue(), value_,\n                other.hasValue(), other.value_);\n            if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n                .INSTANCE) {\n              bitField0_ |= other.bitField0_;\n            }\n            return this;\n          }\n          case MERGE_FROM_STREAM: {\n            com.google.protobuf.CodedInputStream input =\n                (com.google.protobuf.CodedInputStream) arg0;\n            com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n                (com.google.protobuf.ExtensionRegistryLite) arg1;\n            try {\n              boolean done = false;\n              while (!done) {\n                int tag = input.readTag();\n                switch (tag) {\n                  case 0:\n                    done = true;\n                    break;\n                  default: {\n                    if (!parseUnknownField(tag, input)) {\n                      done = true;\n                    }\n                    break;\n                  }\n                  case 10: {\n                    com.android.aapt.Resources.Source.Builder subBuilder = null;\n                    if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                      subBuilder = source_.toBuilder();\n                    }\n                    source_ = input.readMessage(com.android.aapt.Resources.Source.parser(), extensionRegistry);\n                    if (subBuilder != null) {\n                      subBuilder.mergeFrom(source_);\n                      source_ = subBuilder.buildPartial();\n                    }\n                    bitField0_ |= 0x00000001;\n                    break;\n                  }\n                  case 18: {\n                    java.lang.String s = input.readString();\n                    bitField0_ |= 0x00000002;\n                    comment_ = s;\n                    break;\n                  }\n                  case 26: {\n                    com.android.aapt.Resources.Reference.Builder subBuilder = null;\n                    if (((bitField0_ & 0x00000004) == 0x00000004)) {\n                      subBuilder = name_.toBuilder();\n                    }\n                    name_ = input.readMessage(com.android.aapt.Resources.Reference.parser(), extensionRegistry);\n                    if (subBuilder != null) {\n                      subBuilder.mergeFrom(name_);\n                      name_ = subBuilder.buildPartial();\n                    }\n                    bitField0_ |= 0x00000004;\n                    break;\n                  }\n                  case 32: {\n                    bitField0_ |= 0x00000008;\n                    value_ = input.readUInt32();\n                    break;\n                  }\n                }\n              }\n            } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n              throw new RuntimeException(e.setUnfinishedMessage(this));\n            } catch (java.io.IOException e) {\n              throw new RuntimeException(\n                  new com.google.protobuf.InvalidProtocolBufferException(\n                      e.getMessage()).setUnfinishedMessage(this));\n            } finally {\n            }\n          }\n          case GET_DEFAULT_INSTANCE: {\n            return DEFAULT_INSTANCE;\n          }\n          case GET_PARSER: {\n            if (PARSER == null) {    synchronized (com.android.aapt.Resources.Attribute.Symbol.class) {\n                if (PARSER == null) {\n                  PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n                }\n              }\n            }\n            return PARSER;\n          }\n        }\n        throw new UnsupportedOperationException();\n      }\n\n\n      // @@protoc_insertion_point(class_scope:aapt.pb.Attribute.Symbol)\n      private static final com.android.aapt.Resources.Attribute.Symbol DEFAULT_INSTANCE;\n      static {\n        DEFAULT_INSTANCE = new Symbol();\n        DEFAULT_INSTANCE.makeImmutable();\n      }\n\n      public static com.android.aapt.Resources.Attribute.Symbol getDefaultInstance() {\n        return DEFAULT_INSTANCE;\n      }\n\n      private static volatile com.google.protobuf.Parser<Symbol> PARSER;\n\n      public static com.google.protobuf.Parser<Symbol> parser() {\n        return DEFAULT_INSTANCE.getParserForType();\n      }\n    }\n\n    private int bitField0_;\n    public static final int FORMAT_FLAGS_FIELD_NUMBER = 1;\n    private int formatFlags_;\n    /**\n     * <pre>\n     * A bitmask of types that this XML attribute accepts. Corresponds to the flags in the\n     * enum FormatFlags.\n     * </pre>\n     *\n     * <code>optional uint32 format_flags = 1;</code>\n     */\n    public boolean hasFormatFlags() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <pre>\n     * A bitmask of types that this XML attribute accepts. Corresponds to the flags in the\n     * enum FormatFlags.\n     * </pre>\n     *\n     * <code>optional uint32 format_flags = 1;</code>\n     */\n    public int getFormatFlags() {\n      return formatFlags_;\n    }\n    /**\n     * <pre>\n     * A bitmask of types that this XML attribute accepts. Corresponds to the flags in the\n     * enum FormatFlags.\n     * </pre>\n     *\n     * <code>optional uint32 format_flags = 1;</code>\n     */\n    private void setFormatFlags(int value) {\n      bitField0_ |= 0x00000001;\n      formatFlags_ = value;\n    }\n    /**\n     * <pre>\n     * A bitmask of types that this XML attribute accepts. Corresponds to the flags in the\n     * enum FormatFlags.\n     * </pre>\n     *\n     * <code>optional uint32 format_flags = 1;</code>\n     */\n    private void clearFormatFlags() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      formatFlags_ = 0;\n    }\n\n    public static final int MIN_INT_FIELD_NUMBER = 2;\n    private int minInt_;\n    /**\n     * <pre>\n     * The smallest integer allowed for this XML attribute. Only makes sense if the format includes\n     * FormatFlags::INTEGER.\n     * </pre>\n     *\n     * <code>optional int32 min_int = 2;</code>\n     */\n    public boolean hasMinInt() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <pre>\n     * The smallest integer allowed for this XML attribute. Only makes sense if the format includes\n     * FormatFlags::INTEGER.\n     * </pre>\n     *\n     * <code>optional int32 min_int = 2;</code>\n     */\n    public int getMinInt() {\n      return minInt_;\n    }\n    /**\n     * <pre>\n     * The smallest integer allowed for this XML attribute. Only makes sense if the format includes\n     * FormatFlags::INTEGER.\n     * </pre>\n     *\n     * <code>optional int32 min_int = 2;</code>\n     */\n    private void setMinInt(int value) {\n      bitField0_ |= 0x00000002;\n      minInt_ = value;\n    }\n    /**\n     * <pre>\n     * The smallest integer allowed for this XML attribute. Only makes sense if the format includes\n     * FormatFlags::INTEGER.\n     * </pre>\n     *\n     * <code>optional int32 min_int = 2;</code>\n     */\n    private void clearMinInt() {\n      bitField0_ = (bitField0_ & ~0x00000002);\n      minInt_ = 0;\n    }\n\n    public static final int MAX_INT_FIELD_NUMBER = 3;\n    private int maxInt_;\n    /**\n     * <pre>\n     * The largest integer allowed for this XML attribute. Only makes sense if the format includes\n     * FormatFlags::INTEGER.\n     * </pre>\n     *\n     * <code>optional int32 max_int = 3;</code>\n     */\n    public boolean hasMaxInt() {\n      return ((bitField0_ & 0x00000004) == 0x00000004);\n    }\n    /**\n     * <pre>\n     * The largest integer allowed for this XML attribute. Only makes sense if the format includes\n     * FormatFlags::INTEGER.\n     * </pre>\n     *\n     * <code>optional int32 max_int = 3;</code>\n     */\n    public int getMaxInt() {\n      return maxInt_;\n    }\n    /**\n     * <pre>\n     * The largest integer allowed for this XML attribute. Only makes sense if the format includes\n     * FormatFlags::INTEGER.\n     * </pre>\n     *\n     * <code>optional int32 max_int = 3;</code>\n     */\n    private void setMaxInt(int value) {\n      bitField0_ |= 0x00000004;\n      maxInt_ = value;\n    }\n    /**\n     * <pre>\n     * The largest integer allowed for this XML attribute. Only makes sense if the format includes\n     * FormatFlags::INTEGER.\n     * </pre>\n     *\n     * <code>optional int32 max_int = 3;</code>\n     */\n    private void clearMaxInt() {\n      bitField0_ = (bitField0_ & ~0x00000004);\n      maxInt_ = 0;\n    }\n\n    public static final int SYMBOL_FIELD_NUMBER = 4;\n    private com.google.protobuf.Internal.ProtobufList<com.android.aapt.Resources.Attribute.Symbol> symbol_;\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    public java.util.List<com.android.aapt.Resources.Attribute.Symbol> getSymbolList() {\n      return symbol_;\n    }\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    public java.util.List<? extends com.android.aapt.Resources.Attribute.SymbolOrBuilder> \n        getSymbolOrBuilderList() {\n      return symbol_;\n    }\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    public int getSymbolCount() {\n      return symbol_.size();\n    }\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    public com.android.aapt.Resources.Attribute.Symbol getSymbol(int index) {\n      return symbol_.get(index);\n    }\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    public com.android.aapt.Resources.Attribute.SymbolOrBuilder getSymbolOrBuilder(\n        int index) {\n      return symbol_.get(index);\n    }\n    private void ensureSymbolIsMutable() {\n      if (!symbol_.isModifiable()) {\n        symbol_ =\n            com.google.protobuf.GeneratedMessageLite.mutableCopy(symbol_);\n       }\n    }\n\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    private void setSymbol(\n        int index, com.android.aapt.Resources.Attribute.Symbol value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureSymbolIsMutable();\n      symbol_.set(index, value);\n    }\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    private void setSymbol(\n        int index, com.android.aapt.Resources.Attribute.Symbol.Builder builderForValue) {\n      ensureSymbolIsMutable();\n      symbol_.set(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    private void addSymbol(com.android.aapt.Resources.Attribute.Symbol value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureSymbolIsMutable();\n      symbol_.add(value);\n    }\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    private void addSymbol(\n        int index, com.android.aapt.Resources.Attribute.Symbol value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureSymbolIsMutable();\n      symbol_.add(index, value);\n    }\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    private void addSymbol(\n        com.android.aapt.Resources.Attribute.Symbol.Builder builderForValue) {\n      ensureSymbolIsMutable();\n      symbol_.add(builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    private void addSymbol(\n        int index, com.android.aapt.Resources.Attribute.Symbol.Builder builderForValue) {\n      ensureSymbolIsMutable();\n      symbol_.add(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    private void addAllSymbol(\n        java.lang.Iterable<? extends com.android.aapt.Resources.Attribute.Symbol> values) {\n      ensureSymbolIsMutable();\n      com.google.protobuf.AbstractMessageLite.addAll(\n          values, symbol_);\n    }\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    private void clearSymbol() {\n      symbol_ = emptyProtobufList();\n    }\n    /**\n     * <pre>\n     * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n     * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n     */\n    private void removeSymbol(int index) {\n      ensureSymbolIsMutable();\n      symbol_.remove(index);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeUInt32(1, formatFlags_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeInt32(2, minInt_);\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        output.writeInt32(3, maxInt_);\n      }\n      for (int i = 0; i < symbol_.size(); i++) {\n        output.writeMessage(4, symbol_.get(i));\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeUInt32Size(1, formatFlags_);\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeInt32Size(2, minInt_);\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeInt32Size(3, maxInt_);\n      }\n      for (int i = 0; i < symbol_.size(); i++) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(4, symbol_.get(i));\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.Attribute parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Attribute parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Attribute parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Attribute parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Attribute parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Attribute parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Attribute parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Attribute parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Attribute parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Attribute parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.Attribute prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A value that represents an XML attribute and what values it accepts.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Attribute}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.Attribute, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.Attribute)\n        com.android.aapt.Resources.AttributeOrBuilder {\n      // Construct using com.android.aapt.Resources.Attribute.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * A bitmask of types that this XML attribute accepts. Corresponds to the flags in the\n       * enum FormatFlags.\n       * </pre>\n       *\n       * <code>optional uint32 format_flags = 1;</code>\n       */\n      public boolean hasFormatFlags() {\n        return instance.hasFormatFlags();\n      }\n      /**\n       * <pre>\n       * A bitmask of types that this XML attribute accepts. Corresponds to the flags in the\n       * enum FormatFlags.\n       * </pre>\n       *\n       * <code>optional uint32 format_flags = 1;</code>\n       */\n      public int getFormatFlags() {\n        return instance.getFormatFlags();\n      }\n      /**\n       * <pre>\n       * A bitmask of types that this XML attribute accepts. Corresponds to the flags in the\n       * enum FormatFlags.\n       * </pre>\n       *\n       * <code>optional uint32 format_flags = 1;</code>\n       */\n      public Builder setFormatFlags(int value) {\n        copyOnWrite();\n        instance.setFormatFlags(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * A bitmask of types that this XML attribute accepts. Corresponds to the flags in the\n       * enum FormatFlags.\n       * </pre>\n       *\n       * <code>optional uint32 format_flags = 1;</code>\n       */\n      public Builder clearFormatFlags() {\n        copyOnWrite();\n        instance.clearFormatFlags();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The smallest integer allowed for this XML attribute. Only makes sense if the format includes\n       * FormatFlags::INTEGER.\n       * </pre>\n       *\n       * <code>optional int32 min_int = 2;</code>\n       */\n      public boolean hasMinInt() {\n        return instance.hasMinInt();\n      }\n      /**\n       * <pre>\n       * The smallest integer allowed for this XML attribute. Only makes sense if the format includes\n       * FormatFlags::INTEGER.\n       * </pre>\n       *\n       * <code>optional int32 min_int = 2;</code>\n       */\n      public int getMinInt() {\n        return instance.getMinInt();\n      }\n      /**\n       * <pre>\n       * The smallest integer allowed for this XML attribute. Only makes sense if the format includes\n       * FormatFlags::INTEGER.\n       * </pre>\n       *\n       * <code>optional int32 min_int = 2;</code>\n       */\n      public Builder setMinInt(int value) {\n        copyOnWrite();\n        instance.setMinInt(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The smallest integer allowed for this XML attribute. Only makes sense if the format includes\n       * FormatFlags::INTEGER.\n       * </pre>\n       *\n       * <code>optional int32 min_int = 2;</code>\n       */\n      public Builder clearMinInt() {\n        copyOnWrite();\n        instance.clearMinInt();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The largest integer allowed for this XML attribute. Only makes sense if the format includes\n       * FormatFlags::INTEGER.\n       * </pre>\n       *\n       * <code>optional int32 max_int = 3;</code>\n       */\n      public boolean hasMaxInt() {\n        return instance.hasMaxInt();\n      }\n      /**\n       * <pre>\n       * The largest integer allowed for this XML attribute. Only makes sense if the format includes\n       * FormatFlags::INTEGER.\n       * </pre>\n       *\n       * <code>optional int32 max_int = 3;</code>\n       */\n      public int getMaxInt() {\n        return instance.getMaxInt();\n      }\n      /**\n       * <pre>\n       * The largest integer allowed for this XML attribute. Only makes sense if the format includes\n       * FormatFlags::INTEGER.\n       * </pre>\n       *\n       * <code>optional int32 max_int = 3;</code>\n       */\n      public Builder setMaxInt(int value) {\n        copyOnWrite();\n        instance.setMaxInt(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The largest integer allowed for this XML attribute. Only makes sense if the format includes\n       * FormatFlags::INTEGER.\n       * </pre>\n       *\n       * <code>optional int32 max_int = 3;</code>\n       */\n      public Builder clearMaxInt() {\n        copyOnWrite();\n        instance.clearMaxInt();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n       * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n       */\n      public java.util.List<com.android.aapt.Resources.Attribute.Symbol> getSymbolList() {\n        return java.util.Collections.unmodifiableList(\n            instance.getSymbolList());\n      }\n      /**\n       * <pre>\n       * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n       * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n       */\n      public int getSymbolCount() {\n        return instance.getSymbolCount();\n      }/**\n       * <pre>\n       * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n       * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n       */\n      public com.android.aapt.Resources.Attribute.Symbol getSymbol(int index) {\n        return instance.getSymbol(index);\n      }\n      /**\n       * <pre>\n       * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n       * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n       */\n      public Builder setSymbol(\n          int index, com.android.aapt.Resources.Attribute.Symbol value) {\n        copyOnWrite();\n        instance.setSymbol(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n       * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n       */\n      public Builder setSymbol(\n          int index, com.android.aapt.Resources.Attribute.Symbol.Builder builderForValue) {\n        copyOnWrite();\n        instance.setSymbol(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n       * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n       */\n      public Builder addSymbol(com.android.aapt.Resources.Attribute.Symbol value) {\n        copyOnWrite();\n        instance.addSymbol(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n       * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n       */\n      public Builder addSymbol(\n          int index, com.android.aapt.Resources.Attribute.Symbol value) {\n        copyOnWrite();\n        instance.addSymbol(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n       * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n       */\n      public Builder addSymbol(\n          com.android.aapt.Resources.Attribute.Symbol.Builder builderForValue) {\n        copyOnWrite();\n        instance.addSymbol(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n       * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n       */\n      public Builder addSymbol(\n          int index, com.android.aapt.Resources.Attribute.Symbol.Builder builderForValue) {\n        copyOnWrite();\n        instance.addSymbol(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n       * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n       */\n      public Builder addAllSymbol(\n          java.lang.Iterable<? extends com.android.aapt.Resources.Attribute.Symbol> values) {\n        copyOnWrite();\n        instance.addAllSymbol(values);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n       * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n       */\n      public Builder clearSymbol() {\n        copyOnWrite();\n        instance.clearSymbol();\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of enums/flags defined in this attribute. Only makes sense if the format includes\n       * either FormatFlags::ENUM or FormatFlags::FLAGS. Having both is an error.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Attribute.Symbol symbol = 4;</code>\n       */\n      public Builder removeSymbol(int index) {\n        copyOnWrite();\n        instance.removeSymbol(index);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.Attribute)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.Attribute();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          symbol_.makeImmutable();\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.Attribute other = (com.android.aapt.Resources.Attribute) arg1;\n          formatFlags_ = visitor.visitInt(\n              hasFormatFlags(), formatFlags_,\n              other.hasFormatFlags(), other.formatFlags_);\n          minInt_ = visitor.visitInt(\n              hasMinInt(), minInt_,\n              other.hasMinInt(), other.minInt_);\n          maxInt_ = visitor.visitInt(\n              hasMaxInt(), maxInt_,\n              other.hasMaxInt(), other.maxInt_);\n          symbol_= visitor.visitList(symbol_, other.symbol_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 8: {\n                  bitField0_ |= 0x00000001;\n                  formatFlags_ = input.readUInt32();\n                  break;\n                }\n                case 16: {\n                  bitField0_ |= 0x00000002;\n                  minInt_ = input.readInt32();\n                  break;\n                }\n                case 24: {\n                  bitField0_ |= 0x00000004;\n                  maxInt_ = input.readInt32();\n                  break;\n                }\n                case 34: {\n                  if (!symbol_.isModifiable()) {\n                    symbol_ =\n                        com.google.protobuf.GeneratedMessageLite.mutableCopy(symbol_);\n                  }\n                  symbol_.add(\n                      input.readMessage(com.android.aapt.Resources.Attribute.Symbol.parser(), extensionRegistry));\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.Attribute.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.Attribute)\n    private static final com.android.aapt.Resources.Attribute DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new Attribute();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.Attribute getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<Attribute> PARSER;\n\n    public static com.google.protobuf.Parser<Attribute> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface StyleOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.Style)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * The optinal style from which this style inherits attributes.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Reference parent = 1;</code>\n     */\n    boolean hasParent();\n    /**\n     * <pre>\n     * The optinal style from which this style inherits attributes.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Reference parent = 1;</code>\n     */\n    com.android.aapt.Resources.Reference getParent();\n\n    /**\n     * <pre>\n     * The source file information of the parent inheritance declaration.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source parent_source = 2;</code>\n     */\n    boolean hasParentSource();\n    /**\n     * <pre>\n     * The source file information of the parent inheritance declaration.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source parent_source = 2;</code>\n     */\n    com.android.aapt.Resources.Source getParentSource();\n\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    java.util.List<com.android.aapt.Resources.Style.Entry> \n        getEntryList();\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    com.android.aapt.Resources.Style.Entry getEntry(int index);\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    int getEntryCount();\n  }\n  /**\n   * <pre>\n   * A value that represents a style.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.Style}\n   */\n  public  static final class Style extends\n      com.google.protobuf.GeneratedMessageLite<\n          Style, Style.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.Style)\n      StyleOrBuilder {\n    private Style() {\n      entry_ = emptyProtobufList();\n    }\n    public interface EntryOrBuilder extends\n        // @@protoc_insertion_point(interface_extends:aapt.pb.Style.Entry)\n        com.google.protobuf.MessageLiteOrBuilder {\n\n      /**\n       * <pre>\n       * Where the entry was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      boolean hasSource();\n      /**\n       * <pre>\n       * Where the entry was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      com.android.aapt.Resources.Source getSource();\n\n      /**\n       * <pre>\n       * Any comments associated with the entry.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      boolean hasComment();\n      /**\n       * <pre>\n       * Any comments associated with the entry.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      java.lang.String getComment();\n      /**\n       * <pre>\n       * Any comments associated with the entry.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      com.google.protobuf.ByteString\n          getCommentBytes();\n\n      /**\n       * <pre>\n       * A reference to the XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference key = 3;</code>\n       */\n      boolean hasKey();\n      /**\n       * <pre>\n       * A reference to the XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference key = 3;</code>\n       */\n      com.android.aapt.Resources.Reference getKey();\n\n      /**\n       * <pre>\n       * The Item defined for this XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      boolean hasItem();\n      /**\n       * <pre>\n       * The Item defined for this XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      com.android.aapt.Resources.Item getItem();\n    }\n    /**\n     * <pre>\n     * An XML attribute/value pair defined in the style.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Style.Entry}\n     */\n    public  static final class Entry extends\n        com.google.protobuf.GeneratedMessageLite<\n            Entry, Entry.Builder> implements\n        // @@protoc_insertion_point(message_implements:aapt.pb.Style.Entry)\n        EntryOrBuilder {\n      private Entry() {\n        comment_ = \"\";\n      }\n      private int bitField0_;\n      public static final int SOURCE_FIELD_NUMBER = 1;\n      private com.android.aapt.Resources.Source source_;\n      /**\n       * <pre>\n       * Where the entry was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public boolean hasSource() {\n        return ((bitField0_ & 0x00000001) == 0x00000001);\n      }\n      /**\n       * <pre>\n       * Where the entry was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public com.android.aapt.Resources.Source getSource() {\n        return source_ == null ? com.android.aapt.Resources.Source.getDefaultInstance() : source_;\n      }\n      /**\n       * <pre>\n       * Where the entry was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void setSource(com.android.aapt.Resources.Source value) {\n        if (value == null) {\n          throw new NullPointerException();\n        }\n        source_ = value;\n        bitField0_ |= 0x00000001;\n        }\n      /**\n       * <pre>\n       * Where the entry was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void setSource(\n          com.android.aapt.Resources.Source.Builder builderForValue) {\n        source_ = builderForValue.build();\n        bitField0_ |= 0x00000001;\n      }\n      /**\n       * <pre>\n       * Where the entry was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void mergeSource(com.android.aapt.Resources.Source value) {\n        if (source_ != null &&\n            source_ != com.android.aapt.Resources.Source.getDefaultInstance()) {\n          source_ =\n            com.android.aapt.Resources.Source.newBuilder(source_).mergeFrom(value).buildPartial();\n        } else {\n          source_ = value;\n        }\n        bitField0_ |= 0x00000001;\n      }\n      /**\n       * <pre>\n       * Where the entry was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void clearSource() {  source_ = null;\n        bitField0_ = (bitField0_ & ~0x00000001);\n      }\n\n      public static final int COMMENT_FIELD_NUMBER = 2;\n      private java.lang.String comment_;\n      /**\n       * <pre>\n       * Any comments associated with the entry.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public boolean hasComment() {\n        return ((bitField0_ & 0x00000002) == 0x00000002);\n      }\n      /**\n       * <pre>\n       * Any comments associated with the entry.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public java.lang.String getComment() {\n        return comment_;\n      }\n      /**\n       * <pre>\n       * Any comments associated with the entry.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public com.google.protobuf.ByteString\n          getCommentBytes() {\n        return com.google.protobuf.ByteString.copyFromUtf8(comment_);\n      }\n      /**\n       * <pre>\n       * Any comments associated with the entry.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void setComment(\n          java.lang.String value) {\n        if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n        comment_ = value;\n      }\n      /**\n       * <pre>\n       * Any comments associated with the entry.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void clearComment() {\n        bitField0_ = (bitField0_ & ~0x00000002);\n        comment_ = getDefaultInstance().getComment();\n      }\n      /**\n       * <pre>\n       * Any comments associated with the entry.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void setCommentBytes(\n          com.google.protobuf.ByteString value) {\n        if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n        comment_ = value.toStringUtf8();\n      }\n\n      public static final int KEY_FIELD_NUMBER = 3;\n      private com.android.aapt.Resources.Reference key_;\n      /**\n       * <pre>\n       * A reference to the XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference key = 3;</code>\n       */\n      public boolean hasKey() {\n        return ((bitField0_ & 0x00000004) == 0x00000004);\n      }\n      /**\n       * <pre>\n       * A reference to the XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference key = 3;</code>\n       */\n      public com.android.aapt.Resources.Reference getKey() {\n        return key_ == null ? com.android.aapt.Resources.Reference.getDefaultInstance() : key_;\n      }\n      /**\n       * <pre>\n       * A reference to the XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference key = 3;</code>\n       */\n      private void setKey(com.android.aapt.Resources.Reference value) {\n        if (value == null) {\n          throw new NullPointerException();\n        }\n        key_ = value;\n        bitField0_ |= 0x00000004;\n        }\n      /**\n       * <pre>\n       * A reference to the XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference key = 3;</code>\n       */\n      private void setKey(\n          com.android.aapt.Resources.Reference.Builder builderForValue) {\n        key_ = builderForValue.build();\n        bitField0_ |= 0x00000004;\n      }\n      /**\n       * <pre>\n       * A reference to the XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference key = 3;</code>\n       */\n      private void mergeKey(com.android.aapt.Resources.Reference value) {\n        if (key_ != null &&\n            key_ != com.android.aapt.Resources.Reference.getDefaultInstance()) {\n          key_ =\n            com.android.aapt.Resources.Reference.newBuilder(key_).mergeFrom(value).buildPartial();\n        } else {\n          key_ = value;\n        }\n        bitField0_ |= 0x00000004;\n      }\n      /**\n       * <pre>\n       * A reference to the XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference key = 3;</code>\n       */\n      private void clearKey() {  key_ = null;\n        bitField0_ = (bitField0_ & ~0x00000004);\n      }\n\n      public static final int ITEM_FIELD_NUMBER = 4;\n      private com.android.aapt.Resources.Item item_;\n      /**\n       * <pre>\n       * The Item defined for this XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      public boolean hasItem() {\n        return ((bitField0_ & 0x00000008) == 0x00000008);\n      }\n      /**\n       * <pre>\n       * The Item defined for this XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      public com.android.aapt.Resources.Item getItem() {\n        return item_ == null ? com.android.aapt.Resources.Item.getDefaultInstance() : item_;\n      }\n      /**\n       * <pre>\n       * The Item defined for this XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      private void setItem(com.android.aapt.Resources.Item value) {\n        if (value == null) {\n          throw new NullPointerException();\n        }\n        item_ = value;\n        bitField0_ |= 0x00000008;\n        }\n      /**\n       * <pre>\n       * The Item defined for this XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      private void setItem(\n          com.android.aapt.Resources.Item.Builder builderForValue) {\n        item_ = builderForValue.build();\n        bitField0_ |= 0x00000008;\n      }\n      /**\n       * <pre>\n       * The Item defined for this XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      private void mergeItem(com.android.aapt.Resources.Item value) {\n        if (item_ != null &&\n            item_ != com.android.aapt.Resources.Item.getDefaultInstance()) {\n          item_ =\n            com.android.aapt.Resources.Item.newBuilder(item_).mergeFrom(value).buildPartial();\n        } else {\n          item_ = value;\n        }\n        bitField0_ |= 0x00000008;\n      }\n      /**\n       * <pre>\n       * The Item defined for this XML attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      private void clearItem() {  item_ = null;\n        bitField0_ = (bitField0_ & ~0x00000008);\n      }\n\n      public void writeTo(com.google.protobuf.CodedOutputStream output)\n                          throws java.io.IOException {\n        if (((bitField0_ & 0x00000001) == 0x00000001)) {\n          output.writeMessage(1, getSource());\n        }\n        if (((bitField0_ & 0x00000002) == 0x00000002)) {\n          output.writeString(2, getComment());\n        }\n        if (((bitField0_ & 0x00000004) == 0x00000004)) {\n          output.writeMessage(3, getKey());\n        }\n        if (((bitField0_ & 0x00000008) == 0x00000008)) {\n          output.writeMessage(4, getItem());\n        }\n        unknownFields.writeTo(output);\n      }\n\n      public int getSerializedSize() {\n        int size = memoizedSerializedSize;\n        if (size != -1) return size;\n\n        size = 0;\n        if (((bitField0_ & 0x00000001) == 0x00000001)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeMessageSize(1, getSource());\n        }\n        if (((bitField0_ & 0x00000002) == 0x00000002)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeStringSize(2, getComment());\n        }\n        if (((bitField0_ & 0x00000004) == 0x00000004)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeMessageSize(3, getKey());\n        }\n        if (((bitField0_ & 0x00000008) == 0x00000008)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeMessageSize(4, getItem());\n        }\n        size += unknownFields.getSerializedSize();\n        memoizedSerializedSize = size;\n        return size;\n      }\n\n      public static com.android.aapt.Resources.Style.Entry parseFrom(\n          com.google.protobuf.ByteString data)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data);\n      }\n      public static com.android.aapt.Resources.Style.Entry parseFrom(\n          com.google.protobuf.ByteString data,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Style.Entry parseFrom(byte[] data)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data);\n      }\n      public static com.android.aapt.Resources.Style.Entry parseFrom(\n          byte[] data,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Style.Entry parseFrom(java.io.InputStream input)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Style.Entry parseFrom(\n          java.io.InputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Style.Entry parseDelimitedFrom(java.io.InputStream input)\n          throws java.io.IOException {\n        return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Style.Entry parseDelimitedFrom(\n          java.io.InputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Style.Entry parseFrom(\n          com.google.protobuf.CodedInputStream input)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Style.Entry parseFrom(\n          com.google.protobuf.CodedInputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n\n      public static Builder newBuilder() {\n        return DEFAULT_INSTANCE.toBuilder();\n      }\n      public static Builder newBuilder(com.android.aapt.Resources.Style.Entry prototype) {\n        return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n      }\n\n      /**\n       * <pre>\n       * An XML attribute/value pair defined in the style.\n       * </pre>\n       *\n       * Protobuf type {@code aapt.pb.Style.Entry}\n       */\n      public static final class Builder extends\n          com.google.protobuf.GeneratedMessageLite.Builder<\n            com.android.aapt.Resources.Style.Entry, Builder> implements\n          // @@protoc_insertion_point(builder_implements:aapt.pb.Style.Entry)\n          com.android.aapt.Resources.Style.EntryOrBuilder {\n        // Construct using com.android.aapt.Resources.Style.Entry.newBuilder()\n        private Builder() {\n          super(DEFAULT_INSTANCE);\n        }\n\n\n        /**\n         * <pre>\n         * Where the entry was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public boolean hasSource() {\n          return instance.hasSource();\n        }\n        /**\n         * <pre>\n         * Where the entry was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public com.android.aapt.Resources.Source getSource() {\n          return instance.getSource();\n        }\n        /**\n         * <pre>\n         * Where the entry was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder setSource(com.android.aapt.Resources.Source value) {\n          copyOnWrite();\n          instance.setSource(value);\n          return this;\n          }\n        /**\n         * <pre>\n         * Where the entry was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder setSource(\n            com.android.aapt.Resources.Source.Builder builderForValue) {\n          copyOnWrite();\n          instance.setSource(builderForValue);\n          return this;\n        }\n        /**\n         * <pre>\n         * Where the entry was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder mergeSource(com.android.aapt.Resources.Source value) {\n          copyOnWrite();\n          instance.mergeSource(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * Where the entry was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder clearSource() {  copyOnWrite();\n          instance.clearSource();\n          return this;\n        }\n\n        /**\n         * <pre>\n         * Any comments associated with the entry.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public boolean hasComment() {\n          return instance.hasComment();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the entry.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public java.lang.String getComment() {\n          return instance.getComment();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the entry.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public com.google.protobuf.ByteString\n            getCommentBytes() {\n          return instance.getCommentBytes();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the entry.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder setComment(\n            java.lang.String value) {\n          copyOnWrite();\n          instance.setComment(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * Any comments associated with the entry.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder clearComment() {\n          copyOnWrite();\n          instance.clearComment();\n          return this;\n        }\n        /**\n         * <pre>\n         * Any comments associated with the entry.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder setCommentBytes(\n            com.google.protobuf.ByteString value) {\n          copyOnWrite();\n          instance.setCommentBytes(value);\n          return this;\n        }\n\n        /**\n         * <pre>\n         * A reference to the XML attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference key = 3;</code>\n         */\n        public boolean hasKey() {\n          return instance.hasKey();\n        }\n        /**\n         * <pre>\n         * A reference to the XML attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference key = 3;</code>\n         */\n        public com.android.aapt.Resources.Reference getKey() {\n          return instance.getKey();\n        }\n        /**\n         * <pre>\n         * A reference to the XML attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference key = 3;</code>\n         */\n        public Builder setKey(com.android.aapt.Resources.Reference value) {\n          copyOnWrite();\n          instance.setKey(value);\n          return this;\n          }\n        /**\n         * <pre>\n         * A reference to the XML attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference key = 3;</code>\n         */\n        public Builder setKey(\n            com.android.aapt.Resources.Reference.Builder builderForValue) {\n          copyOnWrite();\n          instance.setKey(builderForValue);\n          return this;\n        }\n        /**\n         * <pre>\n         * A reference to the XML attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference key = 3;</code>\n         */\n        public Builder mergeKey(com.android.aapt.Resources.Reference value) {\n          copyOnWrite();\n          instance.mergeKey(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * A reference to the XML attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference key = 3;</code>\n         */\n        public Builder clearKey() {  copyOnWrite();\n          instance.clearKey();\n          return this;\n        }\n\n        /**\n         * <pre>\n         * The Item defined for this XML attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 4;</code>\n         */\n        public boolean hasItem() {\n          return instance.hasItem();\n        }\n        /**\n         * <pre>\n         * The Item defined for this XML attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 4;</code>\n         */\n        public com.android.aapt.Resources.Item getItem() {\n          return instance.getItem();\n        }\n        /**\n         * <pre>\n         * The Item defined for this XML attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 4;</code>\n         */\n        public Builder setItem(com.android.aapt.Resources.Item value) {\n          copyOnWrite();\n          instance.setItem(value);\n          return this;\n          }\n        /**\n         * <pre>\n         * The Item defined for this XML attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 4;</code>\n         */\n        public Builder setItem(\n            com.android.aapt.Resources.Item.Builder builderForValue) {\n          copyOnWrite();\n          instance.setItem(builderForValue);\n          return this;\n        }\n        /**\n         * <pre>\n         * The Item defined for this XML attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 4;</code>\n         */\n        public Builder mergeItem(com.android.aapt.Resources.Item value) {\n          copyOnWrite();\n          instance.mergeItem(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * The Item defined for this XML attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 4;</code>\n         */\n        public Builder clearItem() {  copyOnWrite();\n          instance.clearItem();\n          return this;\n        }\n\n        // @@protoc_insertion_point(builder_scope:aapt.pb.Style.Entry)\n      }\n      protected final Object dynamicMethod(\n          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n          Object arg0, Object arg1) {\n        switch (method) {\n          case NEW_MUTABLE_INSTANCE: {\n            return new com.android.aapt.Resources.Style.Entry();\n          }\n          case IS_INITIALIZED: {\n            return DEFAULT_INSTANCE;\n          }\n          case MAKE_IMMUTABLE: {\n            return null;\n          }\n          case NEW_BUILDER: {\n            return new Builder();\n          }\n          case VISIT: {\n            Visitor visitor = (Visitor) arg0;\n            com.android.aapt.Resources.Style.Entry other = (com.android.aapt.Resources.Style.Entry) arg1;\n            source_ = visitor.visitMessage(source_, other.source_);\n            comment_ = visitor.visitString(\n                hasComment(), comment_,\n                other.hasComment(), other.comment_);\n            key_ = visitor.visitMessage(key_, other.key_);\n            item_ = visitor.visitMessage(item_, other.item_);\n            if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n                .INSTANCE) {\n              bitField0_ |= other.bitField0_;\n            }\n            return this;\n          }\n          case MERGE_FROM_STREAM: {\n            com.google.protobuf.CodedInputStream input =\n                (com.google.protobuf.CodedInputStream) arg0;\n            com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n                (com.google.protobuf.ExtensionRegistryLite) arg1;\n            try {\n              boolean done = false;\n              while (!done) {\n                int tag = input.readTag();\n                switch (tag) {\n                  case 0:\n                    done = true;\n                    break;\n                  default: {\n                    if (!parseUnknownField(tag, input)) {\n                      done = true;\n                    }\n                    break;\n                  }\n                  case 10: {\n                    com.android.aapt.Resources.Source.Builder subBuilder = null;\n                    if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                      subBuilder = source_.toBuilder();\n                    }\n                    source_ = input.readMessage(com.android.aapt.Resources.Source.parser(), extensionRegistry);\n                    if (subBuilder != null) {\n                      subBuilder.mergeFrom(source_);\n                      source_ = subBuilder.buildPartial();\n                    }\n                    bitField0_ |= 0x00000001;\n                    break;\n                  }\n                  case 18: {\n                    java.lang.String s = input.readString();\n                    bitField0_ |= 0x00000002;\n                    comment_ = s;\n                    break;\n                  }\n                  case 26: {\n                    com.android.aapt.Resources.Reference.Builder subBuilder = null;\n                    if (((bitField0_ & 0x00000004) == 0x00000004)) {\n                      subBuilder = key_.toBuilder();\n                    }\n                    key_ = input.readMessage(com.android.aapt.Resources.Reference.parser(), extensionRegistry);\n                    if (subBuilder != null) {\n                      subBuilder.mergeFrom(key_);\n                      key_ = subBuilder.buildPartial();\n                    }\n                    bitField0_ |= 0x00000004;\n                    break;\n                  }\n                  case 34: {\n                    com.android.aapt.Resources.Item.Builder subBuilder = null;\n                    if (((bitField0_ & 0x00000008) == 0x00000008)) {\n                      subBuilder = item_.toBuilder();\n                    }\n                    item_ = input.readMessage(com.android.aapt.Resources.Item.parser(), extensionRegistry);\n                    if (subBuilder != null) {\n                      subBuilder.mergeFrom(item_);\n                      item_ = subBuilder.buildPartial();\n                    }\n                    bitField0_ |= 0x00000008;\n                    break;\n                  }\n                }\n              }\n            } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n              throw new RuntimeException(e.setUnfinishedMessage(this));\n            } catch (java.io.IOException e) {\n              throw new RuntimeException(\n                  new com.google.protobuf.InvalidProtocolBufferException(\n                      e.getMessage()).setUnfinishedMessage(this));\n            } finally {\n            }\n          }\n          case GET_DEFAULT_INSTANCE: {\n            return DEFAULT_INSTANCE;\n          }\n          case GET_PARSER: {\n            if (PARSER == null) {    synchronized (com.android.aapt.Resources.Style.Entry.class) {\n                if (PARSER == null) {\n                  PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n                }\n              }\n            }\n            return PARSER;\n          }\n        }\n        throw new UnsupportedOperationException();\n      }\n\n\n      // @@protoc_insertion_point(class_scope:aapt.pb.Style.Entry)\n      private static final com.android.aapt.Resources.Style.Entry DEFAULT_INSTANCE;\n      static {\n        DEFAULT_INSTANCE = new Entry();\n        DEFAULT_INSTANCE.makeImmutable();\n      }\n\n      public static com.android.aapt.Resources.Style.Entry getDefaultInstance() {\n        return DEFAULT_INSTANCE;\n      }\n\n      private static volatile com.google.protobuf.Parser<Entry> PARSER;\n\n      public static com.google.protobuf.Parser<Entry> parser() {\n        return DEFAULT_INSTANCE.getParserForType();\n      }\n    }\n\n    private int bitField0_;\n    public static final int PARENT_FIELD_NUMBER = 1;\n    private com.android.aapt.Resources.Reference parent_;\n    /**\n     * <pre>\n     * The optinal style from which this style inherits attributes.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Reference parent = 1;</code>\n     */\n    public boolean hasParent() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <pre>\n     * The optinal style from which this style inherits attributes.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Reference parent = 1;</code>\n     */\n    public com.android.aapt.Resources.Reference getParent() {\n      return parent_ == null ? com.android.aapt.Resources.Reference.getDefaultInstance() : parent_;\n    }\n    /**\n     * <pre>\n     * The optinal style from which this style inherits attributes.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Reference parent = 1;</code>\n     */\n    private void setParent(com.android.aapt.Resources.Reference value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      parent_ = value;\n      bitField0_ |= 0x00000001;\n      }\n    /**\n     * <pre>\n     * The optinal style from which this style inherits attributes.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Reference parent = 1;</code>\n     */\n    private void setParent(\n        com.android.aapt.Resources.Reference.Builder builderForValue) {\n      parent_ = builderForValue.build();\n      bitField0_ |= 0x00000001;\n    }\n    /**\n     * <pre>\n     * The optinal style from which this style inherits attributes.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Reference parent = 1;</code>\n     */\n    private void mergeParent(com.android.aapt.Resources.Reference value) {\n      if (parent_ != null &&\n          parent_ != com.android.aapt.Resources.Reference.getDefaultInstance()) {\n        parent_ =\n          com.android.aapt.Resources.Reference.newBuilder(parent_).mergeFrom(value).buildPartial();\n      } else {\n        parent_ = value;\n      }\n      bitField0_ |= 0x00000001;\n    }\n    /**\n     * <pre>\n     * The optinal style from which this style inherits attributes.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Reference parent = 1;</code>\n     */\n    private void clearParent() {  parent_ = null;\n      bitField0_ = (bitField0_ & ~0x00000001);\n    }\n\n    public static final int PARENT_SOURCE_FIELD_NUMBER = 2;\n    private com.android.aapt.Resources.Source parentSource_;\n    /**\n     * <pre>\n     * The source file information of the parent inheritance declaration.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source parent_source = 2;</code>\n     */\n    public boolean hasParentSource() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <pre>\n     * The source file information of the parent inheritance declaration.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source parent_source = 2;</code>\n     */\n    public com.android.aapt.Resources.Source getParentSource() {\n      return parentSource_ == null ? com.android.aapt.Resources.Source.getDefaultInstance() : parentSource_;\n    }\n    /**\n     * <pre>\n     * The source file information of the parent inheritance declaration.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source parent_source = 2;</code>\n     */\n    private void setParentSource(com.android.aapt.Resources.Source value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      parentSource_ = value;\n      bitField0_ |= 0x00000002;\n      }\n    /**\n     * <pre>\n     * The source file information of the parent inheritance declaration.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source parent_source = 2;</code>\n     */\n    private void setParentSource(\n        com.android.aapt.Resources.Source.Builder builderForValue) {\n      parentSource_ = builderForValue.build();\n      bitField0_ |= 0x00000002;\n    }\n    /**\n     * <pre>\n     * The source file information of the parent inheritance declaration.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source parent_source = 2;</code>\n     */\n    private void mergeParentSource(com.android.aapt.Resources.Source value) {\n      if (parentSource_ != null &&\n          parentSource_ != com.android.aapt.Resources.Source.getDefaultInstance()) {\n        parentSource_ =\n          com.android.aapt.Resources.Source.newBuilder(parentSource_).mergeFrom(value).buildPartial();\n      } else {\n        parentSource_ = value;\n      }\n      bitField0_ |= 0x00000002;\n    }\n    /**\n     * <pre>\n     * The source file information of the parent inheritance declaration.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Source parent_source = 2;</code>\n     */\n    private void clearParentSource() {  parentSource_ = null;\n      bitField0_ = (bitField0_ & ~0x00000002);\n    }\n\n    public static final int ENTRY_FIELD_NUMBER = 3;\n    private com.google.protobuf.Internal.ProtobufList<com.android.aapt.Resources.Style.Entry> entry_;\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    public java.util.List<com.android.aapt.Resources.Style.Entry> getEntryList() {\n      return entry_;\n    }\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    public java.util.List<? extends com.android.aapt.Resources.Style.EntryOrBuilder> \n        getEntryOrBuilderList() {\n      return entry_;\n    }\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    public int getEntryCount() {\n      return entry_.size();\n    }\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    public com.android.aapt.Resources.Style.Entry getEntry(int index) {\n      return entry_.get(index);\n    }\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    public com.android.aapt.Resources.Style.EntryOrBuilder getEntryOrBuilder(\n        int index) {\n      return entry_.get(index);\n    }\n    private void ensureEntryIsMutable() {\n      if (!entry_.isModifiable()) {\n        entry_ =\n            com.google.protobuf.GeneratedMessageLite.mutableCopy(entry_);\n       }\n    }\n\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    private void setEntry(\n        int index, com.android.aapt.Resources.Style.Entry value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureEntryIsMutable();\n      entry_.set(index, value);\n    }\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    private void setEntry(\n        int index, com.android.aapt.Resources.Style.Entry.Builder builderForValue) {\n      ensureEntryIsMutable();\n      entry_.set(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    private void addEntry(com.android.aapt.Resources.Style.Entry value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureEntryIsMutable();\n      entry_.add(value);\n    }\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    private void addEntry(\n        int index, com.android.aapt.Resources.Style.Entry value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureEntryIsMutable();\n      entry_.add(index, value);\n    }\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    private void addEntry(\n        com.android.aapt.Resources.Style.Entry.Builder builderForValue) {\n      ensureEntryIsMutable();\n      entry_.add(builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    private void addEntry(\n        int index, com.android.aapt.Resources.Style.Entry.Builder builderForValue) {\n      ensureEntryIsMutable();\n      entry_.add(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    private void addAllEntry(\n        java.lang.Iterable<? extends com.android.aapt.Resources.Style.Entry> values) {\n      ensureEntryIsMutable();\n      com.google.protobuf.AbstractMessageLite.addAll(\n          values, entry_);\n    }\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    private void clearEntry() {\n      entry_ = emptyProtobufList();\n    }\n    /**\n     * <pre>\n     * The set of XML attribute/value pairs for this style.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n     */\n    private void removeEntry(int index) {\n      ensureEntryIsMutable();\n      entry_.remove(index);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeMessage(1, getParent());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeMessage(2, getParentSource());\n      }\n      for (int i = 0; i < entry_.size(); i++) {\n        output.writeMessage(3, entry_.get(i));\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(1, getParent());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(2, getParentSource());\n      }\n      for (int i = 0; i < entry_.size(); i++) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(3, entry_.get(i));\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.Style parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Style parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Style parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Style parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Style parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Style parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Style parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Style parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Style parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Style parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.Style prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A value that represents a style.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Style}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.Style, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.Style)\n        com.android.aapt.Resources.StyleOrBuilder {\n      // Construct using com.android.aapt.Resources.Style.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * The optinal style from which this style inherits attributes.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference parent = 1;</code>\n       */\n      public boolean hasParent() {\n        return instance.hasParent();\n      }\n      /**\n       * <pre>\n       * The optinal style from which this style inherits attributes.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference parent = 1;</code>\n       */\n      public com.android.aapt.Resources.Reference getParent() {\n        return instance.getParent();\n      }\n      /**\n       * <pre>\n       * The optinal style from which this style inherits attributes.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference parent = 1;</code>\n       */\n      public Builder setParent(com.android.aapt.Resources.Reference value) {\n        copyOnWrite();\n        instance.setParent(value);\n        return this;\n        }\n      /**\n       * <pre>\n       * The optinal style from which this style inherits attributes.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference parent = 1;</code>\n       */\n      public Builder setParent(\n          com.android.aapt.Resources.Reference.Builder builderForValue) {\n        copyOnWrite();\n        instance.setParent(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The optinal style from which this style inherits attributes.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference parent = 1;</code>\n       */\n      public Builder mergeParent(com.android.aapt.Resources.Reference value) {\n        copyOnWrite();\n        instance.mergeParent(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The optinal style from which this style inherits attributes.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference parent = 1;</code>\n       */\n      public Builder clearParent() {  copyOnWrite();\n        instance.clearParent();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The source file information of the parent inheritance declaration.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source parent_source = 2;</code>\n       */\n      public boolean hasParentSource() {\n        return instance.hasParentSource();\n      }\n      /**\n       * <pre>\n       * The source file information of the parent inheritance declaration.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source parent_source = 2;</code>\n       */\n      public com.android.aapt.Resources.Source getParentSource() {\n        return instance.getParentSource();\n      }\n      /**\n       * <pre>\n       * The source file information of the parent inheritance declaration.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source parent_source = 2;</code>\n       */\n      public Builder setParentSource(com.android.aapt.Resources.Source value) {\n        copyOnWrite();\n        instance.setParentSource(value);\n        return this;\n        }\n      /**\n       * <pre>\n       * The source file information of the parent inheritance declaration.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source parent_source = 2;</code>\n       */\n      public Builder setParentSource(\n          com.android.aapt.Resources.Source.Builder builderForValue) {\n        copyOnWrite();\n        instance.setParentSource(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The source file information of the parent inheritance declaration.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source parent_source = 2;</code>\n       */\n      public Builder mergeParentSource(com.android.aapt.Resources.Source value) {\n        copyOnWrite();\n        instance.mergeParentSource(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The source file information of the parent inheritance declaration.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source parent_source = 2;</code>\n       */\n      public Builder clearParentSource() {  copyOnWrite();\n        instance.clearParentSource();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The set of XML attribute/value pairs for this style.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n       */\n      public java.util.List<com.android.aapt.Resources.Style.Entry> getEntryList() {\n        return java.util.Collections.unmodifiableList(\n            instance.getEntryList());\n      }\n      /**\n       * <pre>\n       * The set of XML attribute/value pairs for this style.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n       */\n      public int getEntryCount() {\n        return instance.getEntryCount();\n      }/**\n       * <pre>\n       * The set of XML attribute/value pairs for this style.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n       */\n      public com.android.aapt.Resources.Style.Entry getEntry(int index) {\n        return instance.getEntry(index);\n      }\n      /**\n       * <pre>\n       * The set of XML attribute/value pairs for this style.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n       */\n      public Builder setEntry(\n          int index, com.android.aapt.Resources.Style.Entry value) {\n        copyOnWrite();\n        instance.setEntry(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of XML attribute/value pairs for this style.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n       */\n      public Builder setEntry(\n          int index, com.android.aapt.Resources.Style.Entry.Builder builderForValue) {\n        copyOnWrite();\n        instance.setEntry(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of XML attribute/value pairs for this style.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n       */\n      public Builder addEntry(com.android.aapt.Resources.Style.Entry value) {\n        copyOnWrite();\n        instance.addEntry(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of XML attribute/value pairs for this style.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n       */\n      public Builder addEntry(\n          int index, com.android.aapt.Resources.Style.Entry value) {\n        copyOnWrite();\n        instance.addEntry(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of XML attribute/value pairs for this style.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n       */\n      public Builder addEntry(\n          com.android.aapt.Resources.Style.Entry.Builder builderForValue) {\n        copyOnWrite();\n        instance.addEntry(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of XML attribute/value pairs for this style.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n       */\n      public Builder addEntry(\n          int index, com.android.aapt.Resources.Style.Entry.Builder builderForValue) {\n        copyOnWrite();\n        instance.addEntry(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of XML attribute/value pairs for this style.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n       */\n      public Builder addAllEntry(\n          java.lang.Iterable<? extends com.android.aapt.Resources.Style.Entry> values) {\n        copyOnWrite();\n        instance.addAllEntry(values);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of XML attribute/value pairs for this style.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n       */\n      public Builder clearEntry() {\n        copyOnWrite();\n        instance.clearEntry();\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of XML attribute/value pairs for this style.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Style.Entry entry = 3;</code>\n       */\n      public Builder removeEntry(int index) {\n        copyOnWrite();\n        instance.removeEntry(index);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.Style)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.Style();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          entry_.makeImmutable();\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.Style other = (com.android.aapt.Resources.Style) arg1;\n          parent_ = visitor.visitMessage(parent_, other.parent_);\n          parentSource_ = visitor.visitMessage(parentSource_, other.parentSource_);\n          entry_= visitor.visitList(entry_, other.entry_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  com.android.aapt.Resources.Reference.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                    subBuilder = parent_.toBuilder();\n                  }\n                  parent_ = input.readMessage(com.android.aapt.Resources.Reference.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(parent_);\n                    parent_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000001;\n                  break;\n                }\n                case 18: {\n                  com.android.aapt.Resources.Source.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000002) == 0x00000002)) {\n                    subBuilder = parentSource_.toBuilder();\n                  }\n                  parentSource_ = input.readMessage(com.android.aapt.Resources.Source.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(parentSource_);\n                    parentSource_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000002;\n                  break;\n                }\n                case 26: {\n                  if (!entry_.isModifiable()) {\n                    entry_ =\n                        com.google.protobuf.GeneratedMessageLite.mutableCopy(entry_);\n                  }\n                  entry_.add(\n                      input.readMessage(com.android.aapt.Resources.Style.Entry.parser(), extensionRegistry));\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.Style.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.Style)\n    private static final com.android.aapt.Resources.Style DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new Style();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.Style getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<Style> PARSER;\n\n    public static com.google.protobuf.Parser<Style> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface StyleableOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.Styleable)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    java.util.List<com.android.aapt.Resources.Styleable.Entry> \n        getEntryList();\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    com.android.aapt.Resources.Styleable.Entry getEntry(int index);\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    int getEntryCount();\n  }\n  /**\n   * <pre>\n   * A value that represents a &lt;declare-styleable&gt; XML resource. These are not real resources and\n   * only end up as Java fields in the generated R.java. They do not end up in the binary ARSC file.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.Styleable}\n   */\n  public  static final class Styleable extends\n      com.google.protobuf.GeneratedMessageLite<\n          Styleable, Styleable.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.Styleable)\n      StyleableOrBuilder {\n    private Styleable() {\n      entry_ = emptyProtobufList();\n    }\n    public interface EntryOrBuilder extends\n        // @@protoc_insertion_point(interface_extends:aapt.pb.Styleable.Entry)\n        com.google.protobuf.MessageLiteOrBuilder {\n\n      /**\n       * <pre>\n       * Where the attribute was defined within the &lt;declare-styleable&gt; block.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      boolean hasSource();\n      /**\n       * <pre>\n       * Where the attribute was defined within the &lt;declare-styleable&gt; block.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      com.android.aapt.Resources.Source getSource();\n\n      /**\n       * <pre>\n       * Any comments associated with the declaration.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      boolean hasComment();\n      /**\n       * <pre>\n       * Any comments associated with the declaration.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      java.lang.String getComment();\n      /**\n       * <pre>\n       * Any comments associated with the declaration.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      com.google.protobuf.ByteString\n          getCommentBytes();\n\n      /**\n       * <pre>\n       * The reference to the attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference attr = 3;</code>\n       */\n      boolean hasAttr();\n      /**\n       * <pre>\n       * The reference to the attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference attr = 3;</code>\n       */\n      com.android.aapt.Resources.Reference getAttr();\n    }\n    /**\n     * <pre>\n     * An attribute defined for this styleable.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Styleable.Entry}\n     */\n    public  static final class Entry extends\n        com.google.protobuf.GeneratedMessageLite<\n            Entry, Entry.Builder> implements\n        // @@protoc_insertion_point(message_implements:aapt.pb.Styleable.Entry)\n        EntryOrBuilder {\n      private Entry() {\n        comment_ = \"\";\n      }\n      private int bitField0_;\n      public static final int SOURCE_FIELD_NUMBER = 1;\n      private com.android.aapt.Resources.Source source_;\n      /**\n       * <pre>\n       * Where the attribute was defined within the &lt;declare-styleable&gt; block.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public boolean hasSource() {\n        return ((bitField0_ & 0x00000001) == 0x00000001);\n      }\n      /**\n       * <pre>\n       * Where the attribute was defined within the &lt;declare-styleable&gt; block.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public com.android.aapt.Resources.Source getSource() {\n        return source_ == null ? com.android.aapt.Resources.Source.getDefaultInstance() : source_;\n      }\n      /**\n       * <pre>\n       * Where the attribute was defined within the &lt;declare-styleable&gt; block.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void setSource(com.android.aapt.Resources.Source value) {\n        if (value == null) {\n          throw new NullPointerException();\n        }\n        source_ = value;\n        bitField0_ |= 0x00000001;\n        }\n      /**\n       * <pre>\n       * Where the attribute was defined within the &lt;declare-styleable&gt; block.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void setSource(\n          com.android.aapt.Resources.Source.Builder builderForValue) {\n        source_ = builderForValue.build();\n        bitField0_ |= 0x00000001;\n      }\n      /**\n       * <pre>\n       * Where the attribute was defined within the &lt;declare-styleable&gt; block.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void mergeSource(com.android.aapt.Resources.Source value) {\n        if (source_ != null &&\n            source_ != com.android.aapt.Resources.Source.getDefaultInstance()) {\n          source_ =\n            com.android.aapt.Resources.Source.newBuilder(source_).mergeFrom(value).buildPartial();\n        } else {\n          source_ = value;\n        }\n        bitField0_ |= 0x00000001;\n      }\n      /**\n       * <pre>\n       * Where the attribute was defined within the &lt;declare-styleable&gt; block.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void clearSource() {  source_ = null;\n        bitField0_ = (bitField0_ & ~0x00000001);\n      }\n\n      public static final int COMMENT_FIELD_NUMBER = 2;\n      private java.lang.String comment_;\n      /**\n       * <pre>\n       * Any comments associated with the declaration.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public boolean hasComment() {\n        return ((bitField0_ & 0x00000002) == 0x00000002);\n      }\n      /**\n       * <pre>\n       * Any comments associated with the declaration.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public java.lang.String getComment() {\n        return comment_;\n      }\n      /**\n       * <pre>\n       * Any comments associated with the declaration.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public com.google.protobuf.ByteString\n          getCommentBytes() {\n        return com.google.protobuf.ByteString.copyFromUtf8(comment_);\n      }\n      /**\n       * <pre>\n       * Any comments associated with the declaration.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void setComment(\n          java.lang.String value) {\n        if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n        comment_ = value;\n      }\n      /**\n       * <pre>\n       * Any comments associated with the declaration.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void clearComment() {\n        bitField0_ = (bitField0_ & ~0x00000002);\n        comment_ = getDefaultInstance().getComment();\n      }\n      /**\n       * <pre>\n       * Any comments associated with the declaration.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void setCommentBytes(\n          com.google.protobuf.ByteString value) {\n        if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n        comment_ = value.toStringUtf8();\n      }\n\n      public static final int ATTR_FIELD_NUMBER = 3;\n      private com.android.aapt.Resources.Reference attr_;\n      /**\n       * <pre>\n       * The reference to the attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference attr = 3;</code>\n       */\n      public boolean hasAttr() {\n        return ((bitField0_ & 0x00000004) == 0x00000004);\n      }\n      /**\n       * <pre>\n       * The reference to the attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference attr = 3;</code>\n       */\n      public com.android.aapt.Resources.Reference getAttr() {\n        return attr_ == null ? com.android.aapt.Resources.Reference.getDefaultInstance() : attr_;\n      }\n      /**\n       * <pre>\n       * The reference to the attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference attr = 3;</code>\n       */\n      private void setAttr(com.android.aapt.Resources.Reference value) {\n        if (value == null) {\n          throw new NullPointerException();\n        }\n        attr_ = value;\n        bitField0_ |= 0x00000004;\n        }\n      /**\n       * <pre>\n       * The reference to the attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference attr = 3;</code>\n       */\n      private void setAttr(\n          com.android.aapt.Resources.Reference.Builder builderForValue) {\n        attr_ = builderForValue.build();\n        bitField0_ |= 0x00000004;\n      }\n      /**\n       * <pre>\n       * The reference to the attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference attr = 3;</code>\n       */\n      private void mergeAttr(com.android.aapt.Resources.Reference value) {\n        if (attr_ != null &&\n            attr_ != com.android.aapt.Resources.Reference.getDefaultInstance()) {\n          attr_ =\n            com.android.aapt.Resources.Reference.newBuilder(attr_).mergeFrom(value).buildPartial();\n        } else {\n          attr_ = value;\n        }\n        bitField0_ |= 0x00000004;\n      }\n      /**\n       * <pre>\n       * The reference to the attribute.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Reference attr = 3;</code>\n       */\n      private void clearAttr() {  attr_ = null;\n        bitField0_ = (bitField0_ & ~0x00000004);\n      }\n\n      public void writeTo(com.google.protobuf.CodedOutputStream output)\n                          throws java.io.IOException {\n        if (((bitField0_ & 0x00000001) == 0x00000001)) {\n          output.writeMessage(1, getSource());\n        }\n        if (((bitField0_ & 0x00000002) == 0x00000002)) {\n          output.writeString(2, getComment());\n        }\n        if (((bitField0_ & 0x00000004) == 0x00000004)) {\n          output.writeMessage(3, getAttr());\n        }\n        unknownFields.writeTo(output);\n      }\n\n      public int getSerializedSize() {\n        int size = memoizedSerializedSize;\n        if (size != -1) return size;\n\n        size = 0;\n        if (((bitField0_ & 0x00000001) == 0x00000001)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeMessageSize(1, getSource());\n        }\n        if (((bitField0_ & 0x00000002) == 0x00000002)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeStringSize(2, getComment());\n        }\n        if (((bitField0_ & 0x00000004) == 0x00000004)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeMessageSize(3, getAttr());\n        }\n        size += unknownFields.getSerializedSize();\n        memoizedSerializedSize = size;\n        return size;\n      }\n\n      public static com.android.aapt.Resources.Styleable.Entry parseFrom(\n          com.google.protobuf.ByteString data)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data);\n      }\n      public static com.android.aapt.Resources.Styleable.Entry parseFrom(\n          com.google.protobuf.ByteString data,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Styleable.Entry parseFrom(byte[] data)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data);\n      }\n      public static com.android.aapt.Resources.Styleable.Entry parseFrom(\n          byte[] data,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Styleable.Entry parseFrom(java.io.InputStream input)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Styleable.Entry parseFrom(\n          java.io.InputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Styleable.Entry parseDelimitedFrom(java.io.InputStream input)\n          throws java.io.IOException {\n        return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Styleable.Entry parseDelimitedFrom(\n          java.io.InputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Styleable.Entry parseFrom(\n          com.google.protobuf.CodedInputStream input)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Styleable.Entry parseFrom(\n          com.google.protobuf.CodedInputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n\n      public static Builder newBuilder() {\n        return DEFAULT_INSTANCE.toBuilder();\n      }\n      public static Builder newBuilder(com.android.aapt.Resources.Styleable.Entry prototype) {\n        return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n      }\n\n      /**\n       * <pre>\n       * An attribute defined for this styleable.\n       * </pre>\n       *\n       * Protobuf type {@code aapt.pb.Styleable.Entry}\n       */\n      public static final class Builder extends\n          com.google.protobuf.GeneratedMessageLite.Builder<\n            com.android.aapt.Resources.Styleable.Entry, Builder> implements\n          // @@protoc_insertion_point(builder_implements:aapt.pb.Styleable.Entry)\n          com.android.aapt.Resources.Styleable.EntryOrBuilder {\n        // Construct using com.android.aapt.Resources.Styleable.Entry.newBuilder()\n        private Builder() {\n          super(DEFAULT_INSTANCE);\n        }\n\n\n        /**\n         * <pre>\n         * Where the attribute was defined within the &lt;declare-styleable&gt; block.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public boolean hasSource() {\n          return instance.hasSource();\n        }\n        /**\n         * <pre>\n         * Where the attribute was defined within the &lt;declare-styleable&gt; block.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public com.android.aapt.Resources.Source getSource() {\n          return instance.getSource();\n        }\n        /**\n         * <pre>\n         * Where the attribute was defined within the &lt;declare-styleable&gt; block.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder setSource(com.android.aapt.Resources.Source value) {\n          copyOnWrite();\n          instance.setSource(value);\n          return this;\n          }\n        /**\n         * <pre>\n         * Where the attribute was defined within the &lt;declare-styleable&gt; block.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder setSource(\n            com.android.aapt.Resources.Source.Builder builderForValue) {\n          copyOnWrite();\n          instance.setSource(builderForValue);\n          return this;\n        }\n        /**\n         * <pre>\n         * Where the attribute was defined within the &lt;declare-styleable&gt; block.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder mergeSource(com.android.aapt.Resources.Source value) {\n          copyOnWrite();\n          instance.mergeSource(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * Where the attribute was defined within the &lt;declare-styleable&gt; block.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder clearSource() {  copyOnWrite();\n          instance.clearSource();\n          return this;\n        }\n\n        /**\n         * <pre>\n         * Any comments associated with the declaration.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public boolean hasComment() {\n          return instance.hasComment();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the declaration.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public java.lang.String getComment() {\n          return instance.getComment();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the declaration.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public com.google.protobuf.ByteString\n            getCommentBytes() {\n          return instance.getCommentBytes();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the declaration.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder setComment(\n            java.lang.String value) {\n          copyOnWrite();\n          instance.setComment(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * Any comments associated with the declaration.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder clearComment() {\n          copyOnWrite();\n          instance.clearComment();\n          return this;\n        }\n        /**\n         * <pre>\n         * Any comments associated with the declaration.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder setCommentBytes(\n            com.google.protobuf.ByteString value) {\n          copyOnWrite();\n          instance.setCommentBytes(value);\n          return this;\n        }\n\n        /**\n         * <pre>\n         * The reference to the attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference attr = 3;</code>\n         */\n        public boolean hasAttr() {\n          return instance.hasAttr();\n        }\n        /**\n         * <pre>\n         * The reference to the attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference attr = 3;</code>\n         */\n        public com.android.aapt.Resources.Reference getAttr() {\n          return instance.getAttr();\n        }\n        /**\n         * <pre>\n         * The reference to the attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference attr = 3;</code>\n         */\n        public Builder setAttr(com.android.aapt.Resources.Reference value) {\n          copyOnWrite();\n          instance.setAttr(value);\n          return this;\n          }\n        /**\n         * <pre>\n         * The reference to the attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference attr = 3;</code>\n         */\n        public Builder setAttr(\n            com.android.aapt.Resources.Reference.Builder builderForValue) {\n          copyOnWrite();\n          instance.setAttr(builderForValue);\n          return this;\n        }\n        /**\n         * <pre>\n         * The reference to the attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference attr = 3;</code>\n         */\n        public Builder mergeAttr(com.android.aapt.Resources.Reference value) {\n          copyOnWrite();\n          instance.mergeAttr(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * The reference to the attribute.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Reference attr = 3;</code>\n         */\n        public Builder clearAttr() {  copyOnWrite();\n          instance.clearAttr();\n          return this;\n        }\n\n        // @@protoc_insertion_point(builder_scope:aapt.pb.Styleable.Entry)\n      }\n      protected final Object dynamicMethod(\n          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n          Object arg0, Object arg1) {\n        switch (method) {\n          case NEW_MUTABLE_INSTANCE: {\n            return new com.android.aapt.Resources.Styleable.Entry();\n          }\n          case IS_INITIALIZED: {\n            return DEFAULT_INSTANCE;\n          }\n          case MAKE_IMMUTABLE: {\n            return null;\n          }\n          case NEW_BUILDER: {\n            return new Builder();\n          }\n          case VISIT: {\n            Visitor visitor = (Visitor) arg0;\n            com.android.aapt.Resources.Styleable.Entry other = (com.android.aapt.Resources.Styleable.Entry) arg1;\n            source_ = visitor.visitMessage(source_, other.source_);\n            comment_ = visitor.visitString(\n                hasComment(), comment_,\n                other.hasComment(), other.comment_);\n            attr_ = visitor.visitMessage(attr_, other.attr_);\n            if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n                .INSTANCE) {\n              bitField0_ |= other.bitField0_;\n            }\n            return this;\n          }\n          case MERGE_FROM_STREAM: {\n            com.google.protobuf.CodedInputStream input =\n                (com.google.protobuf.CodedInputStream) arg0;\n            com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n                (com.google.protobuf.ExtensionRegistryLite) arg1;\n            try {\n              boolean done = false;\n              while (!done) {\n                int tag = input.readTag();\n                switch (tag) {\n                  case 0:\n                    done = true;\n                    break;\n                  default: {\n                    if (!parseUnknownField(tag, input)) {\n                      done = true;\n                    }\n                    break;\n                  }\n                  case 10: {\n                    com.android.aapt.Resources.Source.Builder subBuilder = null;\n                    if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                      subBuilder = source_.toBuilder();\n                    }\n                    source_ = input.readMessage(com.android.aapt.Resources.Source.parser(), extensionRegistry);\n                    if (subBuilder != null) {\n                      subBuilder.mergeFrom(source_);\n                      source_ = subBuilder.buildPartial();\n                    }\n                    bitField0_ |= 0x00000001;\n                    break;\n                  }\n                  case 18: {\n                    java.lang.String s = input.readString();\n                    bitField0_ |= 0x00000002;\n                    comment_ = s;\n                    break;\n                  }\n                  case 26: {\n                    com.android.aapt.Resources.Reference.Builder subBuilder = null;\n                    if (((bitField0_ & 0x00000004) == 0x00000004)) {\n                      subBuilder = attr_.toBuilder();\n                    }\n                    attr_ = input.readMessage(com.android.aapt.Resources.Reference.parser(), extensionRegistry);\n                    if (subBuilder != null) {\n                      subBuilder.mergeFrom(attr_);\n                      attr_ = subBuilder.buildPartial();\n                    }\n                    bitField0_ |= 0x00000004;\n                    break;\n                  }\n                }\n              }\n            } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n              throw new RuntimeException(e.setUnfinishedMessage(this));\n            } catch (java.io.IOException e) {\n              throw new RuntimeException(\n                  new com.google.protobuf.InvalidProtocolBufferException(\n                      e.getMessage()).setUnfinishedMessage(this));\n            } finally {\n            }\n          }\n          case GET_DEFAULT_INSTANCE: {\n            return DEFAULT_INSTANCE;\n          }\n          case GET_PARSER: {\n            if (PARSER == null) {    synchronized (com.android.aapt.Resources.Styleable.Entry.class) {\n                if (PARSER == null) {\n                  PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n                }\n              }\n            }\n            return PARSER;\n          }\n        }\n        throw new UnsupportedOperationException();\n      }\n\n\n      // @@protoc_insertion_point(class_scope:aapt.pb.Styleable.Entry)\n      private static final com.android.aapt.Resources.Styleable.Entry DEFAULT_INSTANCE;\n      static {\n        DEFAULT_INSTANCE = new Entry();\n        DEFAULT_INSTANCE.makeImmutable();\n      }\n\n      public static com.android.aapt.Resources.Styleable.Entry getDefaultInstance() {\n        return DEFAULT_INSTANCE;\n      }\n\n      private static volatile com.google.protobuf.Parser<Entry> PARSER;\n\n      public static com.google.protobuf.Parser<Entry> parser() {\n        return DEFAULT_INSTANCE.getParserForType();\n      }\n    }\n\n    public static final int ENTRY_FIELD_NUMBER = 1;\n    private com.google.protobuf.Internal.ProtobufList<com.android.aapt.Resources.Styleable.Entry> entry_;\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    public java.util.List<com.android.aapt.Resources.Styleable.Entry> getEntryList() {\n      return entry_;\n    }\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    public java.util.List<? extends com.android.aapt.Resources.Styleable.EntryOrBuilder> \n        getEntryOrBuilderList() {\n      return entry_;\n    }\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    public int getEntryCount() {\n      return entry_.size();\n    }\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    public com.android.aapt.Resources.Styleable.Entry getEntry(int index) {\n      return entry_.get(index);\n    }\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    public com.android.aapt.Resources.Styleable.EntryOrBuilder getEntryOrBuilder(\n        int index) {\n      return entry_.get(index);\n    }\n    private void ensureEntryIsMutable() {\n      if (!entry_.isModifiable()) {\n        entry_ =\n            com.google.protobuf.GeneratedMessageLite.mutableCopy(entry_);\n       }\n    }\n\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    private void setEntry(\n        int index, com.android.aapt.Resources.Styleable.Entry value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureEntryIsMutable();\n      entry_.set(index, value);\n    }\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    private void setEntry(\n        int index, com.android.aapt.Resources.Styleable.Entry.Builder builderForValue) {\n      ensureEntryIsMutable();\n      entry_.set(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    private void addEntry(com.android.aapt.Resources.Styleable.Entry value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureEntryIsMutable();\n      entry_.add(value);\n    }\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    private void addEntry(\n        int index, com.android.aapt.Resources.Styleable.Entry value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureEntryIsMutable();\n      entry_.add(index, value);\n    }\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    private void addEntry(\n        com.android.aapt.Resources.Styleable.Entry.Builder builderForValue) {\n      ensureEntryIsMutable();\n      entry_.add(builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    private void addEntry(\n        int index, com.android.aapt.Resources.Styleable.Entry.Builder builderForValue) {\n      ensureEntryIsMutable();\n      entry_.add(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    private void addAllEntry(\n        java.lang.Iterable<? extends com.android.aapt.Resources.Styleable.Entry> values) {\n      ensureEntryIsMutable();\n      com.google.protobuf.AbstractMessageLite.addAll(\n          values, entry_);\n    }\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    private void clearEntry() {\n      entry_ = emptyProtobufList();\n    }\n    /**\n     * <pre>\n     * The set of attribute declarations.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n     */\n    private void removeEntry(int index) {\n      ensureEntryIsMutable();\n      entry_.remove(index);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      for (int i = 0; i < entry_.size(); i++) {\n        output.writeMessage(1, entry_.get(i));\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      for (int i = 0; i < entry_.size(); i++) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(1, entry_.get(i));\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.Styleable parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Styleable parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Styleable parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Styleable parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Styleable parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Styleable parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Styleable parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Styleable parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Styleable parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Styleable parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.Styleable prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A value that represents a &lt;declare-styleable&gt; XML resource. These are not real resources and\n     * only end up as Java fields in the generated R.java. They do not end up in the binary ARSC file.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Styleable}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.Styleable, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.Styleable)\n        com.android.aapt.Resources.StyleableOrBuilder {\n      // Construct using com.android.aapt.Resources.Styleable.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * The set of attribute declarations.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n       */\n      public java.util.List<com.android.aapt.Resources.Styleable.Entry> getEntryList() {\n        return java.util.Collections.unmodifiableList(\n            instance.getEntryList());\n      }\n      /**\n       * <pre>\n       * The set of attribute declarations.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n       */\n      public int getEntryCount() {\n        return instance.getEntryCount();\n      }/**\n       * <pre>\n       * The set of attribute declarations.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n       */\n      public com.android.aapt.Resources.Styleable.Entry getEntry(int index) {\n        return instance.getEntry(index);\n      }\n      /**\n       * <pre>\n       * The set of attribute declarations.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n       */\n      public Builder setEntry(\n          int index, com.android.aapt.Resources.Styleable.Entry value) {\n        copyOnWrite();\n        instance.setEntry(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of attribute declarations.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n       */\n      public Builder setEntry(\n          int index, com.android.aapt.Resources.Styleable.Entry.Builder builderForValue) {\n        copyOnWrite();\n        instance.setEntry(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of attribute declarations.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n       */\n      public Builder addEntry(com.android.aapt.Resources.Styleable.Entry value) {\n        copyOnWrite();\n        instance.addEntry(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of attribute declarations.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n       */\n      public Builder addEntry(\n          int index, com.android.aapt.Resources.Styleable.Entry value) {\n        copyOnWrite();\n        instance.addEntry(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of attribute declarations.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n       */\n      public Builder addEntry(\n          com.android.aapt.Resources.Styleable.Entry.Builder builderForValue) {\n        copyOnWrite();\n        instance.addEntry(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of attribute declarations.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n       */\n      public Builder addEntry(\n          int index, com.android.aapt.Resources.Styleable.Entry.Builder builderForValue) {\n        copyOnWrite();\n        instance.addEntry(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of attribute declarations.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n       */\n      public Builder addAllEntry(\n          java.lang.Iterable<? extends com.android.aapt.Resources.Styleable.Entry> values) {\n        copyOnWrite();\n        instance.addAllEntry(values);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of attribute declarations.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n       */\n      public Builder clearEntry() {\n        copyOnWrite();\n        instance.clearEntry();\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of attribute declarations.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Styleable.Entry entry = 1;</code>\n       */\n      public Builder removeEntry(int index) {\n        copyOnWrite();\n        instance.removeEntry(index);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.Styleable)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.Styleable();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          entry_.makeImmutable();\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.Styleable other = (com.android.aapt.Resources.Styleable) arg1;\n          entry_= visitor.visitList(entry_, other.entry_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  if (!entry_.isModifiable()) {\n                    entry_ =\n                        com.google.protobuf.GeneratedMessageLite.mutableCopy(entry_);\n                  }\n                  entry_.add(\n                      input.readMessage(com.android.aapt.Resources.Styleable.Entry.parser(), extensionRegistry));\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.Styleable.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.Styleable)\n    private static final com.android.aapt.Resources.Styleable DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new Styleable();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.Styleable getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<Styleable> PARSER;\n\n    public static com.google.protobuf.Parser<Styleable> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface ArrayOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.Array)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    java.util.List<com.android.aapt.Resources.Array.Element> \n        getElementList();\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    com.android.aapt.Resources.Array.Element getElement(int index);\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    int getElementCount();\n  }\n  /**\n   * <pre>\n   * A value that represents an array of resource values.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.Array}\n   */\n  public  static final class Array extends\n      com.google.protobuf.GeneratedMessageLite<\n          Array, Array.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.Array)\n      ArrayOrBuilder {\n    private Array() {\n      element_ = emptyProtobufList();\n    }\n    public interface ElementOrBuilder extends\n        // @@protoc_insertion_point(interface_extends:aapt.pb.Array.Element)\n        com.google.protobuf.MessageLiteOrBuilder {\n\n      /**\n       * <pre>\n       * Where the element was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      boolean hasSource();\n      /**\n       * <pre>\n       * Where the element was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      com.android.aapt.Resources.Source getSource();\n\n      /**\n       * <pre>\n       * Any comments associated with the element.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      boolean hasComment();\n      /**\n       * <pre>\n       * Any comments associated with the element.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      java.lang.String getComment();\n      /**\n       * <pre>\n       * Any comments associated with the element.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      com.google.protobuf.ByteString\n          getCommentBytes();\n\n      /**\n       * <pre>\n       * The value assigned to this element.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 3;</code>\n       */\n      boolean hasItem();\n      /**\n       * <pre>\n       * The value assigned to this element.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 3;</code>\n       */\n      com.android.aapt.Resources.Item getItem();\n    }\n    /**\n     * <pre>\n     * A single element of the array.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Array.Element}\n     */\n    public  static final class Element extends\n        com.google.protobuf.GeneratedMessageLite<\n            Element, Element.Builder> implements\n        // @@protoc_insertion_point(message_implements:aapt.pb.Array.Element)\n        ElementOrBuilder {\n      private Element() {\n        comment_ = \"\";\n      }\n      private int bitField0_;\n      public static final int SOURCE_FIELD_NUMBER = 1;\n      private com.android.aapt.Resources.Source source_;\n      /**\n       * <pre>\n       * Where the element was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public boolean hasSource() {\n        return ((bitField0_ & 0x00000001) == 0x00000001);\n      }\n      /**\n       * <pre>\n       * Where the element was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public com.android.aapt.Resources.Source getSource() {\n        return source_ == null ? com.android.aapt.Resources.Source.getDefaultInstance() : source_;\n      }\n      /**\n       * <pre>\n       * Where the element was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void setSource(com.android.aapt.Resources.Source value) {\n        if (value == null) {\n          throw new NullPointerException();\n        }\n        source_ = value;\n        bitField0_ |= 0x00000001;\n        }\n      /**\n       * <pre>\n       * Where the element was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void setSource(\n          com.android.aapt.Resources.Source.Builder builderForValue) {\n        source_ = builderForValue.build();\n        bitField0_ |= 0x00000001;\n      }\n      /**\n       * <pre>\n       * Where the element was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void mergeSource(com.android.aapt.Resources.Source value) {\n        if (source_ != null &&\n            source_ != com.android.aapt.Resources.Source.getDefaultInstance()) {\n          source_ =\n            com.android.aapt.Resources.Source.newBuilder(source_).mergeFrom(value).buildPartial();\n        } else {\n          source_ = value;\n        }\n        bitField0_ |= 0x00000001;\n      }\n      /**\n       * <pre>\n       * Where the element was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void clearSource() {  source_ = null;\n        bitField0_ = (bitField0_ & ~0x00000001);\n      }\n\n      public static final int COMMENT_FIELD_NUMBER = 2;\n      private java.lang.String comment_;\n      /**\n       * <pre>\n       * Any comments associated with the element.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public boolean hasComment() {\n        return ((bitField0_ & 0x00000002) == 0x00000002);\n      }\n      /**\n       * <pre>\n       * Any comments associated with the element.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public java.lang.String getComment() {\n        return comment_;\n      }\n      /**\n       * <pre>\n       * Any comments associated with the element.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public com.google.protobuf.ByteString\n          getCommentBytes() {\n        return com.google.protobuf.ByteString.copyFromUtf8(comment_);\n      }\n      /**\n       * <pre>\n       * Any comments associated with the element.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void setComment(\n          java.lang.String value) {\n        if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n        comment_ = value;\n      }\n      /**\n       * <pre>\n       * Any comments associated with the element.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void clearComment() {\n        bitField0_ = (bitField0_ & ~0x00000002);\n        comment_ = getDefaultInstance().getComment();\n      }\n      /**\n       * <pre>\n       * Any comments associated with the element.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void setCommentBytes(\n          com.google.protobuf.ByteString value) {\n        if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n        comment_ = value.toStringUtf8();\n      }\n\n      public static final int ITEM_FIELD_NUMBER = 3;\n      private com.android.aapt.Resources.Item item_;\n      /**\n       * <pre>\n       * The value assigned to this element.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 3;</code>\n       */\n      public boolean hasItem() {\n        return ((bitField0_ & 0x00000004) == 0x00000004);\n      }\n      /**\n       * <pre>\n       * The value assigned to this element.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 3;</code>\n       */\n      public com.android.aapt.Resources.Item getItem() {\n        return item_ == null ? com.android.aapt.Resources.Item.getDefaultInstance() : item_;\n      }\n      /**\n       * <pre>\n       * The value assigned to this element.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 3;</code>\n       */\n      private void setItem(com.android.aapt.Resources.Item value) {\n        if (value == null) {\n          throw new NullPointerException();\n        }\n        item_ = value;\n        bitField0_ |= 0x00000004;\n        }\n      /**\n       * <pre>\n       * The value assigned to this element.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 3;</code>\n       */\n      private void setItem(\n          com.android.aapt.Resources.Item.Builder builderForValue) {\n        item_ = builderForValue.build();\n        bitField0_ |= 0x00000004;\n      }\n      /**\n       * <pre>\n       * The value assigned to this element.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 3;</code>\n       */\n      private void mergeItem(com.android.aapt.Resources.Item value) {\n        if (item_ != null &&\n            item_ != com.android.aapt.Resources.Item.getDefaultInstance()) {\n          item_ =\n            com.android.aapt.Resources.Item.newBuilder(item_).mergeFrom(value).buildPartial();\n        } else {\n          item_ = value;\n        }\n        bitField0_ |= 0x00000004;\n      }\n      /**\n       * <pre>\n       * The value assigned to this element.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 3;</code>\n       */\n      private void clearItem() {  item_ = null;\n        bitField0_ = (bitField0_ & ~0x00000004);\n      }\n\n      public void writeTo(com.google.protobuf.CodedOutputStream output)\n                          throws java.io.IOException {\n        if (((bitField0_ & 0x00000001) == 0x00000001)) {\n          output.writeMessage(1, getSource());\n        }\n        if (((bitField0_ & 0x00000002) == 0x00000002)) {\n          output.writeString(2, getComment());\n        }\n        if (((bitField0_ & 0x00000004) == 0x00000004)) {\n          output.writeMessage(3, getItem());\n        }\n        unknownFields.writeTo(output);\n      }\n\n      public int getSerializedSize() {\n        int size = memoizedSerializedSize;\n        if (size != -1) return size;\n\n        size = 0;\n        if (((bitField0_ & 0x00000001) == 0x00000001)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeMessageSize(1, getSource());\n        }\n        if (((bitField0_ & 0x00000002) == 0x00000002)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeStringSize(2, getComment());\n        }\n        if (((bitField0_ & 0x00000004) == 0x00000004)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeMessageSize(3, getItem());\n        }\n        size += unknownFields.getSerializedSize();\n        memoizedSerializedSize = size;\n        return size;\n      }\n\n      public static com.android.aapt.Resources.Array.Element parseFrom(\n          com.google.protobuf.ByteString data)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data);\n      }\n      public static com.android.aapt.Resources.Array.Element parseFrom(\n          com.google.protobuf.ByteString data,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Array.Element parseFrom(byte[] data)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data);\n      }\n      public static com.android.aapt.Resources.Array.Element parseFrom(\n          byte[] data,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Array.Element parseFrom(java.io.InputStream input)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Array.Element parseFrom(\n          java.io.InputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Array.Element parseDelimitedFrom(java.io.InputStream input)\n          throws java.io.IOException {\n        return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Array.Element parseDelimitedFrom(\n          java.io.InputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Array.Element parseFrom(\n          com.google.protobuf.CodedInputStream input)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Array.Element parseFrom(\n          com.google.protobuf.CodedInputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n\n      public static Builder newBuilder() {\n        return DEFAULT_INSTANCE.toBuilder();\n      }\n      public static Builder newBuilder(com.android.aapt.Resources.Array.Element prototype) {\n        return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n      }\n\n      /**\n       * <pre>\n       * A single element of the array.\n       * </pre>\n       *\n       * Protobuf type {@code aapt.pb.Array.Element}\n       */\n      public static final class Builder extends\n          com.google.protobuf.GeneratedMessageLite.Builder<\n            com.android.aapt.Resources.Array.Element, Builder> implements\n          // @@protoc_insertion_point(builder_implements:aapt.pb.Array.Element)\n          com.android.aapt.Resources.Array.ElementOrBuilder {\n        // Construct using com.android.aapt.Resources.Array.Element.newBuilder()\n        private Builder() {\n          super(DEFAULT_INSTANCE);\n        }\n\n\n        /**\n         * <pre>\n         * Where the element was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public boolean hasSource() {\n          return instance.hasSource();\n        }\n        /**\n         * <pre>\n         * Where the element was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public com.android.aapt.Resources.Source getSource() {\n          return instance.getSource();\n        }\n        /**\n         * <pre>\n         * Where the element was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder setSource(com.android.aapt.Resources.Source value) {\n          copyOnWrite();\n          instance.setSource(value);\n          return this;\n          }\n        /**\n         * <pre>\n         * Where the element was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder setSource(\n            com.android.aapt.Resources.Source.Builder builderForValue) {\n          copyOnWrite();\n          instance.setSource(builderForValue);\n          return this;\n        }\n        /**\n         * <pre>\n         * Where the element was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder mergeSource(com.android.aapt.Resources.Source value) {\n          copyOnWrite();\n          instance.mergeSource(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * Where the element was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder clearSource() {  copyOnWrite();\n          instance.clearSource();\n          return this;\n        }\n\n        /**\n         * <pre>\n         * Any comments associated with the element.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public boolean hasComment() {\n          return instance.hasComment();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the element.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public java.lang.String getComment() {\n          return instance.getComment();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the element.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public com.google.protobuf.ByteString\n            getCommentBytes() {\n          return instance.getCommentBytes();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the element.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder setComment(\n            java.lang.String value) {\n          copyOnWrite();\n          instance.setComment(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * Any comments associated with the element.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder clearComment() {\n          copyOnWrite();\n          instance.clearComment();\n          return this;\n        }\n        /**\n         * <pre>\n         * Any comments associated with the element.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder setCommentBytes(\n            com.google.protobuf.ByteString value) {\n          copyOnWrite();\n          instance.setCommentBytes(value);\n          return this;\n        }\n\n        /**\n         * <pre>\n         * The value assigned to this element.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 3;</code>\n         */\n        public boolean hasItem() {\n          return instance.hasItem();\n        }\n        /**\n         * <pre>\n         * The value assigned to this element.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 3;</code>\n         */\n        public com.android.aapt.Resources.Item getItem() {\n          return instance.getItem();\n        }\n        /**\n         * <pre>\n         * The value assigned to this element.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 3;</code>\n         */\n        public Builder setItem(com.android.aapt.Resources.Item value) {\n          copyOnWrite();\n          instance.setItem(value);\n          return this;\n          }\n        /**\n         * <pre>\n         * The value assigned to this element.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 3;</code>\n         */\n        public Builder setItem(\n            com.android.aapt.Resources.Item.Builder builderForValue) {\n          copyOnWrite();\n          instance.setItem(builderForValue);\n          return this;\n        }\n        /**\n         * <pre>\n         * The value assigned to this element.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 3;</code>\n         */\n        public Builder mergeItem(com.android.aapt.Resources.Item value) {\n          copyOnWrite();\n          instance.mergeItem(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * The value assigned to this element.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 3;</code>\n         */\n        public Builder clearItem() {  copyOnWrite();\n          instance.clearItem();\n          return this;\n        }\n\n        // @@protoc_insertion_point(builder_scope:aapt.pb.Array.Element)\n      }\n      protected final Object dynamicMethod(\n          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n          Object arg0, Object arg1) {\n        switch (method) {\n          case NEW_MUTABLE_INSTANCE: {\n            return new com.android.aapt.Resources.Array.Element();\n          }\n          case IS_INITIALIZED: {\n            return DEFAULT_INSTANCE;\n          }\n          case MAKE_IMMUTABLE: {\n            return null;\n          }\n          case NEW_BUILDER: {\n            return new Builder();\n          }\n          case VISIT: {\n            Visitor visitor = (Visitor) arg0;\n            com.android.aapt.Resources.Array.Element other = (com.android.aapt.Resources.Array.Element) arg1;\n            source_ = visitor.visitMessage(source_, other.source_);\n            comment_ = visitor.visitString(\n                hasComment(), comment_,\n                other.hasComment(), other.comment_);\n            item_ = visitor.visitMessage(item_, other.item_);\n            if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n                .INSTANCE) {\n              bitField0_ |= other.bitField0_;\n            }\n            return this;\n          }\n          case MERGE_FROM_STREAM: {\n            com.google.protobuf.CodedInputStream input =\n                (com.google.protobuf.CodedInputStream) arg0;\n            com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n                (com.google.protobuf.ExtensionRegistryLite) arg1;\n            try {\n              boolean done = false;\n              while (!done) {\n                int tag = input.readTag();\n                switch (tag) {\n                  case 0:\n                    done = true;\n                    break;\n                  default: {\n                    if (!parseUnknownField(tag, input)) {\n                      done = true;\n                    }\n                    break;\n                  }\n                  case 10: {\n                    com.android.aapt.Resources.Source.Builder subBuilder = null;\n                    if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                      subBuilder = source_.toBuilder();\n                    }\n                    source_ = input.readMessage(com.android.aapt.Resources.Source.parser(), extensionRegistry);\n                    if (subBuilder != null) {\n                      subBuilder.mergeFrom(source_);\n                      source_ = subBuilder.buildPartial();\n                    }\n                    bitField0_ |= 0x00000001;\n                    break;\n                  }\n                  case 18: {\n                    java.lang.String s = input.readString();\n                    bitField0_ |= 0x00000002;\n                    comment_ = s;\n                    break;\n                  }\n                  case 26: {\n                    com.android.aapt.Resources.Item.Builder subBuilder = null;\n                    if (((bitField0_ & 0x00000004) == 0x00000004)) {\n                      subBuilder = item_.toBuilder();\n                    }\n                    item_ = input.readMessage(com.android.aapt.Resources.Item.parser(), extensionRegistry);\n                    if (subBuilder != null) {\n                      subBuilder.mergeFrom(item_);\n                      item_ = subBuilder.buildPartial();\n                    }\n                    bitField0_ |= 0x00000004;\n                    break;\n                  }\n                }\n              }\n            } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n              throw new RuntimeException(e.setUnfinishedMessage(this));\n            } catch (java.io.IOException e) {\n              throw new RuntimeException(\n                  new com.google.protobuf.InvalidProtocolBufferException(\n                      e.getMessage()).setUnfinishedMessage(this));\n            } finally {\n            }\n          }\n          case GET_DEFAULT_INSTANCE: {\n            return DEFAULT_INSTANCE;\n          }\n          case GET_PARSER: {\n            if (PARSER == null) {    synchronized (com.android.aapt.Resources.Array.Element.class) {\n                if (PARSER == null) {\n                  PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n                }\n              }\n            }\n            return PARSER;\n          }\n        }\n        throw new UnsupportedOperationException();\n      }\n\n\n      // @@protoc_insertion_point(class_scope:aapt.pb.Array.Element)\n      private static final com.android.aapt.Resources.Array.Element DEFAULT_INSTANCE;\n      static {\n        DEFAULT_INSTANCE = new Element();\n        DEFAULT_INSTANCE.makeImmutable();\n      }\n\n      public static com.android.aapt.Resources.Array.Element getDefaultInstance() {\n        return DEFAULT_INSTANCE;\n      }\n\n      private static volatile com.google.protobuf.Parser<Element> PARSER;\n\n      public static com.google.protobuf.Parser<Element> parser() {\n        return DEFAULT_INSTANCE.getParserForType();\n      }\n    }\n\n    public static final int ELEMENT_FIELD_NUMBER = 1;\n    private com.google.protobuf.Internal.ProtobufList<com.android.aapt.Resources.Array.Element> element_;\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    public java.util.List<com.android.aapt.Resources.Array.Element> getElementList() {\n      return element_;\n    }\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    public java.util.List<? extends com.android.aapt.Resources.Array.ElementOrBuilder> \n        getElementOrBuilderList() {\n      return element_;\n    }\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    public int getElementCount() {\n      return element_.size();\n    }\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    public com.android.aapt.Resources.Array.Element getElement(int index) {\n      return element_.get(index);\n    }\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    public com.android.aapt.Resources.Array.ElementOrBuilder getElementOrBuilder(\n        int index) {\n      return element_.get(index);\n    }\n    private void ensureElementIsMutable() {\n      if (!element_.isModifiable()) {\n        element_ =\n            com.google.protobuf.GeneratedMessageLite.mutableCopy(element_);\n       }\n    }\n\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    private void setElement(\n        int index, com.android.aapt.Resources.Array.Element value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureElementIsMutable();\n      element_.set(index, value);\n    }\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    private void setElement(\n        int index, com.android.aapt.Resources.Array.Element.Builder builderForValue) {\n      ensureElementIsMutable();\n      element_.set(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    private void addElement(com.android.aapt.Resources.Array.Element value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureElementIsMutable();\n      element_.add(value);\n    }\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    private void addElement(\n        int index, com.android.aapt.Resources.Array.Element value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureElementIsMutable();\n      element_.add(index, value);\n    }\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    private void addElement(\n        com.android.aapt.Resources.Array.Element.Builder builderForValue) {\n      ensureElementIsMutable();\n      element_.add(builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    private void addElement(\n        int index, com.android.aapt.Resources.Array.Element.Builder builderForValue) {\n      ensureElementIsMutable();\n      element_.add(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    private void addAllElement(\n        java.lang.Iterable<? extends com.android.aapt.Resources.Array.Element> values) {\n      ensureElementIsMutable();\n      com.google.protobuf.AbstractMessageLite.addAll(\n          values, element_);\n    }\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    private void clearElement() {\n      element_ = emptyProtobufList();\n    }\n    /**\n     * <pre>\n     * The list of array elements.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n     */\n    private void removeElement(int index) {\n      ensureElementIsMutable();\n      element_.remove(index);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      for (int i = 0; i < element_.size(); i++) {\n        output.writeMessage(1, element_.get(i));\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      for (int i = 0; i < element_.size(); i++) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(1, element_.get(i));\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.Array parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Array parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Array parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Array parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Array parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Array parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Array parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Array parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Array parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Array parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.Array prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A value that represents an array of resource values.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Array}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.Array, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.Array)\n        com.android.aapt.Resources.ArrayOrBuilder {\n      // Construct using com.android.aapt.Resources.Array.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * The list of array elements.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n       */\n      public java.util.List<com.android.aapt.Resources.Array.Element> getElementList() {\n        return java.util.Collections.unmodifiableList(\n            instance.getElementList());\n      }\n      /**\n       * <pre>\n       * The list of array elements.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n       */\n      public int getElementCount() {\n        return instance.getElementCount();\n      }/**\n       * <pre>\n       * The list of array elements.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n       */\n      public com.android.aapt.Resources.Array.Element getElement(int index) {\n        return instance.getElement(index);\n      }\n      /**\n       * <pre>\n       * The list of array elements.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n       */\n      public Builder setElement(\n          int index, com.android.aapt.Resources.Array.Element value) {\n        copyOnWrite();\n        instance.setElement(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The list of array elements.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n       */\n      public Builder setElement(\n          int index, com.android.aapt.Resources.Array.Element.Builder builderForValue) {\n        copyOnWrite();\n        instance.setElement(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The list of array elements.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n       */\n      public Builder addElement(com.android.aapt.Resources.Array.Element value) {\n        copyOnWrite();\n        instance.addElement(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The list of array elements.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n       */\n      public Builder addElement(\n          int index, com.android.aapt.Resources.Array.Element value) {\n        copyOnWrite();\n        instance.addElement(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The list of array elements.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n       */\n      public Builder addElement(\n          com.android.aapt.Resources.Array.Element.Builder builderForValue) {\n        copyOnWrite();\n        instance.addElement(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The list of array elements.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n       */\n      public Builder addElement(\n          int index, com.android.aapt.Resources.Array.Element.Builder builderForValue) {\n        copyOnWrite();\n        instance.addElement(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The list of array elements.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n       */\n      public Builder addAllElement(\n          java.lang.Iterable<? extends com.android.aapt.Resources.Array.Element> values) {\n        copyOnWrite();\n        instance.addAllElement(values);\n        return this;\n      }\n      /**\n       * <pre>\n       * The list of array elements.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n       */\n      public Builder clearElement() {\n        copyOnWrite();\n        instance.clearElement();\n        return this;\n      }\n      /**\n       * <pre>\n       * The list of array elements.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Array.Element element = 1;</code>\n       */\n      public Builder removeElement(int index) {\n        copyOnWrite();\n        instance.removeElement(index);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.Array)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.Array();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          element_.makeImmutable();\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.Array other = (com.android.aapt.Resources.Array) arg1;\n          element_= visitor.visitList(element_, other.element_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  if (!element_.isModifiable()) {\n                    element_ =\n                        com.google.protobuf.GeneratedMessageLite.mutableCopy(element_);\n                  }\n                  element_.add(\n                      input.readMessage(com.android.aapt.Resources.Array.Element.parser(), extensionRegistry));\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.Array.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.Array)\n    private static final com.android.aapt.Resources.Array DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new Array();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.Array getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<Array> PARSER;\n\n    public static com.google.protobuf.Parser<Array> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface PluralOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.Plural)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    java.util.List<com.android.aapt.Resources.Plural.Entry> \n        getEntryList();\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    com.android.aapt.Resources.Plural.Entry getEntry(int index);\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    int getEntryCount();\n  }\n  /**\n   * <pre>\n   * A value that represents a string and its many variations based on plurality.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.Plural}\n   */\n  public  static final class Plural extends\n      com.google.protobuf.GeneratedMessageLite<\n          Plural, Plural.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.Plural)\n      PluralOrBuilder {\n    private Plural() {\n      entry_ = emptyProtobufList();\n    }\n    /**\n     * <pre>\n     * The arity of the plural.\n     * </pre>\n     *\n     * Protobuf enum {@code aapt.pb.Plural.Arity}\n     */\n    public enum Arity\n        implements com.google.protobuf.Internal.EnumLite {\n      /**\n       * <code>ZERO = 0;</code>\n       */\n      ZERO(0),\n      /**\n       * <code>ONE = 1;</code>\n       */\n      ONE(1),\n      /**\n       * <code>TWO = 2;</code>\n       */\n      TWO(2),\n      /**\n       * <code>FEW = 3;</code>\n       */\n      FEW(3),\n      /**\n       * <code>MANY = 4;</code>\n       */\n      MANY(4),\n      /**\n       * <code>OTHER = 5;</code>\n       */\n      OTHER(5),\n      ;\n\n      /**\n       * <code>ZERO = 0;</code>\n       */\n      public static final int ZERO_VALUE = 0;\n      /**\n       * <code>ONE = 1;</code>\n       */\n      public static final int ONE_VALUE = 1;\n      /**\n       * <code>TWO = 2;</code>\n       */\n      public static final int TWO_VALUE = 2;\n      /**\n       * <code>FEW = 3;</code>\n       */\n      public static final int FEW_VALUE = 3;\n      /**\n       * <code>MANY = 4;</code>\n       */\n      public static final int MANY_VALUE = 4;\n      /**\n       * <code>OTHER = 5;</code>\n       */\n      public static final int OTHER_VALUE = 5;\n\n\n      public final int getNumber() {\n        return value;\n      }\n\n      /**\n       * @deprecated Use {@link #forNumber(int)} instead.\n       */\n      @java.lang.Deprecated\n      public static Arity valueOf(int value) {\n        return forNumber(value);\n      }\n\n      public static Arity forNumber(int value) {\n        switch (value) {\n          case 0: return ZERO;\n          case 1: return ONE;\n          case 2: return TWO;\n          case 3: return FEW;\n          case 4: return MANY;\n          case 5: return OTHER;\n          default: return null;\n        }\n      }\n\n      public static com.google.protobuf.Internal.EnumLiteMap<Arity>\n          internalGetValueMap() {\n        return internalValueMap;\n      }\n      private static final com.google.protobuf.Internal.EnumLiteMap<\n          Arity> internalValueMap =\n            new com.google.protobuf.Internal.EnumLiteMap<Arity>() {\n              public Arity findValueByNumber(int number) {\n                return Arity.forNumber(number);\n              }\n            };\n\n      private final int value;\n\n      private Arity(int value) {\n        this.value = value;\n      }\n\n      // @@protoc_insertion_point(enum_scope:aapt.pb.Plural.Arity)\n    }\n\n    public interface EntryOrBuilder extends\n        // @@protoc_insertion_point(interface_extends:aapt.pb.Plural.Entry)\n        com.google.protobuf.MessageLiteOrBuilder {\n\n      /**\n       * <pre>\n       * Where the plural was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      boolean hasSource();\n      /**\n       * <pre>\n       * Where the plural was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      com.android.aapt.Resources.Source getSource();\n\n      /**\n       * <pre>\n       * Any comments associated with the plural.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      boolean hasComment();\n      /**\n       * <pre>\n       * Any comments associated with the plural.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      java.lang.String getComment();\n      /**\n       * <pre>\n       * Any comments associated with the plural.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      com.google.protobuf.ByteString\n          getCommentBytes();\n\n      /**\n       * <pre>\n       * The arity of the plural.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Plural.Arity arity = 3;</code>\n       */\n      boolean hasArity();\n      /**\n       * <pre>\n       * The arity of the plural.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Plural.Arity arity = 3;</code>\n       */\n      com.android.aapt.Resources.Plural.Arity getArity();\n\n      /**\n       * <pre>\n       * The value assigned to this plural.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      boolean hasItem();\n      /**\n       * <pre>\n       * The value assigned to this plural.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      com.android.aapt.Resources.Item getItem();\n    }\n    /**\n     * <pre>\n     * The plural value for a given arity.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Plural.Entry}\n     */\n    public  static final class Entry extends\n        com.google.protobuf.GeneratedMessageLite<\n            Entry, Entry.Builder> implements\n        // @@protoc_insertion_point(message_implements:aapt.pb.Plural.Entry)\n        EntryOrBuilder {\n      private Entry() {\n        comment_ = \"\";\n      }\n      private int bitField0_;\n      public static final int SOURCE_FIELD_NUMBER = 1;\n      private com.android.aapt.Resources.Source source_;\n      /**\n       * <pre>\n       * Where the plural was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public boolean hasSource() {\n        return ((bitField0_ & 0x00000001) == 0x00000001);\n      }\n      /**\n       * <pre>\n       * Where the plural was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      public com.android.aapt.Resources.Source getSource() {\n        return source_ == null ? com.android.aapt.Resources.Source.getDefaultInstance() : source_;\n      }\n      /**\n       * <pre>\n       * Where the plural was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void setSource(com.android.aapt.Resources.Source value) {\n        if (value == null) {\n          throw new NullPointerException();\n        }\n        source_ = value;\n        bitField0_ |= 0x00000001;\n        }\n      /**\n       * <pre>\n       * Where the plural was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void setSource(\n          com.android.aapt.Resources.Source.Builder builderForValue) {\n        source_ = builderForValue.build();\n        bitField0_ |= 0x00000001;\n      }\n      /**\n       * <pre>\n       * Where the plural was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void mergeSource(com.android.aapt.Resources.Source value) {\n        if (source_ != null &&\n            source_ != com.android.aapt.Resources.Source.getDefaultInstance()) {\n          source_ =\n            com.android.aapt.Resources.Source.newBuilder(source_).mergeFrom(value).buildPartial();\n        } else {\n          source_ = value;\n        }\n        bitField0_ |= 0x00000001;\n      }\n      /**\n       * <pre>\n       * Where the plural was defined.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Source source = 1;</code>\n       */\n      private void clearSource() {  source_ = null;\n        bitField0_ = (bitField0_ & ~0x00000001);\n      }\n\n      public static final int COMMENT_FIELD_NUMBER = 2;\n      private java.lang.String comment_;\n      /**\n       * <pre>\n       * Any comments associated with the plural.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public boolean hasComment() {\n        return ((bitField0_ & 0x00000002) == 0x00000002);\n      }\n      /**\n       * <pre>\n       * Any comments associated with the plural.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public java.lang.String getComment() {\n        return comment_;\n      }\n      /**\n       * <pre>\n       * Any comments associated with the plural.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      public com.google.protobuf.ByteString\n          getCommentBytes() {\n        return com.google.protobuf.ByteString.copyFromUtf8(comment_);\n      }\n      /**\n       * <pre>\n       * Any comments associated with the plural.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void setComment(\n          java.lang.String value) {\n        if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n        comment_ = value;\n      }\n      /**\n       * <pre>\n       * Any comments associated with the plural.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void clearComment() {\n        bitField0_ = (bitField0_ & ~0x00000002);\n        comment_ = getDefaultInstance().getComment();\n      }\n      /**\n       * <pre>\n       * Any comments associated with the plural.\n       * </pre>\n       *\n       * <code>optional string comment = 2;</code>\n       */\n      private void setCommentBytes(\n          com.google.protobuf.ByteString value) {\n        if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n        comment_ = value.toStringUtf8();\n      }\n\n      public static final int ARITY_FIELD_NUMBER = 3;\n      private int arity_;\n      /**\n       * <pre>\n       * The arity of the plural.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Plural.Arity arity = 3;</code>\n       */\n      public boolean hasArity() {\n        return ((bitField0_ & 0x00000004) == 0x00000004);\n      }\n      /**\n       * <pre>\n       * The arity of the plural.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Plural.Arity arity = 3;</code>\n       */\n      public com.android.aapt.Resources.Plural.Arity getArity() {\n        com.android.aapt.Resources.Plural.Arity result = com.android.aapt.Resources.Plural.Arity.forNumber(arity_);\n        return result == null ? com.android.aapt.Resources.Plural.Arity.ZERO : result;\n      }\n      /**\n       * <pre>\n       * The arity of the plural.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Plural.Arity arity = 3;</code>\n       */\n      private void setArity(com.android.aapt.Resources.Plural.Arity value) {\n        if (value == null) {\n          throw new NullPointerException();\n        }\n        bitField0_ |= 0x00000004;\n        arity_ = value.getNumber();\n      }\n      /**\n       * <pre>\n       * The arity of the plural.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Plural.Arity arity = 3;</code>\n       */\n      private void clearArity() {\n        bitField0_ = (bitField0_ & ~0x00000004);\n        arity_ = 0;\n      }\n\n      public static final int ITEM_FIELD_NUMBER = 4;\n      private com.android.aapt.Resources.Item item_;\n      /**\n       * <pre>\n       * The value assigned to this plural.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      public boolean hasItem() {\n        return ((bitField0_ & 0x00000008) == 0x00000008);\n      }\n      /**\n       * <pre>\n       * The value assigned to this plural.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      public com.android.aapt.Resources.Item getItem() {\n        return item_ == null ? com.android.aapt.Resources.Item.getDefaultInstance() : item_;\n      }\n      /**\n       * <pre>\n       * The value assigned to this plural.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      private void setItem(com.android.aapt.Resources.Item value) {\n        if (value == null) {\n          throw new NullPointerException();\n        }\n        item_ = value;\n        bitField0_ |= 0x00000008;\n        }\n      /**\n       * <pre>\n       * The value assigned to this plural.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      private void setItem(\n          com.android.aapt.Resources.Item.Builder builderForValue) {\n        item_ = builderForValue.build();\n        bitField0_ |= 0x00000008;\n      }\n      /**\n       * <pre>\n       * The value assigned to this plural.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      private void mergeItem(com.android.aapt.Resources.Item value) {\n        if (item_ != null &&\n            item_ != com.android.aapt.Resources.Item.getDefaultInstance()) {\n          item_ =\n            com.android.aapt.Resources.Item.newBuilder(item_).mergeFrom(value).buildPartial();\n        } else {\n          item_ = value;\n        }\n        bitField0_ |= 0x00000008;\n      }\n      /**\n       * <pre>\n       * The value assigned to this plural.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item item = 4;</code>\n       */\n      private void clearItem() {  item_ = null;\n        bitField0_ = (bitField0_ & ~0x00000008);\n      }\n\n      public void writeTo(com.google.protobuf.CodedOutputStream output)\n                          throws java.io.IOException {\n        if (((bitField0_ & 0x00000001) == 0x00000001)) {\n          output.writeMessage(1, getSource());\n        }\n        if (((bitField0_ & 0x00000002) == 0x00000002)) {\n          output.writeString(2, getComment());\n        }\n        if (((bitField0_ & 0x00000004) == 0x00000004)) {\n          output.writeEnum(3, arity_);\n        }\n        if (((bitField0_ & 0x00000008) == 0x00000008)) {\n          output.writeMessage(4, getItem());\n        }\n        unknownFields.writeTo(output);\n      }\n\n      public int getSerializedSize() {\n        int size = memoizedSerializedSize;\n        if (size != -1) return size;\n\n        size = 0;\n        if (((bitField0_ & 0x00000001) == 0x00000001)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeMessageSize(1, getSource());\n        }\n        if (((bitField0_ & 0x00000002) == 0x00000002)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeStringSize(2, getComment());\n        }\n        if (((bitField0_ & 0x00000004) == 0x00000004)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeEnumSize(3, arity_);\n        }\n        if (((bitField0_ & 0x00000008) == 0x00000008)) {\n          size += com.google.protobuf.CodedOutputStream\n            .computeMessageSize(4, getItem());\n        }\n        size += unknownFields.getSerializedSize();\n        memoizedSerializedSize = size;\n        return size;\n      }\n\n      public static com.android.aapt.Resources.Plural.Entry parseFrom(\n          com.google.protobuf.ByteString data)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data);\n      }\n      public static com.android.aapt.Resources.Plural.Entry parseFrom(\n          com.google.protobuf.ByteString data,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Plural.Entry parseFrom(byte[] data)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data);\n      }\n      public static com.android.aapt.Resources.Plural.Entry parseFrom(\n          byte[] data,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws com.google.protobuf.InvalidProtocolBufferException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, data, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Plural.Entry parseFrom(java.io.InputStream input)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Plural.Entry parseFrom(\n          java.io.InputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Plural.Entry parseDelimitedFrom(java.io.InputStream input)\n          throws java.io.IOException {\n        return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Plural.Entry parseDelimitedFrom(\n          java.io.InputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n      public static com.android.aapt.Resources.Plural.Entry parseFrom(\n          com.google.protobuf.CodedInputStream input)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input);\n      }\n      public static com.android.aapt.Resources.Plural.Entry parseFrom(\n          com.google.protobuf.CodedInputStream input,\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n          throws java.io.IOException {\n        return com.google.protobuf.GeneratedMessageLite.parseFrom(\n            DEFAULT_INSTANCE, input, extensionRegistry);\n      }\n\n      public static Builder newBuilder() {\n        return DEFAULT_INSTANCE.toBuilder();\n      }\n      public static Builder newBuilder(com.android.aapt.Resources.Plural.Entry prototype) {\n        return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n      }\n\n      /**\n       * <pre>\n       * The plural value for a given arity.\n       * </pre>\n       *\n       * Protobuf type {@code aapt.pb.Plural.Entry}\n       */\n      public static final class Builder extends\n          com.google.protobuf.GeneratedMessageLite.Builder<\n            com.android.aapt.Resources.Plural.Entry, Builder> implements\n          // @@protoc_insertion_point(builder_implements:aapt.pb.Plural.Entry)\n          com.android.aapt.Resources.Plural.EntryOrBuilder {\n        // Construct using com.android.aapt.Resources.Plural.Entry.newBuilder()\n        private Builder() {\n          super(DEFAULT_INSTANCE);\n        }\n\n\n        /**\n         * <pre>\n         * Where the plural was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public boolean hasSource() {\n          return instance.hasSource();\n        }\n        /**\n         * <pre>\n         * Where the plural was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public com.android.aapt.Resources.Source getSource() {\n          return instance.getSource();\n        }\n        /**\n         * <pre>\n         * Where the plural was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder setSource(com.android.aapt.Resources.Source value) {\n          copyOnWrite();\n          instance.setSource(value);\n          return this;\n          }\n        /**\n         * <pre>\n         * Where the plural was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder setSource(\n            com.android.aapt.Resources.Source.Builder builderForValue) {\n          copyOnWrite();\n          instance.setSource(builderForValue);\n          return this;\n        }\n        /**\n         * <pre>\n         * Where the plural was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder mergeSource(com.android.aapt.Resources.Source value) {\n          copyOnWrite();\n          instance.mergeSource(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * Where the plural was defined.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Source source = 1;</code>\n         */\n        public Builder clearSource() {  copyOnWrite();\n          instance.clearSource();\n          return this;\n        }\n\n        /**\n         * <pre>\n         * Any comments associated with the plural.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public boolean hasComment() {\n          return instance.hasComment();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the plural.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public java.lang.String getComment() {\n          return instance.getComment();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the plural.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public com.google.protobuf.ByteString\n            getCommentBytes() {\n          return instance.getCommentBytes();\n        }\n        /**\n         * <pre>\n         * Any comments associated with the plural.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder setComment(\n            java.lang.String value) {\n          copyOnWrite();\n          instance.setComment(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * Any comments associated with the plural.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder clearComment() {\n          copyOnWrite();\n          instance.clearComment();\n          return this;\n        }\n        /**\n         * <pre>\n         * Any comments associated with the plural.\n         * </pre>\n         *\n         * <code>optional string comment = 2;</code>\n         */\n        public Builder setCommentBytes(\n            com.google.protobuf.ByteString value) {\n          copyOnWrite();\n          instance.setCommentBytes(value);\n          return this;\n        }\n\n        /**\n         * <pre>\n         * The arity of the plural.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Plural.Arity arity = 3;</code>\n         */\n        public boolean hasArity() {\n          return instance.hasArity();\n        }\n        /**\n         * <pre>\n         * The arity of the plural.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Plural.Arity arity = 3;</code>\n         */\n        public com.android.aapt.Resources.Plural.Arity getArity() {\n          return instance.getArity();\n        }\n        /**\n         * <pre>\n         * The arity of the plural.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Plural.Arity arity = 3;</code>\n         */\n        public Builder setArity(com.android.aapt.Resources.Plural.Arity value) {\n          copyOnWrite();\n          instance.setArity(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * The arity of the plural.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Plural.Arity arity = 3;</code>\n         */\n        public Builder clearArity() {\n          copyOnWrite();\n          instance.clearArity();\n          return this;\n        }\n\n        /**\n         * <pre>\n         * The value assigned to this plural.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 4;</code>\n         */\n        public boolean hasItem() {\n          return instance.hasItem();\n        }\n        /**\n         * <pre>\n         * The value assigned to this plural.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 4;</code>\n         */\n        public com.android.aapt.Resources.Item getItem() {\n          return instance.getItem();\n        }\n        /**\n         * <pre>\n         * The value assigned to this plural.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 4;</code>\n         */\n        public Builder setItem(com.android.aapt.Resources.Item value) {\n          copyOnWrite();\n          instance.setItem(value);\n          return this;\n          }\n        /**\n         * <pre>\n         * The value assigned to this plural.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 4;</code>\n         */\n        public Builder setItem(\n            com.android.aapt.Resources.Item.Builder builderForValue) {\n          copyOnWrite();\n          instance.setItem(builderForValue);\n          return this;\n        }\n        /**\n         * <pre>\n         * The value assigned to this plural.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 4;</code>\n         */\n        public Builder mergeItem(com.android.aapt.Resources.Item value) {\n          copyOnWrite();\n          instance.mergeItem(value);\n          return this;\n        }\n        /**\n         * <pre>\n         * The value assigned to this plural.\n         * </pre>\n         *\n         * <code>optional .aapt.pb.Item item = 4;</code>\n         */\n        public Builder clearItem() {  copyOnWrite();\n          instance.clearItem();\n          return this;\n        }\n\n        // @@protoc_insertion_point(builder_scope:aapt.pb.Plural.Entry)\n      }\n      protected final Object dynamicMethod(\n          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n          Object arg0, Object arg1) {\n        switch (method) {\n          case NEW_MUTABLE_INSTANCE: {\n            return new com.android.aapt.Resources.Plural.Entry();\n          }\n          case IS_INITIALIZED: {\n            return DEFAULT_INSTANCE;\n          }\n          case MAKE_IMMUTABLE: {\n            return null;\n          }\n          case NEW_BUILDER: {\n            return new Builder();\n          }\n          case VISIT: {\n            Visitor visitor = (Visitor) arg0;\n            com.android.aapt.Resources.Plural.Entry other = (com.android.aapt.Resources.Plural.Entry) arg1;\n            source_ = visitor.visitMessage(source_, other.source_);\n            comment_ = visitor.visitString(\n                hasComment(), comment_,\n                other.hasComment(), other.comment_);\n            arity_ = visitor.visitInt(hasArity(), arity_,\n                other.hasArity(), other.arity_);\n            item_ = visitor.visitMessage(item_, other.item_);\n            if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n                .INSTANCE) {\n              bitField0_ |= other.bitField0_;\n            }\n            return this;\n          }\n          case MERGE_FROM_STREAM: {\n            com.google.protobuf.CodedInputStream input =\n                (com.google.protobuf.CodedInputStream) arg0;\n            com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n                (com.google.protobuf.ExtensionRegistryLite) arg1;\n            try {\n              boolean done = false;\n              while (!done) {\n                int tag = input.readTag();\n                switch (tag) {\n                  case 0:\n                    done = true;\n                    break;\n                  default: {\n                    if (!parseUnknownField(tag, input)) {\n                      done = true;\n                    }\n                    break;\n                  }\n                  case 10: {\n                    com.android.aapt.Resources.Source.Builder subBuilder = null;\n                    if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                      subBuilder = source_.toBuilder();\n                    }\n                    source_ = input.readMessage(com.android.aapt.Resources.Source.parser(), extensionRegistry);\n                    if (subBuilder != null) {\n                      subBuilder.mergeFrom(source_);\n                      source_ = subBuilder.buildPartial();\n                    }\n                    bitField0_ |= 0x00000001;\n                    break;\n                  }\n                  case 18: {\n                    java.lang.String s = input.readString();\n                    bitField0_ |= 0x00000002;\n                    comment_ = s;\n                    break;\n                  }\n                  case 24: {\n                    int rawValue = input.readEnum();\n                    com.android.aapt.Resources.Plural.Arity value = com.android.aapt.Resources.Plural.Arity.forNumber(rawValue);\n                    if (value == null) {\n                      super.mergeVarintField(3, rawValue);\n                    } else {\n                      bitField0_ |= 0x00000004;\n                      arity_ = rawValue;\n                    }\n                    break;\n                  }\n                  case 34: {\n                    com.android.aapt.Resources.Item.Builder subBuilder = null;\n                    if (((bitField0_ & 0x00000008) == 0x00000008)) {\n                      subBuilder = item_.toBuilder();\n                    }\n                    item_ = input.readMessage(com.android.aapt.Resources.Item.parser(), extensionRegistry);\n                    if (subBuilder != null) {\n                      subBuilder.mergeFrom(item_);\n                      item_ = subBuilder.buildPartial();\n                    }\n                    bitField0_ |= 0x00000008;\n                    break;\n                  }\n                }\n              }\n            } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n              throw new RuntimeException(e.setUnfinishedMessage(this));\n            } catch (java.io.IOException e) {\n              throw new RuntimeException(\n                  new com.google.protobuf.InvalidProtocolBufferException(\n                      e.getMessage()).setUnfinishedMessage(this));\n            } finally {\n            }\n          }\n          case GET_DEFAULT_INSTANCE: {\n            return DEFAULT_INSTANCE;\n          }\n          case GET_PARSER: {\n            if (PARSER == null) {    synchronized (com.android.aapt.Resources.Plural.Entry.class) {\n                if (PARSER == null) {\n                  PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n                }\n              }\n            }\n            return PARSER;\n          }\n        }\n        throw new UnsupportedOperationException();\n      }\n\n\n      // @@protoc_insertion_point(class_scope:aapt.pb.Plural.Entry)\n      private static final com.android.aapt.Resources.Plural.Entry DEFAULT_INSTANCE;\n      static {\n        DEFAULT_INSTANCE = new Entry();\n        DEFAULT_INSTANCE.makeImmutable();\n      }\n\n      public static com.android.aapt.Resources.Plural.Entry getDefaultInstance() {\n        return DEFAULT_INSTANCE;\n      }\n\n      private static volatile com.google.protobuf.Parser<Entry> PARSER;\n\n      public static com.google.protobuf.Parser<Entry> parser() {\n        return DEFAULT_INSTANCE.getParserForType();\n      }\n    }\n\n    public static final int ENTRY_FIELD_NUMBER = 1;\n    private com.google.protobuf.Internal.ProtobufList<com.android.aapt.Resources.Plural.Entry> entry_;\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    public java.util.List<com.android.aapt.Resources.Plural.Entry> getEntryList() {\n      return entry_;\n    }\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    public java.util.List<? extends com.android.aapt.Resources.Plural.EntryOrBuilder> \n        getEntryOrBuilderList() {\n      return entry_;\n    }\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    public int getEntryCount() {\n      return entry_.size();\n    }\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    public com.android.aapt.Resources.Plural.Entry getEntry(int index) {\n      return entry_.get(index);\n    }\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    public com.android.aapt.Resources.Plural.EntryOrBuilder getEntryOrBuilder(\n        int index) {\n      return entry_.get(index);\n    }\n    private void ensureEntryIsMutable() {\n      if (!entry_.isModifiable()) {\n        entry_ =\n            com.google.protobuf.GeneratedMessageLite.mutableCopy(entry_);\n       }\n    }\n\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    private void setEntry(\n        int index, com.android.aapt.Resources.Plural.Entry value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureEntryIsMutable();\n      entry_.set(index, value);\n    }\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    private void setEntry(\n        int index, com.android.aapt.Resources.Plural.Entry.Builder builderForValue) {\n      ensureEntryIsMutable();\n      entry_.set(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    private void addEntry(com.android.aapt.Resources.Plural.Entry value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureEntryIsMutable();\n      entry_.add(value);\n    }\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    private void addEntry(\n        int index, com.android.aapt.Resources.Plural.Entry value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureEntryIsMutable();\n      entry_.add(index, value);\n    }\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    private void addEntry(\n        com.android.aapt.Resources.Plural.Entry.Builder builderForValue) {\n      ensureEntryIsMutable();\n      entry_.add(builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    private void addEntry(\n        int index, com.android.aapt.Resources.Plural.Entry.Builder builderForValue) {\n      ensureEntryIsMutable();\n      entry_.add(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    private void addAllEntry(\n        java.lang.Iterable<? extends com.android.aapt.Resources.Plural.Entry> values) {\n      ensureEntryIsMutable();\n      com.google.protobuf.AbstractMessageLite.addAll(\n          values, entry_);\n    }\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    private void clearEntry() {\n      entry_ = emptyProtobufList();\n    }\n    /**\n     * <pre>\n     * The set of arity/plural mappings.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n     */\n    private void removeEntry(int index) {\n      ensureEntryIsMutable();\n      entry_.remove(index);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      for (int i = 0; i < entry_.size(); i++) {\n        output.writeMessage(1, entry_.get(i));\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      for (int i = 0; i < entry_.size(); i++) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(1, entry_.get(i));\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.Plural parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Plural parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Plural parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.Plural parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Plural parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Plural parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Plural parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Plural parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.Plural parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.Plural parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.Plural prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A value that represents a string and its many variations based on plurality.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.Plural}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.Plural, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.Plural)\n        com.android.aapt.Resources.PluralOrBuilder {\n      // Construct using com.android.aapt.Resources.Plural.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * The set of arity/plural mappings.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n       */\n      public java.util.List<com.android.aapt.Resources.Plural.Entry> getEntryList() {\n        return java.util.Collections.unmodifiableList(\n            instance.getEntryList());\n      }\n      /**\n       * <pre>\n       * The set of arity/plural mappings.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n       */\n      public int getEntryCount() {\n        return instance.getEntryCount();\n      }/**\n       * <pre>\n       * The set of arity/plural mappings.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n       */\n      public com.android.aapt.Resources.Plural.Entry getEntry(int index) {\n        return instance.getEntry(index);\n      }\n      /**\n       * <pre>\n       * The set of arity/plural mappings.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n       */\n      public Builder setEntry(\n          int index, com.android.aapt.Resources.Plural.Entry value) {\n        copyOnWrite();\n        instance.setEntry(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of arity/plural mappings.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n       */\n      public Builder setEntry(\n          int index, com.android.aapt.Resources.Plural.Entry.Builder builderForValue) {\n        copyOnWrite();\n        instance.setEntry(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of arity/plural mappings.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n       */\n      public Builder addEntry(com.android.aapt.Resources.Plural.Entry value) {\n        copyOnWrite();\n        instance.addEntry(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of arity/plural mappings.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n       */\n      public Builder addEntry(\n          int index, com.android.aapt.Resources.Plural.Entry value) {\n        copyOnWrite();\n        instance.addEntry(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of arity/plural mappings.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n       */\n      public Builder addEntry(\n          com.android.aapt.Resources.Plural.Entry.Builder builderForValue) {\n        copyOnWrite();\n        instance.addEntry(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of arity/plural mappings.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n       */\n      public Builder addEntry(\n          int index, com.android.aapt.Resources.Plural.Entry.Builder builderForValue) {\n        copyOnWrite();\n        instance.addEntry(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of arity/plural mappings.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n       */\n      public Builder addAllEntry(\n          java.lang.Iterable<? extends com.android.aapt.Resources.Plural.Entry> values) {\n        copyOnWrite();\n        instance.addAllEntry(values);\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of arity/plural mappings.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n       */\n      public Builder clearEntry() {\n        copyOnWrite();\n        instance.clearEntry();\n        return this;\n      }\n      /**\n       * <pre>\n       * The set of arity/plural mappings.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.Plural.Entry entry = 1;</code>\n       */\n      public Builder removeEntry(int index) {\n        copyOnWrite();\n        instance.removeEntry(index);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.Plural)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.Plural();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          entry_.makeImmutable();\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.Plural other = (com.android.aapt.Resources.Plural) arg1;\n          entry_= visitor.visitList(entry_, other.entry_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  if (!entry_.isModifiable()) {\n                    entry_ =\n                        com.google.protobuf.GeneratedMessageLite.mutableCopy(entry_);\n                  }\n                  entry_.add(\n                      input.readMessage(com.android.aapt.Resources.Plural.Entry.parser(), extensionRegistry));\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.Plural.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.Plural)\n    private static final com.android.aapt.Resources.Plural DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new Plural();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.Plural getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<Plural> PARSER;\n\n    public static com.google.protobuf.Parser<Plural> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface XmlNodeOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.XmlNode)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * If set, this node is an element/tag.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.XmlElement element = 1;</code>\n     */\n    boolean hasElement();\n    /**\n     * <pre>\n     * If set, this node is an element/tag.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.XmlElement element = 1;</code>\n     */\n    com.android.aapt.Resources.XmlElement getElement();\n\n    /**\n     * <pre>\n     * If set, this node is a chunk of text.\n     * </pre>\n     *\n     * <code>optional string text = 2;</code>\n     */\n    boolean hasText();\n    /**\n     * <pre>\n     * If set, this node is a chunk of text.\n     * </pre>\n     *\n     * <code>optional string text = 2;</code>\n     */\n    java.lang.String getText();\n    /**\n     * <pre>\n     * If set, this node is a chunk of text.\n     * </pre>\n     *\n     * <code>optional string text = 2;</code>\n     */\n    com.google.protobuf.ByteString\n        getTextBytes();\n\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    boolean hasSource();\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    com.android.aapt.Resources.SourcePosition getSource();\n  }\n  /**\n   * <pre>\n   * Defines an abstract XmlNode that must be either an XmlElement, or\n   * a text node represented by a string.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.XmlNode}\n   */\n  public  static final class XmlNode extends\n      com.google.protobuf.GeneratedMessageLite<\n          XmlNode, XmlNode.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.XmlNode)\n      XmlNodeOrBuilder {\n    private XmlNode() {\n      text_ = \"\";\n    }\n    private int bitField0_;\n    public static final int ELEMENT_FIELD_NUMBER = 1;\n    private com.android.aapt.Resources.XmlElement element_;\n    /**\n     * <pre>\n     * If set, this node is an element/tag.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.XmlElement element = 1;</code>\n     */\n    public boolean hasElement() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <pre>\n     * If set, this node is an element/tag.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.XmlElement element = 1;</code>\n     */\n    public com.android.aapt.Resources.XmlElement getElement() {\n      return element_ == null ? com.android.aapt.Resources.XmlElement.getDefaultInstance() : element_;\n    }\n    /**\n     * <pre>\n     * If set, this node is an element/tag.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.XmlElement element = 1;</code>\n     */\n    private void setElement(com.android.aapt.Resources.XmlElement value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      element_ = value;\n      bitField0_ |= 0x00000001;\n      }\n    /**\n     * <pre>\n     * If set, this node is an element/tag.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.XmlElement element = 1;</code>\n     */\n    private void setElement(\n        com.android.aapt.Resources.XmlElement.Builder builderForValue) {\n      element_ = builderForValue.build();\n      bitField0_ |= 0x00000001;\n    }\n    /**\n     * <pre>\n     * If set, this node is an element/tag.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.XmlElement element = 1;</code>\n     */\n    private void mergeElement(com.android.aapt.Resources.XmlElement value) {\n      if (element_ != null &&\n          element_ != com.android.aapt.Resources.XmlElement.getDefaultInstance()) {\n        element_ =\n          com.android.aapt.Resources.XmlElement.newBuilder(element_).mergeFrom(value).buildPartial();\n      } else {\n        element_ = value;\n      }\n      bitField0_ |= 0x00000001;\n    }\n    /**\n     * <pre>\n     * If set, this node is an element/tag.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.XmlElement element = 1;</code>\n     */\n    private void clearElement() {  element_ = null;\n      bitField0_ = (bitField0_ & ~0x00000001);\n    }\n\n    public static final int TEXT_FIELD_NUMBER = 2;\n    private java.lang.String text_;\n    /**\n     * <pre>\n     * If set, this node is a chunk of text.\n     * </pre>\n     *\n     * <code>optional string text = 2;</code>\n     */\n    public boolean hasText() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <pre>\n     * If set, this node is a chunk of text.\n     * </pre>\n     *\n     * <code>optional string text = 2;</code>\n     */\n    public java.lang.String getText() {\n      return text_;\n    }\n    /**\n     * <pre>\n     * If set, this node is a chunk of text.\n     * </pre>\n     *\n     * <code>optional string text = 2;</code>\n     */\n    public com.google.protobuf.ByteString\n        getTextBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(text_);\n    }\n    /**\n     * <pre>\n     * If set, this node is a chunk of text.\n     * </pre>\n     *\n     * <code>optional string text = 2;</code>\n     */\n    private void setText(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      text_ = value;\n    }\n    /**\n     * <pre>\n     * If set, this node is a chunk of text.\n     * </pre>\n     *\n     * <code>optional string text = 2;</code>\n     */\n    private void clearText() {\n      bitField0_ = (bitField0_ & ~0x00000002);\n      text_ = getDefaultInstance().getText();\n    }\n    /**\n     * <pre>\n     * If set, this node is a chunk of text.\n     * </pre>\n     *\n     * <code>optional string text = 2;</code>\n     */\n    private void setTextBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      text_ = value.toStringUtf8();\n    }\n\n    public static final int SOURCE_FIELD_NUMBER = 3;\n    private com.android.aapt.Resources.SourcePosition source_;\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    public boolean hasSource() {\n      return ((bitField0_ & 0x00000004) == 0x00000004);\n    }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    public com.android.aapt.Resources.SourcePosition getSource() {\n      return source_ == null ? com.android.aapt.Resources.SourcePosition.getDefaultInstance() : source_;\n    }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    private void setSource(com.android.aapt.Resources.SourcePosition value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      source_ = value;\n      bitField0_ |= 0x00000004;\n      }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    private void setSource(\n        com.android.aapt.Resources.SourcePosition.Builder builderForValue) {\n      source_ = builderForValue.build();\n      bitField0_ |= 0x00000004;\n    }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    private void mergeSource(com.android.aapt.Resources.SourcePosition value) {\n      if (source_ != null &&\n          source_ != com.android.aapt.Resources.SourcePosition.getDefaultInstance()) {\n        source_ =\n          com.android.aapt.Resources.SourcePosition.newBuilder(source_).mergeFrom(value).buildPartial();\n      } else {\n        source_ = value;\n      }\n      bitField0_ |= 0x00000004;\n    }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    private void clearSource() {  source_ = null;\n      bitField0_ = (bitField0_ & ~0x00000004);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeMessage(1, getElement());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeString(2, getText());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        output.writeMessage(3, getSource());\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(1, getElement());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(2, getText());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(3, getSource());\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.XmlNode parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.XmlNode parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlNode parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.XmlNode parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlNode parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.XmlNode parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlNode parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.XmlNode parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlNode parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.XmlNode parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.XmlNode prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * Defines an abstract XmlNode that must be either an XmlElement, or\n     * a text node represented by a string.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.XmlNode}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.XmlNode, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.XmlNode)\n        com.android.aapt.Resources.XmlNodeOrBuilder {\n      // Construct using com.android.aapt.Resources.XmlNode.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * If set, this node is an element/tag.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.XmlElement element = 1;</code>\n       */\n      public boolean hasElement() {\n        return instance.hasElement();\n      }\n      /**\n       * <pre>\n       * If set, this node is an element/tag.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.XmlElement element = 1;</code>\n       */\n      public com.android.aapt.Resources.XmlElement getElement() {\n        return instance.getElement();\n      }\n      /**\n       * <pre>\n       * If set, this node is an element/tag.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.XmlElement element = 1;</code>\n       */\n      public Builder setElement(com.android.aapt.Resources.XmlElement value) {\n        copyOnWrite();\n        instance.setElement(value);\n        return this;\n        }\n      /**\n       * <pre>\n       * If set, this node is an element/tag.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.XmlElement element = 1;</code>\n       */\n      public Builder setElement(\n          com.android.aapt.Resources.XmlElement.Builder builderForValue) {\n        copyOnWrite();\n        instance.setElement(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * If set, this node is an element/tag.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.XmlElement element = 1;</code>\n       */\n      public Builder mergeElement(com.android.aapt.Resources.XmlElement value) {\n        copyOnWrite();\n        instance.mergeElement(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * If set, this node is an element/tag.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.XmlElement element = 1;</code>\n       */\n      public Builder clearElement() {  copyOnWrite();\n        instance.clearElement();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * If set, this node is a chunk of text.\n       * </pre>\n       *\n       * <code>optional string text = 2;</code>\n       */\n      public boolean hasText() {\n        return instance.hasText();\n      }\n      /**\n       * <pre>\n       * If set, this node is a chunk of text.\n       * </pre>\n       *\n       * <code>optional string text = 2;</code>\n       */\n      public java.lang.String getText() {\n        return instance.getText();\n      }\n      /**\n       * <pre>\n       * If set, this node is a chunk of text.\n       * </pre>\n       *\n       * <code>optional string text = 2;</code>\n       */\n      public com.google.protobuf.ByteString\n          getTextBytes() {\n        return instance.getTextBytes();\n      }\n      /**\n       * <pre>\n       * If set, this node is a chunk of text.\n       * </pre>\n       *\n       * <code>optional string text = 2;</code>\n       */\n      public Builder setText(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setText(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * If set, this node is a chunk of text.\n       * </pre>\n       *\n       * <code>optional string text = 2;</code>\n       */\n      public Builder clearText() {\n        copyOnWrite();\n        instance.clearText();\n        return this;\n      }\n      /**\n       * <pre>\n       * If set, this node is a chunk of text.\n       * </pre>\n       *\n       * <code>optional string text = 2;</code>\n       */\n      public Builder setTextBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setTextBytes(value);\n        return this;\n      }\n\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n       */\n      public boolean hasSource() {\n        return instance.hasSource();\n      }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n       */\n      public com.android.aapt.Resources.SourcePosition getSource() {\n        return instance.getSource();\n      }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n       */\n      public Builder setSource(com.android.aapt.Resources.SourcePosition value) {\n        copyOnWrite();\n        instance.setSource(value);\n        return this;\n        }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n       */\n      public Builder setSource(\n          com.android.aapt.Resources.SourcePosition.Builder builderForValue) {\n        copyOnWrite();\n        instance.setSource(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n       */\n      public Builder mergeSource(com.android.aapt.Resources.SourcePosition value) {\n        copyOnWrite();\n        instance.mergeSource(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n       */\n      public Builder clearSource() {  copyOnWrite();\n        instance.clearSource();\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.XmlNode)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.XmlNode();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.XmlNode other = (com.android.aapt.Resources.XmlNode) arg1;\n          element_ = visitor.visitMessage(element_, other.element_);\n          text_ = visitor.visitString(\n              hasText(), text_,\n              other.hasText(), other.text_);\n          source_ = visitor.visitMessage(source_, other.source_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  com.android.aapt.Resources.XmlElement.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000001) == 0x00000001)) {\n                    subBuilder = element_.toBuilder();\n                  }\n                  element_ = input.readMessage(com.android.aapt.Resources.XmlElement.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(element_);\n                    element_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000001;\n                  break;\n                }\n                case 18: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000002;\n                  text_ = s;\n                  break;\n                }\n                case 26: {\n                  com.android.aapt.Resources.SourcePosition.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000004) == 0x00000004)) {\n                    subBuilder = source_.toBuilder();\n                  }\n                  source_ = input.readMessage(com.android.aapt.Resources.SourcePosition.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(source_);\n                    source_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000004;\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.XmlNode.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.XmlNode)\n    private static final com.android.aapt.Resources.XmlNode DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new XmlNode();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.XmlNode getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<XmlNode> PARSER;\n\n    public static com.google.protobuf.Parser<XmlNode> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface XmlElementOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.XmlElement)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    java.util.List<com.android.aapt.Resources.XmlNamespace> \n        getNamespaceDeclarationList();\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    com.android.aapt.Resources.XmlNamespace getNamespaceDeclaration(int index);\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    int getNamespaceDeclarationCount();\n\n    /**\n     * <pre>\n     * The namespace URI of this element.\n     * </pre>\n     *\n     * <code>optional string namespace_uri = 2;</code>\n     */\n    boolean hasNamespaceUri();\n    /**\n     * <pre>\n     * The namespace URI of this element.\n     * </pre>\n     *\n     * <code>optional string namespace_uri = 2;</code>\n     */\n    java.lang.String getNamespaceUri();\n    /**\n     * <pre>\n     * The namespace URI of this element.\n     * </pre>\n     *\n     * <code>optional string namespace_uri = 2;</code>\n     */\n    com.google.protobuf.ByteString\n        getNamespaceUriBytes();\n\n    /**\n     * <pre>\n     * The name of this element.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    boolean hasName();\n    /**\n     * <pre>\n     * The name of this element.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    java.lang.String getName();\n    /**\n     * <pre>\n     * The name of this element.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    com.google.protobuf.ByteString\n        getNameBytes();\n\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    java.util.List<com.android.aapt.Resources.XmlAttribute> \n        getAttributeList();\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    com.android.aapt.Resources.XmlAttribute getAttribute(int index);\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    int getAttributeCount();\n\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    java.util.List<com.android.aapt.Resources.XmlNode> \n        getChildList();\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    com.android.aapt.Resources.XmlNode getChild(int index);\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    int getChildCount();\n  }\n  /**\n   * <pre>\n   * An &lt;element&gt; in an XML document.\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.XmlElement}\n   */\n  public  static final class XmlElement extends\n      com.google.protobuf.GeneratedMessageLite<\n          XmlElement, XmlElement.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.XmlElement)\n      XmlElementOrBuilder {\n    private XmlElement() {\n      namespaceDeclaration_ = emptyProtobufList();\n      namespaceUri_ = \"\";\n      name_ = \"\";\n      attribute_ = emptyProtobufList();\n      child_ = emptyProtobufList();\n    }\n    private int bitField0_;\n    public static final int NAMESPACE_DECLARATION_FIELD_NUMBER = 1;\n    private com.google.protobuf.Internal.ProtobufList<com.android.aapt.Resources.XmlNamespace> namespaceDeclaration_;\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    public java.util.List<com.android.aapt.Resources.XmlNamespace> getNamespaceDeclarationList() {\n      return namespaceDeclaration_;\n    }\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    public java.util.List<? extends com.android.aapt.Resources.XmlNamespaceOrBuilder> \n        getNamespaceDeclarationOrBuilderList() {\n      return namespaceDeclaration_;\n    }\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    public int getNamespaceDeclarationCount() {\n      return namespaceDeclaration_.size();\n    }\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    public com.android.aapt.Resources.XmlNamespace getNamespaceDeclaration(int index) {\n      return namespaceDeclaration_.get(index);\n    }\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    public com.android.aapt.Resources.XmlNamespaceOrBuilder getNamespaceDeclarationOrBuilder(\n        int index) {\n      return namespaceDeclaration_.get(index);\n    }\n    private void ensureNamespaceDeclarationIsMutable() {\n      if (!namespaceDeclaration_.isModifiable()) {\n        namespaceDeclaration_ =\n            com.google.protobuf.GeneratedMessageLite.mutableCopy(namespaceDeclaration_);\n       }\n    }\n\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    private void setNamespaceDeclaration(\n        int index, com.android.aapt.Resources.XmlNamespace value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureNamespaceDeclarationIsMutable();\n      namespaceDeclaration_.set(index, value);\n    }\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    private void setNamespaceDeclaration(\n        int index, com.android.aapt.Resources.XmlNamespace.Builder builderForValue) {\n      ensureNamespaceDeclarationIsMutable();\n      namespaceDeclaration_.set(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    private void addNamespaceDeclaration(com.android.aapt.Resources.XmlNamespace value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureNamespaceDeclarationIsMutable();\n      namespaceDeclaration_.add(value);\n    }\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    private void addNamespaceDeclaration(\n        int index, com.android.aapt.Resources.XmlNamespace value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureNamespaceDeclarationIsMutable();\n      namespaceDeclaration_.add(index, value);\n    }\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    private void addNamespaceDeclaration(\n        com.android.aapt.Resources.XmlNamespace.Builder builderForValue) {\n      ensureNamespaceDeclarationIsMutable();\n      namespaceDeclaration_.add(builderForValue.build());\n    }\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    private void addNamespaceDeclaration(\n        int index, com.android.aapt.Resources.XmlNamespace.Builder builderForValue) {\n      ensureNamespaceDeclarationIsMutable();\n      namespaceDeclaration_.add(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    private void addAllNamespaceDeclaration(\n        java.lang.Iterable<? extends com.android.aapt.Resources.XmlNamespace> values) {\n      ensureNamespaceDeclarationIsMutable();\n      com.google.protobuf.AbstractMessageLite.addAll(\n          values, namespaceDeclaration_);\n    }\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    private void clearNamespaceDeclaration() {\n      namespaceDeclaration_ = emptyProtobufList();\n    }\n    /**\n     * <pre>\n     * Namespaces defined on this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n     */\n    private void removeNamespaceDeclaration(int index) {\n      ensureNamespaceDeclarationIsMutable();\n      namespaceDeclaration_.remove(index);\n    }\n\n    public static final int NAMESPACE_URI_FIELD_NUMBER = 2;\n    private java.lang.String namespaceUri_;\n    /**\n     * <pre>\n     * The namespace URI of this element.\n     * </pre>\n     *\n     * <code>optional string namespace_uri = 2;</code>\n     */\n    public boolean hasNamespaceUri() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <pre>\n     * The namespace URI of this element.\n     * </pre>\n     *\n     * <code>optional string namespace_uri = 2;</code>\n     */\n    public java.lang.String getNamespaceUri() {\n      return namespaceUri_;\n    }\n    /**\n     * <pre>\n     * The namespace URI of this element.\n     * </pre>\n     *\n     * <code>optional string namespace_uri = 2;</code>\n     */\n    public com.google.protobuf.ByteString\n        getNamespaceUriBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(namespaceUri_);\n    }\n    /**\n     * <pre>\n     * The namespace URI of this element.\n     * </pre>\n     *\n     * <code>optional string namespace_uri = 2;</code>\n     */\n    private void setNamespaceUri(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      namespaceUri_ = value;\n    }\n    /**\n     * <pre>\n     * The namespace URI of this element.\n     * </pre>\n     *\n     * <code>optional string namespace_uri = 2;</code>\n     */\n    private void clearNamespaceUri() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      namespaceUri_ = getDefaultInstance().getNamespaceUri();\n    }\n    /**\n     * <pre>\n     * The namespace URI of this element.\n     * </pre>\n     *\n     * <code>optional string namespace_uri = 2;</code>\n     */\n    private void setNamespaceUriBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      namespaceUri_ = value.toStringUtf8();\n    }\n\n    public static final int NAME_FIELD_NUMBER = 3;\n    private java.lang.String name_;\n    /**\n     * <pre>\n     * The name of this element.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    public boolean hasName() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <pre>\n     * The name of this element.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    public java.lang.String getName() {\n      return name_;\n    }\n    /**\n     * <pre>\n     * The name of this element.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    public com.google.protobuf.ByteString\n        getNameBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(name_);\n    }\n    /**\n     * <pre>\n     * The name of this element.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    private void setName(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      name_ = value;\n    }\n    /**\n     * <pre>\n     * The name of this element.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    private void clearName() {\n      bitField0_ = (bitField0_ & ~0x00000002);\n      name_ = getDefaultInstance().getName();\n    }\n    /**\n     * <pre>\n     * The name of this element.\n     * </pre>\n     *\n     * <code>optional string name = 3;</code>\n     */\n    private void setNameBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      name_ = value.toStringUtf8();\n    }\n\n    public static final int ATTRIBUTE_FIELD_NUMBER = 4;\n    private com.google.protobuf.Internal.ProtobufList<com.android.aapt.Resources.XmlAttribute> attribute_;\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    public java.util.List<com.android.aapt.Resources.XmlAttribute> getAttributeList() {\n      return attribute_;\n    }\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    public java.util.List<? extends com.android.aapt.Resources.XmlAttributeOrBuilder> \n        getAttributeOrBuilderList() {\n      return attribute_;\n    }\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    public int getAttributeCount() {\n      return attribute_.size();\n    }\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    public com.android.aapt.Resources.XmlAttribute getAttribute(int index) {\n      return attribute_.get(index);\n    }\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    public com.android.aapt.Resources.XmlAttributeOrBuilder getAttributeOrBuilder(\n        int index) {\n      return attribute_.get(index);\n    }\n    private void ensureAttributeIsMutable() {\n      if (!attribute_.isModifiable()) {\n        attribute_ =\n            com.google.protobuf.GeneratedMessageLite.mutableCopy(attribute_);\n       }\n    }\n\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    private void setAttribute(\n        int index, com.android.aapt.Resources.XmlAttribute value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureAttributeIsMutable();\n      attribute_.set(index, value);\n    }\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    private void setAttribute(\n        int index, com.android.aapt.Resources.XmlAttribute.Builder builderForValue) {\n      ensureAttributeIsMutable();\n      attribute_.set(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    private void addAttribute(com.android.aapt.Resources.XmlAttribute value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureAttributeIsMutable();\n      attribute_.add(value);\n    }\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    private void addAttribute(\n        int index, com.android.aapt.Resources.XmlAttribute value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureAttributeIsMutable();\n      attribute_.add(index, value);\n    }\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    private void addAttribute(\n        com.android.aapt.Resources.XmlAttribute.Builder builderForValue) {\n      ensureAttributeIsMutable();\n      attribute_.add(builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    private void addAttribute(\n        int index, com.android.aapt.Resources.XmlAttribute.Builder builderForValue) {\n      ensureAttributeIsMutable();\n      attribute_.add(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    private void addAllAttribute(\n        java.lang.Iterable<? extends com.android.aapt.Resources.XmlAttribute> values) {\n      ensureAttributeIsMutable();\n      com.google.protobuf.AbstractMessageLite.addAll(\n          values, attribute_);\n    }\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    private void clearAttribute() {\n      attribute_ = emptyProtobufList();\n    }\n    /**\n     * <pre>\n     * The attributes of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n     */\n    private void removeAttribute(int index) {\n      ensureAttributeIsMutable();\n      attribute_.remove(index);\n    }\n\n    public static final int CHILD_FIELD_NUMBER = 5;\n    private com.google.protobuf.Internal.ProtobufList<com.android.aapt.Resources.XmlNode> child_;\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    public java.util.List<com.android.aapt.Resources.XmlNode> getChildList() {\n      return child_;\n    }\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    public java.util.List<? extends com.android.aapt.Resources.XmlNodeOrBuilder> \n        getChildOrBuilderList() {\n      return child_;\n    }\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    public int getChildCount() {\n      return child_.size();\n    }\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    public com.android.aapt.Resources.XmlNode getChild(int index) {\n      return child_.get(index);\n    }\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    public com.android.aapt.Resources.XmlNodeOrBuilder getChildOrBuilder(\n        int index) {\n      return child_.get(index);\n    }\n    private void ensureChildIsMutable() {\n      if (!child_.isModifiable()) {\n        child_ =\n            com.google.protobuf.GeneratedMessageLite.mutableCopy(child_);\n       }\n    }\n\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    private void setChild(\n        int index, com.android.aapt.Resources.XmlNode value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureChildIsMutable();\n      child_.set(index, value);\n    }\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    private void setChild(\n        int index, com.android.aapt.Resources.XmlNode.Builder builderForValue) {\n      ensureChildIsMutable();\n      child_.set(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    private void addChild(com.android.aapt.Resources.XmlNode value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureChildIsMutable();\n      child_.add(value);\n    }\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    private void addChild(\n        int index, com.android.aapt.Resources.XmlNode value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      ensureChildIsMutable();\n      child_.add(index, value);\n    }\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    private void addChild(\n        com.android.aapt.Resources.XmlNode.Builder builderForValue) {\n      ensureChildIsMutable();\n      child_.add(builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    private void addChild(\n        int index, com.android.aapt.Resources.XmlNode.Builder builderForValue) {\n      ensureChildIsMutable();\n      child_.add(index, builderForValue.build());\n    }\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    private void addAllChild(\n        java.lang.Iterable<? extends com.android.aapt.Resources.XmlNode> values) {\n      ensureChildIsMutable();\n      com.google.protobuf.AbstractMessageLite.addAll(\n          values, child_);\n    }\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    private void clearChild() {\n      child_ = emptyProtobufList();\n    }\n    /**\n     * <pre>\n     * The children of this element.\n     * </pre>\n     *\n     * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n     */\n    private void removeChild(int index) {\n      ensureChildIsMutable();\n      child_.remove(index);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      for (int i = 0; i < namespaceDeclaration_.size(); i++) {\n        output.writeMessage(1, namespaceDeclaration_.get(i));\n      }\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeString(2, getNamespaceUri());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeString(3, getName());\n      }\n      for (int i = 0; i < attribute_.size(); i++) {\n        output.writeMessage(4, attribute_.get(i));\n      }\n      for (int i = 0; i < child_.size(); i++) {\n        output.writeMessage(5, child_.get(i));\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      for (int i = 0; i < namespaceDeclaration_.size(); i++) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(1, namespaceDeclaration_.get(i));\n      }\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(2, getNamespaceUri());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(3, getName());\n      }\n      for (int i = 0; i < attribute_.size(); i++) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(4, attribute_.get(i));\n      }\n      for (int i = 0; i < child_.size(); i++) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(5, child_.get(i));\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.XmlElement parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.XmlElement parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlElement parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.XmlElement parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlElement parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.XmlElement parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlElement parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.XmlElement parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlElement parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.XmlElement parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.XmlElement prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * An &lt;element&gt; in an XML document.\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.XmlElement}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.XmlElement, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.XmlElement)\n        com.android.aapt.Resources.XmlElementOrBuilder {\n      // Construct using com.android.aapt.Resources.XmlElement.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <pre>\n       * Namespaces defined on this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n       */\n      public java.util.List<com.android.aapt.Resources.XmlNamespace> getNamespaceDeclarationList() {\n        return java.util.Collections.unmodifiableList(\n            instance.getNamespaceDeclarationList());\n      }\n      /**\n       * <pre>\n       * Namespaces defined on this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n       */\n      public int getNamespaceDeclarationCount() {\n        return instance.getNamespaceDeclarationCount();\n      }/**\n       * <pre>\n       * Namespaces defined on this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n       */\n      public com.android.aapt.Resources.XmlNamespace getNamespaceDeclaration(int index) {\n        return instance.getNamespaceDeclaration(index);\n      }\n      /**\n       * <pre>\n       * Namespaces defined on this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n       */\n      public Builder setNamespaceDeclaration(\n          int index, com.android.aapt.Resources.XmlNamespace value) {\n        copyOnWrite();\n        instance.setNamespaceDeclaration(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Namespaces defined on this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n       */\n      public Builder setNamespaceDeclaration(\n          int index, com.android.aapt.Resources.XmlNamespace.Builder builderForValue) {\n        copyOnWrite();\n        instance.setNamespaceDeclaration(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * Namespaces defined on this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n       */\n      public Builder addNamespaceDeclaration(com.android.aapt.Resources.XmlNamespace value) {\n        copyOnWrite();\n        instance.addNamespaceDeclaration(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Namespaces defined on this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n       */\n      public Builder addNamespaceDeclaration(\n          int index, com.android.aapt.Resources.XmlNamespace value) {\n        copyOnWrite();\n        instance.addNamespaceDeclaration(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Namespaces defined on this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n       */\n      public Builder addNamespaceDeclaration(\n          com.android.aapt.Resources.XmlNamespace.Builder builderForValue) {\n        copyOnWrite();\n        instance.addNamespaceDeclaration(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * Namespaces defined on this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n       */\n      public Builder addNamespaceDeclaration(\n          int index, com.android.aapt.Resources.XmlNamespace.Builder builderForValue) {\n        copyOnWrite();\n        instance.addNamespaceDeclaration(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * Namespaces defined on this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n       */\n      public Builder addAllNamespaceDeclaration(\n          java.lang.Iterable<? extends com.android.aapt.Resources.XmlNamespace> values) {\n        copyOnWrite();\n        instance.addAllNamespaceDeclaration(values);\n        return this;\n      }\n      /**\n       * <pre>\n       * Namespaces defined on this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n       */\n      public Builder clearNamespaceDeclaration() {\n        copyOnWrite();\n        instance.clearNamespaceDeclaration();\n        return this;\n      }\n      /**\n       * <pre>\n       * Namespaces defined on this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNamespace namespace_declaration = 1;</code>\n       */\n      public Builder removeNamespaceDeclaration(int index) {\n        copyOnWrite();\n        instance.removeNamespaceDeclaration(index);\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The namespace URI of this element.\n       * </pre>\n       *\n       * <code>optional string namespace_uri = 2;</code>\n       */\n      public boolean hasNamespaceUri() {\n        return instance.hasNamespaceUri();\n      }\n      /**\n       * <pre>\n       * The namespace URI of this element.\n       * </pre>\n       *\n       * <code>optional string namespace_uri = 2;</code>\n       */\n      public java.lang.String getNamespaceUri() {\n        return instance.getNamespaceUri();\n      }\n      /**\n       * <pre>\n       * The namespace URI of this element.\n       * </pre>\n       *\n       * <code>optional string namespace_uri = 2;</code>\n       */\n      public com.google.protobuf.ByteString\n          getNamespaceUriBytes() {\n        return instance.getNamespaceUriBytes();\n      }\n      /**\n       * <pre>\n       * The namespace URI of this element.\n       * </pre>\n       *\n       * <code>optional string namespace_uri = 2;</code>\n       */\n      public Builder setNamespaceUri(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setNamespaceUri(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The namespace URI of this element.\n       * </pre>\n       *\n       * <code>optional string namespace_uri = 2;</code>\n       */\n      public Builder clearNamespaceUri() {\n        copyOnWrite();\n        instance.clearNamespaceUri();\n        return this;\n      }\n      /**\n       * <pre>\n       * The namespace URI of this element.\n       * </pre>\n       *\n       * <code>optional string namespace_uri = 2;</code>\n       */\n      public Builder setNamespaceUriBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setNamespaceUriBytes(value);\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The name of this element.\n       * </pre>\n       *\n       * <code>optional string name = 3;</code>\n       */\n      public boolean hasName() {\n        return instance.hasName();\n      }\n      /**\n       * <pre>\n       * The name of this element.\n       * </pre>\n       *\n       * <code>optional string name = 3;</code>\n       */\n      public java.lang.String getName() {\n        return instance.getName();\n      }\n      /**\n       * <pre>\n       * The name of this element.\n       * </pre>\n       *\n       * <code>optional string name = 3;</code>\n       */\n      public com.google.protobuf.ByteString\n          getNameBytes() {\n        return instance.getNameBytes();\n      }\n      /**\n       * <pre>\n       * The name of this element.\n       * </pre>\n       *\n       * <code>optional string name = 3;</code>\n       */\n      public Builder setName(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setName(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The name of this element.\n       * </pre>\n       *\n       * <code>optional string name = 3;</code>\n       */\n      public Builder clearName() {\n        copyOnWrite();\n        instance.clearName();\n        return this;\n      }\n      /**\n       * <pre>\n       * The name of this element.\n       * </pre>\n       *\n       * <code>optional string name = 3;</code>\n       */\n      public Builder setNameBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setNameBytes(value);\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The attributes of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n       */\n      public java.util.List<com.android.aapt.Resources.XmlAttribute> getAttributeList() {\n        return java.util.Collections.unmodifiableList(\n            instance.getAttributeList());\n      }\n      /**\n       * <pre>\n       * The attributes of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n       */\n      public int getAttributeCount() {\n        return instance.getAttributeCount();\n      }/**\n       * <pre>\n       * The attributes of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n       */\n      public com.android.aapt.Resources.XmlAttribute getAttribute(int index) {\n        return instance.getAttribute(index);\n      }\n      /**\n       * <pre>\n       * The attributes of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n       */\n      public Builder setAttribute(\n          int index, com.android.aapt.Resources.XmlAttribute value) {\n        copyOnWrite();\n        instance.setAttribute(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The attributes of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n       */\n      public Builder setAttribute(\n          int index, com.android.aapt.Resources.XmlAttribute.Builder builderForValue) {\n        copyOnWrite();\n        instance.setAttribute(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The attributes of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n       */\n      public Builder addAttribute(com.android.aapt.Resources.XmlAttribute value) {\n        copyOnWrite();\n        instance.addAttribute(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The attributes of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n       */\n      public Builder addAttribute(\n          int index, com.android.aapt.Resources.XmlAttribute value) {\n        copyOnWrite();\n        instance.addAttribute(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The attributes of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n       */\n      public Builder addAttribute(\n          com.android.aapt.Resources.XmlAttribute.Builder builderForValue) {\n        copyOnWrite();\n        instance.addAttribute(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The attributes of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n       */\n      public Builder addAttribute(\n          int index, com.android.aapt.Resources.XmlAttribute.Builder builderForValue) {\n        copyOnWrite();\n        instance.addAttribute(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The attributes of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n       */\n      public Builder addAllAttribute(\n          java.lang.Iterable<? extends com.android.aapt.Resources.XmlAttribute> values) {\n        copyOnWrite();\n        instance.addAllAttribute(values);\n        return this;\n      }\n      /**\n       * <pre>\n       * The attributes of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n       */\n      public Builder clearAttribute() {\n        copyOnWrite();\n        instance.clearAttribute();\n        return this;\n      }\n      /**\n       * <pre>\n       * The attributes of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlAttribute attribute = 4;</code>\n       */\n      public Builder removeAttribute(int index) {\n        copyOnWrite();\n        instance.removeAttribute(index);\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The children of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n       */\n      public java.util.List<com.android.aapt.Resources.XmlNode> getChildList() {\n        return java.util.Collections.unmodifiableList(\n            instance.getChildList());\n      }\n      /**\n       * <pre>\n       * The children of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n       */\n      public int getChildCount() {\n        return instance.getChildCount();\n      }/**\n       * <pre>\n       * The children of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n       */\n      public com.android.aapt.Resources.XmlNode getChild(int index) {\n        return instance.getChild(index);\n      }\n      /**\n       * <pre>\n       * The children of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n       */\n      public Builder setChild(\n          int index, com.android.aapt.Resources.XmlNode value) {\n        copyOnWrite();\n        instance.setChild(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The children of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n       */\n      public Builder setChild(\n          int index, com.android.aapt.Resources.XmlNode.Builder builderForValue) {\n        copyOnWrite();\n        instance.setChild(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The children of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n       */\n      public Builder addChild(com.android.aapt.Resources.XmlNode value) {\n        copyOnWrite();\n        instance.addChild(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The children of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n       */\n      public Builder addChild(\n          int index, com.android.aapt.Resources.XmlNode value) {\n        copyOnWrite();\n        instance.addChild(index, value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The children of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n       */\n      public Builder addChild(\n          com.android.aapt.Resources.XmlNode.Builder builderForValue) {\n        copyOnWrite();\n        instance.addChild(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The children of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n       */\n      public Builder addChild(\n          int index, com.android.aapt.Resources.XmlNode.Builder builderForValue) {\n        copyOnWrite();\n        instance.addChild(index, builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The children of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n       */\n      public Builder addAllChild(\n          java.lang.Iterable<? extends com.android.aapt.Resources.XmlNode> values) {\n        copyOnWrite();\n        instance.addAllChild(values);\n        return this;\n      }\n      /**\n       * <pre>\n       * The children of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n       */\n      public Builder clearChild() {\n        copyOnWrite();\n        instance.clearChild();\n        return this;\n      }\n      /**\n       * <pre>\n       * The children of this element.\n       * </pre>\n       *\n       * <code>repeated .aapt.pb.XmlNode child = 5;</code>\n       */\n      public Builder removeChild(int index) {\n        copyOnWrite();\n        instance.removeChild(index);\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.XmlElement)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.XmlElement();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          namespaceDeclaration_.makeImmutable();\n          attribute_.makeImmutable();\n          child_.makeImmutable();\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.XmlElement other = (com.android.aapt.Resources.XmlElement) arg1;\n          namespaceDeclaration_= visitor.visitList(namespaceDeclaration_, other.namespaceDeclaration_);\n          namespaceUri_ = visitor.visitString(\n              hasNamespaceUri(), namespaceUri_,\n              other.hasNamespaceUri(), other.namespaceUri_);\n          name_ = visitor.visitString(\n              hasName(), name_,\n              other.hasName(), other.name_);\n          attribute_= visitor.visitList(attribute_, other.attribute_);\n          child_= visitor.visitList(child_, other.child_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  if (!namespaceDeclaration_.isModifiable()) {\n                    namespaceDeclaration_ =\n                        com.google.protobuf.GeneratedMessageLite.mutableCopy(namespaceDeclaration_);\n                  }\n                  namespaceDeclaration_.add(\n                      input.readMessage(com.android.aapt.Resources.XmlNamespace.parser(), extensionRegistry));\n                  break;\n                }\n                case 18: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000001;\n                  namespaceUri_ = s;\n                  break;\n                }\n                case 26: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000002;\n                  name_ = s;\n                  break;\n                }\n                case 34: {\n                  if (!attribute_.isModifiable()) {\n                    attribute_ =\n                        com.google.protobuf.GeneratedMessageLite.mutableCopy(attribute_);\n                  }\n                  attribute_.add(\n                      input.readMessage(com.android.aapt.Resources.XmlAttribute.parser(), extensionRegistry));\n                  break;\n                }\n                case 42: {\n                  if (!child_.isModifiable()) {\n                    child_ =\n                        com.google.protobuf.GeneratedMessageLite.mutableCopy(child_);\n                  }\n                  child_.add(\n                      input.readMessage(com.android.aapt.Resources.XmlNode.parser(), extensionRegistry));\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.XmlElement.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.XmlElement)\n    private static final com.android.aapt.Resources.XmlElement DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new XmlElement();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.XmlElement getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<XmlElement> PARSER;\n\n    public static com.google.protobuf.Parser<XmlElement> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface XmlNamespaceOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.XmlNamespace)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <code>optional string prefix = 1;</code>\n     */\n    boolean hasPrefix();\n    /**\n     * <code>optional string prefix = 1;</code>\n     */\n    java.lang.String getPrefix();\n    /**\n     * <code>optional string prefix = 1;</code>\n     */\n    com.google.protobuf.ByteString\n        getPrefixBytes();\n\n    /**\n     * <code>optional string uri = 2;</code>\n     */\n    boolean hasUri();\n    /**\n     * <code>optional string uri = 2;</code>\n     */\n    java.lang.String getUri();\n    /**\n     * <code>optional string uri = 2;</code>\n     */\n    com.google.protobuf.ByteString\n        getUriBytes();\n\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    boolean hasSource();\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    com.android.aapt.Resources.SourcePosition getSource();\n  }\n  /**\n   * <pre>\n   * A namespace declaration on an XmlElement (xmlns:android=\"http://...\").\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.XmlNamespace}\n   */\n  public  static final class XmlNamespace extends\n      com.google.protobuf.GeneratedMessageLite<\n          XmlNamespace, XmlNamespace.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.XmlNamespace)\n      XmlNamespaceOrBuilder {\n    private XmlNamespace() {\n      prefix_ = \"\";\n      uri_ = \"\";\n    }\n    private int bitField0_;\n    public static final int PREFIX_FIELD_NUMBER = 1;\n    private java.lang.String prefix_;\n    /**\n     * <code>optional string prefix = 1;</code>\n     */\n    public boolean hasPrefix() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <code>optional string prefix = 1;</code>\n     */\n    public java.lang.String getPrefix() {\n      return prefix_;\n    }\n    /**\n     * <code>optional string prefix = 1;</code>\n     */\n    public com.google.protobuf.ByteString\n        getPrefixBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(prefix_);\n    }\n    /**\n     * <code>optional string prefix = 1;</code>\n     */\n    private void setPrefix(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      prefix_ = value;\n    }\n    /**\n     * <code>optional string prefix = 1;</code>\n     */\n    private void clearPrefix() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      prefix_ = getDefaultInstance().getPrefix();\n    }\n    /**\n     * <code>optional string prefix = 1;</code>\n     */\n    private void setPrefixBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      prefix_ = value.toStringUtf8();\n    }\n\n    public static final int URI_FIELD_NUMBER = 2;\n    private java.lang.String uri_;\n    /**\n     * <code>optional string uri = 2;</code>\n     */\n    public boolean hasUri() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <code>optional string uri = 2;</code>\n     */\n    public java.lang.String getUri() {\n      return uri_;\n    }\n    /**\n     * <code>optional string uri = 2;</code>\n     */\n    public com.google.protobuf.ByteString\n        getUriBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(uri_);\n    }\n    /**\n     * <code>optional string uri = 2;</code>\n     */\n    private void setUri(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      uri_ = value;\n    }\n    /**\n     * <code>optional string uri = 2;</code>\n     */\n    private void clearUri() {\n      bitField0_ = (bitField0_ & ~0x00000002);\n      uri_ = getDefaultInstance().getUri();\n    }\n    /**\n     * <code>optional string uri = 2;</code>\n     */\n    private void setUriBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      uri_ = value.toStringUtf8();\n    }\n\n    public static final int SOURCE_FIELD_NUMBER = 3;\n    private com.android.aapt.Resources.SourcePosition source_;\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    public boolean hasSource() {\n      return ((bitField0_ & 0x00000004) == 0x00000004);\n    }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    public com.android.aapt.Resources.SourcePosition getSource() {\n      return source_ == null ? com.android.aapt.Resources.SourcePosition.getDefaultInstance() : source_;\n    }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    private void setSource(com.android.aapt.Resources.SourcePosition value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      source_ = value;\n      bitField0_ |= 0x00000004;\n      }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    private void setSource(\n        com.android.aapt.Resources.SourcePosition.Builder builderForValue) {\n      source_ = builderForValue.build();\n      bitField0_ |= 0x00000004;\n    }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    private void mergeSource(com.android.aapt.Resources.SourcePosition value) {\n      if (source_ != null &&\n          source_ != com.android.aapt.Resources.SourcePosition.getDefaultInstance()) {\n        source_ =\n          com.android.aapt.Resources.SourcePosition.newBuilder(source_).mergeFrom(value).buildPartial();\n      } else {\n        source_ = value;\n      }\n      bitField0_ |= 0x00000004;\n    }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n     */\n    private void clearSource() {  source_ = null;\n      bitField0_ = (bitField0_ & ~0x00000004);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeString(1, getPrefix());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeString(2, getUri());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        output.writeMessage(3, getSource());\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(1, getPrefix());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(2, getUri());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(3, getSource());\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.XmlNamespace parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.XmlNamespace parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlNamespace parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.XmlNamespace parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlNamespace parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.XmlNamespace parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlNamespace parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.XmlNamespace parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlNamespace parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.XmlNamespace parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.XmlNamespace prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * A namespace declaration on an XmlElement (xmlns:android=\"http://...\").\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.XmlNamespace}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.XmlNamespace, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.XmlNamespace)\n        com.android.aapt.Resources.XmlNamespaceOrBuilder {\n      // Construct using com.android.aapt.Resources.XmlNamespace.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <code>optional string prefix = 1;</code>\n       */\n      public boolean hasPrefix() {\n        return instance.hasPrefix();\n      }\n      /**\n       * <code>optional string prefix = 1;</code>\n       */\n      public java.lang.String getPrefix() {\n        return instance.getPrefix();\n      }\n      /**\n       * <code>optional string prefix = 1;</code>\n       */\n      public com.google.protobuf.ByteString\n          getPrefixBytes() {\n        return instance.getPrefixBytes();\n      }\n      /**\n       * <code>optional string prefix = 1;</code>\n       */\n      public Builder setPrefix(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setPrefix(value);\n        return this;\n      }\n      /**\n       * <code>optional string prefix = 1;</code>\n       */\n      public Builder clearPrefix() {\n        copyOnWrite();\n        instance.clearPrefix();\n        return this;\n      }\n      /**\n       * <code>optional string prefix = 1;</code>\n       */\n      public Builder setPrefixBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setPrefixBytes(value);\n        return this;\n      }\n\n      /**\n       * <code>optional string uri = 2;</code>\n       */\n      public boolean hasUri() {\n        return instance.hasUri();\n      }\n      /**\n       * <code>optional string uri = 2;</code>\n       */\n      public java.lang.String getUri() {\n        return instance.getUri();\n      }\n      /**\n       * <code>optional string uri = 2;</code>\n       */\n      public com.google.protobuf.ByteString\n          getUriBytes() {\n        return instance.getUriBytes();\n      }\n      /**\n       * <code>optional string uri = 2;</code>\n       */\n      public Builder setUri(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setUri(value);\n        return this;\n      }\n      /**\n       * <code>optional string uri = 2;</code>\n       */\n      public Builder clearUri() {\n        copyOnWrite();\n        instance.clearUri();\n        return this;\n      }\n      /**\n       * <code>optional string uri = 2;</code>\n       */\n      public Builder setUriBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setUriBytes(value);\n        return this;\n      }\n\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n       */\n      public boolean hasSource() {\n        return instance.hasSource();\n      }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n       */\n      public com.android.aapt.Resources.SourcePosition getSource() {\n        return instance.getSource();\n      }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n       */\n      public Builder setSource(com.android.aapt.Resources.SourcePosition value) {\n        copyOnWrite();\n        instance.setSource(value);\n        return this;\n        }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n       */\n      public Builder setSource(\n          com.android.aapt.Resources.SourcePosition.Builder builderForValue) {\n        copyOnWrite();\n        instance.setSource(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n       */\n      public Builder mergeSource(com.android.aapt.Resources.SourcePosition value) {\n        copyOnWrite();\n        instance.mergeSource(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 3;</code>\n       */\n      public Builder clearSource() {  copyOnWrite();\n        instance.clearSource();\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.XmlNamespace)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.XmlNamespace();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.XmlNamespace other = (com.android.aapt.Resources.XmlNamespace) arg1;\n          prefix_ = visitor.visitString(\n              hasPrefix(), prefix_,\n              other.hasPrefix(), other.prefix_);\n          uri_ = visitor.visitString(\n              hasUri(), uri_,\n              other.hasUri(), other.uri_);\n          source_ = visitor.visitMessage(source_, other.source_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000001;\n                  prefix_ = s;\n                  break;\n                }\n                case 18: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000002;\n                  uri_ = s;\n                  break;\n                }\n                case 26: {\n                  com.android.aapt.Resources.SourcePosition.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000004) == 0x00000004)) {\n                    subBuilder = source_.toBuilder();\n                  }\n                  source_ = input.readMessage(com.android.aapt.Resources.SourcePosition.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(source_);\n                    source_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000004;\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.XmlNamespace.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.XmlNamespace)\n    private static final com.android.aapt.Resources.XmlNamespace DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new XmlNamespace();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.XmlNamespace getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<XmlNamespace> PARSER;\n\n    public static com.google.protobuf.Parser<XmlNamespace> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n  public interface XmlAttributeOrBuilder extends\n      // @@protoc_insertion_point(interface_extends:aapt.pb.XmlAttribute)\n      com.google.protobuf.MessageLiteOrBuilder {\n\n    /**\n     * <code>optional string namespace_uri = 1;</code>\n     */\n    boolean hasNamespaceUri();\n    /**\n     * <code>optional string namespace_uri = 1;</code>\n     */\n    java.lang.String getNamespaceUri();\n    /**\n     * <code>optional string namespace_uri = 1;</code>\n     */\n    com.google.protobuf.ByteString\n        getNamespaceUriBytes();\n\n    /**\n     * <code>optional string name = 2;</code>\n     */\n    boolean hasName();\n    /**\n     * <code>optional string name = 2;</code>\n     */\n    java.lang.String getName();\n    /**\n     * <code>optional string name = 2;</code>\n     */\n    com.google.protobuf.ByteString\n        getNameBytes();\n\n    /**\n     * <code>optional string value = 3;</code>\n     */\n    boolean hasValue();\n    /**\n     * <code>optional string value = 3;</code>\n     */\n    java.lang.String getValue();\n    /**\n     * <code>optional string value = 3;</code>\n     */\n    com.google.protobuf.ByteString\n        getValueBytes();\n\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 4;</code>\n     */\n    boolean hasSource();\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 4;</code>\n     */\n    com.android.aapt.Resources.SourcePosition getSource();\n\n    /**\n     * <pre>\n     * The resource ID (0xPPTTEEEE) of the attribute.\n     * </pre>\n     *\n     * <code>optional uint32 resource_id = 5;</code>\n     */\n    boolean hasResourceId();\n    /**\n     * <pre>\n     * The resource ID (0xPPTTEEEE) of the attribute.\n     * </pre>\n     *\n     * <code>optional uint32 resource_id = 5;</code>\n     */\n    int getResourceId();\n\n    /**\n     * <pre>\n     * The interpreted/compiled version of the `value` string.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item compiled_item = 6;</code>\n     */\n    boolean hasCompiledItem();\n    /**\n     * <pre>\n     * The interpreted/compiled version of the `value` string.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item compiled_item = 6;</code>\n     */\n    com.android.aapt.Resources.Item getCompiledItem();\n  }\n  /**\n   * <pre>\n   * An attribute defined on an XmlElement (android:text=\"...\").\n   * </pre>\n   *\n   * Protobuf type {@code aapt.pb.XmlAttribute}\n   */\n  public  static final class XmlAttribute extends\n      com.google.protobuf.GeneratedMessageLite<\n          XmlAttribute, XmlAttribute.Builder> implements\n      // @@protoc_insertion_point(message_implements:aapt.pb.XmlAttribute)\n      XmlAttributeOrBuilder {\n    private XmlAttribute() {\n      namespaceUri_ = \"\";\n      name_ = \"\";\n      value_ = \"\";\n    }\n    private int bitField0_;\n    public static final int NAMESPACE_URI_FIELD_NUMBER = 1;\n    private java.lang.String namespaceUri_;\n    /**\n     * <code>optional string namespace_uri = 1;</code>\n     */\n    public boolean hasNamespaceUri() {\n      return ((bitField0_ & 0x00000001) == 0x00000001);\n    }\n    /**\n     * <code>optional string namespace_uri = 1;</code>\n     */\n    public java.lang.String getNamespaceUri() {\n      return namespaceUri_;\n    }\n    /**\n     * <code>optional string namespace_uri = 1;</code>\n     */\n    public com.google.protobuf.ByteString\n        getNamespaceUriBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(namespaceUri_);\n    }\n    /**\n     * <code>optional string namespace_uri = 1;</code>\n     */\n    private void setNamespaceUri(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      namespaceUri_ = value;\n    }\n    /**\n     * <code>optional string namespace_uri = 1;</code>\n     */\n    private void clearNamespaceUri() {\n      bitField0_ = (bitField0_ & ~0x00000001);\n      namespaceUri_ = getDefaultInstance().getNamespaceUri();\n    }\n    /**\n     * <code>optional string namespace_uri = 1;</code>\n     */\n    private void setNamespaceUriBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000001;\n      namespaceUri_ = value.toStringUtf8();\n    }\n\n    public static final int NAME_FIELD_NUMBER = 2;\n    private java.lang.String name_;\n    /**\n     * <code>optional string name = 2;</code>\n     */\n    public boolean hasName() {\n      return ((bitField0_ & 0x00000002) == 0x00000002);\n    }\n    /**\n     * <code>optional string name = 2;</code>\n     */\n    public java.lang.String getName() {\n      return name_;\n    }\n    /**\n     * <code>optional string name = 2;</code>\n     */\n    public com.google.protobuf.ByteString\n        getNameBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(name_);\n    }\n    /**\n     * <code>optional string name = 2;</code>\n     */\n    private void setName(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      name_ = value;\n    }\n    /**\n     * <code>optional string name = 2;</code>\n     */\n    private void clearName() {\n      bitField0_ = (bitField0_ & ~0x00000002);\n      name_ = getDefaultInstance().getName();\n    }\n    /**\n     * <code>optional string name = 2;</code>\n     */\n    private void setNameBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000002;\n      name_ = value.toStringUtf8();\n    }\n\n    public static final int VALUE_FIELD_NUMBER = 3;\n    private java.lang.String value_;\n    /**\n     * <code>optional string value = 3;</code>\n     */\n    public boolean hasValue() {\n      return ((bitField0_ & 0x00000004) == 0x00000004);\n    }\n    /**\n     * <code>optional string value = 3;</code>\n     */\n    public java.lang.String getValue() {\n      return value_;\n    }\n    /**\n     * <code>optional string value = 3;</code>\n     */\n    public com.google.protobuf.ByteString\n        getValueBytes() {\n      return com.google.protobuf.ByteString.copyFromUtf8(value_);\n    }\n    /**\n     * <code>optional string value = 3;</code>\n     */\n    private void setValue(\n        java.lang.String value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000004;\n      value_ = value;\n    }\n    /**\n     * <code>optional string value = 3;</code>\n     */\n    private void clearValue() {\n      bitField0_ = (bitField0_ & ~0x00000004);\n      value_ = getDefaultInstance().getValue();\n    }\n    /**\n     * <code>optional string value = 3;</code>\n     */\n    private void setValueBytes(\n        com.google.protobuf.ByteString value) {\n      if (value == null) {\n    throw new NullPointerException();\n  }\n  bitField0_ |= 0x00000004;\n      value_ = value.toStringUtf8();\n    }\n\n    public static final int SOURCE_FIELD_NUMBER = 4;\n    private com.android.aapt.Resources.SourcePosition source_;\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 4;</code>\n     */\n    public boolean hasSource() {\n      return ((bitField0_ & 0x00000008) == 0x00000008);\n    }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 4;</code>\n     */\n    public com.android.aapt.Resources.SourcePosition getSource() {\n      return source_ == null ? com.android.aapt.Resources.SourcePosition.getDefaultInstance() : source_;\n    }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 4;</code>\n     */\n    private void setSource(com.android.aapt.Resources.SourcePosition value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      source_ = value;\n      bitField0_ |= 0x00000008;\n      }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 4;</code>\n     */\n    private void setSource(\n        com.android.aapt.Resources.SourcePosition.Builder builderForValue) {\n      source_ = builderForValue.build();\n      bitField0_ |= 0x00000008;\n    }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 4;</code>\n     */\n    private void mergeSource(com.android.aapt.Resources.SourcePosition value) {\n      if (source_ != null &&\n          source_ != com.android.aapt.Resources.SourcePosition.getDefaultInstance()) {\n        source_ =\n          com.android.aapt.Resources.SourcePosition.newBuilder(source_).mergeFrom(value).buildPartial();\n      } else {\n        source_ = value;\n      }\n      bitField0_ |= 0x00000008;\n    }\n    /**\n     * <pre>\n     * Source line and column info.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.SourcePosition source = 4;</code>\n     */\n    private void clearSource() {  source_ = null;\n      bitField0_ = (bitField0_ & ~0x00000008);\n    }\n\n    public static final int RESOURCE_ID_FIELD_NUMBER = 5;\n    private int resourceId_;\n    /**\n     * <pre>\n     * The resource ID (0xPPTTEEEE) of the attribute.\n     * </pre>\n     *\n     * <code>optional uint32 resource_id = 5;</code>\n     */\n    public boolean hasResourceId() {\n      return ((bitField0_ & 0x00000010) == 0x00000010);\n    }\n    /**\n     * <pre>\n     * The resource ID (0xPPTTEEEE) of the attribute.\n     * </pre>\n     *\n     * <code>optional uint32 resource_id = 5;</code>\n     */\n    public int getResourceId() {\n      return resourceId_;\n    }\n    /**\n     * <pre>\n     * The resource ID (0xPPTTEEEE) of the attribute.\n     * </pre>\n     *\n     * <code>optional uint32 resource_id = 5;</code>\n     */\n    private void setResourceId(int value) {\n      bitField0_ |= 0x00000010;\n      resourceId_ = value;\n    }\n    /**\n     * <pre>\n     * The resource ID (0xPPTTEEEE) of the attribute.\n     * </pre>\n     *\n     * <code>optional uint32 resource_id = 5;</code>\n     */\n    private void clearResourceId() {\n      bitField0_ = (bitField0_ & ~0x00000010);\n      resourceId_ = 0;\n    }\n\n    public static final int COMPILED_ITEM_FIELD_NUMBER = 6;\n    private com.android.aapt.Resources.Item compiledItem_;\n    /**\n     * <pre>\n     * The interpreted/compiled version of the `value` string.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item compiled_item = 6;</code>\n     */\n    public boolean hasCompiledItem() {\n      return ((bitField0_ & 0x00000020) == 0x00000020);\n    }\n    /**\n     * <pre>\n     * The interpreted/compiled version of the `value` string.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item compiled_item = 6;</code>\n     */\n    public com.android.aapt.Resources.Item getCompiledItem() {\n      return compiledItem_ == null ? com.android.aapt.Resources.Item.getDefaultInstance() : compiledItem_;\n    }\n    /**\n     * <pre>\n     * The interpreted/compiled version of the `value` string.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item compiled_item = 6;</code>\n     */\n    private void setCompiledItem(com.android.aapt.Resources.Item value) {\n      if (value == null) {\n        throw new NullPointerException();\n      }\n      compiledItem_ = value;\n      bitField0_ |= 0x00000020;\n      }\n    /**\n     * <pre>\n     * The interpreted/compiled version of the `value` string.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item compiled_item = 6;</code>\n     */\n    private void setCompiledItem(\n        com.android.aapt.Resources.Item.Builder builderForValue) {\n      compiledItem_ = builderForValue.build();\n      bitField0_ |= 0x00000020;\n    }\n    /**\n     * <pre>\n     * The interpreted/compiled version of the `value` string.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item compiled_item = 6;</code>\n     */\n    private void mergeCompiledItem(com.android.aapt.Resources.Item value) {\n      if (compiledItem_ != null &&\n          compiledItem_ != com.android.aapt.Resources.Item.getDefaultInstance()) {\n        compiledItem_ =\n          com.android.aapt.Resources.Item.newBuilder(compiledItem_).mergeFrom(value).buildPartial();\n      } else {\n        compiledItem_ = value;\n      }\n      bitField0_ |= 0x00000020;\n    }\n    /**\n     * <pre>\n     * The interpreted/compiled version of the `value` string.\n     * </pre>\n     *\n     * <code>optional .aapt.pb.Item compiled_item = 6;</code>\n     */\n    private void clearCompiledItem() {  compiledItem_ = null;\n      bitField0_ = (bitField0_ & ~0x00000020);\n    }\n\n    public void writeTo(com.google.protobuf.CodedOutputStream output)\n                        throws java.io.IOException {\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        output.writeString(1, getNamespaceUri());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        output.writeString(2, getName());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        output.writeString(3, getValue());\n      }\n      if (((bitField0_ & 0x00000008) == 0x00000008)) {\n        output.writeMessage(4, getSource());\n      }\n      if (((bitField0_ & 0x00000010) == 0x00000010)) {\n        output.writeUInt32(5, resourceId_);\n      }\n      if (((bitField0_ & 0x00000020) == 0x00000020)) {\n        output.writeMessage(6, getCompiledItem());\n      }\n      unknownFields.writeTo(output);\n    }\n\n    public int getSerializedSize() {\n      int size = memoizedSerializedSize;\n      if (size != -1) return size;\n\n      size = 0;\n      if (((bitField0_ & 0x00000001) == 0x00000001)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(1, getNamespaceUri());\n      }\n      if (((bitField0_ & 0x00000002) == 0x00000002)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(2, getName());\n      }\n      if (((bitField0_ & 0x00000004) == 0x00000004)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeStringSize(3, getValue());\n      }\n      if (((bitField0_ & 0x00000008) == 0x00000008)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(4, getSource());\n      }\n      if (((bitField0_ & 0x00000010) == 0x00000010)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeUInt32Size(5, resourceId_);\n      }\n      if (((bitField0_ & 0x00000020) == 0x00000020)) {\n        size += com.google.protobuf.CodedOutputStream\n          .computeMessageSize(6, getCompiledItem());\n      }\n      size += unknownFields.getSerializedSize();\n      memoizedSerializedSize = size;\n      return size;\n    }\n\n    public static com.android.aapt.Resources.XmlAttribute parseFrom(\n        com.google.protobuf.ByteString data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.XmlAttribute parseFrom(\n        com.google.protobuf.ByteString data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlAttribute parseFrom(byte[] data)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data);\n    }\n    public static com.android.aapt.Resources.XmlAttribute parseFrom(\n        byte[] data,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws com.google.protobuf.InvalidProtocolBufferException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, data, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlAttribute parseFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.XmlAttribute parseFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlAttribute parseDelimitedFrom(java.io.InputStream input)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.XmlAttribute parseDelimitedFrom(\n        java.io.InputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n    public static com.android.aapt.Resources.XmlAttribute parseFrom(\n        com.google.protobuf.CodedInputStream input)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input);\n    }\n    public static com.android.aapt.Resources.XmlAttribute parseFrom(\n        com.google.protobuf.CodedInputStream input,\n        com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n        throws java.io.IOException {\n      return com.google.protobuf.GeneratedMessageLite.parseFrom(\n          DEFAULT_INSTANCE, input, extensionRegistry);\n    }\n\n    public static Builder newBuilder() {\n      return DEFAULT_INSTANCE.toBuilder();\n    }\n    public static Builder newBuilder(com.android.aapt.Resources.XmlAttribute prototype) {\n      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n    }\n\n    /**\n     * <pre>\n     * An attribute defined on an XmlElement (android:text=\"...\").\n     * </pre>\n     *\n     * Protobuf type {@code aapt.pb.XmlAttribute}\n     */\n    public static final class Builder extends\n        com.google.protobuf.GeneratedMessageLite.Builder<\n          com.android.aapt.Resources.XmlAttribute, Builder> implements\n        // @@protoc_insertion_point(builder_implements:aapt.pb.XmlAttribute)\n        com.android.aapt.Resources.XmlAttributeOrBuilder {\n      // Construct using com.android.aapt.Resources.XmlAttribute.newBuilder()\n      private Builder() {\n        super(DEFAULT_INSTANCE);\n      }\n\n\n      /**\n       * <code>optional string namespace_uri = 1;</code>\n       */\n      public boolean hasNamespaceUri() {\n        return instance.hasNamespaceUri();\n      }\n      /**\n       * <code>optional string namespace_uri = 1;</code>\n       */\n      public java.lang.String getNamespaceUri() {\n        return instance.getNamespaceUri();\n      }\n      /**\n       * <code>optional string namespace_uri = 1;</code>\n       */\n      public com.google.protobuf.ByteString\n          getNamespaceUriBytes() {\n        return instance.getNamespaceUriBytes();\n      }\n      /**\n       * <code>optional string namespace_uri = 1;</code>\n       */\n      public Builder setNamespaceUri(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setNamespaceUri(value);\n        return this;\n      }\n      /**\n       * <code>optional string namespace_uri = 1;</code>\n       */\n      public Builder clearNamespaceUri() {\n        copyOnWrite();\n        instance.clearNamespaceUri();\n        return this;\n      }\n      /**\n       * <code>optional string namespace_uri = 1;</code>\n       */\n      public Builder setNamespaceUriBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setNamespaceUriBytes(value);\n        return this;\n      }\n\n      /**\n       * <code>optional string name = 2;</code>\n       */\n      public boolean hasName() {\n        return instance.hasName();\n      }\n      /**\n       * <code>optional string name = 2;</code>\n       */\n      public java.lang.String getName() {\n        return instance.getName();\n      }\n      /**\n       * <code>optional string name = 2;</code>\n       */\n      public com.google.protobuf.ByteString\n          getNameBytes() {\n        return instance.getNameBytes();\n      }\n      /**\n       * <code>optional string name = 2;</code>\n       */\n      public Builder setName(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setName(value);\n        return this;\n      }\n      /**\n       * <code>optional string name = 2;</code>\n       */\n      public Builder clearName() {\n        copyOnWrite();\n        instance.clearName();\n        return this;\n      }\n      /**\n       * <code>optional string name = 2;</code>\n       */\n      public Builder setNameBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setNameBytes(value);\n        return this;\n      }\n\n      /**\n       * <code>optional string value = 3;</code>\n       */\n      public boolean hasValue() {\n        return instance.hasValue();\n      }\n      /**\n       * <code>optional string value = 3;</code>\n       */\n      public java.lang.String getValue() {\n        return instance.getValue();\n      }\n      /**\n       * <code>optional string value = 3;</code>\n       */\n      public com.google.protobuf.ByteString\n          getValueBytes() {\n        return instance.getValueBytes();\n      }\n      /**\n       * <code>optional string value = 3;</code>\n       */\n      public Builder setValue(\n          java.lang.String value) {\n        copyOnWrite();\n        instance.setValue(value);\n        return this;\n      }\n      /**\n       * <code>optional string value = 3;</code>\n       */\n      public Builder clearValue() {\n        copyOnWrite();\n        instance.clearValue();\n        return this;\n      }\n      /**\n       * <code>optional string value = 3;</code>\n       */\n      public Builder setValueBytes(\n          com.google.protobuf.ByteString value) {\n        copyOnWrite();\n        instance.setValueBytes(value);\n        return this;\n      }\n\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 4;</code>\n       */\n      public boolean hasSource() {\n        return instance.hasSource();\n      }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 4;</code>\n       */\n      public com.android.aapt.Resources.SourcePosition getSource() {\n        return instance.getSource();\n      }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 4;</code>\n       */\n      public Builder setSource(com.android.aapt.Resources.SourcePosition value) {\n        copyOnWrite();\n        instance.setSource(value);\n        return this;\n        }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 4;</code>\n       */\n      public Builder setSource(\n          com.android.aapt.Resources.SourcePosition.Builder builderForValue) {\n        copyOnWrite();\n        instance.setSource(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 4;</code>\n       */\n      public Builder mergeSource(com.android.aapt.Resources.SourcePosition value) {\n        copyOnWrite();\n        instance.mergeSource(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * Source line and column info.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.SourcePosition source = 4;</code>\n       */\n      public Builder clearSource() {  copyOnWrite();\n        instance.clearSource();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The resource ID (0xPPTTEEEE) of the attribute.\n       * </pre>\n       *\n       * <code>optional uint32 resource_id = 5;</code>\n       */\n      public boolean hasResourceId() {\n        return instance.hasResourceId();\n      }\n      /**\n       * <pre>\n       * The resource ID (0xPPTTEEEE) of the attribute.\n       * </pre>\n       *\n       * <code>optional uint32 resource_id = 5;</code>\n       */\n      public int getResourceId() {\n        return instance.getResourceId();\n      }\n      /**\n       * <pre>\n       * The resource ID (0xPPTTEEEE) of the attribute.\n       * </pre>\n       *\n       * <code>optional uint32 resource_id = 5;</code>\n       */\n      public Builder setResourceId(int value) {\n        copyOnWrite();\n        instance.setResourceId(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The resource ID (0xPPTTEEEE) of the attribute.\n       * </pre>\n       *\n       * <code>optional uint32 resource_id = 5;</code>\n       */\n      public Builder clearResourceId() {\n        copyOnWrite();\n        instance.clearResourceId();\n        return this;\n      }\n\n      /**\n       * <pre>\n       * The interpreted/compiled version of the `value` string.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item compiled_item = 6;</code>\n       */\n      public boolean hasCompiledItem() {\n        return instance.hasCompiledItem();\n      }\n      /**\n       * <pre>\n       * The interpreted/compiled version of the `value` string.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item compiled_item = 6;</code>\n       */\n      public com.android.aapt.Resources.Item getCompiledItem() {\n        return instance.getCompiledItem();\n      }\n      /**\n       * <pre>\n       * The interpreted/compiled version of the `value` string.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item compiled_item = 6;</code>\n       */\n      public Builder setCompiledItem(com.android.aapt.Resources.Item value) {\n        copyOnWrite();\n        instance.setCompiledItem(value);\n        return this;\n        }\n      /**\n       * <pre>\n       * The interpreted/compiled version of the `value` string.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item compiled_item = 6;</code>\n       */\n      public Builder setCompiledItem(\n          com.android.aapt.Resources.Item.Builder builderForValue) {\n        copyOnWrite();\n        instance.setCompiledItem(builderForValue);\n        return this;\n      }\n      /**\n       * <pre>\n       * The interpreted/compiled version of the `value` string.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item compiled_item = 6;</code>\n       */\n      public Builder mergeCompiledItem(com.android.aapt.Resources.Item value) {\n        copyOnWrite();\n        instance.mergeCompiledItem(value);\n        return this;\n      }\n      /**\n       * <pre>\n       * The interpreted/compiled version of the `value` string.\n       * </pre>\n       *\n       * <code>optional .aapt.pb.Item compiled_item = 6;</code>\n       */\n      public Builder clearCompiledItem() {  copyOnWrite();\n        instance.clearCompiledItem();\n        return this;\n      }\n\n      // @@protoc_insertion_point(builder_scope:aapt.pb.XmlAttribute)\n    }\n    protected final Object dynamicMethod(\n        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n        Object arg0, Object arg1) {\n      switch (method) {\n        case NEW_MUTABLE_INSTANCE: {\n          return new com.android.aapt.Resources.XmlAttribute();\n        }\n        case IS_INITIALIZED: {\n          return DEFAULT_INSTANCE;\n        }\n        case MAKE_IMMUTABLE: {\n          return null;\n        }\n        case NEW_BUILDER: {\n          return new Builder();\n        }\n        case VISIT: {\n          Visitor visitor = (Visitor) arg0;\n          com.android.aapt.Resources.XmlAttribute other = (com.android.aapt.Resources.XmlAttribute) arg1;\n          namespaceUri_ = visitor.visitString(\n              hasNamespaceUri(), namespaceUri_,\n              other.hasNamespaceUri(), other.namespaceUri_);\n          name_ = visitor.visitString(\n              hasName(), name_,\n              other.hasName(), other.name_);\n          value_ = visitor.visitString(\n              hasValue(), value_,\n              other.hasValue(), other.value_);\n          source_ = visitor.visitMessage(source_, other.source_);\n          resourceId_ = visitor.visitInt(\n              hasResourceId(), resourceId_,\n              other.hasResourceId(), other.resourceId_);\n          compiledItem_ = visitor.visitMessage(compiledItem_, other.compiledItem_);\n          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n              .INSTANCE) {\n            bitField0_ |= other.bitField0_;\n          }\n          return this;\n        }\n        case MERGE_FROM_STREAM: {\n          com.google.protobuf.CodedInputStream input =\n              (com.google.protobuf.CodedInputStream) arg0;\n          com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n              (com.google.protobuf.ExtensionRegistryLite) arg1;\n          try {\n            boolean done = false;\n            while (!done) {\n              int tag = input.readTag();\n              switch (tag) {\n                case 0:\n                  done = true;\n                  break;\n                default: {\n                  if (!parseUnknownField(tag, input)) {\n                    done = true;\n                  }\n                  break;\n                }\n                case 10: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000001;\n                  namespaceUri_ = s;\n                  break;\n                }\n                case 18: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000002;\n                  name_ = s;\n                  break;\n                }\n                case 26: {\n                  java.lang.String s = input.readString();\n                  bitField0_ |= 0x00000004;\n                  value_ = s;\n                  break;\n                }\n                case 34: {\n                  com.android.aapt.Resources.SourcePosition.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000008) == 0x00000008)) {\n                    subBuilder = source_.toBuilder();\n                  }\n                  source_ = input.readMessage(com.android.aapt.Resources.SourcePosition.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(source_);\n                    source_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000008;\n                  break;\n                }\n                case 40: {\n                  bitField0_ |= 0x00000010;\n                  resourceId_ = input.readUInt32();\n                  break;\n                }\n                case 50: {\n                  com.android.aapt.Resources.Item.Builder subBuilder = null;\n                  if (((bitField0_ & 0x00000020) == 0x00000020)) {\n                    subBuilder = compiledItem_.toBuilder();\n                  }\n                  compiledItem_ = input.readMessage(com.android.aapt.Resources.Item.parser(), extensionRegistry);\n                  if (subBuilder != null) {\n                    subBuilder.mergeFrom(compiledItem_);\n                    compiledItem_ = subBuilder.buildPartial();\n                  }\n                  bitField0_ |= 0x00000020;\n                  break;\n                }\n              }\n            }\n          } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n            throw new RuntimeException(e.setUnfinishedMessage(this));\n          } catch (java.io.IOException e) {\n            throw new RuntimeException(\n                new com.google.protobuf.InvalidProtocolBufferException(\n                    e.getMessage()).setUnfinishedMessage(this));\n          } finally {\n          }\n        }\n        case GET_DEFAULT_INSTANCE: {\n          return DEFAULT_INSTANCE;\n        }\n        case GET_PARSER: {\n          if (PARSER == null) {    synchronized (com.android.aapt.Resources.XmlAttribute.class) {\n              if (PARSER == null) {\n                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n              }\n            }\n          }\n          return PARSER;\n        }\n      }\n      throw new UnsupportedOperationException();\n    }\n\n\n    // @@protoc_insertion_point(class_scope:aapt.pb.XmlAttribute)\n    private static final com.android.aapt.Resources.XmlAttribute DEFAULT_INSTANCE;\n    static {\n      DEFAULT_INSTANCE = new XmlAttribute();\n      DEFAULT_INSTANCE.makeImmutable();\n    }\n\n    public static com.android.aapt.Resources.XmlAttribute getDefaultInstance() {\n      return DEFAULT_INSTANCE;\n    }\n\n    private static volatile com.google.protobuf.Parser<XmlAttribute> PARSER;\n\n    public static com.google.protobuf.Parser<XmlAttribute> parser() {\n      return DEFAULT_INSTANCE.getParserForType();\n    }\n  }\n\n\n  static {\n  }\n\n  // @@protoc_insertion_point(outer_class_scope)\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/AndroidComponent.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.build.gradle.internal;\n\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.Configuration;\nimport org.gradle.api.artifacts.DependencySet;\nimport org.gradle.api.attributes.Usage;\nimport org.gradle.api.internal.component.SoftwareComponentInternal;\nimport org.gradle.api.internal.component.UsageContext;\nimport org.gradle.api.model.ObjectFactory;\n\nimport java.util.Set;\n\n/**\n * Created by shenghua.nish on 2015-08-24 And in the afternoon.\n */\npublic class AndroidComponent implements SoftwareComponentInternal {\n\n\n    private final DependencySet compileDependencies;\n\n    private final Configuration compileConfiguration;\n\n    private Project project;\n     Usage apiUsage = null;\n\n     Usage runtimeUsage = null;\n\n\n    public AndroidComponent(Configuration compileConfiguration, DependencySet compileDependencies, Project project) {\n        this.compileConfiguration = compileConfiguration;\n        this.compileDependencies = compileDependencies;\n        this.project = project;\n        ObjectFactory factory = project.getObjects();\n        apiUsage = factory.named(Usage.class, Usage.JAVA_API);\n        runtimeUsage = factory.named(Usage.class, Usage.JAVA_RUNTIME);\n\n    }\n\n    @Override\n    public String getName() {\n        return \"android\";\n    }\n\n    @Override\n    public Set<UsageContext> getUsages() {\n        return null;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/ApkDataUtils.java",
    "content": "package com.android.build.gradle.internal;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.BaseVariantOutputImpl;\nimport com.android.ide.common.build.ApkData;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\n\n/**\n * @author lilong\n * @create 2017-11-30 下午1:50\n */\n\npublic class ApkDataUtils {\n\n    public static ApkData get(BaseVariantOutput baseVariantOutput){\n        Method method = null;\n        try {\n            method = BaseVariantOutputImpl.class.getDeclaredMethod(\"getApkData\");\n            method.setAccessible(true);\n            return (ApkData) method.invoke(baseVariantOutput);\n        } catch (IllegalAccessException e) {\n            e.printStackTrace();\n        } catch (InvocationTargetException e) {\n            e.printStackTrace();\n        } catch (NoSuchMethodException e) {\n            e.printStackTrace();\n        }\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/AtlasDependencyManager.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.build.gradle.internal;\n\nimport com.alibaba.fastjson.JSON;\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.dependency.VariantDependencies;\nimport com.android.builder.dependency.level2.AndroidDependency;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.ap.ApDependency;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.dependency.parser.AtlasDepTreeParser;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.extension.TBuildType;\nimport com.taobao.android.builder.tools.PluginTypeUtils;\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.Configuration;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.function.Predicate;\n\n/**\n * A manager to resolve configuration dependencies.\n *\n * @author wuzhong\n */\npublic class AtlasDependencyManager {\n\n    private static final Logger sLogger = LoggerFactory.getLogger(AtlasDependencyManager.class);\n\n    private final Project project;\n\n    private final ExtraModelInfo extraModelInfo;\n\n    private ApDependency apDependency;\n\n    private Set<String>awbs = new HashSet<>();\n\n\n    public AtlasDependencyManager(@NonNull Project project, @NonNull ExtraModelInfo extraModelInfo) {\n        this(project,extraModelInfo,new HashSet<>());\n    }\n\n    public AtlasDependencyManager(Project project, ExtraModelInfo extraModelInfo, Set<String> awbs) {\n        this.project = project;\n        this.extraModelInfo = extraModelInfo;\n        this.awbs = awbs;\n    }\n\n    /**\n     * 1 . detect if has awb dependency\n     * <p>\n     * yes : special process\n     * no  : default process\n     * <p>\n     * 2.  parse to AtlasDependencyTree\n     */\n    public Set<AndroidDependency> resolveDependencies(@NonNull VariantDependencies variantDeps) {\n        this.apDependency = resolveApDependencies(variantDeps);\n        AtlasDependencyTree atlasDependencyTree = new AtlasDepTreeParser(project, extraModelInfo,awbs)\n            .parseDependencyTree(variantDeps);\n\n        sLogger.info(\"[dependencyTree\" + variantDeps.getName() + \"] {}\",\n                     JSON.toJSONString(atlasDependencyTree.getDependencyJson(), true));\n\n        if (PluginTypeUtils.isAppProject(project)) {\n            AtlasBuildContext.androidDependencyTrees.put(variantDeps.getName(), atlasDependencyTree);\n        } else {\n            AtlasBuildContext.libDependencyTrees.put(variantDeps.getName(), atlasDependencyTree);\n        }\n\n\n\n\n//        Set<AndroidDependency> libsToExplode = super.resolveDependencies(variantDeps, testedProjectPath);\n        //return libsToExplode;\n        return new HashSet<>(0);\n    }\n\n    private ApDependency resolveApDependencies(@NonNull VariantDependencies variantDeps) {\n        AtlasExtension atlasExtension = project.getExtensions().getByType(AtlasExtension.class);\n        if (!atlasExtension.getTBuildConfig().isIncremental()) {\n            return null;\n        }\n\n        TBuildType tBuildType = (TBuildType)atlasExtension.getBuildTypes().findByName(variantDeps.getName());\n        if (tBuildType == null) {\n            return null;\n        }\n\n        return new ApDependency(project, tBuildType);\n    }\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/AtlasDependencyManager2.java",
    "content": "package com.android.build.gradle.internal;\n\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.internal.ide.AtlasDependencyGraph;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.builder.dependency.level2.AndroidDependency;\nimport com.android.builder.model.SyncIssue;\nimport com.android.builder.model.level2.DependencyGraphs;\nimport org.gradle.api.Project;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.util.Set;\nimport java.util.function.Consumer;\n\n/**\n * @author lilong\n * @create 2017-12-01 上午10:09\n */\n\npublic class AtlasDependencyManager2 {\n\n    private static final Logger sLogger = LoggerFactory.getLogger(AtlasDependencyManager2.class);\n\n    private final Project project;\n\n    private final ExtraModelInfo extraModelInfo;\n\n//    private ApDependencies apDependencies;\n\n    public AtlasDependencyManager2(@NonNull Project project, @NonNull ExtraModelInfo extraModelInfo) {\n        this.project = project;\n        this.extraModelInfo = extraModelInfo;\n    }\n\n\n    public Set<AndroidDependency> resolveDependencies(@NonNull VariantScope variantScope) {\n//        this.apDependencies = resolveApDependencies(variantDeps);\n\n        AtlasDependencyGraph artifactDependencyGraph = new AtlasDependencyGraph();\n\n        DependencyGraphs dependencyGraphs = artifactDependencyGraph.createLevel4DependencyGraph(variantScope, false, true, new Consumer<SyncIssue>() {\n            @Override\n            public void accept(SyncIssue syncIssue) {\n                sLogger.error(syncIssue.getMessage());\n            }\n        });\n\n\n        return null;\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/api/ApContext.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.build.gradle.internal.api;\n\nimport com.android.utils.FileUtils;\nimport org.apache.commons.io.FilenameUtils;\n\nimport java.io.File;\n\nimport static com.android.SdkConstants.ANDROID_MANIFEST_XML;\n\n/**\n * Created by wuzhong on 2016/10/3.\n *\n * @author wuzhong\n */\npublic class ApContext {\n    public static final String AP_INLINE_APK_FILENAME = \"android.apk\";\n\n    public static final String AP_INLINE_APK_EXTRACT_DIRECTORY = \"android.apk_\";\n\n    public static final String AP_INLINE_AWB_EXPLODED_DIRECTORY = \"exploded-awb\";\n\n    public static final String AP_INLINE_AWB_EXTRACT_DIRECTORY = \"awbs\";\n\n    public static final String APK_FILE_LIST = \"apk-files.txt\";\n\n    public static final String APK_FILE_MD5 = \"apk-files.txt\";\n\n    private static final String SO_LOCATION_PREFIX=\"unzip/lib/armeabi\";\n\n    public static final String PACKAGE_ID_PROPERTIES_FILENAME = \"packageIdFile.properties\";\n\n    public static final String ATLAS_FRAMEWORK_PROPERTIES_FILENAME = \"atlasFrameworkProperties.json\";\n\n    public static final String DEPENDENCIES_FILENAME = \"dependencies.txt\";\n\n    public static final String STABLE_IDS_FILENAME = \"public.txt\";\n\n    private String apDependency;\n\n    private File apFile;\n\n    private File apExploredFolder;\n\n    private File baseApk;\n\n    private File baseApkDirectory;\n\n    private File baseAwbDirectory;\n\n    private File baseExplodedAwbDirectory;\n\n    private File baseManifest;\n\n    private File baseModifyManifest;\n\n    private File baseAtlasFrameworkPropertiesFile;\n\n    private File basePackageIdFile;\n\n    private File baseDependenciesFile;\n\n    private File baseStableIdsFile;\n\n    private File baseUnzipBundleDirectory;\n\n    // Unpack the former\n    public String getApDependency() {\n        return apDependency;\n    }\n\n    public void setApDependency(String apDependency) {\n        this.apDependency = apDependency;\n    }\n\n    public File getApFile() {\n        return apFile;\n    }\n\n    public void setApFile(File apFile) {\n        this.apFile = apFile;\n    }\n\n    // After decompression\n    public File getApExploredFolder() {\n        return apExploredFolder;\n    }\n\n    public void setApExploredFolder(File apExploredFolder) {\n        this.apExploredFolder = apExploredFolder;\n        this.baseManifest = new File(apExploredFolder, ANDROID_MANIFEST_XML);\n        this.baseModifyManifest = FileUtils.join(apExploredFolder, \"manifest-modify\", ANDROID_MANIFEST_XML);\n        this.baseApk = new File(apExploredFolder, AP_INLINE_APK_FILENAME);\n        this.baseApkDirectory = new File(apExploredFolder, AP_INLINE_APK_EXTRACT_DIRECTORY);\n        this.baseAwbDirectory = new File(apExploredFolder, AP_INLINE_AWB_EXTRACT_DIRECTORY);\n        this.baseUnzipBundleDirectory = new File(apExploredFolder,SO_LOCATION_PREFIX);\n        this.baseExplodedAwbDirectory = new File(apExploredFolder, AP_INLINE_AWB_EXPLODED_DIRECTORY);\n        this.basePackageIdFile = new File(apExploredFolder, PACKAGE_ID_PROPERTIES_FILENAME);\n        this.baseAtlasFrameworkPropertiesFile = new File(apExploredFolder, ATLAS_FRAMEWORK_PROPERTIES_FILENAME);\n        this.baseDependenciesFile = new File(apExploredFolder, DEPENDENCIES_FILENAME);\n        this.baseStableIdsFile = new File(apExploredFolder, STABLE_IDS_FILENAME);\n    }\n\n    public File getBaseApkDirectory() {\n        return baseApkDirectory;\n    }\n\n    public File getBaseApk() {\n        return baseApk;\n    }\n\n    public File getBaseAwbDirectory() {\n        return baseAwbDirectory;\n    }\n\n    public File getBaseManifest() {\n        return baseManifest;\n    }\n\n    public File getBaseModifyManifest() {\n        return baseModifyManifest;\n    }\n\n    public File getBaseAtlasFrameworkPropertiesFile() {\n        return baseAtlasFrameworkPropertiesFile;\n    }\n\n    public File getPackageIdFile() {\n        return basePackageIdFile;\n    }\n\n    public File getBaseDependenciesFile() {\n        return baseDependenciesFile;\n    }\n\n    public File getBaseStableIdsFile() {\n        return baseStableIdsFile;\n    }\n\n    public File getBaseAwb(String soFileName) {\n        File file = FileUtils.join(baseAwbDirectory, soFileName);\n        if (!file.exists()) {\n            return null;\n        }\n        return file;\n    }\n\n    public File getBaseExplodedAwb(String soFileName) {\n        File file = FileUtils.join(baseExplodedAwbDirectory, FilenameUtils.getBaseName(soFileName));\n        if (!file.exists()) {\n            return null;\n        }\n        return file;\n    }\n\n    public File getBaseSo(String soFileName){\n        File file = FileUtils.join(baseUnzipBundleDirectory,soFileName);\n        if (file.exists()){\n            return file;\n        }\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/api/ApkFiles.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.build.gradle.internal.api;\n\nimport com.taobao.android.object.ApkFileList;\n\n/**\n * Created by wuzhong on 2017/6/7.\n */\npublic class ApkFiles {\n\n    public ApkFileList apkFileList = new ApkFileList();\n\n    public ApkFileList finalApkFileList = new ApkFileList();\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/api/AppVariantContext.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.build.gradle.internal.api;\n\nimport android.databinding.tool.DataBindingBuilder;\nimport com.alibaba.fastjson.JSON;\nimport com.alibaba.fastjson.JSONArray;\nimport com.alibaba.fastjson.JSONObject;\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.AppExtension;\nimport com.android.build.gradle.BaseExtension;\nimport com.android.build.gradle.internal.variant.ApplicationVariantData;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.ide.common.build.ApkData;\nimport com.android.utils.FileUtils;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Maps;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.diff.DependencyCompareUtils;\nimport com.taobao.android.builder.dependency.diff.DependencyDiff;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.dependency.output.DependencyJson;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.tasks.app.bundle.ProcessAwbAndroidResources;\nimport com.taobao.android.builder.tasks.app.bundle.ProcessResAwbsTask;\nimport com.taobao.android.builder.tools.bundleinfo.ApkFileListUtils;\nimport org.gradle.api.Project;\nimport org.gradle.api.file.ConfigurableFileTree;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.regex.Pattern;\n\nimport static com.android.build.gradle.internal.scope.TaskOutputHolder.TaskOutputType.ANNOTATION_PROCESSOR_LIST;\n\n/**\n * ApplicaitonThe compiled context\n * Created by shenghua.nish on 2016-05-04 3:46 afternoon.\n */\npublic class AppVariantContext<T extends BaseVariantImpl, Z extends BaseExtension, E extends AtlasExtension>\n    extends VariantContext<ApplicationVariantImpl, AppExtension, AtlasExtension> {\n\n    private final ApplicationVariantImpl applicationVariant;\n\n    private final ApplicationVariantData variantData;\n\n    public final Map<String, ProcessAwbAndroidResources> awbsProcessResourcesTask = new HashMap<>();\n\n    private final Map<String, AppVariantOutputContext> outputContextMap = Maps.newHashMap();\n\n\n    public ProcessResAwbsTask processResAwbsTask = null;\n\n    /**\n     * buildCache The manifest of the directory cannot be changed, So save the modified manifest reference\n     */\n    public Map<String, File> manifestMap = new HashMap<>();\n    public String unit_tag = \"\";\n\n\n    public DependencyDiff dependencyDiff;\n\n    /**\n     * bundleList file\n     */\n    public File bundleListCfg;\n\n    private ApkFiles apkFiles;\n\n    public AppVariantContext(ApplicationVariantImpl applicationVariant, Project project, AtlasExtension atlasExtension,\n                             AppExtension appExtension) {\n\n        super(applicationVariant, project, atlasExtension, appExtension);\n        this.applicationVariant = applicationVariant;\n        this.variantData = (ApplicationVariantData) applicationVariant.getVariantData();\n        this.scope = this.variantData.getScope();\n    }\n\n    public ApplicationVariantImpl getApplicationVariant() {\n        return applicationVariant;\n    }\n\n    public ApplicationVariantData getVariantData() {\n        return variantData;\n    }\n\n    public Map<String, AppVariantOutputContext> getOutputContextMap() {\n        return outputContextMap;\n    }\n\n    public File getAwbDexOutput(String awbName) {\n        return new File(scope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-dex/\" + getVariantConfiguration().getDirName() + \"/\" + awbName);\n    }\n\n    public File getAwbRClassSourceOutputDir(AwbBundle awbBundle) {\n        return new File(scope.getGlobalScope().getGeneratedDir(),\n                \"source/awb-r/\" +\n                        getVariantConfiguration().getDirName() +\n                        \"/\" +\n                        awbBundle.getName());\n    }\n\n    public List<ConfigurableFileTree> getAwSourceOutputDir(AwbBundle awbBundle) {\n        Project project = scope.getGlobalScope().getProject();\n        // Build the list of source folders.\n        ImmutableList.Builder<ConfigurableFileTree> sourceSets = ImmutableList.builder();\n\n        // then all the generated src folders.\n        if (getAwbRClassSourceOutputDir(awbBundle) != null) {\n            sourceSets.add(project.fileTree(getAwbRClassSourceOutputDir(awbBundle)));\n        }\n        sourceSets.add(project.fileTree(getAwbMergeResourcesOutputDir(awbBundle)));\n\n        if (scope.getGlobalScope().getExtension().getDataBinding().isEnabled()) {\n            sourceSets.add(project.fileTree(getAwbClassOutputForDataBinding(awbBundle)));\n        }\n\n        return sourceSets.build();\n    }\n\n    public File getAwbLibraryDirForDataBinding(AwbBundle awbBundle) {\n        return new File(scope.getGlobalScope().getIntermediatesDir() +\n                \"/transforms-awbs/databinding/\" +\n                getVariantConfiguration().getDirName() +\n                \"/\" +\n                awbBundle.getName());\n    }\n\n    public File getAwbLayoutInfoOutputForDataBinding(AwbBundle awbBundle) {\n        return new File(scope.getGlobalScope().getIntermediatesDir() +\n                \"/data-binding-info-awbs/\" +\n                getVariantConfiguration().getDirName() +\n                \"/\" +\n                awbBundle.getName());\n    }\n\n    public File getJAwbavaOutputDir(AwbBundle awbBundle) {\n        return new File(scope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-classes/\" +\n                        variantData.getVariantConfiguration().getDirName() +\n                        \"/\" +\n                        awbBundle.getName());\n    }\n\n    public File getAwbClassOutputForDataBinding(AwbBundle awbBundle) {\n        return new File(scope.getGlobalScope().getGeneratedDir(),\n                \"source/awb-dataBinding/\" +\n                        getVariantConfiguration().getDirName() +\n                        \"/\" +\n                        awbBundle.getName());\n    }\n\n    public File getAwbLayoutFolderOutputForDataBinding(AwbBundle awbBundle) {\n        return new File(scope.getGlobalScope().getIntermediatesDir() +\n                \"/data-binding-layout-out-awb/\" +\n                getVariantConfiguration().getDirName() +\n                \"/\" +\n                awbBundle.getName());\n    }\n\n    public File getAwbGeneratedClassListOutputFileForDataBinding(AwbBundle awbBundle) {\n        return new File(getAwbLayoutInfoOutputForDataBinding(awbBundle), \"_generated.txt\");\n    }\n\n    public File getAwbDataBindingMergeArtifacts(AwbBundle awbBundle) {\n\n        return new File(scope.getGlobalScope().getIntermediatesDir().getAbsolutePath() + \"/awb-data-binding-compiler/\" +\n                getVariantConfiguration().getDirName()+\"/\"+awbBundle.getName()+\"/\"+ DataBindingBuilder.ARTIFACT_FILES_DIR_FROM_LIBS);\n    }\n\n        //return new File(scope.getBuildFolderForDataBindingCompiler() +  \"-\" + awbBundle.getName(),\n        //                     DataBindingBuilder.ARTIFACT_FILES_DIR_FROM_LIBS);\n\n\n    public File getAwbMergeResourcesOutputDir(AwbBundle awbBundle) {\n        return new File(scope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-res/merged/\" +\n                        getVariantConfiguration().getDirName() +\n                        \"/\" +\n                        awbBundle.getName());\n    }\n\n    public File getAwbBlameLogFolder(AwbBundle awbBundle) {\n        return new File(scope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-blame/\" +\n                        getVariantConfiguration().getDirName() +\n                        \"/\" +\n                        awbBundle.getName());\n    }\n\n    public File getModifyManifest(AndroidLibrary androidLibrary) {\n        return new File(getModifyManifestDir(),\n                androidLibrary.getResolvedCoordinates().getGroupId() +\n                        \".\" +\n                        androidLibrary.getResolvedCoordinates().getArtifactId() +\n                        \".xml\");\n    }\n\n    @NonNull\n    public Collection<File> getAwbApkFiles() {\n        return FileUtils.find(getAwbApkOutputDir(), Pattern.compile(\"\\\\.so$\"));\n    }\n\n    public File getAwbApkOutputDir() {\n        return new File(scope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-apks/\" + getVariantConfiguration().getDirName() + \"/\");\n    }\n\n    public File getModifyManifestDir() {\n        return new File(scope.getGlobalScope().getIntermediatesDir(),\n                \"/manifest-modify/\" + getVariantConfiguration().getDirName() + \"/\");\n    }\n\n    public File getBundleBaseInfoFile() {\n        File bundleBaseLineInfo = new File(this.getScope()\n                .getGlobalScope()\n                .getProject()\n                .getProjectDir(), \"bundleBaseInfoFile.json\");\n        return bundleBaseLineInfo;\n    }\n\n    public File getAtlasProxySourceDir() {\n        return new File(scope.getGlobalScope().getGeneratedDir(),\n                \"source/atlasproxy/\" + getVariantConfiguration().getDirName());\n    }\n\n    public AppVariantOutputContext getAppVariantOutputContext(ApkData apkData) {\n\n        AppVariantOutputContext appVariantOutputContext = (AppVariantOutputContext) this.getOutputContextMap()\n                .get(apkData.getFullName());\n\n        if (null == appVariantOutputContext) {\n            appVariantOutputContext = new AppVariantOutputContext(apkData.getFullName(),\n                    this,\n                    apkData,\n                    applicationVariant.getVariantData());\n            this.getOutputContextMap().put(apkData.getFullName(), appVariantOutputContext);\n        }\n\n        return appVariantOutputContext;\n    }\n\n    public File getAtlaSourceDir() {\n        return new File(scope.getGlobalScope().getGeneratedDir(),\n                \"source/atlascore/\" + getVariantConfiguration().getDirName());\n    }\n\n    public Map<String, String> getBaseUnitTagMap() throws IOException {\n        Map<String, String> tagMap = new HashMap<>();\n        if (null != this.apContext.getApExploredFolder()\n                && this.apContext.getApExploredFolder().exists()) {\n            File file = new File(this.apContext.getApExploredFolder(), \"atlasFrameworkProperties.json\");\n            if (file.exists()) {\n                JSONObject jsonObject = (JSONObject) JSON.parse(org.apache.commons.io.FileUtils.readFileToString(file));\n                JSONArray jsonArray = jsonObject.getJSONArray(\"bundleInfo\");\n                for (JSONObject obj : jsonArray.toArray(new JSONObject[0])) {\n                    tagMap.put(obj.getString(\"pkgName\"), obj.getString(\"unique_tag\"));\n                }\n            }\n        }\n        return tagMap;\n    }\n\n    public DependencyDiff getDependencyDiff() throws IOException {\n\n        if (null != this.dependencyDiff) {\n            return this.dependencyDiff;\n        }\n\n        if (null !=\n                this.apContext.getApExploredFolder() &&\n                this.apContext.getApExploredFolder()\n                        .exists()) {\n\n            DependencyJson dependencyJson = AtlasBuildContext.androidDependencyTrees\n                    .get(this.getVariantData().getName())\n                    .getDependencyJson();\n            File baseDependencyFile = new File(\n                    this.apContext.getApExploredFolder(),\n                    \"dependencies.txt\");\n            if (baseDependencyFile.exists()) {\n                DependencyDiff dependencyDiff = DependencyCompareUtils\n                        .diff(baseDependencyFile,\n                                dependencyJson);\n\n                this.dependencyDiff = dependencyDiff;\n\n                return dependencyDiff;\n            }\n\n        }\n\n        return null;\n\n    }\n\n    public ApkFiles getApkFiles() {\n\n        if (null != apkFiles) {\n            return apkFiles;\n        }\n\n        apkFiles = ApkFileListUtils.recordApkFileInfos(this);\n        return apkFiles;\n    }\n\n    public File getAwbProguardDir(AwbBundle awbBundle) {\n        File file = new File(scope.getGlobalScope().getIntermediatesDir(),\n                \"awb-proguard/\" + getVariantConfiguration().getDirName() + \"/\" + awbBundle.getName());\n        file.mkdirs();\n        return file;\n    }\n\n    public boolean isDataBindEnabled(AwbBundle awbBundle) {\n\n        if (null == appExtension.getDataBinding() || !appExtension.getDataBinding().isEnabled()) {\n            return false;\n        }\n\n        return atlasExtension.getTBuildConfig().getDataBindingBundles().contains(awbBundle.getPackageName());\n\n    }\n\n    public File getAwbAnnotationProcessorOutputDir(AwbBundle awbBundle) {\n        return new File(scope.getGlobalScope().getGeneratedDir(),\n                \"source/bundle-apt/\" +\n                        getVariantConfiguration().getDirName() +\n                        \"/\" +\n                        awbBundle.getName());\n\n    }\n\n    public File getAwbDexAchiveOutput(AwbBundle awbBundle) {\n        return new File(scope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-achiveDex/\" +\n                        variantData.getVariantConfiguration().getDirName() +\n                        \"/\" +\n                        awbBundle.getName());\n\n    }\n\n    public File getAwbDexAchiveOutputs() {\n        File file = new File(scope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-achiveDex/\" +\n                        variantData.getVariantConfiguration().getDirName());\n\n        if (!file.exists()) {\n            file.mkdirs();\n        }\n        return file;\n\n    }\n\n    public File getMainDexAchive() {\n        return new File(scope.getGlobalScope().getIntermediatesDir(),\n                \"/mainbundle-achiveDex/\" +\n                        variantData.getVariantConfiguration().getDirName());\n    }\n}\n\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/api/AppVariantOutputContext.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.build.gradle.internal.api;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport com.android.build.api.transform.JarInput;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.tasks.databinding.DataBindingExportBuildInfoTask;\nimport com.android.build.gradle.internal.variant.BaseVariantData;\nimport com.android.build.gradle.tasks.PackageApplication;\nimport com.android.ide.common.build.ApkData;\nimport com.android.utils.FileUtils;\nimport com.google.common.collect.Maps;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.app.bundle.ProcessAwbAndroidResources;\nimport com.taobao.android.builder.tasks.transform.AtlasMergeJavaResourcesTransform;\nimport com.taobao.android.object.ArtifactBundleInfo;\nimport org.gradle.api.tasks.compile.JavaCompile;\n\nimport static com.android.SdkConstants.FD_ASSETS;\nimport static com.android.builder.model.AndroidProject.FD_OUTPUTS;\n\n/**\n * Created by shenghua.nish on 2016-05-04 3:46 afternoon.\n */\npublic class AppVariantOutputContext {\n\n    private final String name;\n\n    private final AppVariantContext variantContext;\n\n    private final VariantScope variantScope;\n\n    private final BaseVariantData variantData;\n\n    private final Map<String, JavaCompile> awbJavacTasks = Maps.newHashMap();\n\n    private final Map<String, ProcessAwbAndroidResources> awbAndroidResourcesMap = Maps.newHashMap();\n\n    private final Map<String, AwbTransform> awbTransformMap = Maps.newHashMap();\n\n    private File dexMergeOutFolder;\n\n    public Map<String, AtlasMergeJavaResourcesTransform.NativeInfo> getSoMap() {\n        return soMap;\n    }\n\n    private Map<String, AtlasMergeJavaResourcesTransform.NativeInfo> soMap = new HashMap<>();\n\n    private final Map<String, PackageApplication> awbPackageMap = Maps.newHashMap();\n\n    private final Map<String, DataBindingExportBuildInfoTask> exportBuildInfoTaskMap = Maps.newHashMap();\n\n//    private final Map<String, DataBindingProcessLayoutsTask> dataBindingProcessLayoutsTaskMap = Maps\n//            .newHashMap();\n\n    public Set<ArtifactBundleInfo> artifactBundleInfos;\n\n    public AppBuildInfo appBuildInfo = new AppBuildInfo();\n\n    public ApkData getApkData() {\n        return apkData;\n    }\n\n    private ApkData apkData;\n\n    public Map<String, JavaCompile> getAwbJavacTasks() {\n        return awbJavacTasks;\n    }\n\n    public AppVariantOutputContext(String name, AppVariantContext variantContext, ApkData apkData, BaseVariantData variantData) {\n        this.name = name;\n        this.variantContext = variantContext;\n        this.apkData = apkData;\n        this.variantScope = variantData.getScope();\n        this.variantData = variantData;\n    }\n\n    public AppVariantContext getVariantContext() {\n        return variantContext;\n    }\n\n    public VariantScope getScope() {\n        return variantScope;\n    }\n\n    public BaseVariantData getVariantData() {\n        return variantData;\n    }\n\n    public File getAwbRClassSourceOutputDir(GradleVariantConfiguration config, AwbBundle awbBundle) {\n        return new File(variantScope.getGlobalScope().getGeneratedDir(),\n                        \"source/awb-r/\" + config.getDirName() + \"/\" + awbBundle.getName());\n    }\n\n    public File getAwbApplicationInjectClassOutputDir(GradleVariantConfiguration config, AwbBundle awbBundle) {\n        return new File(variantScope.getGlobalScope().getIntermediatesDir(),\n                \"awb-app-inject/\" + config.getDirName() + \"/\" + awbBundle.getName());\n    }\n\n    public File getAwbMergedResourceDir(GradleVariantConfiguration config, AwbBundle awbBundle) {\n        return new File(variantScope.getGlobalScope().getIntermediatesDir(),\n                        \"/awb-res/merged/\" + config.getDirName() + \"/\" + awbBundle.getName());\n    }\n\n    public File getAwbProcessResourcePackageOutputFile(AwbBundle awbBundle) {\n        return new File(variantScope.getGlobalScope().getIntermediatesDir(),\n                        \"res/\" +\n                        awbBundle.getName() +\n                        \"/resources-\" +\n                        variantData.getVariantConfiguration().getBaseName() +\n                        \".ap_\");\n    }\n\n    public File getAwbCompressResourcePackageOutputFile(AwbBundle awbBundle) {\n        return new File(variantScope.getGlobalScope().getIntermediatesDir(),\n                \"res/\" +\n                        awbBundle.getName() +\n                        \"/resources-\" +\n                        variantData.getVariantConfiguration().getBaseName() +\n                        \"-stripped.ap_\");\n    }\n\n    public Map<String, ProcessAwbAndroidResources> getAwbAndroidResourcesMap() {\n        return awbAndroidResourcesMap;\n    }\n\n    public File getJAwbavaOutputDir(AwbBundle awbBundle) {\n        return new File(variantScope.getGlobalScope().getIntermediatesDir(),\n                        \"/awb-classes/\" +\n                        variantData.getVariantConfiguration().getDirName() +\n                        \"/\" +\n                        awbBundle.getName());\n    }\n\n    public File getAwbJavaDependencyCache(AwbBundle awbBundle) {\n        return new File(variantScope.getGlobalScope().getIntermediatesDir(),\n                        \"/awb-dependency-cache/\" +\n                        variantData.getVariantConfiguration().getDirName() +\n                        \"/\" +\n                        awbBundle.getName());\n    }\n\n    public File getAwbSolib(AwbBundle awbBundle) {\n        return new File(variantScope.getGlobalScope().getIntermediatesDir(),\n                        \"/awb-solib/\" +\n                        variantData.getVariantConfiguration().getDirName() +\n                        \"/\" +\n                        awbBundle.getName());\n    }\n\n    public synchronized Map<String, AwbTransform> getAwbTransformMap() {\n        //TODO\n        if (awbTransformMap.isEmpty()) {\n            AtlasDependencyTree dependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n                    variantContext.getVariantName());\n            for (AwbBundle awbBundle : dependencyTree.getAwbBundles()) {\n                //Generate the AwbTransform object\n                AwbTransform awbTransform = new AwbTransform(awbBundle);\n                //                awbTransform.setInputDir(awbJavaCompile.getDestinationDir());\n                awbTransform.getInputLibraries().addAll(awbBundle.getLibraryJars());  //ADD R.class\n                //                awbTransform.getInputLibraries().addAll(appVariantOutputContext.getJAwbavaOutputDir\n                // (awbBundle));\n                awbTransformMap.put(awbBundle.getName(), awbTransform);\n            }\n        }\n        return awbTransformMap;\n    }\n\n    public Map<String, PackageApplication> getAwbPackageMap() {\n        return awbPackageMap;\n    }\n\n    public Map<String, DataBindingExportBuildInfoTask> getExportBuildInfoTaskMap() {\n        return exportBuildInfoTaskMap;\n    }\n\n//    public Map<String, DataBindingProcessLayoutsTask> getDataBindingProcessLayoutsTaskMap() {\n//        return dataBindingProcessLayoutsTaskMap;\n//    }\n\n\n    public String getAwbPackageOutputFilePath(AwbBundle awbBundle) {\n        String awbOutputName = awbBundle.getAwbSoName();\n\n        Set<String> libSoNames = variantContext.getAtlasExtension().getTBuildConfig().getKeepInLibSoNames();\n\n        String file = null;\n        if (libSoNames.isEmpty() || libSoNames.contains(awbOutputName)) {\n            file = \"lib/armeabi\" + File.separator + awbOutputName;\n        } else {\n            file = FD_ASSETS + File.separator + awbOutputName;\n        }\n\n        Set<String> assetsSoNames = variantContext.getAtlasExtension().getTBuildConfig().getKeepInAssetsSoNames();\n        if (!assetsSoNames.isEmpty() && assetsSoNames.contains(awbOutputName)) {\n            file = FD_ASSETS + File.separator + awbOutputName;\n        }\n        return file;\n    }\n\n    public File getAwbPackageOutputFile(AwbBundle awbBundle) {\n        String awbOutputName = awbBundle.getAwbSoName();\n\n        Set<String> libSoNames = variantContext.getAtlasExtension().getTBuildConfig().getKeepInLibSoNames();\n\n        File file = null;\n\n            file = new File(variantContext.getAwbApkOutputDir(), \"lib/armeabi\" + File.separator + awbOutputName);\n            file.getParentFile().mkdirs();\n        // }else {\n        //     file = new File(variantContext.getVariantData().mergeAssetsTask.getOutputDir(), awbOutputName);\n        // }\n        //\n        // Set<String> assetsSoNames = variantContext.getAtlasExtension().getTBuildConfig().getKeepInAssetsSoNames();\n        // if (!assetsSoNames.isEmpty() && assetsSoNames.contains(awbOutputName)) {\n        //     file = new File(variantContext.getVariantData().mergeAssetsTask.getOutputDir(), awbOutputName);\n        // }\n\n        Set<String> assetsSoNames = variantContext.getAtlasExtension().getTBuildConfig().getKeepInAssetsSoNames();\n        if (!assetsSoNames.isEmpty() && assetsSoNames.contains(awbOutputName)) {\n            file = new File(variantContext.getVariantData().mergeAssetsTask.getOutputDir(), awbOutputName);\n        }\n\n        awbBundle.outputBundleFile = file;\n        return file;\n    }\n\n    /**\n     * Download the download address for dynamic download\n     *\n     * @param awbBundle\n     * @return\n     */\n    public File getAwbPackageOutAppOutputFile(AwbBundle awbBundle) {\n        File outFolder = variantScope.getGlobalScope().getOutputsDir();\n        String awbOutputName = awbBundle.getAwbSoName();\n        File file = new File(outFolder,\n                             \"remote-bundles-\" +\n                             variantData.getVariantConfiguration().getDirName() +\n                             File.separator +\n                             awbOutputName);\n        file.getParentFile().mkdirs();\n        awbBundle.outputBundleFile = file;\n        return file;\n    }\n\n    public File getAwbJniFolder(AwbBundle awbBundle) {\n        return new File(variantScope.getGlobalScope().getIntermediatesDir(),\n                        \"/awb-jnis/\" +\n                        variantData.getVariantConfiguration().getDirName() +\n                        \"/\" +\n                        awbBundle.getName());\n    }\n\n\n    public File getAwbJavaResFolder(AwbBundle awbBundle) {\n        return new File(variantScope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-java-res/\" +\n                        variantData.getVariantConfiguration().getDirName() +\n                        \"/\" +\n                        awbBundle.getName());\n    }\n\n    public File getApkOutputFile(boolean checkExist) {\n        File apkFile;\n\n        apkFile = new File(variantScope.getApkLocation(),\n                      variantScope.getGlobalScope().getProjectBaseName() +\n                      \"-\" +\n                      variantData.getVariantConfiguration().getBaseName() +\n                      \".apk\");\n\n        if (checkExist && !apkFile.exists()) {\n\n            apkFile = new File(variantScope.getApkLocation(), apkData.getOutputFileName());\n        }\n\n            return apkFile;\n    }\n\n    public File getDiffResourceAp() {\n        return new File(variantContext.getScope().getGlobalScope().getIntermediatesDir(),\n                        \"res/resources-\" + variantContext.getVariantName() + \"-diff.ap_\");\n    }\n\n    public File getMappingTxt() {\n        File proguardOut = new File(String.valueOf(variantData.getScope()\n                                                           .getGlobalScope()\n                                                           .getBuildDir()) +\n                                    \"/\" +\n                                    FD_OUTPUTS +\n                                    \"/mapping/\" +\n                                    variantData.getScope().getVariantConfiguration().getDirName());\n        return new File(proguardOut, \"mapping.txt\");\n    }\n\n    public File getTPatchFolder() {\n        return new File(variantContext.getScope().getGlobalScope().getOutputsDir(),\n                        \"tpatch-\" + variantContext.getVariantName());\n    }\n\n    public File getIPatchFolder() {\n        return new File(variantContext.getScope().getGlobalScope().getOutputsDir(),\n                \"ipatch-\" + variantContext.getVariantName());\n    }\n\n    public File getIPatchFile(String versionName) {\n        if (!getIPatchFolder().exists()){\n            FileUtils.mkdirs(getIPatchFolder());\n        }\n        return new File(getIPatchFolder(),versionName + \"@\" + versionName + \".ipatch\");\n    }\n\n    public File getRemoteNativeSoFolder(String bundleName) {\n         File file = new File(variantContext.getScope().getGlobalScope().getOutputsDir(),\n                \"remote-nativeSos-\"+variantData.getVariantConfiguration().getDirName()+File.separator+bundleName);\n         return file;\n    }\n    public File getAPatchFolder() {\n        return new File(variantContext.getScope().getGlobalScope().getOutputsDir(),\n                        \"apatch-\" + variantContext.getVariantName());\n    }\n\n    public File getDiffApk() {\n        return new File(getTPatchFolder(), \"tpatch-diff.apk\");\n    }\n\n    public File getAwbDexOutput(String name) {\n        return new File(variantScope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-dex/\" + variantScope.getVariantConfiguration().getDirName() + \"/\" + name);\n\n    }\n\n    public File getAwbExternalLibsMergeFolder(AwbBundle key) {\n\n        return new File(variantScope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-external-dex/\" + variantScope.getVariantConfiguration().getDirName() + \"/\" + key.getName());\n    }\n\n    public File getMainDexOutDir() {\n        return new File(variantScope.getGlobalScope().getIntermediatesDir(),\n                \"/main-dex/\" + variantScope.getVariantConfiguration().getDirName() + \"/\" );\n    }\n\n    public  File updateAwbDexFile(JarInput jarInput, File output) {\n        boolean localJar = false;\n        if (jarInput.getName().startsWith(\"android.local.jars\")){\n            localJar = true;\n        }\n        if (localJar){\n            //todo awb localJars\n            //subproject local\n\n\n        }\n\n        for (AwbTransform awbTransform:awbTransformMap.values()){\n            if (awbTransform.getFileTransform().containsKey(jarInput.getFile())){\n                File currentFile = awbTransform.getFileTransform().get(jarInput.getFile());\n                awbTransform.getInputLibraries().remove(currentFile);\n                awbTransform.getInputLibraries().add(output);\n                return currentFile;\n            }else {\n               Iterator<File>iterator = awbTransform.getInputLibraries().listIterator();\n               while (iterator.hasNext()){\n                   File file = iterator.next();\n                   if (file.equals(jarInput.getFile())){\n                       iterator.remove();\n                       awbTransform.getInputLibraries().add(output);\n                       return jarInput.getFile();\n                   }\n               }\n            }\n\n        }\n        return null;\n    }\n\n    public void setDexMergeFolder(File outputDir) {\n       this.dexMergeOutFolder = outputDir;\n    }\n\n    public File getDexMergeFolder(){\n        return dexMergeOutFolder;\n    }\n\n    public File getAwbExtractJarsFolder(AwbBundle awbBundle) {\n        return new File(variantScope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-extractJars/\" +\n                        variantData.getVariantConfiguration().getDirName() +\n                        \"/\" +\n                        awbBundle.getName());\n\n    }\n\n    public File getAwbClassesInstantOut(AwbBundle awbBundle) {\n        return new File(variantScope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-instantRun/\" +\n                        variantData.getVariantConfiguration().getDirName() +\n                        \"/\" +\n                        awbBundle.getName());\n    }\n\n\n    public static class AppBuildInfo {\n\n        List<File> otherFiles = new ArrayList<File>();\n\n        //Path and file name\n        Map<String, File> otherFilesMap = new HashMap<>();\n\n        File dependencyTreeFile;\n\n        File dependenciesFile;\n\n        File versionPropertiesFile;\n\n        File buildInfoFile;\n\n        File packageIdFile;\n\n        File bundleInfoFile;\n\n        public File getDependencyTreeFile() {\n            return dependencyTreeFile;\n        }\n\n        public void setDependencyTreeFile(File dependencyTreeFile) {\n            this.dependencyTreeFile = dependencyTreeFile;\n        }\n\n        public File getDependenciesFile() {\n            return dependenciesFile;\n        }\n\n        public void setDependenciesFile(File dependenciesFile) {\n            this.dependenciesFile = dependenciesFile;\n        }\n\n        public File getVersionPropertiesFile() {\n            return versionPropertiesFile;\n        }\n\n        public void setVersionPropertiesFile(File versionPropertiesFile) {\n            this.versionPropertiesFile = versionPropertiesFile;\n        }\n\n        public File getBuildInfoFile() {\n            return buildInfoFile;\n        }\n\n        public void setBuildInfoFile(File buildInfoFile) {\n            this.buildInfoFile = buildInfoFile;\n        }\n\n        public File getPackageIdFile() {\n            return packageIdFile;\n        }\n\n        public void setPackageIdFile(File packageIdFile) {\n            this.packageIdFile = packageIdFile;\n        }\n\n        public File getBundleInfoFile() {\n            return bundleInfoFile;\n        }\n\n        public void setBundleInfoFile(File bundleInfoFile) {\n            this.bundleInfoFile = bundleInfoFile;\n        }\n\n        public List<File> getOtherFiles() {\n            return otherFiles;\n        }\n\n        public void setOtherFiles(List<File> otherFiles) {\n            this.otherFiles = otherFiles;\n        }\n\n        public Map<String, File> getOtherFilesMap() {\n            return otherFilesMap;\n        }\n\n        public void setOtherFilesMap(Map<String, File> otherFilesMap) {\n            this.otherFilesMap = otherFilesMap;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/api/AwbTransform.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.build.gradle.internal.api;\n\nimport java.io.File;\nimport java.util.*;\n\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Maps;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport org.gradle.api.artifacts.result.ResolvedArtifactResult;\n\n/**\n * AwbThe transmission of dependent files\n * Created by shenghua.nish on 2016-06-12 On the morning of mount zalmon.\n */\npublic class AwbTransform {\n\n    private final AwbBundle   awbBundle;\n    private List<File>        inputFiles        = Lists.newArrayList();\n    private List<File>        inputLibraries    = Lists.newArrayList();\n    private File              outDexFile;\n    private Map<String, File> inputLibrariesMap = Maps.newHashMap();\n    private File              javaResourcesInputDir;\n\n    public Map<File, File> getFileTransform() {\n        return fileTransform;\n    }\n\n    public void setFileTransform(Map<File, File> fileTransform) {\n        this.fileTransform = fileTransform;\n    }\n\n    private Map<File,File>    fileTransform = new HashMap<>();\n\n    public List<File> getLibraryResourcesInutDir() {\n        return libraryResourcesInutDir;\n    }\n\n    public void setLibraryResourcesInutDir(List<File> libraryResourcesInutDir) {\n        this.libraryResourcesInutDir = libraryResourcesInutDir;\n    }\n\n    private List<File>        libraryResourcesInutDir = Lists.newArrayList();\n\n    public List<File> getLibraryJniLibsInputDir() {\n        return libraryJniLibsInputDir;\n    }\n\n    public void setLibraryJniLibsInputDir(List<File> libraryJniLibsInputDir) {\n        this.libraryJniLibsInputDir = libraryJniLibsInputDir;\n    }\n\n    private List<File>        libraryJniLibsInputDir = Lists.newArrayList();\n\n    public File getInputLib() {\n        return inputLib;\n    }\n\n    public void setInputLib(File inputLib) {\n        this.inputLib = inputLib;\n    }\n\n    private File              inputLib;\n    private Collection<File>              inputDirs = new HashSet<>();\n\n    public AwbTransform(AwbBundle awbBundle){\n        this.awbBundle = awbBundle;\n    }\n\n    public List<File> getInputFiles() {\n        return inputFiles;\n    }\n\n    public void setInputFiles(List<File> inputFiles) {\n        this.inputFiles = inputFiles;\n    }\n\n    public List<File> getInputLibraries() {\n        return inputLibraries;\n    }\n\n    public void setInputLibraries(List<File> inputLibraries) {\n        this.inputLibraries = inputLibraries;\n    }\n\n    public Map<String, File> getInputLibrariesMap() {\n        return inputLibrariesMap;\n    }\n\n    public void setInputLibrariesMap(Map<String, File> inputLibrariesMap) {\n        this.inputLibrariesMap = inputLibrariesMap;\n    }\n\n    public File getJavaResourcesInputDir() {\n        return javaResourcesInputDir;\n    }\n\n    public void setJavaResourcesInputDir(File javaResourcesInputDir) {\n        this.javaResourcesInputDir = javaResourcesInputDir;\n    }\n\n    public Collection<File> getInputDirs() {\n        return inputDirs;\n    }\n\n    public void setInputDirs(Collection<File> inputDirs) {\n        this.inputDirs = inputDirs;\n    }\n\n    public void addDir(File file){\n        inputDirs.add(file);\n    }\n\n    public AwbBundle getAwbBundle() {\n        return awbBundle;\n    }\n\n    public File getOutDexFile() {\n        return outDexFile;\n    }\n\n    public void setOutDexFile(File outDexFile) {\n        this.outDexFile = outDexFile;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/api/FeatureVariantContext.java",
    "content": "package com.android.build.gradle.internal.api;\n\nimport com.android.build.gradle.AppExtension;\nimport com.android.build.gradle.FeatureExtension;\nimport com.android.build.gradle.tasks.MergeManifests;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.result.ResolvedArtifactResult;\n\nimport java.io.File;\n\n/**\n * FeatureVariantContext\n *\n * @author zhayu.ll\n * @date 18/1/4\n * @time 下午2:50\n * @description  \n */\npublic class FeatureVariantContext extends VariantContext {\n\n    public FeatureVariantContext(FeatureVariantImpl featureVariant, Project project, AtlasExtension atlasExtension, FeatureExtension featureExtension) {\n        super(featureVariant,project,atlasExtension,featureExtension);\n    }\n\n    public File getModifiedManifest(ResolvedArtifactResult artifact) {\n        return new File(getModifyManifestDir(),\n                MergeManifests.getArtifactName(artifact) +\n                        \".xml\");\n\n    }\n\n    public File getModifyManifestDir() {\n        return new File(scope.getGlobalScope().getIntermediatesDir(),\n                \"/manifest-modify/\" + getVariantConfiguration().getDirName() + \"/\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/api/LibVariantContext.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.build.gradle.internal.api;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.LibraryExtension;\nimport com.android.build.gradle.internal.variant.LibraryVariantData;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.tasks.manager.TaskQueryHelper;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.Project;\nimport org.gradle.api.tasks.bundling.Zip;\n\n/**\n * Created by shenghua.nish on 2016-07-15 On the morning of 9:06.\n */\npublic class LibVariantContext extends VariantContext<LibraryVariantImpl, LibraryExtension, AtlasExtension> {\n\n    private Zip bundleTask;\n    private LibraryVariantData variantData;\n\n    private List<File> jarDexList;\n\n    private AwbBundle awbBundle;\n\n    public LibVariantContext(LibraryVariantImpl libraryVariant, Project project, @NonNull AtlasExtension atlasExtension,\n                             LibraryExtension libraryExtension) {\n        super(libraryVariant, project, atlasExtension, libraryExtension);\n        this.variantData = (LibraryVariantData)baseVariantData;\n    }\n\n    public Zip getBundleTask() {\n        return bundleTask;\n    }\n\n    public void setBundleTask(Zip bundleTask) {\n        this.bundleTask = bundleTask;\n    }\n\n    public LibraryVariantData getVariantData() {\n        return variantData;\n    }\n\n    public void setVariantData(LibraryVariantData variantData) {\n        this.variantData = variantData;\n    }\n\n    public List<File> getJarDexList() {\n        return jarDexList;\n    }\n\n    public void setJarDexList(List<File> jarDexList) {\n        this.jarDexList = jarDexList;\n    }\n\n    public AwbBundle getAwbBundle() {\n        return awbBundle;\n    }\n\n    public void setAwbBundle(AwbBundle awbBundle) {\n        this.awbBundle = awbBundle;\n    }\n\n    public List<Zip> getZipTasks() {\n        List<Zip> zipTasks = TaskQueryHelper.findTask(project, Zip.class, getBaseVariantData());\n        List<Zip> result = new ArrayList<Zip>();\n        if (null != zipTasks) {\n            for (Zip zipTask : zipTasks) {\n                if (zipTask.getName().contains(\"bundle\")) {\n                    result.add(zipTask);\n                }\n            }\n        }\n        return result;\n    }\n\n    public File getSourceOutputDir() {\n        return new File(scope.getGlobalScope().getGeneratedDir(),\n                        \"source/awb-r/\" + variantData.getVariantConfiguration().getFullName() + \"/\" + awbBundle\n                            .getName());\n    }\n\n    public File getJavaCDir() {\n        return new File(scope.getGlobalScope().getIntermediatesDir(),\n                        \"/awb-classes/\" + variantData.getVariantConfiguration().getFullName() + \"/\" + awbBundle\n                            .getName());\n    }\n\n    public File getDex() {\n        return new File(scope.getGlobalScope().getBuildDir(), \"dex/classes.dex\");\n    }\n\n    public File getDexFolder() {\n        return new File(scope.getGlobalScope().getIntermediatesDir(),\n                        \"/awb-dex/\" + variantData.getVariantConfiguration().getFullName() + \"/\" + awbBundle.getName());\n    }\n\n    public File getOutputResouceAP() {\n        return new File(scope.getGlobalScope().getIntermediatesDir(), \"res/\" + awbBundle.getName() + \"/resources.ap_\");\n    }\n\n    public File getPackageFile() {\n        if (null != awbBundle.outputBundleFile) {\n            return awbBundle.outputBundleFile;\n        }\n        File manifest = this.getVariantConfiguration().getDefaultSourceSet().getManifestFile();\n        //                Set<String> outOfApkBundles = atlasExtension.getTBuildConfig().getOutOfApkBundles();\n        //                File manifest = libVariantContext.getMergeAwoManifests().getManifestOutputFile();\n        if (null == manifest) {\n            return null;\n        }\n\n        final String packageName = ManifestFileUtils.getPackage(manifest);\n        ;\n        return getAwbPackageOutAppOutputFile(awbBundle, packageName);\n    }\n\n    private File getAwbPackageOutAppOutputFile(AwbBundle awbBundle, String packageName) {\n        File outFolder = scope.getGlobalScope().getOutputsDir();\n        String awbOutputName = getAwbSoName(packageName);\n        File file = new File(outFolder, \"awbs\" + File.separator + awbOutputName);\n        awbBundle.isRemote = true;\n        awbBundle.outputBundleFile = file;\n        return file;\n    }\n\n    private String getAwbSoName(String packageName) {\n        String awbOutputName = \"lib\" + StringUtils.replace(packageName, \".\", \"_\");\n        return awbOutputName + \".so\";\n    }\n\n    public File getMergedManifest() {\n        File manifestOutFile = new File(scope.getGlobalScope().getIntermediatesDir(),\n                                        \"awb-manifest/\" + variantData.getVariantConfiguration().getFullName() +\n                                            \"/\" +\n                                            \"AndroidManifest.xml\");\n        return manifestOutFile;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/api/VariantContext.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.build.gradle.internal.api;\n\nimport com.android.build.gradle.BaseExtension;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.dependency.VariantDependencies;\nimport com.android.build.gradle.internal.pipeline.InjectTransformManager;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.variant.BaseVariantData;\nimport com.android.builder.signing.DefaultSigningConfig;\nimport com.android.utils.FileUtils;\nimport com.android.utils.StringHelper;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.extension.TBuildType;\nimport org.gradle.api.Project;\n\nimport java.io.File;\nimport java.lang.reflect.Method;\nimport java.util.Collection;\n\n/**\n * Created by shenghua.nish on 2016-05-19 Whether in the afternoon.\n */\npublic class VariantContext<T extends BaseVariantImpl, Z extends BaseExtension, E extends AtlasExtension> {\n\n    protected T baseVariant;\n    protected BaseVariantData baseVariantData;\n    protected VariantDependencies variantDependency;\n    protected GradleVariantConfiguration variantConfiguration;\n    protected VariantScope scope;\n    protected Project project;\n    protected InjectTransformManager injectTransformManager;\n    protected E atlasExtension;\n    protected Z appExtension;\n\n    public ApContext apContext = new ApContext();\n\n    public VariantContext(T baseVariant, Project project, E atlasExtension, Z appExtension) {\n        this.baseVariant = baseVariant;\n\n        //classloader It could be father-son relationship, protected The direct invocation of the method throws an exception\n        try {\n            Class clazz = baseVariant.getClass();\n            Method method = clazz.getDeclaredMethod(\"getVariantData\");\n            method.setAccessible(true);\n            this.baseVariantData = (BaseVariantData) method.invoke(baseVariant);\n//            this.baseVariantData = baseVariant.getVariantData();\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n\n        this.variantDependency = this.baseVariantData.getVariantDependency();\n\n        this.scope = this.baseVariantData.getScope();\n\n        this.variantConfiguration = this.baseVariantData.getVariantConfiguration();\n        this.project = project;\n        this.injectTransformManager = new InjectTransformManager(project, variantConfiguration.getFullName());\n        this.atlasExtension = atlasExtension;\n        this.appExtension = appExtension;\n\n    }\n\n    public T getBaseVariant() {\n        return baseVariant;\n    }\n\n    public BaseVariantData getBaseVariantData() {\n        return baseVariantData;\n    }\n\n    public VariantDependencies getVariantDependency() {\n        return variantDependency;\n    }\n\n    public VariantScope getScope() {\n        return scope;\n    }\n\n    public GradleVariantConfiguration getVariantConfiguration() {\n        return variantConfiguration;\n    }\n\n    public Project getProject() {\n        return project;\n    }\n\n    public InjectTransformManager getInjectTransformManager() {\n        return injectTransformManager;\n    }\n\n    public String getVariantName() {\n        return variantConfiguration.getFullName();\n    }\n\n    public AtlasExtension getAtlasExtension() {\n        return atlasExtension;\n    }\n\n    public Z getAppExtension() {\n        return appExtension;\n    }\n\n    public TBuildType getBuildType() {\n        TBuildType tBuildType = (TBuildType) atlasExtension.getBuildTypes().findByName(variantConfiguration.getBuildType().getName());\n        if (null == tBuildType) {\n            tBuildType = new TBuildType(variantConfiguration.getBuildType().getName());\n        }\n        return tBuildType;\n    }\n\n    public DefaultSigningConfig getSigningConfig() {\n        TBuildType tBuildType = getBuildType();\n        return tBuildType.getSigningConfig();\n    }\n\n    public Collection<BaseVariantOutput> getVariantOutputData() {\n        return baseVariant.getOutputs();\n    }\n\n\n    public File getMergeAssets(AwbBundle awbBundle) {\n        return new File(scope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-assets/merged/\" + variantConfiguration.getFullName() + \"/\"\n                        + awbBundle.getName());\n    }\n\n    public File getMergeResources(AwbBundle awbBundle) {\n        return new File(scope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-res/merged/\" + variantConfiguration.getFullName() + \"/\" + awbBundle.getName());\n    }\n\n    public File getMergeNotCompiledFolder(AwbBundle awbBundle) {\n\n        return new File(\n                scope.getGlobalScope().getIntermediatesDir()\n                        + \"/awb-merged-not-compiled-resources/\"\n                        + scope.getVariantConfiguration().getDirName()+\"/\"+awbBundle.getName());\n    }\n    public File getGenerateResValue(AwbBundle awbBundle){\n        return new File(scope.getGlobalScope().getGeneratedDir().getParentFile(),\n                \"/awb-generated/\" + StringHelper.toStrings(\"res\", \"resValue\", scope.getDirectorySegments(),\n                        awbBundle.getName()));\n    }\n\n    public File getGenerateRs(AwbBundle awbBundle){\n        return new File(scope.getGlobalScope().getGeneratedDir().getParentFile(),\n                \"/awb-generated/\" + StringHelper.toStrings(\"res\", \"rs\", scope.getDirectorySegments(),\n                        awbBundle.getName()));\n    }\n\n    public File getPngsOutputDir(AwbBundle awbBundle) {\n        return FileUtils.join(new File(scope.getGlobalScope().getGeneratedDir().getParentFile(),\n                        \"awb-generated\"),\n                StringHelper.toStrings(\"res\", \"pngs\", scope.getDirectorySegments(),\n                        awbBundle.getName()));\n    }\n\n    public File getRenderOutputDir(AwbBundle awbBundle) {\n        return FileUtils.join(new File(scope.getGlobalScope().getGeneratedDir().getParentFile(),\n                        \"awb-generated\"),\n                StringHelper.toStrings(\"res\",\"renderscript\", scope.getDirectorySegments(),\n                        awbBundle.getName()));\n    }\n\n    public File getAwbResourceBlameLogDir(AwbBundle awbBundle) {\n        return FileUtils.join(\n                scope.getGlobalScope().getIntermediatesDir(),\n                StringHelper.toStrings(\n                        \"awb-blame\", \"res\", scope.getDirectorySegments(),awbBundle.getName()));\n\n    }\n\n    public File getAwbShadersOutputDir(AwbBundle awbBundle) {\n        return FileUtils.join(new File(\n                scope.getGlobalScope().getGeneratedDir().getParentFile(),\"/awb-generated/\"),\n                StringHelper.toStrings(\n                        \"assets\", \"shaders\", scope.getDirectorySegments(),awbBundle.getName()));\n\n    }\n\n    public File getAwbMergeNativeLibsOutputDir(AwbBundle awbBundle) {\n        return FileUtils.join(scope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-jniLibs/\" + getVariantConfiguration().getDirName(),awbBundle.getName());\n    }\n\n    public File getMergeShadersOutputDir(AwbBundle awbBundle) {\n        return FileUtils.join(scope.getGlobalScope().getIntermediatesDir(),\n                \"/awb-shaders/\" + getVariantConfiguration().getDirName(),awbBundle.getName());\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/ide/AtlasAndroidLibraryImpl.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.build.gradle.internal.ide;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.annotations.concurrency.Immutable;\nimport com.android.builder.dependency.level2.AndroidDependency;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.builder.model.JavaLibrary;\nimport com.google.common.base.MoreObjects;\nimport com.google.common.base.Objects;\nimport com.google.common.collect.ImmutableList;\n\nimport java.io.File;\nimport java.io.Serializable;\nimport java.util.Collection;\nimport java.util.List;\n\nimport static com.android.SdkConstants.FN_ANDROID_MANIFEST_XML;\n\n/**\n * Serializable implementation of AndroidLibrary for use in the model.\n */\n@Immutable\npublic final class AtlasAndroidLibraryImpl extends LibraryImpl implements AndroidLibrary, Serializable {\n    private static final long serialVersionUID = 1L;\n\n    @Nullable\n    private String variant;\n    private String path;\n\n    public AndroidDependency getAndroidLibrary() {\n        return androidLibrary;\n    }\n\n    public void setAndroidLibrary(AndroidDependency androidLibrary) {\n        this.androidLibrary = androidLibrary;\n    }\n\n    private  AndroidDependency androidLibrary;\n\n    @NonNull\n    private  File folder;\n    @NonNull\n    private File manifest;\n    @NonNull\n    private File jarFile;\n    @NonNull\n    private File resFolder;\n    @NonNull\n    private File assetsFolder;\n    @NonNull\n    private File jniFolder;\n    @NonNull\n    private File aidlFolder;\n    @NonNull\n    private File renderscriptFolder;\n\n    private final File bundle = null;\n    @NonNull\n    private  File proguardRules;\n    @NonNull\n    private File lintJar;\n    @NonNull\n    private File annotations;\n    @NonNull\n    private File publicResources;\n    @NonNull\n    private File symbolFile;\n    @NonNull\n    private final List<AndroidLibrary> androidLibraries;\n    @NonNull\n    private final Collection<JavaLibrary> javaLibraries;\n    @NonNull\n    private Collection<File> localJars;\n\n    private int hashcode;\n\n    public AtlasAndroidLibraryImpl(\n            @NonNull AndroidDependency clonedLibrary,\n            boolean isProvided,\n            boolean isSkipped,\n            @NonNull List<AndroidLibrary> androidLibraries,\n            @NonNull Collection<JavaLibrary> javaLibraries,\n            @NonNull Collection<File> localJavaLibraries) {\n        super(\n                clonedLibrary.getProjectPath(),\n                null,\n                clonedLibrary.getCoordinates(),\n                isSkipped,\n                isProvided);\n\n\n        this.androidLibrary = clonedLibrary;\n        this.androidLibraries = ImmutableList.copyOf(androidLibraries);\n        this.javaLibraries = ImmutableList.copyOf(javaLibraries);\n        this.variant = androidLibrary.getVariant();\n        //FIXME , add localJar later at prepareAllDependencies\n//        this.localJars = clonedLibrary.getLocalJars();\n//        variant = clonedLibrary.getVariant();\n////        bundle = .getArtifactFile();\n////        bundle = clonedLibrary.getClasspathFile();\n//        folder = clonedLibrary.getExtractedFolder();\n//        manifest = clonedLibrary.getManifest();\n//        jarFile = clonedLibrary.getJarFile();\n//        resFolder = clonedLibrary.getResFolder();\n//        assetsFolder = clonedLibrary.getAssetsFolder();\n//        jniFolder = clonedLibrary.getJniFolder();\n//        aidlFolder = clonedLibrary.getAidlFolder();\n//        renderscriptFolder = clonedLibrary.getRenderscriptFolder();\n//        proguardRules = clonedLibrary.getProguardRules();\n//        lintJar = clonedLibrary.getLintJar();\n//        annotations = clonedLibrary.getExternalAnnotations();\n//        publicResources = clonedLibrary.getPublicResources();\n//        symbolFile = clonedLibrary.getSymbolFile();\n//        hashcode = computeHashCode();\n    }\n\n    @Nullable\n    @Override\n    public String getProjectVariant() {\n        return variant;\n    }\n\n    @Override\n    public File getBundle() {\n        return null;\n    }\n\n//    @NonNull\n//    @Override\n//    public File getBundle() {\n//        return bundle;\n//    }\n\n    public void setFolder(File folder){\n        this.folder = folder;\n    }\n\n    @NonNull\n    @Override\n    public File getFolder() {\n        this.folder = androidLibrary.getExtractedFolder();\n        return folder;\n    }\n\n    @NonNull\n    @Override\n    public List<? extends AndroidLibrary> getLibraryDependencies() {\n        return androidLibraries;\n    }\n\n    @NonNull\n    @Override\n    public Collection<? extends JavaLibrary> getJavaDependencies() {\n        return javaLibraries;\n    }\n\n    @NonNull\n    @Override\n    public Collection<File> getLocalJars() {\n        this.localJars = androidLibrary.getLocalJars();\n        return localJars;\n    }\n\n    @NonNull\n    @Override\n    public File getManifest() {\n        this.manifest = new File(getFolder(),FN_ANDROID_MANIFEST_XML);\n        return manifest;\n    }\n\n    @NonNull\n    @Override\n    public File getJarFile() {\n        this.jarFile = androidLibrary.getJarFile();\n        return jarFile;\n    }\n\n    @NonNull\n    @Override\n    public File getResFolder() {\n        this.resFolder = androidLibrary.getResFolder();\n        return resFolder;\n    }\n\n    @NonNull\n    @Override\n    public File getAssetsFolder() {\n        this.assetsFolder = androidLibrary.getAssetsFolder();\n        return assetsFolder;\n    }\n\n    public String getPath(){\n        this.path = androidLibrary.getProjectPath();\n        return path;\n    }\n\n    @NonNull\n    @Override\n    public File getJniFolder() {\n        this.jniFolder = androidLibrary.getJniFolder();\n        return jniFolder;\n    }\n\n    @NonNull\n    @Override\n    public File getAidlFolder() {\n        this.aidlFolder = androidLibrary.getAidlFolder();\n        return aidlFolder;\n    }\n\n    public File getFile(){\n        return androidLibrary.getArtifactFile();\n    }\n\n    @NonNull\n    @Override\n    public File getRenderscriptFolder() {\n        renderscriptFolder = androidLibrary.getRenderscriptFolder();\n        return renderscriptFolder;\n    }\n\n    @NonNull\n    @Override\n    public File getProguardRules() {\n        proguardRules = androidLibrary.getProguardRules();\n        return proguardRules;\n    }\n\n    @NonNull\n    @Override\n    public File getLintJar() {\n        lintJar =  androidLibrary.getLintJar();\n        return lintJar;\n    }\n\n    @NonNull\n    @Override\n    public File getExternalAnnotations() {\n        annotations = androidLibrary.getExternalAnnotations();\n        return annotations;\n    }\n\n    @Override\n    @NonNull\n    public File getPublicResources() {\n        this.publicResources = androidLibrary.getPublicResources();\n        return publicResources;\n    }\n\n    @Override\n    @Deprecated\n    public boolean isOptional() {\n        return isProvided();\n    }\n\n    @NonNull\n    @Override\n    public File getSymbolFile() {\n         this.symbolFile = androidLibrary.getSymbolFile();\n         return symbolFile;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) {\n            return true;\n        }\n        if (o == null || getClass() != o.getClass()) {\n            return false;\n        }\n\n        AtlasAndroidLibraryImpl that = (AtlasAndroidLibraryImpl) o;\n\n        // quick fail on hashcode to avoid comparing the whole tree\n        if (hashcode != that.hashcode || !super.equals(o)) {\n            return false;\n        }\n\n        return Objects.equal(variant, that.variant) &&\n                Objects.equal(bundle, that.bundle) &&\n                Objects.equal(folder, that.folder) &&\n                Objects.equal(manifest, that.manifest) &&\n                Objects.equal(jarFile, that.jarFile) &&\n                Objects.equal(resFolder, that.resFolder) &&\n                Objects.equal(assetsFolder, that.assetsFolder) &&\n                Objects.equal(jniFolder, that.jniFolder) &&\n                Objects.equal(aidlFolder, that.aidlFolder) &&\n                Objects.equal(renderscriptFolder, that.renderscriptFolder) &&\n                Objects.equal(proguardRules, that.proguardRules) &&\n                Objects.equal(lintJar, that.lintJar) &&\n                Objects.equal(annotations, that.annotations) &&\n                Objects.equal(publicResources, that.publicResources) &&\n                Objects.equal(symbolFile, that.symbolFile) &&\n                Objects.equal(androidLibraries, that.androidLibraries) &&\n                Objects.equal(javaLibraries, that.javaLibraries) &&\n                Objects.equal(localJars, that.localJars);\n    }\n\n    @Override\n    public int hashCode() {\n        return hashcode;\n    }\n\n    private int computeHashCode() {\n        return Objects.hashCode(\n                super.hashCode(), variant, bundle, folder, manifest, jarFile, resFolder,\n                assetsFolder, jniFolder, aidlFolder, renderscriptFolder, proguardRules, lintJar,\n                annotations, publicResources, symbolFile, androidLibraries, javaLibraries,\n                localJars);\n    }\n\n    @Override\n    public String toString() {\n        return MoreObjects.toStringHelper(this)\n                .add(\"name\", getName())\n                .add(\"project\", getProject())\n                .add(\"variant\", variant)\n                .add(\"bundle\", bundle)\n                .add(\"folder\", folder)\n                .add(\"manifest\", manifest)\n                .add(\"jarFile\", jarFile)\n                .add(\"resFolder\", resFolder)\n                .add(\"assetsFolder\", assetsFolder)\n                .add(\"jniFolder\", jniFolder)\n                .add(\"aidlFolder\", aidlFolder)\n                .add(\"renderscriptFolder\", renderscriptFolder)\n                .add(\"proguardRules\", proguardRules)\n                .add(\"lintJar\", lintJar)\n                .add(\"annotations\", annotations)\n                .add(\"publicResources\", publicResources)\n                .add(\"symbolFile\", symbolFile)\n                .add(\"androidLibraries\", androidLibraries)\n                .add(\"javaLibraries\", javaLibraries)\n                .add(\"localJars\", localJars)\n                .add(\"super\", super.toString())\n                .toString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/ide/AtlasDependencyGraph.java",
    "content": "package com.android.build.gradle.internal.ide;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.gradle.internal.dependency.ArtifactCollectionWithExtraArtifact;\nimport com.android.build.gradle.internal.dependency.ConfigurationDependencyGraphs;\nimport com.android.build.gradle.internal.dependency.FilteredArtifactCollection;\nimport com.android.build.gradle.internal.dependency.VariantAttr;\nimport com.android.build.gradle.internal.ide.level2.*;\nimport com.android.build.gradle.internal.ide.level2.JavaLibraryImpl;\nimport com.android.build.gradle.internal.publishing.AndroidArtifacts;\nimport com.android.build.gradle.internal.publishing.AtlasAndroidArtifacts;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.options.BooleanOption;\nimport com.android.builder.core.VariantType;\nimport com.android.builder.dependency.MavenCoordinatesImpl;\nimport com.android.builder.model.*;\nimport com.android.builder.model.level2.DependencyGraphs;\nimport com.android.builder.model.level2.GraphItem;\nimport com.android.builder.model.level2.Library;\nimport com.android.ide.common.caching.CreatingCache;\nimport com.android.utils.FileUtils;\nimport com.android.utils.ImmutableCollectors;\nimport com.google.common.base.Preconditions;\nimport com.google.common.collect.*;\nimport com.taobao.android.builder.AtlasPlugin;\nimport org.gradle.api.Action;\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.ArtifactCollection;\nimport org.gradle.api.artifacts.Configuration;\nimport org.gradle.api.artifacts.component.ComponentArtifactIdentifier;\nimport org.gradle.api.artifacts.component.ComponentIdentifier;\nimport org.gradle.api.artifacts.component.ModuleComponentIdentifier;\nimport org.gradle.api.artifacts.component.ProjectComponentIdentifier;\nimport org.gradle.api.artifacts.dsl.DependencyHandler;\nimport org.gradle.api.artifacts.query.ArtifactResolutionQuery;\nimport org.gradle.api.artifacts.result.ResolvedArtifactResult;\nimport org.gradle.api.artifacts.result.ResolvedVariantResult;\nimport org.gradle.api.attributes.AttributeContainer;\nimport org.gradle.api.component.Artifact;\nimport org.gradle.api.specs.Spec;\nimport org.gradle.internal.component.local.model.OpaqueComponentArtifactIdentifier;\nimport org.gradle.jvm.JvmLibrary;\nimport org.gradle.language.base.artifact.SourcesArtifact;\n\nimport java.io.File;\nimport java.util.*;\nimport java.util.function.Consumer;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport static com.android.SdkConstants.*;\nimport static com.android.build.gradle.internal.ide.ModelBuilder.EMPTY_DEPENDENCIES_IMPL;\nimport static com.android.build.gradle.internal.ide.ModelBuilder.EMPTY_DEPENDENCY_GRAPH;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ARTIFACT_TYPE;\n\n/**\n * @author lilong\n * @create 2017-12-01 下午1:24\n */\n\npublic class AtlasDependencyGraph{\n\n\n    private static final String LOCAL_AAR_GROUPID = \"__local_aars__\";\n\n    public static final CreatingCache<AtlasDependencyGraph.HashableResolvedArtifactResult, MavenCoordinates>\n            sMavenCoordinatesCache =\n            new CreatingCache<>(AtlasDependencyGraph::computeMavenCoordinates);\n\n    public static final CreatingCache<AtlasDependencyGraph.HashableResolvedArtifactResult, Library> sLibraryCache =\n            new CreatingCache<>(AtlasDependencyGraph::instantiateLibrary);\n\n    public static final Map<String, Library> sGlobalLibrary = Maps.newHashMap();\n\n    public static final Map<String, AtlasDependencyGraph.HashableResolvedArtifactResult> sLibraryMap = new HashMap<>();\n\n    private DependencyFailureHandler dependencyFailureHandler = new DependencyFailureHandler();\n\n\n    public static void clearCaches() {\n        sMavenCoordinatesCache.clear();\n        sLibraryCache.clear();\n    }\n\n    @NonNull\n    private static Library instantiateLibrary(@NonNull AtlasDependencyGraph.HashableResolvedArtifactResult artifact) {\n        Library library;\n        ComponentIdentifier id = artifact.getId().getComponentIdentifier();\n        String address = AtlasDependencyGraph.computeAddress(artifact);\n\n        if (!(id instanceof ProjectComponentIdentifier) || artifact.isWrappedModule()) {\n            if (artifact.getDependencyType() == DependencyType.ANDROID||artifact.getDependencyType() == DependencyType.AWB) {\n                File explodedFolder = artifact.getFile();\n                library =\n                        new com.android.build.gradle.internal.ide.level2.AndroidLibraryImpl(\n                                address,\n                                artifact.bundleResult != null\n                                        ? artifact.bundleResult.getFile()\n                                        : explodedFolder, // fallback so that the value is non-null\n                                explodedFolder,\n                                findLocalJarsAsStrings(explodedFolder));\n            } else {\n                library = new JavaLibraryImpl(address, artifact.getFile());\n            }\n        } else {\n            library =\n                    new ModuleLibraryImpl(\n                            address,\n                            ((ProjectComponentIdentifier) id).getProjectPath(),\n                            getVariant(artifact));\n        }\n\n        synchronized (sGlobalLibrary) {\n            sGlobalLibrary.put(library.getArtifactAddress(), library);\n        }\n\n        return library;\n    }\n\n    public static Map<String, Library> getGlobalLibMap() {\n        return ImmutableMap.copyOf(sGlobalLibrary);\n    }\n\n    @Nullable\n    public static String getVariant(@NonNull ResolvedArtifactResult artifact) {\n        VariantAttr variantAttr =\n                artifact.getVariant().getAttributes().getAttribute(VariantAttr.ATTRIBUTE);\n        return variantAttr == null ? null : variantAttr.getName();\n    }\n\n    @NonNull\n    public static String computeAddress(@NonNull AtlasDependencyGraph.HashableResolvedArtifactResult artifact) {\n        ComponentIdentifier id = artifact.getId().getComponentIdentifier();\n        if (id instanceof ProjectComponentIdentifier) {\n            String variant = getVariant(artifact);\n            if (variant == null) {\n                return ((ProjectComponentIdentifier) id).getProjectPath().intern();\n            } else {\n                return (((ProjectComponentIdentifier) id).getProjectPath() + \"::\" + variant)\n                        .intern();\n            }\n        } else if (id instanceof ModuleComponentIdentifier || id instanceof OpaqueComponentArtifactIdentifier) {\n            MavenCoordinates coordinates = sMavenCoordinatesCache.get(artifact);\n            Optional.of(coordinates);\n            return coordinates.toString().intern();\n        } else {\n            throw new RuntimeException(\n                    \"Don't know how to handle ComponentIdentifier '\"\n                            + id.getDisplayName()\n                            + \"'of type \"\n                            + id.getClass());\n        }\n    }\n\n    @NonNull\n    private static MavenCoordinates computeMavenCoordinates(\n            @NonNull ResolvedArtifactResult artifact) {\n        // instance should be a hashable.\n        AtlasDependencyGraph.HashableResolvedArtifactResult hashableResult = (AtlasDependencyGraph.HashableResolvedArtifactResult) artifact;\n\n        ComponentIdentifier id = artifact.getId().getComponentIdentifier();\n\n        final File artifactFile = artifact.getFile();\n        final String fileName = artifactFile.getName();\n        String extension = hashableResult.getDependencyType().getExtension();\n        if (id instanceof ModuleComponentIdentifier) {\n            ModuleComponentIdentifier moduleComponentId = (ModuleComponentIdentifier) id;\n            final String module = moduleComponentId.getModule();\n            final String version = moduleComponentId.getVersion();\n            String classifier = null;\n\n            if (!artifact.getFile().isDirectory()) {\n                // attempts to compute classifier based on the filename.\n                String pattern = \"^\" + module + \"-\" + version + \"-(.+)\\\\.\" + extension + \"$\";\n\n                Pattern p = Pattern.compile(pattern);\n                Matcher m = p.matcher(fileName);\n                if (m.matches()) {\n                    classifier = m.group(1);\n                }\n            }\n\n            return new MavenCoordinatesImpl(\n                    moduleComponentId.getGroup(), module, version, extension, classifier);\n        } else if (id instanceof ProjectComponentIdentifier) {\n            return new MavenCoordinatesImpl(\n                    \"artifacts\", ((ProjectComponentIdentifier) id).getProjectPath(), \"unspecified\");\n        } else if (id instanceof OpaqueComponentArtifactIdentifier) {\n            // We have a file based dependency\n            if (hashableResult.getDependencyType() == DependencyType.JAVA) {\n                return getMavenCoordForLocalFile(artifactFile);\n            } else {\n                // local aar?\n                assert artifactFile.isDirectory();\n                return getMavenCoordForLocalFile(artifactFile);\n            }\n        }\n\n        throw new RuntimeException(\n                \"Don't know how to compute maven coordinate for artifact '\"\n                        + artifact.getId().getDisplayName()\n                        + \"' with component identifier of type '\"\n                        + id.getClass()\n                        + \"'.\");\n    }\n\n    @NonNull\n    public static MavenCoordinatesImpl getMavenCoordForLocalFile(File artifactFile) {\n        return new MavenCoordinatesImpl(LOCAL_AAR_GROUPID, artifactFile.getPath(), \"unspecified\");\n    }\n\n\n    public static ArtifactCollection computeArtifactCollection(\n            VariantScope variantScope,\n            @NonNull AtlasAndroidArtifacts.ConsumedConfigType configType,\n            @NonNull AndroidArtifacts.ArtifactScope scope,\n            @NonNull AtlasAndroidArtifacts.AtlasArtifactType artifactType) {\n\n        Configuration configuration;\n        switch (configType) {\n            case COMPILE_CLASSPATH:\n                configuration = variantScope.getVariantData().getVariantDependency().getCompileClasspath();\n                break;\n            case RUNTIME_CLASSPATH:\n                configuration = variantScope.getVariantData().getVariantDependency().getRuntimeClasspath();\n                break;\n            case BUNDLECOMPILE_CLASSPATH:\n                configuration = variantScope.getGlobalScope().getProject().getConfigurations().maybeCreate(AtlasPlugin.BUNDLE_COMPILE);\n                break;\n            case ANNOTATION_PROCESSOR:\n                configuration = variantScope.getVariantData()\n                        .getVariantDependency()\n                        .getAnnotationProcessorConfiguration();\n                break;\n            case METADATA_VALUES:\n                configuration =\n                        variantScope.getVariantData().getVariantDependency().getMetadataValuesConfiguration();\n                break;\n            default:\n                throw new RuntimeException(\"unknown ConfigType value\");\n        }\n\n        Action<AttributeContainer> attributes =\n                container -> container.attribute(ARTIFACT_TYPE, artifactType.getType());\n\n        Spec<ComponentIdentifier> filter = getComponentFilter(scope);\n\n        boolean lenientMode =\n                Boolean.TRUE.equals(\n                        variantScope.getGlobalScope().getProjectOptions().get(BooleanOption.IDE_BUILD_MODEL_ONLY));\n\n        ArtifactCollection artifacts =  configuration\n                .getIncoming()\n                .artifactView(\n                        config -> {\n                            config.attributes(attributes);\n                            if (filter != null) {\n                                config.componentFilter(filter);\n                            }\n                            // TODO somehow read the unresolved dependencies?\n                            config.lenient(lenientMode);\n                        })\n                .getArtifacts();\n\n        if (configType == AtlasAndroidArtifacts.ConsumedConfigType.RUNTIME_CLASSPATH\n                && variantScope.getVariantConfiguration().getType() == VariantType.FEATURE\n                && artifactType != AtlasAndroidArtifacts.AtlasArtifactType.FEATURE_TRANSITIVE_DEPS) {\n            artifacts =\n                    new FilteredArtifactCollection(\n                            variantScope.getGlobalScope().getProject(),\n                            artifacts,\n                            computeArtifactCollection(variantScope,\n                                    AtlasAndroidArtifacts.ConsumedConfigType.RUNTIME_CLASSPATH,\n                                    scope,\n                                    AtlasAndroidArtifacts.AtlasArtifactType.FEATURE_TRANSITIVE_DEPS)\n                                    .getArtifactFiles());\n        }\n        return artifacts;\n    }\n\n\n    @Nullable\n    private static Spec<ComponentIdentifier> getComponentFilter(\n            @NonNull AndroidArtifacts.ArtifactScope scope) {\n        switch (scope) {\n            case ALL:\n                return null;\n            case EXTERNAL:\n                // since we want both Module dependencies and file based dependencies in this case\n                // the best thing to do is search for non ProjectComponentIdentifier.\n                return id -> !(id instanceof ProjectComponentIdentifier);\n            case MODULE:\n                return id -> id instanceof ProjectComponentIdentifier;\n            default:\n                throw new RuntimeException(\"unknown ArtifactScope value\");\n        }\n    }\n\n    /**\n     * Returns a set of HashableResolvedArtifactResult where the {@link\n     * ArtifactDependencyGraph.HashableResolvedArtifactResult#getDependencyType()} and {@link\n     * ArtifactDependencyGraph.HashableResolvedArtifactResult#isWrappedModule()} fields have been setup properly.\n     */\n    public static Set<AtlasDependencyGraph.HashableResolvedArtifactResult> getAllArtifacts(\n            @NonNull VariantScope variantScope,\n            @NonNull AtlasAndroidArtifacts.ConsumedConfigType consumedConfigType,\n            @Nullable DependencyFailureHandler dependencyFailureHandler) {\n        // FIXME change the way we compare dependencies b/64387392\n\n        // we need to figure out the following:\n        // - Is it an external dependency or a sub-project?\n        // - Is it an android or a java dependency\n\n        // Querying for JAR type gives us all the dependencies we care about, and we can use this\n        // to differentiate external vs sub-projects (to a certain degree).\n        ArtifactCollection allArtifactList =\n                computeArtifactList(\n                        variantScope,\n                        consumedConfigType,\n                        AndroidArtifacts.ArtifactScope.ALL,\n                        AtlasAndroidArtifacts.AtlasArtifactType.JAR);\n\n        // Then we can query for MANIFEST that will give us only the Android project so that we\n        // can detect JAVA vs ANDROID.\n        ArtifactCollection manifestList =\n                computeArtifactList(\n                        variantScope,\n                        consumedConfigType,\n                        AndroidArtifacts.ArtifactScope.ALL,\n                        AtlasAndroidArtifacts.AtlasArtifactType.MANIFEST);\n\n        // We still need to understand wrapped jars and aars. The former is difficult (TBD), but\n        // the latter can be done by querying for EXPLODED_AAR. If a sub-project is in this list,\n        // then we need to override the type to be external, rather than sub-project.\n        // This is why we query for Scope.ALL\n        // But we also simply need the exploded AARs for external Android dependencies so that\n        // Studio can access the content.\n        ArtifactCollection explodedAarList =\n                computeArtifactList(\n                        variantScope,\n                        consumedConfigType,\n                        AndroidArtifacts.ArtifactScope.ALL,\n                        AtlasAndroidArtifacts.AtlasArtifactType.EXPLODED_AAR);\n\n        ArtifactCollection explodedAwbList =\n                computeArtifactList(\n                        variantScope,\n                        consumedConfigType,\n                        AndroidArtifacts.ArtifactScope.ALL,\n                        AtlasAndroidArtifacts.AtlasArtifactType.EXPLODED_AWB);\n\n        // We also need the actual AARs so that we can get the artifact location and find the source\n        // location from it.\n        ArtifactCollection aarList =\n                computeArtifactList(\n                        variantScope,\n                        consumedConfigType,\n                        AndroidArtifacts.ArtifactScope.EXTERNAL,\n                        AtlasAndroidArtifacts.AtlasArtifactType.AAR);\n\n        ArtifactCollection awbList =\n                computeArtifactList(\n                        variantScope,\n                        consumedConfigType,\n                        AndroidArtifacts.ArtifactScope.EXTERNAL,\n                        AtlasAndroidArtifacts.AtlasArtifactType.AWB);\n\n\n        // collect dependency resolution failures\n        if (dependencyFailureHandler != null) {\n            // compute the name of the configuration\n            dependencyFailureHandler.addErrors(\n                    variantScope.getGlobalScope().getProject().getPath()\n                            + \"@\"\n                            + variantScope.getFullVariantName()\n                            + \"/\"\n                            + consumedConfigType.getName(),\n                    allArtifactList.getFailures());\n        }\n\n        // build a list of wrapped AAR, and a map of all the exploded-aar artifacts\n        final Set<ComponentIdentifier> wrapperModules = new HashSet<>();\n        final Set<ResolvedArtifactResult> explodedAarArtifacts = explodedAarList.getArtifacts();\n        final Set<ResolvedArtifactResult>explodedAwbArtifacts = explodedAwbList.getArtifacts();\n        final Map<ComponentIdentifier, ResolvedArtifactResult> explodedAarResults =\n                Maps.newHashMapWithExpectedSize(explodedAarArtifacts.size());\n        final Map<ComponentIdentifier, ResolvedArtifactResult> explodedAwbResults =\n                Maps.newHashMapWithExpectedSize(explodedAwbArtifacts.size());\n        for (ResolvedArtifactResult result : explodedAarArtifacts) {\n            final ComponentIdentifier componentIdentifier = result.getId().getComponentIdentifier();\n            if (componentIdentifier instanceof ProjectComponentIdentifier) {\n                wrapperModules.add(componentIdentifier);\n            }\n            explodedAarResults.put(componentIdentifier, result);\n        }\n\n        for (ResolvedArtifactResult result : explodedAwbArtifacts) {\n            final ComponentIdentifier componentIdentifier = result.getId().getComponentIdentifier();\n            if (componentIdentifier instanceof ProjectComponentIdentifier) {\n                wrapperModules.add(componentIdentifier);\n            }\n            explodedAwbResults.put(componentIdentifier, result);\n        }\n\n        final Set<ResolvedArtifactResult> aarArtifacts = aarList.getArtifacts();\n        final Set<ResolvedArtifactResult>awbArtifacts = awbList.getArtifacts();\n        final Map<ComponentIdentifier, ResolvedArtifactResult> aarResults =\n                Maps.newHashMapWithExpectedSize(aarArtifacts.size());\n        final Map<ComponentIdentifier, ResolvedArtifactResult> awbResults =\n                Maps.newHashMapWithExpectedSize(awbArtifacts.size());\n        for (ResolvedArtifactResult result : aarArtifacts) {\n            aarResults.put(result.getId().getComponentIdentifier(), result);\n        }\n        for (ResolvedArtifactResult result : awbArtifacts) {\n            awbResults.put(result.getId().getComponentIdentifier(), result);\n        }\n\n\n        // build a list of android dependencies based on them publishing a MANIFEST element\n        final Set<ResolvedArtifactResult> manifestArtifacts = manifestList.getArtifacts();\n        final Set<ComponentIdentifier> manifestIds =\n                Sets.newHashSetWithExpectedSize(manifestArtifacts.size());\n        for (ResolvedArtifactResult result : manifestArtifacts) {\n            manifestIds.add(result.getId().getComponentIdentifier());\n        }\n\n        // build the final list, using the main list augmented with data from the previous lists.\n        final Set<ResolvedArtifactResult> allArtifacts = allArtifactList.getArtifacts();\n\n        // use a linked hash set to keep the artifact order.\n        final Set<AtlasDependencyGraph.HashableResolvedArtifactResult> artifacts =\n                Sets.newLinkedHashSetWithExpectedSize(allArtifacts.size());\n\n        for (ResolvedArtifactResult artifact : allArtifacts) {\n            final ComponentIdentifier componentIdentifier =\n                    artifact.getId().getComponentIdentifier();\n\n            // check if this is a wrapped module\n            boolean isWrappedModule = wrapperModules.contains(componentIdentifier);\n\n            // check if this is an android external module. In this case, we want to use the exploded\n            // aar as the artifact we depend on rather than just the JAR, so we swap out the\n            // ResolvedArtifactResult.\n            AtlasDependencyGraph.DependencyType dependencyType = DependencyType.JAVA;\n            // optional result that will point to the artifact (AAR) when the current result\n            // is the exploded AAR.\n            ResolvedArtifactResult aarResult = null;\n            if (manifestIds.contains(componentIdentifier)) {\n                dependencyType = DependencyType.ANDROID;\n                // if it's an android dependency, we swap out the manifest result for the exploded\n                // AAR result.\n                // If the exploded AAR is null then it's a sub-project and we can keep the manifest\n                // as the Library we'll create will be a ModuleLibrary which doesn't care about\n                // the artifact file anyway.\n\n                ResolvedArtifactResult explodedAwb = explodedAwbResults.get(componentIdentifier);\n                if (explodedAwb != null){\n                    artifact = explodedAwb;\n                    dependencyType = DependencyType.AWB;\n                    aarResult = awbResults.get(componentIdentifier);\n\n                }else {\n                    ResolvedArtifactResult explodedAar = explodedAarResults.get(componentIdentifier);\n                    if (explodedAar != null) {\n                        artifact = explodedAar;\n                        aarResult = aarResults.get(componentIdentifier);\n                    }\n                }\n\n                // and we need the AAR itself (if it exists)\n            }\n\n            artifacts.add(\n                    new AtlasDependencyGraph.HashableResolvedArtifactResult(\n                            artifact, dependencyType, isWrappedModule, aarResult));\n        }\n\n        return artifacts;\n    }\n\n    @NonNull\n    private static ArtifactCollection computeArtifactList(\n            @NonNull VariantScope variantScope,\n            @NonNull AtlasAndroidArtifacts.ConsumedConfigType consumedConfigType,\n            @NonNull AndroidArtifacts.ArtifactScope scope,\n            @NonNull AtlasAndroidArtifacts.AtlasArtifactType type) {\n        ArtifactCollection artifacts =\n                computeArtifactCollection(variantScope,consumedConfigType, scope, type);\n\n        // because the ArtifactCollection could be a collection over a test variant which ends\n        // up being a ArtifactCollectionWithExtraArtifact, we need to get the actual list\n        // without the tested artifact.\n        if (artifacts instanceof ArtifactCollectionWithExtraArtifact) {\n            return ((ArtifactCollectionWithExtraArtifact) artifacts).getParentArtifacts();\n        }\n\n        return artifacts;\n    }\n\n    /**\n     * Create a level 4 dependency graph.\n     *\n     * @see AndroidProject#MODEL_LEVEL_4_NEW_DEP_MODEL\n     */\n    public DependencyGraphs createLevel4DependencyGraph(\n            @NonNull VariantScope variantScope,\n            boolean withFullDependency,\n            boolean downloadSources,\n            @NonNull Consumer<SyncIssue> failureConsumer) {\n        // FIXME change the way we compare dependencies b/64387392\n\n        try {\n            // get the compile artifact first.\n            Set<AtlasDependencyGraph.HashableResolvedArtifactResult> compileArtifacts =\n                    getAllArtifacts(variantScope, AtlasAndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH, dependencyFailureHandler);\n\n           compileArtifacts.addAll(getAllArtifacts(variantScope,AtlasAndroidArtifacts.ConsumedConfigType.BUNDLECOMPILE_CLASSPATH,dependencyFailureHandler));\n            // force download the javadoc/source artifacts of compile scope only, since the\n            // the runtime-only is never used from the IDE.\n            if (downloadSources) {\n                Set<ComponentIdentifier> ids =\n                        Sets.newHashSetWithExpectedSize(compileArtifacts.size());\n                for (HashableResolvedArtifactResult artifact : compileArtifacts) {\n                    ids.add(artifact.getId().getComponentIdentifier());\n                }\n\n                handleSources(variantScope.getGlobalScope().getProject(), ids, failureConsumer);\n            }\n\n            // In this simpler model, faster computation of the runtime dependencies to get the\n            // provided bit.\n            if (!withFullDependency) {\n                // get the runtime artifacts. We only care about the ComponentIdentifier so we don't\n                // need to call getAllArtifacts() which computes a lot more many things, and takes\n                // longer on large projects.\n                // Instead just get all the jars to get all the dependencies.\n                ArtifactCollection runtimeArtifactCollection =\n                        computeArtifactList(\n                                variantScope,\n                                AtlasAndroidArtifacts.ConsumedConfigType.RUNTIME_CLASSPATH,\n                                AndroidArtifacts.ArtifactScope.ALL,\n                                AtlasAndroidArtifacts.AtlasArtifactType.JAR);\n\n                // build a list of the runtime ComponentIdentifiers\n                final Set<ResolvedArtifactResult> runtimeArtifacts =\n                        runtimeArtifactCollection.getArtifacts();\n                final Set<ComponentIdentifier> runtimeIdentifiers =\n                        Sets.newHashSetWithExpectedSize(runtimeArtifacts.size());\n                for (ResolvedArtifactResult result : runtimeArtifacts) {\n                    runtimeIdentifiers.add(result.getId().getComponentIdentifier());\n                }\n\n                List<String> providedAddresses = Lists.newArrayList();\n\n                List<GraphItem> compileItems =\n                        Lists.newArrayListWithCapacity(compileArtifacts.size());\n                for (AtlasDependencyGraph.HashableResolvedArtifactResult artifact : compileArtifacts) {\n                    final GraphItemImpl graphItem =\n                            new GraphItemImpl(computeAddress(artifact), ImmutableList.of());\n                    compileItems.add(graphItem);\n                    sLibraryCache.get(artifact);\n                    sLibraryMap.put(computeAddress(artifact),artifact);\n                    if (!runtimeIdentifiers.contains(artifact.getId().getComponentIdentifier())) {\n                        providedAddresses.add(graphItem.getArtifactAddress());\n                    }\n                }\n\n                return new SimpleDependencyGraphsImpl(compileItems, providedAddresses);\n            }\n\n            // now build the list of compile items\n            List<GraphItem> compileItems = Lists.newArrayListWithCapacity(compileArtifacts.size());\n            for (AtlasDependencyGraph.HashableResolvedArtifactResult artifact : compileArtifacts) {\n                compileItems.add(new GraphItemImpl(computeAddress(artifact), ImmutableList.of()));\n                sLibraryCache.get(artifact);\n                sLibraryMap.put(computeAddress(artifact),artifact);\n\n            }\n\n            // in this mode, compute GraphItem for the runtime configuration\n            // get the runtime artifacts.\n            Set<AtlasDependencyGraph.HashableResolvedArtifactResult> runtimeArtifacts =\n                    getAllArtifacts(variantScope, AtlasAndroidArtifacts.ConsumedConfigType.RUNTIME_CLASSPATH, dependencyFailureHandler);\n\n           runtimeArtifacts.addAll(getAllArtifacts(variantScope, AtlasAndroidArtifacts.ConsumedConfigType.BUNDLECOMPILE_CLASSPATH, dependencyFailureHandler));\n\n            List<GraphItem> runtimeItems = Lists.newArrayListWithCapacity(runtimeArtifacts.size());\n            for (AtlasDependencyGraph.HashableResolvedArtifactResult artifact : runtimeArtifacts) {\n                runtimeItems.add(new GraphItemImpl(computeAddress(artifact), ImmutableList.of()));\n                sLibraryCache.get(artifact);\n                sLibraryMap.put(computeAddress(artifact),artifact);\n            }\n\n            // compute the provided dependency list, by comparing the compile and runtime items\n            List<GraphItem> providedItems = Lists.newArrayList(compileItems);\n            providedItems.removeAll(runtimeItems);\n            final ImmutableList<String> providedAddresses =\n                    providedItems\n                            .stream()\n                            .map(GraphItem::getArtifactAddress)\n                            .collect(ImmutableCollectors.toImmutableList());\n\n            // FIXME: when full dependency is enabled, this should return a full graph instead of a\n            // flat list.\n\n            return new FullDependencyGraphsImpl(\n                    compileItems,\n                    runtimeItems,\n                    providedAddresses,\n                    ImmutableList.of()); // FIXME: actually get skip list\n        } finally {\n            dependencyFailureHandler.collectIssues().forEach(failureConsumer);\n        }\n    }\n\n    /** Create a level 1 dependency list. */\n    @NonNull\n    public DependenciesImpl createDependencies(\n            @NonNull VariantScope variantScope,\n            boolean downloadSources,\n            @NonNull Consumer<SyncIssue> failureConsumer) {\n        // FIXME change the way we compare dependencies b/64387392\n\n        try {\n            ImmutableList.Builder<String> projects = ImmutableList.builder();\n            ImmutableList.Builder<AndroidLibrary> androidLibraries = ImmutableList.builder();\n            ImmutableList.Builder<JavaLibrary> javaLibrary = ImmutableList.builder();\n\n            // get the runtime artifact. We only care about the ComponentIdentifier so we don't\n            // need to call getAllArtifacts() which computes a lot more many things.\n            // Instead just get all the jars to get all the dependencies.\n            ArtifactCollection runtimeArtifactCollection =\n                    computeArtifactList(\n                            variantScope,\n                            AtlasAndroidArtifacts.ConsumedConfigType.RUNTIME_CLASSPATH,\n                            AndroidArtifacts.ArtifactScope.ALL,\n                            AtlasAndroidArtifacts.AtlasArtifactType.JAR);\n\n            // build a list of the artifacts\n            Set<ComponentIdentifier> runtimeIdentifiers =\n                    new HashSet<>(runtimeArtifactCollection.getArtifacts().size());\n            for (ResolvedArtifactResult result : runtimeArtifactCollection.getArtifacts()) {\n                runtimeIdentifiers.add(result.getId().getComponentIdentifier());\n            }\n\n            Set<AtlasDependencyGraph.HashableResolvedArtifactResult> artifacts =\n                    getAllArtifacts(variantScope, AtlasAndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH, dependencyFailureHandler);\n\n            for (AtlasDependencyGraph.HashableResolvedArtifactResult artifact : artifacts) {\n                ComponentIdentifier id = artifact.getId().getComponentIdentifier();\n\n                boolean isProvided = !runtimeIdentifiers.contains(id);\n\n                boolean isSubproject = id instanceof ProjectComponentIdentifier;\n                String projectPath =\n                        isSubproject ? ((ProjectComponentIdentifier) id).getProjectPath() : null;\n\n                if (artifact.getDependencyType() == DependencyType.JAVA) {\n                    if (projectPath != null) {\n                        projects.add(projectPath);\n                        continue;\n                    }\n                    // FIXME: Dependencies information is not set correctly.\n                    javaLibrary.add(\n                            new com.android.build.gradle.internal.ide.JavaLibraryImpl(\n                                    artifact.getFile(),\n                                    null,\n                                    ImmutableList.of(), /* dependencies */\n                                    null, /* requestedCoordinates */\n                                    Preconditions.checkNotNull(sMavenCoordinatesCache.get(artifact)),\n                                    false, /* isSkipped */\n                                    isProvided));\n                } else {\n                    if (artifact.isWrappedModule()) {\n                        // force external dependency mode.\n                        projectPath = null;\n                    }\n\n                    final File explodedFolder = artifact.getFile();\n\n                    //noinspection VariableNotUsedInsideIf\n                    androidLibraries.add(\n                            new com.android.build.gradle.internal.ide.AndroidLibraryImpl(\n                                    // FIXME: Dependencies information is not set correctly.\n                                    Preconditions.checkNotNull(sMavenCoordinatesCache.get(artifact)),\n                                    projectPath,\n                                    artifact.bundleResult != null\n                                            ? artifact.bundleResult.getFile()\n                                            : explodedFolder,\n                                    // fallback so that the value is non-null\n                                    explodedFolder, /*exploded folder*/\n                                    getVariant(artifact),\n                                    isProvided,\n                                    false, /* dependencyItem.isSkipped() */\n                                    ImmutableList.of(), /* androidLibraries */\n                                    ImmutableList.of(), /* javaLibraries */\n                                    findLocalJarsAsFiles(explodedFolder)));\n                }\n            }\n\n            // force download the source artifacts of the compile classpath only.\n            if (downloadSources) {\n                Set<ComponentIdentifier> ids = Sets.newHashSetWithExpectedSize(artifacts.size());\n                for (AtlasDependencyGraph.HashableResolvedArtifactResult artifact : artifacts) {\n                    ids.add(artifact.getId().getComponentIdentifier());\n                }\n\n                handleSources(variantScope.getGlobalScope().getProject(), ids, failureConsumer);\n            }\n\n            return new DependenciesImpl(\n                    androidLibraries.build(), javaLibrary.build(), projects.build());\n        } finally {\n            dependencyFailureHandler.collectIssues().forEach(failureConsumer);\n        }\n    }\n\n    @NonNull\n    public static Dependencies clone(@NonNull Dependencies dependencies, int modelLevel) {\n        if (modelLevel >= AndroidProject.MODEL_LEVEL_4_NEW_DEP_MODEL) {\n            return EMPTY_DEPENDENCIES_IMPL;\n        }\n\n        // these items are already ready for serializable, all we need to clone is\n        // the Dependencies instance.\n        List<AndroidLibrary> libraries = Collections.emptyList();\n        List<JavaLibrary> javaLibraries = Lists.newArrayList(dependencies.getJavaLibraries());\n        List<String> projects = Collections.emptyList();\n\n        return new DependenciesImpl(libraries, javaLibraries, projects);\n    }\n\n    public static DependencyGraphs clone(\n            @NonNull DependencyGraphs dependencyGraphs,\n            int modelLevel,\n            boolean modelWithFullDependency) {\n        if (modelLevel < AndroidProject.MODEL_LEVEL_4_NEW_DEP_MODEL) {\n            return EMPTY_DEPENDENCY_GRAPH;\n        }\n\n        Preconditions.checkState(dependencyGraphs instanceof ConfigurationDependencyGraphs);\n        ConfigurationDependencyGraphs cdg = (ConfigurationDependencyGraphs) dependencyGraphs;\n\n        // these items are already ready for serializable, all we need to clone is\n        // the DependencyGraphs instance.\n\n        List<Library> libs = cdg.getLibraries();\n        synchronized (sGlobalLibrary) {\n            for (Library library : libs) {\n                sGlobalLibrary.put(library.getArtifactAddress(), library);\n            }\n        }\n\n        final List<GraphItem> nodes = cdg.getCompileDependencies();\n\n        if (modelWithFullDependency) {\n            return new FullDependencyGraphsImpl(\n                    nodes, nodes, ImmutableList.of(), ImmutableList.of());\n        }\n\n        // just need to register the libraries in the global libraries.\n        return new SimpleDependencyGraphsImpl(nodes, cdg.getProvidedLibraries());\n    }\n\n    private static void handleSources(\n            @NonNull Project project,\n            @NonNull Set<ComponentIdentifier> artifacts,\n            @NonNull Consumer<SyncIssue> failureConsumer) {\n        final DependencyHandler dependencies = project.getDependencies();\n\n        try {\n            ArtifactResolutionQuery query = dependencies.createArtifactResolutionQuery();\n            query.forComponents(artifacts);\n\n            @SuppressWarnings(\"unchecked\")\n            Class<? extends Artifact>[] artifactTypesArray =\n                    (Class<? extends Artifact>[]) new Class<?>[] {SourcesArtifact.class};\n            query.withArtifacts(JvmLibrary.class, artifactTypesArray);\n            query.execute().getResolvedComponents();\n        } catch (Throwable t) {\n            DependencyFailureHandlerKt.processDependencyThrowable(\n                    t,\n                    s -> null,\n                    (data, messages) ->\n                            failureConsumer.accept(\n                                    new SyncIssueImpl(\n                                            SyncIssue.TYPE_GENERIC,\n                                            SyncIssue.SEVERITY_WARNING,\n                                            null,\n                                            String.format(\n                                                    \"Unable to download sources: %s\",\n                                                    messages.get(0)),\n                                            messages)));\n        }\n    }\n\n    public enum DependencyType {\n        JAVA(EXT_JAR),\n        ANDROID(EXT_AAR),\n        AWB(\"awb\"),\n        AP(\"ap\");\n\n        @NonNull private final String extension;\n\n        DependencyType(@NonNull String extension) {\n            this.extension = extension;\n        }\n\n        @NonNull\n        public String getExtension() {\n            return extension;\n        }\n    }\n\n    @NonNull\n    private static List<String> findLocalJarsAsStrings(@NonNull File folder) {\n        File localJarRoot = FileUtils.join(folder, FD_JARS, FD_AAR_LIBS);\n\n        if (!localJarRoot.isDirectory()) {\n            return ImmutableList.of();\n        }\n\n        String[] jarFiles = localJarRoot.list((dir, name) -> name.endsWith(DOT_JAR));\n        if (jarFiles != null && jarFiles.length > 0) {\n            List<String> list = Lists.newArrayListWithCapacity(jarFiles.length);\n            for (String jarFile : jarFiles) {\n                list.add(FD_JARS + File.separatorChar + FD_AAR_LIBS + File.separatorChar + jarFile);\n            }\n\n            return list;\n        }\n\n        return ImmutableList.of();\n    }\n\n    @NonNull\n    private static List<File> findLocalJarsAsFiles(@NonNull File folder) {\n        File localJarRoot = FileUtils.join(folder, FD_JARS, FD_AAR_LIBS);\n\n        if (!localJarRoot.isDirectory()) {\n            return ImmutableList.of();\n        }\n\n        File[] jarFiles = localJarRoot.listFiles((dir, name) -> name.endsWith(DOT_JAR));\n        if (jarFiles != null && jarFiles.length > 0) {\n            return ImmutableList.copyOf(jarFiles);\n        }\n\n        return ImmutableList.of();\n    }\n\n    public static class HashableResolvedArtifactResult implements ResolvedArtifactResult {\n        public ResolvedArtifactResult getDelegate() {\n            return delegate;\n        }\n\n        @NonNull private final ResolvedArtifactResult delegate;\n        @NonNull private final AtlasDependencyGraph.DependencyType dependencyType;\n        private final boolean wrappedModule;\n\n        public ResolvedArtifactResult getBundleResult() {\n            return bundleResult;\n        }\n\n        /**\n         * An optional sub-result that represents the bundle file, when the current result\n         * represents an exploded aar\n         */\n        private final ResolvedArtifactResult bundleResult;\n\n        public HashableResolvedArtifactResult(\n                @NonNull ResolvedArtifactResult delegate,\n                @NonNull AtlasDependencyGraph.DependencyType dependencyType,\n                boolean wrappedModule,\n                @Nullable ResolvedArtifactResult bundleResult) {\n            this.delegate = delegate;\n            this.dependencyType = dependencyType;\n            this.wrappedModule = wrappedModule;\n            this.bundleResult = bundleResult;\n        }\n\n        @Override\n        public File getFile() {\n            return delegate.getFile();\n        }\n\n        @Override\n        public ResolvedVariantResult getVariant() {\n            return delegate.getVariant();\n        }\n\n        @Override\n        public ComponentArtifactIdentifier getId() {\n            return delegate.getId();\n        }\n\n        @Override\n        public Class<? extends Artifact> getType() {\n            return delegate.getType();\n        }\n\n        @NonNull\n        public AtlasDependencyGraph.DependencyType getDependencyType() {\n            return dependencyType;\n        }\n\n        public boolean isWrappedModule() {\n            return wrappedModule;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) {\n                return true;\n            }\n            if (o == null || getClass() != o.getClass()) {\n                return false;\n            }\n            AtlasDependencyGraph.HashableResolvedArtifactResult that = (AtlasDependencyGraph.HashableResolvedArtifactResult) o;\n            return wrappedModule == that.wrappedModule\n                    && dependencyType == that.dependencyType\n                    && com.google.common.base.Objects.equal(getFile(), that.getFile())\n                    && com.google.common.base.Objects.equal(getId(), that.getId())\n                    && com.google.common.base.Objects.equal(getType(), that.getType());\n        }\n\n        @Override\n        public int hashCode() {\n            return java.util.Objects.hash(delegate, dependencyType, wrappedModule);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/ide/DependencyConvertUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.build.gradle.internal.ide;\n\nimport com.android.builder.dependency.MavenCoordinatesImpl;\nimport com.android.builder.dependency.level2.AndroidDependency;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.builder.model.JavaLibrary;\nimport com.android.builder.model.MavenCoordinates;\nimport com.google.common.collect.ImmutableList;\nimport com.taobao.android.builder.dependency.model.ApLibrary;\nimport com.taobao.android.builder.dependency.model.ApkLibrary;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.dependency.parser.ResolvedDependencyInfo;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.ModuleVersionIdentifier;\nimport org.gradle.api.artifacts.ResolvedArtifact;\nimport org.gradle.api.artifacts.result.DependencyResult;\nimport org.gradle.api.artifacts.result.ResolvedDependencyResult;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * Tool classes that depend on object transformation\n * Created by shenghua.nish on 2016-05-06 10:44 in the morning.\n */\npublic class DependencyConvertUtils {\n\n    /**\n     * Convert to jar dependency\n     *\n     * @param resolvedDependencyInfo\n     * @return\n     */\n    public static JavaLibrary toJavaLib(ResolvedDependencyInfo resolvedDependencyInfo) {\n\n        ResolvedArtifact artifact = resolvedDependencyInfo.getResolvedArtifact();\n\n        JavaLibrary jarInfo = new JavaLibraryImpl(artifact.getFile(),\n                                                  null,\n                                                  ImmutableList.<JavaLibrary>of(),\n                                                  null,\n                                                  convert(artifact,Type.JAR),\n                                                  false,\n                                                  false);\n        return jarInfo;\n    }\n\n    /**\n     * Simple transformations, no dependencies\n     *\n     * @param resolvedDependencyInfo\n     * @return\n     */\n    public static AndroidLibrary toAndroidLibrary(ResolvedDependencyInfo resolvedDependencyInfo, Project project,\n                                                  boolean bundle) {\n\n        ResolvedArtifact artifact = resolvedDependencyInfo.getResolvedArtifact();\n\n        AndroidDependency androidDependency = AndroidDependency.createExplodedAarLibrary(artifact.getFile(),\n                                                                                         convert(artifact,bundle?Type.AWB:Type.AAR),\n                                                                                         resolvedDependencyInfo\n                                                                                             .getDependencyName(),\n                                                                                         null,\n                                                                                         resolvedDependencyInfo\n                                                                                             .getExplodedDir());\n\n        List<File> localJars = new ArrayList<>();\n\n        return new AtlasAndroidLibraryImpl(androidDependency,\n                                      false,\n                                      false,\n                                      ImmutableList.<AndroidLibrary>of(),\n                                      ImmutableList.<JavaLibrary>of(),\n                                      localJars);\n    }\n\n    //public static List<File> getLocalJars(Project project, boolean bundle, AndroidDependency androidDependency) {\n    //\n    //    if (!bundle) {\n    //        return androidDependency.getLocalJars();\n    //    }\n    //\n    //    boolean localJarEnabled = AtlasBuildContext.sBuilderAdapter.localJarEnabled;\n    //    if (project.hasProperty(\"localJarEnabled\")) {\n    //        localJarEnabled = \"true\".equals(project.property(\"localJarEnabled\"));\n    //    }\n    //\n    //    return localJarEnabled ? androidDependency.getLocalJars() : new ArrayList<>(0);\n    //}\n\n    public static AndroidLibrary toAndroidLibrary(MavenCoordinates mavenCoordinates, File artifact, File dir) {\n\n        AndroidDependency androidDependency = AndroidDependency.createExplodedAarLibrary(artifact,\n                                                                                         mavenCoordinates,\n                                                                                         mavenCoordinates.toString(),\n                                                                                         null,\n                                                                                         dir);\n\n        return new AtlasAndroidLibraryImpl(androidDependency,\n                                      false,\n                                      false,\n                                      ImmutableList.<AndroidLibrary>of(),\n                                      ImmutableList.<JavaLibrary>of(),\n                                      androidDependency.getLocalJars());\n    }\n\n    public static AwbBundle toBundle(ResolvedDependencyInfo resolvedDependencyInfo, Project project) {\n\n        AndroidLibrary androidLibrary = toAndroidLibrary(resolvedDependencyInfo, project, true);\n\n        return new AwbBundle(resolvedDependencyInfo, androidLibrary);\n    }\n\n    public static ApLibrary toApLibrary(ResolvedDependencyInfo resolvedDependencyInfo) {\n        assertType(Type.AP, resolvedDependencyInfo);\n        ResolvedArtifact artifact = resolvedDependencyInfo.getResolvedArtifact();\n        ApLibrary apLibrary = new ApLibrary(convert(artifact,Type.AP),\n                                            artifact.getFile(),\n                                            resolvedDependencyInfo.getExplodedDir());\n        return apLibrary;\n    }\n\n    public static ApkLibrary toApkLibrary(ResolvedDependencyInfo resolvedDependencyInfo) {\n        assertType(Type.APK, resolvedDependencyInfo);\n        ResolvedArtifact artifact = resolvedDependencyInfo.getResolvedArtifact();\n        ApkLibrary apkLibrary = new ApkLibrary(convert(artifact,Type.APK), artifact.getFile());\n        return apkLibrary;\n    }\n\n    private static void assertType(Type expectedType,\n                                   ResolvedDependencyInfo resolvedDependencyInfo) {\n        assert expectedType.equals(Type.getType(resolvedDependencyInfo.getType()));\n    }\n\n    public enum Type {\n        AWB(\"awb\"),\n        AAR(\"aar\"),\n        JAR(\"jar\"),\n        SOLIB(\"solib\"),\n        AP(\"ap\"),\n        APK(\"apk\"),\n        OTHER(\"\");\n\n        public String getType() {\n            return type;\n        }\n\n        private String type;\n\n        Type(String type) {\n            this.type = type.toLowerCase();\n        }\n\n        public static Type getType(String typeName) {\n            for (Type type : Type.values()) {\n                if (StringUtils.equalsIgnoreCase(typeName, type.type)) {\n                    return type;\n                }\n            }\n            return Type.OTHER;\n        }\n    }\n\n    public static MavenCoordinatesImpl convert(ResolvedArtifact artifact,Type type) {\n        return new MavenCoordinatesImpl(artifact.getModuleVersion().getId().getGroup(),\n                                        artifact.getModuleVersion().getId().getName(),\n                                        artifact.getModuleVersion().getId().getVersion(),type.getType(),\n                                        artifact.getClassifier());\n    }\n\n    public static boolean isAwbDependency(DependencyResult dependencyResult,\n                                          Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts, Set<String>awbs) {\n        if (dependencyResult instanceof ResolvedDependencyResult) {\n            ResolvedDependencyResult resolvedDependencyResult = (ResolvedDependencyResult)dependencyResult;\n            ModuleVersionIdentifier moduleVersionIdentifier = resolvedDependencyResult.getSelected().getModuleVersion();\n            List<ResolvedArtifact> resolvedArtifacts = artifacts.get(moduleVersionIdentifier);\n\n            if (resolvedArtifacts != null && resolvedArtifacts.size() > 0) {\n                ResolvedArtifact resolvedArtifact = resolvedArtifacts.get(0);\n                return (\"awb\".equals(resolvedArtifact.getType()) || awbs.contains(resolvedArtifact.getModuleVersion().getId().getGroup()+\":\"+resolvedArtifact.getModuleVersion().getId().getName()));\n            }\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/incremental/TBConstructorRedirection.java",
    "content": "package com.android.build.gradle.internal.incremental;\n\nimport com.android.annotations.NonNull;\nimport org.objectweb.asm.Opcodes;\nimport org.objectweb.asm.Type;\nimport org.objectweb.asm.commons.GeneratorAdapter;\nimport org.objectweb.asm.commons.Method;\nimport org.objectweb.asm.tree.LabelNode;\n\nimport java.util.List;\n\n/**\n * 创建日期：2019/1/24 on 下午5:02\n * 描述:\n * 作者:zhayu.ll\n */\npublic class TBConstructorRedirection extends Redirection {\n\n    // The signature of the dynamically dispatching 'this' constructor. The final parameters is\n    // to disambiguate from other constructors that might preexist on the class.\n    static final String DISPATCHING_THIS_SIGNATURE =\n            \"([Ljava/lang/Object;\"\n                    + TBIncrementalVisitor.ALI_INSTANT_RELOAD_EXCEPTION.getDescriptor() + \")V\";\n\n    private final Constructor constructor;\n\n    /**\n     * @param constructor the constructor to redirect.\n     * @param types the types of the arguments on the super()/this() call.\n     */\n    TBConstructorRedirection(LabelNode label,\n                           Constructor constructor,\n                           @NonNull List<Type> types) {\n        super(label, types, Type.VOID_TYPE);\n        this.constructor = constructor;\n    }\n\n    @Override\n    protected void doRedirect(GeneratorAdapter mv, int change) {\n        mv.loadLocal(change);\n        mv.push(\"init$args.\" + constructor.args.desc);\n\n        Type arrayType = Type.getType(\"[Ljava/lang/Object;\");\n        // init$args args (including this) + locals\n        mv.push(types.size() + 1);\n        mv.newArray(Type.getType(Object.class));\n\n        int array = mv.newLocal(arrayType);\n        mv.dup();\n        mv.storeLocal(array);\n\n        // \"this\" is not ready yet, use null instead.\n        mv.dup();\n        mv.push(0);\n        mv.visitInsn(Opcodes.ACONST_NULL);\n        mv.arrayStore(Type.getType(Object.class));\n\n        // Set the arguments in positions 1..(n-1);\n        ByteCodeUtils.loadVariableArray(mv, ByteCodeUtils.toLocalVariables(types), 1); // Skip the this value\n\n        // Add the locals array at the last position.\n        mv.dup();\n        // The index of the last position of the array.\n        mv.push(types.size());\n        // Create the array with all the local variables declared up to this point.\n        ByteCodeUtils.newVariableArray(mv, constructor.variables.subList(0, constructor.localsAtLoadThis));\n        mv.arrayStore(Type.getType(Object.class));\n\n        mv.invokeInterface(TBIncrementalVisitor.ALI_CHANGE_TYPE, Method.getMethod(\"Object ipc$dispatch(String, Object[])\"));\n        mv.visitTypeInsn(Opcodes.CHECKCAST, \"[Ljava/lang/Object;\");\n        //// At this point, init$args has been called and the result Object is on the stack.\n        //// The value of that Object is Object[] with exactly n + 2 elements.\n        //// The first element is the resulting local variables\n        //// The second element is a string with the qualified name of the constructor to call.\n        //// The remaining elements are the constructor arguments.\n\n        // Keep a reference to the new locals array\n        mv.dup();\n        mv.push(0);\n        mv.arrayLoad(Type.getType(\"[Ljava/lang/Object;\"));\n        mv.visitTypeInsn(Opcodes.CHECKCAST, \"[Ljava/lang/Object;\");\n        mv.storeLocal(array);\n\n        // Call super constructor\n        // Put this behind the returned array\n        mv.visitVarInsn(Opcodes.ALOAD, 0);\n        mv.swap();\n        // Push a null for the marker parameter.\n        mv.visitInsn(Opcodes.ACONST_NULL);\n        // Invoke the constructor\n        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, constructor.owner, \"<init>\", DISPATCHING_THIS_SIGNATURE, false);\n\n        // Dispatch to init$body\n        mv.loadLocal(change);\n        mv.push(\"init$body.\" + constructor.body.desc);\n        mv.loadLocal(array);\n\n        // Now \"this\" can be set\n        mv.dup();\n        mv.push(0);\n        mv.visitVarInsn(Opcodes.ALOAD, 0);\n        mv.arrayStore(Type.getType(Object.class));\n\n        mv.invokeInterface(TBIncrementalVisitor.ALI_CHANGE_TYPE, Method.getMethod(\"Object ipc$dispatch(String, Object[])\"));\n        mv.pop();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/incremental/TBIncrementalChangeVisitor.java",
    "content": "package com.android.build.gradle.internal.incremental;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.VisibleForTesting;\nimport com.android.utils.ILogger;\nimport org.objectweb.asm.*;\nimport org.objectweb.asm.commons.GeneratorAdapter;\nimport org.objectweb.asm.commons.JSRInlinerAdapter;\nimport org.objectweb.asm.commons.Method;\nimport org.objectweb.asm.tree.ClassNode;\nimport org.objectweb.asm.tree.FieldNode;\nimport org.objectweb.asm.tree.MethodNode;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * 创建日期：2019/1/5 on 上午10:54\n * 描述:\n * 作者:zhayu.ll\n */\npublic class TBIncrementalChangeVisitor extends TBIncrementalVisitor {\n\n    public static final VisitorBuilder VISITOR_BUILDER = new IncrementalVisitor.VisitorBuilder() {\n        @NonNull\n        @Override\n        public IncrementalVisitor build(@NonNull ClassNode classNode,\n                                        @NonNull List<ClassNode> parentNodes,\n                                        @NonNull ClassVisitor classVisitor,\n                                        @NonNull ILogger logger) {\n            return new TBIncrementalChangeVisitor(classNode, parentNodes, classVisitor, logger);\n        }\n\n        @NonNull\n        @Override\n        public String getMangledRelativeClassFilePath(@NonNull String path) {\n            // Remove .class (length 6) and replace with $override.class\n            return path.substring(0, path.length() - 6) + OVERRIDE_SUFFIX + \".class\";\n        }\n\n        @NonNull\n        @Override\n        public OutputType getOutputType() {\n            return OutputType.OVERRIDE;\n        }\n    };\n\n    // todo : find a better way to specify logging and append to a log file.\n    private static final boolean DEBUG = false;\n\n    @VisibleForTesting\n    public static final String OVERRIDE_SUFFIX = \"$ipReplace\";\n\n    private static final String METHOD_MANGLE_PREFIX = \"static$\";\n\n    private TBIncrementalChangeVisitor.MachineState state = TBIncrementalChangeVisitor.MachineState.NORMAL;\n    private boolean instantRunDisabled = false;\n\n    // Description prefix used to add fake \"this\" as the first argument to each instance method\n    // when converted to a static method.\n    private String instanceToStaticDescPrefix;\n\n    // List of constructors we encountered and deconstructed.\n    List<MethodNode> addedMethods = new ArrayList<>();\n\n    private enum MachineState {\n        NORMAL, AFTER_NEW\n    }\n\n    public TBIncrementalChangeVisitor(\n            @NonNull ClassNode classNode,\n            @NonNull List<ClassNode> parentNodes,\n            @NonNull ClassVisitor classVisitor,\n            @NonNull ILogger logger) {\n        super(classNode, parentNodes, classVisitor, logger);\n    }\n\n    /**\n     * Turns this class into an override class that can be loaded by our custom class loader:\n     *<ul>\n     *   <li>Make the class name be OriginalName$override</li>\n     *   <li>Ensure the class derives from java.lang.Object, no other inheritance</li>\n     *   <li>Ensure the class has a public parameterless constructor that is a noop.</li>\n     *</ul>\n     */\n    @Override\n    public void visit(int version, int access, String name, String signature, String superName,\n                      String[] interfaces) {\n        super.visit(version, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER,\n                name + OVERRIDE_SUFFIX, signature, \"java/lang/Object\",\n                new String[]{TBIncrementalSupportVisitor.ALI_CHANGE_TYPE.getInternalName()});\n\n        if (DEBUG) {\n            System.out.println(\">>>>>>>> Processing \" + name + \"<<<<<<<<<<<<<\");\n        }\n\n        visitedClassName = name;\n        visitedSuperName = superName;\n        instanceToStaticDescPrefix = \"(L\" + visitedClassName + \";\";\n\n        // Create empty constructor\n        MethodVisitor mv = super\n                .visitMethod(Opcodes.ACC_PUBLIC, \"<init>\", \"()V\", null, null);\n        mv.visitCode();\n        mv.visitVarInsn(Opcodes.ALOAD, 0);\n        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, \"java/lang/Object\", \"<init>\", \"()V\",\n                false);\n        mv.visitInsn(Opcodes.RETURN);\n        mv.visitMaxs(0, 0);\n        mv.visitEnd();\n\n        super.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_STATIC,\n                \"$ipObsolete\", \"Z\", null, null);\n    }\n\n    @Override\n    public void visitOuterClass(String owner, String name, String desc) {\n        // Ignore, the class hierarchy is not relevant in the override classes.\n    }\n\n    @Override\n    public void visitInnerClass(String name, String outerName, String innerName, int access) {\n        // Ignore, the class hierarchy is not relevant in the override classes.\n    }\n\n    @Override\n    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {\n        if (TBIncrementalSupportVisitor.ALI_DISABLE_ANNOTATION_TYPE.getDescriptor().equals(desc)) {\n            instantRunDisabled = true;\n        }\n        return super.visitAnnotation(desc, visible);\n    }\n\n    /**\n     * Generates new delegates for all 'patchable' methods in the visited class. Delegates\n     * are static methods that do the same thing the visited code does, but from outside the class.\n     * For instance methods, the instance is passed as the first argument. Note that:\n     * <ul>\n     *   <li>We ignore the class constructor as we don't support it right now</li>\n     *   <li>We skip abstract methods.</li>\n     *   <li>For constructors split the method body into super arguments and the rest of\n     *   the method body, see {@link ConstructorBuilder}</li>\n     * </ul>\n     */\n    @Override\n    public MethodVisitor visitMethod(int access, String name, String desc, String signature,\n                                     String[] exceptions) {\n\n        if (instantRunDisabled || !isAccessCompatibleWithInstantRun(access)) {\n            // Nothing to generate.\n            return null;\n        }\n        if (name.equals(ByteCodeUtils.CLASS_INITIALIZER)) {\n            // we skip the class init as it can reset static fields which we don't support right now\n            return null;\n        }\n\n        boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;\n        String newDesc = computeOverrideMethodDesc(desc, isStatic);\n\n        if (DEBUG) {\n            System.out.println(\">>> Visiting method \" + visitedClassName + \":\" + name + \":\" + desc);\n            if (exceptions != null) {\n                for (String exception : exceptions) {\n                    System.out.println(\"> Exception thrown : \" + exception);\n                }\n            }\n        }\n        if (DEBUG) {\n            System.out.println(\"New Desc is \" + newDesc + \":\" + isStatic);\n        }\n\n        // Do not carry on any access flags from the original method. For example synchronized\n        // on the original method would translate into a static synchronized method here.\n        access = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC;\n        MethodNode method = getMethodByNameInClass(name, desc, classNode);\n        if (name.equals(ByteCodeUtils.CONSTRUCTOR)) {\n            Constructor constructor = ConstructorBuilder.build(visitedClassName, method);\n\n            MethodVisitor mv = createMethodAdapter(access, constructor.args.name,\n                    constructor.args.desc, constructor.args.desc, constructor.args.signature,\n                    exceptions, isStatic, true /* isConstructor */);\n            constructor.args.accept(mv);\n\n            mv = createMethodAdapter(access, constructor.body.name,\n                    constructor.body.desc, newDesc, constructor.body.signature, exceptions,\n                    isStatic, true /* isConstructor */);\n            constructor.body.accept(mv);\n\n            // Remember our created methods so we can generated the access$dispatch for them.\n            addedMethods.add(constructor.args);\n            addedMethods.add(constructor.body);\n            return null;\n        } else {\n            String newName = isStatic ? computeOverrideMethodName(name, desc) : name;\n            return createMethodAdapter(access, newName, newDesc, newDesc, signature, exceptions,\n                    isStatic, false /* isConstructor */);\n        }\n    }\n\n    /**\n     * Creates a method adapter that will instrument to original code in such a way that it can\n     * patch live code.\n     * @param access the method access flags.\n     * @param name the method name\n     * @param originalDesc the original description.\n     * @param newDesc the modified method description that suits the InstantRun patching algorithms\n     * @param signature the method signature.\n     * @param exceptions the exceptions thrown by the method\n     * @param isStatic true if the method is static, false otherwise.\n     * @param isConstructor true if a constructor. false otherwise.\n     * @return the method adapter visitor.\n     */\n    private MethodVisitor createMethodAdapter(\n            int access,\n            String name,\n            String originalDesc,\n            String newDesc,\n            String signature,\n            String[] exceptions,\n            boolean isStatic,\n            boolean isConstructor) {\n\n        MethodVisitor methodVisitor =\n                super.visitMethod(access, name, originalDesc, signature,  exceptions);\n        methodVisitor = new TBIncrementalChangeVisitor.ISVisitor(methodVisitor, access, name, newDesc, isStatic, isConstructor);\n        // Install the Jsr/Ret inliner adapter, we have had reports of code still using the\n        // Jsr/Ret deprecated byte codes.\n        // see https://code.google.com/p/android/issues/detail?id=220019\n        return new JSRInlinerAdapter(methodVisitor, access, name, newDesc, signature, exceptions);\n    }\n\n    @Override\n    public FieldVisitor visitField(int access, String name, String desc, String signature,\n                                   Object value) {\n        // do not add any of the original class fields in the $override class, they would never\n        // be used and confuse the debugger.\n        return null;\n    }\n\n    public class ISVisitor extends GeneratorAdapter {\n\n        private final boolean isStatic;\n        private final boolean isConstructor;\n\n        /**\n         * Instrument a method.\n         * @param mv the parent method visitor.\n         * @param access the method access flags.\n         * @param name method name.\n         * @param desc method signature.\n         * @param isStatic true if the instrumented method was originally a static method.\n         * @param isConstructor true if  the instrumented code was originally a constructor body.\n         */\n        public ISVisitor(\n                MethodVisitor mv,\n                int access,\n                String name,\n                String desc,\n                boolean isStatic,\n                boolean isConstructor) {\n            super(Opcodes.ASM5, mv, access, name, desc);\n            this.isStatic = isStatic;\n            this.isConstructor = isConstructor;\n        }\n\n        @Override\n        public void visitFieldInsn(int opcode, String owner, String name, String desc) {\n            if (DEBUG) {\n                System.out.println(\n                        \"Visit field access : \" + owner + \":\" + name + \":\" + desc + \":\" + isStatic);\n            }\n            AccessRight accessRight;\n            if (!owner.equals(visitedClassName)) {\n                if (DEBUG) {\n                    System.out.println(owner + \":\" + name + \" field access\");\n                }\n                // we are accessing another object field, and at this point the visitor is not smart\n                // enough to know if has seen this class before or not so we must assume the field\n                // is *not* accessible from the $override class which lives in a different\n                // hierarchy and package.\n                // However, since we made all package-private and protected fields public, and it\n                // cannot be private since the visitedClassName is not the \"owner\", we can safely\n                // assume it's public.\n                accessRight = AccessRight.PUBLIC;\n            } else {\n                // check the field access bits.\n                FieldNode fieldNode = getFieldByName(name);\n                if (fieldNode == null) {\n                    // If this is an inherited field, we might not have had access to the parent\n                    // bytecode. In such a case, treat it as private.\n                    accessRight = AccessRight.PACKAGE_PRIVATE;\n                } else {\n                    accessRight = AccessRight.fromNodeAccess(fieldNode.access);\n                }\n            }\n\n            boolean handled = false;\n            switch(opcode) {\n                case Opcodes.PUTSTATIC:\n                case Opcodes.GETSTATIC:\n                    handled = visitStaticFieldAccess(opcode, owner, name, desc, accessRight);\n                    break;\n                case Opcodes.PUTFIELD:\n                case Opcodes.GETFIELD:\n                    handled = visitFieldAccess(opcode, owner, name, desc, accessRight);\n                    break;\n                default:\n                    System.out.println(\"Unhandled field opcode \" + opcode);\n            }\n            if (!handled) {\n                super.visitFieldInsn(opcode, owner, name, desc);\n            }\n        }\n\n        /**\n         * Visits an instance field access. The field could be of the visited class or it could be\n         * an accessible field from the class being visited (unless it's private).\n         * <p>\n         * For private instance fields, the access instruction is rewritten to calls to reflection\n         * to access the fields value:\n         * <p>\n         * Pseudo code for Get:\n         * <code>\n         *   value = $instance.fieldName;\n         * </code>\n         * becomes:\n         * <code>\n         *   value = (unbox)$package/AndroidInstantRuntime.getPrivateField($instance, $fieldName);\n         * </code>\n         * <p>\n         * Pseudo code for Set:\n         * <code>\n         *   $instance.fieldName = value;\n         * </code>\n         * becomes:\n         * <code>\n         *   $package/AndroidInstantRuntime.setPrivateField($instance, value, $fieldName);\n         * </code>\n         *\n         *\n         * @param opcode the field access opcode, can only be {@link Opcodes#PUTFIELD} or\n         *               {@link Opcodes#GETFIELD}\n         * @param owner the field declaring class\n         * @param name the field name\n         * @param desc the field type\n         * @param accessRight the {@link AccessRight} for the field.\n         * @return true if the field access was handled or false otherwise.\n         */\n        private boolean visitFieldAccess(\n                int opcode, String owner, String name, String desc, AccessRight accessRight) {\n\n            // if the accessed field is anything but public, we must go through reflection.\n            boolean useReflection = accessRight != AccessRight.PUBLIC;\n\n            // if the accessed field is accessed from within a constructor, it might be a public\n            // final field that cannot be set by anything but the original constructor unless\n            // we use reflection.\n            if (!useReflection) {\n                useReflection = isConstructor && (owner.equals(visitedClassName));\n            }\n\n            if (useReflection) {\n                // we should make this more efficient, have a per field access type method\n                // for getting and setting field values.\n                switch (opcode) {\n                    case Opcodes.GETFIELD:\n                        if (DEBUG) {\n                            System.out.println(\"Get field\");\n                        }\n                        // push declaring class\n                        visitLdcInsn(Type.getType(\"L\" + owner + \";\"));\n\n                        // the instance of the owner class we are getting the field value from\n                        // is on top of the stack. It could be \"this\"\n                        push(name);\n\n                        // Stack :  <receiver>\n                        //          <field_declaring_class>\n                        //          <field_name>\n                        invokeStatic(ALI_RUNTIME_TYPE,\n                                Method.getMethod(\"Object getPrivateField(Object, Class, String)\"));\n                        // Stack : <field_value>\n                        ByteCodeUtils.unbox(this, Type.getType(desc));\n                        break;\n                    case Opcodes.PUTFIELD:\n                        if (DEBUG) {\n                            System.out.println(\"Set field\");\n                        }\n                        // the instance of the owner class we are getting the field value from\n                        // is second on the stack. It could be \"this\"\n                        // top of the stack is the new value we are trying to set, box it.\n                        box(Type.getType(desc));\n\n                        // push declaring class\n                        visitLdcInsn(Type.getType(\"L\" + owner + \";\"));\n                        // push the field name.\n                        push(name);\n                        // Stack :  <receiver>\n                        //          <boxed_field_value>\n                        //          <field_declaring_class>\n                        //          <field_name>\n                        invokeStatic(ALI_RUNTIME_TYPE,\n                                Method.getMethod(\n                                        \"void setPrivateField(Object, Object, Class, String)\"));\n                        break;\n                    default:\n                        throw new RuntimeException(\n                                \"VisitFieldAccess called with wrong opcode \" + opcode);\n                }\n                return true;\n            }\n            // if this is a public field, no need to change anything we can access it from the\n            // $override class.\n            return false;\n        }\n\n        /**\n         * Static field access visit.\n         * So far we do not support class initializer \"clinit\" that would reset the static field\n         * value in the class newer versions. Think about the case, where a static initializer\n         * resets a static field value, we don't know if the current field value was set through\n         * the initial class initializer or some code path, should we change the field value to the\n         * new one ?\n         *\n         * For private static fields, the access instruction is rewritten to calls to reflection\n         * to access the fields value:\n         * <p>\n         * Pseudo code for Get:\n         * <code>\n         *   value = $type.fieldName;\n         * </code>\n         * becomes:\n         * <code>\n         *   value = (unbox)$package/AndroidInstantRuntime.getStaticPrivateField(\n         *       $type.class, $fieldName);\n         * </code>\n         * <p>\n         * Pseudo code for Set:\n         * <code>\n         *   $type.fieldName = value;\n         * </code>\n         * becomes:\n         * <code>\n         *   $package/AndroidInstantRuntime.setStaticPrivateField(value, $type.class $fieldName);\n         * </code>\n         *\n         * @param opcode the field access opcode, can only be {@link Opcodes#PUTSTATIC} or\n         *               {@link Opcodes#GETSTATIC}\n         * @param name the field name\n         * @param desc the field type\n         * @param accessRight the {@link AccessRight} for the field.\n         * @return true if the field access was handled or false\n         */\n        private boolean visitStaticFieldAccess(\n                int opcode, String owner, String name, String desc, AccessRight accessRight) {\n\n            if (accessRight != AccessRight.PUBLIC) {\n                switch (opcode) {\n                    case Opcodes.GETSTATIC:\n                        if (DEBUG) {\n                            System.out.println(\"Get static field \" + name);\n                        }\n                        // nothing of interest is on the stack.\n                        visitLdcInsn(Type.getType(\"L\" + owner + \";\"));\n                        push(name);\n                        // Stack : <target_class>\n                        //         <field_name>\n                        invokeStatic(ALI_RUNTIME_TYPE,\n                                Method.getMethod(\"Object getStaticPrivateField(Class, String)\"));\n                        // Stack : <field_value>\n                        ByteCodeUtils.unbox(this, Type.getType(desc));\n                        return true;\n                    case Opcodes.PUTSTATIC:\n                        if (DEBUG) {\n                            System.out.println(\"Set static field \" + name);\n                        }\n                        // the new field value is on top of the stack.\n                        // box it into an Object.\n                        box(Type.getType(desc));\n                        visitLdcInsn(Type.getType(\"L\" + owner + \";\"));\n                        push(name);\n                        // Stack :  <boxed_field_value>\n                        //          <target_class>\n                        //          <field_name>\n                        invokeStatic(ALI_RUNTIME_TYPE,\n                                Method.getMethod(\n                                        \"void setStaticPrivateField(Object, Class, String)\"));\n                        return true;\n                    default:\n                        throw new RuntimeException(\n                                \"VisitStaticFieldAccess called with wrong opcode \" + opcode);\n                }\n            }\n            return false;\n        }\n\n        @Override\n        public void visitMethodInsn(int opcode, String owner, String name, String desc,\n                                    boolean itf) {\n\n            if (DEBUG) {\n                System.out.println(\"Generic Method dispatch : \" + opcode +\n                        \":\" + owner + \":\" + name + \":\" + desc + \":\" + itf + \":\" + isStatic);\n            }\n            boolean opcodeHandled = false;\n            if (opcode == Opcodes.INVOKESPECIAL) {\n                opcodeHandled = handleSpecialOpcode(owner, name, desc, itf);\n            } else if (opcode == Opcodes.INVOKEVIRTUAL) {\n                opcodeHandled = handleVirtualOpcode(owner, name, desc, itf);\n            } else if (opcode == Opcodes.INVOKESTATIC) {\n                opcodeHandled = handleStaticOpcode(owner, name, desc, itf);\n            }\n            if (DEBUG) {\n                System.out.println(\"Opcode handled ? \" + opcodeHandled);\n            }\n            if (!opcodeHandled) {\n                mv.visitMethodInsn(opcode, owner, name, desc, itf);\n            }\n            if (DEBUG) {\n                System.out.println(\"Done with generic method dispatch\");\n            }\n        }\n\n        /**\n         * Rewrites INVOKESPECIAL method calls:\n         * <ul>\n         *  <li>calls to constructors are handled specially (see below)</li>\n         *  <li>calls to super methods are rewritten to call the 'access$super' trampoline we\n         *      injected into the original code</li>\n         *  <li>calls to methods in this class are rewritten to call the mathcin $override class\n         *  static method</li>\n         * </ul>\n         */\n        private boolean handleSpecialOpcode(String owner, String name, String desc,\n                                            boolean itf) {\n            if (name.equals(\"<init>\")) {\n                return handleConstructor(owner, name, desc);\n            }\n            if (owner.equals(visitedClassName)) {\n                if (DEBUG) {\n                    System.out.println(\n                            \"Private Method : \" + name + \":\" + desc + \":\" + itf + \":\" + isStatic);\n                }\n                // private method dispatch, just invoke the $override class static method.\n                String newDesc = computeOverrideMethodDesc(desc, false /*isStatic*/);\n                super.visitMethodInsn(Opcodes.INVOKESTATIC, owner + \"$ipReplace\", name, newDesc, itf);\n                return true;\n            } else {\n                if (DEBUG) {\n                    System.out.println(\n                            \"Super Method : \" + name + \":\" + desc + \":\" + itf + \":\" + isStatic);\n                }\n                int arr = boxParametersToNewLocalArray(Type.getArgumentTypes(desc));\n                push(name + \".\" + desc);\n                loadLocal(arr);\n                mv.visitMethodInsn(Opcodes.INVOKESTATIC, visitedClassName, \"ipc$super\",\n                        instanceToStaticDescPrefix\n                                + \"Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;\",\n                        false);\n                handleReturnType(desc);\n\n                return true;\n            }\n        }\n\n        /**\n         * Rewrites INVOKEVIRTUAL method calls.\n         * <p>\n         * Virtual calls to protected methods are rewritten according to the following pseudo code:\n         * before:\n         * <code>\n         *   $value = $instance.protectedVirtual(arg1, arg2);\n         * </code>\n         * after:\n         * <code>\n         *   $value = (unbox)$package/AndroidInstantRuntime.invokeProtectedMethod($instance,\n         *          new object[] {arg1, arg2}, new Class[] { String.class, Integer.class },\n         *          \"protectedVirtual\");\n         * </code>\n         */\n        private boolean handleVirtualOpcode(String owner, String name, String desc, boolean itf) {\n\n            if (DEBUG) {\n                System.out.println(\n                        \"Virtual Method : \" + name + \":\" + desc + \":\" + itf + \":\" + isStatic);\n\n            }\n            AccessRight accessRight = getMethodAccessRight(owner, name, desc);\n            if (accessRight == AccessRight.PUBLIC) {\n                return false;\n            }\n\n            // for anything else, private, protected and package private, we must go through\n            // reflection.\n            // Stack : <receiver>\n            //      <param_1>\n            //      <param_2>\n            //      ...\n            //      <param_n>\n            pushMethodRedirectArgumentsOnStack(name, desc);\n\n            // Stack : <receiver>\n            //      <array of parameter_values>\n            //      <array of parameter_types>\n            //      <method_name>\n            invokeStatic(ALI_RUNTIME_TYPE, Method.getMethod(\n                    \"Object invokeProtectedMethod(Object, Object[], Class[], String)\"));\n            // Stack : <return value or null if no return value>\n            handleReturnType(desc);\n            return true;\n        }\n\n        /**\n         * Rewrites INVOKESTATIC method calls.\n         * <p>\n         * Static calls to non-public methods are rewritten according to the following pseudo code:\n         * before:\n         * <code>\n         *   $value = $type.protectedStatic(arg1, arg2);\n         * </code>\n         * after:\n         * <code>\n         *   $value = (unbox)$package/AndroidInstantRuntime.invokeProtectedStaticMethod(\n         *          new object[] {arg1, arg2}, new Class[] { String.class, Integer.class },\n         *          \"protectedStatic\", $type.class);\n         * </code>\n         */\n        private boolean handleStaticOpcode(String owner, String name, String desc, boolean itf) {\n\n            if (DEBUG) {\n                System.out.println(\n                        \"Static Method : \" + name + \":\" + desc + \":\" + itf + \":\" + isStatic);\n\n            }\n            AccessRight accessRight = getMethodAccessRight(owner, name, desc);\n            if (accessRight == AccessRight.PUBLIC) {\n                return false;\n            }\n\n            // for anything else, private, protected and package private, we must go through\n            // reflection.\n\n            // stack: <param_1>\n            //      <param_2>\n            //      ...\n            //      <param_n>\n            pushMethodRedirectArgumentsOnStack(name, desc);\n\n            // push the class implementing the original static method\n            visitLdcInsn(Type.getType(\"L\" + owner + \";\"));\n\n            // stack: <boxed method parameter>\n            //      <target parameter types>\n            //      <target method name>\n            //      <target class name>\n            invokeStatic(ALI_RUNTIME_TYPE, Method.getMethod(\n                    \"Object invokeProtectedStaticMethod(Object[], Class[], String, Class)\"));\n            // stack : method return value or null if the method was VOID.\n            handleReturnType(desc);\n            return true;\n        }\n\n        @Override\n        public void visitTypeInsn(int opcode, String s) {\n            if (opcode == Opcodes.NEW) {\n                // state can only normal or dup_after new\n                if (state == TBIncrementalChangeVisitor.MachineState.AFTER_NEW) {\n                    throw new RuntimeException(\"Panic, two NEW opcode without a DUP\");\n                }\n\n                if (isInSamePackage(s)) {\n                    // this is a new allocation in the same package, this could be protected or\n                    // package private class, we must go through reflection, otherwise not.\n                    // set our state so we swallow the next DUP we encounter.\n                    state = TBIncrementalChangeVisitor.MachineState.AFTER_NEW;\n\n                    // swallow the NEW, we will also swallow the DUP associated with the new\n                    return;\n                }\n            }\n            super.visitTypeInsn(opcode, s);\n        }\n\n        @Override\n        public void visitInsn(int opcode) {\n            // check the last object allocation we encountered, if this is in the same package\n            // we need to go through reflection and should therefore remove the DUP, otherwise\n            // we leave it.\n            if (opcode == Opcodes.DUP && state == TBIncrementalChangeVisitor.MachineState.AFTER_NEW) {\n\n                state = TBIncrementalChangeVisitor.MachineState.NORMAL;\n                return;\n            }\n            super.visitInsn(opcode);\n        }\n\n        /**\n         * For calls to constructors in the same package, calls are rewritten to use reflection\n         * to create the instance (see above, the NEW and DUP instructions are also removed) using\n         * the following pseudo code.\n         * <p>\n         * before:\n         * <code>\n         *   $value = new $type(arg1, arg2);\n         * </code>\n         * after:\n         * <code>\n         *   $value = ($type)$package/AndroidInstantRuntime.newForClass(new Object[] {arg1, arg2 },\n         *       new Class[]{ String.class, Integer.class }, $type.class);\n         * </code>\n         *\n         */\n        private boolean handleConstructor(String owner, String name, String desc) {\n\n            if (isInSamePackage(owner)) {\n\n                Type expectedType = Type.getType(\"L\" + owner + \";\");\n                pushMethodRedirectArgumentsOnStack(name, desc);\n\n                // pop the name, we don't need it.\n                pop();\n                visitLdcInsn(expectedType);\n\n                invokeStatic(ALI_RUNTIME_TYPE, Method.getMethod(\n                        \"Object newForClass(Object[], Class[], Class)\"));\n\n                checkCast(expectedType);\n                ByteCodeUtils.unbox(this, expectedType);\n                return true;\n            } else {\n                return false;\n            }\n        }\n\n        @Override\n        public void visitLocalVariable(String name, String desc, String signature, Label start,\n                                       Label end, int index) {\n            // Even if we call the first argument of the static redirection \"this\", JDI has a\n            // specific API to retrieve \"thisObject\" from the current stack frame, which totally\n            // ignores and bypasses this variable declaration. We will not show the renamed\n            // variable to the user and will redirect in Studio to be the real this object.\n            // We use a name unlikely to be used, but different than \"this\".\n            if (\"this\".equals(name)) {\n                name = \"$this\";\n            }\n            super.visitLocalVariable(name, desc, signature, start, end, index);\n        }\n\n        @Override\n        public void visitEnd() {\n            if (DEBUG) {\n                System.out.println(\"Method visit end\");\n            }\n        }\n\n        /**\n         * Returns the actual method access right or a best guess if we don't have access to the\n         * method definition.\n         * @param owner the method owner class\n         * @param name the method name\n         * @param desc the method signature\n         * @return the {@link AccessRight} for that method.\n         */\n        private AccessRight getMethodAccessRight(String owner, String name, String desc) {\n            AccessRight accessRight;\n            if (owner.equals(visitedClassName)) {\n                MethodNode methodByName = getMethodByName(name, desc);\n                if (methodByName == null) {\n                    // we did not find the method invoked on ourselves, which mean that it really\n                    // is a parent class method invocation and we just don't have access to it.\n                    // the most restrictive access right in that case is protected.\n                    return AccessRight.PROTECTED;\n                }\n                accessRight = AccessRight.fromNodeAccess(methodByName.access);\n            } else {\n                // we are accessing another class method, and since we make all protected and\n                // package-private methods public, we can safely assume it is public.\n                accessRight = AccessRight.PUBLIC;\n            }\n            return accessRight;\n        }\n\n        /**\n         * Push arguments necessary to invoke one of the method redirect function :\n         * <ul>{@link GenericInstantRuntime#invokeProtectedMethod(Object, Object[], Class[], String)}</ul>\n         * <ul>{@link GenericInstantRuntime#invokeProtectedStaticMethod(Object[], Class[], String, Class)}</ul>\n         *\n         * This function will only push on the stack the three common arguments :\n         *      Object[] the boxed parameter values\n         *      Class[] the parameter types\n         *      String the original method name\n         *\n         * Stack before :\n         *          <param1>\n         *          <param2>\n         *          ...\n         *          <paramN>\n         * Stack After :\n         *          <array of parameters>\n         *          <array of parameter types>\n         *          <method name>\n         * @param name the original method name.\n         * @param desc the original method signature.\n         */\n        private void pushMethodRedirectArgumentsOnStack(String name, String desc) {\n            Type[] parameterTypes = Type.getArgumentTypes(desc);\n\n            // stack : <parameters values>\n            int parameters = boxParametersToNewLocalArray(parameterTypes);\n            // push the parameter values as a Object[] on the stack.\n            loadLocal(parameters);\n\n            // push the parameter types as a Class[] on the stack\n            pushParameterTypesOnStack(parameterTypes);\n\n            push(name);\n        }\n\n        /**\n         * Creates an array of {@link Class} objects with the same size of the array of the passed\n         * parameter types. For each parameter type, stores its {@link Class} object into the\n         * result array. For intrinsic types which are not present in the class constant pool, just\n         * push the actual {@link Type} object on the stack and let ASM do the rest. For non\n         * intrinsic type use a {@link MethodVisitor#visitLdcInsn(Object)} to ensure the\n         * referenced class's presence in this class constant pool.\n         *\n         * Stack Before : nothing of interest\n         * Stack After : <array of {@link Class}>\n         *\n         * @param parameterTypes a method list of parameters.\n         */\n        private void pushParameterTypesOnStack(Type[] parameterTypes) {\n            push(parameterTypes.length);\n            newArray(Type.getType(Class.class));\n\n            for (int i = 0; i < parameterTypes.length; i++) {\n                dup();\n                push(i);\n                switch(parameterTypes[i].getSort()) {\n                    case Type.OBJECT:\n                    case Type.ARRAY:\n                        visitLdcInsn(parameterTypes[i]);\n                        break;\n                    case Type.BOOLEAN:\n                    case Type.CHAR:\n                    case Type.BYTE:\n                    case Type.SHORT:\n                    case Type.INT:\n                    case Type.LONG:\n                    case Type.FLOAT:\n                    case Type.DOUBLE:\n                        push(parameterTypes[i]);\n                        break;\n                    default:\n                        throw new RuntimeException(\n                                \"Unexpected parameter type \" + parameterTypes[i]);\n\n                }\n                arrayStore(Type.getType(Class.class));\n            }\n        }\n\n        /**\n         * Handle method return logic.\n         * @param desc the method signature\n         */\n        private void handleReturnType(String desc) {\n            Type ret = Type.getReturnType(desc);\n            if (ret.getSort() == Type.VOID) {\n                pop();\n            } else {\n                ByteCodeUtils.unbox(this, ret);\n            }\n        }\n\n        private int boxParametersToNewLocalArray(Type[] parameterTypes) {\n            int parameters = newLocal(Type.getType(\"[Ljava/lang.Object;\"));\n            push(parameterTypes.length);\n            newArray(Type.getType(Object.class));\n            storeLocal(parameters);\n\n            for (int i = parameterTypes.length - 1; i >= 0; i--) {\n                loadLocal(parameters);\n                swap(parameterTypes[i], Type.getType(Object.class));\n                push(i);\n                swap(parameterTypes[i], Type.INT_TYPE);\n                box(parameterTypes[i]);\n                arrayStore(Type.getType(Object.class));\n            }\n            return parameters;\n        }\n    }\n\n    @Override\n    public void visitEnd() {\n        addDispatchMethod();\n    }\n\n    /**\n     * To each class, add the dispatch method called by the original code that acts as a trampoline to\n     * invoke the changed methods.\n     * <p>\n     * Pseudo code:\n     * <code>\n     *   Object access$dispatch(String name, object[] args) {\n     *      if (name.equals(\n     *          \"firstMethod.(L$type;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;\")) {\n     *        return firstMethod(($type)arg[0], (String)arg[1], arg[2]);\n     *      }\n     *      if (name.equals(\"secondMethod.(L$type;Ljava/lang/String;I;)V\")) {\n     *        secondMethod(($type)arg[0], (String)arg[1], (int)arg[2]);\n     *        return;\n     *      }\n     *      ...\n     *      StringBuilder $local1 = new StringBuilder();\n     *      $local1.append(\"Method not found \");\n     *      $local1.append(name);\n     *      $local1.append(\" in \" + visitedClassName +\n     *          \"$dispatch implementation, restart the application\");\n     *      throw new $package/InstantReloadException($local1.toString());\n     *   }\n     * </code>\n     */\n    private void addDispatchMethod() {\n        int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_VARARGS;\n        Method m = new Method(\"ipc$dispatch\", \"(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;\");\n        MethodVisitor visitor = super.visitMethod(access,\n                m.getName(),\n                m.getDescriptor(),\n                null, null);\n\n        final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor);\n\n        if (TRACING_ENABLED) {\n            mv.push(\"Redirecting \");\n            mv.loadArg(0);\n            trace(mv, 2);\n        }\n\n        List<MethodNode> allMethods = new ArrayList<>();\n\n        // if we are disabled, do not generate any dispatch, the method will throw an exception\n        // if invoked which should never happen.\n        if (!instantRunDisabled) {\n            //noinspection unchecked\n            allMethods.addAll(classNode.methods);\n            allMethods.addAll(addedMethods);\n        }\n\n        final Map<String, MethodNode> methods = new HashMap<>();\n        for (MethodNode methodNode : allMethods) {\n            if (methodNode.name.equals(\"<clinit>\") || methodNode.name.equals(\"<init>\")) {\n                continue;\n            }\n            if (!isAccessCompatibleWithInstantRun(methodNode.access)) {\n                continue;\n            }\n            methods.put(methodNode.name + \".\" + methodNode.desc, methodNode);\n        }\n\n        new StringSwitch() {\n            @Override\n            void visitString() {\n                mv.visitVarInsn(Opcodes.ALOAD, 1);\n            }\n\n            @Override\n            void visitCase(String methodName) {\n                MethodNode methodNode = methods.get(methodName);\n                String name = methodNode.name;\n                boolean isStatic = (methodNode.access & Opcodes.ACC_STATIC) != 0;\n                String newDesc =\n                        computeOverrideMethodDesc(methodNode.desc, isStatic);\n\n                if (TRACING_ENABLED) {\n                    trace(mv, \"M: \" + name + \" P:\" + newDesc);\n                }\n                Type[] args = Type.getArgumentTypes(newDesc);\n                int argc = 0;\n                for (Type t : args) {\n                    mv.visitVarInsn(Opcodes.ALOAD, 2);\n                    mv.push(argc);\n                    mv.visitInsn(Opcodes.AALOAD);\n                    ByteCodeUtils.unbox(mv, t);\n                    argc++;\n                }\n                mv.visitMethodInsn(Opcodes.INVOKESTATIC, visitedClassName + OVERRIDE_SUFFIX,\n                        isStatic ? computeOverrideMethodName(name, methodNode.desc) : name,\n                        newDesc, false);\n                Type ret = Type.getReturnType(methodNode.desc);\n                if (ret.getSort() == Type.VOID) {\n                    mv.visitInsn(Opcodes.ACONST_NULL);\n                } else {\n                    mv.box(ret);\n                }\n                mv.visitInsn(Opcodes.ARETURN);\n            }\n\n            @Override\n            void visitDefault() {\n                writeMissingMessageWithHash(mv, visitedClassName);\n            }\n        }.visit(mv, methods.keySet());\n\n        mv.visitMaxs(0, 0);\n        mv.visitEnd();\n\n        super.visitEnd();\n    }\n\n\n    /**\n     * Returns true if the passed class name is in the same package as the visited class.\n     *\n     * @param type The type name of the other object, either a \"com/var/Object\" or a \"[Type\" one.\n     * @return true if className and visited class are in the same java package.\n     */\n    private boolean isInSamePackage(@NonNull String type) {\n        if (type.charAt(0) == '[') {\n            return false;\n        }\n        return getPackage(visitedClassName).equals(getPackage(type));\n    }\n\n    /**\n     * @return the package of the given / separated class name.\n     */\n    private String getPackage(@NonNull String className) {\n        int i = className.lastIndexOf('/');\n        return i == -1 ? className : className.substring(0, i);\n    }\n\n    /**\n     * Returns true if the passed class name is an ancestor of the visited class.\n     *\n     * @param className a / separated class name\n     * @return true if it is an ancestor, false otherwise.\n     */\n    private boolean isAnAncestor(@NonNull String className) {\n        for (ClassNode parentNode : parentNodes) {\n            if (parentNode.name.equals(className)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Instance methods, when converted to static methods need to have the subject object as\n     * the first parameter. If the method is static, it is unchanged.\n     */\n    @NonNull\n    private String computeOverrideMethodDesc(@NonNull String desc, boolean isStatic) {\n        if (isStatic) {\n            return desc;\n        } else {\n            return instanceToStaticDescPrefix + desc.substring(1);\n        }\n    }\n\n    /**\n     * Prevent method name collisions.\n     *\n     * A static method that takes an instance of this class as the first argument might clash with\n     * a rewritten instance method, and this rewrites all methods like that. This is an\n     * over-approximation of the necessary renames, but it has the advantage of neither adding\n     * additional state nor requiring lookups.\n     */\n    @NonNull\n    private String computeOverrideMethodName(@NonNull String name, @NonNull String desc) {\n        if (desc.startsWith(instanceToStaticDescPrefix)\n                && !name.equals(\"init$args\")\n                && !name.equals(\"init$body\")) {\n            return METHOD_MANGLE_PREFIX + name;\n        }\n        return name;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/incremental/TBIncrementalSupportVisitor.java",
    "content": "package com.android.build.gradle.internal.incremental;\n\nimport com.android.annotations.NonNull;\nimport com.android.utils.ILogger;\nimport com.google.common.base.Objects;\nimport org.objectweb.asm.*;\nimport org.objectweb.asm.commons.GeneratorAdapter;\nimport org.objectweb.asm.commons.JSRInlinerAdapter;\nimport org.objectweb.asm.commons.Method;\nimport org.objectweb.asm.tree.ClassNode;\nimport org.objectweb.asm.tree.LabelNode;\nimport org.objectweb.asm.tree.LineNumberNode;\nimport org.objectweb.asm.tree.MethodNode;\n\nimport java.util.*;\nimport java.util.function.Consumer;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\n\n/**\n * 创建日期：2018/11/28 on 下午12:43\n * 描述:\n * 作者:zhayu.ll\n */\npublic class TBIncrementalSupportVisitor extends TBIncrementalVisitor {\n\n    private boolean disableRedirectionForClass = false;\n\n\n\n    public void setPatchInitMethod(boolean patchInitMethod) {\n        this.patchInitMethod = patchInitMethod;\n    }\n\n    private boolean patchInitMethod = false;\n\n\n    public boolean isSupportAddCallSuper() {\n        return supportAddCallSuper;\n    }\n\n    public void setSupportAddCallSuper(boolean supportAddCallSuper) {\n        this.supportAddCallSuper = supportAddCallSuper;\n    }\n\n    private boolean supportAddCallSuper = false;\n\n    private List<MethodNode>methodNodes = new ArrayList<>();\n\n    private List<String>visitSuperMethods = new ArrayList<>();\n\n\n    public boolean isSupportEachMethod() {\n        return supportEachMethod;\n    }\n\n    public void setSupportEachMethod(boolean supportEachMethod) {\n        this.supportEachMethod = supportEachMethod;\n    }\n\n    private boolean supportEachMethod = false;\n\n\n\n    public TBIncrementalSupportVisitor(\n            @NonNull ClassNode classNode,\n            @NonNull List<ClassNode> parentNodes,\n            @NonNull ClassVisitor classVisitor,\n            @NonNull ILogger logger) {\n        super(classNode, parentNodes, classVisitor, logger);\n        classNode.methods.forEach((Consumer<MethodNode>) o -> {\n            if (!o.name.equals(ByteCodeUtils.CONSTRUCTOR) &&! o.name.equals(ByteCodeUtils.CLASS_INITIALIZER)) {\n                methodNodes.add(o);\n            }\n        });\n    }\n\n    /**\n     * Ensures that the class contains a $change field used for referencing the IncrementalChange\n     * dispatcher.\n     *\n     * <p>Also updates package_private visibility to public so we can call into this class from\n     * outside the package.\n     */\n    @Override\n    public void visit(int version, int access, String name, String signature, String superName,\n                      String[] interfaces) {\n        visitedClassName = name;\n        visitedSuperName = superName;\n\n        if (supportEachMethod){\n            methodNodes.forEach(methodNode -> {\n                String fullName = methodNode.name + \".\" + methodNode.desc;\n                super.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC\n                                | Opcodes.ACC_VOLATILE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_TRANSIENT,\n                        \"$ipChange\"+\"$\"+ fullName.hashCode(), getRuntimeTypeName(ALI_CHANGE_TYPE), null, null);\n            });\n\n        }else {\n//            super.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC\n//                            | Opcodes.ACC_VOLATILE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_TRANSIENT,\n//                    \"$ipChange\", getRuntimeTypeName(ALI_CHANGE_TYPE), null, null);\n\n            super.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC\n                            | Opcodes.ACC_TRANSIENT |Opcodes.ACC_SYNTHETIC,\n                    \"$ipChange\", getRuntimeTypeName(ALI_CHANGE_TYPE), null, null);\n        }\n        access = transformClassAccessForInstantRun(access);\n        super.visit(version, access, name, signature, superName, interfaces);\n    }\n\n    @Override\n    public void visitInnerClass(String name, String outerName, String innerName, int access) {\n        int newAccess =\n                access & (~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED)) | Opcodes.ACC_PUBLIC;\n        super.visitInnerClass(name, outerName, innerName, newAccess);\n    }\n\n    @Override\n    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {\n        if (desc.equals(ALI_DISABLE_ANNOTATION_TYPE.getDescriptor())) {\n            disableRedirectionForClass = true;\n        }\n        return super.visitAnnotation(desc, visible);\n    }\n\n\n    @Override\n    public FieldVisitor visitField(int access, String name, String desc, String signature,\n                                   Object value) {\n\n        access = transformAccessForInstantRun(access);\n        return super.visitField(access, name, desc, signature, value);\n    }\n\n    /**\n     * Insert Constructor specific logic({@link ConstructorRedirection} and\n     * {@link ConstructorBuilder}) for constructor redirecting or\n     * normal method redirecting ({@link MethodRedirection}) for other methods.\n     */\n    @Override\n    public MethodVisitor visitMethod(int access, String name, String desc, String signature,\n                                     String[] exceptions) {\n\n        access = transformAccessForInstantRun(access);\n\n        MethodVisitor defaultVisitor = super.visitMethod(access, name, desc, signature, exceptions);\n        MethodNode method =\n                checkNotNull(\n                        getMethodByNameInClass(name, desc, classNode),\n                        \"Method found by visitor but not in the pre-parsed class node.\");\n        // does the method use blacklisted APIs.\n\n        if (!supportAddCallSuper) {\n            method.instructions.accept(new MethodVisitor(api) {\n                @Override\n                public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {\n                    if (opcode == Opcodes.INVOKESPECIAL && !owner.equals(visitedClassName)) {\n                        visitSuperMethods.add(name + \".\" + desc);\n                    }\n                    super.visitMethodInsn(opcode, owner, name, desc, itf);\n                }\n            });\n        }\n\n        //this is method generaged by visualMachine\n\n        if ((access & Opcodes.ACC_SYNTHETIC) != 0){\n            return defaultVisitor;\n        }\n\n        boolean hasIncompatibleChange = InstantRunMethodVerifier.verifyMethod(method)\n                != InstantRunVerifierStatus.COMPATIBLE;\n\n        if (hasIncompatibleChange || disableRedirectionForClass\n                || !isAccessCompatibleWithInstantRun(access)\n                || name.equals(ByteCodeUtils.CLASS_INITIALIZER)) {\n            return defaultVisitor;\n        } else {\n            ArrayList<Type> args = new ArrayList<>(Arrays.asList(Type.getArgumentTypes(desc)));\n            boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;\n            if (!isStatic) {\n                args.add(0, Type.getType(Object.class));\n            }\n\n            // Install the Jsr/Ret inliner adapter, we have had reports of code still using the\n            // Jsr/Ret deprecated byte codes.\n            // see https://code.google.com/p/android/issues/detail?id=220019\n            JSRInlinerAdapter jsrInlinerAdapter = new JSRInlinerAdapter(\n                    defaultVisitor, access, name, desc, signature, exceptions);\n\n            ISMethodVisitor mv = new ISMethodVisitor(jsrInlinerAdapter, access, name, desc);\n            if (name.equals(ByteCodeUtils.CONSTRUCTOR)) {\n\n                if (patchInitMethod) {\n                    Constructor constructor = ConstructorBuilder.build(visitedClassName, method);\n                    LabelNode start = new LabelNode();\n                    method.instructions.insert(constructor.loadThis, start);\n                    if (constructor.lineForLoad != -1) {\n                        // Record the line number from the start of LOAD_0 for uninitialized 'this'.\n                        // This allows a breakpoint to be set at the line with this(...) or super(...)\n                        // call in the constructor.\n                        method.instructions.insert(constructor.loadThis,\n                                new LineNumberNode(constructor.lineForLoad, start));\n                    }\n                    mv.addRedirection(new TBConstructorRedirection(start, constructor, args));\n\n                } else {\n                    return defaultVisitor;\n                }\n\n            } else {\n                mv.addRedirection(new TBMethodRedirection(\n                        new LabelNode(mv.getStartLabel()),\n                        name + \".\" + desc,\n                        args,\n                        Type.getReturnType(desc)));\n            }\n            method.accept(mv);\n            return null;\n        }\n    }\n\n    /**\n     * If a class is package private, make it public so instrumented code living in a different\n     * class loader can instantiate them.\n     *\n     * <p>We also set the {@code ACC_SUPER} flag on every class, since otherwise the\n     * {@code invokespecial} bytecodes in access$super get compiled to invoke-direct, which fails\n     * at runtime (on KitKat). See the VM spec (4.1) for the whole story of {@code ACC_SUPER}. It\n     * is only missing in classes generated by third-party tools, e.g. AspectJ.\n     *\n     * @param access the original class/method/field access.\n     * @return the new access or the same one depending on the original access rights.\n     */\n    private static int transformClassAccessForInstantRun(int access) {\n        AccessRight accessRight = AccessRight.fromNodeAccess(access);\n        int fixedVisibility = accessRight == AccessRight.PACKAGE_PRIVATE\n                ? access | Opcodes.ACC_PUBLIC\n                : access;\n\n        // TODO: only do this on KitKat?\n        return fixedVisibility | Opcodes.ACC_SUPER;\n    }\n\n    /**\n     * If a method/field is not private, make it public. This is to workaround the fact\n     * <ul>Our restart.dex files are loaded with a different class loader than the main dex file\n     * class loader on restart. so we need methods/fields to be public</ul>\n     * <ul>Our reload.dex are loaded from a different class loader as well but methods/fields\n     * are accessed through reflection, yet you need class visibility.</ul>\n     * <p>\n     * remember that in Java, protected methods or fields can be acessed by classes in the same\n     * package :\n     * {@see https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html}\n     *\n     * @param access the original class/method/field access.\n     * @return the new access or the same one depending on the original access rights.\n     */\n    private static int transformAccessForInstantRun(int access) {\n        AccessRight accessRight = AccessRight.fromNodeAccess(access);\n        if (accessRight != AccessRight.PRIVATE) {\n            access &= ~Opcodes.ACC_PROTECTED;\n            access &= ~Opcodes.ACC_PRIVATE;\n            return access | Opcodes.ACC_PUBLIC;\n        }\n        return access;\n    }\n\n    private class ISMethodVisitor extends GeneratorAdapter {\n\n        private boolean disableRedirection = false;\n        private int change;\n        private final List<Type> args;\n        private final List<Redirection> redirections;\n        private final Map<Label, Redirection> resolvedRedirections;\n        private final Label start;\n        private String fullName;\n\n        public ISMethodVisitor(MethodVisitor mv, int access, String name, String desc) {\n            super(Opcodes.ASM5, mv, access, name, desc);\n            this.change = -1;\n            this.redirections = new ArrayList<>();\n            this.resolvedRedirections = new HashMap<>();\n            this.args = new ArrayList<>(Arrays.asList(Type.getArgumentTypes(desc)));\n            this.start = new Label();\n            boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;\n             fullName = name + \".\" + desc;\n\n            // if this is not a static, we add a fictional first parameter what will contain the\n            // \"this\" reference which can be loaded with ILOAD_0 bytecode.\n            if (!isStatic) {\n                args.add(0, Type.getType(Object.class));\n            }\n        }\n\n        @Override\n        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {\n            if (desc.equals(ALI_DISABLE_ANNOTATION_TYPE.getDescriptor())) {\n                disableRedirection = true;\n            }\n            return super.visitAnnotation(desc, visible);\n        }\n\n        /**\n         * inserts a new local '$change' in each method that contains a reference to the type's\n         * IncrementalChange dispatcher, this is done to avoid threading issues.\n         * <p>\n         * Pseudo code:\n         * <code>\n         * $package/IncrementalChange $local1 = $className$.$change;\n         * </code>\n         */\n        @Override\n        public void visitCode() {\n            if (!disableRedirection) {\n                // Labels cannot be used directly as they are volatile between different visits,\n                // so we must use LabelNode and resolve before visiting for better performance.\n                for (Redirection redirection : redirections) {\n                    resolvedRedirections.put(redirection.getPosition().getLabel(), redirection);\n                }\n\n                super.visitLabel(start);\n                change = newLocal(ALI_CHANGE_TYPE);\n                if (supportEachMethod){\n                    visitFieldInsn(Opcodes.GETSTATIC, visitedClassName, \"$ipChange\"+\"$\"+fullName.hashCode(),\n                            getRuntimeTypeName(ALI_CHANGE_TYPE));\n                }else {\n                    visitFieldInsn(Opcodes.GETSTATIC, visitedClassName, \"$ipChange\",\n                            getRuntimeTypeName(ALI_CHANGE_TYPE));\n                }\n                storeLocal(change);\n\n                redirectAt(start);\n            }\n            super.visitCode();\n        }\n\n        @Override\n        public void visitLabel(Label label) {\n            super.visitLabel(label);\n            redirectAt(label);\n        }\n\n        private void redirectAt(Label label) {\n            if (disableRedirection) return;\n            Redirection redirection = resolvedRedirections.get(label);\n            if (redirection != null) {\n                // A special line number to mark this area of code.\n                super.visitLineNumber(0, label);\n                redirection.redirect(this, change);\n            }\n        }\n\n        public void addRedirection(@NonNull Redirection redirection) {\n            redirections.add(redirection);\n        }\n\n\n        @Override\n        public void visitLocalVariable(String name, String desc, String signature, Label start,\n                                       Label end, int index) {\n            // In dex format, the argument names are separated from the local variable names. It\n            // seems to be needed to declare the local argument variables from the beginning of\n            // the methods for dex to pick that up. By inserting code before the first label we\n            // break that. In Java this is fine, and the debugger shows the right thing. However\n            // if we don't readjust the local variables, we just don't see the arguments.\n            if (!disableRedirection && index < args.size()) {\n                start = this.start;\n            }\n            super.visitLocalVariable(name, desc, signature, start, end, index);\n        }\n\n        public Label getStartLabel() {\n            return start;\n        }\n    }\n\n    /**\n     * Decorated {@link MethodNode} that maintains a reference to the class declaring the method.\n     */\n    public static class MethodReference {\n        final MethodNode method;\n        final ClassNode owner;\n\n        private MethodReference(MethodNode method, ClassNode owner) {\n            this.method = method;\n            this.owner = owner;\n        }\n    }\n\n    /***\n     * Inserts a trampoline to this class so that the updated methods can make calls to super\n     * class methods.\n     * <p>\n     * Pseudo code for this trampoline:\n     * <code>\n     *   Object access$super($classType instance, String name, object[] args) {\n     *      switch(name) {\n     *          case \"firstMethod.(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;\":\n     *            return super~instance.firstMethod((String)arg[0], arg[1]);\n     *          case \"secondMethod.(Ljava/lang/String;I)V\":\n     *            return super~instance.firstMethod((String)arg[0], arg[1]);\n     *\n     *          default:\n     *            StringBuilder $local1 = new StringBuilder();\n     *            $local1.append(\"Method not found \");\n     *            $local1.append(name);\n     *            $local1.append(\" in \" $classType $super implementation\");\n     *            throw new $package/InstantReloadException($local1.toString());\n     *      }\n     * </code>\n     */\n    private void createAccessSuper() {\n\n        final Map<String, MethodReference> uniqueMethods = new HashMap<>();\n        if (parentNodes.isEmpty()) {\n            // if we cannot determine the parents for this class, let's blindly add all the\n            // method of the current class as a gateway to a possible parent version.\n            addAllNewMethods(classNode, classNode, uniqueMethods,null);\n        } else {\n            // otherwise, use the parent list.\n\n            for (ClassNode parentNode : parentNodes) {\n\n                addAllNewMethods(classNode, parentNode, uniqueMethods,supportAddCallSuper? null:visitSuperMethods);\n            }\n        }\n\n        if (uniqueMethods.size() == 0){\n            return;\n        }\n\n\n        int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC\n                | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_VARARGS;\n        Method m = new Method(\"ipc$super\", \"(L\" + visitedClassName\n                + \";Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;\");\n        MethodVisitor visitor = super.visitMethod(access,\n                m.getName(),\n                m.getDescriptor(),\n                null, null);\n\n        final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor);\n\n        // Gather all methods from itself and its superclasses to generate a giant access$super\n        // implementation.\n        // This will work fine as long as we don't support adding methods to a class.\n\n        new StringSwitch() {\n            @Override\n            void visitString() {\n                mv.visitVarInsn(Opcodes.ALOAD, 1);\n            }\n\n            @Override\n            void visitCase(String methodName) {\n                MethodReference methodRef = uniqueMethods.get(methodName);\n\n                mv.visitVarInsn(Opcodes.ALOAD, 0);\n\n                Type[] args = Type.getArgumentTypes(methodRef.method.desc);\n                int argc = 0;\n                for (Type t : args) {\n                    mv.visitVarInsn(Opcodes.ALOAD, 2);\n                    mv.push(argc);\n                    mv.visitInsn(Opcodes.AALOAD);\n                    ByteCodeUtils.unbox(mv, t);\n                    argc++;\n                }\n\n                if (TRACING_ENABLED) {\n                    trace(mv, \"super selected \", methodRef.owner.name,\n                            methodRef.method.name, methodRef.method.desc);\n                }\n                String parentName = findParentClassForMethod(methodRef);\n                logger.verbose(\n                        \"Generating ipc$super for %1$s recev %2$s\",\n                        methodRef.method.name,\n                        parentName);\n\n                // Call super on the other object, yup this works cos we are on the right place to\n                // call from.\n                mv.visitMethodInsn(Opcodes.INVOKESPECIAL,\n                        parentName,\n                        methodRef.method.name,\n                        methodRef.method.desc, false);\n\n                Type ret = Type.getReturnType(methodRef.method.desc);\n                if (ret.getSort() == Type.VOID) {\n                    mv.visitInsn(Opcodes.ACONST_NULL);\n                } else {\n                    mv.box(ret);\n                }\n                mv.visitInsn(Opcodes.ARETURN);\n            }\n\n            @Override\n            void visitDefault() {\n//                mv.visitInsn(Opcodes.RETURN);\n\n\n                writeMissingMessageWithHash(mv, visitedClassName);\n            }\n        }.visit(mv, uniqueMethods.keySet());\n\n        mv.visitMaxs(0, 0);\n        mv.visitEnd();\n    }\n\n    /***\n     * Inserts a trampoline to this class so that the updated methods can make calls to\n     * constructors.\n     *\n     * <p>\n     * Pseudo code for this trampoline:\n     * <code>\n     *   ClassName(Object[] args, Marker unused) {\n     *      String name = (String) args[0];\n     *      if (name.equals(\n     *          \"java/lang/ClassName.(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;\")) {\n     *        this((String)arg[1], arg[2]);\n     *        return\n     *      }\n     *      if (name.equals(\"SuperClassName.(Ljava/lang/String;I)V\")) {\n     *        super((String)arg[1], (int)arg[2]);\n     *        return;\n     *      }\n     *      ...\n     *      StringBuilder $local1 = new StringBuilder();\n     *      $local1.append(\"Method not found \");\n     *      $local1.append(name);\n     *      $local1.append(\" in \" $classType $super implementation\");\n     *      throw new $package/InstantReloadException($local1.toString());\n     *   }\n     * </code>\n     */\n    private void createDispatchingThis() {\n        // Gather all methods from itself and its superclasses to generate a giant constructor\n        // implementation.\n        // This will work fine as long as we don't support adding constructors to classes.\n        final Map<String, MethodNode> uniqueMethods = new HashMap<>();\n\n        addAllNewConstructors(uniqueMethods, classNode, true /*keepPrivateConstructors*/);\n        for (ClassNode parentNode : parentNodes) {\n            addAllNewConstructors(uniqueMethods, parentNode, false /*keepPrivateConstructors*/);\n        }\n\n        int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;\n\n        Method m = new Method(ByteCodeUtils.CONSTRUCTOR,\n                ALI_DISPATCHING_THIS_SIGNATURE);\n        MethodVisitor visitor = super.visitMethod(0, m.getName(), m.getDescriptor(), null, null);\n        final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor);\n\n        mv.visitCode();\n        // Mark this code as redirection code\n        Label label = new Label();\n        mv.visitLineNumber(0, label);\n\n        // Get and store the constructor canonical name.\n        mv.visitVarInsn(Opcodes.ALOAD, 1);\n        mv.push(1);\n        mv.visitInsn(Opcodes.AALOAD);\n        mv.unbox(Type.getType(\"Ljava/lang/String;\"));\n        final int constructorCanonicalName = mv.newLocal(Type.getType(\"Ljava/lang/String;\"));\n        mv.storeLocal(constructorCanonicalName);\n\n        new StringSwitch() {\n\n            @Override\n            void visitString() {\n                mv.loadLocal(constructorCanonicalName);\n            }\n\n            @Override\n            void visitCase(String canonicalName) {\n                MethodNode methodNode = uniqueMethods.get(canonicalName);\n                String owner = canonicalName.split(\"\\\\.\")[0];\n\n                // Parse method arguments and\n                mv.visitVarInsn(Opcodes.ALOAD, 0);\n                Type[] args = Type.getArgumentTypes(methodNode.desc);\n                int argc = 1;\n                for (Type t : args) {\n                    mv.visitVarInsn(Opcodes.ALOAD, 1);\n                    mv.push(argc + 1);\n                    mv.visitInsn(Opcodes.AALOAD);\n                    ByteCodeUtils.unbox(mv, t);\n                    argc++;\n                }\n\n                mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, ByteCodeUtils.CONSTRUCTOR,\n                        methodNode.desc, false);\n\n                mv.visitInsn(Opcodes.RETURN);\n            }\n\n            @Override\n            void visitDefault() {\n//                mv.visitInsn(Opcodes.RETURN);\n                writeMissingMessageWithHash(mv, visitedClassName);\n            }\n\n            @Override\n            void visit(GeneratorAdapter mv, Set<String> strings) {\n                super.visit(mv, strings);\n\n            }\n        }.visit(mv, uniqueMethods.keySet());\n\n        mv.visitMaxs(1, 3);\n        mv.visitEnd();\n    }\n\n    @Override\n    public void visitEnd() {\n        if (!visitedSuperName.equals(\"java/lang/Object\")) {\n            createAccessSuper();\n        }\n        if (patchInitMethod) {\n            createDispatchingThis();\n        }\n        super.visitEnd();\n    }\n\n    /**\n     * Find a suitable parent for a method reference. The method owner is not always a valid\n     * parent to dispatch to. For instance, take the following example :\n     * <code>\n     * package a;\n     * public class A {\n     * public void publicMethod();\n     * }\n     * <p>\n     * package a;\n     * class B extends A {\n     * public void publicMethod();\n     * }\n     * <p>\n     * package b;\n     * public class C extends B {\n     * ...\n     * }\n     * </code>\n     * when instrumenting C, the first method reference for \"publicMethod\" is on class B which we\n     * cannot invoke directly since it's present on a private package B which is not located in the\n     * same package as C. However C can still call the \"publicMethod\" since it's defined on A which\n     * is a public class.\n     * <p>\n     * We cannot just blindly take the top most definition of \"publicMethod\" hoping this is the\n     * accessible one since you can very well do :\n     * <code>\n     * package a;\n     * class A {\n     * public void publicMethod();\n     * }\n     * <p>\n     * package a;\n     * public class B extends A {\n     * public void publicMethod();\n     * }\n     * <p>\n     * package b;\n     * public class C extends B {\n     * ...\n     * }\n     * </code>\n     * <p>\n     * In that case, the top most parent class is the one defined the unaccessible method reference.\n     * <p>\n     * Therefore, the solution is to walk up the hierarchy until we find the same method defined on\n     * an accessible class, if we cannot find such a method, the suitable parent is the parent class\n     * of the visited class which is legal (but might consume a DEX id).\n     *\n     * @param methodReference the method reference to find a suitable parent for.\n     * @return the parent class name\n     */\n    @NonNull\n    String findParentClassForMethod(@NonNull MethodReference methodReference) {\n        logger.verbose(\n                \"MethodRef %1$s access(%2$s) -> owner %3$s access(%4$s)\",\n                methodReference.method.name, methodReference.method.access,\n                methodReference.owner.name, methodReference.owner.access);\n        // if the method owner class is accessible from the visited class, just use that.\n        if (isParentClassVisible(methodReference.owner, classNode)) {\n            return methodReference.owner.name;\n        }\n        logger.verbose(\"Found an inaccessible methodReference %1$s\", methodReference.method.name);\n        // walk up the hierarchy, starting at the method reference owner.\n        Iterator<ClassNode> parentIterator = parentNodes.iterator();\n        ClassNode parent = parentIterator.next();\n        while (!parent.name.equals(methodReference.owner.name)\n                && parentIterator.hasNext()) {\n            parent = parentIterator.next();\n        }\n        while (parentIterator.hasNext()) {\n            ClassNode node = parentIterator.next();\n            // check that this parent is visible, there might be several layers of package\n            // private classes.\n            if (isParentClassVisible(node, classNode)) {\n                //noinspection unchecked: ASM API\n                for (MethodNode methodNode : (List<MethodNode>) node.methods) {\n                    // do not reference bridge methods, they might not be translated into dex, or\n                    // might disappear in the next javac compiler for that use case.\n                    if (methodNode.name.equals(methodReference.method.name)\n                            && methodNode.desc.equals(methodReference.method.desc)\n                            && (methodNode.access\n                            & (Opcodes.ACC_BRIDGE | Opcodes.ACC_ABSTRACT)) == 0) {\n                        logger.verbose(\n                                \"Using class %1$s for dispatching %2$s:%3$s\",\n                                node.name,\n                                methodReference.method.name,\n                                methodReference.method.desc);\n                        return node.name;\n                    }\n                }\n            }\n        }\n        logger.verbose(\"Using immediate parent for dispatching %1$s\", methodReference.method.desc);\n        return classNode.superName;\n    }\n\n    private static boolean isParentClassVisible(@NonNull ClassNode parent,\n                                                @NonNull ClassNode child) {\n\n        return ((parent.access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) != 0 ||\n                com.google.common.base.Objects.equal(ByteCodeUtils.getPackageName(parent.name),\n                        ByteCodeUtils.getPackageName(child.name)));\n    }\n\n    /**\n     * Add all unseen methods from the passed ClassNode's methods.\n     *\n     * @param instrumentedClass class that is being visited\n     * @param superClass        the class to save all new methods from\n     * @param methods           the methods already encountered in the ClassNode hierarchy\n     * @param visitSuperMethods\n     * @see ClassNode#methods\n     */\n    public static void addAllNewMethods(\n            ClassNode instrumentedClass,\n            ClassNode superClass,\n            Map<String, MethodReference> methods, List<String> visitSuperMethods) {\n\n        //noinspection unchecked\n        if (superClass.name.equals(\"java/lang/Object\")){\n            return;\n        }\n        for (MethodNode method : (List<MethodNode>) superClass.methods) {\n            if (method.name.equals(ByteCodeUtils.CONSTRUCTOR) || method.name.equals(ByteCodeUtils.CLASS_INITIALIZER)) {\n                continue;\n            }\n            String name = method.name + \".\" + method.desc;\n            if (isAccessCompatibleWithInstantRun(method.access)\n                    && !methods.containsKey(name)\n                    && (method.access & Opcodes.ACC_STATIC) == 0\n                    && isCallableFromSubclass(method, superClass, instrumentedClass)\n                    ) {\n                if (visitSuperMethods == null){\n                    methods.put(name, new MethodReference(method, superClass));\n                }else if (visitSuperMethods.contains(name)) {\n                    methods.put(name, new MethodReference(method, superClass));\n                }\n            }\n        }\n    }\n\n    @SuppressWarnings(\"SimplifiableIfStatement\")\n    private static boolean isCallableFromSubclass(\n            @NonNull MethodNode method,\n            @NonNull ClassNode superClass,\n            @NonNull ClassNode subclass) {\n        if ((method.access & Opcodes.ACC_PRIVATE) != 0) {\n            return false;\n        } else if ((method.access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) != 0) {\n            return true;\n        } else {\n            // \"package private\" access modifier.\n            return Objects.equal(\n                    ByteCodeUtils.getPackageName(superClass.name),\n                    ByteCodeUtils.getPackageName(subclass.name));\n        }\n    }\n\n    /**\n     * Add all constructors from the passed ClassNode's methods. {@see ClassNode#methods}\n     *\n     * @param methods                 the constructors already encountered in the ClassNode hierarchy\n     * @param classNode               the class to save all new methods from.\n     * @param keepPrivateConstructors whether to keep the private constructors.\n     */\n    private void addAllNewConstructors(Map<String, MethodNode> methods, ClassNode classNode,\n                                       boolean keepPrivateConstructors) {\n        //noinspection unchecked\n        for (MethodNode method : (List<MethodNode>) classNode.methods) {\n            if (!method.name.equals(ByteCodeUtils.CONSTRUCTOR)) {\n                continue;\n            }\n\n            if (!isAccessCompatibleWithInstantRun(method.access)) {\n                continue;\n            }\n\n            if (!keepPrivateConstructors && (method.access & Opcodes.ACC_PRIVATE) != 0) {\n                continue;\n            }\n            if (!classNode.name.equals(visitedClassName)\n                    && !classNode.name.equals(visitedSuperName)) {\n                continue;\n            }\n            String key = classNode.name + \".\" + method.desc;\n            if (methods.containsKey(key)) {\n                continue;\n            }\n            methods.put(key, method);\n        }\n    }\n\n\n    private static final class TBVisitorBuilder implements IncrementalVisitor.VisitorBuilder {\n\n        private TBVisitorBuilder() {\n        }\n\n        @NonNull\n        @Override\n        public IncrementalVisitor build(\n                @NonNull ClassNode classNode,\n                @NonNull List<ClassNode> parentNodes,\n                @NonNull ClassVisitor classVisitor,\n                @NonNull ILogger logger) {\n            return new TBIncrementalSupportVisitor(classNode, parentNodes, classVisitor, logger);\n        }\n\n        @Override\n        @NonNull\n        public String getMangledRelativeClassFilePath(@NonNull String originalClassFilePath) {\n            return originalClassFilePath;\n        }\n\n        @NonNull\n        @Override\n        public OutputType getOutputType() {\n            return OutputType.INSTRUMENT;\n        }\n    }\n\n    @NonNull\n    public static final IncrementalVisitor.VisitorBuilder VISITOR_BUILDER = new TBIncrementalSupportVisitor.TBVisitorBuilder();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/incremental/TBIncrementalVisitor.java",
    "content": "package com.android.build.gradle.internal.incremental;\n\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.annotations.VisibleForTesting;\nimport com.android.utils.FileUtils;\nimport com.android.utils.ILogger;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.io.Files;\nimport com.taobao.android.builder.insant.matcher.Imatcher;\nimport com.taobao.android.builder.insant.matcher.ImplementsMatcher;\nimport com.taobao.android.builder.insant.matcher.MatcherCreator;\nimport org.objectweb.asm.*;\nimport org.objectweb.asm.commons.SerialVersionUIDAdder;\nimport org.objectweb.asm.tree.AnnotationNode;\nimport org.objectweb.asm.tree.ClassNode;\nimport org.objectweb.asm.tree.MethodNode;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\n\n/**\n * 创建日期：2018/11/6 on 下午7:41\n * 描述:\n * 作者:zhayu.ll\n */\npublic class TBIncrementalVisitor extends IncrementalVisitor {\n\n    public TBIncrementalVisitor(ClassNode classNode, List<ClassNode> parentNodes, ClassVisitor classVisitor, ILogger logger) {\n        super(classNode, parentNodes, classVisitor, logger);\n    }\n\n    public interface InjectErrorListener {\n\n        void onError(ErrorType errorType);\n\n    }\n\n    public static final String ALI_RUNTIME_PACKAGE = \"com/android/alibaba/ip/runtime\";\n    public static final String ALI_ABSTRACT_PATCHES_LOADER_IMPL =\n            ALI_RUNTIME_PACKAGE + \"/AbstractPatchesLoaderImpl\";\n    public static final String ALI_APP_PATCHES_LOADER_IMPL = ALI_RUNTIME_PACKAGE + \"/AppPatchesLoaderImpl\";\n\n\n    protected static final Type ALI_INSTANT_RELOAD_EXCEPTION =\n            Type.getObjectType(ALI_RUNTIME_PACKAGE + \"/InstantReloadException\");\n\n    public static final String ALI_DISPATCHING_THIS_SIGNATURE =\n            \"([Ljava/lang/Object;\"\n                    + ALI_INSTANT_RELOAD_EXCEPTION.getDescriptor() + \")V\";\n\n    protected static final Type ALI_RUNTIME_TYPE =\n            Type.getObjectType(ALI_RUNTIME_PACKAGE + \"/AndroidInstantRuntime\");\n    public static final Type ALI_DISABLE_ANNOTATION_TYPE =\n            Type.getObjectType(\"com/android/alibaba/ip/api/DisableInstantRun\");\n    public static final Type TARGET_API_TYPE =\n            Type.getObjectType(\"android/annotation/TargetApi\");\n\n    protected static final boolean TRACING_ENABLED = Boolean.getBoolean(\"FDR_TRACING\");\n\n    public static final Type ALI_CHANGE_TYPE = Type.getObjectType(ALI_RUNTIME_PACKAGE + \"/IpChange\");\n\n\n    public static final Type ADD_CLASS =\n            Type.getObjectType(\"com/android/alibaba/ip/api/AddClass\");\n\n    public static final Type MODIFY_CLASS =\n            Type.getObjectType(\"com/android/alibaba/ip/api/ModifyClass\");\n\n    public static final Type MODIFY_FIELD =\n            Type.getObjectType(\"com/android/alibaba/ip/api/ModifyField\");\n\n    public static final Type MODIFY_METHOD =\n            Type.getObjectType(\"com/android/alibaba/ip/api/ModifyMethod\");\n\n    public static final Type ADD_FIELD =\n            Type.getObjectType(\"com/android/alibaba/ip/api/AddField\");\n\n\n    public static final Type ADD_METHOD =\n            Type.getObjectType(\"com/android/alibaba/ip/api/AddMethod\");\n\n\n    public enum ErrorType {\n        R_CLASS, INTERFACE, NEW_API, PACKAGE_DISABLED, NO_METHOD, SUB_EXCEEDED, IMPLEMENTS\n    }\n\n    @Nullable\n    public static File instrumentClass(\n            int targetApiLevel,\n            @NonNull File inputRootDirectory,\n            @NonNull File inputFile,\n            @NonNull File outputDirectory,\n            @NonNull VisitorBuilder visitorBuilder,\n            @NonNull ILogger logger,\n            InjectErrorListener injectErrorListener,\n            boolean addSerialVersionUID, boolean patchInitMethod, boolean patchEachMethod,boolean supportAddCallSuper,int count) throws IOException {\n\n        byte[] classBytes;\n        String path = FileUtils.relativePath(inputFile, inputRootDirectory);\n\n        // if the class is not eligible for IR, return the non instrumented version or null if\n        // the override class is requested.\n        if (!isClassEligibleForInstantRun(inputFile)) {\n            if (injectErrorListener != null) {\n                injectErrorListener.onError(ErrorType.R_CLASS);\n            }\n            if (visitorBuilder.getOutputType() == OutputType.INSTRUMENT) {\n                File outputFile = new File(outputDirectory, path);\n                Files.createParentDirs(outputFile);\n                Files.copy(inputFile, outputFile);\n                return outputFile;\n            } else {\n                return null;\n            }\n        }\n        classBytes = Files.toByteArray(inputFile);\n        ClassReader classReader = new ClassReader(classBytes);\n        // override the getCommonSuperClass to use the thread context class loader instead of\n        // the system classloader. This is useful as ASM needs to load classes from the project\n        // which the system classloader does not have visibility upon.\n        // TODO: investigate if there is not a simpler way than overriding.\n        ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_FRAMES) {\n            @Override\n            protected String getCommonSuperClass(final String type1, final String type2) {\n                Class<?> c, d;\n                ClassLoader classLoader = Thread.currentThread().getContextClassLoader();\n                try {\n                    c = Class.forName(type1.replace('/', '.'), false, classLoader);\n                    d = Class.forName(type2.replace('/', '.'), false, classLoader);\n                } catch (ClassNotFoundException e) {\n                    // This may happen if we're processing class files which reference APIs not\n                    // available on the target device. In this case return a dummy value, since this\n                    // is ignored during dx compilation.\n                    System.err.println(\"can not find superClass:\"+type1 +\" or \"+type2);\n                    return \"instant/run/NoCommonSuperClass\";\n                } catch (Throwable e) {\n                    throw new RuntimeException(type1+\":\"+type2,e);\n                }\n                if (c.isAssignableFrom(d)) {\n                    return type1;\n                }\n                if (d.isAssignableFrom(c)) {\n                    return type2;\n                }\n                if (c.isInterface() || d.isInterface()) {\n                    return \"java/lang/Object\";\n                } else {\n                    do {\n                        c = c.getSuperclass();\n                    } while (!c.isAssignableFrom(d));\n                    return c.getName().replace('.', '/');\n                }\n            }\n        };\n\n        ClassNode classNode = AsmUtils.readClass(classReader);\n\n        boolean hasOtherMethod = false;\n        if (classNode != null && classNode.methods != null) {\n            for (Object methodNode : classNode.methods) {\n                if (methodNode instanceof MethodNode) {\n                    if (!((MethodNode) methodNode).name.equals(ByteCodeUtils.CLASS_INITIALIZER) && !((MethodNode) methodNode).name.equals(ByteCodeUtils.CONSTRUCTOR)) {\n                        hasOtherMethod = true;\n                    }\n                }\n            }\n        }\n\n\n        // when dealing with interface, we just copy the inputFile over without any changes unless\n        // this is a package private interface.\n        AccessRight accessRight = AccessRight.fromNodeAccess(classNode.access);\n        File outputFile = new File(outputDirectory, path);\n\n        if (!hasOtherMethod) {\n            if (visitorBuilder.getOutputType() == OutputType.INSTRUMENT) {\n                Files.createParentDirs(outputFile);\n                Files.write(classBytes, outputFile);\n                return outputFile;\n            } else {\n                return null;\n            }\n\n        }\n\n        if ((classNode.access & Opcodes.ACC_INTERFACE) != 0) {\n            if (visitorBuilder.getOutputType() == OutputType.INSTRUMENT) {\n                // don't change the name of interfaces.\n                if (injectErrorListener != null) {\n                    injectErrorListener.onError(ErrorType.INTERFACE);\n                }\n                Files.createParentDirs(outputFile);\n                if (accessRight == AccessRight.PACKAGE_PRIVATE) {\n                    classNode.access = classNode.access | Opcodes.ACC_PUBLIC;\n                    classNode.accept(classWriter);\n                    Files.write(classWriter.toByteArray(), outputFile);\n                } else {\n                    // just copy the input file over, no change.\n                    Files.write(classBytes, outputFile);\n                }\n                return outputFile;\n            } else {\n                return null;\n            }\n        }\n\n        Class<?> c, d;\n        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();\n        try {\n            c = Class.forName(classNode.name.replace('/', '.'), false, classLoader);\n            for (Imatcher imatcher: MatcherCreator.getMatchers()){\n                d = ((ImplementsMatcher)imatcher).getClazz(classLoader);\n                if (d.isAssignableFrom(c)){\n                    if (visitorBuilder.getOutputType() == OutputType.INSTRUMENT) {\n                        // don't change the name of interfaces.\n                        if (injectErrorListener != null) {\n                            injectErrorListener.onError(ErrorType.IMPLEMENTS);\n                        }\n                        Files.createParentDirs(outputFile);\n\n                        // just copy the input file over, no change.\n                        Files.write(classBytes, outputFile);\n                        return outputFile;\n                    } else {\n                        return null;\n                    }\n                }\n\n            }\n\n        }catch (Throwable e){\n            e.printStackTrace();\n        }\n\n\n\n        AsmUtils.DirectoryBasedClassReader directoryClassReader =\n                new AsmUtils.DirectoryBasedClassReader(getBinaryFolder(inputFile, classNode));\n\n        // if we are targeting a more recent version than the current device, disable instant run\n        // for that class.\n        List<ClassNode> parentsNodes =\n                isClassTargetingNewerPlatform(\n                        targetApiLevel, TARGET_API_TYPE, directoryClassReader, classNode, logger)\n                        ? ImmutableList.of()\n                        : AsmUtils.parseParents(\n                        logger, directoryClassReader, classNode, targetApiLevel);\n        // if we could not determine the parent hierarchy, disable instant run.\n        if (parentsNodes.isEmpty() || isPackageInstantRunDisabled(inputFile)) {\n            if (visitorBuilder.getOutputType() == OutputType.INSTRUMENT) {\n                if (injectErrorListener != null) {\n                    if (parentsNodes.isEmpty()) {\n                        injectErrorListener.onError(ErrorType.NEW_API);\n                    } else {\n                        injectErrorListener.onError(ErrorType.PACKAGE_DISABLED);\n                    }\n                }\n                Files.createParentDirs(outputFile);\n                Files.write(classBytes, outputFile);\n                return outputFile;\n            } else {\n                return null;\n            }\n        }\n\n//        Map<String, TBIncrementalSupportVisitor.MethodReference> methods = new HashMap<>();\n//        for (ClassNode pN : parentsNodes) {\n//            TBIncrementalSupportVisitor.addAllNewMethods(classNode,pN,methods, null);\n//        }\n//        if (methods.size() > count) {\n//            if (visitorBuilder.getOutputType() == OutputType.INSTRUMENT) {\n//                if (injectErrorListener != null) {\n//                    injectErrorListener.onError(ErrorType.SUB_EXCEEDED);\n//                }\n//                Files.createParentDirs(outputFile);\n//                Files.write(classBytes, outputFile);\n//                return outputFile;\n//            } else {\n//                return null;\n//            }\n//        }\n\n        outputFile = new File(outputDirectory, visitorBuilder.getMangledRelativeClassFilePath(path));\n        Files.createParentDirs(outputFile);\n        IncrementalVisitor visitor =\n                visitorBuilder.build(classNode, parentsNodes, classWriter, logger);\n        if (visitor instanceof TBIncrementalSupportVisitor) {\n            ((TBIncrementalSupportVisitor) visitor).setPatchInitMethod(patchInitMethod);\n            ((TBIncrementalSupportVisitor) visitor).setSupportEachMethod(patchEachMethod);\n            ((TBIncrementalSupportVisitor) visitor).setSupportAddCallSuper(supportAddCallSuper);\n\n        }\n\n        if (visitorBuilder.getOutputType() == OutputType.INSTRUMENT) {\n            /*\n             * Classes that do not have a serial version unique identifier, will be updated to\n             * contain one. This is accomplished by using the {@link SerialVersionUIDAdder} class\n             * visitor that is added when this visitor is created (see the constructor). This way,\n             * the serialVersionUID is the same for instrumented and non-instrumented classes. All\n             * classes will have a serialVersionUID, so if some of the classes that is extended\n             * starts implementing {@link java.io.Serializable}, serialization and deserialization\n             * will continue to work correctly.\n             */\n            if (addSerialVersionUID) {\n                classNode.accept(new SerialVersionUIDAdder(visitor));\n            } else {\n                classNode.accept(visitor);\n            }\n        } else {\n            classNode.accept(visitor);\n        }\n\n        Files.write(classWriter.toByteArray(), outputFile);\n        return outputFile;\n    }\n\n\n    @VisibleForTesting\n    public static boolean isClassEligibleForInstantRun(@NonNull File inputFile) {\n\n        if (inputFile.getPath().endsWith(SdkConstants.DOT_CLASS)) {\n            String fileName = inputFile.getName();\n            return !fileName.equals(\"R\" + SdkConstants.DOT_CLASS) && !fileName.startsWith(\"R$\");\n        } else {\n            return false;\n        }\n    }\n\n    protected enum AccessRight {\n\n        PRIVATE, PACKAGE_PRIVATE, PROTECTED, PUBLIC;\n\n        @NonNull\n        public static TBIncrementalVisitor.AccessRight fromNodeAccess(int nodeAccess) {\n            if ((nodeAccess & Opcodes.ACC_PRIVATE) != 0) return PRIVATE;\n            if ((nodeAccess & Opcodes.ACC_PROTECTED) != 0) return PROTECTED;\n            if ((nodeAccess & Opcodes.ACC_PUBLIC) != 0) return PUBLIC;\n            return PACKAGE_PRIVATE;\n        }\n    }\n\n    @NonNull\n    private static File getBinaryFolder(@NonNull File inputFile, @NonNull ClassNode classNode) {\n        return new File(inputFile.getAbsolutePath().substring(0,\n                inputFile.getAbsolutePath().length() - (classNode.name.length() + \".class\".length())));\n    }\n\n    @VisibleForTesting\n    static boolean isClassTargetingNewerPlatform(\n            int targetApiLevel,\n            @NonNull Type targetApiAnnotationType,\n            @NonNull AsmUtils.ClassReaderProvider locator,\n            @NonNull ClassNode classNode,\n            @NonNull ILogger logger) throws IOException {\n\n        List<AnnotationNode> invisibleAnnotations =\n                AsmUtils.getInvisibleAnnotationsOnClassOrOuterClasses(locator, classNode, logger);\n        for (AnnotationNode classAnnotation : invisibleAnnotations) {\n            if (classAnnotation.desc.equals(targetApiAnnotationType.getDescriptor())) {\n                int valueIndex = 0;\n                List values = classAnnotation.values;\n                while (valueIndex < values.size()) {\n                    String name = (String) values.get(valueIndex);\n                    if (name.equals(\"value\")) {\n                        Object value = values.get(valueIndex + 1);\n                        return Integer.class.cast(value) > targetApiLevel;\n                    }\n                    valueIndex = valueIndex + 2;\n                }\n            }\n        }\n        return false;\n    }\n\n    private static boolean isPackageInstantRunDisabled(@NonNull File inputFile) throws IOException {\n\n        ClassNode packageInfoClass = AsmUtils.parsePackageInfo(inputFile);\n        if (packageInfoClass != null) {\n            //noinspection unchecked\n            List<AnnotationNode> annotations = packageInfoClass.invisibleAnnotations;\n            if (annotations == null) {\n                return false;\n            }\n            for (AnnotationNode annotation : annotations) {\n                if (annotation.desc.equals(DISABLE_ANNOTATION_TYPE.getDescriptor())) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/incremental/TBMethodRedirection.java",
    "content": "package com.android.build.gradle.internal.incremental;\n\nimport org.objectweb.asm.Type;\nimport org.objectweb.asm.commons.GeneratorAdapter;\nimport org.objectweb.asm.commons.Method;\nimport org.objectweb.asm.tree.LabelNode;\n\nimport java.util.List;\n\n/**\n * 创建日期：2019/1/5 on 上午11:12\n * 描述:\n * 作者:zhayu.ll\n */\npublic class TBMethodRedirection extends MethodRedirection {\n    private String name;\n\n    TBMethodRedirection(LabelNode label, String name, List<Type> types, Type type) {\n        super(label, name, types, type);\n        this.name = name;\n    }\n\n    @Override\n    protected void doRedirect(GeneratorAdapter mv, int change) {\n        // Push the three arguments\n        mv.loadLocal(change);\n        mv.push(name);\n        ByteCodeUtils.newVariableArray(mv, ByteCodeUtils.toLocalVariables(types));\n\n        // now invoke the generic dispatch method.\n        mv.invokeInterface(TBIncrementalSupportVisitor.ALI_CHANGE_TYPE, Method.getMethod(\"Object ipc$dispatch(String, Object[])\"));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/pipeline/AtlasExtendedContentType.java",
    "content": "package com.android.build.gradle.internal.pipeline;\n\nimport com.android.build.api.transform.QualifiedContent.ContentType;\nimport com.android.build.api.transform.QualifiedContent.DefaultContentType;\nimport com.google.common.collect.ImmutableSet;\n\nimport java.util.Set;\n\n/**\n * Content types private to theAtlas Android Plugin.\n */\npublic enum AtlasExtendedContentType implements ContentType {\n\n    // /**\n    //  * The content is dex files.\n    //  */\n    // DEX(0x1000),\n    //\n    // /**\n    //  * Content is a native library.\n    //  */\n    // NATIVE_LIBS(0x2000),\n    //\n    // /**\n    //  * Instant Run '$override' classes, which contain code of new method bodies.\n    //  *\n    //  * <p>This stream also contains the AbstractPatchesLoaderImpl class for applying HotSwap\n    //  * changes.\n    //  */\n    // CLASSES_ENHANCED(0x4000),\n    //\n    // /**\n    //  * The content is Jack library.\n    //  *\n    //  * This is zip file containing classes in jayce format.\n    //  * If the library has been pre-dexed it will also contain the corresponding dex.\n    //  */\n    // JACK(0x8000),\n\n    AWB_CLASSES(0x03),\n\n    AWB_RESOURCES(0x04),\n\n    AWB_APKS(0x1000000);\n\n    /**\n     * The content is an artifact exported by the data binding compiler.\n     */\n\n    private final int value;\n\n    AtlasExtendedContentType(int value) {\n        this.value = value;\n    }\n\n    @Override\n    public int getValue() {\n        return value;\n    }\n\n    /**\n     * Returns all {@link DefaultContentType} and {@link AtlasExtendedContentType} content types.\n     *\n     * @return a set of all known {@link ContentType}\n     */\n    public static Set<ContentType> getAllContentTypes() {\n        return allContentTypes;\n    }\n\n    private static final Set<ContentType> allContentTypes;\n\n    static {\n        ImmutableSet.Builder<ContentType> builder = ImmutableSet.builder();\n        for (DefaultContentType contentType : DefaultContentType.values()) {\n            builder.add(contentType);\n        }\n        for (AtlasExtendedContentType extendedContentType : AtlasExtendedContentType.values()) {\n            builder.add(extendedContentType);\n        }\n        allContentTypes = builder.build();\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/pipeline/AtlasIncrementalFileMergeTransformUtils.java",
    "content": "package com.android.build.gradle.internal.pipeline;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.apkzlib.utils.CachedSupplier;\nimport com.android.apkzlib.utils.IOExceptionRunnable;\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.builder.files.FileCacheByPath;\nimport com.android.builder.files.IncrementalRelativeFileSets;\nimport com.android.builder.files.RelativeFile;\nimport com.android.builder.files.RelativeFiles;\nimport com.android.builder.merge.IncrementalFileMergerInput;\nimport com.android.builder.merge.LazyIncrementalFileMergerInput;\nimport com.android.builder.merge.LazyIncrementalFileMergerInputs;\nimport com.android.ide.common.res2.FileStatus;\nimport com.google.common.base.Preconditions;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.UncheckedIOException;\nimport java.util.*;\n\n/**\n * @author lilong\n * @create 2017-12-20 下午1:08\n */\npublic class AtlasIncrementalFileMergeTransformUtils {\n\n    private AtlasIncrementalFileMergeTransformUtils() {}\n\n    /**\n     * Creates an {@link IncrementalFileMergerInput} from a {@link JarInput}. All files in the jar\n     * will be reported in the incremental input. This method assumes the input contains\n     * incremental information.\n     *\n     * @param jarInput the jar input\n     * @param zipCache the zip cache; the cache will not be modified\n     * @param cacheUpdate will receive actions to update the cache for the next iteration\n     * @param contentMap if not {@code null}, receives a mapping from all generated inputs to\n     * {@link QualifiedContent} they came from\n     * @return the input\n     */\n    @NonNull\n    public static IncrementalFileMergerInput toIncrementalInput(\n            @NonNull JarInput jarInput,\n            @NonNull FileCacheByPath zipCache,\n            @NonNull List<Runnable> cacheUpdate,\n            @Nullable Map<IncrementalFileMergerInput, QualifiedContent> contentMap) {\n        File jarFile = jarInput.getFile();\n        if (jarFile.isFile()) {\n            cacheUpdate.add(IOExceptionRunnable.asRunnable(() -> zipCache.add(jarFile)));\n        } else {\n            cacheUpdate.add(IOExceptionRunnable.asRunnable(() -> zipCache.remove(jarFile)));\n        }\n\n        IncrementalFileMergerInput input =\n                new LazyIncrementalFileMergerInput(\n                        jarFile.getAbsolutePath(),\n                        new CachedSupplier<>(() -> computeUpdates(jarInput, zipCache)),\n                        new CachedSupplier<>(() -> computeFiles(jarInput)));\n        if (contentMap != null) {\n            contentMap.put(input, jarInput);\n        }\n\n        return input;\n    }\n\n    /**\n     * Creates an {@link IncrementalFileMergerInput} from a {@link DirectoryInput}. All files in the\n     * directory will be reported in the incremental input. This method assumes the input contains\n     * incremental information.\n     *\n     * @param directoryInput the directory input\n     * @param contentMap if not {@code null}, receives a mapping from all generated inputs to\n     * {@link QualifiedContent} they came from\n     * @return the input\n     */\n    @NonNull\n    public static IncrementalFileMergerInput toIncrementalInput(\n            @NonNull DirectoryInput directoryInput,\n            @Nullable Map<IncrementalFileMergerInput, QualifiedContent> contentMap) {\n        IncrementalFileMergerInput input =\n                new LazyIncrementalFileMergerInput(\n                        directoryInput.getFile().getAbsolutePath(),\n                        new CachedSupplier<>(() -> computeUpdates(directoryInput)),\n                        new CachedSupplier<>(() -> computeFiles(directoryInput)));\n\n        if (contentMap != null) {\n            contentMap.put(input, directoryInput);\n        }\n\n        return input;\n    }\n\n    /**\n     * Creates an {@link IncrementalFileMergerInput} from a {@link JarInput}. All files in\n     * the zip will be reported in the incremental input. This method assumes the input does not\n     * contain incremental information. All files will be reported as new.\n     *\n     * @param jarInput the jar input\n     * @param zipCache the zip cache; the cache will not be modified\n     * @param cacheUpdate will receive actions to update the cache for the next iteration\n     * @param contentMap if not {@code null}, receives a mapping from all generated inputs to\n     * {@link QualifiedContent} they came from\n     * @return the input or {@code null} if the jar input does not exist\n     */\n    @Nullable\n    public static IncrementalFileMergerInput toNonIncrementalInput(\n            @NonNull JarInput jarInput,\n            @NonNull FileCacheByPath zipCache,\n            @NonNull List<Runnable> cacheUpdate,\n            @Nullable Map<IncrementalFileMergerInput, QualifiedContent> contentMap) {\n        File jarFile = jarInput.getFile();\n        if (!jarFile.isFile()) {\n            return null;\n        }\n\n        cacheUpdate.add(IOExceptionRunnable.asRunnable(() -> zipCache.add(jarFile)));\n\n        IncrementalFileMergerInput input =\n                LazyIncrementalFileMergerInputs.fromNew(\n                        jarFile.getAbsolutePath(),\n                        ImmutableSet.of(jarFile));\n        if (contentMap != null) {\n            contentMap.put(input, jarInput);\n        }\n\n        return input;\n    }\n\n    /**\n     * Creates an {@link IncrementalFileMergerInput} from a {@link DirectoryInput}. All files in\n     * the directory will be reported in the incremental input. This method assumes the input does\n     * not contain incremental information. All files will be reported as new.\n     *\n     * @param directoryInput the directory input\n     * @param contentMap if not {@code null}, receives a mapping from all generated inputs to\n     * {@link QualifiedContent} they came from\n     * @return the input or {@code null} if the jar input does not exist\n     */\n    @Nullable\n    public static IncrementalFileMergerInput toNonIncrementalInput(\n            @NonNull DirectoryInput directoryInput,\n            @Nullable Map<IncrementalFileMergerInput, QualifiedContent> contentMap) {\n        File dirFile = directoryInput.getFile();\n        if (!dirFile.isDirectory()) {\n            return null;\n        }\n\n        IncrementalFileMergerInput input =\n                LazyIncrementalFileMergerInputs.fromNew(\n                        dirFile.getAbsolutePath(),\n                        ImmutableSet.of(dirFile));\n\n        if (contentMap != null) {\n            contentMap.put(input, directoryInput);\n        }\n\n        return input;\n    }\n\n    /**\n     * Computes all updates in a {@link JarInput}.\n     *\n     * @param jarInput the jar input\n     * @param zipCache the cache of zip files; the cache will not be modified\n     * @return a mapping from all files that have changed to the type of change\n     */\n    @NonNull\n    private static ImmutableMap<RelativeFile, FileStatus> computeUpdates(\n            @NonNull JarInput jarInput,\n            @NonNull FileCacheByPath zipCache) {\n        try {\n            switch (jarInput.getStatus()) {\n                case ADDED:\n                    return IncrementalRelativeFileSets.fromZip(\n                            jarInput.getFile(),\n                            FileStatus.NEW);\n                case REMOVED:\n                    File cached = zipCache.get(jarInput.getFile());\n                    if (cached == null) {\n                        throw new RuntimeException(\"File '\" + jarInput.getFile() + \"' was \"\n                                + \"deleted, but previous version not found in cache\");\n                    }\n\n                    return IncrementalRelativeFileSets.fromZip(cached, FileStatus.REMOVED);\n                case CHANGED:\n                    return IncrementalRelativeFileSets.fromZip(\n                            jarInput.getFile(),\n                            zipCache,\n                            new HashSet<>());\n                case NOTCHANGED:\n                    return ImmutableMap.of();\n                default:\n                    throw new AssertionError();\n            }\n        } catch (IOException e) {\n            throw new UncheckedIOException(e);\n        }\n    }\n\n    /**\n     * Computes a set with all files in a {@link JarInput}.\n     *\n     * @param jarInput the jar input\n     * @return all files in the input\n     */\n    @NonNull\n    private static ImmutableSet<RelativeFile> computeFiles(@NonNull JarInput jarInput) {\n        File jar = jarInput.getFile();\n        assert jar.isFile();\n\n        try {\n            return RelativeFiles.fromZip(jar);\n        } catch (IOException e) {\n            throw new UncheckedIOException(e);\n        }\n    }\n\n\n    /**\n     * Computes all updates in a {@link DirectoryInput}.\n     *\n     * @param directoryInput the directory input\n     * @return a mapping from all files that have changed to the type of change\n     */\n    @NonNull\n    private static ImmutableMap<RelativeFile, FileStatus> computeUpdates(\n            @NonNull DirectoryInput directoryInput) {\n        ImmutableMap.Builder<RelativeFile, FileStatus> builder = ImmutableMap.builder();\n\n        Map<File, Status> changedFiles = directoryInput.getChangedFiles();\n        for (Map.Entry<File, Status> changedFile : changedFiles.entrySet()) {\n            RelativeFile rf = new RelativeFile(directoryInput.getFile(), changedFile.getKey());\n            FileStatus status = mapStatus(changedFile.getValue());\n            if (status != null && !(new File(rf.getBase(), rf.getRelativePath()).isDirectory())) {\n                builder.put(rf, status);\n            }\n        }\n\n        return builder.build();\n    }\n\n    /**\n     * Computes a set with all files in a {@link DirectoryInput}.\n     *\n     * @param directoryInput the directory input\n     * @return all files in the input\n     */\n    @NonNull\n    private static ImmutableSet<RelativeFile> computeFiles(@NonNull DirectoryInput directoryInput) {\n        File dir = directoryInput.getFile();\n        assert dir.isDirectory();\n        return RelativeFiles.fromDirectory(dir);\n    }\n\n    /**\n     * Creates a list of {@link IncrementalFileMergerInput} from a {@link TransformInput}. All files\n     * in the input will be reported in the incremental input, including those inside zips. This\n     * method assumes the input contains incremental information.\n     *\n     * @param transformInput the transform input\n     * @param zipCache the zip cache; the cache will not be modified\n     * @param cacheUpdates receives updates to the cache\n     * @param contentMap if not {@code null}, receives a mapping from all generated inputs to\n     * {@link QualifiedContent} they came from\n     * @param awbBundle\n     * @return the inputs\n     */\n    @NonNull\n    public static ImmutableList<IncrementalFileMergerInput> toIncrementalInput(\n            @NonNull TransformInput transformInput,\n            @NonNull FileCacheByPath zipCache,\n            @NonNull List<Runnable> cacheUpdates,\n            @Nullable Map<IncrementalFileMergerInput, QualifiedContent> contentMap, AwbTransform awbTransform,String name) {\n        ImmutableList.Builder<IncrementalFileMergerInput> builder = ImmutableList.builder();\n\n        for (JarInput jarInput : transformInput.getJarInputs()) {\n\n            if (awbTransform == null) {\n                if (!AtlasBuildContext.atlasMainDexHelperMap.get(name).getMainResFiles().containsKey(jarInput.getFile().getAbsolutePath())) {\n                    continue;\n                }\n            } else {\n                if (!awbTransform.getLibraryResourcesInutDir().contains(jarInput.getFile())){\n                    continue;\n                }\n\n            }\n            builder.add(toIncrementalInput(jarInput, zipCache, cacheUpdates, contentMap));\n        }\n\n        for (DirectoryInput dirInput : transformInput.getDirectoryInputs()) {\n            if (awbTransform == null) {\n                if (!AtlasBuildContext.atlasMainDexHelperMap.get(name).getMainSoFiles().containsKey(dirInput.getFile().getAbsolutePath())) {\n                    continue;\n                }\n\n            }else {\n                if (!awbTransform.getLibraryJniLibsInputDir().contains(dirInput.getFile())){\n                    continue;\n                }\n            }\n\n            builder.add(toIncrementalInput(dirInput, contentMap));\n        }\n\n        for (DirectoryInput dirInput : buildLocalDirInput()) {\n            if (awbTransform == null) {\n                if (!AtlasBuildContext.atlasMainDexHelperMap.get(name).getMainSoFiles().containsKey(dirInput.getFile().getAbsolutePath())) {\n                    continue;\n                }\n\n            }else {\n                if (!awbTransform.getLibraryJniLibsInputDir().contains(dirInput.getFile())){\n                    continue;\n                }\n            }\n\n            IncrementalFileMergerInput mergeInput =\n                    toIncrementalInput(dirInput, contentMap);\n            if (mergeInput != null) {\n                builder.add(mergeInput);\n            }\n\n        }\n\n        return builder.build();\n    }\n\n    /**\n     * Creates a list of {@link IncrementalFileMergerInput} from a {@link TransformInput}. All files\n     * in the input will be reported in the incremental input, including those inside zips. This\n     * method assumes the input does not contain incremental information. All files will be reported\n     * as new.\n     *\n     * @param transformInput the transform input\n     * @param zipCache the zip cache; the cache will not be modified\n     * @param cacheUpdates receives updates to the cache\n     * @param contentMap if not {@code null}, receives a mapping from all generated inputs to\n     * {@link QualifiedContent} they came from\n     * @param awbBundle\n     * @return the inputs\n     */\n    @NonNull\n    public static ImmutableList<IncrementalFileMergerInput> toNonIncrementalInput(\n            @NonNull TransformInput transformInput,\n            @NonNull FileCacheByPath zipCache,\n            @NonNull List<Runnable> cacheUpdates,\n            @Nullable Map<IncrementalFileMergerInput, QualifiedContent> contentMap, AwbTransform awbTransform,String name) {\n        ImmutableList.Builder<IncrementalFileMergerInput> builder = ImmutableList.builder();\n\n        for (JarInput jarInput : transformInput.getJarInputs()) {\n            if (awbTransform == null) {\n                if (!AtlasBuildContext.atlasMainDexHelperMap.get(name).getMainResFiles().containsKey(jarInput.getFile().getAbsolutePath())) {\n                    continue;\n                }\n            } else {\n                if (!awbTransform.getLibraryResourcesInutDir().contains(jarInput.getFile())){\n                    continue;\n                }\n\n            }\n\n            IncrementalFileMergerInput mergeInput =\n                    toNonIncrementalInput(jarInput, zipCache, cacheUpdates, contentMap);\n            if (mergeInput != null) {\n                builder.add(mergeInput);\n            }\n        }\n\n        for (DirectoryInput dirInput : transformInput.getDirectoryInputs()) {\n            if (awbTransform == null) {\n                if (!AtlasBuildContext.atlasMainDexHelperMap.get(name).getMainSoFiles().containsKey(dirInput.getFile().getAbsolutePath())) {\n                    continue;\n                }\n\n            }else {\n                if (!awbTransform.getLibraryJniLibsInputDir().contains(dirInput.getFile())){\n                    continue;\n                }\n            }\n\n            IncrementalFileMergerInput mergeInput =\n                    toNonIncrementalInput(dirInput, contentMap);\n            if (mergeInput != null) {\n                builder.add(mergeInput);\n            }\n\n        }\n\n\n\n        return builder.build();\n    }\n\n    /**\n     * Creates a list of {@link IncrementalFileMergerInput} from a {@link TransformInvocation}. All\n     * files in the input will be reported in the incremental input, including those inside zips.\n     *\n     * @param transformInvocation the transform invocation\n     * @param zipCache the zip cache; the cache will not be modified\n     * @param cacheUpdates receives updates to the cache\n     * @param full is this a full build? If not, then it is an incremental build; in full builds\n     * the output is not cleaned, it is the responsibility of the caller to ensure the output\n     * is properly set up; {@code full} cannot be {@code false} if the transform invocation is not\n     * stating that the invocation is an incremental one\n     * @param contentMap if not {@code null}, receives a mapping from all generated inputs to\n     * {@link QualifiedContent} they came from\n     */\n    @NonNull\n    public static ImmutableList<IncrementalFileMergerInput> toInput(\n            @NonNull TransformInvocation transformInvocation,\n            @NonNull FileCacheByPath zipCache,\n            @NonNull List<Runnable> cacheUpdates,\n            boolean full,\n            @Nullable Map<IncrementalFileMergerInput, QualifiedContent> contentMap, AwbTransform awbBundle,String name) {\n        if (!full) {\n            Preconditions.checkArgument(transformInvocation.isIncremental());\n        }\n\n        if (full) {\n            cacheUpdates.add(IOExceptionRunnable.asRunnable(zipCache::clear));\n        }\n\n        ImmutableList.Builder<IncrementalFileMergerInput> builder = ImmutableList.builder();\n        for (TransformInput input : transformInvocation.getInputs()) {\n            if (full) {\n                builder.addAll(toNonIncrementalInput(input, zipCache, cacheUpdates, contentMap,awbBundle,name));\n            } else {\n                builder.addAll(toIncrementalInput(input, zipCache, cacheUpdates, contentMap,awbBundle,name));\n            }\n        }\n\n        for (DirectoryInput dirInput : buildLocalDirInput()) {\n            if (awbBundle == null) {\n                if (!AtlasBuildContext.atlasMainDexHelperMap.get(name).getMainSoFiles().containsKey(dirInput.getFile().getAbsolutePath())) {\n                    continue;\n                }\n\n            }else {\n                if (!awbBundle.getLibraryJniLibsInputDir().contains(dirInput.getFile())){\n                    continue;\n                }\n            }\n\n            IncrementalFileMergerInput mergeInput =\n                    toNonIncrementalInput(dirInput, contentMap);\n            if (mergeInput != null) {\n                builder.add(mergeInput);\n            }\n\n        }\n\n\n        return builder.build();\n    }\n\n    /**\n     * Maps a {@link Status} to a {@link FileStatus}.\n     *\n     * @param status the status\n     * @return the {@link FileStatus} or {@code null} if {@code status} is {@link Status#NOTCHANGED}\n     */\n    @Nullable\n    private static FileStatus mapStatus(@NonNull Status status) {\n        switch (status) {\n            case ADDED:\n                return FileStatus.NEW;\n            case CHANGED:\n                return FileStatus.CHANGED;\n            case NOTCHANGED:\n                return null;\n            case REMOVED:\n                return FileStatus.REMOVED;\n            default:\n                throw new AssertionError();\n        }\n    }\n\n    private static Collection<? extends DirectoryInput> buildLocalDirInput() {\n        Set<DirectoryInput>directoryInputs = new HashSet<>();\n        for (File file: AtlasBuildContext.localLibs){\n            DirectoryInput directoryInput = new DirectoryInput() {\n                @Override\n                public Map<File, Status> getChangedFiles() {\n                     return ImmutableMap.of(file, Status.NOTCHANGED);\n                }\n\n                @Override\n                public String getName() {\n                    return \"localLibs\";\n                }\n\n                @Override\n                public File getFile() {\n                    return file;\n                }\n\n                @Override\n                public Set<ContentType> getContentTypes() {\n                    return TransformManager.CONTENT_NATIVE_LIBS;\n                }\n\n                @Override\n                public Set<? super Scope> getScopes() {\n                    return TransformManager.SCOPE_FULL_PROJECT;\n                }\n            };\n\n            directoryInputs.add(directoryInput);\n        }\n        return directoryInputs;\n\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/pipeline/AtlasIntermediateFolderUtils.java",
    "content": "package com.android.build.gradle.internal.pipeline;\n\nimport com.android.annotations.NonNull;\nimport com.android.build.api.transform.*;\nimport com.google.common.base.Joiner;\nimport com.google.common.base.Splitter;\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Sets;\nimport org.gradle.api.logging.Logging;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.stream.Collectors;\n\nimport static com.android.SdkConstants.DOT_JAR;\nimport static com.google.common.base.Preconditions.checkNotNull;\nimport static com.google.common.base.Preconditions.checkState;\n\n/**\n * @author lilong\n * @create 2017-12-20 下午1:08\n */\npublic class AtlasIntermediateFolderUtils extends IntermediateFolderUtils {\n\n    @NonNull private  File rootFolder;\n    private  Set<QualifiedContent.ContentType> types;\n    private  Set<? super QualifiedContent.Scope> scopes;\n    // current list of outputs.\n    private List<SubStream> subStreams = new ArrayList<>();\n\n    private List<SubStream>oldSubStreams;\n    // list of outputs that were found in the list, but that are already marked as removed.\n    private List<SubStream> removedSubStreams;\n    private List<SubStream> outOfScopeStreams;\n    private int nextIndex = 0;\n\n\n    public AtlasIntermediateFolderUtils(File rootFolder, Set<QualifiedContent.ContentType> types, Set<? super QualifiedContent.Scope> scopes) {\n        super(rootFolder, types, scopes);\n        this.rootFolder = rootFolder;\n        this.types = types;\n        this.scopes = scopes;\n\n        updateLists(makeRestrictedCopies(SubStream.loadSubStreams(rootFolder)));\n    }\n\n    @Override\n    public synchronized File getContentLocation(String name, Set<QualifiedContent.ContentType> types, Set<? super QualifiedContent.Scope> scopes, Format format) {\n        checkNotNull(name);\n        checkNotNull(types);\n        checkNotNull(scopes);\n        checkNotNull(format);\n        checkState(!name.isEmpty());\n        checkState(!types.isEmpty());\n        checkState(!scopes.isEmpty());\n\n        // search for an existing matching substream.\n        for (SubStream subStream : oldSubStreams) {\n            // look for an existing match. This means same name, types, scopes, and format.\n            if (name.equals(subStream.getName())\n                    && types.equals(subStream.getTypes())\n                    && scopes.equals(subStream.getScopes())\n                    && format == subStream.getFormat()) {\n                    subStreams.add(subStream);\n                return new File(rootFolder, name+\"-\"+subStream.getFilename());\n            }\n        }\n        // didn't find a matching output. create the new output\n        SubStream newSubStream = new SubStream(name, nextIndex++, scopes, types, format, true);\n\n        subStreams.add(newSubStream);\n\n        return new File(rootFolder, name+\"-\"+newSubStream.getFilename());    }\n\n    @Override\n    public TransformInput computeNonIncrementalInputFromFolder() {\n        final List<JarInput> jarInputs = Lists.newArrayList();\n        final List<DirectoryInput> directoryInputs = Lists.newArrayList();\n\n        for (SubStream subStream : subStreams) {\n            if (subStream.getFormat() == Format.DIRECTORY) {\n                directoryInputs.add(\n                        new ImmutableDirectoryInput(\n                                subStream.getName(),\n                                new File(rootFolder, subStream.getName()+\"-\"+subStream.getFilename()),\n                                subStream.getTypes(),\n                                subStream.getScopes()));\n\n            } else {\n                jarInputs.add(\n                        new ImmutableJarInput(\n                                subStream.getName(),\n                                new File(rootFolder, subStream.getName()+\"-\"+subStream.getFilename()),\n                                Status.NOTCHANGED,\n                                subStream.getTypes(),\n                                subStream.getScopes()));\n            }\n        }\n\n        return new ImmutableTransformInput(jarInputs, directoryInputs, rootFolder);\n    }\n\n\n    @NonNull\n    public Collection<File> getFiles(@NonNull StreamFilter streamFilter) {\n        List<File> files = Lists.newArrayListWithExpectedSize(subStreams.size());\n        for (SubStream stream : subStreams) {\n            if (streamFilter.accept(stream.getTypes(), stream.getScopes())) {\n                files.add(new File(rootFolder, stream.getName()+\"-\"+stream.getFilename()));\n            }\n        }\n\n        return files;\n    }\n\n    class IntermediateTransformInput extends IncrementalTransformInput {\n\n        @NonNull\n        private final File inputRoot;\n        private List<String> rootLocationSegments = null;\n\n        IntermediateTransformInput(@NonNull File inputRoot) {\n            this.inputRoot = inputRoot;\n        }\n\n        @Override\n        protected boolean checkRemovedFolder(\n                @NonNull Set<? super QualifiedContent.Scope> transformScopes,\n                @NonNull Set<QualifiedContent.ContentType> transformInputTypes,\n                @NonNull File file,\n                @NonNull List<String> fileSegments) {\n            if (!checkRootSegments(fileSegments)) {\n                return false;\n            }\n\n            // there must be at least 2 additional segments (1 to the root of the folder and 1 for\n            // the file inside.\n            if (fileSegments.size() < rootLocationSegments.size() + 2) {\n                return false;\n            }\n\n            // now check that the segments after the root are what we expect.\n            int index = rootLocationSegments.size();\n            String foldername = fileSegments.get(index);\n\n            // First loop on sub-streams we care about and on match, create a new Input\n            for (SubStream subStream : subStreams) {\n                if ((subStream.getName()+\"-\"+subStream.getFilename()).equals(foldername)\n                        && subStream.getFormat() == Format.DIRECTORY) {\n\n                    // create the mutable folder for it?\n                    MutableDirectoryInput folder =\n                            new MutableDirectoryInput(\n                                    subStream.getName(),\n                                    new File(rootFolder, foldername),\n                                    subStream.getTypes(),\n                                    subStream.getScopes());\n                    // add this file to it.\n                    Logging.getLogger(TransformManager.class)\n                            .info(\"Tagged\" + file.getAbsolutePath() + \" as removed\");\n                    folder.addChangedFile(file, Status.REMOVED);\n\n                    // add it to the list.\n                    addFolderInput(folder);\n\n                    return true;\n                }\n            }\n\n            // now loop on removed sub-streams. These can contain matching and non matching-streams\n            // so we may create an input or not.\n            for (SubStream subStream : removedSubStreams) {\n                if ((subStream.getName()+\"-\"+subStream.getFilename()).equals(foldername)\n                        && subStream.getFormat() == Format.DIRECTORY) {\n                    // we need to check if the type/scope of this file matches this stream,\n                    // as we could be using a sub-stream.\n                    if (!Sets.intersection(transformInputTypes, subStream.getTypes()).isEmpty()\n                            && !Sets.intersection(transformScopes, subStream.getScopes())\n                            .isEmpty()) {\n                        // create the mutable folder for it?\n                        MutableDirectoryInput folder =\n                                new MutableDirectoryInput(\n                                        subStream.getName(),\n                                        new File(rootFolder, foldername),\n                                        subStream.getTypes(),\n                                        subStream.getScopes());\n                        // add this file to it.\n                        Logging.getLogger(TransformManager.class)\n                                .info(\"Tagged\" + file.getAbsolutePath() + \" as removed\");\n                        folder.addChangedFile(file, Status.REMOVED);\n\n                        // add it to the list.\n                        addFolderInput(folder);\n                    }\n\n                    // return true whether the sub-stream is a scope/type match, to mention\n                    // we know about the file.\n                    return true;\n                }\n            }\n\n            // then loop on the out of scope/type sub-streams and just acknowledge the file\n            // is part of the stream if it's a name match.\n            for (SubStream subStream : outOfScopeStreams) {\n                if ((subStream.getName()+\"-\"+subStream.getFilename()).equals(foldername)\n                        && subStream.getFormat() == Format.DIRECTORY) {\n                    return true;\n                }\n            }\n\n            return false;\n        }\n\n        @Override\n        boolean checkRemovedJarFile(\n                @NonNull Set<? super QualifiedContent.Scope> transformScopes,\n                @NonNull Set<QualifiedContent.ContentType> transformInputTypes,\n                @NonNull File file,\n                @NonNull List<String> fileSegments) {\n            if (!checkRootSegments(fileSegments)) {\n                return false;\n            }\n\n            // there must be only 1 additional segments.\n            if (fileSegments.size() != rootLocationSegments.size() + 1) {\n                return false;\n            }\n\n            String filename = file.getName();\n\n            // last segment must end in .jar\n            if (!filename.endsWith(DOT_JAR)) {\n                return false;\n            }\n\n            // First loop on sub-streams we care about and on match, create a new Input\n            for (SubStream subStream : subStreams) {\n                if ((subStream.getName()+\"-\"+subStream.getFilename()).equals(filename)\n                        && subStream.getFormat() == Format.JAR) {\n                    // create the jar input\n                    addImmutableJar(\n                            new ImmutableJarInput(\n                                    subStream.getName(),\n                                    file,\n                                    Status.REMOVED,\n                                    subStream.getTypes(),\n                                    subStream.getScopes()));\n                    return true;\n                }\n            }\n\n            // now loop on removed sub-streams. These can contain matching and non matching-streams\n            // so we may create an input or not.\n            for (SubStream subStream : removedSubStreams) {\n                if ((subStream.getName()+\"-\"+subStream.getFilename()).equals(filename)\n                        && subStream.getFormat() == Format.JAR) {\n                    // we need to check if the type/scope of this file matches this stream,\n                    // as we could be using a sub-stream.\n                    if (!Sets.intersection(transformInputTypes, subStream.getTypes()).isEmpty()\n                            && !Sets.intersection(transformScopes, subStream.getScopes())\n                            .isEmpty()) {\n                        addImmutableJar(\n                                new ImmutableJarInput(\n                                        subStream.getName(),\n                                        file,\n                                        Status.REMOVED,\n                                        subStream.getTypes(),\n                                        subStream.getScopes()));\n                    }\n\n                    // return true whether the sub-stream is a scope/type match, to mention\n                    // we know about the file.\n                    return true;\n                }\n            }\n\n            // then loop on the out of scope/type sub-streams and just acknowledge the file\n            // is part of the stream if it's a name match.\n            for (SubStream subStream : outOfScopeStreams) {\n                if ((subStream.getName()+\"-\"+subStream.getFilename()).equals(filename)\n                        && subStream.getFormat() == Format.JAR) {\n                    return true;\n                }\n            }\n\n            return false;\n        }\n\n        private boolean checkRootSegments(@NonNull List<String> fileSegments) {\n            if (rootLocationSegments == null) {\n                rootLocationSegments = Lists.newArrayList(\n                        Splitter.on(File.separatorChar).split(inputRoot.getAbsolutePath()));\n            }\n\n            if (fileSegments.size() <= rootLocationSegments.size()) {\n                return false;\n            }\n\n            // compare segments going backward as the leafs are more likely to be different.\n            // We can ignore the segments of the file that are beyond the segments for the folder.\n            for (int i = rootLocationSegments.size() - 1 ; i >= 0 ; i--) {\n                if (!rootLocationSegments.get(i).equals(fileSegments.get(i))) {\n                    return false;\n                }\n            }\n\n            return true;\n        }\n\n    }\n\n\n    @NonNull\n    public IncrementalTransformInput computeIncrementalInputFromFolder() {\n        final IncrementalTransformInput input = new AtlasIntermediateFolderUtils.IntermediateTransformInput(rootFolder);\n\n        for (SubStream subStream : subStreams) {\n            if (subStream.getFormat() == Format.DIRECTORY) {\n                input.addFolderInput(\n                        new MutableDirectoryInput(\n                                subStream.getName(),\n                                new File(rootFolder, subStream.getName()+\"-\"+subStream.getFilename()),\n                                subStream.getTypes(),\n                                subStream.getScopes()));\n\n            } else {\n                input.addJarInput(\n                        new QualifiedContentImpl(\n                                subStream.getName(),\n                                new File(rootFolder, subStream.getName()+\"-\"+subStream.getFilename()),\n                                subStream.getTypes(),\n                                subStream.getScopes()));\n            }\n        }\n\n        return input;\n    }\n\n    public void save() throws IOException {\n        // create a copy list with a new present flag based on whether the output actually\n        // exists.\n        // Don't process the removedSubStreams as they were removed in a previous run.\n        List<SubStream> copyList = Lists.newArrayListWithCapacity(subStreams.size());\n        for (SubStream subStream : subStreams) {\n            if (rootFolder.getName().endsWith(\"debug\") && subStream.getScopes().contains(QualifiedContent.Scope.EXTERNAL_LIBRARIES)){\n                subStream = new SubStream(subStream.getName(),subStream.getIndex(),Sets.immutableEnumSet(\n                        QualifiedContent.Scope.PROJECT),subStream.getTypes(),subStream.getFormat(),subStream.isPresent());\n            }\n            copyList.add(\n                    subStream.duplicateWithPresent(\n                            new File(rootFolder, subStream.getName()+\"-\"+subStream.getFilename()).exists()));\n        }\n\n        // save that list.\n        SubStream.save(copyList, rootFolder);\n\n        // and use to to re-fill the normal and removed list for the next transform in case\n        // it's happening in the same graph execution.\n        updateLists(copyList);\n    }\n\n\n    private void updateLists(@NonNull Collection<SubStream> subStreamList) {\n        oldSubStreams =\n                subStreamList.stream().filter(SubStream::isPresent).collect(Collectors.toList());\n        removedSubStreams =\n                subStreamList\n                        .stream()\n                        .filter(subStream -> !subStream.isPresent())\n                        .collect(Collectors.toList());\n    }\n\n    @NonNull\n    private Collection<SubStream> makeRestrictedCopies(@NonNull Collection<SubStream> streams) {\n        List<SubStream> list = Lists.newArrayListWithCapacity(streams.size());\n        outOfScopeStreams = Lists.newArrayList();\n\n        for (SubStream subStream : streams) {\n            if (subStream.getIndex() >= nextIndex) {\n                nextIndex = subStream.getIndex() + 1;\n            }\n\n            if (subStream.isPresent()) {\n                // check these are types we care about and only pass down types we care about.\n                // In this case we can safely return the content with a limited type,\n                // as file extension allows for differentiation.\n                Set<QualifiedContent.ContentType> limitedTypes = Sets.intersection(types, subStream.getTypes());\n                if (!limitedTypes.isEmpty()) {\n                    // We consider compatible sub-stream to:\n                    // - contains 1+ of the main stream scopes\n                    // - and not contain any other scopes.\n                    // SubStream that only contains unwanted scopes are fine\n                    // SubStream that contains some required scope and some other scope generate\n                    // an exception.\n                    boolean foundUnwanted = false;\n                    boolean foundMatch = false;\n                    for (Object scope : subStream.getScopes()) {\n                        //noinspection SuspiciousMethodCalls\n                        if (scopes.contains(scope)) {\n                            foundMatch = true;\n                        } else {\n                            foundUnwanted = true;\n                        }\n                    }\n\n                    if (foundMatch && foundUnwanted) {\n                        // Sort the names, so the error message is stable.\n                        List<String> foundScopes =\n                                subStream\n                                        .getScopes()\n                                        .stream()\n                                        .map(Object::toString)\n                                        .sorted()\n                                        .collect(Collectors.toList());\n\n                        throw new RuntimeException(\n                                String.format(\n                                        \"Unexpected scopes found in folder '%s'. Required: %s. Found: %s\",\n                                        rootFolder,\n                                        Joiner.on(\", \").join(scopes),\n                                        Joiner.on(\", \").join(foundScopes)));\n                    } else if (foundMatch) {\n                        // if the types are an exact match, then just get the substream\n                        if (limitedTypes.size() == subStream.getTypes().size()) {\n                            list.add(subStream);\n                        } else {\n                            // make a restricted copy.\n                            list.add(\n                                    new SubStream(\n                                            subStream.getName(),\n                                            subStream.getIndex(),\n                                            subStream.getScopes(),\n                                            limitedTypes,\n                                            subStream.getFormat(),\n                                            subStream.isPresent()));\n\n                            // and keep the rest around, as out of scope to detect (and ignore)\n                            // changed files. Because we only take streams with a subset only of\n                            // required scopes, we know there's no need to get the\n                            outOfScopeStreams.add(\n                                    new SubStream(\n                                            subStream.getName(),\n                                            subStream.getIndex(),\n                                            subStream.getScopes(),\n                                            minus(subStream.getTypes(), limitedTypes),\n                                            subStream.getFormat(),\n                                            subStream.isPresent()));\n                        }\n\n                    } else {\n                        // no match at all, add to output of scope streams.\n                        outOfScopeStreams.add(subStream);\n                    }\n                } else {\n                    // no match at all, add to output of scope streams.\n                    outOfScopeStreams.add(subStream);\n                }\n            } else {\n                // don't do filtering for removed streams.\n                list.add(subStream);\n            }\n        }\n\n        return list;\n    }\n\n    private static <T> Set<T> minus(Set<T> main, Set<T> minus) {\n        Set<T> result = Sets.newHashSet(main);\n        result.removeAll(minus);\n        return result;\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/pipeline/AtlasIntermediateStreamHelper.java",
    "content": "package com.android.build.gradle.internal.pipeline;\n\nimport com.android.build.api.transform.QualifiedContent;\nimport com.android.build.api.transform.TransformInput;\nimport com.android.build.api.transform.TransformInvocation;\nimport com.android.build.api.transform.TransformOutputProvider;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport org.gradle.api.file.FileCollection;\n\nimport java.lang.reflect.Field;\nimport java.util.Set;\n\n/**\n * @author lilong\n * @create 2017-12-20 下午1:08\n */\npublic class AtlasIntermediateStreamHelper{\n\n\n    private IntermediateStream intermediateStream;\n\n    public AtlasIntermediateStreamHelper(TransformTask transformTask) {\n\n        this.intermediateStream = (IntermediateStream) ReflectUtils.getField(transformTask,\"outputStream\");\n    }\n\n    public void replaceProvider(TransformInvocation transformInvocation){\n        try {\n            Field field = intermediateStream.getClass().getDeclaredField(\"folderUtils\");\n            field.setAccessible(true);\n            IntermediateFolderUtils intermediateFolderUtils = (IntermediateFolderUtils) field.get(intermediateStream);\n            Set<QualifiedContent.ContentType> types = (Set<QualifiedContent.ContentType>) ReflectUtils.getField(intermediateFolderUtils,\"types\");\n            Set<? super QualifiedContent.Scope> scopes = (Set<? super QualifiedContent.Scope>) ReflectUtils.getField(intermediateFolderUtils,\"scopes\");\n            AtlasIntermediateFolderUtils atlasIntermediateFolderUtils = new AtlasIntermediateFolderUtils(intermediateFolderUtils.getRootFolder(),types,scopes);\n            field.set(intermediateStream,atlasIntermediateFolderUtils);\n            TransformOutputProvider transformOutputProvider = transformInvocation.getOutputProvider();\n            ReflectUtils.updateField(transformOutputProvider,\"folderUtils\",atlasIntermediateFolderUtils);\n\n        }catch (Exception e){\n\n        }\n\n\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/pipeline/InjectTransform.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.build.gradle.internal.pipeline;\n\nimport com.android.build.api.transform.Transform;\n\n/**\n * Created by shenghua.nish on 2016-06-15 When in the afternoon.\n */\npublic abstract  class InjectTransform extends Transform{\n    /**\n     * Whether to modify the next Transform input\n     * @return\n     */\n    public abstract  boolean updateNextTransformInput();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/pipeline/InjectTransformManager.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.build.gradle.internal.pipeline;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.api.transform.QualifiedContent;\nimport com.android.build.api.transform.QualifiedContent.Scope;\nimport com.android.build.api.transform.Transform;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.tasks.DefaultAndroidTask;\nimport com.android.builder.model.AndroidProject;\nimport com.android.builder.profile.ThreadRecorder;\nimport com.android.utils.FileUtils;\nimport com.android.utils.StringHelper;\nimport com.google.common.collect.Lists;\n\nimport org.apache.commons.lang3.reflect.FieldUtils;\nimport org.gradle.api.Project;\nimport org.gradle.api.tasks.StopExecutionException;\nimport org.gradle.api.tasks.TaskCollection;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.io.File;\nimport java.lang.reflect.Field;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Set;\nimport java.util.SortedMap;\n\nimport static com.android.utils.StringHelper.capitalize;\n\n/**\n * Inject the injection management class with TransformManger, Mainly injected into the intermediate process of class->dex\n * Created by shenghua.nish on 2016-06-13 2:02 PM.\n */\npublic class InjectTransformManager {\n\n    private static final String FD_TRANSFORMS = \"transforms\";\n\n    private List<Transform> transforms = Lists.newArrayList();\n\n    private List<String> transformTaskList = Lists.newArrayList();\n\n    private final Project project;\n\n    private final String variantName;\n\n    public InjectTransformManager(Project project, @NonNull String variantName) {\n        this.project = project;\n        this.variantName = variantName;\n    }\n\n    public void reset() {\n        transforms.clear();\n        transformTaskList.clear();\n    }\n\n    /**\n     * Add a Transform operation before some Transform\n     *\n     * @param transformClazz\n     * @param injectTransform\n     * @param scope\n     * @param <T>\n     * @return\n     */\n    public <T extends InjectTransform> TransformTask addInjectTransformBeforeTransform(Class<? extends Transform> transformClazz,\n                                                                                       T injectTransform,\n                                                                                       @NonNull VariantScope scope) {\n        TaskCollection<DefaultAndroidTask> androidTasks = project.getTasks()\n                .withType(DefaultAndroidTask.class);\n        SortedMap<String, DefaultAndroidTask> androidTaskSortedMap = androidTasks.getAsMap();\n        TransformTask oprTransformTask = null; // The task to be inserted\n        for (String taskName : androidTaskSortedMap.keySet()) {\n            DefaultAndroidTask androidTask = androidTaskSortedMap.get(taskName);\n            if (variantName.equals(androidTask.getVariantName())) {\n                if (androidTask instanceof TransformTask &&\n                        ((TransformTask) androidTask).getTransform()\n                                .getClass()\n                                .equals(transformClazz)) {\n                    oprTransformTask = (TransformTask) androidTask;\n                    break;\n                }\n            }\n        }\n        if (null == oprTransformTask) {\n            throw new StopExecutionException(\"TransformTask with transfrom type:\" +\n                                                     transformClazz.getName() +\n                                                     \" can not found!\");\n        }\n        transforms.add(injectTransform);\n        //Determines whether the two Transform dependencies are correct, that is, the output type is consistent with the next input type\n        checkTransformConfig(oprTransformTask.getTransform(), injectTransform);\n\n        String taskName = scope.getTaskName(getTaskNamePrefix(injectTransform));\n\n        try {\n            IntermediateStream outputStream = getOutputStream(injectTransform, scope, taskName);\n\n            // Configuration TransformTask\n            TransformTaskParam transformTaskParam = getTransformParam(oprTransformTask);\n            TransformTask.ConfigAction<T> configAction = new TransformTask.ConfigAction<T>(\n                    variantName,\n                    taskName,\n                    injectTransform,\n                    transformTaskParam.consumedInputStreams,\n                    transformTaskParam.referencedInputStreams,\n                    outputStream,\n                    ThreadRecorder.get(),null);\n\n            TransformTask injectTransformTask = project.getTasks()\n                    .create(configAction.getName(), configAction.getType());\n            oprTransformTask.dependsOn(injectTransformTask);\n            for (TransformStream transformStream : transformTaskParam.consumedInputStreams) {\n                if (null != transformStream.getFileCollection()) {\n                    injectTransformTask.dependsOn(transformStream.getFileCollection());\n                }\n            }\n\n//            for (TransformStream transformStream : transformTaskParam.referencedInputStreams) {\n//                if (null != transformStream.getDependencies()) {\n//                    injectTransformTask.dependsOn(transformStream.getDependencies());\n//                }\n//            }\n\n            if (transformTaskList.size() > 0) {\n                injectTransformTask.dependsOn(transformTaskList.get(transformTaskList.size() - 1));\n            }\n            transformTaskList.add(taskName);\n            configAction.execute(injectTransformTask);\n\n            //Modify the input of the oprTransformTask\n            if (injectTransform.updateNextTransformInput()) {\n                Collection<TransformStream> newInputStream = Lists.newArrayList();\n                newInputStream.add(outputStream);\n                updateTransformTaskConfig(oprTransformTask,\n                                          newInputStream,\n                                          transformTaskParam.referencedInputStreams,\n                                          transformTaskParam.outputStream);\n            }\n\n            return injectTransformTask;\n        } catch (IllegalAccessException e) {\n            throw new StopExecutionException(e.getMessage());\n        }\n    }\n\n    /**\n     * Get the task outputStream\n     *\n     * @param injectTransform\n     * @param scope\n     * @param taskName\n     * @param <T>\n     * @return\n     */\n    @NotNull\n    private <T extends Transform> IntermediateStream getOutputStream(T injectTransform,\n                                                                     @NonNull VariantScope scope,\n                                                                     String taskName) {\n        File outRootFolder = FileUtils.join(project.getBuildDir(),\n                                            StringHelper.toStrings(AndroidProject.FD_INTERMEDIATES,\n                                                                   FD_TRANSFORMS,\n                                                                   injectTransform.getName(),\n                                                                   scope.getDirectorySegments()));\n\n        Set<? super Scope> requestedScopes = injectTransform.getScopes();\n\n        // create the output\n        return IntermediateStream.builder(project,injectTransform.getName())\n                .addContentTypes(injectTransform.getOutputTypes())\n                .addScopes(requestedScopes)\n                .setTaskName(taskName)\n                .setRootLocation(outRootFolder).build();\n\n    }\n\n    /**\n     * Gets the list of all transformtasks\n     *\n     * @return\n     */\n    private SortedMap<String, TransformTask> getTransformTasks() {\n        TaskCollection<TransformTask> transformTasks = project.getTasks()\n                .withType(TransformTask.class);\n        return transformTasks.getAsMap();\n    }\n\n    /**\n     * Update the parameters for the transformTask\n     *\n     * @param transformTask\n     * @param consumedInputStreams\n     * @param referencedInputStreams\n     * @param outputStream\n     */\n    private void updateTransformTaskConfig(TransformTask transformTask,\n                                           @NonNull Collection<TransformStream> consumedInputStreams,\n                                           @NonNull Collection<TransformStream> referencedInputStreams,\n                                           @Nullable IntermediateStream outputStream) throws IllegalAccessException {\n        Field consumedInputStreamsField = FieldUtils.getDeclaredField(StreamBasedTask.class,\n                                                                      \"consumedInputStreams\",\n                                                                      true);\n        Field referencedInputStreamsField = FieldUtils.getDeclaredField(StreamBasedTask.class,\n                                                                        \"referencedInputStreams\",\n                                                                        true);\n        Field outputStreamField = FieldUtils.getDeclaredField(StreamBasedTask.class,\n                                                              \"outputStream\",\n                                                              true);\n\n        if (null == consumedInputStreamsField ||\n                null == referencedInputStreamsField ||\n                null == outputStreamField) {\n            throw new StopExecutionException(\n                    \"The TransformTask does not has field with name: consumedInputStreams or referencedInputStreams or outputStream! Plugin version does not support!\");\n        }\n        consumedInputStreamsField.set(transformTask, consumedInputStreams);\n        referencedInputStreamsField.set(transformTask, referencedInputStreams);\n        outputStreamField.set(transformTask, outputStream);\n    }\n\n    /**\n     * Gets the parameters of a transformTask\n     *\n     * @param transformTask\n     * @return\n     * @throws IllegalAccessException\n     */\n    private TransformTaskParam getTransformParam(TransformTask transformTask) throws IllegalAccessException {\n        TransformTaskParam transformTaskParam = new TransformTaskParam();\n        Field consumedInputStreamsField = FieldUtils.getDeclaredField(StreamBasedTask.class,\n                                                                      \"consumedInputStreams\",\n                                                                      true);\n        Field referencedInputStreamsField = FieldUtils.getDeclaredField(StreamBasedTask.class,\n                                                                        \"referencedInputStreams\",\n                                                                        true);\n        Field outputStreamField = FieldUtils.getDeclaredField(StreamBasedTask.class,\n                                                              \"outputStream\",\n                                                              true);\n\n        if (null == consumedInputStreamsField ||\n                null == referencedInputStreamsField ||\n                null == outputStreamField) {\n            throw new StopExecutionException(\n                    \"The TransformTask does not has field with name: consumedInputStreams or referencedInputStreams or outputStream! Plugin version does not support!\");\n        }\n        transformTaskParam.consumedInputStreams = (Collection<TransformStream>) consumedInputStreamsField\n                .get(transformTask);\n        transformTaskParam.referencedInputStreams = (Collection<TransformStream>) referencedInputStreamsField\n                .get(transformTask);\n        transformTaskParam.outputStream = (IntermediateStream) outputStreamField.get(transformTask);\n        return transformTaskParam;\n    }\n\n    /**\n     * The input type of the injection is consistent with the input type of the next task\n     *\n     * @param oprTransform\n     * @param injectTransform\n     */\n    private void checkTransformConfig(Transform oprTransform, Transform injectTransform) {\n        assert (oprTransform.getInputTypes().equals(injectTransform.getOutputTypes()));\n    }\n\n    /**\n     * TransformTaskParameter combination\n     */\n    static class TransformTaskParam {\n\n        Collection<TransformStream> consumedInputStreams;\n\n        Collection<TransformStream> referencedInputStreams;\n\n        IntermediateStream outputStream;\n    }\n\n    @NonNull\n    private static String getTaskNamePrefix(@NonNull Transform transform) {\n        StringBuilder sb = new StringBuilder(100);\n        sb.append(\"transform\");\n\n        Iterator<QualifiedContent.ContentType> iterator = transform.getInputTypes().iterator();\n        // there's always at least one\n        sb.append(capitalize(iterator.next().name().toLowerCase(Locale.getDefault())));\n        while (iterator.hasNext()) {\n            sb.append(\"And\")\n                    .append(capitalize(iterator.next().name().toLowerCase(Locale.getDefault())));\n        }\n\n        sb.append(\"With\").append(capitalize(transform.getName())).append(\"For\");\n\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/publishing/AtlasAndroidArtifacts.java",
    "content": "package com.android.build.gradle.internal.publishing;\n\nimport com.android.annotations.NonNull;\nimport org.gradle.api.artifacts.type.ArtifactTypeDefinition;\nimport org.gradle.api.attributes.Attribute;\n\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.PublishedConfigType.*;\n\n/**\n * @author lilong\n * @create 2017-11-30 上午11:48\n */\n\npublic class AtlasAndroidArtifacts extends AndroidArtifacts{\n\n\n    public static final String TYPE_AWB = \"awb\";\n\n    public static final String TYPE_AP =\"ap\";\n\n    public static final String TYPE_SOLIB =\"solib\";\n\n    public static final String TYPE_AWO = \"awo\";\n\n    public static final String TYPE_REMOVE_BUNDLE = \"remotebundles\";\n\n    public static final String TYPE_PACKAGEID = \"packageIdFile.properties\";\n\n    public static final String TYPE_ARSC = \"resources.arsc\";\n\n    public static final String TYPE_VERSIONS = \"version.properties\";\n\n    public static final String TYPE_DEPENDENCIES = \"dependencies.txt\";\n\n    public static final String TYPE_R_TXT = \"R.txt\";\n\n    public static final String TYPE_APK_FILES = \"apk-files.txt\";\n\n    public static final String TYPE_BUILD_TXT = \"build.txt\";\n\n    public static final String TYPE_MUPPBUNDLEINFO = \"muppBundleInfo.json\";\n\n\n\n    public static final String TYPE_EXPLODED_AWB = \"android-exploded-awb\";\n\n    public static final String TYPE_EXPLODED_AP = \"android-exploded-ap\";\n\n    public static final String TYPE_EXPLODED_SOLIB = \"android-exploded-solib\";\n\n    public static final String TYPE_LIBS = \"libs\";\n\n    public static final String TYPE_ATLAS_JSON = \"atlasFrameworkProperties.json\";\n\n\n    public static final Attribute<String> ARTIFACT_TYPE = Attribute.of(\"artifactType\", String.class);\n\n    // types for main artifacts\n    public static final String TYPE_AAR = \"aar\";\n    private static final String TYPE_APK = \"apk\";\n    private static final String TYPE_JAR = ArtifactTypeDefinition.JAR_TYPE;\n\n    // types for AAR content\n    private static final String TYPE_CLASSES = \"android-classes\";\n    private static final String TYPE_JAVA_RES = \"android-java-res\";\n    private static final String TYPE_MANIFEST = \"android-manifest\";\n    private static final String TYPE_MANIFEST_METADATA = \"android-manifest-metadata\";\n    private static final String TYPE_ANDROID_RES = \"android-res\";\n    private static final String TYPE_ASSETS = \"android-assets\";\n    private static final String TYPE_JNI = \"android-jni\";\n    private static final String TYPE_AIDL = \"android-aidl\";\n    private static final String TYPE_RENDERSCRIPT = \"android-renderscript\";\n    private static final String TYPE_LINT_JAR = \"android-lint\";\n    private static final String TYPE_EXT_ANNOTATIONS = \"android-ext-annot\";\n    private static final String TYPE_PUBLIC_RES = \"android-public-res\";\n    private static final String TYPE_SYMBOL = \"android-symbol\";\n    private static final String TYPE_SYMBOL_WITH_PACKAGE_NAME = \"android-symbol-with-package-name\";\n    private static final String TYPE_PROGUARD_RULES = \"android-proguad\";\n    private static final String TYPE_DATA_BINDING_ARTIFACT = \"android-databinding\";\n    private static final String TYPE_EXPLODED_AAR = \"android-exploded-aar\";\n\n    // types for additional artifacts to go with APK\n    private static final String TYPE_MAPPING = \"android-mapping\";\n    private static final String TYPE_METADATA = \"android-metadata\";\n\n    // types for feature-split content.\n    private static final String TYPE_FEATURE_IDS_DECLARATION = \"android-feature-split-ids\";\n    private static final String TYPE_FEATURE_APPLICATION_ID = \"android-feature-application-id\";\n    private static final String TYPE_FEATURE_RESOURCE_PKG = \"android-feature-res-ap_\";\n    private static final String TYPE_FEATURE_TRANSITIVE_DEPS = \"android-feature-transitive-deps\";\n\n    // types for metadata content.\n    private static final String TYPE_METADATA_FEATURE_DECLARATION = \"android-metadata-feature-decl\";\n    private static final String TYPE_METADATA_FEATURE_MANIFEST =\n            \"android-metadata-feature-manifest\";\n    private static final String TYPE_METADATA_APP_ID_DECLARATION = \"android-metadata-app-id-decl\";\n\n    public enum ConsumedConfigType {\n        COMPILE_CLASSPATH(\"compileClasspath\", API_ELEMENTS, true),\n        RUNTIME_CLASSPATH(\"runtimeClasspath\", RUNTIME_ELEMENTS, true),\n        ANNOTATION_PROCESSOR(\"annotationProcessorClasspath\", RUNTIME_ELEMENTS, false),\n        METADATA_VALUES(\"metadata\", METADATA_ELEMENTS, false),\n        BUNDLECOMPILE_CLASSPATH(\"bundleCompile\",RUNTIME_ELEMENTS,true);\n\n        @NonNull private final String name;\n        @NonNull private final AndroidArtifacts.PublishedConfigType publishedTo;\n        private final boolean needsTestedComponents;\n\n        ConsumedConfigType(\n                @NonNull String name,\n                @NonNull AndroidArtifacts.PublishedConfigType publishedTo,\n                boolean needsTestedComponents) {\n            this.name = name;\n            this.publishedTo = publishedTo;\n            this.needsTestedComponents = needsTestedComponents;\n        }\n\n        @NonNull\n        public String getName() {\n            return name;\n        }\n\n        @NonNull\n        public AndroidArtifacts.PublishedConfigType getPublishedTo() {\n            return publishedTo;\n        }\n\n        public boolean needsTestedComponents() {\n            return needsTestedComponents;\n        }\n    }\n\n    public enum PublishedConfigType {\n        API_ELEMENTS,\n        RUNTIME_ELEMENTS,\n        METADATA_ELEMENTS\n    }\n\n    public enum ArtifactScope {\n        ALL, EXTERNAL, MODULE\n    }\n\n\n    public enum AtlasArtifactType {\n\n        AWB(TYPE_AWB),\n        EXPLODED_AWB(TYPE_EXPLODED_AWB),\n        EXPLODED_AP(TYPE_EXPLODED_AP),\n        AP(TYPE_AP),\n        CLASSES(TYPE_CLASSES),\n        // Jar file for annotation processor as both classes and resources are needed, and for building model\n        JAR(TYPE_JAR),\n\n        // manifest is published to both to compare and detect provided-only library dependencies.\n        MANIFEST(TYPE_MANIFEST),\n        MANIFEST_METADATA(TYPE_MANIFEST_METADATA),\n\n        // API only elements.\n        AIDL(TYPE_AIDL),\n        RENDERSCRIPT(TYPE_RENDERSCRIPT),\n        DATA_BINDING_ARTIFACT(TYPE_DATA_BINDING_ARTIFACT),\n\n        // runtime only elements\n        JAVA_RES(TYPE_JAVA_RES),\n        ANDROID_RES(TYPE_ANDROID_RES),\n        ASSETS(TYPE_ASSETS),\n        SYMBOL_LIST(TYPE_SYMBOL),\n        /**\n         * The symbol list with the package name as the first line. As the r.txt format in the AAR\n         * cannot be changed, this is created by prepending the package name from the\n         * AndroidManifest.xml to the existing r.txt file.\n         */\n        SYMBOL_LIST_WITH_PACKAGE_NAME(TYPE_SYMBOL_WITH_PACKAGE_NAME),\n        JNI(TYPE_JNI),\n        ANNOTATIONS(TYPE_EXT_ANNOTATIONS),\n        PUBLIC_RES(TYPE_PUBLIC_RES),\n        PROGUARD_RULES(TYPE_PROGUARD_RULES),\n\n        LINT(TYPE_LINT_JAR),\n\n        APK_MAPPING(TYPE_MAPPING),\n        APK_METADATA(TYPE_METADATA),\n        APK(TYPE_APK),\n\n        // Feature split related artifacts.\n        FEATURE_IDS_DECLARATION(TYPE_FEATURE_IDS_DECLARATION),\n        FEATURE_APPLICATION_ID_DECLARATION(TYPE_FEATURE_APPLICATION_ID),\n        FEATURE_RESOURCE_PKG(TYPE_FEATURE_RESOURCE_PKG),\n        FEATURE_TRANSITIVE_DEPS(TYPE_FEATURE_TRANSITIVE_DEPS),\n\n        // Metadata artifacts\n        METADATA_FEATURE_DECLARATION(TYPE_METADATA_FEATURE_DECLARATION),\n        METADATA_FEATURE_MANIFEST(TYPE_METADATA_FEATURE_MANIFEST),\n        METADATA_APP_ID_DECLARATION(TYPE_METADATA_APP_ID_DECLARATION),\n\n        // types for querying only. Not publishable.\n        AAR(TYPE_AAR),\n        EXPLODED_AAR(TYPE_EXPLODED_AAR),\n        BASE_AWO(TYPE_AWO),\n        BASE_ATLAS_JSON(TYPE_ATLAS_JSON),\n        BASE_REMOTE_BUNDLE(TYPE_REMOVE_BUNDLE),\n        BASE_PACKAGE_IDS(TYPE_PACKAGEID),\n        BASE_ARSC(TYPE_ARSC),\n        BASE_VERSIONS(TYPE_VERSIONS),\n        BASE_DEPENDENCIES(TYPE_DEPENDENCIES),\n        BASE_R(TYPE_R_TXT),\n        BASE_APK_FILES(TYPE_APK_FILES),\n        BASE_BUILD_TXT(TYPE_BUILD_TXT),\n        BASE_MUPP_JSON(TYPE_MUPPBUNDLEINFO),\n        BASE_APK(TYPE_APK),\n        BASE_MANIFEST(TYPE_MANIFEST),\n        LIBS(TYPE_LIBS);\n\n\n        @NonNull\n        private final String type;\n\n        AtlasArtifactType(@NonNull String type) {\n            this.type = type;\n        }\n\n        @NonNull\n        public String getType() {\n            return type;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/scope/ConventionMappingHelper.java",
    "content": "package com.android.build.gradle.internal.scope;\n\nimport com.android.annotations.NonNull;\nimport groovy.lang.GroovyObject;\nimport org.gradle.api.Task;\nimport org.gradle.api.internal.ConventionMapping;\nimport org.gradle.api.internal.ConventionTask;\n\nimport java.util.concurrent.Callable;\n\n/**\n * @author lilong\n * @create 2017-11-30 下午2:37\n */\n\npublic final class ConventionMappingHelper {\n    private ConventionMappingHelper() {}\n\n    public static void map(@NonNull Task task, @NonNull String key, @NonNull Callable<?> value) {\n        if (task instanceof ConventionTask) {\n            ((ConventionTask) task).getConventionMapping().map(key, value);\n        } else if (task instanceof GroovyObject) {\n            ConventionMapping conventionMapping =\n                    (ConventionMapping) ((GroovyObject) task).getProperty(\"conventionMapping\");\n            conventionMapping.map(key, value);\n        } else {\n            throw new IllegalArgumentException(\n                    \"Don't know how to apply convention mapping to task of type \" + task.getClass().getName());\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/transforms/ApTransform.java",
    "content": "package com.android.build.gradle.internal.transforms;\n\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.internal.publishing.AtlasAndroidArtifacts;\nimport org.gradle.api.artifacts.transform.ArtifactTransform;\n\nimport javax.inject.Inject;\nimport java.io.File;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * @author lilong\n * @create 2017-12-03 下午1:14\n */\n\npublic class ApTransform extends ArtifactTransform {\n\n    @NonNull\n    private final AtlasAndroidArtifacts.AtlasArtifactType targetType;\n\n    @Inject\n    public ApTransform(@NonNull AtlasAndroidArtifacts.AtlasArtifactType targetType) {\n        this.targetType = targetType;\n    }\n\n    @NonNull\n    public static AtlasAndroidArtifacts.AtlasArtifactType[] getTransformTargets() {\n        return new AtlasAndroidArtifacts.AtlasArtifactType[] {\n                AtlasAndroidArtifacts.AtlasArtifactType.BASE_APK,\n                AtlasAndroidArtifacts.AtlasArtifactType.BASE_MANIFEST,\n                AtlasAndroidArtifacts.AtlasArtifactType.BASE_AWO,\n                AtlasAndroidArtifacts.AtlasArtifactType.BASE_ATLAS_JSON,\n                AtlasAndroidArtifacts.AtlasArtifactType.BASE_REMOTE_BUNDLE,\n                AtlasAndroidArtifacts.AtlasArtifactType.BASE_PACKAGE_IDS,\n                AtlasAndroidArtifacts.AtlasArtifactType.BASE_ARSC,\n                AtlasAndroidArtifacts.AtlasArtifactType.BASE_VERSIONS,\n                AtlasAndroidArtifacts.AtlasArtifactType.BASE_DEPENDENCIES,\n                AtlasAndroidArtifacts.AtlasArtifactType.BASE_R,\n                AtlasAndroidArtifacts.AtlasArtifactType.BASE_APK_FILES,\n                AtlasAndroidArtifacts.AtlasArtifactType.BASE_BUILD_TXT,\n                AtlasAndroidArtifacts.AtlasArtifactType.BASE_MUPP_JSON,\n                AtlasAndroidArtifacts.AtlasArtifactType.MANIFEST,\n\n        };\n    }\n\n    @Override\n    public List<File> transform(File input) {\n        File file;\n\n        file = new File(input,targetType.getType());\n        if (file.exists()) {\n            return Collections.singletonList(file);\n        }\n\n        return Collections.emptyList();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/transforms/ExtractApTransform.java",
    "content": "package com.android.build.gradle.internal.transforms;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.io.ByteStreams;\nimport org.gradle.api.artifacts.transform.ArtifactTransform;\n\nimport java.io.*;\nimport java.util.List;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\n\nimport static com.android.utils.FileUtils.mkdirs;\n\n/**\n * @author lilong\n * @create 2017-11-30 下午10:07\n */\n\npublic class ExtractApTransform extends ArtifactTransform {\n\n    @Override\n    public List<File> transform(File input) {\n        File outputDir = getOutputDirectory();\n        mkdirs(outputDir);\n\n        try (InputStream fis = new BufferedInputStream(new FileInputStream(input));\n             ZipInputStream zis = new ZipInputStream(fis)) {\n            // loop on the entries of the intermediary package and put them in the final package.\n            ZipEntry entry;\n            while ((entry = zis.getNextEntry()) != null) {\n                try {\n                    String name = entry.getName();\n\n                    // do not take directories\n                    if (entry.isDirectory()) {\n                        continue;\n                    }\n                    String path = name;\n\n                    File outputFile = new File(outputDir, path.replace('/', File.separatorChar));\n                    mkdirs(outputFile.getParentFile());\n\n                    try (OutputStream outputStream =\n                                 new BufferedOutputStream(new FileOutputStream(outputFile))) {\n                        ByteStreams.copy(zis, outputStream);\n                        outputStream.flush();\n                    }\n                } finally {\n                    zis.closeEntry();\n                }\n            }\n\n        } catch (Throwable t) {\n            throw new RuntimeException(t);\n        }\n\n        return ImmutableList.of(outputDir);\n        }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/transforms/ExtractAwbTransform.java",
    "content": "package com.android.build.gradle.internal.transforms;\n\nimport com.android.build.gradle.internal.dependency.ExtractAarTransform;\nimport com.taobao.android.builder.AtlasBuildContext;\n\nimport java.io.File;\nimport java.util.List;\n\n/**\n * @author lilong\n * @create 2017-11-30 下午10:36\n */\n\npublic class ExtractAwbTransform extends ExtractAarTransform {\n\n    @Override\n    public List<File> transform(File input) {\n        File outputDirectory = getOutputDirectory();\n        AtlasBuildContext.bundleExploadDir.put(outputDirectory.getParentFile().getName(),outputDirectory);\n        return super.transform(input);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/transforms/ExtractSolibTransform.java",
    "content": "package com.android.build.gradle.internal.transforms;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.io.ByteStreams;\nimport org.gradle.api.artifacts.transform.ArtifactTransform;\n\nimport java.io.*;\nimport java.util.List;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\n\nimport static com.android.utils.FileUtils.mkdirs;\n\n/**\n * @author lilong\n * @create 2017-12-03 下午1:08\n */\n\npublic class ExtractSolibTransform extends ArtifactTransform {\n\n    @Override\n    public List<File> transform(File input) {\n        File outputDir = getOutputDirectory();\n\n        mkdirs(outputDir);\n\n        try (InputStream fis = new BufferedInputStream(new FileInputStream(input));\n             ZipInputStream zis = new ZipInputStream(fis)) {\n            // loop on the entries of the intermediary package and put them in the final package.\n            ZipEntry entry;\n            while ((entry = zis.getNextEntry()) != null) {\n                try {\n                    String name = entry.getName();\n\n                    // do not take directories\n                    if (entry.isDirectory()) {\n                        continue;\n                    }\n                    String path = name;\n\n                    File outputFile = new File(outputDir, path.replace('/', File.separatorChar));\n                    mkdirs(outputFile.getParentFile());\n\n                    try (OutputStream outputStream =\n                                 new BufferedOutputStream(new FileOutputStream(outputFile))) {\n                        ByteStreams.copy(zis, outputStream);\n                        outputStream.flush();\n                    }\n                } finally {\n                    zis.closeEntry();\n                }\n            }\n\n        } catch (Throwable t) {\n            throw new RuntimeException(t);\n        }\n\n        return ImmutableList.of(outputDir);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/transforms/LoadSolibFromLibsTransform.java",
    "content": "package com.android.build.gradle.internal.transforms;\n\nimport com.google.common.collect.ImmutableList;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.artifacts.transform.ArtifactTransform;\n\nimport java.io.File;\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * @author lilong\n * @create 2017-12-03 下午2:20\n */\npublic class LoadSolibFromLibsTransform extends ArtifactTransform {\n\n    @Override\n    public List<File> transform(File input) {\n\n        File libs =  new File(input,\"jars/libs\");\n\n        if (!libs.exists()){\n            return ImmutableList.of();\n        }\n        Collection<File>files = FileUtils.listFiles(libs,new String[]{\"so\"},true);\n\n        if (files != null && files.size() > 0){\n            return ImmutableList.of(libs);\n\n        }\n\n        return ImmutableList.of();\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/internal/transforms/LoadSolibTransform.java",
    "content": "package com.android.build.gradle.internal.transforms;\n\nimport com.google.common.collect.ImmutableList;\nimport org.gradle.api.artifacts.transform.ArtifactTransform;\n\nimport java.io.File;\nimport java.util.List;\n/**\n * @author lilong\n * @create 2017-12-20 下午1:08\n */\n\npublic class LoadSolibTransform extends ArtifactTransform {\n\n    @Override\n    public List<File> transform(File input) {\n        return ImmutableList.of(input);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/tasks/PackageAwb.java",
    "content": "package com.android.build.gradle.tasks;\n\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.internal.incremental.InstantRunPatchingPolicy;\nimport com.android.build.gradle.internal.scope.*;\nimport com.android.builder.utils.FileCache;\nimport org.gradle.api.file.FileCollection;\n\nimport java.io.File;\n\n/**\n * Created by chenhjohn on 2017/5/11.\n *\n * @author chenhjohn\n * @date 2017/05/11\n */\n\npublic class PackageAwb extends PackageAndroidArtifact {\n\n\n    // ----- ConfigAction -----\n\n    /**\n     * Configures the task to perform the \"standard\" packaging, including all\n     * files that should end up in the APK.\n     */\n    public static class StandardConfigAction extends ConfigAction<PackageAwb> {\n\n\n        public StandardConfigAction(PackagingScope packagingScope, File outputDirectory, InstantRunPatchingPolicy patchingPolicy, TaskOutputHolder.TaskOutputType inputResourceFilesType, FileCollection resourceFiles, FileCollection manifests, TaskOutputHolder.TaskOutputType manifestType, FileCache fileCache, OutputScope outputScope) {\n\n            super(packagingScope, outputDirectory, patchingPolicy, inputResourceFilesType, resourceFiles, manifests, manifestType, fileCache, outputScope);\n        }\n\n        @NonNull\n        @Override\n        public String getName() {\n            return packagingScope.getTaskName(\"package\");\n        }\n\n        @NonNull\n        @Override\n        public Class<PackageAwb> getType() {\n            return PackageAwb.class;\n        }\n\n        @Override\n        public void execute(@NonNull final PackageAwb PackageAwb) {\n            ConventionMappingHelper.map(PackageAwb, \"outputFile\", packagingScope::getOutputScope);\n            super.execute(PackageAwb);\n        }\n    }\n\n\n    protected VariantScope.TaskOutputType getTaskOutputType(){\n\n        return TaskOutputHolder.TaskOutputType.APK;\n    }\n\n    @Override\n    void recordMetrics(File outputFile, File resourcesApFile) {\n            //\n        return;\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/build/gradle/tasks/factory/AwbAndroidJavaCompile.java",
    "content": "package com.android.build.gradle.tasks.factory;\n\nimport com.android.build.gradle.internal.incremental.InstantRunBuildContext;\nimport com.android.sdklib.AndroidTargetHash;\nimport com.android.sdklib.AndroidVersion;\nimport com.android.utils.FileUtils;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport org.gradle.api.JavaVersion;\nimport org.gradle.api.tasks.CacheableTask;\nimport org.gradle.api.tasks.incremental.IncrementalTaskInputs;\n\n/**\n * @author lilong\n * @create 2017-12-08 上午3:43\n */\n\n@CacheableTask\npublic class AwbAndroidJavaCompile extends AndroidJavaCompile {\n\n    private static boolean analyticsed = false;\n\n    private AwbBundle awbBundle;\n\n    public void setAwbBundle(AwbBundle awbBundle){\n        this.awbBundle = awbBundle;\n    }\n\n    @Override\n    protected void compile(IncrementalTaskInputs inputs) {\n        getLogger().info(\n                \"Compiling with source level {} and target level {}.\",\n                getSourceCompatibility(),\n                getTargetCompatibility());\n        if (isPostN()) {\n            if (!JavaVersion.current().isJava8Compatible()) {\n                throw new RuntimeException(\"compileSdkVersion '\" + compileSdkVersion + \"' requires \"\n                        + \"JDK 1.8 or later to compile.\");\n            }\n        }\n\n        if (awbBundle.isDataBindEnabled() && !analyticsed) {\n            processAnalytics();\n            analyticsed = true;\n        }\n\n        // Create directory for output of annotation processor.\n        FileUtils.mkdirs(annotationProcessorOutputFolder);\n\n        mInstantRunBuildContext.startRecording(InstantRunBuildContext.TaskType.JAVAC);\n        compile();\n        mInstantRunBuildContext.stopRecording(InstantRunBuildContext.TaskType.JAVAC);\n    }\n\n    private boolean isPostN() {\n        final AndroidVersion hash = AndroidTargetHash.getVersionFromHash(compileSdkVersion);\n        return hash != null && hash.getApiLevel() >= 24;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/builder/core/AtlasAapt.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.builder.core;\n\nimport com.android.build.gradle.internal.dsl.AaptOptions;\nimport com.android.builder.internal.aapt.AaptException;\nimport com.android.builder.internal.aapt.AaptPackageConfig;\nimport com.android.builder.internal.aapt.v1.AaptV1;\nimport com.android.ide.common.process.ProcessExecutor;\nimport com.android.ide.common.process.ProcessInfoBuilder;\nimport com.android.ide.common.process.ProcessOutputHandler;\nimport com.android.sdklib.BuildToolInfo;\nimport com.android.utils.ILogger;\n\nimport org.apache.commons.beanutils.BeanUtils;\nimport org.apache.commons.beanutils.PropertyUtils;\nimport org.apache.commons.lang3.reflect.FieldUtils;\nimport org.gradle.api.GradleException;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.List;\n\n/**\n * Created by wuzhong on 2017/2/6.\n */\npublic class AtlasAapt extends AaptV1 {\n    /**\n     * Creates a new entry point to the original {@code aapt}.\n     *\n     * @param processExecutor      the executor for external processes\n     * @param processOutputHandler the handler to process the executed process' output\n     * @param buildToolInfo        the build tools to use\n     * @param logger               logger to use\n     * @param processMode          the process mode to run {@code aapt} on\n     * @param cruncherProcesses    if using build tools that support crunching processes, how many\n     *                             processes to use; if set to {@code 0}, the default number will be used\n     */\n    public AtlasAapt(ProcessExecutor processExecutor,\n                     ProcessOutputHandler processOutputHandler,\n                     BuildToolInfo buildToolInfo,\n                     ILogger logger,\n                     PngProcessMode processMode,\n                     int cruncherProcesses) {\n        super(processExecutor,\n              processOutputHandler,\n              buildToolInfo,\n              logger,\n              processMode,\n              cruncherProcesses);\n    }\n\n\n\n    @Override\n    protected ProcessInfoBuilder makePackageProcessBuilder(AaptPackageConfig config) throws AaptException {\n        ProcessInfoBuilder processInfoBuilder = super.makePackageProcessBuilder(config);\n\n        List<String> args = null;\n        try {\n            args = (List<String>) FieldUtils.readField(processInfoBuilder, \"mArgs\", true);\n        } catch (IllegalAccessException e) {\n            throw new GradleException(\"getargs exception\", e);\n        }\n\n        //args.remove(\"--no-version-vectors\");\n        //\n        ////Does not generate manifest_keep.txt file\n        //int indexD = args.indexOf(\"-D\");\n        //if (indexD > 0){\n        //    args.remove(indexD);\n        //    args.remove(indexD);\n        //}\n\n        //Join the outputs of the R.txt file\n        String sybolOutputDir = config.getSymbolOutputDir().getAbsolutePath();\n        if (!args.contains(\"--output-text-symbols\") && null != sybolOutputDir) {\n            args.add(\"--output-text-symbols\");\n            args.add(sybolOutputDir);\n        }\n\n        return processInfoBuilder;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/builder/core/AtlasBuilder.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.builder.core;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.gradle.internal.aapt.AaptGeneration;\nimport com.android.build.gradle.options.ProjectOptions;\nimport com.android.builder.internal.aapt.Aapt;\nimport com.android.builder.internal.aapt.AaptPackageConfig;\nimport com.android.builder.internal.aapt.AaptPackageConfig.Builder;\nimport com.android.builder.sdk.SdkInfo;\nimport com.android.builder.symbols.*;\nimport com.android.dex.Dex;\nimport com.android.dx.command.dexer.DxContext;\nimport com.android.dx.merge.CollisionPolicy;\nimport com.android.dx.merge.DexMerger;\nimport com.android.ide.common.process.*;\nimport com.android.manifmerger.ManifestMerger2;\nimport com.android.manifmerger.ManifestProvider;\nimport com.android.manifmerger.MergingReport;\nimport com.android.sdklib.BuildToolInfo;\nimport com.android.sdklib.BuildToolInfo.PathId;\nimport com.android.utils.ILogger;\nimport com.google.common.collect.Table;\nimport com.taobao.android.AaptLib;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.tasks.app.bundle.AtlasSymbolIo;\nimport com.taobao.android.builder.tools.*;\nimport com.taobao.android.builder.tools.cache.FileCacheCenter;\nimport com.taobao.android.builder.tools.cache.FileCacheException;\nimport com.taobao.android.builder.tools.zip.ZipUtils;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.FilenameUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.GradleException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.File;\nimport java.io.FilenameFilter;\nimport java.io.IOException;\nimport java.lang.reflect.Method;\nimport java.util.*;\n\n/**\n * 1. Custom Android BuilderTool classes that support custom aapt operations\n * 2. Cache optimization for dex , Adjust the dexOptions parameter\n */\npublic class AtlasBuilder extends AndroidBuilder {\n\n    private static final Logger sLogger = LoggerFactory.getLogger(AtlasBuilder.class);\n\n    public static final String PRE_DEXCACHE_TYPE = \"pre-dex-0.11\";\n\n    protected AtlasExtension atlasExtension;\n\n    public MultiDexer multiDexer;\n\n    protected AndroidBuilder defaultBuilder;\n\n    private DexByteCodeConverter dexByteCodeConverter;\n\n    private final JavaProcessExecutor javaProcessExecutor;\n\n    public List<ManifestProvider>manifestProviders;\n\n    private final ILogger logger;\n\n    private final boolean verboseExec;\n    private boolean useMyDex;\n\n    private AaptGeneration aaptGeneration;\n\n    /**\n     * Creates an AndroidBuilder.\n     * <p/>\n     * <var>verboseExec</var> is needed on top of the ILogger due to remote exec tools not being\n     * able to output info and verbose messages separately.\n     *\n     * @param projectId\n     * @param createdBy           the createdBy String for the apk manifest.\n     * @param processExecutor\n     * @param javaProcessExecutor\n     * @param errorReporter\n     * @param logger              the Logger\n     * @param verboseExec         whether external tools are launched in verbose mode\n     */\n    public AtlasBuilder(@NonNull String projectId,\n                        @Nullable String createdBy,\n                        @NonNull ProcessExecutor processExecutor,\n                        @NonNull JavaProcessExecutor javaProcessExecutor,\n                        @NonNull ErrorReporter errorReporter,\n                        @NonNull ILogger logger,\n                        boolean verboseExec) {\n        super(projectId,\n              createdBy,\n              processExecutor,\n              javaProcessExecutor,\n              errorReporter,\n              logger,\n              verboseExec);\n        this.javaProcessExecutor = javaProcessExecutor;\n        this.verboseExec = verboseExec;\n        this.logger = logger;\n    }\n\n    public void initAapt(ProjectOptions projectOptions){\n        super.setTargetInfo(defaultBuilder.getTargetInfo());\n        super.setSdkInfo(defaultBuilder.getSdkInfo());\n        super.setLibraryRequests((Collection<LibraryRequest>) ReflectUtils.getField(defaultBuilder,\"mLibraryRequests\"));\n        boolean updateAapt = atlasExtension.getTBuildConfig().getUseCustomAapt();\n        aaptGeneration = AaptGeneration.fromProjectOptions(projectOptions);\n        switch (aaptGeneration){\n            case AAPT_V1:\n                if (updateAapt){\n                    updateAapt(PathId.AAPT);\n                }\n                break;\n            // case AAPT_V2:\n            //     if (updateAapt){\n            //         updateAapt(PathId.AAPT2);\n            //     }\n            //     break;\n            // case AAPT_V2_DAEMON_MODE:\n            //     if (updateAapt){\n            //         updateAapt(PathId.DAEMON_AAPT2);\n            //     }\n            //     break;\n            //\n            // case AAPT_V2_JNI:\n            //     if (updateAapt) {\n            //         updateAapt(PathId.DAEMON_AAPT2);\n            //     }\n            //     break;\n                default:break;\n        }\n\n    }\n\n    public AtlasExtension getAtlasExtension() {\n        return atlasExtension;\n    }\n\n    public void setAtlasExtension(AtlasExtension atlasExtension) {\n        this.atlasExtension = atlasExtension;\n    }\n\n    public AndroidBuilder getDefaultBuilder() {\n        return defaultBuilder;\n    }\n\n    public void setDefaultBuilder(AndroidBuilder defaultBuilder) {\n        this.defaultBuilder = defaultBuilder;\n    }\n\n    @Override\n    public void processResources(Aapt aapt,\n                                 Builder aaptConfigBuilder)\n        throws IOException, InterruptedException, ProcessException {\n        String s;\n\n        if (aaptGeneration == AaptGeneration.AAPT_V1) {\n            s = \"--non-constant-id\";\n\n        } else {\n            s = \"--non-final-ids\";\n        }\n\n        if (!atlasExtension.getTBuildConfig().getAaptConstantId() && !aaptConfigBuilder.build()\n            .getOptions()\n            .getAdditionalParameters()\n            .contains(s)) {\n            aaptConfigBuilder.build().getOptions().getAdditionalParameters().add(s);\n        } else {\n            while (aaptConfigBuilder.build().getOptions().getAdditionalParameters().contains(s)){\n                aaptConfigBuilder.build().getOptions().getAdditionalParameters().remove(s);\n            }\n        }\n\n        super.processResources(aapt, aaptConfigBuilder);\n\n\n        File symboFile = new File(aaptConfigBuilder.build().getSymbolOutputDir(),\"R.txt\");\n        if (!symboFile.exists()){\n            throw new ProcessException(symboFile.getAbsolutePath() + \"is not exist!\");\n        }\n\n\n    }\n\n\n\n\n    /**\n     * Deal with awb resources\n     *  @param aaptCommand\n     * @param enforceUniquePackageName\n     * @param processOutputHandler\n     * @param mainSymbolFile\n     */\n    public void processAwbResources(Aapt aapt,AaptPackageConfig.Builder aaptConfigBuilder,\n                                    File mainSymbolFile,File awbSymbolFile,String pacakgeName) throws IOException, ProcessException {\n        aaptConfigBuilder.setBuildToolInfo(getTargetInfo().getBuildTools());\n        aaptConfigBuilder.setAndroidTarget(getTargetInfo().getTarget());\n        aaptConfigBuilder.setLogger(logger);\n            logger.info(\"Aapt output file {}\");\n            AaptPackageConfig aaptConfig = aaptConfigBuilder.build();\n\n        try {\n            aapt.link(aaptConfig).get();\n        } catch (Exception e) {\n            throw new ProcessException(\"Failed to execute aapt\", e);\n        }\n        File sourceOut = aaptConfig.getSourceOutputDir();\n        if (sourceOut != null) {\n            // Figure out what the main symbol file's package is.\n            String mainPackageName = aaptConfig.getCustomPackageForR();\n            if (mainPackageName == null) {\n                mainPackageName =\n                        SymbolUtils.getPackageNameFromManifest(aaptConfig.getManifestFile());\n            }\n\n            // Load the main symbol file.\n            File mainRTxt = new File(aaptConfig.getSymbolOutputDir(), \"R.txt\");\n            File mergedSymbolFile = new File(aaptConfig.getSymbolOutputDir(), \"R-all.txt\");\n            try {\n                sLogger.info(\"awbSymbolFile:\" + mainRTxt);\n                if (null != mainRTxt && mainRTxt.exists()) {\n                    FileUtils.copyFile(mainRTxt, mergedSymbolFile);\n                }else {\n                    throw new ProcessException(mainRTxt.getAbsolutePath() + \"is not exist, maybe no resources in this bundle! \");\n                }\n\n                SymbolTable awbSymbols = build(awbSymbolFile,mainPackageName,mainRTxt,mainSymbolFile,pacakgeName);\n                if (awbSymbols!= null) {\n                    AtlasSymbolIo.write(awbSymbols, mergedSymbolFile);\n                }\n\n                //why do this? youku need use this !\n//                FileUtils.writeLines(mergedSymbolFile, FileUtils.readLines(mainSymbolFile), true);\n            } catch (IOException e) {\n                throw new RuntimeException(\"Could not load file \", e);\n            }\n\n            SymbolTable mainSymbols =\n                    mergedSymbolFile.isFile()\n                            ? AtlasSymbolIo.readFromAapt(mergedSymbolFile, mainPackageName)\n                            : SymbolTable.builder().tablePackage(mainPackageName).build();\n\n\n            // For each dependency, load its symbol file.\n            Set<SymbolTable> depSymbolTables =\n                    SymbolUtils.loadDependenciesSymbolTables(\n                            aaptConfig.getLibrarySymbolTableFiles(), mainPackageName);\n\n            boolean finalIds = true;\n            if (aaptConfig.getVariantType() == VariantType.LIBRARY) {\n                finalIds = false;\n            }\n\n\n            SymbolIo.exportToJava(mainSymbols, sourceOut, finalIds);\n\n            RGeneration.generateRForLibraries(mainSymbols, depSymbolTables, sourceOut, finalIds);\n        }\n    }\n\n\n\n    /**\n     * Get the custom buildToolInfo\n     *\n     * @param targetInfo\n     * @return\n     */\n\n\n    public void updateAapt(PathId pathId) {\n\n        if (null == defaultBuilder.getTargetInfo()) {\n            return;\n            }\n            BuildToolInfo defaultBuildToolInfo = defaultBuilder.getTargetInfo().getBuildTools();\n            File customAaptFile = getAapt();\n            try {\n                Method method = defaultBuildToolInfo.getClass()\n                    .getDeclaredMethod(\"add\", PathId.class, File.class);\n                method.setAccessible(true);\n                method.invoke(defaultBuildToolInfo, pathId, customAaptFile);\n            } catch (Throwable e) {\n                throw new GradleException(e.getMessage());\n            }\n     }\n\n    @Override\n    @NonNull\n    public List<String> getBootClasspathAsStrings(boolean includeOptionalLibraries) {\n\n        return defaultBuilder.getBootClasspathAsStrings(includeOptionalLibraries);\n\n    }\n\n\n    private File getAapt() {\n\n        String osName = \"mac\";\n        String fileName = \"aapt\";\n\n        if (StringUtils.containsIgnoreCase(System.getProperty(\"os.name\"), \"Mac\")) {\n            osName = \"mac\";\n        } else if (StringUtils.containsIgnoreCase(System.getProperty(\"os.name\"), \"Linux\")) {\n            osName = \"linux\";\n        } else if (StringUtils.containsIgnoreCase(System.getProperty(\"os.name\"), \"windows\")) {\n            osName = \"win\";\n            fileName = \"aapt.exe\";\n        }\n        String aaptPath = \"aapt/\" + osName + \"/\" + fileName;\n        File aaptFile = new File(AaptLib.class.getClassLoader().getResource(aaptPath).getFile());\n        if (aaptFile.isFile()) {\n            return aaptFile;\n        }\n\n        File jarFile = PathUtil.getJarFile(AaptLib.class);\n        File jarFolder = new File(jarFile.getParentFile(),\n                                  FilenameUtils.getBaseName(jarFile.getName()));\n        jarFolder.mkdirs();\n        aaptFile = new File(jarFolder, fileName);\n\n        if (!aaptFile.exists()) {\n            aaptFile = ZipUtils.extractZipFileToFolder(jarFile, aaptPath,\n                                                       aaptFile.getParentFile());\n            aaptFile.setExecutable(true);\n        }\n        return aaptFile;\n    }\n\n    //dexMain entrance\n    public void convertByteCode(Collection<File> inputs,\n                                File outDexFolder,\n                                boolean multidex,\n                                File mainDexList,\n                                DexOptions dexOptions,\n                                ProcessOutputHandler processOutputHandler, boolean awb)\n        throws IOException, InterruptedException, ProcessException {\n\n        boolean fastMultiDex = false;\n\n        Profiler.start();\n\n        if (atlasExtension.getTBuildConfig().isDexCacheEnabled() && inputs.size() > 0) {\n\n            Profiler.enter(\"jar2dex\");\n\n            List<Dex> dexs = new ArrayList<>();\n            Map<File, Dex> fileDexMap = new HashMap<>();\n\n            //Do dexMerge\n            File tmpDir = new File(outDexFolder, \"tmp\");\n            tmpDir.mkdirs();\n\n            long startTime = System.currentTimeMillis();\n\n            List<File> outputs = new ArrayList<>();\n\n                for (File input : inputs) {\n                    logger.warning(\"Dex input File:%s\",input.getAbsolutePath());\n\n                    final File dexDir = getDexOutputDir(input, tmpDir, outputs);\n                    dexDir.mkdirs();\n\n                    preDexLibrary(input, dexDir, multidex, dexOptions, processOutputHandler);\n\n                    outputs.add(dexDir);\n            }\n\n                for (File dexDir : outputs) {\n                Collection<File> files = FileUtils.listFiles(dexDir,new String[]{\"dex\"},true);\n                for (File dexFile : files) {\n                    if (dexFile.exists() && dexFile.length() > 0) {\n                        Dex dex = new Dex(dexFile);\n                        dexs.add(dex);\n                        fileDexMap.put(dexFile, dex);\n                    }\n                }\n            }\n\n            Profiler.release();\n            long endDexTime = System.currentTimeMillis();\n\n            Profiler.enter(\"dexmerge\");\n            if (dexs.size() > 0) {\n\n                    if (multidex && !awb) {\n\n                        throw new GradleException(\"can't support~\");\n\n                    } else {\n\n                        DexMerger dexMerger = new DexMerger(dexs.toArray(new Dex[0]),\n                                                            CollisionPolicy.KEEP_FIRST, new DxContext());\n                        Dex dex = dexMerger.merge();\n\n                        File dexFile = new File(outDexFolder, \"classes.dex\");\n\n                        dex.writeTo(dexFile);\n\n                        if (!dexFile.exists()) {\n                            sLogger.error(\"dexmerge failed, not dex file found , inputs : \" + dexs.size());\n                        }\n                    }\n\n\n\n            } else {\n                sLogger.error(\"no dex found to  \" + outDexFolder.getAbsolutePath());\n            }\n            Profiler.release();\n\n            FileUtils.deleteDirectory(tmpDir);\n\n            long finishTime = System.currentTimeMillis();\n\n            sLogger.info(\"[mtldex] dex consume {} , dexmerge consume {}\",\n                         endDexTime - startTime,\n                         finishTime - endDexTime);\n        }\n        Profiler.release();\n        if (fastMultiDex) {\n            sLogger.error(\"[mtldex] main dex consume {} \", Profiler.dump());\n        }\n\n    }\n\n    private File getDexOutputDir(File input, File rootDir, List<File> outputs) {\n        File dexDir = null;\n        if (input.isFile() && input.getName().endsWith(\"jar\")) {\n            dexDir = new File(rootDir, FileNameUtils.getUniqueJarName(input));\n        } else {\n            dexDir = new File(rootDir, \"dexDir\" + outputs.size());\n        }\n        return dexDir;\n    }\n\n\n\n    public void preDexLibrary(@NonNull File inputFile,\n                              @NonNull File outFile,\n                              boolean multiDex,\n                              @NonNull DexOptions dexOptions,\n                              @NonNull ProcessOutputHandler processOutputHandler)\n        throws IOException, InterruptedException, ProcessException {\n\n        if (!atlasExtension.getTBuildConfig().isDexCacheEnabled() || multiDex) {\n            super.preDexLibrary(inputFile, outFile, multiDex, dexOptions, processOutputHandler,14);\n            return;\n        }\n\n        String md5 = \"\";\n        File dexFile = new File(outFile, \"classes.dex\");\n\n        if (!inputFile.getName().startsWith(\"combined\") && !(inputFile.getName().startsWith(\"main\") && inputFile\n            .getName().endsWith(\"jar\")) && inputFile.isFile()) {\n\n            if (inputFile.isFile()) {\n                md5 = MD5Util.getFileMD5(inputFile);\n            } else if (inputFile.isDirectory()) {\n                md5 = MD5Util.getFileMd5(FileUtils.listFiles(inputFile,\n                                                             new String[] {\"class\"},\n                                                             true));\n            }\n\n            //TODO md5 with other\n            if (StringUtils.isNotEmpty(md5)) {\n\n                String other = \"\" + dexOptions.getAdditionalParameters().contains(\"--useMyDex\") + dexOptions\n                    .getJumboMode() + dexOptions.getKeepRuntimeAnnotatedClasses();\n\n                try {\n                    md5 = MD5Util.getMD5(other + md5);\n                } catch (Exception e) {\n                    throw new GradleException(e.getMessage(), e);\n                }\n\n                try {\n                    FileCacheCenter.fetchFile(PRE_DEXCACHE_TYPE, md5, false,\n                                              atlasExtension.getTBuildConfig().isDexNetworkCacheEnabled(), dexFile);\n                } catch (FileCacheException e) {\n                    sLogger.error(e.getMessage(), e);\n                }\n\n                if (dexFile.exists() && dexFile.length() > 0) {\n                    sLogger.info(\"[mtldex] hit cache dex for {} , {}\",\n                                 inputFile.getAbsolutePath(),\n                                 dexFile.getAbsolutePath());\n                    return;\n                } else {\n                    sLogger.info(\"[mtldex] discache dex for {}\", inputFile.getAbsolutePath());\n                }\n            }\n        } else {\n            //R Too much, you need to start multi-dex\n        }\n\n        multiDex = false;\n\n        dexFile.delete();\n\n        //todo  Set the dexOptions\n        DefaultDexOptions defaultDexOptions = DefaultDexOptions.copyOf(dexOptions);\n\n        if (!multiDex) {\n            defaultDexOptions.setJavaMaxHeapSize(\"500m\");\n            defaultDexOptions.setDexInProcess(true);\n            defaultDexOptions.getAdditionalParameters().remove(\"--multi-dex\");\n        }\n\n        sLogger.info(\"[mtldex] pre dex for {} {}\",\n                     inputFile.getAbsolutePath(),\n                     outFile.getAbsolutePath());\n\n        super.preDexLibrary(inputFile, outFile, multiDex, defaultDexOptions, processOutputHandler,14);\n\n        if (multiDex) {\n            return;\n        }\n\n        if (!dexFile.exists() || dexFile.length() == 0) {\n            sLogger.warn(\"dex failed \" + dexFile.getAbsolutePath() + \"->\" + inputFile.getAbsolutePath());\n            return;\n        }\n\n        sLogger.warn(\"dex success \" + dexFile.getAbsolutePath() + \"->\" + inputFile.getAbsolutePath());\n\n        if (StringUtils.isNotEmpty(md5) && dexFile.exists()) {\n            try {\n                FileCacheCenter.cacheFile(PRE_DEXCACHE_TYPE, md5, dexFile,\n                                          AtlasBuildContext.sBuilderAdapter.pushCacheToNetwork && atlasExtension\n                                              .getTBuildConfig().isDexNetworkCacheEnabled());\n            } catch (FileCacheException e) {\n                sLogger.error(e.getMessage(), e);\n            }\n\n        }\n    }\n\n    @Override\n    public SdkInfo getSdkInfo() {\n        return defaultBuilder.getSdkInfo();\n    }\n\n    @Override\n    public MergingReport mergeManifestsForApplication(\n            @NonNull File mainManifest,\n            @NonNull List<File> manifestOverlays,\n            @NonNull List<? extends ManifestProvider> dependencies,\n            @Nullable String featureName,\n            String packageOverride,\n            int versionCode,\n            String versionName,\n            @Nullable String minSdkVersion,\n            @Nullable String targetSdkVersion,\n            @Nullable Integer maxSdkVersion,\n            @NonNull String outManifestLocation,\n            @Nullable String outAaptSafeManifestLocation,\n            @Nullable String outInstantRunManifestLocation,\n            ManifestMerger2.MergeType mergeType,\n            Map<String, Object> placeHolders,\n            @NonNull List<ManifestMerger2.Invoker.Feature> optionalFeatures,\n            @Nullable File reportFile) {\n\n\n        return super.mergeManifestsForApplication(\n                mainManifest,\n                manifestOverlays,\n                manifestProviders,\n                featureName,\n                packageOverride,\n                versionCode,\n                versionName,\n                minSdkVersion,\n                targetSdkVersion,\n                maxSdkVersion,\n                outManifestLocation,\n                outAaptSafeManifestLocation,\n                outInstantRunManifestLocation,\n                mergeType,\n                placeHolders,\n                optionalFeatures,\n                reportFile);\n\n    }\n\n\n    public static interface MultiDexer {\n\n        public Collection<File> repackageJarList(Collection<File> files, File mainDexListFile, boolean release) throws IOException;\n\n        public void dexMerge(Map<File, Dex> fileDexMap, File outDexFolder) throws IOException;\n\n    }\n\n\n    private SymbolTable build(File awbSymbolFile, String mainPackageName,File mainRTxt,File mainSymbolFile,String pacakgeName) throws IOException {\n        SymbolTable.Builder builder = new SymbolTable.Builder();\n        SymbolTable awbSymbols = null;\n        if (awbSymbolFile.exists()){\n            awbSymbols = AtlasSymbolIo.readFromAapt(awbSymbolFile, mainPackageName);\n            awbSymbols.getSymbols().values().forEach(symbol -> builder.add(symbol));\n        };\n\n        if (mainRTxt.exists()) {\n            SymbolTable generateAwbSymbols = AtlasSymbolIo.readFromAapt(mainRTxt, mainPackageName);\n            generateAwbSymbols.getSymbols().values().forEach(symbol -> {\n                if (builder.contains(symbol)) {\n                    removeSymbol(builder, symbol);\n                }\n                builder.add(symbol);\n\n            });\n\n        }\n\n        SymbolTable mainSymbols = AtlasSymbolIo.readFromAapt(mainSymbolFile, pacakgeName);\n        mainSymbols.getSymbols().values().forEach(symbol -> {\n            if (builder.contains(symbol)){\n                removeSymbol(builder,symbol);\n                builder.add(symbol);\n            }\n        });\n\n\n        return builder.build();\n    }\n\n    private void removeSymbol(SymbolTable.Builder builder, Symbol symbol) {\n        Table table = (Table) ReflectUtils.getField(builder,\"symbols\");\n        table.remove(symbol.getResourceType(),symbol.getName());\n    }\n\n\n\n\n    public void writeLines(File file,List<String>lines,boolean append){\n         Set<String>mergeLines = new LinkedHashSet<>();\n        try {\n            List<String> readLines = FileUtils.readLines(file);\n            mergeLines.addAll(readLines);\n            mergeLines.addAll(lines);\n            FileUtils.writeLines(file,mergeLines,append);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n\n    }\n\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/ide/common/process/CmdExecutor.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.ide.common.process;\n\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.utils.ILogger;\n\n/**\n * Created by wuzhong on 2017/2/15.\n */\npublic class CmdExecutor {\n\n    //private static ILogger sLogger = new ILogger() {\n    //    @Override\n    //    public void error(Throwable t, String msgFormat, Object... args) {\n    //        System.out.println(msgFormat);\n    //    }\n    //\n    //    @Override\n    //    public void warning(String msgFormat, Object... args) {\n    //        System.out.println(msgFormat);\n    //    }\n    //\n    //    @Override\n    //    public void info(String msgFormat, Object... args) {\n    //        System.out.println(msgFormat);\n    //    }\n    //\n    //    @Override\n    //    public void verbose(String msgFormat, Object... args) {\n    //        System.out.println(msgFormat);\n    //    }\n    //};\n\n    private static ILogger sLogger = LoggerWrapper.getLogger(CmdExecutor.class);\n    \n    private static final MtlProcessExecutor mProcessExecutor = new MtlProcessExecutor(sLogger);\n\n    private static final ProcessOutputHandler processOutputHandler = new LoggedProcessOutputHandler(\n            sLogger);\n\n    public static boolean execute(String workspace, String cmd, String... args) {\n\n        MtlProcessInfoBuilder builder = new MtlProcessInfoBuilder();\n\n        builder.setExecutable(cmd);\n        builder.addArgs(args);\n\n        builder.setWorkspace(workspace);\n\n        ProcessResult result = mProcessExecutor.execute(builder.createProcess(),\n                                                        processOutputHandler);\n\n        try {\n            result.rethrowFailure().assertNormalExitValue();\n        } catch (ProcessException e) {\n            return false;\n        }\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/ide/common/process/MtlProcessExecutor.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.ide.common.process;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.utils.ILogger;\nimport com.google.common.base.Joiner;\nimport com.google.common.collect.Lists;\nimport com.google.common.io.ByteStreams;\nimport com.google.common.util.concurrent.FutureCallback;\nimport com.google.common.util.concurrent.Futures;\nimport com.google.common.util.concurrent.ListenableFuture;\nimport com.google.common.util.concurrent.SettableFuture;\n\nimport org.apache.commons.lang.StringUtils;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicReference;\n\n/**\n * Created by wuzhong on 2017/2/16.\n */\npublic class MtlProcessExecutor extends DefaultProcessExecutor {\n\n    private ILogger mLogger;\n\n    public MtlProcessExecutor(ILogger logger) {\n        super(logger);\n        this.mLogger = logger;\n    }\n\n    public ListenableFuture<ProcessResult> submit(@NonNull ProcessInfo processInfo,\n                                                  @NonNull final ProcessOutputHandler processOutputHandler) {\n        final List<String> command = buildCommand(processInfo);\n        mLogger.info(\"command: \" + Joiner.on(' ').join(command));\n\n        final SettableFuture<ProcessResult> result = SettableFuture.create();\n\n        try {\n            // Launch the command line process.\n            ProcessBuilder processBuilder = new ProcessBuilder(buildCommand(processInfo));\n\n            Map<String, Object> envVariableMap = processInfo.getEnvironment();\n\n            if (!envVariableMap.isEmpty()) {\n                Map<String, String> env = processBuilder.environment();\n                for (Map.Entry<String, Object> entry : envVariableMap.entrySet()) {\n                    env.put(entry.getKey(), entry.getValue().toString());\n                }\n            }else {\n                Map<String, String> env = processBuilder.environment();\n                env.putAll(System.getenv());\n            }\n\n            if (processInfo instanceof MtlProcessInfo) {\n                MtlProcessInfo mtlProcessInfo = (MtlProcessInfo) processInfo;\n                if (StringUtils.isNotEmpty(mtlProcessInfo.getWorkspace())) {\n                    processBuilder.directory(new File(mtlProcessInfo.getWorkspace()));\n                }\n            }\n\n            // Start the process.\n            Process process = processBuilder.start();\n\n            // Grab the output, and the exit code.\n            final ProcessOutput output = processOutputHandler.createOutput();\n            ListenableFuture<Integer> outputFuture = grabProcessOutput(process, output);\n\n            Futures.addCallback(outputFuture, new FutureCallback<Integer>() {\n                @Override\n                public void onSuccess(Integer exit) {\n                    try {\n                        output.close();\n                        processOutputHandler.handleOutput(output);\n                        result.set(new ProcessResultImpl(command, exit));\n                    } catch (Exception e) {\n                        result.set(new ProcessResultImpl(command, e));\n                    }\n                }\n\n                @Override\n                public void onFailure(@Nullable Throwable t) {\n                    result.set(new ProcessResultImpl(command, t));\n                }\n            });\n        } catch (Exception e) {\n            result.set(new ProcessResultImpl(command, e));\n        }\n\n        return result;\n    }\n\n    private static ListenableFuture<Integer> grabProcessOutput(@NonNull final Process process,\n                                                               @NonNull final ProcessOutput output) {\n        final SettableFuture<Integer> result = SettableFuture.create();\n        final AtomicReference<Exception> exceptionHolder = new AtomicReference<Exception>();\n\n        /*\n         * It looks like on windows process#waitFor() can return before the thread have filled the\n         * arrays, so we wait for both threads and the process itself.\n         *\n         * To make sure everything is complete before setting the future, the thread handling\n         * \"out\" will wait for all its input to be read, will wait for the \"err\" thread to finish\n         * and will wait for the process to finish. Only after all three are done will it set\n         * the future and terminate.\n         *\n         * This means that the future will be set while the \"out\" thread is still running, but\n         * no output is pending and the process has already finished.\n         */\n        final Thread threadErr = new Thread(\"stderr\") {\n            @Override\n            public void run() {\n                InputStream stderr = process.getErrorStream();\n                OutputStream stream = output.getErrorOutput();\n\n                try {\n                    ByteStreams.copy(stderr, stream);\n                    stream.flush();\n                } catch (IOException e) {\n                    exceptionHolder.compareAndSet(null, e);\n                }\n            }\n        };\n\n        Thread threadOut = new Thread(\"stdout\") {\n            @Override\n            public void run() {\n                InputStream stdout = process.getInputStream();\n                OutputStream stream = output.getStandardOutput();\n\n                try {\n                    ByteStreams.copy(stdout, stream);\n                    stream.flush();\n                } catch (Exception e) {\n                    exceptionHolder.compareAndSet(null, e);\n                }\n\n                try {\n                    threadErr.join();\n                    int processResult = process.waitFor();\n                    if (exceptionHolder.get() != null) {\n                        result.setException(exceptionHolder.get());\n                    }\n\n                    result.set(processResult);\n                    output.close();\n                } catch (Exception e) {\n                    result.setException(e);\n                }\n            }\n        };\n\n        threadErr.start();\n        threadOut.start();\n\n        return result;\n    }\n\n    private static List<String> buildCommand(@NonNull ProcessInfo processInfo) {\n        List<String> command = Lists.newArrayList();\n        command.add(processInfo.getExecutable());\n        command.addAll(processInfo.getArgs());\n        return command;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/ide/common/process/MtlProcessInfo.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.ide.common.process;\n\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Created by wuzhong on 2017/2/16.\n */\npublic class MtlProcessInfo implements ProcessInfo {\n\n    private ProcessInfo processInfo;\n\n    private String workspace;\n\n    public MtlProcessInfo(ProcessInfo processInfo, String workspace) {\n        this.processInfo = processInfo;\n        this.workspace = workspace;\n    }\n\n    @Override\n    public String getExecutable() {\n        return processInfo.getExecutable();\n    }\n\n    @Override\n    public List<String> getArgs() {\n        return processInfo.getArgs();\n    }\n\n    @Override\n    public Map<String, Object> getEnvironment() {\n        return processInfo.getEnvironment();\n    }\n\n    public String getWorkspace() {\n        return workspace;\n    }\n\n    public void setWorkspace(String workspace) {\n        this.workspace = workspace;\n    }\n\n    @Override\n    public String getDescription() {\n        return processInfo.getDescription();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/ide/common/process/MtlProcessInfoBuilder.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.android.ide.common.process;\n\n/**\n * Created by wuzhong on 2017/2/16.\n */\npublic class MtlProcessInfoBuilder extends ProcessInfoBuilder {\n\n    private String workspace;\n\n    public String getWorkspace() {\n        return workspace;\n    }\n\n    public void setWorkspace(String workspace) {\n        this.workspace = workspace;\n    }\n\n    public MtlProcessInfo createProcess() {\n\n        MtlProcessInfo mtlProcessInfo = new MtlProcessInfo(super.createProcess(), workspace);\n\n        return mtlProcessInfo;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/tools/r8/AtlasD8.java",
    "content": "package com.android.tools.r8;\nimport com.android.tools.r8.dex.ApplicationReader;\nimport com.android.tools.r8.dex.AtlasApplicationWriter;\nimport com.android.tools.r8.dex.Marker;\nimport com.android.tools.r8.errors.CompilationError;\nimport com.android.tools.r8.errors.MainDexError;\nimport com.android.tools.r8.graph.AppInfo;\nimport com.android.tools.r8.graph.DexApplication;\nimport com.android.tools.r8.ir.conversion.IRConverter;\nimport com.android.tools.r8.naming.NamingLens;\nimport com.android.tools.r8.utils.*;\n\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStreamWriter;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.FileAlreadyExistsException;\nimport java.nio.file.NoSuchFileException;\nimport java.nio.file.Paths;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.ExecutorService;\n\n/**\n * AtlasD8\n *\n * @author zhayu.ll\n * @date 18/4/3\n */\npublic class AtlasD8 {\n    private static final String VERSION = \"v0.1.14\";\n    private static final int STATUS_ERROR = 1;\n\n    public static boolean deepShrink = false;\n\n    private AtlasD8() {\n\n    }\n\n    public static D8Output run(D8Command command) throws IOException {\n        InternalOptions options = command.getInternalOptions();\n        options.skipDebugInfoOpt = true;\n        options.skipDebugLineNumberOpt = true;\n        options.printTimes = true;\n        CompilationResult result = runForTesting(command.getInputApp(), options);\n\n        assert result != null;\n\n        D8Output output = new D8Output(result.androidApp, command.getOutputMode());\n        if (command.getOutputPath() != null) {\n            output.write(command.getOutputPath());\n        }\n\n        return output;\n    }\n\n    public static D8Output run(D8Command command, ExecutorService executor) throws IOException {\n        InternalOptions options = command.getInternalOptions();\n\n        options.skipDebugLineNumberOpt = true;\n        options.skipDebugInfoOpt = true;\n        options.printTimes = true;\n        CompilationResult result = runForTesting(command.getInputApp(), options, executor);\n\n        assert result != null;\n\n        D8Output output = new D8Output(result.androidApp, command.getOutputMode());\n        if (command.getOutputPath() != null) {\n            output.write(command.getOutputPath());\n        }\n\n        return output;\n    }\n\n    private static void run(String[] args) throws IOException, CompilationException {\n        D8Command.Builder builder = D8Command.parse(args);\n        if (builder.getOutputPath() == null) {\n            builder.setOutputPath(Paths.get(\".\"));\n        }\n\n        D8Command command = builder.build();\n        if (command.isPrintHelp()) {\n            System.out.println(D8Command.USAGE_MESSAGE);\n        } else if (command.isPrintVersion()) {\n            System.out.println(\"D8 v0.1.14\");\n        } else {\n            run(command);\n        }\n    }\n\n    public static void main(String[] args) throws IOException {\n        if (args.length == 0) {\n            System.err.println(D8Command.USAGE_MESSAGE);\n            System.exit(1);\n        }\n\n        try {\n            run(args);\n        } catch (NoSuchFileException var3) {\n            System.err.println(\"File not found: \" + var3.getFile());\n            System.exit(1);\n        } catch (FileAlreadyExistsException var4) {\n            System.err.println(\"File already exists: \" + var4.getFile());\n            System.exit(1);\n        } catch (IOException var5) {\n            System.err.println(\"Failed to read or write application files: \" + var5.getMessage());\n            System.exit(1);\n        } catch (RuntimeException var6) {\n            System.err.println(\"Compilation failed with an internal error.\");\n            Throwable cause = var6.getCause() == null ? var6 : var6.getCause();\n            ((Throwable)cause).printStackTrace();\n            System.exit(1);\n        } catch (CompilationException var7) {\n            System.err.println(\"Compilation failed: \" + var7.getMessage());\n            System.err.println(D8Command.USAGE_MESSAGE);\n            System.exit(1);\n        }\n\n    }\n\n    static CompilationResult runForTesting(AndroidApp inputApp, InternalOptions options) throws IOException {\n        ExecutorService executor = ThreadUtils.getExecutorService(options);\n\n        CompilationResult var3;\n        try {\n            var3 = runForTesting(inputApp, options, executor);\n        } finally {\n            executor.shutdown();\n        }\n\n        return var3;\n    }\n\n    private static Marker getMarker(InternalOptions options) {\n        return options.hasMarker() ? options.getMarker() : (new Marker(Marker.Tool.D8)).put(\"version\", \"v0.1.14\").put(\"min-api\", options.minApiLevel);\n    }\n\n    private static CompilationResult runForTesting(AndroidApp inputApp, InternalOptions options, ExecutorService executor) throws IOException {\n        try {\n            assert !inputApp.hasPackageDistribution();\n\n            options.skipMinification = true;\n            options.inlineAccessors = false;\n            options.outline.enabled = false;\n            Timing timing = new Timing(\"DX timer\");\n            DexApplication app = (new ApplicationReader(inputApp, options, timing)).read(executor);\n            AppInfo appInfo = new AppInfo(app);\n            app = optimize(app, appInfo, options, timing, executor);\n            if (options.hasMethodsFilter()) {\n                System.out.println(\"Finished compilation with method filter: \");\n                options.methodsFilter.forEach((m) -> {\n                    System.out.println(\"  - \" + m);\n                });\n                return null;\n            } else {\n                Marker marker = getMarker(options);\n                CompilationResult output = new CompilationResult((new AtlasApplicationWriter(app, appInfo, options, marker, (byte[])null, NamingLens.getIdentityLens(), (byte[])null)).write((PackageDistribution)null, executor), app, appInfo);\n                options.printWarnings();\n                return output;\n            }\n        } catch (MainDexError var8) {\n            throw new CompilationError(var8.getMessageForD8());\n        } catch (ExecutionException var9) {\n            if (var9.getCause() instanceof CompilationError) {\n                throw (CompilationError)var9.getCause();\n            } else {\n                throw new RuntimeException(var9.getMessage(), var9.getCause());\n            }\n        }\n    }\n\n    private static DexApplication optimize(DexApplication application, AppInfo appInfo, InternalOptions options, Timing timing, ExecutorService executor) throws IOException, ExecutionException {\n        CfgPrinter printer = options.printCfg ? new CfgPrinter() : null;\n        IRConverter converter = new IRConverter(timing, application, appInfo, options, printer);\n        application = converter.convertToDex(executor);\n        if (options.printCfg) {\n            if (options.printCfgFile != null && !options.printCfgFile.isEmpty()) {\n                OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(options.printCfgFile), StandardCharsets.UTF_8);\n                Throwable var8 = null;\n\n                try {\n                    writer.write(printer.toString());\n                } catch (Throwable var17) {\n                    var8 = var17;\n                    throw var17;\n                } finally {\n                    if (writer != null) {\n                        if (var8 != null) {\n                            try {\n                                writer.close();\n                            } catch (Throwable var16) {\n                                var8.addSuppressed(var16);\n                            }\n                        } else {\n                            writer.close();\n                        }\n                    }\n\n                }\n            } else {\n                System.out.print(printer.toString());\n            }\n        }\n\n        return application;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/tools/r8/AtlasD8DexArchiveBuilder.java",
    "content": "package com.android.tools.r8;\n\nimport com.android.annotations.NonNull;\nimport com.android.builder.dexing.ClassFileEntry;\nimport com.android.builder.dexing.DexArchiveBuilder;\nimport com.android.builder.dexing.DexArchiveBuilderException;\nimport com.android.tools.r8.utils.FileUtils;\nimport com.android.tools.r8.utils.OutputMode;\nimport com.google.common.util.concurrent.MoreExecutors;\n\nimport java.io.IOException;\nimport java.nio.file.Path;\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.stream.Stream;\n\n/**\n * AtlasD8DexArchiveBuilder\n *\n * @author zhayu.ll\n * @date 18/4/26\n */\npublic class AtlasD8DexArchiveBuilder extends DexArchiveBuilder{\n\n    private int minSdkVersion;\n\n    private boolean isDebug;\n\n    private Path mainDexList;\n\n    private boolean awb;\n\n    public AtlasD8DexArchiveBuilder(int minSdkVersion, boolean isDebug,Path mainDexList,boolean awb){\n\n        this.minSdkVersion = minSdkVersion;\n        this.isDebug = isDebug;\n        this.mainDexList = mainDexList;\n        this.awb = awb;\n\n    }\n\n    @Override\n    public void convert(Stream<ClassFileEntry> input, Path output, boolean isIncremental) throws DexArchiveBuilderException {\n        try {\n            Iterator<byte[]> data = input.map(AtlasD8DexArchiveBuilder::readAllBytes).iterator();\n            if (!data.hasNext()) {\n                // nothing to do here, just return\n                return;\n            }\n\n            D8Command.Builder builder =\n                    D8Command.builder()\n                            .setMode(isDebug?CompilationMode.DEBUG:CompilationMode.RELEASE)\n                            .setMinApiLevel(minSdkVersion)\n                            .setOutputMode(OutputMode.Indexed);\n\n            while (data.hasNext()) {\n                builder.addClassProgramData(data.next());\n            }\n\n            if (!awb && isDebug && minSdkVersion < 21){\n                if (!mainDexList.toFile().exists()){\n                    createNew(mainDexList);\n                }\n                builder.addMainDexListFiles(mainDexList);\n            }\n\n            builder.setOutputPath(output);\n            AtlasD8.run(builder.build(), MoreExecutors.newDirectExecutorService());\n        } catch (Throwable e) {\n            throw new DexArchiveBuilderException(e);\n        }\n    }\n\n\n    //supply fake maindexlist for d8 compile,we will generate real maindexlist in next step for merge dex\n    private void createNew(Path mainDexList) throws IOException {\n        FileUtils.writeTextFile(mainDexList, Arrays.asList(\"android/taobao/atlas/bundleInfo/AtlasBundleInfoGenerator.class\",\"android/taobao/atlas/framework/FrameworkProperties.class\"));\n\n\n    }\n\n    @NonNull\n    private static byte[] readAllBytes(@NonNull ClassFileEntry entry) {\n        try {\n            return entry.readAllBytes();\n        } catch (IOException ex) {\n            throw new DexArchiveBuilderException(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/tools/r8/AtlasD8Merger.java",
    "content": "package com.android.tools.r8;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.builder.dexing.*;\nimport com.android.tools.r8.errors.CompilationError;\nimport com.google.common.collect.Iterables;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.nio.file.Path;\n\n/**\n * AtlasD8Merger\n *\n * @author zhayu.ll\n * @date 18/4/3\n */\npublic class AtlasD8Merger implements DexArchiveMerger {\n    @NonNull\n    private final OutputStream errorStream;\n    private final int minSdkVersion;\n    @NonNull private final CompilationMode compilationMode;\n\n    public AtlasD8Merger(\n            @NonNull OutputStream errorStream,\n            int minSdkVersion,\n            @NonNull CompilationMode compilationMode) {\n        this.errorStream = errorStream;\n        this.minSdkVersion = minSdkVersion;\n        this.compilationMode = compilationMode;\n    }\n\n    @Override\n    public void mergeDexArchives(\n            @NonNull Iterable<Path> inputs,\n            @NonNull Path outputDir,\n            @Nullable Path mainDexClasses,\n            @NonNull DexingType dexingType)\n            throws DexArchiveMergerException {\n        if (Iterables.isEmpty(inputs)) {\n            return;\n        }\n\n        D8Command.Builder builder = D8Command.builder();\n\n        for (Path input : inputs) {\n            try (DexArchive archive = DexArchives.fromInput(input)) {\n                for (DexArchiveEntry dexArchiveEntry : archive.getFiles()) {\n                    builder.addDexProgramData(dexArchiveEntry.getDexFileContent());\n                }\n            } catch (IOException e) {\n                throw new DexArchiveMergerException(e);\n            }\n        }\n        try {\n            if (mainDexClasses != null) {\n                builder.addMainDexListFiles(mainDexClasses);\n            }\n            builder.setMinApiLevel(minSdkVersion).setMode(compilationMode).setOutputPath(outputDir);\n            AtlasD8.run(builder.build());\n        } catch (CompilationException | IOException | CompilationError e) {\n            DexArchiveMergerException exception = new DexArchiveMergerException(e);\n            try {\n                errorStream.write(e.getMessage().getBytes());\n            } catch (IOException ex) {\n                System.err.println(e.getMessage());\n                exception.addSuppressed(ex);\n            }\n            throw exception;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/tools/r8/dex/AtlasApplicationWriter.java",
    "content": "package com.android.tools.r8.dex;\n\nimport com.android.tools.r8.AtlasD8;\nimport com.android.tools.r8.errors.CompilationError;\nimport com.android.tools.r8.graph.*;\nimport com.android.tools.r8.naming.MinifiedNameMapPrinter;\nimport com.android.tools.r8.naming.NamingLens;\nimport com.android.tools.r8.utils.*;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport it.unimi.dsi.fastutil.objects.Object2IntMap;\nimport it.unimi.dsi.fastutil.objects.Object2ReferenceMap;\nimport it.unimi.dsi.fastutil.objects.Reference2IntMap;\n\nimport java.io.*;\nimport java.util.Iterator;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Future;\n\n/**\n * AtlasApplicationWriter\n *\n * @author zhayu.ll\n * @date 18/4/3\n */\npublic class AtlasApplicationWriter extends ApplicationWriter{\n\n\n\n    public AtlasApplicationWriter(DexApplication application, AppInfo appInfo, InternalOptions options, Marker marker, byte[] deadCode, NamingLens namingLens, byte[] proguardSeedsData) {\n        super(application, appInfo, options, marker, deadCode, namingLens, proguardSeedsData);\n    }\n\n    @Override\n    public AndroidApp write(PackageDistribution packageDistribution, ExecutorService executorService) throws IOException, ExecutionException {\n        this.application.timing.begin(\"AtlasApplicationWriter.write\");\n\n        AndroidApp var10;\n        try {\n            this.application.dexItemFactory.sort(this.namingLens);\n\n            assert this.markerString == null || this.application.dexItemFactory.extractMarker() != null;\n\n            AtlasApplicationWriter.SortAnnotations sortAnnotations = new AtlasApplicationWriter.SortAnnotations();\n            this.application.classes().forEach((clazz) -> {\n                clazz.addDependencies(sortAnnotations);\n            });\n            AtlasVirtualFile.Distributor distributor = null;\n            if (this.options.outputMode == OutputMode.FilePerClass) {\n                assert packageDistribution == null : \"Cannot combine package distribution definition with file-per-class option.\";\n\n                distributor = new AtlasVirtualFile.FilePerClassDistributor(this);\n            } else if (!this.options.canUseMultidex() && this.options.mainDexKeepRules.isEmpty() && this.application.mainDexList.isEmpty()) {\n                if (packageDistribution != null) {\n                    throw new CompilationError(\"Cannot apply package distribution. Multidex is not supported with API level \" + this.options.minApiLevel + \". For API level < \" + 21 + \", main dex classes list or rules must be specified.\");\n                }\n\n                distributor = new AtlasVirtualFile.MonoDexDistributor(this);\n            } else if (packageDistribution != null) {\n                assert !this.options.minimalMainDex : \"Cannot combine package distribution definition with minimal-main-dex option.\";\n\n                distributor = new AtlasVirtualFile.PackageMapDistributor(this, packageDistribution, executorService);\n            } else {\n                distributor = new AtlasVirtualFile.FillFilesDistributor(this, this.options.minimalMainDex);\n            }\n\n            Map<Integer, AtlasVirtualFile> newFiles = ((AtlasVirtualFile.Distributor)distributor).run();\n            LinkedHashMap<AtlasVirtualFile, Future<byte[]>> dexDataFutures = new LinkedHashMap();\n\n            for(int i = 0; i < newFiles.size(); ++i) {\n                AtlasVirtualFile newFile = (AtlasVirtualFile)newFiles.get(i);\n\n                assert newFile.getId() == i;\n\n                assert !newFile.isEmpty();\n\n                if (!newFile.isEmpty()) {\n                    dexDataFutures.put(newFile, executorService.submit(() -> {\n                        return writeDexFile(newFile);\n                    }));\n                }\n            }\n\n            AndroidApp.Builder builder = AndroidApp.builder();\n\n            try {\n                Iterator var17 = dexDataFutures.entrySet().iterator();\n\n                while(var17.hasNext()) {\n                    Map.Entry<AtlasVirtualFile, Future<byte[]>> entry = (Map.Entry)var17.next();\n                    builder.addDexProgramData((byte[])((Future)entry.getValue()).get(), ((AtlasVirtualFile)entry.getKey()).getClassDescriptors());\n                }\n            } catch (InterruptedException var14) {\n                throw new RuntimeException(\"Interrupted while waiting for future.\", var14);\n            }\n\n            if (this.deadCode != null) {\n                builder.setDeadCode(this.deadCode);\n            }\n\n            byte[] proguardMapResult = this.writeProguardMapFile();\n            if (proguardMapResult != null) {\n                builder.setProguardMapData(proguardMapResult);\n            }\n\n            if (this.proguardSeedsData != null) {\n                builder.setProguardSeedsData(this.proguardSeedsData);\n            }\n\n            byte[] mainDexList = this.writeMainDexList();\n            if (mainDexList != null) {\n                builder.setMainDexListOutputData(mainDexList);\n            }\n\n            var10 = builder.build();\n        } finally {\n            this.application.timing.end();\n        }\n\n        return var10;\n    }\n\n    private byte[] writeDexFile(AtlasVirtualFile vfile) {\n        FileWriter fileWriter = new FileWriter(vfile.computeMapping(this.application), this.application, this.appInfo, this.options, this.namingLens);\n        fileWriter.rewriteCodeWithJumboStrings(vfile.classes());\n        fileWriter.collect();\n        processFileWriter(fileWriter);\n        return fileWriter.generate();\n    }\n\n    private void processFileWriter(FileWriter fileWriter) {\n        if (AtlasD8.deepShrink) {\n            System.out.println(\"start to deepShrink of dx\");\n            Object mixedSectionOffsets = ReflectUtils.getField(fileWriter, \"mixedSectionOffsets\");\n            ObjectToOffsetMapping mapping = (ObjectToOffsetMapping) ReflectUtils.getField(fileWriter, \"mapping\");\n\n            Object2IntMap<DexDebugInfo> debugInfoObject2IntMap = (Object2IntMap<DexDebugInfo>) ReflectUtils.getField(mixedSectionOffsets, \"debugInfos\");\n            Reference2IntMap<DexCode> codesObject2IntMap = (Reference2IntMap<DexCode>) ReflectUtils.getField(mixedSectionOffsets, \"codes\");\n\n            debugInfoObject2IntMap.clear();\n            for (DexProgramClass dexProgramClass:mapping.getClasses()){\n                ReflectUtils.updateField(dexProgramClass,\"sourceFile\",null);\n            }\n            for (DexCode dexCode:codesObject2IntMap.keySet()){\n                dexCode.setDebugInfo(null);\n            }\n            System.out.println(\"end to deepShrink of dx\");\n        }\n\n\n    }\n\n    private byte[] writeProguardMapFile() throws IOException {\n        if (!this.namingLens.isIdentityLens()) {\n            MinifiedNameMapPrinter printer = new MinifiedNameMapPrinter(this.application, this.namingLens);\n            ByteArrayOutputStream bytes = new ByteArrayOutputStream();\n            PrintStream stream = new PrintStream(bytes);\n            printer.write(stream);\n            stream.flush();\n            return bytes.toByteArray();\n        } else if (this.application.getProguardMap() != null) {\n            ByteArrayOutputStream bytes = new ByteArrayOutputStream();\n            Writer writer = new PrintWriter(bytes);\n            this.application.getProguardMap().write(writer, !this.options.skipDebugLineNumberOpt);\n            writer.flush();\n            return bytes.toByteArray();\n        } else {\n            return null;\n        }\n    }\n\n    private String mapMainDexListName(DexType type) {\n        return DescriptorUtils.descriptorToJavaType(this.namingLens.lookupDescriptor(type).toString()).replace('.', '/') + \".class\";\n    }\n\n    private byte[] writeMainDexList() throws IOException {\n        if (this.application.mainDexList.isEmpty()) {\n            return null;\n        } else {\n            ByteArrayOutputStream bytes = new ByteArrayOutputStream();\n            PrintWriter writer = new PrintWriter(bytes);\n            this.application.mainDexList.forEach((type) -> {\n                writer.println(this.mapMainDexListName(type));\n            });\n            writer.flush();\n            return bytes.toByteArray();\n        }\n    }\n\n    private static class SortAnnotations extends MixedSectionCollection {\n        private SortAnnotations() {\n        }\n\n        public boolean add(DexAnnotationSet dexAnnotationSet) {\n            dexAnnotationSet.sort();\n            return true;\n        }\n\n        public boolean add(DexAnnotation annotation) {\n            annotation.annotation.sort();\n            return true;\n        }\n\n        public boolean add(DexEncodedArray dexEncodedArray) {\n            DexValue[] var2 = dexEncodedArray.values;\n            int var3 = var2.length;\n\n            for(int var4 = 0; var4 < var3; ++var4) {\n                DexValue value = var2[var4];\n                value.sort();\n            }\n\n            return true;\n        }\n\n        public boolean add(DexProgramClass dexClassData) {\n            return true;\n        }\n\n        public boolean add(DexCode dexCode) {\n            return true;\n        }\n\n        public boolean add(DexDebugInfo dexDebugInfo) {\n            return true;\n        }\n\n        public boolean add(DexTypeList dexTypeList) {\n            return true;\n        }\n\n        public boolean add(DexAnnotationSetRefList annotationSetRefList) {\n            return true;\n        }\n\n        public boolean setAnnotationsDirectoryForClass(DexProgramClass clazz, DexAnnotationDirectory annotationDirectory) {\n            return true;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/android/tools/r8/dex/AtlasVirtualFile.java",
    "content": "package com.android.tools.r8.dex;\n\nimport com.android.tools.r8.dex.ApplicationWriter;\nimport com.android.tools.r8.dex.VirtualFile;\nimport com.android.tools.r8.errors.CompilationError;\nimport com.android.tools.r8.errors.InternalCompilerError;\nimport com.android.tools.r8.errors.MainDexError;\nimport com.android.tools.r8.graph.*;\nimport com.android.tools.r8.naming.ClassNameMapper;\nimport com.android.tools.r8.naming.NamingLens;\nimport com.android.tools.r8.utils.DescriptorUtils;\nimport com.android.tools.r8.utils.PackageDistribution;\nimport com.android.tools.r8.utils.ThreadUtils;\nimport com.google.common.collect.Iterators;\nimport com.google.common.collect.Maps;\nimport com.google.common.collect.Sets;\nimport com.google.common.collect.UnmodifiableIterator;\n\nimport java.io.IOException;\nimport java.io.OutputStreamWriter;\nimport java.io.Writer;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.*;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Future;\nimport java.util.function.Function;\n\n/**\n * AtlasFillFilesDistributor\n *\n * @author zhayu.ll\n * @date 18/4/3\n */\npublic class AtlasVirtualFile {\n    private static final int MAX_ENTRIES = 65000;\n    private static final int MAX_PREFILL_ENTRIES = 60536;\n    private final int id;\n    private final AtlasVirtualFile.VirtualFileIndexedItemCollection indexedItems;\n    private final AtlasVirtualFile.IndexedItemTransaction transaction;\n\n    private AtlasVirtualFile(int id, NamingLens namingLens) {\n        this.id = id;\n        this.indexedItems = new AtlasVirtualFile.VirtualFileIndexedItemCollection(id);\n        this.transaction = new AtlasVirtualFile.IndexedItemTransaction(this.indexedItems, namingLens);\n    }\n\n    public int getId() {\n        return this.id;\n    }\n\n    public Set<String> getClassDescriptors() {\n\n        Set<String> classDescriptors = new HashSet<>();\n        for (DexProgramClass clazz : indexedItems.classes) {\n            boolean added = classDescriptors.add(clazz.type.descriptor.toString());\n            assert added;\n        }\n        return classDescriptors;\n    }\n\n    public static String deriveCommonPrefixAndSanityCheck(List<String> fileNames) {\n        Iterator<String> nameIterator = fileNames.iterator();\n        String first = (String)nameIterator.next();\n        if (!first.toLowerCase().endsWith(\".dex\")) {\n            throw new RuntimeException(\"Illegal suffix for dex file: `\" + first + \"`.\");\n        } else {\n            String prefix = first.substring(0, first.length() - \".dex\".length());\n            int var4 = 2;\n\n            String numberPart;\n            do {\n                if (!nameIterator.hasNext()) {\n                    return prefix;\n                }\n\n                String next = (String)nameIterator.next();\n                if (!next.toLowerCase().endsWith(\".dex\")) {\n                    throw new RuntimeException(\"Illegal suffix for dex file: `\" + first + \"`.\");\n                }\n\n                if (!next.startsWith(prefix)) {\n                    throw new RuntimeException(\"Input filenames lack common prefix.\");\n                }\n\n                numberPart = next.substring(prefix.length(), next.length() - \".dex\".length());\n            } while(Integer.parseInt(numberPart) == var4++);\n\n            throw new RuntimeException(\"DEX files are not numbered consecutively.\");\n        }\n    }\n\n    private static Map<DexProgramClass, String> computeOriginalNameMapping(Collection<DexProgramClass> classes, ClassNameMapper proguardMap) {\n        Map<DexProgramClass, String> originalNames = new HashMap();\n        classes.forEach((c) -> {\n            String var10000 = (String)originalNames.put(c, DescriptorUtils.descriptorToJavaType(c.type.toDescriptorString(), proguardMap));\n        });\n        return originalNames;\n    }\n\n    private static String extractPrefixToken(int prefixLength, String className, boolean addStar) {\n        int index = 0;\n        int lastIndex = 0;\n\n        int segmentCount;\n        for(segmentCount = 0; lastIndex != -1 && segmentCount++ < prefixLength; lastIndex = className.indexOf(46, lastIndex + 1)) {\n            index = lastIndex;\n        }\n\n        String prefix = className.substring(0, index);\n        if (addStar && segmentCount >= prefixLength) {\n            prefix = prefix + \".*\";\n        }\n\n        return prefix;\n    }\n\n    public ObjectToOffsetMapping computeMapping(DexApplication application) {\n        assert this.transaction.isEmpty();\n\n        return new ObjectToOffsetMapping(this.id, application, (DexProgramClass[])this.indexedItems.classes.toArray(new DexProgramClass[this.indexedItems.classes.size()]), (DexProto[])this.indexedItems.protos.toArray(new DexProto[this.indexedItems.protos.size()]), (DexType[])this.indexedItems.types.toArray(new DexType[this.indexedItems.types.size()]), (DexMethod[])this.indexedItems.methods.toArray(new DexMethod[this.indexedItems.methods.size()]), (DexField[])this.indexedItems.fields.toArray(new DexField[this.indexedItems.fields.size()]), (DexString[])this.indexedItems.strings.toArray(new DexString[this.indexedItems.strings.size()]), (DexCallSite[])this.indexedItems.callSites.toArray(new DexCallSite[this.indexedItems.callSites.size()]), (DexMethodHandle[])this.indexedItems.methodHandles.toArray(new DexMethodHandle[this.indexedItems.methodHandles.size()]));\n    }\n\n    private void addClass(DexProgramClass clazz) {\n        this.transaction.addClassAndDependencies(clazz);\n    }\n\n    private static boolean isFull(int numberOfMethods, int numberOfFields, int maximum) {\n        return numberOfMethods > maximum || numberOfFields > maximum;\n    }\n\n    private boolean isFull() {\n        return isFull(this.transaction.getNumberOfMethods(), this.transaction.getNumberOfFields(), MAX_ENTRIES);\n    }\n\n    void throwIfFull(boolean hasMainDexList) {\n        if (this.isFull()) {\n            throw new MainDexError(hasMainDexList, (long)this.transaction.getNumberOfMethods(), (long)this.transaction.getNumberOfFields(), MAX_ENTRIES);\n        }\n    }\n\n    private boolean isFilledEnough(AtlasVirtualFile.FillStrategy fillStrategy) {\n        return isFull(this.transaction.getNumberOfMethods(), this.transaction.getNumberOfFields(), fillStrategy == AtlasVirtualFile.FillStrategy.FILL_MAX ? MAX_ENTRIES : MAX_PREFILL_ENTRIES);\n    }\n\n    public void abortTransaction() {\n        this.transaction.abort();\n    }\n\n    public void commitTransaction() {\n        this.transaction.commit();\n    }\n\n    public boolean isEmpty() {\n        return this.indexedItems.classes.isEmpty();\n    }\n\n    public List<DexProgramClass> classes() {\n        return this.indexedItems.classes;\n    }\n\n    private static class PackageSplitPopulator implements Callable<Map<String, Integer>> {\n        private static final int MINIMUM_PREFIX_LENGTH = 4;\n        private static final int MAXIMUM_PREFIX_LENGTH = 7;\n        private static final int MIN_FILL_FACTOR = 5;\n        private final List<DexProgramClass> classes;\n        private final Map<DexProgramClass, String> originalNames;\n        private final Set<String> previousPrefixes;\n        private final DexItemFactory dexItemFactory;\n        private final AtlasVirtualFile.FillStrategy fillStrategy;\n        private final AtlasVirtualFile.VirtualFileCycler cycler;\n\n        PackageSplitPopulator(Map<Integer, AtlasVirtualFile> files, Set<DexProgramClass> classes, Map<DexProgramClass, String> originalNames, Set<String> previousPrefixes, DexItemFactory dexItemFactory, AtlasVirtualFile.FillStrategy fillStrategy, NamingLens namingLens) {\n            this.classes = new ArrayList(classes);\n            this.originalNames = originalNames;\n            this.previousPrefixes = previousPrefixes;\n            this.dexItemFactory = dexItemFactory;\n            this.fillStrategy = fillStrategy;\n            this.cycler = new AtlasVirtualFile.VirtualFileCycler(files, namingLens, fillStrategy);\n        }\n\n        private String getOriginalName(DexProgramClass clazz) {\n            return this.originalNames != null ? (String)this.originalNames.get(clazz) : clazz.toString();\n        }\n\n        public Map<String, Integer> call() throws IOException {\n            int prefixLength = 4;\n            int transactionStartIndex = 0;\n            int fileStartIndex = 0;\n            String currentPrefix = null;\n            Map<String, Integer> newPackageAssignments = new LinkedHashMap();\n            AtlasVirtualFile current = this.cycler.next();\n            List<DexProgramClass> nonPackageClasses = new ArrayList();\n\n            for(int classIndex = 0; classIndex < this.classes.size(); ++classIndex) {\n                DexProgramClass clazz = (DexProgramClass)this.classes.get(classIndex);\n                String originalName = this.getOriginalName(clazz);\n                if (!AtlasVirtualFile.PackageMapPopulator.coveredByPrefix(originalName, currentPrefix)) {\n                    if (currentPrefix != null) {\n                        current.commitTransaction();\n                        this.cycler.restart();\n\n                        assert !newPackageAssignments.containsKey(currentPrefix);\n\n                        newPackageAssignments.put(currentPrefix, current.id);\n                        prefixLength = 3;\n                    }\n\n                    String newPrefix;\n                    do {\n                        ++prefixLength;\n                        newPrefix = AtlasVirtualFile.extractPrefixToken(prefixLength, originalName, false);\n                    } while(currentPrefix != null && (currentPrefix.startsWith(newPrefix) || this.conflictsWithPreviousPrefix(newPrefix, originalName)));\n\n                    if (!newPrefix.equals(\"\")) {\n                        currentPrefix = AtlasVirtualFile.extractPrefixToken(prefixLength, originalName, true);\n                    }\n\n                    transactionStartIndex = classIndex;\n                }\n\n                if (currentPrefix != null) {\n                    assert clazz.superType != null || clazz.type == this.dexItemFactory.objectType;\n\n                    current.addClass(clazz);\n                    if (current.isFilledEnough(this.fillStrategy)) {\n                        current.abortTransaction();\n                        if (classIndex - transactionStartIndex > (classIndex - fileStartIndex) / 5 && prefixLength < 7) {\n                            ++prefixLength;\n                        } else {\n                            fileStartIndex = transactionStartIndex;\n                            if (!this.cycler.hasNext()) {\n                                if (current.transaction.getNumberOfClasses() == 0) {\n                                    for(int j = transactionStartIndex; j <= classIndex; ++j) {\n                                        nonPackageClasses.add(this.classes.get(j));\n                                    }\n\n                                    transactionStartIndex = classIndex + 1;\n                                }\n\n                                this.cycler.addFile();\n                            }\n\n                            current = this.cycler.next();\n                        }\n\n                        currentPrefix = null;\n                        classIndex = transactionStartIndex - 1;\n\n                        assert current != null;\n                    }\n                } else {\n                    assert clazz.superType != null;\n\n                    assert current.transaction.classes.isEmpty();\n\n                    nonPackageClasses.add(clazz);\n                }\n            }\n\n            current.commitTransaction();\n\n            assert !newPackageAssignments.containsKey(currentPrefix);\n\n            if (currentPrefix != null) {\n                newPackageAssignments.put(currentPrefix, current.id);\n            }\n\n            if (nonPackageClasses.size() > 0) {\n                this.addNonPackageClasses(this.cycler, nonPackageClasses);\n            }\n\n            return newPackageAssignments;\n        }\n\n        private void addNonPackageClasses(AtlasVirtualFile.VirtualFileCycler cycler, List<DexProgramClass> nonPackageClasses) {\n            cycler.restart();\n            AtlasVirtualFile current = cycler.next();\n            Iterator var4 = nonPackageClasses.iterator();\n\n            while(var4.hasNext()) {\n                DexProgramClass clazz = (DexProgramClass)var4.next();\n                if (current.isFilledEnough(this.fillStrategy)) {\n                    current = this.getVirtualFile(cycler);\n                }\n\n                current.addClass(clazz);\n\n                while(current.isFull()) {\n                    current.abortTransaction();\n                    current = this.getVirtualFile(cycler);\n                    boolean wasEmpty = current.isEmpty();\n                    current.addClass(clazz);\n                    if (wasEmpty && current.isFull()) {\n                        throw new InternalCompilerError(\"Class \" + clazz.toString() + \" does not fit into a single dex file.\");\n                    }\n                }\n\n                current.commitTransaction();\n            }\n\n        }\n\n        private AtlasVirtualFile getVirtualFile(AtlasVirtualFile.VirtualFileCycler cycler) {\n            AtlasVirtualFile current = null;\n\n            while(cycler.hasNext() && (current = cycler.next()).isFilledEnough(this.fillStrategy)) {\n                ;\n            }\n\n            if (current == null || current.isFilledEnough(this.fillStrategy)) {\n                current = cycler.addFile();\n            }\n\n            return current;\n        }\n\n        private boolean conflictsWithPreviousPrefix(String newPrefix, String originalName) {\n            if (this.previousPrefixes == null) {\n                return false;\n            } else {\n                Iterator var3 = this.previousPrefixes.iterator();\n\n                String previous;\n                do {\n                    if (!var3.hasNext()) {\n                        return false;\n                    }\n\n                    previous = (String)var3.next();\n                } while(!previous.startsWith(newPrefix) || originalName.lastIndexOf(46) <= newPrefix.length());\n\n                return true;\n            }\n        }\n    }\n\n    private static class VirtualFileCycler {\n        private Map<Integer, AtlasVirtualFile> files;\n        private final NamingLens namingLens;\n        private final AtlasVirtualFile.FillStrategy fillStrategy;\n        private int nextFileId;\n        private Iterator<AtlasVirtualFile> allFilesCyclic;\n        private Iterator<AtlasVirtualFile> activeFiles;\n\n        VirtualFileCycler(Map<Integer, AtlasVirtualFile> files, NamingLens namingLens, AtlasVirtualFile.FillStrategy fillStrategy) {\n            this.files = files;\n            this.namingLens = namingLens;\n            this.fillStrategy = fillStrategy;\n            this.nextFileId = (Integer)Collections.max(files.keySet()) + 1;\n            this.reset();\n        }\n\n        private void reset() {\n            this.allFilesCyclic = Iterators.cycle(this.files.values());\n            this.restart();\n        }\n\n        boolean hasNext() {\n            return this.activeFiles.hasNext();\n        }\n\n        AtlasVirtualFile next() {\n            AtlasVirtualFile next = (AtlasVirtualFile)this.activeFiles.next();\n            return next;\n        }\n\n        void restart() {\n            this.activeFiles = Iterators.limit(this.allFilesCyclic, this.files.size());\n        }\n\n        AtlasVirtualFile addFile() {\n            AtlasVirtualFile newFile = new AtlasVirtualFile(this.nextFileId, this.namingLens);\n            this.files.put(this.nextFileId, newFile);\n            ++this.nextFileId;\n            this.reset();\n            return newFile;\n        }\n    }\n\n    private static class PackageMapPopulator implements Callable<List<DexProgramClass>> {\n        private final AtlasVirtualFile file;\n        private final Collection<DexProgramClass> classes;\n        private final PackageDistribution packageDistribution;\n        private final Map<DexProgramClass, String> originalNames;\n\n        PackageMapPopulator(AtlasVirtualFile file, Collection<DexProgramClass> classes, PackageDistribution packageDistribution, Map<DexProgramClass, String> originalNames) {\n            this.file = file;\n            this.classes = classes;\n            this.packageDistribution = packageDistribution;\n            this.originalNames = originalNames;\n        }\n\n        public List<DexProgramClass> call() {\n            String currentPrefix = null;\n            int currentFileId = -1;\n            List<DexProgramClass> inserted = new ArrayList();\n            Iterator var4 = this.classes.iterator();\n\n            do {\n                if (!var4.hasNext()) {\n                    this.file.commitTransaction();\n                    return inserted;\n                }\n\n                DexProgramClass clazz = (DexProgramClass)var4.next();\n                String originalName = (String)this.originalNames.get(clazz);\n\n                assert originalName != null;\n\n                if (!coveredByPrefix(originalName, currentPrefix)) {\n                    if (currentPrefix != null) {\n                        this.file.commitTransaction();\n                    }\n\n                    currentPrefix = this.lookupPrefixFor(originalName);\n                    if (currentPrefix == null) {\n                        currentFileId = -1;\n                    } else {\n                        currentFileId = this.packageDistribution.get(currentPrefix);\n                    }\n                }\n\n                if (currentFileId == this.file.id) {\n                    this.file.addClass(clazz);\n                    inserted.add(clazz);\n                }\n            } while(!this.file.isFull());\n\n            throw new CompilationError(\"Cannot fit package \" + currentPrefix + \" in requested dex file, consider removing mapping.\");\n        }\n\n        private String lookupPrefixFor(String originalName) {\n            int lastIndexOfDot = originalName.lastIndexOf(46);\n            if (lastIndexOfDot < 0) {\n                return null;\n            } else {\n                String prefix = originalName.substring(0, lastIndexOfDot);\n                if (this.packageDistribution.containsFile(prefix)) {\n                    return prefix;\n                } else {\n                    prefix = originalName;\n\n                    do {\n                        int index;\n                        if ((index = prefix.lastIndexOf(46)) == -1) {\n                            return null;\n                        }\n\n                        prefix = prefix.substring(0, index);\n                    } while(!this.packageDistribution.containsFile(prefix + \".*\"));\n\n                    return prefix + \".*\";\n                }\n            }\n        }\n\n        static boolean coveredByPrefix(String originalName, String currentPrefix) {\n            if (currentPrefix == null) {\n                return false;\n            } else if (currentPrefix.endsWith(\".*\")) {\n                return originalName.startsWith(currentPrefix.substring(0, currentPrefix.length() - 2));\n            } else {\n                return originalName.startsWith(currentPrefix) && originalName.lastIndexOf(46) == currentPrefix.length();\n            }\n        }\n    }\n\n    private static class IndexedItemTransaction implements IndexedItemCollection {\n        private final AtlasVirtualFile.VirtualFileIndexedItemCollection base;\n        private final NamingLens namingLens;\n        private final Set<DexProgramClass> classes;\n        private final Set<DexField> fields;\n        private final Set<DexMethod> methods;\n        private final Set<DexType> types;\n        private final Set<DexProto> protos;\n        private final Set<DexString> strings;\n        private final Set<DexCallSite> callSites;\n        private final Set<DexMethodHandle> methodHandles;\n\n        private IndexedItemTransaction(AtlasVirtualFile.VirtualFileIndexedItemCollection base, NamingLens namingLens) {\n            this.classes = new LinkedHashSet();\n            this.fields = new LinkedHashSet();\n            this.methods = new LinkedHashSet();\n            this.types = new LinkedHashSet();\n            this.protos = new LinkedHashSet();\n            this.strings = new LinkedHashSet();\n            this.callSites = new LinkedHashSet();\n            this.methodHandles = new LinkedHashSet();\n            this.base = base;\n            this.namingLens = namingLens;\n        }\n\n        private <T extends IndexedDexItem> boolean maybeInsert(T item, Set<T> set) {\n            if (!item.hasVirtualFileData(this.base.id) && !set.contains(item)) {\n                set.add(item);\n                return true;\n            } else {\n                return false;\n            }\n        }\n\n        void addClassAndDependencies(DexProgramClass clazz) {\n            clazz.collectIndexedItems(this);\n        }\n\n        public boolean addClass(DexProgramClass dexProgramClass) {\n            if (!this.base.seenClasses.contains(dexProgramClass) && !this.classes.contains(dexProgramClass)) {\n                this.classes.add(dexProgramClass);\n                return true;\n            } else {\n                return false;\n            }\n        }\n\n        public boolean addField(DexField field) {\n            return this.maybeInsert(field, this.fields);\n        }\n\n        public boolean addMethod(DexMethod method) {\n            return this.maybeInsert(method, this.methods);\n        }\n\n        public boolean addString(DexString string) {\n            return this.maybeInsert(string, this.strings);\n        }\n\n        public boolean addProto(DexProto proto) {\n            return this.maybeInsert(proto, this.protos);\n        }\n\n        public boolean addType(DexType type) {\n            return this.maybeInsert(type, this.types);\n        }\n\n        public boolean addCallSite(DexCallSite callSite) {\n            return this.maybeInsert(callSite, this.callSites);\n        }\n\n        public boolean addMethodHandle(DexMethodHandle methodHandle) {\n            return this.maybeInsert(methodHandle, this.methodHandles);\n        }\n\n        public DexString getRenamedDescriptor(DexType type) {\n            return this.namingLens.lookupDescriptor(type);\n        }\n\n        public DexString getRenamedName(DexMethod method) {\n            assert this.namingLens.checkTargetCanBeTranslated(method);\n\n            return this.namingLens.lookupName(method);\n        }\n\n        public DexString getRenamedName(DexField field) {\n            return this.namingLens.lookupName(field);\n        }\n\n        int getNumberOfMethods() {\n            return this.methods.size() + this.base.getNumberOfMethods();\n        }\n\n        int getNumberOfFields() {\n            return this.fields.size() + this.base.getNumberOfFields();\n        }\n\n        private <T extends DexItem> void commitItemsIn(Set<T> set, Function<T, Boolean> hook) {\n            set.forEach((item) -> {\n                boolean newlyAdded = (Boolean)hook.apply(item);\n\n                assert newlyAdded;\n\n            });\n            set.clear();\n        }\n\n        void commit() {\n            Set var10001 = this.classes;\n            AtlasVirtualFile.VirtualFileIndexedItemCollection var10002 = this.base;\n            this.base.getClass();\n            this.commitItemsIn(var10001, var10002::addClass);\n            var10001 = this.fields;\n            var10002 = this.base;\n            this.base.getClass();\n            this.commitItemsIn(var10001, var10002::addField);\n            var10001 = this.methods;\n            var10002 = this.base;\n            this.base.getClass();\n            this.commitItemsIn(var10001, var10002::addMethod);\n            var10001 = this.protos;\n            var10002 = this.base;\n            this.base.getClass();\n            this.commitItemsIn(var10001, var10002::addProto);\n            var10001 = this.types;\n            var10002 = this.base;\n            this.base.getClass();\n            this.commitItemsIn(var10001, var10002::addType);\n            var10001 = this.strings;\n            var10002 = this.base;\n            this.base.getClass();\n            this.commitItemsIn(var10001, var10002::addString);\n            var10001 = this.callSites;\n            var10002 = this.base;\n            this.base.getClass();\n            this.commitItemsIn(var10001, var10002::addCallSite);\n            var10001 = this.methodHandles;\n            var10002 = this.base;\n            this.base.getClass();\n            this.commitItemsIn(var10001, var10002::addMethodHandle);\n        }\n\n        void abort() {\n            this.classes.clear();\n            this.fields.clear();\n            this.methods.clear();\n            this.protos.clear();\n            this.types.clear();\n            this.strings.clear();\n        }\n\n        public boolean isEmpty() {\n            return this.classes.isEmpty() && this.fields.isEmpty() && this.methods.isEmpty() && this.protos.isEmpty() && this.types.isEmpty() && this.strings.isEmpty();\n        }\n\n        int getNumberOfStrings() {\n            return this.strings.size() + this.base.getNumberOfStrings();\n        }\n\n        int getNumberOfClasses() {\n            return this.classes.size() + this.base.classes.size();\n        }\n    }\n\n    private static class VirtualFileIndexedItemCollection implements IndexedItemCollection {\n        final int id;\n        private final List<DexProgramClass> classes;\n        private final List<DexProto> protos;\n        private final List<DexType> types;\n        private final List<DexMethod> methods;\n        private final List<DexField> fields;\n        private final List<DexString> strings;\n        private final List<DexCallSite> callSites;\n        private final List<DexMethodHandle> methodHandles;\n        private final Set<DexClass> seenClasses;\n\n        private VirtualFileIndexedItemCollection(int id) {\n            this.classes = new ArrayList();\n            this.protos = new ArrayList();\n            this.types = new ArrayList();\n            this.methods = new ArrayList();\n            this.fields = new ArrayList();\n            this.strings = new ArrayList();\n            this.callSites = new ArrayList();\n            this.methodHandles = new ArrayList();\n            this.seenClasses = Sets.newIdentityHashSet();\n            this.id = id;\n        }\n\n        private <T extends IndexedDexItem> boolean addItem(T item, List<T> itemList) {\n            assert item != null;\n\n            if (item.assignToVirtualFile(this.id)) {\n                itemList.add(item);\n                return true;\n            } else {\n                return false;\n            }\n        }\n\n        public boolean addClass(DexProgramClass clazz) {\n            if (this.seenClasses.add(clazz)) {\n                this.classes.add(clazz);\n                return true;\n            } else {\n                return false;\n            }\n        }\n\n        public boolean addField(DexField field) {\n            return this.addItem(field, this.fields);\n        }\n\n        public boolean addMethod(DexMethod method) {\n            return this.addItem(method, this.methods);\n        }\n\n        public boolean addString(DexString string) {\n            return this.addItem(string, this.strings);\n        }\n\n        public boolean addProto(DexProto proto) {\n            return this.addItem(proto, this.protos);\n        }\n\n        public boolean addCallSite(DexCallSite callSite) {\n            return this.addItem(callSite, this.callSites);\n        }\n\n        public boolean addMethodHandle(DexMethodHandle methodHandle) {\n            return this.addItem(methodHandle, this.methodHandles);\n        }\n\n        public boolean addType(DexType type) {\n            return this.addItem(type, this.types);\n        }\n\n        public int getNumberOfMethods() {\n            return this.methods.size();\n        }\n\n        public int getNumberOfFields() {\n            return this.fields.size();\n        }\n\n        public int getNumberOfStrings() {\n            return this.strings.size();\n        }\n    }\n\n    public static class PackageMapDistributor extends AtlasVirtualFile.DistributorBase {\n        private final PackageDistribution packageDistribution;\n        private final ExecutorService executorService;\n\n        PackageMapDistributor(ApplicationWriter writer, PackageDistribution packageDistribution, ExecutorService executorService) {\n            super(writer);\n            this.packageDistribution = packageDistribution;\n            this.executorService = executorService;\n        }\n\n        public Map<Integer, AtlasVirtualFile> run() throws ExecutionException, IOException {\n            assert this.nameToFileMap.size() == 1;\n\n            assert this.nameToFileMap.containsKey(0);\n\n            int maxReferencedIndex = this.packageDistribution.maxReferencedIndex();\n\n            for(int index = 1; index <= maxReferencedIndex; ++index) {\n                AtlasVirtualFile file = new AtlasVirtualFile(index, this.writer.namingLens);\n                this.nameToFileMap.put(index, file);\n            }\n\n            this.fillForMainDexList(this.classes);\n            this.classes = this.sortClassesByPackage(this.classes, this.originalNames);\n            Set<String> usedPrefixes = this.fillForDistribution(this.classes, this.originalNames);\n            Map newAssignments;\n            if (this.classes.isEmpty()) {\n                newAssignments = Collections.emptyMap();\n            } else {\n                newAssignments = (new AtlasVirtualFile.PackageSplitPopulator(this.nameToFileMap, this.classes, this.originalNames, usedPrefixes, this.application.dexItemFactory, AtlasVirtualFile.FillStrategy.LEAVE_SPACE_FOR_GROWTH, this.writer.namingLens)).call();\n                if (!newAssignments.isEmpty() && this.nameToFileMap.size() > 1) {\n                    System.err.println(\" * The used package map is missing entries. The following default mappings have been used:\");\n                    this.writeAssignments(newAssignments, new OutputStreamWriter(System.err));\n                    System.err.println(\" * Consider updating the map.\");\n                }\n            }\n\n            Path newPackageMap = Paths.get(\"package.map\");\n            System.out.println(\" - \" + newPackageMap.toString());\n            PackageDistribution.writePackageToFileMap(newPackageMap, newAssignments, this.packageDistribution);\n            return this.nameToFileMap;\n        }\n\n        private Set<String> fillForDistribution(Set<DexProgramClass> classes, Map<DexProgramClass, String> originalNames) throws ExecutionException {\n            Set<String> usedPrefixes = null;\n            if (this.packageDistribution != null) {\n                ArrayList<Future<List<DexProgramClass>>> futures = new ArrayList(this.nameToFileMap.size());\n                usedPrefixes = this.packageDistribution.getFiles();\n                Iterator var5 = this.nameToFileMap.values().iterator();\n\n                while(var5.hasNext()) {\n                    AtlasVirtualFile file = (AtlasVirtualFile)var5.next();\n                    AtlasVirtualFile.PackageMapPopulator populator = new AtlasVirtualFile.PackageMapPopulator(file, classes, this.packageDistribution, originalNames);\n                    futures.add(this.executorService.submit(populator));\n                }\n\n                ThreadUtils.awaitFutures(futures).forEach(classes::removeAll);\n            }\n\n            return usedPrefixes;\n        }\n\n        private void writeAssignments(Map<String, Integer> assignments, Writer output) throws IOException {\n            Iterator var3 = assignments.entrySet().iterator();\n\n            while(var3.hasNext()) {\n                Map.Entry<String, Integer> entry = (Map.Entry)var3.next();\n                output.write(\"    \");\n                PackageDistribution.formatEntry(entry, output);\n                output.write(\"\\n\");\n            }\n\n            output.flush();\n        }\n    }\n\n    public static class MonoDexDistributor extends AtlasVirtualFile.DistributorBase {\n        MonoDexDistributor(ApplicationWriter writer) {\n            super(writer);\n        }\n\n        public Map<Integer, AtlasVirtualFile> run() throws ExecutionException, IOException {\n            Iterator var1 = this.classes.iterator();\n\n            while(var1.hasNext()) {\n                DexProgramClass programClass = (DexProgramClass)var1.next();\n                this.mainDexFile.addClass(programClass);\n            }\n\n            this.mainDexFile.commitTransaction();\n            this.mainDexFile.throwIfFull(false);\n            return this.nameToFileMap;\n        }\n    }\n\n    public static class FillFilesDistributor extends AtlasVirtualFile.DistributorBase {\n        boolean minimalMainDex;\n        private final AtlasVirtualFile.FillStrategy fillStrategy;\n\n        FillFilesDistributor(ApplicationWriter writer, boolean minimalMainDex) {\n            super(writer);\n            this.minimalMainDex = minimalMainDex;\n            this.fillStrategy = FillStrategy.FILL_MAX;\n        }\n\n        public Map<Integer, AtlasVirtualFile> run() throws ExecutionException, IOException {\n            this.fillForMainDexList(this.classes);\n            if (this.classes.isEmpty()) {\n                return this.nameToFileMap;\n            } else {\n                Map<Integer, AtlasVirtualFile> filesForDistribution = this.nameToFileMap;\n                if (this.minimalMainDex && !this.mainDexFile.isEmpty()) {\n                    assert !((AtlasVirtualFile)this.nameToFileMap.get(0)).isEmpty();\n\n                    this.nameToFileMap.put(1, new AtlasVirtualFile(1, this.writer.namingLens));\n                    filesForDistribution = Maps.filterKeys(filesForDistribution, (key) -> {\n                        return key != 0;\n                    });\n                }\n\n                this.classes = this.sortClassesByPackage(this.classes, this.originalNames);\n                (new AtlasVirtualFile.PackageSplitPopulator(filesForDistribution, this.classes, this.originalNames, (Set)null, this.application.dexItemFactory, this.fillStrategy, this.writer.namingLens)).call();\n                return this.nameToFileMap;\n            }\n        }\n    }\n\n    public abstract static class DistributorBase extends AtlasVirtualFile.Distributor {\n        protected Set<DexProgramClass> classes;\n        protected Map<DexProgramClass, String> originalNames;\n        protected final AtlasVirtualFile mainDexFile;\n\n        DistributorBase(ApplicationWriter writer) {\n            super(writer);\n            this.mainDexFile = new AtlasVirtualFile(0, writer.namingLens);\n            this.nameToFileMap.put(0, this.mainDexFile);\n            if (writer.markerString != null) {\n                this.mainDexFile.transaction.addString(writer.markerString);\n                this.mainDexFile.commitTransaction();\n            }\n\n            this.classes = Sets.newHashSet(this.application.classes());\n            this.originalNames = AtlasVirtualFile.computeOriginalNameMapping(this.classes, this.application.getProguardMap());\n        }\n\n        protected void fillForMainDexList(Set<DexProgramClass> classes) {\n            if (!this.application.mainDexList.isEmpty()) {\n                AtlasVirtualFile mainDexFile = (AtlasVirtualFile)this.nameToFileMap.get(0);\n\n                for(UnmodifiableIterator var3 = this.application.mainDexList.iterator(); var3.hasNext(); mainDexFile.commitTransaction()) {\n                    DexType type = (DexType)var3.next();\n                    DexClass clazz = this.application.definitionFor(type);\n                    if (clazz != null && clazz.isProgramClass()) {\n                        DexProgramClass programClass = (DexProgramClass)clazz;\n                        mainDexFile.addClass(programClass);\n                        classes.remove(programClass);\n                    } else {\n                        System.out.println(\"WARNING: Application does not contain `\" + type.toSourceString() + \"` as referenced in main-dex-list.\");\n                    }\n                }\n\n                mainDexFile.throwIfFull(true);\n            }\n\n        }\n\n        TreeSet<DexProgramClass> sortClassesByPackage(Set<DexProgramClass> classes, Map<DexProgramClass, String> originalNames) {\n            TreeSet<DexProgramClass> sortedClasses = new TreeSet((a, b) -> {\n                String originalA = (String)originalNames.get(a);\n                String originalB = (String)originalNames.get(b);\n                int indexA = originalA.lastIndexOf(46);\n                int indexB = originalB.lastIndexOf(46);\n                if (indexA == -1 && indexB == -1) {\n                    return originalA.compareTo(originalB);\n                } else if (indexA == -1) {\n                    return -1;\n                } else if (indexB == -1) {\n                    return 1;\n                } else {\n                    String prefixA = originalA.substring(0, indexA);\n                    String prefixB = originalB.substring(0, indexB);\n                    int result = prefixA.compareTo(prefixB);\n                    return result != 0 ? result : originalA.compareTo(originalB);\n                }\n            });\n            sortedClasses.addAll(classes);\n            return sortedClasses;\n        }\n    }\n\n    public static class FilePerClassDistributor extends AtlasVirtualFile.Distributor {\n        FilePerClassDistributor(ApplicationWriter writer) {\n            super(writer);\n        }\n\n        public Map<Integer, AtlasVirtualFile> run() throws ExecutionException, IOException {\n            Iterator var1 = this.application.classes().iterator();\n\n            while(var1.hasNext()) {\n                DexProgramClass clazz = (DexProgramClass)var1.next();\n                AtlasVirtualFile file = new AtlasVirtualFile(this.nameToFileMap.size(), this.writer.namingLens);\n                this.nameToFileMap.put(this.nameToFileMap.size(), file);\n                file.addClass(clazz);\n                file.commitTransaction();\n            }\n\n            return this.nameToFileMap;\n        }\n    }\n\n    public abstract static class Distributor {\n        protected final DexApplication application;\n        protected final ApplicationWriter writer;\n        protected final Map<Integer, AtlasVirtualFile> nameToFileMap = new HashMap();\n\n        Distributor(ApplicationWriter writer) {\n            this.application = writer.application;\n            this.writer = writer;\n        }\n\n        public abstract Map<Integer, AtlasVirtualFile> run() throws ExecutionException, IOException;\n    }\n\n    static enum FillStrategy {\n        FILL_MAX,\n        LEAVE_SPACE_FOR_GROWTH;\n\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/AtlasAppPlugin.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder;\n\nimport com.android.build.gradle.AppPlugin;\nimport com.taobao.android.builder.manager.PluginManager;\nimport org.gradle.api.Plugin;\nimport org.gradle.api.Project;\n\n/**\n * Created by wuzhong on 2017/3/15.\n *\n * @author wuzhong\n * @date 2017/03/15\n */\npublic class AtlasAppPlugin implements Plugin<Project> {\n\n    @Override\n    public void apply(Project project) {\n        PluginManager.addPluginIfNot(project, AppPlugin.class);\n\n        PluginManager.addPluginIfNot(project, AtlasPlugin.class);\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/AtlasBasePlugin.java",
    "content": "package com.taobao.android.builder;\n\nimport com.android.tools.r8.AtlasD8;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.manager.AtlasConfigurationHelper;\nimport com.taobao.android.builder.manager.Version;\nimport com.taobao.android.builder.tools.PluginTypeUtils;\nimport com.taobao.android.builder.tools.log.LogOutputListener;\nimport com.taobao.android.builder.tools.process.ApkProcessor;\nimport org.gradle.BuildResult;\nimport org.gradle.api.Action;\nimport org.gradle.api.Plugin;\nimport org.gradle.api.Project;\nimport org.gradle.api.tasks.StopExecutionException;\nimport org.gradle.internal.reflect.Instantiator;\n\nimport javax.inject.Inject;\nimport java.util.regex.Pattern;\n\n/**\n * @author lilong\n * @create 2017-08-23 When in the morning\n */\n\npublic abstract class AtlasBasePlugin implements Plugin<Project> {\n\n    public static final String BUNDLE_COMPILE = \"bundleCompile\";\n    public static final String PROVIDED_COMPILE = \"providedCompile\";\n\n    protected Project project;\n    public static final Pattern PLUGIN_ACCEPTABLE_VERSIONS = Pattern.compile(\"3\\\\.[0-9].*\");\n    public static final String PLUGIN_MIN_VERSIONS = \"3.0.0\";\n\n    public static final Pattern JDK_VERSIONS = Pattern.compile(\"1\\\\.[8-9].*\");\n    public static final String JDK_MIN_VERSIONS = \"1.8\";\n\n    protected Instantiator instantiator;\n\n    protected AtlasExtension atlasExtension;\n\n    public static String creator = \"AtlasPlugin\" + Version.ANDROID_GRADLE_PLUGIN_VERSION;\n\n    protected AtlasConfigurationHelper atlasConfigurationHelper;\n\n\n    @Inject\n    public AtlasBasePlugin(Instantiator instantiator) {\n\n        this.instantiator = instantiator;\n\n    }\n    @Override\n    public void apply(Project project) {\n        this.project = project;\n        LogOutputListener.addListener(project);\n\n        checkPluginSetup();\n\n        atlasConfigurationHelper = getConfigurationHelper(project);\n\n\n        AtlasBuildContext.atlasConfigurationHelper = atlasConfigurationHelper;\n\n        atlasExtension =  atlasConfigurationHelper.createExtendsion();\n\n\n    }\n\n    protected abstract AtlasConfigurationHelper getConfigurationHelper(Project project);\n\n    /**\n     * Determine if the plug-in's dependency configuration is correct\n     */\n    private void checkPluginSetup() {\n\n        if (!PluginTypeUtils.usedGooglePlugin(project)) {\n            throw new StopExecutionException(\"Atlas plugin need android plugin to run!\");\n        }\n\n        String androidVersion = com.android.builder.Version.ANDROID_GRADLE_PLUGIN_VERSION;\n        //Determine the Android pluginThe version of\n        if (!PLUGIN_ACCEPTABLE_VERSIONS.matcher(androidVersion).matches()) {\n            String errorMessage = String.format(\"Android Gradle plugin version %s is required. Current version is %s. \",\n                    PLUGIN_MIN_VERSIONS, androidVersion);\n            throw new StopExecutionException(errorMessage);\n        }\n\n        //check jdk version\n        String jdkVersion = System.getProperty(\"java.version\");\n        if (!JDK_VERSIONS.matcher(jdkVersion).matches()) {\n            String errorMessage = String.format(\"JDK version %s is required. Current version is %s. \",\n                    JDK_MIN_VERSIONS, jdkVersion);\n            throw new StopExecutionException(errorMessage);\n        }\n\n        project.getGradle().buildFinished(new Action<BuildResult>() {\n            @Override\n            public void execute(BuildResult buildResult) {\n                AtlasBuildContext.reset();\n                AtlasD8.deepShrink = false;\n            }\n        });\n\n//        if (BuildCacheUtils.isBuildCacheEnabled(project)) {\n//            //project.setProperty(AndroidGradleOptions.PROPERTY_ENABLE_BUILD_CACHE, false);\n//            String errorMessage = \"android.enableBuildCache is disabled by atlas, we will open it later, \"\n//                    + \"\\r\\n please `add android.enableBuildCache false` to gradle.properties\";\n//            //throw new StopExecutionException(errorMessage);\n//        }\n\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/AtlasBuildContext.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder;\n\nimport com.android.build.api.transform.QualifiedContent;\nimport com.android.builder.core.AtlasBuilder;\nimport com.android.builder.model.MavenCoordinates;\nimport com.google.common.collect.Maps;\nimport com.google.common.collect.Multimap;\nimport com.taobao.android.builder.adapter.BuilderAdapter;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.manager.AtlasConfigurationHelper;\nimport com.taobao.android.builder.tasks.app.BuildAtlasEnvTask;\nimport com.taobao.android.builder.tools.process.ApkProcessor;\nimport org.gradle.api.Project;\n\nimport java.io.File;\nimport java.util.*;\n\n/**\n * Created by shenghua.nish on 2016-05-09 At 3:50 p.m.\n */\npublic class AtlasBuildContext {\n\n    /**\n     * External plug-ins can change the specific implementation of this class\n     */\n    public static BuilderAdapter sBuilderAdapter = new BuilderAdapter();\n\n    public static Map<String,File>bundleExploadDir = new HashMap<>();\n\n    public static Map<String, AtlasDependencyTree> androidDependencyTrees = Maps.newHashMap();\n\n    public static Map<String, AtlasDependencyTree> libDependencyTrees = Maps.newHashMap();\n\n    public static Map<String, String> customPackageIdMaps = new HashMap<String, String>();\n\n    public static Map<Project, AtlasBuilder> androidBuilderMap = new HashMap<>();\n\n    public static Map<String, AwbBundle> awbBundleMap = new HashMap<String, AwbBundle>();\n\n//    public static AtlasMainDexHelper atlasMainDexHelper = new AtlasMainDexHelper();\n\n    public static Map<String,AtlasMainDexHelper> atlasMainDexHelperMap = new HashMap<>();\n\n\n    public static ApkProcessor atlasApkProcessor = new ApkProcessor.AtlasApkProcessor();\n\n    public static Set<String> conflictDependencies;\n\n\n    public static AtlasConfigurationHelper atlasConfigurationHelper;\n\n\n    public static STATUS status = STATUS.DEXARCHIVE;\n\n    /**\n     * Depending on the original coordinate address, classInject You need to find atlas.\n     *\n     * File open directory -> Coordinates the address\n     */\n    public static Map<String, MavenCoordinates> dependencyTraceMap = new HashMap<>();\n\n    /**\n     * Modified file -> The original file\n     */\n    public static Map<String, String> jarTraceMap = new HashMap<String, String>();\n\n    public static Set<File> localLibs = new HashSet<>();\n\n    public static void reset(){\n        dependencyTraceMap.clear();\n        jarTraceMap.clear();\n        conflictDependencies = null;\n        awbBundleMap.clear();\n        androidBuilderMap.clear();\n        customPackageIdMaps.clear();\n        libDependencyTrees.clear();\n        androidBuilderMap.clear();\n        localLibs.clear();\n        status = STATUS.DEXARCHIVE;\n        bundleExploadDir.clear();\n        atlasMainDexHelperMap.clear();\n\n    }\n\n    public enum STATUS{\n        MULTIDEX,DEXARCHIVE,PREDEX,DEX,EXTERNALLIBSMERGE,DEXMERGE\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/AtlasFeaturePlugin.java",
    "content": "package com.taobao.android.builder;\nimport com.android.build.gradle.*;\nimport com.taobao.android.builder.manager.PluginManager;\nimport org.gradle.api.Plugin;\nimport org.gradle.api.Project;\nimport org.gradle.internal.reflect.Instantiator;\nimport org.gradle.tooling.provider.model.ToolingModelBuilderRegistry;\n\nimport javax.inject.Inject;\n\n/**\n * AtlasFeaturePlugin\n *\n * @author zhayu.ll\n * @date 18/1/3\n * @time 下午7:04\n * @description  \n */\npublic class AtlasFeaturePlugin implements Plugin<Project> {\n\n\n    @Override\n    public void apply(Project project) {\n        PluginManager.addPluginIfNot(project,FeaturePlugin.class);\n        PluginManager.addPluginIfNot(project,AtlasPlugin.class);\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/AtlasInstantAppPlugin.java",
    "content": "package com.taobao.android.builder;\n\nimport com.android.build.gradle.AppPlugin;\nimport com.android.build.gradle.BasePlugin;\nimport com.android.build.gradle.InstantAppPlugin;\nimport com.taobao.android.builder.manager.AtlasConfigurationHelper;\nimport com.taobao.android.builder.manager.PluginManager;\nimport org.gradle.api.Project;\nimport org.gradle.internal.reflect.Instantiator;\n\n/**\n * AtlasInstantAppPlugin\n *\n * @author zhayu.ll\n * @date 18/1/4\n * @time 下午5:54\n * @description  \n */\npublic class AtlasInstantAppPlugin extends AtlasPlugin {\n\n\n    public AtlasInstantAppPlugin(Instantiator instantiator) {\n        super(instantiator);\n    }\n\n    @Override\n    public void apply(Project project) {\n        PluginManager.addPluginIfNot(project, AppPlugin.class);\n        PluginManager.addPluginIfNot(project, InstantAppPlugin.class);\n        super.apply(project);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/AtlasLibPlugin.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder;\n\nimport com.android.build.gradle.LibraryPlugin;\nimport com.taobao.android.builder.manager.PluginManager;\nimport org.gradle.api.Plugin;\nimport org.gradle.api.Project;\n\n/**\n * Created by wuzhong on 2017/3/15.\n *\n * @author wuzhong\n * @date 2017/03/15\n *\n */\npublic class AtlasLibPlugin implements Plugin<Project> {\n\n    @Override\n    public void apply(Project project) {\n\n        PluginManager.addPluginIfNot(project, LibraryPlugin.class);\n\n        PluginManager.addPluginIfNot(project, AtlasPlugin.class);\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/AtlasMainDexHelper.java",
    "content": "package com.taobao.android.builder;\n\n\nimport com.android.build.api.transform.JarInput;\nimport com.android.build.api.transform.QualifiedContent;\nimport com.google.common.collect.Multimap;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.app.BuildAtlasEnvTask;\nimport com.taobao.android.builder.tools.MD5Util;\nimport org.gradle.internal.impldep.com.amazonaws.util.Md5Utils;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.util.*;\nimport java.util.function.Predicate;\n\n/**\n * @author lilong\n * @create 2017-12-27 下午2:30\n */\n\npublic class AtlasMainDexHelper {\n\n    private LinkedHashSet<BuildAtlasEnvTask.FileIdentity> mainDexJar = new LinkedHashSet<>();\n\n\n    public List<File> getInputDirs() {\n        return inputDirs;\n    }\n\n    public void setInputDirs(List<File> inputLibraries) {\n        this.inputDirs = inputDirs;\n    }\n\n    private List<File> inputDirs = new ArrayList<>();\n\n    private Map<String, Boolean> mainManifestMap = new HashMap<>();\n\n    private Map<String, Boolean> mainNativeSoMap = new LinkedHashMap<>();\n\n    private Map<String, Boolean> mainRes = new LinkedHashMap<>();\n\n    public File getMainJavaRes() {\n        return mainJavaRes;\n    }\n\n\n    private File mainJavaRes;\n\n    private Map<QualifiedContent, List<File>> mainDexAchives = new HashMap<>();\n\n    public void addMainDexJars(Set<BuildAtlasEnvTask.FileIdentity> maindexs) {\n        mainDexJar.clear();\n        mainDexJar.addAll(maindexs);\n    }\n\n    public void addAllMainDexJars(Collection<File> maindexs) {\n        mainDexJar.clear();\n        for (File file : maindexs) {\n            mainDexJar.add(new BuildAtlasEnvTask.FileIdentity(file.getName(), file, false, false));\n\n        }\n    }\n\n\n    public void addMainDexManifests(Map mainDexMap) {\n        mainManifestMap.putAll(mainDexMap);\n    }\n\n    public void addMainDexNativeSos(Map mainNativeSo) {\n        mainNativeSoMap.putAll(mainNativeSo);\n    }\n\n    public void addMainRes(Map mainResMap) {\n        mainRes.putAll(mainResMap);\n    }\n\n\n    public Map<String, Boolean> getMainManifestFiles() {\n        return mainManifestMap;\n    }\n\n    public LinkedHashSet<BuildAtlasEnvTask.FileIdentity> getMainDexFiles() {\n        return mainDexJar;\n    }\n\n    public Map<String, Boolean> getMainSoFiles() {\n        return mainNativeSoMap;\n    }\n\n\n    public void updateMainDexFile(File oldFile, File newFile) {\n        for (BuildAtlasEnvTask.FileIdentity id : mainDexJar) {\n            if (!id.file.exists()){\n                continue;\n            }\n            try {\n                if (Files.isSameFile(oldFile.toPath(), id.file.toPath())) {\n                    id.file = newFile;\n                    break;\n                }\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n\n    }\n\n    public void updateMainDexFile(JarInput oldFile, File newFile) {\n        for (BuildAtlasEnvTask.FileIdentity id : mainDexJar) {\n            if (!id.file.exists()){\n                continue;\n            }\n            try {\n                if (Files.isSameFile(oldFile.getFile().toPath(), id.file.toPath())) {\n                    id.file = newFile;\n                    break;\n                } else if (oldFile.getName().startsWith(\"android.local.jars\")) {\n                    if (oldFile.getName().split(\":\")[1].equals(id.file.getName())) {\n                        id.file = newFile;\n                        break;\n                    }\n                }\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n        }\n\n    }\n\n    public void updateMainDexFiles(Map<JarInput, File> fileFileMap) {\n            for (Map.Entry<JarInput,File> entry : fileFileMap.entrySet()) {\n                if (entry.getKey().getFile().exists() && entry.getValue().exists()) {\n                    updateMainDexFile((JarInput) entry.getKey(), (File) entry.getValue());\n                }else {\n                    remove(entry.getKey().getFile());\n                }\n            }\n\n    }\n\n    public void updateMainDexFiles2(Map<File, File> fileFileMap) {\n        for (Map.Entry<File,File> entry : fileFileMap.entrySet()) {\n            if (entry.getKey().exists() && entry.getValue().exists()) {\n                updateMainDexFile((File) entry.getKey(), (File) entry.getValue());\n            }else {\n                remove(entry.getKey());\n            }\n        }\n\n    }\n\n    private void remove(File key) {\n        mainDexJar.removeIf(fileIdentity -> fileIdentity.file.equals(key));\n\n    }\n\n\n    public boolean inMainDex(JarInput jarInput) {\n        File file = jarInput.getFile();\n        boolean flag =  inMainDex(file);\n        if (!flag) {\n            if (jarInput.getName().startsWith(\"android.local.jars\")) {\n                return inMainDex(jarInput.getName().split(\":\")[1], jarInput);\n            }\n        }\n        return flag;\n    }\n\n    private boolean inMainDex(String name, JarInput jarInput) {\n        for (BuildAtlasEnvTask.FileIdentity fileIdentity : mainDexJar) {\n            if (fileIdentity.file.getName().equals(name)) {\n                fileIdentity.file = jarInput.getFile();\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public boolean inMainDex(File jarFile)  {\n        for (BuildAtlasEnvTask.FileIdentity fileIdentity : mainDexJar) {\n            if (!fileIdentity.file.exists()){\n                continue;\n            }\n            try {\n                if (Files.isSameFile(fileIdentity.file.toPath(), jarFile.toPath())) {\n                    return true;\n                }\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n\n        return false;\n    }\n\n\n    public BuildAtlasEnvTask.FileIdentity get(JarInput jarInput) {\n        File file = jarInput.getFile();\n        return get(file);\n    }\n\n    public BuildAtlasEnvTask.FileIdentity get(File jarFile) {\n        for (BuildAtlasEnvTask.FileIdentity fileIdentity : mainDexJar) {\n            try {\n                if (Files.isSameFile(fileIdentity.file.toPath(), jarFile.toPath())) {\n                    return fileIdentity;\n                }\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n        return null;\n    }\n\n\n    public void addMainDex(BuildAtlasEnvTask.FileIdentity fileIdentity) {\n        mainDexJar.add(fileIdentity);\n    }\n\n\n    public Collection<File> getAllMainDexJars() {\n        Set<File> allMainDexJars = new HashSet<>();\n        for (BuildAtlasEnvTask.FileIdentity fileIdentity : mainDexJar) {\n            if (fileIdentity.file.exists()) {\n                allMainDexJars.add(fileIdentity.file);\n            }\n        }\n        return allMainDexJars;\n    }\n\n    public Map<String, Boolean> getMainResFiles() {\n        return mainRes;\n    }\n\n    public void addMainDexAchives(Map<QualifiedContent, List<File>> cacheableItems) {\n        this.mainDexAchives.putAll(cacheableItems);\n    }\n\n    public Map<QualifiedContent, List<File>> getMainDexAchives() {\n        return mainDexAchives;\n    }\n\n    public void addMainJavaRes(File file) {\n        this.mainJavaRes = file;\n    }\n\n    public void  release(){\n        mainDexJar.clear();\n        inputDirs.clear();\n        mainRes.clear();\n        mainNativeSoMap.clear();\n        mainManifestMap.clear();\n        mainDexAchives.clear();\n        mainJavaRes = null;\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/AtlasPlugin.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder;\n\nimport com.taobao.android.builder.manager.AtlasConfigurationHelper;\nimport com.taobao.android.builder.tasks.helper.AtlasListTask;\nimport com.taobao.android.builder.tools.PluginTypeUtils;\nimport groovy.lang.Closure;\nimport org.gradle.api.Action;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Plugin;\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.Configuration;\nimport org.gradle.api.artifacts.Dependency;\nimport org.gradle.internal.reflect.Instantiator;\n\nimport javax.inject.Inject;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Created by shenghua.nish on 2016-05-17 Often in the morning.\n *\n * @author shenghua.nish, wuzhong\n */\npublic class AtlasPlugin extends AtlasBasePlugin {\n\n    @Inject\n    public AtlasPlugin(Instantiator instantiator) {\n        super(instantiator);\n    }\n\n    @Override\n    public void apply(Project project) {\n\n        super.apply(project);\n\n        atlasConfigurationHelper.createLibCompenents();\n\n\n\n        project.afterEvaluate(project1 -> {\n\n            if (PluginTypeUtils.isAppProject(project) && atlasExtension.isAtlasEnabled()) {\n\n                Map<String, String> multiDex = new HashMap<>();\n                multiDex.put(\"group\", \"com.android.support\");\n                multiDex.put(\"module\", \"multidex\");\n                project1.getConfigurations().all(configuration -> configuration.exclude(multiDex));\n\n            }\n\n            Plugin plugin = project.getPlugins().findPlugin(\"kotlin-android\");\n            if (plugin != null) {\n                project.getDependencies().add(\"compile\", \"org.jetbrains.kotlin:kotlin-stdlib:1.2.41\");\n            }\n\n            atlasConfigurationHelper.registAtlasStreams();\n\n\n            atlasConfigurationHelper.configDependencies(atlasExtension.getTBuildConfig().getAwbConfigFile());\n\n\n            //3. update extension\n            atlasConfigurationHelper.updateExtensionAfterEvaluate();\n\n            //4. Set up the android builder\n            try {\n                atlasConfigurationHelper.createBuilderAfterEvaluate();\n            } catch (Exception e) {\n                throw new GradleException(\"update builder failed\", e);\n            }\n\n            //5. Configuration tasks\n           atlasConfigurationHelper.configTasksAfterEvaluate();\n\n            project1.getTasks().create(\"atlasList\", AtlasListTask.class);\n\n        });\n\n    }\n\n    @Override\n    protected AtlasConfigurationHelper getConfigurationHelper(Project project) {\n        return new AtlasConfigurationHelper(project,\n                                            instantiator,\n                                            creator);\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/adapter/AppVariantContextFactory.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.adapter;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport com.android.build.gradle.AppExtension;\nimport com.android.build.gradle.api.ApplicationVariant;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.ApplicationVariantImpl;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport org.gradle.api.Project;\nimport org.jetbrains.annotations.NotNull;\n\n/**\n * Created by wuzhong on 2017/3/28.\n */\npublic class AppVariantContextFactory {\n\n    protected static Map<ApplicationVariant, AppVariantContext> appVariantContextMap\n        = new HashMap<ApplicationVariant, AppVariantContext>();\n\n    public AppVariantContext getAppVariantContext(Project project, ApplicationVariant applicationVariant) {\n\n        AppVariantContext appVariantContext = appVariantContextMap.get(applicationVariant);\n\n        if (null == appVariantContext) {\n\n            appVariantContext = create(project, (ApplicationVariantImpl)applicationVariant);\n\n            appVariantContextMap.put(applicationVariant, appVariantContext);\n\n        }\n\n        return appVariantContext;\n\n    }\n\n    @NotNull\n    public AppVariantContext create(Project project, ApplicationVariantImpl applicationVariant) {\n\n        AppVariantContext appVariantContext;\n        AppExtension appExtension = project.getExtensions().getByType(AppExtension.class);\n\n        AtlasExtension atlasExtension = project.getExtensions().getByType(AtlasExtension.class);\n\n        appVariantContext = new AppVariantContext(applicationVariant, project,\n                                                  atlasExtension, appExtension);\n        return appVariantContext;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/adapter/AtlasExtensionFactory.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.adapter;\n\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.extension.DexConfig;\nimport com.taobao.android.builder.extension.PatchConfig;\nimport com.taobao.android.builder.extension.TBuildType;\nimport com.taobao.android.builder.extension.factory.DexConfigFactory;\nimport com.taobao.android.builder.extension.factory.PatchConfigFactory;\nimport com.taobao.android.builder.extension.factory.TBuildTypeFactory;\nimport org.gradle.api.NamedDomainObjectContainer;\nimport org.gradle.api.Project;\nimport org.gradle.internal.reflect.Instantiator;\n\n/**\n * Created by wuzhong on 2017/3/29.\n */\npublic class AtlasExtensionFactory {\n\n    public AtlasExtension createExtendsion(Project project, Instantiator instantiator) {\n\n        AtlasExtension atlasExtension = getExtendsion(project);\n\n        if (null != atlasExtension) {\n            return atlasExtension;\n        }\n\n        final NamedDomainObjectContainer<TBuildType> buildTypeContainer = project.container(TBuildType.class,\n                                                                                            new TBuildTypeFactory(\n                                                                                                instantiator, project,\n                                                                                                project.getLogger()));\n        final NamedDomainObjectContainer<PatchConfig> patchConfigContainer = project.container(PatchConfig.class,\n                                                                                               new PatchConfigFactory(\n                                                                                                   instantiator,\n                                                                                                   project, project\n                                                                                                       .getLogger()));\n        final NamedDomainObjectContainer<DexConfig>dexConfigContainer = project.container(DexConfig.class,new DexConfigFactory(instantiator,project,project.getLogger()));\n\n        return project.getExtensions().create(\"atlas\", AtlasExtension.class, project, instantiator,\n                                              buildTypeContainer, patchConfigContainer,dexConfigContainer);\n\n    }\n\n    public AtlasExtension getExtendsion(Project project) {\n\n        return project.getExtensions().findByType(AtlasExtension.class);\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/adapter/BuilderAdapter.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.adapter;\n\nimport com.taobao.android.builder.tools.classinject.ApkInjectInfoCreator;\nimport com.taobao.android.builder.tools.sign.AndroidSigner;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Created by wuzhong on 2017/3/29.\n */\npublic class BuilderAdapter {\n\n    public AtlasExtensionFactory extensionFactory = new AtlasExtensionFactory();\n\n    public AppVariantContextFactory appVariantContextFactory = new AppVariantContextFactory();\n\n    public AndroidSigner androidSigner = new AndroidSigner();\n\n    public ApkInjectInfoCreator apkInjectInfoCreator = new ApkInjectInfoCreator();\n\n    public String tpatchHistoryUrl = \"\";\n\n    public boolean packageRemoteAwbInJni = true;\n\n    /**\n     * Add the atlas and atlasupdate dependencies to the main dex\n     */\n    public boolean addAtlasDependency = true;\n\n    /**\n     * bundleAllows local jars to be used by default, Taobao does not open\n     * The local jar of the main bundle is always open\n     */\n    public boolean localJarEnabled = true;\n    /**\n     * Reliance on standard formats\n     */\n    public boolean prettyDependencyFormat = true;\n\n    public boolean pushCacheToNetwork = true;\n\n    public List<String> buildInfos = new ArrayList<>();\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/AtlasDependencyTree.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\nimport com.android.builder.model.AndroidLibrary;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.dependency.model.SoLibrary;\nimport com.taobao.android.builder.dependency.output.DependencyJson;\nimport com.taobao.android.builder.dependency.parser.ResolvedDependencyInfo;\n\n/**\n * AndroidCompiled dependency libraries\n * Created by shenghua.nish on 2016-05-05 5:59 in the afternoon.\n * <p>\n * 1. There is no dependency\n * 2. Just differentiate the dependencies of the main bundle awb Rely on\n *\n * @author shenghua.nish, wuzhong\n */\npublic class AtlasDependencyTree {\n\n    private List<ResolvedDependencyInfo> mResolvedDependencies = Lists.newArrayList();\n\n    /**\n     * The dependency information of the main bundle\n     */\n    private AwbBundle mainBundle = new AwbBundle();\n\n    /**\n     * awb bundleDependent information\n     */\n    private List<AwbBundle> awbBundles = Lists.newArrayList();\n\n    private DependencyJson dependencyJson;\n\n    private List<AndroidLibrary> allAndroidLibrarys;\n\n    public AtlasDependencyTree(List<ResolvedDependencyInfo> mResolvedDependencies) {\n        this.mResolvedDependencies = mResolvedDependencies;\n    }\n\n    private void addChildDependency(List<String> deps, ResolvedDependencyInfo dependencyInfo,\n            boolean printFileSize) {\n        for (ResolvedDependencyInfo child : dependencyInfo.getChildren()) {\n            String childValue = child.getDependencyString(printFileSize);\n            deps.add(childValue);\n            addChildDependency(deps, child, printFileSize);\n        }\n    }\n\n    public AwbBundle getMainBundle() {\n        return mainBundle;\n    }\n\n    public void setMainBundle(AwbBundle mainBundle) {\n        this.mainBundle = mainBundle;\n    }\n\n    public List<AwbBundle> getAwbBundles() {\n        return awbBundles;\n    }\n\n    public void setAwbBundles(List<AwbBundle> awbBundles) {\n        this.awbBundles = awbBundles;\n    }\n\n    /**\n     * Get all aar and awb Rely on\n     *\n     * @return\n     */\n    public List<AndroidLibrary> getAllAndroidLibrarys() {\n\n        if (null == allAndroidLibrarys) {\n\n            allAndroidLibrarys = new ArrayList<>();\n\n            allAndroidLibrarys.addAll(getMainBundle().getAndroidLibraries());\n\n            for (AwbBundle awbBundle : getAwbBundles()) {\n                allAndroidLibrarys.add(awbBundle.getAndroidLibrary());\n                allAndroidLibrarys.addAll(awbBundle.getAndroidLibraries());\n            }\n        }\n\n        return allAndroidLibrarys;\n    }\n\n    /**\n     * Get all the awb dependency lists\n     *\n     * @return\n     */\n    public Set<AndroidLibrary> getAllAwbLibrarys() {\n        Set<AndroidLibrary> sets = new HashSet<>();\n        for (AwbBundle awbBundle : getAwbBundles()) {\n            sets.add(awbBundle.getAndroidLibrary());\n        }\n        return sets;\n    }\n\n    public Set<File> getAllLibraryManifests() {\n        Set<File> libManifests = new HashSet<File>();\n        for (AndroidLibrary manifestDependency : getAllAndroidLibrarys()) {\n            libManifests.add(manifestDependency.getManifest());\n        }\n        return libManifests;\n    }\n\n    public List<SoLibrary> getAllSoLibraries() {\n        List<SoLibrary> soLibraries = new ArrayList<>();\n        soLibraries.addAll(getMainBundle().getSoLibraries());\n        for (AwbBundle awbBundle : getAwbBundles()) {\n            soLibraries.addAll(awbBundle.getSoLibraries());\n        }\n        return soLibraries;\n    }\n\n    public Set<String> getFlatDependencies() {\n\n        DependencyJson dependencyJson = getDependencyJson();\n        Set<String> depenSets = new HashSet<String>();\n\n        if (null != dependencyJson.getAwbs()) {\n            for (String key : dependencyJson.getAwbs().keySet()) {\n                depenSets.add(key);\n                depenSets.addAll(dependencyJson.getAwbs().get(key));\n            }\n        }\n\n        depenSets.addAll(dependencyJson.getMainDex());\n        return depenSets;\n    }\n\n    /**\n     * Convert to ependencyJSon object\n     *\n     * @return\n     */\n    public DependencyJson getDependencyJson() {\n        if (dependencyJson == null) {\n            dependencyJson = createDependencyJson(false);\n        }\n        return dependencyJson;\n    }\n\n    public DependencyJson createDependencyJson(boolean printFileSize) {\n        DependencyJson dependencyJson = new DependencyJson();\n        for (ResolvedDependencyInfo dep : mResolvedDependencies) {\n            String value = dep.getDependencyString(printFileSize);\n            if (\"awb\".equalsIgnoreCase(dep.getType())) {\n                ArrayList<String> awbDeps = dependencyJson.getAwbs().get(value);\n                if (null == awbDeps) {\n                    awbDeps = new ArrayList<String>();\n                }\n                addChildDependency(awbDeps, dep, printFileSize);\n                dependencyJson.getAwbs().put(value, awbDeps);\n            } else {\n                dependencyJson.getMainDex().add(value);\n                addChildDependency(dependencyJson.getMainDex(), dep, printFileSize);\n            }\n        }\n        return dependencyJson;\n    }\n\n    public List<ResolvedDependencyInfo> getResolvedDependencies() {\n        return mResolvedDependencies;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/AtlasProjectDependencyManager.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency;\n\nimport java.util.function.Consumer;\n\nimport com.taobao.android.builder.AtlasPlugin;\nimport org.gradle.api.Project;\nimport org.gradle.api.Task;\nimport org.gradle.api.artifacts.Dependency;\nimport org.gradle.api.artifacts.DependencySet;\nimport org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency;\n\n/**\n * Created by wuzhong on 2017/3/16.\n *\n * @author wuzhong\n * @date 2017/03/16\n */\npublic class AtlasProjectDependencyManager {\n\n    public static void addProjectDependency(Project project, String variantName) {\n\n        Task task = project.getTasks().findByName(\"prepare\" + variantName + \"Dependencies\");\n\n        if (null == task){\n            return;\n        }\n\n        DependencySet dependencies = project.getConfigurations().getByName(\n            AtlasPlugin.BUNDLE_COMPILE).getDependencies();\n\n        if (null == dependencies){\n            return;\n        }\n\n        dependencies.forEach(new Consumer<Dependency>() {\n            @Override\n            public void accept(Dependency dependency) {\n                if (dependency instanceof  DefaultProjectDependency){\n\n                    Project subProject = ((DefaultProjectDependency)dependency).getDependencyProject();\n\n                    Task assembleTask = subProject.getTasks().findByName(\"assembleRelease\");\n\n                    task.dependsOn(assembleTask);\n\n                }\n            }\n        });\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/ap/ApDependency.java",
    "content": "package com.taobao.android.builder.dependency.ap;\n\nimport com.alibaba.fastjson.JSON;\nimport com.google.common.base.Predicate;\nimport com.google.common.collect.Collections2;\nimport com.google.common.collect.Iterables;\nimport com.google.common.collect.Maps;\nimport com.taobao.android.builder.dependency.output.DependencyJson;\nimport com.taobao.android.builder.dependency.parser.ResolvedDependencyInfo;\nimport com.taobao.android.builder.extension.TBuildType;\nimport org.apache.commons.io.IOUtils;\nimport org.gradle.api.Nullable;\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.Configuration;\nimport org.gradle.api.artifacts.Dependency;\nimport org.gradle.api.artifacts.ModuleIdentifier;\nimport org.gradle.api.artifacts.dsl.DependencyHandler;\nimport org.gradle.api.internal.artifacts.DefaultModuleIdentifier;\nimport org.gradle.api.internal.artifacts.dsl.ParsedModuleStringNotation;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\nimport static com.android.build.gradle.internal.api.ApContext.DEPENDENCIES_FILENAME;\nimport static com.google.common.base.Strings.isNullOrEmpty;\n\n/**\n * @author lilong\n * @create 2017-12-03 下午1:49\n */\n\npublic class ApDependency {\n\n    private final DependencyHandler dependencies;\n\n\n    private final Map<ModuleIdentifier, String> mFlatDependenciesMap = Maps.newHashMap();\n\n    private final Map<ModuleIdentifier, String> mMainDependenciesMap = Maps.newHashMap();\n\n    private final Map<ModuleIdentifier, Map<ModuleIdentifier, String>> mAwbDependenciesMap = Maps.newHashMap();\n\n    private final DependencyJson apDependencyJson;\n\n    public ApDependency(Project project, TBuildType tBuildType) {\n        this.dependencies = project.getDependencies();\n        File apBaseFile;\n        apBaseFile = getBaseApFile(project, tBuildType);\n\n        try (ZipFile zip = new ZipFile(apBaseFile)) {\n            ZipEntry entry = zip.getEntry(DEPENDENCIES_FILENAME);\n            try (InputStream in = zip.getInputStream(entry)) {\n                apDependencyJson = JSON.parseObject(IOUtils.toString(in, StandardCharsets.UTF_8), DependencyJson.class);\n            }\n        } catch (IOException e) {\n            throw new RuntimeException(\"Unable to read dependencies.txt from \" + apBaseFile.getAbsolutePath(), e);\n        }\n\n        for (String mainDex : apDependencyJson.getMainDex()) {\n            addDependency(mainDex, mMainDependenciesMap);\n        }\n        for (Map.Entry<String, ArrayList<String>> entry : apDependencyJson.getAwbs().entrySet()) {\n            String awb = entry.getKey();\n            Map<ModuleIdentifier, String> awbDependencies = getAwbDependencies(awb);\n            addDependency(awb, awbDependencies);\n            ArrayList<String> dependenciesString = entry.getValue();\n            for (String dependencyString : dependenciesString) {\n                addDependency(dependencyString, awbDependencies);\n            }\n        }\n    }\n\n    private Map<ModuleIdentifier, String> getAwbDependencies(String awb) {\n        ParsedModuleStringNotation parsedNotation = new ParsedModuleStringNotation(awb,\"awb\");\n        String group = parsedNotation.getGroup();\n        String name = parsedNotation.getName();\n        ModuleIdentifier moduleIdentifier = DefaultModuleIdentifier.newId(group, name);\n        Map<ModuleIdentifier, String> awbDependencies = mAwbDependenciesMap.get(moduleIdentifier);\n        if (awbDependencies == null) {\n            awbDependencies = Maps.newHashMap();\n            mAwbDependenciesMap.put(moduleIdentifier, awbDependencies);\n        }\n        return awbDependencies;\n    }\n\n    public Map<ModuleIdentifier, String> getAwbDependencies(String group, String name) {\n        ModuleIdentifier moduleIdentifier = DefaultModuleIdentifier.newId(group, name);\n        Map<ModuleIdentifier, String> awbDependencies = mAwbDependenciesMap.get(moduleIdentifier);\n        return awbDependencies;\n    }\n\n    private File getBaseApFile(Project project, TBuildType tBuildType) {\n        File apBaseFile;\n        File buildTypeBaseApFile = tBuildType.getBaseApFile();\n        if (null != buildTypeBaseApFile && buildTypeBaseApFile.exists()) {\n            apBaseFile = buildTypeBaseApFile;\n        } else if (!isNullOrEmpty(tBuildType.getBaseApDependency())) {\n            String apDependency = tBuildType.getBaseApDependency();\n            // Preconditions.checkNotNull(apDependency,\n            //                            \"You have to specify the baseApFile property or the baseApDependency\n            // dependency\");\n            Dependency dependency = project.getDependencies().create(apDependency);\n            Configuration configuration = project.getConfigurations().detachedConfiguration(dependency);\n            configuration.setTransitive(false);\n            apBaseFile = Iterables.getOnlyElement(Collections2.filter(configuration.getFiles(), new Predicate<File>() {\n                @Override\n                public boolean apply(@Nullable File file) {\n                    return file.getName().endsWith(\".ap\");\n                }\n            }));\n        } else {\n            throw new IllegalStateException(\"AP is missing\");\n        }\n        return apBaseFile;\n    }\n\n    public boolean isMainLibrary(ResolvedDependencyInfo dependencyInfo) {\n        return mMainDependenciesMap.containsKey(\n                DefaultModuleIdentifier.newId(dependencyInfo.getGroup(), dependencyInfo.getName()));\n    }\n\n    // ----- PRIVATE TASK API -----\n\n    private void addDependency(String dependencyString, Map<ModuleIdentifier, String> awb) {\n        ParsedModuleStringNotation parsedNotation = new ParsedModuleStringNotation(dependencyString,dependencyString.split(\"@\")[1]);\n        ModuleIdentifier moduleIdentifier = DefaultModuleIdentifier.newId(parsedNotation.getGroup(),\n                parsedNotation.getName());\n        String version = parsedNotation.getVersion();\n        awb.put(moduleIdentifier, version);\n        mFlatDependenciesMap.put(moduleIdentifier, version);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/diff/DependencyCompareUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency.diff;\n\nimport com.alibaba.fastjson.JSON;\nimport com.taobao.android.builder.dependency.output.DependencyJson;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\n\n\n/**\n * Rely on the comparison tool class\n * Created by shenghua.nish on 2016-04-05 Good afternoon.\n */\npublic class DependencyCompareUtils {\n\n    private static Logger logger = LoggerFactory.getLogger(DependencyCompareUtils.class);\n\n    /**\n     * Get the difference in dependency between the two versions\n     *\n     * @param baseDependecyFile\n     * @param newDependencyJson\n     * @return\n     */\n    public static DependencyDiff diff(File baseDependecyFile, DependencyJson newDependencyJson) throws IOException {\n        String baseDependencyStr = FileUtils.readFileToString(baseDependecyFile);\n        DependencyJson baseDependencyJson = JSON.parseObject(baseDependencyStr, DependencyJson.class);\n        return diff(baseDependencyJson, newDependencyJson);\n    }\n\n\n    /**\n     * Compare their dependency differences\n     *\n     * @param baseDependencyJson\n     * @param newDependencyJson\n     * @return\n     */\n    public static DependencyDiff diff(DependencyJson baseDependencyJson, DependencyJson newDependencyJson) {\n        DependencyDiff diffResult = new DependencyDiff();\n        // 1. First judge the change of the main dex, for remove, not as a column of change\n        List<String> baseMainDependecies = baseDependencyJson.getMainDex();\n        List<String> newMainDependecies = newDependencyJson.getMainDex();\n        diffResult.setMainDexDiffs(getDiffDependencies(baseMainDependecies, newMainDependecies));\n        if (!diffResult.getMainDexDiffs().isEmpty()) {\n            for (String line : diffResult.getMainDexDiffs()) {\n                diffResult.getMainDexDiffs().add(line);\n            }\n            logger.info(\"[Diff]MainBundle,Diff:\" + StringUtils.join(diffResult.getMainDexDiffs(), \",\"));\n        }\n        // 2. Determine the change in awb\n        Map<String, AwbDependency> baseAwbs = toAwbDependencies(baseDependencyJson.getAwbs());\n        Map<String, AwbDependency> newAwbs = toAwbDependencies(newDependencyJson.getAwbs());\n\n        Set<String> baseAwbBundles = new HashSet<String>();\n\n        for (String bundleName : newAwbs.keySet()) {\n            AwbDependency newAwbDeps = newAwbs.get(bundleName);\n            AwbDependency baseAwbDeps = baseAwbs.get(bundleName);\n            if (null != baseAwbDeps) {\n                if (baseAwbDeps.version.equals(newAwbDeps.version)) {\n                    Set<String> awbDiffs = getDiffDependencies(baseAwbDeps.dependencies, newAwbDeps.dependencies);\n                    if (!awbDiffs.isEmpty()) {\n                        System.out.println(\"[DiffAwb]\" + bundleName + \",Diff:\" + StringUtils.join(awbDiffs, \",\"));\n                        diffResult.getAwbDiffs().add(bundleName);\n                        // Writes a change to the file\n                        diffResult.getModifyLines().add(bundleName + \"(\" + newAwbDeps.version + \")\");\n                        for (String awbDiff : awbDiffs) {\n                            diffResult.getModifyLines().add(\"  \" + awbDiff);\n                        }\n                    }\n                } else {\n                    logger.info(\"[DiffAwb]\" + bundleName + \",baseVersion:\" + baseAwbDeps.version + \",newVersion:\"\n                            + newAwbDeps.version);\n                    // Writes a change to the file\n                    diffResult.getModifyLines().add(bundleName + \"(\" + baseAwbDeps.version + \"=>\" + newAwbDeps.version\n                            + \")\");\n                    Set<String> awbDiffs = getDiffDependencies(baseAwbDeps.dependencies, newAwbDeps.dependencies);\n                    if (!awbDiffs.isEmpty()) {\n                        // Writes a change to the file\n                        for (String awbDiff : awbDiffs) {\n                            diffResult.getModifyLines().add(\"  \" + awbDiff);\n                        }\n                    }\n                    diffResult.getAwbDiffs().add(bundleName);\n                }\n            } else {\n                System.out.println(\"[NewAwb]\" + bundleName + \",newVersion:\" + newAwbs.get(bundleName).version);\n                diffResult.getAwbDiffs().add(bundleName);\n                diffResult.getNewAwbs().add(bundleName);\n                diffResult.getModifyLines().add(bundleName + \"(0=>\" + newAwbDeps.version + \")\");\n                // Decide if it's a new bundle\n                if (!baseAwbBundles.contains(bundleName)) {\n                    diffResult.getNewAwbs().add(bundleName);\n                }\n            }\n        }\n        return diffResult;\n    }\n\n    /**\n     * To compare the diff\n     *\n     * @param baseDependecies\n     * @param newDependecies\n     * @return\n     */\n    private static Set<String> getDiffDependencies(List<String> baseDependecies, List<String> newDependecies) {\n        Set<String> diffs = new HashSet<String>();\n        Map<String, String> baseMap = new HashMap<String, String>();\n        for (String dep : baseDependecies) {\n            String name = dep.substring(0, dep.lastIndexOf(\":\"));\n            String version = dep.substring(dep.lastIndexOf(\":\") + 1);\n            baseMap.put(name, version);\n        }\n        Map<String, String> newMap = new HashMap<String, String>();\n        for (String dep : newDependecies) {\n            String name = dep.substring(0, dep.lastIndexOf(\":\"));\n            String version = dep.substring(dep.lastIndexOf(\":\") + 1);\n            newMap.put(name, version);\n        }\n        for (String key : newMap.keySet()) {\n            String baseValue = baseMap.get(key);\n            String newValue = newMap.get(key);\n            if (!newValue.equals(baseValue)) {\n                diffs.add(key + \"(\" + baseValue + \"=>\" + newValue + \")\");\n            }\n        }\n        return diffs;\n    }\n\n    private static Map<String, AwbDependency> toAwbDependencies(Map<String, ArrayList<String>> awbs) {\n        Map<String, AwbDependency> maps = new HashMap<String, AwbDependency>();\n        for (Map.Entry<String, ArrayList<String>> entry : awbs.entrySet()) {\n            String key = entry.getKey();\n\n            String version = \"\";\n            String name = \"\";\n\n            if (key.contains(\"@\")){\n                String[] arr = key.split(\"[@|:]\");\n                name = arr[0]+\":\"+arr[1];\n                version = arr[2];\n            }else {\n                version = key.substring(key.lastIndexOf(\":\") + 1);\n                name = key.substring(0, key.lastIndexOf(\":\"));\n                name = name.substring(0, name.lastIndexOf(\":\"));\n            }\n            AwbDependency awbDependency = new AwbDependency(version, name, entry.getValue());\n            maps.put(name, awbDependency);\n        }\n        return maps;\n    }\n\n    static class AwbDependency {\n        String version;\n        String bundleName;\n        ArrayList<String> dependencies;\n\n        public AwbDependency(String version, String bundleName, ArrayList<String> dependencies) {\n            this.version = version;\n            this.bundleName = bundleName;\n            this.dependencies = dependencies;\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/diff/DependencyDiff.java",
    "content": "\n/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency.diff;\n\nimport java.util.List;\nimport java.util.Set;\n\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Sets;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\n\n/**\n * Dependency differential information\n * Created by shenghua.nish on 2016-04-05 Moreover in the afternoon.\n */\npublic class DependencyDiff {\n\n    private Set<String>  mainDexDiffs = Sets.newHashSet();\n    private Set<String>  awbDiffs = Sets.newHashSet();\n    private Set<String>  newAwbs = Sets.newHashSet();\n    private List<String> modifyLines = Lists.newArrayList();\n\n    public Set<String> getMainDexDiffs() {\n        return mainDexDiffs;\n    }\n\n    public void setMainDexDiffs(Set<String> mainDexDiffs) {\n        this.mainDexDiffs = mainDexDiffs;\n    }\n\n    public Set<String> getAwbDiffs() {\n        return awbDiffs;\n    }\n\n    public void setAwbDiffs(Set<String> awbDiffs) {\n        this.awbDiffs = awbDiffs;\n    }\n\n    public Set<String> getNewAwbs() {\n        return newAwbs;\n    }\n\n    public void setNewAwbs(Set<String> newAwbs) {\n        this.newAwbs = newAwbs;\n    }\n\n    public List<String> getModifyLines() {\n        return modifyLines;\n    }\n\n    public void setModifyLines(List<String> modifyLines) {\n        this.modifyLines = modifyLines;\n    }\n\n    public boolean isDiffBundle(AwbBundle awbBundle){\n        String key = awbBundle.getResolvedCoordinates().getGroupId() +\n                \":\" +\n                awbBundle.getResolvedCoordinates().getArtifactId();\n        return awbDiffs.contains(key);\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/model/ApLibrary.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency.model;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.builder.model.MavenCoordinates;\n\nimport java.io.File;\n\n/**\n * Created by shenghua.nish on 2016-05-04 (in the afternoon.\n */\npublic class ApLibrary {\n\n    @Nullable\n    private final MavenCoordinates mResolvedCoordinates;\n\n    @NonNull\n    private final File mApFile;\n    /**\n     * Unzip folders\n     */\n    private File mApFolder;\n\n    @NonNull\n    public File getFolder() {\n        return mApFolder;\n    }\n\n    public ApLibrary(@Nullable MavenCoordinates mResolvedCoordinates, File mApFile, File mApFolder){\n        this.mResolvedCoordinates = mResolvedCoordinates;\n        this.mApFile = mApFile;\n        this.mApFolder = mApFolder;\n    }\n\n    public File getApFile() {\n        return mApFile;\n    }\n\n    @Nullable\n    public MavenCoordinates getResolvedCoordinates() {\n        return mResolvedCoordinates;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/model/ApkLibrary.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency.model;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.builder.model.MavenCoordinates;\n\nimport java.io.File;\n\n/**\n * Created by shenghua.nish on 2016-05-06 \"In the morning.\n */\npublic class ApkLibrary {\n\n    @Nullable\n    private final MavenCoordinates mResolvedCoordinates;\n\n    @NonNull\n    private final File apkFile;\n\n    public ApkLibrary(@Nullable MavenCoordinates mResolvedCoordinates, File apkFile){\n        this.mResolvedCoordinates = mResolvedCoordinates;\n        this.apkFile = apkFile;\n\n    }\n\n    public File getApkFile() {\n        return apkFile;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/model/AwbBundle.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency.model;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\n\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.builder.model.JavaLibrary;\nimport com.android.builder.model.MavenCoordinates;\nimport com.android.manifmerger.ManifestProvider;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.builder.dependency.parser.ResolvedDependencyInfo;\nimport com.taobao.android.builder.tools.bundleinfo.model.BundleInfo;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.artifacts.ModuleIdentifier;\nimport org.gradle.api.artifacts.result.ResolvedArtifactResult;\nimport org.jetbrains.annotations.TestOnly;\n\n/**\n * Created by shenghua.nish on 2016-05-06 \"In the afternoon.\n * <p>\n * <p>\n * for atlas bundle\n */\npublic class AwbBundle {\n\n    private boolean mainBundle;\n\n    private String name;\n\n    private String variantName;\n\n    private boolean dataBindEnabled;\n\n    //The current module itself, The main bundle is empty, Otherwise it's awb itself\n    private AndroidLibrary androidLibrary;\n\n    private final List<AndroidLibrary> androidLibraries = new ArrayList<>();\n\n    private final List<JavaLibrary> javaLibraries = new ArrayList<>();\n\n\n    public List<ResolvedArtifactResult> getResolvedResArtifactResults() {\n        return resolvedResArtifactResults;\n    }\n\n    private final List<ResolvedArtifactResult>resolvedResArtifactResults = new ArrayList<>();\n\n    public List<ResolvedArtifactResult> getResolvedAssetsArtifactResults() {\n        return resolvedAssetsArtifactResults;\n    }\n\n    private final List<ResolvedArtifactResult>resolvedAssetsArtifactResults = new ArrayList<>();\n\n    public List<ResolvedArtifactResult> getResolvedSymbolListWithPackageNameArtifactResults() {\n        return resolvedSymbolListWithPackageNameArtifactResults;\n    }\n\n    private final List<ResolvedArtifactResult>resolvedSymbolListWithPackageNameArtifactResults = new ArrayList<>();\n\n\n\n    //Compatible with old patterns, gradually discarded androidLibrary\n    private final List<SoLibrary> soLibraries = new ArrayList<>();\n\n    private File mergedManifest;\n\n    private Map<ModuleIdentifier, String> baseAwbDependencies;\n    /**\n     * The bundle corresponds to a bundle that corresponds to the data configured in bundleInfo\n     */\n    private List<AwbBundle> bundleDependencies = new ArrayList<>();\n\n    private File keepProguardFile;\n\n    public AwbBundle() {\n        mainBundle = true;\n        this.name = \"mainbundle\";\n    }\n\n    public AwbBundle(String name) {\n        this.name = name;\n    }\n\n    public AwbBundle(ResolvedDependencyInfo resolvedDependencyInfo, AndroidLibrary androidLibrary) {\n\n        this.androidLibrary = androidLibrary;\n\n        this.name = resolvedDependencyInfo.getGroup() + \"-\" + resolvedDependencyInfo.getName();\n        this.variantName = resolvedDependencyInfo.getVariantName();\n    }\n\n    public AndroidLibrary getAndroidLibrary() {\n        return androidLibrary;\n    }\n\n    public MavenCoordinates getResolvedCoordinates() {\n        return androidLibrary.getResolvedCoordinates();\n    }\n\n    public List<AndroidLibrary> getAndroidLibraries() {\n        return androidLibraries;\n    }\n\n    public List<JavaLibrary> getJavaLibraries() {\n        return javaLibraries;\n    }\n\n    public List<SoLibrary> getSoLibraries() {\n        return soLibraries;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    List<ManifestProvider> _cacheManifestProviders = null;\n\n    public List<ManifestProvider> getManifestProviders() {\n        if (null != _cacheManifestProviders) {\n            return _cacheManifestProviders;\n        }\n\n        _cacheManifestProviders = new ArrayList<>();\n        List<AndroidLibrary> androidLibraries = new ArrayList<>(getAndroidLibraries());\n        androidLibraries.add(getAndroidLibrary());\n        for (AndroidLibrary androidLibrary : androidLibraries) {\n            _cacheManifestProviders.add(new ManifestProvider() {\n                @Override\n                public File getManifest() {\n                    return androidLibrary.getManifest();\n                }\n\n                @Override\n                public String getName() {\n                    return androidLibrary.getName();\n                }\n            });\n        }\n        return _cacheManifestProviders;\n    }\n\n    public List<AwbBundle> getBundleDependencies() {\n        return bundleDependencies;\n    }\n\n    public File getKeepProguardFile() {\n        return keepProguardFile;\n    }\n\n    public void setKeepProguardFile(File keepProguardFile) {\n        this.keepProguardFile = keepProguardFile;\n    }\n\n    ////////////////////////////////////for outputs////////////////////////////////////////////////\n    ///////////////////////////////////////////////////////////////////////////////////////////////\n\n    public File outputBundleFile;\n\n    private String packageName;\n\n    public boolean isRemote;\n\n    public boolean isMBundle;\n\n    private String soFileName;\n\n    public BundleInfo bundleInfo = new BundleInfo();\n\n    public String getPackageName() {\n\n        if (StringUtils.isEmpty(packageName)) {\n            File manifest = androidLibrary.getManifest();\n            if (!manifest.exists()) {\n                return null;\n            }\n\n            packageName = ManifestFileUtils.getPackage(manifest);\n        }\n\n        return packageName;\n    }\n\n    public String getAwbSoName() {\n        if (org.apache.commons.lang3.StringUtils.isEmpty(soFileName)) {\n            String packageName = getPackageName();\n            if (packageName == null) {\n                return null;\n            }\n\n            soFileName = \"lib\" + StringUtils.replace(packageName, \".\", \"_\") + \".so\";\n        }\n        return soFileName;\n    }\n\n    public File getManifest() {return androidLibrary.getManifest();}\n\n    /**\n     * Get all the associated jars\n     *\n     * @return\n     */\n    public List<File> getLibraryJars() {\n        List<File> jars = Lists.newArrayList();\n        jars.add(androidLibrary.getJarFile());\n        Collection<File> localJars = androidLibrary.getLocalJars();\n        if (null != localJars) {\n            jars.addAll(localJars);\n        }\n\n        if (null != androidLibraries) {\n            for (AndroidLibrary aarBundle : androidLibraries) {\n                if (aarBundle.getJarFile().exists()) {\n                    jars.add(aarBundle.getJarFile());\n                }\n                jars.addAll(aarBundle.getLocalJars());\n            }\n        }\n\n        if (null != javaLibraries) {\n            for (JavaLibrary javaLibrary : javaLibraries) {\n                if (javaLibrary.getJarFile().exists()) {\n                    jars.add(javaLibrary.getJarFile());\n                }\n            }\n        }\n        return jars;\n    }\n\n    /**\n     * Get all relevant aars\n     *\n     * @return\n     */\n    public List<AndroidLibrary> getAllLibraryAars() {\n        List<AndroidLibrary> libraries = Lists.newArrayList();\n        if (null != androidLibrary) {\n            libraries.add(androidLibrary);\n        }\n        libraries.addAll(androidLibraries);\n\n        return libraries;\n    }\n\n    public boolean isDataBindEnabled() {\n        return dataBindEnabled;\n    }\n\n    public void setDataBindEnabled(boolean dataBindEnabled) {\n        this.dataBindEnabled = dataBindEnabled;\n    }\n\n    public File getMergedManifest() {\n        return mergedManifest;\n    }\n\n    public void setMergedManifest(File mergedManifest) {\n        this.mergedManifest = mergedManifest;\n    }\n\n    public boolean isMainBundle() {\n        return mainBundle;\n    }\n\n    public List<String> getAllDependencies() {\n        List<String> list = new ArrayList<>();\n        for (AndroidLibrary androidL : getAllLibraryAars()) {\n            list.add(androidL.getResolvedCoordinates().toString());\n        }\n        for (JavaLibrary javaLibrary : getJavaLibraries()) {\n            list.add(javaLibrary.getResolvedCoordinates().toString());\n        }\n        for (SoLibrary soLibrary : getSoLibraries()) {\n            list.add(soLibrary.getResolvedCoordinates().toString());\n        }\n        Collections.sort(list);\n        return list;\n    }\n\n    public Map<ModuleIdentifier, String> getBaseAwbDependencies() {\n        return baseAwbDependencies;\n    }\n\n    public void setBaseAwbDependencies(Map<ModuleIdentifier, String> baseAwbDependencies) {\n        this.baseAwbDependencies = baseAwbDependencies;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/model/SoLibrary.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency.model;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.gradle.internal.ide.DependencyConvertUtils;\nimport com.android.builder.model.MavenCoordinates;\nimport com.taobao.android.builder.dependency.parser.ResolvedDependencyInfo;\n\nimport org.gradle.api.artifacts.ResolvedArtifact;\n\nimport java.io.File;\n\n/**\n * SolibThe dependence of\n * Created by shenghua.nish on 2016-05-03 When in the afternoon.\n */\npublic class SoLibrary {\n\n    @Nullable\n    private final MavenCoordinates mResolvedCoordinates;\n\n    @NonNull\n    private final File mSoLibFile;\n\n    /**\n     * Unzip folders\n     */\n    private File mSoLibFolder;\n\n    @NonNull\n    public File getFolder() {\n        return mSoLibFolder;\n    }\n\n    public SoLibrary(ResolvedDependencyInfo resolvedDependencyInfo) {\n        ResolvedArtifact artifact = resolvedDependencyInfo.getResolvedArtifact();\n\n        this.mResolvedCoordinates = DependencyConvertUtils.convert(artifact, DependencyConvertUtils.Type.SOLIB);\n        this.mSoLibFile = artifact.getFile();\n        this.mSoLibFolder = resolvedDependencyInfo.getExplodedDir();\n    }\n\n    public SoLibrary(@Nullable MavenCoordinates mResolvedCoordinates,\n                     File mSoLibFile,\n                     File mSoLibFolder) {\n        this.mResolvedCoordinates = mResolvedCoordinates;\n        this.mSoLibFile = mSoLibFile;\n        this.mSoLibFolder = mSoLibFolder;\n    }\n\n    public File getSoLibFile() {\n        return mSoLibFile;\n    }\n\n    public String getName() {\n        return mResolvedCoordinates.getArtifactId() + \"@\" + mResolvedCoordinates.getPackaging();\n    }\n\n    public MavenCoordinates getResolvedCoordinates() {\n        return mResolvedCoordinates;\n    }\n\n    @Override\n    public String toString() {\n        return \"SoLib{\" +\n                \"mResolvedCoordinates=\" +\n                mResolvedCoordinates +\n                \", mSoLibFile=\" +\n                mSoLibFile +\n                \", mSoLibFolder=\" +\n                mSoLibFolder +\n                '}';\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/output/DependencyJson.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency.output;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * DependencyDependence relationship\n * @author shenghua.nish 2014December 9, 2009 On the afternoon of 3:14:05\n */\npublic class DependencyJson implements Serializable{\n    private List<String> mainDex = new LinkedList<String>();\n    private Map<String, ArrayList<String>> awbs    = new HashMap<String, ArrayList<String>>();\n\n    /**\n     * @return the mainDex\n     */\n    public List<String> getMainDex() {\n        return mainDex;\n    }\n\n    /**\n     * @param mainDex the mainDex to set\n     */\n    public void setMainDex(List<String> mainDex) {\n        this.mainDex = mainDex;\n    }\n\n    /**\n     * @return the awbs\n     */\n    public Map<String, ArrayList<String>> getAwbs() {\n        return awbs;\n    }\n\n    /**\n     * @param awbs the awbs to set\n     */\n    public void setAwbs(Map<String, ArrayList<String>> awbs) {\n        this.awbs = awbs;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        DependencyJson that = (DependencyJson) o;\n\n        if (mainDex != null ? !mainDex.equals(that.mainDex) : that.mainDex != null) return false;\n        return awbs != null ? awbs.equals(that.awbs) : that.awbs == null;\n\n    }\n\n    @Override\n    public int hashCode() {\n        int result = mainDex != null ? mainDex.hashCode() : 0;\n        result = 31 * result + (awbs != null ? awbs.hashCode() : 0);\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/parser/AtlasDepHelper.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency.parser;\n\nimport com.android.annotations.NonNull;\nimport org.gradle.api.artifacts.ModuleVersionIdentifier;\nimport org.gradle.api.artifacts.ResolvedArtifact;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * Created by wuzhong on 2017/3/12.\n *\n * @author wuzhong\n * @date 2017/03/12\n */\npublic class AtlasDepHelper {\n\n    private static Logger logger = LoggerFactory.getLogger(AtlasDepHelper.class);\n\n    @NonNull\n    public static String computeArtifactPath(@NonNull ModuleVersionIdentifier moduleVersion,\n                                             @NonNull ResolvedArtifact artifact) {\n        StringBuilder pathBuilder = new StringBuilder();\n\n        pathBuilder.append(normalize(moduleVersion, moduleVersion.getGroup()))\n            .append(\"/\")\n            .append(normalize(moduleVersion, moduleVersion.getName()))\n            .append(\"/\")\n            .append(normalize(moduleVersion, moduleVersion.getVersion()));\n\n        if (artifact.getClassifier() != null && !artifact.getClassifier().isEmpty()) {\n            pathBuilder.append(\"/\")\n                .append(normalize(moduleVersion, artifact.getClassifier()));\n        }\n\n        return pathBuilder.toString();\n    }\n\n    /**\n     * Normalize a path to remove all illegal characters for all supported operating systems.\n     * {@see http://en.wikipedia.org/wiki/Filename#Comparison%5Fof%5Ffile%5Fname%5Flimitations}\n     *\n     * @param id   the module coordinates that generated this path\n     * @param path the proposed path name\n     * @return the normalized path name\n     */\n    public static String normalize(ModuleVersionIdentifier id, String path) {\n        if (path == null || path.isEmpty()) {\n            logger.info(String.format(\n                \"When unzipping library '%s:%s:%s, either group, name or version is empty\",\n                id.getGroup(),\n                id.getName(),\n                id.getVersion()));\n            return path;\n        }\n\n        // list of illegal characters\n        String normalizedPath = path.replaceAll(\"[%<>:\\\"/?*\\\\\\\\]\", \"@\");\n        if (normalizedPath == null || normalizedPath.isEmpty()) {\n            // if the path normalization failed, return the original path.\n            logger.info(String.format(\n                \"When unzipping library '%s:%s:%s, the normalized '%s' is empty\",\n                id.getGroup(),\n                id.getName(),\n                id.getVersion(),\n                path));\n            return path;\n        }\n\n        try {\n            int pathPointer = normalizedPath.length() - 1;\n            // do not end your path with either a dot or a space.\n            String suffix = \"\";\n            while (pathPointer >= 0 && (normalizedPath.charAt(pathPointer) == '.') ||\n                normalizedPath.charAt(pathPointer) == ' ') {\n                pathPointer = pathPointer--;\n                suffix += \"@\";\n            }\n\n            if (pathPointer < 0) {\n                throw new RuntimeException(String.format(\"When unzipping library '%s:%s:%s, \" +\n                                                             \"the path '%s' cannot be transformed into a valid \"\n                                                             + \"directory name\",\n                                                         id.getGroup(),\n                                                         id.getName(),\n                                                         id.getVersion(),\n                                                         path));\n            }\n\n            return normalizedPath.substring(0, pathPointer + 1) + suffix;\n        } catch (Exception e) {\n            logger.error(\n                String.format(\"When unzipping library '%s:%s:%s', \" +\n                                  \"Path normalization failed for input %s\",\n                              id.getGroup(),\n                              id.getName(),\n                              id.getVersion(),\n                              path), e);\n            return path;\n        }\n    }\n\n    @NonNull\n    public static String computeArtifactName(@NonNull ModuleVersionIdentifier moduleVersion,\n                                              @NonNull ResolvedArtifact artifact) {\n        StringBuilder nameBuilder = new StringBuilder();\n\n        nameBuilder.append(moduleVersion.getGroup())\n            .append(\":\")\n            .append(moduleVersion.getName())\n            .append(\":\")\n            .append(moduleVersion.getVersion());\n\n        if (artifact.getClassifier() != null && !artifact.getClassifier().isEmpty()) {\n            nameBuilder.append(\":\").append(artifact.getClassifier());\n        }\n\n        return nameBuilder.toString();\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/parser/AtlasDepTreeParser.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency.parser;\n\nimport com.alibaba.fastjson.JSON;\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.internal.ExtraModelInfo;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.dependency.VariantDependencies;\nimport com.android.build.gradle.internal.ide.DependencyConvertUtils;\nimport com.android.build.gradle.internal.ide.DependencyConvertUtils.Type;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.builder.model.JavaLibrary;\nimport com.android.utils.ILogger;\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Maps;\nimport com.taobao.android.builder.AtlasPlugin;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.dependency.model.SoLibrary;\nimport com.taobao.android.builder.dependency.parser.helper.DependencyGroup;\nimport com.taobao.android.builder.dependency.parser.helper.DependencyResolver;\nimport com.taobao.android.builder.manager.AtlasConfigurationHelper;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.*;\nimport org.gradle.api.artifacts.result.DependencyResult;\nimport org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency;\nimport org.gradle.api.internal.project.ProjectInternal;\nimport org.gradle.api.specs.Specs;\n\nimport java.util.*;\n\nimport static com.android.builder.core.ErrorReporter.EvaluationMode.STANDARD;\n\n/**\n * A manager to resolve configuration dependencies.\n *\n * @author wuzhong\n */\npublic class AtlasDepTreeParser {\n\n    private final Project project;\n\n    private String flavorName;\n\n    private final ExtraModelInfo extraModelInfo;\n\n    private final List<ResolvedDependencyInfo> mResolvedDependencies = Lists.newArrayList();\n\n//    private final ApDependencies apDependencies;\n\n    private final ILogger logger = LoggerWrapper.getLogger(AtlasDepTreeParser.class);\n\n    private Set<String>awbs = new HashSet<>();\n\n    public AtlasDepTreeParser(@NonNull Project project, @NonNull ExtraModelInfo extraModelInfo, Set<String> awbs) {\n        this.project = project;\n        this.extraModelInfo = extraModelInfo;\n        this.awbs =awbs;\n//        this.apDependencies = apDependencies;\n    }\n\n\n    public AtlasDependencyTree parseDependencyTree(@NonNull VariantDependencies variantDeps) {\n//\n        String name = variantDeps.getName().toLowerCase();\n        if (!name.endsWith(\"debug\") && !name.endsWith(\"release\")) {\n            return new AtlasDependencyTree(new ArrayList<>());\n        }\n        if (!name.equals(\"debug\") && name.endsWith(\"debug\")){\n            flavorName = variantDeps.getName().substring(0,name.length()-5);\n        }\n        if (!name.equals(\"release\") && name.endsWith(\"release\")){\n            flavorName = variantDeps.getName().substring(0,name.length()-6);\n        }\n\n\n        Configuration compileClasspath = variantDeps.getCompileClasspath();\n        Configuration runtimeClasspath = variantDeps.getRuntimeClasspath();\n        Configuration apiClasspath = variantDeps.getApiElements();\n        Configuration  configuration = variantDeps.getAnnotationProcessorConfiguration();\n        Configuration bundleClasspath = project.getConfigurations().maybeCreate(AtlasPlugin.BUNDLE_COMPILE);\n\n        ensureConfigured(compileClasspath,project);\n        ensureConfigured(runtimeClasspath,project);\n        ensureConfigured(bundleClasspath,project);\n        ensureConfigured(apiClasspath,project);\n        ensureConfigured(configuration,project);\n\n\n        Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts = Maps.newHashMap();\n        collectArtifacts(compileClasspath, artifacts);\n        collectArtifacts(runtimeClasspath, artifacts);\n        collectArtifacts(apiClasspath,artifacts);\n        collectArtifacts(bundleClasspath, artifacts);\n        collectArtifacts(configuration, artifacts);\n\n        unEnsureConfigured(compileClasspath);\n        unEnsureConfigured(runtimeClasspath);\n        unEnsureConfigured(bundleClasspath);\n        unEnsureConfigured(apiClasspath);\n        unEnsureConfigured(configuration);\n\n\n\n        //Rely on the group\n        DependencyGroup dependencyGroup = new DependencyGroup(compileClasspath, bundleClasspath,artifacts,awbs);\n\n        DependencyResolver dependencyResolver = new DependencyResolver(project, variantDeps, artifacts,\n                                                                       dependencyGroup.bundleProvidedMap,dependencyGroup.bundleCompileMap);\n\n        mResolvedDependencies.addAll(dependencyResolver.resolve(dependencyGroup.compileDependencies, true));\n\n        for (DependencyResult dependencyResult : dependencyGroup.bundleDependencies) {\n            mResolvedDependencies.addAll(dependencyResolver.resolve(Arrays.asList(dependencyResult), false));\n        }\n\n        AtlasDependencyTree atlasDependencyTree = toAtlasDependencyTree();\n\n        check(atlasDependencyTree);\n\n        return atlasDependencyTree;\n    }\n\n    private void unEnsureConfigured(Configuration config) {\n        for (Dependency dependency : config.getAllDependencies()) {\n            if (dependency instanceof ProjectDependency) {\n                ProjectDependency projectDependency = (ProjectDependency)dependency;\n                unPrepareProject(projectDependency,config);\n\n            }\n        }\n    }\n\n    private void unPrepareProject(ProjectDependency projectDependency, Configuration config) {\n        if (projectDependency.getTargetConfiguration()!= null && projectDependency.getTargetConfiguration().equals(AtlasConfigurationHelper.COMPILE_PROJECT_CONFIGURATION_NAME)){\n            projectDependency.setTargetConfiguration(null);\n        }\n        String name = config.getName();\n        Configuration configuration = projectDependency.getDependencyProject().getConfigurations().findByName(name);\n        if (configuration == null) {\n            configuration = projectDependency.getDependencyProject().getConfigurations().findByName(newName(name));\n            }\n        if (configuration!= null && configuration.getAllDependencies()!= null) {\n            unEnsureConfigured(configuration);\n        }\n    }\n\n    private void ensureConfigured(Configuration config,Project project) {\n        for (Dependency dependency : config.getAllDependencies()) {\n            if (dependency instanceof ProjectDependency) {\n                ProjectDependency projectDependency = (ProjectDependency)dependency;\n                prepareProject(projectDependency,config);\n                project.evaluationDependsOn(projectDependency.getDependencyProject().getPath());\n\n            }\n        }\n    }\n\n    private void prepareProject(ProjectDependency projectDependency,Configuration configuration) {\n        if (projectDependency.getTargetConfiguration() == null || projectDependency.getTargetConfiguration().equals(\"default\")){\n            projectDependency.setTargetConfiguration(AtlasConfigurationHelper.COMPILE_PROJECT_CONFIGURATION_NAME);\n        }\n         ((ProjectInternal)((DefaultProjectDependency) projectDependency).getDependencyProject()).evaluate();\n\n        String name = configuration.getName();\n        Configuration config = projectDependency.getDependencyProject().getConfigurations().findByName(name);\n        if (config == null) {\n            config = projectDependency.getDependencyProject().getConfigurations().findByName(newName(name));\n       }\n        if (config!= null && config.getAllDependencies()!= null) {\n            ensureConfigured(config,projectDependency.getDependencyProject());\n        }\n\n    }\n\n    private void collectArtifacts(Configuration configuration,\n                                  Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts) {\n\n\n        Set<ResolvedArtifact> allArtifacts;\n        if (configuration.getState().equals(Configuration.State.UNRESOLVED) && !configuration.getName().equals(AtlasPlugin.BUNDLE_COMPILE)) {\n            configuration.setCanBeResolved(true);\n        }\n        if (!extraModelInfo.getMode().equals(STANDARD)) {\n            allArtifacts = configuration.getResolvedConfiguration().getLenientConfiguration().getArtifacts(\n                Specs.satisfyAll());\n        } else {\n            allArtifacts = configuration.getResolvedConfiguration().getResolvedArtifacts();\n        }\n        for (ResolvedArtifact artifact : allArtifacts) {\n            ModuleVersionIdentifier id = artifact.getModuleVersion().getId();\n            List<ResolvedArtifact> moduleArtifacts = artifacts.get(id);\n\n            if (moduleArtifacts == null) {\n                moduleArtifacts = Lists.newArrayList();\n                artifacts.put(id, moduleArtifacts);\n            }\n\n            if (!moduleArtifacts.contains(artifact)) {\n                moduleArtifacts.add(artifact);\n            }\n        }\n    }\n\n    private String newName(String name) {\n        if (!StringUtils.isEmpty(flavorName)) {\n            name = name.replace(flavorName, \"\");\n        }\n        if (name.startsWith(\"Debug\")) {\n            name = name.replace(\"Debug\", \"debug\");\n\n        }\n        if (name.startsWith(\"Release\")) {\n            name = name.replace(\"Release\", \"release\");\n\n        }\n        return name;\n    }\n\n    private AtlasDependencyTree toAtlasDependencyTree() {\n\n        AtlasDependencyTree atlasDependencyTree = new AtlasDependencyTree(mResolvedDependencies);\n\n        //Setting dependency\n        for (ResolvedDependencyInfo dependencyInfo : mResolvedDependencies) {\n\n            if (Type.AWB == DependencyConvertUtils.Type.getType(dependencyInfo.getType())) {\n\n                AwbBundle bundle = DependencyConvertUtils.toBundle(dependencyInfo, project);\n//                if (apDependencies != null) {\n//                    Map<ModuleIdentifier, String> awbDependencies = apDependencies.getAwbDependencies(\n//                        dependencyInfo.getGroup(), dependencyInfo.getName());\n//                    bundle.setBaseAwbDependencies(awbDependencies);\n//                }\n                atlasDependencyTree.getAwbBundles().add(bundle);\n\n                collect(dependencyInfo, bundle);\n            } else {\n\n                collect(dependencyInfo, atlasDependencyTree.getMainBundle());\n            }\n        }\n\n        return atlasDependencyTree;\n    }\n\n    private void collect(ResolvedDependencyInfo dependencyInfo, AwbBundle awbBundle) {\n\n//        if (apDependencies != null && !awbBundle.isMainBundle()) {\n//            if (apDependencies.isMainLibrary(dependencyInfo)) {\n//                return;\n//            }\n//        }\n        switch (DependencyConvertUtils.Type.getType(dependencyInfo.getType())) {\n            case AAR:\n                //Add it to the main dex\n                awbBundle.getAndroidLibraries().add(\n                    DependencyConvertUtils.toAndroidLibrary(dependencyInfo, project, false));\n                break;\n            case JAR:\n                awbBundle.getJavaLibraries().add(DependencyConvertUtils.toJavaLib(dependencyInfo));\n                break;\n            case SOLIB:\n                awbBundle.getSoLibraries().add(new SoLibrary(dependencyInfo));\n                return;\n            case AWB:\n                break;\n            default:\n                return;\n        }\n\n        if (null != dependencyInfo.getChildren() && !dependencyInfo.getChildren().isEmpty()) {\n            for (ResolvedDependencyInfo resolvedDependencyInfo : dependencyInfo.getChildren()) {\n                collect(resolvedDependencyInfo, awbBundle);\n            }\n        }\n    }\n\n    private void check(AtlasDependencyTree atlasDependencyTree) {\n\n        Map<String, List<String>> dependeys = new HashMap<>();\n        for (AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n            String gav = awbBundle.getAndroidLibrary().getResolvedCoordinates().toString();\n\n            for (AndroidLibrary androidLibrary : awbBundle.getAndroidLibraries()) {\n                addValuetoList(dependeys, gav, androidLibrary.getResolvedCoordinates().toString());\n            }\n\n            for (JavaLibrary javaLibrary : awbBundle.getJavaLibraries()) {\n                addValuetoList(dependeys, gav, javaLibrary.getResolvedCoordinates().toString());\n            }\n\n            for (SoLibrary soLibrary : awbBundle.getSoLibraries()) {\n                addValuetoList(dependeys, gav, soLibrary.getResolvedCoordinates().toString());\n            }\n        }\n\n        List<String> warnings = new ArrayList<>();\n        for (String key : dependeys.keySet()) {\n            List<String> values = dependeys.get(key);\n            if (values.size() > 1) {\n                String msg = key + \":\" + StringUtils.join(values, \",\");\n                warnings.add(msg);\n                logger.warning(msg);\n            }\n        }\n\n        if (warnings.size() > 0) {\n            logger.warning(JSON.toJSONString(atlasDependencyTree.getDependencyJson(), true));\n            throw new GradleException(\"decencyconflict : \" + StringUtils.join(warnings, \"\\r\\n\"));\n        }\n    }\n\n    private void addValuetoList(Map<String, List<String>> dependeys, String gav, String key) {\n        List<String> value = dependeys.get(key);\n        if (null == value) {\n            value = new ArrayList<>();\n            dependeys.put(key, value);\n        }\n        value.add(gav);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/parser/CircleDependencyCheck.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency.parser;\n\nimport com.android.utils.ILogger;\nimport com.google.common.collect.HashMultimap;\nimport com.google.common.collect.Multimap;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.artifacts.ModuleVersionIdentifier;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * Loop dependent detection class\n * <p>\n *     The dependence is detected by simple notation\n * </p>\n * @author shenghua.nish on 2015-12-18 On the morning of the assembling.\n */\npublic class CircleDependencyCheck {\n\n    private final DependencyNode rootDependencyNode;\n\n    public CircleDependencyCheck(ModuleVersionIdentifier identifier){\n        String name = getIdentifier(identifier);\n        rootDependencyNode = new DependencyNode(name, 0);\n        rootDependencyNode.parent = null;\n    }\n\n    /**\n     * Gain roots\n     * @return\n     */\n    public DependencyNode getRootDependencyNode() {\n        return rootDependencyNode;\n    }\n\n    /**\n     * Join the rely on\n     * @param identifier\n     * @param parent\n     * @param ident\n     * @return Determine if there is a circular dependency, and if any, return true\n     */\n    public DependencyNode addDependency(ModuleVersionIdentifier identifier, DependencyNode parent, int ident) {\n        String name = getIdentifier(identifier);\n        DependencyNode node = new DependencyNode(name, ident);\n        node.parent = parent;\n        if (null != parent) {\n            parent.children.add(node);\n        }\n        return node;\n    }\n\n    /**\n     * dependent\n     * @param identifier\n     * @return\n     */\n    private String getIdentifier(ModuleVersionIdentifier identifier) {\n        StringBuilder sb = new StringBuilder();\n        sb.append(identifier.getGroup()).append(\":\");\n        sb.append(identifier.getName()).append(\":\");\n        sb.append(identifier.getVersion());\n        return sb.toString();\n    }\n\n    static final String ARROW = \"=>\";\n\n    /**\n     * Determine whether there are circular dependencies\n     * @return\n     */\n    public CircleResult checkCircle(ILogger logger) {\n        CircleResult circleResult = new CircleResult();\n        circleResult.hasCircle = false;\n        Multimap<String, String> dependenciesMap = HashMultimap.create();\n        Map<String, String> identifierMap = new HashMap<String, String>();\n        // First, all the node tags\n        createIdentifier(rootDependencyNode);\n        fillDepenciesMap(logger, rootDependencyNode, dependenciesMap, identifierMap, 0);\n        // dumpDependencyMap(logger, dependenciesMap);\n\n        // Query dependency\n        for (String key : dependenciesMap.keySet()) {\n            // if(null != logger) logger.verbose(\"****** CHECK CIRCLE: \" + key);\n            Collection<String> dependencyLevels = dependenciesMap.get(key);\n            Set<CircleDep> circleSet = circleLevels(dependencyLevels);\n\n            /*if(null != logger) {\n                logger.verbose(\"DEPENDENCY_LVLS:\");\n                for (String dl : dependencyLevels) {\n                    logger.verbose(dl);\n                }\n            }*/\n\n            if (circleSet.size() > 0) { // There is a cycle of dependency\n                circleResult.hasCircle = true;\n                // if(null != logger) logger.verbose(\"[WARN] HAS CIRCLE\");\n                for (CircleDep circleDep : circleSet) {\n                    // if(null != logger) logger.verbose(\" CIRCLE_DEP: \" + circleDep.level1 + \", \" + circleDep.level2);\n                    StringBuilder sb = new StringBuilder();\n                    sb.append(key);\n                    String parentLevel = circleDep.level1.substring(0, circleDep.level1.length() - 1);\n                    while (StringUtils.isNotBlank(parentLevel)) {\n                        // logger.warning(\" PARENT_LVL: \" + parentLevel);\n                        String parentDepStr = identifierMap.get(parentLevel);\n                        // logger.warning(\" PARENT_DEP: \" + parentDepStr);\n                        sb.append(ARROW).append(parentDepStr);\n                        parentLevel = parentLevel.substring(0, parentLevel.length() - 1);\n                    }\n                    circleResult.detail.add(sb.toString());\n                }\n\n            } else {\n                // if(null != logger) logger.verbose(\"[OK] NO_CIRCLE\");\n            }\n        }\n        return circleResult;\n    }\n\n    private Set<CircleDep> circleLevels(Collection<String> dependencyLevels) {\n        Set<CircleDep> list = new HashSet<CircleDep>();\n        for (String dependencyLevel : dependencyLevels) {\n            for (String level : dependencyLevels) {\n                if (!dependencyLevel.equals(level) && dependencyLevel.startsWith(level)) {\n                    CircleDep circleDep = new CircleDep(dependencyLevel, level);\n                    list.add(circleDep);\n                }\n            }\n        }\n        return list;\n    }\n\n    class CircleDep {\n\n        String level1; // Depending on the hierarchy\n        String level2; // Depending on the hierarchy\n\n        public CircleDep(String level1, String level2){\n            this.level1 = level1;\n            this.level2 = level2;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) {\n                return true;\n            }\n            if (o == null || getClass() != o.getClass()) {\n                return false;\n            }\n\n            CircleDep circleDep = (CircleDep) o;\n\n            if (level1 != null ? !level1.equals(circleDep.level1) : circleDep.level1 != null) {\n                return false;\n            }\n            return !(level2 != null ? !level2.equals(circleDep.level2) : circleDep.level2 != null);\n\n        }\n\n        @Override\n        public int hashCode() {\n            int result = level1 != null ? level1.hashCode() : 0;\n            result = 31 * result + (level2 != null ? level2.hashCode() : 0);\n            return result;\n        }\n    }\n\n    /**\n     * Fill a dependent tree\n     * @param logger\n     * @param node\n     * @param dependenciesMap\n     * @param identifierMap\n     * @param indent\n     */\n    private void fillDepenciesMap(ILogger logger, DependencyNode node, Multimap<String, String> dependenciesMap,\n                                  Map<String, String> identifierMap, int indent) {\n        StringBuilder sb = new StringBuilder();\n        for (int i = 0; i < indent; i++) {\n            sb.append(\" \");\n        }\n        sb.append(node.name);\n        if (null != logger) {\n            logger.verbose(sb.toString());\n        }\n\n        dependenciesMap.put(node.name, node.identifier);\n        identifierMap.put(node.identifier, node.name);\n        for (DependencyNode child : node.children) {\n            fillDepenciesMap(logger, child, dependenciesMap, identifierMap, indent + 1);\n        }\n    }\n\n    /**\n     * Generate all dependent flags\n     */\n    private void createIdentifier(DependencyNode node) {\n        if (null == node.parent) {\n            node.identifier = \"1\";\n        }\n        List<DependencyNode> children = node.children;\n        for (int i = 1; i <= children.size(); i++) {\n            DependencyNode child = children.get(i - 1);\n            if (i >= 10) {\n                // if adding divider between each num, consider 1-1-10 and 1-1-1, which will\n                // be treated as circle-dependency mistakenly.\n                child.identifier = String.format(\"%s(%s)\", node.identifier, i);\n            } else {\n                child.identifier = node.identifier + i;\n            }\n            createIdentifier(child);\n        }\n    }\n\n    /**\n     * The results of circular detection\n     */\n    public static class CircleResult {\n\n        public boolean      hasCircle;\n        public List<String> detail = new ArrayList<String>();\n    }\n\n    /**\n     * Depend on the node\n     */\n    public static class DependencyNode {\n\n        public String               name;\n        public int                  indent;\n        public DependencyNode       parent;\n        public String               identifier;\n        public List<DependencyNode> children = new ArrayList<DependencyNode>();\n\n        public DependencyNode(String name, int indent){\n            this.name = name;\n            this.indent = indent;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) {\n                return true;\n            }\n            if (o == null || getClass() != o.getClass()) {\n                return false;\n            }\n\n            DependencyNode that = (DependencyNode) o;\n\n            if (indent != that.indent) {\n                return false;\n            }\n            return !(name != null ? !name.equals(that.name) : that.name != null);\n\n        }\n\n        @Override\n        public int hashCode() {\n            int result = name != null ? name.hashCode() : 0;\n            result = 31 * result + indent;\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/parser/DependencyLocationManager.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency.parser;\n\nimport com.android.builder.model.MavenCoordinates;\nimport com.android.builder.utils.FileCache;\nimport com.android.utils.FileUtils;\nimport com.taobao.android.builder.tasks.app.BuildAtlasEnvTask;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.Project;\n\nimport java.io.File;\nimport java.util.Optional;\n\nimport static com.android.builder.model.AndroidProject.FD_INTERMEDIATES;\n\n/**\n * Created by wuzhong on 2017/3/16.\n *\n * @author wuzhong\n * @date 2017/03/16\n */\npublic class DependencyLocationManager {\n\n    public static File getExploreDir(Project project, MavenCoordinates mavenCoordinates, File bundle, String type,\n                                     String path) {\n\n        if (!bundle.exists()) {\n            project.getLogger().info(\"missing \" + mavenCoordinates.toString());\n        }\n\n//        if (BuildAtlasEnvTask.allManifests.containsKey(mavenCoordinates.)){\n//\n//            return BuildAtlasEnvTask.allManifests.get(mavenCoordinates.toString().split(\"@\")[0]);\n//        }\n\n//        AtlasDependencyGraph.HashableResolvedArtifactResult hashableResolvedArtifactResult = AtlasDependencyGraph.sLibraryMap.get(mavenCoordinates.toString().intern());\n//\n//        if (hashableResolvedArtifactResult!= null && hashableResolvedArtifactResult.getDelegate()!= null){\n//            return hashableResolvedArtifactResult.getDelegate().getFile();\n//        }\n\n//        if (){\n//\n//            BuildCacheConfiguration\n//        }\n//\n//\n//\n////        Optional<FileCache> buildCache =\n////            AndroidGradleOptions.getBuildCache(project);\n////        File explodedDir;\n////        if (shouldUseBuildCache(project, mavenCoordinates, bundle, buildCache)) { //&& !\"awb\"\n//            // .equals(type)\n////            try {\n////\n////                explodedDir = buildCache.get().getFileInCache(\n////                    PrepareLibraryTask.getBuildCacheInputs(bundle));\n////\n////                return explodedDir;\n////\n////            } catch (IOException e) {\n////                throw new UncheckedIOException(e);\n////            }\n//        } else {\n\n            return FileUtils.join(\n                project.getBuildDir(),\n                FD_INTERMEDIATES,\n                \"exploded-\" + type,\n                path);\n//        }\n\n        //throw new GradleException(\"set explored dir exception\");\n\n    }\n\n    private static boolean shouldUseBuildCache(Project project, MavenCoordinates mavenCoordinates, File bundle,\n                                               Optional<FileCache> buildCache) {\n//        if (!PrepareLibraryTask.shouldUseBuildCache(\n//            buildCache.isPresent(), mavenCoordinates)) {\n//            return false;\n//        }\n\n        if (!bundle.exists()) {\n            return false;\n        }\n\n        if (StringUtils.isEmpty(mavenCoordinates.getGroupId())) {\n            return true;\n        }\n\n        return !isProjectLibrary(project, bundle);\n    }\n\n    public static boolean isProjectLibrary(Project project, File bundle) {\n\n        String rootPath = project.getRootProject().getProjectDir().getAbsolutePath();\n\n        return bundle.getAbsolutePath().startsWith(rootPath);\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/parser/ResolvedDependencyInfo.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency.parser;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.taobao.android.builder.AtlasBuildContext;\nimport org.apache.commons.lang3.StringUtils;\nimport org.gradle.api.artifacts.ModuleVersionIdentifier;\nimport org.gradle.api.artifacts.ResolvedArtifact;\nimport org.gradle.api.internal.artifacts.DefaultModuleVersionIdentifier;\n\n/**\n * Resolved dependencies\n * Created by shenghua.nish on 2015-08-13 \"In the afternoon.\n */\npublic class ResolvedDependencyInfo implements Comparable<ResolvedDependencyInfo> {\n\n    private String version;\n\n    private String group;\n\n    private String name;\n\n    private String type;\n\n    private String classifier;\n\n    private Integer indent;\n\n    private boolean ignore;\n\n    private List<ResolvedDependencyInfo> children = new ArrayList<ResolvedDependencyInfo>();\n\n    private ResolvedDependencyInfo parent;\n\n    private String gradlePath;\n\n    private ResolvedArtifact resolvedArtifact;\n\n    private File explodedDir;\n\n    private String variantName;\n\n    private String dependencyName;\n\n    public ResolvedDependencyInfo(String group, String name, String version, String type) {\n        this.version = version;\n        this.group = group;\n        this.name = name;\n        this.type = type;\n    }\n\n    public ResolvedDependencyInfo(String version,\n                                  String group,\n                                  String name,\n                                  String type,\n                                  String classifier) {\n        this.version = version;\n        this.group = group;\n        this.name = name;\n        this.type = type;\n        this.classifier = classifier;\n    }\n\n    public String getVersion() {\n        return version;\n    }\n\n    public void setVersion(String version) {\n        this.version = version;\n    }\n\n    public String getGroup() {\n        return group;\n    }\n\n    public void setGroup(String group) {\n        this.group = group;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getType() {\n        return type;\n    }\n\n    public void setType(String type) {\n        this.type = type;\n    }\n\n    public String getClassifier() {\n        return classifier;\n    }\n\n    public void setClassifier(String classifier) {\n        this.classifier = classifier;\n    }\n\n    public boolean getIgnore() {\n        return ignore;\n    }\n\n    public void setIgnore(boolean ignore) {\n        this.ignore = ignore;\n    }\n\n    public Integer getIndent() {\n        return indent;\n    }\n\n    public void setIndent(Integer indent) {\n        this.indent = indent;\n    }\n\n    public List<ResolvedDependencyInfo> getChildren() {\n        return children;\n    }\n\n    public void setChildren(List<ResolvedDependencyInfo> children) {\n        this.children = children;\n    }\n\n    public ResolvedDependencyInfo getParent() {\n        return parent;\n    }\n\n    public void setParent(ResolvedDependencyInfo parent) {\n        this.parent = parent;\n    }\n\n    public ModuleVersionIdentifier getModuleVersionIdentifier() {\n        return new DefaultModuleVersionIdentifier(group, name, version);\n    }\n\n    public ResolvedArtifact getResolvedArtifact() {\n        return resolvedArtifact;\n    }\n\n    public void setResolvedArtifact(ResolvedArtifact resolvedArtifact) {\n        this.resolvedArtifact = resolvedArtifact;\n    }\n\n    public String getGradlePath() {\n        return gradlePath;\n    }\n\n    public void setGradlePath(String gradlePath) {\n        this.gradlePath = gradlePath;\n    }\n\n    public File getExplodedDir() {\n        return explodedDir;\n    }\n\n    public void setExplodedDir(File explodedDir) {\n        this.explodedDir = explodedDir;\n    }\n\n    public String getVariantName() {\n        return variantName;\n    }\n\n    public void setVariantName(String variantName) {\n        this.variantName = variantName;\n    }\n\n    public String getDependencyName() {\n        return dependencyName;\n    }\n\n    public void setDependencyName(String dependencyName) {\n        this.dependencyName = dependencyName;\n    }\n\n    public ResolvedDependencyInfo() {\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) {\n            return true;\n        }\n        if (o == null || getClass() != o.getClass()) {\n            return false;\n        }\n\n        ResolvedDependencyInfo that = (ResolvedDependencyInfo)o;\n\n        if (version != null ? !version.equals(that.version) : that.version != null) {\n            return false;\n        }\n        if (group != null ? !group.equals(that.group) : that.group != null) {\n            return false;\n        }\n        if (name != null ? !name.equals(that.name) : that.name != null) {\n            return false;\n        }\n        if (type != null ? !type.equals(that.type) : that.type != null) {\n            return false;\n        }\n        if (classifier != null ? !classifier.equals(that.classifier) : that.classifier != null) {\n            return false;\n        }\n        return indent != null ? indent.equals(that.indent) : that.indent == null;\n    }\n\n    @Override\n    public int hashCode() {\n        int result = version != null ? version.hashCode() : 0;\n        result = 31 * result + (group != null ? group.hashCode() : 0);\n        result = 31 * result + (name != null ? name.hashCode() : 0);\n        result = 31 * result + (type != null ? type.hashCode() : 0);\n        result = 31 * result + (classifier != null ? classifier.hashCode() : 0);\n        result = 31 * result + (indent != null ? indent.hashCode() : 0);\n        return result;\n    }\n\n    @Override\n    public String toString() {\n        StringBuilder sb = new StringBuilder();\n        sb.append(group).append(\":\").append(name);\n        if (StringUtils.isNoneBlank(classifier)) {\n            sb.append(\":\").append(classifier);\n        }\n        sb.append(\":\").append(version);\n        sb.append(\"@\").append(type);\n        return sb.toString();\n    }\n\n    /**\n     * Size judgment, in the case of the two names and so on completely consistent, according to the hierarchy\n     *\n     * @param other\n     * @return\n     */\n    @Override\n    public int compareTo(ResolvedDependencyInfo other) {\n        // If the two are equal, follow the same sequence\n        if (indent < other.indent) {\n            return -1;\n        } else {\n            return 1;\n        }\n    }\n\n    /**\n     * Gets a character description of DependencyInfo\n     *\n     * @return //TODO , do this later\n     * @param printFileSize\n     */\n    public String getDependencyString(boolean printFileSize) {\n        StringBuilder sb = new StringBuilder();\n        sb.append(getGroup()).append(\":\");\n        sb.append(getName()).append(\":\");\n\n        //FIXME REPLACE IT LATER\n        if (AtlasBuildContext.sBuilderAdapter.prettyDependencyFormat) {\n            sb.append(getVersion()).append(\"@\");\n            sb.append(getType());\n        } else {\n            sb.append(getType());\n            if (org.apache.commons.lang.StringUtils.isNotBlank(getClassifier())) {\n                sb.append(\":\").append(getClassifier());\n            }\n            sb.append(\":\").append(getVersion());\n        }\n        if (printFileSize) {\n            File file = getResolvedArtifact().getFile();\n            long fileLength = file.length();\n            sb.append(\" \");\n            sb.append(fileLength);\n        }\n\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/parser/helper/DependencyGroup.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency.parser.helper;\n\nimport com.android.build.gradle.internal.ide.DependencyConvertUtils;\nimport com.taobao.android.builder.AtlasPlugin;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.artifacts.*;\nimport org.gradle.api.artifacts.result.DependencyResult;\nimport org.gradle.api.artifacts.result.UnresolvedArtifactResult;\nimport org.gradle.api.internal.artifacts.DefaultResolvedArtifact;\nimport org.gradle.api.internal.artifacts.dependencies.DefaultExternalModuleDependency;\nimport org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency;\nimport org.gradle.api.internal.artifacts.result.DefaultResolvedDependencyResult;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.util.*;\nimport java.util.function.Consumer;\n\npublic class DependencyGroup {\n\n    private static Logger logger = LoggerFactory.getLogger(DependencyGroup.class);\n\n    public Map<String, Set<DependencyResult>> bundleCompileMap = new HashMap<>();\n\n    public List<DependencyResult> compileDependencies = new ArrayList<>();\n    public List<DependencyResult> bundleDependencies = new ArrayList<>();\n    private Set<String>mainDexs = new HashSet<>();\n\n    /**\n     * bundle (group:name) It corresponds to that Private rely on\n     */\n    public Map<String, Set<String>> bundleProvidedMap = new HashMap<>();\n    public static Map<ModuleVersionIdentifier,ResolvedArtifact> bundleCompileId = new HashMap();\n\n    public DependencyGroup(Configuration compileClasspath,\n                           Configuration bundleClasspath,\n                           Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts, Set<String> awbs) {\n\n        Set<? extends DependencyResult> compileDependencies = compileClasspath.getIncoming()\n                                                                                .getResolutionResult()\n                                                                                .getRoot()\n                                                                                .getDependencies();\n\n        Set<? extends DependencyResult> bundleCompileDependencies = bundleClasspath.getIncoming()\n                                                                            .getResolutionResult()\n                                                                            .getRoot()\n                                                                            .getDependencies();\n\n\n\n        Set<String> bundleSets = getBundleDependencies(compileClasspath, bundleCompileDependencies,awbs);\n        //Analysis of the compileDependencies Bundle dependency\n        for (DependencyResult dependencyResult : compileDependencies) {\n            if (DependencyConvertUtils.isAwbDependency(dependencyResult, artifacts,awbs)) {\n                String name = dependencyResult.toString();\n                if (!bundleSets.contains(name)) {\n                    bundleSets.add(name);\n                    logger.error(\"please use bundleCompile for \" + name);\n                }\n\n            }\n\n        }\n\n\n        Set<String> bundleAddedSets = new HashSet<>();\n        for (DependencyResult dependencyResult : compileDependencies) {\n            if (!bundleSets.contains(dependencyResult.toString())) {\n                this.compileDependencies.add(dependencyResult);\n                mainDexs.add(dependencyResult.toString());\n            } else {\n                bundleAddedSets.add(dependencyResult.toString());\n                this.bundleDependencies.add(dependencyResult);\n\n            }\n        }\n        for (DependencyResult dependencyResult : bundleCompileDependencies) {\n            if (!bundleAddedSets.contains(dependencyResult.toString())) {\n                this.bundleDependencies.add(dependencyResult);\n                bundleAddedSets.add(dependencyResult.toString());\n            }\n        }\n\n        this.bundleProvidedMap = getBundleProvidedMap(bundleClasspath);\n\n\n\n    }\n\n    private Set<String> getBundleDependencies(Configuration compileClasspath,\n                                              Set<? extends DependencyResult> bundleDependencies, Set<String> awbs) {\n        Set<String> bundleSets = new HashSet<>();\n        for (DependencyResult dependencyResult : bundleDependencies) {\n            bundleSets.add(dependencyResult.toString());\n        }\n        for (Dependency dependency : compileClasspath.getAllDependencies()) {\n            if (dependency instanceof DefaultExternalModuleDependency) {\n                DefaultExternalModuleDependency externalModuleDependency = (DefaultExternalModuleDependency)dependency;\n                if (!((DefaultExternalModuleDependency)dependency).getArtifacts().isEmpty()) {\n                    if (StringUtils.equalsIgnoreCase(\"awb\", ((DefaultExternalModuleDependency)dependency).getArtifacts()\n                        .iterator().next().getType()) || awbs.contains(dependency.getGroup()+\":\"+dependency.getName())) {\n                        bundleSets.add(\n                            dependency.getGroup() + \":\" + dependency.getName() + \":\" + dependency.getVersion());\n                    }\n                }\n            }\n        }\n        return bundleSets;\n    }\n\n    /**\n     * Gets the private dependencies of the bundle\n     *\n     * @param bundleClasspath\n     * @return\n     */\n    private Map<String, Set<String>> getBundleProvidedMap(Configuration bundleClasspath) {\n        Map<String, Set<String>> bundleMap = new HashMap<>();\n        bundleClasspath.getDependencies().forEach(new Consumer<Dependency>() {\n            @Override\n            public void accept(Dependency dependency) {\n                if (dependency instanceof DefaultProjectDependency) {\n                    DefaultProjectDependency projectDependency = (DefaultProjectDependency)dependency;\n                    String key = projectDependency.getGroup() + \":\" + projectDependency.getName();\n                    Set<String> providedSets = new HashSet<>();\n                    try {\n                        projectDependency.getDependencyProject().getConfigurations().getByName(\"compile\")\n                            .getDependencies().forEach(\n                            new Consumer<Dependency>() {\n                                @Override\n                                public void accept(Dependency dependency) {\n                                    if (\"com.android.support\".equals(dependency.getGroup()) || \"com.android.databinding\"\n                                        .equals(dependency.getGroup())) {\n                                        providedSets.add(dependency.getGroup() + \":\" + dependency.getName());\n                                    }\n\n                                }\n                            });\n                        projectDependency.getDependencyProject().getConfigurations().getByName(\n                            AtlasPlugin.PROVIDED_COMPILE)\n                            .getDependencies().forEach(\n                            new Consumer<Dependency>() {\n                                @Override\n                                public void accept(Dependency dependency) {\n                                    providedSets.add(dependency.getGroup() + \":\" + dependency.getName());\n                                }\n                            });\n                    } catch (UnknownConfigurationException e) {\n\n                    }\n                    bundleMap.put(key, providedSets);\n                }\n            }\n        });\n        return bundleMap;\n    }\n\n    private Map<String, Set<DependencyResult>>getProjectBundleCompile(Configuration configuration, Set<String> bundleAddedSets){\n        Map<String,Set<DependencyResult>>bundleMap = new HashMap<>();\n        configuration.getAllDependencies().forEach(new Consumer<Dependency>() {\n            @Override\n            public void accept(Dependency dependency) {\n                if (dependency instanceof DefaultProjectDependency) {\n                    DefaultProjectDependency projectDependency = (DefaultProjectDependency)dependency;\n                    String key = \"project \" + \":\" + projectDependency.getName();\n                    if (!bundleAddedSets.contains(key)){\n                        return;\n                    }\n                    Set<DependencyResult> compileSets = new HashSet<>();\n                    try {\n                        Set<ResolvedArtifact> resolvedArtifacts = projectDependency.getDependencyProject().getConfigurations().getByName(\"compile\").getResolvedConfiguration().getResolvedArtifacts();\n                        projectDependency.getDependencyProject().getConfigurations().getByName(\"compile\").getIncoming().getResolutionResult().getRoot().getDependencies().forEach(new Consumer<DependencyResult>() {\n                            @Override\n                            public void accept(DependencyResult dependencyResult) {\n                                if (!mainDexs.contains(dependencyResult.toString())){\n                                        compileSets.add(dependencyResult);\n                                        if (dependencyResult instanceof DefaultResolvedDependencyResult){\n                                            ModuleVersionIdentifier moduleVersionIdentifier = ((DefaultResolvedDependencyResult) dependencyResult).getSelected().getModuleVersion();\n                                            for (ResolvedArtifact resolvedArtifact:resolvedArtifacts) {\n                                                if (resolvedArtifact.getModuleVersion().getId().equals(moduleVersionIdentifier)) {\n                                                    bundleCompileId.put(moduleVersionIdentifier, resolvedArtifact);\n                                                }\n                                            }\n                                        }\n                                }\n                            }\n                        });\n\n                    } catch (UnknownConfigurationException e) {\n\n                    }\n                    bundleMap.put(projectDependency.getGroup()+\":\"+projectDependency.getName(), compileSets);\n                }\n            }\n        });\n        return bundleMap;\n\n    }\n\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/dependency/parser/helper/DependencyResolver.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.dependency.parser.helper;\n\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.dependency.VariantDependencies;\nimport com.android.build.gradle.internal.ide.DependencyConvertUtils;\nimport com.android.builder.model.MavenCoordinates;\nimport com.android.utils.ILogger;\nimport com.google.common.collect.LinkedHashMultimap;\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Multimap;\nimport com.taobao.android.builder.dependency.parser.AtlasDepHelper;\nimport com.taobao.android.builder.dependency.parser.CircleDependencyCheck;\nimport com.taobao.android.builder.dependency.parser.DependencyLocationManager;\nimport com.taobao.android.builder.dependency.parser.ResolvedDependencyInfo;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.ModuleVersionIdentifier;\nimport org.gradle.api.artifacts.ResolvedArtifact;\nimport org.gradle.api.artifacts.component.ComponentIdentifier;\nimport org.gradle.api.artifacts.component.ProjectComponentIdentifier;\nimport org.gradle.api.artifacts.result.DependencyResult;\nimport org.gradle.api.artifacts.result.ResolvedComponentResult;\nimport org.gradle.api.artifacts.result.ResolvedDependencyResult;\n\nimport java.io.File;\nimport java.util.*;\n\n/**\n * Created by wuzhong on 2017/4/17.\n */\npublic class DependencyResolver {\n\n    private static final ILogger logger = LoggerWrapper.getLogger(DependencyResolver.class);\n    private final Map<String, Set<DependencyResult>> bundleCompileMap;\n\n//    private final ApDependencies apDependencies;\n\n    Project project;\n\n    VariantDependencies variantDeps;\n\n    Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts;\n    Set<String>ids = new HashSet<>();\n\n    Map<String, Set<String>> bundleProvidedMap;\n\n    public Set<String> mainDependencies = new HashSet<>();\n\n    public DependencyResolver(Project project, VariantDependencies variantDeps,\n                              Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts,\n                              Map<String, Set<String>> bundleProvidedMap, Map<String,Set<DependencyResult>>bundleCompileMap) {\n        this.project = project;\n        this.variantDeps = variantDeps;\n        this.artifacts = artifacts;\n        this.bundleProvidedMap = bundleProvidedMap;\n        this.bundleCompileMap = bundleCompileMap;\n        if (artifacts!= null){\n            for (ModuleVersionIdentifier moduleVersionIdentifier:artifacts.keySet()){\n               ids.add(moduleVersionIdentifier.getGroup()+\":\"+moduleVersionIdentifier.getName());\n            }\n        }\n//        this.apDependencies = apDependencies;\n    }\n\n    public List<ResolvedDependencyInfo> resolve(List<DependencyResult> dependencyResults, boolean mainBundle) {\n        Multimap<String, ResolvedDependencyInfo> dependenciesMap = LinkedHashMultimap.create();\n        // Instead of using the official flat dependency treatment, you can use your own tree dependence; For application dependencies, we only take compile dependencies\n        Set<ModuleVersionIdentifier> directDependencies = new HashSet<ModuleVersionIdentifier>();\n        Set<String> resolveSets = new HashSet<>();\n        for (DependencyResult dependencyResult : dependencyResults) {\n            if (dependencyResult instanceof ResolvedDependencyResult) {\n                ModuleVersionIdentifier moduleVersion = ((ResolvedDependencyResult)dependencyResult).getSelected()\n                    .getModuleVersion();\n                CircleDependencyCheck circleDependencyCheck = new CircleDependencyCheck(moduleVersion);\n\n                if (!directDependencies.contains(moduleVersion)) {\n                    directDependencies.add(moduleVersion);\n                    resolveDependency(null, ((ResolvedDependencyResult)dependencyResult).getSelected(), artifacts,\n                                      variantDeps, 0, circleDependencyCheck,\n                                      circleDependencyCheck.getRootDependencyNode(), dependenciesMap, resolveSets,mainBundle);\n                }\n\n            }\n        }\n\n        List<ResolvedDependencyInfo> mainResolvdInfo = resolveAllDependencies(dependenciesMap);\n        if (mainBundle) {\n            for (ResolvedDependencyInfo resolvedDependencyInfo : mainResolvdInfo) {\n                addMainDependencyInfo(resolvedDependencyInfo);\n            }\n        }\n        return mainResolvdInfo;\n\n    }\n\n    private void addMainDependencyInfo(ResolvedDependencyInfo resolvedDependencyInfo) {\n\n        this.mainDependencies.add(resolvedDependencyInfo.getGroup() + \":\" + resolvedDependencyInfo.getName());\n\n        for (ResolvedDependencyInfo child : resolvedDependencyInfo.getChildren()) {\n            addMainDependencyInfo(child);\n        }\n\n    }\n\n    /**\n     * Analytical dependence\n     *  @param parent\n     * @param resolvedComponentResult\n     * @param artifacts\n     * @param configDependencies\n     * @param indent\n     * @param mainBundle\n     */\n    private void resolveDependency(ResolvedDependencyInfo parent, ResolvedComponentResult resolvedComponentResult,\n                                   Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts,\n                                   VariantDependencies configDependencies, int indent,\n                                   CircleDependencyCheck circleDependencyCheck,\n                                   CircleDependencyCheck.DependencyNode node,\n                                   Multimap<String, ResolvedDependencyInfo> dependenciesMap,\n                                   Set<String> resolvedDependencies, boolean mainBundle) {\n        ModuleVersionIdentifier moduleVersion = resolvedComponentResult.getModuleVersion();\n\n//        if (checkForExclusion(configDependencies, moduleVersion, resolvedComponentResult)) { return; }\n\n//        if (moduleVersion.getName().equals(\"support-annotations\") && moduleVersion.getGroup().equals(\n//            \"com.android.support\")) {\n//            configDependencies.setAnnotationsPresent(true);\n//        }\n        if (!ids.contains(moduleVersion.getGroup()+\":\"+moduleVersion.getName())){\n            artifacts.put(moduleVersion,Lists.newArrayList((DependencyGroup.bundleCompileId.get(moduleVersion))));\n        }\n        // now loop on all the artifact for this modules.\n        List<ResolvedArtifact> moduleArtifacts = artifacts.get(moduleVersion);\n\n        ComponentIdentifier id = resolvedComponentResult.getId();\n        String gradlePath = (id instanceof ProjectComponentIdentifier) ? ((ProjectComponentIdentifier)id)\n            .getProjectPath() : null;\n\n        // If you can find multiple dependencies at the same time, you can't judge for the time being that it's really useful\n        if (null != moduleArtifacts) {\n            for (ResolvedArtifact resolvedArtifact : moduleArtifacts) {\n                String key = moduleVersion.getGroup() + \":\" + moduleVersion.getName();\n                //remove android.jar\n                if(key.equals(\"com.google.android:android\")){\n                    continue;\n                }\n                if (mainDependencies.contains(key)) {\n                    continue;\n                }\n                if (resolvedDependencies.contains(key)) {\n                    continue;\n                }\n\n                //\n\n                resolvedDependencies.add(key);\n                boolean isAwbBundle = bundleProvidedMap.containsKey(key);\n                Set<String> providedDirectDep = bundleProvidedMap.get(key);\n\n                ResolvedDependencyInfo resolvedDependencyInfo = new ResolvedDependencyInfo(moduleVersion.getVersion(),\n                                                                                           moduleVersion.getGroup(),\n                                                                                           moduleVersion.getName(),\n                                                                                           !mainBundle ? \"awb\"\n                                                                                               : resolvedArtifact\n                                                                                                   .getType(),\n                                                                                           resolvedArtifact\n                                                                                               .getClassifier());\n                resolvedDependencyInfo.setIndent(indent);\n                resolvedDependencyInfo.setGradlePath(gradlePath);\n                resolvedDependencyInfo.setResolvedArtifact(resolvedArtifact);\n\n                String path = AtlasDepHelper.computeArtifactPath(moduleVersion, resolvedArtifact);\n                String name = AtlasDepHelper.computeArtifactName(moduleVersion, resolvedArtifact);\n\n                MavenCoordinates mavenCoordinates = DependencyConvertUtils.convert(resolvedArtifact,!mainBundle? DependencyConvertUtils.Type.AWB: DependencyConvertUtils.Type.AAR);\n\n\n                File explodedDir = DependencyLocationManager.getExploreDir(project, mavenCoordinates,\n                                                                           resolvedArtifact.getFile(),\n                                                                           !mainBundle? \"awb\":resolvedArtifact.getType().toLowerCase(),\n                                                                           path);\n\n                resolvedDependencyInfo.setExplodedDir(explodedDir);\n\n                resolvedDependencyInfo.setDependencyName(name);\n\n                if (null == parent) {\n                    parent = resolvedDependencyInfo;\n                } else {\n                    resolvedDependencyInfo.setParent(parent);\n                    parent.getChildren().add(resolvedDependencyInfo);\n                }\n\n                Set<DependencyResult>dependencyResults = null;\n                Set<? extends DependencyResult> dependencies = (Set<DependencyResult>) resolvedComponentResult.getDependencies();\n                if (bundleCompileMap.containsKey(resolvedDependencyInfo.getGroup()+\":\"+resolvedDependencyInfo.getName())){\n                     dependencyResults= bundleCompileMap.get(parent.getGroup()+\":\"+parent.getName());\n                }\n                    Set<DependencyResult>combineDependencies = combine(dependencyResults,dependencies);\n                if (null != combineDependencies) {\n                    for (DependencyResult dep : combineDependencies) {\n                        if (dep instanceof ResolvedDependencyResult) {\n                            ResolvedComponentResult childResolvedComponentResult = ((ResolvedDependencyResult)dep)\n                                .getSelected();\n\n                            if (isAwbBundle && providedDirectDep.contains(\n                                childResolvedComponentResult.getModuleVersion().getGroup() + \":\"\n                                + childResolvedComponentResult.getModuleVersion().getName())) {\n                                continue;\n                            }\n\n                            CircleDependencyCheck.DependencyNode childNode = circleDependencyCheck.addDependency(\n                                childResolvedComponentResult.getModuleVersion(), node, indent + 1);\n                            CircleDependencyCheck.CircleResult circleResult = circleDependencyCheck.checkCircle(logger);\n                            if (circleResult.hasCircle) {\n                                logger.warning(\"[CircleDependency]\" + StringUtils.join(circleResult.detail, \";\"));\n                            } else {\n                                resolveDependency(parent, ((ResolvedDependencyResult)dep).getSelected(), artifacts,\n                                                  configDependencies, indent + 1, circleDependencyCheck, childNode,\n                                                  dependenciesMap, resolvedDependencies, true);\n                            }\n                        }\n                    }\n                }\n\n                addDependencyInfo(resolvedDependencyInfo, null, dependenciesMap);\n            }\n        }\n\n    }\n\n    private Set<DependencyResult> combine(Set<DependencyResult> dependencyResults, Set<? extends DependencyResult> dependencies) {\n        Set<DependencyResult>combineDependencies = new HashSet<>();\n        if (dependencyResults!= null) {\n            for (DependencyResult dependencyResult : dependencyResults) {\n                combineDependencies.add(dependencyResult);\n            }\n        }\n        if (dependencies!= null) {\n            for (DependencyResult dependencyResult : dependencies) {\n                combineDependencies.add(dependencyResult);\n            }\n        }\n        return combineDependencies;\n    }\n\n//    private boolean checkForExclusion(VariantDependencies configDependencies, ModuleVersionIdentifier moduleVersion,\n//                                      ResolvedComponentResult resolvedComponentResult) {\n//        if (configDependencies.getChecker().checkForExclusion(moduleVersion) || (apDependencies != null\n//                                                                                 && apDependencies\n//                                                                                     .hasSameResolvedDependency(\n//                                                                                         moduleVersion)\n//                                                                                 && !(resolvedComponentResult\n//            .getId() instanceof ProjectComponentIdentifier))) {\n//            return true;\n//        }\n//        return false;\n//    }\n\n    /**\n     * Add the dependency\n     *\n     * @param resolvedDependencyInfo\n     * @param parent                 This parent is a primary dependency\n     */\n    private void addDependencyInfo(ResolvedDependencyInfo resolvedDependencyInfo, ResolvedDependencyInfo parent,\n                                   Multimap<String, ResolvedDependencyInfo> dependenciesMap) {\n\n        dependenciesMap.put(resolvedDependencyInfo.toString(), resolvedDependencyInfo);\n\n        if (null != parent) {\n            resolvedDependencyInfo.setParent(parent);\n        }\n        List<ResolvedDependencyInfo> children = resolvedDependencyInfo.getChildren();\n        if (null != children && children.size() > 0) {\n\n            for (ResolvedDependencyInfo child : children) {\n                addDependencyInfo(child, resolvedDependencyInfo, dependenciesMap);\n            }\n        }\n    }\n\n    /**\n     * Relying on arbitration\n     */\n    private List<ResolvedDependencyInfo> resolveAllDependencies(\n        Multimap<String, ResolvedDependencyInfo> dependenciesMap) {\n\n        List<ResolvedDependencyInfo> allResolvedDependencyInfos = new ArrayList<>();\n\n        // The post-arbitration dependencies. The structure is the parent class - subclass\n        Multimap<ModuleVersionIdentifier, ResolvedDependencyInfo> resolvedDependenciesMap = LinkedHashMultimap.create();\n        Map<ModuleVersionIdentifier, ResolvedDependencyInfo> directDependencies\n            = new HashMap<ModuleVersionIdentifier, ResolvedDependencyInfo>();\n\n        for (String key : dependenciesMap.keySet()) {\n            Collection<ResolvedDependencyInfo> dependencyLevels = dependenciesMap.get(key);\n\n            if (dependencyLevels.size() > 0) {\n\n                List<ResolvedDependencyInfo> resolvedDependencyInfos = Lists.newArrayList();\n                resolvedDependencyInfos.addAll(dependencyLevels);\n                Collections.sort(resolvedDependencyInfos);\n                ResolvedDependencyInfo resolvedDependencyInfo = resolvedDependencyInfos.get(0);\n                ResolvedDependencyInfo parent = resolvedDependencyInfo.getParent();\n                //Children are not required to add information to the resolvedDependenciesMap\n                resolvedDependencyInfo.setChildren(Lists.<ResolvedDependencyInfo>newArrayList());\n                if (null != parent) {\n                    //If the parent is dependent, then the current dependency is added to the dependency of the parent\n                    resolvedDependenciesMap.put(parent.getModuleVersionIdentifier(), resolvedDependencyInfo);\n                } else {\n                    //If there is no parent dependency, it is a primary dependency\n                    directDependencies.put(resolvedDependencyInfo.getModuleVersionIdentifier(), resolvedDependencyInfo);\n                }\n            }\n        }\n\n        // Start building the dependency tree\n\n        for (ModuleVersionIdentifier key : directDependencies.keySet()) {\n            ResolvedDependencyInfo resolvedDependencyInfo = directDependencies.get(key);\n            //Empty the children\n            resolvedDependencyInfo.setChildren(Lists.<ResolvedDependencyInfo>newArrayList());\n            addResolvedDependencyInfo(resolvedDependencyInfo, resolvedDependenciesMap);\n            allResolvedDependencyInfos.add(resolvedDependencyInfo);\n        }\n\n        return allResolvedDependencyInfos;\n\n    }\n\n    /**\n     * A recursive approach to dependency resolution\n     *\n     * @param parentDependency\n     * @param resolvedDependenciesMap\n     */\n    private void addResolvedDependencyInfo(ResolvedDependencyInfo parentDependency,\n                                           Multimap<ModuleVersionIdentifier, ResolvedDependencyInfo>\n                                               resolvedDependenciesMap) {\n        int indent = parentDependency.getIndent();\n        ModuleVersionIdentifier identifier = parentDependency.getModuleVersionIdentifier();\n        Collection<ResolvedDependencyInfo> childDependencies = resolvedDependenciesMap.get(identifier);\n\n        //TODO here\n        for (ResolvedDependencyInfo childDependency : childDependencies) {\n            if (childDependency.getIndent() > indent) {\n                //                System.out.println(parentDependency + \" indent \" + indent + \"->\" + childDependency\n                // +  \" indent \" + childDependency.getIndent());\n                parentDependency.getChildren().add(childDependency);\n                if (childDependency.getIndent() <= 1) {\n                    addResolvedDependencyInfo(childDependency, resolvedDependenciesMap);\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/AtlasExtension.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.extension;\n\nimport com.android.annotations.NonNull;\nimport com.taobao.android.builder.extension.annotation.Config;\nimport com.taobao.android.builder.extension.annotation.ConfigGroup;\nimport com.taobao.android.builder.extension.factory.DefaultChannelConfigFactory;\nimport com.taobao.android.builder.extension.factory.EnhanceConfigFactory;\nimport com.taobao.android.builder.extension.factory.MultiDexConfigFactory;\nimport org.gradle.api.Action;\nimport org.gradle.api.NamedDomainObjectContainer;\nimport org.gradle.api.Project;\nimport org.gradle.api.internal.project.ProjectInternal;\nimport org.gradle.api.logging.Logger;\nimport org.gradle.api.logging.Logging;\nimport org.gradle.internal.reflect.Instantiator;\n\npublic class AtlasExtension<T extends TBuildType, Z extends TBuildConfig> {\n\n    @ConfigGroup(order = 1, advance = false)\n    public Z tBuildConfig;\n\n    @ConfigGroup(order = 2)\n    public NamedDomainObjectContainer<T> buildTypes;\n\n\n\n    public NamedDomainObjectContainer<EnhanceConfig> enhanceConfigs;\n\n    @ConfigGroup(order = 12, advance = false)\n    public NamedDomainObjectContainer<PatchConfig> patchConfigs;\n\n    public NamedDomainObjectContainer<DexConfig> dexConfigs;\n\n\n    public NamedDomainObjectContainer<DefaultChannelConfig> atlasChannelConfigs;\n\n\n\n    public BundleConfig bundleConfig;\n\n    @ConfigGroup(order = 3, advance = true)\n    public ManifestOptions manifestOptions;\n\n    @ConfigGroup(order = 4, advance = false)\n    public NamedDomainObjectContainer<MultiDexConfig> multiDexConfigs;\n\n\n    //If the atlas switch is switched on, the default switch will be opened automatically\n    @Config(title = \"Enable atlas\", message = \"Enable atlas , true/false\", order = 0, group = \"atlas\")\n    private boolean atlasEnabled;\n\n    protected Project project;\n\n\n    public boolean isInstantAppEnabled() {\n        return instantAppEnabled;\n    }\n\n    public void setInstantAppEnabled(boolean instantAppEnabled) {\n        this.instantAppEnabled = instantAppEnabled;\n    }\n\n    private boolean instantAppEnabled;\n\n    protected Logger logger;\n\n    public AtlasExtension() {\n    }\n\n    public AtlasExtension(@NonNull final ProjectInternal project,\n                          @NonNull Instantiator instantiator,\n                          @NonNull NamedDomainObjectContainer<T> buildTypes,\n                          @NonNull NamedDomainObjectContainer<PatchConfig> patchConfigs,\n                          @NonNull NamedDomainObjectContainer<DexConfig> dexConfigs) {\n\n        logger = Logging.getLogger(this.getClass());\n        this.project = project;\n\n        this.patchConfigs = patchConfigs;\n        this.dexConfigs = dexConfigs;\n        this.buildTypes = buildTypes;\n        this.multiDexConfigs = project.container(MultiDexConfig.class, new MultiDexConfigFactory(\n\n            instantiator,project, project.getLogger()));\n        this.atlasChannelConfigs = project.container(DefaultChannelConfig.class, new DefaultChannelConfigFactory(instantiator, project, project.getLogger()));\n        this.enhanceConfigs = project.container(EnhanceConfig.class, new EnhanceConfigFactory(instantiator, project, project.getLogger()));\n        tBuildConfig = (Z) instantiator.newInstance(TBuildConfig.class);\n        manifestOptions = instantiator.newInstance(ManifestOptions.class);\n        bundleConfig = instantiator.newInstance(BundleConfig.class);\n    }\n\n    public void buildTypes(Action<? super NamedDomainObjectContainer<T>> action) {\n        action.execute(buildTypes);\n    }\n\n    public void patchConfigs(Action<? super NamedDomainObjectContainer<PatchConfig>> action) {\n        action.execute(patchConfigs);\n    }\n\n    public void tBuildConfig(Action<Z> action) {\n        action.execute(tBuildConfig);\n    }\n\n    public void dexConfigs(Action<? super NamedDomainObjectContainer<DexConfig>> action) {\n        action.execute(dexConfigs);\n    }\n\n    public void manifestOptions(Action<ManifestOptions> action) {\n        action.execute(manifestOptions);\n    }\n\n    public void bundleConfig(Action<BundleConfig> action) {\n        action.execute(bundleConfig);\n    }\n\n    public void multiDexConfigs(Action<? super NamedDomainObjectContainer<MultiDexConfig>> action) {\n        action.execute(multiDexConfigs);\n    }\n\n    public void enhanceConfigs(Action<? super NamedDomainObjectContainer<EnhanceConfig>> action) {\n        action.execute(enhanceConfigs);\n    }\n\n\n    public void setEnhanceConfigs(NamedDomainObjectContainer<EnhanceConfig> enhanceConfigs) {\n        this.enhanceConfigs = enhanceConfigs;\n    }\n\n\n    public NamedDomainObjectContainer<PatchConfig> getPatchConfigs() {\n        return patchConfigs;\n    }\n\n    public NamedDomainObjectContainer<T> getBuildTypes() {\n        return buildTypes;\n    }\n\n    public BundleConfig getBundleConfig() {\n        return bundleConfig;\n    }\n\n    public ManifestOptions getManifestOptions() {\n        return manifestOptions;\n    }\n\n    public TBuildConfig getTBuildConfig() {\n        return tBuildConfig;\n    }\n\n    public NamedDomainObjectContainer<DexConfig> getDexConfig() {\n        return dexConfigs;\n    }\n\n    public boolean isAtlasEnabled() {\n        return atlasEnabled;\n    }\n\n    public void setAtlasEnabled(boolean atlasEnabled) {\n        this.atlasEnabled = atlasEnabled;\n    }\n\n    public Logger getLogger() {\n        return logger;\n    }\n\n    public Project getProject() {\n        return project;\n    }\n\n    public NamedDomainObjectContainer<MultiDexConfig> getMultiDexConfigs() {\n        return multiDexConfigs;\n    }\n\n    public void setMultiDexConfigs(\n            NamedDomainObjectContainer<MultiDexConfig> multiDexConfigs) {\n        this.multiDexConfigs = multiDexConfigs;\n    }\n\n\n    public Boolean getBaseFeature() {\n        return false;\n    }\n\n\n    public void atlasChannelConfigs(Action<? super NamedDomainObjectContainer<DefaultChannelConfig>> action) {\n        action.execute(atlasChannelConfigs);\n    }\n\n\n    public void setAtlasChannelConfigs(NamedDomainObjectContainer<DefaultChannelConfig> atlasChannelConfigs) {\n        this.atlasChannelConfigs = atlasChannelConfigs;\n    }\n\n}\n\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/BundleConfig.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.extension;\n\n/**\n * Created by wuzhong on 2016/9/30.\n */\npublic class BundleConfig {\n\n    private boolean jarEnabled = false;\n\n    private Boolean awbBundle = false;\n    private Boolean awoBuildEnabled = false;\n    private boolean awoDynDeploy = true;\n    private boolean awoApkBuild = true;\n    private boolean mergeRes = true;\n\n    public Boolean isAwbBundle() {\n        return awbBundle;\n    }\n\n    public void setAwbBundle(Boolean awbBundle) {\n        this.awbBundle = awbBundle;\n    }\n\n    public Boolean isAwoBuildEnabled() {\n        return awoBuildEnabled;\n    }\n\n    public void setAwoBuildEnabled(Boolean awoBuildEnabled) {\n        this.awoBuildEnabled = awoBuildEnabled;\n    }\n\n    public boolean isAwoDynDeploy() {\n        return awoDynDeploy;\n    }\n\n    public void setAwoDynDeploy(boolean awoDynDeploy) {\n        this.awoDynDeploy = awoDynDeploy;\n    }\n\n    public boolean isAwoApkBuild() {\n        return awoApkBuild;\n    }\n\n    public void setAwoApkBuild(boolean awoApkBuild) {\n        this.awoApkBuild = awoApkBuild;\n    }\n\n    public boolean isMergeRes() {\n        return mergeRes;\n    }\n\n    public void setMergeRes(boolean mergeRes) {\n        this.mergeRes = mergeRes;\n    }\n\n    public boolean isJarEnabled() {\n        return jarEnabled;\n    }\n\n    public void setJarEnabled(boolean jarEnabled) {\n        this.jarEnabled = jarEnabled;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/DefaultChannelConfig.java",
    "content": "package com.taobao.android.builder.extension;\n\nimport java.io.File;\nimport java.util.Map;\n\n/**\n * Created by jason on 18/3/20.\n */\n\npublic class DefaultChannelConfig {\n\n    private String name;\n\n    private boolean enabled = false;\n\n    private String ttids = \"\";\n\n    private File ttidFile;\n\n    private String apkName;\n\n    private String channelPropertyName = \"ttid\";\n\n    private String propertiesFile = \"config.properties\";\n\n    private String channelFolder = \"dev-adaptation\";\n\n    public DefaultChannelConfig(String name) {\n        this.name = name;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public boolean isEnabled() {\n        return enabled;\n    }\n\n    public void setEnabled(boolean enabled) {\n        this.enabled = enabled;\n    }\n\n    public String getTtids() {\n        return ttids;\n    }\n\n    public void setTtids(String ttids) {\n        this.ttids = ttids;\n    }\n\n    public File getTtidFile() {\n        return ttidFile;\n    }\n\n    public void setTtidFile(File ttidFile) {\n        this.ttidFile = ttidFile;\n    }\n\n    public String getApkName() {\n        return apkName;\n    }\n\n    public void setApkName(String apkName) {\n        this.apkName = apkName;\n    }\n\n    public String getChannelPropertyName() {\n        return channelPropertyName;\n    }\n\n    public void setChannelPropertyName(String channelPropertyName) {\n        this.channelPropertyName = channelPropertyName;\n    }\n\n    public String getPropertiesFile() {\n        return propertiesFile;\n    }\n\n    public void setPropertiesFile(String propertiesFile) {\n        this.propertiesFile = propertiesFile;\n    }\n\n    public String getChannelFolder() {\n        return channelFolder;\n    }\n\n    public void setChannelFolder(String channelFolder) {\n        this.channelFolder = channelFolder;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/DexConfig.java",
    "content": "package com.taobao.android.builder.extension;\n\n/**\n * @author lilong\n * @create 2017-05-26 On the afternoon of mount zalmon\n */\n\npublic class DexConfig {\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    private String name;\n\n    public DexConfig(String name){\n        this.name = name;\n    }\n\n    private boolean useMyDex = false;\n\n    public boolean isUseMyDex() {\n        return useMyDex;\n    }\n\n    public void setUseMyDex(boolean useMyDex) {\n        this.useMyDex = useMyDex;\n    }\n\n    public boolean isDexInProcess() {\n        return dexInProcess;\n    }\n\n    public void setDexInProcess(boolean dexInProcess) {\n        this.dexInProcess = dexInProcess;\n    }\n\n    private boolean dexInProcess = false;\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/EnhanceConfig.java",
    "content": "package com.taobao.android.builder.extension;\n\nimport java.io.File;\n\n/**\n * EnhanceConfig\n *\n * @author zhayu.ll\n\n * @date 18/5/7\n */\npublic class EnhanceConfig {\n\n        private String name;\n\n        private String version;\n\n        private boolean enabled;\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public String getVersion() {\n            return version;\n        }\n\n        public void setVersion(String version) {\n            this.version = version;\n        }\n\n        private File blackmap;\n\n        private File bundlecfg;\n\n        private File keepso;\n\n        public File getEnhanceJar() {\n            return enhanceJar;\n        }\n\n        public void setEnhanceJar(File enhanceJar) {\n            this.enhanceJar = enhanceJar;\n        }\n\n        private File enhanceJar;\n\n        public String getDependency() {\n            return dependency.concat(\":\"+version);\n        }\n\n        public void setDependency(String dependency) {\n            this.dependency = dependency;\n        }\n\n        private String dependency = \"com.ali.mobisecObfuscate:taobao-obf-tool-chain\";\n\n        public boolean isEnabled() {\n            return enabled;\n        }\n\n        public void setEnabled(boolean enabled) {\n            this.enabled = enabled;\n        }\n\n        public File getBlackmap() {\n            return blackmap;\n        }\n\n        public void setBlackmap(File blackmap) {\n            this.blackmap = blackmap;\n        }\n\n        public File getBundlecfg() {\n            return bundlecfg;\n        }\n\n        public void setBundlecfg(File bundlecfg) {\n            this.bundlecfg = bundlecfg;\n        }\n\n        public File getKeepso() {\n            return keepso;\n        }\n\n        public void setKeepso(File keepso) {\n            this.keepso = keepso;\n        }\n\n        public String getObfnamemode() {\n            return obfnamemode;\n        }\n\n        public void setObfnamemode(String obfnamemode) {\n            this.obfnamemode = obfnamemode;\n        }\n\n        public boolean isMovedebuginfo() {\n            return movedebuginfo;\n        }\n\n        public void setMovedebuginfo(boolean movedebuginfo) {\n            this.movedebuginfo = movedebuginfo;\n        }\n\n        public boolean isOpenj2c() {\n            return openj2c;\n        }\n\n        public void setOpenj2c(boolean openj2c) {\n            this.openj2c = openj2c;\n        }\n\n        public File getJ2ccfg() {\n            return j2ccfg;\n        }\n\n        public void setJ2ccfg(File j2ccfg) {\n            this.j2ccfg = j2ccfg;\n        }\n\n        public File getJ2cpolicy() {\n            return j2cpolicy;\n        }\n\n        public void setJ2cpolicy(File j2cpolicy) {\n            this.j2cpolicy = j2cpolicy;\n        }\n\n        private String obfnamemode;\n\n        private boolean movedebuginfo;\n\n        private boolean openj2c;\n\n        private File j2ccfg;\n\n        private File j2cpolicy;\n\n        public EnhanceConfig(String name) {\n            this.name = name;\n\n        }\n    }\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/ManifestOptions.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.extension;\n\nimport java.io.File;\nimport java.util.Set;\n\nimport com.google.common.collect.Sets;\nimport com.taobao.android.builder.extension.annotation.Config;\n\n/**\n * Created by shenghua.nish on 2016-05-17 And in the morning.\n */\npublic class ManifestOptions {\n\n    @Config(order = 1, message = \"Keep a list of launch launches\", advance = false, group = \"atlas\")\n    private Set<String> retainLaunches = Sets.newHashSet();\n\n    @Config(order = 2, message = \"Reserved permissions list\", advance = false, group = \"atlas\")\n    private Set<String> retainPermissions = Sets.newHashSet();\n\n    @Config(order = 3, message = \"The name of the system permissions removed\", advance = true, group = \"atlas\")\n    private Set<String> removeSystemPermissions = Sets.newHashSet();\n\n    @Config(order = 4, message = \"The name of the removed custom permission\", advance = true, group = \"atlas\")\n    private boolean removeCustomPermission = false;\n\n    @Config(order = 2, message = \"Access list\", advance = true, group = \"atlas\")\n    private File  permissionListFile;\n\n    @Config(order = 2, message = \"Access list\", advance = true, group = \"atlas\")\n    private File  permissionJsonFile;\n\n    @Config(order = 5, message = \"Components add the coordinates of the bundle\", advance = true, group = \"atlas\")\n    private boolean addBundleLocation = true;\n\n    @Config(order = 6, message = \"The ability to open new components\", advance = true, group = \"atlas\")\n    private boolean addAtlasProxyComponents /*= true*/;\n\n    @Config(order = 6, message = \"A channel list that does not perform atlas added components\", advance = true, group = \"atlas\")\n    private Set<String> atlasProxySkipChannels = Sets.newHashSet(\":dexmerge\", \":dex2oat\");\n\n    @Config(order = 7, title = \"Replace the application\",message = \"Use the atlas application, including atlasBasic initialization and multidex logic, Atlas must be opened\", advance = true,\n        group = \"atlas\")\n    private boolean replaceApplication = true;\n\n    @Config(order = 8, title = \"To enable the atlas multidex\", message = \"Using atlas's multiDex function, Atlas must be opened\", advance = true, group = \"atlas\")\n    @Deprecated //Don't use the multi-dex automatic control\n    private boolean addMultiDexMetaData = true;\n\n    @Config(order = 9, message = \"Remove all providers\", advance = true, group = \"atlas\")\n    private boolean removeProvider = false;\n\n    @Config(order = 10, title = \"Do not do bundle for manifest merge\" ,message = \"Non-participating in the manifest merge dependent coordinates, group:name,group2:name2\", advance = true, group = \"atlas\")\n    private Set<String> notMergedBundles = Sets.newHashSet();\n\n    public Set<String> getNotMergedBundles() {\n        return notMergedBundles;\n    }\n\n    public void setNotMergedBundles(Set<String> notMerged) {\n        notMergedBundles = notMerged;\n    }\n\n    /**\n     * Returns a list of launch launches to be retained\n     *\n     * @return\n     */\n\n    public Set<String> getRetainLaunches() {\n        return retainLaunches;\n    }\n\n    /**\n     * Whether to remove custom permissions\n     *\n     * @return\n     */\n    public boolean isRemoveCustomPermission() {\n        return removeCustomPermission;\n    }\n\n    public void setRemoveCustomPermission(boolean removeCustomPermission) {\n        this.removeCustomPermission = removeCustomPermission;\n    }\n\n    /**\n     * Returns the name of the custom permission to keep\n     *\n     * @return\n     */\n\n    public Set<String> getRetainPermissions() {\n        return retainPermissions;\n    }\n\n    /**\n     * Returns the name of the system authority to be removed\n     *\n     * @return\n     */\n\n    public Set<String> getRemoveSystemPermissions() {\n        return removeSystemPermissions;\n    }\n\n    public void setRetainLaunches(Set<String> retainLaunches) {\n        this.retainLaunches = retainLaunches;\n    }\n\n    /**\n     * Sets extensions of files that will not be stored compressed in the APK.\n     * <p>\n     * <p>Equivalent of the -0 flag. See <code>aapt --help</code>\n     */\n    public void retainLaunches(String retainLaunche) {\n        retainLaunches.add(retainLaunche);\n    }\n\n    /**\n     * Sets extensions of files that will not be stored compressed in the APK.\n     * <p>\n     * <p>Equivalent of the -0 flag. See <code>aapt --help</code>\n     */\n    public void retainLaunches(String... retainLaunche) {\n        for (String str : retainLaunche) {\n            retainLaunches.add(str);\n        }\n    }\n\n    public void setRetainPermissions(Set<String> retainPermissions) {\n        this.retainPermissions = retainPermissions;\n    }\n\n    public void setRemoveSystemPermissions(Set<String> removeSystemPermissions) {\n        this.removeSystemPermissions = removeSystemPermissions;\n    }\n\n    public void removeSystemPermissions(String removeSystemPermission) {\n        removeSystemPermissions.add(removeSystemPermission);\n    }\n\n    public void removeSystemPermissions(String... removeSystemPermission) {\n        for (String str : removeSystemPermission) {\n            removeSystemPermissions.add(str);\n        }\n    }\n\n    public void retainPermissions(String retainPermission) {\n        retainPermissions.add(retainPermission);\n    }\n\n    public void retainPermissions(String... retainPermission) {\n        for (String str : retainPermission) {\n            retainPermissions.add(str);\n        }\n    }\n\n    public boolean isAddBundleLocation() {\n        return addBundleLocation;\n    }\n\n    public void setAddBundleLocation(boolean addBundleLocation) {\n        this.addBundleLocation = addBundleLocation;\n    }\n\n    public boolean isReplaceApplication() {\n        return replaceApplication;\n    }\n\n    public void setReplaceApplication(boolean replaceApplication) {\n        this.replaceApplication = replaceApplication;\n    }\n\n    public boolean isAddMultiDexMetaData() {\n        return addMultiDexMetaData;\n    }\n\n    public void setAddMultiDexMetaData(boolean addMultiDexMetaData) {\n        this.addMultiDexMetaData = addMultiDexMetaData;\n    }\n\n    public boolean isRemoveProvider() {\n        return removeProvider;\n    }\n\n    public void setRemoveProvider(boolean removeProvider) {\n        this.removeProvider = removeProvider;\n    }\n\n    public boolean isAddAtlasProxyComponents() {\n        return addAtlasProxyComponents;\n    }\n\n    public void setAddAtlasProxyComponents(boolean addAtlasProxyComponents) {\n        this.addAtlasProxyComponents = addAtlasProxyComponents;\n    }\n\n    public Set<String> getAtlasProxySkipChannels() {\n        return atlasProxySkipChannels;\n    }\n\n    public void setAtlasProxySkipChannels(Set<String> atlasProxySkipChannels) {\n        this.atlasProxySkipChannels = atlasProxySkipChannels;\n    }\n\n    public File getPermissionListFile() {\n        return permissionListFile;\n    }\n\n    public void setPermissionListFile(File permissionListFile) {\n        this.permissionListFile = permissionListFile;\n    }\n\n    public File getPermissionJsonFile() {\n        return permissionJsonFile;\n    }\n\n    public void setPermissionJsonFile(File permissionJsonFile) {\n        this.permissionJsonFile = permissionJsonFile;\n    }\n\n    @Override\n    public String toString() {\n        return \"ManifestOptionsImpl{\" +\n            \"retainLaunches=\" + retainLaunches +\n            \", retainPermissions=\" + retainPermissions +\n            \", removeSystemPermissions=\" + removeSystemPermissions +\n            \", removeCustomPermission=\" + removeCustomPermission +\n            \", addBundleLocation=\" + addBundleLocation +\n            \", notMergedBundles=\" + notMergedBundles +\n            '}';\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/MultiDexConfig.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.extension;\n\nimport java.util.Set;\n\nimport com.google.common.collect.Sets;\nimport com.taobao.android.builder.extension.annotation.Config;\n\n/**\n * Created by wuzhong on 2017/5/8.\n */\npublic class MultiDexConfig {\n\n    private String name;\n\n    public MultiDexConfig(String name) {\n        this.name = name;\n    }\n\n    @Config(title = \"Whether to enable fast\", message = \"Enable atlas , true/false\", order = 0, group = \"atlas\")\n    private boolean fastMultiDex = false;\n\n    @Config(title = \"The extra first dex class list\", message = \"The custom needs to be placed in the entry class in the first dex\", order = 3, group = \"atlas\")\n    private Set<String> firstDexClasses = Sets.newHashSet();\n    /**\n     * dex The number of subcontracting, 0 No restrictions, no two merges\n     */\n    @Config(title = \"dexThe number of\", message = \"0unlimited\", order = 1, group = \"atlas\")\n    private int dexCount;\n\n    public int getMainDexListCount() {\n        return mainDexListCount;\n    }\n\n    public void setMainDexListCount(int mainDexListCount) {\n        this.mainDexListCount = mainDexListCount;\n    }\n\n    private int mainDexListCount;\n\n    @Config(title = \"dexSeparated rules\", message = \"a,b;c,d\", order = 2, group = \"atlas\")\n    private String dexSplitRules;\n\n    @Config(title = \"Does not enter the list of the first dex's blacklist\", message = \"a\", order = 2, group = \"atlas\")\n    private Set<String> mainDexBlackList = Sets.newHashSet();\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public boolean isFastMultiDex() {\n        return fastMultiDex;\n    }\n\n    public void setFastMultiDex(boolean fastMultiDex) {\n        this.fastMultiDex = fastMultiDex;\n    }\n\n    public Set<String> getMainDexBlackList() {\n        return mainDexBlackList;\n    }\n\n    public void setMainDexBlackList(Set<String> mainDexBlackList) {\n        this.mainDexBlackList = mainDexBlackList;\n    }\n\n    public Set<String> getFirstDexClasses() {\n        return firstDexClasses;\n    }\n\n    public void setFirstDexClasses(Set<String> firstDexClasses) {\n        this.firstDexClasses = firstDexClasses;\n    }\n\n    public int getDexCount() {\n        return dexCount;\n    }\n\n    public void setDexCount(int dexCount) {\n        this.dexCount = dexCount;\n    }\n\n    public String getDexSplitRules() {\n        return dexSplitRules;\n    }\n\n    public void setDexSplitRules(String dexSplitRules) {\n        this.dexSplitRules = dexSplitRules;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/PatchConfig.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.extension;\n\nimport com.google.common.collect.Sets;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.extension.annotation.Config;\nimport org.apache.commons.lang.StringUtils;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * Created by shenghua.nish on 2016-05-17 As in the morning.\n */\npublic class PatchConfig {\n\n    private String name;\n\n    @Config(message = \"appThe application name of the registered signature\", order = 0, advance = false, group = \"atlas_patch\")\n    private String appSignName;\n\n    @Config(message = \" Play andfix patch bag \", order = 1, advance = true, group = \"atlas_patch\")\n    private boolean createIPatch = false;\n\n    public boolean isNewPatch() {\n        return newPatch;\n    }\n\n    public void setNewPatch(boolean newPatch) {\n        this.newPatch = newPatch;\n    }\n\n    private boolean newPatch = false;\n\n    @Config(message = \" Dynamic deployment patch bag \", order = 2, group = \"atlas_patch\")\n    private boolean createTPatch = false;\n\n    @Config(message = \"Dynamic deployment does not contain a list of files\", order = 3, advance = true, group = \"atlas_patch\")\n    private Set<String> tPatchNotIncludeFiles = Sets.newHashSet();\n\n    @Config(message = \" andfix Package filtering class A list of files \", order = 4, advance = true, group = \"atlas_patch\")\n    private File filterFile;\n\n    @Config(message = \" andfix Package filtering class tabulation \", order = 5, advance = true, group = \"atlas_patch\")\n    private Set<String> filterClasses = new HashSet<String>();\n\n    private boolean apForBaseFile = true;\n\n    public boolean isDiffNativeSo() {\n        return diffNativeSo;\n    }\n\n    public void setDiffNativeSo(boolean diffNativeSo) {\n        this.diffNativeSo = diffNativeSo;\n    }\n\n    private boolean diffNativeSo = false;\n\n\n    private Set<String> j2cPatchClasses = new HashSet<>();\n\n    public void setPatchClasses(Set<String> patchClasses) {\n        this.patchClasses = patchClasses;\n    }\n\n    private Set<String> patchClasses = new HashSet<>();\n\n    private File apExploredFolder;\n\n    private File finalBasePatchFile;\n\n    public File getHotClassListFile() {\n        return hotClassListFile;\n    }\n\n    public void setHotClassListFile(File hotClassListFile) {\n        this.hotClassListFile = hotClassListFile;\n    }\n\n    private File hotClassListFile;\n\n    public Set<String> getExcludeClasses() {\n        if (excludeClasses.size() > 0){\n            return excludeClasses;\n        }else {\n            return Sets.newHashSet(\"Landroid/taobao/atlas/framework/FrameworkProperties;\",\"Landroid/taobao/atlas/bundleInfo/AtlasBundleInfoGenerator;\");\n        }\n    }\n\n    public void setExcludeClasses(Set<String> excludeClasses) {\n        this.excludeClasses = excludeClasses;\n    }\n\n    //排除的class列表\n    private Set<String>excludeClasses = new HashSet<>();\n\n    private Boolean devlopMode = false;\n    public Set<String> getJ2cPatchClasses() {\n        return j2cPatchClasses;\n    }\n\n    public void setJ2cPatchClasses(Set<String> j2cPatchClasses) {\n        this.j2cPatchClasses = j2cPatchClasses;\n    }\n\n\n\n    public boolean isDiffBundleSo() {\n        return diffBundleSo;\n    }\n\n    public void setDiffBundleSo(boolean diffBundleSo) {\n        this.diffBundleSo = diffBundleSo;\n    }\n\n    private boolean diffBundleSo = false;\n\n    private boolean onlyIncrementInMain = true;\n\n    private boolean onlyIncrementInAwb = true;\n\n    private boolean containMainBundleRes = true;\n\n    private String tpatchMainBundleName = \"libcom_taobao_maindex\";\n\n    private String apatchMainBundleName = \"com_taobao_maindex\";\n\n    private String tpatchHistoryUrl = \"/rpc/dynamicBundle/getAllPatchInfo.json\";\n\n    public String getLastPatchUrl() {\n        if (StringUtils.isEmpty(AtlasBuildContext.sBuilderAdapter.tpatchHistoryUrl)) {\n            return \"\";\n        }\n        return \"http://\" + AtlasBuildContext.sBuilderAdapter.tpatchHistoryUrl + LastPatchUrl;\n    }\n\n    public void setLastPatchUrl(String lastPatchUrl) {\n        LastPatchUrl = lastPatchUrl;\n    }\n\n    private String LastPatchUrl = \"/rpc/dynamicBundle/getLastPatch.json?\";\n\n    private Boolean onlyBuildModifyAwb = false;\n\n    private String noPatchBundles = \"\";\n\n    private String buildId = \"\";\n\n    private boolean tpatchWriteBuildInfo = true;\n\n    private boolean fullResValues;\n\n    private List<String> patchVersions = new ArrayList<>();\n\n    public PatchConfig(String name) {\n        this.name = name;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public boolean isCreateIPatch() {\n        return createIPatch;\n    }\n\n    public void setCreateIPatch(boolean createIPatch) {\n        this.createIPatch = createIPatch;\n    }\n\n    public boolean isCreateTPatch() {\n        return createTPatch;\n    }\n\n    public void setCreateTPatch(boolean createTPatch) {\n        this.createTPatch = createTPatch;\n    }\n\n    public boolean isOnlyIncrementInMain() {\n        return onlyIncrementInMain;\n    }\n\n    public void setOnlyIncrementInMain(boolean onlyIncrementInMain) {\n        this.onlyIncrementInMain = onlyIncrementInMain;\n    }\n\n    public boolean isOnlyIncrementInAwb() {\n        return onlyIncrementInAwb;\n    }\n\n    public void setOnlyIncrementInAwb(boolean onlyIncrementInAwb) {\n        this.onlyIncrementInAwb = onlyIncrementInAwb;\n    }\n\n    public boolean isContainMainBundleRes() {\n        return containMainBundleRes;\n    }\n\n    public void setContainMainBundleRes(boolean containMainBundleRes) {\n        this.containMainBundleRes = containMainBundleRes;\n    }\n\n    public String getTpatchMainBundleName() {\n        return tpatchMainBundleName;\n    }\n\n    public void setTpatchMainBundleName(String tpatchMainBundleName) {\n        this.tpatchMainBundleName = tpatchMainBundleName;\n    }\n\n    public String getApatchMainBundleName() {\n        return apatchMainBundleName;\n    }\n\n    public void setApatchMainBundleName(String apatchMainBundleName) {\n        this.apatchMainBundleName = apatchMainBundleName;\n    }\n\n    public Set<String> gettPatchNotIncludeFiles() {\n        return tPatchNotIncludeFiles;\n    }\n\n    public void settPatchNotIncludeFiles(Set<String> tPatchNotIncludeFiles) {\n        this.tPatchNotIncludeFiles = tPatchNotIncludeFiles;\n    }\n\n    public File getFilterFile() {\n        return filterFile;\n    }\n\n    public void setFilterFile(File filterFile) {\n        this.filterFile = filterFile;\n    }\n\n    public Set<String> getFilterClasses() {\n        return filterClasses;\n    }\n\n    public void setFilterClasses(Set<String> filterClasses) {\n        this.filterClasses = filterClasses;\n    }\n\n    public boolean isApForBaseFile() {\n        return apForBaseFile;\n    }\n\n    public void setApForBaseFile(boolean apForBaseFile) {\n        this.apForBaseFile = apForBaseFile;\n    }\n\n    public File getApExploredFolder() {\n        return apExploredFolder;\n    }\n\n    public void setApExploredFolder(File apExploredFolder) {\n        this.apExploredFolder = apExploredFolder;\n    }\n\n    public File getFinalBasePatchFile() {\n        return finalBasePatchFile;\n    }\n\n    public void setFinalBasePatchFile(File finalBasePatchFile) {\n        this.finalBasePatchFile = finalBasePatchFile;\n    }\n\n    public Boolean getDevlopMode() {\n        return devlopMode;\n    }\n\n    public void setDevlopMode(Boolean devlopMode) {\n        this.devlopMode = devlopMode;\n    }\n\n    public Boolean getOnlyBuildModifyAwb() {\n        return onlyBuildModifyAwb;\n    }\n\n    public void setOnlyBuildModifyAwb(Boolean onlyBuildModifyAwb) {\n        this.onlyBuildModifyAwb = onlyBuildModifyAwb;\n    }\n\n    public String getNoPatchBundles() {\n        return noPatchBundles;\n    }\n\n    public void setNoPatchBundles(String noPatchBundles) {\n        this.noPatchBundles = noPatchBundles;\n    }\n\n    public String getBuildId() {\n        return buildId;\n    }\n\n    public void setBuildId(String buildId) {\n        this.buildId = buildId;\n    }\n\n    public boolean isTpatchWriteBuildInfo() {\n        return tpatchWriteBuildInfo;\n    }\n\n    public void setTpatchWriteBuildInfo(boolean tpatchWriteBuildInfo) {\n        this.tpatchWriteBuildInfo = tpatchWriteBuildInfo;\n    }\n\n    /**\n     * Whether to play the historical patch, Can be achieved by -DdexPatchEnabled=true To turn on\n     *\n     * @return\n     */\n    public String getTpatchHistoryUrl() {\n\n        if (StringUtils.isEmpty(AtlasBuildContext.sBuilderAdapter.tpatchHistoryUrl)) {\n            return \"\";\n        }\n        return \"http://\" + AtlasBuildContext.sBuilderAdapter.tpatchHistoryUrl + tpatchHistoryUrl;\n    }\n\n    public void setTpatchHistoryUrl(String tpatchHistoryUrl) {\n        this.tpatchHistoryUrl = tpatchHistoryUrl;\n    }\n\n    public String getAppSignName() {\n        return appSignName;\n    }\n\n    public void setAppSignName(String appSignName) {\n        this.appSignName = appSignName;\n    }\n\n    public List<String> getPatchVersions() {\n        return patchVersions;\n    }\n\n    public void setPatchVersions(List<String> patchVersions) {\n        this.patchVersions = patchVersions;\n    }\n\n    public boolean isFullResValues() {\n        return fullResValues;\n    }\n\n    public void setFullResValues(boolean fullResValues) {\n        this.fullResValues = fullResValues;\n    }\n\n    public Set<String> getPatchClasses() {\n        return patchClasses;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/TBuildConfig.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.extension;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\nimport com.google.common.collect.Sets;\nimport com.taobao.android.builder.extension.annotation.Config;\n\n/**\n * Created by shenghua.nish on 2016-05-17 At 10:15.\n */\npublic class TBuildConfig {\n\n    @Config(message = \"Remote bundle list, artifactId\", advance = false, order = 1, group = \"atlas\")\n    private Set<String> outOfApkBundles = Sets.newHashSet();\n\n    public Set<String> getBundleToMdex() {\n        return bundleToMdex;\n    }\n\n    public void setBundleToMdex(Set<String> bundleToMdex) {\n        this.bundleToMdex = bundleToMdex;\n    }\n\n    private Set<String>bundleToMdex = Sets.newHashSet();\n\n\n    public Boolean getAllBundlesToMdex() {\n        return allBundlesToMdex;\n    }\n\n    public void setAllBundlesToMdex(Boolean allBundlesToMdex) {\n        this.allBundlesToMdex = allBundlesToMdex;\n    }\n\n    private Boolean allBundlesToMdex = false;\n\n    public Boolean getConsumerProguardEnabled() {\n        return consumerProguardEnabled;\n    }\n\n    public void setConsumerProguardEnabled(Boolean consumerProguardEnabled) {\n        this.consumerProguardEnabled = consumerProguardEnabled;\n    }\n\n    private Boolean consumerProguardEnabled = false;\n\n    public Boolean getMergeBundlesDex() {\n        return mergeBundlesDex;\n    }\n\n    public void setMergeBundlesDex(Boolean mergeBundlesDex) {\n        this.mergeBundlesDex = mergeBundlesDex;\n    }\n\n    private Boolean mergeBundlesDex = false;\n\n    public Boolean getScanDupRes() {\n        return scanDupRes;\n    }\n\n    public void setScanDupRes(Boolean scanDupRes) {\n        this.scanDupRes = scanDupRes;\n    }\n\n    private Boolean scanDupRes = false;\n\n    public String getAppCoordinate() {\n        return appCoordinate;\n    }\n\n    public void setAppCoordinate(String appCoordinate) {\n        this.appCoordinate = appCoordinate;\n    }\n\n    @Config(message = \"appCoordinate groupId:artifactId\", advance = false, order = 1, group = \"atlas\")\n    private String appCoordinate = \"\";\n\n    public String getGroup() {\n        return group;\n    }\n\n    public void setGroup(String group) {\n        this.group = group;\n    }\n\n    @Config(message = \"group\", advance = false, order = 1, group = \"atlas\")\n\n    private String group = \"\";\n\n\n    @Config(title = \"Self-initiated bundle list\", message = \"The value is packageName\", order = 1, advance = false, group = \"atlas\")\n    private List<String> autoStartBundles = new ArrayList<String>();\n\n\n    @Config(title = \"Pre-launch list\",\n        message = \"To implement the PreLaunch class, multiple classes are used , No separate\", order = 1, advance = false, group = \"atlas\")\n    private String preLaunch = \"\";\n\n    @Config(title = \"atlas The subcontract\",\n        message = \"atlasThe primary dex subcontracting mechanism, the first dex to set up only the startup code corresponding to atlas\", order = 3, advance = false, group = \"atlas\")\n    private boolean atlasMultiDex = false;\n\n\n    public boolean isUpdateSdkVersion() {\n        return updateSdkVersion;\n    }\n\n    public void setUpdateSdkVersion(boolean updateSdkVersion) {\n        this.updateSdkVersion = updateSdkVersion;\n    }\n\n    private boolean updateSdkVersion = true;\n\n    @Config(message = \"List of so files to delete\", order = 4, advance = true, group = \"atlas\")\n    private Set<String> removeSoFiles = Sets.newHashSet();\n\n    @Config(title = \"bundleThe packageId definition file\", message = \"bundlePackageId defines files that are not defined automatically\", group = \"atlas\")\n    private File packageIdFile = new File(\"\");\n\n\n    public File getAwbConfigFile() {\n        return awbConfigFile;\n    }\n\n    public void setAwbConfigFile(File awbConfigFile) {\n        this.awbConfigFile = awbConfigFile;\n    }\n\n    private File awbConfigFile = new File(\"\");\n\n    @Config(message = \"Automatically generate the bundle's packageId\", order = 6, advance = false, group = \"atlas\")\n    private boolean autoPackageId = true;\n\n    @Config(message = \"Automatic allocation of packageId The minimum value\", order = 6, advance = false, group = \"atlas\")\n    private int minPackageId = 35;\n\n    @Config(title = \"Build base pack\", message = \"Build the baseline package, and the suggestion is open, otherwise the patch package will not be able to proceed\", order = 0, group = \"atlas_patch\")\n    private Boolean createAP = true;\n\n    @Config(message = \"Merge the bundle jarResource file\", order = 8, advance = true, group = \"atlas\")\n    private Boolean mergeAwbJavaRes = false;\n\n    @Config(message = \"Whether to rely on conflict to terminate packaging\", order = 0, group = \"check\")\n    private boolean abortIfDependencyConflict = false;\n\n    @Config(message = \"Whether class conflicts terminate packaging\", order = 0, group = \"check\")\n    private boolean abortIfClassConflict = false;\n\n    @Config(title = \"Pretreatment of the manifest\", message = \"If atlas is turned on, it must be true\", order = 7, advance = true, group = \"atlas\")\n    private Boolean preProcessManifest = true;\n\n    @Config(title = \"Use a custom aapt\", message = \"If atlas is turned on, it must be true\", order = 8, advance = true, group = \"atlas\")\n    private Boolean useCustomAapt = true;\n\n    @Config(title = \"aaptThe output R is constant\", message = \"The recommended value is set to false, You can reduce the amount of patch packages that are dynamically deployed\", order = 9, advance = true,\n        group = \"atlas\")\n    private Boolean aaptConstantId = true;\n\n    @Config(message = \"Inject the core bundle information\", advance = true, order = 10, group = \"atlas\")\n    private Boolean classInject = false;\n\n    @Config(title = \"The main dex in pile\", message = \"The old version of the main dex dynamic deployment, has been deprecated\", advance = true, order = 11, group = \"atlas\")\n    private Boolean doPreverify = false;\n\n    @Deprecated\n    private Boolean resV4Enabled = true;\n\n\n    public Boolean getDisabledBundleDependency() {\n        return disabledBundleDependency;\n    }\n\n    public void setDisabledBundleDependency(Boolean disabledBundleDependency) {\n        this.disabledBundleDependency = disabledBundleDependency;\n    }\n\n    private Boolean disabledBundleDependency = false;\n\n    @Config(message = \"classInjection before proguard\", advance = true, order = 12, group = \"atlas\")\n    private Boolean injectBeforeProguard = false;\n\n    @Config(title = \"Use the databinding bundle list\", message = \"You need to do a databinding bundle, A value of packageName \", order = 13,\n        advance = true, group = \"atlas\")\n    private Set<String> dataBindingBundles = new HashSet<>();\n\n    @Config(message = \"proguardDo you need to read the confusing configuration in the bundle\", order = 14, advance = true, group = \"atlas\")\n    private boolean bundleProguardConfigEnabled = true;\n\n    @Config(message = \"The confusion in dependencies reads only the keep rule\", order = 15, advance = true, group = \"atlas\")\n    private boolean libraryProguardKeepOnly = true;\n\n    @Config(title = \"proguardConfigure read dependency blacklist\", message = \"group:name,group2:name2\", order = 16, advance = true,\n        group = \"atlas\")\n    private Set<String> bundleProguardConfigBlackList = new HashSet<>();\n\n    @Deprecated\n    private Set<String> insideOfApkBundles = Sets.newHashSet();\n\n\n    public Set<String> getInjectExcludePkgs() {\n        return injectExcludePkgs;\n    }\n\n    public void setInjectExcludePkgs(Set<String> injectExcludePkgs) {\n        this.injectExcludePkgs = injectExcludePkgs;\n    }\n\n    private Set<String>injectExcludePkgs = new HashSet<>();\n\n\n    public Set<String> getInjectPkgs() {\n        return injectPkgs;\n    }\n\n    public void setInjectPkgs(Set<String> injectPkgs) {\n        this.injectPkgs = injectPkgs;\n    }\n\n    private Set<String>injectPkgs = new HashSet<>();\n\n\n    public Set<String> getOutOfApkNativeSos() {\n        return outOfApkNativeSos;\n    }\n\n    public void setOutOfApkNativeSos(Set<String> outOfApkNativeSos) {\n        this.outOfApkNativeSos = outOfApkNativeSos;\n    }\n\n    private Set<String>outOfApkNativeSos = Sets.newHashSet();\n\n    private boolean incremental = false;\n\n\n    public boolean isInjectSerialVersionUID() {\n        return injectSerialVersionUID;\n    }\n\n    public void setInjectSerialVersionUID(boolean injectSerialVersionUID) {\n        this.injectSerialVersionUID = injectSerialVersionUID;\n    }\n\n    private boolean injectSerialVersionUID = false;\n\n    @Config(message = \"Whether to use fast proguard\", order = 16, advance = true, group = \"atlas\")\n    private boolean fastProguard = false;\n\n    private boolean keepJavaResAfterProguard = false;\n\n    @Config(message = \"Whether to use the proguard cache\", order = 17, advance = true, group = \"atlas\")\n    private boolean proguardCacheEnabled = true;\n\n    @Config(message = \"Whether to use the remote proguard cache\", order = 16, advance = true, group = \"atlas\")\n    private boolean proguardNetworkCacheEnabled = false;\n\n    @Config(message = \"Whether to use the dex cache\", order = 17, advance = true, group = \"atlas\")\n    private boolean dexCacheEnabled = true;\n\n    @Config(message = \"Whether to use the remote dex cache\", order = 18, advance = true, group = \"atlas\")\n    private boolean dexNetworkCacheEnabled = false;\n\n    private int proguardParallelCount = 8;\n\n    @Config(message = \"put awb so in assets, not  lib/armeabi dir\", order = 19, advance = true, group = \"atlas\")\n    private Set<String> keepInAssetsSoNames = new HashSet<>();\n\n    @Config(message = \"put awb so in lib/armeabi , not assets dir\", order = 19, advance = true, group = \"atlas\")\n    private Set<String> keepInLibSoNames = new HashSet<>();\n\n\n    public Set<String> getRemoveSoFiles() {\n        return removeSoFiles;\n    }\n\n    public void setRemoveSoFiles(Set<String> removeSoFiles) {\n        this.removeSoFiles = removeSoFiles;\n    }\n\n    public File getPackageIdFile() {\n        return packageIdFile;\n    }\n\n    public void setPackageIdFile(File packageIdFile) {\n        this.packageIdFile = packageIdFile;\n    }\n\n    public boolean isAutoPackageId() {\n        return autoPackageId;\n    }\n\n    public void setAutoPackageId(boolean autoPackageId) {\n        this.autoPackageId = autoPackageId;\n    }\n\n    public Boolean getPreProcessManifest() {\n        return preProcessManifest;\n    }\n\n    public void setPreProcessManifest(Boolean preProcessManifest) {\n        this.preProcessManifest = preProcessManifest;\n    }\n\n    public Boolean getUseCustomAapt() {\n        return useCustomAapt;\n    }\n\n    public void setUseCustomAapt(Boolean useCustomAapt) {\n        this.useCustomAapt = useCustomAapt;\n    }\n\n    public Boolean getAaptConstantId() {\n        return aaptConstantId;\n    }\n\n    public void setAaptConstantId(Boolean aaptConstantId) {\n        this.aaptConstantId = aaptConstantId;\n    }\n\n    public Boolean getClassInject() {\n        return classInject;\n    }\n\n    public void setClassInject(Boolean classInject) {\n        this.classInject = classInject;\n    }\n\n    public Boolean getInjectBeforeProguard() {\n        return injectBeforeProguard;\n    }\n\n    public void setInjectBeforeProguard(Boolean injectBeforeProguard) {\n        this.injectBeforeProguard = injectBeforeProguard;\n    }\n\n    public Boolean getCreateAP() {\n        return createAP;\n    }\n\n    public Boolean getMergeAwbJavaRes() {\n        return mergeAwbJavaRes;\n    }\n\n    public void setMergeAwbJavaRes(Boolean mergeAwbJavaRes) {\n        this.mergeAwbJavaRes = mergeAwbJavaRes;\n    }\n\n    public Set<String> getOutOfApkBundles() {\n\n        return outOfApkBundles;\n    }\n\n    public void setOutOfApkBundles(Set<String> outOfApkBundles) {\n        this.outOfApkBundles = outOfApkBundles;\n    }\n\n    public Set<String> getInsideOfApkBundles() {\n        return insideOfApkBundles;\n    }\n\n    public void setInsideOfApkBundles(Set<String> insideOfApkBundles) {\n        this.insideOfApkBundles = insideOfApkBundles;\n    }\n\n    public List<String> getAutoStartBundles() {\n        return autoStartBundles;\n    }\n\n    public void setAutoStartBundles(List<String> autoStartBundles) {\n        this.autoStartBundles = autoStartBundles;\n    }\n\n    public String getPreLaunch() {\n        return preLaunch;\n    }\n\n    public void setPreLaunch(String preLaunch) {\n        this.preLaunch = preLaunch;\n    }\n\n    public Boolean getDoPreverify() {\n        return doPreverify;\n    }\n\n    public void setDoPreverify(Boolean doPreverify) {\n        this.doPreverify = doPreverify;\n    }\n\n    public Boolean getResV4Enabled() {\n        return resV4Enabled;\n    }\n\n    public void setResV4Enabled(Boolean resV4Enabled) {\n        this.resV4Enabled = resV4Enabled;\n    }\n\n    public boolean isAbortIfDependencyConflict() {\n        return abortIfDependencyConflict;\n    }\n\n    public void setAbortIfDependencyConflict(boolean abortIfDependencyConflict) {\n        this.abortIfDependencyConflict = abortIfDependencyConflict;\n    }\n\n    public boolean isAbortIfClassConflict() {\n        return abortIfClassConflict;\n    }\n\n    public void setAbortIfClassConflict(boolean abortIfClassConflict) {\n        this.abortIfClassConflict = abortIfClassConflict;\n    }\n\n    public Set<String> getDataBindingBundles() {\n        return dataBindingBundles;\n    }\n\n    public void setDataBindingBundles(Set<String> dataBindingBundles) {\n        this.dataBindingBundles = dataBindingBundles;\n    }\n\n    public boolean isAtlasMultiDex() {\n        return atlasMultiDex;\n    }\n\n    public void setAtlasMultiDex(boolean atlasMultiDex) {\n        this.atlasMultiDex = atlasMultiDex;\n    }\n\n    public Boolean isCreateAP() {\n        return createAP;\n    }\n\n    public void setCreateAP(Boolean createAP) {\n        this.createAP = createAP;\n    }\n\n    public boolean isIncremental() {\n        return incremental;\n    }\n\n    public void setIncremental(boolean incremental) {\n        this.incremental = incremental;\n    }\n\n    public boolean isBundleProguardConfigEnabled() {\n        return bundleProguardConfigEnabled;\n    }\n\n    public void setBundleProguardConfigEnabled(boolean bundleProguardConfigEnabled) {\n        this.bundleProguardConfigEnabled = bundleProguardConfigEnabled;\n    }\n\n    public boolean isLibraryProguardKeepOnly() {\n        return libraryProguardKeepOnly;\n    }\n\n    public void setLibraryProguardKeepOnly(boolean libraryProguardKeepOnly) {\n        this.libraryProguardKeepOnly = libraryProguardKeepOnly;\n    }\n\n    public Set<String> getBundleProguardConfigBlackList() {\n        return bundleProguardConfigBlackList;\n    }\n\n    public void setBundleProguardConfigBlackList(Set<String> bundleProguardConfigBlackList) {\n        this.bundleProguardConfigBlackList = bundleProguardConfigBlackList;\n    }\n\n    public int getMinPackageId() {\n        return minPackageId;\n    }\n\n    public void setMinPackageId(int minPackageId) {\n        this.minPackageId = minPackageId;\n    }\n\n    public boolean isFastProguard() {\n        return fastProguard;\n    }\n\n    public void setFastProguard(boolean fastProguard) {\n        this.fastProguard = fastProguard;\n    }\n\n    public int getProguardParallelCount() {\n        return proguardParallelCount;\n    }\n\n    public void setProguardParallelCount(int proguardParallelCount) {\n        this.proguardParallelCount = proguardParallelCount;\n    }\n\n    public boolean isProguardCacheEnabled() {\n        return proguardCacheEnabled;\n    }\n\n    public void setProguardCacheEnabled(boolean proguardCacheEnabled) {\n        this.proguardCacheEnabled = proguardCacheEnabled;\n    }\n\n    public boolean isProguardNetworkCacheEnabled() {\n        return proguardNetworkCacheEnabled;\n    }\n\n    public void setProguardNetworkCacheEnabled(boolean proguardNetworkCacheEnabled) {\n        this.proguardNetworkCacheEnabled = proguardNetworkCacheEnabled;\n    }\n\n    public boolean isDexCacheEnabled() {\n        return dexCacheEnabled;\n    }\n\n    public void setDexCacheEnabled(boolean dexCacheEnabled) {\n        this.dexCacheEnabled = dexCacheEnabled;\n    }\n\n    public boolean isDexNetworkCacheEnabled() {\n        return dexNetworkCacheEnabled;\n    }\n\n    public void setDexNetworkCacheEnabled(boolean dexNetworkCacheEnabled) {\n        this.dexNetworkCacheEnabled = dexNetworkCacheEnabled;\n    }\n\n    public Set<String> getKeepInAssetsSoNames() {\n        return keepInAssetsSoNames;\n    }\n\n    public void setKeepInAssetsSoNames(Set<String> keepInAssetsSoNames) {\n        this.keepInAssetsSoNames = keepInAssetsSoNames;\n    }\n\n    public Set<String> getKeepInLibSoNames() {\n        return keepInLibSoNames;\n    }\n\n    public void setKeepInLibSoNames(Set<String> keepInLibSoNames) {\n        this.keepInLibSoNames = keepInLibSoNames;\n    }\n\n    public boolean isKeepJavaResAfterProguard() {\n        return keepJavaResAfterProguard;\n    }\n\n    public void setKeepJavaResAfterProguard(boolean keepJavaResAfterProguard) {\n        this.keepJavaResAfterProguard = keepJavaResAfterProguard;\n    }\n\n    public void setPushInstall(boolean pushInstall) {\n        this.pushInstall = pushInstall;\n    }\n\n    private boolean pushInstall;\n    public boolean isPushInstall() {\n        return pushInstall;\n    }\n\n    public boolean isPatchConstructors() {\n        return patchConstructors;\n    }\n\n    public void setPatchConstructors(boolean patchConstructors) {\n        this.patchConstructors = patchConstructors;\n    }\n\n    private boolean patchConstructors = false;\n\n    public boolean isPatchEachMethod() {\n        return patchEachMethod;\n    }\n\n    public void setPatchEachMethod(boolean patchEachMethod) {\n        this.patchEachMethod = patchEachMethod;\n    }\n\n    private boolean patchEachMethod = false;\n\n\n\n    public int getPatchSuperMethodCount() {\n        return patchSuperMethodCount;\n    }\n\n    public void setPatchSuperMethodCount(int patchSuperMethodCount) {\n        this.patchSuperMethodCount = patchSuperMethodCount;\n    }\n\n    private int patchSuperMethodCount = 100;\n\n    public void setSupportAddCallSuper(boolean supportAddCallSuper) {\n        this.supportAddCallSuper = supportAddCallSuper;\n    }\n\n    private boolean supportAddCallSuper = false;\n\n\n\n    public boolean isSupportAddCallSuper() {\n        return supportAddCallSuper;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/TBuildType.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.extension;\n\nimport com.android.builder.signing.DefaultSigningConfig;\nimport com.taobao.android.builder.extension.annotation.Config;\n\nimport java.io.File;\n\n/**\n * Created by shenghua.nish on 2016-05-17 1 in the morning.\n */\npublic class TBuildType {\n\n    private String name;\n\n    private File baseApFile;\n\n    @Config(title = \"The baseline depends on the coordinates\",message = \"Such as: com.taobao.android:taobao-android-release:6.3.0-SNAPSHOT@ap \", order = 1, group = \"atlas_patch\")\n    private String baseApDependency;\n\n    public boolean isRealign() {\n        return realign;\n    }\n\n    public void setRealign(boolean realign) {\n        this.realign = realign;\n    }\n\n    private boolean realign;\n\n    public boolean isDebuggable() {\n        return debuggable;\n    }\n\n    public void setDebuggable(boolean debuggable) {\n        this.debuggable = debuggable;\n    }\n\n    private boolean debuggable;\n\n    private PatchConfig patchConfig;\n\n    private DefaultChannelConfig atlasChannelConfig;\n\n    public EnhanceConfig getEnhanceConfig() {\n        return enhanceConfig;\n    }\n\n    public void setEnhanceConfig(EnhanceConfig enhanceConfig) {\n        this.enhanceConfig = enhanceConfig;\n    }\n\n    private EnhanceConfig enhanceConfig;\n\n    public DexConfig getDexConfig() {\n        return dexConfig;\n    }\n\n    public void setDexConfig(DexConfig dexConfig) {\n        this.dexConfig = dexConfig;\n    }\n\n    private DexConfig dexConfig;\n\n    private MultiDexConfig multiDexConfig;\n\n    private DefaultSigningConfig signingConfig;\n\n    public DefaultChannelConfig getAtlasChannelConfig() {\n        return atlasChannelConfig;\n    }\n\n    public void setAtlasChannelConfig(DefaultChannelConfig atlasChannelConfig) {\n        this.atlasChannelConfig = atlasChannelConfig;\n    }\n\n\n    public TBuildType(String name) {\n        this.name = name;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public File getBaseApFile() {\n        return baseApFile;\n    }\n\n    public void setBaseApFile(File baseApFile) {\n        this.baseApFile = baseApFile;\n    }\n\n    public String getBaseApDependency() {\n        return baseApDependency;\n    }\n\n    public void setBaseApDependency(String baseApDependency) {\n        this.baseApDependency = baseApDependency;\n    }\n\n    public PatchConfig getPatchConfig() {\n        return patchConfig;\n    }\n\n    public void setPatchConfig(PatchConfig patchConfig) {\n        this.patchConfig = patchConfig;\n    }\n\n    public DefaultSigningConfig getSigningConfig() {\n        return signingConfig;\n    }\n\n    public void setSigningConfig(DefaultSigningConfig signingConfig) {\n        this.signingConfig = signingConfig;\n    }\n\n    public MultiDexConfig getMultiDexConfig() {\n        return multiDexConfig;\n    }\n\n    public void setMultiDexConfig(MultiDexConfig multiDexConfig) {\n        this.multiDexConfig = multiDexConfig;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/annotation/Config.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.extension.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Created by wuzhong on 2016/12/29.\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.FIELD)\npublic @interface Config {\n\n    public static final String ATLAS = \"atlas\";\n    public static final String CHECK = \"check\";\n    public static final String SIGN = \"sign\";\n    public static final String PROCESS = \"process\";\n    public static final String FEATURE = \"feature\";\n\n    String title() default \"\";\n\n    String message() default \"\";\n\n    int order() default 0;\n\n    boolean advance() default false;\n\n    String group() default \"base\";\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/annotation/ConfigGroup.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.extension.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Created by wuzhong on 2016/12/29.\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.FIELD)\npublic @interface ConfigGroup {\n\n    String message() default \"\";\n\n    int order() default 0;\n\n    boolean advance() default false;\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/factory/DefaultChannelConfigFactory.java",
    "content": "package com.taobao.android.builder.extension.factory;\n\nimport com.taobao.android.builder.extension.DefaultChannelConfig;\n\nimport org.gradle.api.NamedDomainObjectFactory;\nimport org.gradle.api.Project;\nimport org.gradle.api.logging.Logger;\nimport org.gradle.internal.reflect.Instantiator;\nimport com.android.annotations.NonNull;\n\n/**\n * Created by jason on 18/3/20.\n */\n\npublic class DefaultChannelConfigFactory implements NamedDomainObjectFactory<DefaultChannelConfig> {\n\n    @NonNull\n    private final Instantiator instantiator;\n    @NonNull\n    private final Project project;\n    @NonNull\n    private final Logger logger;\n\n    public DefaultChannelConfigFactory(Instantiator instantiator, Project project, Logger logger) {\n        this.instantiator = instantiator;\n        this.project = project;\n        this.logger = logger;\n    }\n\n    @Override\n    public DefaultChannelConfig create(String name) {\n        return instantiator.newInstance(DefaultChannelConfig.class, name);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/factory/DexConfigFactory.java",
    "content": "package com.taobao.android.builder.extension.factory;\n\nimport com.android.annotations.NonNull;\nimport com.taobao.android.builder.extension.DexConfig;\nimport org.gradle.api.NamedDomainObjectFactory;\nimport org.gradle.api.Project;\nimport org.gradle.api.logging.Logger;\nimport org.gradle.internal.reflect.Instantiator;\n\n/**\n * @author lilong\n * @create 2017-05-26 On the afternoon of mount zalmon\n */\n\npublic class DexConfigFactory implements NamedDomainObjectFactory<DexConfig> {\n\n    @NonNull\n    private final Instantiator instantiator;\n    @NonNull\n    private final Project project;\n\n    @NonNull\n    private final Logger logger;\n\n    public DexConfigFactory(@NonNull Instantiator instantiator, @NonNull Project project, @NonNull Logger logger) {\n        this.instantiator = instantiator;\n        this.project = project;\n        this.logger = logger;\n    }\n\n    @Override\n    public DexConfig create(String name) {\n        return instantiator.newInstance(DexConfig.class, name);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/factory/EnhanceConfigFactory.java",
    "content": "package com.taobao.android.builder.extension.factory;\n\nimport com.android.annotations.NonNull;\nimport com.taobao.android.builder.extension.EnhanceConfig;\nimport org.gradle.api.NamedDomainObjectFactory;\nimport org.gradle.api.Project;\nimport org.gradle.api.logging.Logger;\nimport org.gradle.internal.reflect.Instantiator;\n\n/**\n * EnhanceConfigFactory\n *\n * @author zhayu.ll\n\n * @date 18/5/7\n */\npublic class EnhanceConfigFactory implements NamedDomainObjectFactory<EnhanceConfig> {\n\n    @NonNull\n    private final Instantiator instantiator;\n    @NonNull\n    private final Project project;\n\n    @NonNull\n    private final Logger logger;\n\n    public EnhanceConfigFactory(@NonNull Instantiator instantiator, @NonNull Project project, @NonNull Logger logger) {\n        this.instantiator = instantiator;\n        this.project = project;\n        this.logger = logger;\n    }\n\n    @Override\n    public EnhanceConfig create(String name) {\n        return instantiator.newInstance(EnhanceConfig.class, name);\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/factory/MultiDexConfigFactory.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.extension.factory;\n\nimport com.android.annotations.NonNull;\nimport com.taobao.android.builder.extension.MultiDexConfig;\nimport org.gradle.api.NamedDomainObjectFactory;\nimport org.gradle.api.Project;\nimport org.gradle.api.logging.Logger;\nimport org.gradle.internal.reflect.Instantiator;\n\npublic class MultiDexConfigFactory implements NamedDomainObjectFactory<MultiDexConfig> {\n\n    @NonNull\n    private final Instantiator instantiator;\n    @NonNull\n    private final Project project;\n\n    @NonNull\n    private final Logger logger;\n\n    public MultiDexConfigFactory(@NonNull Instantiator instantiator, @NonNull Project project, @NonNull Logger logger) {\n        this.instantiator = instantiator;\n        this.project = project;\n        this.logger = logger;\n    }\n\n    @Override\n    public MultiDexConfig create(String name) {\n        return instantiator.newInstance(MultiDexConfig.class, name);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/factory/PatchConfigFactory.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.extension.factory;\n\nimport com.android.annotations.NonNull;\nimport com.taobao.android.builder.extension.PatchConfig;\nimport org.gradle.api.NamedDomainObjectFactory;\nimport org.gradle.api.Project;\nimport org.gradle.api.logging.Logger;\nimport org.gradle.internal.reflect.Instantiator;\n\n/**\n * Created by shenghua.nish on 2016-05-17 On the afternoon of messias.\n */\npublic class PatchConfigFactory implements NamedDomainObjectFactory<PatchConfig> {\n\n    @NonNull\n    private final Instantiator instantiator;\n    @NonNull\n    private final Project project;\n\n    @NonNull\n    private final Logger logger;\n\n    public PatchConfigFactory(@NonNull Instantiator instantiator, @NonNull Project project, @NonNull Logger logger) {\n        this.instantiator = instantiator;\n        this.project = project;\n        this.logger = logger;\n    }\n\n    @Override\n    public PatchConfig create(String name) {\n        return instantiator.newInstance(PatchConfig.class, name);\n    }\n    \n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/extension/factory/TBuildTypeFactory.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.extension.factory;\n\nimport com.android.annotations.NonNull;\nimport com.taobao.android.builder.extension.TBuildType;\nimport org.gradle.api.NamedDomainObjectFactory;\nimport org.gradle.api.Project;\nimport org.gradle.api.logging.Logger;\nimport org.gradle.internal.reflect.Instantiator;\n\n/**\n * Created by shenghua.nish on 2016-05-17 On the afternoon of 1:40.\n */\npublic class TBuildTypeFactory implements NamedDomainObjectFactory<TBuildType> {\n\n    @NonNull\n    private final Instantiator instantiator;\n    @NonNull\n    private final Project project;\n\n    @NonNull\n    private final Logger logger;\n\n    public TBuildTypeFactory(@NonNull Instantiator instantiator, @NonNull Project project, @NonNull Logger logger) {\n        this.instantiator = instantiator;\n        this.project = project;\n        this.logger = logger;\n    }\n\n    @Override\n    public TBuildType create(String name) {\n        return instantiator.newInstance(TBuildType.class, name);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/hook/AppPluginHook.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.hook;\n\nimport com.android.build.gradle.AppPlugin;\nimport com.android.build.gradle.BasePlugin;\nimport com.android.build.gradle.LibraryPlugin;\nimport com.android.builder.core.AndroidBuilder;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport org.gradle.api.Project;\n\n/**\n * Created by wuzhong on 2017/3/10.\n *\n * 1. Replace dependencyManager\n * 2. Replace androidBuilder\n *\n * @author wuzhong\n * @date 2017/03/10\n */\npublic class AppPluginHook {\n\n    private Project project;\n\n    public AppPluginHook(Project project) {\n        this.project = project;\n    }\n\n//    public void replaceTaskManager() throws Exception {\n//\n//        AppPlugin appPlugin = project.getPlugins().findPlugin(AppPlugin.class);\n//\n//        if (null == appPlugin) {\n//            return;\n//        }\n//\n//        TaskManager taskManager =\n//            (TaskManager)ReflectUtils.getField(BasePlugin.class, appPlugin, \"taskManager\");\n//\n//        DependencyManager dependencyManager = (DependencyManager)ReflectUtils.getField(TaskManager.class, taskManager,\n//                                                                                       \"dependencyManager\");\n//\n//        AtlasDependencyManager atlasDependencyManager = new AtlasDependencyManager(project,\n//                                                                                   (ExtraModelInfo)ReflectUtils\n//                                                                                       .getField(dependencyManager,\n//                                                                                                 \"extraModelInfo\"),\n//                                                                                   (SdkHandler)ReflectUtils\n//                                                                                       .getField(dependencyManager,\n//                                                                                                 \"sdkHandler\"));\n//\n//        ReflectUtils.updateField(TaskManager.class, taskManager, \"dependencyManager\", atlasDependencyManager);\n//\n//    }\n\n    public AndroidBuilder getAndroidBuilder() throws Exception {\n\n        BasePlugin basePlugin = project.getPlugins().findPlugin(AppPlugin.class);\n\n        if (null == basePlugin) {\n            basePlugin = project.getPlugins().findPlugin(LibraryPlugin.class);\n        }\n\n        if (null == basePlugin){\n            return null;\n        }\n\n        AndroidBuilder androidBuilder =\n            (AndroidBuilder)ReflectUtils.getField(BasePlugin.class, basePlugin, \"androidBuilder\");\n\n        return androidBuilder;\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/hook/dex/AtlasD8Creator.java",
    "content": "package com.taobao.android.builder.hook.dex;\n\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.android.builder.core.DexOptions;\nimport com.android.builder.core.ErrorReporter;\nimport com.android.builder.dexing.*;\nimport com.android.builder.utils.FileCache;\nimport com.android.ide.common.process.ProcessOutputHandler;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.transform.dex.AtlasDexArchiveBuilderCacheHander;\n\nimport com.taobao.android.builder.tasks.transform.dex.AtlasMainDexMerger;\nimport com.taobao.android.builder.tasks.transform.dex.AwbDexsMerger;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.FilenameUtils;\n\nimport java.io.File;\nimport java.io.FileFilter;\nimport java.io.IOException;\nimport java.net.URI;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\nimport java.nio.file.StandardCopyOption;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.concurrent.ExecutionException;\nimport java.util.function.Consumer;\nimport java.util.function.Predicate;\n\n/**\n * AtlasD8Creator\n *\n * @author zhayu.ll\n * @date 18/4/2\n */\npublic class AtlasD8Creator {\n\n    private Collection<File>inputFiles;\n\n    private File dexOut;\n\n    private boolean multidex;\n\n    private File mainDexList;\n\n    public File getMainDexOut() {\n        return mainDexOut;\n    }\n\n    public void setMainDexOut(File mainDexOut) {\n        this.mainDexOut = mainDexOut;\n    }\n\n    private File mainDexOut;\n\n    private DexOptions dexOptions;\n\n    private int miniSdk;\n\n    private ProcessOutputHandler processOutputHandler;\n\n    private FileCache fileCache;\n\n    private AtlasDexArchiveBuilderCacheHander cacheHander;\n\n    private DexArchiveBuilder dexArchiveBuilder;\n\n    private VariantContext variantContext;\n\n    private boolean isDebuggable;\n\n    private AppVariantOutputContext appVariantOutputContext;\n\n    private static final LoggerWrapper logger =\n            LoggerWrapper.getLogger(AtlasD8Creator.class);\n\n    public AtlasD8Creator(Collection<File> inputFiles, File dexOutputFile, boolean multidex, File mainDexList, DexOptions dexOptions, int minSdkVersion, FileCache fileCache, ProcessOutputHandler processOutputHandler, VariantContext variantContext, AppVariantOutputContext variantOutputContext) {\n        this.inputFiles = inputFiles;\n        this.dexOut = dexOutputFile;\n        this.multidex = multidex;\n        this.mainDexList = mainDexList;\n        this.dexOptions = dexOptions;\n        this.processOutputHandler = processOutputHandler;\n        this.fileCache = fileCache;\n        this.miniSdk = minSdkVersion;\n        this.isDebuggable = ((AppVariantContext) variantContext).getVariantData().getVariantConfiguration().getBuildType().isDebuggable();\n       this.cacheHander =\n                new AtlasDexArchiveBuilderCacheHander(variantContext.getProject(),\n                        fileCache, dexOptions, minSdkVersion, isDebuggable, DexerTool.D8);\n        this.variantContext = variantContext;\n        this.appVariantOutputContext = variantOutputContext;\n        dexArchiveBuilder = DexArchiveBuilder.createD8DexBuilder(minSdkVersion,isDebuggable);\n\n    }\n\n    public void create(AwbBundle awbBundle){\n        inputFiles.stream().parallel().forEach(file -> {\n            if (file.exists() && file.isDirectory()){\n                logger.warning(\"d8 to dex:\"+file.getAbsolutePath());\n                try (ClassFileInput input = ClassFileInputs.fromPath(file.toPath())) {\n                    dexArchiveBuilder.convert(\n                            input.entries(ClassFileInput.CLASS_MATCHER),\n                            dexOut.toPath(),\n                            false);\n                } catch (DexArchiveBuilderException ex) {\n                    throw new DexArchiveBuilderException(\"Failed to process \" + file.toPath().toString(), ex);\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n            }else {\n                logger.warning(\"d8 to dex:\"+file.getAbsolutePath());\n                File out = new File(dexOut, FilenameUtils.getBaseName(file.getName())+\".dex\");\n                try {\n                    File cacheDex = cacheHander.getCachedVersionIfPresent(file);\n                    if (cacheDex == null ||!cacheDex.exists()){\n                        try (ClassFileInput input = ClassFileInputs.fromPath(file.toPath())) {\n                            dexArchiveBuilder.convert(\n                                    input.entries(ClassFileInput.CLASS_MATCHER),\n                                    out.toPath(),\n                                    false);\n                        } catch (DexArchiveBuilderException ex) {\n                            throw new DexArchiveBuilderException(\"Failed to process \" + file.toPath().toString(), ex);\n                        }\n                        if (out.exists()){\n                            cacheHander.populateCache(file,out);\n                        }\n                    }else {\n                        logger.warning(\"hit d8 cache:\"+file.getAbsolutePath());\n                        Files.copy(\n                                cacheDex.toPath(),\n                                out.toPath(),\n                                StandardCopyOption.REPLACE_EXISTING);\n                    }\n                } catch (IOException e) {\n                    e.printStackTrace();\n                } catch (ExecutionException e) {\n                    e.printStackTrace();\n                } catch (Exception e) {\n                    e.printStackTrace();\n                }\n\n            }\n\n        });\n\n        ErrorReporter errorReporter = variantContext.getScope().getGlobalScope().getAndroidBuilder().getErrorReporter();\n        if (!awbBundle.isMainBundle()) {\n            AwbDexsMerger awbDexsMerger = new AwbDexsMerger(DexingType.MONO_DEX, null, errorReporter, DexMergerTool.D8, miniSdk, isDebuggable, appVariantOutputContext);\n            awbDexsMerger.merge(awbBundle);\n        }else {\n            AtlasMainDexMerger atlasMainDexMerger = new AtlasMainDexMerger(multidex ? DexingType.LEGACY_MULTIDEX:DexingType.MONO_DEX,variantContext.getProject().files(mainDexList),errorReporter,DexMergerTool.D8,miniSdk,isDebuggable,appVariantOutputContext);\n            List<File>dexFiles = new ArrayList();\n            File[][]mergeDexs = {new File[0]};\n            dexFiles.addAll(FileUtils.listFiles(dexOut,new String[]{\"dex\"},true));\n            mergeDexs[0] = dexOut.listFiles(new FileFilter() {\n                @Override\n                public boolean accept(File pathname) {\n                    return pathname.isDirectory()||pathname.getName().endsWith(\".dex\");\n                }\n            });\n\n            atlasMainDexMerger.merge(dexFiles,mainDexOut,mergeDexs);\n        }\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/hook/dex/AtlasDexArchiveMerger.java",
    "content": "package com.taobao.android.builder.hook.dex;\n\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.builder.dexing.*;\nimport com.android.dex.*;\nimport com.android.dx.command.dexer.DxContext;\nimport com.android.utils.ILogger;\nimport com.google.auto.value.AutoValue;\nimport com.google.common.annotations.VisibleForTesting;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Ordering;\nimport com.google.common.collect.Sets;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.*;\nimport java.util.concurrent.ForkJoinPool;\nimport java.util.concurrent.ForkJoinTask;\n\nimport static java.nio.file.Files.readAllLines;\n\n/**\n * AtlasDexArchiveMerger\n *\n * @author zhayu.ll\n * @date 18/1/5\n * @time 下午3:18\n * @description  \n */\npublic class AtlasDexArchiveMerger implements DexArchiveMerger {\n\n    private ForkJoinPool forkJoinPool = null;\n\n    private ILogger logger = LoggerWrapper.getLogger(AtlasDexArchiveMerger.class);\n\n    private DexMergingStrategy mergingStrategy = new AtlasDexMergingStrategy();\n\n\n    public AtlasDexArchiveMerger(ForkJoinPool forkJoinPool) {\n        this.forkJoinPool = forkJoinPool;\n    }\n\n    @Override\n    public void mergeDexArchives(Iterable<Path> inputs, Path outputDir, Path mainDexClasses, DexingType dexingType) throws DexArchiveMergerException {\n\n        List<Path> inputPaths = Ordering.natural().sortedCopy(inputs);\n\n        for (Path path:inputPaths){\n            logger.warning(\"input dexmerge path:\"+path.toString());\n        }\n//        Set<String> mainClasses = null;\n//        try {\n//            mainClasses = Sets.newHashSet(readAllLines(mainDexClasses));\n//        } catch (IOException e) {\n//            e.printStackTrace();\n//        }\n\n\n        Iterator<DexMergeEntry> entries =\n                null;\n        try {\n            entries = getAllEntriesFromArchives(inputPaths).iterator();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        if (!entries.hasNext()) {\n            // nothing to do\n            return;\n        }\n\n        int classesDexSuffix = 0;\n\n\n        List<ForkJoinTask<Void>> subTasks = new ArrayList<>();\n        List<String> toMergeInMain = Lists.newArrayList();\n        mergingStrategy.startNewDex();\n\n        while (entries.hasNext()) {\n            DexMergeEntry entry = entries.next();\n            Dex dex = null;\n            try {\n                dex = new Dex(entry.dexFileContent);\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n\n            if (dexingType == DexingType.LEGACY_MULTIDEX) {\n                if (entry.name.startsWith(\"fastmaindex\")) {\n                    logger.info(\"add fastmultidex.jar to first dex\");\n                    toMergeInMain.add(entry.name);\n                    mergingStrategy.tryToAddForMerging(dex);\n                    break;\n                }\n            }\n        }\n        try {\n            entries = getAllEntriesFromArchives(inputPaths).iterator();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        while (entries.hasNext()) {\n            DexMergeEntry entry = entries.next();\n            Dex dex = null;\n            if (toMergeInMain.contains(entry.name)) {\n                continue;\n            }\n            try {\n                dex = new Dex(entry.dexFileContent);\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n\n            if (!mergingStrategy.tryToAddForMerging(dex)) {\n                Path dexOutput = new File(outputDir.toFile(), getDexFileName(classesDexSuffix++)).toPath();\n                logger.warning(\"dexOutput 0 :\"+dexOutput.toString());\n\n                if (mergingStrategy.getAllDexToMerge().size() > 0) {\n                    subTasks.add(submitForMerging(mergingStrategy.getAllDexToMerge(), dexOutput));\n                }else {\n                    classesDexSuffix --;\n                }\n                mergingStrategy.startNewDex();\n\n                // adding now should succeed\n                if (!mergingStrategy.tryToAddForMerging(dex)) {\n                    if (mergingStrategy instanceof AtlasDexMergingStrategy){\n                        ((AtlasDexMergingStrategy) mergingStrategy).forceAdd(dex);\n                         dexOutput = new File(outputDir.toFile(), getDexFileName(classesDexSuffix++)).toPath();\n                        logger.warning(\"dexOutput 1:\"+dexOutput.toString());\n                        subTasks.add(submitForMerging(mergingStrategy.getAllDexToMerge(), dexOutput));\n                        mergingStrategy.startNewDex();\n\n                    }else {\n                        throw new DexArchiveMergerException(\n                                \"A single DEX file from a dex archive has more than 64K references.\");\n                    }\n                }\n            }\n        }\n\n\n        // if there are some remaining unprocessed dex files, merge them\n        if (!mergingStrategy.getAllDexToMerge().isEmpty()) {\n            Path dexOutput = new File(outputDir.toFile(), getDexFileName(classesDexSuffix)).toPath();\n            logger.warning(\"dexOutput 2:\"+dexOutput.toString());\n\n            if (mergingStrategy.getAllDexToMerge().size() > 0) {\n                subTasks.add(submitForMerging(mergingStrategy.getAllDexToMerge(), dexOutput));\n            }\n        }\n\n        // now wait for all subtasks completion.\n        subTasks.forEach(ForkJoinTask::join);\n\n    }\n\n\n    @NonNull\n    static List<DexMergeEntry> getAllEntriesFromArchives(@NonNull Collection<Path> inputs)\n            throws IOException {\n        List<DexMergeEntry> entries = Lists.newArrayList();\n        for (Path p : inputs) {\n            entries.add(new DexMergeEntry(Files.readAllBytes(p), p.toFile().getParentFile().getName()));\n        }\n        return entries;\n    }\n\n\n    @NonNull\n    private String getDexFileName(int classesDexIndex) {\n        if (classesDexIndex == 0) {\n            return SdkConstants.FN_APK_CLASSES_DEX;\n        } else {\n            return String.format(SdkConstants.FN_APK_CLASSES_N_DEX, (classesDexIndex + 1));\n        }\n    }\n\n    private ForkJoinTask<Void> submitForMerging(\n            @NonNull List<Dex> dexes, @NonNull Path dexOutputPath) {\n        return forkJoinPool.submit(new DexArchiveMergerCallable(dexes, dexOutputPath, new DxContext()));\n    }\n\n    public static class AtlasDexMergingStrategy implements DexMergingStrategy {\n\n        @VisibleForTesting\n        static final int MAX_NUMBER_OF_IDS_IN_DEX = 64000;\n\n        @NonNull\n        private final List<Dex> currentDexesToMerge = Lists.newArrayList();\n        private int currentMethodIdsUsed = 0;\n        private int currentFieldIdsUsed = 0;\n\n        @Override\n        public boolean tryToAddForMerging(@NonNull Dex dexFile) {\n            int dexMethodIds = dexFile.getTableOfContents().methodIds.size;\n            int dexFieldIds = dexFile.getTableOfContents().fieldIds.size;\n\n            if (dexMethodIds + currentMethodIdsUsed > MAX_NUMBER_OF_IDS_IN_DEX) {\n                return false;\n            }\n\n            if (dexFieldIds + currentFieldIdsUsed > MAX_NUMBER_OF_IDS_IN_DEX) {\n                return false;\n            }\n\n            currentMethodIdsUsed += dexMethodIds;\n            currentFieldIdsUsed += dexFieldIds;\n\n            currentDexesToMerge.add(dexFile);\n            return true;\n        }\n\n        public void forceAdd(Dex dex){\n            currentDexesToMerge.add(dex);\n        }\n\n        @Override\n        public void startNewDex() {\n            currentMethodIdsUsed = 0;\n            currentFieldIdsUsed = 0;\n            currentDexesToMerge.clear();\n\n        }\n\n        @NonNull\n        @Override\n        public ImmutableList<Dex> getAllDexToMerge() {\n            return ImmutableList.copyOf(currentDexesToMerge);\n        }\n    }\n\n\n    public static class AtlasDexRefMergingStrategy implements DexMergingStrategy{\n\n        static final int MAX_NUMBER_OF_IDS_IN_DEX = 64000;\n\n        @NonNull private final Set<AtlasDexRefMergingStrategy.FieldEvaluated> fieldRefs = Sets.newHashSet();\n\n        @NonNull private final Set<AtlasDexRefMergingStrategy.MethodEvaluated> methodRefs = Sets.newHashSet();\n        @NonNull private final List<Dex> currentDexes = Lists.newArrayList();\n\n        @Override\n        public boolean tryToAddForMerging(@NonNull Dex dexFile) {\n            if (tryAddFields(dexFile) && tryAddMethods(dexFile)) {\n                currentDexes.add(dexFile);\n                return true;\n            } else {\n                return false;\n            }\n        }\n\n        @Override\n        public void startNewDex() {\n            fieldRefs.clear();\n            methodRefs.clear();\n            currentDexes.clear();\n        }\n\n        @NonNull\n        @Override\n        public ImmutableList<Dex> getAllDexToMerge() {\n            return ImmutableList.copyOf(currentDexes);\n        }\n\n        private boolean tryAddFields(@NonNull Dex dexFile) {\n            List<FieldId> fieldIds = dexFile.fieldIds();\n            Set<AtlasDexRefMergingStrategy.FieldEvaluated> fieldsEvaluated = new HashSet<>(fieldIds.size());\n\n            fieldIds.forEach(f -> fieldsEvaluated.add(AtlasDexRefMergingStrategy.FieldEvaluated.create(f, dexFile)));\n\n            // find how many references are shared, and deduct from the total count\n            int shared = Sets.intersection(fieldsEvaluated, fieldRefs).size();\n\n            if (fieldRefs.size() + fieldsEvaluated.size() - shared >MAX_NUMBER_OF_IDS_IN_DEX ) {\n                return false;\n            } else {\n                fieldRefs.addAll(fieldsEvaluated);\n                return true;\n            }\n        }\n\n        private boolean tryAddMethods(@NonNull Dex dexFile) {\n            List<MethodId> methodIds = dexFile.methodIds();\n            Set<AtlasDexRefMergingStrategy.MethodEvaluated> methodsEvaluated = new HashSet<>(methodIds.size());\n            methodIds.forEach(f -> methodsEvaluated.add(AtlasDexRefMergingStrategy.MethodEvaluated.create(f, dexFile)));\n\n            // find how many references are shared, and deduct from the total count\n            int shared = Sets.intersection(methodsEvaluated, methodRefs).size();\n            if (methodRefs.size() + methodsEvaluated.size() - shared > MAX_NUMBER_OF_IDS_IN_DEX) {\n                return false;\n            } else {\n                methodRefs.addAll(methodsEvaluated);\n                return true;\n            }\n        }\n\n        @AutoValue\n        public abstract static class FieldEvaluated {\n\n            @NonNull\n            public static AtlasDexRefMergingStrategy.FieldEvaluated create(@NonNull FieldId fieldId, @NonNull Dex dex) {\n\n                    return new AutoValue_AtlasDexArchiveMerger_AtlasDexRefMergingStrategy_FieldEvaluated(\n                            dex.typeNames().get(fieldId.getDeclaringClassIndex()),\n                            dex.typeNames().get(fieldId.getTypeIndex()),\n                            dex.strings().get(fieldId.getNameIndex()));\n\n            }\n\n            @NonNull\n            public abstract String declaringClass();\n\n            @NonNull\n            public abstract String type();\n\n            @NonNull\n            public abstract String name();\n        }\n\n        @AutoValue\n        public abstract static class MethodEvaluated {\n\n            @NonNull\n            public static AtlasDexRefMergingStrategy.MethodEvaluated create(@NonNull MethodId methodId, @NonNull Dex dex) {\n                String declaringClass = dex.typeNames().get(methodId.getDeclaringClassIndex());\n                String name = dex.strings().get(methodId.getNameIndex());\n\n                ProtoId protoId = dex.protoIds().get(methodId.getProtoIndex());\n                String protoShorty = dex.strings().get(protoId.getShortyIndex());\n                String protoReturnType = dex.typeNames().get(protoId.getReturnTypeIndex());\n                String protoParameterTypes = dex.readTypeList(protoId.getParametersOffset()).toString();\n                return new AutoValue_AtlasDexArchiveMerger_AtlasDexRefMergingStrategy_MethodEvaluated(declaringClass,name,protoShorty,protoReturnType,protoParameterTypes);\n            }\n\n            @NonNull\n            public abstract String declaringClass();\n\n            @NonNull\n            public abstract String name();\n\n            @NonNull\n            public abstract String protoShorty();\n\n            @NonNull\n            public abstract String protoReturnType();\n\n            @NonNull\n            public abstract String protoParameterTypes();\n        }\n    }\n\n\n    static class DexMergeEntry {\n\n        public byte[] dexFileContent;\n\n        public String name;\n\n        public DexMergeEntry(byte[] dexFileContent, String name) {\n            this.dexFileContent = dexFileContent;\n            this.name = name;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/hook/dex/DexArchiveMergerHook.java",
    "content": "package com.taobao.android.builder.hook.dex;\n\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.builder.dexing.*;\nimport com.android.dex.Dex;\nimport com.android.dx.command.dexer.DxContext;\nimport com.google.common.base.Preconditions;\nimport com.google.common.collect.*;\n\nimport java.io.IOException;\nimport java.nio.file.FileSystems;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.PathMatcher;\nimport java.util.*;\nimport java.util.concurrent.ForkJoinPool;\nimport java.util.concurrent.ForkJoinTask;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.function.Predicate;\n\n/**\n * 创建日期：2018/12/21 on 下午1:11\n * 描述:\n * 作者:zhayu.ll\n */\npublic class DexArchiveMergerHook implements DexArchiveMerger {\n\n    @NonNull private final DxContext dxContext;\n\n    @NonNull private final DexMergingStrategy mergingStrategy;\n\n    @NonNull private final ForkJoinPool forkJoinPool;\n\n    static final PathMatcher jarMatcher =\n            FileSystems.getDefault().getPathMatcher(\"glob:**\" + SdkConstants.DOT_JAR);\n\n\n    public DexArchiveMergerHook(\n            @NonNull DxContext dxContext,\n            @NonNull DexMergingStrategy mergingStrategy,\n            @NonNull ForkJoinPool forkJoinPool) {\n        this.dxContext = dxContext;\n        this.mergingStrategy = mergingStrategy;\n        this.forkJoinPool = forkJoinPool;\n    }\n\n    @Override\n    public void mergeDexArchives(Iterable<Path> inputs, Path outputDir, Path mainDexClasses, DexingType dexingType) throws DexArchiveMergerException {\n\n        if (Iterables.isEmpty(inputs)) {\n            return;\n        }\n        // sort paths so we produce deterministic output\n        List<Path> inputPaths = Ordering.natural().sortedCopy(inputs);\n\n        try {\n            switch (dexingType) {\n                case MONO_DEX:\n                    Preconditions.checkState(\n                            mainDexClasses == null, \"Main dex list cannot be set for monodex.\");\n                    mergeMonoDex(inputPaths, outputDir);\n                    break;\n                case LEGACY_MULTIDEX:\n                    Preconditions.checkNotNull(\n                            mainDexClasses, \"Main dex list must be set for legacy multidex.\");\n                    mergeMultidex(\n                            inputPaths,\n                            outputDir,\n                            Sets.newHashSet(Files.readAllLines(mainDexClasses)),\n                            dexingType);\n                    break;\n                case NATIVE_MULTIDEX:\n                    Preconditions.checkState(\n                            mainDexClasses == null,\n                            \"Main dex list cannot be set for native multidex.\");\n                    mergeMultidex(inputPaths, outputDir, Collections.emptySet(), dexingType);\n                    break;\n                default:\n                    throw new IllegalStateException(\"Unknown dexing mode\" + dexingType);\n            }\n        } catch (IOException e) {\n            throw new DexArchiveMergerException(e);\n        }\n    }\n\n\n    private void mergeMonoDex(@NonNull Collection<Path> inputs, @NonNull Path output)\n            throws IOException {\n        Map<Path, List<Dex>> dexesFromArchives = Maps.newConcurrentMap();\n        // counts how many inputs are yet to be processed\n        AtomicInteger inputsToProcess = new AtomicInteger(inputs.size());\n        ArrayList<ForkJoinTask<Void>> subTasks = new ArrayList<>();\n        for (Path archivePath : inputs) {\n            subTasks.add(\n                    forkJoinPool.submit(\n                            () -> {\n                                try (DexArchive dexArchive = DexArchives.fromInput(archivePath)) {\n                                    List<DexArchiveEntry> entries = dexArchive.getFiles();\n                                    List<Dex> dexes = new ArrayList<>(entries.size());\n                                    for (DexArchiveEntry e : entries) {\n                                        dexes.add(new Dex(e.getDexFileContent()));\n                                    }\n\n                                    dexesFromArchives.put(dexArchive.getRootPath(), dexes);\n                                }\n\n                                if (inputsToProcess.decrementAndGet() == 0) {\n                                    mergeMonoDexEntries(output, dexesFromArchives).join();\n                                }\n                                return null;\n                            }));\n        }\n        // now wait for all subtasks execution.\n        subTasks.forEach(ForkJoinTask::join);\n    }\n\n    private ForkJoinTask<Void> mergeMonoDexEntries(\n            @NonNull Path output, @NonNull Map<Path, List<Dex>> dexesFromArchives) {\n        List<Path> sortedPaths = Ordering.natural().sortedCopy(dexesFromArchives.keySet());\n        int numberOfDexFiles = dexesFromArchives.values().stream().mapToInt(List::size).sum();\n        List<Dex> sortedDexes = new ArrayList<>(numberOfDexFiles);\n        for (Path p : sortedPaths) {\n            sortedDexes.addAll(dexesFromArchives.get(p));\n        }\n        // trigger merging with sorted set\n        return submitForMerging(sortedDexes, output.resolve(getDexFileName(0)));\n    }\n\n    /**\n     * Merges all DEX files from the dex archives into DEX file(s). It does so by using {@link\n     * DexMergingStrategy} which specifies when a DEX file should be started.\n     *\n     * <p>For {@link DexingType#LEGACY_MULTIDEX} mode, only classes specified in the main dex\n     * classes list will be packaged in the classes.dex, thus creating a minimal main DEX. Remaining\n     * DEX classes will be placed in other DEX files.\n     *\n     * @throws IOException if dex archive cannot be read, or merged DEX file(s) cannot be written\n     */\n    private void mergeMultidex(\n            @NonNull Collection<Path> inputs,\n            @NonNull Path output,\n            @NonNull Set<String> mainDexClasses,\n            @NonNull DexingType dexingType)\n            throws IOException, DexArchiveMergerException {\n        Iterator<DexArchiveEntry> entries =\n                getAllEntriesFromArchives(inputs).iterator();\n        if (!entries.hasNext()) {\n            // nothing to do\n            return;\n        }\n\n        int classesDexSuffix;\n        if (dexingType == DexingType.LEGACY_MULTIDEX) {\n            // if we are in native multidex, we should leave classes.dex for the main dex\n            classesDexSuffix = 1;\n        } else {\n            classesDexSuffix = 0;\n        }\n\n        List<ForkJoinTask<Void>> subTasks = new ArrayList<>();\n        List<Dex> toMergeInMain = Lists.newArrayList();\n        mergingStrategy.startNewDex();\n\n        boolean generate = false;\n\n        while (entries.hasNext()) {\n            DexArchiveEntry entry = entries.next();\n            Dex dex = new Dex(entry.getDexFileContent());\n            if (dexingType == DexingType.LEGACY_MULTIDEX &&!generate) {\n                // check if this should go to the main dex\n                String relativeUnixPath =\n                        DexArchiveEntry.withClassExtension(entry.getRelativePathInArchive());\n                if (mainDexClasses.contains(relativeUnixPath)) {\n                    if (!mergingStrategy.tryToAddForMerging(dex)){\n                        if (dexingType == DexingType.LEGACY_MULTIDEX) {\n                            // write the main dex file\n                            subTasks.add(submitForMerging(toMergeInMain, output.resolve(getDexFileName(0))));\n                            generate = true;\n                            mergingStrategy.startNewDex();\n                        }\n\n                    }else {\n                        toMergeInMain.add(dex);\n                        continue;\n                    }\n                }\n            }\n\n            if (!mergingStrategy.tryToAddForMerging(dex)) {\n                Path dexOutput = output.resolve(getDexFileName(classesDexSuffix++));\n                subTasks.add(submitForMerging(mergingStrategy.getAllDexToMerge(), dexOutput));\n                mergingStrategy.startNewDex();\n\n                // adding now should succeed\n                if (!mergingStrategy.tryToAddForMerging(dex)) {\n                    throw new DexArchiveMergerException(\n                            \"A single DEX file from a dex archive has more than 64K references.\");\n                }\n            }\n        }\n\n\n\n        // if there are some remaining unprocessed dex files, merge them\n        if (!mergingStrategy.getAllDexToMerge().isEmpty()) {\n            Path dexOutput = output.resolve(getDexFileName(classesDexSuffix));\n            subTasks.add(submitForMerging(mergingStrategy.getAllDexToMerge(), dexOutput));\n        }\n\n        // now wait for all subtasks completion.\n        subTasks.forEach(ForkJoinTask::join);\n    }\n\n    private ForkJoinTask<Void> submitForMerging(\n            @NonNull List<Dex> dexes, @NonNull Path dexOutputPath) {\n        return forkJoinPool.submit(new DexArchiveMergerCallable(dexes, dexOutputPath, dxContext));\n    }\n\n    @NonNull\n    private String getDexFileName(int classesDexIndex) {\n        if (classesDexIndex == 0) {\n            return SdkConstants.FN_APK_CLASSES_DEX;\n        } else {\n            return String.format(SdkConstants.FN_APK_CLASSES_N_DEX, (classesDexIndex + 1));\n        }\n    }\n\n    public static final Predicate<Path> DEX_ENTRY_FILTER =\n            f -> f.toString().endsWith(SdkConstants.DOT_DEX);\n\n\n    /**\n     * Creates a {@link com.android.builder.dexing.DexArchive} from the specified path. It supports\n     * .jar files and directories as inputs.\n     *\n     * <p>In case of a .jar file, note there are two mutually exclusive modes, write-only and\n     * read-only. In case of a write-only mode, only allowed operation is adding entries. If\n     * read-only mode is used, entires can only be read.\n     */\n    @NonNull\n    public static DexArchive fromInput(@NonNull Path path) throws IOException {\n        if (jarMatcher.matches(path)) {\n            return new NonIncrementalJarDexArchiveHook(path);\n        } else {\n            return new DirDexArchiveHook(path);\n        }\n    }\n\n    @NonNull\n    static List<DexArchiveEntry> getEntriesFromSingleArchive(@NonNull Path archivePath)\n            throws IOException {\n        try (DexArchive archive = fromInput(archivePath)) {\n            return archive.getFiles();\n        }\n    }\n\n    @NonNull\n    static List<DexArchiveEntry> getAllEntriesFromArchives(@NonNull Collection<Path> inputs)\n            throws IOException {\n        List<DexArchiveEntry> entries = Lists.newArrayList();\n        for (Path p : inputs) {\n            entries.addAll(getEntriesFromSingleArchive(p));\n        }\n        return entries;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/hook/dex/DexByteCodeConverterHook.java",
    "content": "package com.taobao.android.builder.hook.dex;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.gradle.internal.BuildCacheUtils;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.android.build.gradle.options.BooleanOption;\nimport com.android.builder.core.*;\nimport com.android.builder.dexing.*;\nimport com.android.builder.internal.compiler.DexWrapper;\nimport com.android.builder.sdk.TargetInfo;\nimport com.android.builder.utils.ExceptionRunnable;\nimport com.android.builder.utils.FileCache;\nimport com.android.builder.utils.PerformanceUtils;\nimport com.android.ide.common.blame.Message;\nimport com.android.ide.common.blame.ParsingProcessOutputHandler;\nimport com.android.ide.common.blame.parser.DexParser;\nimport com.android.ide.common.blame.parser.ToolOutputParser;\nimport com.android.ide.common.internal.WaitableExecutor;\nimport com.android.ide.common.process.*;\nimport com.android.utils.ILogger;\nimport com.android.utils.NdkUtils;\nimport com.google.common.base.Joiner;\nimport com.google.common.base.Stopwatch;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.transform.dex.AtlasDexMerger;\nimport com.taobao.android.builder.tools.FileNameUtils;\nimport com.taobao.android.builder.tools.JarUtils;\nimport com.taobao.android.builder.tools.MD5Util;\nimport com.taobao.android.builder.tools.cache.FileCacheCenter;\nimport com.taobao.android.builder.tools.cache.FileCacheException;\nimport com.taobao.android.builder.tools.multidex.FastMultiDexer;\nimport it.unimi.dsi.fastutil.Hash;\nimport org.apache.commons.compress.compressors.FileNameUtil;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.FilenameUtils;\nimport org.apache.commons.io.IOUtils;\nimport org.gradle.caching.configuration.BuildCache;\n\nimport java.io.*;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.*;\nimport java.util.concurrent.*;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.concurrent.atomic.AtomicLong;\nimport java.util.function.Consumer;\nimport java.util.function.Function;\nimport java.util.function.Predicate;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\nimport java.util.jar.JarOutputStream;\nimport java.util.regex.Pattern;\nimport java.util.stream.Collectors;\nimport java.util.zip.ZipEntry;\n\n\n/**\n * @author lilong\n * @create 2017-05-12 Morning in the afternoon\n */\n\npublic class DexByteCodeConverterHook extends DexByteCodeConverter {\n\n    private VariantContext variantContext;\n\n    private Boolean mIsDexInProcess = null;\n\n    private final TargetInfo mTargetInfo;\n\n    public static final int MAX_CLASSES = 3000;\n\n    private AppVariantOutputContext variantOutputContext;\n\n    private final JavaProcessExecutor mJavaProcessExecutor;\n\n    private List<Future> futureList = new ArrayList<>();\n\n    private static final Object LOCK_FOR_DEX = new Object();\n\n    private static final AtomicInteger DEX_PROCESS_COUNT = new AtomicInteger(4);\n\n\n    private static ExecutorService sDexExecutorService = null;\n\n    AtlasDexArchiveMerger atlasDexArchiveMerger;\n    private ILogger logger;\n\n    private String type = \"main-dex-dx-1.0\";\n\n    Collection<File> inputFile = new ArrayList<>();\n\n    Pattern pattern = Pattern.compile(\"\\\\d+.dex\");\n\n    private AtomicInteger atomicInteger = new AtomicInteger();\n\n    private Set<AwbBundle> mBundleSets = new HashSet<>();\n\n    List<Path> dexPaths = new ArrayList<>();\n\n\n    private WaitableExecutor waitableExecutor = WaitableExecutor.useGlobalSharedThreadPool();\n\n    ForkJoinPool mainforkJoinPool = null;\n    FileCache fileCache = null;\n    FileCache.Inputs.Builder globalCacheBuilder = null;\n\n    private List<Throwable> failures = new ArrayList<>();\n\n\n    public DexByteCodeConverterHook(VariantContext variantContext, AppVariantOutputContext variantOutputContext, ILogger logger, TargetInfo targetInfo, JavaProcessExecutor javaProcessExecutor, boolean verboseExec, ErrorReporter errorReporter) {\n        super(logger, targetInfo, javaProcessExecutor, verboseExec, errorReporter);\n        this.variantContext = variantContext;\n        this.variantOutputContext = variantOutputContext;\n        this.logger = logger;\n        this.mTargetInfo = targetInfo;\n        this.mJavaProcessExecutor = javaProcessExecutor;\n        if (variantContext.getScope().getGlobalScope()\n                .getProjectOptions()\n                .get(BooleanOption.ENABLE_INTERMEDIATE_ARTIFACTS_CACHE)) {\n            fileCache = variantContext.getScope().getGlobalScope().getBuildCache();\n        }\n    }\n\n\n    //    @Override\n//    public void runDexer(DexProcessBuilder builder, DexOptions dexOptions, ProcessOutputHandler processOutputHandler) throws ProcessException, IOException, InterruptedException {\n//        builder.addInputs(inputFile);\n//        super.runDexer(builder,dexOptions,processOutputHandler);\n//\n//\n//    }\n    @Override\n    public void convertByteCode(Collection<File> inputs, File outDexFolder, boolean multidex, final File mainDexList, DexOptions dexOptions, ProcessOutputHandler processOutputHandler, int minSdkVersion) throws IOException, InterruptedException, ProcessException {\n        logger.warning(\"outDexFolder:\"+outDexFolder.getAbsolutePath());\n        FileUtils.forceMkdir(outDexFolder);\n//        outDexFolder.mkdirs();\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n                variantContext.getVariantName());\n\n        if (null != atlasDependencyTree) {\n\n            ProcessOutputHandler outputHandler =\n                    new ParsingProcessOutputHandler(\n                            new ToolOutputParser(new DexParser(), Message.Kind.ERROR, LoggerWrapper.getLogger(DexByteCodeConverterHook.class)),\n                            new ToolOutputParser(new DexParser(), LoggerWrapper.getLogger(DexByteCodeConverterHook.class)),\n                            AtlasBuildContext.androidBuilderMap.get(variantContext.getProject()).getErrorReporter());\n\n\n            for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n                waitableExecutor.execute((Callable<Void>) () -> {\n                            try {\n\n                                long start = System.currentTimeMillis();\n                                //create dex\n                                File dexOutputFile = ((AppVariantContext) variantContext).getAwbDexOutput(awbBundle.getName());\n                                if (dexOutputFile.exists()) {\n                                    FileUtils.cleanDirectory(dexOutputFile);\n                                } else {\n                                    FileUtils.forceMkdir(dexOutputFile);\n                                }\n\n                                // if some of our .jar input files exist, just reset the inputDir to null\n                                AwbTransform awbTransform = variantOutputContext.getAwbTransformMap()\n                                        .get(awbBundle.getName());\n                                List<File> inputFiles = new ArrayList<File>();\n                                inputFiles.addAll(awbTransform.getInputFiles());\n                                inputFiles.addAll(awbTransform.getInputLibraries());\n                                if (null != awbTransform.getInputDirs()) {\n                                    inputFiles.addAll(awbTransform.getInputDirs());\n                                }\n\n\n                                if (variantContext.getScope().getDexer() == DexerTool.DX) {\n                                    AtlasBuildContext.androidBuilderMap.get(variantContext.getProject())\n                                            .convertByteCode(inputFiles,\n                                                    dexOutputFile,\n                                                    false,\n                                                    null,\n                                                    dexOptions,\n                                                    outputHandler, true);\n                                } else if (variantContext.getScope().getDexer() == DexerTool.D8) {\n\n\n                                    new AtlasD8Creator(inputFiles, ((AppVariantContext) variantContext).getAwbDexAchiveOutput(awbBundle), multidex, mainDexList, dexOptions, minSdkVersion, fileCache, processOutputHandler, variantContext, variantOutputContext).create(awbBundle);\n                                }\n\n                                if (awbBundle.isMBundle) {\n                                    mBundleSets.add(awbBundle);\n                                }\n\n                            } catch (Exception e) {\n                                throw new ProcessException(awbBundle.getName(), e);\n\n                            }\n                            return null;\n\n\n                        }\n                );\n            }\n        }\n\n        File tempDexFolder = null;\n\n        inputFile.addAll(AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getAllMainDexJars());\n        inputFile.addAll(AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getInputDirs());\n\n        logger.warning(\"maindex inputFile size :\" + inputFile.size());\n\n        if (variantContext.getScope().getDexer() == DexerTool.D8) {\n\n            AtlasD8Creator atlasD8Creator = new AtlasD8Creator(inputs, ((AppVariantContext) variantContext).getMainDexAchive(), multidex, mainDexList, dexOptions, minSdkVersion, fileCache, processOutputHandler, variantContext, variantOutputContext);\n            atlasD8Creator.setMainDexOut(outDexFolder);\n            atlasD8Creator.create(new AwbBundle());\n            return;\n\n        }\n\n        initDexExecutorService(dexOptions);\n\n        if (!multidex) {\n\n            if (fileCache != null && globalCacheBuilder == null) {\n                globalCacheBuilder = new FileCache.Inputs.Builder(FileCache.Command.PREDEX_LIBRARY)\n                        .putBoolean(\"multidex\", false)\n                        .putLong(\"minisdk\", minSdkVersion)\n                        .putString(\"dexoptions\", dexOptions.getAdditionalParameters().toString())\n                        .putBoolean(\"jumbomode\", dexOptions.getJumboMode())\n                        .putString(\"type\", type);\n\n                inputFile = new ArrayList<>(inputFile);\n                Collections.sort((List<File>) inputFile);\n                FileCache.Inputs inputsKey = globalCacheBuilder.putString(\"md5\", MD5Util.getFileMd5(inputFile)).build();\n\n                try {\n                    fileCache.createFile(outDexFolder, inputsKey, () -> {\n                        logger.warning(\"dex inputFile missCache: \" + inputFile.toString());\n                        outDexFolder.mkdirs();\n                        DexByteCodeConverterHook.super.convertByteCode(inputFile, outDexFolder, multidex, mainDexList, dexOptions, processOutputHandler, minSdkVersion);\n                    });\n                } catch (ExecutionException e) {\n                    e.printStackTrace();\n                    failures.add(e);\n                }\n\n            } else {\n\n                DexByteCodeConverterHook.super.convertByteCode(inputFile, outDexFolder, multidex, mainDexList, dexOptions, processOutputHandler, minSdkVersion);\n            }\n//            try {\n//                for (Future future : futureList) {\n//                    future.get();\n//                }\n//            } catch (Exception e) {\n//                throw new ProcessException(e);\n//            }\n\n        } else {\n\n            if (mainDexList != null && !mainDexList.exists()) {\n                generateMainDexList(mainDexList);\n            }\n\n            tempDexFolder = variantOutputContext.getMainDexOutDir();\n            if (tempDexFolder.exists()) {\n                FileUtils.cleanDirectory(tempDexFolder);\n            }\n\n            File finalTempDexFolder = tempDexFolder;\n            if (fileCache != null && globalCacheBuilder == null) {\n                if (mainDexList!= null) {\n                    globalCacheBuilder = new FileCache.Inputs.Builder(FileCache.Command.PREDEX_LIBRARY)\n                            .putBoolean(\"multidex\", true)\n                            .putFile(\"multidexlist\", mainDexList, FileCache.FileProperties.HASH)\n                            .putLong(\"minisdk\", minSdkVersion)\n                            .putString(\"dexoptions\", dexOptions.getAdditionalParameters().toString())\n                            .putBoolean(\"jumbomode\", dexOptions.getJumboMode())\n                            .putString(\"type\", type);\n                }else {\n                    globalCacheBuilder = new FileCache.Inputs.Builder(FileCache.Command.PREDEX_LIBRARY)\n                            .putBoolean(\"multidex\", true)\n                            .putLong(\"minisdk\", minSdkVersion)\n                            .putString(\"dexoptions\", dexOptions.getAdditionalParameters().toString())\n                            .putBoolean(\"jumbomode\", dexOptions.getJumboMode())\n                            .putString(\"type\", type);\n                }\n\n            }\n\n            if (inputFile.size() ==1 ){\n                splitFile();\n            }\n            inputFile.parallelStream().forEach(file -> {\n                File outPutFolder = new File(finalTempDexFolder, FilenameUtils.getBaseName(file.getName()));\n                if (globalCacheBuilder != null && file.isFile()) {\n                    FileCache.Inputs.Builder builder = copyOf(globalCacheBuilder);\n                    FileCache.Inputs cacheInputs = null;\n                    if (file.isFile()) {\n                        cacheInputs = builder.putFile(\"hash\", file, FileCache.FileProperties.HASH).build();\n                    } else {\n                        Collection<File> files = FileUtils.listFiles(file, new String[]{\"class\"}, true);\n                        Collections.sort((List<File>) files);\n                        cacheInputs = builder.putString(\"hash\", MD5Util.getFileMd5(files)).build();\n                    }\n                    try {\n                        fileCache.createFile(outPutFolder, cacheInputs, () -> {\n                            logger.warning(\"maindex inputFile missCache:\" + file.getAbsolutePath());\n                            outPutFolder.mkdirs();\n                            DexByteCodeConverterHook.super.convertByteCode(Arrays.asList(file), outPutFolder, true, mainDexList, dexOptions, processOutputHandler, minSdkVersion);\n                        });\n                    } catch (Exception e) {\n                        failures.add(e);\n                        e.printStackTrace();\n                    }\n\n                } else {\n                    logger.warning(\"maindex inputFile:\" + file.getAbsolutePath());\n                    outPutFolder.mkdirs();\n                    try {\n                        DexByteCodeConverterHook.super.convertByteCode(Arrays.asList(file), outPutFolder, true, mainDexList, dexOptions, processOutputHandler, minSdkVersion);\n                    } catch (Exception e) {\n                        e.printStackTrace();\n                        failures.add(e);\n                    }\n                }\n\n\n            });\n\n            if (failures.size() > 0) {\n                throw new ProcessException(failures.get(0));\n            }\n\n\n//            for (Future future : futureList) {\n//                try {\n//                    future.get();\n//                } catch (ExecutionException e) {\n//                    throw new ProcessException(e);\n//                }\n//            }\n//\n//            inputFile.stream().parallel().forEach(new Consumer<File>() {\n//                @Override\n//                public void accept(File file) {\n//                    fileCache.createFile()fileCacheMap.get(file)\n//                }\n//            });\n\n\n            Collection<File> dexFiles = FileUtils.listFiles(tempDexFolder, new String[]{\"dex\"}, true);\n            if (dexFiles != null) {\n                logger.warning(\"maindex outDexFiles size:\" + dexFiles.size());\n                dexPaths = dexFiles.stream().map(file -> file.toPath()).collect(Collectors.toList());\n            }\n            mainforkJoinPool = new ForkJoinPool();\n            atlasDexArchiveMerger = new AtlasDexArchiveMerger(mainforkJoinPool);\n            if (!variantContext.getAtlasExtension().getTBuildConfig().getMergeBundlesDex()) {\n                try {\n                    atlasDexArchiveMerger.mergeDexArchives(dexPaths, outDexFolder.toPath(), mainDexList ==null? null:mainDexList.toPath(), DexingType.LEGACY_MULTIDEX);\n                } catch (DexArchiveMergerException e) {\n                    throw new ProcessException(e);\n                }\n            }\n\n        }\n\n        waitableExecutor.waitForTasksWithQuickFail(true);\n\n        atomicInteger.set(FileUtils.listFiles(outDexFolder, new String[]{\"dex\"}, true).size());\n\n        logger.warning(\"maindex final dexs size:\" + atomicInteger.get());\n\n\n        for (AwbBundle bundle : mBundleSets) {\n            File awbDex = new File(((AppVariantContext) variantContext).getAwbDexOutput(bundle.getName()), \"classes.dex\");\n            if (awbDex.exists() && !variantContext.getAtlasExtension().getTBuildConfig().getMergeBundlesDex()) {\n                FileUtils.moveFile(awbDex, new File(outDexFolder, \"classes\" + atomicInteger.incrementAndGet() + \".dex\"));\n            } else if (awbDex.exists() && variantContext.getAtlasExtension().getTBuildConfig().getMergeBundlesDex()) {\n                dexPaths.add(awbDex.toPath());\n            } else {\n                logger.warning(awbDex.getAbsoluteFile() + \" is not exist!\");\n            }\n        }\n\n        if (variantContext.getAtlasExtension().getTBuildConfig().getMergeBundlesDex()) {\n            try {\n                atlasDexArchiveMerger.mergeDexArchives(dexPaths, outDexFolder.toPath(), null, DexingType.LEGACY_MULTIDEX);\n            } catch (DexArchiveMergerException e) {\n                e.printStackTrace();\n            } finally {\n\n            }\n        }\n\n        if (tempDexFolder != null && tempDexFolder.exists()) {\n            FileUtils.deleteDirectory(tempDexFolder);\n        }\n\n\n    }\n\n    private void splitFile() {\n        inputFile = new ArrayList<>(inputFile);\n        File file = inputFile.iterator().next();\n        inputFile.clear();\n        try {\n            JarUtils.splitMainJar((List<File>) inputFile,file,1,MAX_CLASSES);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n    }\n\n\n\n    private void generateEmptyMainDexList(File mainDexList) {\n        try {\n            mainDexList.createNewFile();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    private FileCache.Inputs.Builder copyOf(FileCache.Inputs.Builder globalCacheBuilder) {\n        FileCache.Inputs.Builder builder = new FileCache.Inputs.Builder(FileCache.Command.PREDEX_LIBRARY).putString(\"globalCacheBuilder\", globalCacheBuilder.build().toString());\n        return builder;\n    }\n\n    private void generateMainDexList(File mainDexListFile) {\n        Collection<File> inputs = AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getAllMainDexJars();\n        inputs.addAll(AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getInputDirs());\n        FastMultiDexer fastMultiDexer = (FastMultiDexer) AtlasBuildContext.androidBuilderMap.get(variantContext.getScope().getGlobalScope().getProject()).multiDexer;\n        if (fastMultiDexer == null) {\n            fastMultiDexer = new FastMultiDexer((AppVariantContext) variantContext);\n        }\n        Collection<File> files = null;\n        try {\n            files = fastMultiDexer.repackageJarList(inputs, mainDexListFile, variantContext.getScope().getVariantData().getName().toLowerCase().endsWith(\"release\"));\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        if (files != null && files.size() > 0) {\n            AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).addAllMainDexJars(files);\n\n        }\n    }\n\n    @Override\n    public void runDexer(DexProcessBuilder builder, DexOptions dexOptions, ProcessOutputHandler processOutputHandler) throws ProcessException, IOException, InterruptedException {\n        if (builder.getInputs() == null || builder.getInputs().size() == 0) {\n            return;\n        }\n\n\n        if (dexOptions.getAdditionalParameters().contains(\"--no-optimize\")) {\n            logger.warning(DefaultDexOptions.OPTIMIZE_WARNING);\n        }\n\n        if (shouldDexInProcess(dexOptions)) {\n            dexInProcess(builder, dexOptions, processOutputHandler);\n        } else {\n            dexOutOfProcess(builder, dexOptions, processOutputHandler);\n        }\n\n    }\n\n    private void initDexExecutorService(@NonNull DexOptions dexOptions) {\n        synchronized (LOCK_FOR_DEX) {\n            if (sDexExecutorService == null) {\n                if (dexOptions.getMaxProcessCount() != null) {\n                    DEX_PROCESS_COUNT.set(dexOptions.getMaxProcessCount());\n                }\n                logger.verbose(\n                        \"Allocated dexExecutorService of size %1$d.\",\n                        DEX_PROCESS_COUNT.get());\n                sDexExecutorService = Executors.newFixedThreadPool(DEX_PROCESS_COUNT.get());\n            } else {\n                // check whether our executor service has the same number of max processes as\n                // this module requests, and print a warning if necessary.\n                if (dexOptions.getMaxProcessCount() != null\n                        && dexOptions.getMaxProcessCount() != DEX_PROCESS_COUNT.get()) {\n                    logger.warning(\n                            \"dexOptions is specifying a maximum number of %1$d concurrent dx processes,\"\n                                    + \" but the Gradle daemon was initialized with %2$d.\\n\"\n                                    + \"To initialize with a different maximum value,\"\n                                    + \" first stop the Gradle daemon by calling ‘gradlew —-stop’.\",\n                            dexOptions.getMaxProcessCount(),\n                            DEX_PROCESS_COUNT.get());\n                }\n            }\n        }\n    }\n\n    public synchronized boolean shouldDexInProcess(@NonNull DexOptions dexOptions) {\n        if (mIsDexInProcess != null) {\n            return mIsDexInProcess;\n        }\n        if (!dexOptions.getDexInProcess()) {\n            mIsDexInProcess = false;\n            return false;\n        }\n\n        // Requested memory for dex.\n        Long requestedHeapSize;\n        if (dexOptions.getJavaMaxHeapSize() != null) {\n            requestedHeapSize = PerformanceUtils.parseSizeToBytes(dexOptions.getJavaMaxHeapSize());\n\n            if (requestedHeapSize == null) {\n                logger.warning(\n                        \"Unable to parse dex options size parameter '%1$s', assuming %2$s bytes.\",\n                        dexOptions.getJavaMaxHeapSize(),\n                        DEFAULT_DEX_HEAP_SIZE);\n                requestedHeapSize = DEFAULT_DEX_HEAP_SIZE;\n            }\n        } else {\n            requestedHeapSize = DEFAULT_DEX_HEAP_SIZE;\n        }\n        // Approximate heap size requested.\n        long requiredHeapSizeHeuristic = requestedHeapSize + PerformanceUtils.NON_DEX_HEAP_SIZE;\n        // Get the heap size defined by the user. This value will be compared with\n        // requiredHeapSizeHeuristic, which we suggest the user set in their gradle.properties file.\n        long maxMemory = PerformanceUtils.getUserDefinedHeapSize();\n\n        if (requiredHeapSizeHeuristic > maxMemory) {\n            String dexOptionsComment = \"\";\n            if (dexOptions.getJavaMaxHeapSize() != null) {\n                dexOptionsComment = String.format(\n                        \" (based on the dexOptions.javaMaxHeapSize = %s)\",\n                        dexOptions.getJavaMaxHeapSize());\n            }\n\n            logger.warning(\"\\nRunning dex as a separate process.\\n\\n\"\n                            + \"To run dex in process, the Gradle daemon needs a larger heap.\\n\"\n                            + \"It currently has %1$d MB.\\n\"\n                            + \"For faster builds, increase the maximum heap size for the \"\n                            + \"Gradle daemon to at least %2$s MB%3$s.\\n\"\n                            + \"To do this set org.gradle.jvmargs=-Xmx%2$sM in the \"\n                            + \"project gradle.properties.\\n\"\n                            + \"For more information see \"\n                            + \"https://docs.gradle.org/current/userguide/build_environment.html\\n\",\n                    maxMemory / (1024 * 1024),\n                    // Add -1 and + 1 to round up the division\n                    ((requiredHeapSizeHeuristic - 1) / (1024 * 1024)) + 1,\n                    dexOptionsComment);\n            mIsDexInProcess = false;\n            return false;\n        }\n        mIsDexInProcess = true;\n        return true;\n\n    }\n\n    private void dexInProcess(\n            @NonNull final DexProcessBuilder builder,\n            @NonNull final DexOptions dexOptions,\n            @NonNull final ProcessOutputHandler outputHandler)\n            throws IOException, ProcessException {\n        final String submission = Joiner.on(',').join(builder.getInputs());\n        logger.verbose(\"Dexing in-process : %1$s\", submission);\n        try {\n            //noinspection FieldAccessNotGuarded\n            sDexExecutorService\n                    .submit(\n                            () -> {\n                                Stopwatch stopwatch = Stopwatch.createStarted();\n                                ProcessResult result =\n                                        DexWrapper.run(builder, dexOptions, outputHandler);\n                                result.assertNormalExitValue();\n                                logger.verbose(\n                                        \"Dexing %1$s took %2$s.\", submission, stopwatch.toString());\n                                return null;\n                            }).get()\n            ;\n        } catch (Exception e) {\n            throw new ProcessException(new ArrayList<>(builder.getInputs()).toString(),e);\n        }\n    }\n\n    private void dexOutOfProcess(\n            @NonNull final DexProcessBuilder builder,\n            @NonNull final DexOptions dexOptions,\n            @NonNull final ProcessOutputHandler processOutputHandler)\n            throws ProcessException, InterruptedException {\n        final String submission = Joiner.on(',').join(builder.getInputs());\n        logger.verbose(\"Dexing out-of-process : %1$s\", submission);\n        try {\n            Callable<Void> task = () -> {\n                JavaProcessInfo javaProcessInfo =\n                        builder.build(mTargetInfo.getBuildTools(), dexOptions);\n                ProcessResult result =\n                        mJavaProcessExecutor.execute(javaProcessInfo, processOutputHandler);\n                result.rethrowFailure().assertNormalExitValue();\n                return null;\n            };\n\n            // this is a hack, we always spawn a new process for dependencies.jar so it does\n            // get built in parallel with the slices, this is only valid for InstantRun mode.\n            if (submission.contains(\"dependencies.jar\")) {\n                task.call();\n            } else {\n                //noinspection FieldAccessNotGuarded\n                sDexExecutorService.submit(task).get();\n            }\n        } catch (Exception e) {\n            if (builder.getMinSdkVersion() >= 24\n                    && !DexProcessBuilder.isMinSdkVersionSupported(mTargetInfo.getBuildTools())) {\n                logger.warning(\n                        \"If you are unable to fix the underlying cause of error, dx \"\n                                + \"might have failed because default or static interface methods \"\n                                + \"(requiring minimum sdk version 24), or signature-polymorphic \"\n                                + \"methods (requiring minimum sdk version 26) are used.\\n\"\n                                + \"Please switch to dexing in process or update the build tools to \"\n                                + \"%s.\",\n                        AndroidBuilder.DEFAULT_BUILD_TOOLS_REVISION.toString());\n            }\n            throw new ProcessException(e);\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/hook/dex/DexWrapperHook.java",
    "content": "package com.taobao.android.builder.hook.dex;\n\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.builder.core.DexOptions;\nimport com.android.builder.core.DexProcessBuilder;\nimport com.android.ide.common.process.ProcessException;\nimport com.android.ide.common.process.ProcessOutput;\nimport com.android.ide.common.process.ProcessOutputHandler;\nimport com.android.ide.common.process.ProcessResult;\nimport com.google.common.collect.Iterables;\nimport com.taobao.android.dx.command.DxConsole;\nimport com.taobao.android.dx.command.dexer.Main;\n\nimport java.io.File;\nimport java.io.IOException;\n\n/**\n * @author lilong\n * @create 2017-05-12 At 8:01\n */\n\npublic class DexWrapperHook {\n\n    public static ProcessResult run(\n            @NonNull DexProcessBuilder processBuilder,\n            @NonNull DexOptions dexOptions,\n            @NonNull ProcessOutputHandler outputHandler) throws IOException, ProcessException {\n        ProcessOutput output = outputHandler.createOutput();\n        int res;\n        try {\n//            DxConsole.out = outputHandler.createOutput().getStandardOutput();\n//            DxConsole.err = outputHandler.createOutput().getErrorOutput();\n            DxConsole dxConsole = new DxConsole();\n            Main.Arguments args = buildArguments(processBuilder, dexOptions, dxConsole);\n            res = new Main().run(args);\n        } finally {\n            output.close();\n        }\n\n        outputHandler.handleOutput(output);\n        return new DexProcessResult(res);\n    }\n\n    @NonNull\n    private static Main.Arguments buildArguments(\n            @NonNull DexProcessBuilder processBuilder,\n            @NonNull DexOptions dexOptions,\n            @NonNull DxConsole dxConsole)\n            throws ProcessException {\n        Main.Arguments args = new Main.Arguments();\n\n        // Inputs:\n        args.fileNames = Iterables.toArray(processBuilder.getFilesToAdd(), String.class);\n\n        // Outputs:\n        if (processBuilder.getOutputFile().isDirectory() && !processBuilder.isMultiDex()) {\n            args.outName = new File(processBuilder.getOutputFile(), \"classes.dex\").getPath();\n            args.jarOutput = false;\n        } else {\n            String outputFileAbsolutePath = processBuilder.getOutputFile().getAbsolutePath();\n            args.outName = outputFileAbsolutePath;\n            args.jarOutput = outputFileAbsolutePath.endsWith(SdkConstants.DOT_JAR);\n        }\n\n        // Multi-dex:\n        args.multiDex = processBuilder.isMultiDex();\n        if (processBuilder.getMainDexList() != null) {\n            args.mainDexListFile = processBuilder.getMainDexList().getPath();\n        }\n\n        // Other:\n        args.verbose = processBuilder.isVerbose();\n        // due to b.android.com/82031\n//        args.optimize = true;\n        args.numThreads = 1;\n        args.forceJumbo = dexOptions.getJumboMode();\n        if (dexOptions.getAdditionalParameters().contains(\"--debug\")) {\n            args.debug = true;\n        } else if (dexOptions.getAdditionalParameters().contains(\"--verbose\")) {\n            args.verbose = true;\n        } else if (dexOptions.getAdditionalParameters().contains(\"--verbose-dump\")) {\n            args.verboseDump = true;\n        } else if (dexOptions.getAdditionalParameters().contains(\"--no-files\")) {\n            args.emptyOk = true;\n        } else if (dexOptions.getAdditionalParameters().contains(\"--no-optimize\")) {\n            args.optimize = false;\n        } else if (dexOptions.getAdditionalParameters().contains(\"--no-strict\")) {\n            args.strictNameCheck = false;\n        } else if (dexOptions.getAdditionalParameters().contains(\"--core-library\")) {\n            args.coreLibrary = true;\n        } else if (dexOptions.getAdditionalParameters().contains(\"--statistics\")) {\n            args.statistics = true;\n        }\n//        args.parseFlags(Iterables.toArray(dexOptions.getAdditionalParameters(), String.class));\n//        args.makeOptionsObjects();\n\n        return args;\n    }\n\n    private static class DexProcessResult implements ProcessResult {\n\n        private int mExitValue;\n\n        DexProcessResult(int exitValue) {\n            mExitValue = exitValue;\n        }\n\n        @NonNull\n        @Override\n        public ProcessResult assertNormalExitValue()\n                throws ProcessException {\n            if (mExitValue != 0) {\n                throw new ProcessException(\n                        String.format(\"Return code %d for dex process\", mExitValue));\n            }\n\n            return this;\n        }\n\n        @Override\n        public int getExitValue() {\n            return mExitValue;\n        }\n\n        @NonNull\n        @Override\n        public ProcessResult rethrowFailure()\n                throws ProcessException {\n            return assertNormalExitValue();\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/hook/dex/DirDexArchiveHook.java",
    "content": "package com.taobao.android.builder.hook.dex;\n\nimport com.android.annotations.NonNull;\nimport com.android.builder.dexing.DexArchive;\nimport com.android.builder.dexing.DexArchiveEntry;\nimport com.android.builder.dexing.DexArchives;\nimport com.android.utils.FileUtils;\nimport com.android.utils.PathUtils;\nimport com.google.common.collect.ImmutableList;\n\nimport java.io.BufferedOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.Iterator;\nimport java.util.List;\n\n/**\n * 创建日期：2018/12/21 on 下午1:25\n * 描述:\n * 作者:zhayu.ll\n */\npublic class DirDexArchiveHook implements DexArchive {\n\n    @NonNull\n    private final Path rootDir;\n\n    public DirDexArchiveHook(@NonNull Path rootDir) {\n        this.rootDir = rootDir;\n    }\n\n    @NonNull\n    @Override\n    public Path getRootPath() {\n        return rootDir;\n    }\n\n    @Override\n    public void addFile(@NonNull String relativePath, byte[] bytes, int offset, int end)\n            throws IOException {\n        Path finalPath = rootDir.resolve(relativePath);\n        Files.createDirectories(finalPath.getParent());\n        try (OutputStream os = new BufferedOutputStream(Files.newOutputStream(finalPath))) {\n            os.write(bytes, offset, end);\n            os.flush();\n        }\n    }\n\n    @Override\n    public void removeFile(@NonNull String relativePath) throws IOException {\n        Path finalPath = rootDir.resolve(relativePath);\n        if (Files.isDirectory(finalPath)) {\n            FileUtils.deleteDirectoryContents(finalPath.toFile());\n        }\n        Files.deleteIfExists(finalPath);\n    }\n\n    @Override\n    @NonNull\n    public List<DexArchiveEntry> getFiles() throws IOException {\n        ImmutableList.Builder<DexArchiveEntry> builder = ImmutableList.builder();\n\n        Iterator<Path> files =\n                Files.walk(getRootPath()).filter(DexArchives.DEX_ENTRY_FILTER).iterator();\n\n        while (files.hasNext()) {\n            builder.add(createEntry(files.next()));\n        }\n\n        return builder.build();\n    }\n\n    @Override\n    public void close() throws IOException {\n        // do nothing\n    }\n\n    private DexArchiveEntry createEntry(@NonNull Path dexFile) throws IOException {\n        byte[] content = Files.readAllBytes(dexFile);\n        Path relativePath = getRootPath().relativize(dexFile);\n\n        return new DexArchiveEntry(content, PathUtils.toSystemIndependentPath(relativePath));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/hook/dex/NonIncrementalJarDexArchiveHook.java",
    "content": "package com.taobao.android.builder.hook.dex;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.builder.dexing.DexArchive;\nimport com.android.builder.dexing.DexArchiveEntry;\nimport com.google.common.base.Preconditions;\nimport com.google.common.io.ByteStreams;\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.StandardOpenOption;\nimport java.nio.file.attribute.FileTime;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.List;\nimport java.util.jar.JarOutputStream;\nimport java.util.zip.CRC32;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n/**\n * 创建日期：2018/12/21 on 下午1:24\n * 描述:\n * 作者:zhayu.ll\n */\npublic class NonIncrementalJarDexArchiveHook  implements DexArchive {\n\n\n    private static final FileTime ZERO_TIME = FileTime.fromMillis(0);\n\n    private final Path targetPath;\n    @Nullable\n    private JarOutputStream jarOutputStream;\n    @Nullable private ZipFile readOnlyZipFile;\n\n    public NonIncrementalJarDexArchiveHook(Path targetPath) throws IOException {\n        this.targetPath = targetPath;\n        if (Files.isRegularFile(targetPath)) {\n            // we should read this file\n            this.readOnlyZipFile = new ZipFile(targetPath.toFile());\n        } else {\n            // we are creating this file\n            this.jarOutputStream =\n                    new JarOutputStream(\n                            new BufferedOutputStream(\n                                    Files.newOutputStream(\n                                            targetPath,\n                                            StandardOpenOption.WRITE,\n                                            StandardOpenOption.CREATE_NEW)));\n        }\n    }\n\n    @NonNull\n    @Override\n    public Path getRootPath() {\n        return targetPath;\n    }\n\n    @Override\n    public void addFile(@NonNull String relativePath, byte[] bytes, int offset, int end)\n            throws IOException {\n        Preconditions.checkNotNull(jarOutputStream, \"Archive is not writeable : %s\", targetPath);\n        // Need to pre-compute checksum for STORED (uncompressed) entries)\n        CRC32 checksum = new CRC32();\n        checksum.update(bytes, offset, end);\n\n        ZipEntry zipEntry = new ZipEntry(relativePath);\n        zipEntry.setLastModifiedTime(ZERO_TIME);\n        zipEntry.setLastAccessTime(ZERO_TIME);\n        zipEntry.setCreationTime(ZERO_TIME);\n        zipEntry.setCrc(checksum.getValue());\n        zipEntry.setSize(end - offset);\n        zipEntry.setCompressedSize(end - offset);\n        zipEntry.setMethod(ZipEntry.STORED);\n\n        jarOutputStream.putNextEntry(zipEntry);\n        jarOutputStream.write(bytes, offset, end);\n        jarOutputStream.flush();\n        jarOutputStream.closeEntry();\n    }\n\n    @Override\n    public void removeFile(@NonNull String relativePath) throws IOException {\n        throw new UnsupportedOperationException(\"Not implemented\");\n    }\n\n    @NonNull\n    @Override\n    public List<DexArchiveEntry> getFiles() throws IOException {\n        Preconditions.checkNotNull(readOnlyZipFile, \"Archive is not readable : %s\", targetPath);\n        List<DexArchiveEntry> dexEntries = new ArrayList<>();\n        Enumeration<? extends ZipEntry> entries = readOnlyZipFile.entries();\n        while (entries.hasMoreElements()) {\n            ZipEntry zipEntry = entries.nextElement();\n            try (BufferedInputStream inputStream =\n                         new BufferedInputStream(readOnlyZipFile.getInputStream(zipEntry))) {\n                byte[] content = ByteStreams.toByteArray(inputStream);\n                dexEntries.add(new DexArchiveEntry(content, zipEntry.getName()));\n            }\n        }\n        return dexEntries;\n    }\n\n    @Override\n    public void close() throws IOException {\n        if (jarOutputStream != null) {\n            jarOutputStream.flush();\n            jarOutputStream.close();\n        } else if (readOnlyZipFile != null) {\n            readOnlyZipFile.close();\n        } else {\n            throw new IllegalStateException(\"Dex archive is neither readable nor writable.\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/DelegateProguardTransform.java",
    "content": "package com.taobao.android.builder.insant;\n\nimport com.android.annotations.NonNull;\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.pipeline.InjectTransform;\nimport com.android.build.gradle.internal.pipeline.IntermediateFolderUtils;\nimport com.android.build.gradle.internal.pipeline.TransformManager;\nimport com.android.build.gradle.internal.publishing.AndroidArtifacts;\nimport com.android.build.gradle.internal.scope.GlobalScope;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.transforms.ProGuardTransform;\nimport com.android.build.gradle.internal.transforms.ProguardConfigurable;\nimport com.android.build.gradle.tasks.SimpleWorkQueue;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.builder.tasks.Job;\nimport com.android.builder.tasks.JobContext;\nimport com.android.ide.common.build.ApkData;\nimport com.google.common.base.Joiner;\nimport com.google.common.collect.Sets;\nimport com.google.common.util.concurrent.SettableFuture;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.extension.TBuildConfig;\nimport com.taobao.android.builder.tasks.manager.transform.MtlInjectTransform;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport com.taobao.android.builder.tools.TransformInputUtils;\nimport com.taobao.android.builder.tools.log.FileLogger;\nimport com.taobao.android.builder.tools.proguard.AtlasProguardHelper;\nimport com.taobao.android.builder.tools.proguard.AwbProguardConfiguration;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.IOUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.file.ConfigurableFileCollection;\nimport org.jf.util.ImmutableUtils;\n\nimport java.io.BufferedWriter;\nimport java.io.File;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.lang.reflect.Method;\nimport java.util.*;\nimport java.util.concurrent.ExecutionException;\nimport java.util.function.Consumer;\nimport java.util.logging.Logger;\n\nimport static com.android.builder.model.AndroidProject.FD_OUTPUTS;\n\n/**\n * FakeProguardTransform\n *\n * @author zhayu.ll\n * @date 18/10/18\n */\npublic class DelegateProguardTransform extends MtlInjectTransform {\n\n    private final TBuildConfig buildConfig;\n\n    private static org.gradle.api.logging.Logger sLogger = null;\n\n    private boolean firstTime;\n\n    private ProGuardTransform proGuardTransform;\n\n    List<File> defaultProguardFiles = new ArrayList<>();\n\n    public DelegateProguardTransform(AppVariantContext appVariantContext, ApkData apkData) {\n        super(appVariantContext, apkData);\n        proGuardTransform = new ProGuardTransform(appVariantContext.getScope());\n        this.buildConfig = appVariantContext.getAtlasExtension().getTBuildConfig();\n        sLogger = appVariantContext.getProject().getLogger();\n\n    }\n\n    @Override\n    public boolean updateNextTransformInput() {\n        return false;\n    }\n\n    @Override\n    public String getName() {\n        return \"delegateProguardTransform\";\n    }\n\n    @Override\n    public Set<QualifiedContent.ContentType> getInputTypes() {\n        return TransformManager.CONTENT_JARS;\n    }\n\n    @Override\n    public Set<? super QualifiedContent.Scope> getScopes() {\n        return TransformManager.SCOPE_FULL_PROJECT;\n    }\n\n    @Override\n    public boolean isIncremental() {\n        return false;\n    }\n\n    @Override\n    public void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {\n        super.transform(transformInvocation);\n        firstTime = true;\n        defaultProguardFiles.addAll(appVariantContext.getVariantData().getVariantConfiguration().getBuildType().getProguardFiles());\n\n        if (buildConfig.getConsumerProguardEnabled()){\n            defaultProguardFiles.addAll(appVariantContext.getScope().getArtifactFileCollection(AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH, AndroidArtifacts.ArtifactScope.ALL, AndroidArtifacts.ArtifactType.PROGUARD_RULES).getFiles());\n        }\n\n        List<AwbBundle> awbBundles = AtlasBuildContext.androidDependencyTrees.get(\n                appVariantContext.getScope().getVariantConfiguration().getFullName()).getAwbBundles();\n        if (awbBundles != null && awbBundles.size() > 0) {\n            File bundleRKeepFile = new File(appVariantContext.getBaseVariantData().getScope().getGlobalScope().getIntermediatesDir(), \"awb-progrard/bundleRKeep.cfg\");\n            if (!bundleRKeepFile.getParentFile().exists()) {\n                bundleRKeepFile.getParentFile().mkdirs();\n            }\n\n            StringBuilder keepRStr = new StringBuilder();\n            for (AwbBundle bundleItem : awbBundles) {\n                keepRStr.append(String.format(\"-keep class %s.R{*;}\\n\", bundleItem.bundleInfo.getPkgName()));\n                keepRStr.append(String.format(\"-keep class %s.R$*{*;}\\n\", bundleItem.bundleInfo.getPkgName()));\n            }\n            try {\n                BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(bundleRKeepFile));\n                bufferedWriter.write(keepRStr.toString());\n                bufferedWriter.flush();\n                IOUtils.closeQuietly(bufferedWriter);\n                FileLogger.getInstance(\"proguard\").log(\"R keep infos: \" + keepRStr);\n            } catch (IOException e) {\n                throw new RuntimeException(\"generate bundleRkeepFile failed\", e);\n            }\n            appVariantContext.getBaseVariantData().getVariantConfiguration().getBuildType().getProguardFiles().add(bundleRKeepFile);\n            defaultProguardFiles.add(bundleRKeepFile);\n        }\n\n        //apply bundle Inout\n        applyBundleInOutConfigration(appVariantContext);\n\n        //apply bundle's configuration, Switch control\n        if (buildConfig.isBundleProguardConfigEnabled() &&! buildConfig.getConsumerProguardEnabled()) {\n            applyBundleProguardConfigration(appVariantContext);\n        }\n\n        proGuardTransform.setConfigurationFiles(appVariantContext.getScope().getGlobalScope().getProject().files(defaultProguardFiles));\n\n        //apply mapping\n        applyMapping(appVariantContext);\n\n        //set output\n        File proguardOutFile = new File(appVariantContext.getProject().getBuildDir(), \"outputs/proguard.cfg\");\n        proGuardTransform.printconfiguration(proguardOutFile);\n        SettableFuture<TransformOutputProvider> resultFuture = SettableFuture.create();\n        final Job<Void> job = new Job<>(getName(),\n                new com.android.builder.tasks.Task<Void>() {\n                    @Override\n                    public void run(@NonNull Job<Void> job,\n                                    @NonNull JobContext<Void> context) throws IOException {\n\n                        try {\n                            Method m = ProGuardTransform.class.getDeclaredMethod(\"doMinification\", Collection.class, Collection.class, TransformOutputProvider.class);\n                            m.setAccessible(true);\n                            m.invoke(proGuardTransform, getAllInput(), transformInvocation.getReferencedInputs(), transformInvocation.getOutputProvider());\n                        }catch (Exception e){\n                            e.printStackTrace();\n                        }\n                    }\n\n                    @Override\n                    public void finished() {\n                        resultFuture.set(transformInvocation.getOutputProvider());\n                    }\n\n                    @Override\n                    public void error(Throwable e) {\n                        resultFuture.setException(e);\n                    }\n                }, resultFuture);\n        try {\n            SimpleWorkQueue.push(job);\n\n            // wait for the task completion.\n            try {\n                job.awaitRethrowExceptions();\n            } catch (ExecutionException e) {\n                throw new RuntimeException(\"Job failed, see logs for details\", e.getCause());\n            }\n\n            IntermediateFolderUtils folderUtils = (IntermediateFolderUtils) ReflectUtils.getField(transformInvocation.getOutputProvider(),\"folderUtils\");\n            AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).addAllMainDexJars(FileUtils.listFiles(folderUtils.getRootFolder(),new String[]{\"jar\"},true));\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new RuntimeException(e);\n        }\n    }\n\n    private Collection<TransformInput> getAllInput() {\n        Collection <JarInput> jarInputs = new HashSet<>();\n        Collection<DirectoryInput>directoryInputs = new HashSet<>();\n        Collection<File>jars = AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).getAllMainDexJars();\n        jars.forEach(new Consumer<File>() {\n            @Override\n            public void accept(File file) {\n                jarInputs.add(TransformInputUtils.makeJarInput(file,appVariantContext));\n            }\n        });\n\n        Collection<File>dirs = AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).getInputDirs();\n        dirs.forEach(new Consumer<File>() {\n            @Override\n            public void accept(File file) {\n                directoryInputs.add(TransformInputUtils.makeDirectoryInput(file,appVariantContext));\n            }\n        });\n\n        return Sets.newHashSet(new TransformInput() {\n            @Override\n            public Collection<JarInput> getJarInputs() {\n                return jarInputs;\n            }\n\n            @Override\n            public Collection<DirectoryInput> getDirectoryInputs() {\n                return directoryInputs;\n            }\n        });\n\n\n    }\n\n    public File applyBundleInOutConfigration(final AppVariantContext appVariantContext) {\n\n        VariantScope variantScope = appVariantContext.getScope();\n\n        GlobalScope globalScope = variantScope.getGlobalScope();\n        File proguardOut = new File(Joiner.on(File.separatorChar)\n                .join(String.valueOf(globalScope.getBuildDir()), FD_OUTPUTS, \"mapping\",\n                        variantScope.getVariantConfiguration().getDirName()));\n\n        File awbInOutConfig = new File(proguardOut, \"awb_inout_config.cfg\");\n\n        //Add awb configuration\n        AtlasDependencyTree dependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n                variantScope.getVariantConfiguration().getFullName());\n\n        if (dependencyTree.getAwbBundles().size() > 0) {\n            BaseVariantOutput vod = (BaseVariantOutput) appVariantContext.getVariantOutputData().iterator().next();\n            AppVariantOutputContext appVariantOutputContext = appVariantContext.getAppVariantOutputContext(ApkDataUtils.get(vod));\n            File awbObfuscatedDir = new File(globalScope.getIntermediatesDir(),\n                    \"/classes-proguard/\" + variantScope.getVariantConfiguration()\n                            .getDirName());\n            AwbProguardConfiguration awbProguardConfiguration = new AwbProguardConfiguration(\n                    appVariantOutputContext.getAwbTransformMap().values(), awbObfuscatedDir, appVariantOutputContext);\n\n            try {\n                awbProguardConfiguration.printConfigFile(awbInOutConfig);\n            } catch (IOException e) {\n                throw new GradleException(\"\", e);\n            }\n\n            defaultProguardFiles.add(awbInOutConfig);\n\n        }\n\n        return awbInOutConfig;\n    }\n\n    public File applyMapping(final AppVariantContext appVariantContext) {\n\n        File mappingFile = null;\n        if (null != appVariantContext.apContext.getApExploredFolder() && appVariantContext.apContext\n                .getApExploredFolder().exists()) {\n            mappingFile = new File(appVariantContext.apContext.getApExploredFolder(), \"mapping.txt\");\n        } else {\n            mappingFile = new File(\n                    appVariantContext.getScope().getGlobalScope().getProject().getProjectDir(),\n                    \"mapping.txt\");\n        }\n\n        if (null != mappingFile && mappingFile.exists()) {\n            proGuardTransform.applyTestedMapping(mappingFile);\n            return mappingFile;\n        }\n\n        return null;\n\n    }\n\n    public void applyBundleProguardConfigration(final AppVariantContext appVariantContext) {\n\n        Set<String> blackList = appVariantContext.getAtlasExtension().getTBuildConfig()\n                .getBundleProguardConfigBlackList();\n\n        List<File> proguardFiles = new ArrayList<>();\n        VariantScope variantScope = appVariantContext.getScope();\n        for (AwbBundle awbBundle : AtlasBuildContext.androidDependencyTrees.get(\n                variantScope.getVariantConfiguration().getFullName()).getAwbBundles()) {\n            for (AndroidLibrary androidDependency : awbBundle.getAllLibraryAars()) {\n                File proguardRules = androidDependency.getProguardRules();\n\n                String groupName = androidDependency.getResolvedCoordinates().getGroupId() + \":\" + androidDependency\n                        .getResolvedCoordinates().getArtifactId();\n                if (blackList.contains(groupName)) {\n                    sLogger.info(\"[proguard] skip proguard from \" + androidDependency.getResolvedCoordinates());\n                    continue;\n                }\n\n                if (proguardRules.isFile()) {\n                    proguardFiles.add(proguardRules);\n                    sLogger.warn(\"[proguard] load proguard from \" + androidDependency.getResolvedCoordinates());\n                } else {\n                    sLogger.info(\"[proguard] missing proguard from \" + androidDependency.getResolvedCoordinates());\n                }\n            }\n        }\n        defaultProguardFiles.addAll(proguardFiles);\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/InstantInfo.java",
    "content": "package com.taobao.android.builder.insant;\n\n/**\n * InstantInfo\n *\n * @author zhayu.ll\n * @date 18/10/26\n */\npublic class InstantInfo {\n\n    public String fileName;\n\n    public String baseVersion;\n\n    public String patchVersion;\n\n    public String md5;\n\n    public long patchSize;\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/TaobaoExtractJarsTransform.java",
    "content": "package com.taobao.android.builder.insant;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.VisibleForTesting;\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.transforms.ExtractJarsTransform;\nimport com.android.builder.packaging.PackagingUtils;\nimport com.android.ide.common.internal.WaitableExecutor;\nimport com.android.utils.FileUtils;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Sets;\nimport com.google.common.io.ByteStreams;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.tasks.app.BuildAtlasEnvTask;\nimport com.taobao.android.builder.tools.MD5Util;\nimport org.gradle.api.logging.Logger;\nimport org.gradle.api.logging.Logging;\n\nimport java.io.*;\nimport java.util.HashSet;\nimport java.util.Locale;\nimport java.util.Set;\nimport java.util.function.Consumer;\nimport java.util.jar.JarFile;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\n\nimport static com.android.utils.FileUtils.mkdirs;\nimport static com.google.common.base.Preconditions.checkNotNull;\n\n/**\n * TaobaoExtractJarsTransform\n *\n * @author zhayu.ll\n * @date 18/10/12\n */\npublic class TaobaoExtractJarsTransform extends Transform {\n\n    @VisibleForTesting\n    static Logger LOGGER = Logging.getLogger(TaobaoExtractJarsTransform.class);\n\n    @NonNull\n    private final Set<QualifiedContent.ContentType> contentTypes;\n    @NonNull\n    private final Set<QualifiedContent.Scope> scopes;\n\n    private AppVariantContext variantContext;\n\n    private AppVariantOutputContext variantOutputContext;\n\n    public TaobaoExtractJarsTransform(\n            AppVariantContext variantContext,\n            AppVariantOutputContext variantOutputContext,\n            @NonNull Set<QualifiedContent.ContentType> contentTypes,\n            @NonNull Set<QualifiedContent.Scope> scopes) {\n        this.variantContext = variantContext;\n        this.variantOutputContext = variantOutputContext;\n        this.contentTypes = contentTypes;\n        this.scopes = scopes;\n    }\n\n    @NonNull\n    @Override\n    public String getName() {\n        return \"taobaoextractJars\";\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.ContentType> getInputTypes() {\n        return contentTypes;\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.Scope> getScopes() {\n        return scopes;\n    }\n\n    @Override\n    public boolean isIncremental() {\n        return false;\n    }\n\n    @Override\n    public void transform(TransformInvocation transformInvocation) throws IOException, TransformException, InterruptedException {\n        TransformOutputProvider outputProvider = transformInvocation.getOutputProvider();\n        boolean isIncremental = transformInvocation.isIncremental();\n        checkNotNull(outputProvider, \"Missing output object for transform \" + getName());\n\n        // as_input transform and no referenced scopes, all the inputs will in InputOutputStreams.\n        final boolean extractCode = contentTypes.contains(QualifiedContent.DefaultContentType.CLASSES);\n\n        if (!isIncremental) {\n            outputProvider.deleteAll();\n        }\n        try {\n            WaitableExecutor executor = WaitableExecutor.useGlobalSharedThreadPool();\n\n            AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getInputDirs().clear();\n\n                for (File jarFile : AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getAllMainDexJars()) {\n//                    final File jarFile = jarInput.getFile();\n\n                    JarInput jarInput = makeJarInput(jarFile);\n\n                    LOGGER.warn(\"input JarFile:\"+jarFile.getAbsolutePath());\n\n                    // create an output folder for this jar, keeping its type and scopes.\n                    final File outJarFolder =\n                            outputProvider.getContentLocation(\n                                    jarInput.getName(),\n                                    jarInput.getContentTypes(),\n                                    jarInput.getScopes(),\n                                    Format.DIRECTORY);\n                    FileUtils.mkdirs(outJarFolder);\n                    LOGGER.warn(\"outJar Folder:\"+outJarFolder.getAbsolutePath());\n\n                    AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getInputDirs().add(outJarFolder);\n                    if (!isIncremental) {\n                        executor.execute(() -> {\n                            extractJar(outJarFolder, jarFile, extractCode);\n                            return null;\n                        });\n                    } else {\n                        switch (jarInput.getStatus()) {\n                            case CHANGED:\n                                executor.execute(() -> {\n                                    FileUtils.cleanOutputDir(outJarFolder);\n                                    extractJar(outJarFolder, jarFile, extractCode);\n                                    return null;\n                                });\n                                break;\n                            case ADDED:\n                                executor.execute(() -> {\n                                    extractJar(outJarFolder, jarFile, extractCode);\n                                    return null;\n                                });\n                                break;\n                            case REMOVED:\n                                executor.execute(\n                                        () -> {\n                                            FileUtils.cleanOutputDir(outJarFolder);\n                                            return null;\n                                        });\n                                break;\n                            case NOTCHANGED:\n                                break;\n                        }\n                    }\n            }\n\n            AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).addMainDexJars(Sets.newHashSet());\n\n            for (AwbTransform awbTransform:variantOutputContext.getAwbTransformMap().values()){\n                File outJarFolder = variantOutputContext.getAwbExtractJarsFolder(awbTransform.getAwbBundle());\n                awbTransform.getInputFiles().forEach(file -> executor.execute(() -> {\n                    LOGGER.warn(\"ExtractAwbJar[\"+awbTransform.getAwbBundle().getPackageName()+\"]---------------------\"+file.getAbsolutePath());\n                    extractJar(outJarFolder, file, extractCode);\n                    return null;\n                }));\n                awbTransform.getInputLibraries().forEach(file -> executor.execute(() -> {\n                    LOGGER.warn(\"ExtractAwbJar[\"+awbTransform.getAwbBundle().getPackageName()+\"]---------------------\"+file.getAbsolutePath());\n                    extractJar(outJarFolder, file, extractCode);\n                    return null;\n                }));\n\n                awbTransform.addDir(outJarFolder);\n                awbTransform.getInputFiles().clear();\n            }\n\n\n\n            executor.waitForTasksWithQuickFail(true);\n\n        } catch (InterruptedException e) {\n            throw e;\n        } catch (Exception e) {\n            throw new TransformException(e);\n        }\n    }\n\n        private JarInput makeJarInput(File file) {\n            BuildAtlasEnvTask.FileIdentity finalFileIdentity = AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).get(file);\n            return new JarInput() {\n                @Override\n                public Status getStatus() {\n                    return Status.ADDED;\n                }\n\n                @Override\n                public String getName() {\n\n                    return MD5Util.getFileMD5(file);\n                }\n\n                @Override\n                public File getFile() {\n                    return file;\n                }\n\n                @Override\n                public Set<ContentType> getContentTypes() {\n                    return ImmutableSet.of(QualifiedContent.DefaultContentType.CLASSES);\n                }\n\n                @Override\n                public Set<? super Scope> getScopes() {\n                    if (finalFileIdentity == null){\n                        return  ImmutableSet.of(Scope.EXTERNAL_LIBRARIES);\n                    }\n                    if (finalFileIdentity.subProject) {\n                        return ImmutableSet.of(Scope.SUB_PROJECTS);\n                    } else {\n                        return ImmutableSet.of(Scope.EXTERNAL_LIBRARIES);\n                    }\n                }\n            };\n    }\n\n    private static void extractJar(\n            @NonNull File outJarFolder,\n            @NonNull File jarFile,\n            boolean extractCode) throws IOException {\n        if (!jarFile.exists()){\n            return;\n        }\n        mkdirs(outJarFolder);\n        HashSet<String> lowerCaseNames = new HashSet<>();\n        boolean foundCaseInsensitiveIssue = false;\n\n        try (InputStream fis = new BufferedInputStream(new FileInputStream(jarFile));\n             ZipInputStream zis = new ZipInputStream(fis)) {\n            // loop on the entries of the intermediary package and put them in the final package.\n            ZipEntry entry;\n            while ((entry = zis.getNextEntry()) != null) {\n                try {\n                    String name = entry.getName();\n\n                    // do not take directories\n                    if (entry.isDirectory()) {\n                        continue;\n                    }\n\n                    foundCaseInsensitiveIssue = foundCaseInsensitiveIssue ||\n                            !lowerCaseNames.add(name.toLowerCase(Locale.US));\n\n                    TaobaoExtractJarsTransform.Action action = getAction(name, extractCode);\n                    if (action == TaobaoExtractJarsTransform.Action.COPY) {\n                        File outputFile = new File(outJarFolder,\n                                name.replace('/', File.separatorChar));\n                        mkdirs(outputFile.getParentFile());\n\n                        try (OutputStream outputStream =\n                                     new BufferedOutputStream(new FileOutputStream(outputFile))) {\n                            ByteStreams.copy(zis, outputStream);\n                            outputStream.flush();\n                        }\n                    }\n                } finally {\n                    zis.closeEntry();\n                }\n            }\n\n        }\n\n        if (foundCaseInsensitiveIssue) {\n            LOGGER.error(\n                    \"Jar '{}' contains multiple entries which will map to \"\n                            + \"the same file on case insensitive file systems.\\n\"\n                            + \"This can be caused by obfuscation with useMixedCaseClassNames.\\n\"\n                            + \"This build will be incorrect on case insensitive \"\n                            + \"file systems.\", jarFile.getAbsolutePath());\n        }\n    }\n\n    /**\n     * Define all possible actions for a Jar file entry.\n     */\n    enum Action {\n        /**\n         * Copy the file to the output destination.\n         */\n        COPY,\n        /**\n         * Ignore the file.\n         */\n        IGNORE\n    }\n\n    /**\n     * Provides an {@link ExtractJarsTransform.Action} for the archive entry.\n     * @param archivePath the archive entry path in the archive.\n     * @param extractCode whether to extract class files\n     * @return the action to implement.\n     */\n    @NonNull\n    public static TaobaoExtractJarsTransform.Action getAction(@NonNull String archivePath, boolean extractCode) {\n        // Manifest files are never merged.\n        if (JarFile.MANIFEST_NAME.equals(archivePath)) {\n            return TaobaoExtractJarsTransform.Action.IGNORE;\n        }\n\n        // split the path into segments.\n        String[] segments = archivePath.split(\"/\");\n\n        // empty path? skip to next entry.\n        if (segments.length == 0) {\n            return TaobaoExtractJarsTransform.Action.IGNORE;\n        }\n\n        return PackagingUtils.checkFileForApkPackaging(archivePath, extractCode)\n                ? TaobaoExtractJarsTransform.Action.COPY\n                : TaobaoExtractJarsTransform.Action.IGNORE;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/TaobaoInstantRunDependenciesApkBuilder.java",
    "content": "package com.taobao.android.builder.insant;\n\nimport com.android.build.api.transform.QualifiedContent;\nimport com.android.build.api.transform.TransformException;\nimport com.android.build.api.transform.TransformInvocation;\nimport com.android.build.gradle.internal.aapt.AaptGeneration;\nimport com.android.build.gradle.internal.dsl.CoreSigningConfig;\nimport com.android.build.gradle.internal.incremental.InstantRunBuildContext;\nimport com.android.build.gradle.internal.scope.PackagingScope;\nimport com.android.build.gradle.internal.transforms.InstantRunDependenciesApkBuilder;\nimport com.android.builder.core.AndroidBuilder;\nimport com.android.builder.internal.aapt.AaptOptions;\nimport com.android.builder.utils.FileCache;\nimport com.google.common.collect.Sets;\nimport com.taobao.android.builder.tasks.manager.transform.TransformManager;\nimport org.gradle.api.Project;\nimport org.gradle.api.logging.Logger;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Set;\n\n/**\n * TaobaoInstantRunDependenciesApkBuilder\n *\n * @author zhayu.ll\n * @date 18/10/12\n */\npublic class TaobaoInstantRunDependenciesApkBuilder extends InstantRunDependenciesApkBuilder {\n\n    public TaobaoInstantRunDependenciesApkBuilder(Logger logger, Project project, InstantRunBuildContext buildContext, AndroidBuilder androidBuilder, FileCache fileCache, PackagingScope packagingScope, CoreSigningConfig signingConf, AaptGeneration aaptGeneration, AaptOptions aaptOptions, File outputDirectory, File supportDirectory, File aaptIntermediateDirectory) {\n        super(logger, project, buildContext, androidBuilder, fileCache, packagingScope, signingConf, aaptGeneration, aaptOptions, outputDirectory, supportDirectory, aaptIntermediateDirectory);\n    }\n\n    @Override\n    public Set<QualifiedContent.Scope> getScopes() {\n        return com.android.build.gradle.internal.pipeline.TransformManager.SCOPE_FULL_PROJECT;\n    }\n\n    @Override\n    public void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {\n        super.transform(transformInvocation);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/TaobaoInstantRunDex.java",
    "content": "package com.taobao.android.builder.insant;\n\nimport com.alibaba.fastjson.JSON;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.VisibleForTesting;\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.incremental.FileType;\nimport com.android.build.gradle.internal.incremental.InstantRunBuildContext;\nimport com.android.build.gradle.internal.pipeline.ExtendedContentType;\nimport com.android.build.gradle.internal.scope.InstantRunVariantScope;\nimport com.android.build.gradle.internal.transforms.InstantRunBuildType;\nimport com.android.build.gradle.internal.transforms.InstantRunDex;\nimport com.android.builder.core.DexByteCodeConverter;\nimport com.android.builder.core.DexOptions;\nimport com.android.builder.model.OptionalCompilationStep;\nimport com.android.ide.common.process.LoggedProcessOutputHandler;\nimport com.android.ide.common.process.ProcessException;\nimport com.android.utils.FileUtils;\nimport com.android.utils.ILogger;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Sets;\nimport com.google.common.io.Files;\nimport com.taobao.android.builder.tools.MD5Util;\nimport org.dom4j.DocumentException;\nimport org.gradle.api.logging.Logger;\n\nimport java.io.*;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.function.Supplier;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarOutputStream;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipOutputStream;\n\n/**\n * TaobaoInstantRunDex\n *\n * @author zhayu.ll\n * @date 18/10/18\n */\npublic class TaobaoInstantRunDex extends Transform {\n\n\n    @NonNull\n    private final DexOptions dexOptions;\n\n    @NonNull\n    private final ILogger logger;\n\n    private DexByteCodeConverter dexByteCodeConverter;\n\n    private BaseVariantOutput variantOutput;\n\n    public PreloadJarHooker getPreloadJarHooker() {\n        return preloadJarHooker;\n    }\n\n    public void setPreloadJarHooker(PreloadJarHooker preloadJarHooker) {\n        this.preloadJarHooker = preloadJarHooker;\n    }\n\n    private PreloadJarHooker preloadJarHooker;\n    @NonNull\n    private final InstantRunVariantScope variantScope;\n    private final int minSdkForDx;\n    private AppVariantContext variantContext;\n\n    public TaobaoInstantRunDex(\n            AppVariantContext variantContext,\n            @NonNull InstantRunVariantScope transformVariantScope,\n            DexByteCodeConverter dexByteCodeConverter,\n            @NonNull DexOptions dexOptions,\n            @NonNull Logger logger,\n            int minSdkForDx,\n            BaseVariantOutput variantOutput) {\n        this.variantScope = transformVariantScope;\n        this.variantContext = variantContext;\n        this.dexByteCodeConverter = dexByteCodeConverter;\n        this.dexOptions = dexOptions;\n        this.logger = new LoggerWrapper(logger);\n        this.minSdkForDx = minSdkForDx;\n        this.variantOutput = variantOutput;\n    }\n\n    @Override\n    public void transform(@NonNull TransformInvocation invocation)\n            throws IOException, TransformException, InterruptedException {\n\n        File outputFolder = variantScope.getReloadDexOutputFolder();\n//        boolean changesAreCompatible =\n//                variantScope.getInstantRunBuildContext().hasPassedVerification();\n//        boolean restartDexRequested =\n//                variantScope.getGlobalScope().isActive(OptionalCompilationStep.RESTART_ONLY);\n\n//        if (!changesAreCompatible || restartDexRequested) {\n            FileUtils.cleanOutputDir(outputFolder);\n//            return;\n//        }\n\n        // create a tmp jar file.\n        File classesJar = new File(outputFolder, \"classes.jar\");\n        if (classesJar.exists()) {\n            FileUtils.delete(classesJar);\n        }\n        Files.createParentDirs(classesJar);\n        final TaobaoInstantRunDex.JarClassesBuilder jarClassesBuilder = getJarClassBuilder(classesJar);\n\n        try {\n            for (TransformInput input : invocation.getReferencedInputs()) {\n                for (DirectoryInput directoryInput : input.getDirectoryInputs()) {\n                    if (!directoryInput.getContentTypes()\n                            .contains(ExtendedContentType.CLASSES_ENHANCED)) {\n                        continue;\n                    }\n                    final File folder = directoryInput.getFile();\n                    if (invocation.isIncremental()) {\n                        for (Map.Entry<File, Status> entry :\n                                directoryInput.getChangedFiles().entrySet()) {\n                            if (entry.getValue() != Status.REMOVED) {\n                                File file = entry.getKey();\n                                if (file.isFile()) {\n                                    jarClassesBuilder.add(folder, file);\n                                }\n                            }\n                        }\n                    } else {\n                        Iterable<File> files = FileUtils.getAllFiles(folder);\n                        for (File inputFile : files) {\n                            jarClassesBuilder.add(folder, inputFile);\n                        }\n                    }\n                }\n            }\n        } finally {\n            jarClassesBuilder.close();\n        }\n\n        // if no files were added, clean up and return.\n        if (jarClassesBuilder.isEmpty()) {\n            FileUtils.cleanOutputDir(outputFolder);\n            return;\n        }\n\n        if (preloadJarHooker != null){\n           classesJar = preloadJarHooker.process(classesJar);\n        }\n\n        final ImmutableList.Builder<File> inputFiles = ImmutableList.builder();\n        inputFiles.add(classesJar);\n\n        try {\n            variantScope\n                    .getInstantRunBuildContext()\n                    .startRecording(InstantRunBuildContext.TaskType.INSTANT_RUN_DEX);\n            convertByteCode(inputFiles.build(), outputFolder);\n            variantScope\n                    .getInstantRunBuildContext()\n                    .addChangedFile(FileType.RELOAD_DEX, new File(outputFolder, \"classes.dex\"));\n        } catch (ProcessException e) {\n            throw new TransformException(e);\n        } finally {\n            variantScope\n                    .getInstantRunBuildContext()\n                    .stopRecording(InstantRunBuildContext.TaskType.INSTANT_RUN_DEX);\n        }\n\n        variantScope.getInstantRunBuildContext().close();\n\n        if (variantContext.getScope().getInstantRunBuildContext().isInInstantRunMode()) {\n            InstantRunBuildContext instantRunBuildContext = variantContext.getScope().getInstantRunBuildContext();\n            InstantRunBuildContext.Artifact artifact = instantRunBuildContext.getLastBuild().getArtifactForType(FileType.RELOAD_DEX);\n            File patchFile = artifact.getLocation();\n            String baseVersion = ApkDataUtils.get(variantOutput).getVersionName();\n            if (artifact!= null && patchFile.exists()) {\n                File finalFile = variantContext.getAppVariantOutputContext(ApkDataUtils.get(variantOutput)).getIPatchFile(baseVersion);\n                zipPatch(finalFile, patchFile);\n            }else {\n                logger.warning(\"patchFile is not exist or no classes is modified!\");\n            }\n            return;\n        }\n    }\n\n\n\n    @VisibleForTesting\n    static class JarClassesBuilder implements Closeable {\n        final File outputFile;\n        private JarOutputStream jarOutputStream;\n        boolean empty = true;\n\n        private JarClassesBuilder(@NonNull File outputFile) {\n            this.outputFile = outputFile;\n        }\n\n        void add(File inputDir, File file) throws IOException {\n            if (jarOutputStream == null) {\n                jarOutputStream = new JarOutputStream(\n                        new BufferedOutputStream(new FileOutputStream(outputFile)));\n            }\n            empty = false;\n            copyFileInJar(inputDir, file, jarOutputStream);\n        }\n\n        @Override\n        public void close() throws IOException {\n            if (jarOutputStream != null) {\n                jarOutputStream.close();\n            }\n        }\n\n        boolean isEmpty() {\n            return empty;\n        }\n    }\n\n    @VisibleForTesting\n    protected void convertByteCode(List<File> inputFiles, File outputFolder)\n            throws InterruptedException, ProcessException, IOException {\n        dexByteCodeConverter\n                .convertByteCode(\n                        inputFiles,\n                        outputFolder,\n                        false /* multiDexEnabled */,\n                        null /*getMainDexListFile */,\n                        dexOptions,\n                        new LoggedProcessOutputHandler(logger),\n                        minSdkForDx);\n    }\n\n    @VisibleForTesting\n    protected TaobaoInstantRunDex.JarClassesBuilder getJarClassBuilder(File outputFile) {\n        return new TaobaoInstantRunDex.JarClassesBuilder(outputFile);\n    }\n\n    private static void copyFileInJar(File inputDir, File inputFile, JarOutputStream jarOutputStream)\n            throws IOException {\n\n        String entryName = inputFile.getPath().substring(inputDir.getPath().length() + 1);\n        JarEntry jarEntry = new JarEntry(entryName);\n        jarOutputStream.putNextEntry(jarEntry);\n        Files.copy(inputFile, jarOutputStream);\n        jarOutputStream.closeEntry();\n    }\n\n    @NonNull\n    @Override\n    public String getName() {\n        return \"instantReloadDex\";\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.ContentType> getInputTypes() {\n        return ImmutableSet.of(ExtendedContentType.CLASSES_ENHANCED);\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.Scope> getScopes() {\n        return ImmutableSet.of();\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.Scope> getReferencedScopes() {\n        return Sets.immutableEnumSet(QualifiedContent.Scope.PROJECT);\n    }\n\n    @NonNull\n    @Override\n    public Map<String, Object> getParameterInputs() {\n        ImmutableMap.Builder<String, Object> params = ImmutableMap.builder();\n        params.put(\n                \"changesAreCompatible\",\n                variantScope.getInstantRunBuildContext().hasPassedVerification());\n        params.put(\n                \"restartDexRequested\",\n                variantScope.getGlobalScope().isActive(OptionalCompilationStep.RESTART_ONLY));\n        params.put(\"minSdkForDx\", minSdkForDx);\n        return params.build();\n    }\n\n    @NonNull\n    @Override\n    public Collection<File> getSecondaryDirectoryOutputs() {\n        return ImmutableList.of(variantScope.getReloadDexOutputFolder());\n    }\n\n    @Override\n    public boolean isIncremental() {\n        return true;\n    }\n\n    public static void zipPatch(File file, File dexFile) throws IOException {\n        BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(dexFile));\n        byte[] BUFFER = new byte[4096];\n        FileOutputStream fOutputStream = new FileOutputStream(file);\n        ZipOutputStream zoutput = new ZipOutputStream(fOutputStream);\n        ZipEntry zEntry = new ZipEntry(dexFile.getName());\n        zoutput.putNextEntry(zEntry);\n        int len;\n        while ((len = inputStream.read(BUFFER)) > 0) {\n            zoutput.write(BUFFER, 0, len);\n        }\n        zoutput.closeEntry();\n        zoutput.close();\n        inputStream.close();\n    }\n\n\n    public static interface PreloadJarHooker{\n\n        File process(File jarFile);\n    }\n}\n\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/TaobaoInstantRunSlicer.java",
    "content": "package com.taobao.android.builder.insant;\n\nimport com.android.build.api.transform.QualifiedContent;\nimport com.android.build.api.transform.TransformException;\nimport com.android.build.api.transform.TransformInvocation;\nimport com.android.build.gradle.internal.pipeline.TransformManager;\nimport com.android.build.gradle.internal.scope.InstantRunVariantScope;\nimport com.android.build.gradle.internal.transforms.InstantRunSlicer;\nimport org.gradle.api.logging.Logger;\n\nimport java.io.IOException;\nimport java.util.Set;\n\n/**\n * TaobaoInstantRunSlicer\n *\n * @author zhayu.ll\n * @date 18/10/12\n */\npublic class TaobaoInstantRunSlicer extends InstantRunSlicer {\n\n    public TaobaoInstantRunSlicer(Logger logger, InstantRunVariantScope variantScope) {\n        super(logger, variantScope);\n    }\n\n    @Override\n    public Set<QualifiedContent.Scope> getScopes() {\n        return TransformManager.SCOPE_FULL_PROJECT;\n    }\n\n    @Override\n    public void transform(TransformInvocation transformInvocation) throws IOException, TransformException, InterruptedException {\n        super.transform(transformInvocation);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/TaobaoInstantRunTransform.java",
    "content": "package com.taobao.android.builder.insant;\n\nimport com.alibaba.fastjson.JSON;\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.incremental.TBIncrementalSupportVisitor;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.incremental.*;\nimport com.android.build.gradle.internal.pipeline.ExtendedContentType;\nimport com.android.build.gradle.internal.scope.GlobalScope;\nimport com.android.build.gradle.internal.scope.InstantRunVariantScope;\nimport com.android.build.gradle.options.DeploymentDevice;\nimport com.android.ide.common.internal.WaitableExecutor;\nimport com.android.sdklib.AndroidVersion;\nimport com.android.utils.FileUtils;\nimport com.android.utils.ILogger;\nimport com.google.common.base.Joiner;\nimport com.google.common.base.Preconditions;\nimport com.google.common.base.Throwables;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Sets;\nimport com.google.common.io.Files;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.android.build.gradle.internal.incremental.TBIncrementalVisitor;\nimport com.taobao.android.builder.insant.matcher.MatcherCreator;\nimport com.taobao.android.builder.insant.visitor.ModifyClassVisitor;\nimport com.taobao.android.builder.tools.multidex.mutli.MappingReaderProcess;\nimport org.gradle.api.logging.Logging;\nimport org.objectweb.asm.*;\n\nimport java.io.*;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.util.*;\nimport java.util.function.Consumer;\nimport java.util.stream.Collectors;\n\nimport static com.android.builder.model.AndroidProject.FD_OUTPUTS;\n\n/**\n * TaobaoInstantRunTransform\n *\n * @author zhayu.ll\n * @date 18/10/12\n */\npublic class TaobaoInstantRunTransform extends Transform {\n    private final File injectSuccessFile;\n    private InstantRunVariantScope transformScope;\n    protected static final ILogger LOGGER =\n            new LoggerWrapper(Logging.getLogger(TaobaoInstantRunTransform.class));\n    private final WaitableExecutor executor;\n    private AppVariantContext variantContext;\n    private AppVariantOutputContext variantOutputContext;\n    private final ImmutableList.Builder<String> generatedClasses3Names = ImmutableList.builder();\n    private final AndroidVersion targetPlatformApi;\n    private File injectFailedFile;\n    private List<String> errors = new ArrayList<>();\n    private List<String> success = new ArrayList<>();\n\n    MappingReaderProcess mappingReaderProcess = new MappingReaderProcess();\n\n    private Map<String, String> modifyClasses = new HashMap<>();\n\n\n    public TaobaoInstantRunTransform(AppVariantContext variantContext, AppVariantOutputContext variantOutputContext, WaitableExecutor executor, InstantRunVariantScope transformScope) {\n        this.variantContext = variantContext;\n        this.variantOutputContext = variantOutputContext;\n        this.executor = executor;\n        this.transformScope = transformScope;\n        this.targetPlatformApi =\n                DeploymentDevice.getDeploymentDeviceAndroidVersion(\n                        transformScope.getGlobalScope().getProjectOptions());\n\n        injectFailedFile = new File(variantContext.getProject().getBuildDir(), \"outputs/warning-instrument-inject-error.properties\");\n        injectSuccessFile = new File(variantContext.getProject().getBuildDir(), \"outputs/instrument.properties\");\n\n    }\n\n    @Override\n    public String getName() {\n        return \"taobaoInstantRun\";\n    }\n\n    @Override\n    public Set<QualifiedContent.ContentType> getInputTypes() {\n        return com.android.build.gradle.internal.pipeline.TransformManager.CONTENT_CLASS;\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.ContentType> getOutputTypes() {\n        return ImmutableSet.of(\n                QualifiedContent.DefaultContentType.CLASSES,\n                ExtendedContentType.CLASSES_ENHANCED);\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.Scope> getScopes() {\n        return Sets.immutableEnumSet(QualifiedContent.Scope.PROJECT, QualifiedContent.Scope.SUB_PROJECTS);\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.Scope> getReferencedScopes() {\n        return Sets.immutableEnumSet(QualifiedContent.Scope.EXTERNAL_LIBRARIES,\n                QualifiedContent.Scope.PROVIDED_ONLY);\n    }\n\n    @Override\n    public boolean isIncremental() {\n        return false;\n    }\n\n    @Override\n    public void transform(TransformInvocation invocation) throws IOException, TransformException, InterruptedException {\n\n        File mappingFile = loadProguardFile();\n        boolean isMinifyEnabled = variantContext.getVariantConfiguration().getBuildType().isMinifyEnabled();\n\n        if (mappingFile.exists() && isMinifyEnabled) {\n            proguard.obfuscate.MappingReader mappingReader = new proguard.obfuscate.MappingReader(mappingFile);\n            mappingReader.pump(mappingReaderProcess);\n        }\n\n        if (null != variantContext.apContext.getApExploredFolder() && variantContext.apContext\n                .getApExploredFolder().exists()) {\n            File errorFile = new File(variantContext.apContext.getApExploredFolder(), \"warning-instrument-inject-error.properties\");\n            if (errorFile.exists()) {\n                org.apache.commons.io.FileUtils.readLines(errorFile).forEach(s -> {\n                    if (s.split(\":\").length == 2) {\n                        errors.add(s.split(\":\")[1]);\n                    }\n                });\n            }\n        }\n\n        List<JarInput> jarInputs =\n                invocation\n                        .getInputs()\n                        .stream()\n                        .flatMap(input -> input.getJarInputs().stream())\n                        .collect(Collectors.toList());\n\n        Preconditions.checkState(\n                jarInputs.isEmpty(), \"Unexpected inputs: \" + Joiner.on(\", \").join(jarInputs));\n\n        InstantRunBuildContext buildContext = transformScope.getInstantRunBuildContext();\n\n        buildContext.startRecording(InstantRunBuildContext.TaskType.INSTANT_RUN_TRANSFORM);\n        try {\n            doTransform(invocation);\n        } finally {\n            buildContext.stopRecording(InstantRunBuildContext.TaskType.INSTANT_RUN_TRANSFORM);\n        }\n        org.apache.commons.io.FileUtils.writeLines(injectFailedFile, errors);\n        org.apache.commons.io.FileUtils.writeLines(injectSuccessFile, success);\n\n    }\n\n\n    public void doTransform(TransformInvocation invocation) throws IOException, TransformException, InterruptedException {\n        InstantRunBuildContext buildContext = transformScope.getInstantRunBuildContext();\n        // if we do not run in incremental mode, we should automatically switch to COLD swap.\n        buildContext.setVerifierStatus(\n                InstantRunVerifierStatus.BUILD_NOT_INCREMENTAL);\n\n        // If this is not a HOT_WARM build, clean up the enhanced classes and don't generate new\n        // ones during this build.\n        boolean inHotSwapMode =\n                buildContext.getBuildMode() == InstantRunBuildMode.HOT_WARM;\n\n        TransformOutputProvider outputProvider = invocation.getOutputProvider();\n        if (outputProvider == null) {\n            throw new IllegalStateException(\"InstantRunTransform called with null output\");\n        }\n\n        File classesTwoOutput =\n                outputProvider.getContentLocation(\n                        \"classes\", com.android.build.gradle.internal.pipeline.TransformManager.CONTENT_CLASS, getScopes(), Format.DIRECTORY);\n\n        File classesThreeOutput =\n                outputProvider.getContentLocation(\n                        \"enhanced_classes\",\n                        ImmutableSet.of(ExtendedContentType.CLASSES_ENHANCED),\n                        getScopes(),\n                        Format.DIRECTORY);\n\n        AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getInputDirs().clear();\n        AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getInputDirs().add(classesTwoOutput);\n        AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getInputDirs().add(classesThreeOutput);\n\n        List<TransformException> exceptions = new ArrayList<>();\n        List<WorkItem> workItems = new ArrayList<>();\n        for (TransformInput input : invocation.getInputs()) {\n            for (DirectoryInput directoryInput : input.getDirectoryInputs()) {\n                File inputDir = directoryInput.getFile();\n                LOGGER.warning(\"inputDir:\", inputDir.getAbsolutePath());\n                // non incremental mode, we need to traverse the TransformInput#getFiles()\n                // folder\n                FileUtils.cleanOutputDir(classesTwoOutput);\n                for (File file : Files.fileTreeTraverser().breadthFirstTraversal(inputDir)) {\n                    if (file.isDirectory()) {\n                        continue;\n                    }\n                    PatchPolicy patchPolicy = PatchPolicy.NONE;\n                    if (file.getName().endsWith(SdkConstants.DOT_CLASS)) {\n                        patchPolicy = parseClassPolicy(file);\n                    }\n                    String path = FileUtils.relativePath(file, inputDir);\n                    String className = path.replace(\"/\", \".\").substring(0, path.length() - 6);\n\n                    boolean isAdd = false;\n                    switch (patchPolicy) {\n                        case ADD:\n                            modifyClasses.put(className, PatchPolicy.ADD.name());\n                            workItems.add(() -> transformToClasses2Format(\n                                    inputDir,\n                                    file,\n                                    classesThreeOutput,\n                                    Status.ADDED));\n                            isAdd = true;\n                            break;\n\n                        case MODIFY:\n                            if (errors.contains(path)) {\n                                exceptions.add(new TransformException(path + \" is not support modify because inject error in base build!\"));\n                            }\n                            modifyClasses.put(className, PatchPolicy.MODIFY.name());\n                            workItems.add(() -> transformToClasses3Format(\n                                    inputDir,\n                                    file,\n                                    classesThreeOutput));\n                            break;\n                    }\n                    if (isAdd) {\n                        continue;\n                    }\n\n                    workItems.add(() -> transformToClasses2Format(\n                            inputDir,\n                            file,\n                            classesTwoOutput,\n                            Status.ADDED));\n                }\n\n\n            }\n        }\n\n\n        Map<AwbBundle, File> awbBundleFileMap = new HashMap<>();\n        variantOutputContext.getAwbTransformMap().values().forEach(awbTransform -> {\n            File awbClassesTwoOutout = variantOutputContext.getAwbClassesInstantOut(awbTransform.getAwbBundle());\n            LOGGER.warning(\"InstantAwbclassOut[\" + awbTransform.getAwbBundle().getPackageName() + \"]---------------------\" + awbClassesTwoOutout.getAbsolutePath());\n            FileUtils.mkdirs(awbClassesTwoOutout);\n            try {\n                FileUtils.cleanOutputDir(awbClassesTwoOutout);\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n            awbTransform.getInputDirs().forEach(dir -> {\n                LOGGER.warning(\"InstantAwbclassDir[\" + awbTransform.getAwbBundle().getPackageName() + \"]---------------------\" + dir.getAbsolutePath());\n                for (File file : Files.fileTreeTraverser().breadthFirstTraversal(dir)) {\n                    if (!file.exists() || file.isDirectory()) {\n                        continue;\n                    }\n                    PatchPolicy patchPolicy = PatchPolicy.NONE;\n                    if (file.getName().endsWith(SdkConstants.DOT_CLASS)) {\n                        patchPolicy = parseClassPolicy(file);\n                    }\n                    String path = FileUtils.relativePath(file, dir);\n                    String className = path.replace(\"/\", \".\").substring(0, path.length() - 6);\n                    boolean isAdd = false;\n                    switch (patchPolicy) {\n                        case ADD:\n                            modifyClasses.put(className, PatchPolicy.ADD.name());\n                            workItems.add(() -> transformToClasses2Format(\n                                    dir,\n                                    file,\n                                    classesThreeOutput,\n                                    Status.ADDED));\n                            isAdd = true;\n                            break;\n\n                        case MODIFY:\n                            if (errors.contains(path)) {\n                                exceptions.add(new TransformException(path + \" is not support modify because inject error in base build!\"));\n                            }\n                            modifyClasses.put(className, PatchPolicy.MODIFY.name());\n                            workItems.add(() -> transformToClasses3Format(\n                                    dir,\n                                    file,\n                                    classesThreeOutput));\n                            break;\n                    }\n\n                    if (isAdd) {\n                        continue;\n                    }\n\n                    workItems.add(() -> transformToClasses2Format(\n                            dir,\n                            file,\n                            awbClassesTwoOutout,\n                            Status.ADDED));\n                }\n\n            });\n\n            awbBundleFileMap.put(awbTransform.getAwbBundle(), awbClassesTwoOutout);\n        });\n\n        // first get all referenced input to construct a class loader capable of loading those\n        // classes. This is useful for ASM as it needs to load classes\n        List<URL> referencedInputUrls = getAllClassesLocations(\n                invocation.getInputs(), invocation.getReferencedInputs());\n\n        if (exceptions.size() > 0) {\n            throw exceptions.get(0);\n        }\n        // This class loader could be optimized a bit, first we could create a parent class loader\n        // with the android.jar only that could be stored in the GlobalScope for reuse. This\n        // class loader could also be store in the VariantScope for potential reuse if some\n        // other transform need to load project's classes.\n        try (URLClassLoader urlClassLoader = new NonDelegatingUrlClassloader(referencedInputUrls)) {\n            workItems.forEach(\n                    workItem ->\n                            executor.execute(\n                                    () -> {\n                                        ClassLoader currentThreadClassLoader =\n                                                Thread.currentThread().getContextClassLoader();\n                                        Thread.currentThread()\n                                                .setContextClassLoader(urlClassLoader);\n                                        try {\n                                            return workItem.doWork();\n                                        } finally {\n                                            Thread.currentThread()\n                                                    .setContextClassLoader(\n                                                            currentThreadClassLoader);\n                                        }\n                                    }));\n\n            try {\n                // wait for all work items completion.\n                executor.waitForTasksWithQuickFail(true);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n                throw new TransformException(e);\n            } catch (Exception e) {\n                throw new TransformException(e);\n            }\n        }\n\n        variantOutputContext.getAwbTransformMap().values().parallelStream().forEach(awbTransform -> {\n            awbTransform.getInputLibraries().clear();\n            awbTransform.getInputFiles().clear();\n            awbTransform.getInputDirs().clear();\n            awbTransform.getInputDirs().add(awbBundleFileMap.get(awbTransform.getAwbBundle()));\n        });\n\n        // If our classes.2 transformations indicated that a cold swap was necessary,\n        // clean up the classes.3 output folder as some new files may have been generated.\n        if (generatedClasses3Names.build().size() == 0) {\n            FileUtils.cleanOutputDir(classesThreeOutput);\n        }\n\n        wrapUpOutputs(classesTwoOutput, classesThreeOutput);\n\n    }\n\n    private PatchPolicy parseClassPolicy(File file) {\n        if (!variantContext.getBuildType().getPatchConfig().isCreateIPatch()) {\n            return PatchPolicy.NONE;\n        }\n\n\n        final PatchPolicy[] patchPolicy = {PatchPolicy.NONE};\n        BufferedInputStream inputStream = null;\n        try {\n            inputStream = new BufferedInputStream(new FileInputStream(file));\n            ClassReader classReader = new ClassReader(inputStream);\n            classReader.accept(new ModifyClassVisitor(Opcodes.ASM5, patchPolicy), ClassReader.SKIP_CODE);\n        } catch (Exception e) {\n            e.printStackTrace();\n//            throw new RuntimeException(e);\n        } finally {\n            try {\n                inputStream.close();\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n        return patchPolicy[0];\n    }\n\n    private interface WorkItem {\n\n        Void doWork() throws IOException;\n    }\n\n    @NonNull\n    private List<URL> getAllClassesLocations(\n            @NonNull Collection<TransformInput> inputs,\n            @NonNull Collection<TransformInput> referencedInputs) throws MalformedURLException {\n\n        List<URL> referencedInputUrls = new ArrayList<>();\n\n        // add the bootstrap classpath for jars like android.jar\n        for (File file : transformScope.getInstantRunBootClasspath()) {\n            referencedInputUrls.add(file.toURI().toURL());\n        }\n\n        // now add the project dependencies.\n        for (TransformInput referencedInput : referencedInputs) {\n            addAllClassLocations(referencedInput, referencedInputUrls);\n        }\n\n        // and finally add input folders.\n        for (TransformInput input : inputs) {\n            addAllClassLocations(input, referencedInputUrls);\n        }\n\n\n        variantOutputContext.getAwbTransformMap().values().forEach(new Consumer<AwbTransform>() {\n            @Override\n            public void accept(AwbTransform awbTransform) {\n                try {\n                    addAllClassLocations(awbTransform.getInputFiles(), referencedInputUrls);\n                    addAllClassLocations(awbTransform.getInputDirs(), referencedInputUrls);\n                } catch (MalformedURLException e) {\n                    e.printStackTrace();\n                }\n            }\n        });\n\n        return referencedInputUrls;\n    }\n\n    private static void addAllClassLocations(TransformInput transformInput, List<URL> into)\n            throws MalformedURLException {\n\n        for (DirectoryInput directoryInput : transformInput.getDirectoryInputs()) {\n            into.add(directoryInput.getFile().toURI().toURL());\n        }\n        for (JarInput jarInput : transformInput.getJarInputs()) {\n            into.add(jarInput.getFile().toURI().toURL());\n        }\n    }\n\n    private static void addAllClassLocations(Collection<File> classFiles, List<URL> into)\n            throws MalformedURLException {\n        for (File classFile : classFiles) {\n            into.add(classFile.toURI().toURL());\n        }\n\n    }\n\n\n    private static void deleteOutputFile(\n            @NonNull IncrementalVisitor.VisitorBuilder visitorBuilder,\n            @NonNull File inputDir, @NonNull File inputFile, @NonNull File outputDir) {\n        String inputPath = FileUtils.relativePossiblyNonExistingPath(inputFile, inputDir);\n        String outputPath =\n                visitorBuilder.getMangledRelativeClassFilePath(inputPath);\n        File outputFile = new File(outputDir, outputPath);\n        if (outputFile.exists()) {\n            try {\n                FileUtils.delete(outputFile);\n            } catch (IOException e) {\n                // it's not a big deal if the file cannot be deleted, hopefully\n                // no code is still referencing it, yet we should notify.\n                LOGGER.warning(\"Cannot delete %1$s file.\\nCause: %2$s\",\n                        outputFile, Throwables.getStackTraceAsString(e));\n            }\n        }\n    }\n\n\n    private static class NonDelegatingUrlClassloader extends URLClassLoader {\n\n        public NonDelegatingUrlClassloader(@NonNull List<URL> urls) {\n            super(urls.toArray(new URL[urls.size()]), null);\n        }\n\n        @Override\n        public URL getResource(String name) {\n            // Never delegate to bootstrap classes.\n            return findResource(name);\n        }\n    }\n\n\n    @Nullable\n    protected Void transformToClasses3Format(File inputDir, File inputFile, File outputDir)\n            throws IOException {\n\n\n        File outputFile =\n                TBIncrementalVisitor.instrumentClass(\n                        targetPlatformApi.getFeatureLevel(),\n                        inputDir,\n                        inputFile,\n                        outputDir,\n                        TBIncrementalChangeVisitor.VISITOR_BUILDER,\n                        LOGGER,\n                        null,\n                        false,\n                        variantContext.getAtlasExtension().getTBuildConfig().isPatchConstructors(),\n                        variantContext.getAtlasExtension().getTBuildConfig().isPatchEachMethod(),\n                        variantContext.getAtlasExtension().getTBuildConfig().isSupportAddCallSuper(),\n                        variantContext.getAtlasExtension().getTBuildConfig().getPatchSuperMethodCount());\n\n        // if the visitor returned null, that means the class cannot be hot swapped or more likely\n        // that it was disabled for InstantRun, we don't add it to our collection of generated\n        // classes and it will not be part of the Patch class that apply changes.\n\n        if (outputFile == null) {\n            transformScope\n                    .getInstantRunBuildContext()\n                    .setVerifierStatus(InstantRunVerifierStatus.INSTANT_RUN_DISABLED);\n            LOGGER.info(\"Class %s cannot be hot swapped.\", inputFile);\n            return null;\n        }\n        generatedClasses3Names.add(\n                inputFile.getAbsolutePath().substring(\n                        inputDir.getAbsolutePath().length() + 1,\n                        inputFile.getAbsolutePath().length() - \".class\".length())\n                        .replace(File.separatorChar, '.'));\n        return null;\n    }\n\n\n    @Nullable\n    protected Void transformToClasses2Format(\n            @NonNull final File inputDir,\n            @NonNull final File inputFile,\n            @NonNull final File outputDir,\n            @NonNull final Status change) {\n\n        if (inputFile.getPath().endsWith(SdkConstants.DOT_CLASS)) {\n            String path = FileUtils.relativePath(inputFile, inputDir);\n            try {\n                Set<String> excludePkgs = variantContext.getAtlasExtension().getTBuildConfig().getInjectExcludePkgs();\n                Set<String> pkgs = variantContext.getAtlasExtension().getTBuildConfig().getInjectPkgs();\n                String newPath = originalPath(path);\n\n                if (pkgs.size() > 0) {\n                    for (String s : pkgs) {\n                        boolean matched = MatcherCreator.create(s).match(newPath);\n                        if (matched) {\n                            File file = TBIncrementalVisitor.instrumentClass(\n                                    targetPlatformApi.getFeatureLevel(),\n                                    inputDir,\n                                    inputFile,\n                                    outputDir,\n                                    TBIncrementalSupportVisitor.VISITOR_BUILDER,\n                                    LOGGER,\n                                    errorType -> {\n                                        errors.add(errorType.name() + \":\" + path);\n                                    },\n                                    variantContext.getAtlasExtension().getTBuildConfig().isInjectSerialVersionUID(), variantContext.getAtlasExtension().getTBuildConfig().isPatchConstructors(), variantContext.getAtlasExtension().getTBuildConfig().isPatchEachMethod(), variantContext.getAtlasExtension().getTBuildConfig().isSupportAddCallSuper(), variantContext.getAtlasExtension().getTBuildConfig().getPatchSuperMethodCount());\n                            if (file.length() == inputFile.length()) {\n                                errors.add(\"NO INJECT:\" + path);\n                            } else {\n                                success.add(\"SUCCESS INJECT:\" + path);\n                            }\n\n                            return null;\n                        }\n                    }\n\n                    File outputFile = new File(outputDir, path);\n                    try {\n                        Files.createParentDirs(outputFile);\n                        Files.copy(inputFile, outputFile);\n                        errors.add(\"NO INJECT:\" + path);\n                        return null;\n                    } catch (IOException e1) {\n                        e1.printStackTrace();\n                    }\n\n\n                } else {\n                    for (String s : excludePkgs) {\n                        boolean matched = MatcherCreator.create(s).match(newPath);\n                        if (matched) {\n                            File outputFile = new File(outputDir, path);\n                            try {\n                                Files.createParentDirs(outputFile);\n                                Files.copy(inputFile, outputFile);\n                                errors.add(\"NO INJECT:\" + path);\n                                return null;\n                            } catch (IOException e1) {\n                                e1.printStackTrace();\n                            }\n                        }\n\n                    }\n\n                    File file = TBIncrementalVisitor.instrumentClass(\n                            targetPlatformApi.getFeatureLevel(),\n                            inputDir,\n                            inputFile,\n                            outputDir,\n                            TBIncrementalSupportVisitor.VISITOR_BUILDER,\n                            LOGGER,\n                            errorType -> {\n                                errors.add(errorType.name() + \":\" + path);\n                            },\n                            variantContext.getAtlasExtension().getTBuildConfig().isInjectSerialVersionUID(), variantContext.getAtlasExtension().getTBuildConfig().isPatchConstructors(), variantContext.getAtlasExtension().getTBuildConfig().isPatchEachMethod(), variantContext.getAtlasExtension().getTBuildConfig().isSupportAddCallSuper(), variantContext.getAtlasExtension().getTBuildConfig().getPatchSuperMethodCount());\n                    if (file.length() == inputFile.length()) {\n                        errors.add(\"NO INJECT:\" + path);\n                    } else {\n                        success.add(\"SUCCESS INJECT:\" + path);\n                    }\n\n                }\n\n            } catch (Exception e) {\n                e.printStackTrace();\n                LOGGER.warning(\"exception instrumentClass:\" + inputFile.getPath());\n                errors.add(\"EXCEPTION:\" + path);\n                File outputFile = new File(outputDir, path);\n                try {\n                    Files.createParentDirs(outputFile);\n                    Files.copy(inputFile, outputFile);\n                } catch (IOException e1) {\n                    e1.printStackTrace();\n                }\n\n            }\n        }\n        return null;\n    }\n\n    private String originalPath(String path) {\n        String className = path.replace(\"/\", \".\").substring(0, path.length() - 6);\n        if (mappingReaderProcess.classMapping.size() == 0) {\n            return path;\n        } else {\n            String orign = mappingReaderProcess.classMapping.get(className);\n\n            if (orign == null || orign.equals(className)) {\n                return path;\n            }\n            return orign.replace(\".\", \"/\") + \".class\";\n        }\n    }\n\n    private File loadProguardFile() {\n        GlobalScope globalScope = variantContext.getScope().getGlobalScope();\n        File proguardOut = new File(Joiner.on(File.separatorChar).join(\n                String.valueOf(globalScope.getBuildDir()),\n                FD_OUTPUTS,\n                \"mapping\",\n                variantContext.getScope().getVariantConfiguration().getDirName()));\n\n        File printMapping = new File(proguardOut, \"mapping.txt\");\n\n        return printMapping;\n    }\n\n\n    protected void wrapUpOutputs(File classes2Folder, File classes3Folder)\n            throws IOException {\n\n        // the transform can set the verifier status to failure in some corner cases, in that\n        // case, make sure we delete our classes.3\n//        if (!transformScope.getInstantRunBuildContext().hasPassedVerification()) {\n//            FileUtils.cleanOutputDir(classes3Folder);\n//            return;\n//        }\n        // otherwise, generate the patch file and add it to the list of files to process next.\n        ImmutableList<String> generatedClassNames = generatedClasses3Names.build();\n        if (!generatedClassNames.isEmpty()) {\n            File patchClassInfo = new File(variantContext.getProject().getBuildDir(), \"outputs/patchClassInfo.json\");\n            org.apache.commons.io.FileUtils.writeStringToFile(patchClassInfo, JSON.toJSONString(modifyClasses));\n            modifyClasses.entrySet().forEach(stringStringEntry -> LOGGER.warning(stringStringEntry.getKey() + \":\" + stringStringEntry.getValue()));\n            writePatchFileContents(\n                    generatedClassNames,\n                    classes3Folder,\n                    transformScope.getInstantRunBuildContext().getBuildId());\n        }\n    }\n\n\n    private static void writePatchFileContents(\n            @NonNull ImmutableList<String> patchFileContents, @NonNull File outputDir, long buildId) {\n\n        ClassWriter cw = new ClassWriter(0);\n        MethodVisitor mv;\n\n        cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER,\n                TBIncrementalVisitor.ALI_APP_PATCHES_LOADER_IMPL, null,\n                TBIncrementalVisitor.ALI_ABSTRACT_PATCHES_LOADER_IMPL, null);\n\n        // Add the build ID to force the patch file to be repackaged.\n        cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL,\n                \"BUILD_ID\", \"J\", null, buildId);\n\n        {\n            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, \"<init>\", \"()V\", null, null);\n            mv.visitCode();\n            mv.visitVarInsn(Opcodes.ALOAD, 0);\n            mv.visitMethodInsn(Opcodes.INVOKESPECIAL,\n                    TBIncrementalVisitor.ALI_ABSTRACT_PATCHES_LOADER_IMPL,\n                    \"<init>\", \"()V\", false);\n            mv.visitInsn(Opcodes.RETURN);\n            mv.visitMaxs(1, 1);\n            mv.visitEnd();\n        }\n        {\n            mv = cw.visitMethod(Opcodes.ACC_PUBLIC,\n                    \"getPatchedClasses\", \"()[Ljava/lang/String;\", null, null);\n            mv.visitCode();\n            mv.visitIntInsn(Opcodes.BIPUSH, patchFileContents.size());\n            mv.visitTypeInsn(Opcodes.ANEWARRAY, \"java/lang/String\");\n            for (int index = 0; index < patchFileContents.size(); index++) {\n                mv.visitInsn(Opcodes.DUP);\n                mv.visitIntInsn(Opcodes.BIPUSH, index);\n                mv.visitLdcInsn(patchFileContents.get(index));\n                mv.visitInsn(Opcodes.AASTORE);\n            }\n            mv.visitInsn(Opcodes.ARETURN);\n            mv.visitMaxs(4, 1);\n            mv.visitEnd();\n        }\n        cw.visitEnd();\n\n        byte[] classBytes = cw.toByteArray();\n        File outputFile = new File(outputDir, TBIncrementalVisitor.ALI_APP_PATCHES_LOADER_IMPL + \".class\");\n        try {\n            Files.createParentDirs(outputFile);\n            Files.write(classBytes, outputFile);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n\n    public enum PatchPolicy {\n\n        ADD, MODIFY, NONE\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/matcher/AllMatcher.java",
    "content": "package com.taobao.android.builder.insant.matcher;\n\n/**\n * 创建日期：2018/11/23 on 下午3:03\n * 描述:\n * 作者:zhayu.ll\n */\npublic class AllMatcher implements Imatcher {\n\n    @Override\n    public boolean match(String s) {\n        return true;\n    }\n\n    @Override\n    public String rule() {\n        return \"**\";\n    }\n\n    @Override\n    public Imatcher superMatcher() {\n        return new AllMatcher();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/matcher/ClassMatcher.java",
    "content": "package com.taobao.android.builder.insant.matcher;\n\n/**\n * 创建日期：2018/11/23 on 下午3:01\n * 描述:\n * 作者:zhayu.ll\n */\npublic class ClassMatcher implements Imatcher {\n\n    private String mRule;\n    public ClassMatcher(String rule) {\n        this.mRule = rule;\n    }\n\n    @Override\n    public boolean match(String s) {\n        if(!s.endsWith(\".class\")){\n            return false;\n        }\n        String className = s.replace(\"/\", \".\").substring(0, s.length() - 6);\n\n        return mRule.equals(className);\n    }\n\n    @Override\n    public String rule() {\n        return mRule;\n    }\n\n    @Override\n    public Imatcher superMatcher() {\n\n        return new SubPackgeMatcher(mRule.substring(0,mRule.lastIndexOf(\".\"))+\".*\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/matcher/ExcludeMatcher.java",
    "content": "package com.taobao.android.builder.insant.matcher;\n\n/**\n * 创建日期：2018/11/23 on 下午4:11\n * 描述:\n * 作者:zhayu.ll\n */\npublic class ExcludeMatcher implements Imatcher {\n\n    private String mRule;\n\n    private Imatcher imatcher;\n\n    public ExcludeMatcher(String rule) {\n        this.mRule = rule;\n    }\n\n    @Override\n    public boolean match(String s) {\n        String tempRule = mRule.substring(1);\n        if (imatcher == null) {\n            imatcher = MatcherCreator.create(tempRule);\n        }\n\n        if (imatcher.match(s)) {\n            return false;\n        }\n\n       Imatcher sMatcher = imatcher.superMatcher();\n\n        if (sMatcher.match(s)){\n            return true;\n        }else {\n            return false;\n        }\n    }\n\n    @Override\n    public String rule() {\n        return mRule;\n    }\n\n    @Override\n    public Imatcher superMatcher() {\n        String tempRule = mRule.substring(1);\n        if (imatcher == null) {\n            imatcher = MatcherCreator.create(tempRule);\n        }\n        String superRule = imatcher.superMatcher().rule();\n\n        return new ExcludeMatcher(\"!\".concat(superRule));\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/matcher/Imatcher.java",
    "content": "package com.taobao.android.builder.insant.matcher;\n\n/**\n * 创建日期：2018/11/23 on 下午3:01\n * 描述:\n * 作者:zhayu.ll\n */\npublic interface Imatcher {\n\n        public boolean match(String s);\n\n        public  String rule();\n\n\n        public Imatcher superMatcher();\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/matcher/ImplementsMatcher.java",
    "content": "package com.taobao.android.builder.insant.matcher;\n\n/**\n * 创建日期：2019/1/13 on 上午11:13\n * 描述:\n * 作者:zhayu.ll\n */\npublic class ImplementsMatcher  implements Imatcher{\n\n    private String rule;\n\n    public ImplementsMatcher(String rule) {\n        this.rule = rule;\n    }\n\n    @Override\n    public boolean match(String s) {\n        String iFace = rule.substring(rule.indexOf(\"implements\")+11);\n        return iFace.equals(s.replace(\"/\",\".\"));\n    }\n\n    @Override\n    public String rule() {\n        return rule;\n    }\n\n    @Override\n    public Imatcher superMatcher() {\n        return null;\n    }\n\n    public Class<?> getClazz(ClassLoader classLoader) throws ClassNotFoundException {\n        String iFace = rule.substring(rule.indexOf(\"implements\")+11);\n        return Class.forName(iFace, false, classLoader);\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/matcher/MatcherCreator.java",
    "content": "package com.taobao.android.builder.insant.matcher;\n\nimport org.apache.commons.lang3.StringUtils;\n\nimport java.util.*;\n\n/**\n * 创建日期：2018/11/23 on 下午3:04\n * 描述:\n * 作者:zhayu.ll\n */\npublic class MatcherCreator {\n\n\n\n    static Set<ImplementsMatcher> matchers = new HashSet<>();\n\n    static Map<String, Imatcher> sMatchers = new LinkedHashMap<>();\n\n    public static Imatcher create(String rule) {\n        if (sMatchers.containsKey(rule)) {\n            return sMatchers.get(rule);\n        }\n        if (StringUtils.isEmpty(rule)) {\n            return new NoMatcher();\n        }\n\n        if (rule.equals(\"**\")) {\n            return new AllMatcher();\n        }\n        Imatcher imatcher = null;\n        if (rule.startsWith(\"!\")) {\n            imatcher = new ExcludeMatcher(rule);\n        } else if (rule.endsWith(\".**\")) {\n            imatcher = new PackageMatcher(rule);\n        } else if (rule.endsWith(\".*\")) {\n            imatcher = new SubPackgeMatcher(rule);\n        } else if (rule.startsWith(\"*\") && rule.contains(\"implements\")){\n            imatcher = new ImplementsMatcher(rule);\n            matchers.add((ImplementsMatcher) imatcher);\n        } else {\n            imatcher = new ClassMatcher(rule);\n        }\n\n        sMatchers.put(rule, imatcher);\n\n        return imatcher;\n\n    }\n\n    public static Set<ImplementsMatcher> getMatchers(){\n        return matchers;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/matcher/NoMatcher.java",
    "content": "package com.taobao.android.builder.insant.matcher;\n\n/**\n * 创建日期：2018/11/23 on 下午3:03\n * 描述:\n * 作者:zhayu.ll\n */\npublic class NoMatcher implements Imatcher {\n    @Override\n    public boolean match(String s) {\n        return false;\n    }\n\n    @Override\n    public String rule() {\n        return null;\n    }\n\n    @Override\n    public Imatcher superMatcher() {\n        return new NoMatcher();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/matcher/PackageMatcher.java",
    "content": "package com.taobao.android.builder.insant.matcher;\n\n/**\n * 创建日期：2018/11/23 on 下午3:02\n * 描述:\n * 作者:zhayu.ll\n */\npublic class PackageMatcher implements Imatcher {\n\n    private String rule;\n\n    public PackageMatcher(String rule) {\n        this.rule = rule;\n    }\n\n    @Override\n    public boolean match(String s) {\n        if (s.endsWith(\".class\")) {\n            String className = s.replace(\"/\", \".\").substring(0, s.length() - 6);\n            String tempRule = rule.substring(0, rule.lastIndexOf(\".\"));\n            if (className.startsWith(tempRule)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    @Override\n    public String rule() {\n        return rule;\n    }\n\n    @Override\n    public Imatcher superMatcher() {\n        String tempRule = rule.substring(0, rule.lastIndexOf(\".\"));\n        return new PackageMatcher(tempRule.substring(0,tempRule.lastIndexOf(\".\"))+\".**\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/matcher/SeveralExcludeMatcher.java",
    "content": "package com.taobao.android.builder.insant.matcher;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * 创建日期：2019/2/27 on 下午3:43\n * 描述:\n * 作者:zhayu.ll\n */\npublic class SeveralExcludeMatcher implements Imatcher {\n\n\n    private String rule;\n    List<ExcludeMatcher>excludeMatchers = new ArrayList<>();\n\n    public SeveralExcludeMatcher(String rule) {\n        this.rule = rule;\n        String[]rules = rule.split(\"\\\\|\");\n       for (int i = 0; i < rules.length; i ++){\n           if (i == 0){\n               excludeMatchers.add(new ExcludeMatcher(rules[i]));\n           }else {\n               excludeMatchers.add(new ExcludeMatcher(\"!\"+rules[i]));\n\n           }\n       }\n    }\n\n    @Override\n    public boolean match(String s) {\n        boolean hasMatched = false;\n        for (ExcludeMatcher excludeMatcher:excludeMatchers){\n            if (!excludeMatcher.match(s)){\n                return false;\n            }else {\n                hasMatched = true;\n            }\n        }\n\n\n        return hasMatched;\n    }\n\n    @Override\n    public String rule() {\n        return rule;\n    }\n\n    @Override\n    public Imatcher superMatcher() {\n        return null;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/matcher/SubPackgeMatcher.java",
    "content": "package com.taobao.android.builder.insant.matcher;\n\n/**\n * 创建日期：2018/11/23 on 下午3:02\n * 描述:\n * 作者:zhayu.ll\n */\npublic class SubPackgeMatcher implements Imatcher {\n\n    private String mRule;\n    public SubPackgeMatcher(String rule) {\n            this.mRule = rule;\n    }\n\n    @Override\n    public boolean match(String s) {\n        if (s.endsWith(\".class\")) {\n            String className = s.replace(\"/\", \".\").substring(0, s.length() - 6);\n            String tempRule = mRule.substring(0, mRule.lastIndexOf(\".\"));\n            if (className.substring(0, className.lastIndexOf(\".\")).equals(tempRule)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    @Override\n    public String rule() {\n        return mRule;\n    }\n\n    @Override\n    public Imatcher superMatcher() {\n        return null;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/visitor/ModifyClassVisitor.java",
    "content": "package com.taobao.android.builder.insant.visitor;\n\nimport com.taobao.android.builder.insant.TaobaoInstantRunTransform;\nimport com.android.build.gradle.internal.incremental.TBIncrementalVisitor;\nimport org.objectweb.asm.*;\n\n/**\n * 创建日期：2018/11/30 on 上午10:03\n * 描述:\n * 作者:zhayu.ll\n */\npublic class ModifyClassVisitor extends ClassVisitor {\n\n    private TaobaoInstantRunTransform.PatchPolicy[] patchPolicy;\n\n    public ModifyClassVisitor(int i, TaobaoInstantRunTransform.PatchPolicy[] patchingPolicy) {\n        super(i);\n        this.patchPolicy = patchingPolicy;\n    }\n\n        @Override\n        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {\n            super.visit(version, access, name, signature, superName, interfaces);\n        }\n\n        @Override\n        public void visitSource(String source, String debug) {\n            super.visitSource(source, debug);\n        }\n\n        @Override\n        public void visitOuterClass(String owner, String name, String desc) {\n            super.visitOuterClass(owner, name, desc);\n        }\n\n        @Override\n        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {\n            if (desc.equals(TBIncrementalVisitor.ADD_CLASS.getDescriptor()) && visible) {\n                patchPolicy[0] = TaobaoInstantRunTransform.PatchPolicy.ADD;\n            } else if (desc.equals(TBIncrementalVisitor.MODIFY_CLASS.getDescriptor()) && visible) {\n                patchPolicy[0] = TaobaoInstantRunTransform.PatchPolicy.MODIFY;\n            }\n            return super.visitAnnotation(desc, visible);\n        }\n\n        @Override\n        public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {\n            return super.visitTypeAnnotation(typeRef, typePath, desc, visible);\n        }\n\n        @Override\n        public void visitAttribute(Attribute attr) {\n            super.visitAttribute(attr);\n        }\n\n        @Override\n        public void visitInnerClass(String name, String outerName, String innerName, int access) {\n            super.visitInnerClass(name, outerName, innerName, access);\n        }\n\n        @Override\n        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {\n\n            FieldVisitor fv = super.visitField(access, name, desc, signature, value);\n\n            return new ModifyFieldVisitor(api, fv, patchPolicy);\n        }\n\n        @Override\n        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {\n\n            MethodVisitor mv = super.visitMethod(access,name,desc,signature,exceptions);\n\n            return new ModifyMethodVisitor(api,mv,patchPolicy);\n        }\n\n        @Override\n        public void visitEnd() {\n            super.visitEnd();\n        }\n    }\n\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/visitor/ModifyFieldVisitor.java",
    "content": "package com.taobao.android.builder.insant.visitor;\n\nimport com.taobao.android.builder.insant.TaobaoInstantRunTransform;\nimport com.android.build.gradle.internal.incremental.TBIncrementalVisitor;\nimport org.objectweb.asm.AnnotationVisitor;\nimport org.objectweb.asm.FieldVisitor;\nimport org.objectweb.asm.TypePath;\n\n/**\n * 创建日期：2018/11/30 on 上午10:02\n * 描述:\n * 作者:zhayu.ll\n */\npublic class ModifyFieldVisitor extends FieldVisitor {\n\n\n    private TaobaoInstantRunTransform.PatchPolicy[] py = new TaobaoInstantRunTransform.PatchPolicy[]{TaobaoInstantRunTransform.PatchPolicy.NONE};\n\n    public ModifyFieldVisitor(int api, FieldVisitor fv, TaobaoInstantRunTransform.PatchPolicy[] patchPolicy) {\n        super(api, fv);\n        this.py = patchPolicy;\n    }\n\n    @Override\n    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {\n        if (desc.equals(TBIncrementalVisitor.MODIFY_FIELD.getDescriptor()) && visible) {\n            py[0] = TaobaoInstantRunTransform.PatchPolicy.MODIFY;\n        }else if (desc.equals(TBIncrementalVisitor.ADD_FIELD.getDescriptor()) && visible){\n            throw new RuntimeException(\"add field is not support!\");\n        }\n\n        return super.visitAnnotation(desc, visible);\n    }\n\n    @Override\n    public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {\n\n        return super.visitTypeAnnotation(typeRef, typePath, desc, visible);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/insant/visitor/ModifyMethodVisitor.java",
    "content": "package com.taobao.android.builder.insant.visitor;\n\nimport com.taobao.android.builder.insant.TaobaoInstantRunTransform;\nimport com.android.build.gradle.internal.incremental.TBIncrementalVisitor;\nimport org.objectweb.asm.AnnotationVisitor;\nimport org.objectweb.asm.MethodVisitor;\n\n/**\n * 创建日期：2018/11/30 on 上午10:03\n * 描述:\n * 作者:zhayu.ll\n */\npublic class ModifyMethodVisitor extends MethodVisitor {\n\n    private TaobaoInstantRunTransform.PatchPolicy[] patchPolicy = new TaobaoInstantRunTransform.PatchPolicy[]{TaobaoInstantRunTransform.PatchPolicy.NONE};\n    public ModifyMethodVisitor(int api, MethodVisitor mv, TaobaoInstantRunTransform.PatchPolicy[] patchPolicy) {\n        super(api,mv);\n        this.patchPolicy = patchPolicy;\n    }\n\n    @Override\n    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {\n        if (desc.equals(TBIncrementalVisitor.MODIFY_METHOD.getDescriptor()) && visible) {\n            patchPolicy[0] = TaobaoInstantRunTransform.PatchPolicy.MODIFY;\n        }else if (desc.equals(TBIncrementalVisitor.ADD_METHOD.getDescriptor()) && visible){\n            throw new RuntimeException(\"add method is not support!\");\n        }\n        return super.visitAnnotation(desc, visible);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/manager/AtlasAppTaskManager.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.manager;\n\nimport com.android.SdkConstants;\nimport com.android.build.api.transform.QualifiedContent;\nimport com.android.build.gradle.AppExtension;\nimport com.android.build.gradle.api.ApplicationVariant;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.TaskContainerAdaptor;\nimport com.android.build.gradle.internal.TaskFactory;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.ApplicationVariantImpl;\nimport com.android.build.gradle.internal.api.BaseVariantOutputImpl;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.incremental.InstantRunPatchingPolicy;\nimport com.android.build.gradle.internal.pipeline.OriginalStream;\nimport com.android.build.gradle.internal.pipeline.TransformTask;\nimport com.android.build.gradle.internal.scope.GlobalScope;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.tasks.ExtractProguardFiles;\nimport com.android.build.gradle.internal.tasks.ExtractTryWithResourcesSupportJar;\nimport com.android.build.gradle.internal.transforms.*;\nimport com.android.build.gradle.options.BooleanOption;\nimport com.android.build.gradle.options.ProjectOptions;\nimport com.android.build.gradle.tasks.*;\nimport com.android.builder.core.AtlasBuilder;\nimport com.android.builder.core.DefaultDexOptions;\nimport com.android.builder.core.DexByteCodeConverter;\nimport com.android.builder.core.ErrorReporter;\nimport com.android.builder.dexing.DexingType;\nimport com.android.builder.sdk.TargetInfo;\nimport com.android.ide.common.build.ApkData;\nimport com.google.common.base.Supplier;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Sets;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.AtlasMainDexHelper;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.insant.DelegateProguardTransform;\nimport com.taobao.android.builder.tasks.PrepareAPTask;\nimport com.taobao.android.builder.tasks.app.*;\nimport com.taobao.android.builder.tasks.app.BuildAtlasEnvTask;\nimport com.taobao.android.builder.tasks.app.bundle.JavacAwbsTask;\nimport com.taobao.android.builder.tasks.app.bundle.PackageAwbsTask;\nimport com.taobao.android.builder.tasks.app.bundle.ProcessResAwbsTask;\nimport com.taobao.android.builder.tasks.app.databinding.AwbDataBindingExportBuildInfoTask;\nimport com.taobao.android.builder.tasks.app.databinding.AwbDataBindingMergeArtifactsTask;\nimport com.taobao.android.builder.tasks.app.databinding.AwbDataBindingRenameTask;\nimport com.taobao.android.builder.tasks.app.manifest.StandardizeLibManifestTask;\nimport com.taobao.android.builder.tasks.app.merge.*;\nimport com.taobao.android.builder.tasks.app.merge.bundle.MergeAwbAssets;\nimport com.taobao.android.builder.tasks.app.prepare.PrepareAaptTask;\nimport com.taobao.android.builder.tasks.app.prepare.PrepareBundleInfoTask;\nimport com.taobao.android.builder.tasks.app.prepare.PreparePackageIdsTask;\nimport com.taobao.android.builder.tasks.instantapp.AtlasBundleInstantApp;\nimport com.taobao.android.builder.tasks.manager.MtlTaskContext;\nimport com.taobao.android.builder.tasks.manager.MtlTaskInjector;\nimport com.taobao.android.builder.tasks.manager.transform.MtlTransformContext;\nimport com.taobao.android.builder.tasks.manager.transform.MtlTransformInjector;\nimport com.taobao.android.builder.tasks.manager.transform.TransformManager;\nimport com.taobao.android.builder.tasks.tpatch.DiffBundleInfoTask;\nimport com.taobao.android.builder.tasks.tpatch.TPatchDiffApkBuildTask;\nimport com.taobao.android.builder.tasks.tpatch.TPatchDiffResAPBuildTask;\nimport com.taobao.android.builder.tasks.tpatch.TPatchTask;\nimport com.taobao.android.builder.tasks.transform.AtlasDesugarTransform;\nimport com.taobao.android.builder.tasks.transform.AtlasProguardTransform;\nimport com.taobao.android.builder.tasks.transform.ClassInjectTransform;\nimport com.taobao.android.builder.tasks.transform.TransformReplacer;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport com.taobao.android.builder.tools.multidex.FastMultiDexer;\nimport groovy.lang.Closure;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.Action;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Project;\nimport org.gradle.api.Task;\nimport org.gradle.api.file.ConfigurableFileCollection;\nimport org.gradle.api.file.FileCollection;\nimport org.gradle.api.file.FileTree;\nimport org.gradle.api.internal.AbstractTask;\nimport org.gradle.api.internal.file.AbstractFileCollection;\nimport org.gradle.api.internal.tasks.TaskExecuter;\nimport org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter;\nimport org.gradle.api.specs.Spec;\nimport org.gradle.api.tasks.StopExecutionException;\nimport org.gradle.api.tasks.TaskCollection;\nimport org.gradle.api.tasks.TaskDependency;\nimport org.gradle.api.tasks.compile.JavaCompile;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.UncheckedIOException;\nimport java.lang.reflect.Field;\nimport java.util.*;\nimport java.util.function.Consumer;\n\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactScope.ALL;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactType.JAR;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ConsumedConfigType.ANNOTATION_PROCESSOR;\n\n/**\n * MTLThe plug-in compiles apk's task management\n * Created by shenghua.nish on 2016-05-09 3:55 in the afternoon.\n */\n@SuppressWarnings(\"ALL\")\npublic class AtlasAppTaskManager extends AtlasBaseTaskManager {\n\n    private AppExtension appExtension;\n\n    public AtlasAppTaskManager(AtlasBuilder androidBuilder, AppExtension appExtension, Project project,\n                               AtlasExtension atlasExtension) {\n        super(androidBuilder, appExtension, project, atlasExtension);\n        this.appExtension = appExtension;\n    }\n\n    @Override\n    public void runTask() {\n\n        appExtension.getApplicationVariants().forEach(new Consumer<ApplicationVariant>() {\n\n                                                          @Override\n                                                          public void accept(ApplicationVariant applicationVariant) {\n\n\n                                                              AppVariantContext appVariantContext = AtlasBuildContext.sBuilderAdapter.appVariantContextFactory\n                                                                      .getAppVariantContext(project, applicationVariant);\n                                                              if (!AtlasBuildContext.atlasMainDexHelperMap.containsKey(appVariantContext.getVariantName())){\n                                                                  AtlasBuildContext.atlasMainDexHelperMap.put(appVariantContext.getVariantName(),new AtlasMainDexHelper());\n                                                              }\n\n                                                              TransformReplacer transformReplacer = new TransformReplacer(appVariantContext);\n\n                                                              repalceAndroidBuilder(applicationVariant);\n\n                                                              List<MtlTaskContext> mtlTaskContextList = new ArrayList<MtlTaskContext>();\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(appVariantContext.getVariantData().preBuildTask));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(BuildAtlasEnvTask.ConfigAction.class, null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(ScanDupResTask.ConfigActon.class,null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(LogDependenciesTask.ConfigAction.class, null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(PrepareAPTask.ConfigAction.class, null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(appVariantContext.getVariantData().mergeAssetsTask));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(RenderscriptCompile.class));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(StandardizeLibManifestTask.ConfigAction.class, null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(PrepareBundleInfoTask.ConfigAction.class, null));\n\n                                                              if (!atlasExtension.getTBuildConfig().getClassInject() && atlasExtension.isAtlasEnabled()) {\n                                                                  mtlTaskContextList.add(new MtlTaskContext(GenerateAtlasSourceTask.ConfigAction.class, null));\n                                                              }\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(PreparePackageIdsTask.ConfigAction.class, null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(PrepareAaptTask.ConfigAction.class, null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(AidlCompile.class));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(GenerateBuildConfig.class));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(MergeResAwbsConfigAction.class, null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(MergeAssetAwbsConfigAction.class, null));\n\n                                                              if (null != androidExtension.getDataBinding() && androidExtension.getDataBinding().isEnabled() && !appVariantContext.getAtlasExtension().getTBuildConfig().getAllBundlesToMdex()) {\n\n//                                                                  mtlTaskContextList.add(\n//                                                                          new MtlTaskContext(AwbDataBindingProcessLayoutTask.ConfigAction.class, null));\n                                                                  mtlTaskContextList.add(\n                                                                          new MtlTaskContext(AwbDataBindingExportBuildInfoTask.ConfigAction.class, null));\n                                                                  mtlTaskContextList.add(\n                                                                          new MtlTaskContext(AwbDataBindingMergeArtifactsTask.ConfigAction.class, null));\n\n\n                                                              }\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(MergeManifests.class));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(MergeManifestAwbsConfigAction.class, null));\n\n                                                              //mtlTaskContextList.add(new MtlTaskContext(MergeResV4Dir.ConfigAction.class, null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(ProcessAndroidResources.class));\n\n                                                              ProcessAndroidResources processAndroidResources\n                                                                      = appVariantContext.getScope()\n                                                                      .getProcessResourcesTask()\n                                                                      .get(new TaskContainerAdaptor(appVariantContext.getProject()\n                                                                              .getTasks()));\n                                                              if (processAndroidResources.isAapt2Enabled()) {\n                                                                  processAndroidResources.doLast(new Action<Task>() {\n                                                                      @Override\n                                                                      public void execute(Task task) {\n                                                                          File processResourcePackageOutputDirectory\n                                                                                  = appVariantContext.getScope()\n                                                                                  .getProcessResourcePackageOutputDirectory();\n                                                                          File[] files\n                                                                                  = processResourcePackageOutputDirectory.listFiles(\n                                                                                  (file, name) -> name.endsWith(SdkConstants.DOT_RES));\n                                                                          for (File file : files) {\n                                                                              try {\n                                                                                  ResourcePatch.makePatchable(file);\n                                                                              } catch (IOException e) {\n                                                                                  throw new UncheckedIOException(e);\n                                                                              }\n                                                                          }\n                                                                      }\n                                                                  });\n                                                              }\n                                                              mtlTaskContextList.add(new MtlTaskContext(ProcessResAwbsTask.ConfigAction.class, null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(JavacAwbsTask.ConfigAction.class, null));\n\n\n                                                              if (null != androidExtension.getDataBinding() && androidExtension.getDataBinding().isEnabled() && !appVariantContext.getAtlasExtension().getTBuildConfig().getAllBundlesToMdex()) {\n                                                                  mtlTaskContextList.add(new MtlTaskContext(AwbDataBindingRenameTask.ConfigAction.class, null));\n                                                              }\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(TransformTask.class));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(PackageAwbsTask.ConfigAction.class, null));\n\n                                                              if (appVariantContext.getAtlasExtension().getTBuildConfig().isIncremental() && (\n                                                                      appVariantContext.getBuildType().getPatchConfig() == null || !appVariantContext.getBuildType()\n                                                                              .getPatchConfig().isCreateTPatch())) {\n//                                                                  mtlTaskContextList.add(new MtlTaskContext(PrepareBaseApkTask.ConfigAction.class, null));\n                                                                  final TaskFactory tasks = new TaskContainerAdaptor(project.getTasks());\n                                                                  VariantScope variantScope = appVariantContext.getVariantData().getScope();\n\n\n                                                                  // create the stream generated from this task\n                                                                  variantScope.getTransformManager().addStream(OriginalStream.builder(project, applicationVariant.getName()).addContentType(\n                                                                          QualifiedContent.DefaultContentType.RESOURCES).addScope(QualifiedContent.Scope.PROJECT)\n                                                                          .setFolders(new Supplier<Collection<File>>() {\n                                                                              @Override\n                                                                              public Collection<File> get() {\n                                                                                  return ImmutableList.of(new File(\n                                                                                          appVariantContext.apContext\n                                                                                                  .getBaseApk() + \"_\"));\n                                                                              }\n                                                                          })\n                                                                          .build());\n                                                              }\n\n\n                                                              final TaskFactory tasks = new TaskContainerAdaptor(project.getTasks());\n                                                              VariantScope variantScope = appVariantContext.getVariantData().getScope();\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(PackageApplication.class));\n\n                                                              if (appVariantContext.getAtlasExtension().isInstantAppEnabled()) {\n\n                                                                  mtlTaskContextList.add(new MtlTaskContext(AtlasBundleInstantApp.ConfigAction.class, null));\n                                                              }\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(ApBuildTask.ConfigAction.class, null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(DiffBundleInfoTask.ConfigAction.class, null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(TPatchDiffResAPBuildTask.ConfigAction.class, null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(TPatchDiffApkBuildTask.ConfigAction.class, null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(TPatchTask.ConfigAction.class, null));\n\n                                                              mtlTaskContextList.add(new MtlTaskContext(\"assemble\"));\n\n                                                              new MtlTaskInjector(appVariantContext).injectTasks(mtlTaskContextList, tAndroidBuilder);\n\n                                                              List<MtlTransformContext> mtlTransformContextList = new ArrayList<MtlTransformContext>();\n\n                                                              if (atlasExtension.getTBuildConfig().getClassInject()) {\n                                                                  mtlTransformContextList.add(\n                                                                          new MtlTransformContext(ClassInjectTransform.class, ProGuardTransform.class,\n                                                                                  DexTransform.class));\n                                                              }\n                                                              if (variantScope.getInstantRunBuildContext().isInInstantRunMode() && appVariantContext.getVariantConfiguration().getBuildType().isMinifyEnabled()){\n                                                                  mtlTransformContextList.add(\n                                                                          new MtlTransformContext(DelegateProguardTransform.class, ExtractJarsTransform.class,\n                                                                                  InstantRunTransform.class));\n                                                              }\n\n\n                                                              if (!mtlTransformContextList.isEmpty()) {\n                                                                  new MtlTransformInjector(appVariantContext).injectTasks(mtlTransformContextList);\n                                                              }\n                                                              Collection<BaseVariantOutput> baseVariantOutputDataList = appVariantContext.getVariantOutputData();\n\n                                                              boolean multiDexEnabled = appVariantContext.getVariantData().getVariantConfiguration().isMultiDexEnabled();\n\n                                                              if (atlasExtension.getTBuildConfig().isAtlasMultiDex() && multiDexEnabled) {\n                                                                  transformReplacer.replaceMultiDexListTransform();\n                                                              }\n\n\n                                                              transformReplacer.replaceProguardTransform();\n\n                                                              transformReplacer.disableCache();\n\n\n                                                              if (variantScope.getGlobalScope().getExtension().getDataBinding().isEnabled() && !appVariantContext.getAtlasExtension().getTBuildConfig().getAllBundlesToMdex()) {\n                                                                  transformReplacer.replaceDataBindingMergeArtifactsTransform();\n                                                              }\n\n                                                              for (final BaseVariantOutput vod : baseVariantOutputDataList) {\n                                                                  transformReplacer.replaceFixStackFramesTransform(vod);\n                                                                  transformReplacer.replaceDesugarTransform(vod);\n                                                                  transformReplacer.replaceDexArchiveBuilderTransform(vod);\n                                                                  transformReplacer.replaceDexExternalLibMerge(vod);\n                                                                  transformReplacer.replaceDexMerge(vod);\n                                                                  transformReplacer.replaceDexTransform(appVariantContext, vod);\n                                                                  transformReplacer.replaceShrinkResourcesTransform();\n                                                                  transformReplacer.replaceMergeJavaResourcesTransform(appVariantContext, vod);\n                                                                  transformReplacer.repalaceSomeInstantTransform(vod);\n\n                                                                  if (atlasExtension.getTBuildConfig().isIncremental()) {\n                                                                      InstantRunPatchingPolicy patchingPolicy = variantScope.getInstantRunBuildContext()\n                                                                              .getPatchingPolicy();\n                                                                      BaseVariantOutputImpl variantOutput = (BaseVariantOutputImpl) vod;\n                                                                      ApkData data = ApkDataUtils.get(variantOutput);\n                                                                      AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n                                                                              variantScope.getFullVariantName());\n\n//\n                                                                  }\n\n                                                              }\n\n\n\n//                                                              Boolean includeCompileClasspath =\n//                                                                      appVariantContext.getScope().getVariantConfiguration()\n//                                                                              .getJavaCompileOptions()\n//                                                                              .getAnnotationProcessorOptions()\n//                                                                              .getIncludeCompileClasspath();\n\n//                                                              appVariantContext.getVariantData().javaCompilerTask.doFirst(task -> {\n//                                                                  JavaCompile compile = (JavaCompile) task;\n//                                                                  Set<File> mainDexFiles = new MainFilesCollection(appVariantContext.getVariantName()).getFiles();\n//                                                                  FileCollection mainFiles = appVariantContext.getProject().files(mainDexFiles);\n//                                                                  FileCollection files = appVariantContext.getScope().getArtifactFileCollection(ANNOTATION_PROCESSOR, ALL, JAR);\n//                                                                  FileCollection bootFiles = appVariantContext.getProject().files(appVariantContext.getScope().getGlobalScope().getAndroidBuilder().getBootClasspath(false));\n//                                                                  mainFiles = mainFiles.plus(bootFiles);\n//                                                                  FileCollection fileCollection = compile.getClasspath();\n//                                                                  File kotlinClasses = null;\n//                                                                  for (File file : fileCollection) {\n//                                                                      if (file.getAbsolutePath().contains(\"kotlin-classes\")) {\n//                                                                          mainFiles = mainFiles.plus(appVariantContext.getProject().files(file));\n//                                                                          kotlinClasses = file;\n//                                                                          break;\n//                                                                      }\n//                                                                  }\n//                                                                  compile.setClasspath(mainFiles);\n//                                                                  if (Boolean.TRUE.equals(includeCompileClasspath)) {\n//                                                                      compile.getOptions().setAnnotationProcessorPath(files.plus(mainFiles));\n//                                                                  }\n//                                                              });\n\n                                                              appVariantContext.getVariantData().javaCompilerTask.doLast(new Action<Task>() {\n                                                                  @Override\n                                                                  public void execute(Task task) {\n                                                                      JavaCompile compile = (JavaCompile) task;\n                                                                      AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).getInputDirs().add(compile.getDestinationDir());\n                                                                  }\n                                                              });\n\n                                                              PackageAndroidArtifact packageAndroidArtifact = appVariantContext.getVariantData().getTaskByType(PackageAndroidArtifact.class);\n                                                              if (packageAndroidArtifact != null) {\n                                                                  ReflectUtils.updateField(packageAndroidArtifact, \"javaResourceFiles\", new AbstractFileCollection() {\n                                                                      @Override\n                                                                      public String getDisplayName() {\n                                                                          return \"java-merge-res.jar\";\n                                                                      }\n\n                                                                      @Override\n                                                                      public Set<File> getFiles() {\n                                                                          if (AtlasBuildContext.atlasMainDexHelperMap.get(packageAndroidArtifact.getVariantName()).getMainJavaRes() == null) {\n                                                                              return Sets.newHashSet();\n                                                                          }\n                                                                          return Sets.newHashSet(AtlasBuildContext.atlasMainDexHelperMap.get(packageAndroidArtifact.getVariantName()).getMainJavaRes());\n                                                                      }\n                                                                  });\n                                                              }\n\n                                                              TaskCollection<ExtractTryWithResourcesSupportJar>taskCollection = appVariantContext.getProject().getTasks().withType(ExtractTryWithResourcesSupportJar.class);\n                                                              for (ExtractTryWithResourcesSupportJar task : taskCollection) {\n                                                                  task.doLast(new Action<Task>() {\n                                                                      @Override\n                                                                      public void execute(Task task) {\n                                                                          ConfigurableFileCollection fileCollection = variantScope.getTryWithResourceRuntimeSupportJar();\n                                                                          for (File file : fileCollection.getFiles()) {\n                                                                              if (file.exists()) {\n                                                                                  AtlasBuildContext.atlasMainDexHelperMap.get(variantScope.getFullVariantName()).addMainDex(new BuildAtlasEnvTask.FileIdentity(\"runtime-deps-try-with-resources\", file, false, false));\n                                                                                  break;\n                                                                              }\n                                                                          }\n                                                                      }\n                                                                  });\n\n                                                              }\n                                                          }\n                                                      }\n        );\n    }\n\n\n\n\n\n\n    private void repalceAndroidBuilder(ApplicationVariant applicationVariant) {\n        try {\n            if (applicationVariant instanceof ApplicationVariantImpl) {\n                VariantScope variantScope = ((ApplicationVariantImpl) applicationVariant).getVariantData().getScope();\n                GlobalScope globalScope = variantScope.getGlobalScope();\n//                ReflectUtils.updateField(globalScope, \"androidBuilder\", AtlasBuildContext.androidBuilderMap.get(globalScope.getProject()));\n//                Field f = ProjectOptions.class.getDeclaredField(\"booleanOptions\");\n//                f.setAccessible(true);\n//                Map map = (Map) f.get(((ApplicationVariantImpl) applicationVariant).getVariantData().getScope().getGlobalScope().getProjectOptions());\n//                map.put(BooleanOption.ENABLE_AAPT2, false);\n                AtlasBuildContext.androidBuilderMap.get(globalScope.getProject()).initAapt(globalScope.getProjectOptions());\n\n            }\n        } catch (Exception e) {\n            logger.error(e, \"write globalScope androidBuilder field failed!\");\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/manager/AtlasBaseTaskManager.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.manager;\n\nimport com.android.build.gradle.BaseExtension;\nimport com.android.build.gradle.internal.ExtraModelInfo;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.TaskContainerAdaptor;\nimport com.android.build.gradle.internal.scope.AndroidTaskRegistry;\nimport com.android.build.gradle.options.ProjectOptions;\nimport com.android.builder.core.AtlasBuilder;\nimport com.android.utils.ILogger;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport com.taobao.android.builder.tools.asm.field.Field;\nimport org.gradle.api.Project;\nimport org.gradle.api.internal.tasks.TaskExecuter;\nimport org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter;\nimport org.gradle.api.logging.Logging;\n\n/**\n * Base classes for task management\n * Created by shenghua.nish on 2016-05-10 9:51 in the afternoon.\n */\npublic abstract class AtlasBaseTaskManager<T extends BaseExtension> {\n\n    protected final AtlasBuilder tAndroidBuilder;\n\n    protected final T androidExtension;\n\n    protected final Project project;\n\n    protected final AndroidTaskRegistry androidTasks = new AndroidTaskRegistry();\n\n    protected final TaskContainerAdaptor tasks;\n\n    protected final AtlasExtension atlasExtension;\n\n    protected ExtraModelInfo extraModelInfo;\n\n    protected ILogger logger;\n\n    //protected DependencyManager dependencyManager;\n\n    public AtlasBaseTaskManager(AtlasBuilder androidBuilder, T androidExtension, Project project,\n                                AtlasExtension atlasExtension) {\n        this.tAndroidBuilder = androidBuilder;\n        this.androidExtension = androidExtension;\n        this.project = project;\n        this.tasks = new TaskContainerAdaptor(project.getTasks());\n        this.atlasExtension = atlasExtension;\n        this.logger = new LoggerWrapper(Logging.getLogger(AtlasBaseTaskManager.class));\n        this.extraModelInfo = new ExtraModelInfo(new ProjectOptions(project), Logging.getLogger(AtlasBaseTaskManager.class));\n\n        //this.dependencyManager = new DependencyManager(androidExtension, project, atlasExtension);\n    }\n\n    public void run() {\n\n        resolveDependencies();\n\n        //Initialization configuration\n        parseConfig();\n\n        runTask();\n    }\n\n    protected void resolveDependencies() {\n        //this.dependencyManager.resolveDependencies();\n    }\n\n    /**\n     * Run the inject task haob\n     */\n    public abstract void runTask();\n\n    /**\n     * Parse configuration file\n     */\n    public void parseConfig() {\n\n    }\n\n    protected<V extends TaskExecuter> V getExecuteActionsTaskExecuter(TaskExecuter taskExecuter,Class<V>clazz) {\n        if (taskExecuter == null){\n            return null;\n        }\n        while (get(taskExecuter).getClass()!=clazz){\n\n              taskExecuter = get(taskExecuter);\n        }\n        return (V) get(taskExecuter);\n\n    }\n\n    private TaskExecuter get(TaskExecuter taskExecuter) {\n        Object object = ReflectUtils.getField(taskExecuter, \"executer\");\n        if (object == null) {\n            object = ReflectUtils.getField(taskExecuter, \"delegate\");\n        }\n        if (object == null){\n            return taskExecuter;\n        }\n        return (TaskExecuter) object;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/manager/AtlasConfigurationHelper.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.manager;\n\nimport com.android.build.gradle.*;\nimport com.android.build.gradle.internal.AtlasDependencyManager;\nimport com.android.build.gradle.internal.ExtraModelInfo;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.VariantManager;\nimport com.android.build.gradle.internal.dependency.AarTransform;\nimport com.android.build.gradle.internal.dependency.LibrarySymbolTableTransform;\nimport com.android.build.gradle.internal.process.GradleJavaProcessExecutor;\nimport com.android.build.gradle.internal.process.GradleProcessExecutor;\nimport com.android.build.gradle.internal.publishing.AndroidArtifacts;\nimport com.android.build.gradle.internal.publishing.AtlasAndroidArtifacts;\nimport com.android.build.gradle.internal.transforms.*;\nimport com.android.build.gradle.options.ProjectOptions;\nimport com.android.builder.core.AndroidBuilder;\nimport com.android.builder.core.AtlasBuilder;\nimport com.android.builder.core.ErrorReporter;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.AtlasFeaturePlugin;\nimport com.taobao.android.builder.AtlasPlugin;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.extension.TBuildConfig;\nimport com.taobao.android.builder.hook.AppPluginHook;\nimport com.taobao.android.builder.tools.PluginTypeUtils;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport org.apache.commons.io.FileUtils;\nimport org.codehaus.groovy.runtime.DefaultGroovyMethods;\nimport org.gradle.api.Action;\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.Configuration;\nimport org.gradle.api.artifacts.dsl.DependencyHandler;\nimport org.gradle.internal.reflect.Instantiator;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.function.Consumer;\n\nimport static org.gradle.api.internal.artifacts.ArtifactAttributes.ARTIFACT_FORMAT;\n\n/**\n * Created by wuzhong on 2017/3/7.\n *\n * @author wuzhong zhayu.ll\n * @date 2017/03/07\n */\npublic class AtlasConfigurationHelper {\n\n    private final AppPluginHook appPluginHook;\n\n    public AtlasConfigurationHelper(Project project, Instantiator instantiator, String creator) {\n        this.project = project;\n        this.instantiator = instantiator;\n        this.creator = creator;\n\n        this.appPluginHook = new AppPluginHook(project);\n    }\n\n    public void createLibCompenents() {\n\n        Configuration compileConfiguration = project.getConfigurations()\n                .getByName(COMPILE_CONFIGURATION_NAME);\n        Configuration archivesConfiguration = project.getConfigurations()\n                .getByName(ARCHIVES_CONFIGURATION_NAME);\n        Configuration compileProjectConfiguration = project.getConfigurations()\n                .findByName(COMPILE_PROJECT_CONFIGURATION_NAME);\n\n//        Configuration defaultConfiguration = project.getConfigurations().findByName(DEFAULT);\n\n        if (compileProjectConfiguration == null) {\n            project.getConfigurations().create(COMPILE_PROJECT_CONFIGURATION_NAME, configuration -> configuration.extendsFrom(compileConfiguration, archivesConfiguration));\n        }\n\n//        project.getComponents()\n//                .add(new AndroidComponent(compileConfiguration,\n//                                          compileConfiguration.getAllDependencies()));\n\n        //add provided compile\n        if (null == project.getConfigurations().findByName(AtlasPlugin.PROVIDED_COMPILE)) {\n            project.getConfigurations()\n                    .create(AtlasPlugin.PROVIDED_COMPILE, config -> compileConfiguration.extendsFrom(config));\n\n        }\n\n        //project.getConfigurations().create(AtlasPlugin.BUNDLE_COMPILE);\n        //Configuration providedConfiguration = project.getConfigurations().getByName(\"provided\");\n        project.getConfigurations().create(AtlasPlugin.BUNDLE_COMPILE, new Action<Configuration>() {\n            @Override\n            public void execute(Configuration config) {\n                compileConfiguration.extendsFrom(config);\n            }\n        }).setTransitive(true);\n    }\n\n    /**\n     * Set the extension value for the plug-in , Set special dependency entry\n     **/\n    public AtlasExtension createExtendsion() {\n\n        this.atlasExtension = AtlasBuildContext.sBuilderAdapter.extensionFactory.createExtendsion(\n                project,\n                instantiator);\n\n        return atlasExtension;\n    }\n\n//    public void hookAtlasDependencyManager() {\n//\n//        try {\n//            this.appPluginHook.replaceTaskManager();\n//        } catch (Exception e) {\n//            throw new GradleException(e.getMessage(), e);\n//        }\n//    }\n\n    /**\n     * Set the necessary default parameters for atlas\n     */\n    public void updateExtensionAfterEvaluate() {\n\n        if (atlasExtension.isAtlasEnabled() && !(project.getPlugins().hasPlugin(FeaturePlugin.class) || project.getPlugins().hasPlugin(AtlasFeaturePlugin.class))) {\n            TBuildConfig tBuildConfig = atlasExtension.getTBuildConfig();\n            //            tBuildConfig.setAaptConstantId(false);\n            //tBuildConfig.setClassInject(true);\n            // tBuildConfig.setCreateAP(true);\n            tBuildConfig.setUseCustomAapt(true);\n            atlasExtension.getManifestOptions().setAddMultiDexMetaData(true);\n            //atlasExtension.getManifestOptions().setAddBundleLocation(true);\n            atlasExtension.getManifestOptions().setReplaceApplication(true);\n        } else {\n            atlasExtension.getManifestOptions().setReplaceApplication(false);\n        }\n    }\n\n    public void createBuilderAfterEvaluate() throws Exception {\n\n        AndroidBuilder androidBuilder = appPluginHook.getAndroidBuilder();\n\n        if (null == androidBuilder) {\n            return;\n        }\n\n        AndroidBuilder atlasBuilder = new AtlasBuilder(project.equals(project.getRootProject()) ? project\n                .getName() : project.getPath(),\n                creator,\n                new GradleProcessExecutor(project),\n                new GradleJavaProcessExecutor(project),\n                DefaultGroovyMethods.asType(ReflectUtils.getField(\n                        androidBuilder,\n                        \"mErrorReporter\"),\n                        ErrorReporter.class),\n                LoggerWrapper.getLogger(AtlasBuilder.class),\n                DefaultGroovyMethods.asType(ReflectUtils.getField(\n                        androidBuilder,\n                        \"mVerboseExec\"), Boolean.class));\n\n        ((AtlasBuilder) atlasBuilder).setDefaultBuilder(androidBuilder);\n        ((AtlasBuilder) atlasBuilder).setAtlasExtension(atlasExtension);\n        AtlasBuildContext.androidBuilderMap.put(project, (AtlasBuilder) (atlasBuilder));\n    }\n\n    public void configTasksAfterEvaluate() {\n\n        if (PluginTypeUtils.isAppProject(project)) {\n            AppExtension appExtension = DefaultGroovyMethods.asType(DefaultGroovyMethods.getAt(\n                    project.getExtensions(),\n                    \"android\"), AppExtension.class);\n            new AtlasAppTaskManager(AtlasBuildContext.androidBuilderMap.get(project),\n                    appExtension,\n                    project,\n                    atlasExtension).run();\n        } else if (PluginTypeUtils.isLibraryProject(project)) {\n            LibraryExtension libExtension = DefaultGroovyMethods.asType(DefaultGroovyMethods.getAt(\n                    project.getExtensions(),\n                    \"android\"), LibraryExtension.class);\n            new AtlasLibTaskManager(AtlasBuildContext.androidBuilderMap.get(project),\n                    libExtension,\n                    project,\n                    atlasExtension).run();\n        } else if (PluginTypeUtils.isFeatureProject(project)) {\n            LibraryExtension featureExtension = DefaultGroovyMethods.asType(DefaultGroovyMethods.getAt(\n                    project.getExtensions(),\n                    \"android\"), FeatureExtension.class);\n            new AtlasFeatureTaskManager(AtlasBuildContext.androidBuilderMap.get(project),\n                    featureExtension,\n                    project,\n                    atlasExtension).run();\n        }\n    }\n\n    public Project getProject() {\n        return project;\n    }\n\n    public void setProject(Project project) {\n        this.project = project;\n    }\n\n    public Instantiator getInstantiator() {\n        return instantiator;\n    }\n\n    public void setInstantiator(Instantiator instantiator) {\n        this.instantiator = instantiator;\n    }\n\n    public String getCreator() {\n        return creator;\n    }\n\n    public void setCreator(String creator) {\n        this.creator = creator;\n    }\n\n    private Project project;\n\n    private Instantiator instantiator;\n\n    private String creator;\n\n    public static final String COMPILE_CONFIGURATION_NAME = \"compile\";\n\n    public static final String ARCHIVES_CONFIGURATION_NAME = \"archives\";\n\n    public static final String DEFAULT = \"default\";\n\n\n    public static final String COMPILE_PROJECT_CONFIGURATION_NAME = \"compileProject\";\n\n\n    protected AtlasExtension atlasExtension;\n\n//    public void configDexPatchTasksAfterEvaluate() {\n//        if (PluginTypeUtils.isAppProject(project)) {\n//            AppExtension appExtension = DefaultGroovyMethods.asType(DefaultGroovyMethods.getAt(\n//                    project.getExtensions(),\n//                    \"android\"), AppExtension.class);\n//            new DexPatchTaskManager(AtlasBuildContext.androidBuilderMap.get(project),\n//                    appExtension,\n//                    project,\n//                    atlasExtension).run();\n//        }\n//\n//    }\n\n    public void registAtlasStreams() {\n\n        DependencyHandler dependencyHandler = project.getDependencies();\n\n        final String explodedAwbType = AtlasAndroidArtifacts.TYPE_EXPLODED_AWB;\n\n        final String explodedApType = AtlasAndroidArtifacts.TYPE_EXPLODED_AP;\n\n        final String explodedSolibType = AtlasAndroidArtifacts.TYPE_EXPLODED_SOLIB;\n\n        dependencyHandler.registerTransform(\n                reg -> {\n                    reg.getFrom().attribute(ARTIFACT_FORMAT, AtlasAndroidArtifacts.TYPE_AWB);\n                    reg.getTo().attribute(ARTIFACT_FORMAT, explodedAwbType);\n                    reg.artifactTransform(ExtractAwbTransform.class);\n                });\n\n        for (AndroidArtifacts.ArtifactType transformTarget : AarTransform.getTransformTargets()) {\n            dependencyHandler.registerTransform(\n                    reg -> {\n                        reg.getFrom().attribute(ARTIFACT_FORMAT, explodedAwbType);\n                        reg.getTo().attribute(ARTIFACT_FORMAT, transformTarget.getType());\n                        reg.artifactTransform(\n                                AarTransform.class, config -> config.params(transformTarget));\n                    });\n        }\n\n        dependencyHandler.registerTransform(\n                reg -> {\n                    reg.getFrom().attribute(ARTIFACT_FORMAT, explodedAwbType);\n                    reg.getTo()\n                            .attribute(\n                                    ARTIFACT_FORMAT,\n                                    AndroidArtifacts.ArtifactType.SYMBOL_LIST_WITH_PACKAGE_NAME.getType());\n                    reg.artifactTransform(LibrarySymbolTableTransform.class);\n                });\n        dependencyHandler.registerTransform(\n\n                reg -> {\n                    reg.getFrom().attribute(ARTIFACT_FORMAT, AtlasAndroidArtifacts.TYPE_AP);\n                    reg.getTo().attribute(ARTIFACT_FORMAT, explodedApType);\n                    reg.artifactTransform(ExtractApTransform.class);\n                });\n\n        dependencyHandler.registerTransform(\n                reg -> {\n                    reg.getFrom().attribute(ARTIFACT_FORMAT, AtlasAndroidArtifacts.TYPE_SOLIB);\n                    reg.getTo().attribute(ARTIFACT_FORMAT, explodedSolibType);\n                    reg.artifactTransform(ExtractSolibTransform.class);\n                });\n\n        dependencyHandler.registerTransform(\n                reg -> {\n                    reg.getFrom().attribute(ARTIFACT_FORMAT, explodedSolibType);\n                    reg.getTo().attribute(ARTIFACT_FORMAT, AndroidArtifacts.ArtifactType.JNI.getType());\n                    reg.artifactTransform(LoadSolibTransform.class);\n                });\n\n        dependencyHandler.registerTransform(\n                reg -> {\n                    reg.getFrom().attribute(ARTIFACT_FORMAT, explodedAwbType);\n                    reg.getTo().attribute(ARTIFACT_FORMAT, AtlasAndroidArtifacts.TYPE_LIBS);\n                    reg.artifactTransform(LoadSolibFromLibsTransform.class);\n                }\n        );\n\n        dependencyHandler.registerTransform(\n                reg -> {\n                    reg.getFrom().attribute(ARTIFACT_FORMAT, AtlasAndroidArtifacts.AtlasArtifactType.EXPLODED_AAR.getType());\n                    reg.getTo().attribute(ARTIFACT_FORMAT, AtlasAndroidArtifacts.TYPE_LIBS);\n                    reg.artifactTransform(LoadSolibFromLibsTransform.class);\n                }\n        );\n\n\n    }\n\n    public void configDependencies(File awbConfigFile) {\n\n        Set<String> awbs = getAwbs(awbConfigFile);\n\n        AtlasDependencyManager atlasDependencyManager = new AtlasDependencyManager(project, new ExtraModelInfo(new ProjectOptions(project), project.getLogger()),awbs);\n\n        VariantManager variantManager = getVariantManager();\n\n        if (variantManager!=null) {\n\n            variantManager.getVariantScopes().stream().forEach(variantScope -> atlasDependencyManager.resolveDependencies(variantScope.getVariantDependencies()));\n        }\n    }\n\n    private Set<String> getAwbs(File awbConfigFile) {\n        Set<String>awbs = new HashSet<>();\n        if (awbConfigFile != null && awbConfigFile.exists()){\n            try {\n                awbs.addAll(FileUtils.readLines(awbConfigFile));\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n        return awbs;\n    }\n\n    public VariantManager getVariantManager() {\n\n        VariantManager variantManager = null;\n\n        BasePlugin appPlugin = project.getPlugins().findPlugin(AppPlugin.class);\n\n        if (null == appPlugin) {\n            appPlugin = project.getPlugins().findPlugin(LibraryPlugin.class);\n        }\n        if (appPlugin != null) {\n            try {\n                variantManager = (VariantManager) ReflectUtils.getField(BasePlugin.class, appPlugin, \"variantManager\");\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n\n        }\n\n        return variantManager;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/manager/AtlasFeatureTaskManager.java",
    "content": "package com.taobao.android.builder.manager;\n\nimport com.android.build.api.transform.QualifiedContent;\nimport com.android.build.gradle.BaseExtension;\nimport com.android.build.gradle.FeatureExtension;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.api.FeatureVariant;\nimport com.android.build.gradle.api.LibraryVariant;\nimport com.android.build.gradle.api.LibraryVariantOutput;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.TaskContainerAdaptor;\nimport com.android.build.gradle.internal.api.FeatureVariantContext;\nimport com.android.build.gradle.internal.api.FeatureVariantImpl;\nimport com.android.build.gradle.internal.api.LibVariantContext;\nimport com.android.build.gradle.internal.api.LibraryVariantImpl;\nimport com.android.build.gradle.internal.dependency.FilteredArtifactCollection;\nimport com.android.build.gradle.internal.pipeline.StreamBasedTask;\nimport com.android.build.gradle.internal.pipeline.TransformStream;\nimport com.android.build.gradle.internal.pipeline.TransformTask;\nimport com.android.build.gradle.internal.publishing.AndroidArtifacts;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.transforms.FixStackFramesTransform;\nimport com.android.build.gradle.tasks.GenerateBuildConfig;\nimport com.android.build.gradle.tasks.MergeManifests;\nimport com.android.build.gradle.tasks.ProcessAndroidResources;\nimport com.android.builder.core.AtlasBuilder;\nimport com.android.utils.ILogger;\nimport com.google.common.collect.ImmutableList;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.extension.TBuildType;\nimport com.taobao.android.builder.tasks.app.GenerateAtlasSourceTask;\nimport com.taobao.android.builder.tasks.app.manifest.StandardizeLibManifestTask;\nimport com.taobao.android.builder.tasks.feature.FeatureLibManifestTask;\nimport com.taobao.android.builder.tasks.feature.PrePareFeatureTask;\nimport com.taobao.android.builder.tasks.library.AwbGenerator;\nimport com.taobao.android.builder.tasks.library.JarExtractTask;\nimport com.taobao.android.builder.tasks.manager.MtlTaskContext;\nimport com.taobao.android.builder.tasks.manager.MtlTaskInjector;\nimport com.taobao.android.builder.tasks.manager.transform.TransformManager;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport com.taobao.android.builder.tools.ideaplugin.AwoPropHandler;\nimport org.apache.commons.lang.StringUtils;\nimport org.apache.commons.lang.reflect.FieldUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.ArtifactCollection;\nimport org.gradle.api.file.FileCollection;\nimport org.gradle.api.tasks.bundling.Zip;\n\nimport java.io.IOException;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Proxy;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.function.Consumer;\n\n/**\n * AtlasFeatureTaskManager\n *\n * @author zhayu.ll\n * @date 18/1/3\n * @time 下午8:15\n * @description  \n */\npublic class AtlasFeatureTaskManager extends AtlasBaseTaskManager {\n\n    private FeatureExtension featureExtension;\n\n    private ILogger logger = LoggerWrapper.getLogger(AtlasFeatureTaskManager.class);\n\n    public AtlasFeatureTaskManager(AtlasBuilder androidBuilder, BaseExtension androidExtension, Project project, AtlasExtension atlasExtension) {\n        super(androidBuilder, androidExtension, project, atlasExtension);\n        this.featureExtension = (FeatureExtension) androidExtension;\n    }\n\n    @Override\n    public void runTask() {\n\n        if (featureExtension.getBaseFeature()) {\n            return;\n        }\n\n\n        featureExtension.getFeatureVariants().forEach(featureVariant -> {\n\n            FeatureVariantContext featureVariantContext = new FeatureVariantContext((FeatureVariantImpl) featureVariant,\n                    project, atlasExtension, featureExtension);\n            ArtifactCollection allArtifacts = featureVariantContext.getScope().getArtifactCollection(AndroidArtifacts.ConsumedConfigType.RUNTIME_CLASSPATH, AndroidArtifacts.ArtifactScope.EXTERNAL, AndroidArtifacts.ArtifactType.CLASSES);\n            ArtifactCollection artifacts = featureVariantContext.getScope().getArtifactCollection(AndroidArtifacts.ConsumedConfigType.RUNTIME_CLASSPATH, AndroidArtifacts.ArtifactScope.ALL, AndroidArtifacts.ArtifactType.FEATURE_TRANSITIVE_DEPS);\n            ArtifactCollection filterArtifacts =\n                    new FilteredArtifactCollection(\n                            featureVariantContext.getProject(),\n                            allArtifacts,\n                            artifacts.getArtifactFiles());\n\n            List<TransformTask> transformTasks = TransformManager.findTransformTaskByTransformType(featureVariantContext, FixStackFramesTransform.class);\n            if (transformTasks != null) {\n                for (TransformTask transformTask : transformTasks) {\n                    try {\n                        Field field = StreamBasedTask.class.getDeclaredField(\"consumedInputStreams\");\n                        Field field1 = StreamBasedTask.class.getDeclaredField(\"referencedInputStreams\");\n                        field1.setAccessible(true);\n                        field.setAccessible(true);\n                        Collection<TransformStream> consumedInputStreams = (Collection<TransformStream>) field.get(transformTask);\n                        Collection<TransformStream> referencedInputStreams = (Collection<TransformStream>)field1.get(transformTask);\n                        for (TransformStream stream : consumedInputStreams) {\n                            if (stream.getContentTypes().contains(QualifiedContent.DefaultContentType.CLASSES) && stream.getScopes().contains(QualifiedContent.Scope.EXTERNAL_LIBRARIES)) {\n                                ReflectUtils.updateField(stream, \"fileCollection\", filterArtifacts.getArtifactFiles());\n                                ReflectUtils.updateField(stream, \"artifactCollection\", filterArtifacts);\n\n                                break;\n                            }\n\n                        }\n\n                        for (TransformStream transformStream:referencedInputStreams){\n                            if (transformStream.getContentTypes().contains(QualifiedContent.DefaultContentType.CLASSES)&&transformStream.getScopes().contains(QualifiedContent.Scope.PROVIDED_ONLY)){\n                                ReflectUtils.updateField(transformStream, \"fileCollection\", project.files());\n//                                ReflectUtils.updateField(transformStream, \"artifactCollection\", filterArtifacts);\n                            }\n                        }\n                    } catch (Exception e) {\n\n                    }\n\n                }\n            }\n            featureVariantContext.getScope().getProcessResourcesTask().get(new TaskContainerAdaptor(featureVariantContext.getProject().getTasks())).setEnableAapt2(true);\n\n        });\n\n        featureExtension.getLibraryVariants().forEach(libraryVariant -> {\n\n            LibVariantContext libVariantContext = new LibVariantContext((LibraryVariantImpl) libraryVariant,\n                    project,\n                    atlasExtension,\n                    featureExtension);\n\n            TBuildType tBuildType = libVariantContext.getBuildType();\n            if (null != tBuildType) {\n                try {\n                    new AwoPropHandler().process(tBuildType,\n                            atlasExtension.getBundleConfig());\n                } catch (Exception e) {\n                    throw new GradleException(\"process awo exception\", e);\n                }\n            }\n\n            AwbGenerator awbGenerator = new AwbGenerator(atlasExtension);\n\n            Collection<BaseVariantOutput> list = libVariantContext.getBaseVariant().getOutputs();\n\n            if (null != list) {\n\n                for (BaseVariantOutput libVariantOutputData : list) {\n\n                    Zip zipTask = ((LibraryVariantOutput) (libVariantOutputData)).getPackageLibrary();\n\n                    if (atlasExtension.getBundleConfig().isJarEnabled()) {\n                        new JarExtractTask().generateJarArtifict(zipTask);\n                    }\n\n                    //Build the awb and extension\n//                    if (atlasExtension.getBundleConfig().isAwbBundle()) {\n                    awbGenerator.generateAwbArtifict(zipTask, libVariantContext);\n//                    }\n\n                    if (null != tBuildType && (StringUtils.isNotEmpty(tBuildType.getBaseApDependency())\n                            || null != tBuildType.getBaseApFile()) &&\n\n                            libraryVariant.getName().equals(\"debug\")) {\n\n                        atlasExtension.getTBuildConfig().setUseCustomAapt(true);\n\n                        libVariantContext.setBundleTask(zipTask);\n\n                        try {\n\n                            libVariantContext.setAwbBundle(awbGenerator.createAwbBundle(libVariantContext));\n                        } catch (IOException e) {\n                            throw new GradleException(\"set awb bundle error\");\n                        }\n\n                    }\n\n                }\n\n\n            }\n\n        });\n\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/manager/AtlasLibTaskManager.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.manager;\n\nimport com.android.build.api.transform.Transform;\nimport com.android.build.gradle.LibraryExtension;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.api.LibraryVariant;\nimport com.android.build.gradle.api.LibraryVariantOutput;\nimport com.android.build.gradle.internal.api.LibVariantContext;\nimport com.android.build.gradle.internal.api.LibraryVariantImpl;\nimport com.android.build.gradle.internal.pipeline.TransformTask;\nimport com.android.build.gradle.internal.scope.AndroidTask;\nimport com.android.build.gradle.internal.transforms.LibraryAarJarsTransform;\nimport com.android.build.gradle.internal.transforms.LibraryBaseTransform;\nimport com.android.build.gradle.tasks.MergeResources;\nimport com.android.builder.core.AtlasBuilder;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.extension.TBuildType;\nimport com.taobao.android.builder.tasks.library.AwbGenerator;\nimport com.taobao.android.builder.tasks.library.JarExtractTask;\nimport com.taobao.android.builder.tasks.library.publish.UpdatePomTask;\nimport com.taobao.android.builder.tasks.manager.transform.TransformManager;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport com.taobao.android.builder.tools.ideaplugin.AwoPropHandler;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Project;\nimport org.gradle.api.Task;\nimport org.gradle.api.tasks.bundling.Zip;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.function.Consumer;\n\n/**\n * MTLThe plug-in compiles the lib library's task management\n * Created by shenghua.nish on 2016-05-09 3:55 in the afternoon.\n *\n * @author shenghua.nish, wuzhong\n */\npublic class AtlasLibTaskManager extends AtlasBaseTaskManager {\n\n    private LibraryExtension libraryExtension;\n\n    public AtlasLibTaskManager(AtlasBuilder androidBuilder,\n                               LibraryExtension libraryExtension,\n                               Project project,\n                               AtlasExtension atlasExtension) {\n        super(androidBuilder, libraryExtension, project, atlasExtension);\n        this.libraryExtension = libraryExtension;\n    }\n\n    @Override\n    public void runTask() {\n\n        new UpdatePomTask(project).updatePom();\n\n        libraryExtension.getLibraryVariants().forEach(libraryVariant -> {\n\n            LibVariantContext libVariantContext = new LibVariantContext((LibraryVariantImpl)libraryVariant,\n                                                                        project,\n                                                                        atlasExtension,\n                                                                        libraryExtension);\n\n            TBuildType tBuildType = libVariantContext.getBuildType();\n            if (null != tBuildType) {\n                try {\n                    new AwoPropHandler().process(tBuildType,\n                                                 atlasExtension.getBundleConfig());\n                } catch (Exception e) {\n                    throw new GradleException(\"process awo exception\", e);\n                }\n            }\n\n            AwbGenerator awbGenerator = new AwbGenerator(atlasExtension);\n\n            Collection<BaseVariantOutput> list = libVariantContext.getBaseVariant().getOutputs();\n\n            if (null != list) {\n\n                for (BaseVariantOutput libVariantOutputData : list) {\n\n                    Zip zipTask = ((LibraryVariantOutput)(libVariantOutputData)).getPackageLibrary();\n\n                    if (atlasExtension.getBundleConfig().isJarEnabled()) {\n                        new JarExtractTask().generateJarArtifict(zipTask);\n                    }\n\n                    //Build the awb and extension\n                    if (atlasExtension.getBundleConfig().isAwbBundle()) {\n                        awbGenerator.generateAwbArtifict(zipTask,libVariantContext);\n                    }\n\n                    if (null != tBuildType && (StringUtils.isNotEmpty(tBuildType.getBaseApDependency())\n                        || null != tBuildType.getBaseApFile()) &&\n\n                        libraryVariant.getName().equals(\"debug\")) {\n\n                        atlasExtension.getTBuildConfig().setUseCustomAapt(true);\n\n                        libVariantContext.setBundleTask(zipTask);\n\n                        try {\n\n                            libVariantContext.setAwbBundle(awbGenerator.createAwbBundle(libVariantContext));\n                        } catch (IOException e) {\n                            throw new GradleException(\"set awb bundle error\");\n                        }\n\n//                            if (atlasExtension.getBundleConfig().isAwbBundle()) {\n//                                createAwoTask(libVariantContext, zipTask);\n//                            } else {\n//                                createDexTask(libVariantContext, zipTask);\n//                            }\n                    }\n\n                }\n\n//                    List<TransformTask>transformTasks =  TransformManager.findTransformTaskByTransformType(libVariantContext,LibraryAarJarsTransform.class);\n//                    for (TransformTask transformTask: transformTasks){\n//                        Transform transform = transformTask.getTransform();\n//                        if (transform instanceof LibraryBaseTransform){\n//                            ReflectUtils.updateField(transform,\"excludeListProviders\", Lists.newArrayList(new AtlasExcludeListProvider()));\n//                        }\n//                    }\n\n            }\n\n        });\n    }\n\n//    private void createAwoTask(LibVariantContext libVariantContext, Zip bundleTask) {\n//\n//        List<MtlTaskContext> mtlTaskContexts = new ArrayList<MtlTaskContext>();\n//\n//        mtlTaskContexts.add(new MtlTaskContext(bundleTask));\n//\n//        mtlTaskContexts.add(new MtlTaskContext(PrepareAPTask.ConfigAction.class, null));\n//\n//        //Judgment depends on conflicts in AP and reduces the dependency on awb in apk\n//        mtlTaskContexts.add(new MtlTaskContext(DiffDependencyTask.ConfigAction.class, null));\n//\n//        mtlTaskContexts.add(new MtlTaskContext(PrepareAwoBundleTask.ConfigAction.class, null));\n//\n//        //mergeManifest\n//        mtlTaskContexts.add(new MtlTaskContext(MergeAwoManifests.ConfigAction.class, null));\n//\n//        //MergeAssets\n//        mtlTaskContexts.add(new MtlTaskContext(MergeAwbAssetConfigAction.class, null));\n//\n//        mtlTaskContexts.add(new MtlTaskContext(CopyAwoSolibTask.ConfigAction.class, null));\n//\n//        //MergeRes\n//        mtlTaskContexts.add(new MtlTaskContext(MergeAwbResourceConfigAction.class, null));\n//\n//        //Awb processRes\n//        mtlTaskContexts.add(new MtlTaskContext(ProcessAwoAndroidResources.ConfigAction.class,\n//                                               null));\n//\n//        mtlTaskContexts.add(new MtlTaskContext(AwoJavaCompileConfigAction.class, null));\n//\n//        //Dex\n//        mtlTaskContexts.add(new MtlTaskContext(AwbDexTask.ConfigAction.class, null));\n//\n//        //mtlTaskContexts.add(new MtlTaskContext(PrePackageConfigAction.class, null));\n//\n//        //package\n//        mtlTaskContexts.add(new MtlTaskContext(AwoPackageTask.ConfigAction.class, null));\n//\n//        //Installation to mobile phone\n//        mtlTaskContexts.add(new MtlTaskContext(AwoInstallTask.ConfigAction.class, null));\n//\n//        mtlTaskContexts.add(new MtlTaskContext(AssemblePatchTask.ConfigAction.class, null));\n//\n//        //Signature & zipalign\n//        //        mtlTaskContexts.add(new MtlTaskContext(AwoFullApkBuildTask.ConfigAction.class, null));\n//\n//        //mtlTaskContexts.add(new MtlTaskContext(libVariantContext.getBaseVariantData().assembleVariantTask));\n//\n//        new MtlTaskInjector(libVariantContext).injectTasks(mtlTaskContexts, tAndroidBuilder);\n//    }\n//\n//    private void createDexTask(LibVariantContext libVariantContext, Zip bundleTask) {\n\n//        List<MtlTaskContext> mtlTaskContexts = new ArrayList<MtlTaskContext>();\n//\n//        mtlTaskContexts.add(new MtlTaskContext(bundleTask));\n//\n//        mtlTaskContexts.add(new MtlTaskContext(PrepareAPTask.ConfigAction.class, null));\n//\n//        mtlTaskContexts.add(new MtlTaskContext(PrepareMainDexJarsTask.ConfigAction.class, null));\n//\n//       mtlTaskContexts.add(new MtlTaskContext(DexBuildTask.ConfigAction.class, null));\n//\n//        mtlTaskContexts.add(new MtlTaskContext(DexInstallTask.ConfigAction.class, null));\n//\n//        mtlTaskContexts.add(new MtlTaskContext(AssemblePatchTask.ConfigAction.class, null));\n//\n//        new MtlTaskInjector(libVariantContext).injectTasks(mtlTaskContexts, tAndroidBuilder);\n//    }\n//\n//    private LibraryExtension libraryExtension;\n\n    public class AtlasExcludeListProvider implements LibraryBaseTransform.ExcludeListProvider{\n        public List<String> getExcludeList(){\n            ArrayList arrayList = new ArrayList();\n            arrayList.add(\".*/DataBindingComponent.class$\");\n            arrayList.add(\".*/DataBindingInfo.class$\");\n            arrayList.add(\".*/baseAdapters/BR.class$\");\n        return arrayList;\n        }\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/manager/PluginManager.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.manager;\n\nimport org.gradle.api.Plugin;\nimport org.gradle.api.Project;\nimport org.gradle.api.plugins.PluginContainer;\n\n/**\n * Created by wuzhong on 2017/3/15.\n *\n * @author wuzhong\n * @date 2017/03/15\n */\npublic class PluginManager {\n\n\n    public static void addPluginIfNot(Project project, Class<? extends Plugin> pluginClazz){\n\n        PluginContainer pluginManager = project.getPlugins();\n\n        if (pluginManager.hasPlugin(pluginClazz)){\n            return;\n        }\n\n        pluginManager.apply(pluginClazz);\n\n\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/manager/Version.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.manager;\n\npublic final class Version {\n    private Version() {}\n    public static final String ANDROID_GRADLE_PLUGIN_VERSION = \"2.3.0.alpha1-SNAPSHOT\";\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/PrepareAPTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks;\n\n/**\n * Created by wuzhong on 16/6/13.\n */\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.ApContext;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.android.build.gradle.internal.scope.ConventionMappingHelper;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.utils.FileUtils;\nimport com.google.common.collect.Iterables;\nimport com.google.common.collect.Sets;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.extension.TBuildType;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport com.taobao.android.builder.tools.zip.BetterZip;\nimport org.apache.commons.io.FilenameUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.dom4j.DocumentException;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Nullable;\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.Configuration;\nimport org.gradle.api.artifacts.Dependency;\nimport org.gradle.api.tasks.*;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Set;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.TimeUnit;\n\nimport static com.android.SdkConstants.ANDROID_MANIFEST_XML;\nimport static com.android.SdkConstants.FN_APK_CLASSES_DEX;\nimport static com.android.build.gradle.internal.api.ApContext.*;\nimport static com.android.builder.model.AndroidProject.FD_INTERMEDIATES;\n\n/**\n */\npublic class PrepareAPTask extends BaseTask {\n\n    private ApContext apContext;\n\n    private File apFile;\n\n    private String apDependency;\n\n    private File explodedDir;\n\n    Set<String> awbBundles;\n\n    @InputFile\n    @Optional\n    @Nullable\n    public File getApFile() {\n        return apFile;\n    }\n\n    public void setApFile(File apFile) {\n        this.apFile = apFile;\n    }\n\n    @Input\n    @Optional\n    public String getApDependency() {\n        return apDependency;\n    }\n\n    public void setApDependency(String apDependency) {\n        this.apDependency = apDependency;\n    }\n\n    @OutputDirectory\n    public File getExplodedDir() {\n        return explodedDir;\n    }\n\n    public void setExplodedDir(File explodedDir) {\n        this.explodedDir = explodedDir;\n    }\n\n    @Input\n    @Optional\n    public Set<String> getAwbBundles() {\n        return awbBundles;\n    }\n\n    public void setAwbBundles(Set<String> awbBundles) {\n        this.awbBundles = awbBundles;\n    }\n\n    /**\n     * Directory of so\n     */\n    @TaskAction\n    void generate() throws IOException, DocumentException {\n\n        Project project = getProject();\n        File apBaseFile = null;\n\n        File apFile = getApFile();\n        if (null != apFile && apFile.exists()) {\n            apBaseFile = apFile;\n        } else {\n            String apDependency = getApDependency();\n            if (StringUtils.isNotBlank(apContext.getApDependency())) {\n                Dependency dependency = project.getDependencies().create(apDependency);\n                Configuration configuration = project.getConfigurations().detachedConfiguration(dependency);\n                configuration.setTransitive(false);\n                configuration.getResolutionStrategy().cacheChangingModulesFor(0, TimeUnit.MILLISECONDS);\n                configuration.getResolutionStrategy().cacheDynamicVersionsFor(0, TimeUnit.MILLISECONDS);\n                for (File file : configuration.getFiles()) {\n                    if (file.getName().endsWith(\".ap\")) {\n                        apBaseFile = file;\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (null != apBaseFile && apBaseFile.exists()) {\n\n            try {\n                explodedDir = getExplodedDir();\n                BetterZip.unzipDirectory(apBaseFile, explodedDir);\n                apContext.setApExploredFolder(explodedDir);\n                Set<String> awbBundles = getAwbBundles();\n                if (awbBundles != null) {\n                    // Unzip the baseline Bundle\n                    for (String awbBundle : awbBundles) {\n                        File awbFile = BetterZip.extractFile(new File(explodedDir, AP_INLINE_APK_FILENAME),\n                                                             \"lib/armeabi/\" + awbBundle,\n                                                             new File(explodedDir, AP_INLINE_AWB_EXTRACT_DIRECTORY));\n                        File awbExplodedDir = new File(new File(explodedDir, AP_INLINE_AWB_EXPLODED_DIRECTORY),\n                                                       FilenameUtils.getBaseName(awbBundle));\n                        BetterZip.unzipDirectory(awbFile, awbExplodedDir);\n                        FileUtils.renameTo(new File(awbExplodedDir, FN_APK_CLASSES_DEX),\n                                           new File(awbExplodedDir, \"classes2.dex\"));\n                    }\n                    // Preprocessing increment androidmanifest.xml\n                    ManifestFileUtils.updatePreProcessBaseManifestFile(\n                        FileUtils.join(explodedDir, \"manifest-modify\", ANDROID_MANIFEST_XML),\n                        new File(explodedDir, ANDROID_MANIFEST_XML));\n                }\n                if (explodedDir.listFiles().length == 0){\n                    throw new RuntimeException(\"unzip ap exception, no files found\");\n                }\n            }catch (Throwable e){\n                FileUtils.deleteIfExists(apBaseFile);\n                throw new GradleException(e.getMessage(),e);\n\n            }\n        }\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<PrepareAPTask> {\n\n        public ConfigAction(VariantContext variantContext, BaseVariantOutput baseVariantOutput) {\n            super(variantContext, baseVariantOutput);\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"prepare\", \"AP\");\n        }\n\n        @Override\n        public Class<PrepareAPTask> getType() {\n            return PrepareAPTask.class;\n        }\n\n        @Override\n        public void execute(PrepareAPTask prepareAPTask) {\n\n            super.execute(prepareAPTask);\n\n            //\n            TBuildType tBuildType = variantContext.getBuildType();\n\n            if (StringUtils.isNotEmpty(tBuildType.getBaseApDependency())) {\n                variantContext.apContext.setApDependency(tBuildType.getBaseApDependency());\n            }\n\n            variantContext.apContext.setApFile(tBuildType.getBaseApFile());\n\n            prepareAPTask.apContext = variantContext.apContext;\n\n            File explodedDir = variantContext.getProject().file(\n                variantContext.getProject().getBuildDir().getAbsolutePath() + \"/\" + FD_INTERMEDIATES + \"/exploded-ap\"\n                + \"/\");\n            variantContext.apContext.setApExploredFolder(explodedDir);\n\n            ConventionMappingHelper.map(prepareAPTask, \"apFile\", (Callable<File>) () -> {\n                File apFile = variantContext.apContext.getApFile();\n                if (apFile != null) {\n                    return apFile.exists() ? apFile : null;\n                } else {\n                    return null;\n                }\n            });\n            ConventionMappingHelper.map(prepareAPTask, \"apDependency\", (Callable<String>) () -> variantContext.apContext.getApDependency());\n            ConventionMappingHelper.map(prepareAPTask, \"explodedDir\", (Callable<File>) () -> explodedDir);\n\n            if (variantContext.getAtlasExtension().getTBuildConfig().isIncremental()) {\n                ConventionMappingHelper.map(prepareAPTask, \"awbBundles\", (Callable<Set<String>>) () -> {\n                    AtlasDependencyTree dependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n                        variantContext.getVariantName());\n                    Set<String> awbBundles = Sets.newHashSet(\n                        Iterables.transform(dependencyTree.getAwbBundles(), AwbBundle::getAwbSoName));\n                    return awbBundles;\n                });\n            }\n        }\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/ApBuildTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app;\n\nimport com.alibaba.fastjson.JSON;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.api.ApContext;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.scope.ConventionMappingHelper;\nimport com.android.build.gradle.internal.tasks.DefaultAndroidTask;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.zip.BetterZip;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.tasks.InputFile;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.concurrent.Callable;\n\n/**\n * APTask to package files\n * Created by shenghua.nish on 2015-10-20 7:01 PM.\n */\npublic class ApBuildTask extends DefaultAndroidTask {\n\n    private File apkFile;\n\n    protected AppVariantContext appVariantContext;\n\n    protected BaseVariantOutput baseVariantOutputData;\n\n    private AppVariantOutputContext.AppBuildInfo appBuildInfo;\n\n    private File apUnzipDir;\n\n    @InputFile\n    public File getApkFile() {\n        return apkFile;\n    }\n\n    public void setApkFile(File apkFile) {\n        this.apkFile = apkFile;\n    }\n\n    @TaskAction\n    public void taskAction() {\n        // Generate build. Ap\n        try {\n            createAP(getApkFile(), baseVariantOutputData, appVariantContext);\n        }catch (Throwable e){\n            //getProject().getLogger().error(\"createAp exception\", e);\n            throw new GradleException(\"createAp exception\",e);\n        }\n    }\n\n    private File createAP(File apkFile,\n                          BaseVariantOutput variantOutputData,\n                          AppVariantContext appVariantContext) throws IOException {\n\n        File jarshrinkLog = new File(variantOutputData.getOutputFile()\n                                         .getParentFile()\n                                         .getParentFile(), \"jar-shrink.log\");\n\n        File injectFailedFile = new File(appVariantContext.getProject().getBuildDir(), \"outputs/warning-instrument-inject-error.properties\");\n\n\n        File proguardOut = new File(String.valueOf(appVariantContext.getScope()\n                                                       .getGlobalScope()\n                                                       .getBuildDir()) +\n                                        \"/outputs/mapping/\" +\n                                        appVariantContext\n                                            .getScope()\n                                            .getVariantConfiguration()\n                                            .getDirName());\n\n        // Generate build. Ap\n        String path = apkFile.getAbsolutePath();\n        apUnzipDir = new File(apkFile.getParentFile(), \"ap-unzip\");\n        apUnzipDir.mkdirs();\n\n        int index = path.lastIndexOf(\".apk\");\n        File APFile = new File(path.substring(0, index) + \".ap\");\n\n        addFile(com.android.utils.FileUtils.join(baseVariantOutputData.getProcessManifest().getManifestOutputDirectory(),ApkDataUtils.get(baseVariantOutputData).getDirName(),\"AndroidManifest.xml\"),\n                \"AndroidManifest.xml\");\n        addFile(apkFile, ApContext.AP_INLINE_APK_FILENAME);\n        addFile(new File(\n                appVariantContext.getScope().getGlobalScope().getIntermediatesDir().getAbsolutePath()+\"/\"+\n                \"symbols/\"\n                        + appVariantContext.getScope().getVariantData()\n                        .getVariantConfiguration()\n                        .getDirName(), \"R.txt\"),\n                \"R.txt\");\n\n        addFile(appBuildInfo.getPackageIdFile());\n        addFile(injectFailedFile);\n        addFile(appBuildInfo.getDependenciesFile());\n        addFile(appBuildInfo.getBuildInfoFile());\n        addFile(appBuildInfo.getVersionPropertiesFile());\n        addFile(new File(this.getProject().getBuildDir(),\"outputs/atlasFrameworkProperties.json\"));\n        addFile(new File(this.getProject().getBuildDir(), \"outputs/public.txt\"));\n        //addFile( appBuildInfo.getBundleInfoFile());\n\n        for (File file : appBuildInfo.getOtherFiles()) {\n            addFile(file);\n        }\n\n        for (String filePath : appBuildInfo.getOtherFilesMap().keySet()) {\n            addFile(appBuildInfo.getOtherFilesMap().get(filePath), filePath);\n        }\n\n        addFile(jarshrinkLog, jarshrinkLog.getName());\n\n        try {\n            addFile(getApkFiles(APFile.getParentFile().getParentFile(), appVariantContext),\n                    ApContext.APK_FILE_LIST);\n        }catch (Throwable e){\n            throw new RuntimeException(e);\n\n        }\n\n        getLogger().error(new File(proguardOut\n                ,\"j2cmap.zip\").getAbsolutePath() +\"is exist \"+new File(proguardOut\n                ,\"j2cmap.zip\").exists());\n        if (null != proguardOut &&\n\n            proguardOut.exists() &&\n            (new File(proguardOut, \"mapping.txt\").exists() ||\n                new File(proguardOut, \"full-mapping.txt\").exists()||new File(proguardOut,\"j2cmap.zip\").exists())) {\n            File usageFile = new File(proguardOut, \"usage.txt\");\n            File mappingFile = new File(proguardOut, \"mapping.txt\");\n            File dexCocoMap = new File(proguardOut,\"dexcocomap.zip\");\n            File j2cMap = new File(proguardOut,\"j2cmap.zip\");\n            addFile(usageFile, \"usage.txt\");\n            addFile(mappingFile, \"mapping.txt\");\n            addFile(dexCocoMap,\"dexcocomap.zip\");\n            addFile(j2cMap,\"j2cmap.zip\");\n            addFile(new File(proguardOut, \"full-mapping.txt\"), \"full-mapping.txt\");\n            addFile(new File(proguardOut, \"mapping.data\"), \"mapping.data\");\n        } else if (null != appVariantContext.apContext.getApExploredFolder() &&\n                appVariantContext.apContext.getApExploredFolder().exists()) {\n            File lastApDir = appVariantContext.apContext.getApExploredFolder();\n            File usageFile = new File(lastApDir, \"usage.txt\");\n            File mappingFile = new File(lastApDir, \"mapping.txt\");\n            File dexCocoMap = new File(lastApDir,\"dexcocomap.zip\");\n            File j2cMap = new File(lastApDir,\"j2cmap.zip\");\n            addFile(usageFile, \"usage.txt\");\n            addFile(mappingFile, \"mapping.txt\");\n            addFile(dexCocoMap,\"dexcocomap.zip\");\n            addFile(j2cMap,\"j2cmap.zip\");\n            addFile(new File(lastApDir, \"full-mapping.txt\"), \"full-mapping.txt\");\n            addFile(new File(lastApDir, \"mapping.data\"), \"mapping.data\");\n        }\n\n        BetterZip.zipDirectory(apUnzipDir, APFile);\n\n        FileUtils.deleteDirectory(apUnzipDir);\n\n        return APFile;\n    }\n\n    private static File getApkFiles(File outputDir,\n                                    AppVariantContext appVariantContext) throws IOException {\n\n        File apkFiles = new File(outputDir, ApContext.APK_FILE_LIST);\n        FileUtils.writeStringToFile(apkFiles,\n                                    JSON.toJSONString(appVariantContext.getApkFiles().finalApkFileList));\n        return apkFiles;\n    }\n\n    private void addFile(File file) throws IOException {\n        if (null != file && file.exists()){\n            addFile(file, file.getName());\n        }\n    }\n\n    /**\n     * jarFiles are added to the file\n     *\n     * @param file\n     */\n    private void addFile(File file, String entryName) throws IOException {\n\n        if (!file.exists()) {\n            return;\n        }\n\n        File dest = new File(apUnzipDir, entryName);\n\n        FileUtils.copyFile(file, dest);\n    }\n\n    /**\n     * Configure Ap files\n     */\n    public static class ConfigAction extends MtlBaseTaskAction<ApBuildTask> {\n\n        private final AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext,\n                            BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"create\", \"Ap\");\n        }\n\n        @Override\n        public Class<ApBuildTask> getType() {\n            return ApBuildTask.class;\n        }\n\n        @Override\n        public void execute(ApBuildTask apBuildTask) {\n\n            super.execute(apBuildTask);\n\n            boolean isCreateAP = appVariantContext.getAtlasExtension()\n                .getTBuildConfig()\n                .getCreateAP();\n\n            if (!isCreateAP) {\n                apBuildTask.setEnabled(false);\n                return;\n            }\n\n            ConventionMappingHelper.map(apBuildTask, \"apkFile\", (Callable<File>) () -> getAppVariantOutputContext().getApkOutputFile(true));\n\n            apBuildTask.appVariantContext = appVariantContext;\n            apBuildTask.baseVariantOutputData = baseVariantOutput;\n            apBuildTask.appBuildInfo = getAppVariantOutputContext().appBuildInfo;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/BuildAtlasEnvTask.java",
    "content": "package com.taobao.android.builder.tasks.app;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.api.transform.TransformException;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.TaskContainerAdaptor;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.ide.AtlasAndroidLibraryImpl;\nimport com.android.build.gradle.internal.ide.AtlasDependencyGraph;\nimport com.android.build.gradle.internal.publishing.AndroidArtifacts;\nimport com.android.build.gradle.internal.publishing.AtlasAndroidArtifacts;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.build.gradle.tasks.MergeManifests;\nimport com.android.build.gradle.tasks.MergeResources;\nimport com.android.build.gradle.tasks.MergeSourceSetFolders;\nimport com.android.build.gradle.tasks.ProcessAndroidResources;\nimport com.android.builder.dependency.level2.AndroidDependency;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.builder.model.JavaLibrary;\nimport com.android.ide.common.res2.*;\nimport com.android.resources.ResourceType;\nimport com.google.common.base.Preconditions;\nimport com.google.common.collect.*;\n\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.dependency.model.SoLibrary;\nimport com.taobao.android.builder.tasks.app.merge.AppendMainArtifactsCollection;\nimport com.taobao.android.builder.tasks.app.merge.MainArtifactsCollection;\nimport com.taobao.android.builder.tasks.app.merge.MainFilesCollection;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.filefilter.FalseFileFilter;\nimport org.apache.commons.io.filefilter.IOFileFilter;\nimport org.apache.commons.io.filefilter.TrueFileFilter;\nimport org.gradle.api.Action;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Project;\nimport org.gradle.api.Task;\nimport org.gradle.api.artifacts.ArtifactCollection;\nimport org.gradle.api.artifacts.ProjectDependency;\nimport org.gradle.api.artifacts.component.ComponentIdentifier;\nimport org.gradle.api.artifacts.component.ProjectComponentIdentifier;\nimport org.gradle.api.artifacts.result.ResolvedArtifactResult;\nimport org.gradle.api.file.FileCollection;\nimport org.gradle.api.internal.file.AbstractFileCollection;\nimport org.gradle.api.specs.Spec;\nimport org.gradle.api.tasks.TaskAction;\nimport org.gradle.api.tasks.compile.JavaCompile;\nimport org.gradle.internal.component.external.model.DefaultModuleComponentIdentifier;\nimport org.gradle.internal.component.local.model.DefaultProjectComponentIdentifier;\nimport org.gradle.internal.component.local.model.OpaqueComponentArtifactIdentifier;\nimport org.jetbrains.annotations.NotNull;\nimport org.objectweb.asm.ClassReader;\n\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport java.io.File;\nimport java.io.FilenameFilter;\nimport java.io.IOException;\nimport java.lang.reflect.Field;\nimport java.util.*;\nimport java.util.function.Consumer;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\n\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactScope.ALL;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactType.*;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ConsumedConfigType.ANNOTATION_PROCESSOR;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ConsumedConfigType.RUNTIME_CLASSPATH;\n\n/**\n * @author lilong\n * @create 2017-12-02 上午7:34\n */\n\npublic class BuildAtlasEnvTask extends BaseTask {\n\n\n    private AppVariantOutputContext appVariantOutputContext;\n\n    private ArtifactCollection compileManifests;\n\n    public Map<String, File> allManifests = new HashMap<>();\n\n    public Map<String, File> allSolibs = new HashMap<>();\n\n\n    public Map<String, ResolvedArtifactResult> allAndroidRes = new HashMap<>();\n\n    public Map<String, ResolvedArtifactResult> allAndroidAssets = new HashMap<>();\n\n    public Map<String, ResolvedArtifactResult> allAndroidRnames = new HashMap<>();\n\n\n\n    public Map<String, File> allJavaRes = new HashMap<>();\n\n    public Set<FileIdentity> allJars = new HashSet<>();\n\n    public Set<FileIdentity> appLocalJars = new HashSet<>();\n\n\n    private AppVariantContext appVariantContext;\n\n    private ArtifactCollection compileJars;\n\n    private ArtifactCollection nativeLibs;\n\n    private ArtifactCollection javaResources;\n    private ArtifactCollection nativeLibs2;\n    private ArtifactCollection res;\n    private ArtifactCollection assets;\n\n    private ArtifactCollection symbolListWithPackageNames;\n\n\n\n    @TaskAction\n    void generate() throws TransformException {\n\n        Set<ResolvedArtifactResult> compileArtifacts = compileManifests.getArtifacts();\n        Set<ResolvedArtifactResult> jarArtifacts = compileJars.getArtifacts();\n        Set<ResolvedArtifactResult> nativeLibsArtifacts = nativeLibs.getArtifacts();\n        Set<ResolvedArtifactResult> javaResourcesArtifacts = javaResources.getArtifacts();\n        Set<ResolvedArtifactResult> androidRes = res.getArtifacts();\n        Set<ResolvedArtifactResult> androidAssets = assets.getArtifacts();\n        Set<ResolvedArtifactResult> androidRnames = symbolListWithPackageNames.getArtifacts();\n\n        AtlasDependencyTree androidDependencyTree = AtlasBuildContext.androidDependencyTrees.get(getVariantName());\n        List<AwbBundle> bundles = new ArrayList<>();\n        bundles.add(androidDependencyTree.getMainBundle());\n        bundles.addAll(androidDependencyTree.getAwbBundles());\n\n\n\n\n\n        //this is no used ,if used in future add to transform!\n\n        Set<ResolvedArtifactResult> nativeLibsArtifacts2 = nativeLibs2.getArtifacts();\n\n        nativeLibsArtifacts.addAll(nativeLibsArtifacts2);\n\n        AtlasBuildContext.localLibs = nativeLibs2.getArtifactFiles().getFiles();\n\n\n        for (ResolvedArtifactResult resolvedArtifactResult : jarArtifacts) {\n            ComponentIdentifier componentIdentifier = resolvedArtifactResult.getId().getComponentIdentifier();\n            if (componentIdentifier instanceof DefaultModuleComponentIdentifier) {\n                allJars.add(new FileIdentity(((DefaultModuleComponentIdentifier) componentIdentifier).getGroup() + \":\" + ((DefaultModuleComponentIdentifier) componentIdentifier).getModule(), resolvedArtifactResult.getFile(), resolvedArtifactResult.getId().getDisplayName().startsWith(\"classes.jar\") ? false : true, false));\n            } else if (componentIdentifier instanceof DefaultProjectComponentIdentifier) {\n                String projectPath = ((DefaultProjectComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getProjectPath();\n                allJars.add(new FileIdentity(projectPath.substring(projectPath.lastIndexOf(\":\") + 1), resolvedArtifactResult.getFile(), resolvedArtifactResult.getId().getDisplayName().startsWith(\"classes.jar\") ? false : true, true));\n            } else if (componentIdentifier instanceof OpaqueComponentArtifactIdentifier) {\n                if (resolvedArtifactResult.getFile().getAbsolutePath().contains(\"renderscript\"))\n                appLocalJars.add(new FileIdentity(componentIdentifier.getDisplayName(), resolvedArtifactResult.getFile(), true, false));\n            }\n        }\n        for (ResolvedArtifactResult resolvedArtifactResult : compileArtifacts) {\n            if (resolvedArtifactResult.getId().getComponentIdentifier() instanceof DefaultModuleComponentIdentifier) {\n                allManifests.put(((DefaultModuleComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getGroup() + \":\" + ((DefaultModuleComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getModule(), resolvedArtifactResult.getFile());\n            } else if (resolvedArtifactResult.getId().getComponentIdentifier() instanceof DefaultProjectComponentIdentifier) {\n                String projectPath = ((DefaultProjectComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getProjectPath();\n                allManifests.put(projectPath.substring(projectPath.lastIndexOf(\":\") + 1), resolvedArtifactResult.getFile());\n            }\n        }\n\n        for (ResolvedArtifactResult resolvedArtifactResult : nativeLibsArtifacts) {\n            if (resolvedArtifactResult.getId().getComponentIdentifier() instanceof DefaultModuleComponentIdentifier) {\n                allSolibs.put(((DefaultModuleComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getGroup() + \":\" + ((DefaultModuleComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getModule(), resolvedArtifactResult.getFile());\n            } else if (resolvedArtifactResult.getId().getComponentIdentifier() instanceof DefaultProjectComponentIdentifier) {\n                String projectPath = ((DefaultProjectComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getProjectPath();\n                allSolibs.put(projectPath.substring(projectPath.lastIndexOf(\":\") + 1), resolvedArtifactResult.getFile());\n            }\n        }\n\n        for (ResolvedArtifactResult resolvedArtifactResult : javaResourcesArtifacts) {\n            if (resolvedArtifactResult.getId().getComponentIdentifier() instanceof DefaultModuleComponentIdentifier) {\n                allJavaRes.put(((DefaultModuleComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getGroup() + \":\" + ((DefaultModuleComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getModule(), resolvedArtifactResult.getFile());\n            } else if (resolvedArtifactResult.getId().getComponentIdentifier() instanceof DefaultProjectComponentIdentifier) {\n                String projectPath = ((DefaultProjectComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getProjectPath();\n                allJavaRes.put(projectPath.substring(projectPath.lastIndexOf(\":\") + 1), resolvedArtifactResult.getFile());\n            }\n        }\n\n        for (ResolvedArtifactResult resolvedArtifactResult : androidRes) {\n            if (resolvedArtifactResult.getId().getComponentIdentifier() instanceof DefaultModuleComponentIdentifier) {\n                allAndroidRes.put(((DefaultModuleComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getGroup() + \":\" + ((DefaultModuleComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getModule(), resolvedArtifactResult);\n            } else if (resolvedArtifactResult.getId().getComponentIdentifier() instanceof DefaultProjectComponentIdentifier) {\n                String projectPath = ((DefaultProjectComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getProjectPath();\n                allAndroidRes.put(projectPath.substring(projectPath.lastIndexOf(\":\") + 1), resolvedArtifactResult);\n            }\n        }\n\n        for (ResolvedArtifactResult resolvedArtifactResult : androidAssets) {\n            if (resolvedArtifactResult.getId().getComponentIdentifier() instanceof DefaultModuleComponentIdentifier) {\n                allAndroidAssets.put(((DefaultModuleComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getGroup() + \":\" + ((DefaultModuleComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getModule(), resolvedArtifactResult);\n            } else if (resolvedArtifactResult.getId().getComponentIdentifier() instanceof DefaultProjectComponentIdentifier) {\n                String projectPath = ((DefaultProjectComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getProjectPath();\n                allAndroidAssets.put(projectPath.substring(projectPath.lastIndexOf(\":\") + 1), resolvedArtifactResult);\n            }\n        }\n\n        for (ResolvedArtifactResult resolvedArtifactResult : androidRnames) {\n            if (resolvedArtifactResult.getId().getComponentIdentifier() instanceof DefaultModuleComponentIdentifier) {\n                allAndroidRnames.put(((DefaultModuleComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getGroup() + \":\" + ((DefaultModuleComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getModule(), resolvedArtifactResult);\n            } else if (resolvedArtifactResult.getId().getComponentIdentifier() instanceof DefaultProjectComponentIdentifier) {\n                String projectPath = ((DefaultProjectComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier()).getProjectPath();\n                allAndroidRnames.put(projectPath.substring(projectPath.lastIndexOf(\":\") + 1), resolvedArtifactResult);\n            }\n        }\n\n\n         //app localJar is not support , this may course duplicate localjars\n        appLocalJars.stream().forEach(fileIdentity -> AtlasBuildContext.atlasMainDexHelperMap.get(getVariantName()).addMainDex(fileIdentity));\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(getVariantName());\n        List<AndroidLibrary> androidLibraries = atlasDependencyTree.getAllAndroidLibrarys();\n\n\n        androidLibraries.stream().forEach(androidLibrary -> {\n            if (androidLibrary instanceof AtlasAndroidLibraryImpl) {\n                AndroidDependency fakeAndroidLibrary = ((AtlasAndroidLibraryImpl) androidLibrary).getAndroidLibrary();\n                File id = null;\n\n                if ((id = allManifests.get(androidLibrary.getResolvedCoordinates().getGroupId() + \":\" + androidLibrary.getResolvedCoordinates().getArtifactId())) == null) {\n                    id = allManifests.get(androidLibrary.getResolvedCoordinates().toString().split(\":\")[1]);\n                }\n                if (id == null) {\n                    getLogger().warn(\"id == null---------------------\" + androidLibrary.getResolvedCoordinates().getGroupId() + \":\" + androidLibrary.getResolvedCoordinates().getArtifactId());\n                    throw new GradleException(\"excute failed! \");\n\n                }\n                ReflectUtils.updateField(fakeAndroidLibrary, \"extractedFolder\", id.getParentFile());\n                ReflectUtils.updateField(fakeAndroidLibrary, \"jarsRootFolder\", id.getParentFile());\n                ((AtlasAndroidLibraryImpl) androidLibrary).setAndroidLibrary(AndroidDependency.createExplodedAarLibrary(null, androidLibrary.getResolvedCoordinates(), androidLibrary.getName(), ((AtlasAndroidLibraryImpl) androidLibrary).getPath(), id.getParentFile()));\n                appVariantContext.manifestMap.put(androidLibrary.getManifest().getAbsolutePath(),\n                        appVariantContext.getModifyManifest(androidLibrary));\n            }\n        });\n\n        List<AndroidLibrary> mainDexAndroidLibraries = atlasDependencyTree.getMainBundle().getAndroidLibraries();\n        List<JavaLibrary> mainDexJarLibraries = atlasDependencyTree.getMainBundle().getJavaLibraries();\n        List<SoLibrary> mainSoLibraries = atlasDependencyTree.getMainBundle().getSoLibraries();\n\n        for (AndroidLibrary androidLibrary : mainDexAndroidLibraries) {\n            String name = androidLibrary.getResolvedCoordinates().getGroupId() + \":\" + androidLibrary.getResolvedCoordinates().getArtifactId();\n            String moudleName = androidLibrary.getResolvedCoordinates().toString().split(\":\")[1];\n            fillMainManifest(name, moudleName);\n            fillMainJar(name, moudleName);\n            fillAllJavaRes(name, moudleName);\n            fillMainSolibs(name, moudleName);\n        }\n\n        for (JavaLibrary jarLibrary : mainDexJarLibraries) {\n            String moudleName = jarLibrary.getName().split(\":\")[1];\n            String name = jarLibrary.getResolvedCoordinates().getGroupId() + \":\" + jarLibrary.getResolvedCoordinates().getArtifactId();\n            fillMainJar(name, moudleName);\n            fillAllJavaRes(name, moudleName);\n        }\n\n        for (SoLibrary soLibrary : mainSoLibraries) {\n            String name = soLibrary.getResolvedCoordinates().getGroupId() + \":\" + soLibrary.getResolvedCoordinates().getArtifactId();\n            String moudleName = soLibrary.getResolvedCoordinates().toString().split(\":\")[1];\n            fillMainSolibs(name, moudleName);\n        }\n\n\n        for (AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n            List<AndroidLibrary> awbAndroidLibraries = awbBundle.getAndroidLibraries();\n            List<JavaLibrary> awbJarLibraries = awbBundle.getJavaLibraries();\n            List<SoLibrary> awbSoLibraries = awbBundle.getSoLibraries();\n\n            for (AndroidLibrary androidLibrary : awbAndroidLibraries) {\n                String name = androidLibrary.getResolvedCoordinates().getGroupId() + \":\" + androidLibrary.getResolvedCoordinates().getArtifactId();\n                String moudleName = androidLibrary.getResolvedCoordinates().toString().split(\":\")[1];\n                fillAwbManifest(name, moudleName, awbBundle);\n                fillAwbJar(name, moudleName, awbBundle);\n                fillAwbAllJavaRes(name, moudleName, awbBundle);\n                fillAwbSolibs(name, moudleName, awbBundle);\n                fillAwbAndroidRes(name, moudleName, awbBundle);\n                fillAwbAndroidAssets(name, moudleName, awbBundle);\n                fillAwbAndroidRs(name, moudleName, awbBundle);\n\n            }\n            for (JavaLibrary jarLibrary : awbJarLibraries) {\n                String moudleName = jarLibrary.getName().split(\":\")[1];\n                String name = jarLibrary.getResolvedCoordinates().getGroupId() + \":\" + jarLibrary.getResolvedCoordinates().getArtifactId();\n                fillAwbJar(name, moudleName, awbBundle);\n            }\n            for (SoLibrary soLibrary : awbSoLibraries) {\n                String name = soLibrary.getResolvedCoordinates().getGroupId() + \":\" + soLibrary.getResolvedCoordinates().getArtifactId();\n                String moudleName = soLibrary.getResolvedCoordinates().toString().split(\":\")[1];\n                fillAwbSolibs(name, moudleName, awbBundle);\n            }\n            String name = awbBundle.getResolvedCoordinates().getGroupId() + \":\" + awbBundle.getResolvedCoordinates().getArtifactId();\n            String moudleName = awbBundle.getResolvedCoordinates().toString().split(\":\")[1];\n            fillAwbManifest(name, moudleName, awbBundle);\n            fillAwbJar(name, moudleName, awbBundle);\n            fillAwbAllJavaRes(name, moudleName, awbBundle);\n            fillAwbSolibs(name, moudleName, awbBundle);\n            fillAwbAndroidRes(name, moudleName, awbBundle);\n            fillAwbAndroidAssets(name, moudleName, awbBundle);\n            fillAwbAndroidRs(name, moudleName, awbBundle);\n\n        }\n\n\n        MergeResources mergeResources = appVariantContext.getScope().getMergeResourcesTask().get(new TaskContainerAdaptor(getProject().getTasks()));\n\n        try {\n            //mergeresources\n            Field field = MergeResources.class.getDeclaredField(\"libraries\");\n            field.setAccessible(true);\n            field.set(mergeResources, new MainArtifactsCollection((ArtifactCollection) field.get(mergeResources), getProject(),mergeResources.getVariantName()));\n            appVariantOutputContext.getAwbTransformMap().values().stream().forEach(awbTransform -> {\n                if (isMBundle(appVariantContext,awbTransform.getAwbBundle())) {\n                    try {\n                        awbTransform.getAwbBundle().isMBundle = true;\n                        awbTransform.getAwbBundle().bundleInfo.setIsMBundle(true);\n                        field.set(mergeResources, new AppendMainArtifactsCollection(appVariantContext.getProject(), (ArtifactCollection) field.get(mergeResources), awbTransform.getAwbBundle(), ANDROID_RES));\n                    } catch (IllegalAccessException e) {\n                        e.printStackTrace();\n                    }\n                }\n            });\n            mergeResources.doLast(task -> FileUtils.listFiles(((MergeResources) task).getOutputDir(),new String[]{\"xml\"},true).parallelStream().forEach(file -> {\n                if (!AppendMainArtifactsCollection.bundle2Map.containsKey(file.getName())){\n                    return;\n                }\n                List<String> lines = null;\n                List<String> newLines = new ArrayList<>();\n                try {\n                    lines = FileUtils.readLines(file);\n                    lines.forEach(s -> {\n                        String s1 = s;\n                        if (s.contains(\"http://schemas.android.com/apk/res/\" + AppendMainArtifactsCollection.bundle2Map.get(file.getName()))) {\n                            s1 = s.replace(\"http://schemas.android.com/apk/res/\" + AppendMainArtifactsCollection.bundle2Map.get(file.getName()), \"http://schemas.android.com/apk/res-auto\");\n                        }\n                        newLines.add(s1);\n                    });\n                    FileUtils.writeLines(file, newLines);\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n            }));\n\n\n            //mergeSourcesSets\n            MergeSourceSetFolders mergeSourceSetFolders = appVariantContext.getScope().getMergeAssetsTask().get(new TaskContainerAdaptor(getProject().getTasks()));\n            Field assetsField = MergeSourceSetFolders.class.getDeclaredField(\"libraries\");\n            assetsField.setAccessible(true);\n            assetsField.set(mergeSourceSetFolders, new MainArtifactsCollection((ArtifactCollection) assetsField.get(mergeSourceSetFolders), getProject(),mergeSourceSetFolders.getVariantName()));\n            appVariantOutputContext.getAwbTransformMap().values().stream().forEach(awbTransform -> {\n                if (isMBundle(appVariantContext,awbTransform.getAwbBundle())) {\n                    try {\n                        awbTransform.getAwbBundle().isMBundle = true;\n                        awbTransform.getAwbBundle().bundleInfo.setIsMBundle(true);\n                        assetsField.set(mergeSourceSetFolders, new AppendMainArtifactsCollection(appVariantContext.getProject(), (ArtifactCollection) assetsField.get(mergeSourceSetFolders), awbTransform.getAwbBundle(), ASSETS));\n                    } catch (IllegalAccessException e) {\n                        e.printStackTrace();\n                    }\n                }\n            });\n            AtlasBuildContext.atlasMainDexHelperMap.get(getVariantName()).getMainSoFiles().put(appVariantContext.getScope().getMergeNativeLibsOutputDir().getAbsolutePath(), true);\n\n        } catch (Exception e) {\n\n        }\n\n        //process resources\n        ProcessAndroidResources processAndroidResources = appVariantContext.getScope().getProcessResourcesTask().get(new TaskContainerAdaptor(appVariantContext.getProject().getTasks()));\n        FileCollection fileCollection = processAndroidResources.getSymbolListsWithPackageNames();\n        Set<String> filesNames = new HashSet<>();\n        for (String fileName : AtlasBuildContext.atlasMainDexHelperMap.get(getVariantName()).getMainManifestFiles().keySet()) {\n            filesNames.add(fileName.substring(fileName.lastIndexOf(File.separatorChar) + 1));\n        }\n        FileCollection updateFileCollection = fileCollection.filter(element -> filesNames.contains(element.getParentFile().getParentFile().getName()));\n        ReflectUtils.updateField(processAndroidResources, \"symbolListsWithPackageNames\", updateFileCollection);\n        appVariantOutputContext.getAwbTransformMap().values().stream().forEach(awbTransform -> {\n            if (isMBundle(appVariantContext,awbTransform.getAwbBundle())) {\n                awbTransform.getAwbBundle().isMBundle = true;\n                awbTransform.getAwbBundle().bundleInfo.setIsMBundle(true);\n                FileCollection fc = new AppendMainArtifactsCollection(appVariantContext.getProject(),processAndroidResources.getSymbolListsWithPackageNames() , awbTransform.getAwbBundle(), SYMBOL_LIST_WITH_PACKAGE_NAME).getArtifactFiles();\n                ReflectUtils.updateField(processAndroidResources, \"symbolListsWithPackageNames\", fc);\n            }\n        });\n\n        appVariantContext.processResAwbsTask.mainDexSymbolFileCollection = updateFileCollection;\n\n\n//        FileCollection fs = appVariantContext.getScope().getArtifactFileCollection(AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH,AndroidArtifacts.ArtifactScope.ALL,AndroidArtifacts.ArtifactType.CLASSES);\n//        fs.getFiles().forEach(new Consumer<File>() {\n//            @Override\n//            public void accept(File file) {\n//                if (file.exists()){\n//                    try {\n//                        JarFile jarFile = new JarFile(file);\n//                        Enumeration<JarEntry>enumeration = jarFile.entries();\n//                        while (enumeration.hasMoreElements()){\n//                            JarEntry jarEntry = enumeration.nextElement();\n//                            if (jarEntry.getName().endsWith(\".class\")){\n//                                ClassReader classReader = new ClassReader(jarFile.getInputStream(jarEntry));\n//                                String[]ss = classReader.getInterfaces();\n//                                if (ss!= null){\n//                                    for (String s:ss){\n//                                        if (s.contains(\"IExternalComponentGetter\")||s.contains(\"IExternalComponentGetter.class\")){\n//                                            System.out.println(\"IExternalComponentGetter:\"+jarEntry.getName());\n//                                        }else if (s.contains(\"IExternalModuleGetter\")||s.contains(\"IExternalModuleGetter.class\")){\n//                                            System.out.println(\"IExternalModuleGetter:\"+jarEntry.getName());\n//                                        }\n//                                    }\n//                                }\n//\n//                            }\n//                        }\n//                    } catch (IOException e) {\n//                        e.printStackTrace();\n//                    }\n//                }\n//            }\n//        });\n\n        allManifests.clear();\n        allJavaRes.clear();\n        allSolibs.clear();\n        allJars.clear();\n        allAndroidAssets.clear();\n        allAndroidRes.clear();\n\n\n\n\n\n\n\n//\n//        try {\n//            duplicateClazzNote();\n//        } catch (IOException e) {\n//            e.printStackTrace();\n//        }\n\n    }\n\n\n    private void fillAwbAndroidRs(String name, String moudleName, AwbBundle awbBundle) {\n        ResolvedArtifactResult id = null;\n        if ((id = allAndroidRnames.get(name)) == null) {\n            id = allAndroidRnames.get(moudleName);\n        }\n        if (id != null) {\n            awbBundle.getResolvedSymbolListWithPackageNameArtifactResults().add(id);\n        }\n\n    }\n\n    private void fillAwbAndroidAssets(String name, String moudleName, AwbBundle awbBundle) {\n        ResolvedArtifactResult id = null;\n        if ((id = allAndroidAssets.get(name)) == null) {\n            id = allAndroidAssets.get(moudleName);\n        }\n        if (id != null) {\n            awbBundle.getResolvedAssetsArtifactResults().add(id);\n        }\n    }\n\n    private void fillAwbJar(String name, String moudleName, AwbBundle awbBundle) {\n        AwbTransform awbTransform = appVariantOutputContext.getAwbTransformMap().get(awbBundle.getName());\n\n\n    }\n\n    private void fillAwbManifest(String name, String moudleName, AwbBundle awbBundle) {\n\n    }\n\n    private void fillAwbAndroidRes(String name, String moudleName, AwbBundle awbBundle) {\n        ResolvedArtifactResult id = null;\n        if ((id = allAndroidRes.get(name)) == null) {\n            id = allAndroidRes.get(moudleName);\n        }\n        if (id != null) {\n            awbBundle.getResolvedResArtifactResults().add(id);\n        }\n\n    }\n\n    private void fillAwbSolibs(String name, String moudleName, AwbBundle awbBundle) {\n        AwbTransform awbTransform = appVariantOutputContext.getAwbTransformMap().get(awbBundle.getName());\n        File id = null;\n        if ((id = allSolibs.get(name)) == null) {\n            id = allSolibs.get(moudleName);\n        }\n        if (id != null) {\n            awbTransform.getLibraryJniLibsInputDir().add(id);\n        }\n    }\n\n    private void fillAwbAllJavaRes(String name, String moudleName, AwbBundle awbBundle) {\n        AwbTransform awbTransform = appVariantOutputContext.getAwbTransformMap().get(awbBundle.getName());\n        File id = null;\n        if ((id = allJavaRes.get(name)) == null) {\n            id = allJavaRes.get(moudleName);\n        }\n        if (id != null) {\n            awbTransform.getLibraryResourcesInutDir().add(id);\n        }\n    }\n\n\n    private void duplicateClazzNote() throws IOException {\n        File outPutFile = new File(appVariantContext.getScope().getGlobalScope().getOutputsDir(), \"duplicate-class.txt\");\n        Set<String> warnList = new HashSet<>();\n        Set<File> jarFiles = compileJars.getArtifactFiles().getFiles();\n        Map<String, String> jarClassNames = Maps.newHashMap();\n        for (File jarFile : jarFiles) {\n            JarFile jar = new JarFile(jarFile);\n            Enumeration<JarEntry> entryEnumeration = jar.entries();\n            while (entryEnumeration.hasMoreElements()) {\n                JarEntry jarEntry = entryEnumeration.nextElement();\n                String className = jarEntry.getName();\n                if (className.endsWith(\".class\")) {\n                    if (jarClassNames.containsKey(className)) {\n                        warnList.add(String.format(\"duplicate class %s in %s and %s\", className, jarClassNames.get(className), jarFile.getAbsolutePath()));\n                        getLogger().warn(String.format(\"duplicate class %s in %s and %s\", className, jarClassNames.get(className), jarFile.getAbsolutePath()));\n                    } else {\n                        jarClassNames.put(className, jarFile.getAbsolutePath());\n                    }\n                }\n            }\n        }\n\n        if (!outPutFile.getParentFile().exists()) {\n            outPutFile.getParentFile().mkdirs();\n            FileUtils.writeLines(outPutFile, warnList, true);\n        }\n\n    }\n\n\n\n    private void fillMainManifest(String name, String moudleName) {\n        File id = null;\n        if ((id = allManifests.get(name)) == null) {\n            id = allManifests.get(moudleName);\n        }\n        if (id != null) {\n            AtlasBuildContext.atlasMainDexHelperMap.get(getVariantName()).getMainManifestFiles().put(id.getParentFile().getAbsolutePath(), true);\n        }\n    }\n\n    private void fillMainSolibs(String name, String moudleName) {\n        File id = null;\n        if ((id = allSolibs.get(name)) == null) {\n            id = allSolibs.get(moudleName);\n        }\n        if (id != null) {\n            AtlasBuildContext.atlasMainDexHelperMap.get(getVariantName()).getMainSoFiles().put(id.getAbsolutePath(), true);\n        }\n    }\n\n    private void fillAllJavaRes(String name, String moudleName) {\n        File id = null;\n        if ((id = allJavaRes.get(name)) == null) {\n            id = allJavaRes.get(moudleName);\n        }\n        if (id != null) {\n            AtlasBuildContext.atlasMainDexHelperMap.get(getVariantName()).getMainResFiles().put(id.getAbsolutePath(), true);\n        }\n    }\n\n\n    private void fillMainJar(String name, String moudleName) {\n        Iterator<FileIdentity> identities = allJars.iterator();\n        while (identities.hasNext()) {\n            FileIdentity fileIdentity = identities.next();\n            if (fileIdentity.name.equals(name) || fileIdentity.name.equals(moudleName)) {\n                if (fileIdentity.localJar && fileIdentity.name.equals(fileIdentity.file.getName())){\n                    identities.remove();\n                    continue;\n                }\n                AtlasBuildContext.atlasMainDexHelperMap.get(getVariantName()).getMainDexFiles().add(fileIdentity);\n                identities.remove();\n            }\n        }\n    }\n\n\n\n\n    public static class ConfigAction extends MtlBaseTaskAction<BuildAtlasEnvTask> {\n\n        private AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext,\n                            BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"build\", \"atlasEnv\");\n        }\n\n        @Override\n        public Class<BuildAtlasEnvTask> getType() {\n            return BuildAtlasEnvTask.class;\n        }\n\n        @Override\n        public void execute(BuildAtlasEnvTask updateDependenciesTask) {\n            super.execute(updateDependenciesTask);\n            updateDependenciesTask.appVariantContext = this.appVariantContext;\n            updateDependenciesTask.compileManifests =\n                    appVariantContext.getScope().getArtifactCollection(COMPILE_CLASSPATH, ALL, MANIFEST);\n            updateDependenciesTask.compileJars =\n                    appVariantContext.getScope().getArtifactCollection(COMPILE_CLASSPATH, ALL, CLASSES);\n\n            updateDependenciesTask.appVariantOutputContext = getAppVariantOutputContext();\n            updateDependenciesTask.nativeLibs = appVariantContext.getScope().getArtifactCollection(COMPILE_CLASSPATH, ALL, JNI);\n\n            updateDependenciesTask.nativeLibs2 = AtlasDependencyGraph.computeArtifactCollection(variantContext.getScope(), AtlasAndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH, ALL, AtlasAndroidArtifacts.AtlasArtifactType.LIBS);\n\n            updateDependenciesTask.javaResources = appVariantContext.getScope().getArtifactCollection(COMPILE_CLASSPATH, ALL, JAVA_RES);\n\n            updateDependenciesTask.res = appVariantContext.getScope().getArtifactCollection(COMPILE_CLASSPATH, ALL, ANDROID_RES);\n\n            updateDependenciesTask.assets = appVariantContext.getScope().getArtifactCollection(COMPILE_CLASSPATH, ALL, ASSETS);\n\n            updateDependenciesTask.symbolListWithPackageNames = appVariantContext.getScope().getArtifactCollection(\n                    RUNTIME_CLASSPATH,\n                    ALL,\n                    AndroidArtifacts.ArtifactType.SYMBOL_LIST_WITH_PACKAGE_NAME);\n\n\n\n            List<ProjectDependency> projectDependencies = new ArrayList<>();\n            appVariantContext.getScope().getVariantDependencies().getCompileClasspath().getAllDependencies().forEach(dependency -> {\n                if (dependency instanceof ProjectDependency) {\n                    projectDependencies.add((ProjectDependency) dependency);\n//                        ((ProjectDependency) dependency).getDependencyProject().getConfigurations().getByName(\"compile\").\n//                                getIncoming()\n//                                .artifactView(\n//                                        config -> {\n//                                            config.attributes(attributes);\n//                                            if (filter != null) {\n//                                                config.componentFilter(filter);\n//                                            }\n//                                            // TODO somehow read the unresolved dependencies?\n//                                            config.lenient(lenientMode);\n//                                        })\n//                                .getArtifacts();\n                }\n            });\n\n        }\n    }\n\n    public static class FileIdentity {\n        public String name;\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (!(o instanceof FileIdentity)) return false;\n\n            FileIdentity that = (FileIdentity) o;\n\n            if (localJar != that.localJar) return false;\n            if (subProject != that.subProject) return false;\n            if (name != null ? !name.equals(that.name) : that.name != null) return false;\n            return file != null ? file.equals(that.file) : that.file == null;\n        }\n\n        @Override\n        public int hashCode() {\n            int result = name != null ? name.hashCode() : 0;\n            result = 31 * result + (file != null ? file.hashCode() : 0);\n            result = 31 * result + (localJar ? 1 : 0);\n            result = 31 * result + (subProject ? 1 : 0);\n            return result;\n        }\n\n        public File file;\n        public boolean localJar;\n        public boolean subProject;\n\n        public FileIdentity(String name, File file, boolean localJar, boolean subProject) {\n            this.name = name;\n            this.file = file;\n            this.localJar = localJar;\n            this.subProject = subProject;\n        }\n    }\n\n    @Nullable\n    private static Spec<ComponentIdentifier> getComponentFilter(\n            @NonNull AndroidArtifacts.ArtifactScope scope) {\n        switch (scope) {\n            case ALL:\n                return null;\n            case EXTERNAL:\n                // since we want both Module dependencies and file based dependencies in this case\n                // the best thing to do is search for non ProjectComponentIdentifier.\n                return id -> !(id instanceof ProjectComponentIdentifier);\n            case MODULE:\n                return id -> id instanceof ProjectComponentIdentifier;\n            default:\n                throw new RuntimeException(\"unknown ArtifactScope value\");\n        }\n    }\n\n\n    private boolean isMBundle(AppVariantContext appVariantContext, AwbBundle awbBundle){\n\n\n        if (awbBundle.getPackageName().equals(\"com.taobao.android.customdetail\")){\n            return false;\n        }\n\n        if (appVariantContext.getAtlasExtension().getTBuildConfig().getOutOfApkBundles().contains(awbBundle.getResolvedCoordinates().getArtifactId())){\n            return false;\n        }\n\n        return appVariantContext.getAtlasExtension().getTBuildConfig().getAllBundlesToMdex() || appVariantContext.getAtlasExtension().getTBuildConfig().getBundleToMdex().contains(awbBundle.getPackageName());\n\n    }\n\n\n    private static class EmptyArtifactCollection implements ArtifactCollection{\n        FileCollection updateFileCollection;\n\n        public EmptyArtifactCollection(FileCollection updateFileCollection) {\n            this.updateFileCollection = updateFileCollection;\n        }\n\n        @Override\n        public FileCollection getArtifactFiles() {\n            return updateFileCollection;\n        }\n\n        @Override\n        public Set<ResolvedArtifactResult> getArtifacts() {\n            return ImmutableSet.of();\n        }\n\n        @Override\n        public Collection<Throwable> getFailures() {\n            return null;\n        }\n\n        @NotNull\n        @Override\n        public Iterator<ResolvedArtifactResult> iterator() {\n            return getArtifacts().iterator();\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/GenerateAtlasSourceTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app;\n\nimport com.alibaba.fastjson.JSON;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.builder.model.MavenCoordinates;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.tasks.app.prepare.BundleInfoSourceCreator;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.bundleinfo.model.BasicBundleInfo;\nimport com.taobao.android.builder.tools.classinject.InjectParam;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.IOUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.tasks.Input;\nimport org.gradle.api.tasks.OutputDirectory;\nimport org.gradle.api.tasks.TaskAction;\nimport org.gradle.internal.impldep.org.codehaus.plexus.util.Base64;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.zip.GZIPOutputStream;\n\npublic class GenerateAtlasSourceTask extends BaseTask {\n\n    private AppVariantContext appVariantContext;\n\n    private File outputDir;\n\n    @OutputDirectory\n    public File getOutputDir() {\n        return outputDir;\n    }\n\n    private InjectParam injectParam;\n\n    @Input\n    public InjectParam getInput() {\n        if (null != injectParam) {\n            return injectParam;\n        }\n        try {\n            injectParam = AtlasBuildContext.sBuilderAdapter.apkInjectInfoCreator.creteInjectParam(appVariantContext);\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return injectParam;\n    }\n\n    @TaskAction\n    void generate() {\n\n        InjectParam injectParam = getInput();\n        boolean supportRemoteComponent = true;\n        if (AtlasBuildContext.androidDependencyTrees.get(getVariantName())!= null) {\n            List<AndroidLibrary> libraries = AtlasBuildContext.androidDependencyTrees.get(getVariantName()).getMainBundle().getAndroidLibraries();\n            if (libraries.size() > 0) {\n                for (AndroidLibrary library : libraries) {\n                    MavenCoordinates coordinates = library.getResolvedCoordinates();\n                    if (coordinates.getArtifactId().equals(\"atlas_core\") && coordinates.getGroupId().equals(\"com.taobao.android\")) {\n                        if (coordinates.getVersion().compareTo(\"5.0.8\") < 0) {\n                            supportRemoteComponent = false;\n                        }\n                    }\n                }\n            }\n        }\n        List<BasicBundleInfo> info = JSON.parseArray(injectParam.bundleInfo,BasicBundleInfo.class);\n        File outputSourceGeneratorFile = new File(outputDir,\"android/taobao/atlas/framework/AtlasBundleInfoGenerator.java\");\n        StringBuffer infoGeneratorSourceStr = new BundleInfoSourceCreator().createBundleInfoSourceStr(info,supportRemoteComponent);\n        outputSourceGeneratorFile.getParentFile().mkdirs();\n        try {\n            FileUtils.writeStringToFile(outputSourceGeneratorFile,infoGeneratorSourceStr.toString());\n        } catch (IOException e) {\n            throw new GradleException(e.getMessage(), e);\n        }\n\n        File outputPropertiesFile = new File(outputDir, \"android/taobao/atlas/framework/FrameworkProperties.java\");\n        List<String> lines = new ArrayList<>();\n        outputPropertiesFile.getParentFile().mkdirs();\n        lines.add(\"package android.taobao.atlas.framework;\");\n        lines.add(\"public class FrameworkProperties {\");\n\n        lines.add(\"private String version = \\\"\" + injectParam.version + \"\\\";\");\n        lines.add(\"public String getVersion() {return version;}\");\n        String escapeExprBundleInfo = escapeExprSpecialWord(injectParam.bundleInfo);\n        if(injectParam.bundleInfo.length()<65535){\n            lines.add(\"public static String bundleInfo = \\\"\" + escapeExprBundleInfo + \"\\\";\");\n            lines.add(\"public static final boolean compressInfo = false;\");\n        }else{\n            String compressBundleInfo = compressBundleInfo(injectParam.bundleInfo);\n            lines.add(\"public static String bundleInfo = \\\"\" + compressBundleInfo + \"\\\";\");\n            lines.add(\"public static final boolean compressInfo = true;\");\n        }\n//        lines.add(\"public static String bundleInfo = \\\"\" + escapeExprSpecialWord(injectParam.bundleInfo) + \"\\\";\");\n        //lines.add(\"public static String bunleInfo = \\\"\\\";\");\n        if (StringUtils.isNotEmpty(injectParam.autoStartBundles)) {\n            lines.add(\"public static String autoStartBundles = \\\"\" + injectParam.autoStartBundles + \"\\\";\");\n        }\n        if (StringUtils.isNotEmpty(injectParam.blackDialogActivity)) {\n            lines.add(\"public static String blackDialogActivity = \\\"\" + injectParam.blackDialogActivity + \"\\\";\");\n        }\n            lines.add(\"public static String autoStart = \\\"\" + injectParam.autoStart + \"\\\";\");\n\n        if (StringUtils.isNotEmpty(injectParam.preLaunch)) {\n            lines.add(\"public static String preLaunch = \\\"\" + injectParam.preLaunch + \"\\\";\");\n        }\n        if (StringUtils.isNotEmpty(injectParam.group)) {\n            lines.add(\"public static String group = \\\"\" + injectParam.group + \"\\\";\");\n        }\n        lines.add(\"public static String outApp = \\\"\" + injectParam.outApp + \"\\\";\");\n\n        lines.add(\"}\");\n\n        try {\n\n            FileUtils.writeLines(outputPropertiesFile, lines);\n            Map output = new HashMap();\n            output.put(\"bundleInfo\", JSON.parseArray(injectParam.bundleInfo));\n            output.put(\"autoStartBundles\", injectParam.autoStartBundles);\n            output.put(\"preLaunch\", injectParam.preLaunch);\n            output.put(\"group\", injectParam.group);\n            output.put(\"outApp\", injectParam.outApp);\n            output.put(\"unit_tag\", injectParam.unit_tag);\n            output.put(\"autoStart\",injectParam.autoStart);\n            output.put(\"blackDialogActivity\",injectParam.blackDialogActivity);\n\n            FileUtils.write(new File(appVariantContext.getProject().getBuildDir(),\n                                     \"outputs/atlasFrameworkProperties.json\"), JSON.toJSONString(output, true));\n\n        } catch (Exception e) {\n            throw new GradleException(e.getMessage(), e);\n        }\n\n    }\n\n    private String compressBundleInfo(String bundleInfo){\n        ByteArrayOutputStream cc = new ByteArrayOutputStream();\n        GZIPOutputStream gzip = null;\n        try {\n\n            gzip = new GZIPOutputStream(cc);\n            gzip.write(bundleInfo.getBytes(\"UTF-8\"));\n            gzip.flush();\n            IOUtils.closeQuietly(gzip);\n            byte[] result = cc.toByteArray();\n            return org.apache.commons.codec.binary.Base64.encodeBase64String(result);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    private String escapeExprSpecialWord(String keyword) {\n        if (StringUtils.isNotBlank(keyword)) {\n            String[] fbsArr = {\"\\\"\"};\n            for (String key : fbsArr) {\n                if (keyword.contains(key)) {\n                    keyword = keyword.replace(key, \"\\\\\" + key);\n                }\n            }\n        }\n        return keyword;\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<GenerateAtlasSourceTask> {\n\n        private AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext,\n                            BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"generate\", \"AtlasSources\");\n        }\n\n        @Override\n        public Class<GenerateAtlasSourceTask> getType() {\n            return GenerateAtlasSourceTask.class;\n        }\n\n        @Override\n        public void execute(GenerateAtlasSourceTask atlasSourceTask) {\n\n            super.execute(atlasSourceTask);\n\n            File srcDir = appVariantContext.getAtlaSourceDir();\n            appVariantContext.getVariantData().javacTask.source(srcDir);\n\n            atlasSourceTask.outputDir = srcDir;\n            atlasSourceTask.appVariantContext = appVariantContext;\n\n        }\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/LogDependenciesTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app;\n\n/**\n * Created by wuzhong on 16/6/13.\n */\n\nimport com.alibaba.fastjson.JSON;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.output.DependencyJson;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.FileNameUtils;\nimport com.taobao.android.builder.tools.guide.AtlasExtensionOutput;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * Record the build dependency information, facilitate the analysis and analysis\n */\npublic class LogDependenciesTask extends BaseTask {\n\n    private AppVariantOutputContext.AppBuildInfo appBuildInfo;\n\n    private AppVariantContext appVariantContext;\n\n    @TaskAction\n    void generate() {\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n            getVariantName());\n        if (null == atlasDependencyTree) {\n            return;\n        }\n\n        File treeFile = new File(getProject().getBuildDir(),\n                                 \"outputs/dependencyTree-\" + getVariantName() + \".json\");\n        File treeFileWithFileSize = new File(\n                getProject().getBuildDir(),\n                \"outputs/dependencyTree-fileSize-\" + getVariantName() + \".json\");\n        File dependenciesFile = new File(getProject().getBuildDir(), \"outputs/dependencies.txt\");\n        File versionProperties = new File(getProject().getBuildDir(), \"outputs/version.properties\");\n        File buildInfo = new File(getProject().getBuildDir(), \"outputs/build.txt\");\n        File pluginDependencies =  new File(getProject().getBuildDir(), \"outputs/pluginDependencies.txt\");\n        File atlasConfig = new File(getProject().getBuildDir(), \"outputs/atlasConfig.json\");\n\n        appBuildInfo.setDependencyTreeFile(treeFile);\n        appBuildInfo.setDependenciesFile(dependenciesFile);\n        appBuildInfo.setVersionPropertiesFile(versionProperties);\n        appBuildInfo.setBuildInfoFile(buildInfo);\n\n        treeFile.delete();\n        dependenciesFile.delete();\n        versionProperties.delete();\n        buildInfo.delete();\n\n        treeFile.getParentFile().mkdirs();\n        try {\n\n            DependencyJson dependencyJson = atlasDependencyTree.getDependencyJson();\n\n            Collections.sort(dependencyJson.getMainDex());\n\n            FileUtils.write(treeFile, JSON.toJSONString(dependencyJson, true));\n\n            dependencyJson = atlasDependencyTree.createDependencyJson(true);\n\n            Collections.sort(dependencyJson.getMainDex());\n\n            FileUtils.write(treeFileWithFileSize, JSON.toJSONString(dependencyJson, true));\n\n            //add to ap\n            appBuildInfo.getOtherFilesMap().put(\"awo/dependencyTree.json\", treeFile);\n\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        //Output runtime plug-in dependency list\n        try {\n            //ClassLoader cl = ClassLoader.getSystemClassLoader();\n            URL[] urls = ((URLClassLoader)LogDependenciesTask.class.getClassLoader()).getURLs();\n            List<String> libraries = new ArrayList<>();\n            for (URL url : urls) {\n                libraries.add(url.getFile());\n            }\n            FileUtils.writeLines(pluginDependencies, libraries);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        try {\n            FileUtils.writeStringToFile(dependenciesFile,\n                                        JSON.toJSONString(atlasDependencyTree.getDependencyJson()));\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        try {\n            FileUtils.writeLines(versionProperties, getSortVersionList(atlasDependencyTree));\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        try {\n            List<String> lines = new ArrayList<>();\n            lines.add(\"gradleVersion:\" + getProject().getGradle().getGradleVersion());\n            lines.add(\"androidPluginVersion:\" + com.android.builder.Version.ANDROID_GRADLE_PLUGIN_VERSION);\n            lines.add(\"buildToolsVersion:\" + appVariantContext.getAppExtension().getBuildToolsVersion());\n            lines.add(\"compileSdkVersion:\" + appVariantContext.getAppExtension().getCompileSdkVersion());\n            lines.add(\"atlasPluginVersion:\" + FileNameUtils.getJarVersionName(LogDependenciesTask.class));\n            lines.addAll(AtlasBuildContext.sBuilderAdapter.buildInfos);\n            FileUtils.writeLines(buildInfo, lines);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        try {\n            FileUtils.write(atlasConfig,\n                            JSON.toJSONString(new AtlasExtensionOutput(appVariantContext.getAtlasExtension(),\n                                                                       appVariantContext.getBuildType().getName()),\n                                              true));\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        if (null != AtlasBuildContext.conflictDependencies &&\n            !AtlasBuildContext.conflictDependencies.isEmpty()) {\n            try {\n                FileUtils.writeLines(new File(getProject().getBuildDir(),\n                                              \"outputs/warning-dependencyConflict.properties\"),\n                                     AtlasBuildContext.conflictDependencies);\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n\n            if (appVariantContext.getAtlasExtension()\n                .getTBuildConfig()\n                .isAbortIfDependencyConflict()) {\n                throw new GradleException(\"Rely on conflict, specific see warning - dependencyConflict. Properties\");\n            }\n        }\n\n    }\n\n    private List<String> getSortVersionList(AtlasDependencyTree atlasDependencyTree) {\n        List<String> versionList = new ArrayList<String>();\n\n        try {\n            Set<String> depsSet = atlasDependencyTree.getFlatDependencies();\n            if (depsSet != null && !depsSet.isEmpty()) {\n                for (String dep : depsSet) {\n                    String[] args = dep.split(\":\");\n                    if (args.length == 5 && args[3].equals(\"system\")) {\n                        continue;\n                    }\n                    String version = args[0] + \".\" + args[1] + \".version=\" + args[args.length - 1];\n                    versionList.add(version);\n                }\n            }\n            Collections.sort(versionList);\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n\n        return versionList;\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<LogDependenciesTask> {\n\n        private final AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext,\n                            BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"log\", \"Dependencies\");\n        }\n\n        @Override\n        public Class<LogDependenciesTask> getType() {\n            return LogDependenciesTask.class;\n        }\n\n        @Override\n        public void execute(LogDependenciesTask logDependenciesTask) {\n            super.execute(logDependenciesTask);\n            logDependenciesTask.appBuildInfo = getAppVariantOutputContext().appBuildInfo;\n            logDependenciesTask.appVariantContext = appVariantContext;\n        }\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/ResourcePatch.java",
    "content": "package com.taobao.android.builder.tasks.app;\n\nimport java.io.BufferedInputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.Collection;\nimport java.util.Enumeration;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.regex.Pattern;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\nimport javax.annotation.Nullable;\n\nimport com.android.apksig.apk.ApkUtils;\nimport com.google.common.base.Preconditions;\nimport com.google.common.collect.Iterables;\nimport com.google.common.io.ByteStreams;\nimport com.google.devrel.gmscore.tools.apk.arsc.Chunk;\nimport com.google.devrel.gmscore.tools.apk.arsc.PackageChunk;\nimport com.google.devrel.gmscore.tools.apk.arsc.ResourceFile;\nimport com.google.devrel.gmscore.tools.apk.arsc.ResourceTableChunk;\nimport com.google.devrel.gmscore.tools.apk.arsc.TypeChunk;\nimport com.google.devrel.gmscore.tools.apk.arsc.TypeChunk.Entry;\nimport com.google.devrel.gmscore.tools.apk.arsc.TypeSpecChunk;\nimport com.taobao.android.builder.tools.zip.ZipUtils;\nimport org.apache.commons.io.FileUtils;\n\n/**\n * Created by chenhjohn on 2018/2/27.\n */\n\npublic class ResourcePatch {\n    public static void makePatchable(@Nullable /*@ApkPath*/ File apk) throws IOException {\n        ResourceTableChunk resourceTableChunk = providesResourceTableChunk(apk);\n        PackageChunk packageChunk = Iterables.getOnlyElement(resourceTableChunk.getPackages());\n        Collection<TypeChunk> typeChunks = packageChunk.getTypeChunks();\n        for (TypeChunk typeChunk : typeChunks) {\n            int totalEntryCount = typeChunk.getTotalEntryCount();\n            Entry lastEntry = typeChunk.getEntries().get(totalEntryCount - 1);\n            for (int i = 0; i < 256; i++) {\n                typeChunk.put(totalEntryCount + i, lastEntry);\n            }\n        }\n        Collection<TypeSpecChunk> typeSpecChunks = packageChunk.getTypeSpecChunks();\n        for (TypeSpecChunk typeSpecChunk : typeSpecChunks) {\n            for (int i = 0; i < 256; i++) {\n                typeSpecChunk.add(0);\n            }\n        }\n        byte[] bytes = resourceTableChunk.toByteArray();\n        File file = new File(apk.getParentFile(), \"resources.arsc\" + \"_tmp\");\n        FileUtils.writeByteArrayToFile(file, bytes);\n        File tmpFile = new File(apk.getParentFile(), apk.getName() + \"_tmp\");\n        ZipUtils.addFileToZipFile(apk, tmpFile, file, \"resources.arsc\", true);\n        apk.delete();\n        tmpFile.renameTo(apk);\n    }\n\n    public static ResourceTableChunk providesResourceTableChunk(@Nullable /*@ApkPath*/ File apk) throws IOException {\n        Preconditions.checkNotNull(apk, \"APK is required. Did you forget --apk=/my/app.apk?\");\n        byte[] resourceBytes = getFile(apk, \"resources.arsc\");\n        if (resourceBytes == null) {\n            throw new IOException(String.format(\"Unable to find %s in APK.\", new Object[] {\"resources.arsc\"}));\n        } else {\n            List<Chunk> chunks = (new ResourceFile(resourceBytes)).getChunks();\n            Preconditions.checkState(chunks.size() == 1,\n                \"%s should only have one root chunk.\",\n                new Object[] {\"resources.arsc\"});\n            Chunk resourceTable = (Chunk)chunks.get(0);\n            Preconditions.checkState(resourceTable instanceof ResourceTableChunk,\n                \"%s root chunk must be a ResourceTableChunk.\",\n                new Object[] {\"resources.arsc\"});\n            return (ResourceTableChunk)resourceTable;\n        }\n    }\n\n    /**\n     * Returns a file whose name matches {@code filename}, or null if no file was found.\n     *\n     * @param apkFile  The file containing the apk zip archive.\n     * @param filename The full filename (e.g. res/raw/foo.bar).\n     * @return A byte array containing the contents of the matching file, or null if not found.\n     * @throws IOException Thrown if there's a matching file, but it cannot be read from the apk.\n     */\n    public static byte[] getFile(File apkFile, String filename) throws IOException {\n        Map<String, byte[]> files = getFiles(apkFile, Pattern.quote(filename));\n        return files.get(filename);\n    }\n\n    /**\n     * Returns all files in an apk that match a given regular expression.\n     *\n     * @param apkFile The file containing the apk zip archive.\n     * @param regex   A regular expression to match the requested filenames.\n     * @return A mapping of the matched filenames to their byte contents.\n     * @throws IOException Thrown if a matching file cannot be read from the apk.\n     */\n    public static Map<String, byte[]> getFiles(File apkFile, String regex) throws IOException {\n        return getFiles(apkFile, Pattern.compile(regex));\n    }\n\n    /**\n     * Returns all files in an apk that match a given regular expression.\n     *\n     * @param apkFile The file containing the apk zip archive.\n     * @param regex   A regular expression to match the requested filenames.\n     * @return A mapping of the matched filenames to their byte contents.\n     * @throws IOException Thrown if a matching file cannot be read from the apk.\n     */\n    public static Map<String, byte[]> getFiles(File apkFile, Pattern regex) throws IOException {\n        Map<String, byte[]> files = new LinkedHashMap<>();  // Retain insertion order\n        // Extract apk\n        try (ZipFile apkZip = new ZipFile(apkFile)) {\n            Enumeration<? extends ZipEntry> zipEntries = apkZip.entries();\n            while (zipEntries.hasMoreElements()) {\n                ZipEntry zipEntry = zipEntries.nextElement();\n                // Visit all files with the given extension\n                if (regex.matcher(zipEntry.getName()).matches()) {\n                    // Map class name to definition\n                    try (InputStream is = new BufferedInputStream(apkZip.getInputStream(zipEntry))) {\n                        files.put(zipEntry.getName(), ByteStreams.toByteArray(is));\n                    }\n                }\n            }\n        }\n        return files;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/ScanDupResTask.java",
    "content": "package com.taobao.android.builder.tasks.app;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.android.build.gradle.internal.publishing.AndroidArtifacts;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.build.gradle.tasks.MergeManifests;\nimport com.android.build.gradle.tasks.ResourceException;\nimport com.android.builder.core.BuilderConstants;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.ide.common.res2.*;\nimport com.android.resources.ResourceType;\nimport com.google.common.base.Preconditions;\nimport com.google.common.collect.ArrayListMultimap;\nimport com.google.common.collect.ListMultimap;\nimport com.google.common.collect.Lists;\nimport com.sun.org.apache.xerces.internal.dom.NamedNodeMapImpl;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.MD5Util;\nimport javafx.util.Pair;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.artifacts.ArtifactCollection;\nimport org.gradle.api.artifacts.result.ResolvedArtifactResult;\nimport org.gradle.api.tasks.TaskAction;\n\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport java.io.File;\nimport java.io.IOException;\nimport java.lang.reflect.Field;\nimport java.util.*;\nimport java.util.function.Consumer;\n\n/**\n * ScanDupResTask\n *\n * @author zhayu.ll\n * @date 18/8/10\n */\npublic class ScanDupResTask extends BaseTask {\n\n    private AppVariantOutputContext appVariantOutputContext;\n\n    private AppVariantContext appVariantContext;\n\n    @TaskAction\n    void generate() {\n\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n                getVariantName());\n        if (null == atlasDependencyTree) {\n            return;\n        }\n        File dupResFile = new File(appVariantContext.getProject().getBuildDir(),\"outputs/warning-dup-res.properties\");\n        File dupAssetsFile = new File(appVariantContext.getProject().getBuildDir(),\"outputs/warning-dup-assets.properties\");\n\n        ArtifactCollection res = appVariantContext.getScope().getArtifactCollection(AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH,AndroidArtifacts.ArtifactScope.ALL,AndroidArtifacts.ArtifactType.ANDROID_RES);\n        ArtifactCollection assets = appVariantContext.getScope().getArtifactCollection(AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH,AndroidArtifacts.ArtifactScope.ALL,AndroidArtifacts.ArtifactType.ASSETS);\n\n        Set<String> errors = new HashSet<>();\n\n        Map<Pair<String,File>,String>map1 = new HashMap<>();\n        for (File file :assets.getArtifactFiles().getFiles()){\n            Collection<File> files = FileUtils.listFiles(file,null,true);\n           for (File file1:files){\n               boolean e = false;\n               for (Pair stringFilePair:map1.keySet()){\n                   if (stringFilePair.getKey().equals(file1.getAbsolutePath().substring(file1.getAbsolutePath().indexOf(\"assets\"))) && !isSameFile((File) stringFilePair.getValue(),file1)&&!map1.get(stringFilePair).equals(file.getAbsolutePath())){\n                       errors.add(\"dup assets:\"+file1.getName() +\" in \"+map1.get(stringFilePair) + \" and \"+file.getAbsolutePath());\n                       e = true;\n                       break;\n                   }\n               }\n\n               if (!e){\n\n                       map1.put(new Pair<>(file1.getAbsolutePath().substring(file1.getAbsolutePath().indexOf(\"assets\")),file1),file.getAbsolutePath());\n               }\n\n\n           }\n        }\n        try {\n            FileUtils.writeLines(dupAssetsFile,errors);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        Map<String,File> map = new HashMap<>();\n        Map<String,Pair<String,File>>valuesMap = new HashMap<>();\n        List<String> exceptions = new ArrayList<>();\n\n        ResourceMerger resourceMerger = new ResourceMerger(14);\n        if (res != null) {\n            Set<ResolvedArtifactResult> libArtifacts = res.getArtifacts();\n            List<ResourceSet> resourceSetList = Lists.newArrayListWithExpectedSize(libArtifacts.size());\n            // the order of the artifact is descending order, so we need to reverse it.\n            for (ResolvedArtifactResult artifact : libArtifacts) {\n                ResourceSet resourceSet =\n                        new ResourceSet(\n                                MergeManifests.getArtifactName(artifact),\n                                null,\n                                null,\n                                true);\n                resourceSet.setFromDependency(true);\n                resourceSet.addSource(artifact.getFile());\n\n                // add to 0 always, since we need to reverse the order.\n                resourceSetList.add(0,resourceSet);\n            }\n            resourceSetList.forEach(resourceSet -> {\n                try {\n                    resourceSet.loadFromFiles(getILogger());\n                } catch (MergingException e) {\n                    e.printStackTrace();\n                }\n                resourceMerger.addDataSet(resourceSet);\n            });\n\n            ListMultimap<String, ResourceItem> mValuesResMap = ArrayListMultimap.create();\n\n            try {\n                resourceMerger.mergeData(new MergeConsumer<ResourceItem>() {\n                    @Override\n                    public void start(DocumentBuilderFactory documentBuilderFactory) throws ConsumerException {\n\n                    }\n\n                    @Override\n                    public void end() throws ConsumerException {\n\n                    }\n\n                    @Override\n                    public void addItem(ResourceItem item) throws ConsumerException {\n                        DataFile.FileType type = item.getSourceType();\n                        if (type == DataFile.FileType.XML_VALUES) {\n                            mValuesResMap.put(item.getQualifiers(), item);\n                        } else {\n                            File file = null;\n                            String folderName = null;\n                            Preconditions.checkState(item.getSource() != null);\n                            file = item.getFile();\n                            folderName = getFolderName(item);\n//                            if (ResourceItem.isTouched()) {\n                            String tag= folderName+\"/\"+file.getName();\n\n                            if (type == DataFile.FileType.GENERATED_FILES) {\n                                if (!map.containsKey(tag)){\n                                    map.put(tag,file);\n                                }else if (!map.get(tag).equals(file)){\n                                    if (!isSameBundle(map.get(tag),file,atlasDependencyTree)\n                                            && allInMainBundle(getId(map.get(tag)),getId(file),atlasDependencyTree)\n                                            && !isSameFile(map.get(tag),file))\n                                        exceptions.add(\"dup File:\"+tag+\"|\"+getId(map.get(tag))+\"|\"+getId(file));\n                                }\n//                                    try {\n//                                        MergedResourceWriter.FileGenerationParameters workItem = new MergedResourceWriter.FileGenerationParameters(item, this.mPreprocessor);\n//                                        if (workItem.resourceItem.getSource() != null) {\n//                                            this.getExecutor().submit(workItem);\n//                                        }\n//                                    } catch (Exception var6) {\n//                                        throw new ConsumerException(var6, ((ResourceFile)item.getSource()).getFile());\n//                                    }\n                            }else if (type == DataFile.FileType.SINGLE_FILE){\n                                if (!map.containsKey(tag)){\n                                    map.put(tag,file);\n                                }else if (!map.get(tag).equals(file)){\n                                    if (!isSameBundle(map.get(tag),file,atlasDependencyTree)\n                                            && allInMainBundle(getId(map.get(tag)),getId(file),atlasDependencyTree)\n                                            && !isSameFile(map.get(tag),file))\n                                        exceptions.add(\"dup File:\"+tag+\"|\"+getId(map.get(tag))+\"|\"+getId(file));\n                                }\n                            }\n\n//                                this.mCompileResourceRequests.add(new CompileResourceRequest(file, this.getRootFolder(), folderName));\n//                            }\n                        }\n                    }\n\n                    @Override\n                    public void removeItem(ResourceItem removedItem, ResourceItem replacedBy) throws ConsumerException {\n                        DataFile.FileType removedType = removedItem.getSourceType();\n                        DataFile.FileType replacedType = replacedBy != null ? replacedBy.getSourceType() : null;\n                        switch(removedType) {\n                            case SINGLE_FILE:\n                            case GENERATED_FILES:\n                                if (replacedType == DataFile.FileType.SINGLE_FILE || replacedType == DataFile.FileType.GENERATED_FILES) {\n//                                    System.out.println(removedItem.getQualifiers()+\":\"+removedItem.getQualifiers());\n//                                    File removedFile = getResourceOutputFile(removedItem);\n//                                    File replacedFile = getResourceOutputFile(replacedBy);\n//                                    if (removedFile.equals(replacedFile)) {\n//                                        break;\n//                                    }\n                                }\n\n//                                this.removeOutFile(removedItem);\n                                break;\n                            case XML_VALUES:\n                                mValuesResMap.put(removedItem.getQualifiers(), replacedBy);\n//                                System.out.println(removedItem.getQualifiers());\n//                                this.mQualifierWithDeletedValues.add(removedItem.getQualifiers());\n                                break;\n                            default:\n                                throw new IllegalStateException();\n                        }\n                    }\n\n                    @Override\n                    public boolean ignoreItemInMerge(ResourceItem item) {\n                        DataFile.FileType type = item.getSourceType();\n                        if (type == DataFile.FileType.XML_VALUES) {\n                            mValuesResMap.put(item.getQualifiers(), item);\n                        } else {\n                            File file = null;\n                            String folderName = null;\n                            Preconditions.checkState(item.getSource() != null);\n                            file = item.getFile();\n                            folderName = getFolderName(item);\n//                            if (ResourceItem.isTouched()) {\n                            String tag= folderName+\"/\"+file.getName();\n\n                            if (type == DataFile.FileType.GENERATED_FILES) {\n                                if (!map.containsKey(tag)){\n                                    map.put(tag,file);\n                                }else if (!map.get(tag).equals(file)){\n                                    if (!isSameBundle(map.get(tag),file,atlasDependencyTree)&&allInMainBundle(getId(map.get(tag)),getId(file),atlasDependencyTree)\n                                            && !isSameFile(map.get(tag),file))\n                                        exceptions.add(\"dup File:\"+tag+\"|\"+getId(map.get(tag))+\"|\"+getId(file));\n                                }\n//                                    try {\n//                                        MergedResourceWriter.FileGenerationParameters workItem = new MergedResourceWriter.FileGenerationParameters(item, this.mPreprocessor);\n//                                        if (workItem.resourceItem.getSource() != null) {\n//                                            this.getExecutor().submit(workItem);\n//                                        }\n//                                    } catch (Exception var6) {\n//                                        throw new ConsumerException(var6, ((ResourceFile)item.getSource()).getFile());\n//                                    }\n                            }else if (type == DataFile.FileType.SINGLE_FILE){\n                                if (!map.containsKey(tag)){\n                                    map.put(tag,file);\n                                    if (!isSameBundle(map.get(tag),file,atlasDependencyTree)\n                                            && allInMainBundle(getId(map.get(tag)),getId(file),atlasDependencyTree)\n                                            && !isSameFile(map.get(tag),file))\n                                        exceptions.add(\"dup File:\"+tag+\"|\"+getId(map.get(tag))+\"|\"+getId(file));\n                                }\n                            }\n\n//                                this.mCompileResourceRequests.add(new CompileResourceRequest(file, this.getRootFolder(), folderName));\n//                            }\n                        }\n                        return false;\n                    }\n                },false);\n            } catch (MergingException e) {\n                e.printStackTrace();\n            }\n\n            mValuesResMap.asMap().values().forEach(resourceItems -> {\n                for (ResourceItem resourceItem:resourceItems){\n                    String tag = null;\n                    if (resourceItem.getSource() == null){\n                        tag = resourceItem.getQualifiers() + \":\" +resourceItem.getType().getName()+\":\"+resourceItem.getName();\n\n                    }else {\n                        tag = resourceItem.getQualifiers() + \":\" +  resourceItem.getKey();\n                    }\n                    if (!valuesMap.containsKey(tag)){\n                        String value = getOtherString(resourceItem);\n                        if (resourceItem.getSource() == null ||resourceItem.getFile() == null) {\n                            valuesMap.put(tag, new Pair<String,File>(value,new File(\"aa\")));\n                        }else {\n                            valuesMap.put(tag, new Pair<String, File>(value,resourceItem.getFile()));\n\n                        }\n                    }else {\n                        if (resourceItem.getFile()!= null && valuesMap.get(tag)!= null) {\n                            if (!valuesMap.get(tag).equals(resourceItem.getFile()) && !isSameValue(resourceItem,valuesMap.get(tag).getKey()))\n                                if (!tag.equals(\":string/app_name\")) {\n                                    exceptions.add(\"dup value \" + tag + \"|\" + valuesMap.get(tag).getKey() + \"|\" + getOtherString(resourceItem) + \"|\" + getId(valuesMap.get(tag).getValue()) + \"|\" + getId(resourceItem.getFile()));\n                                }\n                                }\n                    }\n                }\n\n            });\n\n            Collections.sort(exceptions);\n            try {\n                FileUtils.writeLines(dupResFile,exceptions);\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n\n\n    }\n\n    public static class ConfigActon extends MtlBaseTaskAction<ScanDupResTask>{\n\n        private AppVariantContext variantContext;\n        public ConfigActon(VariantContext variantContext, BaseVariantOutput baseVariantOutput) {\n            super(variantContext, baseVariantOutput);\n            this.variantContext = (AppVariantContext) variantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"scan\", \"DupRes\");\n        }\n\n        @Override\n        public Class<ScanDupResTask> getType() {\n            return ScanDupResTask.class;\n        }\n\n        @Override\n        public void execute(ScanDupResTask scanDupResTask) {\n            super.execute(scanDupResTask);\n            if (!variantContext.getAtlasExtension().getTBuildConfig().getScanDupRes()){\n                scanDupResTask.setEnabled(false);\n                return;\n            }\n            scanDupResTask.appVariantContext = variantContext;\n            scanDupResTask.appVariantOutputContext = getAppVariantOutputContext();\n        }\n    }\n\n    private boolean isSameBundle(File file, File file1, AtlasDependencyTree atlasDependencyTree) {\n\n        return false;\n//        String id1 = getId(file);\n//        String id2 = getId(file1);\n//\n//        return isSameBundle(id1,id2,atlasDependencyTree);\n\n\n    }\n\n    private String getId(File file){\n        String id1= file.getAbsolutePath().substring(file.getAbsolutePath().indexOf(\"files-1.1\")+10);\n        id1 = id1.substring(0,id1.indexOf(\"/\"));\n        return id1;\n    }\n\n\n\n    private static String getFolderName(ResourceItem resourceItem) {\n        ResourceType itemType = resourceItem.getType();\n        String folderName = itemType.getName();\n        String qualifiers = resourceItem.getQualifiers();\n        if (!qualifiers.isEmpty()) {\n            folderName = folderName + \"-\" + qualifiers;\n        }\n\n        return folderName;\n    }\n\n\n    private boolean allInMainBundle(String id1,String id2,AtlasDependencyTree atlasDependencyTree){\n\n        return true;\n\n    }\n\n\n    private boolean isSameFile(File file1,File file2){\n        return MD5Util.getFileMD5(file1).equals(MD5Util.getFileMD5(file2));\n    }\n\n    private boolean isSameValue(ResourceItem resourceItem,String value){\n\n       return getOtherString(resourceItem).equals(value);\n    }\n\n    private String getOtherString(ResourceItem resourceItem){\n\n        if (resourceItem.getValue().getFirstChild() != null && hasValues(resourceItem)){\n            return resourceItem.getValue().getFirstChild().toString();\n        }\n        Field field = null;\n        try {\n            field = NamedNodeMapImpl.class.getDeclaredField(\"nodes\");\n            ((Field) field).setAccessible(true);\n            return field.get(resourceItem.getValue().getAttributes()).toString();\n        } catch (NoSuchFieldException e) {\n            e.printStackTrace();\n        } catch (IllegalAccessException e) {\n            e.printStackTrace();\n        }\n        return \"\";\n\n    }\n\n    private boolean hasValues(ResourceItem resourceItem) {\n        return resourceItem.getType().getName().equals(\"bool\")\n                ||resourceItem.getType().getName().equals(\"color\")\n                ||resourceItem.getType().getName().equals(\"id\")\n                ||resourceItem.getType().getName().equals(\"integer\")\n                ||resourceItem.getType().getName().equals(\"string\")\n                ||resourceItem.getType().getName().equals(\"public\");\n    }\n\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/bundle/AtlasSymbolIo.java",
    "content": "package com.taobao.android.builder.tasks.app.bundle;\n\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.builder.symbols.*;\nimport com.android.ide.common.xml.AndroidManifestParser;\nimport com.android.resources.ResourceType;\nimport com.android.utils.FileUtils;\nimport com.android.utils.ILogger;\nimport com.google.common.base.Charsets;\nimport com.google.common.base.Preconditions;\nimport com.google.common.base.Splitter;\nimport com.google.common.collect.ImmutableCollection;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Lists;\nimport com.google.common.io.ByteStreams;\nimport org.xml.sax.SAXException;\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.io.PrintWriter;\nimport java.io.UncheckedIOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.function.Function;\nimport java.util.stream.Collectors;\nimport javax.xml.parsers.ParserConfigurationException;\n\n/**\n * @author lilong\n * @create 2017-12-18 上午11:17\n */\n\npublic class AtlasSymbolIo {\n\n\n    public static final String ANDROID_ATTR_PREFIX = \"android_\";\n\n    private static ILogger logger = LoggerWrapper.getLogger(AtlasSymbolIo.class);\n\n    private AtlasSymbolIo() {}\n\n    /**\n     * Loads a symbol table from a symbol file.\n     *\n     * @param file the symbol file\n     * @param tablePackage the package name associated with the table\n     * @return the table read\n     * @throws IOException failed to read the table\n     */\n    @NonNull\n    public static SymbolTable read(@NonNull File file, @Nullable String tablePackage)\n            throws IOException {\n        return read(file, tablePackage, AtlasSymbolIo.InOrderHandler::new);\n    }\n\n    /**\n     * Loads a symbol table from a symbol file created by aapt\n     *\n     * @param file the symbol file\n     * @param tablePackage the package name associated with the table\n     * @return the table read\n     * @throws IOException failed to read the table\n     */\n    @NonNull\n    public static SymbolTable readFromAapt(@NonNull File file, @Nullable String tablePackage)\n            throws IOException {\n        return read(file, tablePackage, AtlasSymbolIo.AaptHandler::new);\n    }\n\n    @NonNull\n    private static SymbolTable read(\n            @NonNull File file,\n            @Nullable String tablePackage,\n            @NonNull Function<String, AtlasSymbolIo.StyleableIndexHandler> handlerFunction)\n            throws IOException {\n        List<String> lines = Files.readAllLines(file.toPath(), Charsets.UTF_8);\n//        Collections.reverse(lines);\n        SymbolTable.Builder table = readLines(lines, 1, file.toPath(), handlerFunction);\n\n        if (tablePackage != null) {\n            table.tablePackage(tablePackage);\n        }\n\n        return table.build();\n    }\n\n    /**\n     * Loads a symbol table from a synthetic namespaced symbol file.\n     *\n     * <p>This is just a symbol table, but with the addition of the table package as the first line.\n     *\n     * @param file the symbol file\n     * @return the table read\n     * @throws IOException failed to read the table\n     */\n    @NonNull\n    public static SymbolTable readTableWithPackage(@NonNull File file) throws IOException {\n        return readTableWithPackage(file.toPath());\n    }\n\n    @NonNull\n    public static SymbolTable readTableWithPackage(@NonNull Path file) throws IOException {\n\n        List<String> lines = Files.readAllLines(file, Charsets.UTF_8);\n\n        if (lines.isEmpty()) {\n            throw new IOException(\"Internal error: Symbol file with package cannot be empty.\");\n        }\n\n        SymbolTable.Builder table = readLines(lines, 2, file, AtlasSymbolIo.InOrderHandler::new);\n        table.tablePackage(lines.get(0).trim());\n\n        return table.build();\n    }\n\n    @NonNull\n    private static SymbolTable.Builder readLines(\n            @NonNull List<String> lines,\n            int startLine,\n            @NonNull Path file,\n            @NonNull Function<String, AtlasSymbolIo.StyleableIndexHandler> handlerFunction)\n            throws IOException {\n        SymbolTable.Builder table = SymbolTable.builder();\n\n        int lineIndex = startLine;\n        String line = null;\n        try {\n            final AtlasSymbolIo.SymbolFilter symbolFilter =\n                    (resType, javaType) ->\n                            resType.equals(ResourceType.STYLEABLE.getName())\n                                    && javaType.equals(SymbolJavaType.INT.getTypeName());\n\n            final int count = lines.size();\n            for (; lineIndex <= count; lineIndex++) {\n                line = lines.get(lineIndex - 1);\n\n                AtlasSymbolIo.SymbolData data = readLine(line, null);\n                // because there are some misordered file out there we want to make sure\n                // both the resType is Styleable and the javaType is array.\n                // We skip the non arrays that are out of sort\n                // data cannot be null, since the filter is null\n                // noinspection ConstantConditions\n                if (data.resourceType == ResourceType.STYLEABLE) {\n                    if (data.javaType == SymbolJavaType.INT_LIST) {\n                        final String data_name = data.name + \"_\";\n                        AtlasSymbolIo.StyleableIndexHandler indexHandler = handlerFunction.apply(data_name);\n                        AtlasSymbolIo.SymbolData subData;\n                        // read the next line\n                        while (lineIndex < count\n                                && (subData = readLine(lines.get(lineIndex), symbolFilter))\n                                != null) {\n                            // line is value, inc the index\n                            lineIndex++;\n\n                            // noinspection ConstantConditions\n                            indexHandler.handle(subData);\n                        }\n\n                        Symbol symbol = Symbol.createSymbol(\n                                data.resourceType,\n                                data.name,\n                                data.javaType,\n                                data.value,\n                                indexHandler.getChildrenNames());\n                        if (!table.contains(symbol)) {\n                            table.add(symbol);\n                        }else {\n                        }\n                    }\n\n                } else {\n                    Symbol symbol = Symbol.createSymbol(\n                            data.resourceType,\n                            data.name,\n                            data.javaType,\n                            data.value,\n                            ImmutableList.of());\n                    if (!table.contains(symbol)) {\n                        table.add(symbol);\n                    }else {\n                    }\n                }\n            }\n        } catch (IndexOutOfBoundsException | IOException e) {\n            throw new IOException(\n                    String.format(\n                            \"File format error reading %s line %d: '%s'\",\n                            file.toString(), lineIndex, line),\n                    e);\n        }\n\n        return table;\n    }\n\n    private static class SymbolData {\n        @NonNull final ResourceType resourceType;\n        @NonNull final String name;\n        @NonNull final SymbolJavaType javaType;\n        @NonNull final String value;\n\n        public SymbolData(\n                @NonNull ResourceType resourceType,\n                @NonNull String name,\n                @NonNull SymbolJavaType javaType,\n                @NonNull String value) {\n            this.resourceType = resourceType;\n            this.name = name;\n            this.javaType = javaType;\n            this.value = value;\n        }\n    }\n\n    @FunctionalInterface\n    private interface SymbolFilter {\n        boolean validate(@NonNull String resourceType, @NonNull String javaType);\n    }\n\n    @Nullable\n    private static AtlasSymbolIo.SymbolData readLine(@NonNull String line, @Nullable AtlasSymbolIo.SymbolFilter filter)\n            throws IOException {\n        // format is \"<type> <class> <name> <value>\"\n        // don't want to split on space as value could contain spaces.\n        int pos = line.indexOf(' ');\n        String typeName = line.substring(0, pos);\n\n        SymbolJavaType type = SymbolJavaType.getEnum(typeName);\n        int pos2 = line.indexOf(' ', pos + 1);\n        String className = line.substring(pos + 1, pos2);\n\n        if (filter != null && !filter.validate(className, typeName)) {\n            return null;\n        }\n\n        ResourceType resourceType = ResourceType.getEnum(className);\n        if (resourceType == null) {\n            throw new IOException(\"Invalid resource type \" + className);\n        }\n        int pos3 = line.indexOf(' ', pos2 + 1);\n        String name = line.substring(pos2 + 1, pos3);\n        String value = line.substring(pos3 + 1);\n\n        return new SymbolData(resourceType, name, type, value);\n    }\n\n    /** Handler for the styleable indices read from a R.txt file. */\n    private interface StyleableIndexHandler {\n        void handle(@NonNull AtlasSymbolIo.SymbolData data);\n\n        @NonNull\n        List<String> getChildrenNames();\n    }\n\n    private abstract static class BaseHandler implements AtlasSymbolIo.StyleableIndexHandler {\n        @NonNull protected final String prefix;\n\n        BaseHandler(@NonNull String prefix) {\n            this.prefix = prefix;\n        }\n\n        protected String computeItemName(@NonNull String name) {\n            // tweak the name to remove the styleable prefix\n            String indexName = name.substring(prefix.length());\n            // check if it's a namespace, in which case replace android_name\n            // with android:name\n            if (indexName.startsWith(ANDROID_ATTR_PREFIX)) {\n                indexName =\n                        SdkConstants.ANDROID_NS_NAME_PREFIX\n                                + indexName.substring(ANDROID_ATTR_PREFIX.length());\n            }\n\n            return indexName;\n        }\n    }\n\n    /** Handler that just create the children name in the order the items are read */\n    private static class InOrderHandler extends AtlasSymbolIo.BaseHandler {\n\n        @NonNull private final List<String> childrenNames = Lists.newArrayList();\n\n        InOrderHandler(@NonNull String prefix) {\n            super(prefix);\n        }\n\n        @Override\n        public void handle(@NonNull AtlasSymbolIo.SymbolData subData) {\n            // check if the sub item actually belongs to this declare-styleable,\n            // because of broken R.txt files.\n            // We could have a int/styleable that follows a int[]/styleable but\n            // is an index for a different declare-styleable.\n            if (subData.name.startsWith(prefix)) {\n                childrenNames.add(computeItemName(subData.name));\n            }\n        }\n\n        @NonNull\n        @Override\n        public List<String> getChildrenNames() {\n            return ImmutableList.copyOf(childrenNames);\n        }\n    }\n\n    /**\n     * Handler sorting the items based on their values rather than the order they are read.\n     *\n     * <p>This is compatible with R.txt files generated by aapt.\n     */\n    private static class AaptHandler extends AtlasSymbolIo.BaseHandler {\n        @NonNull private final List<AtlasSymbolIo.SymbolData> allDatas = Lists.newArrayList();\n\n        public AaptHandler(@NonNull String prefix) {\n            super(prefix);\n        }\n\n        @Override\n        public void handle(@NonNull AtlasSymbolIo.SymbolData data) {\n            allDatas.add(data);\n        }\n\n        @NonNull\n        @Override\n        public List<String> getChildrenNames() {\n            // sort the data by their values.\n            allDatas.sort(Comparator.comparingInt(o -> Integer.parseInt(o.value)));\n\n            // now extract the names only, and remove the prefix\n            return allDatas.stream().map(this::computeName).collect(Collectors.toList());\n        }\n\n        @NonNull\n        private String computeName(@NonNull AtlasSymbolIo.SymbolData data) {\n            return computeItemName(data.name);\n        }\n    }\n\n    /**\n     * Writes a symbol table to a symbol file.\n     *\n     * @param table the table\n     * @param file the file where the table should be written\n     * @throws UncheckedIOException I/O error\n     */\n    public static void write(@NonNull SymbolTable table, @NonNull File file) {\n        write(table, file.toPath());\n    }\n\n    public static void write(@NonNull SymbolTable table, @NonNull Path file) {\n\n        try (BufferedOutputStream os = new BufferedOutputStream(Files.newOutputStream(file));\n             PrintWriter pw = new PrintWriter(os)) {\n\n            // loop on the resource types so that the order is always the same\n            for (ResourceType resType : ResourceType.values()) {\n                List<Symbol> symbols = getSymbolByResourceType(table, resType);\n                if (symbols.isEmpty()) {\n                    continue;\n                }\n\n                for (Symbol s : symbols) {\n                    pw.print(s.getJavaType().getTypeName());\n                    pw.print(' ');\n                    pw.print(s.getResourceType().getName());\n                    pw.print(' ');\n                    pw.print(s.getName());\n                    pw.print(' ');\n                    pw.print(s.getValue());\n                    pw.print('\\n');\n\n                    // Declare styleables have the attributes that were defined under their node\n                    // listed in\n                    // the children list.\n                    if (s.getJavaType() == SymbolJavaType.INT_LIST) {\n                        Preconditions.checkArgument(\n                                s.getResourceType() == ResourceType.STYLEABLE,\n                                \"Only resource type 'styleable' is allowed to have java type 'int[]'\");\n\n                        List<String> children = s.getChildren();\n                        for (int i = 0; i < children.size(); ++i) {\n                            pw.print(SymbolJavaType.INT.getTypeName());\n                            pw.print(' ');\n                            pw.print(ResourceType.STYLEABLE.getName());\n                            pw.print(' ');\n                            pw.print(s.getName());\n                            pw.print('_');\n                            pw.print(SymbolUtils.canonicalizeValueResourceName(children.get(i)));\n                            pw.print(' ');\n                            pw.print(Integer.toString(i));\n                            pw.print('\\n');\n                        }\n                    }\n                }\n            }\n        } catch (IOException e) {\n            throw new UncheckedIOException(e);\n        }\n    }\n\n    /**\n     * Writes the symbol table with the package name as the first line.\n     *\n     * @param symbolTable The R.txt file. If it does not exist, the result will be a file containing\n     *     only the package name\n     * @param manifest The AndroidManifest.xml file for this library. The package name is extracted\n     *     and written as the first line of the output.\n     * @param outputFile The file to write the result to.\n     */\n    public static void writeSymbolTableWithPackage(\n            @NonNull Path symbolTable, @NonNull Path manifest, @NonNull Path outputFile)\n            throws IOException {\n        @Nullable String packageName;\n        try (InputStream is = new BufferedInputStream(Files.newInputStream(manifest))) {\n            packageName = AndroidManifestParser.parse(is).getPackage();\n        } catch (SAXException | ParserConfigurationException e) {\n            throw new IOException(e);\n        }\n        try (OutputStream os = new BufferedOutputStream(Files.newOutputStream(outputFile))) {\n            if (packageName != null) {\n                os.write(packageName.getBytes(Charsets.UTF_8));\n            }\n            os.write('\\n');\n            if (!Files.exists(symbolTable)) {\n                return;\n            }\n            try (InputStream is = new BufferedInputStream(Files.newInputStream(symbolTable))) {\n                ByteStreams.copy(is, os);\n            }\n        }\n    }\n\n    /**\n     * Exports a symbol table to a java {@code R} class source. This method will create the source\n     * file and any necessary directories. For example, if the package is {@code a.b} and the class\n     * name is {@code RR}, this method will generate a file called {@code RR.java} in directory\n     * {@code directory/a/b} creating directories {@code a} and {@code b} if necessary.\n     *\n     * @param table the table to export\n     * @param directory the directory where the R source should be generated\n     * @param finalIds should the generated IDs be final?\n     * @return the generated file\n     * @throws UncheckedIOException failed to generate the source\n     */\n    @NonNull\n    public static File exportToJava(\n            @NonNull SymbolTable table, @NonNull File directory, boolean finalIds) {\n        Preconditions.checkArgument(directory.isDirectory());\n\n        /*\n         * Build the path to the class file, creating any needed directories.\n         */\n        Splitter splitter = Splitter.on('.');\n        Iterable<String> directories = splitter.split(table.getTablePackage());\n        File file = directory;\n        for (String d : directories) {\n            file = new File(file, d);\n        }\n\n        FileUtils.mkdirs(file);\n        file = new File(file, SdkConstants.R_CLASS + SdkConstants.DOT_JAVA);\n\n        String idModifiers = finalIds ? \"public static final\" : \"public static\";\n\n        try (PrintWriter pw =\n                     new PrintWriter(new BufferedOutputStream(Files.newOutputStream(file.toPath())))) {\n\n            pw.println(\"/* AUTO-GENERATED FILE.  DO NOT MODIFY.\");\n            pw.println(\" *\");\n            pw.println(\" * This class was automatically generated by the\");\n            pw.println(\" * gradle plugin from the resource data it found. It\");\n            pw.println(\" * should not be modified by hand.\");\n            pw.println(\" */\");\n\n            if (!table.getTablePackage().isEmpty()) {\n                pw.print(\"package \");\n                pw.print(table.getTablePackage());\n                pw.print(';');\n                pw.println();\n            }\n\n            pw.println();\n            pw.println(\"public final class R {\");\n\n            final String typeName = SymbolJavaType.INT.getTypeName();\n\n            // loop on the resource types so that the order is always the same\n            for (ResourceType resType : ResourceType.values()) {\n                List<Symbol> symbols = getSymbolByResourceType(table, resType);\n                if (symbols.isEmpty()) {\n                    continue;\n                }\n                pw.print(\"    public static final class \");\n                pw.print(resType.getName());\n                pw.print(\" {\");\n                pw.println();\n\n                for (Symbol s : symbols) {\n                    final String name = s.getName();\n                    pw.print(\"        \");\n                    pw.print(idModifiers);\n                    pw.print(' ');\n                    pw.print(s.getJavaType().getTypeName());\n                    pw.print(' ');\n                    pw.print(name);\n                    pw.print(\" = \");\n                    pw.print(s.getValue());\n                    pw.print(';');\n                    pw.println();\n\n                    // Declare styleables have the attributes that were defined under their\n                    // node\n                    // listed in the children list.\n                    if (s.getJavaType() == SymbolJavaType.INT_LIST) {\n                        Preconditions.checkArgument(\n                                s.getResourceType() == ResourceType.STYLEABLE,\n                                \"Only resource type 'styleable'\"\n                                        + \" is allowed to have java type 'int[]'\");\n                        List<String> children = s.getChildren();\n                        for (int i = 0; i < children.size(); ++i) {\n                            pw.print(\"        \");\n                            pw.print(idModifiers);\n                            pw.print(' ');\n                            pw.print(typeName);\n                            pw.print(' ');\n                            pw.print(name);\n                            pw.print('_');\n                            pw.print(SymbolUtils.canonicalizeValueResourceName(children.get(i)));\n                            pw.print(\" = \");\n                            pw.print(i);\n                            pw.print(';');\n                            pw.println();\n                        }\n                    }\n                }\n                pw.print(\"    }\");\n                pw.println();\n            }\n\n            pw.print('}');\n            pw.println();\n        } catch (IOException e) {\n            throw new UncheckedIOException(e);\n        }\n\n        return file;\n    }\n\n    /**\n     * Collect all the symbols for a particular symbol type to a sorted list of symbols.\n     *\n     * <p>The symbols are sorted by name to make output predicable and, therefore, testing easier.\n     */\n    @NonNull\n    private static List<Symbol> getSymbolByResourceType(\n            @NonNull SymbolTable table, @NonNull ResourceType type) {\n        final Comparator<Symbol> nameComparator = Comparator.comparing(Symbol::getName);\n\n        final ImmutableCollection<Symbol> symbolCollection = table.getSymbols().row(type).values();\n\n        List<Symbol> symbols = Lists.newArrayList(symbolCollection);\n        symbols.sort(nameComparator);\n        return symbols;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/bundle/AwbApkPackageTask.java",
    "content": "package com.taobao.android.builder.tasks.app.bundle;\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.Enumeration;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.stream.Stream;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\nimport java.util.zip.ZipOutputStream;\n\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.apkzlib.utils.IOExceptionWrapper;\nimport com.android.apkzlib.zip.compress.Zip64NotSupportedException;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.android.build.gradle.internal.incremental.DexPackagingPolicy;\nimport com.android.build.gradle.internal.incremental.FileType;\nimport com.android.build.gradle.internal.incremental.InstantRunBuildContext;\nimport com.android.build.gradle.internal.packaging.IncrementalPackagerBuilder;\nimport com.android.build.gradle.internal.scope.BuildOutput;\nimport com.android.build.gradle.internal.scope.BuildOutputs;\nimport com.android.build.gradle.internal.scope.DefaultGradlePackagingScope;\nimport com.android.build.gradle.internal.scope.OutputScope;\nimport com.android.build.gradle.internal.scope.TaskOutputHolder;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.tasks.KnownFilesSaveData;\nimport com.android.builder.core.AndroidBuilder;\nimport com.android.builder.files.FileCacheByPath;\nimport com.android.builder.files.IncrementalRelativeFileSets;\nimport com.android.builder.files.RelativeFile;\nimport com.android.builder.internal.packaging.IncrementalPackager;\nimport com.android.builder.model.SigningConfig;\nimport com.android.builder.packaging.PackagingUtils;\nimport com.android.ide.common.build.ApkData;\nimport com.android.ide.common.res2.FileStatus;\nimport com.android.utils.FileUtils;\nimport com.google.common.base.Predicates;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Maps;\nimport com.google.common.io.ByteStreams;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tools.zip.BetterZip;\nimport org.gradle.api.file.FileCollection;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\n\n/**\n * @author lilong\n * @create 2017-12-06 上午11:17\n */\n\npublic class AwbApkPackageTask {\n\n    private final String taskName;\n    private FileCollection resourceFiles;\n    private OutputScope outputScope;\n    private AwbBundle awbBundle;\n    private File outputDirectory;\n    private AppVariantOutputContext appVariantOutputContext;\n    private FileCollection dexFolders;\n    private FileCollection javaResouresFiles;\n    private FileCollection assets;\n    private FileCollection jniFolders;\n    private FileCollection awbManifestFolder;\n    protected InstantRunBuildContext instantRunContext;\n\n\n    private static final String ZIP_DIFF_CACHE_DIR = \"zip-cache\";\n\n    private static final String ZIP_64_COPY_DIR = \"zip64-copy\";\n    private DexPackagingPolicy dexPackagingPolicy = DexPackagingPolicy.STANDARD;\n    private SigningConfig signingConfig;\n    private AndroidBuilder androidBuilder;\n    private int miniSdkVersion;\n    private boolean debug;\n    private Set<String> supportAbis;\n    private boolean jniDebug;\n    Collection<String> aaptOptionsNoCompress;\n    private DefaultGradlePackagingScope packagingScope;\n\n    public AwbApkPackageTask(FileCollection resourceFiles, VariantContext variantContext, AwbBundle awbBundle, AppVariantOutputContext appVariantOutputContext, FileCollection dexFolders,\n                             FileCollection javaResouresFiles, FileCollection assets, FileCollection jniFolders, FileCollection awbManifestFolder, AndroidBuilder androidBuilder,\n                             int miniSdkVersion, String taskName) {\n        this.packagingScope = new DefaultGradlePackagingScope(variantContext.getScope());\n        this.resourceFiles = resourceFiles;\n        this.outputScope = variantContext.getScope().getOutputScope();\n        this.awbBundle = awbBundle;\n        this.appVariantOutputContext = appVariantOutputContext;\n        this.outputDirectory = ((AppVariantContext) variantContext).getAwbApkOutputDir();\n        this.dexFolders = dexFolders;\n        this.javaResouresFiles = javaResouresFiles;\n        this.assets = assets;\n        this.jniFolders = jniFolders;\n        this.awbManifestFolder = awbManifestFolder;\n        this.instantRunContext = packagingScope.getInstantRunBuildContext();\n        this.signingConfig = packagingScope.getSigningConfig();\n        this.androidBuilder = androidBuilder;\n        this.miniSdkVersion = miniSdkVersion;\n        this.debug = packagingScope.isDebuggable();\n        supportAbis = packagingScope.getSupportedAbis();\n        this.jniDebug = packagingScope.isJniDebuggable();\n        aaptOptionsNoCompress = packagingScope.getAaptOptions().getNoCompress();\n        this.taskName = taskName;\n\n\n    }\n\n    public File getAwbPackageOutputFile(AppVariantContext variantContext, String awbOutputName) {\n        Set<String> libSoNames = variantContext.getAtlasExtension().getTBuildConfig().getKeepInLibSoNames();\n\n        File file = null;\n        if (libSoNames.isEmpty() || libSoNames.contains(awbOutputName)) {\n            //直接移动到主apk的lib下\n            file = new File(packagingScope.getJniFolders().getSingleFile(), \"lib/armeabi\" + File.separator + awbOutputName);\n        } else {\n            file = new File(variantContext.getVariantData().mergeAssetsTask.getOutputDir(), awbOutputName);\n        }\n\n        Set<String> assetsSoNames = variantContext.getAtlasExtension().getTBuildConfig().getKeepInAssetsSoNames();\n        if (!assetsSoNames.isEmpty() && assetsSoNames.contains(awbOutputName)) {\n            file = new File(variantContext.getVariantData().mergeAssetsTask.getOutputDir(), awbOutputName);\n        }\n        return file;\n    }\n\n    public File doFullTaskAction() throws IOException {\n        if (supportAbis == null){\n            supportAbis = ImmutableSet.of();\n        }\n        ApkData apkData = appVariantOutputContext.getScope().getOutputScope().getApkDatas().get(0);\n        if (dexFolders.getSingleFile().exists() && awbBundle.getMergedManifest().exists()) {\n            File[] dexFile = dexFolders.getSingleFile().listFiles((dir, name) -> name.equals(\"classes.dex\"));\n            if (dexFile != null) {\n                File file = AtlasBuildContext.atlasApkProcessor.securitySignApk(dexFile[0], awbBundle.getMergedManifest(),appVariantOutputContext.getVariantContext().getBuildType(),true);\n                if (file!= null && file.exists()) {\n                    BetterZip.addFile(getAndroidResources(apkData, resourceFiles.getSingleFile()).iterator().next(), \"res/drawable/\".concat(file.getName()), file);\n                }\n            }\n        }\n        File file = splitFullAction(apkData, resourceFiles.getSingleFile());\n        outputScope.save(VariantScope.TaskOutputType.APK, outputDirectory);\n        return file;\n    }\n\n\n    public File splitFullAction(@NonNull ApkData apkData, @Nullable File processedResources)\n            throws IOException {\n\n        File incrementalDirForSplit = new File(getIncrementalFolder(awbBundle), apkData.getFullName());\n\n        /*\n         * Clear the intermediate build directory. We don't know if anything is in there and\n         * since this is a full build, we don't want to get any interference from previous state.\n         */\n        if (incrementalDirForSplit.exists()) {\n            FileUtils.deleteDirectoryContents(incrementalDirForSplit);\n        } else {\n            FileUtils.mkdirs(incrementalDirForSplit);\n        }\n\n        File cacheByPathDir = new File(incrementalDirForSplit, ZIP_DIFF_CACHE_DIR);\n        FileUtils.mkdirs(cacheByPathDir);\n        FileCacheByPath cacheByPath = new FileCacheByPath(cacheByPathDir);\n\n        /*\n         * Clear the cache to make sure we have do not do an incremental build.\n         */\n        cacheByPath.clear();\n\n        Set<File> androidResources = getAndroidResources(apkData, processedResources);\n\n        appVariantOutputContext.getVariantContext().getProject().getLogger().warn(awbBundle.getName()+\" androidResources File:\"+androidResources.iterator().next().getAbsolutePath());\n\n        FileUtils.mkdirs(outputDirectory);\n\n        File outputFile = getOutputFile(awbBundle);\n\n        /*\n         * Additionally, make sure we have no previous package, if it exists.\n         */\n        FileUtils.deleteIfExists(outputFile);\n\n        ImmutableMap<RelativeFile, FileStatus> updatedDex =\n                IncrementalRelativeFileSets.fromZipsAndDirectories(dexFolders);\n        ImmutableMap<RelativeFile, FileStatus> updatedJavaResources = getJavaResourcesChanges();\n        ImmutableMap<RelativeFile, FileStatus> updatedAssets =\n                IncrementalRelativeFileSets.fromZipsAndDirectories(assets.getFiles());\n        ImmutableMap<RelativeFile, FileStatus> updatedAndroidResources =\n                IncrementalRelativeFileSets.fromZipsAndDirectories(androidResources);\n        ImmutableMap<RelativeFile, FileStatus> updatedJniResources =\n                IncrementalRelativeFileSets.fromZipsAndDirectories(jniFolders);\n\n        Collection<BuildOutput> manifestOutputs = BuildOutputs.load(TaskOutputHolder.TaskOutputType.MERGED_MANIFESTS, awbManifestFolder.getSingleFile().getParentFile());\n\n        doTask(\n                apkData,\n                incrementalDirForSplit,\n                outputFile,\n                cacheByPath,\n                manifestOutputs,\n                updatedDex,\n                updatedJavaResources,\n                updatedAssets,\n                updatedAndroidResources,\n                updatedJniResources);\n\n        /*\n         * Update the known files.\n         */\n        KnownFilesSaveData saveData = KnownFilesSaveData.make(incrementalDirForSplit);\n        saveData.setInputSet(updatedDex.keySet(), KnownFilesSaveData.InputSet.DEX);\n        saveData.setInputSet(updatedJavaResources.keySet(), KnownFilesSaveData.InputSet.JAVA_RESOURCE);\n        saveData.setInputSet(updatedAssets.keySet(), KnownFilesSaveData.InputSet.ASSET);\n        saveData.setInputSet(updatedAndroidResources.keySet(), KnownFilesSaveData.InputSet.ANDROID_RESOURCE);\n        saveData.setInputSet(updatedJniResources.keySet(), KnownFilesSaveData.InputSet.NATIVE_RESOURCE);\n        saveData.saveCurrentData();\n        File file;\n        String outputFileName = outputFile.getName();\n        file = getAwbPackageOutputFile(appVariantOutputContext.getVariantContext(), outputFileName);\n        FileUtils.copyFileToDirectory(outputFile, file.getParentFile());\n        return new File(file.getParentFile(), outputFileName);\n    }\n\n    private void doTask(\n            @NonNull ApkData apkData,\n            @NonNull File incrementalDirForSplit,\n            @NonNull File outputFile,\n            @NonNull FileCacheByPath cacheByPath,\n            @NonNull Collection<BuildOutput> manifestOutputs,\n            @NonNull ImmutableMap<RelativeFile, FileStatus> changedDex,\n            @NonNull ImmutableMap<RelativeFile, FileStatus> changedJavaResources,\n            @NonNull ImmutableMap<RelativeFile, FileStatus> changedAssets,\n            @NonNull ImmutableMap<RelativeFile, FileStatus> changedAndroidResources,\n            @NonNull ImmutableMap<RelativeFile, FileStatus> changedNLibs)\n            throws IOException {\n\n        ImmutableMap.Builder<RelativeFile, FileStatus> javaResourcesForApk =\n                ImmutableMap.builder();\n        javaResourcesForApk.putAll(changedJavaResources);\n\n        if (dexPackagingPolicy == DexPackagingPolicy.INSTANT_RUN_MULTI_APK) {\n            changedDex = ImmutableMap.copyOf(\n                    Maps.filterKeys(\n                            changedDex,\n                            Predicates.compose(\n                                    Predicates.in(dexFolders.getFiles()),\n                                    RelativeFile::getBase\n                            )));\n        }\n        final ImmutableMap<RelativeFile, FileStatus> dexFilesToPackage = changedDex;\n\n        String abiFilter = apkData.getFilter(com.android.build.OutputFile.FilterType.ABI);\n\n        // find the manifest file for this split.\n        BuildOutput manifestForSplit =\n                OutputScope.getOutput(manifestOutputs, TaskOutputHolder.TaskOutputType.MERGED_MANIFESTS, apkData);\n\n        FileUtils.mkdirs(outputFile.getParentFile());\n\n        try (IncrementalPackager packager =\n                     new IncrementalPackagerBuilder()\n                             .withOutputFile(outputFile)\n                             .withSigning(null)\n                             .withCreatedBy(androidBuilder.getCreatedBy())\n                             .withMinSdk(miniSdkVersion)\n                             // TODO: allow extra metadata to be saved in the split scope to avoid\n                             // reparsing\n                             // these manifest files.\n                             .withNativeLibraryPackagingMode(\n                                     PackagingUtils.getNativeLibrariesLibrariesPackagingMode(manifestForSplit == null ? awbManifestFolder.getSingleFile() :\n                                             manifestForSplit.getOutputFile()))\n                             .withNoCompressPredicate(\n                                     PackagingUtils.getNoCompressPredicate(\n                                             aaptOptionsNoCompress, manifestForSplit == null ? awbManifestFolder.getSingleFile():manifestForSplit.getOutputFile()))\n                             .withIntermediateDir(incrementalDirForSplit)\n                             .withProject(appVariantOutputContext.getScope().getGlobalScope().getProject())\n                             .withDebuggableBuild(debug)\n                             .withAcceptedAbis(\n                                     abiFilter == null ? supportAbis : ImmutableSet.of(abiFilter))\n                             .withJniDebuggableBuild(jniDebug)\n                             .build()) {\n            packager.updateDex(dexFilesToPackage);\n            packager.updateJavaResources(changedJavaResources);\n            packager.updateAssets(changedAssets);\n            packager.updateAndroidResources(changedAndroidResources);\n            packager.updateNativeLibraries(changedNLibs);\n            // Only report APK as built if it has actually changed.\n            if (packager.hasPendingChangesWithWait()) {\n                // FIX-ME : below would not work in multi apk situations. There is code somewhere\n                // to ensure we only build ONE multi APK for the target device, make sure it is still\n                // active.\n                instantRunContext.addChangedFile(FileType.MAIN, outputFile);\n            }\n        }\n\n        /*\n         * Save all used zips in the cache.\n         */\n        Stream.concat(\n                dexFilesToPackage.keySet().stream(),\n                Stream.concat(\n                        changedJavaResources.keySet().stream(),\n                        Stream.concat(\n                                changedAndroidResources.keySet().stream(),\n                                changedNLibs.keySet().stream())))\n                .map(RelativeFile::getBase)\n                .filter(File::isFile)\n                .distinct()\n                .forEach(\n                        (File f) -> {\n                            try {\n                                cacheByPath.add(f);\n                            } catch (IOException e) {\n                                throw new IOExceptionWrapper(e);\n                            }\n                        });\n    }\n\n    @NonNull\n    Set<File> getAndroidResources(@NonNull ApkData apkData, @Nullable File processedResources)\n            throws IOException {\n\n        //todo :for instantrun mode ....\n//        if (instantRunContext.isInInstantRunMode()\n//                && instantRunContext.getPatchingPolicy()\n//                == InstantRunPatchingPolicy.MULTI_APK_SEPARATE_RESOURCES) {\n//            Collection<BuildOutput> manifestFiles =\n//                    BuildOutputs.load(\n//                            TaskOutputHolder.TaskOutputType.INSTANT_RUN_MERGED_MANIFESTS,\n//                            manifests);\n//            BuildOutput manifestOutput =\n//                    OutputScope.getOutput(\n//                            manifestFiles,\n//                            TaskOutputHolder.TaskOutputType.INSTANT_RUN_MERGED_MANIFESTS,\n//                            apkData);\n//\n//            if (manifestOutput == null) {\n//                throw new RuntimeException(\"Cannot find merged manifest file\");\n//            }\n//            File manifestFile = manifestOutput.getOutputFile();\n//            return ImmutableSet.of(generateEmptyAndroidResourcesForInstantRun(manifestFile));\n//        } else {\n        return processedResources != null\n                ? ImmutableSet.of(processedResources)\n                : ImmutableSet.of();\n//        }\n    }\n\n\n    private File getOutputFile(AwbBundle awbBundle) {\n        if (null != awbBundle.outputBundleFile) {\n            return awbBundle.outputBundleFile;\n        }\n\n        if (AtlasBuildContext.sBuilderAdapter.packageRemoteAwbInJni && awbBundle.isRemote) {\n            File file = appVariantOutputContext.getAwbPackageOutAppOutputFile(awbBundle);\n            appVariantOutputContext.appBuildInfo.getOtherFilesMap()\n                    .put(\"remotebundles/\" + file.getName(), file);\n            return file;\n        }\n\n        return appVariantOutputContext.getAwbPackageOutputFile(awbBundle);\n    }\n\n\n    ImmutableMap<RelativeFile, FileStatus> getJavaResourcesChanges() throws IOException {\n\n        ImmutableMap.Builder<RelativeFile, FileStatus> updatedJavaResourcesBuilder =\n                ImmutableMap.builder();\n        for (File javaResourceFile : javaResouresFiles) {\n            try {\n                updatedJavaResourcesBuilder.putAll(\n                        javaResourceFile.isFile()\n                                ? IncrementalRelativeFileSets.fromZip(javaResourceFile)\n                                : IncrementalRelativeFileSets.fromDirectory(javaResourceFile));\n            } catch (Zip64NotSupportedException e) {\n                updatedJavaResourcesBuilder.putAll(\n                        IncrementalRelativeFileSets.fromZip(\n                                copyJavaResourcesOnly(getIncrementalFolder(awbBundle), javaResourceFile)));\n            }\n        }\n        return updatedJavaResourcesBuilder.build();\n    }\n\n    private File getIncrementalFolder(AwbBundle awbBundle) {\n\n        return new File(packagingScope.getIncrementalDir(taskName), awbBundle.getName());\n\n\n    }\n\n    static File copyJavaResourcesOnly(File destinationFolder, File zip64File) throws IOException {\n        File cacheDir = new File(destinationFolder, ZIP_64_COPY_DIR);\n        File copiedZip = new File(cacheDir, zip64File.getName());\n        FileUtils.mkdirs(copiedZip.getParentFile());\n\n        try (ZipFile inFile = new ZipFile(zip64File);\n             ZipOutputStream outFile =\n                     new ZipOutputStream(\n                             new BufferedOutputStream(new FileOutputStream(copiedZip)))) {\n\n            Enumeration<? extends ZipEntry> entries = inFile.entries();\n            while (entries.hasMoreElements()) {\n                ZipEntry zipEntry = entries.nextElement();\n                if (!zipEntry.getName().endsWith(SdkConstants.DOT_CLASS)) {\n                    outFile.putNextEntry(new ZipEntry(zipEntry.getName()));\n                    try {\n                        ByteStreams.copy(\n                                new BufferedInputStream(inFile.getInputStream(zipEntry)), outFile);\n                    } finally {\n                        outFile.closeEntry();\n                    }\n                }\n            }\n        }\n        return copiedZip;\n    }\n\n\n    public void doIncrementalTaskAction(Map<File, FileStatus> changedInputs) throws IOException {\n        checkNotNull(changedInputs, \"changedInputs == null\");\n        outputScope.parallelForEachOutput(\n                BuildOutputs.load(TaskOutputHolder.TaskOutputType.PROCESSED_RES, resourceFiles),\n                TaskOutputHolder.TaskOutputType.PROCESSED_RES,\n                TaskOutputHolder.TaskOutputType.PROCESSED_RES,\n                (split, output) -> splitIncrementalAction(split, output, changedInputs));\n        outputScope.save(TaskOutputHolder.TaskOutputType.PROCESSED_RES, outputDirectory);\n    }\n\n    private File splitIncrementalAction(\n            ApkData apkData, @Nullable File processedResources, Map<File, FileStatus> changedInputs)\n            throws IOException {\n\n        Set<File> androidResources = getAndroidResources(apkData, processedResources);\n\n        File incrementalDirForSplit = new File(getIncrementalFolder(awbBundle), apkData.getFullName());\n\n        File cacheByPathDir = new File(incrementalDirForSplit, ZIP_DIFF_CACHE_DIR);\n        if (!cacheByPathDir.exists()) {\n            FileUtils.mkdirs(cacheByPathDir);\n        }\n        FileCacheByPath cacheByPath = new FileCacheByPath(cacheByPathDir);\n\n        KnownFilesSaveData saveData = KnownFilesSaveData.make(incrementalDirForSplit);\n\n        final Set<File> assetsFiles = assets.getFiles();\n\n        Set<Runnable> cacheUpdates = new HashSet<>();\n        ImmutableMap<RelativeFile, FileStatus> changedDexFiles =\n                KnownFilesSaveData.getChangedInputs(\n                        changedInputs,\n                        saveData,\n                        KnownFilesSaveData.InputSet.DEX,\n                        dexFolders.getFiles(),\n                        cacheByPath,\n                        cacheUpdates);\n\n        ImmutableMap<RelativeFile, FileStatus> changedJavaResources;\n        try {\n            changedJavaResources =\n                    KnownFilesSaveData.getChangedInputs(\n                            changedInputs,\n                            saveData,\n                            KnownFilesSaveData.InputSet.JAVA_RESOURCE,\n                            javaResouresFiles.getFiles(),\n                            cacheByPath,\n                            cacheUpdates);\n        } catch (Zip64NotSupportedException e) {\n            // copy all changedInputs into a smaller jar and rerun.\n            ImmutableMap.Builder<File, FileStatus> copiedInputs = ImmutableMap.builder();\n            for (Map.Entry<File, FileStatus> fileFileStatusEntry : changedInputs.entrySet()) {\n                copiedInputs.put(\n                        copyJavaResourcesOnly(getIncrementalFolder(awbBundle), fileFileStatusEntry.getKey()),\n                        fileFileStatusEntry.getValue());\n            }\n            changedJavaResources =\n                    KnownFilesSaveData.getChangedInputs(\n                            copiedInputs.build(),\n                            saveData,\n                            KnownFilesSaveData.InputSet.JAVA_RESOURCE,\n                            javaResouresFiles.getFiles(),\n                            cacheByPath,\n                            cacheUpdates);\n        }\n\n        ImmutableMap<RelativeFile, FileStatus> changedAssets =\n                KnownFilesSaveData.getChangedInputs(\n                        changedInputs,\n                        saveData,\n                        KnownFilesSaveData.InputSet.ASSET,\n                        assetsFiles,\n                        cacheByPath,\n                        cacheUpdates);\n\n        ImmutableMap<RelativeFile, FileStatus> changedAndroidResources =\n                KnownFilesSaveData.getChangedInputs(\n                        changedInputs,\n                        saveData,\n                        KnownFilesSaveData.InputSet.ANDROID_RESOURCE,\n                        androidResources,\n                        cacheByPath,\n                        cacheUpdates);\n\n        ImmutableMap<RelativeFile, FileStatus> changedNLibs =\n                KnownFilesSaveData.getChangedInputs(\n                        changedInputs,\n                        saveData,\n                        KnownFilesSaveData.InputSet.NATIVE_RESOURCE,\n                        jniFolders.getFiles(),\n                        cacheByPath,\n                        cacheUpdates);\n\n        File outputFile = getOutputFile(awbBundle);\n\n        Collection<BuildOutput> manifestOutputs = BuildOutputs.load(TaskOutputHolder.TaskOutputType.MERGED_MANIFESTS, awbManifestFolder.getSingleFile().getParentFile());\n\n        doTask(\n                apkData,\n                incrementalDirForSplit,\n                outputFile,\n                cacheByPath,\n                manifestOutputs,\n                changedDexFiles,\n                changedJavaResources,\n                changedAssets,\n                changedAndroidResources,\n                changedNLibs);\n\n        /*\n         * Update the cache\n         */\n        cacheUpdates.forEach(Runnable::run);\n\n        /*\n         * Update the save data keep files.\n         */\n        ImmutableMap<RelativeFile, FileStatus> allDex =\n                IncrementalRelativeFileSets.fromZipsAndDirectories(dexFolders);\n        ImmutableMap<RelativeFile, FileStatus> allJavaResources =\n                IncrementalRelativeFileSets.fromZipsAndDirectories(javaResouresFiles);\n        ImmutableMap<RelativeFile, FileStatus> allAssets =\n                IncrementalRelativeFileSets.fromZipsAndDirectories(assetsFiles);\n        ImmutableMap<RelativeFile, FileStatus> allAndroidResources =\n                IncrementalRelativeFileSets.fromZipsAndDirectories(androidResources);\n        ImmutableMap<RelativeFile, FileStatus> allJniResources =\n                IncrementalRelativeFileSets.fromZipsAndDirectories(jniFolders);\n\n        saveData.setInputSet(allDex.keySet(), KnownFilesSaveData.InputSet.DEX);\n        saveData.setInputSet(allJavaResources.keySet(), KnownFilesSaveData.InputSet.JAVA_RESOURCE);\n        saveData.setInputSet(allAssets.keySet(), KnownFilesSaveData.InputSet.ASSET);\n        saveData.setInputSet(allAndroidResources.keySet(), KnownFilesSaveData.InputSet.ANDROID_RESOURCE);\n        saveData.setInputSet(allJniResources.keySet(), KnownFilesSaveData.InputSet.NATIVE_RESOURCE);\n        saveData.saveCurrentData();\n        return outputFile;\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/bundle/AwbJavaCompileConfigAction.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.bundle;\n\nimport com.android.build.api.transform.QualifiedContent;\nimport com.android.build.gradle.api.AnnotationProcessorOptions;\nimport com.android.build.gradle.internal.CompileOptions;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.pipeline.OriginalStream;\nimport com.android.build.gradle.internal.publishing.AndroidArtifacts;\nimport com.android.build.gradle.internal.scope.ConventionMappingHelper;\nimport com.android.build.gradle.internal.scope.TaskConfigAction;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.tasks.factory.AbstractCompilesUtil;\nimport com.android.build.gradle.tasks.factory.AndroidJavaCompile;\nimport com.android.build.gradle.tasks.factory.AwbAndroidJavaCompile;\nimport com.android.builder.profile.ProcessProfileWriter;\nimport com.android.utils.FileUtils;\nimport com.android.utils.ILogger;\nimport com.google.common.base.Joiner;\nimport com.google.wireless.android.sdk.stats.GradleBuildProject;\nimport com.google.wireless.android.sdk.stats.GradleBuildVariant;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport org.gradle.api.Action;\nimport org.gradle.api.Task;\nimport org.gradle.api.artifacts.Configuration;\nimport org.gradle.api.file.FileCollection;\nimport org.gradle.api.tasks.compile.JavaCompile;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.sql.Ref;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.Callable;\n\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactScope.ALL;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactType.*;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ConsumedConfigType.ANNOTATION_PROCESSOR;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH;\nimport static com.android.build.gradle.internal.scope.TaskOutputHolder.TaskOutputType.ANNOTATION_PROCESSOR_LIST;\nimport static com.android.build.gradle.internal.scope.TaskOutputHolder.TaskOutputType.DATA_BINDING_DEPENDENCY_ARTIFACTS;\n/**\n * @author lilong\n * @create 2017-12-08 上午3:43\n */\n\npublic class AwbJavaCompileConfigAction implements TaskConfigAction<AwbAndroidJavaCompile> {\n\n    private static final ILogger LOG = LoggerWrapper.getLogger(AwbJavaCompileConfigAction.class);\n\n    private AwbBundle awbBundle;\n\n    private AppVariantOutputContext appVariantOutputContext;\n\n    private VariantScope scope;\n\n    public AwbJavaCompileConfigAction(AwbBundle awbBundle,\n                                      AppVariantOutputContext appVariantOutputContext) {\n        this.awbBundle = awbBundle;\n        this.appVariantOutputContext = appVariantOutputContext;\n        this.scope = appVariantOutputContext.getScope();\n    }\n\n    @Override\n    public String getName() {\n        return scope.getTaskName(\"compileAwb\", \"JavaWithJavac[\" + awbBundle.getName() + \"]\");\n    }\n\n    @Override\n    public Class<AwbAndroidJavaCompile> getType() {\n        return AwbAndroidJavaCompile.class;\n    }\n\n    /**\n     * AwbInstantRun is not supported for the moment\n     *\n     * @param javacTask\n     */\n    @Override\n    public void execute(AwbAndroidJavaCompile javacTask) {\n\n        appVariantOutputContext.getAwbJavacTasks().put(awbBundle.getName(), javacTask);\n        ProcessAwbAndroidResources processAwbAndroidResources = appVariantOutputContext.getAwbAndroidResourcesMap()\n                .get(awbBundle.getName());\n        assert null != processAwbAndroidResources;\n\n        javacTask.source(processAwbAndroidResources.getSourceOutputDir());\n        if (appVariantOutputContext.getVariantContext().isDataBindEnabled(awbBundle) && awbBundle.isDataBindEnabled()) {\n            javacTask.source(appVariantOutputContext.getVariantContext()\n                    .getAwbClassOutputForDataBinding(awbBundle));\n        }\n\n\n//        ConventionMappingHelper.map(javacTask, \"classpath\", (Callable<FileCollection>) () -> getInputJars());\n\n        FileCollection classpath = getInputJars();\n\n        javacTask.setDestinationDir(appVariantOutputContext.getJAwbavaOutputDir(awbBundle));\n\n        final boolean keepDefaultBootstrap = scope.keepDefaultBootstrap();\n\n        if (!keepDefaultBootstrap) {\n            // Set boot classpath if we don't need to keep the default.  Otherwise, this is added as\n            // normal classpath.\n            javacTask\n                    .getOptions()\n                    .setBootClasspath(\n                            Joiner.on(File.pathSeparator)\n                                    .join(\n                                            scope.getGlobalScope()\n                                                    .getAndroidBuilder()\n                                                    .getBootClasspathAsStrings(false)));\n        }\n\n//        FileCollection classpath = scope.getJavaClasspath(COMPILE_CLASSPATH, CLASSES);\n        if (keepDefaultBootstrap) {\n            classpath =\n                    classpath.plus(\n                            appVariantOutputContext.getVariantContext().getProject().files(appVariantOutputContext.getScope().getGlobalScope().getAndroidBuilder().getBootClasspath(false)));\n        }\n        javacTask.setClasspath(classpath);\n\n        appVariantOutputContext.getScope().getTransformManager().addStream(OriginalStream.builder(appVariantOutputContext.getVariantContext().getProject(), \"awb-classes\")\n                .addContentType(QualifiedContent.DefaultContentType.CLASSES)\n                .addScope(QualifiedContent.Scope.PROJECT)\n                .setFileCollection(appVariantOutputContext.getVariantContext().getProject().files(appVariantOutputContext.getJAwbavaOutputDir(awbBundle)))\n                .build());\n        appVariantOutputContext.getAwbTransformMap().get(awbBundle.getName()).addDir(appVariantOutputContext.getJAwbavaOutputDir(awbBundle));\n        CompileOptions compileOptions = scope.getGlobalScope().getExtension().getCompileOptions();\n        AbstractCompilesUtil.configureLanguageLevel(javacTask,\n                compileOptions,\n                scope.getGlobalScope()\n                        .getExtension()\n                        .getCompileSdkVersion(),\n                scope.getJava8LangSupportType());\n        javacTask.getOptions().setEncoding(compileOptions.getEncoding());\n\n        Boolean includeCompileClasspath =\n                scope.getVariantConfiguration()\n                        .getJavaCompileOptions()\n                        .getAnnotationProcessorOptions()\n                        .getIncludeCompileClasspath();\n\n        FileCollection processorPath =\n                scope.getArtifactFileCollection(ANNOTATION_PROCESSOR, ALL, JAR);\n        if (Boolean.TRUE.equals(includeCompileClasspath)) {\n            // We need the jar files because annotation processors require the resources.\n            processorPath = processorPath.plus(scope.getJavaClasspath(COMPILE_CLASSPATH, JAR));\n        }\n\n        javacTask.getOptions().setAnnotationProcessorPath(processorPath);\n\n\n        boolean incremental = AbstractCompilesUtil.isIncremental(\n                appVariantOutputContext.getScope().getGlobalScope().getProject(),\n                scope,\n                compileOptions,\n                null, /* processorConfiguration, JavaCompile handles annotation processor now */\n                LOG);\n\n        javacTask.getOptions().setIncremental(incremental);\n\n\n        AnnotationProcessorOptions annotationProcessorOptions =\n                scope.getVariantConfiguration().getJavaCompileOptions()\n                        .getAnnotationProcessorOptions();\n\n\n//        javacTask.getOptions().getCompilerArgs().add(\"-processorpath\");\n//            javacTask.getOptions().getCompilerArgs().add(FileUtils.joinFilePaths(processorPath));\n\n        if (!annotationProcessorOptions.getClassNames().isEmpty()) {\n            javacTask.getOptions().getCompilerArgs().add(\"-processor\");\n            javacTask.getOptions().getCompilerArgs().add(\n                    Joiner.on(',').join(annotationProcessorOptions.getClassNames()));\n        }\n\n        if (!annotationProcessorOptions.getArguments().isEmpty()) {\n            for (Map.Entry<String, String> arg :\n                    annotationProcessorOptions.getArguments().entrySet()) {\n\n                String key = arg.getKey();\n                String value = arg.getValue();\n\n                if (\"android.databinding.modulePackage\".equals(key)) {\n                    value = awbBundle.getPackageName() + \"._bundleapp_\";\n                } else if (\"android.databinding.artifactType\".equals(key)) {\n                    //value = \"LIBRARY\";\n                } else if (\"android.databinding.xmlOutDir\".equals(key)) {\n                    value = appVariantOutputContext.getVariantContext().getAwbLayoutInfoOutputForDataBinding(awbBundle)\n                            .getAbsolutePath();\n                } else if (\"android.databinding.bindingBuildFolder\".equals(key)) {\n                    value = appVariantOutputContext.getVariantContext().getAwbDataBindingMergeArtifacts(awbBundle).getParentFile()\n                            .getAbsolutePath();\n                } else if (\"android.databinding.generationalFileOutDir\".equals(key)) {\n                    value = value + \"-\" + awbBundle.getName();\n                }\n\n                javacTask.getOptions().getCompilerArgs().add(\n                        \"-A\" + key + \"=\" + value);\n            }\n        }\n\n        javacTask.getOptions().getCompilerArgs().add(\"-s\");\n        javacTask.getOptions().getCompilerArgs().add(\n                appVariantOutputContext.getVariantContext().getAwbAnnotationProcessorOutputDir(awbBundle).getAbsolutePath());\n\n        FileUtils.mkdirs(appVariantOutputContext.getVariantContext().getAwbAnnotationProcessorOutputDir(awbBundle));\n\n        if (scope.getGlobalScope().getExtension().getDataBinding().isEnabled()\n                && appVariantOutputContext.getVariantContext().isDataBindEnabled(awbBundle)) {\n            File file = appVariantOutputContext.getVariantContext().getAwbDataBindingMergeArtifacts(awbBundle);\n            ReflectUtils.updateField(javacTask, \"dataBindingDependencyArtifacts\", scope.getGlobalScope().getProject().files(file));\n\n\n\n//            FileCollection files =\n//                    appVariantOutputContext.getScope().getArtifactCollection(COMPILE_CLASSPATH, ALL, DATA_BINDING_ARTIFACT).getArtifactFiles();\n//            for (File databingFile : files.getFiles()) {\n//                for (File binFile : org.apache.commons.io.FileUtils.listFiles(databingFile,new String[]{\"bin\"},true)) {\n//                    if (binFile.getName().contains(\"baseAdapters\")) {\n//                        try {\n//                            FileUtils.copyFileToDirectory(binFile, appVariantOutputContext.getVariantContext().getAwbDataBindingMergeArtifacts(awbBundle));\n//                        } catch (IOException e) {\n//                            e.printStackTrace();\n//                        }\n//                    }\n//                }\n//            }\n        }\n\n\n            ReflectUtils.updateField(javacTask, \"annotationProcessorOutputFolder\", appVariantOutputContext.getVariantContext().getAwbAnnotationProcessorOutputDir(awbBundle));\n\n            ReflectUtils.updateField(javacTask, \"compileSdkVersion\", scope.getGlobalScope().getExtension().getCompileSdkVersion());\n\n            ReflectUtils.updateField(javacTask, \"processorListFile\", appVariantOutputContext.getVariantContext().getScope().getOutput(ANNOTATION_PROCESSOR_LIST));\n\n            ReflectUtils.updateField(javacTask, \"variantName\", scope.getFullVariantName());\n\n            ReflectUtils.updateField(javacTask, \"mInstantRunBuildContext\", scope.getInstantRunBuildContext());\n\n            GradleBuildVariant.Builder builder = ProcessProfileWriter.getOrCreateVariant(scope.getGlobalScope().getProject().getPath(), scope.getFullVariantName());\n\n            if (builder != null && builder.getAnnotationProcessorsList().size() > 0) {\n                builder.clearAnnotationProcessors();\n            }\n            javacTask.setAwbBundle(awbBundle);\n\n            //modification\n\n\n    }\n\n    private FileCollection getInputJars() {\n        FileCollection classpath = scope.getJavaClasspath(AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH, AndroidArtifacts.ArtifactType.JAR);\n        Set<File> dependencies = new HashSet<File>();\n        dependencies.addAll(classpath.getFiles());\n        //Increase the awb dependency\n\n        dependencies.addAll(awbBundle.getLibraryJars());\n\n        FileCollection allClassPatch = appVariantOutputContext.getVariantContext()\n            .getProject()\n            .files(dependencies);\n        return allClassPatch;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/bundle/AwbPackagingScope.java",
    "content": "package com.taobao.android.builder.tasks.app.bundle;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.scope.DefaultGradlePackagingScope;\nimport com.android.build.gradle.internal.scope.GlobalScope;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\n\n/**\n * Created by chenhjohn on 2017/5/11.\n *\n * @author chenhjohn\n * @date 2017/05/11\n */\n\npublic class AwbPackagingScope extends DefaultGradlePackagingScope {\n\n    protected final VariantScope variantScope;\n\n    protected final GlobalScope globalScope;\n\n    private final AppVariantContext appVariantContext;\n\n    private final AppVariantOutputContext appVariantOutputContext;\n\n    private final GradleVariantConfiguration config;\n\n\n    private final AwbBundle awbBundle;\n\n    public AwbPackagingScope(VariantScope variantOutputScope, AppVariantContext appVariantContext,\n                             AwbBundle awbBundle, BaseVariantOutput variantOutput) {\n        super(variantOutputScope);\n        this.variantScope = variantOutputScope;\n        this.globalScope = variantScope.getGlobalScope();\n        this.appVariantContext = appVariantContext;\n        config = variantScope.getVariantConfiguration();\n        appVariantOutputContext = appVariantContext.getAppVariantOutputContext(ApkDataUtils.get(variantOutput));\n        this.awbBundle = awbBundle;\n    }\n\n//    @NonNull\n//    @Override\n//    public AndroidBuilder getAndroidBuilder() {\n//        return globalScope.getAndroidBuilder();\n//    }\n//\n////    @NonNull\n////    @Override\n////    public File getFinalResourcesFile() {\n////        ProcessAwbAndroidResources processAwbAndroidResources = appVariantOutputContext.getAwbAndroidResourcesMap().get(\n////            awbBundle.getName());\n////        if (processAwbAndroidResources == null) { return null; }\n////        File resourceFile = processAwbAndroidResources.getPackageOutputFile();\n////        return resourceFile;\n////    }\n//\n//    @NonNull\n//    @Override\n//    public String getFullVariantName() {\n//        return variantScope.getFullVariantName();\n//    }\n//\n//\n//    @NonNull\n//    @Override\n//    public InstantRunBuildContext getInstantRunBuildContext() {\n//        return variantScope.getInstantRunBuildContext();\n//    }\n//\n//    @NonNull\n//    @Override\n//    public File getInstantRunSupportDir() {\n//        return variantScope.getInstantRunSupportDir();\n//    }\n//\n//    @NonNull\n//    @Override\n//    public File getIncrementalDir(@NonNull String name) {\n//        return variantScope.getIncrementalDir(name);\n//    }\n//\n//    @NonNull\n//    @Override\n//    public FileCollection getDexFolders() {\n//        super.getDexFolders()\n//        File dexOutputFile = appVariantContext.getAwbDexOutput(awbBundle.getName());\n//        Set<File> dexFolders = new HashSet<File>();\n//        dexFolders.add(dexOutputFile);\n//        return dexFolders;\n//    }\n//\n//    @NonNull\n//    @Override\n//    public FileCollection getJavaResources() {\n//        super.getJavaResources()\n//        Set<File> javaResourcesLocations = Sets.newHashSet();\n//        if (appVariantContext.getAtlasExtension().getTBuildConfig().isIncremental()\n//            && awbBundle.getBaseAwbDependencies() != null && awbBundle.getBaseAwbDependencies().size() > 1) {\n//            File baseAwb = appVariantOutputContext.getVariantContext().apContext.getBaseExplodedAwb(\n//                awbBundle.getAwbSoName());\n//            javaResourcesLocations.add(baseAwb);\n//        }\n//        if (appVariantContext.getAtlasExtension().getTBuildConfig().getMergeAwbJavaRes()) {\n//            javaResourcesLocations.addAll(awbBundle.getLibraryJars());\n//        }\n//        return javaResourcesLocations;\n//    }\n//\n////    @NonNull\n////    @Override\n////    public File getAssetsDir() {\n////        return appVariantOutputContext.getVariantContext().getMergeAssets(awbBundle);\n////    }\n//\n//    @NonNull\n//    @Override\n//    public FileCollection getJniFolders() {\n//        Set<File> jniFolders = Sets.newHashSet();\n//        if (appVariantOutputContext.getAwbJniFolder(awbBundle) != null && appVariantOutputContext.getAwbJniFolder(\n//            awbBundle).exists()) {\n//            jniFolders.add(appVariantOutputContext.getAwbJniFolder(awbBundle));\n//        }\n//        return jniFolders;\n//    }\n//\n//\n//\n//    @NonNull\n//    @Override\n//    public Set<String> getAbiFilters() {\n////        if (appVariantOutputContext.getMainOutputFile().getFilter(com.android.build.OutputFile.ABI) != null) {\n////            return ImmutableSet.of(variantOutputData.getMainOutputFile().getFilter(com.android.build.OutputFile.ABI));\n////        }\n//        Set<String> supportedAbis = config.getSupportedAbis();\n//        if (supportedAbis != null) {\n//            return supportedAbis;\n//        }\n//        return ImmutableSet.of();\n//    }\n//\n//\n//\n//    @Nullable\n//    @Override\n//    public Set<String> getSupportedAbis() {\n//        return variantScope.getVariantConfiguration().getSupportedAbis();\n//    }\n//\n//    @Override\n//    public boolean isDebuggable() {\n//        return variantScope.getVariantConfiguration().getBuildType().isDebuggable();\n//    }\n//\n//    @Override\n//    public boolean isJniDebuggable() {\n//        return variantScope.getVariantConfiguration().getBuildType().isJniDebuggable();\n//    }\n//\n//    @Nullable\n//    @Override\n//    public CoreSigningConfig getSigningConfig() {\n//        return variantScope.getVariantConfiguration().getSigningConfig();\n//    }\n//\n//    @NonNull\n//    @Override\n//    public PackagingOptions getPackagingOptions() {\n//        return globalScope.getExtension().getPackagingOptions();\n//    }\n//\n//    @NonNull\n//    @Override\n//    public String getTaskName(@NonNull String name) {\n//        return getTaskName(name, \"\");\n//    }\n//\n//    @NonNull\n//    @Override\n//    public String getTaskName(@NonNull String prefix, @NonNull String suffix) {\n//        return variantScope.getTaskName(prefix, StringHelper.capitalize(awbBundle.getName()) + suffix);\n//    }\n//\n//    @NonNull\n//    @Override\n//    public Project getProject() {\n//        return globalScope.getProject();\n//    }\n//\n//\n//    private File getOutputFile(AwbBundle awbBundle) {\n//        if (null != awbBundle.outputBundleFile) {\n//            return awbBundle.outputBundleFile;\n//        }\n//\n//        if (AtlasBuildContext.sBuilderAdapter.packageRemoteAwbInJni && awbBundle.isRemote) {\n//            File file = appVariantOutputContext.getAwbPackageOutAppOutputFile(awbBundle);\n//            appVariantOutputContext.appBuildInfo.getOtherFilesMap().put(\"remotebundles/\" + file.getName(), file);\n//            return file;\n//        }\n//\n//        return appVariantOutputContext.getAwbPackageOutputFile(awbBundle);\n//    }\n//\n//\n//    @NonNull\n//    @Override\n//    public File getInstantRunSplitApkOutputFolder() {\n//        return variantScope.getInstantRunSplitApkOutputFolder();\n//    }\n//\n//\n//\n//    @NonNull\n//    @Override\n//    public String getApplicationId() {\n//        return variantScope.getVariantConfiguration().getApplicationId();\n//    }\n//\n//    @Override\n//    public int getVersionCode() {\n//        return 0;\n//    }\n//\n//    @Nullable\n//    @Override\n//    public String getVersionName() {\n//        return null;\n//    }\n//\n\n\n//    @NonNull\n//    @Override\n//    public VariantType getVariantType() {\n//        return VariantType.LIBRARY;\n//    }\n//\n//    @NonNull\n//    @Override\n//    public File getManifestFile() {\n//        // TODO: Replace with an empty manifest.\n//        return awbBundle.getMergedManifest();\n//    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/bundle/Dex.java",
    "content": "package com.taobao.android.builder.tasks.app.bundle;\n\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.dsl.DexOptions;\nimport com.android.build.gradle.internal.scope.ConventionMappingHelper;\nimport com.android.build.gradle.internal.scope.TaskConfigAction;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.build.gradle.internal.variant.ApkVariantData;\nimport com.android.ide.common.blame.Message;\nimport com.android.ide.common.blame.ParsingProcessOutputHandler;\nimport com.android.ide.common.blame.parser.DexParser;\nimport com.android.ide.common.blame.parser.ToolOutputParser;\nimport com.android.ide.common.process.ProcessException;\nimport com.android.ide.common.process.ProcessOutputHandler;\nimport com.android.utils.FileUtils;\nimport com.android.utils.StringHelper;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.dex.DexException;\nimport com.taobao.android.dx.merge.CollisionPolicy;\nimport com.taobao.android.dx.merge.DexMerger;\nimport org.gradle.api.Action;\nimport org.gradle.api.tasks.*;\nimport org.gradle.api.tasks.incremental.IncrementalTaskInputs;\nimport org.gradle.api.tasks.incremental.InputFileDetails;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\nimport static com.android.builder.model.AndroidProject.FD_INTERMEDIATES;\n\npublic class Dex extends BaseTask {\n    @Input\n    public String getBuildToolsVersion() {\n        return getBuildTools().getRevision().toString();\n    }\n\n    /**\n     * Actual entry point for the action.\n     * Calls out to the doTaskAction as needed.\n     */\n    @TaskAction\n    public void taskAction(IncrementalTaskInputs inputs) throws IOException, InterruptedException, ProcessException {\n        Collection<File> _inputFiles = getInputFiles();\n        File _inputDir = getInputDir();\n        if (_inputFiles == null && _inputDir == null) {\n            throw new RuntimeException(\"Dex task \\'\" + getName() + \": inputDir and inputFiles cannot both be null\");\n        }\n\n        if (!dexOptions.getIncremental() || !enableIncremental) {\n            doTaskAction(_inputFiles, _inputDir, false);\n            return;\n\n        }\n\n        if (!inputs.isIncremental()) {\n            getProject().getLogger().info(\"Unable to do incremental execution: full task run.\");\n            doTaskAction(_inputFiles, _inputDir, false);\n            return;\n\n        }\n\n        final AtomicBoolean forceFullRun = new AtomicBoolean();\n\n        //noinspection GroovyAssignabilityCheck\n        inputs.outOfDate(new Action<InputFileDetails>() {\n            @Override\n            public void execute(InputFileDetails change) {\n                // force full dx run if existing jar file is modified\n                // New jar files are fine.\n                if (((InputFileDetails)change).isModified() && ((InputFileDetails)change).getFile().getPath().endsWith(\n                    SdkConstants.DOT_JAR)) {\n                    getProject().getLogger().info(\n                        \"Force full dx run: Found updated \" + String.valueOf(((InputFileDetails)change).getFile()));\n                    forceFullRun.set(true);\n                }\n\n            }\n\n        });\n\n        //noinspection GroovyAssignabilityCheck\n        inputs.removed(change -> {\n            // force full dx run if existing jar file is removed\n            if (((InputFileDetails)change).getFile().getPath().endsWith(SdkConstants.DOT_JAR)) {\n                getProject().getLogger().info(\n                    \"Force full dx run: Found removed \" + String.valueOf(((InputFileDetails)change).getFile()));\n                forceFullRun.set(true);\n            }\n\n        });\n\n        doTaskAction(_inputFiles, _inputDir, !forceFullRun.get());\n    }\n\n    private void doTaskAction(@Nullable Collection<File> inputFiles, @Nullable File inputDir, boolean incremental)\n        throws IOException, ProcessException, InterruptedException {\n        File outFolder = getOutputFolder();\n        if (!incremental) {\n            FileUtils.deleteDirectoryContents(outFolder);\n        }\n\n        File tmpFolder = getTmpFolder();\n        tmpFolder.mkdirs();\n\n        // if some of our .jar input files exist, just reset the inputDir to null\n        for (File inputFile : inputFiles) {\n            if (inputFile.exists()) {\n                inputDir = null;\n            }\n\n        }\n\n        if (inputDir != null) {\n            inputFiles = getProject().files(inputDir).getFiles();\n        }\n        final ProcessOutputHandler outputHandler = new ParsingProcessOutputHandler(\n            new ToolOutputParser(new DexParser(), Message.Kind.ERROR, getILogger()),\n            new ToolOutputParser(new DexParser(), getILogger()), getBuilder().getErrorReporter());\n\n        List<File> inputDexFiles = new ArrayList<File>();\n        inputDexFiles.addAll(inputFiles);\n        inputDexFiles.addAll(getLibraries());\n        getBuilder().getDexByteCodeConverter().convertByteCode(inputDexFiles, outFolder, getMultiDexEnabled(), getMainDexListFile(),\n                                     getDexOptions(), outputHandler,14);\n        File dexBaseFile = getDexBaseFile();\n        if (dexBaseFile != null) {\n            ZipFile files = new ZipFile(dexBaseFile);\n            ZipEntry entry = files.getEntry(\"classes.dex\");\n            if (entry == null) {\n                throw new DexException(\"Expected classes.dex in \" + dexBaseFile);\n            }\n            File file = new File(outFolder, \"classes.dex\");\n            com.taobao.android.dex.Dex merged = new DexMerger(new com.taobao.android.dex.Dex[]{new com.taobao.android.dex.Dex(file),\n                new com.taobao.android.dex.Dex(files.getInputStream(entry))}, CollisionPolicy.KEEP_FIRST).merge();\n            merged.writeTo(file);\n        }\n    }\n\n    @OutputDirectory\n    public File getOutputFolder() {\n        return outputFolder;\n    }\n\n    public void setOutputFolder(File outputFolder) {\n        this.outputFolder = outputFolder;\n    }\n\n    @Input\n    @Optional\n    public List<String> getAdditionalParameters() {\n        return additionalParameters;\n    }\n\n    public void setAdditionalParameters(List<String> additionalParameters) {\n        this.additionalParameters = additionalParameters;\n    }\n\n    public boolean getEnableIncremental() {\n        return enableIncremental;\n    }\n\n    public boolean isEnableIncremental() {\n        return enableIncremental;\n    }\n\n    public void setEnableIncremental(boolean enableIncremental) {\n        this.enableIncremental = enableIncremental;\n    }\n\n    @InputFiles\n    @Optional\n    public Collection<File> getInputFiles() {\n        return inputFiles;\n    }\n\n    public void setInputFiles(Collection<File> inputFiles) {\n        this.inputFiles = inputFiles;\n    }\n\n    @InputDirectory\n    @Optional\n    public File getInputDir() {\n        return inputDir;\n    }\n\n    public void setInputDir(File inputDir) {\n        this.inputDir = inputDir;\n    }\n\n    @InputFiles\n    public Collection<File> getLibraries() {\n        return libraries;\n    }\n\n    public void setLibraries(Collection<File> libraries) {\n        this.libraries = libraries;\n    }\n\n    @Nested\n    public DexOptions getDexOptions() {\n        return dexOptions;\n    }\n\n    public void setDexOptions(DexOptions dexOptions) {\n        this.dexOptions = dexOptions;\n    }\n\n    @Input\n    public boolean getMultiDexEnabled() {\n        return multiDexEnabled;\n    }\n\n    public boolean isMultiDexEnabled() {\n        return multiDexEnabled;\n    }\n\n    public void setMultiDexEnabled(boolean multiDexEnabled) {\n        this.multiDexEnabled = multiDexEnabled;\n    }\n\n    @Input\n    public boolean getOptimize() {\n        return optimize;\n    }\n\n    public boolean isOptimize() {\n        return optimize;\n    }\n\n    public void setOptimize(boolean optimize) {\n        this.optimize = optimize;\n    }\n\n    @InputFile\n    @Optional\n    public File getMainDexListFile() {\n        return mainDexListFile;\n    }\n\n    public void setMainDexListFile(File mainDexListFile) {\n        this.mainDexListFile = mainDexListFile;\n    }\n\n    public File getDexBaseFile() {\n        return dexBaseFile;\n    }\n\n    public void setDexBaseFile(File dexBaseFile) {\n        this.dexBaseFile = dexBaseFile;\n    }\n\n    public File getTmpFolder() {\n        return tmpFolder;\n    }\n\n    public void setTmpFolder(File tmpFolder) {\n        this.tmpFolder = tmpFolder;\n    }\n\n    @OutputDirectory\n    private File outputFolder;\n\n    @Input\n    @Optional\n    private List<String> additionalParameters;\n\n    private boolean enableIncremental = true;\n\n    @InputFiles\n    @Optional\n    private Collection<File> inputFiles;\n\n    @InputDirectory\n    @Optional\n    private File inputDir;\n\n    @InputFiles\n    private Collection<File> libraries;\n\n    @Nested\n    private DexOptions dexOptions;\n\n    @Input\n    private boolean multiDexEnabled = false;\n\n    @Input\n    private boolean optimize = true;\n\n    @InputFile\n    @Optional\n    private File dexBaseFile;\n\n    @InputFile\n    @Optional\n    private File mainDexListFile;\n\n    private File tmpFolder;\n\n    public static class ConfigAction implements TaskConfigAction<Dex> {\n        public ConfigAction(VariantScope scope, AppVariantOutputContext appVariantOutputContext, AwbBundle awbBundle) {\n            this.scope = scope;\n            this.appVariantOutputContext = appVariantOutputContext;\n            this.awbBundle = awbBundle;\n        }\n\n        @Override\n        public String getName() {\n            return getTaskName(\"dex\", \"\");\n        }\n\n        public String getTaskName(@NonNull String prefix, @NonNull String suffix) {\n            return scope.getTaskName(prefix, StringHelper.capitalize(awbBundle.getName()) + suffix);\n        }\n\n        @Override\n        public Class<Dex> getType() {\n            return ((Class<Dex>)(Dex.class));\n        }\n\n        @Override\n        public void execute(Dex dexTask) {\n            ApkVariantData variantData = (ApkVariantData)scope.getVariantData();\n            final GradleVariantConfiguration config = variantData.getVariantConfiguration();\n\n            // boolean isTestForApp = config.getType().isForTesting() && (DefaultGroovyMethods.asType(variantData,\n            //                                                                                        TestVariantData\n            //                                                                                            .class))\n            //     .getTestedVariantData().getVariantConfiguration().getType().equals(DEFAULT);\n            //\n            // boolean isMultiDexEnabled = config.isMultiDexEnabled() && !isTestForApp;\n            // boolean isLegacyMultiDexMode = config.isLegacyMultiDexMode();\n\n            // variantData.dexTask = dexTask;\n            dexTask.setVariantName(scope.getFullVariantName());\n            dexTask.setAndroidBuilder(scope.getGlobalScope().getAndroidBuilder());\n            ConventionMappingHelper.map(dexTask, \"outputFolder\", new Callable<File>() {\n                @Override\n                public File call() throws Exception {\n                    return appVariantOutputContext.getAwbDexOutput(awbBundle.getName());\n                }\n\n            });\n            dexTask.setTmpFolder(new File(\n                String.valueOf(scope.getGlobalScope().getBuildDir()) + \"/\" + FD_INTERMEDIATES + \"/tmp/dex/\" + config\n                    .getDirName()));\n            dexTask.setDexOptions(scope.getGlobalScope().getExtension().getDexOptions());\n            // dexTask.setMultiDexEnabled(isMultiDexEnabled);\n            // dx doesn't work with receving --no-optimize in debug so we disable it for now.\n            dexTask.setOptimize(true);//!variantData.variantConfiguration.buildType.debuggable\n\n            // inputs\n            // if (awbBundle.invokeMethod(\"getInputDirCallable\", new Object[0]) != null) {\n            //     ConventionMappingHelper.map(dexTask, \"inputDir\",\n            //                                 awbBundle.invokeMethod(\"getInputDirCallable\", new Object[0]));\n            // }\n\n            ConventionMappingHelper.map(dexTask, \"inputDir\", new Callable<File>() {\n                @Override\n                public File call() {\n                    AwbTransform awbTransform = appVariantOutputContext.getAwbTransformMap().get(awbBundle.getName());\n                    return awbTransform.getInputDirs().iterator().next();\n                }\n            });\n            ConventionMappingHelper.map(dexTask, \"inputFiles\", new Callable<List<File>>() {\n                @Override\n                public List<File> call() {\n                    AwbTransform awbTransform = appVariantOutputContext.getAwbTransformMap().get(awbBundle.getName());\n                    return awbTransform.getInputFiles();\n                }\n            });\n//            ConventionMappingHelper.map(dexTask, \"dexBaseFile\", new Callable<File>() {\n//                @Override\n//                public File call() {\n//                    if (!awbBundle.getManifest().exists()) {\n//                        return null;\n//                    }\n\n//                }\n//            });\n            ConventionMappingHelper.map(dexTask, \"libraries\", new Callable<List<File>>() {\n                @Override\n                public List<File> call() {\n                    AwbTransform awbTransform = appVariantOutputContext.getAwbTransformMap().get(awbBundle.getName());\n                    return awbTransform.getInputLibraries();\n                }\n            });\n\n            // if (isMultiDexEnabled && isLegacyMultiDexMode) {\n            //     // configure the dex task to receive the generated class list.\n            //     ConventionMappingHelper.map(dexTask, \"mainDexListFile\", new Callable<File>() {\n            //         @Override\n            //         public File call() throws Exception {\n            //             return scope.getMainDexListFile();\n            //         }\n            //\n            //     });\n            // }\n\n        }\n\n        private final VariantScope scope;\n\n        private final AppVariantOutputContext appVariantOutputContext;\n\n        private final AwbBundle awbBundle;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/bundle/JavacAwbsTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.bundle;\n\nimport com.android.build.gradle.BaseExtension;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.build.gradle.tasks.factory.AndroidJavaCompile;\nimport com.android.build.gradle.tasks.factory.AwbAndroidJavaCompile;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tasks.manager.TaskCreater;\nimport com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.tasks.TaskAction;\nimport org.gradle.api.tasks.compile.JavaCompile;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.ExecutionException;\n\n/**\n * compiling awb the R file\n */\npublic class JavacAwbsTask extends BaseTask {\n\n    static final String taskName = \"javacAwbs\";\n\n    private AppVariantOutputContext appVariantOutputContext;\n\n    @TaskAction\n    void run() throws ExecutionException, InterruptedException {\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(getVariantName());\n\n        if (null == atlasDependencyTree) {\n            return;\n        }\n\n        BaseExtension androidExtension = appVariantOutputContext.getVariantContext().getAppExtension();\n        boolean isDatabindEnabled = null != androidExtension.getDataBinding() && androidExtension.getDataBinding()\n            .isEnabled();\n\n        ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper(taskName, getLogger(),0);\n        ExecutorServicesHelper executorServicesHelper2 = new ExecutorServicesHelper(taskName+\"databinding\", getLogger(),\n                                                                                    1);\n        List<Runnable> runnables = new ArrayList<>();\n        List<Runnable> runnables2 = new ArrayList<>();\n\n        for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n            if (awbBundle.isMBundle){\n                continue;\n            }\n            Runnable runnable = new Runnable() {\n                @Override\n                public void run() {\n\n                    try {\n\n                        AwbJavaCompileConfigAction awbJavaCompileConfigAction = new AwbJavaCompileConfigAction(\n                            awbBundle, appVariantOutputContext);\n\n                        AwbAndroidJavaCompile awbJavaCompile = TaskCreater.create(getProject(),\n                                                                        awbJavaCompileConfigAction.getName(),\n                                                                        awbJavaCompileConfigAction.getType());\n\n                        awbJavaCompileConfigAction.execute(awbJavaCompile);\n\n                        awbJavaCompile.execute();\n\n                        AwbTransform awbTransform = appVariantOutputContext.getAwbTransformMap().get(\n                            awbBundle.getName());\n\n                        awbTransform.addDir(awbJavaCompile.getDestinationDir());\n\n                    } catch (Throwable e) {\n                        e.printStackTrace();\n                        throw new GradleException(\"javac \" + awbBundle.getName() + \" failed\");\n                    }\n\n                }\n            };\n\n            if (appVariantOutputContext.getVariantContext().isDataBindEnabled(awbBundle)){\n                runnables2.add(runnable);\n            }else {\n                runnables.add(runnable);\n            }\n\n        }\n\n        executorServicesHelper.execute(runnables);\n        executorServicesHelper2.execute(runnables2);\n\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<JavacAwbsTask> {\n\n        public ConfigAction(AppVariantContext appVariantContext, BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(taskName);\n        }\n\n        @Override\n        public Class<JavacAwbsTask> getType() {\n            return JavacAwbsTask.class;\n        }\n\n        @Override\n        public void execute(JavacAwbsTask javacAwbsTask) {\n\n            super.execute(javacAwbsTask);\n\n            javacAwbsTask.appVariantOutputContext = getAppVariantOutputContext();\n\n        }\n    }\n\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/bundle/PackageAwbsTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\n/**\n * @author wuzhong,lilong\n * @create 2017-12-06 上午11:17\n */\n\n\npackage com.taobao.android.builder.tasks.app.bundle;\n\nimport com.android.SdkConstants;\nimport com.android.build.gradle.AndroidConfig;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.TaskContainerAdaptor;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.pipeline.TransformTask;\nimport com.android.build.gradle.internal.scope.TaskOutputHolder;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.build.gradle.internal.transforms.MergeJavaResourcesTransform;\nimport com.android.build.gradle.tasks.PackageApplication;\nimport com.android.dex.DexException;\nimport com.android.dx.command.dexer.DxContext;\nimport com.android.dx.merge.CollisionPolicy;\nimport com.android.dx.merge.DexMerger;\nimport com.android.utils.FileUtils;\nimport com.android.utils.ILogger;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Sets;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.app.bundle.actions.FirstApkAction;\nimport com.taobao.android.builder.tasks.app.bundle.actions.LastApkAction;\nimport com.taobao.android.builder.tasks.app.bundle.actions.LastBundleAction;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tasks.manager.transform.TransformManager;\nimport com.taobao.android.builder.tasks.transform.AtlasMergeJavaResourcesTransform;\nimport com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper;\nimport com.taobao.android.builder.tools.log.FileLogger;\nimport com.taobao.android.builder.tools.zip.BetterZip;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.atomic.AtomicLong;\nimport java.util.function.Consumer;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\nimport static com.android.SdkConstants.FN_RES_BASE;\nimport static com.android.SdkConstants.RES_QUALIFIER_SEP;\n\npublic class PackageAwbsTask extends BaseTask {\n\n    final String taskName = \"packageAwbs\";\n\n    private AndroidConfig androidConfig;\n\n    private AppVariantContext appVariantContext;\n\n    private AppVariantOutputContext appVariantOutputContext;\n\n    private GradleVariantConfiguration config;\n\n    Map<AwbBundle,File>bundles = new HashMap<>();\n\n    private BaseVariantOutput variantOutputData;\n    private ILogger mLogger = LoggerWrapper.getLogger(PackageAwbsTask.class);\n\n    /**\n     * Directory of so\n     */\n    @TaskAction\n    void createAwbPackages() throws ExecutionException, InterruptedException, IOException {\n        File awbApkOutputDir = appVariantContext.getAwbApkOutputDir();\n        FileUtils.cleanOutputDir(awbApkOutputDir);\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n                getVariantName());\n\n        if (null == atlasDependencyTree) {\n            return;\n        }\n\n        ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper(taskName,\n                                                                                   getLogger(),\n                                                                                   0);\n        List<Runnable> runnables = new ArrayList<>();\n\n        final AtomicLong dexTotalTime = new AtomicLong(0);\n        final AtomicLong packageTotalTime = new AtomicLong(0);\n        final Map<String, Long[]> monitors = new HashMap<String, Long[]>();\n        long startTime = System.currentTimeMillis();\n        for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n            if (awbBundle.isMBundle){\n                continue;\n            }\n            runnables.add(() -> {\n\n                try {\n\n                    long start = System.currentTimeMillis();\n                    //create dex\n                    File dexOutputFile = appVariantContext.getAwbDexOutput(awbBundle.getName());\n\n                    long endDex = System.currentTimeMillis();\n\n                    //PACKAGE APP:\n                    File resourceFile = null;\n                   if (appVariantContext.getScope().useResourceShrinker()) {\n                       resourceFile = appVariantOutputContext.getAwbCompressResourcePackageOutputFile(awbBundle);\n\n                   }else {\n                       resourceFile = appVariantOutputContext.getAwbAndroidResourcesMap()\n                               .get(awbBundle.getName())\n                               .getPackageOutputFile();\n                   }\n                   if (!resourceFile.exists()){\n                       resourceFile = appVariantOutputContext.getAwbAndroidResourcesMap()\n                               .get(awbBundle.getName())\n                               .getPackageOutputFile();\n                   }\n\n                    Set<File> dexFolders = new HashSet<File>();\n                    dexFolders.add(dexOutputFile);\n\n                    Set<File> jniFolders = Sets.newHashSet();\n                    if (appVariantOutputContext.getAwbJniFolder(awbBundle) != null &&\n                        appVariantOutputContext.getAwbJniFolder(awbBundle).exists()) {\n                        jniFolders.add(appVariantOutputContext.getAwbJniFolder(awbBundle));\n                    }\n\n                    Set<File> javaResourcesLocations = Sets.newHashSet();\n                    if (appVariantContext.getAtlasExtension()\n                                .getTBuildConfig()\n                                .isIncremental() && awbBundle.getAllLibraryAars().size() > 1) {\n                        File baseAwb = appVariantOutputContext.getVariantContext().apContext.getBaseAwb(\n                                awbBundle.getAwbSoName());\n                        if (baseAwb != null) {\n                            ZipFile files = new ZipFile(baseAwb);\n                            ZipEntry entry = files.getEntry(\"classes.dex\");\n                            if (entry == null) {\n                                throw new DexException(\"Expected classes.dex in \" + baseAwb);\n                            }\n                            File file = new File(dexOutputFile, \"classes.dex\");\n                            com.android.dex.Dex[]dexes=new com.android.dex.Dex[2];\n                            dexes[0] = new com.android.dex.Dex(file);\n                            dexes[1] = new com.android.dex.Dex(files.getInputStream(\n                                    entry));\n                            com.android.dex.Dex merged = new DexMerger(dexes, CollisionPolicy.KEEP_FIRST,new DxContext()).merge();\n                            merged.writeTo(file);\n                            javaResourcesLocations.add(baseAwb);\n                        }\n                    }\n                    if (appVariantContext.getAtlasExtension()\n                            .getTBuildConfig()\n                            .getMergeAwbJavaRes()) {\n                        javaResourcesLocations.add(new File(appVariantOutputContext.getAwbJavaResFolder(awbBundle),\"res.jar\"));\n                    }\n\n                    AwbApkPackageTask awbApkPackageTask = new AwbApkPackageTask(getProject().files(resourceFile),appVariantContext,awbBundle,appVariantOutputContext,getProject().files(dexFolders),getProject().files(javaResourcesLocations),getProject().files(appVariantOutputContext.getVariantContext().getMergeAssets(awbBundle)),getProject().files(jniFolders),getProject().files(awbBundle.getMergedManifest()),getBuilder(),config.getMinSdkVersion().getApiLevel(),getName());\n                    File awbFile = awbApkPackageTask.doFullTaskAction();\n                    bundles.put(awbBundle,awbFile);\n\n\n////                        //TODO 2.3\n//                        AtlasBuildContext.androidBuilderMap.get(getProject())\n//                                .oldPackageApk(resourceFile.getAbsolutePath(),\n//                                               dexFolders,\n//                                               javaResourcesLocations,\n//                                               jniFolders,\n//                                               null,\n//                                               getAbiFilters(),\n//                                               config.getBuildType().isJniDebuggable(),\n//                                               null,\n//                                               getOutputFile(awbBundle),\n//                                               config.getMinSdkVersion().getApiLevel(),\n//                                               new com.google.common.base.Predicate<String>() {\n//                                                   @Override\n//                                                   public boolean apply(@Nullable String s) {\n//                                                       return false;\n//                                                   }\n//                                               });\n\n\n\n                    long endPackage = System.currentTimeMillis();\n\n                    dexTotalTime.addAndGet(endDex - start);\n                    packageTotalTime.addAndGet(endPackage - endDex);\n                    monitors.put(awbBundle.getName(),\n                                 new Long[]{endDex - start, endPackage - endDex});\n                } catch (Throwable e) {\n                    //e.printStackTrace();\n                    throw new GradleException(\"package \" + awbBundle.getName() + \" failed\", e);\n                }\n            });\n        }\n\n        executorServicesHelper.execute(runnables);\n\n        getLogger().info(\">>>>> packageAwbs >>>>>>>>>>>>\");\n\n        FileLogger fileLogger = FileLogger.getInstance(\"packageAwbs\");\n        fileLogger.log(\"totalTime is \" + (System.currentTimeMillis() - startTime));\n        fileLogger.log(\"dexTotalTime is \" + dexTotalTime);\n        fileLogger.log(\"packageTotalTime is \" + packageTotalTime);\n        String format = \"[packageawb]  bundle:%50s  dexTime: %10d  packageTime: %10d \";\n        for (String bundle : monitors.keySet()) {\n            Long[] value = monitors.get(bundle);\n            fileLogger.log(String.format(format, bundle, value[0], value[1]));\n        }\n\n        getLogger().info(\">>>>> packageAwbs >>>>>>>>>>>>\");\n\n\n        PackageApplication packageApplication = appVariantContext.getScope().getPackageApplicationTask().get(new TaskContainerAdaptor(appVariantContext.getScope().getGlobalScope().getProject().getTasks()));\n\n        packageApplication.doFirst(new FirstApkAction(appVariantOutputContext));\n\n        packageApplication.doLast(new LastApkAction());\n\n    }\n\n\n\n    private Set<String> getAbiFilters() {\n        if (variantOutputData.getMainOutputFile().getFilterTypes() !=\n            null) {\n            return ImmutableSet.copyOf(variantOutputData.getMainOutputFile()\n                                           .getFilterTypes());\n        }\n        Set<String> supportedAbis = config.getSupportedAbis();\n        if (supportedAbis != null) {\n            return supportedAbis;\n        }\n        return ImmutableSet.of();\n    }\n\n    public Map<AwbBundle,File> getAwbMap() {\n        return bundles;\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<PackageAwbsTask> {\n\n        private final AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext,\n                            BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"package\", \"Awbs\");\n        }\n\n        @Override\n        public Class<PackageAwbsTask> getType() {\n            return PackageAwbsTask.class;\n        }\n\n        @Override\n        public void execute(PackageAwbsTask packageAwbsTask) {\n            super.execute(packageAwbsTask);\n            packageAwbsTask.androidConfig = appVariantContext.getAppExtension();\n            packageAwbsTask.appVariantContext = appVariantContext;\n            packageAwbsTask.appVariantOutputContext = getAppVariantOutputContext();\n            packageAwbsTask.config = scope.getVariantConfiguration();\n            packageAwbsTask.variantOutputData = baseVariantOutput;\n            LastBundleAction lastBundleAction = new LastBundleAction(packageAwbsTask.getAwbMap(),getAppVariantOutputContext());\n            packageAwbsTask.doLast(lastBundleAction);\n\n        }\n    }\n\n\n\n\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/bundle/ProcessAwbAndroidResources.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\npackage com.taobao.android.builder.tasks.app.bundle;\n\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\n\nimport java.io.FilenameFilter;\nimport java.nio.file.Path;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.TaskManager;\nimport com.android.build.gradle.internal.aapt.AaptGeneration;\nimport com.android.build.gradle.internal.aapt.AaptGradleFactory;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.dsl.AaptOptions;\nimport com.android.build.gradle.internal.dsl.DslAdaptersKt;\nimport com.android.build.gradle.internal.incremental.FileType;\nimport com.android.build.gradle.internal.incremental.InstantRunBuildContext;\nimport com.android.build.gradle.internal.scope.*;\nimport com.android.build.gradle.internal.tasks.ApplicationId;\nimport com.android.build.gradle.internal.tasks.IncrementalTask;\nimport com.android.build.gradle.internal.variant.BaseVariantData;\nimport com.android.build.gradle.options.BooleanOption;\nimport com.android.build.gradle.options.DeploymentDevice;\nimport com.android.build.gradle.options.ProjectOptions;\nimport com.android.build.gradle.options.StringOption;\nimport com.android.builder.core.AndroidBuilder;\nimport com.android.builder.core.AtlasBuilder;\nimport com.android.builder.core.VariantType;\nimport com.android.builder.internal.aapt.Aapt;\nimport com.android.builder.internal.aapt.AaptPackageConfig;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.builder.symbols.SymbolIo;\nimport com.android.builder.utils.FileCache;\nimport com.android.ide.common.blame.MergingLog;\nimport com.android.ide.common.blame.MergingLogRewriter;\nimport com.android.ide.common.blame.ParsingProcessOutputHandler;\nimport com.android.ide.common.blame.parser.ToolOutputParser;\nimport com.android.ide.common.blame.parser.aapt.Aapt2OutputParser;\nimport com.android.ide.common.blame.parser.aapt.AaptOutputParser;\nimport com.android.ide.common.process.LoggedProcessOutputHandler;\nimport com.android.ide.common.process.ProcessOutputHandler;\nimport com.android.utils.FileUtils;\nimport com.google.common.base.Charsets;\nimport com.google.common.collect.Iterators;\nimport com.google.common.io.Files;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport org.apache.commons.beanutils.BeanUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.file.FileCollection;\nimport org.gradle.api.tasks.*;\nimport org.gradle.api.tasks.Optional;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.concurrent.Callable;\nimport java.util.function.Consumer;\nimport java.util.jar.JarFile;\nimport java.util.zip.ZipEntry;\n\n/**\n * @author lilong\n * @create 2017-12-06 上午11:17\n */\n\n\npublic class ProcessAwbAndroidResources extends IncrementalTask {\n\n    private File manifestFile;\n\n    private File instantRunManifestFile;\n\n    private File resDir;\n\n    private File assetsDir;\n\n    private File sourceOutputDir;\n\n    private File textSymbolOutputDir;\n\n    private File packageOutputFile;\n\n    private File proguardOutputFile;\n\n    private Collection<String> resourceConfigs;\n\n    private String preferredDensity;\n\n    private List<? extends AndroidLibrary> libraries;\n\n    private String packageForR;\n\n    private Collection<String> splits;\n\n    private boolean enforceUniquePackageName;\n\n    private VariantType type;\n\n    private boolean debuggable;\n\n    private boolean pseudoLocalesEnabled;\n\n    private AaptOptions aaptOptions;\n\n    private File mergeBlameLogFolder;\n\n    private InstantRunBuildContext instantRunBuildContext;\n\n    private File instantRunSupportDir;\n\n    private File buildInfoFile;\n\n    private File mainSymbolFile;\n\n    private String awbBundleName;\n\n    private String customPackageId;\n\n    private String sktPackageName;\n\n    private File shareResourceFile;\n\n    private File shareResourceFile2;\n\n    private File rtxtFile;\n\n    private File baselineFile;\n    private AwbBundle awbBundle;\n    private AppVariantOutputContext appVariantContext;\n    private AaptGeneration aaptGeneration;\n    public FileCollection mainDexSymbolFileCollection;\n\n\n    @Override\n    protected void doFullTaskAction() throws IOException {\n\n        File srcOut = getSourceOutputDir();\n        aaptGeneration = AaptGeneration.fromProjectOptions(appVariantContext.getScope().getGlobalScope().getProjectOptions());\n\n//        aaptGeneration = AaptGeneration.AAPT_V1;\n\n        if (srcOut != null) {\n            //            FileUtils.emptyFolder(srcOut);\n            srcOut.delete();\n            srcOut.mkdirs();\n        }\n\n        getTextSymbolOutputDir().mkdirs();\n        getPackageOutputFile().getParentFile().mkdirs();\n\n        @Nullable File resOutBaseNameFile = getPackageOutputFile();\n\n        // If are in instant run mode and we have an instant run enabled manifest\n        File instantRunManifest = getInstantRunManifestFile();\n        File manifestFileToPackage = instantRunBuildContext.isInInstantRunMode() &&\n                instantRunManifest != null &&\n                instantRunManifest.exists() ? instantRunManifest : getManifestFile();\n\n        //Add additional parameters required for the awb module to compile\n\n        Set<File> libraries = new HashSet<>();\n        for (AndroidLibrary androidLibrary:getLibraries()){\n            if (androidLibrary.getSymbolFile().exists()) {\n                if (androidLibrary.getManifest().exists() && androidLibrary.getSymbolFile().exists()) {\n                    File libraryRtxt = androidLibrary.getSymbolFile();\n                    File awbPackageR = new File(libraryRtxt.getParentFile(),\"package-aware-r.txt\");\n                    SymbolIo.writeSymbolTableWithPackage(libraryRtxt.toPath(),androidLibrary.getManifest().toPath(), awbPackageR.toPath());\n                    libraries.add(awbPackageR);\n                }\n            }\n        }\n//        libraries.addAll(mainDexSymbolFileCollection.getFiles());\n\n        addAaptOptions(aaptGeneration);\n        AaptPackageConfig.Builder aaptPackageCommandBuilder = new AaptPackageConfig.Builder()\n                .setManifestFile(manifestFileToPackage)\n                .setOptions(DslAdaptersKt.convert(getAaptOptions()))\n                .setResourceDir(getResDir())\n                .setLibrarySymbolTableFiles(libraries)\n                .setCustomPackageForR(getPackageForR())\n                .setSourceOutputDir(srcOut)\n                .setSymbolOutputDir(getTextSymbolOutputDir())\n                .setResourceOutputApk(resOutBaseNameFile)\n                .setProguardOutputFile(getProguardOutputFile())\n                .setVariantType(getType())\n                .setDebuggable(debuggable)\n                .setResourceConfigs(getResourceConfigs())\n                .setSplits(getSplits())\n                .setPreferredDensity(getPreferredDensity())\n                .setPseudoLocalize(getPseudoLocalesEnabled())\n                .setListResourceFiles(aaptGeneration == AaptGeneration.AAPT_V2);\n//                .setPackageId(Integer.valueOf(getCustomPackageId()));\n\n        @NonNull AndroidBuilder builder = getBuilder();\n\n        Aapt aapt = makeAapt();\n\n        try {\n            if (builder instanceof AtlasBuilder) {\n                ((AtlasBuilder) builder).processAwbResources(aapt, aaptPackageCommandBuilder,getMainSymbolFile(),awbBundle.getAndroidLibrary().getSymbolFile(),appVariantContext.getVariantData().getApplicationId());\n            }else {\n                builder.processResources(aapt,aaptPackageCommandBuilder);\n            }\n            if (resOutBaseNameFile != null) {\n                if (instantRunBuildContext.isInInstantRunMode()) {\n\n                    instantRunBuildContext.addChangedFile(FileType.RESOURCES, resOutBaseNameFile);\n\n                    // get the new manifest file CRC\n                    JarFile jarFile = new JarFile(resOutBaseNameFile);\n                    String currentIterationCRC = null;\n                    try {\n                        ZipEntry entry = jarFile.getEntry(SdkConstants.ANDROID_MANIFEST_XML);\n                        if (entry != null) {\n                            currentIterationCRC = String.valueOf(entry.getCrc());\n                        }\n                    } finally {\n                        jarFile.close();\n                    }\n\n                    // check the manifest file binary format.\n                    File crcFile = new File(instantRunSupportDir, \"manifest.crc\");\n                    if (crcFile.exists() && currentIterationCRC != null) {\n                        // compare its content with the new binary file crc.\n                        String previousIterationCRC = Files.readFirstLine(crcFile, Charsets.UTF_8);\n                        if (!currentIterationCRC.equals(previousIterationCRC)) {\n                            instantRunBuildContext.close();\n                            //instantRunBuildContext.setVerifierResult(InstantRunVerifierStatus\n                            // .BINARY_MANIFEST_FILE_CHANGE);\n                        }\n                    }\n\n                    // write the new manifest file CRC.\n                    Files.createParentDirs(crcFile);\n                    Files.write(currentIterationCRC, crcFile, Charsets.UTF_8);\n                }\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n            throw new GradleException(\"process res exception\", e);\n        }\n    }\n\n    //Add special command parameters\n    private void addAaptOptions(AaptGeneration aaptGeneration) {\n        //BUGFIX , The direct access property is written without access to the property name of the dynamic class\n        List<String> options = new ArrayList<String>();\n        String customPackageId = getCustomPackageId();\n        if (StringUtils.isNotBlank(customPackageId)) {\n            String[] split = customPackageId.split(\"\\\\.\");\n\n            if (aaptGeneration == AaptGeneration.AAPT_V1) {\n                options.add(\"--forced-package-id\");\n                options.add(split[0]);\n            } else {\n                options.add(\"--package-id\");\n                options.add(String.valueOf(Integer.parseInt(split[0]) + 0x7f));\n            }\n\n            // options.add(split[0]);\n            if (split.length > 1) { // After using the decimal point, one represents type idOffset position\n\n                if (aaptGeneration == AaptGeneration.AAPT_V1) {\n                    options.add(\"--type-id-offset\");\n                    options.add(split[1]);\n                } else {\n                    // TODO: 2018/3/5 AAPT_V2 type-id-offset\n                }\n\n            }\n        }\n        if (StringUtils.isNotBlank(getSktPackageName())) {\n\n            if (aaptGeneration == AaptGeneration.AAPT_V1) {\n                options.add(\"--main-package\");\n                options.add(getSktPackageName());\n            } else {\n                options.add(\"--rename-manifest-package\");\n                options.add(getPackageForR());\n            }\n\n        }\n        if (getAssetsDir()!= null){\n            options.add(\"-A\");\n            options.add(getAssetsDir().getAbsolutePath());\n        }\n        if (null != getShareResourceFile() && getShareResourceFile().exists()) {\n            options.add(\"-I\");\n            options.add(getShareResourceFile().getAbsolutePath());\n        }\n        if (null != getShareResourceFile2() && getShareResourceFile2().exists()) {\n            options.add(\"-I\");\n            options.add(getShareResourceFile2().getAbsolutePath());\n        }\n        if (null != getBaselineFile()) {\n            options.add(\"-B\");\n            options.add(getBaselineFile().getAbsolutePath());\n            options.add(\"--merge\");\n        }\n        if (!options.contains(\"--output-text-symbols\")){\n            options.add(\"--output-text-symbols\");\n            options.add(getTextSymbolOutputDir().getAbsolutePath());\n        }\n        String s;\n\n        if (aaptGeneration == AaptGeneration.AAPT_V1) {\n            s = \"--non-constant-id\";\n        } else {\n            s = \"--non-final-ids\";\n        }\n\n        if (!aaptOptions.getAdditionalParameters().contains(s)) {\n            aaptOptions.getAdditionalParameters().add(s);\n        }\n\n        aaptOptions.additionalParameters(options.toArray(new String[0]));\n    }\n\n    private boolean isSplitPackage(File file, File resBaseName) {\n        if (file.getName().startsWith(resBaseName.getName())) {\n            for (String split : splits) {\n                if (file.getName().contains(split)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    private Aapt makeAapt() throws IOException {\n        AndroidBuilder builder = getBuilder();\n        MergingLog mergingLog = new MergingLog(getMergeBlameLogFolder());\n        FileCache fileCache = appVariantContext.getScope().getGlobalScope().getBuildCache();\n        ProcessOutputHandler processOutputHandler =\n                new ParsingProcessOutputHandler(\n                        new ToolOutputParser(\n                                aaptGeneration == AaptGeneration.AAPT_V1\n                                        ? new AaptOutputParser()\n                                        : new Aapt2OutputParser(),\n                                getILogger()),\n                        new MergingLogRewriter(mergingLog::find, builder.getErrorReporter()));\n\n        return AaptGradleFactory.make(\n                aaptGeneration,\n                builder,\n                processOutputHandler,\n                fileCache,\n                true,\n                FileUtils.mkdirs(new File(getIncrementalFolder(), \"awb-aapt-temp/\"+awbBundle.getName())),\n                aaptOptions.getCruncherProcesses());\n    }\n\n    @Nullable\n    private static String absolutePath(@Nullable File file) {\n        return file == null ? null : file.getAbsolutePath();\n    }\n\n    public static class ConfigAction implements TaskConfigAction<ProcessAwbAndroidResources> {\n\n        private final VariantScope scope;\n\n        private final File symbolLocation;\n\n        private final boolean generateResourcePackage;\n\n        private final AwbBundle awbBundle;\n\n        private final AndroidBuilder tAndroidBuilder;\n\n        private final BaseVariantOutput variantOutput;\n\n        private InstantRunBuildContext instantRunBuildContext;\n\n        private final AppVariantOutputContext appVariantOutputContext;\n\n        public ConfigAction(VariantScope scope, File symbolLocation, boolean generateResourcePackage, AwbBundle awbBundle, AndroidBuilder androidBuilder, AppVariantOutputContext appVariantOutputContext, BaseVariantOutput variantOutput) {\n            this.scope = scope;\n            this.symbolLocation = symbolLocation;\n            this.generateResourcePackage = generateResourcePackage;\n            this.awbBundle = awbBundle;\n            this.tAndroidBuilder = androidBuilder;\n            this.appVariantOutputContext = appVariantOutputContext;\n            this.variantOutput = variantOutput;\n        }\n\n        @NonNull\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"process\", \"AwbResources[\" + awbBundle.getName() + \"]\");\n        }\n\n        @NonNull\n        @Override\n        public Class<ProcessAwbAndroidResources> getType() {\n            return ProcessAwbAndroidResources.class;\n        }\n\n        @Override\n        public void execute(@NonNull ProcessAwbAndroidResources processResources) {\n            final BaseVariantData variantData = scope.getVariantData();\n            final GradleVariantConfiguration config = variantData.getVariantConfiguration();\n            appVariantOutputContext.getAwbAndroidResourcesMap()\n                    .put(awbBundle.getName(), processResources);\n            processResources.setAndroidBuilder(tAndroidBuilder);\n            processResources.setVariantName(config.getFullName());\n            processResources.awbBundle = awbBundle;\n\n//            if (variantData.getSplitHandlingPolicy() ==\n//                SplitHandlingPolicy.RELEASE_21_AND_AFTER_POLICY) {\n                Set<String> allFilters = new HashSet<String>();\n                allFilters.addAll(variantData.getFilters(com.android.build.OutputFile.FilterType.DENSITY));\n                allFilters.addAll(variantData.getFilters(com.android.build.OutputFile.FilterType.LANGUAGE));\n                processResources.splits = allFilters;\n//            }\n\n            //Set the special parameters needed for the AWB resource processing\n            ConventionMappingHelper.map(processResources, \"mainSymbolFile\", new Callable<File>() {\n                @Override\n                public File call() throws Exception {\n                    return variantOutput.getProcessResources().getTextSymbolOutputFile();\n                }\n            });\n\n            processResources.setAwbBundleName(awbBundle.getName());\n\n            //TODO\n\n            ConventionMappingHelper.map(processResources,\n                                        \"customPackageId\",\n                                        new Callable<String>() {\n                                            @Override\n                                            public String call() throws Exception {\n\n                                                String value = AtlasBuildContext.customPackageIdMaps\n                                                        .get(awbBundle.getResolvedCoordinates()\n                                                                     .getGroupId() +\n                                                             \":\" +\n                                                             awbBundle.getResolvedCoordinates()\n                                                                     .getArtifactId());\n                                                if (org.apache.commons.lang.StringUtils.isEmpty(\n                                                        value)) {\n                                                    throw new GradleException(\"package id is empaty\" +\n                                                                              awbBundle);\n                                                }\n                                                return value;\n                                            }\n                                        });\n\n            ConventionMappingHelper.map(processResources,\n                                        \"shareResourceFile\",\n                                        new Callable<File>() {\n                                            @Override\n                                            public File call() throws Exception {\n                                                List<File>files = new ArrayList<>();\n                                                variantData.getScope().getOutputScope().getOutputs(VariantScope.TaskOutputType.PROCESSED_RES).forEach(buildOutput -> files.add(buildOutput.getOutputFile()));\n                                                if (files.size() == 0){\n                                                    return variantData.getScope().getProcessResourcePackageOutputDirectory().listFiles(new FilenameFilter() {\n                                                        @Override\n                                                        public boolean accept(File dir, String name) {\n                                                            return name.endsWith(\".ap_\");\n                                                        }\n                                                    })[0];\n                                                }\n                                                return files.get(0);\n                                            }\n                                        });\n\n            ConventionMappingHelper.map(processResources, \"sktPackageName\", new Callable<String>() {\n                @Override\n                public String call() throws Exception {\n                    FileCollection files = null;\n//                    if (scope.isBaseFeature()) {\n//                         files = scope.getArtifactFileCollection(\n//                                METADATA_VALUES, MODULE, METADATA_APP_ID_DECLARATION);\n//                    }\n                    String packageOverride;\n                    if (files != null && !files.isEmpty()) {\n                        packageOverride =\n                                ApplicationId.load(files.getSingleFile()).getApplicationId();\n                    } else {\n                        packageOverride = scope.getVariantConfiguration().getIdOverride();\n                    }\n\n                    if (packageOverride == null){\n                        File androidManifest = FileUtils.join(\n                                variantOutput.getProcessManifest().getManifestOutputDirectory(),\n                                variantOutput.getDirName(),\n                                SdkConstants.ANDROID_MANIFEST_XML);\n                     packageOverride = ManifestFileUtils.getApplicationId(androidManifest);\n                    }\n                    if (null != packageOverride) {\n                        return packageOverride;\n                    } else {\n                        return config.getOriginalApplicationId();\n                    }\n                }\n            });\n\n            // only generate code if the density filter is null, and if we haven't generated\n            // it yet (if you have abi + density splits, then several abi output will have no\n            // densityFilter)\n            //TODO  What's the use of removing this if logic\n            //            if (variantOutputData.getMainOutputFile()\n            //                    .getFilter(com.android.build.OutputFile.DENSITY) == null\n            //                    && variantData.generateRClassTask == null) {\n            //                variantData.generateRClassTask = processResources;\n//            processResources.enforceUniquePackageName = scope.getGlobalScope().getExtension().getPackagingOptions().\n//                    .getExtension()\n//                    .getEnforceUniquePackageName();\n            processResources.enforceUniquePackageName = true;\n\n            ConventionMappingHelper.map(processResources,\n                                        \"libraries\",\n                                        new Callable<List<? extends AndroidLibrary>>() {\n                                            @Override\n                                            public List<? extends AndroidLibrary> call() throws Exception {\n                                                List<AndroidLibrary>awbLibraries = new ArrayList<>();\n                                                awbLibraries.addAll(awbBundle.getAndroidLibraries());\n                                                awbLibraries.add(awbBundle.getAndroidLibrary());\n                                                return awbLibraries;\n                                            }\n                                        });\n            ConventionMappingHelper.map(processResources, \"packageForR\", new Callable<String>() {\n                @Override\n                public String call() throws Exception {\n                    return awbBundle.getPackageName();\n                }\n            });\n\n            ConventionMappingHelper.map(processResources, \"rtxtFile\", new Callable<File>() {\n                @Override\n                public File call() throws Exception {\n                    return new File(awbBundle.getAndroidLibrary().getFolder(), \"R.txt\");\n                }\n            });\n\n            // TODO: unify with generateBuilderConfig, compileAidl, and library packaging somehow?\n                processResources.setSourceOutputDir(appVariantOutputContext.getAwbRClassSourceOutputDir(\n                    config,\n                    awbBundle));\n            processResources.setTextSymbolOutputDir(symbolLocation);\n\n            //AWbDo not do shrinkResource work for a while\n            //                if (config.getBuildType().isMinifyEnabled()) {\n            //                    if (config.getBuildType().isShrinkResources() && config.getUseJack()) {\n            //                        LoggingUtil.displayWarning(Logging.getLogger(getClass()),\n            //                                config.getGlobalScope().getProject(),\n            //                                \"shrinkResources does not yet work with useJack=true\");\n            //                    }\n            //                    processResources.setProguardOutputFile(\n            //                            config.getVariantScope().getProcessAndroidResourcesProguardOutputFile());\n            //\n            //                } else if (config.getBuildType().isShrinkResources()) {\n            //                    LoggingUtil.displayWarning(Logging.getLogger(getClass()),\n            //                            config.getGlobalScope().getProject(),\n            //                            \"To shrink resources you must also enable ProGuard\");\n            //                }\n            //            }\n\n            ConventionMappingHelper.map(processResources, \"manifestFile\", new Callable<File>() {\n                @Override\n                public File call() throws Exception {\n                    return awbBundle.getMergedManifest();\n                }\n            });\n\n            ConventionMappingHelper.map(processResources,\n                                        \"instantRunManifestFile\",\n                                        new Callable<File>() {\n                                            @Override\n                                            public File call() throws Exception {\n                                                return awbBundle.getMergedManifest();\n                                            }\n                                        });\n\n            ConventionMappingHelper.map(processResources, \"resDir\", new Callable<File>() {\n                @Override\n                public File call() throws Exception {\n\n                    File file = null;\n//                    if (appVariantOutputContext.getVariantContext().isDataBindEnabled(awbBundle)) {\n//                        file = appVariantOutputContext.getVariantContext()\n//                                .getAwbLayoutFolderOutputForDataBinding(awbBundle);\n//                    } else {\n                        file = appVariantOutputContext.getVariantContext()\n                                .getMergeResources(awbBundle);\n//                    }\n\n                    if (!file.exists()) {\n                        file.mkdirs();\n                    }\n                    return file;\n                }\n            });\n\n            ConventionMappingHelper.map(processResources, \"assetsDir\", new Callable<File>() {\n                @Override\n                public File call() throws Exception {\n                    return appVariantOutputContext.getVariantContext().getMergeAssets(awbBundle);\n                }\n            });\n            if (appVariantOutputContext.getVariantContext()\n                    .getAtlasExtension()\n                    .getTBuildConfig()\n                    .isIncremental()) {\n                ConventionMappingHelper.map(processResources, \"baselineFile\", new Callable<File>() {\n                    @Override\n                    public File call() throws Exception {\n                        return appVariantOutputContext.getVariantContext().apContext.getBaseAwb(\n                                awbBundle.getAwbSoName());\n                    }\n                });\n\n                ConventionMappingHelper.map(processResources,\n                                            \"shareResourceFile2\",\n                                            new Callable<File>() {\n                                                @Override\n                                                public File call() throws Exception {\n                                                    return appVariantOutputContext.getVariantContext().apContext\n                                                            .getBaseApk();\n                                                }\n                                            });\n            }\n\n            if (generateResourcePackage) {\n                processResources.setPackageOutputFile(appVariantOutputContext.getAwbProcessResourcePackageOutputFile(\n                        awbBundle));\n            }\n\n            processResources.setType(config.getType());\n            processResources.setDebuggable(config.getBuildType().isDebuggable());\n            processResources.appVariantContext =appVariantOutputContext;\n            AaptOptions aaptOptions = scope.getGlobalScope().getExtension().getAaptOptions();\n            AaptOptions cloneAaptOptions = new MyAaptOptions();\n            try {\n                BeanUtils.copyProperties(cloneAaptOptions, aaptOptions);\n            } catch (Throwable e) {\n                throw new StopExecutionException(e.getMessage());\n            }\n            processResources.setAaptOptions(cloneAaptOptions);\n\n            processResources.setPseudoLocalesEnabled(config.getBuildType()\n                                                             .isPseudoLocalesEnabled());\n\n            ConventionMappingHelper.map(processResources,\n                                        \"resourceConfigs\",\n                                        new Callable<Collection<String>>() {\n                                            @Override\n                                            public Collection<String> call() throws Exception {\n                                                FileCollection splitList =\n                                                        scope.getOutput(TaskOutputHolder.TaskOutputType.SPLIT_LIST);\n\n                                                SplitList splitList1 = SplitList.load(splitList);\n\n                                                return splitList1.getFilters(SplitList.RESOURCE_CONFIGS);\n//                                                Collection<String> resConfigs = config.getMergedFlavor()\n//                                                        .getResourceConfigurations();\n//                                                if (resConfigs.size() == 1 &&\n//                                                    Iterators.getOnlyElement(resConfigs.iterator())\n//                                                            .equals(\"auto\")) {\n//                                                    if (scope.getGlobalScope()\n//                                                                .getAndroidBuilder()\n//                                                                .getTargetInfo()\n//                                                                .getBuildTools()\n//                                                                .getRevision()\n//                                                                .getMajor() >= 21) {\n//                                                        return variantData.discoverListOfResourceConfigs();\n//                                                    } else {\n//                                                        return variantData.discoverListOfResourceConfigs();\n//                                                    }\n//                                                }\n//                                                return config.getMergedFlavor()\n//                                                        .getResourceConfigurations();\n                                            }\n                                        });\n\n            ConventionMappingHelper.map(processResources,\n                                        \"preferredDensity\",\n                    (Callable<String>) () -> {\n                        FileCollection splitList =\n                                scope.getOutput(TaskOutputHolder.TaskOutputType.SPLIT_LIST);\n\n                        SplitList splitList1 = SplitList.load(splitList);\n                        return splitList1.getFilters(SplitList.RESOURCE_CONFIGS).isEmpty()\n                                ? scope.getGlobalScope().getProjectOptions().get(StringOption.IDE_BUILD_TARGET_DENSITY)\n                                : null;\n                    }\n                    );\n\n            processResources.setMergeBlameLogFolder(getResourceBlameLogDir(config));\n\n            processResources.instantRunSupportDir = getInstantRunSupportDir(config);\n\n            ProjectOptions projectOptions = scope.getGlobalScope().getProjectOptions();\n            this.instantRunBuildContext =\n                    new InstantRunBuildContext(\n                            variantData.getVariantConfiguration().isInstantRunBuild(scope.getGlobalScope()),\n                            AaptGeneration.fromProjectOptions(projectOptions),\n                            DeploymentDevice.getDeploymentDeviceAndroidVersion(projectOptions),\n                            projectOptions.get(StringOption.IDE_BUILD_TARGET_ABI),\n                            projectOptions.get(StringOption.IDE_BUILD_TARGET_DENSITY),\n                            projectOptions.get(BooleanOption.ENABLE_SEPARATE_APK_RESOURCES));\n           processResources.instantRunBuildContext = instantRunBuildContext;\n            //processResources.buildInfoFile = InstantRunWrapperTask.ConfigAction.getTmpBuildInfoFile(\n            //        scope.getVariantScope());\n        }\n\n        public File getInstantRunSupportDir(GradleVariantConfiguration config) {\n            return new File(scope.getGlobalScope().getIntermediatesDir(),\n                            \"/awb-instant-run-support/\" +\n                            config.getDirName() +\n                            \"/\" +\n                            awbBundle.getName());\n        }\n\n        public File getResourceBlameLogDir(GradleVariantConfiguration config) {\n            return new File(scope.getGlobalScope().getIntermediatesDir(),\n                            \"awb-blame/res/\" +\n                            config.getDirectorySegments() +\n                            \"/\" +\n                            awbBundle.getName());\n        }\n    }\n\n    @InputFile\n    public File getManifestFile() {\n        return manifestFile;\n    }\n\n    public void setManifestFile(File manifestFile) {\n        this.manifestFile = manifestFile;\n    }\n\n    // not an input, it's optional and should never changes independently of the main manifest file.\n    public File getInstantRunManifestFile() {\n        return instantRunManifestFile;\n    }\n\n    public void setInstantRunManifestFile(File manifestFile) {\n        this.instantRunManifestFile = manifestFile;\n    }\n\n    @NonNull\n    @InputDirectory\n    public File getResDir() {\n        return resDir;\n    }\n\n    public void setResDir(@NonNull File resDir) {\n        this.resDir = resDir;\n    }\n\n    @InputDirectory\n    @Optional\n    @Nullable\n    public File getAssetsDir() {\n        return assetsDir;\n    }\n\n    public void setAssetsDir(File assetsDir) {\n        this.assetsDir = assetsDir;\n    }\n\n    @OutputDirectory\n    @Optional\n    @Nullable\n    public File getSourceOutputDir() {\n        return sourceOutputDir;\n    }\n\n    public void setSourceOutputDir(File sourceOutputDir) {\n        this.sourceOutputDir = sourceOutputDir;\n    }\n\n    @OutputDirectory\n    @Optional\n    @Nullable\n    public File getTextSymbolOutputDir() {\n        return textSymbolOutputDir;\n    }\n\n    public void setTextSymbolOutputDir(File textSymbolOutputDir) {\n        this.textSymbolOutputDir = textSymbolOutputDir;\n    }\n\n    @OutputFile\n    @Optional\n    @Nullable\n    public File getPackageOutputFile() {\n        return packageOutputFile;\n    }\n\n    public void setPackageOutputFile(File packageOutputFile) {\n        this.packageOutputFile = packageOutputFile;\n    }\n\n    @OutputFile\n    @Optional\n    @Nullable\n    public File getProguardOutputFile() {\n        return proguardOutputFile;\n    }\n\n    public void setProguardOutputFile(File proguardOutputFile) {\n        this.proguardOutputFile = proguardOutputFile;\n    }\n\n    @Input\n    public Collection<String> getResourceConfigs() {\n        return resourceConfigs;\n    }\n\n    public void setResourceConfigs(Collection<String> resourceConfigs) {\n        this.resourceConfigs = resourceConfigs;\n    }\n\n    @Input\n    @Optional\n    @Nullable\n    public String getPreferredDensity() {\n        return preferredDensity;\n    }\n\n    public void setPreferredDensity(String preferredDensity) {\n        this.preferredDensity = preferredDensity;\n    }\n\n    @Input\n    String getBuildToolsVersion() {\n        return getBuildTools().getRevision().toString();\n    }\n\n    @Nested\n    @Optional\n    @Nullable\n    public List<? extends AndroidLibrary> getLibraries() {\n        return libraries;\n    }\n\n    public void setLibraries(List<? extends AndroidLibrary> libraries) {\n        this.libraries = libraries;\n    }\n\n    @Input\n    @Optional\n    @Nullable\n    public String getPackageForR() {\n        return packageForR;\n    }\n\n    public void setPackageForR(String packageForR) {\n        this.packageForR = packageForR;\n    }\n\n    @Input\n    @Optional\n    @Nullable\n    public Collection<String> getSplits() {\n        return splits;\n    }\n\n    public void setSplits(Collection<String> splits) {\n        this.splits = splits;\n    }\n\n    @Input\n    public boolean getEnforceUniquePackageName() {\n        return enforceUniquePackageName;\n    }\n\n    public void setEnforceUniquePackageName(boolean enforceUniquePackageName) {\n        this.enforceUniquePackageName = enforceUniquePackageName;\n    }\n\n    /**\n     * Does not change between incremental builds, so does not need to be @Input.\n     */\n    public VariantType getType() {\n        return type;\n    }\n\n    public void setType(VariantType type) {\n        this.type = type;\n    }\n\n    @Input\n    public boolean getDebuggable() {\n        return debuggable;\n    }\n\n    public void setDebuggable(boolean debuggable) {\n        this.debuggable = debuggable;\n    }\n\n    @Input\n    public boolean getPseudoLocalesEnabled() {\n        return pseudoLocalesEnabled;\n    }\n\n    public void setPseudoLocalesEnabled(boolean pseudoLocalesEnabled) {\n        this.pseudoLocalesEnabled = pseudoLocalesEnabled;\n    }\n\n    @Nested\n    public com.android.build.gradle.internal.dsl.AaptOptions getAaptOptions() {\n        return aaptOptions;\n    }\n\n    public void setAaptOptions(AaptOptions aaptOptions) {\n        this.aaptOptions = aaptOptions;\n    }\n\n    @Input\n    public File getMergeBlameLogFolder() {\n        return mergeBlameLogFolder;\n    }\n\n    public void setMergeBlameLogFolder(File mergeBlameLogFolder) {\n        this.mergeBlameLogFolder = mergeBlameLogFolder;\n    }\n\n    @InputFile\n    public File getMainSymbolFile() {\n        return mainSymbolFile;\n    }\n\n    public void setMainSymbolFile(File mainSymbolFile) {\n        this.mainSymbolFile = mainSymbolFile;\n    }\n\n    @Input\n    public String getAwbBundleName() {\n        return awbBundleName;\n    }\n\n    public void setAwbBundleName(String awbBundleName) {\n        this.awbBundleName = awbBundleName;\n    }\n\n    @Input\n    @Optional\n    public String getCustomPackageId() {\n        return customPackageId;\n    }\n\n    public void setCustomPackageId(String customPackageId) {\n        this.customPackageId = customPackageId;\n    }\n\n    @Input\n    public String getSktPackageName() {\n        return sktPackageName;\n    }\n\n    public void setSktPackageName(String sktPackageName) {\n        this.sktPackageName = sktPackageName;\n    }\n\n    @InputFile\n    public File getShareResourceFile() {\n        return shareResourceFile;\n    }\n\n    public void setShareResourceFile(File shareResourceFile) {\n        this.shareResourceFile = shareResourceFile;\n    }\n\n    @InputFile\n    @Optional\n    public File getShareResourceFile2() {\n        return shareResourceFile2;\n    }\n\n    public void setShareResourceFile2(File shareResourceFile2) {\n        this.shareResourceFile2 = shareResourceFile2;\n    }\n\n    @InputFile\n    @Optional\n    public File getRtxtFile() {\n        return rtxtFile;\n    }\n\n    @InputFile\n    @Optional\n    public File getBaselineFile() {\n        return baselineFile;\n    }\n\n    public void setBaselineFile(File baselineFile) {\n        this.baselineFile = baselineFile;\n    }\n\n    public static class MyAaptOptions extends AaptOptions {\n\n        @Override\n        public void useNewCruncher(boolean value) {\n\n        }\n\n        @Override\n        public void setUseNewCruncher(boolean value) {\n\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/bundle/ProcessResAwbsTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.bundle;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tasks.manager.TaskCreater;\nimport com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.file.FileCollection;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.ExecutionException;\n\n/**\n * Pack up awb the resource\n */\npublic class ProcessResAwbsTask extends BaseTask {\n\n    static final String taskName = \"processResAwbs\";\n\n    private AppVariantContext appVariantContext;\n    private AppVariantOutputContext appVariantOutputContext;\n\n    public FileCollection mainDexSymbolFileCollection;\n\n    private BaseVariantOutput baseVariantOutput;\n\n\n    @TaskAction\n    void run() throws ExecutionException, InterruptedException {\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n                getVariantName());\n\n        if (null == atlasDependencyTree) {\n            return;\n        }\n\n        final VariantScope outputScope = appVariantOutputContext.getScope();\n\n        ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper(taskName,\n                                                                                   getLogger(),\n                                                                                   0);\n        List<Runnable> runnables = new ArrayList<>();\n\n        for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n            if (awbBundle.isMBundle){\n                continue;\n            }\n\n            runnables.add(new Runnable() {\n                @Override\n                public void run() {\n\n                    File symbolLocation = new File(outputScope.getGlobalScope()\n                                                           .getIntermediatesDir(),\n                                                   \"awb-symbols/\" +\n                                                           outputScope\n                                                                   .getVariantConfiguration()\n                                                                   .getDirName() +\n                                                           \"/\" +\n                                                           awbBundle.getName());\n\n                    //Write the resources to the ap for debug\n                    if (\"debug\".equals(appVariantOutputContext.getVariantContext()\n                                               .getBaseVariantData()\n                                               .getName())) {\n                        appVariantOutputContext.appBuildInfo.getOtherFilesMap()\n                                .put(\"awo/\" + awbBundle.getPackageName() + \".R.txt\",\n                                     new File(symbolLocation, \"R.txt\"));\n                    }\n\n                    ProcessAwbAndroidResources.ConfigAction configAction = new ProcessAwbAndroidResources.ConfigAction(\n                            outputScope,\n                            symbolLocation,\n                            true,\n                            awbBundle,\n                            getBuilder(),\n                            appVariantOutputContext,baseVariantOutput);\n\n                    ProcessAwbAndroidResources processAwbAndroidResources = TaskCreater.create(\n                            getProject(),\n                            configAction.getName(),\n                            configAction.getType());\n                    processAwbAndroidResources.mainDexSymbolFileCollection = mainDexSymbolFileCollection;\n\n                    appVariantContext.awbsProcessResourcesTask.put(awbBundle.getName(),processAwbAndroidResources);\n                    configAction.execute(processAwbAndroidResources);\n\n                    try {\n                        processAwbAndroidResources.doFullTaskAction();\n                    } catch (IOException e) {\n                        throw new GradleException(\"process awb res exception\", e);\n                    }\n                }\n            });\n        }\n\n        executorServicesHelper.execute(runnables);\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<ProcessResAwbsTask> {\n\n        private AppVariantContext variantContext;\n        public ConfigAction(AppVariantContext appVariantContext,\n                            BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n            this.variantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(taskName);\n        }\n\n        @Override\n        public Class<ProcessResAwbsTask> getType() {\n            return ProcessResAwbsTask.class;\n        }\n\n        @Override\n        public void execute(ProcessResAwbsTask processResAwbsTask) {\n\n            super.execute(processResAwbsTask);\n            processResAwbsTask.baseVariantOutput = baseVariantOutput;\n            processResAwbsTask.appVariantContext = variantContext;\n            processResAwbsTask.appVariantOutputContext = getAppVariantOutputContext();\n            variantContext.processResAwbsTask= processResAwbsTask;\n        }\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/bundle/actions/FirstApkAction.java",
    "content": "package com.taobao.android.builder.tasks.app.bundle.actions;\n\nimport com.android.SdkConstants;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.scope.TaskOutputHolder;\nimport com.android.build.gradle.tasks.PackageApplication;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport com.taobao.android.builder.tools.zip.BetterZip;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.Action;\nimport org.gradle.api.Task;\n\nimport java.io.File;\nimport java.io.IOException;\n\nimport static com.android.SdkConstants.FN_RES_BASE;\nimport static com.android.SdkConstants.RES_QUALIFIER_SEP;\n\n/**\n * FirstApkAction\n *\n * @author zhayu.ll\n * @date 18/1/12\n * @time 下午7:23\n * @description  \n */\npublic class FirstApkAction implements Action<Task> {\n\n    private AppVariantOutputContext appVariantOutputContext;\n\n    public FirstApkAction(AppVariantOutputContext appVariantOutputContext) {\n        this.appVariantOutputContext = appVariantOutputContext;\n    }\n    @Override\n    public void execute(Task task) {\n        assert task instanceof PackageApplication;\n        PackageApplication packageApplication = (PackageApplication) task;\n        if (packageApplication.getName().startsWith(\"packageInstantRunResources\")){\n            return;\n        }\n        File bundleInfoFile = new File(appVariantOutputContext.getScope().getGlobalScope().getOutputsDir(),\n                \"bundleInfo-\" +\n                        appVariantOutputContext.getVariantContext().getVariantConfiguration()\n                                .getVersionName() +\n                        \".json\");\n\n        File nativeInfoFile = new File(appVariantOutputContext.getScope().getGlobalScope().getOutputsDir(),\n                \"nativeInfo-\" +\n                        appVariantOutputContext.getVariantContext().getVariantConfiguration()\n                                .getVersionName() +\n                        \".json\");\n        File resOutBaseNameFile =\n                new File(\n                        packageApplication.getResourceFiles().getSingleFile(),\n                        FN_RES_BASE\n                                + RES_QUALIFIER_SEP\n                                + appVariantOutputContext.getVariantContext().getVariantName()\n                                + SdkConstants.DOT_RES);\n\n\n        File[]dexs = null;\n\n        if (packageApplication.getDexFolders().getFiles().size() == 0){\n            dexs = appVariantOutputContext.getDexMergeFolder().listFiles(pathname -> pathname.getName().equals(\"classes.dex\"));\n            ReflectUtils.updateField(packageApplication,\"dexFolders\",appVariantOutputContext.getVariantContext().getProject().files(appVariantOutputContext.getDexMergeFolder()));\n        }else {\n            dexs = packageApplication.getDexFolders().getSingleFile().listFiles(pathname -> pathname.getName().equals(\"classes.dex\"));\n        }\n        if (dexs!= null && dexs.length == 1) {\n            File androidManifest = null;\n            if (appVariantOutputContext.getApkData().getFilterName() == null){\n                androidManifest = com.android.utils.FileUtils.join(appVariantOutputContext.getScope().getOutput(TaskOutputHolder.TaskOutputType.MERGED_MANIFESTS).getSingleFile(),\"AndroidManifest.xml\");\n            }else {\n                androidManifest = com.android.utils.FileUtils.join(appVariantOutputContext.getScope().getOutput(TaskOutputHolder.TaskOutputType.MERGED_MANIFESTS).getSingleFile(),appVariantOutputContext.getApkData().getDirName(),\"AndroidManifest.xml\");\n            }\n            File file = AtlasBuildContext.atlasApkProcessor.securitySignApk(dexs[0], androidManifest,appVariantOutputContext.getVariantContext().getBuildType(),false);\n            if (file!= null && file.exists()){\n                try {\n                    BetterZip.addFile(resOutBaseNameFile, \"res/drawable/\".concat(file.getName()), file);\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n            }\n        }\n        if (bundleInfoFile.exists()){\n            try {\n                BetterZip.addFile(resOutBaseNameFile, \"assets/\".concat(bundleInfoFile.getName()), bundleInfoFile);\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n\n        if (nativeInfoFile.exists()){\n            try {\n                BetterZip.addFile(resOutBaseNameFile, \"assets/\".concat(nativeInfoFile.getName()), nativeInfoFile);\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/bundle/actions/LastApkAction.java",
    "content": "package com.taobao.android.builder.tasks.app.bundle.actions;\nimport org.gradle.api.Action;\nimport org.gradle.api.Task;\n\n/**\n * ApkLastAction\n *\n * @author zhayu.ll\n * @date 18/1/12\n * @time 下午5:38\n * @description  \n */\npublic class LastApkAction implements Action<Task> {\n\n\n    @Override\n    public void execute(Task packageApplication) {\n        \n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/bundle/actions/LastBundleAction.java",
    "content": "package com.taobao.android.builder.tasks.app.bundle.actions;\n\nimport com.alibaba.fastjson.JSON;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.utils.ILogger;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.transform.AtlasMergeJavaResourcesTransform;\nimport com.taobao.android.builder.tools.MD5Util;\nimport com.taobao.android.builder.tools.bundleinfo.DynamicBundleInfo;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.Action;\nimport org.gradle.api.Task;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.locks.Lock;\n\n/**\n * LastBundleAction\n *\n * @author zhayu.ll\n * @date 18/1/12\n * @time 下午6:49\n * @description  \n */\npublic class LastBundleAction implements Action<Task> {\n\n    private ILogger logger = LoggerWrapper.getLogger(LastBundleAction.class);\n\n    protected Map<AwbBundle, File> awbBundles;\n\n    protected AppVariantOutputContext appVariantOutputContext;\n\n    public LastBundleAction(Map<AwbBundle, File> awbMap, AppVariantOutputContext appVariantOutputContext) {\n        this.awbBundles = awbMap;\n        this.appVariantOutputContext = appVariantOutputContext;\n    }\n\n    @Override\n    public void execute(Task o) {\n\n        if (appVariantOutputContext.getSoMap().size() > 0) {\n            File nativeBundleInfo = new File(appVariantOutputContext.getScope().getGlobalScope().getOutputsDir(),\n                    \"nativeInfo-\" +\n                            appVariantOutputContext.getVariantContext().getVariantConfiguration()\n                                    .getVersionName() +\n                            \".json\");\n\n            try {\n                org.apache.commons.io.FileUtils.write(nativeBundleInfo, JSON.toJSONString(appVariantOutputContext.getSoMap().values()));\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n\n        if (appVariantOutputContext.getVariantData().getName().endsWith(\"debug\")) {\n            if (awbBundles != null) {\n                for (Map.Entry<AwbBundle, File> entry : awbBundles.entrySet()) {\n                    String url = AtlasBuildContext.atlasApkProcessor.uploadBundle(appVariantOutputContext.getVariantContext().getProject(), entry.getValue(), entry.getKey(), appVariantOutputContext.getVariantContext().getBuildType());\n                    if (StringUtils.isNotEmpty(url)) {\n                        entry.getKey().bundleInfo.setUrl(url);\n                    }\n                    entry.getKey().bundleInfo.setMd5(MD5Util.getFileMD5(entry.getValue()));\n                    entry.getKey().bundleInfo.setSize(entry.getValue().length());\n                    AtlasBuildContext.atlasApkProcessor.removeBundle(appVariantOutputContext, entry.getKey(), entry.getValue());\n                }\n\n            }\n            List<DynamicBundleInfo> dynamicBundleInfos = AtlasBuildContext.atlasApkProcessor.generateAllBundleInfo(awbBundles.keySet());\n            File bundleInfoFile = new File(appVariantOutputContext.getScope().getGlobalScope().getOutputsDir(),\n                    \"bundleInfo-\" +\n                            appVariantOutputContext.getVariantContext().getVariantConfiguration()\n                                    .getVersionName() +\n                            \".json\");\n\n            try {\n                org.apache.commons.io.FileUtils.write(bundleInfoFile, JSON.toJSONString(dynamicBundleInfos));\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n\n        } else {\n            logger.info(\"do nothing when packageAwbs done in \" + appVariantOutputContext.getVariantData().getName() + \" build!\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/databinding/AwbDataBindingExportBuildInfoTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.databinding;\n\nimport android.databinding.tool.DataBindingBuilder;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.publishing.AndroidArtifacts;\nimport com.android.build.gradle.internal.scope.TaskConfigAction;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.build.gradle.internal.tasks.databinding.DataBindingExportBuildInfoTask;\nimport com.android.build.gradle.internal.variant.BaseVariantData;\nimport com.google.common.base.Predicate;\nimport com.google.common.base.Supplier;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Iterables;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tasks.manager.TaskCreater;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper;\nimport org.gradle.api.file.ConfigurableFileTree;\nimport org.gradle.api.file.FileCollection;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.concurrent.ExecutionException;\n\n/**\n * Created by wuzhong on 2017/3/27.\n */\npublic class AwbDataBindingExportBuildInfoTask extends BaseTask {\n\n    AppVariantContext appVariantContext;\n\n    @TaskAction\n    public void run() throws ExecutionException, InterruptedException {\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n            getVariantName());\n\n        if (null == atlasDependencyTree) {\n            return;\n        }\n\n        DataBindingBuilder dataBindingBuilder = new DataBindingBuilder();\n        dataBindingBuilder.setPrintMachineReadableOutput(false);\n        dataBindingBuilder.setDebugLogEnabled(appVariantContext.getProject().getLogger().isDebugEnabled());\n\n        List<Runnable> tasks = new ArrayList<Runnable>();\n\n        for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n\n            if (!appVariantContext.getAtlasExtension().getTBuildConfig().getDataBindingBundles().contains(awbBundle.getPackageName())|| awbBundle.isMBundle){\n                continue;\n            }\n\n            tasks.add(new Runnable() {\n                @Override\n                public void run() {\n\n                    AwbDataBindingExportBuildInfoConfigAction exportBuildInfoConfigAction\n                        = new AwbDataBindingExportBuildInfoConfigAction(appVariantContext, awbBundle,\n                                                                        dataBindingBuilder\n                                                                            .getPrintMachineReadableOutput(),\n                                                                        dataBindingBuilder);\n                    DataBindingExportBuildInfoTask exportBuildInfoTask = TaskCreater.create(\n                        appVariantContext.getProject(),\n                        exportBuildInfoConfigAction\n                            .getName(),\n                        exportBuildInfoConfigAction\n                            .getType());\n                    exportBuildInfoConfigAction.execute(exportBuildInfoTask);\n\n                    exportBuildInfoTask.execute();\n                }\n            });\n\n        }\n\n        ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper(\"dataBindingExportBuildInfo\",\n                                                                                   getLogger(),\n                                                                                   0);\n\n        executorServicesHelper.execute(tasks);\n\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<AwbDataBindingExportBuildInfoTask> {\n\n        private AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext, BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"dataBindingExportBuildInfo\", \"Awbs\");\n        }\n\n        @Override\n        public Class<AwbDataBindingExportBuildInfoTask> getType() {\n            return AwbDataBindingExportBuildInfoTask.class;\n        }\n\n        @Override\n        public void execute(AwbDataBindingExportBuildInfoTask parallelTask) {\n\n            super.execute(parallelTask);\n\n            parallelTask.appVariantContext = appVariantContext;\n\n        }\n    }\n\n    public static class AwbDataBindingExportBuildInfoConfigAction implements TaskConfigAction<DataBindingExportBuildInfoTask> {\n        private final AppVariantContext appVariantContext;\n        private final boolean printMachineReadableErrors;\n        private final AwbBundle awbBundle;\n        private final DataBindingBuilder dataBindingBuilder;\n\n        public AwbDataBindingExportBuildInfoConfigAction(AppVariantContext appVariantContext, AwbBundle awbBundle,\n                                                         boolean printMachineReadableErrors,\n                                                         DataBindingBuilder dataBindingBuilder) {\n            this.appVariantContext = appVariantContext;\n            this.printMachineReadableErrors = printMachineReadableErrors;\n            this.awbBundle = awbBundle;\n            this.dataBindingBuilder = dataBindingBuilder;\n        }\n\n        @Override\n        public String getName() {\n            return appVariantContext.getScope().getTaskName(\n                \"dataBindingExportBuildInfoAwb[\" + awbBundle.getName() + \"]\");\n        }\n\n        @Override\n        public Class<DataBindingExportBuildInfoTask> getType() {\n            return DataBindingExportBuildInfoTask.class;\n        }\n\n        @Override\n        public void execute(DataBindingExportBuildInfoTask task) {\n            final BaseVariantData variantData = appVariantContext.getScope()\n                .getVariantData();\n            task.setXmlProcessor(\n                AwbXmlProcessor.getLayoutXmlProcessor(appVariantContext, awbBundle, dataBindingBuilder));\n            task.setSdkDir(appVariantContext.getScope().getGlobalScope().getSdkHandler().getSdkFolder());\n            if (!appVariantContext.getAwbLayoutInfoOutputForDataBinding(awbBundle).exists()) {\n                appVariantContext.getAwbLayoutInfoOutputForDataBinding(awbBundle).mkdirs();\n            }\n            task.setXmlOutFolder(appVariantContext.getAwbLayoutInfoOutputForDataBinding(awbBundle));\n\n            ReflectUtils.updateField(task, \"compilerClasspath\", (Supplier<FileCollection>) () -> appVariantContext.getScope().getJavaClasspath(AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH, AndroidArtifacts.ArtifactType.CLASSES));\n            Object o = new Supplier<Collection<ConfigurableFileTree>>() {\n                @Override\n                public Collection<ConfigurableFileTree> get() {\n                    Iterable ier = Iterables.filter(appVariantContext.getAwSourceOutputDir(awbBundle), new Predicate<ConfigurableFileTree>() {\n                        @Override\n                        public boolean apply(ConfigurableFileTree input) {\n                            File dataBindingOut = appVariantContext\n                                    .getAwbClassOutputForDataBinding(awbBundle);\n                            return !dataBindingOut.equals(input.getDir());\n                        }\n                    });\n                    return ImmutableList.copyOf(ier);\n\n                }\n            };\n            ReflectUtils.updateField(task, \"compilerSources\", o);\n\n//                    new Predicate<ConfigurableFileTree>() {\n//                        @Override\n//                        public boolean apply(ConfigurableFileTree input) {\n//                            File\n//                                    dataBindingOut = appVariantContext\n//                                    .getAwbClassOutputForDataBinding(awbBundle);\n//                            return !dataBindingOut.equals(input.getDir());\n//                        }\n//                    })));\n//\n//            ConventionMappingHelper\n//                .map(task, \"compilerSources\", new Callable<Iterable<ConfigurableFileTree>>() {\n//                    @Override\n//                    public Iterable<ConfigurableFileTree> call() throws Exception {\n//                        return Iterables.filter(appVariantContext.getAwSourceOutputDir(awbBundle),\n//                                                new Predicate<ConfigurableFileTree>() {\n//                                                    @Override\n//                                                    public boolean apply(ConfigurableFileTree input) {\n//                                                        File\n//                                                            dataBindingOut = appVariantContext\n//                                                            .getAwbClassOutputForDataBinding(awbBundle);\n//                                                        return !dataBindingOut.equals(input.getDir());\n//                                                    }\n//                                                });\n//                    }\n//                });\n\n            task.setExportClassListTo(variantData.getType().isExportDataBindingClassList() ?\n                                          new File(appVariantContext.getAwbLayoutFolderOutputForDataBinding(awbBundle),\n                                                   \"_generated.txt\") : null);\n            //task.setPrintMachineReadableErrors(printMachineReadableErrors);\n            task.setDataBindingClassOutput(appVariantContext.getAwbClassOutputForDataBinding(awbBundle));\n\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/databinding/AwbDataBindingMergeArtifactsTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.databinding;\n\nimport android.databinding.tool.DataBindingBuilder;\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.AndroidConfig;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.utils.FileUtils;\nimport com.google.common.base.Charsets;\nimport com.google.common.hash.HashCode;\nimport com.google.common.hash.HashFunction;\nimport com.google.common.hash.Hashing;\nimport com.google.common.io.ByteStreams;\nimport com.google.common.io.Closer;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.ExecutionException;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\n\npublic class AwbDataBindingMergeArtifactsTask extends BaseTask {\n\n    static final String taskName = \"dataBindingMergeAwbsArtifacts\";\n\n    private AndroidConfig androidConfig;\n    private AppVariantContext appVariantContext;\n    private AppVariantOutputContext appVariantOutputContext;\n    private GradleVariantConfiguration config;\n    private BaseVariantOutput variantOutputData;\n\n    /**\n     * Directory of so\n     */\n    @TaskAction\n    void createAwbPackages() throws ExecutionException, InterruptedException {\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(getVariantName());\n\n        if (null == atlasDependencyTree) {\n            return;\n        }\n\n\n        ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper(taskName, getLogger(), 0);\n        List<Runnable> runnables = new ArrayList<>();\n\n        for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n\n            if (!appVariantContext.getAtlasExtension().getTBuildConfig().getDataBindingBundles().contains(awbBundle.getPackageName()) || awbBundle.isMBundle){\n                continue;\n            }\n\n            runnables.add(new Runnable() {\n                @Override\n                public void run() {\n\n                    try {\n                        fullCopy(appVariantContext.getAwbDataBindingMergeArtifacts(awbBundle),\n                                 awbBundle);\n\n\n                    } catch (Throwable e) {\n                        e.printStackTrace();\n                        throw new GradleException(\"merge awb artifact failed\");\n                    }\n\n                }\n            });\n\n        }\n\n        executorServicesHelper.execute(runnables);\n\n    }\n\n    private void fullCopy(File outFolder, AwbBundle awbBundle) throws IOException {\n        if (outFolder.exists()) {\n            FileUtils.deleteDirectoryContents(outFolder);\n        }else {\n            FileUtils.mkdirs(outFolder);\n        }\n        AndroidLibrary awbAndroidLibrary = awbBundle.getAndroidLibrary();\n        File awbDataBindingDir = new File(awbAndroidLibrary.getFolder(), \"data-binding\");\n        File awbArtifactFolder = new File(awbDataBindingDir,\n                DataBindingBuilder.INCREMENTAL_BIN_AAR_DIR);\n        if (awbArtifactFolder.exists()) {\n        //noinspection ConstantConditions\n        for (String artifactName : awbArtifactFolder.list()) {\n            if (isResource(artifactName)) {\n                FileUtils.copyFile(new File(awbArtifactFolder, artifactName),\n                        new File(outFolder, artifactName));\n            }\n        }\n        }\n        extractBinFilesFromJar(outFolder, awbAndroidLibrary.getJarFile());\n\n        for (AndroidLibrary androidLibrary : awbBundle.getAllLibraryAars()) {\n            File dataBindingDir = new File(androidLibrary.getFolder(), \"data-binding\");\n            if (!dataBindingDir.exists()) {\n                continue;\n            }\n            File artifactFolder = new File(dataBindingDir,\n                                           DataBindingBuilder.INCREMENTAL_BIN_AAR_DIR);\n            if (!artifactFolder.exists()) {\n                continue;\n            }\n            //noinspection ConstantConditions\n            for (String artifactName : artifactFolder.list()) {\n                if (isResource(artifactName)) {\n                    FileUtils.copyFile(new File(artifactFolder, artifactName),\n                                       new File(outFolder, artifactName));\n                }\n            }\n        }\n\n        for (File jarFile : awbBundle.getLibraryJars()) {\n            extractBinFilesFromJar(outFolder, jarFile);\n        }\n\n        for (String fileName : outFolder.list()) {\n            if (fileName.endsWith(\"br.bin\") || fileName.endsWith(\"layout.bin\") || fileName.endsWith(\n                \"setter_store.bin\")) {\n                awbBundle.setDataBindEnabled(true);\n                break;\n            }\n        }\n    }\n\n    private static boolean isResource(String fileName) {\n        for (String ext : DataBindingBuilder.RESOURCE_FILE_EXTENSIONS) {\n            if (fileName.endsWith(ext)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private void extractBinFilesFromJar(File outFolder, File jarFile) throws IOException {\n        File jarOutFolder = getOutFolderForJarFile(outFolder, jarFile);\n        if (jarOutFolder.exists()) {\n            FileUtils.deleteDirectoryContents(jarOutFolder);\n        }else {\n            FileUtils.mkdirs(jarOutFolder);\n        }\n\n        try (Closer localCloser = Closer.create()) {\n            FileInputStream fis = localCloser.register(new FileInputStream(jarFile));\n            ZipInputStream zis = localCloser.register(new ZipInputStream(fis));\n            ZipEntry entry;\n            while ((entry = zis.getNextEntry()) != null) {\n                if (entry.isDirectory()) {\n                    continue;\n                }\n\n                String name = entry.getName();\n\n                if (!isResource(name)) {\n                    continue;\n                }\n                // get rid of the path. We don't need it since the file name includes the domain\n                name = new File(name).getName();\n                File out = new File(jarOutFolder, name);\n                //noinspection ResultOfMethodCallIgnored\n                FileOutputStream fos = localCloser.register(new FileOutputStream(out));\n                ByteStreams.copy(zis, fos);\n                zis.closeEntry();\n            }\n        }\n    }\n\n    @NonNull\n    private File getOutFolderForJarFile(File outFolder, File jarFile) {\n        return new File(outFolder, getJarFilePrefix(jarFile));\n    }\n\n    /**\n     * Files exported from jars are exported into a certain folder so that we can rebuild them\n     * when the related jar file changes.\n     */\n    @NonNull\n    private static String getJarFilePrefix(@NonNull File inputFile) {\n        // get the filename\n        String name = inputFile.getName();\n        // remove the extension\n        int pos = name.lastIndexOf('.');\n        if (pos != -1) {\n            name = name.substring(0, pos);\n        }\n\n        // add a hash of the original file path.\n        String input = inputFile.getAbsolutePath();\n        HashFunction hashFunction = Hashing.sha1();\n        HashCode hashCode = hashFunction.hashString(input, Charsets.UTF_16LE);\n\n        return name + \"-\" + hashCode.toString();\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<AwbDataBindingMergeArtifactsTask> {\n\n        private AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext, BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(taskName);\n        }\n\n        @Override\n        public Class<AwbDataBindingMergeArtifactsTask> getType() {\n            return AwbDataBindingMergeArtifactsTask.class;\n        }\n\n        @Override\n        public void execute(AwbDataBindingMergeArtifactsTask packageAwbsTask) {\n\n            super.execute(packageAwbsTask);\n\n            packageAwbsTask.androidConfig = appVariantContext.getAppExtension();\n            packageAwbsTask.appVariantContext = appVariantContext;\n            packageAwbsTask.appVariantOutputContext = getAppVariantOutputContext();\n            packageAwbsTask.config = scope.getVariantConfiguration();\n            packageAwbsTask.variantOutputData = baseVariantOutput;\n\n        }\n    }\n\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/databinding/AwbDataBindingProcessLayoutTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.databinding;\n\nimport android.databinding.tool.DataBindingBuilder;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.app.merge.bundle.AwbDataBindingProcessLayoutsTask;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tasks.manager.TaskCreater;\nimport com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.ExecutionException;\n\n/**\n * Created by wuzhong on 2017/3/27.\n */\npublic class AwbDataBindingProcessLayoutTask extends BaseTask {\n\n    AppVariantContext appVariantContext;\n\n\n    @TaskAction\n    public void run() throws ExecutionException, InterruptedException {\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n            getVariantName());\n\n        if (null == atlasDependencyTree) {\n            return;\n        }\n\n        DataBindingBuilder dataBindingBuilder = new DataBindingBuilder();\n        dataBindingBuilder.setPrintMachineReadableOutput(false);\n        dataBindingBuilder.setDebugLogEnabled(appVariantContext.getProject().getLogger().isDebugEnabled());\n\n        List<Runnable> tasks = new ArrayList<Runnable>();\n\n        for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n\n            if (!appVariantContext.getAtlasExtension().getTBuildConfig().getDataBindingBundles().contains(awbBundle.getPackageName()) || awbBundle.isMBundle){\n                continue;\n            }\n\n            tasks.add(() -> {\n\n                AwbDataBindingProcessLayoutsTask.AwbDataBindingProcessLayoutsConfigAction processLayoutsConfigAction =\n                    new AwbDataBindingProcessLayoutsTask.AwbDataBindingProcessLayoutsConfigAction(appVariantContext, awbBundle, dataBindingBuilder);\n                AwbDataBindingProcessLayoutsTask dataBindingProcessLayoutsTask = TaskCreater.create(\n                    appVariantContext.getProject(), processLayoutsConfigAction.getName(),\n                    processLayoutsConfigAction.getType());\n\n                processLayoutsConfigAction.execute(dataBindingProcessLayoutsTask);\n\n                dataBindingProcessLayoutsTask.execute();\n            });\n\n        }\n\n        ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper(\"dataBindingProcessLayoutTask\",\n                                                                                   getLogger(),\n                                                                                   0);\n\n        executorServicesHelper.execute(tasks);\n\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<AwbDataBindingProcessLayoutTask> {\n\n        private AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext, BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"dataBindingProcessLayout\", \"Awbs\");\n        }\n\n        @Override\n        public Class<AwbDataBindingProcessLayoutTask> getType() {\n            return AwbDataBindingProcessLayoutTask.class;\n        }\n\n        @Override\n        public void execute(AwbDataBindingProcessLayoutTask parallelTask) {\n\n            super.execute(parallelTask);\n\n            parallelTask.appVariantContext = appVariantContext;\n\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/databinding/AwbDataBindingRenameTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.databinding;\n\nimport java.io.File;\nimport java.io.FileFilter;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ExecutionException;\n\nimport com.android.build.gradle.AndroidConfig;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.ide.common.internal.WaitableExecutor;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.FileNameUtils;\nimport com.taobao.android.builder.tools.asm.ClassNameRenamer;\nimport com.taobao.android.builder.tools.asm.ClazzReplacer;\nimport com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.tasks.TaskAction;\n\npublic class AwbDataBindingRenameTask extends BaseTask {\n\n    static final String taskName = \"dataBindingRename\";\n\n    private AndroidConfig androidConfig;\n    private AppVariantContext appVariantContext;\n    private AppVariantOutputContext appVariantOutputContext;\n    private GradleVariantConfiguration config;\n\n    /**\n     * Directory of so\n     */\n    @TaskAction\n    void createAwbPackages() throws ExecutionException, InterruptedException {\n        WaitableExecutor workerExecutor = WaitableExecutor.useGlobalSharedThreadPool();\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(getVariantName());\n\n        if (null == atlasDependencyTree) {\n            return;\n        }\n\n        ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper(taskName, getLogger(), 0);\n\n        for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n\n            if (!appVariantContext.getAtlasExtension().getTBuildConfig().getDataBindingBundles().contains(awbBundle.getPackageName())){\n                continue;\n            }\n\n            if (!awbBundle.isDataBindEnabled()|| awbBundle.isMBundle) {\n                continue;\n            }\n            workerExecutor.execute(new Callable() {\n\n                @Override\n                public Object call() {\n\n                    try {\n\n                        File dataBindingClazzFolder = appVariantOutputContext.getVariantContext().getJAwbavaOutputDir(\n                            awbBundle);\n                        String packageName = awbBundle.getPackageName();\n                        String appName = awbBundle.getPackageName() + \"._bundleapp_\";\n\n                        //Remove classes that already exist\n                        File dataMapperClazz = new File(dataBindingClazzFolder,\n                                                        \"android/databinding/DataBinderMapper.class\");\n                        if (!dataMapperClazz.exists()) {\n                            throw new GradleException(\"missing datamapper class\");\n                        }\n                        File dataBindComponentClazz = new File(dataBindingClazzFolder,\n                                \"android/databinding/DataBindingComponent.class\");\n                        if (!dataBindComponentClazz.exists()) {\n                            throw new GradleException(\"missing dataBindComponent.class\");\n                        }\n                        File dataBindDynamicUtilsClazz = new File(dataBindingClazzFolder,\n                                \"android/databinding/DynamicUtil.class\");\n                        if (!dataBindDynamicUtilsClazz.exists()) {\n                            throw new GradleException(\"missing dataBindDynamicUtils.class\");\n                        }\n\n                        ClassNameRenamer.rewriteDataBinderMapper(dataBindingClazzFolder, \"android/databinding/DataBinderMapper\",\n                                packageName.replace(\".\", \"/\") +\n                                        \"/DataBinderMapper\", dataMapperClazz);\n                        ClassNameRenamer.rewriteDataBinderMapper(dataBindingClazzFolder, \"android/databinding/DataBindingComponent\",\n                                packageName.replace(\".\", \"/\") +\n                                        \"/DataBindingComponent\", dataBindComponentClazz);\n\n                        ClassNameRenamer.rewriteDataBinderMapper(dataBindingClazzFolder, \"android/databinding/dataBindDynamicUtils\",\n                                packageName.replace(\".\", \"/\") +\n                                        \"/dataBindDynamicUtils\", dataBindDynamicUtilsClazz);\n\n                        FileUtils.deleteDirectory(new File(dataBindingClazzFolder, \"android/databinding\"));\n\n\n                        //FileUtils.deleteDirectory(new File(dataBindingClazzFolder, packageName.replace(\".\", \"/\") +\n                        // \"/_bundleapp_\" ));\n\n                        File appDir = new File(dataBindingClazzFolder, appName.replace(\".\", \"/\"));\n                        if (appDir.exists()) {\n                            File[] files = appDir.listFiles(new FileFilter() {\n                                @Override\n                                public boolean accept(File pathname) {\n                                    return pathname.isFile() && !pathname.isDirectory();\n                                }\n                            });\n                            for (File tmp : files) {\n                                FileUtils.forceDelete(tmp);\n                            }\n                        }\n\n                        //rename DataBindUtils\n                        AwbTransform awbTransform = appVariantOutputContext.getAwbTransformMap().get(\n                            awbBundle.getName());\n\n                        List<File> files = awbTransform.getInputLibraries();\n\n                        Map<String, String> replaceMap = new HashMap<>();\n                        replaceMap.put(\"android/databinding/DataBindingUtil\",\n                                       \"android/databinding/AtlasDataBindingUtil\");\n\n                        List<File> newLibrarys = new ArrayList<>();\n\n                        for (File inputJar : files) {\n\n                            File outputJar = new File(appVariantContext.getAwbLibraryDirForDataBinding(awbBundle),\n                                                      FileNameUtils.getUniqueJarName(inputJar) + \".jar\");\n\n                            outputJar.delete();\n                            outputJar.getParentFile().mkdirs();\n                            outputJar.createNewFile();\n\n                            new ClazzReplacer(inputJar, outputJar, replaceMap).execute();\n                            newLibrarys.add(outputJar);\n                            awbTransform.getFileTransform().put(inputJar,outputJar);\n                        }\n\n                        awbTransform.setInputLibraries(newLibrarys);\n\n                    } catch (Throwable e) {\n                        e.printStackTrace();\n                        throw new GradleException(\"databinding awb failed\", e);\n                    }\n\n                    return null;\n                }\n            });\n\n        }\n        workerExecutor.waitForTasksWithQuickFail(true);\n\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<AwbDataBindingRenameTask> {\n\n        private AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext, BaseVariantOutput baseVariantOutput) {\n            super(appVariantContext, baseVariantOutput);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(taskName);\n        }\n\n        @Override\n        public Class<AwbDataBindingRenameTask> getType() {\n            return AwbDataBindingRenameTask.class;\n        }\n\n        @Override\n        public void execute(AwbDataBindingRenameTask packageAwbsTask) {\n\n            super.execute(packageAwbsTask);\n\n//            packageAwbsTask.androidConfig = appVariantContext.getAppExtension();\n            packageAwbsTask.appVariantContext = appVariantContext;\n            packageAwbsTask.appVariantOutputContext = getAppVariantOutputContext();\n//            packageAwbsTask.config = scope.getVariantConfiguration();\n//            packageAwbsTask.variantOutputData = (ApkVariantOutputData)scope.getVariantOutputData();\n\n        }\n    }\n    \n\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/databinding/AwbXmlProcessor.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.databinding;\n\nimport android.databinding.tool.DataBindingBuilder;\nimport android.databinding.tool.LayoutXmlProcessor;\n\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.ide.common.blame.MergingLog;\nimport com.android.ide.common.blame.SourceFile;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\n\nimport java.io.File;\n\n/**\n * Created by wuzhong on 2016/10/24.\n */\npublic class AwbXmlProcessor {\n\n    public static LayoutXmlProcessor getLayoutXmlProcessor(AppVariantContext appVariantContext,\n                                                           AwbBundle awbBundle,\n                                                           DataBindingBuilder dataBindingBuilder) {\n\n        File resourceBlameLogDir = appVariantContext.getAwbBlameLogFolder(awbBundle);\n\n        //        if (!resourceBlameLogDir.exists()) {\n        //            resourceBlameLogDir = appVariantContext.getScope().getResourceBlameLogDir();\n        //        }\n\n        final MergingLog mergingLog = new MergingLog(resourceBlameLogDir);\n        LayoutXmlProcessor layoutXmlProcessor = new LayoutXmlProcessor(\n\n                 awbBundle.getPackageName(),\n                //                ManifestFileUtils.getPackage(awbBundle.getOrgManifestFile()),\n\n                //                \"com.taobao.demo2\",\n                //appVariantContext.getVariantConfiguration().getOriginalApplicationId(),\n\n                dataBindingBuilder.createJavaFileWriter(appVariantContext.getAwbClassOutputForDataBinding(\n                        awbBundle)),\n\n                //                appVariantContext.getVariantData().getType() == VariantType.LIBRARY,\n                new LayoutXmlProcessor.OriginalFileLookup() {\n\n                    @Override\n                    public File getOriginalFileFor(File file) {\n                        SourceFile input = new SourceFile(file);\n                        SourceFile original = mergingLog.find(input);\n                        // merged log api returns the file back if original cannot be found.\n                        // it is not what we want so we alter the response.\n                        return original == input ? input.getSourceFile() : original.getSourceFile();\n                    }\n                });\n\n        return layoutXmlProcessor;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/manifest/PostProcessManifestAction.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.manifest;\n\nimport com.android.SdkConstants;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.dsl.BuildType;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.utils.FileUtils;\nimport com.google.common.collect.HashMultimap;\nimport com.google.common.collect.Maps;\nimport com.google.common.collect.Multimap;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.extension.MultiDexConfig;\nimport com.taobao.android.builder.tools.manifest.AtlasProxy;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport com.taobao.android.builder.tools.manifest.ManifestHelper;\nimport com.taobao.android.builder.tools.manifest.Result;\nimport org.dom4j.DocumentException;\nimport org.gradle.api.Action;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Task;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.CopyOption;\nimport java.nio.file.Files;\nimport java.nio.file.StandardCopyOption;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Created by wuzhong on 2017/4/13.\n */\npublic class PostProcessManifestAction implements Action<Task> {\n\n    private AppVariantContext appVariantContext;\n    private BaseVariantOutput baseVariantOutputData;\n\n    public PostProcessManifestAction(AppVariantContext appVariantContext, BaseVariantOutput baseVariantOutput) {\n        this.appVariantContext = appVariantContext;\n        this.baseVariantOutputData = baseVariantOutput;\n    }\n\n    @Override\n    public void execute(Task task) {\n\n        AtlasExtension atlasExtension = appVariantContext.getAtlasExtension();\n\n        File bundleBaseLineInfo = appVariantContext.getBundleBaseInfoFile();\n\n        VariantScope variantScope = appVariantContext.getScope();\n        GradleVariantConfiguration config = variantScope.getVariantConfiguration();\n        AtlasDependencyTree dependencyTree = AtlasBuildContext.androidDependencyTrees.get(config.getFullName());\n\n        File androidManifest = null;\n\n        File file = variantScope\n                .getInstantRunManifestOutputDirectory();\n        if (null != file && file.exists() && variantScope.getInstantRunBuildContext().isInInstantRunMode()) {\n\n            androidManifest = FileUtils.join(\n                    baseVariantOutputData.getProcessManifest().getInstantRunManifestOutputDirectory(),\n                    baseVariantOutputData.getDirName(),\n                    SdkConstants.ANDROID_MANIFEST_XML);\n\n        } else {\n            androidManifest = FileUtils.join(\n                    baseVariantOutputData.getProcessManifest().getManifestOutputDirectory(),\n                    baseVariantOutputData.getDirName(),\n                    SdkConstants.ANDROID_MANIFEST_XML);\n        }\n        try {\n\n            Result result = ManifestFileUtils.postProcessManifests(androidManifest,\n                    getLibManifestMap(),\n                    getLibManifestDepenendyMap(),\n                    bundleBaseLineInfo,\n                    atlasExtension.manifestOptions,\n                    isMultiDexEnabled(),\n                    variantScope.getInstantRunBuildContext().isInInstantRunMode(),\n                    appVariantContext.getBuildType().isDebuggable(),\n                    atlasExtension.getTBuildConfig()\n                            .getOutOfApkBundles(), atlasExtension.getTBuildConfig().getInsideOfApkBundles(), atlasExtension.getTBuildConfig().isPushInstall());\n\n\n            File proxySrcDir = appVariantContext.getAtlasProxySourceDir();\n            if (AtlasProxy.genProxyJavaSource(proxySrcDir, result)) {\n//                appVariantContext.getVariantData().javacTask.source(proxySrcDir);\n            }\n\n            ManifestHelper.checkManifest(appVariantContext,\n                    androidManifest, dependencyTree,\n                    atlasExtension);\n        } catch (DocumentException e1) {\n            e1.printStackTrace();\n        } catch (IOException e1) {\n            e1.printStackTrace();\n        }\n\n\n//                ManifestFileUtils.postProcessManifests(\n//                        instantRunAndroidManifest,\n//                    getLibManifestMap(),\n//                    getLibManifestDepenendyMap(),\n//                    bundleBaseLineInfo,\n//                    atlasExtension.manifestOptions,\n//                    isMultiDexEnabled(),\n//                    true,\n//                        appVariantContext.getBuildType().isDebuggable(),\n//                        atlasExtension.getTBuildConfig()\n//                        .getOutOfApkBundles(),atlasExtension.getTBuildConfig().getInsideOfApkBundles(),atlasExtension.getTBuildConfig().isPushInstall());\n//            }\n\n        // manifest list check\n\n\n        //TODO??\n        //AtlasBuildContext.androidBuilderMap.get(appVariantContext.getProject()).generateKeepList(\n        //    baseVariantOutputData.manifestProcessorTask.getManifestOutputFile(),\n        //    appVariantContext.getScope()\n        //        .getManifestKeepListProguardFile());\n\n\n    }\n\n    private List<? extends AndroidLibrary> getAwbLibraries() {\n        return ManifestHelper.getManifestDependencies(\n                AtlasBuildContext.androidDependencyTrees\n                        .get(appVariantContext.getScope().getVariantConfiguration().getFullName()).getAwbBundles(),\n                appVariantContext.getAtlasExtension().manifestOptions.getNotMergedBundles(),\n                appVariantContext.getProject().getLogger());\n    }\n\n    private boolean isMultiDexEnabled() {\n        boolean isMultiDex = false;\n        for (BuildType buildType : appVariantContext.getAppExtension().getBuildTypes()) {\n            if (buildType.getName().equals(baseVariantOutputData.getName())) {\n                isMultiDex = (null !=\n                        buildType.getMultiDexEnabled()) ? buildType.getMultiDexEnabled() : false;\n                break;\n            }\n        }\n\n        MultiDexConfig multiDexConfig = (MultiDexConfig) appVariantContext.getAtlasExtension().getMultiDexConfigs().findByName(appVariantContext.getBuildType().getName());\n        boolean fastMultiDex = null != multiDexConfig && multiDexConfig.isFastMultiDex();\n\n        return isMultiDex || fastMultiDex;\n    }\n\n    private Map<String, File> getLibManifestMap() {\n        Map<String, File> maps = Maps.newHashMap();\n        List<? extends AndroidLibrary> libs = getAwbLibraries();\n        if (libs == null || libs.isEmpty()) {\n            return Collections.emptyMap();\n        }\n\n        for (AndroidLibrary mdi : libs) {\n            ((HashMap<String, File>) maps).put(mdi.getName(), mdi.getManifest());\n        }\n\n        return maps;\n    }\n\n    private Multimap<String, File> getLibManifestDepenendyMap() {\n        Multimap<String, File> maps = HashMultimap.create();\n        List<? extends AndroidLibrary> libs = getAwbLibraries();\n        if (libs == null || libs.isEmpty()) {\n            return maps;\n        }\n\n        for (AndroidLibrary mdi : libs) {\n            for (AndroidLibrary childLib : mdi.getLibraryDependencies()) {\n                ((HashMultimap<String, File>) maps).put(mdi.getName(), childLib.getManifest());\n            }\n        }\n\n        return maps;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/manifest/PreProcessManifestAction.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.manifest;\n\nimport com.android.build.gradle.api.ApkVariantOutput;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.scope.ConventionMappingHelper;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.tasks.ManifestProcessorTask;\nimport com.android.build.gradle.tasks.MergeManifests;\nimport com.android.builder.core.DefaultManifestParser;\nimport com.android.builder.core.DefaultProductFlavor;\nimport com.android.builder.model.ProductFlavor;\nimport com.android.manifmerger.ManifestProvider;\nimport com.google.common.base.Strings;\nimport com.google.common.collect.Sets;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.tools.manifest.ManifestHelper;\nimport org.gradle.api.Action;\nimport org.gradle.api.Task;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.concurrent.Callable;\n\n/**\n * Set the awb The bundle of depend on\n *\n * @author wuzhong\n */\npublic class PreProcessManifestAction implements Action<Task> {\n\n    private static final Logger sLogger = LoggerFactory.getLogger(PreProcessManifestAction.class);\n\n    private final AppVariantContext appVariantContext;\n\n    private final BaseVariantOutput baseVariantOutput;\n\n    public PreProcessManifestAction(AppVariantContext appVariantContext, BaseVariantOutput baseVariantOutput) {\n        this.appVariantContext = appVariantContext;\n        this.baseVariantOutput = baseVariantOutput;\n    }\n\n    @Override\n    public void execute(Task task) {\n\n        AtlasExtension atlasExtension = appVariantContext.getAtlasExtension();\n\n        ManifestProcessorTask manifestProcessorTask = baseVariantOutput.getProcessManifest();\n\n        Set<String> notMergedArtifacts = Sets.newHashSet();\n\n        if (null != atlasExtension.getManifestOptions() && null != atlasExtension.getManifestOptions()\n            .getNotMergedBundles()) {\n            notMergedArtifacts = atlasExtension.getManifestOptions().getNotMergedBundles();\n        }\n\n        if (manifestProcessorTask instanceof MergeManifests) {\n\n            MergeManifests mergeManifests = (MergeManifests)manifestProcessorTask;\n\n            VariantScope variantScope = appVariantContext.getScope();\n            GradleVariantConfiguration config = variantScope.getVariantConfiguration();\n            AtlasDependencyTree dependencyTree = AtlasBuildContext.androidDependencyTrees.get(config.getFullName());\n\n            List<ManifestProvider> bundleProviders = ManifestHelper.getBundleManifest(appVariantContext, dependencyTree,\n                                                                                      atlasExtension);\n\n            List<ManifestProvider> mainDexProviders = ManifestHelper.getMainDexManifest(appVariantContext, dependencyTree,\n                    atlasExtension);\n\n            List<ManifestProvider> allManifest = new ArrayList<>();\n            modifyForIncremental(mergeManifests, allManifest);\n//            allManifest.addAll(ManifestHelper.convert(mergeManifests.getProviders(), appVariantContext));\n            allManifest.addAll(bundleProviders);\n            allManifest.addAll(mainDexProviders);\n\n            AtlasBuildContext.androidBuilderMap.get(appVariantContext.getProject()).manifestProviders = allManifest;\n\n            mergeManifests.setAndroidBuilder(AtlasBuildContext.androidBuilderMap.get(appVariantContext.getProject()));\n            //if (sLogger.isInfoEnabled()) {\n            //    for (ManifestProvider manifestProvider : allManifest) {\n            //        sLogger.warn(\"[manifestLibs] \" + manifestProvider.getManifest().getAbsolutePath());\n            //    }\n            //}\n\n            // Without this step, each time getLibraries It's going to be recomputed from the mapping\n//            mergeManifests.(allManifest);\n        }\n    }\n\n    private void modifyForIncremental(MergeManifests mergeManifests, List<ManifestProvider> allManifest) {\n        if (appVariantContext.getAtlasExtension().getTBuildConfig().isIncremental()) {\n            File mainManifest = mergeManifests.getMainManifest();\n            File baseManifest = appVariantContext.apContext.getBaseModifyManifest();\n            // allManifest.add(new ManifestHelper.MainManifestProvider(mainManifest, \"main-manifest\"));\n            ConventionMappingHelper.map(mergeManifests, \"mainManifest\", new Callable<File>() {\n                @Override\n                public File call() throws Exception {\n                    return baseManifest;\n                }\n            });\n            if (baseVariantOutput instanceof ApkVariantOutput) {\n                // TODO Improve performance\n                ApkVariantOutput variantOutputData = (ApkVariantOutput)baseVariantOutput;\n                DefaultManifestParser manifestParser = new DefaultManifestParser(baseManifest);\n                String versionNameOverride = variantOutputData.getVersionNameOverride();\n                if (Strings.isNullOrEmpty(versionNameOverride)) {\n                    variantOutputData.setVersionNameOverride(manifestParser.getVersionName());\n                    GradleVariantConfiguration variantConfiguration = appVariantContext.getScope()\n                        .getVariantConfiguration();\n                    ProductFlavor mergedFlavor = variantConfiguration.getMergedFlavor();\n                    String versionName = mergedFlavor.getVersionName();\n                    if (versionName == null) {\n                        ((DefaultProductFlavor)mergedFlavor).setVersionName(manifestParser.getVersionName());\n                    }\n                }\n                int versionCodeOverride = variantOutputData.getVersionCodeOverride();\n                if (versionCodeOverride == -1) {\n                    variantOutputData.setVersionCodeOverride(manifestParser.getVersionCode());\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/manifest/StandardizeLibManifestTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.manifest;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.publishing.AndroidArtifacts;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.builder.model.AndroidLibrary;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport com.taobao.android.builder.tools.manifest.ManifestInfo;\nimport com.taobao.android.builder.tools.xml.XmlHelper;\nimport org.apache.commons.lang.StringUtils;\nimport org.dom4j.Attribute;\nimport org.dom4j.Document;\nimport org.dom4j.DocumentException;\nimport org.dom4j.Element;\nimport org.gradle.api.DefaultTask;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Task;\nimport org.gradle.api.artifacts.ArtifactCollection;\nimport org.gradle.api.file.FileCollection;\nimport org.gradle.api.specs.Spec;\nimport org.gradle.api.tasks.*;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * The task of preprocessing the manifest file\n * <p>\n * 1. Get rid of application information\n * 2. Get rid of use-sdk\n * 4. complemented className\n * <p>\n * Created by shenghua.nish on 2016-05-09 Faith in the afternoon.\n *\n * @author shenghua.nish, wuzhong\n */\npublic class StandardizeLibManifestTask extends DefaultTask {\n\n    @InputFile\n    File mainManifestFile;\n\n\n    ArtifactCollection libraryManifests;\n    @InputFiles\n    @PathSensitive(PathSensitivity.NAME_ONLY)\n    public FileCollection getCompileManifests() {\n\n        return libraryManifests.getArtifactFiles();\n    }\n\n\n    @OutputFiles\n    private Collection<File> getOutputFiles() {\n        return appVariantContext.manifestMap.values();\n    }\n\n    List<AndroidLibrary> androidLibraries;\n\n    AppVariantContext appVariantContext;\n\n    @TaskAction\n    public void preProcess() throws IOException, DocumentException, InterruptedException {\n\n        AtlasDependencyTree dependencyTree = AtlasBuildContext.androidDependencyTrees.get(appVariantContext.getVariantName());\n        androidLibraries = dependencyTree.getAllAndroidLibrarys();\n\n\n        ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper(\"StandardizeLibManifestTask\",\n                                                                                   getLogger(), 0);\n        List<Runnable> runnables = new ArrayList<>();\n\n        ManifestInfo mainManifestFileObject = getManifestFileObject(mainManifestFile);\n\n        appVariantContext.getModifyManifestDir().mkdirs();\n\n        for (AndroidLibrary androidLibrary : androidLibraries) {\n\n            File file = androidLibrary.getManifest();\n\n            if (!file.exists()) {\n                getLogger().error(androidLibrary.getResolvedCoordinates().toString() + \" not has manifest : \" + file\n                    .getAbsolutePath());\n                return;\n            }\n\n            runnables.add(new Runnable() {\n\n                @Override\n                public void run() {\n                    try {\n\n                        File modifyManifest = appVariantContext.getModifyManifest(androidLibrary);\n\n                        //getLogger().error(file.getAbsolutePath() + \" -> \" + modifyManifest\n                        //    .getAbsolutePath());\n\n                        ManifestFileUtils.updatePreProcessManifestFile(modifyManifest, file, mainManifestFileObject,\n                                                                       appVariantContext.getAtlasExtension().getTBuildConfig().isUpdateSdkVersion(), appVariantContext.getAtlasExtension()\n                                                                           .getTBuildConfig().isIncremental());\n\n                    } catch (Throwable e) {\n                        e.printStackTrace();\n                        throw new GradleException(\"preprocess manifest failed \" + file.getAbsolutePath(), e);\n                    }\n                }\n\n            });\n        }\n\n        executorServicesHelper.execute(runnables);\n\n    }\n\n    /**\n     * Get the contents of the mainifest file\n     *\n     * @param manifestFile\n     * @return\n     */\n    public static ManifestInfo getManifestFileObject(File manifestFile) throws DocumentException {\n\n        ManifestInfo manifestFileObject = new ManifestInfo();\n        manifestFileObject.setManifestFile(manifestFile);\n        if (manifestFile.exists()) {\n            Document document = XmlHelper.readXml(manifestFile);// Read the XML file\n            Element root = document.getRootElement();// Get the root node\n            for (Attribute attribute : root.attributes()) {\n                if (StringUtils.isNotBlank(attribute.getNamespacePrefix())) {\n                    manifestFileObject.addManifestProperty(attribute.getNamespacePrefix() + \":\" + attribute.getName(),\n                                                           attribute.getValue());\n                } else {\n                    manifestFileObject.addManifestProperty(attribute.getName(), attribute.getValue());\n                }\n            }\n            Element useSdkElement = root.element(\"uses-sdk\");\n            Element applicationElement = root.element(\"application\");\n            if (null != useSdkElement) {\n                for (Attribute attribute : useSdkElement.attributes()) {\n                    if (StringUtils.isNotBlank(attribute.getNamespacePrefix())) {\n                        manifestFileObject.addUseSdkProperty(attribute.getNamespacePrefix() + \":\" + attribute.getName(),\n                                                             attribute.getValue());\n                    } else {\n                        manifestFileObject.addUseSdkProperty(attribute.getName(), attribute.getValue());\n                    }\n                }\n            }\n            if (null != applicationElement) {\n                for (Attribute attribute : applicationElement.attributes()) {\n                    if (StringUtils.isNotBlank(attribute.getNamespacePrefix())) {\n                        manifestFileObject.addApplicationProperty(\n                            attribute.getNamespacePrefix() + \":\" + attribute.getName(), attribute.getValue());\n                    } else {\n                        manifestFileObject.addApplicationProperty(attribute.getName(), attribute.getValue());\n                    }\n                }\n            }\n        }\n        manifestFileObject.init();\n        return manifestFileObject;\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<StandardizeLibManifestTask> {\n\n        private final AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext variantContext, BaseVariantOutput baseVariantOutput) {\n            super(variantContext, baseVariantOutput);\n            this.appVariantContext = variantContext;\n        }\n\n        @Override\n        public String getName() {\n            return appVariantContext.getScope().getTaskName(\"standardize\", \"LibManifest\");\n        }\n\n        @Override\n        public Class<StandardizeLibManifestTask> getType() {\n            return StandardizeLibManifestTask.class;\n        }\n\n        @Override\n        public void execute(StandardizeLibManifestTask task) {\n            VariantScope variantScope = appVariantContext.getScope();\n            final GradleVariantConfiguration config = variantScope.getVariantConfiguration();\n\n            task.mainManifestFile = config.getMainManifest();\n            task.libraryManifests = variantScope.getArtifactCollection(AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH, AndroidArtifacts.ArtifactScope.ALL, AndroidArtifacts.ArtifactType.MANIFEST);\n            task.appVariantContext = appVariantContext;\n\n\n            baseVariantOutput.getProcessManifest().doFirst(\n                new PreProcessManifestAction(appVariantContext, baseVariantOutput));\n\n//            if (!appVariantContext.getAtlasExtension().getTBuildConfig().isIncremental()) {\n            baseVariantOutput.getProcessManifest().doLast(\n                    new PostProcessManifestAction(appVariantContext, baseVariantOutput));\n\n            File proxySrcDir = appVariantContext.getAtlasProxySourceDir();\n            appVariantContext.getVariantData().javacTask.source(proxySrcDir);\n\n        }\n\n\n//        }\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/merge/AppendMainArtifactsCollection.java",
    "content": "package com.taobao.android.builder.tasks.app.merge;\n\nimport com.android.build.gradle.internal.publishing.AndroidArtifacts;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport org.apache.commons.io.FileUtils;\nimport org.dom4j.Document;\nimport org.dom4j.DocumentException;\nimport org.dom4j.io.SAXReader;\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.ArtifactCollection;\nimport org.gradle.api.artifacts.component.ComponentArtifactIdentifier;\nimport org.gradle.api.artifacts.result.ResolvedArtifactResult;\nimport org.gradle.api.file.FileCollection;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.function.Consumer;\n\n/**\n * AppendMainArtifactsCollection\n *\n * @author zhayu.ll\n * @date 18/6/12\n */\npublic class AppendMainArtifactsCollection implements ArtifactCollection {\n\n    private ArtifactCollection artifactResults;\n\n    private FileCollection filesResults;\n\n\n\n    private Set<ResolvedArtifactResult> allResults = new HashSet<>();\n\n    public static Map<String,String> bundle2Map = new HashMap<>();\n\n    private FileCollection allFiles = null;\n\n\n    private AwbBundle awbBundle;\n    private Project project;\n\n    private AndroidArtifacts.ArtifactType artifactType;\n\n    public AppendMainArtifactsCollection(Project project, ArtifactCollection artifactResults, AwbBundle awbBundle, AndroidArtifacts.ArtifactType artifactType) {\n        this.artifactResults = artifactResults;\n        this.awbBundle = awbBundle;\n        this.project = project;\n        this.artifactType = artifactType;\n    }\n\n    public AppendMainArtifactsCollection(Project project, FileCollection filesResults, AwbBundle awbBundle, AndroidArtifacts.ArtifactType artifactType) {\n        this.filesResults = filesResults;\n        this.awbBundle = awbBundle;\n        this.project = project;\n        this.artifactType = artifactType;\n    }\n\n    @Override\n    public FileCollection getArtifactFiles() {\n        if (allFiles != null) {\n            return allFiles;\n        }\n        FileCollection files = null;\n        if (artifactResults!= null) {\n            files = artifactResults.getArtifactFiles();\n        }else {\n            files = filesResults;\n        }\n        Set<File> fileSet = new HashSet<>();\n\n        switch (artifactType) {\n            case ANDROID_RES:\n                for (ResolvedArtifactResult resolvedArtifactResult : awbBundle.getResolvedResArtifactResults()) {\n                    fileSet.add(correctFile(resolvedArtifactResult.getFile()));\n                }\n                allFiles = files.plus(project.files(fileSet));\n                return allFiles;\n            case ASSETS:\n                for (ResolvedArtifactResult resolvedArtifactResult : awbBundle.getResolvedAssetsArtifactResults()) {\n                    fileSet.add(resolvedArtifactResult.getFile());\n                }\n                allFiles = files.plus(project.files(fileSet));\n                return allFiles;\n            case SYMBOL_LIST_WITH_PACKAGE_NAME:\n                for (ResolvedArtifactResult resolvedArtifactResult : awbBundle.getResolvedSymbolListWithPackageNameArtifactResults()) {\n                    fileSet.add(resolvedArtifactResult.getFile());\n                }\n                allFiles = files.plus(project.files(fileSet));\n                return allFiles;\n\n        }\n\n        return null;\n    }\n\n    @Override\n    public Set<ResolvedArtifactResult> getArtifacts() {\n        if (allResults.size() == 0) {\n            allResults.addAll(artifactResults.getArtifacts());\n\n            switch (artifactType) {\n                case ASSETS:\n                    allResults.addAll(awbBundle.getResolvedAssetsArtifactResults());\n                    break;\n\n                case ANDROID_RES:\n                    allResults.addAll(awbBundle.getResolvedResArtifactResults());\n                    break;\n\n                case SYMBOL_LIST_WITH_PACKAGE_NAME:\n                    allResults.addAll(awbBundle.getResolvedSymbolListWithPackageNameArtifactResults());\n\n            }\n\n        }\n        return allResults;\n    }\n\n    @Override\n    public Collection<Throwable> getFailures() {\n        return null;\n    }\n\n    @NotNull\n    @Override\n    public Iterator<ResolvedArtifactResult> iterator() {\n        if (allResults.size() == 0) {\n            getArtifacts();\n        }\n        return allResults.iterator();\n    }\n\n    private File correctFile(File file) {\n            Collection<File> files = FileUtils.listFiles(file, new String[]{\"xml\"}, true);\n            files.parallelStream().forEach(file1 -> {\n                List<String> lines = null;\n                try {\n                    lines = FileUtils.readLines(file1);\n                    lines.forEach(new Consumer<String>() {\n                        @Override\n                        public void accept(String s) {\n                            if (s.contains(\"http://schemas.android.com/apk/res/\" + awbBundle.getPackageName())){\n                                bundle2Map.put(file1.getName(),awbBundle.getPackageName());\n                            }\n//                            String s1 = s.replace(\"http://schemas.android.com/apk/res/\" + awbBundle.getPackageName(), \"http://schemas.android.com/apk/res-auto\");\n//                            newLines.add(s1);\n                        }\n                    });\n//                    FileUtils.writeLines(file1, newLines);\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n            });\n        return file;\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/merge/MainArtifactsCollection.java",
    "content": "package com.taobao.android.builder.tasks.app.merge;\n\nimport com.taobao.android.builder.AtlasBuildContext;\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.ArtifactCollection;\nimport org.gradle.api.artifacts.result.ResolvedArtifactResult;\nimport org.gradle.api.file.FileCollection;\n\nimport java.io.File;\nimport java.util.*;\nimport java.util.function.Consumer;\n\n/**\n * @author lilong\n * @create 2017-12-06 下午11:02\n */\n\npublic class MainArtifactsCollection implements ArtifactCollection {\n\n    private Set<ResolvedArtifactResult>fullArtifacts = new HashSet<>();\n    private Project project;\n    private String variantName;\n\n    Set<ResolvedArtifactResult>mainDexs;\n\n    public MainArtifactsCollection(ArtifactCollection fullArtifacts, Project project,String variantName) {\n        this.fullArtifacts = fullArtifacts.getArtifacts();\n        this.project = project;\n        this.variantName = variantName;\n    }\n\n    @Override\n    public FileCollection getArtifactFiles() {\n        Set<File> mainDexFiles = new HashSet<>();\n        if (mainDexs != null){\n            for (ResolvedArtifactResult resolvedArtifactResult:mainDexs){\n                mainDexFiles.add(resolvedArtifactResult.getFile());\n            }\n        }else {\n            getArtifacts();\n            getArtifactFiles();\n        }\n\n        return project.files(mainDexFiles);\n    }\n\n    @Override\n    public Set<ResolvedArtifactResult> getArtifacts() {\n            mainDexs = new HashSet<>();\n        for (ResolvedArtifactResult resolvedArtifactResult:fullArtifacts){\n            String name = resolvedArtifactResult.getFile().getAbsolutePath();\n            if (AtlasBuildContext.atlasMainDexHelperMap.get(variantName).getMainManifestFiles().containsKey(name.substring(0,name.lastIndexOf(File.separatorChar)))){\n                mainDexs.add(resolvedArtifactResult);\n            }\n        }\n        return mainDexs;\n\n    }\n\n    @Override\n    public Collection<Throwable> getFailures() {\n        return null;\n    }\n\n    @Override\n    public Iterator<ResolvedArtifactResult> iterator() {\n        return getArtifacts().iterator();\n    }\n\n    @Override\n    public void forEach(Consumer<? super ResolvedArtifactResult> action) {\n        getArtifacts().forEach(action);\n    }\n\n    @Override\n    public Spliterator<ResolvedArtifactResult> spliterator() {\n        return getArtifacts().spliterator();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/merge/MainFilesCollection.java",
    "content": "package com.taobao.android.builder.tasks.app.merge;\n\nimport com.taobao.android.builder.AtlasBuildContext;\nimport groovy.lang.Closure;\nimport org.gradle.api.Project;\nimport org.gradle.api.file.FileCollection;\nimport org.gradle.api.file.FileTree;\nimport org.gradle.api.internal.file.AbstractFileCollection;\nimport org.gradle.api.specs.Spec;\nimport org.gradle.api.tasks.StopExecutionException;\nimport org.gradle.api.tasks.TaskDependency;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.io.File;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Set;\n\n/**\n * MainFilesCollection\n *\n * @author zhayu.ll\n * @date 18/3/1\n */\npublic class MainFilesCollection extends AbstractFileCollection{\n\n    private Set<File>mainJars = new HashSet<>();\n    private String name;\n\n    public MainFilesCollection(String name) {\n        this.name = name;\n    }\n\n\n    @Override\n    public String getDisplayName() {\n        return \"maindex-jars\";\n    }\n\n    @Override\n    public Set<File> getFiles() {\n        if (mainJars.size() > 0){\n            return mainJars;\n        }else {\n            mainJars.addAll(AtlasBuildContext.atlasMainDexHelperMap.get(name).getAllMainDexJars());\n        }\n        return mainJars;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/merge/MergeAssetAwbsConfigAction.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.merge;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.app.merge.bundle.MergeAwbAssets;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tasks.manager.MtlParallelTask;\nimport com.taobao.android.builder.tasks.manager.TaskCreater;\nimport org.gradle.api.DefaultTask;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n\npublic class MergeAssetAwbsConfigAction extends MtlBaseTaskAction<MtlParallelTask> {\n\n    private AppVariantContext appVariantContext;\n\n    public MergeAssetAwbsConfigAction(AppVariantContext appVariantContext, BaseVariantOutput baseVariantOutputData) {\n        super(appVariantContext, baseVariantOutputData);\n        this.appVariantContext = appVariantContext;\n    }\n\n    @Override\n    public String getName() {\n        return scope.getTaskName(\"mergeAsserts\", \"Awbs\");\n    }\n\n    @Override\n    public Class<MtlParallelTask> getType() {\n        return MtlParallelTask.class;\n    }\n\n    @Override\n    public void execute(MtlParallelTask parallelTask) {\n\n        super.execute(parallelTask);\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(parallelTask.getVariantName());\n\n        if (null == atlasDependencyTree) {\n            return;\n        }\n\n        List<DefaultTask> tasks = new ArrayList<DefaultTask>();\n\n        for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n            if (awbBundle.isMBundle){\n                continue;\n            }\n\n            MergeAwbAssets.MergeAwbAssetConfigAction mergeAwbAssetConfigAction = new MergeAwbAssets.MergeAwbAssetConfigAction(appVariantContext, baseVariantOutput, awbBundle);\n\n            MergeAwbAssets mergeTask = TaskCreater.create(appVariantContext.getProject(), mergeAwbAssetConfigAction.getName(), mergeAwbAssetConfigAction.getType());\n\n            mergeAwbAssetConfigAction.execute(mergeTask);\n\n            tasks.add(mergeTask);\n\n        }\n\n\n        parallelTask.parallelTask = tasks;\n        parallelTask.concurrent = false;\n        parallelTask.uniqueTaskName = getName();\n\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/merge/MergeAwbsJniFolder.java",
    "content": "package com.taobao.android.builder.tasks.app.merge;\n\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.app.merge.bundle.MergeAwbAssets;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tasks.manager.MtlParallelTask;\nimport com.taobao.android.builder.tasks.manager.TaskCreater;\nimport org.gradle.api.DefaultTask;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class MergeAwbsJniFolder extends MtlBaseTaskAction<MtlParallelTask> {\n    private AppVariantContext appVariantContext;\n\n    public MergeAwbsJniFolder(AppVariantContext appVariantContext, BaseVariantOutput baseVariantOutputData) {\n        super(appVariantContext, baseVariantOutputData);\n        this.appVariantContext = appVariantContext;\n    }\n\n    @Override\n    public String getName() {\n        return scope.getTaskName(\"mergeJniFolders\", \"Awbs\");\n    }\n\n    @Override\n    public Class<MtlParallelTask> getType() {\n        return MtlParallelTask.class;\n    }\n\n    @Override\n    public void execute(MtlParallelTask parallelTask) {\n\n        super.execute(parallelTask);\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(parallelTask.getVariantName());\n\n        if (null == atlasDependencyTree) {\n            return;\n        }\n\n        List<DefaultTask> tasks = new ArrayList<DefaultTask>();\n\n        for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n\n            MergeAwbAssets.MergeAwbJniLibFoldersConfigAction mergeAwbJniLibFoldersConfigAction = new MergeAwbAssets.MergeAwbJniLibFoldersConfigAction(appVariantContext, baseVariantOutput, awbBundle);\n\n            MergeAwbAssets mergeTask = TaskCreater.create(appVariantContext.getProject(), mergeAwbJniLibFoldersConfigAction.getName(), mergeAwbJniLibFoldersConfigAction.getType());\n\n            mergeAwbJniLibFoldersConfigAction.execute(mergeTask);\n\n            tasks.add(mergeTask);\n\n        }\n\n\n        parallelTask.parallelTask = tasks;\n        parallelTask.concurrent = false;\n        parallelTask.uniqueTaskName = getName();\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/merge/MergeManifestAwbsConfigAction.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.merge;\n\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.aapt.AaptGeneration;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.scope.TaskConfigAction;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.options.ProjectOptions;\nimport com.android.builder.core.AtlasBuilder;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.manager.AbstractBundleTask;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tasks.manager.MtlParallelTask;\nimport com.taobao.android.builder.tasks.manager.TaskCreater;\nimport com.taobao.android.builder.tools.VersionUtils;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.DefaultTask;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.tasks.Input;\nimport org.gradle.api.tasks.OutputFile;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class MergeManifestAwbsConfigAction extends MtlBaseTaskAction<MtlParallelTask> {\n\n    private final AppVariantContext appVariantContext;\n\n    private static final String MANIFEST_TEMPLATE = \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\"\n            + \"<manifest xmlns:android=\\\"http://schemas.android.com/apk/res/android\\\"\\n\"\n        + \"          package=\\\"${packageName}\\\"\\n\"\n        + \"          ${featureName}\\n\"\n            + \"    xmlns:tools=\\\"http://schemas.android.com/tools\\\"\\n\"\n            + \"          android:versionCode=\\\"${versionCode}\\\"\\n\"\n            + \"          android:versionName=\\\"${versionName}\\\">\\n\"\n        + \"    <uses-sdk android:minSdkVersion=\\\"${minSdkVersion}\\\" android:targetSdkVersion=\\\"${targetSdkVersion}\\\" />\\n\"\n            + \"    <application></application>\\n\"\n            + \"</manifest>\\n\";\n\n    public MergeManifestAwbsConfigAction(AppVariantContext appVariantContext,\n                                         BaseVariantOutput baseVariantOutputData) {\n        super(appVariantContext, baseVariantOutputData);\n        this.appVariantContext = appVariantContext;\n    }\n\n    @Override\n    public String getName() {\n        return scope.getTaskName(\"mergeManifest\", \"Awbs\");\n    }\n\n    @Override\n    public Class<MtlParallelTask> getType() {\n        return MtlParallelTask.class;\n    }\n\n    @Override\n    public void execute(MtlParallelTask parallelTask) {\n\n        super.execute(parallelTask);\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n            parallelTask.getVariantName());\n\n        if (null == atlasDependencyTree) {\n            return;\n        }\n\n        List<DefaultTask> tasks = new ArrayList<DefaultTask>();\n\n        AppVariantOutputContext appVariantOutputContext = getAppVariantOutputContext();\n\n        for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n\n            MergeAwbManifests.ConfigAction configAction = new MergeAwbManifests.ConfigAction(\n                appVariantOutputContext.getScope(),\n                awbBundle, appVariantOutputContext);\n            MergeAwbManifests mergeAwbManifests = TaskCreater.create(appVariantContext.getProject(),\n                                                                     configAction.getName(), configAction.getType());\n\n            configAction.execute(mergeAwbManifests);\n\n            tasks.add(mergeAwbManifests);\n\n        }\n\n        parallelTask.parallelTask = tasks;\n        parallelTask.uniqueTaskName = getName();\n\n    }\n\n    public static class MergeAwbManifests extends AbstractBundleTask {\n\n        @Input\n        protected String versionCode;\n\n        private AppVariantOutputContext appVariantOutputContext;\n\n        private AaptGeneration aaptGeneration;\n\n        @Override\n        protected void doFullTaskAction() {\n\n            AtlasBuilder atlasBuilder = AtlasBuildContext.androidBuilderMap.get(getProject());\n\n            String versionName = awbBundle.getResolvedCoordinates().getVersion();\n\n            try {\n                String packageName;\n                String featureName = \"\";\n\n                if (aaptGeneration == AaptGeneration.AAPT_V1) {\n                    packageName = awbBundle.getPackageName();\n                } else {\n                    packageName = appVariantOutputContext.getScope().getVariantConfiguration().getApplicationId();\n                    featureName = awbBundle.getPackageName();\n                    featureName = \"        featureSplit=\\\"\" + featureName + \"\\\"\\n\";\n                }\n\n                mergeManifestsForBunlde(getManifestOutputFile(), packageName, featureName, getBundleVersion(),\n                    versionCode,\n                    appVariantOutputContext.getScope().getVariantConfiguration().getMinSdkVersion().getApiString(),\n                    appVariantOutputContext.getScope().getVariantConfiguration().getTargetSdkVersion().getApiString());\n\n                appVariantOutputContext.getScope().getOutputScope().save(VariantScope.TaskOutputType.MERGED_MANIFESTS, getManifestOutputFile().getParentFile());\n\n            } catch (IOException e) {\n                throw new GradleException(e.getMessage(), e);\n            }\n\n        }\n\n        public void mergeManifestsForBunlde(File outputFile, String packageName, CharSequence featureName,\n                                            String versionName, String versionCode,\n                                            String minSdkVersion, String targetSdkVersion)\n                throws IOException {\n\n            String xml = MANIFEST_TEMPLATE.replace(\"${packageName}\", packageName).replace(\"${featureName}\", featureName)\n                .replace(\"${versionCode}\", versionCode)\n                .replace(\"${versionName}\", versionName)\n                .replace(\"${minSdkVersion}\", minSdkVersion)\n                .replace(\"${targetSdkVersion}\", targetSdkVersion);\n            ;\n\n            outputFile.getParentFile().mkdirs();\n            outputFile.delete();\n\n            FileUtils.write(outputFile, xml);\n\n        }\n\n        @OutputFile\n        protected File getManifestOutputFile() {\n            return awbBundle.getMergedManifest();\n        }\n\n        public static class ConfigAction implements TaskConfigAction<MergeAwbManifests> {\n\n            private final VariantScope scope;\n\n            private final AwbBundle awbBundle;\n\n            private final AppVariantOutputContext appVariantOutputContext;\n\n            public ConfigAction(VariantScope scope,\n                                AwbBundle awbBundle,\n                                AppVariantOutputContext appVariantOutputContext) {\n                this.scope = scope;\n                this.awbBundle = awbBundle;\n                this.appVariantOutputContext = appVariantOutputContext;\n            }\n\n            @NonNull\n            @Override\n            public String getName() {\n                return scope.getTaskName(\"process\", \"AwbManifest[\" + awbBundle.getName() + \"]\");\n            }\n\n            @NonNull\n            @Override\n            public Class<MergeAwbManifests> getType() {\n                return MergeAwbManifests.class;\n            }\n\n            @Override\n            public void execute(@NonNull MergeAwbManifests processManifestTask) {\n\n                String variantName = scope\n                    .getVariantConfiguration()\n                    .getFullName();\n\n                processManifestTask.setVariantName(variantName);\n\n                processManifestTask.awbBundle = awbBundle;\n\n                final ProjectOptions projectOptions = scope.getGlobalScope().getProjectOptions();\n\n                processManifestTask.aaptGeneration = AaptGeneration.fromProjectOptions(projectOptions);\n                processManifestTask.appVariantOutputContext = appVariantOutputContext;\n\n                processManifestTask.versionCode = String.valueOf(VersionUtils.getVersionCode(appVariantOutputContext));\n\n                File manifestOutFile = new File(scope.getGlobalScope().getIntermediatesDir(),\n                                                \"/awb-manifests/full/\" +\n                                                    variantName +\n                                                    \"/\" +\n                                                    awbBundle.getName() +\n                                                    \"/AndroidManifest.xml\");\n\n                awbBundle.setMergedManifest(manifestOutFile);\n\n            }\n\n        }\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/merge/MergeResAwbsConfigAction.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.merge;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.app.merge.bundle.MergeAwbResource;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tasks.manager.MtlParallelTask;\nimport com.taobao.android.builder.tasks.manager.TaskCreater;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.Action;\nimport org.gradle.api.DefaultTask;\nimport org.gradle.api.Task;\nimport org.gradle.api.specs.Spec;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class MergeResAwbsConfigAction extends MtlBaseTaskAction<MtlParallelTask> {\n\n    private AppVariantContext appVariantContext;\n\n    public MergeResAwbsConfigAction(AppVariantContext appVariantContext,\n                                    BaseVariantOutput baseVariantOutput) {\n        super(appVariantContext, baseVariantOutput);\n        this.appVariantContext = appVariantContext;\n    }\n\n    @Override\n    public String getName() {\n        return scope.getTaskName(\"mergeRes\", \"Awbs\");\n    }\n\n    @Override\n    public Class<MtlParallelTask> getType() {\n        return MtlParallelTask.class;\n    }\n\n    @Override\n    public void execute(MtlParallelTask parallelTask) {\n\n        super.execute(parallelTask);\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n                parallelTask.getVariantName());\n\n        if (null == atlasDependencyTree) {\n            return;\n        }\n\n        List<DefaultTask> tasks = new ArrayList<DefaultTask>();\n\n        for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n            if (awbBundle.isMBundle){\n                continue;\n            }\n\n            MergeAwbResource.MergeAwbResourceConfigAction mergeAwbResourceConfigAction = new MergeAwbResource.MergeAwbResourceConfigAction(\n                    appVariantContext,\n                    baseVariantOutput,\n                    awbBundle);\n\n            final MergeAwbResource mergeTask = TaskCreater.create(appVariantContext.getProject(),\n                                                                mergeAwbResourceConfigAction.getName(),\n                                                                mergeAwbResourceConfigAction.getType());\n//            mergeTask.getOutputs().cacheIf(new Spec<Task>() {\n//                @Override\n//                public boolean isSatisfiedBy(Task element) {\n//                    return false;\n//                }\n//            });\n\n            mergeTask.setBlameLogFolder(appVariantContext.getAwbBlameLogFolder(awbBundle));\n\n            mergeAwbResourceConfigAction.execute(mergeTask);\n\n            tasks.add(mergeTask);\n\n            mergeTask.doLast(new Action<Task>() {\n                @Override\n                public void execute(Task task) {\n                    File publicRes = new File(awbBundle.getAndroidLibrary().getResFolder(), \"values/public.xml\");\n                    if (publicRes.exists()) {\n                        try {\n                            FileUtils.copyFile(publicRes,\n                                               new File(mergeTask.getOutputDir(),\n                                                        \"values/public.xml\"));\n                        } catch (IOException e) {\n                            e.printStackTrace();\n                        }\n                    }\n                }\n            });\n        }\n\n        parallelTask.parallelTask = tasks;\n        parallelTask.uniqueTaskName = getName();\n        parallelTask.concurrent = true;\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/merge/MergeResV4Dir.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\npackage com.taobao.android.builder.tasks.app.merge;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.tasks.DefaultAndroidTask;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.File;\nimport java.io.IOException;\n\n@Deprecated\npublic class MergeResV4Dir extends DefaultAndroidTask {\n\n    private VariantScope variantScope;\n\n    private VariantContext variantContext;\n\n    @TaskAction\n    public void taskAction() throws IOException {\n\n        File resDir = variantScope.getFinalResourcesDir();\n\n        moveFiles(resDir);\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n                getVariantName());\n\n        if (null != atlasDependencyTree) {\n            for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n\n                File awbResDir = variantContext.getMergeResources(awbBundle);\n\n                moveFiles(awbResDir);\n            }\n        }\n    }\n\n    private void moveFiles(File root) throws IOException {\n        if (null == root || !root.exists()) {\n            return;\n        }\n\n        File[] files = root.listFiles();\n        for (File tmp : files) {\n\n            if (tmp.isDirectory() &&\n                    tmp.getName().startsWith(\"drawable-\") &&\n                    tmp.getName().endsWith(\"dpi\")) {\n                File toDir = new File(root, tmp.getName() + \"-v4\");\n                toDir.mkdirs();\n\n                FileUtils.copyDirectory(tmp, toDir);\n                FileUtils.deleteDirectory(tmp);\n            }\n        }\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<MergeResV4Dir> {\n\n        private AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext,\n                            BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"merge\", \"ResV4Dir\");\n        }\n\n        @Override\n        public Class<MergeResV4Dir> getType() {\n            return MergeResV4Dir.class;\n        }\n\n        @Override\n        public void execute(MergeResV4Dir task) {\n            super.execute(task);\n\n            if (!appVariantContext.getAtlasExtension().getTBuildConfig().getResV4Enabled()) {\n                task.setEnabled(false);\n                return;\n            }\n\n            task.variantScope = appVariantContext.getScope();\n            task.variantContext = appVariantContext;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/merge/MergeSoLibTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.merge;\n\n/**\n * Created by wuzhong on 16/6/13.\n */\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.scope.ConventionMappingHelper;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.builder.model.AndroidLibrary;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Multimap;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.dependency.model.SoLibrary;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.solib.NativeSoUtils;\nimport com.taobao.android.builder.tools.zip.BetterZip;\nimport com.taobao.android.builder.tools.zip.ZipUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.tasks.Input;\nimport org.gradle.api.tasks.OutputDirectory;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.concurrent.Callable;\n\n/**\n * Handle various so dependent tasks\n * Created by shenghua.nish on 2015-08-25 So in the afternoon.\n */\npublic class MergeSoLibTask extends BaseTask {\n\n    /**\n     * The main bundle has jnifolders, which contain the jni directory of the main and dependent aar\n     */\n    Set<File> jniFolders;\n\n    /**\n     * Solib that the main bundle depends on\n     */\n    List<SoLibrary> mainDexSoLibraries;\n\n    /**\n     * Relying on the awbs\n     */\n    List<AwbBundle> awbLibs;\n\n    @Input\n    Set<String> supportAbis;\n\n    @Input\n    Set<String> removeSoFiles;\n\n    @OutputDirectory\n    File mainBundleOutputFolder;\n\n    /**\n     * Whether or not the main dex and awb's so are repeated\n     */\n    @Input\n    Boolean failOnDuplicateSo;\n\n    AppVariantOutputContext appVariantOutputContext;\n\n    /**\n     * Directory of so\n     */\n    @TaskAction\n    void generate() {\n        List<File> scanDirs = new ArrayList<File>();\n        //The master bundle's jnifolder directory\n        if (!getMainBundleOutputFolder().exists()) {\n            getMainBundleOutputFolder().mkdirs();\n        }\n\n        for (File jniFolder : getJniFolders()) {\n            if (jniFolder.exists() && jniFolder.isDirectory()) {\n                NativeSoUtils.copyLocalNativeLibraries(jniFolder,\n                                                       getMainBundleOutputFolder(),\n                                                       getSupportAbis(),\n                                                       getRemoveSoFiles());\n            }\n        }\n\n        scanDirs.add(getMainBundleOutputFolder());\n\n        //Solib so that increases the dependency of the main bundle\n        for (SoLibrary mainSoLib : getMainDexSoLibraries()) {\n            File explodeFolder = mainSoLib.getFolder();\n            if (explodeFolder.exists() && explodeFolder.isDirectory()) {\n                NativeSoUtils.copyLocalNativeLibraries(explodeFolder,\n                                                       getMainBundleOutputFolder(),\n                                                       getSupportAbis(),\n                                                       getRemoveSoFiles());\n            }\n        }\n\n        //To deal with the awb bundleThe so\n        for (AwbBundle awbLib : getAwbLibs()) {\n            File awbOutputFolder = new File(appVariantOutputContext.getAwbJniFolder(awbLib), \"lib\");\n            awbOutputFolder.mkdirs();\n            scanDirs.add(awbOutputFolder);\n            File awbJniFolder = awbLib.getAndroidLibrary().getJniFolder();\n            if (awbJniFolder.exists() && awbJniFolder.isDirectory()) {\n                NativeSoUtils.copyLocalNativeLibraries(awbJniFolder,\n                                                       awbOutputFolder,\n                                                       getSupportAbis(),\n                                                       getRemoveSoFiles());\n            }\n            //In order to be compatible with older aar, awb format\n            File libJniFolder = new File(awbLib.getAndroidLibrary().getFolder(), \"libs\");\n            if (libJniFolder.exists() && libJniFolder.isDirectory()) {\n                NativeSoUtils.copyLocalNativeLibraries(libJniFolder,\n                                                       awbOutputFolder,\n                                                       getSupportAbis(),\n                                                       getRemoveSoFiles());\n            }\n            List<? extends AndroidLibrary> deps = awbLib.getAndroidLibraries();\n            for (AndroidLibrary dep : deps) {\n                File depJniFolder = dep.getJniFolder();\n                if (depJniFolder.exists() && depJniFolder.isDirectory()) {\n                    NativeSoUtils.copyLocalNativeLibraries(depJniFolder,\n                                                           awbOutputFolder,\n                                                           getSupportAbis(),\n                                                           getRemoveSoFiles());\n                }\n                //In order to be compatible with older aar, awb format\n                File depLibsFolder = new File(dep.getFolder(), \"libs\");\n                if (depLibsFolder.exists() && depLibsFolder.isDirectory()) {\n                    NativeSoUtils.copyLocalNativeLibraries(depLibsFolder,\n                                                           awbOutputFolder,\n                                                           getSupportAbis(),\n                                                           getRemoveSoFiles());\n                }\n            }\n\n            List<SoLibrary> solibs = awbLib.getSoLibraries();\n            if (null != solibs) {\n                for (SoLibrary solib : solibs) {\n                    File explodeFolder = solib.getFolder();\n                    try {\n                        BetterZip.unzipDirectory(solib.getSoLibFile(),explodeFolder);\n                    } catch (IOException e) {\n                        e.printStackTrace();\n                    }\n                    if (explodeFolder.exists() && explodeFolder.isDirectory()) {\n                        NativeSoUtils.copyLocalNativeLibraries(explodeFolder,\n                                                               awbOutputFolder,\n                                                               getSupportAbis(),\n                                                               getRemoveSoFiles());\n                    }\n                }\n            }\n        }\n        //Determine whether there are duplicate so files\n        // Perform a query of duplicate files\n        Map<String, Multimap<String, File>> soMaps = NativeSoUtils.getAbiSoFiles(getSupportAbis(),\n                                                                                 getRemoveSoFiles(),\n                                                                                 scanDirs);\n        boolean hasDup = false;\n        for (Map.Entry<String, Multimap<String, File>> entry : soMaps.entrySet()) {\n            String abi = entry.getKey();\n            Multimap<String, File> soFiles = soMaps.get(abi);\n            for (String soKey : soFiles.keys()) {\n                if (soFiles.get(soKey).size() > 1) {\n                    getILogger().warning(\"[SO Duplicate][\" +\n                                                 abi +\n                                                 \"]:\" +\n                                                 StringUtils.join(soFiles.get(soKey), \",\"));\n                    hasDup = true;\n                } else {\n                    getILogger().verbose(\"[SO][\" +\n                                                 abi +\n                                                 \"]:\" +\n                                                 StringUtils.join(soFiles.get(soKey), \",\"));\n                }\n            }\n        }\n\n        //        if (hasDup && getFailOnDuplicateSo()) {\n        //            throw new RuntimeException(\"SO file has duplicate files!See detail info!\");\n        //        }\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<MergeSoLibTask> {\n\n        AtlasDependencyTree dependencyTree;\n\n        private AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext,\n                            BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n\n            this.appVariantContext = appVariantContext;\n            GradleVariantConfiguration config = scope.getVariantConfiguration();\n            dependencyTree = AtlasBuildContext.androidDependencyTrees.get(config.getFullName());\n        }\n\n        /**\n         * Return the name of the task to be configured.\n         */\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"merge\", \"SoLib\");\n        }\n\n        /**\n         * Return the class type of the task to be configured.\n         */\n        @Override\n        public Class<MergeSoLibTask> getType() {\n            return MergeSoLibTask.class;\n        }\n\n        /**\n         * Performs this action against the given object.\n         *\n         * @param copySoLibTask The object to perform the action on.\n         */\n        @Override\n        public void execute(MergeSoLibTask copySoLibTask) {\n\n            super.execute(copySoLibTask);\n\n            final AppVariantOutputContext appVariantOutputContext = getAppVariantOutputContext();\n\n            final GradleVariantConfiguration config = scope.getVariantConfiguration();\n\n            ConventionMappingHelper.map(copySoLibTask, \"jniFolders\", new Callable<Set<File>>() {\n                @Override\n                public Set call() throws Exception {\n                    Set<File> set = new HashSet<File>();\n                    for (AndroidLibrary aarBundle : dependencyTree.getMainBundle().getAndroidLibraries()) {\n                        if (!aarBundle.isOptional()) {\n                            File jniFolder = new File(aarBundle.getFolder(), \"libs\");\n                            if (jniFolder.isDirectory()) {\n                                set.add(jniFolder);\n                            }\n                        }\n                    }\n                    return set;\n                }\n            });\n\n            ConventionMappingHelper.map(copySoLibTask, \"awbLibs\", new Callable<List>() {\n                @Override\n                public List call() throws Exception {\n                    return dependencyTree.getAwbBundles();\n                }\n            });\n\n            ConventionMappingHelper.map(copySoLibTask, \"mainDexSoLibraries\", new Callable<List>() {\n                @Override\n                public List call() throws Exception {\n                    return dependencyTree.getMainBundle().getSoLibraries();\n                }\n            });\n\n            ConventionMappingHelper.map(copySoLibTask, \"supportAbis\", new Callable<Set>() {\n                @Override\n                public Set call() throws Exception {\n\n                    if (baseVariantOutput.getFilterTypes()!= null && baseVariantOutput.getFilterTypes().size()!= 0){\n                        return ImmutableSet.copyOf(baseVariantOutput.getFilterTypes());\n                    }\n                    Set<String> supportedAbis = config.getSupportedAbis();\n                    if (supportedAbis != null) {\n                        return supportedAbis;\n                    }\n\n                    return ImmutableSet.of();\n                }\n            });\n\n            ConventionMappingHelper.map(copySoLibTask, \"removeSoFiles\", new Callable<Set>() {\n                @Override\n                public Set call() throws Exception {\n                    return appVariantContext.getAtlasExtension()\n                            .getTBuildConfig()\n                            .getRemoveSoFiles();\n                }\n            });\n\n            //            File mainJniOutputFolder = new File(\n            //                    config.getGlobalScope().getBuildDir() , \"/\" + AndroidProject.FD_INTERMEDIATES + \"/jniFolder/\"\n            //                    + config.getVariantData().getVariantConfiguration().getDirName());\n\n            final File mainJniOutputFolder = appVariantContext.getBaseVariantData().ndkCompileTask.getSoFolder();\n            copySoLibTask.setMainBundleOutputFolder(mainJniOutputFolder);\n\n            copySoLibTask.appVariantOutputContext = appVariantOutputContext;\n            //            ConventionMappingHelper.map(processSolibTask, \"awbBundleOutputFolder\", new Callable<File>() {\n            //                @Override\n            //                public File call() throws Exception {\n            //                    return awbJniOutputFolder;\n            //                }\n            //            });\n            copySoLibTask.setVariantName(appVariantContext.getBaseVariantData().getName());\n        }\n    }\n\n    public Set<File> getJniFolders() {\n        return jniFolders;\n    }\n\n    public void setJniFolders(Set<File> jniFolders) {\n        this.jniFolders = jniFolders;\n    }\n\n    public List<SoLibrary> getMainDexSoLibraries() {\n        return mainDexSoLibraries;\n    }\n\n    public void setMainDexSoLibraries(List<SoLibrary> mainDexSoLibraries) {\n        this.mainDexSoLibraries = mainDexSoLibraries;\n    }\n\n    public List<AwbBundle> getAwbLibs() {\n        return awbLibs;\n    }\n\n    public void setAwbLibs(List<AwbBundle> awbLibs) {\n        this.awbLibs = awbLibs;\n    }\n\n    public Set<String> getSupportAbis() {\n        return supportAbis;\n    }\n\n    public void setSupportAbis(Set<String> supportAbis) {\n        this.supportAbis = supportAbis;\n    }\n\n    public File getMainBundleOutputFolder() {\n        return mainBundleOutputFolder;\n    }\n\n    public void setMainBundleOutputFolder(File mainBundleOutputFolder) {\n        this.mainBundleOutputFolder = mainBundleOutputFolder;\n    }\n\n    public Set<String> getRemoveSoFiles() {\n        return removeSoFiles;\n    }\n\n    public void setRemoveSoFiles(Set<String> removeSoFiles) {\n        this.removeSoFiles = removeSoFiles;\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/merge/bundle/AwbDataBindingProcessLayoutsTask.java",
    "content": "package com.taobao.android.builder.tasks.app.merge.bundle;\n\nimport android.databinding.tool.DataBindingBuilder;\nimport android.databinding.tool.LayoutXmlProcessor;\nimport android.databinding.tool.processing.Scope;\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.scope.TaskConfigAction;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.app.databinding.AwbXmlProcessor;\nimport org.gradle.api.Action;\nimport org.gradle.api.DefaultTask;\nimport org.gradle.api.tasks.InputDirectory;\nimport org.gradle.api.tasks.OutputDirectory;\nimport org.gradle.api.tasks.TaskAction;\nimport org.gradle.api.tasks.incremental.IncrementalTaskInputs;\nimport org.gradle.api.tasks.incremental.InputFileDetails;\nimport org.xml.sax.SAXException;\nimport javax.xml.bind.JAXBException;\n\nimport javax.xml.parsers.ParserConfigurationException;\nimport javax.xml.xpath.XPathExpressionException;\nimport java.io.File;\nimport java.io.IOException;\n\n/**\n * @author lilong\n * @create 2017-12-07 下午9:11\n */\n\npublic class AwbDataBindingProcessLayoutsTask extends DefaultTask {\n\n    private LayoutXmlProcessor xmlProcessor;\n\n    private File sdkDir;\n\n    private int minSdk;\n\n    private File layoutInputFolder;\n\n    private File layoutOutputFolder;\n\n    private File xmlInfoOutFolder;\n\n    @InputDirectory\n    public File getLayoutInputFolder() {\n        return layoutInputFolder;\n    }\n\n    public void setLayoutInputFolder(File layoutInputFolder) {\n        this.layoutInputFolder = layoutInputFolder;\n    }\n\n    @OutputDirectory\n    public File getLayoutOutputFolder() {\n        return layoutOutputFolder;\n    }\n\n    public void setLayoutOutputFolder(File layoutOutputFolder) {\n        this.layoutOutputFolder = layoutOutputFolder;\n    }\n\n    @OutputDirectory\n    public File getXmlInfoOutFolder() {\n        return xmlInfoOutFolder;\n    }\n\n    @TaskAction\n    public void processResources(IncrementalTaskInputs incrementalTaskInputs)\n            throws ParserConfigurationException, SAXException, XPathExpressionException,\n            IOException, JAXBException {\n        final LayoutXmlProcessor.ResourceInput resourceInput =\n                new LayoutXmlProcessor.ResourceInput(incrementalTaskInputs.isIncremental(),\n                        getLayoutInputFolder(), getLayoutOutputFolder());\n        if (incrementalTaskInputs.isIncremental()) {\n            incrementalTaskInputs.outOfDate(new Action<InputFileDetails>() {\n                @Override\n                public void execute(InputFileDetails inputFileDetails) {\n                    if (inputFileDetails.isAdded()) {\n                        resourceInput.added(inputFileDetails.getFile());\n                    } else if (inputFileDetails.isModified()) {\n                        resourceInput.changed(inputFileDetails.getFile());\n                    }\n                }\n            });\n            incrementalTaskInputs.removed(new Action<InputFileDetails>() {\n                @Override\n                public void execute(InputFileDetails inputFileDetails) {\n                    resourceInput.removed(inputFileDetails.getFile());\n                }\n            });\n        }\n        xmlProcessor.processResources(resourceInput);\n        Scope.assertNoError();\n        xmlProcessor.writeLayoutInfoFiles(getXmlInfoOutFolder());\n        Scope.assertNoError();\n    }\n\n    public void setXmlProcessor(LayoutXmlProcessor xmlProcessor) {\n        this.xmlProcessor = xmlProcessor;\n    }\n\n    public File getSdkDir() {\n        return sdkDir;\n    }\n\n    public void setSdkDir(File sdkDir) {\n        this.sdkDir = sdkDir;\n    }\n\n    public int getMinSdk() {\n        return minSdk;\n    }\n\n    public void setMinSdk(int minSdk) {\n        this.minSdk = minSdk;\n    }\n\n    public void setXmlInfoOutFolder(File xmlInfoOutFolder) {\n        this.xmlInfoOutFolder = xmlInfoOutFolder;\n    }\n\n    public static class AwbDataBindingProcessLayoutsConfigAction\n            implements TaskConfigAction<AwbDataBindingProcessLayoutsTask> {\n        private final AppVariantContext appVariantContext;\n        private final AwbBundle awbBundle;\n        private final DataBindingBuilder dataBindingBuilder;\n\n        public AwbDataBindingProcessLayoutsConfigAction(AppVariantContext appVariantContext, AwbBundle awbBundle,\n                                                        DataBindingBuilder dataBindingBuilder) {\n            this.appVariantContext = appVariantContext;\n            this.awbBundle = awbBundle;\n            this.dataBindingBuilder = dataBindingBuilder;\n        }\n\n        @Override\n        public String getName() {\n            return appVariantContext.getScope().getTaskName(\"dataBindingProcessLayouts[\" + awbBundle.getName() + \"]\");\n        }\n\n        @Override\n        public Class<AwbDataBindingProcessLayoutsTask> getType() {\n            return AwbDataBindingProcessLayoutsTask.class;\n        }\n\n        @Override\n        public void execute(AwbDataBindingProcessLayoutsTask task) {\n            VariantScope variantScope = appVariantContext.getScope();\n            task.setXmlProcessor(\n                    AwbXmlProcessor.getLayoutXmlProcessor(appVariantContext, awbBundle, dataBindingBuilder));\n            task.setSdkDir(variantScope.getGlobalScope().getSdkHandler().getSdkFolder());\n            task.setMinSdk(variantScope.getVariantConfiguration().getMinSdkVersion().getApiLevel());\n            task.setLayoutInputFolder(appVariantContext.getAwbMergeResourcesOutputDir(awbBundle));\n            task.setLayoutOutputFolder(appVariantContext.getAwbLayoutFolderOutputForDataBinding(awbBundle));\n            task.setXmlInfoOutFolder(appVariantContext.getAwbLayoutInfoOutputForDataBinding(awbBundle));\n\n        }\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/merge/bundle/MergeAwbAssets.java",
    "content": "package com.taobao.android.builder.tasks.app.merge.bundle;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.VisibleForTesting;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.android.build.gradle.internal.dsl.AaptOptions;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.tasks.IncrementalTask;\nimport com.android.build.gradle.internal.variant.BaseVariantData;\nimport com.android.build.gradle.tasks.MergeSourceSetFolders;\nimport com.android.build.gradle.tasks.ResourceException;\nimport com.android.build.gradle.tasks.WorkerExecutorAdapter;\nimport com.android.builder.core.VariantConfiguration;\nimport com.android.builder.core.VariantType;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.builder.model.SourceProvider;\nimport com.android.ide.common.res2.*;\nimport com.android.ide.common.workers.WorkerExecutorFacade;\nimport com.android.utils.FileUtils;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport org.gradle.api.Project;\nimport org.gradle.api.file.FileCollection;\nimport org.gradle.api.tasks.*;\nimport org.gradle.workers.WorkerExecutor;\n\nimport javax.inject.Inject;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.function.Supplier;\n\n/**\n * @author lilong\n * @create 2017-12-04 下午5:16\n */\n\npublic class MergeAwbAssets extends IncrementalTask{\n\n    // ----- PUBLIC TASK API -----\n\n    private File outputDir;\n    private AwbBundle awbBundle;\n\n    private AppVariantContext variantContext;\n\n    @OutputDirectory\n    public File getOutputDir() {\n        return outputDir;\n    }\n\n    public void setOutputDir(File outputDir) {\n        this.outputDir = outputDir;\n    }\n\n    // ----- PRIVATE TASK API -----\n\n    // file inputs as raw files, lazy behind a memoized/bypassed supplier\n    private Supplier<Collection<File>> sourceFolderInputs;\n\n    // supplier of the assets set, for execution only.\n    private Supplier<List<AssetSet>> assetSetSupplier;\n\n    // for the dependencies\n    private List<AndroidLibrary> libraries = null;\n\n    private FileCollection shadersOutputDir = null;\n    private FileCollection copyApk = null;\n    private String ignoreAssets = null;\n\n    private final FileValidity<AssetSet> fileValidity = new FileValidity<>();\n\n    private final WorkerExecutorFacade<MergedAssetWriter.AssetWorkParameters> workerExecutor;\n\n    @Inject\n    public MergeAwbAssets(WorkerExecutor workerExecutor) {\n        this.workerExecutor = new WorkerExecutorAdapter<>(workerExecutor, MergeSourceSetFolders.AssetWorkAction.class);\n    }\n\n    @Override\n    @Internal\n    protected boolean isIncremental() {\n        return true;\n    }\n\n    @Override\n    protected void doFullTaskAction() throws IOException {\n        if (awbBundle.isMBundle){\n            return;\n        }\n        // this is full run, clean the previous output\n        File destinationDir = getOutputDir();\n        FileUtils.cleanOutputDir(destinationDir);\n\n        List<AssetSet> assetSets = computeAssetSetList();\n\n        // create a new merger and populate it with the sets.\n        AssetMerger merger = new AssetMerger();\n\n        try {\n            for (AssetSet assetSet : assetSets) {\n                // set needs to be loaded.\n                assetSet.loadFromFiles(getILogger());\n                merger.addDataSet(assetSet);\n            }\n\n            // get the merged set and write it down.\n            MergedAssetWriter writer = new MergedAssetWriter(destinationDir, workerExecutor);\n\n            merger.mergeData(writer, false /*doCleanUp*/);\n\n            // No exception? Write the known state.\n            merger.writeBlobTo(getIncrementalFolder(), writer, false);\n        } catch (MergingException e) {\n            getLogger().error(\"Could not merge source set folders: \", e);\n            merger.cleanBlob(getIncrementalFolder());\n            throw new ResourceException(e.getMessage(), e);\n        }\n//        if (awbBundle.mBundle){\n//            org.apache.commons.io.FileUtils.moveDirectoryToDirectory(destinationDir,variantContext.getVariantData().mergeAssetsTask.getOutputDir(),true);\n//        }\n    }\n\n    @Override\n    protected void doIncrementalTaskAction(Map<File, FileStatus> changedInputs) throws IOException {\n        // create a merger and load the known state.\n        AssetMerger merger = new AssetMerger();\n        try {\n            if (!merger.loadFromBlob(getIncrementalFolder(), true /*incrementalState*/)) {\n                doFullTaskAction();\n                return;\n            }\n\n            // compare the known state to the current sets to detect incompatibility.\n            // This is in case there's a change that's too hard to do incrementally. In this case\n            // we'll simply revert to full build.\n            List<AssetSet> assetSets = computeAssetSetList();\n\n            if (!merger.checkValidUpdate(assetSets)) {\n                getLogger().info(\"Changed Asset sets: full task run!\");\n                doFullTaskAction();\n                return;\n\n            }\n\n            // The incremental process is the following:\n            // Loop on all the changed files, find which ResourceSet it belongs to, then ask\n            // the resource set to update itself with the new file.\n            for (Map.Entry<File, FileStatus> entry : changedInputs.entrySet()) {\n                File changedFile = entry.getKey();\n\n                // Ignore directories.\n                if (changedFile.isDirectory()) {\n                    continue;\n                }\n\n                merger.findDataSetContaining(changedFile, fileValidity);\n                if (fileValidity.getStatus() == FileValidity.FileStatus.UNKNOWN_FILE) {\n                    doFullTaskAction();\n                    return;\n\n                } else if (fileValidity.getStatus() == FileValidity.FileStatus.VALID_FILE) {\n                    if (!fileValidity.getDataSet().updateWith(\n                            fileValidity.getSourceFile(),\n                            changedFile,\n                            entry.getValue(),\n                            getILogger())) {\n                        getLogger().info(\n                                \"Failed to process {} event! Full task run\", entry.getValue());\n                        doFullTaskAction();\n                        return;\n                    }\n                }\n            }\n\n            MergedAssetWriter writer = new MergedAssetWriter(getOutputDir(), workerExecutor);\n\n            merger.mergeData(writer, false /*doCleanUp*/);\n\n            // No exception? Write the known state.\n            merger.writeBlobTo(getIncrementalFolder(), writer, false);\n        } catch (MergingException e) {\n            getLogger().error(\"Could not merge source set folders: \", e);\n            merger.cleanBlob(getIncrementalFolder());\n            throw new ResourceException(e.getMessage(), e);\n        } finally {\n            // some clean up after the task to help multi variant/module builds.\n            fileValidity.clear();\n        }\n    }\n\n    public static class AssetWorkAction implements Runnable {\n\n        private final MergedAssetWriter.AssetWorkAction workAction;\n\n        @Inject\n        public AssetWorkAction(MergedAssetWriter.AssetWorkParameters workItem) {\n            workAction = new MergedAssetWriter.AssetWorkAction(workItem);\n        }\n\n        @Override\n        public void run() {\n            workAction.run();\n        }\n    }\n\n    @Optional\n    @InputFiles\n    @PathSensitive(PathSensitivity.RELATIVE)\n    public FileCollection getLibraries() {\n        List<File>files = new ArrayList<>();\n        if (libraries != null) {\n            for (AndroidLibrary androidLibrary:libraries){\n                files.add(androidLibrary.getAssetsFolder());\n            }\n        }\n        files.add(awbBundle.getAndroidLibrary().getAssetsFolder());\n        return getProject().files(files);\n    }\n\n    @VisibleForTesting\n    public void setLibraries(@NonNull List<AndroidLibrary> libraries) {\n        this.libraries = libraries;\n    }\n\n    @InputFiles\n    @Optional\n    @PathSensitive(PathSensitivity.RELATIVE)\n    public FileCollection getShadersOutputDir() {\n        return shadersOutputDir;\n    }\n\n    @VisibleForTesting\n    void setShadersOutputDir(FileCollection shadersOutputDir) {\n        this.shadersOutputDir = shadersOutputDir;\n    }\n\n    @InputFiles\n    @Optional\n    @PathSensitive(PathSensitivity.RELATIVE)\n    public FileCollection getCopyApk() {\n        return copyApk;\n    }\n\n    @VisibleForTesting\n    void setCopyApk(FileCollection copyApk) {\n        this.copyApk = copyApk;\n    }\n\n    @Input\n    @Optional\n    public String getIgnoreAssets() {\n        return ignoreAssets;\n    }\n\n    @VisibleForTesting\n    void setAssetSetSupplier(Supplier<List<AssetSet>> assetSetSupplier) {\n        this.assetSetSupplier = assetSetSupplier;\n    }\n\n    // input list for the source folder based asset folders.\n    @InputFiles\n    @PathSensitive(PathSensitivity.RELATIVE)\n    public Collection<File> getSourceFolderInputs() {\n        return sourceFolderInputs.get();\n    }\n\n    /**\n     * Compute the list of Asset set to be used during execution based all the inputs.\n     */\n    @VisibleForTesting\n    List<AssetSet> computeAssetSetList() {\n        List<AssetSet> assetSetList;\n        List<AssetSet> assetSets = assetSetSupplier.get();\n        if (copyApk == null\n                && shadersOutputDir == null\n                && ignoreAssets == null\n                && libraries == null) {\n            assetSetList = new ArrayList<>(assetSets);\n        } else {\n            int size = assetSets.size() + 3;\n            if (libraries != null) {\n                size += libraries.size();\n            }\n\n            assetSetList = Lists.newArrayListWithExpectedSize(size);\n\n            // get the dependency base assets sets.\n            // add at the beginning since the libraries are less important than the folder based\n            // asset sets.\n            if (libraries != null) {\n                // the order of the artifact is descending order, so we need to reverse it.\n                List<? extends AndroidLibrary> bundleDeps = awbBundle.getAndroidLibraries();\n                // the list of dependency must be reversed to use the right overlay order.\n                for (int n = bundleDeps.size() - 1; n >= 0; n--) {\n                    AndroidLibrary dependency = bundleDeps.get(n);\n\n                    File assetFolder = dependency.getAssetsFolder();\n                    if (assetFolder.isDirectory()) {\n                        AssetSet assetSet = new AssetSet(dependency.getName());\n                        assetSet.addSource(assetFolder);\n                        assetSetList.add(assetSet);\n                    }\n                }\n\n            }\n                File awbAssetFolder = awbBundle.getAndroidLibrary().getAssetsFolder();\n                if (awbAssetFolder.isDirectory()) {\n                    AssetSet awbAssetSet = new AssetSet(awbBundle.getAndroidLibrary().getFolder().getName());\n                    awbAssetSet.addSource(awbAssetFolder);\n                    assetSetList.add(awbAssetSet);\n                }\n\n\n\n            // add the generated folders to the first set of the folder-based sets.\n            List<File> generatedAssetFolders = Lists.newArrayList();\n\n            if (shadersOutputDir != null) {\n                generatedAssetFolders.addAll(shadersOutputDir.getFiles());\n            }\n\n            if (copyApk != null) {\n                generatedAssetFolders.addAll(copyApk.getFiles());\n            }\n\n//            // for awb no need to add main assets\n//            final AssetSet mainAssetSet = assetSets.get(0);\n//            assert mainAssetSet.getConfigName().equals(BuilderConstants.MAIN);\n//            mainAssetSet.addSources(generatedAssetFolders);\n\n            assetSetList.addAll(assetSets);\n        }\n\n        if (ignoreAssets != null) {\n            for (AssetSet set : assetSetList) {\n                set.setIgnoredPatterns(ignoreAssets);\n            }\n        }\n\n        return assetSetList;\n    }\n\n\n    public static class MergeAwbAssetConfigAction extends MtlBaseTaskAction<MergeAwbAssets> {\n        @NonNull\n        protected final VariantScope scope;\n\n        @NonNull protected final File outputDir;\n\n        private AwbBundle awbBundle;\n\n        public MergeAwbAssetConfigAction(VariantContext variantContext, BaseVariantOutput baseVariantOutput, AwbBundle awbBundle) {\n            super(variantContext, baseVariantOutput);\n            this.variantContext = variantContext;\n            this.scope = variantContext.getScope();\n            this.awbBundle = awbBundle;\n            this.outputDir = variantContext.getMergeAssets(awbBundle);\n        }\n\n        @Override\n        public String getName() {\n            return variantContext.getScope().getTaskName(\"merge\", \"Assets[\" + awbBundle.getName() + \"]\");\n        }\n\n        @NonNull\n        @Override\n        public Class<MergeAwbAssets> getType() {\n            return MergeAwbAssets.class;\n        }\n\n        @Override\n        public void execute(@NonNull MergeAwbAssets mergeAssetsTask) {\n            BaseVariantData variantData = scope.getVariantData();\n            VariantConfiguration variantConfig = variantData.getVariantConfiguration();\n            mergeAssetsTask.setAndroidBuilder(scope.getGlobalScope().getAndroidBuilder());\n            mergeAssetsTask.setVariantName(variantConfig.getFullName());\n            mergeAssetsTask.setIncrementalFolder(scope.getIncrementalDir(getName()));\n            final Project project = scope.getGlobalScope().getProject();\n\n            final Function<SourceProvider, Collection<File>> assetDirFunction =\n                    SourceProvider::getAssetsDirectories;\n//            mergeAssetsTask.assetSetSupplier =\n//                    () -> variantConfig.getSourceFilesAsAssetSets(assetDirFunction);\n\n            mergeAssetsTask.assetSetSupplier = ()-> ImmutableList.of();\n            mergeAssetsTask.sourceFolderInputs = () -> ImmutableList.of();\n//            mergeAssetsTask.sourceFolderInputs =\n//                    TaskInputHelper.bypassFileSupplier(\n//                            () -> variantConfig.getSourceFiles(assetDirFunction));\n\n            mergeAssetsTask.shadersOutputDir = project.files(variantContext.getAwbShadersOutputDir(awbBundle));\n            if (variantData.copyApkTask != null) {\n                mergeAssetsTask.copyApk = project.files(variantData.copyApkTask.getDestinationDir());\n            }\n\n            AaptOptions options = scope.getGlobalScope().getExtension().getAaptOptions();\n            if (options != null) {\n                mergeAssetsTask.ignoreAssets = options.getIgnoreAssets();\n            }\n\n            if (!variantConfig.getType().equals(VariantType.LIBRARY)) {\n                mergeAssetsTask.libraries = awbBundle.getAndroidLibraries();\n            }\n\n            mergeAssetsTask.awbBundle = awbBundle;\n            mergeAssetsTask.variantContext = (AppVariantContext) this.variantContext;\n            mergeAssetsTask.setOutputDir(outputDir);\n        }\n    }\n\n    public static class MergeAwbJniLibFoldersConfigAction extends MtlBaseTaskAction<MergeAwbAssets> {\n\n        private AwbBundle awbBundle;\n        public MergeAwbJniLibFoldersConfigAction(VariantContext variantContext, BaseVariantOutput baseVariantOutput, AwbBundle awbBundle) {\n            super(variantContext,baseVariantOutput);\n            this.awbBundle = awbBundle;\n        }\n\n        @NonNull\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"merge\", \"JniLibFolders[\"+awbBundle.getName()+\"]\");\n        }\n\n        @Override\n        public Class<MergeAwbAssets> getType() {\n            return MergeAwbAssets.class;\n        }\n\n        @Override\n        public void execute(@NonNull MergeAwbAssets mergeAssetsTask) {\n            BaseVariantData variantData = scope.getVariantData();\n            VariantConfiguration variantConfig = variantData.getVariantConfiguration();\n\n            mergeAssetsTask.setAndroidBuilder(scope.getGlobalScope().getAndroidBuilder());\n            mergeAssetsTask.setVariantName(variantConfig.getFullName());\n            mergeAssetsTask.setIncrementalFolder(scope.getIncrementalDir(getName()));\n//            final Project project = scope.getGlobalScope().getProject();\n//            final Function<SourceProvider, Collection<File>> assetDirFunction =\n//                    SourceProvider::getJniLibsDirectories;\n//            mergeAssetsTask.assetSetSupplier =\n//                    () -> variantConfig.getSourceFilesAsAssetSets(assetDirFunction);\n//            mergeAssetsTask.sourceFolderInputs =\n//                    TaskInputHelper.bypassFileSupplier(\n//                            () -> variantConfig.getSourceFiles(assetDirFunction));\n\n            mergeAssetsTask.assetSetSupplier = () -> ImmutableList.of();\n            mergeAssetsTask.sourceFolderInputs = ()-> ImmutableList.of();\n            mergeAssetsTask.awbBundle = awbBundle;\n            if (!variantConfig.getType().equals(VariantType.LIBRARY)) {\n                mergeAssetsTask.libraries = awbBundle.getAndroidLibraries();\n            }\n            mergeAssetsTask.setOutputDir(variantContext.getAwbMergeNativeLibsOutputDir(awbBundle));\n        }\n    }\n\n    public static class MergeAwbShaderSourceFoldersConfigAction extends MtlBaseTaskAction<MergeAwbAssets> {\n\n        private AwbBundle awbBundle;\n\n        public MergeAwbShaderSourceFoldersConfigAction(VariantContext variantContext, BaseVariantOutput baseVariantOutput, AwbBundle awbBundle) {\n            super(variantContext,baseVariantOutput);\n            this.awbBundle = awbBundle;\n        }\n\n        @NonNull\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"merge\", \"Shaders[\"+awbBundle.getName()+\"]\");\n        }\n\n        @Override\n        public Class getType() {\n            return MergeAwbAssets.class;\n        }\n\n        @Override\n        public void execute(@NonNull MergeAwbAssets mergeAssetsTask) {\n            BaseVariantData variantData = scope.getVariantData();\n            VariantConfiguration variantConfig = variantData.getVariantConfiguration();\n\n            mergeAssetsTask.setAndroidBuilder(scope.getGlobalScope().getAndroidBuilder());\n            mergeAssetsTask.setVariantName(variantConfig.getFullName());\n            mergeAssetsTask.setIncrementalFolder(scope.getIncrementalDir(getName()));\n            final Project project = scope.getGlobalScope().getProject();\n\n            final Function<SourceProvider, Collection<File>> assetDirFunction =\n                    SourceProvider::getShadersDirectories;\n//            mergeAssetsTask.assetSetSupplier =\n//                    () -> variantConfig.getSourceFilesAsAssetSets(assetDirFunction);\n//            mergeAssetsTask.sourceFolderInputs =\n//                    TaskInputHelper.bypassFileSupplier(\n//                            () -> variantConfig.getSourceFiles(assetDirFunction));\n            mergeAssetsTask.assetSetSupplier = () -> ImmutableList.of();\n            mergeAssetsTask.sourceFolderInputs = () -> ImmutableList.of();\n\n            mergeAssetsTask.awbBundle = awbBundle;\n            if (!variantConfig.getType().equals(VariantType.LIBRARY)) {\n                mergeAssetsTask.libraries = awbBundle.getAndroidLibraries();\n            }\n            mergeAssetsTask.setOutputDir(variantContext.getMergeShadersOutputDir(awbBundle));\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/merge/bundle/MergeAwbResource.java",
    "content": "package com.taobao.android.builder.tasks.app.merge.bundle;\n\nimport android.databinding.tool.LayoutXmlProcessor;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.CombinedInput;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.aapt.AaptGeneration;\nimport com.android.build.gradle.internal.aapt.AaptGradleFactory;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.tasks.IncrementalTask;\nimport com.android.build.gradle.internal.tasks.TaskInputHelper;\nimport com.android.build.gradle.internal.variant.BaseVariantData;\nimport com.android.build.gradle.options.BooleanOption;\nimport com.android.build.gradle.tasks.MergeResources;\nimport com.android.build.gradle.tasks.ResourceException;\nimport com.android.build.gradle.tasks.WorkerExecutorAdapter;\nimport com.android.builder.core.AndroidBuilder;\nimport com.android.builder.internal.aapt.Aapt;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.builder.model.VectorDrawablesOptions;\nimport com.android.builder.png.VectorDrawableRenderer;\nimport com.android.builder.utils.FileCache;\nimport com.android.ide.common.blame.MergingLog;\nimport com.android.ide.common.blame.MergingLogRewriter;\nimport com.android.ide.common.blame.ParsingProcessOutputHandler;\nimport com.android.ide.common.blame.parser.ToolOutputParser;\nimport com.android.ide.common.blame.parser.aapt.Aapt2OutputParser;\nimport com.android.ide.common.blame.parser.aapt.AaptOutputParser;\nimport com.android.ide.common.process.LoggedProcessOutputHandler;\nimport com.android.ide.common.res2.*;\nimport com.android.ide.common.vectordrawable.ResourcesNotSupportedException;\nimport com.android.ide.common.workers.WorkerExecutorFacade;\nimport com.android.resources.Density;\nimport com.android.utils.FileUtils;\nimport com.android.utils.ILogger;\nimport com.google.common.annotations.VisibleForTesting;\nimport com.google.common.base.MoreObjects;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport org.gradle.api.Action;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Project;\nimport org.gradle.api.Task;\nimport org.gradle.api.file.FileCollection;\nimport org.gradle.api.tasks.*;\nimport org.gradle.api.tasks.Optional;\nimport org.gradle.workers.WorkerExecutor;\nimport org.jaxen.JaxenException;\n\nimport javax.inject.Inject;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.util.*;\nimport java.util.concurrent.ExecutionException;\nimport java.util.function.Supplier;\nimport java.util.stream.Collectors;\n\n/**\n * @author lilong\n * @create 2017-12-01 下午4:30\n */\n\n@CacheableTask\npublic class MergeAwbResource extends IncrementalTask {\n\n    private AwbBundle awbBundle;\n\n\n    public void setAwbBundle(AwbBundle awbBundle) {\n        this.awbBundle = awbBundle;\n    }\n\n    private File outputDir;\n\n\n    private SingleFileProcessor layoutXmlProcessor;\n    private File generatedPngsOutputDir;\n\n    // ----- PRIVATE TASK API -----\n\n    /**\n     * Optional file to write any publicly imported resource types and names to\n     */\n    private File publicFile;\n\n    private boolean processResources;\n\n    private boolean crunchPng;\n\n    private boolean validateEnabled;\n\n    private File blameLogFolder;\n\n    @Nullable\n    private FileCache fileCache;\n\n    // file inputs as raw files, lazy behind a memoized/bypassed supplier\n    private Supplier<Collection<File>> sourceFolderInputs;\n    private Supplier<List<ResourceSet>> resSetSupplier;\n\n    private List<ResourceSet> processedInputs;\n\n    private List<AndroidLibrary> libraries;\n\n    private FileCollection renderscriptResOutputDir;\n    private FileCollection generatedResOutputDir;\n    private FileCollection microApkResDirectory;\n    private FileCollection extraGeneratedResFolders;\n\n    private final FileValidity<ResourceSet> fileValidity = new FileValidity<>();\n\n    private boolean disableVectorDrawables;\n\n    private Collection<String> generatedDensities;\n\n    private int minSdk;\n\n    private VariantScope variantScope;\n\n    private AaptGeneration aaptGeneration;\n\n//    @Nullable private SingleFileProcessor dataBindingLayoutProcessor;\n\n    /** Where data binding exports its outputs after parsing layout files. */\n    @Nullable private File dataBindingLayoutInfoOutFolder;\n\n    @Nullable private File mergedNotCompiledResourcesOutputDirectory;\n\n    private boolean pseudoLocalesEnabled;\n\n    @NonNull\n    private static Aapt makeAapt(\n            @NonNull AaptGeneration aaptGeneration,\n            @NonNull AndroidBuilder builder,\n            @Nullable FileCache fileCache,\n            boolean crunchPng,\n            @NonNull VariantScope scope,\n            @NonNull File intermediateDir,\n            @Nullable MergingLog blameLog)\n            throws IOException {\n        return AaptGradleFactory.make(\n                aaptGeneration,\n                builder,\n                blameLog != null\n                        ? new ParsingProcessOutputHandler(\n                        new ToolOutputParser(\n                                aaptGeneration == AaptGeneration.AAPT_V1\n                                        ? new AaptOutputParser()\n                                        : new Aapt2OutputParser(),\n                                builder.getLogger()),\n                        new MergingLogRewriter(blameLog::find, builder.getErrorReporter()))\n                        : new LoggedProcessOutputHandler(\n                        new AaptGradleFactory.FilteringLogger(builder.getLogger())),\n                fileCache,\n                crunchPng,\n                intermediateDir,\n                scope.getGlobalScope().getExtension().getAaptOptions().getCruncherProcesses());\n    }\n\n    @Input\n    public String getBuildToolsVersion() {\n        return getBuildTools().getRevision().toString();\n    }\n\n    @Override\n    protected boolean isIncremental() {\n        return false;\n    }\n\n    @OutputDirectory\n    @Optional\n    public File getDataBindingLayoutInfoOutFolder() {\n        return dataBindingLayoutInfoOutFolder;\n    }\n\n    private final WorkerExecutorFacade<MergedResourceWriter.FileGenerationParameters>\n            workerExecutorFacade;\n\n    @Inject\n    public MergeAwbResource(WorkerExecutor workerExecutor) {\n        this.workerExecutorFacade =\n                new WorkerExecutorAdapter<>(workerExecutor, MergeAwbResource.FileGenerationWorkAction.class);\n    }\n\n    @Override\n    protected void doFullTaskAction() throws IOException, ExecutionException {\n        if (awbBundle.isMBundle){\n            return;\n        }\n        ResourcePreprocessor preprocessor = getPreprocessor();\n\n        // this is full run, clean the previous output\n        File destinationDir = getOutputDir();\n        FileUtils.cleanOutputDir(destinationDir);\n\n        List<ResourceSet> resourceSets = getConfiguredResourceSets(preprocessor);\n\n        // create a new merger and populate it with the sets.\n        ResourceMerger merger = new ResourceMerger(minSdk);\n        MergingLog mergingLog =\n                getBlameLogFolder() != null ? new MergingLog(getBlameLogFolder()) : null;\n\n        try (QueueableResourceCompiler resourceCompiler =\n                     processResources\n                             ? makeAapt(\n                             aaptGeneration,\n                             getBuilder(),\n                             fileCache,\n                             crunchPng,\n                             variantScope,\n                             getAaptTempDir(),\n                             mergingLog)\n                             : QueueableResourceCompiler.NONE) {\n\n            for (ResourceSet resourceSet : resourceSets) {\n                resourceSet.loadFromFiles(getILogger());\n                merger.addDataSet(resourceSet);\n            }\n\n            MergedResourceWriter writer =\n                    new MergedResourceWriter(\n                            workerExecutorFacade,\n                            destinationDir,\n                            getPublicFile(),\n                            mergingLog,\n                            preprocessor,\n                            resourceCompiler,\n                            getIncrementalFolder(),\n                            null,\n//                            layoutXmlProcessor,//dataBindingLayoutProcessor,\n                            mergedNotCompiledResourcesOutputDirectory,\n                            pseudoLocalesEnabled,\n                            getCrunchPng());\n\n            merger.mergeData(writer, false /*doCleanUp*/);\n\n            if (layoutXmlProcessor != null) {\n                try {\n                    layoutXmlProcessor.end();\n\n                }catch (Exception e){\n\n                }\n            }\n\n            // No exception? Write the known state.\n            merger.writeBlobTo(getIncrementalFolder(), writer, false);\n        } catch (MergingException e) {\n            System.out.println(e.getMessage());\n            merger.cleanBlob(getIncrementalFolder());\n            throw new ResourceException(e.getMessage(), e);\n        } finally {\n            cleanup();\n        }\n    }\n\n    @Override\n    protected void doIncrementalTaskAction(Map<File, FileStatus> changedInputs)\n            throws IOException, ExecutionException {\n        ResourcePreprocessor preprocessor = getPreprocessor();\n\n        // create a merger and load the known state.\n        ResourceMerger merger = new ResourceMerger(minSdk);\n        try {\n            if (!merger.loadFromBlob(getIncrementalFolder(), true /*incrementalState*/)) {\n                doFullTaskAction();\n                return;\n            }\n\n            for (ResourceSet resourceSet : merger.getDataSets()) {\n                resourceSet.setPreprocessor(preprocessor);\n            }\n\n            List<ResourceSet> resourceSets = getConfiguredResourceSets(preprocessor);\n\n            // compare the known state to the current sets to detect incompatibility.\n            // This is in case there's a change that's too hard to do incrementally. In this case\n            // we'll simply revert to full build.\n            if (!merger.checkValidUpdate(resourceSets)) {\n                getLogger().info(\"Changed Resource sets: full task run!\");\n                doFullTaskAction();\n                return;\n            }\n\n            // The incremental process is the following:\n            // Loop on all the changed files, find which ResourceSet it belongs to, then ask\n            // the resource set to update itself with the new file.\n            for (Map.Entry<File, FileStatus> entry : changedInputs.entrySet()) {\n                File changedFile = entry.getKey();\n\n                merger.findDataSetContaining(changedFile, fileValidity);\n                if (fileValidity.getStatus() == FileValidity.FileStatus.UNKNOWN_FILE) {\n                    doFullTaskAction();\n                    return;\n                } else if (fileValidity.getStatus() == FileValidity.FileStatus.VALID_FILE) {\n                    if (!fileValidity.getDataSet().updateWith(\n                            fileValidity.getSourceFile(), changedFile, entry.getValue(),\n                            getILogger())) {\n                        getLogger().info(\n                                String.format(\"Failed to process %s event! Full task run\",\n                                        entry.getValue()));\n                        doFullTaskAction();\n                        return;\n                    }\n                }\n            }\n\n            MergingLog mergingLog =\n                    getBlameLogFolder() != null ? new MergingLog(getBlameLogFolder()) : null;\n\n            try (QueueableResourceCompiler resourceCompiler =\n                         processResources\n                                 ? makeAapt(\n                                 aaptGeneration,\n                                 getBuilder(),\n                                 fileCache,\n                                 crunchPng,\n                                 variantScope,\n                                 getAaptTempDir(),\n                                 mergingLog)\n                                 : QueueableResourceCompiler.NONE) {\n\n                MergedResourceWriter writer =\n                        new MergedResourceWriter(\n                                workerExecutorFacade,\n                                getOutputDir(),\n                                getPublicFile(),\n                                mergingLog,\n                                preprocessor,\n                                resourceCompiler,\n                                getIncrementalFolder(),\n                                null,//dataBindingLayoutProcessor,\n                                mergedNotCompiledResourcesOutputDirectory,\n                                pseudoLocalesEnabled,\n                                getCrunchPng());\n\n                merger.mergeData(writer, false /*doCleanUp*/);\n\n//                if (dataBindingLayoutProcessor != null) {\n//                    dataBindingLayoutProcessor.end();\n//                }\n\n                // No exception? Write the known state.\n                merger.writeBlobTo(getIncrementalFolder(), writer, false);\n            }\n        } catch (MergingException e) {\n            merger.cleanBlob(getIncrementalFolder());\n            throw new ResourceException(e.getMessage(), e);\n        } finally {\n            cleanup();\n        }\n    }\n\n    public static class FileGenerationWorkAction implements Runnable {\n\n        private final MergedResourceWriter.FileGenerationWorkAction workAction;\n\n        @Inject\n        public FileGenerationWorkAction(MergedResourceWriter.FileGenerationParameters workItem) {\n            this.workAction = new MergedResourceWriter.FileGenerationWorkAction(workItem);\n        }\n\n        @Override\n        public void run() {\n            workAction.run();\n        }\n    }\n\n    private static class MergeResourcesVectorDrawableRenderer extends VectorDrawableRenderer {\n\n        public MergeResourcesVectorDrawableRenderer(\n                int minSdk,\n                File outputDir,\n                Collection<Density> densities,\n                Supplier<ILogger> loggerSupplier) {\n            super(minSdk, outputDir, densities, loggerSupplier);\n        }\n\n        @Override\n        public void generateFile(File toBeGenerated, File original) throws IOException {\n            try {\n                super.generateFile(toBeGenerated, original);\n            } catch (ResourcesNotSupportedException e) {\n                // Add gradle-specific error message.\n                throw new GradleException(\n                        String.format(\n                                \"Can't process attribute %1$s=\\\"%2$s\\\": \"\n                                        + \"references to other resources are not supported by \"\n                                        + \"build-time PNG generation. \"\n                                        + \"See http://developer.android.com/tools/help/vector-asset-studio.html \"\n                                        + \"for details.\",\n                                e.getName(), e.getValue()));\n            }\n        }\n    }\n\n    @NonNull\n    private ResourcePreprocessor getPreprocessor() {\n        // Only one pre-processor for now. The code will need slight changes when we add more.\n\n        if (isDisableVectorDrawables()) {\n            // If the user doesn't want any PNGs, leave the XML file alone as well.\n            return NoOpResourcePreprocessor.INSTANCE;\n        }\n\n        Collection<Density> densities =\n                getGeneratedDensities().stream().map(Density::getEnum).collect(Collectors.toList());\n\n        return new MergeAwbResource.MergeResourcesVectorDrawableRenderer(\n                getMinSdk(),\n                getGeneratedPngsOutputDir(),\n                densities,\n                LoggerWrapper.supplierFor(MergeAwbResource.class));\n    }\n\n    @NonNull\n    private List<ResourceSet> getConfiguredResourceSets(ResourcePreprocessor preprocessor) {\n        // it is possible that this get called twice in case the incremental run fails and reverts\n        // back to full task run. Because the cached ResourceList is modified we don't want\n        // to recompute this twice (plus, why recompute it twice anyway?)\n        if (processedInputs == null) {\n            processedInputs = computeResourceSetList();\n            List<ResourceSet> generatedSets = Lists.newArrayListWithCapacity(processedInputs.size());\n\n            for (ResourceSet resourceSet : processedInputs) {\n                resourceSet.setPreprocessor(preprocessor);\n                ResourceSet generatedSet = new GeneratedResourceSet(resourceSet);\n                resourceSet.setGeneratedSet(generatedSet);\n                generatedSets.add(generatedSet);\n            }\n\n            // We want to keep the order of the inputs. Given inputs:\n            // (A, B, C, D)\n            // We want to get:\n            // (A-generated, A, B-generated, B, C-generated, C, D-generated, D).\n            // Therefore, when later in {@link DataMerger} we look for sources going through the\n            // list backwards, B-generated will take priority over A (but not B).\n            // A real life use-case would be if an app module generated resource overrode a library\n            // module generated resource (existing not in generated but bundled dir at this stage):\n            // (lib, app debug, app main)\n            // We will get:\n            // (lib generated, lib, app debug generated, app debug, app main generated, app main)\n            for (int i = 0; i < generatedSets.size(); ++i) {\n                processedInputs.add(2 * i, generatedSets.get(i));\n            }\n        }\n\n        return processedInputs;\n    }\n\n    /**\n     * Release resource sets not needed any more, otherwise they will waste heap space for the\n     * duration of the build.\n     *\n     * <p>This might be called twice when an incremental build falls back to a full one.\n     */\n    private void cleanup() {\n        fileValidity.clear();\n        processedInputs = null;\n    }\n\n    @InputFiles\n    @PathSensitive(PathSensitivity.RELATIVE)\n    public FileCollection getRenderscriptResOutputDir() {\n        return renderscriptResOutputDir;\n    }\n\n    @VisibleForTesting\n    void setRenderscriptResOutputDir(@NonNull FileCollection renderscriptResOutputDir) {\n        this.renderscriptResOutputDir = renderscriptResOutputDir;\n    }\n\n    @InputFiles\n    @PathSensitive(PathSensitivity.RELATIVE)\n    public FileCollection getGeneratedResOutputDir() {\n        return generatedResOutputDir;\n    }\n\n    @VisibleForTesting\n    void setGeneratedResOutputDir(@NonNull FileCollection generatedResOutputDir) {\n        this.generatedResOutputDir = generatedResOutputDir;\n    }\n\n    @InputFiles\n    @PathSensitive(PathSensitivity.RELATIVE)\n    @Optional\n    public FileCollection getMicroApkResDirectory() {\n        return microApkResDirectory;\n    }\n\n    @VisibleForTesting\n    void setMicroApkResDirectory(@NonNull FileCollection microApkResDirectory) {\n        this.microApkResDirectory = microApkResDirectory;\n    }\n\n    @InputFiles\n    @PathSensitive(PathSensitivity.RELATIVE)\n    @Optional\n    public FileCollection getExtraGeneratedResFolders() {\n        return extraGeneratedResFolders;\n    }\n\n    @VisibleForTesting\n    void setExtraGeneratedResFolders(@NonNull FileCollection extraGeneratedResFolders) {\n        this.extraGeneratedResFolders = extraGeneratedResFolders;\n    }\n\n    @Optional\n    @InputFiles\n    @PathSensitive(PathSensitivity.RELATIVE)\n    public FileCollection getLibraries() {\n        List<File>resFiles = new ArrayList<>();\n        for (AndroidLibrary androidLibrary:libraries){\n            resFiles.add(androidLibrary.getResFolder());\n        }\n        resFiles.add(awbBundle.getAndroidLibrary().getResFolder());\n        return getProject().files(resFiles);\n }\n\n    @VisibleForTesting\n    void setLibraries(List<AndroidLibrary> libraries) {\n        this.libraries = libraries;\n    }\n\n    @InputFiles\n    @PathSensitive(PathSensitivity.RELATIVE)\n    public Collection<File> getSourceFolderInputs() {\n        return sourceFolderInputs.get();\n    }\n\n    @OutputDirectory\n    public File getOutputDir() {\n        return outputDir;\n    }\n\n    public void setOutputDir(File outputDir) {\n        this.outputDir = outputDir;\n    }\n\n    @Input\n    public boolean getCrunchPng() {\n        return crunchPng;\n    }\n\n    @Input\n    public boolean getProcessResources() {\n        return processResources;\n    }\n\n    @Optional\n    @OutputFile\n    public File getPublicFile() {\n        return publicFile;\n    }\n\n    public void setPublicFile(File publicFile) {\n        this.publicFile = publicFile;\n    }\n\n    // Synthetic input: the validation flag is set on the resource sets in ConfigAction.execute.\n    @Input\n    public boolean isValidateEnabled() {\n        return validateEnabled;\n    }\n\n    public void setValidateEnabled(boolean validateEnabled) {\n        this.validateEnabled = validateEnabled;\n    }\n\n    @OutputDirectory\n    @Optional\n    public File getBlameLogFolder() {\n        return blameLogFolder;\n    }\n\n    public void setBlameLogFolder(File blameLogFolder) {\n        this.blameLogFolder = blameLogFolder;\n    }\n\n    @OutputDirectory\n    public File getGeneratedPngsOutputDir() {\n        return generatedPngsOutputDir;\n    }\n\n    public void setGeneratedPngsOutputDir(File generatedPngsOutputDir) {\n        this.generatedPngsOutputDir = generatedPngsOutputDir;\n    }\n\n    @Input\n    public Collection<String> getGeneratedDensities() {\n        return generatedDensities;\n    }\n\n    @Input\n    public int getMinSdk() {\n        return minSdk;\n    }\n\n    public void setMinSdk(int minSdk) {\n        this.minSdk = minSdk;\n    }\n\n    public void setGeneratedDensities(Collection<String> generatedDensities) {\n        this.generatedDensities = generatedDensities;\n    }\n\n    @Input\n    public boolean isDisableVectorDrawables() {\n        return disableVectorDrawables;\n    }\n\n    public void setDisableVectorDrawables(boolean disableVectorDrawables) {\n        this.disableVectorDrawables = disableVectorDrawables;\n    }\n\n    @Input\n    public String getAaptGeneration() {\n        return aaptGeneration.name();\n    }\n\n    @Nullable\n    @OutputDirectory\n    @Optional\n    public File getMergedNotCompiledResourcesOutputDirectory() {\n        return mergedNotCompiledResourcesOutputDirectory;\n    }\n\n    @Input\n    public boolean isPseudoLocalesEnabled() {\n        return pseudoLocalesEnabled;\n    }\n\n    @VisibleForTesting\n    void setResSetSupplier(@NonNull Supplier<List<ResourceSet>> resSetSupplier) {\n        this.resSetSupplier = resSetSupplier;\n    }\n\n    /**\n     * Compute the list of resource set to be used during execution based all the inputs.\n     */\n    @VisibleForTesting\n    @NonNull\n    List<ResourceSet> computeResourceSetList() {\n        List<ResourceSet> sourceFolderSets = resSetSupplier.get();\n        int size = sourceFolderSets.size() + 4;\n        if (libraries != null) {\n            size += libraries.size();\n        }\n\n        List<ResourceSet> resourceSetList = Lists.newArrayListWithExpectedSize(size);\n\n        // add at the beginning since the libraries are less important than the folder based\n        // resource sets.\n        // get the dependencies first\n        if (libraries != null) {\n            // the order of the artifact is descending order, so we need to reverse it.\n            for (AndroidLibrary artifact : libraries) {\n                ResourceSet resourceSet =\n                        new ResourceSet(\n                                artifact.getName(),\n                                null,\n                                null,\n                                validateEnabled);\n                resourceSet.setFromDependency(true);\n                resourceSet.addSource(artifact.getResFolder());\n\n                // add to 0 always, since we need to reverse the order.\n                resourceSetList.add(0,resourceSet);\n            }\n        }\n\n\n        ResourceSet resourceSet =\n                new ResourceSet(\n                        awbBundle.getName(),\n                        null,\n                        null,\n                        validateEnabled);\n        resourceSet.setFromDependency(true);\n        resourceSet.addSource(awbBundle.getAndroidLibrary().getResFolder());\n        // add the folder based next\n        resourceSetList.addAll(sourceFolderSets);\n        resourceSetList.add(resourceSet);\n\n        // We add the generated folders to the main set\n        List<File> generatedResFolders = Lists.newArrayList();\n\n        generatedResFolders.addAll(renderscriptResOutputDir.getFiles());\n        generatedResFolders.addAll(generatedResOutputDir.getFiles());\n\n        FileCollection extraFolders = getExtraGeneratedResFolders();\n        if (extraFolders != null) {\n            generatedResFolders.addAll(extraFolders.getFiles());\n        }\n        if (microApkResDirectory != null) {\n            generatedResFolders.addAll(microApkResDirectory.getFiles());\n        }\n\n//        // add the generated files to the main set.\n//        final ResourceSet mainResourceSet = sourceFolderSets.get(0);\n//        assert mainResourceSet.getConfigName().equals(BuilderConstants.MAIN);\n//        mainResourceSet.addSources(generatedResFolders);\n\n        return resourceSetList;\n    }\n\n    /**\n     * Obtains the temporary directory for {@code aapt} to use.\n     *\n     * @return the temporary directory\n     */\n    @NonNull\n    private File getAaptTempDir() {\n        return FileUtils.mkdirs(new File(getIncrementalFolder(), \"aapt-temp\"));\n    }\n\n    public static class MergeAwbResourceConfigAction extends MtlBaseTaskAction<MergeAwbResource> {\n\n        @NonNull\n        private final VariantScope scope;\n\n        private AwbBundle awbBundle;\n\n        private VariantContext variantContext;\n        @Nullable\n        private final File outputLocation;\n        @Nullable private final File mergedNotCompiledOutputDirectory;\n        private final boolean includeDependencies;\n        private final boolean processResources;\n\n\n        public MergeAwbResourceConfigAction(VariantContext variantContext,\n                                            BaseVariantOutput baseVariantOutput,\n                                            AwbBundle awbBundle) {\n            super(variantContext, baseVariantOutput);\n            this.variantContext = variantContext;\n            this.awbBundle = awbBundle;\n            this.scope = variantContext.getScope();\n            this.outputLocation = variantContext.getMergeResources(awbBundle);\n            this.mergedNotCompiledOutputDirectory = variantContext.getMergeNotCompiledFolder(awbBundle);\n            this.includeDependencies = true;\n            this.processResources = true;\n        }\n//        public MergeAwbResourceConfigAction(\n//                @NonNull VariantScope scope,\n//                @NonNull String taskNamePrefix,\n//                @Nullable File outputLocation,\n//                @Nullable File mergedNotCompiledOutputDirectory,\n//                boolean includeDependencies,\n//                boolean processResources) {\n//            this.scope = scope;\n//            this.taskNamePrefix = taskNamePrefix;\n//            this.outputLocation = outputLocation;\n//            this.mergedNotCompiledOutputDirectory = mergedNotCompiledOutputDirectory;\n//            this.includeDependencies = includeDependencies;\n//            this.processResources = processResources;\n//        }\n\n        @NonNull\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"merge\", \"Resource[\" + awbBundle.getName() + \"]\");\n        }\n\n        @NonNull\n        @Override\n        public Class<MergeAwbResource> getType() {\n            return MergeAwbResource.class;\n        }\n\n        @Override\n        public void execute(@NonNull MergeAwbResource mergeResourcesTask) {\n            final BaseVariantData variantData = scope.getVariantData();\n            final Project project = scope.getGlobalScope().getProject();\n            mergeResourcesTask.awbBundle = awbBundle;\n            mergeResourcesTask.setMinSdk(\n                    variantData.getVariantConfiguration().getMinSdkVersion().getApiLevel());\n            mergeResourcesTask.aaptGeneration =\n                    AaptGeneration.fromProjectOptions(scope.getGlobalScope().getProjectOptions());\n            mergeResourcesTask.setAndroidBuilder(scope.getGlobalScope().getAndroidBuilder());\n            mergeResourcesTask.fileCache = scope.getGlobalScope().getBuildCache();\n            mergeResourcesTask.setVariantName(scope.getVariantConfiguration().getFullName());\n            mergeResourcesTask.setIncrementalFolder(scope.getIncrementalDir(getName()));\n            mergeResourcesTask.variantScope = scope;\n            // Libraries use this task twice, once for compilation (with dependencies),\n            // where blame is useful, and once for packaging where it is not.\n            if (includeDependencies) {\n                mergeResourcesTask.setBlameLogFolder(variantContext.getAwbResourceBlameLogDir(awbBundle));\n            }\n            mergeResourcesTask.processResources = processResources;\n            mergeResourcesTask.crunchPng = scope.isCrunchPngs();\n\n            VectorDrawablesOptions vectorDrawablesOptions = variantData\n                    .getVariantConfiguration()\n                    .getMergedFlavor()\n                    .getVectorDrawables();\n\n            Set<String> generatedDensities = vectorDrawablesOptions.getGeneratedDensities();\n\n            // Collections.<String>emptySet() is used intentionally instead of Collections.emptySet()\n            // to keep compatibility with javac 1.8.0_45 used by ab/\n            mergeResourcesTask.setGeneratedDensities(\n                    MoreObjects.firstNonNull(generatedDensities, Collections.<String>emptySet()));\n\n            mergeResourcesTask.setDisableVectorDrawables(\n                    (vectorDrawablesOptions.getUseSupportLibrary() != null\n                            && vectorDrawablesOptions.getUseSupportLibrary())\n                            || mergeResourcesTask.getGeneratedDensities().isEmpty());\n\n            final boolean validateEnabled =\n                    !scope.getGlobalScope()\n                            .getProjectOptions()\n                            .get(BooleanOption.DISABLE_RESOURCE_VALIDATION);\n\n            mergeResourcesTask.setValidateEnabled(validateEnabled);\n\n            if (includeDependencies) {\n                mergeResourcesTask.libraries = awbBundle.getAndroidLibraries();\n            }\n\n            mergeResourcesTask.resSetSupplier =\n                    () -> ImmutableList.of();\n            mergeResourcesTask.sourceFolderInputs =\n                    TaskInputHelper.bypassFileSupplier(\n                            () ->ImmutableList.of());\n            mergeResourcesTask.extraGeneratedResFolders = variantData.getExtraGeneratedResFolders();\n            mergeResourcesTask.renderscriptResOutputDir = project.files(variantContext.getGenerateRs(awbBundle));\n            mergeResourcesTask.generatedResOutputDir = project.files(variantContext.getGenerateResValue(awbBundle));\n            if (scope.getMicroApkTask() != null &&\n                    variantData.getVariantConfiguration().getBuildType().isEmbedMicroApp()) {\n                mergeResourcesTask.microApkResDirectory = project.files(scope.getMicroApkResDirectory());\n            }\n\n            mergeResourcesTask.setOutputDir(outputLocation);\n            mergeResourcesTask.setGeneratedPngsOutputDir(variantContext.getPngsOutputDir(awbBundle));\n//            variantData.mergeResourcesTask = mergeResourcesTask;\n\n\n            if (scope.getGlobalScope().getExtension().getDataBinding().isEnabled() && ((AppVariantContext)variantContext).isDataBindEnabled(awbBundle)) {\n                // Keep as an output.\n                mergeResourcesTask.dataBindingLayoutInfoOutFolder =\n                      ((AppVariantContext) variantContext).getAwbLayoutInfoOutputForDataBinding(awbBundle);\n\n                mergeResourcesTask.layoutXmlProcessor =\n                        new SingleFileProcessor() {\n                            final LayoutXmlProcessor processor =\n                                    variantData.getLayoutXmlProcessor();\n\n                            @Override\n                            public boolean processSingleFile(File file, File out) throws Exception {\n                                return processor.processSingleFile(file, out);\n                            }\n\n                            @Override\n                            public void processRemovedFile(File file) {\n                                processor.processRemovedFile(file);\n                            }\n\n                            @Override\n                            public void end() throws javax.xml.bind.JAXBException{\n                                processor.writeLayoutInfoFiles(\n                                        mergeResourcesTask.dataBindingLayoutInfoOutFolder);\n                            }\n                        };\n            }\n\n            mergeResourcesTask.mergedNotCompiledResourcesOutputDirectory =\n                    mergedNotCompiledOutputDirectory;\n\n            mergeResourcesTask.pseudoLocalesEnabled =\n                    scope.getVariantData()\n                            .getVariantConfiguration()\n                            .getBuildType()\n                            .isPseudoLocalesEnabled();\n\n\n\n\n        }\n\n\n    }\n\n    // Workaround for https://issuetracker.google.com/67418335\n    @Override\n    @Input\n    @NonNull\n    public String getCombinedInput() {\n        return new CombinedInput(super.getCombinedInput())\n                .add(\"dataBindingLayoutInfoOutFolder\", getDataBindingLayoutInfoOutFolder())\n                .add(\"publicFile\", getPublicFile())\n                .add(\"blameLogFolder\", getBlameLogFolder())\n                .add(\n                        \"mergedNotCompiledResourcesOutputDirectory\",\n                        getMergedNotCompiledResourcesOutputDirectory())\n                .toString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/prepare/AddLocalJarTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.prepare;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.builder.model.AndroidLibrary;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper;\nimport org.dom4j.DocumentException;\nimport org.gradle.api.Project;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.ExecutionException;\n\nimport static com.android.SdkConstants.DOT_JAR;\nimport static com.android.SdkConstants.FD_AAR_LIBS;\n\n/**\n * 1. Increase localjar\n *\n * @author wuzhong\n */\npublic class AddLocalJarTask extends BaseTask {\n\n    static final String taskName = \"addLocalJar\";\n\n    AtlasDependencyTree atlasDependencyTree;\n\n    AppVariantContext appVariantContext;\n\n    @TaskAction\n    void run() throws ExecutionException, InterruptedException, IOException, DocumentException {\n        ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper(taskName,\n                                                                                   getLogger(),\n                                                                                   0);\n\n        Project project = getProject();\n        //TODO localjar for main dex must on\n        for( AndroidLibrary androidLibrary : atlasDependencyTree.getMainBundle().getAllLibraryAars()){\n            List<File> localJars = getLocalJars(androidLibrary.getFolder());\n            //System.out.println(\"get local libs\");\n            for (File file : localJars) {\n                project.getLogger().info(\"add local jar to dependency \" + file.getAbsolutePath() + \"->\" + androidLibrary\n                    .getResolvedCoordinates().toString());\n            }\n            androidLibrary.getLocalJars().addAll(localJars);\n        }\n\n        if (isLocalJarEnabled(project)) {\n            List<AndroidLibrary> bundleLibraries = new ArrayList<>(atlasDependencyTree.getAllAndroidLibrarys());\n            bundleLibraries.removeAll(atlasDependencyTree.getMainBundle().getAllLibraryAars());\n            for (final AndroidLibrary aarBundle : bundleLibraries) {\n                List<File> localJars = getLocalJars(aarBundle.getFolder());\n                //System.out.println(\"get local libs\");\n                for (File file : localJars) {\n                    project.getLogger().info(\"add local jar to dependency \" + file.getAbsolutePath() + \"->\" + aarBundle\n                        .getResolvedCoordinates().toString());\n                }\n                aarBundle.getLocalJars().addAll(localJars);\n            }\n        }\n\n    }\n\n    private boolean isLocalJarEnabled(Project project) {\n        boolean localJarEnabled = AtlasBuildContext.sBuilderAdapter.localJarEnabled;\n        if (project.hasProperty(\"localJarEnabled\")) {\n            localJarEnabled = \"true\".equals(project.property(\"localJarEnabled\"));\n        }\n        return localJarEnabled;\n    }\n\n    private List<File> getLocalJars(File rootDir) {\n        List<File> localJars = Lists.newArrayList();\n        List<File> rootDirs = new ArrayList<>();\n        rootDirs.add(new File(rootDir, FD_AAR_LIBS));\n        rootDirs.add(new File(rootDir, \"jars/\"+FD_AAR_LIBS));\n\n        for (File root : rootDirs){\n            File[] jarList = root.listFiles();\n            if (jarList != null) {\n                for (File jars : jarList) {\n                    if (jars.isFile() && jars.getName().endsWith(DOT_JAR)) {\n                        localJars.add(jars);\n                    }\n                }\n            }\n        }\n\n        return localJars;\n    }\n\n\n\n    public static class ConfigAction extends MtlBaseTaskAction<AddLocalJarTask> {\n\n        AppVariantContext appVariantContext;\n        public ConfigAction(AppVariantContext appVariantContext,\n                            BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(taskName);\n        }\n\n        @Override\n        public Class<AddLocalJarTask> getType() {\n            return AddLocalJarTask.class;\n        }\n\n        @Override\n        public void execute(AddLocalJarTask localJarTask) {\n\n            super.execute(localJarTask);\n            localJarTask.appVariantContext =appVariantContext;\n            localJarTask.atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n                localJarTask.getVariantName());\n        }\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/prepare/BundleInfoSourceCreator.java",
    "content": "package com.taobao.android.builder.tasks.app.prepare;\n\nimport com.taobao.android.builder.tools.bundleinfo.model.BasicBundleInfo;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Created by guanjie on 2017/9/23.\n */\npublic class BundleInfoSourceCreator {\n    private boolean supportRemote = true;\n    public StringBuffer createBundleInfoSourceStr(List<BasicBundleInfo> basicBundleInfos,boolean supportRemotecomponent){\n        supportRemote = supportRemotecomponent;\n        StringBuffer buffer = new StringBuffer();\n        buffer.append(\"package android.taobao.atlas.bundleInfo;\\n\" +\n                \"\\n\" +\n                \"import java.util.ArrayList;\\n\" +\n                \"import java.util.HashMap;\\n\" +\n                \"import java.util.LinkedHashMap;\\n\" +\n                \"import java.util.List;\\n\" +\n                \"\\n\" +\n                \"\\n\" +\n                \"public class AtlasBundleInfoGenerator {\\n\" +\n                \"    public static BundleListing generateBundleInfo(){\\n\" +\n                \"        LinkedHashMap<String,BundleListing.BundleInfo> bundleInfos = new LinkedHashMap<>();\\n\" +\n                \"        HashMap<String,Boolean> activities;\\n\" +\n                \"        HashMap<String,Boolean> services;\\n\" +\n                \"        HashMap<String,Boolean> receivers;\\n\" +\n                \"        HashMap<String,Boolean> providers;\\n\" +\n                \"        HashMap<String,String> remoteFragments;\\n\" +\n                \"        HashMap<String,String> remoteViews;\\n\" +\n                \"        HashMap<String,String> remoteTransactors;\\n\" +\n                \"        List<String> dependencies;\\n\" +\n                \"        BundleListing.BundleInfo info;\\n\" +\n                \"\\n\" +\n                \"        BundleListing listing = new BundleListing();\\n\" +\n                \"        listing.bundles = bundleInfos;\\n\");\n\n        if(basicBundleInfos!=null && basicBundleInfos.size()>0){\n            for(BasicBundleInfo info : basicBundleInfos){\n                buffer.append(generateBundleInfoItem(info));\n            }\n        }\n\n        buffer.append(\"        return listing;\\n\" +\n                \"    }\\n\" +\n                \"}\");\n        return buffer;\n    }\n\n    private StringBuffer generateBundleInfoItem(BasicBundleInfo info){\n        StringBuffer infoBuffer = new StringBuffer();\n        infoBuffer.append(\"info = new BundleListing.BundleInfo();\\n\" +\n                \"        activities = new HashMap<>();\\n\" +\n                \"        services = new HashMap<>();\\n\" +\n                \"        receivers = new HashMap<>();\\n\" +\n                \"        providers = new HashMap<>();\\n\" +\n                \"        remoteFragments = new HashMap<>();\\n\" +\n                \"        remoteViews = new HashMap<>();\\n\" +\n                \"        remoteTransactors = new HashMap<>();\\n\" +\n                \"        dependencies = new ArrayList<>();\\n\" +\n                \"        info.activities = activities;\\n\" +\n                \"        info.services = services;\\n\" +\n                \"        info.receivers = receivers;\\n\" +\n                \"        info.contentProviders = providers;\\n\" +\n                ( supportRemote ?\n                \"        info.remoteFragments = remoteFragments;\\n\" +\n                \"        info.remoteViews = remoteViews;\\n\" +\n                \"        info.remoteTransactors = remoteTransactors;\\n\" : \"\")+\n                \"        info.dependency = dependencies;\\n\");\n\n        infoBuffer.append(String.format(\"info.unique_tag = \\\"%s\\\";\\n\",info.getUnique_tag()));\n        infoBuffer.append(String.format(\"info.pkgName = \\\"%s\\\";\\n\",info.getPkgName()));\n        infoBuffer.append(String.format(\"info.isInternal = %s;\\n\",info.getIsInternal()));\n        infoBuffer.append(String.format(\"info.isMBundle = %s;\\n\",info.getIsMBundle()));\n        if(info.getApplicationName()!=null) {\n            infoBuffer.append(String.format(\"info.applicationName = \\\"%s\\\";\\n\", info.getApplicationName()));\n        }\n\n        List<String> components = info.getActivities();\n        if(components!=null && components.size()>0){\n            for(String activity : components){\n                infoBuffer.append(String.format(\"activities.put(\\\"%s\\\",Boolean.FALSE);\\n\",activity));\n            }\n        }\n        components = info.getServices();\n        if(components!=null && components.size()>0){\n            for(String service : components){\n                infoBuffer.append(String.format(\"services.put(\\\"%s\\\",Boolean.FALSE);\\n\",service));\n            }\n        }\n        components = info.getReceivers();\n        if(components!=null && components.size()>0){\n            for(String receiver : components){\n                infoBuffer.append(String.format(\"receivers.put(\\\"%s\\\",Boolean.FALSE);\\n\",receiver));\n            }\n        }\n        components = info.getContentProviders();\n        if(components!=null && components.size()>0){\n            for(String provider : components){\n                infoBuffer.append(String.format(\"providers.put(\\\"%s\\\",Boolean.FALSE);\\n\",provider));\n            }\n        }\n\n        HashMap<String,String> remoteFragments= info.getRemoteFragments();\n        if(remoteFragments!=null){\n            for (Map.Entry<String, String> entry : remoteFragments.entrySet()) {\n                infoBuffer.append(String.format(\"remoteFragments.put(\\\"%s\\\",\\\"%s\\\");\\n\",entry.getKey(),entry.getValue()));\n            }\n        }\n\n        HashMap<String,String> remoteViews= info.getRemoteViews();\n        if(remoteViews!=null){\n            for (Map.Entry<String, String> entry : remoteViews.entrySet()) {\n                infoBuffer.append(String.format(\"remoteViews.put(\\\"%s\\\",\\\"%s\\\");\\n\",entry.getKey(),entry.getValue()));\n            }\n        }\n\n        HashMap<String,String> remoteTransactors= info.getRemoteTransactors();\n        if(remoteTransactors!=null){\n            for (Map.Entry<String, String> entry : remoteTransactors.entrySet()) {\n                infoBuffer.append(String.format(\"remoteTransactors.put(\\\"%s\\\",\\\"%s\\\");\\n\",entry.getKey(),entry.getValue()));\n            }\n        }\n\n        List<String> dependencies = info.getDependency();\n        if(dependencies!=null && dependencies.size()>0){\n            for(String dependency : dependencies){\n                if(dependency!=null) {\n                    infoBuffer.append(String.format(\"dependencies.add(\\\"%s\\\");\\n\", dependency));\n                }\n            }\n        }\n        infoBuffer.append(\"bundleInfos.put(info.pkgName,info);\\n\");\n        return infoBuffer;\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/prepare/PrepareAaptTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.prepare;\n\n/**\n * Created by wuzhong on 16/6/13.\n */\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.TaskContainerAdaptor;\nimport com.android.build.gradle.internal.api.ApContext;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.dsl.AaptOptions;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.build.gradle.tasks.ProcessAndroidResources;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.File;\nimport java.util.ArrayList;\n\npublic class PrepareAaptTask extends BaseTask {\n\n    AppVariantContext appVariantContext;\n\n    ProcessAndroidResources processAndroidResources;\n    //MergeResources mergeResources;\n\n    @TaskAction\n    public void doExecute() {\n\n        AaptOptions aaptOptions = processAndroidResources.getAaptOptions();\n        if (null == aaptOptions) {\n            aaptOptions = new AaptOptions();\n        }\n        if (null == aaptOptions.getAdditionalParameters()) {\n            aaptOptions.setAdditionalParameters(new ArrayList<String>());\n        }\n\n        processAndroidResources.setAndroidBuilder(getBuilder());\n        processAndroidResources.setAaptOptions(aaptOptions);\n\n        ApContext apContext = appVariantContext.apContext;\n        if (processAndroidResources.isAapt2Enabled()) {\n            aaptOptions.getAdditionalParameters().add(\"--emit-ids\");\n            aaptOptions.getAdditionalParameters().add(new File(getProject().getBuildDir(),\n                \"outputs/public.txt\").getAbsolutePath());\n        }\n        if (null != apContext && apContext.getBaseApk() != null && apContext.getBaseApk().exists()) {\n            File baseApk = appVariantContext.apContext.getBaseApk();\n            //You need to increase the -b parameter\n            if (processAndroidResources.isAapt2Enabled()) {\n                aaptOptions.getAdditionalParameters().add(\"-I\");\n            } else {\n                if (!aaptOptions.getAdditionalParameters().contains(\"-B\")) {\n                    aaptOptions.getAdditionalParameters().add(\"-B\");\n                }\n            }\n            aaptOptions.getAdditionalParameters().add(baseApk.getAbsolutePath());\n            if (processAndroidResources.isAapt2Enabled()) {\n                aaptOptions.getAdditionalParameters().add(\"--stable-ids\");\n                aaptOptions.getAdditionalParameters().add(apContext.getBaseStableIdsFile().getAbsolutePath());\n            }\n            if (appVariantContext.getAtlasExtension().getTBuildConfig().isIncremental() && (\n                appVariantContext.getBuildType().getPatchConfig() == null || !appVariantContext.getBuildType()\n                    .getPatchConfig()\n                    .isCreateTPatch())) {\n                aaptOptions.getAdditionalParameters().add(\"--vm-safemode\");\n                aaptOptions.getAdditionalParameters().add(\"--merge\");\n            }\n            //AndroidManifestThe file cannot e modified OR ignored when patch, so the current selection is ignored when patch\n        }\n\n        //TODO update merge resource\n        //mergeResources.setAndroidBuilder(AtlasBuildContext.androidBuilder);\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<PrepareAaptTask> {\n\n        private final AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext, BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"prepare\", \"Aapt\");\n        }\n\n        @Override\n        public Class<PrepareAaptTask> getType() {\n            return PrepareAaptTask.class;\n        }\n\n        @Override\n        public void execute(PrepareAaptTask prepareAaptTask) {\n\n            super.execute(prepareAaptTask);\n\n            if (!appVariantContext.getAtlasExtension().getTBuildConfig().getUseCustomAapt()) {\n                prepareAaptTask.setEnabled(false);\n                return;\n            }\n\n            prepareAaptTask.appVariantContext = appVariantContext;\n            prepareAaptTask.processAndroidResources = appVariantContext.getScope()\n                .getProcessResourcesTask()\n                .get(new TaskContainerAdaptor(scope.getGlobalScope().getProject().getTasks()));\n\n            //prepareAaptTask.mergeResources = appVariantContext.getVariantData().mergeResourcesTask;\n\n        }\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/prepare/PrepareBundleInfoTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.prepare;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.bundleinfo.BundleInfoUtils;\nimport com.taobao.android.builder.tools.bundleinfo.model.BundleInfo;\nimport org.apache.commons.io.FileUtils;\nimport org.dom4j.DocumentException;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ExecutionException;\nimport java.util.function.Consumer;\nimport java.util.function.Predicate;\nimport java.util.stream.Collectors;\n\npublic class PrepareBundleInfoTask extends BaseTask {\n\n    AppVariantOutputContext appVariantOutputContext;\n\n    @TaskAction\n    void run() throws ExecutionException, InterruptedException, IOException, DocumentException {\n\n        AtlasBuildContext.awbBundleMap = collectBundleInfo(appVariantOutputContext);\n\n        AppVariantContext appVariantContext = appVariantOutputContext.getVariantContext();\n        BundleInfoUtils.setupAwbBundleInfos(appVariantContext);\n\n        //Generate the bundle manifest file\n        generateBundleListCfg(appVariantContext);\n\n    }\n\n    private void generateBundleListCfg(AppVariantContext appVariantContext) throws IOException {\n        List<String> bundleLists = AtlasBuildContext.awbBundleMap.values().stream().filter(awbBundle -> !awbBundle.isMBundle).map(awbBundle -> {\n            return appVariantOutputContext.getAwbPackageOutputFilePath(awbBundle);\n        }).sorted().collect(Collectors.toList());\n        File outputFile = new File(appVariantContext.getScope().getGlobalScope().getOutputsDir(), \"bundleList.cfg\");\n        FileUtils.deleteQuietly(outputFile);\n        outputFile.getParentFile().mkdirs();\n        FileUtils.writeLines(outputFile, bundleLists);\n\n        appVariantContext.bundleListCfg = outputFile;\n        //Set the bundle dependencies\n\n        List<BundleInfo> bundleInfos = new ArrayList<>();\n        AtlasBuildContext.awbBundleMap.values().stream().forEach(awbBundle -> bundleInfos.add(awbBundle.bundleInfo));\n\n    }\n\n    private Map<String, AwbBundle> collectBundleInfo(AppVariantOutputContext appVariantOutputContext) {\n\n        List<AwbBundle> awbBundles = AtlasBuildContext.androidDependencyTrees.get(\n            appVariantOutputContext.getVariantData().getName()).getAwbBundles();\n\n        Map<String, AwbBundle> map = new HashMap<String, AwbBundle>();\n\n        for (AwbBundle awbBundle : awbBundles) {\n\n            try {\n                map.put(awbBundle.getAwbSoName(), awbBundle);\n            } catch (Throwable e) {\n                getProject().getLogger().error(awbBundle.getAndroidLibrary().toString(), e);\n            }\n        }\n\n        return map;\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<PrepareBundleInfoTask> {\n\n        public ConfigAction(AppVariantContext appVariantContext,\n                            BaseVariantOutput variantOutput) {\n            super(appVariantContext, variantOutput);\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"prepareBundleInfo\");\n        }\n\n        @Override\n        public Class<PrepareBundleInfoTask> getType() {\n            return PrepareBundleInfoTask.class;\n        }\n\n        @Override\n        public void execute(PrepareBundleInfoTask prepareBundleInfoTask) {\n\n            super.execute(prepareBundleInfoTask);\n\n            prepareBundleInfoTask.appVariantOutputContext = getAppVariantOutputContext();\n        }\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/app/prepare/PreparePackageIdsTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.app.prepare;\n\n/**\n * Created by wuzhong on 16/6/13.\n */\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\n\nimport com.alibaba.fastjson.JSON;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.extension.TBuildConfig;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.tasks.TaskAction;\n\n/**\n * Distribution packageId\n */\npublic class PreparePackageIdsTask extends BaseTask {\n\n\n    AppVariantContext appVariantContext;\n    AppVariantOutputContext.AppBuildInfo appBuildInfo;\n\n    /**\n     * packageid The range is 30 - 127\n     */\n    @TaskAction\n    void generate() throws IOException {\n\n        TBuildConfig tBuildConfig = appVariantContext.getAtlasExtension().getTBuildConfig();\n\n        File packageIdFile = tBuildConfig.getPackageIdFile();\n        File apPackageIdFile = appVariantContext.apContext.getPackageIdFile();\n        boolean isAutoPackageId = tBuildConfig.isAutoPackageId();\n        int minPackageId = tBuildConfig.getMinPackageId();\n\n        Map<String, String> autoConfigMap = new HashMap<String, String>();\n        if (null != apPackageIdFile && apPackageIdFile.exists()) {\n            autoConfigMap.putAll(loadPackageIdProperties(apPackageIdFile));\n        } else if (null != packageIdFile && packageIdFile.exists()) {\n            autoConfigMap.putAll(loadPackageIdProperties(packageIdFile));\n        }\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(getVariantName());\n\n        for (AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n            String key = awbBundle.getResolvedCoordinates().getGroupId() + \":\" + awbBundle.getResolvedCoordinates().getArtifactId();\n            if (autoConfigMap.containsKey(key)) {\n                continue;\n            }\n\n            File customPackageIDFile = new File(awbBundle.getAndroidLibrary().getFolder(), \"customPackageID.txt\");\n            String packageId = getCustomPackageId(customPackageIDFile);\n            if (StringUtils.isNotEmpty(packageId)) {\n                autoConfigMap.put(key, packageId);\n            } else {\n                autoConfigMap.put(key, \"\");\n            }\n        }\n\n        if (isAutoPackageId && autoConfigMap.containsValue(\"\")) {\n\n            //Automatic allocation of autoConfig\n            List<String> keys = new ArrayList<String>(autoConfigMap.keySet());\n            Collections.sort(keys);\n\n            for (String key : keys) {\n                if (\"\".equals(autoConfigMap.get(key))) {\n\n                    for (int i = minPackageId; i </*=*/ 127; i++) {\n                        if (!autoConfigMap.values().contains(String.valueOf(i))) {\n                            autoConfigMap.put(key, String.valueOf(i));\n                            break;\n                        }\n                    }\n                }\n            }\n\n        }\n\n        AtlasBuildContext.customPackageIdMaps = autoConfigMap;\n\n        //wite package Id file\n        File outPkgFile = new File(getProject().getBuildDir(), \"outputs/packageIdFile.properties\");\n        writeProperties(autoConfigMap, outPkgFile);\n\n        appBuildInfo.setPackageIdFile(outPkgFile);\n\n        //check value\n        if (autoConfigMap.containsValue(\"\")) {\n            getLogger().error(JSON.toJSONString(autoConfigMap, true));\n            throw new GradleException(\"packageId Error configuration, please check\");\n        }\n\n        if (autoConfigMap.size() != new HashSet(autoConfigMap.values()).size()) {\n//            getLogger().error(JSON.toJSONString(autoConfigMap, true));\n\n            Map<String, PackageIdItem> idItemMap = new HashMap<String, PackageIdItem>();\n\n            for (String key : autoConfigMap.keySet()) {\n                String customPackageId = autoConfigMap.get(key);\n                PackageIdItem packageIdItem = idItemMap.get(customPackageId);\n                if (null == packageIdItem) {\n                    String[] split = customPackageId.split(\"\\\\.\");\n                    packageIdItem = new PackageIdItem();\n                    packageIdItem.packageId = Integer.valueOf(split[0]);\n                    if (split.length > 1) {\n                        packageIdItem.typeIdOffset = Integer.valueOf(split[1]);\n                    }\n                    idItemMap.put(customPackageId, packageIdItem);\n                }\n                packageIdItem.bundles.add(key);\n            }\n\n            Collection<PackageIdItem> collection = idItemMap.values();\n            List<PackageIdItem> packageList = new ArrayList<PackageIdItem>(collection);\n            Collections.sort(packageList, new Comparator<PackageIdItem>() {\n                @Override\n                public int compare(PackageIdItem o1, PackageIdItem o2) {\n                    return o1.packageId - o2.packageId;\n                }\n            });\n            getLogger().error(JSON.toJSONString(packageList, true));\n\n\n            throw new GradleException(\"packageId Configuration error, duplicate, please check\");\n        }\n\n        // check if packageID is not used\n        Map<String, String> autoConfigMap2 = new HashMap<>(autoConfigMap);\n        for (AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n            String key = awbBundle.getResolvedCoordinates().getGroupId() + \":\" + awbBundle.getResolvedCoordinates().getArtifactId();\n            autoConfigMap2.remove(key);\n        }\n        if (autoConfigMap2.size() > 0){\n            File outPkgFile2 = new File(getProject().getBuildDir(), \"outputs/warning-unusedPackageIdFile.properties\");\n            writeProperties(autoConfigMap2, outPkgFile2);\n        }\n\n    }\n\n    private void writeProperties(Map<String, String> map, File file) {\n        file.delete();\n        file.getParentFile().mkdirs();\n        try {\n            List<String> lines = new ArrayList<String>();\n            for (String key : map.keySet()) {\n                lines.add(key + \"=\" + map.get(key));\n            }\n            FileUtils.writeLines(file, lines);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n    }\n\n    /**\n     * Read the component's packageId\n     *\n     * @param packageIdFile\n     * @return\n     */\n    private Map<String, String> loadPackageIdProperties(File packageIdFile) throws IOException {\n        Map<String, String> values = new HashMap<String, String>();\n        if (null != packageIdFile && packageIdFile.exists() && packageIdFile.isFile()) {\n            List<String> lines = FileUtils.readLines(packageIdFile);\n            for (String line : lines) {\n                String[] lineValues = StringUtils.split(line, \"=\");\n                if (null != lineValues && lineValues.length >= 2) {\n                    String key = StringUtils.trim(lineValues[0]);\n                    String value = StringUtils.trim(lineValues[1]);\n                    values.put(key, value);\n                }\n            }\n        }\n        return values;\n    }\n\n    private String getCustomPackageId(File customIdFile) throws IOException {\n        if (null != customIdFile && customIdFile.exists()) {\n            return FileUtils.readFileToString(customIdFile);\n        }\n        return \"\";\n    }\n\n\n    public static class ConfigAction extends MtlBaseTaskAction<PreparePackageIdsTask> {\n\n        private AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext, BaseVariantOutput baseVariantOutput) {\n            super(appVariantContext, baseVariantOutput);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"prepare\", \"packageIds\");\n        }\n\n        @Override\n        public Class<PreparePackageIdsTask> getType() {\n            return PreparePackageIdsTask.class;\n        }\n\n        @Override\n        public void execute(PreparePackageIdsTask packageIdsTask) {\n\n            super.execute(packageIdsTask);\n\n            packageIdsTask.appVariantContext = appVariantContext;\n            packageIdsTask.appBuildInfo = getAppVariantOutputContext().appBuildInfo;\n\n\n        }\n    }\n\n    public static class PackageIdItem {\n        public int packageId;\n        public int typeIdOffset;\n        public List<String> bundles = new ArrayList<String>();\n    }\n\n\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/awo/utils/AwoInstaller.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.awo.utils;\n\nimport java.io.File;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.List;\n\nimport com.android.builder.core.AndroidBuilder;\nimport com.android.ddmlib.AndroidDebugBridge;\nimport com.android.ddmlib.DdmPreferences;\nimport com.android.ddmlib.IDevice;\nimport com.taobao.android.builder.tools.command.CommandExecutor;\nimport com.taobao.android.builder.tools.command.ExecutionException;\nimport org.apache.commons.io.FilenameUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.logging.Logger;\n\npublic class AwoInstaller {\n\n    public static final String PATCH_NAME_PREFIX = \"kernal_\";\n\n    public static final String PATCH_INSTALL_DIRECTORY_PREFIX = \"/sdcard/Android/data/\";\n\n    public static final String PATCH_INSTALL_DIRECTORY_SUFFIX = \"/files/atlas-debug/\";\n\n    private static final long ADB_TIMEOUT_MS = 60L * 1000;\n\n    private static final Object ADB_LOCK = new Object();\n\n    private static boolean adbInitialized = false;\n\n    protected static int adbConnectionTimeout = 5000;\n\n    //protected static final List<String> PATCH_DEPENDENCY_SCOPES = Arrays.asList(\n    //        Artifact.SCOPE_SYSTEM, Artifact.SCOPE_IMPORT\n    //);\n\n    public static void installTPatch(AndroidBuilder androidBuilder, File tPatchFile, File updateInfoFile,\n                                     String packageName, Logger logger) {\n        try {\n            installPatchIfDeviceConnected(androidBuilder, tPatchFile, packageName, logger, tPatchFile.getName());\n            installPatchIfDeviceConnected(androidBuilder, updateInfoFile, packageName, logger,\n                                          FilenameUtils.getBaseName(tPatchFile.getName()) + \".json\");\n            notifyApppatching(androidBuilder, packageName, logger);\n        } catch (Throwable e) {\n            throw new GradleException(\"install awo error\", e);\n        }\n    }\n\n    public static void installAwoSo(AndroidBuilder androidBuilder, File maindexFile, Collection<File> awoSoFiles,\n                                    String packageName, Logger logger) {\n        try {\n            if (maindexFile != null) {\n                if (!maindexFile.exists()) {\n                    throw new IllegalArgumentException(\n                        \"maindexFile file \" + maindexFile.getAbsolutePath() + \" does not exist.\");\n                }\n\n                installPatchIfDeviceConnected(androidBuilder, maindexFile, packageName, logger,\n                                              \"libcom_taobao_maindex.so\");\n            }\n            if (awoSoFiles != null) {\n                for (File awoSoFile : awoSoFiles) {\n                    if (!awoSoFile.exists()) {\n                        throw new IllegalArgumentException(\n                            \"awoSoFile file \" + awoSoFile.getAbsolutePath() + \" does not exist.\");\n                    }\n\n                    installPatchIfDeviceConnected(androidBuilder, awoSoFile, packageName, logger, awoSoFile.getName());\n                }\n            }\n            notifyApppatching(androidBuilder, packageName, logger);\n        } catch (Throwable e) {\n            throw new GradleException(\"install awo error\", e);\n        }\n    }\n\n    public static void installAwoSo(AndroidBuilder androidBuilder, File awoSoFile, String packageName, Logger logger,\n                                    String name) {\n\n        try {\n            installPatchIfDeviceConnected(androidBuilder, awoSoFile, packageName, logger, name);\n            notifyApppatching(androidBuilder, packageName, logger);\n        } catch (Throwable e) {\n            throw new GradleException(\"install awo error\", e);\n        }\n    }\n\n    /**\n     * no device or too many device make install fail\n     *\n     * @param name\n     * @param patch\n     * @return\n     */\n    private static boolean installPatchIfDeviceConnected(AndroidBuilder androidBuilder, File patch, String patchPkg,\n                                                         Logger logger, String name) {\n\n        final AndroidDebugBridge androidDebugBridge = initAndroidDebugBridge(androidBuilder);\n\n        if (!androidDebugBridge.isConnected()) {\n            throw new RuntimeException(\"Android Debug Bridge is not connected.\");\n        }\n\n        waitForInitialDeviceList(androidDebugBridge, logger);\n        List<IDevice> devices = Arrays.asList(androidDebugBridge.getDevices());\n        String PATCH_INSTALL_DIRECTORY = String.format(\"%s%s%s\", PATCH_INSTALL_DIRECTORY_PREFIX, patchPkg,\n                                                       PATCH_INSTALL_DIRECTORY_SUFFIX);\n        if (devices.size() == 0) {\n            throw new RuntimeException(String.format(\"%s%s%s%s%s\",\n                                                     \"no device connected,please check whether the connection is \"\n                                                     + \"successful or copy \", patch,\n                                                     \" in build/outputs/awbs/libxxx.so \", PATCH_INSTALL_DIRECTORY,\n                                                     \" and restart you app\"));\n        }\n        if (devices.size() > 1) {\n            throw new RuntimeException(\"too much devices be connected,please disconnect the others and try again\");\n        }\n        CommandExecutor executor = CommandExecutor.Factory.createDefaultCommmandExecutor();\n        executor.setLogger(logger);\n        executor.setCaptureStdOut(true);\n        executor.setCaptureStdErr(true);\n        List<String> cmd = Arrays.asList(\"push\", patch.getAbsolutePath(), PATCH_INSTALL_DIRECTORY + name);\n        try {\n            executor.executeCommand(androidBuilder.getSdkInfo().getAdb().getAbsolutePath(), cmd, false);\n            return true;\n        } catch (ExecutionException e) {\n            throw new RuntimeException(\"Error while trying to push patch to device \", e);\n        } finally {\n            String errout = executor.getStandardError();\n            if ((errout != null) && (errout.trim().length() > 0)) {\n                logger.error(errout);\n            }\n        }\n    }\n\n    protected static AndroidDebugBridge initAndroidDebugBridge(AndroidBuilder androidBuilder) {\n        synchronized (ADB_LOCK) {\n            if (!adbInitialized) {\n                DdmPreferences.setTimeOut(adbConnectionTimeout);\n                AndroidDebugBridge.init(false);\n                adbInitialized = true;\n            }\n            AndroidDebugBridge androidDebugBridge = AndroidDebugBridge.createBridge(\n                androidBuilder.getSdkInfo().getAdb().getAbsolutePath(), false);\n            waitUntilConnected(androidDebugBridge);\n            return androidDebugBridge;\n        }\n    }\n\n    private static void waitUntilConnected(AndroidDebugBridge adb) {\n        int trials = 10;\n        final int connectionWaitTime = 50;\n        while (trials > 0) {\n            try {\n                Thread.sleep(connectionWaitTime);\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n            if (adb.isConnected()) {\n                break;\n            }\n            trials--;\n        }\n    }\n\n    /**\n     * Wait for the Android Debug Bridge to return an initial device list.\n     */\n    protected static void waitForInitialDeviceList(final AndroidDebugBridge androidDebugBridge, Logger logger) {\n        if (!androidDebugBridge.hasInitialDeviceList()) {\n            logger.info(\"Waiting for initial device list from the Android Debug Bridge\");\n            long limitTime = System.currentTimeMillis() + ADB_TIMEOUT_MS;\n            while (!androidDebugBridge.hasInitialDeviceList() && (System.currentTimeMillis() < limitTime)) {\n                try {\n                    Thread.sleep(1000);\n                } catch (InterruptedException e) {\n                    throw new RuntimeException(\"Interrupted waiting for initial device list from Android Debug Bridge\");\n                }\n            }\n            if (!androidDebugBridge.hasInitialDeviceList()) {\n                logger.error(\"Did not receive initial device list from the Android Debug Bridge.\");\n            }\n        }\n    }\n\n    /**\n     * todo how know which app will be debugged?\n     * just support taobao.apk now\n     */\n    private static void notifyApppatching(AndroidBuilder androidBuilder, String patchPkg, Logger logger) {\n        CommandExecutor executor = CommandExecutor.Factory.createDefaultCommmandExecutor();\n        executor.setLogger(logger);\n        executor.setCaptureStdOut(true);\n        executor.setCaptureStdErr(true);\n        //        List<String> killCmd = Arrays.asList(\"shell\", \"am\", \"force-stop\", packageNameForPatch);\n        //        List<String> startCmd = Arrays.asList(\"shell\", \"am\", \"start\", packageNameForPatch + \"/\" +\n        // launcherActivityForPatch);\n        List<String> patchCmd = Arrays.asList(\"shell\", \"am\", \"broadcast\", \"-a\", \"com.taobao.atlas.intent.PATCH_APP\",\n                                              \"-e\", \"pkg\", patchPkg, \"-n\",\n                                              patchPkg + \"/com.taobao.atlas.update.AwoPatchReceiver\");\n        try {\n            executor.executeCommand(androidBuilder.getSdkInfo().getAdb().getAbsolutePath(), patchCmd, false);\n        } catch (Exception e) {\n            throw new RuntimeException(\"error while restarting app,you can also restart by yourself\", e);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/execution/SkipExecuter.java",
    "content": "package com.taobao.android.builder.tasks.execution;\n\nimport com.google.common.collect.ImmutableList;\nimport org.gradle.api.internal.TaskInternal;\nimport org.gradle.api.internal.tasks.TaskExecuter;\nimport org.gradle.api.internal.tasks.TaskExecutionContext;\nimport org.gradle.api.internal.tasks.TaskExecutionOutcome;\nimport org.gradle.api.internal.tasks.TaskStateInternal;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * SkipUpdateToDateExecuter\n *\n * @author zhayu.ll\n * @date 18/3/1\n */\npublic class SkipExecuter implements TaskExecuter{\n\n    private static final Logger LOGGER = LoggerFactory.getLogger(SkipExecuter.class);\n\n    private TaskExecuter executer;\n\n    public SkipExecuter(TaskExecuter executer) {\n        this.executer = executer;\n    }\n    public void execute(TaskInternal task, TaskStateInternal state, TaskExecutionContext context) {\n        LOGGER.info(\"skip SkipExecuter\");\n        executer.execute(task, state, context);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/feature/FeatureLibManifestTask.java",
    "content": "package com.taobao.android.builder.tasks.feature;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.FeatureVariantContext;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.dsl.CoreBuildType;\nimport com.android.build.gradle.internal.dsl.CoreProductFlavor;\nimport com.android.build.gradle.internal.scope.BuildOutput;\nimport com.android.build.gradle.internal.scope.BuildOutputs;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.tasks.DefaultAndroidTask;\nimport com.android.build.gradle.tasks.MergeManifests;\nimport com.android.builder.core.VariantConfiguration;\nimport com.android.manifmerger.ManifestProvider;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport com.taobao.android.builder.tools.manifest.ManifestInfo;\nimport org.dom4j.DocumentException;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.artifacts.ArtifactCollection;\nimport org.gradle.api.artifacts.result.ResolvedArtifactResult;\nimport org.gradle.api.file.FileCollection;\nimport org.gradle.api.tasks.Internal;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Set;\n\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactScope.ALL;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactScope.MODULE;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactType.MANIFEST;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactType.METADATA_APP_ID_DECLARATION;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactType.METADATA_FEATURE_MANIFEST;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ConsumedConfigType.METADATA_VALUES;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ConsumedConfigType.RUNTIME_CLASSPATH;\nimport static com.taobao.android.builder.tasks.app.manifest.StandardizeLibManifestTask.getManifestFileObject;\n\n/**\n * FeatureLibManifestTask\n *\n * @author zhayu.ll\n * @date 18/1/4\n * @time 下午4:28\n * @description  \n */\npublic class FeatureLibManifestTask extends DefaultAndroidTask{\n\n\n    private ArtifactCollection manifests;\n    private FileCollection packageManifest;\n    private ArtifactCollection featureManifests;\n    private FeatureVariantContext featureVariantContext;\n    private File mainManifestFile;\n    private VariantConfiguration variantConfiguration;\n\n    @Internal\n    public VariantConfiguration getVariantConfiguration() {\n        return variantConfiguration;\n    }\n\n    public void setVariantConfiguration(\n            VariantConfiguration<CoreBuildType, CoreProductFlavor, CoreProductFlavor> variantConfiguration) {\n        this.variantConfiguration = variantConfiguration;\n    }\n\n\n    @TaskAction\n    public void taskAction() throws DocumentException, IOException {\n\n        mainManifestFile = variantConfiguration.getMainManifest();\n        ManifestInfo mainManifestFileObject = getManifestFileObject(mainManifestFile);\n        final Set<ResolvedArtifactResult> artifacts = manifests.getArtifacts();\n        List<ManifestProvider> providers = Lists.newArrayListWithCapacity(artifacts.size() + 2);\n        for (ResolvedArtifactResult artifact : artifacts) {\n            File manifestFile = artifact.getFile();\n            File modifyManifest = featureVariantContext.getModifiedManifest(artifact);\n            ManifestFileUtils.updatePreProcessManifestFile(modifyManifest, manifestFile, mainManifestFileObject,\n                    true, featureVariantContext.getAtlasExtension()\n                            .getTBuildConfig().isIncremental());\n            providers.add(new MergeManifests.ConfigAction.ManifestProviderImpl(\n                    modifyManifest,\n                    MergeManifests.getArtifactName(artifact)));\n        }\n\n\n        if (featureManifests != null) {\n            final Set<ResolvedArtifactResult> featureArtifacts = featureManifests.getArtifacts();\n            for (ResolvedArtifactResult artifact : featureArtifacts) {\n                File directory = artifact.getFile();\n                File modifyManifest = featureVariantContext.getModifiedManifest(artifact);\n                Collection<BuildOutput> splitOutputs =\n                        BuildOutputs.load(VariantScope.TaskOutputType.MERGED_MANIFESTS, directory);\n                if (splitOutputs.isEmpty()) {\n                    throw new GradleException(\"Could not load manifest from \" + directory);\n                }\n                ManifestFileUtils.updatePreProcessManifestFile(modifyManifest, splitOutputs.iterator().next().getOutputFile(), mainManifestFileObject,\n                        true, featureVariantContext.getAtlasExtension()\n                                .getTBuildConfig().isIncremental());\n\n                providers.add(\n                        new MergeManifests.ConfigAction.ManifestProviderImpl(\n                                modifyManifest,\n                                MergeManifests.getArtifactName(artifact)));\n            }\n        }\n        AtlasBuildContext.androidBuilderMap.get(getProject()).manifestProviders = providers;\n\n    }\n\n\n\n\n\n\n\n\n    public static class ConfigAction extends MtlBaseTaskAction<FeatureLibManifestTask>{\n\n        private FeatureVariantContext featureVariantContext;\n\n        public ConfigAction(VariantContext variantContext, BaseVariantOutput baseVariantOutput) {\n            super(variantContext, baseVariantOutput);\n            this.featureVariantContext = (FeatureVariantContext) variantContext;\n        }\n\n        @Override\n        public void execute(FeatureLibManifestTask task) {\n\n            task.setVariantName(variantContext.getVariantName());\n\n            task.featureVariantContext = featureVariantContext;\n            task.manifests =\n                    scope.getArtifactCollection(RUNTIME_CLASSPATH, ALL, MANIFEST);\n            task.packageManifest =\n                    scope.getArtifactFileCollection(\n                            METADATA_VALUES, MODULE, METADATA_APP_ID_DECLARATION);\n\n            final GradleVariantConfiguration config = scope.getVariantData().getVariantConfiguration();\n\n            task.setVariantConfiguration(config);\n            task.featureManifests =\n                    scope.getArtifactCollection(\n                            METADATA_VALUES, MODULE, METADATA_FEATURE_MANIFEST);\n            super.execute(task);\n        }\n\n        @Override\n        public String getName() {\n            return variantContext.getScope().getTaskName(\"feature\",\"libManifest\");\n        }\n\n        @Override\n        public Class<FeatureLibManifestTask> getType() {\n            return FeatureLibManifestTask.class;\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/feature/PrePareFeatureTask.java",
    "content": "package com.taobao.android.builder.tasks.feature;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport org.gradle.api.tasks.TaskAction;\n\nimport javax.xml.ws.Action;\n\n/**\n * PrePareFeatureTask\n *\n * @author zhayu.ll\n * @date 18/1/15\n * @time 下午4:32\n * @description  \n */\npublic class PrePareFeatureTask extends BaseTask {\n\n    private VariantContext variantContext;\n\n    @TaskAction\n    public void action(){\n\n\n    }\n\n\n\n\n\n\n    public static class ConfigAction extends MtlBaseTaskAction<PrePareFeatureTask>{\n\n        public ConfigAction(VariantContext variantContext, BaseVariantOutput baseVariantOutput) {\n            super(variantContext, baseVariantOutput);\n        }\n\n        @Override\n        public String getName() {\n            return variantContext.getBaseVariantData().getTaskName(\"prepare\",\"feature\");\n        }\n\n        @Override\n        public Class getType() {\n            return PrePareFeatureTask.class;\n        }\n\n        @Override\n        public void execute(PrePareFeatureTask task) {\n            task.setVariantName(variantContext.getVariantName());\n            task.variantContext = variantContext;\n\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/helper/AtlasListTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.helper;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.alibaba.fastjson.JSON;\n\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.tools.guide.AtlasConfigField;\nimport com.taobao.android.builder.tools.guide.AtlasConfigHelper;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.DefaultTask;\nimport org.gradle.api.Project;\nimport org.gradle.api.tasks.TaskAction;\n\n/**\n * Created by wuzhong on 2017/3/18.\n *\n * @author wuzhong\n * @date 2017/03/18\n */\npublic class AtlasListTask extends DefaultTask {\n\n    @TaskAction\n    public void executeTask() {\n\n        Project project = getProject();\n\n        AtlasExtension atlasExtension = project.getExtensions().getByType(AtlasExtension.class);\n\n        List<AtlasConfigField> list = null;\n        try {\n            list = AtlasConfigHelper.readConfig(atlasExtension, \"atlas\");\n        } catch (Throwable e) {\n            e.printStackTrace();\n            return;\n        }\n\n        List<String> lines = new ArrayList<>();\n        lines.add(\" function  | The name of the configuration |  type | value \");\n        lines.add(\" ------------- | ------------- | ------------- | ------------- \");\n\n        for (AtlasConfigField configField : list) {\n            lines.add(\n                configField.desc + \"  | \" + configField.name + \" | \" + configField.type + \"  | \"\n                    + configField.value);\n        }\n\n        for (String line : lines) {\n            project.getLogger().error(line);\n        }\n\n        File file = new File(project.getProjectDir(), \"atlasConfigList.MD\");\n\n        try {\n            FileUtils.writeLines(file, lines);\n            project.getLogger().error(file.getAbsolutePath() + \" has generated\");\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        try {\n            FileUtils.write(new File(project.getProjectDir(), \"atlasConfigList.json\"), JSON.toJSONString(list,true));\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/instantapp/AtlasBundleInstantApp.java",
    "content": "package com.taobao.android.builder.tasks.instantapp;\n\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.android.build.gradle.internal.dsl.CoreSigningConfig;\nimport com.android.build.gradle.internal.scope.*;\nimport com.android.build.gradle.internal.tasks.DefaultAndroidTask;\nimport com.android.build.gradle.internal.variant.MultiOutputPolicy;\nimport com.android.builder.signing.DefaultSigningConfig;\nimport com.android.builder.signing.SigningException;\nimport com.android.utils.FileUtils;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.sign.AndroidSigner;\nimport com.taobao.android.builder.tools.zip.BetterZip;\nimport org.apache.commons.compress.utils.IOUtils;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.*;\nimport java.util.Enumeration;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\nimport java.util.zip.ZipInputStream;\nimport java.util.zip.ZipOutputStream;\n\nimport static com.android.SdkConstants.DOT_ANDROID_PACKAGE;\nimport static com.android.SdkConstants.DOT_ZIP;\n\npublic class AtlasBundleInstantApp extends DefaultAndroidTask {\n\n    private File apkFile;\n\n    private File bundleDirectory;\n    private String bundleName;\n    private VariantScope scope;\n    private static Pattern excludePattern = Pattern.compile(\"^(META-INF/)\\\\w*\");\n    private static Pattern apkPattern = Pattern.compile(\"libcom_\\\\w*(.so)$\");\n\n\n    @TaskAction\n    public void taskAction() throws IOException {\n        FileUtils.mkdirs(bundleDirectory);\n        File bundleFile = new File(bundleDirectory, bundleName);\n        FileUtils.deleteIfExists(bundleFile);\n        File baseFeatureApk = new File(bundleDirectory, \"baseFeature.apk\");\n        if (!apkFile.exists()){\n            File[]apkFiles = apkFile.getParentFile().listFiles(new FileFilter() {\n                @Override\n                public boolean accept(File pathname) {\n                    return pathname.getName().endsWith(\".apk\");\n                }\n            });\n            if (apkFiles != null){\n                apkFile = apkFiles[0];\n            }\n        }\n        if (apkFile.exists()) {\n            try {\n                make(baseFeatureApk, apkFile, bundleFile, scope.getVariantConfiguration().getSigningConfig());\n            } catch (SigningException e) {\n                e.printStackTrace();\n            }\n        }else {\n            getLogger().error(apkFile.getAbsolutePath()+\" is not exist!\");\n        }\n    }\n\n\n    private void make(File baseFeatureApk, File apkFile, File bundleFile, CoreSigningConfig signingConfig) throws IOException, SigningException {\n        ZipFile zipFile = new ZipFile(apkFile);\n        Enumeration entries = zipFile.entries();\n        ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(bundleFile));\n        ZipOutputStream baseFeatureStream = new ZipOutputStream(new FileOutputStream(baseFeatureApk));\n        while (entries.hasMoreElements()) {\n            ZipEntry zipEntry = (ZipEntry) entries.nextElement();\n            if (excludePattern.matcher(zipEntry.getName()).find()) {\n                continue;\n            } else if (apkPattern.matcher(zipEntry.getName()).find()) {\n                byte[] inputBuffer = IOUtils.toByteArray(zipFile.getInputStream(zipEntry));\n                zipOutputStream.putNextEntry(new ZipEntry(zipEntry.getName().substring(zipEntry.getName().lastIndexOf(\"/\") + 1).replace(\".so\", DOT_ANDROID_PACKAGE)));\n                zipOutputStream.write(inputBuffer, 0, inputBuffer.length);\n                zipOutputStream.closeEntry();\n            } else {\n                byte[] inputBuffer = IOUtils.toByteArray(zipFile.getInputStream(zipEntry));\n                if (zipEntry.getMethod() == ZipEntry.STORED) {\n                    baseFeatureStream.putNextEntry(new ZipEntry(zipEntry));\n                } else {\n                    baseFeatureStream.putNextEntry(new ZipEntry(zipEntry.getName()));\n\n                }\n                baseFeatureStream.write(inputBuffer, 0, inputBuffer.length);\n                baseFeatureStream.closeEntry();\n            }\n        }\n        baseFeatureStream.close();\n        zipOutputStream.close();\n        AndroidSigner androidSigner = new AndroidSigner();\n        File signedApk = new File(baseFeatureApk.getParentFile(), \"baseFeature-signed.apk\");\n        androidSigner.signFile(baseFeatureApk, signedApk, (DefaultSigningConfig) signingConfig);\n        BetterZip.addFile(bundleFile,\"baseFeature.apk\",signedApk);\n        FileUtils.deleteIfExists(signedApk);\n        FileUtils.deleteIfExists(baseFeatureApk);\n    }\n\n\n    public static class ConfigAction extends MtlBaseTaskAction<AtlasBundleInstantApp> {\n\n        public ConfigAction(VariantContext variantContext, BaseVariantOutput baseVariantOutput) {\n            super(variantContext, baseVariantOutput);\n        }\n\n        @NonNull\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"package\", \"AtlasInstantAppBundle\");\n        }\n\n        @NonNull\n        @Override\n        public Class<AtlasBundleInstantApp> getType() {\n            return AtlasBundleInstantApp.class;\n        }\n\n        @Override\n        public void execute(@NonNull AtlasBundleInstantApp bundleInstantApp) {\n            bundleInstantApp.setVariantName(scope.getFullVariantName());\n            final boolean splitsArePossible =\n                    scope.getOutputScope().getMultiOutputPolicy() == MultiOutputPolicy.SPLITS;\n            File finalApkLocation = scope.getApkLocation();\n            File outputDirectory =\n                    splitsArePossible\n                            ? scope.getFullApkPackagesOutputDirectory()\n                            : finalApkLocation;\n            bundleInstantApp.bundleName = scope.getGlobalScope().getProjectBaseName().concat(\"-\").concat(scope.getFullVariantName()).concat(DOT_ZIP);\n\n            bundleInstantApp.bundleDirectory = outputDirectory;\n\n            bundleInstantApp.scope = variantContext.getScope();\n\n            bundleInstantApp.apkFile = new File(outputDirectory, scope.getOutputScope().getApkDatas().get(0).getOutputFileName());\n\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/library/AndroidComponetCreator.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.library;\n\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport org.gradle.api.Project;\nimport org.gradle.api.artifacts.Configuration;\nimport org.gradle.api.internal.artifacts.publish.ArchivePublishArtifact;\nimport org.gradle.api.tasks.bundling.Zip;\n\n/**\n * Created by wuzhong on 2017/2/25.\n */\n@Deprecated\npublic class AndroidComponetCreator {\n\n    public static final String COMPILE_CONFIGURATION_NAME = \"compile\";\n\n    private AtlasExtension atlasExtension;\n\n    private Project project;\n\n    public AndroidComponetCreator(AtlasExtension atlasExtension, Project project) {\n        this.atlasExtension = atlasExtension;\n        this.project = project;\n    }\n\n    public void createAndroidComponent(Zip bundleTask) {\n        //Add a components. Android\n        if (atlasExtension.getBundleConfig().isAwbBundle()) {\n            Configuration compileConfiguration = project.getConfigurations()\n                .getByName(COMPILE_CONFIGURATION_NAME);\n            ArchivePublishArtifact bundleArtifact = new ArchivePublishArtifact(bundleTask);\n            compileConfiguration.getArtifacts().add(bundleArtifact);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/library/AwbGenerator.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.library;\n\nimport com.android.build.gradle.internal.ExtraModelInfo;\nimport com.android.build.gradle.internal.api.LibVariantContext;\nimport com.android.build.gradle.internal.ide.DependencyConvertUtils;\nimport com.android.build.gradle.options.ProjectOptions;\nimport com.android.build.gradle.tasks.AndroidZip;\nimport com.android.builder.dependency.MavenCoordinatesImpl;\nimport com.android.builder.model.MavenCoordinates;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.dependency.parser.AtlasDepTreeParser;\nimport com.taobao.android.builder.dependency.parser.ResolvedDependencyInfo;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.FilenameUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Project;\nimport org.gradle.api.tasks.bundling.Zip;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.HashSet;\n\nimport static com.android.builder.model.AndroidProject.FD_INTERMEDIATES;\n\n/**\n * Created by wuzhong on 2017/2/25.\n *\n * @author wuzhong\n */\npublic class AwbGenerator {\n\n    private final AtlasExtension atlasExtension;\n\n    public AwbGenerator(AtlasExtension atlasExtension) {\n        this.atlasExtension = atlasExtension;\n    }\n\n    /**\n     * Create a basic AWB task\n     */\n    public void generateAwbArtifict(final Zip bundleTask, LibVariantContext libVariantOutputData) {\n\n        Project project = bundleTask.getProject();\n\n        bundleTask.setExtension(\"awb\");\n\n        if (bundleTask instanceof AndroidZip) {\n            String fileName = FilenameUtils.getBaseName(bundleTask.getArchiveName()) + \".awb\";\n            ((AndroidZip) bundleTask).setArchiveNameSupplier(() -> fileName);\n\n        }\n        bundleTask.setDestinationDir(new File(bundleTask.getDestinationDir().getParentFile(), \"awb\"));\n        File destDir = libVariantOutputData.getScope().getBaseBundleDir();\n\n        bundleTask.doFirst(task -> {\n\n            File bundleBaseInfoFile = project.file(\"bundleBaseInfoFile.json\");\n            File customBundleIdFile = project.file(\"customPackageID.txt\");\n\n            if (bundleBaseInfoFile.exists()) {\n                project.getLogger().warn(\"copy \" + bundleBaseInfoFile.getAbsolutePath() + \" to awb\");\n                try {\n                    FileUtils.copyFileToDirectory(bundleBaseInfoFile, destDir);\n                } catch (IOException e) {\n                    throw new GradleException(e.getMessage(), e);\n                }\n            }\n\n            if (customBundleIdFile.exists()){\n                try {\n                    FileUtils.copyFileToDirectory(customBundleIdFile, destDir);\n                } catch (IOException e) {\n                    throw new GradleException(e.getMessage(), e);\n                }\n            }\n\n\n\n\n        });\n\n        bundleTask.doLast(task -> {\n\n            File outputFile = new File(bundleTask.getDestinationDir(), bundleTask.getArchiveName());\n\n            if (!outputFile.exists()) {\n                return;\n            }\n\n            //Regenerating aar\n            if (atlasExtension.getBundleConfig().isAwbBundle()) {\n                try {\n                    FileUtils.copyFile(outputFile,\n                                       new File(new File(bundleTask.getDestinationDir().getParentFile(), \"aar\"),\n                                                FilenameUtils.getBaseName(bundleTask.getArchiveName()) + \".aar\"));\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n            }\n        });\n    }\n\n    public AwbBundle createAwbBundle(LibVariantContext libVariantContext) throws IOException {\n\n        String variantName = libVariantContext.getVariantName();\n\n        AtlasDependencyTree libDependencyTree = AtlasBuildContext.libDependencyTrees.get(variantName);\n\n        //TODO 2.3\n        if (null == libDependencyTree) {\n\n            libDependencyTree = new AtlasDepTreeParser(libVariantContext.getProject(),\n                                                       new ExtraModelInfo(new ProjectOptions(libVariantContext.getProject()),null), new HashSet<>())\n                .parseDependencyTree(libVariantContext.getVariantDependency());\n            AtlasBuildContext.libDependencyTrees.put(variantName, libDependencyTree);\n        }\n\n        Project project = libVariantContext.getProject();\n\n        String groupName = (String)project.getGroup();\n        String name = \"\";\n        String version = (String)project.getVersion();\n        if (project.hasProperty(\"archivesBaseName\")) {\n            name = (String)project.getProperties().get(\"archivesBaseName\");\n        } else {\n            name = project.getName();\n        }\n\n        File explodedDir = project.file(\n            project.getBuildDir().getAbsolutePath() + \"/\" + FD_INTERMEDIATES + \"/exploded-awb/\" + computeArtifactPath(\n                groupName, name, version));\n        FileUtils.deleteDirectory(explodedDir);\n\n        MavenCoordinates mavenCoordinates = new MavenCoordinatesImpl(groupName, name, version, \"awb\", \"\");\n\n        ResolvedDependencyInfo resolvedDependencyInfo = new ResolvedDependencyInfo(groupName, name, version, \"awb\");\n        resolvedDependencyInfo.setVariantName(libVariantContext.getVariantName());\n\n        AwbBundle awbBundle = new AwbBundle(resolvedDependencyInfo, DependencyConvertUtils\n            .toAndroidLibrary(mavenCoordinates, libVariantContext.getBundleTask().getArchivePath(), explodedDir));\n\n        awbBundle.getSoLibraries().addAll(libDependencyTree.getMainBundle().getSoLibraries());\n        awbBundle.getAndroidLibraries().addAll(libDependencyTree.getMainBundle().getAndroidLibraries());\n        awbBundle.getJavaLibraries().addAll(libDependencyTree.getMainBundle().getJavaLibraries());\n\n        return awbBundle;\n\n    }\n\n    private String computeArtifactPath(String groupName, String name, String version) {\n        StringBuilder pathBuilder = new StringBuilder();\n        pathBuilder.append(groupName).append(\"/\").append(name).append(\"/\").append(version);\n\n        return pathBuilder.toString();\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/library/JarExtractTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.library;\n\nimport java.io.File;\n\nimport com.taobao.android.builder.tools.zip.ZipUtils;\nimport org.apache.commons.io.FilenameUtils;\nimport org.gradle.api.Action;\nimport org.gradle.api.Task;\nimport org.gradle.api.tasks.bundling.Zip;\n\n/**\n * Created by wuzhong on 2017/2/25.\n *\n * @author wuzhong\n */\npublic class JarExtractTask {\n\n    /**\n     * Create a basic AWB task\n     */\n    public void generateJarArtifict(final Zip bundleTask) {\n\n        bundleTask.doLast(new Action<Task>() {\n\n            @Override\n            public void execute(Task task) {\n\n                File outputFile = new File(bundleTask.getDestinationDir(),\n                                           bundleTask.getArchiveName());\n\n                if (!outputFile.exists()) {\n                    return;\n                }\n\n                File f = ZipUtils.extractZipFileToFolder(outputFile,\n                                                         \"classes.jar\",\n                                                         outputFile.getParentFile());\n\n                if (null != f && f.exists()) {\n                    File jar = new File(new File(bundleTask.getDestinationDir().getParentFile(), \"jar\"),\n                                        FilenameUtils.getBaseName(bundleTask.getArchiveName()) +\n                                            \".jar\");\n                    jar.getParentFile().mkdirs();\n                    f.renameTo(jar);\n\n                }\n\n            }\n        });\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/library/ModuleInfoWriter.java",
    "content": "///*\n// *\n// *\n// *\n// *                                   Apache License\n// *                             Version 2.0, January 2004\n// *                          http://www.apache.org/licenses/\n// *\n// *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n// *\n// *     1. Definitions.\n// *\n// *        \"License\" shall mean the terms and conditions for use, reproduction,\n// *        and distribution as defined by Sections 1 through 9 of this document.\n// *\n// *        \"Licensor\" shall mean the copyright owner or entity authorized by\n// *        the copyright owner that is granting the License.\n// *\n// *        \"Legal Entity\" shall mean the union of the acting entity and all\n// *        other entities that control, are controlled by, or are under common\n// *        control with that entity. For the purposes of this definition,\n// *        \"control\" means (i) the power, direct or indirect, to cause the\n// *        direction or management of such entity, whether by contract or\n// *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n// *        outstanding shares, or (iii) beneficial ownership of such entity.\n// *\n// *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n// *        exercising permissions granted by this License.\n// *\n// *        \"Source\" form shall mean the preferred form for making modifications,\n// *        including but not limited to software source code, documentation\n// *        source, and configuration files.\n// *\n// *        \"Object\" form shall mean any form resulting from mechanical\n// *        transformation or translation of a Source form, including but\n// *        not limited to compiled object code, generated documentation,\n// *        and conversions to other media types.\n// *\n// *        \"Work\" shall mean the work of authorship, whether in Source or\n// *        Object form, made available under the License, as indicated by a\n// *        copyright notice that is included in or attached to the work\n// *        (an example is provided in the Appendix below).\n// *\n// *        \"Derivative Works\" shall mean any work, whether in Source or Object\n// *        form, that is based on (or derived from) the Work and for which the\n// *        editorial revisions, annotations, elaborations, or other modifications\n// *        represent, as a whole, an original work of authorship. For the purposes\n// *        of this License, Derivative Works shall not include works that remain\n// *        separable from, or merely link (or bind by name) to the interfaces of,\n// *        the Work and Derivative Works thereof.\n// *\n// *        \"Contribution\" shall mean any work of authorship, including\n// *        the original version of the Work and any modifications or additions\n// *        to that Work or Derivative Works thereof, that is intentionally\n// *        submitted to Licensor for inclusion in the Work by the copyright owner\n// *        or by an individual or Legal Entity authorized to submit on behalf of\n// *        the copyright owner. For the purposes of this definition, \"submitted\"\n// *        means any form of electronic, verbal, or written communication sent\n// *        to the Licensor or its representatives, including but not limited to\n// *        communication on electronic mailing lists, source code control systems,\n// *        and issue tracking systems that are managed by, or on behalf of, the\n// *        Licensor for the purpose of discussing and improving the Work, but\n// *        excluding communication that is conspicuously marked or otherwise\n// *        designated in writing by the copyright owner as \"Not a Contribution.\"\n// *\n// *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n// *        on behalf of whom a Contribution has been received by Licensor and\n// *        subsequently incorporated within the Work.\n// *\n// *     2. Grant of Copyright License. Subject to the terms and conditions of\n// *        this License, each Contributor hereby grants to You a perpetual,\n// *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n// *        copyright license to reproduce, prepare Derivative Works of,\n// *        publicly display, publicly perform, sublicense, and distribute the\n// *        Work and such Derivative Works in Source or Object form.\n// *\n// *     3. Grant of Patent License. Subject to the terms and conditions of\n// *        this License, each Contributor hereby grants to You a perpetual,\n// *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n// *        (except as stated in this section) patent license to make, have made,\n// *        use, offer to sell, sell, import, and otherwise transfer the Work,\n// *        where such license applies only to those patent claims licensable\n// *        by such Contributor that are necessarily infringed by their\n// *        Contribution(s) alone or by combination of their Contribution(s)\n// *        with the Work to which such Contribution(s) was submitted. If You\n// *        institute patent litigation against any entity (including a\n// *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n// *        or a Contribution incorporated within the Work constitutes direct\n// *        or contributory patent infringement, then any patent licenses\n// *        granted to You under this License for that Work shall terminate\n// *        as of the date such litigation is filed.\n// *\n// *     4. Redistribution. You may reproduce and distribute copies of the\n// *        Work or Derivative Works thereof in any medium, with or without\n// *        modifications, and in Source or Object form, provided that You\n// *        meet the following conditions:\n// *\n// *        (a) You must give any other recipients of the Work or\n// *            Derivative Works a copy of this License; and\n// *\n// *        (b) You must cause any modified files to carry prominent notices\n// *            stating that You changed the files; and\n// *\n// *        (c) You must retain, in the Source form of any Derivative Works\n// *            that You distribute, all copyright, patent, trademark, and\n// *            attribution notices from the Source form of the Work,\n// *            excluding those notices that do not pertain to any part of\n// *            the Derivative Works; and\n// *\n// *        (d) If the Work includes a \"NOTICE\" text file as part of its\n// *            distribution, then any Derivative Works that You distribute must\n// *            include a readable copy of the attribution notices contained\n// *            within such NOTICE file, excluding those notices that do not\n// *            pertain to any part of the Derivative Works, in at least one\n// *            of the following places: within a NOTICE text file distributed\n// *            as part of the Derivative Works; within the Source form or\n// *            documentation, if provided along with the Derivative Works; or,\n// *            within a display generated by the Derivative Works, if and\n// *            wherever such third-party notices normally appear. The contents\n// *            of the NOTICE file are for informational purposes only and\n// *            do not modify the License. You may add Your own attribution\n// *            notices within Derivative Works that You distribute, alongside\n// *            or as an addendum to the NOTICE text from the Work, provided\n// *            that such additional attribution notices cannot be construed\n// *            as modifying the License.\n// *\n// *        You may add Your own copyright statement to Your modifications and\n// *        may provide additional or different license terms and conditions\n// *        for use, reproduction, or distribution of Your modifications, or\n// *        for any such Derivative Works as a whole, provided Your use,\n// *        reproduction, and distribution of the Work otherwise complies with\n// *        the conditions stated in this License.\n// *\n// *     5. Submission of Contributions. Unless You explicitly state otherwise,\n// *        any Contribution intentionally submitted for inclusion in the Work\n// *        by You to the Licensor shall be under the terms and conditions of\n// *        this License, without any additional terms or conditions.\n// *        Notwithstanding the above, nothing herein shall supersede or modify\n// *        the terms of any separate license agreement you may have executed\n// *        with Licensor regarding such Contributions.\n// *\n// *     6. Trademarks. This License does not grant permission to use the trade\n// *        names, trademarks, service marks, or product names of the Licensor,\n// *        except as required for reasonable and customary use in describing the\n// *        origin of the Work and reproducing the content of the NOTICE file.\n// *\n// *     7. Disclaimer of Warranty. Unless required by applicable law or\n// *        agreed to in writing, Licensor provides the Work (and each\n// *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n// *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n// *        implied, including, without limitation, any warranties or conditions\n// *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n// *        PARTICULAR PURPOSE. You are solely responsible for determining the\n// *        appropriateness of using or redistributing the Work and assume any\n// *        risks associated with Your exercise of permissions under this License.\n// *\n// *     8. Limitation of Liability. In no event and under no legal theory,\n// *        whether in tort (including negligence), contract, or otherwise,\n// *        unless required by applicable law (such as deliberate and grossly\n// *        negligent acts) or agreed to in writing, shall any Contributor be\n// *        liable to You for damages, including any direct, indirect, special,\n// *        incidental, or consequential damages of any character arising as a\n// *        result of this License or out of the use or inability to use the\n// *        Work (including but not limited to damages for loss of goodwill,\n// *        work stoppage, computer failure or malfunction, or any and all\n// *        other commercial damages or losses), even if such Contributor\n// *        has been advised of the possibility of such damages.\n// *\n// *     9. Accepting Warranty or Additional Liability. While redistributing\n// *        the Work or Derivative Works thereof, You may choose to offer,\n// *        and charge a fee for, acceptance of support, warranty, indemnity,\n// *        or other liability obligations and/or rights consistent with this\n// *        License. However, in accepting such obligations, You may act only\n// *        on Your own behalf and on Your sole responsibility, not on behalf\n// *        of any other Contributor, and only if You agree to indemnify,\n// *        defend, and hold each Contributor harmless for any liability\n// *        incurred by, or claims asserted against, such Contributor by reason\n// *        of your accepting any such warranty or additional liability.\n// *\n// *     END OF TERMS AND CONDITIONS\n// *\n// *     APPENDIX: How to apply the Apache License to your work.\n// *\n// *        To apply the Apache License to your work, attach the following\n// *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n// *        replaced with your own identifying information. (Don't include\n// *        the brackets!)  The text should be enclosed in the appropriate\n// *        comment syntax for the file format. We also recommend that a\n// *        file or class name and description of purpose be included on the\n// *        same \"printed page\" as the copyright notice for easier\n// *        identification within third-party archives.\n// *\n// *     Copyright 2016 Alibaba Group\n// *\n// *     Licensed under the Apache License, Version 2.0 (the \"License\");\n// *     you may not use this file except in compliance with the License.\n// *     You may obtain a copy of the License at\n// *\n// *         http://www.apache.org/licenses/LICENSE-2.0\n// *\n// *     Unless required by applicable law or agreed to in writing, software\n// *     distributed under the License is distributed on an \"AS IS\" BASIS,\n// *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// *     See the License for the specific language governing permissions and\n// *     limitations under the License.\n// *\n// *\n// */\n//\n//package com.taobao.android.builder.tasks.library;\n//\n//import java.io.File;\n//import java.util.List;\n//\n//import com.alibaba.fastjson.JSON;\n//\n//import com.android.build.gradle.api.LibraryVariant;\n//import com.android.builder.model.SourceProvider;\n//import com.taobao.android.builder.tasks.awo.projectstrucure.ModuleInfo;\n//import org.apache.commons.io.FileUtils;\n//import org.gradle.api.Project;\n//\n///**\n// * Created by wuzhong on 2017/2/25.\n// */\n//@Deprecated\n//public class ModuleInfoWriter {\n//\n//    private Project project;\n//\n//    private LibraryVariant libraryVariant;\n//\n//    public ModuleInfoWriter(Project project, LibraryVariant libraryVariant) {\n//        this.project = project;\n//        this.libraryVariant = libraryVariant;\n//    }\n//\n//    public void write() {\n//        //Generate the basic information for the project\n//        try {\n//            ModuleInfo moduleInfo = new ModuleInfo();\n//            moduleInfo.group = project.getGroup().toString();\n//            moduleInfo.name = project.getName();\n//            moduleInfo.version = project.getVersion().toString();\n//\n//            moduleInfo.path = project.getProjectDir()\n//                .getAbsolutePath()\n//                .replace(project.getRootDir().getAbsolutePath(), \"\")\n//                .substring(1);\n//\n//            //Access to the android manifst\n//            moduleInfo.packageName = libraryVariant.getApplicationId();\n//\n//            List<SourceProvider> sourceProviders = libraryVariant.getSourceSets();\n//\n//            for (SourceProvider sourceProvider : sourceProviders) {\n//\n//                for (File java : sourceProvider.getJavaDirectories()) {\n//                    if (java.exists()) {\n//                        moduleInfo.java_SrcDirs.add(java.getAbsolutePath());\n//                    }\n//                }\n//\n//                for (File res : sourceProvider.getResDirectories()) {\n//                    if (res.exists()) {\n//                        moduleInfo.res_srcDirs.add(res.getAbsolutePath());\n//                    }\n//                }\n//\n//                for (File assets : sourceProvider.getAssetsDirectories()) {\n//                    if (assets.exists()) {\n//                        moduleInfo.assets_srcDirs.add(assets.getAbsolutePath());\n//                    }\n//                }\n//            }\n//\n//            File moduleInfoFile = new File(project.getRootDir(), \".awo/\" + moduleInfo.name + \".mi\");\n//            moduleInfoFile.getParentFile().mkdirs();\n//\n//            FileUtils.write(moduleInfoFile, JSON.toJSONString(moduleInfo, true));\n//        } catch (Throwable e) {\n//            e.printStackTrace();\n//        }\n//    }\n//}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/library/publish/PublishHooker.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.library.publish;\n\nimport com.taobao.android.builder.tasks.maven.PublishToMavenRepositoryHook;\n\nimport org.gradle.api.Action;\nimport org.gradle.api.Project;\nimport org.gradle.api.Task;\nimport org.gradle.api.publish.maven.tasks.PublishToMavenRepository;\nimport org.gradle.api.publish.plugins.PublishingPlugin;\nimport org.gradle.api.tasks.TaskContainer;\n\n/**\n * Created by wuzhong on 2017/2/9.\n */\npublic class PublishHooker {\n\n    PublishToMavenRepository publishTask = null;\n\n    PublishToMavenRepositoryHook hookTask = null;\n\n    private Project project;\n\n    public PublishHooker(Project project) {\n        this.project = project;\n    }\n\n    public void hookPublish() {\n\n        project.getTasks().whenTaskAdded(new Action<Task>() {\n            @Override\n            public void execute(Task task) {\n                if (\"publishMavenPublicationToMavenRepository\".equals(task.getName())) {\n                    publishTask = (PublishToMavenRepository) task;\n                    task.setEnabled(false);\n\n                    if (null != hookTask) {\n                        hookTask.setRepository(publishTask.getRepository());\n                        hookTask.setPublication(publishTask.getPublication());\n                    }\n                }\n            }\n        });\n\n        final TaskContainer tasks = project.getTasks();\n        Task publishLifecycleTask = tasks.findByName(PublishingPlugin.PUBLISH_LIFECYCLE_TASK_NAME);\n\n        if (null == publishLifecycleTask){\n            return;\n        }\n\n        String taskName = \"publishMavenPublicationToMavenRepositoryHook\";\n        hookTask = tasks.create(taskName,\n                                PublishToMavenRepositoryHook.class,\n                                new Action<PublishToMavenRepositoryHook>() {\n                                    public void execute(PublishToMavenRepositoryHook publishTask) {\n                                        publishTask.setGroup(PublishingPlugin.PUBLISH_TASK_GROUP);\n                                    }\n                                });\n\n        publishLifecycleTask.dependsOn(taskName);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/library/publish/UpdatePomTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.library.publish;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.function.Consumer;\n\nimport com.android.build.gradle.LibraryPlugin;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.IOUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.dom4j.Document;\nimport org.dom4j.DocumentException;\nimport org.dom4j.Element;\nimport org.dom4j.io.OutputFormat;\nimport org.dom4j.io.SAXReader;\nimport org.dom4j.io.XMLWriter;\nimport org.gradle.api.Action;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Project;\nimport org.gradle.api.Task;\nimport org.gradle.api.artifacts.Dependency;\nimport org.gradle.api.artifacts.DependencySet;\nimport org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency;\nimport org.gradle.api.publish.maven.tasks.GenerateMavenPom;\n\n/**\n * Created by wuzhong on 2017/2/9.\n *\n * Update the pom dependencies type and scope\n *\n * @author wuzhong\n */\npublic class UpdatePomTask {\n\n    private Project project;\n\n    public UpdatePomTask(Project project) {\n        this.project = project;\n    }\n\n    public void updatePom() {\n\n        project.getTasks().whenTaskAdded(new Action<Task>() {\n            @Override\n            public void execute(Task task) {\n\n                if (\"generatePomFileForMavenPublication\".equals(task.getName())) {\n\n                    GenerateMavenPom generateMavenPom = (GenerateMavenPom)task;\n\n                    generateMavenPom.doLast(new Action<Task>() {\n                        @Override\n                        public void execute(Task task) {\n\n                            try {\n                                updatePomXml(generateMavenPom.getDestination());\n                            } catch (Throwable e) {\n                                throw new GradleException(e.getMessage(), e);\n                            }\n\n                        }\n                    });\n\n                }\n\n            }\n        });\n\n    }\n\n    private void updatePomXml(File xml) throws IOException, DocumentException {\n\n        Map<String, DependencyExtraInfo> extraInfoMap = getExtraMap();\n\n        File backupFile = new File(xml.getParentFile(), \"pom-backup.xml\");\n        FileUtils.deleteQuietly(backupFile);\n\n        FileUtils.moveFile(xml, backupFile);\n\n        XMLWriter writer = null;// Declares the object that writes XML\n        SAXReader reader = new SAXReader();\n        OutputFormat format = OutputFormat.createPrettyPrint();\n        format.setEncoding(\"UTF-8\");// Sets the encoding format for the XML file\n        FileOutputStream fos = new FileOutputStream(xml);\n\n        try {\n            Document document = reader.read(backupFile);// Read the XML file\n\n            Element dependencies = document.getRootElement().element(\"dependencies\");\n\n            if ((null != dependencies) && null != dependencies.elements()) {\n                List<Element> list = dependencies.elements();\n\n                for (Element element : list) {\n\n                    List<Element> itemList = element.elements();\n\n                    String group = \"\";\n                    String name = \"\";\n                    String type;\n                    String scope;\n\n                    Element scopeEl = null;\n                    Element typeEl = null;\n\n                    for (Element element1 : itemList) {\n                        if (\"groupId\".equals(element1.getQName().getName())) {\n                            group = element1.getStringValue();\n                        } else if (\"artifactId\".equals(element1.getQName().getName())) {\n                            name = element1.getStringValue();\n                        } else if (\"scope\".equals(element1.getQName().getName())) {\n                            scope = element1.getStringValue();\n                            scopeEl = element1;\n                        } else if (\"type\".equals(element1.getQName().getName())) {\n                            type = element1.getStringValue();\n                            typeEl = element1;\n                        }\n                    }\n\n                    DependencyExtraInfo dependencyExtraInfo = extraInfoMap.get(group + \":\" + name);\n                    if (null == dependencyExtraInfo) {\n                        continue;\n                    }\n\n                    //update scope\n                    if (StringUtils.isNotEmpty(dependencyExtraInfo.scope)) {\n                        if (null != scopeEl) {\n                            scopeEl.setText(dependencyExtraInfo.scope);\n                        } else {\n                            Element newEl = element.addElement(\"scope\");\n                            newEl.setText(dependencyExtraInfo.scope);\n                        }\n                    }\n\n                    if (StringUtils.isNotEmpty(dependencyExtraInfo.type)) {\n                        if (null != typeEl) {\n                            typeEl.setText(dependencyExtraInfo.type);\n                        } else {\n                            Element newEl = element.addElement(\"type\");\n                            newEl.setText(dependencyExtraInfo.type);\n                        }\n                    }\n\n                }\n            }\n\n            writer = new XMLWriter(fos, format);\n            writer.write(document);\n\n        } finally {\n            if (null != writer) {\n                writer.close();\n            }\n            IOUtils.closeQuietly(fos);\n        }\n\n    }\n\n    private Map<String, DependencyExtraInfo> getExtraMap() {\n\n        Map<String, DependencyExtraInfo> dependencyExtraInfoMap = new HashMap<>();\n\n        DependencySet dependencies = project.getConfigurations().getByName(\"compile\").getDependencies();\n\n        dependencies.forEach(new Consumer<Dependency>() {\n            @Override\n            public void accept(Dependency dependency) {\n\n                String group = dependency.getGroup();\n                String name = dependency.getName();\n                String scope = \"compile\";\n                String type = \"\";\n                if (dependency instanceof DefaultProjectDependency) {\n                    DefaultProjectDependency projectDependency = (DefaultProjectDependency)dependency;\n                    if (projectDependency.getDependencyProject().getPlugins().hasPlugin(LibraryPlugin.class)) {\n                        type = \"aar\";\n                    }\n                }\n\n                dependencyExtraInfoMap.put(group + \":\" + name, new DependencyExtraInfo(type, scope));\n\n            }\n        });\n\n        return dependencyExtraInfoMap;\n\n    }\n\n    private static class DependencyExtraInfo {\n\n        String type;\n        String scope;\n\n        public DependencyExtraInfo(String type, String scope) {\n            this.type = type;\n            this.scope = scope;\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/manager/AbstractBundleTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.manager;\n\nimport java.io.File;\n\nimport com.android.build.gradle.internal.tasks.IncrementalTask;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport org.gradle.api.tasks.Input;\nimport org.gradle.api.tasks.InputFile;\nimport org.gradle.api.tasks.Optional;\n\n/**\n * Created by wuzhong on 2017/4/9.\n */\npublic abstract class AbstractBundleTask extends IncrementalTask {\n\n    protected AwbBundle awbBundle;\n\n    @Input\n    @Optional\n    protected String getBundleVersion() {\n        return awbBundle.getResolvedCoordinates().getVersion();\n    }\n\n    @InputFile\n    protected File getManifest() {\n        return awbBundle.getAndroidLibrary().getManifest();\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/manager/MtlBaseTaskAction.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.manager;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.android.build.gradle.internal.scope.TaskConfigAction;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.tasks.DefaultAndroidTask;\nimport com.android.build.gradle.internal.variant.BaseVariantData;\nimport org.apache.commons.lang3.reflect.FieldUtils;\nimport org.gradle.api.Task;\nimport org.gradle.api.tasks.StopExecutionException;\n\nimport java.lang.reflect.Field;\n\n/**\n * Created by wuzhong on 16/7/5.\n */\npublic abstract class MtlBaseTaskAction<T extends Task> implements TaskConfigAction<T> {\n\n    protected VariantScope scope;\n\n    protected VariantContext variantContext;\n\n    protected BaseVariantData baseVariantData;\n\n    protected  BaseVariantOutput baseVariantOutput;\n\n    public MtlBaseTaskAction(VariantContext variantContext,\n                             BaseVariantOutput baseVariantOutput) {\n        this.variantContext = variantContext;\n        this.baseVariantData = variantContext.getBaseVariantData();\n        this.scope = baseVariantData.getScope();\n        this.baseVariantOutput = baseVariantOutput;\n    }\n\n    protected AppVariantOutputContext getAppVariantOutputContext() {\n\n        if (!(variantContext instanceof AppVariantContext)) {\n            return null;\n        }\n\n        AppVariantContext appVariantContext = (AppVariantContext) variantContext;\n\n        AppVariantOutputContext appVariantOutputContext = (AppVariantOutputContext) appVariantContext\n                .getOutputContextMap()\n                .get(ApkDataUtils.get(baseVariantOutput).getFullName());\n\n        if (null == appVariantOutputContext) {\n            appVariantOutputContext = new AppVariantOutputContext(ApkDataUtils.get(baseVariantOutput).getFullName(),\n                                                                  appVariantContext,\n                    ApkDataUtils.get(baseVariantOutput),\n                                                                  baseVariantData);\n            appVariantContext.getOutputContextMap()\n                    .put(ApkDataUtils.get(baseVariantOutput).getFullName(), appVariantOutputContext);\n        }\n\n        return appVariantOutputContext;\n    }\n\n    @Override\n    public void execute(T task) {\n\n        if (task instanceof DefaultAndroidTask) {\n            DefaultAndroidTask defaultAndroidTask = (DefaultAndroidTask) task;\n            defaultAndroidTask.setVariantName(baseVariantData\n                                                      .getVariantConfiguration()\n                                                      .getFullName());\n        }\n\n        //        ConventionMappingHelper.map(task, \"appVariantContext\", new Callable<AppVariantContext>() {\n        //            @Override\n        //            public AppVariantContext call() throws Exception {\n        //                return appVariantContext;\n        //            }\n        //        });\n        //\n        //        ConventionMappingHelper.map(task, \"baseVariantOutputData\", new Callable<BaseVariantOutputData>() {\n        //            @Override\n        //            public BaseVariantOutputData call() throws Exception {\n        //                return baseVariantOutputData;\n        //            }\n        //        });\n\n    }\n\n    protected void setFieldValueByReflection(Task task, String fieldName, Object value) {\n        Field field = FieldUtils.getField(task.getClass(), fieldName, true);\n        if (null == field) {\n            throw new StopExecutionException(\"The field with name:\" +\n                                                     fieldName +\n                                                     \" does not existed in class:\" +\n                                                     task.getClass().getName());\n        }\n        try {\n            FieldUtils.writeField(field, task, value, true);\n        } catch (IllegalAccessException e) {\n            throw new StopExecutionException(e.getMessage());\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/manager/MtlParallelTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.manager;\n\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.ide.common.internal.WaitableExecutor;\nimport org.apache.commons.lang3.StringUtils;\nimport org.gradle.api.DefaultTask;\nimport org.gradle.api.internal.project.DefaultProject;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.util.List;\nimport java.util.concurrent.Callable;\n\n/**\n * Created by wuzhong on 2016/10/13.\n */\npublic class MtlParallelTask extends BaseTask {\n\n    public String uniqueTaskName;\n\n    public List<DefaultTask> parallelTask;\n\n    public boolean concurrent = true;\n\n\n    WaitableExecutor waitableExecutor = WaitableExecutor.useGlobalSharedThreadPool();\n\n    @TaskAction\n    void run() {\n\n        if (null == parallelTask || parallelTask.isEmpty()) {\n            return;\n        }\n\n        if (concurrent) {\n\n            String taskName = uniqueTaskName;\n            if (StringUtils.isEmpty(taskName)) {\n                taskName = parallelTask.get(0).getClass().getSimpleName();\n            }\n\n            parallelTask.forEach(task -> waitableExecutor.execute((Callable) () -> {\n                task.execute();\n                return null;\n            }));\n\n            try {\n                waitableExecutor.waitForTasksWithQuickFail(true);\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n\n\n        } else {\n            for (final DefaultTask task : parallelTask) {\n                task.execute();\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/manager/MtlTaskContext.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.manager;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport org.gradle.api.Project;\nimport org.gradle.api.Task;\n\nimport java.util.List;\n\n/**\n * Created by wuzhong on 16/6/24.\n */\npublic class MtlTaskContext {\n\n    private boolean isSystemTask;\n\n    private Class<? extends Task> sysTaskClazz;\n\n    private Task sysTask;\n\n    private Class<? extends MtlBaseTaskAction> taskActionClazz;\n\n    private String taskName;\n\n    private TaskFilter taskFilter;\n\n\n    public MtlTaskContext(Class<? extends Task> taskClass) {\n        this.sysTaskClazz = taskClass;\n        this.isSystemTask = true;\n    }\n\n    public MtlTaskContext(Task sysTask) {\n        this.sysTask = sysTask;\n        this.isSystemTask = true;\n    }\n\n    public MtlTaskContext(String taskName) {\n        this.taskName = taskName;\n        this.isSystemTask = true;\n    }\n\n    /**\n     * Add custom tasks\n     *\n     * @param taskActionClazz\n     * @param taskFilter\n     */\n    public MtlTaskContext(Class<? extends MtlBaseTaskAction> taskActionClazz, TaskFilter taskFilter) {\n        this.taskActionClazz = taskActionClazz;\n        this.taskFilter = taskFilter;\n    }\n\n    public boolean isSystemTask() {\n        return isSystemTask;\n    }\n\n    public void setSystemTask(boolean systemTask) {\n        isSystemTask = systemTask;\n    }\n\n    public Class<? extends Task> getSysTaskClazz() {\n        return sysTaskClazz;\n    }\n\n    public void setSysTaskClazz(Class<Task> sysTaskClazz) {\n        this.sysTaskClazz = sysTaskClazz;\n    }\n\n    public Class<? extends MtlBaseTaskAction> getTaskActionClazz() {\n        return taskActionClazz;\n    }\n\n    public void setTaskActionClazz(Class<MtlBaseTaskAction> taskActionClazz) {\n        this.taskActionClazz = taskActionClazz;\n    }\n\n    public String getTaskName() {\n        return taskName;\n    }\n\n    public void setTaskName(String taskName) {\n        this.taskName = taskName;\n    }\n\n    public TaskFilter getTaskFilter() {\n        return taskFilter;\n    }\n\n    public void setTaskFilter(TaskFilter taskFilter) {\n        this.taskFilter = taskFilter;\n    }\n\n    public static interface TaskFilter {\n        public List<Task> getBeforeTasks(Project project, BaseVariantOutput vod);\n    }\n\n    public Task getSysTask() {\n        return sysTask;\n    }\n\n    public void setSysTask(Task sysTask) {\n        this.sysTask = sysTask;\n    }\n\n    @Override\n    public String toString() {\n        return \"MtlTaskContext{\" +\n                \"isSystemTask=\" + isSystemTask +\n                \", sysTaskClazz=\" + sysTaskClazz +\n                \", taskActionClazz=\" + taskActionClazz +\n                \", taskName='\" + taskName + '\\'' +\n                \", taskFilter=\" + taskFilter +\n                '}';\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/manager/MtlTaskFactory.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.manager;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport org.gradle.api.Task;\n\n/**\n * Created by wuzhong on 16/6/24.\n */\npublic interface MtlTaskFactory {\n\n    Task createTask(VariantContext variantContext, BaseVariantOutput vod, Class<? extends MtlBaseTaskAction> baseTaskAction);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/manager/MtlTaskFactoryImpl.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.manager;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Task;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.lang.reflect.Constructor;\n\n/**\n * Created by wuzhong on 16/7/5.\n */\npublic class MtlTaskFactoryImpl implements MtlTaskFactory {\n\n    private static Logger sLogger = LoggerFactory.getLogger(MtlTaskFactory.class);\n\n    @Override\n    public Task createTask(VariantContext variantContext, BaseVariantOutput vod,\n                           Class<? extends MtlBaseTaskAction> baseTaskAction) {\n\n        if (null == baseTaskAction) {\n            return null;\n        }\n\n        try {\n\n            MtlBaseTaskAction mtlBaseTaskAction = getConstructor(baseTaskAction, variantContext.getClass()).newInstance(\n                variantContext, vod);\n\n            Task task = variantContext.getProject().getTasks().findByName(mtlBaseTaskAction.getName());\n\n            if (null == task) {\n                task = variantContext.getProject().getTasks().create(mtlBaseTaskAction.getName(),\n                                                                     mtlBaseTaskAction.getType());\n                mtlBaseTaskAction.execute(task);\n            } else {\n                sLogger.info(mtlBaseTaskAction.getName() + \" is already added\");\n            }\n\n            return task;\n\n        } catch (Throwable e) {\n            //sLogger.error(\"add task exception\", e);\n            throw new GradleException(e.getMessage(),e);\n        }\n\n        //return null;\n    }\n\n    private Constructor<? extends MtlBaseTaskAction> getConstructor(Class<? extends MtlBaseTaskAction> baseTaskAction,\n                                                                    Class variantClazz) throws NoSuchMethodException {\n\n        try {\n            return baseTaskAction.getConstructor(variantClazz, BaseVariantOutput.class);\n        } catch (NoSuchMethodException ex1) {\n\n            Class superClazz = variantClazz.getSuperclass();\n\n            if (null != superClazz) {\n                return getConstructor(baseTaskAction, superClazz);\n            } else {\n                throw ex1;\n            }\n\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/manager/MtlTaskInjector.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.manager;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.build.gradle.internal.tasks.DefaultAndroidTask;\nimport com.android.builder.core.AndroidBuilder;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.Project;\nimport org.gradle.api.Task;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * Created by wuzhong on 16/6/24.\n */\npublic class MtlTaskInjector {\n\n    private Project project;\n    private VariantContext variantContext;\n    private MtlTaskFactory mtlTaskFactory;\n\n    public MtlTaskInjector(VariantContext variantContext) {\n        this.variantContext = variantContext;\n        this.project = variantContext.getProject();\n        this.mtlTaskFactory = new MtlTaskFactoryImpl();\n    }\n\n    public void injectTasks(List<MtlTaskContext> mtlTaskContexts, AndroidBuilder androidBuilder) {\n\n        Collection<BaseVariantOutput> baseVariantOutputDataList = variantContext.getVariantOutputData();\n\n        for (final BaseVariantOutput vod : baseVariantOutputDataList) {\n\n            //TODO What if the intermediate step does not generate task\n            List<Task> beforeTasks = new ArrayList<Task>();\n\n            for (MtlTaskContext mtlTaskContext : mtlTaskContexts) {\n\n                //Get the task instance\n                List<Task> tasks = new ArrayList<Task>();\n                if (mtlTaskContext.isSystemTask()) {\n                    if (null != mtlTaskContext.getSysTask()) {\n                        tasks.add(mtlTaskContext.getSysTask());\n                    } else if (null != mtlTaskContext.getSysTaskClazz()) {\n                        Class taskClazz = mtlTaskContext.getSysTaskClazz();\n                        tasks.addAll(findTask(taskClazz, variantContext.getVariantName() ));\n                    } else {\n                        Task task = project.getTasks().findByName(\n                            variantContext.getBaseVariantData().getTaskName(mtlTaskContext.getTaskName(),\"\"));\n                        if (null != task) {\n                            tasks.add(task);\n                        }\n                    }\n                } else {\n                    Task task = mtlTaskFactory.createTask(variantContext, vod, mtlTaskContext.getTaskActionClazz());\n                    if (null != task) {\n\n                        if (null != androidBuilder && task instanceof BaseTask) {\n                            ((BaseTask)task).setAndroidBuilder(androidBuilder);\n                        }\n\n                        tasks.add(task);\n                    }\n                }\n\n                if (tasks.isEmpty()) {\n                    //                    throw new RuntimeException(\"task is not found \" + mtlTaskContext);\n                    project.getLogger().info(\"task is not found \" + vod.getName() + mtlTaskContext);\n                } else {\n                    if (!beforeTasks.isEmpty()) {\n                        for (Task task : tasks) {\n                            project.getLogger().debug(\n                                \"[MtlTaskInjector]\" + vod.getName() + \":\" + task + \"->\" + StringUtils\n                                    .join(beforeTasks.toArray()));\n                            for (Task before : beforeTasks) {\n                                project.getLogger().info(\n                                    \"[tasks] set task \" + task.getProject().getName() + \":\" + task.getName() + \"->\"\n                                        + before.getProject().getName() + \":\" + before.getName());\n                                task.dependsOn(before);\n                            }\n                        }\n                    }\n                    beforeTasks.clear();\n                    beforeTasks.addAll(tasks);\n\n                    if (null != mtlTaskContext.getTaskFilter()) {\n                        List<Task> beforeTasks2 = mtlTaskContext.getTaskFilter().getBeforeTasks(project, vod);\n                        for (Task task : tasks) {\n                            project.getLogger().debug(\n                                \"[MtlTaskInjector]\" + vod.getName() + \":\" + task + \"->\" + StringUtils\n                                    .join(beforeTasks2.toArray()));\n                            for (Task before : beforeTasks2) {\n                                project.getLogger().info(\n                                    \"[tasks] set task \" + task.getProject().getName() + \":\" + task.getName() + \"->\"\n                                        + before.getProject().getName() + \":\" + before.getName());\n                                task.dependsOn(before);\n                            }\n                        }\n                    }\n                }\n\n            }\n        }\n    }\n\n    protected List<Task> findTask(Class<Task> clazz, String variantName) {\n        Task[] androidTasks = project.getTasks().withType(clazz).toArray(new Task[0]);\n        List<Task> taskList = new ArrayList();\n        for (Task task : androidTasks) {\n            if (task.getName().endsWith(\"TestJavaWithJavac\")){\n                continue;\n            }\n            if (variantName.contains(\"-\")){\n                variantName = variantName.replace(\"-\",\"\");\n            }\n            if (task instanceof DefaultAndroidTask) {\n\n                if (variantName.toLowerCase().equals(((DefaultAndroidTask)task).getVariantName().toLowerCase())) {\n                    taskList.add(task);\n                }\n            } else {\n                String name = task.getName();\n                if (name.toLowerCase().contains(variantName.toLowerCase())) {\n                    taskList.add(task);\n                }\n            }\n        }\n        return taskList;\n    }\n\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/manager/TaskCreater.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.manager;\n\nimport org.gradle.api.Project;\nimport org.gradle.api.Task;\n\n/**\n * Created by wuzhong on 2016/10/20.\n */\npublic class TaskCreater {\n\n    public static synchronized <T extends Task> T create(Project project, String name, Class<T> type) {\n        return project.getTasks().create(name, type);\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/manager/TaskQueryHelper.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.manager;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.android.build.gradle.internal.tasks.DefaultAndroidTask;\nimport com.android.build.gradle.internal.variant.BaseVariantData;\nimport org.gradle.api.Project;\nimport org.gradle.api.Task;\n\n/**\n * Created by wuzhong on 16/6/26.\n */\npublic class TaskQueryHelper<T extends Task> {\n\n    public static <T extends Task> List<T> findTask(Project project, Class<T> clazz, BaseVariantData vod) {\n\n        Task[] androidTasks = project.getTasks().withType(clazz).toArray(new Task[0]);\n\n        String variantName = vod.getName();\n\n        List<Task> taskList = new ArrayList();\n        for (Task task : androidTasks) {\n            if (task instanceof DefaultAndroidTask) {\n                if (variantName.equals(((DefaultAndroidTask)task).getVariantName())) {\n                    taskList.add(task);\n                }\n            } else {\n\n                String name = task.getName();\n                if (name.toLowerCase().contains(variantName)) {\n                    taskList.add(task);\n                }\n            }\n\n        }\n        return (List<T>)taskList;\n    }\n\n    public static <T> List<T> findTask(Project project, Class<? extends Task> clazz) {\n        Task[] androidTasks = project.getTasks().withType(clazz).toArray(new Task[0]);\n        List<Task> taskList = new ArrayList();\n        for (Task task : androidTasks) {\n            taskList.add(task);\n        }\n        return (List<T>)taskList;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/manager/transform/MtlInjectTransform.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.manager.transform;\n\nimport com.android.build.api.transform.Format;\nimport com.android.build.api.transform.JarInput;\nimport com.android.build.api.transform.TransformOutputProvider;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.pipeline.InjectTransform;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.ide.common.build.ApkData;\nimport com.taobao.android.builder.tools.FileNameUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.File;\n\n/**\n * Created by wuzhong on 2016/11/30.\n */\npublic abstract class MtlInjectTransform extends InjectTransform {\n\n    private static Logger logger = LoggerFactory.getLogger(MtlInjectTransform.class);\n\n    protected VariantScope scope;\n    protected AppVariantContext appVariantContext;\n    protected ApkData apkData;\n\n    public MtlInjectTransform(AppVariantContext appVariantContext, ApkData apkData) {\n        this.appVariantContext = appVariantContext;\n        this.apkData= apkData;\n        this.scope = appVariantContext.getScope();\n    }\n\n    @Override\n    public boolean updateNextTransformInput() {\n        return true;\n    }\n\n    protected AppVariantOutputContext getAppVariantOutputContext() {\n\n        AppVariantOutputContext appVariantOutputContext = (AppVariantOutputContext)appVariantContext\n            .getOutputContextMap().get(apkData.getFullName());\n\n        if (null == appVariantOutputContext) {\n            appVariantOutputContext =\n                new AppVariantOutputContext(apkData.getFullName(), appVariantContext,\n                        apkData, scope.getVariantData());\n            appVariantContext.getOutputContextMap().put(apkData.getFullName(), appVariantOutputContext);\n        }\n\n        return appVariantOutputContext;\n    }\n\n    protected File getOutputFile(TransformOutputProvider outputProvider, JarInput jarInput) {\n\n        if (null != logger) {\n            logger.debug(\"[ClassInject]\" + jarInput.getFile().getAbsolutePath());\n        }\n\n        return outputProvider.getContentLocation(getUniqueJarName(jarInput),\n                                                 jarInput.getContentTypes(),\n                                                 jarInput.getScopes(),\n                                                 Format.JAR);\n\n    }\n\n    protected String getUniqueJarName(JarInput jarInput) {\n\n        return FileNameUtils.getUniqueJarName(jarInput.getFile());\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/manager/transform/MtlTransformContext.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.manager.transform;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.android.build.api.transform.Transform;\n\n/**\n * Created by wuzhong on 16/6/24.\n */\npublic class MtlTransformContext {\n\n    private Class<? extends MtlInjectTransform> transformTask;\n\n    private List<Class<? extends Transform>> beforeClazzList = new ArrayList<Class<? extends Transform>>();\n\n    public MtlTransformContext(Class<? extends MtlInjectTransform> transformTask, Class<? extends Transform>... clazz) {\n        this.transformTask = transformTask;\n        if (null != clazz) {\n            for (Class<? extends Transform> cl : clazz) {\n                beforeClazzList.add(cl);\n            }\n        }\n    }\n\n    public Class<? extends MtlInjectTransform> getTransformTask() {\n        return transformTask;\n    }\n\n    public List<Class<? extends Transform>> getBeforeClazzList() {\n        return beforeClazzList;\n    }\n\n    @Override\n    public String toString() {\n        return \"MtlTransformContext{\" +\n            \"transformTask=\" + transformTask +\n            \", beforeClazzList=\" + beforeClazzList +\n            '}';\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/manager/transform/MtlTransformInjector.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.manager.transform;\n\nimport com.android.build.VariantOutput;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.pipeline.TransformTask;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Project;\nimport org.gradle.api.tasks.TaskCollection;\n\nimport java.util.List;\n\n/**\n * Created by wuzhong on 2016/11/30.\n */\npublic class MtlTransformInjector {\n\n    private Project project;\n    private AppVariantContext appVariantContext;\n\n    public MtlTransformInjector(AppVariantContext appVariantContext) {\n        this.appVariantContext = appVariantContext;\n        this.project = appVariantContext.getProject();\n    }\n\n    public void injectTasks(List<MtlTransformContext> mtlTaskContexts) {\n\n\n\n        for (final Object vod : appVariantContext.getVariantOutputData()) {\n\n            for (MtlTransformContext mtlTransformContext : mtlTaskContexts) {\n\n                TransformTask transformTask = findTransformTask(mtlTransformContext);\n\n                TransformTask injectedTask = appVariantContext.getInjectTransformManager()\n                    .addInjectTransformBeforeTransform(transformTask.getTransform().getClass(),\n                                                       TransformManager.createTransform(appVariantContext,\n                                                                                        mtlTransformContext\n                                                                                            .getTransformTask(), (BaseVariantOutput) vod),\n                                                       appVariantContext.getScope());\n\n                injectedTask.dependsOn(appVariantContext.getVariantData().compileTask);\n\n            }\n\n        }\n\n    }\n\n    private TransformTask findTransformTask(MtlTransformContext mtlTransformContext) {\n\n        for (Class clazz : mtlTransformContext.getBeforeClazzList()) {\n            TransformTask transformTask = findTransformTask(clazz);\n            if (null != transformTask) {\n                return transformTask;\n            }\n        }\n\n        throw new GradleException(\"transform task is not found \" + mtlTransformContext);\n\n    }\n\n    private TransformTask findTransformTask(Class transformClazz) {\n\n        TaskCollection<TransformTask> androidTasks = project.getTasks().withType(TransformTask.class);\n\n        for (TransformTask transformTask : androidTasks) {\n            if (transformTask.getTransform().getClass().equals(transformClazz)) {\n\n                if (appVariantContext.getVariantData().getName().equals(transformTask.getVariantName())) {\n                    return transformTask;\n                }\n            }\n        }\n\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/manager/transform/TransformManager.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.manager.transform;\n\nimport com.android.build.api.transform.Transform;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.android.build.gradle.internal.pipeline.TransformTask;\nimport com.android.builder.core.VariantConfiguration;\nimport com.android.ide.common.build.ApkData;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport org.apache.commons.lang.reflect.FieldUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.tasks.TaskCollection;\n\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.util.List;\nimport java.util.SortedMap;\n\npublic class TransformManager {\n\n    public static List<TransformTask> findTransformTaskByTransformType(VariantContext appVariantContext, Class<?>\n        transformClass) {\n        List<TransformTask> transformTasksList = Lists.newArrayList();\n        VariantConfiguration config = appVariantContext.getVariantConfiguration();\n        TaskCollection<TransformTask> transformTasks = appVariantContext.getProject().getTasks().withType(\n            TransformTask.class);\n        SortedMap<String, TransformTask> transformTaskSortedMap = transformTasks.getAsMap();\n        String variantName = config.getFullName();\n        for (String taskName : transformTaskSortedMap.keySet()) {\n            TransformTask transformTask = transformTaskSortedMap.get(taskName);\n            if (variantName == transformTask.getVariantName()) {\n                if (transformTask.getTransform().getClass() == transformClass) {\n                    transformTasksList.add(transformTask);\n                }\n            }\n        }\n        return transformTasksList;\n    }\n\n\n\n    public static <T extends Transform> T createTransform(AppVariantContext appVariantContext,\n                                                          Class<T> clazz, BaseVariantOutput vod) {\n\n        if (null == clazz) {\n            return null;\n        }\n        try {\n\n            return (T)getConstructor(appVariantContext, clazz,ApkDataUtils.get(vod)).newInstance(\n                appVariantContext, ApkDataUtils.get(vod));\n\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n        return null;\n\n    }\n\n    private static Constructor<? extends Transform> getConstructor(AppVariantContext appVariantContext,\n                                                                   Class<? extends Transform>\n                                                                           transformClazz, ApkData apkData)\n        throws NoSuchMethodException {\n        try {\n            return transformClazz.getConstructor(appVariantContext.getClass(),ApkData.class);\n        } catch (NoSuchMethodException e) {\n            return transformClazz.getConstructor(appVariantContext.getClass().getSuperclass(),ApkData.class);\n        }\n    }\n\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/maven/PublishToMavenRepositoryHook.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.maven;\n\nimport org.gradle.api.GradleException;\nimport org.gradle.api.Incubating;\nimport org.gradle.api.InvalidUserDataException;\nimport org.gradle.api.artifacts.repositories.MavenArtifactRepository;\nimport org.gradle.api.internal.artifacts.repositories.transport.RepositoryTransportFactory;\nimport org.gradle.api.publish.internal.PublishOperation;\nimport org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal;\nimport org.gradle.api.publish.maven.internal.publisher.MavenPublisher;\nimport org.gradle.api.publish.maven.internal.publisher.MavenRemotePublisher;\nimport org.gradle.api.publish.maven.internal.publisher.StaticLockingMavenPublisher;\nimport org.gradle.api.publish.maven.internal.publisher.ValidatingMavenPublisher;\nimport org.gradle.api.publish.maven.tasks.AbstractPublishToMaven;\nimport org.gradle.api.tasks.TaskAction;\n\nimport javax.inject.Inject;\n\n/**\n * Publishes a {@link org.gradle.api.publish.maven.MavenPublication} to a {@link MavenArtifactRepository}.\n *\n * @since 1.4\n */\n@Incubating\npublic class PublishToMavenRepositoryHook extends AbstractPublishToMaven {\n\n    private MavenArtifactRepository repository;\n\n    /**\n     * The repository to publish to.\n     *\n     * @return The repository to publish to\n     */\n    public MavenArtifactRepository getRepository() {\n        return repository;\n    }\n\n    /**\n     * Sets the repository to publish to.\n     *\n     * @param repository The repository to publish to\n     */\n    public void setRepository(MavenArtifactRepository repository) {\n        this.repository = repository;\n    }\n\n    @TaskAction\n    public void publish() {\n\n        MavenPublicationInternal publicationInternal = getPublicationInternal();\n        if (publicationInternal == null) {\n            throw new InvalidUserDataException(\"The 'publication' property is required\");\n        }\n\n        MavenArtifactRepository repository = getRepository();\n        if (repository == null) {\n            throw new InvalidUserDataException(\"The 'repository' property is required\");\n        }\n\n        doPublish(publicationInternal, repository);\n    }\n\n    private void doPublish(final MavenPublicationInternal publication,\n                           final MavenArtifactRepository repository) {\n        new PublishOperation(publication, repository.getName()) {\n            @Override\n            protected void publish() throws Exception {\n\n                try {\n                    MavenPublisher remotePublisher = new MavenRemotePublisher(\n                            getLoggingManagerFactory(),\n                            getMavenRepositoryLocator(),\n                            getTemporaryDirFactory(),\n                            getRepositoryTransportFactory());\n                    MavenPublisher staticLockingPublisher = new StaticLockingMavenPublisher(\n                            remotePublisher);\n                    MavenPublisher validatingPublisher = new ValidatingMavenPublisher(\n                            staticLockingPublisher);\n\n                    validatingPublisher.publish(publication.asNormalisedPublication(), repository);\n                } catch (Throwable e) {\n\n                    String message = e.getMessage();\n                    if (message.contains(\"Could not write to resource\") &&\n                            !publication.getVersion().endsWith(\"SNAPSHOT\")) {\n                        throw new GradleException(\"Unable to deploy releaseThe release is packaged with the MTL platform\",e);\n                    }\n\n                    if (message.contains(\"status code 400\") &&\n                            !publication.getVersion().endsWith(\"SNAPSHOT\")) {\n                        throw new GradleException(\"Your release \" +\n                                                          publication.getVersion() +\n                                                          \" It already exists in the warehouse\",e);\n                    }\n\n                    if (message.contains(\"status code 413\")) {\n                        throw new GradleException(\"You post more than 200M, unable to upload\",e);\n                    }\n\n                    throw e;\n                }\n            }\n        }.run();\n    }\n\n    @Inject\n    protected RepositoryTransportFactory getRepositoryTransportFactory() {\n        throw new UnsupportedOperationException();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/tpatch/DiffBundleInfoTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.tpatch;\n\nimport com.alibaba.fastjson.JSON;\nimport com.alibaba.fastjson.JSONArray;\nimport com.alibaba.fastjson.JSONObject;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.scope.ConventionMappingHelper;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.diff.DependencyDiff;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.bundleinfo.model.BundleInfo;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport com.taobao.android.object.ArtifactBundleInfo;\nimport com.taobao.android.object.DiffType;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.dom4j.*;\nimport org.dom4j.io.SAXReader;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.tasks.*;\nimport org.gradle.api.tasks.Optional;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.concurrent.Callable;\n\n/**\n * Created by wuzhong on 16/6/24.\n */\npublic class DiffBundleInfoTask extends BaseTask {\n\n    private AppVariantOutputContext appVariantOutputContext;\n\n    private File apDir;\n\n    private File manifestFile;\n\n    private File outJsonFile;\n\n    private DependencyDiff dependencyDiff;\n\n    @OutputDirectory\n    @Optional\n    public File getOutJsonFile() {\n        return outJsonFile;\n    }\n\n    @InputFile\n    @Optional\n    public File getManifestFile() {\n        return manifestFile;\n    }\n\n    public DependencyDiff getDependencyDiff() {\n        return dependencyDiff;\n    }\n\n    @InputDirectory\n    @Optional\n    public File getApDir() {\n        return apDir;\n    }\n\n    /**\n     * Generate this file\n     */\n    @TaskAction\n    public void generate() throws IOException {\n\n        dependencyDiff = getDependencyDiff();\n\n        //If it's patch, get the diff operation\n        if (null == dependencyDiff) {\n            return;\n        }\n\n        try {\n            appVariantOutputContext.artifactBundleInfos = getArtifactBundleInfo(getDependencyDiff(),\n                                                                                getManifestFile(),\n                                                                                getApDir());\n            FileUtils.writeStringToFile(new File(getOutJsonFile(), \"dependencyDiff.json\"),\n                                        JSON.toJSONString(dependencyDiff, true));\n        } catch (Exception e) {\n            throw new GradleException(e.getMessage());\n        }\n    }\n\n    private Set<ArtifactBundleInfo> getArtifactBundleInfo(DependencyDiff dependencyDiff,\n                                                          File mainfestFile,\n                                                          File apDir) throws IOException, DocumentException {\n\n        Set<ArtifactBundleInfo> artifactBundleInfos = new HashSet<ArtifactBundleInfo>();\n        if (null == apDir) {\n            throw new GradleException(\"No Ap dependency found!\");\n        }\n        File apManifest = new File(apDir, \"AndroidManifest.xml\");\n        String apVersion = null;\n        try {\n            apVersion = ManifestFileUtils.getVersionName(apManifest);\n        } catch (Exception e) {\n            throw new GradleException(e.getMessage(), e);\n        }\n\n        Map<String,String> tagMap = new HashMap<>();\n        JSONObject jsonObject = (JSONObject)JSON.parse(FileUtils.readFileToString(new File(apDir, \"atlasFrameworkProperties.json\")));\n        JSONArray jsonArray = jsonObject.getJSONArray(\"bundleInfo\");\n        for (JSONObject obj : jsonArray.toArray(new JSONObject[0])){\n            tagMap.put(obj.getString(\"pkgName\"), obj.getString(\"unique_tag\"));\n        }\n\n\n\n        // 2. Add your own bundle\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n                appVariantOutputContext.getVariantContext().\n                        getVariantConfiguration().getFullName());\n\n        List<AwbBundle>modifyMbundles = new ArrayList<>();\n        for (AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n            BundleInfo bundleInfo = awbBundle.bundleInfo;\n            ArtifactBundleInfo awbBundleInfo = new ArtifactBundleInfo();\n            awbBundleInfo.setMainBundle(false);\n            awbBundleInfo.setDependency(newDependency(bundleInfo.getDependency(),appVariantOutputContext.getVariantContext()));\n            awbBundleInfo.setPkgName(bundleInfo.getPkgName());\n            awbBundleInfo.setApplicationName(bundleInfo.getApplicationName());\n            awbBundleInfo.setArtifactId(awbBundle.getResolvedCoordinates().getArtifactId());\n            awbBundleInfo.setName(bundleInfo.getName());\n            //History bundle's tag todo\n            awbBundleInfo.setSrcUnitTag(tagMap.get(bundleInfo.getPkgName()));\n            awbBundleInfo.setUnitTag(bundleInfo.getUnique_tag());\n            String version = bundleInfo.getVersion();\n            if (version.indexOf(\"@\") > 0) {\n                String[] arr = version.split(\"@\");\n                version = arr[arr.length - 1];\n            }\n            awbBundleInfo.setVersion(version);\n\n            //TODO\n            bundleInfo.getUnique_tag();\n\n            String libBundleName = getBundleName(awbBundle);\n            if (dependencyDiff.getAwbDiffs().contains(libBundleName)) {\n                if (dependencyDiff.getNewAwbs().contains(libBundleName)) {\n                    awbBundleInfo.setDiffType(DiffType.ADD);\n                } else {\n                    awbBundleInfo.setDiffType(DiffType.MODIFY);\n                }\n            } else {\n                awbBundleInfo.setDiffType(DiffType.NONE);\n            }\n\n            if (awbBundle.isMBundle) {\n                if (awbBundleInfo.getDiffType() == DiffType.ADD || awbBundleInfo.getDiffType() == DiffType.MODIFY) {\n                    modifyMbundles.add(awbBundle);\n                }\n                continue;\n            }\n\n            artifactBundleInfos.add(awbBundleInfo);\n        }\n\n        // 1. First add the main bundle\n        ArtifactBundleInfo mainBundleInfo = getMainArtifactBundInfo(mainfestFile);\n        mainBundleInfo.setBaseVersion(apVersion);\n        mainBundleInfo.setMainBundle(true);\n        mainBundleInfo.setVersion(appVariantOutputContext.getVariantContext()\n                .getVariantConfiguration()\n                .getVersionName());\n        if (dependencyDiff.getMainDexDiffs().size() > 0 || modifyMbundles.size() > 0) {\n            mainBundleInfo.setDiffType(DiffType.MODIFY);\n        } else {\n            mainBundleInfo.setDiffType(DiffType.NONE);\n        }\n\n        mainBundleInfo.setSrcUnitTag(jsonObject.getString(\"unit_tag\"));\n        mainBundleInfo.setUnitTag(appVariantOutputContext.getVariantContext().unit_tag);\n\n        artifactBundleInfos.add(mainBundleInfo);\n\n        return artifactBundleInfos;\n    }\n\n    private List<String> newDependency(List<String> dependency,AppVariantContext appVariantContext) {\n        List<String>dependencies = new ArrayList<>();\n        if (appVariantContext.getAtlasExtension().getTBuildConfig().getAllBundlesToMdex()||dependency == null ||dependency.size() == 0){\n            return dependencies;\n        }\n        for (String s:dependency){\n            if (!appVariantContext.getAtlasExtension().getTBuildConfig().getBundleToMdex().contains(s)){\n                dependencies.add(s);\n            }\n        }\n        return dependencies;\n\n    }\n\n    private String getBundleName(AwbBundle libraryDependency) {\n        return libraryDependency.getResolvedCoordinates().getGroupId() +\n                \":\" +\n                libraryDependency.getResolvedCoordinates().getArtifactId();\n    }\n\n    private static ArtifactBundleInfo getMainArtifactBundInfo(File manifestFile) {\n        ArtifactBundleInfo mainBundleInfo = new ArtifactBundleInfo();\n        SAXReader reader = new SAXReader();\n        Document document = null;// Read the XML file\n        try {\n            document = reader.read(manifestFile);\n        } catch (DocumentException e) {\n            throw new GradleException(e.getMessage(), e);\n        }\n        Element root = document.getRootElement();// Get the root node\n\n        List<? extends Node> metadataNodes = root.selectNodes(\"//meta-data\");\n        for (Node node : metadataNodes) {\n            Element element = (Element) node;\n            Attribute attribute = element.attribute(\"name\");\n            if (attribute.getValue().equals(\"label\")) {\n                Attribute labelAttribute = element.attribute(\"value\");\n                mainBundleInfo.setName(labelAttribute.getValue());\n            }\n        }\n\n        List<? extends Node> applicatNodes = root.selectNodes(\"//application\");\n        for (Node node : applicatNodes) {\n            Element element = (Element) node;\n            Attribute attribute = element.attribute(\"name\");\n            if (attribute != null) {\n                mainBundleInfo.setApplicationName(attribute.getValue());\n            }\n        }\n\n        if (\"manifest\".equalsIgnoreCase(root.getName())) {\n            List<Attribute> attributes = root.attributes();\n            for (Attribute attr : attributes) {\n                if (StringUtils.equalsIgnoreCase(attr.getName(), \"versionName\")) {\n                    String versionName = attr.getValue();\n                    mainBundleInfo.setVersion(versionName);\n                }\n            }\n        }\n        String pkgName = root.attributeValue(\"package\");\n        mainBundleInfo.setPkgName(pkgName);\n        return mainBundleInfo;\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<DiffBundleInfoTask> {\n\n        private AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext,\n                            BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n            this.appVariantContext = appVariantContext;\n        }\n\n        /**\n         * Return the name of the task to be configured.\n         */\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"diffBundleInfo\");\n        }\n\n        /**\n         * Return the class type of the task to be configured.\n         */\n        @Override\n        public Class<DiffBundleInfoTask> getType() {\n            return DiffBundleInfoTask.class;\n        }\n\n        /**\n         * Performs this action against the given object.\n         *\n         * @param diffBundleInfoTask The object to perform the action on.\n         */\n        @Override\n        public void execute(DiffBundleInfoTask diffBundleInfoTask) {\n\n            super.execute(diffBundleInfoTask);\n\n            if (!appVariantContext.getAtlasExtension().isAtlasEnabled()){\n                diffBundleInfoTask.setEnabled(false);\n            }\n\n            final GradleVariantConfiguration config = scope\n                    .getVariantConfiguration();\n\n            ConventionMappingHelper.map(diffBundleInfoTask, \"outJsonFile\", new Callable<File>() {\n                @Override\n                public File call() throws Exception {\n                    File file = scope.getGlobalScope().getOutputsDir();\n                    if (!file.exists()) {\n                        file.mkdirs();\n                    }\n                    return file;\n                }\n            });\n\n            ConventionMappingHelper.map(diffBundleInfoTask, \"manifestFile\", new Callable<File>() {\n                @Override\n                public File call() throws Exception {\n                    return com.android.utils.FileUtils.join(baseVariantOutput.getProcessManifest().getManifestOutputDirectory(), new String[]{baseVariantOutput.getDirName(), \"AndroidManifest.xml\"});\n                }\n            });\n\n            //Set the DependencyDiff\n            ConventionMappingHelper.map(diffBundleInfoTask,\n                                        \"dependencyDiff\",\n                                        new Callable<DependencyDiff>() {\n                                            @Override\n                                            public DependencyDiff call() throws Exception {\n                                                return appVariantContext.getDependencyDiff();\n                                            }\n                                        });\n\n            ConventionMappingHelper.map(diffBundleInfoTask, \"apDir\", new Callable<File>() {\n                @Override\n                public File call() throws Exception {\n\n                    if (null != appVariantContext.apContext.getApExploredFolder() &&\n                            appVariantContext.apContext.getApExploredFolder().exists()) {\n                        return appVariantContext.apContext.getApExploredFolder();\n                    }\n                    return null;\n                }\n            });\n\n            diffBundleInfoTask.appVariantOutputContext = getAppVariantOutputContext();\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/tpatch/PackageTPatchConfigAction.java",
    "content": "package com.taobao.android.builder.tasks.tpatch;\n\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.VariantContext;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport org.gradle.api.tasks.Sync;\n\n/**\n * Created by chenhjohn on 2017/5/13.\n */\n\npublic class PackageTPatchConfigAction extends MtlBaseTaskAction<Sync> {\n    public PackageTPatchConfigAction(VariantContext variantContext, BaseVariantOutput baseVariantOutputData) {\n        super(variantContext, baseVariantOutputData);\n    }\n\n    @NonNull\n    @Override\n    public String getName() {\n        return scope.getTaskName(\"package\", \"TPatch\");\n    }\n\n    @NonNull\n    @Override\n    public Class<Sync> getType() {\n        return Sync.class;\n    }\n\n    @Override\n    public void execute(@NonNull Sync packageRenderscript) {\n        packageRenderscript.from(getAppVariantOutputContext().getApkOutputFile(true));\n        packageRenderscript.from(((AppVariantContext)variantContext).getAwbApkFiles());\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/tpatch/TPatchDiffApkBuildTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.tpatch;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.scope.ConventionMappingHelper;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.taobao.android.builder.extension.PatchConfig;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.Profiler;\nimport com.taobao.android.builder.tools.zip.BetterZip;\nimport com.taobao.android.builder.tools.zip.ZipUtils;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.tasks.InputFile;\nimport org.gradle.api.tasks.OutputDirectory;\nimport org.gradle.api.tasks.OutputFile;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.File;\nimport java.util.HashMap;\nimport java.util.concurrent.Callable;\nimport java.util.zip.ZipEntry;\n\n/**\n * Created by wuzhong on 2016/9/27.\n */\npublic class TPatchDiffApkBuildTask extends BaseTask {\n\n    private File resourceFile;\n    private File apkFile;\n    private File diffAPkFile;\n\n    @TaskAction\n    public void doApkBuild() throws Exception {\n\n        //TODO Merge 2 zip packages\n        apkFile = getApkFile();\n        diffAPkFile = getDiffAPkFile();\n\n        Profiler.start(\"build tpatch apk\");\n\n        Profiler.enter(\"prepare dir\");\n        File tmpWorkDir = new File(diffAPkFile.getParentFile(), \"tmp-apk\");\n        if (tmpWorkDir.exists()) {\n            FileUtils.deleteDirectory(tmpWorkDir);\n        }\n        if (!tmpWorkDir.exists()) {\n            tmpWorkDir.mkdirs();\n        }\n\n        BetterZip.unzipDirectory(apkFile,tmpWorkDir);\n\n        //Map zipEntityMap = new HashMap();\n        //ZipUtils.unzip(apkFile, tmpWorkDir.getAbsolutePath(), \"UTF-8\", zipEntityMap, true);\n\n        FileUtils.deleteDirectory(new File(tmpWorkDir, \"assets\"));\n        FileUtils.deleteDirectory(new File(tmpWorkDir, \"res\"));\n        FileUtils.forceDelete(new File(tmpWorkDir, \"resources.arsc\"));\n        FileUtils.forceDelete(new File(tmpWorkDir, \"AndroidManifest.xml\"));\n\n        File resdir = new File(diffAPkFile.getParentFile(), \"tmp-diffResAp\");\n        resdir.mkdirs();\n        ZipUtils.unzip(getResourceFile(), resdir.getAbsolutePath(), \"UTF-8\", new HashMap<String, ZipEntry>(), true);\n\n        FileUtils.copyDirectory(resdir, tmpWorkDir);\n\n        Profiler.release();\n\n        Profiler.enter(\"rezip\");\n\n        if (getProject().hasProperty(\"atlas.createDiffApk\")) {\n            BetterZip.zipDirectory(tmpWorkDir, diffAPkFile);\n        }\n        else {\n            if (diffAPkFile.exists()){\n                FileUtils.deleteDirectory(diffAPkFile);\n            }\n            FileUtils.moveDirectory(tmpWorkDir,diffAPkFile);\n        }\n\n        //ZipUtils.rezip(diffAPkFile, tmpWorkDir, zipEntityMap);\n        Profiler.release();\n\n        FileUtils.deleteDirectory(tmpWorkDir);\n        FileUtils.deleteDirectory(resdir);\n\n        getLogger().warn(Profiler.dump());\n\n    }\n\n\n    @InputFile\n    public File getResourceFile() {\n        return resourceFile;\n    }\n\n    @InputFile\n    public File getApkFile() {\n        return apkFile;\n    }\n\n    @OutputDirectory\n    public File getDiffAPkFile() {\n        return diffAPkFile;\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<TPatchDiffApkBuildTask> {\n\n\n        public ConfigAction(AppVariantContext appVariantContext, BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"createTPatchDiffApk\");\n        }\n\n        @Override\n        public Class<TPatchDiffApkBuildTask> getType() {\n            return TPatchDiffApkBuildTask.class;\n        }\n\n        @Override\n        public void execute(TPatchDiffApkBuildTask packageApp) {\n\n            super.execute(packageApp);\n\n            PatchConfig patchConfig = variantContext.getBuildType().getPatchConfig();\n\n            if (null == patchConfig || !patchConfig.isCreateTPatch()) {\n                packageApp.setEnabled(false);\n                return;\n            }\n\n            ConventionMappingHelper.map(packageApp, \"resourceFile\", new Callable<File>() {\n                @Override\n                public File call() {\n                    return getAppVariantOutputContext().getDiffResourceAp();\n                }\n            });\n\n            ConventionMappingHelper.map(packageApp, \"apkFile\", new Callable<File>() {\n                @Override\n                public File call() {\n                    return getAppVariantOutputContext().getApkOutputFile(true);\n                }\n            });\n\n\n            ConventionMappingHelper.map(packageApp, \"diffAPkFile\", new Callable<File>() {\n                @Override\n                public File call() throws Exception {\n                    File apkFile = getAppVariantOutputContext().getDiffApk();\n                    apkFile.getParentFile().mkdirs();\n                    return apkFile;\n                }\n            });\n\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/tpatch/TPatchDiffResAPBuildTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.tpatch;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.Callable;\n\nimport com.alibaba.fastjson.JSON;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.gradle.AndroidGradleOptions;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.TaskContainerAdaptor;\nimport com.android.build.gradle.internal.aapt.AaptGeneration;\nimport com.android.build.gradle.internal.aapt.AaptGradleFactory;\nimport com.android.build.gradle.internal.api.ApContext;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.dsl.AaptOptions;\nimport com.android.build.gradle.internal.dsl.DslAdaptersKt;\nimport com.android.build.gradle.internal.scope.ConventionMappingHelper;\nimport com.android.build.gradle.internal.scope.SplitList;\nimport com.android.build.gradle.internal.scope.TaskOutputHolder;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.build.gradle.internal.variant.BaseVariantData;\nimport com.android.build.gradle.internal.variant.MultiOutputPolicy;\nimport com.android.build.gradle.options.StringOption;\nimport com.android.builder.core.AndroidBuilder;\nimport com.android.builder.core.AtlasBuilder;\nimport com.android.builder.core.VariantType;\nimport com.android.builder.internal.aapt.Aapt;\nimport com.android.builder.internal.aapt.AaptPackageConfig;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.builder.utils.FileCache;\nimport com.android.ide.common.blame.MergingLog;\nimport com.android.ide.common.blame.MergingLogRewriter;\nimport com.android.ide.common.blame.ParsingProcessOutputHandler;\nimport com.android.ide.common.blame.parser.ToolOutputParser;\nimport com.android.ide.common.blame.parser.aapt.Aapt2OutputParser;\nimport com.android.ide.common.blame.parser.aapt.AaptOutputParser;\nimport com.android.ide.common.build.ApkData;\nimport com.android.ide.common.process.ProcessException;\nimport com.android.ide.common.process.ProcessOutputHandler;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Iterators;\nimport com.taobao.android.builder.extension.PatchConfig;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.diff.DiffResExtractor;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport com.taobao.android.object.ApkFileList;\nimport org.apache.commons.beanutils.BeanUtils;\nimport org.apache.commons.io.FileUtils;\nimport org.dom4j.DocumentException;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.file.FileCollection;\nimport org.gradle.api.tasks.*;\n\nimport static com.android.build.gradle.internal.api.ApContext.APK_FILE_LIST;\n\n/**\n * Deal with the task of diff. Ap_\n * Created by wuzhong\n */\npublic class TPatchDiffResAPBuildTask extends BaseTask {\n\n    private File manifestFile;\n\n    private File baseManifestFile;\n\n    private AaptOptions aaptOptions;\n\n    private File diffResDir;\n\n    private List<? extends AndroidLibrary> libraries;\n\n    private String packageForR;\n\n    private AppVariantContext appVariantContext;\n    private FileCache fileCache;\n\n    private FileCollection splitListInput;\n    private ApkData apkData;\n\n    @OutputFile\n    public File getPackageOutputFile() {\n\n        return packageOutputFile;\n    }\n\n    private File packageOutputFile;\n\n    private VariantType type;\n\n    private boolean debuggable;\n\n    private MultiOutputPolicy multiOutputPolicy;\n\n\n    private boolean pseudoLocalesEnabled;\n\n    private Collection<String> resourceConfigs;\n\n    private Collection<String> splits;\n\n    private String preferredDensity;\n\n    private File mergeBlameLogFolder;\n\n    private String buildTargetDensity;\n\n\n    @NonNull\n    @Internal\n    private Set<String> getSplits(@NonNull SplitList splitList) throws IOException {\n        return SplitList.getSplits(splitList, multiOutputPolicy);\n    }\n\n    private boolean enforceUniquePackageName;\n\n    @TaskAction\n    protected void doAction() throws IOException {\n\n        manifestFile = getManifestFile();\n\n        aaptOptions = getAaptOptions();\n        diffResDir = getDiffResDir();\n        resourceConfigs = getResourceConfigs();\n        preferredDensity = getPreferredDensity();\n        SplitList splitList = SplitList.load(splitListInput);\n\n\n        //TODO  minifyManifest\n        File miniManifest = new File(packageOutputFile.getParentFile(), \"AndroidManifest.xml\");\n        try {\n            ManifestFileUtils.createPatchManifest(manifestFile, getBaseManifestFile(), miniManifest);\n        } catch (DocumentException e) {\n            throw new GradleException(e.getMessage());\n        }\n\n        String splitFilter = apkData.getFilter(com.android.build.OutputFile.FilterType.DENSITY);\n\n        String preferredDensity =\n                splitFilter != null\n                        ? splitFilter\n                        // if resConfigs is set, we should not use our preferredDensity.\n                        : splitList.getFilters(SplitList.RESOURCE_CONFIGS).isEmpty()\n                        ? buildTargetDensity\n                        : null;\n\n\n        File assetsFolder = new File(diffResDir, \"assets\");\n        File resFolder = new File(diffResDir, \"res\");\n\n        if (!assetsFolder.exists()) {\n            assetsFolder.mkdirs();\n        }\n        if (!resFolder.exists()) {\n            resFolder.mkdirs();\n        }\n\n\n        aaptOptions.getAdditionalParameters().add(\"-A\");\n        aaptOptions.getAdditionalParameters().add(assetsFolder.getAbsolutePath());\n        AaptGeneration aaptGeneration = AaptGeneration.fromProjectOptions(appVariantContext.getScope().getGlobalScope().getProjectOptions());\n        Aapt aapt = makeAapt(aaptGeneration);\n        AaptPackageConfig.Builder config =\n                new AaptPackageConfig.Builder()\n                        .setManifestFile(miniManifest)\n                        .setOptions(DslAdaptersKt.convert(aaptOptions))\n                        .setResourceDir(resFolder)\n                        .setLibrarySymbolTableFiles(\n                                ImmutableSet.of())\n                        .setCustomPackageForR(packageForR)\n                        .setResourceOutputApk(packageOutputFile)\n                        .setVariantType(type)\n                        .setDebuggable(debuggable)\n                        .setResourceConfigs(\n                                splitList.getFilters(SplitList.RESOURCE_CONFIGS))\n                        .setSplits(getSplits(splitList))\n                        .setPreferredDensity(preferredDensity)\n                        .setListResourceFiles(aaptGeneration == AaptGeneration.AAPT_V2);\n\n        try {\n            getBuilder().processResources(aapt, config);\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        } catch (ProcessException e) {\n            e.printStackTrace();\n        }\n\n    }\n\n\n    public static class ConfigAction extends MtlBaseTaskAction<TPatchDiffResAPBuildTask> {\n\n        private final AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext, BaseVariantOutput baseVariantOutput) {\n\n            super(appVariantContext, baseVariantOutput);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"processDiffResources\");\n        }\n\n        @Override\n        public Class<TPatchDiffResAPBuildTask> getType() {\n            return TPatchDiffResAPBuildTask.class;\n        }\n\n        @Override\n        public void execute(TPatchDiffResAPBuildTask processDiffResources) {\n\n            super.execute(processDiffResources);\n            processDiffResources.appVariantContext = appVariantContext;\n\n            processDiffResources.packageForR = baseVariantData.getVariantConfiguration().getApplicationId();\n\n            processDiffResources.fileCache = scope.getGlobalScope().getBuildCache();\n\n            processDiffResources.buildTargetDensity =\n                    scope.getGlobalScope().getProjectOptions().get(StringOption.IDE_BUILD_TARGET_DENSITY);\n\n            processDiffResources.apkData = ApkDataUtils.get(baseVariantOutput);\n\n            processDiffResources.multiOutputPolicy =\n                    scope.getVariantData().getOutputScope().getMultiOutputPolicy();\n\n            PatchConfig patchConfig = appVariantContext.getBuildType().getPatchConfig();\n            if (null == patchConfig || !patchConfig.isCreateTPatch()) {\n                processDiffResources.setEnabled(false);\n                return;\n            }\n\n            //AAPT command params\n            final BaseVariantData variantData = appVariantContext.getVariantData();\n            final GradleVariantConfiguration config = variantData.getVariantConfiguration();\n            processDiffResources.mergeBlameLogFolder = scope.getResourceBlameLogDir();\n            processDiffResources.pseudoLocalesEnabled = config.getBuildType().isPseudoLocalesEnabled();\n            //Setting ap output\n            processDiffResources.packageOutputFile = (getAppVariantOutputContext().getDiffResourceAp());\n            processDiffResources.type = (config.getType());\n            processDiffResources.debuggable = (config.getBuildType().isDebuggable());\n\n            ConventionMappingHelper.map(processDiffResources, \"manifestFile\", new Callable<File>() {\n                @Override\n                public File call() throws Exception {\n                    return new File(scope.getManifestProcessorTask().get(new TaskContainerAdaptor(scope.getGlobalScope().getProject().getTasks())).getManifestOutputDirectory(),\"AndroidManifest.xml\");\n                }\n            });\n\n            ConventionMappingHelper.map(processDiffResources, \"baseManifestFile\", new Callable<File>() {\n                @Override\n                public File call() throws Exception {\n                    return new File(appVariantContext.apContext.getApExploredFolder(), \"AndroidManifest.xml\");\n                }\n            });\n\n            ConventionMappingHelper.map(processDiffResources, \"aaptOptions\", new Callable<AaptOptions>() {\n                @Override\n                public AaptOptions call() throws Exception {\n                    //Set aapt parameters\n                    AaptOptions aaptOptions = scope.getGlobalScope().getExtension().getAaptOptions();\n                    // if (null == aaptOptions.getAdditionalParameters() || !aaptOptions.getAdditionalParameters()\n                    //     .contains(\"-B\")) {\n                    //\n                    //     PatchConfig patchConfig = appVariantContext.getBuildType().getPatchConfig();\n                    //     if (patchConfig == null || !(patchConfig.isCreateAPatch() || patchConfig.isCreateTPatch())) {\n                    //         return aaptOptions;\n                    //     }\n                    //\n                    //     AaptOptions cloneAaptOptions = new AaptOptions();\n                    //     try {\n                    //         BeanUtils.copyProperties(cloneAaptOptions, aaptOptions);\n                    //     } catch (Throwable e) {\n                    //         throw new StopExecutionException(e.getMessage());\n                    //     }\n                    //     aaptOptions = cloneAaptOptions;\n                    //\n                    //     List<String> additionParameters = aaptOptions.getAdditionalParameters();\n                    //     if (null == additionParameters) {\n                    //         additionParameters = new ArrayList<String>();\n                    //     }\n                    //     additionParameters.add(\"-B\");\n                    //     additionParameters.add(appVariantContext.apContext.getBaseApk().getAbsolutePath());\n                    // }\n                    return aaptOptions;\n                }\n            });\n\n            processDiffResources.splitListInput =\n                    scope.getOutput(TaskOutputHolder.TaskOutputType.SPLIT_LIST);\n\n\n            ConventionMappingHelper.map(processDiffResources, \"diffResDir\", new Callable<File>() {\n                @Override\n                public File call() throws Exception {\n\n                    PatchConfig patchConfig = appVariantContext.getBuildType().getPatchConfig();\n                    if (patchConfig == null) {\n                        return null;\n                    }\n\n                    File baseApk = new File(appVariantContext.apContext.getApExploredFolder(),\n                                            ApContext.AP_INLINE_APK_FILENAME);\n                    File baseApkFileList = new File(appVariantContext.apContext.getApExploredFolder(), APK_FILE_LIST);\n                    File currentApk = getAppVariantOutputContext().getApkOutputFile(true);\n\n                    if (!baseApk.exists() || !currentApk.exists() || !baseApkFileList.exists()) {\n                        return null;\n                    }\n\n                    File rawResDir = new File(scope.getGlobalScope().getIntermediatesDir(),\n                                              \"tpatch\"\n                                                  + File.separator\n                                                  + config.getFullName()\n                                                  + File.separator\n                                                  + \"raw-res\");\n                    File diffDir = new File(scope.getGlobalScope().getIntermediatesDir(),\n                                            \"tpatch\"\n                                                + File.separator\n                                                + config.getFullName()\n                                                + File.separator\n                                                + \"diff-res\");\n\n                    if (diffDir.exists()) {\n                        return diffDir;\n                    }\n\n                    diffDir.mkdirs();\n                    rawResDir.mkdirs();\n\n                    //TODO\n                    ApkFileList baseApkFiles = JSON.parseObject(FileUtils.readFileToString(baseApkFileList),\n                                                                ApkFileList.class);\n                    ApkFileList currentApkFiles = appVariantContext.getApkFiles().finalApkFileList;\n\n                    Set<String> diffFiles = new HashSet<String>();\n                    HashMap<String, String> baseFiles = baseApkFiles.getMainBundle();\n                    HashMap<String, String> newFiles = currentApkFiles.getMainBundle();\n\n                    if (null != newFiles) {\n                        for (Map.Entry<String, String> entry : newFiles.entrySet()) {\n                            String name = entry.getKey();\n                            if (name.startsWith(\"res/\")) {\n                                String md5 = entry.getValue();\n                                String baseMd5 = baseFiles.get(name);\n                                if (null == baseMd5 || !baseMd5.equals(md5)) {\n                                    diffFiles.add(name);\n                                }\n                            }\n                        }\n                    }\n\n                    FileUtils.copyDirectory(scope.getFinalResourcesDir(), new File(rawResDir, \"res\"));\n                    FileUtils.copyDirectory(variantData.mergeAssetsTask.getOutputDir(), new File(rawResDir, \"assets\"));\n\n                    DiffResExtractor.extractDiff(appVariantContext,\n                                                 diffFiles,\n                                                 currentApk,\n                                                 baseApk,\n                                                 rawResDir,\n                                                 diffDir,\n                                                 patchConfig.isFullResValues());\n\n                    return diffDir;\n                }\n            });\n        }\n    }\n\n    @InputFile\n    public File getManifestFile() {\n        return manifestFile;\n    }\n\n    @InputFile\n    public File getBaseManifestFile() {\n        return baseManifestFile;\n    }\n\n    public AaptOptions getAaptOptions() {\n        return aaptOptions;\n    }\n\n    @InputDirectory\n    public File getDiffResDir() {\n        return diffResDir;\n    }\n\n    public Collection<String> getResourceConfigs() {\n        return resourceConfigs;\n    }\n\n    public String getPreferredDensity() {\n        return preferredDensity;\n    }\n\n    private Aapt makeAapt(AaptGeneration aaptGeneration) throws IOException {\n        AndroidBuilder builder = getBuilder();\n        MergingLog mergingLog = new MergingLog(mergeBlameLogFolder);\n\n        ProcessOutputHandler processOutputHandler =\n                new ParsingProcessOutputHandler(\n                        new ToolOutputParser(\n                                aaptGeneration == AaptGeneration.AAPT_V1\n                                        ? new AaptOutputParser()\n                                        : new Aapt2OutputParser(),\n                                getILogger()),\n                        new MergingLogRewriter(mergingLog::find, builder.getErrorReporter()));\n\n        return AaptGradleFactory.make(\n                aaptGeneration,\n                builder,\n            processOutputHandler,\n            fileCache,\n            true,\n            com.android.utils.FileUtils.mkdirs(new File(appVariantContext.getScope().getIncrementalDir(getName()),\n                \"aapt-temp\")),\n                aaptOptions.getCruncherProcesses());\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/tpatch/TPatchTask.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.tpatch;\n\nimport com.alibaba.fastjson.JSON;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.TaskContainerAdaptor;\nimport com.android.build.gradle.internal.api.ApContext;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.incremental.FileType;\nimport com.android.build.gradle.internal.incremental.InstantRunBuildContext;\nimport com.android.build.gradle.internal.scope.ConventionMappingHelper;\nimport com.android.build.gradle.internal.tasks.BaseTask;\nimport com.android.builder.signing.DefaultSigningConfig;\nimport com.android.builder.signing.SigningException;\nimport com.android.utils.Pair;\nimport com.intellij.util.io.ZipUtil;\nimport com.taobao.android.PatchManager;\nimport com.taobao.android.PatchType;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.extension.TBuildType;\nimport com.taobao.android.builder.insant.InstantInfo;\nimport com.taobao.android.builder.tasks.manager.MtlBaseTaskAction;\nimport com.taobao.android.builder.tools.BuildHelper;\nimport com.taobao.android.builder.tools.MD5Util;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport com.taobao.android.builder.tools.zip.ZipUtils;\nimport com.taobao.android.inputs.BaseInput;\nimport com.taobao.android.inputs.DexPatchInput;\nimport com.taobao.android.inputs.HotPatchInput;\nimport com.taobao.android.inputs.TpatchInput;\nimport com.taobao.android.object.ApkFileList;\nimport com.taobao.android.object.ArtifactBundleInfo;\nimport com.taobao.android.object.DiffType;\nimport com.taobao.android.tpatch.model.ApkBO;\nimport com.taobao.android.tpatch.model.BundleBO;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.dom4j.DocumentException;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.tasks.Input;\nimport org.gradle.api.tasks.OutputDirectory;\nimport org.gradle.api.tasks.TaskAction;\n\nimport java.io.*;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.concurrent.Callable;\nimport java.util.function.Consumer;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\nimport java.util.zip.ZipOutputStream;\n\nimport static com.android.build.gradle.internal.api.ApContext.APK_FILE_MD5;\n\n/**\n * Dynamic deployment of the tpatch build task\n * Created by wuzhong\n */\npublic class TPatchTask extends BaseTask {\n\n    private TPatchContext patchContext;\n\n    private DefaultSigningConfig signingConfig;\n\n    private File outPatchFolder;\n\n    private File instantInfoFile;\n\n    private AppVariantContext appVariantContext;\n\n    @TaskAction\n    public void doTPatch() throws Exception {\n\n        patchContext = getPatchContext();\n        signingConfig = getSigningConfig();\n        outPatchFolder = getOutPatchFolder();\n\n        //the bundle List Copied to the outpatchFoulder\n        new File(outPatchFolder, appVariantContext.bundleListCfg.getName()).delete();\n        outPatchFolder.mkdirs();\n        FileUtils.copyFileToDirectory(appVariantContext.bundleListCfg, outPatchFolder);\n\n        // Get the container version\n        String baseApkVersion = patchContext.getBaseVersionName();\n        String newApkVersion = patchContext.versionName;\n\n        File baseApk = patchContext.getBaseApk();\n\n        File newApk = patchContext.diffApkFile;\n        boolean retainMainBundleRes = true;\n\n        if (null == newApk || !newApk.exists()) {\n            newApk = patchContext.newApk;\n            retainMainBundleRes = false;\n        }\n\n        getLogger().info(\"BaseApk:\" +\n                baseApk +\n                \",baseVersion:\" +\n                baseApkVersion +\n                \",newApk:\" +\n                newApk +\n                \",newApkVersion:\" +\n                newApkVersion);\n\n        ApkBO apkBO = new ApkBO(baseApk, baseApkVersion, baseApk.getName());\n        ApkBO newApkBO = new ApkBO(newApk, newApkVersion, newApk.getName());\n        BaseInput baseInput = createInput(apkBO, newApkBO, retainMainBundleRes);\n        if (baseInput.patchType.equals(PatchType.DEXPATCH)) {\n            List<ArtifactBundleInfo> modifyBundles = new ArrayList<ArtifactBundleInfo>();\n            baseInput.artifactBundleInfos.forEach(artifactBundleInfo -> {\n                if (artifactBundleInfo.getDiffType().equals(DiffType.MODIFY)) {\n                    modifyBundles.add(artifactBundleInfo);\n                }\n            });\n            if (modifyBundles.size() > 1) {\n                throw new Exception(\"more than 1 bundle has changed:\" + JSON.toJSONString(modifyBundles));\n            }\n        }\n        PatchManager patchManager = new PatchManager(baseInput);\n        patchManager.setLogger(getILogger());\n        getLogger().info(\"start to do patch\");\n\n        patchManager.doPatch();\n\n        getLogger().info(\"finish  do patch\");\n\n\n        try {\n\n            FileUtils.writeStringToFile(new File(getOutPatchFolder(), \"tpatch-bundles.json\"),\n                    JSON.toJSONString(patchContext.artifactBundleInfos));\n\n\n            FileUtils.forceDelete(patchContext.newApk);\n\n        } catch (Exception e) {\n            throw new GradleException(e.getMessage(), e);\n        }\n\n    }\n\n\n    private BaseInput createInput(ApkBO apkBO, ApkBO newApkBO, boolean retainMainBundleRes) throws IOException {\n        TpatchInput tpatchInput = null;\n        if (getProject().hasProperty(\"hotfix\")) {\n            tpatchInput = new HotPatchInput();\n        } else {\n            tpatchInput = new DexPatchInput();\n        }\n        tpatchInput.baseApkBo = apkBO;\n        tpatchInput.newApkBo = newApkBO;\n        tpatchInput.baseApkFileList = patchContext.getBaseApkFiles();\n        tpatchInput.newApkFileList = patchContext.getNewApkFiles(appVariantContext);\n        tpatchInput.outPatchDir = outPatchFolder;\n        tpatchInput.productName = patchContext.appSignName;\n        tpatchInput.outPutJson = new File(getOutPatchFolder(), \"patchs.json\");\n        tpatchInput.artifactBundleInfos = patchContext.artifactBundleInfos;\n        tpatchInput.diffBundleDex = true;\n        tpatchInput.newPatch = patchContext.newPatch;\n        tpatchInput.mainBundleName = patchContext.mainBundleName;\n        tpatchInput.retainMainBundleRes = retainMainBundleRes;\n        if (StringUtils.isNotBlank(patchContext.excludeFiles)) {\n            tpatchInput.notIncludeFiles = (patchContext.excludeFiles.split(\",\"));\n        }\n        if (apkBO.getVersionName().equals(newApkBO.getVersionName())) {\n            if (tpatchInput instanceof HotPatchInput) {\n                ((HotPatchInput) tpatchInput).hotClassListFile = patchContext.hotClassListFile;\n                ((HotPatchInput) tpatchInput).patchType = PatchType.HOTFIX;\n                ((HotPatchInput) tpatchInput).excludeClasses = patchContext.excludeClasses;\n\n            } else {\n                tpatchInput.patchType = PatchType.DEXPATCH;\n                ((DexPatchInput) tpatchInput).patchClasses = patchContext.patchClasses;\n                ((DexPatchInput) tpatchInput).excludeClasses = patchContext.excludeClasses;\n            }\n            tpatchInput.mainBundleName = \"com.taobao.maindex\";\n        } else {\n            tpatchInput.patchType = PatchType.TPATCH;\n            tpatchInput.createHisPatch = true;\n            tpatchInput.diffNativeSo = patchContext.diffNativeSo;\n            tpatchInput.diffBundleSo = patchContext.diffBundleSo;\n            tpatchInput.bundleWhiteList = appVariantContext.bundleListCfg;\n            tpatchInput.createAll = StringUtils.isEmpty(patchContext.tpatchHistoryUrl);\n            tpatchInput.LAST_PATCH_URL = patchContext.LAST_PATCH_URL;\n            tpatchInput.hisPatchUrl = patchContext.tpatchHistoryUrl;\n            if (null != patchContext.patchVersions) {\n                tpatchInput.versionList = patchContext.patchVersions;\n            }\n        }\n        List<Pair<BundleBO, BundleBO>> remoteBundles = new ArrayList<>();\n\n        //Get the remote bundle\n        for (AwbBundle awbBundle : AtlasBuildContext.awbBundleMap.values()) {\n            if (awbBundle.isRemote) {\n\n                File bundleFile = awbBundle.outputBundleFile;\n\n                getProject().getLogger().error(\"add bundle compare \" + bundleFile.getAbsolutePath());\n\n                BundleBO newBundleBO = new BundleBO(awbBundle.getResolvedCoordinates().getArtifactId(), bundleFile, \"\");\n\n                File baseBundleFile = new File(patchContext.apExplodeFolder, \"remotebundles/\" + bundleFile.getName());\n\n                getProject().getLogger().error(\"add bundle compare base : \" + baseBundleFile.getAbsolutePath());\n\n                BundleBO baseBundleBO = null;\n                if (baseBundleFile.exists()) {\n\n                    getProject().getLogger().error(\n                            \"add bundle compare \" + baseBundleFile.getAbsolutePath() + \"->\" + bundleFile.getAbsolutePath());\n\n                    baseBundleBO = new BundleBO(awbBundle.getResolvedCoordinates().getArtifactId(), baseBundleFile, \"\");\n                }\n                remoteBundles.add(Pair.of(baseBundleBO, newBundleBO));\n            }\n        }\n\n        if (remoteBundles.size() > 0) {\n            tpatchInput.splitDiffBundle = remoteBundles;\n        }\n        return tpatchInput;\n\n    }\n\n    private void resignBaseApk(String baseApkVersion, ApkFileList apkFileList) throws IOException, SigningException {\n        File baseVesrionApk = new File(patchContext.newApk.getParentFile(),\n                patchContext.newApk.getName()\n                        .replace(\".apk\", \"-\" + baseApkVersion + \".apk\"));\n        FileUtils.copyFile(patchContext.getBaseApk(), baseVesrionApk);\n        if (patchContext.writeBuildInfo && StringUtils.isNotEmpty(patchContext.buildId)) {\n            File buildFile = new File(getOutPatchFolder(), \"build.txt\");\n            FileUtils.writeStringToFile(buildFile,\n                    patchContext.buildId +\n                            \",\" +\n                            patchContext.versionName +\n                            \",\" +\n                            apkFileList.getMainBundle().get(\"classes.dex\"));\n            if (buildFile != null && buildFile.exists()) {\n                getLogger().info(\"add build file to apk!\");\n                BuildHelper.writeFileToApk(buildFile, baseVesrionApk, \"assets/build.txt\");\n            }\n\n            String bundleInfoFileName = \"bundleInfo-\" +\n                    appVariantContext.getVariantConfiguration().getVersionName() + \".json\";\n            File bundleInfoFile = new File(appVariantContext.getScope().getGlobalScope().getOutputsDir(),\n                    bundleInfoFileName);\n            if (bundleInfoFile.exists()) {\n                getLogger().info(\"add \" + bundleInfoFileName + \" to apk!\");\n                BuildHelper.writeFileToApk(bundleInfoFile, baseVesrionApk, \"assets/\" + bundleInfoFileName);\n            }\n\n            BuildHelper.reSign(baseVesrionApk, signingConfig);\n        }\n    }\n\n    public File getOutPatchFolder() {\n        return outPatchFolder;\n    }\n\n    public DefaultSigningConfig getSigningConfig() {\n        return signingConfig;\n    }\n\n    @Input\n    public TPatchContext getPatchContext() {\n        return patchContext;\n    }\n\n    public static class ConfigAction extends MtlBaseTaskAction<TPatchTask> {\n\n        private AppVariantContext appVariantContext;\n\n        public ConfigAction(AppVariantContext appVariantContext,\n                            BaseVariantOutput baseVariantOutputData) {\n            super(appVariantContext, baseVariantOutputData);\n            this.appVariantContext = appVariantContext;\n        }\n\n        @Override\n        public String getName() {\n            return scope.getTaskName(\"createTPatch\");\n        }\n\n        @Override\n        public Class<TPatchTask> getType() {\n            return TPatchTask.class;\n        }\n\n        @Override\n        public void execute(TPatchTask tPatchTask) {\n\n            super.execute(tPatchTask);\n\n            final TBuildType tBuildType = appVariantContext.getBuildType();\n\n            if (null == tBuildType ||\n                    null == tBuildType.getPatchConfig() ||\n                    !tBuildType.getPatchConfig().isCreateTPatch()) {\n                tPatchTask.setEnabled(false);\n                return;\n            }\n\n\n            tPatchTask.appVariantContext = appVariantContext;\n\n\n            ConventionMappingHelper.map(tPatchTask, \"outPatchFolder\", new Callable<File>() {\n\n                @Override\n                public File call() throws Exception {\n                    return getAppVariantOutputContext().getTPatchFolder();\n                }\n            });\n\n            ConventionMappingHelper.map(tPatchTask,\n                    \"signingConfig\",\n                    new Callable<DefaultSigningConfig>() {\n\n                        @Override\n                        public DefaultSigningConfig call() throws Exception {\n                            return appVariantContext.getSigningConfig();\n                        }\n                    });\n\n            ConventionMappingHelper.map(tPatchTask, \"patchContext\", new Callable<TPatchContext>() {\n\n                @Override\n                public TPatchContext call() throws Exception {\n\n                    TPatchContext tPatchContext = new TPatchContext();\n\n                    AppVariantOutputContext appVariantOutputContext = getAppVariantOutputContext();\n\n                    tPatchContext.diffApkFile = appVariantOutputContext.getDiffApk();\n                    tPatchContext.newApk = appVariantOutputContext.getApkOutputFile(true);\n                    tPatchContext.outPatchFolder = appVariantOutputContext.getTPatchFolder();\n                    tPatchContext.manifestFile = new File(scope.getManifestProcessorTask().get(new TaskContainerAdaptor(scope.getGlobalScope().getProject().getTasks())).getManifestOutputDirectory(), \"AndroidManifest.xml\");\n                    tPatchContext.apExplodeFolder = appVariantContext.apContext.getApExploredFolder();\n                    tPatchContext.versionName = ApkDataUtils.get(baseVariantOutput).getVersionName();\n                    tPatchContext.tpatchHistoryUrl = tBuildType.getPatchConfig()\n                            .getTpatchHistoryUrl();\n                    tPatchContext.hotClassListFile = tBuildType.getPatchConfig().getHotClassListFile();\n                    tPatchContext.LAST_PATCH_URL = tBuildType.getPatchConfig().getLastPatchUrl();\n                    tPatchContext.onlyBuildModifyAwb = tBuildType.getPatchConfig()\n                            .getOnlyBuildModifyAwb();\n                    tPatchContext.artifactBundleInfos = appVariantOutputContext.artifactBundleInfos;\n                    tPatchContext.notPatchBundles = tBuildType.getPatchConfig().getNoPatchBundles();\n                    tPatchContext.diffNativeSo = tBuildType.getPatchConfig().isDiffNativeSo();\n                    tPatchContext.diffBundleSo = tBuildType.getPatchConfig().isDiffBundleSo();\n                    tPatchContext.mainBundleName = tBuildType.getPatchConfig()\n                            .getTpatchMainBundleName();\n                    tPatchContext.excludeFiles = tBuildType.getPatchConfig()\n                            .gettPatchNotIncludeFiles()\n                            .isEmpty() ? \"\" : StringUtils.join(tBuildType.getPatchConfig()\n                                    .gettPatchNotIncludeFiles(),\n                            \",\");\n\n                    tPatchContext.buildId = tBuildType.getPatchConfig().getBuildId();\n\n                    tPatchContext.newPatch = tBuildType.getPatchConfig().isNewPatch();\n                    tPatchContext.writeBuildInfo = tBuildType.getPatchConfig()\n                            .isTpatchWriteBuildInfo();\n                    tPatchContext.diffBundleDex = tBuildType.getPatchConfig()\n                            .isOnlyIncrementInAwb();\n                    tPatchContext.diffMainDex = tBuildType.getPatchConfig()\n                            .isOnlyIncrementInMain();\n                    tPatchContext.excludeClasses = tBuildType.getPatchConfig()\n                            .getExcludeClasses();\n\n                    tPatchContext.patchClasses = tBuildType.getPatchConfig()\n                            .getPatchClasses();\n\n                    tPatchContext.appSignName = tBuildType.getPatchConfig().getAppSignName();\n\n                    tPatchContext.patchVersions = tBuildType.getPatchConfig().getPatchVersions();\n\n                    return tPatchContext;\n                }\n            });\n        }\n    }\n\n    public static class TPatchContext implements Serializable {\n\n        public File diffApkFile;\n\n        public File newApk;\n\n        public File outPatchFolder;\n\n        public File manifestFile;\n\n        public File apExplodeFolder;\n\n        public String versionName;\n\n        public String tpatchHistoryUrl;\n\n        public String LAST_PATCH_URL;\n\n        public Boolean onlyBuildModifyAwb;\n\n        public String notPatchBundles;\n\n        public String buildId;\n\n        public boolean newPatch = true;\n\n        public boolean diffNativeSo;\n\n        public boolean writeBuildInfo;\n\n        /**\n         * Decide whether to diff the bundle's dex file\n         */\n        public boolean diffBundleDex;\n\n\n        public Set<String> excludeClasses;\n\n        public boolean diffMainDex;\n\n        //    @Parameter(property = \"android.patch.mainBundleName\", defaultValue = \"libcom_taobao_maindex\")\n        public String mainBundleName;\n\n        public List<String> patchVersions;\n\n        public Set<ArtifactBundleInfo> artifactBundleInfos;\n\n        public Set<String> patchClasses = new HashSet<>();\n\n        /**\n         * patchDirectories that need to be excluded\n         */\n        public String excludeFiles;\n\n        public String appSignName;\n\n        public File hotClassListFile;\n\n        public boolean diffBundleSo;\n\n        public File getNewApkFiles(AppVariantContext appVariantContext) throws IOException {\n            ApkFileList apkFileList = appVariantContext.getApkFiles().finalApkFileList;\n            File apkFiles = new File(outPatchFolder.getParentFile(), APK_FILE_MD5);\n            FileUtils.writeStringToFile(apkFiles, JSON.toJSONString(apkFileList));\n            return apkFiles;\n        }\n\n        public File getBaseApk() {\n            File apkFile = new File(apExplodeFolder, ApContext.AP_INLINE_APK_FILENAME);\n            return apkFile;\n        }\n\n        public File getBaseApkFiles() {\n            File apkFileList = new File(apExplodeFolder, APK_FILE_MD5);\n            return apkFileList;\n        }\n\n        public String getBaseVersionName() throws IOException, DocumentException {\n            File apManifestFile = new File(apExplodeFolder, \"AndroidManifest.xml\");\n            String baseVersionName = ManifestFileUtils.getVersionName(apManifestFile);\n            return baseVersionName;\n        }\n    }\n\n    public static void zipPatch(File file, File dexFile) throws IOException {\n        if (!file.exists())\n            file.createNewFile();\n        BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(dexFile));\n        byte[] BUFFER = new byte[4096];\n        FileOutputStream fOutputStream = new FileOutputStream(file);\n        ZipOutputStream zoutput = new ZipOutputStream(fOutputStream);\n        ZipEntry zEntry = new ZipEntry(dexFile.getName());\n        zoutput.putNextEntry(zEntry);\n        int len;\n        while ((len = inputStream.read(BUFFER)) > 0) {\n            zoutput.write(BUFFER, 0, len);\n        }\n        zoutput.closeEntry();\n        zoutput.close();\n        inputStream.close();\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/AtlasDataBindingMergeArtifactsTransform.java",
    "content": "package com.taobao.android.builder.tasks.transform;\n\nimport android.databinding.tool.DataBindingBuilder;\nimport com.android.annotations.NonNull;\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.pipeline.TransformManager;\nimport com.android.build.gradle.internal.tasks.databinding.DataBindingMergeArtifactsTransform;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.utils.ILogger;\nimport com.google.common.base.Charsets;\nimport com.google.common.base.Predicate;\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common.collect.Sets;\nimport com.google.common.hash.HashCode;\nimport com.google.common.hash.HashFunction;\nimport com.google.common.hash.Hashing;\nimport com.google.common.io.ByteStreams;\nimport com.google.common.io.Closer;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.logging.Logger;\n\nimport javax.annotation.Nullable;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Set;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\n\n/**\n * @author lilong\n * @create 2017-12-08 上午2:28\n */\n\npublic class AtlasDataBindingMergeArtifactsTransform extends DataBindingMergeArtifactsTransform {\n\n    @NonNull\n    private final ILogger logger;\n    private final File outFolder;\n    private final AppVariantContext variantContext;\n\n    public AtlasDataBindingMergeArtifactsTransform(AppVariantContext variantContext, Logger logger, File outFolder) {\n\n        super(logger, outFolder);\n        this.logger = new LoggerWrapper(logger);\n        this.outFolder = outFolder;\n        this.variantContext = variantContext;\n    }\n\n\n\n    @NonNull\n    @Override\n    public String getName() {\n        return \"dataBindingMergeArtifacts\";\n    }\n\n    @NonNull\n    @Override\n    public Collection<File> getSecondaryDirectoryOutputs() {\n        return Collections.singleton(outFolder);\n    }\n\n    @Override\n    public void transform(@NonNull TransformInvocation transformInvocation)\n            throws TransformException, InterruptedException, IOException {\n\n\n        Collection<TransformInput> inputs = transformInvocation.getReferencedInputs();\n        //noinspection ResultOfMethodCallIgnored\n        outFolder.mkdirs();\n        if (transformInvocation.isIncremental()) {\n            incrementalUpdate(inputs);\n        } else {\n            fullCopy(inputs);\n        }\n    }\n\n    private void incrementalUpdate(@NonNull Collection<TransformInput> inputs) {\n\n\n        inputs.forEach(input -> input.getDirectoryInputs().stream().filter((Predicate<DirectoryInput>) input1 -> {\n             File file = input1.getFile().getParentFile();\n            if (AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getMainManifestFiles().containsKey(file.getAbsolutePath()) || variantContext.getAtlasExtension().getTBuildConfig().getAllBundlesToMdex()){\n                return false;\n            }\n            return true;\n        }).forEach(directoryInput -> {\n            directoryInput.getChangedFiles().forEach((file, status) -> {\n                if (isResource(file.getName())) {\n                    switch (status) {\n                        case NOTCHANGED:\n                            // Ignore\n                            break;\n                        case ADDED:\n                        case CHANGED:\n                            try {\n                                FileUtils.copyFile(file, new File(outFolder, file.getName()));\n                            } catch (IOException e) {\n                                logger.error(e, \"Cannot copy data binding artifacts from \"\n                                        + \"dependency.\");\n                            }\n                            break;\n                        case REMOVED:\n                            FileUtils.deleteQuietly(new File(outFolder, file.getName()));\n                            break;\n                    }\n                }\n            });\n        }));\n        inputs.forEach(input -> input.getJarInputs().forEach(jarInput -> {\n            switch (jarInput.getStatus()) {\n                case NOTCHANGED:\n                    // Ignore\n                    break;\n                case ADDED:\n                case CHANGED:\n                    try {\n                        extractBinFilesFromJar(jarInput.getFile());\n                    } catch (IOException e) {\n                        logger.error(e, \"Cannot extract data binding from input jar \");\n                    }\n                    break;\n                case REMOVED:\n                    File jarOutFolder = getOutFolderForJarFile(jarInput.getFile());\n                    FileUtils.deleteQuietly(jarOutFolder);\n                    break;\n            }\n        }));\n    }\n\n    private void fullCopy(Collection<TransformInput> inputs) throws IOException {\n        FileUtils.deleteQuietly(outFolder);\n        FileUtils.forceMkdir(outFolder);\n\n        for (TransformInput input : inputs) {\n            for (DirectoryInput dirInput : input.getDirectoryInputs()) {\n                File dataBindingDir = dirInput.getFile();\n                if (!dataBindingDir.exists()) {\n                    continue;\n                }\n                if (!AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getMainManifestFiles().containsKey(dataBindingDir.getParentFile().getAbsolutePath())&&!variantContext.getAtlasExtension().getTBuildConfig().getAllBundlesToMdex()){\n                    continue;\n                }\n\n                File artifactFolder = new File(dataBindingDir,\n                        DataBindingBuilder.INCREMENTAL_BIN_AAR_DIR);\n                if (!artifactFolder.exists()) {\n                    continue;\n                }\n                //noinspection ConstantConditions\n                for (String artifactName : artifactFolder.list()) {\n                    if (isResource(artifactName)) {\n                        FileUtils.copyFile(new File(artifactFolder, artifactName),\n                                new File(outFolder, artifactName));\n                    }\n                }\n            }\n            for(JarInput jarInput : input.getJarInputs()) {\n                File jarFile = jarInput.getFile();\n                extractBinFilesFromJar(jarFile);\n            }\n        }\n    }\n\n    private static boolean isResource(String fileName) {\n        for (String ext : DataBindingBuilder.RESOURCE_FILE_EXTENSIONS) {\n            if (fileName.endsWith(ext)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.ContentType> getInputTypes() {\n        return TransformManager.DATA_BINDING_ARTIFACT;\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.Scope> getReferencedScopes() {\n        return Sets.immutableEnumSet(QualifiedContent.Scope.SUB_PROJECTS,\n                QualifiedContent.Scope.EXTERNAL_LIBRARIES);\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.Scope> getScopes() {\n        return TransformManager.EMPTY_SCOPES;\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.ContentType> getOutputTypes() {\n        //noinspection unchecked\n        return ImmutableSet.of();\n    }\n\n    @Override\n    public boolean isIncremental() {\n        return true;\n    }\n\n    private void extractBinFilesFromJar(File jarFile) throws IOException {\n        File jarOutFolder = getOutFolderForJarFile(jarFile);\n        FileUtils.deleteQuietly(jarOutFolder);\n        FileUtils.forceMkdir(jarOutFolder);\n\n        try (Closer localCloser = Closer.create()) {\n            FileInputStream fis = localCloser.register(new FileInputStream(jarFile));\n            ZipInputStream zis = localCloser.register(new ZipInputStream(fis));\n            ZipEntry entry;\n            while ((entry = zis.getNextEntry()) != null) {\n                if (entry.isDirectory()) {\n                    continue;\n                }\n\n                String name = entry.getName();\n\n                if (!isResource(name)) {\n                    continue;\n                }\n                // get rid of the path. We don't need it since the file name includes the domain\n                name = new File(name).getName();\n                File out = new File(jarOutFolder, name);\n                //noinspection ResultOfMethodCallIgnored\n                FileOutputStream fos = localCloser.register(new FileOutputStream(out));\n                ByteStreams.copy(zis, fos);\n                zis.closeEntry();\n            }\n        }\n    }\n\n    @NonNull\n    private File getOutFolderForJarFile(File jarFile) {\n        return new File(outFolder, getJarFilePrefix(jarFile));\n    }\n\n    /**\n     * Files exported from jars are exported into a certain folder so that we can rebuild them\n     * when the related jar file changes.\n     */\n    @NonNull\n    private static String getJarFilePrefix(@NonNull File inputFile) {\n        // get the filename\n        String name = inputFile.getName();\n        // remove the extension\n        int pos = name.lastIndexOf('.');\n        if (pos != -1) {\n            name = name.substring(0, pos);\n        }\n\n        // add a hash of the original file path.\n        String input = inputFile.getAbsolutePath();\n        HashFunction hashFunction = Hashing.sha1();\n        HashCode hashCode = hashFunction.hashString(input, Charsets.UTF_16LE);\n\n        return name + \"-\" + hashCode.toString();\n    }\n\n\n    private void processAwbsDataBindings() throws IOException{\n        AtlasDependencyTree atlasDependencyTree =  AtlasBuildContext.androidDependencyTrees.get(variantContext.getVariantName());\n        for (AwbBundle awbBundle:atlasDependencyTree.getAwbBundles()){\n            File awbDataBindDepsOutDir = variantContext.getAwbDataBindingMergeArtifacts(awbBundle);\n            for (AndroidLibrary androidLibrary:awbBundle.getAndroidLibraries()){\n                File artifactFolder = new File(androidLibrary.getFolder(),DataBindingBuilder.DATA_BINDING_ROOT_FOLDER_IN_AAR+\"/\"+DataBindingBuilder.INCREMENTAL_BIN_AAR_DIR);\n                if (artifactFolder.exists() && artifactFolder.listFiles()!= null){\n                    for (String artifactName : artifactFolder.list()) {\n                        if (isResource(artifactName)) {\n                            FileUtils.copyFile(new File(artifactFolder, artifactName),\n                                    new File(awbDataBindDepsOutDir, artifactName));\n                        }\n                    }\n                }\n            }\n            File awbDataBindDir = new File(awbBundle.getAndroidLibrary().getFolder(),DataBindingBuilder.DATA_BINDING_ROOT_FOLDER_IN_AAR+\"/\"+DataBindingBuilder.INCREMENTAL_BIN_AAR_DIR);\n            if (awbDataBindDir.exists() && awbDataBindDir.listFiles()!= null){\n                for (String artifactName : awbDataBindDir.list()) {\n                    if (isResource(artifactName)) {\n                        FileUtils.copyFile(new File(awbDataBindDir, artifactName),\n                                new File(awbDataBindDepsOutDir, artifactName));\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/AtlasDesugarTransform.java",
    "content": "package com.taobao.android.builder.tasks.transform;\n\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.pipeline.TransformManager;\nimport com.android.build.gradle.internal.transforms.DesugarTransform;\nimport com.android.build.gradle.internal.transforms.DesugarWorkerItem;\nimport com.android.build.gradle.internal.transforms.TransformInputUtil;\nimport com.android.builder.Version;\nimport com.android.builder.core.DesugarProcessBuilder;\nimport com.android.builder.utils.FileCache;\nimport com.android.ide.common.internal.WaitableExecutor;\nimport com.android.ide.common.process.JavaProcessExecutor;\nimport com.android.ide.common.process.LoggedProcessOutputHandler;\nimport com.android.ide.common.process.ProcessException;\nimport com.android.utils.PathUtils;\nimport com.google.common.base.Preconditions;\nimport com.google.common.base.Throwables;\nimport com.google.common.collect.*;\nimport com.google.common.hash.Hashing;\nimport com.google.common.hash.HashingInputStream;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport org.gradle.workers.WorkerExecutor;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.URL;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.StandardCopyOption;\nimport java.util.*;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.atomic.AtomicReference;\nimport java.util.function.Supplier;\nimport java.util.stream.Collectors;\n\n/**\n * AtlasDesugarTransform\n *\n * @author zhayu.ll\n * @date 18/2/7\n */\npublic class AtlasDesugarTransform extends Transform {\n    public Transform oldTransform;\n\n    private enum FileCacheInputParams {\n\n        /**\n         * The input file.\n         */\n        FILE,\n\n        /**\n         * Version of the plugin containing Desugar used to generate the output.\n         */\n        PLUGIN_VERSION,\n\n        /**\n         * Minimum sdk version passed to Desugar, affects output.\n         */\n        MIN_SDK_VERSION,\n    }\n\n    private static class InputEntry {\n        @Nullable\n        private final FileCache cache;\n        @Nullable\n        private final FileCache.Inputs inputs;\n        @NonNull\n        private final Path inputPath;\n        @NonNull\n        private final Path outputPath;\n\n        public InputEntry(\n                @Nullable FileCache cache,\n                @Nullable FileCache.Inputs inputs,\n                @NonNull Path inputPath,\n                @NonNull Path outputPath) {\n            this.cache = cache;\n            this.inputs = inputs;\n            this.inputPath = inputPath;\n            this.outputPath = outputPath;\n        }\n\n        @Nullable\n        public FileCache getCache() {\n            return cache;\n        }\n\n        @Nullable\n        public FileCache.Inputs getInputs() {\n            return inputs;\n        }\n\n        @NonNull\n        public Path getInputPath() {\n            return inputPath;\n        }\n\n        @NonNull\n        public Path getOutputPath() {\n            return outputPath;\n        }\n    }\n\n    private static final LoggerWrapper logger = LoggerWrapper.getLogger(DesugarTransform.class);\n\n    @SuppressWarnings(\"FieldAccessedSynchronizedAndUnsynchronized\")\n    // we initialize this field only once, so having unsynchronized reads is fine\n    private static final AtomicReference<Path> desugarJar = new AtomicReference<Path>(null);\n\n    private static final String DESUGAR_JAR = \"desugar_deploy.jar\";\n\n    @NonNull\n    private final Supplier<List<File>> androidJarClasspath;\n    private final AppVariantOutputContext appVariantOutputContext;\n    @NonNull\n    private final List<Path> compilationBootclasspath;\n    @Nullable\n    private final FileCache userCache;\n    private final int minSdk;\n    @NonNull\n    private final JavaProcessExecutor executor;\n    @NonNull\n    private final Path tmpDir;\n    @NonNull\n    private final WaitableExecutor waitableExecutor;\n    private boolean verbose;\n    private final boolean enableGradleWorkers;\n\n    @NonNull\n    private Set<AtlasDesugarTransform.InputEntry> cacheMisses = Sets.newConcurrentHashSet();\n\n    public AtlasDesugarTransform(AppVariantOutputContext appVariantOutputContext,\n                                 @NonNull Supplier<List<File>> androidJarClasspath,\n                                 @NonNull List<Path> compilationBootclasspath,\n                                 @Nullable FileCache userCache,\n                                 int minSdk,\n                                 @NonNull JavaProcessExecutor executor,\n                                 boolean verbose,\n                                 boolean enableGradleWorkers,\n                                 @NonNull Path tmpDir) {\n        this.appVariantOutputContext = appVariantOutputContext;\n        this.androidJarClasspath = androidJarClasspath;\n        this.compilationBootclasspath = compilationBootclasspath;\n        this.userCache = userCache;\n        this.minSdk = minSdk;\n        this.executor = executor;\n        this.waitableExecutor = WaitableExecutor.useGlobalSharedThreadPool();\n        this.verbose = verbose;\n        this.enableGradleWorkers = enableGradleWorkers;\n        this.tmpDir = tmpDir;\n    }\n\n    @NonNull\n    @Override\n    public String getName() {\n        return \"desugar\";\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.ContentType> getInputTypes() {\n        return TransformManager.CONTENT_CLASS;\n    }\n\n    @NonNull\n    @Override\n    public Set<? super QualifiedContent.Scope> getScopes() {\n        return TransformManager.SCOPE_FULL_PROJECT;\n    }\n\n    @NonNull\n    @Override\n    public Set<? super QualifiedContent.Scope> getReferencedScopes() {\n        return ImmutableSet.of(QualifiedContent.Scope.PROVIDED_ONLY, QualifiedContent.Scope.TESTED_CODE);\n    }\n\n    @NonNull\n    @Override\n    public Map<String, Object> getParameterInputs() {\n        return ImmutableMap.of(\"Min sdk\", minSdk);\n    }\n\n    @NonNull\n    @Override\n    public Collection<SecondaryFile> getSecondaryFiles() {\n        ImmutableList.Builder<SecondaryFile> files = ImmutableList.builder();\n        androidJarClasspath.get().forEach(file -> files.add(SecondaryFile.nonIncremental(file)));\n\n        compilationBootclasspath.forEach(\n                file -> files.add(SecondaryFile.nonIncremental(file.toFile())));\n\n        return files.build();\n    }\n\n    @Override\n    public boolean isIncremental() {\n        return false;\n    }\n\n    @Override\n    public void transform(@NonNull TransformInvocation transformInvocation)\n            throws TransformException, InterruptedException, IOException {\n        try {\n            Map<JarInput, File> transformFiles = new HashMap<>();\n            initDesugarJar(userCache);\n            processInputs(transformInvocation, transformFiles);\n            waitableExecutor.waitForTasksWithQuickFail(true);\n\n            if (enableGradleWorkers) {\n                processNonCachedOnesWithGradleExecutor(\n                        transformInvocation.getContext().getWorkerExecutor(),\n                        getClasspath(transformInvocation));\n            } else {\n                processNonCachedOnes(getClasspath(transformInvocation));\n                waitableExecutor.waitForTasksWithQuickFail(true);\n            }\n            AtlasBuildContext.atlasMainDexHelperMap.get(appVariantOutputContext.getVariantContext().getVariantName()).updateMainDexFiles(transformFiles);\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new TransformException(e);\n        } catch (Exception e) {\n            throw new TransformException(e);\n        }\n    }\n\n    private void processInputs(@NonNull TransformInvocation transformInvocation, Map<JarInput, File> transformFiles) throws Exception {\n        TransformOutputProvider outputProvider = transformInvocation.getOutputProvider();\n        Preconditions.checkNotNull(outputProvider);\n        outputProvider.deleteAll();\n        AtlasBuildContext.atlasMainDexHelperMap.get(appVariantOutputContext.getVariantContext().getVariantName()).getInputDirs().clear();\n        for (TransformInput input : transformInvocation.getInputs()) {\n            for (DirectoryInput dirInput : input.getDirectoryInputs()) {\n                Path rootFolder = dirInput.getFile().toPath();\n                Path output = getOutputPath(transformInvocation.getOutputProvider(), dirInput);\n                if (Files.notExists(rootFolder)) {\n                    PathUtils.deleteIfExists(output);\n                } else {\n                    AtlasBuildContext.atlasMainDexHelperMap.get(appVariantOutputContext.getVariantContext().getVariantName()).getInputDirs().add(output.toFile());\n                    Set<Status> statuses = Sets.newHashSet(dirInput.getChangedFiles().values());\n                    boolean reRun =\n                            !transformInvocation.isIncremental()\n                                    || !Objects.equals(\n                                    statuses, Collections.singleton(Status.NOTCHANGED));\n\n                    if (reRun) {\n                        PathUtils.deleteIfExists(output);\n                        processSingle(rootFolder, output, dirInput.getScopes());\n                    }\n                }\n            }\n\n\n            for (JarInput jarInput : input.getJarInputs()) {\n                if (jarInput.getScopes().contains(QualifiedContent.Scope.SUB_PROJECTS)) {\n                    if (jarInput.getName().contains(\"::\")) {\n                        continue;\n                    }\n                }\n                Path output = getOutputPath(outputProvider, jarInput);\n                if (inMainDex(jarInput)) {\n                    Files.deleteIfExists(output);\n                    logger.info(\"process maindex desugar:\" + jarInput.getFile().getAbsolutePath());\n                    processSingle(jarInput.getFile().toPath(), output, jarInput.getScopes());\n                    transformFiles.put(jarInput, output.toFile());\n                } else {\n                    File file = appVariantOutputContext.updateAwbDexFile(jarInput, output.toFile());\n                    if (file != null) {\n                        if (!jarInput.getFile().equals(file)) {\n                            logger.info(\"process awb desugar:\" + file.getAbsolutePath());\n                            Files.deleteIfExists(output);\n                            processSingle(file.toPath(), output, jarInput.getScopes());\n                        } else {\n                            logger.info(\"process awb desugar:\" + jarInput.getFile().getAbsolutePath());\n                            Files.deleteIfExists(output);\n                            processSingle(jarInput.getFile().toPath(), output, jarInput.getScopes());\n                        }\n                    } else {\n                        throw new TransformException(jarInput.getFile().getAbsolutePath() + \"is not in maindex and awb libraries in AtlasdesugarTransform!\");\n                    }\n                }\n            }\n        }\n    }\n\n    private void processNonCachedOnes(List<Path> classpath) throws IOException {\n        int parallelExecutions = waitableExecutor.getParallelism();\n\n        int index = 0;\n        Multimap<Integer, AtlasDesugarTransform.InputEntry> procBuckets = ArrayListMultimap.create();\n        for (AtlasDesugarTransform.InputEntry pathPathEntry : cacheMisses) {\n            int bucketId = index % parallelExecutions;\n            procBuckets.put(bucketId, pathPathEntry);\n            index++;\n        }\n\n        List<Path> desugarBootclasspath = getBootclasspath();\n        for (Integer bucketId : procBuckets.keySet()) {\n            Callable<Void> callable =\n                    () -> {\n                        Map<Path, Path> inToOut = Maps.newHashMap();\n                        for (AtlasDesugarTransform.InputEntry e : procBuckets.get(bucketId)) {\n                            inToOut.put(e.getInputPath(), e.getOutputPath());\n                        }\n\n                        DesugarProcessBuilder processBuilder =\n                                new DesugarProcessBuilder(\n                                        desugarJar.get(),\n                                        verbose,\n                                        inToOut,\n                                        classpath,\n                                        desugarBootclasspath,\n                                        minSdk,\n                                        tmpDir);\n                        boolean isWindows =\n                                SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS;\n                        executor.execute(\n                                processBuilder.build(isWindows),\n                                new LoggedProcessOutputHandler(logger))\n                                .rethrowFailure()\n                                .assertNormalExitValue();\n\n                        // now copy to the cache because now we have the file\n                        for (AtlasDesugarTransform.InputEntry e : procBuckets.get(bucketId)) {\n                            if (e.getCache() != null && e.getInputs() != null) {\n                                e.getCache()\n                                        .createFileInCacheIfAbsent(\n                                                e.getInputs(),\n                                                in -> Files.copy(e.getOutputPath(), in.toPath()));\n                            }\n                        }\n\n                        return null;\n                    };\n            waitableExecutor.execute(callable);\n        }\n    }\n\n    private void processNonCachedOnesWithGradleExecutor(\n            WorkerExecutor workerExecutor, List<Path> classpath)\n            throws IOException, ProcessException, ExecutionException {\n        List<Path> desugarBootclasspath = getBootclasspath();\n        for (AtlasDesugarTransform.InputEntry pathPathEntry : cacheMisses) {\n            DesugarWorkerItem workerItem =\n                    new DesugarWorkerItem(\n                            desugarJar.get(),\n                            PathUtils.createTmpDirToRemoveOnShutdown(\"gradle_lambdas\"),\n                            true,\n                            pathPathEntry.getInputPath(),\n                            pathPathEntry.getOutputPath(),\n                            classpath,\n                            desugarBootclasspath,\n                            minSdk);\n\n            workerExecutor.submit(DesugarWorkerItem.DesugarAction.class, workerItem::configure);\n        }\n\n        workerExecutor.await();\n\n        for (AtlasDesugarTransform.InputEntry e : cacheMisses) {\n            if (e.getCache() != null && e.getInputs() != null) {\n                e.getCache()\n                        .createFileInCacheIfAbsent(\n                                e.getInputs(), in -> Files.copy(e.getOutputPath(), in.toPath()));\n            }\n        }\n    }\n\n    @NonNull\n    private List<Path> getClasspath(@NonNull TransformInvocation transformInvocation)\n            throws IOException {\n        ImmutableList.Builder<Path> classpathEntries = ImmutableList.builder();\n\n        classpathEntries.addAll(\n                TransformInputUtil.getAllFiles(transformInvocation.getInputs())\n                        .stream()\n                        .map(File::toPath)\n                        .iterator());\n\n        classpathEntries.addAll(\n                TransformInputUtil.getAllFiles(transformInvocation.getReferencedInputs())\n                        .stream()\n                        .map(File::toPath)\n                        .iterator());\n\n        return classpathEntries.build();\n    }\n\n    @NonNull\n    private List<Path> getBootclasspath() throws IOException {\n        List<Path> desugarBootclasspath =\n                androidJarClasspath.get().stream().map(File::toPath).collect(Collectors.toList());\n        desugarBootclasspath.addAll(compilationBootclasspath);\n\n        return desugarBootclasspath;\n    }\n\n    private void processSingle(\n            @NonNull Path input, @NonNull Path output, @NonNull Set<? super QualifiedContent.Scope> scopes)\n            throws Exception {\n        waitableExecutor.execute(\n                () -> {\n                    if (output.toString().endsWith(SdkConstants.DOT_JAR)) {\n                        Files.createDirectories(output.getParent());\n                    } else {\n                        Files.createDirectories(output);\n                    }\n\n                    FileCache cacheToUse;\n                    if (Files.isRegularFile(input)\n                            && Objects.equals(\n                            scopes, Collections.singleton(QualifiedContent.Scope.EXTERNAL_LIBRARIES))) {\n                        cacheToUse = userCache;\n                    } else {\n                        cacheToUse = null;\n                    }\n\n                    processUsingCache(input, output, cacheToUse);\n                    return null;\n                });\n    }\n\n    private void processUsingCache(\n            @NonNull Path input,\n            @NonNull Path output,\n            @Nullable FileCache cache)\n            throws Exception {\n        if (cache != null) {\n            try {\n                FileCache.Inputs cacheKey = getBuildCacheInputs(input, minSdk);\n                if (cache.cacheEntryExists(cacheKey)) {\n                    logger.info(\"process desugar hit cache:\" + input.toFile().getAbsolutePath());\n                    FileCache.QueryResult result =\n                            cache.createFile(\n                                    output.toFile(),\n                                    cacheKey,\n                                    () -> {\n                                        throw new AssertionError(\"Entry should exist.\");\n                                    });\n\n                    if (result.getQueryEvent().equals(FileCache.QueryEvent.CORRUPTED)) {\n                        Objects.requireNonNull(result.getCauseOfCorruption());\n                        logger.verbose(\n                                \"The build cache at '%1$s' contained an invalid cache entry.\\n\"\n                                        + \"Cause: %2$s\\n\"\n                                        + \"We have recreated the cache entry.\\n\",\n                                cache.getCacheDirectory().getAbsolutePath(),\n                                Throwables.getStackTraceAsString(result.getCauseOfCorruption()));\n                    }\n\n                    if (Files.notExists(output)) {\n                        throw new RuntimeException(\n                                String.format(\n                                        \"Entry for %s is invalid. Please clean your build cache \"\n                                                + \"under %s.\",\n                                        output.toString(),\n                                        cache.getCacheDirectory().getAbsolutePath()));\n                    }\n                } else {\n                    cacheMissAction(cache, cacheKey, input, output);\n                }\n            } catch (Exception exception) {\n                logger.error(\n                        null,\n                        String.format(\n                                \"Unable to Desugar '%1$s' to '%2$s' using the build cache at\"\n                                        + \" '%3$s'.\\n\",\n                                input.toString(),\n                                output.toString(),\n                                cache.getCacheDirectory().getAbsolutePath()));\n                throw new RuntimeException(exception);\n            }\n        } else {\n            cacheMissAction(null, null, input, output);\n        }\n    }\n\n    private void cacheMissAction(\n            @Nullable FileCache cache,\n            @Nullable FileCache.Inputs inputs,\n            @NonNull Path input,\n            @NonNull Path output)\n            throws IOException, ProcessException {\n        logger.info(\"process desugar miss cache:\" + input.toFile().getAbsolutePath());\n\n        // add it to the list of cache misses, that will be processed\n        cacheMisses.add(new AtlasDesugarTransform.InputEntry(cache, inputs, input, output));\n    }\n\n    @NonNull\n    private static Path getOutputPath(\n            @NonNull TransformOutputProvider outputProvider, @NonNull QualifiedContent content) {\n        return outputProvider\n                .getContentLocation(\n                        content.getName(),\n                        content.getContentTypes(),\n                        content.getScopes(),\n                        content.getFile().isDirectory() ? Format.DIRECTORY : Format.JAR)\n                .toPath();\n    }\n\n    @NonNull\n    private static FileCache.Inputs getBuildCacheInputs(@NonNull Path input, int minSdkVersion)\n            throws IOException {\n        FileCache.Inputs.Builder buildCacheInputs =\n                new FileCache.Inputs.Builder(FileCache.Command.DESUGAR_LIBRARY);\n\n        buildCacheInputs\n                .putFile(\n                        AtlasDesugarTransform.FileCacheInputParams.FILE.name(),\n                        input.toFile(),\n                        FileCache.FileProperties.PATH_HASH)\n                .putString(\n                        AtlasDesugarTransform.FileCacheInputParams.PLUGIN_VERSION.name(),\n                        Version.ANDROID_GRADLE_PLUGIN_VERSION)\n                .putLong(AtlasDesugarTransform.FileCacheInputParams.MIN_SDK_VERSION.name(), minSdkVersion);\n\n        return buildCacheInputs.build();\n    }\n\n    /**\n     * Set this location of extracted desugar jar that is used for processing.\n     */\n    private static void initDesugarJar(@Nullable FileCache cache) throws IOException {\n        if (isDesugarJarInitialized()) {\n            return;\n        }\n\n        URL url = DesugarProcessBuilder.class.getClassLoader().getResource(DESUGAR_JAR);\n        Preconditions.checkNotNull(url);\n\n        Path extractedDesugar = null;\n        if (cache != null) {\n            try {\n                String fileHash;\n                try (HashingInputStream stream =\n                             new HashingInputStream(Hashing.sha256(), url.openStream())) {\n                    fileHash = stream.hash().toString();\n                }\n                FileCache.Inputs inputs =\n                        new FileCache.Inputs.Builder(FileCache.Command.EXTRACT_DESUGAR_JAR)\n                                .putString(\"pluginVersion\", Version.ANDROID_GRADLE_PLUGIN_VERSION)\n                                .putString(\"jarUrl\", url.toString())\n                                .putString(\"fileHash\", fileHash)\n                                .build();\n\n                File cachedFile =\n                        cache.createFileInCacheIfAbsent(\n                                inputs, file -> copyDesugarJar(url, file.toPath()))\n                                .getCachedFile();\n                Preconditions.checkNotNull(cachedFile);\n                extractedDesugar = cachedFile.toPath();\n            } catch (IOException | ExecutionException e) {\n                logger.error(e, \"Unable to cache Desugar jar. Extracting to temp dir.\");\n            }\n        }\n\n        synchronized (desugarJar) {\n            if (isDesugarJarInitialized()) {\n                return;\n            }\n\n            if (extractedDesugar == null) {\n                extractedDesugar = PathUtils.createTmpToRemoveOnShutdown(DESUGAR_JAR);\n                copyDesugarJar(url, extractedDesugar);\n            }\n            desugarJar.set(extractedDesugar);\n        }\n    }\n\n    private static void copyDesugarJar(@NonNull URL inputUrl, @NonNull Path targetPath)\n            throws IOException {\n        try (InputStream inputStream = inputUrl.openConnection().getInputStream()) {\n            Files.copy(inputStream, targetPath, StandardCopyOption.REPLACE_EXISTING);\n        }\n    }\n\n    private static boolean isDesugarJarInitialized() {\n        return desugarJar.get() != null && Files.isRegularFile(desugarJar.get());\n    }\n\n    private boolean inMainDex(JarInput jarInput) throws IOException {\n\n        return AtlasBuildContext.atlasMainDexHelperMap.get(appVariantOutputContext.getVariantContext().getVariantName()).inMainDex(jarInput);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/AtlasFixStackFramesTransform.java",
    "content": "package com.taobao.android.builder.tasks.transform;\n\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.transforms.FixStackFramesTransform;\nimport com.android.builder.utils.ExceptionRunnable;\nimport com.android.builder.utils.FileCache;\nimport com.android.ide.common.internal.WaitableExecutor;\nimport com.google.common.base.Preconditions;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Iterables;\nimport com.google.common.io.ByteStreams;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.app.BuildAtlasEnvTask;\nimport org.objectweb.asm.ClassReader;\nimport org.objectweb.asm.ClassWriter;\n\nimport java.io.*;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.attribute.FileTime;\nimport java.util.*;\nimport java.util.function.Supplier;\nimport java.util.zip.CRC32;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\nimport java.util.zip.ZipOutputStream;\n\n/**\n * AtlasFixStackFramesTransform\n *\n * @author zhayu.ll\n * @date 18/2/7\n */\npublic class AtlasFixStackFramesTransform extends Transform {\n\n    public Transform oldTransform;\n    private WaitableExecutor waitableExecutor = WaitableExecutor.useGlobalSharedThreadPool();\n    private AppVariantOutputContext appVariantOutputContext;\n\n    @NonNull\n    private final Supplier<List<File>> androidJarClasspath;\n    @NonNull\n    private final List<Path> compilationBootclasspath;\n    @Nullable\n    private final FileCache userCache;\n    @Nullable\n    private URLClassLoader classLoader = null;\n\n    public AtlasFixStackFramesTransform(AppVariantOutputContext appVariantOutputContext, Supplier<List<File>> androidJarClasspath, List<Path> compilationBootclasspath, FileCache userCache) {\n        this.androidJarClasspath = androidJarClasspath;\n        this.compilationBootclasspath = compilationBootclasspath;\n        this.userCache = userCache;\n        this.appVariantOutputContext = appVariantOutputContext;\n    }\n\n    @NonNull\n    private URLClassLoader getClassLoader(@NonNull TransformInvocation invocation)\n            throws MalformedURLException {\n        if (classLoader == null) {\n            ImmutableList.Builder<URL> urls = new ImmutableList.Builder<>();\n            for (File file : androidJarClasspath.get()) {\n                urls.add(file.toURI().toURL());\n            }\n            for (Path bootClasspath : this.compilationBootclasspath) {\n                if (Files.exists(bootClasspath)) {\n                    urls.add(bootClasspath.toUri().toURL());\n                }\n            }\n            for (TransformInput inputs :\n                    Iterables.concat(invocation.getInputs(), invocation.getReferencedInputs())) {\n                for (DirectoryInput directoryInput : inputs.getDirectoryInputs()) {\n                    if (directoryInput.getFile().isDirectory()) {\n                        urls.add(directoryInput.getFile().toURI().toURL());\n                    }\n                }\n                for (JarInput jarInput : inputs.getJarInputs()) {\n                    if (jarInput.getFile().isFile()) {\n                        urls.add(jarInput.getFile().toURI().toURL());\n                    }\n                }\n            }\n\n            ImmutableList<URL> allUrls = urls.build();\n            URL[] classLoaderUrls = allUrls.toArray(new URL[allUrls.size()]);\n            classLoader = new URLClassLoader(classLoaderUrls);\n        }\n        return classLoader;\n    }\n\n    private static class FixFramesVisitor extends ClassWriter {\n\n        @NonNull\n        private final URLClassLoader classLoader;\n\n        public FixFramesVisitor(int flags, @NonNull URLClassLoader classLoader) {\n            super(flags);\n            this.classLoader = classLoader;\n        }\n\n        @Override\n        protected String getCommonSuperClass(String type1, String type2) {\n            Class<?> c;\n            Class<?> d;\n            ClassLoader classLoader = this.classLoader;\n            try {\n                c = Class.forName(type1.replace('/', '.'), false, classLoader);\n                d = Class.forName(type2.replace('/', '.'), false, classLoader);\n            } catch (Exception e) {\n                throw new RuntimeException(\n                        String.format(\n                                \"Unable to find common supper type for %s and %s.\", type1, type2),\n                        e);\n            }\n            if (c.isAssignableFrom(d)) {\n                return type1;\n            }\n            if (d.isAssignableFrom(c)) {\n                return type2;\n            }\n            if (c.isInterface() || d.isInterface()) {\n                return \"java/lang/Object\";\n            } else {\n                do {\n                    c = c.getSuperclass();\n                } while (!c.isAssignableFrom(d));\n                return c.getName().replace('.', '/');\n            }\n        }\n    }\n\n    private static final LoggerWrapper logger =\n            LoggerWrapper.getLogger(FixStackFramesTransform.class);\n    private static final FileTime ZERO = FileTime.fromMillis(0);\n\n\n    @Override\n    public String getName() {\n        return oldTransform.getName();\n    }\n\n    @Override\n    public Set<QualifiedContent.ContentType> getInputTypes() {\n        return oldTransform.getInputTypes();\n    }\n\n    @Override\n    public Set<? super QualifiedContent.Scope> getScopes() {\n        return oldTransform.getScopes();\n    }\n\n    @Override\n    public Set<? super QualifiedContent.Scope> getReferencedScopes() {\n        return oldTransform.getReferencedScopes();\n    }\n\n    @Override\n    public Collection<SecondaryFile> getSecondaryFiles() {\n        return oldTransform.getSecondaryFiles();\n    }\n\n    @Override\n    public boolean isIncremental() {\n        return false;\n    }\n\n    @Override\n    public void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {\n        TransformOutputProvider outputProvider =\n                Preconditions.checkNotNull(transformInvocation.getOutputProvider());\n\n//        boolean incremental = transformInvocation.isIncremental();\n//        if (!incremental) {\n            outputProvider.deleteAll();\n//        }\n        Map<JarInput,File> mainDexTransformFiles = new HashMap<>();\n        try {\n            for (TransformInput input : transformInvocation.getInputs()) {\n                for (JarInput jarInput : input.getJarInputs()) {\n                    boolean flag = inMainDex(jarInput);\n                    File output =\n                            outputProvider.getContentLocation(\n                                    jarInput.getName(),\n                                    jarInput.getContentTypes(),\n                                    jarInput.getScopes(),\n                                    Format.JAR);\n                    if (flag) {\n                        mainDexTransformFiles.put(jarInput,output);\n                        Files.deleteIfExists(output.toPath());\n                        logger.info(\"process maindex fixStackFrames:\"+jarInput.getFile().getAbsolutePath());\n                        processJar(jarInput.getFile(), output, transformInvocation);\n                    } else {\n                        File file = appVariantOutputContext.updateAwbDexFile(jarInput, output);\n                        if (file!= null){\n                            if (!jarInput.getFile().equals(file)){\n                                logger.info(\"process awb fixStackFrames:\"+file.getAbsolutePath());\n                                Files.deleteIfExists(output.toPath());\n                                processJar(file, output, transformInvocation);\n                            }else {\n                                logger.info(\"process awb fixStackFrames:\"+jarInput.getFile().getAbsolutePath());\n                                Files.deleteIfExists(output.toPath());\n                                processJar(jarInput.getFile(), output, transformInvocation);\n                            }\n                        }else {\n                            logger.warning(jarInput.getFile().getAbsolutePath() +\"is not in maindex and awb libraries in AtlasFixStackFramesTransform!\");\n                        }\n                    }\n\n                }\n            }\n\n            waitableExecutor.waitForTasksWithQuickFail(true);\n            AtlasBuildContext.atlasMainDexHelperMap.get(appVariantOutputContext.getVariantContext().getVariantName()).updateMainDexFiles(mainDexTransformFiles);\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n        } catch (Exception e) {\n            throw new TransformException(e);\n        } finally {\n            if (classLoader != null) {\n                classLoader.close();\n            }\n        }\n    }\n\n    private void processJar(\n            @NonNull File input, @NonNull File output, @NonNull TransformInvocation invocation) {\n        waitableExecutor.execute(\n                () -> {\n                    ExceptionRunnable fileCreator = createFile(input, output, invocation);\n                    if (userCache != null) {\n                        FileCache.Inputs key =\n                                new FileCache.Inputs.Builder(FileCache.Command.FIX_STACK_FRAMES)\n                                        .putFile(\n                                                \"file\",\n                                                input,\n                                                FileCache.FileProperties.PATH_HASH)\n                                        .build();\n                        FileCache.QueryResult queryResult = userCache.createFile(output, key, fileCreator);\n                        if (queryResult.getQueryEvent().equals(FileCache.QueryEvent.HIT)){\n                            logger.info(\"process fixStackFrames hit:\"+input.getAbsolutePath());\n                        }else{\n                            logger.info(\"process fixStackFrames miss:\"+input.getAbsolutePath());\n\n                        }\n\n\n                    } else {\n                        fileCreator.run();\n                    }\n                    return null;\n                });\n    }\n\n    @NonNull\n    private ExceptionRunnable createFile(\n            @NonNull File input, @NonNull File output, @NonNull TransformInvocation invocation) {\n        return () -> {\n            try (ZipFile inputZip = new ZipFile(input);\n                 ZipOutputStream outputZip =\n                         new ZipOutputStream(\n                                 new BufferedOutputStream(\n                                         Files.newOutputStream(output.toPath())))) {\n                Enumeration<? extends ZipEntry> inEntries = inputZip.entries();\n                while (inEntries.hasMoreElements()) {\n                    ZipEntry entry = inEntries.nextElement();\n                    if (!entry.getName().endsWith(SdkConstants.DOT_CLASS)) {\n                        continue;\n                    }\n                    InputStream originalFile =\n                            new BufferedInputStream(inputZip.getInputStream(entry));\n                    ZipEntry outEntry = new ZipEntry(entry.getName());\n\n                    byte[] newEntryContent =\n                            getFixedClass(originalFile, getClassLoader(invocation));\n                    CRC32 crc32 = new CRC32();\n                    crc32.update(newEntryContent);\n                    outEntry.setCrc(crc32.getValue());\n                    outEntry.setMethod(ZipEntry.STORED);\n                    outEntry.setSize(newEntryContent.length);\n                    outEntry.setCompressedSize(newEntryContent.length);\n                    outEntry.setLastAccessTime(ZERO);\n                    outEntry.setLastModifiedTime(ZERO);\n                    outEntry.setCreationTime(ZERO);\n\n                    outputZip.putNextEntry(outEntry);\n                    outputZip.write(newEntryContent);\n                    outputZip.closeEntry();\n                }\n            }\n        };\n    }\n\n    @NonNull\n    private static byte[] getFixedClass(\n            @NonNull InputStream originalFile, @NonNull URLClassLoader classLoader)\n            throws IOException {\n        byte[] bytes = ByteStreams.toByteArray(originalFile);\n        try {\n            ClassReader classReader = new ClassReader(bytes);\n            ClassWriter classWriter = new AtlasFixStackFramesTransform.FixFramesVisitor(ClassWriter.COMPUTE_FRAMES, classLoader);\n            classReader.accept(classWriter, ClassReader.SKIP_FRAMES);\n            return classWriter.toByteArray();\n        } catch (Throwable t) {\n            // we could not fix it, just copy the original and log the exception\n            logger.verbose(t.getMessage());\n            return bytes;\n        }\n    }\n\n    private boolean inMainDex(JarInput jarInput) throws IOException {\n\n        return AtlasBuildContext.atlasMainDexHelperMap.get(appVariantOutputContext.getVariantContext().getVariantName()).inMainDex(jarInput);\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/AtlasMergeJavaResourcesTransform.java",
    "content": "package com.taobao.android.builder.tasks.transform;\n\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.dsl.PackagingOptions;\nimport com.android.build.gradle.internal.packaging.PackagingFileAction;\nimport com.android.build.gradle.internal.packaging.ParsedPackagingOptions;\nimport com.android.build.gradle.internal.pipeline.AtlasIncrementalFileMergeTransformUtils;\nimport com.android.build.gradle.internal.pipeline.ExtendedContentType;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.transforms.MergeJavaResourcesTransform;\nimport com.android.builder.files.FileCacheByPath;\nimport com.android.builder.merge.*;\nimport com.android.ide.common.internal.WaitableExecutor;\nimport com.android.utils.FileUtils;\nimport com.android.utils.ImmutableCollectors;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tools.MD5Util;\nimport com.taobao.android.builder.tools.zip.BetterZip;\nimport com.taobao.android.builder.tools.zip.ZipUtils;\nimport org.gradle.internal.impldep.org.apache.tools.zip.ZipUtil;\n\nimport java.io.*;\nimport java.nio.file.Files;\nimport java.util.*;\nimport java.util.concurrent.Callable;\nimport java.util.function.Consumer;\nimport java.util.function.Predicate;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport java.util.stream.Collectors;\nimport java.util.zip.ZipOutputStream;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\n\n\n/**\n * @author lilong\n * @create 2017-12-27 下午2:30\n */\n\npublic class AtlasMergeJavaResourcesTransform extends MergeJavaResourcesTransform {\n\n    private static final Pattern JAR_ABI_PATTERN = Pattern.compile(\"lib/([^/]+)/[^/]+\");\n    private static final Pattern ABI_FILENAME_PATTERN = Pattern.compile(\".*\\\\.so\");\n\n    @NonNull\n    private final PackagingOptions packagingOptions;\n\n    @NonNull\n    private final String name;\n\n    @NonNull\n    private final Set<? super QualifiedContent.Scope> mergeScopes;\n    @NonNull\n    private final Set<QualifiedContent.ContentType> mergedType;\n\n\n    private Set<String> paths = new HashSet<>();\n\n\n    @NonNull\n    private final File intermediateDir;\n\n    private final Predicate<String> acceptedPathsPredicate;\n    @NonNull\n    private File cacheDir;\n\n\n    private AppVariantOutputContext appVariantOutputContext;\n\n\n    private File outputLocation;\n\n    private WaitableExecutor waitableExecutor;\n\n    public AtlasMergeJavaResourcesTransform(AppVariantOutputContext appVariantOutputContext, PackagingOptions packagingOptions, Set<? super QualifiedContent.Scope> mergeScopes, QualifiedContent.ContentType mergedType, String name, VariantScope variantScope) {\n        super(packagingOptions, mergeScopes, mergedType, name, variantScope);\n        this.packagingOptions = packagingOptions;\n        this.name = name;\n        this.mergeScopes = ImmutableSet.copyOf(mergeScopes);\n        this.mergedType = ImmutableSet.of(mergedType);\n        this.intermediateDir = variantScope.getIncrementalDir(\n                variantScope.getFullVariantName() + \"-\" + name);\n        waitableExecutor = WaitableExecutor.useGlobalSharedThreadPool();\n        this.appVariantOutputContext = appVariantOutputContext;\n        if (mergedType == QualifiedContent.DefaultContentType.RESOURCES) {\n            acceptedPathsPredicate =\n                    path -> !path.endsWith(SdkConstants.DOT_CLASS)\n                            && !path.endsWith(SdkConstants.DOT_NATIVE_LIBS);\n        } else if (mergedType == ExtendedContentType.NATIVE_LIBS) {\n            acceptedPathsPredicate =\n                    path -> {\n                        Matcher m = JAR_ABI_PATTERN.matcher(path);\n\n                        // if the ABI is accepted, check the 3rd segment\n                        if (m.matches()) {\n                            paths.add(path);\n                            // remove the beginning of the path (lib/<abi>/)\n                            String filename = path.substring(5 + m.group(1).length());\n                            // and check the filename\n                            return ABI_FILENAME_PATTERN.matcher(filename).matches() ||\n                                    SdkConstants.FN_GDBSERVER.equals(filename) ||\n                                    SdkConstants.FN_GDB_SETUP.equals(filename);\n                        }\n\n                        return false;\n\n                    };\n        } else {\n            throw new UnsupportedOperationException(\n                    \"mergedType param must be RESOURCES or NATIVE_LIBS\");\n        }\n    }\n\n    private void processAtlasNativeSo(String path) {\n        appVariantOutputContext.getVariantContext().getProject().getLogger().info(\"processAtlasNativeSo soFile path:\" + path);\n        Set<String> removedNativeSos = appVariantOutputContext.getVariantContext().getAtlasExtension().getTBuildConfig().getOutOfApkNativeSos();\n        if (removedNativeSos.size() > 0) {\n            if (removedNativeSos.contains(path)) {\n                File soFile = outputLocation.toPath().resolve(path).toFile();\n                appVariantOutputContext.getVariantContext().getProject().getLogger().info(\"remove soFile path:\" + soFile.getAbsolutePath());\n                String url = AtlasBuildContext.atlasApkProcessor.uploadNativeSo(appVariantOutputContext.getVariantContext().getProject(), soFile, appVariantOutputContext.getVariantContext().getBuildType());\n                NativeInfo nativeInfo = new NativeInfo();\n                nativeInfo.bundleName = \"mainBundle\";\n                nativeInfo.md5 = MD5Util.getFileMD5(soFile);\n                nativeInfo.url = url;\n                nativeInfo.path = path;\n                appVariantOutputContext.getSoMap().put(path, nativeInfo);\n                try {\n                    org.apache.commons.io.FileUtils.moveFileToDirectory(soFile, appVariantOutputContext.getRemoteNativeSoFolder(nativeInfo.bundleName), true);\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n            }\n        }\n    }\n\n    @Override\n    public void transform(TransformInvocation invocation) throws IOException {\n\n        waitableExecutor.execute(new Callable<Void>() {\n            @Override\n            public Void call() throws Exception {\n                cacheDir = new File(intermediateDir, \"zip-cache\");\n                FileUtils.mkdirs(cacheDir);\n                FileCacheByPath zipCache = new FileCacheByPath(cacheDir);\n                TransformOutputProvider outputProvider = invocation.getOutputProvider();\n                checkNotNull(outputProvider, \"Missing output object for transform \" + getName());\n\n                ParsedPackagingOptions packagingOptions = new ParsedPackagingOptions(AtlasMergeJavaResourcesTransform.this.packagingOptions);\n\n                boolean full = false;\n                IncrementalFileMergerState state = loadMergeState();\n                if (state == null || !invocation.isIncremental()) {\n                    /*\n                     * This is a full build.\n                     */\n                    state = new IncrementalFileMergerState();\n                    outputProvider.deleteAll();\n                    full = true;\n                }\n\n                List<Runnable> cacheUpdates = new ArrayList<>();\n\n                Map<IncrementalFileMergerInput, QualifiedContent> contentMap = new HashMap<>();\n                List<IncrementalFileMergerInput> inputs =\n                        new ArrayList<>(\n                                AtlasIncrementalFileMergeTransformUtils.toInput(\n                                        invocation,\n                                        zipCache,\n                                        cacheUpdates,\n                                        full,\n                                        contentMap, null,appVariantOutputContext.getVariantContext().getVariantName()));\n\n\n\n\n                /*\n                 * In an ideal world, we could just send the inputs to the file merger. However, in the\n                 * real world we live in, things are more complicated :)\n                 *\n                 * We need to:\n                 *\n                 * 1. We need to bring inputs that refer to the project scope before the other inputs.\n                 * 2. Prefix libraries that come from directories with \"lib/\".\n                 * 3. Filter all inputs to remove anything not accepted by acceptedPathsPredicate neither\n                 * by packagingOptions.\n                 */\n\n                // Sort inputs to move project scopes to the start.\n                inputs.sort((i0, i1) -> {\n                    int v0 = contentMap.get(i0).getScopes().contains(QualifiedContent.Scope.PROJECT) ? 0 : 1;\n                    int v1 = contentMap.get(i1).getScopes().contains(QualifiedContent.Scope.PROJECT) ? 0 : 1;\n                    return v0 - v1;\n                });\n\n                // Prefix libraries with \"lib/\" if we're doing libraries.\n                assert mergedType.size() == 1;\n                QualifiedContent.ContentType mergedType = AtlasMergeJavaResourcesTransform.this.mergedType.iterator().next();\n                if (mergedType == ExtendedContentType.NATIVE_LIBS) {\n                    inputs =\n                            inputs.stream()\n                                    .map(\n                                            i -> {\n                                                QualifiedContent qc = contentMap.get(i);\n                                                if (qc.getFile().isDirectory()) {\n                                                    i =\n                                                            new RenameIncrementalFileMergerInput(\n                                                                    i,\n                                                                    s -> \"lib/\" + s,\n                                                                    s -> s.substring(\"lib/\".length()));\n                                                    contentMap.put(i, qc);\n                                                }\n\n                                                return i;\n                                            })\n                                    .collect(Collectors.toList());\n                }\n\n                // Filter inputs.\n                Predicate<String> inputFilter =\n                        acceptedPathsPredicate.and(\n                                path -> packagingOptions.getAction(path) != PackagingFileAction.EXCLUDE);\n                inputs = inputs.stream()\n                        .map(i -> {\n                            IncrementalFileMergerInput i2 =\n                                    new FilterIncrementalFileMergerInput(i, inputFilter);\n                            contentMap.put(i2, contentMap.get(i));\n                            return i2;\n                        })\n                        .collect(Collectors.toList());\n\n                /*\n                 * Create the algorithm used by the merge transform. This algorithm decides on which\n                 * algorithm to delegate to depending on the packaging option of the path. By default it\n                 * requires just one file (no merging).\n                 */\n                StreamMergeAlgorithm mergeTransformAlgorithm = StreamMergeAlgorithms.select(path -> {\n                    PackagingFileAction packagingAction = packagingOptions.getAction(path);\n                    switch (packagingAction) {\n                        case EXCLUDE:\n                            // Should have been excluded from the input.\n                            throw new AssertionError();\n                        case PICK_FIRST:\n                            return StreamMergeAlgorithms.pickFirst();\n                        case MERGE:\n                            return StreamMergeAlgorithms.concat();\n                        case NONE:\n                            return StreamMergeAlgorithms.acceptOnlyOne();\n                        default:\n                            throw new AssertionError();\n                    }\n                });\n\n                /*\n                 * Create an output that uses the algorithm. This is not the final output because,\n                 * unfortunately, we still have the complexity of the project scope overriding other scopes\n                 * to solve.\n                 *\n                 * When resources inside a jar file are extracted to a directory, the results may not be\n                 * expected on Windows if the file names end with \".\" (bug 65337573), or if there is an\n                 * uppercase/lowercase conflict. To work around this issue, we copy these resources to a\n                 * jar file.\n                 */\n                IncrementalFileMergerOutput baseOutput;\n                if (mergedType == QualifiedContent.DefaultContentType.RESOURCES) {\n                    outputLocation =\n                            outputProvider.getContentLocation(\n                                    \"resources\", getOutputTypes(), getScopes(), Format.JAR);\n                    baseOutput =\n                            IncrementalFileMergerOutputs.fromAlgorithmAndWriter(\n                                    mergeTransformAlgorithm, MergeOutputWriters.toZip(outputLocation));\n                    AtlasBuildContext.atlasMainDexHelperMap.get(appVariantOutputContext.getVariantContext().getVariantName()).addMainJavaRes(outputLocation);\n                } else {\n                    outputLocation =\n                            outputProvider.getContentLocation(\n                                    \"resources\", getOutputTypes(), getScopes(), Format.DIRECTORY);\n                    baseOutput =\n                            IncrementalFileMergerOutputs.fromAlgorithmAndWriter(\n                                    mergeTransformAlgorithm,\n                                    MergeOutputWriters.toDirectory(outputLocation));\n                }\n\n                /*\n                 * We need a custom output to handle the case in which the same path appears in multiple\n                 * inputs and the action is NONE, but only one input is actually PROJECT. In this specific\n                 * case we will ignore all other inputs.\n                 */\n\n                Set<IncrementalFileMergerInput> projectInputs =\n                        contentMap.keySet().stream()\n                                .filter(i -> contentMap.get(i).getScopes().contains(QualifiedContent.Scope.PROJECT))\n                                .collect(Collectors.toSet());\n\n                IncrementalFileMergerOutput output = new DelegateIncrementalFileMergerOutput(baseOutput) {\n                    @Override\n                    public void create(\n                            @NonNull String path,\n                            @NonNull List<IncrementalFileMergerInput> inputs) {\n                        super.create(path, filter(path, inputs));\n                    }\n\n                    @Override\n                    public void update(\n                            @NonNull String path,\n                            @NonNull List<String> prevInputNames,\n                            @NonNull List<IncrementalFileMergerInput> inputs) {\n                        super.update(path, prevInputNames, filter(path, inputs));\n                    }\n\n                    @Override\n                    public void remove(@NonNull String path) {\n                        super.remove(path);\n                    }\n\n                    @NonNull\n                    private ImmutableList<IncrementalFileMergerInput> filter(\n                            @NonNull String path,\n                            @NonNull List<IncrementalFileMergerInput> inputs) {\n                        PackagingFileAction packagingAction = packagingOptions.getAction(path);\n                        if (packagingAction == PackagingFileAction.NONE\n                                && inputs.stream().anyMatch(projectInputs::contains)) {\n                            inputs = inputs.stream()\n                                    .filter(projectInputs::contains)\n                                    .collect(ImmutableCollectors.toImmutableList());\n                        }\n\n                        return ImmutableList.copyOf(inputs);\n                    }\n                };\n\n                state = IncrementalFileMerger.merge(ImmutableList.copyOf(inputs), output, state);\n                saveMergeState(state);\n\n                cacheUpdates.forEach(Runnable::run);\n                return null;\n            }\n        });\n\n        for (AwbTransform awbTransform : appVariantOutputContext.getAwbTransformMap().values()) {\n\n            File awbCacheDir = new File(intermediateDir, \"awb-zip-cache\" + File.separator + awbTransform.getAwbBundle().getName());\n            waitableExecutor.execute(new Callable<Void>() {\n                @Override\n                public Void call() throws Exception {\n                    FileUtils.mkdirs(awbCacheDir);\n                    FileCacheByPath zipCache = new FileCacheByPath(awbCacheDir);\n                    ParsedPackagingOptions packagingOptions = new ParsedPackagingOptions(AtlasMergeJavaResourcesTransform.this.packagingOptions);\n                    boolean full = false;\n                    IncrementalFileMergerState state = loadAwbMergeState(awbTransform.getAwbBundle());\n                    if (state == null || !invocation.isIncremental()) {\n                        /*\n                         * This is a full build.\n                         */\n                        state = new IncrementalFileMergerState();\n                        if (appVariantOutputContext.getAwbJniFolder(awbTransform.getAwbBundle()).exists() && mergedType.contains(ExtendedContentType.NATIVE_LIBS)) {\n                            FileUtils.deleteDirectoryContents(appVariantOutputContext.getAwbJniFolder(awbTransform.getAwbBundle()));\n                        }\n                        if (appVariantOutputContext.getAwbJavaResFolder(awbTransform.getAwbBundle()).exists() && mergedType.contains(QualifiedContent.DefaultContentType.RESOURCES)) {\n                            FileUtils.deleteDirectoryContents(appVariantOutputContext.getAwbJavaResFolder(awbTransform.getAwbBundle()));\n                        }\n\n                        full = true;\n                    }\n\n                    List<Runnable> cacheUpdates = new ArrayList<>();\n\n                    Map<IncrementalFileMergerInput, QualifiedContent> contentMap = new HashMap<>();\n                    List<IncrementalFileMergerInput> inputs =\n                            new ArrayList<>(\n                                    AtlasIncrementalFileMergeTransformUtils.toInput(\n                                            invocation,\n                                            zipCache,\n                                            cacheUpdates,\n                                            full,\n                                            contentMap, awbTransform,appVariantOutputContext.getVariantContext().getVariantName()));\n\n\n\n\n                    /*\n                     * In an ideal world, we could just send the inputs to the file merger. However, in the\n                     * real world we live in, things are more complicated :)\n                     *\n                     * We need to:\n                     *\n                     * 1. We need to bring inputs that refer to the project scope before the other inputs.\n                     * 2. Prefix libraries that come from directories with \"lib/\".\n                     * 3. Filter all inputs to remove anything not accepted by acceptedPathsPredicate neither\n                     * by packagingOptions.\n                     */\n\n                    // Sort inputs to move project scopes to the start.\n                    inputs.sort((i0, i1) -> {\n                        int v0 = contentMap.get(i0).getScopes().contains(QualifiedContent.Scope.PROJECT) ? 0 : 1;\n                        int v1 = contentMap.get(i1).getScopes().contains(QualifiedContent.Scope.PROJECT) ? 0 : 1;\n                        return v0 - v1;\n                    });\n\n                    // Prefix libraries with \"lib/\" if we're doing libraries.\n                    assert mergedType.size() == 1;\n                    QualifiedContent.ContentType mergedType = AtlasMergeJavaResourcesTransform.this.mergedType.iterator().next();\n                    if (mergedType == ExtendedContentType.NATIVE_LIBS) {\n                        inputs =\n                                inputs.stream()\n                                        .map(\n                                                i -> {\n                                                    QualifiedContent qc = contentMap.get(i);\n                                                    if (qc.getFile().isDirectory()) {\n                                                        i =\n                                                                new RenameIncrementalFileMergerInput(\n                                                                        i,\n                                                                        s -> \"lib/\" + s,\n                                                                        s -> s.substring(\"lib/\".length()));\n                                                        contentMap.put(i, qc);\n                                                    }\n\n                                                    return i;\n                                                })\n                                        .collect(Collectors.toList());\n                    }\n\n                    // Filter inputs.\n                    Predicate<String> inputFilter =\n                            acceptedPathsPredicate.and(\n                                    path -> packagingOptions.getAction(path) != PackagingFileAction.EXCLUDE);\n                    inputs = inputs.stream()\n                            .map(i -> {\n                                IncrementalFileMergerInput i2 =\n                                        new FilterIncrementalFileMergerInput(i, inputFilter);\n                                contentMap.put(i2, contentMap.get(i));\n                                return i2;\n                            })\n                            .collect(Collectors.toList());\n\n                    /*\n                     * Create the algorithm used by the merge transform. This algorithm decides on which\n                     * algorithm to delegate to depending on the packaging option of the path. By default it\n                     * requires just one file (no merging).\n                     */\n                    StreamMergeAlgorithm mergeTransformAlgorithm = StreamMergeAlgorithms.select(path -> {\n                        PackagingFileAction packagingAction = packagingOptions.getAction(path);\n                        switch (packagingAction) {\n                            case EXCLUDE:\n                                // Should have been excluded from the input.\n                                throw new AssertionError();\n                            case PICK_FIRST:\n                                return StreamMergeAlgorithms.pickFirst();\n                            case MERGE:\n                                return StreamMergeAlgorithms.concat();\n                            case NONE:\n                                return StreamMergeAlgorithms.acceptOnlyOne();\n                            default:\n                                throw new AssertionError();\n                        }\n                    });\n\n                    /*\n                     * Create an output that uses the algorithm. This is not the final output because,\n                     * unfortunately, we still have the complexity of the project scope overriding other scopes\n                     * to solve.\n                     *\n                     * When resources inside a jar file are extracted to a directory, the results may not be\n                     * expected on Windows if the file names end with \".\" (bug 65337573), or if there is an\n                     * uppercase/lowercase conflict. To work around this issue, we copy these resources to a\n                     * jar file.\n                     */\n                    IncrementalFileMergerOutput baseOutput;\n                    if (mergedType == QualifiedContent.DefaultContentType.RESOURCES) {\n                        File outputLocation = new File(appVariantOutputContext.getAwbJavaResFolder(awbTransform.getAwbBundle()), \"res.jar\");\n                        if (!appVariantOutputContext.getAwbJavaResFolder(awbTransform.getAwbBundle()).exists()) {\n                            appVariantOutputContext.getAwbJavaResFolder(awbTransform.getAwbBundle()).mkdirs();\n                        }\n                        createEmptyZipFile(outputLocation);\n                        baseOutput =\n                                IncrementalFileMergerOutputs.fromAlgorithmAndWriter(\n                                        mergeTransformAlgorithm, MergeOutputWriters.toZip(outputLocation));\n                    } else {\n                        File outputLocation = appVariantOutputContext.getAwbJniFolder(awbTransform.getAwbBundle());\n                        baseOutput =\n                                IncrementalFileMergerOutputs.fromAlgorithmAndWriter(\n                                        mergeTransformAlgorithm,\n                                        MergeOutputWriters.toDirectory(outputLocation));\n                    }\n\n                    /*\n                     * We need a custom output to handle the case in which the same path appears in multiple\n                     * inputs and the action is NONE, but only one input is actually PROJECT. In this specific\n                     * case we will ignore all other inputs.\n                     */\n\n                    Set<IncrementalFileMergerInput> projectInputs =\n                            contentMap.keySet().stream()\n                                    .filter(i -> contentMap.get(i).getScopes().contains(QualifiedContent.Scope.PROJECT))\n                                    .collect(Collectors.toSet());\n\n                    IncrementalFileMergerOutput output = new DelegateIncrementalFileMergerOutput(baseOutput) {\n                        @Override\n                        public void create(\n                                @NonNull String path,\n                                @NonNull List<IncrementalFileMergerInput> inputs) {\n                            super.create(path, filter(path, inputs));\n                        }\n\n                        @Override\n                        public void update(\n                                @NonNull String path,\n                                @NonNull List<String> prevInputNames,\n                                @NonNull List<IncrementalFileMergerInput> inputs) {\n                            super.update(path, prevInputNames, filter(path, inputs));\n                        }\n\n                        @Override\n                        public void remove(@NonNull String path) {\n                            super.remove(path);\n                        }\n\n                        @NonNull\n                        private ImmutableList<IncrementalFileMergerInput> filter(\n                                @NonNull String path,\n                                @NonNull List<IncrementalFileMergerInput> inputs) {\n                            PackagingFileAction packagingAction = packagingOptions.getAction(path);\n                            if (packagingAction == PackagingFileAction.NONE\n                                    && inputs.stream().anyMatch(projectInputs::contains)) {\n                                inputs = inputs.stream()\n                                        .filter(projectInputs::contains)\n                                        .collect(ImmutableCollectors.toImmutableList());\n                            }\n\n                            return ImmutableList.copyOf(inputs);\n                        }\n                    };\n\n                    state = IncrementalFileMerger.merge(ImmutableList.copyOf(inputs), output, state);\n                    saveAwbMergeState(state, awbTransform.getAwbBundle());\n\n                    cacheUpdates.forEach(Runnable::run);\n\n                    return null;\n                }\n            });\n\n\n        }\n\n\n        try {\n            waitableExecutor.waitForTasksWithQuickFail(false);\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n\n        appVariantOutputContext.getAwbTransformMap().values().stream().forEach(awbTransform -> {\n            if (awbTransform.getAwbBundle().isMBundle) {\n                if (mergedType.contains(ExtendedContentType.NATIVE_LIBS)) {\n                    File bundleOutputLocation = appVariantOutputContext.getAwbJniFolder(awbTransform.getAwbBundle());\n                    if (bundleOutputLocation.exists()) {\n                        try {\n\n                            org.apache.commons.io.FileUtils.copyDirectory(bundleOutputLocation, outputLocation);\n                            org.apache.commons.io.FileUtils.deleteDirectory(bundleOutputLocation);\n                        } catch (IOException e) {\n                            e.printStackTrace();\n                        }\n                    }\n\n                } else {\n                    File bundleOutputLocation = new File(appVariantOutputContext.getAwbJavaResFolder(awbTransform.getAwbBundle()), \"res.jar\");\n                    File tempDir = new File(outputLocation.getParentFile(), \"unzip\");\n                    try {\n                        if (bundleOutputLocation.exists() && ZipUtils.isZipFile(bundleOutputLocation)) {\n                            BetterZip.unzipDirectory(bundleOutputLocation, tempDir);\n                        }\n                    } catch (IOException e) {\n                        e.printStackTrace();\n                    }\n                }\n            }\n        });\n\n        if (!mergedType.contains(ExtendedContentType.NATIVE_LIBS)) {\n            File tempDir = new File(outputLocation.getParentFile(), \"unzip\");\n            if (outputLocation != null && outputLocation.exists() && ZipUtils.isZipFile(outputLocation)) {\n                BetterZip.unzipDirectory(outputLocation, tempDir);\n            }\n            if (tempDir.exists() && tempDir.listFiles() != null) {\n                FileUtils.deleteIfExists(outputLocation);\n                BetterZip.zipDirectory(tempDir, outputLocation);\n            }\n\n        }\n\n\n        paths.parallelStream().forEach(s ->  processAtlasNativeSo(s));\n\n\n    }\n\n\n\n    private void createEmptyZipFile(File outputLocation) throws IOException {\n        ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outputLocation)));\n        zipOutputStream.close();\n\n    }\n\n    private IncrementalFileMergerState loadAwbMergeState(AwbBundle awbBundle) throws IOException {\n        File incrementalFile = incrementalAwbStateFile(awbBundle);\n        if (!incrementalFile.isFile()) {\n            return null;\n        }\n\n        try (ObjectInputStream i = new ObjectInputStream(new FileInputStream(incrementalFile))) {\n            return (IncrementalFileMergerState) i.readObject();\n        } catch (ClassNotFoundException e) {\n            throw new IOException(e);\n        }\n\n    }\n\n    @Nullable\n    private IncrementalFileMergerState loadMergeState() throws IOException {\n        File incrementalFile = incrementalStateFile();\n        if (!incrementalFile.isFile()) {\n            return null;\n        }\n\n        try (ObjectInputStream i = new ObjectInputStream(new FileInputStream(incrementalFile))) {\n            return (IncrementalFileMergerState) i.readObject();\n        } catch (ClassNotFoundException e) {\n            throw new IOException(e);\n        }\n    }\n\n    /**\n     * Save the incremental merge state.\n     *\n     * @param state the state\n     * @throws IOException failed to save the state\n     */\n    private void saveMergeState(@NonNull IncrementalFileMergerState state) throws IOException {\n        File incrementalFile = incrementalStateFile();\n\n        FileUtils.mkdirs(incrementalFile.getParentFile());\n        try (ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream(incrementalFile))) {\n            o.writeObject(state);\n        }\n    }\n\n\n    private void saveAwbMergeState(@NonNull IncrementalFileMergerState state, AwbBundle awbBundle) throws IOException {\n        File incrementalFile = incrementalAwbStateFile(awbBundle);\n\n        FileUtils.mkdirs(incrementalFile.getParentFile());\n        try (ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream(incrementalFile))) {\n            o.writeObject(state);\n        }\n    }\n\n    @NonNull\n    private File incrementalStateFile() {\n        return new File(intermediateDir, \"merge-state\");\n    }\n\n    @NonNull\n    private File incrementalAwbStateFile(AwbBundle awbBundle) {\n        return new File(intermediateDir, \"awb-merge-state\" + File.pathSeparator + awbBundle.getName());\n    }\n\n\n    public class NativeInfo {\n        public String path;\n        public String url;\n        public String md5;\n        public String bundleName;\n\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/AtlasProguardTransform.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.transform;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.api.transform.*;\nimport com.android.build.api.transform.QualifiedContent.ContentType;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.pipeline.OriginalStream;\nimport com.android.build.gradle.internal.pipeline.TransformManager;\nimport static com.android.SdkConstants.DOT_JAR;\nimport static com.android.builder.model.AndroidProject.FD_OUTPUTS;\nimport static com.android.utils.FileUtils.mkdirs;\nimport static com.android.utils.FileUtils.renameTo;\nimport static com.google.common.base.Preconditions.checkNotNull;\nimport com.android.build.gradle.internal.pipeline.TransformTask;\nimport com.android.build.gradle.internal.scope.GlobalScope;\nimport com.android.build.gradle.internal.transforms.BaseProguardAction;\nimport com.android.build.gradle.internal.transforms.ProGuardTransform;\nimport com.android.build.gradle.internal.transforms.ProguardConfigurable;\nimport com.android.build.gradle.tasks.SimpleWorkQueue;\nimport com.android.builder.tasks.Job;\nimport com.android.builder.tasks.JobContext;\nimport com.google.common.base.Joiner;\nimport com.google.common.base.Supplier;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Lists;\nimport com.google.common.util.concurrent.SettableFuture;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.extension.TBuildConfig;\nimport com.taobao.android.builder.tasks.app.BuildAtlasEnvTask;\nimport com.taobao.android.builder.tools.FileNameUtils;\nimport com.taobao.android.builder.tools.Profiler;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport com.taobao.android.builder.tools.log.FileLogger;\nimport com.taobao.android.builder.tools.proguard.AtlasProguardHelper;\nimport com.taobao.android.builder.tools.proguard.BundleProguarder;\nimport com.taobao.android.builder.tools.proguard.KeepOnlyConfigurationParser;\nimport com.taobao.android.builder.tools.proguard.domain.Input;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.IOUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.file.ConfigurableFileCollection;\nimport proguard.ClassPath;\nimport proguard.ClassPathEntry;\nimport proguard.Configuration;\nimport proguard.ParseException;\n\nimport java.io.BufferedWriter;\nimport java.io.File;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.concurrent.ExecutionException;\n\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactScope.ALL;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactScope.EXTERNAL;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactType.CLASSES;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactType.PROGUARD_RULES;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH;\nimport static com.android.build.gradle.internal.publishing.AndroidArtifacts.ConsumedConfigType.RUNTIME_CLASSPATH;\n\n/**\n * Created by wuzhong on 2017/4/25.\n */\npublic class AtlasProguardTransform extends ProGuardTransform {\n\n    public AppVariantContext appVariantContext;\n    public ProGuardTransform oldTransform;\n    public TransformTask nextTransformTask;\n\n    private TBuildConfig buildConfig;\n    private final File printMapping;\n    private final File dump;\n    private final File printSeeds;\n    private final File printUsage;\n    private final ImmutableList<File> secondaryFileOutputs;\n    private File testedMappingFile = null;\n    private org.gradle.api.artifacts.Configuration testMappingConfiguration = null;\n\n    static boolean firstTime = true;\n\n    List<File> defaultProguardFiles = new ArrayList<>();\n    private List<File> nonConsumerProguardFiles = new ArrayList<>();\n\n    private File proguardOut;\n\n    private ConfigurableFileCollection oldConfigurableFileCollection;\n\n    @Override\n    public Set<ContentType> getOutputTypes() {\n        if (appVariantContext.getAtlasExtension().getTBuildConfig().isFastProguard() && !appVariantContext.getAtlasExtension().getTBuildConfig().isKeepJavaResAfterProguard()) {\n            return TransformManager.CONTENT_CLASS;\n        }\n        return super.getOutputTypes();\n    }\n\n    public AtlasProguardTransform(AppVariantContext appVariantContext) {\n        super(appVariantContext.getScope());\n        this.appVariantContext = appVariantContext;\n        this.buildConfig = appVariantContext.getAtlasExtension().getTBuildConfig();\n        proguardOut = new File(Joiner.on(File.separatorChar).join(\n                String.valueOf(appVariantContext.getScope().getGlobalScope().getBuildDir()),\n                FD_OUTPUTS,\n                \"mapping\",\n                appVariantContext.getScope().getVariantConfiguration().getDirName()));\n\n        printMapping = new File(proguardOut, \"mapping.txt\");\n        dump = new File(proguardOut, \"dump.txt\");\n        printSeeds = new File(proguardOut, \"seeds.txt\");\n        printUsage = new File(proguardOut, \"usage.txt\");\n        secondaryFileOutputs = ImmutableList.of(printMapping, dump, printSeeds, printUsage);\n\n    }\n\n\n    @Override\n    public boolean isCacheable() {\n        return false;\n    }\n\n    @Override\n    public void transform(TransformInvocation invocation) throws TransformException {\n        firstTime = true;\n         oldConfigurableFileCollection = (ConfigurableFileCollection) ReflectUtils.getField(ProguardConfigurable.class, oldTransform,\n                \"configurationFiles\");\n\n        //原本官方支持consumerproguardFiles,但是在手淘环境下，业务方胡乱配置优化参数，会导致各种问题，所以在fastprogaurd情况下,我们认为consumerproguardfiles无效，只能在app工程下统一配置proguard\n        if (appVariantContext.getAtlasExtension().getTBuildConfig().isFastProguard()) {\n            defaultProguardFiles.addAll(\n                    appVariantContext.getVariantData().getVariantConfiguration().getBuildType().getProguardFiles());\n        } else {\n\n            defaultProguardFiles.addAll(appVariantContext.getVariantData().getVariantConfiguration().getBuildType().getProguardFiles());\n            nonConsumerProguardFiles.addAll(\n                    appVariantContext.getVariantData().getVariantConfiguration().getBuildType().getProguardFiles());\n\n        }\n\n        if (buildConfig.getConsumerProguardEnabled()){\n            nonConsumerProguardFiles.addAll(appVariantContext.getScope().getArtifactFileCollection(COMPILE_CLASSPATH,ALL,PROGUARD_RULES).getFiles());\n\n        }\n\n        List<AwbBundle> awbBundles = AtlasBuildContext.androidDependencyTrees.get(\n                appVariantContext.getScope().getVariantConfiguration().getFullName()).getAwbBundles();\n        if (awbBundles != null && awbBundles.size() > 0) {\n            File bundleRKeepFile = new File(appVariantContext.getBaseVariantData().getScope().getGlobalScope().getIntermediatesDir(), \"awb-progrard/bundleRKeep.cfg\");\n            if (!bundleRKeepFile.getParentFile().exists()) {\n                bundleRKeepFile.getParentFile().mkdirs();\n            }\n\n            StringBuilder keepRStr = new StringBuilder();\n            for (AwbBundle bundleItem : awbBundles) {\n                keepRStr.append(String.format(\"-keep class %s.R{*;}\\n\", bundleItem.bundleInfo.getPkgName()));\n                keepRStr.append(String.format(\"-keep class %s.R$*{*;}\\n\", bundleItem.bundleInfo.getPkgName()));\n            }\n            try {\n                BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(bundleRKeepFile));\n                bufferedWriter.write(keepRStr.toString());\n                bufferedWriter.flush();\n                IOUtils.closeQuietly(bufferedWriter);\n                FileLogger.getInstance(\"proguard\").log(\"R keep infos: \" + keepRStr);\n            } catch (IOException e) {\n                throw new RuntimeException(\"generate bundleRkeepFile failed\", e);\n            }\n            appVariantContext.getBaseVariantData().getVariantConfiguration().getBuildType().getProguardFiles().add(bundleRKeepFile);\n            defaultProguardFiles.add(bundleRKeepFile);\n        }\n\n        if (appVariantContext.getAtlasExtension().getTBuildConfig().isFastProguard()) {\n            fastTransform(invocation);\n            return;\n        }\n\n        try {\n\n            oldConfigurableFileCollection = appVariantContext.getProject().files().from(nonConsumerProguardFiles);\n\n            ReflectUtils.updateField(this, \"configurationFiles\", oldConfigurableFileCollection);\n\n\n//            Configuration configuration = (Configuration) ReflectUtils.getField(BaseProguardAction.class,\n//                    oldTransform, \"configuration\");\n//            if (null == this.configuration.keep) {\n//                this.configuration.keep = new ArrayList();\n//            }\n//            if (null != configuration.keep) {\n//                this.configuration.keep.addAll(configuration.keep);\n//            }\n//\n        } catch (Exception e) {\n            throw new GradleException(e.getMessage(), e);\n        }\n\n        //apply bundle Inout\n        AtlasProguardHelper.applyBundleInOutConfigration(appVariantContext, this);\n\n        //apply bundle's configuration, Switch control\n        if (buildConfig.isBundleProguardConfigEnabled()) {\n            AtlasProguardHelper.applyBundleProguardConfigration(appVariantContext, this);\n        }\n\n        //apply mapping\n        AtlasProguardHelper.applyMapping(appVariantContext, this);\n\n        //set output\n        File proguardOutFile = new File(appVariantContext.getProject().getBuildDir(), \"outputs/proguard.cfg\");\n        this.printconfiguration(proguardOutFile);\n\n        doTransform(invocation);\n    }\n\n    private void doTransform(TransformInvocation invocation) {\n        SettableFuture<TransformOutputProvider> resultFuture = SettableFuture.create();\n        final Job<Void> job = new Job<>(getName(),\n                new com.android.builder.tasks.Task<Void>() {\n                    @Override\n                    public void run(@NonNull Job<Void> job,\n                                    @NonNull JobContext<Void> context) throws IOException {\n                        doMinification(\n                                invocation.getInputs(),\n                                invocation.getReferencedInputs(),\n                                invocation.getOutputProvider());\n                    }\n\n                    @Override\n                    public void finished() {\n                        resultFuture.set(invocation.getOutputProvider());\n                    }\n\n                    @Override\n                    public void error(Throwable e) {\n                        resultFuture.setException(e);\n\n                    }\n                }, resultFuture);\n        try {\n            SimpleWorkQueue.push(job);\n\n            // wait for the task completion.\n            try {\n                job.awaitRethrowExceptions();\n            } catch (ExecutionException e) {\n                throw new RuntimeException(\"Job failed, see logs for details\", e.getCause());\n            }\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new RuntimeException(e);\n        }\n\n    }\n\n    private void doMinification(\n            @NonNull Collection<TransformInput> inputs,\n            @NonNull Collection<TransformInput> referencedInputs,\n            @Nullable TransformOutputProvider output) throws IOException {\n        Set<ContentType> outputTypes = getOutputTypes();\n        Set<QualifiedContent.Scope> scopes = (Set<QualifiedContent.Scope>) getScopes();\n        File outFile = output.getContentLocation(\"main\", outputTypes, scopes,\n                Format.JAR);\n            mkdirs(outFile.getParentFile());\n\n        try {\n            GlobalScope globalScope = appVariantContext.getScope().getGlobalScope();\n\n            // set the mapping file if there is one.\n            File testedMappingFile = computeMappingFile();\n            if (testedMappingFile != null) {\n                applyMapping(testedMappingFile);\n            }\n\n            // --- InJars / LibraryJars ---\n            addInputsToConfiguration(inputs, false);\n            addInputsToConfiguration(referencedInputs, true);\n\n            // libraryJars: the runtime jars, with all optional libraries.\n            for (File runtimeJar : ((GlobalScope) globalScope).getAndroidBuilder().getBootClasspath(true)) {\n                libraryJar(runtimeJar);\n            }\n\n            // --- Out files ---\n            outJar(outFile);\n\n            // proguard doesn't verify that the seed/mapping/usage folders exist and will fail\n            // if they don't so create them.\n            mkdirs(proguardOut);\n\n\n            for (File configFile : oldConfigurableFileCollection.getFiles()) {\n//                for (File file:(Collection<File>)((Supplier)configFile).get()){\n                    applyConfigurationFile(configFile);\n//                }\n            }\n\n            configuration.printMapping = printMapping;\n            configuration.dump = dump;\n            configuration.printSeeds = printSeeds;\n            configuration.printUsage = printUsage;\n\n            forceprocessing();\n            runProguard();\n\n\n        } catch (Exception e) {\n            if (e instanceof IOException) {\n                throw (IOException) e;\n            }\n\n            throw new IOException(e);\n        }\n    }\n\n    private void addInputsToConfiguration(\n            @NonNull Collection<TransformInput> inputs,\n            boolean referencedOnly) {\n        ClassPath classPath;\n        List<String> baseFilter;\n\n        if (referencedOnly) {\n            classPath = configuration.libraryJars;\n            baseFilter = JAR_FILTER;\n        } else {\n            classPath = configuration.programJars;\n            baseFilter = null;\n        }\n\n        for (TransformInput transformInput : inputs) {\n            for (JarInput jarInput : transformInput.getJarInputs()) {\n                handleQualifiedContent(classPath, jarInput, baseFilter);\n            }\n\n            for (DirectoryInput directoryInput : transformInput.getDirectoryInputs()) {\n                handleQualifiedContent(classPath, directoryInput, baseFilter);\n            }\n        }\n    }\n\n    private void handleQualifiedContent(\n            @NonNull ClassPath classPath,\n            @NonNull QualifiedContent content,\n            @Nullable List<String> baseFilter) {\n        List<String> filter = baseFilter;\n\n        if (!content.getContentTypes().contains(QualifiedContent.DefaultContentType.CLASSES)) {\n            // if the content is not meant to contain classes, we ignore them\n            // in case they are present.\n            ImmutableList.Builder<String> builder = ImmutableList.builder();\n            if (filter != null) {\n                builder.addAll(filter);\n            }\n            builder.add(\"!**.class\");\n            filter = builder.build();\n        } else if (!content.getContentTypes().contains(QualifiedContent.DefaultContentType.RESOURCES)) {\n            // if the content is not meant to contain resources, we ignore them\n            // in case they are present (by accepting only classes.)\n            filter = ImmutableList.of(\"**.class\");\n        }\n\n        inputJar(classPath, content.getFile(), filter);\n    }\n\n    @Nullable\n    private File computeMappingFile() {\n        if (testedMappingFile != null && testedMappingFile.isFile()) {\n            return testedMappingFile;\n        } else if (testMappingConfiguration != null && testMappingConfiguration.getSingleFile().isFile()) {\n            return testMappingConfiguration.getSingleFile();\n        }\n\n        return null;\n    }\n\n    public void fastTransform(TransformInvocation invocation) throws TransformException {\n\n        try {\n\n            Profiler.start(\"start\");\n\n            List<File> mainJars = new ArrayList<>();\n            for (TransformInput transformInput : invocation.getInputs()) {\n                for (JarInput jarInput : transformInput.getJarInputs()) {\n                    if (AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).inMainDex(jarInput)) {\n                        mainJars.add(jarInput.getFile());\n                    }\n                }\n            }\n\n            Profiler.enter(\"bundleproguard\");\n            //Do the concurrent proguard for the bundle, and the cache first\n            AtlasProguardHelper.doBundleProguard(appVariantContext, mainJars);\n            Profiler.release();\n\n            Profiler.enter(\"mainproguard\");\n            doMainBundleProguard(invocation);\n            Profiler.release();\n\n            Profiler.release();\n\n            //if (appVariantContext.getProject().getGradle().getStartParameter().isProfile()) {\n            //    appVariantContext.getProject().getLogger().warn(\"proguard profile >>>>>\" );\n            //    appVariantContext.getProject().getLogger().warn( Profiler.dump());\n            //}\n            FileLogger.getInstance(\"proguard\").log(Profiler.dump());\n\n        } catch (Exception e) {\n            throw new GradleException(e.getMessage(), e);\n        }\n    }\n\n    private void doMainBundleProguard(TransformInvocation invocation) throws Exception {\n\n        //apply bundle Inout\n        Profiler.enter(\"bundleKeep\");\n        File bundleKeep = AtlasProguardHelper.generateBundleKeepCfg(appVariantContext);\n        Profiler.release();\n\n        Input input = new Input();\n        AwbBundle awbBundle = new AwbBundle();\n        awbBundle.getAndroidLibraries().addAll(AtlasBuildContext.androidDependencyTrees.get(appVariantContext.getVariantName()).getMainBundle().getAndroidLibraries());\n        AwbTransform awbTransform = new AwbTransform(awbBundle);\n        input.getAwbBundles().add(awbTransform);\n\n        List<File> unProguardJars = new ArrayList<>();\n        //Enter the input\n        for (TransformInput transformInput : invocation.getInputs()) {\n            for (JarInput jarInput : transformInput.getJarInputs()) {\n                File file = jarInput.getFile();\n                if (file.getName().startsWith(\"combined-rmerge\")) {\n                    unProguardJars.add(file);\n                } else if (AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).inMainDex(jarInput)) {\n                    awbTransform.getInputLibraries().add(file);\n                }\n            }\n            for (DirectoryInput directoryInput : transformInput.getDirectoryInputs()) {\n                if (AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).getInputDirs().contains(directoryInput.getFile())) {\n                    awbTransform.getInputLibraries().add(directoryInput.getFile());\n                }\n            }\n        }\n\n        //inputting librarys\n        input.getLibraries().addAll(\n                appVariantContext.getScope().getGlobalScope().getAndroidBuilder().getBootClasspath(true));\n        input.getLibraries().addAll(unProguardJars);\n\n        //The default proguard configuration\n        input.getDefaultProguardFiles().addAll(defaultProguardFiles);\n\n        //bundle keeps\n        input.getParentKeeps().add(bundleKeep);\n\n        File outFile = invocation.getOutputProvider().getContentLocation(\"main\", getOutputTypes(), getScopes(),\n                Format.JAR);\n\n        outFile.delete();\n        input.proguardOutputDir = invocation.getOutputProvider().getContentLocation(\"main\", getOutputTypes(), getScopes(),\n                Format.DIRECTORY);\n        input.printMapping = (File) ReflectUtils.getField(oldTransform, \"printMapping\");\n        input.dump = (File) ReflectUtils.getField(oldTransform, \"dump\");\n        input.printSeeds = (File) ReflectUtils.getField(oldTransform, \"printSeeds\");\n        input.printUsage = (File) ReflectUtils.getField(oldTransform, \"printUsage\");\n        input.printConfiguration = new File(appVariantContext.getProject().getBuildDir(), \"outputs/proguard.cfg\");\n\n        Profiler.enter(\"executeproguard\");\n        BundleProguarder.execute(appVariantContext, input);\n        transformInput(input);\n\n        Profiler.release();\n\n        for (File jar : unProguardJars) {\n\n            File to = invocation.getOutputProvider().getContentLocation(FileNameUtils.getUniqueJarName(jar),\n                    getOutputTypes(), getScopes(),\n                    Format.JAR);\n            FileUtils.copyFile(jar, to);\n\n        }\n\n        OriginalStream originalStream = OriginalStream.builder(appVariantContext.getProject(), \"proguard-classes\")\n                .addContentTypes(com.android.build.gradle.internal.pipeline.TransformManager.CONTENT_CLASS)\n                .addScope(QualifiedContent.Scope.PROJECT)\n                .setFileCollection(appVariantContext.getProject().files(AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).getAllMainDexJars()))\n                .build();\n\n        if (nextTransformTask != null) {\n            Collection consumedInputStreams = (Collection) ReflectUtils.getField(nextTransformTask, \"consumedInputStreams\");\n            if (appVariantContext.getAtlasExtension().getTBuildConfig().isFastProguard() && consumedInputStreams != null) {\n                consumedInputStreams.add(originalStream);\n            }\n        }\n\n    }\n\n    private  void transformInput(Input input) {\n        if (input.maindexFileTransform.size() == 0 && input.maindexFolderTransform.size() == 0) {\n            return;\n        }\n        AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).updateMainDexFiles2(input.maindexFileTransform);\n        if (input.maindexFolderTransform.size() > 0) {\n            AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).getInputDirs().clear();\n            for (File file : input.maindexFolderTransform.values()) {\n                AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).addMainDex(new BuildAtlasEnvTask.FileIdentity(file.getName(), file, false, false));\n            }\n        }\n\n    }\n\n\n    @Override\n    public void applyConfigurationFile(File file) throws IOException, ParseException {\n        //appVariantContext.getVariantConfiguration().getProguardFiles(false, new ArrayList<>());\n//        if (buildConfig.isLibraryProguardKeepOnly() && !nonConsumerProguardFiles.contains(file)) {\n//            appVariantContext.getProject().getLogger().info(\"applyConfigurationFile keep only :\" + file);\n//            applyLibConfigurationFile(file);\n//            return;\n//        }\n        appVariantContext.getProject().getLogger().info(\"applyConfigurationFile :\" + file);\n        super.applyConfigurationFile(file);\n    }\n\n\n\n\n    public void applyLibConfigurationFile(@NonNull File file) throws IOException, ParseException {\n        KeepOnlyConfigurationParser parser =\n                new KeepOnlyConfigurationParser(file, System.getProperties());\n        try {\n            parser.parse(configuration);\n        } finally {\n            parser.close();\n        }\n    }\n\n\n    @Override\n    protected void outJar(@NonNull File file) {\n        if (firstTime) {\n            AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).getMainDexFiles().clear();\n            AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).getInputDirs().clear();\n\n            firstTime = false;\n        }\n        BuildAtlasEnvTask.FileIdentity fileIdentity = new BuildAtlasEnvTask.FileIdentity(\"proguard-main\", file, false, false);\n        AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).getMainDexFiles().add(fileIdentity);\n        super.outJar(file);\n    }\n\n    @Override\n    protected void inputJar(\n            @NonNull ClassPath classPath, @NonNull File file, @Nullable List<String> filter) {\n        if (file.isDirectory()) {\n            super.inputJar(classPath, file, filter);\n        } else {\n            if (AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).inMainDex(file)) {\n                super.inputJar(classPath, file, filter);\n            } else if (appVariantContext.getScope().getGlobalScope().getAndroidBuilder().getBootClasspath(true).contains(file)) {\n                super.inputJar(classPath, file, filter);\n            } else if (AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).getInputDirs().contains(file)) {\n                super.inputJar(classPath, file, filter);\n\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/AtlasTransformUtils.java",
    "content": "package com.taobao.android.builder.tasks.transform;\n\nimport com.android.build.api.transform.TransformInvocation;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.transforms.TransformInputUtil;\n\nimport com.google.common.collect.ImmutableSet;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\n\nimport java.io.File;\nimport java.util.Collection;\n\npublic final class AtlasTransformUtils {\n    private AtlasTransformUtils() {\n    }\n\n    public static Collection<File> getTransformInputs(AppVariantContext appVariantContext,\n            TransformInvocation invocation) {\n        ImmutableSet.Builder<File> builder = ImmutableSet.builder();\n        Collection<File> transformInputs = TransformInputUtil.getAllFiles(invocation.getInputs());\n        builder.addAll(transformInputs);\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n                appVariantContext.getVariantConfiguration().getFullName());\n\n        if (atlasDependencyTree.getAwbBundles().size() > 0) {\n\n            BaseVariantOutput vod =\n                    (BaseVariantOutput) appVariantContext.getVariantOutputData().iterator().next();\n            AppVariantOutputContext appVariantOutputContext =\n                    appVariantContext.getAppVariantOutputContext(ApkDataUtils.get(vod));\n            Collection<AwbTransform> awbTransforms =\n                    appVariantOutputContext.getAwbTransformMap().values();\n            awbTransforms.forEach(awbTransform -> {\n                builder.addAll(awbTransform.getInputLibraries());\n            });\n        }\n        return builder.build();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/ClassInjectTransform.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tasks.transform;\n\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.pipeline.TransformManager;\nimport com.android.build.gradle.internal.publishing.AndroidArtifacts;\nimport com.android.build.gradle.internal.scope.VariantScopeImpl;\nimport com.android.ide.common.build.ApkData;\nimport com.google.common.base.Joiner;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.tasks.manager.transform.MtlInjectTransform;\nimport com.taobao.android.builder.tools.PathUtil;\nimport com.taobao.android.builder.tools.classinject.CodeInjectByJavassist;\nimport com.taobao.android.builder.tools.classinject.InjectParam;\nimport javassist.ClassPool;\nimport javassist.NotFoundException;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang3.reflect.FieldUtils;\nimport org.gradle.api.GradleException;\nimport org.gradle.api.logging.Logger;\nimport org.gradle.api.tasks.StopExecutionException;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.List;\nimport java.util.Set;\n\nimport static com.google.common.base.Preconditions.checkNotNull;\n\n/**\n * Code injection classes\n * Created by shenghua.nish on 2016-06-15 Instant in the afternoon.\n */\npublic class ClassInjectTransform extends MtlInjectTransform {\n\n    private final Logger logger;\n\n    public ClassInjectTransform(AppVariantContext appVariantContext,\n                                ApkData apkData) {\n        super(appVariantContext, apkData);\n        this.logger = appVariantContext.getProject().getLogger();\n    }\n\n    @Override\n    public String getName() {\n        return \"classInject\";\n    }\n\n    @Override\n    public Set<QualifiedContent.ContentType> getInputTypes() {\n        return TransformManager.CONTENT_CLASS;\n    }\n\n    @Override\n    public Set<QualifiedContent.ContentType> getOutputTypes() {\n        return TransformManager.CONTENT_JARS;\n    }\n\n    @Override\n    public Set<QualifiedContent.ScopeType> getScopes() {\n        return TransformManager.SCOPE_FULL_WITH_IR_FOR_DEXING;\n    }\n\n    @Override\n    public boolean isIncremental() {\n        return false;\n    }\n\n    @Override\n    public void transform(TransformInvocation transformInvocation)\n        throws TransformException, IOException, InterruptedException {\n        TransformOutputProvider outputProvider = transformInvocation.getOutputProvider();\n        checkNotNull(outputProvider, \"Missing output object for transform \" + getName());\n\n        // Gather a full list of all inputs.\n        List<JarInput> jarInputs = Lists.newArrayList();\n        List<DirectoryInput> directoryInputs = Lists.newArrayList();\n        for (TransformInput input : transformInvocation.getInputs()) {\n            jarInputs.addAll(input.getJarInputs());\n            directoryInputs.addAll(input.getDirectoryInputs());\n        }\n\n        outputProvider.deleteAll();\n        ClassPool classPool = initClassPool(jarInputs, directoryInputs);\n\n        InjectParam injectParam = null;\n        try {\n\n            injectParam = AtlasBuildContext.sBuilderAdapter.apkInjectInfoCreator.creteInjectParam(appVariantContext);\n\n            injectParam.outputFile = new File(appVariantContext.getProject().getBuildDir(),\n                                              \"outputs/atlasFrameworkProperties.json\");\n\n        } catch (Exception e) {\n            throw new TransformException(e);\n        }\n\n        for (JarInput jarInput : jarInputs) {\n\n            File to = getOutputFile(outputProvider, jarInput);\n\n            //Only to atlas Code injection, No more jarmerge\n            if (injectParam.removePreverify && !isAtlasDependency(jarInput.getFile(), to) && jarInputs.size() > 1) {\n                FileUtils.copyFile(jarInput.getFile(), to);\n            } else {\n                try {\n                    CodeInjectByJavassist.inject(classPool, jarInput.getFile(), to, injectParam);\n                } catch (Exception e) {\n                    throw new GradleException(e.getMessage(), e);\n                }\n            }\n        }\n\n        // Inject the code in the directory\n        for (DirectoryInput directoryInput : directoryInputs) {\n            if (null != logger) {\n                logger.debug(\"[ClassInject]\" + directoryInput.getFile().getAbsolutePath());\n            }\n            String folderName = directoryInput.getFile().getName();\n            File to = outputProvider.getContentLocation(folderName,\n                                                        directoryInput.getContentTypes(),\n                                                        directoryInput.getScopes(),\n                                                        Format.DIRECTORY);\n            if (!injectParam.removePreverify) {\n                try {\n                    CodeInjectByJavassist.injectFolder(classPool,\n                                                       directoryInput.getFile(),\n                                                       to,\n                                                       injectParam);\n                } catch (Exception e) {\n                    throw new GradleException(e.getMessage(), e);\n                }\n            } else {\n\n                FileUtils.copyDirectory(directoryInput.getFile(), to);\n\n            }\n        }\n    }\n\n    private boolean isAtlasDependency(File jarFile, File outputFile) {\n        return jarFile.getAbsolutePath().contains(\"atlas\") || outputFile.getAbsolutePath().contains(\"atlas\");\n    }\n\n    @Override\n    public boolean updateNextTransformInput() {\n        return true;\n    }\n\n    private ClassPool initClassPool(List<JarInput> jarInputs,\n                                    List<DirectoryInput> directoryInputs) {\n\n        if (((VariantScopeImpl)this.appVariantContext.getScope()).getVariantData()\n            .getName()\n            .toLowerCase()\n            .contains(\"debug\")) {\n            try {\n                FieldUtils.writeStaticField(ClassPool.class, \"defaultPool\", null, true);\n            } catch (IllegalAccessException e) {\n                e.printStackTrace();\n            }\n        } else {\n            //logger.warn(\">>> Do not open daemon <<<<\");\n        }\n\n        final ClassPool pool = ClassPool.getDefault();\n\n        try {\n            File verifyFile = PathUtil.getJarFile(com.taobao.verify.Verifier.class);\n            pool.insertClassPath(verifyFile.getAbsolutePath());\n            for (File file : scope.getJavaClasspath(AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH, AndroidArtifacts.ArtifactType.CLASSES)) {\n                if (file.isFile()) {\n                    pool.insertClassPath(file.getAbsolutePath());\n                } else {\n                    pool.appendClassPath(file.getAbsolutePath());\n                }\n            }\n            String path = Joiner.on(File.pathSeparator)\n                .join(scope.getGlobalScope()\n                          .getAndroidBuilder()\n                          .getBootClasspathAsStrings(false));\n            pool.appendPathList(path);\n            for (JarInput jarInput : jarInputs) {\n                pool.insertClassPath(jarInput.getFile().getAbsolutePath());\n            }\n            for (DirectoryInput directoryInput : directoryInputs) {\n                pool.appendClassPath(directoryInput.getFile().getAbsolutePath());\n            }\n        } catch (NotFoundException e) {\n            throw new StopExecutionException(e.getMessage());\n        }\n        return pool;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/ResourcesShrinker.java",
    "content": "package com.taobao.android.builder.tasks.transform;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.aapt.AaptGeneration;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.android.build.gradle.internal.dsl.AaptOptions;\nimport com.android.build.gradle.internal.pipeline.TransformManager;\nimport com.android.build.gradle.internal.scope.*;\nimport com.android.build.gradle.internal.transforms.ShrinkResourcesTransform;\nimport com.android.build.gradle.internal.variant.BaseVariantData;\nimport com.android.build.gradle.internal.variant.MultiOutputPolicy;\nimport com.android.build.gradle.tasks.ResourceUsageAnalyzer;\nimport com.android.builder.core.VariantType;\nimport com.android.ide.common.build.ApkData;\nimport com.android.ide.common.internal.WaitableExecutor;\nimport com.android.utils.FileUtils;\nimport com.google.common.collect.ImmutableList;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport org.gradle.api.file.FileCollection;\nimport org.gradle.api.logging.LogLevel;\nimport org.gradle.api.logging.Logger;\nimport org.gradle.tooling.BuildException;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.ForkJoinTask;\n\n/**\n * ResourcesShrinker\n *\n * @author zhayu.ll\n * @date 18/5/22\n */\npublic class ResourcesShrinker extends Transform {\n\n    public ShrinkResourcesTransform resourcesTransform;\n    private static boolean ourWarned = true; // Logging disabled until shrinking is on by default.\n\n    @NonNull\n    private final BaseVariantData variantData;\n\n    @NonNull\n    private final Logger logger;\n\n    @NonNull\n    private final File sourceDir;\n    @NonNull\n    private final FileCollection resourceDir;\n    @Nullable\n    private final FileCollection mappingFileSrc;\n    @NonNull\n    private final FileCollection mergedManifests;\n    @NonNull\n    private final FileCollection uncompressedResources;\n    @NonNull\n    private final FileCollection splitListInput;\n\n    @NonNull\n    private final AaptGeneration aaptGeneration;\n    @NonNull\n    private final AaptOptions aaptOptions;\n    @NonNull\n    private final VariantType variantType;\n    private final boolean isDebuggableBuildType;\n    @NonNull\n    private final MultiOutputPolicy multiOutputPolicy;\n\n    @NonNull\n    private final File compressedResources;\n\n    private AppVariantContext variantContext;\n\n\n    @Override\n    public boolean isCacheable() {\n        return true;\n    }\n\n    public ResourcesShrinker(ShrinkResourcesTransform resourcesTransform, @NonNull BaseVariantData variantData,\n                             @NonNull FileCollection uncompressedResources,\n                             @NonNull File compressedResources,\n                             @NonNull AaptGeneration aaptGeneration,\n                             @NonNull FileCollection splitListInput,\n                             @NonNull Logger logger,\n                             AppVariantContext variantContext) {\n\n        this.variantContext = variantContext;\n        this.resourcesTransform = resourcesTransform;\n        VariantScope variantScope = variantData.getScope();\n        GlobalScope globalScope = variantScope.getGlobalScope();\n        GradleVariantConfiguration variantConfig = variantData.getVariantConfiguration();\n\n        this.variantData = variantData;\n        this.logger = logger;\n\n        this.sourceDir = variantScope.getRClassSourceOutputDir();\n        this.resourceDir = variantScope.getOutput(TaskOutputHolder.TaskOutputType.MERGED_NOT_COMPILED_RES);\n        this.mappingFileSrc =\n                variantScope.hasOutput(TaskOutputHolder.TaskOutputType.APK_MAPPING)\n                        ? variantScope.getOutput(TaskOutputHolder.TaskOutputType.APK_MAPPING)\n                        : null;\n        this.mergedManifests = variantScope.getOutput(TaskOutputHolder.TaskOutputType.MERGED_MANIFESTS);\n        this.uncompressedResources = uncompressedResources;\n        this.splitListInput = splitListInput;\n\n        this.aaptGeneration = aaptGeneration;\n        this.aaptOptions = globalScope.getExtension().getAaptOptions();\n        this.variantType = variantData.getType();\n        this.isDebuggableBuildType = variantConfig.getBuildType().isDebuggable();\n        this.multiOutputPolicy = variantData.getOutputScope().getMultiOutputPolicy();\n        this.compressedResources = compressedResources;\n    }\n\n    @Override\n    public String getName() {\n        return resourcesTransform.getName();\n    }\n\n    @Override\n    public Set<QualifiedContent.ContentType> getInputTypes() {\n        return resourcesTransform.getInputTypes();\n    }\n\n    @Override\n    public Set<? super QualifiedContent.Scope> getScopes() {\n        return resourcesTransform.getScopes();\n    }\n\n    @Override\n    public boolean isIncremental() {\n        return false;\n    }\n\n    @Override\n    public void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {\n        super.transform(transformInvocation);\n        SplitList splitList = SplitList.load(splitListInput);\n        Collection<BuildOutput> uncompressedBuildOutputs = BuildOutputs.load(uncompressedResources);\n        OutputScope outputScope = variantData.getScope().getOutputScope();\n        outputScope.parallelForEachOutput(\n                uncompressedBuildOutputs,\n                TaskOutputHolder.TaskOutputType.PROCESSED_RES,\n                TaskOutputHolder.TaskOutputType.SHRUNK_PROCESSED_RES,\n                this::splitAction,\n                transformInvocation,\n                splitList);\n        outputScope.save(TaskOutputHolder.TaskOutputType.SHRUNK_PROCESSED_RES, compressedResources);\n\n\n    }\n\n    @Nullable\n    public File splitAction(\n            @NonNull ApkData apkData,\n            @Nullable File uncompressedResourceFile,\n            TransformInvocation invocation,\n            SplitList splitList) {\n\n        if (uncompressedResourceFile == null) {\n            return null;\n        }\n\n        List<File> classes = new ArrayList<>();\n        classes.addAll(AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getInputDirs());\n        classes.addAll(AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getAllMainDexJars());\n        AppVariantOutputContext appVariantOutputContext = variantContext.getAppVariantOutputContext(apkData);\n        for (AwbTransform awbTransform : appVariantOutputContext.getAwbTransformMap().values()) {\n            classes.addAll(awbTransform.getInputLibraries());\n            if (awbTransform.getInputDirs()!= null && awbTransform.getInputDirs().size() > 0) {\n                classes.addAll(awbTransform.getInputDirs());\n            }\n        }\n\n\n        WaitableExecutor executor = WaitableExecutor.useGlobalSharedThreadPool();\n\n        Collection<BuildOutput> mergedManifests = BuildOutputs.load(ResourcesShrinker.this.mergedManifests);\n        BuildOutput mergedManifest =\n                OutputScope.getOutput(mergedManifests, TaskOutputHolder.TaskOutputType.MERGED_MANIFESTS, apkData);\n        File mappingFile = mappingFileSrc != null ? mappingFileSrc.getSingleFile() : null;\n\n        ForkJoinTask<File> task = executor.execute(() -> {\n            File reportFile = null;\n            if (mappingFile != null) {\n                File logDir = mappingFile.getParentFile();\n                if (logDir != null) {\n                    reportFile = new File(logDir, \"resources.txt\");\n                }\n            }\n            File compressedResourceFile =\n                    new File(\n                            compressedResources,\n                            \"resources-\" + apkData.getBaseName() + \"-stripped.ap_\");\n            FileUtils.mkdirs(compressedResourceFile.getParentFile());\n\n\n            if (mergedManifest == null) {\n                try {\n                    FileUtils.copyFile(uncompressedResourceFile, compressedResourceFile);\n                } catch (IOException e) {\n                    logger.error(\"Failed to copy uncompressed resource file :\", e);\n                    throw new RuntimeException(\"Failed to copy uncompressed resource file\", e);\n                }\n                return compressedResourceFile;\n            }\n\n            // Analyze resources and usages and strip out unused\n            ResourceUsageAnalyzer analyzer =\n                    new ResourceUsageAnalyzer(\n                            sourceDir,\n                            classes,\n                            mergedManifest.getOutputFile(),\n                            mappingFile,\n                            resourceDir.getSingleFile(),\n                            reportFile);\n            try {\n                analyzer.setVerbose(logger.isEnabled(LogLevel.INFO));\n                analyzer.setDebug(logger.isEnabled(LogLevel.DEBUG));\n                analyzer.analyze();\n\n                // Just rewrite the .ap_ file to strip out the res/ files for unused resources\n                analyzer.rewriteResourceZip(uncompressedResourceFile, compressedResourceFile);\n\n                // Dump some stats\n                int unused = analyzer.getUnusedResourceCount();\n                if (unused > 0) {\n                    StringBuilder sb = new StringBuilder(200);\n                    sb.append(\"Removed unused resources\");\n\n                    // This is a bit misleading until we can strip out all resource types:\n                    //int total = analyzer.getTotalResourceCount()\n                    //sb.append(\"(\" + unused + \"/\" + total + \")\")\n\n                    long before = uncompressedResourceFile.length();\n                    long after = compressedResourceFile.length();\n                    long percent = (int) ((before - after) * 100 / before);\n                    sb.append(\": Binary resource data reduced from \").\n                            append(toKbString(before)).\n                            append(\"KB to \").\n                            append(toKbString(after)).\n                            append(\"KB: Removed \").append(percent).append(\"%\");\n                    if (!ourWarned) {\n                        ourWarned = true;\n                        String name = variantData.getVariantConfiguration().getBuildType().getName();\n                        sb.append(\"\\n\")\n                                .append(\n                                        \"Note: If necessary, you can disable resource shrinking by adding\\n\")\n                                .append(\"android {\\n\")\n                                .append(\"    buildTypes {\\n\")\n                                .append(\"        \")\n                                .append(name)\n                                .append(\" {\\n\")\n                                .append(\"            shrinkResources false\\n\")\n                                .append(\"        }\\n\")\n                                .append(\"    }\\n\")\n                                .append(\"}\");\n                    }\n\n                    System.out.println(sb.toString());\n                }\n            } catch (Exception e) {\n                logger.quiet(\"Failed to shrink resources: ignoring\", e);\n            } finally {\n                analyzer.dispose();\n            }\n            return compressedResourceFile;\n\n        });\n\n        for (AwbTransform awbTransform : appVariantOutputContext.getAwbTransformMap().values()) {\n            AwbBundle awbBundle = awbTransform.getAwbBundle();\n            File compressedBundleResourceFile = appVariantOutputContext.getAwbCompressResourcePackageOutputFile(awbBundle);\n            File unCompressedBundleResourceFile = appVariantOutputContext.getAwbProcessResourcePackageOutputFile(awbBundle);\n            File awbResDir = appVariantOutputContext.getAwbMergedResourceDir(variantContext.getVariantConfiguration(),awbBundle);\n            File reportFile = new File(uncompressedResourceFile.getParentFile(), \"resources.txt\");\n            File bundleSourceDir = appVariantOutputContext.getAwbRClassSourceOutputDir(variantContext.getVariantConfiguration(),awbBundle);\n            executor.execute(() -> {\n                ResourceUsageAnalyzer analyzer =\n                        new ResourceUsageAnalyzer(\n                                bundleSourceDir,\n                                classes,\n                                mergedManifest.getOutputFile(),\n                                mappingFile,\n                                awbResDir,\n                                reportFile);\n                try {\n                    analyzer.setVerbose(logger.isEnabled(LogLevel.INFO));\n                    analyzer.setDebug(logger.isEnabled(LogLevel.DEBUG));\n                    analyzer.analyze();\n\n                    // Just rewrite the .ap_ file to strip out the res/ files for unused resources\n                    analyzer.rewriteResourceZip(unCompressedBundleResourceFile, compressedBundleResourceFile);\n\n                    // Dump some stats\n                    int unused = analyzer.getUnusedResourceCount();\n                    if (unused > 0) {\n                        StringBuilder sb = new StringBuilder(200);\n                        sb.append(\"Removed awb bundle\" + awbBundle.getName() + \" unused resources\");\n\n                        // This is a bit misleading until we can strip out all resource types:\n                        //int total = analyzer.getTotalResourceCount()\n                        //sb.append(\"(\" + unused + \"/\" + total + \")\")\n\n                        long before = unCompressedBundleResourceFile.length();\n                        long after = compressedBundleResourceFile.length();\n                        long percent = (int) ((before - after) * 100 / before);\n                        sb.append(\": Binary resource data reduced from \").\n                                append(toKbString(before)).\n                                append(\"KB to \").\n                                append(toKbString(after)).\n                                append(\"KB: Removed \").append(percent).append(\"%\");\n                        if (!ourWarned) {\n                            ourWarned = true;\n                            String name = variantData.getVariantConfiguration().getBuildType().getName();\n                            sb.append(\"\\n\")\n                                    .append(\n                                            \"Note: If necessary, you can disable resource shrinking by adding\\n\")\n                                    .append(\"android {\\n\")\n                                    .append(\"    buildTypes {\\n\")\n                                    .append(\"        \")\n                                    .append(name)\n                                    .append(\" {\\n\")\n                                    .append(\"            shrinkResources false\\n\")\n                                    .append(\"        }\\n\")\n                                    .append(\"    }\\n\")\n                                    .append(\"}\");\n                        }\n\n                        System.out.println(sb.toString());\n                    }\n                } catch (Exception e) {\n                    logger.quiet(\"Failed to shrink resources: ignoring\", e);\n                } finally {\n                    analyzer.dispose();\n                }\n                return compressedBundleResourceFile;\n            });\n        }\n\n        try {\n            List<WaitableExecutor.TaskResult<File>> taskResults = executor.waitForAllTasks();\n            taskResults.forEach(\n                    taskResult -> {\n                        if (taskResult.getException() != null) {\n                            throw new BuildException(\n                                    taskResult.getException().getMessage(),\n                                    taskResult.getException());\n                        }\n                    });\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new RuntimeException(e);\n        }\n\n        return task.join();\n\n    }\n\n    private static String toKbString(long size) {\n        return Integer.toString((int) size / 1024);\n    }\n\n    public Set<QualifiedContent.Scope> getReferencedScopes() {\n        return TransformManager.SCOPE_FULL_PROJECT;\n    }\n\n    public Map<String, Object> getParameterInputs() {\n        return resourcesTransform.getParameterInputs();\n    }\n\n    public Collection<SecondaryFile> getSecondaryFiles() {\n        return resourcesTransform.getSecondaryFiles();\n    }\n\n    @NonNull\n    @Override\n    public Collection<File> getSecondaryDirectoryOutputs() {\n        return ImmutableList.of(compressedResources);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/TransformReplacer.java",
    "content": "package com.taobao.android.builder.tasks.transform;\n\nimport android.databinding.tool.DataBindingBuilder;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.api.transform.QualifiedContent;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.ExtraModelInfo;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.TaskManager;\nimport com.android.build.gradle.internal.aapt.AaptGeneration;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.dsl.PackagingOptions;\nimport com.android.build.gradle.internal.pipeline.TransformTask;\nimport com.android.build.gradle.internal.process.GradleJavaProcessExecutor;\nimport com.android.build.gradle.internal.scope.DefaultGradlePackagingScope;\nimport com.android.build.gradle.internal.scope.PackagingScope;\nimport com.android.build.gradle.internal.scope.TaskOutputHolder;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.tasks.databinding.DataBindingMergeArtifactsTransform;\nimport com.android.build.gradle.internal.transforms.*;\nimport com.android.build.gradle.options.BooleanOption;\nimport com.android.build.gradle.options.IntegerOption;\nimport com.android.build.gradle.options.ProjectOptions;\nimport com.android.build.gradle.tasks.ir.FastDeployRuntimeExtractorTask;\nimport com.android.builder.core.AtlasBuilder;\nimport com.android.builder.core.DefaultDexOptions;\nimport com.android.builder.core.DexOptions;\nimport com.android.builder.core.ErrorReporter;\nimport com.android.builder.dexing.DexMergerTool;\nimport com.android.builder.dexing.DexingType;\nimport com.android.builder.utils.FileCache;\nimport com.android.ide.common.internal.WaitableExecutor;\nimport com.android.ide.common.process.JavaProcessExecutor;\nimport com.android.utils.FileUtils;\nimport com.google.common.collect.ImmutableSet;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.hook.dex.DexByteCodeConverterHook;\nimport com.taobao.android.builder.insant.*;\nimport com.taobao.android.builder.tasks.manager.transform.TransformManager;\nimport com.taobao.android.builder.tasks.transform.dex.AtlasDexArchiveBuilderTransform;\nimport com.taobao.android.builder.tasks.transform.dex.AtlasDexMergerTransform;\nimport com.taobao.android.builder.tasks.transform.dex.AtlasMultiDexListTransform;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport com.taobao.android.builder.tools.multidex.FastMultiDexer;\nimport groovy.transform.PackageScope;\nimport org.gradle.api.Action;\nimport org.gradle.api.Task;\nimport org.gradle.api.internal.tasks.DefaultTaskOutputs;\nimport org.gradle.api.logging.LogLevel;\nimport org.gradle.api.logging.Logging;\nimport org.gradle.api.specs.AndSpec;\nimport org.gradle.api.specs.Spec;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Path;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.function.Consumer;\nimport java.util.function.Supplier;\n\nimport static com.google.common.base.Verify.verifyNotNull;\n\n/**\n * @author lilong\n * @create 2017-12-08 上午9:02\n */\n\npublic class TransformReplacer {\n\n    private AppVariantContext variantContext;\n\n    public TransformReplacer(AppVariantContext variantContext) {\n        this.variantContext = variantContext;\n    }\n\n    public void replaceDexArchiveBuilderTransform(BaseVariantOutput vod) {\n        List<TransformTask> list = TransformManager.findTransformTaskByTransformType(variantContext,\n                DexArchiveBuilderTransform.class);\n\n        DefaultDexOptions dexOptions = variantContext.getAppExtension().getDexOptions();\n\n        boolean minified = variantContext.getScope().getCodeShrinker() != null;\n\n        ProjectOptions projectOptions = variantContext.getScope().getGlobalScope().getProjectOptions();\n\n        FileCache userLevelCache = getUserDexCache(minified, dexOptions.getPreDexLibraries());\n        for (TransformTask transformTask : list) {\n            AtlasDexArchiveBuilderTransform atlasDexArchiveBuilderTransform = new AtlasDexArchiveBuilderTransform(variantContext, vod,\n                    dexOptions,\n                    variantContext.getScope().getGlobalScope().getAndroidBuilder().getErrorReporter(),\n                    userLevelCache,\n                    variantContext.getScope().getMinSdkVersion().getFeatureLevel(),\n                    variantContext.getScope().getDexer(),\n                    projectOptions.get(BooleanOption.ENABLE_GRADLE_WORKERS),\n                    projectOptions.get(IntegerOption.DEXING_READ_BUFFER_SIZE),\n                    projectOptions.get(IntegerOption.DEXING_WRITE_BUFFER_SIZE),\n                    variantContext.getScope().getVariantConfiguration().getBuildType().isDebuggable());\n            atlasDexArchiveBuilderTransform.setTransformTask(transformTask);\n            ReflectUtils.updateField(transformTask, \"transform\", atlasDexArchiveBuilderTransform);\n            if (variantContext.getScope().getInstantRunBuildContext().isInInstantRunMode() && variantContext.getVariantConfiguration().getMinSdkVersion().getApiLevel() < 21) {\n                transformTask.doLast(task -> {\n                    task.getLogger().info(\"generate maindexList......\");\n                    generateMainDexList(variantContext.getScope());\n\n                });\n            }\n\n        }\n\n    }\n\n    private void generateMainDexList(VariantScope variantScope) {\n        File mainDexListFile = variantScope.getMainDexListFile();\n        Collection<File> inputs = AtlasBuildContext.atlasMainDexHelperMap.get(variantScope.getFullVariantName()).getAllMainDexJars();\n        inputs.addAll(AtlasBuildContext.atlasMainDexHelperMap.get(variantScope.getFullVariantName()).getInputDirs());\n        FastMultiDexer fastMultiDexer = new FastMultiDexer(variantContext);\n        Collection<File> files = null;\n        try {\n            files = fastMultiDexer.repackageJarList(inputs, mainDexListFile, variantScope.getVariantData().getName().toLowerCase().endsWith(\"release\"));\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        if (files != null && files.size() > 0) {\n            AtlasBuildContext.atlasMainDexHelperMap.get(variantScope.getFullVariantName()).addAllMainDexJars(files);\n\n        }\n    }\n\n    public void replaceDataBindingMergeArtifactsTransform() {\n        List<TransformTask> list = TransformManager.findTransformTaskByTransformType(variantContext,\n                DataBindingMergeArtifactsTransform.class);\n        for (TransformTask transformTask : list) {\n            File outFolder =\n                    new File(\n                            variantContext.getScope().getBuildFolderForDataBindingCompiler(),\n                            DataBindingBuilder.ARTIFACT_FILES_DIR_FROM_LIBS);\n            AtlasDataBindingMergeArtifactsTransform dataBindingMergeArtifactsTransform = new AtlasDataBindingMergeArtifactsTransform(variantContext, Logging.getLogger(AtlasDataBindingMergeArtifactsTransform.class), outFolder);\n            ReflectUtils.updateField(transformTask, \"transform\", dataBindingMergeArtifactsTransform);\n        }\n\n    }\n\n    @Nullable\n    private FileCache getUserDexCache(boolean isMinifiedEnabled, boolean preDexLibraries) {\n//        if (!preDexLibraries || isMinifiedEnabled) {\n//            return null;\n//        }\n        return getUserIntermediatesCache();\n    }\n\n    @Nullable\n    private FileCache getUserIntermediatesCache() {\n        if (variantContext.getScope().getGlobalScope()\n                .getProjectOptions()\n                .get(BooleanOption.ENABLE_INTERMEDIATE_ARTIFACTS_CACHE)) {\n            return variantContext.getScope().getGlobalScope().getBuildCache();\n        } else {\n            return null;\n        }\n    }\n\n\n    public void replaceDexExternalLibMerge(BaseVariantOutput vod) {\n        List<TransformTask> list = TransformManager.findTransformTaskByTransformType(variantContext,\n                ExternalLibsMergerTransform.class);\n        for (TransformTask transformTask : list) {\n            transformTask.setEnabled(false);\n\n\n        }\n    }\n\n    public void replaceDexMerge(BaseVariantOutput vod) {\n        List<TransformTask> list = TransformManager.findTransformTaskByTransformType(variantContext,\n                DexMergerTransform.class);\n        DexingType dexingType = variantContext.getScope().getDexingType();\n        if (variantContext.getScope().getInstantRunBuildContext().isInInstantRunMode() && variantContext.getVariantConfiguration().getMinSdkVersion().getApiLevel() < 21) {\n            dexingType = DexingType.LEGACY_MULTIDEX;\n        }\n        DexMergerTool dexMergerTool = variantContext.getScope().getDexMerger();\n        int sdkVerision = variantContext.getScope().getMinSdkVersion().getFeatureLevel();\n        boolean debug = variantContext.getScope().getVariantConfiguration().getBuildType().isDebuggable();\n        ErrorReporter errorReporter = variantContext.getScope().getGlobalScope().getAndroidBuilder().getErrorReporter();\n        for (TransformTask transformTask : list) {\n            AtlasDexMergerTransform dexMergerTransform = new AtlasDexMergerTransform(\n                    variantContext.getAppVariantOutputContext(ApkDataUtils.get(vod))\n                    , dexingType,\n                    dexingType == DexingType.LEGACY_MULTIDEX\n                            ? variantContext.getProject().files(variantContext.getScope().getMainDexListFile())\n                            : null,\n                    errorReporter, dexMergerTool, sdkVerision, debug);\n            ReflectUtils.updateField(transformTask, \"transform\", dexMergerTransform);\n\n        }\n    }\n\n    public void replaceMultiDexListTransform() {\n        List<TransformTask> list = null;\n        FastMultiDexer fastMultiDexer = new FastMultiDexer(variantContext);\n        if (usingIncrementalDexing(variantContext.getScope())) {\n            list = TransformManager.findTransformTaskByTransformType(variantContext,\n                    MainDexListTransform.class);\n        } else {\n            list = TransformManager.findTransformTaskByTransformType(variantContext,\n                    MultiDexTransform.class);\n        }\n        if (list.size() > 0 && fastMultiDexer.isFastMultiDexEnabled()) {\n            com.android.build.gradle.internal.dsl.DexOptions dexOptions = variantContext.getScope().getGlobalScope().getExtension().getDexOptions();\n            AtlasMultiDexListTransform atlasMultiDexListTransform = new AtlasMultiDexListTransform(variantContext.getScope(), dexOptions);\n            for (TransformTask transformTask : list) {\n                ReflectUtils.updateField(transformTask, \"transform\", atlasMultiDexListTransform);\n                transformTask.doFirst(task -> AtlasBuildContext.androidBuilderMap.get(task.getProject()).multiDexer = (AtlasBuilder.MultiDexer) fastMultiDexer);\n                transformTask.doLast(task -> AtlasBuildContext.androidBuilderMap.get(task.getProject()).multiDexer = null);\n            }\n        }\n    }\n\n    private boolean usingIncrementalDexing(@NonNull VariantScope variantScope) {\n        if (!variantScope.getGlobalScope().getProjectOptions().get(BooleanOption.ENABLE_DEX_ARCHIVE)) {\n            return false;\n        }\n        if (variantScope.getVariantConfiguration().getBuildType().isDebuggable()) {\n            return true;\n        }\n\n        // In release builds only D8 can be used. See b/37140568 for details.\n        return variantScope.getGlobalScope().getProjectOptions().get(BooleanOption.ENABLE_D8);\n    }\n\n    public void replaceProguardTransform() {\n\n        List<TransformTask> baseTransforms = TransformManager.findTransformTaskByTransformType(\n                variantContext, ProGuardTransform.class);\n        List<TransformTask> nextTransformTasks = TransformManager.findTransformTaskByTransformType(\n                variantContext, DexArchiveBuilderTransform.class);\n\n        for (TransformTask transformTask : baseTransforms) {\n            AtlasProguardTransform newTransform = new AtlasProguardTransform(variantContext);\n            newTransform.oldTransform = (ProGuardTransform) transformTask.getTransform();\n            for (TransformTask nextTransformTask : nextTransformTasks) {\n                if (nextTransformTask.getVariantName().equals(transformTask.getVariantName())) {\n                    newTransform.nextTransformTask = nextTransformTask;\n                }\n            }\n            ReflectUtils.updateField(transformTask, \"transform\",\n                    newTransform);\n\n//\n        }\n    }\n\n    public void replaceDexTransform(AppVariantContext appVariantContext, BaseVariantOutput vod) {\n        List<TransformTask> baseTransforms = TransformManager.findTransformTaskByTransformType(\n                variantContext, DexTransform.class);\n\n        DefaultDexOptions dexOptions = appVariantContext.getAppExtension().getDexOptions();\n        DexingType dexingType = appVariantContext.getScope().getDexingType();\n        DexByteCodeConverterHook dexByteCodeConverterHook = new DexByteCodeConverterHook(variantContext\n                , variantContext.getAppVariantOutputContext(ApkDataUtils.get(vod))\n                , LoggerWrapper.getLogger(DexByteCodeConverterHook.class)\n                , appVariantContext.getScope().getGlobalScope().getAndroidBuilder().getTargetInfo()\n                , new GradleJavaProcessExecutor(appVariantContext.getProject())\n                , appVariantContext.getProject().getLogger().isEnabled(LogLevel.INFO)\n                , new ExtraModelInfo(appVariantContext.getScope().getGlobalScope().getProjectOptions(), appVariantContext.getProject().getLogger()));\n\n        for (TransformTask transformTask : baseTransforms) {\n            DexTransform newTransform = new DexTransform(dexOptions\n                    , dexingType\n                    , false\n                    , appVariantContext.getProject().files(variantContext.getScope().getMainDexListFile())\n                    , verifyNotNull(appVariantContext.getScope().getGlobalScope().getAndroidBuilder().getTargetInfo(), \"Target Info not set.\")\n                    , dexByteCodeConverterHook\n                    , appVariantContext.getScope().getGlobalScope().getAndroidBuilder().getErrorReporter()\n                    , variantContext.getScope().getMinSdkVersion().getFeatureLevel());\n            ReflectUtils.updateField(transformTask, \"transform\",\n                    newTransform);\n        }\n\n    }\n\n    public void replaceMergeJavaResourcesTransform(AppVariantContext appVariantContext, BaseVariantOutput vod) {\n        List<TransformTask> baseTransforms = TransformManager.findTransformTaskByTransformType(\n                variantContext, MergeJavaResourcesTransform.class);\n        for (TransformTask transformTask : baseTransforms) {\n            MergeJavaResourcesTransform transform = (MergeJavaResourcesTransform) transformTask.getTransform();\n            PackagingOptions packagingOptions = (PackagingOptions) ReflectUtils.getField(transform, \"packagingOptions\");\n            packagingOptions.exclude(\"**.aidl\");\n            packagingOptions.exclude(\"**.cfg\");\n            Set<? super QualifiedContent.Scope> mergeScopes = (Set<? super QualifiedContent.Scope>) ReflectUtils.getField(transform, \"mergeScopes\");\n            Set<QualifiedContent.ContentType> mergedType = (Set<QualifiedContent.ContentType>) ReflectUtils.getField(transform, \"mergedType\");\n            String name = (String) ReflectUtils.getField(transform, \"name\");\n            AtlasMergeJavaResourcesTransform atlasMergeJavaResourcesTransform = new AtlasMergeJavaResourcesTransform(appVariantContext.getAppVariantOutputContext(ApkDataUtils.get(vod)), packagingOptions, mergeScopes, mergedType.iterator().next(), name, appVariantContext.getScope());\n            ReflectUtils.updateField(transformTask, \"transform\",\n                    atlasMergeJavaResourcesTransform);\n        }\n\n    }\n\n    public void replaceFixStackFramesTransform(BaseVariantOutput vod) {\n        List<TransformTask> baseTransforms = TransformManager.findTransformTaskByTransformType(\n                variantContext, FixStackFramesTransform.class);\n        for (TransformTask transformTask : baseTransforms) {\n            FixStackFramesTransform transform = (FixStackFramesTransform) transformTask.getTransform();\n\n            AtlasFixStackFramesTransform atlasFixStackFramesTransform = new AtlasFixStackFramesTransform(variantContext.getAppVariantOutputContext(ApkDataUtils.get(vod)), (Supplier<List<File>>) ReflectUtils.getField(transform, \"androidJarClasspath\"), (List<Path>) ReflectUtils.getField(transform, \"compilationBootclasspath\"), (FileCache) ReflectUtils.getField(transform, \"userCache\"));\n            atlasFixStackFramesTransform.oldTransform = transform;\n            ReflectUtils.updateField(transformTask, \"transform\",\n                    atlasFixStackFramesTransform);\n        }\n    }\n\n    public void replaceDesugarTransform(BaseVariantOutput vod) {\n        List<TransformTask> baseTransforms = TransformManager.findTransformTaskByTransformType(\n                variantContext, DesugarTransform.class);\n        for (TransformTask transformTask : baseTransforms) {\n            DesugarTransform transform = (DesugarTransform) transformTask.getTransform();\n            AtlasDesugarTransform atlasDesugarTransform = new AtlasDesugarTransform(\n                    variantContext.getAppVariantOutputContext(ApkDataUtils.get(vod)),\n                    (Supplier<List<File>>) ReflectUtils.getField(transform, \"androidJarClasspath\"),\n                    (List) ReflectUtils.getField(transform, \"compilationBootclasspath\"),\n                    variantContext.getScope().getGlobalScope().getBuildCache(),\n                    (int) ReflectUtils.getField(transform, \"minSdk\"),\n                    (JavaProcessExecutor) ReflectUtils.getField(transform, \"executor\"),\n                    (boolean) ReflectUtils.getField(transform, \"verbose\"),\n                    (boolean) ReflectUtils.getField(transform, \"enableGradleWorkers\"),\n                    (Path) ReflectUtils.getField(transform, \"tmpDir\"));\n            atlasDesugarTransform.oldTransform = transform;\n            ReflectUtils.updateField(transformTask, \"transform\",\n                    atlasDesugarTransform);\n        }\n    }\n\n    public void replaceShrinkResourcesTransform() {\n        File shrinkerOutput =\n                FileUtils.join(\n                        variantContext.getScope().getGlobalScope().getIntermediatesDir(),\n                        \"res_stripped\",\n                        variantContext.getScope().getVariantConfiguration().getDirName());\n        List<TransformTask> baseTransforms = TransformManager.findTransformTaskByTransformType(\n                variantContext, ShrinkResourcesTransform.class);\n        for (TransformTask transform : baseTransforms) {\n            ShrinkResourcesTransform oldTransform = (ShrinkResourcesTransform) transform.getTransform();\n            ResourcesShrinker resourcesShrinker = new ResourcesShrinker(oldTransform, variantContext.getVariantData(),\n                    variantContext.getScope().getOutput(TaskOutputHolder.TaskOutputType.PROCESSED_RES),\n                    shrinkerOutput,\n                    AaptGeneration.fromProjectOptions(variantContext.getScope().getGlobalScope().getProjectOptions()),\n                    variantContext.getScope().getOutput(TaskOutputHolder.TaskOutputType.SPLIT_LIST),\n                    variantContext.getProject().getLogger(),\n                    variantContext);\n            ReflectUtils.updateField(transform, \"transform\",\n                    resourcesShrinker);\n\n        }\n\n\n    }\n\n    public void disableCache() {\n        List<TransformTask> list = null;\n        if (usingIncrementalDexing(variantContext.getScope())) {\n            list = TransformManager.findTransformTaskByTransformType(variantContext,\n                    MainDexListTransform.class);\n        } else {\n            list = TransformManager.findTransformTaskByTransformType(variantContext,\n                    MultiDexTransform.class);\n        }\n        if (list != null) {\n            for (TransformTask transformTask : list) {\n                List<Object> list1 = (List<Object>) ReflectUtils.getField(DefaultTaskOutputs.class, transformTask.getOutputs(), \"cacheIfSpecs\");\n                list1.clear();\n                ReflectUtils.updateField(transformTask.getOutputs(), \"upToDateSpec\", AndSpec.empty());\n\n\n            }\n        }\n\n        list = TransformManager.findTransformTaskByTransformType(variantContext,\n                AtlasProguardTransform.class);\n        if (list != null) {\n            for (TransformTask transformTask : list) {\n                List<Object> list1 = (List<Object>) ReflectUtils.getField(DefaultTaskOutputs.class, transformTask.getOutputs(), \"cacheIfSpecs\");\n                list1.clear();\n                ReflectUtils.updateField(transformTask.getOutputs(), \"upToDateSpec\", AndSpec.empty());\n\n            }\n        }\n\n        list = TransformManager.findTransformTaskByTransformType(variantContext,\n                DexTransform.class);\n        if (list != null) {\n            for (TransformTask transformTask : list) {\n                List<Object> list1 = (List<Object>) ReflectUtils.getField(DefaultTaskOutputs.class, transformTask.getOutputs(), \"cacheIfSpecs\");\n                list1.clear();\n                ReflectUtils.updateField(transformTask.getOutputs(), \"upToDateSpec\", AndSpec.empty());\n\n            }\n        }\n\n        list = TransformManager.findTransformTaskByTransformType(variantContext,\n                AtlasMultiDexListTransform.class);\n        if (list != null) {\n            for (TransformTask transformTask : list) {\n                List<Object> list1 = (List<Object>) ReflectUtils.getField(DefaultTaskOutputs.class, transformTask.getOutputs(), \"cacheIfSpecs\");\n                list1.clear();\n                ReflectUtils.updateField(transformTask.getOutputs(), \"upToDateSpec\", AndSpec.empty());\n\n\n            }\n        }\n\n\n    }\n\n    public void repalaceSomeInstantTransform(BaseVariantOutput vod) {\n\n        variantContext.getProject().getTasks().withType(FastDeployRuntimeExtractorTask.class).forEach(fastDeployRuntimeExtractorTask -> fastDeployRuntimeExtractorTask.setEnabled(false));\n        List<TransformTask> baseTransforms = TransformManager.findTransformTaskByTransformType(\n                variantContext, InstantRunDependenciesApkBuilder.class);\n        if (baseTransforms != null && baseTransforms.size() > 0) {\n            for (TransformTask transformTask : baseTransforms) {\n                transformTask.setEnabled(false);\n            }\n        }\n\n        List<TransformTask> transforms = TransformManager.findTransformTaskByTransformType(\n                variantContext, InstantRunTransform.class);\n        if (transforms != null && transforms.size() > 0) {\n            for (TransformTask transformTask : transforms) {\n                TaobaoInstantRunTransform taobaoInstantRunTransform = new TaobaoInstantRunTransform(variantContext, variantContext.getAppVariantOutputContext(ApkDataUtils.get(vod)), WaitableExecutor.useGlobalSharedThreadPool(),\n                        variantContext.getScope());\n                ReflectUtils.updateField(transformTask, \"transform\", taobaoInstantRunTransform);\n            }\n        }\n\n\n        List<TransformTask> verifytransforms = TransformManager.findTransformTaskByTransformType(\n                variantContext, InstantRunVerifierTransform.class);\n        if (verifytransforms != null && verifytransforms.size() > 0) {\n            for (TransformTask transformTask : verifytransforms) {\n                transformTask.setEnabled(false);\n            }\n        }\n\n        List<TransformTask> transforms1 = TransformManager.findTransformTaskByTransformType(\n                variantContext, ExtractJarsTransform.class);\n        if (transforms1 != null && transforms1.size() > 0) {\n            for (TransformTask transformTask : transforms1) {\n                TaobaoExtractJarsTransform taobaoExtractJarsTransform = new TaobaoExtractJarsTransform(variantContext, variantContext.getAppVariantOutputContext(ApkDataUtils.get(vod)), ImmutableSet.of(QualifiedContent.DefaultContentType.CLASSES),\n                        ImmutableSet.of(QualifiedContent.Scope.SUB_PROJECTS));\n                ReflectUtils.updateField(transformTask, \"transform\", taobaoExtractJarsTransform);\n            }\n        }\n\n        List<TransformTask> transforms2 = TransformManager.findTransformTaskByTransformType(\n                variantContext, InstantRunDex.class);\n        if (transforms2 != null && transforms2.size() > 0) {\n            for (TransformTask transformTask : transforms2) {\n                TaobaoInstantRunDex taobaoInstantRunDex = new TaobaoInstantRunDex(variantContext,\n                        variantContext.getScope(),\n                        variantContext.getScope().getGlobalScope().getAndroidBuilder().getDexByteCodeConverter(),\n                        (DexOptions) ReflectUtils.getField(transformTask.getTransform(), \"dexOptions\"),\n                        variantContext.getProject().getLogger(),\n                        (Integer) ReflectUtils.getField(transformTask.getTransform(), \"minSdkForDx\"),\n                vod);\n                ReflectUtils.updateField(transformTask, \"transform\", taobaoInstantRunDex);\n            }\n        }\n\n\n        List<TransformTask> transformTaskList = TransformManager.findTransformTaskByTransformType(\n                variantContext, InstantRunSliceSplitApkBuilder.class);\n        if (transformTaskList != null && transformTaskList.size() > 0) {\n            for (TransformTask transformTask : transformTaskList) {\n                transformTask.setEnabled(false);\n            }\n        }\n\n        List<TransformTask> transformTaskList1 = TransformManager.findTransformTaskByTransformType(\n                variantContext, InstantRunSlicer.class);\n        if (transformTaskList1 != null && transformTaskList1.size() > 0) {\n            for (TransformTask transformTask : transformTaskList1) {\n                transformTask.setEnabled(false);\n//                TaobaoInstantRunSlicer taobaoInstantRunSlicer = new TaobaoInstantRunSlicer(variantContext.getProject().getLogger(),variantContext.getScope());\n//                ReflectUtils.updateField(transformTask,\"transform\",taobaoInstantRunSlicer);\n            }\n        }\n\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/dex/AtlasDexArchiveBuilderCacheHander.java",
    "content": "package com.taobao.android.builder.tasks.transform.dex;\n\nimport android.databinding.tool.util.L;\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.api.transform.JarInput;\nimport com.android.build.api.transform.QualifiedContent;\nimport com.android.build.gradle.internal.BuildCacheUtils;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.pipeline.OriginalStream;\nimport com.android.build.gradle.internal.transforms.DexArchiveBuilderTransform;\nimport com.android.build.gradle.internal.transforms.PreDexTransform;\nimport com.android.builder.core.DexOptions;\nimport com.android.builder.dexing.DexerTool;\nimport com.android.builder.utils.FileCache;\nimport com.android.dx.Version;\nimport com.android.tools.r8.AtlasD8;\nimport com.android.utils.FileUtils;\nimport com.google.common.base.*;\nimport com.google.common.collect.Multimap;\nimport com.google.common.hash.Hashing;\nimport com.google.common.io.ByteStreams;\nimport com.taobao.android.builder.tools.MD5Util;\nimport org.gradle.api.Project;\n\nimport java.nio.file.*;\nimport java.io.*;\nimport java.util.*;\nimport java.util.concurrent.ExecutionException;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\nimport java.util.jar.JarOutputStream;\n\nimport static com.android.builder.dexing.ClassFileInput.CLASS_MATCHER;\n\n/**\n * @author lilong\n * @create 2017-12-08 上午3:47\n */\n\npublic class AtlasDexArchiveBuilderCacheHander {\n    private static final LoggerWrapper logger =\n            LoggerWrapper.getLogger(AtlasDexArchiveBuilderCacheHander.class);\n\n    // Increase this if we might have generated broken cache entries to invalidate them.\n    private static final int CACHE_KEY_VERSION = 4;\n\n    @Nullable\n    private final FileCache userLevelCache;\n    @NonNull\n    private final DexOptions dexOptions;\n    private final int minSdkVersion;\n    private final boolean isDebuggable;\n    @NonNull\n    private final DexerTool dexer;\n\n    private static Project project;\n\n    public AtlasDexArchiveBuilderCacheHander(Project p,\n            @Nullable FileCache userLevelCache,\n            @NonNull DexOptions dexOptions,\n            int minSdkVersion,\n            boolean isDebuggable,\n            @NonNull DexerTool dexer) {\n        project = p;\n        this.userLevelCache = userLevelCache;\n        this.dexOptions = dexOptions;\n        this.minSdkVersion = minSdkVersion;\n        this.isDebuggable = isDebuggable;\n        this.dexer = dexer;\n    }\n\n    @Nullable\n    public File getCachedVersionIfPresent(JarInput input) throws Exception {\n        FileCache cache =\n                getBuildCache(\n                        input.getFile(), isExternalLib(input), userLevelCache);\n\n        if (cache == null) {\n            return null;\n        }\n\n        FileCache.Inputs buildCacheInputs =\n                getBuildCacheInputs(\n                        input.getFile(), dexOptions, dexer, minSdkVersion, isDebuggable);\n        return cache.cacheEntryExists(buildCacheInputs)\n                ? cache.getFileInCache(buildCacheInputs)\n                : null;\n    }\n\n    @Nullable\n    public File getCachedVersionIfPresent(File input) throws Exception {\n        assert input.isFile();\n        FileCache cache =\n                getBuildCache(\n                        input, true, userLevelCache);\n\n        if (cache == null) {\n            return null;\n        }\n\n        FileCache.Inputs buildCacheInputs =\n                getBuildCacheInputs(\n                        input, dexOptions, dexer, minSdkVersion, isDebuggable);\n        return cache.cacheEntryExists(buildCacheInputs)\n                ? cache.getFileInCache(buildCacheInputs)\n                : null;\n    }\n\n    /**\n     * Returns if the qualified content is an external jar.\n     */\n    private static boolean isExternalLib(@NonNull QualifiedContent content) {\n        return content.getFile().isFile()\n                && content.getScopes()\n                .equals(Collections.singleton(QualifiedContent.Scope.EXTERNAL_LIBRARIES))\n                && content.getContentTypes()\n                .equals(Collections.singleton(QualifiedContent.DefaultContentType.CLASSES))\n                && !content.getName().startsWith(OriginalStream.LOCAL_JAR_GROUPID);\n    }\n\n    /**\n     * Input parameters to be provided by the client when using {@link FileCache}.\n     * <p>\n     * <p>The clients of {@link FileCache} need to exhaustively specify all the inputs that affect\n     * the creation of an output file/directory. This enum class lists the input parameters that are\n     * used in {@link DexArchiveBuilderCacheHandler}.\n     */\n    private enum FileCacheInputParams {\n\n        /**\n         * The input file.\n         */\n        FILE,\n\n        /**\n         * Dx version used to create the dex archive.\n         */\n        DX_VERSION,\n\n        /**\n         * Whether jumbo mode is enabled.\n         */\n        JUMBO_MODE,\n\n        /**\n         * Whether optimize is enabled.\n         */\n        OPTIMIZE,\n\n        /**\n         * Tool used to produce the dex archive.\n         */\n        DEXER_TOOL,\n\n        /**\n         * Version of the cache key.\n         */\n        CACHE_KEY_VERSION,\n\n        /**\n         * Min sdk version used to generate dex.\n         */\n        MIN_SDK_VERSION,\n\n        /**\n         * If generate dex is debuggable.\n         */\n        IS_DEBUGGABLE,\n    }\n\n    /**\n     * Returns a {@link FileCache.Inputs} object computed from the given parameters for the\n     * predex-library task to use the build cache.\n     */\n    @NonNull\n    public static FileCache.Inputs getBuildCacheInputs(\n            @NonNull File inputFile,\n            @NonNull DexOptions dexOptions,\n            @NonNull DexerTool dexerTool,\n            int minSdkVersion,\n            boolean isDebuggable)\n            throws Exception {\n        // To use the cache, we need to specify all the inputs that affect the outcome of a pre-dex\n        // (see DxDexKey for an exhaustive list of these inputs)\n        FileCache.Inputs.Builder buildCacheInputs =\n                new FileCache.Inputs.Builder(FileCache.Command.PREDEX_LIBRARY_TO_DEX_ARCHIVE);\n        java.util.function.Predicate<String> CLASS_MATCHER = s -> s.endsWith(SdkConstants.DOT_CLASS);\n\n        if (inputFile.isDirectory()){\n            String hash = Files.walk(inputFile.toPath())\n                    .filter(p -> CLASS_MATCHER.test(p.toString())).sorted().map(new Function<Path, String>() {\n                        @javax.annotation.Nullable\n                        @Override\n                        public String apply(@javax.annotation.Nullable Path input) {\n                            try {\n                                return com.google.common.io.Files.asByteSource(input.toFile()).hash(Hashing.sha256()).toString();\n                            } catch (IOException e) {\n                                e.printStackTrace();\n                            }\n                            return \"\";\n                        }\n                    }).collect(StringBuilder::new, StringBuilder::append, StringBuilder::append).toString();\n\n\n\n            buildCacheInputs\n                    .putString(\"hash\",MD5Util.getMD5(hash))\n                    .putString(FileCacheInputParams.DX_VERSION.name(), Version.VERSION)\n                    .putBoolean(FileCacheInputParams.JUMBO_MODE.name(), isJumboModeEnabledForDx())\n                    .putBoolean(\n                            FileCacheInputParams.OPTIMIZE.name(),\n                            !dexOptions.getAdditionalParameters().contains(\"--no-optimize\"))\n                    .putString(FileCacheInputParams.DEXER_TOOL.name(), dexerTool.name())\n                    .putLong(FileCacheInputParams.CACHE_KEY_VERSION.name(), CACHE_KEY_VERSION)\n                    .putLong(FileCacheInputParams.MIN_SDK_VERSION.name(), minSdkVersion)\n                    .putBoolean(FileCacheInputParams.IS_DEBUGGABLE.name(), isDebuggable);\n\n\n\n        }else {\n            buildCacheInputs\n                    .putFile(\n                            FileCacheInputParams.FILE.name(),\n                            inputFile,\n                            FileCache.FileProperties.HASH)\n                    .putString(FileCacheInputParams.DX_VERSION.name(), Version.VERSION)\n                    .putBoolean(FileCacheInputParams.JUMBO_MODE.name(), isJumboModeEnabledForDx())\n                    .putBoolean(\n                            FileCacheInputParams.OPTIMIZE.name(),\n                            !dexOptions.getAdditionalParameters().contains(\"--no-optimize\"))\n                    .putString(FileCacheInputParams.DEXER_TOOL.name(), dexerTool.name())\n                    .putLong(FileCacheInputParams.CACHE_KEY_VERSION.name(), CACHE_KEY_VERSION)\n                    .putLong(FileCacheInputParams.MIN_SDK_VERSION.name(), minSdkVersion)\n                    .putBoolean(FileCacheInputParams.IS_DEBUGGABLE.name(), isDebuggable);\n        }\n       if (project.hasProperty(\"light\") && project.hasProperty(\"deepShrink\")){\n            buildCacheInputs.putBoolean(\"deepShrink\",AtlasD8.deepShrink);\n        }\n        return buildCacheInputs.build();\n    }\n\n    /**\n     * Jumbo mode is always enabled for dex archives - see http://b.android.com/321744\n     */\n    static boolean isJumboModeEnabledForDx() {\n        return true;\n    }\n\n\n    static FileCache getBuildCache(\n            @NonNull File inputFile, boolean isExternalLib, @Nullable FileCache buildCache) {\n        // We use the build cache only when it is enabled and the input file is a (non-snapshot)\n        // external-library jar file\n        if (buildCache == null || !isExternalLib) {\n            return null;\n        }\n        // After the check above, here the build cache should be enabled and the input file is an\n        // external-library jar file. We now check whether it is a snapshot version or not (to\n        // address http://b.android.com/228623).\n        // Note that the current check is based on the file path; if later on there is a more\n        // reliable way to verify whether an input file is a snapshot, we should replace this check\n        // with that.\n        if (inputFile.getPath().contains(\"-SNAPSHOT\")) {\n            return null;\n        } else {\n            return buildCache;\n        }\n    }\n\n    void populateCache(Multimap<QualifiedContent, File> cacheableItems)\n            throws Exception {\n\n        for (QualifiedContent input : cacheableItems.keys()) {\n            FileCache cache =\n                    getBuildCache(\n                            input.getFile(), isExternalLib(input), userLevelCache);\n            if (cache != null) {\n                FileCache.Inputs buildCacheInputs =\n                        AtlasDexArchiveBuilderCacheHander.getBuildCacheInputs(\n                                input.getFile(), dexOptions, dexer, minSdkVersion, isDebuggable);\n                FileCache.QueryResult result =\n                        cache.createFileInCacheIfAbsent(\n                                buildCacheInputs,\n                                in -> {\n                                    Collection<File> dexArchives = cacheableItems.get(input);\n                                    logger.verbose(\n                                            \"Merging %1$s into %2$s\",\n                                            Joiner.on(',').join(dexArchives), in.getAbsolutePath());\n                                    mergeJars(in, cacheableItems.get(input));\n                                });\n                if (result.getQueryEvent().equals(FileCache.QueryEvent.CORRUPTED)) {\n                    Verify.verifyNotNull(result.getCauseOfCorruption());\n                    logger.info(\n                            \"The build cache at '%1$s' contained an invalid cache entry.\\n\"\n                                    + \"Cause: %2$s\\n\"\n                                    + \"We have recreated the cache entry.\\n\"\n                                    + \"%3$s\",\n                            cache.getCacheDirectory().getAbsolutePath(),\n                            Throwables.getStackTraceAsString(result.getCauseOfCorruption()),\n                            BuildCacheUtils.BUILD_CACHE_TROUBLESHOOTING_MESSAGE);\n                }\n            }\n        }\n    }\n\n    public void populateCache(File input,File out)\n            throws Exception {\n\n            FileCache cache =\n                    getBuildCache(\n                            input, true, userLevelCache);\n            if (cache != null) {\n                FileCache.Inputs buildCacheInputs =\n                        AtlasDexArchiveBuilderCacheHander.getBuildCacheInputs(\n                                input, dexOptions, dexer, minSdkVersion, isDebuggable);\n                FileCache.QueryResult result =\n                        cache.createFileInCacheIfAbsent(\n                                buildCacheInputs,\n                                in -> {\n                                    Files.copy(out.toPath(),in.toPath());\n                                });\n                if (result.getQueryEvent().equals(FileCache.QueryEvent.CORRUPTED)) {\n                    Verify.verifyNotNull(result.getCauseOfCorruption());\n                    logger.info(\n                            \"The build cache at '%1$s' contained an invalid cache entry.\\n\"\n                                    + \"Cause: %2$s\\n\"\n                                    + \"We have recreated the cache entry.\\n\"\n                                    + \"%3$s\",\n                            cache.getCacheDirectory().getAbsolutePath(),\n                            Throwables.getStackTraceAsString(result.getCauseOfCorruption()),\n                            BuildCacheUtils.BUILD_CACHE_TROUBLESHOOTING_MESSAGE);\n                }else if (result.getQueryEvent().equals(FileCache.QueryEvent.MISSED)){\n                    logger.warning(\"miss D8 cache:\"+input.getAbsolutePath());\n                }else if (result.getQueryEvent().equals(FileCache.QueryEvent.HIT)){\n                    logger.warning(\"hit D8 cache:\"+input.getAbsolutePath());\n\n                }\n            }\n    }\n\n\n    private static void mergeJars(File out, Iterable<File> dexArchives) throws IOException {\n\n        try (JarOutputStream jarOutputStream =\n                     new JarOutputStream(new BufferedOutputStream(new FileOutputStream(out)))) {\n\n            Set<String> usedNames = new HashSet<>();\n            for (File dexArchive : dexArchives) {\n                if (dexArchive.exists()) {\n                    try (JarFile jarFile = new JarFile(dexArchive)) {\n                        Enumeration<JarEntry> entries = jarFile.entries();\n                        while (entries.hasMoreElements()) {\n                            JarEntry jarEntry = entries.nextElement();\n                            // Get unique name as jars might have multiple classes.dex, as for D8\n                            // we do not want to output single dex per class for performance reasons\n                            String entryName = jarEntry.getName();\n                            while (!usedNames.add(entryName)) {\n                                entryName = \"_\" + entryName;\n                            }\n                            jarOutputStream.putNextEntry(new JarEntry(entryName));\n                            try (InputStream inputStream =\n                                         new BufferedInputStream(jarFile.getInputStream(jarEntry))) {\n                                ByteStreams.copy(inputStream, jarOutputStream);\n                            }\n                            jarOutputStream.closeEntry();\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/dex/AtlasDexArchiveBuilderTransform.java",
    "content": "package com.taobao.android.builder.tasks.transform.dex;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.annotations.VisibleForTesting;\nimport com.android.build.VariantOutput;\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.pipeline.*;\nimport com.android.build.gradle.internal.transforms.DexArchiveBuilderTransform;\nimport com.android.build.gradle.tasks.PackageAndroidArtifact;\nimport com.android.builder.core.DefaultDexOptions;\nimport com.android.builder.core.DexOptions;\nimport com.android.builder.core.ErrorReporter;\nimport com.android.builder.dexing.*;\nimport com.android.builder.utils.FileCache;\nimport com.android.dx.command.dexer.DxContext;\nimport com.android.ide.common.blame.Message;\nimport com.android.ide.common.blame.ParsingProcessOutputHandler;\nimport com.android.ide.common.blame.parser.DexParser;\nimport com.android.ide.common.blame.parser.ToolOutputParser;\nimport com.android.ide.common.internal.WaitableExecutor;\nimport com.android.ide.common.process.ProcessException;\nimport com.android.ide.common.process.ProcessOutput;\nimport com.android.ide.common.process.ProcessOutputHandler;\nimport com.android.tools.r8.AtlasD8DexArchiveBuilder;\nimport com.android.utils.FileUtils;\nimport com.google.common.base.Preconditions;\nimport com.google.common.collect.*;\nimport com.sun.javafx.scene.transform.TransformUtils;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.app.BuildAtlasEnvTask;\nimport com.taobao.android.builder.tools.FileNameUtils;\nimport com.taobao.android.builder.tools.MD5Util;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport com.taobao.android.builder.tools.TransformInputUtils;\nimport com.taobao.android.builder.tools.log.FileLogger;\nimport org.apache.commons.collections.MultiHashMap;\nimport org.gradle.tooling.BuildException;\nimport org.gradle.workers.IsolationMode;\n\nimport javax.inject.Inject;\nimport java.io.*;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.util.*;\nimport java.util.function.Predicate;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.nio.file.StandardCopyOption;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\n\n\n/**\n * @author lilong\n * @create 2017-12-08 上午3:43\n */\n\npublic class AtlasDexArchiveBuilderTransform extends Transform {\n    private static final LoggerWrapper logger =\n            LoggerWrapper.getLogger(DexArchiveBuilderTransform.class);\n\n    public static final int DEFAULT_BUFFER_SIZE_IN_KB = 100;\n\n    public static int NUMBER_OF_BUCKETS = 1;\n\n    private static final String CACHE_ID = \"dex-archive\";\n\n    private static final String CACHE_VERSION=\"1.0\";\n\n\n    @NonNull\n    private final DexOptions dexOptions;\n\n    @NonNull\n    private final ErrorReporter errorReporter;\n    @VisibleForTesting\n    @NonNull\n    final WaitableExecutor executor;\n\n    Multimap<QualifiedContent, File> cacheItems = HashMultimap.create();\n\n    private final int minSdkVersion;\n    @NonNull\n    private final DexerTool dexer;\n    @NonNull\n    private final AtlasDexArchiveBuilderCacheHander cacheHandler;\n    private final boolean useGradleWorkers;\n    private final int inBufferSize;\n    private final int outBufferSize;\n    private final boolean isDebuggable;\n    private final AppVariantContext variantContext;\n    private final BaseVariantOutput variantOutput;\n    private TransformTask transformTask;\n\n    public AtlasDexArchiveBuilderTransform(AppVariantContext variantContext, VariantOutput variantOutput,\n                                           @NonNull DexOptions dexOptions,\n                                           @NonNull ErrorReporter errorReporter,\n                                           @Nullable FileCache userLevelCache,\n                                           int minSdkVersion,\n                                           @NonNull DexerTool dexer,\n                                           boolean useGradleWorkers,\n                                           @Nullable Integer inBufferSize,\n                                           @Nullable Integer outBufferSize,\n                                           boolean isDebuggable) {\n\n        this.variantContext = variantContext;\n        this.variantOutput = (BaseVariantOutput) variantOutput;\n        this.dexOptions = dexOptions;\n        this.errorReporter = errorReporter;\n        this.minSdkVersion = minSdkVersion;\n        this.dexer = dexer;\n        this.executor = WaitableExecutor.useGlobalSharedThreadPool();\n        this.cacheHandler =\n                new AtlasDexArchiveBuilderCacheHander(variantContext.getProject(),\n                        userLevelCache, dexOptions, minSdkVersion, isDebuggable, dexer);\n        this.useGradleWorkers = useGradleWorkers;\n        this.inBufferSize =\n                (inBufferSize == null ? DEFAULT_BUFFER_SIZE_IN_KB : inBufferSize) * 1024;\n        this.outBufferSize =\n                (outBufferSize == null ? DEFAULT_BUFFER_SIZE_IN_KB : outBufferSize) * 1024;\n        this.isDebuggable = isDebuggable;\n\n    }\n\n    @NonNull\n    @Override\n    public String getName() {\n        return \"dexBuilder\";\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.ContentType> getInputTypes() {\n         return ImmutableSet.of(\n                QualifiedContent.DefaultContentType.CLASSES,\n                ExtendedContentType.CLASSES_ENHANCED);\n    }\n\n    @NonNull\n    @Override\n    public Set<QualifiedContent.ContentType> getOutputTypes() {\n        return ImmutableSet.of(ExtendedContentType.DEX_ARCHIVE);\n    }\n\n    @NonNull\n    @Override\n    public Set<? super QualifiedContent.Scope> getScopes() {\n        return TransformManager.SCOPE_FULL_WITH_IR_FOR_DEXING;\n    }\n\n    @NonNull\n    @Override\n    public Map<String, Object> getParameterInputs() {\n        try {\n            Map<String, Object> params = new LinkedHashMap<>(4);\n            params.put(\"optimize\", !dexOptions.getAdditionalParameters().contains(\"--no-optimize\"));\n            params.put(\"jumbo\", dexOptions.getJumboMode());\n            params.put(\"min-sdk-version\", minSdkVersion);\n            params.put(\"dex-builder-tool\", dexer.name());\n\n            return params;\n        } catch (Exception e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    @Override\n    public boolean isIncremental() {\n        return false;\n    }\n\n    @Override\n    public void transform(@NonNull TransformInvocation transformInvocation)\n            throws IOException {\n\n        AtlasIntermediateStreamHelper atlasIntermediateStreamHelper = new AtlasIntermediateStreamHelper(transformTask);\n        atlasIntermediateStreamHelper.replaceProvider(transformInvocation);\n        AtlasBuildContext.status = AtlasBuildContext.STATUS.DEXARCHIVE;\n        TransformOutputProvider outputProvider = transformInvocation.getOutputProvider();\n        Preconditions.checkNotNull(outputProvider, \"Missing output provider.\");\n        outputProvider.deleteAll();\n        org.apache.commons.io.FileUtils.cleanDirectory(variantContext.getAwbDexAchiveOutputs());\n\n\n        if (dexer == DexerTool.D8) {\n            logger.info(\"D8 is used to build dex.\");\n        }\n\n        if (dexOptions.getAdditionalParameters().contains(\"--no-optimize\")) {\n            logger.warning(DefaultDexOptions.OPTIMIZE_WARNING);\n        }\n\n        logger.verbose(\"Task is incremental : %b \", transformInvocation.isIncremental());\n//\n//        if (!transformInvocation.isIncremental()) {\n//        }\n\n        List<QualifiedContent> listFiles = new ArrayList<>();\n        Set<File>mainJars = new HashSet<>();\n\n        try {\n            for (TransformInput input : transformInvocation.getInputs()) {\n                for (DirectoryInput dirInput : input.getDirectoryInputs()) {\n                    mainJars.add(dirInput.getFile());\n                    logger.verbose(\"Dir input %s\", dirInput.getFile().toString());\n                    List<File>dirFiles = convertToDexArchive(\n                            transformInvocation.getContext(),\n                            dirInput,\n                            outputProvider,\n                            false);\n                    cacheItems.putAll(dirInput,dirFiles);\n                }\n\n                for (JarInput jarInput : input.getJarInputs()) {\n                    if (jarInput.getFile().getName().equals(PackageAndroidArtifact.INSTANT_RUN_PACKAGES_PREFIX + \".jar\")){\n                        logger.warning(\"skip instant run jar:\"+jarInput.getFile().getAbsolutePath());\n                        continue;\n                    }\n                    if (!inMainDex(jarInput)) {\n                        listFiles.add(jarInput);\n                        continue;\n                    }\n                    mainJars.add(jarInput.getFile());\n                    if (!validJar(jarInput)){\n                        continue;\n                    }\n\n                    logger.verbose(\"Jar input %s\", jarInput.getFile().toString());\n                    List<File> dexArchives =\n                            processJarInput(\n                                    transformInvocation.getContext(),\n                                    false,\n                                    jarInput,\n                                    outputProvider);\n                    cacheItems.putAll(jarInput,dexArchives);\n\n                }\n\n            }\n\n            for (File file:AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getAllMainDexJars()){\n                if (mainJars.contains(file)){\n                    continue;\n                }else {\n                    if (file.getName().equals(PackageAndroidArtifact.INSTANT_RUN_PACKAGES_PREFIX + \".jar\")){\n                        logger.warning(\"skip instant run jar:\"+file.getAbsolutePath());\n                        continue;\n                    }\n                    JarInput jarInput = TransformInputUtils.makeJarInput(file,variantContext);\n                    List<File> dexArchives =\n                            processJarInput(\n                                    transformInvocation.getContext(),\n                                    false,\n                                    jarInput,\n                                    outputProvider);\n                    cacheItems.putAll(jarInput,dexArchives);\n                }\n            }\n\n\n            for (File file:AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).getInputDirs()){\n                if (mainJars.contains(file)){\n                    continue;\n                }else {\n                    DirectoryInput dirInput = TransformInputUtils.makeDirectoryInput(file,variantContext);\n                    logger.verbose(\"Dir input %s\", dirInput.getFile().toString());\n                    List<File>files = convertToDexArchive(\n                            transformInvocation.getContext(),\n                            dirInput,\n                            outputProvider,\n                            false);\n                    cacheItems.putAll(dirInput,files);\n                }\n            }\n\n\n\n\n            processAwbDexArchive(transformInvocation, listFiles);\n            // all work items have been submitted, now wait for completion.\n            if (useGradleWorkers) {\n                transformInvocation.getContext().getWorkerExecutor().await();\n            } else {\n                executor.waitForTasksWithQuickFail(false);\n            }\n\n\n            if (!cacheItems.isEmpty()) {\n                cacheHandler.populateCache(cacheItems);\n            }\n\n            if (variantContext.getScope().getMainDexListFile().exists()){\n                variantContext.getScope().getMainDexListFile().delete();\n            }\n\n        }catch (Exception e){\n            e.printStackTrace();\n            throw new IOException(e.getMessage());\n        }\n\n\n    }\n\n    private boolean validJar(JarInput jarInput) {\n        if (computerClassCount(jarInput.getFile()) == 0){\n            return false;\n        }else {\n            return true;\n        }\n    }\n\n    private boolean inMainDex(JarInput jarInput) {\n\n        if (jarInput.getFile().getName().contains(PackageAndroidArtifact.INSTANT_RUN_PACKAGES_PREFIX + \"-bootstrap.jar\")){\n            return true;\n        }\n        boolean flag = AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).inMainDex(jarInput);\n        return flag;\n    }\n\n\n    private List<File> processJarInput(\n            @NonNull Context context,\n            boolean isIncremental,\n            @NonNull JarInput jarInput,\n            TransformOutputProvider transformOutputProvider)\n            throws Exception {\n                return convertJarToDexArchive(context, jarInput, transformOutputProvider);\n    }\n\n    private List<File> processAwbJarInput(\n            @NonNull Context context,\n            boolean isIncremental,\n            @NonNull JarInput jarInput,\n            File transformOutputProvider)\n            throws Exception {\n\n        return convertAwbJarToDexArchive(context, jarInput, transformOutputProvider);\n\n    }\n\n    private List<File> convertJarToDexArchive(\n            @NonNull Context context,\n            @NonNull JarInput toConvert,\n            @NonNull TransformOutputProvider transformOutputProvider)\n            throws Exception {\n\n        File cachedVersion = cacheHandler.getCachedVersionIfPresent(toConvert);\n        if (cachedVersion == null) {\n            logger.info(\"AtlasDexArchiveBuilder miss cache:\"+toConvert.getFile().getAbsolutePath()+\"-> null\");\n            return convertToDexArchive(context, toConvert, transformOutputProvider, false);\n        } else {\n            File outputFile = getPreDexJar(transformOutputProvider, toConvert, null);\n            logger.info(\"AtlasDexArchiveBuilder hit cache:\"+toConvert.getFile().getAbsolutePath()+\"->\"+outputFile.getAbsolutePath());\n            if (!outputFile.getParentFile().exists()){\n                outputFile.getParentFile().mkdirs();\n            }\n            Files.copy(\n                    cachedVersion.toPath(),\n                    outputFile.toPath(),\n                    StandardCopyOption.REPLACE_EXISTING);\n            // no need to try to cache an already cached version.\n            return ImmutableList.of();\n        }\n    }\n\n    private List<File> convertAwbJarToDexArchive(\n            @NonNull Context context,\n            @NonNull JarInput toConvert,\n            @NonNull File transformOutputProvider)\n            throws Exception {\n\n        File cachedVersion = cacheHandler.getCachedVersionIfPresent(toConvert);\n        if (cachedVersion == null) {\n            logger.info(\"AtlasDexArchiveBuilder miss cache:\"+toConvert.getFile().getAbsolutePath()+\"-> null\");\n\n            return convertAwbToDexArchive(context, toConvert, transformOutputProvider, false,true);\n        } else {\n            logger.info(\"AtlasDexArchiveBuilder hit cache:\"+toConvert.getFile().getAbsolutePath()+\"->\"+cachedVersion.getAbsolutePath());\n            File outputFile = getAwbPreDexJar(transformOutputProvider, toConvert, null);\n\n            FileUtils.copyFile(cachedVersion,outputFile);\n\n            // no need to try to cache an already cached version.\n            return ImmutableList.of();\n        }\n    }\n\n    public void setTransformTask(TransformTask transformTask) {\n        this.transformTask = transformTask;\n    }\n\n    public static class DexConversionParameters implements Serializable {\n        private final QualifiedContent input;\n        private final String output;\n        private final int numberOfBuckets;\n        private final int buckedId;\n        private final int minSdkVersion;\n        private final List<String> dexAdditionalParameters;\n        private final int inBufferSize;\n        private final int outBufferSize;\n        private final DexerTool dexer;\n        private final boolean isDebuggable;\n        private final boolean isIncremental;\n        private final boolean awb;\n\n        public DexConversionParameters(\n                QualifiedContent input,\n                File output,\n                int numberOfBuckets,\n                int buckedId,\n                int minSdkVersion,\n                List<String> dexAdditionalParameters,\n                int inBufferSize,\n                int outBufferSize,\n                DexerTool dexer,\n                boolean isDebuggable,\n                boolean isIncremental,\n                boolean awb) {\n            this.input = input;\n            this.numberOfBuckets = numberOfBuckets;\n            this.buckedId = buckedId;\n            this.output = output.toURI().toString();\n            this.minSdkVersion = minSdkVersion;\n            this.dexAdditionalParameters = dexAdditionalParameters;\n            this.inBufferSize = inBufferSize;\n            this.outBufferSize = outBufferSize;\n            this.dexer = dexer;\n            this.isDebuggable = isDebuggable;\n            this.isIncremental = isIncremental;\n            this.awb = awb;\n        }\n\n        public boolean belongsToThisBucket(String path) {\n            return (Math.abs(path.hashCode()) % numberOfBuckets) == buckedId;\n        }\n\n        public boolean isDirectoryBased() {\n            return input instanceof DirectoryInput;\n        }\n    }\n\n\n    private DexArchiveBuilder getDexArchiveBuilder(\n            int minSdkVersion,\n            List<String> dexAdditionalParameters,\n            int inBufferSize,\n            int outBufferSize,\n            DexerTool dexer,\n            boolean isDebuggable,\n            boolean awb,\n            OutputStream outStream,\n            OutputStream errStream)\n            throws IOException {\n\n        DexArchiveBuilder dexArchiveBuilder;\n        switch (dexer) {\n            case DX:\n                boolean optimizedDex = !dexAdditionalParameters.contains(\"--no-optimize\");\n                DxContext dxContext = new DxContext(outStream, errStream);\n                DexArchiveBuilderConfig config =\n                        new DexArchiveBuilderConfig(\n                                dxContext,\n                                optimizedDex,\n                                inBufferSize,\n                                minSdkVersion,\n                                DexerTool.DX,\n                                outBufferSize,\n                                AtlasDexArchiveBuilderCacheHander.isJumboModeEnabledForDx());\n\n                dexArchiveBuilder = DexArchiveBuilder.createDxDexBuilder(config);\n                break;\n            case D8:\n                dexArchiveBuilder =\n                        new AtlasD8DexArchiveBuilder(minSdkVersion,isDebuggable,AtlasDexArchiveBuilderTransform.this.variantContext.getScope().getMainDexListFile().toPath(),awb);\n                break;\n            default:\n                throw new AssertionError(\"Unknown dexer type: \" + dexer.name());\n        }\n        return dexArchiveBuilder;\n    }\n\n    private List<File> convertToDexArchive(\n            @NonNull Context context,\n            @NonNull QualifiedContent input,\n            @NonNull TransformOutputProvider outputProvider,\n            boolean isIncremental)\n            throws Exception {\n\n        logger.verbose(\"Dexing {}\", input.getFile().getAbsolutePath());\n        ImmutableList.Builder<File> dexArchives = ImmutableList.builder();\n        for (int bucketId = 0; bucketId < NUMBER_OF_BUCKETS; bucketId++) {\n            File preDexOutputFile = getPreDexFile(outputProvider, input, bucketId);\n            if (input.getFile().isDirectory()) {\n                File cachedVersion = cacheHandler.getCachedVersionIfPresent(input.getFile());\n                dexArchives.add(preDexOutputFile);\n                if (cachedVersion != null) {\n                    FileUtils.copyDirectoryContentToDirectory(cachedVersion, preDexOutputFile);\n                    return dexArchives.build();\n\n                }\n            }\n            if (preDexOutputFile.isDirectory() && preDexOutputFile.exists()) {\n                FileUtils.cleanOutputDir(preDexOutputFile);\n            }else {\n                FileUtils.deleteIfExists(preDexOutputFile);\n            }\n            AtlasDexArchiveBuilderTransform.DexConversionParameters parameters =\n                    new AtlasDexArchiveBuilderTransform.DexConversionParameters(\n                            input,\n                            preDexOutputFile,\n                            NUMBER_OF_BUCKETS,\n                            bucketId,\n                            minSdkVersion,\n                            dexOptions.getAdditionalParameters(),\n                            inBufferSize,\n                            outBufferSize,\n                            dexer,\n                            isDebuggable,\n                            isIncremental,\n                            false);\n\n            if (useGradleWorkers) {\n                context.getWorkerExecutor()\n                        .submit(\n                                DexArchiveBuilderTransform.DexConversionWorkAction.class,\n                                configuration -> {\n                                    configuration.setIsolationMode(IsolationMode.NONE);\n                                    configuration.setParams(parameters);\n                                });\n            } else {\n                executor.execute(\n                        () -> {\n                            ProcessOutputHandler outputHandler =\n                                    new ParsingProcessOutputHandler(\n                                            new ToolOutputParser(\n                                                    new DexParser(), Message.Kind.ERROR, logger),\n                                            new ToolOutputParser(new DexParser(), logger),\n                                            errorReporter);\n                            ProcessOutput output = null;\n                            try (Closeable ignored = output = outputHandler.createOutput()) {\n                                launchProcessing(\n                                        parameters,\n                                        output.getStandardOutput(),\n                                        output.getErrorOutput());\n                            } finally {\n                                if (output != null) {\n                                    try {\n                                        outputHandler.handleOutput(output);\n                                    } catch (ProcessException e) {\n                                        // ignore this one\n                                    }\n                                }\n                            }\n                            return null;\n                        });\n            }\n        }\n        List<File> files = dexArchives.build();\n        return files;\n    }\n\n\n    private void launchProcessing(\n            @NonNull AtlasDexArchiveBuilderTransform.DexConversionParameters dexConversionParameters,\n            @NonNull OutputStream outStream,\n            @NonNull OutputStream errStream)\n            throws IOException, URISyntaxException {\n        DexArchiveBuilder dexArchiveBuilder =\n                getDexArchiveBuilder(\n                        dexConversionParameters.minSdkVersion,\n                        dexConversionParameters.dexAdditionalParameters,\n                        dexConversionParameters.inBufferSize,\n                        dexConversionParameters.outBufferSize,\n                        dexConversionParameters.dexer,\n                        dexConversionParameters.isDebuggable,\n                        dexConversionParameters.awb,\n                        outStream,\n                        errStream);\n\n                                                                                                                                                                                                                                                                                                                                    Path inputPath = dexConversionParameters.input.getFile().toPath();\n        Predicate<String> bucketFilter = dexConversionParameters::belongsToThisBucket;\n\n        boolean hasIncrementalInfo =\n                dexConversionParameters.isDirectoryBased() && dexConversionParameters.isIncremental;\n        Predicate<String> toProcess =\n                hasIncrementalInfo\n                        ? path -> {\n                    Map<File, Status> changedFiles =\n                            ((DirectoryInput) dexConversionParameters.input)\n                                    .getChangedFiles();\n\n                    File resolved = inputPath.resolve(path).toFile();\n                    Status status = changedFiles.get(resolved);\n                    return status == Status.ADDED || status == Status.CHANGED;\n                }\n                        : path -> true;\n\n        bucketFilter = bucketFilter.and(toProcess);\n\n        try (ClassFileInput input = ClassFileInputs.fromPath(inputPath)) {\n            dexArchiveBuilder.convert(\n                    input.entries(bucketFilter),\n                    Paths.get(new URI(dexConversionParameters.output)),\n                    dexConversionParameters.isDirectoryBased());\n        } catch (DexArchiveBuilderException ex) {\n            throw new DexArchiveBuilderException(\"Failed to process \" + inputPath.toString(), ex);\n        }\n    }\n\n    @NonNull\n    private static File getPreDexFile(\n            @NonNull TransformOutputProvider output,\n            @NonNull QualifiedContent qualifiedContent,\n            int bucketId) {\n\n        return qualifiedContent.getFile().isDirectory()\n                ? getPreDexFolder(output, (DirectoryInput) qualifiedContent)\n                : getPreDexJar(output, (JarInput) qualifiedContent, bucketId);\n    }\n\n    @NonNull\n    private static File getPreDexJar(\n            @NonNull TransformOutputProvider output,\n            @NonNull JarInput qualifiedContent,\n            @Nullable Integer bucketId) {\n\n        return output.getContentLocation(\n                qualifiedContent.getName().replace(\":\",\"-\") + (bucketId == null ? \"\" : (\"-\" + bucketId)),\n                ImmutableSet.of(ExtendedContentType.DEX_ARCHIVE),\n                qualifiedContent.getScopes(),\n                Format.JAR);\n    }\n\n    @NonNull\n    private static File getPreDexFolder(\n            @NonNull TransformOutputProvider output, @NonNull DirectoryInput directoryInput) {\n\n        return FileUtils.mkdirs(\n                output.getContentLocation(\n                        directoryInput.getName(),\n                        ImmutableSet.of(ExtendedContentType.DEX_ARCHIVE),\n                        directoryInput.getScopes(),\n                        Format.DIRECTORY));\n    }\n\n\n    private List<File> convertAwbToDexArchive(\n            @NonNull Context context,\n            @NonNull QualifiedContent input,\n            @NonNull File outputProvider,\n            boolean isIncremental,\n            boolean awb)\n            throws Exception {\n\n        int count = 0;\n        if (input.getFile().isFile()) {\n             count = computerClassCount(input.getFile());\n           \n        }else if (input.getFile().isDirectory()){\n            count = 1;\n        }\n        logger.verbose(\"Dexing {}\", input.getFile().getAbsolutePath());\n\n        ImmutableList.Builder<File> dexArchives = ImmutableList.builder();\n\n        for (int bucketId = 0; bucketId < count; bucketId++) {\n            File preDexOutputFile = getAwbPreDexFile(outputProvider, input, bucketId);\n            if (input.getFile().isDirectory()) {\n                File cachedVersion = cacheHandler.getCachedVersionIfPresent(input.getFile());\n                dexArchives.add(preDexOutputFile);\n                if (cachedVersion != null) {\n                    FileUtils.copyDirectoryContentToDirectory(cachedVersion, preDexOutputFile);\n                    return dexArchives.build();\n                }\n            }\n            if (preDexOutputFile.isDirectory() && preDexOutputFile.exists()) {\n                FileUtils.cleanOutputDir(preDexOutputFile);\n            }else {\n                FileUtils.deleteIfExists(preDexOutputFile);\n            }\n            AtlasDexArchiveBuilderTransform.DexConversionParameters parameters =\n                    new AtlasDexArchiveBuilderTransform.DexConversionParameters(\n                            input,\n                            preDexOutputFile,\n                            NUMBER_OF_BUCKETS,\n                            bucketId,\n                            minSdkVersion,\n                            dexOptions.getAdditionalParameters(),\n                            inBufferSize,\n                            outBufferSize,\n                            dexer,\n                            isDebuggable,\n                            false,\n                            awb);\n\n            if (useGradleWorkers) {\n                context.getWorkerExecutor()\n                        .submit(\n                                DexArchiveBuilderTransform.DexConversionWorkAction.class,\n                                configuration -> {\n                                    configuration.setIsolationMode(IsolationMode.NONE);\n                                    configuration.setParams(parameters);\n                                });\n            } else {\n                executor.execute(\n                        () -> {\n                            ProcessOutputHandler outputHandler =\n                                    new ParsingProcessOutputHandler(\n                                            new ToolOutputParser(\n                                                    new DexParser(), Message.Kind.ERROR, logger),\n                                            new ToolOutputParser(new DexParser(), logger),\n                                            errorReporter);\n                            ProcessOutput output = null;\n                            try (Closeable ignored = output = outputHandler.createOutput()) {\n                                launchProcessing(\n                                        parameters,\n                                        output.getStandardOutput(),\n                                        output.getErrorOutput());\n                            } finally {\n                                if (output != null) {\n                                    try {\n                                        outputHandler.handleOutput(output);\n                                    } catch (ProcessException e) {\n                                        // ignore this one\n                                    }\n                                }\n                            }\n                            return null;\n                        });\n            }\n        }\n\n       List<File>files =  dexArchives.build();\n        return files;\n    }\n\n\n    private void processAwbDexArchive(TransformInvocation transformInvocation, List<QualifiedContent> listFiles) throws Exception {\n\n        File awbApkOutputDir = ((AppVariantContext) variantContext).getAwbApkOutputDir();\n        FileUtils.cleanOutputDir(awbApkOutputDir);\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n                variantContext.getScope().getFullVariantName());\n\n        if (null == atlasDependencyTree) {\n            return;\n        }\n\n        for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n\n            Multimap<QualifiedContent, File> cacheableItems = HashMultimap.create();\n\n            List<QualifiedContent> qualifiedContents = new LinkedList<>();\n\n            long start = System.currentTimeMillis();\n\n\n            // if some of our .jar input files exist, just reset the inputDir to null\n            AwbTransform awbTransform = variantContext.getAppVariantOutputContext(ApkDataUtils.get(variantOutput)).getAwbTransformMap()\n                    .get(awbBundle.getName());\n            List<File> inputFiles = new ArrayList<File>();\n            inputFiles.addAll(awbTransform.getInputFiles());\n            inputFiles.addAll(awbTransform.getInputLibraries());\n            if (null != awbTransform.getInputDirs()) {\n                inputFiles.addAll(awbTransform.getInputDirs());\n            }\n\n            for (File file : inputFiles) {\n                logger.warning(awbBundle.getName()+\":\"+file.getAbsolutePath());\n                boolean find = false;\n                for (QualifiedContent content : listFiles) {\n                    if (content.getFile().getAbsolutePath().equals(file.getAbsolutePath())) {\n                        find = true;\n                        qualifiedContents.add(content);\n                        break;\n                    }\n                }\n\n                if (!find) {\n                    if (file.isDirectory()) {\n                        DirectoryInput directoryInput = TransformInputUtils.makeDirectoryInput(file,variantContext);\n                        qualifiedContents.add(directoryInput);\n                    } else if (file.isFile()) {\n                        JarInput jarInput = TransformInputUtils.makeJarInput(file,variantContext);\n                        qualifiedContents.add(jarInput);\n                    }\n\n                }\n\n            }\n            for (QualifiedContent qualifiedContent : qualifiedContents) {\n                if (qualifiedContent.getFile().isDirectory()) {\n                    List<File>awbFiles = convertAwbToDexArchive(\n                            transformInvocation.getContext(),\n                            qualifiedContent, variantContext.getAwbDexAchiveOutput(awbBundle), transformInvocation.isIncremental()\n                    ,true);\n                    cacheableItems.putAll(qualifiedContent, awbFiles);\n\n                } else {\n                    List<File> jarFiles = processAwbJarInput(transformInvocation.getContext(), transformInvocation.isIncremental(), (JarInput) qualifiedContent, variantContext.getAwbDexAchiveOutput(awbBundle));\n                    cacheableItems.putAll(qualifiedContent, jarFiles);\n                }\n            }\n\n            cacheItems.putAll(cacheableItems);\n\n\n        }\n    }\n\n    private File getAwbPreDexFile(File outputProvider, QualifiedContent qualifiedContent, Integer bucketId) {\n        return qualifiedContent.getFile().isDirectory()\n                ? getAwbPreDexFolder(outputProvider, (DirectoryInput) qualifiedContent)\n                : getAwbPreDexJar(outputProvider, (JarInput) qualifiedContent, bucketId);\n    }\n\n      Map<String,Integer> dexcount = new HashMap<>();\n\n\n    private File getAwbPreDexJar(\n            @NonNull File output,\n            @NonNull JarInput qualifiedContent,\n            @Nullable Integer bucketId) {\n        if (!output.exists()){\n            output.mkdirs();\n        }\n        if (bucketId == null){\n            return new File(output, qualifiedContent.getName().replace(\":\",\"-\") + (bucketId == null ? \"\" : (\"-\" + bucketId)) + \".jar\");\n        }\n//        synchronized (object) {\n            if (bucketId > 5) {\n                bucketId = dexcount.get(qualifiedContent.getName());\n            }\n            dexcount.put(qualifiedContent.getName(), bucketId++);\n//        }\n\n        return new File(output, qualifiedContent.getName().replace(\":\",\"-\") + (bucketId == null ? \"\" : (\"-\" + bucketId)) + \".jar\");\n\n    }\n\n    @NonNull\n    private static File getAwbPreDexFolder(\n            @NonNull File output, @NonNull DirectoryInput directoryInput) {\n        return FileUtils.mkdirs(new File(output, directoryInput.getName()));\n    }\n\n\n\n\n    private int computerClassCount(File file){\n        JarFile jarFile = null;\n        int count = 0;\n        try {\n            jarFile = new JarFile(file);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        Enumeration enumeration= jarFile.entries();\n        while (enumeration.hasMoreElements()){\n            JarEntry jarEntry = (JarEntry) enumeration.nextElement();\n            if (jarEntry.getName().endsWith(\".class\")){\n                count ++;\n            }\n            if (count > 1){\n                return 1;\n            }\n        }\n       return count;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/dex/AtlasDexMerger.java",
    "content": "package com.taobao.android.builder.tasks.transform.dex;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.api.transform.Format;\nimport com.android.build.api.transform.QualifiedContent;\nimport com.android.build.api.transform.TransformInvocation;\nimport com.android.build.api.transform.TransformOutputProvider;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.pipeline.TransformManager;\nimport com.android.builder.core.ErrorReporter;\nimport com.android.builder.dexing.DexMergerTool;\nimport com.android.builder.dexing.DexingType;\nimport com.android.builder.utils.FileCache;\nimport com.android.ide.common.blame.Message;\nimport com.android.ide.common.blame.ParsingProcessOutputHandler;\nimport com.android.ide.common.blame.parser.DexParser;\nimport com.android.ide.common.blame.parser.ToolOutputParser;\nimport com.android.ide.common.process.ProcessOutput;\nimport com.android.ide.common.process.ProcessOutputHandler;\nimport com.android.tools.r8.AtlasD8;\nimport com.google.common.base.Preconditions;\nimport com.google.common.collect.ImmutableList;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.file.FileCollection;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.*;\nimport java.util.concurrent.ForkJoinPool;\nimport java.util.concurrent.ForkJoinTask;\n\n/**\n * AtlasDexMerger\n *\n * @author zhayu.ll\n * @date 18/2/9\n */\npublic abstract class AtlasDexMerger {\n    @NonNull\n    protected final DexingType dexingType;\n\n\n    protected LoggerWrapper logger;\n\n    public CacheHandler cacheHandler;\n\n    @Nullable\n    protected final FileCollection mainDexListFile;\n\n    @NonNull protected final DexMergerTool dexMerger;\n\n    protected static final String CACHE_VERSION=\"1.0.1\";\n\n    protected final String CLASSES_DEX=\"classes.dex\";\n\n    protected final int minSdkVersion;\n    protected final boolean isDebuggable;\n    @NonNull protected final ErrorReporter errorReporter;\n\n    public List<File> getAllDexsArchives() {\n        return allDexsArchives;\n    }\n\n    protected List<File>allDexsArchives = new ArrayList<>();\n\n    @NonNull private final ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();\n\n    protected AppVariantOutputContext variantOutputContext;\n\n    protected ProcessOutputHandler outputHandler;\n\n\n    public AtlasDexMerger(DexingType dexingType, FileCollection mainDexListFile, ErrorReporter errorReporter, DexMergerTool dexMerger, int minSdkVersion, boolean isDebuggable, AppVariantOutputContext appVariantOutputContext) {\n        this.dexingType = dexingType;\n        this.mainDexListFile = mainDexListFile;\n        this.dexMerger = dexMerger;\n        this.minSdkVersion = minSdkVersion;\n        this.isDebuggable = isDebuggable;\n        this.logger= LoggerWrapper.getLogger(getClass());\n        Preconditions.checkState(\n                (dexingType == DexingType.LEGACY_MULTIDEX) == (mainDexListFile != null),\n                \"Main dex list must only be set when in legacy multidex\");\n        this.errorReporter = errorReporter;\n        this.variantOutputContext = appVariantOutputContext;\n         outputHandler =\n                new ParsingProcessOutputHandler(\n                        new ToolOutputParser(new DexParser(), Message.Kind.ERROR, logger),\n                        new ToolOutputParser(new DexParser(), logger),\n                        errorReporter);\n\n    }\n\n\n    protected FileCache.Inputs getBuildCacheInputs(List<File> mainDexFiles, DexingType dexingType, DexMergerTool dexMerger, File file, int minSdkVersion, boolean isDebuggable, String bundleName,String id) {\n        FileCache.Inputs.Builder inputsBuilder = new FileCache.Inputs.Builder(FileCache.Command.PREDEX_LIBRARY_TO_DEX_ARCHIVE);\n        for (int i = 0; i < mainDexFiles.size();i++) {\n            inputsBuilder.putFile(String.valueOf(i), mainDexFiles.get(i), FileCache.FileProperties.HASH);\n        }\n        inputsBuilder.putString(\"dexingType\",dexingType.name()).putString(\"dexMerger\",dexMerger.name());\n        if (file!= null && file.exists()) {\n            inputsBuilder.putFile(\"maindexlist\", file, FileCache.FileProperties.HASH);\n        }\n        inputsBuilder.putLong(\"minSdkVersion\",minSdkVersion).putBoolean(\"isDebuggable\",isDebuggable);\n        inputsBuilder.putString(\"type\",id).putString(\"version\",CACHE_VERSION);\n        inputsBuilder.putString(\"bundleName\",bundleName);\n        if (AtlasD8.deepShrink) {\n            inputsBuilder.putBoolean(\"deepShrink\", AtlasD8.deepShrink);\n        }\n\n        FileCache.Inputs inputs = inputsBuilder.build();\n        return inputs;\n    }\n\n\n    protected void sort(List<File>dexFiles){\n        Collections.sort(dexFiles, (o1, o2) -> {\n            if (o1.length() > o2.length()) {\n                return 1;\n            }else if (o1.length() < o2.length()){\n                return -1;\n            }else {\n                return 0;\n            }\n        });\n    }\n\n\n    @NonNull\n    private ForkJoinTask<Void> submitForMerging(\n            @NonNull ProcessOutput output,\n            @NonNull File dexOutputDir,\n            @NonNull Iterable<Path> dexArchives,\n            @Nullable Path mainDexList) {\n        DexMergeTransformCallable callable =\n                new DexMergeTransformCallable(\n                        dexingType,\n                        output,\n                        dexOutputDir,\n                        dexArchives,\n                        mainDexList,\n                        forkJoinPool,\n                        dexMerger,\n                        minSdkVersion,\n                        isDebuggable);\n        return forkJoinPool.submit(callable);\n    }\n\n\n    @NonNull\n    protected List<ForkJoinTask<Void>> handleNativeMultiDex(\n            @NonNull List<File> inputs,\n            @NonNull ProcessOutput output,\n            @NonNull File outPutDir,\n            File mainDexList)\n            throws IOException {\n//        ImmutableList.Builder<ForkJoinTask<Void>> subTasks = ImmutableList.builder();\n//\n//        throw new IOException(\"instantRun in AtlasPlugin is deprecared!\");\n\n        ImmutableList.Builder<Path> dexArchiveBuilder = ImmutableList.builder();\n        for ( File file:inputs){\n            dexArchiveBuilder.add(file.toPath());\n        }\n        ImmutableList<Path> dexesToMerge = dexArchiveBuilder.build();\n        if (dexesToMerge.isEmpty()) {\n            return ImmutableList.of();\n        }\n\n        return ImmutableList.of(submitForMerging(output, outPutDir, dexesToMerge, mainDexList == null ? null:mainDexList.toPath()));\n\n    }\n\n    @NonNull\n    public List<ForkJoinTask<Void>> handleLegacyAndMonoDex(\n            @NonNull Collection<File> inputs,\n            @NonNull ProcessOutput output,File awbDexOutFolder,File mainDexList)\n            throws IOException {\n        ImmutableList.Builder<Path> dexArchiveBuilder = ImmutableList.builder();\n        for ( File file:inputs){\n            dexArchiveBuilder.add(file.toPath());\n        }\n        ImmutableList<Path> dexesToMerge = dexArchiveBuilder.build();\n        if (dexesToMerge.isEmpty()) {\n            return ImmutableList.of();\n        }\n\n        return ImmutableList.of(submitForMerging(output, awbDexOutFolder, dexesToMerge, mainDexList== null? null:mainDexList.toPath()));\n    }\n\n    public abstract void merge(TransformInvocation transformInvocation);\n\n\n    @NonNull\n    protected File getDexOutputLocation(\n            @NonNull TransformOutputProvider outputProvider,\n            @NonNull String name,\n            @NonNull Set<? super QualifiedContent.Scope> scopes) {\n        return outputProvider.getContentLocation(name, TransformManager.CONTENT_DEX, scopes, Format.DIRECTORY);\n    }\n\n    public void mergeAll(TransformInvocation transformInvocation) throws IOException {\n        ProcessOutput output = outputHandler.createOutput();\n        for (File file:allDexsArchives){\n            logger.warning(\"mergeAll File:\"+file.getAbsolutePath());\n        }\n        TransformOutputProvider outputProvider = transformInvocation.getOutputProvider();\n        File outputDir =\n                getDexOutputLocation(outputProvider, \"main\", TransformManager.SCOPE_FULL_PROJECT);\n\n        File finalDexDir = new File(outputDir.getParentFile(),\"temp\");\n        finalDexDir.mkdirs();\n        List<ForkJoinTask<Void>> mergeTasks = new ArrayList();\n        if (dexingType == DexingType.NATIVE_MULTIDEX) {\n            mergeTasks.addAll(\n                    handleNativeMultiDex(\n                            allDexsArchives,\n                            output,\n                            finalDexDir,\n                             null));\n        } else {\n            mergeTasks.addAll(\n                    handleLegacyAndMonoDex(\n                            allDexsArchives, output, finalDexDir, mainDexListFile == null ? null : mainDexListFile.getSingleFile()));\n        }\n\n        mergeTasks.forEach(voidForkJoinTask -> voidForkJoinTask.join());\n\n        FileUtils.deleteDirectory(outputDir);\n        FileUtils.moveDirectory(finalDexDir,outputDir);\n\n    }\n\n\n    public static interface CacheHandler{\n\n        void handleMissActionResult(File outputDir,File in) throws IOException;\n\n        void handleQueryResult(FileCache.QueryResult queryResult,File outDir,String bundleName) throws IOException;\n\n    }\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/dex/AtlasDexMergerTransform.java",
    "content": "package com.taobao.android.builder.tasks.transform.dex;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.internal.BuildCacheUtils;\nimport com.android.build.gradle.internal.InternalScope;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.pipeline.ExtendedContentType;\nimport com.android.build.gradle.internal.pipeline.TransformManager;\nimport com.android.build.gradle.internal.transforms.DexMergerTransform;\nimport com.android.build.gradle.internal.transforms.DexMergerTransformCallable;\nimport com.android.builder.core.ErrorReporter;\nimport com.android.builder.dexing.DexMergerTool;\nimport com.android.builder.dexing.DexingType;\nimport com.android.builder.utils.ExceptionRunnable;\nimport com.android.builder.utils.FileCache;\nimport com.android.ide.common.blame.Message;\nimport com.android.ide.common.blame.ParsingProcessOutputHandler;\nimport com.android.ide.common.blame.parser.DexParser;\nimport com.android.ide.common.blame.parser.ToolOutputParser;\nimport com.android.ide.common.process.ProcessException;\nimport com.android.ide.common.process.ProcessOutput;\nimport com.android.ide.common.process.ProcessOutputHandler;\nimport com.android.tools.r8.AtlasD8;\nimport com.android.utils.FileUtils;\nimport com.android.utils.ILogger;\nimport com.google.common.collect.*;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tools.MD5Util;\nimport javafx.util.Pair;\nimport org.gradle.api.file.FileCollection;\n\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ForkJoinPool;\nimport java.util.concurrent.ForkJoinTask;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n/**\n * @author lilong\n * @create 2017-12-08 下午5:26\n */\n\npublic class AtlasDexMergerTransform extends Transform {\n\n\n    private AtlasDexMerger atlasMainDexMerger;\n\n    private AtlasDexMerger awbDexMerger;\n\n    private File mainDexListFile;\n    private DexingType dexingType;\n    private DexMergerTool dexMergerTool;\n    private AppVariantOutputContext variantOutputContext;\n\n    public AtlasDexMergerTransform(AppVariantOutputContext appVariantOutputContext,\n                                   @NonNull DexingType dexingType,\n                                   @Nullable FileCollection mainDexListFile,\n                                   @NonNull ErrorReporter errorReporter,\n                                   @NonNull DexMergerTool dexMerger,\n                                   int minSdkVersion,\n                                   boolean isDebuggable\n    ) {\n        this.variantOutputContext = appVariantOutputContext;\n        atlasMainDexMerger = new AtlasMainDexMerger(dexingType, mainDexListFile, errorReporter, dexMerger, minSdkVersion, isDebuggable, appVariantOutputContext);\n        awbDexMerger = new AwbDexsMerger(DexingType.MONO_DEX, null, errorReporter, dexMerger, minSdkVersion, isDebuggable, appVariantOutputContext);\n        this.mainDexListFile = mainDexListFile == null ? null : mainDexListFile.getSingleFile();\n        this.dexingType = dexingType;\n        this.dexMergerTool = dexMerger;\n\n\n    }\n\n    @Override\n    public String getName() {\n        return \"atlasDexmerge\";\n    }\n\n    @Override\n    public Set<QualifiedContent.ContentType> getInputTypes() {\n        return ImmutableSet.of(ExtendedContentType.DEX_ARCHIVE);\n    }\n\n    @Override\n    public Set<QualifiedContent.ContentType> getOutputTypes() {\n        return TransformManager.CONTENT_DEX;\n    }\n\n    @Override\n    public Set<? super QualifiedContent.Scope> getScopes() {\n        return TransformManager.SCOPE_FULL_WITH_IR_FOR_DEXING;\n\n    }\n\n    @Override\n    public Collection<SecondaryFile> getSecondaryFiles() {\n        if (mainDexListFile != null) {\n            return ImmutableList.of(SecondaryFile.nonIncremental(mainDexListFile));\n        } else {\n            return ImmutableList.of();\n        }\n    }\n\n    @Override\n    public Map<String, Object> getParameterInputs() {\n        Map<String, Object> params = new LinkedHashMap<>(2);\n        params.put(\"dexing-type\", dexingType.name());\n        params.put(\"dex-merger-tool\", dexMergerTool.name());\n        return params;\n    }\n\n    @Override\n    public boolean isIncremental() {\n        return false;\n    }\n\n    @Override\n    public boolean isCacheable() {\n        return false;\n    }\n\n    @Override\n    public void transform(TransformInvocation transformInvocation) throws TransformException, IOException, InterruptedException {\n        if (variantOutputContext.getVariantContext().getProject().hasProperty(\"light\") && variantOutputContext.getVariantContext().getProject().hasProperty(\"deepShrink\")) {\n            AtlasD8.deepShrink = true;\n        }\n        super.transform(transformInvocation);\n        TransformOutputProvider transformOutputProvider = transformInvocation.getOutputProvider();\n        transformOutputProvider.deleteAll();\n        atlasMainDexMerger.merge(transformInvocation);\n        awbDexMerger.merge(transformInvocation);\n        if (variantOutputContext.getVariantContext().getAtlasExtension().getTBuildConfig().getMergeBundlesDex()) {\n            atlasMainDexMerger.getAllDexsArchives().addAll(awbDexMerger.getAllDexsArchives());\n            atlasMainDexMerger.mergeAll(transformInvocation);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/dex/AtlasMainDexMerger.java",
    "content": "package com.taobao.android.builder.tasks.transform.dex;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.annotations.VisibleForTesting;\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.internal.BuildCacheUtils;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.pipeline.IntermediateFolderUtils;\nimport com.android.build.gradle.internal.pipeline.TransformManager;\nimport com.android.builder.core.ErrorReporter;\nimport com.android.builder.dexing.DexMergerTool;\nimport com.android.builder.dexing.DexingType;\nimport com.android.builder.utils.FileCache;\nimport com.android.ide.common.process.ProcessException;\nimport com.android.ide.common.process.ProcessOutput;\nimport com.android.ide.common.process.ProcessOutputHandler;\nimport com.android.prefs.AndroidLocation;\nimport com.android.utils.FileUtils;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport org.gradle.api.Project;\nimport org.gradle.api.file.FileCollection;\n\nimport java.io.*;\nimport java.lang.reflect.Field;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.*;\nimport java.util.concurrent.ForkJoinPool;\nimport java.util.concurrent.ForkJoinTask;\nimport java.util.function.Consumer;\nimport java.util.stream.Collectors;\n\n/**\n * @author lilong\n * @create 2017-12-27 上午9:43\n */\n\n\npublic class AtlasMainDexMerger extends AtlasDexMerger {\n\n    private static final String ID = \"atlasmaindexmerge\";\n\n\n    public AtlasMainDexMerger(DexingType dexingType, FileCollection mainDexListFile, ErrorReporter errorReporter, DexMergerTool dexMerger, int minSdkVersion, boolean isDebuggable, AppVariantOutputContext appVariantOutputContext) {\n\n        super(dexingType, mainDexListFile, errorReporter, dexMerger, minSdkVersion, isDebuggable, appVariantOutputContext);\n        cacheHandler = new CacheHandler() {\n            @Override\n            public void handleMissActionResult(File outputDir, File in) throws IOException {\n                File[] dexs = outputDir.listFiles((dir, name) -> name.endsWith(\".dex\"));\n                if (dexs != null && dexs.length > 1) {\n                    org.apache.commons.io.FileUtils.copyDirectory(outputDir,in);\n//                    for (File file : dexs) {\n//                        org.apache.commons.io.FileUtils.copyFileToDirectory(file, in.getParentFile());\n//                    }\n\n                } else if (dexs.length == 1) {\n                    if (!in.getParentFile().exists()){\n                        in.getParentFile().mkdirs();\n                    }\n                    Files.copy(dexs[0].toPath(), in.toPath());\n                } else {\n                    throw new IOException(\"no dex file merge out\");\n                }\n            }\n\n            @Override\n            public void handleQueryResult(FileCache.QueryResult result, File outputDir, String bundleName) throws IOException {\n\n                if (result.getQueryEvent().equals(FileCache.QueryEvent.HIT)) {\n                    if (result.getCachedFile().exists() && result.getCachedFile().isDirectory()) {\n                        logger.info(\"hit maindex dexmerge cache ->\" + result.getCachedFile().getAbsolutePath());\n                        org.apache.commons.io.FileUtils.copyDirectory(result.getCachedFile(), outputDir);\n                    } else if (result.getCachedFile().exists() && result.getCachedFile().isFile()) {\n//                        File[] dexs = result.getCachedFile().getParentFile().listFiles((dir, name) -> name.endsWith(\".dex\"));\n//                        if (dexs != null && dexs.length > 0) {\n//                            for (File dex : dexs) {\n                                logger.info(\"hit maindex dexmerge cache ->\" + result.getCachedFile().getAbsolutePath());\n                                org.apache.commons.io.FileUtils.copyFile(result.getCachedFile(), new File(outputDir,CLASSES_DEX));\n//                            }\n\n//                        }\n                    }\n                } else {\n                    logger.info(\"miss maindex dexmerge cache -> null\");\n\n                }\n            }\n        };\n    }\n\n    @Override\n    public void merge(TransformInvocation transformInvocation) {\n\n        if (dexMerger == DexMergerTool.D8) {\n            logger.info(\"D8 is used to merge dex.\");\n        }\n\n        TransformOutputProvider outputProvider = transformInvocation.getOutputProvider();\n        Collection<TransformInput> transformInputs = transformInvocation.getInputs();\n\n        List<File> mainDexFiles = new ArrayList<>();\n\n        final File[][] mergeDexs = {new File[0]};\n\n        File outputDir =\n                getDexOutputLocation(outputProvider, \"main\", TransformManager.SCOPE_FULL_PROJECT);\n        // this deletes and creates the dir for the output\n        try {\n            FileUtils.cleanOutputDir(outputDir);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        variantOutputContext.setDexMergeFolder(outputDir);\n\n        transformInputs.forEach((TransformInput transformInput) -> {\n            File file = (File) ReflectUtils.getField(transformInput, \"optionalRootLocation\");\n            if (file != null && file.exists()) {\n                mainDexFiles.addAll(org.apache.commons.io.FileUtils.listFiles(file, new String[]{\"jar\", \"dex\"}, true));\n                mergeDexs[0] = file.listFiles(pathname -> pathname.getName().endsWith(\".jar\") || pathname.isDirectory());\n            }\n        });\n\n\n        merge(mainDexFiles,outputDir,mergeDexs);\n\n    }\n\n    public void merge(List<File>mainDexFiles,File outputDir,File[][] mergeDexs) {\n        sort(mainDexFiles);\n        FileCache.Inputs buildCacheInputs =\n                getBuildCacheInputs(\n                        mainDexFiles, dexingType, dexMerger, mainDexListFile == null ? null : mainDexListFile.getSingleFile(), minSdkVersion, isDebuggable, \"maindex\", ID);\n        ProcessOutput output = outputHandler.createOutput();\n        FileCache fileCache = BuildCacheUtils.createBuildCacheIfEnabled(variantOutputContext.getVariantContext().getProject(), variantOutputContext.getScope().getGlobalScope().getProjectOptions());\n        if (fileCache == null){\n            try {\n                fileCache = FileCache.getInstanceWithMultiProcessLocking(new File(AndroidLocation.getFolder(),\"atlas-buildCache\"));\n            } catch (AndroidLocation.AndroidLocationException e) {\n                e.printStackTrace();\n            }\n        }\n\n        if (variantOutputContext.getVariantContext().getAtlasExtension().getTBuildConfig().getMergeBundlesDex()){\n            allDexsArchives.addAll(Arrays.asList(mergeDexs[0]));\n            return;\n        }\n\n        try {\n            FileCache.QueryResult result = fileCache.createFileInCacheIfAbsent(\n                    buildCacheInputs,\n                    in -> {\n                        List<ForkJoinTask<Void>> mergeTasks = new ArrayList();\n                        if (dexingType == DexingType.NATIVE_MULTIDEX) {\n                            mergeTasks.addAll(\n                                    handleNativeMultiDex(\n                                            Arrays.asList(mergeDexs[0]),\n                                            output,\n                                            outputDir,\n                                            mainDexListFile == null ? null : mainDexListFile.getSingleFile()));\n                        } else {\n                            mergeTasks.addAll(\n                                    handleLegacyAndMonoDex(\n                                            Arrays.asList(mergeDexs[0]), output, outputDir, mainDexListFile == null ? null : mainDexListFile.getSingleFile()));\n                        }\n\n                        mergeTasks.forEach(voidForkJoinTask -> voidForkJoinTask.join());\n\n                        cacheHandler.handleMissActionResult(outputDir, in);\n\n                        if (output != null) {\n                            try {\n                                outputHandler.handleOutput(output);\n                            } catch (ProcessException e) {\n                                // ignore this one\n                            }\n                        }\n                    });\n\n            cacheHandler.handleQueryResult(result, outputDir, \"maindex\");\n\n\n        }catch (Exception e){\n            e.printStackTrace();\n        }\n    }\n\n\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/dex/AtlasMultiDexListTransform.java",
    "content": "package com.taobao.android.builder.tasks.transform.dex;\n\nimport com.android.annotations.NonNull;\nimport com.android.build.api.transform.*;\nimport com.android.build.gradle.internal.dsl.DexOptions;\nimport com.android.build.gradle.internal.pipeline.TransformManager;\nimport com.android.build.gradle.internal.pipeline.TransformTask;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.transforms.BaseProguardAction;\nimport com.android.build.gradle.internal.transforms.MultiDexTransform;\nimport com.android.build.gradle.internal.transforms.TransformInputUtil;\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.ImmutableSet;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.tasks.app.BuildAtlasEnvTask;\nimport com.taobao.android.builder.tasks.app.BuildAtlasEnvTask;\nimport com.taobao.android.builder.tools.multidex.FastMultiDexer;\nimport org.gradle.api.logging.LogLevel;\nimport org.gradle.api.logging.LoggingManager;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Objects;\nimport java.util.Set;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\n/**\n * @author lilong\n * @create 2017-12-27 下午2:30\n */\n\n\npublic class AtlasMultiDexListTransform extends BaseProguardAction {\n\n    private final File mainDexListFile;\n    private final File manifestKeepListProguardFile;\n    private final File userMainDexKeepProguard;\n    private final File userMainDexKeepFile;\n    private VariantScope variantScope;\n\n    public AtlasMultiDexListTransform(VariantScope variantScope, DexOptions dexOptions) {\n        super(variantScope);\n        this.variantScope = variantScope;\n        mainDexListFile = variantScope.getMainDexListFile();\n        this.manifestKeepListProguardFile = variantScope.getManifestKeepListProguardFile();\n        this.userMainDexKeepProguard = variantScope.getVariantConfiguration().getMultiDexKeepProguard();\n        this.userMainDexKeepFile = variantScope.getVariantConfiguration().getMultiDexKeepFile();\n\n    }\n\n    @Override\n    public String getName() {\n        return \"atlasmultidexlist\";\n    }\n\n    @Override\n    public Set<QualifiedContent.ContentType> getInputTypes() {\n        return ImmutableSet.of(QualifiedContent.DefaultContentType.CLASSES);\n    }\n\n    @Override\n    public Set<QualifiedContent.ContentType> getOutputTypes() {\n        return ImmutableSet.of(QualifiedContent.DefaultContentType.CLASSES);\n    }\n\n    @Override\n    public Set<QualifiedContent.Scope> getScopes() {\n        return TransformManager.EMPTY_SCOPES;\n    }\n\n    @Override\n    public Set<QualifiedContent.Scope> getReferencedScopes() {\n        return TransformManager.SCOPE_FULL_PROJECT;\n    }\n\n    @Override\n    public Collection<SecondaryFile> getSecondaryFiles() {\n        return Stream.of(manifestKeepListProguardFile, userMainDexKeepFile, userMainDexKeepProguard)\n                .filter(Objects::nonNull)\n                .map(SecondaryFile::nonIncremental)\n                .collect(Collectors.toList());\n    }\n\n    @Override\n    public Collection<File> getSecondaryFileOutputs() {\n        return ImmutableList.of(mainDexListFile);\n    }\n\n    @Override\n    public boolean isIncremental() {\n        return false;\n    }\n\n    public void transform(@NonNull TransformInvocation transformInvocation)\n            throws TransformException, InterruptedException, IOException {\n        if (mainDexListFile.exists() && !variantScope.getVariantData().getName().toLowerCase().endsWith(\"release\")){\n            return;\n        }\n        LoggingManager loggingManager = transformInvocation.getContext().getLogging();\n        loggingManager.captureStandardOutput(LogLevel.INFO);\n        loggingManager.captureStandardError(LogLevel.WARN);\n        Collection<File> inputs =AtlasBuildContext.atlasMainDexHelperMap.get(variantScope.getFullVariantName()).getAllMainDexJars();\n        inputs.addAll(AtlasBuildContext.atlasMainDexHelperMap.get(variantScope.getFullVariantName()).getInputDirs());\n        if (AtlasBuildContext.androidBuilderMap.get(variantScope.getGlobalScope().getProject()) == null) {\n            super.transform(transformInvocation);\n        } else if (AtlasBuildContext.androidBuilderMap.get(variantScope.getGlobalScope().getProject()).multiDexer == null) {\n            super.transform(transformInvocation);\n        }\n        FastMultiDexer fastMultiDexer = (FastMultiDexer) AtlasBuildContext.androidBuilderMap.get(variantScope.getGlobalScope().getProject()).multiDexer;\n\n        Collection<File>files = fastMultiDexer.repackageJarList(inputs, mainDexListFile,variantScope.getVariantData().getName().toLowerCase().endsWith(\"release\"));\n\n        if (files!= null && files.size() > 0){\n            AtlasBuildContext.atlasMainDexHelperMap.get(variantScope.getFullVariantName()).addAllMainDexJars(files);\n\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/dex/AwbDexsMerger.java",
    "content": "package com.taobao.android.builder.tasks.transform.dex;\n\nimport com.android.build.api.transform.TransformInvocation;\nimport com.android.build.gradle.internal.BuildCacheUtils;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.pipeline.TransformManager;\nimport com.android.builder.core.ErrorReporter;\nimport com.android.builder.dexing.DexMergerTool;\nimport com.android.builder.dexing.DexerTool;\nimport com.android.builder.dexing.DexingType;\nimport com.android.builder.utils.FileCache;\nimport com.android.ide.common.process.ProcessException;\nimport com.android.ide.common.process.ProcessOutput;\nimport com.android.ide.common.process.ProcessOutputHandler;\nimport com.android.prefs.AndroidLocation;\nimport com.android.utils.FileUtils;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport org.gradle.api.file.FileCollection;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.concurrent.ForkJoinTask;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.function.Consumer;\n\n/**\n * AwbDexsMerger\n *\n * @author zhayu.ll\n * @date 18/2/9\n */\npublic class AwbDexsMerger extends AtlasDexMerger {\n\n    private static final String ID = \"atlasbundledexmerge\";\n\n    private AtomicInteger atomicInteger = new AtomicInteger();\n\n    private File mainDexOut = null;\n\n\n    public AwbDexsMerger(DexingType dexingType, FileCollection mainDexListFile, ErrorReporter errorReporter, DexMergerTool dexMerger, int minSdkVersion, boolean isDebuggable, AppVariantOutputContext appVariantOutputContext) {\n        super(dexingType, mainDexListFile, errorReporter, dexMerger, minSdkVersion, isDebuggable, appVariantOutputContext);\n            cacheHandler = new CacheHandler() {\n            @Override\n            public void handleMissActionResult(File outputDir, File in) throws IOException {\n                File[] dexs = outputDir.listFiles((dir, name) -> name.endsWith(\".dex\"));\n                if (dexs != null && dexs.length > 1) {\n                    for (File file : dexs) {\n                        org.apache.commons.io.FileUtils.copyFileToDirectory(file, in.getParentFile());\n                    }\n\n                } else if (dexs.length == 1) {\n\n                    Files.copy(dexs[0].toPath(), in.toPath());\n                } else {\n                    throw new IOException(\"no dex file merge out\");\n                }\n            }\n\n            @Override\n            public void handleQueryResult(FileCache.QueryResult result, File outDir, String bundleName) throws IOException {\n\n                if (result.getQueryEvent().equals(FileCache.QueryEvent.HIT)) {\n                    logger.info(\"hit dexmerge cache \" + bundleName + \"->\" + result.getCachedFile().getAbsolutePath());\n                    if (result.getCachedFile().exists()) {\n                        org.apache.commons.io.FileUtils.copyFile(result.getCachedFile(), new File(outDir, CLASSES_DEX));\n                    }\n                } else {\n                    logger.info(\"miss dexmerge cache \" + bundleName + \"-> null\");\n\n                }\n            }\n        };\n    }\n\n\n\n    @Override\n    public void merge(TransformInvocation transformInvocation) {\n\n        mainDexOut = getDexOutputLocation(transformInvocation.getOutputProvider(),\"main\", TransformManager.SCOPE_FULL_PROJECT);\n        if (!mainDexOut.exists() || !mainDexOut.isDirectory()){\n            return;\n        }\n        atomicInteger.set(org.apache.commons.io.FileUtils.listFiles(mainDexOut,new String[]{\"dex\"},true).size());\n        for (AwbTransform awbTransform : variantOutputContext.getAwbTransformMap().values()) {\n           merge(awbTransform.getAwbBundle());\n        }\n\n    }\n\n    public void merge(AwbBundle awbBundle){\n        File file = variantOutputContext.getVariantContext().getAwbDexAchiveOutput(awbBundle);\n        List<File> awbDexFiles = new ArrayList<>();\n        if (!file.exists() || !file.isDirectory()){\n            return;\n        }\n        awbDexFiles.addAll(org.apache.commons.io.FileUtils.listFiles(file, new String[]{\"jar\", \"dex\"}, true));\n        File[] mergeDexs = file.listFiles(pathname -> pathname.getName().endsWith(\".jar\") || pathname.isDirectory());\n        sort(awbDexFiles);\n        File outPutFolder = variantOutputContext.getAwbDexOutput(awbBundle.getName());\n        try {\n            FileUtils.cleanOutputDir(outPutFolder);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        FileCache.Inputs buildCacheInputs = getBuildCacheInputs(awbDexFiles, dexingType, dexMerger, null, minSdkVersion, isDebuggable, awbBundle.getName(), ID);\n        ProcessOutput output = outputHandler.createOutput();\n        FileCache fileCache = BuildCacheUtils.createBuildCacheIfEnabled(variantOutputContext.getVariantContext().getProject(), variantOutputContext.getScope().getGlobalScope().getProjectOptions());\n        if (fileCache == null){\n            try {\n                fileCache = FileCache.getInstanceWithMultiProcessLocking(new File(AndroidLocation.getFolder(),\"atlas-buildCache\"));\n            } catch (AndroidLocation.AndroidLocationException e) {\n                e.printStackTrace();\n            }\n        }\n        if (variantOutputContext.getVariantContext().getAtlasExtension().getTBuildConfig().getMergeBundlesDex() && !awbBundle.isRemote && awbBundle.isMBundle){\n            allDexsArchives.addAll(Arrays.asList(mergeDexs));\n            return;\n        }\n        try {\n            FileCache.QueryResult result = fileCache.createFileInCacheIfAbsent(\n                    buildCacheInputs,\n                    in -> {\n                        List<ForkJoinTask<Void>> mergeTasks = new ArrayList<ForkJoinTask<Void>>();\n                        mergeTasks.addAll(\n                                handleLegacyAndMonoDex(\n                                        Arrays.asList(mergeDexs), output, outPutFolder, null));\n                        mergeTasks.forEach(voidForkJoinTask -> voidForkJoinTask.join());\n\n                        cacheHandler.handleMissActionResult(outPutFolder, in);\n                        if (output != null) {\n                            try {\n                                outputHandler.handleOutput(output);\n                            } catch (ProcessException e) {\n                                // ignore this one\n                            }\n                        }\n                    }\n\n            );\n\n            cacheHandler.handleQueryResult(result, outPutFolder, awbBundle.getName());\n\n\n\n            if (awbBundle.isMBundle){\n                org.apache.commons.io.FileUtils.moveFile(new File(outPutFolder, CLASSES_DEX),new File(mainDexOut,\"classes\"+atomicInteger.incrementAndGet()+\".dex\"));\n            }\n\n        } catch (Exception e) {\n            e.printStackTrace();\n\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tasks/transform/dex/DexMergeTransformCallable.java",
    "content": "package com.taobao.android.builder.tasks.transform.dex;\n\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.builder.dexing.DexArchiveMerger;\nimport com.android.builder.dexing.DexMergerTool;\nimport com.android.builder.dexing.DexingType;\nimport com.android.dx.command.dexer.DxContext;\nimport com.android.ide.common.process.ProcessOutput;\nimport com.android.tools.r8.AtlasD8Merger;\nimport com.android.tools.r8.CompilationMode;\nimport com.taobao.android.builder.hook.dex.AtlasDexArchiveMerger;\nimport com.taobao.android.builder.hook.dex.DexArchiveMergerHook;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport sun.security.krb5.internal.PAData;\n\nimport java.io.File;\nimport java.nio.file.Path;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ForkJoinPool;\n\n/**\n * DexMergeTransformCallable\n *\n * @author zhayu.ll\n * @date 18/4/3\n */\npublic class DexMergeTransformCallable implements Callable<Void>{\n    @NonNull\n    private final DexingType dexingType;\n    @NonNull private final ProcessOutput processOutput;\n    @NonNull private final File dexOutputDir;\n    @NonNull private final Iterable<Path> dexArchives;\n    @NonNull private final ForkJoinPool forkJoinPool;\n    @Nullable\n    private final Path mainDexList;\n    @NonNull private final DexMergerTool dexMerger;\n    private final int minSdkVersion;\n    private final boolean isDebuggable;\n\n    public DexMergeTransformCallable(\n            @NonNull DexingType dexingType,\n            @NonNull ProcessOutput processOutput,\n            @NonNull File dexOutputDir,\n            @NonNull Iterable<Path> dexArchives,\n            @Nullable Path mainDexList,\n            @NonNull ForkJoinPool forkJoinPool,\n            @NonNull DexMergerTool dexMerger,\n            int minSdkVersion,\n            boolean isDebuggable) {\n        this.dexingType = dexingType;\n        this.processOutput = processOutput;\n        this.dexOutputDir = dexOutputDir;\n        this.dexArchives = dexArchives;\n        this.mainDexList = mainDexList;\n        this.forkJoinPool = forkJoinPool;\n        this.dexMerger = dexMerger;\n        this.minSdkVersion = minSdkVersion;\n        this.isDebuggable = isDebuggable;\n    }\n\n    @Override\n    public Void call() throws Exception {\n        DexArchiveMerger merger;\n        switch (dexMerger) {\n            case DX:\n                DxContext dxContext =\n                        new DxContext(\n                                processOutput.getStandardOutput(), processOutput.getErrorOutput());\n                merger = DexArchiveMerger.createDxDexMerger(dxContext,forkJoinPool);\n                ReflectUtils.updateField(merger,\"mergingStrategy\",new AtlasDexArchiveMerger.AtlasDexRefMergingStrategy());\n//                merger = new DexArchiveMergerHook(dxContext,new AtlasDexArchiveMerger.AtlasDexRefMergingStrategy(),forkJoinPool);\n                break;\n            case D8:\n                int d8MinSdkVersion = minSdkVersion;\n                if (d8MinSdkVersion < 21 && dexingType == DexingType.NATIVE_MULTIDEX) {\n                    // D8 has baked-in logic that does not allow multiple dex files without\n                    // main dex list if min sdk < 21. When we deploy the app to a device with api\n                    // level 21+, we will promote legacy multidex to native multidex, but the min\n                    // sdk version will be less than 21, which will cause D8 failure as we do not\n                    // supply the main dex list. In order to prevent that, it is safe to set min\n                    // sdk version to 21.\n                    d8MinSdkVersion = 21;\n                }\n                merger = new AtlasD8Merger(\n                        processOutput.getErrorOutput(),\n                        d8MinSdkVersion,\n                        isDebuggable ? CompilationMode.DEBUG : CompilationMode.RELEASE);\n                break;\n            default:\n                throw new AssertionError(\"Unknown dex merger \" + dexMerger.name());\n        }\n\n        merger.mergeDexArchives(dexArchives, dexOutputDir.toPath(), mainDexList, dexingType);\n        return null;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/BuildHelper.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools;\n\nimport com.android.builder.core.AndroidBuilder;\nimport com.android.builder.signing.DefaultSigningConfig;\nimport com.android.builder.signing.SigningException;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.tools.zip.ZipUtils;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.Action;\nimport org.gradle.api.Project;\nimport org.gradle.process.ExecSpec;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.regex.Pattern;\n\nimport static com.android.sdklib.BuildToolInfo.PathId.ZIP_ALIGN;\n\n/**\n * Created by wuzhong on 16/6/22.\n */\npublic class BuildHelper {\n\n    public static File doSign(File apkFile, DefaultSigningConfig signConfig) throws IOException, SigningException {\n\n        if (null == signConfig) {\n            return apkFile;\n        }\n\n        File signFile = new File(apkFile.getParent(), apkFile.getName().replace(\".apk\", \"-signed.apk\"));\n\n        AtlasBuildContext.sBuilderAdapter.androidSigner.signFile(apkFile, signFile, signConfig);\n\n        return signFile;\n    }\n\n\n    public static File reSign(File apkFile, DefaultSigningConfig signConfig) throws IOException, SigningException {\n\n        String filePath = apkFile.getAbsolutePath();\n        File workDir = new File(apkFile.getParentFile(), \"_tmpsign\");\n        apkFile.renameTo(new File(workDir, apkFile.getName()));\n\n        File unsignedApk = new File(apkFile.getParentFile(), apkFile.getName() + \"_\");\n        Pattern pattern = Pattern.compile(\"META-INF\");\n        ZipUtils.removeZipEntry(apkFile, pattern, unsignedApk);\n\n        AtlasBuildContext.sBuilderAdapter.androidSigner.signFile(unsignedApk, apkFile, signConfig);\n\n        apkFile.renameTo(new File(filePath));\n        FileUtils.deleteDirectory(workDir);\n        return apkFile;\n    }\n\n\n    public static synchronized File doZipAlign(final AndroidBuilder androidBuilder, Project project, final File apkFile) {\n\n        final File zipalignedFile = new File(apkFile.getParent(), apkFile.getName().replace(\".apk\", \"-zipaligned.apk\"));\n\n        project.exec(new Action<ExecSpec>() {\n            @Override\n            public void execute(ExecSpec execSpec) {\n\n                String path = androidBuilder.getTargetInfo()\n                        .getBuildTools().getPath(ZIP_ALIGN);\n                execSpec.executable(new File(path));\n                execSpec.args(\"-f\", \"4\");\n                execSpec.args(apkFile);\n                execSpec.args(zipalignedFile);\n            }\n        });\n\n        return zipalignedFile;\n    }\n\n    public static void writeFileToApk(File destFile, File file, String path) throws IOException {\n        File outPutFile = new File(file.getParent(), \"temp.apk\");\n        ZipUtils.addFileToZipFile(file, outPutFile, destFile, path, true);\n        FileUtils.deleteQuietly(file);\n        FileUtils.moveFile(outPutFile, file);\n        FileUtils.deleteQuietly(destFile);\n    }\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/EnvHelper.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools;\n\n/**\n * Created by wuzhong on 16/8/11.\n */\npublic class EnvHelper {\n\n    public static String  getEnv(String key){\n        String val = System.getProperty(key);\n        if(null != val){\n            return val;\n        }\n        val = System.getenv(key);\n        if(null != val){\n            return val;\n        }\n        val = System.getProperty(\"MUPP_\"+key);\n        if(null != val){\n            return val;\n        }\n        val = System.getenv(\"MUPP_\"+key);\n        if(null != val){\n            return val;\n        }\n        return null;\n    }\n\n    public static String getEnv(String key, String defValue){\n        String val = System.getProperty(key);\n        if(null != val){\n            return val;\n        }\n        val = System.getenv(key);\n        if(null != val){\n            return val;\n        }\n        val = System.getProperty(\"MUPP_\"+key);\n        if(null != val){\n            return val;\n        }\n        val = System.getenv(\"MUPP_\"+key);\n        if(null != val){\n            return val;\n        }\n        return defValue;\n    }\n\n    public static int getEnv(String key, int defValue){\n        return Integer.valueOf(getEnv(key,String.valueOf(defValue)));\n    }\n\n    public static boolean getEnv(String key, boolean defValue){\n        return Boolean.valueOf(getEnv(key,String.valueOf(defValue)));\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/FileNameUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools;\n\nimport java.io.File;\nimport java.util.Set;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport com.android.builder.model.MavenCoordinates;\nimport com.google.common.collect.Sets;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport org.apache.commons.io.FilenameUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.jetbrains.annotations.NotNull;\n\nimport static com.android.SdkConstants.DOT_JAR;\n\n/**\n * Created by wuzhong on 2017/3/30.\n */\npublic class FileNameUtils {\n\n    private static Set<String> outFileNames = Sets.newHashSet();\n\n    private static AtomicInteger index = new AtomicInteger(0);\n\n    public static String getUniqueJarName(File inputFile) {\n\n        String jarFileName = inputFile.getName();\n\n        String newFileName = \"\";\n\n        if (jarFileName.equalsIgnoreCase(\"classes.jar\")) {\n\n            String inputPath = inputFile.getAbsolutePath();\n            String rootInputPath = \"\";\n\n            //Calculate the original jar path\n            while (true) {\n                rootInputPath = AtlasBuildContext.jarTraceMap.get(inputPath);\n                if (null == rootInputPath) {\n                    rootInputPath = inputPath;\n                    break;\n                }\n            }\n\n            if (StringUtils.isNotEmpty(rootInputPath)) {\n                MavenCoordinates mavenCoordinates = getMavenCoordinate(rootInputPath);\n                if (null != mavenCoordinates) {\n                    newFileName = mavenCoordinates.getArtifactId();\n                }\n            }\n\n        } else {\n            newFileName = jarFileName;\n        }\n\n        if (StringUtils.isEmpty(newFileName)) {\n            if (inputFile.getAbsolutePath().contains(\".android/build-cache/\")){\n                File androidManifest = new File(inputFile.getParentFile(),\"AndroidManifest.xml\");\n                if (!androidManifest.exists()){\n                    androidManifest = new File(inputFile.getParentFile().getParentFile(),\"AndroidManifest.xml\");\n                }\n                if (androidManifest.exists()){\n                    newFileName = ManifestFileUtils.getPackage(androidManifest).replace(\".\",\"\");\n                }else {\n                    System.err.println(\"input file \" + inputFile.getAbsolutePath() + \" is not found unque name !\");\n                    newFileName = \"nogav\";\n                }\n            }else {\n                newFileName = getNameByParent(inputFile);\n            }\n        }\n\n        String outFileName = newFileName;\n        if (newFileName.endsWith(DOT_JAR)) {\n            outFileName = outFileName.substring(0, outFileName.length() - DOT_JAR.length());\n        }\n\n        if (outFileNames.contains(outFileName)) {\n            outFileName = outFileName + \"-\" + index.incrementAndGet();\n        }\n        outFileNames.add(outFileName);\n\n        return outFileName;\n    }\n\n    @NotNull\n    private static String getNameByParent(File inputFile) {\n        return inputFile\n            .getParentFile()\n            .getParentFile()\n            .getParentFile()\n            .getName() +\n            \"-\" +\n            inputFile.getParentFile().getParentFile().getName() +\n            DOT_JAR;\n    }\n\n    public static String getUniqueFileName(String name, String type) {\n        String outFileName = name.replace(\".jar\",\"\") + \"_\" + type;\n        if (outFileNames.contains(outFileName)) {\n            outFileName = outFileName + index.incrementAndGet();\n        }\n        outFileNames.add(outFileName);\n        return outFileName;\n    }\n\n    private static MavenCoordinates getMavenCoordinate(String path) {\n        File file = new File(path);\n        File parentDir = file.getParentFile();\n        //Look for level 3\n        for (int i = 0; i < 3; i++) {\n            MavenCoordinates mavenCoordinates = AtlasBuildContext.dependencyTraceMap.get(parentDir.getAbsolutePath());\n            if (null != mavenCoordinates) {\n                return mavenCoordinates;\n            }\n            parentDir = parentDir.getParentFile();\n        }\n\n        return null;\n    }\n\n    public static String getJarVersionName(Class clazz) {\n        String name = FilenameUtils.getBaseName(clazz.getProtectionDomain().getCodeSource().getLocation().getFile());\n        int index = name.indexOf(\"-\");\n        if (index == -1) {\n            return \"\";\n        }\n        return name.substring(index + 1);\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/JarUtils.java",
    "content": "package com.taobao.android.builder.tools;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.IOUtils;\n\nimport java.io.*;\nimport java.util.Enumeration;\nimport java.util.List;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\nimport java.util.jar.JarOutputStream;\nimport java.util.zip.ZipEntry;\n\n/**\n * JarUtils\n *\n * @author zhayu.ll\n * @date 18/9/1\n */\npublic class JarUtils {\n\n\n    public static void splitMainJar(List<File> result, File outJar, int index,int maxClassesSize) throws IOException {\n        boolean hasClass = false;\n        File splitOutJar = new File(outJar.getParentFile(), FileNameUtils.getUniqueJarName(outJar) + \"-\" + (index + 1) + \".jar\");\n        File splitOutJarMain = new File(outJar.getParentFile(), FileNameUtils.getUniqueJarName(outJar) + \"-\" + (index) + \".jar\");\n        JarOutputStream jos = new JarOutputStream(\n                new BufferedOutputStream(new FileOutputStream(splitOutJar)));\n        JarOutputStream josMain = new JarOutputStream(\n                new BufferedOutputStream(new FileOutputStream(splitOutJarMain)));\n        JarFile jarFile = new JarFile(outJar);\n        try {\n\n            Enumeration<JarEntry> entryEnumeration = jarFile.entries();\n            int i = 0;\n            while (entryEnumeration.hasMoreElements()) {\n                JarEntry jarEntry = entryEnumeration.nextElement();\n                if (jarEntry.getName().endsWith(\".class\")) {\n                    i++;\n                }\n                if (i > maxClassesSize) {\n                    hasClass = true;\n                    copyStream(jarFile.getInputStream(jarEntry), jos, jarEntry, jarEntry.getName());\n                } else {\n                    copyStream(jarFile.getInputStream(jarEntry), josMain, jarEntry, jarEntry.getName());\n                }\n            }\n            IOUtils.closeQuietly(jos);\n            IOUtils.closeQuietly(josMain);\n            jarFile.close();\n            if (!hasClass) {\n                FileUtils.deleteQuietly(splitOutJar);\n                return;\n            } else {\n                FileUtils.deleteQuietly(outJar);\n                result.remove(outJar);\n                result.add(splitOutJar);\n                result.add(splitOutJarMain);\n            }\n            splitMainJar(result, splitOutJar, index + 1,maxClassesSize);\n        }catch (Exception e){\n\n        }finally {\n\n        }\n\n    }\n\n    private static void copyStream(InputStream inputStream, JarOutputStream jos, JarEntry ze, String pathName) {\n        try {\n\n            ZipEntry newEntry = new ZipEntry(pathName);\n            // Make sure there is date and time set.\n            if (ze.getTime() != -1) {\n                newEntry.setTime(ze.getTime());\n                newEntry.setCrc(ze.getCrc()); // If found set it into output file.\n            }\n            jos.putNextEntry(newEntry);\n            IOUtils.copy(inputStream, jos);\n            IOUtils.closeQuietly(inputStream);\n        } catch (Exception e) {\n            e.printStackTrace();\n            //throw new GradleException(\"copy stream exception\", e);\n            //e.printStackTrace();\n//            logger.error(\"copy stream exception >>> \" + pathName + \" >>>\" + e.getMessage());\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/MD5Util.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools;\n\nimport java.io.File;\nimport java.io.FileFilter;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * Created by shenghua.nish on 2015-04-13 \"In the afternoon.\n */\npublic class MD5Util {\n    /**\n     * The default password string combination, which is used by apache to verify the file's correctness, is the default combination\n     */\n    private final static String[] hexDigits = {\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"a\", \"b\", \"c\", \"d\",\n            \"e\", \"f\"};\n    protected static MessageDigest messagedigest = null;\n\n    static {\n        try {\n            messagedigest = MessageDigest.getInstance(\"MD5\");\n        } catch (NoSuchAlgorithmException nsaex) {\n            nsaex.printStackTrace();\n        }\n    }\n\n    /**\n     * The getMD5 method is passed to the original string that you need to convert, and will return the MD5 code of the string\n     *\n     * @param code Original string\n     * @return Returns the MD5 code of the string\n     */\n    public static String getMD5(String origincode) throws Exception {\n        MessageDigest messageDigest = MessageDigest.getInstance(\"MD5\");\n        byte[] bytes = origincode.getBytes();\n        byte[] results = messageDigest.digest(bytes);\n        StringBuilder stringBuilder = new StringBuilder();\n\n        for (byte result : results) {\n            // Convert the byte array into a hexadecimal character into the stringbuilder\n            stringBuilder.append(String.format(\"%02x\", result));\n        }\n\n        return stringBuilder.toString();\n    }\n\n    /**\n     * Get MD5 of one file:hex string\n     *\n     * @param file\n     * @return\n     */\n    public static String getFileMD5(File file) {\n        if (!file.exists() || !file.isFile()) {\n            return null;\n        }\n        MessageDigest digest = null;\n        FileInputStream in = null;\n        byte buffer[] = new byte[1024];\n        int len;\n        String md5 = \"\";\n        try {\n            digest = MessageDigest.getInstance(\"MD5\");\n            in = new FileInputStream(file);\n            while ((len = in.read(buffer, 0, 1024)) != -1) {\n                digest.update(buffer, 0, len);\n            }\n            in.close();\n            md5 = byteArrayToHexString(digest.digest());\n        } catch (Exception e) {\n            e.printStackTrace();\n            return null;\n        }\n\n        return md5;\n    }\n\n\n    /***\n     * Get MD5 of one file! The test ok!\n     *\n     * @param filepath\n     * @return\n     */\n    public static String getFileMD5(String filepath) {\n        File file = new File(filepath);\n        return getFileMD5(file);\n    }\n\n\n    public static String getFileMD5String(File file) throws IOException {\n        return getFileMD5(file);\n    }\n\n    /**\n     * Rotations byte array is hexadecimal string\n     *\n     * @param b An array of bytes\n     * @return Hexadecimal string\n     */\n    private static String byteArrayToHexString(byte[] b) {\n        StringBuffer resultSb = new StringBuffer();\n        for (int i = 0; i < b.length; i++) {\n            resultSb.append(byteToHexString(b[i]));\n        }\n        return resultSb.toString();\n    }\n\n    // Converts a byte into a hexadecimal form string\n    private static String byteToHexString(byte b) {\n        int n = b;\n        if (n < 0)\n            n = 256 + n;\n        int d1 = n / 16;\n        int d2 = n % 16;\n        return hexDigits[d1] + hexDigits[d2];\n    }\n\n    public static String getFileMd5(Collection<File> inputFiles) {\n\n        StringBuilder stringBuilder = new StringBuilder();\n\n        FileFilter fileFilter = new FileFilter() {\n            @Override\n            public boolean accept(File pathname) {\n                return pathname.isFile();\n            }\n        };\n\n\n        for (File file : inputFiles) {\n            if (null == file || !file.exists()) {\n                continue;\n            }\n            if (file.isFile()) {\n                stringBuilder.append(MD5Util.getFileMD5(file));\n            } else {\n                List<File> files = new ArrayList<File>();\n                listFilesForFolder(file, files);\n                for (File file1 : files) {\n                    stringBuilder.append(MD5Util.getFileMD5(file1));\n                }\n            }\n\n        }\n\n        try {\n            return MD5Util.getMD5(stringBuilder.toString());\n        } catch (Exception e) {\n            e.printStackTrace();\n            return \"\";\n        }\n\n\n    }\n\n    private static void listFilesForFolder(final File folder, List<File> fileList) {\n        for (final File fileEntry : folder.listFiles()) {\n            if (fileEntry.isDirectory()) {\n                listFilesForFolder(fileEntry,fileList);\n            } else {\n                fileList.add(fileEntry);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/OSUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\npackage com.taobao.android.builder.tools;\n\n/**\n * Determine the utility class for the operating system\n * @author shenghua.nish 2014-6-22 On the morning of 9:19:07\n */\npublic class OSUtils {\n    private static String OS = System.getProperty(\"os.name\").toLowerCase();  \n      \n    public static boolean isLinux(){  \n        return OS.indexOf(\"linux\")>=0;  \n    }  \n      \n    public static boolean isMacOS(){  \n        return OS.indexOf(\"mac\")>=0&&OS.indexOf(\"os\")>0&&OS.indexOf(\"x\")<0;  \n    }  \n      \n    public static boolean isMacOSX(){  \n        return OS.indexOf(\"mac\")>=0&&OS.indexOf(\"os\")>0&&OS.indexOf(\"x\")>0;  \n    }  \n      \n    public static boolean isWindows(){  \n        return OS.indexOf(\"windows\")>=0;  \n    }  \n      \n    \n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/PathUtil.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\npackage com.taobao.android.builder.tools;\n\nimport java.io.File;\n\n/**\n * The tool class of the path \n * @author shenghua.nish 2012-6-20 On the afternoon of 1:16:01\n */\npublic class PathUtil {\n\n    /**\n     * Gets the file object of the current Jar file\n     * @return\n     */\n    public static File getCurrentJarFile(){\n       return getJarFile(PathUtil.class);\n    }\n    /**\n     * Get the folder where the jar is located\n     * @param klazz\n     * @return\n     */\n    public static File getJarFile(Class<?> klazz){\n        String path = klazz.getProtectionDomain().getCodeSource().getLocation().getFile();\n        File jarFile = new File(path);\n       return jarFile;\n    }\n\n    public static String toRelative(File basedir, String absolutePath) {\n        absolutePath = absolutePath.replace('\\\\', '/');\n        String basedirPath = basedir.getAbsolutePath().replace('\\\\', '/');\n        String relative;\n        if(absolutePath.startsWith(basedirPath)) {\n            relative = absolutePath.substring(basedirPath.length());\n            if(relative.startsWith(\"/\")) {\n                relative = relative.substring(1);\n            }\n\n            if(relative.length() <= 0) {\n                relative = \".\";\n            }\n        } else {\n            relative = absolutePath;\n        }\n\n        return relative;\n    }\n   \n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/PluginTypeUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools;\n\nimport com.android.build.gradle.AppPlugin;\nimport com.android.build.gradle.FeaturePlugin;\nimport com.android.build.gradle.LibraryPlugin;\nimport org.gradle.api.Project;\n\n/**\n * Created by shenghua.nish on 2016-05-17 But in the afternoon.\n */\npublic class PluginTypeUtils {\n\n    private static final String[] ANDROID_SUPPORT_PLUGINS = new String[] {\"com.taobao.android.application\",\n        \"com.android.application\",\n        \"com.taobao.android.library\",\n        \"com.android.library\",\n        \"com.taobao.atlas.library\",\n        \"com.taobao.atlas.application\"};\n    private static final String[] APP_SUPPORT_PLUGINS = new String[] {\"com.taobao.android.application\",\n        \"com.taobao.atlas.application\", \"com.android.application\"};\n    private static final String[] LIBRARY_SUPPORT_PLUGINS = new String[] {\"com.taobao.android.library\",\n        \"com.android.library\", \"com.taobao.atlas.library\"};\n    private static final String[] MTL_ANDROID_PLUGINS = new String[] {\"com.taobao.android.application\",\n        \"com.taobao.android.library\", \"com.taobao.atlas.library\", \"com.taobao.atlas.application\"};\n    private static final String[] GOOGLE_ANDROID_PLUGINS = new String[] {\"com.android.application\",\n        \"com.android.library\",\"com.android.feature\",\"com.android.instantapp\"};\n\n    private static final String[] FEATURE_ANDROID_PLUGINS = new String[] {\"com.android.feature\",\n            \"com.taobao.atlas.feature\"};\n\n    private static final String[] INSTANTAPP_ANDROID_PLUGINS = new String[] {\"com.android.instantapp\",\n            \"com.taobao.atlas.instantapp\"};\n\n    /**\n     * To determine whether Android is a project, use the Android gradle plugin as the basis\n     *\n     * @param project\n     * @return\n     */\n    public static boolean isAndroidProject(Project project) {\n        return hasPlugins(project, ANDROID_SUPPORT_PLUGINS);\n    }\n\n    /**\n     * Decide if it's a Library project\n     *\n     * @param project\n     * @return\n     */\n    public static boolean isLibraryProject(Project project) {\n        return hasPlugins(project, LIBRARY_SUPPORT_PLUGINS);\n    }\n    public static boolean isFeatureProject(Project project) {\n        return hasPlugins(project, FEATURE_ANDROID_PLUGINS);\n    }\n\n    public static boolean isInstantAppProject(Project project) {\n        return hasPlugins(project, INSTANTAPP_ANDROID_PLUGINS);\n    }\n    /**\n     * Determine whether it is an APP project\n     *\n     * @param project\n     * @return\n     */\n    public static boolean isAppProject(Project project) {\n        return hasPlugins(project, APP_SUPPORT_PLUGINS);\n    }\n\n    /**\n     * Decide if you are using taobao's androidPlugin\n     *\n     * @param project\n     * @return\n     */\n    public static boolean usedMtlPlugin(Project project) {\n        return hasPlugins(project, MTL_ANDROID_PLUGINS);\n    }\n\n    /**\n     * Decide if you're using GuGe's androidPlugin\n     *\n     * @param project\n     * @return\n     */\n    public static boolean usedGooglePlugin(Project project) {\n        return hasPlugins(project, GOOGLE_ANDROID_PLUGINS) || project.getPlugins().hasPlugin(AppPlugin.class)\n            || project.getPlugins().hasPlugin(LibraryPlugin.class)||project.getPlugins().hasPlugin(FeaturePlugin.class);\n\n    }\n\n    public static boolean hasApplyGooglePlugin(Project project) {\n        return hasPlugins(project, GOOGLE_ANDROID_PLUGINS);\n    }\n\n    private static boolean hasPlugins(Project project, String... plugins) {\n        for (String plugin : plugins) {\n            if (project.getPlugins().hasPlugin(plugin)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/Profiler.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\n//\n// Source code recreated from a .class file by IntelliJ IDEA\n// (powered by Fernflower decompiler)\n//\n\npackage com.taobao.android.builder.tools;\n\nimport java.text.MessageFormat;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\nimport org.apache.commons.lang.ObjectUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic final class Profiler {\n\n    public static Logger sLogger = LoggerFactory.getLogger(Profiler.class);\n\n    private static final ThreadLocal entryStack = new ThreadLocal();\n\n    public Profiler() {\n    }\n\n    public static void start() {\n        start((String)null);\n    }\n\n    public static void start(String message) {\n        entryStack.set(new Profiler.Entry(message, (Profiler.Entry)null, (Profiler.Entry)null));\n    }\n\n    public static void start(Profiler.Message message) {\n        entryStack.set(new Profiler.Entry(message, (Profiler.Entry)null, (Profiler.Entry)null));\n    }\n\n    public static void reset() {\n        entryStack.set((Object)null);\n    }\n\n    public static void enter(String message) {\n        Profiler.Entry currentEntry = getCurrentEntry();\n        if (currentEntry != null) {\n            currentEntry.enterSubEntry(message);\n        }\n\n    }\n\n    public static void enter(Profiler.Message message) {\n        Profiler.Entry currentEntry = getCurrentEntry();\n        if (currentEntry != null) {\n            currentEntry.enterSubEntry(message);\n        }\n\n    }\n\n    public static void release() {\n        Profiler.Entry currentEntry = getCurrentEntry();\n        if (currentEntry != null) {\n            currentEntry.release();\n        }\n\n    }\n\n    public static long getDuration() {\n        Profiler.Entry entry = (Profiler.Entry)entryStack.get();\n        return entry != null ? entry.getDuration() : -1L;\n    }\n\n    public static String dump() {\n        return dump(\"\", \"\");\n    }\n\n    public static String dump(String prefix) {\n        return dump(prefix, prefix);\n    }\n\n    public static String dump(String prefix1, String prefix2) {\n        Profiler.Entry entry = (Profiler.Entry)entryStack.get();\n        return entry != null ? entry.toString(prefix1, prefix2) : \"\";\n    }\n\n    public static Profiler.Entry getEntry() {\n        return (Profiler.Entry)entryStack.get();\n    }\n\n    private static Profiler.Entry getCurrentEntry() {\n        Profiler.Entry subEntry = (Profiler.Entry)entryStack.get();\n        Profiler.Entry entry = null;\n        if (subEntry != null) {\n            do {\n                entry = subEntry;\n                subEntry = subEntry.getUnreleasedEntry();\n            } while (subEntry != null);\n        }\n\n        return entry;\n    }\n\n    public interface Message {\n\n        String getBriefMessage();\n\n        String getDetailedMessage();\n    }\n\n    public static final class Entry {\n        private final List subEntries;\n        private final Object message;\n        private final Profiler.Entry parentEntry;\n        private final Profiler.Entry firstEntry;\n        private final long baseTime;\n        private final long startTime;\n        private long endTime;\n\n        private Entry(Object message, Profiler.Entry parentEntry, Profiler.Entry firstEntry) {\n            this.subEntries = new ArrayList(4);\n            this.message = message;\n            this.startTime = System.currentTimeMillis();\n            this.parentEntry = parentEntry;\n            this.firstEntry = (Profiler.Entry)ObjectUtils.defaultIfNull(firstEntry, this);\n            this.baseTime = firstEntry == null ? 0L : firstEntry.startTime;\n        }\n\n        public String getMessage() {\n            String messageString = null;\n            if (this.message instanceof String) {\n                messageString = (String)this.message;\n            } else if (this.message instanceof Profiler.Message) {\n                Profiler.Message messageObject = (Profiler.Message)this.message;\n\n                messageString = messageObject.getDetailedMessage();\n\n            }\n\n            return StringUtils.defaultIfEmpty(messageString, (String)null);\n        }\n\n        public long getStartTime() {\n            return this.baseTime > 0L ? this.startTime - this.baseTime : 0L;\n        }\n\n        public long getEndTime() {\n            return this.endTime < this.baseTime ? -1L : this.endTime - this.baseTime;\n        }\n\n        public long getDuration() {\n            return this.endTime < this.startTime ? -1L : this.endTime - this.startTime;\n        }\n\n        public long getDurationOfSelf() {\n            long duration = this.getDuration();\n            if (duration < 0L) {\n                return -1L;\n            } else if (this.subEntries.isEmpty()) {\n                return duration;\n            } else {\n                for (int i = 0; i < this.subEntries.size(); ++i) {\n                    Profiler.Entry subEntry = (Profiler.Entry)this.subEntries.get(i);\n                    duration -= subEntry.getDuration();\n                }\n\n                return duration < 0L ? -1L : duration;\n            }\n        }\n\n        public double getPecentage() {\n            double parentDuration = 0.0D;\n            double duration = (double)this.getDuration();\n            if (this.parentEntry != null && this.parentEntry.isReleased()) {\n                parentDuration = (double)this.parentEntry.getDuration();\n            }\n\n            return duration > 0.0D && parentDuration > 0.0D ? duration / parentDuration : 0.0D;\n        }\n\n        public double getPecentageOfAll() {\n            double firstDuration = 0.0D;\n            double duration = (double)this.getDuration();\n            if (this.firstEntry != null && this.firstEntry.isReleased()) {\n                firstDuration = (double)this.firstEntry.getDuration();\n            }\n\n            return duration > 0.0D && firstDuration > 0.0D ? duration / firstDuration : 0.0D;\n        }\n\n        public List getSubEntries() {\n            return Collections.unmodifiableList(this.subEntries);\n        }\n\n        private void release() {\n            this.endTime = System.currentTimeMillis();\n        }\n\n        private boolean isReleased() {\n            return this.endTime > 0L;\n        }\n\n        private void enterSubEntry(Object message) {\n            Profiler.Entry subEntry = new Profiler.Entry(message, this, this.firstEntry);\n            this.subEntries.add(subEntry);\n        }\n\n        private Profiler.Entry getUnreleasedEntry() {\n            Profiler.Entry subEntry = null;\n            if (!this.subEntries.isEmpty()) {\n                subEntry = (Profiler.Entry)this.subEntries.get(this.subEntries.size() - 1);\n                if (subEntry.isReleased()) {\n                    subEntry = null;\n                }\n            }\n\n            return subEntry;\n        }\n\n        @Override\n        public String toString() {\n            return this.toString(\"\", \"\");\n        }\n\n        private String toString(String prefix1, String prefix2) {\n            StringBuffer buffer = new StringBuffer();\n            this.toString(buffer, prefix1, prefix2);\n            return buffer.toString();\n        }\n\n        private void toString(StringBuffer buffer, String prefix1, String prefix2) {\n            buffer.append(prefix1);\n            String message = this.getMessage();\n            long startTime = this.getStartTime();\n            long duration = this.getDuration();\n            long durationOfSelf = this.getDurationOfSelf();\n            double percent = this.getPecentage();\n            double percentOfAll = this.getPecentageOfAll();\n            Object[] params = new Object[] {message, new Long(startTime), new Long(duration), new Long(durationOfSelf),\n                new Double(percent), new Double(percentOfAll)};\n            StringBuffer pattern = new StringBuffer(\"{1,number} \");\n            if (this.isReleased()) {\n                pattern.append(\"[{2,number}ms\");\n                if (durationOfSelf > 0L && durationOfSelf != duration) {\n                    pattern.append(\" ({3,number}ms)\");\n                }\n\n                if (percent > 0.0D) {\n                    pattern.append(\", {4,number,##%}\");\n                }\n\n                if (percentOfAll > 0.0D) {\n                    pattern.append(\", {5,number,##%}\");\n                }\n\n                pattern.append(\"]\");\n            } else {\n                pattern.append(\"[UNRELEASED]\");\n            }\n\n            if (message != null) {\n                pattern.append(\" - {0}\");\n            }\n\n            buffer.append(MessageFormat.format(pattern.toString(), params));\n\n            for (int i = 0; i < this.subEntries.size(); ++i) {\n                Profiler.Entry subEntry = (Profiler.Entry)this.subEntries.get(i);\n                buffer.append('\\n');\n                if (i == this.subEntries.size() - 1) {\n                    subEntry.toString(buffer, prefix2 + \"`---\", prefix2 + \"    \");\n                } else if (i == 0) {\n                    subEntry.toString(buffer, prefix2 + \"+---\", prefix2 + \"|   \");\n                } else {\n                    subEntry.toString(buffer, prefix2 + \"+---\", prefix2 + \"|   \");\n                }\n            }\n\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/ReflectUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools;\n\nimport java.lang.reflect.Field;\n\n/**\n * Created by wuzhong on 2017/3/7.\n *\n * @author wuzhong\n * @date 2017/03/07\n */\npublic class ReflectUtils {\n\n    public static Object getField(Object obj, String fieldName) {\n        Class<?>clazz = obj.getClass();\n        while (clazz!=Object.class){\n            try {\n                Field field = clazz.getDeclaredField(fieldName);\n                field.setAccessible(true);\n                return field.get(obj);\n            }catch (Exception e){\n                clazz = clazz.getSuperclass();\n            }\n\n\n        }\n\n        return null;\n    }\n\n    public static Object getField(Class clazz,  Object obj, String fieldName) {\n        while (clazz!=Object.class){\n            try {\n                Field field = clazz.getDeclaredField(fieldName);\n                field.setAccessible(true);\n                return field.get(obj);\n            }catch (Exception e){\n                clazz = clazz.getSuperclass();\n            }\n\n\n        }\n\n        return null;\n    }\n\n    public static void updateField(Object obj, String fieldName, Object value) {\n        for(Class<?> clazz = obj.getClass() ; clazz != Object.class ; clazz = clazz.getSuperclass()) {\n            try {\n                Field field = clazz.getDeclaredField(fieldName);\n                field.setAccessible(true);\n                field.set(obj,value);\n                return;\n                }\n                catch (Exception e) {\n\n            }\n        }\n    }\n\n    public static void updateField(Class clazz,\n                                   Object obj,\n                                   String fieldName,\n                                   Object value) throws Exception {\n        Field t = clazz.getDeclaredField(fieldName);\n        t.setAccessible(true);\n        t.set(obj, value);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/TransformInputUtils.java",
    "content": "package com.taobao.android.builder.tools;\n\nimport com.android.build.api.transform.DirectoryInput;\nimport com.android.build.api.transform.JarInput;\nimport com.android.build.api.transform.QualifiedContent;\nimport com.android.build.api.transform.Status;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.ImmutableSet;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.tasks.app.BuildAtlasEnvTask;\n\nimport java.io.File;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * TransformInputUtils\n *\n * @author zhayu.ll\n * @date 18/10/18\n */\npublic class TransformInputUtils {\n\n    public static DirectoryInput makeDirectoryInput(File file, AppVariantContext variantContext) {\n        return new DirectoryInput() {\n            @Override\n            public Map<File, Status> getChangedFiles() {\n                return ImmutableMap.of(file, Status.CHANGED);\n            }\n\n            @Override\n            public String getName() {\n                return \"folder\";\n            }\n\n            @Override\n            public File getFile() {\n                return file;\n            }\n\n            @Override\n            public Set<QualifiedContent.ContentType> getContentTypes() {\n                return ImmutableSet.of(QualifiedContent.DefaultContentType.CLASSES);\n            }\n\n            @Override\n            public Set<? super QualifiedContent.Scope> getScopes() {\n                return ImmutableSet.of(Scope.EXTERNAL_LIBRARIES);\n            }\n        };\n\n    }\n\n\n    public static JarInput makeJarInput(File file,AppVariantContext variantContext) {\n        BuildAtlasEnvTask.FileIdentity finalFileIdentity = AtlasBuildContext.atlasMainDexHelperMap.get(variantContext.getVariantName()).get(file);\n        return new JarInput() {\n            @Override\n            public Status getStatus() {\n                return Status.ADDED;\n            }\n\n            @Override\n            public String getName() {\n\n                return MD5Util.getFileMD5(file);\n            }\n\n            @Override\n            public File getFile() {\n                return file;\n            }\n\n            @Override\n            public Set<QualifiedContent.ContentType> getContentTypes() {\n                return ImmutableSet.of(QualifiedContent.DefaultContentType.CLASSES);\n            }\n\n            @Override\n            public Set<? super QualifiedContent.Scope> getScopes() {\n                if (finalFileIdentity == null){\n                    return  ImmutableSet.of(Scope.EXTERNAL_LIBRARIES);\n                }\n                if (finalFileIdentity.subProject) {\n                    return ImmutableSet.of(Scope.SUB_PROJECTS);\n                } else {\n                    return ImmutableSet.of(Scope.EXTERNAL_LIBRARIES);\n                }\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/VersionUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools;\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport org.dom4j.DocumentException;\n\nimport java.io.File;\nimport java.io.IOException;\n\n/**\n * Created by wuzhong on 16/7/6.\n */\npublic class VersionUtils {\n\n    public static String getVersionName(BaseVariantOutput baseVariantOutput, File manifest) {\n\n        String versionName = null;\n\n        if (baseVariantOutput != null) {\n            versionName = ApkDataUtils.get(baseVariantOutput).getVersionName();\n        }\n\n        if (null == versionName) {\n            try {\n                versionName = ManifestFileUtils.getVersionName(manifest);\n            } catch (IOException e) {\n                e.printStackTrace();\n            } catch (DocumentException e) {\n                e.printStackTrace();\n            }\n        }\n        return versionName;\n    }\n\n    public static int getVersionCode(AppVariantOutputContext appVariantOutputContext) {\n\n//        try {\n////            return appVariantOutputContext.getApk;\n//        } catch (Throwable e) {\n            return appVariantOutputContext.getVariantData().getVariantConfiguration().getVersionCode();\n//        }\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/asm/ClassNameRenamer.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.asm;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Set;\n\nimport org.apache.commons.io.IOUtils;\nimport org.objectweb.asm.ClassReader;\nimport org.objectweb.asm.ClassVisitor;\nimport org.objectweb.asm.ClassWriter;\nimport org.objectweb.asm.MethodVisitor;\nimport org.objectweb.asm.Opcodes;\n\n/**\n * Created by wuzhong on 2017/3/30.\n */\npublic class ClassNameRenamer {\n\n    public static void rewriteDataBinderMapper(File dir, String fromName, String toName,\n                                               File Clazz) throws IOException {\n        FileInputStream fileInputStream = new FileInputStream(Clazz);\n        ClassReader in1 = new ClassReader(fileInputStream);\n        ClassWriter cw = new ClassWriter(0);\n\n        Set<String> renames = new HashSet<String>();\n        renames.add(fromName);\n        in1.accept(new ClassRenamer(cw, renames, toName), 8);\n\n        File destClass = new File(dir, toName + \".class\");\n        destClass.getParentFile().mkdirs();\n        FileOutputStream fileOutputStream = new FileOutputStream(destClass);\n        fileOutputStream.write(cw.toByteArray());\n        IOUtils.closeQuietly(fileOutputStream);\n        IOUtils.closeQuietly(fileInputStream);\n\n    }\n\n    static class ClassRenamer extends ClassVisitor implements Opcodes {\n\n        private Set oldNames;\n        private final String newName;\n\n        public ClassRenamer(ClassVisitor cv, Set oldNames, String newName) {\n            super(ASM4, cv);\n            this.oldNames = oldNames;\n            this.newName = newName;\n        }\n\n        @Override\n        public void visit(int version, int access, String name, String signature, String superName,\n                          String[] interfaces) {\n            oldNames.add(name);\n            cv.visit(version, ACC_PUBLIC, newName, signature, superName, interfaces);\n        }\n\n        @Override\n        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {\n            MethodVisitor mv = cv.visitMethod(access, name, desc, fix(signature), exceptions);\n            if (mv != null && (access & ACC_ABSTRACT) == 0) {\n                mv = new ClassRenamer.MethodRenamer(mv);\n            }\n            return mv;\n        }\n\n        class MethodRenamer extends MethodVisitor {\n\n            public MethodRenamer(final MethodVisitor mv) {\n                super(ASM4, mv);\n            }\n\n            @Override\n            public void visitTypeInsn(int i, String s) {\n                if (oldNames.contains(s)) {\n                    s = newName;\n                }\n                mv.visitTypeInsn(i, s);\n            }\n\n            @Override\n            public void visitFieldInsn(int opcode, String owner, String name, String desc) {\n                if (oldNames.contains(owner)) {\n                    mv.visitFieldInsn(opcode, newName, name, fix(desc));\n                } else {\n                    mv.visitFieldInsn(opcode, owner, name, fix(desc));\n                }\n            }\n\n            @Override\n            public void visitMethodInsn(int opcode, String owner, String name, String desc) {\n                if (oldNames.contains(owner)) {\n                    mv.visitMethodInsn(opcode, newName, name, fix(desc));\n                } else {\n                    mv.visitMethodInsn(opcode, owner, name, fix(desc));\n                }\n            }\n        }\n\n        private String fix(String s) {\n            if (s != null) {\n                Iterator it = oldNames.iterator();\n                String name;\n                while (it.hasNext()) {\n                    name = (String)it.next();\n                    if (s.indexOf(name) != -1) {\n                        s = s.replaceAll(name, newName);\n                    }\n                }\n            }\n            return s;\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/asm/ClazzBasicHandler.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.asm;\n\nimport org.apache.commons.io.IOUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.*;\nimport java.util.Enumeration;\nimport java.util.Map;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\nimport java.util.jar.JarOutputStream;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipOutputStream;\n\n/**\n * Created by wuzhong on 2016/12/13.\n */\npublic abstract class ClazzBasicHandler {\n\n    public static Logger logger = LoggerFactory.getLogger(ClazzBasicHandler.class);\n\n\n    protected File jar;\n    protected File outJar;\n    protected Map<String, String> reMapping;\n\n    public ClazzBasicHandler(File jar, File outJar, Map<String, String> reMapping) {\n        this.jar = jar;\n        this.outJar = outJar;\n        this.reMapping = reMapping;\n    }\n\n    public void execute() throws IOException {\n\n        logger.info(\"[ClazzReplacer] rewriteJar from \" + jar.getAbsolutePath() + \" to \" + outJar.getAbsolutePath());\n\n        JarFile jarFile = new JarFile(jar);\n\n        JarOutputStream jos = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(outJar)));\n\n        Enumeration<JarEntry> jarFileEntries = jarFile.entries();\n\n        while (jarFileEntries.hasMoreElements()) {\n\n            JarEntry ze = jarFileEntries.nextElement();\n\n            String pathName = ze.getName();\n\n            logger.info(jar.getAbsolutePath() + \"->\" + pathName);\n\n            if (!pathName.endsWith(\".class\")) {\n                justCopy(jarFile, jos, ze, pathName);\n                continue;\n            }\n\n            handleClazz(jarFile, jos, ze, pathName);\n\n        }\n\n        jarFile.close();\n//        IOUtils.closeQuietly(fileOutputStream);\n        IOUtils.closeQuietly(jos);\n    }\n\n    protected void justCopy(JarFile jarFile, JarOutputStream jos, JarEntry ze, String pathName) {\n        try {\n            InputStream inputStream = jarFile.getInputStream(ze);\n            copyStreamToJar(inputStream, jos, pathName, ze.getTime());\n        } catch (Exception e) {\n            logger.error(\"justCopy exception\", e);\n        }\n    }\n\n\n    protected abstract void handleClazz(JarFile jarFile, JarOutputStream jos, JarEntry ze, String pathName);\n\n\n    protected void copyStreamToJar(InputStream zin, ZipOutputStream out, String currentName, long fileTime) throws IOException {\n        // Create new entry for zip file.\n\n        ZipEntry newEntry = new ZipEntry(currentName);\n        // Make sure there is date and time set.\n        if (fileTime != -1) {\n            newEntry.setTime(fileTime); // If found set it into output file.\n        }\n        out.putNextEntry(newEntry);\n        if (zin != null) {\n            IOUtils.copy(zin, out);\n        }\n        IOUtils.closeQuietly(zin);\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/asm/ClazzReplacer.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.asm;\n\nimport org.objectweb.asm.ClassReader;\nimport org.objectweb.asm.ClassWriter;\nimport org.objectweb.asm.commons.RemappingClassAdapter;\nimport org.objectweb.asm.commons.SimpleRemapper;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.File;\nimport java.io.InputStream;\nimport java.util.Map;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\nimport java.util.jar.JarOutputStream;\n\n/**\n * Created by wuzhong on 2016/12/13.\n */\npublic class ClazzReplacer extends ClazzBasicHandler {\n\n    public ClazzReplacer(File jar, File outJar, Map<String, String> reMapping) {\n        super(jar, outJar, reMapping);\n    }\n\n    @Override\n    protected void handleClazz(JarFile jarFile, JarOutputStream jos, JarEntry ze, String pathName) {\n\n        //            logger.log(pathName);\n        if (reMapping.containsKey(pathName.substring(0, pathName.length() - 6))) {\n            logger.info(\"[ClazzReplacer] remove class  \" + pathName + \" form \" + jarFile);\n            return;\n        }\n\n        try {\n            InputStream in = jarFile.getInputStream(ze);\n            ClassReader cr = new ClassReader(in);\n            ClassWriter cw = new ClassWriter(0);\n            RemappingClassAdapter remappingClassAdapter = new RemappingClassAdapter(cw, new SimpleRemapper(reMapping));\n            cr.accept(remappingClassAdapter, ClassReader.EXPAND_FRAMES);\n\n            InputStream inputStream = new ByteArrayInputStream(cw.toByteArray());\n            copyStreamToJar(inputStream, jos, pathName, ze.getTime());\n\n        } catch (Throwable e) {\n\n            System.err.println(\"[ClazzReplacer] rewrite error > \" + pathName);\n            justCopy(jarFile, jos, ze, pathName);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/asm/MethodReplacer.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.asm;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.File;\nimport java.io.InputStream;\nimport java.util.Map;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\nimport java.util.jar.JarOutputStream;\n\nimport com.taobao.android.builder.tools.asm.method.MethodReplaceClazzVisitor;\nimport com.taobao.android.builder.tools.asm.method.MethodStore;\nimport org.apache.commons.io.IOUtils;\nimport org.objectweb.asm.ClassReader;\nimport org.objectweb.asm.ClassWriter;\nimport org.objectweb.asm.Opcodes;\n\n/**\n * Created by wuzhong on 2016/12/13.\n */\npublic class MethodReplacer extends ClazzBasicHandler {\n\n    private MethodStore methodStore;\n\n    public MethodReplacer(File jar, File outJar, Map<String, String> reMapping) {\n        super(jar, outJar, reMapping);\n        this.methodStore = new MethodStore(reMapping);\n    }\n\n    @Override\n    protected void handleClazz(JarFile jarFile, JarOutputStream jos, JarEntry ze, String pathName) {\n\n        try {\n            InputStream jarFileInputStream = jarFile.getInputStream(ze);\n\n            ClassReader classReader = new ClassReader(jarFileInputStream);\n\n            ClassWriter classWriter = new ClassWriter(0);\n\n            StringBuilder stringBuilder = new StringBuilder();\n            stringBuilder.append(jar.getAbsolutePath()).append(\".\").append(pathName);\n\n            classReader.accept(new MethodReplaceClazzVisitor(Opcodes.ASM4, classWriter, methodStore, stringBuilder),\n                               ClassReader.EXPAND_FRAMES);\n\n            ByteArrayInputStream inputStream = new ByteArrayInputStream(classWriter.toByteArray());\n            copyStreamToJar(inputStream, jos, pathName, ze.getTime());\n            IOUtils.closeQuietly(inputStream);\n\n        } catch (Throwable e) {\n\n            System.err.println(\"[MethodReplacer] rewrite error > \" + pathName);\n            justCopy(jarFile, jos, ze, pathName);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/asm/field/AsmFieldEditor.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.asm.field;\n\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.util.List;\n\nimport org.objectweb.asm.ClassReader;\nimport org.objectweb.asm.ClassWriter;\nimport org.objectweb.asm.FieldVisitor;\nimport org.objectweb.asm.Opcodes;\nimport org.objectweb.asm.Type;\n\n/**\n * Created by wuzhong on 2017/4/27.\n */\npublic class AsmFieldEditor {\n\n    public static byte[] edit(FileInputStream fileInputStream, List<Field> fields) throws IOException {\n\n        ClassReader cr = new ClassReader(fileInputStream);\n        return rewriteBytes(fields, cr);\n\n    }\n\n\n    public static byte[] edit(String className, List<Field> fields) throws IOException {\n\n        ClassReader cr = new ClassReader(className);\n        return rewriteBytes(fields, cr);\n\n    }\n\n    private static byte[] rewriteBytes(List<Field> fields, ClassReader cr) {\n        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);\n        ModifyClassVisiter modifyClassVisiter = new ModifyClassVisiter(Opcodes.ASM5, cw);\n\n        for (Field field : fields) {\n            modifyClassVisiter.addRemoveField(field.name);\n        }\n        cr.accept(modifyClassVisiter, Opcodes.ASM5);\n\n        for (Field field : fields) {\n\n            FieldVisitor fv = cw.visitField(field.flag,\n                                            field.name,\n                                            Type.getDescriptor(field.value.getClass()),\n                                            null,\n                                            field.value);\n            fv.visitEnd();\n\n        }\n\n        return cw.toByteArray();\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/asm/field/Field.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.asm.field;\n\n/**\n * Created by wuzhong on 2017/4/27.\n */\npublic class Field {\n\n    public String name;\n    public int flag;\n    public Object value;\n\n    public Field(int flag, String name, Object value) {\n        this.name = name;\n        this.flag = flag;\n        this.value = value;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/asm/field/ModifyClassVisiter.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.asm.field;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\nimport org.objectweb.asm.ClassVisitor;\nimport org.objectweb.asm.FieldVisitor;\n\n/**\n * Created by wuzhong on 2017/4/27.\n */\npublic class ModifyClassVisiter extends ClassVisitor {\n\n    private Set<String> removeFields = new HashSet<>();\n\n    public ModifyClassVisiter(int api) {\n        super(api);\n    }\n\n    public ModifyClassVisiter(int api, ClassVisitor cv) {\n        super(api, cv);\n    }\n\n    @Override\n    public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {\n        if (removeFields.contains(name)) {\n            return null;\n        }\n        return super.visitField(access, name, desc, signature, value);\n    }\n\n    public void addRemoveField(String fieldName) {\n        this.removeFields.add(fieldName);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/asm/method/Method.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.asm.method;\n\n/**\n * Created by wuzhong on 2016/12/13.\n */\npublic class Method {\n\n    public String owner;\n    public String name;\n    public String desc;\n\n    @Override\n    public String toString() {\n        return \"Method{\" +\n                \"owner='\" + owner + '\\'' +\n                \", name='\" + name + '\\'' +\n                \", desc='\" + desc + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/asm/method/MethodReplaceClazzVisitor.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.asm.method;\n\nimport org.objectweb.asm.ClassVisitor;\nimport org.objectweb.asm.ClassWriter;\nimport org.objectweb.asm.MethodVisitor;\nimport org.objectweb.asm.Opcodes;\n\npublic final class MethodReplaceClazzVisitor extends ClassVisitor {\n\n    private MethodStore methodStore;\n    private StringBuilder stringBuilder;\n\n    public MethodReplaceClazzVisitor(int api, ClassWriter cw, MethodStore methodStore,StringBuilder stringBuilder ) {\n        super(api, cw);\n        this.methodStore = methodStore;\n        this.stringBuilder = stringBuilder;\n    }\n\n    @Override\n    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {\n        MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions);\n        return new MethodReplaceMethodVisitor(Opcodes.ASM4, methodVisitor, methodStore,stringBuilder);\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/asm/method/MethodReplaceMethodVisitor.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.asm.method;\n\nimport org.objectweb.asm.Handle;\nimport org.objectweb.asm.MethodVisitor;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic final class MethodReplaceMethodVisitor extends MethodVisitor {\n\n    private static Logger logger = LoggerFactory.getLogger(MethodReplaceMethodVisitor.class);\n\n    private MethodStore methodStore;\n    private StringBuilder stringBuilder;\n\n    public MethodReplaceMethodVisitor(int asm4, MethodVisitor methodVisitor, MethodStore methodStore,StringBuilder stringBuilder ) {\n        super(asm4, methodVisitor);\n        this.methodStore = methodStore;\n        this.stringBuilder = stringBuilder;\n    }\n\n\n    @Override\n    public void visitMethodInsn(\n            int opcode, String owner, String name, String desc, boolean itf) {\n\n        Method method = methodStore.findMethod(owner, name, desc);\n\n        if (null == method) {\n            super.visitMethodInsn(opcode, owner, name, desc, itf);\n            return;\n        }\n\n        stringBuilder.append(\">>\").append(owner).append(name).append(desc).append(\">>\").append(method);\n\n        logger.info(stringBuilder.toString());\n\n        super.visitMethodInsn(opcode, method.owner,\n                method.name, null == method.desc ? desc : method.desc, false);\n\n\n    }\n\n    @Override\n    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {\n        super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);\n    }\n\n    //visitInvokeDynamicInsn\n\n    @Override\n    public void visitParameter(String name, int access) {\n        super.visitParameter(name, access);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/asm/method/MethodStore.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.asm.method;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Created by wuzhong on 2016/12/13.\n */\npublic class MethodStore {\n\n    private Map<String, Method> methodMap = new HashMap<>();\n\n    public MethodStore(Map<String, String> map) {\n\n        for (String key : map.keySet()) {\n\n            String value = map.get(key);\n\n            String[] values = value.split(\"\\\\|\");\n\n            Method method = new Method();\n            method.owner = values[0];\n            method.name = values[1];\n            if (values.length == 3) {\n                method.desc = values[3];\n            }\n\n            methodMap.put(key, method);\n\n        }\n\n\n    }\n\n\n    public Method findMethod(String owner, String name, String desc) {\n\n        Method method = methodMap.get(owner + \"|\" + name);\n        if (null != method) {\n            return method;\n        }\n\n        return methodMap.get(owner + \"|\" + name + \"|\" + desc);\n\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/bundleinfo/ApkFileListUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.bundleinfo;\n\nimport java.io.BufferedInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.List;\n\nimport android.aapt.pb.internal.ResourcesInternal.CompiledFile;\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.internal.api.ApkFiles;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.google.common.base.Preconditions;\nimport com.google.protobuf.CodedInputStream;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tools.MD5Util;\nimport com.taobao.android.builder.tools.PathUtil;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.filefilter.IOFileFilter;\nimport org.apache.commons.io.filefilter.TrueFileFilter;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.UncheckedIOException;\nimport org.gradle.api.tasks.StopExecutionException;\n\n/**\n * Created by wuzhong on 16/6/15.\n */\npublic class ApkFileListUtils {\n\n    /**\n     * Records resource information for apk files\n     */\n    public static ApkFiles recordApkFileInfos(AppVariantContext appVariantContext) {\n\n        ApkFiles apkFiles = new ApkFiles();\n\n        List<File> mainBundleResFolders = new ArrayList<File>();\n        mainBundleResFolders.add(appVariantContext.getScope().getVariantData().mergeResourcesTask.getOutputDir());\n        prepareApkFileList(appVariantContext.getScope().getVariantData().mergeAssetsTask.getOutputDir(),\n                           \"assets\", apkFiles);\n        for (File resFolder : mainBundleResFolders) {\n            prepareApkFileList(resFolder, \"res\", apkFiles);\n        }\n\n        // Record the resource information for each bundle\n        AtlasDependencyTree dependencyTree = AtlasBuildContext.androidDependencyTrees.get(appVariantContext.getScope().\n            getVariantConfiguration().getFullName());\n        if (null == dependencyTree) {\n            throw new StopExecutionException(\"DependencyTree cannot be null!\");\n        }\n\n        List<AwbBundle> libs = dependencyTree.getAwbBundles();\n\n        for (AwbBundle awbLib : libs) {\n            File mergeAssertFolder = appVariantContext.getMergeAssets(awbLib);\n            File mergeResFolder = appVariantContext.getMergeResources(awbLib);\n            String awbName = awbLib.getName();\n            prepareApkFileList(mergeAssertFolder, \"assets\", awbName, apkFiles);\n            prepareApkFileList(mergeResFolder, \"res\", awbName, apkFiles);\n        }\n\n        return apkFiles;\n    }\n\n    /**\n     * Initializes the file list information for the apk file\n     *\n     * @return\n     */\n    protected static void prepareApkFileList(File folder, String prefixName, ApkFiles apkFiles) {\n        if (!folder.exists()) {\n            return;\n        }\n        // Gets information about the main bundle\n        Collection<File> files = FileUtils.listFiles(folder, new PureFileFilter(), TrueFileFilter.INSTANCE);\n        for (File file : files) {\n            if (file.isFile()) {\n                String relativePath = prefixName + File.separator + PathUtil.toRelative(folder, file.getAbsolutePath());\n                String md5;\n                if (\"res\".equals(prefixName)) {\n                    md5 = getResMd5(file);\n                } else {\n                    md5 = MD5Util.getFileMD5(file);\n                }\n                if (isImageFile(relativePath)) {\n                    apkFiles.apkFileList.put(relativePath, md5);\n                }\n                apkFiles.finalApkFileList.put(relativePath, md5);\n            }\n        }\n    }\n\n    private static String getResMd5(File file) {\n        String md5;\n//        if (isCompiledFile(file.getName())) {\n//            md5 = getCompiledFileMd5(file);\n//        } else {\n            md5 = MD5Util.getFileMD5(file);\n//        }\n        return md5;\n    }\n\n    private static String getCompiledFileMd5(File file) {\n        String md5;\n        try (InputStream is = new BufferedInputStream(new FileInputStream(file))) {\n            CodedInputStream codedInputStream = CodedInputStream.newInstance(is);\n            int numFiles = codedInputStream.readRawLittleEndian32();\n            // Preconditions.checkState(numFiles == 1, \"inline xml not implemented yet\");\n            long pbSize = codedInputStream.readRawLittleEndian64();\n            codedInputStream.pushLimit((int)pbSize);\n            CompiledFile compiledFile = CompiledFile.parser().parsePartialFrom(codedInputStream);\n            md5 = MD5Util.getFileMD5(compiledFile.getSourcePath());\n            // codedInputStream.popLimit((int)pbSize);\n            // codedInputStream.pushLimit(0);\n            return md5;\n        } catch (IOException e) {\n            throw new UncheckedIOException(e);\n        }\n    }\n\n    protected static void prepareApkFileList(File folder, String prefixName, String awbName, ApkFiles apkFiles) {\n        if (!folder.exists()) {\n            return;\n        }\n        // Gets information about the main bundle\n        Collection<File> files = FileUtils.listFiles(folder, new PureFileFilter(), TrueFileFilter.INSTANCE);\n        for (File file : files) {\n            if (file.isFile()) {\n                String relativePath = prefixName + File.separator + PathUtil.toRelative(folder, file.getAbsolutePath());\n                String md5 = MD5Util.getFileMD5(file);\n                if (isImageFile(relativePath)) {\n                    if (null == apkFiles.apkFileList.getAwbs().get(awbName)) {\n                        apkFiles.apkFileList.getAwbs().put(awbName, new HashMap<String, String>());\n                    }\n                    apkFiles.apkFileList.getAwbs().get(awbName).put(relativePath, md5);\n                }\n                if (null == apkFiles.finalApkFileList.getAwbs().get(awbName)) {\n                    apkFiles.finalApkFileList.getAwbs().put(awbName, new HashMap<String, String>());\n                }\n                apkFiles.finalApkFileList.getAwbs().get(awbName).put(relativePath, md5);\n            }\n        }\n\n    }\n\n    private static final String[] IMG_EXTENSIONS = new String[] {\".png\", \".jpg\"};\n\n    private static boolean isImageFile(String name) {\n        for (String imgExt : IMG_EXTENSIONS) {\n            if (StringUtils.endsWithIgnoreCase(name, imgExt)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    @NonNull\n    private static final String FLAT_FILE_EXTENSION = \".flat\";\n\n    @NonNull\n    private static final String ARSC_FLAT_FILE_EXTENSION = \".arsc.flat\";\n\n    private static boolean isCompiledFile(String name) {\n        if (StringUtils.endsWithIgnoreCase(name, FLAT_FILE_EXTENSION) && !StringUtils.endsWithIgnoreCase(name,\n            ARSC_FLAT_FILE_EXTENSION)) {\n            return true;\n        }\n        return false;\n    }\n\n    public static class PureFileFilter implements IOFileFilter {\n        @Override\n        public boolean accept(File file) {\n            return accept(file.getParentFile(), file.getName());\n        }\n\n        @Override\n        public boolean accept(File dir, String name) {\n            if (isIgnore(name)) {\n                return false;\n            }\n            return !new File(dir, name).isDirectory();\n        }\n    }\n\n    public static final String[] DEFAULTEXCLUDES = new String[] {\"**/*~\", \"**/#*#\", \"**/.#*\", \"**/%*%\", \"**/._*\",\n        \"**/CVS\", \"**/CVS/**\", \"**/.cvsignore\", \"**/RCS\", \"**/RCS/**\", \"**/SCCS\", \"**/SCCS/**\", \"**/vssver.scc\",\n        \"**/.svn\", \"**/.svn/**\", \"**/.arch-ids\", \"**/.arch-ids/**\", \"**/.bzr\", \"**/.bzr/**\", \"**/.MySCMServerInfo\",\n        \"**/.DS_Store\", \"**/.metadata\", \"**/.metadata/**\", \"**/.hg\", \"**/.hg/**\", \"**/.git\", \"**/.git/**\",\n        \"**/BitKeeper\", \"**/BitKeeper/**\", \"**/ChangeSet\", \"**/ChangeSet/**\", \"**/_darcs\", \"**/_darcs/**\",\n        \"**/.darcsrepo\", \"**/.darcsrepo/**\", \"**/-darcs-backup*\", \"**/.darcs-temp-mail\"};\n\n    private static boolean isIgnore(String name) {\n        for (String pattern : DEFAULTEXCLUDES) {\n            if (match(pattern, name, true)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public static boolean match(String pattern, String str, boolean isCaseSensitive) {\n        char[] patArr = pattern.toCharArray();\n        char[] strArr = str.toCharArray();\n        int patIdxStart = 0;\n        int patIdxEnd = patArr.length - 1;\n        int strIdxStart = 0;\n        int strIdxEnd = strArr.length - 1;\n        boolean containsStar = false;\n\n        int i;\n        for (i = 0; i < patArr.length; ++i) {\n            if (patArr[i] == 42) {\n                containsStar = true;\n                break;\n            }\n        }\n\n        char ch;\n        if (!containsStar) {\n            if (patIdxEnd != strIdxEnd) {\n                return false;\n            } else {\n                for (i = 0; i <= patIdxEnd; ++i) {\n                    ch = patArr[i];\n                    if (ch != 63 && !equals(ch, strArr[i], isCaseSensitive)) {\n                        return false;\n                    }\n                }\n\n                return true;\n            }\n        } else if (patIdxEnd == 0) {\n            return true;\n        } else {\n            while ((ch = patArr[patIdxStart]) != 42 && strIdxStart <= strIdxEnd) {\n                if (ch != 63 && !equals(ch, strArr[strIdxStart], isCaseSensitive)) {\n                    return false;\n                }\n\n                ++patIdxStart;\n                ++strIdxStart;\n            }\n\n            if (strIdxStart > strIdxEnd) {\n                for (i = patIdxStart; i <= patIdxEnd; ++i) {\n                    if (patArr[i] != 42) {\n                        return false;\n                    }\n                }\n\n                return true;\n            } else {\n                while ((ch = patArr[patIdxEnd]) != 42 && strIdxStart <= strIdxEnd) {\n                    if (ch != 63 && !equals(ch, strArr[strIdxEnd], isCaseSensitive)) {\n                        return false;\n                    }\n\n                    --patIdxEnd;\n                    --strIdxEnd;\n                }\n\n                if (strIdxStart > strIdxEnd) {\n                    for (i = patIdxStart; i <= patIdxEnd; ++i) {\n                        if (patArr[i] != 42) {\n                            return false;\n                        }\n                    }\n\n                    return true;\n                } else {\n                    while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {\n                        i = -1;\n\n                        int patLength;\n                        for (patLength = patIdxStart + 1; patLength <= patIdxEnd; ++patLength) {\n                            if (patArr[patLength] == 42) {\n                                i = patLength;\n                                break;\n                            }\n                        }\n\n                        if (i == patIdxStart + 1) {\n                            ++patIdxStart;\n                        } else {\n                            patLength = i - patIdxStart - 1;\n                            int strLength = strIdxEnd - strIdxStart + 1;\n                            int foundIdx = -1;\n                            int i1 = 0;\n\n                            label132:\n                            while (i1 <= strLength - patLength) {\n                                for (int j = 0; j < patLength; ++j) {\n                                    ch = patArr[patIdxStart + j + 1];\n                                    if (ch != 63 && !equals(ch, strArr[strIdxStart + i1 + j], isCaseSensitive)) {\n                                        ++i1;\n                                        continue label132;\n                                    }\n                                }\n\n                                foundIdx = strIdxStart + i1;\n                                break;\n                            }\n\n                            if (foundIdx == -1) {\n                                return false;\n                            }\n\n                            patIdxStart = i;\n                            strIdxStart = foundIdx + patLength;\n                        }\n                    }\n\n                    for (i = patIdxStart; i <= patIdxEnd; ++i) {\n                        if (patArr[i] != 42) {\n                            return false;\n                        }\n                    }\n\n                    return true;\n                }\n            }\n        }\n    }\n\n    private static boolean equals(char c1, char c2, boolean isCaseSensitive) {\n        return c1 == c2 ? true : !isCaseSensitive && (Character.toUpperCase(c1) == Character.toUpperCase(c2)\n            || Character.toLowerCase(c1) == Character.toLowerCase(c2));\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/bundleinfo/BundleGraphExecutor.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.bundleinfo;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.function.Consumer;\n\nimport com.taobao.android.builder.tools.Profiler;\nimport com.taobao.android.builder.tools.bundleinfo.model.BundleInfo;\nimport com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.GradleException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * Created by wuzhong on 2017/5/15.\n */\npublic class BundleGraphExecutor {\n\n    private static Logger logger = LoggerFactory.getLogger(BundleGraphExecutor.class);\n\n    public static void execute(List<BundleInfo> bundleInfos, int parableCount, BundleItemRunner bundleItemRunner)\n        throws IOException, InterruptedException {\n\n        Map<String, BundleInfo> bundleInfoMap = new HashMap<>();\n        bundleInfos.forEach(new Consumer<BundleInfo>() {\n            @Override\n            public void accept(BundleInfo bundleInfo) {\n                bundleInfoMap.put(bundleInfo.getPkgName(), bundleInfo);\n            }\n        });\n\n        Map<String, BundleItem> bundleItemMap = getBundleItemMap(bundleInfoMap);\n\n        handleCircleDependency(bundleItemMap);\n\n        int size = bundleItemMap.size();\n\n        ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper(\"bundleGraph\", logger, parableCount);\n\n        int index = 0;\n        int j = 0;\n        while (index <= size) {\n\n            List<String> keys = new ArrayList<>();\n            List<Runnable> runnables = new ArrayList<>();\n\n            for (String key : bundleItemMap.keySet()) {\n\n                //System.out.println(\"test\" + key);\n                BundleItem bundleItem = bundleItemMap.get(key);\n\n                if (bundleItem.canResolve()) {\n\n                    index++;\n                    //bundleItem.resolve();\n                    keys.add(key);\n\n                    final String name = index + bundleItem.bundleInfo.getPkgName();\n                    runnables.add(new Runnable() {\n                        @Override\n                        public void run() {\n                            logger.warn(\"start to do bundle proguard for \" + name);\n                            bundleItemRunner.execute(bundleItem);\n                            logger.warn(\"end do bundle proguard for \" + name);\n                        }\n                    });\n\n                }\n            }\n\n            Profiler.enter(\"execute stage \" + j++ + \" runnables \" + runnables.size());\n            executorServicesHelper.execute(runnables);\n            Profiler.release();\n\n            if (keys.isEmpty()) {\n                break;\n            }\n\n            for (String key : keys) {\n                bundleItemMap.get(key).resolve();\n                bundleItemMap.remove(key);\n            }\n        }\n\n        if (index != size) {\n            throw new GradleException(\"bundleGraph is some thing wrong\");\n        }\n\n    }\n\n    private static Map<String, BundleItem> getBundleItemMap(Map<String, BundleInfo> bundleInfoMap) {\n        Map<String, BundleItem> bundleItemMap = new HashMap<>();\n        for (BundleInfo bundleInfo : bundleInfoMap.values()) {\n\n            BundleItem bundleItem = bundleItemMap.get(bundleInfo.getPkgName());\n\n            if (null == bundleItem) {\n                bundleItem = new BundleItem();\n                bundleItem.bundleInfo = bundleInfo;\n                bundleItemMap.put(bundleInfo.getPkgName(), bundleItem);\n            }\n\n            //Computing rely on\n            for (String dependency : bundleInfo.getDependency()) {\n                if (StringUtils.isNotEmpty(dependency)) {\n                    BundleItem child = bundleItemMap.get(dependency);\n                    if (null == child) {\n                        child = new BundleItem();\n                        child.bundleInfo = bundleInfoMap.get(dependency);\n                        if (null == child.bundleInfo){\n                            throw new GradleException(\"bundle dependency is error , not bundle found for \" + dependency + \" ; which may define in \" + bundleInfo.getPkgName());\n                        }\n                        bundleItemMap.put(dependency, child);\n                    }\n\n                    bundleItem.children.add(child);\n                    child.parents.add(bundleItem);\n                }\n            }\n\n        }\n        return bundleItemMap;\n    }\n\n    private static void handleCircleDependency(Map<String, BundleItem> bundleItemMap) {\n        Map<String, Set<BundleItem>> circleMap = new HashMap<>();\n        for (BundleItem bundleItem : bundleItemMap.values()) {\n            Set<BundleItem> bundleItems = new HashSet<>();\n            if (bundleItem.isLoop(bundleItem, new HashSet<>())) {\n                bundleItem.getCircles(bundleItems, bundleItem);\n                List<String> list = new ArrayList<>();\n                for (BundleItem b : bundleItems) {\n                    list.add(b.bundleInfo.getPkgName());\n                }\n                Collections.sort(list);\n                String key = StringUtils.join(list.toArray(),\",\");\n                circleMap.put(key, bundleItems);\n            }\n        }\n\n        //TODO\n        for (Set<BundleItem> sets : circleMap.values()) {\n            int i = 0;\n            BundleItem main = null;\n            for (BundleItem bundleItem : getOrderList(sets)) {\n                if (i++ == 0) {\n                    main = bundleItem;\n                } else {\n                    bundleItemMap.remove(bundleItem.bundleInfo.getPkgName());\n                    main.addBundleItem(bundleItem);\n                }\n            }\n        }\n\n\n\n    }\n\n    private static List<BundleItem> getOrderList(Set<BundleItem> sets){\n        List<BundleItem> list = new ArrayList<>(sets);\n        list.sort((o1, o2) -> o1.bundleInfo.getPkgName().compareTo(o2.bundleInfo.getPkgName()));\n        return list;\n    }\n\n}\n\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/bundleinfo/BundleInfoUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.bundleinfo;\n\nimport com.alibaba.fastjson.JSON;\nimport com.alibaba.fastjson.TypeReference;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.google.common.collect.Maps;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.extension.TBuildConfig;\nimport com.taobao.android.builder.tools.bundleinfo.model.BundleInfo;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport com.taobao.android.builder.tools.manifest.ManifestHelper;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.dom4j.DocumentException;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.function.Consumer;\n\n/**\n * Created by wuzhong on 2016/11/24.\n * <p>\n * Collect all bundle information based on the dependent tree\n */\npublic class BundleInfoUtils {\n\n    public static void setupAwbBundleInfos(AppVariantContext appVariantContext) throws IOException, DocumentException {\n\n        String apkVersion = appVariantContext.getVariantConfiguration().getVersionName();\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n            appVariantContext.getScope().\n                getVariantConfiguration().getFullName());\n\n        /**\n         * name Is artifictId\n         */\n        Map<String, BundleInfo> bundleInfoMap = getBundleInfoMap(appVariantContext);\n\n        String baseVersion = apkVersion;\n\n        if (null != appVariantContext.apContext && null != appVariantContext.apContext.getBaseManifest() && appVariantContext.apContext.getBaseManifest().exists()){\n            baseVersion = ManifestFileUtils.getVersionName(appVariantContext.apContext.getBaseManifest());\n        }\n\n        for (AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n            update(awbBundle, bundleInfoMap, appVariantContext, apkVersion, baseVersion);\n            if (appVariantContext.getAtlasExtension().getTBuildConfig().getDisabledBundleDependency()){\n                awbBundle.bundleInfo.getDependency().clear();\n            }\n        }\n    }\n\n    /**\n     * Resolve the manifest file and get BundleInfo\n     *\n     * @return\n     */\n    private static void update(AwbBundle awbBundle,\n                               Map<String, BundleInfo> bundleInfoMap,\n                               AppVariantContext appVariantContext,\n                               String apkVersion, String baseVersion) throws DocumentException {\n\n        String artifactId = awbBundle.getResolvedCoordinates().getArtifactId();\n        BundleInfo bundleInfo = bundleInfoMap.get(artifactId);\n        if (null != bundleInfo) {\n            awbBundle.bundleInfo = bundleInfo;\n        } else {\n            bundleInfo = awbBundle.bundleInfo;\n        }\n        bundleInfo.setIsMBundle(awbBundle.isMBundle);\n        if (appVariantContext.getAtlasExtension().getTBuildConfig().getInsideOfApkBundles().size() > 0){\n            awbBundle.isRemote = !appVariantContext.getAtlasExtension()\n                    .getTBuildConfig()\n                    .getInsideOfApkBundles()\n                    .contains(artifactId);\n        }else if (appVariantContext.getAtlasExtension().getTBuildConfig().getOutOfApkBundles().size() > 0) {\n            awbBundle.isRemote = appVariantContext.getAtlasExtension()\n                    .getTBuildConfig()\n                    .getOutOfApkBundles()\n                    .contains(artifactId);\n        }\n\n\n        bundleInfo.setIsInternal(!awbBundle.isRemote);\n        bundleInfo.setVersion(baseVersion + \"@\" + awbBundle.getResolvedCoordinates().getVersion());\n        bundleInfo.setPkgName(awbBundle.getPackageName());\n\n        String applicationName = ManifestFileUtils.getApplicationName(awbBundle.getManifest());\n        if (StringUtils.isNotEmpty(applicationName)) {\n            if (applicationName.startsWith(\".\")) {\n                applicationName = awbBundle.getPackageName() + applicationName;\n            }\n            bundleInfo.setApplicationName(applicationName);\n        }\n\n        ManifestHelper.collectBundleInfo(appVariantContext, bundleInfo, awbBundle.getManifest(),\n                                         awbBundle.getAndroidLibraries());\n\n\n    }\n\n\n\n    private static Map<String, BundleInfo> getBundleInfoMap(AppVariantContext appVariantContext) throws IOException {\n        File baseBunfleInfoFile = new File(appVariantContext.getScope()\n                                               .getGlobalScope()\n                                               .getProject()\n                                               .getProjectDir(), \"bundleBaseInfoFile.json\");\n\n        //Use the file replacement in the plug-in\n\n\n\n\n        Map<String, BundleInfo> bundleFileMap = Maps.newHashMap();\n        if (null != baseBunfleInfoFile &&\n            baseBunfleInfoFile.exists() &&\n            baseBunfleInfoFile.canRead()) {\n            String bundleBaseInfo = FileUtils.readFileToString(baseBunfleInfoFile, \"utf-8\");\n            bundleFileMap = JSON.parseObject(bundleBaseInfo,\n                                             new TypeReference<Map<String, BundleInfo>>() {\n                                             });\n        }\n\n        List<AwbBundle> awbBundles = AtlasBuildContext.androidDependencyTrees.get(\n            appVariantContext.getVariantData().getName()).getAwbBundles();\n\n        List<String> duplicatedBundleInfo = new ArrayList<>();\n        Set<String>pkgNames = new HashSet<>();\n        for (AwbBundle awbBundle : awbBundles) {\n            pkgNames.add(awbBundle.getPackageName());\n            String name = awbBundle.getResolvedCoordinates().getArtifactId();\n            File bundleBaseInfoFile = new File(awbBundle.getAndroidLibrary().getFolder(), \"bundleBaseInfoFile.json\");\n            if (bundleBaseInfoFile.exists()) {\n                String json = FileUtils.readFileToString(bundleBaseInfoFile, \"utf-8\");\n                BundleInfo bundleInfo = JSON.parseObject(json, BundleInfo.class);\n                if (bundleFileMap.containsKey(name)) {\n                    appVariantContext.getProject().getLogger().error(\n                        \"bundleBaseInfoFile>>>\" + name + \" has declared bundleBaseInfoFile\");\n                    duplicatedBundleInfo.add(name);\n                    for (String dependency:bundleInfo.getDependency()) {\n                        if (!bundleFileMap.get(name).getDependency().contains(dependency))\n                        bundleFileMap.get(name).getDependency().add(dependency);\n                    }\n                }else {\n                    bundleFileMap.put(name,bundleInfo);\n                }\n\n            }\n        }\n\n        bundleFileMap.values().forEach(bundleInfo -> {\n            List<String>removedBundles = new ArrayList<>();\n            List<String>deps = bundleInfo.getDependency();\n            for (String s:deps){\n                if (!pkgNames.contains(s)){\n                    removedBundles.add(s);\n                }\n            }\n            deps.removeAll(removedBundles);\n        });\n\n        if (duplicatedBundleInfo.size() > 0) {\n            FileUtils.writeLines(\n                new File(appVariantContext.getProject().getBuildDir(), \"outputs/warning-dupbundleinfo.properties\"),\n                duplicatedBundleInfo);\n        }\n\n        return bundleFileMap;\n    }\n\n\n    public static File writeBundleInfo(AppVariantContext appVariantContext) throws IOException, DocumentException {\n\n        List<BundleInfo> bundleInfoList = getBundleInfoList(appVariantContext);\n\n        File bundleInfoFile = new File(appVariantContext.getProject().getBuildDir(),\n                                       \"outputs/bundleInfo-\" +\n                                           appVariantContext.getVariantConfiguration()\n                                               .getVersionName() +\n                                           \".json\");\n        File bundleInfoFile2 = new File(appVariantContext.getProject().getBuildDir(),\n                                        \"outputs/pretty-bundleInfo-\" +\n                                            appVariantContext.getVariantConfiguration()\n                                                .getVersionName() +\n                                            \".json\");\n\n        try {\n            FileUtils.write(bundleInfoFile, JSON.toJSONString(bundleInfoList, false));\n            FileUtils.write(bundleInfoFile2, JSON.toJSONString(bundleInfoList, true));\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        return bundleInfoFile;\n    }\n\n    @NotNull\n    public static List<BundleInfo> getBundleInfoList(AppVariantContext appVariantContext) {\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n            appVariantContext.getScope().\n                getVariantConfiguration().getFullName());\n\n        List<BundleInfo> bundleInfoList = new ArrayList<BundleInfo>();\n\n        for (AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n            bundleInfoList.add(awbBundle.bundleInfo);\n        }\n        return bundleInfoList;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/bundleinfo/BundleItem.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.bundleinfo;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\nimport com.taobao.android.builder.tools.bundleinfo.model.BundleInfo;\n\n/**\n * Created by wuzhong on 2017/5/15.\n */\npublic class BundleItem {\n\n    public BundleInfo bundleInfo;\n\n    public Set<BundleInfo> circles = new HashSet<>();\n\n    public Set<BundleItem> parents = new HashSet<>();\n\n    public Set<BundleItem> children = new HashSet<>();\n\n    private boolean resolved;\n\n    public boolean canResolve() {\n\n        //System.out.println(\"test\" + bundleInfo.getPkgName() );\n\n        if (this.resolved) {\n            return false;\n        }\n\n        if (parents.isEmpty()) {\n            return true;\n        }\n\n        if (ifParentResolved()) {\n            return true;\n        }\n\n        return false;\n    }\n\n    private boolean ifParentResolved() {\n        for (BundleItem parent : parents) {\n            if (!parent.isResolved()) {\n                return false;\n            }else {\n                //System.out.println(parent.bundleInfo.getPkgName() + \" resolved\");\n            }\n        }\n        return true;\n    }\n\n    public boolean getCircles(Set<BundleItem> sets, BundleItem root){\n        if (this.isResolved()){\n            return false;\n        }\n        //If it's a cycle\n        if (sets.contains(this)){\n            return true;\n        }\n\n        sets.add(this);\n        Set<String> stringSet = new HashSet<>();\n        for (BundleItem bundleItem : children){\n\n            if (canLoopTo( bundleItem, root,stringSet)){\n                if(bundleItem.getCircles(sets,root)){\n                    return true;\n                }\n            }\n\n\n        }\n        return false;\n    }\n\n    public boolean isLoop(BundleItem bundleItem, Set<BundleItem> resolves){\n        for (BundleItem child : children){\n            if (resolves.contains(child)){\n                continue;\n            }\n            resolves.add(child);\n            if (child == bundleItem){\n                return true;\n            }\n            if(child.isLoop(bundleItem,resolves)){\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public boolean canLoopTo(BundleItem from, BundleItem end , Set<String> stringSet){\n        String key = from.bundleInfo.getPkgName() + \"->\" + end.bundleInfo.getPkgName();\n        if (stringSet.contains(key)){\n            return false;\n        }\n        stringSet.add(key);\n        System.out.println(key);\n        for (BundleItem child : from.children){\n            if (child == end){\n                return true;\n            }\n            if (child == from){\n                continue;\n            }\n            if(canLoopTo(child, end,stringSet)){\n                return true;\n            }\n        }\n        return false;\n    }\n\n\n    public void resolve() {\n        this.resolved = true;\n    }\n\n    public boolean isResolved() {\n        return resolved;\n    }\n\n    public void addBundleItem(BundleItem bundleItem) {\n        circles.add(bundleItem.bundleInfo);\n        this.parents.addAll(bundleItem.parents);\n        this.children.addAll(bundleItem.children);\n\n        for (BundleItem parent : bundleItem.parents){\n            parent.children.remove(bundleItem);\n            parent.children.add(this);\n        }\n\n        for (BundleItem child : bundleItem.children){\n            child.parents.remove(bundleItem);\n            child.parents.add(this);\n        }\n\n        this.parents.remove(this);\n        this.children.remove(this);\n\n    }\n\n    public List<BundleInfo> getBundleGroup(){\n        List<BundleInfo> bundleItems = new ArrayList<>(circles);\n        bundleItems.add(bundleInfo);\n        return bundleItems;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/bundleinfo/BundleItemRunner.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.bundleinfo;\n\n/**\n * Created by wuzhong on 2017/5/15.\n */\npublic interface BundleItemRunner {\n\n    public void execute(BundleItem bundleItem);\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/bundleinfo/DynamicBundleInfo.java",
    "content": "package com.taobao.android.builder.tools.bundleinfo;\n\n/**\n * DynamicBundleInfo\n *\n * @author zhayu.ll\n * @date 18/1/10\n * @time 下午4:51\n * @description  \n */\npublic class DynamicBundleInfo {\n\n    public String name;\n\n    public String url;\n\n    public Long size;\n\n    public String md5;\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/bundleinfo/model/BasicBundleInfo.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.bundleinfo.model;\n\nimport com.google.common.collect.Lists;\n\nimport java.util.HashMap;\nimport java.util.List;\n\n/**\n * Created by wuzhong on 2016/11/24.\n */\npublic class BasicBundleInfo {\n\n    private String pkgName;\n\n    /**\n     * The main dex depends on + the md5 that is currently dependent\n     */\n    private String unique_tag;\n\n    private String applicationName;\n\n    private String version;\n\n\n    public Boolean getIsMBundle() {\n        return isMBundle;\n    }\n\n    public void setIsMBundle(boolean mainBundle) {\n        isMBundle = mainBundle;\n    }\n\n    private Boolean isMBundle = false;\n\n    private List<String> dependency = Lists.newArrayList();\n\n    private List<String> activities = Lists.newArrayList();\n\n    private List<String> services = Lists.newArrayList();\n\n    private List<String> receivers = Lists.newArrayList();\n\n    private List<String> contentProviders = Lists.newArrayList();\n\n    private HashMap<String,String> remoteFragments= new HashMap<String,String>();\n\n    private HashMap<String,String> remoteViews = new HashMap<String,String>();\n\n    private HashMap<String,String> remoteTransactors = new HashMap<String,String>();\n\n    private Boolean isInternal = true;\n\n    public HashMap<String, String> getRemoteViews() {\n        return remoteViews;\n    }\n\n    public void setRemoteViews(HashMap<String, String> remoteViews) {\n        this.remoteViews = remoteViews;\n    }\n\n    public HashMap<String, String> getRemoteTransactors() {\n        return remoteTransactors;\n    }\n\n    public void setRemoteTransactors(HashMap<String, String> remoteTransactors) {\n        this.remoteTransactors = remoteTransactors;\n    }\n\n    public HashMap<String, String> getRemoteFragments() {\n        return remoteFragments;\n    }\n\n    public void setRemoteFragments(HashMap<String, String> remoteFragments) {\n        this.remoteFragments = remoteFragments;\n    }\n\n    public String getPkgName() {\n        return pkgName;\n    }\n\n    public void setPkgName(String pkgName) {\n        this.pkgName = pkgName;\n    }\n\n    public String getApplicationName() {\n        return applicationName;\n    }\n\n    public void setApplicationName(String applicationName) {\n        this.applicationName = applicationName;\n    }\n\n    public String getVersion() {\n        return version;\n    }\n\n    public void setVersion(String version) {\n        this.version = version;\n    }\n\n    public List<String> getDependency() {\n        return dependency;\n    }\n\n    public void setDependency(List<String> dependency) {\n        this.dependency = dependency;\n    }\n\n    public List<String> getActivities() {\n        return activities;\n    }\n\n    public void setActivities(List<String> activities) {\n        this.activities = activities;\n    }\n\n    public List<String> getServices() {\n        return services;\n    }\n\n    public void setServices(List<String> services) {\n        this.services = services;\n    }\n\n    public List<String> getReceivers() {\n        return receivers;\n    }\n\n    public void setReceivers(List<String> receivers) {\n        this.receivers = receivers;\n    }\n\n    public List<String> getContentProviders() {\n        return contentProviders;\n    }\n\n    public void setContentProviders(List<String> contentProviders) {\n        this.contentProviders = contentProviders;\n    }\n\n    public boolean getIsInternal() {\n        return isInternal;\n    }\n\n    public void setIsInternal(boolean internal) {\n        isInternal = internal;\n    }\n\n    public String getUnique_tag() {\n        return unique_tag;\n    }\n\n    public void setUnique_tag(String unique_tag) {\n        this.unique_tag = unique_tag;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/bundleinfo/model/BundleInfo.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.bundleinfo.model;\n\n/**\n * atlasThe information class for the business Bundle Created by shenghua.nish on 2015-08-26 1:09 p.m.\n */\npublic class BundleInfo extends BasicBundleInfo {\n\n    private String name;\n\n    private Long size;\n\n    private String desc;\n\n    private String url;\n\n    private Boolean manifestUpdated;\n\n    private String md5;\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public Long getSize() {\n        return size;\n    }\n\n    public void setSize(Long size) {\n        this.size = size;\n    }\n\n    public String getDesc() {\n        return desc;\n    }\n\n    public void setDesc(String desc) {\n        this.desc = desc;\n    }\n\n    public String getUrl() {\n        return url;\n    }\n\n    public void setUrl(String url) {\n        this.url = url;\n    }\n\n    public String getMd5() {\n        return md5;\n    }\n\n    public void setMd5(String md5) {\n        this.md5 = md5;\n    }\n\n    public Boolean isManifestUpdated() {\n        return manifestUpdated;\n    }\n\n    public void setManifestUpdated(Boolean manifestUpdated) {\n        this.manifestUpdated = manifestUpdated;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/cache/Cache.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.cache;\n\nimport java.io.File;\nimport java.io.IOException;\n\n/**\n * Created by wuzhong on 2017/6/8.\n */\npublic interface Cache {\n\n    /**\n     * Memory cache\n     *\n     * @param type\n     * @param key\n     * @param file\n     * @return\n     */\n    public void cacheFile(String type, String key, File file) throws FileCacheException;\n\n    /**\n     * Read cache\n     *\n     * @param type\n     * @param key\n     * @param localFile\n     * @return\n     * @throws IOException\n     */\n    public boolean fetchFile(String type, String key, File localFile, boolean folder) throws FileCacheException;\n\n\n    public File getLocalCacheFile(String type, String key);\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/cache/FileCacheCenter.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.cache;\n\nimport java.io.File;\nimport java.io.IOException;\n\nimport com.taobao.android.builder.tools.log.FileLogger;\nimport org.apache.commons.io.FileUtils;\n\n/**\n * Created by wuzhong on 2017/6/8.\n *\n * Unified file cache center\n */\npublic class FileCacheCenter {\n\n    public static final boolean BUILD_CACHE_ENABLED = true;\n    private static FileLogger logger = FileLogger.getInstance(\"filecache\");\n\n    public static Cache networkCache;\n    public static Cache localCache = new SimpleLocalCache();\n\n    /**\n     * Cache files or folders\n     *\n     * @param type\n     * @param key\n     * @param file\n     * @throws FileCacheException\n     */\n    public static void cacheFile(String type, String key, File file, boolean remote) throws FileCacheException {\n\n        if (!BUILD_CACHE_ENABLED){\n            return;\n        }\n\n        localCache.cacheFile(type, key, file);\n\n        logger.log(type + \".\" + key + \" cache \" + file.getAbsolutePath() + \" to local success\");\n\n        if (null != networkCache && remote) {\n            networkCache.cacheFile(type, key, file);\n            logger.log(type + \".\" + key + \" cache \" + file.getAbsolutePath() + \" to network success\");\n        }\n\n    }\n\n    /**\n     * Query the file, if the local file does not exist, try to read the cache from the cloud\n     *\n     * @param type\n     * @param key\n     * @param folder\n     * @return\n     * @throws FileCacheException\n     */\n    public static File queryFile(String type, String key, boolean folder, boolean remote) throws FileCacheException {\n\n        if (!BUILD_CACHE_ENABLED){\n            return null;\n        }\n\n        File localCacheFile = localCache.getLocalCacheFile(type, key);\n        if (localCacheFile.exists()) {\n\n            if (folder != localCacheFile.isDirectory()) {\n                try {\n                    FileUtils.forceDelete(localCacheFile);\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n                throw new FileCacheException(\"local dir is folder \" + folder);\n            }\n\n            logger.log(type + \".\" + key + \" query local cache  \" + localCacheFile.getAbsolutePath() + \" success\");\n            return localCacheFile;\n        }else {\n            logger.log(type + \".\" + key + \" miss local cache  \" + localCacheFile.getAbsolutePath());\n        }\n\n        if (null == networkCache || !remote) {\n            return localCacheFile;\n        }\n\n        try {\n\n            boolean success = networkCache.fetchFile(type, key, localCacheFile, folder);\n\n            logger.log(type + \".\" + key + \" fetch remote cache  \" + localCacheFile.getAbsolutePath() + success);\n\n            if (success) {\n                return localCacheFile;\n            }\n\n        } catch (Throwable e) {\n\n            logger.log(type + \".\" + key + \" fetch remote cache  \" + localCacheFile.getAbsolutePath() + \" exception\");\n            e.printStackTrace();\n        }\n\n        logger.log(type + \".\" + key + \" get cache file failed  \" + localCacheFile.getAbsolutePath());\n        try {\n            FileUtils.forceDelete(localCacheFile);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        return localCacheFile;\n\n    }\n\n\n    public static void fetchFile(String type, String key, boolean folder, boolean remote, File dest) throws FileCacheException {\n\n        if (!BUILD_CACHE_ENABLED){\n            return;\n        }\n\n        File cacheFile = queryFile(type,key,folder,remote);\n\n        if (null != cacheFile && cacheFile.exists()){\n\n            try {\n                if (cacheFile.isFile()) {\n                    FileUtils.copyFile(cacheFile, dest);\n                } else {\n                    FileUtils.copyDirectory(cacheFile, dest);\n                }\n                logger.log(type + \".\" + key + \" fech  file success  \" + dest.getAbsolutePath());\n            }catch (Throwable e){\n                throw new FileCacheException(e.getMessage(),e);\n            }\n\n        }\n\n\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/cache/FileCacheException.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.cache;\n\n/**\n * Created by wuzhong on 2017/6/8.\n */\npublic class FileCacheException extends Exception {\n\n    public FileCacheException(String message) {\n        super(message);\n    }\n\n    public FileCacheException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public FileCacheException(Throwable cause) {\n        super(cause);\n    }\n\n    public FileCacheException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause, enableSuppression, writableStackTrace);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/cache/FileLockUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.cache;\n\nimport java.io.File;\nimport java.io.RandomAccessFile;\nimport java.nio.channels.FileLock;\n\nimport org.gradle.api.GradleException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * Created by wuzhong on 2017/5/14.\n */\npublic class FileLockUtils {\n\n    private static Logger log = LoggerFactory.getLogger(FileLockUtils.class);\n\n    public static boolean lock(File file, Runnable runnable) {\n        try {\n\n            File lockFile = file;\n            if (lockFile.isDirectory()) {\n                lockFile = new File(lockFile, \".atlaslock\");\n            }\n            RandomAccessFile randomAccessFile;\n            FileLock fileLock ;\n            try {\n                randomAccessFile = new RandomAccessFile(lockFile, \"rw\");\n                fileLock = randomAccessFile.getChannel().tryLock();\n            } catch (Exception e) {\n                throw new GradleException(e.getMessage(),e);\n            }\n            if (fileLock != null) {\n                File finalLockFile = lockFile;\n                Runtime.getRuntime().addShutdownHook(new Thread() {\n                    @Override\n                    public void run() {\n                        try {\n                            fileLock.release();\n                            randomAccessFile.close();\n                            finalLockFile.delete();\n                        } catch (Exception e) {\n                            log.error(\"Unable to remove lock file: \" + file.getAbsolutePath(), e);\n                        }\n                    }\n                });\n\n                runnable.run();\n\n                lockFile.delete();\n                return true;\n            }\n\n        } finally {\n\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/cache/SimpleLocalCache.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.cache;\n\nimport java.io.File;\nimport java.io.IOException;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.jetbrains.annotations.NotNull;\n\n/**\n * Created by wuzhong on 2017/6/8.\n */\npublic class SimpleLocalCache implements Cache {\n\n    //java.io.tmpdir\n    static File cacheDir;\n\n    static {\n        cacheDir = new File(System.getProperty(\"user.home\"), \".mtl-plugin/cache\");\n        cacheDir.mkdirs();\n    }\n\n    @Override\n    public void cacheFile(String type, String key, File file) throws FileCacheException {\n        if (StringUtils.isEmpty(key)) {\n            throw new FileCacheException(\"cache key is empty \");\n        }\n        File cacheFile = getLocalCacheFile(type, key);\n        if (cacheFile.exists()) {\n            throw new FileCacheException(\"file cache alerady exist:\" + cacheFile.getAbsolutePath());\n        }\n\n        try {\n\n            cacheFile.getParentFile().mkdirs();\n\n            if (file.isFile()) {\n                FileUtils.copyFile(file, cacheFile);\n            } else {\n\n                cacheFile.mkdirs();\n\n                FileLockUtils.lock(cacheFile, new Runnable() {\n                    @Override\n                    public void run() {\n                        try {\n                            FileUtils.copyDirectory(file, cacheFile);\n                        } catch (Throwable e) {\n                            try {\n                                FileUtils.forceDelete(cacheFile);\n                            } catch (IOException e1) {\n                                e1.printStackTrace();\n                            }\n                            throw new RuntimeException(e.getMessage(), e);\n                        }\n                    }\n                });\n            }\n        } catch (Throwable e) {\n            throw new FileCacheException(e.getMessage(), e);\n        }\n\n    }\n\n    @Override\n    public boolean fetchFile(String type, String key, File localFile, boolean folder) throws FileCacheException {\n\n        if (StringUtils.isEmpty(key)) {\n            throw new FileCacheException(\"cache key is empty \");\n        }\n\n        File cacheFile = getLocalCacheFile(type, key);\n\n        try {\n            if (cacheFile.exists() && cacheFile.length() > 0) {\n                if (cacheFile.isDirectory()) {\n                    FileUtils.copyDirectory(cacheFile, localFile);\n                } else {\n                    FileUtils.copyFile(cacheFile, localFile);\n                }\n            }\n        } catch (IOException e) {\n            throw new FileCacheException(e.getMessage(), e);\n        }\n\n        return true;\n    }\n\n    @NotNull\n    public File getLocalCacheFile(String type, String key) {\n        return new File(cacheDir, type + \"/\" + key);\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/cache/SimpleNetworkCache.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.cache;\n\nimport java.io.File;\nimport java.io.IOException;\n\nimport com.taobao.android.builder.tools.zip.BetterZip;\n\n/**\n * Created by wuzhong on 2017/6/8.\n */\npublic class SimpleNetworkCache implements Cache{\n\n    private NetworkProtocol networkProtocol;\n\n    public SimpleNetworkCache(NetworkProtocol networkProtocol) {\n        this.networkProtocol = networkProtocol;\n    }\n\n    @Override\n    public void cacheFile(String type, String key, File file) throws FileCacheException {\n\n        File toUploadFile = file;\n        if (file.isDirectory()){\n            toUploadFile = new File(file.getParentFile(),toUploadFile.getName()+\"_tmp.zip\");\n            try {\n                BetterZip.zipDirectory(file,toUploadFile);\n            } catch (IOException e) {\n                throw new FileCacheException(e.getMessage(),e);\n            }\n        }\n\n        try {\n            if (!networkProtocol.uploadFile(type + \"/\" + key, toUploadFile)) {\n                throw new FileCacheException(\"upload file failed\");\n            }\n        }finally {\n            //Delete folder\n            if(toUploadFile.getName().endsWith(\"_tmp.zip\")){\n                toUploadFile.delete();\n            }\n        }\n    }\n\n    @Override\n    public boolean fetchFile(String type, String key, File localFile, boolean folder) throws FileCacheException {\n\n        boolean succss = networkProtocol.downloadFile(type + \"/\" + key, localFile);\n\n        if (!succss){\n            return false;\n        }\n\n        if (folder){\n\n            //Unzip the files\n            File current = new File(localFile.getAbsolutePath());\n            File zipFile = new File(localFile.getParentFile(),localFile.getName()+\"_tmp.zip\");\n            localFile.renameTo(zipFile);\n\n            try {\n                BetterZip.unzipDirectory(zipFile,current);\n                zipFile.delete();\n            } catch (IOException e) {\n                throw new FileCacheException(e.getMessage(),e);\n            }\n\n        }\n\n        return true;\n\n    }\n\n    @Override\n    public File getLocalCacheFile(String type, String key) {\n        return null;\n    }\n\n\n    public static interface NetworkProtocol {\n\n        boolean downloadFile(String key, File localFile);\n\n        boolean uploadFile(String key, File file);\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/classinject/ApkInjectInfoCreator.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.classinject;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.math.BigInteger;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.function.Consumer;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\nimport com.alibaba.fastjson.JSON;\n\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.diff.DependencyDiff;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.extension.TBuildConfig;\nimport com.taobao.android.builder.tools.MD5Util;\nimport com.taobao.android.builder.tools.bundleinfo.model.BasicBundleInfo;\nimport com.taobao.android.builder.tools.bundleinfo.model.BundleInfo;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang3.StringUtils;\n\n/**\n * Created by wuzhong on 2016/12/1.\n */\npublic class ApkInjectInfoCreator {\n\n    public InjectParam creteInjectParam(AppVariantContext appVariantContext) throws Exception {\n        InjectParam injectParam = new InjectParam();\n\n        injectParam.removePreverify = !appVariantContext.getAtlasExtension()\n            .getTBuildConfig()\n            .getDoPreverify();\n        injectParam.version = appVariantContext.getVariantConfiguration().getVersionName();\n\n        AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n            appVariantContext.getScope().\n                getVariantConfiguration().getFullName());\n\n        List<BasicBundleInfo> basicBundleInfos = new ArrayList<BasicBundleInfo>();\n        Map<String, BasicBundleInfo> basicBundleInfoMap = new HashMap<>();\n        List<String>mainDexDependencies = atlasDependencyTree.getMainBundle().getAllDependencies();\n        Collections.sort(mainDexDependencies, new Comparator<String>() {\n            @Override\n            public int compare(String o1, String o2) {\n                return o1.compareTo(o2);\n            }\n        });\n        String mainMd532 = MD5Util.getMD5(StringUtils.join(mainDexDependencies));\n        String md5base36 = new BigInteger(mainMd532.substring(8,24),16).toString(36);\n        injectParam.unit_tag = md5base36;\n        appVariantContext.unit_tag = md5base36;\n\n        //Depends on whether the change is sent\n        DependencyDiff dependencyDiff = appVariantContext.getDependencyDiff();\n        Map<String, String> baseTagMap = appVariantContext.getBaseUnitTagMap();\n\n        for (AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {\n//            if (awbBundle.isMBundle){\n//                continue;\n//            }\n\n            BundleInfo bundleInfo = awbBundle.bundleInfo;\n\n            BasicBundleInfo basicBundleInfo = new BasicBundleInfo();\n\n            basicBundleInfo.setApplicationName(bundleInfo.getApplicationName());\n            basicBundleInfo.setVersion(bundleInfo.getVersion());\n            basicBundleInfo.setPkgName(bundleInfo.getPkgName());\n\n            //set unique_tag\n            String bundleDependencyMd532 = MD5Util.getMD5(StringUtils.join(awbBundle.getAllDependencies()));\n            String bundleUnitTag = \"\";\n\n            if ( null != dependencyDiff && !dependencyDiff.isDiffBundle(awbBundle)){\n                bundleUnitTag = baseTagMap.get(awbBundle.getPackageName());\n            }\n            if (StringUtils.isEmpty(bundleUnitTag)){\n                String bundleMd532 = MD5Util.getMD5(mainMd532 + bundleDependencyMd532);\n                bundleUnitTag = new BigInteger(bundleMd532.substring(8,24),16).toString(36);\n            }\n\n            basicBundleInfo.setUnique_tag(bundleUnitTag);\n            bundleInfo.setUnique_tag(bundleUnitTag);\n\n            if (!bundleInfo.getIsInternal()) {\n                basicBundleInfo.setIsInternal(false);\n            }\n            if (awbBundle.isMBundle){\n                basicBundleInfo.setIsMBundle(true);\n            }\n            if (!bundleInfo.getActivities().isEmpty()) {\n                basicBundleInfo.setActivities(bundleInfo.getActivities());\n            }\n            if (!bundleInfo.getContentProviders().isEmpty()) {\n                basicBundleInfo.setContentProviders(bundleInfo.getContentProviders());\n            }\n            if (!bundleInfo.getDependency().isEmpty()) {\n                basicBundleInfo.setDependency(bundleInfo.getDependency());\n            }\n            if (!bundleInfo.getReceivers().isEmpty()) {\n                basicBundleInfo.setReceivers(bundleInfo.getReceivers());\n            }\n            if (!bundleInfo.getServices().isEmpty()) {\n                basicBundleInfo.setServices(bundleInfo.getServices());\n            }\n            if (!bundleInfo.getRemoteFragments().isEmpty()) {\n                basicBundleInfo.setRemoteFragments(bundleInfo.getRemoteFragments());\n            }\n            if (!bundleInfo.getRemoteViews().isEmpty()) {\n                basicBundleInfo.setRemoteViews(bundleInfo.getRemoteViews());\n            }\n            if (!bundleInfo.getRemoteTransactors().isEmpty()) {\n                basicBundleInfo.setRemoteTransactors(bundleInfo.getRemoteTransactors());\n            }\n\n            basicBundleInfos.add(basicBundleInfo);\n            basicBundleInfoMap.put(bundleInfo.getPkgName(), basicBundleInfo);\n        }\n\n//        Collections.sort(basicBundleInfos, (o1, o2) -> {\n//            if (o1.getDependency().contains(o2.getPkgName())){\n//                return -1;\n//            }else {\n//                return 1;\n//            }\n//        });\n\n       basicBundleInfos.forEach(basicBundleInfo -> checkDependency(basicBundleInfo,atlasDependencyTree.getAwbBundles()));\n\n                injectParam.bundleInfo = JSON.toJSONString(basicBundleInfos);\n\n        //FIXME MOVE TO MTL-PLUGIN\n        //List<String> autoStartBundles = new ArrayList<String>(appVariantContext.getAtlasExtension().getTBuildConfig\n        // ().getAutoStartBundles());\n        //\n        //UpdateConfig updateConfig = appVariantContext.getAtlasExtension().getUpdateConfig();\n        //if (updateConfig.enabled) {\n        //    injectParam.group = updateConfig.getProductName();\n        //    injectParam.outApp = updateConfig.isOutApp();\n        //    autoStartBundles.add(0, updateConfig.getSdkPkgName());\n        //}\n        //\n        injectParam.group = appVariantContext.getAtlasExtension().getTBuildConfig().getGroup();\n\n        injectParam.autoStartBundles = StringUtils.join(appVariantContext.getAtlasExtension()\n                                                            .getTBuildConfig()\n                                                            .getAutoStartBundles(), \",\");\n        injectParam.preLaunch = appVariantContext.getAtlasExtension()\n            .getTBuildConfig()\n            .getPreLaunch();\n        mergeBundleInfos(appVariantContext, injectParam, basicBundleInfos, basicBundleInfoMap);\n        return injectParam;\n    }\n\n    private void checkDependency(BasicBundleInfo basicBundleInfo, List<AwbBundle> awbBundles) {\n        if (basicBundleInfo.getIsMBundle()){\n           basicBundleInfo.getDependency().parallelStream().forEach(s -> awbBundles.stream().forEach(awbBundle -> {\n               if (awbBundle.getPackageName().equals(s)){\n                   if (!awbBundle.isMBundle){\n                       throw new IllegalArgumentException(basicBundleInfo.getPkgName()+\" mbundle can not dependent local bundle or remote Bundle\" +s);\n                   }\n               }\n           }));\n        }\n\n    }\n\n\n\n\n    private void mergeBundleInfos(AppVariantContext appVariantContext, InjectParam injectParam,\n                                  List<BasicBundleInfo> basicBundleInfos,\n                                  Map<String, BasicBundleInfo> basicBundleInfoMap) throws IOException {\n        if (appVariantContext.getAtlasExtension().getTBuildConfig().isIncremental()) {\n            File atlasFrameworkPropertiesFile = new File(appVariantContext.apContext.getApExploredFolder(),\n                                                         \"atlasFrameworkProperties.json\");\n            if (!atlasFrameworkPropertiesFile.exists()) {\n                return;\n            }\n            String atlasFrameworkPropertiesStr = FileUtils.readFileToString(\n                atlasFrameworkPropertiesFile);\n            FrameworkProperties atlasFrameworkProperties = JSON.parseObject(\n                atlasFrameworkPropertiesStr,\n                FrameworkProperties.class);\n            List<BasicBundleInfo> baseBundleInfos = atlasFrameworkProperties.bundleInfo;\n            for (BasicBundleInfo baseBundleInfo : baseBundleInfos) {\n                BasicBundleInfo basicBundleInfo = basicBundleInfoMap.get(baseBundleInfo.getPkgName());\n                if (basicBundleInfo == null) {\n                    basicBundleInfos.add(baseBundleInfo);\n                    continue;\n                }\n                if (!baseBundleInfo.getActivities().isEmpty()) {\n                    basicBundleInfo.setActivities(concatList(baseBundleInfo.getActivities(),\n                                                             basicBundleInfo.getActivities()));\n                }\n                if (!baseBundleInfo.getContentProviders().isEmpty()) {\n                    basicBundleInfo.setContentProviders(concatList(baseBundleInfo.getContentProviders(),\n                                                                   basicBundleInfo.getContentProviders()));\n                }\n                if (!baseBundleInfo.getDependency().isEmpty()) {\n                    basicBundleInfo.setDependency(concatList(baseBundleInfo.getDependency(),\n                                                             basicBundleInfo.getDependency()));\n                }\n                if (!baseBundleInfo.getReceivers().isEmpty()) {\n                    basicBundleInfo.setReceivers(concatList(baseBundleInfo.getReceivers(),\n                                                            basicBundleInfo.getReceivers()));\n                }\n                if (!baseBundleInfo.getServices().isEmpty()) {\n                    basicBundleInfo.setServices(concatList(baseBundleInfo.getServices(),\n                                                           basicBundleInfo.getServices()));\n                }\n\n                if(!baseBundleInfo.getRemoteFragments().isEmpty()){\n                    basicBundleInfo.getRemoteFragments().putAll(baseBundleInfo.getRemoteFragments());\n                }\n                if(!baseBundleInfo.getRemoteViews().isEmpty()){\n                    basicBundleInfo.getRemoteViews().putAll(baseBundleInfo.getRemoteViews());\n                }\n                if(!baseBundleInfo.getRemoteTransactors().isEmpty()){\n                    basicBundleInfo.getRemoteTransactors().putAll(baseBundleInfo.getRemoteTransactors());\n                }\n            }\n            injectParam.bundleInfo = JSON.toJSONString(basicBundleInfos);\n            injectParam.autoStartBundles = atlasFrameworkProperties.autoStartBundles;\n            injectParam.preLaunch = atlasFrameworkProperties.preLaunch;\n        }\n    }\n\n    private static List<String> concatList(List<String> listOne, List<String> listTwo) {\n        return Stream.concat(listOne.stream(), listTwo.stream())\n            .distinct()\n            .collect(Collectors.toList());\n    }\n\n\n    public void injectTpatchValuesRes(AppVariantContext appVariantContext, File valuesXml) {\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/classinject/ClazzInjecter.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.classinject;\n\nimport java.util.Map;\n\n/**\n * Created by wuzhong on 2016/12/27.\n */\npublic interface ClazzInjecter {\n\n    public Map<String, String> getInjectFields();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/classinject/CodeInjectByJavassist.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.classinject;\n\nimport com.alibaba.fastjson.JSON;\nimport javassist.*;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.IOUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.*;\nimport java.util.*;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\nimport java.util.jar.JarOutputStream;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipException;\nimport java.util.zip.ZipOutputStream;\n\n/**\n * Code injection is done through Javassist\n * Created by shenghua.nish on 2015-10-22 Again in the afternoon.\n */\npublic class CodeInjectByJavassist {\n\n    public static Map<String, ClazzInjecter> sInjecterMap = new HashMap<String, ClazzInjecter>();\n\n    private static Logger logger = LoggerFactory.getLogger(CodeInjectByJavassist.class);\n\n    public synchronized static byte[] inject(ClassPool pool,\n                                             String className,\n                                             InjectParam injectParam) throws Exception {\n\n        CtClass cc = pool.get(className);\n        cc.defrost();\n        if (className.equalsIgnoreCase(\"android.taobao.atlas.framework.FrameworkProperties\") ||\n            className.equalsIgnoreCase(\"android.taobao.atlas.version.VersionKernal\")) {\n\n            if (StringUtils.isNotBlank(injectParam.version)) {\n                CtClass ctClass = pool.get(\"java.lang.String\");\n                CtField ctField = new CtField(ctClass, \"version\", cc);\n                ctField.setModifiers(Modifier.PRIVATE);\n                CtMethod ctMethod = CtNewMethod.getter(\"getVersion\", ctField);\n                ctMethod.setModifiers(Modifier.PUBLIC);\n                CtField.Initializer initializer = CtField.Initializer.constant(injectParam.version);\n                try {\n                    cc.removeField(ctField);\n\n                }catch (Exception e){\n\n                }\n                cc.addField(ctField, initializer);\n                try {\n                    cc.removeMethod(ctMethod);\n                }catch (Exception e){\n\n                }\n                cc.addMethod(ctMethod);\n                logger.info(\n                    \"[android.taobao.atlas.framework.FrameworkProperties] inject version \" +\n                        injectParam.version);\n            }\n\n            addField(pool, cc, \"bundleInfo\", injectParam.bundleInfo);\n            addField(pool, cc, \"autoStartBundles\", injectParam.autoStartBundles);\n            addField(pool, cc, \"preLaunch\", injectParam.preLaunch);\n            addField(pool, cc, \"group\", injectParam.group);\n            addField(pool, cc, \"outApp\", String.valueOf(injectParam.outApp));\n            addField(pool, cc, \"autoStart\", String.valueOf(injectParam.autoStart));\n            addField(pool, cc, \"blackDialogActivity\", String.valueOf(injectParam.blackDialogActivity));\n\n\n            if (null != injectParam.outputFile) {\n                Map output = new HashMap();\n                output.put(\"bundleInfo\", JSON.parseArray(injectParam.bundleInfo));\n                output.put(\"autoStartBundles\", injectParam.autoStartBundles);\n                output.put(\"preLaunch\", injectParam.preLaunch);\n                output.put(\"group\", injectParam.group);\n                output.put(\"outApp\", injectParam.outApp);\n                output.put(\"unit_tag\", injectParam.unit_tag);\n                output.put(\"autoStart\",injectParam.autoStart);\n                output.put(\"blackDialogActivity\",injectParam.blackDialogActivity);\n                FileUtils.write(injectParam.outputFile, JSON.toJSONString(output, true));\n            }\n\n        }\n\n        ClazzInjecter clazzInjecter = sInjecterMap.get(className);\n        if (null != clazzInjecter) {\n            Map<String, String> stringMap = clazzInjecter.getInjectFields();\n            if (!stringMap.isEmpty()) {\n                for (String key : stringMap.keySet()) {\n                    addField(pool, cc, key, stringMap.get(key));\n                }\n            }\n        }\n\n        if (!injectParam.removePreverify) {\n            Collection<String> refClasses = cc.getRefClasses();\n            if (refClasses.contains(\"com.taobao.verify.Verifier\")) {\n                return cc.toBytecode();\n            }\n            boolean flag = false;\n            if (className.equalsIgnoreCase(\"com.ut.mini.crashhandler.IUTCrashCaughtListner\")) {\n                flag = true;\n            }\n\n            if (cc.isInterface()) {\n                final CtClass defClass = pool.get(Class.class.getName());\n                CtField defField = new CtField(defClass, \"_inject_field__\", cc);\n                defField.setModifiers(Modifier.STATIC | Modifier.PUBLIC | Modifier.FINAL);\n                cc.addField(defField,\n                            CtField.Initializer.byExpr(\n                                \"Boolean.TRUE.booleanValue()?java.lang.String.class:com.taobao.verify.Verifier\"\n                                    + \".class;\"));\n            } else {\n                CtConstructor[] ctConstructors = cc.getDeclaredConstructors();\n                if (null != ctConstructors && ctConstructors.length > 0) {\n                    CtConstructor ctConstructor = ctConstructors[0];\n                    ctConstructor.insertBeforeBody(\n                        \"if(Boolean.FALSE.booleanValue()){java.lang.String.valueOf(com.taobao.verify.Verifier\"\n                            + \".class);}\");\n                } else {\n                    final CtClass defClass = pool.get(Class.class.getName());\n                    CtField defField = new CtField(defClass, \"_inject_field__\", cc);\n                    defField.setModifiers(Modifier.STATIC);\n                    cc.addField(defField,\n                                CtField.Initializer.byExpr(\n                                    \"Boolean.TRUE.booleanValue()?java.lang.String.class:com.taobao.verify\"\n                                        + \".Verifier.class;\"));\n                }\n            }\n        }\n        return cc.toBytecode();\n\n    }\n\n    private static void addField(ClassPool pool,\n                                 CtClass cc,\n                                 String key,\n                                 String value) throws NotFoundException, CannotCompileException {\n        if (StringUtils.isNotBlank(value)) {\n            try {\n                cc.removeField(cc.getField(key));\n            } catch (NotFoundException notfoundException) {\n            }\n            logger.info(\"inject key \" + key + \"->\" + value);\n            CtClass ctClass = pool.get(\"java.lang.String\");\n            CtField ctField = new CtField(ctClass, key, cc);\n            ctField.setModifiers(Modifier.STATIC | Modifier.PUBLIC);\n            CtField.Initializer initializer = CtField.Initializer.constant(value);\n            cc.addField(ctField, initializer);\n        }\n    }\n\n    /**\n     * Inject replacement operations for class files in the specified folder\n     *\n     * @param pool\n     * @param folder\n     * @param outFolder\n     * @return\n     * @throws IOException\n     * @throws CannotCompileException\n     * @throws NotFoundException\n     * @throws Exception\n     */\n    public static List<String> injectFolder(ClassPool pool,\n                                            File folder,\n                                            File outFolder,\n                                            InjectParam injectParam) throws Exception {\n        List<String> errorFiles = new ArrayList<String>();\n        if (folder.exists() && folder.isDirectory()) {\n            Collection<File> classFiles = FileUtils.listFiles(folder, new String[] {\"class\"}, true);\n            for (File classFile : classFiles) {\n                String className = toRelative(folder, classFile.getAbsolutePath());\n                File outClassFile = new File(outFolder, className);\n                outClassFile.getParentFile().mkdirs();\n                className = StringUtils.replace(className, File.separator, \".\");\n                className = className.substring(0, className.length() - 6);\n                byte[] codes;\n\n                codes = inject(pool, className, injectParam);\n                FileUtils.writeByteArrayToFile(outClassFile, codes);\n\n            }\n        }\n        return errorFiles;\n    }\n\n    /**\n     * The injection of code for the specified jar package\n     *\n     * @param inJar\n     * @param outJar\n     * @throws IOException\n     * @throws NotFoundException\n     * @throws CannotCompileException\n     */\n    public static List<String> inject(ClassPool pool,\n                                      File inJar,\n                                      File outJar,\n                                      InjectParam injectParam) throws Exception {\n        List<String> errorFiles = new ArrayList<String>();\n        JarFile jarFile = newJarFile(inJar);\n\n        outJar.getParentFile().mkdirs();\n        FileOutputStream fileOutputStream = new FileOutputStream(outJar);\n        JarOutputStream jos = new JarOutputStream(new BufferedOutputStream(fileOutputStream));\n        Enumeration<JarEntry> jarFileEntries = jarFile.entries();\n        JarEntry jarEntry = null;\n        while (jarFileEntries.hasMoreElements()) {\n            jarEntry = jarFileEntries.nextElement();\n            String name = jarEntry.getName();\n            String className = StringUtils.replace(name, File.separator, \"/\");\n            className = StringUtils.replace(className, \"/\", \".\");\n            className = StringUtils.substring(className, 0, className.length() - 6);\n            if (!StringUtils.endsWithIgnoreCase(name, \".class\")) {\n                InputStream inputStream = jarFile.getInputStream(jarEntry);\n                copyStreamToJar(inputStream, jos, name, jarEntry.getTime(), jarEntry);\n                IOUtils.closeQuietly(inputStream);\n            } else {\n                byte[] codes;\n\n                codes = inject(pool, className, injectParam);\n                InputStream classInstream = new ByteArrayInputStream(codes);\n                copyStreamToJar(classInstream, jos, name, jarEntry.getTime(), jarEntry);\n\n            }\n        }\n        jarFile.close();\n        IOUtils.closeQuietly(jos);\n        return errorFiles;\n    }\n\n    private static void copyStreamToJar(InputStream zin,\n                                        ZipOutputStream out,\n                                        String currentName,\n                                        long fileTime,\n                                        ZipEntry zipEntry) throws IOException {\n        // Create new entry for zip file.\n        ZipEntry newEntry = new ZipEntry(currentName);\n\n        // Make sure there is date and time set.\n        if (fileTime != -1) {\n            newEntry.setTime(fileTime); // If found set it into output file.\n        }\n        out.putNextEntry(newEntry);\n        if (zin != null) {\n            IOUtils.copy(zin, out);\n        }\n    }\n\n    private static JarFile newJarFile(File jar) throws IOException {\n        try {\n            return new JarFile(jar);\n        } catch (ZipException zex) {\n            throw new ZipException(\"error in opening zip file \" + jar);\n        }\n    }\n\n    public static String toRelative(File basedir, String absolutePath) {\n        absolutePath = absolutePath.replace('\\\\', '/');\n        String basedirPath = basedir.getAbsolutePath().replace('\\\\', '/');\n        String relative;\n        if (absolutePath.startsWith(basedirPath)) {\n            relative = absolutePath.substring(basedirPath.length());\n            if (relative.startsWith(\"/\")) {\n                relative = relative.substring(1);\n            }\n\n            if (relative.length() <= 0) {\n                relative = \".\";\n            }\n        } else {\n            relative = absolutePath;\n        }\n\n        return relative;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/classinject/FrameworkProperties.java",
    "content": "package com.taobao.android.builder.tools.classinject;\n\nimport com.taobao.android.builder.tools.bundleinfo.model.BasicBundleInfo;\n\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * Created by chenhjohn on 2017/4/28.\n */\n\npublic class FrameworkProperties {\n    public List<BasicBundleInfo> bundleInfo;\n\n    public String unit_tag;\n\n    public boolean outApp = false;\n\n    public String autoStartBundles;\n\n    public String preLaunch;\n\n    public String blackDialogActivity;\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/classinject/InjectParam.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.classinject;\n\nimport java.io.File;\nimport java.io.Serializable;\n\n/**\n * Created by wuzhong on 2016/11/24.\n */\npublic class InjectParam implements Serializable {\n\n    public String unit_tag;\n\n    public String version;\n\n    public String bundleInfo;\n\n    public String group;\n\n    public String autoStartBundles;\n\n    public String preLaunch;\n\n    public boolean outApp = false;\n\n    public boolean autoStart = true;\n\n    public String blackDialogActivity;\n\n    public boolean removePreverify;\n\n    public File outputFile;\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) { return true; }\n        if (o == null || getClass() != o.getClass()) { return false; }\n\n        InjectParam that = (InjectParam)o;\n\n        if (outApp != that.outApp) { return false; }\n        if (removePreverify != that.removePreverify) { return false; }\n        if (!version.equals(that.version)) { return false; }\n        if (!bundleInfo.equals(that.bundleInfo)) { return false; }\n        if (group != null ? !group.equals(that.group) : that.group != null) { return false; }\n        if (autoStartBundles != null ? !autoStartBundles.equals(that.autoStartBundles)\n            : that.autoStartBundles != null) {\n            return false;\n        }\n        return preLaunch != null ? preLaunch.equals(that.preLaunch) : that.preLaunch == null;\n    }\n\n    @Override\n    public int hashCode() {\n        int result = version.hashCode();\n        result = 31 * result + bundleInfo.hashCode();\n        result = 31 * result + (group != null ? group.hashCode() : 0);\n        result = 31 * result + (autoStartBundles != null ? autoStartBundles.hashCode() : 0);\n        result = 31 * result + (preLaunch != null ? preLaunch.hashCode() : 0);\n        result = 31 * result + (outApp ? 1 : 0);\n        result = 31 * result + (removePreverify ? 1 : 0);\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/command/CommandExecutor.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\npackage com.taobao.android.builder.tools.command;\n\nimport org.codehaus.plexus.util.cli.CommandLineException;\nimport org.codehaus.plexus.util.cli.CommandLineUtils;\nimport org.codehaus.plexus.util.cli.Commandline;\nimport org.codehaus.plexus.util.cli.StreamConsumer;\nimport org.codehaus.plexus.util.cli.shell.Shell;\nimport org.gradle.api.logging.Logger;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n *\n */\npublic interface CommandExecutor {\n    /**\n     * Sets the plexus logger.\n     *\n     * @param logger the plexus logger\n     */\n    void setLogger(Logger logger);\n\n    /**\n     * Executes the command for the specified executable and list of command options.\n     *\n     * @param executable the name of the executable (csc, xsd, etc).\n     * @param commands   the command options for the compiler/executable\n     * @throws ExecutionException if compiler or executable writes anything to the standard error stream or if the process returns a\n     *                            process result != 0.\n     */\n    void executeCommand(String executable, List<String> commands) throws ExecutionException;\n\n    /**\n     * Executes the command for the specified executable and list of command options.\n     *\n     * @param executable         the name of the executable (csc, xsd, etc).\n     * @param commands           the commands options for the compiler/executable\n     * @param failsOnErrorOutput if true, throws an <code>ExecutionException</code> if there the compiler or executable writes anything\n     *                           to the error output stream. By default, this value is true\n     * @throws ExecutionException if compiler or executable writes anything to the standard error stream (provided the\n     *                            failsOnErrorOutput is not false) or if the process returns a process result != 0.\n     */\n    void executeCommand(String executable, List<String> commands, boolean failsOnErrorOutput)\n            throws ExecutionException;\n\n    /**\n     * Executes the command for the specified executable and list of command options. If the compiler or executable is\n     * not within the environmental path, you should use this method to specify the working directory. Always use this\n     * method for executables located within the local maven repository.\n     *\n     * @param executable       the name of the executable (csc, xsd, etc).\n     * @param commands         the command options for the compiler/executable\n     * @param workingDirectory the directory where the command will be executed\n     * @throws ExecutionException if compiler or executable writes anything to the standard error stream (provided the\n     *                            failsOnErrorOutput is not false) or if the process returns a process result != 0.\n     */\n    void executeCommand(String executable, List<String> commands, File workingDirectory, boolean failsOnErrorOutput)\n            throws ExecutionException;\n\n    /**\n     * Returns the process result of executing the command. Typically a value of 0 means that the process executed\n     * successfully.\n     *\n     * @return the process result of executing the command\n     */\n    int getResult();\n\n    /**\n     * @return the process id for the executed command.\n     */\n    long getPid();\n\n    /**\n     * Returns the standard output from executing the command.\n     *\n     * @return the standard output from executing the command\n     */\n    String getStandardOut();\n\n    /**\n     * Returns the standard error from executing the command.\n     *\n     * @return the standard error from executing the command\n     */\n    String getStandardError();\n\n    /**\n     * Adds an environment variable with the specified name and value to the executor.\n     */\n    void addEnvironment(String name, String value);\n\n    void setErrorListener(ErrorListener errorListener);\n\n    void setCustomShell(Shell s);\n\n    void setCaptureStdOut(boolean captureStdOut);\n\n    void setCaptureStdErr(boolean captureStdErr);\n\n    /**\n     *\n     */\n    public interface ErrorListener {\n        boolean isError(String error);\n    }\n\n    /**\n     * Provides factory services for creating a default instance of the command executor.\n     */\n    class Factory {\n\n        /**\n         * Constructor\n         */\n        private Factory() {\n        }\n\n        private static final class DefaultCommandExecutor implements CommandExecutor {\n            private Map<String, String> environment;\n            /**\n             * Instance of a plugin logger.\n             */\n            private Logger logger;\n            /**\n             * Standard Out\n             */\n            private StreamConsumer stdOut;\n            /**\n             * Standard Error\n             */\n            private ErrorStreamConsumer stdErr;\n            /**\n             * Process result\n             */\n            private int result;\n            /*\n             */\n            private ErrorListener errorListener;\n            long pid;\n            private Commandline commandline;\n            private Shell customShell;\n\n            private boolean captureStdOut;\n            private boolean captureStdErr;\n\n            @Override\n            public void setLogger(Logger logger) {\n                this.logger = logger;\n            }\n\n            @Override\n            public void executeCommand(String executable, List<String> commands) throws ExecutionException {\n                executeCommand(executable, commands, null, true);\n            }\n\n            @Override\n            public void executeCommand(String executable, List<String> commands, boolean failsOnErrorOutput)\n                    throws ExecutionException {\n                executeCommand(executable, commands, null, failsOnErrorOutput);\n            }\n\n            @Override\n            public void executeCommand(String executable, List<String> commands, File workingDirectory,\n                                       boolean failsOnErrorOutput) throws ExecutionException {\n                if (commands == null) {\n                    commands = new ArrayList<String>();\n                }\n                stdOut = new StreamConsumerImpl(logger, captureStdOut);\n                stdErr = new ErrorStreamConsumer(logger, errorListener, captureStdErr);\n                commandline = new Commandline();\n                if (customShell != null) {\n                    commandline.setShell(customShell);\n                }\n                commandline.setExecutable(executable);\n\n                // Add the environment variables as needed\n                if (environment != null) {\n                    for (Map.Entry<String, String> entry : environment.entrySet()) {\n                        commandline.addEnvironment(entry.getKey(), entry.getValue());\n                    }\n                }\n\n                commandline.addArguments(commands.toArray(new String[commands.size()]));\n                if (workingDirectory != null && workingDirectory.exists()) {\n                    commandline.setWorkingDirectory(workingDirectory.getAbsolutePath());\n                }\n                try {\n                    logger.debug(\"ANDROID-040-000: Executing command: Commandline = \" + commandline);\n                    result = CommandLineUtils.executeCommandLine(commandline, stdOut, stdErr);\n                    if (logger != null) {\n                        logger.debug(\"ANDROID-040-000: Executed command: Commandline = \" + commandline + \", Result = \"\n                                + result);\n                    } else {\n                        System.out.println(\"ANDROID-040-000: Executed command: Commandline = \" + commandline\n                                + \", Result = \" + result);\n                    }\n                    if (failsOnErrorOutput && stdErr.hasError() || result != 0) {\n                        throw new ExecutionException(\"ANDROID-040-001: Could not execute: Command = \"\n                                + commandline.toString() + \", Result = \" + result);\n                    }\n                } catch (CommandLineException e) {\n                    throw new ExecutionException(\"ANDROID-040-002: Could not execute: Command = \"\n                            + commandline.toString() + \", Error message = \" + e.getMessage());\n                }\n                setPid(commandline.getPid());\n            }\n\n            @Override\n            public int getResult() {\n                return result;\n            }\n\n            @Override\n            public String getStandardOut() {\n                if (!captureStdOut) {\n                    throw new IllegalStateException(\"Unable to provide StdOut since it was not captured\");\n                }\n                return stdOut.toString();\n            }\n\n            @Override\n            public String getStandardError() {\n                if (!captureStdErr) {\n                    throw new IllegalStateException(\"Unable to provide StdOut since it was not captured\");\n                }\n                return stdErr.toString();\n            }\n\n            @Override\n            public void addEnvironment(String name, String value) {\n                if (environment == null) {\n                    environment = new HashMap<String, String>();\n                }\n                environment.put(name, value);\n            }\n\n            @Override\n            public void setErrorListener(ErrorListener errorListener) {\n                this.errorListener = errorListener;\n            }\n\n            public void setPid(long pid) {\n                this.pid = pid;\n            }\n\n            @Override\n            public long getPid() {\n                return pid;\n            }\n\n            @Override\n            public void setCustomShell(Shell shell) {\n                this.customShell = shell;\n            }\n\n            @Override\n            public void setCaptureStdOut(boolean captureStdOut) {\n                this.captureStdOut = captureStdOut;\n            }\n\n            @Override\n            public void setCaptureStdErr(boolean captureStdErr) {\n                this.captureStdErr = captureStdErr;\n            }\n        }\n\n        /**\n         * StreamConsumer instance that buffers the entire output\n         */\n        static class StreamConsumerImpl implements StreamConsumer {\n            private StringBuffer sb = new StringBuffer();\n            private final Logger logger;\n            private boolean captureStdOut;\n\n            public StreamConsumerImpl(Logger logger, boolean captureStdOut) {\n                this.logger = logger;\n                this.captureStdOut = captureStdOut;\n            }\n\n            @Override\n            public void consumeLine(String line) {\n                if (captureStdOut) {\n                    sb.append(line);\n                }\n                if (logger != null) {\n                    logger.debug(line);\n                }\n            }\n\n            /**\n             * Returns the stream\n             *\n             * @return the stream\n             */\n            @Override\n            public String toString() {\n                return sb.toString();\n            }\n        }\n\n        /**\n         * Provides behavior for determining whether the command utility wrote anything to the Standard Error Stream.\n         * NOTE: I am using this to decide whether to fail the NMaven build. If the compiler implementation chooses to\n         * write warnings to the error stream, then the build will fail on warnings!!!\n         */\n        static class ErrorStreamConsumer implements StreamConsumer {\n            /**\n             * Is true if there was anything consumed from the stream, otherwise false\n             */\n            private boolean error;\n            /**\n             * Buffer to store the stream\n             */\n            private StringBuffer sbe = new StringBuffer();\n            private final Logger logger;\n            private final ErrorListener errorListener;\n            private boolean captureStdErr;\n\n            public ErrorStreamConsumer(Logger logger, ErrorListener errorListener, boolean captureStdErr) {\n                this.logger = logger;\n                this.errorListener = errorListener;\n                this.captureStdErr = captureStdErr;\n\n                if (logger == null) {\n                    System.out.println(\"ANDROID-040-003: Error Log not set: Will not output error logs\");\n                }\n                error = false;\n            }\n\n            @Override\n            public void consumeLine(String line) {\n                if (captureStdErr) {\n                    sbe.append(line);\n                }\n                if (logger != null) {\n                    logger.info(line);\n                }\n                if (errorListener != null) {\n                    error = errorListener.isError(line);\n                } else {\n                    error = true;\n                }\n            }\n\n            /**\n             * Returns false if the command utility wrote to the Standard Error Stream, otherwise returns true.\n             *\n             * @return false if the command utility wrote to the Standard Error Stream, otherwise returns true.\n             */\n            public boolean hasError() {\n                return error;\n            }\n\n            /**\n             * Returns the error stream\n             *\n             * @return error stream\n             */\n            @Override\n            public String toString() {\n                return sbe.toString();\n            }\n        }\n\n        /**\n         * Returns a default instance of the command executor\n         *\n         * @return a default instance of the command executor\n         */\n        public static CommandExecutor createDefaultCommmandExecutor() {\n            return new DefaultCommandExecutor();\n\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/command/ExecutionException.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\npackage com.taobao.android.builder.tools.command;\n\n/**\n *\n */\npublic class ExecutionException extends Exception\n{\n\n    static final long serialVersionUID = - 7843278034782074384L;\n\n    /**\n     * Constructs an <code>ExecutionException</code>  with no exception message.\n     */\n    public ExecutionException()\n    {\n        super();\n    }\n\n    /**\n     * Constructs an <code>ExecutionException</code> with the specified exception message.\n     *\n     * @param message the exception message\n     */\n    public ExecutionException(String message )\n    {\n        super( message );\n    }\n\n    /**\n     * Constructs an <code>ExecutionException</code> with the specified exception message and cause of the exception.\n     *\n     * @param message the exception message\n     * @param cause   the cause of the exception\n     */\n    public ExecutionException(String message, Throwable cause )\n    {\n        super( message, cause );\n    }\n\n    /**\n     * Constructs an <code>ExecutionException</code> with the cause of the exception.\n     *\n     * @param cause the cause of the exception\n     */\n    public ExecutionException(Throwable cause )\n    {\n        super( cause );\n    }\n}\n\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/concurrent/ExecutorServicesHelper.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\npackage com.taobao.android.builder.tools.concurrent;\n\nimport java.util.List;\nimport java.util.concurrent.BlockingQueue;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.stream.Stream;\n\nimport org.gradle.api.GradleException;\nimport org.slf4j.Logger;\n\npublic class ExecutorServicesHelper {\n\n    // Number of threads started\n    private ExecutorService executorService = null;\n\n    private Logger logger;\n\n    private String name;\n\n    private int threadCount;\n\n    public ExecutorServicesHelper(String name, Logger logger, int threadCount) {\n\n        this.name = name;\n        this.logger = logger;\n\n        if (threadCount == 0) {\n            threadCount = (Runtime.getRuntime().availableProcessors() / 2) + 1;\n        }\n\n        this.threadCount = threadCount;\n        //\n    }\n\n    public AtomicInteger index = new AtomicInteger(0);\n\n    private boolean hasException;\n\n    private Throwable exception;\n\n    public void execute(List<Runnable> runnables) throws InterruptedException {\n\n        if (runnables.isEmpty()) {\n            return;\n        }\n\n        Stream<Runnable> stream = runnables.stream();\n        if (threadCount > 1) {\n            stream = stream.parallel();\n        }\n\n        stream.forEach((Runnable runnable) -> {\n            try {\n\n                if (!hasException) {\n                    info(\"excute \" +\n                             name +\n                             \" task at \" +\n                             index.incrementAndGet() +\n                             \"/\" +\n                             runnables.size());\n                    runnable.run();\n                }\n            } catch (Throwable gradleException) {\n                hasException = true;\n                exception = gradleException;\n            }\n        });\n\n        if (hasException) {\n            throw new GradleException(exception.getMessage(), exception);\n        }\n    }\n\n    public <T> void execute(BlockingQueue<T> blockingQueue,\n                            Handler<T> handler) throws InterruptedException {\n\n        if (blockingQueue.isEmpty()) {\n            return;\n        }\n\n        if (null == this.executorService){\n            this.executorService = Executors.newFixedThreadPool(threadCount);\n        }\n\n        final CountDownLatch countDownLatch = new CountDownLatch(this.threadCount);\n\n        for (int i = 0; i < this.threadCount; i++) {\n            this.executorService.execute(new Runnable() {\n                @Override\n                public void run() {\n\n                    try {\n\n                        while (true) {\n\n                            T t = blockingQueue.poll();\n\n                            if (null == t) {\n                                break;\n                            }\n\n                            handler.handle(t);\n                        }\n                    } catch (GradleException gradleException) {\n                        hasException = true;\n                        exception = gradleException;\n                    } finally {\n                        countDownLatch.countDown();\n                    }\n                }\n            });\n        }\n\n        countDownLatch.await();\n\n        if (hasException) {\n            throw new GradleException(exception.getMessage(), exception);\n        }\n    }\n\n    private void info(String msg) {\n        if (null != logger) {\n            logger.info(msg);\n        } else {\n            System.out.println(msg);\n        }\n    }\n\n    public static interface Handler<T> {\n\n        public void handle(T t);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/diff/DiffResExtractor.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.diff;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.Set;\nimport java.util.UUID;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.tools.MD5Util;\nimport com.taobao.android.builder.tools.zip.ZipUtils;\nimport groovy.lang.Closure;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.filefilter.TrueFileFilter;\nimport org.gradle.api.file.CopySpec;\n\nimport static com.taobao.android.builder.tools.xml.XmlHelper.removeStringValue;\n\n/**\n * Created by wuzhong on 2016/9/30.\n */\npublic class DiffResExtractor {\n\n    /**\n     * assets : Compare apk directly\n     * res : Through diffResFiles , Go to apk validation\n     *\n     * @param appVariantContext\n     * @param diffResFiles\n     * @param currentApk\n     * @param baseApk\n     * @param fullResDir\n     * @param destDir\n     * @throws IOException\n     */\n    public static void extractDiff(AppVariantContext appVariantContext, Set<String> diffResFiles, File currentApk,\n                                   File baseApk, File fullResDir, File destDir, boolean fullValues) throws IOException {\n\n        if (!currentApk.exists() || !baseApk.exists() || !fullResDir.exists()) {\n            return;\n        }\n\n        FileUtils.deleteDirectory(destDir);\n        destDir.mkdirs();\n\n        File tmpFolder = new File(destDir.getParentFile(), \"tmp-diffRes\");\n        FileUtils.deleteDirectory(tmpFolder);\n        tmpFolder.mkdirs();\n\n        File apkDir = new File(tmpFolder, \"newApkDir\");\n        File baseApkDir = new File(tmpFolder, \"baseApkDir\");\n\n        ZipUtils.unzip(currentApk, apkDir.getAbsolutePath());\n        ZipUtils.unzip(baseApk, baseApkDir.getAbsolutePath());\n\n        //compare res and assets\n        Collection<File> files = FileUtils.listFiles(apkDir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);\n\n        int basePathLength = apkDir.getAbsolutePath().length();\n\n        //List<String> diffResPath = new ArrayList<String>();\n\n        //Calculate the assets\n        for (File file : files) {\n\n            String relativePath = file.getAbsolutePath().substring(basePathLength);\n\n            if (!relativePath.startsWith(\"/assets/\")) {\n                continue;\n            }\n\n            File baseFile = new File(baseApkDir, relativePath);\n            if (!baseFile.exists() || !MD5Util.getFileMD5(file).equals(MD5Util.getFileMD5(baseFile))) {\n                FileUtils.copyFile(file, new File(destDir, relativePath));\n            }\n        }\n\n        //Calculate the res\n        for (String diffFile : diffResFiles) {\n\n            File baseFile = new File(baseApkDir, diffFile);\n            File currentFile = new File(apkDir, diffFile);\n\n            if (baseFile.exists() && currentFile.exists() && MD5Util.getFileMD5(baseFile).equals(MD5Util.getFileMD5(\n                currentFile))) {\n                continue;\n            }\n\n            //copy file\n            File rawFile = new File(fullResDir, diffFile);\n            if (rawFile.exists()) {\n                FileUtils.copyFile(rawFile, new File(destDir, diffFile));\n            }\n        }\n\n        // //Resource. Arsc must be generated\n        File resDir = new File(destDir, \"res\");\n        File valuesDir = new File(resDir, \"values\");\n        if (fullValues) {\n            FileUtils.forceMkdir(valuesDir);\n            appVariantContext.getProject().copy(new Closure(DiffResExtractor.class) {\n                public Object doCall(CopySpec cs) {\n                    cs.from(fullResDir);\n                    cs.into(destDir);\n                    cs.include(\"res/values*/**\");\n\n                    return cs;\n                }\n            });\n\n            // FileUtils.copyFile(new File(fullResDir, \"res/values/values.xml\"),\n            //                    new File(destDir, \"res/values/values.xml\"));\n        } else {\n            if (!resDir.exists()) {\n                FileUtils.forceMkdir(valuesDir);\n                File stringsFile = new File(valuesDir, \"strings.xml\");\n                UUID uuid = UUID.randomUUID();\n                FileUtils.writeStringToFile(stringsFile,\n                                            String.format(\n                                                \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n<resources>\\n    <string \"\n                                                    + \"name=\\\"%s\\\">%s</string>\\n</resources>\\n\",\n                                                uuid,\n                                                uuid),\n                                            \"UTF-8\",\n                                            false);\n            }\n        }\n\n        //XML Settings values.\n        File valuesXml = new File(resDir, \"values/values.xml\");\n\n        AtlasBuildContext.sBuilderAdapter.apkInjectInfoCreator.injectTpatchValuesRes(appVariantContext, valuesXml);\n        try {\n            removeStringValue(valuesXml, \"ttid\");\n            removeStringValue(valuesXml, \"config_channel\");\n        } catch (Exception e) {\n            throw new RuntimeException(e);\n        }\n\n        final Pattern densityOnlyPattern = Pattern.compile(\"[a-zA-Z]+-[a-zA-Z]+dpi\");\n        if (resDir.exists()) {\n            File[] resDirs = resDir.listFiles();\n            if (resDirs != null) {\n                for (File file : resDirs) {\n                    Matcher m = densityOnlyPattern.matcher(file.getName());\n                    if (m.matches()) {\n                        FileUtils.moveDirectory(file, new File(file.getAbsolutePath() + \"-v3\"));\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/groovy/ClosureFactory.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.groovy;\n\nimport groovy.lang.Closure;\nimport groovy.lang.GroovyClassLoader;\nimport groovy.lang.GroovyObject;\nimport org.apache.commons.lang.StringUtils;\n\nimport java.io.IOException;\n\n/**\n * Created by wuzhong on 2016/12/1.\n */\npublic class ClosureFactory {\n\n    public static Closure<?> buildClosure(String... strings) throws IOException {\n\n        Closure<?> closure = null;\n\n        // Create a method returning a closure\n        StringBuilder sb = new StringBuilder(\"def closure() { { script -> \");\n        sb.append(StringUtils.join(strings, \"\\n\"));\n        sb.append(\" } }\");\n\n        // Create an anonymous class for the method\n        GroovyClassLoader loader = new GroovyClassLoader();\n        Class<?> groovyClass = loader.parseClass(sb.toString());\n\n        try {\n            // Create an instance of the class\n            GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();\n\n            // Invoke the object's method and thus obtain the closure\n            closure = (Closure<?>) groovyObject.invokeMethod(\"closure\", null);\n        } catch (Throwable e) {\n            throw new RuntimeException(e);\n        } finally {\n            loader.close();\n        }\n\n        return closure;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/guide/AtlasConfigField.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.guide;\n\n/**\n * Created by wuzhong on 2016/12/30.\n */\npublic class AtlasConfigField {\n\n    public String name;\n\n    public String title;\n\n    public String desc;\n\n    public String group;\n\n    public int order;\n\n    public String value;\n\n    public int groupOrder;\n\n    public String variantName = \"\";\n\n    public String type;\n\n    public boolean advanced;\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/guide/AtlasConfigHelper.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.guide;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.Map;\n\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.extension.annotation.Config;\nimport com.taobao.android.builder.extension.annotation.ConfigGroup;\nimport org.apache.commons.beanutils.BeanUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.gradle.api.NamedDomainObjectContainer;\n\n/**\n * Created by wuzhong on 2016/12/31.\n *\n * @author wuzhong\n */\npublic class AtlasConfigHelper {\n\n    public static void setProperty(Object object,\n                                   Map<String, String> paramMap)\n        throws InvocationTargetException, NoSuchFieldException, InstantiationException, IllegalAccessException {\n\n        for (String key : paramMap.keySet()) {\n\n            String value = paramMap.get(key);\n            if (key.startsWith(\"mtl.\")) {\n                key = key.substring(4);\n            }\n\n            setProperty(object, key, value);\n        }\n    }\n\n    public static void setProperty(Object object,\n                                   String fieldName,\n                                   String value)\n        throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException {\n\n        String[] fieldNames = fieldName.split(\"\\\\.\");\n\n        Object last = object;\n        for (int i = 0; i < fieldNames.length - 1; i++) {\n\n            String field = fieldNames[i];\n\n            if (last instanceof NamedDomainObjectContainer) {\n                last = ((NamedDomainObjectContainer)last).maybeCreate(field);\n            } else {\n                Field declaredField = last.getClass().getField(field);\n                declaredField.setAccessible(true);\n\n                if (null == declaredField.get(last)) {\n                    Object newInstance = declaredField.getType()\n                        .getConstructors()\n                        .getClass()\n                        .newInstance();\n                    declaredField.set(last, newInstance);\n                }\n\n                last = declaredField.get(last);\n            }\n        }\n\n        BeanUtils.setProperty(last, fieldNames[fieldNames.length - 1], value);\n    }\n\n    public static List<AtlasConfigField> readConfig(AtlasExtension atlasExtension, String prefix)\n        throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {\n\n        List<AtlasConfigField> configFieldList = new ArrayList<AtlasConfigField>();\n\n        readConfig(atlasExtension, prefix, configFieldList, 0, \"\");\n\n        Collections.sort(configFieldList, new Comparator<AtlasConfigField>() {\n            @Override\n            public int compare(AtlasConfigField o1, AtlasConfigField o2) {\n\n                if (o1.groupOrder != o2.groupOrder) {\n                    return o1.groupOrder - o2.groupOrder;\n                }\n\n                int compare = String.CASE_INSENSITIVE_ORDER.compare(o1.group, o2.group);\n                if (0 != compare) {\n                    return compare;\n                }\n\n                if (!o1.variantName.equals(o2.variantName)) {\n                    return o1.variantName.equals(\"release\") ? 1 : -1;\n                }\n\n                return o1.order - o2.order;\n            }\n        });\n\n        return configFieldList;\n    }\n\n    private static void readConfig(Object object,\n                                   String prefix,\n                                   List<AtlasConfigField> configFieldList,\n                                   int groupOrder,\n                                   String variantName) throws IllegalAccessException {\n\n        if (null == object) {\n            return;\n        }\n\n        for (Field field : getAllFields(object.getClass())) {\n\n            field.setAccessible(true);\n\n            Config config = field.getAnnotation(Config.class);\n            if (null != config) {\n                AtlasConfigField configField = new AtlasConfigField();\n                configField.name = prefix + \".\" + field.getName();\n                configField.order = config.order();\n                configField.desc = config.message();\n                Object obj = field.get(object);\n                String value = \"\";\n                if (obj != null && !(obj instanceof Map) && !(obj instanceof List)) {\n                    value = String.valueOf(obj);\n                }\n                configField.value = value;\n                configField.groupOrder = groupOrder;\n                configField.variantName = variantName;\n                configField.type = field.getType().getSimpleName();\n                configField.advanced = config.advance();\n                configField.group = config.group();\n\n                String variant = StringUtils.isEmpty(variantName) ? \"\" : (\"[\" + variantName + \"]\");\n                String title = StringUtils.isEmpty(config.title()) ? config.message() : config.title();\n                configField.title = variant + title;\n\n                configFieldList.add(configField);\n\n                continue;\n            }\n\n            ConfigGroup configGroup = field.getAnnotation(ConfigGroup.class);\n            if (null != configGroup) {\n\n                Object nestedValue = field.get(object);\n\n                if (nestedValue instanceof NamedDomainObjectContainer) {\n\n                    readConfig(((NamedDomainObjectContainer)nestedValue).maybeCreate(\"debug\"),\n                               prefix + \".\" + field.getName() + \".debug\",\n                               configFieldList,\n                               configGroup.order(),\n                               \"debug\");\n                    readConfig(((NamedDomainObjectContainer)nestedValue).maybeCreate(\"release\"),\n                               prefix + \".\" + field.getName() + \".release\",\n                               configFieldList,\n                               configGroup.order(),\n                               \"release\");\n                } else {\n\n                    readConfig(nestedValue,\n                               prefix + \".\" + field.getName(),\n                               configFieldList,\n                               configGroup.order(),\n                               \"\");\n                }\n            }\n        }\n    }\n\n    public static List<Field> getAllFields(Class clazz) {\n        List<Field> fieldList = new ArrayList<Field>();\n        getAllFields(fieldList, clazz);\n        return fieldList;\n    }\n\n    private static List<Field> getAllFields(List<Field> fields, Class<?> type) {\n        fields.addAll(Arrays.asList(type.getDeclaredFields()));\n\n        if (type.getSuperclass() != null) {\n            fields = getAllFields(fields, type.getSuperclass());\n        }\n\n        return fields;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/guide/AtlasExtensionOutput.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.guide;\n\nimport com.android.builder.signing.DefaultSigningConfig;\nimport com.taobao.android.builder.extension.*;\nimport org.apache.commons.beanutils.BeanUtils;\nimport org.apache.commons.beanutils.ConvertUtils;\nimport org.apache.commons.beanutils.converters.FileConverter;\n\n/**\n * Created by wuzhong on 2017/1/11.\n */\npublic class AtlasExtensionOutput extends AtlasExtension {\n\n    static {\n\n        ConvertUtils.register(new FileConverter(null), java.io.File.class);\n\n    }\n\n    public TBuildType tBuildType;\n\n    public AtlasExtensionOutput(AtlasExtension atlasExtension, String name) {\n\n        this.setAtlasEnabled(atlasExtension.isAtlasEnabled());\n\n        this.manifestOptions = new ManifestOptions();\n        this.tBuildConfig = new TBuildConfig();\n        copyProps(this.manifestOptions, atlasExtension.getManifestOptions());\n        copyProps(this.tBuildConfig, atlasExtension.getTBuildConfig());\n\n        this.tBuildType = new TBuildType(name);\n\n        TBuildType mtlBuildTypeValue = (TBuildType)atlasExtension.getBuildTypes().findByName(name);\n        if (null == mtlBuildTypeValue) {\n            return;\n        }\n//        mtlBuildTypeValue.setDexConfig((DexConfig) atlasExtension.dexConfigs.maybeCreate(name));\n\n        tBuildType.setBaseApDependency(mtlBuildTypeValue.getBaseApDependency());\n        tBuildType.setBaseApFile(mtlBuildTypeValue.getBaseApFile());\n        tBuildType.setSigningConfig(new DefaultSigningConfig(name));\n        tBuildType.setPatchConfig(new PatchConfig(name));\n        tBuildType.setDexConfig(new DexConfig(name));\n\n        copyProps(tBuildType.getSigningConfig(), mtlBuildTypeValue.getSigningConfig());\n        copyProps(tBuildType.getPatchConfig(), mtlBuildTypeValue.getPatchConfig());\n        copyProps(tBuildType.getDexConfig(),mtlBuildTypeValue.getDexConfig());\n    }\n\n    private void copyProps(Object dest, Object orig) {\n        if (orig == null) {\n            return;\n        }\n        try {\n            BeanUtils.copyProperties(dest, orig);\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/ideaplugin/ApDownloader.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.ideaplugin;\n\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.tools.MD5Util;\nimport org.apache.commons.io.FileUtils;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.InputStreamReader;\nimport java.net.URL;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * Created by wuzhong on 16/8/29.\n */\npublic class ApDownloader {\n\n//    String matcher = \"buildConfigId=(\\\\d+)\";\n\n    public static File downloadAP(String mtlConfigUrl, File root) throws Exception {\n\n        Pattern p = Pattern.compile(\"buildConfigId=(\\\\d+)\");\n        Matcher m = p.matcher(mtlConfigUrl);\n\n        String configId = \"\";\n\n        if (m.find()) {\n            configId = m.group(1);\n        }\n\n        String apiUrl = \"http://\" +\n                AtlasBuildContext.sBuilderAdapter.tpatchHistoryUrl + \"/rpc/androidPlugin/getAp.json?buildConfigId=\" + configId;\n\n        URL api = new URL(apiUrl);\n        BufferedReader in = new BufferedReader(\n                new InputStreamReader(api.openStream()));\n\n        String inputLine = in.readLine();\n        in.close();\n\n        String downloadUrl = inputLine.trim().replace(\"\\\"\", \"\").replace(\"\\\\\", \"\");\n\n        File file = new File(root, MD5Util.getMD5(downloadUrl) + \".ap\");\n        if (file.exists()) {\n            return file;\n        }\n\n        URL downloadApi = new URL(downloadUrl);\n        System.out.println(\"start to download ap from \" + downloadUrl);\n\n        File tmpFile = new File(file.getParentFile(), String.valueOf(System.currentTimeMillis()));\n\n        FileUtils.copyURLToFile(downloadApi, file);\n        return file;\n\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/ideaplugin/AwoPropHandler.java",
    "content": "\n/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.ideaplugin;\n\nimport com.taobao.android.builder.extension.BundleConfig;\nimport com.taobao.android.builder.extension.TBuildType;\nimport com.taobao.android.builder.tools.EnvHelper;\nimport org.apache.commons.lang3.StringUtils;\nimport org.gradle.api.tasks.StopExecutionException;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.util.Properties;\n\n/**\n * Created by wuzhong on 16/9/1.\n */\npublic class AwoPropHandler {\n\n    public static final String MTL_URL = \"mtl_url\";\n    public static final String AP_PATH = \"ap_path\";\n    public static final String REFRESH_AP = \"refreshAp\";\n    public static final String SUPPORT_DYN = \"support_dyn\";\n    public static final String SUPPORT_APK = \"support_apk\";\n\n    public void process(TBuildType buildType, BundleConfig bundleConfig) throws Exception {\n\n        String propfile = EnvHelper.getEnv(\"awoprop\");\n\n        if (StringUtils.isEmpty(propfile)) {\n            return;\n        }\n\n        Properties properties = new Properties();\n        properties.load(new FileInputStream(propfile));\n\n        String ap_path = properties.getProperty(AP_PATH);\n        boolean refresh_ap = \"true\".equals(properties.getProperty(REFRESH_AP));\n        String mtl_url = properties.getProperty(MTL_URL);\n\n        if (!refresh_ap && StringUtils.isNotEmpty(ap_path) && new File(ap_path).exists()) {\n            //not need download\n            System.out.println(\"[awo] ap file exist\");\n        }\n\n        if (StringUtils.isEmpty(mtl_url)) {\n            throw new StopExecutionException(\"mtl_url is not configed\");\n        }\n\n        ap_path = ApDownloader.downloadAP(mtl_url, new File(propfile).getParentFile()).getAbsolutePath();\n        properties.setProperty(AP_PATH, ap_path);\n        properties.store(new FileOutputStream(propfile), \"update path\");\n\n        buildType.setBaseApFile(new File(ap_path));\n\n        bundleConfig.setAwoBuildEnabled(true);\n        bundleConfig.setAwoDynDeploy(\"true\".equals(properties.getProperty(SUPPORT_DYN, \"true\")));\n        bundleConfig.setAwoApkBuild(\"true\".equals(properties.getProperty(SUPPORT_APK, \"true\")));\n    }\n\n}\n\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/jarmerge/JarMergerWithOverride.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.jarmerge;\n\nimport com.android.annotations.NonNull;\nimport com.android.build.gradle.internal.LoggerWrapper;\nimport com.android.builder.packaging.ZipAbortException;\nimport com.android.builder.packaging.ZipEntryFilter;\nimport com.android.utils.FileUtils;\nimport com.android.utils.ILogger;\nimport com.google.common.collect.HashMultimap;\nimport com.google.common.collect.Multimap;\nimport com.google.common.io.Closer;\n\nimport org.gradle.api.logging.Logging;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarOutputStream;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\n\n/**\n * Jar Merger class.,\n */\npublic class JarMergerWithOverride {\n\n    private final byte[] buffer = new byte[8192];\n\n    @NonNull\n    private final ILogger logger = new LoggerWrapper(Logging.getLogger(JarMergerWithOverride.class));\n\n    @NonNull\n    private final File jarFile;\n\n    private ZipEntryFilter filter;\n\n    private Closer closer;\n\n    private JarOutputStream jarOutputStream;\n\n    private Multimap<String, String> duplicates = HashMultimap.create(10000, 3);\n\n    public JarMergerWithOverride(@NonNull File jarFile) throws IOException {\n        this.jarFile = jarFile;\n    }\n\n    private void init() throws IOException {\n        if (closer == null) {\n            FileUtils.mkdirs(jarFile.getParentFile());\n\n            closer = Closer.create();\n\n            FileOutputStream fos = closer.register(new FileOutputStream(jarFile));\n            jarOutputStream = closer.register(new JarOutputStream(fos));\n        }\n    }\n\n    /**\n     * Sets a list of regex to exclude from the jar.\n     */\n    public void setFilter(@NonNull ZipEntryFilter filter) {\n        this.filter = filter;\n    }\n\n    public void addFolder(@NonNull File folder) throws IOException {\n        init();\n        try {\n            addFolder(folder, \"\");\n        } catch (ZipAbortException e) {\n            throw new IOException(e);\n        }\n    }\n\n    private void addFolder(@NonNull File folder,\n                           @NonNull String path) throws IOException, ZipAbortException {\n        logger.verbose(\"addFolder(%1$s, %2$s)\", folder, path);\n        File[] files = folder.listFiles();\n        if (files != null) {\n            for (File file : files) {\n                if (file.isFile()) {\n                    String entryPath = path + file.getName();\n                    if (filter == null || filter.checkEntry(entryPath)) {\n                        logger.verbose(\"addFolder(%1$s, %2$s): entry %3$s\",\n                                       folder,\n                                       path,\n                                       entryPath);\n                        duplicates.put(path + file.getName(), folder.getAbsolutePath());\n                        if (duplicates.get(path + file.getName()).size() > 1) {\n                            logger.info(\"[Duplicated]\" +\n                                                path +\n                                                file.getName() +\n                                                \":\" +\n                                                folder.getAbsolutePath() +\n                                                \":\" +\n                                                duplicates.get(path + file.getName()));\n                            continue;\n                        }\n\n                        // new entry\n                        jarOutputStream.putNextEntry(new JarEntry(entryPath));\n\n                        // put the file content\n                        Closer localCloser = Closer.create();\n                        try {\n                            FileInputStream fis = localCloser.register(new FileInputStream(file));\n                            int count;\n                            while ((count = fis.read(buffer)) != -1) {\n                                jarOutputStream.write(buffer, 0, count);\n                            }\n                        } finally {\n                            localCloser.close();\n                        }\n\n                        // close the entry\n                        jarOutputStream.closeEntry();\n                    }\n                } else if (file.isDirectory()) {\n                    addFolder(file, path + file.getName() + \"/\");\n                }\n            }\n        }\n    }\n\n    public void addJar(@NonNull File file) throws IOException {\n        addJar(file, false);\n    }\n\n    public void addJar(@NonNull File file, boolean removeEntryTimestamp) throws IOException {\n        logger.verbose(\"addJar(%1$s)\", file);\n        init();\n\n        Closer localCloser = Closer.create();\n        try {\n            FileInputStream fis = localCloser.register(new FileInputStream(file));\n            ZipInputStream zis = localCloser.register(new ZipInputStream(fis));\n\n            // loop on the entries of the jar file package and put them in the final jar\n            ZipEntry entry;\n            while ((entry = zis.getNextEntry()) != null) {\n                // do not take directories or anything inside a potential META-INF folder.\n                if (entry.isDirectory()) {\n                    continue;\n                }\n\n                String name = entry.getName();\n                if (filter != null && !filter.checkEntry(entry.getName())) {\n                    continue;\n                }\n                JarEntry newEntry;\n\n                // Preserve the STORED method of the input entry.\n                if (entry.getMethod() == JarEntry.STORED) {\n                    newEntry = new JarEntry(entry);\n                } else {\n                    // Create a new entry so that the compressed len is recomputed.\n                    newEntry = new JarEntry(name);\n                }\n                if (removeEntryTimestamp) {\n                    newEntry.setTime(0);\n                }\n\n                // add the entry to the jar archive\n                logger.verbose(\"addJar(%1$s): entry %2$s\", file, name);\n                duplicates.put(name, file.getAbsolutePath());\n                if (duplicates.get(name).size() > 1) {\n                    logger.info(\"[Duplicated]\" +\n                                        name +\n                                        \":\" +\n                                        file.getAbsolutePath() +\n                                        \":\" +\n                                        duplicates.get(name));\n                    continue;\n                }\n\n                jarOutputStream.putNextEntry(newEntry);\n\n                // read the content of the entry from the input stream, and write it into the archive.\n                int count;\n                while ((count = zis.read(buffer)) != -1) {\n                    jarOutputStream.write(buffer, 0, count);\n                }\n\n                // close the entries for this file\n                jarOutputStream.closeEntry();\n                zis.closeEntry();\n            }\n        } catch (ZipAbortException e) {\n            throw new IOException(\"check exception\",e);\n        } finally {\n            localCloser.close();\n        }\n    }\n\n    public void addEntry(@NonNull String path, @NonNull byte[] bytes) throws IOException {\n        init();\n\n        jarOutputStream.putNextEntry(new JarEntry(path));\n        jarOutputStream.write(bytes);\n        jarOutputStream.closeEntry();\n    }\n\n    public void close() throws IOException {\n        if (closer != null) {\n            closer.close();\n        }\n    }\n\n    public Multimap<String, String> getDuplicates() {\n        return duplicates;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/log/FileLogger.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.log;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Timer;\nimport java.util.TimerTask;\n\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.Project;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * Created by wuzhong on 2017/6/8.\n */\npublic class FileLogger {\n\n    private static Logger sLogger = LoggerFactory.getLogger(FileLogger.class);\n    public static Project project;\n\n    private List<String> lines = new ArrayList<>();\n\n    private String fileName;\n    private File logFile;\n\n    private static Map<String, FileLogger> sFileLoggerMap = new HashMap<>();\n\n    private static Timer sTimer;\n    static {\n        sTimer = new Timer(\"localfilelog\");\n        sTimer.scheduleAtFixedRate(new TimerTask() {\n            @Override\n            public void run() {\n                if (null != project){\n                    writeToFile(project);\n                }\n            }\n        }, 10*1000, 10*1000);\n    }\n\n    public void log(String content) {\n\n        if (null == project || !project.getGradle().getStartParameter().isProfile()) {\n            return;\n        }\n\n        lines.add(content);\n\n    }\n\n    public static FileLogger getInstance(String fileName) {\n        FileLogger fileLogger = sFileLoggerMap.get(fileName);\n        if (null == fileLogger) {\n            fileLogger = new FileLogger();\n            fileLogger.fileName = fileName;\n            sFileLoggerMap.put(fileName, fileLogger);\n        }\n        return fileLogger;\n    }\n\n    private File getLogFile() {\n        if (null != logFile){\n            return logFile;\n        }\n        if (null == project){\n            return null;\n        }\n        File outputDir = new File(project.getBuildDir(), \"logs\");\n        outputDir.mkdirs();\n        logFile = new File(outputDir, fileName + \".log\");\n        return logFile;\n    }\n\n    public static void shutDown(Project project){\n        sTimer.cancel();\n        writeToFile(project);\n    }\n\n    private static synchronized void writeToFile(Project project) {\n\n        if (sFileLoggerMap.isEmpty()) {\n            return;\n        }\n\n        new ArrayList<>(sFileLoggerMap.values()).parallelStream().forEach(fileLogger -> {\n            try {\n                if (fileLogger.lines.isEmpty()){\n                    return;\n                }\n                FileUtils.writeLines(fileLogger.getLogFile(),  new ArrayList<>(fileLogger.lines),true);\n                fileLogger.lines = new ArrayList<>();\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        });\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/log/LogOutputListener.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.log;\n\nimport org.gradle.BuildListener;\nimport org.gradle.BuildResult;\nimport org.gradle.api.Project;\nimport org.gradle.api.initialization.Settings;\nimport org.gradle.api.invocation.Gradle;\n\n/**\n * Created by wuzhong on 2017/6/8.\n */\npublic class LogOutputListener {\n\n    public static void addListener(Project project) {\n\n        FileLogger.project = project.getRootProject();\n\n        project.getGradle().addListener(new BuildListener() {\n            @Override\n            public void buildStarted(Gradle gradle) {\n            }\n\n            @Override\n            public void settingsEvaluated(Settings settings) {\n\n            }\n\n            @Override\n            public void projectsLoaded(Gradle gradle) {\n\n            }\n\n            @Override\n            public void projectsEvaluated(Gradle gradle) {\n\n            }\n\n            @Override\n            public void buildFinished(BuildResult buildResult) {\n                FileLogger.shutDown(project);\n            }\n        });\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/manifest/AtlasProxy.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.manifest;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\nimport com.google.common.collect.Lists;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.dom4j.Document;\nimport org.dom4j.Element;\nimport org.dom4j.Node;\n\n/**\n * Created by wuzhong on 2017/4/13.\n *\n * * example:\n * if your app has three process: 1 :com.taobao.demo\n * 2 :remote\n * 3 :com.taobao.single\n *\n * then AndroidManifest will add the components below\n *\n * <Activity\n * android:name=\"ATLASPROXY_com_taobao_demo_Activity\"/>\n * <Activity\n * android:name=\"ATLASPROXY_remote_Activity\"\n * android:process=\":remote\"/>\n * <Activity\n * android:name=\"ATLASPROXY_com_taobao_single_Activity\"\n * android:process=\"com.taobao.single\"/>\n *\n * <Service\n * android:name=\"ATLASPROXY_com_taobao_demo_Service\"/>\n * <Service\n * android:name=\"ATLASPROXY_remote_Service\"\n * android:process=\":remote\"/>\n * <Service\n * android:name=\"ATLASPROXY_com_taobao_single_Service\"\n * android:process=\"com.taobao.single\"/>\n *\n * <ContentProvider\n * android:name=\"ATLASPROXY_com_taobao_demo_Provider\"\n * android:authorities=\"ATLASPROXY_com_taobao_demo_Provider\"/>\n * <ContentProvider\n * android:name=\"ATLASPROXY_remote_Provider\"\n * android:authorities=\"ATLASPROXY_remote_Provider\"\n * android:process=\":remote\"/>\n * <ContentProvider\n * android:name=\"ATLASPROXY_com_taobao_single_Provider\"\n * android:authorities=\"ATLASPROXY_com_taobao_single_Provider\"\n * android:process=\"com.taobao.single\"/>\n *\n * and also apk will add the classses below\n *\n * class ATLASPROXY_com_taobao_demo_Service   extends android.taobao.atlas.runtime.newcomponent.service\n * .AdditionBaseDelegateService\n * class ATLASPROXY_remote_Service            extends android.taobao.atlas.runtime.newcomponent.service\n * .AdditionBaseDelegateService\n * class ATLASPROXY_com_taobao_single_Service extends android.taobao.atlas.runtime.newcomponent.service\n * .AdditionBaseDelegateService\n *\n * class ATLASPROXY_com_taobao_demo_Provider    extends android.taobao.atlas.runtime.newcomponent.provider\n * .ContentProviderBridge\n * class ATLASPROXY_remote_Service              extends android.taobao.atlas.runtime.newcomponent.provider\n * .ContentProviderBridge\n * class ATLASPROXY_com_taobao_single_Provider  extends android.taobao.atlas.runtime.newcomponent.provider\n * .ContentProviderBridge\n */\npublic class AtlasProxy {\n\n    public static final String ATLAS_PROXY_PACKAGE = \"android.taobao.atlas.runtime.newcomponent\";\n\n    public static void addAtlasProxyClazz(Document document, Set<String> nonProxyChannels,  Result result) {\n\n        Element root = document.getRootElement();// Get the root node\n\n        List<? extends Node> serviceNodes = root.selectNodes(\"//@android:process\");\n\n        String packageName = root.attribute(\"package\").getStringValue();\n\n        Set<String> processNames = new HashSet<>();\n        processNames.add(packageName);\n\n        for (Node node : serviceNodes) {\n            if (null != node && StringUtils.isNotEmpty(node.getStringValue())) {\n                String value = node.getStringValue();\n                processNames.add(value);\n            }\n        }\n\n        processNames.removeAll(nonProxyChannels);\n\n        List<String> elementNames = Lists.newArrayList(\"activity\");\n\n        Element applicationElement = root.element(\"application\");\n\n        for (String processName : processNames) {\n\n            boolean isMainPkg = packageName.equals(processName);\n            //boolean isMainPkg = true;\n            String processClazzName = processName.replace(\":\", \"\").replace(\".\", \"_\");\n\n            for (String elementName : elementNames) {\n\n                String fullClazzName = \"ATLASPROXY_\" +  (isMainPkg ? \"\" : (packageName.replace(\".\", \"_\") + \"_\" )) +  processClazzName + \"_\" + StringUtils.capitalize(elementName);\n\n                if (\"activity\".equals(elementName)) {\n                    result.proxyActivities.add(fullClazzName);\n                } else if (\"service\".equals(elementName)) {\n                    result.proxyServices.add(fullClazzName);\n                } else {\n                    result.proxyProviders.add(fullClazzName);\n                }\n\n                Element newElement = applicationElement.addElement(elementName);\n                newElement.addAttribute(\"android:name\", ATLAS_PROXY_PACKAGE + \".\" + fullClazzName);\n\n                if (!packageName.equals(processName)) {\n                    newElement.addAttribute(\"android:process\", processName);\n                }\n\n                boolean isProvider = \"provider\".equals(elementName);\n                if (isProvider) {\n                    newElement.addAttribute(\"android:authorities\",\n                                            ATLAS_PROXY_PACKAGE + \".\" + fullClazzName);\n                }\n\n            }\n\n        }\n\n    }\n\n    private static String serviceTmp\n        = \"package \" + ATLAS_PROXY_PACKAGE + \";\\r\\n\"\n        + \"public class ${clazzName} extends \" + ATLAS_PROXY_PACKAGE\n        + \".service.BaseDelegateService {}\";\n    private static String providerTmp\n        = \"package \" + ATLAS_PROXY_PACKAGE + \";\\r\\n\"\n        + \"public class ${clazzName} extends \" + ATLAS_PROXY_PACKAGE\n        + \".provider.ContentProviderBridge {}\";\n\n    public static boolean genProxyJavaSource(File rootDir, Result result) throws IOException {\n\n        if (result.proxyProviders.isEmpty() && result.proxyServices\n            .isEmpty()) {\n            return false;\n        }\n\n        rootDir = new File(rootDir, ATLAS_PROXY_PACKAGE.replace(\".\", \"/\"));\n        FileUtils.deleteDirectory(rootDir);\n        rootDir.mkdirs();\n\n        for (String clazzName : result.proxyServices) {\n            FileUtils.write(new File(rootDir, clazzName + \".java\"), serviceTmp.replace(\"${clazzName}\", clazzName));\n        }\n\n        for (String clazzName : result.proxyProviders) {\n            FileUtils.write(new File(rootDir, clazzName + \".java\"), providerTmp.replace(\"${clazzName}\", clazzName));\n        }\n\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/manifest/ManifestFileUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.manifest;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport javax.xml.xpath.XPath;\nimport javax.xml.xpath.XPathExpressionException;\n\nimport com.alibaba.fastjson.JSON;\nimport com.alibaba.fastjson.TypeReference;\n\nimport com.android.xml.AndroidXPathFactory;\nimport com.google.common.collect.HashBasedTable;\nimport com.google.common.collect.Maps;\nimport com.google.common.collect.Multimap;\nimport com.google.common.collect.Table;\nimport com.taobao.android.builder.extension.ManifestOptions;\nimport com.taobao.android.builder.tools.bundleinfo.model.BundleInfo;\nimport com.taobao.android.builder.tools.manifest.Permission.Item;\nimport com.taobao.android.builder.tools.xml.XmlHelper;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.IOUtils;\nimport org.apache.commons.lang.StringUtils;\nimport org.dom4j.Attribute;\nimport org.dom4j.Comment;\nimport org.dom4j.Document;\nimport org.dom4j.DocumentException;\nimport org.dom4j.Element;\nimport org.dom4j.Node;\nimport org.dom4j.Visitor;\nimport org.dom4j.VisitorSupport;\nimport org.dom4j.io.OutputFormat;\nimport org.dom4j.io.SAXReader;\nimport org.dom4j.io.XMLWriter;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.xml.sax.InputSource;\n\n/**\n * @author shenghua.nish\n * @date 2015-04-22 At 10:58\n */\npublic class ManifestFileUtils {\n\n    private static final Logger logger = LoggerFactory.getLogger(ManifestFileUtils.class);\n\n    public static String[] SYSTEM_PERMISSION = new String[] {\"android.permission\", \"com.android\"};\n\n    private static final String INSTANT_RUN_CONTENTPROVIDER = \"com.android.tools.ir.server.InstantRunContentProvider\";\n\n    private static final String ALI_INSTANT_RUN_CONTENTPROVIDER = \"com.android.alibaba.ip.server.InstantRunContentProvider\";\n\n\n    /**\n     * Follow up the manifest\n     *  @param mainManifest\n     * @param libManifestMap\n     * @param baseBunfleInfoFile\n     * @param manifestOptions\n     * @param debuggable\n     */\n    public static Result postProcessManifests(File mainManifest, Map<String, File> libManifestMap,\n                                              Multimap<String, File> libDependenciesMaps, File baseBunfleInfoFile,\n                                              ManifestOptions manifestOptions, boolean addMultiDex,\n                                              boolean isInstantRun, boolean debuggable, Set<String> remoteBundles, Set<String> insideBundles, boolean pushInstall)\n        throws IOException, DocumentException {\n\n        Result result = new Result();\n\n        File inputFile = new File(mainManifest.getParentFile(), \"AndroidManifest-backup.xml\");\n        FileUtils.deleteQuietly(inputFile);\n        FileUtils.moveFile(mainManifest, inputFile);\n\n        Document document = XmlHelper.readXml(inputFile);\n\n        if (null != baseBunfleInfoFile && baseBunfleInfoFile.exists()) {\n            addApplicationMetaData(document, libManifestMap, baseBunfleInfoFile, manifestOptions, remoteBundles,insideBundles);\n        }\n\n        if (null != manifestOptions && manifestOptions.isAddAtlasProxyComponents()) {\n            AtlasProxy.addAtlasProxyClazz(document, manifestOptions.getAtlasProxySkipChannels(), result);\n        }\n\n            addAndroidLabel(document,pushInstall);\n\n        if (null != manifestOptions && manifestOptions.isAddBundleLocation()) {\n            addBundleLocationToDestManifest(document, libManifestMap, libDependenciesMaps, manifestOptions);\n        }\n        if (null != manifestOptions && manifestOptions.isReplaceApplication()) {\n            replaceManifestApplicationName(document);\n        }\n\n        if ((null != manifestOptions && manifestOptions.isAddMultiDexMetaData()) || addMultiDex) {\n            addMultiDexMetaData(document);\n        }\n        if (null != manifestOptions && manifestOptions.isRemoveProvider()) {\n            removeProvider(document);\n        }\n        if (isInstantRun) {\n            singleProcess(document,ManifestFileUtils.getApplicationId(inputFile));\n        }\n\n        if (isInstantRun && !debuggable){\n            disableDebuggable(document);\n\n        }\n        removeCustomLaunches(document, manifestOptions);\n        updatePermission(document, manifestOptions);\n        removeComments(document);\n\n        XmlHelper.saveDocument(document, mainManifest);\n\n        printlnPermissions(document);\n\n        return result;\n    }\n\n    private static void singleProcess(Document document, String applicationId) {\n            List<Node> nodes = document.getRootElement().selectNodes(\"//provider\");\n        for (Node node : nodes) {\n            Element element = (Element)node;\n            String value = element.attributeValue(\"name\");\n            if (value.equals(INSTANT_RUN_CONTENTPROVIDER)){\n                element.addAttribute(\"name\",ALI_INSTANT_RUN_CONTENTPROVIDER);\n                element.addAttribute(\"authorities\",applicationId+\".\"+ALI_INSTANT_RUN_CONTENTPROVIDER);\n                Attribute attribute = element.attribute(\"multiprocess\");\n                if (attribute!= null) {\n                    attribute.setValue(\"false\");\n                    logger.warn(\"singleProcess  com.android.tools.ir.server.InstantRunContentProvider.......\");\n                }\n\n            }\n\n        }\n\n    }\n\n    private static void disableDebuggable(Document document) {\n        Element root = document.getRootElement();// Get the root node\n        Element app = root.element(\"application\");\n        Attribute attribute = app.attribute(\"debuggable\");\n        if (attribute!= null){\n            attribute.setValue(\"false\");\n            logger.warn(\"disable android:debuggable .......\");\n//            app.remove(attribute);\n        }\n    }\n\n    private static void addAndroidLabel(Document document,boolean pushInstall) {\n        Element root = document.getRootElement();// Get the root node\n        Element applicationElement = root.element(\"application\");\n        Attribute attribute = applicationElement.attribute(\"android:extractNativeLibs\");\n        if (attribute == null && pushInstall){\n            applicationElement.addAttribute(\"android:extractNativeLibs\",\"false\");\n        }else if (pushInstall){\n            attribute.setValue(\"false\");\n        }else if (!pushInstall && attribute!= null){\n            applicationElement.remove(attribute);\n        }\n    }\n\n    /**\n     * Replace the original application in the manifest nameFor AtlasBridgeApplication\n     * The original name has been written in meta-data\n     */\n    private static void replaceManifestApplicationName(Document document) {\n        // Write meta-data information\n        Element root = document.getRootElement();// Get the root node\n        Element applicationElement = root.element(\"application\");\n        String realApplicationClassName = applicationElement.attributeValue(\"name\");\n\n        if (null == realApplicationClassName) {\n            realApplicationClassName = \"\";\n        }\n\n        applicationElement.addAttribute(StringUtils.isEmpty(realApplicationClassName) ? \"android:name\" : \"name\",\n                                        \"android.taobao.atlas.startup.AtlasBridgeApplication\");\n\n        Element metaData = applicationElement.addElement(\"meta-data\");\n        metaData.addAttribute(\"android:name\", \"REAL_APPLICATION\");\n        metaData.addAttribute(\"android:value\", realApplicationClassName);\n    }\n\n    private static void addMultiDexMetaData(Document document) {\n        // Write meta-data information\n        Element root = document.getRootElement();// Get the root node\n        Element applicationElement = root.element(\"application\");\n\n        Element metaData = applicationElement.addElement(\"meta-data\");\n        metaData.addAttribute(\"android:name\", \"multidex_enable\");\n        metaData.addAttribute(\"android:value\", \"true\");\n    }\n\n    /**\n     * Add the metadata information to the manifest of the Lord as a solution for atals\n     *\n     * @param document\n     * @param libManifestMap\n     * @param baseBunfleInfoFile\n     * @param manifestOptions\n     */\n    private static void addApplicationMetaData(Document document, Map<String, File> libManifestMap,\n                                               File baseBunfleInfoFile, ManifestOptions manifestOptions,\n                                               Set<String> remoteBundles,Set<String>insideBundles) throws IOException, DocumentException {\n        Map<String, BundleInfo> bundleFileMap = Maps.newHashMap();\n        // Parsing basic information\n        if (null != baseBunfleInfoFile && baseBunfleInfoFile.exists() && baseBunfleInfoFile.canRead()) {\n            String bundleBaseInfo = FileUtils.readFileToString(baseBunfleInfoFile, \"utf-8\");\n            bundleFileMap = JSON.parseObject(bundleBaseInfo, new TypeReference<Map<String, BundleInfo>>() {});\n        }\n        Map<String, LibBundleInfo> awbManifestMap = Maps.newHashMap();\n        for (Map.Entry<String, File> entry : libManifestMap.entrySet()) {\n            String artifactId = entry.getKey();\n\n            String libName = artifactId.substring(artifactId.indexOf(\"-\") + 1);\n\n            File libManifest = entry.getValue();\n            if (libManifest.exists()) {\n                SAXReader reader = new SAXReader();\n                Document libDocument = reader.read(libManifest);// Read the XML file\n                Element libRoot = libDocument.getRootElement();// Get the root node\n                String packageName = libRoot.attributeValue(\"package\");\n                Element applicationElement = libRoot.element(\"application\");\n                String applicationName = null;\n                if (null != applicationElement) {\n                    applicationName = applicationElement.attributeValue(\"name\");\n                }\n                LibBundleInfo libBundleInfo = new LibBundleInfo(artifactId, packageName, applicationName,\n                                                                bundleFileMap.get(libName), libName);\n                awbManifestMap.put(artifactId, libBundleInfo);\n            }\n        }\n\n        // Write meta-data information\n        Element root = document.getRootElement();// Get the root node\n        List<? extends Node> nodes = root.selectNodes(\"//application\");\n        for (Node node : nodes) {\n            Element element = (Element)node;\n            for (String artifactId : libManifestMap.keySet()) {\n                LibBundleInfo libBundleInfo = awbManifestMap.get(artifactId);\n                if (StringUtils.isNotBlank(libBundleInfo.applicationName)) {\n                    String bundlePackageName = libBundleInfo.packageName;\n                    BundleInfo bundleInfo = libBundleInfo.bundleInfo;\n                    Element metaData = element.addElement(\"meta-data\");\n\n                    String bundleDepValue = \"\";\n                    if (null != bundleInfo && bundleInfo.getDependency() != null) {\n                        bundleDepValue = StringUtils.join(bundleInfo.getDependency(), \"|\");\n                    }\n                    String value = libBundleInfo.applicationName + \",\" + !(remoteBundles.contains(libBundleInfo.libName)||insideBundles.contains(libBundleInfo.libName))\n                        + \",\" + bundleDepValue;\n                    logger.info(\"[bundleInfo] add bundle value : \" + value + \" to manifest\");\n                    metaData.addAttribute(\"android:name\", \"bundle_\" + bundlePackageName);\n                    metaData.addAttribute(\"android:value\", value);\n                }\n            }\n        }\n    }\n\n    static class LibBundleInfo {\n\n        String name;\n\n        String packageName;\n\n        String applicationName;\n\n        BundleInfo bundleInfo;\n\n        String libName;\n\n        public LibBundleInfo(String name, String packageName, String applicationName, BundleInfo bundleInfo,\n                             String libName) {\n            this.name = name;\n            this.packageName = packageName;\n            this.applicationName = applicationName;\n            this.bundleInfo = bundleInfo;\n            this.libName = libName;\n        }\n    }\n\n    /**\n     * Add bundleLocation to the manifest file\n     *\n     * @param document\n     * @param libManifestMap\n     * @param manifestOptions\n     * @throws DocumentException\n     */\n    private static void addBundleLocationToDestManifest(Document document, Map<String, File> libManifestMap,\n                                                        Multimap<String, File> libDependenciesMaps,\n                                                        ManifestOptions manifestOptions) throws DocumentException {\n        Table<String, String, String> bundleInfoTable = HashBasedTable.create();\n        Map<String, String> packageNameMap = new HashMap<String, String>();\n        for (Map.Entry<String, File> entry : libManifestMap.entrySet()) {\n            File libManifest = entry.getValue();\n            if (libManifest.exists()) {\n                SAXReader reader = new SAXReader();\n                Document libDocument = reader.read(libManifest);// Read the XML file\n                Element libRoot = libDocument.getRootElement();// Get the root node\n                String packageName = libRoot.attributeValue(\"package\");\n                packageNameMap.put(entry.getKey(), packageName);\n                List<? extends Node> nodes = libRoot.selectNodes(\"//activity|//service|//receiver\");\n                for (Node node : nodes) {\n                    Element e = (Element)node;\n                    String name = e.attributeValue(\"name\");\n                    String type = e.getName();\n                    bundleInfoTable.put(type, name, packageName);\n                }\n            }\n        }\n\n        // Gets all dependent manifest information\n        for (String key : libDependenciesMaps.keySet()) {\n            Collection<File> libManifests = libDependenciesMaps.get(key);\n            for (File libManifest : libManifests) {\n                if (libManifest.exists()) {\n                    SAXReader reader = new SAXReader();\n                    Document libDocument = reader.read(libManifest);// Read the XML file\n                    Element libRoot = libDocument.getRootElement();// Get the root node\n                    String packageName = packageNameMap.get(key);\n                    List<? extends Node> nodes = libRoot.selectNodes(\"//activity|//service|//receiver\");\n                    for (Node node : nodes) {\n                        Element e = (Element)node;\n                        String name = e.attributeValue(\"name\");\n                        String type = e.getName();\n                        bundleInfoTable.put(type, name, packageName);\n                    }\n                }\n            }\n        }\n\n        Element root = document.getRootElement();// Get the root node\n        List<? extends Node> nodes = root.selectNodes(\"//activity|//service|//receiver\");\n        for (Node node : nodes) {\n            Element e = (Element)node;\n            String name = e.attributeValue(\"name\");\n            String type = e.getName();\n            String packageName = bundleInfoTable.get(type, name);\n            if (null != packageName) {\n                Element metaData = e.addElement(\"meta-data\");\n                metaData.addAttribute(\"android:name\", \"bundleLocation\");\n                metaData.addAttribute(\"android:value\", packageName);\n            }\n        }\n    }\n\n    /**\n     * Delete the custom header\n     *\n     * @param document\n     * @param manifestOptions\n     */\n    private static void removeCustomLaunches(Document document, ManifestOptions manifestOptions) {\n        if (null == manifestOptions) {\n            return;\n        }\n        Element root = document.getRootElement();// Get the root node\n        // Update launch information\n        if (manifestOptions.getRetainLaunches() != null && manifestOptions.getRetainLaunches().size() > 0) {\n            List<? extends Node> nodes = root.selectNodes(\n                \"//activity/intent-filter/category|//activity-alias/intent-filter/category\");\n            for (Node node : nodes) {\n                Element e = (Element)node;\n                if (\"android.intent.category.LAUNCHER\".equalsIgnoreCase(e.attributeValue(\"name\"))) {\n                    Element activityElement = e.getParent().getParent();\n                    String activiyName = activityElement.attributeValue(\"name\");\n                    if (!manifestOptions.getRetainLaunches().contains(activiyName)) {\n                        if (activityElement.getName().equalsIgnoreCase(\"activity-alias\")) {\n                            activityElement.getParent().remove(activityElement);\n                        } else {\n                            e.getParent().remove(e);\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * Set the permissions for the manifest\n     *\n     * @param document\n     * @param manifestOptions\n     */\n    private static void updatePermission(Document document, ManifestOptions manifestOptions) throws IOException {\n        if (null == manifestOptions) {\n            return;\n        }\n\n        Element root = document.getRootElement();// Get the root node\n\n        if (null != manifestOptions.getPermissionJsonFile() && manifestOptions.getPermissionJsonFile().exists()) {\n            String json = FileUtils.readFileToString(manifestOptions.getPermissionJsonFile());\n            Permission permission = JSON.parseObject(json, Permission.class);\n\n            List<Node> nodes = root.selectNodes(\"//permission\");\n            List<Node> nodes1 = root.selectNodes(\"//uses-permission\");\n            List<Node> nodes2 = root.selectNodes(\"//uses-feature\");\n\n            for (Node node : nodes) {\n                Element element = (Element)node;\n                String name = element.attributeValue(\"name\");\n                Item item = Permission.query(permission.getPermissions(), name);\n                if (null == item) {\n                    logger.warn(\"[permission] remove \" + name);\n                    element.getParent().remove(element);\n                }\n            }\n\n            for (Node node : nodes1) {\n                Element element = (Element)node;\n                String name = element.attributeValue(\"name\");\n                Item item = Permission.query(permission.getUses_permissions(), name);\n                if (null == item) {\n                    logger.warn(\"[uses-permission] remove \" + name);\n                    element.getParent().remove(element);\n                }\n            }\n\n            for (Node node : nodes2) {\n                Element element = (Element)node;\n                String name = element.attributeValue(\"name\");\n                if (StringUtils.isEmpty(name)){\n                    continue;\n                }\n                Item item = Permission.query(permission.getUses_features(), name);\n                if (null == item) {\n                    logger.warn(\"[uses-feature] remove \" + name);\n                    element.getParent().remove(element);\n                } else {\n                    //Modify the value\n                    if (StringUtils.isNotEmpty(item.getValue())) {\n                        Attribute required = element.attribute(\"required\");\n                        if (null != required){\n                            required.setValue(item.getValue());\n                        }\n                        //element.addAttribute(new QName(\"required\", new Namespace(\"android\", null)), item.getValue());\n                    }\n                }\n            }\n\n            return;\n        }\n\n        if (null != manifestOptions.getPermissionListFile() && manifestOptions.getPermissionListFile().exists()) {\n            List<String> whiteList = FileUtils.readLines(manifestOptions.getPermissionListFile());\n            List<Node> nodes = new ArrayList<>();\n            nodes.addAll(root.selectNodes(\"//permission\"));\n            nodes.addAll(root.selectNodes(\"//uses-permission\"));\n\n            for (Node node : nodes) {\n                Element element = (Element)node;\n                String name = element.attributeValue(\"name\");\n                if (!whiteList.contains(name)) {\n                    logger.warn(\"[permission] remove \" + name);\n                    element.getParent().remove(element);\n                }\n            }\n\n            return;\n        }\n\n        // Update custom permissions\n        if (manifestOptions.isRemoveCustomPermission()) {\n            List<? extends Node> nodes = root.selectNodes(\"//permission\");\n            for (Node node : nodes) {\n                Element element = (Element)node;\n                String name = element.attributeValue(\"name\");\n                boolean retain = false;\n                for (String systemPermission : SYSTEM_PERMISSION) {\n                    if (name.startsWith(systemPermission)) {\n                        retain = true;\n                        break;\n                    }\n                }\n                // If there is a custom permission\n                if (null != manifestOptions.getRetainPermissions()\n                    && manifestOptions.getRetainPermissions().size() > 0) {\n                    for (String retainPermission : manifestOptions.getRetainPermissions()) {\n                        if (name.startsWith(retainPermission)) {\n                            retain = true;\n                            break;\n                        }\n                    }\n                }\n                if (!retain) {\n                    element.getParent().remove(element);\n                }\n            }\n        }\n\n        // Update system permissions\n        if (null != manifestOptions.getRemoveSystemPermissions()\n            && manifestOptions.getRemoveSystemPermissions().size() > 0) {\n            List<? extends Node> nodes = root.selectNodes(\"//uses-permission\");\n            for (Node node : nodes) {\n                Element element = (Element)node;\n                String name = element.attributeValue(\"name\");\n                Set<String> removedPermissions = manifestOptions.getRemoveSystemPermissions();\n                if (removedPermissions.contains(name)) {\n                    element.getParent().remove(element);\n                }\n            }\n        }\n    }\n\n    public static void printlnPermissions(Document document) throws IOException {\n        Element root = document.getRootElement();// Get the root node\n        List<Node> nodes = new ArrayList<>();\n        nodes.addAll(root.selectNodes(\"//permission\"));\n        nodes.addAll(root.selectNodes(\"//uses-permission\"));\n\n        Set<String> permissons = new HashSet<>();\n        for (Node node : nodes) {\n            Element element = (Element)node;\n            String name = element.attributeValue(\"name\");\n            permissons.add(name);\n        }\n\n        logger.warn(\"[permission] start >>>>>>>> \");\n        List<String> lines = new ArrayList<>(permissons);\n        Collections.sort(lines);\n        for (String name : lines) {\n            logger.warn(name);\n        }\n        logger.warn(\"[permission] end <<<<<<<<< \");\n    }\n\n    /**\n     * Remove comments from XML\n     *\n     * @param document\n     * @throws IOException\n     * @throws DocumentException\n     */\n    private static void removeComments(Document document) throws IOException, DocumentException {\n        Visitor visitor = new VisitorSupport() {\n\n            @Override\n            public void visit(Comment comment) {\n                comment.setText(\" \");\n            }\n        };\n        document.accept(visitor);\n    }\n\n    /**\n     * Get the packageId for the manifest file\n     *\n     * @param manifestFile\n     * @return\n     */\n    public static String getApplicationId(File manifestFile) {\n        SAXReader reader = new SAXReader();\n        if (manifestFile.exists()) {\n            Document document = null;// Read the XML file\n            try {\n                document = reader.read(manifestFile);\n                Element root = document.getRootElement();// Get the root node\n                String packageName = root.attributeValue(\"package\");\n                return packageName;\n            } catch (DocumentException e) {\n                e.printStackTrace();\n            }\n        }\n        return null;\n    }\n    //\n    ///**\n    // * Preprocess the specified manifest file\n    // *\n    // * @param mainManifestFile\n    // * @param libManifestFiles\n    // * @param updateSdkVersion\n    // */\n    //@Deprecated\n    //public static void preProcessManifests(File mainManifestFile,\n    //                                       List<File> libManifestFiles,\n    //                                       boolean updateSdkVersion) throws DocumentException, IOException {\n    //    ManifestFileObject mainManifestFileObject = getManifestFileObject(mainManifestFile);\n    //    for (File libManifestFile : libManifestFiles) {\n    //        // Write files\n    //        updatePreProcessManifestFile(libManifestFile, mainManifestFileObject, updateSdkVersion);\n    //    }\n    //\n    //    //Get the bundleInfo information\n    //\n    //}\n\n    public static void updatePreProcessBaseManifestFile(File modifyManifest, File orgManifestFile)\n        throws IOException, DocumentException {\n\n        Document document = XmlHelper.readXml(orgManifestFile);// Read the XML file\n\n        Element root = document.getRootElement();// Get the root node\n        root.addNamespace(\"tools\", \"http://schemas.android.com/tools\");\n        Element applicationElement = root.element(\"application\");\n\n        //Determines whether there is application and needs to be deleted\n        if (null != applicationElement) {\n            applicationElement.addAttribute(\"tools:replace\",\n                                            \"android:name,android:icon,android:allowBackup,android:label,\"\n                                                + \"android:supportsRtl\");\n        }\n\n        XmlHelper.saveDocument(document, modifyManifest);\n    }\n\n    /**\n     * Update the libManifest file\n     *\n     * @param modifyManifest\n     * @param mainManifestFileObject param updateSdkVersion\n     * @param incremental\n     */\n\n    public static void updatePreProcessManifestFile(File modifyManifest, File orgManifestFile,\n                                                    ManifestInfo mainManifestFileObject, boolean updateSdkVersion,\n                                                    boolean incremental) throws IOException, DocumentException {\n\n        Document document = XmlHelper.readXml(orgManifestFile);// Read the XML file\n\n        Element root = document.getRootElement();// Get the root node\n        if (updateSdkVersion) {\n            Element useSdkElement = root.element(\"uses-sdk\");\n            if (null != useSdkElement) {\n                useSdkElement.getParent().remove(useSdkElement);\n            }\n        }\n\n        // First, we will manually process the tools:remove and tools:replace rules, and find that some of them are not necessarily possible through the ManifestMerge\n        Element applicationElement = root.element(\"application\");\n\n        List<Node> supportVersion = root.selectNodes(\"//meta-data\");\n\n        //Determines whether there is application and needs to be deleted\n        if (null != applicationElement) {\n            Attribute attribute = applicationElement.attribute(\"name\");\n            if (null != attribute) {\n                applicationElement.remove(attribute);\n            }\n        }\n\n        for (Node node : supportVersion) {\n            Element element = (Element)node;\n            Attribute attribute = element.attribute(\"name\");\n            if (attribute != null) {\n                if (attribute.getValue().equals(\"android.support.VERSION\")) {\n                    if (element.attribute(\"value\")!= null)\n                    element.attribute(\"value\").setValue(\"25.3.1\");\n                }\n            }\n        }\n//        if (supportVersion!= null && supportVersion.size() > 0){\n//            if (supportVersion.(\"name\");\n//        }\n\n        Map<String, String> replaceAttrs = mainManifestFileObject.getReplaceApplicationAttribute();\n        List<String> removeAttrs = mainManifestFileObject.getRemoveApplicationAttribute();\n\n        if (null != applicationElement) {\n            // Remove the tools properties from the lib project\n            List<Attribute> toRomoved = new ArrayList<Attribute>();\n            for (Attribute attribute : applicationElement.attributes()) {\n                if (attribute.getName().equals(\"replace\") || attribute.getName().equals(\"remove\")) {\n                    // applicationElement.remove(attribute);\n                    // applicationElement.attributes().remove(attribute);\n                    toRomoved.add(attribute);\n                }\n            }\n            if (toRomoved.size() > 0) {\n                for (Attribute attribute : toRomoved) {\n                    applicationElement.remove(attribute);\n                }\n            }\n\n            updateApplicationElement(applicationElement, replaceAttrs, removeAttrs);\n        }\n\n        //Handle the packageName TODO\n        String packageName = root.attributeValue(\"package\");\n        if (StringUtils.isEmpty(packageName)) {\n            packageName = ManifestFileUtils.getPackage(orgManifestFile);\n        }\n\n        List<? extends Node> applicatNodes = root.selectNodes(\"//application\");\n        for (Node node : applicatNodes) {\n            Element element = (Element)node;\n            Attribute attribute = element.attribute(\"name\");\n            if (attribute != null) {\n                if (!attribute.getValue().startsWith(packageName)) {\n                    attribute.setValue(packageName + attribute.getValue());\n                }\n            }\n        }\n\n        fillFullClazzName(root, packageName, \"activity\");\n        fillFullClazzName(root, packageName, \"provider\");\n        fillFullClazzName(root, packageName, \"receiver\");\n        fillFullClazzName(root, packageName, \"service\");\n        if (incremental) {\n            root.addNamespace(\"tools\", \"http://schemas.android.com/tools\");\n            List<? extends Node> nodes = root.selectNodes(\"//application/*\");\n            for (Node node : nodes) {\n                Element element = (Element)node;\n                element.addAttribute(\"tools:node\", \"replace\");\n            }\n        }\n\n        XmlHelper.saveDocument(document, modifyManifest);\n    }\n\n    private static void fillFullClazzName(Element root, String packageName, String type) {\n        List<? extends Node> applicatNodes = root.selectNodes(\"//\" + type);\n        for (Node node : applicatNodes) {\n            Element element = (Element)node;\n            Attribute attribute = element.attribute(\"name\");\n            if (attribute != null) {\n                if (attribute.getValue().startsWith(\".\")) {\n                    attribute.setValue(packageName + attribute.getValue());\n                }\n            }\n        }\n    }\n\n    /**\n     * Update the Application node information\n     *\n     * @param element\n     * @param replaceAttrs\n     * @param removeAttrs\n     */\n    private static void updateApplicationElement(Element element, Map<String, String> replaceAttrs,\n                                                 List<String> removeAttrs) {\n        for (Map.Entry<String, String> entry : replaceAttrs.entrySet()) {\n            String key = entry.getKey();\n            key = StringUtils.substringAfter(key, \":\");\n            Attribute attribute = element.attribute(key);\n            if (null != attribute) {\n                element.remove(attribute);\n            }\n        }\n        for (String key : removeAttrs) {\n            key = StringUtils.substringAfter(key, \":\");\n            Attribute attribute = element.attribute(key);\n            if (null != attribute) {\n                element.remove(attribute);\n            }\n        }\n    }\n\n    /**\n     * Update the attributes of element\n     *\n     * @param element\n     * @param properties\n     */\n    private static void updateElement(Element element, Map<String, String> properties) {\n        for (Map.Entry<String, String> entry : properties.entrySet()) {\n            String key = entry.getKey();\n            if (key.startsWith(\"tools:\")) {\n                continue;\n            }\n            String keyNoPrefix = key;\n            String[] values = StringUtils.split(key, \":\");\n            if (values.length > 1) {\n                keyNoPrefix = values[1];\n            }\n            if (null == entry.getValue()) {\n                continue;\n            } else {\n                Attribute attribute = element.attribute(keyNoPrefix);\n                if (null != attribute) {\n                    attribute.setValue(entry.getValue());\n                } else {\n                    element.addAttribute(key, entry.getValue());\n                }\n            }\n        }\n    }\n\n    static Map<String, String> manifestMap = new HashMap<String, String>();\n\n    public static String getPackage(File manifestFile) {\n\n        String version = manifestMap.get(manifestFile.getAbsolutePath());\n        if (null != version) {\n            return version;\n        }\n\n        XPath xpath = AndroidXPathFactory.newXPath();\n\n        try {\n            version = xpath.evaluate(\"/manifest/@package\", new InputSource(new FileInputStream(manifestFile)));\n            manifestMap.put(manifestFile.getAbsolutePath(), version);\n            return version;\n        } catch (XPathExpressionException e) {\n            // won't happen.\n        } catch (FileNotFoundException e) {\n            throw new RuntimeException(e);\n        }\n\n        return null;\n    }\n\n    public static String getApplicationName(File manifestFile) {\n        XPath xpath = AndroidXPathFactory.newXPath();\n        try {\n            return xpath.evaluate(\"/manifest/application/@android:name\",\n                                  new InputSource(new FileInputStream(manifestFile)));\n        } catch (XPathExpressionException e) {\n            // won't happen.\n        } catch (FileNotFoundException e) {\n            throw new RuntimeException(e);\n        }\n\n        return null;\n    }\n\n    /**\n     * Update the plug-in's minSdkVersion and targetSdkVersion\n     *\n     * @param androidManifestFile\n     * @throws IOException\n     * @throws DocumentException\n     */\n    public static String getVersionName(File androidManifestFile) throws IOException, DocumentException {\n        SAXReader reader = new SAXReader();\n        String versionName = \"\";\n        if (androidManifestFile.exists()) {\n            Document document = reader.read(androidManifestFile);// Read the XML file\n            Element root = document.getRootElement();// Get the root node\n            if (\"manifest\".equalsIgnoreCase(root.getName())) {\n                List<Attribute> attributes = root.attributes();\n                for (Attribute attr : attributes) {\n                    if (StringUtils.equalsIgnoreCase(attr.getName(), \"versionName\")) {\n                        versionName = attr.getValue();\n                    }\n                }\n            }\n        }\n        return versionName;\n    }\n\n    public static String getVersionCode(File androidManifestFile) throws IOException, DocumentException {\n        SAXReader reader = new SAXReader();\n        String versionCode = \"\";\n        if (androidManifestFile.exists()) {\n            Document document = reader.read(androidManifestFile);// Read the XML file\n            Element root = document.getRootElement();// Get the root node\n            if (\"manifest\".equalsIgnoreCase(root.getName())) {\n                List<Attribute> attributes = root.attributes();\n                for (Attribute attr : attributes) {\n                    if (StringUtils.equalsIgnoreCase(attr.getName(), \"versionCode\")) {\n                        versionCode = attr.getValue();\n                    }\n                }\n            }\n        }\n        return versionCode;\n    }\n\n    public static void removeProvider(File androidManifestFile) throws IOException, DocumentException {\n        File backupFile = new File(androidManifestFile.getParentFile(), \"AndroidManifest-backup.xml\");\n        FileUtils.deleteQuietly(backupFile);\n        FileUtils.moveFile(androidManifestFile, backupFile);\n\n        XMLWriter writer = null;// Declares the object that writes XML\n        SAXReader reader = new SAXReader();\n        OutputFormat format = OutputFormat.createPrettyPrint();\n        format.setEncoding(\"UTF-8\");// Sets the encoding format for the XML file\n        FileOutputStream fos = new FileOutputStream(androidManifestFile);\n\n        if (androidManifestFile.exists()) {\n            try {\n                Document document = reader.read(backupFile);// Read the XML file\n                Element root = document.getRootElement();// Get the root node\n                List<? extends Node> nodes = root.selectNodes(\"//provider\");\n                for (Node node : nodes) {\n                    Element element = (Element)node;\n                    String name = element.attributeValue(\"name\");\n                    logger.info(\"[Remove Provider]\" + name);\n                    element.getParent().remove(element);\n                }\n                writer = new XMLWriter(fos, format);\n                writer.write(document);\n            } finally {\n                if (null != writer) {\n                    writer.close();\n                }\n                IOUtils.closeQuietly(fos);\n            }\n        }\n    }\n\n    private static void removeProvider(Document document) throws IOException, DocumentException {\n\n        Element root = document.getRootElement();// Get the root node\n        List<? extends Node> nodes = root.selectNodes(\"//provider\");\n        for (Node node : nodes) {\n            Element element = (Element)node;\n            String name = element.attributeValue(\"name\");\n            logger.info(\"[Remove Provider]\" + name);\n            element.getParent().remove(element);\n        }\n    }\n\n    private static void removeProcess(Document document) throws IOException, DocumentException {\n\n        Element root = document.getRootElement();// Get the root node\n        List<? extends Node> nodes = root.selectNodes(\"//*[@android:process]\");\n        for (Node node : nodes) {\n            Element element = (Element)node;\n            String process = element.attributeValue(\"process\");\n            logger.info(\"[Remove Element]\" + element + process);\n            element.remove(element.attribute(\"process\"));\n        }\n    }\n\n    public static void createPatchManifest(File mainManifest, File originalManifest, File destManifest)\n        throws IOException, DocumentException {\n\n        Document document = XmlHelper.readXml(mainManifest);\n        Document baseDoc = XmlHelper.readXml(originalManifest);\n\n        List<Node> newNodes = selectComponents(document.getRootElement());\n        List<Node> baseNodes = selectComponents(baseDoc.getRootElement());\n\n        Map<String, Node> baseNodeMap = new HashMap<>();\n        for (Node node : baseNodes) {\n            Element el = (Element)node;\n            String key = el.attributeValue(\"process\") + el.attributeValue(\"name\");\n            baseNodeMap.put(key, node);\n        }\n\n        Element applicationElement = document.getRootElement().element(\"application\");\n        applicationElement.clearContent();\n        document.getRootElement().clearContent();\n        document.getRootElement().add(applicationElement);\n\n        for (Node node : newNodes) {\n            Element el = (Element)node;\n            String key = el.attributeValue(\"process\") + el.attributeValue(\"name\");\n            if (!baseNodeMap.containsKey(key) && !el.attributeValue(\"name\").startsWith(\n                AtlasProxy.ATLAS_PROXY_PACKAGE)) {\n                applicationElement.add(node);\n            }\n        }\n\n        XmlHelper.saveDocument(document, destManifest);\n    }\n\n    private static List<Node> selectComponents(Element root) {\n\n        String[] components = new String[] {\"activity\", \"provider\", \"receiver\", \"service\"};\n\n        List<Node> nodes = new ArrayList<>();\n        for (String component : components) {\n            nodes.addAll(root.selectNodes(\"//\" + component));\n        }\n\n        return nodes;\n    }\n\n    public static void main(String []args) throws DocumentException {\n        File manifest = new File(\"/Users/lilong/.gradle/caches/transforms-1/files-1.1/recyclerview-v7-25.3.1.aar/1046cd92fdcfb77468417d61ed21e0db/AndroidManifest.xml\");\n        Document document = XmlHelper.readXml(manifest);\n        Element element = document.getRootElement();\n        Attribute attribute = element.attribute(\"meta-data\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/manifest/ManifestHelper.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.manifest;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\n\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.manifmerger.ManifestProvider;\nimport com.google.common.collect.Sets;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.extension.AtlasExtension;\nimport com.taobao.android.builder.tools.bundleinfo.model.BundleInfo;\nimport org.apache.commons.lang.StringUtils;\nimport org.dom4j.Attribute;\nimport org.dom4j.Document;\nimport org.dom4j.DocumentException;\nimport org.dom4j.Element;\nimport org.dom4j.Node;\nimport org.dom4j.io.SAXReader;\nimport org.gradle.api.GradleException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * Created by wuzhong on 2017/3/6.\n */\npublic class ManifestHelper {\n\n    private static Logger sLogger = LoggerFactory.getLogger(ManifestHelper.class);\n\n    public static List<ManifestProvider> getBundleManifest(AppVariantContext appVariantContext,\n                                                           AtlasDependencyTree dependencyTree,\n                                                           AtlasExtension atlasExtension) {\n\n        Set<String> notMergedArtifacts = getNotMergedBundles(atlasExtension);\n\n        List<ManifestProvider> bundleProviders = new ArrayList<>();\n\n        for (AwbBundle awbBundle : dependencyTree.getAwbBundles()) {\n            String cord = String.format(\"%s:%s\",\n                                        awbBundle.getResolvedCoordinates().getGroupId(),\n                                        awbBundle.getResolvedCoordinates().getArtifactId());\n\n            if (null != notMergedArtifacts && notMergedArtifacts.contains(cord)) {\n                continue;\n            }\n\n            bundleProviders.add(createManifestProvider(awbBundle.getAndroidLibrary(), appVariantContext));\n\n            for (AndroidLibrary androidLibrary : awbBundle.getAndroidLibraries()) {\n                bundleProviders.add(createManifestProvider(androidLibrary, appVariantContext));\n            }\n\n        }\n\n        return bundleProviders;\n\n    }\n\n    public static boolean checkManifest(AppVariantContext appVariantContext, File fullManifest,\n                                        AtlasDependencyTree dependencyTree,\n                                        AtlasExtension atlasExtension) throws DocumentException {\n\n        Set<String> notMergedArtifacts = getNotMergedBundles(atlasExtension);\n\n        BundleInfo mainBundleInfo = new BundleInfo();\n        collectBundleInfo(appVariantContext, mainBundleInfo, fullManifest, null);\n\n        List<String> errors = new ArrayList<>();\n        for (AwbBundle awbBundle : dependencyTree.getAwbBundles()) {\n            String cord = String.format(\"%s:%s\",\n                                        awbBundle.getResolvedCoordinates().getGroupId(),\n                                        awbBundle.getResolvedCoordinates().getArtifactId());\n\n            if (null != notMergedArtifacts && notMergedArtifacts.contains(cord)) {\n                continue;\n            }\n\n            for (String activity : awbBundle.bundleInfo.getActivities()) {\n                if (StringUtils.isNotEmpty(activity) && !mainBundleInfo.getActivities().contains(activity)) {\n                    errors.add(\"miss activity:\" + activity);\n                }\n            }\n\n            for (String service : awbBundle.bundleInfo.getServices()) {\n                if (StringUtils.isNotEmpty(service) && !mainBundleInfo.getServices().contains(service)) {\n                    errors.add(\"miss service:\" + service);\n                }\n            }\n\n            if (!atlasExtension.getManifestOptions().isRemoveProvider()) {\n                for (String provider : awbBundle.bundleInfo.getContentProviders()) {\n                    if (StringUtils.isNotEmpty(provider) && !mainBundleInfo.getContentProviders().contains(provider)) {\n                        errors.add(\"miss provider:\" + provider);\n                    }\n                }\n            }\n\n            for (String receiver : awbBundle.bundleInfo.getReceivers()) {\n                if (StringUtils.isNotEmpty(receiver) && !mainBundleInfo.getReceivers().contains(receiver)) {\n                    errors.add(\"miss receiver:\" + receiver);\n                }\n            }\n\n        }\n\n        if (errors.isEmpty()) {\n            return true;\n        }\n\n        for (String err : errors) {\n            sLogger.error(err);\n        }\n\n        throw new GradleException(\"manifest merge error :\" + StringUtils.join(errors, \",\"));\n    }\n\n    private static Set<String> getNotMergedBundles(AtlasExtension atlasExtension) {\n        Set<String> notMergedArtifacts = Sets.newHashSet();\n        if (null != atlasExtension.getManifestOptions() &&\n            null != atlasExtension.getManifestOptions().getNotMergedBundles()) {\n            notMergedArtifacts = atlasExtension.getManifestOptions().getNotMergedBundles();\n        }\n        return notMergedArtifacts;\n    }\n\n    private static ManifestProvider createManifestProvider(AndroidLibrary androidLibrary,\n                                                           AppVariantContext appVariantContext) {\n        File modifyManifest = getModifyManifestFile(androidLibrary, appVariantContext);\n        return new BundleManifestProvider(modifyManifest);\n    }\n\n    private static File getModifyManifestFile(AndroidLibrary androidLibrary, AppVariantContext appVariantContext) {\n        return getModifyManifestFile(androidLibrary.getManifest(), appVariantContext);\n    }\n\n    public static File getModifyManifestFile(File manifest, AppVariantContext appVariantContext) {\n\n        File modifyManifest = (File)appVariantContext.manifestMap.get(manifest.getAbsolutePath());\n\n        //sLogger.error(\"get file : \" + manifest.getAbsolutePath() + \"->\" + modifyManifest);\n\n        if (null == modifyManifest || !modifyManifest.exists()) {\n            return manifest;\n        }\n        return modifyManifest;\n    }\n\n    public static void collectBundleInfo(AppVariantContext appVariantContext, BundleInfo bundleInfo, File manifest,\n                                         List<AndroidLibrary> androidLibraries)\n        throws DocumentException {\n        SAXReader reader = new SAXReader();\n        Document document = reader.read(getModifyManifestFile(manifest, appVariantContext));// Read the XML file\n        Element root = document.getRootElement();// Get the root node\n\n        List<? extends Node> metadataNodes = root.selectNodes(\"//meta-data\");\n        for (Node node : metadataNodes) {\n            Element element = (Element)node;\n            Attribute attribute = element.attribute(\"name\");\n            if (attribute.getValue().equals(\"label\")) {\n                Attribute labelAttribute = element.attribute(\"value\");\n                bundleInfo.setName(labelAttribute.getValue());\n            } else if (attribute.getValue().equals(\"description\")) {\n                Attribute descAttribute = element.attribute(\"value\");\n                bundleInfo.setDesc(descAttribute.getValue());\n            } else if(attribute.getValue().startsWith(\"atlas.fragment.intent.action.\")){\n                bundleInfo.getRemoteFragments().put(attribute.getValue(),\n                        element.attribute(\"value\").getValue());\n            }else if(attribute.getValue().startsWith(\"atlas.view.intent.action\")){\n                bundleInfo.getRemoteViews().put(attribute.getValue(),\n                        element.attribute(\"value\").getValue());\n            }else if(attribute.getValue().startsWith(\"atlas.transaction.intent.action\")){\n                bundleInfo.getRemoteTransactors().put(attribute.getValue(),\n                        element.attribute(\"value\").getValue());\n            }\n        }\n\n        addComponents(bundleInfo, root);\n\n        if (null != androidLibraries) {\n            for (AndroidLibrary depLib : androidLibraries) {\n                SAXReader reader2 = new SAXReader();\n                Document document2 = reader2.read(\n                    getModifyManifestFile(depLib.getManifest(), appVariantContext));// Read the XML file\n                Element root2 = document2.getRootElement();// Get the root node\n                addComponents(bundleInfo, root2);\n            }\n        }\n\n    }\n\n    private static void addComponents(BundleInfo bundleInfo, Element root) {\n        List<? extends Node> serviceNodes = root.selectNodes(\"//service\");\n        for (Node node : serviceNodes) {\n            Element element = (Element)node;\n            Attribute attribute = element.attribute(\"name\");\n            addToList(bundleInfo.getServices(),attribute.getValue());\n        }\n        List<? extends Node> receiverNodes = root.selectNodes(\"//receiver\");\n        for (Node node : receiverNodes) {\n            Element element = (Element)node;\n            Attribute attribute = element.attribute(\"name\");\n            addToList(bundleInfo.getReceivers(),attribute.getValue());\n        }\n        List<? extends Node> providerNodes = root.selectNodes(\"//provider\");\n        for (Node node : providerNodes) {\n            Element element = (Element)node;\n            Attribute attribute = element.attribute(\"name\");\n            addToList(bundleInfo.getContentProviders(),attribute.getValue());\n        }\n        List<? extends Node> activityNodes = root.selectNodes(\"//activity\");\n        for (Node node : activityNodes) {\n            Element element = (Element)node;\n            Attribute attribute = element.attribute(\"name\");\n            addToList(bundleInfo.getActivities(),attribute.getValue());\n        }\n    }\n\n    private static void addToList(List<String> list, String value){\n        if (StringUtils.isEmpty(value) || list.contains(value)){\n            return;\n        }\n        list.add(value);\n    }\n\n    public static List<ManifestProvider> convert(List<ManifestProvider> manifestProviders,\n                                                 AppVariantContext appVariantContext) {\n        List<ManifestProvider> modifyManifest = new ArrayList<>();\n\n        for (ManifestProvider manifestProvider : manifestProviders) {\n\n            File manifest = getModifyManifestFile(manifestProvider.getManifest(), appVariantContext);\n\n            modifyManifest.add(new MainManifestProvider(manifest, manifestProvider.getName()));\n\n        }\n\n        return modifyManifest;\n    }\n\n    public static List<ManifestProvider> getMainDexManifest(AppVariantContext appVariantContext, AtlasDependencyTree dependencyTree, AtlasExtension atlasExtension) {\n\n        Set<String> notMergedArtifacts = getNotMergedBundles(atlasExtension);\n\n        List<ManifestProvider> mainProviders = new ArrayList<>();\n\n        for (AndroidLibrary androidLibrary:dependencyTree.getMainBundle().getAndroidLibraries()){\n            String cord = String.format(\"%s:%s\",\n                    androidLibrary.getResolvedCoordinates().getGroupId(),\n                    androidLibrary.getResolvedCoordinates().getArtifactId());\n\n            if (null != notMergedArtifacts && notMergedArtifacts.contains(cord)) {\n                continue;\n            }\n\n            mainProviders.add(createManifestProvider(androidLibrary, appVariantContext));\n        }\n\n        return mainProviders;\n\n    }\n\n    public static class BundleManifestProvider implements ManifestProvider {\n\n        private File manifest;\n\n        public BundleManifestProvider(File manifest) {\n            this.manifest = manifest;\n        }\n\n        @Override\n        public File getManifest() {\n            return manifest;\n        }\n\n        @Override\n        public String getName() {\n            return manifest.getName();\n        }\n    }\n\n    public static class MainManifestProvider implements ManifestProvider {\n\n        private File manifest;\n        private String name;\n\n        public MainManifestProvider(File manifest, String name) {\n            this.manifest = manifest;\n            this.name = name;\n        }\n\n        @Override\n        public File getManifest() {\n            return manifest;\n        }\n\n        @Override\n        public String getName() {\n            return name;\n        }\n    }\n\n    public static List<? extends AndroidLibrary> getManifestDependencies(List<AwbBundle> awbBundles,\n                                                                         Set<String> notMergedArtifacts,\n                                                                         org.gradle.api.logging.Logger logger) {\n\n        List<AndroidLibrary> list = new ArrayList<>();\n\n        for (AwbBundle lib : awbBundles) {\n            // get the dependencies\n            // [vliux] respect manifestOption.notMergedBundle\n            String cord = String.format(\"%s:%s\",\n                                        lib.getResolvedCoordinates().getGroupId(),\n                                        lib.getResolvedCoordinates().getArtifactId());\n            if (null == notMergedArtifacts || !notMergedArtifacts.contains(cord)) {\n\n                list.add(lib.getAndroidLibrary());\n                list.addAll(lib.getAndroidLibraries());\n\n            } else {\n                logger.info(\"[NotMergedManifest] \" + cord);\n            }\n        }\n\n        return list;\n    }\n}\n\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/manifest/ManifestInfo.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.manifest;\n\nimport org.apache.commons.lang.StringUtils;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * ManifestCommon information in files\n * Created by shenghua.nish on 2015-04-22 11:06 in the morning.\n */\npublic class ManifestInfo {\n\n    private Map<String,String> manifestProperties = new HashMap<String, String>();\n    private Map<String,String> applicationProperties = new HashMap<String, String>();\n    private Map<String,String> useSdkProperties = new HashMap<String, String>();\n    private File manifestFile;\n\n    Map<String,String> replaceApplicationAttribute = new HashMap<>();\n    List<String> removeApplicationAttribute = new ArrayList<>();\n\n    public File getManifestFile() {\n        return manifestFile;\n    }\n\n    public void setManifestFile(File manifestFile) {\n        this.manifestFile = manifestFile;\n    }\n\n\n    public Map<String, String> getManifestProperties() {\n        return manifestProperties;\n    }\n\n    public ManifestInfo addManifestProperty(String key, String value){\n        this.manifestProperties.put(key,value);\n        return this;\n    }\n\n    public void setManifestProperties(Map<String, String> manifestProperties) {\n        this.manifestProperties = manifestProperties;\n    }\n\n    public Map<String, String> getApplicationProperties() {\n        return applicationProperties;\n    }\n\n    public ManifestInfo addApplicationProperty(String key, String value){\n        this.applicationProperties.put(key,value);\n        return this;\n    }\n\n    public void setApplicationProperties(Map<String, String> applicationProperties) {\n        this.applicationProperties = applicationProperties;\n    }\n\n    public Map<String, String> getUseSdkProperties() {\n        return useSdkProperties;\n    }\n\n    public ManifestInfo addUseSdkProperty(String key, String value){\n        this.useSdkProperties.put(key,value);\n        return this;\n    }\n\n    public void setUseSdkProperties(Map<String, String> useSdkProperties) {\n        this.useSdkProperties = useSdkProperties;\n    }\n\n    public void init(){\n        this.replaceApplicationAttribute.putAll(_getReplaceApplicationAttribute());\n        this.removeApplicationAttribute.addAll(_getRemoveApplicationAttribute());\n    }\n\n    /**\n     * Gets the properties that need to be replaced\n     * @return\n     */\n    public Map<String,String> _getReplaceApplicationAttribute(){\n        Map<String,String> replaceAttrMap = new HashMap<String,String>();\n        //Let's start by determining if there is a replace property\n        if(applicationProperties.containsKey(\"tools:replace\")){\n            String replaceAttrs = applicationProperties.get(\"tools:replace\");\n            String[] attrs = StringUtils.split(replaceAttrs,\",\");\n            if(null!= attrs && attrs.length > 0){\n                for(String attr:attrs){\n                    String value = applicationProperties.get(attr);\n                    if(null == value){\n                        value = applicationProperties.get(\"android:\" + attr);\n                    }\n                    if(null != value) {\n                        replaceAttrMap.put(attr, value);\n                    }\n                }\n            }\n        }\n        return replaceAttrMap;\n    }\n\n    /**\n     * Gets the properties that need to be deleted\n     * @return\n     */\n    public List<String> _getRemoveApplicationAttribute(){\n        List<String> removeAttrList = new ArrayList<String>();\n        //Let's start by determining if there is a replace property\n        if(applicationProperties.containsKey(\"tools:remove\")){\n            String replaceAttrs = applicationProperties.get(\"tools:remove\");\n            String[] attrs = StringUtils.split(replaceAttrs,\",\");\n            if(null!= attrs && attrs.length > 0){\n                for(String attr:attrs){\n                    removeAttrList.add(attr);\n                }\n            }\n        }\n        return removeAttrList;\n    }\n\n    public Map<String, String> getReplaceApplicationAttribute() {\n        return replaceApplicationAttribute;\n    }\n\n    public List<String> getRemoveApplicationAttribute() {\n        return removeApplicationAttribute;\n    }\n\n    @Override\n    public String toString() {\n        return \"ManifestFileObject{\" +\n                \"manifestProperties=\" + manifestProperties +\n                \", applicationProperties=\" + applicationProperties +\n                \", useSdkProperties=\" + useSdkProperties +\n                \", manifestFile=\" + manifestFile +\n                '}';\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/manifest/Permission.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.manifest;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Created by wuzhong on 2017/8/1.\n */\npublic class Permission {\n\n    private List<Item> permissions = new ArrayList<>();\n    private List<Item> uses_permissions = new ArrayList<>();\n    private List<Item> uses_features = new ArrayList<>();\n\n    public static Item query(List<Item> list, String name) {\n        for (Item item : list) {\n            if (item!=null &&name.equals(item.getName())) {\n                return item;\n            }\n        }\n        return null;\n    }\n\n    public List<Item> getPermissions() {\n        return permissions;\n    }\n\n    public void setPermissions(List<Item> permissions) {\n        this.permissions = permissions;\n    }\n\n    public List<Item> getUses_permissions() {\n        return uses_permissions;\n    }\n\n    public void setUses_permissions(List<Item> uses_permissions) {\n        this.uses_permissions = uses_permissions;\n    }\n\n    public List<Item> getUses_features() {\n        return uses_features;\n    }\n\n    public void setUses_features(List<Item> uses_features) {\n        this.uses_features = uses_features;\n    }\n\n    public static class Item {\n\n        private String name;\n        private String value;\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public String getValue() {\n            return value;\n        }\n\n        public void setValue(String value) {\n            this.value = value;\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/manifest/Result.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.manifest;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Created by wuzhong on 2017/4/13.\n */\npublic class Result implements Serializable {\n\n    public boolean success;\n\n    public List<String> proxyActivities = new ArrayList<>();\n    public List<String> proxyServices = new ArrayList<>();\n    public List<String> proxyProviders = new ArrayList<>();\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/multidex/FastMultiDexer.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.multidex;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Map;\n\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.builder.core.AtlasBuilder.MultiDexer;\nimport com.android.dex.Dex;\nimport com.android.dx.command.dexer.DxContext;\nimport com.android.dx.merge.CollisionPolicy;\nimport com.android.dx.merge.DexMerger;\nimport com.taobao.android.builder.extension.MultiDexConfig;\nimport com.taobao.android.builder.tools.multidex.dex.DexGroup;\nimport com.taobao.android.builder.tools.multidex.mutli.JarRefactor;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * Created by wuzhong on 2017/5/8.\n */\npublic class FastMultiDexer implements MultiDexer {\n\n    private static final Logger logger = LoggerFactory.getLogger(FastMultiDexer.class);\n\n    private final AppVariantContext appVariantContext;\n\n    private final MultiDexConfig multiDexConfig;\n\n    public FastMultiDexer(AppVariantContext appVariantContext) {\n        this.appVariantContext = appVariantContext;\n        this.multiDexConfig = (MultiDexConfig)appVariantContext.getAtlasExtension().getMultiDexConfigs().findByName(\n            appVariantContext.getVariantConfiguration().getBuildType().getName());\n    }\n\n    public boolean isFastMultiDexEnabled() {\n        if (null == multiDexConfig) {\n            return false;\n        }\n        boolean fastMultiDex = multiDexConfig.isFastMultiDex();\n\n        return fastMultiDex&&appVariantContext.getVariantData().getVariantConfiguration().isMultiDexEnabled();\n\n//        if (fastMultiDex && appVariantContext.getVariantData().getVariantConfiguration().isMultiDexEnabled()) {\n//            return true;\n//\n////            if (appVariantContext.getVariantData().getVariantConfiguration().isMultiDexEnabled()) {\n////                throw new GradleException(\n////                    \"atlas fast multi dex must close android's default multi dex , please `multiDexEnabled false`\");\n////            }\n////\n////            if (appVariantContext.getAtlasExtension().getTBuildConfig().isAtlasMultiDex()) {\n////                logger.error(\"atlasMultiDex is ignored\");\n////            }\n//        }\n//        return fastMultiDex;\n    }\n\n    @Override\n    public Collection<File> repackageJarList(Collection<File> files, File mainDexListFile, boolean release) throws IOException {\n\n        return new JarRefactor(appVariantContext, multiDexConfig).repackageJarList(files,mainDexListFile,release);\n\n    }\n\n    @Override\n    public void dexMerge(Map<File, Dex> fileDexMap, File outDexFolder) throws IOException {\n\n       com.taobao.android.builder.tools.multidex.dex.DexMerger dexMerger\n            = new com.taobao.android.builder.tools.multidex.dex.DexMerger(multiDexConfig, fileDexMap);\n\n        List<DexGroup> dexDtos = dexMerger.group();\n\n        dexMerger.executeMerge(outDexFolder, dexDtos);\n\n    }\n\n    private void mergeDex(File outDexFolder, List<Dex> tmpList, int index, Dex[] mergedList) throws IOException {\n\n        DexMerger dexMerger = new DexMerger(tmpList.toArray(new Dex[0]), CollisionPolicy.KEEP_FIRST,new DxContext());\n        Dex dex = dexMerger.merge();\n\n        mergedList[index] = dex;\n\n        String name = \"classes\" + (0 == index ? \"\" : String.valueOf(index + 1)) + \".dex\";\n\n        File dexFile = new File(outDexFolder, name);\n\n        dex.writeTo(dexFile);\n    }\n\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/multidex/dex/DexGroup.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.multidex.dex;\n\nimport com.android.dex.Dex;\nimport com.android.dex.DexIndexOverflowException;\nimport com.android.dex.FieldId;\nimport com.android.dex.MethodId;\n\nimport java.util.*;\n\npublic class DexGroup {\n\n    public static final int MAX_FIELD_IDS = 65500;\n    public static final int MAX_METHOD_IDS = 64400;\n    public static final int MAX_METHOD_IDS_FIRSTDEX = 64400;\n\n    public boolean firstDex;\n\n    public List<Dex> dexs = new ArrayList<>();\n\n    private Map<String,List<Dex>>methodTreeMap = new HashMap<>();\n    private Map<String,List<Dex>>fieldTreeMap = new HashMap<>();\n\n    public boolean addDex(Dex dex) {\n         Map<String,List<Dex>>tempMethodTreeMap = new HashMap<>(methodTreeMap);\n         Map<String,List<Dex>>tempFieldTreeMap = new HashMap<>(fieldTreeMap);\n        for (MethodId methodId:dex.methodIds()){\n            if (tempMethodTreeMap.containsKey(methodId.toString())){\n                tempMethodTreeMap.get(methodId.toString()).add(dex);\n            }else {\n                List<Dex>dexes = new ArrayList<>();\n                dexes.add(dex);\n                tempMethodTreeMap.put(methodId.toString(),dexes);\n            }\n        }\n\n        for (FieldId fieldId:dex.fieldIds()){\n            if (tempFieldTreeMap.containsKey(fieldId.toString())){\n                tempFieldTreeMap.get(fieldId.toString()).add(dex);\n            }else {\n                List<Dex>dexes = new ArrayList<>();\n                dexes.add(dex);\n                tempFieldTreeMap.put(fieldId.toString(),dexes);\n            }\n        }\n\n//        fields = fields+dex.fieldIds().size();\n//        if (fields > MAX_FIELD_IDS){\n//            return false;\n//        }\n//        methods = methods+dex.methodIds().size();\n//        if (methods > MAX_METHOD_IDS){\n//            return false;\n//        }\n\n        if (dex.methodIds().size() > MAX_METHOD_IDS_FIRSTDEX || dex.fieldIds().size() > MAX_FIELD_IDS){\n            throw new DexIndexOverflowException(\"field or method ID not in [0, 0xffff]: \" + \"tempMethods size:\"+dex.methodIds().size() + \"tempFields size:\" +dex.fieldIds().size());\n\n        }\n        if (tempMethodTreeMap.size() > MAX_METHOD_IDS||tempFieldTreeMap.size() > MAX_FIELD_IDS){\n            return false;\n        }\n        fieldTreeMap = new HashMap<>(tempFieldTreeMap);\n        methodTreeMap = new HashMap<>(tempMethodTreeMap);\n        dexs.add(dex);\n        tempFieldTreeMap.clear();\n        tempMethodTreeMap.clear();\n\n        return true;\n    }\n\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/multidex/dex/DexMerger.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.multidex.dex;\n\nimport com.android.dex.Dex;\nimport com.android.dex.DexIndexOverflowException;\nimport com.android.dx.command.dexer.DxContext;\nimport com.android.dx.merge.CollisionPolicy;\nimport com.taobao.android.builder.extension.MultiDexConfig;\nimport com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper;\nimport com.taobao.android.builder.tools.multidex.FastMultiDexer;\nimport org.apache.commons.lang.StringUtils;\nimport org.gradle.api.GradleException;\nimport org.jetbrains.annotations.NotNull;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.stream.Collectors;\n\n/**\n * Created by wuzhong on 2017/5/31.\n */\npublic class DexMerger {\n\n    public static final String FASTMAINDEX_JAR = \"fastmaindex\";\n    private static Logger logger = LoggerFactory.getLogger(DexMerger.class);\n\n    private MultiDexConfig multiDexConfig;\n    private List<File> fileList;\n\n    private LinkedHashMap<File, Dex> jarDexMap = new LinkedHashMap<>();\n    public List<Dex> dexList = new ArrayList<>();\n\n    public DexMerger(MultiDexConfig multiDexConfig, Collection<File> fileList) throws IOException {\n\n        this.multiDexConfig = multiDexConfig;\n        this.fileList = fileList.stream().sorted(new FileComparator()).collect(Collectors.toList());\n\n        for (File file : fileList) {\n            Dex dex = new Dex(file);\n            jarDexMap.put(file, dex);\n        }\n\n        dexList = new ArrayList<>(jarDexMap.values());\n\n    }\n\n    public DexMerger(MultiDexConfig multiDexConfig, Map<File, Dex> fileDexMap) {\n        this.multiDexConfig = multiDexConfig;\n        this.fileList = fileDexMap.keySet().stream().sorted(new FileComparator()).collect(Collectors.toList());\n\n        for (File file : fileList) {\n            Dex dex = fileDexMap.get(file);\n            jarDexMap.put(file, dex);\n        }\n\n        dexList = new ArrayList<>(jarDexMap.values());\n\n    }\n\n    public List<DexGroup> group() {\n        List<DexGroup> dexGroupList = new ArrayList<>();\n        addDexByRule(dexGroupList);\n\n        addDexLimited(dexGroupList, true);\n\n        return dexGroupList;\n\n    }\n\n    public void executeMerge(File outDexFolder, List<DexGroup> dexGroupList) {\n\n        ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper(\"dexmerge\", LoggerFactory\n            .getLogger(FastMultiDexer.class), dexGroupList.size());\n        List<Runnable> runnables = new ArrayList<>(dexGroupList.size());\n\n        Dex[] mergedList = new Dex[dexGroupList.size()];\n        for (int i = 0; i < dexGroupList.size(); i++) {\n            final List<Dex> dexes = dexGroupList.get(i).dexs;\n            final int index = i;\n            runnables.add(new Runnable() {\n                @Override\n                public void run() {\n                    try {\n                        mergeDex(outDexFolder, dexes, index, mergedList);\n                    } catch (Throwable e) {\n                        throw new GradleException(e.getMessage(), e);\n                    }\n                }\n            });\n        }\n\n        try {\n            executorServicesHelper.execute(runnables);\n        } catch (InterruptedException e) {\n            throw new GradleException(e.getMessage(), e);\n        }\n\n        if (!dexList.isEmpty() ) {\n            mergeSmallDexs(outDexFolder, mergedList);\n        }\n\n    }\n\n    private void mergeSmallDexs(File outDexFolder, Dex[] mergedList) {\n        List<DexGroup> dexGroupList = new ArrayList<>();\n        for (int i = 0; i < mergedList.length; i++) {\n            DexGroup dexGroup = new DexGroup();\n            dexGroup.firstDex = (0 == i);\n            dexGroup.addDex(mergedList[i]);\n            dexGroupList.add(i, dexGroup);\n        }\n\n        addDexLimited(dexGroupList, false);\n\n        executeMerge(outDexFolder, dexGroupList);\n    }\n\n    private void mergeDex(File outDexFolder, List<Dex> tmpList, int index, Dex[] mergedList) throws IOException {\n\n        com.android.dx.merge.DexMerger dexMerger = new com.android.dx.merge.DexMerger(\n            tmpList.toArray(new Dex[0]),\n            CollisionPolicy.KEEP_FIRST,new DxContext());\n\n        dexMerger.setCompactWasteThreshold(1024);\n\n        Dex dex = dexMerger.merge();\n\n        mergedList[index] = dex;\n\n        if (dexList.isEmpty()) {\n            logger.warn(\"dexCount of {}, methods {} , fields {}\", index, dex.getTableOfContents().methodIds.size,\n                        dex.getTableOfContents().fieldIds.size);\n\n            String name = \"classes\" + (0 == index ? \"\" : String.valueOf(index + 1)) + \".dex\";\n\n            File dexFile = new File(outDexFolder, name);\n\n            dex.writeTo(dexFile);\n        }\n    }\n\n    private void addDexByRule(List<DexGroup> dexDtos) {\n\n        DexGroup fistDto = new DexGroup();\n        fistDto.firstDex = (true);\n        dexDtos.add(0, fistDto);\n        for (File file : fileList) {\n            if (file.getParentFile().getName().startsWith(FASTMAINDEX_JAR)) {\n                logger.warn(String.format(\"add %s to first dex!\",file.getAbsolutePath()));\n                Dex dex = jarDexMap.get(file);\n                fistDto.addDex(dex);\n                dexList.remove(dex);\n            }\n        }\n\n        if (StringUtils.isEmpty(multiDexConfig.getDexSplitRules())) {\n            return;\n        }\n\n        String[] rules = multiDexConfig.getDexSplitRules().split(\";\");\n        for (int i = 0; i < rules.length; i++) {\n\n            DexGroup dexDto = null;\n            if (0 == i) {\n                dexDto = fistDto;\n            } else {\n                dexDto = new DexGroup();\n                dexDtos.add(i, dexDto);\n            }\n\n            String rule = rules[i];\n            if (StringUtils.isEmpty(rule)) {\n                continue;\n            }\n            String[] items = rule.split(\",\");\n            for (File file : fileList) {\n                if (match(items, file) || (0 == i && file.getAbsolutePath().contains(FASTMAINDEX_JAR))) {\n\n                    logger.warn(\"FASTMULTIDEX put file \" + file.getAbsolutePath() + \" to dex \" + i);\n\n                    Dex dex = jarDexMap.get(file);\n                    if (!dexDto.addDex(dex)) {\n                        throw new DexIndexOverflowException(file.getAbsolutePath() + \" can't add to dex\" + i);\n                    }\n                    dexList.remove(dex);\n                }\n            }\n        }\n\n    }\n\n    private void addDexLimited(List<DexGroup> dexDtos, boolean limited) {\n\n        int dexCount = multiDexConfig.getDexCount();\n        if (dexCount == 0) {\n            dexCount = Integer.MAX_VALUE;\n        }\n\n        int index = 0;\n        DexGroup dexDto = getDexDto(dexDtos, index);\n        for (Dex dex : new ArrayList<>(dexList)) {\n            //If you can't join in, you need to re-extend a dex\n            while (!dexDto.addDex(dex)) {\n\n                if (limited && index >= dexCount) {\n                    return;\n                }\n\n                dexDto = getDexDto(dexDtos, index++);\n\n            }\n            dexList.remove(dex);\n        }\n\n    }\n\n    @NotNull\n    private DexGroup getDexDto(List<DexGroup> dexDtos, int index) {\n        if (dexDtos.size() <= index) {\n            DexGroup dexDto = new DexGroup();\n            dexDtos.add(index, dexDto);\n            return dexDto;\n        }\n\n        DexGroup dexDto = dexDtos.get(index);\n        if (null == dexDto) {\n            dexDto = new DexGroup();\n            if (index == 0) {\n                dexDto.firstDex = true;\n            }\n            dexDtos.add(index, dexDto);\n        }\n        return dexDto;\n    }\n\n    private boolean match(String[] items, File file) {\n        for (String artiId : items) {\n            if (file.getParentFile().getName().contains(artiId)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/multidex/dex/FileComparator.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.multidex.dex;\n\nimport java.io.File;\nimport java.util.Comparator;\n\npublic class FileComparator implements Comparator<File> {\n\n    @Override\n    public int compare(File o1, File o2) {\n        if (o1.getAbsolutePath().contains(\"fastmaindex\")) {\n            return 1;\n        } else if (o2.getAbsolutePath().contains(\"fastmaindex\")) {\n            return -1;\n        }\n        return (int)(o2.length() - o1.length());\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/multidex/mutli/JarRefactor.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.multidex.mutli;\n\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.builder.packaging.JarMerger;\nimport com.taobao.android.builder.extension.MultiDexConfig;\nimport com.taobao.android.builder.tools.FileNameUtils;\nimport com.taobao.android.builder.tools.JarUtils;\nimport com.taobao.android.builder.tools.multidex.dex.DexMerger;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.IOUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.*;\nimport java.util.*;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\nimport java.util.jar.JarOutputStream;\nimport java.util.zip.ZipEntry;\n\n/**\n * Created by wuzhong on 2017/6/16.\n */\npublic class JarRefactor {\n\n    private static Logger logger = LoggerFactory.getLogger(JarRefactor.class);\n\n    private AppVariantContext appVariantContext;\n    private MultiDexConfig multiDexConfig;\n    private boolean splitJar = false;\n\n    public static final int MAX_CLASSES = 3000;\n\n    public JarRefactor(AppVariantContext appVariantContext,\n                       MultiDexConfig multiDexConfig) {\n        this.appVariantContext = appVariantContext;\n        this.multiDexConfig = multiDexConfig;\n    }\n\n    public Collection<File> repackageJarList(Collection<File> files, File mainDexListFile, boolean release) throws IOException {\n\n\n        List<String> mainDexList = new MainDexLister(appVariantContext, multiDexConfig).getMainDexList(files,mainDexListFile);\n        if (release){\n            return generateFirstDexJar(mainDexList,files);\n\n        }else {\n            return null;\n        }\n\n\n    }\n\n    private Collection<File> generateFirstDexJar(List<String>mainDexList,Collection<File> files)throws IOException {\n\n        List<File> jarList = new ArrayList<>();\n        List<File> folderList = new ArrayList<>();\n        for (File file : files) {\n            if (file.isDirectory()) {\n                folderList.add(file);\n            } else {\n                jarList.add(file);\n            }\n        }\n\n        File dir = new File(appVariantContext.getScope().getGlobalScope().getIntermediatesDir(),\n                \"fastmultidex/\" + appVariantContext.getVariantName());\n        FileUtils.deleteDirectory(dir);\n        dir.mkdirs();\n\n        if (!folderList.isEmpty()) {\n            File mergedJar = new File(dir, \"jarmerging/combined.jar\");\n            mergedJar.getParentFile().mkdirs();\n            mergedJar.delete();\n            mergedJar.createNewFile();\n            JarMerger jarMerger = new JarMerger(mergedJar.toPath());\n            for (File folder : folderList) {\n                jarMerger.addDirectory(folder.toPath());\n            }\n            jarMerger.close();\n            if (mergedJar.length() > 0) {\n                jarList.add(mergedJar);\n            }\n        }\n\n        List<File> result = new ArrayList<>();\n        File maindexJar = new File(dir, DexMerger.FASTMAINDEX_JAR + \".jar\");\n\n        JarOutputStream mainJarOuputStream = new JarOutputStream(\n                new BufferedOutputStream(new FileOutputStream(maindexJar)));\n\n        //First order\n        Collections.sort(jarList, new NameComparator());\n\n        for (File jar : jarList) {\n            File outJar = new File(dir, FileNameUtils.getUniqueJarName(jar) + \".jar\");\n\n            result.add(outJar);\n            JarFile jarFile = new JarFile(jar);\n            JarOutputStream jos = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(outJar)));\n            Enumeration<JarEntry> jarFileEntries = jarFile.entries();\n\n            List<String> pathList = new ArrayList<>();\n            while (jarFileEntries.hasMoreElements()) {\n                JarEntry ze = jarFileEntries.nextElement();\n                String pathName = ze.getName();\n                if (mainDexList.contains(pathName)) {\n                    copyStream(jarFile.getInputStream(ze), mainJarOuputStream, ze, pathName);\n                    pathList.add(pathName);\n                }\n            }\n\n            if (!pathList.isEmpty()) {\n                jarFileEntries = jarFile.entries();\n                while (jarFileEntries.hasMoreElements()) {\n                    JarEntry ze = jarFileEntries.nextElement();\n                    String pathName = ze.getName();\n                    if (!pathList.contains(pathName)) {\n                        copyStream(jarFile.getInputStream(ze), jos, ze, pathName);\n                    }\n                }\n            }\n\n            jarFile.close();\n            IOUtils.closeQuietly(jos);\n\n            if (pathList.isEmpty()) {\n                FileUtils.copyFile(jar, outJar);\n            }\n            if (!appVariantContext.getAtlasExtension().getTBuildConfig().isFastProguard() && files.size() == 1){\n                JarUtils.splitMainJar(result,outJar,1,MAX_CLASSES);\n            }\n        }\n\n        IOUtils.closeQuietly(mainJarOuputStream);\n\n        Collections.sort(result, new NameComparator());\n\n        result.add(0, maindexJar);\n\n        return result;\n    }\n\n\n\n    private void copyStream(InputStream inputStream, JarOutputStream jos, JarEntry ze, String pathName) {\n        try {\n\n            ZipEntry newEntry = new ZipEntry(pathName);\n            // Make sure there is date and time set.\n            if (ze.getTime() != -1) {\n                newEntry.setTime(ze.getTime());\n                newEntry.setCrc(ze.getCrc()); // If found set it into output file.\n            }\n            jos.putNextEntry(newEntry);\n            IOUtils.copy(inputStream, jos);\n            IOUtils.closeQuietly(inputStream);\n        } catch (Exception e) {\n            //throw new GradleException(\"copy stream exception\", e);\n            //e.printStackTrace();\n            logger.error(\"copy stream exception >>> \" + pathName + \" >>>\" + e.getMessage());\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/multidex/mutli/MainDexLister.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.multidex.mutli;\n\n\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.core.GradleVariantConfiguration;\nimport com.google.common.base.Joiner;\nimport com.taobao.android.builder.extension.MultiDexConfig;\nimport com.taobao.android.builder.extension.TBuildConfig;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport javassist.ClassPool;\nimport javassist.CtClass;\nimport javassist.NotFoundException;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.GradleException;\nimport org.jetbrains.annotations.Nullable;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport proguard.obfuscate.MappingReader;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\n\nimport static com.android.builder.model.AndroidProject.FD_OUTPUTS;\n\n/**\n * Created by wuzhong on 2017/6/16.\n */\npublic class MainDexLister {\n\n    private static Logger logger = LoggerFactory.getLogger(MainDexLister.class);\n\n    private AppVariantContext appVariantContext;\n    private MultiDexConfig multiDexConfig;\n\n    public MainDexLister(AppVariantContext appVariantContext,\n                         MultiDexConfig multiDexConfig) {\n        this.appVariantContext = appVariantContext;\n        this.multiDexConfig = multiDexConfig;\n    }\n\n    public List<String> getMainDexList(Collection<File> files, File mainDexListFile) {\n\n        GradleVariantConfiguration config = appVariantContext.getVariantConfiguration();\n\n        Set<String> mainDexList = new HashSet<String>();\n\n        //Confusion of the map\n        //Map<String, String> classMap = getClassObfMap(config);\n        Collection<BaseVariantOutput> collection = appVariantContext.getVariantOutputData();\n        File manifest = com.android.utils.FileUtils.join(collection.iterator().next().getProcessManifest().getManifestOutputDirectory(),new String[]{collection.iterator().next().getDirName(),\"AndroidManifest.xml\"});\n        if (appVariantContext.getScope().getInstantRunBuildContext().isInInstantRunMode()){\n            manifest = com.android.utils.FileUtils.join(collection.iterator().next().getProcessManifest().getInstantRunManifestOutputDirectory(),new String[]{collection.iterator().next().getDirName(),\"AndroidManifest.xml\"});\n        }\n        String applicationName = ManifestFileUtils.getApplicationName(manifest);\n\n        ClassPool classPool = new ClassPool();\n\n        try {\n            for (File file : files) {\n                if (file.isFile()) {\n                    classPool.insertClassPath(file.getAbsolutePath());\n                } else {\n                    classPool.appendClassPath(file.getAbsolutePath());\n                }\n            }\n        } catch (NotFoundException e) {\n            throw new GradleException(e.getMessage(), e);\n        }\n\n        TBuildConfig tBuildConfig = appVariantContext.getAtlasExtension().getTBuildConfig();\n\n        HashSet handleList = new HashSet<String>();\n        Set<String> headClasses = new LinkedHashSet<>();\n\n        headClasses.add(applicationName);\n        headClasses.add(\"android.taobao.atlas.bridge.BridgeApplicationDelegate\");\n        headClasses.addAll(multiDexConfig.getFirstDexClasses());\n        List<String> maindexListClazz = new ArrayList<String>();\n\n        String preLaunchStr = tBuildConfig.getPreLaunch();\n        if (!org.apache.commons.lang3.StringUtils.isEmpty(preLaunchStr)) {\n            String[] launchArray = preLaunchStr.split(\"\\\\|\");\n            if (launchArray.length > 0) {\n                for (String launchItem : launchArray) {\n                    String[] launchInfo = launchItem.split(\":\");\n                    String clazzName = launchInfo[0];\n                    headClasses.add(clazzName);\n                }\n            }\n        }\n\n        for (String clazz:headClasses){\n            clazz = clazz.replaceAll(\"\\\\.\", \"/\") + \".class\";\n            maindexListClazz.add(clazz);\n        }\n\n        for (String headClass : headClasses) {\n            addRefClazz(classPool, headClass, mainDexList, handleList,\"\");\n        }\n\n        //get manifest\n        for (String newLine : mainDexList) {\n            newLine = newLine.replaceAll(\"\\\\.\", \"/\") + \".class\";\n            maindexListClazz.add(newLine);\n        }\n        for (String className :headClasses) {\n            className = className.replaceAll(\"\\\\.\", \"/\") + \".class\";\n            maindexListClazz.add(className);\n        }\n\n        if (multiDexConfig.getMainDexListCount()!=0){\n            maindexListClazz = maindexListClazz.subList(0,multiDexConfig.getMainDexListCount());\n        }\n\n        try {\n            FileUtils.writeLines(mainDexListFile,\n                                 maindexListClazz);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        return maindexListClazz;\n    }\n\n    private Map<String, String> getClassObfMap(GradleVariantConfiguration config) {\n        Map<String, String> classMap = new HashMap<String, String>();\n        boolean isMinifyEnabled = config.getBuildType().isMinifyEnabled();\n        File proguardOut = new File(Joiner.on(File.separatorChar).join(\n            String.valueOf(appVariantContext.getScope().getGlobalScope().getBuildDir()), FD_OUTPUTS, \"mapping\",\n            appVariantContext.getScope().getVariantConfiguration().getDirName()));\n        File mappingFile = new File(proguardOut, \"mapping.txt\");\n        // Parse the mapping file to generate the new mainDexListFile\n        if (isMinifyEnabled && mappingFile.exists()) {\n            MappingReader mappingReader = new MappingReader(mappingFile);\n            MappingReaderProcess process = new MappingReaderProcess();\n            try {\n                mappingReader.pump(process);\n            } catch (IOException e) {\n                throw new GradleException(e.getMessage(), e);\n            }\n            classMap = process.classMapping;\n        }\n        return classMap;\n    }\n\n    @Nullable\n    private String getRealClazz(Map<String, String> classMap, String line) {\n        String realClazz = classMap.isEmpty() ? line : classMap.get(line);\n        if (null == realClazz) {\n            realClazz = line;\n        }\n        return realClazz;\n    }\n\n    private void addRefClazz(ClassPool classPool, String clazz, Set<String> classList, Set<String> handleList, String root) {\n\n        if (handleList.contains(clazz)) {\n            return;\n        }\n\n        //blacklisting\n        if (!multiDexConfig.getMainDexBlackList().isEmpty()) {\n            for (String blackItem : multiDexConfig.getMainDexBlackList()) {\n                if (clazz.startsWith(blackItem)) {\n                    return;\n                }\n            }\n        }\n\n        try {\n\n            CtClass ctClass = classPool.get(clazz);\n\n            if (null != ctClass) {\n\n                logger.info(\"[MainDex] add \" + clazz + \" to main dex list , because of \" + root);\n                classList.add(clazz);\n                handleList.add(clazz);\n                if (classList.size() > JarRefactor.MAX_CLASSES){\n                    return;\n                }\n                Collection<String> references = ctClass.getRefClasses();\n\n                if (null == references) {\n                    return;\n                }\n\n                for (String clazz2 : references) {\n                    addRefClazz(classPool, clazz2, classList, handleList , root + \"->\" + clazz);\n                }\n            }\n        } catch (Throwable e) {\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/multidex/mutli/MappingReaderProcess.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.multidex.mutli;\n\nimport java.util.Map;\n\nimport com.google.common.collect.Maps;\nimport proguard.obfuscate.MappingProcessor;\n\npublic class MappingReaderProcess implements MappingProcessor {\n    public Map<String, String> classMapping = Maps.newHashMap();\n\n    @Override\n    public boolean processClassMapping(String className, String newClassName) {\n        classMapping.put(newClassName, className);\n        return true;\n    }\n\n    @Override\n    public void processFieldMapping(String className, String fieldType, String fieldName, String newClassName,\n                                    String newFieldName) {\n    }\n\n    @Override\n    public void processMethodMapping(String className, int firstLineNumber, int lastLineNumber,\n                                     String methodReturnType, String methodName, String methodArguments,\n                                     String newClassName, int newFirstLineNumber, int newLastLineNumber,\n                                     String newMethodName) {\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/multidex/mutli/NameComparator.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.multidex.mutli;\n\nimport java.io.File;\n\nimport org.apache.commons.io.comparator.NameFileComparator;\n\n/**\n * Created by wuzhong on 2017/5/9.\n */\npublic class NameComparator extends NameFileComparator {\n\n    @Override\n    public int compare(File file1, File file2) {\n\n        if (file1.getName().startsWith(\"combined\")) {\n            return 1;\n        }\n\n        if (file2.getName().startsWith(\"combined\")) {\n            return -1;\n        }\n\n        return super.compare(file1, file2);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/process/ApkProcessor.java",
    "content": "package com.taobao.android.builder.tools.process;\n\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.builder.core.AndroidBuilder;\nimport com.android.builder.model.BuildType;\nimport com.android.builder.model.SigningConfig;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.extension.TBuildType;\nimport com.taobao.android.builder.tools.BuildHelper;\nimport com.taobao.android.builder.tools.bundleinfo.DynamicBundleInfo;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.Project;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * ApkProcessor\n *\n * @author zhayu.ll\n * @date 18/1/10\n * @time 下午4:43\n * @description  \n */\npublic interface ApkProcessor {\n\n\n    File securitySignApk(File dexFile,File androidManifestFile,TBuildType tBuildType,boolean bundle);\n\n    String uploadBundle(Project project,File apkFile, AwbBundle awbBundle, TBuildType buildType);\n\n     String uploadNativeSo(Project project,File apkFile, TBuildType buildType);\n\n\n        void removeBundle(AppVariantOutputContext appVariantOutputContext,AwbBundle awbBundle,File bundleFile);\n\n    List<DynamicBundleInfo> generateAllBundleInfo(Collection<AwbBundle> awbBundles);\n\n    void signApk(File apkFile, SigningConfig signingConfig);\n\n    File zipAlignApk(Project project,File apkFile , AndroidBuilder androidBuilder,TBuildType buildType);\n\n\n    public abstract class DefaultApkProcessor implements ApkProcessor{\n\n        @Override\n        public File securitySignApk(File dexFile, File androidManifestFile,TBuildType tBuildType,boolean bundle){\n            return null;\n\n        }\n\n        @Override\n        public String uploadBundle(Project project,File apkFile,AwbBundle awbBundle,TBuildType buildType) {\n            return null;\n        }\n\n        @Override\n        public String uploadNativeSo(Project project, File apkFile, TBuildType buildType) {\n            return null;\n        }\n\n        @Override\n        public void removeBundle(AppVariantOutputContext appVariantOutputContext, AwbBundle awbBundle, File bundleFile) {\n            File outofApkLocation = appVariantOutputContext.getAwbPackageOutAppOutputFile(\n                    awbBundle);\n            awbBundle.outputBundleFile = outofApkLocation;\n\n            if (outofApkLocation.exists()) {\n                outofApkLocation.delete();\n            }\n            if (!outofApkLocation.getParentFile().exists()) {\n                outofApkLocation.getParentFile().mkdirs();\n            }\n            bundleFile.renameTo(outofApkLocation);\n            //add to ap\n            appVariantOutputContext.appBuildInfo.getOtherFilesMap().put(\n                    \"remotebundles/\" + outofApkLocation.getName(), outofApkLocation);\n        }\n\n        @Override\n        public List<DynamicBundleInfo> generateAllBundleInfo(Collection<AwbBundle> awbBundles) {\n            List<DynamicBundleInfo> bundleInfoList = new ArrayList<>();\n            if (awbBundles == null){\n                return bundleInfoList;\n            }\n\n            for (AwbBundle awbBundle : awbBundles) {\n                DynamicBundleInfo dynamicBundleInfo = new DynamicBundleInfo();\n                if (awbBundle.isRemote && !awbBundle.isMBundle) {\n                    dynamicBundleInfo.url = awbBundle.bundleInfo.getUrl();\n                }\n                dynamicBundleInfo.md5 = awbBundle.bundleInfo.getMd5();\n                dynamicBundleInfo.size = awbBundle.bundleInfo.getSize();\n                dynamicBundleInfo.name = awbBundle.getPackageName();\n                bundleInfoList.add(dynamicBundleInfo);\n\n            }\n            return bundleInfoList;\n        }\n\n        @Override\n        public void signApk(File apkFile, SigningConfig signingConfig) {\n\n        }\n\n        @Override\n        public File zipAlignApk(Project project,File apkFile, AndroidBuilder androidBuilder,TBuildType buildType) {\n            File zipSignApk = BuildHelper.doZipAlign(androidBuilder, project,apkFile);\n            return zipSignApk;\n\n        }\n    }\n\n    public static class AtlasApkProcessor extends DefaultApkProcessor{\n\n        @Override\n        public void removeBundle(AppVariantOutputContext appVariantOutputContext, AwbBundle awbBundle, File bundleFile) {\n            if (awbBundle.isRemote && !awbBundle.isMBundle) {\n                super.removeBundle(appVariantOutputContext, awbBundle, bundleFile);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/AtlasProguardHelper.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.proguard;\n\nimport com.alibaba.fastjson.JSON;\nimport com.alibaba.fastjson.TypeReference;\nimport com.android.build.gradle.api.BaseVariantOutput;\nimport com.android.build.gradle.internal.ApkDataUtils;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.android.build.gradle.internal.scope.GlobalScope;\nimport com.android.build.gradle.internal.scope.VariantScope;\nimport com.android.build.gradle.internal.transforms.ProGuardTransform;\nimport com.android.builder.model.AndroidLibrary;\nimport com.google.common.base.Joiner;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.AtlasDependencyTree;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tools.Profiler;\nimport com.taobao.android.builder.tools.bundleinfo.BundleGraphExecutor;\nimport com.taobao.android.builder.tools.bundleinfo.BundleItem;\nimport com.taobao.android.builder.tools.bundleinfo.BundleItemRunner;\nimport com.taobao.android.builder.tools.bundleinfo.model.BundleInfo;\nimport com.taobao.android.builder.tools.proguard.domain.Input;\nimport com.taobao.android.builder.tools.proguard.dump.ClazzRefInfo;\nimport com.taobao.android.builder.tools.proguard.dump.KeepConverter;\nimport org.apache.commons.io.FileUtils;\nimport org.gradle.api.GradleException;\nimport org.jetbrains.annotations.NotNull;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\n\nimport static com.android.builder.model.AndroidProject.FD_OUTPUTS;\n\n/**\n * Created by wuzhong on 2016/12/9.\n */\npublic class AtlasProguardHelper {\n\n    private static Logger sLogger = LoggerFactory.getLogger(AtlasProguardHelper.class);\n\n    public static List<File>configs = new ArrayList<>();\n\n    public static void doBundleProguard(final AppVariantContext appVariantContext, List<File> mainDexJars)\n        throws Exception {\n\n        Profiler.enter(\"preparebundleproguard\");\n        VariantScope variantScope = appVariantContext.getScope();\n        AtlasDependencyTree dependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n            variantScope.getVariantConfiguration().getFullName());\n\n        if (dependencyTree.getAwbBundles().isEmpty()) {\n            return;\n        }\n\n        List<File> libs = new ArrayList<>(\n            appVariantContext.getScope().getGlobalScope().getAndroidBuilder().getBootClasspath(true));\n\n        //All dependent classes\n        Profiler.enter(\"getDefaultClasses\");\n        Set<String> defaultLibClasses = getClassList(libs);\n        Profiler.release();\n\n        libs.addAll(mainDexJars);\n\n        //Get the basic proguard configuration\n        List<File> defaultProguardFiles = new ArrayList<>(\n\n            appVariantContext.getVariantConfiguration().getBuildType().getProguardFiles());\n        Collections.sort(defaultProguardFiles);\n\n        BaseVariantOutput vod = (BaseVariantOutput) appVariantContext.getVariantOutputData().iterator().next();\n        AppVariantOutputContext appVariantOutputContext = appVariantContext.getAppVariantOutputContext(ApkDataUtils.get(vod));\n\n        int parallelCount = appVariantContext.getAtlasExtension().getTBuildConfig().getProguardParallelCount();\n        ////FIXME\n        //parallelCount = 1;\n\n        Map<BundleInfo, AwbTransform> bundleInfoAwbTransformMap = new HashMap<>();\n        for (AwbTransform awbTransform : appVariantOutputContext.getAwbTransformMap().values()) {\n            bundleInfoAwbTransformMap.put(awbTransform.getAwbBundle().bundleInfo, awbTransform);\n        }\n        Profiler.release();\n\n        BundleGraphExecutor.execute(new ArrayList<>(bundleInfoAwbTransformMap.keySet()), parallelCount,\n                                    new BundleItemRunner() {\n                                        @Override\n                                        public void execute(BundleItem bundleItem) {\n\n                                            try {\n\n                                                Input input = new Input();\n                                                AwbTransform awbTransform = bundleInfoAwbTransformMap.get(\n                                                    bundleItem.bundleInfo);\n                                                input.getAwbBundles().add(awbTransform);\n                                                for (BundleInfo sub : bundleItem.circles) {\n                                                    input.getAwbBundles().add(bundleInfoAwbTransformMap.get(sub));\n                                                }\n\n                                                input.getDefaultProguardFiles().addAll(defaultProguardFiles);\n                                                input.getLibraries().addAll(libs);\n                                                input.getDefaultLibraryClasses().addAll(defaultLibClasses);\n\n                                                input.printConfiguration = new File(\n                                                    appVariantContext\n                                                        .getAwbProguardDir(input.getAwbBundles().get(0).getAwbBundle()),\n                                                    \"proguard.cfg\");\n                                                input.printUsage = new File(\n                                                    appVariantContext\n                                                        .getAwbProguardDir(input.getAwbBundles().get(0).getAwbBundle()),\n                                                    \"usage.cfg\");\n\n                                                addLibraryProguardFiles(appVariantContext, input);\n\n                                                addChildDependency(bundleItem, input, bundleInfoAwbTransformMap);\n\n                                                addParentKeeps(bundleItem, input, awbTransform,\n                                                               bundleInfoAwbTransformMap, appVariantContext);\n\n                                                BundleProguarder.execute(appVariantContext, input);\n\n                                            } catch (Exception e) {\n                                                e.printStackTrace();\n                                                throw new GradleException(\n                                                    \"proguard \" + bundleItem.bundleInfo.getPkgName(), e);\n                                            }\n                                        }\n                                    });\n\n    }\n\n    @NotNull\n    private static void addLibraryProguardFiles(AppVariantContext appVariantContext, Input input) {\n\n        if (!appVariantContext.getAtlasExtension().getTBuildConfig().isBundleProguardConfigEnabled()) {\n            return;\n        }\n\n        Set<String> blackList = appVariantContext.getAtlasExtension().getTBuildConfig()\n            .getBundleProguardConfigBlackList();\n        for (AwbTransform awbTransform : input.getAwbBundles()) {\n            AwbBundle awbBundle = awbTransform.getAwbBundle();\n            for (AndroidLibrary androidDependency : awbBundle.getAllLibraryAars()) {\n                File proguardRules = androidDependency.getProguardRules();\n                String groupName = androidDependency.getResolvedCoordinates().getGroupId() + \":\" + androidDependency\n                    .getResolvedCoordinates().getArtifactId();\n                if (blackList.contains(groupName)) {\n                    sLogger.info(\"[proguard] skip proguard from \" + androidDependency.getResolvedCoordinates());\n                    continue;\n                }\n                if (proguardRules.exists() && proguardRules.isFile()) {\n                    input.getLibraryProguardFiles().add(proguardRules);\n                    sLogger.warn(\"[proguard] load proguard from \" + androidDependency.getResolvedCoordinates());\n                } else {\n                    sLogger.info(\"[proguard] missing proguard from \" + androidDependency.getResolvedCoordinates());\n                }\n            }\n        }\n    }\n\n    private static void addChildDependency(BundleItem bundleItem, Input input,\n                                           Map<BundleInfo, AwbTransform> bundleInfoAwbTransformMap) throws IOException {\n\n        List<String>pkgNames = new ArrayList<>();\n\n        input.getAwbBundles().forEach(awbTransform -> pkgNames.add(awbTransform.getAwbBundle().getPackageName()));\n\n        sLogger.info(\"combine to proguard bundles:\"+pkgNames.toString());\n\n        List<AwbTransform> childTransforms = new ArrayList<>();\n\n        sLogger.info(\"combine to proguard bundles:\"+pkgNames.toString());\n\n        for (BundleItem child : bundleItem.children) {\n            if (!pkgNames.contains(child.bundleInfo.getPkgName())) {\n                childTransforms.add(bundleInfoAwbTransformMap.get(child.bundleInfo));\n            }else {\n                sLogger.error(child.bundleInfo.getPkgName() +\" in proguard bundles so discard from \"+ bundleItem.bundleInfo.getPkgName()+\"libraries...\");\n            }\n            for (BundleInfo sub : child.circles) {\n                if (!pkgNames.contains(sub.getPkgName())) {\n                    childTransforms.add(bundleInfoAwbTransformMap.get(sub));\n                }else {\n                    sLogger.error(sub.getPkgName() +\" in proguard bundles so discard from \"+ bundleItem.bundleInfo.getPkgName()+\" libraries...\");\n\n                }\n            }\n        }\n\n        List<AwbBundle> childBundles = new ArrayList<>();\n        for (AwbTransform child : childTransforms) {\n            input.getLibraries().addAll(child.getInputLibraries());\n            //join\n            childBundles.add(child.getAwbBundle());\n        }\n    }\n\n    private static void addParentKeeps(BundleItem bundleItem, Input input, AwbTransform awbTransform,\n                                       Map<BundleInfo, AwbTransform> bundleInfoAwbTransformMap,\n                                       AppVariantContext appVariantContext) throws IOException {\n        Set<AwbBundle> parentBundles = new HashSet<>();\n        for (BundleItem parent : bundleItem.parents) {\n            parentBundles.add(bundleInfoAwbTransformMap.get(parent.bundleInfo).getAwbBundle());\n            for (BundleInfo sub : parent.circles) {\n                parentBundles.add(bundleInfoAwbTransformMap.get(sub).getAwbBundle());\n            }\n        }\n        if (!parentBundles.isEmpty()) {\n            List<AwbBundle> bundles = new ArrayList<>(parentBundles);\n            Collections.sort(bundles, new Comparator<AwbBundle>() {\n                @Override\n                public int compare(AwbBundle o1, AwbBundle o2) {\n                    return o1.getName().compareTo(o2.getName());\n                }\n            });\n            File keepFile = generateKeepFile(bundles,\n                                             appVariantContext.getAwbProguardDir(\n                                                 awbTransform.getAwbBundle()));\n            input.getParentKeeps().add(keepFile);\n        }\n    }\n\n    public static Set<String> getClassList(List<File> files) throws IOException {\n        Set<String> sets = new HashSet<>();\n        for (File file : files) {\n\n            JarFile jarFile = new JarFile(file);\n            Enumeration<JarEntry> entryEnumeration = jarFile.entries();\n\n            while (entryEnumeration.hasMoreElements()) {\n                JarEntry jarEntry = entryEnumeration.nextElement();\n                if (null == jarEntry) {\n                    continue;\n                }\n                String name = jarEntry.getName();\n                if (name.endsWith(\".class\")) {\n                    name = name.substring(0, name.length() - 6);\n                    sets.add(name);\n                }\n            }\n        }\n        return sets;\n    }\n\n    public static void applyBundleKeepsV2(final AppVariantContext appVariantContext,\n                                          ProGuardTransform proGuardTransform) throws IOException {\n\n        File maindexkeep = generateBundleKeepCfg(appVariantContext);\n\n        proGuardTransform.setConfigurationFiles(appVariantContext.getScope().getGlobalScope().getProject().files(maindexkeep));\n\n    }\n\n    @NotNull\n    public static File generateBundleKeepCfg(AppVariantContext appVariantContext) throws IOException {\n        AtlasDependencyTree dependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n            appVariantContext.getVariantConfiguration().getFullName());\n        return generateKeepFile(dependencyTree.getAwbBundles(),\n                                appVariantContext.getScope().getGlobalScope().getOutputsDir());\n    }\n\n    @NotNull\n    private static File generateKeepFile(List<AwbBundle> awbBundles, File dir) throws IOException {\n\n        KeepConverter refClazzContainer = new KeepConverter();\n        for (AwbBundle awbBundle : awbBundles) {\n            if (null != awbBundle.getKeepProguardFile() && awbBundle.getKeepProguardFile().exists()) {\n\n                String json = FileUtils.readFileToString(awbBundle.getKeepProguardFile());\n                Map<String, ClazzRefInfo> refClazzMap = JSON.parseObject(json,\n                                                                         new TypeReference<Map<String, ClazzRefInfo>>\n                                                                             () {});\n\n                refClazzContainer.addRefClazz(refClazzMap);\n\n            } else {\n                sLogger.error(\n                    \"missing \" + awbBundle.getKeepProguardFile().getAbsolutePath());\n            }\n        }\n\n        File maindexkeep = new File(dir, \"maindexkeep.cfg\");\n        FileUtils.writeLines(maindexkeep, refClazzContainer.convertToKeeplines());\n        return maindexkeep;\n    }\n\n    public static void applyBundleKeeps(final AppVariantContext appVariantContext,\n                                        ProGuardTransform proGuardTransform) {\n\n        Set<File> proguardFiles = new HashSet<File>();\n\n        GlobalScope globalScope = appVariantContext.getScope().getGlobalScope();\n        //Add awb configuration\n        AtlasDependencyTree dependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n            appVariantContext.getVariantConfiguration().getFullName());\n\n        for (AwbBundle awbBundle : dependencyTree.getAwbBundles()) {\n            if (null != awbBundle.getKeepProguardFile() && awbBundle.getKeepProguardFile().exists()) {\n                proguardFiles.add(awbBundle.getKeepProguardFile());\n            } else {\n                appVariantContext.getProject().getLogger().error(\n                    \"missing \" + awbBundle.getKeepProguardFile().getAbsolutePath());\n            }\n        }\n\n        proGuardTransform.setConfigurationFiles(appVariantContext.getScope().getGlobalScope().getProject().files(proguardFiles));\n\n    }\n\n    public static File applyBundleInOutConfigration(final AppVariantContext appVariantContext,\n                                                    ProGuardTransform proGuardTransform) {\n\n        VariantScope variantScope = appVariantContext.getScope();\n\n        GlobalScope globalScope = variantScope.getGlobalScope();\n        File proguardOut = new File(Joiner.on(File.separatorChar)\n                                        .join(String.valueOf(globalScope.getBuildDir()), FD_OUTPUTS, \"mapping\",\n                                              variantScope.getVariantConfiguration().getDirName()));\n\n        File awbInOutConfig = new File(proguardOut, \"awb_inout_config.cfg\");\n\n        //Add awb configuration\n        AtlasDependencyTree dependencyTree = AtlasBuildContext.androidDependencyTrees.get(\n            variantScope.getVariantConfiguration().getFullName());\n\n        if (dependencyTree.getAwbBundles().size() > 0) {\n\n            BaseVariantOutput vod = (BaseVariantOutput) appVariantContext.getVariantOutputData().iterator().next();\n            AppVariantOutputContext appVariantOutputContext = appVariantContext.getAppVariantOutputContext(ApkDataUtils.get(vod));\n            File awbObfuscatedDir = new File(globalScope.getIntermediatesDir(),\n                                             \"/classes-proguard/\" + variantScope.getVariantConfiguration()\n                                                 .getDirName());\n            AwbProguardConfiguration awbProguardConfiguration = new AwbProguardConfiguration(\n                appVariantOutputContext.getAwbTransformMap().values(), awbObfuscatedDir, appVariantOutputContext);\n\n            try {\n                configs = awbProguardConfiguration.printConfigFile(awbInOutConfig);\n            } catch (IOException e) {\n                throw new GradleException(\"\", e);\n            }\n\n            proGuardTransform.setConfigurationFiles(appVariantContext.getScope().getGlobalScope().getProject().files(awbInOutConfig));\n\n        }\n\n        return awbInOutConfig;\n    }\n\n    //TODO move\n    //public static Set<String> blackList = Sets.newHashSet(\"com.alibaba:eaze\",\"com.alibaba.mobileim:IMKit\");\n    public static void applyBundleProguardConfigration(final AppVariantContext appVariantContext,\n                                                       ProGuardTransform proGuardTransform) {\n\n        Set<String> blackList = appVariantContext.getAtlasExtension().getTBuildConfig()\n            .getBundleProguardConfigBlackList();\n\n        List<File> proguardFiles = new ArrayList<>();\n        VariantScope variantScope = appVariantContext.getScope();\n        for (AwbBundle awbBundle : AtlasBuildContext.androidDependencyTrees.get(\n            variantScope.getVariantConfiguration().getFullName()).getAwbBundles()) {\n            for (AndroidLibrary androidDependency : awbBundle.getAllLibraryAars()) {\n                File proguardRules = androidDependency.getProguardRules();\n\n                String groupName = androidDependency.getResolvedCoordinates().getGroupId() + \":\" + androidDependency\n                    .getResolvedCoordinates().getArtifactId();\n                if (blackList.contains(groupName)) {\n                    sLogger.info(\"[proguard] skip proguard from \" + androidDependency.getResolvedCoordinates());\n                    continue;\n                }\n\n                if (proguardRules.isFile()) {\n                    proguardFiles.add(proguardRules);\n                    sLogger.warn(\"[proguard] load proguard from \" + androidDependency.getResolvedCoordinates());\n                } else {\n                    sLogger.info(\"[proguard] missing proguard from \" + androidDependency.getResolvedCoordinates());\n                }\n            }\n        }\n\n        proGuardTransform.setConfigurationFiles(appVariantContext.getScope().getGlobalScope().getProject().files(proguardFiles));\n\n    }\n\n    public static File applyMapping(final AppVariantContext appVariantContext, ProGuardTransform proGuardTransform) {\n\n        File mappingFile = null;\n        if (null != appVariantContext.apContext.getApExploredFolder() && appVariantContext.apContext\n            .getApExploredFolder().exists()) {\n            mappingFile = new File(appVariantContext.apContext.getApExploredFolder(), \"mapping.txt\");\n        } else {\n            mappingFile = new File(\n                appVariantContext.getScope().getGlobalScope().getProject().getProjectDir(),\n                \"mapping.txt\");\n        }\n\n        if (null != mappingFile && mappingFile.exists()) {\n            proGuardTransform.applyTestedMapping(mappingFile);\n            return mappingFile;\n        }\n\n        return null;\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/AwbProguardConfiguration.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.proguard;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\nimport com.android.build.gradle.internal.api.AppVariantOutputContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.google.common.collect.Lists;\nimport org.apache.commons.io.FileUtils;\n\n/**\n * Add Awb configuration to confusing configuration\n * Created by shenghua.nish on 2016-06-12 This morning.\n */\n@Deprecated\npublic class AwbProguardConfiguration {\n\n    public static final String INJARS_OPTION = \"-injars\";\n\n    public static final String OUTJARS_OPTION = \"-outjars\";\n\n    public static final String OBUSCATED_JAR = \"obfuscated.jar\";\n\n    private final Collection<AwbTransform> awbTransforms;\n\n    private final File awbObfuscatedDir;\n\n    private final AppVariantOutputContext appVariantOutputContext;\n\n    public AwbProguardConfiguration(Collection<AwbTransform> awbTransforms,\n                                    File awbObfuscatedDir,\n                                    AppVariantOutputContext appVariantOutputContext) {\n        this.awbTransforms = awbTransforms;\n        this.awbObfuscatedDir = awbObfuscatedDir;\n        this.appVariantOutputContext = appVariantOutputContext;\n    }\n\n    /**\n     * Print the proguard config file to the specified file\n     *\n     * @param outConfigFile\n     */\n    public List<File> printConfigFile(File outConfigFile) throws IOException {\n        List<String> configs = Lists.newArrayList();\n        List<File> bundleFiles = Lists.newArrayList();\n\n        //awbProguard for no lib, convenient for predex\n        for (AwbTransform awbTransform : awbTransforms) {\n\n            List<File> inputLibraries = Lists.newArrayList();\n\n            String name = awbTransform.getAwbBundle().getName();\n            File obuscateDir = new File(awbObfuscatedDir, awbTransform.getAwbBundle().getName());\n            obuscateDir.mkdirs();\n\n            //configs.add();\n\n            if (null != awbTransform.getInputDirs() && awbTransform.getInputDirs().size() > 0) {\n                for (File dir : awbTransform.getInputDirs()) {\n                    if (dir.exists()) {\n                        configs.add(INJARS_OPTION + \" \" + dir.getAbsolutePath());\n                        File obsJar = new File(obuscateDir, \"inputdir_\" + OBUSCATED_JAR);\n                        inputLibraries.add(obsJar);\n                        configs.add(OUTJARS_OPTION + \" \" + obsJar.getAbsolutePath());\n\n                    }\n                }\n            }\n\n            Set<String> classNames = new HashSet<>();\n            for (File inputLibrary : awbTransform.getInputLibraries()) {\n                configs.add(INJARS_OPTION + \" \" + inputLibrary.getAbsolutePath());\n                bundleFiles.add(inputLibrary);\n                String fileName = inputLibrary.getName();\n\n                if (classNames.contains(fileName)) {\n                    fileName = \"a\" + classNames.size() + \"_\" + fileName;\n                }\n\n                classNames.add(fileName);\n\n                File obsJar = new File(obuscateDir, fileName);\n\n                inputLibraries.add(obsJar);\n                configs.add(OUTJARS_OPTION + \" \" + obsJar.getAbsolutePath());\n            }\n            //            configs.add();\n\n            awbTransform.setInputFiles(inputLibraries);\n            awbTransform.getInputDirs().clear();\n            awbTransform.getInputLibraries().clear();\n            appVariantOutputContext.getAwbTransformMap().put(name, awbTransform);\n        }\n        FileUtils.writeLines(outConfigFile, configs);\n        return bundleFiles;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/BundleProguarder.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.proguard;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport com.alibaba.fastjson.JSON;\n\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport com.taobao.android.builder.tasks.app.BuildAtlasEnvTask;\nimport com.taobao.android.builder.tools.FileNameUtils;\nimport com.taobao.android.builder.tools.ReflectUtils;\nimport com.taobao.android.builder.tools.cache.FileCacheCenter;\nimport com.taobao.android.builder.tools.cache.FileCacheException;\nimport com.taobao.android.builder.tools.log.FileLogger;\nimport com.taobao.android.builder.tools.proguard.domain.Input;\nimport com.taobao.android.builder.tools.proguard.domain.Result;\nimport com.taobao.android.builder.tools.proguard.dump.BundleProguardDumper;\nimport com.taobao.android.builder.tools.proguard.dump.ClazzRefInfo;\nimport com.taobao.android.builder.tools.zip.ZipUtils;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.jetbrains.annotations.NotNull;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport proguard.Configuration;\nimport proguard.ConfigurationParser;\nimport proguard.ParseException;\nimport proguard.ProGuard;\nimport proguard.classfile.ClassPool;\n\nimport static com.taobao.android.builder.tools.proguard.AwbProguardConfiguration.INJARS_OPTION;\nimport static com.taobao.android.builder.tools.proguard.AwbProguardConfiguration.OUTJARS_OPTION;\nimport static proguard.AtlasProguardConstants.INOUT_CFG;\n\n/**\n * Created by wuzhong on 2017/5/13.\n */\npublic class BundleProguarder {\n\n    public static final String CACHE_TYPE = \"proguard-bundles-0.12\";\n\n    private static Logger logger = LoggerFactory.getLogger(BundleProguarder.class);\n    private static FileLogger fileLogger = FileLogger.getInstance(\"proguard\");\n\n    public static void execute(AppVariantContext appVariantContext, Input input) throws Exception {\n        if (input.proguardOutputDir != null && input.proguardOutputDir.exists()) {\n            FileUtils.cleanDirectory(input.proguardOutputDir);\n        }\n        if (!appVariantContext.getAtlasExtension().getTBuildConfig().isProguardCacheEnabled()) {\n            doProguard(appVariantContext, input);\n            return;\n        }\n\n        String md5 = input.getMd5();\n\n        Result result = loadProguardFromCache(appVariantContext, input);\n\n        String bundleName = input.getAwbBundles().get(0).getAwbBundle().getName();\n\n        if (result.success) {\n            fileLogger.log(bundleName + \" hit cache \" + result.cacheDir.getAbsolutePath());\n            return;\n        }\n        fileLogger.log(bundleName + \" miss cache \" + result.cacheDir.getAbsolutePath());\n\n        long startTime = System.currentTimeMillis();\n        doProguard(appVariantContext, input);\n        double during = (System.currentTimeMillis() - startTime) / 1000.0;\n        fileLogger.log(bundleName + \"proguard consume (s) \" + during);\n\n        //cache\n        if (null != result.cacheDir) {\n            try {\n                cacheProguard(appVariantContext, input, result);\n            } catch (Throwable e) {\n                logger.error(e.getMessage(), e);\n            }\n        }\n\n    }\n\n    public static Result loadProguardFromCache(AppVariantContext appVariantContext, Input input) throws Exception {\n\n        Result result = new Result();\n\n        String md5 = input.getMd5();\n\n        result.key = input.getAwbBundles().get(0).getAwbBundle().getName() + \"_\" + md5;\n\n        logger.info(\"bundle proguard for \" + result.key + \" with md5 key \" + md5);\n\n        File cacheDir = FileCacheCenter.queryFile(CACHE_TYPE, result.key, true,\n                                                  isRemoteCacheEnabled(appVariantContext));\n        result.cacheDir = cacheDir;\n        if (null == cacheDir || !cacheDir.exists()) {\n            logger.warn(\"bundle proguard for \" + result.key + \" miss  cache \" + cacheDir.getAbsolutePath());\n            return result;\n        }\n        logger.warn(\"bundle proguard for \" + result.key + \" hit  cache \");\n\n        File keepJson = new File(cacheDir, \"keep.json\");\n        File proguardCfg = new File(cacheDir, \"proguard.cfg\");\n        File usageCfg = new File(cacheDir, \"usage.cfg\");\n\n        Map<String,File> md5Map = input.getMd5Files();\n\n        if (input.getAwbBundles().get(0).getAwbBundle().isMainBundle()) {\n            AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).getMainDexFiles().clear();\n            AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).getInputDirs().clear();\n\n            for (File file : cacheDir.listFiles()) {\n                if (file.getName().endsWith(\"jar\") && ZipUtils.isZipFile(file)) {\n\n                    String jarMd5 = file.getName().replace(\".jar\",\"\");\n                    File srcFile = md5Map.get(jarMd5);\n\n                    if ( null != srcFile && srcFile.exists()){\n                        String fileName = FileNameUtils.getUniqueJarName(srcFile);\n                        FileUtils.copyFile(file,new File(input.proguardOutputDir,   fileName+\".jar\"));\n                        AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).addMainDex(new BuildAtlasEnvTask.FileIdentity(fileName,new File(input.proguardOutputDir, fileName + \".jar\"),false,false));\n                    }else {\n                        FileUtils.copyFileToDirectory(file, input.proguardOutputDir);\n                        AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).addMainDex(new BuildAtlasEnvTask.FileIdentity(file.getName(),new File(input.proguardOutputDir, file.getName()),false,false));\n\n                    }\n\n                }\n            }\n\n            File awbProguardDir = input.printConfiguration.getParentFile();\n            //FileUtils.copyFileToDirectory(keepJson, awbProguardDir);\n            if (proguardCfg.exists()) {\n                FileUtils.copyFileToDirectory(proguardCfg,\n                                              awbProguardDir);\n            }\n            if (usageCfg.exists()) {\n                FileUtils.copyFileToDirectory(usageCfg,\n                                              awbProguardDir);\n            }\n\n            result.success = true;\n            return result;\n        } else {\n\n            if (!keepJson.exists()) {\n                logger.error(\"bundle proguard for \" + result.key + \" missing keep.json  \");\n                FileUtils.deleteDirectory(cacheDir);\n                return result;\n            }\n\n            Map<AwbTransform, List<File>> transformListMap = new HashMap<>();\n            for (AwbTransform awbTransform : input.getAwbBundles()) {\n\n                File awbProguardDir = appVariantContext.getAwbProguardDir(awbTransform.getAwbBundle());\n                FileUtils.copyFileToDirectory(keepJson, awbProguardDir);\n                if (proguardCfg.exists()) {\n                    FileUtils.copyFileToDirectory(proguardCfg,\n                                                  awbProguardDir);\n                }\n                if (usageCfg.exists()) {\n                    FileUtils.copyFileToDirectory(usageCfg,\n                                                  awbProguardDir);\n                }\n\n                List<File> inputFiles = new ArrayList<>();\n                transformListMap.put(awbTransform, inputFiles);\n\n                List<File> files = new ArrayList<>();\n                files.addAll(awbTransform.getInputLibraries());\n\n                //configs.add();\n                if (null != awbTransform.getInputDirs() && awbTransform.getInputDirs().size() > 0) {\n                    files.addAll(awbTransform.getInputDirs());\n                }\n\n                for (File oldFile : files) {\n                    File file = new File(cacheDir, input.getFileMd5s().get(oldFile) + \".jar\");\n                    if (file.exists()) {\n                        if (ZipUtils.isZipFile(file)) {\n                            inputFiles.add(file);\n                        }\n                    } else {\n                        logger.error(\"miss proguard jar for :\" + file.getAbsolutePath());\n                        FileUtils.deleteDirectory(cacheDir);\n                        logger.error(\"delete cache Dir \" + cacheDir.getAbsolutePath());\n                        return result;\n                    }\n                }\n            }\n\n            for (AwbTransform awbTransform : input.getAwbBundles()) {\n                awbTransform.setInputFiles(transformListMap.get(awbTransform));\n                awbTransform.getInputDirs().clear();\n                awbTransform.getInputLibraries().clear();\n                awbTransform.getAwbBundle().setKeepProguardFile(keepJson);\n            }\n\n            result.success = true;\n            return result;\n\n        }\n\n    }\n\n    private static boolean isRemoteCacheEnabled(AppVariantContext appVariantContext) {\n        return appVariantContext.getAtlasExtension().getTBuildConfig().isProguardNetworkCacheEnabled();\n    }\n\n    public static void doProguard(AppVariantContext appVariantContext, Input input)\n        throws Exception {\n\n        Configuration configuration = parseConfiguration(appVariantContext, input);\n        configuration.dump = input.dump;\n        if (null == input.printConfiguration) {\n            configuration.printConfiguration = new File(\n                appVariantContext.getAwbProguardDir(input.getAwbBundles().get(0).getAwbBundle()), \"proguard.cfg\");\n        } else {\n            configuration.printConfiguration = input.printConfiguration;\n        }\n\n        configuration.printSeeds = null;\n        configuration.dump = null;\n        configuration.obfuscate = false;\n//        configuration.optimizationPasses = 1;\n\n        configuration.printUsage = input.printUsage;\n        configuration.printMapping = input.printMapping;\n\n        // Execute ProGuard with these options.\n        ProGuard proGuard = new ProGuard(configuration);\n\n        System.out.println(\">>> start to do proguard\");\n\n        proGuard.execute();\n        System.out.println(\"<<< end proguard\");\n\n        ClassPool classPool = (ClassPool)ReflectUtils.getField(proGuard, \"programClassPool\");\n\n        Map<String, ClazzRefInfo> clazzRefInfoMap = BundleProguardDumper.dump(proGuard,\n                                                                              input.getDefaultLibraryClasses());\n\n\n        //Fileoutputs\n        for (AwbTransform awbTransform : input.getAwbBundles()) {\n            if (!awbTransform.getAwbBundle().isMainBundle()) {\n                AwbBundle awbBundle = awbTransform.getAwbBundle();\n                File fileOut = new File(appVariantContext.getAwbProguardDir(awbBundle), \"keep.json\");\n                fileOut.delete();\n                fileOut.getParentFile().mkdirs();\n                FileUtils.write(fileOut, JSON.toJSONString(clazzRefInfoMap));\n                awbBundle.setKeepProguardFile(fileOut);\n            }\n        }\n\n    }\n\n\n    @NotNull\n    private static Configuration parseConfiguration(AppVariantContext appVariantContext, Input input)\n        throws IOException, ParseException {\n        Configuration configuration = new Configuration();\n\n        List<File> proguardFiles = new ArrayList<>();\n\n        proguardFiles.add(printInOut(appVariantContext, input));\n\n        proguardFiles.addAll(input.getDefaultProguardFiles());\n        proguardFiles.addAll(input.getParentKeeps());\n        for (File file : proguardFiles) {\n            ConfigurationParser parser = new ConfigurationParser(file, System.getProperties());\n            try {\n                parser.parse(configuration);\n            } finally {\n                parser.close();\n            }\n        }\n\n        for (File file : input.getLibraryProguardFiles()) {\n            KeepOnlyConfigurationParser parser = new KeepOnlyConfigurationParser(file, System.getProperties());\n            try {\n                parser.parse(configuration);\n            } finally {\n                parser.close();\n            }\n        }\n        return configuration;\n    }\n\n    private static File printInOut(AppVariantContext appVariantContext, Input input)\n        throws IOException {\n\n        File proguardDir = input.proguardOutputDir;\n        if (null == proguardDir) {\n            proguardDir = appVariantContext.getAwbProguardDir(input.getAwbBundles().get(0).getAwbBundle());\n        }\n        proguardDir.mkdirs();\n\n        File inoutConfigs = new File(proguardDir, INOUT_CFG);\n        List<String> configs = new ArrayList<>();\n\n\n\n\n        for (AwbTransform awbTransform : input.getAwbBundles()) {\n\n            List<File> inputLibraries = Lists.newArrayList();\n\n            for (File inputLibrary : awbTransform.getInputLibraries()) {\n\n                configs.add(INJARS_OPTION + \" \" + inputLibrary.getAbsolutePath());\n\n                String name = FileNameUtils.getUniqueJarName(inputLibrary);\n                File obsJar = new File(proguardDir, name + \".jar\");\n\n                input.proguardJarMap.put(obsJar, input.getFileMd5s().get(inputLibrary));\n\n                inputLibraries.add(obsJar);\n                configs.add(OUTJARS_OPTION + \" \" + obsJar.getAbsolutePath());\n\n                if (inputLibrary.isDirectory() && AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).getInputDirs().contains(inputLibrary)){\n                    input.maindexFolderTransform.put(inputLibrary,obsJar);\n                }else if (AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).inMainDex(inputLibrary)) {\n                    input.maindexFileTransform.put(inputLibrary,obsJar);\n//                    AtlasBuildContext.atlasMainDexHelper.updateMainDexFile(inputLibrary, obsJar);\n                }else if (awbTransform.getAwbBundle().isMainBundle()){\n                    AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).addMainDex(new BuildAtlasEnvTask.FileIdentity(obsJar.getName(),obsJar,false,false));\n                }\n            }\n\n            //configs.add();\n            if (null != awbTransform.getInputDirs() && awbTransform.getInputDirs().size() > 0) {\n\n                for (File dir:awbTransform.getInputDirs()) {\n                    if (!dir.exists()){\n                        continue;\n                    }\n                    configs.add(INJARS_OPTION + \" \" + dir.getAbsolutePath());\n\n                    String name = input.getFileMd5s().get(dir);\n                    if (null == name) {\n                        name = FileNameUtils.getUniqueFileName(dir.getName(), \"proguard\");\n                    }\n\n                    File obsJar = new File(proguardDir,\n                            name + \".jar\");\n                    inputLibraries.add(obsJar);\n                    configs.add(OUTJARS_OPTION + \" \" + obsJar.getAbsolutePath());\n                    if (awbTransform.getAwbBundle().isMainBundle()) {\n                        AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).getInputDirs().clear();\n                        AtlasBuildContext.atlasMainDexHelperMap.get(appVariantContext.getVariantName()).addMainDex(new BuildAtlasEnvTask.FileIdentity(obsJar.getName(), obsJar, false, false));\n                    }\n                }\n\n            }\n\n            awbTransform.setInputFiles(inputLibraries);\n            awbTransform.getInputDirs().clear();\n            awbTransform.getInputLibraries().clear();\n        }\n\n        for (File library : input.getLibraries()) {\n            configs.add(\"-libraryjars \" + library.getAbsolutePath());\n        }\n\n        FileUtils.writeLines(inoutConfigs, configs);\n\n        return inoutConfigs;\n    }\n\n    private static void cacheProguard(AppVariantContext appVariantContext, Input input, Result result)\n        throws FileCacheException, IOException {\n\n        AwbBundle awbBundle = input.getAwbBundles().get(0).getAwbBundle();\n        File tmpDir = new File(appVariantContext.getScope().getGlobalScope().getIntermediatesDir(),\n                               \"progurad-cache/\" + awbBundle.getName());\n        tmpDir.mkdirs();\n\n        for (AwbTransform awbTransform : input.getAwbBundles()) {\n            for (File file : awbTransform.getInputFiles()) {\n                if (file.exists()) {\n                    String md5 = input.proguardJarMap.get(file);\n                    if (StringUtils.isNoneEmpty(md5)) {\n                        FileUtils.copyFile(file, new File(tmpDir, md5 + \".jar\"));\n                    } else {\n                        FileUtils.copyFileToDirectory(file, tmpDir);\n                    }\n                } else {\n                    new File(tmpDir, file.getName()).createNewFile();\n                }\n            }\n        }\n\n        //Keep cache. Json\n        File keepFile = awbBundle.getKeepProguardFile();\n        if (null != keepFile && keepFile.exists()) {\n            FileUtils.copyFileToDirectory(keepFile, tmpDir);\n        }\n\n        File proguardCfg = new File(null != input.proguardOutputDir ? input.proguardOutputDir\n                                        : appVariantContext\n                                            .getAwbProguardDir(awbBundle),\n                                    \"proguard.cfg\");\n        if (!proguardCfg.exists()){\n            proguardCfg = input.printConfiguration;\n        }\n        if ( null != proguardCfg && proguardCfg.exists()) {\n            FileUtils.copyFileToDirectory(proguardCfg, tmpDir);\n        }\n\n        File usageCfg = new File(null != input.proguardOutputDir ? input.proguardOutputDir\n                                     : appVariantContext\n                                         .getAwbProguardDir(awbBundle),\n                                 \"usage.cfg\");\n        if (!usageCfg.exists()){\n            usageCfg = input.printUsage;\n        }\n        if ( null != usageCfg && usageCfg.exists()) {\n            FileUtils.copyFileToDirectory(usageCfg, tmpDir);\n        }\n\n        FileCacheCenter.cacheFile(CACHE_TYPE, result.key, tmpDir,\n                                  AtlasBuildContext.sBuilderAdapter.pushCacheToNetwork && isRemoteCacheEnabled(\n                                      appVariantContext));\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/KeepOnlyConfigurationParser.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\npackage com.taobao.android.builder.tools.proguard;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.LineNumberReader;\nimport java.io.StringReader;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Properties;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport proguard.ArgumentWordReader;\nimport proguard.AtlasProguardConstants;\nimport proguard.ClassPath;\nimport proguard.ClassPathEntry;\nimport proguard.ClassSpecification;\nimport proguard.Configuration;\nimport proguard.ConfigurationParser;\nimport proguard.FileWordReader;\nimport proguard.KeepClassSpecification;\nimport proguard.LineWordReader;\nimport proguard.MemberSpecification;\nimport proguard.ParseException;\nimport proguard.WordReader;\nimport proguard.classfile.ClassConstants;\nimport proguard.classfile.JavaConstants;\nimport proguard.classfile.util.ClassUtil;\nimport proguard.util.ListUtil;\n\n/**\n * This class parses ProGuard configurations. Configurations can be read from an\n * array of arguments or from a configuration file or URL. External references\n * in file names ('<...>') can be resolved against a given set of properties.\n *\n * @author Eric Lafortune\n */\npublic class KeepOnlyConfigurationParser {\n    private static Logger sLogger = LoggerFactory.getLogger(KeepOnlyConfigurationParser.class);\n\n    private final WordReader reader;\n    private final Properties properties;\n\n    private String nextWord;\n    private String lastComments;\n\n    private String filePath;\n\n    /**\n     * Creates a new ConfigurationParser for the given String arguments and\n     * the given Properties.\n     */\n    public KeepOnlyConfigurationParser(String[] args,\n                                       Properties properties) throws IOException {\n        this(args, null, properties);\n    }\n\n    /**\n     * Creates a new ConfigurationParser for the given String arguments,\n     * with the given base directory and the given Properties.\n     */\n    public KeepOnlyConfigurationParser(String[] args,\n                                       File baseDir,\n                                       Properties properties) throws IOException {\n        this(new ArgumentWordReader(args, baseDir), properties);\n    }\n\n    /**\n     * Creates a new ConfigurationParser for the given lines,\n     * with the given base directory and the given Properties.\n     */\n    public KeepOnlyConfigurationParser(String lines,\n                                       String description,\n                                       File baseDir,\n                                       Properties properties) throws IOException {\n        this(new LineWordReader(new LineNumberReader(new StringReader(lines)),\n                                description,\n                                baseDir),\n             properties);\n    }\n\n    /**\n     * Creates a new ConfigurationParser for the given file, with the system\n     * Properties.\n     *\n     * @deprecated Temporary code for backward compatibility in Obclipse.\n     */\n    public KeepOnlyConfigurationParser(File file) throws IOException {\n        this(file, System.getProperties());\n    }\n\n    /**\n     * Creates a new ConfigurationParser for the given file and the given\n     * Properties.\n     */\n    public KeepOnlyConfigurationParser(File file,\n                                       Properties properties) throws IOException {\n        this(new FileWordReader(file), properties);\n        this.filePath = file.getAbsolutePath();\n    }\n\n    /**\n     * Creates a new ConfigurationParser for the given URL and the given\n     * Properties.\n     */\n    public KeepOnlyConfigurationParser(URL url,\n                                       Properties properties) throws IOException {\n        this(new FileWordReader(url), properties);\n    }\n\n    /**\n     * Creates a new ConfigurationParser for the given word reader and the\n     * given Properties.\n     */\n    public KeepOnlyConfigurationParser(WordReader reader,\n                                       Properties properties) throws IOException {\n        this.reader = reader;\n        this.properties = properties;\n\n        readNextWord();\n    }\n\n    /**\n     * Parses and returns the configuration.\n     *\n     * @param configuration the configuration that is updated as a side-effect.\n     * @throws ParseException if the any of the configuration settings contains\n     * a syntax error.\n     * @throws IOException if an IO error occurs while reading a configuration.\n     */\n    public void parse(Configuration configuration)\n        throws ParseException, IOException {\n        while (nextWord != null) {\n            lastComments = reader.lastComments();\n\n            // First include directives.\n            if (AtlasProguardConstants.AT_DIRECTIVE.startsWith(nextWord) ||\n                AtlasProguardConstants.INCLUDE_DIRECTIVE.startsWith(nextWord)) {\n                configuration.lastModified = parseIncludeArgument(configuration.lastModified);\n            } else if (AtlasProguardConstants.BASE_DIRECTORY_DIRECTIVE.startsWith(nextWord)) {\n                parseBaseDirectoryArgument();\n            }\n\n            // Then configuration options with or without arguments.\n            else if (AtlasProguardConstants.INJARS_OPTION.startsWith(nextWord)) {\n                configuration.programJars = parseClassPathArgument(configuration.programJars, false);\n            } else if (AtlasProguardConstants.OUTJARS_OPTION.startsWith(nextWord)) {\n                configuration.programJars = parseClassPathArgument(configuration.programJars, true);\n            }\n            //else if (AtlasProguardConstants.LIBRARYJARS_OPTION                               .startsWith\n            // (nextWord)) configuration.libraryJars                      = parseClassPathArgument(configuration\n            // .libraryJars, false);\n            //else if (AtlasProguardConstants.RESOURCEJARS_OPTION                              .startsWith\n            // (nextWord)) throw new ParseException(\"The '-resourcejars' option is no longer supported. Please\n            // use the '-injars' option for all input\");\n            //else if (AtlasProguardConstants.SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION           .startsWith\n            // (nextWord)) configuration.skipNonPublicLibraryClasses      = parseNoArgument(true);\n            //else if (AtlasProguardConstants.DONT_SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION      .startsWith\n            // (nextWord)) configuration.skipNonPublicLibraryClasses      = parseNoArgument(false);\n            //else if (AtlasProguardConstants.DONT_SKIP_NON_PUBLIC_LIBRARY_CLASS_MEMBERS_OPTION.startsWith\n            // (nextWord)) configuration.skipNonPublicLibraryClassMembers = parseNoArgument(false);\n            //else if (AtlasProguardConstants.TARGET_OPTION                                    .startsWith\n            // (nextWord)) configuration.targetClassVersion               = parseClassVersion();\n            //else if (AtlasProguardConstants.FORCE_PROCESSING_OPTION                          .startsWith\n            // (nextWord)) configuration.lastModified                     = parseNoArgument(Long.MAX_VALUE);\n\n            else if (AtlasProguardConstants.KEEP_OPTION.startsWith(nextWord)) {\n                configuration.keep = parseKeepClassSpecificationArguments(configuration.keep, true, false, false);\n            } else if (AtlasProguardConstants.KEEP_CLASS_MEMBERS_OPTION.startsWith(nextWord)) {\n                configuration.keep = parseKeepClassSpecificationArguments(configuration.keep, false, false, false);\n            } else if (AtlasProguardConstants.KEEP_CLASSES_WITH_MEMBERS_OPTION.startsWith(nextWord)) {\n                configuration.keep = parseKeepClassSpecificationArguments(configuration.keep, false, true, false);\n            } else if (AtlasProguardConstants.KEEP_NAMES_OPTION.startsWith(nextWord)) {\n                configuration.keep = parseKeepClassSpecificationArguments(configuration.keep, true, false, true);\n            } else if (AtlasProguardConstants.KEEP_CLASS_MEMBER_NAMES_OPTION.startsWith(nextWord)) {\n                configuration.keep = parseKeepClassSpecificationArguments(configuration.keep, false, false, true);\n            } else if (AtlasProguardConstants.KEEP_CLASSES_WITH_MEMBER_NAMES_OPTION.startsWith(nextWord)) {\n                configuration.keep = parseKeepClassSpecificationArguments(configuration.keep, false, true, true);\n            }\n            //else if (AtlasProguardConstants.PRINT_SEEDS_OPTION                               .startsWith\n            // (nextWord)) configuration.printSeeds                       = parseOptionalFile();\n\n            // After '-keep'.\n            else if (AtlasProguardConstants.KEEP_DIRECTORIES_OPTION.startsWith(nextWord)) {\n                configuration.keepDirectories = parseCommaSeparatedList(\"directory name\", true, true, false, true,\n                                                                        false, true, false, false,\n                                                                        configuration.keepDirectories);\n            }\n\n            //else if (AtlasProguardConstants.DONT_SHRINK_OPTION                               .startsWith\n            // (nextWord)) configuration.shrink                           = parseNoArgument(false);\n            //else if (AtlasProguardConstants.PRINT_USAGE_OPTION                               .startsWith\n            // (nextWord)) configuration.printUsage                       = parseOptionalFile();\n            //else if (AtlasProguardConstants.WHY_ARE_YOU_KEEPING_OPTION                       .startsWith\n            // (nextWord)) configuration.whyAreYouKeeping                 = parseClassSpecificationArguments\n            // (configuration.whyAreYouKeeping);\n\n            //else if (AtlasProguardConstants.DONT_OPTIMIZE_OPTION                             .startsWith\n            // (nextWord)) configuration.optimize                         = parseNoArgument(false);\n            //else if (AtlasProguardConstants.OPTIMIZATION_PASSES                              .startsWith\n            // (nextWord)) configuration.optimizationPasses               = parseIntegerArgument();\n            //else if (AtlasProguardConstants.OPTIMIZATIONS                                    .startsWith\n            // (nextWord)) configuration.optimizations                    = parseCommaSeparatedList(\"optimization\n            // name\", true, false, false, false, false, false, false, false, configuration.optimizations);\n            //else if (AtlasProguardConstants.ASSUME_NO_SIDE_EFFECTS_OPTION                    .startsWith\n            // (nextWord)) configuration.assumeNoSideEffects              = parseClassSpecificationArguments\n            // (configuration.assumeNoSideEffects);\n            //else if (AtlasProguardConstants.ALLOW_ACCESS_MODIFICATION_OPTION                 .startsWith\n            // (nextWord)) configuration.allowAccessModification          = parseNoArgument(true);\n            //else if (AtlasProguardConstants.MERGE_INTERFACES_AGGRESSIVELY_OPTION             .startsWith\n            // (nextWord)) configuration.mergeInterfacesAggressively      = parseNoArgument(true);\n\n            //else if (AtlasProguardConstants.DONT_OBFUSCATE_OPTION                            .startsWith\n            // (nextWord)) configuration.obfuscate                        = parseNoArgument(false);\n            //else if (AtlasProguardConstants.PRINT_MAPPING_OPTION                             .startsWith\n            // (nextWord)) configuration.printMapping                     = parseOptionalFile();\n            //else if (AtlasProguardConstants.APPLY_MAPPING_OPTION                             .startsWith\n            // (nextWord)) configuration.applyMapping                     = parseFile();\n            //else if (AtlasProguardConstants.OBFUSCATION_DICTIONARY_OPTION                    .startsWith\n            // (nextWord)) configuration.obfuscationDictionary            = parseFile();\n            //else if (AtlasProguardConstants.CLASS_OBFUSCATION_DICTIONARY_OPTION              .startsWith\n            // (nextWord)) configuration.classObfuscationDictionary       = parseFile();\n            //else if (AtlasProguardConstants.PACKAGE_OBFUSCATION_DICTIONARY_OPTION            .startsWith\n            // (nextWord)) configuration.packageObfuscationDictionary     = parseFile();\n            //else if (AtlasProguardConstants.OVERLOAD_AGGRESSIVELY_OPTION                     .startsWith\n            // (nextWord)) configuration.overloadAggressively             = parseNoArgument(true);\n            //else if (AtlasProguardConstants.USE_UNIQUE_CLASS_MEMBER_NAMES_OPTION             .startsWith\n            // (nextWord)) configuration.useUniqueClassMemberNames        = parseNoArgument(true);\n            //else if (AtlasProguardConstants.DONT_USE_MIXED_CASE_CLASS_NAMES_OPTION           .startsWith\n            // (nextWord)) configuration.useMixedCaseClassNames           = parseNoArgument(false);\n            else if (AtlasProguardConstants.KEEP_PACKAGE_NAMES_OPTION.startsWith(nextWord)) {\n                configuration.keepPackageNames = parseCommaSeparatedList(\"package name\", true, true, false, false, true,\n                                                                         false, true, false,\n                                                                         configuration.keepPackageNames);\n            }\n            //else if (AtlasProguardConstants.FLATTEN_PACKAGE_HIERARCHY_OPTION                 .startsWith\n            // (nextWord)) configuration.flattenPackageHierarchy          = ClassUtil.internalClassName\n            // (parseOptionalArgument());\n            //else if (AtlasProguardConstants.REPACKAGE_CLASSES_OPTION                         .startsWith\n            // (nextWord)) configuration.repackageClasses                 = ClassUtil.internalClassName\n            // (parseOptionalArgument());\n            //else if (AtlasProguardConstants.DEFAULT_PACKAGE_OPTION                           .startsWith\n            // (nextWord)) configuration.repackageClasses                 = ClassUtil.internalClassName\n            // (parseOptionalArgument());\n            else if (AtlasProguardConstants.KEEP_ATTRIBUTES_OPTION.startsWith(nextWord)) {\n                configuration.keepAttributes = parseCommaSeparatedList(\"attribute name\", true, true, false, false, true,\n                                                                       false, false, false,\n                                                                       configuration.keepAttributes);\n            } else if (AtlasProguardConstants.KEEP_PARAMETER_NAMES_OPTION.startsWith(nextWord)) {\n                configuration.keepParameterNames = parseNoArgument(true);\n            }\n            //else if (AtlasProguardConstants.RENAME_SOURCE_FILE_ATTRIBUTE_OPTION              .startsWith\n            // (nextWord)) configuration.newSourceFileAttribute           = parseOptionalArgument();\n            //else if (AtlasProguardConstants.ADAPT_CLASS_STRINGS_OPTION                       .startsWith\n            // (nextWord)) configuration.adaptClassStrings                = parseCommaSeparatedList(\"class name\",\n            // true, true, false, false, true, false, true, false, configuration.adaptClassStrings);\n            //else if (AtlasProguardConstants.ADAPT_RESOURCE_FILE_NAMES_OPTION                 .startsWith\n            // (nextWord)) configuration.adaptResourceFileNames           = parseCommaSeparatedList(\"resource\n            // file name\", true, true, false, true, false, false, false, false, configuration\n            // .adaptResourceFileNames);\n            //else if (AtlasProguardConstants.ADAPT_RESOURCE_FILE_CONTENTS_OPTION              .startsWith\n            // (nextWord)) configuration.adaptResourceFileContents        = parseCommaSeparatedList(\"resource\n            // file name\", true, true, false, true, false, false, false, false, configuration\n            // .adaptResourceFileContents);\n\n            //else if (AtlasProguardConstants.DONT_PREVERIFY_OPTION                            .startsWith\n            // (nextWord)) configuration.preverify                        = parseNoArgument(false);\n            //else if (AtlasProguardConstants.MICRO_EDITION_OPTION                             .startsWith\n            // (nextWord)) configuration.microEdition                     = parseNoArgument(true);\n\n            //else if (AtlasProguardConstants.VERBOSE_OPTION                                   .startsWith\n            // (nextWord)) configuration.verbose                          = parseNoArgument(true);\n            //else if (AtlasProguardConstants.DONT_NOTE_OPTION                                 .startsWith\n            // (nextWord)) configuration.note                             = parseCommaSeparatedList(\"class name\",\n            // true, true, false, false, true, false, true, false, configuration.note);\n            else if (AtlasProguardConstants.DONT_WARN_OPTION.startsWith(nextWord)) {\n                configuration.warn = parseCommaSeparatedList(\"class name\", true, true, false, false, true, false, true,\n                                                             false, configuration.warn);\n            }\n            //else if (AtlasProguardConstants.IGNORE_WARNINGS_OPTION                           .startsWith\n            // (nextWord)) configuration.ignoreWarnings                   = parseNoArgument(true);\n            //else if (AtlasProguardConstants.PRINT_CONFIGURATION_OPTION                       .startsWith\n            // (nextWord)) configuration.printConfiguration               = parseOptionalFile();\n            //else if (AtlasProguardConstants.DUMP_OPTION                                      .startsWith\n            // (nextWord)) configuration.dump                             = parseOptionalFile();\n            else {\n                //throw new GradleException(\"Unsupport option in library \" + reader.locationDescription());\n                sLogger.error(\"Unsupport option \" + reader.locationDescription());\n                readNextWord(false);\n            }\n        }\n    }\n\n    /**\n     * Closes the configuration.\n     *\n     * @throws IOException if an IO error occurs while closing the configuration.\n     */\n    public void close() throws IOException {\n        if (reader != null) {\n            reader.close();\n        }\n    }\n\n    private long parseIncludeArgument(long lastModified) throws ParseException, IOException {\n        // Read the configuration file name.\n        readNextWord(\"configuration file name\", true, false);\n\n        File file = file(nextWord);\n        reader.includeWordReader(new FileWordReader(file));\n\n        readNextWord();\n\n        return Math.max(lastModified, file.lastModified());\n    }\n\n    private void parseBaseDirectoryArgument() throws ParseException, IOException {\n        // Read the base directory name.\n        readNextWord(\"base directory name\", true, false);\n\n        reader.setBaseDir(file(nextWord));\n\n        readNextWord();\n    }\n\n    private ClassPath parseClassPathArgument(ClassPath classPath,\n                                             boolean isOutput)\n        throws ParseException, IOException {\n        // Create a new List if necessary.\n        if (classPath == null) {\n            classPath = new ClassPath();\n        }\n\n        while (true) {\n            // Read the next jar name.\n            readNextWord(\"jar or directory name\", true, false);\n\n            // Create a new class path entry.\n            ClassPathEntry entry = new ClassPathEntry(file(nextWord), isOutput);\n\n            // Read the opening parenthesis or the separator, if any.\n            readNextWord();\n\n            // Read the optional filters.\n            if (!configurationEnd() &&\n                AtlasProguardConstants.OPEN_ARGUMENTS_KEYWORD.equals(nextWord)) {\n                // Read all filters in an array.\n                List[] filters = new List[7];\n\n                int counter = 0;\n                do {\n                    // Read the filter.\n                    filters[counter++] =\n                        parseCommaSeparatedList(\"filter\", true, true, true, true, false, true, false, false, null);\n                }\n                while (counter < filters.length &&\n                    AtlasProguardConstants.SEPARATOR_KEYWORD.equals(nextWord));\n\n                // Make sure there is a closing parenthesis.\n                if (!AtlasProguardConstants.CLOSE_ARGUMENTS_KEYWORD.equals(nextWord)) {\n                    throw new ParseException(\n                        \"Expecting separating '\" + AtlasProguardConstants.ARGUMENT_SEPARATOR_KEYWORD +\n                            \"' or '\" + AtlasProguardConstants.SEPARATOR_KEYWORD +\n                            \"', or closing '\" + AtlasProguardConstants.CLOSE_ARGUMENTS_KEYWORD +\n                            \"' before \" + reader.locationDescription());\n                }\n\n                // Set all filters from the array on the entry.\n                entry.setFilter(filters[--counter]);\n                if (counter > 0) {\n                    entry.setJarFilter(filters[--counter]);\n                    if (counter > 0) {\n                        entry.setWarFilter(filters[--counter]);\n                        if (counter > 0) {\n                            entry.setEarFilter(filters[--counter]);\n                            if (counter > 0) {\n                                entry.setZipFilter(filters[--counter]);\n                                if (counter > 0) {\n                                    // For backward compatibility, the apk\n                                    // filter comes second in the list.\n                                    entry.setApkFilter(filters[--counter]);\n                                    if (counter > 0) {\n                                        // For backward compatibility, the aar\n                                        // filter comes first in the list.\n                                        entry.setAarFilter(filters[--counter]);\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n\n                // Read the separator, if any.\n                readNextWord();\n            }\n\n            // Add the entry to the list.\n            classPath.add(entry);\n\n            if (configurationEnd()) {\n                return classPath;\n            }\n\n            if (!nextWord.equals(AtlasProguardConstants.JAR_SEPARATOR_KEYWORD)) {\n                throw new ParseException(\n                    \"Expecting class path separator '\" + AtlasProguardConstants.JAR_SEPARATOR_KEYWORD +\n                        \"' before \" + reader.locationDescription());\n            }\n        }\n    }\n\n    private int parseClassVersion()\n        throws ParseException, IOException {\n        // Read the obligatory target.\n        readNextWord(\"java version\");\n\n        int classVersion = ClassUtil.internalClassVersion(nextWord);\n        if (classVersion == 0) {\n            throw new ParseException(\"Unsupported java version \" + reader.locationDescription());\n        }\n\n        readNextWord();\n\n        return classVersion;\n    }\n\n    private int parseIntegerArgument()\n        throws ParseException, IOException {\n        try {\n            // Read the obligatory integer.\n            readNextWord(\"integer\");\n\n            int integer = Integer.parseInt(nextWord);\n\n            readNextWord();\n\n            return integer;\n        } catch (NumberFormatException e) {\n            throw new ParseException(\"Expecting integer argument instead of '\" + nextWord +\n                                         \"' before \" + reader.locationDescription());\n        }\n    }\n\n    private File parseFile()\n        throws ParseException, IOException {\n        // Read the obligatory file name.\n        readNextWord(\"file name\", true, false);\n\n        // Make sure the file is properly resolved.\n        File file = file(nextWord);\n\n        readNextWord();\n\n        return file;\n    }\n\n    private File parseOptionalFile()\n        throws ParseException, IOException {\n        // Read the optional file name.\n        readNextWord(true);\n\n        // Didn't the user specify a file name?\n        if (configurationEnd()) {\n            return Configuration.STD_OUT;\n        }\n\n        // Make sure the file is properly resolved.\n        File file = file(nextWord);\n\n        readNextWord();\n\n        return file;\n    }\n\n    private String parseOptionalArgument() throws IOException {\n        // Read the optional argument.\n        readNextWord();\n\n        // Didn't the user specify an argument?\n        if (configurationEnd()) {\n            return \"\";\n        }\n\n        String argument = nextWord;\n\n        readNextWord();\n\n        return argument;\n    }\n\n    private boolean parseNoArgument(boolean value) throws IOException {\n        readNextWord();\n\n        return value;\n    }\n\n    private long parseNoArgument(long value) throws IOException {\n        readNextWord();\n\n        return value;\n    }\n\n    private List parseKeepClassSpecificationArguments(List keepClassSpecifications,\n                                                      boolean markClasses,\n                                                      boolean markConditionally,\n                                                      boolean allowShrinking)\n        throws ParseException, IOException {\n        // Create a new List if necessary.\n        if (keepClassSpecifications == null) {\n            keepClassSpecifications = new ArrayList();\n        }\n\n        boolean markDescriptorClasses = false;\n        //boolean allowShrinking        = false;\n        boolean allowOptimization = false;\n        boolean allowObfuscation = false;\n\n        // Read the keep modifiers.\n        while (true) {\n            readNextWord(\"keyword '\" + AtlasProguardConstants.CLASS_KEYWORD +\n                             \"', '\" + JavaConstants.ACC_INTERFACE +\n                             \"', or '\" + JavaConstants.ACC_ENUM + \"'\",\n                         false, true);\n\n            if (!AtlasProguardConstants.ARGUMENT_SEPARATOR_KEYWORD.equals(nextWord)) {\n                // Not a comma. Stop parsing the keep modifiers.\n                break;\n            }\n\n            readNextWord(\"keyword '\" + AtlasProguardConstants.ALLOW_SHRINKING_SUBOPTION +\n                             \"', '\" + AtlasProguardConstants.ALLOW_OPTIMIZATION_SUBOPTION +\n                             \"', or '\" + AtlasProguardConstants.ALLOW_OBFUSCATION_SUBOPTION + \"'\");\n\n            if (AtlasProguardConstants.INCLUDE_DESCRIPTOR_CLASSES_SUBOPTION.startsWith(nextWord)) {\n                markDescriptorClasses = true;\n            } else if (AtlasProguardConstants.ALLOW_SHRINKING_SUBOPTION.startsWith(nextWord)) {\n                allowShrinking = true;\n            } else if (AtlasProguardConstants.ALLOW_OPTIMIZATION_SUBOPTION.startsWith(nextWord)) {\n                allowOptimization = true;\n            } else if (AtlasProguardConstants.ALLOW_OBFUSCATION_SUBOPTION.startsWith(nextWord)) {\n                allowObfuscation = true;\n            } else {\n                throw new ParseException(\n                    \"Expecting keyword '\" + AtlasProguardConstants.INCLUDE_DESCRIPTOR_CLASSES_SUBOPTION +\n                        \"', '\" + AtlasProguardConstants.ALLOW_SHRINKING_SUBOPTION +\n                        \"', '\" + AtlasProguardConstants.ALLOW_OPTIMIZATION_SUBOPTION +\n                        \"', or '\" + AtlasProguardConstants.ALLOW_OBFUSCATION_SUBOPTION +\n                        \"' before \" + reader.locationDescription());\n            }\n        }\n\n        // Read the class configuration.\n        ClassSpecification classSpecification =\n            parseClassSpecificationArguments();\n\n        // Create and add the keep configuration.\n        keepClassSpecifications.add(new KeepClassSpecification(markClasses,\n                                                               markConditionally,\n                                                               markDescriptorClasses,\n                                                               allowShrinking,\n                                                               allowOptimization,\n                                                               allowObfuscation,\n                                                               classSpecification));\n        return keepClassSpecifications;\n    }\n\n    private List parseClassSpecificationArguments(List classSpecifications)\n        throws ParseException, IOException {\n        // Create a new List if necessary.\n        if (classSpecifications == null) {\n            classSpecifications = new ArrayList();\n        }\n\n        // Read and add the class configuration.\n        readNextWord(\"keyword '\" + AtlasProguardConstants.CLASS_KEYWORD +\n                         \"', '\" + JavaConstants.ACC_INTERFACE +\n                         \"', or '\" + JavaConstants.ACC_ENUM + \"'\",\n                     false, true);\n\n        classSpecifications.add(parseClassSpecificationArguments());\n\n        return classSpecifications;\n    }\n\n    /**\n     * Parses and returns a class specification.\n     *\n     * @throws ParseException if the class specification contains a syntax error.\n     * @throws IOException if an IO error occurs while reading the class\n     * specification.\n     */\n    public ClassSpecification parseClassSpecificationArguments()\n        throws ParseException, IOException {\n        // Clear the annotation type.\n        String annotationType = null;\n\n        // Clear the class access modifiers.\n        int requiredSetClassAccessFlags = 0;\n        int requiredUnsetClassAccessFlags = 0;\n\n        // Parse the class annotations and access modifiers until the class keyword.\n        while (!AtlasProguardConstants.CLASS_KEYWORD.equals(nextWord)) {\n            // Strip the negating sign, if any.\n            boolean negated =\n                nextWord.startsWith(AtlasProguardConstants.NEGATOR_KEYWORD);\n\n            String strippedWord = negated ?\n                nextWord.substring(1) :\n                nextWord;\n\n            // Parse the class access modifiers.\n            int accessFlag =\n                strippedWord.equals(JavaConstants.ACC_PUBLIC) ? ClassConstants.ACC_PUBLIC :\n                    strippedWord.equals(JavaConstants.ACC_FINAL) ? ClassConstants.ACC_FINAL :\n                        strippedWord.equals(JavaConstants.ACC_INTERFACE) ? ClassConstants.ACC_INTERFACE :\n                            strippedWord.equals(JavaConstants.ACC_ABSTRACT) ? ClassConstants.ACC_ABSTRACT :\n                                strippedWord.equals(JavaConstants.ACC_SYNTHETIC) ? ClassConstants.ACC_SYNTHETIC :\n                                    strippedWord.equals(JavaConstants.ACC_ANNOTATION) ? ClassConstants.ACC_ANNOTATTION :\n                                        strippedWord.equals(JavaConstants.ACC_ENUM) ? ClassConstants.ACC_ENUM :\n                                            unknownAccessFlag();\n\n            // Is it an annotation modifier?\n            if (accessFlag == ClassConstants.ACC_ANNOTATTION) {\n                // Already read the next word.\n                readNextWord(\"annotation type or keyword '\" + JavaConstants.ACC_INTERFACE + \"'\",\n                             false, false);\n\n                // Is the next word actually an annotation type?\n                if (!nextWord.equals(JavaConstants.ACC_INTERFACE) &&\n                    !nextWord.equals(JavaConstants.ACC_ENUM) &&\n                    !nextWord.equals(AtlasProguardConstants.CLASS_KEYWORD)) {\n                    // Parse the annotation type.\n                    annotationType =\n                        ListUtil.commaSeparatedString(\n                            parseCommaSeparatedList(\"annotation type\",\n                                                    false, false, false, false, true, false, false, true, null), false);\n\n                    // Continue parsing the access modifier that we just read\n                    // in the next cycle.\n                    continue;\n                }\n\n                // Otherwise just handle the annotation modifier.\n            }\n\n            if (!negated) {\n                requiredSetClassAccessFlags |= accessFlag;\n            } else {\n                requiredUnsetClassAccessFlags |= accessFlag;\n            }\n\n            if ((requiredSetClassAccessFlags &\n                requiredUnsetClassAccessFlags) != 0) {\n                throw new ParseException(\"Conflicting class access modifiers for '\" + strippedWord +\n                                             \"' before \" + reader.locationDescription());\n            }\n\n            if (strippedWord.equals(JavaConstants.ACC_INTERFACE) ||\n                strippedWord.equals(JavaConstants.ACC_ENUM) ||\n                strippedWord.equals(AtlasProguardConstants.CLASS_KEYWORD)) {\n                // The interface or enum keyword. Stop parsing the class flags.\n                break;\n            }\n\n            // Should we read the next word?\n            if (accessFlag != ClassConstants.ACC_ANNOTATTION) {\n                readNextWord(\"keyword '\" + AtlasProguardConstants.CLASS_KEYWORD +\n                                 \"', '\" + JavaConstants.ACC_INTERFACE +\n                                 \"', or '\" + JavaConstants.ACC_ENUM + \"'\",\n                             false, true);\n            }\n        }\n\n        // Parse the class name part.\n        String externalClassName =\n            ListUtil.commaSeparatedString(\n                parseCommaSeparatedList(\"class name or interface name\",\n                                        true, false, false, false, true, false, false, false, null), false);\n\n        // For backward compatibility, allow a single \"*\" wildcard to match any\n        // class.\n        String className = AtlasProguardConstants.ANY_CLASS_KEYWORD.equals(externalClassName) ?\n            null :\n            ClassUtil.internalClassName(externalClassName);\n\n        // Clear the annotation type and the class name of the extends part.\n        String extendsAnnotationType = null;\n        String extendsClassName = null;\n\n        if (!configurationEnd()) {\n            // Parse 'implements ...' or 'extends ...' part, if any.\n            if (AtlasProguardConstants.IMPLEMENTS_KEYWORD.equals(nextWord) ||\n                AtlasProguardConstants.EXTENDS_KEYWORD.equals(nextWord)) {\n                readNextWord(\"class name or interface name\", false, true);\n\n                // Parse the annotation type, if any.\n                if (AtlasProguardConstants.ANNOTATION_KEYWORD.equals(nextWord)) {\n                    extendsAnnotationType =\n                        ListUtil.commaSeparatedString(\n                            parseCommaSeparatedList(\"annotation type\",\n                                                    true, false, false, false, true, false, false, true, null), false);\n                }\n\n                String externalExtendsClassName =\n                    ListUtil.commaSeparatedString(\n                        parseCommaSeparatedList(\"class name or interface name\",\n                                                false, false, false, false, true, false, false, false, null), false);\n\n                extendsClassName = AtlasProguardConstants.ANY_CLASS_KEYWORD.equals(externalExtendsClassName) ?\n                    null :\n                    ClassUtil.internalClassName(externalExtendsClassName);\n            }\n        }\n\n        // Create the basic class specification.\n        ClassSpecification classSpecification =\n            new ClassSpecification(lastComments,\n                                   requiredSetClassAccessFlags,\n                                   requiredUnsetClassAccessFlags,\n                                   annotationType,\n                                   className,\n                                   extendsAnnotationType,\n                                   extendsClassName);\n\n        // Now add any class members to this class specification.\n        if (!configurationEnd()) {\n            // Check the class member opening part.\n            if (!AtlasProguardConstants.OPEN_KEYWORD.equals(nextWord)) {\n                throw new ParseException(\"Expecting opening '\" + AtlasProguardConstants.OPEN_KEYWORD +\n                                             \"' at \" + reader.locationDescription());\n            }\n\n            // Parse all class members.\n            while (true) {\n                readNextWord(\"class member description\" +\n                                 \" or closing '\" + AtlasProguardConstants.CLOSE_KEYWORD + \"'\",\n                             false, true);\n\n                if (nextWord.equals(AtlasProguardConstants.CLOSE_KEYWORD)) {\n                    // The closing brace. Stop parsing the class members.\n                    readNextWord();\n\n                    break;\n                }\n\n                parseMemberSpecificationArguments(externalClassName,\n                                                  classSpecification);\n            }\n        }\n\n        return classSpecification;\n    }\n\n    private void parseMemberSpecificationArguments(String externalClassName,\n                                                   ClassSpecification classSpecification)\n        throws ParseException, IOException {\n        // Clear the annotation name.\n        String annotationType = null;\n\n        // Parse the class member access modifiers, if any.\n        int requiredSetMemberAccessFlags = 0;\n        int requiredUnsetMemberAccessFlags = 0;\n\n        while (!configurationEnd(true)) {\n            // Parse the annotation type, if any.\n            if (AtlasProguardConstants.ANNOTATION_KEYWORD.equals(nextWord)) {\n                annotationType =\n                    ListUtil.commaSeparatedString(\n                        parseCommaSeparatedList(\"annotation type\",\n                                                true, false, false, false, true, false, false, true, null), false);\n                continue;\n            }\n\n            String strippedWord = nextWord.startsWith(\"!\") ?\n                nextWord.substring(1) :\n                nextWord;\n\n            // Parse the class member access modifiers.\n            int accessFlag =\n                strippedWord.equals(JavaConstants.ACC_PUBLIC) ? ClassConstants.ACC_PUBLIC :\n                    strippedWord.equals(JavaConstants.ACC_PRIVATE) ? ClassConstants.ACC_PRIVATE :\n                        strippedWord.equals(JavaConstants.ACC_PROTECTED) ? ClassConstants.ACC_PROTECTED :\n                            strippedWord.equals(JavaConstants.ACC_STATIC) ? ClassConstants.ACC_STATIC :\n                                strippedWord.equals(JavaConstants.ACC_FINAL) ? ClassConstants.ACC_FINAL :\n                                    strippedWord.equals(JavaConstants.ACC_SYNCHRONIZED)\n                                        ? ClassConstants.ACC_SYNCHRONIZED :\n                                        strippedWord.equals(JavaConstants.ACC_VOLATILE) ? ClassConstants.ACC_VOLATILE :\n                                            strippedWord.equals(JavaConstants.ACC_TRANSIENT)\n                                                ? ClassConstants.ACC_TRANSIENT :\n                                                strippedWord.equals(JavaConstants.ACC_BRIDGE)\n                                                    ? ClassConstants.ACC_BRIDGE :\n                                                    strippedWord.equals(JavaConstants.ACC_VARARGS)\n                                                        ? ClassConstants.ACC_VARARGS :\n                                                        strippedWord.equals(JavaConstants.ACC_NATIVE)\n                                                            ? ClassConstants.ACC_NATIVE :\n                                                            strippedWord.equals(JavaConstants.ACC_ABSTRACT)\n                                                                ? ClassConstants.ACC_ABSTRACT :\n                                                                strippedWord.equals(JavaConstants.ACC_STRICT)\n                                                                    ? ClassConstants.ACC_STRICT :\n                                                                    strippedWord.equals(JavaConstants.ACC_SYNTHETIC)\n                                                                        ? ClassConstants.ACC_SYNTHETIC :\n                                                                        0;\n            if (accessFlag == 0) {\n                // Not a class member access modifier. Stop parsing them.\n                break;\n            }\n\n            if (strippedWord.equals(nextWord)) {\n                requiredSetMemberAccessFlags |= accessFlag;\n            } else {\n                requiredUnsetMemberAccessFlags |= accessFlag;\n            }\n\n            // Make sure the user doesn't try to set and unset the same\n            // access flags simultaneously.\n            if ((requiredSetMemberAccessFlags &\n                requiredUnsetMemberAccessFlags) != 0) {\n                throw new ParseException(\"Conflicting class member access modifiers for \" +\n                                             reader.locationDescription());\n            }\n\n            readNextWord(\"class member description\");\n        }\n\n        // Parse the class member type and name part.\n\n        // Did we get a special wildcard?\n        if (AtlasProguardConstants.ANY_CLASS_MEMBER_KEYWORD.equals(nextWord) ||\n            AtlasProguardConstants.ANY_FIELD_KEYWORD.equals(nextWord) ||\n            AtlasProguardConstants.ANY_METHOD_KEYWORD.equals(nextWord)) {\n            // Act according to the type of wildcard..\n            if (AtlasProguardConstants.ANY_CLASS_MEMBER_KEYWORD.equals(nextWord)) {\n                checkFieldAccessFlags(requiredSetMemberAccessFlags,\n                                      requiredUnsetMemberAccessFlags);\n                checkMethodAccessFlags(requiredSetMemberAccessFlags,\n                                       requiredUnsetMemberAccessFlags);\n\n                classSpecification.addField(\n                    new MemberSpecification(requiredSetMemberAccessFlags,\n                                            requiredUnsetMemberAccessFlags,\n                                            annotationType,\n                                            null,\n                                            null));\n                classSpecification.addMethod(\n                    new MemberSpecification(requiredSetMemberAccessFlags,\n                                            requiredUnsetMemberAccessFlags,\n                                            annotationType,\n                                            null,\n                                            null));\n            } else if (AtlasProguardConstants.ANY_FIELD_KEYWORD.equals(nextWord)) {\n                checkFieldAccessFlags(requiredSetMemberAccessFlags,\n                                      requiredUnsetMemberAccessFlags);\n\n                classSpecification.addField(\n                    new MemberSpecification(requiredSetMemberAccessFlags,\n                                            requiredUnsetMemberAccessFlags,\n                                            annotationType,\n                                            null,\n                                            null));\n            } else if (AtlasProguardConstants.ANY_METHOD_KEYWORD.equals(nextWord)) {\n                checkMethodAccessFlags(requiredSetMemberAccessFlags,\n                                       requiredUnsetMemberAccessFlags);\n\n                classSpecification.addMethod(\n                    new MemberSpecification(requiredSetMemberAccessFlags,\n                                            requiredUnsetMemberAccessFlags,\n                                            annotationType,\n                                            null,\n                                            null));\n            }\n\n            // We still have to read the closing separator.\n            readNextWord(\"separator '\" + AtlasProguardConstants.SEPARATOR_KEYWORD + \"'\");\n\n            if (!AtlasProguardConstants.SEPARATOR_KEYWORD.equals(nextWord)) {\n                throw new ParseException(\"Expecting separator '\" + AtlasProguardConstants.SEPARATOR_KEYWORD +\n                                             \"' before \" + reader.locationDescription());\n            }\n        } else {\n            // Make sure we have a proper type.\n            checkJavaIdentifier(\"java type\");\n            String type = nextWord;\n\n            readNextWord(\"class member name\");\n            String name = nextWord;\n\n            // Did we get just one word before the opening parenthesis?\n            if (AtlasProguardConstants.OPEN_ARGUMENTS_KEYWORD.equals(name)) {\n                // This must be a constructor then.\n                // Make sure the type is a proper constructor name.\n                if (!(type.equals(ClassConstants.METHOD_NAME_INIT) ||\n                    type.equals(externalClassName) ||\n                    type.equals(ClassUtil.externalShortClassName(externalClassName)))) {\n                    throw new ParseException(\"Expecting type and name \" +\n                                                 \"instead of just '\" + type +\n                                                 \"' before \" + reader.locationDescription());\n                }\n\n                // Assign the fixed constructor type and name.\n                type = JavaConstants.TYPE_VOID;\n                name = ClassConstants.METHOD_NAME_INIT;\n            } else {\n                // It's not a constructor.\n                // Make sure we have a proper name.\n                checkJavaIdentifier(\"class member name\");\n\n                // Read the opening parenthesis or the separating\n                // semi-colon.\n                readNextWord(\"opening '\" + AtlasProguardConstants.OPEN_ARGUMENTS_KEYWORD +\n                                 \"' or separator '\" + AtlasProguardConstants.SEPARATOR_KEYWORD + \"'\");\n            }\n\n            // Are we looking at a field, a method, or something else?\n            if (AtlasProguardConstants.SEPARATOR_KEYWORD.equals(nextWord)) {\n                // It's a field.\n                checkFieldAccessFlags(requiredSetMemberAccessFlags,\n                                      requiredUnsetMemberAccessFlags);\n\n                // We already have a field descriptor.\n                String descriptor = ClassUtil.internalType(type);\n\n                // Add the field.\n                classSpecification.addField(\n                    new MemberSpecification(requiredSetMemberAccessFlags,\n                                            requiredUnsetMemberAccessFlags,\n                                            annotationType,\n                                            name,\n                                            descriptor));\n            } else if (AtlasProguardConstants.OPEN_ARGUMENTS_KEYWORD.equals(nextWord)) {\n                // It's a method.\n                checkMethodAccessFlags(requiredSetMemberAccessFlags,\n                                       requiredUnsetMemberAccessFlags);\n\n                // Parse the method arguments.\n                String descriptor =\n                    ClassUtil.internalMethodDescriptor(type,\n                                                       parseCommaSeparatedList(\"argument\", true, true, true, false,\n                                                                               true, false, false, false, null));\n\n                if (!AtlasProguardConstants.CLOSE_ARGUMENTS_KEYWORD.equals(nextWord)) {\n                    throw new ParseException(\n                        \"Expecting separating '\" + AtlasProguardConstants.ARGUMENT_SEPARATOR_KEYWORD +\n                            \"' or closing '\" + AtlasProguardConstants.CLOSE_ARGUMENTS_KEYWORD +\n                            \"' before \" + reader.locationDescription());\n                }\n\n                // Read the separator after the closing parenthesis.\n                readNextWord(\"separator '\" + AtlasProguardConstants.SEPARATOR_KEYWORD + \"'\");\n\n                if (!AtlasProguardConstants.SEPARATOR_KEYWORD.equals(nextWord)) {\n                    throw new ParseException(\"Expecting separator '\" + AtlasProguardConstants.SEPARATOR_KEYWORD +\n                                                 \"' before \" + reader.locationDescription());\n                }\n\n                // Add the method.\n                classSpecification.addMethod(\n                    new MemberSpecification(requiredSetMemberAccessFlags,\n                                            requiredUnsetMemberAccessFlags,\n                                            annotationType,\n                                            name,\n                                            descriptor));\n            } else {\n                // It doesn't look like a field or a method.\n                throw new ParseException(\"Expecting opening '\" + AtlasProguardConstants.OPEN_ARGUMENTS_KEYWORD +\n                                             \"' or separator '\" + AtlasProguardConstants.SEPARATOR_KEYWORD +\n                                             \"' before \" + reader.locationDescription());\n            }\n        }\n    }\n\n    /**\n     * Reads a comma-separated list of java identifiers or of file names.\n     * Examples of invocation arguments:\n     * (\"directory name\", true,  true,  false, true,  false, true,  false, false, ...)\n     * (\"optimization\",   true,  false, false, false, false, false, false, false, ...)\n     * (\"package name\",   true,  true,  false, false, true,  false, true,  false, ...)\n     * (\"attribute name\", true,  true,  false, false, true,  false, false, false, ...)\n     * (\"class name\",     true,  true,  false, false, true,  false, true,  false, ...)\n     * (\"resource file\",  true,  true,  false, true,  false, false, false, false, ...)\n     * (\"resource file\",  true,  true,  false, true,  false, false, false, false, ...)\n     * (\"class name\",     true,  true,  false, false, true,  false, true,  false, ...)\n     * (\"class name\",     true,  true,  false, false, true,  false, true,  false, ...)\n     * (\"filter\",         true,  true,  true,  true,  false, true,  false, false, ...)\n     * (\"annotation \",    false, false, false, false, true,  false, false, true,  ...)\n     * (\"class name \",    true,  false, false, false, true,  false, false, false, ...)\n     * (\"annotation \",    true,  false, false, false, true,  false, false, true,  ...)\n     * (\"class name \",    false, false, false, false, true,  false, false, false, ...)\n     * (\"annotation \",    true,  false, false, false, true,  false, false, true,  ...)\n     * (\"argument\",       true,  true,  true,  false, true,  false, false, false, ...)\n     */\n    private List parseCommaSeparatedList(String expectedDescription,\n                                         boolean readFirstWord,\n                                         boolean allowEmptyList,\n                                         boolean expectClosingParenthesis,\n                                         boolean isFileName,\n                                         boolean checkJavaIdentifiers,\n                                         boolean replaceSystemProperties,\n                                         boolean replaceExternalClassNames,\n                                         boolean replaceExternalTypes,\n                                         List list)\n        throws ParseException, IOException {\n        if (list == null) {\n            list = new ArrayList();\n        }\n\n        if (readFirstWord) {\n            if (!allowEmptyList) {\n                // Read the first list entry.\n                readNextWord(expectedDescription, isFileName, false);\n            } else if (expectClosingParenthesis) {\n                // Read the first list entry.\n                readNextWord(expectedDescription, isFileName, false);\n\n                // Return if the entry is actually empty (an empty file name or\n                // a closing parenthesis).\n                if (nextWord.length() == 0) {\n                    // Read the closing parenthesis\n                    readNextWord(\"closing '\" + AtlasProguardConstants.CLOSE_ARGUMENTS_KEYWORD +\n                                     \"'\");\n\n                    return list;\n                } else if (nextWord.equals(AtlasProguardConstants.CLOSE_ARGUMENTS_KEYWORD)) {\n                    return list;\n                }\n            } else {\n                // Read the first list entry, if there is any.\n                readNextWord(isFileName);\n\n                // Check if the list is empty.\n                if (configurationEnd()) {\n                    return list;\n                }\n            }\n        }\n\n        while (true) {\n            if (checkJavaIdentifiers) {\n                checkJavaIdentifier(\"java type\");\n            }\n\n            if (replaceSystemProperties) {\n                nextWord = replaceSystemProperties(nextWord);\n            }\n\n            if (replaceExternalClassNames) {\n                nextWord = ClassUtil.internalClassName(nextWord);\n            }\n\n            if (replaceExternalTypes) {\n                nextWord = ClassUtil.internalType(nextWord);\n            }\n\n            list.add(nextWord);\n\n            if (expectClosingParenthesis) {\n                // Read a comma (or a closing parenthesis, or a different word).\n                readNextWord(\"separating '\" + AtlasProguardConstants.ARGUMENT_SEPARATOR_KEYWORD +\n                                 \"' or closing '\" + AtlasProguardConstants.CLOSE_ARGUMENTS_KEYWORD +\n                                 \"'\");\n            } else {\n                // Read a comma (or a different word).\n                readNextWord();\n            }\n\n            if (!AtlasProguardConstants.ARGUMENT_SEPARATOR_KEYWORD.equals(nextWord)) {\n                return list;\n            }\n\n            // Read the next list entry.\n            readNextWord(expectedDescription, isFileName, false);\n        }\n    }\n\n    /**\n     * Throws a ParseException for an unexpected keyword.\n     */\n    private int unknownAccessFlag() throws ParseException {\n        throw new ParseException(\"Unexpected keyword \" + reader.locationDescription());\n    }\n\n    /**\n     * Creates a properly resolved File, based on the given word.\n     */\n    private File file(String word) throws ParseException {\n        String fileName = replaceSystemProperties(word);\n        File file = new File(fileName);\n\n        // Try to get an absolute file.\n        if (!file.isAbsolute()) {\n            file = new File(reader.getBaseDir(), fileName);\n        }\n\n        return file;\n    }\n\n    /**\n     * Replaces any properties in the given word by their values.\n     * For instance, the substring \"<java.home>\" is replaced by its value.\n     */\n    private String replaceSystemProperties(String word) throws ParseException {\n        int fromIndex = 0;\n        while (true) {\n            fromIndex = word.indexOf(AtlasProguardConstants.OPEN_SYSTEM_PROPERTY, fromIndex);\n            if (fromIndex < 0) {\n                break;\n            }\n\n            int toIndex = word.indexOf(AtlasProguardConstants.CLOSE_SYSTEM_PROPERTY, fromIndex + 1);\n            if (toIndex < 0) {\n                break;\n            }\n\n            String propertyName = word.substring(fromIndex + 1, toIndex);\n            String propertyValue = properties.getProperty(propertyName);\n            if (propertyValue == null) {\n                throw new ParseException(\"Value of system property '\" + propertyName +\n                                             \"' is undefined in \" + reader.locationDescription());\n            }\n\n            word = word.substring(0, fromIndex) + propertyValue + word.substring(toIndex + 1);\n\n            fromIndex += propertyValue.length();\n        }\n\n        return word;\n    }\n\n    /**\n     * Reads the next word of the configuration in the 'nextWord' field,\n     * throwing an exception if there is no next word.\n     */\n    private void readNextWord(String expectedDescription)\n        throws ParseException, IOException {\n        readNextWord(expectedDescription, false, false);\n    }\n\n    /**\n     * Reads the next word of the configuration in the 'nextWord' field,\n     * throwing an exception if there is no next word.\n     */\n    private void readNextWord(String expectedDescription,\n                              boolean isFileName,\n                              boolean expectingAtCharacter)\n        throws ParseException, IOException {\n        readNextWord(isFileName);\n        if (configurationEnd(expectingAtCharacter)) {\n            throw new ParseException(\"Expecting \" + expectedDescription +\n                                         \" before \" + reader.locationDescription());\n        }\n    }\n\n    /**\n     * Reads the next word of the configuration in the 'nextWord' field.\n     */\n    private void readNextWord() throws IOException {\n        readNextWord(false);\n    }\n\n    /**\n     * Reads the next word of the configuration in the 'nextWord' field.\n     */\n    private void readNextWord(boolean isFileName) throws IOException {\n        nextWord = reader.nextWord(isFileName);\n    }\n\n    /**\n     * Returns whether the end of the configuration has been reached.\n     */\n    private boolean configurationEnd() {\n        return configurationEnd(false);\n    }\n\n    /**\n     * Returns whether the end of the configuration has been reached.\n     */\n    private boolean configurationEnd(boolean expectingAtCharacter) {\n        return nextWord == null ||\n            nextWord.startsWith(AtlasProguardConstants.OPTION_PREFIX) ||\n            (!expectingAtCharacter &&\n                nextWord.equals(AtlasProguardConstants.AT_DIRECTIVE));\n    }\n\n    /**\n     * Checks whether the given word is a valid Java identifier and throws\n     * a ParseException if it isn't. Wildcard characters are accepted.\n     */\n    private void checkJavaIdentifier(String expectedDescription)\n        throws ParseException {\n        if (!isJavaIdentifier(nextWord)) {\n            throw new ParseException(\"Expecting \" + expectedDescription +\n                                         \" before \" + reader.locationDescription());\n        }\n    }\n\n    /**\n     * Returns whether the given word is a valid Java identifier.\n     * Wildcard characters are accepted.\n     */\n    private boolean isJavaIdentifier(String aWord) {\n        if (aWord.length() == 0) {\n            return false;\n        }\n\n        for (int index = 0; index < aWord.length(); index++) {\n            char c = aWord.charAt(index);\n            if (!(Character.isJavaIdentifierPart(c) ||\n                c == '.' ||\n                c == '[' ||\n                c == ']' ||\n                c == '<' ||\n                c == '>' ||\n                c == '-' ||\n                c == '!' ||\n                c == '*' ||\n                c == '?' ||\n                c == '%')) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Checks whether the given access flags are valid field access flags,\n     * throwing a ParseException if they aren't.\n     */\n    private void checkFieldAccessFlags(int requiredSetMemberAccessFlags,\n                                       int requiredUnsetMemberAccessFlags)\n        throws ParseException {\n        if (((requiredSetMemberAccessFlags |\n            requiredUnsetMemberAccessFlags) &\n            ~ClassConstants.VALID_ACC_FIELD) != 0) {\n            throw new ParseException(\"Invalid method access modifier for field before \" +\n                                         reader.locationDescription());\n        }\n    }\n\n    /**\n     * Checks whether the given access flags are valid method access flags,\n     * throwing a ParseException if they aren't.\n     */\n    private void checkMethodAccessFlags(int requiredSetMemberAccessFlags,\n                                        int requiredUnsetMemberAccessFlags)\n        throws ParseException {\n        if (((requiredSetMemberAccessFlags |\n            requiredUnsetMemberAccessFlags) &\n            ~ClassConstants.VALID_ACC_METHOD) != 0) {\n            throw new ParseException(\"Invalid field access modifier for method before \" +\n                                         reader.locationDescription());\n        }\n    }\n\n    /**\n     * A main method for testing configuration parsing.\n     */\n    public static void main(String[] args) {\n        try {\n            ConfigurationParser parser =\n                new ConfigurationParser(args, System.getProperties());\n\n            try {\n                parser.parse(new Configuration());\n            } catch (ParseException ex) {\n                ex.printStackTrace();\n            } finally {\n                parser.close();\n            }\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/ProGuardPercentPrinter.java",
    "content": "package com.taobao.android.builder.tools.proguard;\n\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.build.api.transform.DirectoryInput;\nimport com.android.build.api.transform.Format;\nimport com.android.build.api.transform.JarInput;\nimport com.android.build.api.transform.QualifiedContent;\nimport com.android.build.api.transform.Status;\nimport com.android.build.api.transform.TransformInput;\nimport com.android.build.api.transform.TransformInvocation;\nimport com.android.build.api.transform.TransformOutputProvider;\nimport com.android.build.gradle.internal.api.AppVariantContext;\nimport com.android.builder.model.AndroidLibrary;\nimport com.android.builder.model.JavaLibrary;\nimport com.android.builder.model.Library;\n\nimport com.google.common.base.Charsets;\nimport com.google.common.base.Preconditions;\nimport com.google.common.collect.ImmutableMap;\nimport com.google.common.collect.Ordering;\nimport com.google.common.io.Files;\nimport com.taobao.android.builder.AtlasBuildContext;\nimport com.taobao.android.builder.tasks.transform.AtlasTransformUtils;\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.PrintWriter;\nimport java.io.UncheckedIOException;\nimport java.nio.file.Path;\nimport java.util.Collection;\nimport java.util.Enumeration;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\npublic class ProGuardPercentPrinter {\n    private final AppVariantContext appVariantContext;\n    private final TransformInvocation invocation;\n    private final Collection<File> transformInputs;\n    private final Map<File, Library> fileLibraryMap;\n    private final Map<File, File> injarsOutjarsMap;\n\n    public ProGuardPercentPrinter(AppVariantContext appVariantContext,\n            TransformInvocation invocation) {\n        this.appVariantContext = appVariantContext;\n        this.invocation = invocation;\n        transformInputs =\n                AtlasTransformUtils.getTransformInputs(this.appVariantContext, invocation);\n        fileLibraryMap = buildFileLibraryMap();\n\n        injarsOutjarsMap = buildgetInjarsOutjarsMap();\n    }\n\n    public Map<File, File> getInjarsOutjarsMap() {\n        return injarsOutjarsMap;\n    }\n\n    private Map<File, File> buildgetInjarsOutjarsMap() {\n        TransformOutputProvider outputProvider = invocation.getOutputProvider();\n        Preconditions.checkNotNull(outputProvider);\n        //if (!invocation.isIncremental()) {\n        //    outputProvider.deleteAll();\n        //}\n        ImmutableMap.Builder<File, File> builder = ImmutableMap.builder();\n        for (TransformInput input : invocation.getInputs()) {\n            for (DirectoryInput dirInput : input.getDirectoryInputs()) {\n                Path output = getOutputPath(invocation.getOutputProvider(), dirInput);\n                //if (!dirInput.getFile().isDirectory()) {\n                //    PathUtils.deleteIfExists(output);\n                //}\n\n                Path dirPath = dirInput.getFile().toPath();\n                builder.put(dirPath.toFile(), output.toFile());\n            }\n            for (JarInput jarInput : input.getJarInputs()) {\n                if (invocation.isIncremental() && jarInput.getStatus() == Status.NOTCHANGED) {\n                    continue;\n                }\n                Path output = getOutputPath(outputProvider, jarInput);\n                //PathUtils.deleteIfExists(output);\n                Path path = jarInput.getFile().toPath();\n                builder.put(path.toFile(), output.toFile());\n            }\n        }\n        return builder.build();\n    }\n\n    @NonNull\n    private static Path getOutputPath(@NonNull TransformOutputProvider outputProvider,\n            @NonNull QualifiedContent content) {\n        return outputProvider.getContentLocation(content.getName(),\n                content.getContentTypes(),\n                content.getScopes(),\n                content instanceof DirectoryInput ? Format.DIRECTORY : Format.JAR).toPath();\n    }\n\n    private Map<File, Library> buildFileLibraryMap() {\n        return Stream.concat(AtlasBuildContext.androidDependencyTrees.get(\n                appVariantContext.getScope()\n                        .getVariantConfiguration()\n                        .getFullName()).getAwbBundles().stream(),\n                Stream.of(AtlasBuildContext.androidDependencyTrees.get(appVariantContext.getScope()\n                        .getVariantConfiguration()\n                        .getFullName()).getMainBundle())).flatMap(awbBundle -> Stream.concat(\n                awbBundle.getAllLibraryAars().stream(),\n                awbBundle.getJavaLibraries().stream())).collect(Collectors.toMap(library -> {\n\n            try (ZipFile zip = new ZipFile(getFile(library))) {\n\n                Enumeration<? extends ZipEntry> entries = zip.entries();\n                while (entries.hasMoreElements()) {\n                    ZipEntry zipEntry = entries.nextElement();\n                    if (!zipEntry.getName().endsWith(SdkConstants.DOT_CLASS)) {\n                        continue;\n                    }\n                    try (BufferedInputStream inputStream = new BufferedInputStream(zip\n                            .getInputStream(\n                            zipEntry))) {\n\n                    }\n                    Optional<File> fileStream = transformInputs.stream().filter(file -> {\n                        try (ZipFile zipFile = new ZipFile(file)) {\n                            ZipEntry entry = zipFile.getEntry(zipEntry.getName());\n                            if (entry != null) {\n                                try (InputStream is = zipFile.getInputStream(entry)) {\n\n                                }\n                                return true;\n                            }\n                            return false;\n                        } catch (IOException e) {\n                            throw new UncheckedIOException(e);\n                        }\n                    }).findFirst();\n                    if (fileStream.isPresent()) {\n                        return fileStream.get();\n                    }\n                }\n            } catch (IOException e) {\n                throw new UncheckedIOException(e);\n            }\n            return null;\n        }, library -> library));\n    }\n\n    private static File getFile(Object library) {\n        File file;\n        if (library instanceof AndroidLibrary) {\n            file = ((AndroidLibrary) library).getJarFile();\n        } else if (library instanceof JavaLibrary) {\n            file = ((JavaLibrary) library).getJarFile();\n        } else {\n\n            //file =;\n            throw new IllegalArgumentException(\n                    \"unexpected library type: \" + library.getClass().getName());\n        }\n        return file;\n    }\n\n    public void dispose(File inOutConfigration) {\n        File proGuardPercentFile = new File(inOutConfigration.getParentFile(),\n                \"proGuardPercent.properties\");\n        try (PrintWriter pw = new PrintWriter(new BufferedOutputStream(new FileOutputStream(\n                proGuardPercentFile)))) {\n            for (Map.Entry<File, Double> entry : getProGuardPercentMap(inOutConfigration)\n                    .entrySet()) {\n                final File key = entry.getKey();\n                final Double value = entry.getValue();\n                Library library = fileLibraryMap.get(key);\n                if (library == null) {\n                    pw.print(library.getResolvedCoordinates());\n                } else {\n                    pw.print(key);\n                }\n                pw.print(\": \");\n                printPercent(pw, value);\n                pw.println();\n            }\n        } catch (IOException e) {\n            throw new UncheckedIOException(e);\n        }\n    }\n\n    public static void printPercent(PrintWriter pw, double fraction) {\n        fraction *= 100;\n        if (fraction < 1) {\n            pw.print(String.format(\"%.2f\", fraction));\n        } else if (fraction < 10) {\n            pw.print(String.format(\"%.1f\", fraction));\n        } else {\n            pw.print(String.format(\"%.0f\", fraction));\n        }\n        pw.print(\"%\");\n    }\n\n    private ImmutableMap<File, Double> getProGuardPercentMap(File inOutConfigration) {\n        try {\n            ImmutableMap.Builder<File, Double> builder = ImmutableMap.builder();\n            builder.orderEntriesByValue(Ordering.natural());\n            for (Map.Entry<File, File> entry : injarsOutjarsMap.entrySet()) {\n                final File key = entry.getKey();\n                final File value = entry.getValue();\n                long keyLength = key.length();\n                long valueLength = value.length();\n                builder.put(key, (double) valueLength / (double) keyLength);\n            }\n            List<String> lines = Files.readLines(inOutConfigration, Charsets.UTF_8);\n            final int N = lines.size();\n            for (int i = 0; i < N; i += 2) {\n                String s = lines.get(i);\n                File injarsFile = getFile(s);\n                File outjarsFile = new File(lines.get(i + 1));\n                long injarsFileLength = injarsFile.length();\n                long outjarsFileLength = outjarsFile.length();\n                builder.put(injarsFile, (double) outjarsFileLength / (double) injarsFileLength);\n            }\n            return builder.build();\n        } catch (IOException e) {\n            throw new UncheckedIOException(e);\n        }\n    }\n\n    private File getFile(String s) {\n        final String[] parsed = s.split(\" \");\n        if (parsed.length < 2) {\n            throw new IllegalArgumentException(\"Insufficient arguments\");\n        }\n\n        //String s2 = parsed[0];\n        return new File(parsed[1]);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/domain/Input.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.proguard.domain;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.Set;\n\nimport com.android.build.api.transform.JarInput;\nimport com.android.build.gradle.internal.api.AwbTransform;\nimport com.taobao.android.builder.tools.MD5Util;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang.StringUtils;\n\n/**\n * Created by wuzhong on 2017/5/13.\n */\npublic class Input {\n\n    private List<AwbTransform> awbBundles = new ArrayList<>();\n\n    private Set<File> defaultProguardFiles = new HashSet<>();\n\n    private Set<File> libraryProguardFiles = new HashSet<>();\n\n    private Set<File> libraries = new HashSet<>();\n\n    private List<File> parentKeeps = new ArrayList<>();\n\n    private Set<String> defaultLibraryClasses = new HashSet<>();\n\n    private Map<File, String> fileMd5s = new HashMap<>();\n\n    /**\n     * proguard_out -> proguard_in_md5\n     */\n    public Map<File,String> proguardJarMap = new HashMap<>();\n\n    public File dump;\n    public File printMapping;\n    public File printUsage;\n    public File printSeeds;\n    public File printConfiguration;\n\n    public File proguardOutputDir;\n\n    public Map<File,File>maindexFileTransform = new HashMap<>();\n\n    public Map<File,File>maindexFolderTransform = new HashMap<>();\n\n\n    public List<AwbTransform> getAwbBundles() {\n        return awbBundles;\n    }\n\n    public void setAwbBundles(List<AwbTransform> awbBundles) {\n        this.awbBundles = awbBundles;\n    }\n\n    public Set<File> getDefaultProguardFiles() {\n        return defaultProguardFiles;\n    }\n\n    public void setDefaultProguardFiles(Set<File> defaultProguardFiles) {\n        this.defaultProguardFiles = defaultProguardFiles;\n    }\n\n    public List<File> getParentKeeps() {\n        return parentKeeps;\n    }\n\n    public void setParentKeeps(List<File> parentKeeps) {\n        this.parentKeeps = parentKeeps;\n    }\n\n    public Set<File> getLibraries() {\n        return libraries;\n    }\n\n    public Set<String> getDefaultLibraryClasses() {\n        return defaultLibraryClasses;\n    }\n\n    public Map<File, String> getFileMd5s() {\n        return fileMd5s;\n    }\n\n    public Map<String,File> getMd5Files() {\n         Map<String,File> map = new HashMap<>();\n         for (Entry<File,String> entry : getFileMd5s().entrySet()){\n             map.put(entry.getValue(),entry.getKey());\n         }\n         return map;\n    }\n\n    public Set<File> getLibraryProguardFiles() {\n        return libraryProguardFiles;\n    }\n\n    String md5;\n\n    public String getMd5() throws Exception {\n        if (StringUtils.isNotEmpty(md5)) {\n            return md5;\n        }\n\n        List<File> files = new ArrayList<>();\n        files.addAll(getParentKeeps());\n        files.addAll(getDefaultProguardFiles());\n        files.addAll(getLibraryProguardFiles());\n        for (AwbTransform awbTransform : this.getAwbBundles()) {\n            for (File file : awbTransform.getInputLibraries()) {\n                files.add(file);\n            }\n            //configs.add();\n            if (null != awbTransform.getInputDirs() && awbTransform.getInputDirs().size() > 0) {\n                files.addAll(awbTransform.getInputDirs());\n            }\n        }\n\n        for (File file : files) {\n            if (file.isFile()) {\n                String md5 = MD5Util.getFileMD5(file);\n                fileMd5s.put(file, md5);\n            } else {\n                String md5 = MD5Util.getFileMd5(FileUtils.listFiles(file,\n                                                                    new String[] {\"class\"},\n                                                                    true));\n                fileMd5s.put(file, md5);\n            }\n        }\n\n        List<String> mds = new ArrayList<>(fileMd5s.values());\n        Collections.sort(mds);\n\n        md5 =  MD5Util.getMD5(StringUtils.join(mds.toArray(new String[0])));\n        return md5;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/domain/Result.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.proguard.domain;\n\nimport java.io.File;\n\n/**\n * Created by wuzhong on 2017/5/14.\n */\npublic class Result {\n\n    public boolean success ;\n\n    public String key;\n\n    public File cacheDir;\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/dump/AbstractClasslVisitor.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.proguard.dump;\n\nimport proguard.classfile.Clazz;\nimport proguard.classfile.LibraryClass;\nimport proguard.classfile.LibraryField;\nimport proguard.classfile.LibraryMethod;\nimport proguard.classfile.ProgramClass;\nimport proguard.classfile.ProgramField;\nimport proguard.classfile.ProgramMethod;\nimport proguard.classfile.constant.ClassConstant;\nimport proguard.classfile.constant.DoubleConstant;\nimport proguard.classfile.constant.FieldrefConstant;\nimport proguard.classfile.constant.FloatConstant;\nimport proguard.classfile.constant.IntegerConstant;\nimport proguard.classfile.constant.InterfaceMethodrefConstant;\nimport proguard.classfile.constant.InvokeDynamicConstant;\nimport proguard.classfile.constant.LongConstant;\nimport proguard.classfile.constant.MethodHandleConstant;\nimport proguard.classfile.constant.MethodTypeConstant;\nimport proguard.classfile.constant.MethodrefConstant;\nimport proguard.classfile.constant.NameAndTypeConstant;\nimport proguard.classfile.constant.StringConstant;\nimport proguard.classfile.constant.Utf8Constant;\nimport proguard.classfile.constant.visitor.ConstantVisitor;\nimport proguard.classfile.util.SimplifiedVisitor;\nimport proguard.classfile.visitor.ClassVisitor;\nimport proguard.classfile.visitor.MemberVisitor;\n\n/**\n * Created by wuzhong on 2017/5/12.\n */\npublic class AbstractClasslVisitor extends SimplifiedVisitor implements ConstantVisitor, MemberVisitor, ClassVisitor {\n\n    @Override\n    public void visitProgramClass(ProgramClass programClass) {\n        programClass.constantPoolEntriesAccept(this);\n    }\n\n    @Override\n    public void visitLibraryClass(LibraryClass libraryClass) {\n    }\n\n    @Override\n    public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) {\n\n    }\n\n    @Override\n    public void visitLongConstant(Clazz clazz, LongConstant longConstant) {\n\n    }\n\n    @Override\n    public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) {\n\n    }\n\n    @Override\n    public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) {\n\n    }\n\n    @Override\n    public void visitStringConstant(Clazz clazz, StringConstant stringConstant) {\n\n    }\n\n    @Override\n    public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) {\n\n    }\n\n    @Override\n    public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) {\n\n    }\n\n    @Override\n    public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) {\n\n    }\n\n    @Override\n    public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) {\n    }\n\n    @Override\n    public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant) {\n\n    }\n\n    @Override\n    public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) {\n    }\n\n    @Override\n    public void visitClassConstant(Clazz clazz, ClassConstant classConstant) {\n\n    }\n\n    @Override\n    public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) {\n\n    }\n\n    @Override\n    public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) {\n\n    }\n\n    @Override\n    public void visitProgramField(ProgramClass programClass, ProgramField programField) {\n    }\n\n    @Override\n    public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) {\n    }\n\n    @Override\n    public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) {\n    }\n\n    @Override\n    public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) {\n    }\n\n    public void println(String message) {\n        System.out.println(message);\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/dump/BundleProguardDumper.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.proguard.dump;\n\nimport java.util.Map;\nimport java.util.Set;\n\nimport com.taobao.android.builder.tools.proguard.dump.utils.ReflectUtils;\nimport proguard.ProGuard;\nimport proguard.classfile.ClassPool;\n\n/**\n * Created by wuzhong on 2017/6/2.\n */\npublic class BundleProguardDumper {\n\n    public static Map<String, ClazzRefInfo> dump(ProGuard proGuard, Set<String> defaultClasses) throws Exception {\n\n        ClassPool classPool = (ClassPool)ReflectUtils.getField(proGuard, \"programClassPool\");\n        ClassPool libClassPool = (ClassPool)ReflectUtils.getField(proGuard, \"libraryClassPool\");\n\n        VisitorDTO visitorDTO = new VisitorDTO(defaultClasses, classPool, libClassPool);\n\n        classPool.classesAccept(new ClassStructVisitor(visitorDTO));\n        classPool.classesAccept(new ClassDetailVisitor(visitorDTO));\n        visitorDTO.addSuperRefInfo();\n\n        return visitorDTO.clazzRefInfoMap;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/dump/ClassDetailVisitor.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.proguard.dump;\n\nimport proguard.classfile.Clazz;\nimport proguard.classfile.LibraryClass;\nimport proguard.classfile.LibraryMethod;\nimport proguard.classfile.Method;\nimport proguard.classfile.ProgramClass;\nimport proguard.classfile.ProgramMember;\nimport proguard.classfile.ProgramMethod;\nimport proguard.classfile.attribute.Attribute;\nimport proguard.classfile.attribute.CodeAttribute;\nimport proguard.classfile.attribute.visitor.AttributeVisitor;\nimport proguard.classfile.constant.FieldrefConstant;\nimport proguard.classfile.constant.InterfaceMethodrefConstant;\nimport proguard.classfile.constant.MethodrefConstant;\nimport proguard.classfile.instruction.ConstantInstruction;\nimport proguard.classfile.instruction.Instruction;\nimport proguard.classfile.instruction.visitor.InstructionVisitor;\n\n/**\n * Created by wuzhong on 2017/5/12.\n */\npublic class ClassDetailVisitor extends AbstractClasslVisitor implements AttributeVisitor, InstructionVisitor {\n\n    private VisitorDTO visitorDTO;\n\n    public ClassDetailVisitor(VisitorDTO visitorDTO) {\n        this.visitorDTO = visitorDTO;\n    }\n\n    //class There are big problems with the order of uncertainty\n    @Override\n    public void visitProgramClass(ProgramClass programClass) {\n        programClass.constantPoolEntriesAccept(this);\n\n        programClass.methodsAccept(this);\n    }\n\n    //@Override\n    //public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) {\n    //\n    //    String clazzName = clazz.getClassName(methodrefConstant.u2classIndex);\n    //    ClazzRefInfo clazzRefInfo = visitorDTO.getClazzRefInfo(clazzName);\n    //\n    //    String methodName = clazz.getName(methodrefConstant.u2nameAndTypeIndex);\n    //    if (null != clazzRefInfo) {\n    //        clazzRefInfo.getMethods().add(methodName);\n    //    }\n    //\n    //}\n\n    @Override\n    public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) {\n        visitMember(programClass, programMethod);\n    }\n\n    private void visitMember(ProgramClass programClass, ProgramMember programMember) {\n        if (programMember.u2attributesCount > 0) {\n            //println(\"Class member attributes (count = \" + programMember.u2attributesCount + \"):\");\n            programMember.attributesAccept(programClass, this);\n        }\n    }\n\n    @Override\n    public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset,\n                                    Instruction instruction) {\n        //println(instruction.toString(offset));\n    }\n\n    @Override\n    public void visitAnyAttribute(Clazz clazz, Attribute attribute) {\n        //super.visitAnyAttribute(clazz, attribute);\n\n        //System.out.println(\">>>>>>\");\n\n    }\n\n    @Override\n    public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) {\n\n        //println(\"visitCodeAttribute >>>>>\");\n\n        codeAttribute.instructionsAccept(clazz, method, this);\n    }\n\n    @Override\n    public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset,\n                                         ConstantInstruction constantInstruction) {\n        //println(\"visitConstantInstruction >>>\" + constantInstruction.toString(offset));\n\n        //indent();\n        clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);\n        //outdent();\n    }\n\n    @Override\n    public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) {\n\n        //println(\"visitMethodrefConstant Methodref [\" +\n        //            clazz.getClassName(methodrefConstant.u2classIndex) + \".\" +\n        //            clazz.getName(methodrefConstant.u2nameAndTypeIndex) + \" \" +\n        //            clazz.getType(methodrefConstant.u2nameAndTypeIndex) + \"]\");\n\n        addMethod(clazz.getClassName(methodrefConstant.u2classIndex),\n                  clazz.getName(methodrefConstant.u2nameAndTypeIndex),\n                  clazz.getType(methodrefConstant.u2nameAndTypeIndex), false);\n\n    }\n\n    @Override\n    public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant) {\n        //println(\"visitInterfaceMethodrefConstant InterfaceMethodref [\" +\n        //            clazz.getClassName(interfaceMethodrefConstant.u2classIndex) + \".\" +\n        //            clazz.getName(interfaceMethodrefConstant.u2nameAndTypeIndex) + \" \" +\n        //            clazz.getType(interfaceMethodrefConstant.u2nameAndTypeIndex) + \"]\");\n\n        addMethod(clazz.getClassName(interfaceMethodrefConstant.u2classIndex),\n                  clazz.getName(interfaceMethodrefConstant.u2nameAndTypeIndex),\n                  clazz.getType(interfaceMethodrefConstant.u2nameAndTypeIndex), true);\n\n    }\n\n    @Override\n    public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) {\n\n        //println(\"visitFieldrefConstant Methodref [\" +\n        //            clazz.getClassName(fieldrefConstant.u2classIndex) + \".\" +\n        //            clazz.getName(fieldrefConstant.u2nameAndTypeIndex) + \" \" +\n        //            clazz.getType(fieldrefConstant.u2nameAndTypeIndex) + \"]\");\n\n        addField(clazz.getClassName(fieldrefConstant.u2classIndex),\n                 clazz.getName(fieldrefConstant.u2nameAndTypeIndex));\n\n    }\n\n    private void addMethod(String name, String method, String args, boolean interfaceClazz) {\n        //println(\"addMethod \" + name + \".\" + method);\n\n        ClazzRefInfo clazzRefInfo = visitorDTO.getClazzRefInfo(name);\n        if (null != clazzRefInfo) {\n\n            if (interfaceClazz) {\n                clazzRefInfo.setNeedExtend(true);\n            }\n\n            //keep it interface\n            LibraryClass libraryClass = (LibraryClass)visitorDTO.libraryClassPool.getClass(clazzRefInfo.getClazzName());\n            //Determine if you can hit super class\n            if (null != libraryClass) {\n\n                ClazzRefInfo superRefInfo = getSuperClazzRef(libraryClass, method, args);\n                if (null != superRefInfo){\n                    superRefInfo.getMethods().add(method);\n                }\n\n            }\n\n            //clazzRefInfo.getMethods().add(method);\n\n        }\n\n    }\n\n    private ClazzRefInfo getSuperClazzRef(LibraryClass libraryClass, String methodName, String args) {\n        if (null == libraryClass || !visitorDTO.isLibClazz(libraryClass.getName())) {\n            return null;\n        }\n        for (LibraryMethod method : libraryClass.methods) {\n            if (method.name.equals(methodName) && method.descriptor.equals(args)) {\n                ClazzRefInfo clazzRefInfo = visitorDTO.getClazzRefInfoByName(libraryClass.getName());\n                return clazzRefInfo;\n            }\n        }\n\n        Clazz clazz = libraryClass.getSuperClass();\n        ClazzRefInfo clazzRefInfo = getClazzRefInfoBySuper(methodName, args, clazz);\n        if (clazzRefInfo != null) {\n            return clazzRefInfo;\n        }\n        for (int i = 0; i < libraryClass.getInterfaceCount(); i++) {\n            ClazzRefInfo clazzRefInfo1 = getClazzRefInfoBySuper(methodName, args, libraryClass.getInterface(i));\n            if (clazzRefInfo1 != null) {\n                return clazzRefInfo1;\n            }\n        }\n        return null;\n    }\n\n    private ClazzRefInfo getClazzRefInfoBySuper(String methodName, String args, Clazz clazz) {\n        if (null != clazz && visitorDTO.isLibClazz(clazz.getName())) {\n            return getSuperClazzRef((LibraryClass)clazz, methodName, args);\n        }\n        return null;\n    }\n\n    private void addField(String name, String field) {\n\n        //println(\"addField \" + name + \".\" + field);\n\n        ClazzRefInfo clazzRefInfo = visitorDTO.getClazzRefInfo(name);\n        if (null != clazzRefInfo) {\n            clazzRefInfo.getFields().add(field);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/dump/ClassStructVisitor.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.proguard.dump;\n\nimport com.taobao.android.builder.tools.proguard.dump.VisitorDTO.ClassStruct;\nimport com.taobao.android.builder.tools.proguard.dump.VisitorDTO.LibraryClazzInfo;\nimport org.apache.commons.lang.StringUtils;\nimport proguard.classfile.Clazz;\nimport proguard.classfile.LibraryClass;\nimport proguard.classfile.ProgramClass;\nimport proguard.classfile.ProgramField;\nimport proguard.classfile.ProgramMethod;\nimport proguard.classfile.visitor.ClassVisitor;\n\n/**\n * Created by wuzhong on 2017/5/12.\n *\n * Find the parent-child relationship of all classes, yes The current class -> root library class\n */\npublic class ClassStructVisitor extends AbstractClasslVisitor implements ClassVisitor {\n\n    private VisitorDTO visitorDTO;\n\n    public ClassStructVisitor(VisitorDTO visitorDTO) {\n        this.visitorDTO = visitorDTO;\n    }\n\n    //class There are big problems with the order of uncertainty\n    @Override\n    public void visitProgramClass(ProgramClass programClass) {\n\n        addSuperClass(programClass);\n\n        for (int i = 0; i < programClass.getInterfaceCount(); i++) {\n            addInterface(programClass, i);\n        }\n\n        programClass.methodsAccept(this);\n\n        programClass.fieldsAccept(this);\n\n    }\n\n    private void addInterface(ProgramClass programClass, int i) {\n        String interfaceClazz = programClass.getInterfaceName(i);\n        //Simplify the process\n        if (visitorDTO.isLibClazz(interfaceClazz)) {\n            ClassStruct classStruct = getOrCreateClassStruct(programClass);\n            classStruct.addInterface(interfaceClazz);\n\n            //add super interface to keep\n            addSuperInterfaces(interfaceClazz, classStruct);\n\n        }\n    }\n\n    private void addSuperInterfaces(String interfaceClazz, ClassStruct classStruct) {\n        LibraryClass libraryClass = (LibraryClass)visitorDTO.libraryClassPool.getClass(interfaceClazz);\n        if (null == libraryClass) {\n            return;\n        }\n        for (int index = 0; index < libraryClass.getInterfaceCount(); index++) {\n            Clazz superInter = libraryClass.getInterface(index);\n            if (null != superInter && visitorDTO.isLibClazz(superInter.getName())) {\n                classStruct.addInterface(superInter.getName());\n\n                //Then an iterative\n                addSuperInterfaces(superInter.getName(), classStruct);\n\n            }\n        }\n    }\n\n    private ClassStruct getOrCreateClassStruct(ProgramClass programClass) {\n        ClassStruct classStruct = visitorDTO.classStructMap.get(programClass.getName());\n        if (null == classStruct) {\n            classStruct = new ClassStruct();\n            visitorDTO.classStructMap.put(programClass.getName(), classStruct);\n        }\n        return classStruct;\n    }\n\n    private void addSuperClass(ProgramClass programClass) {\n        String superName = visitorDTO.findRootLibClazz(programClass);\n        if (StringUtils.isEmpty(superName)) {\n            return;\n        }\n        ClassStruct classStruct = getOrCreateClassStruct(programClass);\n        classStruct.superClazzName = superName;\n    }\n\n    @Override\n    public void visitProgramField(ProgramClass programClass, ProgramField programField) {\n        LibraryClazzInfo libraryClazzInfo = getOrCreateLibraryClazzInfo(programClass);\n        if (null != libraryClazzInfo) {\n            libraryClazzInfo.addField(programField.getName(programClass));\n        }\n    }\n\n    @Override\n    public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) {\n        LibraryClazzInfo libraryClazzInfo = getOrCreateLibraryClazzInfo(programClass);\n        if (null != libraryClazzInfo) {\n            libraryClazzInfo.addMethod(programMethod.getName(programClass));\n        }\n    }\n\n    private LibraryClazzInfo getOrCreateLibraryClazzInfo(ProgramClass programClass) {\n\n        return visitorDTO.getLibraryClazzInfo(programClass.getName());\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/dump/ClazzRefInfo.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.proguard.dump;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * Class information referenced\n */\npublic class ClazzRefInfo {\n\n    private String clazzName;\n\n    private boolean keepAll;\n\n    /**\n     * You need to keep the class\n     */\n    private boolean needExtend;\n\n    //for json serizable\n    public ClazzRefInfo() {\n    }\n\n    public ClazzRefInfo(String clazzName) {\n        this.clazzName = clazzName;\n    }\n\n    private Set<String> methods = new HashSet<>();\n    private Set<String> fields = new HashSet<>();\n\n    public String getClazzName() {\n        return clazzName;\n    }\n\n    public void setClazzName(String clazzName) {\n        this.clazzName = clazzName;\n    }\n\n    public Set<String> getMethods() {\n        return methods;\n    }\n\n    public void setMethods(Set<String> methods) {\n        this.methods = methods;\n    }\n\n    public Set<String> getFields() {\n        return fields;\n    }\n\n    public void setFields(Set<String> fields) {\n        this.fields = fields;\n    }\n\n    public boolean isKeepAll() {\n        return keepAll;\n    }\n\n    public void setKeepAll(boolean keepAll) {\n        this.keepAll = keepAll;\n    }\n\n    public boolean isNeedExtend() {\n        return needExtend;\n    }\n\n    public void setNeedExtend(boolean needExtend) {\n        this.needExtend = needExtend;\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/dump/ClazzRefInfoContainer.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.proguard.dump;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Created by wuzhong on 2017/5/14.\n */\npublic class ClazzRefInfoContainer {\n\n    private Map<String, ClazzRefInfo> refClazzMap = new HashMap<>();\n\n    public ClazzRefInfoContainer(\n        Map<String, ClazzRefInfo> refClazzMap) {\n        this.refClazzMap = refClazzMap;\n    }\n\n    public ClazzRefInfoContainer() {\n    }\n\n    public void addRefClazz(Map<String, ClazzRefInfo> other) {\n\n        for (String key : other.keySet()) {\n\n            ClazzRefInfo otherClazz = other.get(key);\n            ClazzRefInfo clazz = refClazzMap.get(key);\n            if (null == clazz) {\n                refClazzMap.put(key, otherClazz);\n            } else {\n                clazz.getFields().addAll(otherClazz.getFields());\n                clazz.getMethods().addAll(otherClazz.getMethods());\n                clazz.setKeepAll(clazz.isKeepAll() || otherClazz.isKeepAll());\n                clazz.setNeedExtend(clazz.isNeedExtend() || otherClazz.isNeedExtend());\n            }\n        }\n\n    }\n\n    public List<String> convertToKeeplines() {\n\n        List<ClazzRefInfo> refClazzes = new ArrayList<>(refClazzMap.values());\n        Collections.sort(refClazzes, new Comparator<ClazzRefInfo>() {\n            @Override\n            public int compare(ClazzRefInfo o1, ClazzRefInfo o2) {\n                return o1.getClazzName().compareTo(o2.getClazzName());\n            }\n        });\n\n        List<String> lines = new ArrayList<>();\n        for (ClazzRefInfo refClazz : refClazzes) {\n\n            String line = \"-keep class \";\n            addKeepLines(lines, refClazz, line);\n\n            if (refClazz.isNeedExtend()){\n                line += \" * extends \";\n                addKeepLines(lines, refClazz, line);\n            }\n\n        }\n        return lines;\n\n    }\n\n    private void addKeepLines(List<String> lines, ClazzRefInfo refClazz, String line) {\n        line += refClazz.getClazzName().replace(\"/\", \".\");\n        if (refClazz.isKeepAll()) {\n            lines.add(line + \" { *; }\");\n        } else {\n            lines.add(line + \" {\");\n            List<String> methods = new ArrayList<>(refClazz.getMethods());\n            List<String> fields = new ArrayList<>(refClazz.getFields());\n            Collections.sort(methods);\n            Collections.sort(fields);\n            for (String name : methods) {\n                lines.add(\" *** \" + name + \"(...);\");\n            }\n            for (String name : fields) {\n                lines.add(\" *** \" + name + \";\");\n            }\n            lines.add(\"}\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/dump/KeepConverter.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.proguard.dump;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Created by wuzhong on 2017/5/14.\n */\npublic class KeepConverter {\n\n    private Map<String, ClazzRefInfo> refClazzMap = new HashMap<>();\n\n    public KeepConverter(\n        Map<String, ClazzRefInfo> refClazzMap) {\n        this.refClazzMap = refClazzMap;\n    }\n\n    public KeepConverter() {\n    }\n\n    public void addRefClazz(Map<String, ClazzRefInfo> other) {\n\n        for (String key : other.keySet()) {\n\n            ClazzRefInfo otherClazz = other.get(key);\n            ClazzRefInfo clazz = refClazzMap.get(key);\n            if (null == clazz) {\n                refClazzMap.put(key, otherClazz);\n            } else {\n                clazz.getFields().addAll(otherClazz.getFields());\n                clazz.getMethods().addAll(otherClazz.getMethods());\n                clazz.setKeepAll(clazz.isKeepAll() || otherClazz.isKeepAll());\n                clazz.setNeedExtend(clazz.isNeedExtend() || otherClazz.isNeedExtend());\n            }\n        }\n\n    }\n\n    public List<String> convertToKeeplines() {\n\n        List<ClazzRefInfo> refClazzes = new ArrayList<>(refClazzMap.values());\n        Collections.sort(refClazzes, new Comparator<ClazzRefInfo>() {\n            @Override\n            public int compare(ClazzRefInfo o1, ClazzRefInfo o2) {\n                return o1.getClazzName().compareTo(o2.getClazzName());\n            }\n        });\n\n        List<String> lines = new ArrayList<>();\n        for (ClazzRefInfo refClazz : refClazzes) {\n\n            String line = \"-keep class \";\n            addKeepLines(lines, refClazz, line);\n\n            if (refClazz.isNeedExtend()){\n                line += \" * extends \";\n                addKeepLines(lines, refClazz, line);\n            }\n\n        }\n        return lines;\n\n    }\n\n    private void addKeepLines(List<String> lines, ClazzRefInfo refClazz, String line) {\n        line += refClazz.getClazzName().replace(\"/\", \".\");\n        if (refClazz.isKeepAll()) {\n            lines.add(line + \" { *; }\");\n        } else {\n            lines.add(line + \" {\");\n            List<String> methods = new ArrayList<>(refClazz.getMethods());\n            List<String> fields = new ArrayList<>(refClazz.getFields());\n            Collections.sort(methods);\n            Collections.sort(fields);\n            for (String name : methods) {\n                lines.add(\" *** \" + name + \"(...);\");\n            }\n            for (String name : fields) {\n                lines.add(\" *** \" + name + \";\");\n            }\n            lines.add(\"}\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/dump/VisitorDTO.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.proguard.dump;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.apache.commons.lang.StringUtils;\nimport proguard.classfile.ClassConstants;\nimport proguard.classfile.ClassPool;\nimport proguard.classfile.Clazz;\nimport proguard.classfile.LibraryClass;\n\n/**\n * Created by wuzhong on 2017/5/27.\n */\npublic class VisitorDTO {\n\n    /**\n     * System class list, aa/bb\n     */\n    public Set<String> defaultClasses;\n\n    /**\n     * The current classpool\n     */\n    public ClassPool currentClassPool;\n\n    public ClassPool libraryClassPool;\n\n    public Set<String> abstractClasses = new HashSet<>();\n\n    /**\n     * current classpool The structure of the next class, among them super Points to the library The class of\n     */\n    public Map<String, ClassStruct> classStructMap = new HashMap<>();\n\n    public Map<String, LibraryClazzInfo> libraryClazzInfoMap = new HashMap<>();\n\n    /**\n     * Final output\n     */\n    public Map<String, ClazzRefInfo> clazzRefInfoMap = new HashMap<>();\n\n    public VisitorDTO(Set<String> defaultClasses, ClassPool currentClassPool, ClassPool libraryClassPool) {\n        this.defaultClasses = defaultClasses;\n        this.currentClassPool = currentClassPool;\n        this.libraryClassPool = libraryClassPool;\n    }\n\n    /**\n     * Find out what's closest to him library class\n     *\n     * @param programClass\n     * @return\n     */\n    public String findRootLibClazz(Clazz programClass) {\n        Clazz superClass = programClass.getSuperClass();\n        if (null == superClass) {\n            return \"\";\n        }\n        if (superClass instanceof LibraryClass) {\n            LibraryClass libraryClass = (LibraryClass)superClass;\n            String className = libraryClass.getName();\n            if (isLibClazz(className)) {\n                if ((libraryClass.getAccessFlags() & ClassConstants.ACC_ABSTRACT) == ClassConstants.ACC_ABSTRACT) {\n                    abstractClasses.add(className);\n                }\n                return className;\n            }\n            return \"\";\n        }\n        return findRootLibClazz(superClass);\n    }\n\n    public String findRootLibClazz(String className) {\n        if (isLibClazz(className)) {\n            return className;\n        }\n        Clazz clazz = currentClassPool.getClass(className);\n        //assert clazz!=null;\n        if (null == clazz) {\n            return \"\";\n        }\n        return findRootLibClazz(clazz);\n    }\n\n    public boolean isLibClazz(String className) {\n        //System.out.println(className);\n        if (defaultClasses.contains(className)) {\n            return false;\n        }\n        if (className.contains(\"[\")) {\n            return false;\n        }\n        if (null != currentClassPool.getClass(className)) {\n            return false;\n        }\n        return true;\n    }\n\n    public LibraryClazzInfo getLibraryClazzInfo(String className) {\n        String rootLibraryClass = this.findRootLibClazz(className);\n        if (StringUtils.isEmpty(rootLibraryClass)) {\n            return null;\n        }\n\n        LibraryClazzInfo libraryClazzInfo = this.libraryClazzInfoMap.get(rootLibraryClass);\n        if (null == libraryClazzInfo) {\n            libraryClazzInfo = new LibraryClazzInfo();\n            this.libraryClazzInfoMap.put(rootLibraryClass, libraryClazzInfo);\n        }\n        return libraryClazzInfo;\n    }\n\n    public ClazzRefInfo getClazzRefInfo(String className) {\n        String rootLibraryClass = this.findRootLibClazz(className);\n        if (StringUtils.isEmpty(rootLibraryClass)) {\n            return null;\n        }\n\n        return getClazzRefInfoByName(rootLibraryClass);\n    }\n\n    public ClazzRefInfo getClazzRefInfoByName(String className) {\n        ClazzRefInfo libraryClazzInfo = this.clazzRefInfoMap.get(className);\n        if (null == libraryClazzInfo) {\n            libraryClazzInfo = new ClazzRefInfo(className);\n            this.clazzRefInfoMap.put(className, libraryClazzInfo);\n            if (isVirtualClass(className)){\n                libraryClazzInfo.setNeedExtend(true);\n            }\n        }\n\n        return libraryClazzInfo;\n\n    }\n\n    public void addSuperRefInfo() {\n        for (ClassStruct classStruct : classStructMap.values()) {\n            if (StringUtils.isNotEmpty(classStruct.superClazzName)) {\n                if (abstractClasses.contains(classStruct.superClazzName)) {\n                    getClazzRefInfoByName(classStruct.superClazzName).setKeepAll(true);\n                } else {\n                    getClazzRefInfoByName(classStruct.superClazzName).setNeedExtend(true);\n                }\n            }\n            for (String inter : classStruct.libInterfaces) {\n                getClazzRefInfoByName(inter).setKeepAll(true);\n            }\n        }\n    }\n\n    private boolean isVirtualClass(String className){\n        Clazz clazz = libraryClassPool.getClass(className);\n        if (null == clazz){\n            return false;\n        }\n        if ((clazz.getAccessFlags() & ClassConstants.ACC_ABSTRACT) == ClassConstants.ACC_ABSTRACT) {\n            abstractClasses.add(className);\n            return true;\n        }\n        return false;\n    }\n\n    public static class ClassStruct {\n\n        public String superAbsClazzName;\n\n        public String superClazzName;\n\n        public Set<String> libInterfaces = new HashSet<>();\n\n        public synchronized void addInterface(String str){\n            libInterfaces.add(str);\n        }\n\n    }\n\n    public static class LibraryClazzInfo {\n\n        public String clazzName;\n\n        public Set<String> appMethods = new HashSet<>();\n\n        public Set<String> appFields = new HashSet<>();\n\n        public synchronized void addMethod(String str) {\n            appMethods.add(str);\n        }\n\n        public synchronized void addField(String str) {\n            appFields.add(str);\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/proguard/dump/utils/ReflectUtils.java",
    "content": "package com.taobao.android.builder.tools.proguard.dump.utils;\n\nimport java.lang.reflect.Field;\n\npublic class ReflectUtils {\n\n    public static Object getField(Object obj, String fieldName) throws Exception {\n        Field t = obj.getClass().getDeclaredField(fieldName);\n        t.setAccessible(true);\n        return t.get(obj);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/sign/AndroidSigner.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.sign;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Map;\n\nimport com.android.builder.signing.DefaultSigningConfig;\nimport com.android.builder.signing.SigningException;\n\n/**\n * Created by wuzhong on 2016/12/6.\n */\npublic class AndroidSigner {\n\n    public boolean signFile(File inFile, File outFile, DefaultSigningConfig signingConfig) throws IOException,\n            SigningException {\n        return LocalSignHelper.sign(inFile, outFile, signingConfig, \"\");\n    }\n\n\n    public boolean signFile(File inFile, File outFile, DefaultSigningConfig signingConfig, Map params) throws IOException,\n                                                                                                       SigningException {\n        return signFile(inFile,outFile,signingConfig);\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/sign/LocalSignHelper.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.sign;\n\nimport com.android.apkzlib.zfile.ApkCreator;\nimport com.android.apkzlib.zfile.ApkCreatorFactory;\nimport com.android.apkzlib.zfile.ApkZFileCreatorFactory;\nimport com.android.apkzlib.zfile.NativeLibrariesPackagingMode;\nimport com.android.apkzlib.zip.ZFileOptions;\nimport com.android.apkzlib.zip.compress.BestAndDefaultDeflateExecutorCompressor;\n\nimport com.android.builder.signing.DefaultSigningConfig;\nimport com.android.builder.signing.SigningException;\nimport com.android.ide.common.signing.CertificateInfo;\nimport com.android.ide.common.signing.KeystoreHelper;\nimport com.android.ide.common.signing.KeytoolException;\nimport com.google.common.base.Preconditions;\nimport com.google.common.base.Predicate;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.tools.ant.taskdefs.Zip;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.security.NoSuchAlgorithmException;\n\nimport java.security.PrivateKey;\nimport java.util.*;\nimport java.util.concurrent.LinkedBlockingDeque;\nimport java.util.concurrent.ThreadPoolExecutor;\nimport java.util.concurrent.TimeUnit;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n/**\n * Created by shenghua.nish on 2015-11-06 10:54 a.m.\n */\npublic class LocalSignHelper {\n    /**\n     * Local signature tool classes\n     *\n     * @param inputFile\n     * @param outputFile\n     * @param signingConfig\n     * @return\n     *\n     *\n     */\n\n\n    private static NativeLibrariesPackagingMode nativeLibrariesPackagingMode = NativeLibrariesPackagingMode.COMPRESSED;\n    public static boolean sign(File inputFile,\n                               File outputFile,\n                               DefaultSigningConfig signingConfig,\n                               String signName) throws IOException, SigningException {\n\n\n            if (outputFile.exists()) {\n                FileUtils.deleteQuietly(outputFile);\n            }else {\n                FileUtils.forceMkdir(outputFile.getParentFile());\n            }\n\n            try {\n\n                CertificateInfo certificateInfo = null;\n                if (signingConfig != null && signingConfig.isSigningReady()) {\n                    certificateInfo = KeystoreHelper.getCertificateInfo(signingConfig.getStoreType(),\n                            Preconditions.checkNotNull(signingConfig.getStoreFile()),\n                            Preconditions.checkNotNull(signingConfig.getStorePassword()),\n                            Preconditions.checkNotNull(signingConfig.getKeyPassword()),\n                            Preconditions.checkNotNull(signingConfig.getKeyAlias()));\n                    if (certificateInfo == null) {\n                        throw new SigningException(\"Failed to read key from keystore\");\n                    }\n                    System.err.println(\"LocalSign:\"+signingConfig.toString());\n                } else {\n                    throw new SigningException(\"SigningConfig not found or incomplete\");\n                }\n\n\n                Predicate<String> noCompressPredicate = getNoCompressPredicate(inputFile.getAbsolutePath());\n                        ApkCreatorFactory.CreationData creationData =\n                        new ApkCreatorFactory.CreationData(\n                                outputFile,\n                                certificateInfo.getKey(),\n                                certificateInfo.getCertificate(),\n                                signingConfig.isV1SigningEnabled(),\n                                signingConfig.isV2SigningEnabled(),\n                                null,\n                                null,\n                                14,\n                                nativeLibrariesPackagingMode,\n                                noCompressPredicate);\n\n                ApkCreatorFactory apkCreatorFactory = createFactory();\n\n                ApkCreator mApkCreator = apkCreatorFactory.make(creationData);\n\n                mApkCreator.writeZip(inputFile,null,null);\n\n                mApkCreator.hasPendingChangesWithWait();\n\n                mApkCreator.close();\n\n\n            } catch (Exception e) {\n\n                throw new SigningException(e.getMessage(), e);\n\n            } finally {\n\n            }\n\n\n            return true;\n\n    }\n\n\n    private static ApkCreatorFactory createFactory() {\n        ZFileOptions options = new ZFileOptions();\n        options.setNoTimestamps(true);\n        options.setCoverEmptySpaceUsingExtraField(true);\n        ThreadPoolExecutor compressionExecutor =\n                new ThreadPoolExecutor(\n                        0, /* Number of always alive threads */\n                        2,\n                        100,\n                        TimeUnit.MILLISECONDS,\n                        new LinkedBlockingDeque<>());\n        options.setCompressor(\n                new BestAndDefaultDeflateExecutorCompressor(\n                        compressionExecutor,\n                        options.getTracker(),\n                        1.0));\n        options.setAutoSortFiles(true);\n        return new ApkZFileCreatorFactory(options);\n\n    }\n\n    private static Predicate<String> getNoCompressPredicate(String srcPath) throws IOException {\n        Set<String> noCompressEntries = new HashSet<>();\n        ZipFile zipFile = new ZipFile(srcPath);\n        Enumeration<? extends ZipEntry> entries = zipFile.entries();\n        while (entries.hasMoreElements()){\n            ZipEntry zipEntry = entries.nextElement();\n            if (zipEntry.getMethod() == 0){\n                if (zipEntry.getName().endsWith(\".so\")){\n                    nativeLibrariesPackagingMode = NativeLibrariesPackagingMode.UNCOMPRESSED_AND_ALIGNED;\n                }\n                noCompressEntries.add(zipEntry.getName());\n            }\n        }\n        return s -> noCompressEntries.contains(s);\n    }\n\n    private static Predicate<String> getNoCompressPredicate(File inputFile) throws IOException {\n        List<String> paths = new ArrayList<>();\n        ZipFile zFile = new ZipFile(inputFile);\n        Enumeration<? extends ZipEntry>enumeration =  zFile.entries();\n        while (enumeration.hasMoreElements()){\n            ZipEntry zipEntry = enumeration.nextElement();\n            if (zipEntry.getMethod()==0){\n                paths.add(zipEntry.getName());\n            }\n        }\n        return s -> paths.contains(s);\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/sign/LocalSignedJarBuilder.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.sign;\n\nimport com.android.SdkConstants;\nimport com.android.annotations.NonNull;\nimport com.android.annotations.Nullable;\nimport com.android.builder.signing.SigningException;\n\nimport org.apache.commons.lang.StringUtils;\nimport org.bouncycastle.asn1.ASN1InputStream;\nimport org.bouncycastle.asn1.DEROutputStream;\nimport org.bouncycastle.cert.jcajce.JcaCertStore;\nimport org.bouncycastle.cms.CMSException;\nimport org.bouncycastle.cms.CMSProcessableByteArray;\nimport org.bouncycastle.cms.CMSSignedData;\nimport org.bouncycastle.cms.CMSSignedDataGenerator;\nimport org.bouncycastle.cms.CMSTypedData;\nimport org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;\nimport org.bouncycastle.operator.ContentSigner;\nimport org.bouncycastle.operator.OperatorCreationException;\nimport org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;\nimport org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;\nimport org.bouncycastle.util.encoders.Base64;\n\nimport java.io.BufferedOutputStream;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FilterOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.io.PrintStream;\nimport java.security.DigestOutputStream;\nimport java.security.GeneralSecurityException;\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.PrivateKey;\nimport java.security.Signature;\nimport java.security.cert.CertificateEncodingException;\nimport java.security.cert.X509Certificate;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.util.jar.Attributes;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\nimport java.util.jar.JarOutputStream;\nimport java.util.jar.Manifest;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\n\n/**\n * Local signature tool classes\n * Created by shenghua.nish on 2015-10-16 Sqlstate morning.\n */\npublic class LocalSignedJarBuilder {\n    private static final String DIGEST_ALGORITHM = \"SHA1\";\n\n    private static final String DIGEST_ATTR = \"SHA1-Digest\";\n\n    private static final String DIGEST_MANIFEST_ATTR = \"SHA1-Digest-Manifest\";\n\n    /**\n     * Write to another stream and track how many bytes have been\n     * written.\n     */\n    private static class CountOutputStream extends FilterOutputStream {\n        private int mCount = 0;\n\n        public CountOutputStream(OutputStream out) {\n            super(out);\n            mCount = 0;\n        }\n\n        @Override\n        public void write(int b) throws IOException {\n            super.write(b);\n            mCount++;\n        }\n\n        @Override\n        public void write(byte[] b, int off, int len) throws IOException {\n            super.write(b, off, len);\n            mCount += len;\n        }\n\n        public int size() {\n            return mCount;\n        }\n    }\n\n    private JarOutputStream mOutputJar;\n\n    private PrivateKey mKey;\n\n    private X509Certificate mCertificate;\n\n    private Manifest mManifest;\n\n    private MessageDigest mMessageDigest;\n\n    private String mSignFile;\n\n    private byte[] mBuffer = new byte[4096];\n\n    /**\n     * Classes which implement this interface provides a method to check whether a file should\n     * be added to a Jar file.\n     */\n    public interface IZipEntryFilter {\n\n        /**\n         * An exception thrown during packaging of a zip file into APK file.\n         * This is typically thrown by implementations of\n         * {@link IZipEntryFilter#checkEntry(String)}.\n         */\n        public static class ZipAbortException extends Exception {\n            private static final long serialVersionUID = 1L;\n\n            public ZipAbortException() {\n                super();\n            }\n\n            public ZipAbortException(String format, Object... args) {\n                super(String.format(format, args));\n            }\n\n            public ZipAbortException(Throwable cause, String format, Object... args) {\n                super(String.format(format, args), cause);\n            }\n\n            public ZipAbortException(Throwable cause) {\n                super(cause);\n            }\n        }\n\n        /**\n         * Checks a file for inclusion in a Jar archive.\n         *\n         * @param archivePath the archive file path of the entry\n         * @return <code>true</code> if the file should be included.\n         * @throws ZipAbortException if writing the file should be aborted.\n         */\n        public boolean checkEntry(String archivePath) throws ZipAbortException;\n    }\n\n    /**\n     * Creates a {@link SignedJarBuilder} with a given output stream, and signing information.\n     * <p/>If either <code>key</code> or <code>certificate</code> is <code>null</code> then\n     * the archive will not be signed.\n     *\n     * @param out         the {@link OutputStream} where to write the Jar archive.\n     * @param key         the {@link PrivateKey} used to sign the archive, or <code>null</code>.\n     * @param certificate the {@link X509Certificate} used to sign the archive, or\n     *                    <code>null</code>.\n     * @throws IOException\n     * @throws NoSuchAlgorithmException\n     */\n    public LocalSignedJarBuilder(@NonNull OutputStream out,\n                                 @Nullable PrivateKey key,\n                                 @Nullable X509Certificate certificate,\n                                 @Nullable String builtBy,\n                                 @Nullable String createdBy,\n                                 @Nullable String signFile) throws IOException, NoSuchAlgorithmException {\n        mOutputJar = new JarOutputStream(new BufferedOutputStream(out));\n        mOutputJar.setLevel(9);\n        mKey = key;\n        mCertificate = certificate;\n        mSignFile = signFile;\n\n        if (mKey != null && mCertificate != null) {\n            mManifest = new Manifest();\n            Attributes main = mManifest.getMainAttributes();\n            main.putValue(\"Manifest-Version\", \"1.0\");\n            if (builtBy != null) {\n                main.putValue(\"Built-By\", builtBy);\n            }\n            if (createdBy != null) {\n                main.putValue(\"Created-By\", createdBy);\n            }\n\n            mMessageDigest = MessageDigest.getInstance(DIGEST_ALGORITHM);\n        }\n    }\n\n    /**\n     * Writes a new {@link File} into the archive.\n     *\n     * @param inputFile the {@link File} to write.\n     * @param jarPath   the filepath inside the archive.\n     * @throws IOException\n     */\n    public void writeFile(File inputFile, String jarPath) throws IOException {\n        // Get an input stream on the file.\n        FileInputStream fis = new FileInputStream(inputFile);\n        try {\n\n            // create the zip entry\n            JarEntry entry = new JarEntry(jarPath);\n            entry.setTime(inputFile.lastModified());\n\n            writeEntry(fis, entry);\n        } finally {\n            // close the file stream used to read the file\n            fis.close();\n        }\n    }\n\n    private final byte[] buffer = new byte[8192];\n\n    /**\n     * Copies the content of a Jar/Zip archive into the receiver archive.\n     * <p/>An optional {@link IZipEntryFilter} allows to selectively choose which files\n     * to copy over.\n     *\n     * @param input  the {@link InputStream} for the Jar/Zip to copy.\n     * @param filter the filter or <code>null</code>\n     * @throws IOException\n     * @throws SignedJarBuilder.IZipEntryFilter.ZipAbortException if the {@link IZipEntryFilter} filter indicated that the write\n     *                                                            must be aborted.\n     */\n    public void writeZip(InputStream input,\n                         IZipEntryFilter filter) throws IOException, IZipEntryFilter.ZipAbortException {\n        ZipInputStream zis = new ZipInputStream(input);\n\n        try {\n            // loop on the entries of the intermediary package and put them in the final package.\n            ZipEntry entry;\n            while ((entry = zis.getNextEntry()) != null) {\n                String name = entry.getName();\n\n                // do not take directories or anything inside a potential META-INF folder.\n                if (entry.isDirectory()) {\n                    continue;\n                }\n\n                // ignore some of the content in META-INF/ but not all\n                if (name.startsWith(\"META-INF/\")) {\n                    // ignore the manifest file.\n                    String subName = name.substring(9);\n                    if (\"MANIFEST.MF\".equals(subName)) {\n                        int count;\n                        ByteArrayOutputStream out = new ByteArrayOutputStream();\n                        while ((count = zis.read(buffer)) != -1) {\n                            out.write(buffer, 0, count);\n                        }\n                        ByteArrayInputStream swapStream = new ByteArrayInputStream(out.toByteArray());\n                        Manifest manifest = new Manifest(swapStream);\n                        mManifest.getMainAttributes().putAll(manifest.getMainAttributes());\n                        continue;\n                    }\n\n                    // special case for Maven meta-data because we really don't care about them in apks.\n                    if (name.startsWith(\"META-INF/maven/\")) {\n                        continue;\n                    }\n\n                    // check for subfolder\n                    int index = subName.indexOf('/');\n                    if (index == -1) {\n                        // no sub folder, ignores signature files.\n                        if (subName.endsWith(\".SF\") ||\n                                name.endsWith(\".RSA\") ||\n                                name.endsWith(\".DSA\")) {\n                            continue;\n                        }\n                    }\n                }\n\n                // if we have a filter, we check the entry against it\n                if (filter != null && !filter.checkEntry(name)) {\n                    continue;\n                }\n\n                JarEntry newEntry;\n\n                // Preserve the STORED method of the input entry.\n                if (entry.getMethod() == JarEntry.STORED) {\n                    newEntry = new JarEntry(entry);\n                } else {\n                    // Create a new entry so that the compressed len is recomputed.\n                    newEntry = new JarEntry(name);\n                }\n\n                writeEntry(zis, newEntry);\n\n                zis.closeEntry();\n            }\n        } finally {\n            zis.close();\n        }\n    }\n\n    /**\n     * Closes the Jar archive by creating the manifest, and signing the archive.\n     *\n     * @throws IOException\n     * @throws SigningException\n     */\n    public void close() throws IOException, SigningException {\n        if (mManifest != null) {\n            // write the manifest to the jar file\n            mOutputJar.putNextEntry(new JarEntry(JarFile.MANIFEST_NAME));\n            mManifest.write(mOutputJar);\n\n            try {\n                // CERT.SF\n                Signature signature = Signature.getInstance(\"SHA1with\" + mKey.getAlgorithm());\n                signature.initSign(mKey);\n                if (StringUtils.isBlank(mSignFile)) {\n                    mOutputJar.putNextEntry(new JarEntry(\"META-INF/CERT.SF\"));\n                } else {\n                    mOutputJar.putNextEntry(new JarEntry(\"META-INF/\" + mSignFile + \".SF\"));\n                }\n\n                ByteArrayOutputStream baos = new ByteArrayOutputStream();\n                writeSignatureFile(baos);\n                byte[] signedData = baos.toByteArray();\n                mOutputJar.write(signedData);\n\n                if (StringUtils.isBlank(mSignFile)) {\n                    mOutputJar.putNextEntry(new JarEntry(\"META-INF/CERT.\" + mKey.getAlgorithm()));\n                } else {\n                    mOutputJar.putNextEntry(new JarEntry(\"META-INF/\" +\n                                                                 mSignFile +\n                                                                 \".\" +\n                                                                 mKey.getAlgorithm()));\n                }\n                // CERT.*\n                writeSignatureBlock(new CMSProcessableByteArray(signedData), mCertificate, mKey);\n            } catch (Exception e) {\n                throw new SigningException(e);\n            }\n        }\n\n        mOutputJar.close();\n        mOutputJar = null;\n    }\n\n    /**\n     * Clean up of the builder for interrupted workflow.\n     * This does nothing if {@link #close()} was called successfully.\n     */\n    public void cleanUp() {\n        if (mOutputJar != null) {\n            try {\n                mOutputJar.close();\n            } catch (IOException e) {\n                // pass\n            }\n        }\n    }\n\n    /**\n     * Adds an entry to the output jar, and write its content from the {@link InputStream}\n     *\n     * @param input The input stream from where to write the entry content.\n     * @param entry the entry to write in the jar.\n     * @throws IOException\n     */\n    private void writeEntry(InputStream input, JarEntry entry) throws IOException {\n        // add the entry to the jar archive\n        mOutputJar.putNextEntry(entry);\n\n        // read the content of the entry from the input stream, and write it into the archive.\n        int count;\n        while ((count = input.read(mBuffer)) != -1) {\n            mOutputJar.write(mBuffer, 0, count);\n\n            // update the digest\n            if (mMessageDigest != null) {\n                mMessageDigest.update(mBuffer, 0, count);\n            }\n        }\n\n        // close the entry for this file\n        mOutputJar.closeEntry();\n\n        if (mManifest != null) {\n            // update the manifest for this entry.\n            Attributes attr = mManifest.getAttributes(entry.getName());\n            if (attr == null) {\n                attr = new Attributes();\n                mManifest.getEntries().put(entry.getName(), attr);\n            }\n            attr.putValue(DIGEST_ATTR, new String(Base64.encode(mMessageDigest.digest()), \"ASCII\"));\n        }\n    }\n\n    /**\n     * Writes a .SF file with a digest to the manifest.\n     */\n    private void writeSignatureFile(OutputStream out) throws IOException, GeneralSecurityException {\n        Manifest sf = new Manifest();\n        Attributes main = sf.getMainAttributes();\n        main.putValue(\"Signature-Version\", \"1.0\");\n        main.putValue(\"Created-By\", \"1.0 (Android)\");\n\n        MessageDigest md = MessageDigest.getInstance(DIGEST_ALGORITHM);\n        PrintStream print = new PrintStream(new DigestOutputStream(new ByteArrayOutputStream(), md),\n                                            true,\n                                            SdkConstants.UTF_8);\n\n        // Digest of the entire manifest\n        mManifest.write(print);\n        print.flush();\n        main.putValue(DIGEST_MANIFEST_ATTR, new String(Base64.encode(md.digest()), \"ASCII\"));\n\n        Map<String, Attributes> entries = mManifest.getEntries();\n        for (Map.Entry<String, Attributes> entry : entries.entrySet()) {\n            // Digest of the manifest stanza for this entry.\n            print.print(\"Name: \" + entry.getKey() + \"\\r\\n\");\n            for (Map.Entry<Object, Object> att : entry.getValue().entrySet()) {\n                print.print(att.getKey() + \": \" + att.getValue() + \"\\r\\n\");\n            }\n            print.print(\"\\r\\n\");\n            print.flush();\n\n            Attributes sfAttr = new Attributes();\n            sfAttr.putValue(DIGEST_ATTR, new String(Base64.encode(md.digest()), \"ASCII\"));\n            sf.getEntries().put(entry.getKey(), sfAttr);\n        }\n        CountOutputStream cout = new CountOutputStream(out);\n        sf.write(cout);\n\n        // A bug in the java.util.jar implementation of Android platforms\n        // up to version 1.6 will cause a spurious IOException to be thrown\n        // if the length of the signature file is a multiple of 1024 bytes.\n        // As a workaround, add an extra CRLF in this case.\n        if ((cout.size() % 1024) == 0) {\n            cout.write('\\r');\n            cout.write('\\n');\n        }\n    }\n\n    /**\n     * Write the certificate file with a digital signature.\n     */\n    private void writeSignatureBlock(CMSTypedData data,\n                                     X509Certificate publicKey,\n                                     PrivateKey privateKey) throws IOException, CertificateEncodingException, OperatorCreationException, CMSException {\n\n        ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>();\n        certList.add(publicKey);\n        JcaCertStore certs = new JcaCertStore(certList);\n\n        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();\n        ContentSigner sha1Signer = new JcaContentSignerBuilder(\"SHA1with\" +\n                                                                       privateKey.getAlgorithm()).build(\n                privateKey);\n        gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder()\n                                                                             .build()).setDirectSignature(\n                true).build(sha1Signer, publicKey));\n        gen.addCertificates(certs);\n        CMSSignedData sigData = gen.generate(data, false);\n\n        ASN1InputStream asn1 = new ASN1InputStream(sigData.getEncoded());\n        DEROutputStream dos = new DEROutputStream(mOutputJar);\n        dos.writeObject(asn1.readObject());\n\n        dos.flush();\n        dos.close();\n        asn1.close();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/solib/NativeSoFilter.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\npackage com.taobao.android.builder.tools.solib;\n\nimport org.apache.commons.io.filefilter.IOFileFilter;\nimport org.apache.commons.lang.StringUtils;\n\nimport java.io.File;\nimport java.util.Set;\n\n/**\n * Class nativesofilter.java implementation description: TODO Class implementation description\n * @author shenghua.nish 2015July 16, 2007 On the afternoon of 3:52:39\n */\npublic class NativeSoFilter implements IOFileFilter {\n\n    private Set<String> supportAbis;\n    private Set<String> removeSoFiles;\n\n    public NativeSoFilter(Set<String> supportAbis,Set<String> removeSoFiles){\n        this.supportAbis = supportAbis;\n        this.removeSoFiles = removeSoFiles;\n    }\n\n    @Override\n    public boolean accept(File file) {\n\n        if (file.isDirectory()) {\n            return true;\n        } else {\n            String fileName = file.getName();\n            if(null != removeSoFiles  && removeSoFiles.size() > 0){\n                if(removeSoFiles.contains(fileName)){\n                    return false;\n                }\n            }\n\n            String path = file.getAbsolutePath();\n            boolean isSupportAbi = false;\n            if(null != supportAbis && supportAbis.size() > 0) {\n                for (String supportAbi : supportAbis) {\n                    String abi = File.separator + supportAbi + File.separator + fileName;\n                    if (path.indexOf(abi) > 0) {\n                        isSupportAbi = true;\n                        break;\n                    }\n                }\n            }else{\n                isSupportAbi=true;\n            }\n            if (isSupportAbi\n                && (StringUtils.endsWithIgnoreCase(fileName, \".so\") || \"gdbserver\".equalsIgnoreCase(fileName))) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    @Override\n    public boolean accept(File dir, String name) {\n        return accept(new File(dir, name));\n    }\n\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/solib/NativeSoUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\npackage com.taobao.android.builder.tools.solib;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport com.google.common.collect.HashMultimap;\nimport com.google.common.collect.Multimap;\nimport com.taobao.android.builder.tools.MD5Util;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.FilenameUtils;\nimport org.apache.commons.io.filefilter.IOFileFilter;\nimport org.apache.commons.io.filefilter.TrueFileFilter;\nimport org.apache.commons.lang.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * A tool class for the original so file\n *\n * @author shenghua.nish 2015July 16, 2007 On the afternoon of 3:19:41\n */\npublic class NativeSoUtils {\n\n    private static Logger sLogger = LoggerFactory.getLogger(NativeSoUtils.class);\n\n    /**\n     * Verify the directory of the so file under the abi\n     *\n     * @param supportAbis\n     * @param removeSoFiles\n     * @param dirs\n     * @return\n     */\n    public static Map<String, Multimap<String, File>> getAbiSoFiles(Set<String> supportAbis, Set<String> removeSoFiles,\n                                                                    List<File> dirs) {\n        Map<String, Multimap<String, File>> result = new HashMap<String, Multimap<String, File>>();\n        IOFileFilter filter = new NativeSoFilter(supportAbis, removeSoFiles);\n        for (File dir : dirs) {\n            Collection<File> files = FileUtils.listFiles(dir, filter, TrueFileFilter.TRUE);\n            for (File file : files) {\n                File parentFolder = file.getParentFile();\n                String parentName = parentFolder.getName();\n                String shortName = getSoShortName(file);\n                Multimap<String, File> maps = result.get(parentName);\n                if (null == maps) {\n                    maps = HashMultimap.create(10, 3);\n                }\n                maps.put(shortName, file);\n                result.put(parentName, maps);\n            }\n\n        }\n        return result;\n    }\n\n    /**\n     * Acquisition relative path\n     *\n     * @param baseDir\n     * @param file\n     * @return\n     */\n    public static String getRelativePath(File baseDir, File file) {\n        return StringUtils.remove(file.getAbsolutePath(), baseDir.getAbsolutePath());\n    }\n\n    /**\n     * Gets a short name after the removal version number of a so file\n     *\n     * @param soFile\n     * @return\n     */\n    public static String getSoShortName(File soFile) {\n        String baseName = FilenameUtils.getBaseName(soFile.getName());\n        String shortName = baseName.replaceAll(\"-(\\\\d*\\\\.\\\\d*)*\", \"\");\n        return shortName + \".\" + FilenameUtils.getExtension(soFile.getName());\n    }\n\n    /**\n     * @param localNativeLibrariesDirectory\n     * @param destinationDirectory\n     * @param supportAbis                   Type of architecture supported\n     * @param removeSoFiles\n     */\n    public static void copyLocalNativeLibraries(final File localNativeLibrariesDirectory,\n                                                final File destinationDirectory, Set<String> supportAbis,\n                                                Set<String> removeSoFiles) {\n        sLogger.info(\"Copying existing native libraries from \" + localNativeLibrariesDirectory + \" to \"\n                         + destinationDirectory);\n        try {\n            IOFileFilter filter = new NativeSoFilter(supportAbis, removeSoFiles);\n            // First, determine whether there is a file of the same name, if there is a discrepancy\n            Collection<File> files = FileUtils.listFiles(localNativeLibrariesDirectory, filter, TrueFileFilter.TRUE);\n            List<String> dumpFiles = new ArrayList<String>();\n            for (File file : files) {\n                String relativePath = getRelativePath(localNativeLibrariesDirectory, file);\n                File destFile = new File(destinationDirectory, relativePath);\n                if (destFile.exists()) {\n                    String orgFileMd5 = MD5Util.getFileMD5(file);\n                    String destFileMd5 = MD5Util.getFileMD5(destFile);\n                    if (!orgFileMd5.equals(destFileMd5)) {\n                        dumpFiles.add(file.getAbsolutePath() + \" to \" + destFile.getAbsolutePath());\n                    }\n                }\n            }\n            if (dumpFiles.size() > 0) {\n                throw new RuntimeException(\"Copy native so error,duplicate file exist!:\\n\"\n                                               + StringUtils.join(dumpFiles, \"\\n\"));\n            }\n            FileUtils.copyDirectory(localNativeLibrariesDirectory, destinationDirectory, filter);\n        } catch (IOException e) {\n            throw new RuntimeException(\"Could not copy native dependency.\", e);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/xml/XmlHelper.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.xml;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.List;\n\nimport org.apache.commons.io.IOUtils;\nimport org.dom4j.Document;\nimport org.dom4j.DocumentException;\nimport org.dom4j.Element;\nimport org.dom4j.Node;\nimport org.dom4j.io.OutputFormat;\nimport org.dom4j.io.SAXReader;\nimport org.dom4j.io.XMLWriter;\n\n/**\n * Created by wuzhong on 2017/4/13.\n */\npublic class XmlHelper {\n\n    public static Document readXml(File inputFile) throws DocumentException {\n\n        SAXReader reader = new SAXReader();\n\n        Document document = reader.read(inputFile);// Read the XML file\n\n        return document;\n    }\n\n    public static void saveDocument(Document document, File file) throws IOException {\n\n        file.getParentFile().mkdirs();\n\n        OutputFormat format = OutputFormat.createPrettyPrint();\n        format.setEncoding(\"UTF-8\");\n\n        saveFile(document, format, file);\n    }\n\n    public static void saveFile(Document document, OutputFormat format, File file) throws IOException {\n\n        XMLWriter writer = null;// Declares the object that writes XML\n        FileOutputStream fos = null;\n        try {\n            fos = new FileOutputStream(file);\n            writer = new XMLWriter(fos, format);\n            writer.write(document);\n        } finally {\n            if (null != writer) {\n                writer.close();\n            }\n            IOUtils.closeQuietly(fos);\n        }\n    }\n\n    public static void removeStringValue(File file, String key) throws IOException, DocumentException {\n\n        if (!file.exists()) {\n            return;\n        }\n\n        Document document = XmlHelper.readXml(file);// Read the XML file\n        Element root = document.getRootElement();// Get the root node\n        List<? extends Node> nodes = root.selectNodes(\"//string\");\n        for (Node node : nodes) {\n            Element element = (Element)node;\n            String name = element.attributeValue(\"name\");\n            if (key.equals(name)) {\n                element.getParent().remove(element);\n                break;\n            }\n        }\n        // sLogger.warn(\"[resxmlediter] add \" + key + \" to \" + file.getAbsolutePath());\n        XmlHelper.saveDocument(document, file);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/zip/BetterZip.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.zip;\n\nimport java.io.File;\nimport java.io.IOException;\n\nimport com.android.ide.common.process.CmdExecutor;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.FilenameUtils;\n\n/**\n * Created by wuzhong on 2017/2/15.\n */\npublic class BetterZip {\n\n    public static File extractFile(File zipFile, String path, File destDir) {\n\n        destDir.mkdirs();\n\n        new File(destDir, path).delete();\n\n        //unzip -j taobao-android-debug.apk  res/drawable/abc_wb_textfield_cdf.jpg -d .\n        boolean success = CmdExecutor.execute(\"\", \"unzip\", \"-o\", \"-j\", zipFile.getAbsolutePath(), path, \"-d\",\n                                              destDir.getAbsolutePath());\n\n        if (success) {\n            return new File(destDir, FilenameUtils.getName(path));\n        }\n\n        return ZipUtils.extractZipFileToFolder(zipFile, path, destDir);\n    }\n\n    public static boolean addFile(File zipFile, String path, File file) throws IOException {\n\n        if (file.isDirectory()) {\n            return false;\n        }\n\n        File rootDir = new File(file.getParentFile(), \"_tmp\");\n        rootDir.delete();\n\n        FileUtils.copyFile(file, new File(rootDir, path));\n\n        //zip -r taobao-android-debug.apk zzzz\n        boolean success = CmdExecutor.execute(rootDir.getAbsolutePath(), \"zip\", \"-r\", zipFile.getAbsolutePath(), path);\n\n        rootDir.delete();\n        if (success) {\n            return true;\n        }\n\n        File tmpFile = new File(zipFile.getParentFile(), zipFile.getName() + \"_tmp\");\n        ZipUtils.addFileToZipFile(zipFile, tmpFile, file, path, true);\n        zipFile.delete();\n        tmpFile.renameTo(zipFile);\n\n        return true;\n    }\n\n    public static boolean zipDirectory(File folder, File dest) throws IOException {\n\n        if (!folder.isDirectory()) {\n            return false;\n        }\n\n        //zip -r taobao-android-debug.apk zzzz\n        boolean success = CmdExecutor.execute(folder.getAbsolutePath(), \"zip\", \"-r\", dest.getAbsolutePath(), \".\");\n\n        if (success) {\n            return true;\n        }\n\n        dest.delete();\n\n        try {\n            ZipUtils.addFileAndDirectoryToZip(dest, folder);\n        } catch (Exception e) {\n            e.printStackTrace();\n            return false;\n        }\n\n        return true;\n    }\n\n    public static boolean unzipDirectory(File zipFile, File dest) throws IOException {\n\n        if (!zipFile.exists()) {\n            return false;\n        }\n\n        //zip -r taobao-android-debug.apk zzzz\n        boolean success = CmdExecutor.execute(dest.getAbsolutePath(), \"unzip\", \"-o\", zipFile.getAbsolutePath(), \"-d\",\n                                              dest.getAbsolutePath());\n\n        if (success) {\n            return true;\n        }\n\n        dest.delete();\n\n        try {\n            ZipUtils.unzip(zipFile, dest.getAbsolutePath());\n        } catch (Exception e) {\n            e.printStackTrace();\n            return false;\n        }\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/zip/FileMkUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\n//\n// Source code recreated from a .class file by IntelliJ IDEA\n// (powered by Fernflower decompiler)\n//\n\npackage com.taobao.android.builder.tools.zip;\n\nimport java.io.File;\n\npublic class FileMkUtils {\n    public FileMkUtils() {\n    }\n\n    public static void mkdirs(File folder) {\n        if(!folder.exists()) {\n            folder.mkdirs();\n        }\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/zip/ZipUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.zip;\n\n/**\n * Created by bisheng.dongbs on 16/6/24.\n */\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.Closeable;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.regex.Pattern;\nimport java.util.zip.CRC32;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\nimport java.util.zip.ZipOutputStream;\n\nimport org.apache.commons.compress.archivers.zip.ZipArchiveEntry;\nimport org.apache.commons.compress.archivers.zip.ZipFile;\nimport org.apache.commons.io.FilenameUtils;\nimport org.apache.commons.io.IOUtils;\nimport org.codehaus.plexus.util.StringUtils;\nimport org.gradle.api.GradleException;\n\nimport static java.util.zip.ZipEntry.STORED;\n\n/**\n * Press tools\n */\npublic class ZipUtils {\n\n    /**\n     * <p>\n     * unzip.\n     * </p>\n     *\n     * @param zipFile     a {@link java.io.File} object.\n     * @param destination a {@link String} object.\n     * @return a {@link java.util.List} object.\n     */\n    public static List<String> unzip(final File zipFile, final String destination) {\n        return unzip(zipFile, destination, null);\n    }\n\n    /**\n     * <p>\n     * unzip.\n     * </p>\n     *\n     * @param zipFile     a {@link java.io.File} object.\n     * @param destination a {@link String} object.\n     * @param encoding    a {@link String} object.\n     * @return a {@link java.util.List} object.\n     */\n    public static List<String> unzip(final File zipFile, final String destination, String encoding) {\n        List<String> fileNames = new ArrayList<String>();\n        String dest = destination;\n        if (!destination.endsWith(File.separator)) {\n            dest = destination + File.separator;\n        }\n        ZipFile file;\n        try {\n            file = null;\n            if (null == encoding) { file = new ZipFile(zipFile); } else { file = new ZipFile(zipFile, encoding); }\n            Enumeration<ZipArchiveEntry> en = file.getEntries();\n            ZipArchiveEntry ze = null;\n            while (en.hasMoreElements()) {\n                ze = en.nextElement();\n                File f = new File(dest, ze.getName());\n                if (ze.isDirectory()) {\n                    f.mkdirs();\n                    continue;\n                } else {\n                    f.getParentFile().mkdirs();\n                    InputStream is = file.getInputStream(ze);\n                    OutputStream os = new FileOutputStream(f);\n                    IOUtils.copy(is, os);\n                    is.close();\n                    os.close();\n                    fileNames.add(f.getAbsolutePath());\n                }\n            }\n            file.close();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        return fileNames;\n    }\n\n    public static List<String> extractZipFolderToFolder(final File zipFile, final String path, final String destination, String encoding) {\n        List<String> fileNames = new ArrayList<String>();\n        String dest = destination;\n        if (!destination.endsWith(File.separator)) {\n            dest = destination + File.separator;\n        }\n        ZipFile file;\n        try {\n            file = null;\n            if (null == encoding) {\n                file = new ZipFile(zipFile);\n            } else {\n                file = new ZipFile(zipFile, encoding);\n            }\n            Enumeration<ZipArchiveEntry> en = file.getEntries();\n            ZipArchiveEntry ze = null;\n            while (en.hasMoreElements()) {\n                ze = en.nextElement();\n                String name = ze.getName();\n                if (name.startsWith(path)) {\n                    File f = new File(dest, FilenameUtils.getName(name));\n\n                    if (ze.isDirectory()) {\n                        f.mkdirs();\n                        continue;\n                    } else {\n                        f.getParentFile().mkdirs();\n                        InputStream is = file.getInputStream(ze);\n                        OutputStream os = new FileOutputStream(f);\n                        IOUtils.copy(is, os);\n                        is.close();\n                        os.close();\n                        fileNames.add(f.getAbsolutePath());\n                    }\n                }\n            }\n            file.close();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        return fileNames;\n    }\n\n    /**\n     * <p>\n     * isZipFile.\n     * </p>\n     *\n     * @param zipFile a {@link java.io.File} object.\n     * @return a boolean.\n     */\n    public static boolean isZipFile(File zipFile) {\n        try {\n            ZipFile zf = new ZipFile(zipFile);\n            boolean isZip = zf.getEntries().hasMoreElements();\n            zf.close();\n            return isZip;\n        } catch (IOException e) {\n            return false;\n        }\n    }\n\n    private static String getFileName(File folder, File file) {\n        String name = StringUtils.replace(file.getAbsolutePath(), folder.getAbsolutePath() + \"/\", \"\");\n        return name;\n    }\n\n    public static List<String> listZipEntries(File zipFile) {\n        List<String> list = new ArrayList<String>();\n        ZipFile zip;\n        try {\n            zip = new ZipFile(zipFile);\n            Enumeration<ZipArchiveEntry> en = zip.getEntries();\n            ZipArchiveEntry ze = null;\n            while (en.hasMoreElements()) {\n                ze = en.nextElement();\n                String name = ze.getName();\n                name = StringUtils.replace(name, \"/\", \".\");\n                if (name.endsWith(\".class\")) {\n                    list.add(name);\n                }\n            }\n            if (null != zip) { ZipFile.closeQuietly(zip); }\n        } catch (IOException e) {\n        }\n        return list;\n    }\n\n    /**\n     * A file in a zip file to a specified location\n     *\n     * @param zipFile\n     * @param path\n     * @param destFolder\n     * @throws java.io.IOException\n     */\n    public static File extractZipFileToFolder(File zipFile, String path, File destFolder) {\n        ZipFile zip;\n        File destFile = null;\n        try {\n            zip = new ZipFile(zipFile);\n            ZipArchiveEntry zipArchiveEntry = zip.getEntry(path);\n            if (null != zipArchiveEntry) {\n                String name = zipArchiveEntry.getName();\n                name = FilenameUtils.getName(name);\n                destFile = new File(destFolder, name);\n                FileMkUtils.mkdirs(destFolder);\n                destFile.createNewFile();\n                InputStream is = zip.getInputStream(zipArchiveEntry);\n                FileOutputStream fos = new FileOutputStream(destFile);\n                int length = 0;\n                byte[] b = new byte[1024];\n                while ((length = is.read(b, 0, 1024)) != -1) {\n                    fos.write(b, 0, length);\n                }\n                is.close();\n                fos.close();\n            }\n            if (null != zip) { ZipFile.closeQuietly(zip); }\n        } catch (IOException e) {\n            throw new GradleException(e.getMessage(), e);\n        }\n        return destFile;\n    }\n\n    /**\n     * Add file to zip file\n     *\n     * @param zipFile\n     * @param file\n     * @param destPath\n     * @param overwrite No cover\n     * @throws java.io.IOException\n     */\n    public static void addFileToZipFile(File zipFile, File outZipFile, File file, String destPath, boolean overwrite)\n        throws IOException {\n        byte[] buf = new byte[1024];\n        ZipInputStream zin = new ZipInputStream(new FileInputStream(zipFile));\n        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outZipFile));\n        ZipEntry entry = zin.getNextEntry();\n        boolean addFile = true;\n        while (entry != null) {\n            boolean addEntry = true;\n            String name = entry.getName();\n            if (StringUtils.equalsIgnoreCase(name, destPath)) {\n                if (overwrite) {\n                    addEntry = false;\n                } else {\n                    addFile = false;\n                }\n            }\n            if (addEntry) {\n                ZipEntry zipEntry = null;\n                if (STORED == entry.getMethod()) {\n                    zipEntry = new ZipEntry(entry);\n                } else {\n                    zipEntry = new ZipEntry(name);\n                }\n                out.putNextEntry(zipEntry);\n                int len;\n                while ((len = zin.read(buf)) > 0) {\n                    out.write(buf, 0, len);\n                }\n            }\n            entry = zin.getNextEntry();\n        }\n\n        if (addFile) {\n            InputStream in = new FileInputStream(file);\n            // Add ZIP entry to output stream.\n            ZipEntry zipEntry = new ZipEntry(destPath);\n            out.putNextEntry(zipEntry);\n            // Transfer bytes from the file to the ZIP file\n            int len;\n            while ((len = in.read(buf)) > 0) {\n                out.write(buf, 0, len);\n            }\n            // Complete the entry\n            out.closeEntry();\n            in.close();\n        }\n        // Close the streams\n        zin.close();\n        out.close();\n    }\n\n    /**\n     * The piece is compressed into a zip package, which is mainly used by solib\n     *\n     * @param output\n     * @param srcDir\n     * @throws Exception\n     */\n    public static void addFileAndDirectoryToZip(File output, File srcDir) throws Exception {\n        if (output.isDirectory()) {\n            throw new IOException(\"This is a directory!\");\n        }\n        if (!output.getParentFile().exists()) {\n            output.getParentFile().mkdirs();\n        }\n\n        if (!output.exists()) {\n            output.createNewFile();\n        }\n        List fileList = getSubFiles(srcDir);\n        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(output));\n        ZipEntry ze = null;\n        byte[] buf = new byte[1024];\n        int readLen = 0;\n        for (int i = 0; i < fileList.size(); i++) {\n            File f = (File)fileList.get(i);\n            ze = new ZipEntry(getAbsFileName(srcDir.getPath(), f));\n            ze.setSize(f.length());\n            ze.setTime(f.lastModified());\n            zos.putNextEntry(ze);\n            InputStream is = new BufferedInputStream(new FileInputStream(f));\n            while ((readLen = is.read(buf, 0, 1024)) != -1) {\n                zos.write(buf, 0, readLen);\n            }\n            is.close();\n        }\n        zos.close();\n    }\n\n    private static String getAbsFileName(String baseDir, File realFileName) {\n        File real = realFileName;\n        File base = new File(baseDir);\n        String ret = real.getName();\n        while (true) {\n            real = real.getParentFile();\n            if (real == null) {\n                break;\n            }\n            if (real.equals(base)) {\n                break;\n            } else {\n                ret = real.getName() + \"/\" + ret;\n            }\n        }\n        return ret;\n    }\n\n    private static List getSubFiles(File baseDir) {\n        List ret = new ArrayList();\n        File[] tmp = baseDir.listFiles();\n        for (int i = 0; i < tmp.length; i++) {\n            if (tmp[i].isFile()) { ret.add(tmp[i]); }\n            if (tmp[i].isDirectory()) { ret.addAll(getSubFiles(tmp[i])); }\n        }\n        return ret;\n    }\n\n    /**\n     * Determines whether the specified folder exists in the specified zip directory\n     *\n     * @param zipFile\n     * @param pathName\n     * @return\n     */\n    public static boolean isFolderExist(File zipFile, String pathName) {\n\n        ZipFile file = null;\n        try {\n            file = new ZipFile(zipFile);\n            Enumeration<ZipArchiveEntry> en = file.getEntries();\n            while (en.hasMoreElements()) {\n                ZipArchiveEntry entry = en.nextElement();\n                String name = entry.getName();\n                if (name.startsWith(pathName)) {\n                    return true;\n                }\n\n            }\n            return false;\n        } catch (IOException e) {\n        } finally {\n            if (null != file) {\n                try {\n                    file.close();\n                } catch (IOException e) {\n\n                }\n            }\n\n        }\n        return false;\n    }\n\n    public static boolean removeZipEntry(File file, Pattern pattern, File targetFile)\n        throws FileNotFoundException, IOException {\n        byte[] buffer = new byte[1024];\n        java.util.zip.ZipFile zipFile = new java.util.zip.ZipFile(file);\n        ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(targetFile)));\n        BufferedOutputStream bo = new BufferedOutputStream(out);\n        InputStream inputStream;\n        Enumeration enumeration = zipFile.entries();\n        while (enumeration.hasMoreElements()) {\n            ZipEntry zipEntry = (ZipEntry)enumeration.nextElement();\n            String name = zipEntry.getName();\n            if (pattern.matcher(name).find()) {\n                continue;\n            }\n            out.putNextEntry(zipEntry);\n            inputStream = zipFile.getInputStream(zipEntry);\n            write(inputStream, out, buffer);\n            bo.flush();\n\n        }\n\n        closeQuitely(zipFile);\n        closeQuitely(out);\n        closeQuitely(bo);\n\n        return true;\n    }\n\n    private static void write(InputStream inputStream, ZipOutputStream out, byte[] buffer) throws IOException {\n        int length = inputStream.read(buffer);\n        while (length != -1) {\n            out.write(buffer, 0, length);\n            length = inputStream.read(buffer);\n        }\n        closeQuitely(inputStream);\n    }\n\n    private static void closeQuitely(Closeable closeable) throws IOException {\n        if (closeable != null) {\n            closeable.close();\n        }\n    }\n\n    public static List<String> unzip(final File zipFile, final String destination, String encoding,\n                                     Map<String, ZipEntry> zipEntryMethodMap) {\n        return unzip(zipFile, destination, encoding, zipEntryMethodMap, false);\n    }\n\n    public static List<String> unzip(final File zipFile, final String destination, String encoding,\n                                     Map<String, ZipEntry> zipEntryMethodMap, boolean isRelativePath) {\n        List<String> fileNames = new ArrayList<String>();\n        String dest = destination;\n        if (!destination.endsWith(File.separator)) {\n            dest = destination + File.separator;\n        }\n        ZipFile file;\n        try {\n            file = null;\n            if (null == encoding) { file = new ZipFile(zipFile); } else { file = new ZipFile(zipFile, encoding); }\n            Enumeration<ZipArchiveEntry> en = file.getEntries();\n            ZipArchiveEntry ze = null;\n            while (en.hasMoreElements()) {\n                ze = en.nextElement();\n                File f = new File(dest, ze.getName());\n                if (ze.isDirectory()) {\n                    f.mkdirs();\n                    continue;\n                } else {\n                    f.getParentFile().mkdirs();\n                    InputStream is = file.getInputStream(ze);\n                    OutputStream os = new FileOutputStream(f);\n                    IOUtils.copy(is, os);\n                    is.close();\n                    os.close();\n                    fileNames.add(f.getAbsolutePath());\n                    if (zipEntryMethodMap != null && ze.getMethod() == STORED) {\n                        zipEntryMethodMap.put(isRelativePath ? ze.getName() : f.getAbsolutePath(), ze);\n                    }\n                }\n            }\n            file.close();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        return fileNames;\n    }\n\n    public static void addFileAndDirectoryToZip(File output, File srcDir, Map<String, ZipEntry> zipEntryMethodMap)\n        throws Exception {\n        if (output.isDirectory()) {\n            throw new IOException(\"This is a directory!\");\n        }\n        if (!output.getParentFile().exists()) {\n            output.getParentFile().mkdirs();\n        }\n\n        if (!output.exists()) {\n            output.createNewFile();\n        }\n        List fileList = getSubFiles(srcDir);\n        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(output));\n        ZipEntry ze = null;\n        byte[] buf = new byte[1024];\n        int readLen = 0;\n        for (int i = 0; i < fileList.size(); i++) {\n            File f = (File)fileList.get(i);\n            ze = new ZipEntry(getAbsFileName(srcDir.getPath(), f));\n            ze.setSize(f.length());\n            ze.setTime(f.lastModified());\n            if (zipEntryMethodMap != null) {\n                ZipEntry originEntry = zipEntryMethodMap.get(f.getAbsolutePath());\n                if (originEntry != null) {\n                    ze.setCompressedSize(originEntry.getCompressedSize());\n                    ze.setCrc(originEntry.getCrc());\n                    ze.setMethod(originEntry.getMethod());\n                }\n            }\n            zos.putNextEntry(ze);\n            InputStream is = new BufferedInputStream(new FileInputStream(f));\n            while ((readLen = is.read(buf, 0, 1024)) != -1) {\n                zos.write(buf, 0, readLen);\n            }\n            is.close();\n        }\n        zos.close();\n    }\n\n    public static void rezip(File output, File srcDir, Map<String, ZipEntry> zipEntryMethodMap) throws Exception {\n        if (output.isDirectory()) {\n            throw new IOException(\"This is a directory!\");\n        }\n        if (!output.getParentFile().exists()) {\n            output.getParentFile().mkdirs();\n        }\n\n        if (!output.exists()) {\n            output.createNewFile();\n        }\n        List fileList = getSubFiles(srcDir);\n        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(output));\n        ZipEntry ze = null;\n        byte[] buf = new byte[1024];\n        int readLen = 0;\n        for (int i = 0; i < fileList.size(); i++) {\n            File f = (File)fileList.get(i);\n            ze = new ZipEntry(getAbsFileName(srcDir.getPath(), f));\n            ze.setSize(f.length());\n            ze.setTime(f.lastModified());\n            if (zipEntryMethodMap != null) {\n                ZipEntry originEntry = zipEntryMethodMap.get(ze.getName());\n                if (originEntry != null) {\n                    if (originEntry.getMethod() == STORED) {\n                        ze.setCompressedSize(f.length());\n                        InputStream in = new BufferedInputStream(new FileInputStream(f));\n                        try {\n                            CRC32 crc = new CRC32();\n                            int c;\n                            while ((c = in.read()) != -1) {\n                                crc.update(c);\n                            }\n                            ze.setCrc(crc.getValue());\n                        } finally {\n                            in.close();\n                        }\n                    }\n                    ze.setMethod(originEntry.getMethod());\n                }\n            }\n            zos.putNextEntry(ze);\n            InputStream is = new BufferedInputStream(new FileInputStream(f));\n            while ((readLen = is.read(buf, 0, 1024)) != -1) {\n                zos.write(buf, 0, readLen);\n            }\n            is.close();\n        }\n        zos.close();\n    }\n\n    public static void main(String[] args) {\n        String name = \"T.class\";\n        System.out.println(name.substring(0, name.length() - 6));\n    }\n\n}\n\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/com/taobao/android/builder/tools/zipalign/ZipAlignUtils.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.android.builder.tools.zipalign;\n\nimport com.android.builder.core.AndroidBuilder;\nimport org.gradle.api.Action;\nimport org.gradle.api.Project;\nimport org.gradle.process.ExecSpec;\n\nimport java.io.File;\n\nimport static com.android.sdklib.BuildToolInfo.PathId.ZIP_ALIGN;\n\n/**\n * Created by wuzhong on 2016/12/7.\n */\npublic class ZipAlignUtils {\n\n    public static synchronized File doZipAlign(final AndroidBuilder androidBuilder, Project project, final File apkFile) {\n\n        final File zipalignedFile = new File(apkFile.getParent(), apkFile.getName().replace(\".apk\", \"-zipaligned.apk\"));\n\n        project.exec(new Action<ExecSpec>() {\n            @Override\n            public void execute(ExecSpec execSpec) {\n\n                String path = androidBuilder.getTargetInfo()\n                        .getBuildTools().getPath(ZIP_ALIGN);\n                execSpec.executable(new File(path));\n                execSpec.args(\"-f\", \"4\");\n                execSpec.args(apkFile);\n                execSpec.args(zipalignedFile);\n            }\n        });\n\n        return zipalignedFile;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/proguard/AtlasProguardConstants.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage proguard;\n\n/**\n * Created by wuzhong on 2017/5/13.\n */\npublic class AtlasProguardConstants extends ConfigurationConstants {\n\n    public static final String INOUT_CFG = \"inout_config.cfg\";\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/java/proguard/io/JarWriter.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\npackage proguard.io;\n\nimport proguard.classfile.ClassConstants;\n\nimport java.io.*;\nimport java.util.*;\nimport java.util.jar.*;\nimport java.util.zip.*;\n\n/**\n * This DataEntryWriter sends data entries to a given jar/zip file.\n * The manifest and comment properties can optionally be set.\n *\n * @author Eric Lafortune\n */\npublic class JarWriter implements DataEntryWriter, Finisher\n{\n    private final DataEntryWriter dataEntryWriter;\n    private final Manifest        manifest;\n    private final String          comment;\n\n    private OutputStream    currentParentOutputStream;\n    private ZipOutputStream currentJarOutputStream;\n    private Finisher        currentFinisher;\n    private DataEntry       currentDataEntry;\n\n    // The names of the jar entries that are already in the jar.\n    private final Set jarEntryNames = new HashSet();\n\n\n    /**\n     * Creates a new JarWriter without manifest or comment.\n     */\n    public JarWriter(DataEntryWriter dataEntryWriter)\n    {\n        this(dataEntryWriter, null, null);\n    }\n\n\n    /**\n     * Creates a new JarWriter.\n     */\n    public JarWriter(DataEntryWriter dataEntryWriter,\n                     Manifest        manifest,\n                     String          comment)\n    {\n        this.dataEntryWriter = dataEntryWriter;\n        this.manifest        = manifest;\n        this.comment         = comment;\n    }\n\n\n    // Implementations for DataEntryWriter.\n\n    public boolean createDirectory(DataEntry dataEntry) throws IOException\n    {\n        // Make sure we can start with a new entry.\n        if (!prepareEntry(dataEntry))\n        {\n            return false;\n        }\n\n        // Close the previous ZIP entry, if any.\n        closeEntry();\n\n        // Get the directory entry name.\n        String name = dataEntry.getName() + ClassConstants.PACKAGE_SEPARATOR;\n\n        // We have to check if the name is already used, because\n        // ZipOutputStream doesn't handle this case properly (it throws\n        // an exception which can be caught, but the ZipDataEntry is\n        // remembered anyway).\n        if (jarEntryNames.add(name))\n        {\n            // Create a new directory entry.\n            currentJarOutputStream.putNextEntry(new ZipEntry(name));\n            currentJarOutputStream.closeEntry();\n        }\n\n        // Clear the finisher.\n        currentFinisher  = null;\n        currentDataEntry = null;\n\n        return true;\n    }\n\n\n    public OutputStream getOutputStream(DataEntry dataEntry) throws IOException\n    {\n        return getOutputStream(dataEntry,  null);\n    }\n\n\n    public OutputStream getOutputStream(DataEntry dataEntry,\n                                        Finisher  finisher) throws IOException\n    {\n        //Make sure we can start with a new entry.\n        if (!prepareEntry(dataEntry))\n        {\n            return null;\n        }\n\n        // Do we need a new entry?\n        if (!dataEntry.equals(currentDataEntry))\n        {\n            // Close the previous ZIP entry, if any.\n            closeEntry();\n\n            // Get the entry name.\n            String name = dataEntry.getName();\n\n            // We have to check if the name is already used, because\n            // ZipOutputStream doesn't handle this case properly (it throws\n            // an exception which can be caught, but the ZipDataEntry is\n            // remembered anyway).\n            if (!jarEntryNames.add(name))\n            {\n                throw new IOException(\"Duplicate zip entry [\"+dataEntry+\"]\");\n            }\n\n            // Create a new entry.\n            ZipEntry zipEntry = new ZipEntry(name);\n            zipEntry.setTime(0);\n            currentJarOutputStream.putNextEntry(zipEntry);\n\n            // Set up the finisher for the entry.\n            currentFinisher  = finisher;\n            currentDataEntry = dataEntry;\n        }\n\n        return currentJarOutputStream;\n    }\n\n\n    public void finish() throws IOException\n    {\n        // Finish the entire ZIP stream, if any.\n        if (currentJarOutputStream != null)\n        {\n            // Close the previous ZIP entry, if any.\n            closeEntry();\n\n            // Finish the entire ZIP stream.\n            currentJarOutputStream.finish();\n            currentJarOutputStream    = null;\n            currentParentOutputStream = null;\n            jarEntryNames.clear();\n        }\n    }\n\n\n    public void close() throws IOException\n    {\n        // Close the parent stream.\n        dataEntryWriter.close();\n    }\n\n\n    // Small utility methods.\n\n    /**\n     * Makes sure the current output stream is set up for the given entry.\n     */\n    private boolean prepareEntry(DataEntry dataEntry) throws IOException\n    {\n        // Get the parent stream, new or existing.\n        // This may finish our own jar output stream.\n        OutputStream parentOutputStream =\n            dataEntryWriter.getOutputStream(dataEntry.getParent(), this);\n\n        // Did we get a stream?\n        if (parentOutputStream == null)\n        {\n            return false;\n        }\n\n        // Do we need a new stream?\n        if (currentParentOutputStream == null)\n        {\n            currentParentOutputStream = parentOutputStream;\n\n            // Create a new jar stream, with a manifest, if set.\n            currentJarOutputStream = manifest != null ?\n                new JarOutputStream(parentOutputStream, manifest) :\n                new ZipOutputStream(parentOutputStream);\n\n            // Add a comment, if set.\n            if (comment != null)\n            {\n                currentJarOutputStream.setComment(comment);\n            }\n        }\n\n        return true;\n    }\n\n\n    /**\n     * Closes the previous ZIP entry, if any.\n     */\n    private void closeEntry() throws IOException\n    {\n        if (currentDataEntry != null)\n        {\n            // Let any finisher finish up first.\n            if (currentFinisher != null)\n            {\n                currentFinisher.finish();\n                currentFinisher = null;\n            }\n\n            currentJarOutputStream.closeEntry();\n            currentDataEntry = null;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/resources/META-INF/gradle-plugins/com.taobao.atlas.application.properties",
    "content": "#\n#\n#\n#\n#                                   Apache License\n#                             Version 2.0, January 2004\n#                          http://www.apache.org/licenses/\n#\n#     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n#\n#     1. Definitions.\n#\n#        \"License\" shall mean the terms and conditions for use, reproduction,\n#        and distribution as defined by Sections 1 through 9 of this document.\n#\n#        \"Licensor\" shall mean the copyright owner or entity authorized by\n#        the copyright owner that is granting the License.\n#\n#        \"Legal Entity\" shall mean the union of the acting entity and all\n#        other entities that control, are controlled by, or are under common\n#        control with that entity. For the purposes of this definition,\n#        \"control\" means (i) the power, direct or indirect, to cause the\n#        direction or management of such entity, whether by contract or\n#        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n#        outstanding shares, or (iii) beneficial ownership of such entity.\n#\n#        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n#        exercising permissions granted by this License.\n#\n#        \"Source\" form shall mean the preferred form for making modifications,\n#        including but not limited to software source code, documentation\n#        source, and configuration files.\n#\n#        \"Object\" form shall mean any form resulting from mechanical\n#        transformation or translation of a Source form, including but\n#        not limited to compiled object code, generated documentation,\n#        and conversions to other media types.\n#\n#        \"Work\" shall mean the work of authorship, whether in Source or\n#        Object form, made available under the License, as indicated by a\n#        copyright notice that is included in or attached to the work\n#        (an example is provided in the Appendix below).\n#\n#        \"Derivative Works\" shall mean any work, whether in Source or Object\n#        form, that is based on (or derived from) the Work and for which the\n#        editorial revisions, annotations, elaborations, or other modifications\n#        represent, as a whole, an original work of authorship. For the purposes\n#        of this License, Derivative Works shall not include works that remain\n#        separable from, or merely link (or bind by name) to the interfaces of,\n#        the Work and Derivative Works thereof.\n#\n#        \"Contribution\" shall mean any work of authorship, including\n#        the original version of the Work and any modifications or additions\n#        to that Work or Derivative Works thereof, that is intentionally\n#        submitted to Licensor for inclusion in the Work by the copyright owner\n#        or by an individual or Legal Entity authorized to submit on behalf of\n#        the copyright owner. For the purposes of this definition, \"submitted\"\n#        means any form of electronic, verbal, or written communication sent\n#        to the Licensor or its representatives, including but not limited to\n#        communication on electronic mailing lists, source code control systems,\n#        and issue tracking systems that are managed by, or on behalf of, the\n#        Licensor for the purpose of discussing and improving the Work, but\n#        excluding communication that is conspicuously marked or otherwise\n#        designated in writing by the copyright owner as \"Not a Contribution.\"\n#\n#        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n#        on behalf of whom a Contribution has been received by Licensor and\n#        subsequently incorporated within the Work.\n#\n#     2. Grant of Copyright License. Subject to the terms and conditions of\n#        this License, each Contributor hereby grants to You a perpetual,\n#        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n#        copyright license to reproduce, prepare Derivative Works of,\n#        publicly display, publicly perform, sublicense, and distribute the\n#        Work and such Derivative Works in Source or Object form.\n#\n#     3. Grant of Patent License. Subject to the terms and conditions of\n#        this License, each Contributor hereby grants to You a perpetual,\n#        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n#        (except as stated in this section) patent license to make, have made,\n#        use, offer to sell, sell, import, and otherwise transfer the Work,\n#        where such license applies only to those patent claims licensable\n#        by such Contributor that are necessarily infringed by their\n#        Contribution(s) alone or by combination of their Contribution(s)\n#        with the Work to which such Contribution(s) was submitted. If You\n#        institute patent litigation against any entity (including a\n#        cross-claim or counterclaim in a lawsuit) alleging that the Work\n#        or a Contribution incorporated within the Work constitutes direct\n#        or contributory patent infringement, then any patent licenses\n#        granted to You under this License for that Work shall terminate\n#        as of the date such litigation is filed.\n#\n#     4. Redistribution. You may reproduce and distribute copies of the\n#        Work or Derivative Works thereof in any medium, with or without\n#        modifications, and in Source or Object form, provided that You\n#        meet the following conditions:\n#\n#        (a) You must give any other recipients of the Work or\n#            Derivative Works a copy of this License; and\n#\n#        (b) You must cause any modified files to carry prominent notices\n#            stating that You changed the files; and\n#\n#        (c) You must retain, in the Source form of any Derivative Works\n#            that You distribute, all copyright, patent, trademark, and\n#            attribution notices from the Source form of the Work,\n#            excluding those notices that do not pertain to any part of\n#            the Derivative Works; and\n#\n#        (d) If the Work includes a \"NOTICE\" text file as part of its\n#            distribution, then any Derivative Works that You distribute must\n#            include a readable copy of the attribution notices contained\n#            within such NOTICE file, excluding those notices that do not\n#            pertain to any part of the Derivative Works, in at least one\n#            of the following places: within a NOTICE text file distributed\n#            as part of the Derivative Works; within the Source form or\n#            documentation, if provided along with the Derivative Works; or,\n#            within a display generated by the Derivative Works, if and\n#            wherever such third-party notices normally appear. The contents\n#            of the NOTICE file are for informational purposes only and\n#            do not modify the License. You may add Your own attribution\n#            notices within Derivative Works that You distribute, alongside\n#            or as an addendum to the NOTICE text from the Work, provided\n#            that such additional attribution notices cannot be construed\n#            as modifying the License.\n#\n#        You may add Your own copyright statement to Your modifications and\n#        may provide additional or different license terms and conditions\n#        for use, reproduction, or distribution of Your modifications, or\n#        for any such Derivative Works as a whole, provided Your use,\n#        reproduction, and distribution of the Work otherwise complies with\n#        the conditions stated in this License.\n#\n#     5. Submission of Contributions. Unless You explicitly state otherwise,\n#        any Contribution intentionally submitted for inclusion in the Work\n#        by You to the Licensor shall be under the terms and conditions of\n#        this License, without any additional terms or conditions.\n#        Notwithstanding the above, nothing herein shall supersede or modify\n#        the terms of any separate license agreement you may have executed\n#        with Licensor regarding such Contributions.\n#\n#     6. Trademarks. This License does not grant permission to use the trade\n#        names, trademarks, service marks, or product names of the Licensor,\n#        except as required for reasonable and customary use in describing the\n#        origin of the Work and reproducing the content of the NOTICE file.\n#\n#     7. Disclaimer of Warranty. Unless required by applicable law or\n#        agreed to in writing, Licensor provides the Work (and each\n#        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n#        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n#        implied, including, without limitation, any warranties or conditions\n#        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n#        PARTICULAR PURPOSE. You are solely responsible for determining the\n#        appropriateness of using or redistributing the Work and assume any\n#        risks associated with Your exercise of permissions under this License.\n#\n#     8. Limitation of Liability. In no event and under no legal theory,\n#        whether in tort (including negligence), contract, or otherwise,\n#        unless required by applicable law (such as deliberate and grossly\n#        negligent acts) or agreed to in writing, shall any Contributor be\n#        liable to You for damages, including any direct, indirect, special,\n#        incidental, or consequential damages of any character arising as a\n#        result of this License or out of the use or inability to use the\n#        Work (including but not limited to damages for loss of goodwill,\n#        work stoppage, computer failure or malfunction, or any and all\n#        other commercial damages or losses), even if such Contributor\n#        has been advised of the possibility of such damages.\n#\n#     9. Accepting Warranty or Additional Liability. While redistributing\n#        the Work or Derivative Works thereof, You may choose to offer,\n#        and charge a fee for, acceptance of support, warranty, indemnity,\n#        or other liability obligations and/or rights consistent with this\n#        License. However, in accepting such obligations, You may act only\n#        on Your own behalf and on Your sole responsibility, not on behalf\n#        of any other Contributor, and only if You agree to indemnify,\n#        defend, and hold each Contributor harmless for any liability\n#        incurred by, or claims asserted against, such Contributor by reason\n#        of your accepting any such warranty or additional liability.\n#\n#     END OF TERMS AND CONDITIONS\n#\n#     APPENDIX: How to apply the Apache License to your work.\n#\n#        To apply the Apache License to your work, attach the following\n#        boilerplate notice, with the fields enclosed by brackets \"[]\"\n#        replaced with your own identifying information. (Don't include\n#        the brackets!)  The text should be enclosed in the appropriate\n#        comment syntax for the file format. We also recommend that a\n#        file or class name and description of purpose be included on the\n#        same \"printed page\" as the copyright notice for easier\n#        identification within third-party archives.\n#\n#     Copyright 2016 Alibaba Group\n#\n#     Licensed under the Apache License, Version 2.0 (the \"License\");\n#     you may not use this file except in compliance with the License.\n#     You may obtain a copy of the License at\n#\n#         http://www.apache.org/licenses/LICENSE-2.0\n#\n#     Unless required by applicable law or agreed to in writing, software\n#     distributed under the License is distributed on an \"AS IS\" BASIS,\n#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n#     See the License for the specific language governing permissions and\n#     limitations under the License.\n#\n#\n#\n\nimplementation-class=com.taobao.android.builder.AtlasAppPlugin"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/resources/META-INF/gradle-plugins/com.taobao.atlas.dexpatch.properties",
    "content": "implementation-class=com.taobao.android.builder.AtlasDexPatchPlugin"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/resources/META-INF/gradle-plugins/com.taobao.atlas.feature.properties",
    "content": "implementation-class=com.taobao.android.builder.AtlasFeaturePlugin"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/resources/META-INF/gradle-plugins/com.taobao.atlas.instantapp.properties",
    "content": "implementation-class=com.taobao.android.builder.AtlasDexPatchPlugin"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/resources/META-INF/gradle-plugins/com.taobao.atlas.library.properties",
    "content": "#\n#\n#\n#\n#                                   Apache License\n#                             Version 2.0, January 2004\n#                          http://www.apache.org/licenses/\n#\n#     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n#\n#     1. Definitions.\n#\n#        \"License\" shall mean the terms and conditions for use, reproduction,\n#        and distribution as defined by Sections 1 through 9 of this document.\n#\n#        \"Licensor\" shall mean the copyright owner or entity authorized by\n#        the copyright owner that is granting the License.\n#\n#        \"Legal Entity\" shall mean the union of the acting entity and all\n#        other entities that control, are controlled by, or are under common\n#        control with that entity. For the purposes of this definition,\n#        \"control\" means (i) the power, direct or indirect, to cause the\n#        direction or management of such entity, whether by contract or\n#        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n#        outstanding shares, or (iii) beneficial ownership of such entity.\n#\n#        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n#        exercising permissions granted by this License.\n#\n#        \"Source\" form shall mean the preferred form for making modifications,\n#        including but not limited to software source code, documentation\n#        source, and configuration files.\n#\n#        \"Object\" form shall mean any form resulting from mechanical\n#        transformation or translation of a Source form, including but\n#        not limited to compiled object code, generated documentation,\n#        and conversions to other media types.\n#\n#        \"Work\" shall mean the work of authorship, whether in Source or\n#        Object form, made available under the License, as indicated by a\n#        copyright notice that is included in or attached to the work\n#        (an example is provided in the Appendix below).\n#\n#        \"Derivative Works\" shall mean any work, whether in Source or Object\n#        form, that is based on (or derived from) the Work and for which the\n#        editorial revisions, annotations, elaborations, or other modifications\n#        represent, as a whole, an original work of authorship. For the purposes\n#        of this License, Derivative Works shall not include works that remain\n#        separable from, or merely link (or bind by name) to the interfaces of,\n#        the Work and Derivative Works thereof.\n#\n#        \"Contribution\" shall mean any work of authorship, including\n#        the original version of the Work and any modifications or additions\n#        to that Work or Derivative Works thereof, that is intentionally\n#        submitted to Licensor for inclusion in the Work by the copyright owner\n#        or by an individual or Legal Entity authorized to submit on behalf of\n#        the copyright owner. For the purposes of this definition, \"submitted\"\n#        means any form of electronic, verbal, or written communication sent\n#        to the Licensor or its representatives, including but not limited to\n#        communication on electronic mailing lists, source code control systems,\n#        and issue tracking systems that are managed by, or on behalf of, the\n#        Licensor for the purpose of discussing and improving the Work, but\n#        excluding communication that is conspicuously marked or otherwise\n#        designated in writing by the copyright owner as \"Not a Contribution.\"\n#\n#        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n#        on behalf of whom a Contribution has been received by Licensor and\n#        subsequently incorporated within the Work.\n#\n#     2. Grant of Copyright License. Subject to the terms and conditions of\n#        this License, each Contributor hereby grants to You a perpetual,\n#        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n#        copyright license to reproduce, prepare Derivative Works of,\n#        publicly display, publicly perform, sublicense, and distribute the\n#        Work and such Derivative Works in Source or Object form.\n#\n#     3. Grant of Patent License. Subject to the terms and conditions of\n#        this License, each Contributor hereby grants to You a perpetual,\n#        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n#        (except as stated in this section) patent license to make, have made,\n#        use, offer to sell, sell, import, and otherwise transfer the Work,\n#        where such license applies only to those patent claims licensable\n#        by such Contributor that are necessarily infringed by their\n#        Contribution(s) alone or by combination of their Contribution(s)\n#        with the Work to which such Contribution(s) was submitted. If You\n#        institute patent litigation against any entity (including a\n#        cross-claim or counterclaim in a lawsuit) alleging that the Work\n#        or a Contribution incorporated within the Work constitutes direct\n#        or contributory patent infringement, then any patent licenses\n#        granted to You under this License for that Work shall terminate\n#        as of the date such litigation is filed.\n#\n#     4. Redistribution. You may reproduce and distribute copies of the\n#        Work or Derivative Works thereof in any medium, with or without\n#        modifications, and in Source or Object form, provided that You\n#        meet the following conditions:\n#\n#        (a) You must give any other recipients of the Work or\n#            Derivative Works a copy of this License; and\n#\n#        (b) You must cause any modified files to carry prominent notices\n#            stating that You changed the files; and\n#\n#        (c) You must retain, in the Source form of any Derivative Works\n#            that You distribute, all copyright, patent, trademark, and\n#            attribution notices from the Source form of the Work,\n#            excluding those notices that do not pertain to any part of\n#            the Derivative Works; and\n#\n#        (d) If the Work includes a \"NOTICE\" text file as part of its\n#            distribution, then any Derivative Works that You distribute must\n#            include a readable copy of the attribution notices contained\n#            within such NOTICE file, excluding those notices that do not\n#            pertain to any part of the Derivative Works, in at least one\n#            of the following places: within a NOTICE text file distributed\n#            as part of the Derivative Works; within the Source form or\n#            documentation, if provided along with the Derivative Works; or,\n#            within a display generated by the Derivative Works, if and\n#            wherever such third-party notices normally appear. The contents\n#            of the NOTICE file are for informational purposes only and\n#            do not modify the License. You may add Your own attribution\n#            notices within Derivative Works that You distribute, alongside\n#            or as an addendum to the NOTICE text from the Work, provided\n#            that such additional attribution notices cannot be construed\n#            as modifying the License.\n#\n#        You may add Your own copyright statement to Your modifications and\n#        may provide additional or different license terms and conditions\n#        for use, reproduction, or distribution of Your modifications, or\n#        for any such Derivative Works as a whole, provided Your use,\n#        reproduction, and distribution of the Work otherwise complies with\n#        the conditions stated in this License.\n#\n#     5. Submission of Contributions. Unless You explicitly state otherwise,\n#        any Contribution intentionally submitted for inclusion in the Work\n#        by You to the Licensor shall be under the terms and conditions of\n#        this License, without any additional terms or conditions.\n#        Notwithstanding the above, nothing herein shall supersede or modify\n#        the terms of any separate license agreement you may have executed\n#        with Licensor regarding such Contributions.\n#\n#     6. Trademarks. This License does not grant permission to use the trade\n#        names, trademarks, service marks, or product names of the Licensor,\n#        except as required for reasonable and customary use in describing the\n#        origin of the Work and reproducing the content of the NOTICE file.\n#\n#     7. Disclaimer of Warranty. Unless required by applicable law or\n#        agreed to in writing, Licensor provides the Work (and each\n#        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n#        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n#        implied, including, without limitation, any warranties or conditions\n#        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n#        PARTICULAR PURPOSE. You are solely responsible for determining the\n#        appropriateness of using or redistributing the Work and assume any\n#        risks associated with Your exercise of permissions under this License.\n#\n#     8. Limitation of Liability. In no event and under no legal theory,\n#        whether in tort (including negligence), contract, or otherwise,\n#        unless required by applicable law (such as deliberate and grossly\n#        negligent acts) or agreed to in writing, shall any Contributor be\n#        liable to You for damages, including any direct, indirect, special,\n#        incidental, or consequential damages of any character arising as a\n#        result of this License or out of the use or inability to use the\n#        Work (including but not limited to damages for loss of goodwill,\n#        work stoppage, computer failure or malfunction, or any and all\n#        other commercial damages or losses), even if such Contributor\n#        has been advised of the possibility of such damages.\n#\n#     9. Accepting Warranty or Additional Liability. While redistributing\n#        the Work or Derivative Works thereof, You may choose to offer,\n#        and charge a fee for, acceptance of support, warranty, indemnity,\n#        or other liability obligations and/or rights consistent with this\n#        License. However, in accepting such obligations, You may act only\n#        on Your own behalf and on Your sole responsibility, not on behalf\n#        of any other Contributor, and only if You agree to indemnify,\n#        defend, and hold each Contributor harmless for any liability\n#        incurred by, or claims asserted against, such Contributor by reason\n#        of your accepting any such warranty or additional liability.\n#\n#     END OF TERMS AND CONDITIONS\n#\n#     APPENDIX: How to apply the Apache License to your work.\n#\n#        To apply the Apache License to your work, attach the following\n#        boilerplate notice, with the fields enclosed by brackets \"[]\"\n#        replaced with your own identifying information. (Don't include\n#        the brackets!)  The text should be enclosed in the appropriate\n#        comment syntax for the file format. We also recommend that a\n#        file or class name and description of purpose be included on the\n#        same \"printed page\" as the copyright notice for easier\n#        identification within third-party archives.\n#\n#     Copyright 2016 Alibaba Group\n#\n#     Licensed under the Apache License, Version 2.0 (the \"License\");\n#     you may not use this file except in compliance with the License.\n#     You may obtain a copy of the License at\n#\n#         http://www.apache.org/licenses/LICENSE-2.0\n#\n#     Unless required by applicable law or agreed to in writing, software\n#     distributed under the License is distributed on an \"AS IS\" BASIS,\n#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n#     See the License for the specific language governing permissions and\n#     limitations under the License.\n#\n#\n#\n\nimplementation-class=com.taobao.android.builder.AtlasLibPlugin"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/main/resources/META-INF/gradle-plugins/com.taobao.atlas.properties",
    "content": "#\n#\n#\n#\n#                                   Apache License\n#                             Version 2.0, January 2004\n#                          http://www.apache.org/licenses/\n#\n#     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n#\n#     1. Definitions.\n#\n#        \"License\" shall mean the terms and conditions for use, reproduction,\n#        and distribution as defined by Sections 1 through 9 of this document.\n#\n#        \"Licensor\" shall mean the copyright owner or entity authorized by\n#        the copyright owner that is granting the License.\n#\n#        \"Legal Entity\" shall mean the union of the acting entity and all\n#        other entities that control, are controlled by, or are under common\n#        control with that entity. For the purposes of this definition,\n#        \"control\" means (i) the power, direct or indirect, to cause the\n#        direction or management of such entity, whether by contract or\n#        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n#        outstanding shares, or (iii) beneficial ownership of such entity.\n#\n#        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n#        exercising permissions granted by this License.\n#\n#        \"Source\" form shall mean the preferred form for making modifications,\n#        including but not limited to software source code, documentation\n#        source, and configuration files.\n#\n#        \"Object\" form shall mean any form resulting from mechanical\n#        transformation or translation of a Source form, including but\n#        not limited to compiled object code, generated documentation,\n#        and conversions to other media types.\n#\n#        \"Work\" shall mean the work of authorship, whether in Source or\n#        Object form, made available under the License, as indicated by a\n#        copyright notice that is included in or attached to the work\n#        (an example is provided in the Appendix below).\n#\n#        \"Derivative Works\" shall mean any work, whether in Source or Object\n#        form, that is based on (or derived from) the Work and for which the\n#        editorial revisions, annotations, elaborations, or other modifications\n#        represent, as a whole, an original work of authorship. For the purposes\n#        of this License, Derivative Works shall not include works that remain\n#        separable from, or merely link (or bind by name) to the interfaces of,\n#        the Work and Derivative Works thereof.\n#\n#        \"Contribution\" shall mean any work of authorship, including\n#        the original version of the Work and any modifications or additions\n#        to that Work or Derivative Works thereof, that is intentionally\n#        submitted to Licensor for inclusion in the Work by the copyright owner\n#        or by an individual or Legal Entity authorized to submit on behalf of\n#        the copyright owner. For the purposes of this definition, \"submitted\"\n#        means any form of electronic, verbal, or written communication sent\n#        to the Licensor or its representatives, including but not limited to\n#        communication on electronic mailing lists, source code control systems,\n#        and issue tracking systems that are managed by, or on behalf of, the\n#        Licensor for the purpose of discussing and improving the Work, but\n#        excluding communication that is conspicuously marked or otherwise\n#        designated in writing by the copyright owner as \"Not a Contribution.\"\n#\n#        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n#        on behalf of whom a Contribution has been received by Licensor and\n#        subsequently incorporated within the Work.\n#\n#     2. Grant of Copyright License. Subject to the terms and conditions of\n#        this License, each Contributor hereby grants to You a perpetual,\n#        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n#        copyright license to reproduce, prepare Derivative Works of,\n#        publicly display, publicly perform, sublicense, and distribute the\n#        Work and such Derivative Works in Source or Object form.\n#\n#     3. Grant of Patent License. Subject to the terms and conditions of\n#        this License, each Contributor hereby grants to You a perpetual,\n#        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n#        (except as stated in this section) patent license to make, have made,\n#        use, offer to sell, sell, import, and otherwise transfer the Work,\n#        where such license applies only to those patent claims licensable\n#        by such Contributor that are necessarily infringed by their\n#        Contribution(s) alone or by combination of their Contribution(s)\n#        with the Work to which such Contribution(s) was submitted. If You\n#        institute patent litigation against any entity (including a\n#        cross-claim or counterclaim in a lawsuit) alleging that the Work\n#        or a Contribution incorporated within the Work constitutes direct\n#        or contributory patent infringement, then any patent licenses\n#        granted to You under this License for that Work shall terminate\n#        as of the date such litigation is filed.\n#\n#     4. Redistribution. You may reproduce and distribute copies of the\n#        Work or Derivative Works thereof in any medium, with or without\n#        modifications, and in Source or Object form, provided that You\n#        meet the following conditions:\n#\n#        (a) You must give any other recipients of the Work or\n#            Derivative Works a copy of this License; and\n#\n#        (b) You must cause any modified files to carry prominent notices\n#            stating that You changed the files; and\n#\n#        (c) You must retain, in the Source form of any Derivative Works\n#            that You distribute, all copyright, patent, trademark, and\n#            attribution notices from the Source form of the Work,\n#            excluding those notices that do not pertain to any part of\n#            the Derivative Works; and\n#\n#        (d) If the Work includes a \"NOTICE\" text file as part of its\n#            distribution, then any Derivative Works that You distribute must\n#            include a readable copy of the attribution notices contained\n#            within such NOTICE file, excluding those notices that do not\n#            pertain to any part of the Derivative Works, in at least one\n#            of the following places: within a NOTICE text file distributed\n#            as part of the Derivative Works; within the Source form or\n#            documentation, if provided along with the Derivative Works; or,\n#            within a display generated by the Derivative Works, if and\n#            wherever such third-party notices normally appear. The contents\n#            of the NOTICE file are for informational purposes only and\n#            do not modify the License. You may add Your own attribution\n#            notices within Derivative Works that You distribute, alongside\n#            or as an addendum to the NOTICE text from the Work, provided\n#            that such additional attribution notices cannot be construed\n#            as modifying the License.\n#\n#        You may add Your own copyright statement to Your modifications and\n#        may provide additional or different license terms and conditions\n#        for use, reproduction, or distribution of Your modifications, or\n#        for any such Derivative Works as a whole, provided Your use,\n#        reproduction, and distribution of the Work otherwise complies with\n#        the conditions stated in this License.\n#\n#     5. Submission of Contributions. Unless You explicitly state otherwise,\n#        any Contribution intentionally submitted for inclusion in the Work\n#        by You to the Licensor shall be under the terms and conditions of\n#        this License, without any additional terms or conditions.\n#        Notwithstanding the above, nothing herein shall supersede or modify\n#        the terms of any separate license agreement you may have executed\n#        with Licensor regarding such Contributions.\n#\n#     6. Trademarks. This License does not grant permission to use the trade\n#        names, trademarks, service marks, or product names of the Licensor,\n#        except as required for reasonable and customary use in describing the\n#        origin of the Work and reproducing the content of the NOTICE file.\n#\n#     7. Disclaimer of Warranty. Unless required by applicable law or\n#        agreed to in writing, Licensor provides the Work (and each\n#        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n#        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n#        implied, including, without limitation, any warranties or conditions\n#        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n#        PARTICULAR PURPOSE. You are solely responsible for determining the\n#        appropriateness of using or redistributing the Work and assume any\n#        risks associated with Your exercise of permissions under this License.\n#\n#     8. Limitation of Liability. In no event and under no legal theory,\n#        whether in tort (including negligence), contract, or otherwise,\n#        unless required by applicable law (such as deliberate and grossly\n#        negligent acts) or agreed to in writing, shall any Contributor be\n#        liable to You for damages, including any direct, indirect, special,\n#        incidental, or consequential damages of any character arising as a\n#        result of this License or out of the use or inability to use the\n#        Work (including but not limited to damages for loss of goodwill,\n#        work stoppage, computer failure or malfunction, or any and all\n#        other commercial damages or losses), even if such Contributor\n#        has been advised of the possibility of such damages.\n#\n#     9. Accepting Warranty or Additional Liability. While redistributing\n#        the Work or Derivative Works thereof, You may choose to offer,\n#        and charge a fee for, acceptance of support, warranty, indemnity,\n#        or other liability obligations and/or rights consistent with this\n#        License. However, in accepting such obligations, You may act only\n#        on Your own behalf and on Your sole responsibility, not on behalf\n#        of any other Contributor, and only if You agree to indemnify,\n#        defend, and hold each Contributor harmless for any liability\n#        incurred by, or claims asserted against, such Contributor by reason\n#        of your accepting any such warranty or additional liability.\n#\n#     END OF TERMS AND CONDITIONS\n#\n#     APPENDIX: How to apply the Apache License to your work.\n#\n#        To apply the Apache License to your work, attach the following\n#        boilerplate notice, with the fields enclosed by brackets \"[]\"\n#        replaced with your own identifying information. (Don't include\n#        the brackets!)  The text should be enclosed in the appropriate\n#        comment syntax for the file format. We also recommend that a\n#        file or class name and description of purpose be included on the\n#        same \"printed page\" as the copyright notice for easier\n#        identification within third-party archives.\n#\n#     Copyright 2016 Alibaba Group\n#\n#     Licensed under the Apache License, Version 2.0 (the \"License\");\n#     you may not use this file except in compliance with the License.\n#     You may obtain a copy of the License at\n#\n#         http://www.apache.org/licenses/LICENSE-2.0\n#\n#     Unless required by applicable law or agreed to in writing, software\n#     distributed under the License is distributed on an \"AS IS\" BASIS,\n#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n#     See the License for the specific language governing permissions and\n#     limitations under the License.\n#\n#\n#\n\nimplementation-class=com.taobao.android.builder.AtlasPlugin"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/test/java/com/taobao/asm/AsmExample.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.asm;\n\nimport org.objectweb.asm.ClassReader;\nimport org.objectweb.asm.ClassVisitor;\nimport org.objectweb.asm.ClassWriter;\nimport org.objectweb.asm.MethodVisitor;\nimport org.objectweb.asm.Opcodes;\n\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\n\npublic class AsmExample extends ClassLoader implements Opcodes {\n\n    public static class Foo {\n        public static void execute() {\n            System.out.println(\"test changed method name\");\n        }\n\n        public static void changeMethodContent() {\n            System.out.println(\"test change method\");\n        }\n    }\n\n    public static void main(String[] args) throws IOException, IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException {\n\n        ClassReader cr = new ClassReader(Foo.class.getName());\n        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);\n        ClassVisitor cv = new MethodChangeClassAdapter(cw);\n        cr.accept(cv, Opcodes.ASM4);\n\n        //Add a new method  \n        MethodVisitor mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,\n                                          \"add\",\n                                          \"([Ljava/lang/String;)V\",\n                                          null,\n                                          null);\n        // pushes the 'out' field (of type PrintStream) of the System class  \n        mw.visitFieldInsn(GETSTATIC, \"java/lang/System\", \"out\", \"Ljava/io/PrintStream;\");\n        // pushes the \"Hello World!\" String constant  \n        mw.visitLdcInsn(\"this is add method print!\");\n        // invokes the 'println' method (defined in the PrintStream class)  \n        mw.visitMethodInsn(INVOKEVIRTUAL,\n                           \"java/io/PrintStream\",\n                           \"println\",\n                           \"(Ljava/lang/String;)V\");\n        mw.visitInsn(RETURN);\n        // this code uses a maximum of two stack elements and two local  \n        // variables  \n        mw.visitMaxs(0, 0);\n        mw.visitEnd();\n\n        // gets the bytecode of the Example class, and loads it dynamically  \n        byte[] code = cw.toByteArray();\n\n        AsmExample loader = new AsmExample();\n        Class<?> exampleClass = loader.defineClass(Foo.class.getName(), code, 0, code.length);\n\n        for (Method method : exampleClass.getMethods()) {\n            System.out.println(method);\n        }\n\n        System.out.println(\"*************\");\n\n        // uses the dynamically generated class to print 'Helloworld'  \n        exampleClass.getMethods()[0].invoke(null);  //Change the method content by calling the changeMethodContent\n\n        System.out.println(\"*************\");\n\n        exampleClass.getMethods()[1].invoke(null); //Call execute to modify the method name\n\n        // gets the bytecode of the Example class, and loads it dynamically  \n\n        FileOutputStream fos = new FileOutputStream(\"e:\\\\logs\\\\Example.class\");\n        fos.write(code);\n        fos.close();\n    }\n\n    static class MethodChangeClassAdapter extends ClassVisitor implements Opcodes {\n\n        public MethodChangeClassAdapter(final ClassVisitor cv) {\n            super(Opcodes.ASM4, cv);\n        }\n\n        @Override\n        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {\n            if (cv != null) {\n                cv.visit(version, access, name, signature, superName, interfaces);\n            }\n        }\n\n        @Override\n        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {\n            if (cv != null && \"execute\".equals(name)) { //When the method is called execute, the modified method is called execute1  \n                return cv.visitMethod(access, name + \"1\", desc, signature, exceptions);\n            }\n\n            if (\"changeMethodContent\".equals(name))  //The changeMethodContent here is the method that needs to be modified  , modify the method content\n            {\n                MethodVisitor mv = cv.visitMethod(access,\n                                                  name,\n                                                  desc,\n                                                  signature,\n                                                  exceptions);//So let's get the original method\n                MethodVisitor newMethod = null;\n                newMethod = new AsmMethodVisit(mv); //Access needs to be modified    \n                return newMethod;\n            }\n            if (cv != null) {\n                return cv.visitMethod(access, name, desc, signature, exceptions);\n            }\n\n            return null;\n        }\n    }\n\n    static class AsmMethodVisit extends MethodVisitor {\n\n        public AsmMethodVisit(MethodVisitor mv) {\n            super(Opcodes.ASM4, mv);\n        }\n\n        @Override\n        public void visitMethodInsn(int opcode, String owner, String name, String desc) {\n            super.visitMethodInsn(opcode, owner, name, desc);\n        }\n\n        @Override\n        public void visitCode() {\n            //This method is accessed at the head of the access method only once  \n            //New instructions can be inserted here  \n            super.visitCode();\n        }\n\n        @Override\n        public void visitInsn(int opcode) {\n            //This method can get the operation type of each instruction in the method, which is accessed many times  \n            //If a new instruction should be added at the end of the method, it should be judged:  \n            if (opcode == Opcodes.RETURN) {\n                // pushes the 'out' field (of type PrintStream) of the System class  \n                mv.visitFieldInsn(GETSTATIC, \"java/lang/System\", \"out\", \"Ljava/io/PrintStream;\");\n                // pushes the \"Hello World!\" String constant  \n                mv.visitLdcInsn(\"this is a modify method!\");\n                // invokes the 'println' method (defined in the PrintStream class)  \n                mv.visitMethodInsn(INVOKEVIRTUAL,\n                                   \"java/io/PrintStream\",\n                                   \"println\",\n                                   \"(Ljava/lang/String;)V\");\n                //                mv.visitInsn(RETURN);\n            }\n            super.visitInsn(opcode);\n        }\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/test/java/com/taobao/asm/AsmFieldTest.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.asm;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.taobao.android.builder.tools.asm.field.AsmFieldEditor;\nimport com.taobao.android.builder.tools.asm.field.Field;\nimport org.junit.Test;\nimport org.objectweb.asm.Opcodes;\n\n/**\n * Created by wuzhong on 2017/4/27.\n */\npublic class AsmFieldTest implements Opcodes {\n\n    @Test\n    public void test() throws Throwable {\n\n        List<Field> fields = new ArrayList<>();\n        fields.add(new Field(ACC_PUBLIC + ACC_STATIC + ACC_FINAL, \"name\", \"wuzhong\"));\n        fields.add(new Field(ACC_PUBLIC + ACC_STATIC + ACC_FINAL, \"age\", 1));\n        fields.add(new Field(ACC_PUBLIC + ACC_STATIC + ACC_FINAL, \"type\", 1L));\n        fields.add(new Field(ACC_PUBLIC + ACC_STATIC + ACC_FINAL, \"b\", false));\n\n        byte[] code = AsmFieldEditor.edit(Config.class.getName(), fields);\n        File file = new File(\"Config.class\");\n        System.out.println(file.getAbsolutePath());\n        FileOutputStream fos = new FileOutputStream(file);\n        fos.write(code);\n        fos.close();\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/test/java/com/taobao/asm/AsmTest.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.asm;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\n\nimport com.taobao.android.builder.tools.asm.field.ModifyClassVisiter;\nimport com.taobao.asm.AsmExample.MethodChangeClassAdapter;\nimport org.junit.Test;\nimport org.objectweb.asm.ClassReader;\nimport org.objectweb.asm.ClassVisitor;\nimport org.objectweb.asm.ClassWriter;\nimport org.objectweb.asm.FieldVisitor;\nimport org.objectweb.asm.MethodVisitor;\nimport org.objectweb.asm.Opcodes;\nimport org.objectweb.asm.Type;\n\n/**\n * Created by wuzhong on 2017/4/27.\n */\npublic class AsmTest implements Opcodes{\n\n    @Test\n    public void test() throws Throwable {\n\n        ClassReader cr = new ClassReader(Config.class.getName());\n        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);\n        ClassVisitor cv = new MethodChangeClassAdapter(cw);\n        cr.accept(cv, Opcodes.ASM5);\n\n        //Add a new method\n        MethodVisitor mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,\n                                          \"add\",\n                                          \"([Ljava/lang/String;)V\",\n                                          null,\n                                          null);\n\n        // pushes the 'out' field (of type PrintStream) of the System class\n        mw.visitFieldInsn(GETSTATIC,\n                          \"java/lang/System\",\n                          \"out\",\n                          \"Ljava/io/PrintStream;\");\n        // pushes the \"Hello World!\" String constant\n        mw.visitLdcInsn(\"this is add method print!\");\n        // invokes the 'println' method (defined in the PrintStream class)\n        mw.visitMethodInsn(INVOKEVIRTUAL,\n                           \"java/io/PrintStream\",\n                           \"println\",\n                           \"(Ljava/lang/String;)V\");\n        mw.visitInsn(RETURN);\n        // this code uses a maximum of two stack elements and two local\n        // variables\n        mw.visitMaxs(0, 0);\n        mw.visitEnd();\n\n\n        //Type.getDescriptor(AdviceFlowOuterHolder.class)\n        FieldVisitor fv = cw.visitField(ACC_PUBLIC + ACC_STATIC + ACC_FINAL,\n                                         \"age\",\n                                        Type.INT_TYPE.toString(),\n                                         null,\n                                         1);\n        fv.visitEnd();\n\n        FieldVisitor fv2 = cw.visitField(ACC_PUBLIC + ACC_STATIC + ACC_FINAL,\n                                        \"name2\",\n                                        Type.getDescriptor(String.class),\n                                        null,\n                                        \"name2\");\n        fv2.visitEnd();\n\n\n        ModifyClassVisiter cv2 = new ModifyClassVisiter(Opcodes.ASM5);\n        cv2.addRemoveField(\"name\");\n        cr.accept(cv2, Opcodes.ASM5);\n\n        FieldVisitor fv3 = cw.visitField(ACC_PUBLIC + ACC_STATIC + ACC_FINAL,\n                                         \"name\",\n                                         Type.getDescriptor(String.class),\n                                         null,\n                                         \"name\");\n        fv3.visitEnd();\n\n\n\n\n        byte[] code = cw.toByteArray();\n        File file = new File(\"Config.class\");\n        System.out.println(file.getAbsolutePath());\n        FileOutputStream fos = new FileOutputStream(file);\n        fos.write(code);\n        fos.close();\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/test/java/com/taobao/asm/Config.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.asm;\n\n/**\n * Created by wuzhong on 2017/4/27.\n */\npublic class Config {\n\n    public String name;\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/test/java/com/taobao/atlas/bundle/BundleDependenyTest.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.atlas.bundle;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\n\nimport com.google.common.collect.Sets;\nimport com.taobao.android.builder.dependency.model.AwbBundle;\nimport org.apache.commons.io.FileUtils;\nimport org.junit.Test;\n\n/**\n * Created by wuzhong on 2017/5/13.\n */\npublic class BundleDependenyTest {\n\n    @Test\n    public void test(){\n\n        List<AwbBundle> awbBundles = new ArrayList<>();\n\n        AwbBundle awbBundle1 = new AwbBundle(\"Isolated bundle\");\n        AwbBundle awbBundle2 = new AwbBundle(\"Isolated child bundleA\");\n        AwbBundle awbBundle3 = new AwbBundle(\"Depends on the bundle\");\n        awbBundle3.getBundleDependencies().add(awbBundle2);\n\n        AwbBundle awbBundle4 = new AwbBundle(\"Cycle dependence A\");\n        AwbBundle awbBundle5 = new AwbBundle(\"Cycle dependence B\");\n        AwbBundle awbBundle6 = new AwbBundle(\"Cycle dependence C\");\n        awbBundle5.getBundleDependencies().add(awbBundle6);\n        awbBundle6.getBundleDependencies().add(awbBundle4);\n        awbBundle4.getBundleDependencies().add(awbBundle5);\n\n        awbBundles.add(awbBundle1);\n        awbBundles.add(awbBundle2);\n        awbBundles.add(awbBundle3);\n        awbBundles.add(awbBundle4);\n        awbBundles.add(awbBundle5);\n        awbBundles.add(awbBundle6);\n\n        //Generate awbBundleGraph\n\n        //Take the top one\n        for (AwbBundle awbBundle: awbBundles){\n\n        }\n\n\n\n\n\n\n\n    }\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/test/java/com/taobao/atlas/cache/FileLockTest.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.atlas.cache;\n\nimport java.io.File;\n\nimport com.taobao.android.builder.tools.cache.FileLockUtils;\nimport org.junit.Test;\n\n/**\n * Created by wuzhong on 2017/5/16.\n */\npublic class FileLockTest {\n\n    @Test\n    public void test(){\n\n        File dir = new File(\"build/test/lock\");\n        System.out.println(dir.getAbsolutePath());\n\n        dir.mkdirs();\n\n        FileLockUtils.lock(dir, new Runnable() {\n            @Override\n            public void run() {\n                System.out.println(\"1111\");\n\n                try {\n                    Thread.sleep(1000);\n                } catch (InterruptedException e) {\n                    e.printStackTrace();\n                }\n\n            }\n        });\n\n        FileLockUtils.lock(dir, new Runnable() {\n            @Override\n            public void run() {\n                System.out.println(\"2222\");\n\n                try {\n                    Thread.sleep(1000);\n                } catch (InterruptedException e) {\n                    e.printStackTrace();\n                }\n\n            }\n        });\n\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/test/java/com/taobao/atlas/dex/FastDexMergeTest.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.atlas.dex;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.List;\n\nimport com.taobao.android.builder.extension.MultiDexConfig;\nimport com.taobao.android.builder.tools.multidex.dex.DexGroup;\nimport com.taobao.android.builder.tools.multidex.dex.DexMerger;\nimport org.apache.commons.io.FileUtils;\nimport org.junit.Test;\n\n/**\n * Created by wuzhong on 2017/5/19.\n */\npublic class FastDexMergeTest {\n\n    @Test\n    public void test() throws IOException {\n\n        //String dir\n        //    = \"/Users/wuzhong/workspace/ali_android/cainiao/guoguo_android/guoguo_app/build/intermediates/transforms\"\n        //    + \"/dex/debug/folders/1000/1f/main\";\n\n        String dir = \"/Users/wuzhong/Downloads/alipay\";\n\n        //String dir = \"/Users/wuzhong/Downloads/guoguo\";\n        Collection<File> files = FileUtils.listFiles(new File(dir), new String[] {\"dex\"}, true);\n\n        //testA(files);\n        //\n        //testB(files);\n\n        testC(files);\n\n    }\n\n    private void testA(Collection<File> files) throws IOException {\n        MultiDexConfig multiDexConfig = new MultiDexConfig(\"debug\");\n        DexMerger dexMerger = new DexMerger(multiDexConfig, files);\n        List<DexGroup> dexDtos = dexMerger.group();\n        //System.out.println(JSON.toJSONString(dexDtos,true));\n        System.out.println(dexDtos.size());\n        System.out.println(dexMerger.dexList.size());\n    }\n\n    private void testB(Collection<File> files) throws IOException {\n        MultiDexConfig multiDexConfig = new MultiDexConfig(\"debug\");\n        multiDexConfig.setDexCount(3);\n        DexMerger dexMerger = new DexMerger(multiDexConfig, files);\n        List<DexGroup> dexDtos = dexMerger.group();\n        //System.out.println(JSON.toJSONString(dexDtos,true));\n        System.out.println(dexDtos.size());\n        System.out.println(dexMerger.dexList.size());\n    }\n\n    private void testC(Collection<File> files) throws IOException {\n        MultiDexConfig multiDexConfig = new MultiDexConfig(\"debug\");\n        //multiDexConfig.setDexSplitRules(\"a12312,123213;c123123,d123123;ee123123\");\n        //multiDexConfig.setDexCount(3);\n        DexMerger dexMerger = new DexMerger(multiDexConfig, files);\n        List<DexGroup> dexDtos = dexMerger.group();\n        System.out.println(dexDtos.size());\n        System.out.println(dexMerger.dexList.size());\n        FileUtils.deleteDirectory(new File(\"/Users/wuzhong/Downloads/dex\"));\n        new File(\"/Users/wuzhong/Downloads/dex\").mkdirs();\n        dexMerger.executeMerge(new File(\"/Users/wuzhong/Downloads/dex\"),dexDtos);\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/test/java/com/taobao/atlas/manifest/ManifestHelperTest.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.atlas.manifest;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\n\nimport com.taobao.android.builder.tools.manifest.AtlasProxy;\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport com.taobao.android.builder.tools.manifest.Result;\nimport org.apache.commons.io.IOUtils;\nimport org.dom4j.Document;\nimport org.dom4j.DocumentException;\nimport org.dom4j.io.OutputFormat;\nimport org.dom4j.io.SAXReader;\nimport org.dom4j.io.XMLWriter;\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * Created by wuzhong on 2017/4/12.\n */\npublic class ManifestHelperTest {\n\n    @Test\n    public void test() throws DocumentException, IOException {\n\n        File manifest = new File(\n            ManifestHelperTest.class.getClassLoader().getResource(\"AndroidManifest.xml\").getFile());\n\n        File manifest2 = new File(\n            ManifestHelperTest.class.getClassLoader().getResource(\"AndroidManifest2.xml\").getFile());\n\n        File manifest3 = new File( manifest2.getParentFile(),\"AndroidManifest3.xml\");\n\n        Assert.assertTrue(manifest.exists());\n\n        ManifestFileUtils.createPatchManifest(manifest,manifest2,manifest3);\n\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/test/java/com/taobao/atlas/manifest/ManifestTest.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage com.taobao.atlas.manifest;\n\nimport java.io.File;\nimport java.io.IOException;\n\nimport com.taobao.android.builder.tools.manifest.ManifestFileUtils;\nimport com.taobao.android.builder.tools.xml.XmlHelper;\nimport org.dom4j.Document;\nimport org.dom4j.DocumentException;\nimport org.junit.Test;\n\n/**\n * Created by wuzhong on 2017/4/13.\n */\npublic class ManifestTest {\n\n    @Test\n    public void test() throws DocumentException, IOException {\n        System.out.printf(\"123\");\n\n        Document document =  XmlHelper.readXml(new File(\"/Users/wuzhong/Downloads/AndroidManifest.xml\"));\n\n        ManifestFileUtils.printlnPermissions(document);\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/test/java/proguard/KeepOnlyConfigurationParserTest.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\npackage proguard;\n\nimport java.io.File;\nimport java.io.IOException;\n\nimport com.alibaba.fastjson.JSON;\n\nimport com.taobao.android.builder.tools.proguard.KeepOnlyConfigurationParser;\nimport org.junit.Test;\n\n/**\n * Created by wuzhong on 2017/4/26.\n */\npublic class KeepOnlyConfigurationParserTest {\n\n    @Test\n    public void test() throws IOException, ParseException {\n\n        File\n            file = new File(\n            \"src/test/resources/proguard.txt\");\n\n        Configuration configuration = new Configuration();\n\n        // Parse the options specified in the command line arguments.\n        KeepOnlyConfigurationParser parser = new KeepOnlyConfigurationParser(file,\n                                                                             System.getProperties());\n        try {\n            parser.parse(configuration);\n        } finally {\n            parser.close();\n        }\n\n        System.out.println(JSON.toJSONString(configuration,true));\n\n        //// Execute ProGuard with these options.\n        //new ProGuard(configuration).execute();\n\n    }\n\n}"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/test/resources/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~\n  ~\n  ~\n  ~                                   Apache License\n  ~                             Version 2.0, January 2004\n  ~                          http://www.apache.org/licenses/\n  ~\n  ~     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n  ~\n  ~     1. Definitions.\n  ~\n  ~        \"License\" shall mean the terms and conditions for use, reproduction,\n  ~        and distribution as defined by Sections 1 through 9 of this document.\n  ~\n  ~        \"Licensor\" shall mean the copyright owner or entity authorized by\n  ~        the copyright owner that is granting the License.\n  ~\n  ~        \"Legal Entity\" shall mean the union of the acting entity and all\n  ~        other entities that control, are controlled by, or are under common\n  ~        control with that entity. For the purposes of this definition,\n  ~        \"control\" means (i) the power, direct or indirect, to cause the\n  ~        direction or management of such entity, whether by contract or\n  ~        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n  ~        outstanding shares, or (iii) beneficial ownership of such entity.\n  ~\n  ~        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n  ~        exercising permissions granted by this License.\n  ~\n  ~        \"Source\" form shall mean the preferred form for making modifications,\n  ~        including but not limited to software source code, documentation\n  ~        source, and configuration files.\n  ~\n  ~        \"Object\" form shall mean any form resulting from mechanical\n  ~        transformation or translation of a Source form, including but\n  ~        not limited to compiled object code, generated documentation,\n  ~        and conversions to other media types.\n  ~\n  ~        \"Work\" shall mean the work of authorship, whether in Source or\n  ~        Object form, made available under the License, as indicated by a\n  ~        copyright notice that is included in or attached to the work\n  ~        (an example is provided in the Appendix below).\n  ~\n  ~        \"Derivative Works\" shall mean any work, whether in Source or Object\n  ~        form, that is based on (or derived from) the Work and for which the\n  ~        editorial revisions, annotations, elaborations, or other modifications\n  ~        represent, as a whole, an original work of authorship. For the purposes\n  ~        of this License, Derivative Works shall not include works that remain\n  ~        separable from, or merely link (or bind by name) to the interfaces of,\n  ~        the Work and Derivative Works thereof.\n  ~\n  ~        \"Contribution\" shall mean any work of authorship, including\n  ~        the original version of the Work and any modifications or additions\n  ~        to that Work or Derivative Works thereof, that is intentionally\n  ~        submitted to Licensor for inclusion in the Work by the copyright owner\n  ~        or by an individual or Legal Entity authorized to submit on behalf of\n  ~        the copyright owner. For the purposes of this definition, \"submitted\"\n  ~        means any form of electronic, verbal, or written communication sent\n  ~        to the Licensor or its representatives, including but not limited to\n  ~        communication on electronic mailing lists, source code control systems,\n  ~        and issue tracking systems that are managed by, or on behalf of, the\n  ~        Licensor for the purpose of discussing and improving the Work, but\n  ~        excluding communication that is conspicuously marked or otherwise\n  ~        designated in writing by the copyright owner as \"Not a Contribution.\"\n  ~\n  ~        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n  ~        on behalf of whom a Contribution has been received by Licensor and\n  ~        subsequently incorporated within the Work.\n  ~\n  ~     2. Grant of Copyright License. Subject to the terms and conditions of\n  ~        this License, each Contributor hereby grants to You a perpetual,\n  ~        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n  ~        copyright license to reproduce, prepare Derivative Works of,\n  ~        publicly display, publicly perform, sublicense, and distribute the\n  ~        Work and such Derivative Works in Source or Object form.\n  ~\n  ~     3. Grant of Patent License. Subject to the terms and conditions of\n  ~        this License, each Contributor hereby grants to You a perpetual,\n  ~        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n  ~        (except as stated in this section) patent license to make, have made,\n  ~        use, offer to sell, sell, import, and otherwise transfer the Work,\n  ~        where such license applies only to those patent claims licensable\n  ~        by such Contributor that are necessarily infringed by their\n  ~        Contribution(s) alone or by combination of their Contribution(s)\n  ~        with the Work to which such Contribution(s) was submitted. If You\n  ~        institute patent litigation against any entity (including a\n  ~        cross-claim or counterclaim in a lawsuit) alleging that the Work\n  ~        or a Contribution incorporated within the Work constitutes direct\n  ~        or contributory patent infringement, then any patent licenses\n  ~        granted to You under this License for that Work shall terminate\n  ~        as of the date such litigation is filed.\n  ~\n  ~     4. Redistribution. You may reproduce and distribute copies of the\n  ~        Work or Derivative Works thereof in any medium, with or without\n  ~        modifications, and in Source or Object form, provided that You\n  ~        meet the following conditions:\n  ~\n  ~        (a) You must give any other recipients of the Work or\n  ~            Derivative Works a copy of this License; and\n  ~\n  ~        (b) You must cause any modified files to carry prominent notices\n  ~            stating that You changed the files; and\n  ~\n  ~        (c) You must retain, in the Source form of any Derivative Works\n  ~            that You distribute, all copyright, patent, trademark, and\n  ~            attribution notices from the Source form of the Work,\n  ~            excluding those notices that do not pertain to any part of\n  ~            the Derivative Works; and\n  ~\n  ~        (d) If the Work includes a \"NOTICE\" text file as part of its\n  ~            distribution, then any Derivative Works that You distribute must\n  ~            include a readable copy of the attribution notices contained\n  ~            within such NOTICE file, excluding those notices that do not\n  ~            pertain to any part of the Derivative Works, in at least one\n  ~            of the following places: within a NOTICE text file distributed\n  ~            as part of the Derivative Works; within the Source form or\n  ~            documentation, if provided along with the Derivative Works; or,\n  ~            within a display generated by the Derivative Works, if and\n  ~            wherever such third-party notices normally appear. The contents\n  ~            of the NOTICE file are for informational purposes only and\n  ~            do not modify the License. You may add Your own attribution\n  ~            notices within Derivative Works that You distribute, alongside\n  ~            or as an addendum to the NOTICE text from the Work, provided\n  ~            that such additional attribution notices cannot be construed\n  ~            as modifying the License.\n  ~\n  ~        You may add Your own copyright statement to Your modifications and\n  ~        may provide additional or different license terms and conditions\n  ~        for use, reproduction, or distribution of Your modifications, or\n  ~        for any such Derivative Works as a whole, provided Your use,\n  ~        reproduction, and distribution of the Work otherwise complies with\n  ~        the conditions stated in this License.\n  ~\n  ~     5. Submission of Contributions. Unless You explicitly state otherwise,\n  ~        any Contribution intentionally submitted for inclusion in the Work\n  ~        by You to the Licensor shall be under the terms and conditions of\n  ~        this License, without any additional terms or conditions.\n  ~        Notwithstanding the above, nothing herein shall supersede or modify\n  ~        the terms of any separate license agreement you may have executed\n  ~        with Licensor regarding such Contributions.\n  ~\n  ~     6. Trademarks. This License does not grant permission to use the trade\n  ~        names, trademarks, service marks, or product names of the Licensor,\n  ~        except as required for reasonable and customary use in describing the\n  ~        origin of the Work and reproducing the content of the NOTICE file.\n  ~\n  ~     7. Disclaimer of Warranty. Unless required by applicable law or\n  ~        agreed to in writing, Licensor provides the Work (and each\n  ~        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n  ~        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n  ~        implied, including, without limitation, any warranties or conditions\n  ~        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n  ~        PARTICULAR PURPOSE. You are solely responsible for determining the\n  ~        appropriateness of using or redistributing the Work and assume any\n  ~        risks associated with Your exercise of permissions under this License.\n  ~\n  ~     8. Limitation of Liability. In no event and under no legal theory,\n  ~        whether in tort (including negligence), contract, or otherwise,\n  ~        unless required by applicable law (such as deliberate and grossly\n  ~        negligent acts) or agreed to in writing, shall any Contributor be\n  ~        liable to You for damages, including any direct, indirect, special,\n  ~        incidental, or consequential damages of any character arising as a\n  ~        result of this License or out of the use or inability to use the\n  ~        Work (including but not limited to damages for loss of goodwill,\n  ~        work stoppage, computer failure or malfunction, or any and all\n  ~        other commercial damages or losses), even if such Contributor\n  ~        has been advised of the possibility of such damages.\n  ~\n  ~     9. Accepting Warranty or Additional Liability. While redistributing\n  ~        the Work or Derivative Works thereof, You may choose to offer,\n  ~        and charge a fee for, acceptance of support, warranty, indemnity,\n  ~        or other liability obligations and/or rights consistent with this\n  ~        License. However, in accepting such obligations, You may act only\n  ~        on Your own behalf and on Your sole responsibility, not on behalf\n  ~        of any other Contributor, and only if You agree to indemnify,\n  ~        defend, and hold each Contributor harmless for any liability\n  ~        incurred by, or claims asserted against, such Contributor by reason\n  ~        of your accepting any such warranty or additional liability.\n  ~\n  ~     END OF TERMS AND CONDITIONS\n  ~\n  ~     APPENDIX: How to apply the Apache License to your work.\n  ~\n  ~        To apply the Apache License to your work, attach the following\n  ~        boilerplate notice, with the fields enclosed by brackets \"[]\"\n  ~        replaced with your own identifying information. (Don't include\n  ~        the brackets!)  The text should be enclosed in the appropriate\n  ~        comment syntax for the file format. We also recommend that a\n  ~        file or class name and description of purpose be included on the\n  ~        same \"printed page\" as the copyright notice for easier\n  ~        identification within third-party archives.\n  ~\n  ~     Copyright 2016 Alibaba Group\n  ~\n  ~     Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~     you may not use this file except in compliance with the License.\n  ~     You may obtain a copy of the License at\n  ~\n  ~         http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~     Unless required by applicable law or agreed to in writing, software\n  ~     distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~     See the License for the specific language governing permissions and\n  ~     limitations under the License.\n  ~\n  ~\n  -->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com.taobao.demo\" android:versionCode=\"1\" android:versionName=\"1.0.0\">\n  <uses-sdk android:minSdkVersion=\"14\" android:targetSdkVersion=\"25\"/>  \n  <!-- -->  \n  <uses-permission android:name=\"android.permission.INTERNET\"/>  \n  <meta-data android:name=\"android.support.VERSION\" android:value=\"25.3.0\"/>  \n  <application android:name=\"android.taobao.atlas.startup.AtlasBridgeApplication\" android:allowBackup=\"true\" android:icon=\"@mipmap/ic_launcher\" android:label=\"Atlas\" android:supportsRtl=\"true\"> \n    <activity android:name=\"com.taobao.demo.MainActivity\" android:label=\"@string/app_name\" android:theme=\"@style/AppTheme.NoActionBar\"/>  \n    <activity android:name=\"com.taobao.demo.UpdateDemoActivity\" android:label=\"@string/title_activity_scrolling\" android:theme=\"@style/AppTheme.NoActionBar\"/>  \n    <activity android:name=\"com.taobao.demo.RemoteDemoActivity\" android:label=\"@string/title_activity_update\" android:theme=\"@style/AppTheme.NoActionBar\"/>  \n    <activity android:name=\"com.taobao.secondbundlelibrary.SecondbundleShareActivity\" android:theme=\"@style/Theme.AppCompat.Light\">\n      <meta-data android:name=\"bundleLocation\" android:value=\"com.taobao.secondbundlelibrary\"/>\n    </activity>  \n    <activity android:name=\"com.taobao.secondbundle.SecondBundleActivity\" android:theme=\"@style/AppTheme.NoActionBar\">\n      <meta-data android:name=\"bundleLocation\" android:value=\"com.taobao.secondbundle\"/>\n    </activity>  \n    <activity android:name=\"com.taobao.remotebunle.RemoteBundleActivity\" android:theme=\"@style/AppTheme.NoActionBar\">\n      <meta-data android:name=\"bundleLocation\" android:value=\"com.taobao.remotebunle\"/>\n    </activity>  \n    <activity android:name=\"com.taobao.firstbundle.FirstBundleActivity\" android:theme=\"@style/AppTheme.NoActionBar\">\n      <meta-data android:name=\"bundleLocation\" android:value=\"com.taobao.firstbundle\"/>\n    </activity>  \n    <service android:name=\"com.taobao.firstbundle.FirstBundleService\" android:enabled=\"true\" android:exported=\"true\">\n      <meta-data android:name=\"bundleLocation\" android:value=\"com.taobao.firstbundle\"/>\n    </service>  \n    <activity android:name=\"com.taobao.splashscreen.WelcomeActivity\" android:configChanges=\"orientation|keyboardHidden|screenSize\" android:theme=\"@style/FullscreenTheme\"> \n      <intent-filter> \n        <action android:name=\"android.intent.action.MAIN\"/>  \n        <category android:name=\"android.intent.category.LAUNCHER\"/> \n      </intent-filter> \n    </activity>  \n    <activity android:name=\"com.taobao.middleware.ItemListActivity\" android:label=\"@string/title_item_list\" android:theme=\"@style/AppTheme.NoActionBar\"/>  \n    <activity android:name=\"com.taobao.middleware.ItemDetailActivity\" android:label=\"@string/title_item_detail\" android:parentActivityName=\"com.taobao.middleware.ItemListActivity\" android:theme=\"@style/AppTheme.NoActionBar\"> \n      <meta-data android:name=\"android.support.PARENT_ACTIVITY\" android:value=\"com.taobao.middleware.ItemListActivity\"/> \n    </activity>  \n    <service android:name=\"com.taobao.atlas.dexmerge.DexMergeService\" android:process=\":dexmerge\"> \n      <intent-filter> \n        <action android:name=\"com.taobao.atlas.dexmerge.DexMergeService\"/> \n      </intent-filter> \n    </service>  \n    <receiver android:name=\"com.taobao.atlas.update.AwoPatchReceiver\"> \n      <intent-filter> \n        <action android:name=\"com.taobao.atlas.intent.PATCH_APP\"/> \n      </intent-filter>  \n      <intent-filter> \n        <action android:name=\"com.taobao.atlas.intent.DEX_PATCH_APP\"/> \n      </intent-filter>  \n      <intent-filter> \n        <action android:name=\"com.taobao.atlas.intent.ROLLBACK_PATCH\"/> \n      </intent-filter>  \n      <intent-filter> \n        <action android:name=\"com.taobao.atlas.intent.ROLLBACK_DEX_PATCH\"/> \n      </intent-filter> \n    </receiver>\n    <service android:name=\"com.taobao.test.TCMSService\" android:exported=\"true\" android:process=\"com.taobao.test\">\n      <meta-data android:name=\"bundleLocation\" android:value=\"com.alibaba.sdk.android\"/>\n    </service>\n    <provider android:name=\"com.taobao.test.MsgProvider\" android:authorities=\"com.taobao.test\" android:exported=\"false\" android:multiprocess=\"true\" android:process=\":messagebox\"/>\n    <service android:name=\"com.taobao.android.runtime.Dex2OatService\" android:process=\":dex2oat\"/>  \n    <meta-data android:name=\"REAL_APPLICATION\" android:value=\"com.taobao.demo.DemoApplication\"/>\n    <meta-data android:name=\"multidex_enable\" android:value=\"true\"/>\n  </application> \n</manifest>\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/test/resources/AndroidManifest2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~\n  ~\n  ~\n  ~                                   Apache License\n  ~                             Version 2.0, January 2004\n  ~                          http://www.apache.org/licenses/\n  ~\n  ~     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n  ~\n  ~     1. Definitions.\n  ~\n  ~        \"License\" shall mean the terms and conditions for use, reproduction,\n  ~        and distribution as defined by Sections 1 through 9 of this document.\n  ~\n  ~        \"Licensor\" shall mean the copyright owner or entity authorized by\n  ~        the copyright owner that is granting the License.\n  ~\n  ~        \"Legal Entity\" shall mean the union of the acting entity and all\n  ~        other entities that control, are controlled by, or are under common\n  ~        control with that entity. For the purposes of this definition,\n  ~        \"control\" means (i) the power, direct or indirect, to cause the\n  ~        direction or management of such entity, whether by contract or\n  ~        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n  ~        outstanding shares, or (iii) beneficial ownership of such entity.\n  ~\n  ~        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n  ~        exercising permissions granted by this License.\n  ~\n  ~        \"Source\" form shall mean the preferred form for making modifications,\n  ~        including but not limited to software source code, documentation\n  ~        source, and configuration files.\n  ~\n  ~        \"Object\" form shall mean any form resulting from mechanical\n  ~        transformation or translation of a Source form, including but\n  ~        not limited to compiled object code, generated documentation,\n  ~        and conversions to other media types.\n  ~\n  ~        \"Work\" shall mean the work of authorship, whether in Source or\n  ~        Object form, made available under the License, as indicated by a\n  ~        copyright notice that is included in or attached to the work\n  ~        (an example is provided in the Appendix below).\n  ~\n  ~        \"Derivative Works\" shall mean any work, whether in Source or Object\n  ~        form, that is based on (or derived from) the Work and for which the\n  ~        editorial revisions, annotations, elaborations, or other modifications\n  ~        represent, as a whole, an original work of authorship. For the purposes\n  ~        of this License, Derivative Works shall not include works that remain\n  ~        separable from, or merely link (or bind by name) to the interfaces of,\n  ~        the Work and Derivative Works thereof.\n  ~\n  ~        \"Contribution\" shall mean any work of authorship, including\n  ~        the original version of the Work and any modifications or additions\n  ~        to that Work or Derivative Works thereof, that is intentionally\n  ~        submitted to Licensor for inclusion in the Work by the copyright owner\n  ~        or by an individual or Legal Entity authorized to submit on behalf of\n  ~        the copyright owner. For the purposes of this definition, \"submitted\"\n  ~        means any form of electronic, verbal, or written communication sent\n  ~        to the Licensor or its representatives, including but not limited to\n  ~        communication on electronic mailing lists, source code control systems,\n  ~        and issue tracking systems that are managed by, or on behalf of, the\n  ~        Licensor for the purpose of discussing and improving the Work, but\n  ~        excluding communication that is conspicuously marked or otherwise\n  ~        designated in writing by the copyright owner as \"Not a Contribution.\"\n  ~\n  ~        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n  ~        on behalf of whom a Contribution has been received by Licensor and\n  ~        subsequently incorporated within the Work.\n  ~\n  ~     2. Grant of Copyright License. Subject to the terms and conditions of\n  ~        this License, each Contributor hereby grants to You a perpetual,\n  ~        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n  ~        copyright license to reproduce, prepare Derivative Works of,\n  ~        publicly display, publicly perform, sublicense, and distribute the\n  ~        Work and such Derivative Works in Source or Object form.\n  ~\n  ~     3. Grant of Patent License. Subject to the terms and conditions of\n  ~        this License, each Contributor hereby grants to You a perpetual,\n  ~        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n  ~        (except as stated in this section) patent license to make, have made,\n  ~        use, offer to sell, sell, import, and otherwise transfer the Work,\n  ~        where such license applies only to those patent claims licensable\n  ~        by such Contributor that are necessarily infringed by their\n  ~        Contribution(s) alone or by combination of their Contribution(s)\n  ~        with the Work to which such Contribution(s) was submitted. If You\n  ~        institute patent litigation against any entity (including a\n  ~        cross-claim or counterclaim in a lawsuit) alleging that the Work\n  ~        or a Contribution incorporated within the Work constitutes direct\n  ~        or contributory patent infringement, then any patent licenses\n  ~        granted to You under this License for that Work shall terminate\n  ~        as of the date such litigation is filed.\n  ~\n  ~     4. Redistribution. You may reproduce and distribute copies of the\n  ~        Work or Derivative Works thereof in any medium, with or without\n  ~        modifications, and in Source or Object form, provided that You\n  ~        meet the following conditions:\n  ~\n  ~        (a) You must give any other recipients of the Work or\n  ~            Derivative Works a copy of this License; and\n  ~\n  ~        (b) You must cause any modified files to carry prominent notices\n  ~            stating that You changed the files; and\n  ~\n  ~        (c) You must retain, in the Source form of any Derivative Works\n  ~            that You distribute, all copyright, patent, trademark, and\n  ~            attribution notices from the Source form of the Work,\n  ~            excluding those notices that do not pertain to any part of\n  ~            the Derivative Works; and\n  ~\n  ~        (d) If the Work includes a \"NOTICE\" text file as part of its\n  ~            distribution, then any Derivative Works that You distribute must\n  ~            include a readable copy of the attribution notices contained\n  ~            within such NOTICE file, excluding those notices that do not\n  ~            pertain to any part of the Derivative Works, in at least one\n  ~            of the following places: within a NOTICE text file distributed\n  ~            as part of the Derivative Works; within the Source form or\n  ~            documentation, if provided along with the Derivative Works; or,\n  ~            within a display generated by the Derivative Works, if and\n  ~            wherever such third-party notices normally appear. The contents\n  ~            of the NOTICE file are for informational purposes only and\n  ~            do not modify the License. You may add Your own attribution\n  ~            notices within Derivative Works that You distribute, alongside\n  ~            or as an addendum to the NOTICE text from the Work, provided\n  ~            that such additional attribution notices cannot be construed\n  ~            as modifying the License.\n  ~\n  ~        You may add Your own copyright statement to Your modifications and\n  ~        may provide additional or different license terms and conditions\n  ~        for use, reproduction, or distribution of Your modifications, or\n  ~        for any such Derivative Works as a whole, provided Your use,\n  ~        reproduction, and distribution of the Work otherwise complies with\n  ~        the conditions stated in this License.\n  ~\n  ~     5. Submission of Contributions. Unless You explicitly state otherwise,\n  ~        any Contribution intentionally submitted for inclusion in the Work\n  ~        by You to the Licensor shall be under the terms and conditions of\n  ~        this License, without any additional terms or conditions.\n  ~        Notwithstanding the above, nothing herein shall supersede or modify\n  ~        the terms of any separate license agreement you may have executed\n  ~        with Licensor regarding such Contributions.\n  ~\n  ~     6. Trademarks. This License does not grant permission to use the trade\n  ~        names, trademarks, service marks, or product names of the Licensor,\n  ~        except as required for reasonable and customary use in describing the\n  ~        origin of the Work and reproducing the content of the NOTICE file.\n  ~\n  ~     7. Disclaimer of Warranty. Unless required by applicable law or\n  ~        agreed to in writing, Licensor provides the Work (and each\n  ~        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n  ~        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n  ~        implied, including, without limitation, any warranties or conditions\n  ~        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n  ~        PARTICULAR PURPOSE. You are solely responsible for determining the\n  ~        appropriateness of using or redistributing the Work and assume any\n  ~        risks associated with Your exercise of permissions under this License.\n  ~\n  ~     8. Limitation of Liability. In no event and under no legal theory,\n  ~        whether in tort (including negligence), contract, or otherwise,\n  ~        unless required by applicable law (such as deliberate and grossly\n  ~        negligent acts) or agreed to in writing, shall any Contributor be\n  ~        liable to You for damages, including any direct, indirect, special,\n  ~        incidental, or consequential damages of any character arising as a\n  ~        result of this License or out of the use or inability to use the\n  ~        Work (including but not limited to damages for loss of goodwill,\n  ~        work stoppage, computer failure or malfunction, or any and all\n  ~        other commercial damages or losses), even if such Contributor\n  ~        has been advised of the possibility of such damages.\n  ~\n  ~     9. Accepting Warranty or Additional Liability. While redistributing\n  ~        the Work or Derivative Works thereof, You may choose to offer,\n  ~        and charge a fee for, acceptance of support, warranty, indemnity,\n  ~        or other liability obligations and/or rights consistent with this\n  ~        License. However, in accepting such obligations, You may act only\n  ~        on Your own behalf and on Your sole responsibility, not on behalf\n  ~        of any other Contributor, and only if You agree to indemnify,\n  ~        defend, and hold each Contributor harmless for any liability\n  ~        incurred by, or claims asserted against, such Contributor by reason\n  ~        of your accepting any such warranty or additional liability.\n  ~\n  ~     END OF TERMS AND CONDITIONS\n  ~\n  ~     APPENDIX: How to apply the Apache License to your work.\n  ~\n  ~        To apply the Apache License to your work, attach the following\n  ~        boilerplate notice, with the fields enclosed by brackets \"[]\"\n  ~        replaced with your own identifying information. (Don't include\n  ~        the brackets!)  The text should be enclosed in the appropriate\n  ~        comment syntax for the file format. We also recommend that a\n  ~        file or class name and description of purpose be included on the\n  ~        same \"printed page\" as the copyright notice for easier\n  ~        identification within third-party archives.\n  ~\n  ~     Copyright 2016 Alibaba Group\n  ~\n  ~     Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~     you may not use this file except in compliance with the License.\n  ~     You may obtain a copy of the License at\n  ~\n  ~         http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~     Unless required by applicable law or agreed to in writing, software\n  ~     distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~     See the License for the specific language governing permissions and\n  ~     limitations under the License.\n  ~\n  ~\n  -->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com.taobao.demo\" android:versionCode=\"1\" android:versionName=\"1.0.0\">\n  <uses-sdk android:minSdkVersion=\"14\" android:targetSdkVersion=\"25\"/>  \n  <!-- -->  \n  <uses-permission android:name=\"android.permission.INTERNET\"/>  \n  <meta-data android:name=\"android.support.VERSION\" android:value=\"25.3.0\"/>  \n  <application android:name=\"android.taobao.atlas.startup.AtlasBridgeApplication\" android:allowBackup=\"true\" android:icon=\"@mipmap/ic_launcher\" android:label=\"Atlas\" android:supportsRtl=\"true\"> \n    <activity android:name=\"com.taobao.demo.MainActivity\" android:label=\"@string/app_name\" android:theme=\"@style/AppTheme.NoActionBar\"/>  \n    <activity android:name=\"com.taobao.demo.UpdateDemoActivity\" android:label=\"@string/title_activity_scrolling\" android:theme=\"@style/AppTheme.NoActionBar\"/>  \n    <activity android:name=\"com.taobao.demo.RemoteDemoActivity\" android:label=\"@string/title_activity_update\" android:theme=\"@style/AppTheme.NoActionBar\"/>  \n    <activity android:name=\"com.taobao.secondbundlelibrary.SecondbundleShareActivity\" android:theme=\"@style/Theme.AppCompat.Light\">\n      <meta-data android:name=\"bundleLocation\" android:value=\"com.taobao.secondbundlelibrary\"/>\n    </activity>  \n    <activity android:name=\"com.taobao.secondbundle.SecondBundleActivity\" android:theme=\"@style/AppTheme.NoActionBar\">\n      <meta-data android:name=\"bundleLocation\" android:value=\"com.taobao.secondbundle\"/>\n    </activity>  \n    <activity android:name=\"com.taobao.remotebunle.RemoteBundleActivity\" android:theme=\"@style/AppTheme.NoActionBar\">\n      <meta-data android:name=\"bundleLocation\" android:value=\"com.taobao.remotebunle\"/>\n    </activity>  \n    <activity android:name=\"com.taobao.firstbundle.FirstBundleActivity\" android:theme=\"@style/AppTheme.NoActionBar\">\n      <meta-data android:name=\"bundleLocation\" android:value=\"com.taobao.firstbundle\"/>\n    </activity>  \n    <service android:name=\"com.taobao.firstbundle.FirstBundleService\" android:enabled=\"true\" android:exported=\"true\">\n      <meta-data android:name=\"bundleLocation\" android:value=\"com.taobao.firstbundle\"/>\n    </service>  \n    <activity android:name=\"com.taobao.splashscreen.WelcomeActivity\" android:configChanges=\"orientation|keyboardHidden|screenSize\" android:theme=\"@style/FullscreenTheme\"> \n      <intent-filter> \n        <action android:name=\"android.intent.action.MAIN\"/>  \n        <category android:name=\"android.intent.category.LAUNCHER\"/> \n      </intent-filter> \n    </activity>  \n    <activity android:name=\"com.taobao.middleware.ItemListActivity\" android:label=\"@string/title_item_list\" android:theme=\"@style/AppTheme.NoActionBar\"/>  \n    <activity android:name=\"com.taobao.middleware.ItemDetailActivity\" android:label=\"@string/title_item_detail\" android:parentActivityName=\"com.taobao.middleware.ItemListActivity\" android:theme=\"@style/AppTheme.NoActionBar\"> \n      <meta-data android:name=\"android.support.PARENT_ACTIVITY\" android:value=\"com.taobao.middleware.ItemListActivity\"/> \n    </activity>\n    <receiver android:name=\"com.taobao.atlas.update.AwoPatchReceiver\"> \n      <intent-filter> \n        <action android:name=\"com.taobao.atlas.intent.PATCH_APP\"/> \n      </intent-filter>  \n      <intent-filter> \n        <action android:name=\"com.taobao.atlas.intent.DEX_PATCH_APP\"/> \n      </intent-filter>  \n      <intent-filter> \n        <action android:name=\"com.taobao.atlas.intent.ROLLBACK_PATCH\"/> \n      </intent-filter>  \n      <intent-filter> \n        <action android:name=\"com.taobao.atlas.intent.ROLLBACK_DEX_PATCH\"/> \n      </intent-filter> \n    </receiver>\n    <service android:name=\"com.taobao.test.TCMSService\" android:exported=\"true\" android:process=\"com.taobao.test\">\n      <meta-data android:name=\"bundleLocation\" android:value=\"com.alibaba.sdk.android\"/>\n    </service>\n    <provider android:name=\"com.taobao.test.MsgProvider\" android:authorities=\"com.taobao.test\" android:exported=\"false\" android:multiprocess=\"true\" android:process=\":messagebox\"/>\n    <service android:name=\"com.taobao.android.runtime.Dex2OatService\" android:process=\":dex2oat\"/>  \n    <meta-data android:name=\"REAL_APPLICATION\" android:value=\"com.taobao.demo.DemoApplication\"/>\n    <meta-data android:name=\"multidex_enable\" android:value=\"true\"/>\n  </application> \n</manifest>\n"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/test/resources/bundleInfoList.json",
    "content": "[\n  {\n    \"activities\":[],\n    \"applicationName\":\"com.taobao.dynamic.test.DynamicApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.dynamic.test\",\n    \"receivers\":[\n      \"com.taobao.dynamic.test.DynamicVerifyReceiver\",\n      \"com.taobao.dynamic.test.AndFixTestReceiver\"\n    ],\n    \"services\":[],\n    \"version\":\"1.0.0@1.0.0\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tao.rate.ui.commit.MainRateActivity\",\n      \"com.taobao.tao.rate.ui.commit.MainRateLoadingActivity\",\n      \"com.taobao.tao.rate.ui.photo.PhotoPreviewActivity\",\n      \"com.taobao.tao.rate.ui.photo.UploadPhotoPreviewActivity\",\n      \"com.taobao.tao.rate.ui.commit.AppendRateActivity\",\n      \"com.taobao.tao.rate.ui.commit.RateEditActivity\",\n      \"com.taobao.tao.rate.ui.myrate.MyRateActivity\",\n      \"com.taobao.tao.rate.ui.shoprate.RateShopDetailActivity\",\n      \"com.taobao.tao.rate.ui.ratedetail.RateDetailActivity\",\n      \"com.taobao.tao.rate.ui.photo.TakePhotoActivity\",\n      \"com.taobao.tao.rate.ui.ShowCommandActivity\",\n      \"com.taobao.tao.rate.ui.commit.NavRateSucessActivity\",\n      \"com.taobao.tao.rate.ui.RateVideoActivity\",\n      \"com.taobao.socialsdk.activity.CommentListActivity\",\n      \"com.taobao.socialsdk.activity.ImageDisplayActivity\",\n      \"com.taobao.socialsdk.activity.HistroyActivity\",\n      \"com.taobao.socialsdk.activity.CustomCommentListActivity\",\n      \"com.taobao.android.social.activity.CommentListActivity\",\n      \"com.taobao.android.social.activity.CommentAllListActivity\",\n      \"com.taobao.android.social.activity.CommentDetailActivity\",\n      \"com.taobao.android.social.activity.CommentReplyActivity\",\n      \"com.taobao.tao.flexbox.layoutmanager.preview.ComponentPreviewActivity\",\n      \"com.taobao.ugc.kit.activity.PreviewActivity\",\n      \"com.taobao.ugc.mini.activity.MiniPublishActivity\",\n      \"com.taobao.ugc.mini.activity.MiniPopupActivity\",\n      \"com.taobao.ugc.kit.activity.PreviewActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.rate.RateApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.dynamic\",\n      \"com.taobao.taobao.home\",\n      \"com.taobao.avplayer\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"\",\n    \"pkgName\":\"com.taobao.trade.rate\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.socialsdk.SocialService\",\n      \"com.taobao.social.sdk.jsbridge.SocialJsBridgeService\",\n      \"com.taobao.ugc.mini.service.MicroPublishService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@2.2.2.17\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.ton.TONMainActivity\"\n    ],\n    \"applicationName\":\"com.taobao.ton.TONApplocation\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.ton\",\n    \"receivers\":[],\n    \"services\":[],\n    \"version\":\"1.0.0@1.3.0.0\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.luaview.activity.LuaViewActivity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.ju.luaview\",\n    \"receivers\":[],\n    \"services\":[],\n    \"version\":\"1.0.0@5.12.0.16\"\n  },\n  {\n    \"activities\":[\n      \"com.huawei.android.pushselfshow.permission.RequestPermissionsActivity\"\n    ],\n    \"applicationName\":\"com.taobao.huawei.HuaWeiApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.huawei\",\n    \"receivers\":[\n      \"org.android.agoo.huawei.HuaWeiReceiver\"\n    ],\n    \"services\":[],\n    \"version\":\"1.0.0@1.1.3\"\n  },\n  {\n    \"activities\":[\n      \"com.alibaba.security.biometrics.face.auth.FaceLivenessActivity\",\n      \"com.alibaba.security.biometrics.face.auth.FaceCaptchaActivity\",\n      \"com.alibaba.security.biometrics.face.auth.view.FaceLivenessNavActitity\",\n      \"com.alibaba.security.biometrics.face.auth.FaceActivity\",\n      \"com.alibaba.security.biometrics.face.auth.FaceLivenessActivity\",\n      \"com.alibaba.security.biometrics.face.auth.FaceCaptchaActivity\",\n      \"com.alibaba.security.biometrics.face.auth.view.FaceLivenessNavActitity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.alibaba.security.biometrics.face\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.alibaba.security.biometrics.aidl.AuthAidlService\"\n    ],\n    \"version\":\"1.0.0@1.5.1.1\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tao.mytaobao.MyTaoBaoActivity\",\n      \"com.taobao.tao.DeliveryManageActivity\",\n      \"com.taobao.mytaobao.setting.TaobaoSettingActivity\",\n      \"com.taobao.mytaobao.setting.UpdateSnsNickActivity\",\n      \"com.taobao.mytaobao.setting.AboutTaobaoActivity\",\n      \"com.taobao.mytaobao.setting.UserProfileActivity\",\n      \"com.taobao.mytaobao.setting.AccountSecurityActivity\",\n      \"com.taobao.mytaobao.setting.GeneralSettingActivity\",\n      \"com.taobao.tao.bindcard.BindCardActivity\",\n      \"com.taobao.mytaobao.homepage.MytaobaoUserGuideActivity\",\n      \"com.taobao.tao.mytaobao.AllAppsActivity\",\n      \"com.taobao.tao.mytaobao.TempOneActivity\",\n      \"com.taobao.tao.mytaobao.TempTwoActivity\",\n      \"com.taobao.mytaobao.editorpage.CardEditActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.MytaobaoApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.android.capsule\",\n      \"com.taobao.acds\",\n      \"com.taobao.trade.rate\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"我的淘宝\",\n    \"pkgName\":\"com.taobao.mytaobao\",\n    \"receivers\":[\n      \"com.taobao.tao.mytaobao.MytaobaoLifeBroadCastReceiver\",\n      \"com.taobao.tao.mytaobao.logistic.LogisticReceiver\"\n    ],\n    \"services\":[\n      \"com.taobao.tao.diagnose.DiagnoseService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@4.0.7.1\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.detail.rate.RateViewPagerActivity\",\n      \"com.taobao.detail.rate.ImageViewActivity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.detail.rate\",\n    \"receivers\":[],\n    \"services\":[],\n    \"version\":\"1.0.0@1.1.0.8\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.ju.android.ui.main.TabMainActivity\",\n      \"com.taobao.ju.android.jutou.JutouActivity\",\n      \"com.taobao.ju.android.reserve.JuReserveActivity1\",\n      \"com.taobao.ju.android.reserve.JuReserveActivity2\",\n      \"com.taobao.ju.android.reserve.JuReserveActivity3\",\n      \"com.taobao.ju.android.reserve.JuReserveActivity4\",\n      \"com.taobao.ju.android.voice.VoiceRecognizeActivity\",\n      \"com.taobao.ju.android.ui.main.HomeTabActivity\",\n      \"com.taobao.ju.android.search.view.SearchActivity\",\n      \"com.taobao.ju.android.homepage.HomeActivity\",\n      \"com.taobao.ju.android.luaview.activity.LuaViewActivity\",\n      \"com.taobao.ju.android.luaview.activity.LuaOrH5RouterActivity\",\n      \"com.taobao.ju.android.ui.common.JuWindVaneActivity\",\n      \"com.taobao.ju.android.juplugin.customtitle.ChannelImageTitleActivity\",\n      \"com.taobao.ju.android.ui.main.MyProfileActivity\",\n      \"com.taobao.ju.android.luaview.activity.LuaViewActivity\",\n      \"com.taobao.ju.android.luaview.activity.LuaOrH5RouterActivity\"\n    ],\n    \"applicationName\":\"com.taobao.ju.android.TaoApp\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.relationship\",\n      \"com.taobao.ju.luaview\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"聚划算\",\n    \"pkgName\":\"com.taobao.ju.android\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.ju.android.service.JuIntentService\",\n      \"com.taobao.ju.android.luaview.global.JuLuaViewService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@ju-tao-plugin-4.9.0.2\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.pirateengine.isvcontainer.ChestEggsActivity\",\n      \"com.taobao.pirateengine.isvcontainer.ISVActivity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.pirateengine\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.pirateengine.aidl.PirateEngineService\"\n    ],\n    \"version\":\"1.0.0@2.2.3\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.alijk.activity.MainBoardActivity\",\n      \"com.taobao.alijk.activity.ICWebviewActivity\",\n      \"android.taobao.windvane.runtimepermission.PermissionActivity\"\n    ],\n    \"applicationName\":\"com.taobao.alijk.AlijkTaobaoApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.headline\",\n      \"com.taobao.login4android\",\n      \"com.taobao.dynamic\",\n      \"com.taobao.taobao.alipay\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":false,\n    \"md5\":\"\",\n    \"name\":\"阿里健康\",\n    \"pkgName\":\"com.taobao.alijk.entry\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@1.0.0.3\"\n  },\n  {\n    \"activities\":[],\n    \"applicationName\":\"com.taobao.acds.ACDSApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.acds\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.acds.compact.ACDSBusinessService\",\n      \"com.taobao.acds.compact.AccsACDSService\"\n    ],\n    \"version\":\"1.0.0@3.3.9.2\"\n  },\n  {\n    \"activities\":[],\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.android.msoa\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.android.msoa.MSOADynamicJsbridgeService\"\n    ],\n    \"version\":\"1.0.0@1.0.9.2\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.android.headline.ui.HeadlineMainActivity\",\n      \"com.taobao.android.headline.broswer.BrowserActivity\",\n      \"com.taobao.android.headline.common.imagepreview.ImagePreviewActivity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.taobao.home\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"淘宝头条\",\n    \"pkgName\":\"com.taobao.headline\",\n    \"receivers\":[\n      \"com.taobao.nbcache.CacheRebootReceiver\"\n    ],\n    \"services\":[\n      \"com.taobao.android.headline.jsbridge.DynamicJsbridgeService\",\n      \"com.taobao.nbcache.service.NBCacheService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@2.8.2.11\"\n  },\n  {\n    \"activities\":[],\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.appfrmbundle\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"\",\n    \"pkgName\":\"com.taobao.tao.powermsg\",\n    \"receivers\":[\n      \"com.taobao.tao.powermsg.PowerMsgReceiver\"\n    ],\n    \"services\":[\n      \"com.taobao.tao.powermsg.outter.PowerMsg4WXService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@1.1.4.1\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.taolive.TaoLiveVideoActivity\",\n      \"com.taobao.taolive.TaoLiveLinkLiveGameActivity\",\n      \"com.taobao.taolive.TaoLiveHomepageActivity\",\n      \"com.taobao.taolive.TaoLiveSearchActivity\",\n      \"com.taobao.taolive.TaoLiveTagActivity\",\n      \"com.taobao.taolive.TaoLiveAnchorActivity\",\n      \"com.taobao.taolive.TaoLiveAnchorTagActivity\",\n      \"com.taobao.taolive.TaoLiveFollowListActivity\",\n      \"com.taobao.taolive.TaoLiveAnchorRecordActivity\",\n      \"com.taobao.taolive.ReserveActivity01\",\n      \"com.taobao.taolive.ReserveActivity02\",\n      \"com.taobao.taolive.ReserveActivity03\",\n      \"com.taobao.taolive.ReserveActivity04\",\n      \"com.taobao.taolive.ReserveActivity05\",\n      \"com.taobao.taolive.ReserveActivity06\",\n      \"com.taobao.taolive.TaoLivePreListActivity\",\n      \"com.taobao.taolive.TaoLiveSliceActivity\",\n      \"com.taobao.taolive.TaoLiveScreenRecordPreviewActivity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.wangxin\",\n      \"com.taobao.avplayer\",\n      \"com.taobao.tao.powermsg\",\n      \"com.taobao.appfrmbundle\",\n      \"com.taobao.taobao.home\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"直播\",\n    \"pkgName\":\"com.taobao.taolive\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.tbliveweexvideo.TBLiveWeexService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@1.0.10.35\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.android.map.SimpleLocationActivity\",\n      \"com.taobao.android.map.LocateAddressActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.TaoApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"\"\n    ],\n    \"desc\":\"手淘地图模块用来为您在地图上显示店面的具体位置\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"手淘地图模块\",\n    \"pkgName\":\"com.taobao.taobao.map\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@2.0.8\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.taoguide.minidetail.MiniDetailActivity\",\n      \"com.taobao.taoguide.ArcticInterestActivity\",\n      \"com.taobao.taoguide.ArcticListActivity\",\n      \"com.taobao.taoguide.ArcticSearchActivity\",\n      \"com.taobao.taoguide.AlbumListActivity\",\n      \"com.taobao.taoguide.specialdetail.SpeciallistDetailActivity\",\n      \"com.taobao.taoguide.minidetail.ImageSliderActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.TaoApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"\"\n    ],\n    \"desc\":\"@string/taoguide_desc\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"@string/taoguide_label\",\n    \"pkgName\":\"com.taobao.taoguide\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@2.6.8.29\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.mother.babyprofile.ui.MyBabyActivity\",\n      \"com.taobao.mother.babyprofile.ui.ProfileEditActivity\",\n      \"com.taobao.mother.toolkit.ui.RaiseActivity\",\n      \"com.taobao.mother.toolkit.ui.FoodActivity\",\n      \"com.taobao.mother.toolkit.ui.PooActivity\",\n      \"com.taobao.mother.toolkit.ui.SleepActivity\",\n      \"com.taobao.mother.toolkit.ui.HistoryActivity\"\n    ],\n    \"applicationName\":\"com.taobao.mother.compat.base.MomApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.android.newtrade\",\n      \"com.taobao.android.detail\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"\",\n    \"pkgName\":\"com.taobao.mother\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@0.0.3.7\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.update.lightapk.storagespace.SpaceActivity\",\n      \"com.taobao.update.lightapk.BundleNotFoundActivity\",\n      \"com.taobao.test.UpdateSettingsActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.update.UpdateApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.tao.update\",\n    \"receivers\":[\n      \"com.taobao.atlas.update.AwoPatchReceiver\",\n      \"com.taobao.update.bundle.BundleInstalledExitAppReceiver\",\n      \"com.taobao.update.test.DynamicTestReceiver\",\n      \"com.taobao.update.test.AndFixTestReceiver\",\n      \"com.taobao.update.test.ApkTestReceiver\"\n    ],\n    \"services\":[\n      \"com.taobao.atlas.dexmerge.DexMergeService\"\n    ],\n    \"version\":\"1.0.0@5.6.1.32\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.TaoRecordVideoActivity\",\n      \"com.taobao.GuangRecordVideoActivity\",\n      \"com.taobao.GuangFilterVideoActivity\",\n      \"com.taobao.TaoPlayRecordVideoActivity\",\n      \"com.taobao.URLDispatchActivity\",\n      \"com.taobao.TaoVideoFilterActivity\",\n      \"com.im.IMRecordVideoActivity\",\n      \"com.im.IMPlayRecordVideoActivity\"\n    ],\n    \"applicationName\":\"com.taobao.TBAVRecorderApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":false,\n    \"pkgName\":\"com.taobao.taorecorder\",\n    \"receivers\":[\n      \"com.im.av.logic.manage.IMSTMtopAVUploadReceiver\"\n    ],\n    \"services\":[],\n    \"version\":\"1.0.0@2.0.13.11\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.guang.activity.EffectActivity\",\n      \"com.taobao.guang.activity.GuangDetailActivity\",\n      \"com.taobao.guang.activity.ImageShowerActivity\",\n      \"com.taobao.guang.activity.PublishH5Activity\",\n      \"com.taobao.ishopping.detail.ui.activity.DetailActivity\",\n      \"com.taobao.guang.activity.EmptyTempActivity1\",\n      \"com.taobao.guang.activity.EmptyTempActivity2\",\n      \"com.taobao.guang.activity.EmptyTempActivity3\",\n      \"com.taobao.guang.activity.EmptyTempActivity4\",\n      \"com.taobao.guang.activity.EmptyTempActivity5\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.guang\",\n    \"receivers\":[],\n    \"services\":[],\n    \"version\":\"1.0.0@2.2.3.3\"\n  },\n  {\n    \"activities\":[],\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.alivfssdk.monitor\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.alivfssdk.monitor.AVFSMonitorService\"\n    ],\n    \"version\":\"1.0.0@2.1.2.4\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tao.talent.publish.PublishNewFeedActivity\",\n      \"com.taobao.tao.talent.picker.PublishAddLocationActivity\",\n      \"com.taobao.tao.talent.picker.PublishAddTagActivity\",\n      \"com.taobao.tao.talent.main.TalentMainActivity\",\n      \"com.taobao.tao.talent.account.DarenAccountActivity\",\n      \"com.taobao.tao.talent.now.NowActivity\",\n      \"com.taobao.tao.talent.feed.FeedDetailActivity\",\n      \"com.taobao.tao.talent.search.SearchResultActivity\",\n      \"com.taobao.tao.talent.taoke.TaokeActivity\",\n      \"com.taobao.tao.talent.search.TagSearchActivity\",\n      \"com.taobao.tao.talent.detail.DarenDetailActivity\",\n      \"com.taobao.wireless.publisher.activity.PublishH5Activity\",\n      \"com.taobao.wireless.publisher.activity.PublishTransitiveActivity\",\n      \"com.taobao.wireless.publisher.component.goods.GoodsPickActivity\",\n      \"com.taobao.wireless.publisher.activity.PublishEditActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.talent.TalentApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.headline\",\n      \"com.taobao.relationship\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"淘宝达人\",\n    \"pkgName\":\"com.taobao.talent\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@1.8.0.80\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.android.tbcatch_android.TBCatchWeexActivity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.dynamic\",\n      \"com.taobao.android.gmlab\",\n      \"com.taobao.tbarmagic\",\n      \"com.taobao.weappplus\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"\",\n    \"pkgName\":\"com.taobao.android.tbcatch\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.android.tbcatch_android.weex.module.TBCatchAccsModule\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@1.0.2.31\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.lifeservice.home2.LifeHomeActivity\",\n      \"com.taobao.lifeservice.addrsearch.activity.ChangeLocationAddressActivity\",\n      \"com.taobao.lifeservice.addrmanager.HomeAddressBookActivity\",\n      \"com.taobao.lifeservice.addrmanager.HomeAddAddressActivity\",\n      \"com.taobao.lifeservice.addrmanager.HomeAddressSearchActivity\",\n      \"com.taobao.lifeservice.addrmanager.HomeEditAddressActivity\",\n      \"com.taobao.lifeservice.addrmanager.HomeMapLocationActivity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.taobao.map\",\n      \"com.taobao.dynamic\",\n      \"com.taobao.taobao.alipay\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"\",\n    \"pkgName\":\"com.taobao.lifeservice\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@1.4.5.32\"\n  },\n  {\n    \"activities\":[],\n    \"applicationName\":\"com.taobao.appfrmbundle.AppfrmApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.appfrmbundle\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.appfrmbundle.mkt.AccsReceiverService\"\n    ],\n    \"version\":\"1.0.0@0.2.1.3\"\n  },\n  {\n    \"activities\":[],\n    \"applicationName\":\"com.taobao.xiaomi.XiaoMiApplication\",\n    \"contentProviders\":[\n      \"com.google.firebase.provider.FirebaseInitProvider\"\n    ],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.xiaomi\",\n    \"receivers\":[\n      \"org.android.agoo.xiaomi.MiPushBroadcastReceiver\",\n      \"com.google.firebase.iid.FirebaseInstanceIdReceiver\",\n      \"com.google.firebase.iid.FirebaseInstanceIdInternalReceiver\"\n    ],\n    \"services\":[\n      \"com.xiaomi.mipush.sdk.PushMessageHandler\",\n      \"com.xiaomi.mipush.sdk.MessageHandleService\",\n      \"com.google.firebase.messaging.FirebaseMessagingService\",\n      \"org.android.agoo.gcm.AgooFirebaseInstanceIDService\",\n      \"org.android.agoo.gcm.AgooFirebaseMessagingService\",\n      \"com.google.firebase.iid.FirebaseInstanceIdService\"\n    ],\n    \"version\":\"1.0.0@1.2.5\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.search.searchdoor.SearchDoorActivity\",\n      \"com.taobao.search.common.SearchInShopRouteActivity\",\n      \"com.taobao.search.mmd.SearchResultActivity\",\n      \"com.taobao.search.inshopsearch.InShopSearchResultActivity\",\n      \"com.taobao.search.mmd.onesearch.OnesearchNxActivity\",\n      \"com.taobao.search.mmd.SearchLandingActivity\",\n      \"com.taobao.search.common.chitu.ChituPanelActivity\",\n      \"com.taobao.search.inshopsearch.InShopSearchDoorActivty\",\n      \"com.taobao.search.nx.CatmapActivity\",\n      \"com.taobao.search.mmd.SearchReservedActivity\"\n    ],\n    \"applicationName\":\"com.taobao.search.common.SearchApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.speech\",\n      \"com.taobao.avplayer\",\n      \"com.taobao.appfrmbundle\",\n      \"com.taobao.dynamic\",\n      \"com.etao.feimagesearch\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"\",\n    \"pkgName\":\"com.taobao.search\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@3.7.0.2\"\n  },\n  {\n    \"activities\":[],\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.taobao.home\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"\",\n    \"pkgName\":\"com.taobao.android.gmlab\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@1.0.4.20\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tao.msgcenter.activity.MsgCenterCategoryActivity\",\n      \"com.taobao.wangxin.activity.ChatActivity\",\n      \"com.taobao.tao.msgcenter.activity.AmpMsgListActivity\",\n      \"com.taobao.tao.msgcenter.activity.AmpMsgLayerActivity\",\n      \"com.taobao.wangxin.activity.WXChatLayerActivity\",\n      \"com.taobao.tao.msgcenter.activity.MyTaoAccountActivity\",\n      \"com.taobao.tao.msgcenter.activity.OfficialMsgListActivity\",\n      \"com.taobao.tao.msgcenter.activity.MsgSettingsActivity\",\n      \"com.taobao.tao.msgcenter.activity.PrivateSettingsActivity\",\n      \"com.taobao.tao.msgcenter.activity.MsgCenterShareGoodsActivity\",\n      \"com.taobao.tao.msgcenter.activity.MsgCenterShareShopActivity\",\n      \"com.taobao.tao.msgcenter.activity.MyTaoFriendCodeActivity\",\n      \"com.taobao.tao.msgcenter.activity.MsgCenterGroupListActivity\",\n      \"com.taobao.tao.msgcenter.activity.MsgCenterFlodCvsListActivity\",\n      \"com.taobao.tao.msgcenter.activity.ServiceConfigActivity\",\n      \"com.taobao.tao.msgcenter.activity.GroupCodeConfirmActivity\",\n      \"com.taobao.tao.msgcenter.activity.ForwardingSendActivity\",\n      \"com.taobao.tao.msgcenter.activity.AddFriendEntryActivity\",\n      \"com.taobao.tao.msgcenter.activity.IMContactsListActivity\",\n      \"com.taobao.tao.msgcenter.activity.AddTaoFriendActivity\",\n      \"com.taobao.tao.msgcenter.activity.EditFriendNameActivity\",\n      \"com.taobao.tao.msgcenter.activity.IMMessageListViewActivity\",\n      \"com.taobao.wangxin.activity.WangxinActivity\",\n      \"com.taobao.tao.msgcenter.activity.NotifyJumpActivity\",\n      \"com.taobao.tao.msgcenter.activity.MsgCenterThirdPushActivity\",\n      \"com.taobao.wangxin.activity.FromWangxinActivity\",\n      \"com.taobao.tao.msgcenter.activity.GroupScanCodeResultActivity\",\n      \"com.taobao.tao.msgcenter.activity.MyTaoFriendScanCodeResultActivity\",\n      \"com.taobao.tao.relation.activity.HPMainActivity\",\n      \"com.taobao.wangxin.ui.video.IMVideoDetailActivity\",\n      \"com.taobao.tao.msgcenter.activity.ExpressionListActivity\",\n      \"com.taobao.tao.msgcenter.activity.PicConfirmActivity\",\n      \"com.taobao.tao.msgcenter.activity.GroupMemberEditorActivity\",\n      \"com.taobao.tao.msgcenter.activity.GroupNoticeEditActivity\",\n      \"com.taobao.tao.msgcenter.activity.GroupChatConfigActivity\",\n      \"com.taobao.tao.msgcenter.activity.PrivateChatConfigActivity\",\n      \"com.taobao.tao.msgcenter.activity.MsgCenterFriendActivity\",\n      \"com.taobao.tao.msgcenter.activity.MsgCenterUserNameEditActivity\",\n      \"com.taobao.tao.msgcenter.activity.FestivalCardEditActivity\",\n      \"com.taobao.tao.msgcenter.activity.TargetSelectActivity\",\n      \"com.taobao.tao.msgcenter.activity.SwipePopActivity\",\n      \"com.taobao.tao.msgcenter.activity.FestivalCardSelectActivity\",\n      \"com.taobao.tao.msgcenter.activity.ChatGoodsListActivity\",\n      \"com.taobao.tao.msgcenter.activity.WeexPageActivity\",\n      \"com.taobao.tao.msgcenter.activity.GroupChatMemberListActivity\",\n      \"com.taobao.tao.msgcenter.activity.GroupCodeActivity\",\n      \"com.taobao.tao.msgcenter.activity.MsgCenterErrorActivity\",\n      \"com.taobao.tao.msgcenter.activity.GroupJoinActivity\",\n      \"com.taobao.tao.relation.activity.HPRecentAccessActivity\",\n      \"com.taobao.tao.msgcenter.activity.HolderOneActivity\",\n      \"com.taobao.tao.msgcenter.activity.HolderTwoActivity\",\n      \"com.taobao.tao.msgcenter.activity.HolderThreeActivity\",\n      \"com.taobao.tao.msgcenter.activity.ShareGoodsSearchActivity\",\n      \"com.alibaba.mobileim.ui.PrivacyProtectionActivity\",\n      \"com.taobao.wangxin.ui.associatinginput.AssociatingInputSettingActivity\",\n      \"com.taobao.msg.opensdk.activity.UserNameEditActivity\",\n      \"com.alibaba.mobileim.ui.WxChattingActvity\",\n      \"com.alibaba.mobileim.ui.WxViewMergedForwardMsgActivity\",\n      \"com.alibaba.mobileim.ui.WxConversationActivity\",\n      \"com.alibaba.mobileim.ui.chat.MultiImageActivity\",\n      \"com.alibaba.mobileim.kit.imageviewer.ShowImageActivity\",\n      \"com.alibaba.mobileim.ui.multi.lightservice.MultiPickGalleryActivity\",\n      \"com.alibaba.mobileim.ui.selectfriend.SelectFriendsActivity\",\n      \"com.alibaba.mobileim.ui.FeedbackActvity\",\n      \"com.alibaba.mobileim.login.WaitProgresssActivity\",\n      \"com.alibaba.mobileim.kit.chat.EnlargeChattingTextActivity\",\n      \"com.alibaba.tcms.service.MonitorActivity\",\n      \"com.alibaba.mobileim.kit.video.IMPlayVideoDetailActivity\",\n      \"com.alibaba.mobileim.ui.web.CustomHybridActivity\",\n      \"com.alibaba.mobileim.appmonitor.floatview.FloatViewActivity\",\n      \"com.alibaba.mobileim.ui.PrivacyProtectionActivity\",\n      \"com.alibaba.wxlib.util.RequestPermissionActivity\",\n      \"com.alibaba.mobileim.expressionpkg.expressionpkgstore.ExpressionPkgsStoreActivity\",\n      \"com.alibaba.mobileim.expressionpkg.expressionpkgmanage.ExpressionPkgsManagerActivity\",\n      \"com.alibaba.mobileim.expressionpkg.expressionpkgdetail.ExpressionPkgDetailActivity\",\n      \"com.alibaba.mobileim.customexpression.CustomExpressionManageActivity\",\n      \"com.alibaba.mobileim.ui.videochat.VideoChatActivity\",\n      \"com.alibaba.mobileim.ui.hongbao.SendHongbaoActivity\",\n      \"com.alibaba.mobileim.ui.hongbao.OpenHongbaoActivity\",\n      \"com.alibaba.mobileim.ui.hongbao.MyHongbaoActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.msgcenter.outter.WxApplication\",\n    \"contentProviders\":[\n      \"com.taobao.tao.msgcenter.manager.provider.MsgProvider\"\n    ],\n    \"dependency\":[\n      \"com.taobao.weapp\",\n      \"com.taobao.appfrmbundle\",\n      \"com.taobao.detail.rate\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"旺信\",\n    \"pkgName\":\"com.taobao.wangxin\",\n    \"receivers\":[\n      \"com.taobao.tao.msgcenter.event.AgooAndWeitaoMsgReceiver\",\n      \"com.taobao.tao.msgcenter.outter.BundleLaunchReceiver\"\n    ],\n    \"services\":[\n      \"\",\n      \"com.taobao.tao.msgcenter.outter.MessageBoxAIDLService\",\n      \"com.taobao.tao.amp.remote.AccsReceiverCallback\",\n      \"com.alibaba.mobileim.channel.service.InetIOService\",\n      \"com.taobao.tao.msgcenter.outter.ContactsShareService\",\n      \"com.taobao.tao.msgcenter.outter.JsbridgeRegisterService\",\n      \"com.taobao.tao.msgcenter.custom.ChatDefaultService\",\n      \"com.alibaba.mobileim.appmonitor.tiptool.TooltipService\",\n      \"com.alibaba.tcms.service.TCMSService\",\n      \"com.alibaba.tcms.service.TCMSService$TCMSKernalService\",\n      \"com.alibaba.tcms.service.ListenerService\",\n      \"com.alibaba.tcms.service.TCMSService\",\n      \"com.alibaba.tcms.service.TCMSService$TCMSKernalService\",\n      \"com.alibaba.tcms.service.ListenerService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@3.3.11.12\"\n  },\n  {\n    \"activities\":[\n      \"com.alibaba.wdk.barcode.TxdBarcodeActivity\",\n      \"com.alibaba.wdk.barcode.TxdBarcodeBackup1Activity\",\n      \"com.alibaba.wdk.barcode.TxdBarcodeBackup2Activity\"\n    ],\n    \"applicationName\":\"com.alibaba.wdk.TxdApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"desc\":\"淘宝生鲜服务\",\n    \"isInternal\":true,\n    \"name\":\"淘鲜达\",\n    \"pkgName\":\"com.alibaba.wdk.txd\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.alibaba.wdk.barcode.TxdBarcodeService\",\n      \"com.alibaba.wdk.barcode.TxdBarcodeIntentService\"\n    ],\n    \"version\":\"1.0.0@1.0.9\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.htao.android.bundle.home.HtaoHomeActivity\"\n    ],\n    \"applicationName\":\"com.taobao.htao.android.HTaoApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.taobao.home\",\n      \"com.taobao.android.capsule\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"\",\n    \"pkgName\":\"com.taobao.android.htao\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@1.1.0.16\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.cloakroom.MyVirtualActivity\",\n      \"com.taobao.cloakroom.CloakRoomActivity\",\n      \"com.taobao.cloakroom.PhotoTipActivity\",\n      \"com.taobao.cloakroom.CloakSettingsActivity\",\n      \"com.taobao.cloakroom.WaittingActivity\",\n      \"com.taobao.cloakroom.FloatBuyActivity\",\n      \"com.taobao.armarker.activity.ARMarkerActivity\"\n    ],\n    \"applicationName\":\"com.taobao.armarker.ARMarkerApplocation\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.cloakroom\",\n    \"receivers\":[],\n    \"services\":[],\n    \"version\":\"1.0.0@1.5.0.8\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tao.coupon.detail.CouponDetailActivity\",\n      \"com.taobao.tao.common.CouponContainerActivity\",\n      \"com.taobao.tao.exclusive.list.ExclusiveActListActivity\",\n      \"com.taobao.tao.exclusive.detail.ExclusiveActDetailActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.TaoApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.android.scancode\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"卡券\",\n    \"pkgName\":\"com.taobao.coupon\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@2.4.2.4\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.favorites.NewFavoriteGoodsActivity\",\n      \"com.taobao.favorites.FavCategoryDetailInfoActivity\",\n      \"com.taobao.favorites.FavCategoryDetailActivity\",\n      \"com.taobao.favorites.FavAddItemActivity\",\n      \"com.taobao.favorites.FavChecklistDetailActivity\",\n      \"com.taobao.favorites.FavEditChecklistActivity\",\n      \"com.taobao.favorites.FavOtherActivity\",\n      \"com.taobao.favorites.FavSelectItemActivity\",\n      \"com.taobao.favorites.FavSelectTemplateActivity\",\n      \"com.taobao.favorites.components.category.offerout.FavCategoryAllActivity\",\n      \"com.taobao.favorites.components.category.offerout.FavCategoryPopupActivity\",\n      \"com.taobao.favorites.components.category.offerout.FavCategoryCreateActivity\"\n    ],\n    \"applicationName\":\"com.taobao.favorites.FavoriteApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.favorite\",\n    \"receivers\":[\n      \"com.taobao.favorites.NewFavoriteGoodsActivity$GoodsRefreshReceiver\"\n    ],\n    \"services\":[\n      \"com.taobao.favorites.service.FavContentService\",\n      \"com.taobao.favorites.service.FavGoodService\"\n    ],\n    \"version\":\"1.0.0@1.1.8.1\"\n  },\n  {\n    \"activities\":[],\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.tmall.wireless.tangram.plugin\",\n    \"receivers\":[],\n    \"services\":[],\n    \"version\":\"1.0.0@1.0.2.29\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.android.shop.activity.ShopHomePageActivity\",\n      \"com.taobao.android.shop.activity.ShopUrlRouterActivity\",\n      \"com.taobao.android.shop.activity.ShopCategoryActivity\",\n      \"com.taobao.tao.combo.ShopComboActivity\",\n      \"com.taobao.android.shop.activity.ShopWeexActivity\",\n      \"com.taobao.android.shop.activity.ShopLoftActivity\"\n    ],\n    \"applicationName\":\"com.taobao.android.shop.application.ShopApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.weapp\",\n      \"com.taobao.avplayer\",\n      \"com.taobao.search\",\n      \"com.taobao.relationship\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"店铺\",\n    \"pkgName\":\"com.taobao.shop\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@6.0.1.1\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.browser.BrowserActivity\",\n      \"com.taobao.browser.exbrowser.BrowserUpperActivity\",\n      \"com.taobao.browser.exbrowser.hardwareAcceleratedBrowser\",\n      \"com.taobao.browser.exbrowser.LandscapeBrowserActivity\",\n      \"com.taobao.browser.router.FromH5RouterActivity\",\n      \"com.taobao.browser.fragment.FragmentContainerActivity\",\n      \"com.taobao.browser.Activity.VideoPlayerActivity\",\n      \"com.taobao.browser.jsbridge.ui.CameraActivity\",\n      \"com.taobao.browser.jsbridge.ui.CityList\",\n      \"com.taobao.browser.jsbridge.ui.chooseImg.ImgFileListActivity\",\n      \"com.taobao.browser.jsbridge.ui.chooseImg.ImgsActivity\",\n      \"android.taobao.windvane.runtimepermission.PermissionActivity\"\n    ],\n    \"applicationName\":\"com.taobao.browser.BrowserApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.playbuddy\",\n      \"com.taobao.avplayer\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"browser\",\n    \"pkgName\":\"com.taobao.browser\",\n    \"receivers\":[],\n    \"services\":[\n      \"android.taobao.windvane.extra.jsbridge.WVACCSService\",\n      \"com.taobao.browser.jsbridge.DynamicJsbridgeService\",\n      \"com.taobao.playbudyy.gameplugin.danmu.DanmuCallbackService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@3.0.0.8\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.avplayer.DWActivity\",\n      \"com.taobao.avplayer.DWDanmaEditActivity\",\n      \"com.taobao.avplayer.AddCartProxyActivity\",\n      \"com.taobao.avplayer.detail.DWVideoDetailActivity\"\n    ],\n    \"applicationName\":\"com.taobao.avplayer.DWApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.taobao.home\",\n      \"com.taobao.tao.powermsg\",\n      \"com.taobao.relationship\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"视频互动\",\n    \"pkgName\":\"com.taobao.avplayer\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.avplayer.service.DWH5PluginService\",\n      \"com.taobao.avplayer.service.DWWXComponentService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@2.0.2.14\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tao.ocean.home.activity.OceanHomeActivity\",\n      \"com.taobao.tao.ocean.userhome.ui.UserHomeActivity\",\n      \"com.taobao.tao.ocean.userhome.ui.MyHomeActivity\",\n      \"com.taobao.tao.ocean.topic.ui.TopicActivity\",\n      \"com.taobao.tao.ocean.feed.ui.FeedDetailActivity\",\n      \"com.taobao.tao.ocean.community.ui.OceanCommunityActivity\",\n      \"com.taobao.tao.ocean.userhome.ui.MyFavTopicActivity\",\n      \"com.taobao.tao.ocean.userhome.ui.NewEliteTopicActivity\",\n      \"com.taobao.tao.ocean.post.acitvity.CreateTopicActivity\",\n      \"com.taobao.tao.ocean.community.ui.MyCommunityActivity\",\n      \"com.taobao.tao.ocean.search.ui.SearchActivity\",\n      \"com.taobao.tao.ocean.search.ui.SearchMoreCommunityActivity\",\n      \"com.taobao.ocean.video.OceanVideoPlayActivity\",\n      \"com.taobao.tao.ocean.post.acitvity.SelectCircleActivity\",\n      \"com.taobao.tao.ocean.post.acitvity.CreateCheckActivity\",\n      \"com.taobao.tao.ocean.qa.CreateQuestionActivity\",\n      \"com.taobao.tao.ocean.qa.RecommendProductActivity\",\n      \"com.taobao.tao.ocean.qa.AnswerQuestionActivity\",\n      \"com.taobao.tao.ocean.qa.QADetailActivity\",\n      \"com.taobao.tao.ocean.qa.QuestionListActivity\",\n      \"com.taobao.tao.ocean.qa.QuestionCommentDetailActivity\",\n      \"com.taobao.tao.ocean.community.ui.CommunityShareListActivity\",\n      \"com.taobao.tao.ocean.component.ComponentPreviewActivity\",\n      \"com.taobao.tao.ocean.energy.TransparentEnergyActivity\",\n      \"com.taobao.tao.ocean.dispatcher.DispatcherManager\",\n      \"com.taobao.tao.ocean.qa.RoundTableActivity\",\n      \"com.taobao.ugc.framework.UGCContainerActivity\",\n      \"com.taobao.ugc.activity.UGCPreviewActivity\",\n      \"com.taobao.ugc.framework.UGCLoadingActivity\",\n      \"com.taobao.ugc.activity.AnonymousActivity\",\n      \"com.taobao.reborn.ugc.activity.LoadingActivity\",\n      \"com.taobao.reborn.ugc.activity.ContainerActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.ocean.core.OceanApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.dynamic\",\n      \"com.taobao.trade.rate\",\n      \"com.taobao.speech\",\n      \"com.taobao.android.capsule\",\n      \"com.taobao.detail.rate\",\n      \"com.taobao.relationship\",\n      \"com.taobao.avplayer\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"社区\",\n    \"pkgName\":\"com.taobao.ocean\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@1.2.22.3\"\n  },\n  {\n    \"activities\":[\n      \"com.tmall.market.plugin.main.MainTabActivity\",\n      \"com.tmall.market.plugin.homepage.HomepageActivity\",\n      \"com.tmall.market.plugin.browser.BrowserActivity\",\n      \"com.tmall.market.plugin.address.CitySelectorActivity\",\n      \"com.tmall.market.plugin.placeholder.PlaceholderActivity1\",\n      \"com.tmall.market.plugin.placeholder.PlaceholderActivity2\",\n      \"com.tmall.market.plugin.main.MainTabActivity\",\n      \"com.tmall.market.plugin.homepage.HomepageActivity\",\n      \"com.tmall.market.plugin.browser.BrowserActivity\",\n      \"com.tmall.market.plugin.address.CitySelectorActivity\",\n      \"com.tmall.market.plugin.placeholder.PlaceholderActivity1\",\n      \"com.tmall.market.plugin.placeholder.PlaceholderActivity2\"\n    ],\n    \"applicationName\":\"com.taobao.android.market.plugin.MarketApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.tmall.wireless.plugin\",\n      \"com.tmall.wireless.tangram.plugin\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"\",\n    \"pkgName\":\"com.taobao.android.market.plugin\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.tmall.market.plugin.placeholder.PlaceholderService1\",\n      \"com.tmall.market.plugin.placeholder.PlaceholderService2\",\n      \"com.tmall.android.hotpot.main.CartService\",\n      \"com.tmall.android.hotpot.main.CartService\",\n      \"com.tmall.market.plugin.placeholder.PlaceholderService1\",\n      \"com.tmall.market.plugin.placeholder.PlaceholderService2\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@1.3.4.17\"\n  },\n  {\n    \"activities\":[\n      \"com.tmall.wireless.module.search.location.TMLocationSelectActivity\",\n      \"com.tmall.wireless.module.search.xbiz.input.activity.TMSearchInputActivity\",\n      \"com.tmall.wireless.module.search.searchResult.TMSearchResultActivity\",\n      \"com.tmall.wireless.module.search.xbiz.supermarket.TMSearchMarketActivity\",\n      \"com.tmall.wireless.module.search.xbiz.global.TMSearchGlobalActivity\",\n      \"com.tmall.wireless.module.category.TMNewCategoryActivity\",\n      \"com.tmall.wireless.module.search.xbiz.findsimilar.TMSearchFindSimilarActivity\",\n      \"com.tmall.wireless.module.search.components.TMSearchLandingPageActivity\",\n      \"com.tmall.abtest.debug.AbDebugActivity\",\n      \"com.tmall.oreo.debug.OreoDebugActivity\",\n      \"com.tmall.abtest.debug.AbDebugActivity\",\n      \"com.tmall.oreo.debug.OreoDebugActivity\"\n    ],\n    \"applicationName\":\"com.tmall.wireless.plugin.core.BaseApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.dynamic\",\n      \"com.taobao.weapp\",\n      \"com.tmall.wireless.tangram.plugin\"\n    ],\n    \"desc\":\"尚天猫，就购了\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"天猫\",\n    \"pkgName\":\"com.tmall.wireless.plugin\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.tmall.android.arscan.windvane.JSBridgeARGoScanService\",\n      \"com.tmall.android.arscan.windvane.JSBridgeARGoScanService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@1.0.9.28\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.ranger3.console.RangerConsoleActivity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.ranger\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.ranger.RangerService\",\n      \"com.taobao.ranger3.RangerACCSService\"\n    ],\n    \"version\":\"1.0.0@3.2.4.4\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.chargecenter.CenterTabActivity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.login4android\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"充值中心\",\n    \"pkgName\":\"com.taobao.chargecenter\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@2.3.0.7\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.interact.publish.activity.InteractsdkMainActivity\",\n      \"com.taobao.interact.publish.activity.ImageChoiceActivity\",\n      \"com.taobao.interact.publish.activity.ImageCaptrueActivity\",\n      \"com.taobao.interact.publish.activity.ImageGalleryActivity\",\n      \"com.taobao.interact.publish.activity.ImageCropActivity\",\n      \"com.taobao.interact.publish.activity.ImageFilterActivity\",\n      \"com.taobao.interact.publish.activity.ImageMultiActivity\",\n      \"com.taobao.interact.publish.activity.ImagePreviewActivity\"\n    ],\n    \"applicationName\":\"com.taobao.interact.publish.application.PublishApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.interact.publish\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.interact.publish.service.PublishService\",\n      \"com.taobao.interact.upload.service.UploadService\"\n    ],\n    \"version\":\"1.0.0@1.3.17.2\"\n  },\n  {\n    \"activities\":[],\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.playbuddy\",\n    \"receivers\":[],\n    \"services\":[],\n    \"version\":\"1.0.0@3.7.6\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.linkmanager.AlibcOpenActivity\",\n      \"com.taobao.linkmanager.AlibcAuthActivity\",\n      \"com.taobao.linkmanager.AlibcTransparentActivity\",\n      \"com.taobao.linkmanager.AlibcAuthCompatActivity\",\n      \"com.taobao.linkmanager.AlibcOauthActivity\",\n      \"com.taobao.linkmanager.AlibcBindActivity\",\n      \"com.taobao.linkmanager.AlibcHtmlActivity\",\n      \"com.taobao.linkmanager.AlibcWindvaneCompatActivity\",\n      \"com.taobao.linkmanager.AlibcEntranceActivity\",\n      \"com.taobao.linkmanager.debug.AlibcTestOpenAPIActivity\",\n      \"com.taobao.linkmanager.debug.AlibcTestActivity\",\n      \"com.taobao.flowcustoms.OutgoingIntermediateActivity\",\n      \"com.alibaba.alibclinkpartner.ui.ALPEntranceActivity\"\n    ],\n    \"applicationName\":\"com.taobao.linkmanager.LinkManagerApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.alibcpromotion\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"\",\n    \"pkgName\":\"com.taobao.linkmanager\",\n    \"receivers\":[\n      \"com.taobao.linkmanager.TaobaoStartReceiver\",\n      \"com.taobao.linkmanager.DeeplinkExecuteReceiver\"\n    ],\n    \"services\":[\n      \"com.taobao.linkmanager.auth.AlibcOpenService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@1.0.0.35\"\n  },\n  {\n    \"activities\":[\n      \"com.alipay.android.app.pay.MiniLaucherActivity\",\n      \"com.alipay.android.app.flybird.ui.window.FlybirdLocalViewActivity\",\n      \"com.alipay.android.app.ui.quickpay.window.MiniWebActivity\",\n      \"com.alipay.android.app.ui.quickpay.window.MiniPayActivity\",\n      \"com.alipay.android.app.flybird.ui.window.FlyBirdWindowActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.TaoApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.dynamic\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"极简支付\",\n    \"pkgName\":\"com.taobao.taobao.alipay\",\n    \"receivers\":[\n      \"com.alipay.android.app.LiveConnectReceiver\"\n    ],\n    \"services\":[\n      \"com.alipay.android.app.MspService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@3.3.8\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tao.homepage.MainActivity3\",\n      \"com.taobao.tao.homepage.preview.HomeTemplatePreviewActivity\",\n      \"com.taobao.tao.ad.AdNavActivity\",\n      \"com.taobao.tao.homepage.overlay.OverlayActivity\",\n      \"com.taobao.android.editionswitcher.EditionSwitcherActivity\",\n      \"com.taobao.tao.apass.ApassJsPicCropActivity\",\n      \"com.taobao.tao.apass.ApassPicCropActivity\",\n      \"com.taobao.mafia.engine.MafiaActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.homepage.HomeApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.taobao.home\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.taolive.FaceDetectorService\"\n    ],\n    \"version\":\"1.0.0@5.0.3.4\"\n  },\n  {\n    \"activities\":[],\n    \"applicationName\":\"com.taobao.android.capsule.CapsuleApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.android.capsule\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.rewardservice.sdk.plugin.DynamicJsbridgeService\",\n      \"com.taobao.android.favsdk.favtaobaouse.FavDynamicJsbridgeService\"\n    ],\n    \"version\":\"1.0.0@1.0.0.39\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.magicmirror.MagicMirrorActivity\",\n      \"com.taobao.magicmirror.MagicShoppingListActivity\",\n      \"com.taobao.magicmirror.MagicShareActivity\"\n    ],\n    \"applicationName\":\"com.taobao.magicmirror.application.MagicMirrorApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.android.newtrade\",\n      \"com.taobao.android.detail\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"试妆试戴\",\n    \"pkgName\":\"com.taobao.magicmirror\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.magicmirror.bridge.MagicMirrorService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@1.2.1.2\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.login4android.activity.LoginProxyActivity\",\n      \"com.taobao.login4android.activity.AlipaySSOResultActivity\",\n      \"com.taobao.android.sso.v2.ui.SsoAuthActivity\",\n      \"com.taobao.android.sso.v2.ui.SsoPlaceHolderActivity\",\n      \"com.ali.user.mobile.login.ui.UserLoginActivity\",\n      \"com.ali.user.mobile.login.ui.UserAccountActivity\",\n      \"com.ali.user.mobile.login.ui.AliUserLoginSMSActivity\",\n      \"com.ali.user.mobile.webview.WebViewActivity\",\n      \"com.ali.user.mobile.webview.WindVaneWebViewActivity\",\n      \"com.ali.user.mobile.ui.BackupActivity\",\n      \"com.ali.user.mobile.login.ui.BindActivity\",\n      \"com.ali.user.mobile.account.bind.TaobaoAccountBindActivity\",\n      \"com.ali.user.mobile.register.ui.AliUserRegisterActivity\",\n      \"com.ali.user.mobile.login.ui.PlaceHolderActivity\",\n      \"com.ali.user.mobile.webview.HtmlActivity\",\n      \"com.ali.user.mobile.register.ui.AliUserRegisterChoiceRegionActivity\",\n      \"com.ali.user.mobile.register.ui.AliUserRegisterSMSActivity\",\n      \"com.ali.user.mobile.webview.AliUserRegisterWebview\",\n      \"com.ali.user.mobile.register.ui.AliUserRegisterSetLoginPassword\",\n      \"com.ali.user.mobile.account.bind.NewAccountBindActivity\"\n    ],\n    \"applicationName\":\"com.taobao.login4android.LoginApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.dynamic\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"扫码登录\",\n    \"pkgName\":\"com.taobao.login4android\",\n    \"receivers\":[\n      \"com.taobao.login4android.monitor.DelayLoginReceiver\"\n    ],\n    \"services\":[\n      \"com.taobao.login4android.aidl.LoginService\",\n      \"com.taobao.android.sso.v2.service.LoginAccsService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@1.0.8.2\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.weex.WXActivity\",\n      \"com.taobao.weex.WXMultipleActivity\",\n      \"com.taobao.weex.WxBriefWvActivity\"\n    ],\n    \"applicationName\":\"com.taobao.weex.WXApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.browser\",\n      \"com.taobao.android.capsule\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"weex_bundle\",\n    \"pkgName\":\"com.taobao.weappplus\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@1.12.0.11\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tao.alipay.cashdesk.CashDeskActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.TaoApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.taobao.cashdesk\",\n    \"receivers\":[],\n    \"services\":[],\n    \"version\":\"1.0.0@2.6.1.4\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tao.contacts.share.ContactsImportActivity\",\n      \"com.taobao.tao.contacts.share.ShareMessageListViewActivity\",\n      \"com.taobao.share.view.WeiboShareActivity\",\n      \"com.taobao.share.view.MomoShareActivity\",\n      \"com.taobao.taobao.apshare.ShareEntryActivity\",\n      \"com.taobao.taobao.ddshare.DDShareActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.ContactsApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.tao.contacts\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.share.aidl.services.ShareCopyService\",\n      \"com.taobao.share.aidl.services.ShareBusinessService\",\n      \"com.taobao.share.aidl.services.SharePasswordService\",\n      \"com.taobao.share.aidl.services.ClipShareService\",\n      \"com.taobao.share.aidl.services.QRCodeParserService\",\n      \"com.taobao.share.aidl.services.ShareDecodeURLService\",\n      \"com.taobao.share.aidl.services.ShareJSRegisterService\"\n    ],\n    \"version\":\"1.0.0@2.8.1.5\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.trade.debug.TradeDebugActivity\",\n      \"com.taobao.trade.debug.TradeSettingActivity\",\n      \"com.taobao.trade.debug.TradeLogActivity\",\n      \"com.taobao.tao.purchase.activity.PurchaseActivity\",\n      \"com.taobao.tao.purchase.wdk.activity.WDKTradeActivity\",\n      \"com.taobao.order.list.OrderCoreListActivity\",\n      \"com.taobao.order.detail.ui.OrderCoreDetailActivity\",\n      \"com.taobao.order.list.OrderCoreSearchResultActivity\",\n      \"com.taobao.order.list.OrderListActivity\",\n      \"com.taobao.order.detail.ui.OrderDetailActivity\",\n      \"com.taobao.refundorder.RefundOrderListActivity\",\n      \"com.taobao.order.search.OrderSearchActivity\",\n      \"com.taobao.order.list.OrderSearchResultActivity\",\n      \"com.taobao.android.trade.cart.CartActivity\",\n      \"com.taobao.android.trade.cart.CartCoudanActivity\",\n      \"com.taobao.android.address.wrapper.activity.AddressEditorWrapperActivity_\",\n      \"com.taobao.android.address.wrapper.activity.AddressAddNewWrapperActivity_\",\n      \"com.taobao.android.address.wrapper.activity.AddressAreaWrapperActivity_\",\n      \"com.taobao.android.address.wrapper.activity.AddressPickerWrapperActivity_\",\n      \"com.taobao.android.address.wrapper.activity.AddressBookWrapperActivity_\"\n    ],\n    \"applicationName\":\"com.taobao.android.newtrade.NewTradeApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.cainiao\",\n      \"com.taobao.android.detail\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"交易\",\n    \"pkgName\":\"com.taobao.android.newtrade\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@2.3.6\"\n  },\n  {\n    \"activities\":[],\n    \"applicationName\":\"com.taobao.speech.SpeechApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.speech\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.speech.service.SearchSpeechService\"\n    ],\n    \"version\":\"1.0.0@1.0.1.6\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tao.RushPromotionMainActivity\",\n      \"com.taobao.tao.RemindedItemActivity\",\n      \"com.taobao.tao.rushpromotion.luaview.activity.LuaOrH5RouterActivity\",\n      \"com.taobao.tao.rushpromotion.luaview.activity.LuaViewActivity\",\n      \"com.taobao.tao.CategoryActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.RushPromotionApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.ju.luaview\"\n    ],\n    \"desc\":\"每天几十款1元秒杀尽在淘抢购!\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"淘抢购\",\n    \"pkgName\":\"com.taobao.rushpromotion\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@2.3.6.137\"\n  },\n  {\n    \"activities\":[\n      \"com.etao.feimagesearch.FEISCaptureActivity\",\n      \"com.etao.feimagesearch.FEISImageEditorActivity\",\n      \"com.etao.feimagesearch.album.FEISAlbumActivity\",\n      \"com.etao.feimagesearch.FEISJSBridgeEnterActivity\",\n      \"com.etao.feimagesearch.history.FEISHistoryActivity\",\n      \"com.etao.feimagesearch.search.SearchResultActivity\",\n      \"com.etao.feimagesearch.activities.FullPageOperateActivity\",\n      \"com.etao.feimagesearch.activities.ScanOperateActivity\"\n    ],\n    \"applicationName\":\"com.etao.feimagesearch.FEISApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.browser\",\n      \"com.taobao.search\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"拍照购\",\n    \"pkgName\":\"com.etao.feimagesearch\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@5.5.9.57\"\n  },\n  {\n    \"activities\":[],\n    \"applicationName\":\"com.alibaba.dynamic.DynamicApp\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.alibaba.dynamic.weex\",\n    \"receivers\":[],\n    \"services\":[],\n    \"version\":\"1.0.0@0.1.0.6\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.openmarket.OpenMarketChannelActivity\",\n      \"com.taobao.openmarket.OpenMarketTagActivity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"desc\":\"@string/openmarket_name\",\n    \"isInternal\":true,\n    \"name\":\"@string/openmarket_name\",\n    \"pkgName\":\"com.taobao.openmarket\",\n    \"receivers\":[],\n    \"services\":[],\n    \"version\":\"1.0.0@1.2.3.18\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.taobao.scancode.common.activity.ScancodeContainerActivity\",\n      \"com.taobao.taobao.scancode.barcode.util.ScancodeBrowserActivity\",\n      \"com.taobao.taobao.test.TestUrlNavActivity\",\n      \"com.taobao.taobao.scancode.barcode.activity.RecommendActivity\",\n      \"com.taobao.taobao.scancode.gateway.activity.ScancodeGatewayActivity\",\n      \"com.taobao.taobao.scancode.express.activity.ScancodeExpressActivity\",\n      \"com.taobao.taobao.scancode.history.activity.ScanHistoryActivity\"\n    ],\n    \"applicationName\":\"com.taobao.taobao.scancode.common.ScancodeApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.etao.feimagesearch\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"扫码\",\n    \"pkgName\":\"com.taobao.android.scancode\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.taobao.scancode.encode.aidlservice.EncodeService\",\n      \"com.alibaba.mtl.appmonitor.AppMonitorService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@3.0.9.17\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.android.vr.projects.vr520.VRPlayerActivity\",\n      \"com.taobao.android.vr.projects.weex.WeexUIActivity\",\n      \"com.taobao.android.vr.projects.vrtour.ReserveActivity\",\n      \"com.taobao.android.vrsupport.activity.common.BaseVRVideoActivity\",\n      \"com.taobao.android.vr.sdk.image.VRImageActivity\",\n      \"com.taobao.android.vr.projects.vrtour.VRActivity\",\n      \"com.taobao.android.vr.projects.buyplus.main.BuyPlusActivity\",\n      \"com.taobao.android.vr.projects.buyplus.main.BuyplusGuideActivity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.tao.powermsg\",\n      \"com.taobao.taobao.home\",\n      \"com.taobao.weappplus\",\n      \"com.taobao.taolive\",\n      \"com.taobao.android.gmlab\",\n      \"com.taobao.android.tbcatch\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"\",\n    \"pkgName\":\"com.taobao.android.vr\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.android.vr.sdk.jsbridge.VRDyJsbService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@1.8.3.9\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tao.channel.WomenDressActivity\",\n      \"com.taobao.tao.channel.MenDressActivity\",\n      \"com.taobao.tao.channel.infodetail.InfoDetailActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.TaoApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"行业频道\",\n    \"pkgName\":\"com.taobao.tao.channel\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@1.2.5.27\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tao.detail.activity.DetailActivity\",\n      \"com.taobao.android.detail.activity.weex.DetailWeexActivity\",\n      \"com.taobao.detail.ask.TestActivity\",\n      \"com.taobao.android.detail.kit.activity.SecKillAnswerActivity\",\n      \"com.taobao.android.detail.kit.activity.HotAnswerActivity\",\n      \"com.taobao.android.detail.kit.extract.gallery.GalleryActivity\",\n      \"com.taobao.detail.ask.TestActivity\",\n      \"com.taobao.tao.sku.view.MainSkuActivity\",\n      \"com.taobao.tao.sku.view.maccolor.MacColorSelectActivity\",\n      \"com.taobao.android.measure.activity.DemoActivity\",\n      \"com.taobao.android.measure.activity.ArMeasureMainActivity\"\n    ],\n    \"applicationName\":\"com.taobao.android.detail.DetailApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.avplayer\",\n      \"com.taobao.detail.rate\",\n      \"com.taobao.taobao.home\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"详情\",\n    \"pkgName\":\"com.taobao.android.detail\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.android.detail.service.WXPanoramaService\",\n      \"com.taobao.android.detail.service.MSOADetailService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@2.5.1.8\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.weapp.WeAppActivity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.weapp\",\n    \"receivers\":[],\n    \"services\":[],\n    \"version\":\"1.0.0@5.0.0.0\"\n  },\n  {\n    \"activities\":[],\n    \"applicationName\":\"com.taobao.relationship.application.RelationshipApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.relationship\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.relationship.jsbridge.FollowJsBridgeService\",\n      \"com.taobao.relationship.weex.FollowWeexSerivice\"\n    ],\n    \"version\":\"1.0.0@1.0.3.4\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.cun.business.activity.StubStandardActivity1\",\n      \"com.taobao.cun.business.activity.StubStandardActivity2\",\n      \"com.taobao.cun.business.activity.StubStandardActivity3\",\n      \"com.taobao.cun.business.activity.StubSingleInstanceActivity\",\n      \"com.taobao.cun.bundle.foundation.media.ui.MultiSelectPhotoFolderActivity\",\n      \"com.taobao.cun.bundle.foundation.media.ui.MultiSelectPhotoFolderDetailsActivity\",\n      \"com.taobao.cun.bundle.foundation.media.ui.PreviewPhotoActivity\",\n      \"com.taobao.cun.business.search.activity.SearchMainActivity1\",\n      \"com.taobao.cun.business.search.activity.SearchResultActivity1\",\n      \"com.taobao.cun.bundle.business.ann.view.AnnMessageDetailActivity\",\n      \"com.taobao.cun.bundle.business.ann.view.AnnMessageActivity\",\n      \"com.taobao.cun.bundle.community.ui.activity.CommunityPostDetailActivity1\",\n      \"com.taobao.cun.bundle.community.ui.activity.CommunityPublishActivity1\",\n      \"com.taobao.cun.bundle.community.ui.activity.CommunityCategoryActivity1\",\n      \"com.taobao.cun.bundle.community.ui.activity.CommunityUserPostListActivity1\",\n      \"com.taobao.cun.bundle.community.ui.activity.CommunitySubLocalActivity1\",\n      \"com.taobao.cun.bundle.community.ui.activity.CommunityHomeActivity\",\n      \"com.taobao.cun.business.service.ServiceCenterActivity1\",\n      \"com.taobao.cun.bundle.station.bind.activity.StationBindConfirmActivity\",\n      \"com.taobao.cun.bundle.station.bind.activity.StationBindSearchActivity\",\n      \"com.taobao.cun.bundle.station.bind.activity.StationBindLocationActivity\",\n      \"com.taobao.cun.bundle.villageserver.VillageServerMainActivity\"\n    ],\n    \"applicationName\":\"com.taobao.cun.CuntaoApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.cun\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.android.sso.internal.PidGetterService\"\n    ],\n    \"version\":\"1.0.0@0.3.0.5\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tao.allspark.container.editor.EditorActivity\",\n      \"com.taobao.tao.allspark.framework.BasicActivity\",\n      \"com.taobao.tao.allspark.index.guide.GuideActivity\",\n      \"com.taobao.wetao.home.WeTaoMainActivity\",\n      \"com.taobao.wetao.secondfloor.activity.SecondFloorActivity\",\n      \"com.taobao.wetao.topic.TopicActivity\",\n      \"com.taobao.wetao.aggregation.AggregationActivity\",\n      \"com.taobao.allspark.activity.AllSparkFragmentActivity\",\n      \"com.taobao.tao.allspark.activity.AddFollowTipActivity\",\n      \"com.taobao.tao.allspark.feed.activity.DongtaiCancelActivity\",\n      \"com.taobao.tao.allspark.topic.activity.TopicDropDownActivity\",\n      \"com.taobao.tao.allspark.container.WeDetailContainerActivity\",\n      \"com.taobao.tao.allspark.promotion.PromotionActivity\",\n      \"com.taobao.tao.allspark.pop.activity.WeiTaoLayerActivity\",\n      \"com.taobao.pikachu.activity.PikaMainActivity\"\n    ],\n    \"applicationName\":\"com.taobao.allspark.AllSparkApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.weapp\",\n      \"com.taobao.avplayer\",\n      \"com.taobao.relationship\",\n      \"com.taobao.trade.rate\",\n      \"com.taobao.acds\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"微淘\",\n    \"pkgName\":\"com.taobao.allspark\",\n    \"receivers\":[\n      \"com.taobao.tao.allspark.broadcastreceiver.AllsparkBroadcastReceiver\"\n    ],\n    \"services\":[\n      \"com.taobao.tao.allspark.service.AllSparkService\",\n      \"com.taobao.allspark.AllsparkEmptyService\",\n      \"com.taobao.pikachu.service.PikaJsBridgeService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@6.0.11\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.takeout.TakeoutMainActivity\",\n      \"com.taobao.takeout.index.ShopListActivity\",\n      \"com.taobao.takeout.utils.ActionViewDianReceiver\",\n      \"com.taobao.takeout.search.TakeoutSearchActivity\",\n      \"com.taobao.takeout.store.TakeoutStoreSearchActivity\",\n      \"com.taobao.takeout.search.SearchOutSideActivity\",\n      \"com.taobao.takeout.utils.TakeoutImageViewPagerActivity\",\n      \"com.taobao.takeout.favor.TakeoutFavorListActivity\",\n      \"com.taobao.takeout.purchase.PurchaseActivity\",\n      \"com.taobao.takeout.store.TakeoutStoreActivity\",\n      \"com.taobao.takeout.dishgoods.TakeoutDishGoodsActivity\",\n      \"com.taobao.takeout.order.detail.TakeoutOrderDetailActivity\",\n      \"com.taobao.diliveraddress.activity.HomeTestRiderMapActivity\"\n    ],\n    \"applicationName\":\"com.taobao.takeout.TakeoutApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.taobao.map\",\n      \"com.taobao.dynamic\",\n      \"com.taobao.lifeservice\"\n    ],\n    \"desc\":\"淘宝餐饮服务\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"口碑外卖\",\n    \"pkgName\":\"com.taobao.takeout\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.takeout.order.detail.service.TakeoutOrderDetailACCSService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@4.2.0.51\"\n  },\n  {\n    \"activities\":[\n      \"com.alibaba.security.rp.activity.RPTakePhotoActivity\",\n      \"com.alibaba.security.rp.activity.RPH5Activity\",\n      \"com.alibaba.security.rp.activity.RPH5Activity\",\n      \"com.alibaba.security.rp.activity.RPTakePhotoActivity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.alibaba.security.biometrics.face\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"\",\n    \"pkgName\":\"com.alibaba.security.rp.service\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.alibaba.security.rp.service.DynamicRPJsbridgeService\",\n      \"com.alibaba.security.rp.service.RPService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@1.3.0.70\"\n  },\n  {\n    \"activities\":[],\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.tmallpedometer\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.tmallpedometer.TmallPedometerJSBridgeService\",\n      \"com.tmall.health.service.KeepService\"\n    ],\n    \"version\":\"1.0.0@1.0.1\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.taobao.audio.audiorecorder.AudioRecorderActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.TaoApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"desc\":\"录音组件\",\n    \"isInternal\":true,\n    \"name\":\"录音组件\",\n    \"pkgName\":\"com.taobao.android.audio\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.interact.mediaplayer.service.MediaPlayerService\"\n    ],\n    \"version\":\"1.0.0@2.1.1.1\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tbarmagic.ARNavigationActivity\",\n      \"com.taobao.tbarmagic.ARMarkerActivity\",\n      \"com.taobao.tbarmagic.ardetail.main.ARDetailMarkerActivity\",\n      \"com.taobao.tbarmagic.ardetail.main.ARDetailActivity\",\n      \"com.taobao.tbarmagic.LBSActivity\",\n      \"com.taobao.tbarmagic.detail3d.Detail3DDemoActivity\",\n      \"com.taobao.tbarmagic.detail3d.Detail3DH5Activity\"\n    ],\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.android.gmlab\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"\",\n    \"pkgName\":\"com.taobao.tbarmagic\",\n    \"receivers\":[],\n    \"services\":[\n      \"com.taobao.tbarmagic.jsbridge.TBARPlatformWVService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@1.0.3.1\"\n  },\n  {\n    \"activities\":[],\n    \"applicationName\":\"com.taobao.passivelocation.PassiveLocationApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"com.taobao.dynamic\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"被动定位\",\n    \"pkgName\":\"com.taobao.passivelocation\",\n    \"receivers\":[\n      \"com.taobao.passivelocation.gathering.receiver.LocationChangedReceiver\"\n    ],\n    \"services\":[\n      \"com.amap.api.location.APSService\",\n      \"com.taobao.activelocation.service.aidl.TBLocationServiceImpl\",\n      \"com.taobao.activelocation.report.service.ActiveReportService\",\n      \"com.taobao.passivelocation.service.UserSwitchControlService\",\n      \"com.taobao.geofence.aidl.FenceServiceImpl\",\n      \"com.taobao.passivelocation.gathering.service.LocationGatheringService\",\n      \"com.taobao.passivelocation.report.service.LocationReportService\",\n      \"com.taobao.geofence.service.GeofenceService\",\n      \"com.taobao.collection.receiver.AccCollectionService\",\n      \"com.taobao.passivelocation.aidl.PassiveLocationServiceImpl\",\n      \"com.taobao.nativefence.service.NativeFenceService\",\n      \"com.taobao.nativefence.service.NativeFenceIntentService\",\n      \"com.taobao.nativefence.service.NativeFenceService$NativeFenceInnerService\"\n    ],\n    \"size\":0,\n    \"version\":\"1.0.0@2.2.9\"\n  },\n  {\n    \"activities\":[],\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.dynamic\",\n    \"receivers\":[],\n    \"services\":[],\n    \"version\":\"1.0.0@1.0.4.18\"\n  },\n  {\n    \"activities\":[],\n    \"applicationName\":\"com.taobao.alibcpromotion.AlibcPromotionApplication\",\n    \"contentProviders\":[\n      \"com.taobao.alibcpromotion.AlibcContentProvider\"\n    ],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.alibcpromotion\",\n    \"receivers\":[],\n    \"services\":[],\n    \"version\":\"1.0.0@1.0.0.0\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.tao.ReminderActivity\",\n      \"com.taobao.tao.TBCalendarActivity\",\n      \"com.taobao.tao.TBCalendarListActivity\",\n      \"com.taobao.tao.calendar.alarm.ReminderFromNotityActivity\"\n    ],\n    \"applicationName\":\"com.taobao.tao.CalendarApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[],\n    \"isInternal\":true,\n    \"pkgName\":\"com.taobao.calendar\",\n    \"receivers\":[\n      \"com.taobao.calendar.sdk.alarm.CalendarAlarmReceiver\",\n      \"com.taobao.calendar.sdk.alarm.NotificationLogSupport\"\n    ],\n    \"services\":[\n      \"com.taobao.calendar.sdk.synchronize.SynService\",\n      \"com.taobao.calendar.sdk.alarm.CalendarAlarmService\",\n      \"com.taobao.calendar.sdk.aidl.CalendarServiceImpl\"\n    ],\n    \"version\":\"1.0.0@2.4.1.45\"\n  },\n  {\n    \"activities\":[\n      \"com.taobao.cainiao.logistic.LogisticDetailActivity\",\n      \"com.taobao.cainiao.card.LogisticDetailCardActivity\"\n    ],\n    \"applicationName\":\"com.taobao.cainiao.CainiaoApplication\",\n    \"contentProviders\":[],\n    \"dependency\":[\n      \"\"\n    ],\n    \"desc\":\"\",\n    \"isInternal\":true,\n    \"md5\":\"\",\n    \"name\":\"物流\",\n    \"pkgName\":\"com.taobao.cainiao\",\n    \"receivers\":[],\n    \"services\":[],\n    \"size\":0,\n    \"version\":\"1.0.0@1.5.3.20\"\n  }\n]"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/src/test/resources/log4j.properties",
    "content": "#\n#\n#\n#\n#                                   Apache License\n#                             Version 2.0, January 2004\n#                          http://www.apache.org/licenses/\n#\n#     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n#\n#     1. Definitions.\n#\n#        \"License\" shall mean the terms and conditions for use, reproduction,\n#        and distribution as defined by Sections 1 through 9 of this document.\n#\n#        \"Licensor\" shall mean the copyright owner or entity authorized by\n#        the copyright owner that is granting the License.\n#\n#        \"Legal Entity\" shall mean the union of the acting entity and all\n#        other entities that control, are controlled by, or are under common\n#        control with that entity. For the purposes of this definition,\n#        \"control\" means (i) the power, direct or indirect, to cause the\n#        direction or management of such entity, whether by contract or\n#        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n#        outstanding shares, or (iii) beneficial ownership of such entity.\n#\n#        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n#        exercising permissions granted by this License.\n#\n#        \"Source\" form shall mean the preferred form for making modifications,\n#        including but not limited to software source code, documentation\n#        source, and configuration files.\n#\n#        \"Object\" form shall mean any form resulting from mechanical\n#        transformation or translation of a Source form, including but\n#        not limited to compiled object code, generated documentation,\n#        and conversions to other media types.\n#\n#        \"Work\" shall mean the work of authorship, whether in Source or\n#        Object form, made available under the License, as indicated by a\n#        copyright notice that is included in or attached to the work\n#        (an example is provided in the Appendix below).\n#\n#        \"Derivative Works\" shall mean any work, whether in Source or Object\n#        form, that is based on (or derived from) the Work and for which the\n#        editorial revisions, annotations, elaborations, or other modifications\n#        represent, as a whole, an original work of authorship. For the purposes\n#        of this License, Derivative Works shall not include works that remain\n#        separable from, or merely link (or bind by name) to the interfaces of,\n#        the Work and Derivative Works thereof.\n#\n#        \"Contribution\" shall mean any work of authorship, including\n#        the original version of the Work and any modifications or additions\n#        to that Work or Derivative Works thereof, that is intentionally\n#        submitted to Licensor for inclusion in the Work by the copyright owner\n#        or by an individual or Legal Entity authorized to submit on behalf of\n#        the copyright owner. For the purposes of this definition, \"submitted\"\n#        means any form of electronic, verbal, or written communication sent\n#        to the Licensor or its representatives, including but not limited to\n#        communication on electronic mailing lists, source code control systems,\n#        and issue tracking systems that are managed by, or on behalf of, the\n#        Licensor for the purpose of discussing and improving the Work, but\n#        excluding communication that is conspicuously marked or otherwise\n#        designated in writing by the copyright owner as \"Not a Contribution.\"\n#\n#        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n#        on behalf of whom a Contribution has been received by Licensor and\n#        subsequently incorporated within the Work.\n#\n#     2. Grant of Copyright License. Subject to the terms and conditions of\n#        this License, each Contributor hereby grants to You a perpetual,\n#        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n#        copyright license to reproduce, prepare Derivative Works of,\n#        publicly display, publicly perform, sublicense, and distribute the\n#        Work and such Derivative Works in Source or Object form.\n#\n#     3. Grant of Patent License. Subject to the terms and conditions of\n#        this License, each Contributor hereby grants to You a perpetual,\n#        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n#        (except as stated in this section) patent license to make, have made,\n#        use, offer to sell, sell, import, and otherwise transfer the Work,\n#        where such license applies only to those patent claims licensable\n#        by such Contributor that are necessarily infringed by their\n#        Contribution(s) alone or by combination of their Contribution(s)\n#        with the Work to which such Contribution(s) was submitted. If You\n#        institute patent litigation against any entity (including a\n#        cross-claim or counterclaim in a lawsuit) alleging that the Work\n#        or a Contribution incorporated within the Work constitutes direct\n#        or contributory patent infringement, then any patent licenses\n#        granted to You under this License for that Work shall terminate\n#        as of the date such litigation is filed.\n#\n#     4. Redistribution. You may reproduce and distribute copies of the\n#        Work or Derivative Works thereof in any medium, with or without\n#        modifications, and in Source or Object form, provided that You\n#        meet the following conditions:\n#\n#        (a) You must give any other recipients of the Work or\n#            Derivative Works a copy of this License; and\n#\n#        (b) You must cause any modified files to carry prominent notices\n#            stating that You changed the files; and\n#\n#        (c) You must retain, in the Source form of any Derivative Works\n#            that You distribute, all copyright, patent, trademark, and\n#            attribution notices from the Source form of the Work,\n#            excluding those notices that do not pertain to any part of\n#            the Derivative Works; and\n#\n#        (d) If the Work includes a \"NOTICE\" text file as part of its\n#            distribution, then any Derivative Works that You distribute must\n#            include a readable copy of the attribution notices contained\n#            within such NOTICE file, excluding those notices that do not\n#            pertain to any part of the Derivative Works, in at least one\n#            of the following places: within a NOTICE text file distributed\n#            as part of the Derivative Works; within the Source form or\n#            documentation, if provided along with the Derivative Works; or,\n#            within a display generated by the Derivative Works, if and\n#            wherever such third-party notices normally appear. The contents\n#            of the NOTICE file are for informational purposes only and\n#            do not modify the License. You may add Your own attribution\n#            notices within Derivative Works that You distribute, alongside\n#            or as an addendum to the NOTICE text from the Work, provided\n#            that such additional attribution notices cannot be construed\n#            as modifying the License.\n#\n#        You may add Your own copyright statement to Your modifications and\n#        may provide additional or different license terms and conditions\n#        for use, reproduction, or distribution of Your modifications, or\n#        for any such Derivative Works as a whole, provided Your use,\n#        reproduction, and distribution of the Work otherwise complies with\n#        the conditions stated in this License.\n#\n#     5. Submission of Contributions. Unless You explicitly state otherwise,\n#        any Contribution intentionally submitted for inclusion in the Work\n#        by You to the Licensor shall be under the terms and conditions of\n#        this License, without any additional terms or conditions.\n#        Notwithstanding the above, nothing herein shall supersede or modify\n#        the terms of any separate license agreement you may have executed\n#        with Licensor regarding such Contributions.\n#\n#     6. Trademarks. This License does not grant permission to use the trade\n#        names, trademarks, service marks, or product names of the Licensor,\n#        except as required for reasonable and customary use in describing the\n#        origin of the Work and reproducing the content of the NOTICE file.\n#\n#     7. Disclaimer of Warranty. Unless required by applicable law or\n#        agreed to in writing, Licensor provides the Work (and each\n#        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n#        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n#        implied, including, without limitation, any warranties or conditions\n#        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n#        PARTICULAR PURPOSE. You are solely responsible for determining the\n#        appropriateness of using or redistributing the Work and assume any\n#        risks associated with Your exercise of permissions under this License.\n#\n#     8. Limitation of Liability. In no event and under no legal theory,\n#        whether in tort (including negligence), contract, or otherwise,\n#        unless required by applicable law (such as deliberate and grossly\n#        negligent acts) or agreed to in writing, shall any Contributor be\n#        liable to You for damages, including any direct, indirect, special,\n#        incidental, or consequential damages of any character arising as a\n#        result of this License or out of the use or inability to use the\n#        Work (including but not limited to damages for loss of goodwill,\n#        work stoppage, computer failure or malfunction, or any and all\n#        other commercial damages or losses), even if such Contributor\n#        has been advised of the possibility of such damages.\n#\n#     9. Accepting Warranty or Additional Liability. While redistributing\n#        the Work or Derivative Works thereof, You may choose to offer,\n#        and charge a fee for, acceptance of support, warranty, indemnity,\n#        or other liability obligations and/or rights consistent with this\n#        License. However, in accepting such obligations, You may act only\n#        on Your own behalf and on Your sole responsibility, not on behalf\n#        of any other Contributor, and only if You agree to indemnify,\n#        defend, and hold each Contributor harmless for any liability\n#        incurred by, or claims asserted against, such Contributor by reason\n#        of your accepting any such warranty or additional liability.\n#\n#     END OF TERMS AND CONDITIONS\n#\n#     APPENDIX: How to apply the Apache License to your work.\n#\n#        To apply the Apache License to your work, attach the following\n#        boilerplate notice, with the fields enclosed by brackets \"[]\"\n#        replaced with your own identifying information. (Don't include\n#        the brackets!)  The text should be enclosed in the appropriate\n#        comment syntax for the file format. We also recommend that a\n#        file or class name and description of purpose be included on the\n#        same \"printed page\" as the copyright notice for easier\n#        identification within third-party archives.\n#\n#     Copyright 2016 Alibaba Group\n#\n#     Licensed under the Apache License, Version 2.0 (the \"License\");\n#     you may not use this file except in compliance with the License.\n#     You may obtain a copy of the License at\n#\n#         http://www.apache.org/licenses/LICENSE-2.0\n#\n#     Unless required by applicable law or agreed to in writing, software\n#     distributed under the License is distributed on an \"AS IS\" BASIS,\n#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n#     See the License for the specific language governing permissions and\n#     limitations under the License.\n#\n#\n#\n\nlog4j.appender.debugLog=org.apache.log4j.FileAppender\nlog4j.appender.debugLog.File=/Users/wuzhong/github/atlas/atlas-gradle-plugin/logs/debug.log\nlog4j.appender.debugLog.layout=org.apache.log4j.PatternLayout\nlog4j.appender.debugLog.layout.ConversionPattern=%d [%24F:%t:%L] - %m%n\nlog4j.category.debugLogger=debugLog"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/test.sh",
    "content": "cd ../../atlas-demo/AtlasDemo/\n./gradlew clean assembleDebug --stacktrace\n./gradlew publish\n\n./gradlew clean assembleDebug -DapVersion=1.0.0 --stacktrace\ncd ../../atlas-gradle-plugin/atlas-plugin"
  },
  {
    "path": "atlas-gradle-plugin/atlas-plugin/todo.txt",
    "content": "1. 多模块\n2. atlasPlugin\n3. jdk，builder， gradle 等版本的校验\n\n\n \"com.taobao.weex.devtools.inspector.network.NetworkEventReporter$InspectorHeaders\" on path: DexPathList[[zip file \"/data/app/com.taobao.taobao-1/base.apk\n\n                    E  PurchaseActivity  LoadingTime : 417 ms , onCreate : true, FirstOpen : true\n        BundleInstaller  E  com.taobao.taobao.alipay-->[com.taobao.dynamic, com.taobao.taobao.alipay]\n                         E  find valid bundle : /data/user/0/com.taobao.taobao/lib/libcom_taobao_taobao_alipay.so\n                         E  real install com.taobao.taobao.alipay\n  BundleArchiveRevision  E  /data/user/0/com.taobao.taobao/files/storage/com.taobao.taobao.alipay/version.1\n      BundleClassLoader  E  nativeLibPath : /data/user/0/com.taobao.taobao/files/storage/com.taobao.taobao.alipay/version.1/lib:/data/app/com.taobao.taobao-1/lib/arm:/system/li\n                            b:/vendor/lib:/data/user/0/com.taobao.taobao/files/storage/com.taobao.dynamic/version.1/lib\n              Framework  E  bundle archieve dexopt bundle /data/user/0/com.taobao.taobao/lib/libcom_taobao_taobao_alipay.so cost time = 1482 ms\n        BundleInstaller  E  notify finish [com.taobao.taobao.alipay]\n        BundleLifeCycle  E  start com.taobao.tao.TaoApplication\n                         E  start finishcom.taobao.tao.TaoApplication\n    InstrumentationHook  E  async startActivity\n        BundleLifeCycle  E  start com.taobao.cainiao.CainiaoApplication\n                         E  start finishcom.taobao.cainiao.CainiaoApplication\n       ifaa_fingerprint  E  java.lang.ClassNotFoundException: org.ifaa.android.manager.IFAAManagerFactory\n                         E      at java.lang.Class.classForName(Native Method)\n                         E      at java.lang.Class.forName(Class.java:400)\n                         E      at java.lang.Class.forName(Class.java:326)\n                         E      at com.alipay.security.mobile.alipayauthenticatorservice.fingerprint.manager.IFAAFingerprintManagerFactory.getIFAAManager(IFAAFingerprintManager\n                            Factory.java:31)\n\n"
  },
  {
    "path": "atlas-gradle-plugin/build.gradle",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) buildInfoGeneratorbeneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\nbuildscript {\n\n    repositories {\n\n        //本地库，local repository(${user.home}/.m2/repository)\n        mavenLocal()\n\n        jcenter()\n        google()\n    }\n\n    dependencies {\n        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'\n        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'\n        //引入其他的插件\n    }\n}\n\n\ndescription = \"\"\"atlas gradle plugin\"\"\"\n\n\ntask wrapper(type: Wrapper) {\n    gradleVersion = '4.2.1'\n    distributionUrl = 'http://services.gradle.org/distributions/gradle-4.2.1-all.zip'\n}\n\nsubprojects {\n\n    if (!project.getBuildFile().exists()) {\n        return;\n    }\n\n    def command = project.getGradle().startParameter.toString()\n    def publishFile = new File(project.getRootDir(),\n                               \"publish_\" + (command.contains(\"bintray\") ? \"bintray\" : \"mvn\") + \".gradle\");\n\n    if (publishFile.exists()) {\n        apply from: publishFile.getAbsolutePath()\n    }\n\n    repositories {\n        //本地库，local repository(${user.home}/.m2/repository)\n        mavenLocal()\n        jcenter()\n        google()\n    }\n\n    group = 'com.taobao.android'\n\n    tasks.withType(JavaCompile) {\n        sourceCompatibility = 1.8\n        targetCompatibility = 1.8\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/.gitignore",
    "content": "*.iml\n.gradle\n.idea/\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n!.idea/codeStyleSettings.xml\n.DS_Store\n/build\n/captures\n.vscode/\n\n# Taken from Android.gitignore https://github.com/github/gitignore/blob/master/Android.gitignore\n#\n# Built application files\n*.apk\n*.ap_\n\n# Files for the Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# Intellij\n*.iml\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/build.gradle",
    "content": "\n\napply plugin: 'java'\nsourceSets {\n    main {\n//        groovy.srcDirs = ['src/main/groovy']\n        java.srcDirs = ['src/main/java']\n        resources.srcDirs = ['src/main/resources']\n    }\n}\n\n\n\ndependencies {\n    compile localGroovy()\n    compile gradleApi()\n//    compile fileTree(dir: 'libs', include: '*.jar')\n    compile 'commons-io:commons-io:2.4'\n    compile 'org.smali:smali:2.2.2'\n    compile 'org.smali:baksmali:2.2.2'\n    compile 'org.antlr:antlr-runtime:3.5.2'\n    compile 'org.apache.commons:commons-lang3:3.4'\n    compile 'org.apache.commons:commons-compress:1.4.1'\n    compile \"com.android.tools:common:26.0.1\"\n    compile \"com.alibaba:fastjson:1.1.46.android\"\n    compile \"org.apache.httpcomponents:httpclient:4.4\"\n    compile 'io.reactivex.rxjava2:rxjava:2.0.1'\n    compile 'org.reactivestreams:reactive-streams:1.0.0@jar'\n\n\n\n}\n\n\ngroup 'com.taobao.android'\n\n\nversion \"3.0.0-rc16\"\n\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Mon Jan 16 11:27:51 CST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-2.12-all.zip\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/AXMLResource.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\npackage android.content.res;\n\nimport android.content.res.chunk.ChunkType;\nimport android.content.res.chunk.ChunkUtil;\nimport android.content.res.chunk.sections.ResourceSection;\nimport android.content.res.chunk.sections.StringSection;\nimport android.content.res.chunk.types.AXMLHeader;\nimport android.content.res.chunk.types.Attribute;\nimport android.content.res.chunk.types.Chunk;\nimport android.content.res.chunk.types.StartTag;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.util.Iterator;\nimport java.util.LinkedHashSet;\n\n/**\n * Main AXMLResource object\n *\n * @author tstrazzere\n */\npublic class AXMLResource {\n\n    AXMLHeader header;\n    StringSection stringSection;\n    ResourceSection resourceSection;\n    LinkedHashSet<Chunk> chunks;\n\n    public AXMLResource() {\n        chunks = new LinkedHashSet<Chunk>();\n    }\n\n    public AXMLResource(InputStream stream) throws IOException {\n        chunks = new LinkedHashSet<Chunk>();\n        if (!read(stream)) {\n            throw new IOException();\n        }\n    }\n\n    public void injectApplicationAttribute(Attribute attribute) {\n        StartTag tag = getApplicationTag();\n\n        tag.insertOrReplaceAttribute(attribute);\n    }\n\n    public StartTag getApplicationTag() {\n        Iterator<Chunk> iterator = chunks.iterator();\n        while (iterator.hasNext()) {\n            Chunk chunk = iterator.next();\n            if (chunk instanceof StartTag &&\n                    ((StartTag) chunk).getName(stringSection).equalsIgnoreCase(\"application\")) {\n                return (StartTag) chunk;\n            }\n        }\n\n        return null;\n    }\n\n    public StringSection getStringSection() {\n        return stringSection;\n    }\n\n    public boolean read(InputStream stream) throws IOException {\n\n        IntReader reader = new IntReader(stream, false);\n\n        // Get an attempted size until we know the read size\n        int size = stream.available();\n\n        while ((size - reader.getBytesRead()) > 4) {\n            // This should just read all the chunks\n            Chunk chunk = ChunkUtil.createChunk(reader);\n\n            switch (chunk.getChunkType()) {\n                case AXML_HEADER:\n                    header = (AXMLHeader) chunk;\n                    // TODO : This should warn if true\n                    // This will cause breakages if the header is lying\n                    //size = header.getSize();\n                    break;\n                case STRING_SECTION:\n                    stringSection = (StringSection) chunk;\n                    break;\n                // operational = true;\n                case RESOURCE_SECTION:\n                    resourceSection = (ResourceSection) chunk;\n                    break;\n                case START_NAMESPACE:\n                case END_NAMESPACE:\n                case START_TAG:\n                case END_TAG:\n                case TEXT_TAG:\n                    chunks.add(chunk);\n                    break;\n                case BUFFER:\n                    // Do nothing right now, not even add it to the chunk stuff\n                    break;\n                default:\n                    throw new IOException(\"Hit an unknown chunk type!\");\n            }\n        }\n\n        if ((header != null) && (stringSection != null) && (resourceSection != null)) {\n            if (header.getSize() != reader.getBytesRead()) {\n                System.out.println(\"Potential issue as the bytes read is not equal to the amount of bytes in the file\");\n            }\n            return true;\n        }\n\n        return false;\n    }\n\n    public void write(OutputStream outputStream) throws IOException {\n\n        int chunkSizes = 0;\n        Iterator<Chunk> iterator = chunks.iterator();\n        while (iterator.hasNext()) {\n            Chunk chunk = iterator.next();\n            chunkSizes += chunk.getSize();\n        }\n\n\n        outputStream.write(ByteBuffer.allocate(8)\n                .order(ByteOrder.LITTLE_ENDIAN)\n                .putInt(ChunkType.AXML_HEADER.getIntType())\n                .putInt(((2 * 4) + stringSection.getSize() + resourceSection.getSize() + chunkSizes))\n                .array());\n        outputStream.write(stringSection.toBytes());\n        outputStream.write(resourceSection.toBytes());\n        iterator = chunks.iterator();\n        while (iterator.hasNext()) {\n            Chunk chunk = iterator.next();\n            outputStream.write(chunk.toBytes());\n        }\n\n    }\n\n    public String toXmlString() {\n        StringBuilder sb = new StringBuilder();\n        sb.append(header.toXML(stringSection, resourceSection, 0)).append(\"\\n\");\n        Iterator<Chunk> iterator = chunks.iterator();\n        int indents = 0;\n        String nameSpace = null;\n        while (iterator.hasNext()) {\n            Chunk chunk = iterator.next();\n            if (chunk.getChunkType() == ChunkType.END_TAG) {\n                indents--;\n            }\n             if(chunk.getChunkType() == ChunkType.START_NAMESPACE){\n                 nameSpace = chunk.toXML(stringSection, resourceSection, indents);\n             }else {\n                 if(null!= nameSpace && chunk.getChunkType() == ChunkType.START_TAG){\n                     StartTag startTag = (StartTag) chunk;\n                     sb.append(startTag.toXMLWithNamespace(stringSection, resourceSection, indents,nameSpace)).append(\"\\n\");\n                 }else {\n                     sb.append(chunk.toXML(stringSection, resourceSection, indents)).append(\"\\n\");\n                 }\n             }\n//            sb.append(chunk.toXML(stringSection, resourceSection, indents)).append(\"\\n\");\n\n            if (chunk.getChunkType() == ChunkType.START_TAG) {\n                nameSpace = null;\n                indents++;\n            }\n        }\n        return sb.toString();\n    }\n\n    private static void log(String format, Object... arguments) {\n        System.out.printf(format, arguments);\n        System.out.println();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/IntReader.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\npackage android.content.res;\n\nimport java.io.EOFException;\nimport java.io.IOException;\nimport java.io.InputStream;\n\n/**\n * Simple helper class that allows reading of integers.\n * <p>\n * TODO: implement buffering\n *\n * @author Dmitry Skiba\n */\npublic class IntReader {\n\n    private InputStream stream;\n    private boolean bigEndian;\n    private int bytesRead;\n\n    public IntReader(InputStream stream, boolean bigEndian) {\n        reset(stream, bigEndian);\n    }\n\n    /**\n     * Reset the POJO to use a new stream.\n     *\n     * @param newStream   the {@code InputStream} to use\n     * @param isBigEndian a boolean for whether or not the stream is in Big Endian format\n     */\n    public void reset(InputStream newStream, boolean isBigEndian) {\n        stream = newStream;\n        bigEndian = isBigEndian;\n        bytesRead = 0;\n    }\n\n    /**\n     * Close the current stream being used by the POJO.\n     */\n    public void close() {\n        if (stream != null) {\n            try {\n                stream.close();\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n            reset(null, false);\n        }\n    }\n\n    public int readByte() throws IOException {\n        return readInt(1);\n    }\n\n    public int readShort() throws IOException {\n        return readInt(2);\n    }\n\n    public int readInt() throws IOException {\n        return readInt(4);\n    }\n\n    /**\n     * Read an integer of a certain length from the current stream.\n     *\n     * @param length to read\n     * @return\n     * @throws IOException\n     */\n    public int readInt(int length) throws IOException {\n        if ((length < 0) || (length > 4)) {\n            throw new IllegalArgumentException();\n        }\n        int result = 0;\n        int byteRead = 0;\n        if (bigEndian) {\n            for (int i = (length - 1) * 8; i >= 0; i -= 8) {\n                byteRead = stream.read();\n                bytesRead++;\n                if (byteRead == -1) {\n                    throw new EOFException();\n                }\n                result |= (byteRead << i);\n            }\n        } else {\n            length *= 8;\n            for (int i = 0; i != length; i += 8) {\n                byteRead = stream.read();\n                bytesRead++;\n                if (byteRead == -1) {\n                    throw new EOFException();\n                }\n                result |= (byteRead << i);\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * Skip a specific number of bytes in the stream.\n     *\n     * @param bytes\n     * @throws IOException\n     */\n    public void skip(int bytes) throws IOException {\n        if (bytes > 0) {\n            if (stream.skip(bytes) != bytes) {\n                throw new EOFException();\n            }\n            bytesRead += bytes;\n        }\n    }\n\n    public void skipInt() throws IOException {\n        skip(4);\n    }\n\n    public int getBytesRead() {\n        return bytesRead;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/AttributeType.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk;\n\n/**\n * Enum for attribute types for ChunkTypes\n *\n * @author tstrazzere\n */\npublic enum AttributeType {\n\n    STRING {\n        @Override\n        public int getIntType() {\n            return 0x03000008;\n        }\n    },\n    INT {\n        @Override\n        public int getIntType() {\n            return 0x10000008;\n        }\n    },\n    RESOURCE {\n        @Override\n        public int getIntType() {\n            return 0x01000008;\n        }\n    },\n    BOOLEAN {\n        @Override\n        public int getIntType() {\n            return 0x12000008;\n        }\n    },\n    ATTR {\n        @Override\n        public int getIntType() {\n            return 0x02000008;\n        }\n    },\n    DIMEN {\n        @Override\n        public int getIntType() {\n            return 0x05000008;\n        }\n    },\n    FRACTION {\n        @Override\n        public int getIntType() {\n            return 0x06000008;\n        }\n    },\n    FLOAT {\n        @Override\n        public int getIntType() {\n            return 0x04000008;\n        }\n    },\n    FLAGS {\n        @Override\n        public int getIntType() {\n            return 0x11000008;\n        }\n    },\n    COLOR1 {\n        @Override\n        public int getIntType() {\n            return 0x1C000008;\n        }\n    },\n    COLOR2 {\n        @Override\n        public int getIntType() {\n            return 0x1D000008;\n        }\n    };\n\n    public abstract int getIntType();\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/ChunkType.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk;\n\n/**\n * Enum for ChunkTypes - the different types of Chunks available to create\n *\n * @author tstrazzere\n */\npublic enum ChunkType {\n    BUFFER {\n        // This is a faked type\n        @Override\n        public int getIntType() {\n            return 0;\n        }\n    },\n    ATTRIBUTE {\n        // This is a faked type\n        // XXX : Unneeded?\n        @Override\n        public int getIntType() {\n            return 0;\n        }\n    },\n    AXML_HEADER {\n        @Override\n        public int getIntType() {\n            return 0x00080003;\n        }\n    },\n    STRING_SECTION {\n        @Override\n        public int getIntType() {\n            return 0x001C0001;\n        }\n    },\n    RESOURCE_SECTION {\n        @Override\n        public int getIntType() {\n            return 0x00080180;\n        }\n    },\n    START_NAMESPACE {\n        @Override\n        public int getIntType() {\n            return 0x00100100;\n        }\n    },\n    END_NAMESPACE {\n        @Override\n        public int getIntType() {\n            return 0x00100101;\n        }\n    },\n    START_TAG {\n        @Override\n        public int getIntType() {\n            return 0x00100102;\n        }\n    },\n    END_TAG {\n        @Override\n        public int getIntType() {\n            return 0x00100103;\n        }\n    },\n    TEXT_TAG {\n        @Override\n        public int getIntType() {\n            return 0x00100104;\n        }\n    };\n\n    public abstract int getIntType();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/ChunkUtil.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk;\n\nimport android.content.res.IntReader;\nimport android.content.res.chunk.sections.ResourceSection;\nimport android.content.res.chunk.sections.StringSection;\nimport android.content.res.chunk.types.*;\n\nimport java.io.IOException;\n\n/**\n * Simple class for reading chunk types.\n *\n * @author tstrazzere\n */\npublic class ChunkUtil {\n\n    // TODO : This seems silly\n    public static ChunkType readChunkType(IntReader reader) throws IOException {\n        int type = reader.readInt();\n\n        for (ChunkType chunkType : ChunkType.values()) {\n            if (chunkType.getIntType() == type) {\n                return chunkType;\n            }\n        }\n\n        throw new IOException(\"Unexpected tag!\");\n    }\n\n    public static Chunk createChunk(IntReader reader) throws IOException {\n        ChunkType chunkType = readChunkType(reader);\n\n        switch (chunkType) {\n            case AXML_HEADER:\n                return new AXMLHeader(chunkType, reader);\n            case STRING_SECTION:\n                return new StringSection(chunkType, reader);\n            case RESOURCE_SECTION:\n                return new ResourceSection(chunkType, reader);\n            case START_NAMESPACE:\n            case END_NAMESPACE:\n                return new NameSpace(chunkType, reader);\n            case START_TAG:\n                return new StartTag(chunkType, reader);\n            case END_TAG:\n                return new EndTag(chunkType, reader);\n            case TEXT_TAG:\n                return new TextTag(chunkType, reader);\n            case BUFFER:\n                return new Buffer(chunkType, reader);\n            default:\n                throw new IOException(\"Unexpected tag!\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/PoolItem.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk;\n\n/**\n * Simple POJO for keeping the offsets and data for items inside of \"pools\".\n *\n * @author tstrazzere\n */\npublic class PoolItem {\n    private int itemOffset;\n    private String itemData;\n\n    public PoolItem(int offset, String data) {\n        itemOffset = offset;\n        itemData = data;\n    }\n\n    public int getOffset() {\n        return itemOffset;\n    }\n\n    public void setString(String data) {\n        itemData = data;\n    }\n\n    public String getString() {\n        return itemData;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/sections/ChunkSection.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk.sections;\n\nimport android.content.res.IntReader;\nimport android.content.res.chunk.types.Chunk;\n\nimport java.io.IOException;\n\n/**\n * Interface for Chunk which is a section type\n *\n * @author tstrazzere\n */\npublic interface ChunkSection extends Chunk {\n\n    /**\n     * Read the 'header' part of the section.\n     */\n    public void readHeader(IntReader inputReader) throws IOException;\n\n    /**\n     * Read the\n     *\n     * @param inputReader\n     * @throws IOException\n     */\n    public void readSection(IntReader inputReader) throws IOException;\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/sections/GenericChunkSection.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk.sections;\n\nimport android.content.res.IntReader;\nimport android.content.res.chunk.ChunkType;\nimport android.content.res.chunk.types.Chunk;\nimport android.content.res.chunk.types.GenericChunk;\n\nimport java.io.IOException;\n\n/**\n * Generic ChunkSection class for generalizing the reading and minimizing the repetitive code inside of the specific\n * sections (likely overkill..)\n *\n * @author tstrazzere\n */\npublic abstract class GenericChunkSection extends GenericChunk implements Chunk, ChunkSection {\n\n    public GenericChunkSection(ChunkType chunkType, IntReader reader) {\n        super(chunkType, reader);\n\n        try {\n            readSection(reader);\n\n            reader.skip(Math.abs(reader.getBytesRead() - getStartPosition() - size));\n        } catch (IOException e) {\n            // Catching this here allows us to continue reading\n            e.printStackTrace();\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/sections/ResourceSection.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk.sections;\n\nimport android.content.res.IntReader;\nimport android.content.res.chunk.ChunkType;\nimport android.content.res.chunk.types.Chunk;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.util.ArrayList;\n\n/**\n * Concrete class for the section which is specifically for the resource ids.\n *\n * @author tstrazzere\n */\npublic class ResourceSection extends GenericChunkSection implements Chunk, ChunkSection {\n\n    // TODO : Make this an ArrayList so it's easier to add/remove\n    protected ArrayList<Integer> resourceIDs;\n\n    public ResourceSection(ChunkType chunkType, IntReader reader) {\n        super(chunkType, reader);\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#readHeader(android.content.res.IntReader)\n     */\n    @Override\n    public void readHeader(IntReader inputReader) throws IOException {\n        // Initialize this variable here\n        resourceIDs = new ArrayList<>();\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.sections.ChunkSection#readSection(android.content.res.IntReader)\n     */\n    @Override\n    public void readSection(IntReader inputReader) throws IOException {\n        for (int i = 0; i < ((size / 4) - 2); i++) {\n            addResource(inputReader.readInt());\n        }\n    }\n\n    public void addResource(int value) {\n        resourceIDs.add(value);\n    }\n\n    @Override\n    public int getSize() {\n        // Tag + Size + resourceIds\n        return 4 + 4 + (resourceIDs.size() * 4);\n    }\n\n    public int getResourceID(int index) {\n        return resourceIDs.get(index);\n    }\n\n    public int getResourceCount() {\n        return resourceIDs.size();\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#toXML(android.content.res.chunk.sections.StringSection,\n     * android.content.res.chunk.sections.ResourceSection, int)\n     */\n    @Override\n    public String toXML(StringSection stringSection, ResourceSection resourceSection, int indent) {\n        return null;\n    }\n\n    /*\n     * (non-Javadoc)\n     *\n     * @see android.content.res.chunk.types.Chunk#toBytes()\n     */\n    @Override\n    public byte[] toBytes() {\n        byte[] header = super.toBytes();\n\n        ByteBuffer offsetBuffer = ByteBuffer.allocate(resourceIDs.size() * 4).order(ByteOrder.LITTLE_ENDIAN);\n\n        for (int id : resourceIDs) {\n            offsetBuffer.putInt(id);\n        }\n        byte[] body = offsetBuffer.array();\n\n        return ByteBuffer.allocate(header.length + body.length)\n                .put(header)\n                .put(body)\n                .array();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/sections/StringSection.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk.sections;\n\nimport android.content.res.IntReader;\nimport android.content.res.chunk.ChunkType;\nimport android.content.res.chunk.PoolItem;\nimport android.content.res.chunk.types.Chunk;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.util.ArrayList;\nimport java.util.Arrays;\n\npublic class StringSection extends GenericChunkSection implements Chunk, ChunkSection {\n\n    // This specific tag appears unused but might need to be implemented? or used as an unknown?\n    @SuppressWarnings(\"unused\")\n    private final int SORTED_FLAG = 1 << 0;\n    private final int UTF8_FLAG = 1 << 8;\n\n    private int stringChunkCount;\n    private int styleChunkCount;\n    private int stringChunkFlags;\n    private int stringChunkPoolOffset;\n    private int styleChunkPoolOffset;\n\n    // FIXME:\n    // This likely could just be an ordered array of Strings if the Integer is just ordered and the key..\n    private ArrayList<PoolItem> stringChunkPool;\n    private ArrayList<PoolItem> styleChunkPool;\n\n    public StringSection(ChunkType chunkType, IntReader inputReader) {\n        super(chunkType, inputReader);\n    }\n\n    @Override\n    public void readHeader(IntReader inputReader) throws IOException {\n        stringChunkCount = inputReader.readInt();\n        styleChunkCount = inputReader.readInt();\n        stringChunkFlags = inputReader.readInt();\n\n        stringChunkPoolOffset = inputReader.readInt();\n        stringChunkPool = new ArrayList<PoolItem>();\n\n        styleChunkPoolOffset = inputReader.readInt();\n        styleChunkPool = new ArrayList<PoolItem>();\n    }\n\n    @Override\n    public void readSection(IntReader inputReader) throws IOException {\n        for (int i = 0; i < stringChunkCount; i++) {\n            stringChunkPool.add(new PoolItem(inputReader.readInt(), null));\n        }\n\n        if (!stringChunkPool.isEmpty()) {\n            readPool(stringChunkPool, stringChunkFlags, inputReader);\n        }\n\n        // TODO : Does this need the flags?\n        // FIXME: This is potentially wrong\n        for (int i = 0; i < styleChunkCount; i++) {\n            styleChunkPool.add(new PoolItem(inputReader.readInt(), null));\n        }\n\n        if (!styleChunkPool.isEmpty()) {\n            readPool(styleChunkPool, stringChunkFlags, inputReader);\n        }\n    }\n\n    // TODO : Ensure we goto the proper offset in the case it isn't in proper order\n    private void readPool(ArrayList<PoolItem> pool, int flags, IntReader inputReader) throws IOException {\n        int offset = 0;\n        for (PoolItem item : pool) {\n            // TODO: This assumes that the pool is ordered...\n            inputReader.skip(item.getOffset() - offset);\n            offset = item.getOffset();\n\n            int length = 0;\n            if ((flags & UTF8_FLAG) != 0) {\n                length = inputReader.readByte();\n                offset += 1;\n            } else {\n                length = inputReader.readShort();\n                offset += 2;\n            }\n\n            StringBuilder result = new StringBuilder(length);\n            for (; length != 0; length -= 1) {\n                if ((flags & UTF8_FLAG) != 0) {\n                    result.append((char) inputReader.readByte());\n                    offset += 1;\n                } else {\n                    result.append((char) inputReader.readShort());\n                    offset += 2;\n                }\n            }\n\n            item.setString(result.toString());\n        }\n    }\n\n    public int getStringIndex(String string) {\n        if (string != null) {\n            for (PoolItem item : stringChunkPool) {\n                if (item.getString().equals(string)) {\n                    return stringChunkPool.indexOf(item);\n                }\n            }\n        }\n\n        return -1;\n    }\n\n    public int putStringIndex(String string) {\n        int currentPosition = getStringIndex(string);\n        if (currentPosition != -1) {\n            return currentPosition;\n        }\n\n        stringChunkPool.add(new PoolItem(-1, string));\n\n        return getStringIndex(string);\n    }\n\n    public String getString(int index) {\n        if ((index > -1) && (index < stringChunkPool.size())) {\n            return stringChunkPool.get(index).getString();\n        }\n\n        return \"\";\n    }\n\n    public String getStyle(int index) {\n        return styleChunkPool.get(index).getString();\n    }\n\n    @Override\n    public String toXML(StringSection stringSection, ResourceSection resourceSection, int indent) {\n        return null;\n    }\n\n    @Override\n    public int getSize() {\n        int stringDataSize = 0;\n        int previousSize;\n        for (PoolItem item : stringChunkPool) {\n            previousSize = stringDataSize;\n            // TODO: This is potentially wrong\n            // length identifier\n            stringDataSize += ((stringChunkFlags & UTF8_FLAG) == 0) ? 2 : 1;\n            // actual string data\n            stringDataSize += item.getString().length() * (((stringChunkFlags & UTF8_FLAG) == 0) ? 2 : 1);\n            // buffer\n            int bufferSize = 4 - (stringDataSize - previousSize) % 4;\n            if (bufferSize > 0 && bufferSize < 4) {\n                stringDataSize += bufferSize;\n            }\n        }\n\n        int styleDataSize = 0;\n        for (PoolItem item : styleChunkPool) {\n            styleDataSize += item.getString().length() * (((stringChunkFlags & UTF8_FLAG) == 0) ? 2 : 1);\n        }\n\n        return (2 * 4) + // Header\n                (5 * 4) + // static sections\n                (stringChunkPool.size() * 4) + // string table offset size\n                stringDataSize +\n                (styleChunkPool.size() * 4) + // style table offset size\n                styleDataSize;\n    }\n\n    /*\n     * (non-Javadoc)\n     *\n     * @see android.content.res.chunk.types.Chunk#toBytes()\n     */\n    @Override\n    public byte[] toBytes() {\n        byte[] header = super.toBytes();\n\n        // TODO : We need to ensure these are already \"sorted\"\n        ByteBuffer offsetBuffer = ByteBuffer.allocate(stringChunkPool.size() * 4)\n                .order(ByteOrder.LITTLE_ENDIAN);\n        int offset = 0;\n        int previousOffset;\n        ArrayList<byte[]> stringData = new ArrayList<>();\n        for (PoolItem item : stringChunkPool) {\n            offsetBuffer.putInt(offset);\n            previousOffset = offset;\n\n            // TODO : Ensure this is properly handled, potentially a ULEB128?\n            // Add string length bytes\n            if (item.getString().length() > 255) {\n                System.err.println(\"Error, string length is greater than the current expected lengths!\");\n            }\n            offset += ((stringChunkFlags & UTF8_FLAG) == 0) ? 2 : 1;\n\n            // Add length of string based on if UTF-8 flag is enabled\n            offset += item.getString().length() * (((stringChunkFlags & UTF8_FLAG) == 0) ? 2 : 1);\n\n            // Add buffer\n            int bufferSize = 4 - ((offset - previousOffset) % 4);\n            if (bufferSize > 0 && bufferSize < 4) {\n                offset += bufferSize;\n            }\n\n            // Append actual length + data\n            ByteBuffer length;\n            if ((stringChunkFlags & UTF8_FLAG) == 0) {\n                length = ByteBuffer.allocate(2)\n                        .order(ByteOrder.LITTLE_ENDIAN)\n                        .putShort((short) item.getString().length());\n            } else {\n                length = ByteBuffer.allocate(1)\n                        .put((byte) item.getString().length());\n            }\n\n            ByteBuffer string = ByteBuffer.allocate(item.getString().length() * (((stringChunkFlags & UTF8_FLAG) == 0) ? 2 : 1))\n                    .order(ByteOrder.LITTLE_ENDIAN);\n            for (byte character : item.getString().getBytes()) {\n                if ((stringChunkFlags & UTF8_FLAG) == 0) {\n                    string.putShort(character);\n                } else {\n                    string.put(character);\n                }\n            }\n\n            ByteBuffer stringDataBuffer = ByteBuffer.allocate(offset - previousOffset)\n                    .order(ByteOrder.LITTLE_ENDIAN)\n                    .put(length.array())\n                    .put(string.array());\n\n            if (bufferSize > 0 && bufferSize < 4) {\n                // TODO : fix this\n                byte[] buffer = new byte[bufferSize];\n                Arrays.fill(buffer, (byte) 0x00);\n                stringDataBuffer.put(buffer);\n            }\n\n            stringData.add(stringDataBuffer.array());\n        }\n\n        // Combine strings into one buffer\n        ByteBuffer stringsBuffer = ByteBuffer.allocate(offsetBuffer.capacity() + offset)\n                .order(ByteOrder.LITTLE_ENDIAN)\n                .put(offsetBuffer.array());\n        for (byte[] data : stringData) {\n            stringsBuffer.put(data);\n        }\n        byte[] strings = stringsBuffer.array();\n\n//        byte[] styles = new byte[]{0x00};\n\n        int newStringChunkOffset = 0;\n        if (!stringChunkPool.isEmpty()) {\n            newStringChunkOffset = (5 * 4) /* header + 3 other ints above it */\n                    + stringChunkPool.size() * 4 /* index table size */\n                    + 8 /* (this space and the style chunk offset */;\n        }\n\n        int newStyleChunkOffset = 0;\n        if (!styleChunkPool.isEmpty()) {\n            newStyleChunkOffset = (6 * 4) /* header + 4 other ints above it */\n                    + styleChunkPool.size() * 4 /* index table size */\n                    + 8 /* (this space and the style chunk offset */;\n        }\n\n        byte[] body = ByteBuffer.allocate(5 * 4)\n                .order(ByteOrder.LITTLE_ENDIAN)\n                .putInt(stringChunkPool.size())\n                .putInt(styleChunkPool.size())\n                .putInt(stringChunkFlags)\n                .putInt(newStringChunkOffset)\n                .putInt(newStyleChunkOffset)\n                .array();\n\n        return ByteBuffer.allocate(header.length + body.length + strings.length /*+ styles.length*/)\n                .order(ByteOrder.LITTLE_ENDIAN)\n                .put(header)\n                .put(body)\n                .put(strings)\n//                .put(styles)\n                .array();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/types/AXMLHeader.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk.types;\n\nimport android.content.res.IntReader;\nimport android.content.res.chunk.ChunkType;\nimport android.content.res.chunk.sections.ResourceSection;\nimport android.content.res.chunk.sections.StringSection;\n\nimport java.io.IOException;\n\n/**\n * ChunkType which is for the AXMLHeader, should be at the beginning and only the beginning of the files.\n * <p>\n * TODO : Check and warn if not at the beginning\n * TODO : toBytes() needs to understand the correct size of the entire file\n *\n * @author tstrazzere\n */\npublic class AXMLHeader extends GenericChunk {\n\n    public AXMLHeader(ChunkType chunkType, IntReader inputReader) {\n        super(chunkType, inputReader);\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#readHeader(android.content.res.IntReader)\n     */\n    @Override\n    public void readHeader(IntReader inputReader) throws IOException {\n        // Nothing else to do\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#toXML(android.content.res.chunk.sections.StringSection,\n     * android.content.res.chunk.sections.ResourceSection, int)\n     */\n    @Override\n    public String toXML(StringSection stringSection, ResourceSection resourceSection, int indent) {\n        return indent(indent) + \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\";\n    }\n\n    /*\n     * (non-Javadoc)\n     *\n     * @see android.content.res.chunk.types.Chunk#toBytes()\n     */\n    @Override\n    public byte[] toBytes() {\n        return super.toBytes();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/types/Attribute.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk.types;\n\nimport android.content.res.IntReader;\nimport android.content.res.chunk.AttributeType;\nimport android.content.res.chunk.ChunkType;\nimport android.content.res.chunk.sections.ResourceSection;\nimport android.content.res.chunk.sections.StringSection;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\n\n/**\n * Specific type of Chunk which contains the metadata\n *\n * @author tstrazzere\n */\npublic class Attribute implements Chunk {\n\n    private int uri;\n    private int name;\n    private int stringData;\n    // TODO : Refactor to proper enum\n    private int attributeType;\n    private int data;\n\n    public Attribute(String uri,\n                     String name,\n                     String stringData,\n                     AttributeType type,\n                     Object data,\n                     StringSection stringSection) {\n        this.uri = stringSection.getStringIndex(uri);\n        this.name = stringSection.getStringIndex(name);\n        this.stringData = stringSection.getStringIndex(stringData);\n        this.attributeType = type.getIntType();\n\n        if (attributeType == AttributeType.STRING.getIntType()) {\n            if (this.stringData == -1) {\n                this.stringData = stringSection.putStringIndex(stringData);\n            }\n            this.data = -1;\n        } else {\n            this.data = (int) data;\n        }\n\n    }\n\n    public Attribute(IntReader reader) {\n        try {\n            uri = reader.readInt();\n            name = reader.readInt();\n            stringData = reader.readInt();\n            attributeType = reader.readInt();\n            data = reader.readInt();\n        } catch (IOException exception) {\n            // TODO : Handle this better\n            exception.printStackTrace();\n        }\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#readHeader(android.content.res.IntReader)\n     */\n    @Override\n    public void readHeader(IntReader inputReader) throws IOException {\n        // No header to read here\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#getChunkType()\n     */\n    @Override\n    public ChunkType getChunkType() {\n        return ChunkType.ATTRIBUTE;\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#getSize()\n     */\n    @Override\n    public int getSize() {\n        return 4 * 5;\n    }\n\n    public int getNameIndex() {\n        return name;\n    }\n\n    public int getStringDataIndex() {\n        return stringData;\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#toXML(android.content.res.chunk.sections.StringSection,\n     * android.content.res.chunk.sections.ResourceSection, int)\n     */\n    @Override\n    public String toXML(StringSection stringSection, ResourceSection resourceSection, int indent) {\n        StringBuffer buffer = new StringBuffer();\n        if ((uri - 1) > 0) {\n            buffer.append(stringSection.getString(uri - 1));\n            buffer.append(\":\");\n        }\n\n        buffer.append(stringSection.getString(name));\n\n        buffer.append(\"=\\\"\");\n\n        // TODO : This should be a switch...\n        if (attributeType == AttributeType.STRING.getIntType()) {\n            buffer.append(stringSection.getString(stringData));\n        } else if (attributeType == AttributeType.INT.getIntType()) {\n            buffer.append(data);\n        } else if (attributeType == AttributeType.RESOURCE.getIntType()) {\n            buffer.append(\"@\");\n            buffer.append(Integer.toHexString(data).toUpperCase());\n        } else if (attributeType == AttributeType.BOOLEAN.getIntType()) {\n            // TODO : Double check this..\n            if (data == -1) {\n                buffer.append(\"true\");\n            } else if (data == 0) {\n                buffer.append(\"false\");\n            } else {\n                buffer.append(\"ERROR\");\n            }\n        }\n\n        buffer.append(\"\\\"\");\n\n        return buffer.toString();\n    }\n\n    /*\n     * (non-Javadoc)\n     *\n     * @see android.content.res.chunk.types.Chunk#toBytes()\n     */\n    @Override\n    public byte[] toBytes() {\n        return ByteBuffer.allocate(getSize())\n                .order(ByteOrder.LITTLE_ENDIAN)\n                .putInt(uri)\n                .putInt(name)\n                .putInt(stringData)\n                .putInt(attributeType)\n                .putInt(data)\n                .array();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/types/Buffer.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk.types;\n\nimport android.content.res.IntReader;\nimport android.content.res.chunk.ChunkType;\nimport android.content.res.chunk.sections.ResourceSection;\nimport android.content.res.chunk.sections.StringSection;\n\nimport java.io.IOException;\n\n/**\n * This \"buffer\" chunk is currently being used for empty space, though it might not be needed\n * <p>\n * TODO: Verify this is needed\n * <p>\n * TODO: If kept, should potentially alert/warn if it happens\n *\n * @author tstrazzere\n */\npublic class Buffer implements Chunk {\n\n    public Buffer(ChunkType chunkType, IntReader inputReader) {\n\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#readHeader(android.content.res.IntReader)\n     */\n    @Override\n    public void readHeader(IntReader inputReader) throws IOException {\n        // No header to read here\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#getChunkType()\n     */\n    @Override\n    public ChunkType getChunkType() {\n        return ChunkType.BUFFER;\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#getSize()\n     */\n    @Override\n    public int getSize() {\n        return 4;\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#toXML(android.content.res.chunk.sections.StringSection,\n     * android.content.res.chunk.sections.ResourceSection, int)\n     */\n    @Override\n    public String toXML(StringSection stringSection, ResourceSection resourceSection, int indent) {\n        return null;\n    }\n\n    /*\n     * (non-Javadoc)\n     *\n     * @see android.content.res.chunk.types.Chunk#toBytes()\n     */\n    @Override\n    public byte[] toBytes() {\n        return new byte[]{\n                0x00, 0x00, 0x00, 0x00\n        };\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/types/Chunk.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk.types;\n\nimport android.content.res.IntReader;\nimport android.content.res.chunk.ChunkType;\nimport android.content.res.chunk.sections.ResourceSection;\nimport android.content.res.chunk.sections.StringSection;\n\nimport java.io.IOException;\n\n/**\n * Generic interface for everything that is at minimum a \"chunk\"\n *\n * @author tstrazzere\n */\npublic interface Chunk {\n    public static String BLANK = \" \";\n    /**\n     * Read the header section of the chunk\n     *\n     * @param reader\n     * @throws IOException\n     */\n    public void readHeader(IntReader reader) throws IOException;\n\n    /**\n     * @return the ChunkType for the current Chunk\n     */\n    public ChunkType getChunkType();\n\n    /**\n     * @return the int size of the ChunkType\n     */\n    public int getSize();\n\n    // XXX: Not sure this needs to exist\n\n    /**\n     * @return a String representation of the Chunk\n     */\n    public String toString();\n\n    /**\n     * @param stringSection\n     * @param resourceSection\n     * @param indent\n     * @return a String representation in XML form\n     */\n    public String toXML(StringSection stringSection, ResourceSection resourceSection, int indent);\n\n    /**\n     * Get the a byte[] for the chunk\n     *\n     * @return\n     */\n    public byte[] toBytes();\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/types/EndTag.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk.types;\n\nimport android.content.res.IntReader;\nimport android.content.res.chunk.ChunkType;\nimport android.content.res.chunk.sections.ResourceSection;\nimport android.content.res.chunk.sections.StringSection;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\n\n/**\n * Specific chunk for ending sections and/or namespaces\n *\n * @author tstrazzere\n */\npublic class EndTag extends GenericChunk implements Chunk {\n\n    private int lineNumber;\n    private int commentIndex;\n    private int namespaceUri;\n    private int name;\n\n    public EndTag(ChunkType chunkType, IntReader inputReader) {\n        super(chunkType, inputReader);\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#readHeader(android.content.res.IntReader)\n     */\n    @Override\n    public void readHeader(IntReader inputReader) throws IOException {\n        lineNumber = inputReader.readInt();\n        commentIndex = inputReader.readInt();\n        namespaceUri = inputReader.readInt();\n        name = inputReader.readInt();\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#toXML(android.content.res.chunk.sections.StringSection,\n     * android.content.res.chunk.sections.ResourceSection, int)\n     */\n    @Override\n    public String toXML(StringSection stringSection, ResourceSection resourceSection, int indent) {\n        return indent(indent) + \"</\" + stringSection.getString(name) + \">\";\n    }\n\n    /*\n     * (non-Javadoc)\n     *\n     * @see android.content.res.chunk.types.Chunk#toBytes()\n     */\n    @Override\n    public byte[] toBytes() {\n        byte[] header = super.toBytes();\n\n        byte[] body = ByteBuffer.allocate(4 * 4)\n                .order(ByteOrder.LITTLE_ENDIAN)\n                .putInt(lineNumber)\n                .putInt(commentIndex)\n                .putInt(namespaceUri)\n                .putInt(name)\n                .array();\n\n        return ByteBuffer.allocate(header.length + body.length)\n                .order(ByteOrder.LITTLE_ENDIAN)\n                .put(header)\n                .put(body)\n                .array();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/types/GenericChunk.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk.types;\n\nimport android.content.res.IntReader;\nimport android.content.res.chunk.ChunkType;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\n\n/**\n * Abstract class for the generic lifting required by all Chunks\n *\n * @author tstrazzere\n */\npublic abstract class GenericChunk implements Chunk {\n\n    private int startPosition;\n\n    private ChunkType type;\n    protected int size;\n\n    public GenericChunk(ChunkType chunkType, IntReader reader) {\n        startPosition = reader.getBytesRead() - 4;\n        type = chunkType;\n        try {\n            size = reader.readInt();\n            readHeader(reader);\n        } catch (IOException exception) {\n            // TODO : Handle this better\n            exception.printStackTrace();\n        }\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#getChunkType()\n     */\n    public ChunkType getChunkType() {\n        return type;\n    }\n\n    /*\n     *` (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#getSize()\n     */\n    public int getSize() {\n        return size;\n    }\n\n    /**\n     * @return the int position inside of the file where the Chunk starts\n     */\n    public int getStartPosition() {\n        return startPosition;\n    }\n\n    /**\n     * @param indents\n     * @return a number of indents needed for properly formatting XML\n     */\n    protected String indent(int indents) {\n        StringBuffer buffer = new StringBuffer();\n        for (int i = 0; i < indents; i++) {\n            buffer.append(\"\\t\");\n        }\n        return buffer.toString();\n    }\n\n    /*\n     * (non-Javadoc)\n     *\n     * @see android.content.res.chunk.types.Chunk#toBytes()\n     */\n    @Override\n    public byte[] toBytes() {\n        return ByteBuffer.allocate(8)\n                .order(ByteOrder.LITTLE_ENDIAN)\n                .putInt(type.getIntType())\n                .putInt(getSize()).array();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/types/NameSpace.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk.types;\n\nimport android.content.res.IntReader;\nimport android.content.res.chunk.ChunkType;\nimport android.content.res.chunk.sections.ResourceSection;\nimport android.content.res.chunk.sections.StringSection;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\n\n/**\n * Namespace Chunk - used for denoting the borders of the XML boundries\n *\n * @author tstrazzere\n */\npublic class NameSpace extends GenericChunk implements Chunk {\n\n    private int lineNumber;\n    private int commentIndex;\n    private int prefix;\n    private int uri;\n\n    public NameSpace(ChunkType chunkType, IntReader inputReader) {\n        super(chunkType, inputReader);\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#readHeader(android.content.res.IntReader)\n     */\n    @Override\n    public void readHeader(IntReader inputReader) throws IOException {\n        lineNumber = inputReader.readInt();\n        commentIndex = inputReader.readInt();\n        prefix = inputReader.readInt();\n        uri = inputReader.readInt();\n    }\n\n    /**\n     * @return if the Namespace Chunk is either a START_NAMESPACE or END_NAMESPACE\n     */\n    public boolean isStart() {\n        return (getChunkType() == ChunkType.START_NAMESPACE) ? true : false;\n    }\n\n    public int getUri() {\n        return uri;\n    }\n\n    public int getPrefix() {\n        return prefix;\n    }\n\n    public int getLineNumber() {\n        return lineNumber;\n    }\n\n    public String toString(StringSection stringSection) {\n        return \"xmlns\" + \":\" + stringSection.getString(getPrefix()) + \"=\\\"\" + stringSection.getString(getUri()) + \"\\\"\";\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#toXML(android.content.res.chunk.sections.StringSection,\n     * android.content.res.chunk.sections.ResourceSection, int)\n     */\n    @Override\n    public String toXML(StringSection stringSection, ResourceSection resourceSection, int indent) {\n        if (isStart()) {\n            return indent(indent) + toString(stringSection);\n        } else {\n            return \"\";\n        }\n    }\n\n    /*\n     * (non-Javadoc)\n     *\n     * @see android.content.res.chunk.types.Chunk#toBytes()\n     */\n    @Override\n    public byte[] toBytes() {\n        byte[] header = super.toBytes();\n\n        byte[] body = ByteBuffer.allocate(4 * 4)\n                .order(ByteOrder.LITTLE_ENDIAN)\n                .putInt(lineNumber)\n                .putInt(commentIndex)\n                .putInt(prefix)\n                .putInt(uri)\n                .array();\n\n        return ByteBuffer.allocate(header.length + body.length)\n                .order(ByteOrder.LITTLE_ENDIAN)\n                .put(header)\n                .put(body)\n                .array();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/types/StartTag.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk.types;\n\nimport android.content.res.IntReader;\nimport android.content.res.chunk.ChunkType;\nimport android.content.res.chunk.sections.ResourceSection;\nimport android.content.res.chunk.sections.StringSection;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.util.ArrayList;\nimport java.util.Iterator;\n\n/**\n * StartTag type of Chunk, differs from a Namespace as there will be specific metadata inside of it\n *\n * @author tstrazzere\n */\npublic class StartTag extends GenericChunk implements Chunk {\n\n    private int                  lineNumber;\n    private int                  commentIndex;\n    private int                  namespaceUri;\n    private int                  name;\n    private int                  flags;\n    private int                  attributeCount;\n    private int                  classAttribute;\n    private ArrayList<Attribute> attributes;\n\n    public StartTag(ChunkType chunkType, IntReader inputReader){\n        super(chunkType, inputReader);\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#readHeader(android.content.res.IntReader)\n     */\n    @Override\n    public void readHeader(IntReader inputReader) throws IOException {\n        lineNumber = inputReader.readInt();\n        commentIndex = inputReader.readInt();\n        namespaceUri = inputReader.readInt();\n        name = inputReader.readInt();\n        flags = inputReader.readInt();\n        attributeCount = inputReader.readInt();\n        classAttribute = inputReader.readInt();\n\n        attributes = new ArrayList<>();\n        if (attributeCount > 0) {\n            for (int i = 0; i < attributeCount; i++) {\n                attributes.add(new Attribute(inputReader));\n            }\n        }\n    }\n\n    public int getLineNumber() {\n        return lineNumber;\n    }\n\n    @Override\n    public int getSize() {\n        return (9 * 4) + (attributeCount * 20);\n    }\n\n    public ArrayList<Attribute> getAttributes() {\n        return attributes;\n    }\n\n    public void insertOrReplaceAttribute(Attribute newAttribute) {\n        Iterator<Attribute> iterator = attributes.iterator();\n        while (iterator.hasNext()) {\n            Attribute attribute = iterator.next();\n            if (attribute.getNameIndex() == newAttribute.getNameIndex()) {\n                iterator.remove();\n            }\n        }\n\n        attributes.add(newAttribute);\n    }\n\n    public String getName(StringSection stringSection) {\n        return stringSection.getString(name);\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#toXML(android.content.res.chunk.sections.StringSection,\n     * android.content.res.chunk.sections.ResourceSection, int)\n     */\n    @Override\n    public String toXML(StringSection stringSection, ResourceSection resourceSection, int indent) {\n        StringBuffer buffer = new StringBuffer();\n        buffer.append(indent(indent));\n        buffer.append(\"<\");\n        buffer.append(stringSection.getString(name));\n        buffer.append(BLANK);\n\n        for (int i = 0; i < attributeCount; i++) {\n            buffer.append(indent(indent + 1));\n            buffer.append(attributes.get(i).toXML(stringSection, resourceSection, indent));\n            buffer.append(BLANK);\n        }\n\n        buffer.append(indent(indent + 1));\n        buffer.append(\">\");\n\n        return buffer.toString();\n    }\n\n    public String toXMLWithNamespace(StringSection stringSection, ResourceSection resourceSection, int indent,String nameSpace) {\n        StringBuffer buffer = new StringBuffer();\n        buffer.append(indent(indent));\n        buffer.append(\"<\");\n        buffer.append(stringSection.getString(name));\n        buffer.append(\"\\n\");\n\n        buffer.append(nameSpace);\n        for (int i = 0; i < attributeCount; i++) {\n            buffer.append(indent(indent + 1));\n            buffer.append(attributes.get(i).toXML(stringSection, resourceSection, indent));\n            buffer.append(\"\\n\");\n        }\n\n        buffer.append(indent(indent + 1));\n        buffer.append(\">\");\n\n        return buffer.toString();\n    }\n\n\n    /*\n     * (non-Javadoc)\n     *\n     * @see android.content.res.chunk.types.Chunk#toBytes()\n     */\n    @Override\n    public byte[] toBytes() {\n        byte[] header = super.toBytes();\n\n        byte[] staticBody = ByteBuffer.allocate(7\n                                                * 4).order(ByteOrder.LITTLE_ENDIAN).putInt(lineNumber).putInt(commentIndex).putInt(namespaceUri).putInt(name).putInt(flags).putInt(attributes.size()).putInt(classAttribute).array();\n\n        byte[] dynamicBody;\n        if (attributes.size() > 0) {\n            ByteBuffer attributeData = ByteBuffer.allocate(attributes.size() * 20).order(ByteOrder.LITTLE_ENDIAN);\n            for (Attribute attribute : attributes) {\n                attributeData.put(attribute.toBytes());\n            }\n\n            dynamicBody = attributeData.array();\n        } else {\n            dynamicBody = new byte[] {};\n        }\n\n        return ByteBuffer.allocate(header.length + staticBody.length\n                                   + dynamicBody.length).order(ByteOrder.LITTLE_ENDIAN).put(header).put(staticBody).put(dynamicBody).array();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/android/content/res/chunk/types/TextTag.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage android.content.res.chunk.types;\n\nimport android.content.res.IntReader;\nimport android.content.res.chunk.ChunkType;\nimport android.content.res.chunk.sections.ResourceSection;\nimport android.content.res.chunk.sections.StringSection;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\n\n/**\n * Specific Chunk which contains a text key and value\n *\n * @author tstrazzere\n */\npublic class TextTag extends GenericChunk implements Chunk {\n\n    private int lineNumber;\n    private int commentIndex;\n\n    private int name;\n    private int rawValue;\n    private int typedValue;\n\n    public TextTag(ChunkType chunkType, IntReader inputReader) {\n        super(chunkType, inputReader);\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#readHeader(android.content.res.IntReader)\n     */\n    @Override\n    public void readHeader(IntReader inputReader) throws IOException {\n        lineNumber = inputReader.readInt();\n        commentIndex = inputReader.readInt();\n        name = inputReader.readInt();\n        rawValue = inputReader.readInt();\n        typedValue = inputReader.readInt();\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see android.content.res.chunk.types.Chunk#toXML(android.content.res.chunk.sections.StringSection,\n     * android.content.res.chunk.sections.ResourceSection, int)\n     */\n    @Override\n    public String toXML(StringSection stringSection, ResourceSection resourceSection, int indent) {\n        StringBuffer buffer = new StringBuffer();\n\n        buffer.append(indent(indent));\n        buffer.append(stringSection.getString(name));\n\n        return buffer.toString();\n    }\n\n    /*\n     * (non-Javadoc)\n     *\n     * @see android.content.res.chunk.types.Chunk#toBytes()\n     */\n    @Override\n    public byte[] toBytes() {\n        byte[] header = super.toBytes();\n\n        byte[] body = ByteBuffer.allocate(5 * 4)\n                .order(ByteOrder.LITTLE_ENDIAN)\n                .putInt(lineNumber)\n                .putInt(commentIndex)\n                .putInt(name)\n                .putInt(rawValue)\n                .putInt(typedValue)\n                .array();\n\n        return ByteBuffer.allocate(header.length + body.length)\n                .order(ByteOrder.LITTLE_ENDIAN)\n                .put(header)\n                .put(body)\n                .array();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/PatchManager.java",
    "content": "package com.taobao.android;\n\nimport com.android.utils.ILogger;\nimport com.taobao.android.inputs.BaseInput;\nimport com.taobao.android.outputs.PatchFile;\nimport com.taobao.android.tools.*;\n\n/**\n * @author lilong\n * @create 2017-11-03 上午12:03\n */\n\npublic class PatchManager {\n    private BaseInput input;\n    public void setLogger(ILogger logger) {\n        this.logger = logger;\n    }\n\n    private ILogger logger;\n\n    public PatchManager(BaseInput input) {\n        this.input = input;\n    }\n\n    public PatchFile doPatch() throws Exception {\n        AbstractTool abstractTool = null;\n       if (input.patchType.equals(PatchType.TPATCH)){\n           abstractTool = new TPatchTool();\n       }else if (input.patchType.equals(PatchType.DEXPATCH)){\n           abstractTool = new DexPatchTool();\n       }else if (input.patchType.equals(PatchType.APATCH)){\n           abstractTool = new APatchTool();\n       }else if (input.patchType.equals(PatchType.HOTFIX)){\n           abstractTool = new HotPatchTool();\n       }\n       abstractTool.setInput(input);\n       abstractTool.setLogger(logger);\n\n       return abstractTool.doPatch();\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/PatchType.java",
    "content": "package com.taobao.android;\n\n/**\n * @author lilong\n * @create 2017-11-02 下午11:40\n */\n\npublic enum PatchType {\n\n    DEXPATCH,SOPHIX,APATCH,TPATCH,HOTFIX;\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/apatch/AndFixFilterImpl.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.apatch;\n\nimport com.taobao.android.filter.AbstractDexFilter;\nimport com.taobao.android.differ.dex.PatchException;\nimport com.taobao.android.object.ClassDiffInfo;\nimport com.taobao.android.object.DexDiffInfo;\nimport com.taobao.android.object.DiffType;\nimport com.taobao.android.object.FieldDiffInfo;\nimport com.taobao.android.object.MethodDiffInfo;\n\nimport org.jf.dexlib2.dexbacked.DexBackedClassDef;\nimport org.jf.dexlib2.dexbacked.DexBackedField;\nimport org.jf.dexlib2.dexbacked.DexBackedMethod;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * Created by lilong on 16/6/17.\n * <p/>\n\n */\npublic class AndFixFilterImpl extends AbstractDexFilter {\n\n\n    public AndFixFilterImpl(DexDiffInfo diffInfo) throws PatchException {\n        super(diffInfo);\n\n\n    }\n\n    @Override\n    public boolean filterClass(ClassDiffInfo classDiffInfo) throws PatchException {\n        boolean isInnerclass = false;\n        DexBackedClassDef dexBackedClassDef = classDiffInfo.getClassDef();\n        if (classDiffInfo.getType().equals(DiffType.ADD)) {\n            return false;\n//            if (dexBackedClassDef.getAnnotations().size() > 0) {\n//                Set<? extends Annotation> annotations = dexBackedClassDef.getAnnotations();\n//                for (Annotation dexBackedAnnotation : annotations) {\n//                    if (dexBackedAnnotation.getType().equals(\"dalvik/annotation/EnclosingClass;\"))\n//                        throw new PatchException(\"can't add member class:\" + dexBackedClassDef.getType());\n//                }\n//            }\n//            String className = DexDiffer.getDalvikClassName(dexBackedClassDef.getType());\n//            MappingParser mappingParser = new MappingParser(APatchTool.mappingFile);\n//            String outterClassName = mappingParser.getOuterClass(className);\n//            if (!className.equals(outterClassName)) {\n//                isInnerclass = true;\n//                if (SmaliDiffUtils.diff(diffInfo, outterClassName, className, outFile)) {\n//                    classDiffInfo.setType(DiffType.NONE);\n//                    return true;\n//                } else {\n//                    throw new PatchException(\"can't add anonymous class;\" + dexBackedClassDef.getType());\n//                }\n//            }\n//            throw new PatchException(\"can't add class:\" + dexBackedClassDef.getType());\n        } else if (classDiffInfo.getType().equals(DiffType.MODIFY)) {\n            if (classDiffInfo.getName().endsWith(\".R\")||classDiffInfo.getName().contains(\".R$\")){\n                return true;\n            }\n            Set<MethodDiffInfo> needFilterMethod = new HashSet<MethodDiffInfo>();\n            Set<FieldDiffInfo> needFilterField = new HashSet<FieldDiffInfo>();\n\n            if (classDiffInfo.getModifyMethods().size() > 0) {\n                for (MethodDiffInfo methodDiffInfo : classDiffInfo.getModifyMethods()) {\n                    if (filterMethod(methodDiffInfo)) {\n                        System.out.println(methodDiffInfo.getBackedMethod().getDefiningClass()+\":\"+methodDiffInfo.getBackedMethod().getName()+ \" is filtered!\");\n                        needFilterMethod.add(methodDiffInfo);\n                    }\n                }\n            }\n            classDiffInfo.getModifyMethods().removeAll(needFilterMethod);\n            if (classDiffInfo.getModifyFields().size() > 0) {\n                for (FieldDiffInfo fieldDiffInfo : classDiffInfo.getModifyFields()) {\n                    if (filterField(fieldDiffInfo)) {\n                        needFilterField.add(fieldDiffInfo);\n                    }\n                }\n            }\n            classDiffInfo.getModifyFields().removeAll(needFilterField);\n            if (classDiffInfo.getModifyFields().size() == 0 && classDiffInfo.getModifyMethods().size() == 0) {\n                classDiffInfo.setType(DiffType.NONE);\n                return true;\n            }\n        }\n        return false;\n    }\n\n    @Override\n    public boolean filterMethod(MethodDiffInfo methodDiffInfo) throws PatchException {\n        DexBackedMethod dexBackedMethod = methodDiffInfo.getBackedMethod();\n        if (dexBackedMethod.getName().equals(\"<clinit>\") || dexBackedMethod.getName().contains(\"ajc$preClinit\")||dexBackedMethod.getName().equals(\"<init>\")||dexBackedMethod.getName().contains(\"access$\")) {\n            return true;\n        }\n\n        if (methodDiffInfo.getType().equals(DiffType.REMOVE)) {\n            return true;\n        } else if (methodDiffInfo.getType().equals(DiffType.ADD)){\n            throw new PatchException(\"can't add method:\" + dexBackedMethod.getName() + \" in class:\" + dexBackedMethod.getDefiningClass());\n        }\n\n        if (dexBackedMethod.getParameters().size() > 8) {\n            throw new PatchException(\"can't patch method:\" + dexBackedMethod.getName() + \"has Parameters above 8 in class:\"+dexBackedMethod.getDefiningClass());\n        }\n        if (dexBackedMethod.getParameterTypes().contains(\"J\") || dexBackedMethod.getParameterTypes().contains(\"D\") || dexBackedMethod.getParameterTypes().contains(\"F\")) {\n           throw new PatchException(\"can't patch method:\" + dexBackedMethod.getName() + \"has ParameterType long,double or float in class:\"+dexBackedMethod.getDefiningClass());\n        }\n        return false;\n    }\n\n    @Override\n    public boolean filterField(FieldDiffInfo fieldDiffInfo) throws PatchException {\n        DexBackedField dexBackedField = fieldDiffInfo.getBackedField();\n        if (dexBackedField.getType().equals(DiffType.ADD)) {\n            throw new PatchException(\"can,t add new Field:\"\n                    + dexBackedField.getName() + \"(\" + dexBackedField.getType() + \"), \" + \"in class :\"\n                    + dexBackedField.getDefiningClass());\n        } else if (dexBackedField.getType().equals(DiffType.MODIFY)) {\n            throw new PatchException(\"can,t modify Field:\"\n                    + dexBackedField.getName() + \"(\" + dexBackedField.getType() + \"), \" + \"in class :\"\n                    + dexBackedField.getDefiningClass());\n        }\n        return true;\n    }\n\n}"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/apatch/ApkPatch.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.apatch;\n\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Sets;\nimport com.taobao.android.apatch.utils.Formater;\nimport com.taobao.android.apatch.utils.SmaliDiffUtils;\nimport com.taobao.android.apatch.utils.TypeGenUtil;\nimport com.taobao.android.differ.dex.DexDiffer;\nimport com.taobao.android.differ.dex.PatchException;\nimport com.taobao.android.object.DexDiffInfo;\nimport org.apache.commons.io.FileUtils;\nimport org.jf.dexlib2.dexbacked.DexBackedAnnotation;\nimport org.jf.dexlib2.dexbacked.DexBackedAnnotationElement;\nimport org.jf.dexlib2.dexbacked.DexBackedClassDef;\nimport org.jf.dexlib2.dexbacked.DexBackedMethod;\nimport org.jf.dexlib2.dexbacked.value.DexBackedAnnotationEncodedValue;\nimport org.jf.dexlib2.dexbacked.value.DexBackedArrayEncodedValue;\nimport org.jf.dexlib2.dexbacked.value.DexBackedTypeEncodedValue;\nimport org.jf.dexlib2.iface.Annotation;\nimport org.jf.dexlib2.iface.AnnotationElement;\nimport org.jf.dexlib2.iface.value.EncodedValue;\nimport org.jf.dexlib2.iface.value.TypeEncodedValue;\nimport org.jf.util.ClassFileNameHandler;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.sql.Date;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.jar.Attributes;\nimport java.util.jar.Manifest;\n\n\n/**\n */\npublic class ApkPatch extends com.taobao.android.apatch.Build {\n\n    private List<File> baseFiles = Lists.newArrayList();\n    private List<File> newFiles = Lists.newArrayList();\n\n    private File diffFile;\n    private File diffJsonFile;\n    private Set<String> classes;\n\n    public static String currentClassType;\n\n    // 设置白名单文件路径\n    public void setPath(String filterPath) {\n        this.filterPath = filterPath;\n    }\n\n    public ApkPatch(File baseFile, File newFile, String name, File out) {\n        super(name, out);\n        this.baseFiles.add(baseFile);\n        this.newFiles.add(newFile);\n\n    }\n\n    public ApkPatch(List<File> baseFiles, List<File> newFiles, String name, File out) {\n        super(name, out);\n        this.baseFiles = baseFiles;\n        this.newFiles = newFiles;\n\n    }\n\n    public void setDiffFile(File diffFile) {\n        this.diffFile = diffFile;\n    }\n\n    public void setDiffJsonFile(File diffJsonFile) {\n        this.diffJsonFile = diffJsonFile;\n    }\n\n    public File doPatch() throws PatchException {\n        try {\n            File aptchFolder = new File(out, name);\n            File smaliDir = new File(aptchFolder, \"smali\");\n            if (!smaliDir.exists()) {\n                smaliDir.mkdirs();\n            }\n            try {\n                FileUtils.cleanDirectory(smaliDir);\n            } catch (IOException e) {\n                throw new RuntimeException(e);\n            }\n\n            File dexFile = new File(aptchFolder, \"diff.dex\");\n            if (dexFile.exists() && !dexFile.delete()) {\n                throw new RuntimeException(\"diff.dex can't be removed.\");\n            }\n            File outFile = new File(aptchFolder, \"diff\" + SUFFIX);\n            if (outFile.exists() && !outFile.delete()) {\n                throw new RuntimeException(\"diff\" + SUFFIX + \" can't be removed.\");\n            }\n\n            currentTimeStamp = System.currentTimeMillis();\n            DexDiffer dexDiffer = new DexDiffer(baseFiles, newFiles, 19);\n            dexDiffer.setTpatch(false);\n            // 创建白名单过滤类\n            if ((this.filterPath != null) && !(this.filterPath.equals(\"\"))) {\n                dexDiffer.createFilter(this.filterPath);\n            }\n            //diff\n            DexDiffInfo info = dexDiffer.doDiff();\n            dexDiffer.setDexDiffFilter(new AndFixFilterImpl(info));\n\n            //diffFilter\n            dexDiffer.dexFilter();\n\n            info.update();\n            //写json\n            if (null != diffFile && null != diffJsonFile) {\n                info.writeToFile(name, diffFile, diffJsonFile);\n            }\n\n            //生成dex\n            classes = SmaliDiffUtils.buildCode(smaliDir,dexFile, info);\n            if (null == classes || classes.size() <= 0) {\n                return null;\n            }\n\n\n            File smaliDir2 = new File(aptchFolder, \"smali2\");\n            if (!smaliDir2.exists()) {\n                smaliDir2.mkdirs();\n            }\n            try {\n                FileUtils.cleanDirectory(smaliDir2);\n            } catch (IOException e) {\n                throw new RuntimeException(e);\n            }\n            prepareClasses = buildPrepareClass(smaliDir2, newFiles, info);\n\n            DexDiffInfo.release();\n            build(outFile, dexFile);\n            File file = release(aptchFolder, dexFile, outFile);\n            release();\n            return file;\n        } catch (Exception e) {\n            throw new PatchException(e);\n        }\n    }\n\n\n    private static Set<String> buildPrepareClass(File smaliDir, List<File> newFiles,\n                                                 DexDiffInfo info) throws PatchException {\n        Set<DexBackedClassDef> classes = Sets.newHashSet();\n        classes = SmaliDiffUtils.scanClasses(smaliDir, newFiles);\n        ArrayList<String> methods = new ArrayList<String>();\n        {\n            Set<DexBackedMethod> tempSet = info.getModifiedMethods();\n            for (DexBackedMethod methodRef : tempSet) {\n                String template = methodRef.getDefiningClass() + \"->\" + methodRef.getName();\n                methods.add(template);\n                System.out.println(\"template: \" + template);\n                if (superClasses.containsKey(methodRef.getDefiningClass())) {\n                    ArrayList<String> derivedClasses = superClasses.get(methodRef.getDefiningClass());\n                    for (int i = 0; i < derivedClasses.size(); i++) {\n                        template = derivedClasses.get(i) + \"->\" + methodRef.getName();\n                        System.out.println(\"template: \" + template);\n                        methods.add(template);\n                    }\n                }\n            }\n        }\n\n        Set<String> prepareClasses = new HashSet<String>();\n        try {\n            final ClassFileNameHandler inFileNameHandler = new ClassFileNameHandler(smaliDir, \".smali\");\n            for (DexBackedClassDef classDef : classes) {\n                currentClassType = null;\n                String className = TypeGenUtil.newType(classDef.getType());\n                // baksmali.disassembleClass(classDef, outFileNameHandler, options);\n                File smaliFile = inFileNameHandler.getUniqueFilenameForClass(className);\n                if (!smaliFile.exists()){\n                    continue;\n                }\n                //增加class注解到prepare\n                getClassAnnotaionPrepareClasses(classDef,prepareClasses,info);\n\n                BufferedReader br = new BufferedReader(new FileReader(smaliFile));\n                String data = br.readLine();// 一次读入一行，直到读入null为文件结束\n                while (data != null) {\n                    boolean find = false;\n                    for (String m : methods) {\n                        if (data.contains(m)) {\n                            find = true;\n                            break;\n                        }\n                    }\n                    if (find) {\n                        prepareClasses.add(className.substring(1, className.length() - 1).replace('/', '.'));\n                        System.out.println(\"prepare class: \" + className);\n                        break;\n                    }\n                    data = br.readLine(); // 接着读下一行\n                }\n                br.close();\n\n            }\n        } catch (Exception e) {\n            throw new PatchException(e);\n        }\n        for (DexBackedMethod method:info.getModifiedMethods()) {\n            prepareClasses.add(method.getDefiningClass().substring(1, method.getDefiningClass().length() - 1).replace(\"/\", \".\"));\n        }\n        //增加modify的anatation到prepare\n//        getMethodAnnotaionPrepareClasses(info,prepareClasses);\n        return prepareClasses;\n    }\n\n\n    public static void getMethodAnnotaionPrepareClasses(DexDiffInfo dexDiffInfo, Set<String> prepareclasses){\n\n        for (DexBackedMethod method:dexDiffInfo.getModifiedMethods()){\n            Set<? extends Annotation>annotations = method.getAnnotations();\n            if (annotations == null){\n                continue;\n            }\n            for (Annotation annotation:annotations){\n                String type = annotation.getType();\n                if (type!= null&&type.startsWith(\"L\")&&type.endsWith(\";\")){\n                    prepareclasses.add(type.substring(1, type.length() - 1).replace('/', '.'));\n                    System.out.println(\"prepare class: \" + type);\n                }\n                Set<? extends AnnotationElement> elements = annotation.getElements();\n                for (AnnotationElement dexBackedAnnotationElement:elements){\n                    if (dexBackedAnnotationElement.getValue() instanceof DexBackedArrayEncodedValue){\n                        List<? extends EncodedValue> values = ((DexBackedArrayEncodedValue) dexBackedAnnotationElement.getValue()).getValue();\n                        for (EncodedValue encodedValue:values) {\n                            if (encodedValue instanceof TypeEncodedValue) {\n                                prepareclasses.add(((TypeEncodedValue) encodedValue).getValue().substring(1, ((TypeEncodedValue) encodedValue).getValue().length() - 1).replace('/', '.'));\n                                System.out.println(\"prepare class: \" + ((TypeEncodedValue) encodedValue).getValue());\n                            }\n                        }\n\n                    }else if (dexBackedAnnotationElement.getValue() instanceof DexBackedTypeEncodedValue){\n                        String value = ((DexBackedTypeEncodedValue) dexBackedAnnotationElement.getValue()).getValue();\n                        prepareclasses.add(value.substring(1, value.length() - 1).replace('/', '.'));\n                        System.out.println(\"prepare class: \" + value);\n                    }\n                }\n            }\n        }\n\n    }\n\n    public static void getClassAnnotaionPrepareClasses(DexBackedClassDef classDef, Set<String> prepareclasses,DexDiffInfo dexDiffInfo){\n\n        for (DexBackedClassDef modifyClasses:dexDiffInfo.getModifiedClasses()){\n            if (classDef.getType().equals(modifyClasses.getType())){\n                if (classDef.getAnnotations()!= null){\n                    Set<? extends DexBackedAnnotation>annotations = classDef.getAnnotations();\n                    for (DexBackedAnnotation annotation:annotations){\n                        String type = annotation.getType();\n                        if (type!= null&&type.startsWith(\"L\")&&type.endsWith(\";\")){\n                            prepareclasses.add(type.substring(1, type.length() - 1).replace('/', '.'));\n                            System.out.println(\"prepare class: \" + type);\n                        }\n                        Set<? extends DexBackedAnnotationElement> elements = annotation.getElements();\n                        for (DexBackedAnnotationElement dexBackedAnnotationElement:elements){\n                            if (dexBackedAnnotationElement.getValue() instanceof DexBackedArrayEncodedValue){\n                                List<? extends EncodedValue> values = ((DexBackedArrayEncodedValue) dexBackedAnnotationElement.getValue()).getValue();\n                                for (EncodedValue encodedValue:values) {\n                                    if (encodedValue instanceof TypeEncodedValue) {\n                                        prepareclasses.add(((TypeEncodedValue) encodedValue).getValue().substring(1, ((TypeEncodedValue) encodedValue).getValue().length() - 1).replace('/', '.'));\n                                        System.out.println(\"prepare class: \" + ((TypeEncodedValue) encodedValue).getValue());\n                                    }\n                                }\n\n                            }else if (dexBackedAnnotationElement.getValue() instanceof DexBackedTypeEncodedValue){\n                                String value = ((DexBackedTypeEncodedValue) dexBackedAnnotationElement.getValue()).getValue();\n                                prepareclasses.add(value.substring(1, value.length() - 1).replace('/', '.'));\n                                System.out.println(\"prepare class: \" + value);\n                            }else if (dexBackedAnnotationElement.getValue() instanceof DexBackedAnnotationEncodedValue){\n                                String value = ((DexBackedAnnotationEncodedValue) dexBackedAnnotationElement.getValue()).getType();\n                            }\n\n                        }\n                    }\n\n                }\n            }\n        }\n\n    }\n\n\n    @SuppressWarnings(\"deprecation\")\n    protected Manifest getMeta() {\n        Manifest manifest = new Manifest();\n        Attributes main = manifest.getMainAttributes();\n        main.putValue(\"Manifest-Version\", \"1.0\");\n        main.putValue(\"Created-By\", \"1.0 (ApkPatch)\");\n        main.putValue(\"Created-Time\", new Date(System.currentTimeMillis()).toGMTString());\n        main.putValue(\"From-File\", baseFiles.get(0).getName());\n        main.putValue(\"To-File\", newFiles.get(0).getName());\n        main.putValue(\"Patch-Name\", name);\n        main.putValue(name + \"-Patch-Classes\", Formater.dotStringList(classes));\n        main.putValue(name + \"-Prepare-Classes\", Formater.dotStringList(prepareClasses));\n        main.putValue(name + \"-Used-Methods\", Formater.dotStringList(usedMethods));\n        main.putValue(name + \"-Modified-Classes\", Formater.dotStringList(modifiedClasses));\n        main.putValue(name + \"-Used-Classes\", Formater.dotStringList(usedClasses));\n        main.putValue(name + \"-add-classes\", Formater.dotStringList(addClasses));\n\n        return manifest;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/apatch/Build.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.apatch;\n\nimport com.taobao.android.apatch.builder.PatchBuilder;\nimport com.taobao.android.apatch.utils.HexUtil;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.security.KeyStoreException;\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.UnrecoverableEntryException;\nimport java.security.cert.CertificateException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.jar.Manifest;\n\n/**\n */\npublic abstract class Build {\n\n    public static Set<String> prepareClasses = new HashSet<String>();\n    protected String filterPath;                                                // 类白名单路径\n    public static Map<String, ArrayList<String>> superClasses = new HashMap<String, ArrayList<String>>();\n    public static Set<String> modifiedClasses = new HashSet<String>();\n    public static Set<String> usedMethods = new HashSet<String>();\n    public static Set<String> usedClasses = new HashSet<String>();\n    public static Set<String> addClasses = new HashSet<String>();\n    public static long currentTimeStamp = 0;\n\n\n    protected static final String SUFFIX = \".jar\";\n    protected String name;\n    protected File out;\n\n    public Build(String name, File out) {\n        this.name = name;\n        this.out = out;\n        if (!out.exists()) {\n            out.mkdirs();\n        } else if (!out.isDirectory()) {\n            throw new RuntimeException(\"output path must be directory.\");\n        }\n    }\n\n\n    protected File release(File outDir, File dexFile, File outFile) throws NoSuchAlgorithmException, IOException {\n        MessageDigest messageDigest = MessageDigest.getInstance(\"md5\");\n        FileInputStream fileInputStream = new FileInputStream(dexFile);\n        byte[] buffer = new byte[8192];\n        int len = 0;\n        while ((len = fileInputStream.read(buffer)) > 0) {\n            messageDigest.update(buffer, 0, len);\n        }\n\n        String md5 = HexUtil.hex(messageDigest.digest());\n        fileInputStream.close();\n        File apatch = new File(outDir, name + \"-\" + md5 + SUFFIX);\n        outFile.renameTo(apatch);\n        return apatch;\n    }\n\n    protected void build(File outFile, File dexFile) throws KeyStoreException, IOException, NoSuchAlgorithmException,\n            CertificateException, UnrecoverableEntryException {\n        PatchBuilder builder = new PatchBuilder(outFile, dexFile, null, System.out);\n        builder.writeMeta(outFile, getMeta());\n        builder.sealPatch();\n    }\n\n    protected abstract Manifest getMeta();\n\n\n    protected void release() {\n        prepareClasses.clear();\n        superClasses.clear();\n        usedMethods.clear();\n        usedClasses.clear();\n        modifiedClasses.clear();\n        addClasses.clear();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/apatch/FastBuild.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.apatch;\n\nimport com.taobao.android.apatch.utils.Formater;\nimport com.taobao.android.apatch.utils.SmaliDiffUtils;\nimport com.taobao.android.differ.dex.PatchException;\nimport com.taobao.android.object.DexDiffInfo;\n\nimport org.antlr.runtime.RecognitionException;\nimport org.apache.commons.io.FileUtils;\nimport org.jf.dexlib2.iface.ClassDef;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.security.KeyStoreException;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.UnrecoverableEntryException;\nimport java.security.cert.CertificateException;\nimport java.sql.Date;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.jar.Attributes;\nimport java.util.jar.Manifest;\n\n/**\n * Created by lilong on 16/7/7.\n */\npublic class FastBuild extends Build {\n\n    private Set<String> classes;\n    private Set<? extends ClassDef> dexBackNewClasses = new HashSet<ClassDef>();\n    private File diffFile;\n    private File diffJsonFile;\n    public static String currentClassType;\n    public DexDiffInfo dexDiffInfo;\n\n    public FastBuild(String name, File out) {\n        super(name, out);\n    }\n\n    public void setDiffFile(File diffFile) {\n        this.diffFile = diffFile;\n    }\n\n    public void setDiffJsonFile(File diffJsonFile) {\n        this.diffJsonFile = diffJsonFile;\n    }\n\n    public void setDiffInfo(DexDiffInfo dexDiffInfo) {\n        this.dexDiffInfo = dexDiffInfo;\n    }\n\n    public void setClasses(Set<? extends ClassDef> dexBackNewClasses) {\n        this.dexBackNewClasses = dexBackNewClasses;\n    }\n\n    public File dopatch() throws IOException, RecognitionException, CertificateException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableEntryException, PatchException {\n\n        File dexFile = new File(out, \"diff.dex\");\n        if (dexFile.exists() && !dexFile.delete()) {\n            throw new RuntimeException(\"diff.dex can't be removed.\");\n        }\n        File outFile = new File(out, \"diff\" + SUFFIX);\n        if (outFile.exists() && !outFile.delete()) {\n            throw new RuntimeException(\"diff\" + SUFFIX + \" can't be removed.\");\n        }\n        currentTimeStamp = System.currentTimeMillis();\n        File smaliDir = new File(out, \"smali\");\n        if (smaliDir.exists()) {\n            FileUtils.cleanDirectory(smaliDir);\n\n        }\n        smaliDir.mkdirs();\n        classes = SmaliDiffUtils.buildCode(smaliDir, dexFile, dexDiffInfo);\n        if (null == classes || classes.size() <= 0) {\n            return null;\n        }\n        if (null != diffFile && null != diffJsonFile) {\n            dexDiffInfo.writeToFile(name, diffFile, diffJsonFile);\n        }\n        DexDiffInfo.release();\n        build(outFile, dexFile);\n        File file = release(out, dexFile, outFile);\n        release();\n\n        return file;\n\n    }\n\n    @Override\n    protected Manifest getMeta() {\n        Manifest manifest = new Manifest();\n        Attributes main = manifest.getMainAttributes();\n        main.putValue(\"Manifest-Version\", \"1.0\");\n        main.putValue(\"Created-By\", \"1.0 (ApkPatch)\");\n        main.putValue(\"Created-Time\", new Date(System.currentTimeMillis()).toGMTString());\n        main.putValue(\"Patch-Name\", name);\n        main.putValue(name + \"-Patch-Classes\", Formater.dotStringList(classes));\n        main.putValue(name + \"-Prepare-Classes\", Formater.dotStringList(prepareClasses));\n        main.putValue(name + \"-Used-Methods\", Formater.dotStringList(usedMethods));\n        main.putValue(name + \"-Modified-Classes\", Formater.dotStringList(modifiedClasses));\n        main.putValue(name + \"-Used-Classes\", Formater.dotStringList(usedClasses));\n        main.putValue(name + \"-add-classes\", Formater.dotStringList(addClasses));\n        return manifest;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/apatch/MergePatch.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.apatch;\n\nimport com.taobao.android.dex.Dex;\nimport com.taobao.android.differ.dex.PatchException;\nimport com.taobao.android.dx.merge.CollisionPolicy;\nimport com.taobao.android.dx.merge.DexMerger;\nimport org.apache.commons.io.FileUtils;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.sql.Date;\nimport java.util.jar.Attributes;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\nimport java.util.jar.Manifest;\n\n/**\n */\npublic class MergePatch extends Build {\n\n    private File[] patchs;\n\n    public MergePatch(File[] patchs, String name, File out) {\n        super(name, out);\n        this.patchs = patchs;\n        assert null != patchs;\n    }\n\n    public File doMerge() throws PatchException {\n        try {\n            File dexFile = new File(out, \"merge.dex\");\n            if (dexFile.exists() && !dexFile.delete()) {\n                throw new RuntimeException(\"merge.dex can't be removed.\");\n            }\n            File outFile = new File(out, \"merge\" + SUFFIX);\n            if (dexFile.exists() && !dexFile.delete()) {\n                throw new RuntimeException(\"merge\" + SUFFIX + \" can't be removed.\");\n            }\n            if (patchs.length > 1) {\n                mergeCode(dexFile);\n                build(outFile, dexFile);\n                return release(out, dexFile, outFile);\n            } else if (patchs.length == 1) {\n                return patchs[0];\n            }\n        } catch (Exception e) {\n            throw new PatchException(e);\n        }\n        return null;\n    }\n\n    private void mergeCode(File dexFile) throws IOException {\n        Dex dexA = null;\n        Dex dexB = null;\n        for (File file : patchs) {\n            if (!dexFile.exists() && dexA == null) {\n                dexA = getDexFromJar(file);\n                continue;\n            } else if (dexFile.exists()) {\n                dexA = new Dex(dexFile);\n            }\n            dexB = getDexFromJar(file);\n            Dex[] dexs = new Dex[2];\n            dexs[0] = dexA;\n            dexs[1] = dexB;\n//            List<Dex>dexes = new ArrayList<>();\n//            List<Dex>dexes = Arrays.asList(dexs);\n            DexMerger dexMerger = new DexMerger(dexs, CollisionPolicy.FAIL);\n            dexMerger.merge().writeTo(dexFile);\n        }\n    }\n\n    private Dex getDexFromJar(File file) throws IOException {\n        JarFile jarFile = null;\n        try {\n            jarFile = new JarFile(file);\n            JarEntry dexEntry = jarFile.getJarEntry(\"classes.dex\");\n            return new Dex(jarFile.getInputStream(dexEntry));\n        } finally {\n            if (jarFile != null) {\n                jarFile.close();\n            }\n        }\n    }\n\n    @SuppressWarnings(\"deprecation\")\n    @Override\n    protected Manifest getMeta() {\n        Manifest retManifest = new Manifest();\n        Attributes main = retManifest.getMainAttributes();\n        main.putValue(\"Manifest-Version\", \"1.0\");\n        main.putValue(\"Created-By\", \"1.0 (ApkPatch)\");\n        main.putValue(\"Created-Time\", new Date(System.currentTimeMillis()).toGMTString());\n        main.putValue(\"Patch-Name\", name);\n\n        try {\n            fillManifest(main);\n        } catch (IOException e) {\n            e.printStackTrace();\n            return null;\n        }\n        return retManifest;\n    }\n\n    private void fillManifest(Attributes main) throws IOException {\n        JarFile jarFile;\n        Manifest manifest;\n        StringBuffer fromBuffer = new StringBuffer();\n        StringBuffer toBuffer = new StringBuffer();\n        String from;\n        String to;\n        String name;\n        // String classes;\n        for (File file : patchs) {\n            jarFile = new JarFile(file);\n            JarEntry dexEntry = jarFile.getJarEntry(\"META-INF/PATCH.MF\");\n            manifest = new Manifest(jarFile.getInputStream(dexEntry));\n            Attributes attributes = manifest.getMainAttributes();\n\n            from = attributes.getValue(\"From-File\");\n            if (fromBuffer.length() > 0) {\n                fromBuffer.append(',');\n            }\n            fromBuffer.append(from);\n            to = attributes.getValue(\"To-File\");\n            if (toBuffer.length() > 0) {\n                toBuffer.append(',');\n            }\n            toBuffer.append(to);\n\n            name = attributes.getValue(\"Patch-Name\");\n            // classes = attributes.getValue(name + \"-Patch-Classes\");\n            main.putValue(name + \"-Patch-Classes\", attributes.getValue(name + \"-Patch-Classes\"));\n            main.putValue(name + \"-Prepare-Classes\", attributes.getValue(name + \"-Prepare-Classes\"));\n            main.putValue(name + \"-Used-Methods\", attributes.getValue(name + \"-Used-Methods\"));\n            main.putValue(name + \"-Modified-Classes\", attributes.getValue(name + \"-Modified-Classes\"));\n            main.putValue(name + \"-Used-Classes\", attributes.getValue(name + \"-Used-Classes\"));\n            main.putValue(name + \"-add-classes\", attributes.getValue(name + \"-add-classes\"));\n\n\n        }\n        main.putValue(\"From-File\", fromBuffer.toString());\n        main.putValue(\"To-File\", toBuffer.toString());\n    }\n\n    }\n\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/apatch/annotation/MethodReplaceAnnotation.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.apatch.annotation;\n\nimport org.jf.dexlib2.AnnotationVisibility;\nimport org.jf.dexlib2.base.BaseAnnotation;\nimport org.jf.dexlib2.base.BaseAnnotationElement;\nimport org.jf.dexlib2.iface.AnnotationElement;\nimport org.jf.dexlib2.iface.value.EncodedValue;\nimport org.jf.dexlib2.immutable.value.ImmutableStringEncodedValue;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * Created by lilong on 16/6/30.\n */\npublic class MethodReplaceAnnotation extends BaseAnnotation {\n    //\tprivate static String ANNOTATION = \"Lc8/vJb;\";\n    public static String ANNOTATION = \"Lcom/alipay/euler/andfix/annotation/MethodReplace;\";\n    private Set<BaseAnnotationElement> mElements = new HashSet<BaseAnnotationElement>();\n\n    @Override\n    public int getVisibility() {\n        return AnnotationVisibility.getVisibility(\"runtime\");\n    }\n\n    @Override\n    public String getType() {\n        return ANNOTATION;\n    }\n\n    public void setType(String type) {\n        ANNOTATION = type;\n    }\n\n\n    public MethodReplaceAnnotation(final String clazz, final String method) {\n        BaseAnnotationElement clazzElement = new BaseAnnotationElement() {\n\n            @Override\n            public EncodedValue getValue() {\n                String name = clazz.substring(1, clazz.length() - 1).replace('/', '.');\n                return new ImmutableStringEncodedValue(name);\n            }\n\n            @Override\n            public String getName() {\n                // TODO Auto-generated method stub\n                return \"clazz\";\n            }\n        };\n        mElements.add(clazzElement);\n\n        BaseAnnotationElement methodElement = new BaseAnnotationElement() {\n\n            @Override\n            public EncodedValue getValue() {\n                return new ImmutableStringEncodedValue(method);\n            }\n\n            @Override\n            public String getName() {\n                // TODO Auto-generated method stub\n                return \"method\";\n            }\n        };\n        mElements.add(methodElement);\n    }\n\n    @Override\n    public Set<? extends AnnotationElement> getElements() {\n        return mElements;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/apatch/builder/PatchBuilder.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.apatch.builder;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.PrintStream;\nimport java.security.KeyStore.PrivateKeyEntry;\nimport java.security.cert.X509Certificate;\nimport java.util.jar.JarEntry;\nimport java.util.jar.Manifest;\n\n/**\n * Created by lilong on 16/6/30.\n */\npublic class PatchBuilder {\n\n    private SignedJarBuilder mBuilder;\n\n    public PatchBuilder(File outFile, File dexFile, PrivateKeyEntry key,\n                        PrintStream verboseStream) {\n        try {\n            if (null != key) {\n                mBuilder = new SignedJarBuilder(\n                        new FileOutputStream(outFile, false), key.getPrivateKey(),\n                        (X509Certificate) key.getCertificate());\n            } else {\n                mBuilder = new SignedJarBuilder(\n                        new FileOutputStream(outFile, false), null,\n                        null);\n            }\n            mBuilder.writeFile(dexFile, \"classes.dex\");\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    public void writeMeta(File outFile, Manifest manifest) {\n        try {\n            mBuilder.getOutputStream().putNextEntry(\n                    new JarEntry(\"META-INF/PATCH.MF\"));\n            manifest.write(mBuilder.getOutputStream());\n\n            manifest.write(new FileOutputStream(new File(outFile.getParent(), \"PATCH.MF\")));\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    public void sealPatch() {\n        try {\n            mBuilder.close();\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/apatch/builder/SignedJarBuilder.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.apatch.builder;\n\nimport sun.misc.BASE64Encoder;\nimport sun.security.pkcs.ContentInfo;\nimport sun.security.pkcs.PKCS7;\nimport sun.security.pkcs.SignerInfo;\nimport sun.security.x509.AlgorithmId;\nimport sun.security.x509.X500Name;\n\nimport java.io.*;\nimport java.security.*;\nimport java.security.cert.X509Certificate;\nimport java.util.Map;\nimport java.util.jar.*;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\n\n/**\n * Created by lilong on 16/6/30.\n */\npublic class SignedJarBuilder {\n    private static final String DIGEST_ALGORITHM = \"SHA1\";\n    private static final String DIGEST_ATTR = \"SHA1-Digest\";\n    private static final String DIGEST_MANIFEST_ATTR = \"SHA1-Digest-Manifest\";\n\n    /**\n     * Write to another stream and also feed it to the Signature object.\n     */\n    private static class SignatureOutputStream extends FilterOutputStream {\n        private Signature mSignature;\n        private int mCount = 0;\n\n        public SignatureOutputStream(OutputStream out, Signature sig) {\n            super(out);\n            mSignature = sig;\n        }\n\n        @Override\n        public void write(int b) throws IOException {\n            try {\n                mSignature.update((byte) b);\n            } catch (SignatureException e) {\n                throw new IOException(\"SignatureException: \" + e);\n            }\n            super.write(b);\n            mCount++;\n        }\n\n        @Override\n        public void write(byte[] b, int off, int len) throws IOException {\n            try {\n                mSignature.update(b, off, len);\n            } catch (SignatureException e) {\n                throw new IOException(\"SignatureException: \" + e);\n            }\n            super.write(b, off, len);\n            mCount += len;\n        }\n\n        public int size() {\n            return mCount;\n        }\n    }\n\n    private JarOutputStream mOutputJar;\n    private PrivateKey mKey;\n    private X509Certificate mCertificate;\n    private Manifest mManifest;\n    private BASE64Encoder mBase64Encoder;\n    private MessageDigest mMessageDigest;\n    private byte[] mBuffer = new byte[4096];\n\n    /**\n     * Classes which implement this interface provides a method to check whether a file should\n     * be added to a Jar file.\n     */\n    public interface IZipEntryFilter {\n        /**\n         * An exception thrown during packaging of a zip file into APK file.\n         * This is typically thrown by implementations of\n         * {@link IZipEntryFilter#checkEntry(String)}.\n         */\n        public static class ZipAbortException extends Exception {\n            private static final long serialVersionUID = 1L;\n\n            public ZipAbortException() {\n                super();\n            }\n\n            public ZipAbortException(String format, Object... args) {\n                super(String.format(format, args));\n            }\n\n            public ZipAbortException(Throwable cause, String format, Object... args) {\n                super(String.format(format, args), cause);\n            }\n\n            public ZipAbortException(Throwable cause) {\n                super(cause);\n            }\n        }\n\n        /**\n         * Checks a file for inclusion in a Jar archive.\n         *\n         * @param archivePath the archive file path of the entry\n         * @return <code>true</code> if the file should be included.\n         * @throws ZipAbortException if writing the file should be aborted.\n         */\n        public boolean checkEntry(String archivePath) throws ZipAbortException;\n    }\n\n    /**\n     * Creates a {@link SignedJarBuilder} with a given output stream, and signing information.\n     * <p/>If either <code>key</code> or <code>certificate</code> is <code>null</code> then\n     * the archive will not be signed.\n     *\n     * @param out         the {@link OutputStream} where to write the Jar archive.\n     * @param key         the {@link PrivateKey} used to sign the archive, or <code>null</code>.\n     * @param certificate the {@link X509Certificate} used to sign the archive, or\n     *                    <code>null</code>.\n     * @throws IOException\n     * @throws NoSuchAlgorithmException\n     */\n    public SignedJarBuilder(OutputStream out, PrivateKey key, X509Certificate certificate)\n            throws IOException, NoSuchAlgorithmException {\n        mOutputJar = new JarOutputStream(new BufferedOutputStream(out));\n        mOutputJar.setLevel(9);\n        mKey = key;\n        mCertificate = certificate;\n        if (mKey != null && mCertificate != null) {\n            mManifest = new Manifest();\n            Attributes main = mManifest.getMainAttributes();\n            main.putValue(\"Manifest-Version\", \"1.0\");\n            main.putValue(\"Created-By\", \"1.0 (ApkPatch)\");\n            mBase64Encoder = new BASE64Encoder();\n            mMessageDigest = MessageDigest.getInstance(DIGEST_ALGORITHM);\n        }\n    }\n\n    /**\n     * Writes a new {@link File} into the archive.\n     *\n     * @param inputFile the {@link File} to write.\n     * @param jarPath   the filepath inside the archive.\n     * @throws IOException\n     */\n    public void writeFile(File inputFile, String jarPath) throws IOException {\n        // Get an input stream on the file.\n        FileInputStream fis = new FileInputStream(inputFile);\n        try {\n            // create the zip entry\n            JarEntry entry = new JarEntry(jarPath);\n            entry.setTime(inputFile.lastModified());\n            writeEntry(fis, entry);\n        } finally {\n            // close the file stream used to read the file\n            fis.close();\n        }\n    }\n\n    /**\n     * Copies the content of a Jar/Zip archive into the receiver archive.\n     * <p/>An optional {@link IZipEntryFilter} allows to selectively choose which files\n     * to copy over.\n     *\n     * @param input  the {@link InputStream} for the Jar/Zip to copy.\n     * @param filter the filter or <code>null</code>\n     * @throws IOException\n     */\n    public void writeZip(InputStream input, IZipEntryFilter filter)\n            throws IOException, IZipEntryFilter.ZipAbortException {\n        ZipInputStream zis = new ZipInputStream(input);\n        try {\n            // loop on the entries of the intermediary package and put them in the final package.\n            ZipEntry entry;\n            while ((entry = zis.getNextEntry()) != null) {\n                String name = entry.getName();\n                // do not take directories or anything inside a potential META-INF folder.\n                if (entry.isDirectory() || name.startsWith(\"META-INF/\")) {\n                    continue;\n                }\n                // if we have a filter, we check the entry against it\n                if (filter != null && filter.checkEntry(name) == false) {\n                    continue;\n                }\n                JarEntry newEntry;\n                // Preserve the STORED method of the input entry.\n                if (entry.getMethod() == JarEntry.STORED) {\n                    newEntry = new JarEntry(entry);\n                } else {\n                    // Create a new entry so that the compressed len is recomputed.\n                    newEntry = new JarEntry(name);\n                }\n                writeEntry(zis, newEntry);\n                zis.closeEntry();\n            }\n        } finally {\n            zis.close();\n        }\n    }\n\n    /**\n     * Closes the Jar archive by creating the manifest, and signing the archive.\n     *\n     * @throws IOException\n     * @throws GeneralSecurityException\n     */\n    public void close() throws IOException, GeneralSecurityException {\n        if (mManifest != null) {\n            // write the manifest to the jar file\n            mOutputJar.putNextEntry(new JarEntry(JarFile.MANIFEST_NAME));\n            mManifest.write(mOutputJar);\n            // CERT.SF\n            Signature signature = Signature.getInstance(\"SHA1with\" + mKey.getAlgorithm());\n            signature.initSign(mKey);\n            mOutputJar.putNextEntry(new JarEntry(\"META-INF/CERT.SF\"));\n            SignatureOutputStream out = new SignatureOutputStream(mOutputJar, signature);\n            writeSignatureFile(out);\n            // CERT.*\n            mOutputJar.putNextEntry(new JarEntry(\"META-INF/CERT.\" + mKey.getAlgorithm()));\n            writeSignatureBlock(signature, mCertificate, mKey);\n            // close out at the end because it can also close mOutputJar.\n            // (there's some timing issue here I think, because it's worked before with out\n            // being closed after writing CERT.SF).\n            out.close();\n        }\n        mOutputJar.close();\n        mOutputJar = null;\n    }\n\n    /**\n     * Clean up of the builder for interrupted workflow.\n     * This does nothing if {@link #close()} was called successfully.\n     */\n    public void cleanUp() {\n        if (mOutputJar != null) {\n            try {\n                mOutputJar.close();\n            } catch (IOException e) {\n                // pass\n            }\n        }\n    }\n\n    /**\n     * Adds an entry to the output jar, and write its content from the {@link InputStream}\n     *\n     * @param input The input stream from where to write the entry content.\n     * @param entry the entry to write in the jar.\n     * @throws IOException\n     */\n    private void writeEntry(InputStream input, JarEntry entry) throws IOException {\n        // add the entry to the jar archive\n        mOutputJar.putNextEntry(entry);\n        // read the content of the entry from the input stream, and write it into the archive.\n        int count;\n        while ((count = input.read(mBuffer)) != -1) {\n            mOutputJar.write(mBuffer, 0, count);\n            // update the digest\n            if (mMessageDigest != null) {\n                mMessageDigest.update(mBuffer, 0, count);\n            }\n        }\n        // close the entry for this file\n        mOutputJar.closeEntry();\n        if (mManifest != null) {\n            // update the manifest for this entry.\n            Attributes attr = mManifest.getAttributes(entry.getName());\n            if (attr == null) {\n                attr = new Attributes();\n                mManifest.getEntries().put(entry.getName(), attr);\n            }\n            attr.putValue(DIGEST_ATTR, mBase64Encoder.encode(mMessageDigest.digest()));\n        }\n    }\n\n    /**\n     * Writes a .SF file with a digest to the manifest.\n     */\n    private void writeSignatureFile(SignatureOutputStream out)\n            throws IOException, GeneralSecurityException {\n        Manifest sf = new Manifest();\n        Attributes main = sf.getMainAttributes();\n        main.putValue(\"Signature-Version\", \"1.0\");\n        main.putValue(\"Created-By\", \"1.0 (Android)\");\n        BASE64Encoder base64 = new BASE64Encoder();\n        MessageDigest md = MessageDigest.getInstance(DIGEST_ALGORITHM);\n        PrintStream print = new PrintStream(\n                new DigestOutputStream(new ByteArrayOutputStream(), md),\n                true, \"utf-8\");\n        // Digest of the entire manifest\n        mManifest.write(print);\n        print.flush();\n        main.putValue(DIGEST_MANIFEST_ATTR, base64.encode(md.digest()));\n        Map<String, Attributes> entries = mManifest.getEntries();\n        for (Map.Entry<String, Attributes> entry : entries.entrySet()) {\n            // Digest of the manifest stanza for this entry.\n            print.print(\"Name: \" + entry.getKey() + \"\\r\\n\");\n            for (Map.Entry<Object, Object> att : entry.getValue().entrySet()) {\n                print.print(att.getKey() + \": \" + att.getValue() + \"\\r\\n\");\n            }\n            print.print(\"\\r\\n\");\n            print.flush();\n            Attributes sfAttr = new Attributes();\n            sfAttr.putValue(DIGEST_ATTR, base64.encode(md.digest()));\n            sf.getEntries().put(entry.getKey(), sfAttr);\n        }\n        sf.write(out);\n        // A bug in the java.util.jar implementation of Android platforms\n        // up to version 1.6 will cause a spurious IOException to be thrown\n        // if the length of the signature file is a multiple of 1024 bytes.\n        // As a workaround, add an extra CRLF in this case.\n        if ((out.size() % 1024) == 0) {\n            out.write('\\r');\n            out.write('\\n');\n        }\n    }\n\n    /**\n     * Write the certificate file with a digital signature.\n     */\n    private void writeSignatureBlock(Signature signature, X509Certificate publicKey,\n                                     PrivateKey privateKey)\n            throws IOException, GeneralSecurityException {\n        SignerInfo signerInfo = new SignerInfo(\n                new X500Name(publicKey.getIssuerX500Principal().getName()),\n                publicKey.getSerialNumber(),\n                AlgorithmId.get(DIGEST_ALGORITHM),\n                AlgorithmId.get(privateKey.getAlgorithm()),\n                signature.sign());\n        PKCS7 pkcs7 = new PKCS7(\n                new AlgorithmId[]{AlgorithmId.get(DIGEST_ALGORITHM)},\n                new ContentInfo(ContentInfo.DATA_OID, null),\n                new X509Certificate[]{publicKey},\n                new SignerInfo[]{signerInfo});\n        pkcs7.encodeSignedData(mOutputJar);\n    }\n\n    public JarOutputStream getOutputStream() {\n        return mOutputJar;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/apatch/utils/Formater.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.apatch.utils;\nimport org.jf.dexlib2.dexbacked.DexBackedField;\n\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * Created by lilong on 16/6/30.\n */\npublic class Formater {\n    public static String format(List<DexBackedField> fields) {\n        StringBuffer buffer = new StringBuffer();\n        for (DexBackedField field : fields) {\n            buffer.append(field.getName() + \"(\" + field.getType() + \"), \");\n        }\n        return buffer.toString();\n    }\n\n    public static String formatStringList(List<String> strings) {\n        StringBuffer buffer = new StringBuffer();\n        for (String string : strings) {\n            buffer.append(string);\n        }\n        return buffer.toString();\n    }\n\n    public static String dotStringList(Set<String> strings) {\n        StringBuffer buffer = new StringBuffer();\n        for (String string : strings) {\n            if (buffer.length() > 0) {\n                buffer.append(',');\n            }\n            buffer.append(string);\n        }\n        return buffer.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/apatch/utils/HexUtil.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.apatch.utils;\n\n\n\n/**\n * @author sanping.li@alipay.com\n *\n */\npublic class HexUtil {\n\n\t// 返回十六进制字符串\n\tpublic static String hex(byte[] arr) {\n\t   StringBuffer hexString = new StringBuffer();  \n        for (int i = 0; i < arr.length; i++) {  \n            String hex = Integer.toHexString(arr[i] & 0xFF);  \n            if(hex.length() == 1){  \n                hex = '0' + hex;  \n            }\n            hexString.append(hex);  \n        }        \n        return hexString.toString();  \n\t}\n}\n\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/apatch/utils/MappingParser.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.apatch.utils;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileReader;\n\n/**\n * Created by lilong on 16/6/17.\n */\npublic class MappingParser {\n\n    private File mappingFile;\n\n    public MappingParser(File file) {\n        this.mappingFile = file;\n    }\n\n    public String getOuterClass(String className) {\n        if (mappingFile == null || !mappingFile.exists()) {\n            return getOuterClass(className, false);\n        } else {\n            String map = parseMappingFile(mappingFile, className, false);\n            if (map == null) {\n                return className;\n            }\n            String outClass = getOuterClass(map, false);\n            return parseMappingFile(mappingFile, outClass, true);\n\n        }\n    }\n\n    public String getOuterClass(String className, boolean isMapping) {\n        int index = className.lastIndexOf(\"$\");\n        if (index == -1 && !isMapping) {\n            return className;\n        } else if (index != -1 && !isMapping) {\n            return className.substring(0, index);\n        }\n        return className;\n    }\n\n\n    private String parseMappingFile(File mappingFile, String className, boolean isSource) {\n        String line = null;\n        String mappingClassName = null;\n        try {\n            FileReader in = new FileReader(mappingFile);\n            BufferedReader br = new BufferedReader(in);\n            line = br.readLine();\n            while (line != null) {\n                if (isSource && line.contains(className + \" -> \")) {\n\n                    mappingClassName = line.split(\":\")[0].split(\" -> \")[1];\n                    break;\n                } else if (!isSource && line.contains(\" -> \" + className)) {\n                    mappingClassName = line.split(\" -> \")[0];\n                    break;\n                }\n\n                line = br.readLine();\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return mappingClassName;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/apatch/utils/SmaliDiffUtils.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.apatch.utils;\n\nimport com.google.common.collect.Sets;\nimport com.taobao.android.apatch.ApkPatch;\nimport com.taobao.android.differ.dex.DexDiffer;\nimport com.taobao.android.differ.dex.PatchException;\nimport com.taobao.android.object.DexDiffInfo;\nimport com.taobao.android.smali.AfBakSmali;\nimport com.taobao.android.smali.SmaliMod;\nimport org.antlr.runtime.RecognitionException;\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.dexlib2.DexFileFactory;\nimport org.jf.dexlib2.Opcode;\nimport org.jf.dexlib2.Opcodes;\nimport org.jf.dexlib2.ReferenceType;\nimport org.jf.dexlib2.dexbacked.DexBackedClassDef;\nimport org.jf.dexlib2.dexbacked.DexBackedDexFile;\nimport org.jf.dexlib2.dexbacked.DexBackedMethod;\nimport org.jf.dexlib2.iface.ClassDef;\nimport org.jf.dexlib2.iface.DexFile;\nimport org.jf.dexlib2.iface.instruction.Instruction;\nimport org.jf.dexlib2.iface.instruction.ReferenceInstruction;\nimport org.jf.dexlib2.iface.reference.MethodReference;\nimport org.jf.dexlib2.util.SyntheticAccessorResolver;\nimport org.jf.dexlib2.writer.builder.DexBuilder;\nimport org.jf.dexlib2.writer.io.FileDataStore;\nimport org.jf.util.ClassFileNameHandler;\n\nimport javax.annotation.Nonnull;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\n\n\n/**\n * Created by lilong on 16/6/17.\n */\npublic class SmaliDiffUtils {\n\n\n    public static boolean diff(DexDiffInfo diffInfo, String outterClassName, String className, File out) throws PatchException {\n        String methodName = null;\n        DexBackedMethod sDexBackedMethod = null;\n        DexBackedClassDef oldDexBackClassDef = null;\n        DexBackedClassDef newDexBackClassDef = null;\n        File oldTemp = new File(out, \"smaliTemp1\");\n        if (!oldTemp.exists()) {\n            oldTemp.mkdirs();\n        }\n        File newTemp = new File(out, \"smaliTemp2\");\n        if (!newTemp.exists()) {\n            newTemp.mkdirs();\n        }\n        for (DexBackedClassDef dexBackedClassDef : diffInfo.getOldClasses().keySet()) {\n            if (DexDiffer.getDalvikClassName(dexBackedClassDef.getType()).equals(outterClassName)) {\n                oldDexBackClassDef = dexBackedClassDef;\n            }\n        }\n        for (DexBackedClassDef dexBackedClassDef : diffInfo.getNewClasses()) {\n            if (DexDiffer.getDalvikClassName(dexBackedClassDef.getType()).equals(outterClassName)) {\n                newDexBackClassDef = dexBackedClassDef;\n            }\n        }\n        if (oldDexBackClassDef == null) {\n            return false;\n        }\n\n        disassemble(oldTemp, oldDexBackClassDef);\n        disassemble(newTemp, newDexBackClassDef);\n\n        Iterable<? extends DexBackedMethod> oldDexBackedMethods = oldDexBackClassDef.getMethods();\n        Iterable<? extends DexBackedMethod> newDexBackedMethods = newDexBackClassDef.getMethods();\n        boolean find = false;\n        for (DexBackedMethod dexBackedMethod : newDexBackedMethods) {\n            Iterator<? extends Instruction> instructions = dexBackedMethod.getImplementation().getInstructions().iterator();\n            while (instructions.hasNext()) {\n                Instruction instruction = instructions.next();\n                if (instruction instanceof ReferenceInstruction) {\n                    Opcode opcode = instruction.getOpcode();\n                    if (opcode.referenceType == ReferenceType.METHOD) {\n                        MethodReference methodReference = null;\n                        try {\n                            methodReference = (MethodReference) ((ReferenceInstruction) instruction).getReference();\n                            if (DexDiffer.getDalvikClassName(methodReference.getDefiningClass()).equals(className)) {\n                                sDexBackedMethod = dexBackedMethod;\n                                find = true;\n                                break;\n                            }\n                        } catch (DexBackedDexFile.InvalidItemIndex ex) {\n                            ex.getStackTrace();\n                        }\n                    }\n\n                }\n            }\n            if (find) {\n                break;\n            }\n\n        }\n\n        for (DexBackedMethod dexBackedMethod : oldDexBackedMethods) {\n            if (compare(dexBackedMethod, sDexBackedMethod)) {\n                return true;\n            }\n        }\n        return false;\n\n    }\n\n    private static boolean compare(DexBackedMethod dexBackedMethod, DexBackedMethod sDexBackedMethod) {\n        if (dexBackedMethod == null || sDexBackedMethod == null || dexBackedMethod.getName() == null || sDexBackedMethod.getName() == null) {\n            return false;\n        }\n        if (dexBackedMethod.getName().equals(sDexBackedMethod.getName())) {\n            List<String> parameters = dexBackedMethod.getParameterTypes();\n            List<String> sParameters = sDexBackedMethod.getParameterTypes();\n            if (parameters.size() != sParameters.size()) {\n                return false;\n            }\n            for (String param : parameters) {\n                if (!sParameters.contains(param)) {\n                    return false;\n                }\n            }\n            return true;\n        }\n        return false;\n    }\n\n    public static Set<String> buildCode(File smaliDir, File dexFile, DexDiffInfo info) throws IOException,\n            RecognitionException {\n        Set<String> classes = new HashSet<String>();\n        Set<DexBackedClassDef> classDefs = new HashSet<DexBackedClassDef>();\n        classDefs.addAll(info.getModifiedClasses());\n        classDefs.addAll(info.getAddedClasses());\n        final ClassFileNameHandler outFileNameHandler = new ClassFileNameHandler(smaliDir, \".smali\");\n        final ClassFileNameHandler inFileNameHandler = new ClassFileNameHandler(smaliDir, \".smali\");\n        DexBuilder dexBuilder = new DexBuilder(Opcodes.getDefault());\n        File smaliFile;\n        String className;\n        for (DexBackedClassDef classDef : classDefs) {\n            ApkPatch.currentClassType = classDef.getType();\n            className = TypeGenUtil.newType(classDef.getType());\n            AfBakSmali.disassembleClass(classDef, outFileNameHandler, getBuildOption(classDefs, 19), false, false);\n            smaliFile = inFileNameHandler.getUniqueFilenameForClass(className);\n            classes.add(className.substring(1, className.length() - 1).replace('/', '.'));\n            SmaliMod.assembleSmaliFile(smaliFile, dexBuilder, true, true);\n        }\n\n        dexBuilder.writeTo(new FileDataStore(dexFile));\n\n        return classes;\n    }\n\n    public static Set<String> buildCode(File dexFile, DexDiffInfo info) throws IOException,\n            RecognitionException {\n        Set<String>classes = new HashSet<>();\n        Set<DexBackedClassDef> classDefs = new HashSet<DexBackedClassDef>();\n        classDefs.addAll(info.getModifiedClasses());\n        classDefs.addAll(info.getAddedClasses());\n        DexFileFactory.writeDexFile(dexFile.getAbsolutePath(), new DexFile() {\n            @Nonnull\n            @Override\n            public Set<? extends ClassDef> getClasses() {\n                return new AbstractSet<DexBackedClassDef>() {\n                    @Override\n                    public Iterator<DexBackedClassDef> iterator() {\n                        return classDefs.iterator();\n                    }\n\n                    @Override\n                    public int size() {\n                        return classDefs.size();\n                    }\n                };\n            }\n\n            @Nonnull\n            @Override\n            public Opcodes getOpcodes() {\n                return Opcodes.getDefault();\n            }\n        });\n\n        for (ClassDef classDef:classDefs){\n            classes.add(classDef.getType());\n        }\n        return classes;\n    }\n\n    public static Set<DexBackedClassDef> scanClasses(File smaliDir, List<File> newFiles) throws PatchException {\n\n        Set<DexBackedClassDef> classes = Sets.newHashSet();\n        try {\n            for (File newFile : newFiles) {\n                DexBackedDexFile newDexFile = DexFileFactory.loadDexFile(newFile, Opcodes.getDefault());\n                Set<? extends DexBackedClassDef> dexClasses = newDexFile.getClasses();\n                classes.addAll(dexClasses);\n            }\n\n            final ClassFileNameHandler outFileNameHandler = new ClassFileNameHandler(smaliDir, \".smali\");\n            final ClassFileNameHandler inFileNameHandler = new ClassFileNameHandler(smaliDir, \".smali\");\n\n            for (DexBackedClassDef classDef : classes) {\n                String className = classDef.getType();\n                ApkPatch.currentClassType = null;\n                AfBakSmali.disassembleClass(classDef, outFileNameHandler, getBuildOption(classes, 19), true, true);\n                File smaliFile = inFileNameHandler.getUniqueFilenameForClass(className);\n            }\n        } catch (Exception e) {\n            throw new PatchException(e);\n        }\n        return classes;\n    }\n\n    public static File disassemble(File smaliDir, DexBackedClassDef dexBackedClassDef) throws PatchException {\n\n        Set<DexBackedClassDef> classes = Sets.newHashSet();\n        classes.add(dexBackedClassDef);\n        final ClassFileNameHandler outFileNameHandler = new ClassFileNameHandler(smaliDir, \".smali\");\n        final ClassFileNameHandler inFileNameHandler = new ClassFileNameHandler(smaliDir, \".smali\");\n        String className = dexBackedClassDef.getType();\n        AfBakSmali.disassembleClass(dexBackedClassDef, outFileNameHandler, getBuildOption(classes, 19), true, false);\n        File smaliFile = inFileNameHandler.getUniqueFilenameForClass(className);\n        return smaliFile;\n\n    }\n\n\n    public static BaksmaliOptions getBuildOption(Iterable<? extends ClassDef> collection, int apiLevel) {\n        BaksmaliOptions options = new BaksmaliOptions();\n\n        options.deodex = false;\n        options.parameterRegisters = false;\n        options.localsDirective = true;\n        options.sequentialLabels = true;\n        options.debugInfo = true;\n        options.codeOffsets = false;\n        options.accessorComments = false;\n        options.registerInfo = 0;// 128\n        options.inlineResolver = null;\n        options.apiLevel = apiLevel;\n        if (!options.accessorComments) {\n            options.syntheticAccessorResolver = new SyntheticAccessorResolver(Opcodes.getDefault(),collection);\n        }\n\n        return options;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/apatch/utils/TypeGenUtil.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.apatch.utils;\n\nimport com.taobao.android.apatch.ApkPatch;\nimport com.taobao.android.apatch.Build;\nimport com.taobao.android.object.DexDiffInfo;\n\n/**\n * @author lilong\n */\npublic class TypeGenUtil {\n\n    public static String newType(String type) {\n        if (null != DexDiffInfo.getModifiedClasses(type)) {\n            if (ApkPatch.currentClassType != null) {\n                if (!type.equalsIgnoreCase(ApkPatch.currentClassType)) {\n                    return type;\n                }\n                return type.substring(0, type.length() - 1) + \"_CF_\" + Build.currentTimeStamp + \";\";\n            }\n        }\n        return type;\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/Renderers/BooleanRenderer.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.Renderers;\n\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\npublic class BooleanRenderer {\n    public static void writeTo(IndentingWriter writer, boolean val) throws IOException {\n        if (val) {\n            writer.write(\"true\");\n        } else {\n            writer.write(\"false\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/Renderers/ByteRenderer.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.Renderers;\n\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\npublic class ByteRenderer  {\n    public static void writeTo(IndentingWriter writer, byte val) throws IOException {\n        if (val<0) {\n            writer.write(\"-0x\");\n            writer.printUnsignedLongAsHex(-val);\n            writer.write('t');\n        } else {\n            writer.write(\"0x\");\n            writer.printUnsignedLongAsHex(val);\n            writer.write('t');\n        }\n    }\n\n    public static void writeUnsignedTo(IndentingWriter writer, byte val) throws IOException {\n        writer.write(\"0x\");\n        writer.printUnsignedLongAsHex(val & 0xFF);\n        writer.write('t');\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/Renderers/CharRenderer.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.Renderers;\n\nimport org.jf.util.IndentingWriter;\nimport org.jf.util.StringUtils;\n\nimport java.io.IOException;\n\npublic class CharRenderer {\n    public static void writeTo(IndentingWriter writer, char val) throws IOException {\n        writer.write('\\'');\n        StringUtils.writeEscapedChar(writer, val);\n        writer.write('\\'');\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/Renderers/DoubleRenderer.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.Renderers;\n\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\npublic class DoubleRenderer {\n    public static void writeTo(IndentingWriter writer, double val) throws IOException {\n        writer.write(Double.toString(val));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/Renderers/FloatRenderer.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.Renderers;\n\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\npublic class FloatRenderer {\n    public static void writeTo(IndentingWriter writer, float val) throws IOException {\n        writer.write(Float.toString(val));\n        writer.write('f');\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/Renderers/IntegerRenderer.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.Renderers;\n\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\npublic class IntegerRenderer {\n    public static void writeTo(IndentingWriter writer, int val) throws IOException {\n        if (val<0) {\n            writer.write(\"-0x\");\n            writer.printUnsignedLongAsHex(-((long) val));\n        } else {\n            writer.write(\"0x\");\n            writer.printUnsignedLongAsHex(val);\n        }\n    }\n\n    public static void writeUnsignedTo(IndentingWriter writer, int val) throws IOException {\n        writer.write(\"0x\");\n        writer.printUnsignedLongAsHex(val & 0xFFFFFFFFL);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/Renderers/LongRenderer.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.Renderers;\n\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\npublic class LongRenderer {\n    public static void writeTo(IndentingWriter writer, long val) throws IOException {\n        if (val<0) {\n            writer.write(\"-0x\");\n            writer.printUnsignedLongAsHex(-val);\n            writer.write('L');\n        } else {\n            writer.write(\"0x\");\n            writer.printUnsignedLongAsHex(val);\n            writer.write('L');\n        }\n    }\n\n    public static void writeSignedIntOrLongTo(IndentingWriter writer, long val) throws IOException {\n        if (val<0) {\n            writer.write(\"-0x\");\n            writer.printUnsignedLongAsHex(-val);\n            if (val < Integer.MIN_VALUE) {\n                writer.write('L');\n            }\n        } else {\n            writer.write(\"0x\");\n            writer.printUnsignedLongAsHex(val);\n            if (val > Integer.MAX_VALUE) {\n                writer.write('L');\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/Renderers/ShortRenderer.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.Renderers;\n\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\npublic class ShortRenderer {\n    public static void writeTo(IndentingWriter writer, short val) throws IOException {\n        if (val < 0) {\n            writer.write(\"-0x\");\n            writer.printUnsignedLongAsHex(-val);\n            writer.write('s');\n        } else {\n            writer.write(\"0x\");\n            writer.printUnsignedLongAsHex(val);\n            writer.write('s');\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/AnnotationFormatter.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport com.taobao.android.apatch.annotation.MethodReplaceAnnotation;\nimport com.taobao.android.baksmali.adaptors.EncodedValue.AnnotationEncodedValueAdaptor;\n\nimport org.jf.dexlib2.AnnotationVisibility;\nimport org.jf.dexlib2.iface.Annotation;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\nimport java.util.Collection;\n\nimport javax.annotation.Nonnull;\nimport javax.annotation.Nullable;\n\npublic class AnnotationFormatter {\n\n    public static void writeTo(@Nonnull IndentingWriter writer,\n                               @Nonnull Collection<? extends Annotation> annotations,\n                               @Nullable String containingClass, MethodReplaceAnnotation methodReplaceAnnotation) throws IOException {\n        boolean first = true;\n        for (Annotation annotation : annotations) {\n            if (!first) {\n                writer.write('\\n');\n            }\n            first = false;\n\n            writeTo(writer, annotation, containingClass);\n        }\n        if (null != methodReplaceAnnotation) {\n            writeTo(writer, methodReplaceAnnotation, containingClass);\n        }\n    }\n\n    public static void writeTo(@Nonnull IndentingWriter writer,\n                               @Nonnull Collection<? extends Annotation> annotations,\n                               @Nullable String containingClass) throws IOException {\n        boolean first = true;\n        for (Annotation annotation : annotations) {\n            if (!first) {\n                writer.write('\\n');\n            }\n            first = false;\n\n            writeTo(writer, annotation, containingClass);\n        }\n    }\n\n    public static void writeTo(@Nonnull IndentingWriter writer, @Nonnull Annotation annotation,\n                               @Nullable String containingClass) throws IOException {\n        writer.write(\".annotation \");\n        writer.write(AnnotationVisibility.getVisibility(annotation.getVisibility()));\n        writer.write(' ');\n        writer.write(annotation.getType());\n        writer.write('\\n');\n\n        AnnotationEncodedValueAdaptor.writeElementsTo(writer, annotation.getElements(), containingClass);\n\n        writer.write(\".end annotation\\n\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/BlankMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport org.jf.util.IndentingWriter;\n\n//a \"spacer\" between instructions\npublic class BlankMethodItem extends MethodItem {\n    public BlankMethodItem(int codeAddress) {\n        super(codeAddress);\n    }\n\n    public double getSortOrder() {\n        return Integer.MAX_VALUE;\n    }\n\n    public boolean writeTo(IndentingWriter writer) {\n        //we didn't technically print something, but returning true indicates that a newline should be printed\n        //after this method item, which is the intended functionality\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/CatchMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport java.io.IOException;\n\nimport javax.annotation.Nonnull;\nimport javax.annotation.Nullable;\n\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.util.IndentingWriter;\n\npublic class CatchMethodItem extends MethodItem {\n    private final String exceptionType;\n\n    private final LabelMethodItem tryStartLabel;\n    private final LabelMethodItem tryEndLabel;\n    private final LabelMethodItem handlerLabel;\n\n    public CatchMethodItem(@Nonnull BaksmaliOptions options, @Nonnull MethodDefinition.LabelCache labelCache,\n                           int codeAddress, @Nullable String exceptionType, int startAddress, int endAddress,\n                           int handlerAddress) {\n        super(codeAddress);\n        this.exceptionType = exceptionType;\n\n        tryStartLabel = labelCache.internLabel(new LabelMethodItem(options, startAddress, \"try_start_\"));\n\n        //use the address from the last covered instruction, but make the label\n        //name refer to the address of the next instruction\n        tryEndLabel = labelCache.internLabel(new EndTryLabelMethodItem(options, codeAddress, endAddress));\n\n        if (exceptionType == null) {\n            handlerLabel = labelCache.internLabel(new LabelMethodItem(options, handlerAddress, \"catchall_\"));\n        } else {\n            handlerLabel = labelCache.internLabel(new LabelMethodItem(options, handlerAddress, \"catch_\"));\n        }\n    }\n\n    public LabelMethodItem getTryStartLabel() {\n        return tryStartLabel;\n    }\n\n    public LabelMethodItem getTryEndLabel() {\n        return tryEndLabel;\n    }\n\n    public LabelMethodItem getHandlerLabel() {\n        return handlerLabel;\n    }\n\n    public double getSortOrder() {\n        //sort after instruction and end_try label\n        return 102;\n    }\n\n    @Override\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        if (exceptionType == null) {\n            writer.write(\".catchall\");\n        } else {\n            writer.write(\".catch \");\n            writer.write(exceptionType);\n        }\n        writer.write(\" {\");\n        tryStartLabel.writeTo(writer);\n        writer.write(\" .. \");\n        tryEndLabel.writeTo(writer);\n        writer.write(\"} \");\n        handlerLabel.writeTo(writer);\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/ClassDefinition.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport com.google.common.collect.Lists;\nimport com.taobao.android.apatch.ApkPatch;\nimport com.taobao.android.apatch.annotation.MethodReplaceAnnotation;\nimport com.taobao.android.apatch.utils.TypeGenUtil;\nimport com.taobao.android.baksmali.util.ReferenceUtil;\nimport com.taobao.android.object.DexDiffInfo;\n\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.dexlib2.AccessFlags;\nimport org.jf.dexlib2.dexbacked.DexBackedClassDef;\nimport org.jf.dexlib2.dexbacked.DexBackedDexFile.InvalidItemIndex;\nimport org.jf.dexlib2.iface.Annotation;\nimport org.jf.dexlib2.iface.ClassDef;\nimport org.jf.dexlib2.iface.Field;\nimport org.jf.dexlib2.iface.Method;\nimport org.jf.dexlib2.iface.MethodImplementation;\nimport org.jf.dexlib2.iface.instruction.Instruction;\nimport org.jf.dexlib2.iface.instruction.formats.Instruction21c;\nimport org.jf.dexlib2.iface.reference.FieldReference;\nimport org.jf.util.IndentingWriter;\nimport org.jf.util.StringUtils;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\nimport javax.annotation.Nonnull;\n\npublic class ClassDefinition {\n\n    @Nonnull\n    public final BaksmaliOptions options;\n    @Nonnull\n    public final ClassDef classDef;\n    @Nonnull\n    private final HashSet<String> fieldsSetInStaticConstructor;\n    @Nonnull\n    public final boolean isScan;\n    @Nonnull\n    public final boolean fullMethod;\n\n    protected boolean validationErrors;\n\n    public ClassDefinition(@Nonnull BaksmaliOptions options, @Nonnull ClassDef classDef,\n                           @Nonnull boolean isScan, @Nonnull boolean fullMethod) {\n        this.options = options;\n        this.classDef = classDef;\n        this.isScan = isScan;\n        this.fullMethod = fullMethod;\n        fieldsSetInStaticConstructor = findFieldsSetInStaticConstructor();\n    }\n\n    public ClassDefinition(BaksmaliOptions options, ClassDef classDef) {\n        this.options = options;\n        this.classDef = classDef;\n        this.isScan = false;\n        this.fieldsSetInStaticConstructor = findFieldsSetInStaticConstructor();\n        this.fullMethod = true;\n    }\n\n\n    public boolean hadValidationErrors() {\n        return validationErrors;\n    }\n\n    @Nonnull\n    private HashSet<String> findFieldsSetInStaticConstructor() {\n        HashSet<String> fieldsSetInStaticConstructor = new HashSet<String>();\n\n        for (Method method : classDef.getDirectMethods()) {\n            if (method.getName().equals(\"<clinit>\")) {\n                MethodImplementation impl = method.getImplementation();\n                if (impl != null) {\n                    for (Instruction instruction : impl.getInstructions()) {\n                        switch (instruction.getOpcode()) {\n                            case SPUT:\n                            case SPUT_BOOLEAN:\n                            case SPUT_BYTE:\n                            case SPUT_CHAR:\n                            case SPUT_OBJECT:\n                            case SPUT_SHORT:\n                            case SPUT_WIDE: {\n                                Instruction21c ins = (Instruction21c) instruction;\n                                FieldReference fieldRef = null;\n                                try {\n                                    fieldRef = (FieldReference) ins.getReference();\n                                } catch (InvalidItemIndex ex) {\n                                    // just ignore it for now. We'll deal with it later, when processing the instructions\n                                    // themselves\n                                }\n                                if (fieldRef != null &&\n                                        fieldRef.getDefiningClass().equals((classDef.getType()))) {\n                                    fieldsSetInStaticConstructor.add(ReferenceUtil.getShortFieldDescriptor(fieldRef));\n                                }\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        return fieldsSetInStaticConstructor;\n    }\n\n    public void writeTo(IndentingWriter writer) throws IOException {\n        writeClass(writer);\n        writeSuper(writer);\n        writeSourceFile(writer);\n        writeInterfaces(writer);\n        writeAnnotations(writer);\n        Set<String> staticFields = writeStaticFields(writer);\n        writeInstanceFields(writer, staticFields);\n        Set<String> directMethods = writeDirectMethods(writer);\n        writeVirtualMethods(writer, directMethods);\n    }\n\n    private void writeClass(IndentingWriter writer) throws IOException {\n        writer.write(\".class \");\n        writeAccessFlags(writer);\n        writer.write(TypeGenUtil.newType(classDef.getType()));\n        writer.write('\\n');\n    }\n\n    private void writeAccessFlags(IndentingWriter writer) throws IOException {\n        for (AccessFlags accessFlag : AccessFlags.getAccessFlagsForClass(classDef.getAccessFlags())) {\n            writer.write(accessFlag.toString());\n            writer.write(' ');\n        }\n    }\n\n    private void writeSuper(IndentingWriter writer) throws IOException {\n        String superClass = classDef.getSuperclass();\n        if (superClass != null) {\n            writer.write(\".super \");\n            writer.write(superClass);\n            writer.write('\\n');\n\n\n            if (isScan) {\n                //    System.out.println(\"writeSuper: \" + superClass + \" \" + classDef.getType());\n                ArrayList<String> derivedClasses = null;\n                if (ApkPatch.superClasses.containsKey(superClass)) {\n                    derivedClasses = ApkPatch.superClasses.get(superClass);\n                } else {\n                    derivedClasses = new ArrayList<String>();\n                    ApkPatch.superClasses.put(superClass, derivedClasses);\n                }\n                derivedClasses.add(classDef.getType());\n            }\n        }\n    }\n\n    private void writeSourceFile(IndentingWriter writer) throws IOException {\n        String sourceFile = classDef.getSourceFile();\n        if (sourceFile != null) {\n            writer.write(\".source \\\"\");\n            StringUtils.writeEscapedString(writer, sourceFile);\n            writer.write(\"\\\"\\n\");\n        }\n    }\n\n    private void writeInterfaces(IndentingWriter writer) throws IOException {\n        List<String> interfaces = Lists.newArrayList(classDef.getInterfaces());\n        Collections.sort(interfaces);\n\n        if (interfaces.size() != 0) {\n            writer.write('\\n');\n            writer.write(\"# interfaces\\n\");\n            for (String interfaceName : interfaces) {\n                writer.write(\".implements \");\n                writer.write(interfaceName);\n                writer.write('\\n');\n            }\n        }\n    }\n\n    private void writeAnnotations(IndentingWriter writer) throws IOException {\n        Collection<? extends Annotation> classAnnotations = classDef.getAnnotations();\n        if (classAnnotations.size() != 0) {\n            writer.write(\"\\n\\n\");\n            writer.write(\"# annotations\\n\");\n\n            String containingClass = null;\n            if (options.implicitReferences) {\n                containingClass = classDef.getType();\n            }\n\n            AnnotationFormatter.writeTo(writer, classAnnotations, containingClass);\n        }\n    }\n\n    private Set<String> writeStaticFields(IndentingWriter writer) throws IOException {\n        if (!fullMethod && !DexDiffInfo.addedClasses.contains(classDef)) {\n            return null;\n        }\n        boolean wroteHeader = false;\n        Set<String> writtenFields = new HashSet<String>();\n\n        Iterable<? extends Field> staticFields;\n        if (classDef instanceof DexBackedClassDef) {\n            staticFields = ((DexBackedClassDef) classDef).getStaticFields(false);\n        } else {\n            staticFields = classDef.getStaticFields();\n        }\n\n        for (Field field : staticFields) {\n            if (!wroteHeader) {\n                writer.write(\"\\n\\n\");\n                writer.write(\"# static fields\");\n                wroteHeader = true;\n            }\n            writer.write('\\n');\n\n            boolean setInStaticConstructor;\n            IndentingWriter fieldWriter = writer;\n            String fieldString = ReferenceUtil.getShortFieldDescriptor(field);\n            if (!writtenFields.add(fieldString)) {\n                writer.write(\"# duplicate field ignored\\n\");\n                fieldWriter = new CommentingIndentingWriter(writer);\n                System.err.println(String.format(\"Ignoring duplicate field: %s->%s\", classDef.getType(), fieldString));\n                setInStaticConstructor = false;\n            } else {\n                setInStaticConstructor = fieldsSetInStaticConstructor.contains(fieldString);\n            }\n            FieldDefinition.writeTo(options, fieldWriter, field, setInStaticConstructor);\n        }\n        return writtenFields;\n    }\n\n    private void writeInstanceFields(IndentingWriter writer, Set<String> staticFields) throws IOException {\n        if (!fullMethod&& !DexDiffInfo.addedClasses.contains(classDef)) {\n            return;\n        }\n        boolean wroteHeader = false;\n        Set<String> writtenFields = new HashSet<String>();\n\n        Iterable<? extends Field> instanceFields;\n        if (classDef instanceof DexBackedClassDef) {\n            instanceFields = ((DexBackedClassDef) classDef).getInstanceFields(false);\n        } else {\n            instanceFields = classDef.getInstanceFields();\n        }\n\n        for (Field field : instanceFields) {\n            if (!wroteHeader) {\n                writer.write(\"\\n\\n\");\n                writer.write(\"# instance fields\");\n                wroteHeader = true;\n            }\n            writer.write('\\n');\n\n            IndentingWriter fieldWriter = writer;\n            String fieldString = ReferenceUtil.getShortFieldDescriptor(field);\n            if (!writtenFields.add(fieldString)) {\n                writer.write(\"# duplicate field ignored\\n\");\n                fieldWriter = new CommentingIndentingWriter(writer);\n                System.err.println(String.format(\"Ignoring duplicate field: %s->%s\", classDef.getType(), fieldString));\n            } else if (staticFields.contains(fieldString)) {\n                System.err.println(String.format(\"Duplicate static+instance field found: %s->%s\",\n                        classDef.getType(), fieldString));\n                System.err.println(\"You will need to rename one of these fields, including all references.\");\n\n                writer.write(\"# There is both a static and instance field with this signature.\\n\" +\n                        \"# You will need to rename one of these fields, including all references.\\n\");\n            }\n            FieldDefinition.writeTo(options, fieldWriter, field, false);\n        }\n    }\n\n    private Set<String> writeDirectMethods(IndentingWriter writer) throws IOException {\n        boolean wroteHeader = false;\n        Set<String> writtenMethods = new HashSet<String>();\n\n        Iterable<? extends Method> directMethods;\n        Set<? extends Method> modifieds = null;\n        if (classDef instanceof DexBackedClassDef) {\n            directMethods = ((DexBackedClassDef) classDef).getDirectMethods(false);\n            modifieds = (Set<? extends Method>) DexDiffInfo.modifiedMethods;\n        } else {\n            directMethods = classDef.getDirectMethods();\n        }\n\n        MethodReplaceAnnotation replaceAnnotaion;\n        for (Method method : directMethods) {\n\n\n            if (!fullMethod && !DexDiffInfo.addedClasses.contains(classDef)) {\n                if (!modifieds.contains(method) && !DexDiffInfo.addedMethods.contains(method)) {\n                    continue;\n                }\n            }\n\n            if (!wroteHeader) {\n                writer.write(\"\\n\\n\");\n                writer.write(\"# direct methods\");\n                wroteHeader = true;\n            }\n            writer.write('\\n');\n\n            // TODO: check for method validation errors\n            String methodString = ReferenceUtil.getMethodDescriptor(method, true);\n\n            IndentingWriter methodWriter = writer;\n            if (!writtenMethods.add(methodString)) {\n                writer.write(\"# duplicate method ignored\\n\");\n                methodWriter = new CommentingIndentingWriter(writer);\n            }\n\n            MethodImplementation methodImpl = method.getImplementation();\n            if (methodImpl == null) {\n                MethodDefinition.writeEmptyMethodTo(methodWriter, method, options);\n            } else {\n                MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);\n                methodDefinition.setFullMethod(fullMethod);\n                methodDefinition.writeTo(methodWriter);\n            }\n        }\n        return writtenMethods;\n    }\n\n    private void writeVirtualMethods(IndentingWriter writer, Set<String> directMethods) throws IOException {\n        boolean wroteHeader = false;\n        Set<String> writtenMethods = new HashSet<String>();\n\n        Iterable<? extends Method> virtualMethods;\n        Set<? extends Method> modifieds = null;\n        if (classDef instanceof DexBackedClassDef) {\n            virtualMethods = ((DexBackedClassDef) classDef).getVirtualMethods(false);\n            modifieds = (Set<? extends Method>) DexDiffInfo.modifiedMethods;\n        } else {\n            virtualMethods = classDef.getVirtualMethods();\n        }\n\n        MethodReplaceAnnotation replaceAnnotaion;\n        for (Method method : virtualMethods) {\n\n            if (!fullMethod && !DexDiffInfo.addedClasses.contains(classDef)) {\n                if (!modifieds.contains(method) && !DexDiffInfo.addedMethods.contains(method)) {\n                    continue;\n                }\n            }\n\n\n            if (!wroteHeader) {\n                writer.write(\"\\n\\n\");\n                writer.write(\"# virtual methods\");\n                wroteHeader = true;\n            }\n            writer.write('\\n');\n\n            // TODO: check for method validation errors\n            String methodString = ReferenceUtil.getMethodDescriptor(method, true);\n\n            IndentingWriter methodWriter = writer;\n            if (!writtenMethods.add(methodString)) {\n                writer.write(\"# duplicate method ignored\\n\");\n                methodWriter = new CommentingIndentingWriter(writer);\n            } else if (directMethods.contains(methodString)) {\n                writer.write(\"# There is both a direct and virtual method with this signature.\\n\" +\n                        \"# You will need to rename one of these methods, including all references.\\n\");\n                System.err.println(String.format(\"Duplicate direct+virtual method found: %s->%s\",\n                        classDef.getType(), methodString));\n                System.err.println(\"You will need to rename one of these methods, including all references.\");\n            }\n\n            MethodImplementation methodImpl = method.getImplementation();\n            if (methodImpl == null) {\n                MethodDefinition.writeEmptyMethodTo(methodWriter, method, options);\n            } else {\n                MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);\n                methodDefinition.writeTo(methodWriter);\n            }\n        }\n    }\n\n    public ClassDef getClassDef() {\n        return classDef;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/CommentMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\npublic class CommentMethodItem extends MethodItem {\n    //private final StringTemplate template;\n    private final String comment;\n    private final double sortOrder;\n\n    public CommentMethodItem(String comment, int codeAddress, double sortOrder) {\n        super(codeAddress);\n        this.comment = comment;\n        this.sortOrder = sortOrder;\n    }\n\n    public double getSortOrder() {\n        return sortOrder;\n    }\n\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        writer.write('#');\n        writer.write(comment);\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/CommentedOutMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\npublic class CommentedOutMethodItem extends MethodItem {\n    private final MethodItem commentedOutMethodItem;\n\n    public CommentedOutMethodItem(MethodItem commentedOutMethodItem) {\n        super(commentedOutMethodItem.getCodeAddress());\n        this.commentedOutMethodItem = commentedOutMethodItem;\n    }\n\n    public double getSortOrder() {\n        return commentedOutMethodItem.getSortOrder() + .001;\n    }\n\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        writer.write('#');\n        commentedOutMethodItem.writeTo(writer);\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/CommentingIndentingWriter.java",
    "content": "/*\n * Copyright 2013, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\nimport java.io.Writer;\n\npublic class CommentingIndentingWriter extends IndentingWriter {\n    public CommentingIndentingWriter(Writer writer) {\n        super(writer);\n    }\n\n    @Override\n    protected void writeIndent() throws IOException {\n        writer.write(\"# \");\n        super.writeIndent();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Debug/BeginEpilogueMethodItem.java",
    "content": "/*\n * Copyright 2012, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Debug;\n\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\npublic class BeginEpilogueMethodItem extends DebugMethodItem {\n    public BeginEpilogueMethodItem(int codeAddress, int sortOrder) {\n        super(codeAddress, sortOrder);\n    }\n\n    @Override\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        writer.write(\".prologue\");\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Debug/DebugMethodItem.java",
    "content": "/*\n * Copyright 2012, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Debug;\n\nimport com.taobao.android.baksmali.adaptors.RegisterFormatter;\nimport com.taobao.android.baksmali.adaptors.MethodItem;\nimport org.jf.dexlib2.DebugItemType;\nimport org.jf.dexlib2.iface.debug.*;\nimport org.jf.util.ExceptionWithContext;\n\npublic abstract class DebugMethodItem extends MethodItem {\n    private final int sortOrder;\n\n    protected DebugMethodItem(int codeAddress, int sortOrder) {\n        super(codeAddress);\n        this.sortOrder = sortOrder;\n    }\n\n    @Override public double getSortOrder() { return sortOrder; }\n\n    public static DebugMethodItem build(RegisterFormatter registerFormatter, DebugItem debugItem) {\n        int codeAddress = debugItem.getCodeAddress();\n        switch (debugItem.getDebugItemType()) {\n            case DebugItemType.START_LOCAL:\n                return new StartLocalMethodItem(codeAddress, -1, registerFormatter, (StartLocal)debugItem);\n            case DebugItemType.END_LOCAL:\n                return new EndLocalMethodItem(codeAddress, -1, registerFormatter, (EndLocal)debugItem);\n            case DebugItemType.RESTART_LOCAL:\n                return new RestartLocalMethodItem(codeAddress, -1, registerFormatter, (RestartLocal)debugItem);\n            case DebugItemType.EPILOGUE_BEGIN:\n                return new BeginEpilogueMethodItem(codeAddress, -4);\n            case DebugItemType.PROLOGUE_END:\n                return new EndPrologueMethodItem(codeAddress, -4);\n            case DebugItemType.SET_SOURCE_FILE:\n                return new SetSourceFileMethodItem(codeAddress, -3, (SetSourceFile)debugItem);\n            case DebugItemType.LINE_NUMBER:\n                return new LineNumberMethodItem(codeAddress, -2, (LineNumber)debugItem);\n            default:\n                throw new ExceptionWithContext(\"Invalid debug item type: %d\", debugItem.getDebugItemType());\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Debug/EndLocalMethodItem.java",
    "content": "/*\n * Copyright 2012, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Debug;\n\nimport com.taobao.android.baksmali.adaptors.RegisterFormatter;\nimport org.jf.dexlib2.iface.debug.EndLocal;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\nimport javax.annotation.Nonnull;\n\npublic class EndLocalMethodItem extends DebugMethodItem {\n    @Nonnull private final EndLocal endLocal;\n    @Nonnull private final RegisterFormatter registerFormatter;\n\n    public EndLocalMethodItem(int codeAddress, int sortOrder, @Nonnull RegisterFormatter registerFormatter,\n                                @Nonnull EndLocal endLocal) {\n        super(codeAddress, sortOrder);\n        this.endLocal = endLocal;\n        this.registerFormatter = registerFormatter;\n    }\n\n    @Override\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        writer.write(\".end local \");\n        registerFormatter.writeTo(writer, endLocal.getRegister());\n\n        String name = endLocal.getName();\n        String type = endLocal.getType();\n        String signature = endLocal.getSignature();\n        if (name != null || type != null || signature != null) {\n            writer.write(\"    # \");\n            LocalFormatter.writeLocal(writer, name, type, signature);\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Debug/EndPrologueMethodItem.java",
    "content": "/*\n * Copyright 2012, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Debug;\n\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\npublic class EndPrologueMethodItem extends DebugMethodItem {\n    public EndPrologueMethodItem(int codeAddress, int sortOrder) {\n        super(codeAddress, sortOrder);\n    }\n\n    @Override\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        writer.write(\".prologue\");\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Debug/LineNumberMethodItem.java",
    "content": "/*\n * Copyright 2012, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Debug;\n\nimport org.jf.dexlib2.iface.debug.LineNumber;\nimport org.jf.util.IndentingWriter;\n\nimport javax.annotation.Nonnull;\nimport java.io.IOException;\n\npublic class LineNumberMethodItem extends DebugMethodItem {\n    private final int lineNumber;\n\n    public LineNumberMethodItem(int codeAddress, int sortOrder, @Nonnull LineNumber lineNumber) {\n        super(codeAddress, sortOrder);\n        this.lineNumber = lineNumber.getLineNumber();\n    }\n\n    @Override\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        writer.write(\".line \");\n        writer.printUnsignedIntAsDec(lineNumber);\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Debug/LocalFormatter.java",
    "content": "/*\n * Copyright 2013, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Debug;\n\nimport com.taobao.android.baksmali.adaptors.ReferenceFormatter;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\nimport javax.annotation.Nonnull;\nimport javax.annotation.Nullable;\n\npublic class LocalFormatter {\n    /**\n     * Writes out the given local info\n     *\n     * The written string will be something like:\n     *\n     * \"localVar\":Ljava/lang/String;, \"SomeSignature\"\n     * \"localVar\":Ljava/lang/String;\n     * \"localVar\":V, \"SomeSignature\"\n     * null:Ljava/lang/String;, \"SomeSignature\"\n     * null:V, \"SomeSignature\"\n     *\n     * One of name, type or signature must be non-null\n     */\n    public static void writeLocal(@Nonnull IndentingWriter writer, @Nullable String name, @Nullable String type,\n                                  @Nullable String signature) throws IOException {\n        if (name != null) {\n            ReferenceFormatter.writeStringReference(writer, name);\n        } else {\n            writer.write(\"null\");\n        }\n        writer.write(':');\n        if (type != null) {\n            writer.write(type);\n        } else {\n            writer.write(\"V\");\n        }\n        if (signature != null) {\n            writer.write(\", \");\n            ReferenceFormatter.writeStringReference(writer, signature);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Debug/RestartLocalMethodItem.java",
    "content": "/*\n * Copyright 2012, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Debug;\n\nimport com.taobao.android.baksmali.adaptors.RegisterFormatter;\nimport org.jf.dexlib2.iface.debug.RestartLocal;\nimport org.jf.util.IndentingWriter;\n\nimport javax.annotation.Nonnull;\nimport java.io.IOException;\n\npublic class RestartLocalMethodItem extends DebugMethodItem {\n    @Nonnull private final RestartLocal restartLocal;\n    @Nonnull private final RegisterFormatter registerFormatter;\n\n    public RestartLocalMethodItem(int codeAddress, int sortOrder, @Nonnull RegisterFormatter registerFormatter,\n                              @Nonnull RestartLocal restartLocal) {\n        super(codeAddress, sortOrder);\n        this.restartLocal = restartLocal;\n        this.registerFormatter = registerFormatter;\n    }\n\n    @Override\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        writer.write(\".restart local \");\n        registerFormatter.writeTo(writer, restartLocal.getRegister());\n\n        String name = restartLocal.getName();\n        String type = restartLocal.getType();\n        String signature = restartLocal.getSignature();\n        if (name != null || type != null || signature != null) {\n            writer.write(\"    # \");\n            LocalFormatter.writeLocal(writer, name, type, signature);\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Debug/SetSourceFileMethodItem.java",
    "content": "/*\n * Copyright 2012, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Debug;\n\nimport org.jf.dexlib2.iface.debug.SetSourceFile;\nimport org.jf.util.IndentingWriter;\nimport org.jf.util.StringUtils;\n\nimport javax.annotation.Nonnull;\nimport javax.annotation.Nullable;\nimport java.io.IOException;\n\npublic class SetSourceFileMethodItem extends DebugMethodItem {\n    @Nullable private final String sourceFile;\n\n    public SetSourceFileMethodItem(int codeAddress, int sortOrder, @Nonnull SetSourceFile setSourceFile) {\n        super(codeAddress, sortOrder);\n        this.sourceFile = setSourceFile.getSourceFile();\n    }\n\n    @Override\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        writer.write(\".source\");\n\n        if (sourceFile != null) {\n            writer.write(\" \\\"\");\n            StringUtils.writeEscapedString(writer, sourceFile);\n            writer.write('\"');\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Debug/StartLocalMethodItem.java",
    "content": "/*\n * Copyright 2012, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Debug;\n\nimport com.taobao.android.baksmali.adaptors.RegisterFormatter;\nimport org.jf.dexlib2.iface.debug.StartLocal;\nimport org.jf.util.IndentingWriter;\n\nimport javax.annotation.Nonnull;\nimport java.io.IOException;\n\npublic class StartLocalMethodItem extends DebugMethodItem {\n    @Nonnull private final StartLocal startLocal;\n    @Nonnull private final RegisterFormatter registerFormatter;\n\n    public StartLocalMethodItem(int codeAddress, int sortOrder, @Nonnull RegisterFormatter registerFormatter,\n                                @Nonnull StartLocal startLocal) {\n        super(codeAddress, sortOrder);\n        this.startLocal = startLocal;\n        this.registerFormatter = registerFormatter;\n    }\n\n    @Override\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        writer.write(\".local \");\n        registerFormatter.writeTo(writer, startLocal.getRegister());\n\n        String name = startLocal.getName();\n        String type = startLocal.getType();\n        String signature = startLocal.getSignature();\n\n        if (name != null || type != null || signature != null) {\n            writer.write(\", \");\n            LocalFormatter.writeLocal(writer, name, type, signature);\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/EncodedValue/AnnotationEncodedValueAdaptor.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.EncodedValue;\n\nimport org.jf.dexlib2.iface.AnnotationElement;\nimport org.jf.dexlib2.iface.value.AnnotationEncodedValue;\nimport org.jf.util.IndentingWriter;\n\nimport javax.annotation.Nonnull;\nimport javax.annotation.Nullable;\nimport java.io.IOException;\nimport java.util.Collection;\n\npublic abstract class AnnotationEncodedValueAdaptor {\n\n    public static void writeTo(@Nonnull IndentingWriter writer,\n                               @Nonnull AnnotationEncodedValue annotationEncodedValue,\n                               @Nullable String containingClass) throws IOException {\n        writer.write(\".subannotation \");\n        writer.write(annotationEncodedValue.getType());\n        writer.write('\\n');\n\n        writeElementsTo(writer, annotationEncodedValue.getElements(), containingClass);\n        writer.write(\".end subannotation\");\n    }\n\n    public static void writeElementsTo(@Nonnull IndentingWriter writer,\n                                       @Nonnull Collection<? extends AnnotationElement> annotationElements,\n                                       @Nullable String containingClass) throws IOException {\n        writer.indent(4);\n        for (AnnotationElement annotationElement: annotationElements) {\n            writer.write(annotationElement.getName());\n            writer.write(\" = \");\n            EncodedValueAdaptor.writeTo(writer, annotationElement.getValue(), containingClass);\n            writer.write('\\n');\n        }\n        writer.deindent(4);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/EncodedValue/ArrayEncodedValueAdaptor.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.EncodedValue;\n\nimport org.jf.dexlib2.iface.value.ArrayEncodedValue;\nimport org.jf.dexlib2.iface.value.EncodedValue;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\nimport java.util.Collection;\n\nimport javax.annotation.Nonnull;\nimport javax.annotation.Nullable;\n\npublic class ArrayEncodedValueAdaptor {\n    public static void writeTo(@Nonnull IndentingWriter writer,\n                               @Nonnull ArrayEncodedValue arrayEncodedValue,\n                               @Nullable String containingClass) throws IOException {\n        writer.write('{');\n        Collection<? extends EncodedValue> values = arrayEncodedValue.getValue();\n        if (values.size() == 0) {\n            writer.write('}');\n            return;\n        }\n\n        writer.write('\\n');\n        writer.indent(4);\n        boolean first = true;\n        for (EncodedValue encodedValue: values) {\n            if (!first) {\n                writer.write(\",\\n\");\n            }\n            first = false;\n\n            EncodedValueAdaptor.writeTo(writer, encodedValue, containingClass);\n        }\n        writer.deindent(4);\n        writer.write(\"\\n}\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/EncodedValue/EncodedValueAdaptor.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.EncodedValue;\n\nimport com.taobao.android.baksmali.adaptors.ReferenceFormatter;\nimport com.taobao.android.baksmali.Renderers.BooleanRenderer;\nimport com.taobao.android.baksmali.Renderers.ByteRenderer;\nimport com.taobao.android.baksmali.Renderers.CharRenderer;\nimport com.taobao.android.baksmali.Renderers.DoubleRenderer;\nimport com.taobao.android.baksmali.Renderers.FloatRenderer;\nimport com.taobao.android.baksmali.Renderers.IntegerRenderer;\nimport com.taobao.android.baksmali.Renderers.LongRenderer;\nimport com.taobao.android.baksmali.Renderers.ShortRenderer;\nimport com.taobao.android.baksmali.util.ReferenceUtil;\n\nimport org.jf.dexlib2.ValueType;\nimport org.jf.dexlib2.iface.value.AnnotationEncodedValue;\nimport org.jf.dexlib2.iface.value.ArrayEncodedValue;\nimport org.jf.dexlib2.iface.value.BooleanEncodedValue;\nimport org.jf.dexlib2.iface.value.ByteEncodedValue;\nimport org.jf.dexlib2.iface.value.CharEncodedValue;\nimport org.jf.dexlib2.iface.value.DoubleEncodedValue;\nimport org.jf.dexlib2.iface.value.EncodedValue;\nimport org.jf.dexlib2.iface.value.EnumEncodedValue;\nimport org.jf.dexlib2.iface.value.FieldEncodedValue;\nimport org.jf.dexlib2.iface.value.FloatEncodedValue;\nimport org.jf.dexlib2.iface.value.IntEncodedValue;\nimport org.jf.dexlib2.iface.value.LongEncodedValue;\nimport org.jf.dexlib2.iface.value.MethodEncodedValue;\nimport org.jf.dexlib2.iface.value.ShortEncodedValue;\nimport org.jf.dexlib2.iface.value.StringEncodedValue;\nimport org.jf.dexlib2.iface.value.TypeEncodedValue;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\nimport javax.annotation.Nonnull;\nimport javax.annotation.Nullable;\n\npublic abstract class EncodedValueAdaptor {\n    public static void writeTo(@Nonnull IndentingWriter writer, @Nonnull EncodedValue encodedValue,\n                               @Nullable String containingClass)\n            throws IOException {\n        switch (encodedValue.getValueType()) {\n            case ValueType.ANNOTATION:\n                AnnotationEncodedValueAdaptor.writeTo(writer, (AnnotationEncodedValue) encodedValue, containingClass);\n                return;\n            case ValueType.ARRAY:\n                ArrayEncodedValueAdaptor.writeTo(writer, (ArrayEncodedValue)encodedValue, containingClass);\n                return;\n            case ValueType.BOOLEAN:\n                BooleanRenderer.writeTo(writer, ((BooleanEncodedValue) encodedValue).getValue());\n                return;\n            case ValueType.BYTE:\n                ByteRenderer.writeTo(writer, ((ByteEncodedValue) encodedValue).getValue());\n                return;\n            case ValueType.CHAR:\n                CharRenderer.writeTo(writer, ((CharEncodedValue) encodedValue).getValue());\n                return;\n            case ValueType.DOUBLE:\n                DoubleRenderer.writeTo(writer, ((DoubleEncodedValue) encodedValue).getValue());\n                return;\n            case ValueType.ENUM:\n                EnumEncodedValue enumEncodedValue = (EnumEncodedValue)encodedValue;\n                boolean useImplicitReference = false;\n                if (enumEncodedValue.getValue().getDefiningClass().equals(containingClass)) {\n                    useImplicitReference = true;\n                }\n                writer.write(\".enum \");\n                ReferenceUtil.writeFieldDescriptor(writer, enumEncodedValue.getValue(), useImplicitReference);\n                return;\n            case ValueType.FIELD:\n                FieldEncodedValue fieldEncodedValue = (FieldEncodedValue)encodedValue;\n                useImplicitReference = false;\n                if (fieldEncodedValue.getValue().getDefiningClass().equals(containingClass)) {\n                    useImplicitReference = true;\n                }\n                ReferenceUtil.writeFieldDescriptor(writer, fieldEncodedValue.getValue(), useImplicitReference);\n                return;\n            case ValueType.FLOAT:\n                FloatRenderer.writeTo(writer, ((FloatEncodedValue) encodedValue).getValue());\n                return;\n            case ValueType.INT:\n                IntegerRenderer.writeTo(writer, ((IntEncodedValue) encodedValue).getValue());\n                return;\n            case ValueType.LONG:\n                LongRenderer.writeTo(writer, ((LongEncodedValue) encodedValue).getValue());\n                return;\n            case ValueType.METHOD:\n                MethodEncodedValue methodEncodedValue = (MethodEncodedValue)encodedValue;\n                useImplicitReference = false;\n                if (methodEncodedValue.getValue().getDefiningClass().equals(containingClass)) {\n                    useImplicitReference = true;\n                }\n                ReferenceUtil.writeMethodDescriptor(writer, methodEncodedValue.getValue(), useImplicitReference);\n                return;\n            case ValueType.NULL:\n                writer.write(\"null\");\n                return;\n            case ValueType.SHORT:\n                ShortRenderer.writeTo(writer, ((ShortEncodedValue) encodedValue).getValue());\n                return;\n            case ValueType.STRING:\n                ReferenceFormatter.writeStringReference(writer, ((StringEncodedValue) encodedValue).getValue());\n                return;\n            case ValueType.TYPE:\n                writer.write(((TypeEncodedValue)encodedValue).getValue());\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/EndTryLabelMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport org.jf.baksmali.BaksmaliOptions;\n\nimport javax.annotation.Nonnull;\n\npublic class EndTryLabelMethodItem extends LabelMethodItem {\n    private int endTryAddress;\n\n    public EndTryLabelMethodItem(@Nonnull BaksmaliOptions options, int codeAddress, int endTryAddress) {\n        super(options, codeAddress, \"try_end_\");\n        this.endTryAddress = endTryAddress;\n    }\n\n    public double getSortOrder() {\n        //sort after instruction, but before catch directive\n        return 101;\n    }\n\n    public int getLabelAddress() {\n        return endTryAddress;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/FieldDefinition.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport com.taobao.android.apatch.utils.TypeGenUtil;\nimport com.taobao.android.baksmali.adaptors.EncodedValue.EncodedValueAdaptor;\n\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.dexlib2.AccessFlags;\nimport org.jf.dexlib2.iface.Annotation;\nimport org.jf.dexlib2.iface.Field;\nimport org.jf.dexlib2.iface.value.EncodedValue;\nimport org.jf.dexlib2.util.EncodedValueUtils;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\nimport java.util.Collection;\n\npublic class FieldDefinition {\n    public static void writeTo(BaksmaliOptions options, IndentingWriter writer, Field field,\n                               boolean setInStaticConstructor) throws IOException {\n        EncodedValue initialValue = field.getInitialValue();\n        int accessFlags = field.getAccessFlags();\n\n        if (setInStaticConstructor &&\n                AccessFlags.STATIC.isSet(accessFlags) &&\n                AccessFlags.FINAL.isSet(accessFlags) &&\n                initialValue != null) {\n            if (!EncodedValueUtils.isDefaultValue(initialValue)) {\n                writer.write(\"# The value of this static final field might be set in the static constructor\\n\");\n            } else {\n                // don't write out the default initial value for static final fields that get set in the static\n                // constructor\n                initialValue = null;\n            }\n        }\n\n        writer.write(\".field \");\n        writeAccessFlags(writer, field.getAccessFlags());\n        writer.write(field.getName());\n        writer.write(':');\n        String clazz = TypeGenUtil.newType(field.getType());\n        writer.write(clazz);\n        if (initialValue != null) {\n            writer.write(\" = \");\n\n            String containingClass = null;\n            if (options.implicitReferences) {\n                containingClass = field.getDefiningClass();\n            }\n\n            EncodedValueAdaptor.writeTo(writer, initialValue, containingClass);\n        }\n\n        writer.write('\\n');\n\n        Collection<? extends Annotation> annotations = field.getAnnotations();\n        if (annotations.size() > 0) {\n            writer.indent(4);\n\n            String containingClass = null;\n            if (options.implicitReferences) {\n                containingClass = field.getDefiningClass();\n            }\n\n            AnnotationFormatter.writeTo(writer, annotations, containingClass);\n            writer.deindent(4);\n            writer.write(\".end field\\n\");\n        }\n    }\n\n    private static void writeAccessFlags(IndentingWriter writer, int accessFlags) throws IOException {\n        for (AccessFlags accessFlag : AccessFlags.getAccessFlagsForField(accessFlags)) {\n            writer.write(accessFlag.toString());\n            writer.write(' ');\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Format/ArrayDataMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Format;\n\nimport com.taobao.android.baksmali.adaptors.MethodDefinition;\nimport com.taobao.android.baksmali.Renderers.LongRenderer;\nimport org.jf.dexlib2.iface.instruction.formats.ArrayPayload;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\nimport java.util.List;\n\npublic class ArrayDataMethodItem extends InstructionMethodItem<ArrayPayload> {\n    public ArrayDataMethodItem(MethodDefinition methodDef, int codeAddress, ArrayPayload instruction) {\n        super(methodDef, codeAddress, instruction);\n    }\n\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        int elementWidth = instruction.getElementWidth();\n\n        writer.write(\".array-data \");\n        writer.printSignedIntAsDec(instruction.getElementWidth());\n        writer.write('\\n');\n\n        writer.indent(4);\n\n        List<Number> elements = instruction.getArrayElements();\n\n        String suffix = \"\";\n        switch (elementWidth) {\n            case 1:\n                suffix = \"t\";\n                break;\n            case 2:\n                suffix = \"s\";\n                break;\n        }\n\n        for (Number number: elements) {\n            org.jf.baksmali.Renderers.LongRenderer.writeSignedIntOrLongTo(writer, number.longValue());\n            writer.write(suffix);\n            if (elementWidth == 8) {\n                writeCommentIfLikelyDouble(writer, number.longValue());\n            } else if (elementWidth == 4) {\n                int value = number.intValue();\n                boolean isResourceId = writeCommentIfResourceId(writer, value);\n                if (!isResourceId) writeCommentIfLikelyFloat(writer, value);\n            }\n            writer.write(\"\\n\");\n        }\n        writer.deindent(4);\n        writer.write(\".end array-data\");\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Format/InstructionMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Format;\n\nimport com.taobao.android.baksmali.adaptors.MethodDefinition;\nimport com.taobao.android.baksmali.adaptors.MethodItem;\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.dexlib2.Opcode;\nimport org.jf.dexlib2.ReferenceType;\nimport org.jf.dexlib2.VerificationError;\nimport org.jf.dexlib2.dexbacked.DexBackedDexFile.InvalidItemIndex;\nimport org.jf.dexlib2.iface.instruction.*;\nimport org.jf.dexlib2.iface.instruction.formats.Instruction20bc;\nimport org.jf.dexlib2.iface.instruction.formats.Instruction31t;\nimport org.jf.dexlib2.iface.instruction.formats.UnknownInstruction;\nimport org.jf.dexlib2.iface.reference.FieldReference;\nimport org.jf.dexlib2.iface.reference.MethodReference;\nimport org.jf.dexlib2.iface.reference.Reference;\nimport org.jf.dexlib2.iface.reference.TypeReference;\nimport org.jf.util.ExceptionWithContext;\nimport org.jf.util.IndentingWriter;\nimport org.jf.util.NumberUtils;\n\nimport java.io.IOException;\nimport java.util.Map;\n\nimport javax.annotation.Nonnull;\n\npublic class InstructionMethodItem<T extends Instruction> extends MethodItem {\n    @Nonnull protected final MethodDefinition methodDef;\n    @Nonnull protected final T instruction;\n\n    public InstructionMethodItem(@Nonnull MethodDefinition methodDef, int codeAddress, @Nonnull T instruction) {\n        super(codeAddress);\n        this.methodDef = methodDef;\n        this.instruction = instruction;\n    }\n\n    public double getSortOrder() {\n        //instructions should appear after everything except an \"end try\" label and .catch directive\n        return 100;\n    }\n\n    private boolean isAllowedOdex(@Nonnull Opcode opcode) {\n        BaksmaliOptions options = methodDef.classDef.options;\n        if (options.allowOdex) {\n            return true;\n        }\n\n        if (methodDef.classDef.options.apiLevel >= 14) {\n            return false;\n        }\n\n        return opcode.isVolatileFieldAccessor() || opcode == Opcode.THROW_VERIFICATION_ERROR;\n    }\n\n    private String writeInvalidItemIndex(InvalidItemIndex ex, int type, IndentingWriter writer)\n            throws IOException {\n        writer.write(\"#\");\n        writer.write(ex.getMessage());\n        writer.write(\"\\n\");\n        return String.format(\"%s@%d\", ReferenceType.toString(type), ex.getInvalidIndex());\n    }\n\n    @Override\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        Opcode opcode = instruction.getOpcode();\n        String verificationErrorName = null;\n        String referenceString = null;\n        String referenceString2 = null;\n\n        boolean commentOutInstruction = false;\n\n        if (instruction instanceof Instruction20bc) {\n            int verificationError = ((Instruction20bc)instruction).getVerificationError();\n            verificationErrorName = VerificationError.getVerificationErrorName(verificationError);\n            if (verificationErrorName == null) {\n                writer.write(\"#was invalid verification error type: \");\n                writer.printSignedIntAsDec(verificationError);\n                writer.write(\"\\n\");\n                verificationErrorName = \"generic-error\";\n            }\n        }\n\n        if (instruction instanceof ReferenceInstruction) {\n            ReferenceInstruction referenceInstruction = (ReferenceInstruction)instruction;\n            String classContext = null;\n            if (methodDef.classDef.options.implicitReferences) {\n                classContext = methodDef.method.getDefiningClass();\n            }\n\n            try {\n                Reference reference = referenceInstruction.getReference();\n                referenceString = org.jf.dexlib2.util.ReferenceUtil.getReferenceString(reference, classContext);\n                assert referenceString != null;\n            } catch (InvalidItemIndex ex) {\n                commentOutInstruction = true;\n                referenceString = writeInvalidItemIndex(ex, referenceInstruction.getReferenceType(),\n                        writer);\n            } catch (ReferenceType.InvalidReferenceTypeException ex) {\n                writer.write(\"#invalid reference type: \");\n                writer.printSignedIntAsDec(ex.getReferenceType());\n                commentOutInstruction = true;\n\n                referenceString = \"invalid_reference\";\n            }\n\n            if (instruction instanceof DualReferenceInstruction) {\n                DualReferenceInstruction dualReferenceInstruction =\n                        (DualReferenceInstruction) instruction;\n                try {\n                    Reference reference2 = dualReferenceInstruction.getReference2();\n                    referenceString2 = org.jf.dexlib2.util.ReferenceUtil.getReferenceString(reference2, classContext);\n                } catch (InvalidItemIndex ex) {\n                    commentOutInstruction = true;\n                    referenceString2 = writeInvalidItemIndex(ex,\n                            dualReferenceInstruction.getReferenceType2(), writer);\n                } catch (ReferenceType.InvalidReferenceTypeException ex) {\n                    writer.write(\"#invalid reference type: \");\n                    writer.printSignedIntAsDec(ex.getReferenceType());\n                    commentOutInstruction = true;\n\n                    referenceString2 = \"invalid_reference\";\n                }\n            }\n        }\n\n        if (instruction instanceof Instruction31t) {\n            boolean validPayload = true;\n\n            switch (instruction.getOpcode()) {\n                case PACKED_SWITCH:\n                    int baseAddress = methodDef.getPackedSwitchBaseAddress(\n                            this.codeAddress + ((Instruction31t)instruction).getCodeOffset());\n                    if (baseAddress == -1) {\n                        validPayload = false;\n                    }\n                    break;\n                case SPARSE_SWITCH:\n                    baseAddress = methodDef.getSparseSwitchBaseAddress(\n                            this.codeAddress + ((Instruction31t)instruction).getCodeOffset());\n                    if (baseAddress == -1) {\n                        validPayload = false;\n                    }\n                    break;\n                case FILL_ARRAY_DATA:\n                    try {\n                        methodDef.findPayloadOffset(this.codeAddress + ((Instruction31t)instruction).getCodeOffset(),\n                                Opcode.ARRAY_PAYLOAD);\n                    } catch (org.jf.baksmali.Adaptors.MethodDefinition.InvalidSwitchPayload ex) {\n                        validPayload = false;\n                    }\n                    break;\n                default:\n                    throw new ExceptionWithContext(\"Invalid 31t opcode: %s\", instruction.getOpcode());\n            }\n\n            if (!validPayload) {\n                writer.write(\"#invalid payload reference\\n\");\n                commentOutInstruction = true;\n            }\n        }\n\n        if (opcode.odexOnly()) {\n            if (!isAllowedOdex(opcode)) {\n                writer.write(\"#disallowed odex opcode\\n\");\n                commentOutInstruction = true;\n            }\n        }\n\n        if (commentOutInstruction) {\n            writer.write(\"#\");\n        }\n\n        switch (instruction.getOpcode().format) {\n            case Format10t:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeTargetLabel(writer);\n                break;\n            case Format10x:\n                if (instruction instanceof UnknownInstruction) {\n                    writer.write(\"#unknown opcode: 0x\");\n                    writer.printUnsignedLongAsHex(((UnknownInstruction)instruction).getOriginalOpcode());\n                    writer.write('\\n');\n                }\n                writeOpcode(writer);\n                break;\n            case Format11n:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeFirstRegister(writer);\n                writer.write(\", \");\n                writeLiteral(writer);\n                break;\n            case Format11x:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeFirstRegister(writer);\n                break;\n            case Format12x:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeFirstRegister(writer);\n                writer.write(\", \");\n                writeSecondRegister(writer);\n                break;\n            case Format20bc:\n                writeOpcode(writer);\n                writer.write(' ');\n                writer.write(verificationErrorName);\n                writer.write(\", \");\n                writer.write(referenceString);\n                break;\n            case Format20t:\n            case Format30t:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeTargetLabel(writer);\n                break;\n            case Format21c:\n            case Format31c:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeFirstRegister(writer);\n                writer.write(\", \");\n                writer.write(referenceString);\n                break;\n            case Format21ih:\n            case Format21lh:\n            case Format21s:\n            case Format31i:\n            case Format51l:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeFirstRegister(writer);\n                writer.write(\", \");\n                writeLiteral(writer);\n                if (instruction.getOpcode().setsWideRegister()) {\n                    writeCommentIfLikelyDouble(writer);\n                } else {\n                    boolean isResourceId = writeCommentIfResourceId(writer);\n                    if (!isResourceId) writeCommentIfLikelyFloat(writer);\n                }\n                break;\n            case Format21t:\n            case Format31t:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeFirstRegister(writer);\n                writer.write(\", \");\n                writeTargetLabel(writer);\n                break;\n            case Format22b:\n            case Format22s:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeFirstRegister(writer);\n                writer.write(\", \");\n                writeSecondRegister(writer);\n                writer.write(\", \");\n                writeLiteral(writer);\n                break;\n            case Format22c:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeFirstRegister(writer);\n                writer.write(\", \");\n                writeSecondRegister(writer);\n                writer.write(\", \");\n                writer.write(referenceString);\n                break;\n            case Format22cs:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeFirstRegister(writer);\n                writer.write(\", \");\n                writeSecondRegister(writer);\n                writer.write(\", \");\n                writeFieldOffset(writer);\n                break;\n            case Format22t:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeFirstRegister(writer);\n                writer.write(\", \");\n                writeSecondRegister(writer);\n                writer.write(\", \");\n                writeTargetLabel(writer);\n                break;\n            case Format22x:\n            case Format32x:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeFirstRegister(writer);\n                writer.write(\", \");\n                writeSecondRegister(writer);\n                break;\n            case Format23x:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeFirstRegister(writer);\n                writer.write(\", \");\n                writeSecondRegister(writer);\n                writer.write(\", \");\n                writeThirdRegister(writer);\n                break;\n            case Format35c:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeInvokeRegisters(writer);\n                writer.write(\", \");\n                writer.write(referenceString);\n                break;\n            case Format35mi:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeInvokeRegisters(writer);\n                writer.write(\", \");\n                writeInlineIndex(writer);\n                break;\n            case Format35ms:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeInvokeRegisters(writer);\n                writer.write(\", \");\n                writeVtableIndex(writer);\n                break;\n            case Format3rc:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeInvokeRangeRegisters(writer);\n                writer.write(\", \");\n                writer.write(referenceString);\n                break;\n            case Format3rmi:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeInvokeRangeRegisters(writer);\n                writer.write(\", \");\n                writeInlineIndex(writer);\n                break;\n            case Format3rms:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeInvokeRangeRegisters(writer);\n                writer.write(\", \");\n                writeVtableIndex(writer);\n                break;\n            case Format45cc:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeInvokeRegisters(writer);\n                writer.write(\", \");\n                writer.write(referenceString);\n                writer.write(\", \");\n                writer.write(referenceString2);\n                break;\n            case Format4rcc:\n                writeOpcode(writer);\n                writer.write(' ');\n                writeInvokeRangeRegisters(writer);\n                writer.write(\", \");\n                writer.write(referenceString);\n                writer.write(\", \");\n                writer.write(referenceString2);\n                break;\n            default:\n                assert false;\n                return false;\n        }\n\n        if (commentOutInstruction) {\n            writer.write(\"\\nnop\");\n        }\n\n        return true;\n    }\n\n    protected void writeOpcode(IndentingWriter writer) throws IOException {\n        writer.write(instruction.getOpcode().name);\n    }\n\n    protected void writeTargetLabel(IndentingWriter writer) throws IOException {\n        //this method is overridden by OffsetInstructionMethodItem, and should only be called for the formats that\n        //have a target\n        throw new RuntimeException();\n    }\n\n    protected void writeRegister(IndentingWriter writer, int registerNumber) throws IOException {\n        methodDef.registerFormatter.writeTo(writer, registerNumber);\n    }\n\n    protected void writeFirstRegister(IndentingWriter writer) throws IOException {\n        writeRegister(writer, ((OneRegisterInstruction)instruction).getRegisterA());\n    }\n\n    protected void writeSecondRegister(IndentingWriter writer) throws IOException {\n        writeRegister(writer, ((TwoRegisterInstruction)instruction).getRegisterB());\n    }\n\n    protected void writeThirdRegister(IndentingWriter writer) throws IOException {\n        writeRegister(writer, ((ThreeRegisterInstruction) instruction).getRegisterC());\n    }\n\n    protected void writeInvokeRegisters(IndentingWriter writer) throws IOException {\n        FiveRegisterInstruction instruction = (FiveRegisterInstruction)this.instruction;\n        final int regCount = instruction.getRegisterCount();\n\n        writer.write('{');\n        switch (regCount) {\n            case 1:\n                writeRegister(writer, instruction.getRegisterC());\n                break;\n            case 2:\n                writeRegister(writer, instruction.getRegisterC());\n                writer.write(\", \");\n                writeRegister(writer, instruction.getRegisterD());\n                break;\n            case 3:\n                writeRegister(writer, instruction.getRegisterC());\n                writer.write(\", \");\n                writeRegister(writer, instruction.getRegisterD());\n                writer.write(\", \");\n                writeRegister(writer, instruction.getRegisterE());\n                break;\n            case 4:\n                writeRegister(writer, instruction.getRegisterC());\n                writer.write(\", \");\n                writeRegister(writer, instruction.getRegisterD());\n                writer.write(\", \");\n                writeRegister(writer, instruction.getRegisterE());\n                writer.write(\", \");\n                writeRegister(writer, instruction.getRegisterF());\n                break;\n            case 5:\n                writeRegister(writer, instruction.getRegisterC());\n                writer.write(\", \");\n                writeRegister(writer, instruction.getRegisterD());\n                writer.write(\", \");\n                writeRegister(writer, instruction.getRegisterE());\n                writer.write(\", \");\n                writeRegister(writer, instruction.getRegisterF());\n                writer.write(\", \");\n                writeRegister(writer, instruction.getRegisterG());\n                break;\n        }\n        writer.write('}');\n    }\n\n    protected void writeInvokeRangeRegisters(IndentingWriter writer) throws IOException {\n        RegisterRangeInstruction instruction = (RegisterRangeInstruction)this.instruction;\n\n        int regCount = instruction.getRegisterCount();\n        if (regCount == 0) {\n            writer.write(\"{}\");\n        } else {\n            int startRegister = instruction.getStartRegister();\n            methodDef.registerFormatter.writeRegisterRange(writer, startRegister, startRegister+regCount-1);\n        }\n    }\n\n    protected void writeLiteral(IndentingWriter writer) throws IOException {\n        org.jf.baksmali.Renderers.LongRenderer.writeSignedIntOrLongTo(writer, ((WideLiteralInstruction)instruction).getWideLiteral());\n    }\n\n    protected void writeCommentIfLikelyFloat(IndentingWriter writer) throws IOException {\n        writeCommentIfLikelyFloat(writer, ((NarrowLiteralInstruction)instruction).getNarrowLiteral());\n    }\n\n    protected void writeCommentIfLikelyFloat(IndentingWriter writer, int val) throws IOException {\n        if (NumberUtils.isLikelyFloat(val)) {\n            writer.write(\"    # \");\n            float fval = Float.intBitsToFloat(val);\n            if (fval == Float.POSITIVE_INFINITY)\n                writer.write(\"Float.POSITIVE_INFINITY\");\n            else if (fval == Float.NEGATIVE_INFINITY)\n                writer.write(\"Float.NEGATIVE_INFINITY\");\n            else if (fval == Float.NaN)\n                writer.write(\"Float.NaN\");\n            else if (fval == Float.MAX_VALUE)\n                writer.write(\"Float.MAX_VALUE\");\n            else if (fval == (float)Math.PI)\n                writer.write(\"(float)Math.PI\");\n            else if (fval == (float)Math.E)\n                writer.write(\"(float)Math.E\");\n            else {\n                writer.write(Float.toString(fval));\n                writer.write('f');\n            }\n        }\n    }\n\n    protected void writeCommentIfLikelyDouble(IndentingWriter writer) throws IOException {\n        writeCommentIfLikelyDouble(writer, ((WideLiteralInstruction)instruction).getWideLiteral());\n    }\n\n    protected void writeCommentIfLikelyDouble(IndentingWriter writer, long val) throws IOException {\n        if (NumberUtils.isLikelyDouble(val)) {\n            writer.write(\"    # \");\n            double dval = Double.longBitsToDouble(val);\n            if (dval == Double.POSITIVE_INFINITY)\n                writer.write(\"Double.POSITIVE_INFINITY\");\n            else if (dval == Double.NEGATIVE_INFINITY)\n                writer.write(\"Double.NEGATIVE_INFINITY\");\n            else if (dval == Double.NaN)\n                writer.write(\"Double.NaN\");\n            else if (dval == Double.MAX_VALUE)\n                writer.write(\"Double.MAX_VALUE\");\n            else if (dval == Math.PI)\n                writer.write(\"Math.PI\");\n            else if (dval == Math.E)\n                writer.write(\"Math.E\");\n            else\n                writer.write(Double.toString(dval));\n        }\n    }\n\n    protected boolean writeCommentIfResourceId(IndentingWriter writer) throws IOException {\n        return writeCommentIfResourceId(writer, ((NarrowLiteralInstruction)instruction).getNarrowLiteral());\n    }\n\n    protected boolean writeCommentIfResourceId(IndentingWriter writer, int val) throws IOException {\n        Map<Integer,String> resourceIds = methodDef.classDef.options.resourceIds;\n        String resource = resourceIds.get(Integer.valueOf(val));\n        if (resource != null) {\n            writer.write(\"    # \");\n            writer.write(resource);\n            return true;\n        }\n        return false;\n    }\n\n    protected void writeFieldOffset(IndentingWriter writer) throws IOException {\n        writer.write(\"field@0x\");\n        writer.printUnsignedLongAsHex(((FieldOffsetInstruction)instruction).getFieldOffset());\n    }\n\n    protected void writeInlineIndex(IndentingWriter writer) throws IOException {\n        writer.write(\"inline@\");\n        writer.printSignedIntAsDec(((InlineIndexInstruction)instruction).getInlineIndex());\n    }\n\n    protected void writeVtableIndex(IndentingWriter writer) throws IOException {\n        writer.write(\"vtable@\");\n        writer.printSignedIntAsDec(((VtableIndexInstruction)instruction).getVtableIndex());\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Format/InstructionMethodItemFactory.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Format;\n\nimport com.taobao.android.baksmali.adaptors.MethodDefinition;\nimport org.jf.dexlib2.analysis.UnresolvedOdexInstruction;\nimport org.jf.dexlib2.iface.instruction.Instruction;\nimport org.jf.dexlib2.iface.instruction.OffsetInstruction;\nimport org.jf.dexlib2.iface.instruction.formats.ArrayPayload;\nimport org.jf.dexlib2.iface.instruction.formats.PackedSwitchPayload;\nimport org.jf.dexlib2.iface.instruction.formats.SparseSwitchPayload;\n\npublic class InstructionMethodItemFactory {\n    private InstructionMethodItemFactory() {\n    }\n\n    public static InstructionMethodItem makeInstructionFormatMethodItem(\n            MethodDefinition methodDef, int codeAddress, Instruction instruction) {\n\n        if (instruction instanceof OffsetInstruction) {\n            return new OffsetInstructionFormatMethodItem(methodDef.classDef.options, methodDef, codeAddress,\n                    (OffsetInstruction)instruction);\n        }\n\n        if (instruction instanceof UnresolvedOdexInstruction) {\n            return new UnresolvedOdexInstructionMethodItem(methodDef, codeAddress,\n                    (UnresolvedOdexInstruction)instruction);\n        }\n\n        switch (instruction.getOpcode().format) {\n            case ArrayPayload:\n                return new ArrayDataMethodItem(methodDef, codeAddress, (ArrayPayload)instruction);\n            case PackedSwitchPayload:\n                return new PackedSwitchMethodItem(methodDef, codeAddress, (PackedSwitchPayload)instruction);\n            case SparseSwitchPayload:\n                return new SparseSwitchMethodItem(methodDef, codeAddress, (SparseSwitchPayload)instruction);\n            default:\n                return new InstructionMethodItem<Instruction>(methodDef, codeAddress, instruction);\n        }\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Format/OffsetInstructionFormatMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Format;\n\nimport com.taobao.android.baksmali.adaptors.LabelMethodItem;\nimport com.taobao.android.baksmali.adaptors.MethodDefinition;\n\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.dexlib2.Opcode;\nimport org.jf.dexlib2.iface.instruction.OffsetInstruction;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\nimport javax.annotation.Nonnull;\n\npublic class OffsetInstructionFormatMethodItem extends InstructionMethodItem<OffsetInstruction> {\n    protected LabelMethodItem label;\n\n    public OffsetInstructionFormatMethodItem(@Nonnull BaksmaliOptions options, @Nonnull MethodDefinition methodDef,\n                                             int codeAddress, OffsetInstruction instruction) {\n        super(methodDef, codeAddress, instruction);\n\n        label = new LabelMethodItem(options, codeAddress + instruction.getCodeOffset(), getLabelPrefix());\n        label = methodDef.getLabelCache().internLabel(label);\n    }\n\n    @Override\n    protected void writeTargetLabel(IndentingWriter writer) throws IOException {\n        label.writeTo(writer);\n    }\n\n    public LabelMethodItem getLabel() {\n        return label;\n    }\n\n    private String getLabelPrefix() {\n        Opcode opcode = instruction.getOpcode();\n        switch (opcode.format) {\n            case Format10t:\n            case Format20t:\n            case Format30t:\n                return \"goto_\";\n            case Format21t:\n            case Format22t:\n                return \"cond_\";\n            case Format31t:\n                if (opcode == Opcode.FILL_ARRAY_DATA) {\n                    return \"array_\";\n                }\n                if (opcode == Opcode.PACKED_SWITCH) {\n                    return \"pswitch_data_\";\n                }\n                // Opcode.SPARSE_SWITCH;\n                return \"sswitch_data_\";\n        }\n\n        assert false;\n        return null;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Format/PackedSwitchMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Format;\n\nimport com.taobao.android.baksmali.adaptors.CommentingIndentingWriter;\nimport com.taobao.android.baksmali.adaptors.LabelMethodItem;\nimport com.taobao.android.baksmali.adaptors.MethodDefinition;\nimport com.taobao.android.baksmali.Renderers.IntegerRenderer;\nimport org.jf.dexlib2.iface.instruction.SwitchElement;\nimport org.jf.dexlib2.iface.instruction.formats.PackedSwitchPayload;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchPayload> {\n    private final List<PackedSwitchMethodItem.PackedSwitchTarget> targets;\n    private final int firstKey;\n\n    // Whether this sparse switch instruction should be commented out because it is never referenced\n    private boolean commentedOut;\n\n    public PackedSwitchMethodItem(MethodDefinition methodDef, int codeAddress, PackedSwitchPayload instruction) {\n        super(methodDef, codeAddress, instruction);\n\n        int baseCodeAddress = methodDef.getPackedSwitchBaseAddress(codeAddress);\n\n        targets = new ArrayList<PackedSwitchMethodItem.PackedSwitchTarget>();\n\n        boolean first = true;\n        int firstKey = 0;\n        if (baseCodeAddress >= 0) {\n            for (SwitchElement switchElement: instruction.getSwitchElements()) {\n                if (first) {\n                    firstKey = switchElement.getKey();\n                    first = false;\n                }\n                LabelMethodItem label = methodDef.getLabelCache().internLabel(\n                        new LabelMethodItem(methodDef.classDef.options, baseCodeAddress + switchElement.getOffset(),\n                                \"pswitch_\"));\n                targets.add(new PackedSwitchMethodItem.PackedSwitchLabelTarget(label));\n            }\n        } else {\n            commentedOut = true;\n            for (SwitchElement switchElement: instruction.getSwitchElements()) {\n                if (first) {\n                    firstKey = switchElement.getKey();\n                    first = false;\n                }\n                targets.add(new PackedSwitchMethodItem.PackedSwitchOffsetTarget(switchElement.getOffset()));\n            }\n        }\n        this.firstKey = firstKey;\n    }\n\n    @Override\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        if (commentedOut) {\n            writer = new org.jf.baksmali.Adaptors.CommentingIndentingWriter(writer);\n        }\n        writer.write(\".packed-switch \");\n        org.jf.baksmali.Renderers.IntegerRenderer.writeTo(writer, firstKey);\n        writer.indent(4);\n        writer.write('\\n');\n        int key = firstKey;\n        for (PackedSwitchMethodItem.PackedSwitchTarget target: targets) {\n            target.writeTargetTo(writer);\n            writeCommentIfResourceId(writer, key);\n            writer.write('\\n');\n            key++;\n        }\n        writer.deindent(4);\n        writer.write(\".end packed-switch\");\n        return true;\n    }\n\n    private static abstract class PackedSwitchTarget {\n        public abstract void writeTargetTo(IndentingWriter writer) throws IOException;\n    }\n\n    private static class PackedSwitchLabelTarget extends PackedSwitchTarget {\n        private final LabelMethodItem target;\n        public PackedSwitchLabelTarget(LabelMethodItem target) {\n            this.target = target;\n        }\n        public void writeTargetTo(IndentingWriter writer) throws IOException {\n            target.writeTo(writer);\n        }\n    }\n\n    private static class PackedSwitchOffsetTarget extends PackedSwitchTarget {\n        private final int target;\n        public PackedSwitchOffsetTarget(int target) {\n            this.target = target;\n        }\n        public void writeTargetTo(IndentingWriter writer) throws IOException {\n            if (target >= 0) {\n                writer.write('+');\n            }\n            writer.printSignedIntAsDec(target);\n        }\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Format/SparseSwitchMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Format;\n\nimport com.taobao.android.baksmali.adaptors.CommentingIndentingWriter;\nimport com.taobao.android.baksmali.adaptors.LabelMethodItem;\nimport com.taobao.android.baksmali.adaptors.MethodDefinition;\nimport com.taobao.android.baksmali.Renderers.IntegerRenderer;\n\nimport org.jf.dexlib2.iface.instruction.SwitchElement;\nimport org.jf.dexlib2.iface.instruction.formats.SparseSwitchPayload;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchPayload> {\n    private final List<SparseSwitchMethodItem.SparseSwitchTarget> targets;\n\n    // Whether this sparse switch instruction should be commented out because it is never referenced\n    private boolean commentedOut;\n\n    public SparseSwitchMethodItem(MethodDefinition methodDef, int codeAddress, SparseSwitchPayload instruction) {\n        super(methodDef, codeAddress, instruction);\n\n        int baseCodeAddress = methodDef.getSparseSwitchBaseAddress(codeAddress);\n\n        targets = new ArrayList<SparseSwitchMethodItem.SparseSwitchTarget>();\n        if (baseCodeAddress >= 0) {\n            for (SwitchElement switchElement: instruction.getSwitchElements()) {\n                LabelMethodItem label = methodDef.getLabelCache().internLabel(\n                        new LabelMethodItem( methodDef.classDef.options, baseCodeAddress + switchElement.getOffset(),\n                                \"sswitch_\"));\n                targets.add(new SparseSwitchMethodItem.SparseSwitchLabelTarget(switchElement.getKey(), label));\n            }\n        } else {\n            commentedOut = true;\n            //if we couldn't determine a base address, just use relative offsets rather than labels\n            for (SwitchElement switchElement: instruction.getSwitchElements()) {\n                targets.add(new SparseSwitchMethodItem.SparseSwitchOffsetTarget(switchElement.getKey(), switchElement.getOffset()));\n            }\n        }\n    }\n\n    @Override\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        if (commentedOut) {\n            writer = new org.jf.baksmali.Adaptors.CommentingIndentingWriter(writer);\n        }\n\n        writer.write(\".sparse-switch\\n\");\n        writer.indent(4);\n        for (SparseSwitchMethodItem.SparseSwitchTarget target: targets) {\n            org.jf.baksmali.Renderers.IntegerRenderer.writeTo(writer, target.getKey());\n            writer.write(\" -> \");\n            target.writeTargetTo(writer);\n            writeCommentIfResourceId(writer, target.getKey());\n            writer.write('\\n');\n        }\n        writer.deindent(4);\n        writer.write(\".end sparse-switch\");\n        return true;\n    }\n\n    private static abstract class SparseSwitchTarget {\n        private final int key;\n        public SparseSwitchTarget(int key) {\n            this.key = key;\n        }\n        public int getKey() { return key; }\n        public abstract void writeTargetTo(IndentingWriter writer) throws IOException;\n    }\n\n    private static class SparseSwitchLabelTarget extends SparseSwitchMethodItem.SparseSwitchTarget {\n        private final LabelMethodItem target;\n        public SparseSwitchLabelTarget(int key, LabelMethodItem target) {\n            super(key);\n            this.target = target;\n        }\n\n        public void writeTargetTo(IndentingWriter writer) throws IOException {\n            target.writeTo(writer);\n        }\n    }\n\n    private static class SparseSwitchOffsetTarget extends SparseSwitchMethodItem.SparseSwitchTarget {\n        private final int target;\n        public SparseSwitchOffsetTarget(int key, int target) {\n            super(key);\n            this.target = target;\n        }\n\n        public void writeTargetTo(IndentingWriter writer) throws IOException {\n            if (target >= 0) {\n                writer.write('+');\n            }\n            writer.printSignedIntAsDec(target);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/Format/UnresolvedOdexInstructionMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors.Format;\n\nimport com.taobao.android.baksmali.adaptors.MethodDefinition;\nimport org.jf.dexlib2.analysis.UnresolvedOdexInstruction;\nimport org.jf.util.IndentingWriter;\n\nimport javax.annotation.Nonnull;\nimport java.io.IOException;\n\npublic class UnresolvedOdexInstructionMethodItem extends InstructionMethodItem<UnresolvedOdexInstruction> {\n    public UnresolvedOdexInstructionMethodItem(@Nonnull MethodDefinition methodDef, int codeAddress,\n                                               @Nonnull UnresolvedOdexInstruction instruction) {\n        super(methodDef, codeAddress, instruction);\n    }\n\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        writeThrowTo(writer);\n        return true;\n    }\n\n    private void writeThrowTo(IndentingWriter writer) throws IOException {\n        writer.write(\"#Replaced unresolvable odex instruction with a throw\\n\");\n        writer.write(\"throw \");\n        writeRegister(writer, instruction.objectRegisterNum);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/LabelMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\nimport javax.annotation.Nonnull;\n\npublic class LabelMethodItem extends MethodItem {\n    private final BaksmaliOptions options;\n    private final String labelPrefix;\n    private int labelSequence;\n\n    public LabelMethodItem(@Nonnull BaksmaliOptions options, int codeAddress, @Nonnull String labelPrefix) {\n        super(codeAddress);\n        this.options = options;\n        this.labelPrefix = labelPrefix;\n    }\n\n    public double getSortOrder() {\n        return 0;\n    }\n\n    public int compareTo(MethodItem methodItem) {\n        int result = super.compareTo(methodItem);\n\n        if (result == 0) {\n            if (methodItem instanceof LabelMethodItem) {\n                result = labelPrefix.compareTo(((LabelMethodItem)methodItem).labelPrefix);\n            }\n        }\n        return result;\n    }\n\n    public int hashCode() {\n        //force it to call equals when two labels are at the same address\n        return getCodeAddress();\n    }\n\n    public boolean equals(Object o) {\n        if (!(o instanceof LabelMethodItem)) {\n            return false;\n        }\n        return this.compareTo((MethodItem)o) == 0;\n    }\n\n\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        writer.write(':');\n        writer.write(labelPrefix);\n        if (options.sequentialLabels) {\n            writer.printUnsignedLongAsHex(labelSequence);\n        } else {\n            writer.printUnsignedLongAsHex(this.getLabelAddress());\n        }\n        return true;\n    }\n\n    public String getLabelPrefix() {\n        return labelPrefix;\n    }\n\n    public int getLabelAddress() {\n        return this.getCodeAddress();\n    }\n\n    public int getLabelSequence() {\n        return labelSequence;\n    }\n\n    public void setLabelSequence(int labelSequence) {\n        this.labelSequence = labelSequence;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/MethodDefinition.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.apatch.annotation.MethodReplaceAnnotation;\nimport com.taobao.android.baksmali.adaptors.Debug.DebugMethodItem;\nimport com.taobao.android.baksmali.adaptors.Debug.EndPrologueMethodItem;\nimport com.taobao.android.baksmali.adaptors.Format.InstructionMethodItemFactory;\nimport com.taobao.android.baksmali.util.ReferenceUtil;\nimport com.taobao.android.object.DexDiffInfo;\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.dexlib2.AccessFlags;\nimport org.jf.dexlib2.Format;\nimport org.jf.dexlib2.Opcode;\nimport org.jf.dexlib2.ReferenceType;\nimport org.jf.dexlib2.analysis.AnalysisException;\nimport org.jf.dexlib2.analysis.AnalyzedInstruction;\nimport org.jf.dexlib2.analysis.MethodAnalyzer;\nimport org.jf.dexlib2.dexbacked.DexBackedDexFile.InvalidItemIndex;\nimport org.jf.dexlib2.iface.*;\nimport org.jf.dexlib2.iface.debug.DebugItem;\nimport org.jf.dexlib2.iface.instruction.Instruction;\nimport org.jf.dexlib2.iface.instruction.OffsetInstruction;\nimport org.jf.dexlib2.iface.instruction.ReferenceInstruction;\nimport org.jf.dexlib2.iface.instruction.formats.Instruction31t;\nimport org.jf.dexlib2.iface.reference.MethodReference;\nimport org.jf.dexlib2.immutable.instruction.ImmutableInstruction31t;\nimport org.jf.dexlib2.util.InstructionOffsetMap;\nimport org.jf.dexlib2.util.InstructionOffsetMap.InvalidInstructionOffset;\nimport org.jf.dexlib2.util.SyntheticAccessorResolver;\nimport org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember;\nimport org.jf.dexlib2.util.TypeUtils;\nimport org.jf.util.ExceptionWithContext;\nimport org.jf.util.IndentingWriter;\nimport org.jf.util.SparseIntArray;\n\nimport javax.annotation.Nonnull;\nimport javax.annotation.Nullable;\nimport java.io.IOException;\nimport java.util.*;\n\npublic class MethodDefinition {\n    @Nonnull\n    public final ClassDefinition classDef;\n    @Nonnull\n    public final Method method;\n    @Nonnull\n    public final MethodImplementation methodImpl;\n    @Nonnull\n    public final ImmutableList<Instruction> instructions;\n    @Nonnull\n    public final List<Instruction> effectiveInstructions;\n\n    @Nonnull\n    public final ImmutableList<MethodParameter> methodParameters;\n    public RegisterFormatter registerFormatter;\n\n    @Nonnull\n    private final LabelCache labelCache = new LabelCache();\n\n    @Nonnull\n    private final SparseIntArray packedSwitchMap;\n    @Nonnull\n    private final SparseIntArray sparseSwitchMap;\n    @Nonnull\n    private final InstructionOffsetMap instructionOffsetMap;\n    private boolean fullMethod = false;\n\n    public void setFullMethod(boolean fullMethod) {\n        this.fullMethod = fullMethod;\n    }\n\n    public MethodDefinition(@Nonnull ClassDefinition classDef, @Nonnull Method method,\n                            @Nonnull MethodImplementation methodImpl) {\n        this.classDef = classDef;\n        this.method = method;\n        this.methodImpl = methodImpl;\n\n        try {\n            //TODO: what about try/catch blocks inside the dead code? those will need to be commented out too. ugh.\n\n            instructions = ImmutableList.copyOf(methodImpl.getInstructions());\n            methodParameters = ImmutableList.copyOf(method.getParameters());\n\n            effectiveInstructions = Lists.newArrayList(instructions);\n\n            packedSwitchMap = new SparseIntArray(0);\n            sparseSwitchMap = new SparseIntArray(0);\n            instructionOffsetMap = new InstructionOffsetMap(instructions);\n\n            int endOffset = instructionOffsetMap.getInstructionCodeOffset(instructions.size() - 1) +\n                    instructions.get(instructions.size() - 1).getCodeUnits();\n\n            for (int i = 0; i < instructions.size(); i++) {\n                Instruction instruction = instructions.get(i);\n\n                Opcode opcode = instruction.getOpcode();\n                if (opcode == Opcode.PACKED_SWITCH) {\n                    boolean valid = true;\n                    int codeOffset = instructionOffsetMap.getInstructionCodeOffset(i);\n                    int targetOffset = codeOffset + ((OffsetInstruction) instruction).getCodeOffset();\n                    try {\n                        targetOffset = findPayloadOffset(targetOffset, Opcode.PACKED_SWITCH_PAYLOAD);\n                    } catch (InvalidSwitchPayload ex) {\n                        valid = false;\n                    }\n                    if (valid) {\n                        if (packedSwitchMap.get(targetOffset, -1) != -1) {\n                            Instruction payloadInstruction =\n                                    findSwitchPayload(targetOffset, Opcode.PACKED_SWITCH_PAYLOAD);\n                            targetOffset = endOffset;\n                            effectiveInstructions.set(i, new ImmutableInstruction31t(opcode,\n                                    ((Instruction31t) instruction).getRegisterA(), targetOffset - codeOffset));\n                            effectiveInstructions.add(payloadInstruction);\n                            endOffset += payloadInstruction.getCodeUnits();\n                        }\n                        packedSwitchMap.append(targetOffset, codeOffset);\n                    }\n                } else if (opcode == Opcode.SPARSE_SWITCH) {\n                    boolean valid = true;\n                    int codeOffset = instructionOffsetMap.getInstructionCodeOffset(i);\n                    int targetOffset = codeOffset + ((OffsetInstruction) instruction).getCodeOffset();\n                    try {\n                        targetOffset = findPayloadOffset(targetOffset, Opcode.SPARSE_SWITCH_PAYLOAD);\n                    } catch (InvalidSwitchPayload ex) {\n                        valid = false;\n                        // The offset to the payload instruction was invalid. Nothing to do, except that we won't\n                        // add this instruction to the map.\n                    }\n                    if (valid) {\n                        if (sparseSwitchMap.get(targetOffset, -1) != -1) {\n                            Instruction payloadInstruction =\n                                    findSwitchPayload(targetOffset, Opcode.SPARSE_SWITCH_PAYLOAD);\n                            targetOffset = endOffset;\n                            effectiveInstructions.set(i, new ImmutableInstruction31t(opcode,\n                                    ((Instruction31t) instruction).getRegisterA(), targetOffset - codeOffset));\n                            effectiveInstructions.add(payloadInstruction);\n                            endOffset += payloadInstruction.getCodeUnits();\n                        }\n                        sparseSwitchMap.append(targetOffset, codeOffset);\n                    }\n                }\n            }\n        } catch (Exception ex) {\n            String methodString;\n            try {\n                methodString = ReferenceUtil.getMethodDescriptor(method);\n            } catch (Exception ex2) {\n                throw ExceptionWithContext.withContext(ex, \"Error while processing method\");\n            }\n            throw ExceptionWithContext.withContext(ex, \"Error while processing method %s\", methodString);\n        }\n    }\n\n    public static void writeEmptyMethodTo(IndentingWriter writer, Method method,\n                                          BaksmaliOptions options) throws IOException {\n        writer.write(\".method \");\n        writeAccessFlags(writer, method.getAccessFlags());\n        writer.write(method.getName());\n        writer.write(\"(\");\n        ImmutableList<MethodParameter> methodParameters = ImmutableList.copyOf(method.getParameters());\n        for (MethodParameter parameter : methodParameters) {\n            writer.write(parameter.getType());\n        }\n        writer.write(\")\");\n        writer.write(method.getReturnType());\n        writer.write('\\n');\n\n        writer.indent(4);\n        writeParameters(writer, method, methodParameters, options);\n\n        String containingClass = null;\n        if (options.implicitReferences) {\n            containingClass = method.getDefiningClass();\n        }\n        //如果是修改的方法，需要添加ReplaceAnnotation\n        if (DexDiffInfo.modifiedMethods.contains(method)) {\n            MethodReplaceAnnotation replaceAnnotation = new MethodReplaceAnnotation(method.getDefiningClass(), method.getName());\n            AnnotationFormatter.writeTo(writer, method.getAnnotations(), containingClass, replaceAnnotation);\n        } else {\n            AnnotationFormatter.writeTo(writer, method.getAnnotations(), containingClass);\n        }\n        writer.deindent(4);\n        writer.write(\".end method\\n\");\n    }\n\n    public void writeTo(IndentingWriter writer) throws IOException {\n        int parameterRegisterCount = 0;\n        if (!AccessFlags.STATIC.isSet(method.getAccessFlags())) {\n            parameterRegisterCount++;\n        }\n\n        writer.write(\".method \");\n        writeAccessFlags(writer, method.getAccessFlags());\n        writer.write(method.getName());\n        writer.write(\"(\");\n        for (MethodParameter parameter : methodParameters) {\n            String type = parameter.getType();\n            writer.write(type);\n            parameterRegisterCount++;\n            if (TypeUtils.isWideType(type)) {\n                parameterRegisterCount++;\n            }\n        }\n        writer.write(\")\");\n        writer.write(method.getReturnType());\n        writer.write('\\n');\n\n        writer.indent(4);\n        if (classDef.options.localsDirective) {\n            writer.write(\".locals \");\n            int registerCount = methodImpl.getRegisterCount() - parameterRegisterCount;\n            writer.printSignedIntAsDec(registerCount);\n        } else {\n            writer.write(\".registers \");\n            writer.printSignedIntAsDec(methodImpl.getRegisterCount());\n        }\n        writer.write('\\n');\n        writeParameters(writer, method, methodParameters, classDef.options);\n\n        if (registerFormatter == null) {\n            registerFormatter = new RegisterFormatter(classDef.options, methodImpl.getRegisterCount(),\n                    parameterRegisterCount);\n        }\n\n        String containingClass = null;\n        if (classDef.options.implicitReferences) {\n            containingClass = method.getDefiningClass();\n        }\n        //如果是修改的方法，需要添加ReplaceAnnotation\n        if (DexDiffInfo.modifiedMethods.contains(method)) {\n            MethodReplaceAnnotation replaceAnnotation = new MethodReplaceAnnotation(method.getDefiningClass(), method.getName());\n            AnnotationFormatter.writeTo(writer, method.getAnnotations(), containingClass, replaceAnnotation);\n        } else {\n            AnnotationFormatter.writeTo(writer, method.getAnnotations(), containingClass);\n        }\n\n        writer.write('\\n');\n\n        boolean first = true;\n        boolean writeCheckCast = false;\n        List<MethodItem> methodItems = getMethodItems();\n        for (MethodItem methodItem : methodItems) {\n            if (first) {\n                first = false;\n                if (!fullMethod && !(methodItem instanceof EndPrologueMethodItem) && !DexDiffInfo.addedClasses.contains(classDef.getClassDef())) {\n                    if (!AccessFlags.STATIC.isSet(method.getAccessFlags())) {\n                        writer.write(\"check-cast p0, \" + method.getDefiningClass());\n                        writer.write('\\n');\n                        writeCheckCast = true;\n\n                    }\n                }\n\n            }\n            if (methodItem.writeTo(writer)) {\n                writer.write('\\n');\n            }\n\n            if (!writeCheckCast && !fullMethod && !DexDiffInfo.addedClasses.contains(classDef.getClassDef())) {\n                if (!AccessFlags.STATIC.isSet(method.getAccessFlags())) {\n                    if (methodItem instanceof EndPrologueMethodItem) {\n                        writer.write(\"check-cast p0, \" + method.getDefiningClass());\n                        writer.write('\\n');\n                        writeCheckCast = true;\n                    }\n                }\n\n\n            }\n        }\n        writer.deindent(4);\n        writer.write(\".end method\\n\");\n    }\n\n    public Instruction findSwitchPayload(int targetOffset, Opcode type) {\n        int targetIndex;\n        try {\n            targetIndex = instructionOffsetMap.getInstructionIndexAtCodeOffset(targetOffset);\n        } catch (InvalidInstructionOffset ex) {\n            throw new InvalidSwitchPayload(targetOffset);\n        }\n\n        //TODO: does dalvik let you pad with multiple nops?\n        //TODO: does dalvik let a switch instruction point to a non-payload instruction?\n\n        Instruction instruction = instructions.get(targetIndex);\n        if (instruction.getOpcode() != type) {\n            // maybe it's pointing to a NOP padding instruction. Look at the next instruction\n            if (instruction.getOpcode() == Opcode.NOP) {\n                targetIndex += 1;\n                if (targetIndex < instructions.size()) {\n                    instruction = instructions.get(targetIndex);\n                    if (instruction.getOpcode() == type) {\n                        return instruction;\n                    }\n                }\n            }\n            throw new InvalidSwitchPayload(targetOffset);\n        } else {\n            return instruction;\n        }\n    }\n\n    public int findPayloadOffset(int targetOffset, Opcode type) {\n        int targetIndex;\n        try {\n            targetIndex = instructionOffsetMap.getInstructionIndexAtCodeOffset(targetOffset);\n        } catch (InvalidInstructionOffset ex) {\n            throw new InvalidSwitchPayload(targetOffset);\n        }\n\n        //TODO: does dalvik let you pad with multiple nops?\n        //TODO: does dalvik let a switch instruction point to a non-payload instruction?\n\n        Instruction instruction = instructions.get(targetIndex);\n        if (instruction.getOpcode() != type) {\n            // maybe it's pointing to a NOP padding instruction. Look at the next instruction\n            if (instruction.getOpcode() == Opcode.NOP) {\n                targetIndex += 1;\n                if (targetIndex < instructions.size()) {\n                    instruction = instructions.get(targetIndex);\n                    if (instruction.getOpcode() == type) {\n                        return instructionOffsetMap.getInstructionCodeOffset(targetIndex);\n                    }\n                }\n            }\n            throw new InvalidSwitchPayload(targetOffset);\n        } else {\n            return targetOffset;\n        }\n    }\n\n    private static void writeAccessFlags(IndentingWriter writer, int accessFlags)\n            throws IOException {\n        for (AccessFlags accessFlag : AccessFlags.getAccessFlagsForMethod(accessFlags)) {\n            writer.write(accessFlag.toString());\n            writer.write(' ');\n        }\n    }\n\n    private static void writeParameters(IndentingWriter writer, Method method,\n                                        List<? extends MethodParameter> parameters,\n                                        BaksmaliOptions options) throws IOException {\n        boolean isStatic = AccessFlags.STATIC.isSet(method.getAccessFlags());\n        int registerNumber = isStatic ? 0 : 1;\n        for (MethodParameter parameter : parameters) {\n            String parameterType = parameter.getType();\n            String parameterName = parameter.getName();\n            Collection<? extends Annotation> annotations = parameter.getAnnotations();\n            if (parameterName != null || annotations.size() != 0) {\n                writer.write(\".param p\");\n                writer.printSignedIntAsDec(registerNumber);\n\n                if (parameterName != null && options.debugInfo) {\n                    writer.write(\", \");\n                    ReferenceFormatter.writeStringReference(writer, parameterName);\n                }\n                writer.write(\"    # \");\n                writer.write(parameterType);\n                writer.write(\"\\n\");\n                if (annotations.size() > 0) {\n                    writer.indent(4);\n\n                    String containingClass = null;\n                    if (options.implicitReferences) {\n                        containingClass = method.getDefiningClass();\n                    }\n                    AnnotationFormatter.writeTo(writer, annotations, containingClass);\n                    writer.deindent(4);\n                    writer.write(\".end param\\n\");\n                }\n            }\n\n            registerNumber++;\n            if (TypeUtils.isWideType(parameterType)) {\n                registerNumber++;\n            }\n        }\n    }\n\n    @Nonnull\n    public LabelCache getLabelCache() {\n        return labelCache;\n    }\n\n    public int getPackedSwitchBaseAddress(int packedSwitchPayloadCodeOffset) {\n        return packedSwitchMap.get(packedSwitchPayloadCodeOffset, -1);\n    }\n\n    public int getSparseSwitchBaseAddress(int sparseSwitchPayloadCodeOffset) {\n        return sparseSwitchMap.get(sparseSwitchPayloadCodeOffset, -1);\n    }\n\n    private List<MethodItem> getMethodItems() {\n        ArrayList<MethodItem> methodItems = new ArrayList<MethodItem>();\n\n        if ((classDef.options.registerInfo != 0) || (classDef.options.deodex && needsAnalyzed())) {\n            addAnalyzedInstructionMethodItems(methodItems);\n        } else {\n            addInstructionMethodItems(methodItems);\n        }\n\n        addTries(methodItems);\n        if (classDef.options.debugInfo) {\n            addDebugInfo(methodItems);\n        }\n\n        if (classDef.options.sequentialLabels) {\n            setLabelSequentialNumbers();\n        }\n\n        for (LabelMethodItem labelMethodItem : labelCache.getLabels()) {\n            methodItems.add(labelMethodItem);\n        }\n\n        Collections.sort(methodItems);\n\n        return methodItems;\n    }\n\n    private boolean needsAnalyzed() {\n        for (Instruction instruction : methodImpl.getInstructions()) {\n            if (instruction.getOpcode().odexOnly()) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private void addInstructionMethodItems(List<MethodItem> methodItems) {\n        int currentCodeAddress = 0;\n\n        for (int i = 0; i < effectiveInstructions.size(); i++) {\n            Instruction instruction = effectiveInstructions.get(i);\n\n            MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this,\n                    currentCodeAddress, instruction);\n\n            methodItems.add(methodItem);\n\n            if (i != effectiveInstructions.size() - 1) {\n                methodItems.add(new BlankMethodItem(currentCodeAddress));\n            }\n\n            if (classDef.options.codeOffsets) {\n                methodItems.add(new MethodItem(currentCodeAddress) {\n\n                    @Override\n                    public double getSortOrder() {\n                        return -1000;\n                    }\n\n                    @Override\n                    public boolean writeTo(IndentingWriter writer) throws IOException {\n                        writer.write(\"#@\");\n                        writer.printUnsignedLongAsHex(codeAddress & 0xFFFFFFFFL);\n                        return true;\n                    }\n                });\n            }\n\n            if (!classDef.options.accessorComments && (instruction instanceof ReferenceInstruction)) {\n                Opcode opcode = instruction.getOpcode();\n\n                if (opcode.referenceType == ReferenceType.METHOD) {\n                    MethodReference methodReference = null;\n                    try {\n                        methodReference = (MethodReference) ((ReferenceInstruction) instruction).getReference();\n                    } catch (InvalidItemIndex ex) {\n                        // just ignore it for now. We'll deal with it later, when processing the instructions\n                        // themselves\n                    }\n\n                    if (methodReference != null &&\n                            SyntheticAccessorResolver.looksLikeSyntheticAccessor(methodReference.getName())) {\n                        AccessedMember accessedMember =\n                                classDef.options.syntheticAccessorResolver.getAccessedMember(methodReference);\n                        if (accessedMember != null) {\n                            methodItems.add(new SyntheticAccessCommentMethodItem(accessedMember, currentCodeAddress));\n                        }\n                    }\n                }\n            }\n\n            currentCodeAddress += instruction.getCodeUnits();\n        }\n    }\n\n    private void addAnalyzedInstructionMethodItems(List<MethodItem> methodItems) {\n        MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classDef.options.classPath, method,\n                classDef.options.inlineResolver,classDef.options.normalizeVirtualMethods);\n\n        AnalysisException analysisException = methodAnalyzer.getAnalysisException();\n        if (analysisException != null) {\n            // TODO: need to keep track of whether any errors occurred, so we can exit with a non-zero result\n            methodItems.add(new CommentMethodItem(\n                    String.format(\"AnalysisException: %s\", analysisException.getMessage()),\n                    analysisException.codeAddress, Integer.MIN_VALUE));\n            analysisException.printStackTrace(System.err);\n        }\n\n        List<AnalyzedInstruction> instructions = methodAnalyzer.getAnalyzedInstructions();\n\n        int currentCodeAddress = 0;\n        for (int i = 0; i < instructions.size(); i++) {\n            AnalyzedInstruction instruction = instructions.get(i);\n\n            MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(\n                    this, currentCodeAddress, instruction.getInstruction());\n\n            methodItems.add(methodItem);\n\n            if (instruction.getInstruction().getOpcode().format == Format.UnresolvedOdexInstruction) {\n                methodItems.add(new CommentedOutMethodItem(\n                        InstructionMethodItemFactory.makeInstructionFormatMethodItem(\n                                this, currentCodeAddress, instruction.getOriginalInstruction())));\n            }\n\n            if (i != instructions.size() - 1) {\n                methodItems.add(new BlankMethodItem(currentCodeAddress));\n            }\n\n            if (classDef.options.codeOffsets) {\n                methodItems.add(new MethodItem(currentCodeAddress) {\n\n                    @Override\n                    public double getSortOrder() {\n                        return -1000;\n                    }\n\n                    @Override\n                    public boolean writeTo(IndentingWriter writer) throws IOException {\n                        writer.write(\"#@\");\n                        writer.printUnsignedLongAsHex(codeAddress & 0xFFFFFFFFL);\n                        return true;\n                    }\n                });\n            }\n\n            if (classDef.options.registerInfo != 0 &&\n                    !instruction.getInstruction().getOpcode().format.isPayloadFormat) {\n                methodItems.add(\n                        new PreInstructionRegisterInfoMethodItem(classDef.options.registerInfo,\n                                methodAnalyzer, registerFormatter, instruction, currentCodeAddress));\n\n                methodItems.add(\n                        new PostInstructionRegisterInfoMethodItem(registerFormatter, instruction, currentCodeAddress));\n            }\n\n            currentCodeAddress += instruction.getInstruction().getCodeUnits();\n        }\n    }\n\n    private void addTries(List<MethodItem> methodItems) {\n        List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks = methodImpl.getTryBlocks();\n        if (tryBlocks.size() == 0) {\n            return;\n        }\n\n        int lastInstructionAddress = instructionOffsetMap.getInstructionCodeOffset(instructions.size() - 1);\n        int codeSize = lastInstructionAddress + instructions.get(instructions.size() - 1).getCodeUnits();\n\n        for (TryBlock<? extends ExceptionHandler> tryBlock : tryBlocks) {\n            int startAddress = tryBlock.getStartCodeAddress();\n            int endAddress = startAddress + tryBlock.getCodeUnitCount();\n\n            if (startAddress >= codeSize) {\n                throw new RuntimeException(String.format(\"Try start offset %d is past the end of the code block.\",\n                        startAddress));\n            }\n            // Note: not >=. endAddress == codeSize is valid, when the try covers the last instruction\n            if (endAddress > codeSize) {\n                throw new RuntimeException(String.format(\"Try end offset %d is past the end of the code block.\",\n                        endAddress));\n            }\n\n            /**\n             * The end address points to the address immediately after the end of the last\n             * instruction that the try block covers. We want the .catch directive and end_try\n             * label to be associated with the last covered instruction, so we need to get\n             * the address for that instruction\n             */\n\n            int lastCoveredIndex = instructionOffsetMap.getInstructionIndexAtCodeOffset(endAddress - 1, false);\n            int lastCoveredAddress = instructionOffsetMap.getInstructionCodeOffset(lastCoveredIndex);\n\n            for (ExceptionHandler handler : tryBlock.getExceptionHandlers()) {\n                int handlerAddress = handler.getHandlerCodeAddress();\n                if (handlerAddress >= codeSize) {\n                    throw new ExceptionWithContext(\n                            \"Exception handler offset %d is past the end of the code block.\", handlerAddress);\n                }\n\n                //use the address from the last covered instruction\n                CatchMethodItem catchMethodItem = new CatchMethodItem(classDef.options, labelCache, lastCoveredAddress,\n                        handler.getExceptionType(), startAddress, endAddress, handlerAddress);\n                methodItems.add(catchMethodItem);\n            }\n        }\n    }\n\n    private void addDebugInfo(final List<MethodItem> methodItems) {\n        for (DebugItem debugItem : methodImpl.getDebugItems()) {\n            methodItems.add(DebugMethodItem.build(registerFormatter, debugItem));\n        }\n    }\n\n    private void setLabelSequentialNumbers() {\n        HashMap<String, Integer> nextLabelSequenceByType = new HashMap<String, Integer>();\n        ArrayList<LabelMethodItem> sortedLabels = new ArrayList<LabelMethodItem>(labelCache.getLabels());\n\n        //sort the labels by their location in the method\n        Collections.sort(sortedLabels);\n\n        for (LabelMethodItem labelMethodItem : sortedLabels) {\n            Integer labelSequence = nextLabelSequenceByType.get(labelMethodItem.getLabelPrefix());\n            if (labelSequence == null) {\n                labelSequence = 0;\n            }\n            labelMethodItem.setLabelSequence(labelSequence);\n            nextLabelSequenceByType.put(labelMethodItem.getLabelPrefix(), labelSequence + 1);\n        }\n    }\n\n    @Nullable\n    private String getContainingClassForImplicitReference() {\n        if (classDef.options.implicitReferences) {\n            return classDef.classDef.getType();\n        }\n        return null;\n    }\n\n    public static class LabelCache {\n        protected HashMap<LabelMethodItem, LabelMethodItem> labels = new HashMap<LabelMethodItem, LabelMethodItem>();\n\n        public LabelCache() {\n        }\n\n        public LabelMethodItem internLabel(LabelMethodItem labelMethodItem) {\n            LabelMethodItem internedLabelMethodItem = labels.get(labelMethodItem);\n            if (internedLabelMethodItem != null) {\n                return internedLabelMethodItem;\n            }\n            labels.put(labelMethodItem, labelMethodItem);\n            return labelMethodItem;\n        }\n\n\n        public Collection<LabelMethodItem> getLabels() {\n            return labels.values();\n        }\n    }\n\n    public static class InvalidSwitchPayload extends ExceptionWithContext {\n        private final int payloadOffset;\n\n        public InvalidSwitchPayload(int payloadOffset) {\n            super(\"No switch payload at offset: %d\", payloadOffset);\n            this.payloadOffset = payloadOffset;\n        }\n\n        public int getPayloadOffset() {\n            return payloadOffset;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/MethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\npublic abstract class MethodItem implements Comparable<MethodItem> {\n    protected final int codeAddress;\n\n    protected MethodItem(int codeAddress) {\n        this.codeAddress = codeAddress;\n    }\n\n    public int getCodeAddress() {\n        return codeAddress;\n    }\n\n    //return an arbitrary double that determines how this item will be sorted with others at the same address\n    public abstract double getSortOrder();\n\n    public int compareTo(MethodItem methodItem) {\n        int result = ((Integer) codeAddress).compareTo(methodItem.codeAddress);\n\n        if (result == 0){\n            return ((Double)getSortOrder()).compareTo(methodItem.getSortOrder());\n        }\n        return result;\n    }\n\n    public abstract boolean writeTo(IndentingWriter writer) throws IOException;\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/PostInstructionRegisterInfoMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.dexlib2.analysis.AnalyzedInstruction;\nimport org.jf.dexlib2.analysis.RegisterType;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\nimport java.util.BitSet;\n\nimport javax.annotation.Nonnull;\n\npublic class PostInstructionRegisterInfoMethodItem extends MethodItem {\n    @Nonnull private final RegisterFormatter registerFormatter;\n    @Nonnull private final AnalyzedInstruction analyzedInstruction;\n\n    public PostInstructionRegisterInfoMethodItem(@Nonnull RegisterFormatter registerFormatter,\n                                                 @Nonnull AnalyzedInstruction analyzedInstruction,\n                                                 int codeAddress) {\n        super(codeAddress);\n        this.registerFormatter = registerFormatter;\n        this.analyzedInstruction = analyzedInstruction;\n    }\n\n    @Override\n    public double getSortOrder() {\n        return 100.1;\n    }\n\n    @Override\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        int registerInfo = registerFormatter.options.registerInfo;\n        int registerCount = analyzedInstruction.getRegisterCount();\n        BitSet registers = new BitSet(registerCount);\n\n        if ((registerInfo & BaksmaliOptions.ALL) != 0) {\n            registers.set(0, registerCount);\n        } else {\n            if ((registerInfo & BaksmaliOptions.ALLPOST) != 0) {\n                registers.set(0, registerCount);\n            } else if ((registerInfo & BaksmaliOptions.DEST) != 0) {\n                addDestRegs(registers, registerCount);\n            }\n        }\n\n        return writeRegisterInfo(writer, registers);\n    }\n\n    private void addDestRegs(BitSet printPostRegister, int registerCount) {\n        for (int registerNum=0; registerNum<registerCount; registerNum++) {\n            if (!analyzedInstruction.getPreInstructionRegisterType(registerNum).equals(\n                    analyzedInstruction.getPostInstructionRegisterType(registerNum))) {\n                printPostRegister.set(registerNum);\n            }\n        }\n    }\n\n    private boolean writeRegisterInfo(IndentingWriter writer, BitSet registers) throws IOException {\n        int registerNum = registers.nextSetBit(0);\n        if (registerNum < 0) {\n            return false;\n        }\n\n        writer.write('#');\n        for (; registerNum >= 0; registerNum = registers.nextSetBit(registerNum + 1)) {\n            RegisterType registerType = analyzedInstruction.getPostInstructionRegisterType(registerNum);\n\n            registerFormatter.writeTo(writer, registerNum);\n            writer.write('=');\n            registerType.writeTo(writer);\n            writer.write(';');\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/PreInstructionRegisterInfoMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.dexlib2.analysis.AnalyzedInstruction;\nimport org.jf.dexlib2.analysis.MethodAnalyzer;\nimport org.jf.dexlib2.analysis.RegisterType;\nimport org.jf.dexlib2.iface.instruction.FiveRegisterInstruction;\nimport org.jf.dexlib2.iface.instruction.OneRegisterInstruction;\nimport org.jf.dexlib2.iface.instruction.RegisterRangeInstruction;\nimport org.jf.dexlib2.iface.instruction.ThreeRegisterInstruction;\nimport org.jf.dexlib2.iface.instruction.TwoRegisterInstruction;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\nimport java.util.BitSet;\n\nimport javax.annotation.Nonnull;\n\npublic class PreInstructionRegisterInfoMethodItem extends MethodItem {\n    private final int registerInfo;\n    @Nonnull private final MethodAnalyzer methodAnalyzer;\n    @Nonnull private final RegisterFormatter registerFormatter;\n    @Nonnull private final AnalyzedInstruction analyzedInstruction;\n\n    public PreInstructionRegisterInfoMethodItem(int registerInfo,\n                                                @Nonnull MethodAnalyzer methodAnalyzer,\n                                                @Nonnull RegisterFormatter registerFormatter,\n                                                @Nonnull AnalyzedInstruction analyzedInstruction,\n                                                int codeAddress) {\n        super(codeAddress);\n        this.registerInfo = registerInfo;\n        this.methodAnalyzer = methodAnalyzer;\n        this.registerFormatter = registerFormatter;\n        this.analyzedInstruction = analyzedInstruction;\n    }\n\n    @Override\n    public double getSortOrder() {\n        return 99.9;\n    }\n\n    @Override\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        int registerCount = analyzedInstruction.getRegisterCount();\n        BitSet registers = new BitSet(registerCount);\n        BitSet mergeRegisters = null;\n\n        if ((registerInfo & BaksmaliOptions.ALL) != 0) {\n            registers.set(0, registerCount);\n        } else {\n            if ((registerInfo & BaksmaliOptions.ALLPRE) != 0) {\n                registers.set(0, registerCount);\n            } else {\n                if ((registerInfo & BaksmaliOptions.ARGS) != 0) {\n                    addArgsRegs(registers);\n                }\n                if ((registerInfo & BaksmaliOptions.MERGE) != 0) {\n                    if (analyzedInstruction.isBeginningInstruction()) {\n                        addParamRegs(registers, registerCount);\n                    }\n                    mergeRegisters = new BitSet(registerCount);\n                    addMergeRegs(mergeRegisters, registerCount);\n                } else if ((registerInfo & BaksmaliOptions.FULLMERGE) != 0 &&\n                        (analyzedInstruction.isBeginningInstruction())) {\n                    addParamRegs(registers, registerCount);\n                }\n            }\n        }\n\n        if ((registerInfo & BaksmaliOptions.FULLMERGE) != 0) {\n            if (mergeRegisters == null) {\n                mergeRegisters = new BitSet(registerCount);\n                addMergeRegs(mergeRegisters, registerCount);\n            }\n            registers.or(mergeRegisters);\n        } else if (mergeRegisters != null) {\n            registers.or(mergeRegisters);\n            mergeRegisters = null;\n        }\n\n        return writeRegisterInfo(writer, registers, mergeRegisters);\n    }\n\n    private void addArgsRegs(BitSet registers) {\n        if (analyzedInstruction.getInstruction() instanceof RegisterRangeInstruction) {\n            RegisterRangeInstruction instruction = (RegisterRangeInstruction)analyzedInstruction.getInstruction();\n\n            registers.set(instruction.getStartRegister(),\n                    instruction.getStartRegister() + instruction.getRegisterCount());\n        } else if (analyzedInstruction.getInstruction() instanceof FiveRegisterInstruction) {\n            FiveRegisterInstruction instruction = (FiveRegisterInstruction)analyzedInstruction.getInstruction();\n            int regCount = instruction.getRegisterCount();\n            switch (regCount) {\n                case 5:\n                    registers.set(instruction.getRegisterG());\n                    //fall through\n                case 4:\n                    registers.set(instruction.getRegisterF());\n                    //fall through\n                case 3:\n                    registers.set(instruction.getRegisterE());\n                    //fall through\n                case 2:\n                    registers.set(instruction.getRegisterD());\n                    //fall through\n                case 1:\n                    registers.set(instruction.getRegisterC());\n            }\n        } else if (analyzedInstruction.getInstruction() instanceof ThreeRegisterInstruction) {\n            ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.getInstruction();\n            registers.set(instruction.getRegisterA());\n            registers.set(instruction.getRegisterB());\n            registers.set(instruction.getRegisterC());\n        } else if (analyzedInstruction.getInstruction() instanceof TwoRegisterInstruction) {\n            TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.getInstruction();\n            registers.set(instruction.getRegisterA());\n            registers.set(instruction.getRegisterB());\n        } else if (analyzedInstruction.getInstruction() instanceof OneRegisterInstruction) {\n            OneRegisterInstruction instruction = (OneRegisterInstruction)analyzedInstruction.getInstruction();\n            registers.set(instruction.getRegisterA());\n        }\n    }\n\n    private void addMergeRegs(BitSet registers, int registerCount) {\n        if (analyzedInstruction.getPredecessorCount() <= 1) {\n            //in the common case of an instruction that only has a single predecessor which is the previous\n            //instruction, the pre-instruction registers will always match the previous instruction's\n            //post-instruction registers\n            return;\n        }\n\n        for (int registerNum=0; registerNum<registerCount; registerNum++) {\n            RegisterType mergedRegisterType = analyzedInstruction.getPreInstructionRegisterType(registerNum);\n\n            for (AnalyzedInstruction predecessor: analyzedInstruction.getPredecessors()) {\n                RegisterType predecessorRegisterType = predecessor.getPostInstructionRegisterType(registerNum);\n                if (predecessorRegisterType.category != RegisterType.UNKNOWN &&\n                        !predecessorRegisterType.equals(mergedRegisterType)) {\n                    registers.set(registerNum);\n                }\n            }\n        }\n    }\n\n    private void addParamRegs(BitSet registers, int registerCount) {\n        int parameterRegisterCount = methodAnalyzer.getParamRegisterCount();\n        registers.set(registerCount-parameterRegisterCount, registerCount);\n    }\n\n    private void writeFullMerge(IndentingWriter writer, int registerNum) throws IOException {\n        registerFormatter.writeTo(writer, registerNum);\n        writer.write('=');\n        analyzedInstruction.getPreInstructionRegisterType(registerNum).writeTo(writer);\n        writer.write(\":merge{\");\n\n        boolean first = true;\n\n        for (AnalyzedInstruction predecessor: analyzedInstruction.getPredecessors()) {\n            RegisterType predecessorRegisterType = predecessor.getPostInstructionRegisterType(registerNum);\n\n            if (!first) {\n                writer.write(',');\n            }\n\n            if (predecessor.getInstructionIndex() == -1) {\n                //the fake \"StartOfMethod\" instruction\n                writer.write(\"Start:\");\n            } else {\n                writer.write(\"0x\");\n                writer.printUnsignedLongAsHex(methodAnalyzer.getInstructionAddress(predecessor));\n                writer.write(':');\n            }\n            predecessorRegisterType.writeTo(writer);\n\n            first = false;\n        }\n        writer.write('}');\n    }\n\n    private boolean writeRegisterInfo(IndentingWriter writer, BitSet registers,\n                                      BitSet fullMergeRegisters) throws IOException {\n        boolean firstRegister = true;\n        boolean previousWasFullMerge = false;\n        int registerNum = registers.nextSetBit(0);\n        if (registerNum < 0) {\n            return false;\n        }\n\n        writer.write('#');\n        for (; registerNum >= 0; registerNum = registers.nextSetBit(registerNum + 1)) {\n            boolean fullMerge = fullMergeRegisters!=null && fullMergeRegisters.get(registerNum);\n            if (fullMerge) {\n                if (!firstRegister) {\n                    writer.write('\\n');\n                    writer.write('#');\n                }\n                writeFullMerge(writer, registerNum);\n                previousWasFullMerge = true;\n            } else {\n                if (previousWasFullMerge) {\n                    writer.write('\\n');\n                    writer.write('#');\n                    previousWasFullMerge = false;\n                }\n\n                RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(registerNum);\n\n                registerFormatter.writeTo(writer, registerNum);\n                writer.write('=');\n\n                registerType.writeTo(writer);\n                writer.write(';');\n            }\n\n            firstRegister = false;\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/ReferenceFormatter.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport com.taobao.android.baksmali.util.ReferenceUtil;\nimport org.jf.dexlib2.ReferenceType;\nimport org.jf.dexlib2.iface.reference.FieldReference;\nimport org.jf.dexlib2.iface.reference.MethodReference;\nimport org.jf.dexlib2.iface.reference.Reference;\nimport org.jf.dexlib2.iface.reference.StringReference;\nimport org.jf.dexlib2.iface.reference.TypeReference;\nimport org.jf.util.IndentingWriter;\nimport org.jf.util.StringUtils;\n\nimport java.io.IOException;\n\npublic class ReferenceFormatter {\n    public static void writeStringReference(IndentingWriter writer, String item) throws IOException {\n        writer.write('\"');\n        StringUtils.writeEscapedString(writer, item);\n        writer.write('\"');\n    }\n\n    public static void writeReference(IndentingWriter writer, int referenceType,\n                                      Reference reference) throws IOException {\n        switch (referenceType) {\n            case ReferenceType.STRING:\n                writeStringReference(writer, ((StringReference)reference).getString());\n                return;\n            case ReferenceType.TYPE:\n                writer.write(((TypeReference)reference).getType());\n                return;\n            case ReferenceType.METHOD:\n                ReferenceUtil.writeMethodDescriptor(writer, (MethodReference) reference);\n                return;\n            case ReferenceType.FIELD:\n                ReferenceUtil.writeFieldDescriptor(writer, (FieldReference)reference);\n                return;\n            default:\n                throw new IllegalStateException(\"Unknown reference type\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/RegisterFormatter.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2010 Ben Gruver (JesusFreke)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\nimport javax.annotation.Nonnull;\n\n/**\n * This class contains the logic used for formatting registers\n */\npublic class RegisterFormatter {\n    @Nonnull public final BaksmaliOptions options;\n    public final int registerCount;\n    public final int parameterRegisterCount;\n\n    public RegisterFormatter(@Nonnull BaksmaliOptions options, int registerCount, int parameterRegisterCount) {\n        this.options = options;\n        this.registerCount = registerCount;\n        this.parameterRegisterCount = parameterRegisterCount;\n    }\n\n    /**\n     * Write out the register range value used by Format3rc. If baksmali.noParameterRegisters is true, it will always\n     * output the registers in the v<n> format. But if false, then it will check if *both* registers are parameter\n     * registers, and if so, use the p<n> format for both. If only the last register is a parameter register, it will\n     * use the v<n> format for both, otherwise it would be confusing to have something like {v20 .. p1}\n     * @param writer the <code>IndentingWriter</code> to write to\n     * @param startRegister the first register in the range\n     * @param lastRegister the last register in the range\n     */\n    public void writeRegisterRange(IndentingWriter writer, int startRegister, int lastRegister) throws IOException {\n        if (!options.parameterRegisters) {\n            assert startRegister <= lastRegister;\n\n            if (startRegister >= registerCount - parameterRegisterCount) {\n                writer.write(\"{p\");\n                writer.printSignedIntAsDec(startRegister - (registerCount - parameterRegisterCount));\n                writer.write(\" .. p\");\n                writer.printSignedIntAsDec(lastRegister - (registerCount - parameterRegisterCount));\n                writer.write('}');\n                return;\n            }\n        }\n        writer.write(\"{v\");\n        writer.printSignedIntAsDec(startRegister);\n        writer.write(\" .. v\");\n        writer.printSignedIntAsDec(lastRegister);\n        writer.write('}');\n    }\n\n    /**\n     * Writes a register with the appropriate format. If baksmali.noParameterRegisters is true, then it will always\n     * output a register in the v<n> format. If false, then it determines if the register is a parameter register,\n     * and if so, formats it in the p<n> format instead.\n     *\n     * @param writer the <code>IndentingWriter</code> to write to\n     * @param register the register number\n     */\n    public void writeTo(IndentingWriter writer, int register) throws IOException {\n        if (!options.parameterRegisters) {\n            if (register >= registerCount - parameterRegisterCount) {\n                writer.write('p');\n                writer.printSignedIntAsDec((register - (registerCount - parameterRegisterCount)));\n                return;\n            }\n        }\n        writer.write('v');\n        writer.printSignedIntAsDec(register);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/adaptors/SyntheticAccessCommentMethodItem.java",
    "content": "/*\n * [The \"BSD licence\"]\n * Copyright (c) 2011 Ben Gruver\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\npackage com.taobao.android.baksmali.adaptors;\n\nimport org.jf.dexlib2.ReferenceType;\nimport org.jf.dexlib2.util.SyntheticAccessorResolver;\nimport org.jf.util.ExceptionWithContext;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\n\npublic class SyntheticAccessCommentMethodItem extends MethodItem {\n    private final SyntheticAccessorResolver.AccessedMember accessedMember;\n\n    public SyntheticAccessCommentMethodItem(SyntheticAccessorResolver.AccessedMember accessedMember, int codeAddress) {\n        super(codeAddress);\n        this.accessedMember = accessedMember;\n    }\n\n    public double getSortOrder() {\n        //just before the pre-instruction register information, if any\n        return 99.8;\n    }\n\n    public boolean writeTo(IndentingWriter writer) throws IOException {\n        writer.write(\"# \");\n        switch (accessedMember.accessedMemberType) {\n            case SyntheticAccessorResolver.METHOD:\n                writer.write(\"invokes: \");\n                break;\n            case SyntheticAccessorResolver.GETTER:\n                writer.write(\"getter for: \");\n                break;\n            case SyntheticAccessorResolver.SETTER:\n                writer.write(\"setter for: \");\n                break;\n            case SyntheticAccessorResolver.PREFIX_INCREMENT:\n                writer.write(\"++operator for: \");\n                break;\n            case SyntheticAccessorResolver.POSTFIX_INCREMENT:\n                writer.write(\"operator++ for: \");\n                break;\n            case SyntheticAccessorResolver.PREFIX_DECREMENT:\n                writer.write(\"--operator for: \");\n                break;\n            case SyntheticAccessorResolver.POSTFIX_DECREMENT:\n                writer.write(\"operator-- for: \");\n                break;\n            case SyntheticAccessorResolver.ADD_ASSIGNMENT:\n                writer.write(\"+= operator for: \");\n                break;\n            case SyntheticAccessorResolver.SUB_ASSIGNMENT:\n                writer.write(\"-= operator for: \");\n                break;\n            case SyntheticAccessorResolver.MUL_ASSIGNMENT:\n                writer.write(\"*= operator for: \");\n                break;\n            case SyntheticAccessorResolver.DIV_ASSIGNMENT:\n                writer.write(\"/= operator for: \");\n                break;\n            case SyntheticAccessorResolver.REM_ASSIGNMENT:\n                writer.write(\"%= operator for: \");\n                break;\n            case SyntheticAccessorResolver.AND_ASSIGNMENT:\n                writer.write(\"&= operator for: \");\n                break;\n            case SyntheticAccessorResolver.OR_ASSIGNMENT:\n                writer.write(\"|= operator for: \");\n                break;\n            case SyntheticAccessorResolver.XOR_ASSIGNMENT:\n                writer.write(\"^= operator for: \");\n                break;\n            case SyntheticAccessorResolver.SHL_ASSIGNMENT:\n                writer.write(\"<<= operator for: \");\n                break;\n            case SyntheticAccessorResolver.SHR_ASSIGNMENT:\n                writer.write(\">>= operator for: \");\n                break;\n            case SyntheticAccessorResolver.USHR_ASSIGNMENT:\n                writer.write(\">>>= operator for: \");\n                break;\n            default:\n                throw new ExceptionWithContext(\"Unknown access type: %d\", accessedMember.accessedMemberType);\n        }\n\n        int referenceType;\n        if (accessedMember.accessedMemberType == SyntheticAccessorResolver.METHOD) {\n            referenceType = ReferenceType.METHOD;\n        } else {\n            referenceType = ReferenceType.FIELD;\n        }\n        ReferenceFormatter.writeReference(writer, referenceType, accessedMember.accessedMember);\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/baksmali/util/ReferenceUtil.java",
    "content": "package com.taobao.android.baksmali.util;\n\nimport com.taobao.android.apatch.utils.TypeGenUtil;\nimport com.taobao.android.object.DexDiffInfo;\n\nimport org.jf.dexlib2.dexbacked.DexBackedClassDef;\nimport org.jf.dexlib2.dexbacked.DexBackedField;\nimport org.jf.dexlib2.iface.reference.FieldReference;\nimport org.jf.dexlib2.iface.reference.MethodReference;\nimport org.jf.dexlib2.iface.reference.Reference;\nimport org.jf.dexlib2.iface.reference.StringReference;\nimport org.jf.dexlib2.iface.reference.TypeReference;\nimport org.jf.util.StringUtils;\n\nimport java.io.IOException;\nimport java.io.Writer;\n\nimport javax.annotation.Nonnull;\nimport javax.annotation.Nullable;\n\n;\n;\n\n/**\n * Created by shenghua.nish on 2016-03-18 下午9:32.\n */\npublic class ReferenceUtil {\n    public static String getMethodDescriptor(MethodReference methodReference) {\n        return getMethodDescriptor(methodReference, false);\n    }\n\n    public static String getMethodDescriptor(MethodReference methodReference, boolean useImplicitReference) {\n        StringBuilder sb = new StringBuilder();\n        if (!useImplicitReference) {\n            String clazz = methodReference.getDefiningClass();//TypeGenUtil.newType(methodReference.getDefiningClass());\n            sb.append(clazz);\n            sb.append(\"->\");\n        }\n        sb.append(methodReference.getName());\n        sb.append('(');\n        for (CharSequence paramType : methodReference.getParameterTypes()) {\n            sb.append(paramType);\n        }\n        sb.append(')');\n        sb.append(methodReference.getReturnType());\n        return sb.toString();\n    }\n\n    public static void writeMethodDescriptor(Writer writer, MethodReference methodReference) throws IOException {\n        writeMethodDescriptor(writer, methodReference, false);\n    }\n\n    public static void writeMethodDescriptor(Writer writer, MethodReference methodReference,\n                                             boolean useImplicitReference) throws IOException {\n        if (!useImplicitReference) {\n            String clazz = TypeGenUtil.newType(methodReference.getDefiningClass());\n            writer.write(clazz);\n            writer.write(\"->\");\n        }\n        writer.write(methodReference.getName());\n        writer.write('(');\n        for (CharSequence paramType : methodReference.getParameterTypes()) {\n            writer.write(paramType.toString());\n        }\n        writer.write(')');\n        writer.write(methodReference.getReturnType());\n    }\n\n    public static String getFieldDescriptor(FieldReference fieldReference) {\n        return getFieldDescriptor(fieldReference, false);\n    }\n\n    public static String getFieldDescriptor(FieldReference fieldReference, boolean useImplicitReference) {\n        StringBuilder sb = new StringBuilder();\n        if (!useImplicitReference) {\n            String clazz = fieldReference.getDefiningClass();\n            if (DexDiffInfo.getModifiedClasses(clazz) != null) {\n                if (isStaticFiled(DexDiffInfo.getModifiedClasses(clazz), fieldReference)) {//静态变量要访问以前的\n                } else {\n                    //\t\tclazz = TypeGenUtil.newType(clazz);\n                }\n            }\n            sb.append(clazz);\n            sb.append(\"->\");\n        }\n        sb.append(fieldReference.getName());\n        sb.append(':');\n\n        String clazz = fieldReference.getType();//TypeGenUtil.newType(fieldReference.getType());\n        sb.append(clazz);\n        return sb.toString();\n    }\n\n    public static String getShortFieldDescriptor(FieldReference fieldReference) {\n        StringBuilder sb = new StringBuilder();\n        sb.append(fieldReference.getName());\n        sb.append(':');\n        String clazz = TypeGenUtil.newType(fieldReference.getType());\n        sb.append(clazz);\n        return sb.toString();\n    }\n\n    public static void writeFieldDescriptor(Writer writer, FieldReference fieldReference) throws IOException {\n        writeFieldDescriptor(writer, fieldReference, false);\n    }\n\n    public static void writeFieldDescriptor(Writer writer, FieldReference fieldReference,\n                                            boolean implicitReference) throws IOException {\n        if (!implicitReference) {\n            String clazz = fieldReference.getDefiningClass();\n            if (DexDiffInfo.getModifiedClasses(clazz) != null) {\n                if (isStaticFiled(DexDiffInfo.getModifiedClasses(clazz), fieldReference)) {//静态变量要访问以前的\n                } else {\n                    clazz = TypeGenUtil.newType(clazz);\n                }\n            }\n            writer.write(clazz);\n            writer.write(\"->\");\n        }\n        writer.write(fieldReference.getName());\n        writer.write(':');\n        writer.write(fieldReference.getType());\n    }\n\n    @Nullable\n    public static String getReferenceString(@Nonnull Reference reference) {\n        return getReferenceString(reference, null);\n    }\n\n    @Nullable\n    public static String getReferenceString(@Nonnull Reference reference, @Nullable String containingClass) {\n        if (reference instanceof StringReference) {\n            return String.format(\"\\\"%s\\\"\", StringUtils.escapeString(((StringReference) reference).getString()));\n        }\n        if (reference instanceof TypeReference) {\n            String clazz = ((TypeReference) reference).getType(); //TypeGenUtil.newType(((TypeReference)reference).getType());\n            return clazz;\n        }\n        if (reference instanceof FieldReference) {\n            FieldReference fieldReference = (FieldReference) reference;\n            boolean useImplicitReference = fieldReference.getDefiningClass().equals(containingClass);\n            return getFieldDescriptor((FieldReference) reference, useImplicitReference);\n        }\n        if (reference instanceof MethodReference) {\n            MethodReference methodReference = (MethodReference) reference;\n            boolean useImplicitReference = methodReference.getDefiningClass().equals(containingClass);\n            return getMethodDescriptor((MethodReference) reference, useImplicitReference);\n        }\n        return null;\n    }\n\n    private static boolean isStaticFiled(DexBackedClassDef classDef, FieldReference reference) {\n        for (DexBackedField field : classDef.getStaticFields()) {\n            if (field.equals(reference)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private ReferenceUtil() {\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/Annotation.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\nimport static com.taobao.android.dex.EncodedValueReader.ENCODED_ANNOTATION;\n\n/**\n * An annotation.\n */\npublic final class Annotation implements Comparable<Annotation> {\n    private final Dex dex;\n    private final byte visibility;\n    private final EncodedValue encodedAnnotation;\n\n    public Annotation(Dex dex, byte visibility, EncodedValue encodedAnnotation) {\n        this.dex = dex;\n        this.visibility = visibility;\n        this.encodedAnnotation = encodedAnnotation;\n    }\n\n    public byte getVisibility() {\n        return visibility;\n    }\n\n    public EncodedValueReader getReader() {\n        return new EncodedValueReader(encodedAnnotation, ENCODED_ANNOTATION);\n    }\n\n    public int getTypeIndex() {\n        EncodedValueReader reader = getReader();\n        reader.readAnnotation();\n        return reader.getAnnotationType();\n    }\n\n    public void writeTo(Dex.Section out) {\n        out.writeByte(visibility);\n        encodedAnnotation.writeTo(out);\n    }\n\n    @Override public int compareTo(Annotation other) {\n        return encodedAnnotation.compareTo(other.encodedAnnotation);\n    }\n\n    @Override public String toString() {\n        return dex == null\n                ? visibility + \" \" + getTypeIndex()\n                : visibility + \" \" + dex.typeNames().get(getTypeIndex());\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/ClassData.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\npublic final class ClassData {\n    private final Field[] staticFields;\n    private final Field[] instanceFields;\n    private final Method[] directMethods;\n    private final Method[] virtualMethods;\n\n    public ClassData(Field[] staticFields, Field[] instanceFields,\n            Method[] directMethods, Method[] virtualMethods) {\n        this.staticFields = staticFields;\n        this.instanceFields = instanceFields;\n        this.directMethods = directMethods;\n        this.virtualMethods = virtualMethods;\n    }\n\n    public Field[] getStaticFields() {\n        return staticFields;\n    }\n\n    public Field[] getInstanceFields() {\n        return instanceFields;\n    }\n\n    public Method[] getDirectMethods() {\n        return directMethods;\n    }\n\n    public Method[] getVirtualMethods() {\n        return virtualMethods;\n    }\n\n    public Field[] allFields() {\n        Field[] result = new Field[staticFields.length + instanceFields.length];\n        System.arraycopy(staticFields, 0, result, 0, staticFields.length);\n        System.arraycopy(instanceFields, 0, result, staticFields.length, instanceFields.length);\n        return result;\n    }\n\n    public Method[] allMethods() {\n        Method[] result = new Method[directMethods.length + virtualMethods.length];\n        System.arraycopy(directMethods, 0, result, 0, directMethods.length);\n        System.arraycopy(virtualMethods, 0, result, directMethods.length, virtualMethods.length);\n        return result;\n    }\n\n    public static class Field {\n        private final int fieldIndex;\n        private final int accessFlags;\n\n        public Field(int fieldIndex, int accessFlags) {\n            this.fieldIndex = fieldIndex;\n            this.accessFlags = accessFlags;\n        }\n\n        public int getFieldIndex() {\n            return fieldIndex;\n        }\n\n        public int getAccessFlags() {\n            return accessFlags;\n        }\n    }\n\n    public static class Method {\n        private final int methodIndex;\n        private final int accessFlags;\n        private final int codeOffset;\n\n        public Method(int methodIndex, int accessFlags, int codeOffset) {\n            this.methodIndex = methodIndex;\n            this.accessFlags = accessFlags;\n            this.codeOffset = codeOffset;\n        }\n\n        public int getMethodIndex() {\n            return methodIndex;\n        }\n\n        public int getAccessFlags() {\n            return accessFlags;\n        }\n\n        public int getCodeOffset() {\n            return codeOffset;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/ClassDef.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\n/**\n * A type definition.\n */\npublic final class ClassDef {\n    public static final int NO_INDEX = -1;\n    private final Dex buffer;\n    private final int offset;\n    private final int typeIndex;\n    private final int accessFlags;\n    private final int supertypeIndex;\n    private final int interfacesOffset;\n    private final int sourceFileIndex;\n    private final int annotationsOffset;\n    private final int classDataOffset;\n    private final int staticValuesOffset;\n\n    public ClassDef(Dex buffer, int offset, int typeIndex, int accessFlags,\n            int supertypeIndex, int interfacesOffset, int sourceFileIndex,\n            int annotationsOffset, int classDataOffset, int staticValuesOffset) {\n        this.buffer = buffer;\n        this.offset = offset;\n        this.typeIndex = typeIndex;\n        this.accessFlags = accessFlags;\n        this.supertypeIndex = supertypeIndex;\n        this.interfacesOffset = interfacesOffset;\n        this.sourceFileIndex = sourceFileIndex;\n        this.annotationsOffset = annotationsOffset;\n        this.classDataOffset = classDataOffset;\n        this.staticValuesOffset = staticValuesOffset;\n    }\n\n    public int getOffset() {\n        return offset;\n    }\n\n    public int getTypeIndex() {\n        return typeIndex;\n    }\n\n    public int getSupertypeIndex() {\n        return supertypeIndex;\n    }\n\n    public int getInterfacesOffset() {\n        return interfacesOffset;\n    }\n\n    public short[] getInterfaces() {\n        return buffer.readTypeList(interfacesOffset).getTypes();\n    }\n\n    public int getAccessFlags() {\n        return accessFlags;\n    }\n\n    public int getSourceFileIndex() {\n        return sourceFileIndex;\n    }\n\n    public int getAnnotationsOffset() {\n        return annotationsOffset;\n    }\n\n    public int getClassDataOffset() {\n        return classDataOffset;\n    }\n\n    public int getStaticValuesOffset() {\n        return staticValuesOffset;\n    }\n\n    @Override public String toString() {\n        if (buffer == null) {\n            return typeIndex + \" \" + supertypeIndex;\n        }\n\n        StringBuilder result = new StringBuilder();\n        result.append(buffer.typeNames().get(typeIndex));\n        if (supertypeIndex != NO_INDEX) {\n            result.append(\" extends \").append(buffer.typeNames().get(supertypeIndex));\n        }\n        return result.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/Code.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\npublic final class Code {\n    private final int registersSize;\n    private final int insSize;\n    private final int outsSize;\n    private final int debugInfoOffset;\n    private final short[] instructions;\n    private final Try[] tries;\n    private final CatchHandler[] catchHandlers;\n\n    public Code(int registersSize, int insSize, int outsSize, int debugInfoOffset,\n            short[] instructions, Try[] tries, CatchHandler[] catchHandlers) {\n        this.registersSize = registersSize;\n        this.insSize = insSize;\n        this.outsSize = outsSize;\n        this.debugInfoOffset = debugInfoOffset;\n        this.instructions = instructions;\n        this.tries = tries;\n        this.catchHandlers = catchHandlers;\n    }\n\n    public int getRegistersSize() {\n        return registersSize;\n    }\n\n    public int getInsSize() {\n        return insSize;\n    }\n\n    public int getOutsSize() {\n        return outsSize;\n    }\n\n    public int getDebugInfoOffset() {\n        return debugInfoOffset;\n    }\n\n    public short[] getInstructions() {\n        return instructions;\n    }\n\n    public Try[] getTries() {\n        return tries;\n    }\n\n    public CatchHandler[] getCatchHandlers() {\n        return catchHandlers;\n    }\n\n    public static class Try {\n        final int startAddress;\n        final int instructionCount;\n        final int catchHandlerIndex;\n\n        Try(int startAddress, int instructionCount, int catchHandlerIndex) {\n            this.startAddress = startAddress;\n            this.instructionCount = instructionCount;\n            this.catchHandlerIndex = catchHandlerIndex;\n        }\n\n        public int getStartAddress() {\n            return startAddress;\n        }\n\n        public int getInstructionCount() {\n            return instructionCount;\n        }\n\n        /**\n         * Returns this try's catch handler <strong>index</strong>. Note that\n         * this is distinct from the its catch handler <strong>offset</strong>.\n         */\n        public int getCatchHandlerIndex() {\n            return catchHandlerIndex;\n        }\n    }\n\n    public static class CatchHandler {\n        final int[] typeIndexes;\n        final int[] addresses;\n        final int catchAllAddress;\n        final int offset;\n\n        public CatchHandler(int[] typeIndexes, int[] addresses, int catchAllAddress, int offset) {\n            this.typeIndexes = typeIndexes;\n            this.addresses = addresses;\n            this.catchAllAddress = catchAllAddress;\n            this.offset = offset;\n        }\n\n        public int[] getTypeIndexes() {\n            return typeIndexes;\n        }\n\n        public int[] getAddresses() {\n            return addresses;\n        }\n\n        public int getCatchAllAddress() {\n            return catchAllAddress;\n        }\n\n        public int getOffset() {\n            return offset;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/Dex.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\nimport com.taobao.android.dex.Code.CatchHandler;\nimport com.taobao.android.dex.Code.Try;\nimport com.taobao.android.dex.util.ByteInput;\nimport com.taobao.android.dex.util.ByteOutput;\nimport com.taobao.android.dex.util.FileUtils;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.io.UTFDataFormatException;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\nimport java.util.AbstractList;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.NoSuchElementException;\nimport java.util.RandomAccess;\nimport java.util.zip.Adler32;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n/**\n * The bytes of a dex file in memory for reading and writing. All int offsets\n * are unsigned.\n */\npublic final class Dex {\n    private static final int CHECKSUM_OFFSET = 8;\n    private static final int CHECKSUM_SIZE = 4;\n    private static final int SIGNATURE_OFFSET = CHECKSUM_OFFSET + CHECKSUM_SIZE;\n    private static final int SIGNATURE_SIZE = 20;\n    // Provided as a convenience to avoid a memory allocation to benefit Dalvik.\n    // Note: libcore.util.EmptyArray cannot be accessed when this code isn't run on Dalvik.\n    static final short[] EMPTY_SHORT_ARRAY = new short[0];\n\n    private ByteBuffer data;\n    private final TableOfContents tableOfContents = new TableOfContents();\n    private int nextSectionStart = 0;\n    private final StringTable strings = new StringTable();\n    private final TypeIndexToDescriptorIndexTable typeIds = new TypeIndexToDescriptorIndexTable();\n    private final TypeIndexToDescriptorTable typeNames = new TypeIndexToDescriptorTable();\n    private final ProtoIdTable protoIds = new ProtoIdTable();\n    private final FieldIdTable fieldIds = new FieldIdTable();\n    private final MethodIdTable methodIds = new MethodIdTable();\n\n    /**\n     * Creates a new dex that reads from {@code data}. It is an error to modify\n     * {@code data} after using it to create a dex buffer.\n     */\n    public Dex(byte[] data) throws IOException {\n        this(ByteBuffer.wrap(data));\n    }\n\n    private Dex(ByteBuffer data) throws IOException {\n        this.data = data;\n        this.data.order(ByteOrder.LITTLE_ENDIAN);\n        this.tableOfContents.readFrom(this);\n    }\n\n    /**\n     * Creates a new empty dex of the specified size.\n     */\n    public Dex(int byteCount) throws IOException {\n        this.data = ByteBuffer.wrap(new byte[byteCount]);\n        this.data.order(ByteOrder.LITTLE_ENDIAN);\n    }\n\n    /**\n     * Creates a new dex buffer of the dex in {@code in}, and closes {@code in}.\n     */\n    public Dex(InputStream in) throws IOException {\n        loadFrom(in);\n    }\n\n    /**\n     * Creates a new dex buffer from the dex file {@code file}.\n     */\n    public Dex(File file) throws IOException {\n        if (FileUtils.hasArchiveSuffix(file.getName())) {\n            ZipFile zipFile = new ZipFile(file);\n            ZipEntry entry = zipFile.getEntry(DexFormat.DEX_IN_JAR_NAME);\n            if (entry != null) {\n                loadFrom(zipFile.getInputStream(entry));\n                zipFile.close();\n            } else {\n                throw new DexException(\"Expected \" + DexFormat.DEX_IN_JAR_NAME + \" in \" + file);\n            }\n        } else if (file.getName().endsWith(\".dex\")) {\n            loadFrom(new FileInputStream(file));\n        } else {\n            throw new DexException(\"unknown output extension: \" + file);\n        }\n    }\n\n    /**\n     * Creates a new dex from the contents of {@code bytes}. This API supports\n     * both {@code .dex} and {@code .odex} input. Calling this constructor\n     * transfers ownership of {@code bytes} to the returned Dex: it is an error\n     * to access the buffer after calling this method.\n     */\n    public static Dex create(ByteBuffer data) throws IOException {\n        data.order(ByteOrder.LITTLE_ENDIAN);\n\n        // if it's an .odex file, set position and limit to the .dex section\n        if (data.get(0) == 'd'\n                && data.get(1) == 'e'\n                && data.get(2) == 'y'\n                && data.get(3) == '\\n') {\n            data.position(8);\n            int offset = data.getInt();\n            int length = data.getInt();\n            data.position(offset);\n            data.limit(offset + length);\n            data = data.slice();\n        }\n\n        return new Dex(data);\n    }\n\n    private void loadFrom(InputStream in) throws IOException {\n        ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();\n        byte[] buffer = new byte[8192];\n\n        int count;\n        while ((count = in.read(buffer)) != -1) {\n            bytesOut.write(buffer, 0, count);\n        }\n        in.close();\n\n        this.data = ByteBuffer.wrap(bytesOut.toByteArray());\n        this.data.order(ByteOrder.LITTLE_ENDIAN);\n        this.tableOfContents.readFrom(this);\n    }\n\n    private static void checkBounds(int index, int length) {\n        if (index < 0 || index >= length) {\n            throw new IndexOutOfBoundsException(\"index:\" + index + \", length=\" + length);\n        }\n    }\n\n    public void writeTo(OutputStream out) throws IOException {\n        byte[] buffer = new byte[8192];\n        ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe\n        data.clear();\n        while (data.hasRemaining()) {\n            int count = Math.min(buffer.length, data.remaining());\n            data.get(buffer, 0, count);\n            out.write(buffer, 0, count);\n        }\n    }\n\n    public void writeTo(File dexOut) throws IOException {\n        OutputStream out = new FileOutputStream(dexOut);\n        writeTo(out);\n        out.close();\n    }\n\n    public TableOfContents getTableOfContents() {\n        return tableOfContents;\n    }\n\n    public Section open(int position) {\n        if (position < 0 || position >= data.capacity()) {\n            throw new IllegalArgumentException(\"position=\" + position\n                    + \" length=\" + data.capacity());\n        }\n        ByteBuffer sectionData = data.duplicate();\n        sectionData.order(ByteOrder.LITTLE_ENDIAN); // necessary?\n        sectionData.position(position);\n        sectionData.limit(data.capacity());\n        return new Section(\"section\", sectionData);\n    }\n\n    public Section appendSection(int maxByteCount, String name) {\n        if ((maxByteCount & 3) != 0) {\n            throw new IllegalStateException(\"Not four byte aligned!\");\n        }\n        int limit = nextSectionStart + maxByteCount;\n        ByteBuffer sectionData = data.duplicate();\n        sectionData.order(ByteOrder.LITTLE_ENDIAN); // necessary?\n        sectionData.position(nextSectionStart);\n        sectionData.limit(limit);\n        Section result = new Section(name, sectionData);\n        nextSectionStart = limit;\n        return result;\n    }\n\n    public int getLength() {\n        return data.capacity();\n    }\n\n    public int getNextSectionStart() {\n        return nextSectionStart;\n    }\n\n    /**\n     * Returns a copy of the the bytes of this dex.\n     */\n    public byte[] getBytes() {\n        ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe\n        byte[] result = new byte[data.capacity()];\n        data.position(0);\n        data.get(result);\n        return result;\n    }\n\n    public List<String> strings() {\n        return strings;\n    }\n\n    public List<Integer> typeIds() {\n        return typeIds;\n    }\n\n    public List<String> typeNames() {\n        return typeNames;\n    }\n\n    public List<ProtoId> protoIds() {\n        return protoIds;\n    }\n\n    public List<FieldId> fieldIds() {\n        return fieldIds;\n    }\n\n    public List<MethodId> methodIds() {\n        return methodIds;\n    }\n\n    public Iterable<ClassDef> classDefs() {\n        return new ClassDefIterable();\n    }\n\n    public TypeList readTypeList(int offset) {\n        if (offset == 0) {\n            return TypeList.EMPTY;\n        }\n        return open(offset).readTypeList();\n    }\n\n    public ClassData readClassData(ClassDef classDef) {\n        int offset = classDef.getClassDataOffset();\n        if (offset == 0) {\n            throw new IllegalArgumentException(\"offset == 0\");\n        }\n        return open(offset).readClassData();\n    }\n\n    public Code readCode(ClassData.Method method) {\n        int offset = method.getCodeOffset();\n        if (offset == 0) {\n            throw new IllegalArgumentException(\"offset == 0\");\n        }\n        return open(offset).readCode();\n    }\n\n    /**\n     * Returns the signature of all but the first 32 bytes of this dex. The\n     * first 32 bytes of dex files are not specified to be included in the\n     * signature.\n     */\n    public byte[] computeSignature() throws IOException {\n        MessageDigest digest;\n        try {\n            digest = MessageDigest.getInstance(\"SHA-1\");\n        } catch (NoSuchAlgorithmException e) {\n            throw new AssertionError();\n        }\n        byte[] buffer = new byte[8192];\n        ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe\n        data.limit(data.capacity());\n        data.position(SIGNATURE_OFFSET + SIGNATURE_SIZE);\n        while (data.hasRemaining()) {\n            int count = Math.min(buffer.length, data.remaining());\n            data.get(buffer, 0, count);\n            digest.update(buffer, 0, count);\n        }\n        return digest.digest();\n    }\n\n    /**\n     * Returns the checksum of all but the first 12 bytes of {@code dex}.\n     */\n    public int computeChecksum() throws IOException {\n        Adler32 adler32 = new Adler32();\n        byte[] buffer = new byte[8192];\n        ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe\n        data.limit(data.capacity());\n        data.position(CHECKSUM_OFFSET + CHECKSUM_SIZE);\n        while (data.hasRemaining()) {\n            int count = Math.min(buffer.length, data.remaining());\n            data.get(buffer, 0, count);\n            adler32.update(buffer, 0, count);\n        }\n        return (int) adler32.getValue();\n    }\n\n    /**\n     * Generates the signature and checksum of the dex file {@code out} and\n     * writes them to the file.\n     */\n    public void writeHashes() throws IOException {\n        open(SIGNATURE_OFFSET).write(computeSignature());\n        open(CHECKSUM_OFFSET).writeInt(computeChecksum());\n    }\n\n    /**\n     * Look up a field id name index from a field index. Cheaper than:\n     * {@code fieldIds().get(fieldDexIndex).getNameIndex();}\n     */\n    public int nameIndexFromFieldIndex(int fieldIndex) {\n        checkBounds(fieldIndex, tableOfContents.fieldIds.size);\n        int position = tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * fieldIndex);\n        position += SizeOf.USHORT;  // declaringClassIndex\n        position += SizeOf.USHORT;  // typeIndex\n        return data.getInt(position);  // nameIndex\n    }\n\n    public int findStringIndex(String s) {\n        return Collections.binarySearch(strings, s);\n    }\n\n    public int findTypeIndex(String descriptor) {\n        return Collections.binarySearch(typeNames, descriptor);\n    }\n\n    public int findFieldIndex(FieldId fieldId) {\n        return Collections.binarySearch(fieldIds, fieldId);\n    }\n\n    public int findMethodIndex(MethodId methodId) {\n        return Collections.binarySearch(methodIds, methodId);\n    }\n\n    public int findClassDefIndexFromTypeIndex(int typeIndex) {\n        checkBounds(typeIndex, tableOfContents.typeIds.size);\n        if (!tableOfContents.classDefs.exists()) {\n            return -1;\n        }\n        for (int i = 0; i < tableOfContents.classDefs.size; i++) {\n            if (typeIndexFromClassDefIndex(i) == typeIndex) {\n                return i;\n            }\n        }\n        return -1;\n    }\n\n    /**\n     * Look up a field id type index from a field index. Cheaper than:\n     * {@code fieldIds().get(fieldDexIndex).getTypeIndex();}\n     */\n    public int typeIndexFromFieldIndex(int fieldIndex) {\n        checkBounds(fieldIndex, tableOfContents.fieldIds.size);\n        int position = tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * fieldIndex);\n        position += SizeOf.USHORT;  // declaringClassIndex\n        return data.getShort(position) & 0xFFFF;  // typeIndex\n    }\n\n    /**\n     * Look up a method id declaring class index from a method index. Cheaper than:\n     * {@code methodIds().get(methodIndex).getDeclaringClassIndex();}\n     */\n    public int declaringClassIndexFromMethodIndex(int methodIndex) {\n        checkBounds(methodIndex, tableOfContents.methodIds.size);\n        int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);\n        return data.getShort(position) & 0xFFFF;  // declaringClassIndex\n    }\n\n    /**\n     * Look up a method id name index from a method index. Cheaper than:\n     * {@code methodIds().get(methodIndex).getNameIndex();}\n     */\n    public int nameIndexFromMethodIndex(int methodIndex) {\n        checkBounds(methodIndex, tableOfContents.methodIds.size);\n        int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);\n        position += SizeOf.USHORT;  // declaringClassIndex\n        position += SizeOf.USHORT;  // protoIndex\n        return data.getInt(position);  // nameIndex\n    }\n\n    /**\n     * Look up a parameter type ids from a method index. Cheaper than:\n     * {@code readTypeList(protoIds.get(methodIds().get(methodDexIndex).getProtoIndex()).getParametersOffset()).getTypes();}\n     */\n    public short[] parameterTypeIndicesFromMethodIndex(int methodIndex) {\n        checkBounds(methodIndex, tableOfContents.methodIds.size);\n        int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);\n        position += SizeOf.USHORT;  // declaringClassIndex\n        int protoIndex = data.getShort(position) & 0xFFFF;\n        checkBounds(protoIndex, tableOfContents.protoIds.size);\n        position = tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * protoIndex);\n        position += SizeOf.UINT;  // shortyIndex\n        position += SizeOf.UINT;  // returnTypeIndex\n        int parametersOffset = data.getInt(position);\n        if (parametersOffset == 0) {\n            return EMPTY_SHORT_ARRAY;\n        }\n        position = parametersOffset;\n        int size = data.getInt(position);\n        if (size <= 0) {\n            throw new AssertionError(\"Unexpected parameter type list size: \" + size);\n        }\n        position += SizeOf.UINT;\n        short[] types = new short[size];\n        for (int i = 0; i < size; i++) {\n            types[i] = data.getShort(position);\n            position += SizeOf.USHORT;\n        }\n        return types;\n    }\n\n    /**\n     * Look up a method id return type index from a method index. Cheaper than:\n     * {@code protoIds().get(methodIds().get(methodDexIndex).getProtoIndex()).getReturnTypeIndex();}\n     */\n    public int returnTypeIndexFromMethodIndex(int methodIndex) {\n        checkBounds(methodIndex, tableOfContents.methodIds.size);\n        int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);\n        position += SizeOf.USHORT;  // declaringClassIndex\n        int protoIndex = data.getShort(position) & 0xFFFF;\n        checkBounds(protoIndex, tableOfContents.protoIds.size);\n        position = tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * protoIndex);\n        position += SizeOf.UINT;  // shortyIndex\n        return data.getInt(position);  // returnTypeIndex\n    }\n\n    /**\n     * Look up a descriptor index from a type index. Cheaper than:\n     * {@code open(tableOfContents.typeIds.off + (index * SizeOf.TYPE_ID_ITEM)).readInt();}\n     */\n    public int descriptorIndexFromTypeIndex(int typeIndex) {\n       checkBounds(typeIndex, tableOfContents.typeIds.size);\n       int position = tableOfContents.typeIds.off + (SizeOf.TYPE_ID_ITEM * typeIndex);\n       return data.getInt(position);\n    }\n\n    /**\n     * Look up a type index index from a class def index.\n     */\n    public int typeIndexFromClassDefIndex(int classDefIndex) {\n        checkBounds(classDefIndex, tableOfContents.classDefs.size);\n        int position = tableOfContents.classDefs.off + (SizeOf.CLASS_DEF_ITEM * classDefIndex);\n        return data.getInt(position);\n    }\n\n    /**\n     * Look up an annotation directory offset from a class def index.\n     */\n    public int annotationDirectoryOffsetFromClassDefIndex(int classDefIndex) {\n        checkBounds(classDefIndex, tableOfContents.classDefs.size);\n        int position = tableOfContents.classDefs.off + (SizeOf.CLASS_DEF_ITEM * classDefIndex);\n        position += SizeOf.UINT;  // type\n        position += SizeOf.UINT;  // accessFlags\n        position += SizeOf.UINT;  // superType\n        position += SizeOf.UINT;  // interfacesOffset\n        position += SizeOf.UINT;  // sourceFileIndex\n        return data.getInt(position);\n    }\n\n    /**\n     * Look up interface types indices from a  return type index from a method index. Cheaper than:\n     * {@code ...getClassDef(classDefIndex).getInterfaces();}\n     */\n    public short[] interfaceTypeIndicesFromClassDefIndex(int classDefIndex) {\n        checkBounds(classDefIndex, tableOfContents.classDefs.size);\n        int position = tableOfContents.classDefs.off + (SizeOf.CLASS_DEF_ITEM * classDefIndex);\n        position += SizeOf.UINT;  // type\n        position += SizeOf.UINT;  // accessFlags\n        position += SizeOf.UINT;  // superType\n        int interfacesOffset = data.getInt(position);\n        if (interfacesOffset == 0) {\n            return EMPTY_SHORT_ARRAY;\n        }\n        position = interfacesOffset;\n        int size = data.getInt(position);\n        if (size <= 0) {\n            throw new AssertionError(\"Unexpected interfaces list size: \" + size);\n        }\n        position += SizeOf.UINT;\n        short[] types = new short[size];\n        for (int i = 0; i < size; i++) {\n            types[i] = data.getShort(position);\n            position += SizeOf.USHORT;\n        }\n        return types;\n    }\n\n    public final class Section implements ByteInput, ByteOutput {\n        private final String name;\n        private final ByteBuffer data;\n        private final int initialPosition;\n\n        private Section(String name, ByteBuffer data) {\n            this.name = name;\n            this.data = data;\n            this.initialPosition = data.position();\n        }\n\n        public int getPosition() {\n            return data.position();\n        }\n\n        public int readInt() {\n            return data.getInt();\n        }\n\n        public short readShort() {\n            return data.getShort();\n        }\n\n        public int readUnsignedShort() {\n            return readShort() & 0xffff;\n        }\n\n        public byte readByte() {\n            return data.get();\n        }\n\n        public byte[] readByteArray(int length) {\n            byte[] result = new byte[length];\n            data.get(result);\n            return result;\n        }\n\n        public short[] readShortArray(int length) {\n            if (length == 0) {\n                return EMPTY_SHORT_ARRAY;\n            }\n            short[] result = new short[length];\n            for (int i = 0; i < length; i++) {\n                result[i] = readShort();\n            }\n            return result;\n        }\n\n        public int readUleb128() {\n            return Leb128.readUnsignedLeb128(this);\n        }\n\n        public int readUleb128p1() {\n            return Leb128.readUnsignedLeb128(this) - 1;\n        }\n\n        public int readSleb128() {\n            return Leb128.readSignedLeb128(this);\n        }\n\n        public void writeUleb128p1(int i) {\n            writeUleb128(i + 1);\n        }\n\n        public TypeList readTypeList() {\n            int size = readInt();\n            short[] types = readShortArray(size);\n            alignToFourBytes();\n            return new TypeList(Dex.this, types);\n        }\n\n        public String readString() {\n            int offset = readInt();\n            int savedPosition = data.position();\n            int savedLimit = data.limit();\n            data.position(offset);\n            data.limit(data.capacity());\n            try {\n                int expectedLength = readUleb128();\n                String result = Mutf8.decode(this, new char[expectedLength]);\n                if (result.length() != expectedLength) {\n                    throw new DexException(\"Declared length \" + expectedLength\n                            + \" doesn't match decoded length of \" + result.length());\n                }\n                return result;\n            } catch (UTFDataFormatException e) {\n                throw new DexException(e);\n            } finally {\n                data.position(savedPosition);\n                data.limit(savedLimit);\n            }\n        }\n\n        public FieldId readFieldId() {\n            int declaringClassIndex = readUnsignedShort();\n            int typeIndex = readUnsignedShort();\n            int nameIndex = readInt();\n            return new FieldId(Dex.this, declaringClassIndex, typeIndex, nameIndex);\n        }\n\n        public MethodId readMethodId() {\n            int declaringClassIndex = readUnsignedShort();\n            int protoIndex = readUnsignedShort();\n            int nameIndex = readInt();\n            return new MethodId(Dex.this, declaringClassIndex, protoIndex, nameIndex);\n        }\n\n        public ProtoId readProtoId() {\n            int shortyIndex = readInt();\n            int returnTypeIndex = readInt();\n            int parametersOffset = readInt();\n            return new ProtoId(Dex.this, shortyIndex, returnTypeIndex, parametersOffset);\n        }\n\n        public ClassDef readClassDef() {\n            int offset = getPosition();\n            int type = readInt();\n            int accessFlags = readInt();\n            int supertype = readInt();\n            int interfacesOffset = readInt();\n            int sourceFileIndex = readInt();\n            int annotationsOffset = readInt();\n            int classDataOffset = readInt();\n            int staticValuesOffset = readInt();\n            return new ClassDef(Dex.this, offset, type, accessFlags, supertype,\n                    interfacesOffset, sourceFileIndex, annotationsOffset, classDataOffset,\n                    staticValuesOffset);\n        }\n\n        private Code readCode() {\n            int registersSize = readUnsignedShort();\n            int insSize = readUnsignedShort();\n            int outsSize = readUnsignedShort();\n            int triesSize = readUnsignedShort();\n            int debugInfoOffset = readInt();\n            int instructionsSize = readInt();\n            short[] instructions = readShortArray(instructionsSize);\n            Try[] tries;\n            CatchHandler[] catchHandlers;\n            if (triesSize > 0) {\n                if (instructions.length % 2 == 1) {\n                    readShort(); // padding\n                }\n\n                /*\n                 * We can't read the tries until we've read the catch handlers.\n                 * Unfortunately they're in the opposite order in the dex file\n                 * so we need to read them out-of-order.\n                 */\n                Section triesSection = open(data.position());\n                skip(triesSize * SizeOf.TRY_ITEM);\n                catchHandlers = readCatchHandlers();\n                tries = triesSection.readTries(triesSize, catchHandlers);\n            } else {\n                tries = new Try[0];\n                catchHandlers = new CatchHandler[0];\n            }\n            return new Code(registersSize, insSize, outsSize, debugInfoOffset, instructions,\n                            tries, catchHandlers);\n        }\n\n        private CatchHandler[] readCatchHandlers() {\n            int baseOffset = data.position();\n            int catchHandlersSize = readUleb128();\n            CatchHandler[] result = new CatchHandler[catchHandlersSize];\n            for (int i = 0; i < catchHandlersSize; i++) {\n                int offset = data.position() - baseOffset;\n                result[i] = readCatchHandler(offset);\n            }\n            return result;\n        }\n\n        private Try[] readTries(int triesSize, CatchHandler[] catchHandlers) {\n            Try[] result = new Try[triesSize];\n            for (int i = 0; i < triesSize; i++) {\n                int startAddress = readInt();\n                int instructionCount = readUnsignedShort();\n                int handlerOffset = readUnsignedShort();\n                int catchHandlerIndex = findCatchHandlerIndex(catchHandlers, handlerOffset);\n                result[i] = new Try(startAddress, instructionCount, catchHandlerIndex);\n            }\n            return result;\n        }\n\n        private int findCatchHandlerIndex(CatchHandler[] catchHandlers, int offset) {\n            for (int i = 0; i < catchHandlers.length; i++) {\n                CatchHandler catchHandler = catchHandlers[i];\n                if (catchHandler.getOffset() == offset) {\n                    return i;\n                }\n            }\n            throw new IllegalArgumentException();\n        }\n\n        private CatchHandler readCatchHandler(int offset) {\n            int size = readSleb128();\n            int handlersCount = Math.abs(size);\n            int[] typeIndexes = new int[handlersCount];\n            int[] addresses = new int[handlersCount];\n            for (int i = 0; i < handlersCount; i++) {\n                typeIndexes[i] = readUleb128();\n                addresses[i] = readUleb128();\n            }\n            int catchAllAddress = size <= 0 ? readUleb128() : -1;\n            return new CatchHandler(typeIndexes, addresses, catchAllAddress, offset);\n        }\n\n        private ClassData readClassData() {\n            int staticFieldsSize = readUleb128();\n            int instanceFieldsSize = readUleb128();\n            int directMethodsSize = readUleb128();\n            int virtualMethodsSize = readUleb128();\n            ClassData.Field[] staticFields = readFields(staticFieldsSize);\n            ClassData.Field[] instanceFields = readFields(instanceFieldsSize);\n            ClassData.Method[] directMethods = readMethods(directMethodsSize);\n            ClassData.Method[] virtualMethods = readMethods(virtualMethodsSize);\n            return new ClassData(staticFields, instanceFields, directMethods, virtualMethods);\n        }\n\n        private ClassData.Field[] readFields(int count) {\n            ClassData.Field[] result = new ClassData.Field[count];\n            int fieldIndex = 0;\n            for (int i = 0; i < count; i++) {\n                fieldIndex += readUleb128(); // field index diff\n                int accessFlags = readUleb128();\n                result[i] = new ClassData.Field(fieldIndex, accessFlags);\n            }\n            return result;\n        }\n\n        private ClassData.Method[] readMethods(int count) {\n            ClassData.Method[] result = new ClassData.Method[count];\n            int methodIndex = 0;\n            for (int i = 0; i < count; i++) {\n                methodIndex += readUleb128(); // method index diff\n                int accessFlags = readUleb128();\n                int codeOff = readUleb128();\n                result[i] = new ClassData.Method(methodIndex, accessFlags, codeOff);\n            }\n            return result;\n        }\n\n        /**\n         * Returns a byte array containing the bytes from {@code start} to this\n         * section's current position.\n         */\n        private byte[] getBytesFrom(int start) {\n            int end = data.position();\n            byte[] result = new byte[end - start];\n            data.position(start);\n            data.get(result);\n            return result;\n        }\n\n        public Annotation readAnnotation() {\n            byte visibility = readByte();\n            int start = data.position();\n            new EncodedValueReader(this, EncodedValueReader.ENCODED_ANNOTATION).skipValue();\n            return new Annotation(Dex.this, visibility, new EncodedValue(getBytesFrom(start)));\n        }\n\n        public EncodedValue readEncodedArray() {\n            int start = data.position();\n            new EncodedValueReader(this, EncodedValueReader.ENCODED_ARRAY).skipValue();\n            return new EncodedValue(getBytesFrom(start));\n        }\n\n        public void skip(int count) {\n            if (count < 0) {\n                throw new IllegalArgumentException();\n            }\n            data.position(data.position() + count);\n        }\n\n        /**\n         * Skips bytes until the position is aligned to a multiple of 4.\n         */\n        public void alignToFourBytes() {\n            data.position((data.position() + 3) & ~3);\n        }\n\n        /**\n         * Writes 0x00 until the position is aligned to a multiple of 4.\n         */\n        public void alignToFourBytesWithZeroFill() {\n            while ((data.position() & 3) != 0) {\n                data.put((byte) 0);\n            }\n        }\n\n        public void assertFourByteAligned() {\n            if ((data.position() & 3) != 0) {\n                throw new IllegalStateException(\"Not four byte aligned!\");\n            }\n        }\n\n        public void write(byte[] bytes) {\n            this.data.put(bytes);\n        }\n\n        public void writeByte(int b) {\n            data.put((byte) b);\n        }\n\n        public void writeShort(short i) {\n            data.putShort(i);\n        }\n\n        public void writeUnsignedShort(int i) {\n            short s = (short) i;\n            if (i != (s & 0xffff)) {\n                throw new IllegalArgumentException(\"Expected an unsigned short: \" + i);\n            }\n            writeShort(s);\n        }\n\n        public void write(short[] shorts) {\n            for (short s : shorts) {\n                writeShort(s);\n            }\n        }\n\n        public void writeInt(int i) {\n            data.putInt(i);\n        }\n\n        public void writeUleb128(int i) {\n            try {\n                Leb128.writeUnsignedLeb128(this, i);\n            } catch (ArrayIndexOutOfBoundsException e) {\n                throw new DexException(\"Section limit \" + data.limit() + \" exceeded by \" + name);\n            }\n        }\n\n        public void writeSleb128(int i) {\n            try {\n                Leb128.writeSignedLeb128(this, i);\n            } catch (ArrayIndexOutOfBoundsException e) {\n                throw new DexException(\"Section limit \" + data.limit() + \" exceeded by \" + name);\n            }\n        }\n\n        public void writeStringData(String value) {\n            try {\n                int length = value.length();\n                writeUleb128(length);\n                write(Mutf8.encode(value));\n                writeByte(0);\n            } catch (UTFDataFormatException e) {\n                throw new AssertionError();\n            }\n        }\n\n        public void writeTypeList(TypeList typeList) {\n            short[] types = typeList.getTypes();\n            writeInt(types.length);\n            for (short type : types) {\n                writeShort(type);\n            }\n            alignToFourBytesWithZeroFill();\n        }\n\n        /**\n         * Returns the number of bytes remaining in this section.\n         */\n        public int remaining() {\n            return data.remaining();\n        }\n\n        /**\n         * Returns the number of bytes used by this section.\n         */\n        public int used() {\n            return data.position() - initialPosition;\n        }\n    }\n\n    private final class StringTable extends AbstractList<String> implements RandomAccess {\n        @Override public String get(int index) {\n            checkBounds(index, tableOfContents.stringIds.size);\n            return open(tableOfContents.stringIds.off + (index * SizeOf.STRING_ID_ITEM))\n                    .readString();\n        }\n        @Override public int size() {\n            return tableOfContents.stringIds.size;\n        }\n    }\n\n    private final class TypeIndexToDescriptorIndexTable extends AbstractList<Integer>\n            implements RandomAccess {\n        @Override public Integer get(int index) {\n            return descriptorIndexFromTypeIndex(index);\n        }\n        @Override public int size() {\n            return tableOfContents.typeIds.size;\n        }\n    }\n\n    private final class TypeIndexToDescriptorTable extends AbstractList<String>\n            implements RandomAccess {\n        @Override public String get(int index) {\n            return strings.get(descriptorIndexFromTypeIndex(index));\n        }\n        @Override public int size() {\n            return tableOfContents.typeIds.size;\n        }\n    }\n\n    private final class ProtoIdTable extends AbstractList<ProtoId> implements RandomAccess {\n        @Override public ProtoId get(int index) {\n            checkBounds(index, tableOfContents.protoIds.size);\n            return open(tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * index))\n                    .readProtoId();\n        }\n        @Override public int size() {\n            return tableOfContents.protoIds.size;\n        }\n    }\n\n    private final class FieldIdTable extends AbstractList<FieldId> implements RandomAccess {\n        @Override public FieldId get(int index) {\n            checkBounds(index, tableOfContents.fieldIds.size);\n            return open(tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * index))\n                    .readFieldId();\n        }\n        @Override public int size() {\n            return tableOfContents.fieldIds.size;\n        }\n    }\n\n    private final class MethodIdTable extends AbstractList<MethodId> implements RandomAccess {\n        @Override public MethodId get(int index) {\n            checkBounds(index, tableOfContents.methodIds.size);\n            return open(tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * index))\n                    .readMethodId();\n        }\n        @Override public int size() {\n            return tableOfContents.methodIds.size;\n        }\n    }\n\n    private final class ClassDefIterator implements Iterator<ClassDef> {\n        private final Section in = open(tableOfContents.classDefs.off);\n        private int count = 0;\n\n        @Override\n        public boolean hasNext() {\n            return count < tableOfContents.classDefs.size;\n        }\n        @Override\n        public ClassDef next() {\n            if (!hasNext()) {\n                throw new NoSuchElementException();\n            }\n            count++;\n            return in.readClassDef();\n        }\n        @Override\n            public void remove() {\n            throw new UnsupportedOperationException();\n        }\n    }\n\n    private final class ClassDefIterable implements Iterable<ClassDef> {\n        public Iterator<ClassDef> iterator() {\n            return !tableOfContents.classDefs.exists()\n               ? Collections.<ClassDef>emptySet().iterator()\n               : new ClassDefIterator();\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/DexException.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\n\n/**\n * Thrown when there's a format problem reading, writing, or generally\n * processing a dex file.\n */\npublic class DexException extends ExceptionWithContext {\n    public DexException(String message) {\n        super(message);\n    }\n\n    public DexException(Throwable cause) {\n        super(cause);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/DexFormat.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\n/**\n * Constants that show up in and are otherwise related to {@code .dex}\n * files, and helper methods for same.\n */\npublic final class DexFormat {\n    private DexFormat() {}\n\n    /**\n     * API level to target in order to produce the most modern file\n     * format\n     */\n    public static final int API_CURRENT = 14;\n\n    /** API level to target in order to suppress extended opcode usage */\n    public static final int API_NO_EXTENDED_OPCODES = 13;\n\n    /**\n     * file name of the primary {@code .dex} file inside an\n     * application or library {@code .jar} file\n     */\n    public static final String DEX_IN_JAR_NAME = \"classes.dex\";\n\n    /** common prefix for all dex file \"magic numbers\" */\n    public static final String MAGIC_PREFIX = \"dex\\n\";\n\n    /** common suffix for all dex file \"magic numbers\" */\n    public static final String MAGIC_SUFFIX = \"\\0\";\n\n    /** dex file version number for the current format variant */\n    public static final String VERSION_CURRENT = \"036\";\n\n    /** dex file version number for API level 13 and earlier */\n    public static final String VERSION_FOR_API_13 = \"035\";\n\n    /**\n     * value used to indicate endianness of file contents\n     */\n    public static final int ENDIAN_TAG = 0x12345678;\n\n    /**\n     * Maximum addressable field or method index.\n     * The largest addressable member is 0xffff, in the \"instruction formats\" spec as field@CCCC or\n     * meth@CCCC.\n     */\n    public static final int MAX_MEMBER_IDX = 0xFFFF;\n\n    /**\n     * Maximum addressable type index.\n     * The largest addressable type is 0xffff, in the \"instruction formats\" spec as type@CCCC.\n     */\n    public static final int MAX_TYPE_IDX = 0xFFFF;\n\n    /**\n     * Returns the API level corresponding to the given magic number,\n     * or {@code -1} if the given array is not a well-formed dex file\n     * magic number.\n     */\n    public static int magicToApi(byte[] magic) {\n        if (magic.length != 8) {\n            return -1;\n        }\n\n        if ((magic[0] != 'd') || (magic[1] != 'e') || (magic[2] != 'x') || (magic[3] != '\\n') ||\n                (magic[7] != '\\0')) {\n            return -1;\n        }\n\n        String version = \"\" + ((char) magic[4]) + ((char) magic[5]) +((char) magic[6]);\n\n        if (version.equals(VERSION_CURRENT)) {\n            return API_CURRENT;\n        } else if (version.equals(VERSION_FOR_API_13)) {\n            return 13;\n        }\n\n        return -1;\n    }\n\n    /**\n     * Returns the magic number corresponding to the given target API level.\n     */\n    public static String apiToMagic(int targetApiLevel) {\n        String version;\n\n        if (targetApiLevel >= API_CURRENT) {\n            version = VERSION_CURRENT;\n        } else {\n            version = VERSION_FOR_API_13;\n        }\n\n        return MAGIC_PREFIX + version + MAGIC_SUFFIX;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/DexIndexOverflowException.java",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\n/**\n * Thrown when there's an index overflow writing a dex file.\n */\npublic final class DexIndexOverflowException extends DexException {\n    public DexIndexOverflowException(String message) {\n        super(message);\n    }\n\n    public DexIndexOverflowException(Throwable cause) {\n        super(cause);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/EncodedValue.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\nimport com.taobao.android.dex.util.ByteArrayByteInput;\nimport com.taobao.android.dex.util.ByteInput;\n\n/**\n * An encoded value or array.\n */\npublic final class EncodedValue implements Comparable<EncodedValue> {\n    private final byte[] data;\n\n    public EncodedValue(byte[] data) {\n        this.data = data;\n    }\n\n    public ByteInput asByteInput() {\n        return new ByteArrayByteInput(data);\n    }\n\n    public byte[] getBytes() {\n        return data;\n    }\n\n    public void writeTo(Dex.Section out) {\n        out.write(data);\n    }\n\n    @Override public int compareTo(EncodedValue other) {\n        int size = Math.min(data.length, other.data.length);\n        for (int i = 0; i < size; i++) {\n            if (data[i] != other.data[i]) {\n                return (data[i] & 0xff) - (other.data[i] & 0xff);\n            }\n        }\n        return data.length - other.data.length;\n    }\n\n    @Override public String toString() {\n        return Integer.toHexString(data[0] & 0xff) + \"...(\" + data.length + \")\";\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/EncodedValueCodec.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\nimport com.taobao.android.dex.util.ByteInput;\nimport com.taobao.android.dex.util.ByteOutput;\n\n/**\n * Read and write {@code encoded_value} primitives.\n */\npublic final class EncodedValueCodec {\n    private EncodedValueCodec() {\n    }\n\n    /**\n     * Writes a signed integral to {@code out}.\n     */\n    public static void writeSignedIntegralValue(ByteOutput out, int type, long value) {\n        /*\n         * Figure out how many bits are needed to represent the value,\n         * including a sign bit: The bit count is subtracted from 65\n         * and not 64 to account for the sign bit. The xor operation\n         * has the effect of leaving non-negative values alone and\n         * unary complementing negative values (so that a leading zero\n         * count always returns a useful number for our present\n         * purpose).\n         */\n        int requiredBits = 65 - Long.numberOfLeadingZeros(value ^ (value >> 63));\n\n        // Round up the requiredBits to a number of bytes.\n        int requiredBytes = (requiredBits + 0x07) >> 3;\n\n        /*\n         * Write the header byte, which includes the type and\n         * requiredBytes - 1.\n         */\n        out.writeByte(type | ((requiredBytes - 1) << 5));\n\n        // Write the value, per se.\n        while (requiredBytes > 0) {\n            out.writeByte((byte) value);\n            value >>= 8;\n            requiredBytes--;\n        }\n    }\n\n    /**\n     * Writes an unsigned integral to {@code out}.\n     */\n    public static void writeUnsignedIntegralValue(ByteOutput out, int type, long value) {\n        // Figure out how many bits are needed to represent the value.\n        int requiredBits = 64 - Long.numberOfLeadingZeros(value);\n        if (requiredBits == 0) {\n            requiredBits = 1;\n        }\n\n        // Round up the requiredBits to a number of bytes.\n        int requiredBytes = (requiredBits + 0x07) >> 3;\n\n        /*\n         * Write the header byte, which includes the type and\n         * requiredBytes - 1.\n         */\n        out.writeByte(type | ((requiredBytes - 1) << 5));\n\n        // Write the value, per se.\n        while (requiredBytes > 0) {\n            out.writeByte((byte) value);\n            value >>= 8;\n            requiredBytes--;\n        }\n    }\n\n    /**\n     * Writes a right-zero-extended value to {@code out}.\n     */\n    public static void writeRightZeroExtendedValue(ByteOutput out, int type, long value) {\n        // Figure out how many bits are needed to represent the value.\n        int requiredBits = 64 - Long.numberOfTrailingZeros(value);\n        if (requiredBits == 0) {\n            requiredBits = 1;\n        }\n\n        // Round up the requiredBits to a number of bytes.\n        int requiredBytes = (requiredBits + 0x07) >> 3;\n\n        // Scootch the first bits to be written down to the low-order bits.\n        value >>= 64 - (requiredBytes * 8);\n\n        /*\n         * Write the header byte, which includes the type and\n         * requiredBytes - 1.\n         */\n        out.writeByte(type | ((requiredBytes - 1) << 5));\n\n        // Write the value, per se.\n        while (requiredBytes > 0) {\n            out.writeByte((byte) value);\n            value >>= 8;\n            requiredBytes--;\n        }\n    }\n\n    /**\n     * Read a signed integer.\n     *\n     * @param zwidth byte count minus one\n     */\n    public static int readSignedInt(ByteInput in, int zwidth) {\n        int result = 0;\n        for (int i = zwidth; i >= 0; i--) {\n            result = (result >>> 8) | ((in.readByte() & 0xff) << 24);\n        }\n        result >>= (3 - zwidth) * 8;\n        return result;\n    }\n\n    /**\n     * Read an unsigned integer.\n     *\n     * @param zwidth byte count minus one\n     * @param fillOnRight true to zero fill on the right; false on the left\n     */\n    public static int readUnsignedInt(ByteInput in, int zwidth, boolean fillOnRight) {\n        int result = 0;\n        if (!fillOnRight) {\n            for (int i = zwidth; i >= 0; i--) {\n                result = (result >>> 8) | ((in.readByte() & 0xff) << 24);\n            }\n            result >>>= (3 - zwidth) * 8;\n        } else {\n            for (int i = zwidth; i >= 0; i--) {\n                result = (result >>> 8) | ((in.readByte() & 0xff) << 24);\n            }\n        }\n        return result;\n    }\n\n    /**\n     * Read a signed long.\n     *\n     * @param zwidth byte count minus one\n     */\n    public static long readSignedLong(ByteInput in, int zwidth) {\n        long result = 0;\n        for (int i = zwidth; i >= 0; i--) {\n            result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);\n        }\n        result >>= (7 - zwidth) * 8;\n        return result;\n    }\n\n    /**\n     * Read an unsigned long.\n     *\n     * @param zwidth byte count minus one\n     * @param fillOnRight true to zero fill on the right; false on the left\n     */\n    public static long readUnsignedLong(ByteInput in, int zwidth, boolean fillOnRight) {\n        long result = 0;\n        if (!fillOnRight) {\n            for (int i = zwidth; i >= 0; i--) {\n                result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);\n            }\n            result >>>= (7 - zwidth) * 8;\n        } else {\n            for (int i = zwidth; i >= 0; i--) {\n                result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);\n            }\n        }\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/EncodedValueReader.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\nimport com.taobao.android.dex.util.ByteInput;\n\n/**\n * Pull parser for encoded values.\n */\npublic final class EncodedValueReader {\n    public static final int ENCODED_BYTE = 0x00;\n    public static final int ENCODED_SHORT = 0x02;\n    public static final int ENCODED_CHAR = 0x03;\n    public static final int ENCODED_INT = 0x04;\n    public static final int ENCODED_LONG = 0x06;\n    public static final int ENCODED_FLOAT = 0x10;\n    public static final int ENCODED_DOUBLE = 0x11;\n    public static final int ENCODED_STRING = 0x17;\n    public static final int ENCODED_TYPE = 0x18;\n    public static final int ENCODED_FIELD = 0x19;\n    public static final int ENCODED_ENUM = 0x1b;\n    public static final int ENCODED_METHOD = 0x1a;\n    public static final int ENCODED_ARRAY = 0x1c;\n    public static final int ENCODED_ANNOTATION = 0x1d;\n    public static final int ENCODED_NULL = 0x1e;\n    public static final int ENCODED_BOOLEAN = 0x1f;\n\n    /** placeholder type if the type is not yet known */\n    private static final int MUST_READ = -1;\n\n    protected final ByteInput in;\n    private int type = MUST_READ;\n    private int annotationType;\n    private int arg;\n\n    public EncodedValueReader(ByteInput in) {\n        this.in = in;\n    }\n\n    public EncodedValueReader(EncodedValue in) {\n        this(in.asByteInput());\n    }\n\n    /**\n     * Creates a new encoded value reader whose only value is the specified\n     * known type. This is useful for encoded values without a type prefix,\n     * such as class_def_item's encoded_array or annotation_item's\n     * encoded_annotation.\n     */\n    public EncodedValueReader(ByteInput in, int knownType) {\n        this.in = in;\n        this.type = knownType;\n    }\n\n    public EncodedValueReader(EncodedValue in, int knownType) {\n        this(in.asByteInput(), knownType);\n    }\n\n    /**\n     * Returns the type of the next value to read.\n     */\n    public int peek() {\n        if (type == MUST_READ) {\n            int argAndType = in.readByte() & 0xff;\n            type = argAndType & 0x1f;\n            arg = (argAndType & 0xe0) >> 5;\n        }\n        return type;\n    }\n\n    /**\n     * Begins reading the elements of an array, returning the array's size. The\n     * caller must follow up by calling a read method for each element in the\n     * array. For example, this reads a byte array: <pre>   {@code\n     *   int arraySize = readArray();\n     *   for (int i = 0, i < arraySize; i++) {\n     *     readByte();\n     *   }\n     * }</pre>\n     */\n    public int readArray() {\n        checkType(ENCODED_ARRAY);\n        type = MUST_READ;\n        return Leb128.readUnsignedLeb128(in);\n    }\n\n    /**\n     * Begins reading the fields of an annotation, returning the number of\n     * fields. The caller must follow up by making alternating calls to {@link\n     * #readAnnotationName()} and another read method. For example, this reads\n     * an annotation whose fields are all bytes: <pre>   {@code\n     *   int fieldCount = readAnnotation();\n     *   int annotationType = getAnnotationType();\n     *   for (int i = 0; i < fieldCount; i++) {\n     *       readAnnotationName();\n     *       readByte();\n     *   }\n     * }</pre>\n     */\n    public int readAnnotation() {\n        checkType(ENCODED_ANNOTATION);\n        type = MUST_READ;\n        annotationType = Leb128.readUnsignedLeb128(in);\n        return Leb128.readUnsignedLeb128(in);\n    }\n\n    /**\n     * Returns the type of the annotation just returned by {@link\n     * #readAnnotation()}. This method's value is undefined unless the most\n     * recent call was to {@link #readAnnotation()}.\n     */\n    public int getAnnotationType() {\n        return annotationType;\n    }\n\n    public int readAnnotationName() {\n        return Leb128.readUnsignedLeb128(in);\n    }\n\n    public byte readByte() {\n        checkType(ENCODED_BYTE);\n        type = MUST_READ;\n        return (byte) EncodedValueCodec.readSignedInt(in, arg);\n    }\n\n    public short readShort() {\n        checkType(ENCODED_SHORT);\n        type = MUST_READ;\n        return (short) EncodedValueCodec.readSignedInt(in, arg);\n    }\n\n    public char readChar() {\n        checkType(ENCODED_CHAR);\n        type = MUST_READ;\n        return (char) EncodedValueCodec.readUnsignedInt(in, arg, false);\n    }\n\n    public int readInt() {\n        checkType(ENCODED_INT);\n        type = MUST_READ;\n        return EncodedValueCodec.readSignedInt(in, arg);\n    }\n\n    public long readLong() {\n        checkType(ENCODED_LONG);\n        type = MUST_READ;\n        return EncodedValueCodec.readSignedLong(in, arg);\n    }\n\n    public float readFloat() {\n        checkType(ENCODED_FLOAT);\n        type = MUST_READ;\n        return Float.intBitsToFloat(EncodedValueCodec.readUnsignedInt(in, arg, true));\n    }\n\n    public double readDouble() {\n        checkType(ENCODED_DOUBLE);\n        type = MUST_READ;\n        return Double.longBitsToDouble(EncodedValueCodec.readUnsignedLong(in, arg, true));\n    }\n\n    public int readString() {\n        checkType(ENCODED_STRING);\n        type = MUST_READ;\n        return EncodedValueCodec.readUnsignedInt(in, arg, false);\n    }\n\n    public int readType() {\n        checkType(ENCODED_TYPE);\n        type = MUST_READ;\n        return EncodedValueCodec.readUnsignedInt(in, arg, false);\n    }\n\n    public int readField() {\n        checkType(ENCODED_FIELD);\n        type = MUST_READ;\n        return EncodedValueCodec.readUnsignedInt(in, arg, false);\n    }\n\n    public int readEnum() {\n        checkType(ENCODED_ENUM);\n        type = MUST_READ;\n        return EncodedValueCodec.readUnsignedInt(in, arg, false);\n    }\n\n    public int readMethod() {\n        checkType(ENCODED_METHOD);\n        type = MUST_READ;\n        return EncodedValueCodec.readUnsignedInt(in, arg, false);\n    }\n\n    public void readNull() {\n        checkType(ENCODED_NULL);\n        type = MUST_READ;\n    }\n\n    public boolean readBoolean() {\n        checkType(ENCODED_BOOLEAN);\n        type = MUST_READ;\n        return arg != 0;\n    }\n\n    /**\n     * Skips a single value, including its nested values if it is an array or\n     * annotation.\n     */\n    public void skipValue() {\n        switch (peek()) {\n        case ENCODED_BYTE:\n            readByte();\n            break;\n        case ENCODED_SHORT:\n            readShort();\n            break;\n        case ENCODED_CHAR:\n            readChar();\n            break;\n        case ENCODED_INT:\n            readInt();\n            break;\n        case ENCODED_LONG:\n            readLong();\n            break;\n        case ENCODED_FLOAT:\n            readFloat();\n            break;\n        case ENCODED_DOUBLE:\n            readDouble();\n            break;\n        case ENCODED_STRING:\n            readString();\n            break;\n        case ENCODED_TYPE:\n            readType();\n            break;\n        case ENCODED_FIELD:\n            readField();\n            break;\n        case ENCODED_ENUM:\n            readEnum();\n            break;\n        case ENCODED_METHOD:\n            readMethod();\n            break;\n        case ENCODED_ARRAY:\n            for (int i = 0, size = readArray(); i < size; i++) {\n                skipValue();\n            }\n            break;\n        case ENCODED_ANNOTATION:\n            for (int i = 0, size = readAnnotation(); i < size; i++) {\n                readAnnotationName();\n                skipValue();\n            }\n            break;\n        case ENCODED_NULL:\n            readNull();\n            break;\n        case ENCODED_BOOLEAN:\n            readBoolean();\n            break;\n        default:\n            throw new DexException(\"Unexpected type: \" + Integer.toHexString(type));\n        }\n    }\n\n    private void checkType(int expected) {\n        if (peek() != expected) {\n            throw new IllegalStateException(\n                    String.format(\"Expected %x but was %x\", expected, peek()));\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/FieldId.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\nimport com.taobao.android.dex.util.Unsigned;\n\npublic final class FieldId implements Comparable<FieldId> {\n    private final Dex dex;\n    private final int declaringClassIndex;\n    private final int typeIndex;\n    private final int nameIndex;\n\n    public FieldId(Dex dex, int declaringClassIndex, int typeIndex, int nameIndex) {\n        this.dex = dex;\n        this.declaringClassIndex = declaringClassIndex;\n        this.typeIndex = typeIndex;\n        this.nameIndex = nameIndex;\n    }\n\n    public int getDeclaringClassIndex() {\n        return declaringClassIndex;\n    }\n\n    public int getTypeIndex() {\n        return typeIndex;\n    }\n\n    public int getNameIndex() {\n        return nameIndex;\n    }\n\n    public int compareTo(FieldId other) {\n        if (declaringClassIndex != other.declaringClassIndex) {\n            return Unsigned.compare(declaringClassIndex, other.declaringClassIndex);\n        }\n        if (nameIndex != other.nameIndex) {\n            return Unsigned.compare(nameIndex, other.nameIndex);\n        }\n        return Unsigned.compare(typeIndex, other.typeIndex); // should always be 0\n    }\n\n    public void writeTo(Dex.Section out) {\n        out.writeUnsignedShort(declaringClassIndex);\n        out.writeUnsignedShort(typeIndex);\n        out.writeInt(nameIndex);\n    }\n\n    @Override public String toString() {\n        if (dex == null) {\n            return declaringClassIndex + \" \" + typeIndex + \" \" + nameIndex;\n        }\n        return dex.typeNames().get(declaringClassIndex)+\".\"+dex.typeNames().get(typeIndex) + \".\" + dex.strings().get(nameIndex);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/Leb128.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\nimport com.taobao.android.dex.util.ByteInput;\nimport com.taobao.android.dex.util.ByteOutput;\n\n/**\n * Reads and writes DWARFv3 LEB 128 signed and unsigned integers. See DWARF v3\n * section 7.6.\n */\npublic final class Leb128 {\n    private Leb128() {\n    }\n\n    /**\n     * Gets the number of bytes in the unsigned LEB128 encoding of the\n     * given value.\n     *\n     * @param value the value in question\n     * @return its write size, in bytes\n     */\n    public static int unsignedLeb128Size(int value) {\n        // TODO: This could be much cleverer.\n\n        int remaining = value >> 7;\n        int count = 0;\n\n        while (remaining != 0) {\n            remaining >>= 7;\n            count++;\n        }\n\n        return count + 1;\n    }\n\n    /**\n     * Gets the number of bytes in the signed LEB128 encoding of the\n     * given value.\n     *\n     * @param value the value in question\n     * @return its write size, in bytes\n     */\n    public static int signedLeb128Size(int value) {\n        // TODO: This could be much cleverer.\n\n        int remaining = value >> 7;\n        int count = 0;\n        boolean hasMore = true;\n        int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;\n\n        while (hasMore) {\n            hasMore = (remaining != end)\n                || ((remaining & 1) != ((value >> 6) & 1));\n\n            value = remaining;\n            remaining >>= 7;\n            count++;\n        }\n\n        return count;\n    }\n\n    /**\n     * Reads an signed integer from {@code in}.\n     */\n    public static int readSignedLeb128(ByteInput in) {\n        int result = 0;\n        int cur;\n        int count = 0;\n        int signBits = -1;\n\n        do {\n            cur = in.readByte() & 0xff;\n            result |= (cur & 0x7f) << (count * 7);\n            signBits <<= 7;\n            count++;\n        } while (((cur & 0x80) == 0x80) && count < 5);\n\n        if ((cur & 0x80) == 0x80) {\n            throw new DexException(\"invalid LEB128 sequence\");\n        }\n\n        // Sign extend if appropriate\n        if (((signBits >> 1) & result) != 0 ) {\n            result |= signBits;\n        }\n\n        return result;\n    }\n\n    /**\n     * Reads an unsigned integer from {@code in}.\n     */\n    public static int readUnsignedLeb128(ByteInput in) {\n        int result = 0;\n        int cur;\n        int count = 0;\n\n        do {\n            cur = in.readByte() & 0xff;\n            result |= (cur & 0x7f) << (count * 7);\n            count++;\n        } while (((cur & 0x80) == 0x80) && count < 5);\n\n        if ((cur & 0x80) == 0x80) {\n            throw new DexException(\"invalid LEB128 sequence\");\n        }\n\n        return result;\n    }\n\n    /**\n     * Writes {@code value} as an unsigned integer to {@code out}, starting at\n     * {@code offset}. Returns the number of bytes written.\n     */\n    public static void writeUnsignedLeb128(ByteOutput out, int value) {\n        int remaining = value >>> 7;\n\n        while (remaining != 0) {\n            out.writeByte((byte) ((value & 0x7f) | 0x80));\n            value = remaining;\n            remaining >>>= 7;\n        }\n\n        out.writeByte((byte) (value & 0x7f));\n    }\n\n    /**\n     * Writes {@code value} as a signed integer to {@code out}, starting at\n     * {@code offset}. Returns the number of bytes written.\n     */\n    public static void writeSignedLeb128(ByteOutput out, int value) {\n        int remaining = value >> 7;\n        boolean hasMore = true;\n        int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;\n\n        while (hasMore) {\n            hasMore = (remaining != end)\n                    || ((remaining & 1) != ((value >> 6) & 1));\n\n            out.writeByte((byte) ((value & 0x7f) | (hasMore ? 0x80 : 0)));\n            value = remaining;\n            remaining >>= 7;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/MethodId.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\nimport com.taobao.android.dex.util.Unsigned;\n\npublic final class MethodId implements Comparable<MethodId> {\n    private final Dex dex;\n    private final int declaringClassIndex;\n    private final int protoIndex;\n    private final int nameIndex;\n\n    public MethodId(Dex dex, int declaringClassIndex, int protoIndex, int nameIndex) {\n        this.dex = dex;\n        this.declaringClassIndex = declaringClassIndex;\n        this.protoIndex = protoIndex;\n        this.nameIndex = nameIndex;\n    }\n\n    public int getDeclaringClassIndex() {\n        return declaringClassIndex;\n    }\n\n    public int getProtoIndex() {\n        return protoIndex;\n    }\n\n    public int getNameIndex() {\n        return nameIndex;\n    }\n\n    public int compareTo(MethodId other) {\n        if (declaringClassIndex != other.declaringClassIndex) {\n            return Unsigned.compare(declaringClassIndex, other.declaringClassIndex);\n        }\n        if (nameIndex != other.nameIndex) {\n            return Unsigned.compare(nameIndex, other.nameIndex);\n        }\n        return Unsigned.compare(protoIndex, other.protoIndex);\n    }\n\n    public void writeTo(Dex.Section out) {\n        out.writeUnsignedShort(declaringClassIndex);\n        out.writeUnsignedShort(protoIndex);\n        out.writeInt(nameIndex);\n    }\n\n    @Override public String toString() {\n        if (dex == null) {\n            return declaringClassIndex + \" \" + protoIndex + \" \" + nameIndex;\n        }\n        return dex.typeNames().get(declaringClassIndex)\n                + \".\" + dex.strings().get(nameIndex)\n                + dex.readTypeList(dex.protoIds().get(protoIndex).getParametersOffset());\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/Mutf8.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\nimport com.taobao.android.dex.util.ByteInput;\nimport java.io.UTFDataFormatException;\n\n/**\n * Modified UTF-8 as described in the dex file format spec.\n *\n * <p>Derived from libcore's MUTF-8 encoder at java.nio.charset.ModifiedUtf8.\n */\npublic final class Mutf8 {\n    private Mutf8() {}\n\n    /**\n     * Decodes bytes from {@code in} into {@code out} until a delimiter 0x00 is\n     * encountered. Returns a new string containing the decoded characters.\n     */\n    public static String decode(ByteInput in, char[] out) throws UTFDataFormatException {\n        int s = 0;\n        while (true) {\n            char a = (char) (in.readByte() & 0xff);\n            if (a == 0) {\n                return new String(out, 0, s);\n            }\n            out[s] = a;\n            if (a < '\\u0080') {\n                s++;\n            } else if ((a & 0xe0) == 0xc0) {\n                int b = in.readByte() & 0xff;\n                if ((b & 0xC0) != 0x80) {\n                    throw new UTFDataFormatException(\"bad second byte\");\n                }\n                out[s++] = (char) (((a & 0x1F) << 6) | (b & 0x3F));\n            } else if ((a & 0xf0) == 0xe0) {\n                int b = in.readByte() & 0xff;\n                int c = in.readByte() & 0xff;\n                if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80)) {\n                    throw new UTFDataFormatException(\"bad second or third byte\");\n                }\n                out[s++] = (char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F));\n            } else {\n                throw new UTFDataFormatException(\"bad byte\");\n            }\n        }\n    }\n\n    /**\n     * Returns the number of bytes the modified UTF8 representation of 's' would take.\n     */\n    private static long countBytes(String s, boolean shortLength) throws UTFDataFormatException {\n        long result = 0;\n        final int length = s.length();\n        for (int i = 0; i < length; ++i) {\n            char ch = s.charAt(i);\n            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.\n                ++result;\n            } else if (ch <= 2047) {\n                result += 2;\n            } else {\n                result += 3;\n            }\n            if (shortLength && result > 65535) {\n                throw new UTFDataFormatException(\"String more than 65535 UTF bytes long\");\n            }\n        }\n        return result;\n    }\n\n    /**\n     * Encodes the modified UTF-8 bytes corresponding to {@code s} into  {@code\n     * dst}, starting at {@code offset}.\n     */\n    public static void encode(byte[] dst, int offset, String s) {\n        final int length = s.length();\n        for (int i = 0; i < length; i++) {\n            char ch = s.charAt(i);\n            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.\n                dst[offset++] = (byte) ch;\n            } else if (ch <= 2047) {\n                dst[offset++] = (byte) (0xc0 | (0x1f & (ch >> 6)));\n                dst[offset++] = (byte) (0x80 | (0x3f & ch));\n            } else {\n                dst[offset++] = (byte) (0xe0 | (0x0f & (ch >> 12)));\n                dst[offset++] = (byte) (0x80 | (0x3f & (ch >> 6)));\n                dst[offset++] = (byte) (0x80 | (0x3f & ch));\n            }\n        }\n    }\n\n    /**\n     * Returns an array containing the <i>modified UTF-8</i> form of {@code s}.\n     */\n    public static byte[] encode(String s) throws UTFDataFormatException {\n        int utfCount = (int) countBytes(s, true);\n        byte[] result = new byte[utfCount];\n        encode(result, 0, s);\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/ProtoId.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\nimport com.taobao.android.dex.util.Unsigned;\n\npublic final class ProtoId implements Comparable<ProtoId> {\n    private final Dex dex;\n    private final int shortyIndex;\n    private final int returnTypeIndex;\n    private final int parametersOffset;\n\n    public ProtoId(Dex dex, int shortyIndex, int returnTypeIndex, int parametersOffset) {\n        this.dex = dex;\n        this.shortyIndex = shortyIndex;\n        this.returnTypeIndex = returnTypeIndex;\n        this.parametersOffset = parametersOffset;\n    }\n\n    public int compareTo(ProtoId other) {\n        if (returnTypeIndex != other.returnTypeIndex) {\n            return Unsigned.compare(returnTypeIndex, other.returnTypeIndex);\n        }\n        return Unsigned.compare(parametersOffset, other.parametersOffset);\n    }\n\n    public int getShortyIndex() {\n        return shortyIndex;\n    }\n\n    public int getReturnTypeIndex() {\n        return returnTypeIndex;\n    }\n\n    public int getParametersOffset() {\n        return parametersOffset;\n    }\n\n    public void writeTo(Dex.Section out) {\n        out.writeInt(shortyIndex);\n        out.writeInt(returnTypeIndex);\n        out.writeInt(parametersOffset);\n    }\n\n    @Override public String toString() {\n        if (dex == null) {\n            return shortyIndex + \" \" + returnTypeIndex + \" \" + parametersOffset;\n        }\n\n        return dex.strings().get(shortyIndex)\n                + \": \" + dex.typeNames().get(returnTypeIndex)\n                + \" \" + dex.readTypeList(parametersOffset);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/SizeOf.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\npublic final class SizeOf {\n    private SizeOf() {}\n\n    public static final int UBYTE = 1;\n    public static final int USHORT = 2;\n    public static final int UINT = 4;\n\n    public static final int SIGNATURE = UBYTE * 20;\n\n    /**\n     * magic ubyte[8]\n     * checksum uint\n     * signature ubyte[20]\n     * file_size uint\n     * header_size uint\n     * endian_tag uint\n     * link_size uint\n     * link_off uint\n     * map_off uint\n     * string_ids_size uint\n     * string_ids_off uint\n     * type_ids_size uint\n     * type_ids_off uint\n     * proto_ids_size uint\n     * proto_ids_off uint\n     * field_ids_size uint\n     * field_ids_off uint\n     * method_ids_size uint\n     * method_ids_off uint\n     * class_defs_size uint\n     * class_defs_off uint\n     * data_size uint\n     * data_off uint\n     */\n    public static final int HEADER_ITEM = (8 * UBYTE) + UINT + SIGNATURE + (20 * UINT); // 0x70\n\n    /**\n     * string_data_off uint\n     */\n    public static final int STRING_ID_ITEM = UINT;\n\n    /**\n     * descriptor_idx uint\n     */\n    public static final int TYPE_ID_ITEM = UINT;\n\n    /**\n     * type_idx ushort\n     */\n    public static final int TYPE_ITEM = USHORT;\n\n    /**\n     * shorty_idx uint\n     * return_type_idx uint\n     * return_type_idx uint\n     */\n    public static final int PROTO_ID_ITEM = UINT + UINT + UINT;\n\n    /**\n     * class_idx ushort\n     * type_idx/proto_idx ushort\n     * name_idx uint\n     */\n    public static final int MEMBER_ID_ITEM = USHORT + USHORT + UINT;\n\n    /**\n     * class_idx uint\n     * access_flags uint\n     * superclass_idx uint\n     * interfaces_off uint\n     * source_file_idx uint\n     * annotations_off uint\n     * class_data_off uint\n     * static_values_off uint\n     */\n    public static final int CLASS_DEF_ITEM = 8 * UINT;\n\n    /**\n     * type ushort\n     * unused ushort\n     * size uint\n     * offset uint\n     */\n    public static final int MAP_ITEM = USHORT + USHORT + UINT + UINT;\n\n    /**\n     * start_addr uint\n     * insn_count ushort\n     * handler_off ushort\n     */\n    public static final int TRY_ITEM = UINT + USHORT + USHORT;\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/TableOfContents.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\nimport java.io.IOException;\nimport java.io.UnsupportedEncodingException;\nimport java.util.Arrays;\n\n/**\n * The file header and map.\n */\npublic final class TableOfContents {\n\n    /*\n     * TODO: factor out ID constants.\n     */\n\n    public final Section header = new Section(0x0000);\n    public final Section stringIds = new Section(0x0001);\n    public final Section typeIds = new Section(0x0002);\n    public final Section protoIds = new Section(0x0003);\n    public final Section fieldIds = new Section(0x0004);\n    public final Section methodIds = new Section(0x0005);\n    public final Section classDefs = new Section(0x0006);\n    public final Section mapList = new Section(0x1000);\n    public final Section typeLists = new Section(0x1001);\n    public final Section annotationSetRefLists = new Section(0x1002);\n    public final Section annotationSets = new Section(0x1003);\n    public final Section classDatas = new Section(0x2000);\n    public final Section codes = new Section(0x2001);\n    public final Section stringDatas = new Section(0x2002);\n    public final Section debugInfos = new Section(0x2003);\n    public final Section annotations = new Section(0x2004);\n    public final Section encodedArrays = new Section(0x2005);\n    public final Section annotationsDirectories = new Section(0x2006);\n    public final Section[] sections = {\n            header, stringIds, typeIds, protoIds, fieldIds, methodIds, classDefs, mapList,\n            typeLists, annotationSetRefLists, annotationSets, classDatas, codes, stringDatas,\n            debugInfos, annotations, encodedArrays, annotationsDirectories\n    };\n\n    public int checksum;\n    public byte[] signature;\n    public int fileSize;\n    public int linkSize;\n    public int linkOff;\n    public int dataSize;\n    public int dataOff;\n\n    public TableOfContents() {\n        signature = new byte[20];\n    }\n\n    public void readFrom(Dex dex) throws IOException {\n        readHeader(dex.open(0));\n        readMap(dex.open(mapList.off));\n        computeSizesFromOffsets();\n    }\n\n    private void readHeader(Dex.Section headerIn) throws UnsupportedEncodingException {\n        byte[] magic = headerIn.readByteArray(8);\n        int apiTarget = DexFormat.magicToApi(magic);\n\n        if (apiTarget != DexFormat.API_NO_EXTENDED_OPCODES) {\n            throw new DexException(\"Unexpected magic: \" + Arrays.toString(magic));\n        }\n\n        checksum = headerIn.readInt();\n        signature = headerIn.readByteArray(20);\n        fileSize = headerIn.readInt();\n        int headerSize = headerIn.readInt();\n        if (headerSize != SizeOf.HEADER_ITEM) {\n            throw new DexException(\"Unexpected header: 0x\" + Integer.toHexString(headerSize));\n        }\n        int endianTag = headerIn.readInt();\n        if (endianTag != DexFormat.ENDIAN_TAG) {\n            throw new DexException(\"Unexpected endian tag: 0x\" + Integer.toHexString(endianTag));\n        }\n        linkSize = headerIn.readInt();\n        linkOff = headerIn.readInt();\n        mapList.off = headerIn.readInt();\n        if (mapList.off == 0) {\n            throw new DexException(\"Cannot merge dex files that do not contain a map\");\n        }\n        stringIds.size = headerIn.readInt();\n        stringIds.off = headerIn.readInt();\n        typeIds.size = headerIn.readInt();\n        typeIds.off = headerIn.readInt();\n        protoIds.size = headerIn.readInt();\n        protoIds.off = headerIn.readInt();\n        fieldIds.size = headerIn.readInt();\n        fieldIds.off = headerIn.readInt();\n        methodIds.size = headerIn.readInt();\n        methodIds.off = headerIn.readInt();\n        classDefs.size = headerIn.readInt();\n        classDefs.off = headerIn.readInt();\n        dataSize = headerIn.readInt();\n        dataOff = headerIn.readInt();\n    }\n\n    private void readMap(Dex.Section in) throws IOException {\n        int mapSize = in.readInt();\n        Section previous = null;\n        for (int i = 0; i < mapSize; i++) {\n            short type = in.readShort();\n            in.readShort(); // unused\n            Section section = getSection(type);\n            int size = in.readInt();\n            int offset = in.readInt();\n\n            if ((section.size != 0 && section.size != size)\n                    || (section.off != -1 && section.off != offset)) {\n                throw new DexException(\"Unexpected map value for 0x\" + Integer.toHexString(type));\n            }\n\n            section.size = size;\n            section.off = offset;\n\n            if (previous != null && previous.off > section.off) {\n                throw new DexException(\"Map is unsorted at \" + previous + \", \" + section);\n            }\n\n            previous = section;\n        }\n        Arrays.sort(sections);\n    }\n\n    public void computeSizesFromOffsets() {\n        int end = dataOff + dataSize;\n        for (int i = sections.length - 1; i >= 0; i--) {\n            Section section = sections[i];\n            if (section.off == -1) {\n                continue;\n            }\n            if (section.off > end) {\n                throw new DexException(\"Map is unsorted at \" + section);\n            }\n            section.byteCount = end - section.off;\n            end = section.off;\n        }\n    }\n\n    private Section getSection(short type) {\n        for (Section section : sections) {\n            if (section.type == type) {\n                return section;\n            }\n        }\n        throw new IllegalArgumentException(\"No such map item: \" + type);\n    }\n\n    public void writeHeader(Dex.Section out) throws IOException {\n        out.write(DexFormat.apiToMagic(DexFormat.API_NO_EXTENDED_OPCODES).getBytes(\"UTF-8\"));\n        out.writeInt(checksum);\n        out.write(signature);\n        out.writeInt(fileSize);\n        out.writeInt(SizeOf.HEADER_ITEM);\n        out.writeInt(DexFormat.ENDIAN_TAG);\n        out.writeInt(linkSize);\n        out.writeInt(linkOff);\n        out.writeInt(mapList.off);\n        out.writeInt(stringIds.size);\n        out.writeInt(stringIds.off);\n        out.writeInt(typeIds.size);\n        out.writeInt(typeIds.off);\n        out.writeInt(protoIds.size);\n        out.writeInt(protoIds.off);\n        out.writeInt(fieldIds.size);\n        out.writeInt(fieldIds.off);\n        out.writeInt(methodIds.size);\n        out.writeInt(methodIds.off);\n        out.writeInt(classDefs.size);\n        out.writeInt(classDefs.off);\n        out.writeInt(dataSize);\n        out.writeInt(dataOff);\n    }\n\n    public void writeMap(Dex.Section out) throws IOException {\n        int count = 0;\n        for (Section section : sections) {\n            if (section.exists()) {\n                count++;\n            }\n        }\n\n        out.writeInt(count);\n        for (Section section : sections) {\n            if (section.exists()) {\n                out.writeShort(section.type);\n                out.writeShort((short) 0);\n                out.writeInt(section.size);\n                out.writeInt(section.off);\n            }\n        }\n    }\n\n    public static class Section implements Comparable<Section> {\n        public final short type;\n        public int size = 0;\n        public int off = -1;\n        public int byteCount = 0;\n\n        public Section(int type) {\n            this.type = (short) type;\n        }\n\n        public boolean exists() {\n            return size > 0;\n        }\n\n        public int compareTo(Section section) {\n            if (off != section.off) {\n                return off < section.off ? -1 : 1;\n            }\n            return 0;\n        }\n\n        @Override public String toString() {\n            return String.format(\"Section[type=%#x,off=%#x,size=%#x]\", type, off, size);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/TypeList.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex;\n\nimport com.taobao.android.dex.util.Unsigned;\n\npublic final class TypeList implements Comparable<TypeList> {\n\n    public static final TypeList EMPTY = new TypeList(null, Dex.EMPTY_SHORT_ARRAY);\n\n    private final Dex dex;\n    private final short[] types;\n\n    public TypeList(Dex dex, short[] types) {\n        this.dex = dex;\n        this.types = types;\n    }\n\n    public short[] getTypes() {\n        return types;\n    }\n\n    @Override public int compareTo(TypeList other) {\n        for (int i = 0; i < types.length && i < other.types.length; i++) {\n            if (types[i] != other.types[i]) {\n                return Unsigned.compare(types[i], other.types[i]);\n            }\n        }\n        return Unsigned.compare(types.length, other.types.length);\n    }\n\n    @Override public String toString() {\n        StringBuilder result = new StringBuilder();\n        result.append(\"(\");\n        for (int i = 0, typesLength = types.length; i < typesLength; i++) {\n            result.append(dex != null ? dex.typeNames().get(types[i]) : types[i]);\n        }\n        result.append(\")\");\n        return result.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/util/ByteArrayByteInput.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex.util;\n\npublic final class ByteArrayByteInput implements ByteInput {\n\n    private final byte[] bytes;\n    private int position;\n\n    public ByteArrayByteInput(byte... bytes) {\n        this.bytes = bytes;\n    }\n\n    @Override public byte readByte() {\n        return bytes[position++];\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/util/ByteInput.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex.util;\n\n/**\n * A byte source.\n */\npublic interface ByteInput {\n\n    /**\n     * Returns a byte.\n     *\n     * @throws IndexOutOfBoundsException if all bytes have been read.\n     */\n    byte readByte();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/util/ByteOutput.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex.util;\n\n/**\n * A byte sink.\n */\npublic interface ByteOutput {\n\n    /**\n     * Writes a byte.\n     *\n     * @throws IndexOutOfBoundsException if all bytes have been written.\n     */\n    void writeByte(int i);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/util/ExceptionWithContext.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex.util;\n\nimport java.io.PrintStream;\nimport java.io.PrintWriter;\n\n/**\n * Exception which carries around structured context.\n */\npublic class ExceptionWithContext extends RuntimeException {\n    /** {@code non-null;} human-oriented context of the exception */\n    private StringBuffer context;\n\n    /**\n     * Augments the given exception with the given context, and return the\n     * result. The result is either the given exception if it was an\n     * {@link ExceptionWithContext}, or a newly-constructed exception if it\n     * was not.\n     *\n     * @param ex {@code non-null;} the exception to augment\n     * @param str {@code non-null;} context to add\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static ExceptionWithContext withContext(Throwable ex, String str) {\n        ExceptionWithContext ewc;\n\n        if (ex instanceof ExceptionWithContext) {\n            ewc = (ExceptionWithContext) ex;\n        } else {\n            ewc = new ExceptionWithContext(ex);\n        }\n\n        ewc.addContext(str);\n        return ewc;\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param message human-oriented message\n     */\n    public ExceptionWithContext(String message) {\n        this(message, null);\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param cause {@code null-ok;} exception that caused this one\n     */\n    public ExceptionWithContext(Throwable cause) {\n        this(null, cause);\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param message human-oriented message\n     * @param cause {@code null-ok;} exception that caused this one\n     */\n    public ExceptionWithContext(String message, Throwable cause) {\n        super((message != null) ? message :\n              (cause != null) ? cause.getMessage() : null,\n              cause);\n\n        if (cause instanceof ExceptionWithContext) {\n            String ctx = ((ExceptionWithContext) cause).context.toString();\n            context = new StringBuffer(ctx.length() + 200);\n            context.append(ctx);\n        } else {\n            context = new StringBuffer(200);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void printStackTrace(PrintStream out) {\n        super.printStackTrace(out);\n        out.println(context);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void printStackTrace(PrintWriter out) {\n        super.printStackTrace(out);\n        out.println(context);\n    }\n\n    /**\n     * Adds a line of context to this instance.\n     *\n     * @param str {@code non-null;} new context\n     */\n    public void addContext(String str) {\n        if (str == null) {\n            throw new NullPointerException(\"str == null\");\n        }\n\n        context.append(str);\n        if (!str.endsWith(\"\\n\")) {\n            context.append('\\n');\n        }\n    }\n\n    /**\n     * Gets the context.\n     *\n     * @return {@code non-null;} the context\n     */\n    public String getContext() {\n        return context.toString();\n    }\n\n    /**\n     * Prints the message and context.\n     *\n     * @param out {@code non-null;} where to print to\n     */\n    public void printContext(PrintStream out) {\n        out.println(getMessage());\n        out.print(context);\n    }\n\n    /**\n     * Prints the message and context.\n     *\n     * @param out {@code non-null;} where to print to\n     */\n    public void printContext(PrintWriter out) {\n        out.println(getMessage());\n        out.print(context);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/util/FileUtils.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex.util;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\n\n/**\n * File I/O utilities.\n */\npublic final class FileUtils {\n    private FileUtils() {\n    }\n\n    /**\n     * Reads the named file, translating {@link IOException} to a\n     * {@link RuntimeException} of some sort.\n     *\n     * @param fileName {@code non-null;} name of the file to read\n     * @return {@code non-null;} contents of the file\n     */\n    public static byte[] readFile(String fileName) {\n        File file = new File(fileName);\n        return readFile(file);\n    }\n\n    /**\n     * Reads the given file, translating {@link IOException} to a\n     * {@link RuntimeException} of some sort.\n     *\n     * @param file {@code non-null;} the file to read\n     * @return {@code non-null;} contents of the file\n     */\n    public static byte[] readFile(File file) {\n        if (!file.exists()) {\n            throw new RuntimeException(file + \": file not found\");\n        }\n\n        if (!file.isFile()) {\n            throw new RuntimeException(file + \": not a file\");\n        }\n\n        if (!file.canRead()) {\n            throw new RuntimeException(file + \": file not readable\");\n        }\n\n        long longLength = file.length();\n        int length = (int) longLength;\n        if (length != longLength) {\n            throw new RuntimeException(file + \": file too long\");\n        }\n\n        byte[] result = new byte[length];\n\n        try {\n            FileInputStream in = new FileInputStream(file);\n            int at = 0;\n            while (length > 0) {\n                int amt = in.read(result, at, length);\n                if (amt == -1) {\n                    throw new RuntimeException(file + \": unexpected EOF\");\n                }\n                at += amt;\n                length -= amt;\n            }\n            in.close();\n        } catch (IOException ex) {\n            throw new RuntimeException(file + \": trouble reading\", ex);\n        }\n\n        return result;\n    }\n\n    /**\n     * Returns true if {@code fileName} names a .zip, .jar, or .apk.\n     */\n    public static boolean hasArchiveSuffix(String fileName) {\n        return fileName.endsWith(\".zip\")\n                || fileName.endsWith(\".jar\")\n                || fileName.endsWith(\".apk\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dex/util/Unsigned.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dex.util;\n\n/**\n * Unsigned arithmetic over Java's signed types.\n */\npublic final class Unsigned {\n    private Unsigned() {}\n\n    public static int compare(short ushortA, short ushortB) {\n        if (ushortA == ushortB) {\n            return 0;\n        }\n        int a = ushortA & 0xFFFF;\n        int b = ushortB & 0xFFFF;\n        return a < b ? -1 : 1;\n    }\n\n    public static int compare(int uintA, int uintB) {\n        if (uintA == uintB) {\n            return 0;\n        }\n        long a = uintA & 0xFFFFFFFFL;\n        long b = uintB & 0xFFFFFFFFL;\n        return a < b ? -1 : 1;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/differ/dex/ApkDiff.java",
    "content": "package com.taobao.android.differ.dex;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * @author lilong\n * @create 2017-03-22 下午7:39\n */\n\npublic class ApkDiff implements Serializable {\n    private String baseApkVersion;\n\n    public String getBaseApkVersion() {\n        return baseApkVersion;\n    }\n\n    public void setBaseApkVersion(String baseApkVersion) {\n        this.baseApkVersion = baseApkVersion;\n    }\n\n    public String getNewApkVersion() {\n        return newApkVersion;\n    }\n\n    public void setNewApkVersion(String newApkVersion) {\n        this.newApkVersion = newApkVersion;\n    }\n\n    public String getNewApkMd5() {\n        return newApkMd5;\n    }\n\n    public void setNewApkMd5(String newApkMd5) {\n        this.newApkMd5 = newApkMd5;\n    }\n\n    public String getFileName() {\n        return fileName;\n    }\n\n    public void setFileName(String fileName) {\n        this.fileName = fileName;\n    }\n\n    public List<BundleDiffResult> getBundleDiffResults() {\n        return bundleDiffResults;\n    }\n\n    public void setBundleDiffResults(List<BundleDiffResult> bundleDiffResults) {\n        this.bundleDiffResults = bundleDiffResults;\n    }\n\n    private String newApkVersion;\n    private String newApkMd5;\n    private String fileName;\n    private List<BundleDiffResult>bundleDiffResults = new ArrayList<>();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/differ/dex/BundleDiffResult.java",
    "content": "package com.taobao.android.differ.dex;\n\nimport com.taobao.android.object.DiffType;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * @author lilong\n * @create 2017-03-22 下午7:02\n */\n\npublic class BundleDiffResult implements Serializable {\n\n    private String bundleName;\n\n    public String getBundleName() {\n        return bundleName;\n    }\n\n    public void setBundleName(String bundleName) {\n        this.bundleName = bundleName;\n    }\n\n    public void setClassDiffs(List<ClassDiff> classDiffs) {\n        this.classDiffs = classDiffs;\n    }\n\n    public List<ClassDiff> getClassDiffs() {\n        return classDiffs;\n    }\n\n    private List<ClassDiff>classDiffs = new ArrayList<>();\n\n    public static class ClassDiff implements Serializable{\n        private String className;\n\n        private DiffType diffType;\n\n        private List<MethodDiff>methodDiffs = new ArrayList<>();\n\n        public String getClassName() {\n            return className;\n        }\n\n        public void setClassName(String className) {\n            this.className = className;\n        }\n\n        public DiffType getDiffType() {\n            return diffType;\n        }\n\n        public void setDiffType(DiffType diffType) {\n            this.diffType = diffType;\n        }\n\n        public List<MethodDiff> getMethodDiffs() {\n            return methodDiffs;\n        }\n\n        public void setMethodDiffs(List<MethodDiff> methodDiffs) {\n            this.methodDiffs = methodDiffs;\n        }\n\n        public List<FieldDiff> getFieldDiffs() {\n            return fieldDiffs;\n        }\n\n        public void setFieldDiffs(List<FieldDiff> fieldDiffs) {\n            this.fieldDiffs = fieldDiffs;\n        }\n\n        private List<FieldDiff>fieldDiffs = new ArrayList<>();\n\n    }\n\n    public static class MethodDiff implements Serializable{\n        private String methodDesc;\n\n        public String getMethodDesc() {\n            return methodDesc;\n        }\n\n        public void setMethodDesc(String methodDesc) {\n            this.methodDesc = methodDesc;\n        }\n\n        public DiffType getDiffType() {\n            return diffType;\n        }\n\n        public void setDiffType(DiffType diffType) {\n            this.diffType = diffType;\n        }\n\n        private DiffType diffType;\n    }\n\n    public static class FieldDiff implements Serializable{\n        private String fieldDesc;\n\n        public String getFieldDesc() {\n            return fieldDesc;\n        }\n\n        public void setFieldDesc(String fieldDesc) {\n            this.fieldDesc = fieldDesc;\n        }\n\n        public DiffType getDiffType() {\n            return diffType;\n        }\n\n        public void setDiffType(DiffType diffType) {\n            this.diffType = diffType;\n        }\n\n        private DiffType diffType;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/differ/dex/DexDiffer.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.differ.dex;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.google.common.base.Objects;\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Maps;\nimport com.google.common.collect.Sets;\nimport com.taobao.android.filter.DexDiffFilter;\nimport com.taobao.android.filter.Filter;\nimport com.taobao.android.object.*;\nimport com.taobao.android.utils.DexCompareUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.jf.dexlib2.DexFileFactory;\nimport org.jf.dexlib2.Opcodes;\nimport org.jf.dexlib2.dexbacked.*;\nimport org.jf.dexlib2.iface.Annotation;\nimport org.jf.dexlib2.iface.value.EncodedValue;\nimport org.jf.dexlib2.util.ReferenceUtil;\n\nimport javax.annotation.Nullable;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.function.Consumer;\n\npublic class DexDiffer {\n\n    private List<File> baseDexFiles = Lists.newArrayList();\n    private List<File> newDexFiles = Lists.newArrayList();\n    private int apiLevel;\n\n    public String getNoPatchDexNum() {\n        return noPatchDexNum;\n    }\n\n    private String noPatchDexNum;\n\n    private static final String NO_PATCH_DEX = \"NO_PATCH_DEX\";\n\n\n    private static final String PATCH_VERSION = \"PATCH_VERSION\";\n\n\n    public boolean isNewPatch() {\n        return newPatch;\n    }\n\n    public void setNewPatch(boolean newPatch) {\n        this.newPatch = newPatch;\n    }\n\n    private boolean newPatch = true;\n\n\n    private Map<String, org.jf.dexlib2.iface.ClassDef>lastBundleClassMap = new HashMap<String, org.jf.dexlib2.iface.ClassDef>();\n    private DexDiffInfo dexDiffInfo = new DexDiffInfo();\n\n    public List<DiffClass> getDiffClasses() {\n        return diffClasses;\n    }\n\n    private List<DiffClass>diffClasses = new ArrayList<>();\n\n    public Set<String> getExludeClasses() {\n        return exludeClasses;\n    }\n\n    public void setExludeClasses(Set<String> exludeClasses) {\n        this.exludeClasses = exludeClasses;\n    }\n\n    private Set<String>exludeClasses = new HashSet<>();\n\n    public Set<String> getPatchClasses() {\n        return patchClasses;\n    }\n\n    public void setPatchClasses(Set<String> patchClasses) {\n        this.patchClasses = patchClasses;\n    }\n\n    private Set<String>patchClasses = new HashSet<>();\n\n    //dex filter\n    private DexDiffFilter dexDiffFilter;\n    //\n    private Filter filter;\n\n    public void setTpatch(boolean tpatch) {\n        this.tpatch = tpatch;\n    }\n\n    private boolean tpatch;\n\n    private Map<String, DexBackedClassDef> baseClassDefMap = new HashMap<String, DexBackedClassDef>();\n\n    public DexDiffer(List<File> baseDexFiles, List<File> newDexFiles, int apiLevel) {\n        this.baseDexFiles = baseDexFiles;\n        this.newDexFiles = newDexFiles;\n        this.apiLevel = apiLevel;\n    }\n\n    public DexDiffer(File baseDex, File newDex, int apiLevel) {\n        baseDexFiles.add(baseDex);\n        newDexFiles.add(newDex);\n        this.apiLevel = apiLevel;\n    }\n\n\n    public void setDexDiffFilter(DexDiffFilter dexDiffFilter) {\n        this.dexDiffFilter = dexDiffFilter;\n    }\n\n    public void setLastBundleClassMap(Map<String, org.jf.dexlib2.iface.ClassDef> map){\n        this.lastBundleClassMap = map;\n    }\n\n\n    public void createFilter(String filterPath) {\n        this.filter = new Filter(filterPath);\n    }\n\n\n    /**\n     * 获取二个dex文件的diff差异\n     *\n     * @return\n     */\n    public DexDiffInfo doDiff() throws IOException, PatchException {\n        scanBaseDexFile();\n        Set<DexBackedClassDef> newDexClassDefs = Sets.newHashSet();\n        for (File newDexFile : newDexFiles) {\n            DexBackedDexFile newBackedDexFile = DexFileFactory.loadDexFile(newDexFile, Opcodes.getDefault());\n            newDexClassDefs.addAll(newBackedDexFile.getClasses());\n            dexDiffInfo.setNewClasses(newDexClassDefs);\n        }\n        for (DexBackedClassDef newClassDef : newDexClassDefs) {\n            if (filter != null) {\n                if (filter.isFiltered(newClassDef.getType())) {\n                    System.out.println(\"filter class:\"+newClassDef.getType());\n                    continue;\n                }\n            }\n            String className = getDalvikClassName(newClassDef.getType());\n            if (!tpatch&&exludeClasses.contains(newClassDef.getType())){\n                continue;\n            }\n\n            if (!tpatch&&patchClasses.size() > 0 && !patchClasses.contains(newClassDef.getType())){\n                continue;\n            }\n\n            if (!tpatch &&(newClassDef.getType().contains(\"/R$\")||newClassDef.getType().contains(\"/R;\"))){\n                continue;\n            }\n            DexBackedClassDef baseClassDef = baseClassDefMap.get(className);\n            ClassDiffInfo classDiffInfo = compareClassDef(baseClassDef, newClassDef);\n            if (DiffType.MODIFY.equals(classDiffInfo.getType())){\n                DiffClass diffClass = new DiffClass(baseClassDef.getType(),dexDiffInfo.getBaseClassDefNum(baseClassDef));\n                diffClasses.add(diffClass);\n                dexDiffInfo.getClassDiffInfoMap().put(className, classDiffInfo);\n            } else if (DiffType.ADD.equals(classDiffInfo.getType())) {\n                dexDiffInfo.getClassDiffInfoMap().put(className, classDiffInfo);\n            }else if (DiffType.NONE.equals(classDiffInfo.getType())){\n                if (lastBundleClassMap.containsKey(newClassDef.getType())&&tpatch){\n                    System.out.println(\"overide class:\"+className);\n//                    ClassDiffInfo classDiffInfo = new ClassDiffInfo();\n                    classDiffInfo.setType(DiffType.OVERRIDE);\n                    classDiffInfo.setClassDef(baseClassDef);\n                    dexDiffInfo.getClassDiffInfoMap().put(className,classDiffInfo);\n                    DiffClass diffClass = new DiffClass(baseClassDef.getType(),dexDiffInfo.getBaseClassDefNum(baseClassDef));\n                    diffClasses.add(diffClass);\n                }\n\n            }\n        }\n\n        if (noPatchDexNum != null){\n            diffClasses.add(new DiffClass(NO_PATCH_DEX,Integer.valueOf(noPatchDexNum)));\n        }\n\n        diffClasses.add(new DiffClass(PATCH_VERSION,newPatch ? 2:1));\n        return dexDiffInfo;\n    }\n\n\n\n    public void dexFilter() throws PatchException {\n        if (dexDiffFilter != null) {\n            dexDiffFilter.filterDex();\n        }\n\n    }\n\n    /**\n     * scan base Dex,get base Dex info\n     */\n    private void scanBaseDexFile() throws IOException {\n        for (File baseDexFile : baseDexFiles) {\n            String s = baseDexFile.getName().substring(7);\n            String dexNum = s.startsWith(\".\")? \"0\":s.substring(0,s.indexOf(\".\"));\n            DexBackedDexFile baseBackedDexFile = DexFileFactory.loadDexFile(baseDexFile, Opcodes.getDefault());\n            final Set<? extends DexBackedClassDef> baseClassDefs = baseBackedDexFile.getClasses();\n            baseClassDefs.forEach(new Consumer<DexBackedClassDef>() {\n                @Override\n                public void accept(DexBackedClassDef dexBackedClassDef) {\n                    if (dexBackedClassDef.getType().equals(\"Lcom/ali/mobisecenhance/ReflectMap;\")){\n                        noPatchDexNum = dexNum;\n                    }\n                }\n            });\n            dexDiffInfo.setOldClasses(dexNum,baseClassDefs);\n            for (DexBackedClassDef baseClassDef : baseClassDefs) {\n                String className = getDalvikClassName(baseClassDef.getType());\n                baseClassDefMap.put(className, baseClassDef);\n            }\n        }\n    }\n\n    /**\n     * compare two classDef\n     *\n     * @param baseClassDef\n     * @param newClassDef\n     * @return\n     */\n    private ClassDiffInfo compareClassDef(DexBackedClassDef baseClassDef, DexBackedClassDef newClassDef) throws PatchException {\n        ClassDiffInfo classDiffInfo = new ClassDiffInfo();\n        String className = null;\n        if (null == baseClassDef && null != newClassDef) {\n            className = getDalvikClassName(newClassDef.getType());\n            classDiffInfo.setName(className);\n            classDiffInfo.setClassDef(newClassDef);\n            classDiffInfo.setType(DiffType.ADD);\n        } else if (null != baseClassDef && null == newClassDef) {\n            className = getDalvikClassName(baseClassDef.getType());\n            classDiffInfo.setName(className);\n            classDiffInfo.setClassDef(baseClassDef);\n            classDiffInfo.setType(DiffType.REMOVE);\n        } else {// 比较是否有变更\n            className = getDalvikClassName(baseClassDef.getType());\n            classDiffInfo.setName(className);\n            classDiffInfo.setClassDef(newClassDef);\n            boolean classDefModify = compareClassDef_(baseClassDef, newClassDef);\n            boolean methodDefModify = false;\n            boolean fieldDefModify = false;\n            if (classDefModify) {\n                classDiffInfo.setType(DiffType.MODIFY);\n                // 1. 比较类里面的方法\n                compareMethods(baseClassDef, newClassDef, classDiffInfo);\n                // 2. 比较类里面的字段\n                compareFields(baseClassDef, newClassDef, classDiffInfo);\n            } else {\n                // 1. 比较类里面的方法\n                methodDefModify = compareMethods(baseClassDef, newClassDef, classDiffInfo);\n                // 2. 比较类里面的字段\n                fieldDefModify = compareFields(baseClassDef, newClassDef, classDiffInfo);\n                if (methodDefModify || fieldDefModify) {\n                    classDiffInfo.setType(DiffType.MODIFY);\n                } else {\n                    classDiffInfo.setType(DiffType.NONE);\n                }\n            }\n\n        }\n        return classDiffInfo;\n    }\n\n    /**\n     * 得到这个类的字符串化的定义\n     *\n     * @param baseClassDef\n     * @param newClassDef\n     * @return 2个类的定义是否变更\n     */\n    private boolean compareClassDef_(DexBackedClassDef baseClassDef, DexBackedClassDef newClassDef) {\n        if (null == baseClassDef || null == newClassDef) {\n            return false;\n        }\n        if (baseClassDef.equals(newClassDef)) {\n            // compare access flag\n            if (baseClassDef.getAccessFlags() != newClassDef.getAccessFlags()) {\n                return true;\n            }\n            // compare super class\n            if (!StringUtils.equals(baseClassDef.getSuperclass(), newClassDef.getSuperclass())) {\n                return true;\n            }\n            // compare interfaces\n            if (!equalsImpl(baseClassDef.getInterfaces(), newClassDef.getInterfaces())) {\n                return true;\n            }\n            // compare annotations\n            if (!equalsImpl(baseClassDef.getAnnotations(), newClassDef.getAnnotations())) {\n                return true;\n            }\n            // 不考虑sourceFile\n            return false;\n        }\n        return true;\n    }\n\n    private boolean equalsImpl(Collection<?> s, @Nullable Object object) {\n        if (s == object) {\n            return true;\n        } else if (object instanceof Collection){\n            Collection o = (Collection) object;\n            try {\n                return s.size() == o.size() && s.containsAll(o);\n            } catch (NullPointerException var4) {\n                return false;\n            } catch (ClassCastException var5) {\n                return false;\n            }\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * compare two methods\n     * FIXME:\n     *\n     * @param baseClassDef\n     * @param newClassDef\n     * @param classDiffInfo\n     */\n    private boolean compareMethods(DexBackedClassDef baseClassDef, DexBackedClassDef newClassDef,\n                                   ClassDiffInfo classDiffInfo) throws PatchException {\n        Map<String, DexBackedMethod> baseMethodDefMaps = Maps.newHashMap();\n        for (DexBackedMethod dexBackedMethod : baseClassDef.getMethods()) {\n            String baseMethodDesc = ReferenceUtil.getMethodDescriptor(dexBackedMethod);\n            baseMethodDefMaps.put(baseMethodDesc, dexBackedMethod);\n        }\n        for (DexBackedMethod newMethod : newClassDef.getMethods()) {\n            MethodDiffInfo methodDiffInfo = new MethodDiffInfo();\n            String newethodDesc = ReferenceUtil.getMethodDescriptor(newMethod);\n            methodDiffInfo.setBackedMethod(newMethod);\n            DexBackedMethod baseMethod = baseMethodDefMaps.get(newethodDesc);\n            if (null == baseMethod) {\n                methodDiffInfo.setType(DiffType.ADD);\n                classDiffInfo.getModifyMethods().add(methodDiffInfo);\n                continue;\n            }\n            // TODO:\n\n            Set<? extends Annotation>newAnnotations = newMethod.getAnnotations();\n            Set<? extends Annotation>baseAnnotations = baseMethod.getAnnotations();\n            int newAcc = newMethod.getAccessFlags();\n            int baseAcc = baseMethod.getAccessFlags();\n\n            DexBackedMethodImplementation newMethodImplementation = newMethod.getImplementation();\n            DexBackedMethodImplementation baseMethodImplementation = baseMethod.getImplementation();\n            if (!DexCompareUtils.compareMethod(newMethodImplementation, baseMethodImplementation)||\n                    !equalsImpl(baseAnnotations,newAnnotations)||newAcc!=baseAcc) {\n                methodDiffInfo.setType(DiffType.MODIFY);\n                classDiffInfo.getModifyMethods().add(methodDiffInfo);\n\n            }\n            baseMethodDefMaps.remove(newethodDesc);\n        }\n        // 如果方法已经移除\n        if (baseMethodDefMaps.size() > 0) {\n            for (Map.Entry<String, DexBackedMethod> entry : baseMethodDefMaps.entrySet()) {\n                MethodDiffInfo methodDiffInfo = new MethodDiffInfo();\n                methodDiffInfo.setType(DiffType.REMOVE);\n                methodDiffInfo.setBackedMethod(entry.getValue());\n                classDiffInfo.getModifyMethods().add(methodDiffInfo);\n            }\n        }\n        if (classDiffInfo.getModifyMethods().size() > 0) {\n            return true;\n        }\n        return false;\n    }\n\n\n    /**\n     * compare filed in two dex Files\n     *\n     * @param baseClassDef\n     * @param newClassDef\n     * @param classDiffInfo\n     */\n    private boolean compareFields(DexBackedClassDef baseClassDef, DexBackedClassDef newClassDef,\n                                  ClassDiffInfo classDiffInfo) throws PatchException {\n        Map<String, DexBackedField> baseFieldMaps = Maps.newHashMap();\n        for (DexBackedField backedField : baseClassDef.getFields()) {\n            baseFieldMaps.put(ReferenceUtil.getFieldDescriptor(backedField), backedField);\n        }\n        for (DexBackedField newField : newClassDef.getFields()) {\n            FieldDiffInfo fieldDiffInfo = new FieldDiffInfo();\n            fieldDiffInfo.setBackedField(newField);\n            String fieldDesc = ReferenceUtil.getFieldDescriptor(newField);\n            DexBackedField baseField = baseFieldMaps.get(fieldDesc);\n            if (null == baseField) {\n                fieldDiffInfo.setType(DiffType.ADD);\n                classDiffInfo.getModifyFields().add(fieldDiffInfo);\n                continue;\n            }\n\n\n            // init value\n            EncodedValue baseInitaValue = baseField.getInitialValue();\n            EncodedValue newInitaValue = newField.getInitialValue();\n            if (!Objects.equal(baseInitaValue, newInitaValue)) {\n                fieldDiffInfo.setType(DiffType.MODIFY);\n                classDiffInfo.getModifyFields().add(fieldDiffInfo);\n                baseFieldMaps.remove(fieldDesc);\n                continue;\n            }\n            //annotation\n            Set<? extends DexBackedAnnotation> backedAnnotations = baseField.getAnnotations();\n            if (!equalsImpl(backedAnnotations,newField.getAnnotations())){\n                fieldDiffInfo.setType(DiffType.MODIFY);\n                classDiffInfo.getModifyFields().add(fieldDiffInfo);\n                baseFieldMaps.remove(fieldDesc);\n                continue;\n            }\n            //type\n            if (!baseField.getType().equals(newField.getType())){\n                fieldDiffInfo.setType(DiffType.MODIFY);\n                classDiffInfo.getModifyFields().add(fieldDiffInfo);\n                baseFieldMaps.remove(fieldDesc);\n                continue;\n            }\n            //accessflag\n\n            if (baseField.getAccessFlags() != newField.getAccessFlags()){\n                fieldDiffInfo.setType(DiffType.MODIFY);\n                classDiffInfo.getModifyFields().add(fieldDiffInfo);\n                baseFieldMaps.remove(fieldDesc);\n                continue;\n            }\n\n            baseFieldMaps.remove(fieldDesc);\n\n        }\n        // if member is removed\n        if (baseFieldMaps.size() > 0) {\n            for (Map.Entry<String, DexBackedField> entry : baseFieldMaps.entrySet()) {\n                FieldDiffInfo fieldDiffInfo = new FieldDiffInfo();\n                fieldDiffInfo.setBackedField(entry.getValue());\n                fieldDiffInfo.setType(DiffType.REMOVE);\n                classDiffInfo.getModifyFields().add(fieldDiffInfo);\n            }\n        }\n        if (classDiffInfo.getModifyFields().size() > 0) {\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * get dalvik className\n     *\n     * @param className\n     * @return\n     */\n    public static String getDalvikClassName(String className) {\n        if (className.charAt(0) != 'L' || className.charAt(className.length() - 1) != ';') {\n            throw new RuntimeException(\"Not a valid dalvik class name\");\n        }\n        return StringUtils.replace(className.substring(1, className.length() - 1), \"/\", \".\");\n    }\n\n    private static class DiffClass implements Comparable<DiffClass>{\n        public String className;\n        public Integer dexNumber;\n\n        public DiffClass(String className, Integer dexNumber) {\n            this.className = className;\n            this.dexNumber = dexNumber;\n        }\n\n\n        @Override\n        public String toString() {\n            return dexNumber+\"-\"+className;\n        }\n\n        @Override\n        public int compareTo(DiffClass o) {\n            return Integer.valueOf(dexNumber)-Integer.valueOf(o.dexNumber);\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/differ/dex/PatchException.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.differ.dex;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\n/**\n * Created by shenghua.nish on 2016-03-17 下午2:00.\n */\npublic class PatchException extends Exception {\n    public PatchException() {\n        super();\n    }\n\n    public PatchException(String message) {\n        super(message);\n    }\n\n    public PatchException(String message, Throwable cause) {\n        super(message, cause);\n    }\n\n    public PatchException(Throwable cause) {\n        super(cause);\n    }\n\n    protected PatchException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {\n        super(message, cause);\n    }\n\n    @Override\n    public synchronized Throwable fillInStackTrace() {\n        return this;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/Version.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx;\n\n/**\n * Version number for dx.\n */\npublic class Version {\n    /** {@code non-null;} version string */\n    public static final String VERSION = \"1.12\";\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttAnnotationDefault.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.rop.cst.Constant;\n\n/**\n * Attribute class for {@code AnnotationDefault} attributes.\n */\npublic final class AttAnnotationDefault extends BaseAttribute {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"AnnotationDefault\";\n\n    /** {@code non-null;} the annotation default value */\n    private final Constant value;\n\n    /** {@code >= 0;} attribute data length in the original classfile (not\n     * including the attribute header) */\n    private final int byteLength;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param value {@code non-null;} the annotation default value\n     * @param byteLength {@code >= 0;} attribute data length in the original\n     * classfile (not including the attribute header)\n     */\n    public AttAnnotationDefault(Constant value, int byteLength) {\n        super(ATTRIBUTE_NAME);\n\n        if (value == null) {\n            throw new NullPointerException(\"value == null\");\n        }\n\n        this.value = value;\n        this.byteLength = byteLength;\n    }\n\n    /** {@inheritDoc} */\n    public int byteLength() {\n        // Add six for the standard attribute header.\n        return byteLength + 6;\n    }\n\n    /**\n     * Gets the annotation default value.\n     *\n     * @return {@code non-null;} the value\n     */\n    public Constant getValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttCode.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.cf.code.ByteCatchList;\nimport com.taobao.android.dx.cf.code.BytecodeArray;\nimport com.taobao.android.dx.cf.iface.AttributeList;\nimport com.taobao.android.dx.util.MutabilityException;\n\n/**\n * Attribute class for standard {@code Code} attributes.\n */\npublic final class AttCode extends BaseAttribute {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"Code\";\n\n    /** {@code >= 0;} the stack size */\n    private final int maxStack;\n\n    /** {@code >= 0;} the number of locals */\n    private final int maxLocals;\n\n    /** {@code non-null;} array containing the bytecode per se */\n    private final BytecodeArray code;\n\n    /** {@code non-null;} the exception table */\n    private final ByteCatchList catches;\n\n    /** {@code non-null;} the associated list of attributes */\n    private final AttributeList attributes;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param maxStack {@code >= 0;} the stack size\n     * @param maxLocals {@code >= 0;} the number of locals\n     * @param code {@code non-null;} array containing the bytecode per se\n     * @param catches {@code non-null;} the exception table\n     * @param attributes {@code non-null;} the associated list of attributes\n     */\n    public AttCode(int maxStack, int maxLocals, BytecodeArray code,\n                   ByteCatchList catches, AttributeList attributes) {\n        super(ATTRIBUTE_NAME);\n\n        if (maxStack < 0) {\n            throw new IllegalArgumentException(\"maxStack < 0\");\n        }\n\n        if (maxLocals < 0) {\n            throw new IllegalArgumentException(\"maxLocals < 0\");\n        }\n\n        if (code == null) {\n            throw new NullPointerException(\"code == null\");\n        }\n\n        try {\n            if (catches.isMutable()) {\n                throw new MutabilityException(\"catches.isMutable()\");\n            }\n        } catch (NullPointerException ex) {\n            // Translate the exception.\n            throw new NullPointerException(\"catches == null\");\n        }\n\n        try {\n            if (attributes.isMutable()) {\n                throw new MutabilityException(\"attributes.isMutable()\");\n            }\n        } catch (NullPointerException ex) {\n            // Translate the exception.\n            throw new NullPointerException(\"attributes == null\");\n        }\n\n        this.maxStack = maxStack;\n        this.maxLocals = maxLocals;\n        this.code = code;\n        this.catches = catches;\n        this.attributes = attributes;\n    }\n\n    public int byteLength() {\n        return 10 + code.byteLength() + catches.byteLength() +\n            attributes.byteLength();\n    }\n\n    /**\n     * Gets the maximum stack size.\n     *\n     * @return {@code >= 0;} the maximum stack size\n     */\n    public int getMaxStack() {\n        return maxStack;\n    }\n\n    /**\n     * Gets the number of locals.\n     *\n     * @return {@code >= 0;} the number of locals\n     */\n    public int getMaxLocals() {\n        return maxLocals;\n    }\n\n    /**\n     * Gets the bytecode array.\n     *\n     * @return {@code non-null;} the bytecode array\n     */\n    public BytecodeArray getCode() {\n        return code;\n    }\n\n    /**\n     * Gets the exception table.\n     *\n     * @return {@code non-null;} the exception table\n     */\n    public ByteCatchList getCatches() {\n        return catches;\n    }\n\n    /**\n     * Gets the associated attribute list.\n     *\n     * @return {@code non-null;} the attribute list\n     */\n    public AttributeList getAttributes() {\n        return attributes;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttConstantValue.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.rop.cst.CstDouble;\nimport com.taobao.android.dx.rop.cst.CstFloat;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.cst.CstLong;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.TypedConstant;\n\n/**\n * Attribute class for standard {@code ConstantValue} attributes.\n */\npublic final class AttConstantValue extends BaseAttribute {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"ConstantValue\";\n\n    /** {@code non-null;} the constant value */\n    private final TypedConstant constantValue;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param constantValue {@code non-null;} the constant value, which must\n     * be an instance of one of: {@code CstString},\n     * {@code CstInteger}, {@code CstLong},\n     * {@code CstFloat}, or {@code CstDouble}\n     */\n    public AttConstantValue(TypedConstant constantValue) {\n        super(ATTRIBUTE_NAME);\n\n        if (!((constantValue instanceof CstString) ||\n               (constantValue instanceof CstInteger) ||\n               (constantValue instanceof CstLong) ||\n               (constantValue instanceof CstFloat) ||\n               (constantValue instanceof CstDouble))) {\n            if (constantValue == null) {\n                throw new NullPointerException(\"constantValue == null\");\n            }\n            throw new IllegalArgumentException(\"bad type for constantValue\");\n        }\n\n        this.constantValue = constantValue;\n    }\n\n    /** {@inheritDoc} */\n    public int byteLength() {\n        return 8;\n    }\n\n    /**\n     * Gets the constant value of this instance. The returned value\n     * is an instance of one of: {@code CstString},\n     * {@code CstInteger}, {@code CstLong},\n     * {@code CstFloat}, or {@code CstDouble}.\n     *\n     * @return {@code non-null;} the constant value\n     */\n    public TypedConstant getConstantValue() {\n        return constantValue;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttDeprecated.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\n/**\n * Attribute class for standard {@code Deprecated} attributes.\n */\npublic final class AttDeprecated extends BaseAttribute {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"Deprecated\";\n\n    /**\n     * Constructs an instance.\n     */\n    public AttDeprecated() {\n        super(ATTRIBUTE_NAME);\n    }\n\n    /** {@inheritDoc} */\n    public int byteLength() {\n        return 6;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttEnclosingMethod.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstType;\n\n/**\n * Attribute class for standards-track {@code EnclosingMethod}\n * attributes.\n */\npublic final class AttEnclosingMethod extends BaseAttribute {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"EnclosingMethod\";\n\n    /** {@code non-null;} the innermost enclosing class */\n    private final CstType type;\n\n    /** {@code null-ok;} the name-and-type of the innermost enclosing method, if any */\n    private final CstNat method;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param type {@code non-null;} the innermost enclosing class\n     * @param method {@code null-ok;} the name-and-type of the innermost enclosing\n     * method, if any\n     */\n    public AttEnclosingMethod(CstType type, CstNat method) {\n        super(ATTRIBUTE_NAME);\n\n        if (type == null) {\n            throw new NullPointerException(\"type == null\");\n        }\n\n        this.type = type;\n        this.method = method;\n    }\n\n    /** {@inheritDoc} */\n    public int byteLength() {\n        return 10;\n    }\n\n    /**\n     * Gets the innermost enclosing class.\n     *\n     * @return {@code non-null;} the innermost enclosing class\n     */\n    public CstType getEnclosingClass() {\n        return type;\n    }\n\n    /**\n     * Gets the name-and-type of the innermost enclosing method, if\n     * any.\n     *\n     * @return {@code null-ok;} the name-and-type of the innermost enclosing\n     * method, if any\n     */\n    public CstNat getMethod() {\n        return method;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttExceptions.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.MutabilityException;\n\n/**\n * Attribute class for standard {@code Exceptions} attributes.\n */\npublic final class AttExceptions extends BaseAttribute {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"Exceptions\";\n\n    /** {@code non-null;} list of exception classes */\n    private final TypeList exceptions;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param exceptions {@code non-null;} list of classes, presumed but not\n     * verified to be subclasses of {@code Throwable}\n     */\n    public AttExceptions(TypeList exceptions) {\n        super(ATTRIBUTE_NAME);\n\n        try {\n            if (exceptions.isMutable()) {\n                throw new MutabilityException(\"exceptions.isMutable()\");\n            }\n        } catch (NullPointerException ex) {\n            // Translate the exception.\n            throw new NullPointerException(\"exceptions == null\");\n        }\n\n        this.exceptions = exceptions;\n    }\n\n    /** {@inheritDoc} */\n    public int byteLength() {\n        return 8 + exceptions.size() * 2;\n    }\n\n    /**\n     * Gets the list of classes associated with this instance. In\n     * general, these classes are not pre-verified to be subclasses of\n     * {@code Throwable}.\n     *\n     * @return {@code non-null;} the list of classes\n     */\n    public TypeList getExceptions() {\n        return exceptions;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttInnerClasses.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.util.MutabilityException;\n\n/**\n * Attribute class for standard {@code InnerClasses} attributes.\n */\npublic final class AttInnerClasses extends BaseAttribute {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"InnerClasses\";\n\n    /** {@code non-null;} list of inner class entries */\n    private final InnerClassList innerClasses;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param innerClasses {@code non-null;} list of inner class entries\n     */\n    public AttInnerClasses(InnerClassList innerClasses) {\n        super(ATTRIBUTE_NAME);\n\n        try {\n            if (innerClasses.isMutable()) {\n                throw new MutabilityException(\"innerClasses.isMutable()\");\n            }\n        } catch (NullPointerException ex) {\n            // Translate the exception.\n            throw new NullPointerException(\"innerClasses == null\");\n        }\n\n        this.innerClasses = innerClasses;\n    }\n\n    /** {@inheritDoc} */\n    public int byteLength() {\n        return 8 + innerClasses.size() * 8;\n    }\n\n    /**\n     * Gets the list of \"inner class\" entries associated with this instance.\n     *\n     * @return {@code non-null;} the list\n     */\n    public InnerClassList getInnerClasses() {\n        return innerClasses;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttLineNumberTable.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.cf.code.LineNumberList;\nimport com.taobao.android.dx.util.MutabilityException;\n\n/**\n * Attribute class for standard {@code LineNumberTable} attributes.\n */\npublic final class AttLineNumberTable extends BaseAttribute {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"LineNumberTable\";\n\n    /** {@code non-null;} list of line number entries */\n    private final LineNumberList lineNumbers;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param lineNumbers {@code non-null;} list of line number entries\n     */\n    public AttLineNumberTable(LineNumberList lineNumbers) {\n        super(ATTRIBUTE_NAME);\n\n        try {\n            if (lineNumbers.isMutable()) {\n                throw new MutabilityException(\"lineNumbers.isMutable()\");\n            }\n        } catch (NullPointerException ex) {\n            // Translate the exception.\n            throw new NullPointerException(\"lineNumbers == null\");\n        }\n\n        this.lineNumbers = lineNumbers;\n    }\n\n    /** {@inheritDoc} */\n    public int byteLength() {\n        return 8 + 4 * lineNumbers.size();\n    }\n\n    /**\n     * Gets the list of \"line number\" entries associated with this instance.\n     *\n     * @return {@code non-null;} the list\n     */\n    public LineNumberList getLineNumbers() {\n        return lineNumbers;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttLocalVariableTable.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.cf.code.LocalVariableList;\n\n/**\n * Attribute class for standard {@code LocalVariableTable} attributes.\n */\npublic final class AttLocalVariableTable extends BaseLocalVariables {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"LocalVariableTable\";\n\n    /**\n     * Constructs an instance.\n     *\n     * @param localVariables {@code non-null;} list of local variable entries\n     */\n    public AttLocalVariableTable(LocalVariableList localVariables) {\n        super(ATTRIBUTE_NAME, localVariables);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttLocalVariableTypeTable.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.cf.code.LocalVariableList;\n\n/**\n * Attribute class for standard {@code LocalVariableTypeTable} attributes.\n */\npublic final class AttLocalVariableTypeTable extends BaseLocalVariables {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"LocalVariableTypeTable\";\n\n    /**\n     * Constructs an instance.\n     *\n     * @param localVariables {@code non-null;} list of local variable entries\n     */\n    public AttLocalVariableTypeTable(LocalVariableList localVariables) {\n        super(ATTRIBUTE_NAME, localVariables);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttRuntimeInvisibleAnnotations.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.rop.annotation.Annotations;\n\n/**\n * Attribute class for standard {@code RuntimeInvisibleAnnotations}\n * attributes.\n */\npublic final class AttRuntimeInvisibleAnnotations extends BaseAnnotations {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"RuntimeInvisibleAnnotations\";\n\n    /**\n     * Constructs an instance.\n     *\n     * @param annotations {@code non-null;} the list of annotations\n     * @param byteLength {@code >= 0;} attribute data length in the original\n     * classfile (not including the attribute header)\n     */\n    public AttRuntimeInvisibleAnnotations(Annotations annotations,\n            int byteLength) {\n        super(ATTRIBUTE_NAME, annotations, byteLength);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttRuntimeInvisibleParameterAnnotations.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.rop.annotation.AnnotationsList;\n\n/**\n * Attribute class for standard\n * {@code RuntimeInvisibleParameterAnnotations} attributes.\n */\npublic final class AttRuntimeInvisibleParameterAnnotations\n        extends BaseParameterAnnotations {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME =\n        \"RuntimeInvisibleParameterAnnotations\";\n\n    /**\n     * Constructs an instance.\n     *\n     * @param parameterAnnotations {@code non-null;} the parameter annotations\n     * @param byteLength {@code >= 0;} attribute data length in the original\n     * classfile (not including the attribute header)\n     */\n    public AttRuntimeInvisibleParameterAnnotations(\n            AnnotationsList parameterAnnotations, int byteLength) {\n        super(ATTRIBUTE_NAME, parameterAnnotations, byteLength);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttRuntimeVisibleAnnotations.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.rop.annotation.Annotations;\n\n/**\n * Attribute class for standard {@code RuntimeVisibleAnnotations}\n * attributes.\n */\npublic final class AttRuntimeVisibleAnnotations extends BaseAnnotations {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"RuntimeVisibleAnnotations\";\n\n    /**\n     * Constructs an instance.\n     *\n     * @param annotations {@code non-null;} the list of annotations\n     * @param byteLength {@code >= 0;} attribute data length in the original\n     * classfile (not including the attribute header)\n     */\n    public AttRuntimeVisibleAnnotations(Annotations annotations,\n            int byteLength) {\n        super(ATTRIBUTE_NAME, annotations, byteLength);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttRuntimeVisibleParameterAnnotations.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.rop.annotation.AnnotationsList;\n\n/**\n * Attribute class for standard {@code RuntimeVisibleParameterAnnotations}\n * attributes.\n */\npublic final class AttRuntimeVisibleParameterAnnotations\n        extends BaseParameterAnnotations {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME =\n        \"RuntimeVisibleParameterAnnotations\";\n\n    /**\n     * Constructs an instance.\n     *\n     * @param annotations {@code non-null;} the parameter annotations\n     * @param byteLength {@code >= 0;} attribute data length in the original\n     * classfile (not including the attribute header)\n     */\n    public AttRuntimeVisibleParameterAnnotations(\n            AnnotationsList annotations, int byteLength) {\n        super(ATTRIBUTE_NAME, annotations, byteLength);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttSignature.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.rop.cst.CstString;\n\n/**\n * Attribute class for standards-track {@code Signature} attributes.\n */\npublic final class AttSignature extends BaseAttribute {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"Signature\";\n\n    /** {@code non-null;} the signature string */\n    private final CstString signature;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param signature {@code non-null;} the signature string\n     */\n    public AttSignature(CstString signature) {\n        super(ATTRIBUTE_NAME);\n\n        if (signature == null) {\n            throw new NullPointerException(\"signature == null\");\n        }\n\n        this.signature = signature;\n    }\n\n    /** {@inheritDoc} */\n    public int byteLength() {\n        return 8;\n    }\n\n    /**\n     * Gets the signature string.\n     *\n     * @return {@code non-null;} the signature string\n     */\n    public CstString getSignature() {\n        return signature;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttSourceFile.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.rop.cst.CstString;\n\n/**\n * Attribute class for standard {@code SourceFile} attributes.\n */\npublic final class AttSourceFile extends BaseAttribute {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"SourceFile\";\n\n    /** {@code non-null;} name of the source file */\n    private final CstString sourceFile;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param sourceFile {@code non-null;} the name of the source file\n     */\n    public AttSourceFile(CstString sourceFile) {\n        super(ATTRIBUTE_NAME);\n\n        if (sourceFile == null) {\n            throw new NullPointerException(\"sourceFile == null\");\n        }\n\n        this.sourceFile = sourceFile;\n    }\n\n    /** {@inheritDoc} */\n    public int byteLength() {\n        return 8;\n    }\n\n    /**\n     * Gets the source file name of this instance.\n     *\n     * @return {@code non-null;} the source file\n     */\n    public CstString getSourceFile() {\n        return sourceFile;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/AttSynthetic.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\n/**\n * Attribute class for standard {@code Synthetic} attributes.\n */\npublic final class AttSynthetic extends BaseAttribute {\n    /** {@code non-null;} attribute name for attributes of this type */\n    public static final String ATTRIBUTE_NAME = \"Synthetic\";\n\n    /**\n     * Constructs an instance.\n     */\n    public AttSynthetic() {\n        super(ATTRIBUTE_NAME);\n    }\n\n    /** {@inheritDoc} */\n    public int byteLength() {\n        return 6;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/BaseAnnotations.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.rop.annotation.Annotations;\nimport com.taobao.android.dx.util.MutabilityException;\n\n/**\n * Base class for annotations attributes.\n */\npublic abstract class BaseAnnotations extends BaseAttribute {\n    /** {@code non-null;} list of annotations */\n    private final Annotations annotations;\n\n    /** {@code >= 0;} attribute data length in the original classfile (not\n     * including the attribute header) */\n    private final int byteLength;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param attributeName {@code non-null;} the name of the attribute\n     * @param annotations {@code non-null;} the list of annotations\n     * @param byteLength {@code >= 0;} attribute data length in the original\n     * classfile (not including the attribute header)\n     */\n    public BaseAnnotations(String attributeName, Annotations annotations,\n            int byteLength) {\n        super(attributeName);\n\n        try {\n            if (annotations.isMutable()) {\n                throw new MutabilityException(\"annotations.isMutable()\");\n            }\n        } catch (NullPointerException ex) {\n            // Translate the exception.\n            throw new NullPointerException(\"annotations == null\");\n        }\n\n        this.annotations = annotations;\n        this.byteLength = byteLength;\n    }\n\n    /** {@inheritDoc} */\n    public final int byteLength() {\n        // Add six for the standard attribute header.\n        return byteLength + 6;\n    }\n\n    /**\n     * Gets the list of annotations associated with this instance.\n     *\n     * @return {@code non-null;} the list\n     */\n    public final Annotations getAnnotations() {\n        return annotations;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/BaseAttribute.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.cf.iface.Attribute;\n\n/**\n * Base implementation of {@link Attribute}, which directly stores\n * the attribute name but leaves the rest up to subclasses.\n */\npublic abstract class BaseAttribute implements Attribute {\n    /** {@code non-null;} attribute name */\n    private final String name;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param name {@code non-null;} attribute name\n     */\n    public BaseAttribute(String name) {\n        if (name == null) {\n            throw new NullPointerException(\"name == null\");\n        }\n\n        this.name = name;\n    }\n\n    /** {@inheritDoc} */\n    public String getName() {\n        return name;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/BaseLocalVariables.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.cf.code.LocalVariableList;\nimport com.taobao.android.dx.util.MutabilityException;\n\n/**\n * Base attribute class for standard {@code LocalVariableTable}\n * and {@code LocalVariableTypeTable} attributes.\n */\npublic abstract class BaseLocalVariables extends BaseAttribute {\n    /** {@code non-null;} list of local variable entries */\n    private final LocalVariableList localVariables;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param name {@code non-null;} attribute name\n     * @param localVariables {@code non-null;} list of local variable entries\n     */\n    public BaseLocalVariables(String name,\n            LocalVariableList localVariables) {\n        super(name);\n\n        try {\n            if (localVariables.isMutable()) {\n                throw new MutabilityException(\"localVariables.isMutable()\");\n            }\n        } catch (NullPointerException ex) {\n            // Translate the exception.\n            throw new NullPointerException(\"localVariables == null\");\n        }\n\n        this.localVariables = localVariables;\n    }\n\n    /** {@inheritDoc} */\n    public final int byteLength() {\n        return 8 + localVariables.size() * 10;\n    }\n\n    /**\n     * Gets the list of \"local variable\" entries associated with this instance.\n     *\n     * @return {@code non-null;} the list\n     */\n    public final LocalVariableList getLocalVariables() {\n        return localVariables;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/BaseParameterAnnotations.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.rop.annotation.AnnotationsList;\nimport com.taobao.android.dx.util.MutabilityException;\n\n/**\n * Base class for parameter annotation list attributes.\n */\npublic abstract class BaseParameterAnnotations extends BaseAttribute {\n    /** {@code non-null;} list of annotations */\n    private final AnnotationsList parameterAnnotations;\n\n    /** {@code >= 0;} attribute data length in the original classfile (not\n     * including the attribute header) */\n    private final int byteLength;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param attributeName {@code non-null;} the name of the attribute\n     * @param parameterAnnotations {@code non-null;} the annotations\n     * @param byteLength {@code >= 0;} attribute data length in the original\n     * classfile (not including the attribute header)\n     */\n    public BaseParameterAnnotations(String attributeName,\n            AnnotationsList parameterAnnotations, int byteLength) {\n        super(attributeName);\n\n        try {\n            if (parameterAnnotations.isMutable()) {\n                throw new MutabilityException(\n                        \"parameterAnnotations.isMutable()\");\n            }\n        } catch (NullPointerException ex) {\n            // Translate the exception.\n            throw new NullPointerException(\"parameterAnnotations == null\");\n        }\n\n        this.parameterAnnotations = parameterAnnotations;\n        this.byteLength = byteLength;\n    }\n\n    /** {@inheritDoc} */\n    public final int byteLength() {\n        // Add six for the standard attribute header.\n        return byteLength + 6;\n    }\n\n    /**\n     * Gets the list of annotation lists associated with this instance.\n     *\n     * @return {@code non-null;} the list\n     */\n    public final AnnotationsList getParameterAnnotations() {\n        return parameterAnnotations;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/InnerClassList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.util.FixedSizeList;\n\n/**\n * List of \"inner class\" entries, which are the contents of\n * {@code InnerClasses} attributes.\n */\npublic final class InnerClassList extends FixedSizeList {\n    /**\n     * Constructs an instance.\n     *\n     * @param count the number of elements to be in the list of inner classes\n     */\n    public InnerClassList(int count) {\n        super(count);\n    }\n\n    /**\n     * Gets the indicated item.\n     *\n     * @param n {@code >= 0;} which item\n     * @return {@code null-ok;} the indicated item\n     */\n    public Item get(int n) {\n        return (Item) get0(n);\n    }\n\n    /**\n     * Sets the item at the given index.\n     *\n     * @param n {@code >= 0, < size();} which class\n     * @param innerClass {@code non-null;} class this item refers to\n     * @param outerClass {@code null-ok;} outer class that this class is a\n     * member of, if any\n     * @param innerName {@code null-ok;} original simple name of this class,\n     * if not anonymous\n     * @param accessFlags original declared access flags\n     */\n    public void set(int n, CstType innerClass, CstType outerClass,\n                    CstString innerName, int accessFlags) {\n        set0(n, new Item(innerClass, outerClass, innerName, accessFlags));\n    }\n\n    /**\n     * Item in an inner classes list.\n     */\n    public static class Item {\n        /** {@code non-null;} class this item refers to */\n        private final CstType innerClass;\n\n        /** {@code null-ok;} outer class that this class is a member of, if any */\n        private final CstType outerClass;\n\n        /** {@code null-ok;} original simple name of this class, if not anonymous */\n        private final CstString innerName;\n\n        /** original declared access flags */\n        private final int accessFlags;\n\n        /**\n         * Constructs an instance.\n         *\n         * @param innerClass {@code non-null;} class this item refers to\n         * @param outerClass {@code null-ok;} outer class that this class is a\n         * member of, if any\n         * @param innerName {@code null-ok;} original simple name of this\n         * class, if not anonymous\n         * @param accessFlags original declared access flags\n         */\n        public Item(CstType innerClass, CstType outerClass,\n                    CstString innerName, int accessFlags) {\n            if (innerClass == null) {\n                throw new NullPointerException(\"innerClass == null\");\n            }\n\n            this.innerClass = innerClass;\n            this.outerClass = outerClass;\n            this.innerName = innerName;\n            this.accessFlags = accessFlags;\n        }\n\n        /**\n         * Gets the class this item refers to.\n         *\n         * @return {@code non-null;} the class\n         */\n        public CstType getInnerClass() {\n            return innerClass;\n        }\n\n        /**\n         * Gets the outer class that this item's class is a member of, if any.\n         *\n         * @return {@code null-ok;} the class\n         */\n        public CstType getOuterClass() {\n            return outerClass;\n        }\n\n        /**\n         * Gets the original name of this item's class, if not anonymous.\n         *\n         * @return {@code null-ok;} the name\n         */\n        public CstString getInnerName() {\n            return innerName;\n        }\n\n        /**\n         * Gets the original declared access flags.\n         *\n         * @return the access flags\n         */\n        public int getAccessFlags() {\n            return accessFlags;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/RawAttribute.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.attrib;\n\nimport com.taobao.android.dx.rop.cst.ConstantPool;\nimport com.taobao.android.dx.util.ByteArray;\n\n/**\n * Raw attribute, for holding onto attributes that are unrecognized.\n */\npublic final class RawAttribute extends BaseAttribute {\n    /** {@code non-null;} attribute data */\n    private final ByteArray data;\n\n    /**\n     * {@code null-ok;} constant pool to use for resolution of cpis in {@link\n     * #data}\n     */\n    private final ConstantPool pool;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param name {@code non-null;} attribute name\n     * @param data {@code non-null;} attribute data\n     * @param pool {@code null-ok;} constant pool to use for cpi resolution\n     */\n    public RawAttribute(String name, ByteArray data, ConstantPool pool) {\n        super(name);\n\n        if (data == null) {\n            throw new NullPointerException(\"data == null\");\n        }\n\n        this.data = data;\n        this.pool = pool;\n    }\n\n    /**\n     * Constructs an instance from a sub-array of a {@link ByteArray}.\n     *\n     * @param name {@code non-null;} attribute name\n     * @param data {@code non-null;} array containing the attribute data\n     * @param offset offset in {@code data} to the attribute data\n     * @param length length of the attribute data, in bytes\n     * @param pool {@code null-ok;} constant pool to use for cpi resolution\n     */\n    public RawAttribute(String name, ByteArray data, int offset,\n                        int length, ConstantPool pool) {\n        this(name, data.slice(offset, offset + length), pool);\n    }\n\n    /**\n     * Get the raw data of the attribute.\n     *\n     * @return {@code non-null;} the data\n     */\n    public ByteArray getData() {\n        return data;\n    }\n\n    /** {@inheritDoc} */\n    public int byteLength() {\n        return data.size() + 6;\n    }\n\n    /**\n     * Gets the constant pool to use for cpi resolution, if any. It\n     * presumably came from the class file that this attribute came\n     * from.\n     *\n     * @return {@code null-ok;} the constant pool\n     */\n    public ConstantPool getPool() {\n        return pool;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/attrib/package.html",
    "content": "<body>\n<p>Implementation of containers and utilities for all the standard Java\nattribute types.</p>\n\n<p><b>PACKAGES USED:</b>\n<ul>\n<li><code>com.taobao.android.dx.cf.iface</code></li>\n<li><code>com.taobao.android.dx.rop.pool</code></li>\n<li><code>com.taobao.android.dx.util</code></li>\n</ul>\n</body>\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/BaseMachine.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.rop.code.LocalItem;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.type.Prototype;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport java.util.ArrayList;\n\n/**\n * Base implementation of {@link Machine}.\n *\n * <p><b>Note:</b> For the most part, the documentation for this class\n * ignores the distinction between {@link Type} and {@link\n * TypeBearer}.</p>\n */\npublic abstract class BaseMachine implements Machine {\n    /* {@code non-null;} the prototype for the associated method */\n    private final Prototype prototype;\n\n    /** {@code non-null;} primary arguments */\n    private TypeBearer[] args;\n\n    /** {@code >= 0;} number of primary arguments */\n    private int argCount;\n\n    /** {@code null-ok;} type of the operation, if salient */\n    private Type auxType;\n\n    /** auxiliary {@code int} argument */\n    private int auxInt;\n\n    /** {@code null-ok;} auxiliary constant argument */\n    private Constant auxCst;\n\n    /** auxiliary branch target argument */\n    private int auxTarget;\n\n    /** {@code null-ok;} auxiliary switch cases argument */\n    private SwitchList auxCases;\n\n    /** {@code null-ok;} auxiliary initial value list for newarray */\n    private ArrayList<Constant> auxInitValues;\n\n    /** {@code >= -1;} last local accessed */\n    private int localIndex;\n\n    /** specifies if local has info in the local variable table */\n    private boolean localInfo;\n\n    /** {@code null-ok;} local target spec, if salient and calculated */\n    private RegisterSpec localTarget;\n\n    /** {@code non-null;} results */\n    private TypeBearer[] results;\n\n    /**\n     * {@code >= -1;} count of the results, or {@code -1} if no results\n     * have been set\n     */\n    private int resultCount;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param prototype {@code non-null;} the prototype for the\n     * associated method\n     */\n    public BaseMachine(Prototype prototype) {\n        if (prototype == null) {\n            throw new NullPointerException(\"prototype == null\");\n        }\n\n        this.prototype = prototype;\n        args = new TypeBearer[10];\n        results = new TypeBearer[6];\n        clearArgs();\n    }\n\n    /** {@inheritDoc} */\n    public Prototype getPrototype() {\n        return prototype;\n    }\n\n    /** {@inheritDoc} */\n    public final void clearArgs() {\n        argCount = 0;\n        auxType = null;\n        auxInt = 0;\n        auxCst = null;\n        auxTarget = 0;\n        auxCases = null;\n        auxInitValues = null;\n        localIndex = -1;\n        localInfo = false;\n        localTarget = null;\n        resultCount = -1;\n    }\n\n    /** {@inheritDoc} */\n    public final void popArgs(Frame frame, int count) {\n        ExecutionStack stack = frame.getStack();\n\n        clearArgs();\n\n        if (count > args.length) {\n            // Grow args, and add a little extra room to grow even more.\n            args = new TypeBearer[count + 10];\n        }\n\n        for (int i = count - 1; i >= 0; i--) {\n            args[i] = stack.pop();\n        }\n\n        argCount = count;\n    }\n\n    /** {@inheritDoc} */\n    public void popArgs(Frame frame, Prototype prototype) {\n        StdTypeList types = prototype.getParameterTypes();\n        int size = types.size();\n\n        // Use the above method to do the actual popping...\n        popArgs(frame, size);\n\n        // ...and then verify the popped types.\n\n        for (int i = 0; i < size; i++) {\n            if (! Merger.isPossiblyAssignableFrom(types.getType(i), args[i])) {\n                throw new SimException(\"at stack depth \" + (size - 1 - i) +\n                        \", expected type \" + types.getType(i).toHuman() +\n                        \" but found \" + args[i].getType().toHuman());\n            }\n        }\n    }\n\n    public final void popArgs(Frame frame, Type type) {\n        // Use the above method to do the actual popping...\n        popArgs(frame, 1);\n\n        // ...and then verify the popped type.\n        if (! Merger.isPossiblyAssignableFrom(type, args[0])) {\n            throw new SimException(\"expected type \" + type.toHuman() +\n                    \" but found \" + args[0].getType().toHuman());\n        }\n    }\n\n    /** {@inheritDoc} */\n    public final void popArgs(Frame frame, Type type1, Type type2) {\n        // Use the above method to do the actual popping...\n        popArgs(frame, 2);\n\n        // ...and then verify the popped types.\n\n        if (! Merger.isPossiblyAssignableFrom(type1, args[0])) {\n            throw new SimException(\"expected type \" + type1.toHuman() +\n                    \" but found \" + args[0].getType().toHuman());\n        }\n\n        if (! Merger.isPossiblyAssignableFrom(type2, args[1])) {\n            throw new SimException(\"expected type \" + type2.toHuman() +\n                    \" but found \" + args[1].getType().toHuman());\n        }\n    }\n\n    /** {@inheritDoc} */\n    public final void popArgs(Frame frame, Type type1, Type type2,\n            Type type3) {\n        // Use the above method to do the actual popping...\n        popArgs(frame, 3);\n\n        // ...and then verify the popped types.\n\n        if (! Merger.isPossiblyAssignableFrom(type1, args[0])) {\n            throw new SimException(\"expected type \" + type1.toHuman() +\n                    \" but found \" + args[0].getType().toHuman());\n        }\n\n        if (! Merger.isPossiblyAssignableFrom(type2, args[1])) {\n            throw new SimException(\"expected type \" + type2.toHuman() +\n                    \" but found \" + args[1].getType().toHuman());\n        }\n\n        if (! Merger.isPossiblyAssignableFrom(type3, args[2])) {\n            throw new SimException(\"expected type \" + type3.toHuman() +\n                    \" but found \" + args[2].getType().toHuman());\n        }\n    }\n\n    /** {@inheritDoc} */\n    public final void localArg(Frame frame, int idx) {\n        clearArgs();\n        args[0] = frame.getLocals().get(idx);\n        argCount = 1;\n        localIndex = idx;\n    }\n\n    /** {@inheritDoc} */\n    public final void localInfo(boolean local) {\n        localInfo = local;\n    }\n\n    /** {@inheritDoc} */\n    public final void auxType(Type type) {\n        auxType = type;\n    }\n\n    /** {@inheritDoc} */\n    public final void auxIntArg(int value) {\n        auxInt = value;\n    }\n\n    /** {@inheritDoc} */\n    public final void auxCstArg(Constant cst) {\n        if (cst == null) {\n            throw new NullPointerException(\"cst == null\");\n        }\n\n        auxCst = cst;\n    }\n\n    /** {@inheritDoc} */\n    public final void auxTargetArg(int target) {\n        auxTarget = target;\n    }\n\n    /** {@inheritDoc} */\n    public final void auxSwitchArg(SwitchList cases) {\n        if (cases == null) {\n            throw new NullPointerException(\"cases == null\");\n        }\n\n        auxCases = cases;\n    }\n\n    /** {@inheritDoc} */\n    public final void auxInitValues(ArrayList<Constant> initValues) {\n        auxInitValues = initValues;\n    }\n\n    /** {@inheritDoc} */\n    public final void localTarget(int idx, Type type, LocalItem local) {\n        localTarget = RegisterSpec.makeLocalOptional(idx, type, local);\n    }\n\n    /**\n     * Gets the number of primary arguments.\n     *\n     * @return {@code >= 0;} the number of primary arguments\n     */\n    protected final int argCount() {\n        return argCount;\n    }\n\n    /**\n     * Gets the width of the arguments (where a category-2 value counts as\n     * two).\n     *\n     * @return {@code >= 0;} the argument width\n     */\n    protected final int argWidth() {\n        int result = 0;\n\n        for (int i = 0; i < argCount; i++) {\n            result += args[i].getType().getCategory();\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets the {@code n}th primary argument.\n     *\n     * @param n {@code >= 0, < argCount();} which argument\n     * @return {@code non-null;} the indicated argument\n     */\n    protected final TypeBearer arg(int n) {\n        if (n >= argCount) {\n            throw new IllegalArgumentException(\"n >= argCount\");\n        }\n\n        try {\n            return args[n];\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"n < 0\");\n        }\n    }\n\n    /**\n     * Gets the type auxiliary argument.\n     *\n     * @return {@code null-ok;} the salient type\n     */\n    protected final Type getAuxType() {\n        return auxType;\n    }\n\n    /**\n     * Gets the {@code int} auxiliary argument.\n     *\n     * @return the argument value\n     */\n    protected final int getAuxInt() {\n        return auxInt;\n    }\n\n    /**\n     * Gets the constant auxiliary argument.\n     *\n     * @return {@code null-ok;} the argument value\n     */\n    protected final Constant getAuxCst() {\n        return auxCst;\n    }\n\n    /**\n     * Gets the branch target auxiliary argument.\n     *\n     * @return the argument value\n     */\n    protected final int getAuxTarget() {\n        return auxTarget;\n    }\n\n    /**\n     * Gets the switch cases auxiliary argument.\n     *\n     * @return {@code null-ok;} the argument value\n     */\n    protected final SwitchList getAuxCases() {\n        return auxCases;\n    }\n\n    /**\n     * Gets the init values auxiliary argument.\n     *\n     * @return {@code null-ok;} the argument value\n     */\n    protected final ArrayList<Constant> getInitValues() {\n        return auxInitValues;\n    }\n    /**\n     * Gets the last local index accessed.\n     *\n     * @return {@code >= -1;} the salient local index or {@code -1} if none\n     * was set since the last time {@link #clearArgs} was called\n     */\n    protected final int getLocalIndex() {\n        return localIndex;\n    }\n\n    /**\n     * Gets whether the loaded local has info in the local variable table.\n     *\n     * @return {@code true} if local arg has info in the local variable table\n     */\n    protected final boolean getLocalInfo() {\n        return localInfo;\n    }\n\n    /**\n     * Gets the target local register spec of the current operation, if any.\n     * The local target spec is the combination of the values indicated\n     * by a previous call to {@link #localTarget} with the type of what\n     * should be the sole result set by a call to {@link #setResult} (or\n     * the combination {@link #clearResult} then {@link #addResult}.\n     *\n     * @param isMove {@code true} if the operation being performed on the\n     * local is a move. This will cause constant values to be propagated\n     * to the returned local\n     * @return {@code null-ok;} the salient register spec or {@code null} if no\n     * local target was set since the last time {@link #clearArgs} was\n     * called\n     */\n    protected final RegisterSpec getLocalTarget(boolean isMove) {\n        if (localTarget == null) {\n            return null;\n        }\n\n        if (resultCount != 1) {\n            throw new SimException(\"local target with \" +\n                    ((resultCount == 0) ? \"no\" : \"multiple\") + \" results\");\n        }\n\n        TypeBearer result = results[0];\n        Type resultType = result.getType();\n        Type localType = localTarget.getType();\n\n        if (resultType == localType) {\n            /*\n             * If this is to be a move operation and the result is a\n             * known value, make the returned localTarget embody that\n             * value.\n             */\n            if (isMove) {\n                return localTarget.withType(result);\n            } else {\n                return localTarget;\n            }\n        }\n\n        if (! Merger.isPossiblyAssignableFrom(localType, resultType)) {\n            // The result and local types are inconsistent. Complain!\n            throwLocalMismatch(resultType, localType);\n            return null;\n        }\n\n        if (localType == Type.OBJECT) {\n            /*\n             * The result type is more specific than the local type,\n             * so use that instead.\n             */\n            localTarget = localTarget.withType(result);\n        }\n\n        return localTarget;\n    }\n\n    /**\n     * Clears the results.\n     */\n    protected final void clearResult() {\n        resultCount = 0;\n    }\n\n    /**\n     * Sets the results list to be the given single value.\n     *\n     * <p><b>Note:</b> If there is more than one result value, the\n     * others may be added by using {@link #addResult}.</p>\n     *\n     * @param result {@code non-null;} result value\n     */\n    protected final void setResult(TypeBearer result) {\n        if (result == null) {\n            throw new NullPointerException(\"result == null\");\n        }\n\n        results[0] = result;\n        resultCount = 1;\n    }\n\n    /**\n     * Adds an additional element to the list of results.\n     *\n     * @see #setResult\n     *\n     * @param result {@code non-null;} result value\n     */\n    protected final void addResult(TypeBearer result) {\n        if (result == null) {\n            throw new NullPointerException(\"result == null\");\n        }\n\n        results[resultCount] = result;\n        resultCount++;\n    }\n\n    /**\n     * Gets the count of results. This throws an exception if results were\n     * never set. (Explicitly clearing the results counts as setting them.)\n     *\n     * @return {@code >= 0;} the count\n     */\n    protected final int resultCount() {\n        if (resultCount < 0) {\n            throw new SimException(\"results never set\");\n        }\n\n        return resultCount;\n    }\n\n    /**\n     * Gets the width of the results (where a category-2 value counts as\n     * two).\n     *\n     * @return {@code >= 0;} the result width\n     */\n    protected final int resultWidth() {\n        int width = 0;\n\n        for (int i = 0; i < resultCount; i++) {\n            width += results[i].getType().getCategory();\n        }\n\n        return width;\n    }\n\n    /**\n     * Gets the {@code n}th result value.\n     *\n     * @param n {@code >= 0, < resultCount();} which result\n     * @return {@code non-null;} the indicated result value\n     */\n    protected final TypeBearer result(int n) {\n        if (n >= resultCount) {\n            throw new IllegalArgumentException(\"n >= resultCount\");\n        }\n\n        try {\n            return results[n];\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"n < 0\");\n        }\n    }\n\n    /**\n     * Stores the results of the latest operation into the given frame. If\n     * there is a local target (see {@link #localTarget}), then the sole\n     * result is stored to that target; otherwise any results are pushed\n     * onto the stack.\n     *\n     * @param frame {@code non-null;} frame to operate on\n     */\n    protected final void storeResults(Frame frame) {\n        if (resultCount < 0) {\n            throw new SimException(\"results never set\");\n        }\n\n        if (resultCount == 0) {\n            // Nothing to do.\n            return;\n        }\n\n        if (localTarget != null) {\n            /*\n             * Note: getLocalTarget() doesn't necessarily return\n             * localTarget directly.\n             */\n            frame.getLocals().set(getLocalTarget(false));\n        } else {\n            ExecutionStack stack = frame.getStack();\n            for (int i = 0; i < resultCount; i++) {\n                if (localInfo) {\n                    stack.setLocal();\n                }\n                stack.push(results[i]);\n            }\n        }\n    }\n\n    /**\n     * Throws an exception that indicates a mismatch in local variable\n     * types.\n     *\n     * @param found {@code non-null;} the encountered type\n     * @param local {@code non-null;} the local variable's claimed type\n     */\n    public static void throwLocalMismatch(TypeBearer found,\n            TypeBearer local) {\n        throw new SimException(\"local variable type mismatch: \" +\n                \"attempt to set or access a value of type \" +\n                found.toHuman() +\n                \" using a local variable of type \" +\n                local.toHuman() +\n                \". This is symptomatic of .class transformation tools \" +\n                \"that ignore local variable information.\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/BasicBlocker.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstMemberRef;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.Bits;\nimport com.taobao.android.dx.util.IntList;\nimport java.util.ArrayList;\n\n/**\n * Utility that identifies basic blocks in bytecode.\n */\npublic final class BasicBlocker implements BytecodeArray.Visitor {\n    /** {@code non-null;} method being converted */\n    private final ConcreteMethod method;\n\n    /**\n     * {@code non-null;} work set; bits indicate offsets in need of\n     * examination\n     */\n    private final int[] workSet;\n\n    /**\n     * {@code non-null;} live set; bits indicate potentially-live\n     * opcodes; contrawise, a bit that isn't on is either in the\n     * middle of an instruction or is a definitely-dead opcode\n     */\n    private final int[] liveSet;\n\n    /**\n     * {@code non-null;} block start set; bits indicate the starts of\n     * basic blocks, including the opcodes that start blocks of\n     * definitely-dead code\n     */\n    private final int[] blockSet;\n\n    /**\n     * {@code non-null, sparse;} for each instruction offset to a branch of\n     * some sort, the list of targets for that instruction\n     */\n    private final IntList[] targetLists;\n\n    /**\n     * {@code non-null, sparse;} for each instruction offset to a throwing\n     * instruction, the list of exception handlers for that instruction\n     */\n    private final ByteCatchList[] catchLists;\n\n    /** offset of the previously parsed bytecode */\n    private int previousOffset;\n\n    /**\n     * Identifies and enumerates the basic blocks in the given method,\n     * returning a list of them. The returned list notably omits any\n     * definitely-dead code that is identified in the process.\n     *\n     * @param method {@code non-null;} method to convert\n     * @return {@code non-null;} list of basic blocks\n     */\n    public static ByteBlockList identifyBlocks(ConcreteMethod method) {\n        BasicBlocker bb = new BasicBlocker(method);\n\n        bb.doit();\n        return bb.getBlockList();\n    }\n\n    /**\n     * Constructs an instance. This class is not publicly instantiable; use\n     * {@link #identifyBlocks}.\n     *\n     * @param method {@code non-null;} method to convert\n     */\n    private BasicBlocker(ConcreteMethod method) {\n        if (method == null) {\n            throw new NullPointerException(\"method == null\");\n        }\n\n        this.method = method;\n\n        /*\n         * The \"+1\" below is so the idx-past-end is also valid,\n         * avoiding a special case, but without preventing\n         * flow-of-control falling past the end of the method from\n         * getting properly reported.\n         */\n        int sz = method.getCode().size() + 1;\n\n        workSet = Bits.makeBitSet(sz);\n        liveSet = Bits.makeBitSet(sz);\n        blockSet = Bits.makeBitSet(sz);\n        targetLists = new IntList[sz];\n        catchLists = new ByteCatchList[sz];\n        previousOffset = -1;\n    }\n\n    /*\n     * Note: These methods are defined implementation of the interface\n     * BytecodeArray.Visitor; since the class isn't publicly\n     * instantiable, no external code ever gets a chance to actually\n     * call these methods.\n     */\n\n    /** {@inheritDoc} */\n    public void visitInvalid(int opcode, int offset, int length) {\n        visitCommon(offset, length, true);\n    }\n\n    /** {@inheritDoc} */\n    public void visitNoArgs(int opcode, int offset, int length, Type type) {\n        switch (opcode) {\n            case ByteOps.IRETURN:\n            case ByteOps.RETURN: {\n                visitCommon(offset, length, false);\n                targetLists[offset] = IntList.EMPTY;\n                break;\n            }\n            case ByteOps.ATHROW: {\n                visitCommon(offset, length, false);\n                visitThrowing(offset, length, false);\n                break;\n            }\n            case ByteOps.IALOAD:\n            case ByteOps.LALOAD:\n            case ByteOps.FALOAD:\n            case ByteOps.DALOAD:\n            case ByteOps.AALOAD:\n            case ByteOps.BALOAD:\n            case ByteOps.CALOAD:\n            case ByteOps.SALOAD:\n            case ByteOps.IASTORE:\n            case ByteOps.LASTORE:\n            case ByteOps.FASTORE:\n            case ByteOps.DASTORE:\n            case ByteOps.AASTORE:\n            case ByteOps.BASTORE:\n            case ByteOps.CASTORE:\n            case ByteOps.SASTORE:\n            case ByteOps.ARRAYLENGTH:\n            case ByteOps.MONITORENTER:\n            case ByteOps.MONITOREXIT: {\n                /*\n                 * These instructions can all throw, so they have to end\n                 * the block they appear in (since throws are branches).\n                 */\n                visitCommon(offset, length, true);\n                visitThrowing(offset, length, true);\n                break;\n            }\n            case ByteOps.IDIV:\n            case ByteOps.IREM: {\n                /*\n                 * The int and long versions of division and remainder may\n                 * throw, but not the other types.\n                 */\n                visitCommon(offset, length, true);\n                if ((type == Type.INT) || (type == Type.LONG)) {\n                    visitThrowing(offset, length, true);\n                }\n                break;\n            }\n            default: {\n                visitCommon(offset, length, true);\n                break;\n            }\n        }\n    }\n\n    /** {@inheritDoc} */\n    public void visitLocal(int opcode, int offset, int length,\n            int idx, Type type, int value) {\n        if (opcode == ByteOps.RET) {\n            visitCommon(offset, length, false);\n            targetLists[offset] = IntList.EMPTY;\n        } else {\n            visitCommon(offset, length, true);\n        }\n    }\n\n    /** {@inheritDoc} */\n    public void visitConstant(int opcode, int offset, int length,\n            Constant cst, int value) {\n        visitCommon(offset, length, true);\n\n        if ((cst instanceof CstMemberRef) || (cst instanceof CstType) ||\n            (cst instanceof CstString)) {\n            /*\n             * Instructions with these sorts of constants have the\n             * possibility of throwing, so this instruction needs to\n             * end its block (since it can throw, and possible-throws\n             * are branch points).\n             */\n            visitThrowing(offset, length, true);\n        }\n    }\n\n    /** {@inheritDoc} */\n    public void visitBranch(int opcode, int offset, int length,\n            int target) {\n        switch (opcode) {\n            case ByteOps.GOTO: {\n                visitCommon(offset, length, false);\n                targetLists[offset] = IntList.makeImmutable(target);\n                break;\n            }\n            case ByteOps.JSR: {\n                /*\n                 * Each jsr is quarantined into a separate block (containing\n                 * only the jsr instruction) but is otherwise treated\n                 * as a conditional branch. (That is to say, both its\n                 * target and next instruction begin new blocks.)\n                 */\n                addWorkIfNecessary(offset, true);\n                // Fall through to next case...\n            }\n            default: {\n                int next = offset + length;\n                visitCommon(offset, length, true);\n                addWorkIfNecessary(next, true);\n                targetLists[offset] = IntList.makeImmutable(next, target);\n                break;\n            }\n        }\n\n        addWorkIfNecessary(target, true);\n    }\n\n    /** {@inheritDoc} */\n    public void visitSwitch(int opcode, int offset, int length,\n            SwitchList cases, int padding) {\n        visitCommon(offset, length, false);\n        addWorkIfNecessary(cases.getDefaultTarget(), true);\n\n        int sz = cases.size();\n        for (int i = 0; i < sz; i++) {\n            addWorkIfNecessary(cases.getTarget(i), true);\n        }\n\n        targetLists[offset] = cases.getTargets();\n    }\n\n    /** {@inheritDoc} */\n    public void visitNewarray(int offset, int length, CstType type,\n            ArrayList<Constant> intVals) {\n        visitCommon(offset, length, true);\n        visitThrowing(offset, length, true);\n    }\n\n    /**\n     * Extracts the list of basic blocks from the bit sets.\n     *\n     * @return {@code non-null;} the list of basic blocks\n     */\n    private ByteBlockList getBlockList() {\n        BytecodeArray bytes = method.getCode();\n        ByteBlock[] bbs = new ByteBlock[bytes.size()];\n        int count = 0;\n\n        for (int at = 0, next; /*at*/; at = next) {\n            next = Bits.findFirst(blockSet, at + 1);\n            if (next < 0) {\n                break;\n            }\n\n            if (Bits.get(liveSet, at)) {\n                /*\n                 * Search backward for the branch or throwing\n                 * instruction at the end of this block, if any. If\n                 * there isn't any, then \"next\" is the sole target.\n                 */\n                IntList targets = null;\n                int targetsAt = -1;\n                ByteCatchList blockCatches;\n\n                for (int i = next - 1; i >= at; i--) {\n                    targets = targetLists[i];\n                    if (targets != null) {\n                        targetsAt = i;\n                        break;\n                    }\n                }\n\n                if (targets == null) {\n                    targets = IntList.makeImmutable(next);\n                    blockCatches = ByteCatchList.EMPTY;\n                } else {\n                    blockCatches = catchLists[targetsAt];\n                    if (blockCatches == null) {\n                        blockCatches = ByteCatchList.EMPTY;\n                    }\n                }\n\n                bbs[count] =\n                    new ByteBlock(at, at, next, targets, blockCatches);\n                count++;\n            }\n        }\n\n        ByteBlockList result = new ByteBlockList(count);\n        for (int i = 0; i < count; i++) {\n            result.set(i, bbs[i]);\n        }\n\n        return result;\n    }\n\n    /**\n     * Does basic block identification.\n     */\n    private void doit() {\n        BytecodeArray bytes = method.getCode();\n        ByteCatchList catches = method.getCatches();\n        int catchSz = catches.size();\n\n        /*\n         * Start by setting offset 0 as the start of a block and in need\n         * of work...\n         */\n        Bits.set(workSet, 0);\n        Bits.set(blockSet, 0);\n\n        /*\n         * And then process the work set, add new work based on\n         * exception ranges that are active, and iterate until there's\n         * nothing left to work on.\n         */\n        while (!Bits.isEmpty(workSet)) {\n            try {\n                bytes.processWorkSet(workSet, this);\n            } catch (IllegalArgumentException ex) {\n                // Translate the exception.\n                throw new SimException(\"flow of control falls off \" +\n                                       \"end of method\",\n                                       ex);\n            }\n\n            for (int i = 0; i < catchSz; i++) {\n                ByteCatchList.Item item = catches.get(i);\n                int start = item.getStartPc();\n                int end = item.getEndPc();\n                if (Bits.anyInRange(liveSet, start, end)) {\n                    Bits.set(blockSet, start);\n                    Bits.set(blockSet, end);\n                    addWorkIfNecessary(item.getHandlerPc(), true);\n                }\n            }\n        }\n    }\n\n    /**\n     * Sets a bit in the work set, but only if the instruction in question\n     * isn't yet known to be possibly-live.\n     *\n     * @param offset offset to the instruction in question\n     * @param blockStart {@code true} iff this instruction starts a\n     * basic block\n     */\n    private void addWorkIfNecessary(int offset, boolean blockStart) {\n        if (!Bits.get(liveSet, offset)) {\n            Bits.set(workSet, offset);\n        }\n\n        if (blockStart) {\n            Bits.set(blockSet, offset);\n        }\n    }\n\n    /**\n     * Helper method used by all the visitor methods.\n     *\n     * @param offset offset to the instruction\n     * @param length length of the instruction, in bytes\n     * @param nextIsLive {@code true} iff the instruction after\n     * the indicated one is possibly-live (because this one isn't an\n     * unconditional branch, a return, or a switch)\n     */\n    private void visitCommon(int offset, int length, boolean nextIsLive) {\n        Bits.set(liveSet, offset);\n\n        if (nextIsLive) {\n            /*\n             * If the next instruction is flowed to by this one, just\n             * add it to the work set, and then a subsequent visit*()\n             * will deal with it as appropriate.\n             */\n            addWorkIfNecessary(offset + length, false);\n        } else {\n            /*\n             * If the next instruction isn't flowed to by this one,\n             * then mark it as a start of a block but *don't* add it\n             * to the work set, so that in the final phase we can know\n             * dead code blocks as those marked as blocks but not also marked\n             * live.\n             */\n            Bits.set(blockSet, offset + length);\n        }\n    }\n\n    /**\n     * Helper method used by all the visitor methods that deal with\n     * opcodes that possibly throw. This method should be called after calling\n     * {@link #visitCommon}.\n     *\n     * @param offset offset to the instruction\n     * @param length length of the instruction, in bytes\n     * @param nextIsLive {@code true} iff the instruction after\n     * the indicated one is possibly-live (because this one isn't an\n     * unconditional throw)\n     */\n    private void visitThrowing(int offset, int length, boolean nextIsLive) {\n        int next = offset + length;\n\n        if (nextIsLive) {\n            addWorkIfNecessary(next, true);\n        }\n\n        ByteCatchList catches = method.getCatches().listFor(offset);\n        catchLists[offset] = catches;\n        targetLists[offset] = catches.toTargetList(nextIsLive ? next : -1);\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    public void setPreviousOffset(int offset) {\n        previousOffset = offset;\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    public int getPreviousOffset() {\n        return previousOffset;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/ByteBlock.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.IntList;\nimport com.taobao.android.dx.util.LabeledItem;\n\n/**\n * Representation of a basic block in a bytecode array.\n */\npublic final class ByteBlock implements LabeledItem {\n    /** {@code >= 0;} label for this block */\n    private final int label;\n\n    /** {@code >= 0;} bytecode offset (inclusive) of the start of the block */\n    private final int start;\n\n    /** {@code > start;} bytecode offset (exclusive) of the end of the block */\n    private final int end;\n\n    /** {@code non-null;} list of successors that this block may branch to */\n    private final IntList successors;\n\n    /** {@code non-null;} list of exceptions caught and their handler targets */\n    private final ByteCatchList catches;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param label {@code >= 0;} target label for this block\n     * @param start {@code >= 0;} bytecode offset (inclusive) of the start\n     * of the block\n     * @param end {@code > start;} bytecode offset (exclusive) of the end\n     * of the block\n     * @param successors {@code non-null;} list of successors that this block may\n     * branch to\n     * @param catches {@code non-null;} list of exceptions caught and their\n     * handler targets\n     */\n    public ByteBlock(int label, int start, int end, IntList successors,\n                     ByteCatchList catches) {\n        if (label < 0) {\n            throw new IllegalArgumentException(\"label < 0\");\n        }\n\n        if (start < 0) {\n            throw new IllegalArgumentException(\"start < 0\");\n        }\n\n        if (end <= start) {\n            throw new IllegalArgumentException(\"end <= start\");\n        }\n\n        if (successors == null) {\n            throw new NullPointerException(\"targets == null\");\n        }\n\n        int sz = successors.size();\n        for (int i = 0; i < sz; i++) {\n            if (successors.get(i) < 0) {\n                throw new IllegalArgumentException(\"successors[\" + i +\n                                                   \"] == \" +\n                                                   successors.get(i));\n            }\n        }\n\n        if (catches == null) {\n            throw new NullPointerException(\"catches == null\");\n        }\n\n        this.label = label;\n        this.start = start;\n        this.end = end;\n        this.successors = successors;\n        this.catches = catches;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return '{' + Hex.u2(label) + \": \" + Hex.u2(start) + \"..\" +\n            Hex.u2(end) + '}';\n    }\n\n    /**\n     * Gets the label of this block.\n     *\n     * @return {@code >= 0;} the label\n     */\n    public int getLabel() {\n        return label;\n    }\n\n    /**\n     * Gets the bytecode offset (inclusive) of the start of this block.\n     *\n     * @return {@code >= 0;} the start offset\n     */\n    public int getStart() {\n        return start;\n    }\n\n    /**\n     * Gets the bytecode offset (exclusive) of the end of this block.\n     *\n     * @return {@code > getStart();} the end offset\n     */\n    public int getEnd() {\n        return end;\n    }\n\n    /**\n     * Gets the list of successors that this block may branch to\n     * non-exceptionally.\n     *\n     * @return {@code non-null;} the successor list\n     */\n    public IntList getSuccessors() {\n        return successors;\n    }\n\n    /**\n     * Gets the list of exceptions caught and their handler targets.\n     *\n     * @return {@code non-null;} the catch list\n     */\n    public ByteCatchList getCatches() {\n        return catches;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/ByteBlockList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.LabeledList;\n\n/**\n * List of {@link ByteBlock} instances.\n */\npublic final class ByteBlockList extends LabeledList {\n\n    /**\n     * Constructs an instance.\n     *\n     * @param size {@code >= 0;} the number of elements to be in the list\n     */\n    public ByteBlockList(int size) {\n        super(size);\n    }\n\n    /**\n     * Gets the indicated element. It is an error to call this with the\n     * index for an element which was never set; if you do that, this\n     * will throw {@code NullPointerException}.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @return {@code non-null;} the indicated element\n     */\n    public ByteBlock get(int n) {\n        return (ByteBlock) get0(n);\n    }\n\n    /**\n     * Gets the block with the given label.\n     *\n     * @param label the label to look for\n     * @return {@code non-null;} the block with the given label\n     */\n    public ByteBlock labelToBlock(int label) {\n        int idx = indexOfLabel(label);\n\n        if (idx < 0) {\n            throw new IllegalArgumentException(\"no such label: \"\n                    + Hex.u2(label));\n        }\n\n        return get(idx);\n    }\n\n    /**\n     * Sets the element at the given index.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @param bb {@code null-ok;} the value to store\n     */\n    public void set(int n, ByteBlock bb) {\n        super.set(n, bb);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/ByteCatchList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.FixedSizeList;\nimport com.taobao.android.dx.util.IntList;\n\n/**\n * List of catch entries, that is, the elements of an \"exception table,\"\n * which is part of a standard {@code Code} attribute.\n */\npublic final class ByteCatchList extends FixedSizeList {\n    /** {@code non-null;} convenient zero-entry instance */\n    public static final ByteCatchList EMPTY = new ByteCatchList(0);\n\n    /**\n     * Constructs an instance.\n     *\n     * @param count the number of elements to be in the table\n     */\n    public ByteCatchList(int count) {\n        super(count);\n    }\n\n    /**\n     * Gets the total length of this structure in bytes, when included in\n     * a {@code Code} attribute. The returned value includes the\n     * two bytes for {@code exception_table_length}.\n     *\n     * @return {@code >= 2;} the total length, in bytes\n     */\n    public int byteLength() {\n        return 2 + size() * 8;\n    }\n\n    /**\n     * Gets the indicated item.\n     *\n     * @param n {@code >= 0;} which item\n     * @return {@code null-ok;} the indicated item\n     */\n    public Item get(int n) {\n        return (Item) get0(n);\n    }\n\n    /**\n     * Sets the item at the given index.\n     *\n     * @param n {@code >= 0, < size();} which entry to set\n     * @param item {@code non-null;} the item\n     */\n    public void set(int n, Item item) {\n        if (item == null) {\n            throw new NullPointerException(\"item == null\");\n        }\n\n        set0(n, item);\n    }\n\n    /**\n     * Sets the item at the given index.\n     *\n     * @param n {@code >= 0, < size();} which entry to set\n     * @param startPc {@code >= 0;} the start pc (inclusive) of the handler's range\n     * @param endPc {@code >= startPc;} the end pc (exclusive) of the\n     * handler's range\n     * @param handlerPc {@code >= 0;} the pc of the exception handler\n     * @param exceptionClass {@code null-ok;} the exception class or\n     * {@code null} to catch all exceptions with this handler\n     */\n    public void set(int n, int startPc, int endPc, int handlerPc,\n            CstType exceptionClass) {\n        set0(n, new Item(startPc, endPc, handlerPc, exceptionClass));\n    }\n\n    /**\n     * Gets the list of items active at the given address. The result is\n     * automatically made immutable.\n     *\n     * @param pc which address\n     * @return {@code non-null;} list of exception handlers active at\n     * {@code pc}\n     */\n    public ByteCatchList listFor(int pc) {\n        int sz = size();\n        Item[] resultArr = new Item[sz];\n        int resultSz = 0;\n\n        for (int i = 0; i < sz; i++) {\n            Item one = get(i);\n            if (one.covers(pc) && typeNotFound(one, resultArr, resultSz)) {\n                resultArr[resultSz] = one;\n                resultSz++;\n            }\n        }\n\n        if (resultSz == 0) {\n            return EMPTY;\n        }\n\n        ByteCatchList result = new ByteCatchList(resultSz);\n        for (int i = 0; i < resultSz; i++) {\n            result.set(i, resultArr[i]);\n        }\n\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Helper method for {@link #listFor}, which tells whether a match\n     * is <i>not</i> found for the exception type of the given item in\n     * the given array. A match is considered to be either an exact type\n     * match or the class {@code Object} which represents a catch-all.\n     *\n     * @param item {@code non-null;} item with the exception type to look for\n     * @param arr {@code non-null;} array to search in\n     * @param count {@code non-null;} maximum number of elements in the array to check\n     * @return {@code true} iff the exception type is <i>not</i> found\n     */\n    private static boolean typeNotFound(Item item, Item[] arr, int count) {\n        CstType type = item.getExceptionClass();\n\n        for (int i = 0; i < count; i++) {\n            CstType one = arr[i].getExceptionClass();\n            if ((one == type) || (one == CstType.OBJECT)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Returns a target list corresponding to this instance. The result\n     * is a list of all the exception handler addresses, with the given\n     * {@code noException} address appended if appropriate. The\n     * result is automatically made immutable.\n     *\n     * @param noException {@code >= -1;} the no-exception address to append, or\n     * {@code -1} not to append anything\n     * @return {@code non-null;} list of exception targets, with\n     * {@code noException} appended if necessary\n     */\n    public IntList toTargetList(int noException) {\n        if (noException < -1) {\n            throw new IllegalArgumentException(\"noException < -1\");\n        }\n\n        boolean hasDefault = (noException >= 0);\n        int sz = size();\n\n        if (sz == 0) {\n            if (hasDefault) {\n                /*\n                 * The list is empty, but there is a no-exception\n                 * address; so, the result is just that address.\n                 */\n                return IntList.makeImmutable(noException);\n            }\n            /*\n             * The list is empty and there isn't even a no-exception\n             * address.\n             */\n            return IntList.EMPTY;\n        }\n\n        IntList result = new IntList(sz + (hasDefault ? 1 : 0));\n\n        for (int i = 0; i < sz; i++) {\n            result.add(get(i).getHandlerPc());\n        }\n\n        if (hasDefault) {\n            result.add(noException);\n        }\n\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Returns a rop-style catches list equivalent to this one.\n     *\n     * @return {@code non-null;} the converted instance\n     */\n    public TypeList toRopCatchList() {\n        int sz = size();\n        if (sz == 0) {\n            return StdTypeList.EMPTY;\n        }\n\n        StdTypeList result = new StdTypeList(sz);\n\n        for (int i = 0; i < sz; i++) {\n            result.set(i, get(i).getExceptionClass().getClassType());\n        }\n\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Item in an exception handler list.\n     */\n    public static class Item {\n        /** {@code >= 0;} the start pc (inclusive) of the handler's range */\n        private final int startPc;\n\n        /** {@code >= startPc;} the end pc (exclusive) of the handler's range */\n        private final int endPc;\n\n        /** {@code >= 0;} the pc of the exception handler */\n        private final int handlerPc;\n\n        /** {@code null-ok;} the exception class or {@code null} to catch all\n         * exceptions with this handler */\n        private final CstType exceptionClass;\n\n        /**\n         * Constructs an instance.\n         *\n         * @param startPc {@code >= 0;} the start pc (inclusive) of the\n         * handler's range\n         * @param endPc {@code >= startPc;} the end pc (exclusive) of the\n         * handler's range\n         * @param handlerPc {@code >= 0;} the pc of the exception handler\n         * @param exceptionClass {@code null-ok;} the exception class or\n         * {@code null} to catch all exceptions with this handler\n         */\n        public Item(int startPc, int endPc, int handlerPc,\n                CstType exceptionClass) {\n            if (startPc < 0) {\n                throw new IllegalArgumentException(\"startPc < 0\");\n            }\n\n            if (endPc < startPc) {\n                throw new IllegalArgumentException(\"endPc < startPc\");\n            }\n\n            if (handlerPc < 0) {\n                throw new IllegalArgumentException(\"handlerPc < 0\");\n            }\n\n            this.startPc = startPc;\n            this.endPc = endPc;\n            this.handlerPc = handlerPc;\n            this.exceptionClass = exceptionClass;\n        }\n\n        /**\n         * Gets the start pc (inclusive) of the handler's range.\n         *\n         * @return {@code >= 0;} the start pc (inclusive) of the handler's range.\n         */\n        public int getStartPc() {\n            return startPc;\n        }\n\n        /**\n         * Gets the end pc (exclusive) of the handler's range.\n         *\n         * @return {@code >= startPc;} the end pc (exclusive) of the\n         * handler's range.\n         */\n        public int getEndPc() {\n            return endPc;\n        }\n\n        /**\n         * Gets the pc of the exception handler.\n         *\n         * @return {@code >= 0;} the pc of the exception handler\n         */\n        public int getHandlerPc() {\n            return handlerPc;\n        }\n\n        /**\n         * Gets the class of exception handled.\n         *\n         * @return {@code non-null;} the exception class; {@link CstType#OBJECT}\n         * if this entry handles all possible exceptions\n         */\n        public CstType getExceptionClass() {\n            return (exceptionClass != null) ?\n                exceptionClass : CstType.OBJECT;\n        }\n\n        /**\n         * Returns whether the given address is in the range of this item.\n         *\n         * @param pc the address\n         * @return {@code true} iff this item covers {@code pc}\n         */\n        public boolean covers(int pc) {\n            return (pc >= startPc) && (pc < endPc);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/ByteOps.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Constants and utility methods for dealing with bytecode arrays at an\n * opcode level.\n */\npublic class ByteOps {\n    // one constant per opcode\n    public static final int NOP = 0x00;\n    public static final int ACONST_NULL = 0x01;\n    public static final int ICONST_M1 = 0x02;\n    public static final int ICONST_0 = 0x03;\n    public static final int ICONST_1 = 0x04;\n    public static final int ICONST_2 = 0x05;\n    public static final int ICONST_3 = 0x06;\n    public static final int ICONST_4 = 0x07;\n    public static final int ICONST_5 = 0x08;\n    public static final int LCONST_0 = 0x09;\n    public static final int LCONST_1 = 0x0a;\n    public static final int FCONST_0 = 0x0b;\n    public static final int FCONST_1 = 0x0c;\n    public static final int FCONST_2 = 0x0d;\n    public static final int DCONST_0 = 0x0e;\n    public static final int DCONST_1 = 0x0f;\n    public static final int BIPUSH = 0x10;\n    public static final int SIPUSH = 0x11;\n    public static final int LDC = 0x12;\n    public static final int LDC_W = 0x13;\n    public static final int LDC2_W = 0x14;\n    public static final int ILOAD = 0x15;\n    public static final int LLOAD = 0x16;\n    public static final int FLOAD = 0x17;\n    public static final int DLOAD = 0x18;\n    public static final int ALOAD = 0x19;\n    public static final int ILOAD_0 = 0x1a;\n    public static final int ILOAD_1 = 0x1b;\n    public static final int ILOAD_2 = 0x1c;\n    public static final int ILOAD_3 = 0x1d;\n    public static final int LLOAD_0 = 0x1e;\n    public static final int LLOAD_1 = 0x1f;\n    public static final int LLOAD_2 = 0x20;\n    public static final int LLOAD_3 = 0x21;\n    public static final int FLOAD_0 = 0x22;\n    public static final int FLOAD_1 = 0x23;\n    public static final int FLOAD_2 = 0x24;\n    public static final int FLOAD_3 = 0x25;\n    public static final int DLOAD_0 = 0x26;\n    public static final int DLOAD_1 = 0x27;\n    public static final int DLOAD_2 = 0x28;\n    public static final int DLOAD_3 = 0x29;\n    public static final int ALOAD_0 = 0x2a;\n    public static final int ALOAD_1 = 0x2b;\n    public static final int ALOAD_2 = 0x2c;\n    public static final int ALOAD_3 = 0x2d;\n    public static final int IALOAD = 0x2e;\n    public static final int LALOAD = 0x2f;\n    public static final int FALOAD = 0x30;\n    public static final int DALOAD = 0x31;\n    public static final int AALOAD = 0x32;\n    public static final int BALOAD = 0x33;\n    public static final int CALOAD = 0x34;\n    public static final int SALOAD = 0x35;\n    public static final int ISTORE = 0x36;\n    public static final int LSTORE = 0x37;\n    public static final int FSTORE = 0x38;\n    public static final int DSTORE = 0x39;\n    public static final int ASTORE = 0x3a;\n    public static final int ISTORE_0 = 0x3b;\n    public static final int ISTORE_1 = 0x3c;\n    public static final int ISTORE_2 = 0x3d;\n    public static final int ISTORE_3 = 0x3e;\n    public static final int LSTORE_0 = 0x3f;\n    public static final int LSTORE_1 = 0x40;\n    public static final int LSTORE_2 = 0x41;\n    public static final int LSTORE_3 = 0x42;\n    public static final int FSTORE_0 = 0x43;\n    public static final int FSTORE_1 = 0x44;\n    public static final int FSTORE_2 = 0x45;\n    public static final int FSTORE_3 = 0x46;\n    public static final int DSTORE_0 = 0x47;\n    public static final int DSTORE_1 = 0x48;\n    public static final int DSTORE_2 = 0x49;\n    public static final int DSTORE_3 = 0x4a;\n    public static final int ASTORE_0 = 0x4b;\n    public static final int ASTORE_1 = 0x4c;\n    public static final int ASTORE_2 = 0x4d;\n    public static final int ASTORE_3 = 0x4e;\n    public static final int IASTORE = 0x4f;\n    public static final int LASTORE = 0x50;\n    public static final int FASTORE = 0x51;\n    public static final int DASTORE = 0x52;\n    public static final int AASTORE = 0x53;\n    public static final int BASTORE = 0x54;\n    public static final int CASTORE = 0x55;\n    public static final int SASTORE = 0x56;\n    public static final int POP = 0x57;\n    public static final int POP2 = 0x58;\n    public static final int DUP = 0x59;\n    public static final int DUP_X1 = 0x5a;\n    public static final int DUP_X2 = 0x5b;\n    public static final int DUP2 = 0x5c;\n    public static final int DUP2_X1 = 0x5d;\n    public static final int DUP2_X2 = 0x5e;\n    public static final int SWAP = 0x5f;\n    public static final int IADD = 0x60;\n    public static final int LADD = 0x61;\n    public static final int FADD = 0x62;\n    public static final int DADD = 0x63;\n    public static final int ISUB = 0x64;\n    public static final int LSUB = 0x65;\n    public static final int FSUB = 0x66;\n    public static final int DSUB = 0x67;\n    public static final int IMUL = 0x68;\n    public static final int LMUL = 0x69;\n    public static final int FMUL = 0x6a;\n    public static final int DMUL = 0x6b;\n    public static final int IDIV = 0x6c;\n    public static final int LDIV = 0x6d;\n    public static final int FDIV = 0x6e;\n    public static final int DDIV = 0x6f;\n    public static final int IREM = 0x70;\n    public static final int LREM = 0x71;\n    public static final int FREM = 0x72;\n    public static final int DREM = 0x73;\n    public static final int INEG = 0x74;\n    public static final int LNEG = 0x75;\n    public static final int FNEG = 0x76;\n    public static final int DNEG = 0x77;\n    public static final int ISHL = 0x78;\n    public static final int LSHL = 0x79;\n    public static final int ISHR = 0x7a;\n    public static final int LSHR = 0x7b;\n    public static final int IUSHR = 0x7c;\n    public static final int LUSHR = 0x7d;\n    public static final int IAND = 0x7e;\n    public static final int LAND = 0x7f;\n    public static final int IOR = 0x80;\n    public static final int LOR = 0x81;\n    public static final int IXOR = 0x82;\n    public static final int LXOR = 0x83;\n    public static final int IINC = 0x84;\n    public static final int I2L = 0x85;\n    public static final int I2F = 0x86;\n    public static final int I2D = 0x87;\n    public static final int L2I = 0x88;\n    public static final int L2F = 0x89;\n    public static final int L2D = 0x8a;\n    public static final int F2I = 0x8b;\n    public static final int F2L = 0x8c;\n    public static final int F2D = 0x8d;\n    public static final int D2I = 0x8e;\n    public static final int D2L = 0x8f;\n    public static final int D2F = 0x90;\n    public static final int I2B = 0x91;\n    public static final int I2C = 0x92;\n    public static final int I2S = 0x93;\n    public static final int LCMP = 0x94;\n    public static final int FCMPL = 0x95;\n    public static final int FCMPG = 0x96;\n    public static final int DCMPL = 0x97;\n    public static final int DCMPG = 0x98;\n    public static final int IFEQ = 0x99;\n    public static final int IFNE = 0x9a;\n    public static final int IFLT = 0x9b;\n    public static final int IFGE = 0x9c;\n    public static final int IFGT = 0x9d;\n    public static final int IFLE = 0x9e;\n    public static final int IF_ICMPEQ = 0x9f;\n    public static final int IF_ICMPNE = 0xa0;\n    public static final int IF_ICMPLT = 0xa1;\n    public static final int IF_ICMPGE = 0xa2;\n    public static final int IF_ICMPGT = 0xa3;\n    public static final int IF_ICMPLE = 0xa4;\n    public static final int IF_ACMPEQ = 0xa5;\n    public static final int IF_ACMPNE = 0xa6;\n    public static final int GOTO = 0xa7;\n    public static final int JSR = 0xa8;\n    public static final int RET = 0xa9;\n    public static final int TABLESWITCH = 0xaa;\n    public static final int LOOKUPSWITCH = 0xab;\n    public static final int IRETURN = 0xac;\n    public static final int LRETURN = 0xad;\n    public static final int FRETURN = 0xae;\n    public static final int DRETURN = 0xaf;\n    public static final int ARETURN = 0xb0;\n    public static final int RETURN = 0xb1;\n    public static final int GETSTATIC = 0xb2;\n    public static final int PUTSTATIC = 0xb3;\n    public static final int GETFIELD = 0xb4;\n    public static final int PUTFIELD = 0xb5;\n    public static final int INVOKEVIRTUAL = 0xb6;\n    public static final int INVOKESPECIAL = 0xb7;\n    public static final int INVOKESTATIC = 0xb8;\n    public static final int INVOKEINTERFACE = 0xb9;\n    public static final int INVOKEDYNAMIC = 0xba;\n    public static final int NEW = 0xbb;\n    public static final int NEWARRAY = 0xbc;\n    public static final int ANEWARRAY = 0xbd;\n    public static final int ARRAYLENGTH = 0xbe;\n    public static final int ATHROW = 0xbf;\n    public static final int CHECKCAST = 0xc0;\n    public static final int INSTANCEOF = 0xc1;\n    public static final int MONITORENTER = 0xc2;\n    public static final int MONITOREXIT = 0xc3;\n    public static final int WIDE = 0xc4;\n    public static final int MULTIANEWARRAY = 0xc5;\n    public static final int IFNULL = 0xc6;\n    public static final int IFNONNULL = 0xc7;\n    public static final int GOTO_W = 0xc8;\n    public static final int JSR_W = 0xc9;\n\n    // a constant for each valid argument to \"newarray\"\n\n    public static final int NEWARRAY_BOOLEAN = 4;\n    public static final int NEWARRAY_CHAR = 5;\n    public static final int NEWARRAY_FLOAT = 6;\n    public static final int NEWARRAY_DOUBLE = 7;\n    public static final int NEWARRAY_BYTE = 8;\n    public static final int NEWARRAY_SHORT = 9;\n    public static final int NEWARRAY_INT = 10;\n    public static final int NEWARRAY_LONG = 11;\n\n    // a constant for each possible instruction format\n\n    /** invalid */\n    public static final int FMT_INVALID = 0;\n\n    /** \"-\": {@code op} */\n    public static final int FMT_NO_ARGS = 1;\n\n    /** \"0\": {@code op}; implies {@code max_locals >= 1} */\n    public static final int FMT_NO_ARGS_LOCALS_1 = 2;\n\n    /** \"1\": {@code op}; implies {@code max_locals >= 2} */\n    public static final int FMT_NO_ARGS_LOCALS_2 = 3;\n\n    /** \"2\": {@code op}; implies {@code max_locals >= 3} */\n    public static final int FMT_NO_ARGS_LOCALS_3 = 4;\n\n    /** \"3\": {@code op}; implies {@code max_locals >= 4} */\n    public static final int FMT_NO_ARGS_LOCALS_4 = 5;\n\n    /** \"4\": {@code op}; implies {@code max_locals >= 5} */\n    public static final int FMT_NO_ARGS_LOCALS_5 = 6;\n\n    /** \"b\": {@code op target target} */\n    public static final int FMT_BRANCH = 7;\n\n    /** \"c\": {@code op target target target target} */\n    public static final int FMT_WIDE_BRANCH = 8;\n\n    /** \"p\": {@code op #cpi #cpi}; constant restricted as specified */\n    public static final int FMT_CPI = 9;\n\n    /**\n     * \"l\": {@code op local}; category-1 local; implies\n     * {@code max_locals} is at least two more than the given\n     * local number\n     */\n    public static final int FMT_LOCAL_1 = 10;\n\n    /**\n     * \"m\": {@code op local}; category-2 local; implies\n     * {@code max_locals} is at least two more than the given\n     * local number\n     */\n    public static final int FMT_LOCAL_2 = 11;\n\n    /**\n     * \"y\": {@code op #byte} ({@code bipush} and\n     * {@code newarray})\n     */\n    public static final int FMT_LITERAL_BYTE = 12;\n\n    /** \"I\": {@code invokeinterface cpi cpi count 0} */\n    public static final int FMT_INVOKEINTERFACE = 13;\n\n    /** \"L\": {@code ldc #cpi}; constant restricted as specified */\n    public static final int FMT_LDC = 14;\n\n    /** \"S\": {@code sipush #byte #byte} */\n    public static final int FMT_SIPUSH = 15;\n\n    /** \"T\": {@code tableswitch ...} */\n    public static final int FMT_TABLESWITCH = 16;\n\n    /** \"U\": {@code lookupswitch ...} */\n    public static final int FMT_LOOKUPSWITCH = 17;\n\n    /** \"M\": {@code multianewarray cpi cpi dims} */\n    public static final int FMT_MULTIANEWARRAY = 18;\n\n    /** \"W\": {@code wide ...} */\n    public static final int FMT_WIDE = 19;\n\n    /** mask for the bits representing the opcode format */\n    public static final int FMT_MASK = 0x1f;\n\n    /** \"I\": flag bit for valid cp type for {@code Integer} */\n    public static final int CPOK_Integer = 0x20;\n\n    /** \"F\": flag bit for valid cp type for {@code Float} */\n    public static final int CPOK_Float = 0x40;\n\n    /** \"J\": flag bit for valid cp type for {@code Long} */\n    public static final int CPOK_Long = 0x80;\n\n    /** \"D\": flag bit for valid cp type for {@code Double} */\n    public static final int CPOK_Double = 0x100;\n\n    /** \"c\": flag bit for valid cp type for {@code Class} */\n    public static final int CPOK_Class = 0x200;\n\n    /** \"s\": flag bit for valid cp type for {@code String} */\n    public static final int CPOK_String = 0x400;\n\n    /** \"f\": flag bit for valid cp type for {@code Fieldref} */\n    public static final int CPOK_Fieldref = 0x800;\n\n    /** \"m\": flag bit for valid cp type for {@code Methodref} */\n    public static final int CPOK_Methodref = 0x1000;\n\n    /** \"i\": flag bit for valid cp type for {@code InterfaceMethodref} */\n    public static final int CPOK_InterfaceMethodref = 0x2000;\n\n    /**\n     * {@code non-null;} map from opcodes to format or'ed with allowed constant\n     * pool types\n     */\n    private static final int[] OPCODE_INFO = new int[256];\n\n    /** {@code non-null;} map from opcodes to their names */\n    private static final String[] OPCODE_NAMES = new String[256];\n\n    /** {@code non-null;} bigass string describing all the opcodes */\n    private static final String OPCODE_DETAILS =\n        \"00 - nop;\" +\n        \"01 - aconst_null;\" +\n        \"02 - iconst_m1;\" +\n        \"03 - iconst_0;\" +\n        \"04 - iconst_1;\" +\n        \"05 - iconst_2;\" +\n        \"06 - iconst_3;\" +\n        \"07 - iconst_4;\" +\n        \"08 - iconst_5;\" +\n        \"09 - lconst_0;\" +\n        \"0a - lconst_1;\" +\n        \"0b - fconst_0;\" +\n        \"0c - fconst_1;\" +\n        \"0d - fconst_2;\" +\n        \"0e - dconst_0;\" +\n        \"0f - dconst_1;\" +\n        \"10 y bipush;\" +\n        \"11 S sipush;\" +\n        \"12 L:IFcs ldc;\" +\n        \"13 p:IFcs ldc_w;\" +\n        \"14 p:DJ ldc2_w;\" +\n        \"15 l iload;\" +\n        \"16 m lload;\" +\n        \"17 l fload;\" +\n        \"18 m dload;\" +\n        \"19 l aload;\" +\n        \"1a 0 iload_0;\" +\n        \"1b 1 iload_1;\" +\n        \"1c 2 iload_2;\" +\n        \"1d 3 iload_3;\" +\n        \"1e 1 lload_0;\" +\n        \"1f 2 lload_1;\" +\n        \"20 3 lload_2;\" +\n        \"21 4 lload_3;\" +\n        \"22 0 fload_0;\" +\n        \"23 1 fload_1;\" +\n        \"24 2 fload_2;\" +\n        \"25 3 fload_3;\" +\n        \"26 1 dload_0;\" +\n        \"27 2 dload_1;\" +\n        \"28 3 dload_2;\" +\n        \"29 4 dload_3;\" +\n        \"2a 0 aload_0;\" +\n        \"2b 1 aload_1;\" +\n        \"2c 2 aload_2;\" +\n        \"2d 3 aload_3;\" +\n        \"2e - iaload;\" +\n        \"2f - laload;\" +\n        \"30 - faload;\" +\n        \"31 - daload;\" +\n        \"32 - aaload;\" +\n        \"33 - baload;\" +\n        \"34 - caload;\" +\n        \"35 - saload;\" +\n        \"36 - istore;\" +\n        \"37 - lstore;\" +\n        \"38 - fstore;\" +\n        \"39 - dstore;\" +\n        \"3a - astore;\" +\n        \"3b 0 istore_0;\" +\n        \"3c 1 istore_1;\" +\n        \"3d 2 istore_2;\" +\n        \"3e 3 istore_3;\" +\n        \"3f 1 lstore_0;\" +\n        \"40 2 lstore_1;\" +\n        \"41 3 lstore_2;\" +\n        \"42 4 lstore_3;\" +\n        \"43 0 fstore_0;\" +\n        \"44 1 fstore_1;\" +\n        \"45 2 fstore_2;\" +\n        \"46 3 fstore_3;\" +\n        \"47 1 dstore_0;\" +\n        \"48 2 dstore_1;\" +\n        \"49 3 dstore_2;\" +\n        \"4a 4 dstore_3;\" +\n        \"4b 0 astore_0;\" +\n        \"4c 1 astore_1;\" +\n        \"4d 2 astore_2;\" +\n        \"4e 3 astore_3;\" +\n        \"4f - iastore;\" +\n        \"50 - lastore;\" +\n        \"51 - fastore;\" +\n        \"52 - dastore;\" +\n        \"53 - aastore;\" +\n        \"54 - bastore;\" +\n        \"55 - castore;\" +\n        \"56 - sastore;\" +\n        \"57 - pop;\" +\n        \"58 - pop2;\" +\n        \"59 - dup;\" +\n        \"5a - dup_x1;\" +\n        \"5b - dup_x2;\" +\n        \"5c - dup2;\" +\n        \"5d - dup2_x1;\" +\n        \"5e - dup2_x2;\" +\n        \"5f - swap;\" +\n        \"60 - iadd;\" +\n        \"61 - ladd;\" +\n        \"62 - fadd;\" +\n        \"63 - dadd;\" +\n        \"64 - isub;\" +\n        \"65 - lsub;\" +\n        \"66 - fsub;\" +\n        \"67 - dsub;\" +\n        \"68 - imul;\" +\n        \"69 - lmul;\" +\n        \"6a - fmul;\" +\n        \"6b - dmul;\" +\n        \"6c - idiv;\" +\n        \"6d - ldiv;\" +\n        \"6e - fdiv;\" +\n        \"6f - ddiv;\" +\n        \"70 - irem;\" +\n        \"71 - lrem;\" +\n        \"72 - frem;\" +\n        \"73 - drem;\" +\n        \"74 - ineg;\" +\n        \"75 - lneg;\" +\n        \"76 - fneg;\" +\n        \"77 - dneg;\" +\n        \"78 - ishl;\" +\n        \"79 - lshl;\" +\n        \"7a - ishr;\" +\n        \"7b - lshr;\" +\n        \"7c - iushr;\" +\n        \"7d - lushr;\" +\n        \"7e - iand;\" +\n        \"7f - land;\" +\n        \"80 - ior;\" +\n        \"81 - lor;\" +\n        \"82 - ixor;\" +\n        \"83 - lxor;\" +\n        \"84 l iinc;\" +\n        \"85 - i2l;\" +\n        \"86 - i2f;\" +\n        \"87 - i2d;\" +\n        \"88 - l2i;\" +\n        \"89 - l2f;\" +\n        \"8a - l2d;\" +\n        \"8b - f2i;\" +\n        \"8c - f2l;\" +\n        \"8d - f2d;\" +\n        \"8e - d2i;\" +\n        \"8f - d2l;\" +\n        \"90 - d2f;\" +\n        \"91 - i2b;\" +\n        \"92 - i2c;\" +\n        \"93 - i2s;\" +\n        \"94 - lcmp;\" +\n        \"95 - fcmpl;\" +\n        \"96 - fcmpg;\" +\n        \"97 - dcmpl;\" +\n        \"98 - dcmpg;\" +\n        \"99 b ifeq;\" +\n        \"9a b ifne;\" +\n        \"9b b iflt;\" +\n        \"9c b ifge;\" +\n        \"9d b ifgt;\" +\n        \"9e b ifle;\" +\n        \"9f b if_icmpeq;\" +\n        \"a0 b if_icmpne;\" +\n        \"a1 b if_icmplt;\" +\n        \"a2 b if_icmpge;\" +\n        \"a3 b if_icmpgt;\" +\n        \"a4 b if_icmple;\" +\n        \"a5 b if_acmpeq;\" +\n        \"a6 b if_acmpne;\" +\n        \"a7 b goto;\" +\n        \"a8 b jsr;\" +\n        \"a9 l ret;\" +\n        \"aa T tableswitch;\" +\n        \"ab U lookupswitch;\" +\n        \"ac - ireturn;\" +\n        \"ad - lreturn;\" +\n        \"ae - freturn;\" +\n        \"af - dreturn;\" +\n        \"b0 - areturn;\" +\n        \"b1 - return;\" +\n        \"b2 p:f getstatic;\" +\n        \"b3 p:f putstatic;\" +\n        \"b4 p:f getfield;\" +\n        \"b5 p:f putfield;\" +\n        \"b6 p:m invokevirtual;\" +\n        \"b7 p:m invokespecial;\" +\n        \"b8 p:m invokestatic;\" +\n        \"b9 I:i invokeinterface;\" +\n        \"bb p:c new;\" +\n        \"bc y newarray;\" +\n        \"bd p:c anewarray;\" +\n        \"be - arraylength;\" +\n        \"bf - athrow;\" +\n        \"c0 p:c checkcast;\" +\n        \"c1 p:c instanceof;\" +\n        \"c2 - monitorenter;\" +\n        \"c3 - monitorexit;\" +\n        \"c4 W wide;\" +\n        \"c5 M:c multianewarray;\" +\n        \"c6 b ifnull;\" +\n        \"c7 b ifnonnull;\" +\n        \"c8 c goto_w;\" +\n        \"c9 c jsr_w;\";\n\n    static {\n        // Set up OPCODE_INFO and OPCODE_NAMES.\n        String s = OPCODE_DETAILS;\n        int len = s.length();\n\n        for (int i = 0; i < len; /*i*/) {\n            int idx = (Character.digit(s.charAt(i), 16) << 4) |\n                Character.digit(s.charAt(i + 1), 16);\n            int info;\n            switch (s.charAt(i + 3)) {\n                case '-': info = FMT_NO_ARGS; break;\n                case '0': info = FMT_NO_ARGS_LOCALS_1; break;\n                case '1': info = FMT_NO_ARGS_LOCALS_2; break;\n                case '2': info = FMT_NO_ARGS_LOCALS_3; break;\n                case '3': info = FMT_NO_ARGS_LOCALS_4; break;\n                case '4': info = FMT_NO_ARGS_LOCALS_5; break;\n                case 'b': info = FMT_BRANCH; break;\n                case 'c': info = FMT_WIDE_BRANCH; break;\n                case 'p': info = FMT_CPI; break;\n                case 'l': info = FMT_LOCAL_1; break;\n                case 'm': info = FMT_LOCAL_2; break;\n                case 'y': info = FMT_LITERAL_BYTE; break;\n                case 'I': info = FMT_INVOKEINTERFACE; break;\n                case 'L': info = FMT_LDC; break;\n                case 'S': info = FMT_SIPUSH; break;\n                case 'T': info = FMT_TABLESWITCH; break;\n                case 'U': info = FMT_LOOKUPSWITCH; break;\n                case 'M': info = FMT_MULTIANEWARRAY; break;\n                case 'W': info = FMT_WIDE; break;\n                default: info = FMT_INVALID; break;\n            }\n\n            i += 5;\n            if (s.charAt(i - 1) == ':') {\n                inner:\n                for (;;) {\n                    switch (s.charAt(i)) {\n                        case 'I': info |= CPOK_Integer; break;\n                        case 'F': info |= CPOK_Float; break;\n                        case 'J': info |= CPOK_Long; break;\n                        case 'D': info |= CPOK_Double; break;\n                        case 'c': info |= CPOK_Class; break;\n                        case 's': info |= CPOK_String; break;\n                        case 'f': info |= CPOK_Fieldref; break;\n                        case 'm': info |= CPOK_Methodref; break;\n                        case 'i': info |= CPOK_InterfaceMethodref; break;\n                        default: break inner;\n                    }\n                    i++;\n                }\n                i++;\n            }\n\n            int endAt = s.indexOf(';', i);\n            OPCODE_INFO[idx] = info;\n            OPCODE_NAMES[idx] = s.substring(i, endAt);\n            i = endAt + 1;\n        }\n    }\n\n    /**\n     * This class is uninstantiable.\n     */\n    private ByteOps() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Gets the name of the given opcode.\n     *\n     * @param opcode {@code >= 0, <= 255;} the opcode\n     * @return {@code non-null;} its name\n     */\n    public static String opName(int opcode) {\n        String result = OPCODE_NAMES[opcode];\n\n        if (result == null) {\n            result = \"unused_\" + Hex.u1(opcode);\n            OPCODE_NAMES[opcode] = result;\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets the format and allowed cp types of the given opcode.\n     *\n     * @param opcode {@code >= 0, <= 255;} the opcode\n     * @return its format and allowed cp types\n     */\n    public static int opInfo(int opcode) {\n        return OPCODE_INFO[opcode];\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/BytecodeArray.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.cf.iface.ParseException;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.ConstantPool;\nimport com.taobao.android.dx.rop.cst.CstDouble;\nimport com.taobao.android.dx.rop.cst.CstFloat;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.cst.CstKnownNull;\nimport com.taobao.android.dx.rop.cst.CstLiteralBits;\nimport com.taobao.android.dx.rop.cst.CstLong;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.Bits;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.ArrayList;\n\n/**\n * Bytecode array, which is part of a standard {@code Code} attribute.\n */\npublic final class BytecodeArray {\n    /** convenient no-op implementation of {@link Visitor} */\n    public static final Visitor EMPTY_VISITOR = new BaseVisitor();\n\n    /** {@code non-null;} underlying bytes */\n    private final ByteArray bytes;\n\n    /**\n     * {@code non-null;} constant pool to use when resolving constant\n     * pool indices\n     */\n    private final ConstantPool pool;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param bytes {@code non-null;} underlying bytes\n     * @param pool {@code non-null;} constant pool to use when\n     * resolving constant pool indices\n     */\n    public BytecodeArray(ByteArray bytes, ConstantPool pool) {\n        if (bytes == null) {\n            throw new NullPointerException(\"bytes == null\");\n        }\n\n        if (pool == null) {\n            throw new NullPointerException(\"pool == null\");\n        }\n\n        this.bytes = bytes;\n        this.pool = pool;\n    }\n\n    /**\n     * Gets the underlying byte array.\n     *\n     * @return {@code non-null;} the byte array\n     */\n    public ByteArray getBytes() {\n        return bytes;\n    }\n\n    /**\n     * Gets the size of the bytecode array, per se.\n     *\n     * @return {@code >= 0;} the length of the bytecode array\n     */\n    public int size() {\n        return bytes.size();\n    }\n\n    /**\n     * Gets the total length of this structure in bytes, when included in\n     * a {@code Code} attribute. The returned value includes the\n     * array size plus four bytes for {@code code_length}.\n     *\n     * @return {@code >= 4;} the total length, in bytes\n     */\n    public int byteLength() {\n        return 4 + bytes.size();\n    }\n\n    /**\n     * Parses each instruction in the array, in order.\n     *\n     * @param visitor {@code null-ok;} visitor to call back to for\n     * each instruction\n     */\n    public void forEach(Visitor visitor) {\n        int sz = bytes.size();\n        int at = 0;\n\n        while (at < sz) {\n            /*\n             * Don't record the previous offset here, so that we get to see the\n             * raw code that initializes the array\n             */\n            at += parseInstruction(at, visitor);\n        }\n    }\n\n    /**\n     * Finds the offset to each instruction in the bytecode array. The\n     * result is a bit set with the offset of each opcode-per-se flipped on.\n     *\n     * @see Bits\n     * @return {@code non-null;} appropriately constructed bit set\n     */\n    public int[] getInstructionOffsets() {\n        int sz = bytes.size();\n        int[] result = Bits.makeBitSet(sz);\n        int at = 0;\n\n        while (at < sz) {\n            Bits.set(result, at, true);\n            int length = parseInstruction(at, null);\n            at += length;\n        }\n\n        return result;\n    }\n\n    /**\n     * Processes the given \"work set\" by repeatedly finding the lowest bit\n     * in the set, clearing it, and parsing and visiting the instruction at\n     * the indicated offset (that is, the bit index), repeating until the\n     * work set is empty. It is expected that the visitor will regularly\n     * set new bits in the work set during the process.\n     *\n     * @param workSet {@code non-null;} the work set to process\n     * @param visitor {@code non-null;} visitor to call back to for\n     * each instruction\n     */\n    public void processWorkSet(int[] workSet, Visitor visitor) {\n        if (visitor == null) {\n            throw new NullPointerException(\"visitor == null\");\n        }\n\n        for (;;) {\n            int offset = Bits.findFirst(workSet, 0);\n            if (offset < 0) {\n                break;\n            }\n            Bits.clear(workSet, offset);\n            parseInstruction(offset, visitor);\n            visitor.setPreviousOffset(offset);\n        }\n    }\n\n    /**\n     * Parses the instruction at the indicated offset. Indicate the\n     * result by calling the visitor if supplied and by returning the\n     * number of bytes consumed by the instruction.\n     *\n     * <p>In order to simplify further processing, the opcodes passed\n     * to the visitor are canonicalized, altering the opcode to a more\n     * universal one and making formerly implicit arguments\n     * explicit. In particular:</p>\n     *\n     * <ul>\n     * <li>The opcodes to push literal constants of primitive types all become\n     *   {@code ldc}.\n     *   E.g., {@code fconst_0}, {@code sipush}, and\n     *   {@code lconst_0} qualify for this treatment.</li>\n     * <li>{@code aconst_null} becomes {@code ldc} of a\n     *   \"known null.\"</li>\n     * <li>Shorthand local variable accessors become the corresponding\n     *   longhand. E.g. {@code aload_2} becomes {@code aload}.</li>\n     * <li>{@code goto_w} and {@code jsr_w} become {@code goto}\n     *   and {@code jsr} (respectively).</li>\n     * <li>{@code ldc_w} becomes {@code ldc}.</li>\n     * <li>{@code tableswitch} becomes {@code lookupswitch}.\n     * <li>Arithmetic, array, and value-returning ops are collapsed\n     *   to the {@code int} variant opcode, with the {@code type}\n     *   argument set to indicate the actual type. E.g.,\n     *   {@code fadd} becomes {@code iadd}, but\n     *   {@code type} is passed as {@code Type.FLOAT} in that\n     *   case. Similarly, {@code areturn} becomes\n     *   {@code ireturn}. (However, {@code return} remains\n     *   unchanged.</li>\n     * <li>Local variable access ops are collapsed to the {@code int}\n     *   variant opcode, with the {@code type} argument set to indicate\n     *   the actual type. E.g., {@code aload} becomes {@code iload},\n     *   but {@code type} is passed as {@code Type.OBJECT} in\n     *   that case.</li>\n     * <li>Numeric conversion ops ({@code i2l}, etc.) are left alone\n     *   to avoid too much confustion, but their {@code type} is\n     *   the pushed type. E.g., {@code i2b} gets type\n     *   {@code Type.INT}, and {@code f2d} gets type\n     *   {@code Type.DOUBLE}. Other unaltered opcodes also get\n     *   their pushed type. E.g., {@code arraylength} gets type\n     *   {@code Type.INT}.</li>\n     * </ul>\n     *\n     * @param offset {@code >= 0, < bytes.size();} offset to the start of the\n     * instruction\n     * @param visitor {@code null-ok;} visitor to call back to\n     * @return the length of the instruction, in bytes\n     */\n    public int parseInstruction(int offset, Visitor visitor) {\n        if (visitor == null) {\n            visitor = EMPTY_VISITOR;\n        }\n\n        try {\n            int opcode = bytes.getUnsignedByte(offset);\n            int info = ByteOps.opInfo(opcode);\n            int fmt = info & ByteOps.FMT_MASK;\n\n            switch (opcode) {\n                case ByteOps.NOP: {\n                    visitor.visitNoArgs(opcode, offset, 1, Type.VOID);\n                    return 1;\n                }\n                case ByteOps.ACONST_NULL: {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstKnownNull.THE_ONE, 0);\n                    return 1;\n                }\n                case ByteOps.ICONST_M1: {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstInteger.VALUE_M1, -1);\n                    return 1;\n                }\n                case ByteOps.ICONST_0: {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstInteger.VALUE_0, 0);\n                    return 1;\n                }\n                case ByteOps.ICONST_1: {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstInteger.VALUE_1, 1);\n                    return 1;\n                }\n                case ByteOps.ICONST_2: {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstInteger.VALUE_2, 2);\n                    return 1;\n                }\n                case ByteOps.ICONST_3: {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstInteger.VALUE_3, 3);\n                    return 1;\n                }\n                case ByteOps.ICONST_4: {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstInteger.VALUE_4, 4);\n                    return 1;\n                }\n                case ByteOps.ICONST_5:  {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstInteger.VALUE_5, 5);\n                    return 1;\n                }\n                case ByteOps.LCONST_0: {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstLong.VALUE_0, 0);\n                    return 1;\n                }\n                case ByteOps.LCONST_1: {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstLong.VALUE_1, 0);\n                    return 1;\n                }\n                case ByteOps.FCONST_0: {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstFloat.VALUE_0, 0);\n                    return 1;\n                }\n                case ByteOps.FCONST_1: {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstFloat.VALUE_1, 0);\n                    return 1;\n                }\n                case ByteOps.FCONST_2:  {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstFloat.VALUE_2, 0);\n                    return 1;\n                }\n                case ByteOps.DCONST_0: {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstDouble.VALUE_0, 0);\n                    return 1;\n                }\n                case ByteOps.DCONST_1: {\n                    visitor.visitConstant(ByteOps.LDC, offset, 1,\n                                          CstDouble.VALUE_1, 0);\n                    return 1;\n                }\n                case ByteOps.BIPUSH: {\n                    int value = bytes.getByte(offset + 1);\n                    visitor.visitConstant(ByteOps.LDC, offset, 2,\n                                          CstInteger.make(value), value);\n                    return 2;\n                }\n                case ByteOps.SIPUSH: {\n                    int value = bytes.getShort(offset + 1);\n                    visitor.visitConstant(ByteOps.LDC, offset, 3,\n                                          CstInteger.make(value), value);\n                    return 3;\n                }\n                case ByteOps.LDC: {\n                    int idx = bytes.getUnsignedByte(offset + 1);\n                    Constant cst = pool.get(idx);\n                    int value = (cst instanceof CstInteger) ?\n                        ((CstInteger) cst).getValue() : 0;\n                    visitor.visitConstant(ByteOps.LDC, offset, 2, cst, value);\n                    return 2;\n                }\n                case ByteOps.LDC_W: {\n                    int idx = bytes.getUnsignedShort(offset + 1);\n                    Constant cst = pool.get(idx);\n                    int value = (cst instanceof CstInteger) ?\n                        ((CstInteger) cst).getValue() : 0;\n                    visitor.visitConstant(ByteOps.LDC, offset, 3, cst, value);\n                    return 3;\n                }\n                case ByteOps.LDC2_W: {\n                    int idx = bytes.getUnsignedShort(offset + 1);\n                    Constant cst = pool.get(idx);\n                    visitor.visitConstant(ByteOps.LDC2_W, offset, 3, cst, 0);\n                    return 3;\n                }\n                case ByteOps.ILOAD: {\n                    int idx = bytes.getUnsignedByte(offset + 1);\n                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx,\n                                       Type.INT, 0);\n                    return 2;\n                }\n                case ByteOps.LLOAD: {\n                    int idx = bytes.getUnsignedByte(offset + 1);\n                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx,\n                                       Type.LONG, 0);\n                    return 2;\n                }\n                case ByteOps.FLOAD: {\n                    int idx = bytes.getUnsignedByte(offset + 1);\n                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx,\n                                       Type.FLOAT, 0);\n                    return 2;\n                }\n                case ByteOps.DLOAD: {\n                    int idx = bytes.getUnsignedByte(offset + 1);\n                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx,\n                                       Type.DOUBLE, 0);\n                    return 2;\n                }\n                case ByteOps.ALOAD: {\n                    int idx = bytes.getUnsignedByte(offset + 1);\n                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx,\n                                       Type.OBJECT, 0);\n                    return 2;\n                }\n                case ByteOps.ILOAD_0:\n                case ByteOps.ILOAD_1:\n                case ByteOps.ILOAD_2:\n                case ByteOps.ILOAD_3: {\n                    int idx = opcode - ByteOps.ILOAD_0;\n                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx,\n                                       Type.INT, 0);\n                    return 1;\n                }\n                case ByteOps.LLOAD_0:\n                case ByteOps.LLOAD_1:\n                case ByteOps.LLOAD_2:\n                case ByteOps.LLOAD_3: {\n                    int idx = opcode - ByteOps.LLOAD_0;\n                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx,\n                                       Type.LONG, 0);\n                    return 1;\n                }\n                case ByteOps.FLOAD_0:\n                case ByteOps.FLOAD_1:\n                case ByteOps.FLOAD_2:\n                case ByteOps.FLOAD_3: {\n                    int idx = opcode - ByteOps.FLOAD_0;\n                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx,\n                                       Type.FLOAT, 0);\n                    return 1;\n                }\n                case ByteOps.DLOAD_0:\n                case ByteOps.DLOAD_1:\n                case ByteOps.DLOAD_2:\n                case ByteOps.DLOAD_3: {\n                    int idx = opcode - ByteOps.DLOAD_0;\n                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx,\n                                       Type.DOUBLE, 0);\n                    return 1;\n                }\n                case ByteOps.ALOAD_0:\n                case ByteOps.ALOAD_1:\n                case ByteOps.ALOAD_2:\n                case ByteOps.ALOAD_3: {\n                    int idx = opcode - ByteOps.ALOAD_0;\n                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx,\n                                       Type.OBJECT, 0);\n                    return 1;\n                }\n                case ByteOps.IALOAD: {\n                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.INT);\n                    return 1;\n                }\n                case ByteOps.LALOAD: {\n                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.LONG);\n                    return 1;\n                }\n                case ByteOps.FALOAD: {\n                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1,\n                                        Type.FLOAT);\n                    return 1;\n                }\n                case ByteOps.DALOAD: {\n                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1,\n                                        Type.DOUBLE);\n                    return 1;\n                }\n                case ByteOps.AALOAD: {\n                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1,\n                                        Type.OBJECT);\n                    return 1;\n                }\n                case ByteOps.BALOAD: {\n                    /*\n                     * Note: This is a load from either a byte[] or a\n                     * boolean[].\n                     */\n                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.BYTE);\n                    return 1;\n                }\n                case ByteOps.CALOAD: {\n                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.CHAR);\n                    return 1;\n                }\n                case ByteOps.SALOAD: {\n                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1,\n                                        Type.SHORT);\n                    return 1;\n                }\n                case ByteOps.ISTORE: {\n                    int idx = bytes.getUnsignedByte(offset + 1);\n                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx,\n                                       Type.INT, 0);\n                    return 2;\n                }\n                case ByteOps.LSTORE: {\n                    int idx = bytes.getUnsignedByte(offset + 1);\n                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx,\n                                       Type.LONG, 0);\n                    return 2;\n                }\n                case ByteOps.FSTORE: {\n                    int idx = bytes.getUnsignedByte(offset + 1);\n                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx,\n                                       Type.FLOAT, 0);\n                    return 2;\n                }\n                case ByteOps.DSTORE: {\n                    int idx = bytes.getUnsignedByte(offset + 1);\n                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx,\n                                       Type.DOUBLE, 0);\n                    return 2;\n                }\n                case ByteOps.ASTORE: {\n                    int idx = bytes.getUnsignedByte(offset + 1);\n                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx,\n                                       Type.OBJECT, 0);\n                    return 2;\n                }\n                case ByteOps.ISTORE_0:\n                case ByteOps.ISTORE_1:\n                case ByteOps.ISTORE_2:\n                case ByteOps.ISTORE_3: {\n                    int idx = opcode - ByteOps.ISTORE_0;\n                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx,\n                                       Type.INT, 0);\n                    return 1;\n                }\n                case ByteOps.LSTORE_0:\n                case ByteOps.LSTORE_1:\n                case ByteOps.LSTORE_2:\n                case ByteOps.LSTORE_3: {\n                    int idx = opcode - ByteOps.LSTORE_0;\n                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx,\n                                       Type.LONG, 0);\n                    return 1;\n                }\n                case ByteOps.FSTORE_0:\n                case ByteOps.FSTORE_1:\n                case ByteOps.FSTORE_2:\n                case ByteOps.FSTORE_3: {\n                    int idx = opcode - ByteOps.FSTORE_0;\n                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx,\n                                       Type.FLOAT, 0);\n                    return 1;\n                }\n                case ByteOps.DSTORE_0:\n                case ByteOps.DSTORE_1:\n                case ByteOps.DSTORE_2:\n                case ByteOps.DSTORE_3: {\n                    int idx = opcode - ByteOps.DSTORE_0;\n                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx,\n                                       Type.DOUBLE, 0);\n                    return 1;\n                }\n                case ByteOps.ASTORE_0:\n                case ByteOps.ASTORE_1:\n                case ByteOps.ASTORE_2:\n                case ByteOps.ASTORE_3: {\n                    int idx = opcode - ByteOps.ASTORE_0;\n                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx,\n                                       Type.OBJECT, 0);\n                    return 1;\n                }\n                case ByteOps.IASTORE: {\n                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, Type.INT);\n                    return 1;\n                }\n                case ByteOps.LASTORE: {\n                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1,\n                                        Type.LONG);\n                    return 1;\n                }\n                case ByteOps.FASTORE: {\n                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1,\n                                        Type.FLOAT);\n                    return 1;\n                }\n                case ByteOps.DASTORE: {\n                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1,\n                                        Type.DOUBLE);\n                    return 1;\n                }\n                case ByteOps.AASTORE: {\n                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1,\n                                        Type.OBJECT);\n                    return 1;\n                }\n                case ByteOps.BASTORE: {\n                    /*\n                     * Note: This is a load from either a byte[] or a\n                     * boolean[].\n                     */\n                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1,\n                                        Type.BYTE);\n                    return 1;\n                }\n                case ByteOps.CASTORE: {\n                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1,\n                                        Type.CHAR);\n                    return 1;\n                }\n                case ByteOps.SASTORE: {\n                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1,\n                                        Type.SHORT);\n                    return 1;\n                }\n                case ByteOps.POP:\n                case ByteOps.POP2:\n                case ByteOps.DUP:\n                case ByteOps.DUP_X1:\n                case ByteOps.DUP_X2:\n                case ByteOps.DUP2:\n                case ByteOps.DUP2_X1:\n                case ByteOps.DUP2_X2:\n                case ByteOps.SWAP: {\n                    visitor.visitNoArgs(opcode, offset, 1, Type.VOID);\n                    return 1;\n                }\n                case ByteOps.IADD:\n                case ByteOps.ISUB:\n                case ByteOps.IMUL:\n                case ByteOps.IDIV:\n                case ByteOps.IREM:\n                case ByteOps.INEG:\n                case ByteOps.ISHL:\n                case ByteOps.ISHR:\n                case ByteOps.IUSHR:\n                case ByteOps.IAND:\n                case ByteOps.IOR:\n                case ByteOps.IXOR: {\n                    visitor.visitNoArgs(opcode, offset, 1, Type.INT);\n                    return 1;\n                }\n                case ByteOps.LADD:\n                case ByteOps.LSUB:\n                case ByteOps.LMUL:\n                case ByteOps.LDIV:\n                case ByteOps.LREM:\n                case ByteOps.LNEG:\n                case ByteOps.LSHL:\n                case ByteOps.LSHR:\n                case ByteOps.LUSHR:\n                case ByteOps.LAND:\n                case ByteOps.LOR:\n                case ByteOps.LXOR: {\n                    /*\n                     * It's \"opcode - 1\" because, conveniently enough, all\n                     * these long ops are one past the int variants.\n                     */\n                    visitor.visitNoArgs(opcode - 1, offset, 1, Type.LONG);\n                    return 1;\n                }\n                case ByteOps.FADD:\n                case ByteOps.FSUB:\n                case ByteOps.FMUL:\n                case ByteOps.FDIV:\n                case ByteOps.FREM:\n                case ByteOps.FNEG: {\n                    /*\n                     * It's \"opcode - 2\" because, conveniently enough, all\n                     * these float ops are two past the int variants.\n                     */\n                    visitor.visitNoArgs(opcode - 2, offset, 1, Type.FLOAT);\n                    return 1;\n                }\n                case ByteOps.DADD:\n                case ByteOps.DSUB:\n                case ByteOps.DMUL:\n                case ByteOps.DDIV:\n                case ByteOps.DREM:\n                case ByteOps.DNEG: {\n                    /*\n                     * It's \"opcode - 3\" because, conveniently enough, all\n                     * these double ops are three past the int variants.\n                     */\n                    visitor.visitNoArgs(opcode - 3, offset, 1, Type.DOUBLE);\n                    return 1;\n                }\n                case ByteOps.IINC: {\n                    int idx = bytes.getUnsignedByte(offset + 1);\n                    int value = bytes.getByte(offset + 2);\n                    visitor.visitLocal(opcode, offset, 3, idx,\n                                       Type.INT, value);\n                    return 3;\n                }\n                case ByteOps.I2L:\n                case ByteOps.F2L:\n                case ByteOps.D2L: {\n                    visitor.visitNoArgs(opcode, offset, 1, Type.LONG);\n                    return 1;\n                }\n                case ByteOps.I2F:\n                case ByteOps.L2F:\n                case ByteOps.D2F: {\n                    visitor.visitNoArgs(opcode, offset, 1, Type.FLOAT);\n                    return 1;\n                }\n                case ByteOps.I2D:\n                case ByteOps.L2D:\n                case ByteOps.F2D: {\n                    visitor.visitNoArgs(opcode, offset, 1, Type.DOUBLE);\n                    return 1;\n                }\n                case ByteOps.L2I:\n                case ByteOps.F2I:\n                case ByteOps.D2I:\n                case ByteOps.I2B:\n                case ByteOps.I2C:\n                case ByteOps.I2S:\n                case ByteOps.LCMP:\n                case ByteOps.FCMPL:\n                case ByteOps.FCMPG:\n                case ByteOps.DCMPL:\n                case ByteOps.DCMPG:\n                case ByteOps.ARRAYLENGTH: {\n                    visitor.visitNoArgs(opcode, offset, 1, Type.INT);\n                    return 1;\n                }\n                case ByteOps.IFEQ:\n                case ByteOps.IFNE:\n                case ByteOps.IFLT:\n                case ByteOps.IFGE:\n                case ByteOps.IFGT:\n                case ByteOps.IFLE:\n                case ByteOps.IF_ICMPEQ:\n                case ByteOps.IF_ICMPNE:\n                case ByteOps.IF_ICMPLT:\n                case ByteOps.IF_ICMPGE:\n                case ByteOps.IF_ICMPGT:\n                case ByteOps.IF_ICMPLE:\n                case ByteOps.IF_ACMPEQ:\n                case ByteOps.IF_ACMPNE:\n                case ByteOps.GOTO:\n                case ByteOps.JSR:\n                case ByteOps.IFNULL:\n                case ByteOps.IFNONNULL: {\n                    int target = offset + bytes.getShort(offset + 1);\n                    visitor.visitBranch(opcode, offset, 3, target);\n                    return 3;\n                }\n                case ByteOps.RET: {\n                    int idx = bytes.getUnsignedByte(offset + 1);\n                    visitor.visitLocal(opcode, offset, 2, idx,\n                                       Type.RETURN_ADDRESS, 0);\n                    return 2;\n                }\n                case ByteOps.TABLESWITCH: {\n                    return parseTableswitch(offset, visitor);\n                }\n                case ByteOps.LOOKUPSWITCH: {\n                    return parseLookupswitch(offset, visitor);\n                }\n                case ByteOps.IRETURN: {\n                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1, Type.INT);\n                    return 1;\n                }\n                case ByteOps.LRETURN: {\n                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1,\n                                        Type.LONG);\n                    return 1;\n                }\n                case ByteOps.FRETURN: {\n                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1,\n                                        Type.FLOAT);\n                    return 1;\n                }\n                case ByteOps.DRETURN: {\n                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1,\n                                        Type.DOUBLE);\n                    return 1;\n                }\n                case ByteOps.ARETURN: {\n                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1,\n                                        Type.OBJECT);\n                    return 1;\n                }\n                case ByteOps.RETURN:\n                case ByteOps.ATHROW:\n                case ByteOps.MONITORENTER:\n                case ByteOps.MONITOREXIT: {\n                    visitor.visitNoArgs(opcode, offset, 1, Type.VOID);\n                    return 1;\n                }\n                case ByteOps.GETSTATIC:\n                case ByteOps.PUTSTATIC:\n                case ByteOps.GETFIELD:\n                case ByteOps.PUTFIELD:\n                case ByteOps.INVOKEVIRTUAL:\n                case ByteOps.INVOKESPECIAL:\n                case ByteOps.INVOKESTATIC:\n                case ByteOps.NEW:\n                case ByteOps.ANEWARRAY:\n                case ByteOps.CHECKCAST:\n                case ByteOps.INSTANCEOF: {\n                    int idx = bytes.getUnsignedShort(offset + 1);\n                    Constant cst = pool.get(idx);\n                    visitor.visitConstant(opcode, offset, 3, cst, 0);\n                    return 3;\n                }\n                case ByteOps.INVOKEINTERFACE: {\n                    int idx = bytes.getUnsignedShort(offset + 1);\n                    int count = bytes.getUnsignedByte(offset + 3);\n                    int expectZero = bytes.getUnsignedByte(offset + 4);\n                    Constant cst = pool.get(idx);\n                    visitor.visitConstant(opcode, offset, 5, cst,\n                                          count | (expectZero << 8));\n                    return 5;\n                }\n                case ByteOps.INVOKEDYNAMIC: {\n                  throw new ParseException(\"invokedynamic not supported\");\n                }\n                case ByteOps.NEWARRAY: {\n                    return parseNewarray(offset, visitor);\n                }\n                case ByteOps.WIDE: {\n                    return parseWide(offset, visitor);\n                }\n                case ByteOps.MULTIANEWARRAY: {\n                    int idx = bytes.getUnsignedShort(offset + 1);\n                    int dimensions = bytes.getUnsignedByte(offset + 3);\n                    Constant cst = pool.get(idx);\n                    visitor.visitConstant(opcode, offset, 4, cst, dimensions);\n                    return 4;\n                }\n                case ByteOps.GOTO_W:\n                case ByteOps.JSR_W: {\n                    int target = offset + bytes.getInt(offset + 1);\n                    int newop =\n                        (opcode == ByteOps.GOTO_W) ? ByteOps.GOTO :\n                        ByteOps.JSR;\n                    visitor.visitBranch(newop, offset, 5, target);\n                    return 5;\n                }\n                default: {\n                    visitor.visitInvalid(opcode, offset, 1);\n                    return 1;\n                }\n            }\n        } catch (SimException ex) {\n            ex.addContext(\"...at bytecode offset \" + Hex.u4(offset));\n            throw ex;\n        } catch (RuntimeException ex) {\n            SimException se = new SimException(ex);\n            se.addContext(\"...at bytecode offset \" + Hex.u4(offset));\n            throw se;\n        }\n    }\n\n    /**\n     * Helper to deal with {@code tableswitch}.\n     *\n     * @param offset the offset to the {@code tableswitch} opcode itself\n     * @param visitor {@code non-null;} visitor to use\n     * @return instruction length, in bytes\n     */\n    private int parseTableswitch(int offset, Visitor visitor) {\n        int at = (offset + 4) & ~3; // \"at\" skips the padding.\n\n        // Collect the padding.\n        int padding = 0;\n        for (int i = offset + 1; i < at; i++) {\n            padding = (padding << 8) | bytes.getUnsignedByte(i);\n        }\n\n        int defaultTarget = offset + bytes.getInt(at);\n        int low = bytes.getInt(at + 4);\n        int high = bytes.getInt(at + 8);\n        int count = high - low + 1;\n        at += 12;\n\n        if (low > high) {\n            throw new SimException(\"low / high inversion\");\n        }\n\n        SwitchList cases = new SwitchList(count);\n        for (int i = 0; i < count; i++) {\n            int target = offset + bytes.getInt(at);\n            at += 4;\n            cases.add(low + i, target);\n        }\n        cases.setDefaultTarget(defaultTarget);\n        cases.removeSuperfluousDefaults();\n        cases.setImmutable();\n\n        int length = at - offset;\n        visitor.visitSwitch(ByteOps.LOOKUPSWITCH, offset, length, cases,\n                            padding);\n\n        return length;\n    }\n\n    /**\n     * Helper to deal with {@code lookupswitch}.\n     *\n     * @param offset the offset to the {@code lookupswitch} opcode itself\n     * @param visitor {@code non-null;} visitor to use\n     * @return instruction length, in bytes\n     */\n    private int parseLookupswitch(int offset, Visitor visitor) {\n        int at = (offset + 4) & ~3; // \"at\" skips the padding.\n\n        // Collect the padding.\n        int padding = 0;\n        for (int i = offset + 1; i < at; i++) {\n            padding = (padding << 8) | bytes.getUnsignedByte(i);\n        }\n\n        int defaultTarget = offset + bytes.getInt(at);\n        int npairs = bytes.getInt(at + 4);\n        at += 8;\n\n        SwitchList cases = new SwitchList(npairs);\n        for (int i = 0; i < npairs; i++) {\n            int match = bytes.getInt(at);\n            int target = offset + bytes.getInt(at + 4);\n            at += 8;\n            cases.add(match, target);\n        }\n        cases.setDefaultTarget(defaultTarget);\n        cases.removeSuperfluousDefaults();\n        cases.setImmutable();\n\n        int length = at - offset;\n        visitor.visitSwitch(ByteOps.LOOKUPSWITCH, offset, length, cases,\n                            padding);\n\n        return length;\n    }\n\n    /**\n     * Helper to deal with {@code newarray}.\n     *\n     * @param offset the offset to the {@code newarray} opcode itself\n     * @param visitor {@code non-null;} visitor to use\n     * @return instruction length, in bytes\n     */\n    private int parseNewarray(int offset, Visitor visitor) {\n        int value = bytes.getUnsignedByte(offset + 1);\n        CstType type;\n        switch (value) {\n            case ByteOps.NEWARRAY_BOOLEAN: {\n                type = CstType.BOOLEAN_ARRAY;\n                break;\n            }\n            case ByteOps.NEWARRAY_CHAR: {\n                type = CstType.CHAR_ARRAY;\n                break;\n            }\n            case ByteOps.NEWARRAY_DOUBLE: {\n                type = CstType.DOUBLE_ARRAY;\n                break;\n            }\n            case ByteOps.NEWARRAY_FLOAT: {\n                type = CstType.FLOAT_ARRAY;\n                break;\n            }\n            case ByteOps.NEWARRAY_BYTE: {\n                type = CstType.BYTE_ARRAY;\n                break;\n            }\n            case ByteOps.NEWARRAY_SHORT: {\n                type = CstType.SHORT_ARRAY;\n                break;\n            }\n            case ByteOps.NEWARRAY_INT: {\n                type = CstType.INT_ARRAY;\n                break;\n            }\n            case ByteOps.NEWARRAY_LONG: {\n                type = CstType.LONG_ARRAY;\n                break;\n            }\n            default: {\n                throw new SimException(\"bad newarray code \" +\n                        Hex.u1(value));\n            }\n        }\n\n        // Revisit the previous bytecode to find out the length of the array\n        int previousOffset = visitor.getPreviousOffset();\n        ConstantParserVisitor constantVisitor = new ConstantParserVisitor();\n        int arrayLength = 0;\n\n        /*\n         * For visitors that don't record the previous offset, -1 will be\n         * seen here\n         */\n        if (previousOffset >= 0) {\n            parseInstruction(previousOffset, constantVisitor);\n            if (constantVisitor.cst instanceof CstInteger &&\n                    constantVisitor.length + previousOffset == offset) {\n                arrayLength = constantVisitor.value;\n\n            }\n        }\n\n        /*\n         * Try to match the array initialization idiom. For example, if the\n         * subsequent code is initializing an int array, we are expecting the\n         * following pattern repeatedly:\n         *  dup\n         *  push index\n         *  push value\n         *  *astore\n         *\n         * where the index value will be incrimented sequentially from 0 up.\n         */\n        int nInit = 0;\n        int curOffset = offset+2;\n        int lastOffset = curOffset;\n        ArrayList<Constant> initVals = new ArrayList<Constant>();\n\n        if (arrayLength != 0) {\n            while (true) {\n                boolean punt = false;\n\n                // First, check if the next bytecode is dup.\n                int nextByte = bytes.getUnsignedByte(curOffset++);\n                if (nextByte != ByteOps.DUP)\n                    break;\n\n                /*\n                 * Next, check if the expected array index is pushed to\n                 * the stack.\n                 */\n                parseInstruction(curOffset, constantVisitor);\n                if (constantVisitor.length == 0 ||\n                        !(constantVisitor.cst instanceof CstInteger) ||\n                        constantVisitor.value != nInit)\n                    break;\n\n                // Next, fetch the init value and record it.\n                curOffset += constantVisitor.length;\n\n                /*\n                 * Next, find out what kind of constant is pushed onto\n                 * the stack.\n                 */\n                parseInstruction(curOffset, constantVisitor);\n                if (constantVisitor.length == 0 ||\n                        !(constantVisitor.cst instanceof CstLiteralBits))\n                    break;\n\n                curOffset += constantVisitor.length;\n                initVals.add(constantVisitor.cst);\n\n                nextByte = bytes.getUnsignedByte(curOffset++);\n                // Now, check if the value is stored to the array properly.\n                switch (value) {\n                    case ByteOps.NEWARRAY_BYTE:\n                    case ByteOps.NEWARRAY_BOOLEAN: {\n                        if (nextByte != ByteOps.BASTORE) {\n                            punt = true;\n                        }\n                        break;\n                    }\n                    case ByteOps.NEWARRAY_CHAR: {\n                        if (nextByte != ByteOps.CASTORE) {\n                            punt = true;\n                        }\n                        break;\n                    }\n                    case ByteOps.NEWARRAY_DOUBLE: {\n                        if (nextByte != ByteOps.DASTORE) {\n                            punt = true;\n                        }\n                        break;\n                    }\n                    case ByteOps.NEWARRAY_FLOAT: {\n                        if (nextByte != ByteOps.FASTORE) {\n                            punt = true;\n                        }\n                        break;\n                    }\n                    case ByteOps.NEWARRAY_SHORT: {\n                        if (nextByte != ByteOps.SASTORE) {\n                            punt = true;\n                        }\n                        break;\n                    }\n                    case ByteOps.NEWARRAY_INT: {\n                        if (nextByte != ByteOps.IASTORE) {\n                            punt = true;\n                        }\n                        break;\n                    }\n                    case ByteOps.NEWARRAY_LONG: {\n                        if (nextByte != ByteOps.LASTORE) {\n                            punt = true;\n                        }\n                        break;\n                    }\n                    default:\n                        punt = true;\n                        break;\n                }\n                if (punt) {\n                    break;\n                }\n                lastOffset = curOffset;\n                nInit++;\n            }\n        }\n\n        /*\n         * For singleton arrays it is still more economical to\n         * generate the aput.\n         */\n        if (nInit < 2 || nInit != arrayLength) {\n            visitor.visitNewarray(offset, 2, type, null);\n            return 2;\n        } else {\n            visitor.visitNewarray(offset, lastOffset - offset, type, initVals);\n            return lastOffset - offset;\n        }\n     }\n\n\n    /**\n     * Helper to deal with {@code wide}.\n     *\n     * @param offset the offset to the {@code wide} opcode itself\n     * @param visitor {@code non-null;} visitor to use\n     * @return instruction length, in bytes\n     */\n    private int parseWide(int offset, Visitor visitor) {\n        int opcode = bytes.getUnsignedByte(offset + 1);\n        int idx = bytes.getUnsignedShort(offset + 2);\n        switch (opcode) {\n            case ByteOps.ILOAD: {\n                visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx,\n                                   Type.INT, 0);\n                return 4;\n            }\n            case ByteOps.LLOAD: {\n                visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx,\n                                   Type.LONG, 0);\n                return 4;\n            }\n            case ByteOps.FLOAD: {\n                visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx,\n                                   Type.FLOAT, 0);\n                return 4;\n            }\n            case ByteOps.DLOAD: {\n                visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx,\n                                   Type.DOUBLE, 0);\n                return 4;\n            }\n            case ByteOps.ALOAD: {\n                visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx,\n                                   Type.OBJECT, 0);\n                return 4;\n            }\n            case ByteOps.ISTORE: {\n                visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx,\n                                   Type.INT, 0);\n                return 4;\n            }\n            case ByteOps.LSTORE: {\n                visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx,\n                                   Type.LONG, 0);\n                return 4;\n            }\n            case ByteOps.FSTORE: {\n                visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx,\n                                   Type.FLOAT, 0);\n                return 4;\n            }\n            case ByteOps.DSTORE: {\n                visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx,\n                                   Type.DOUBLE, 0);\n                return 4;\n            }\n            case ByteOps.ASTORE: {\n                visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx,\n                                   Type.OBJECT, 0);\n                return 4;\n            }\n            case ByteOps.RET: {\n                visitor.visitLocal(opcode, offset, 4, idx,\n                                   Type.RETURN_ADDRESS, 0);\n                return 4;\n            }\n            case ByteOps.IINC: {\n                int value = bytes.getShort(offset + 4);\n                visitor.visitLocal(opcode, offset, 6, idx,\n                                   Type.INT, value);\n                return 6;\n            }\n            default: {\n                visitor.visitInvalid(ByteOps.WIDE, offset, 1);\n                return 1;\n            }\n        }\n    }\n\n    /**\n     * Instruction visitor interface.\n     */\n    public interface Visitor {\n        /**\n         * Visits an invalid instruction.\n         *\n         * @param opcode the opcode\n         * @param offset offset to the instruction\n         * @param length length of the instruction, in bytes\n         */\n        public void visitInvalid(int opcode, int offset, int length);\n\n        /**\n         * Visits an instruction which has no inline arguments\n         * (implicit or explicit).\n         *\n         * @param opcode the opcode\n         * @param offset offset to the instruction\n         * @param length length of the instruction, in bytes\n         * @param type {@code non-null;} type the instruction operates on\n         */\n        public void visitNoArgs(int opcode, int offset, int length,\n                                Type type);\n\n        /**\n         * Visits an instruction which has a local variable index argument.\n         *\n         * @param opcode the opcode\n         * @param offset offset to the instruction\n         * @param length length of the instruction, in bytes\n         * @param idx the local variable index\n         * @param type {@code non-null;} the type of the accessed value\n         * @param value additional literal integer argument, if salient (i.e.,\n         * for {@code iinc})\n         */\n        public void visitLocal(int opcode, int offset, int length,\n                               int idx, Type type, int value);\n\n        /**\n         * Visits an instruction which has a (possibly synthetic)\n         * constant argument, and possibly also an\n         * additional literal integer argument. In the case of\n         * {@code multianewarray}, the argument is the count of\n         * dimensions. In the case of {@code invokeinterface},\n         * the argument is the parameter count or'ed with the\n         * should-be-zero value left-shifted by 8. In the case of entries\n         * of type {@code int}, the {@code value} field always\n         * holds the raw value (for convenience of clients).\n         *\n         * <p><b>Note:</b> In order to avoid giving it a barely-useful\n         * visitor all its own, {@code newarray} also uses this\n         * form, passing {@code value} as the array type code and\n         * {@code cst} as a {@link CstType} instance\n         * corresponding to the array type.</p>\n         *\n         * @param opcode the opcode\n         * @param offset offset to the instruction\n         * @param length length of the instruction, in bytes\n         * @param cst {@code non-null;} the constant\n         * @param value additional literal integer argument, if salient\n         * (ignore if not)\n         */\n        public void visitConstant(int opcode, int offset, int length,\n                                  Constant cst, int value);\n\n        /**\n         * Visits an instruction which has a branch target argument.\n         *\n         * @param opcode the opcode\n         * @param offset offset to the instruction\n         * @param length length of the instruction, in bytes\n         * @param target the absolute (not relative) branch target\n         */\n        public void visitBranch(int opcode, int offset, int length,\n                                int target);\n\n        /**\n         * Visits a switch instruction.\n         *\n         * @param opcode the opcode\n         * @param offset offset to the instruction\n         * @param length length of the instruction, in bytes\n         * @param cases {@code non-null;} list of (value, target)\n         * pairs, plus the default target\n         * @param padding the bytes found in the padding area (if any),\n         * packed\n         */\n        public void visitSwitch(int opcode, int offset, int length,\n                                SwitchList cases, int padding);\n\n        /**\n         * Visits a newarray instruction.\n         *\n         * @param offset   offset to the instruction\n         * @param length   length of the instruction, in bytes\n         * @param type {@code non-null;} the type of the array\n         * @param initVals {@code non-null;} list of bytecode offsets\n         * for init values\n         */\n        public void visitNewarray(int offset, int length, CstType type,\n                                  ArrayList<Constant> initVals);\n\n        /**\n         * Set previous bytecode offset\n         * @param offset    offset of the previous fully parsed bytecode\n         */\n        public void setPreviousOffset(int offset);\n\n        /**\n         * Get previous bytecode offset\n         * @return return the recored offset of the previous bytecode\n         */\n        public int getPreviousOffset();\n    }\n\n    /**\n     * Base implementation of {@link Visitor}, which has empty method\n     * bodies for all methods.\n     */\n    public static class BaseVisitor implements Visitor {\n\n        /** offset of the previously parsed bytecode */\n        private int previousOffset;\n\n        BaseVisitor() {\n            previousOffset = -1;\n        }\n\n        /** {@inheritDoc} */\n        public void visitInvalid(int opcode, int offset, int length) {\n            // This space intentionally left blank.\n        }\n\n        /** {@inheritDoc} */\n        public void visitNoArgs(int opcode, int offset, int length,\n                Type type) {\n            // This space intentionally left blank.\n        }\n\n        /** {@inheritDoc} */\n        public void visitLocal(int opcode, int offset, int length,\n                int idx, Type type, int value) {\n            // This space intentionally left blank.\n        }\n\n        /** {@inheritDoc} */\n        public void visitConstant(int opcode, int offset, int length,\n                Constant cst, int value) {\n            // This space intentionally left blank.\n        }\n\n        /** {@inheritDoc} */\n        public void visitBranch(int opcode, int offset, int length,\n                int target) {\n            // This space intentionally left blank.\n        }\n\n        /** {@inheritDoc} */\n        public void visitSwitch(int opcode, int offset, int length,\n                SwitchList cases, int padding) {\n            // This space intentionally left blank.\n        }\n\n        /** {@inheritDoc} */\n        public void visitNewarray(int offset, int length, CstType type,\n                ArrayList<Constant> initValues) {\n            // This space intentionally left blank.\n        }\n\n        /** {@inheritDoc} */\n        public void setPreviousOffset(int offset) {\n            previousOffset = offset;\n        }\n\n        /** {@inheritDoc} */\n        public int getPreviousOffset() {\n            return previousOffset;\n        }\n    }\n\n    /**\n     * Implementation of {@link Visitor}, which just pays attention\n     * to constant values.\n     */\n    class ConstantParserVisitor extends BaseVisitor {\n        Constant cst;\n        int length;\n        int value;\n\n        /** Empty constructor */\n        ConstantParserVisitor() {\n        }\n\n        private void clear() {\n            length = 0;\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public void visitInvalid(int opcode, int offset, int length) {\n            clear();\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public void visitNoArgs(int opcode, int offset, int length,\n                Type type) {\n            clear();\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public void visitLocal(int opcode, int offset, int length,\n                int idx, Type type, int value) {\n            clear();\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public void visitConstant(int opcode, int offset, int length,\n                Constant cst, int value) {\n            this.cst = cst;\n            this.length = length;\n            this.value = value;\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public void visitBranch(int opcode, int offset, int length,\n                int target) {\n            clear();\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public void visitSwitch(int opcode, int offset, int length,\n                SwitchList cases, int padding) {\n            clear();\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public void visitNewarray(int offset, int length, CstType type,\n                ArrayList<Constant> initVals) {\n            clear();\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public void setPreviousOffset(int offset) {\n            // Intentionally left empty\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public int getPreviousOffset() {\n            // Intentionally left empty\n            return -1;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/ConcreteMethod.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.cf.attrib.AttCode;\nimport com.taobao.android.dx.cf.attrib.AttLineNumberTable;\nimport com.taobao.android.dx.cf.attrib.AttLocalVariableTable;\nimport com.taobao.android.dx.cf.attrib.AttLocalVariableTypeTable;\nimport com.taobao.android.dx.cf.iface.AttributeList;\nimport com.taobao.android.dx.cf.iface.ClassFile;\nimport com.taobao.android.dx.cf.iface.Method;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Prototype;\n\n/**\n * Container for all the giblets that make up a concrete Java bytecode method.\n * It implements {@link Method}, so it provides all the original access\n * (by delegation), but it also constructs and keeps useful versions of\n * stuff extracted from the method's {@code Code} attribute.\n */\npublic final class ConcreteMethod implements Method {\n    /** {@code non-null;} method being wrapped */\n    private final Method method;\n\n    /**\n     * {@code null-ok;} the class's {@code SourceFile} attribute value,\n     * if any\n     */\n    private final CstString sourceFile;\n\n    /**\n     * whether the class that this method is part of is defined with\n     * {@code ACC_SUPER}\n     */\n    private final boolean accSuper;\n\n    /** {@code non-null;} the code attribute */\n    private final AttCode attCode;\n\n    /** {@code non-null;} line number list */\n    private final LineNumberList lineNumbers;\n\n    /** {@code non-null;} local variable list */\n    private final LocalVariableList localVariables;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param method {@code non-null;} the method to be based on\n     * @param cf {@code non-null;} the class file that contains this method\n     * @param keepLines whether to keep the line number information\n     * (if any)\n     * @param keepLocals whether to keep the local variable\n     * information (if any)\n     */\n    public ConcreteMethod(Method method, ClassFile cf, boolean keepLines, boolean keepLocals) {\n        this(method, cf.getAccessFlags(), cf.getSourceFile(), keepLines, keepLocals);\n    }\n\n    public ConcreteMethod(Method method, int accessFlags, CstString sourceFile,\n            boolean keepLines, boolean keepLocals) {\n        this.method = method;\n        this.accSuper = (accessFlags & AccessFlags.ACC_SUPER) != 0;\n        this.sourceFile = sourceFile;\n\n        AttributeList attribs = method.getAttributes();\n        this.attCode = (AttCode) attribs.findFirst(AttCode.ATTRIBUTE_NAME);\n\n        AttributeList codeAttribs = attCode.getAttributes();\n\n        /*\n         * Combine all LineNumberTable attributes into one, with the\n         * combined result saved into the instance. The following code\n         * isn't particularly efficient for doing merges, but as far\n         * as I know, this situation rarely occurs \"in the\n         * wild,\" so there's not much point in optimizing for it.\n         */\n        LineNumberList lineNumbers = LineNumberList.EMPTY;\n        if (keepLines) {\n            for (AttLineNumberTable lnt = (AttLineNumberTable)\n                     codeAttribs.findFirst(AttLineNumberTable.ATTRIBUTE_NAME);\n                 lnt != null;\n                 lnt = (AttLineNumberTable) codeAttribs.findNext(lnt)) {\n                lineNumbers = LineNumberList.concat(lineNumbers,\n                        lnt.getLineNumbers());\n            }\n        }\n        this.lineNumbers = lineNumbers;\n\n        LocalVariableList localVariables = LocalVariableList.EMPTY;\n        if (keepLocals) {\n            /*\n             * Do likewise (and with the same caveat) for\n             * LocalVariableTable and LocalVariableTypeTable attributes.\n             * This combines both of these kinds of attribute into a\n             * single LocalVariableList.\n             */\n            for (AttLocalVariableTable lvt = (AttLocalVariableTable)\n                     codeAttribs.findFirst(\n                             AttLocalVariableTable.ATTRIBUTE_NAME);\n                 lvt != null;\n                 lvt = (AttLocalVariableTable) codeAttribs.findNext(lvt)) {\n                localVariables =\n                    LocalVariableList.concat(localVariables,\n                            lvt.getLocalVariables());\n            }\n\n            LocalVariableList typeList = LocalVariableList.EMPTY;\n            for (AttLocalVariableTypeTable lvtt = (AttLocalVariableTypeTable)\n                     codeAttribs.findFirst(\n                             AttLocalVariableTypeTable.ATTRIBUTE_NAME);\n                 lvtt != null;\n                 lvtt =\n                     (AttLocalVariableTypeTable) codeAttribs.findNext(lvtt)) {\n                typeList =\n                    LocalVariableList.concat(typeList,\n                            lvtt.getLocalVariables());\n            }\n\n            if (typeList.size() != 0) {\n                localVariables =\n                    LocalVariableList.mergeDescriptorsAndSignatures(\n                            localVariables, typeList);\n            }\n        }\n        this.localVariables = localVariables;\n    }\n\n    /** {@inheritDoc} */\n    public CstNat getNat() {\n        return method.getNat();\n    }\n\n    /** {@inheritDoc} */\n    public CstString getName() {\n        return method.getName();\n    }\n\n    /** {@inheritDoc} */\n    public CstString getDescriptor() {\n        return method.getDescriptor();\n    }\n\n    /** {@inheritDoc} */\n    public int getAccessFlags() {\n        return method.getAccessFlags();\n    }\n\n    /** {@inheritDoc} */\n    public AttributeList getAttributes() {\n        return method.getAttributes();\n    }\n\n    /** {@inheritDoc} */\n    public CstType getDefiningClass() {\n        return method.getDefiningClass();\n    }\n\n    /** {@inheritDoc} */\n    public Prototype getEffectiveDescriptor() {\n        return method.getEffectiveDescriptor();\n    }\n\n    /**\n     * Gets whether the class that this method is part of is defined with\n     * {@code ACC_SUPER}.\n     *\n     * @return the {@code ACC_SUPER} value\n     */\n    public boolean getAccSuper() {\n        return accSuper;\n    }\n\n    /**\n     * Gets the maximum stack size.\n     *\n     * @return {@code >= 0;} the maximum stack size\n     */\n    public int getMaxStack() {\n        return attCode.getMaxStack();\n    }\n\n    /**\n     * Gets the number of locals.\n     *\n     * @return {@code >= 0;} the number of locals\n     */\n    public int getMaxLocals() {\n        return attCode.getMaxLocals();\n    }\n\n    /**\n     * Gets the bytecode array.\n     *\n     * @return {@code non-null;} the bytecode array\n     */\n    public BytecodeArray getCode() {\n        return attCode.getCode();\n    }\n\n    /**\n     * Gets the exception table.\n     *\n     * @return {@code non-null;} the exception table\n     */\n    public ByteCatchList getCatches() {\n        return attCode.getCatches();\n    }\n\n    /**\n     * Gets the line number list.\n     *\n     * @return {@code non-null;} the line number list\n     */\n    public LineNumberList getLineNumbers() {\n        return lineNumbers;\n    }\n\n    /**\n     * Gets the local variable list.\n     *\n     * @return {@code non-null;} the local variable list\n     */\n    public LocalVariableList getLocalVariables() {\n        return localVariables;\n    }\n\n    /**\n     * Returns a {@link SourcePosition} instance corresponding to the\n     * given bytecode offset.\n     *\n     * @param offset {@code >= 0;} the bytecode offset\n     * @return {@code non-null;} an appropriate instance\n     */\n    public SourcePosition makeSourcePosistion(int offset) {\n        return new SourcePosition(sourceFile, offset,\n                                  lineNumbers.pcToLine(offset));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/ExecutionStack.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.MutabilityControl;\n\n/**\n * Representation of a Java method execution stack.\n *\n * <p><b>Note:</b> For the most part, the documentation for this class\n * ignores the distinction between {@link Type} and {@link\n * TypeBearer}.</p>\n */\npublic final class ExecutionStack extends MutabilityControl {\n    /** {@code non-null;} array of stack contents */\n    private final TypeBearer[] stack;\n\n    /**\n     * {@code non-null;} array specifying whether stack contents have entries\n     * in the local variable table\n     */\n    private final boolean[] local;\n    /**\n     * {@code >= 0;} stack pointer (points one past the end) / current stack\n     * size\n     */\n    private int stackPtr;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param maxStack {@code >= 0;} the maximum size of the stack for this\n     * instance\n     */\n    public ExecutionStack(int maxStack) {\n        super(maxStack != 0);\n        stack = new TypeBearer[maxStack];\n        local = new boolean[maxStack];\n        stackPtr = 0;\n    }\n\n    /**\n     * Makes and returns a mutable copy of this instance.\n     *\n     * @return {@code non-null;} the copy\n     */\n    public ExecutionStack copy() {\n        ExecutionStack result = new ExecutionStack(stack.length);\n\n        System.arraycopy(stack, 0, result.stack, 0, stack.length);\n        System.arraycopy(local, 0, result.local, 0, local.length);\n        result.stackPtr = stackPtr;\n\n        return result;\n    }\n\n    /**\n     * Annotates (adds context to) the given exception with information\n     * about this instance.\n     *\n     * @param ex {@code non-null;} the exception to annotate\n     */\n    public void annotate(ExceptionWithContext ex) {\n        int limit = stackPtr - 1;\n\n        for (int i = 0; i <= limit; i++) {\n            String idx = (i == limit) ? \"top0\" : Hex.u2(limit - i);\n\n            ex.addContext(\"stack[\" + idx + \"]: \" +\n                          stackElementString(stack[i]));\n        }\n    }\n\n    /**\n     * Replaces all the occurrences of the given uninitialized type in\n     * this stack with its initialized equivalent.\n     *\n     * @param type {@code non-null;} type to replace\n     */\n    public void makeInitialized(Type type) {\n        if (stackPtr == 0) {\n            // We have to check for this before checking for immutability.\n            return;\n        }\n\n        throwIfImmutable();\n\n        Type initializedType = type.getInitializedType();\n\n        for (int i = 0; i < stackPtr; i++) {\n            if (stack[i] == type) {\n                stack[i] = initializedType;\n            }\n        }\n    }\n\n    /**\n     * Gets the maximum stack size for this instance.\n     *\n     * @return {@code >= 0;} the max stack size\n     */\n    public int getMaxStack() {\n        return stack.length;\n    }\n\n    /**\n     * Gets the current stack size.\n     *\n     * @return {@code >= 0, < getMaxStack();} the current stack size\n     */\n    public int size() {\n        return stackPtr;\n    }\n\n    /**\n     * Clears the stack. (That is, this method pops everything off.)\n     */\n    public void clear() {\n        throwIfImmutable();\n\n        for (int i = 0; i < stackPtr; i++) {\n            stack[i] = null;\n            local[i] = false;\n        }\n\n        stackPtr = 0;\n    }\n\n    /**\n     * Pushes a value of the given type onto the stack.\n     *\n     * @param type {@code non-null;} type of the value\n     * @throws SimException thrown if there is insufficient room on the\n     * stack for the value\n     */\n    public void push(TypeBearer type) {\n        throwIfImmutable();\n\n        int category;\n\n        try {\n            type = type.getFrameType();\n            category = type.getType().getCategory();\n        } catch (NullPointerException ex) {\n            // Elucidate the exception.\n            throw new NullPointerException(\"type == null\");\n        }\n\n        if ((stackPtr + category) > stack.length) {\n            throwSimException(\"overflow\");\n            return;\n        }\n\n        if (category == 2) {\n            stack[stackPtr] = null;\n            stackPtr++;\n        }\n\n        stack[stackPtr] = type;\n        stackPtr++;\n    }\n\n    /**\n     * Flags the next value pushed onto the stack as having local info.\n     */\n    public void setLocal() {\n        throwIfImmutable();\n\n        local[stackPtr] = true;\n    }\n\n    /**\n     * Peeks at the {@code n}th element down from the top of the stack.\n     * {@code n == 0} means to peek at the top of the stack. Note that\n     * this will return {@code null} if the indicated element is the\n     * deeper half of a category-2 value.\n     *\n     * @param n {@code >= 0;} which element to peek at\n     * @return {@code null-ok;} the type of value stored at that element\n     * @throws SimException thrown if {@code n >= size()}\n     */\n    public TypeBearer peek(int n) {\n        if (n < 0) {\n            throw new IllegalArgumentException(\"n < 0\");\n        }\n\n        if (n >= stackPtr) {\n            return throwSimException(\"underflow\");\n        }\n\n        return stack[stackPtr - n - 1];\n    }\n\n    /**\n     * Peeks at the {@code n}th element down from the top of the\n     * stack, returning whether or not it has local info.\n     *\n     * @param n {@code >= 0;} which element to peek at\n     * @return {@code true} if the value has local info, {@code false} otherwise\n     * @throws SimException thrown if {@code n >= size()}\n     */\n    public boolean peekLocal(int n) {\n        if (n < 0) {\n            throw new IllegalArgumentException(\"n < 0\");\n        }\n\n        if (n >= stackPtr) {\n            throw new SimException(\"stack: underflow\");\n        }\n\n        return local[stackPtr - n - 1];\n    }\n\n    /**\n     * Peeks at the {@code n}th element down from the top of the\n     * stack, returning the type per se, as opposed to the\n     * <i>type-bearer</i>.  This method is just a convenient shorthand\n     * for {@code peek(n).getType()}.\n     *\n     * @see #peek\n     */\n    public Type peekType(int n) {\n        return peek(n).getType();\n    }\n\n    /**\n     * Pops the top element off of the stack.\n     *\n     * @return {@code non-null;} the type formerly on the top of the stack\n     * @throws SimException thrown if the stack is empty\n     */\n    public TypeBearer pop() {\n        throwIfImmutable();\n\n        TypeBearer result = peek(0);\n\n        stack[stackPtr - 1] = null;\n        local[stackPtr - 1] = false;\n        stackPtr -= result.getType().getCategory();\n\n        return result;\n    }\n\n    /**\n     * Changes an element already on a stack. This method is useful in limited\n     * contexts, particularly when merging two instances. As such, it places\n     * the following restriction on its behavior: You may only replace\n     * values with other values of the same category.\n     *\n     * @param n {@code >= 0;} which element to change, where {@code 0} is\n     * the top element of the stack\n     * @param type {@code non-null;} type of the new value\n     * @throws SimException thrown if {@code n >= size()} or\n     * the action is otherwise prohibited\n     */\n    public void change(int n, TypeBearer type) {\n        throwIfImmutable();\n\n        try {\n            type = type.getFrameType();\n        } catch (NullPointerException ex) {\n            // Elucidate the exception.\n            throw new NullPointerException(\"type == null\");\n        }\n\n        int idx = stackPtr - n - 1;\n        TypeBearer orig = stack[idx];\n\n        if ((orig == null) ||\n            (orig.getType().getCategory() != type.getType().getCategory())) {\n            throwSimException(\"incompatible substitution: \" +\n                              stackElementString(orig) + \" -> \" +\n                              stackElementString(type));\n        }\n\n        stack[idx] = type;\n    }\n\n    /**\n     * Merges this stack with another stack. A new instance is returned if\n     * this merge results in a change. If no change results, this instance is\n     * returned.  See {@link Merger#mergeStack(ExecutionStack,ExecutionStack)\n     * Merger.mergeStack()}\n     *\n     * @param other {@code non-null;} a stack to merge with\n     * @return {@code non-null;} the result of the merge\n     */\n    public ExecutionStack merge(ExecutionStack other) {\n        try {\n            return Merger.mergeStack(this, other);\n        } catch (SimException ex) {\n            ex.addContext(\"underlay stack:\");\n            this.annotate(ex);\n            ex.addContext(\"overlay stack:\");\n            other.annotate(ex);\n            throw ex;\n        }\n    }\n\n    /**\n     * Gets the string form for a stack element. This is the same as\n     * {@code toString()} except that {@code null} is converted\n     * to {@code \"<invalid>\"}.\n     *\n     * @param type {@code null-ok;} the stack element\n     * @return {@code non-null;} the string form\n     */\n    private static String stackElementString(TypeBearer type) {\n        if (type == null) {\n            return \"<invalid>\";\n        }\n\n        return type.toString();\n    }\n\n    /**\n     * Throws a properly-formatted exception.\n     *\n     * @param msg {@code non-null;} useful message\n     * @return never (keeps compiler happy)\n     */\n    private static TypeBearer throwSimException(String msg) {\n        throw new SimException(\"stack: \" + msg);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/Frame.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.IntList;\n\n/**\n * Representation of a Java method execution frame. A frame consists\n * of a set of locals and a value stack, and it can be told to act on\n * them to load and store values between them and an \"arguments /\n * results\" area.\n */\npublic final class Frame {\n    /** {@code non-null;} the locals */\n    private final LocalsArray locals;\n\n    /** {@code non-null;} the stack */\n    private final ExecutionStack stack;\n\n    /** {@code null-ok;} stack of labels of subroutines that this block is nested in */\n    private final IntList subroutines;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param locals {@code non-null;} the locals array to use\n     * @param stack {@code non-null;} the execution stack to use\n     */\n    private Frame(LocalsArray locals, ExecutionStack stack) {\n        this(locals, stack, IntList.EMPTY);\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param locals {@code non-null;} the locals array to use\n     * @param stack {@code non-null;} the execution stack to use\n     * @param subroutines {@code non-null;} list of subroutine start labels for\n     * subroutines this frame is nested in\n     */\n    private Frame(LocalsArray locals,\n            ExecutionStack stack, IntList subroutines) {\n        if (locals == null) {\n            throw new NullPointerException(\"locals == null\");\n        }\n\n        if (stack == null) {\n            throw new NullPointerException(\"stack == null\");\n        }\n\n        subroutines.throwIfMutable();\n\n        this.locals = locals;\n        this.stack = stack;\n        this.subroutines = subroutines;\n    }\n\n    /**\n     * Constructs an instance. The locals array initially consists of\n     * all-uninitialized values (represented as {@code null}s) and\n     * the stack starts out empty.\n     *\n     * @param maxLocals {@code >= 0;} the maximum number of locals this instance\n     * can refer to\n     * @param maxStack {@code >= 0;} the maximum size of the stack for this\n     * instance\n     */\n    public Frame(int maxLocals, int maxStack) {\n        this(new OneLocalsArray(maxLocals), new ExecutionStack(maxStack));\n    }\n\n    /**\n     * Makes and returns a mutable copy of this instance. The copy\n     * contains copies of the locals and stack (that is, it doesn't\n     * share them with the original).\n     *\n     * @return {@code non-null;} the copy\n     */\n    public Frame copy() {\n        return new Frame(locals.copy(), stack.copy(), subroutines);\n    }\n\n    /**\n     * Makes this instance immutable.\n     */\n    public void setImmutable() {\n        locals.setImmutable();\n        stack.setImmutable();\n        // \"subroutines\" is always immutable\n    }\n\n    /**\n     * Replaces all the occurrences of the given uninitialized type in\n     * this frame with its initialized equivalent.\n     *\n     * @param type {@code non-null;} type to replace\n     */\n    public void makeInitialized(Type type) {\n        locals.makeInitialized(type);\n        stack.makeInitialized(type);\n    }\n\n    /**\n     * Gets the locals array for this instance.\n     *\n     * @return {@code non-null;} the locals array\n     */\n    public LocalsArray getLocals() {\n        return locals;\n    }\n\n    /**\n     * Gets the execution stack for this instance.\n     *\n     * @return {@code non-null;} the execution stack\n     */\n    public ExecutionStack getStack() {\n        return stack;\n    }\n\n    /**\n     * Returns the largest subroutine nesting this block may be in. An\n     * empty list is returned if this block is not in any subroutine.\n     * Subroutines are identified by the label of their start block. The\n     * list is ordered such that the deepest nesting (the actual subroutine\n     * this block is in) is the last label in the list.\n     *\n     * @return {@code non-null;} list as noted above\n     */\n    public IntList getSubroutines() {\n        return subroutines;\n    }\n\n    /**\n     * Initialize this frame with the method's parameters. Used for the first\n     * frame.\n     *\n     * @param params Type list of method parameters.\n     */\n    public void initializeWithParameters(StdTypeList params) {\n        int at = 0;\n        int sz = params.size();\n\n        for (int i = 0; i < sz; i++) {\n             Type one = params.get(i);\n             locals.set(at, one);\n             at += one.getCategory();\n        }\n    }\n\n    /**\n     * Returns a Frame instance representing the frame state that should\n     * be used when returning from a subroutine. The stack state of all\n     * subroutine invocations is identical, but the locals state may differ.\n     *\n     * @param startLabel {@code >=0;} The label of the returning subroutine's\n     * start block\n     * @param subLabel {@code >=0;} A calling label of a subroutine\n     * @return {@code null-ok;} an appropriatly-constructed instance, or null\n     * if label is not in the set\n     */\n    public Frame subFrameForLabel(int startLabel, int subLabel) {\n        LocalsArray subLocals = null;\n\n        if (locals instanceof LocalsArraySet) {\n            subLocals = ((LocalsArraySet)locals).subArrayForLabel(subLabel);\n        }\n\n        IntList newSubroutines;\n        try {\n            newSubroutines = subroutines.mutableCopy();\n\n            if (newSubroutines.pop() != startLabel) {\n                throw new RuntimeException(\"returning from invalid subroutine\");\n            }\n            newSubroutines.setImmutable();\n        } catch (IndexOutOfBoundsException ex) {\n            throw new RuntimeException(\"returning from invalid subroutine\");\n        } catch (NullPointerException ex) {\n            throw new NullPointerException(\"can't return from non-subroutine\");\n        }\n\n        return (subLocals == null) ? null\n                : new Frame(subLocals, stack, newSubroutines);\n    }\n\n    /**\n     * Merges two frames. If the merged result is the same as this frame,\n     * then this instance is returned.\n     *\n     * @param other {@code non-null;} another frame\n     * @return {@code non-null;} the result of merging the two frames\n     */\n    public Frame mergeWith(Frame other) {\n        LocalsArray resultLocals;\n        ExecutionStack resultStack;\n        IntList resultSubroutines;\n\n        resultLocals = getLocals().merge(other.getLocals());\n        resultStack = getStack().merge(other.getStack());\n        resultSubroutines = mergeSubroutineLists(other.subroutines);\n\n        resultLocals = adjustLocalsForSubroutines(\n                resultLocals, resultSubroutines);\n\n        if ((resultLocals == getLocals())\n                && (resultStack == getStack())\n                && subroutines == resultSubroutines) {\n            return this;\n        }\n\n        return new Frame(resultLocals, resultStack, resultSubroutines);\n    }\n\n    /**\n     * Merges this frame's subroutine lists with another. The result\n     * is the deepest common nesting (effectively, the common prefix of the\n     * two lists).\n     *\n     * @param otherSubroutines label list of subroutine start blocks, from\n     * least-nested to most-nested.\n     * @return {@code non-null;} merged subroutine nest list as described above\n     */\n    private IntList mergeSubroutineLists(IntList otherSubroutines) {\n        if (subroutines.equals(otherSubroutines)) {\n            return subroutines;\n        }\n\n        IntList resultSubroutines = new IntList();\n\n        int szSubroutines = subroutines.size();\n        int szOthers = otherSubroutines.size();\n        for (int i = 0; i < szSubroutines && i < szOthers\n                && (subroutines.get(i) == otherSubroutines.get(i)); i++) {\n            resultSubroutines.add(i);\n        }\n\n        resultSubroutines.setImmutable();\n\n        return resultSubroutines;\n    }\n\n    /**\n     * Adjusts a locals array to account for a merged subroutines list.\n     * If a frame merge results in, effectively, a subroutine return through\n     * a throw then the current locals will be a LocalsArraySet that will\n     * need to be trimmed of all OneLocalsArray elements that relevent to\n     * the subroutine that is returning.\n     *\n     * @param locals {@code non-null;} LocalsArray from before a merge\n     * @param subroutines {@code non-null;} a label list of subroutine start blocks\n     * representing the subroutine nesting of the block being merged into.\n     * @return {@code non-null;} locals set appropriate for merge\n     */\n    private static LocalsArray adjustLocalsForSubroutines(\n            LocalsArray locals, IntList subroutines) {\n        if (! (locals instanceof LocalsArraySet)) {\n            // nothing to see here\n            return locals;\n        }\n\n        LocalsArraySet laSet = (LocalsArraySet)locals;\n\n        if (subroutines.size() == 0) {\n            /*\n             * We've merged from a subroutine context to a non-subroutine\n             * context, likely via a throw. Our successor will only need\n             * to consider the primary locals state, not the state of\n             * all possible subroutine paths.\n             */\n\n            return laSet.getPrimary();\n        }\n\n        /*\n         * It's unclear to me if the locals set needs to be trimmed here.\n         * If it does, then I believe it is all of the calling blocks\n         * in the subroutine at the end of \"subroutines\" passed into\n         * this method that should be removed.\n         */\n        return laSet;\n    }\n\n    /**\n     * Merges this frame with the frame of a subroutine caller at\n     * {@code predLabel}. Only called on the frame at the first\n     * block of a subroutine.\n     *\n     * @param other {@code non-null;} another frame\n     * @param subLabel label of subroutine start block\n     * @param predLabel label of calling block\n     * @return {@code non-null;} the result of merging the two frames\n     */\n    public Frame mergeWithSubroutineCaller(Frame other, int subLabel,\n            int predLabel) {\n        LocalsArray resultLocals;\n        ExecutionStack resultStack;\n\n        resultLocals = getLocals().mergeWithSubroutineCaller(\n                other.getLocals(), predLabel);\n        resultStack = getStack().merge(other.getStack());\n\n        IntList newOtherSubroutines = other.subroutines.mutableCopy();\n        newOtherSubroutines.add(subLabel);\n        newOtherSubroutines.setImmutable();\n\n        if ((resultLocals == getLocals())\n                && (resultStack == getStack())\n                && subroutines.equals(newOtherSubroutines)) {\n            return this;\n        }\n\n        IntList resultSubroutines;\n\n        if (subroutines.equals(newOtherSubroutines)) {\n            resultSubroutines = subroutines;\n        } else {\n            /*\n             * The new subroutines list should be the deepest of the two\n             * lists being merged, but the postfix of the resultant list\n             * must be equal to the shorter list.\n             */\n            IntList nonResultSubroutines;\n\n            if (subroutines.size() > newOtherSubroutines.size()) {\n                resultSubroutines = subroutines;\n                nonResultSubroutines = newOtherSubroutines;\n            } else {\n                resultSubroutines = newOtherSubroutines;\n                nonResultSubroutines = subroutines;\n            }\n\n            int szResult = resultSubroutines.size();\n            int szNonResult = nonResultSubroutines.size();\n\n            for (int i = szNonResult - 1; i >=0; i-- ) {\n                if (nonResultSubroutines.get(i)\n                        != resultSubroutines.get(\n                        i + (szResult - szNonResult))) {\n                    throw new\n                            RuntimeException(\"Incompatible merged subroutines\");\n                }\n            }\n\n        }\n\n        return new Frame(resultLocals, resultStack, resultSubroutines);\n    }\n\n    /**\n     * Makes a frame for a subroutine start block, given that this is the\n     * ending frame of one of the subroutine's calling blocks. Subroutine\n     * calls may be nested and thus may have nested locals state, so we\n     * start with an initial state as seen by the subroutine, but keep track\n     * of the individual locals states that will be expected when the individual\n     * subroutine calls return.\n     *\n     * @param subLabel label of subroutine start block\n     * @param callerLabel {@code >=0;} label of the caller block where this frame\n     * came from.\n     * @return a new instance to begin a called subroutine.\n     */\n    public Frame makeNewSubroutineStartFrame(int subLabel, int callerLabel) {\n        IntList newSubroutines = subroutines.mutableCopy();\n        newSubroutines.add(subLabel);\n        Frame newFrame = new Frame(locals.getPrimary(), stack,\n                IntList.makeImmutable(subLabel));\n        return newFrame.mergeWithSubroutineCaller(this, subLabel, callerLabel);\n    }\n\n    /**\n     * Makes a new frame for an exception handler block invoked from this\n     * frame.\n     *\n     * @param exceptionClass exception that the handler block will handle\n     * @return new frame\n     */\n    public Frame makeExceptionHandlerStartFrame(CstType exceptionClass) {\n        ExecutionStack newStack = getStack().copy();\n\n        newStack.clear();\n        newStack.push(exceptionClass);\n\n        return new Frame(getLocals(), newStack, subroutines);\n    }\n\n    /**\n     * Annotates (adds context to) the given exception with information\n     * about this frame.\n     *\n     * @param ex {@code non-null;} the exception to annotate\n     */\n    public void annotate(ExceptionWithContext ex) {\n        locals.annotate(ex);\n        stack.annotate(ex);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/LineNumberList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.util.FixedSizeList;\n\n/**\n * List of \"line number\" entries, which are the contents of\n * {@code LineNumberTable} attributes.\n */\npublic final class LineNumberList extends FixedSizeList {\n    /** {@code non-null;} zero-size instance */\n    public static final LineNumberList EMPTY = new LineNumberList(0);\n\n    /**\n     * Returns an instance which is the concatenation of the two given\n     * instances.\n     *\n     * @param list1 {@code non-null;} first instance\n     * @param list2 {@code non-null;} second instance\n     * @return {@code non-null;} combined instance\n     */\n    public static LineNumberList concat(LineNumberList list1,\n                                        LineNumberList list2) {\n        if (list1 == EMPTY) {\n            // easy case\n            return list2;\n        }\n\n        int sz1 = list1.size();\n        int sz2 = list2.size();\n        LineNumberList result = new LineNumberList(sz1 + sz2);\n\n        for (int i = 0; i < sz1; i++) {\n            result.set(i, list1.get(i));\n        }\n\n        for (int i = 0; i < sz2; i++) {\n            result.set(sz1 + i, list2.get(i));\n        }\n\n        return result;\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param count the number of elements to be in the list\n     */\n    public LineNumberList(int count) {\n        super(count);\n    }\n\n    /**\n     * Gets the indicated item.\n     *\n     * @param n {@code >= 0;} which item\n     * @return {@code null-ok;} the indicated item\n     */\n    public Item get(int n) {\n        return (Item) get0(n);\n    }\n\n    /**\n     * Sets the item at the given index.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @param item {@code non-null;} the item\n     */\n    public void set(int n, Item item) {\n        if (item == null) {\n            throw new NullPointerException(\"item == null\");\n        }\n\n        set0(n, item);\n    }\n\n    /**\n     * Sets the item at the given index.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @param startPc {@code >= 0;} start pc of this item\n     * @param lineNumber {@code >= 0;} corresponding line number\n     */\n    public void set(int n, int startPc, int lineNumber) {\n        set0(n, new Item(startPc, lineNumber));\n    }\n\n    /**\n     * Gets the line number associated with the given address.\n     *\n     * @param pc {@code >= 0;} the address to look up\n     * @return {@code >= -1;} the associated line number, or {@code -1} if\n     * none is known\n     */\n    public int pcToLine(int pc) {\n        /*\n         * Line number entries don't have to appear in any particular\n         * order, so we have to do a linear search. TODO: If\n         * this turns out to be a bottleneck, consider sorting the\n         * list prior to use.\n         */\n        int sz = size();\n        int bestPc = -1;\n        int bestLine = -1;\n\n        for (int i = 0; i < sz; i++) {\n            Item one = get(i);\n            int onePc = one.getStartPc();\n            if ((onePc <= pc) && (onePc > bestPc)) {\n                bestPc = onePc;\n                bestLine = one.getLineNumber();\n                if (bestPc == pc) {\n                    // We can't do better than this\n                    break;\n                }\n            }\n        }\n\n        return bestLine;\n    }\n\n    /**\n     * Item in a line number table.\n     */\n    public static class Item {\n        /** {@code >= 0;} start pc of this item */\n        private final int startPc;\n\n        /** {@code >= 0;} corresponding line number */\n        private final int lineNumber;\n\n        /**\n         * Constructs an instance.\n         *\n         * @param startPc {@code >= 0;} start pc of this item\n         * @param lineNumber {@code >= 0;} corresponding line number\n         */\n        public Item(int startPc, int lineNumber) {\n            if (startPc < 0) {\n                throw new IllegalArgumentException(\"startPc < 0\");\n            }\n\n            if (lineNumber < 0) {\n                throw new IllegalArgumentException(\"lineNumber < 0\");\n            }\n\n            this.startPc = startPc;\n            this.lineNumber = lineNumber;\n        }\n\n        /**\n         * Gets the start pc of this item.\n         *\n         * @return the start pc\n         */\n        public int getStartPc() {\n            return startPc;\n        }\n\n        /**\n         * Gets the line number of this item.\n         *\n         * @return the line number\n         */\n        public int getLineNumber() {\n            return lineNumber;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/LocalVariableList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.rop.code.LocalItem;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.FixedSizeList;\n\n/**\n * List of \"local variable\" entries, which are the contents of\n * {@code LocalVariableTable} and {@code LocalVariableTypeTable}\n * attributes, as well as combinations of the two.\n */\npublic final class LocalVariableList extends FixedSizeList {\n    /** {@code non-null;} zero-size instance */\n    public static final LocalVariableList EMPTY = new LocalVariableList(0);\n\n    /**\n     * Returns an instance which is the concatenation of the two given\n     * instances. The result is immutable.\n     *\n     * @param list1 {@code non-null;} first instance\n     * @param list2 {@code non-null;} second instance\n     * @return {@code non-null;} combined instance\n     */\n    public static LocalVariableList concat(LocalVariableList list1,\n                                           LocalVariableList list2) {\n        if (list1 == EMPTY) {\n            // easy case\n            return list2;\n        }\n\n        int sz1 = list1.size();\n        int sz2 = list2.size();\n        LocalVariableList result = new LocalVariableList(sz1 + sz2);\n\n        for (int i = 0; i < sz1; i++) {\n            result.set(i, list1.get(i));\n        }\n\n        for (int i = 0; i < sz2; i++) {\n            result.set(sz1 + i, list2.get(i));\n        }\n\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Returns an instance which is the result of merging the two\n     * given instances, where one instance should have only type\n     * descriptors and the other only type signatures. The merged\n     * result is identical to the one with descriptors, except that\n     * any element whose {name, index, start, length} matches an\n     * element in the signature list gets augmented with the\n     * corresponding signature. The result is immutable.\n     *\n     * @param descriptorList {@code non-null;} list with descriptors\n     * @param signatureList {@code non-null;} list with signatures\n     * @return {@code non-null;} the merged result\n     */\n    public static LocalVariableList mergeDescriptorsAndSignatures(\n            LocalVariableList descriptorList,\n            LocalVariableList signatureList) {\n        int descriptorSize = descriptorList.size();\n        LocalVariableList result = new LocalVariableList(descriptorSize);\n\n        for (int i = 0; i < descriptorSize; i++) {\n            Item item = descriptorList.get(i);\n            Item signatureItem = signatureList.itemToLocal(item);\n            if (signatureItem != null) {\n                CstString signature = signatureItem.getSignature();\n                item = item.withSignature(signature);\n            }\n            result.set(i, item);\n        }\n\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param count the number of elements to be in the list\n     */\n    public LocalVariableList(int count) {\n        super(count);\n    }\n\n    /**\n     * Gets the indicated item.\n     *\n     * @param n {@code >= 0;} which item\n     * @return {@code null-ok;} the indicated item\n     */\n    public Item get(int n) {\n        return (Item) get0(n);\n    }\n\n    /**\n     * Sets the item at the given index.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @param item {@code non-null;} the item\n     */\n    public void set(int n, Item item) {\n        if (item == null) {\n            throw new NullPointerException(\"item == null\");\n        }\n\n        set0(n, item);\n    }\n\n    /**\n     * Sets the item at the given index.\n     *\n     * <p><b>Note:</b> At least one of {@code descriptor} or\n     * {@code signature} must be passed as non-null.</p>\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @param startPc {@code >= 0;} the start pc of this variable's scope\n     * @param length {@code >= 0;} the length (in bytecodes) of this variable's\n     * scope\n     * @param name {@code non-null;} the variable's name\n     * @param descriptor {@code null-ok;} the variable's type descriptor\n     * @param signature {@code null-ok;} the variable's type signature\n     * @param index {@code >= 0;} the variable's local index\n     */\n    public void set(int n, int startPc, int length, CstString name,\n            CstString descriptor, CstString signature, int index) {\n        set0(n, new Item(startPc, length, name, descriptor, signature, index));\n    }\n\n    /**\n     * Gets the local variable information in this instance which matches\n     * the given {@link com.taobao.android.dx.cf.code.LocalVariableList.Item}\n     * in all respects but the type descriptor and signature, if any.\n     *\n     * @param item {@code non-null;} local variable information to match\n     * @return {@code null-ok;} the corresponding local variable information stored\n     * in this instance, or {@code null} if there is no matching\n     * information\n     */\n    public Item itemToLocal(Item item) {\n        int sz = size();\n\n        for (int i = 0; i < sz; i++) {\n            Item one = (Item) get0(i);\n\n            if ((one != null) && one.matchesAllButType(item)) {\n                return one;\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Gets the local variable information associated with a given address\n     * and local index, if any. <b>Note:</b> In standard classfiles, a\n     * variable's start point is listed as the address of the instruction\n     * <i>just past</i> the one that sets the variable.\n     *\n     * @param pc {@code >= 0;} the address to look up\n     * @param index {@code >= 0;} the local variable index\n     * @return {@code null-ok;} the associated local variable information, or\n     * {@code null} if none is known\n     */\n    public Item pcAndIndexToLocal(int pc, int index) {\n        int sz = size();\n\n        for (int i = 0; i < sz; i++) {\n            Item one = (Item) get0(i);\n\n            if ((one != null) && one.matchesPcAndIndex(pc, index)) {\n                return one;\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Item in a local variable table.\n     */\n    public static class Item {\n        /** {@code >= 0;} the start pc of this variable's scope */\n        private final int startPc;\n\n        /** {@code >= 0;} the length (in bytecodes) of this variable's scope */\n        private final int length;\n\n        /** {@code non-null;} the variable's name */\n        private final CstString name;\n\n        /** {@code null-ok;} the variable's type descriptor */\n        private final CstString descriptor;\n\n        /** {@code null-ok;} the variable's type signature */\n        private final CstString signature;\n\n        /** {@code >= 0;} the variable's local index */\n        private final int index;\n\n        /**\n         * Constructs an instance.\n         *\n         * <p><b>Note:</b> At least one of {@code descriptor} or\n         * {@code signature} must be passed as non-null.</p>\n         *\n         * @param startPc {@code >= 0;} the start pc of this variable's scope\n         * @param length {@code >= 0;} the length (in bytecodes) of this variable's\n         * scope\n         * @param name {@code non-null;} the variable's name\n         * @param descriptor {@code null-ok;} the variable's type descriptor\n         * @param signature {@code null-ok;} the variable's type signature\n         * @param index {@code >= 0;} the variable's local index\n         */\n        public Item(int startPc, int length, CstString name,\n                CstString descriptor, CstString signature, int index) {\n            if (startPc < 0) {\n                throw new IllegalArgumentException(\"startPc < 0\");\n            }\n\n            if (length < 0) {\n                throw new IllegalArgumentException(\"length < 0\");\n            }\n\n            if (name == null) {\n                throw new NullPointerException(\"name == null\");\n            }\n\n            if ((descriptor == null) && (signature == null)) {\n                throw new NullPointerException(\n                        \"(descriptor == null) && (signature == null)\");\n            }\n\n            if (index < 0) {\n                throw new IllegalArgumentException(\"index < 0\");\n            }\n\n            this.startPc = startPc;\n            this.length = length;\n            this.name = name;\n            this.descriptor = descriptor;\n            this.signature = signature;\n            this.index = index;\n        }\n\n        /**\n         * Gets the start pc of this variable's scope.\n         *\n         * @return {@code >= 0;} the start pc of this variable's scope\n         */\n        public int getStartPc() {\n            return startPc;\n        }\n\n        /**\n         * Gets the length (in bytecodes) of this variable's scope.\n         *\n         * @return {@code >= 0;} the length (in bytecodes) of this variable's scope\n         */\n        public int getLength() {\n            return length;\n        }\n\n        /**\n         * Gets the variable's type descriptor.\n         *\n         * @return {@code null-ok;} the variable's type descriptor\n         */\n        public CstString getDescriptor() {\n            return descriptor;\n        }\n\n        /**\n         * Gets the variable's LocalItem, a (name, signature) tuple\n         *\n         * @return {@code null-ok;} the variable's type descriptor\n         */\n        public LocalItem getLocalItem() {\n            return LocalItem.make(name, signature);\n        }\n\n        /**\n         * Gets the variable's type signature. Private because if you need this,\n         * you want getLocalItem() instead.\n         *\n         * @return {@code null-ok;} the variable's type signature\n         */\n        private CstString getSignature() {\n            return signature;\n        }\n\n        /**\n         * Gets the variable's local index.\n         *\n         * @return {@code >= 0;} the variable's local index\n         */\n        public int getIndex() {\n            return index;\n        }\n\n        /**\n         * Gets the variable's type descriptor. This is a convenient shorthand\n         * for {@code Type.intern(getDescriptor().getString())}.\n         *\n         * @return {@code non-null;} the variable's type\n         */\n        public Type getType() {\n            return Type.intern(descriptor.getString());\n        }\n\n        /**\n         * Constructs and returns an instance which is identical to this\n         * one, except that the signature is changed to the given value.\n         *\n         * @param newSignature {@code non-null;} the new signature\n         * @return {@code non-null;} an appropriately-constructed instance\n         */\n        public Item withSignature(CstString newSignature) {\n            return new Item(startPc, length, name, descriptor, newSignature,\n                    index);\n        }\n\n        /**\n         * Gets whether this instance matches (describes) the given\n         * address and index.\n         *\n         * @param pc {@code >= 0;} the address in question\n         * @param index {@code >= 0;} the local variable index in question\n         * @return {@code true} iff this instance matches {@code pc}\n         * and {@code index}\n         */\n        public boolean matchesPcAndIndex(int pc, int index) {\n            return (index == this.index) &&\n                (pc >= startPc) &&\n                (pc < (startPc + length));\n        }\n\n        /**\n         * Gets whether this instance matches (describes) the given\n         * other instance exactly in all fields except type descriptor and\n         * type signature.\n         *\n         * @param other {@code non-null;} the instance to compare to\n         * @return {@code true} iff this instance matches\n         */\n        public boolean matchesAllButType(Item other) {\n            return (startPc == other.startPc)\n                && (length == other.length)\n                && (index == other.index)\n                && name.equals(other.name);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/LocalsArray.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport com.taobao.android.dx.util.MutabilityControl;\nimport com.taobao.android.dx.util.ToHuman;\n\n/**\n * Representation of an array of local variables, with Java semantics.\n *\n * <p><b>Note:</b> For the most part, the documentation for this class\n * ignores the distinction between {@link Type} and {@link\n * TypeBearer}.</p>\n */\npublic abstract class LocalsArray extends MutabilityControl implements ToHuman {\n\n    /**\n     * Constructs an instance, explicitly indicating the mutability.\n     *\n     * @param mutable {@code true} if this instance is mutable\n     */\n    protected LocalsArray(boolean mutable) {\n        super(mutable);\n    }\n\n    /**\n     * Makes and returns a mutable copy of this instance.\n     *\n     * @return {@code non-null;} the copy\n     */\n    public abstract LocalsArray copy();\n\n    /**\n     * Annotates (adds context to) the given exception with information\n     * about this instance.\n     *\n     * @param ex {@code non-null;} the exception to annotate\n     */\n    public abstract void annotate(ExceptionWithContext ex);\n\n    /**\n     * Replaces all the occurrences of the given uninitialized type in\n     * this array with its initialized equivalent.\n     *\n     * @param type {@code non-null;} type to replace\n     */\n    public abstract void makeInitialized(Type type);\n\n    /**\n     * Gets the maximum number of locals this instance can refer to.\n     *\n     * @return the max locals\n     */\n    public abstract int getMaxLocals();\n\n    /**\n     * Sets the type stored at the given local index. If the given type\n     * is category-2, then (a) the index must be at least two less than\n     * {@link #getMaxLocals} and (b) the next index gets invalidated\n     * by the operation. In case of either category, if the <i>previous</i>\n     * local contains a category-2 value, then it too is invalidated by\n     * this operation.\n     *\n     * @param idx {@code >= 0, < getMaxLocals();} which local\n     * @param type {@code non-null;} new type for the local at {@code idx}\n     */\n    public abstract void set(int idx, TypeBearer type);\n\n    /**\n     * Sets the type for the local indicated by the given register spec\n     * to that register spec (which includes type and optional name\n     * information). This is identical to calling\n     * {@code set(spec.getReg(), spec)}.\n     *\n     * @param spec {@code non-null;} register spec to use as the basis for the update\n     */\n    public abstract void set(RegisterSpec spec);\n\n    /**\n     * Invalidates the local at the given index.\n     *\n     * @param idx {@code >= 0, < getMaxLocals();} which local\n     */\n    public abstract void invalidate(int idx);\n\n    /**\n     * Gets the type stored at the given local index, or {@code null}\n     * if the given local is uninitialized / invalid.\n     *\n     * @param idx {@code >= 0, < getMaxLocals();} which local\n     * @return {@code null-ok;} the type of value stored in that local\n     */\n    public abstract TypeBearer getOrNull(int idx);\n\n    /**\n     * Gets the type stored at the given local index, only succeeding if\n     * the given local contains a valid type (though it is allowed to\n     * be an uninitialized instance).\n     *\n     * @param idx {@code >= 0, < getMaxLocals();} which local\n     * @return {@code non-null;} the type of value stored in that local\n     * @throws SimException thrown if {@code idx} is valid, but\n     * the contents are invalid\n     */\n    public abstract TypeBearer get(int idx);\n\n    /**\n     * Gets the type stored at the given local index, which is expected\n     * to be an initialized category-1 value.\n     *\n     * @param idx {@code >= 0, < getMaxLocals();} which local\n     * @return {@code non-null;} the type of value stored in that local\n     * @throws SimException thrown if {@code idx} is valid, but\n     * one of the following holds: (a) the local is invalid; (b) the local\n     * contains an uninitialized instance; (c) the local contains a\n     * category-2 value\n     */\n    public abstract TypeBearer getCategory1(int idx);\n\n    /**\n     * Gets the type stored at the given local index, which is expected\n     * to be a category-2 value.\n     *\n     * @param idx {@code >= 0, < getMaxLocals();} which local\n     * @return {@code non-null;} the type of value stored in that local\n     * @throws SimException thrown if {@code idx} is valid, but\n     * one of the following holds: (a) the local is invalid; (b) the local\n     * contains a category-1 value\n     */\n    public abstract TypeBearer getCategory2(int idx);\n\n    /**\n     * Merges this instance with {@code other}. If the merged result is\n     * the same as this instance, then this is returned (not a copy).\n     *\n     * @param other {@code non-null;} another LocalsArray\n     * @return {@code non-null;} the merge result, a new instance or this\n     */\n    public abstract LocalsArray merge(LocalsArray other);\n\n    /**\n     * Merges this instance with a {@code LocalsSet} from a subroutine\n     * caller. To be used when merging in the first block of a subroutine.\n     *\n     * @param other {@code other non-null;} another LocalsArray. The final locals\n     * state of a subroutine caller.\n     * @param predLabel the label of the subroutine caller block.\n     * @return {@code non-null;} the merge result, a new instance or this\n     */\n    public abstract LocalsArraySet mergeWithSubroutineCaller\n            (LocalsArray other, int predLabel);\n\n    /**\n     * Gets the locals set appropriate for the current execution context.\n     * That is, if this is a {@code OneLocalsArray} instance, then return\n     * {@code this}, otherwise return {@code LocalsArraySet}'s\n     * primary.\n     *\n     * @return locals for this execution context.\n     */\n    protected abstract OneLocalsArray getPrimary();\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/LocalsArraySet.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.ArrayList;\n\n/**\n * Representation of a set of local variable arrays, with Java semantics.\n * This peculiar case is to support in-method subroutines, which can\n * have different locals sets for each caller.\n *\n * <p><b>Note:</b> For the most part, the documentation for this class\n * ignores the distinction between {@link com.taobao.android.dx.rop.type.Type} and {@link\n * com.taobao.android.dx.rop.type.TypeBearer}.</p>\n */\npublic class LocalsArraySet extends LocalsArray {\n\n    /**\n     * The primary LocalsArray represents the locals as seen from\n     * the subroutine itself, which is the merged representation of all the\n     * individual locals states.\n     */\n    private final OneLocalsArray primary;\n\n    /**\n     * Indexed by label of caller block: the locals specific to each caller's\n     * invocation of the subroutine.\n     */\n    private final ArrayList<LocalsArray> secondaries;\n\n    /**\n     * Constructs an instance. The locals array initially consists of\n     * all-uninitialized values (represented as {@code null}s).\n     *\n     * @param maxLocals {@code >= 0;} the maximum number of locals this instance\n     * can refer to\n     */\n    public LocalsArraySet(int maxLocals) {\n        super(maxLocals != 0);\n        primary = new OneLocalsArray(maxLocals);\n        secondaries = new ArrayList();\n    }\n\n    /**\n     * Constructs an instance with the specified primary and secondaries set.\n     *\n     * @param primary {@code non-null;} primary locals to use\n     * @param secondaries {@code non-null;} secondaries set, indexed by subroutine\n     * caller label.\n     */\n    public LocalsArraySet(OneLocalsArray primary,\n            ArrayList<LocalsArray> secondaries) {\n        super(primary.getMaxLocals() > 0);\n\n        this.primary = primary;\n        this.secondaries = secondaries;\n    }\n\n    /**\n     * Constructs an instance which is a copy of another.\n     *\n     * @param toCopy {@code non-null;} instance to copy.\n     */\n    private LocalsArraySet(LocalsArraySet toCopy) {\n        super(toCopy.getMaxLocals() > 0);\n\n        primary = toCopy.primary.copy();\n        secondaries = new ArrayList(toCopy.secondaries.size());\n\n        int sz = toCopy.secondaries.size();\n        for (int i = 0; i < sz; i++) {\n            LocalsArray la = toCopy.secondaries.get(i);\n\n            if (la == null) {\n                secondaries.add(null);\n            } else {\n                secondaries.add(la.copy());\n            }\n        }\n    }\n\n\n    /** @inheritDoc */\n    @Override\n    public void setImmutable() {\n        primary.setImmutable();\n\n        for (LocalsArray la : secondaries) {\n            if (la != null) {\n                la.setImmutable();\n            }\n        }\n        super.setImmutable();\n    }\n\n    /** @inheritDoc */\n    @Override\n    public LocalsArray copy() {\n        return new LocalsArraySet(this);\n    }\n\n    /** @inheritDoc */\n    @Override\n    public void annotate(ExceptionWithContext ex) {\n        ex.addContext(\"(locals array set; primary)\");\n        primary.annotate(ex);\n\n        int sz = secondaries.size();\n        for (int label = 0; label < sz; label++) {\n            LocalsArray la = secondaries.get(label);\n\n            if (la != null) {\n                ex.addContext(\"(locals array set: primary for caller \"\n                        + Hex.u2(label) + ')');\n\n                la.getPrimary().annotate(ex);\n            }\n        }\n    }\n\n    /** {@inheritDoc*/\n    public String toHuman() {\n        StringBuilder sb = new StringBuilder();\n\n        sb.append(\"(locals array set; primary)\\n\");\n\n        sb.append(getPrimary().toHuman());\n        sb.append('\\n');\n\n        int sz = secondaries.size();\n        for (int label = 0; label < sz; label++) {\n            LocalsArray la = secondaries.get(label);\n\n            if (la != null) {\n                sb.append(\"(locals array set: primary for caller \"\n                        + Hex.u2(label) + \")\\n\");\n\n                sb.append(la.getPrimary().toHuman());\n                sb.append('\\n');\n            }\n        }\n\n        return sb.toString();\n    }\n\n    /** @inheritDoc */\n    @Override\n    public void makeInitialized(Type type) {\n        int len = primary.getMaxLocals();\n\n        if (len == 0) {\n            // We have to check for this before checking for immutability.\n            return;\n        }\n\n        throwIfImmutable();\n\n        primary.makeInitialized(type);\n\n        for (LocalsArray la : secondaries) {\n            if (la != null) {\n                la.makeInitialized(type);\n            }\n        }\n    }\n\n    /** @inheritDoc */\n    @Override\n    public int getMaxLocals() {\n        return primary.getMaxLocals();\n    }\n\n    /** @inheritDoc */\n    @Override\n    public void set(int idx, TypeBearer type) {\n        throwIfImmutable();\n\n        primary.set(idx, type);\n\n        for (LocalsArray la : secondaries) {\n            if (la != null) {\n                la.set(idx, type);\n            }\n        }\n    }\n\n    /** @inheritDoc */\n    @Override\n    public void set(RegisterSpec spec) {\n        set(spec.getReg(), spec);\n    }\n\n    /** @inheritDoc */\n    @Override\n    public void invalidate(int idx) {\n        throwIfImmutable();\n\n        primary.invalidate(idx);\n\n        for (LocalsArray la : secondaries) {\n            if (la != null) {\n                la.invalidate(idx);\n            }\n        }\n    }\n\n    /** @inheritDoc */\n    @Override\n    public TypeBearer getOrNull(int idx) {\n        return primary.getOrNull(idx);\n    }\n\n    /** @inheritDoc */\n    @Override\n    public TypeBearer get(int idx) {\n        return primary.get(idx);\n    }\n\n    /** @inheritDoc */\n    @Override\n    public TypeBearer getCategory1(int idx) {\n        return primary.getCategory1(idx);\n    }\n\n    /** @inheritDoc */\n    @Override\n    public TypeBearer getCategory2(int idx) {\n        return primary.getCategory2(idx);\n    }\n\n    /**\n     * Merges this set with another {@code LocalsArraySet} instance.\n     *\n     * @param other {@code non-null;} to merge\n     * @return {@code non-null;} this instance if merge was a no-op, or\n     * new merged instance.\n     */\n    private LocalsArraySet mergeWithSet(LocalsArraySet other) {\n        OneLocalsArray newPrimary;\n        ArrayList<LocalsArray> newSecondaries;\n        boolean secondariesChanged = false;\n\n        newPrimary = primary.merge(other.getPrimary());\n\n        int sz1 = secondaries.size();\n        int sz2 = other.secondaries.size();\n        int sz = Math.max(sz1, sz2);\n        newSecondaries = new ArrayList(sz);\n\n        for (int i = 0; i < sz; i++) {\n            LocalsArray la1 = (i < sz1 ? secondaries.get(i) : null);\n            LocalsArray la2 = (i < sz2 ? other.secondaries.get(i) : null);\n            LocalsArray resultla = null;\n\n            if (la1 == la2) {\n                resultla = la1;\n            } else if (la1 == null) {\n                resultla = la2;\n            } else if (la2 == null) {\n                resultla = la1;\n            } else {\n                try {\n                    resultla = la1.merge(la2);\n                } catch (SimException ex) {\n                    ex.addContext(\n                            \"Merging locals set for caller block \" + Hex.u2(i));\n                }\n            }\n\n            secondariesChanged = secondariesChanged || (la1 != resultla);\n\n            newSecondaries.add(resultla);\n        }\n\n        if ((primary == newPrimary) && ! secondariesChanged ) {\n            return this;\n        }\n\n        return new LocalsArraySet(newPrimary, newSecondaries);\n    }\n\n    /**\n     * Merges this set with a {@code OneLocalsArray} instance.\n     *\n     * @param other {@code non-null;} to merge\n     * @return {@code non-null;} this instance if merge was a no-op, or\n     * new merged instance.\n     */\n    private LocalsArraySet mergeWithOne(OneLocalsArray other) {\n        OneLocalsArray newPrimary;\n        ArrayList<LocalsArray> newSecondaries;\n        boolean secondariesChanged = false;\n\n        newPrimary = primary.merge(other.getPrimary());\n        newSecondaries = new ArrayList(secondaries.size());\n\n        int sz = secondaries.size();\n        for (int i = 0; i < sz; i++) {\n            LocalsArray la = secondaries.get(i);\n            LocalsArray resultla = null;\n\n            if (la != null) {\n                try {\n                    resultla = la.merge(other);\n                } catch (SimException ex) {\n                    ex.addContext(\"Merging one locals against caller block \"\n                                    + Hex.u2(i));\n                }\n            }\n\n            secondariesChanged = secondariesChanged || (la != resultla);\n\n            newSecondaries.add(resultla);\n        }\n\n        if ((primary == newPrimary) && ! secondariesChanged ) {\n            return this;\n        }\n\n        return new LocalsArraySet(newPrimary, newSecondaries);\n    }\n\n    /** @inheritDoc */\n    @Override\n    public LocalsArraySet merge(LocalsArray other) {\n        LocalsArraySet result;\n\n        try {\n            if (other instanceof LocalsArraySet) {\n                result = mergeWithSet((LocalsArraySet) other);\n            } else {\n                result = mergeWithOne((OneLocalsArray) other);\n            }\n        } catch (SimException ex) {\n            ex.addContext(\"underlay locals:\");\n            annotate(ex);\n            ex.addContext(\"overlay locals:\");\n            other.annotate(ex);\n            throw ex;\n        }\n\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Gets the {@code LocalsArray} instance for a specified subroutine\n     * caller label, or null if label has no locals associated with it.\n     *\n     * @param label {@code >= 0;} subroutine caller label\n     * @return {@code null-ok;} locals if available.\n     */\n    private LocalsArray getSecondaryForLabel(int label) {\n        if (label >= secondaries.size()) {\n            return null;\n        }\n\n        return secondaries.get(label);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public LocalsArraySet mergeWithSubroutineCaller\n            (LocalsArray other, int predLabel) {\n\n        LocalsArray mine = getSecondaryForLabel(predLabel);\n        LocalsArray newSecondary;\n        OneLocalsArray newPrimary;\n\n        newPrimary = primary.merge(other.getPrimary());\n\n        if (mine == other) {\n            newSecondary = mine;\n        } else if (mine == null) {\n            newSecondary = other;\n        } else {\n            newSecondary = mine.merge(other);\n        }\n\n        if ((newSecondary == mine) && (newPrimary == primary)) {\n            return this;\n        } else {\n            /*\n             * We're going to re-build a primary as a merge of all the\n             * secondaries.\n             */\n            newPrimary = null;\n\n            int szSecondaries = secondaries.size();\n            int sz = Math.max(predLabel + 1, szSecondaries);\n            ArrayList<LocalsArray> newSecondaries = new ArrayList(sz);\n            for (int i = 0; i < sz; i++) {\n                LocalsArray la = null;\n\n                if (i == predLabel) {\n                    /*\n                     * This LocalsArray always replaces any existing one,\n                     * since this is the result of a refined iteration.\n                     */\n                    la = newSecondary;\n                } else if (i < szSecondaries) {\n                    la = secondaries.get(i);\n                }\n\n                if (la != null) {\n                    if (newPrimary == null) {\n                        newPrimary = la.getPrimary();\n                    } else {\n                        newPrimary = newPrimary.merge(la.getPrimary());\n                    }\n                }\n\n                newSecondaries.add(la);\n            }\n\n            LocalsArraySet result\n                    = new LocalsArraySet(newPrimary, newSecondaries);\n            result.setImmutable();\n            return result;\n        }\n    }\n\n    /**\n     * Returns a LocalsArray instance representing the locals state that should\n     * be used when returning to a subroutine caller.\n     *\n     * @param subLabel {@code >= 0;} A calling label of a subroutine\n     * @return {@code null-ok;} an instance for this subroutine, or null if subroutine\n     * is not in this set.\n     */\n    public LocalsArray subArrayForLabel(int subLabel) {\n        LocalsArray result = getSecondaryForLabel(subLabel);\n        return result;\n    }\n\n    /**{@inheritDoc}*/\n    @Override\n    protected OneLocalsArray getPrimary() {\n        return primary;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/Machine.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.rop.code.LocalItem;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.type.Prototype;\nimport com.taobao.android.dx.rop.type.Type;\nimport java.util.ArrayList;\n\n/**\n * Interface for machines capable of executing bytecode by acting\n * upon a {@link Frame}. A machine conceptually contains four arbitrary-value\n * argument slots, slots for several literal-value arguments, and slots for\n * branch target information.\n */\npublic interface Machine {\n    /**\n     * Gets the effective prototype of the method that this instance is\n     * being used for. The <i>effective</i> prototype includes an initial\n     * {@code this} argument for instance methods.\n     *\n     * @return {@code non-null;} the method prototype\n     */\n    public Prototype getPrototype();\n\n    /**\n     * Clears the regular and auxiliary arguments area.\n     */\n    public void clearArgs();\n\n    /**\n     * Pops the given number of values from the stack (of either category),\n     * and store them in the arguments area, indicating that there are now\n     * that many arguments. Also, clear the auxiliary arguments.\n     *\n     * @param frame {@code non-null;} frame to operate on\n     * @param count {@code >= 0;} number of values to pop\n     */\n    public void popArgs(Frame frame, int count);\n\n    /**\n     * Pops values from the stack of the types indicated by the given\n     * {@code Prototype} (popped in reverse of the argument\n     * order, so the first prototype argument type is for the deepest\n     * element of the stack), and store them in the arguments area,\n     * indicating that there are now that many arguments. Also, clear\n     * the auxiliary arguments.\n     *\n     * @param frame {@code non-null;} frame to operate on\n     * @param prototype {@code non-null;} prototype indicating arguments to pop\n     */\n    public void popArgs(Frame frame, Prototype prototype);\n\n    /**\n     * Pops a value from the stack of the indicated type, and store it\n     * in the arguments area, indicating that there are now that many\n     * arguments. Also, clear the auxiliary arguments.\n     *\n     * @param frame {@code non-null;} frame to operate on\n     * @param type {@code non-null;} type of the argument\n     */\n    public void popArgs(Frame frame, Type type);\n\n    /**\n     * Pops values from the stack of the indicated types (popped in\n     * reverse argument order, so the first indicated type is for the\n     * deepest element of the stack), and store them in the arguments\n     * area, indicating that there are now that many arguments. Also,\n     * clear the auxiliary arguments.\n     *\n     * @param frame {@code non-null;} frame to operate on\n     * @param type1 {@code non-null;} type of the first argument\n     * @param type2 {@code non-null;} type of the second argument\n     */\n    public void popArgs(Frame frame, Type type1, Type type2);\n\n    /**\n     * Pops values from the stack of the indicated types (popped in\n     * reverse argument order, so the first indicated type is for the\n     * deepest element of the stack), and store them in the arguments\n     * area, indicating that there are now that many arguments. Also,\n     * clear the auxiliary arguments.\n     *\n     * @param frame {@code non-null;} frame to operate on\n     * @param type1 {@code non-null;} type of the first argument\n     * @param type2 {@code non-null;} type of the second argument\n     * @param type3 {@code non-null;} type of the third argument\n     */\n    public void popArgs(Frame frame, Type type1, Type type2, Type type3);\n\n    /**\n     * Loads the local variable with the given index as the sole argument in\n     * the arguments area. Also, clear the auxiliary arguments.\n     *\n     * @param frame {@code non-null;} frame to operate on\n     * @param idx {@code >= 0;} the local variable index\n     */\n    public void localArg(Frame frame, int idx);\n\n    /**\n     * Used to specify if a loaded local variable has info in the local\n     * variable table.\n     *\n     * @param local {@code true} if local arg has info in local variable table\n     */\n    public void localInfo(boolean local);\n\n    /**\n     * Indicates that the salient type of this operation is as\n     * given. This differentiates between, for example, the various\n     * arithmetic opcodes, which, by the time they hit a\n     * {@code Machine} are collapsed to the {@code int}\n     * variant. (See {@link BytecodeArray#parseInstruction} for\n     * details.)\n     *\n     * @param type {@code non-null;} the salient type of the upcoming operation\n     */\n    public void auxType(Type type);\n\n    /**\n     * Indicates that there is an auxiliary (inline, not stack)\n     * argument of type {@code int}, with the given value.\n     *\n     * <p><b>Note:</b> Perhaps unintuitively, the stack manipulation\n     * ops (e.g., {@code dup} and {@code swap}) use this to\n     * indicate the result stack pattern with a straightforward hex\n     * encoding of the push order starting with least-significant\n     * nibbles getting pushed first). For example, an all-category-1\n     * {@code dup2_x1} sets this to {@code 0x12312}, and the\n     * other form of that op sets this to\n     * {@code 0x121}.</p>\n     *\n     * <p><b>Also Note:</b> For {@code switch*} instructions, this is\n     * used to indicate the padding value (which is only useful for\n     * verification).</p>\n     *\n     * @param value the argument value\n     */\n    public void auxIntArg(int value);\n\n    /**\n     * Indicates that there is an auxiliary (inline, not stack) object\n     * argument, with the value based on the given constant.\n     *\n     * <p><b>Note:</b> Some opcodes use both {@code int} and\n     * constant auxiliary arguments.</p>\n     *\n     * @param cst {@code non-null;} the constant containing / referencing\n     * the value\n     */\n    public void auxCstArg(Constant cst);\n\n    /**\n     * Indicates that there is an auxiliary (inline, not stack) argument\n     * indicating a branch target.\n     *\n     * @param target the argument value\n     */\n    public void auxTargetArg(int target);\n\n    /**\n     * Indicates that there is an auxiliary (inline, not stack) argument\n     * consisting of a {@code switch*} table.\n     *\n     * <p><b>Note:</b> This is generally used in conjunction with\n     * {@link #auxIntArg} (which holds the padding).</p>\n     *\n     * @param cases {@code non-null;} the list of key-target pairs, plus the default\n     * target\n     */\n    public void auxSwitchArg(SwitchList cases);\n\n    /**\n     * Indicates that there is an auxiliary (inline, not stack) argument\n     * consisting of a list of initial values for a newly created array.\n     *\n     * @param initValues {@code non-null;} the list of constant values to initialize\n     * the array\n     */\n    public void auxInitValues(ArrayList<Constant> initValues);\n\n    /**\n     * Indicates that the target of this operation is the given local.\n     *\n     * @param idx {@code >= 0;} the local variable index\n     * @param type {@code non-null;} the type of the local\n     * @param local {@code null-ok;} the name and signature of the local, if known\n     */\n    public void localTarget(int idx, Type type, LocalItem local);\n\n    /**\n     * \"Runs\" the indicated opcode in an appropriate way, using the arguments\n     * area as appropriate, and modifying the given frame in response.\n     *\n     * @param frame {@code non-null;} frame to operate on\n     * @param offset {@code >= 0;} byte offset in the method to the opcode being\n     * run\n     * @param opcode {@code >= 0;} the opcode to run\n     */\n    public void run(Frame frame, int offset, int opcode);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/Merger.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Utility methods to merge various frame information.\n */\npublic final class Merger {\n    /**\n     * This class is uninstantiable.\n     */\n    private Merger() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Merges two locals arrays. If the merged result is the same as the first\n     * argument, then return the first argument (not a copy).\n     *\n     * @param locals1 {@code non-null;} a locals array\n     * @param locals2 {@code non-null;} another locals array\n     * @return {@code non-null;} the result of merging the two locals arrays\n     */\n    public static OneLocalsArray mergeLocals(OneLocalsArray locals1,\n                                          OneLocalsArray locals2) {\n        if (locals1 == locals2) {\n            // Easy out.\n            return locals1;\n        }\n\n        int sz = locals1.getMaxLocals();\n        OneLocalsArray result = null;\n\n        if (locals2.getMaxLocals() != sz) {\n            throw new SimException(\"mismatched maxLocals values\");\n        }\n\n        for (int i = 0; i < sz; i++) {\n            TypeBearer tb1 = locals1.getOrNull(i);\n            TypeBearer tb2 = locals2.getOrNull(i);\n            TypeBearer resultType = mergeType(tb1, tb2);\n            if (resultType != tb1) {\n                /*\n                 * We only need to do anything when the result differs\n                 * from what is in the first array, since that's what the\n                 * result gets initialized to.\n                 */\n                if (result == null) {\n                    result = locals1.copy();\n                }\n\n                if (resultType == null) {\n                    result.invalidate(i);\n                } else {\n                    result.set(i, resultType);\n                }\n            }\n        }\n\n        if (result == null) {\n            return locals1;\n        }\n\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Merges two stacks. If the merged result is the same as the first\n     * argument, then return the first argument (not a copy).\n     *\n     * @param stack1 {@code non-null;} a stack\n     * @param stack2 {@code non-null;} another stack\n     * @return {@code non-null;} the result of merging the two stacks\n     */\n    public static ExecutionStack mergeStack(ExecutionStack stack1,\n                                            ExecutionStack stack2) {\n        if (stack1 == stack2) {\n            // Easy out.\n            return stack1;\n        }\n\n        int sz = stack1.size();\n        ExecutionStack result = null;\n\n        if (stack2.size() != sz) {\n            throw new SimException(\"mismatched stack depths\");\n        }\n\n        for (int i = 0; i < sz; i++) {\n            TypeBearer tb1 = stack1.peek(i);\n            TypeBearer tb2 = stack2.peek(i);\n            TypeBearer resultType = mergeType(tb1, tb2);\n            if (resultType != tb1) {\n                /*\n                 * We only need to do anything when the result differs\n                 * from what is in the first stack, since that's what the\n                 * result gets initialized to.\n                 */\n                if (result == null) {\n                    result = stack1.copy();\n                }\n\n                try {\n                    if (resultType == null) {\n                        throw new SimException(\"incompatible: \" + tb1 + \", \" +\n                                               tb2);\n                    } else {\n                        result.change(i, resultType);\n                    }\n                } catch (SimException ex) {\n                    ex.addContext(\"...while merging stack[\" + Hex.u2(i) + \"]\");\n                    throw ex;\n                }\n            }\n        }\n\n        if (result == null) {\n            return stack1;\n        }\n\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Merges two frame types.\n     *\n     * @param ft1 {@code non-null;} a frame type\n     * @param ft2 {@code non-null;} another frame type\n     * @return {@code non-null;} the result of merging the two types\n     */\n    public static TypeBearer mergeType(TypeBearer ft1, TypeBearer ft2) {\n        if ((ft1 == null) || ft1.equals(ft2)) {\n            return ft1;\n        } else if (ft2 == null) {\n            return null;\n        } else {\n            Type type1 = ft1.getType();\n            Type type2 = ft2.getType();\n\n            if (type1 == type2) {\n                return type1;\n            } else if (type1.isReference() && type2.isReference()) {\n                if (type1 == Type.KNOWN_NULL) {\n                    /*\n                     * A known-null merges with any other reference type to\n                     * be that reference type.\n                     */\n                    return type2;\n                } else if (type2 == Type.KNOWN_NULL) {\n                    /*\n                     * The same as above, but this time it's type2 that's\n                     * the known-null.\n                     */\n                    return type1;\n                } else if (type1.isArray() && type2.isArray()) {\n                    TypeBearer componentUnion =\n                        mergeType(type1.getComponentType(),\n                                type2.getComponentType());\n                    if (componentUnion == null) {\n                        /*\n                         * At least one of the types is a primitive type,\n                         * so the merged result is just Object.\n                         */\n                        return Type.OBJECT;\n                    }\n                    return ((Type) componentUnion).getArrayType();\n                } else {\n                    /*\n                     * All other unequal reference types get merged to be\n                     * Object in this phase. This is fine here, but it\n                     * won't be the right thing to do in the verifier.\n                     */\n                    return Type.OBJECT;\n                }\n            } else if (type1.isIntlike() && type2.isIntlike()) {\n                /*\n                 * Merging two non-identical int-like types results in\n                 * the type int.\n                 */\n                return Type.INT;\n            } else {\n                return null;\n            }\n        }\n    }\n\n    /**\n     * Returns whether the given supertype is possibly assignable from\n     * the given subtype. This takes into account primitiveness,\n     * int-likeness, known-nullness, and array dimensions, but does\n     * not assume anything about class hierarchy other than that the\n     * type {@code Object} is the supertype of all reference\n     * types and all arrays are assignable to\n     * {@code Serializable} and {@code Cloneable}.\n     *\n     * @param supertypeBearer {@code non-null;} the supertype\n     * @param subtypeBearer {@code non-null;} the subtype\n     */\n    public static boolean isPossiblyAssignableFrom(TypeBearer supertypeBearer,\n            TypeBearer subtypeBearer) {\n        Type supertype = supertypeBearer.getType();\n        Type subtype = subtypeBearer.getType();\n\n        if (supertype.equals(subtype)) {\n            // Easy out.\n            return true;\n        }\n\n        int superBt = supertype.getBasicType();\n        int subBt = subtype.getBasicType();\n\n        // Treat return types as Object for the purposes of this method.\n\n        if (superBt == Type.BT_ADDR) {\n            supertype = Type.OBJECT;\n            superBt = Type.BT_OBJECT;\n        }\n\n        if (subBt == Type.BT_ADDR) {\n            subtype = Type.OBJECT;\n            subBt = Type.BT_OBJECT;\n        }\n\n        if ((superBt != Type.BT_OBJECT) || (subBt != Type.BT_OBJECT)) {\n            /*\n             * No two distinct primitive types are assignable in this sense,\n             * unless they are both int-like.\n             */\n            return supertype.isIntlike() && subtype.isIntlike();\n        }\n\n        // At this point, we know both types are reference types.\n\n        if (supertype == Type.KNOWN_NULL) {\n            /*\n             * A known-null supertype is only assignable from another\n             * known-null (handled in the easy out at the top of the\n             * method).\n             */\n            return false;\n        } else if (subtype == Type.KNOWN_NULL) {\n            /*\n             * A known-null subtype is in fact assignable to any\n             * reference type.\n             */\n            return true;\n        } else if (supertype == Type.OBJECT) {\n            /*\n             * Object is assignable from any reference type.\n             */\n            return true;\n        } else if (supertype.isArray()) {\n            // The supertype is an array type.\n            if (! subtype.isArray()) {\n                // The subtype isn't an array, and so can't be assignable.\n                return false;\n            }\n\n            /*\n             * Strip off as many matched component types from both\n             * types as possible, and check the assignability of the\n             * results.\n             */\n            do {\n                supertype = supertype.getComponentType();\n                subtype = subtype.getComponentType();\n            } while (supertype.isArray() && subtype.isArray());\n\n            return isPossiblyAssignableFrom(supertype, subtype);\n        } else if (subtype.isArray()) {\n            /*\n             * Other than Object (handled above), array types are\n             * assignable only to Serializable and Cloneable.\n             */\n            return (supertype == Type.SERIALIZABLE) ||\n                (supertype == Type.CLONEABLE);\n        } else {\n            /*\n             * All other unequal reference types are considered at\n             * least possibly assignable.\n             */\n            return true;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/OneLocalsArray.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Representation of an array of local variables, with Java semantics.\n *\n * <p><b>Note:</b> For the most part, the documentation for this class\n * ignores the distinction between {@link com.taobao.android.dx.rop.type.Type} and {@link\n * com.taobao.android.dx.rop.type.TypeBearer}.</p>\n */\npublic class OneLocalsArray extends LocalsArray {\n    /** {@code non-null;} actual array */\n    private final TypeBearer[] locals;\n\n    /**\n     * Constructs an instance. The locals array initially consists of\n     * all-uninitialized values (represented as {@code null}s).\n     *\n     * @param maxLocals {@code >= 0;} the maximum number of locals this instance\n     * can refer to\n     */\n    public OneLocalsArray(int maxLocals) {\n        super(maxLocals != 0);\n        locals = new TypeBearer[maxLocals];\n    }\n\n    /** @inheritDoc */\n    public OneLocalsArray copy() {\n        OneLocalsArray result = new OneLocalsArray(locals.length);\n\n        System.arraycopy(locals, 0, result.locals, 0, locals.length);\n\n        return result;\n    }\n\n    /** @inheritDoc */\n    public void annotate(ExceptionWithContext ex) {\n        for (int i = 0; i < locals.length; i++) {\n            TypeBearer type = locals[i];\n            String s = (type == null) ? \"<invalid>\" : type.toString();\n            ex.addContext(\"locals[\" + Hex.u2(i) + \"]: \" + s);\n        }\n    }\n\n    /** {@inheritDoc*/\n    public String toHuman() {\n        StringBuilder sb = new StringBuilder();\n\n        for (int i = 0; i < locals.length; i++) {\n            TypeBearer type = locals[i];\n            String s = (type == null) ? \"<invalid>\" : type.toString();\n            sb.append(\"locals[\" + Hex.u2(i) + \"]: \" + s + \"\\n\");\n        }\n\n        return sb.toString();\n    }\n\n    /** @inheritDoc */\n    public void makeInitialized(Type type) {\n        int len = locals.length;\n\n        if (len == 0) {\n            // We have to check for this before checking for immutability.\n            return;\n        }\n\n        throwIfImmutable();\n\n        Type initializedType = type.getInitializedType();\n\n        for (int i = 0; i < len; i++) {\n            if (locals[i] == type) {\n                locals[i] = initializedType;\n            }\n        }\n    }\n\n    /** @inheritDoc */\n    public int getMaxLocals() {\n        return locals.length;\n    }\n\n    /** @inheritDoc */\n    public void set(int idx, TypeBearer type) {\n        throwIfImmutable();\n\n        try {\n            type = type.getFrameType();\n        } catch (NullPointerException ex) {\n            // Elucidate the exception\n            throw new NullPointerException(\"type == null\");\n        }\n\n        if (idx < 0) {\n            throw new IndexOutOfBoundsException(\"idx < 0\");\n        }\n\n        // Make highest possible out-of-bounds check happen first.\n        if (type.getType().isCategory2()) {\n            locals[idx + 1] = null;\n        }\n\n        locals[idx] = type;\n\n        if (idx != 0) {\n            TypeBearer prev = locals[idx - 1];\n            if ((prev != null) && prev.getType().isCategory2()) {\n                locals[idx - 1] = null;\n            }\n        }\n    }\n\n    /** @inheritDoc */\n    public void set(RegisterSpec spec) {\n        set(spec.getReg(), spec);\n    }\n\n    /** @inheritDoc */\n    public void invalidate(int idx) {\n        throwIfImmutable();\n        locals[idx] = null;\n    }\n\n    /** @inheritDoc */\n    public TypeBearer getOrNull(int idx) {\n        return locals[idx];\n    }\n\n    /** @inheritDoc */\n    public TypeBearer get(int idx) {\n        TypeBearer result = locals[idx];\n\n        if (result == null) {\n            return throwSimException(idx, \"invalid\");\n        }\n\n        return result;\n    }\n\n    /** @inheritDoc */\n    public TypeBearer getCategory1(int idx) {\n        TypeBearer result = get(idx);\n        Type type = result.getType();\n\n        if (type.isUninitialized()) {\n            return throwSimException(idx, \"uninitialized instance\");\n        }\n\n        if (type.isCategory2()) {\n            return throwSimException(idx, \"category-2\");\n        }\n\n        return result;\n    }\n\n    /** @inheritDoc */\n    public TypeBearer getCategory2(int idx) {\n        TypeBearer result = get(idx);\n\n        if (result.getType().isCategory1()) {\n            return throwSimException(idx, \"category-1\");\n        }\n\n        return result;\n    }\n\n    /** @inheritDoc */\n    @Override\n    public LocalsArray merge(LocalsArray other) {\n        if (other instanceof OneLocalsArray) {\n            return merge((OneLocalsArray)other);\n        } else { //LocalsArraySet\n            // LocalsArraySet knows how to merge me.\n            return other.merge(this);\n        }\n    }\n\n    /**\n     * Merges this OneLocalsArray instance with another OneLocalsArray\n     * instance. A more-refined version of {@link #merge(LocalsArray) merge}\n     * which is called by that method when appropriate.\n     *\n     * @param other locals array with which to merge\n     * @return this instance if merge was a no-op, or a new instance if\n     * the merge resulted in a change.\n     */\n    public OneLocalsArray merge(OneLocalsArray other) {\n        try {\n            return Merger.mergeLocals(this, other);\n        } catch (SimException ex) {\n            ex.addContext(\"underlay locals:\");\n            annotate(ex);\n            ex.addContext(\"overlay locals:\");\n            other.annotate(ex);\n            throw ex;\n        }\n    }\n\n    /** @inheritDoc */\n    @Override\n    public LocalsArraySet mergeWithSubroutineCaller\n            (LocalsArray other, int predLabel) {\n\n        LocalsArraySet result = new LocalsArraySet(getMaxLocals());\n        return result.mergeWithSubroutineCaller(other, predLabel);\n    }\n\n    /**{@inheritDoc}*/\n    @Override\n    protected OneLocalsArray getPrimary() {\n        return this;\n    }\n\n    /**\n     * Throws a properly-formatted exception.\n     *\n     * @param idx the salient local index\n     * @param msg {@code non-null;} useful message\n     * @return never (keeps compiler happy)\n     */\n    private static TypeBearer throwSimException(int idx, String msg) {\n        throw new SimException(\"local \" + Hex.u2(idx) + \": \" + msg);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/ReturnAddress.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Representation of a subroutine return address. In Java verification,\n * somewhat counterintuitively, the salient bit of information you need to\n * know about a return address is the <i>start address</i> of the subroutine\n * being returned from, not the address being returned <i>to</i>, so that's\n * what instances of this class hang onto.\n */\npublic final class ReturnAddress implements TypeBearer {\n    /** {@code >= 0;} the start address of the subroutine being returned from */\n    private final int subroutineAddress;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param subroutineAddress {@code >= 0;} the start address of the\n     * subroutine being returned from\n     */\n    public ReturnAddress(int subroutineAddress) {\n        if (subroutineAddress < 0) {\n            throw new IllegalArgumentException(\"subroutineAddress < 0\");\n        }\n\n        this.subroutineAddress = subroutineAddress;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return (\"<addr:\" + Hex.u2(subroutineAddress) + \">\");\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return toString();\n    }\n\n    /** {@inheritDoc} */\n    public Type getType() {\n        return Type.RETURN_ADDRESS;\n    }\n\n    /** {@inheritDoc} */\n    public TypeBearer getFrameType() {\n        return this;\n    }\n\n    /** {@inheritDoc} */\n    public int getBasicType() {\n        return Type.RETURN_ADDRESS.getBasicType();\n    }\n\n    /** {@inheritDoc} */\n    public int getBasicFrameType() {\n        return Type.RETURN_ADDRESS.getBasicFrameType();\n    }\n\n    /** {@inheritDoc} */\n    public boolean isConstant() {\n        return false;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (!(other instanceof ReturnAddress)) {\n            return false;\n        }\n\n        return subroutineAddress == ((ReturnAddress) other).subroutineAddress;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return subroutineAddress;\n    }\n\n    /**\n     * Gets the subroutine address.\n     *\n     * @return {@code >= 0;} the subroutine address\n     */\n    public int getSubroutineAddress() {\n        return subroutineAddress;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/Ropper.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.cf.iface.MethodList;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.code.BasicBlock;\nimport com.taobao.android.dx.rop.code.BasicBlockList;\nimport com.taobao.android.dx.rop.code.Insn;\nimport com.taobao.android.dx.rop.code.InsnList;\nimport com.taobao.android.dx.rop.code.PlainCstInsn;\nimport com.taobao.android.dx.rop.code.PlainInsn;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rop;\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.rop.code.Rops;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.rop.code.ThrowingCstInsn;\nimport com.taobao.android.dx.rop.code.ThrowingInsn;\nimport com.taobao.android.dx.rop.code.TranslationAdvice;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Prototype;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.Bits;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.IntList;\n\nimport java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Utility that converts a basic block list into a list of register-oriented\n * blocks.\n */\npublic final class Ropper {\n    /** label offset for the parameter assignment block */\n    private static final int PARAM_ASSIGNMENT = -1;\n\n    /** label offset for the return block */\n    private static final int RETURN = -2;\n\n    /** label offset for the synchronized method final return block */\n    private static final int SYNCH_RETURN = -3;\n\n    /** label offset for the first synchronized method setup block */\n    private static final int SYNCH_SETUP_1 = -4;\n\n    /** label offset for the second synchronized method setup block */\n    private static final int SYNCH_SETUP_2 = -5;\n\n    /**\n     * label offset for the first synchronized method exception\n     * handler block\n     */\n    private static final int SYNCH_CATCH_1 = -6;\n\n    /**\n     * label offset for the second synchronized method exception\n     * handler block\n     */\n    private static final int SYNCH_CATCH_2 = -7;\n\n    /** number of special label offsets */\n    private static final int SPECIAL_LABEL_COUNT = 7;\n\n    /** {@code non-null;} method being converted */\n    private final ConcreteMethod method;\n\n    /** {@code non-null;} original block list */\n    private final ByteBlockList blocks;\n\n    /** max locals of the method */\n    private final int maxLocals;\n\n    /** max label (exclusive) of any original bytecode block */\n    private final int maxLabel;\n\n    /** {@code non-null;} simulation machine to use */\n    private final RopperMachine machine;\n\n    /** {@code non-null;} simulator to use */\n    private final Simulator sim;\n\n    /**\n     * {@code non-null;} sparse array mapping block labels to initial frame\n     * contents, if known\n     */\n    private final Frame[] startFrames;\n\n    /** {@code non-null;} output block list in-progress */\n    private final ArrayList<BasicBlock> result;\n\n    /**\n     * {@code non-null;} list of subroutine-nest labels\n     * (See {@link Frame#getSubroutines} associated with each result block.\n     * Parallel to {@link Ropper#result}.\n     */\n    private final ArrayList<IntList> resultSubroutines;\n\n    /**\n     * {@code non-null;} for each block (by label) that is used as an exception\n     * handler in the input, the exception handling info in Rop.\n     */\n    private final CatchInfo[] catchInfos;\n\n    /**\n     * whether an exception-handler block for a synchronized method was\n     * ever required\n     */\n    private boolean synchNeedsExceptionHandler;\n\n    /**\n     * {@code non-null;} list of subroutines indexed by label of start\n     * address */\n    private final Subroutine[] subroutines;\n\n    /** true if {@code subroutines} is non-empty */\n    private boolean hasSubroutines;\n\n    /** Allocates labels of exception handler setup blocks. */\n    private final ExceptionSetupLabelAllocator exceptionSetupLabelAllocator;\n\n    /**\n     * Keeps mapping of an input exception handler target code and how it is generated/targeted in\n     * Rop.\n     */\n    private class CatchInfo {\n        /**\n         * {@code non-null;} map of ExceptionHandlerSetup by the type they handle */\n        private final Map<Type, ExceptionHandlerSetup> setups =\n                new HashMap<Type, ExceptionHandlerSetup>();\n\n        /**\n         * Get the {@link ExceptionHandlerSetup} corresponding to the given type. The\n         * ExceptionHandlerSetup is created if this the first request for the given type.\n         *\n         * @param caughtType {@code non-null;}  the type catch by the requested setup\n         * @return {@code non-null;} the handler setup block info for the given type\n         */\n        ExceptionHandlerSetup getSetup(Type caughtType) {\n            ExceptionHandlerSetup handler = setups.get(caughtType);\n            if (handler == null) {\n                int handlerSetupLabel = exceptionSetupLabelAllocator.getNextLabel();\n                handler = new ExceptionHandlerSetup(caughtType, handlerSetupLabel);\n                setups.put(caughtType, handler);\n            }\n            return handler;\n        }\n\n        /**\n         * Get all {@link ExceptionHandlerSetup} of this handler.\n         *\n         * @return {@code non-null;}\n         */\n       Collection<ExceptionHandlerSetup> getSetups() {\n            return setups.values();\n        }\n    }\n\n    /**\n     * Keeps track of an exception handler setup.\n     */\n    private static class ExceptionHandlerSetup {\n        /**\n         * {@code non-null;} The caught type. */\n        private Type caughtType;\n        /**\n         * {@code >= 0;} The label of the exception setup block. */\n        private int label;\n\n        /**\n         * Constructs instance.\n         *\n         * @param caughtType {@code non-null;} the caught type\n         * @param label {@code >= 0;} the label\n         */\n        ExceptionHandlerSetup(Type caughtType, int label) {\n            this.caughtType = caughtType;\n            this.label = label;\n        }\n\n        /**\n         * @return {@code non-null;} the caught type\n         */\n        Type getCaughtType() {\n            return caughtType;\n        }\n\n        /**\n         * @return {@code >= 0;} the label\n         */\n        public int getLabel() {\n            return label;\n        }\n    }\n\n    /**\n     * Keeps track of subroutines that exist in java form and are inlined in\n     * Rop form.\n     */\n    private class Subroutine {\n        /** list of all blocks that jsr to this subroutine */\n        private BitSet callerBlocks;\n        /** List of all blocks that return from this subroutine */\n        private BitSet retBlocks;\n        /** first block in this subroutine */\n        private int startBlock;\n\n        /**\n         * Constructs instance.\n         *\n         * @param startBlock First block of the subroutine.\n         */\n        Subroutine(int startBlock) {\n            this.startBlock = startBlock;\n            retBlocks = new BitSet(maxLabel);\n            callerBlocks = new BitSet(maxLabel);\n            hasSubroutines = true;\n        }\n\n        /**\n         * Constructs instance.\n         *\n         * @param startBlock First block of the subroutine.\n         * @param retBlock one of the ret blocks (final blocks) of this\n         * subroutine.\n         */\n        Subroutine(int startBlock, int retBlock) {\n            this(startBlock);\n            addRetBlock(retBlock);\n        }\n\n        /**\n         * @return {@code >= 0;} the label of the subroutine's start block.\n         */\n        int getStartBlock() {\n            return startBlock;\n        }\n\n        /**\n         * Adds a label to the list of ret blocks (final blocks) for this\n         * subroutine.\n         *\n         * @param retBlock ret block label\n         */\n        void addRetBlock(int retBlock) {\n            retBlocks.set(retBlock);\n        }\n\n        /**\n         * Adds a label to the list of caller blocks for this subroutine.\n         *\n         * @param label a block that invokes this subroutine.\n         */\n        void addCallerBlock(int label) {\n            callerBlocks.set(label);\n        }\n\n        /**\n         * Generates a list of subroutine successors. Note: successor blocks\n         * could be listed more than once. This is ok, because this successor\n         * list (and the block it's associated with) will be copied and inlined\n         * before we leave the ropper. Redundent successors will result in\n         * redundent (no-op) merges.\n         *\n         * @return all currently known successors\n         * (return destinations) for that subroutine\n         */\n        IntList getSuccessors() {\n            IntList successors = new IntList(callerBlocks.size());\n\n            /*\n             * For each subroutine caller, get it's target. If the\n             * target is us, add the ret target (subroutine successor)\n             * to our list\n             */\n\n            for (int label = callerBlocks.nextSetBit(0); label >= 0;\n                 label = callerBlocks.nextSetBit(label+1)) {\n                BasicBlock subCaller = labelToBlock(label);\n                successors.add(subCaller.getSuccessors().get(0));\n            }\n\n            successors.setImmutable();\n\n            return successors;\n        }\n\n        /**\n         * Merges the specified frame into this subroutine's successors,\n         * setting {@code workSet} as appropriate. To be called with\n         * the frame of a subroutine ret block.\n         *\n         * @param frame {@code non-null;} frame from ret block to merge\n         * @param workSet {@code non-null;} workset to update\n         */\n        void mergeToSuccessors(Frame frame, int[] workSet) {\n            for (int label = callerBlocks.nextSetBit(0); label >= 0;\n                 label = callerBlocks.nextSetBit(label+1)) {\n                BasicBlock subCaller = labelToBlock(label);\n                int succLabel = subCaller.getSuccessors().get(0);\n\n                Frame subFrame = frame.subFrameForLabel(startBlock, label);\n\n                if (subFrame != null) {\n                    mergeAndWorkAsNecessary(succLabel, -1, null,\n                            subFrame, workSet);\n                } else {\n                    Bits.set(workSet, label);\n                }\n            }\n        }\n    }\n\n    /**\n     * Converts a {@link ConcreteMethod} to a {@link RopMethod}.\n     *\n     * @param method {@code non-null;} method to convert\n     * @param advice {@code non-null;} translation advice to use\n     * @param methods {@code non-null;} list of methods defined by the class\n     *     that defines {@code method}.\n     * @return {@code non-null;} the converted instance\n     */\n    public static RopMethod convert(ConcreteMethod method,\n            TranslationAdvice advice, MethodList methods) {\n        try {\n            Ropper r = new Ropper(method, advice, methods);\n            r.doit();\n            return r.getRopMethod();\n        } catch (SimException ex) {\n            ex.addContext(\"...while working on method \" +\n                          method.getNat().toHuman());\n            throw ex;\n        }\n    }\n\n    /**\n     * Constructs an instance. This class is not publicly instantiable; use\n     * {@link #convert}.\n     *\n     * @param method {@code non-null;} method to convert\n     * @param advice {@code non-null;} translation advice to use\n     * @param methods {@code non-null;} list of methods defined by the class\n     *     that defines {@code method}.\n     */\n    private Ropper(ConcreteMethod method, TranslationAdvice advice, MethodList methods) {\n        if (method == null) {\n            throw new NullPointerException(\"method == null\");\n        }\n\n        if (advice == null) {\n            throw new NullPointerException(\"advice == null\");\n        }\n\n        this.method = method;\n        this.blocks = BasicBlocker.identifyBlocks(method);\n        this.maxLabel = blocks.getMaxLabel();\n        this.maxLocals = method.getMaxLocals();\n        this.machine = new RopperMachine(this, method, advice, methods);\n        this.sim = new Simulator(machine, method);\n        this.startFrames = new Frame[maxLabel];\n        this.subroutines = new Subroutine[maxLabel];\n\n        /*\n         * The \"* 2 + 10\" below is to conservatively believe that every\n         * block is an exception handler target and should also\n         * take care of enough other possible extra overhead such that\n         * the underlying array is unlikely to need resizing.\n         */\n        this.result = new ArrayList<BasicBlock>(blocks.size() * 2 + 10);\n        this.resultSubroutines =\n            new ArrayList<IntList>(blocks.size() * 2 + 10);\n\n        this.catchInfos = new CatchInfo[maxLabel];\n        this.synchNeedsExceptionHandler = false;\n\n        /*\n         * Set up the first stack frame with the right limits, but leave it\n         * empty here (to be filled in outside of the constructor).\n         */\n        startFrames[0] = new Frame(maxLocals, method.getMaxStack());\n        exceptionSetupLabelAllocator = new ExceptionSetupLabelAllocator();\n    }\n\n    /**\n     * Gets the first (lowest) register number to use as the temporary\n     * area when unwinding stack manipulation ops.\n     *\n     * @return {@code >= 0;} the first register to use\n     */\n    /*package*/ int getFirstTempStackReg() {\n        /*\n         * We use the register that is just past the deepest possible\n         * stack element, plus one if the method is synchronized to\n         * avoid overlapping with the synch register. We don't need to\n         * do anything else special at this level, since later passes\n         * will merely notice the highest register used by explicit\n         * inspection.\n         */\n        int regCount = getNormalRegCount();\n        return isSynchronized() ? regCount + 1 : regCount;\n    }\n\n    /**\n     * Gets the label for the given special-purpose block. The given label\n     * should be one of the static constants defined by this class.\n     *\n     * @param label {@code < 0;} the special label constant\n     * @return {@code >= 0;} the actual label value to use\n     */\n    private int getSpecialLabel(int label) {\n        /*\n         * The label is bitwise-complemented so that mistakes where\n         * LABEL is used instead of getSpecialLabel(LABEL) cause a\n         * failure at block construction time, since negative labels\n         * are illegal. 0..maxLabel (exclusive) are the original blocks and\n         * maxLabel..(maxLabel + method.getCatches().size()) are reserved for exception handler\n         * setup blocks (see getAvailableLabel(), exceptionSetupLabelAllocator).\n         */\n        return maxLabel + method.getCatches().size() + ~label;\n    }\n\n    /**\n     * Gets the minimum label for unreserved use.\n     *\n     * @return {@code >= 0;} the minimum label\n     */\n    private int getMinimumUnreservedLabel() {\n        /*\n         * The labels below (maxLabel + method.getCatches().size() + SPECIAL_LABEL_COUNT) are\n         * reserved for particular uses.\n         */\n\n        return maxLabel + method.getCatches().size() + SPECIAL_LABEL_COUNT;\n    }\n\n    /**\n     * Gets an unreserved and available label.\n     * Labels are distributed this way:\n     * <ul>\n     * <li>[0, maxLabel[ are the labels of the blocks directly\n     * corresponding to the input bytecode.</li>\n     * <li>[maxLabel, maxLabel + method.getCatches().size()[ are reserved for exception setup\n     * blocks.</li>\n     * <li>[maxLabel + method.getCatches().size(),\n     * maxLabel + method.getCatches().size() + SPECIAL_LABEL_COUNT[ are reserved for special blocks,\n     * ie param assignement, return and synch blocks.</li>\n     * <li>[maxLabel method.getCatches().size() + SPECIAL_LABEL_COUNT, getAvailableLabel()[ assigned\n     *  labels. Note that some\n     * of the assigned labels may not be used any more if they were assigned to a block that was\n     * deleted since.</li>\n     * </ul>\n     *\n     * @return {@code >= 0;} an available label with the guaranty that all greater labels are\n     * also available.\n     */\n    private int getAvailableLabel() {\n        int candidate = getMinimumUnreservedLabel();\n\n        for (BasicBlock bb : result) {\n            int label = bb.getLabel();\n            if (label >= candidate) {\n                candidate = label + 1;\n            }\n        }\n\n        return candidate;\n    }\n\n    /**\n     * Gets whether the method being translated is synchronized.\n     *\n     * @return whether the method being translated is synchronized\n     */\n    private boolean isSynchronized() {\n        int accessFlags = method.getAccessFlags();\n        return (accessFlags & AccessFlags.ACC_SYNCHRONIZED) != 0;\n    }\n\n    /**\n     * Gets whether the method being translated is static.\n     *\n     * @return whether the method being translated is static\n     */\n    private boolean isStatic() {\n        int accessFlags = method.getAccessFlags();\n        return (accessFlags & AccessFlags.ACC_STATIC) != 0;\n    }\n\n    /**\n     * Gets the total number of registers used for \"normal\" purposes (i.e.,\n     * for the straightforward translation from the original Java).\n     *\n     * @return {@code >= 0;} the total number of registers used\n     */\n    private int getNormalRegCount() {\n        return maxLocals + method.getMaxStack();\n    }\n\n    /**\n     * Gets the register spec to use to hold the object to synchronize on,\n     * for a synchronized method.\n     *\n     * @return {@code non-null;} the register spec\n     */\n    private RegisterSpec getSynchReg() {\n        /*\n         * We use the register that is just past the deepest possible\n         * stack element, with a minimum of v1 since v0 is what's\n         * always used to hold the caught exception when unwinding. We\n         * don't need to do anything else special at this level, since\n         * later passes will merely notice the highest register used\n         * by explicit inspection.\n         */\n        int reg = getNormalRegCount();\n        return RegisterSpec.make((reg < 1) ? 1 : reg, Type.OBJECT);\n    }\n\n    /**\n     * Searches {@link #result} for a block with the given label. Returns its\n     * index if found, or returns {@code -1} if there is no such block.\n     *\n     * @param label the label to look for\n     * @return {@code >= -1;} the index for the block with the given label or\n     * {@code -1} if there is no such block\n     */\n    private int labelToResultIndex(int label) {\n        int sz = result.size();\n        for (int i = 0; i < sz; i++) {\n            BasicBlock one = result.get(i);\n            if (one.getLabel() == label) {\n                return i;\n            }\n        }\n\n        return -1;\n    }\n\n    /**\n     * Searches {@link #result} for a block with the given label. Returns it if\n     * found, or throws an exception if there is no such block.\n     *\n     * @param label the label to look for\n     * @return {@code non-null;} the block with the given label\n     */\n    private BasicBlock labelToBlock(int label) {\n        int idx = labelToResultIndex(label);\n\n        if (idx < 0) {\n            throw new IllegalArgumentException(\"no such label \" +\n                    Hex.u2(label));\n        }\n\n        return result.get(idx);\n    }\n\n    /**\n     * Adds a block to the output result.\n     *\n     * @param block {@code non-null;} the block to add\n     * @param subroutines {@code non-null;} subroutine label list\n     * as described in {@link Frame#getSubroutines}\n     */\n    private void addBlock(BasicBlock block, IntList subroutines) {\n        if (block == null) {\n            throw new NullPointerException(\"block == null\");\n        }\n\n        result.add(block);\n        subroutines.throwIfMutable();\n        resultSubroutines.add(subroutines);\n    }\n\n    /**\n     * Adds or replace a block in the output result. If this is a\n     * replacement, then any extra blocks that got added with the\n     * original get removed as a result of calling this method.\n     *\n     * @param block {@code non-null;} the block to add or replace\n     * @param subroutines {@code non-null;} subroutine label list\n     * as described in {@link Frame#getSubroutines}\n     * @return {@code true} if the block was replaced or\n     * {@code false} if it was added for the first time\n     */\n    private boolean addOrReplaceBlock(BasicBlock block, IntList subroutines) {\n        if (block == null) {\n            throw new NullPointerException(\"block == null\");\n        }\n\n        int idx = labelToResultIndex(block.getLabel());\n        boolean ret;\n\n        if (idx < 0) {\n            ret = false;\n        } else {\n            /*\n             * We are replacing a pre-existing block, so find any\n             * blocks that got added as part of the original and\n             * remove those too. Such blocks are (possibly indirect)\n             * successors of this block which are out of the range of\n             * normally-translated blocks.\n             */\n            removeBlockAndSpecialSuccessors(idx);\n            ret = true;\n        }\n\n        result.add(block);\n        subroutines.throwIfMutable();\n        resultSubroutines.add(subroutines);\n        return ret;\n    }\n\n    /**\n     * Adds or replaces a block in the output result. Do not delete\n     * any successors.\n     *\n     * @param block {@code non-null;} the block to add or replace\n     * @param subroutines {@code non-null;} subroutine label list\n     * as described in {@link Frame#getSubroutines}\n     * @return {@code true} if the block was replaced or\n     * {@code false} if it was added for the first time\n     */\n    private boolean addOrReplaceBlockNoDelete(BasicBlock block,\n            IntList subroutines) {\n        if (block == null) {\n            throw new NullPointerException(\"block == null\");\n        }\n\n        int idx = labelToResultIndex(block.getLabel());\n        boolean ret;\n\n        if (idx < 0) {\n            ret = false;\n        } else {\n            result.remove(idx);\n            resultSubroutines.remove(idx);\n            ret = true;\n        }\n\n        result.add(block);\n        subroutines.throwIfMutable();\n        resultSubroutines.add(subroutines);\n        return ret;\n    }\n\n    /**\n     * Helper for {@link #addOrReplaceBlock} which recursively removes\n     * the given block and all blocks that are (direct and indirect)\n     * successors of it whose labels indicate that they are not in the\n     * normally-translated range.\n     *\n     * @param idx {@code non-null;} block to remove (etc.)\n     */\n    private void removeBlockAndSpecialSuccessors(int idx) {\n        int minLabel = getMinimumUnreservedLabel();\n        BasicBlock block = result.get(idx);\n        IntList successors = block.getSuccessors();\n        int sz = successors.size();\n\n        result.remove(idx);\n        resultSubroutines.remove(idx);\n\n        for (int i = 0; i < sz; i++) {\n            int label = successors.get(i);\n            if (label >= minLabel) {\n                idx = labelToResultIndex(label);\n                if (idx < 0) {\n                    throw new RuntimeException(\"Invalid label \"\n                            + Hex.u2(label));\n                }\n                removeBlockAndSpecialSuccessors(idx);\n            }\n        }\n    }\n\n    /**\n     * Extracts the resulting {@link RopMethod} from the instance.\n     *\n     * @return {@code non-null;} the method object\n     */\n    private RopMethod getRopMethod() {\n\n        // Construct the final list of blocks.\n\n        int sz = result.size();\n        BasicBlockList bbl = new BasicBlockList(sz);\n        for (int i = 0; i < sz; i++) {\n            bbl.set(i, result.get(i));\n        }\n        bbl.setImmutable();\n\n        // Construct the method object to wrap it all up.\n\n        /*\n         * Note: The parameter assignment block is always the first\n         * that should be executed, hence the second argument to the\n         * constructor.\n         */\n        return new RopMethod(bbl, getSpecialLabel(PARAM_ASSIGNMENT));\n    }\n\n    /**\n     * Does the conversion.\n     */\n    private void doit() {\n        int[] workSet = Bits.makeBitSet(maxLabel);\n\n        Bits.set(workSet, 0);\n        addSetupBlocks();\n        setFirstFrame();\n\n        for (;;) {\n            int offset = Bits.findFirst(workSet, 0);\n            if (offset < 0) {\n                break;\n            }\n            Bits.clear(workSet, offset);\n            ByteBlock block = blocks.labelToBlock(offset);\n            Frame frame = startFrames[offset];\n            try {\n                processBlock(block, frame, workSet);\n            } catch (SimException ex) {\n                ex.addContext(\"...while working on block \" + Hex.u2(offset));\n                throw ex;\n            }\n        }\n\n        addReturnBlock();\n        addSynchExceptionHandlerBlock();\n        addExceptionSetupBlocks();\n\n        if (hasSubroutines) {\n            // Subroutines are very rare, so skip this step if it's n/a\n            inlineSubroutines();\n        }\n    }\n\n    /**\n     * Sets up the first frame to contain all the incoming parameters in\n     * locals.\n     */\n    private void setFirstFrame() {\n        Prototype desc = method.getEffectiveDescriptor();\n        startFrames[0].initializeWithParameters(desc.getParameterTypes());\n        startFrames[0].setImmutable();\n    }\n\n    /**\n     * Processes the given block.\n     *\n     * @param block {@code non-null;} block to process\n     * @param frame {@code non-null;} start frame for the block\n     * @param workSet {@code non-null;} bits representing work to do,\n     * which this method may add to\n     */\n    private void processBlock(ByteBlock block, Frame frame, int[] workSet) {\n        // Prepare the list of caught exceptions for this block.\n        ByteCatchList catches = block.getCatches();\n        machine.startBlock(catches.toRopCatchList());\n\n        /*\n         * Using a copy of the given frame, simulate each instruction,\n         * calling into machine for each.\n         */\n        frame = frame.copy();\n        sim.simulate(block, frame);\n        frame.setImmutable();\n\n        int extraBlockCount = machine.getExtraBlockCount();\n        ArrayList<Insn> insns = machine.getInsns();\n        int insnSz = insns.size();\n\n        /*\n         * Merge the frame into each possible non-exceptional\n         * successor.\n         */\n\n        int catchSz = catches.size();\n        IntList successors = block.getSuccessors();\n\n        int startSuccessorIndex;\n\n        Subroutine calledSubroutine = null;\n        if (machine.hasJsr()) {\n            /*\n             * If this frame ends in a JSR, only merge our frame with\n             * the subroutine start, not the subroutine's return target.\n             */\n            startSuccessorIndex = 1;\n\n            int subroutineLabel = successors.get(1);\n\n            if (subroutines[subroutineLabel] == null) {\n                subroutines[subroutineLabel] =\n                    new Subroutine (subroutineLabel);\n            }\n\n            subroutines[subroutineLabel].addCallerBlock(block.getLabel());\n\n            calledSubroutine = subroutines[subroutineLabel];\n        } else if (machine.hasRet()) {\n            /*\n             * This block ends in a ret, which means it's the final block\n             * in some subroutine. Ultimately, this block will be copied\n             * and inlined for each call and then disposed of.\n             */\n\n            ReturnAddress ra = machine.getReturnAddress();\n            int subroutineLabel = ra.getSubroutineAddress();\n\n            if (subroutines[subroutineLabel] == null) {\n                subroutines[subroutineLabel]\n                        = new Subroutine (subroutineLabel, block.getLabel());\n            } else {\n                subroutines[subroutineLabel].addRetBlock(block.getLabel());\n            }\n\n            successors = subroutines[subroutineLabel].getSuccessors();\n            subroutines[subroutineLabel]\n                    .mergeToSuccessors(frame, workSet);\n            // Skip processing below since we just did it.\n            startSuccessorIndex = successors.size();\n        } else if (machine.wereCatchesUsed()) {\n            /*\n             * If there are catches, then the first successors\n             * (which will either be all of them or all but the last one)\n             * are catch targets.\n             */\n            startSuccessorIndex = catchSz;\n        } else {\n            startSuccessorIndex = 0;\n        }\n\n        int succSz = successors.size();\n        for (int i = startSuccessorIndex; i < succSz;\n             i++) {\n            int succ = successors.get(i);\n            try {\n                mergeAndWorkAsNecessary(succ, block.getLabel(),\n                        calledSubroutine, frame, workSet);\n            } catch (SimException ex) {\n                ex.addContext(\"...while merging to block \" + Hex.u2(succ));\n                throw ex;\n            }\n        }\n\n        if ((succSz == 0) && machine.returns()) {\n            /*\n             * The block originally contained a return, but it has\n             * been made to instead end with a goto, and we need to\n             * tell it at this point that its sole successor is the\n             * return block. This has to happen after the merge loop\n             * above, since, at this point, the return block doesn't\n             * actually exist; it gets synthesized at the end of\n             * processing the original blocks.\n             */\n            successors = IntList.makeImmutable(getSpecialLabel(RETURN));\n            succSz = 1;\n        }\n\n        int primarySucc;\n\n        if (succSz == 0) {\n            primarySucc = -1;\n        } else {\n            primarySucc = machine.getPrimarySuccessorIndex();\n            if (primarySucc >= 0) {\n                primarySucc = successors.get(primarySucc);\n            }\n        }\n\n        /*\n         * This variable is true only when the method is synchronized and\n         * the block being processed can possibly throw an exception.\n         */\n        boolean synch = isSynchronized() && machine.canThrow();\n\n        if (synch || (catchSz != 0)) {\n            /*\n             * Deal with exception handlers: Merge an exception-catch\n             * frame into each possible exception handler, and\n             * construct a new set of successors to point at the\n             * exception handler setup blocks (which get synthesized\n             * at the very end of processing).\n             */\n            boolean catchesAny = false;\n            IntList newSucc = new IntList(succSz);\n            for (int i = 0; i < catchSz; i++) {\n                ByteCatchList.Item one = catches.get(i);\n                CstType exceptionClass = one.getExceptionClass();\n                int targ = one.getHandlerPc();\n\n                catchesAny |= (exceptionClass == CstType.OBJECT);\n\n                Frame f = frame.makeExceptionHandlerStartFrame(exceptionClass);\n\n                try {\n                    mergeAndWorkAsNecessary(targ, block.getLabel(),\n                            null, f, workSet);\n                } catch (SimException ex) {\n                    ex.addContext(\"...while merging exception to block \" +\n                                  Hex.u2(targ));\n                    throw ex;\n                }\n\n                /*\n                 * Set up the exception handler type.\n                 */\n                CatchInfo handlers = catchInfos[targ];\n                if (handlers == null) {\n                    handlers = new CatchInfo();\n                    catchInfos[targ] = handlers;\n                }\n                ExceptionHandlerSetup handler = handlers.getSetup(exceptionClass.getClassType());\n\n                /*\n                 * The synthesized exception setup block will have the label given by handler.\n                 */\n                newSucc.add(handler.getLabel());\n            }\n\n            if (synch && !catchesAny) {\n                /*\n                 * The method is synchronized and this block doesn't\n                 * already have a catch-all handler, so add one to the\n                 * end, both in the successors and in the throwing\n                 * instruction(s) at the end of the block (which is where\n                 * the caught classes live).\n                 */\n                newSucc.add(getSpecialLabel(SYNCH_CATCH_1));\n                synchNeedsExceptionHandler = true;\n\n                for (int i = insnSz - extraBlockCount - 1; i < insnSz; i++) {\n                    Insn insn = insns.get(i);\n                    if (insn.canThrow()) {\n                        insn = insn.withAddedCatch(Type.OBJECT);\n                        insns.set(i, insn);\n                    }\n                }\n            }\n\n            if (primarySucc >= 0) {\n                newSucc.add(primarySucc);\n            }\n\n            newSucc.setImmutable();\n            successors = newSucc;\n        }\n\n        // Construct the final resulting block(s), and store it (them).\n\n        int primarySuccListIndex = successors.indexOf(primarySucc);\n\n        /*\n         * If there are any extra blocks, work backwards through the\n         * list of instructions, adding single-instruction blocks, and\n         * resetting the successors variables as appropriate.\n         */\n        for (/*extraBlockCount*/; extraBlockCount > 0; extraBlockCount--) {\n            /*\n             * Some of the blocks that the RopperMachine wants added\n             * are for move-result insns, and these need goto insns as well.\n             */\n            Insn extraInsn = insns.get(--insnSz);\n            boolean needsGoto\n                    = extraInsn.getOpcode().getBranchingness()\n                        == Rop.BRANCH_NONE;\n            InsnList il = new InsnList(needsGoto ? 2 : 1);\n            IntList extraBlockSuccessors = successors;\n\n            il.set(0, extraInsn);\n\n            if (needsGoto) {\n                il.set(1, new PlainInsn(Rops.GOTO,\n                        extraInsn.getPosition(), null,\n                        RegisterSpecList.EMPTY));\n                /*\n                 * Obviously, this block won't be throwing an exception\n                 * so it should only have one successor.\n                 */\n                extraBlockSuccessors = IntList.makeImmutable(primarySucc);\n            }\n            il.setImmutable();\n\n            int label = getAvailableLabel();\n            BasicBlock bb = new BasicBlock(label, il, extraBlockSuccessors,\n                    primarySucc);\n            // All of these extra blocks will be in the same subroutine\n            addBlock(bb, frame.getSubroutines());\n\n            successors = successors.mutableCopy();\n            successors.set(primarySuccListIndex, label);\n            successors.setImmutable();\n            primarySucc = label;\n        }\n\n        Insn lastInsn = (insnSz == 0) ? null : insns.get(insnSz - 1);\n\n        /*\n         * Add a goto to the end of the block if it doesn't already\n         * end with a branch, to maintain the invariant that all\n         * blocks end with a branch of some sort or other. Note that\n         * it is possible for there to be blocks for which no\n         * instructions were ever output (e.g., only consist of pop*\n         * in the original Java bytecode).\n         */\n        if ((lastInsn == null) ||\n            (lastInsn.getOpcode().getBranchingness() == Rop.BRANCH_NONE)) {\n            SourcePosition pos = (lastInsn == null) ? SourcePosition.NO_INFO :\n                lastInsn.getPosition();\n            insns.add(new PlainInsn(Rops.GOTO, pos, null,\n                                    RegisterSpecList.EMPTY));\n            insnSz++;\n        }\n\n        /*\n         * Construct a block for the remaining instructions (which in\n         * the usual case is all of them).\n         */\n\n        InsnList il = new InsnList(insnSz);\n        for (int i = 0; i < insnSz; i++) {\n            il.set(i, insns.get(i));\n        }\n        il.setImmutable();\n\n        BasicBlock bb =\n            new BasicBlock(block.getLabel(), il, successors, primarySucc);\n        addOrReplaceBlock(bb, frame.getSubroutines());\n    }\n\n    /**\n     * Helper for {@link #processBlock}, which merges frames and\n     * adds to the work set, as necessary.\n     *\n     * @param label {@code >= 0;} label to work on\n     * @param pred  predecessor label; must be {@code >= 0} when\n     * {@code label} is a subroutine start block and calledSubroutine\n     * is non-null. Otherwise, may be -1.\n     * @param calledSubroutine {@code null-ok;} a Subroutine instance if\n     * {@code label} is the first block in a subroutine.\n     * @param frame {@code non-null;} new frame for the labelled block\n     * @param workSet {@code non-null;} bits representing work to do,\n     * which this method may add to\n     */\n    private void mergeAndWorkAsNecessary(int label, int pred,\n            Subroutine calledSubroutine, Frame frame, int[] workSet) {\n        Frame existing = startFrames[label];\n        Frame merged;\n\n        if (existing != null) {\n            /*\n             * Some other block also continues at this label. Merge\n             * the frames, and re-set the bit in the work set if there\n             * was a change.\n             */\n            if (calledSubroutine != null) {\n                merged = existing.mergeWithSubroutineCaller(frame,\n                        calledSubroutine.getStartBlock(), pred);\n            } else {\n                merged = existing.mergeWith(frame);\n            }\n            if (merged != existing) {\n                startFrames[label] = merged;\n                Bits.set(workSet, label);\n            }\n        } else {\n            // This is the first time this label has been encountered.\n            if (calledSubroutine != null) {\n                startFrames[label]\n                        = frame.makeNewSubroutineStartFrame(label, pred);\n            } else {\n                startFrames[label] = frame;\n            }\n            Bits.set(workSet, label);\n        }\n    }\n\n    /**\n     * Constructs and adds the blocks that perform setup for the rest of\n     * the method. This includes a first block which merely contains\n     * assignments from parameters to the same-numbered registers and\n     * a possible second block which deals with synchronization.\n     */\n    private void addSetupBlocks() {\n        LocalVariableList localVariables = method.getLocalVariables();\n        SourcePosition pos = method.makeSourcePosistion(0);\n        Prototype desc = method.getEffectiveDescriptor();\n        StdTypeList params = desc.getParameterTypes();\n        int sz = params.size();\n        InsnList insns = new InsnList(sz + 1);\n        int at = 0;\n\n        for (int i = 0; i < sz; i++) {\n            Type one = params.get(i);\n            LocalVariableList.Item local =\n                localVariables.pcAndIndexToLocal(0, at);\n            RegisterSpec result = (local == null) ?\n                RegisterSpec.make(at, one) :\n                RegisterSpec.makeLocalOptional(at, one, local.getLocalItem());\n\n            Insn insn = new PlainCstInsn(Rops.opMoveParam(one), pos, result,\n                                         RegisterSpecList.EMPTY,\n                                         CstInteger.make(at));\n            insns.set(i, insn);\n            at += one.getCategory();\n        }\n\n        insns.set(sz, new PlainInsn(Rops.GOTO, pos, null,\n                                    RegisterSpecList.EMPTY));\n        insns.setImmutable();\n\n        boolean synch = isSynchronized();\n        int label = synch ? getSpecialLabel(SYNCH_SETUP_1) : 0;\n        BasicBlock bb =\n            new BasicBlock(getSpecialLabel(PARAM_ASSIGNMENT), insns,\n                           IntList.makeImmutable(label), label);\n        addBlock(bb, IntList.EMPTY);\n\n        if (synch) {\n            RegisterSpec synchReg = getSynchReg();\n            Insn insn;\n            if (isStatic()) {\n                insn = new ThrowingCstInsn(Rops.CONST_OBJECT, pos,\n                                           RegisterSpecList.EMPTY,\n                                           StdTypeList.EMPTY,\n                                           method.getDefiningClass());\n                insns = new InsnList(1);\n                insns.set(0, insn);\n            } else {\n                insns = new InsnList(2);\n                insn = new PlainCstInsn(Rops.MOVE_PARAM_OBJECT, pos,\n                                        synchReg, RegisterSpecList.EMPTY,\n                                        CstInteger.VALUE_0);\n                insns.set(0, insn);\n                insns.set(1, new PlainInsn(Rops.GOTO, pos, null,\n                                           RegisterSpecList.EMPTY));\n            }\n\n            int label2 = getSpecialLabel(SYNCH_SETUP_2);\n            insns.setImmutable();\n            bb = new BasicBlock(label, insns,\n                                IntList.makeImmutable(label2), label2);\n            addBlock(bb, IntList.EMPTY);\n\n            insns = new InsnList(isStatic() ? 2 : 1);\n\n            if (isStatic()) {\n                insns.set(0, new PlainInsn(Rops.opMoveResultPseudo(synchReg),\n                        pos, synchReg, RegisterSpecList.EMPTY));\n            }\n\n            insn = new ThrowingInsn(Rops.MONITOR_ENTER, pos,\n                                    RegisterSpecList.make(synchReg),\n                                    StdTypeList.EMPTY);\n            insns.set(isStatic() ? 1 :0, insn);\n            insns.setImmutable();\n            bb = new BasicBlock(label2, insns, IntList.makeImmutable(0), 0);\n            addBlock(bb, IntList.EMPTY);\n        }\n    }\n\n    /**\n     * Constructs and adds the return block, if necessary. The return\n     * block merely contains an appropriate {@code return}\n     * instruction.\n     */\n    private void addReturnBlock() {\n        Rop returnOp = machine.getReturnOp();\n\n        if (returnOp == null) {\n            /*\n             * The method being converted never returns normally, so there's\n             * no need for a return block.\n             */\n            return;\n        }\n\n        SourcePosition returnPos = machine.getReturnPosition();\n        int label = getSpecialLabel(RETURN);\n\n        if (isSynchronized()) {\n            InsnList insns = new InsnList(1);\n            Insn insn = new ThrowingInsn(Rops.MONITOR_EXIT, returnPos,\n                                         RegisterSpecList.make(getSynchReg()),\n                                         StdTypeList.EMPTY);\n            insns.set(0, insn);\n            insns.setImmutable();\n\n            int nextLabel = getSpecialLabel(SYNCH_RETURN);\n            BasicBlock bb =\n                new BasicBlock(label, insns,\n                               IntList.makeImmutable(nextLabel), nextLabel);\n            addBlock(bb, IntList.EMPTY);\n\n            label = nextLabel;\n        }\n\n        InsnList insns = new InsnList(1);\n        TypeList sourceTypes = returnOp.getSources();\n        RegisterSpecList sources;\n\n        if (sourceTypes.size() == 0) {\n            sources = RegisterSpecList.EMPTY;\n        } else {\n            RegisterSpec source = RegisterSpec.make(0, sourceTypes.getType(0));\n            sources = RegisterSpecList.make(source);\n        }\n\n        Insn insn = new PlainInsn(returnOp, returnPos, null, sources);\n        insns.set(0, insn);\n        insns.setImmutable();\n\n        BasicBlock bb = new BasicBlock(label, insns, IntList.EMPTY, -1);\n        addBlock(bb, IntList.EMPTY);\n    }\n\n    /**\n     * Constructs and adds, if necessary, the catch-all exception handler\n     * block to deal with unwinding the lock taken on entry to a synchronized\n     * method.\n     */\n    private void addSynchExceptionHandlerBlock() {\n        if (!synchNeedsExceptionHandler) {\n            /*\n             * The method being converted either isn't synchronized or\n             * can't possibly throw exceptions in its main body, so\n             * there's no need for a synchronized method exception\n             * handler.\n             */\n            return;\n        }\n\n        SourcePosition pos = method.makeSourcePosistion(0);\n        RegisterSpec exReg = RegisterSpec.make(0, Type.THROWABLE);\n        BasicBlock bb;\n        Insn insn;\n\n        InsnList insns = new InsnList(2);\n        insn = new PlainInsn(Rops.opMoveException(Type.THROWABLE), pos,\n                             exReg, RegisterSpecList.EMPTY);\n        insns.set(0, insn);\n        insn = new ThrowingInsn(Rops.MONITOR_EXIT, pos,\n                                RegisterSpecList.make(getSynchReg()),\n                                StdTypeList.EMPTY);\n        insns.set(1, insn);\n        insns.setImmutable();\n\n        int label2 = getSpecialLabel(SYNCH_CATCH_2);\n        bb = new BasicBlock(getSpecialLabel(SYNCH_CATCH_1), insns,\n                            IntList.makeImmutable(label2), label2);\n        addBlock(bb, IntList.EMPTY);\n\n        insns = new InsnList(1);\n        insn = new ThrowingInsn(Rops.THROW, pos,\n                                RegisterSpecList.make(exReg),\n                                StdTypeList.EMPTY);\n        insns.set(0, insn);\n        insns.setImmutable();\n\n        bb = new BasicBlock(label2, insns, IntList.EMPTY, -1);\n        addBlock(bb, IntList.EMPTY);\n    }\n\n    /**\n     * Creates the exception handler setup blocks. \"maxLocals\"\n     * below is because that's the register number corresponding\n     * to the sole element on a one-deep stack (which is the\n     * situation at the start of an exception handler block).\n     */\n    private void addExceptionSetupBlocks() {\n\n        int len = catchInfos.length;\n        for (int i = 0; i < len; i++) {\n            CatchInfo catches = catchInfos[i];\n            if (catches != null) {\n                for (ExceptionHandlerSetup one : catches.getSetups()) {\n                    Insn proto = labelToBlock(i).getFirstInsn();\n                    SourcePosition pos = proto.getPosition();\n                    InsnList il = new InsnList(2);\n\n                    Insn insn = new PlainInsn(Rops.opMoveException(one.getCaughtType()),\n                            pos,\n                            RegisterSpec.make(maxLocals, one.getCaughtType()),\n                            RegisterSpecList.EMPTY);\n                    il.set(0, insn);\n\n                    insn = new PlainInsn(Rops.GOTO, pos, null,\n                            RegisterSpecList.EMPTY);\n                    il.set(1, insn);\n                    il.setImmutable();\n\n                    BasicBlock bb = new BasicBlock(one.getLabel(),\n                            il,\n                            IntList.makeImmutable(i),\n                            i);\n                    addBlock(bb, startFrames[i].getSubroutines());\n                }\n            }\n        }\n    }\n\n    /**\n     * Checks to see if the basic block is a subroutine caller block.\n     *\n     * @param bb {@code non-null;} the basic block in question\n     * @return true if this block calls a subroutine\n     */\n    private boolean isSubroutineCaller(BasicBlock bb) {\n        IntList successors = bb.getSuccessors();\n        if (successors.size() < 2) return false;\n\n        int subLabel = successors.get(1);\n\n        return (subLabel < subroutines.length)\n                && (subroutines[subLabel] != null);\n    }\n\n    /**\n     * Inlines any subroutine calls.\n     */\n    private void inlineSubroutines() {\n        final IntList reachableSubroutineCallerLabels = new IntList(4);\n\n        /*\n         * Compile a list of all subroutine calls reachable\n         * through the normal (non-subroutine) flow.  We do this first, since\n         * we'll be affecting the call flow as we go.\n         *\n         * Start at label 0 --  the param assignment block has nothing for us\n         */\n        forEachNonSubBlockDepthFirst(0, new BasicBlock.Visitor() {\n            public void visitBlock(BasicBlock b) {\n                if (isSubroutineCaller(b)) {\n                    reachableSubroutineCallerLabels.add(b.getLabel());\n                }\n            }\n        });\n\n        /*\n         * Convert the resultSubroutines list, indexed by block index,\n         * to a label-to-subroutines mapping used by the inliner.\n         */\n        int largestAllocedLabel = getAvailableLabel();\n        ArrayList<IntList> labelToSubroutines\n                = new ArrayList<IntList>(largestAllocedLabel);\n        for (int i = 0; i < largestAllocedLabel; i++) {\n            labelToSubroutines.add(null);\n        }\n\n        for (int i = 0; i < result.size(); i++) {\n            BasicBlock b = result.get(i);\n            if (b == null) {\n                continue;\n            }\n            IntList subroutineList = resultSubroutines.get(i);\n            labelToSubroutines.set(b.getLabel(), subroutineList);\n        }\n\n        /*\n         * Inline all reachable subroutines.\n         * Inner subroutines will be inlined as they are encountered.\n         */\n        int sz = reachableSubroutineCallerLabels.size();\n        for (int i = 0 ; i < sz ; i++) {\n            int label = reachableSubroutineCallerLabels.get(i);\n            new SubroutineInliner(\n                    new LabelAllocator(getAvailableLabel()),\n                    labelToSubroutines)\n                    .inlineSubroutineCalledFrom(labelToBlock(label));\n        }\n\n        // Now find the blocks that aren't reachable and remove them\n        deleteUnreachableBlocks();\n    }\n\n    /**\n     * Deletes all blocks that cannot be reached. This is run to delete\n     * original subroutine blocks after subroutine inlining.\n     */\n    private void deleteUnreachableBlocks() {\n        final IntList reachableLabels = new IntList(result.size());\n\n        // subroutine inlining is done now and we won't update this list here\n        resultSubroutines.clear();\n\n        forEachNonSubBlockDepthFirst(getSpecialLabel(PARAM_ASSIGNMENT),\n                new BasicBlock.Visitor() {\n\n            public void visitBlock(BasicBlock b) {\n                reachableLabels.add(b.getLabel());\n            }\n        });\n\n        reachableLabels.sort();\n\n        for (int i = result.size() - 1 ; i >= 0 ; i--) {\n            if (reachableLabels.indexOf(result.get(i).getLabel()) < 0) {\n                result.remove(i);\n                // unnecessary here really, since subroutine inlining is done\n                //resultSubroutines.remove(i);\n            }\n        }\n    }\n\n    /**\n     * Allocates labels, without requiring previously allocated labels\n     * to have been added to the blocks list.\n     */\n    private static class LabelAllocator {\n        int nextAvailableLabel;\n\n        /**\n         * @param startLabel available label to start allocating from\n         */\n        LabelAllocator(int startLabel) {\n            nextAvailableLabel = startLabel;\n        }\n\n        /**\n         * @return next available label\n         */\n        int getNextLabel() {\n            return nextAvailableLabel++;\n        }\n    }\n\n    /**\n     * Allocates labels for exception setup blocks.\n     */\n    private class ExceptionSetupLabelAllocator extends LabelAllocator {\n        int maxSetupLabel;\n\n        ExceptionSetupLabelAllocator() {\n            super(maxLabel);\n            maxSetupLabel = maxLabel + method.getCatches().size();\n        }\n\n        @Override\n        int getNextLabel() {\n            if (nextAvailableLabel >= maxSetupLabel) {\n                throw new IndexOutOfBoundsException();\n            }\n            return nextAvailableLabel ++;\n        }\n    }\n\n    /**\n     * Inlines a subroutine. Start by calling\n     * {@link #inlineSubroutineCalledFrom}.\n     */\n    private class SubroutineInliner {\n        /**\n         * maps original label to the label that will be used by the\n         * inlined version\n         */\n        private final HashMap<Integer, Integer> origLabelToCopiedLabel;\n\n        /** set of original labels that need to be copied */\n        private final BitSet workList;\n\n        /** the label of the original start block for this subroutine */\n        private int subroutineStart;\n\n        /** the label of the ultimate return block */\n        private int subroutineSuccessor;\n\n        /** used for generating new labels for copied blocks */\n        private final LabelAllocator labelAllocator;\n\n        /**\n         * A mapping, indexed by label, to subroutine nesting list.\n         * The subroutine nest list is as returned by\n         * {@link Frame#getSubroutines}.\n         */\n        private final ArrayList<IntList> labelToSubroutines;\n\n        SubroutineInliner(final LabelAllocator labelAllocator,\n                ArrayList<IntList> labelToSubroutines) {\n            origLabelToCopiedLabel = new HashMap<Integer, Integer>();\n\n            workList = new BitSet(maxLabel);\n\n            this.labelAllocator = labelAllocator;\n            this.labelToSubroutines = labelToSubroutines;\n        }\n\n        /**\n         * Inlines a subroutine.\n         *\n         * @param b block where {@code jsr} occurred in the original bytecode\n         */\n        void inlineSubroutineCalledFrom(final BasicBlock b) {\n            /*\n             * The 0th successor of a subroutine caller block is where\n             * the subroutine should return to. The 1st successor is\n             * the start block of the subroutine.\n             */\n            subroutineSuccessor = b.getSuccessors().get(0);\n            subroutineStart = b.getSuccessors().get(1);\n\n            /*\n             * This allocates an initial label and adds the first\n             * block to the worklist.\n             */\n            int newSubStartLabel = mapOrAllocateLabel(subroutineStart);\n\n            for (int label = workList.nextSetBit(0); label >= 0;\n                 label = workList.nextSetBit(0)) {\n                workList.clear(label);\n                int newLabel = origLabelToCopiedLabel.get(label);\n\n                copyBlock(label, newLabel);\n\n                if (isSubroutineCaller(labelToBlock(label))) {\n                    new SubroutineInliner(labelAllocator, labelToSubroutines)\n                        .inlineSubroutineCalledFrom(labelToBlock(newLabel));\n                }\n            }\n\n            /*\n             * Replace the original caller block, since we now have a\n             * new successor\n             */\n\n            addOrReplaceBlockNoDelete(\n                new BasicBlock(b.getLabel(), b.getInsns(),\n                    IntList.makeImmutable (newSubStartLabel),\n                            newSubStartLabel),\n                labelToSubroutines.get(b.getLabel()));\n        }\n\n        /**\n         * Copies a basic block, mapping its successors along the way.\n         *\n         * @param origLabel original block label\n         * @param newLabel label that the new block should have\n         */\n        private void copyBlock(int origLabel, int newLabel) {\n\n            BasicBlock origBlock = labelToBlock(origLabel);\n\n            final IntList origSuccessors = origBlock.getSuccessors();\n            IntList successors;\n            int primarySuccessor = -1;\n            Subroutine subroutine;\n\n            if (isSubroutineCaller(origBlock)) {\n                /*\n                 * A subroutine call inside a subroutine call.\n                 * Set up so we can recurse. The caller block should have\n                 * it's first successor be a copied block that will be\n                 * the subroutine's return point. It's second successor will\n                 * be copied when we recurse, and remains as the original\n                 * label of the start of the inner subroutine.\n                 */\n\n                successors = IntList.makeImmutable(\n                        mapOrAllocateLabel(origSuccessors.get(0)),\n                        origSuccessors.get(1));\n                // primary successor will be set when this block is replaced\n            } else if (null\n                    != (subroutine = subroutineFromRetBlock(origLabel))) {\n                /*\n                 * this is a ret block -- its successor\n                 * should be subroutineSuccessor\n                 */\n\n                // Sanity check\n                if (subroutine.startBlock != subroutineStart) {\n                    throw new RuntimeException (\n                            \"ret instruction returns to label \"\n                            + Hex.u2 (subroutine.startBlock)\n                            + \" expected: \" + Hex.u2(subroutineStart));\n                }\n\n                successors = IntList.makeImmutable(subroutineSuccessor);\n                primarySuccessor = subroutineSuccessor;\n            } else {\n                // Map all the successor labels\n\n                int origPrimary = origBlock.getPrimarySuccessor();\n                int sz = origSuccessors.size();\n\n                successors = new IntList(sz);\n\n                for (int i = 0 ; i < sz ; i++) {\n                    int origSuccLabel = origSuccessors.get(i);\n                    int newSuccLabel =  mapOrAllocateLabel(origSuccLabel);\n\n                    successors.add(newSuccLabel);\n\n                    if (origPrimary == origSuccLabel) {\n                        primarySuccessor = newSuccLabel;\n                    }\n                }\n\n                successors.setImmutable();\n            }\n\n            addBlock (\n                new BasicBlock(newLabel,\n                    filterMoveReturnAddressInsns(origBlock.getInsns()),\n                    successors, primarySuccessor),\n                    labelToSubroutines.get(newLabel));\n        }\n\n        /**\n         * Checks to see if a specified label is involved in a specified\n         * subroutine.\n         *\n         * @param label {@code >= 0;} a basic block label\n         * @param subroutineStart {@code >= 0;} a subroutine as identified\n         * by the label of its start block\n         * @return true if the block is dominated by the subroutine call\n         */\n        private boolean involvedInSubroutine(int label, int subroutineStart) {\n            IntList subroutinesList = labelToSubroutines.get(label);\n            return (subroutinesList != null && subroutinesList.size() > 0\n                    && subroutinesList.top() == subroutineStart);\n        }\n\n        /**\n         * Maps the label of a pre-copied block to the label of the inlined\n         * block, allocating a new label and adding it to the worklist\n         * if necessary.  If the origLabel is a \"special\" label, it\n         * is returned exactly and not scheduled for duplication: copying\n         * never proceeds past a special label, which likely is the function\n         * return block or an immediate predecessor.\n         *\n         * @param origLabel label of original, pre-copied block\n         * @return label for new, inlined block\n         */\n        private int mapOrAllocateLabel(int origLabel) {\n            int resultLabel;\n            Integer mappedLabel = origLabelToCopiedLabel.get(origLabel);\n\n            if (mappedLabel != null) {\n                resultLabel = mappedLabel;\n            } else if (!involvedInSubroutine(origLabel,subroutineStart)) {\n                /*\n                 * A subroutine has ended by some means other than a \"ret\"\n                 * (which really means a throw caught later).\n                 */\n                resultLabel = origLabel;\n            } else {\n                resultLabel = labelAllocator.getNextLabel();\n                workList.set(origLabel);\n                origLabelToCopiedLabel.put(origLabel, resultLabel);\n\n                // The new label has the same frame as the original label\n                while (labelToSubroutines.size() <= resultLabel) {\n                    labelToSubroutines.add(null);\n                }\n                labelToSubroutines.set(resultLabel,\n                        labelToSubroutines.get(origLabel));\n            }\n\n            return resultLabel;\n        }\n    }\n\n    /**\n     * Finds a {@code Subroutine} that is returned from by a {@code ret} in\n     * a given block.\n     *\n     * @param label A block that originally contained a {@code ret} instruction\n     * @return {@code null-ok;} found subroutine or {@code null} if none\n     * was found\n     */\n    private Subroutine subroutineFromRetBlock(int label) {\n        for (int i = subroutines.length - 1 ; i >= 0 ; i--) {\n            if (subroutines[i] != null) {\n                Subroutine subroutine = subroutines[i];\n\n                if (subroutine.retBlocks.get(label)) {\n                    return subroutine;\n                }\n            }\n        }\n\n        return null;\n    }\n\n\n    /**\n     * Removes all {@code move-return-address} instructions, returning a new\n     * {@code InsnList} if necessary. The {@code move-return-address}\n     * insns are dead code after subroutines have been inlined.\n     *\n     * @param insns {@code InsnList} that may contain\n     * {@code move-return-address} insns\n     * @return {@code InsnList} with {@code move-return-address} removed\n     */\n    private InsnList filterMoveReturnAddressInsns(InsnList insns) {\n        int sz;\n        int newSz = 0;\n\n        // First see if we need to filter, and if so what the new size will be\n        sz = insns.size();\n        for (int i = 0; i < sz; i++) {\n            if (insns.get(i).getOpcode() != Rops.MOVE_RETURN_ADDRESS) {\n                newSz++;\n            }\n        }\n\n        if (newSz == sz) {\n            return insns;\n        }\n\n        // Make a new list without the MOVE_RETURN_ADDRESS insns\n        InsnList newInsns = new InsnList(newSz);\n\n        int newIndex = 0;\n        for (int i = 0; i < sz; i++) {\n            Insn insn = insns.get(i);\n            if (insn.getOpcode() != Rops.MOVE_RETURN_ADDRESS) {\n                newInsns.set(newIndex++, insn);\n            }\n        }\n\n        newInsns.setImmutable();\n        return newInsns;\n    }\n\n    /**\n     * Visits each non-subroutine block once in depth-first successor order.\n     *\n     * @param firstLabel label of start block\n     * @param v callback interface\n     */\n    private void forEachNonSubBlockDepthFirst(int firstLabel,\n            BasicBlock.Visitor v) {\n        forEachNonSubBlockDepthFirst0(labelToBlock(firstLabel),\n                v, new BitSet(maxLabel));\n    }\n\n    /**\n     * Visits each block once in depth-first successor order, ignoring\n     * {@code jsr} targets. Worker for {@link #forEachNonSubBlockDepthFirst}.\n     *\n     * @param next next block to visit\n     * @param v callback interface\n     * @param visited set of blocks already visited\n     */\n    private void forEachNonSubBlockDepthFirst0(\n            BasicBlock next, BasicBlock.Visitor v, BitSet visited) {\n        v.visitBlock(next);\n        visited.set(next.getLabel());\n\n        IntList successors = next.getSuccessors();\n        int sz = successors.size();\n\n        for (int i = 0; i < sz; i++) {\n            int succ = successors.get(i);\n\n            if (visited.get(succ)) {\n                continue;\n            }\n\n            if (isSubroutineCaller(next) && i > 0) {\n                // ignore jsr targets\n                continue;\n            }\n\n            /*\n             * Ignore missing labels: they're successors of\n             * subroutines that never invoke a ret.\n             */\n            int idx = labelToResultIndex(succ);\n            if (idx >= 0) {\n                forEachNonSubBlockDepthFirst0(result.get(idx), v, visited);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/RopperMachine.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.cf.iface.Method;\nimport com.taobao.android.dx.cf.iface.MethodList;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.code.FillArrayDataInsn;\nimport com.taobao.android.dx.rop.code.Insn;\nimport com.taobao.android.dx.rop.code.PlainCstInsn;\nimport com.taobao.android.dx.rop.code.PlainInsn;\nimport com.taobao.android.dx.rop.code.RegOps;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rop;\nimport com.taobao.android.dx.rop.code.Rops;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.rop.code.SwitchInsn;\nimport com.taobao.android.dx.rop.code.ThrowingCstInsn;\nimport com.taobao.android.dx.rop.code.ThrowingInsn;\nimport com.taobao.android.dx.rop.code.TranslationAdvice;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.IntList;\nimport java.util.ArrayList;\n\n/**\n * Machine implementation for use by {@link Ropper}.\n */\n/*package*/ final class RopperMachine extends ValueAwareMachine {\n    /** {@code non-null;} array reflection class */\n    private static final CstType ARRAY_REFLECT_TYPE =\n        new CstType(Type.internClassName(\"java/lang/reflect/Array\"));\n\n    /**\n     * {@code non-null;} method constant for use in converting\n     * {@code multianewarray} instructions\n     */\n    private static final CstMethodRef MULTIANEWARRAY_METHOD =\n        new CstMethodRef(ARRAY_REFLECT_TYPE,\n                         new CstNat(new CstString(\"newInstance\"),\n                                    new CstString(\"(Ljava/lang/Class;[I)\" +\n                                                \"Ljava/lang/Object;\")));\n\n    /** {@code non-null;} {@link Ropper} controlling this instance */\n    private final Ropper ropper;\n\n    /** {@code non-null;} method being converted */\n    private final ConcreteMethod method;\n\n    /** {@code non-null:} list of methods from the class whose method is being converted */\n    private final MethodList methods;\n\n    /** {@code non-null;} translation advice */\n    private final TranslationAdvice advice;\n\n    /** max locals of the method */\n    private final int maxLocals;\n\n    /** {@code non-null;} instructions for the rop basic block in-progress */\n    private final ArrayList<Insn> insns;\n\n    /** {@code non-null;} catches for the block currently being processed */\n    private TypeList catches;\n\n    /** whether the catches have been used in an instruction */\n    private boolean catchesUsed;\n\n    /** whether the block contains a {@code return} */\n    private boolean returns;\n\n    /** primary successor index */\n    private int primarySuccessorIndex;\n\n    /** {@code >= 0;} number of extra basic blocks required */\n    private int extraBlockCount;\n\n    /** true if last processed block ends with a jsr or jsr_W*/\n    private boolean hasJsr;\n\n    /** true if an exception can be thrown by the last block processed */\n    private boolean blockCanThrow;\n\n    /**\n     * If non-null, the ReturnAddress that was used by the terminating ret\n     * instruction. If null, there was no ret instruction encountered.\n     */\n\n    private ReturnAddress returnAddress;\n\n    /**\n     * {@code null-ok;} the appropriate {@code return} op or {@code null}\n     * if it is not yet known\n     */\n    private Rop returnOp;\n\n    /**\n     * {@code null-ok;} the source position for the return block or {@code null}\n     * if it is not yet known\n     */\n    private SourcePosition returnPosition;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param ropper {@code non-null;} ropper controlling this instance\n     * @param method {@code non-null;} method being converted\n     * @param advice {@code non-null;} translation advice to use\n     * @param methods {@code non-null;} list of methods defined by the class\n     *     that defines {@code method}.\n     */\n    public RopperMachine(Ropper ropper, ConcreteMethod method,\n            TranslationAdvice advice, MethodList methods) {\n        super(method.getEffectiveDescriptor());\n\n        if (methods == null) {\n            throw new NullPointerException(\"methods == null\");\n        }\n\n        if (ropper == null) {\n            throw new NullPointerException(\"ropper == null\");\n        }\n\n        if (advice == null) {\n            throw new NullPointerException(\"advice == null\");\n        }\n\n        this.ropper = ropper;\n        this.method = method;\n        this.methods = methods;\n        this.advice = advice;\n        this.maxLocals = method.getMaxLocals();\n        this.insns = new ArrayList<Insn>(25);\n        this.catches = null;\n        this.catchesUsed = false;\n        this.returns = false;\n        this.primarySuccessorIndex = -1;\n        this.extraBlockCount = 0;\n        this.blockCanThrow = false;\n        this.returnOp = null;\n        this.returnPosition = null;\n    }\n\n    /**\n     * Gets the instructions array. It is shared and gets modified by\n     * subsequent calls to this instance.\n     *\n     * @return {@code non-null;} the instructions array\n     */\n    public ArrayList<Insn> getInsns() {\n        return insns;\n    }\n\n    /**\n     * Gets the return opcode encountered, if any.\n     *\n     * @return {@code null-ok;} the return opcode\n     */\n    public Rop getReturnOp() {\n        return returnOp;\n    }\n\n    /**\n     * Gets the return position, if known.\n     *\n     * @return {@code null-ok;} the return position\n     */\n    public SourcePosition getReturnPosition() {\n        return returnPosition;\n    }\n\n    /**\n     * Gets ready to start working on a new block. This will clear the\n     * {@link #insns} list, set {@link #catches}, reset whether it has\n     * been used, reset whether the block contains a\n     * {@code return}, and reset {@link #primarySuccessorIndex}.\n     */\n    public void startBlock(TypeList catches) {\n        this.catches = catches;\n\n        insns.clear();\n        catchesUsed = false;\n        returns = false;\n        primarySuccessorIndex = 0;\n        extraBlockCount = 0;\n        blockCanThrow = false;\n        hasJsr = false;\n        returnAddress = null;\n    }\n\n    /**\n     * Gets whether {@link #catches} was used. This indicates that the\n     * last instruction in the block is one of the ones that can throw.\n     *\n     * @return whether {@code catches} has been used\n     */\n    public boolean wereCatchesUsed() {\n        return catchesUsed;\n    }\n\n    /**\n     * Gets whether the block just processed ended with a\n     * {@code return}.\n     *\n     * @return whether the block returns\n     */\n    public boolean returns() {\n        return returns;\n    }\n\n    /**\n     * Gets the primary successor index. This is the index into the\n     * successors list where the primary may be found or\n     * {@code -1} if there are successors but no primary\n     * successor. This may return something other than\n     * {@code -1} in the case of an instruction with no\n     * successors at all (primary or otherwise).\n     *\n     * @return {@code >= -1;} the primary successor index\n     */\n    public int getPrimarySuccessorIndex() {\n        return primarySuccessorIndex;\n    }\n\n    /**\n     * Gets how many extra blocks will be needed to represent the\n     * block currently being translated. Each extra block should consist\n     * of one instruction from the end of the original block.\n     *\n     * @return {@code >= 0;} the number of extra blocks needed\n     */\n    public int getExtraBlockCount() {\n        return extraBlockCount;\n    }\n\n    /**\n     * @return true if at least one of the insn processed since the last\n     * call to startBlock() can throw.\n     */\n    public boolean canThrow() {\n        return blockCanThrow;\n    }\n\n    /**\n     * @return true if a JSR has ben encountered since the last call to\n     * startBlock()\n     */\n    public boolean hasJsr() {\n        return hasJsr;\n    }\n\n    /**\n     * @return {@code true} if a {@code ret} has ben encountered since\n     * the last call to {@code startBlock()}\n     */\n    public boolean hasRet() {\n        return returnAddress != null;\n    }\n\n    /**\n     * @return {@code null-ok;} return address of a {@code ret}\n     * instruction if encountered since last call to startBlock().\n     * {@code null} if no ret instruction encountered.\n     */\n    public ReturnAddress getReturnAddress() {\n        return returnAddress;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void run(Frame frame, int offset, int opcode) {\n        /*\n         * This is the stack pointer after the opcode's arguments have been\n         * popped.\n         */\n        int stackPointer = maxLocals + frame.getStack().size();\n\n        // The sources have to be retrieved before super.run() gets called.\n        RegisterSpecList sources = getSources(opcode, stackPointer);\n        int sourceCount = sources.size();\n\n        super.run(frame, offset, opcode);\n\n        SourcePosition pos = method.makeSourcePosistion(offset);\n        RegisterSpec localTarget = getLocalTarget(opcode == ByteOps.ISTORE);\n        int destCount = resultCount();\n        RegisterSpec dest;\n\n        if (destCount == 0) {\n            dest = null;\n            switch (opcode) {\n                case ByteOps.POP:\n                case ByteOps.POP2: {\n                    // These simply don't appear in the rop form.\n                    return;\n                }\n            }\n        } else if (localTarget != null) {\n            dest = localTarget;\n        } else if (destCount == 1) {\n            dest = RegisterSpec.make(stackPointer, result(0));\n        } else {\n            /*\n             * This clause only ever applies to the stack manipulation\n             * ops that have results (that is, dup* and swap but not\n             * pop*).\n             *\n             * What we do is first move all the source registers into\n             * the \"temporary stack\" area defined for the method, and\n             * then move stuff back down onto the main \"stack\" in the\n             * arrangement specified by the stack op pattern.\n             *\n             * Note: This code ends up emitting a lot of what will\n             * turn out to be superfluous moves (e.g., moving back and\n             * forth to the same local when doing a dup); however,\n             * that makes this code a bit easier (and goodness knows\n             * it doesn't need any extra complexity), and all the SSA\n             * stuff is going to want to deal with this sort of\n             * superfluous assignment anyway, so it should be a wash\n             * in the end.\n             */\n            int scratchAt = ropper.getFirstTempStackReg();\n            RegisterSpec[] scratchRegs = new RegisterSpec[sourceCount];\n\n            for (int i = 0; i < sourceCount; i++) {\n                RegisterSpec src = sources.get(i);\n                TypeBearer type = src.getTypeBearer();\n                RegisterSpec scratch = src.withReg(scratchAt);\n                insns.add(new PlainInsn(Rops.opMove(type), pos, scratch, src));\n                scratchRegs[i] = scratch;\n                scratchAt += src.getCategory();\n            }\n\n            for (int pattern = getAuxInt(); pattern != 0; pattern >>= 4) {\n                int which = (pattern & 0x0f) - 1;\n                RegisterSpec scratch = scratchRegs[which];\n                TypeBearer type = scratch.getTypeBearer();\n                insns.add(new PlainInsn(Rops.opMove(type), pos,\n                                        scratch.withReg(stackPointer),\n                                        scratch));\n                stackPointer += type.getType().getCategory();\n            }\n            return;\n        }\n\n        TypeBearer destType = (dest != null) ? dest : Type.VOID;\n        Constant cst = getAuxCst();\n        int ropOpcode;\n        Rop rop;\n        Insn insn;\n\n        if (opcode == ByteOps.MULTIANEWARRAY) {\n            blockCanThrow = true;\n\n            // Add the extra instructions for handling multianewarray.\n\n            extraBlockCount = 6;\n\n            /*\n             * Add an array constructor for the int[] containing all the\n             * dimensions.\n             */\n            RegisterSpec dimsReg =\n                RegisterSpec.make(dest.getNextReg(), Type.INT_ARRAY);\n            rop = Rops.opFilledNewArray(Type.INT_ARRAY, sourceCount);\n            insn = new ThrowingCstInsn(rop, pos, sources, catches,\n                    CstType.INT_ARRAY);\n            insns.add(insn);\n\n            // Add a move-result for the new-filled-array\n            rop = Rops.opMoveResult(Type.INT_ARRAY);\n            insn = new PlainInsn(rop, pos, dimsReg, RegisterSpecList.EMPTY);\n            insns.add(insn);\n\n            /*\n             * Add a const-class instruction for the specified array\n             * class.\n             */\n\n            /*\n             * Remove as many dimensions from the originally specified\n             * class as are given in the explicit list of dimensions,\n             * so as to pass the right component class to the standard\n             * Java library array constructor.\n             */\n            Type componentType = ((CstType) cst).getClassType();\n            for (int i = 0; i < sourceCount; i++) {\n                componentType = componentType.getComponentType();\n            }\n\n            RegisterSpec classReg =\n                RegisterSpec.make(dest.getReg(), Type.CLASS);\n\n            if (componentType.isPrimitive()) {\n                /*\n                 * The component type is primitive (e.g., int as opposed\n                 * to Integer), so we have to fetch the corresponding\n                 * TYPE class.\n                 */\n                CstFieldRef typeField =\n                    CstFieldRef.forPrimitiveType(componentType);\n                insn = new ThrowingCstInsn(Rops.GET_STATIC_OBJECT, pos,\n                                           RegisterSpecList.EMPTY,\n                                           catches, typeField);\n            } else {\n                /*\n                 * The component type is an object type, so just make a\n                 * normal class reference.\n                 */\n                insn = new ThrowingCstInsn(Rops.CONST_OBJECT, pos,\n                                           RegisterSpecList.EMPTY, catches,\n                                           new CstType(componentType));\n            }\n\n            insns.add(insn);\n\n            // Add a move-result-pseudo for the get-static or const\n            rop = Rops.opMoveResultPseudo(classReg.getType());\n            insn = new PlainInsn(rop, pos, classReg, RegisterSpecList.EMPTY);\n            insns.add(insn);\n\n            /*\n             * Add a call to the \"multianewarray method,\" that is,\n             * Array.newInstance(class, dims). Note: The result type\n             * of newInstance() is Object, which is why the last\n             * instruction in this sequence is a cast to the right\n             * type for the original instruction.\n             */\n\n            RegisterSpec objectReg =\n                RegisterSpec.make(dest.getReg(), Type.OBJECT);\n\n            insn = new ThrowingCstInsn(\n                    Rops.opInvokeStatic(MULTIANEWARRAY_METHOD.getPrototype()),\n                    pos, RegisterSpecList.make(classReg, dimsReg),\n                    catches, MULTIANEWARRAY_METHOD);\n            insns.add(insn);\n\n            // Add a move-result.\n            rop = Rops.opMoveResult(MULTIANEWARRAY_METHOD.getPrototype()\n                    .getReturnType());\n            insn = new PlainInsn(rop, pos, objectReg, RegisterSpecList.EMPTY);\n            insns.add(insn);\n\n            /*\n             * And finally, set up for the remainder of this method to\n             * add an appropriate cast.\n             */\n\n            opcode = ByteOps.CHECKCAST;\n            sources = RegisterSpecList.make(objectReg);\n        } else if (opcode == ByteOps.JSR) {\n            // JSR has no Rop instruction\n            hasJsr = true;\n            return;\n        } else if (opcode == ByteOps.RET) {\n            try {\n                returnAddress = (ReturnAddress)arg(0);\n            } catch (ClassCastException ex) {\n                throw new RuntimeException(\n                        \"Argument to RET was not a ReturnAddress\", ex);\n            }\n            // RET has no Rop instruction.\n            return;\n        }\n\n        ropOpcode = jopToRopOpcode(opcode, cst);\n        rop = Rops.ropFor(ropOpcode, destType, sources, cst);\n\n        Insn moveResult = null;\n        if (dest != null && rop.isCallLike()) {\n            /*\n             * We're going to want to have a move-result in the next\n             * basic block.\n             */\n            extraBlockCount++;\n\n            moveResult = new PlainInsn(\n                    Rops.opMoveResult(((CstMethodRef) cst).getPrototype()\n                    .getReturnType()), pos, dest, RegisterSpecList.EMPTY);\n\n            dest = null;\n        } else if (dest != null && rop.canThrow()) {\n            /*\n             * We're going to want to have a move-result-pseudo in the\n             * next basic block.\n             */\n            extraBlockCount++;\n\n            moveResult = new PlainInsn(\n                    Rops.opMoveResultPseudo(dest.getTypeBearer()),\n                    pos, dest, RegisterSpecList.EMPTY);\n\n            dest = null;\n        }\n        if (ropOpcode == RegOps.NEW_ARRAY) {\n            /*\n             * In the original bytecode, this was either a primitive\n             * array constructor \"newarray\" or an object array\n             * constructor \"anewarray\". In the former case, there is\n             * no explicit constant, and in the latter, the constant\n             * is for the element type and not the array type. The rop\n             * instruction form for both of these is supposed to be\n             * the resulting array type, so we initialize / alter\n             * \"cst\" here, accordingly. Conveniently enough, the rop\n             * opcode already gets constructed with the proper array\n             * type.\n             */\n            cst = CstType.intern(rop.getResult());\n        } else if ((cst == null) && (sourceCount == 2)) {\n            TypeBearer firstType = sources.get(0).getTypeBearer();\n            TypeBearer lastType = sources.get(1).getTypeBearer();\n\n            if ((lastType.isConstant() || firstType.isConstant()) &&\n                 advice.hasConstantOperation(rop, sources.get(0),\n                                             sources.get(1))) {\n\n                if (lastType.isConstant()) {\n                    /*\n                     * The target architecture has an instruction that can\n                     * build in the constant found in the second argument,\n                     * so pull it out of the sources and just use it as a\n                     * constant here.\n                     */\n                    cst = (Constant) lastType;\n                    sources = sources.withoutLast();\n\n                    // For subtraction, change to addition and invert constant\n                    if (rop.getOpcode() == RegOps.SUB) {\n                        ropOpcode = RegOps.ADD;\n                        CstInteger cstInt = (CstInteger) lastType;\n                        cst = CstInteger.make(-cstInt.getValue());\n                    }\n                } else {\n                    /*\n                     * The target architecture has an instruction that can\n                     * build in the constant found in the first argument,\n                     * so pull it out of the sources and just use it as a\n                     * constant here.\n                     */\n                    cst = (Constant) firstType;\n                    sources = sources.withoutFirst();\n                }\n\n                rop = Rops.ropFor(ropOpcode, destType, sources, cst);\n            }\n        }\n\n        SwitchList cases = getAuxCases();\n        ArrayList<Constant> initValues = getInitValues();\n        boolean canThrow = rop.canThrow();\n\n        blockCanThrow |= canThrow;\n\n        if (cases != null) {\n            if (cases.size() == 0) {\n                // It's a default-only switch statement. It can happen!\n                insn = new PlainInsn(Rops.GOTO, pos, null,\n                                     RegisterSpecList.EMPTY);\n                primarySuccessorIndex = 0;\n            } else {\n                IntList values = cases.getValues();\n                insn = new SwitchInsn(rop, pos, dest, sources, values);\n                primarySuccessorIndex = values.size();\n            }\n        } else if (ropOpcode == RegOps.RETURN) {\n            /*\n             * Returns get turned into the combination of a move (if\n             * non-void and if the return doesn't already mention\n             * register 0) and a goto (to the return block).\n             */\n            if (sources.size() != 0) {\n                RegisterSpec source = sources.get(0);\n                TypeBearer type = source.getTypeBearer();\n                if (source.getReg() != 0) {\n                    insns.add(new PlainInsn(Rops.opMove(type), pos,\n                                            RegisterSpec.make(0, type),\n                                            source));\n                }\n            }\n            insn = new PlainInsn(Rops.GOTO, pos, null, RegisterSpecList.EMPTY);\n            primarySuccessorIndex = 0;\n            updateReturnOp(rop, pos);\n            returns = true;\n        } else if (cst != null) {\n            if (canThrow) {\n                insn =\n                    new ThrowingCstInsn(rop, pos, sources, catches, cst);\n                catchesUsed = true;\n                primarySuccessorIndex = catches.size();\n            } else {\n                insn = new PlainCstInsn(rop, pos, dest, sources, cst);\n            }\n        } else if (canThrow) {\n            insn = new ThrowingInsn(rop, pos, sources, catches);\n            catchesUsed = true;\n            if (opcode == ByteOps.ATHROW) {\n                /*\n                 * The op athrow is the only one where it's possible\n                 * to have non-empty successors and yet not have a\n                 * primary successor.\n                 */\n                primarySuccessorIndex = -1;\n            } else {\n                primarySuccessorIndex = catches.size();\n            }\n        } else {\n            insn = new PlainInsn(rop, pos, dest, sources);\n        }\n\n        insns.add(insn);\n\n        if (moveResult != null) {\n            insns.add(moveResult);\n        }\n\n        /*\n         * If initValues is non-null, it means that the parser has\n         * seen a group of compatible constant initialization\n         * bytecodes that are applied to the current newarray. The\n         * action we take here is to convert these initialization\n         * bytecodes into a single fill-array-data ROP which lays out\n         * all the constant values in a table.\n         */\n        if (initValues != null) {\n            extraBlockCount++;\n            insn = new FillArrayDataInsn(Rops.FILL_ARRAY_DATA, pos,\n                    RegisterSpecList.make(moveResult.getResult()), initValues,\n                    cst);\n            insns.add(insn);\n        }\n    }\n\n    /**\n     * Helper for {@link #run}, which gets the list of sources for the.\n     * instruction.\n     *\n     * @param opcode the opcode being translated\n     * @param stackPointer {@code >= 0;} the stack pointer after the\n     * instruction's arguments have been popped\n     * @return {@code non-null;} the sources\n     */\n    private RegisterSpecList getSources(int opcode, int stackPointer) {\n        int count = argCount();\n\n        if (count == 0) {\n            // We get an easy out if there aren't any sources.\n            return RegisterSpecList.EMPTY;\n        }\n\n        int localIndex = getLocalIndex();\n        RegisterSpecList sources;\n\n        if (localIndex >= 0) {\n            // The instruction is operating on a local variable.\n            sources = new RegisterSpecList(1);\n            sources.set(0, RegisterSpec.make(localIndex, arg(0)));\n        } else {\n            sources = new RegisterSpecList(count);\n            int regAt = stackPointer;\n            for (int i = 0; i < count; i++) {\n                RegisterSpec spec = RegisterSpec.make(regAt, arg(i));\n                sources.set(i, spec);\n                regAt += spec.getCategory();\n            }\n\n            switch (opcode) {\n                case ByteOps.IASTORE: {\n                    /*\n                     * The Java argument order for array stores is\n                     * (array, index, value), but the rop argument\n                     * order is (value, array, index). The following\n                     * code gets the right arguments in the right\n                     * places.\n                     */\n                    if (count != 3) {\n                        throw new RuntimeException(\"shouldn't happen\");\n                    }\n                    RegisterSpec array = sources.get(0);\n                    RegisterSpec index = sources.get(1);\n                    RegisterSpec value = sources.get(2);\n                    sources.set(0, value);\n                    sources.set(1, array);\n                    sources.set(2, index);\n                    break;\n                }\n                case ByteOps.PUTFIELD: {\n                    /*\n                     * Similar to above: The Java argument order for\n                     * putfield is (object, value), but the rop\n                     * argument order is (value, object).\n                     */\n                    if (count != 2) {\n                        throw new RuntimeException(\"shouldn't happen\");\n                    }\n                    RegisterSpec obj = sources.get(0);\n                    RegisterSpec value = sources.get(1);\n                    sources.set(0, value);\n                    sources.set(1, obj);\n                    break;\n                }\n            }\n        }\n\n        sources.setImmutable();\n        return sources;\n    }\n\n    /**\n     * Sets or updates the information about the return block.\n     *\n     * @param op {@code non-null;} the opcode to use\n     * @param pos {@code non-null;} the position to use\n     */\n    private void updateReturnOp(Rop op, SourcePosition pos) {\n        if (op == null) {\n            throw new NullPointerException(\"op == null\");\n        }\n\n        if (pos == null) {\n            throw new NullPointerException(\"pos == null\");\n        }\n\n        if (returnOp == null) {\n            returnOp = op;\n            returnPosition = pos;\n        } else {\n            if (returnOp != op) {\n                throw new SimException(\"return op mismatch: \" + op + \", \" +\n                                       returnOp);\n            }\n\n            if (pos.getLine() > returnPosition.getLine()) {\n                // Pick the largest line number to be the \"canonical\" return.\n                returnPosition = pos;\n            }\n        }\n    }\n\n    /**\n     * Gets the register opcode for the given Java opcode.\n     *\n     * @param jop {@code >= 0;} the Java opcode\n     * @param cst {@code null-ok;} the constant argument, if any\n     * @return {@code >= 0;} the corresponding register opcode\n     */\n    private int jopToRopOpcode(int jop, Constant cst) {\n        switch (jop) {\n            case ByteOps.POP:\n            case ByteOps.POP2:\n            case ByteOps.DUP:\n            case ByteOps.DUP_X1:\n            case ByteOps.DUP_X2:\n            case ByteOps.DUP2:\n            case ByteOps.DUP2_X1:\n            case ByteOps.DUP2_X2:\n            case ByteOps.SWAP:\n            case ByteOps.JSR:\n            case ByteOps.RET:\n            case ByteOps.MULTIANEWARRAY: {\n                // These need to be taken care of specially.\n                break;\n            }\n            case ByteOps.NOP: {\n                return RegOps.NOP;\n            }\n            case ByteOps.LDC:\n            case ByteOps.LDC2_W: {\n                return RegOps.CONST;\n            }\n            case ByteOps.ILOAD:\n            case ByteOps.ISTORE: {\n                return RegOps.MOVE;\n            }\n            case ByteOps.IALOAD: {\n                return RegOps.AGET;\n            }\n            case ByteOps.IASTORE: {\n                return RegOps.APUT;\n            }\n            case ByteOps.IADD:\n            case ByteOps.IINC: {\n                return RegOps.ADD;\n            }\n            case ByteOps.ISUB: {\n                return RegOps.SUB;\n            }\n            case ByteOps.IMUL: {\n                return RegOps.MUL;\n            }\n            case ByteOps.IDIV: {\n                return RegOps.DIV;\n            }\n            case ByteOps.IREM: {\n                return RegOps.REM;\n            }\n            case ByteOps.INEG: {\n                return RegOps.NEG;\n            }\n            case ByteOps.ISHL: {\n                return RegOps.SHL;\n            }\n            case ByteOps.ISHR: {\n                return RegOps.SHR;\n            }\n            case ByteOps.IUSHR: {\n                return RegOps.USHR;\n            }\n            case ByteOps.IAND: {\n                return RegOps.AND;\n            }\n            case ByteOps.IOR: {\n                return RegOps.OR;\n            }\n            case ByteOps.IXOR: {\n                return RegOps.XOR;\n            }\n            case ByteOps.I2L:\n            case ByteOps.I2F:\n            case ByteOps.I2D:\n            case ByteOps.L2I:\n            case ByteOps.L2F:\n            case ByteOps.L2D:\n            case ByteOps.F2I:\n            case ByteOps.F2L:\n            case ByteOps.F2D:\n            case ByteOps.D2I:\n            case ByteOps.D2L:\n            case ByteOps.D2F: {\n                return RegOps.CONV;\n            }\n            case ByteOps.I2B: {\n                return RegOps.TO_BYTE;\n            }\n            case ByteOps.I2C: {\n                return RegOps.TO_CHAR;\n            }\n            case ByteOps.I2S: {\n                return RegOps.TO_SHORT;\n            }\n            case ByteOps.LCMP:\n            case ByteOps.FCMPL:\n            case ByteOps.DCMPL: {\n                return RegOps.CMPL;\n            }\n            case ByteOps.FCMPG:\n            case ByteOps.DCMPG: {\n                return RegOps.CMPG;\n            }\n            case ByteOps.IFEQ:\n            case ByteOps.IF_ICMPEQ:\n            case ByteOps.IF_ACMPEQ:\n            case ByteOps.IFNULL: {\n                return RegOps.IF_EQ;\n            }\n            case ByteOps.IFNE:\n            case ByteOps.IF_ICMPNE:\n            case ByteOps.IF_ACMPNE:\n            case ByteOps.IFNONNULL: {\n                return RegOps.IF_NE;\n            }\n            case ByteOps.IFLT:\n            case ByteOps.IF_ICMPLT: {\n                return RegOps.IF_LT;\n            }\n            case ByteOps.IFGE:\n            case ByteOps.IF_ICMPGE: {\n                return RegOps.IF_GE;\n            }\n            case ByteOps.IFGT:\n            case ByteOps.IF_ICMPGT: {\n                return RegOps.IF_GT;\n            }\n            case ByteOps.IFLE:\n            case ByteOps.IF_ICMPLE: {\n                return RegOps.IF_LE;\n            }\n            case ByteOps.GOTO: {\n                return RegOps.GOTO;\n            }\n            case ByteOps.LOOKUPSWITCH: {\n                return RegOps.SWITCH;\n            }\n            case ByteOps.IRETURN:\n            case ByteOps.RETURN: {\n                return RegOps.RETURN;\n            }\n            case ByteOps.GETSTATIC: {\n                return RegOps.GET_STATIC;\n            }\n            case ByteOps.PUTSTATIC: {\n                return RegOps.PUT_STATIC;\n            }\n            case ByteOps.GETFIELD: {\n                return RegOps.GET_FIELD;\n            }\n            case ByteOps.PUTFIELD: {\n                return RegOps.PUT_FIELD;\n            }\n            case ByteOps.INVOKEVIRTUAL: {\n                CstMethodRef ref = (CstMethodRef) cst;\n                // The java bytecode specification does not explicitly disallow\n                // invokevirtual calls to any instance method, though it\n                // specifies that instance methods and private methods \"should\" be\n                // called using \"invokespecial\" instead of \"invokevirtual\".\n                // Several bytecode tools generate \"invokevirtual\" instructions for\n                // invocation of private methods.\n                //\n                // The dalvik opcode specification on the other hand allows\n                // invoke-virtual to be used only with \"normal\" virtual methods,\n                // i.e, ones that are not private, static, final or constructors.\n                // We therefore need to transform invoke-virtual calls to private\n                // instance methods to invoke-direct opcodes.\n                //\n                // Note that it assumes that all methods for a given class are\n                // defined in the same dex file.\n                //\n                // NOTE: This is a slow O(n) loop, and can be replaced with a\n                // faster implementation (at the cost of higher memory usage)\n                // if it proves to be a hot area of code.\n                if (ref.getDefiningClass().equals(method.getDefiningClass())) {\n                    for (int i = 0; i < methods.size(); ++i) {\n                        final Method m = methods.get(i);\n                        if (AccessFlags.isPrivate(m.getAccessFlags()) &&\n                                ref.getNat().equals(m.getNat())) {\n                            return RegOps.INVOKE_DIRECT;\n                        }\n                    }\n                }\n                return RegOps.INVOKE_VIRTUAL;\n            }\n            case ByteOps.INVOKESPECIAL: {\n                /*\n                 * Determine whether the opcode should be\n                 * INVOKE_DIRECT or INVOKE_SUPER. See vmspec-2 section 6\n                 * on \"invokespecial\" as well as section 4.8.2 (7th\n                 * bullet point) for the gory details.\n                 */\n                CstMethodRef ref = (CstMethodRef) cst;\n                if (ref.isInstanceInit() ||\n                    (ref.getDefiningClass().equals(method.getDefiningClass())) ||\n                    !method.getAccSuper()) {\n                    return RegOps.INVOKE_DIRECT;\n                }\n                return RegOps.INVOKE_SUPER;\n            }\n            case ByteOps.INVOKESTATIC: {\n                return RegOps.INVOKE_STATIC;\n            }\n            case ByteOps.INVOKEINTERFACE: {\n                return RegOps.INVOKE_INTERFACE;\n            }\n            case ByteOps.NEW: {\n                return RegOps.NEW_INSTANCE;\n            }\n            case ByteOps.NEWARRAY:\n            case ByteOps.ANEWARRAY: {\n                return RegOps.NEW_ARRAY;\n            }\n            case ByteOps.ARRAYLENGTH: {\n                return RegOps.ARRAY_LENGTH;\n            }\n            case ByteOps.ATHROW: {\n                return RegOps.THROW;\n            }\n            case ByteOps.CHECKCAST: {\n                return RegOps.CHECK_CAST;\n            }\n            case ByteOps.INSTANCEOF: {\n                return RegOps.INSTANCE_OF;\n            }\n            case ByteOps.MONITORENTER: {\n                return RegOps.MONITOR_ENTER;\n            }\n            case ByteOps.MONITOREXIT: {\n                return RegOps.MONITOR_EXIT;\n            }\n        }\n\n        throw new RuntimeException(\"shouldn't happen\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/SimException.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\n\n/**\n * Exception from simulation.\n */\npublic class SimException\n        extends ExceptionWithContext {\n    public SimException(String message) {\n        super(message);\n    }\n\n    public SimException(Throwable cause) {\n        super(cause);\n    }\n\n    public SimException(String message, Throwable cause) {\n        super(message, cause);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/Simulator.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.rop.code.LocalItem;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.cst.CstInterfaceMethodRef;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Prototype;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.ArrayList;\n\n/**\n * Class which knows how to simulate the effects of executing bytecode.\n *\n * <p><b>Note:</b> This class is not thread-safe. If multiple threads\n * need to use a single instance, they must synchronize access explicitly\n * between themselves.</p>\n */\npublic class Simulator {\n    /**\n     * {@code non-null;} canned error message for local variable\n     * table mismatches\n     */\n    private static final String LOCAL_MISMATCH_ERROR =\n        \"This is symptomatic of .class transformation tools that ignore \" +\n        \"local variable information.\";\n\n    /** {@code non-null;} machine to use when simulating */\n    private final Machine machine;\n\n    /** {@code non-null;} array of bytecode */\n    private final BytecodeArray code;\n\n    /** {@code non-null;} local variable information */\n    private final LocalVariableList localVariables;\n\n    /** {@code non-null;} visitor instance to use */\n    private final SimVisitor visitor;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param machine {@code non-null;} machine to use when simulating\n     * @param method {@code non-null;} method data to use\n     */\n    public Simulator(Machine machine, ConcreteMethod method) {\n        if (machine == null) {\n            throw new NullPointerException(\"machine == null\");\n        }\n\n        if (method == null) {\n            throw new NullPointerException(\"method == null\");\n        }\n\n        this.machine = machine;\n        this.code = method.getCode();\n        this.localVariables = method.getLocalVariables();\n        this.visitor = new SimVisitor();\n    }\n\n    /**\n     * Simulates the effect of executing the given basic block. This modifies\n     * the passed-in frame to represent the end result.\n     *\n     * @param bb {@code non-null;} the basic block\n     * @param frame {@code non-null;} frame to operate on\n     */\n    public void simulate(ByteBlock bb, Frame frame) {\n        int end = bb.getEnd();\n\n        visitor.setFrame(frame);\n\n        try {\n            for (int off = bb.getStart(); off < end; /*off*/) {\n                int length = code.parseInstruction(off, visitor);\n                visitor.setPreviousOffset(off);\n                off += length;\n            }\n        } catch (SimException ex) {\n            frame.annotate(ex);\n            throw ex;\n        }\n    }\n\n    /**\n     * Simulates the effect of the instruction at the given offset, by\n     * making appropriate calls on the given frame.\n     *\n     * @param offset {@code >= 0;} offset of the instruction to simulate\n     * @param frame {@code non-null;} frame to operate on\n     * @return the length of the instruction, in bytes\n     */\n    public int simulate(int offset, Frame frame) {\n        visitor.setFrame(frame);\n        return code.parseInstruction(offset, visitor);\n    }\n\n    /**\n     * Constructs an \"illegal top-of-stack\" exception, for the stack\n     * manipulation opcodes.\n     */\n    private static SimException illegalTos() {\n        return new SimException(\"stack mismatch: illegal \" +\n                \"top-of-stack for opcode\");\n    }\n\n    /**\n     * Returns the required array type for an array load or store\n     * instruction, based on a given implied type and an observed\n     * actual array type.\n     *\n     * <p>The interesting cases here have to do with object arrays,\n     * <code>byte[]</code>s, <code>boolean[]</code>s, and\n     * known-nulls.</p>\n     *\n     * <p>In the case of arrays of objects, we want to narrow the type\n     * to the actual array present on the stack, as long as what is\n     * present is an object type. Similarly, due to a quirk of the\n     * original bytecode representation, the instructions for dealing\n     * with <code>byte[]</code> and <code>boolean[]</code> are\n     * undifferentiated, and we aim here to return whichever one was\n     * actually present on the stack.</p>\n     *\n     * <p>In the case where there is a known-null on the stack where\n     * an array is expected, our behavior depends on the implied type\n     * of the instruction. When the implied type is a reference, we\n     * don't attempt to infer anything, as we don't know the dimension\n     * of the null constant and thus any explicit inferred type could\n     * be wrong. When the implied type is a primitive, we fall back to\n     * the implied type of the instruction. Due to the quirk described\n     * above, this means that source code that uses\n     * <code>boolean[]</code> might get translated surprisingly -- but\n     * correctly -- into an instruction that specifies a\n     * <code>byte[]</code>. It will be correct, because should the\n     * code actually execute, it will necessarily throw a\n     * <code>NullPointerException</code>, and it won't matter what\n     * opcode variant is used to achieve that result.</p>\n     *\n     * @param impliedType {@code non-null;} type implied by the\n     * instruction; is <i>not</i> an array type\n     * @param foundArrayType {@code non-null;} type found on the\n     * stack; is either an array type or a known-null\n     * @return {@code non-null;} the array type that should be\n     * required in this context\n     */\n    private static Type requiredArrayTypeFor(Type impliedType,\n            Type foundArrayType) {\n        if (foundArrayType == Type.KNOWN_NULL) {\n            return impliedType.isReference()\n                ? Type.KNOWN_NULL\n                : impliedType.getArrayType();\n        }\n\n        if ((impliedType == Type.OBJECT)\n                && foundArrayType.isArray()\n                && foundArrayType.getComponentType().isReference()) {\n            return foundArrayType;\n        }\n\n        if ((impliedType == Type.BYTE)\n                && (foundArrayType == Type.BOOLEAN_ARRAY)) {\n            /*\n             * Per above, an instruction with implied byte[] is also\n             * allowed to be used on boolean[].\n             */\n            return Type.BOOLEAN_ARRAY;\n        }\n\n        return impliedType.getArrayType();\n    }\n\n    /**\n     * Bytecode visitor used during simulation.\n     */\n    private class SimVisitor implements BytecodeArray.Visitor {\n        /**\n         * {@code non-null;} machine instance to use (just to avoid excessive\n         * cross-object field access)\n         */\n        private final Machine machine;\n\n        /**\n         * {@code null-ok;} frame to use; set with each call to\n         * {@link Simulator#simulate}\n         */\n        private Frame frame;\n\n        /** offset of the previous bytecode */\n        private int previousOffset;\n\n        /**\n         * Constructs an instance.\n         */\n        public SimVisitor() {\n            this.machine = Simulator.this.machine;\n            this.frame = null;\n        }\n\n        /**\n         * Sets the frame to act on.\n         *\n         * @param frame {@code non-null;} the frame\n         */\n        public void setFrame(Frame frame) {\n            if (frame == null) {\n                throw new NullPointerException(\"frame == null\");\n            }\n\n            this.frame = frame;\n        }\n\n        /** {@inheritDoc} */\n        public void visitInvalid(int opcode, int offset, int length) {\n            throw new SimException(\"invalid opcode \" + Hex.u1(opcode));\n        }\n\n        /** {@inheritDoc} */\n        public void visitNoArgs(int opcode, int offset, int length,\n                Type type) {\n            switch (opcode) {\n                case ByteOps.NOP: {\n                    machine.clearArgs();\n                    break;\n                }\n                case ByteOps.INEG: {\n                    machine.popArgs(frame, type);\n                    break;\n                }\n                case ByteOps.I2L:\n                case ByteOps.I2F:\n                case ByteOps.I2D:\n                case ByteOps.I2B:\n                case ByteOps.I2C:\n                case ByteOps.I2S: {\n                    machine.popArgs(frame, Type.INT);\n                    break;\n                }\n                case ByteOps.L2I:\n                case ByteOps.L2F:\n                case ByteOps.L2D: {\n                    machine.popArgs(frame, Type.LONG);\n                    break;\n                }\n                case ByteOps.F2I:\n                case ByteOps.F2L:\n                case ByteOps.F2D: {\n                    machine.popArgs(frame, Type.FLOAT);\n                    break;\n                }\n                case ByteOps.D2I:\n                case ByteOps.D2L:\n                case ByteOps.D2F: {\n                    machine.popArgs(frame, Type.DOUBLE);\n                    break;\n                }\n                case ByteOps.RETURN: {\n                    machine.clearArgs();\n                    checkReturnType(Type.VOID);\n                    break;\n                }\n                case ByteOps.IRETURN: {\n                    Type checkType = type;\n                    if (type == Type.OBJECT) {\n                        /*\n                         * For an object return, use the best-known\n                         * type of the popped value.\n                         */\n                        checkType = frame.getStack().peekType(0);\n                    }\n                    machine.popArgs(frame, type);\n                    checkReturnType(checkType);\n                    break;\n                }\n                case ByteOps.POP: {\n                    Type peekType = frame.getStack().peekType(0);\n                    if (peekType.isCategory2()) {\n                        throw illegalTos();\n                    }\n                    machine.popArgs(frame, 1);\n                    break;\n                }\n                case ByteOps.ARRAYLENGTH: {\n                    Type arrayType = frame.getStack().peekType(0);\n                    if (!arrayType.isArrayOrKnownNull()) {\n                        throw new SimException(\"type mismatch: expected \" +\n                                \"array type but encountered \" +\n                                arrayType.toHuman());\n                    }\n                    machine.popArgs(frame, Type.OBJECT);\n                    break;\n                }\n                case ByteOps.ATHROW:\n                case ByteOps.MONITORENTER:\n                case ByteOps.MONITOREXIT: {\n                    machine.popArgs(frame, Type.OBJECT);\n                    break;\n                }\n                case ByteOps.IALOAD: {\n                    /*\n                     * See comment on requiredArrayTypeFor() for explanation\n                     * about what's going on here.\n                     */\n                    Type foundArrayType = frame.getStack().peekType(1);\n                    Type requiredArrayType =\n                        requiredArrayTypeFor(type, foundArrayType);\n\n                    // Make type agree with the discovered requiredArrayType.\n                    type = (requiredArrayType == Type.KNOWN_NULL)\n                        ? Type.KNOWN_NULL\n                        : requiredArrayType.getComponentType();\n\n                    machine.popArgs(frame, requiredArrayType, Type.INT);\n                    break;\n                }\n                case ByteOps.IADD:\n                case ByteOps.ISUB:\n                case ByteOps.IMUL:\n                case ByteOps.IDIV:\n                case ByteOps.IREM:\n                case ByteOps.IAND:\n                case ByteOps.IOR:\n                case ByteOps.IXOR: {\n                    machine.popArgs(frame, type, type);\n                    break;\n                }\n                case ByteOps.ISHL:\n                case ByteOps.ISHR:\n                case ByteOps.IUSHR: {\n                    machine.popArgs(frame, type, Type.INT);\n                    break;\n                }\n                case ByteOps.LCMP: {\n                    machine.popArgs(frame, Type.LONG, Type.LONG);\n                    break;\n                }\n                case ByteOps.FCMPL:\n                case ByteOps.FCMPG: {\n                    machine.popArgs(frame, Type.FLOAT, Type.FLOAT);\n                    break;\n                }\n                case ByteOps.DCMPL:\n                case ByteOps.DCMPG: {\n                    machine.popArgs(frame, Type.DOUBLE, Type.DOUBLE);\n                    break;\n                }\n                case ByteOps.IASTORE: {\n                    /*\n                     * See comment on requiredArrayTypeFor() for\n                     * explanation about what's going on here. In\n                     * addition to that, the category 1 vs. 2 thing\n                     * below is to deal with the fact that, if the\n                     * element type is category 2, we have to skip\n                     * over one extra stack slot to find the array.\n                     */\n                    ExecutionStack stack = frame.getStack();\n                    int peekDepth = type.isCategory1() ? 2 : 3;\n                    Type foundArrayType = stack.peekType(peekDepth);\n                    boolean foundArrayLocal = stack.peekLocal(peekDepth);\n\n                    Type requiredArrayType =\n                        requiredArrayTypeFor(type, foundArrayType);\n\n                    /*\n                     * Make type agree with the discovered requiredArrayType\n                     * if it has local info.\n                     */\n                    if (foundArrayLocal) {\n                        type = (requiredArrayType == Type.KNOWN_NULL)\n                            ? Type.KNOWN_NULL\n                            : requiredArrayType.getComponentType();\n                    }\n\n                    machine.popArgs(frame, requiredArrayType, Type.INT, type);\n                    break;\n                }\n                case ByteOps.POP2:\n                case ByteOps.DUP2: {\n                    ExecutionStack stack = frame.getStack();\n                    int pattern;\n\n                    if (stack.peekType(0).isCategory2()) {\n                        // \"form 2\" in vmspec-2\n                        machine.popArgs(frame, 1);\n                        pattern = 0x11;\n                    } else if (stack.peekType(1).isCategory1()) {\n                        // \"form 1\"\n                        machine.popArgs(frame, 2);\n                        pattern = 0x2121;\n                    } else {\n                        throw illegalTos();\n                    }\n\n                    if (opcode == ByteOps.DUP2) {\n                        machine.auxIntArg(pattern);\n                    }\n                    break;\n                }\n                case ByteOps.DUP: {\n                    Type peekType = frame.getStack().peekType(0);\n\n                    if (peekType.isCategory2()) {\n                        throw illegalTos();\n                    }\n\n                    machine.popArgs(frame, 1);\n                    machine.auxIntArg(0x11);\n                    break;\n                }\n                case ByteOps.DUP_X1: {\n                    ExecutionStack stack = frame.getStack();\n\n                    if (!(stack.peekType(0).isCategory1() &&\n                          stack.peekType(1).isCategory1())) {\n                        throw illegalTos();\n                    }\n\n                    machine.popArgs(frame, 2);\n                    machine.auxIntArg(0x212);\n                    break;\n                }\n                case ByteOps.DUP_X2: {\n                    ExecutionStack stack = frame.getStack();\n\n                    if (stack.peekType(0).isCategory2()) {\n                        throw illegalTos();\n                    }\n\n                    if (stack.peekType(1).isCategory2()) {\n                        // \"form 2\" in vmspec-2\n                        machine.popArgs(frame, 2);\n                        machine.auxIntArg(0x212);\n                    } else if (stack.peekType(2).isCategory1()) {\n                        // \"form 1\"\n                        machine.popArgs(frame, 3);\n                        machine.auxIntArg(0x3213);\n                    } else {\n                        throw illegalTos();\n                    }\n                    break;\n                }\n                case ByteOps.DUP2_X1: {\n                    ExecutionStack stack = frame.getStack();\n\n                    if (stack.peekType(0).isCategory2()) {\n                        // \"form 2\" in vmspec-2\n                        if (stack.peekType(2).isCategory2()) {\n                            throw illegalTos();\n                        }\n                        machine.popArgs(frame, 2);\n                        machine.auxIntArg(0x212);\n                    } else {\n                        // \"form 1\"\n                        if (stack.peekType(1).isCategory2() ||\n                            stack.peekType(2).isCategory2()) {\n                            throw illegalTos();\n                        }\n                        machine.popArgs(frame, 3);\n                        machine.auxIntArg(0x32132);\n                    }\n                    break;\n                }\n                case ByteOps.DUP2_X2: {\n                    ExecutionStack stack = frame.getStack();\n\n                    if (stack.peekType(0).isCategory2()) {\n                        if (stack.peekType(2).isCategory2()) {\n                            // \"form 4\" in vmspec-2\n                            machine.popArgs(frame, 2);\n                            machine.auxIntArg(0x212);\n                        } else if (stack.peekType(3).isCategory1()) {\n                            // \"form 2\"\n                            machine.popArgs(frame, 3);\n                            machine.auxIntArg(0x3213);\n                        } else {\n                            throw illegalTos();\n                        }\n                    } else if (stack.peekType(1).isCategory1()) {\n                        if (stack.peekType(2).isCategory2()) {\n                            // \"form 3\"\n                            machine.popArgs(frame, 3);\n                            machine.auxIntArg(0x32132);\n                        } else if (stack.peekType(3).isCategory1()) {\n                            // \"form 1\"\n                            machine.popArgs(frame, 4);\n                            machine.auxIntArg(0x432143);\n                        } else {\n                            throw illegalTos();\n                        }\n                    } else {\n                        throw illegalTos();\n                    }\n                    break;\n                }\n                case ByteOps.SWAP: {\n                    ExecutionStack stack = frame.getStack();\n\n                    if (!(stack.peekType(0).isCategory1() &&\n                          stack.peekType(1).isCategory1())) {\n                        throw illegalTos();\n                    }\n\n                    machine.popArgs(frame, 2);\n                    machine.auxIntArg(0x12);\n                    break;\n                }\n                default: {\n                    visitInvalid(opcode, offset, length);\n                    return;\n                }\n            }\n\n            machine.auxType(type);\n            machine.run(frame, offset, opcode);\n        }\n\n        /**\n         * Checks whether the prototype is compatible with returning the\n         * given type, and throws if not.\n         *\n         * @param encountered {@code non-null;} the encountered return type\n         */\n        private void checkReturnType(Type encountered) {\n            Type returnType = machine.getPrototype().getReturnType();\n\n            /*\n             * Check to see if the prototype's return type is\n             * possibly assignable from the type we encountered. This\n             * takes care of all the salient cases (types are the same,\n             * they're compatible primitive types, etc.).\n             */\n            if (!Merger.isPossiblyAssignableFrom(returnType, encountered)) {\n                throw new SimException(\"return type mismatch: prototype \" +\n                        \"indicates \" + returnType.toHuman() +\n                        \", but encountered type \" + encountered.toHuman());\n            }\n        }\n\n        /** {@inheritDoc} */\n        public void visitLocal(int opcode, int offset, int length,\n                int idx, Type type, int value) {\n            /*\n             * Note that the \"type\" parameter is always the simplest\n             * type based on the original opcode, e.g., \"int\" for\n             * \"iload\" (per se) and \"Object\" for \"aload\". So, when\n             * possible, we replace the type with the one indicated in\n             * the local variable table, though we still need to check\n             * to make sure it's valid for the opcode.\n             *\n             * The reason we use (offset + length) for the localOffset\n             * for a store is because it is only after the store that\n             * the local type becomes valid. On the other hand, the\n             * type associated with a load is valid at the start of\n             * the instruction.\n             */\n            int localOffset =\n                (opcode == ByteOps.ISTORE) ? (offset + length) : offset;\n            LocalVariableList.Item local =\n                localVariables.pcAndIndexToLocal(localOffset, idx);\n            Type localType;\n\n            if (local != null) {\n                localType = local.getType();\n                if (localType.getBasicFrameType() !=\n                        type.getBasicFrameType()) {\n                    BaseMachine.throwLocalMismatch(type, localType);\n                    return;\n                }\n            } else {\n                localType = type;\n            }\n\n            switch (opcode) {\n                case ByteOps.ILOAD:\n                case ByteOps.RET: {\n                    machine.localArg(frame, idx);\n                    machine.localInfo(local != null);\n                    machine.auxType(type);\n                    break;\n                }\n                case ByteOps.ISTORE: {\n                    LocalItem item\n                            = (local == null) ? null : local.getLocalItem();\n                    machine.popArgs(frame, type);\n                    machine.auxType(type);\n                    machine.localTarget(idx, localType, item);\n                    break;\n                }\n                case ByteOps.IINC: {\n                    LocalItem item\n                            = (local == null) ? null : local.getLocalItem();\n                    machine.localArg(frame, idx);\n                    machine.localTarget(idx, localType, item);\n                    machine.auxType(type);\n                    machine.auxIntArg(value);\n                    machine.auxCstArg(CstInteger.make(value));\n                    break;\n                }\n                default: {\n                    visitInvalid(opcode, offset, length);\n                    return;\n                }\n            }\n\n            machine.run(frame, offset, opcode);\n        }\n\n        /** {@inheritDoc} */\n        public void visitConstant(int opcode, int offset, int length,\n                Constant cst, int value) {\n            switch (opcode) {\n                case ByteOps.ANEWARRAY: {\n                    machine.popArgs(frame, Type.INT);\n                    break;\n                }\n                case ByteOps.PUTSTATIC: {\n                    Type fieldType = ((CstFieldRef) cst).getType();\n                    machine.popArgs(frame, fieldType);\n                    break;\n                }\n                case ByteOps.GETFIELD:\n                case ByteOps.CHECKCAST:\n                case ByteOps.INSTANCEOF: {\n                    machine.popArgs(frame, Type.OBJECT);\n                    break;\n                }\n                case ByteOps.PUTFIELD: {\n                    Type fieldType = ((CstFieldRef) cst).getType();\n                    machine.popArgs(frame, Type.OBJECT, fieldType);\n                    break;\n                }\n                case ByteOps.INVOKEINTERFACE: {\n                    /*\n                     * Convert the interface method ref into a normal\n                     * method ref.\n                     */\n                    cst = ((CstInterfaceMethodRef) cst).toMethodRef();\n                    // and fall through...\n                }\n                case ByteOps.INVOKEVIRTUAL:\n                case ByteOps.INVOKESPECIAL: {\n                    /*\n                     * Get the instance prototype, and use it to direct\n                     * the machine.\n                     */\n                    Prototype prototype =\n                        ((CstMethodRef) cst).getPrototype(false);\n                    machine.popArgs(frame, prototype);\n                    break;\n                }\n                case ByteOps.INVOKESTATIC: {\n                    /*\n                     * Get the static prototype, and use it to direct\n                     * the machine.\n                     */\n                    Prototype prototype =\n                        ((CstMethodRef) cst).getPrototype(true);\n                    machine.popArgs(frame, prototype);\n                    break;\n                }\n                case ByteOps.MULTIANEWARRAY: {\n                    /*\n                     * The \"value\" here is the count of dimensions to\n                     * create. Make a prototype of that many \"int\"\n                     * types, and tell the machine to pop them. This\n                     * isn't the most efficient way in the world to do\n                     * this, but then again, multianewarray is pretty\n                     * darn rare and so not worth much effort\n                     * optimizing for.\n                     */\n                    Prototype prototype =\n                        Prototype.internInts(Type.VOID, value);\n                    machine.popArgs(frame, prototype);\n                    break;\n                }\n                default: {\n                    machine.clearArgs();\n                    break;\n                }\n            }\n\n            machine.auxIntArg(value);\n            machine.auxCstArg(cst);\n            machine.run(frame, offset, opcode);\n        }\n\n        /** {@inheritDoc} */\n        public void visitBranch(int opcode, int offset, int length,\n                int target) {\n            switch (opcode) {\n                case ByteOps.IFEQ:\n                case ByteOps.IFNE:\n                case ByteOps.IFLT:\n                case ByteOps.IFGE:\n                case ByteOps.IFGT:\n                case ByteOps.IFLE: {\n                    machine.popArgs(frame, Type.INT);\n                    break;\n                }\n                case ByteOps.IFNULL:\n                case ByteOps.IFNONNULL: {\n                    machine.popArgs(frame, Type.OBJECT);\n                    break;\n                }\n                case ByteOps.IF_ICMPEQ:\n                case ByteOps.IF_ICMPNE:\n                case ByteOps.IF_ICMPLT:\n                case ByteOps.IF_ICMPGE:\n                case ByteOps.IF_ICMPGT:\n                case ByteOps.IF_ICMPLE: {\n                    machine.popArgs(frame, Type.INT, Type.INT);\n                    break;\n                }\n                case ByteOps.IF_ACMPEQ:\n                case ByteOps.IF_ACMPNE: {\n                    machine.popArgs(frame, Type.OBJECT, Type.OBJECT);\n                    break;\n                }\n                case ByteOps.GOTO:\n                case ByteOps.JSR:\n                case ByteOps.GOTO_W:\n                case ByteOps.JSR_W: {\n                    machine.clearArgs();\n                    break;\n                }\n                default: {\n                    visitInvalid(opcode, offset, length);\n                    return;\n                }\n            }\n\n            machine.auxTargetArg(target);\n            machine.run(frame, offset, opcode);\n        }\n\n        /** {@inheritDoc} */\n        public void visitSwitch(int opcode, int offset, int length,\n                SwitchList cases, int padding) {\n            machine.popArgs(frame, Type.INT);\n            machine.auxIntArg(padding);\n            machine.auxSwitchArg(cases);\n            machine.run(frame, offset, opcode);\n        }\n\n        /** {@inheritDoc} */\n        public void visitNewarray(int offset, int length, CstType type,\n                ArrayList<Constant> initValues) {\n            machine.popArgs(frame, Type.INT);\n            machine.auxInitValues(initValues);\n            machine.auxCstArg(type);\n            machine.run(frame, offset, ByteOps.NEWARRAY);\n        }\n\n        /** {@inheritDoc} */\n        public void setPreviousOffset(int offset) {\n            previousOffset = offset;\n        }\n\n        /** {@inheritDoc} */\n        public int getPreviousOffset() {\n            return previousOffset;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/SwitchList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.util.IntList;\nimport com.taobao.android.dx.util.MutabilityControl;\n\n/**\n * List of (value, target) mappings representing the choices of a\n * {@code tableswitch} or {@code lookupswitch} instruction. It\n * also holds the default target for the switch.\n */\npublic final class SwitchList extends MutabilityControl {\n    /** {@code non-null;} list of test values */\n    private final IntList values;\n\n    /**\n     * {@code non-null;} list of targets corresponding to the test values; there\n     * is always one extra element in the target list, to hold the\n     * default target\n     */\n    private final IntList targets;\n\n    /** ultimate size of the list */\n    private int size;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param size {@code >= 0;} the number of elements to be in the table\n     */\n    public SwitchList(int size) {\n        super(true);\n        this.values = new IntList(size);\n        this.targets = new IntList(size + 1);\n        this.size = size;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void setImmutable() {\n        values.setImmutable();\n        targets.setImmutable();\n        super.setImmutable();\n    }\n\n    /**\n     * Gets the size of the list.\n     *\n     * @return {@code >= 0;} the list size\n     */\n    public int size() {\n        return size;\n    }\n\n    /**\n     * Gets the indicated test value.\n     *\n     * @param n {@code >= 0;}, &lt; size(); which index\n     * @return the test value\n     */\n    public int getValue(int n) {\n        return values.get(n);\n    }\n\n    /**\n     * Gets the indicated target. Asking for the target at {@code size()}\n     * returns the default target.\n     *\n     * @param n {@code >= 0, <= size();} which index\n     * @return {@code >= 0;} the target\n     */\n    public int getTarget(int n) {\n        return targets.get(n);\n    }\n\n    /**\n     * Gets the default target. This is just a shorthand for\n     * {@code getTarget(size())}.\n     *\n     * @return {@code >= 0;} the default target\n     */\n    public int getDefaultTarget() {\n        return targets.get(size);\n    }\n\n    /**\n     * Gets the list of all targets. This includes one extra element at the\n     * end of the list, which holds the default target.\n     *\n     * @return {@code non-null;} the target list\n     */\n    public IntList getTargets() {\n        return targets;\n    }\n\n    /**\n     * Gets the list of all case values.\n     *\n     * @return {@code non-null;} the case value list\n     */\n    public IntList getValues() {\n        return values;\n    }\n\n    /**\n     * Sets the default target. It is only valid to call this method\n     * when all the non-default elements have been set.\n     *\n     * @param target {@code >= 0;} the absolute (not relative) default target\n     * address\n     */\n    public void setDefaultTarget(int target) {\n        throwIfImmutable();\n\n        if (target < 0) {\n            throw new IllegalArgumentException(\"target < 0\");\n        }\n\n        if (targets.size() != size) {\n            throw new RuntimeException(\"non-default elements not all set\");\n        }\n\n        targets.add(target);\n    }\n\n    /**\n     * Adds the given item.\n     *\n     * @param value the test value\n     * @param target {@code >= 0;} the absolute (not relative) target address\n     */\n    public void add(int value, int target) {\n        throwIfImmutable();\n\n        if (target < 0) {\n            throw new IllegalArgumentException(\"target < 0\");\n        }\n\n        values.add(value);\n        targets.add(target);\n    }\n\n    /**\n     * Shrinks this instance if possible, removing test elements that\n     * refer to the default target. This is only valid after the instance\n     * is fully populated, including the default target (naturally).\n     */\n    public void removeSuperfluousDefaults() {\n        throwIfImmutable();\n\n        int sz = size;\n\n        if (sz != (targets.size() - 1)) {\n            throw new IllegalArgumentException(\"incomplete instance\");\n        }\n\n        int defaultTarget = targets.get(sz);\n        int at = 0;\n\n        for (int i = 0; i < sz; i++) {\n            int target = targets.get(i);\n            if (target != defaultTarget) {\n                if (i != at) {\n                    targets.set(at, target);\n                    values.set(at, values.get(i));\n                }\n                at++;\n            }\n        }\n\n        if (at != sz) {\n            values.shrink(at);\n            targets.set(at, defaultTarget);\n            targets.shrink(at + 1);\n            size = at;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/ValueAwareMachine.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.code;\n\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Prototype;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * {@link Machine} which keeps track of known values but does not do\n * smart/realistic reference type calculations.\n */\npublic class ValueAwareMachine extends BaseMachine {\n    /**\n     * Constructs an instance.\n     *\n     * @param prototype {@code non-null;} the prototype for the associated\n     * method\n     */\n    public ValueAwareMachine(Prototype prototype) {\n        super(prototype);\n    }\n\n    /** {@inheritDoc} */\n    public void run(Frame frame, int offset, int opcode) {\n        switch (opcode) {\n            case ByteOps.NOP:\n            case ByteOps.IASTORE:\n            case ByteOps.POP:\n            case ByteOps.POP2:\n            case ByteOps.IFEQ:\n            case ByteOps.IFNE:\n            case ByteOps.IFLT:\n            case ByteOps.IFGE:\n            case ByteOps.IFGT:\n            case ByteOps.IFLE:\n            case ByteOps.IF_ICMPEQ:\n            case ByteOps.IF_ICMPNE:\n            case ByteOps.IF_ICMPLT:\n            case ByteOps.IF_ICMPGE:\n            case ByteOps.IF_ICMPGT:\n            case ByteOps.IF_ICMPLE:\n            case ByteOps.IF_ACMPEQ:\n            case ByteOps.IF_ACMPNE:\n            case ByteOps.GOTO:\n            case ByteOps.RET:\n            case ByteOps.LOOKUPSWITCH:\n            case ByteOps.IRETURN:\n            case ByteOps.RETURN:\n            case ByteOps.PUTSTATIC:\n            case ByteOps.PUTFIELD:\n            case ByteOps.ATHROW:\n            case ByteOps.MONITORENTER:\n            case ByteOps.MONITOREXIT:\n            case ByteOps.IFNULL:\n            case ByteOps.IFNONNULL: {\n                // Nothing to do for these ops in this class.\n                clearResult();\n                break;\n            }\n            case ByteOps.LDC:\n            case ByteOps.LDC2_W: {\n                setResult((TypeBearer) getAuxCst());\n                break;\n            }\n            case ByteOps.ILOAD:\n            case ByteOps.ISTORE: {\n                setResult(arg(0));\n                break;\n            }\n            case ByteOps.IALOAD:\n            case ByteOps.IADD:\n            case ByteOps.ISUB:\n            case ByteOps.IMUL:\n            case ByteOps.IDIV:\n            case ByteOps.IREM:\n            case ByteOps.INEG:\n            case ByteOps.ISHL:\n            case ByteOps.ISHR:\n            case ByteOps.IUSHR:\n            case ByteOps.IAND:\n            case ByteOps.IOR:\n            case ByteOps.IXOR:\n            case ByteOps.IINC:\n            case ByteOps.I2L:\n            case ByteOps.I2F:\n            case ByteOps.I2D:\n            case ByteOps.L2I:\n            case ByteOps.L2F:\n            case ByteOps.L2D:\n            case ByteOps.F2I:\n            case ByteOps.F2L:\n            case ByteOps.F2D:\n            case ByteOps.D2I:\n            case ByteOps.D2L:\n            case ByteOps.D2F:\n            case ByteOps.I2B:\n            case ByteOps.I2C:\n            case ByteOps.I2S:\n            case ByteOps.LCMP:\n            case ByteOps.FCMPL:\n            case ByteOps.FCMPG:\n            case ByteOps.DCMPL:\n            case ByteOps.DCMPG:\n            case ByteOps.ARRAYLENGTH: {\n                setResult(getAuxType());\n                break;\n            }\n            case ByteOps.DUP:\n            case ByteOps.DUP_X1:\n            case ByteOps.DUP_X2:\n            case ByteOps.DUP2:\n            case ByteOps.DUP2_X1:\n            case ByteOps.DUP2_X2:\n            case ByteOps.SWAP: {\n                clearResult();\n                for (int pattern = getAuxInt(); pattern != 0; pattern >>= 4) {\n                    int which = (pattern & 0x0f) - 1;\n                    addResult(arg(which));\n                }\n                break;\n            }\n\n            case ByteOps.JSR: {\n                setResult(new ReturnAddress(getAuxTarget()));\n                break;\n            }\n            case ByteOps.GETSTATIC:\n            case ByteOps.GETFIELD:\n            case ByteOps.INVOKEVIRTUAL:\n            case ByteOps.INVOKESTATIC:\n            case ByteOps.INVOKEINTERFACE: {\n                Type type = ((TypeBearer) getAuxCst()).getType();\n                if (type == Type.VOID) {\n                    clearResult();\n                } else {\n                    setResult(type);\n                }\n                break;\n            }\n            case ByteOps.INVOKESPECIAL: {\n                Type thisType = arg(0).getType();\n                if (thisType.isUninitialized()) {\n                    frame.makeInitialized(thisType);\n                }\n                Type type = ((TypeBearer) getAuxCst()).getType();\n                if (type == Type.VOID) {\n                    clearResult();\n                } else {\n                    setResult(type);\n                }\n                break;\n            }\n            case ByteOps.NEW: {\n                Type type = ((CstType) getAuxCst()).getClassType();\n                setResult(type.asUninitialized(offset));\n                break;\n            }\n            case ByteOps.NEWARRAY:\n            case ByteOps.CHECKCAST:\n            case ByteOps.MULTIANEWARRAY: {\n                Type type = ((CstType) getAuxCst()).getClassType();\n                setResult(type);\n                break;\n            }\n            case ByteOps.ANEWARRAY: {\n                Type type = ((CstType) getAuxCst()).getClassType();\n                setResult(type.getArrayType());\n                break;\n            }\n            case ByteOps.INSTANCEOF: {\n                setResult(Type.INT);\n                break;\n            }\n            default: {\n                throw new RuntimeException(\"shouldn't happen: \" +\n                                           Hex.u1(opcode));\n            }\n        }\n\n        storeResults(frame);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/code/package.html",
    "content": "<body>\n<p>Implementation of classes having to do with Java simulation, such as\nis needed for verification or stack-to-register conversion.</p>\n\n<p><b>PACKAGES USED:</b>\n<ul>\n<li><code>com.taobao.android.dx.rop.pool</code></li>\n<li><code>com.taobao.android.dx.util</code></li>\n</ul>\n</body>\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/cst/ConstantPoolParser.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.cst;\n\nimport static com.taobao.android.dx.cf.cst.ConstantTags.CONSTANT_Class;\nimport static com.taobao.android.dx.cf.cst.ConstantTags.CONSTANT_Double;\nimport static com.taobao.android.dx.cf.cst.ConstantTags.CONSTANT_Fieldref;\nimport static com.taobao.android.dx.cf.cst.ConstantTags.CONSTANT_Float;\nimport static com.taobao.android.dx.cf.cst.ConstantTags.CONSTANT_Integer;\nimport static com.taobao.android.dx.cf.cst.ConstantTags.CONSTANT_InterfaceMethodref;\nimport static com.taobao.android.dx.cf.cst.ConstantTags.CONSTANT_Long;\nimport static com.taobao.android.dx.cf.cst.ConstantTags.CONSTANT_Methodref;\nimport static com.taobao.android.dx.cf.cst.ConstantTags.CONSTANT_NameAndType;\nimport static com.taobao.android.dx.cf.cst.ConstantTags.CONSTANT_String;\nimport static com.taobao.android.dx.cf.cst.ConstantTags.CONSTANT_Utf8;\nimport static com.taobao.android.dx.cf.cst.ConstantTags.CONSTANT_MethodHandle;\nimport static com.taobao.android.dx.cf.cst.ConstantTags.CONSTANT_MethodType;\nimport static com.taobao.android.dx.cf.cst.ConstantTags.CONSTANT_InvokeDynamic;\nimport com.taobao.android.dx.cf.iface.ParseException;\nimport com.taobao.android.dx.cf.iface.ParseObserver;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstDouble;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.rop.cst.CstFloat;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.cst.CstInterfaceMethodRef;\nimport com.taobao.android.dx.rop.cst.CstLong;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.cst.StdConstantPool;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.BitSet;\n\n/**\n * Parser for a constant pool embedded in a class file.\n */\npublic final class ConstantPoolParser {\n    /** {@code non-null;} the bytes of the constant pool */\n    private final ByteArray bytes;\n\n    /** {@code non-null;} actual parsed constant pool contents */\n    private final StdConstantPool pool;\n\n    /** {@code non-null;} byte offsets to each cst */\n    private final int[] offsets;\n\n    /**\n     * -1 || &gt;= 10; the end offset of this constant pool in the\n     * {@code byte[]} which it came from or {@code -1} if not\n     * yet parsed\n     */\n    private int endOffset;\n\n    /** {@code null-ok;} parse observer, if any */\n    private ParseObserver observer;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param bytes {@code non-null;} the bytes of the file\n     */\n    public ConstantPoolParser(ByteArray bytes) {\n        int size = bytes.getUnsignedShort(8); // constant_pool_count\n\n        this.bytes = bytes;\n        this.pool = new StdConstantPool(size);\n        this.offsets = new int[size];\n        this.endOffset = -1;\n    }\n\n    /**\n     * Sets the parse observer for this instance.\n     *\n     * @param observer {@code null-ok;} the observer\n     */\n    public void setObserver(ParseObserver observer) {\n        this.observer = observer;\n    }\n\n    /**\n     * Gets the end offset of this constant pool in the {@code byte[]}\n     * which it came from.\n     *\n     * @return {@code >= 10;} the end offset\n     */\n    public int getEndOffset() {\n        parseIfNecessary();\n        return endOffset;\n    }\n\n    /**\n     * Gets the actual constant pool.\n     *\n     * @return {@code non-null;} the constant pool\n     */\n    public StdConstantPool getPool() {\n        parseIfNecessary();\n        return pool;\n    }\n\n    /**\n     * Runs {@link #parse} if it has not yet been run successfully.\n     */\n    private void parseIfNecessary() {\n        if (endOffset < 0) {\n            parse();\n        }\n    }\n\n    /**\n     * Does the actual parsing.\n     */\n    private void parse() {\n        determineOffsets();\n\n        if (observer != null) {\n            observer.parsed(bytes, 8, 2,\n                            \"constant_pool_count: \" + Hex.u2(offsets.length));\n            observer.parsed(bytes, 10, 0, \"\\nconstant_pool:\");\n            observer.changeIndent(1);\n        }\n\n        /*\n         * Track the constant value's original string type. True if constants[i] was\n         * a CONSTANT_Utf8, false for any other type including CONSTANT_string.\n         */\n        BitSet wasUtf8 = new BitSet(offsets.length);\n\n        for (int i = 1; i < offsets.length; i++) {\n            int offset = offsets[i];\n            if ((offset != 0) && (pool.getOrNull(i) == null)) {\n                parse0(i, wasUtf8);\n            }\n        }\n\n        if (observer != null) {\n            for (int i = 1; i < offsets.length; i++) {\n                Constant cst = pool.getOrNull(i);\n                if (cst == null) {\n                    continue;\n                }\n                int offset = offsets[i];\n                int nextOffset = endOffset;\n                for (int j = i + 1; j < offsets.length; j++) {\n                    int off = offsets[j];\n                    if (off != 0) {\n                        nextOffset = off;\n                        break;\n                    }\n                }\n                String human = wasUtf8.get(i)\n                        ? Hex.u2(i) + \": utf8{\\\"\" + cst.toHuman() + \"\\\"}\"\n                        : Hex.u2(i) + \": \" + cst.toString();\n                observer.parsed(bytes, offset, nextOffset - offset, human);\n            }\n\n            observer.changeIndent(-1);\n            observer.parsed(bytes, endOffset, 0, \"end constant_pool\");\n        }\n    }\n\n    /**\n     * Populates {@link #offsets} and also completely parse utf8 constants.\n     */\n    private void determineOffsets() {\n        int at = 10; // offset from the start of the file to the first cst\n        int lastCategory;\n\n        for (int i = 1; i < offsets.length; i += lastCategory) {\n            offsets[i] = at;\n            int tag = bytes.getUnsignedByte(at);\n            try {\n                switch (tag) {\n                    case CONSTANT_Integer:\n                    case CONSTANT_Float:\n                    case CONSTANT_Fieldref:\n                    case CONSTANT_Methodref:\n                    case CONSTANT_InterfaceMethodref:\n                    case CONSTANT_NameAndType: {\n                        lastCategory = 1;\n                        at += 5;\n                        break;\n                    }\n                    case CONSTANT_Long:\n                    case CONSTANT_Double: {\n                        lastCategory = 2;\n                        at += 9;\n                        break;\n                    }\n                    case CONSTANT_Class:\n                    case CONSTANT_String: {\n                        lastCategory = 1;\n                        at += 3;\n                        break;\n                    }\n                    case CONSTANT_Utf8: {\n                        lastCategory = 1;\n                        at += bytes.getUnsignedShort(at + 1) + 3;\n                        break;\n                    }\n                    case CONSTANT_MethodHandle: {\n                        throw new ParseException(\"MethodHandle not supported\");\n                    }\n                    case CONSTANT_MethodType: {\n                        throw new ParseException(\"MethodType not supported\");\n                    }\n                    case CONSTANT_InvokeDynamic: {\n                        throw new ParseException(\"InvokeDynamic not supported\");\n                    }\n                    default: {\n                        throw new ParseException(\"unknown tag byte: \" + Hex.u1(tag));\n                    }\n                }\n            } catch (ParseException ex) {\n                ex.addContext(\"...while preparsing cst \" + Hex.u2(i) + \" at offset \" + Hex.u4(at));\n                throw ex;\n            }\n        }\n\n        endOffset = at;\n    }\n\n    /**\n     * Parses the constant for the given index if it hasn't already been\n     * parsed, also storing it in the constant pool. This will also\n     * have the side effect of parsing any entries the indicated one\n     * depends on.\n     *\n     * @param idx which constant\n     * @return {@code non-null;} the parsed constant\n     */\n    private Constant parse0(int idx, BitSet wasUtf8) {\n        Constant cst = pool.getOrNull(idx);\n        if (cst != null) {\n            return cst;\n        }\n\n        int at = offsets[idx];\n\n        try {\n            int tag = bytes.getUnsignedByte(at);\n            switch (tag) {\n                case CONSTANT_Utf8: {\n                    cst = parseUtf8(at);\n                    wasUtf8.set(idx);\n                    break;\n                }\n                case CONSTANT_Integer: {\n                    int value = bytes.getInt(at + 1);\n                    cst = CstInteger.make(value);\n                    break;\n                }\n                case CONSTANT_Float: {\n                    int bits = bytes.getInt(at + 1);\n                    cst = CstFloat.make(bits);\n                    break;\n                }\n                case CONSTANT_Long: {\n                    long value = bytes.getLong(at + 1);\n                    cst = CstLong.make(value);\n                    break;\n                }\n                case CONSTANT_Double: {\n                    long bits = bytes.getLong(at + 1);\n                    cst = CstDouble.make(bits);\n                    break;\n                }\n                case CONSTANT_Class: {\n                    int nameIndex = bytes.getUnsignedShort(at + 1);\n                    CstString name = (CstString) parse0(nameIndex, wasUtf8);\n                    cst = new CstType(Type.internClassName(name.getString()));\n                    break;\n                }\n                case CONSTANT_String: {\n                    int stringIndex = bytes.getUnsignedShort(at + 1);\n                    cst = parse0(stringIndex, wasUtf8);\n                    break;\n                }\n                case CONSTANT_Fieldref: {\n                    int classIndex = bytes.getUnsignedShort(at + 1);\n                    CstType type = (CstType) parse0(classIndex, wasUtf8);\n                    int natIndex = bytes.getUnsignedShort(at + 3);\n                    CstNat nat = (CstNat) parse0(natIndex, wasUtf8);\n                    cst = new CstFieldRef(type, nat);\n                    break;\n                }\n                case CONSTANT_Methodref: {\n                    int classIndex = bytes.getUnsignedShort(at + 1);\n                    CstType type = (CstType) parse0(classIndex, wasUtf8);\n                    int natIndex = bytes.getUnsignedShort(at + 3);\n                    CstNat nat = (CstNat) parse0(natIndex, wasUtf8);\n                    cst = new CstMethodRef(type, nat);\n                    break;\n                }\n                case CONSTANT_InterfaceMethodref: {\n                    int classIndex = bytes.getUnsignedShort(at + 1);\n                    CstType type = (CstType) parse0(classIndex, wasUtf8);\n                    int natIndex = bytes.getUnsignedShort(at + 3);\n                    CstNat nat = (CstNat) parse0(natIndex, wasUtf8);\n                    cst = new CstInterfaceMethodRef(type, nat);\n                    break;\n                }\n                case CONSTANT_NameAndType: {\n                    int nameIndex = bytes.getUnsignedShort(at + 1);\n                    CstString name = (CstString) parse0(nameIndex, wasUtf8);\n                    int descriptorIndex = bytes.getUnsignedShort(at + 3);\n                    CstString descriptor = (CstString) parse0(descriptorIndex, wasUtf8);\n                    cst = new CstNat(name, descriptor);\n                    break;\n                }\n                case CONSTANT_MethodHandle: {\n                    throw new ParseException(\"MethodHandle not supported\");\n                }\n                case CONSTANT_MethodType: {\n                    throw new ParseException(\"MethodType not supported\");\n                }\n                case CONSTANT_InvokeDynamic: {\n                    throw new ParseException(\"InvokeDynamic not supported\");\n                }\n                default: {\n                    throw new ParseException(\"unknown tag byte: \" + Hex.u1(tag));\n                }\n            }\n        } catch (ParseException ex) {\n            ex.addContext(\"...while parsing cst \" + Hex.u2(idx) +\n                          \" at offset \" + Hex.u4(at));\n            throw ex;\n        } catch (RuntimeException ex) {\n            ParseException pe = new ParseException(ex);\n            pe.addContext(\"...while parsing cst \" + Hex.u2(idx) +\n                          \" at offset \" + Hex.u4(at));\n            throw pe;\n        }\n\n        pool.set(idx, cst);\n        return cst;\n    }\n\n    /**\n     * Parses a utf8 constant.\n     *\n     * @param at offset to the start of the constant (where the tag byte is)\n     * @return {@code non-null;} the parsed value\n     */\n    private CstString parseUtf8(int at) {\n        int length = bytes.getUnsignedShort(at + 1);\n\n        at += 3; // Skip to the data.\n\n        ByteArray ubytes = bytes.slice(at, at + length);\n\n        try {\n            return new CstString(ubytes);\n        } catch (IllegalArgumentException ex) {\n            // Translate the exception\n            throw new ParseException(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/cst/ConstantTags.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.cst;\n\n/**\n * Tags for constant pool constants.\n */\npublic interface ConstantTags {\n    /** tag for a {@code CONSTANT_Utf8_info} */\n    int CONSTANT_Utf8 = 1;\n\n    /** tag for a {@code CONSTANT_Integer_info} */\n    int CONSTANT_Integer = 3;\n\n    /** tag for a {@code CONSTANT_Float_info} */\n    int CONSTANT_Float = 4;\n\n    /** tag for a {@code CONSTANT_Long_info} */\n    int CONSTANT_Long = 5;\n\n    /** tag for a {@code CONSTANT_Double_info} */\n    int CONSTANT_Double = 6;\n\n    /** tag for a {@code CONSTANT_Class_info} */\n    int CONSTANT_Class = 7;\n\n    /** tag for a {@code CONSTANT_String_info} */\n    int CONSTANT_String = 8;\n\n    /** tag for a {@code CONSTANT_Fieldref_info} */\n    int CONSTANT_Fieldref = 9;\n\n    /** tag for a {@code CONSTANT_Methodref_info} */\n    int CONSTANT_Methodref = 10;\n\n    /** tag for a {@code CONSTANT_InterfaceMethodref_info} */\n    int CONSTANT_InterfaceMethodref = 11;\n\n    /** tag for a {@code CONSTANT_NameAndType_info} */\n    int CONSTANT_NameAndType = 12;\n\n    /** tag for a {@code CONSTANT_MethodHandle} */\n    int CONSTANT_MethodHandle = 15;\n\n    /** tag for a {@code CONSTANT_MethodType} */\n    int CONSTANT_MethodType = 16;\n\n    /** tag for a {@code CONSTANT_InvokeDynamic} */\n    int CONSTANT_InvokeDynamic = 18;\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/direct/AnnotationParser.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.direct;\n\nimport com.taobao.android.dx.cf.iface.ParseException;\nimport com.taobao.android.dx.cf.iface.ParseObserver;\nimport com.taobao.android.dx.rop.annotation.Annotation;\nimport com.taobao.android.dx.rop.annotation.AnnotationVisibility;\nimport com.taobao.android.dx.rop.annotation.Annotations;\nimport com.taobao.android.dx.rop.annotation.AnnotationsList;\nimport com.taobao.android.dx.rop.annotation.NameValuePair;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.ConstantPool;\nimport com.taobao.android.dx.rop.cst.CstAnnotation;\nimport com.taobao.android.dx.rop.cst.CstArray;\nimport com.taobao.android.dx.rop.cst.CstBoolean;\nimport com.taobao.android.dx.rop.cst.CstByte;\nimport com.taobao.android.dx.rop.cst.CstChar;\nimport com.taobao.android.dx.rop.cst.CstDouble;\nimport com.taobao.android.dx.rop.cst.CstEnumRef;\nimport com.taobao.android.dx.rop.cst.CstFloat;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.cst.CstLong;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstShort;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\nimport java.io.IOException;\n\n/**\n * Parser for annotations.\n */\npublic final class AnnotationParser {\n    /** {@code non-null;} class file being parsed */\n    private final DirectClassFile cf;\n\n    /** {@code non-null;} constant pool to use */\n    private final ConstantPool pool;\n\n    /** {@code non-null;} bytes of the attribute data */\n    private final ByteArray bytes;\n\n    /** {@code null-ok;} parse observer, if any */\n    private final ParseObserver observer;\n\n    /** {@code non-null;} input stream to parse from */\n    private final ByteArray.MyDataInputStream input;\n\n    /**\n     * {@code non-null;} cursor for use when informing the observer of what\n     * was parsed\n     */\n    private int parseCursor;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param cf {@code non-null;} class file to parse from\n     * @param offset {@code >= 0;} offset into the class file data to parse at\n     * @param length {@code >= 0;} number of bytes left in the attribute data\n     * @param observer {@code null-ok;} parse observer to notify, if any\n     */\n    public AnnotationParser(DirectClassFile cf, int offset, int length,\n            ParseObserver observer) {\n        if (cf == null) {\n            throw new NullPointerException(\"cf == null\");\n        }\n\n        this.cf = cf;\n        this.pool = cf.getConstantPool();\n        this.observer = observer;\n        this.bytes = cf.getBytes().slice(offset, offset + length);\n        this.input = bytes.makeDataInputStream();\n        this.parseCursor = 0;\n    }\n\n    /**\n     * Parses an annotation value ({@code element_value}) attribute.\n     *\n     * @return {@code non-null;} the parsed constant value\n     */\n    public Constant parseValueAttribute() {\n        Constant result;\n\n        try {\n            result = parseValue();\n\n            if (input.available() != 0) {\n                throw new ParseException(\"extra data in attribute\");\n            }\n        } catch (IOException ex) {\n            // ByteArray.MyDataInputStream should never throw.\n            throw new RuntimeException(\"shouldn't happen\", ex);\n        }\n\n        return result;\n    }\n\n    /**\n     * Parses a parameter annotation attribute.\n     *\n     * @param visibility {@code non-null;} visibility of the parsed annotations\n     * @return {@code non-null;} the parsed list of lists of annotations\n     */\n    public AnnotationsList parseParameterAttribute(\n            AnnotationVisibility visibility) {\n        AnnotationsList result;\n\n        try {\n            result = parseAnnotationsList(visibility);\n\n            if (input.available() != 0) {\n                throw new ParseException(\"extra data in attribute\");\n            }\n        } catch (IOException ex) {\n            // ByteArray.MyDataInputStream should never throw.\n            throw new RuntimeException(\"shouldn't happen\", ex);\n        }\n\n        return result;\n    }\n\n    /**\n     * Parses an annotation attribute, per se.\n     *\n     * @param visibility {@code non-null;} visibility of the parsed annotations\n     * @return {@code non-null;} the list of annotations read from the attribute\n     * data\n     */\n    public Annotations parseAnnotationAttribute(\n            AnnotationVisibility visibility) {\n        Annotations result;\n\n        try {\n            result = parseAnnotations(visibility);\n\n            if (input.available() != 0) {\n                throw new ParseException(\"extra data in attribute\");\n            }\n        } catch (IOException ex) {\n            // ByteArray.MyDataInputStream should never throw.\n            throw new RuntimeException(\"shouldn't happen\", ex);\n        }\n\n        return result;\n    }\n\n    /**\n     * Parses a list of annotation lists.\n     *\n     * @param visibility {@code non-null;} visibility of the parsed annotations\n     * @return {@code non-null;} the list of annotation lists read from the attribute\n     * data\n     */\n    private AnnotationsList parseAnnotationsList(\n            AnnotationVisibility visibility) throws IOException {\n        int count = input.readUnsignedByte();\n\n        if (observer != null) {\n            parsed(1, \"num_parameters: \" + Hex.u1(count));\n        }\n\n        AnnotationsList outerList = new AnnotationsList(count);\n\n        for (int i = 0; i < count; i++) {\n            if (observer != null) {\n                parsed(0, \"parameter_annotations[\" + i + \"]:\");\n                changeIndent(1);\n            }\n\n            Annotations annotations = parseAnnotations(visibility);\n            outerList.set(i, annotations);\n\n            if (observer != null) {\n                observer.changeIndent(-1);\n            }\n        }\n\n        outerList.setImmutable();\n        return outerList;\n    }\n\n    /**\n     * Parses an annotation list.\n     *\n     * @param visibility {@code non-null;} visibility of the parsed annotations\n     * @return {@code non-null;} the list of annotations read from the attribute\n     * data\n     */\n    private Annotations parseAnnotations(AnnotationVisibility visibility)\n            throws IOException {\n        int count = input.readUnsignedShort();\n\n        if (observer != null) {\n            parsed(2, \"num_annotations: \" + Hex.u2(count));\n        }\n\n        Annotations annotations = new Annotations();\n\n        for (int i = 0; i < count; i++) {\n            if (observer != null) {\n                parsed(0, \"annotations[\" + i + \"]:\");\n                changeIndent(1);\n            }\n\n            Annotation annotation = parseAnnotation(visibility);\n            annotations.add(annotation);\n\n            if (observer != null) {\n                observer.changeIndent(-1);\n            }\n        }\n\n        annotations.setImmutable();\n        return annotations;\n    }\n\n    /**\n     * Parses a single annotation.\n     *\n     * @param visibility {@code non-null;} visibility of the parsed annotation\n     * @return {@code non-null;} the parsed annotation\n     */\n    private Annotation parseAnnotation(AnnotationVisibility visibility)\n            throws IOException {\n        requireLength(4);\n\n        int typeIndex = input.readUnsignedShort();\n        int numElements = input.readUnsignedShort();\n        CstString typeString = (CstString) pool.get(typeIndex);\n        CstType type = new CstType(Type.intern(typeString.getString()));\n\n        if (observer != null) {\n            parsed(2, \"type: \" + type.toHuman());\n            parsed(2, \"num_elements: \" + numElements);\n        }\n\n        Annotation annotation = new Annotation(type, visibility);\n\n        for (int i = 0; i < numElements; i++) {\n            if (observer != null) {\n                parsed(0, \"elements[\" + i + \"]:\");\n                changeIndent(1);\n            }\n\n            NameValuePair element = parseElement();\n            annotation.add(element);\n\n            if (observer != null) {\n                changeIndent(-1);\n            }\n        }\n\n        annotation.setImmutable();\n        return annotation;\n    }\n\n    /**\n     * Parses a {@link NameValuePair}.\n     *\n     * @return {@code non-null;} the parsed element\n     */\n    private NameValuePair parseElement() throws IOException {\n        requireLength(5);\n\n        int elementNameIndex = input.readUnsignedShort();\n        CstString elementName = (CstString) pool.get(elementNameIndex);\n\n        if (observer != null) {\n            parsed(2, \"element_name: \" + elementName.toHuman());\n            parsed(0, \"value: \");\n            changeIndent(1);\n        }\n\n        Constant value = parseValue();\n\n        if (observer != null) {\n            changeIndent(-1);\n        }\n\n        return new NameValuePair(elementName, value);\n    }\n\n    /**\n     * Parses an annotation value.\n     *\n     * @return {@code non-null;} the parsed value\n     */\n    private Constant parseValue() throws IOException {\n        int tag = input.readUnsignedByte();\n\n        if (observer != null) {\n            CstString humanTag = new CstString(Character.toString((char) tag));\n            parsed(1, \"tag: \" + humanTag.toQuoted());\n        }\n\n        switch (tag) {\n            case 'B': {\n                CstInteger value = (CstInteger) parseConstant();\n                return CstByte.make(value.getValue());\n            }\n            case 'C': {\n                CstInteger value = (CstInteger) parseConstant();\n                int intValue = value.getValue();\n                return CstChar.make(value.getValue());\n            }\n            case 'D': {\n                CstDouble value = (CstDouble) parseConstant();\n                return value;\n            }\n            case 'F': {\n                CstFloat value = (CstFloat) parseConstant();\n                return value;\n            }\n            case 'I': {\n                CstInteger value = (CstInteger) parseConstant();\n                return value;\n            }\n            case 'J': {\n                CstLong value = (CstLong) parseConstant();\n                return value;\n            }\n            case 'S': {\n                CstInteger value = (CstInteger) parseConstant();\n                return CstShort.make(value.getValue());\n            }\n            case 'Z': {\n                CstInteger value = (CstInteger) parseConstant();\n                return CstBoolean.make(value.getValue());\n            }\n            case 'c': {\n                int classInfoIndex = input.readUnsignedShort();\n                CstString value = (CstString) pool.get(classInfoIndex);\n                Type type = Type.internReturnType(value.getString());\n\n                if (observer != null) {\n                    parsed(2, \"class_info: \" + type.toHuman());\n                }\n\n                return new CstType(type);\n            }\n            case 's': {\n                return parseConstant();\n            }\n            case 'e': {\n                requireLength(4);\n\n                int typeNameIndex = input.readUnsignedShort();\n                int constNameIndex = input.readUnsignedShort();\n                CstString typeName = (CstString) pool.get(typeNameIndex);\n                CstString constName = (CstString) pool.get(constNameIndex);\n\n                if (observer != null) {\n                    parsed(2, \"type_name: \" + typeName.toHuman());\n                    parsed(2, \"const_name: \" + constName.toHuman());\n                }\n\n                return new CstEnumRef(new CstNat(constName, typeName));\n            }\n            case '@': {\n                Annotation annotation =\n                    parseAnnotation(AnnotationVisibility.EMBEDDED);\n                return new CstAnnotation(annotation);\n            }\n            case '[': {\n                requireLength(2);\n\n                int numValues = input.readUnsignedShort();\n                CstArray.List list = new CstArray.List(numValues);\n\n                if (observer != null) {\n                    parsed(2, \"num_values: \" + numValues);\n                    changeIndent(1);\n                }\n\n                for (int i = 0; i < numValues; i++) {\n                    if (observer != null) {\n                        changeIndent(-1);\n                        parsed(0, \"element_value[\" + i + \"]:\");\n                        changeIndent(1);\n                    }\n                    list.set(i, parseValue());\n                }\n\n                if (observer != null) {\n                    changeIndent(-1);\n                }\n\n                list.setImmutable();\n                return new CstArray(list);\n            }\n            default: {\n                throw new ParseException(\"unknown annotation tag: \" +\n                        Hex.u1(tag));\n            }\n        }\n    }\n\n    /**\n     * Helper for {@link #parseValue}, which parses a constant reference\n     * and returns the referred-to constant value.\n     *\n     * @return {@code non-null;} the parsed value\n     */\n    private Constant parseConstant() throws IOException {\n        int constValueIndex = input.readUnsignedShort();\n        Constant value = (Constant) pool.get(constValueIndex);\n\n        if (observer != null) {\n            String human = (value instanceof CstString)\n                ? ((CstString) value).toQuoted()\n                : value.toHuman();\n            parsed(2, \"constant_value: \" + human);\n        }\n\n        return value;\n    }\n\n    /**\n     * Helper which will throw an exception if the given number of bytes\n     * is not available to be read.\n     *\n     * @param requiredLength the number of required bytes\n     */\n    private void requireLength(int requiredLength) throws IOException {\n        if (input.available() < requiredLength) {\n            throw new ParseException(\"truncated annotation attribute\");\n        }\n    }\n\n    /**\n     * Helper which indicates that some bytes were just parsed. This should\n     * only be used (for efficiency sake) if the parse is known to be\n     * observed.\n     *\n     * @param length {@code >= 0;} number of bytes parsed\n     * @param message {@code non-null;} associated message\n     */\n    private void parsed(int length, String message) {\n        observer.parsed(bytes, parseCursor, length, message);\n        parseCursor += length;\n    }\n\n    /**\n     * Convenience wrapper that simply calls through to\n     * {@code observer.changeIndent()}.\n     *\n     * @param indent the amount to change the indent by\n     */\n    private void changeIndent(int indent) {\n        observer.changeIndent(indent);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/direct/AttributeFactory.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.direct;\n\nimport com.taobao.android.dx.cf.attrib.RawAttribute;\nimport com.taobao.android.dx.cf.iface.Attribute;\nimport com.taobao.android.dx.cf.iface.ParseException;\nimport com.taobao.android.dx.cf.iface.ParseObserver;\nimport com.taobao.android.dx.rop.cst.ConstantPool;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Factory capable of instantiating various {@link Attribute} subclasses\n * depending on the context and name.\n */\npublic class AttributeFactory {\n    /** context for attributes on class files */\n    public static final int CTX_CLASS = 0;\n\n    /** context for attributes on fields */\n    public static final int CTX_FIELD = 1;\n\n    /** context for attributes on methods */\n    public static final int CTX_METHOD = 2;\n\n    /** context for attributes on code attributes */\n    public static final int CTX_CODE = 3;\n\n    /** number of contexts */\n    public static final int CTX_COUNT = 4;\n\n    /**\n     * Constructs an instance.\n     */\n    public AttributeFactory() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Parses and makes an attribute based on the bytes at the\n     * indicated position in the given array. This method figures out\n     * the name, and then does all the setup to call on to {@link #parse0},\n     * which does the actual construction.\n     *\n     * @param cf {@code non-null;} class file to parse from\n     * @param context context to parse in; one of the {@code CTX_*}\n     * constants\n     * @param offset offset into {@code dcf}'s {@code bytes}\n     * to start parsing at\n     * @param observer {@code null-ok;} parse observer to report to, if any\n     * @return {@code non-null;} an appropriately-constructed {@link Attribute}\n     */\n    public final Attribute parse(DirectClassFile cf, int context, int offset,\n                                 ParseObserver observer) {\n        if (cf == null) {\n            throw new NullPointerException(\"cf == null\");\n        }\n\n        if ((context < 0) || (context >= CTX_COUNT)) {\n            throw new IllegalArgumentException(\"bad context\");\n        }\n\n        CstString name = null;\n\n        try {\n            ByteArray bytes = cf.getBytes();\n            ConstantPool pool = cf.getConstantPool();\n            int nameIdx = bytes.getUnsignedShort(offset);\n            int length = bytes.getInt(offset + 2);\n\n            name = (CstString) pool.get(nameIdx);\n\n            if (observer != null) {\n                observer.parsed(bytes, offset, 2,\n                                \"name: \" + name.toHuman());\n                observer.parsed(bytes, offset + 2, 4,\n                                \"length: \" + Hex.u4(length));\n            }\n\n            return parse0(cf, context, name.getString(), offset + 6, length,\n                          observer);\n        } catch (ParseException ex) {\n            ex.addContext(\"...while parsing \" +\n                    ((name != null) ? (name.toHuman() + \" \") : \"\") +\n                    \"attribute at offset \" + Hex.u4(offset));\n            throw ex;\n        }\n    }\n\n    /**\n     * Parses attribute content. The base class implements this by constructing\n     * an instance of {@link RawAttribute}. Subclasses are expected to\n     * override this to do something better in most cases.\n     *\n     * @param cf {@code non-null;} class file to parse from\n     * @param context context to parse in; one of the {@code CTX_*}\n     * constants\n     * @param name {@code non-null;} the attribute name\n     * @param offset offset into {@code bytes} to start parsing at; this\n     * is the offset to the start of attribute data, not to the header\n     * @param length the length of the attribute data\n     * @param observer {@code null-ok;} parse observer to report to, if any\n     * @return {@code non-null;} an appropriately-constructed {@link Attribute}\n     */\n    protected Attribute parse0(DirectClassFile cf, int context, String name,\n                               int offset, int length,\n                               ParseObserver observer) {\n        ByteArray bytes = cf.getBytes();\n        ConstantPool pool = cf.getConstantPool();\n        Attribute result = new RawAttribute(name, bytes, offset, length, pool);\n\n        if (observer != null) {\n            observer.parsed(bytes, offset, length, \"attribute data\");\n        }\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/direct/AttributeListParser.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.direct;\n\nimport com.taobao.android.dx.cf.iface.Attribute;\nimport com.taobao.android.dx.cf.iface.ParseException;\nimport com.taobao.android.dx.cf.iface.ParseObserver;\nimport com.taobao.android.dx.cf.iface.StdAttributeList;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Parser for lists of attributes.\n */\nfinal /*package*/ class AttributeListParser {\n    /** {@code non-null;} the class file to parse from */\n    private final DirectClassFile cf;\n\n    /** attribute parsing context */\n    private final int context;\n\n    /** offset in the byte array of the classfile to the start of the list */\n    private final int offset;\n\n    /** {@code non-null;} attribute factory to use */\n    private final AttributeFactory attributeFactory;\n\n    /** {@code non-null;} list of parsed attributes */\n    private final StdAttributeList list;\n\n    /** {@code >= -1;} the end offset of this list in the byte array of the\n     * classfile, or {@code -1} if not yet parsed */\n    private int endOffset;\n\n    /** {@code null-ok;} parse observer, if any */\n    private ParseObserver observer;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param cf {@code non-null;} class file to parse from\n     * @param context attribute parsing context (see {@link AttributeFactory})\n     * @param offset offset in {@code bytes} to the start of the list\n     * @param attributeFactory {@code non-null;} attribute factory to use\n     */\n    public AttributeListParser(DirectClassFile cf, int context, int offset,\n                               AttributeFactory attributeFactory) {\n        if (cf == null) {\n            throw new NullPointerException(\"cf == null\");\n        }\n\n        if (attributeFactory == null) {\n            throw new NullPointerException(\"attributeFactory == null\");\n        }\n\n        int size = cf.getBytes().getUnsignedShort(offset);\n\n        this.cf = cf;\n        this.context = context;\n        this.offset = offset;\n        this.attributeFactory = attributeFactory;\n        this.list = new StdAttributeList(size);\n        this.endOffset = -1;\n    }\n\n    /**\n     * Sets the parse observer for this instance.\n     *\n     * @param observer {@code null-ok;} the observer\n     */\n    public void setObserver(ParseObserver observer) {\n        this.observer = observer;\n    }\n\n    /**\n     * Gets the end offset of this constant pool in the {@code byte[]}\n     * which it came from.\n     *\n     * @return {@code >= 0;} the end offset\n     */\n    public int getEndOffset() {\n        parseIfNecessary();\n        return endOffset;\n    }\n\n    /**\n     * Gets the parsed list.\n     *\n     * @return {@code non-null;} the list\n     */\n    public StdAttributeList getList() {\n        parseIfNecessary();\n        return list;\n    }\n\n    /**\n     * Runs {@link #parse} if it has not yet been run successfully.\n     */\n    private void parseIfNecessary() {\n        if (endOffset < 0) {\n            parse();\n        }\n    }\n\n    /**\n     * Does the actual parsing.\n     */\n    private void parse() {\n        int sz = list.size();\n        int at = offset + 2; // Skip the count.\n\n        ByteArray bytes = cf.getBytes();\n\n        if (observer != null) {\n            observer.parsed(bytes, offset, 2,\n                            \"attributes_count: \" + Hex.u2(sz));\n        }\n\n        for (int i = 0; i < sz; i++) {\n            try {\n                if (observer != null) {\n                    observer.parsed(bytes, at, 0,\n                                    \"\\nattributes[\" + i + \"]:\\n\");\n                    observer.changeIndent(1);\n                }\n\n                Attribute attrib =\n                    attributeFactory.parse(cf, context, at, observer);\n\n                at += attrib.byteLength();\n                list.set(i, attrib);\n\n                if (observer != null) {\n                    observer.changeIndent(-1);\n                    observer.parsed(bytes, at, 0,\n                                    \"end attributes[\" + i + \"]\\n\");\n                }\n            } catch (ParseException ex) {\n                ex.addContext(\"...while parsing attributes[\" + i + \"]\");\n                throw ex;\n            } catch (RuntimeException ex) {\n                ParseException pe = new ParseException(ex);\n                pe.addContext(\"...while parsing attributes[\" + i + \"]\");\n                throw pe;\n            }\n        }\n\n        endOffset = at;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/direct/ClassPathOpener.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.direct;\n\nimport com.taobao.android.dex.util.FileUtils;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n/**\n * Opens all the class files found in a class path element. Path elements\n * can point to class files, {jar,zip,apk} files, or directories containing\n * class files.\n */\npublic class ClassPathOpener {\n\n    /** {@code non-null;} pathname to start with */\n    private final String pathname;\n    /** {@code non-null;} callback interface */\n    private final Consumer consumer;\n    /**\n     * If true, sort such that classes appear before their inner\n     * classes and \"package-info\" occurs before all other classes in that\n     * package.\n     */\n    private final boolean sort;\n    private FileNameFilter filter;\n\n    /**\n     * Callback interface for {@code ClassOpener}.\n     */\n    public interface Consumer {\n\n        /**\n         * Provides the file name and byte array for a class path element.\n         *\n         * @param name {@code non-null;} filename of element. May not be a valid\n         * filesystem path.\n         *\n         * @param lastModified milliseconds since 1970-Jan-1 00:00:00 GMT\n         * @param bytes {@code non-null;} file data\n         * @return true on success. Result is or'd with all other results\n         * from {@code processFileBytes} and returned to the caller\n         * of {@code process()}.\n         */\n        boolean processFileBytes(String name, long lastModified, byte[] bytes);\n\n        /**\n         * Informs consumer that an exception occurred while processing\n         * this path element. Processing will continue if possible.\n         *\n         * @param ex {@code non-null;} exception\n         */\n        void onException(Exception ex);\n\n        /**\n         * Informs consumer that processing of an archive file has begun.\n         *\n         * @param file {@code non-null;} archive file being processed\n         */\n        void onProcessArchiveStart(File file);\n    }\n\n    /**\n     * Filter interface for {@code ClassOpener}.\n     */\n    public interface FileNameFilter {\n\n        boolean accept(String path);\n    }\n\n    /**\n     * An accept all filter.\n     */\n    public static final FileNameFilter acceptAll = new FileNameFilter() {\n\n        @Override\n        public boolean accept(String path) {\n            return true;\n        }\n    };\n\n    /**\n     * Constructs an instance.\n     *\n     * @param pathname {@code non-null;} path element to process\n     * @param sort if true, sort such that classes appear before their inner\n     * classes and \"package-info\" occurs before all other classes in that\n     * package.\n     * @param consumer {@code non-null;} callback interface\n     */\n    public ClassPathOpener(String pathname, boolean sort, Consumer consumer) {\n        this(pathname, sort, acceptAll, consumer);\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param pathname {@code non-null;} path element to process\n     * @param sort if true, sort such that classes appear before their inner\n     * classes and \"package-info\" occurs before all other classes in that\n     * package.\n     * @param consumer {@code non-null;} callback interface\n     */\n    public ClassPathOpener(String pathname, boolean sort, FileNameFilter filter,\n            Consumer consumer) {\n        this.pathname = pathname;\n        this.sort = sort;\n        this.consumer = consumer;\n        this.filter = filter;\n    }\n\n    /**\n     * Processes a path element.\n     *\n     * @return the OR of all return values\n     * from {@code Consumer.processFileBytes()}.\n     */\n    public boolean process() {\n        File file = new File(pathname);\n\n        return processOne(file, true);\n    }\n\n    /**\n     * Processes one file.\n     *\n     * @param file {@code non-null;} the file to process\n     * @param topLevel whether this is a top-level file (that is,\n     * specified directly on the commandline)\n     * @return whether any processing actually happened\n     */\n    private boolean processOne(File file, boolean topLevel) {\n        try {\n            if (file.isDirectory()) {\n                return processDirectory(file, topLevel);\n            }\n\n            String path = file.getPath();\n\n            if (path.endsWith(\".zip\") ||\n                    path.endsWith(\".jar\") ||\n                    path.endsWith(\".apk\")) {\n                return processArchive(file);\n            }\n            if (filter.accept(path)) {\n                byte[] bytes = FileUtils.readFile(file);\n                return consumer.processFileBytes(path, file.lastModified(), bytes);\n            } else {\n                return false;\n            }\n        } catch (Exception ex) {\n            consumer.onException(ex);\n            return false;\n        }\n    }\n\n    /**\n     * Sorts java class names such that outer classes preceed their inner\n     * classes and \"package-info\" preceeds all other classes in its package.\n     *\n     * @param a {@code non-null;} first class name\n     * @param b {@code non-null;} second class name\n     * @return {@code compareTo()}-style result\n     */\n    private static int compareClassNames(String a, String b) {\n        // Ensure inner classes sort second\n        a = a.replace('$','0');\n        b = b.replace('$','0');\n\n        /*\n         * Assuming \"package-info\" only occurs at the end, ensures package-info\n         * sorts first.\n         */\n        a = a.replace(\"package-info\", \"\");\n        b = b.replace(\"package-info\", \"\");\n\n        return a.compareTo(b);\n    }\n\n    /**\n     * Processes a directory recursively.\n     *\n     * @param dir {@code non-null;} file representing the directory\n     * @param topLevel whether this is a top-level directory (that is,\n     * specified directly on the commandline)\n     * @return whether any processing actually happened\n     */\n    private boolean processDirectory(File dir, boolean topLevel) {\n        if (topLevel) {\n            dir = new File(dir, \".\");\n        }\n\n        File[] files = dir.listFiles();\n        int len = files.length;\n        boolean any = false;\n\n        if (sort) {\n            Arrays.sort(files, new Comparator<File>() {\n                public int compare(File a, File b) {\n                    return compareClassNames(a.getName(), b.getName());\n                }\n            });\n        }\n\n        for (int i = 0; i < len; i++) {\n            any |= processOne(files[i], false);\n        }\n\n        return any;\n    }\n\n    /**\n     * Processes the contents of an archive ({@code .zip},\n     * {@code .jar}, or {@code .apk}).\n     *\n     * @param file {@code non-null;} archive file to process\n     * @return whether any processing actually happened\n     * @throws IOException on i/o problem\n     */\n    private boolean processArchive(File file) throws IOException {\n        ZipFile zip = new ZipFile(file);\n\n        ArrayList<? extends ZipEntry> entriesList\n                = Collections.list(zip.entries());\n\n        if (sort) {\n            Collections.sort(entriesList, new Comparator<ZipEntry>() {\n               public int compare (ZipEntry a, ZipEntry b) {\n                   return compareClassNames(a.getName(), b.getName());\n               }\n            });\n        }\n\n        consumer.onProcessArchiveStart(file);\n\n        ByteArrayOutputStream baos = new ByteArrayOutputStream(40000);\n        byte[] buf = new byte[20000];\n        boolean any = false;\n\n        for (ZipEntry one : entriesList) {\n            final boolean isDirectory = one.isDirectory();\n\n            String path = one.getName();\n            if (filter.accept(path)) {\n                final byte[] bytes;\n                if (!isDirectory) {\n                    InputStream in = zip.getInputStream(one);\n\n                    baos.reset();\n                    int read;\n                    while ((read = in.read(buf)) != -1) {\n                        baos.write(buf, 0, read);\n                    }\n\n                    in.close();\n                    bytes = baos.toByteArray();\n                } else {\n                    bytes = new byte[0];\n                }\n\n                any |= consumer.processFileBytes(path, one.getTime(), bytes);\n            }\n        }\n\n        zip.close();\n        return any;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/direct/CodeObserver.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.direct;\n\nimport com.taobao.android.dx.cf.code.ByteOps;\nimport com.taobao.android.dx.cf.code.BytecodeArray;\nimport com.taobao.android.dx.cf.code.SwitchList;\nimport com.taobao.android.dx.cf.iface.ParseObserver;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstDouble;\nimport com.taobao.android.dx.rop.cst.CstFloat;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.cst.CstKnownNull;\nimport com.taobao.android.dx.rop.cst.CstLong;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.ArrayList;\n\n/**\n * Bytecode visitor to use when \"observing\" bytecode getting parsed.\n */\npublic class CodeObserver implements BytecodeArray.Visitor {\n    /** {@code non-null;} actual array of bytecode */\n    private final ByteArray bytes;\n\n    /** {@code non-null;} observer to inform of parsing */\n    private final ParseObserver observer;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param bytes {@code non-null;} actual array of bytecode\n     * @param observer {@code non-null;} observer to inform of parsing\n     */\n    public CodeObserver(ByteArray bytes, ParseObserver observer) {\n        if (bytes == null) {\n            throw new NullPointerException(\"bytes == null\");\n        }\n\n        if (observer == null) {\n            throw new NullPointerException(\"observer == null\");\n        }\n\n        this.bytes = bytes;\n        this.observer = observer;\n    }\n\n    /** {@inheritDoc} */\n    public void visitInvalid(int opcode, int offset, int length) {\n        observer.parsed(bytes, offset, length, header(offset));\n    }\n\n    /** {@inheritDoc} */\n    public void visitNoArgs(int opcode, int offset, int length, Type type) {\n        observer.parsed(bytes, offset, length, header(offset));\n    }\n\n    /** {@inheritDoc} */\n    public void visitLocal(int opcode, int offset, int length,\n            int idx, Type type, int value) {\n        String idxStr = (length <= 3) ? Hex.u1(idx) : Hex.u2(idx);\n        boolean argComment = (length == 1);\n        String valueStr = \"\";\n\n        if (opcode == ByteOps.IINC) {\n            valueStr = \", #\" +\n                ((length <= 3) ? Hex.s1(value) : Hex.s2(value));\n        }\n\n        String catStr = \"\";\n        if (type.isCategory2()) {\n            catStr = (argComment ? \",\" : \" //\") + \" category-2\";\n        }\n\n        observer.parsed(bytes, offset, length,\n                        header(offset) + (argComment ? \" // \" : \" \") +\n                        idxStr + valueStr + catStr);\n    }\n\n    /** {@inheritDoc} */\n    public void visitConstant(int opcode, int offset, int length,\n            Constant cst, int value) {\n        if (cst instanceof CstKnownNull) {\n            // This is aconst_null.\n            visitNoArgs(opcode, offset, length, null);\n            return;\n        }\n\n        if (cst instanceof CstInteger) {\n            visitLiteralInt(opcode, offset, length, value);\n            return;\n        }\n\n        if (cst instanceof CstLong) {\n            visitLiteralLong(opcode, offset, length,\n                             ((CstLong) cst).getValue());\n            return;\n        }\n\n        if (cst instanceof CstFloat) {\n            visitLiteralFloat(opcode, offset, length,\n                              ((CstFloat) cst).getIntBits());\n            return;\n        }\n\n        if (cst instanceof CstDouble) {\n            visitLiteralDouble(opcode, offset, length,\n                             ((CstDouble) cst).getLongBits());\n            return;\n        }\n\n        String valueStr = \"\";\n        if (value != 0) {\n            valueStr = \", \";\n            if (opcode == ByteOps.MULTIANEWARRAY) {\n                valueStr += Hex.u1(value);\n            } else {\n                valueStr += Hex.u2(value);\n            }\n        }\n\n        observer.parsed(bytes, offset, length,\n                        header(offset) + \" \" + cst + valueStr);\n    }\n\n    /** {@inheritDoc} */\n    public void visitBranch(int opcode, int offset, int length,\n                            int target) {\n        String targetStr = (length <= 3) ? Hex.u2(target) : Hex.u4(target);\n        observer.parsed(bytes, offset, length,\n                        header(offset) + \" \" + targetStr);\n    }\n\n    /** {@inheritDoc} */\n    public void visitSwitch(int opcode, int offset, int length,\n            SwitchList cases, int padding) {\n        int sz = cases.size();\n        StringBuffer sb = new StringBuffer(sz * 20 + 100);\n\n        sb.append(header(offset));\n        if (padding != 0) {\n            sb.append(\" // padding: \" + Hex.u4(padding));\n        }\n        sb.append('\\n');\n\n        for (int i = 0; i < sz; i++) {\n            sb.append(\"  \");\n            sb.append(Hex.s4(cases.getValue(i)));\n            sb.append(\": \");\n            sb.append(Hex.u2(cases.getTarget(i)));\n            sb.append('\\n');\n        }\n\n        sb.append(\"  default: \");\n        sb.append(Hex.u2(cases.getDefaultTarget()));\n\n        observer.parsed(bytes, offset, length, sb.toString());\n    }\n\n    /** {@inheritDoc} */\n    public void visitNewarray(int offset, int length, CstType cst,\n            ArrayList<Constant> intVals) {\n        String commentOrSpace = (length == 1) ? \" // \" : \" \";\n        String typeName = cst.getClassType().getComponentType().toHuman();\n\n        observer.parsed(bytes, offset, length,\n                        header(offset) + commentOrSpace + typeName);\n    }\n\n    /** {@inheritDoc} */\n    public void setPreviousOffset(int offset) {\n        // Do nothing\n    }\n\n    /** {@inheritDoc} */\n    public int getPreviousOffset() {\n        return -1;\n    }\n\n    /**\n     * Helper to produce the first bit of output for each instruction.\n     *\n     * @param offset the offset to the start of the instruction\n     */\n    private String header(int offset) {\n        /*\n         * Note: This uses the original bytecode, not the\n         * possibly-transformed one.\n         */\n        int opcode = bytes.getUnsignedByte(offset);\n        String name = ByteOps.opName(opcode);\n\n        if (opcode == ByteOps.WIDE) {\n            opcode = bytes.getUnsignedByte(offset + 1);\n            name += \" \" + ByteOps.opName(opcode);\n        }\n\n        return Hex.u2(offset) + \": \" + name;\n    }\n\n    /**\n     * Helper for {@link #visitConstant} where the constant is an\n     * {@code int}.\n     *\n     * @param opcode the opcode\n     * @param offset offset to the instruction\n     * @param length instruction length\n     * @param value constant value\n     */\n    private void visitLiteralInt(int opcode, int offset, int length,\n            int value) {\n        String commentOrSpace = (length == 1) ? \" // \" : \" \";\n        String valueStr;\n\n        opcode = bytes.getUnsignedByte(offset); // Compare with orig op below.\n        if ((length == 1) || (opcode == ByteOps.BIPUSH)) {\n            valueStr = \"#\" + Hex.s1(value);\n        } else if (opcode == ByteOps.SIPUSH) {\n            valueStr = \"#\" + Hex.s2(value);\n        } else {\n            valueStr = \"#\" + Hex.s4(value);\n        }\n\n        observer.parsed(bytes, offset, length,\n                        header(offset) + commentOrSpace + valueStr);\n    }\n\n    /**\n     * Helper for {@link #visitConstant} where the constant is a\n     * {@code long}.\n     *\n     * @param opcode the opcode\n     * @param offset offset to the instruction\n     * @param length instruction length\n     * @param value constant value\n     */\n    private void visitLiteralLong(int opcode, int offset, int length,\n            long value) {\n        String commentOrLit = (length == 1) ? \" // \" : \" #\";\n        String valueStr;\n\n        if (length == 1) {\n            valueStr = Hex.s1((int) value);\n        } else {\n            valueStr = Hex.s8(value);\n        }\n\n        observer.parsed(bytes, offset, length,\n                        header(offset) + commentOrLit + valueStr);\n    }\n\n    /**\n     * Helper for {@link #visitConstant} where the constant is a\n     * {@code float}.\n     *\n     * @param opcode the opcode\n     * @param offset offset to the instruction\n     * @param length instruction length\n     * @param bits constant value, as float-bits\n     */\n    private void visitLiteralFloat(int opcode, int offset, int length,\n            int bits) {\n        String optArg = (length != 1) ? \" #\" + Hex.u4(bits) : \"\";\n\n        observer.parsed(bytes, offset, length,\n                        header(offset) + optArg + \" // \" +\n                        Float.intBitsToFloat(bits));\n    }\n\n    /**\n     * Helper for {@link #visitConstant} where the constant is a\n     * {@code double}.\n     *\n     * @param opcode the opcode\n     * @param offset offset to the instruction\n     * @param length instruction length\n     * @param bits constant value, as double-bits\n     */\n    private void visitLiteralDouble(int opcode, int offset, int length,\n            long bits) {\n        String optArg = (length != 1) ? \" #\" + Hex.u8(bits) : \"\";\n\n        observer.parsed(bytes, offset, length,\n                        header(offset) + optArg + \" // \" +\n                        Double.longBitsToDouble(bits));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/direct/DirectClassFile.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.direct;\n\nimport com.taobao.android.dx.cf.attrib.AttSourceFile;\nimport com.taobao.android.dx.cf.cst.ConstantPoolParser;\nimport com.taobao.android.dx.cf.iface.Attribute;\nimport com.taobao.android.dx.cf.iface.AttributeList;\nimport com.taobao.android.dx.cf.iface.ClassFile;\nimport com.taobao.android.dx.cf.iface.FieldList;\nimport com.taobao.android.dx.cf.iface.MethodList;\nimport com.taobao.android.dx.cf.iface.ParseException;\nimport com.taobao.android.dx.cf.iface.ParseObserver;\nimport com.taobao.android.dx.cf.iface.StdAttributeList;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.cst.ConstantPool;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.cst.StdConstantPool;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Class file with info taken from a {@code byte[]} or slice thereof.\n */\npublic class DirectClassFile implements ClassFile {\n    /** the expected value of the ClassFile.magic field */\n    private static final int CLASS_FILE_MAGIC = 0xcafebabe;\n\n    /**\n     * minimum {@code .class} file major version\n     *\n     * See http://en.wikipedia.org/wiki/Java_class_file for an up-to-date\n     * list of version numbers. Currently known (taken from that table) are:\n     *\n     *     J2SE 7.0 = 51 (0x33 hex),\n     *     J2SE 6.0 = 50 (0x32 hex),\n     *     J2SE 5.0 = 49 (0x31 hex),\n     *     JDK 1.4 = 48 (0x30 hex),\n     *     JDK 1.3 = 47 (0x2F hex),\n     *     JDK 1.2 = 46 (0x2E hex),\n     *     JDK 1.1 = 45 (0x2D hex).\n     *\n     * Valid ranges are typically of the form\n     * \"A.0 through B.C inclusive\" where A <= B and C >= 0,\n     * which is why we don't have a CLASS_FILE_MIN_MINOR_VERSION.\n     */\n    private static final int CLASS_FILE_MIN_MAJOR_VERSION = 45;\n\n    /**\n     * maximum {@code .class} file major version\n     *\n     * Note: if you change this, please change \"java.class.version\" in System.java.\n     */\n    private static final int CLASS_FILE_MAX_MAJOR_VERSION = 52;\n\n    /** maximum {@code .class} file minor version */\n    private static final int CLASS_FILE_MAX_MINOR_VERSION = 0;\n\n    /**\n     * {@code non-null;} the file path for the class, excluding any base directory\n     * specification\n     */\n    private final String filePath;\n\n    /** {@code non-null;} the bytes of the file */\n    private final ByteArray bytes;\n\n    /**\n     * whether to be strict about parsing; if\n     * {@code false}, this avoids doing checks that only exist\n     * for purposes of verification (such as magic number matching and\n     * path-package consistency checking)\n     */\n    private final boolean strictParse;\n\n    /**\n     * {@code null-ok;} the constant pool; only ever {@code null}\n     * before the constant pool is successfully parsed\n     */\n    private StdConstantPool pool;\n\n    /**\n     * the class file field {@code access_flags}; will be {@code -1}\n     * before the file is successfully parsed\n     */\n    private int accessFlags;\n\n    /**\n     * {@code null-ok;} the class file field {@code this_class},\n     * interpreted as a type constant; only ever {@code null}\n     * before the file is successfully parsed\n     */\n    private CstType thisClass;\n\n    /**\n     * {@code null-ok;} the class file field {@code super_class}, interpreted\n     * as a type constant if non-zero\n     */\n    private CstType superClass;\n\n    /**\n     * {@code null-ok;} the class file field {@code interfaces}; only\n     * ever {@code null} before the file is successfully\n     * parsed\n     */\n    private TypeList interfaces;\n\n    /**\n     * {@code null-ok;} the class file field {@code fields}; only ever\n     * {@code null} before the file is successfully parsed\n     */\n    private FieldList fields;\n\n    /**\n     * {@code null-ok;} the class file field {@code methods}; only ever\n     * {@code null} before the file is successfully parsed\n     */\n    private MethodList methods;\n\n    /**\n     * {@code null-ok;} the class file field {@code attributes}; only\n     * ever {@code null} before the file is successfully\n     * parsed\n     */\n    private StdAttributeList attributes;\n\n    /** {@code null-ok;} attribute factory, if any */\n    private AttributeFactory attributeFactory;\n\n    /** {@code null-ok;} parse observer, if any */\n    private ParseObserver observer;\n\n    /**\n     * Returns the string form of an object or {@code \"(none)\"}\n     * (rather than {@code \"null\"}) for {@code null}.\n     *\n     * @param obj {@code null-ok;} the object to stringify\n     * @return {@code non-null;} the appropriate string form\n     */\n    public static String stringOrNone(Object obj) {\n        if (obj == null) {\n            return \"(none)\";\n        }\n\n        return obj.toString();\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param bytes {@code non-null;} the bytes of the file\n     * @param filePath {@code non-null;} the file path for the class,\n     * excluding any base directory specification\n     * @param strictParse whether to be strict about parsing; if\n     * {@code false}, this avoids doing checks that only exist\n     * for purposes of verification (such as magic number matching and\n     * path-package consistency checking)\n     */\n    public DirectClassFile(ByteArray bytes, String filePath,\n                           boolean strictParse) {\n        if (bytes == null) {\n            throw new NullPointerException(\"bytes == null\");\n        }\n\n        if (filePath == null) {\n            throw new NullPointerException(\"filePath == null\");\n        }\n\n        this.filePath = filePath;\n        this.bytes = bytes;\n        this.strictParse = strictParse;\n        this.accessFlags = -1;\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param bytes {@code non-null;} the bytes of the file\n     * @param filePath {@code non-null;} the file path for the class,\n     * excluding any base directory specification\n     * @param strictParse whether to be strict about parsing; if\n     * {@code false}, this avoids doing checks that only exist\n     * for purposes of verification (such as magic number matching and\n     * path-package consistency checking)\n     */\n    public DirectClassFile(byte[] bytes, String filePath,\n                           boolean strictParse) {\n        this(new ByteArray(bytes), filePath, strictParse);\n    }\n\n    /**\n     * Sets the parse observer for this instance.\n     *\n     * @param observer {@code null-ok;} the observer\n     */\n    public void setObserver(ParseObserver observer) {\n        this.observer = observer;\n    }\n\n    /**\n     * Sets the attribute factory to use.\n     *\n     * @param attributeFactory {@code non-null;} the attribute factory\n     */\n    public void setAttributeFactory(AttributeFactory attributeFactory) {\n        if (attributeFactory == null) {\n            throw new NullPointerException(\"attributeFactory == null\");\n        }\n\n        this.attributeFactory = attributeFactory;\n    }\n\n    /**\n     * Gets the path where this class file is located.\n     *\n     * @return {@code non-null;} the filePath\n     */\n    public String getFilePath() {\n      return filePath;\n    }\n\n    /**\n     * Gets the {@link ByteArray} that this instance's data comes from.\n     *\n     * @return {@code non-null;} the bytes\n     */\n    public ByteArray getBytes() {\n        return bytes;\n    }\n\n    /** {@inheritDoc} */\n    public int getMagic() {\n        parseToInterfacesIfNecessary();\n        return getMagic0();\n    }\n\n    /** {@inheritDoc} */\n    public int getMinorVersion() {\n        parseToInterfacesIfNecessary();\n        return getMinorVersion0();\n    }\n\n    /** {@inheritDoc} */\n    public int getMajorVersion() {\n        parseToInterfacesIfNecessary();\n        return getMajorVersion0();\n    }\n\n    /** {@inheritDoc} */\n    public int getAccessFlags() {\n        parseToInterfacesIfNecessary();\n        return accessFlags;\n    }\n\n    /** {@inheritDoc} */\n    public CstType getThisClass() {\n        parseToInterfacesIfNecessary();\n        return thisClass;\n    }\n\n    /** {@inheritDoc} */\n    public CstType getSuperclass() {\n        parseToInterfacesIfNecessary();\n        return superClass;\n    }\n\n    /** {@inheritDoc} */\n    public ConstantPool getConstantPool() {\n        parseToInterfacesIfNecessary();\n        return pool;\n    }\n\n    /** {@inheritDoc} */\n    public TypeList getInterfaces() {\n        parseToInterfacesIfNecessary();\n        return interfaces;\n    }\n\n    /** {@inheritDoc} */\n    public FieldList getFields() {\n        parseToEndIfNecessary();\n        return fields;\n    }\n\n    /** {@inheritDoc} */\n    public MethodList getMethods() {\n        parseToEndIfNecessary();\n        return methods;\n    }\n\n    /** {@inheritDoc} */\n    public AttributeList getAttributes() {\n        parseToEndIfNecessary();\n        return attributes;\n    }\n\n    /** {@inheritDoc} */\n    public CstString getSourceFile() {\n        AttributeList attribs = getAttributes();\n        Attribute attSf = attribs.findFirst(AttSourceFile.ATTRIBUTE_NAME);\n\n        if (attSf instanceof AttSourceFile) {\n            return ((AttSourceFile) attSf).getSourceFile();\n        }\n\n        return null;\n    }\n\n    /**\n     * Constructs and returns an instance of {@link TypeList} whose\n     * data comes from the bytes of this instance, interpreted as a\n     * list of constant pool indices for classes, which are in turn\n     * translated to type constants. Instance construction will fail\n     * if any of the (alleged) indices turn out not to refer to\n     * constant pool entries of type {@code Class}.\n     *\n     * @param offset offset into {@link #bytes} for the start of the\n     * data\n     * @param size number of elements in the list (not number of bytes)\n     * @return {@code non-null;} an appropriately-constructed class list\n     */\n    public TypeList makeTypeList(int offset, int size) {\n        if (size == 0) {\n            return StdTypeList.EMPTY;\n        }\n\n        if (pool == null) {\n            throw new IllegalStateException(\"pool not yet initialized\");\n        }\n\n        return new DcfTypeList(bytes, offset, size, pool, observer);\n    }\n\n    /**\n     * Gets the class file field {@code magic}, but without doing any\n     * checks or parsing first.\n     *\n     * @return the magic value\n     */\n    public int getMagic0() {\n        return bytes.getInt(0);\n    }\n\n    /**\n     * Gets the class file field {@code minor_version}, but\n     * without doing any checks or parsing first.\n     *\n     * @return the minor version\n     */\n    public int getMinorVersion0() {\n        return bytes.getUnsignedShort(4);\n    }\n\n    /**\n     * Gets the class file field {@code major_version}, but\n     * without doing any checks or parsing first.\n     *\n     * @return the major version\n     */\n    public int getMajorVersion0() {\n        return bytes.getUnsignedShort(6);\n    }\n\n    /**\n     * Runs {@link #parse} if it has not yet been run to cover up to\n     * the interfaces list.\n     */\n    private void parseToInterfacesIfNecessary() {\n        if (accessFlags == -1) {\n            parse();\n        }\n    }\n\n    /**\n     * Runs {@link #parse} if it has not yet been run successfully.\n     */\n    private void parseToEndIfNecessary() {\n        if (attributes == null) {\n            parse();\n        }\n    }\n\n    /**\n     * Does the parsing, handing exceptions.\n     */\n    private void parse() {\n        try {\n            parse0();\n        } catch (ParseException ex) {\n            ex.addContext(\"...while parsing \" + filePath);\n            throw ex;\n        } catch (RuntimeException ex) {\n            ParseException pe = new ParseException(ex);\n            pe.addContext(\"...while parsing \" + filePath);\n            throw pe;\n        }\n    }\n\n    /**\n     * Sees if the .class file header magic has the good value.\n     *\n     * @param magic the value of a classfile \"magic\" field\n     * @return true if the magic is valid\n     */\n    private boolean isGoodMagic(int magic) {\n        return magic == CLASS_FILE_MAGIC;\n    }\n\n    /**\n     * Sees if the .class file header version are within\n     * range.\n     *\n     * @param minorVersion the value of a classfile \"minor_version\" field\n     * @param majorVersion the value of a classfile \"major_version\" field\n     * @return true if the parameters are valid and within range\n     */\n    private boolean isGoodVersion(int minorVersion, int majorVersion) {\n        /* Valid version ranges are typically of the form\n         * \"A.0 through B.C inclusive\" where A <= B and C >= 0,\n         * which is why we don't have a CLASS_FILE_MIN_MINOR_VERSION.\n         */\n        if (minorVersion >= 0) {\n            /* Check against max first to handle the case where\n             * MIN_MAJOR == MAX_MAJOR.\n             */\n            if (majorVersion == CLASS_FILE_MAX_MAJOR_VERSION) {\n                if (minorVersion <= CLASS_FILE_MAX_MINOR_VERSION) {\n                    return true;\n                }\n            } else if (majorVersion < CLASS_FILE_MAX_MAJOR_VERSION &&\n                       majorVersion >= CLASS_FILE_MIN_MAJOR_VERSION) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Does the actual parsing.\n     */\n    private void parse0() {\n        if (bytes.size() < 10) {\n            throw new ParseException(\"severely truncated class file\");\n        }\n\n        if (observer != null) {\n            observer.parsed(bytes, 0, 0, \"begin classfile\");\n            observer.parsed(bytes, 0, 4, \"magic: \" + Hex.u4(getMagic0()));\n            observer.parsed(bytes, 4, 2,\n                            \"minor_version: \" + Hex.u2(getMinorVersion0()));\n            observer.parsed(bytes, 6, 2,\n                            \"major_version: \" + Hex.u2(getMajorVersion0()));\n        }\n\n        if (strictParse) {\n            /* Make sure that this looks like a valid class file with a\n             * version that we can handle.\n             */\n            if (!isGoodMagic(getMagic0())) {\n                throw new ParseException(\"bad class file magic (\" + Hex.u4(getMagic0()) + \")\");\n            }\n\n            if (!isGoodVersion(getMinorVersion0(), getMajorVersion0())) {\n                throw new ParseException(\"unsupported class file version \" +\n                                         getMajorVersion0() + \".\" +\n                                         getMinorVersion0());\n            }\n        }\n\n        ConstantPoolParser cpParser = new ConstantPoolParser(bytes);\n        cpParser.setObserver(observer);\n        pool = cpParser.getPool();\n        pool.setImmutable();\n\n        int at = cpParser.getEndOffset();\n        int accessFlags = bytes.getUnsignedShort(at); // u2 access_flags;\n        int cpi = bytes.getUnsignedShort(at + 2); // u2 this_class;\n        thisClass = (CstType) pool.get(cpi);\n        cpi = bytes.getUnsignedShort(at + 4); // u2 super_class;\n        superClass = (CstType) pool.get0Ok(cpi);\n        int count = bytes.getUnsignedShort(at + 6); // u2 interfaces_count\n\n        if (observer != null) {\n            observer.parsed(bytes, at, 2,\n                            \"access_flags: \" +\n                            AccessFlags.classString(accessFlags));\n            observer.parsed(bytes, at + 2, 2, \"this_class: \" + thisClass);\n            observer.parsed(bytes, at + 4, 2, \"super_class: \" +\n                            stringOrNone(superClass));\n            observer.parsed(bytes, at + 6, 2,\n                            \"interfaces_count: \" + Hex.u2(count));\n            if (count != 0) {\n                observer.parsed(bytes, at + 8, 0, \"interfaces:\");\n            }\n        }\n\n        at += 8;\n        interfaces = makeTypeList(at, count);\n        at += count * 2;\n\n        if (strictParse) {\n            /*\n             * Make sure that the file/jar path matches the declared\n             * package/class name.\n             */\n            String thisClassName = thisClass.getClassType().getClassName();\n            if (!(filePath.endsWith(\".class\") &&\n                  filePath.startsWith(thisClassName) &&\n                  (filePath.length() == (thisClassName.length() + 6)))) {\n                throw new ParseException(\"class name (\" + thisClassName +\n                                         \") does not match path (\" +\n                                         filePath + \")\");\n            }\n        }\n\n        /*\n         * Only set the instance variable accessFlags here, since\n         * that's what signals a successful parse of the first part of\n         * the file (through the interfaces list).\n         */\n        this.accessFlags = accessFlags;\n\n        FieldListParser flParser =\n            new FieldListParser(this, thisClass, at, attributeFactory);\n        flParser.setObserver(observer);\n        fields = flParser.getList();\n        at = flParser.getEndOffset();\n\n        MethodListParser mlParser =\n            new MethodListParser(this, thisClass, at, attributeFactory);\n        mlParser.setObserver(observer);\n        methods = mlParser.getList();\n        at = mlParser.getEndOffset();\n\n        AttributeListParser alParser =\n            new AttributeListParser(this, AttributeFactory.CTX_CLASS, at,\n                                    attributeFactory);\n        alParser.setObserver(observer);\n        attributes = alParser.getList();\n        attributes.setImmutable();\n        at = alParser.getEndOffset();\n\n        if (at != bytes.size()) {\n            throw new ParseException(\"extra bytes at end of class file, \" +\n                                     \"at offset \" + Hex.u4(at));\n        }\n\n        if (observer != null) {\n            observer.parsed(bytes, at, 0, \"end classfile\");\n        }\n    }\n\n    /**\n     * Implementation of {@link TypeList} whose data comes directly\n     * from the bytes of an instance of this (outer) class,\n     * interpreted as a list of constant pool indices for classes\n     * which are in turn returned as type constants. Instance\n     * construction will fail if any of the (alleged) indices turn out\n     * not to refer to constant pool entries of type\n     * {@code Class}.\n     */\n    private static class DcfTypeList implements TypeList {\n        /** {@code non-null;} array containing the data */\n        private final ByteArray bytes;\n\n        /** number of elements in the list (not number of bytes) */\n        private final int size;\n\n        /** {@code non-null;} the constant pool */\n        private final StdConstantPool pool;\n\n        /**\n         * Constructs an instance.\n         *\n         * @param bytes {@code non-null;} original classfile's bytes\n         * @param offset offset into {@link #bytes} for the start of the\n         * data\n         * @param size number of elements in the list (not number of bytes)\n         * @param pool {@code non-null;} the constant pool to use\n         * @param observer {@code null-ok;} parse observer to use, if any\n         */\n        public DcfTypeList(ByteArray bytes, int offset, int size,\n                StdConstantPool pool, ParseObserver observer) {\n            if (size < 0) {\n                throw new IllegalArgumentException(\"size < 0\");\n            }\n\n            bytes = bytes.slice(offset, offset + size * 2);\n            this.bytes = bytes;\n            this.size = size;\n            this.pool = pool;\n\n            for (int i = 0; i < size; i++) {\n                offset = i * 2;\n                int idx = bytes.getUnsignedShort(offset);\n                CstType type;\n                try {\n                    type = (CstType) pool.get(idx);\n                } catch (ClassCastException ex) {\n                    // Translate the exception.\n                    throw new RuntimeException(\"bogus class cpi\", ex);\n                }\n                if (observer != null) {\n                    observer.parsed(bytes, offset, 2, \"  \" + type);\n                }\n            }\n        }\n\n        /** {@inheritDoc} */\n        public boolean isMutable() {\n            return false;\n        }\n\n        /** {@inheritDoc} */\n        public int size() {\n            return size;\n        }\n\n        /** {@inheritDoc} */\n        public int getWordCount() {\n            // It is the same as size because all elements are classes.\n            return size;\n        }\n\n        /** {@inheritDoc} */\n        public Type getType(int n) {\n            int idx = bytes.getUnsignedShort(n * 2);\n            return ((CstType) pool.get(idx)).getClassType();\n        }\n\n        /** {@inheritDoc} */\n        public TypeList withAddedType(Type type) {\n            throw new UnsupportedOperationException(\"unsupported\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/direct/FieldListParser.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.direct;\n\nimport com.taobao.android.dx.cf.iface.AttributeList;\nimport com.taobao.android.dx.cf.iface.Member;\nimport com.taobao.android.dx.cf.iface.StdField;\nimport com.taobao.android.dx.cf.iface.StdFieldList;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstType;\n\n/**\n * Parser for lists of fields in a class file.\n */\nfinal /*package*/ class FieldListParser extends MemberListParser {\n    /** {@code non-null;} list in progress */\n    private final StdFieldList fields;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param cf {@code non-null;} the class file to parse from\n     * @param definer {@code non-null;} class being defined\n     * @param offset offset in {@code bytes} to the start of the list\n     * @param attributeFactory {@code non-null;} attribute factory to use\n     */\n    public FieldListParser(DirectClassFile cf, CstType definer, int offset,\n            AttributeFactory attributeFactory) {\n        super(cf, definer, offset, attributeFactory);\n        fields = new StdFieldList(getCount());\n    }\n\n    /**\n     * Gets the parsed list.\n     *\n     * @return {@code non-null;} the parsed list\n     */\n    public StdFieldList getList() {\n        parseIfNecessary();\n        return fields;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String humanName() {\n        return \"field\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String humanAccessFlags(int accessFlags) {\n        return AccessFlags.fieldString(accessFlags);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int getAttributeContext() {\n        return AttributeFactory.CTX_FIELD;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected Member set(int n, int accessFlags, CstNat nat,\n                         AttributeList attributes) {\n        StdField field =\n            new StdField(getDefiner(), accessFlags, nat, attributes);\n\n        fields.set(n, field);\n        return field;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/direct/MemberListParser.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.direct;\n\nimport com.taobao.android.dx.cf.iface.AttributeList;\nimport com.taobao.android.dx.cf.iface.Member;\nimport com.taobao.android.dx.cf.iface.ParseException;\nimport com.taobao.android.dx.cf.iface.ParseObserver;\nimport com.taobao.android.dx.cf.iface.StdAttributeList;\nimport com.taobao.android.dx.rop.cst.ConstantPool;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Parser for lists of class file members (that is, fields and methods).\n */\nabstract /*package*/ class MemberListParser {\n    /** {@code non-null;} the class file to parse from */\n    private final DirectClassFile cf;\n\n    /** {@code non-null;} class being defined */\n    private final CstType definer;\n\n    /** offset in the byte array of the classfile to the start of the list */\n    private final int offset;\n\n    /** {@code non-null;} attribute factory to use */\n    private final AttributeFactory attributeFactory;\n\n    /** {@code >= -1;} the end offset of this list in the byte array of the\n     * classfile, or {@code -1} if not yet parsed */\n    private int endOffset;\n\n    /** {@code null-ok;} parse observer, if any */\n    private ParseObserver observer;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param cf {@code non-null;} the class file to parse from\n     * @param definer {@code non-null;} class being defined\n     * @param offset offset in {@code bytes} to the start of the list\n     * @param attributeFactory {@code non-null;} attribute factory to use\n     */\n    public MemberListParser(DirectClassFile cf, CstType definer,\n            int offset, AttributeFactory attributeFactory) {\n        if (cf == null) {\n            throw new NullPointerException(\"cf == null\");\n        }\n\n        if (offset < 0) {\n            throw new IllegalArgumentException(\"offset < 0\");\n        }\n\n        if (attributeFactory == null) {\n            throw new NullPointerException(\"attributeFactory == null\");\n        }\n\n        this.cf = cf;\n        this.definer = definer;\n        this.offset = offset;\n        this.attributeFactory = attributeFactory;\n        this.endOffset = -1;\n    }\n\n    /**\n     * Gets the end offset of this constant pool in the {@code byte[]}\n     * which it came from.\n     *\n     * @return {@code >= 0;} the end offset\n     */\n    public int getEndOffset() {\n        parseIfNecessary();\n        return endOffset;\n    }\n\n    /**\n     * Sets the parse observer for this instance.\n     *\n     * @param observer {@code null-ok;} the observer\n     */\n    public final void setObserver(ParseObserver observer) {\n        this.observer = observer;\n    }\n\n    /**\n     * Runs {@link #parse} if it has not yet been run successfully.\n     */\n    protected final void parseIfNecessary() {\n        if (endOffset < 0) {\n            parse();\n        }\n    }\n\n    /**\n     * Gets the count of elements in the list.\n     *\n     * @return the count\n     */\n    protected final int getCount() {\n        ByteArray bytes = cf.getBytes();\n        return bytes.getUnsignedShort(offset);\n    }\n\n    /**\n     * Gets the class file being defined.\n     *\n     * @return {@code non-null;} the class\n     */\n    protected final CstType getDefiner() {\n        return definer;\n    }\n\n    /**\n     * Gets the human-oriented name for what this instance is parsing.\n     * Subclasses must override this method.\n     *\n     * @return {@code non-null;} the human oriented name\n     */\n    protected abstract String humanName();\n\n    /**\n     * Gets the human-oriented string for the given access flags.\n     * Subclasses must override this method.\n     *\n     * @param accessFlags the flags\n     * @return {@code non-null;} the string form\n     */\n    protected abstract String humanAccessFlags(int accessFlags);\n\n    /**\n     * Gets the {@code CTX_*} constant to use when parsing attributes.\n     * Subclasses must override this method.\n     *\n     * @return {@code non-null;} the human oriented name\n     */\n    protected abstract int getAttributeContext();\n\n    /**\n     * Sets an element in the list. Subclasses must override this method.\n     *\n     * @param n which element\n     * @param accessFlags the {@code access_flags}\n     * @param nat the interpreted name and type (based on the two\n     * {@code *_index} fields)\n     * @param attributes list of parsed attributes\n     * @return {@code non-null;} the constructed member\n     */\n    protected abstract Member set(int n, int accessFlags, CstNat nat,\n            AttributeList attributes);\n\n    /**\n     * Does the actual parsing.\n     */\n    private void parse() {\n        int attributeContext = getAttributeContext();\n        int count = getCount();\n        int at = offset + 2; // Skip the count.\n\n        ByteArray bytes = cf.getBytes();\n        ConstantPool pool = cf.getConstantPool();\n\n        if (observer != null) {\n            observer.parsed(bytes, offset, 2,\n                            humanName() + \"s_count: \" + Hex.u2(count));\n        }\n\n        for (int i = 0; i < count; i++) {\n            try {\n                int accessFlags = bytes.getUnsignedShort(at);\n                int nameIdx = bytes.getUnsignedShort(at + 2);\n                int descIdx = bytes.getUnsignedShort(at + 4);\n                CstString name = (CstString) pool.get(nameIdx);\n                CstString desc = (CstString) pool.get(descIdx);\n\n                if (observer != null) {\n                    observer.startParsingMember(bytes, at, name.getString(),\n                                                desc.getString());\n                    observer.parsed(bytes, at, 0, \"\\n\" + humanName() +\n                                    \"s[\" + i + \"]:\\n\");\n                    observer.changeIndent(1);\n                    observer.parsed(bytes, at, 2,\n                                    \"access_flags: \" +\n                                    humanAccessFlags(accessFlags));\n                    observer.parsed(bytes, at + 2, 2,\n                                    \"name: \" + name.toHuman());\n                    observer.parsed(bytes, at + 4, 2,\n                                    \"descriptor: \" + desc.toHuman());\n                }\n\n                at += 6;\n                AttributeListParser parser =\n                    new AttributeListParser(cf, attributeContext, at,\n                                            attributeFactory);\n                parser.setObserver(observer);\n                at = parser.getEndOffset();\n                StdAttributeList attributes = parser.getList();\n                attributes.setImmutable();\n                CstNat nat = new CstNat(name, desc);\n                Member member = set(i, accessFlags, nat, attributes);\n\n                if (observer != null) {\n                    observer.changeIndent(-1);\n                    observer.parsed(bytes, at, 0, \"end \" + humanName() +\n                                    \"s[\" + i + \"]\\n\");\n                    observer.endParsingMember(bytes, at, name.getString(),\n                                              desc.getString(), member);\n                }\n            } catch (ParseException ex) {\n                ex.addContext(\"...while parsing \" + humanName() + \"s[\" + i +\n                              \"]\");\n                throw ex;\n            } catch (RuntimeException ex) {\n                ParseException pe = new ParseException(ex);\n                pe.addContext(\"...while parsing \" + humanName() + \"s[\" + i +\n                              \"]\");\n                throw pe;\n            }\n        }\n\n        endOffset = at;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/direct/MethodListParser.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.direct;\n\nimport com.taobao.android.dx.cf.iface.AttributeList;\nimport com.taobao.android.dx.cf.iface.Member;\nimport com.taobao.android.dx.cf.iface.StdMethod;\nimport com.taobao.android.dx.cf.iface.StdMethodList;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstType;\n\n/**\n * Parser for lists of methods in a class file.\n */\nfinal /*package*/ class MethodListParser extends MemberListParser {\n    /** {@code non-null;} list in progress */\n    final private StdMethodList methods;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param cf {@code non-null;} the class file to parse from\n     * @param definer {@code non-null;} class being defined\n     * @param offset offset in {@code bytes} to the start of the list\n     * @param attributeFactory {@code non-null;} attribute factory to use\n     */\n    public MethodListParser(DirectClassFile cf, CstType definer,\n            int offset, AttributeFactory attributeFactory) {\n        super(cf, definer, offset, attributeFactory);\n        methods = new StdMethodList(getCount());\n    }\n\n    /**\n     * Gets the parsed list.\n     *\n     * @return {@code non-null;} the parsed list\n     */\n    public StdMethodList getList() {\n        parseIfNecessary();\n        return methods;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String humanName() {\n        return \"method\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String humanAccessFlags(int accessFlags) {\n        return AccessFlags.methodString(accessFlags);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int getAttributeContext() {\n        return AttributeFactory.CTX_METHOD;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected Member set(int n, int accessFlags, CstNat nat,\n                         AttributeList attributes) {\n        StdMethod meth =\n            new StdMethod(getDefiner(), accessFlags, nat, attributes);\n\n        methods.set(n, meth);\n        return meth;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/direct/StdAttributeFactory.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.direct;\n\nimport com.taobao.android.dx.cf.attrib.AttAnnotationDefault;\nimport com.taobao.android.dx.cf.attrib.AttCode;\nimport com.taobao.android.dx.cf.attrib.AttConstantValue;\nimport com.taobao.android.dx.cf.attrib.AttDeprecated;\nimport com.taobao.android.dx.cf.attrib.AttEnclosingMethod;\nimport com.taobao.android.dx.cf.attrib.AttExceptions;\nimport com.taobao.android.dx.cf.attrib.AttInnerClasses;\nimport com.taobao.android.dx.cf.attrib.AttLineNumberTable;\nimport com.taobao.android.dx.cf.attrib.AttLocalVariableTable;\nimport com.taobao.android.dx.cf.attrib.AttLocalVariableTypeTable;\nimport com.taobao.android.dx.cf.attrib.AttRuntimeInvisibleAnnotations;\nimport com.taobao.android.dx.cf.attrib.AttRuntimeInvisibleParameterAnnotations;\nimport com.taobao.android.dx.cf.attrib.AttRuntimeVisibleAnnotations;\nimport com.taobao.android.dx.cf.attrib.AttRuntimeVisibleParameterAnnotations;\nimport com.taobao.android.dx.cf.attrib.AttSignature;\nimport com.taobao.android.dx.cf.attrib.AttSourceFile;\nimport com.taobao.android.dx.cf.attrib.AttSynthetic;\nimport com.taobao.android.dx.cf.attrib.InnerClassList;\nimport com.taobao.android.dx.cf.code.ByteCatchList;\nimport com.taobao.android.dx.cf.code.BytecodeArray;\nimport com.taobao.android.dx.cf.code.LineNumberList;\nimport com.taobao.android.dx.cf.code.LocalVariableList;\nimport com.taobao.android.dx.cf.iface.Attribute;\nimport com.taobao.android.dx.cf.iface.ParseException;\nimport com.taobao.android.dx.cf.iface.ParseObserver;\nimport com.taobao.android.dx.cf.iface.StdAttributeList;\nimport com.taobao.android.dx.rop.annotation.AnnotationVisibility;\nimport com.taobao.android.dx.rop.annotation.Annotations;\nimport com.taobao.android.dx.rop.annotation.AnnotationsList;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.ConstantPool;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.cst.TypedConstant;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\nimport java.io.IOException;\n\n/**\n * Standard subclass of {@link AttributeFactory}, which knows how to parse\n * all the standard attribute types.\n */\npublic class StdAttributeFactory\n    extends AttributeFactory {\n    /** {@code non-null;} shared instance of this class */\n    public static final StdAttributeFactory THE_ONE =\n        new StdAttributeFactory();\n\n    /**\n     * Constructs an instance.\n     */\n    public StdAttributeFactory() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected Attribute parse0(DirectClassFile cf, int context, String name,\n            int offset, int length, ParseObserver observer) {\n        switch (context) {\n            case CTX_CLASS: {\n                if (name == AttDeprecated.ATTRIBUTE_NAME) {\n                    return deprecated(cf, offset, length, observer);\n                }\n                if (name == AttEnclosingMethod.ATTRIBUTE_NAME) {\n                    return enclosingMethod(cf, offset, length, observer);\n                }\n                if (name == AttInnerClasses.ATTRIBUTE_NAME) {\n                    return innerClasses(cf, offset, length, observer);\n                }\n                if (name == AttRuntimeInvisibleAnnotations.ATTRIBUTE_NAME) {\n                    return runtimeInvisibleAnnotations(cf, offset, length,\n                            observer);\n                }\n                if (name == AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME) {\n                    return runtimeVisibleAnnotations(cf, offset, length,\n                            observer);\n                }\n                if (name == AttSynthetic.ATTRIBUTE_NAME) {\n                    return synthetic(cf, offset, length, observer);\n                }\n                if (name == AttSignature.ATTRIBUTE_NAME) {\n                    return signature(cf, offset, length, observer);\n                }\n                if (name == AttSourceFile.ATTRIBUTE_NAME) {\n                    return sourceFile(cf, offset, length, observer);\n                }\n                break;\n            }\n            case CTX_FIELD: {\n                if (name == AttConstantValue.ATTRIBUTE_NAME) {\n                    return constantValue(cf, offset, length, observer);\n                }\n                if (name == AttDeprecated.ATTRIBUTE_NAME) {\n                    return deprecated(cf, offset, length, observer);\n                }\n                if (name == AttRuntimeInvisibleAnnotations.ATTRIBUTE_NAME) {\n                    return runtimeInvisibleAnnotations(cf, offset, length,\n                            observer);\n                }\n                if (name == AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME) {\n                    return runtimeVisibleAnnotations(cf, offset, length,\n                            observer);\n                }\n                if (name == AttSignature.ATTRIBUTE_NAME) {\n                    return signature(cf, offset, length, observer);\n                }\n                if (name == AttSynthetic.ATTRIBUTE_NAME) {\n                    return synthetic(cf, offset, length, observer);\n                }\n                break;\n            }\n            case CTX_METHOD: {\n                if (name == AttAnnotationDefault.ATTRIBUTE_NAME) {\n                    return annotationDefault(cf, offset, length, observer);\n                }\n                if (name == AttCode.ATTRIBUTE_NAME) {\n                    return code(cf, offset, length, observer);\n                }\n                if (name == AttDeprecated.ATTRIBUTE_NAME) {\n                    return deprecated(cf, offset, length, observer);\n                }\n                if (name == AttExceptions.ATTRIBUTE_NAME) {\n                    return exceptions(cf, offset, length, observer);\n                }\n                if (name == AttRuntimeInvisibleAnnotations.ATTRIBUTE_NAME) {\n                    return runtimeInvisibleAnnotations(cf, offset, length,\n                            observer);\n                }\n                if (name == AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME) {\n                    return runtimeVisibleAnnotations(cf, offset, length,\n                            observer);\n                }\n                if (name == AttRuntimeInvisibleParameterAnnotations.\n                        ATTRIBUTE_NAME) {\n                    return runtimeInvisibleParameterAnnotations(\n                            cf, offset, length, observer);\n                }\n                if (name == AttRuntimeVisibleParameterAnnotations.\n                        ATTRIBUTE_NAME) {\n                    return runtimeVisibleParameterAnnotations(\n                            cf, offset, length, observer);\n                }\n                if (name == AttSignature.ATTRIBUTE_NAME) {\n                    return signature(cf, offset, length, observer);\n                }\n                if (name == AttSynthetic.ATTRIBUTE_NAME) {\n                    return synthetic(cf, offset, length, observer);\n                }\n                break;\n            }\n            case CTX_CODE: {\n                if (name == AttLineNumberTable.ATTRIBUTE_NAME) {\n                    return lineNumberTable(cf, offset, length, observer);\n                }\n                if (name == AttLocalVariableTable.ATTRIBUTE_NAME) {\n                    return localVariableTable(cf, offset, length, observer);\n                }\n                if (name == AttLocalVariableTypeTable.ATTRIBUTE_NAME) {\n                    return localVariableTypeTable(cf, offset, length,\n                            observer);\n                }\n                break;\n            }\n        }\n\n        return super.parse0(cf, context, name, offset, length, observer);\n    }\n\n    /**\n     * Parses an {@code AnnotationDefault} attribute.\n     */\n    private Attribute annotationDefault(DirectClassFile cf,\n            int offset, int length, ParseObserver observer) {\n        if (length < 2) {\n            throwSeverelyTruncated();\n        }\n\n        AnnotationParser ap =\n            new AnnotationParser(cf, offset, length, observer);\n        Constant cst = ap.parseValueAttribute();\n\n        return new AttAnnotationDefault(cst, length);\n    }\n\n    /**\n     * Parses a {@code Code} attribute.\n     */\n    private Attribute code(DirectClassFile cf, int offset, int length,\n            ParseObserver observer) {\n        if (length < 12) {\n            return throwSeverelyTruncated();\n        }\n\n        ByteArray bytes = cf.getBytes();\n        ConstantPool pool = cf.getConstantPool();\n        int maxStack = bytes.getUnsignedShort(offset); // u2 max_stack\n        int maxLocals = bytes.getUnsignedShort(offset + 2); // u2 max_locals\n        int codeLength = bytes.getInt(offset + 4); // u4 code_length\n        int origOffset = offset;\n\n        if (observer != null) {\n            observer.parsed(bytes, offset, 2,\n                            \"max_stack: \" + Hex.u2(maxStack));\n            observer.parsed(bytes, offset + 2, 2,\n                            \"max_locals: \" + Hex.u2(maxLocals));\n            observer.parsed(bytes, offset + 4, 4,\n                            \"code_length: \" + Hex.u4(codeLength));\n        }\n\n        offset += 8;\n        length -= 8;\n\n        if (length < (codeLength + 4)) {\n            return throwTruncated();\n        }\n\n        int codeOffset = offset;\n        offset += codeLength;\n        length -= codeLength;\n        BytecodeArray code =\n            new BytecodeArray(bytes.slice(codeOffset, codeOffset + codeLength),\n                              pool);\n        if (observer != null) {\n            code.forEach(new CodeObserver(code.getBytes(), observer));\n        }\n\n        // u2 exception_table_length\n        int exceptionTableLength = bytes.getUnsignedShort(offset);\n        ByteCatchList catches = (exceptionTableLength == 0) ?\n            ByteCatchList.EMPTY :\n            new ByteCatchList(exceptionTableLength);\n\n        if (observer != null) {\n            observer.parsed(bytes, offset, 2,\n                            \"exception_table_length: \" +\n                            Hex.u2(exceptionTableLength));\n        }\n\n        offset += 2;\n        length -= 2;\n\n        if (length < (exceptionTableLength * 8 + 2)) {\n            return throwTruncated();\n        }\n\n        for (int i = 0; i < exceptionTableLength; i++) {\n            if (observer != null) {\n                observer.changeIndent(1);\n            }\n\n            int startPc = bytes.getUnsignedShort(offset);\n            int endPc = bytes.getUnsignedShort(offset + 2);\n            int handlerPc = bytes.getUnsignedShort(offset + 4);\n            int catchTypeIdx = bytes.getUnsignedShort(offset + 6);\n            CstType catchType = (CstType) pool.get0Ok(catchTypeIdx);\n            catches.set(i, startPc, endPc, handlerPc, catchType);\n            if (observer != null) {\n                observer.parsed(bytes, offset, 8,\n                                Hex.u2(startPc) + \"..\" + Hex.u2(endPc) +\n                                \" -> \" + Hex.u2(handlerPc) + \" \" +\n                                ((catchType == null) ? \"<any>\" :\n                                 catchType.toHuman()));\n            }\n            offset += 8;\n            length -= 8;\n\n            if (observer != null) {\n                observer.changeIndent(-1);\n            }\n        }\n\n        catches.setImmutable();\n\n        AttributeListParser parser =\n            new AttributeListParser(cf, CTX_CODE, offset, this);\n        parser.setObserver(observer);\n\n        StdAttributeList attributes = parser.getList();\n        attributes.setImmutable();\n\n        int attributeByteCount = parser.getEndOffset() - offset;\n        if (attributeByteCount != length) {\n            return throwBadLength(attributeByteCount + (offset - origOffset));\n        }\n\n        return new AttCode(maxStack, maxLocals, code, catches, attributes);\n    }\n\n    /**\n     * Parses a {@code ConstantValue} attribute.\n     */\n    private Attribute constantValue(DirectClassFile cf, int offset, int length,\n            ParseObserver observer) {\n        if (length != 2) {\n            return throwBadLength(2);\n        }\n\n        ByteArray bytes = cf.getBytes();\n        ConstantPool pool = cf.getConstantPool();\n        int idx = bytes.getUnsignedShort(offset);\n        TypedConstant cst = (TypedConstant) pool.get(idx);\n        Attribute result = new AttConstantValue(cst);\n\n        if (observer != null) {\n            observer.parsed(bytes, offset, 2, \"value: \" + cst);\n        }\n\n        return result;\n    }\n\n    /**\n     * Parses a {@code Deprecated} attribute.\n     */\n    private Attribute deprecated(DirectClassFile cf, int offset, int length,\n            ParseObserver observer) {\n        if (length != 0) {\n            return throwBadLength(0);\n        }\n\n        return new AttDeprecated();\n    }\n\n    /**\n     * Parses an {@code EnclosingMethod} attribute.\n     */\n    private Attribute enclosingMethod(DirectClassFile cf, int offset,\n            int length, ParseObserver observer) {\n        if (length != 4) {\n            throwBadLength(4);\n        }\n\n        ByteArray bytes = cf.getBytes();\n        ConstantPool pool = cf.getConstantPool();\n\n        int idx = bytes.getUnsignedShort(offset);\n        CstType type = (CstType) pool.get(idx);\n\n        idx = bytes.getUnsignedShort(offset + 2);\n        CstNat method = (CstNat) pool.get0Ok(idx);\n\n        Attribute result = new AttEnclosingMethod(type, method);\n\n        if (observer != null) {\n            observer.parsed(bytes, offset, 2, \"class: \" + type);\n            observer.parsed(bytes, offset + 2, 2, \"method: \" +\n                            DirectClassFile.stringOrNone(method));\n        }\n\n        return result;\n    }\n\n    /**\n     * Parses an {@code Exceptions} attribute.\n     */\n    private Attribute exceptions(DirectClassFile cf, int offset, int length,\n            ParseObserver observer) {\n        if (length < 2) {\n            return throwSeverelyTruncated();\n        }\n\n        ByteArray bytes = cf.getBytes();\n        int count = bytes.getUnsignedShort(offset); // number_of_exceptions\n\n        if (observer != null) {\n            observer.parsed(bytes, offset, 2,\n                            \"number_of_exceptions: \" + Hex.u2(count));\n        }\n\n        offset += 2;\n        length -= 2;\n\n        if (length != (count * 2)) {\n            throwBadLength((count * 2) + 2);\n        }\n\n        TypeList list = cf.makeTypeList(offset, count);\n        return new AttExceptions(list);\n    }\n\n    /**\n     * Parses an {@code InnerClasses} attribute.\n     */\n    private Attribute innerClasses(DirectClassFile cf, int offset, int length,\n            ParseObserver observer) {\n        if (length < 2) {\n            return throwSeverelyTruncated();\n        }\n\n        ByteArray bytes = cf.getBytes();\n        ConstantPool pool = cf.getConstantPool();\n        int count = bytes.getUnsignedShort(offset); // number_of_classes\n\n        if (observer != null) {\n            observer.parsed(bytes, offset, 2,\n                            \"number_of_classes: \" + Hex.u2(count));\n        }\n\n        offset += 2;\n        length -= 2;\n\n        if (length != (count * 8)) {\n            throwBadLength((count * 8) + 2);\n        }\n\n        InnerClassList list = new InnerClassList(count);\n\n        for (int i = 0; i < count; i++) {\n            int innerClassIdx = bytes.getUnsignedShort(offset);\n            int outerClassIdx = bytes.getUnsignedShort(offset + 2);\n            int nameIdx = bytes.getUnsignedShort(offset + 4);\n            int accessFlags = bytes.getUnsignedShort(offset + 6);\n            CstType innerClass = (CstType) pool.get(innerClassIdx);\n            CstType outerClass = (CstType) pool.get0Ok(outerClassIdx);\n            CstString name = (CstString) pool.get0Ok(nameIdx);\n            list.set(i, innerClass, outerClass, name, accessFlags);\n            if (observer != null) {\n                observer.parsed(bytes, offset, 2,\n                                \"inner_class: \" +\n                                DirectClassFile.stringOrNone(innerClass));\n                observer.parsed(bytes, offset + 2, 2,\n                                \"  outer_class: \" +\n                                DirectClassFile.stringOrNone(outerClass));\n                observer.parsed(bytes, offset + 4, 2,\n                                \"  name: \" +\n                                DirectClassFile.stringOrNone(name));\n                observer.parsed(bytes, offset + 6, 2,\n                                \"  access_flags: \" +\n                                AccessFlags.innerClassString(accessFlags));\n            }\n            offset += 8;\n        }\n\n        list.setImmutable();\n        return new AttInnerClasses(list);\n    }\n\n    /**\n     * Parses a {@code LineNumberTable} attribute.\n     */\n    private Attribute lineNumberTable(DirectClassFile cf, int offset,\n            int length, ParseObserver observer) {\n        if (length < 2) {\n            return throwSeverelyTruncated();\n        }\n\n        ByteArray bytes = cf.getBytes();\n        int count = bytes.getUnsignedShort(offset); // line_number_table_length\n\n        if (observer != null) {\n            observer.parsed(bytes, offset, 2,\n                            \"line_number_table_length: \" + Hex.u2(count));\n        }\n\n        offset += 2;\n        length -= 2;\n\n        if (length != (count * 4)) {\n            throwBadLength((count * 4) + 2);\n        }\n\n        LineNumberList list = new LineNumberList(count);\n\n        for (int i = 0; i < count; i++) {\n            int startPc = bytes.getUnsignedShort(offset);\n            int lineNumber = bytes.getUnsignedShort(offset + 2);\n            list.set(i, startPc, lineNumber);\n            if (observer != null) {\n                observer.parsed(bytes, offset, 4,\n                                Hex.u2(startPc) + \" \" + lineNumber);\n            }\n            offset += 4;\n        }\n\n        list.setImmutable();\n        return new AttLineNumberTable(list);\n    }\n\n    /**\n     * Parses a {@code LocalVariableTable} attribute.\n     */\n    private Attribute localVariableTable(DirectClassFile cf, int offset,\n            int length, ParseObserver observer) {\n        if (length < 2) {\n            return throwSeverelyTruncated();\n        }\n\n        ByteArray bytes = cf.getBytes();\n        int count = bytes.getUnsignedShort(offset);\n\n        if (observer != null) {\n            observer.parsed(bytes, offset, 2,\n                    \"local_variable_table_length: \" + Hex.u2(count));\n        }\n\n        LocalVariableList list = parseLocalVariables(\n                bytes.slice(offset + 2, offset + length), cf.getConstantPool(),\n                observer, count, false);\n        return new AttLocalVariableTable(list);\n    }\n\n    /**\n     * Parses a {@code LocalVariableTypeTable} attribute.\n     */\n    private Attribute localVariableTypeTable(DirectClassFile cf, int offset,\n            int length, ParseObserver observer) {\n        if (length < 2) {\n            return throwSeverelyTruncated();\n        }\n\n        ByteArray bytes = cf.getBytes();\n        int count = bytes.getUnsignedShort(offset);\n\n        if (observer != null) {\n            observer.parsed(bytes, offset, 2,\n                    \"local_variable_type_table_length: \" + Hex.u2(count));\n        }\n\n        LocalVariableList list = parseLocalVariables(\n                bytes.slice(offset + 2, offset + length), cf.getConstantPool(),\n                observer, count, true);\n        return new AttLocalVariableTypeTable(list);\n    }\n\n    /**\n     * Parse the table part of either a {@code LocalVariableTable}\n     * or a {@code LocalVariableTypeTable}.\n     *\n     * @param bytes {@code non-null;} bytes to parse, which should <i>only</i>\n     * contain the table data (no header)\n     * @param pool {@code non-null;} constant pool to use\n     * @param count {@code >= 0;} the number of entries\n     * @param typeTable {@code true} iff this is for a type table\n     * @return {@code non-null;} the constructed list\n     */\n    private LocalVariableList parseLocalVariables(ByteArray bytes,\n            ConstantPool pool, ParseObserver observer, int count,\n            boolean typeTable) {\n        if (bytes.size() != (count * 10)) {\n            // \"+ 2\" is for the count.\n            throwBadLength((count * 10) + 2);\n        }\n\n        ByteArray.MyDataInputStream in = bytes.makeDataInputStream();\n        LocalVariableList list = new LocalVariableList(count);\n\n        try {\n            for (int i = 0; i < count; i++) {\n                int startPc = in.readUnsignedShort();\n                int length = in.readUnsignedShort();\n                int nameIdx = in.readUnsignedShort();\n                int typeIdx = in.readUnsignedShort();\n                int index = in.readUnsignedShort();\n                CstString name = (CstString) pool.get(nameIdx);\n                CstString type = (CstString) pool.get(typeIdx);\n                CstString descriptor = null;\n                CstString signature = null;\n\n                if (typeTable) {\n                    signature = type;\n                } else {\n                    descriptor = type;\n                }\n\n                list.set(i, startPc, length, name,\n                        descriptor, signature, index);\n\n                if (observer != null) {\n                    observer.parsed(bytes, i * 10, 10, Hex.u2(startPc) +\n                            \"..\" + Hex.u2(startPc + length) + \" \" +\n                            Hex.u2(index) + \" \" + name.toHuman() + \" \" +\n                            type.toHuman());\n                }\n            }\n        } catch (IOException ex) {\n            throw new RuntimeException(\"shouldn't happen\", ex);\n        }\n\n        list.setImmutable();\n        return list;\n    }\n\n    /**\n     * Parses a {@code RuntimeInvisibleAnnotations} attribute.\n     */\n    private Attribute runtimeInvisibleAnnotations(DirectClassFile cf,\n            int offset, int length, ParseObserver observer) {\n        if (length < 2) {\n            throwSeverelyTruncated();\n        }\n\n        AnnotationParser ap =\n            new AnnotationParser(cf, offset, length, observer);\n        Annotations annotations =\n            ap.parseAnnotationAttribute(AnnotationVisibility.BUILD);\n\n        return new AttRuntimeInvisibleAnnotations(annotations, length);\n    }\n\n    /**\n     * Parses a {@code RuntimeVisibleAnnotations} attribute.\n     */\n    private Attribute runtimeVisibleAnnotations(DirectClassFile cf,\n            int offset, int length, ParseObserver observer) {\n        if (length < 2) {\n            throwSeverelyTruncated();\n        }\n\n        AnnotationParser ap =\n            new AnnotationParser(cf, offset, length, observer);\n        Annotations annotations =\n            ap.parseAnnotationAttribute(AnnotationVisibility.RUNTIME);\n\n        return new AttRuntimeVisibleAnnotations(annotations, length);\n    }\n\n    /**\n     * Parses a {@code RuntimeInvisibleParameterAnnotations} attribute.\n     */\n    private Attribute runtimeInvisibleParameterAnnotations(DirectClassFile cf,\n            int offset, int length, ParseObserver observer) {\n        if (length < 2) {\n            throwSeverelyTruncated();\n        }\n\n        AnnotationParser ap =\n            new AnnotationParser(cf, offset, length, observer);\n        AnnotationsList list =\n            ap.parseParameterAttribute(AnnotationVisibility.BUILD);\n\n        return new AttRuntimeInvisibleParameterAnnotations(list, length);\n    }\n\n    /**\n     * Parses a {@code RuntimeVisibleParameterAnnotations} attribute.\n     */\n    private Attribute runtimeVisibleParameterAnnotations(DirectClassFile cf,\n            int offset, int length, ParseObserver observer) {\n        if (length < 2) {\n            throwSeverelyTruncated();\n        }\n\n        AnnotationParser ap =\n            new AnnotationParser(cf, offset, length, observer);\n        AnnotationsList list =\n            ap.parseParameterAttribute(AnnotationVisibility.RUNTIME);\n\n        return new AttRuntimeVisibleParameterAnnotations(list, length);\n    }\n\n    /**\n     * Parses a {@code Signature} attribute.\n     */\n    private Attribute signature(DirectClassFile cf, int offset, int length,\n            ParseObserver observer) {\n        if (length != 2) {\n            throwBadLength(2);\n        }\n\n        ByteArray bytes = cf.getBytes();\n        ConstantPool pool = cf.getConstantPool();\n        int idx = bytes.getUnsignedShort(offset);\n        CstString cst = (CstString) pool.get(idx);\n        Attribute result = new AttSignature(cst);\n\n        if (observer != null) {\n            observer.parsed(bytes, offset, 2, \"signature: \" + cst);\n        }\n\n        return result;\n    }\n\n    /**\n     * Parses a {@code SourceFile} attribute.\n     */\n    private Attribute sourceFile(DirectClassFile cf, int offset, int length,\n            ParseObserver observer) {\n        if (length != 2) {\n            throwBadLength(2);\n        }\n\n        ByteArray bytes = cf.getBytes();\n        ConstantPool pool = cf.getConstantPool();\n        int idx = bytes.getUnsignedShort(offset);\n        CstString cst = (CstString) pool.get(idx);\n        Attribute result = new AttSourceFile(cst);\n\n        if (observer != null) {\n            observer.parsed(bytes, offset, 2, \"source: \" + cst);\n        }\n\n        return result;\n    }\n\n    /**\n     * Parses a {@code Synthetic} attribute.\n     */\n    private Attribute synthetic(DirectClassFile cf, int offset, int length,\n            ParseObserver observer) {\n        if (length != 0) {\n            return throwBadLength(0);\n        }\n\n        return new AttSynthetic();\n    }\n\n    /**\n     * Throws the right exception when a known attribute has a way too short\n     * length.\n     *\n     * @return never\n     * @throws ParseException always thrown\n     */\n    private static Attribute throwSeverelyTruncated() {\n        throw new ParseException(\"severely truncated attribute\");\n    }\n\n    /**\n     * Throws the right exception when a known attribute has a too short\n     * length.\n     *\n     * @return never\n     * @throws ParseException always thrown\n     */\n    private static Attribute throwTruncated() {\n        throw new ParseException(\"truncated attribute\");\n    }\n\n    /**\n     * Throws the right exception when an attribute has an unexpected length\n     * (given its contents).\n     *\n     * @param expected expected length\n     * @return never\n     * @throws ParseException always thrown\n     */\n    private static Attribute throwBadLength(int expected) {\n        throw new ParseException(\"bad attribute length; expected length \" +\n                                 Hex.u4(expected));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/direct/package.html",
    "content": "<body>\n<p>Implementation of <code>cf.iface.*</code> based on a direct representation\nof class files as <code>byte[]</code>s.</p>\n\n<p><b>PACKAGES USED:</b>\n<ul>\n<li><code>com.taobao.android.dx.cf.attrib</code></li>\n<li><code>com.taobao.android.dx.cf.iface</code></li>\n<li><code>com.taobao.android.dx.rop.pool</code></li>\n<li><code>com.taobao.android.dx.util</code></li>\n</ul>\n</body>\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/Attribute.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\n/**\n * Interface representing attributes of class files (directly or indirectly).\n */\npublic interface Attribute {\n    /**\n     * Get the name of the attribute.\n     *\n     * @return {@code non-null;} the name\n     */\n    public String getName();\n\n    /**\n     * Get the total length of the attribute in bytes, including the\n     * header. Since the header is always six bytes, the result of\n     * this method is always at least {@code 6}.\n     *\n     * @return {@code >= 6;} the total length, in bytes\n     */\n    public int byteLength();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/AttributeList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\n/**\n * Interface for lists of attributes.\n */\npublic interface AttributeList {\n    /**\n     * Get whether this instance is mutable. Note that the\n     * {@code AttributeList} interface itself doesn't provide any means\n     * of mutation, but that doesn't mean that there isn't a non-interface\n     * way of mutating an instance.\n     *\n     * @return {@code true} iff this instance is somehow mutable\n     */\n    public boolean isMutable();\n\n    /**\n     * Get the number of attributes in the list.\n     *\n     * @return the size\n     */\n    public int size();\n\n    /**\n     * Get the {@code n}th attribute.\n     *\n     * @param n {@code n >= 0, n < size();} which attribute\n     * @return {@code non-null;} the attribute in question\n     */\n    public Attribute get(int n);\n\n    /**\n     * Get the total length of this list in bytes, when part of a\n     * class file. The returned value includes the two bytes for the\n     * {@code attributes_count} length indicator.\n     *\n     * @return {@code >= 2;} the total length, in bytes\n     */\n    public int byteLength();\n\n    /**\n     * Get the first attribute in the list with the given name, if any.\n     *\n     * @param name {@code non-null;} attribute name\n     * @return {@code null-ok;} first attribute in the list with the given name,\n     * or {@code null} if there is none\n     */\n    public Attribute findFirst(String name);\n\n    /**\n     * Get the next attribute in the list after the given one, with the same\n     * name, if any.\n     *\n     * @param attrib {@code non-null;} attribute to start looking after\n     * @return {@code null-ok;} next attribute after {@code attrib} with the\n     * same name as {@code attrib}\n     */\n    public Attribute findNext(Attribute attrib);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/ClassFile.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\nimport com.taobao.android.dx.rop.cst.ConstantPool;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.TypeList;\n\n/**\n * Interface for things which purport to be class files or reasonable\n * facsimiles thereof.\n *\n * <p><b>Note:</b> The fields referred to in this documentation are of the\n * {@code ClassFile} structure defined in vmspec-2 sec4.1.\n */\npublic interface ClassFile extends HasAttribute {\n    /**\n     * Gets the field {@code magic}.\n     *\n     * @return the value in question\n     */\n    public int getMagic();\n\n    /**\n     * Gets the field {@code minor_version}.\n     *\n     * @return the value in question\n     */\n    public int getMinorVersion();\n\n    /**\n     * Gets the field {@code major_version}.\n     *\n     * @return the value in question\n     */\n    public int getMajorVersion();\n\n    /**\n     * Gets the field {@code access_flags}.\n     *\n     * @return the value in question\n     */\n    public int getAccessFlags();\n\n    /**\n     * Gets the field {@code this_class}, interpreted as a type constant.\n     *\n     * @return {@code non-null;} the value in question\n     */\n    public CstType getThisClass();\n\n    /**\n     * Gets the field {@code super_class}, interpreted as a type constant\n     * if non-zero.\n     *\n     * @return {@code null-ok;} the value in question\n     */\n    public CstType getSuperclass();\n\n    /**\n     * Gets the field {@code constant_pool} (along with\n     * {@code constant_pool_count}).\n     *\n     * @return {@code non-null;} the constant pool\n     */\n    public ConstantPool getConstantPool();\n\n    /**\n     * Gets the field {@code interfaces} (along with\n     * {@code interfaces_count}).\n     *\n     * @return {@code non-null;} the list of interfaces\n     */\n    public TypeList getInterfaces();\n\n    /**\n     * Gets the field {@code fields} (along with\n     * {@code fields_count}).\n     *\n     * @return {@code non-null;} the list of fields\n     */\n    public FieldList getFields();\n\n    /**\n     * Gets the field {@code methods} (along with\n     * {@code methods_count}).\n     *\n     * @return {@code non-null;} the list of fields\n     */\n    public MethodList getMethods();\n\n    /**\n     * Gets the field {@code attributes} (along with\n     * {@code attributes_count}).\n     *\n     * @return {@code non-null;} the list of attributes\n     */\n    public AttributeList getAttributes();\n\n    /**\n     * Gets the name out of the {@code SourceFile} attribute of this\n     * file, if any. This is a convenient shorthand for scrounging around\n     * the class's attributes.\n     *\n     * @return {@code non-null;} the constant pool\n     */\n    public CstString getSourceFile();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/Field.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\nimport com.taobao.android.dx.rop.cst.TypedConstant;\n\n/**\n * Interface representing fields of class files.\n */\npublic interface Field\n        extends Member {\n    /**\n     * Get the constant value for this field, if any. This only returns\n     * non-{@code null} for a {@code static final} field which\n     * includes a {@code ConstantValue} attribute.\n     *\n     * @return {@code null-ok;} the constant value, or {@code null} if this\n     * field isn't a constant\n     */\n    public TypedConstant getConstantValue();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/FieldList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\n/**\n * Interface for lists of fields.\n */\npublic interface FieldList\n{\n    /**\n     * Get whether this instance is mutable. Note that the\n     * {@code FieldList} interface itself doesn't provide any means\n     * of mutation, but that doesn't mean that there isn't a non-interface\n     * way of mutating an instance.\n     *\n     * @return {@code true} iff this instance is somehow mutable\n     */\n    public boolean isMutable();\n\n    /**\n     * Get the number of fields in the list.\n     *\n     * @return the size\n     */\n    public int size();\n\n    /**\n     * Get the {@code n}th field.\n     *\n     * @param n {@code n >= 0, n < size();} which field\n     * @return {@code non-null;} the field in question\n     */\n    public Field get(int n);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/HasAttribute.java",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\n/**\n * An element that can have {@link Attribute}\n */\npublic interface HasAttribute {\n\n    /**\n     * Get the element {@code attributes} (along with\n     * {@code attributes_count}).\n     *\n     * @return {@code non-null;} the attributes list\n     */\n    public AttributeList getAttributes();\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/Member.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\n\n/**\n * Interface representing members of class files (that is, fields and methods).\n */\npublic interface Member extends HasAttribute {\n    /**\n     * Get the defining class.\n     *\n     * @return {@code non-null;} the defining class\n     */\n    public CstType getDefiningClass();\n\n    /**\n     * Get the field {@code access_flags}.\n     *\n     * @return the access flags\n     */\n    public int getAccessFlags();\n\n    /**\n     * Get the field {@code name_index} of the member. This is\n     * just a convenient shorthand for {@code getNat().getName()}.\n     *\n     * @return {@code non-null;} the name\n     */\n    public CstString getName();\n\n    /**\n     * Get the field {@code descriptor_index} of the member. This is\n     * just a convenient shorthand for {@code getNat().getDescriptor()}.\n     *\n     * @return {@code non-null;} the descriptor\n     */\n    public CstString getDescriptor();\n\n    /**\n     * Get the name and type associated with this member. This is a\n     * combination of the fields {@code name_index} and\n     * {@code descriptor_index} in the original classfile, interpreted\n     * via the constant pool.\n     *\n     * @return {@code non-null;} the name and type\n     */\n    public CstNat getNat();\n\n    /**\n     * Get the field {@code attributes} (along with\n     * {@code attributes_count}).\n     *\n     * @return {@code non-null;} the constant pool\n     */\n    public AttributeList getAttributes();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/Method.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\nimport com.taobao.android.dx.rop.type.Prototype;\n\n/**\n * Interface representing methods of class files.\n */\npublic interface Method\n    extends Member\n{\n    /**\n     * Get the <i>effective</i> method descriptor, which includes, if\n     * necessary, a first {@code this} parameter.\n     *\n     * @return {@code non-null;} the effective method descriptor\n     */\n    public Prototype getEffectiveDescriptor();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/MethodList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\n/**\n * Interface for lists of methods.\n */\npublic interface MethodList {\n    /**\n     * Get whether this instance is mutable. Note that the\n     * {@code MethodList} interface itself doesn't provide any means\n     * of mutation, but that doesn't mean that there isn't a non-interface\n     * way of mutating an instance.\n     *\n     * @return {@code true} iff this instance is somehow mutable\n     */\n    public boolean isMutable();\n\n    /**\n     * Get the number of methods in the list.\n     *\n     * @return the size\n     */\n    public int size();\n\n    /**\n     * Get the {@code n}th method.\n     *\n     * @param n {@code n >= 0, n < size();} which method\n     * @return {@code non-null;} the method in question\n     */\n    public Method get(int n);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/ParseException.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\n\n/**\n * Exception from parsing.\n */\npublic class ParseException\n        extends ExceptionWithContext {\n    public ParseException(String message) {\n        super(message);\n    }\n\n    public ParseException(Throwable cause) {\n        super(cause);\n    }\n\n    public ParseException(String message, Throwable cause) {\n        super(message, cause);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/ParseObserver.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\nimport com.taobao.android.dx.util.ByteArray;\n\n/**\n * Observer of parsing in action. This is used to supply feedback from\n * the various things that parse particularly to the dumping utilities.\n */\npublic interface ParseObserver {\n    /**\n     * Indicate that the level of indentation for a dump should increase\n     * or decrease (positive or negative argument, respectively).\n     *\n     * @param indentDelta the amount to change indentation\n     */\n    public void changeIndent(int indentDelta);\n\n    /**\n     * Indicate that a particular member is now being parsed.\n     *\n     * @param bytes {@code non-null;} the source that is being parsed\n     * @param offset offset into {@code bytes} for the start of the\n     * member\n     * @param name {@code non-null;} name of the member\n     * @param descriptor {@code non-null;} descriptor of the member\n     */\n    public void startParsingMember(ByteArray bytes, int offset, String name,\n                                   String descriptor);\n\n    /**\n     * Indicate that a particular member is no longer being parsed.\n     *\n     * @param bytes {@code non-null;} the source that was parsed\n     * @param offset offset into {@code bytes} for the end of the\n     * member\n     * @param name {@code non-null;} name of the member\n     * @param descriptor {@code non-null;} descriptor of the member\n     * @param member {@code non-null;} the actual member that was parsed\n     */\n    public void endParsingMember(ByteArray bytes, int offset, String name,\n                                 String descriptor, Member member);\n\n    /**\n     * Indicate that some parsing happened.\n     *\n     * @param bytes {@code non-null;} the source that was parsed\n     * @param offset offset into {@code bytes} for what was parsed\n     * @param len number of bytes parsed\n     * @param human {@code non-null;} human form for what was parsed\n     */\n    public void parsed(ByteArray bytes, int offset, int len, String human);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/StdAttributeList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\nimport com.taobao.android.dx.util.FixedSizeList;\n\n/**\n * Standard implementation of {@link AttributeList}, which directly stores\n * an array of {@link Attribute} objects and can be made immutable.\n */\npublic final class StdAttributeList extends FixedSizeList\n        implements AttributeList {\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size the size of the list\n     */\n    public StdAttributeList(int size) {\n        super(size);\n    }\n\n    /** {@inheritDoc} */\n    public Attribute get(int n) {\n        return (Attribute) get0(n);\n    }\n\n    /** {@inheritDoc} */\n    public int byteLength() {\n        int sz = size();\n        int result = 2; // u2 attributes_count\n\n        for (int i = 0; i < sz; i++) {\n            result += get(i).byteLength();\n        }\n\n        return result;\n    }\n\n    /** {@inheritDoc} */\n    public Attribute findFirst(String name) {\n        int sz = size();\n\n        for (int i = 0; i < sz; i++) {\n            Attribute att = get(i);\n            if (att.getName().equals(name)) {\n                return att;\n            }\n        }\n\n        return null;\n    }\n\n    /** {@inheritDoc} */\n    public Attribute findNext(Attribute attrib) {\n        int sz = size();\n        int at;\n\n        outer: {\n            for (at = 0; at < sz; at++) {\n                Attribute att = get(at);\n                if (att == attrib) {\n                    break outer;\n                }\n            }\n\n            return null;\n        }\n\n        String name = attrib.getName();\n\n        for (at++; at < sz; at++) {\n            Attribute att = get(at);\n            if (att.getName().equals(name)) {\n                return att;\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Sets the attribute at the given index.\n     *\n     * @param n {@code >= 0, < size();} which attribute\n     * @param attribute {@code null-ok;} the attribute object\n     */\n    public void set(int n, Attribute attribute) {\n        set0(n, attribute);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/StdField.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\nimport com.taobao.android.dx.cf.attrib.AttConstantValue;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.cst.TypedConstant;\n\n/**\n * Standard implementation of {@link Field}, which directly stores\n * all the associated data.\n */\npublic final class StdField extends StdMember implements Field {\n    /**\n     * Constructs an instance.\n     *\n     * @param definingClass {@code non-null;} the defining class\n     * @param accessFlags access flags\n     * @param nat {@code non-null;} member name and type (descriptor)\n     * @param attributes {@code non-null;} list of associated attributes\n     */\n    public StdField(CstType definingClass, int accessFlags, CstNat nat,\n                    AttributeList attributes) {\n        super(definingClass, accessFlags, nat, attributes);\n    }\n\n    /** {@inheritDoc} */\n    public TypedConstant getConstantValue() {\n        AttributeList attribs = getAttributes();\n        AttConstantValue cval = (AttConstantValue)\n            attribs.findFirst(AttConstantValue.ATTRIBUTE_NAME);\n\n        if (cval == null) {\n            return null;\n        }\n\n        return cval.getConstantValue();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/StdFieldList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\nimport com.taobao.android.dx.util.FixedSizeList;\n\n/**\n * Standard implementation of {@link FieldList}, which directly stores\n * an array of {@link Field} objects and can be made immutable.\n */\npublic final class StdFieldList extends FixedSizeList implements FieldList {\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size the size of the list\n     */\n    public StdFieldList(int size) {\n        super(size);\n    }\n\n    /** {@inheritDoc} */\n    public Field get(int n) {\n        return (Field) get0(n);\n    }\n\n    /**\n     * Sets the field at the given index.\n     *\n     * @param n {@code >= 0, < size();} which field\n     * @param field {@code null-ok;} the field object\n     */\n    public void set(int n, Field field) {\n        set0(n, field);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/StdMember.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\n\n/**\n * Standard implementation of {@link Member}, which directly stores\n * all the associated data.\n */\npublic abstract class StdMember implements Member {\n    /** {@code non-null;} the defining class */\n    private final CstType definingClass;\n\n    /** access flags */\n    private final int accessFlags;\n\n    /** {@code non-null;} member name and type */\n    private final CstNat nat;\n\n    /** {@code non-null;} list of associated attributes */\n    private final AttributeList attributes;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param definingClass {@code non-null;} the defining class\n     * @param accessFlags access flags\n     * @param nat {@code non-null;} member name and type (descriptor)\n     * @param attributes {@code non-null;} list of associated attributes\n     */\n    public StdMember(CstType definingClass, int accessFlags, CstNat nat,\n                     AttributeList attributes) {\n        if (definingClass == null) {\n            throw new NullPointerException(\"definingClass == null\");\n        }\n\n        if (nat == null) {\n            throw new NullPointerException(\"nat == null\");\n        }\n\n        if (attributes == null) {\n            throw new NullPointerException(\"attributes == null\");\n        }\n\n        this.definingClass = definingClass;\n        this.accessFlags = accessFlags;\n        this.nat = nat;\n        this.attributes = attributes;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        StringBuffer sb = new StringBuffer(100);\n\n        sb.append(getClass().getName());\n        sb.append('{');\n        sb.append(nat.toHuman());\n        sb.append('}');\n\n        return sb.toString();\n    }\n\n    /** {@inheritDoc} */\n    public final CstType getDefiningClass() {\n        return definingClass;\n    }\n\n    /** {@inheritDoc} */\n    public final int getAccessFlags() {\n        return accessFlags;\n    }\n\n    /** {@inheritDoc} */\n    public final CstNat getNat() {\n        return nat;\n    }\n\n    /** {@inheritDoc} */\n    public final CstString getName() {\n        return nat.getName();\n    }\n\n    /** {@inheritDoc} */\n    public final CstString getDescriptor() {\n        return nat.getDescriptor();\n    }\n\n    /** {@inheritDoc} */\n    public final AttributeList getAttributes() {\n        return attributes;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/StdMethod.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Prototype;\n\n/**\n * Standard implementation of {@link Method}, which directly stores\n * all the associated data.\n */\npublic final class StdMethod extends StdMember implements Method {\n    /** {@code non-null;} the effective method descriptor */\n    private final Prototype effectiveDescriptor;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param definingClass {@code non-null;} the defining class\n     * @param accessFlags access flags\n     * @param nat {@code non-null;} member name and type (descriptor)\n     * @param attributes {@code non-null;} list of associated attributes\n     */\n    public StdMethod(CstType definingClass, int accessFlags, CstNat nat,\n            AttributeList attributes) {\n        super(definingClass, accessFlags, nat, attributes);\n\n        String descStr = getDescriptor().getString();\n        effectiveDescriptor =\n            Prototype.intern(descStr, definingClass.getClassType(),\n                                    AccessFlags.isStatic(accessFlags),\n                                    nat.isInstanceInit());\n    }\n\n    /** {@inheritDoc} */\n    public Prototype getEffectiveDescriptor() {\n        return effectiveDescriptor;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/StdMethodList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.cf.iface;\n\nimport com.taobao.android.dx.util.FixedSizeList;\n\n/**\n * Standard implementation of {@link MethodList}, which directly stores\n * an array of {@link Method} objects and can be made immutable.\n */\npublic final class StdMethodList extends FixedSizeList implements MethodList {\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size the size of the list\n     */\n    public StdMethodList(int size) {\n        super(size);\n    }\n\n    /** {@inheritDoc} */\n    public Method get(int n) {\n        return (Method) get0(n);\n    }\n\n    /**\n     * Sets the method at the given index.\n     *\n     * @param n {@code >= 0, < size();} which method\n     * @param method {@code null-ok;} the method object\n     */\n    public void set(int n, Method method) {\n        set0(n, method);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/cf/iface/package.html",
    "content": "<body>\n<p>Interfaces and base classes for dealing with class files. This package\ndoesn't have any parsing but does have basic container implementations.</p>\n\n<p><b>PACKAGES USED:</b>\n<ul>\n<li><code>com.taobao.android.dx.rop.pool</code></li>\n<li><code>com.taobao.android.dx.util</code></li>\n</ul>\n</body>\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/DxConsole.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.io.PrintStream;\n\n/**\n * Provides standard and error PrintStream object to output information.<br>\n * By default the PrintStream objects link to {@code System.out} and\n * {@code System.err} but they can be changed to link to other\n * PrintStream.\n */\npublic class DxConsole {\n    /**\n     * Standard output stream. Links to {@code System.out} by default.\n     */\n    public static PrintStream out = System.out;\n\n    /**\n     * Error output stream. Links to {@code System.err} by default.\n     */\n    public static PrintStream err = System.err;\n\n    /**\n     * Output stream which prints to nowhere.\n     */\n    public static final PrintStream noop = new PrintStream(new OutputStream() {\n\n        @Override\n        public void write(int b) throws IOException {\n            // noop\n        }\n    });\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/Main.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command;\n\nimport com.taobao.android.dx.Version;\n\n/**\n * Main class for dx. It recognizes enough options to be able to dispatch\n * to the right \"actual\" main.\n */\npublic class Main {\n    private static String USAGE_MESSAGE =\n        \"usage:\\n\" +\n        \"  dx --dex [--debug] [--verbose] [--positions=<style>] \" +\n        \"[--no-locals]\\n\" +\n        \"  [--no-optimize] [--statistics] [--[no-]optimize-list=<file>] \" +\n        \"[--no-strict]\\n\" +\n        \"  [--keep-classes] [--output=<file>] [--dump-to=<file>] \" +\n        \"[--dump-width=<n>]\\n\" +\n        \"  [--dump-method=<name>[*]] [--verbose-dump] [--no-files] \" +\n        \"[--core-library]\\n\" +\n        \"  [--num-threads=<n>] [--incremental] [--force-jumbo] [--no-warning]\\n\" +\n        \"  [--multi-dex [--main-dex-list=<file> [--minimal-main-dex]]\\n\" +\n        \"  [--input-list=<file>]\\n\" +\n        \"  [<file>.class | <file>.{zip,jar,apk} | <directory>] ...\\n\" +\n        \"    Convert a set of classfiles into a dex file, optionally \" +\n        \"embedded in a\\n\" +\n        \"    jar/zip. Output name must end with one of: .dex .jar \" +\n        \".zip .apk or be a directory.\\n\" +\n        \"    Positions options: none, important, lines.\\n\" +\n        \"    --multi-dex: allows to generate several dex files if needed. \" +\n        \"This option is \\n\" +\n        \"    exclusive with --incremental, causes --num-threads to be ignored \" +\n        \"and only\\n\" +\n        \"    supports folder or archive output.\\n\" +\n        \"    --main-dex-list=<file>: <file> is a list of class file names, \" +\n        \"classes defined by\\n\" +\n        \"    those class files are put in classes.dex.\\n\" +\n        \"    --minimal-main-dex: only classes selected by --main-dex-list are \" +\n        \"to be put in\\n\" +\n        \"    the main dex.\\n\" +\n        \"    --input-list: <file> is a list of inputs.\\n\" +\n        \"    Each line in <file> must end with one of: .class .jar .zip .apk or be a directory.\\n\" +\n        \"  dx --annotool --annotation=<class> [--element=<element types>]\\n\" +\n        \"  [--print=<print types>]\\n\" +\n        \"  dx --dump [--debug] [--strict] [--bytes] [--optimize]\\n\" +\n        \"  [--basic-blocks | --rop-blocks | --ssa-blocks | --dot] \" +\n        \"[--ssa-step=<step>]\\n\" +\n        \"  [--width=<n>] [<file>.class | <file>.txt] ...\\n\" +\n        \"    Dump classfiles, or transformations thereof, in a \" +\n        \"human-oriented format.\\n\" +\n        \"  dx --find-usages <file.dex> <declaring type> <member>\\n\" +\n        \"    Find references and declarations to a field or method.\\n\" +\n        \"    declaring type: a class name in internal form, like \" +\n        \"Ljava/lang/Object;\\n\" +\n        \"    member: a field or method name, like hashCode\\n\" +\n        \"  dx -J<option> ... <arguments, in one of the above \" +\n        \"forms>\\n\" +\n        \"    Pass VM-specific options to the virtual machine that \" +\n        \"runs dx.\\n\" +\n        \"  dx --version\\n\" +\n        \"    Print the version of this tool (\" + Version.VERSION +\n        \").\\n\" +\n        \"  dx --help\\n\" +\n        \"    Print this message.\";\n\n    /**\n     * This class is uninstantiable.\n     */\n    private Main() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Run!\n     */\n    public static void main(String[] args) {\n        boolean gotCmd = false;\n        boolean showUsage = false;\n\n        try {\n            for (int i = 0; i < args.length; i++) {\n                String arg = args[i];\n                if (arg.equals(\"--\") || !arg.startsWith(\"--\")) {\n                    gotCmd = false;\n                    showUsage = true;\n                    break;\n                }\n\n                gotCmd = true;\n                if (arg.equals(\"--dex\")) {\n                    new com.taobao.android.dx.command.dexer.Main().main(without(args, i));\n                    break;\n                } else if (arg.equals(\"--dump\")) {\n                    com.taobao.android.dx.command.dump.Main.main(without(args, i));\n                    break;\n                } else if (arg.equals(\"--annotool\")) {\n                    com.taobao.android.dx.command.annotool.Main.main(\n                            without(args, i));\n                    break;\n                } else if (arg.equals(\"--find-usages\")) {\n                    com.taobao.android.dx.command.findusages.Main.main(without(args, i));\n                    break;\n                } else if (arg.equals(\"--version\")) {\n                    version();\n                    break;\n                } else if (arg.equals(\"--help\")) {\n                    showUsage = true;\n                    break;\n                } else {\n                    gotCmd = false;\n                }\n            }\n        } catch (UsageException ex) {\n            showUsage = true;\n        } catch (RuntimeException ex) {\n            System.err.println(\"\\nUNEXPECTED TOP-LEVEL EXCEPTION:\");\n            ex.printStackTrace();\n            System.exit(2);\n        } catch (Throwable ex) {\n            System.err.println(\"\\nUNEXPECTED TOP-LEVEL ERROR:\");\n            ex.printStackTrace();\n            if ((ex instanceof NoClassDefFoundError)\n                    || (ex instanceof NoSuchMethodError)) {\n                System.err.println(\n                        \"Note: You may be using an incompatible \" +\n                        \"virtual machine or class library.\\n\" +\n                        \"(This program is known to be incompatible \" +\n                        \"with recent releases of GCJ.)\");\n            }\n            System.exit(3);\n        }\n\n        if (!gotCmd) {\n            System.err.println(\"error: no command specified\");\n            showUsage = true;\n        }\n\n        if (showUsage) {\n            usage();\n            System.exit(1);\n        }\n    }\n\n    /**\n     * Prints the version message.\n     */\n    private static void version() {\n        System.err.println(\"dx version \" + Version.VERSION);\n        System.exit(0);\n    }\n\n    /**\n     * Prints the usage message.\n     */\n    private static void usage() {\n        System.err.println(USAGE_MESSAGE);\n    }\n\n    /**\n     * Returns a copy of the given args array, but without the indicated\n     * element.\n     *\n     * @param orig {@code non-null;} original array\n     * @param n which element to omit\n     * @return {@code non-null;} new array\n     */\n    private static String[] without(String[] orig, int n) {\n        int len = orig.length - 1;\n        String[] newa = new String[len];\n        System.arraycopy(orig, 0, newa, 0, n);\n        System.arraycopy(orig, n + 1, newa, n, len - n);\n        return newa;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/UsageException.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command;\n\n/**\n * Simple exception class used to communicate that the command-line tool\n * should print the usage message.\n */\npublic class UsageException extends RuntimeException {\n    // This space intentionally left blank.\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/annotool/AnnotationLister.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command.annotool;\n\nimport com.taobao.android.dx.cf.attrib.AttRuntimeInvisibleAnnotations;\nimport com.taobao.android.dx.cf.attrib.AttRuntimeVisibleAnnotations;\nimport com.taobao.android.dx.cf.attrib.BaseAnnotations;\nimport com.taobao.android.dx.cf.direct.ClassPathOpener;\nimport com.taobao.android.dx.cf.direct.DirectClassFile;\nimport com.taobao.android.dx.cf.direct.StdAttributeFactory;\nimport com.taobao.android.dx.cf.iface.Attribute;\nimport com.taobao.android.dx.cf.iface.AttributeList;\nimport com.taobao.android.dx.rop.annotation.Annotation;\nimport com.taobao.android.dx.util.ByteArray;\nimport java.io.File;\nimport java.lang.annotation.ElementType;\nimport java.util.HashSet;\n\n/**\n * Greps annotations on a set of class files and prints matching elements\n * to stdout. What counts as a match and what should be printed is controlled\n * by the {@code Main.Arguments} instance.\n */\nclass AnnotationLister {\n    /**\n     * The string name of the pseudo-class that\n     * contains package-wide annotations\n     */\n    private static final String PACKAGE_INFO = \"package-info\";\n\n    /** current match configuration */\n    private final Main.Arguments args;\n\n    /** Set of classes whose inner classes should be considered matched */\n    HashSet<String> matchInnerClassesOf = new HashSet<String>();\n\n    /** set of packages whose classes should be considered matched */\n    HashSet<String> matchPackages = new HashSet<String>();\n\n    AnnotationLister (Main.Arguments args) {\n        this.args = args;\n    }\n\n    /** Processes based on configuration specified in constructor. */\n    void process() {\n        for (String path : args.files) {\n            ClassPathOpener opener;\n\n            opener = new ClassPathOpener(path, true,\n                    new ClassPathOpener.Consumer() {\n                public boolean processFileBytes(String name, long lastModified, byte[] bytes) {\n                    if (!name.endsWith(\".class\")) {\n                        return true;\n                    }\n\n                    ByteArray ba = new ByteArray(bytes);\n                    DirectClassFile cf\n                        = new DirectClassFile(ba, name, true);\n\n                    cf.setAttributeFactory(StdAttributeFactory.THE_ONE);\n                    AttributeList attributes = cf.getAttributes();\n                    Attribute att;\n\n                    String cfClassName\n                            = cf.getThisClass().getClassType().getClassName();\n\n                    if (cfClassName.endsWith(PACKAGE_INFO)) {\n                        att = attributes.findFirst(\n                                AttRuntimeInvisibleAnnotations.ATTRIBUTE_NAME);\n\n                        for (;att != null; att = attributes.findNext(att)) {\n                            BaseAnnotations ann = (BaseAnnotations)att;\n                            visitPackageAnnotation(cf, ann);\n                        }\n\n                        att = attributes.findFirst(\n                                AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME);\n\n                        for (;att != null; att = attributes.findNext(att)) {\n                            BaseAnnotations ann = (BaseAnnotations)att;\n                            visitPackageAnnotation(cf, ann);\n                        }\n                    } else if (isMatchingInnerClass(cfClassName)\n                            || isMatchingPackage(cfClassName)) {\n                        printMatch(cf);\n                    } else {\n                        att = attributes.findFirst(\n                                AttRuntimeInvisibleAnnotations.ATTRIBUTE_NAME);\n\n                        for (;att != null; att = attributes.findNext(att)) {\n                            BaseAnnotations ann = (BaseAnnotations)att;\n                            visitClassAnnotation(cf, ann);\n                        }\n\n                        att = attributes.findFirst(\n                                AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME);\n\n                        for (;att != null; att = attributes.findNext(att)) {\n                            BaseAnnotations ann = (BaseAnnotations)att;\n                            visitClassAnnotation(cf, ann);\n                        }\n                    }\n\n                    return true;\n                }\n\n                public void onException(Exception ex) {\n                    throw new RuntimeException(ex);\n                }\n\n                public void onProcessArchiveStart(File file) {\n\n                }\n\n            });\n\n            opener.process();\n        }\n    }\n\n    /**\n     * Inspects a class annotation.\n     *\n     * @param cf {@code non-null;} class file\n     * @param ann {@code non-null;} annotation\n     */\n    private void visitClassAnnotation(DirectClassFile cf,\n            BaseAnnotations ann) {\n\n        if (!args.eTypes.contains(ElementType.TYPE)) {\n            return;\n        }\n\n        for (Annotation anAnn : ann.getAnnotations().getAnnotations()) {\n            String annClassName\n                    = anAnn.getType().getClassType().getClassName();\n            if (args.aclass.equals(annClassName)) {\n                printMatch(cf);\n            }\n        }\n    }\n\n    /**\n     * Inspects a package annotation\n     *\n     * @param cf {@code non-null;} class file of \"package-info\" pseudo-class\n     * @param ann {@code non-null;} annotation\n     */\n    private void visitPackageAnnotation(\n            DirectClassFile cf, BaseAnnotations ann) {\n\n        if (!args.eTypes.contains(ElementType.PACKAGE)) {\n            return;\n        }\n\n        String packageName = cf.getThisClass().getClassType().getClassName();\n\n        int slashIndex = packageName.lastIndexOf('/');\n\n        if (slashIndex == -1) {\n            packageName = \"\";\n        } else {\n            packageName\n                    = packageName.substring(0, slashIndex);\n        }\n\n\n        for (Annotation anAnn : ann.getAnnotations().getAnnotations()) {\n            String annClassName\n                    = anAnn.getType().getClassType().getClassName();\n            if (args.aclass.equals(annClassName)) {\n                printMatchPackage(packageName);\n            }\n        }\n    }\n\n\n    /**\n     * Prints, or schedules for printing, elements related to a\n     * matching package.\n     *\n     * @param packageName {@code non-null;} name of package\n     */\n    private void printMatchPackage(String packageName) {\n        for (Main.PrintType pt : args.printTypes) {\n            switch (pt) {\n                case CLASS:\n                case INNERCLASS:\n                case METHOD:\n                    matchPackages.add(packageName);\n                    break;\n                case PACKAGE:\n                    System.out.println(packageName.replace('/','.'));\n                    break;\n            }\n        }\n    }\n\n    /**\n     * Prints, or schedules for printing, elements related to a matching\n     * class.\n     *\n     * @param cf {@code non-null;} matching class\n     */\n    private void printMatch(DirectClassFile cf) {\n        for (Main.PrintType pt : args.printTypes) {\n            switch (pt) {\n                case CLASS:\n                    String classname;\n                    classname =\n                        cf.getThisClass().getClassType().getClassName();\n                    classname = classname.replace('/','.');\n                    System.out.println(classname);\n                    break;\n                case INNERCLASS:\n                    matchInnerClassesOf.add(\n                            cf.getThisClass().getClassType().getClassName());\n                    break;\n                case METHOD:\n                    //TODO\n                    break;\n                case PACKAGE:\n                    break;\n            }\n        }\n    }\n\n    /**\n     * Checks to see if a specified class name should be considered a match\n     * due to previous matches.\n     *\n     * @param s {@code non-null;} class name\n     * @return true if this class should be considered a match\n     */\n    private boolean isMatchingInnerClass(String s) {\n        int i;\n\n        while (0 < (i = s.lastIndexOf('$'))) {\n            s = s.substring(0, i);\n            if (matchInnerClassesOf.contains(s)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Checks to see if a specified package should be considered a match due\n     * to previous matches.\n     *\n     * @param s {@code non-null;} package name\n     * @return true if this package should be considered a match\n     */\n    private boolean isMatchingPackage(String s) {\n        int slashIndex = s.lastIndexOf('/');\n\n        String packageName;\n        if (slashIndex == -1) {\n            packageName = \"\";\n        } else {\n            packageName\n                    = s.substring(0, slashIndex);\n        }\n\n        return matchPackages.contains(packageName);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/annotool/Main.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command.annotool;\n\nimport java.lang.annotation.ElementType;\nimport java.util.EnumSet;\nimport java.util.Locale;\n\npublic class Main {\n\n    private static class InvalidArgumentException extends Exception {\n        InvalidArgumentException() {\n            super();\n        }\n\n        InvalidArgumentException(String s) {\n            super(s);\n        }\n    }\n\n    enum PrintType {\n        CLASS,\n        INNERCLASS,\n        METHOD,\n        PACKAGE\n    }\n\n\n    static class Arguments {\n        /**\n         * from --annotation, dot-separated classname\n         * of annotation to look for\n         */\n        String aclass;\n\n        /** from --eTypes */\n        EnumSet<ElementType> eTypes = EnumSet.noneOf(ElementType.class);\n\n        /** from --print */\n        EnumSet<PrintType> printTypes = EnumSet.noneOf(PrintType.class);\n\n        /** remaining positional arguments */\n        String[] files;\n\n        Arguments() {\n        }\n\n        void parse (String[] argArray) throws InvalidArgumentException {\n            for (int i = 0; i < argArray.length; i++) {\n                String arg = argArray[i];\n\n                if (arg.startsWith(\"--annotation=\")) {\n                    String argParam = arg.substring(arg.indexOf('=') + 1);\n                    if (aclass != null) {\n                        throw new InvalidArgumentException(\n                                \"--annotation can only be specified once.\");\n                    }\n                    aclass = argParam.replace('.','/');\n                } else if (arg.startsWith(\"--element=\")) {\n                    String argParam = arg.substring(arg.indexOf('=') + 1);\n\n                    try {\n                        for (String p : argParam.split(\",\")) {\n                            eTypes.add(ElementType.valueOf(p.toUpperCase(Locale.ROOT)));\n                        }\n                    } catch (IllegalArgumentException ex) {\n                        throw new InvalidArgumentException(\n                                \"invalid --element\");\n                    }\n                } else if (arg.startsWith(\"--print=\")) {\n                    String argParam = arg.substring(arg.indexOf('=') + 1);\n\n                    try {\n                        for (String p : argParam.split(\",\")) {\n                            printTypes.add(PrintType.valueOf(p.toUpperCase(Locale.ROOT)));\n                        }\n                    } catch (IllegalArgumentException ex) {\n                        throw new InvalidArgumentException(\"invalid --print\");\n                    }\n                } else {\n                    files = new String[argArray.length - i];\n                    System.arraycopy(argArray, i, files, 0, files.length);\n                    break;\n                }\n            }\n\n            if (aclass == null) {\n                throw new InvalidArgumentException(\n                        \"--annotation must be specified\");\n            }\n\n            if (printTypes.isEmpty()) {\n                printTypes.add(PrintType.CLASS);\n            }\n\n            if (eTypes.isEmpty()) {\n                eTypes.add(ElementType.TYPE);\n            }\n\n            EnumSet<ElementType> set = eTypes.clone();\n\n            set.remove(ElementType.TYPE);\n            set.remove(ElementType.PACKAGE);\n            if (!set.isEmpty()) {\n                throw new InvalidArgumentException(\n                        \"only --element parameters 'type' and 'package' \"\n                                + \"supported\");\n            }\n        }\n    }\n\n    /**\n     * This class is uninstantiable.\n     */\n    private Main() {\n        // This space intentionally left blank.\n    }\n\n    public static void main(String[] argArray) {\n\n        final Arguments args = new Arguments();\n\n        try {\n            args.parse(argArray);\n        } catch (InvalidArgumentException ex) {\n            System.err.println(ex.getMessage());\n\n            throw new RuntimeException(\"usage\");\n        }\n\n        new AnnotationLister(args).process();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/dexer/Main.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command.dexer;\n\nimport com.taobao.android.dex.Dex;\nimport com.taobao.android.dex.DexException;\nimport com.taobao.android.dex.DexFormat;\nimport com.taobao.android.dex.util.FileUtils;\nimport com.taobao.android.dx.Version;\nimport com.taobao.android.dx.cf.code.SimException;\nimport com.taobao.android.dx.cf.direct.ClassPathOpener;\nimport com.taobao.android.dx.cf.direct.ClassPathOpener.FileNameFilter;\nimport com.taobao.android.dx.cf.direct.DirectClassFile;\nimport com.taobao.android.dx.cf.direct.StdAttributeFactory;\nimport com.taobao.android.dx.cf.iface.ParseException;\nimport com.taobao.android.dx.command.DxConsole;\nimport com.taobao.android.dx.command.UsageException;\nimport com.taobao.android.dx.dex.DexOptions;\nimport com.taobao.android.dx.dex.cf.CfOptions;\nimport com.taobao.android.dx.dex.cf.CfTranslator;\nimport com.taobao.android.dx.dex.code.PositionList;\nimport com.taobao.android.dx.dex.file.ClassDefItem;\nimport com.taobao.android.dx.dex.file.DexFile;\nimport com.taobao.android.dx.dex.file.EncodedMethod;\nimport com.taobao.android.dx.merge.CollisionPolicy;\nimport com.taobao.android.dx.merge.DexMerger;\nimport com.taobao.android.dx.rop.annotation.Annotation;\nimport com.taobao.android.dx.rop.annotation.Annotations;\nimport com.taobao.android.dx.rop.annotation.AnnotationsList;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstString;\n\nimport java.io.*;\nimport java.util.*;\nimport java.util.concurrent.*;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.jar.Attributes;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarOutputStream;\nimport java.util.jar.Manifest;\n\n/**\n * Main class for the class file translator.\n */\npublic class Main {\n\n    /**\n     * File extension of a {@code .dex} file.\n     */\n    private static final String DEX_EXTENSION = \".dex\";\n\n    /**\n     * File name prefix of a {@code .dex} file automatically loaded in an\n     * archive.\n     */\n    private static final String DEX_PREFIX = \"classes\";\n\n\n    private  List<Boolean>resultList = new ArrayList<>();\n\n    /**\n     * {@code non-null;} the lengthy message that tries to discourage\n     * people from defining core classes in applications\n     */\n    private static final String IN_RE_CORE_CLASSES =\n        \"Ill-advised or mistaken usage of a core class (java.* or javax.*)\\n\" +\n        \"when not building a core library.\\n\\n\" +\n        \"This is often due to inadvertently including a core library file\\n\" +\n        \"in your application's project, when using an IDE (such as\\n\" +\n        \"Eclipse). If you are sure you're not intentionally defining a\\n\" +\n        \"core class, then this is the most likely explanation of what's\\n\" +\n        \"going on.\\n\\n\" +\n        \"However, you might actually be trying to define a class in a core\\n\" +\n        \"namespace, the source of which you may have taken, for example,\\n\" +\n        \"from a non-Android virtual machine project. This will most\\n\" +\n        \"assuredly not work. At a minimum, it jeopardizes the\\n\" +\n        \"compatibility of your app with future versions of the platform.\\n\" +\n        \"It is also often of questionable legality.\\n\\n\" +\n        \"If you really intend to build a core library -- which is only\\n\" +\n        \"appropriate as part of creating a full virtual machine\\n\" +\n        \"distribution, as opposed to compiling an application -- then use\\n\" +\n        \"the \\\"--core-library\\\" option to suppress this error message.\\n\\n\" +\n        \"If you go ahead and use \\\"--core-library\\\" but are in fact\\n\" +\n        \"building an application, then be forewarned that your application\\n\" +\n        \"will still fail to build or run, at some point. Please be\\n\" +\n        \"prepared for angry customers who find, for example, that your\\n\" +\n        \"application ceases to function once they upgrade their operating\\n\" +\n        \"system. You will be to blame for this problem.\\n\\n\" +\n        \"If you are legitimately using some code that happens to be in a\\n\" +\n        \"core package, then the easiest safe alternative you have is to\\n\" +\n        \"repackage that code. That is, move the classes in question into\\n\" +\n        \"your own package namespace. This means that they will never be in\\n\" +\n        \"conflict with core system classes. JarJar is a tool that may help\\n\" +\n        \"you in this endeavor. If you find that you cannot do this, then\\n\" +\n        \"that is an indication that the path you are on will ultimately\\n\" +\n        \"lead to pain, suffering, grief, and lamentation.\\n\";\n\n    /**\n     * {@code non-null;} name of the standard manifest file in {@code .jar}\n     * files\n     */\n    private static final String MANIFEST_NAME = \"META-INF/MANIFEST.MF\";\n\n    /**\n     * {@code non-null;} attribute name for the (quasi-standard?)\n     * {@code Created-By} attribute\n     */\n    private static final Attributes.Name CREATED_BY =\n        new Attributes.Name(\"Created-By\");\n\n    /**\n     * {@code non-null;} list of {@code javax} subpackages that are considered\n     * to be \"core\". <b>Note:</b>: This list must be sorted, since it\n     * is binary-searched.\n     */\n    private static final String[] JAVAX_CORE = {\n        \"accessibility\", \"crypto\", \"imageio\", \"management\", \"naming\", \"net\",\n        \"print\", \"rmi\", \"security\", \"sip\", \"sound\", \"sql\", \"swing\",\n        \"transaction\", \"xml\"\n    };\n\n    /* Array.newInstance may be added by RopperMachine,\n     * ArrayIndexOutOfBoundsException.<init> may be added by EscapeAnalysis */\n    private static final int MAX_METHOD_ADDED_DURING_DEX_CREATION = 2;\n\n    /* <primitive types box class>.TYPE */\n    private static final int MAX_FIELD_ADDED_DURING_DEX_CREATION = 9;\n\n    /** number of errors during processing */\n    private  AtomicInteger errors = new AtomicInteger(0);\n\n    /** {@code non-null;} parsed command-line arguments */\n    private  Arguments args;\n\n    /** {@code non-null;} output file in-progress */\n    private  DexFile outputDex;\n\n    /**\n     * {@code null-ok;} map of resources to include in the output, or\n     * {@code null} if resources are being ignored\n     */\n    private  TreeMap<String, byte[]> outputResources;\n\n    /** Library .dex files to merge into the output .dex. */\n    private  final List<byte[]> libraryDexBuffers = new ArrayList<byte[]>();\n\n    /** Thread pool object used for multi-thread class translation. */\n    private  ExecutorService classTranslatorPool;\n\n    /** Single thread executor, for collecting results of parallel translation,\n     * and adding classes to dex file in original input file order. */\n    private  ExecutorService classDefItemConsumer;\n\n    /** Futures for {@code classDefItemConsumer} tasks. */\n    private  List<Future<Boolean>> addToDexFutures =\n            new ArrayList<Future<Boolean>>();\n\n    /** Thread pool object used for multi-thread dex conversion (to byte array).\n     * Used in combination with multi-dex support, to allow outputing\n     * a completed dex file, in parallel with continuing processing. */\n    private  ExecutorService dexOutPool;\n\n    /** Futures for {@code dexOutPool} task. */\n    private  List<Future<byte[]>> dexOutputFutures =\n            new ArrayList<Future<byte[]>>();\n\n    /** Lock object used to to coordinate dex file rotation, and\n     * multi-threaded translation. */\n    private  Object dexRotationLock = new Object();\n\n    /** Record the number if method indices \"reserved\" for files\n     * committed to translation in the context of the current dex\n     * file, but not yet added. */\n    private  int maxMethodIdsInProcess = 0;\n\n    /** Record the number if field indices \"reserved\" for files\n     * committed to translation in the context of the current dex\n     * file, but not yet added. */\n    private  int maxFieldIdsInProcess = 0;\n\n    /** true if any files are successfully processed */\n    private  volatile boolean anyFilesProcessed;\n\n    /** class files older than this must be defined in the target dex file. */\n    private static long minimumFileAge = 0;\n\n    private  Set<String> classesInMainDex = null;\n\n    private  List<byte[]> dexOutputArrays = new ArrayList<byte[]>();\n\n    private  OutputStreamWriter humanOutWriter = null;\n\n    /**\n     * This class is uninstantiable.\n     */\n    public Main() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Run and exit if something unexpected happened.\n     * @param argArray the command line arguments\n     */\n    public void main(String[] argArray) throws IOException {\n        Arguments arguments = new Arguments();\n        arguments.parse(argArray);\n\n        int result = run(arguments);\n        if (result != 0) {\n            System.exit(result);\n        }\n    }\n\n    /**\n     * Run and return a result code.\n     * @param arguments the data + parameters for the conversion\n     * @return 0 if success > 0 otherwise.\n     */\n    public int run(Arguments arguments) throws IOException {\n\n        // Reset the error count to start fresh.\n        errors.set(0);\n        // empty the list, so that  tools that load dx and keep it around\n        // for multiple runs don't reuse older buffers.\n        libraryDexBuffers.clear();\n\n        args = arguments;\n        args.makeOptionsObjects();\n\n        OutputStream humanOutRaw = null;\n        if (args.humanOutName != null) {\n            humanOutRaw = openOutput(args.humanOutName);\n            humanOutWriter = new OutputStreamWriter(humanOutRaw);\n        }\n\n        try {\n            if (args.multiDex) {\n                return runMultiDex();\n            } else {\n                return runMonoDex();\n            }\n        } finally {\n            closeOutput(humanOutRaw);\n        }\n    }\n\n    /**\n     * {@code non-null;} Error message for too many method/field/type ids.\n     */\n    public  String getTooManyIdsErrorMessage() {\n        if (args.multiDex) {\n            return \"The list of classes given in \" + Arguments.MAIN_DEX_LIST_OPTION +\n                   \" is too big and does not fit in the main dex.\";\n        } else {\n            return \"You may try using \" + Arguments.MULTI_DEX_OPTION + \" option.\";\n        }\n    }\n\n    private int runMonoDex() throws IOException {\n\n        File incrementalOutFile = null;\n        if (args.incremental) {\n            if (args.outName == null) {\n                System.err.println(\n                        \"error: no incremental output name specified\");\n                return -1;\n            }\n            incrementalOutFile = new File(args.outName);\n            if (incrementalOutFile.exists()) {\n                minimumFileAge = incrementalOutFile.lastModified();\n            }\n        }\n\n        if (!processAllFiles()) {\n            return 1;\n        }\n\n        if (args.incremental && !anyFilesProcessed) {\n            return 0; // this was a no-op incremental build\n        }\n\n        // this array is null if no classes were defined\n        byte[] outArray = null;\n\n        if (!outputDex.isEmpty() || (args.humanOutName != null)) {\n            outArray = writeDex(outputDex);\n\n            if (outArray == null) {\n                return 2;\n            }\n        }\n\n        if (args.incremental) {\n            outArray = mergeIncremental(outArray, incrementalOutFile);\n        }\n\n        outArray = mergeLibraryDexBuffers(outArray);\n\n        if (args.jarOutput) {\n            // Effectively free up the (often massive) DexFile memory.\n            outputDex = null;\n\n            if (outArray != null) {\n                outputResources.put(DexFormat.DEX_IN_JAR_NAME, outArray);\n            }\n            if (!createJar(args.outName)) {\n                return 3;\n            }\n        } else if (outArray != null && args.outName != null) {\n            OutputStream out = openOutput(args.outName);\n            out.write(outArray);\n            closeOutput(out);\n        }\n\n        return 0;\n    }\n\n    private  int runMultiDex() throws IOException {\n\n        assert !args.incremental;\n\n        if (args.mainDexListFile != null) {\n            classesInMainDex = new HashSet<String>();\n            readPathsFromFile(args.mainDexListFile, classesInMainDex);\n        }\n\n        dexOutPool = Executors.newFixedThreadPool(args.numThreads);\n\n        if (!processAllFiles()) {\n            return 1;\n        }\n\n        if (!libraryDexBuffers.isEmpty()) {\n            throw new DexException(\"Library dex files are not supported in multi-dex mode\");\n        }\n\n        if (outputDex != null) {\n            // this array is null if no classes were defined\n\n            dexOutputFutures.add(dexOutPool.submit(new DexWriter(outputDex)));\n\n            // Effectively free up the (often massive) DexFile memory.\n            outputDex = null;\n        }\n        try {\n            dexOutPool.shutdown();\n            if (!dexOutPool.awaitTermination(600L, TimeUnit.SECONDS)) {\n                throw new RuntimeException(\"Timed out waiting for dex writer threads.\");\n            }\n\n            for (Future<byte[]> f : dexOutputFutures) {\n                dexOutputArrays.add(f.get());\n            }\n\n        } catch (InterruptedException ex) {\n            dexOutPool.shutdownNow();\n            throw new RuntimeException(\"A dex writer thread has been interrupted.\");\n        } catch (Exception e) {\n            dexOutPool.shutdownNow();\n            throw new RuntimeException(\"Unexpected exception in dex writer thread\");\n        }\n\n        if (args.jarOutput) {\n            for (int i = 0; i < dexOutputArrays.size(); i++) {\n                outputResources.put(getDexFileName(i),\n                        dexOutputArrays.get(i));\n            }\n\n            if (!createJar(args.outName)) {\n                return 3;\n            }\n        } else if (args.outName != null) {\n            File outDir = new File(args.outName);\n            assert outDir.isDirectory();\n            for (int i = 0; i < dexOutputArrays.size(); i++) {\n                OutputStream out = new FileOutputStream(new File(outDir, getDexFileName(i)));\n                try {\n                    out.write(dexOutputArrays.get(i));\n                } finally {\n                    closeOutput(out);\n                }\n            }\n        }\n\n        return 0;\n    }\n\n    private static String getDexFileName(int i) {\n        if (i == 0) {\n            return DexFormat.DEX_IN_JAR_NAME;\n        } else {\n            return DEX_PREFIX + (i + 1) + DEX_EXTENSION;\n        }\n    }\n\n    private static void readPathsFromFile(String fileName, Collection<String> paths) throws IOException {\n        BufferedReader bfr = null;\n        try {\n            FileReader fr = new FileReader(fileName);\n            bfr = new BufferedReader(fr);\n\n            String line;\n\n            while (null != (line = bfr.readLine())) {\n                paths.add(fixPath(line));\n            }\n\n        } finally {\n            if (bfr != null) {\n                bfr.close();\n            }\n        }\n    }\n\n    /**\n     * Merges the dex files {@code update} and {@code base}, preferring\n     * {@code update}'s definition for types defined in both dex files.\n     *\n     * @param base a file to find the previous dex file. May be a .dex file, a\n     *     jar file possibly containing a .dex file, or null.\n     * @return the bytes of the merged dex file, or null if both the update\n     *     and the base dex do not exist.\n     */\n    private static byte[] mergeIncremental(byte[] update, File base) throws IOException {\n        Dex dexA = null;\n        Dex dexB = null;\n\n        if (update != null) {\n            dexA = new Dex(update);\n        }\n\n        if (base.exists()) {\n            dexB = new Dex(base);\n        }\n\n        Dex result;\n        if (dexA == null && dexB == null) {\n            return null;\n        } else if (dexA == null) {\n            result = dexB;\n        } else if (dexB == null) {\n            result = dexA;\n        } else {\n            result = new DexMerger(new Dex[] {dexA, dexB}, CollisionPolicy.KEEP_FIRST).merge();\n        }\n\n        ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();\n        result.writeTo(bytesOut);\n        return bytesOut.toByteArray();\n    }\n\n    /**\n     * Merges the dex files in library jars. If multiple dex files define the\n     * same type, this fails with an exception.\n     */\n    private  byte[] mergeLibraryDexBuffers(byte[] outArray) throws IOException {\n        ArrayList<Dex> dexes = new ArrayList<Dex>();\n        if (outArray != null) {\n            dexes.add(new Dex(outArray));\n        }\n        for (byte[] libraryDex : libraryDexBuffers) {\n            dexes.add(new Dex(libraryDex));\n        }\n        if (dexes.isEmpty()) {\n            return null;\n        }\n        Dex merged = new DexMerger(dexes.toArray(new Dex[dexes.size()]), CollisionPolicy.FAIL).merge();\n        return merged.getBytes();\n    }\n\n    /**\n     * Constructs the output {@link DexFile}, fill it in with all the\n     * specified classes, and populate the resources map if required.\n     *\n     * @return whether processing was successful\n     */\n    private boolean processAllFiles() {\n        createDexFile();\n\n        if (args.jarOutput) {\n            outputResources = new TreeMap<String, byte[]>();\n        }\n\n        anyFilesProcessed = false;\n        String[] fileNames = args.fileNames;\n        Arrays.sort(fileNames);\n\n        // translate classes in parallel\n        if (args.numThreads > 1) {\n            classTranslatorPool = new ThreadPoolExecutor(args.numThreads,\n                    args.numThreads, 0, TimeUnit.SECONDS,\n                    new ArrayBlockingQueue<Runnable>(2 * args.numThreads, true),\n                    new ThreadPoolExecutor.CallerRunsPolicy());\n            // collect translated and write to dex in order\n            classDefItemConsumer = Executors.newSingleThreadExecutor();\n        }\n\n\n        try {\n            if (args.mainDexListFile != null) {\n                // with --main-dex-list\n                FileNameFilter mainPassFilter = args.strictNameCheck ? new MainDexListFilter() :\n                    new BestEffortMainDexListFilter();\n\n                // forced in main dex\n                for (int i = 0; i < fileNames.length; i++) {\n                    processOne(fileNames[i], mainPassFilter);\n                }\n\n                if (dexOutputFutures.size() > 0) {\n                    throw new DexException(\"Too many classes in \" + Arguments.MAIN_DEX_LIST_OPTION\n                            + \", main dex capacity exceeded\");\n                }\n\n                if (args.minimalMainDex) {\n                    // start second pass directly in a secondary dex file.\n\n                    // Wait for classes in progress to complete\n                    synchronized(dexRotationLock) {\n                        while(maxMethodIdsInProcess > 0 || maxFieldIdsInProcess > 0) {\n                            try {\n                                dexRotationLock.wait();\n                            } catch(InterruptedException ex) {\n                                /* ignore */\n                            }\n                        }\n                    }\n\n                    rotateDexFile();\n                }\n\n                // remaining files\n                for (int i = 0; i < fileNames.length; i++) {\n                    processOne(fileNames[i], new NotFilter(mainPassFilter));\n                }\n            } else {\n                // without --main-dex-list\n                for (int i = 0; i < fileNames.length; i++) {\n                    processOne(fileNames[i], ClassPathOpener.acceptAll);\n                }\n            }\n        } catch (StopProcessing ex) {\n            /*\n             * Ignore it and just let the error reporting do\n             * their things.\n             */\n        }\n\n        if (args.numThreads > 1){\n            try {\n                classTranslatorPool.shutdown();\n                classTranslatorPool.awaitTermination(600L, TimeUnit.SECONDS);\n                classDefItemConsumer.shutdown();\n                classDefItemConsumer.awaitTermination(600L, TimeUnit.SECONDS);\n\n                if (addToDexFutures.size() > 0) {\n                    for (Future<Boolean> f : addToDexFutures) {\n                        try {\n                            f.get();\n                        } catch (ExecutionException ex) {\n                            // Catch any previously uncaught exceptions from\n                            // class translation and adding to dex.\n                            int count = errors.incrementAndGet();\n                            if (count < 10) {\n                                if (args.debug) {\n                                    DxConsole.err.println(\"Uncaught translation error:\");\n                                    ex.getCause().printStackTrace(DxConsole.err);\n                                } else {\n                                    DxConsole.err.println(\"Uncaught translation error: \" + ex.getCause());\n                                }\n                            } else {\n                                throw new InterruptedException(\"Too many errors\");\n                            }\n                        }\n                    }\n                }\n\n            } catch (InterruptedException ie) {\n                classTranslatorPool.shutdownNow();\n                classDefItemConsumer.shutdownNow();\n                throw new RuntimeException(\"Translation has been interrupted\", ie);\n            } catch (Exception e) {\n                classTranslatorPool.shutdownNow();\n                classDefItemConsumer.shutdownNow();\n                e.printStackTrace(System.out);\n                throw new RuntimeException(\"Unexpected exception in translator thread.\", e);\n            }\n\n            int errorNum = errors.get();\n            if (errorNum != 0) {\n                DxConsole.err.println(errorNum + \" error\" +\n                        ((errorNum == 1) ? \"\" : \"s\") + \"; aborting\");\n                return false;\n            }\n\n            if (args.incremental && !anyFilesProcessed) {\n                return true;\n            }\n\n            if (!(anyFilesProcessed || args.emptyOk)) {\n                DxConsole.err.println(\"no classfiles specified\");\n                return false;\n            }\n\n        }else {\n                for (Boolean value : resultList) {\n                    try {\n                        if (value == false){\n                            throw new ExecutionException(new Throwable(\"dx failed!\"));\n                        }\n                    } catch (ExecutionException ex) {\n                        // Catch any previously uncaught exceptions from\n                        // class translation and adding to dex.\n                        int count = errors.incrementAndGet();\n                        if (count < 10) {\n                            if (args.debug) {\n                                DxConsole.err.println(\"Uncaught translation error:\");\n                                ex.getCause().printStackTrace(DxConsole.err);\n                            } else {\n                                DxConsole.err.println(\"Uncaught translation error: \" + ex.getCause());\n                            }\n                        } else {\n                            DxConsole.err.println(\"too many errors\");\n                        }\n                    }\n                }\n            }\n\n\n\n        return true;\n    }\n\n    private  void createDexFile() {\n        outputDex = new DexFile(args.dexOptions);\n\n        if (args.dumpWidth != 0) {\n            outputDex.setDumpWidth(args.dumpWidth);\n        }\n    }\n\n    private  void rotateDexFile() {\n        if (outputDex != null) {\n            if (dexOutPool != null && args.numThreads > 1) {\n                dexOutputFutures.add(dexOutPool.submit(new DexWriter(outputDex)));\n            } else {\n                dexOutputArrays.add(writeDex(outputDex));\n            }\n        }\n\n        createDexFile();\n    }\n\n    /**\n     * Processes one pathname element.\n     *\n     * @param pathname {@code non-null;} the pathname to process. May\n     * be the path of a class file, a jar file, or a directory\n     * containing class files.\n     * @param filter {@code non-null;} A filter for excluding files.\n     */\n    private  void processOne(String pathname, FileNameFilter filter) {\n        ClassPathOpener opener;\n\n        opener = new ClassPathOpener(pathname, true, filter, new FileBytesConsumer());\n\n        if (opener.process()) {\n          updateStatus(true);\n        }\n    }\n\n    private  void updateStatus(boolean res) {\n        anyFilesProcessed |= res;\n    }\n\n\n    /**\n     * Processes one file, which may be either a class or a resource.\n     *\n     * @param name {@code non-null;} name of the file\n     * @param bytes {@code non-null;} contents of the file\n     * @return whether processing was successful\n     */\n    private boolean processFileBytes(String name, long lastModified, byte[] bytes) {\n\n        boolean isClass = name.endsWith(\".class\");\n        boolean isClassesDex = name.equals(DexFormat.DEX_IN_JAR_NAME);\n        boolean keepResources = (outputResources != null);\n\n        if (!isClass && !isClassesDex && !keepResources) {\n            if (args.verbose) {\n                DxConsole.out.println(\"ignored resource \" + name);\n            }\n            return false;\n        }\n\n        if (args.verbose) {\n            DxConsole.out.println(\"processing \" + name + \"...\");\n        }\n\n        String fixedName = fixPath(name);\n\n        if (isClass) {\n\n            if (keepResources && args.keepClassesInJar) {\n                synchronized (outputResources) {\n                    outputResources.put(fixedName, bytes);\n                }\n            }\n            if (lastModified < minimumFileAge) {\n                return true;\n            }\n            processClass(fixedName, bytes);\n            // Assume that an exception may occur. Status will be updated\n            // asynchronously, if the class compiles without error.\n            return false;\n        } else if (isClassesDex) {\n            synchronized (libraryDexBuffers) {\n                libraryDexBuffers.add(bytes);\n            }\n            return true;\n        } else {\n            synchronized (outputResources) {\n                outputResources.put(fixedName, bytes);\n            }\n            return true;\n        }\n    }\n\n    /**\n     * Processes one classfile.\n     *\n     * @param name {@code non-null;} name of the file, clipped such that it\n     * <i>should</i> correspond to the name of the class it contains\n     * @param bytes {@code non-null;} contents of the file\n     * @return whether processing was successful\n     */\n    private  boolean processClass(String name, byte[] bytes) {\n        if (! args.coreLibrary) {\n            checkClassName(name);\n        }\n\n        try {\n            new DirectClassFileConsumer(name, bytes, null).call(\n                    new ClassParserTask(name, bytes).call());\n        } catch (ParseException ex) {\n            // handled in FileBytesConsumer\n            throw ex;\n        } catch(Exception ex) {\n            throw new RuntimeException(\"Exception parsing classes \"+ name , ex);\n        }\n\n        return true;\n    }\n\n\n    private  DirectClassFile parseClass(String name, byte[] bytes) {\n\n        DirectClassFile cf = new DirectClassFile(bytes, name,\n                args.cfOptions.strictNameCheck);\n        cf.setAttributeFactory(StdAttributeFactory.THE_ONE);\n        cf.getMagic(); // triggers the actual parsing\n        return cf;\n    }\n\n    private  ClassDefItem translateClass(byte[] bytes, DirectClassFile cf) {\n        try {\n            return CfTranslator.translate(cf, bytes, args.cfOptions,\n                    args.dexOptions, outputDex);\n        } catch (ParseException ex) {\n            DxConsole.err.println(\"\\ntrouble processing:\");\n            if (args.debug) {\n                ex.printStackTrace(DxConsole.err);\n            } else {\n                ex.printContext(DxConsole.err);\n            }\n        }\n        errors.incrementAndGet();\n        return null;\n    }\n\n    private  boolean addClassToDex(ClassDefItem clazz) {\n        synchronized (outputDex) {\n            outputDex.add(clazz);\n        }\n        return true;\n    }\n\n    /**\n     * Check the class name to make sure it's not a \"core library\"\n     * class. If there is a problem, this updates the error count and\n     * throws an exception to stop processing.\n     *\n     * @param name {@code non-null;} the fully-qualified internal-form\n     * class name\n     */\n    private  void checkClassName(String name) {\n        boolean bogus = false;\n\n        if (name.startsWith(\"java/\")) {\n            bogus = true;\n        } else if (name.startsWith(\"javax/\")) {\n            int slashAt = name.indexOf('/', 6);\n            if (slashAt == -1) {\n                // Top-level javax classes are verboten.\n                bogus = true;\n            } else {\n                String pkg = name.substring(6, slashAt);\n                bogus = (Arrays.binarySearch(JAVAX_CORE, pkg) >= 0);\n            }\n        }\n\n        if (! bogus) {\n            return;\n        }\n\n        /*\n         * The user is probably trying to include an entire desktop\n         * core library in a misguided attempt to get their application\n         * working. Try to help them understand what's happening.\n         */\n\n        DxConsole.err.println(\"\\ntrouble processing \\\"\" + name + \"\\\":\\n\\n\" +\n                IN_RE_CORE_CLASSES);\n        errors.incrementAndGet();\n        throw new StopProcessing();\n    }\n\n    /**\n     * Converts {@link #outputDex} into a {@code byte[]} and do whatever\n     * human-oriented dumping is required.\n     *\n     * @return {@code null-ok;} the converted {@code byte[]} or {@code null}\n     * if there was a problem\n     */\n    private  byte[] writeDex(DexFile outputDex) {\n        byte[] outArray = null;\n\n        try {\n            try {\n                if (args.methodToDump != null) {\n                    /*\n                     * Simply dump the requested method. Note: The call\n                     * to toDex() is required just to get the underlying\n                     * structures ready.\n                     */\n                    outputDex.toDex(null, false);\n                    dumpMethod(outputDex, args.methodToDump, humanOutWriter);\n                } else {\n                    /*\n                     * This is the usual case: Create an output .dex file,\n                     * and write it, dump it, etc.\n                     */\n                    outArray = outputDex.toDex(humanOutWriter, args.verboseDump);\n                }\n\n                if (args.statistics) {\n                    DxConsole.out.println(outputDex.getStatistics().toHuman());\n                }\n            } finally {\n                if (humanOutWriter != null) {\n                    humanOutWriter.flush();\n                }\n            }\n        } catch (Exception ex) {\n            if (args.debug) {\n                DxConsole.err.println(\"\\ntrouble writing output:\");\n                ex.printStackTrace(DxConsole.err);\n            } else {\n                DxConsole.err.println(\"\\ntrouble writing output: \" +\n                                   ex.getMessage());\n            }\n            ex.printStackTrace();\n            return null;\n        }\n        return outArray;\n    }\n\n    /**\n     * Creates a jar file from the resources (including dex file arrays).\n     *\n     * @param fileName {@code non-null;} name of the file\n     * @return whether the creation was successful\n     */\n    private  boolean createJar(String fileName) {\n        /*\n         * Make or modify the manifest (as appropriate), put the dex\n         * array into the resources map, and then process the entire\n         * resources map in a uniform manner.\n         */\n\n        try {\n            Manifest manifest = makeManifest();\n            OutputStream out = openOutput(fileName);\n            JarOutputStream jarOut = new JarOutputStream(out, manifest);\n\n            try {\n                for (Map.Entry<String, byte[]> e :\n                         outputResources.entrySet()) {\n                    String name = e.getKey();\n                    byte[] contents = e.getValue();\n                    JarEntry entry = new JarEntry(name);\n                    int length = contents.length;\n\n                    if (args.verbose) {\n                        DxConsole.out.println(\"writing \" + name + \"; size \" + length + \"...\");\n                    }\n\n                    entry.setSize(length);\n                    jarOut.putNextEntry(entry);\n                    jarOut.write(contents);\n                    jarOut.closeEntry();\n                }\n            } finally {\n                jarOut.finish();\n                jarOut.flush();\n                closeOutput(out);\n            }\n        } catch (Exception ex) {\n            if (args.debug) {\n                DxConsole.err.println(\"\\ntrouble writing output:\");\n                ex.printStackTrace(DxConsole.err);\n            } else {\n                DxConsole.err.println(\"\\ntrouble writing output: \" +\n                                   ex.getMessage());\n            }\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Creates and returns the manifest to use for the output. This may\n     * modify {@link #outputResources} (removing the pre-existing manifest).\n     *\n     * @return {@code non-null;} the manifest\n     */\n    private  Manifest makeManifest() throws IOException {\n        byte[] manifestBytes = outputResources.get(MANIFEST_NAME);\n        Manifest manifest;\n        Attributes attribs;\n\n        if (manifestBytes == null) {\n            // We need to construct an entirely new manifest.\n            manifest = new Manifest();\n            attribs = manifest.getMainAttributes();\n            attribs.put(Attributes.Name.MANIFEST_VERSION, \"1.0\");\n        } else {\n            manifest = new Manifest(new ByteArrayInputStream(manifestBytes));\n            attribs = manifest.getMainAttributes();\n            outputResources.remove(MANIFEST_NAME);\n        }\n\n        String createdBy = attribs.getValue(CREATED_BY);\n        if (createdBy == null) {\n            createdBy = \"\";\n        } else {\n            createdBy += \" + \";\n        }\n        createdBy += \"dx \" + Version.VERSION;\n\n        attribs.put(CREATED_BY, createdBy);\n        attribs.putValue(\"Dex-Location\", DexFormat.DEX_IN_JAR_NAME);\n\n        return manifest;\n    }\n\n    /**\n     * Opens and returns the named file for writing, treating \"-\" specially.\n     *\n     * @param name {@code non-null;} the file name\n     * @return {@code non-null;} the opened file\n     */\n    private static OutputStream openOutput(String name) throws IOException {\n        if (name.equals(\"-\") ||\n                name.startsWith(\"-.\")) {\n            return System.out;\n        }\n\n        return new FileOutputStream(name);\n    }\n\n    /**\n     * Flushes and closes the given output stream, except if it happens to be\n     * {@link System#out} in which case this method does the flush but not\n     * the close. This method will also silently do nothing if given a\n     * {@code null} argument.\n     *\n     * @param stream {@code null-ok;} what to close\n     */\n    private static void closeOutput(OutputStream stream) throws IOException {\n        if (stream == null) {\n            return;\n        }\n\n        stream.flush();\n\n        if (stream != System.out) {\n            stream.close();\n        }\n    }\n\n    /**\n     * Returns the \"fixed\" version of a given file path, suitable for\n     * use as a path within a {@code .jar} file and for checking\n     * against a classfile-internal \"this class\" name. This looks for\n     * the last instance of the substring {@code \"/./\"} within\n     * the path, and if it finds it, it takes the portion after to be\n     * the fixed path. If that isn't found but the path starts with\n     * {@code \"./\"}, then that prefix is removed and the rest is\n     * return. If neither of these is the case, this method returns\n     * its argument.\n     *\n     * @param path {@code non-null;} the path to \"fix\"\n     * @return {@code non-null;} the fixed version (which might be the same as\n     * the given {@code path})\n     */\n    private static String fixPath(String path) {\n        /*\n         * If the path separator is \\ (like on windows), we convert the\n         * path to a standard '/' separated path.\n         */\n        if (File.separatorChar == '\\\\') {\n            path = path.replace('\\\\', '/');\n        }\n\n        int index = path.lastIndexOf(\"/./\");\n\n        if (index != -1) {\n            return path.substring(index + 3);\n        }\n\n        if (path.startsWith(\"./\")) {\n            return path.substring(2);\n        }\n\n        return path;\n    }\n\n    /**\n     * Dumps any method with the given name in the given file.\n     *\n     * @param dex {@code non-null;} the dex file\n     * @param fqName {@code non-null;} the fully-qualified name of the\n     * method(s)\n     * @param out {@code non-null;} where to dump to\n     */\n    private  void dumpMethod(DexFile dex, String fqName,\n            OutputStreamWriter out) {\n        boolean wildcard = fqName.endsWith(\"*\");\n        int lastDot = fqName.lastIndexOf('.');\n\n        if ((lastDot <= 0) || (lastDot == (fqName.length() - 1))) {\n            DxConsole.err.println(\"bogus fully-qualified method name: \" +\n                               fqName);\n            return;\n        }\n\n        String className = fqName.substring(0, lastDot).replace('.', '/');\n        String methodName = fqName.substring(lastDot + 1);\n        ClassDefItem clazz = dex.getClassOrNull(className);\n\n        if (clazz == null) {\n            DxConsole.err.println(\"no such class: \" + className);\n            return;\n        }\n\n        if (wildcard) {\n            methodName = methodName.substring(0, methodName.length() - 1);\n        }\n\n        ArrayList<EncodedMethod> allMeths = clazz.getMethods();\n        TreeMap<CstNat, EncodedMethod> meths =\n            new TreeMap<CstNat, EncodedMethod>();\n\n        /*\n         * Figure out which methods to include in the output, and get them\n         * all sorted, so that the printout code is robust with respect to\n         * changes in the underlying order.\n         */\n        for (EncodedMethod meth : allMeths) {\n            String methName = meth.getName().getString();\n            if ((wildcard && methName.startsWith(methodName)) ||\n                (!wildcard && methName.equals(methodName))) {\n                meths.put(meth.getRef().getNat(), meth);\n            }\n        }\n\n        if (meths.size() == 0) {\n            DxConsole.err.println(\"no such method: \" + fqName);\n            return;\n        }\n\n        PrintWriter pw = new PrintWriter(out);\n\n        for (EncodedMethod meth : meths.values()) {\n            // TODO: Better stuff goes here, perhaps.\n            meth.debugPrint(pw, args.verboseDump);\n\n            /*\n             * The (default) source file is an attribute of the class, but\n             * it's useful to see it in method dumps.\n             */\n            CstString sourceFile = clazz.getSourceFile();\n            if (sourceFile != null) {\n                pw.println(\"  source file: \" + sourceFile.toQuoted());\n            }\n\n            Annotations methodAnnotations =\n                clazz.getMethodAnnotations(meth.getRef());\n            AnnotationsList parameterAnnotations =\n                clazz.getParameterAnnotations(meth.getRef());\n\n            if (methodAnnotations != null) {\n                pw.println(\"  method annotations:\");\n                for (Annotation a : methodAnnotations.getAnnotations()) {\n                    pw.println(\"    \" + a);\n                }\n            }\n\n            if (parameterAnnotations != null) {\n                pw.println(\"  parameter annotations:\");\n                int sz = parameterAnnotations.size();\n                for (int i = 0; i < sz; i++) {\n                    pw.println(\"    parameter \" + i);\n                    Annotations annotations = parameterAnnotations.get(i);\n                    for (Annotation a : annotations.getAnnotations()) {\n                        pw.println(\"      \" + a);\n                    }\n                }\n            }\n        }\n\n        pw.flush();\n    }\n\n    private static class NotFilter implements FileNameFilter {\n        private final FileNameFilter filter;\n\n        private NotFilter(FileNameFilter filter) {\n            this.filter = filter;\n        }\n\n        @Override\n        public boolean accept(String path) {\n            return !filter.accept(path);\n        }\n    }\n\n    /**\n     * A quick and accurate filter for when file path can be trusted.\n     */\n    private  class MainDexListFilter implements FileNameFilter {\n\n        @Override\n        public boolean accept(String fullPath) {\n            if (fullPath.endsWith(\".class\")) {\n                String path = fixPath(fullPath);\n                return classesInMainDex.contains(path);\n            } else {\n                return true;\n            }\n        }\n    }\n\n    /**\n     * A best effort conservative filter for when file path can <b>not</b> be trusted.\n     */\n    private  class BestEffortMainDexListFilter implements FileNameFilter {\n\n       Map<String, List<String>> map = new HashMap<String, List<String>>();\n\n       public BestEffortMainDexListFilter() {\n           for (String pathOfClass : classesInMainDex) {\n               String normalized = fixPath(pathOfClass);\n               String simple = getSimpleName(normalized);\n               List<String> fullPath = map.get(simple);\n               if (fullPath == null) {\n                   fullPath = new ArrayList<String>(1);\n                   map.put(simple, fullPath);\n               }\n               fullPath.add(normalized);\n           }\n        }\n\n        @Override\n        public boolean accept(String path) {\n            if (path.endsWith(\".class\")) {\n                String normalized = fixPath(path);\n                String simple = getSimpleName(normalized);\n                List<String> fullPaths = map.get(simple);\n                if (fullPaths != null) {\n                    for (String fullPath : fullPaths) {\n                        if (normalized.endsWith(fullPath)) {\n                            return true;\n                        }\n                    }\n                }\n                return false;\n            } else {\n                return true;\n            }\n        }\n\n        private  String getSimpleName(String path) {\n            int index = path.lastIndexOf('/');\n            if (index >= 0) {\n                return path.substring(index + 1);\n            } else {\n                return path;\n            }\n        }\n    }\n\n    /**\n     * Exception class used to halt processing prematurely.\n     */\n    private static class StopProcessing extends RuntimeException {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Command-line argument parser and access.\n     */\n    public static class Arguments {\n\n        private static final String MINIMAL_MAIN_DEX_OPTION = \"--minimal-main-dex\";\n\n        private static final String MAIN_DEX_LIST_OPTION = \"--main-dex-list\";\n\n        private static final String MULTI_DEX_OPTION = \"--multi-dex\";\n\n        private static final String NUM_THREADS_OPTION = \"--num-threads\";\n\n        private static final String INCREMENTAL_OPTION = \"--incremental\";\n\n        private static final String INPUT_LIST_OPTION = \"--input-list\";\n\n        /** whether to run in debug mode */\n        public boolean debug = false;\n\n        /** whether to emit warning messages */\n        public boolean warnings = true;\n\n        /** whether to emit high-level verbose human-oriented output */\n        public boolean verbose = true;\n\n        /** whether to emit verbose human-oriented output in the dump file */\n        public boolean verboseDump = false;\n\n        /** whether we are constructing a core library */\n        public boolean coreLibrary = false;\n\n        /** {@code null-ok;} particular method to dump */\n        public String methodToDump = null;\n\n        /** max width for columnar output */\n        public int dumpWidth = 0;\n\n        /** {@code null-ok;} output file name for binary file */\n        public String outName = null;\n\n        /** {@code null-ok;} output file name for human-oriented dump */\n        public String humanOutName = null;\n\n        /** whether strict file-name-vs-class-name checking should be done */\n        public boolean strictNameCheck = true;\n\n        /**\n         * whether it is okay for there to be no {@code .class} files\n         * to process\n         */\n        public boolean emptyOk = false;\n\n        /**\n         * whether the binary output is to be a {@code .jar} file\n         * instead of a plain {@code .dex}\n         */\n        public boolean jarOutput = false;\n\n        /**\n         * when writing a {@code .jar} file, whether to still\n         * keep the {@code .class} files\n         */\n        public boolean keepClassesInJar = false;\n\n        /** how much source position info to preserve */\n        public int positionInfo = PositionList.LINES;\n\n        /** whether to keep local variable information */\n        public boolean localInfo = true;\n\n        /** whether to merge with the output dex file if it exists. */\n        public boolean incremental = false;\n\n        /** whether to force outputs of const-string/jumbo for all indexes,\n         *  to allow merges between dex files with many strings. */\n        public boolean forceJumbo = false;\n\n        /** {@code non-null} after {@link #parse}; file name arguments */\n        public String[] fileNames;\n\n        /** whether to do SSA/register optimization */\n        public boolean optimize = true;\n\n        /** Filename containg list of methods to optimize */\n        public String optimizeListFile = null;\n\n        /** Filename containing list of methods to NOT optimize */\n        public String dontOptimizeListFile = null;\n\n        /** Whether to print statistics to stdout at end of compile cycle */\n        public boolean statistics;\n\n        /** Options for class file transformation */\n        public CfOptions cfOptions;\n\n        /** Options for dex file output */\n        public DexOptions dexOptions;\n\n        /** number of threads to run with */\n        public int numThreads = 1;\n\n        /** outputs of multiple dex is allowed */\n        public boolean multiDex = false;\n\n        /** Optional file containing a list of class files containing classes to be forced in main\n         * dex */\n        public String mainDexListFile = null;\n\n        /** Produce the smallest possible main dex. Ignored unless multiDex is true and\n         * mainDexListFile is specified and non empty. */\n        public boolean minimalMainDex = false;\n\n        /** Optional list containing inputs read in from a file. */\n        private List<String> inputList = null;\n\n        private int maxNumberOfIdxPerDex = DexFormat.MAX_MEMBER_IDX + 1;\n\n        private static class ArgumentsParser {\n\n            /** The arguments to process. */\n            private final String[] arguments;\n            /** The index of the next argument to process. */\n            private int index;\n            /** The current argument being processed after a {@link #getNext()} call. */\n            private String current;\n            /** The last value of an argument processed by {@link #isArg(String)}. */\n            private String lastValue;\n\n            public ArgumentsParser(String[] arguments) {\n                this.arguments = arguments;\n                index = 0;\n            }\n\n            public String getCurrent() {\n                return current;\n            }\n\n            public String getLastValue() {\n                return lastValue;\n            }\n\n            /**\n             * Moves on to the next argument.\n             * Returns false when we ran out of arguments that start with --.\n             */\n            public boolean getNext() {\n                if (index >= arguments.length) {\n                    return false;\n                }\n                current = arguments[index];\n                if (current.equals(\"--\") || !current.startsWith(\"--\")) {\n                    return false;\n                }\n                index++;\n                return true;\n            }\n\n            /**\n             * Similar to {@link #getNext()}, this moves on the to next argument.\n             * It does not check however whether the argument starts with --\n             * and thus can be used to retrieve values.\n             */\n            private boolean getNextValue() {\n                if (index >= arguments.length) {\n                    return false;\n                }\n                current = arguments[index];\n                index++;\n                return true;\n            }\n\n            /**\n             * Returns all the arguments that have not been processed yet.\n             */\n            public String[] getRemaining() {\n                int n = arguments.length - index;\n                String[] remaining = new String[n];\n                if (n > 0) {\n                    System.arraycopy(arguments, index, remaining, 0, n);\n                }\n                return remaining;\n            }\n\n            /**\n             * Checks the current argument against the given prefix.\n             * If prefix is in the form '--name=', an extra value is expected.\n             * The argument can then be in the form '--name=value' or as a 2-argument\n             * form '--name value'.\n             */\n            public boolean isArg(String prefix) {\n                int n = prefix.length();\n                if (n > 0 && prefix.charAt(n-1) == '=') {\n                    // Argument accepts a value. Capture it.\n                    if (current.startsWith(prefix)) {\n                        // Argument is in the form --name=value, split the value out\n                        lastValue = current.substring(n);\n                        return true;\n                    } else {\n                        // Check whether we have \"--name value\" as 2 arguments\n                        prefix = prefix.substring(0, n-1);\n                        if (current.equals(prefix)) {\n                            if (getNextValue()) {\n                                lastValue = current;\n                                return true;\n                            } else {\n                                System.err.println(\"Missing value after parameter \" + prefix);\n                                throw new UsageException();\n                            }\n                        }\n                        return false;\n                    }\n                } else {\n                    // Argument does not accept a value.\n                    return current.equals(prefix);\n                }\n            }\n        }\n\n        /**\n         * Parses the given command-line arguments.\n         *\n         * @param args {@code non-null;} the arguments\n         */\n        public void parse(String[] args) {\n//            args = new String[2];\n//            args[0] = \"--input-list=/Users/lilong/Downloads/log\";\n//            args[1] = \"--output=/Users/lilong/Downloads/c.dex\";\n//            args[2] = \"--output=/Users/lilong/Downloads/c.dex\";\n\n            ArgumentsParser parser = new ArgumentsParser(args);\n\n            boolean outputIsDirectory = false;\n            boolean outputIsDirectDex = false;\n\n            while(parser.getNext()) {\n                if (parser.isArg(\"--debug\")) {\n                    debug = true;\n                } else if (parser.isArg(\"--no-warning\")) {\n                    warnings = false;\n                } else if (parser.isArg(\"--verbose\")) {\n                    verbose = true;\n                } else if (parser.isArg(\"--verbose-dump\")) {\n                    verboseDump = true;\n                } else if (parser.isArg(\"--no-files\")) {\n                    emptyOk = true;\n                } else if (parser.isArg(\"--no-optimize\")) {\n                    optimize = false;\n                } else if (parser.isArg(\"--no-strict\")) {\n                    strictNameCheck = false;\n                } else if (parser.isArg(\"--core-library\")) {\n                    coreLibrary = true;\n                } else if (parser.isArg(\"--statistics\")) {\n                    statistics = true;\n                } else if (parser.isArg(\"--optimize-list=\")) {\n                    if (dontOptimizeListFile != null) {\n                        System.err.println(\"--optimize-list and \"\n                                + \"--no-optimize-list are incompatible.\");\n                        throw new UsageException();\n                    }\n                    optimize = true;\n                    optimizeListFile = parser.getLastValue();\n                } else if (parser.isArg(\"--no-optimize-list=\")) {\n                    if (dontOptimizeListFile != null) {\n                        System.err.println(\"--optimize-list and \"\n                                + \"--no-optimize-list are incompatible.\");\n                        throw new UsageException();\n                    }\n                    optimize = true;\n                    dontOptimizeListFile = parser.getLastValue();\n                } else if (parser.isArg(\"--keep-classes\")) {\n                    keepClassesInJar = true;\n                } else if (parser.isArg(\"--output=\")) {\n                    outName = parser.getLastValue();\n                    if (new File(outName).isDirectory()) {\n                        jarOutput = false;\n                        outputIsDirectory = true;\n                    } else if (FileUtils.hasArchiveSuffix(outName)) {\n                        jarOutput = true;\n                    } else if (outName.endsWith(\".dex\") ||\n                               outName.equals(\"-\")) {\n                        jarOutput = false;\n                        outputIsDirectDex = true;\n                    } else {\n                        System.err.println(\"unknown output extension: \" +\n                                           outName);\n                        throw new UsageException();\n                    }\n                } else if (parser.isArg(\"--dump-to=\")) {\n                    humanOutName = parser.getLastValue();\n                } else if (parser.isArg(\"--dump-width=\")) {\n                    dumpWidth = Integer.parseInt(parser.getLastValue());\n                } else if (parser.isArg(\"--dump-method=\")) {\n                    methodToDump = parser.getLastValue();\n                    jarOutput = false;\n                } else if (parser.isArg(\"--positions=\")) {\n                    String pstr = parser.getLastValue().intern();\n                    if (pstr == \"none\") {\n                        positionInfo = PositionList.NONE;\n                    } else if (pstr == \"important\") {\n                        positionInfo = PositionList.IMPORTANT;\n                    } else if (pstr == \"lines\") {\n                        positionInfo = PositionList.LINES;\n                    } else {\n                        System.err.println(\"unknown positions option: \" +\n                                           pstr);\n                        throw new UsageException();\n                    }\n                } else if (parser.isArg(\"--no-locals\")) {\n                    localInfo = false;\n                } else if (parser.isArg(NUM_THREADS_OPTION + \"=\")) {\n                    numThreads = Integer.parseInt(parser.getLastValue());\n                } else if (parser.isArg(INCREMENTAL_OPTION)) {\n                    incremental = true;\n                } else if (parser.isArg(\"--force-jumbo\")) {\n                    forceJumbo = true;\n                } else if (parser.isArg(MULTI_DEX_OPTION)) {\n                    multiDex = true;\n                } else if (parser.isArg(MAIN_DEX_LIST_OPTION + \"=\")) {\n                    mainDexListFile = parser.getLastValue();\n                } else if (parser.isArg(MINIMAL_MAIN_DEX_OPTION)) {\n                    minimalMainDex = true;\n                } else if (parser.isArg(\"--set-max-idx-number=\")) { // undocumented test option\n                    maxNumberOfIdxPerDex = Integer.parseInt(parser.getLastValue());\n                } else if(parser.isArg(INPUT_LIST_OPTION + \"=\")) {\n                    File inputListFile = new File(parser.getLastValue());\n                    try{\n                        inputList = new ArrayList<String>();\n                        readPathsFromFile(inputListFile.getAbsolutePath(), inputList);\n                    } catch(IOException e) {\n                        System.err.println(\n                            \"Unable to read input list file: \" + inputListFile.getName());\n                        // problem reading the file so we should halt execution\n                        throw new UsageException();\n                    }\n                } else {\n                    System.err.println(\"unknown option: \" + parser.getCurrent());\n                    throw new UsageException();\n                }\n            }\n\n            fileNames = parser.getRemaining();\n            if(inputList != null && !inputList.isEmpty()) {\n                // append the file names to the end of the input list\n                inputList.addAll(Arrays.asList(fileNames));\n                fileNames = inputList.toArray(new String[inputList.size()]);\n            }\n\n            if (fileNames.length == 0) {\n                if (!emptyOk) {\n                    System.err.println(\"no input files specified\");\n                    throw new UsageException();\n                }\n            } else if (emptyOk) {\n                System.out.println(\"ignoring input files\");\n            }\n\n            if ((humanOutName == null) && (methodToDump != null)) {\n                humanOutName = \"-\";\n            }\n\n            if (mainDexListFile != null && !multiDex) {\n                System.err.println(MAIN_DEX_LIST_OPTION + \" is only supported in combination with \"\n                    + MULTI_DEX_OPTION);\n                throw new UsageException();\n            }\n\n            if (minimalMainDex && (mainDexListFile == null || !multiDex)) {\n                System.err.println(MINIMAL_MAIN_DEX_OPTION + \" is only supported in combination with \"\n                    + MULTI_DEX_OPTION + \" and \" + MAIN_DEX_LIST_OPTION);\n                throw new UsageException();\n            }\n\n            if (multiDex && incremental) {\n                System.err.println(INCREMENTAL_OPTION + \" is not supported with \"\n                    + MULTI_DEX_OPTION);\n                throw new UsageException();\n            }\n\n            if (multiDex && outputIsDirectDex) {\n                System.err.println(\"Unsupported output \\\"\" + outName +\"\\\". \" + MULTI_DEX_OPTION +\n                        \" supports only archive or directory output\");\n                throw new UsageException();\n            }\n\n            if (outputIsDirectory && !multiDex) {\n                outName = new File(outName, DexFormat.DEX_IN_JAR_NAME).getPath();\n            }\n\n            makeOptionsObjects();\n        }\n\n        /**\n         * Copies relevent arguments over into CfOptions and\n         * DexOptions instances.\n         */\n        private void makeOptionsObjects() {\n            cfOptions = new CfOptions();\n            cfOptions.positionInfo = positionInfo;\n            cfOptions.localInfo = localInfo;\n            cfOptions.strictNameCheck = strictNameCheck;\n            cfOptions.optimize = optimize;\n            cfOptions.optimizeListFile = optimizeListFile;\n            cfOptions.dontOptimizeListFile = dontOptimizeListFile;\n            cfOptions.statistics = statistics;\n\n            if (warnings) {\n                cfOptions.warn = DxConsole.err;\n            } else {\n                cfOptions.warn = DxConsole.noop;\n            }\n\n            dexOptions = new DexOptions();\n            dexOptions.forceJumbo = forceJumbo;\n        }\n    }\n\n    /**\n     * Callback class for processing input file bytes, produced by the\n     * ClassPathOpener.\n     */\n    private  class FileBytesConsumer implements ClassPathOpener.Consumer {\n\n        @Override\n        public boolean processFileBytes(String name, long lastModified,\n                byte[] bytes)   {\n            return Main.this.processFileBytes(name, lastModified, bytes);\n        }\n\n        @Override\n        public void onException(Exception ex) {\n            if (ex instanceof StopProcessing) {\n                throw (StopProcessing) ex;\n            } else if (ex instanceof SimException) {\n                DxConsole.err.println(\"\\nEXCEPTION FROM SIMULATION:\");\n                DxConsole.err.println(ex.getMessage() + \"\\n\");\n                DxConsole.err.println(((SimException) ex).getContext());\n            } else if (ex instanceof ParseException) {\n                DxConsole.err.println(\"\\nPARSE ERROR:\");\n                ParseException parseException = (ParseException) ex;\n                if (args.debug) {\n                    parseException.printStackTrace(DxConsole.err);\n                } else {\n                    parseException.printContext(DxConsole.err);\n                }\n            } else {\n                DxConsole.err.println(\"\\nUNEXPECTED TOP-LEVEL EXCEPTION:\");\n                ex.printStackTrace(DxConsole.err);\n            }\n            errors.incrementAndGet();\n        }\n\n        @Override\n        public void onProcessArchiveStart(File file) {\n            if (args.verbose) {\n                DxConsole.out.println(\"processing archive \" + file + \"...\");\n            }\n        }\n    }\n\n    /** Callable helper class to parse class bytes. */\n    private  class ClassParserTask implements Callable<DirectClassFile> {\n\n        String name;\n        byte[] bytes;\n\n        private ClassParserTask(String name, byte[] bytes) {\n            this.name = name;\n            this.bytes = bytes;\n        }\n\n        @Override\n        public DirectClassFile call() throws Exception {\n            DirectClassFile cf =  parseClass(name, bytes);\n\n            return cf;\n        }\n    }\n\n    /**\n     * Callable helper class used to sequentially collect the results of\n     * the (optionally parallel) translation phase, in correct input file order.\n     * This class is also responsible for coordinating dex file rotation\n     * with the ClassDefItemConsumer class.\n     * We maintain invariant that the number of indices used in the current\n     * dex file plus the max number of indices required by classes passed to\n     * the translation phase and not yet added to the dex file, is less than\n     * or equal to the dex file limit.\n     * For each parsed file, we estimate the maximum number of indices it may\n     * require. If passing the file to the translation phase would invalidate\n     * the invariant, we wait, until the next class is added to the dex file,\n     * and then reevaluate the invariant. If there are no further classes in\n     * the translation phase, we rotate the dex file.\n     */\n    private  class DirectClassFileConsumer implements Callable<Boolean> {\n\n        String name;\n        byte[] bytes;\n        Future<DirectClassFile> dcff;\n\n        private DirectClassFileConsumer(String name, byte[] bytes,\n                Future<DirectClassFile> dcff) {\n            this.name = name;\n            this.bytes = bytes;\n            this.dcff = dcff;\n        }\n\n        @Override\n        public Boolean call() throws Exception {\n\n            DirectClassFile cf = dcff.get();\n            return call(cf);\n        }\n\n        private Boolean call(DirectClassFile cf) {\n\n            int maxMethodIdsInClass = 0;\n            int maxFieldIdsInClass = 0;\n\n            if (args.multiDex) {\n\n                // Calculate max number of indices this class will add to the\n                // dex file.\n                // The possibility of overloading means that we can't easily\n                // know how many constant are needed for declared methods and\n                // fields. We therefore make the simplifying assumption that\n                // all constants are external method or field references.\n\n                int constantPoolSize = cf.getConstantPool().size();\n                maxMethodIdsInClass = constantPoolSize + cf.getMethods().size()\n                        + MAX_METHOD_ADDED_DURING_DEX_CREATION;\n                maxFieldIdsInClass = constantPoolSize + cf.getFields().size()\n                        + MAX_FIELD_ADDED_DURING_DEX_CREATION;\n                synchronized(dexRotationLock) {\n\n                    int numMethodIds;\n                    int numFieldIds;\n                    // Number of indices used in current dex file.\n                    synchronized(outputDex) {\n                        numMethodIds = outputDex.getMethodIds().items().size();\n                        numFieldIds = outputDex.getFieldIds().items().size();\n                    }\n                    // Wait until we're sure this class will fit in the current\n                    // dex file.\n                    while(((numMethodIds + maxMethodIdsInClass + maxMethodIdsInProcess\n                            > args.maxNumberOfIdxPerDex) ||\n                           (numFieldIds + maxFieldIdsInClass + maxFieldIdsInProcess\n                            > args.maxNumberOfIdxPerDex))) {\n\n                        if (maxMethodIdsInProcess > 0 || maxFieldIdsInProcess > 0) {\n                            // There are classes in the translation phase that\n                            // have not yet been added to the dex file, so we\n                            // wait for the next class to complete.\n                            try {\n                                dexRotationLock.wait();\n                            } catch(InterruptedException ex) {\n                                /* ignore */\n                            }\n                        } else if (outputDex.getClassDefs().items().size() > 0) {\n                            // There are no further classes in the translation\n                            // phase, and we have a full dex file. Rotate!\n                            rotateDexFile();\n                        } else {\n                            // The estimated number of indices is too large for\n                            // an empty dex file. We proceed hoping the actual\n                            // number of indices needed will fit.\n                            break;\n                        }\n                        synchronized(outputDex) {\n                            numMethodIds = outputDex.getMethodIds().items().size();\n                            numFieldIds = outputDex.getFieldIds().items().size();\n                        }\n                    }\n                    // Add our estimate to the total estimate for\n                    // classes under translation.\n                    maxMethodIdsInProcess += maxMethodIdsInClass;\n                    maxFieldIdsInProcess += maxFieldIdsInClass;\n                }\n            }\n\n            // Submit class to translation phase.\n\n            if (args.numThreads > 1){\n                Future<ClassDefItem> cdif = classTranslatorPool.submit(\n                        new ClassTranslatorTask(name, bytes, cf));\n                Future<Boolean> res = classDefItemConsumer.submit(new ClassDefItemConsumer(\n                        name, cdif, maxMethodIdsInClass, maxFieldIdsInClass));\n                addToDexFutures.add(res);\n            }else {\n//\n                ClassDefItem classDefItem = new ClassTranslatorTask(name, bytes, cf).call();\n                try {\n                    Boolean result = new ClassDefItemConsumer(name, classDefItem, maxMethodIdsInClass, maxFieldIdsInClass).call();\n                    resultList.add(result);\n                } catch (Exception e) {\n                    e.printStackTrace();\n                }\n            }\n\n\n\n            return true;\n        }\n    }\n\n\n    /** Callable helper class to translate classes in parallel  */\n    private  class ClassTranslatorTask implements Callable<ClassDefItem> {\n\n        String name;\n        byte[] bytes;\n        DirectClassFile classFile;\n\n        private ClassTranslatorTask(String name, byte[] bytes,\n                DirectClassFile classFile) {\n            this.name = name;\n            this.bytes = bytes;\n            this.classFile = classFile;\n        }\n\n        @Override\n        public ClassDefItem call() {\n            ClassDefItem clazz = translateClass(bytes, classFile);\n            return clazz;\n        }\n    }\n\n    /**\n     * Callable helper class used to collect the results of\n     * the parallel translation phase, adding the translated classes to\n     * the current dex file in correct (deterministic) file order.\n     * This class is also responsible for coordinating dex file rotation\n     * with the DirectClassFileConsumer class.\n     */\n    private  class ClassDefItemConsumer implements Callable<Boolean> {\n\n        String name;\n        Future<ClassDefItem> futureClazz;\n        int maxMethodIdsInClass;\n        int maxFieldIdsInClass;\n        private ClassDefItem clazz;\n\n        private ClassDefItemConsumer(String name, Future<ClassDefItem> futureClazz,\n                int maxMethodIdsInClass, int maxFieldIdsInClass) {\n            this.name = name;\n            this.futureClazz = futureClazz;\n            this.maxMethodIdsInClass = maxMethodIdsInClass;\n            this.maxFieldIdsInClass = maxFieldIdsInClass;\n        }\n\n        private ClassDefItemConsumer(String name,ClassDefItem classDefItem,int maxMethodIdsInClass,int maxFieldIdsInClass){\n            this.name = name;\n            this.clazz = classDefItem;\n            this.maxFieldIdsInClass = maxFieldIdsInClass;\n            this.maxMethodIdsInClass = maxMethodIdsInClass;\n\n        }\n\n        @Override\n        public Boolean call() throws Exception {\n            try {\n                if (clazz == null) {\n                    clazz = futureClazz.get();\n                }\n                if (clazz != null) {\n                    addClassToDex(clazz);\n                    updateStatus(true);\n                }\n                return true;\n            } catch(ExecutionException ex) {\n                // Rethrow previously uncaught translation exceptions.\n                // These, as well as any exceptions from addClassToDex,\n                // are handled and reported in processAllFiles().\n                Throwable t = ex.getCause();\n                throw (t instanceof Exception) ? (Exception) t : ex;\n            } finally {\n                if (args.multiDex) {\n                    // Having added our actual indicies to the dex file,\n                    // we subtract our original estimate from the total estimate,\n                    // and signal the translation phase, which may be paused\n                    // waiting to determine if more classes can be added to the\n                    // current dex file, or if a new dex file must be created.\n                    synchronized(dexRotationLock) {\n                        maxMethodIdsInProcess -= maxMethodIdsInClass;\n                        maxFieldIdsInProcess -= maxFieldIdsInClass;\n                        dexRotationLock.notifyAll();\n                    }\n                }\n            }\n        }\n    }\n\n    /** Callable helper class to convert dex files in worker threads */\n    private  class DexWriter implements Callable<byte[]> {\n\n        private DexFile dexFile;\n\n        private DexWriter(DexFile dexFile) {\n            this.dexFile = dexFile;\n        }\n\n        @Override\n        public byte[] call() throws IOException {\n            return writeDex(dexFile);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/dump/Args.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command.dump;\n\n/**\n * contains command line parsedArgs values\n */\nclass Args {\n    /** whether to run in debug mode */\n    boolean debug = false;\n\n    /** whether to dump raw bytes where salient */\n    boolean rawBytes = false;\n\n    /** whether to dump information about basic blocks */\n    boolean basicBlocks = false;\n\n    /** whether to dump regiserized blocks */\n    boolean ropBlocks = false;\n\n    /** whether to dump SSA-form blocks */\n    boolean ssaBlocks = false;\n\n    /** Step in SSA processing to stop at, or null for all */\n    String ssaStep = null;\n\n    /** whether to run SSA optimizations */\n    boolean optimize = false;\n\n    /** whether to be strict about parsing classfiles*/\n    boolean strictParse = false;\n\n    /** max width for columnar output */\n    int width = 0;\n\n    /** whether to dump flow-graph in \"dot\" format */\n    boolean dotDump = false;\n\n    /** if non-null, an explicit method to dump */\n    String method;\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/dump/BaseDumper.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command.dump;\n\nimport com.taobao.android.dx.cf.code.ConcreteMethod;\nimport com.taobao.android.dx.cf.iface.Member;\nimport com.taobao.android.dx.cf.iface.ParseObserver;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.IndentingWriter;\nimport com.taobao.android.dx.util.TwoColumnOutput;\nimport java.io.IOException;\nimport java.io.PrintStream;\nimport java.io.StringWriter;\n\n/**\n * Base class for the various human-friendly dumpers.\n */\npublic abstract class BaseDumper\n        implements ParseObserver {\n    /** {@code non-null;} array of data being dumped */\n    private final byte[] bytes;\n\n    /** whether or not to include the raw bytes (in a column on the left) */\n    private final boolean rawBytes;\n\n    /** {@code non-null;} where to dump to */\n    private final PrintStream out;\n\n    /** width of the output in columns */\n    private final int width;\n\n    /**\n     * {@code non-null;} the file path for the class, excluding any base\n     * directory specification\n     */\n    private final String filePath;\n\n    /** whether to be strict about parsing */\n    private final boolean strictParse;\n\n     /** number of bytes per line in hex dumps */\n    private final int hexCols;\n\n    /** the current level of indentation */\n    private int indent;\n\n    /** {@code non-null;} the current column separator string */\n    private String separator;\n\n    /** the offset of the next byte to dump */\n    private int at;\n\n    /** commandline parsedArgs */\n    protected Args args;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param bytes {@code non-null;} bytes of the (alleged) class file\n     * on the left)\n     * @param out {@code non-null;} where to dump to\n     * @param filePath the file path for the class, excluding any base\n     * directory specification\n     */\n    public BaseDumper(byte[] bytes, PrintStream out,\n                      String filePath, Args args) {\n        this.bytes = bytes;\n        this.rawBytes = args.rawBytes;\n        this.out = out;\n        this.width = (args.width <= 0) ? 79 : args.width;\n        this.filePath = filePath;\n        this.strictParse = args.strictParse;\n        this.indent = 0;\n        this.separator = rawBytes ? \"|\" : \"\";\n        this.at = 0;\n        this.args = args;\n\n        int hexCols = (((width - 5) / 15) + 1) & ~1;\n        if (hexCols < 6) {\n            hexCols = 6;\n        } else if (hexCols > 10) {\n            hexCols = 10;\n        }\n        this.hexCols = hexCols;\n    }\n\n    /**\n     * Computes the total width, in register-units, of the parameters for\n     * this method.\n     * @param meth method to process\n     * @return width in register-units\n     */\n    static int computeParamWidth(ConcreteMethod meth, boolean isStatic) {\n        return meth.getEffectiveDescriptor().getParameterTypes().\n            getWordCount();\n    }\n\n    /** {@inheritDoc} */\n    public void changeIndent(int indentDelta) {\n        indent += indentDelta;\n\n        separator = rawBytes ? \"|\" : \"\";\n        for (int i = 0; i < indent; i++) {\n            separator += \"  \";\n        }\n    }\n\n    /** {@inheritDoc} */\n    public void parsed(ByteArray bytes, int offset, int len, String human) {\n        offset = bytes.underlyingOffset(offset, getBytes());\n\n        boolean rawBytes = getRawBytes();\n\n        if (offset < at) {\n            println(\"<dump skipped backwards to \" + Hex.u4(offset) + \">\");\n            at = offset;\n        } else if (offset > at) {\n            String hex = rawBytes ? hexDump(at, offset - at) : \"\";\n            print(twoColumns(hex, \"<skipped to \" + Hex.u4(offset) + \">\"));\n            at = offset;\n        }\n\n        String hex = rawBytes ? hexDump(offset, len) : \"\";\n        print(twoColumns(hex, human));\n        at += len;\n    }\n\n    /** {@inheritDoc} */\n    public void startParsingMember(ByteArray bytes, int offset, String name,\n                                   String descriptor) {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    public void endParsingMember(ByteArray bytes, int offset, String name,\n                                 String descriptor, Member member) {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Gets the current dump cursor (that is, the offset of the expected\n     * next byte to dump).\n     *\n     * @return {@code >= 0;} the dump cursor\n     */\n    protected final int getAt() {\n        return at;\n    }\n\n    /**\n     * Sets the dump cursor to the indicated offset in the given array.\n     *\n     * @param arr {@code non-null;} array in question\n     * @param offset {@code >= 0;} offset into the array\n     */\n    protected final void setAt(ByteArray arr, int offset) {\n        at = arr.underlyingOffset(offset, bytes);\n    }\n\n    /**\n     * Gets the array of {@code byte}s to process.\n     *\n     * @return {@code non-null;} the bytes\n     */\n    protected final byte[] getBytes() {\n        return bytes;\n    }\n\n    /**\n     * Gets the filesystem/jar path of the file being dumped.\n     *\n     * @return {@code non-null;} the path\n     */\n    protected final String getFilePath() {\n        return filePath;\n    }\n\n    /**\n     * Gets whether to be strict about parsing.\n     *\n     * @return whether to be strict about parsing\n     */\n    protected final boolean getStrictParse() {\n        return strictParse;\n    }\n\n    /**\n     * Prints the given string to this instance's output stream.\n     *\n     * @param s {@code null-ok;} string to print\n     */\n    protected final void print(String s) {\n        out.print(s);\n    }\n\n    /**\n     * Prints the given string to this instance's output stream, followed\n     * by a newline.\n     *\n     * @param s {@code null-ok;} string to print\n     */\n    protected final void println(String s) {\n        out.println(s);\n    }\n\n    /**\n     * Gets whether this dump is to include raw bytes.\n     *\n     * @return the raw bytes flag\n     */\n    protected final boolean getRawBytes() {\n        return rawBytes;\n    }\n\n    /**\n     * Gets the width of the first column of output. This is {@code 0}\n     * unless raw bytes are being included in the output.\n     *\n     * @return {@code >= 0;} the width of the first column\n     */\n    protected final int getWidth1() {\n        if (rawBytes) {\n            return 5 + (hexCols * 2) + (hexCols / 2);\n        }\n\n        return 0;\n    }\n\n    /**\n     * Gets the width of the second column of output.\n     *\n     * @return {@code >= 0;} the width of the second column\n     */\n    protected final int getWidth2() {\n        int w1 = rawBytes ? (getWidth1() + 1) : 0;\n        return width - w1 - (indent * 2);\n    }\n\n    /**\n     * Constructs a hex data dump of the given portion of {@link #bytes}.\n     *\n     * @param offset offset to start dumping at\n     * @param len length to dump\n     * @return {@code non-null;} the dump\n     */\n    protected final String hexDump(int offset, int len) {\n        return Hex.dump(bytes, offset, len, offset, hexCols, 4);\n    }\n\n    /**\n     * Combines a pair of strings as two columns, or if this is one-column\n     * output, format the otherwise-second column.\n     *\n     * @param s1 {@code non-null;} the first column's string\n     * @param s2 {@code non-null;} the second column's string\n     * @return {@code non-null;} the combined output\n     */\n    protected final String twoColumns(String s1, String s2) {\n        int w1 = getWidth1();\n        int w2 = getWidth2();\n\n        try {\n            if (w1 == 0) {\n                int len2 = s2.length();\n                StringWriter sw = new StringWriter(len2 * 2);\n                IndentingWriter iw = new IndentingWriter(sw, w2, separator);\n\n                iw.write(s2);\n                if ((len2 == 0) || (s2.charAt(len2 - 1) != '\\n')) {\n                    iw.write('\\n');\n                }\n                iw.flush();\n\n                return sw.toString();\n            } else {\n                return TwoColumnOutput.toString(s1, w1, separator, s2, w2);\n            }\n        } catch (IOException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/dump/BlockDumper.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command.dump;\n\nimport com.taobao.android.dx.cf.code.BasicBlocker;\nimport com.taobao.android.dx.cf.code.ByteBlock;\nimport com.taobao.android.dx.cf.code.ByteBlockList;\nimport com.taobao.android.dx.cf.code.ByteCatchList;\nimport com.taobao.android.dx.cf.code.BytecodeArray;\nimport com.taobao.android.dx.cf.code.ConcreteMethod;\nimport com.taobao.android.dx.cf.code.Ropper;\nimport com.taobao.android.dx.cf.direct.CodeObserver;\nimport com.taobao.android.dx.cf.direct.DirectClassFile;\nimport com.taobao.android.dx.cf.direct.StdAttributeFactory;\nimport com.taobao.android.dx.cf.iface.Member;\nimport com.taobao.android.dx.cf.iface.Method;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.code.BasicBlock;\nimport com.taobao.android.dx.rop.code.BasicBlockList;\nimport com.taobao.android.dx.rop.code.DexTranslationAdvice;\nimport com.taobao.android.dx.rop.code.Insn;\nimport com.taobao.android.dx.rop.code.InsnList;\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.rop.code.TranslationAdvice;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.ssa.Optimizer;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.IntList;\nimport java.io.PrintStream;\n\n/**\n * Utility to dump basic block info from methods in a human-friendly form.\n */\npublic class BlockDumper\n        extends BaseDumper {\n    /** whether or not to registerize (make rop blocks) */\n    private boolean rop;\n\n    /**\n     * {@code null-ok;} the class file object being constructed;\n     * becomes non-null during {@link #dump}\n     */\n    protected DirectClassFile classFile;\n\n    /** whether or not to suppress dumping */\n    protected boolean suppressDump;\n\n    /** whether this is the first method being dumped */\n    private boolean first;\n\n    /** whether or not to run the ssa optimziations */\n    private boolean optimize;\n\n    /**\n     * Dumps the given array, interpreting it as a class file and dumping\n     * methods with indications of block-level stuff.\n     *\n     * @param bytes {@code non-null;} bytes of the (alleged) class file\n     * @param out {@code non-null;} where to dump to\n     * @param filePath the file path for the class, excluding any base\n     * directory specification\n     * @param rop whether or not to registerize (make rop blocks)\n     * @param args commandline parsedArgs\n     */\n    public static void dump(byte[] bytes, PrintStream out,\n            String filePath, boolean rop, Args args) {\n        BlockDumper bd = new BlockDumper(bytes, out, filePath,\n                rop, args);\n        bd.dump();\n    }\n\n    /**\n     * Constructs an instance. This class is not publicly instantiable.\n     * Use {@link #dump}.\n     */\n    BlockDumper(byte[] bytes, PrintStream out, String filePath,\n            boolean rop, Args args) {\n        super(bytes, out, filePath, args);\n\n        this.rop = rop;\n        this.classFile = null;\n        this.suppressDump = true;\n        this.first = true;\n        this.optimize = args.optimize;\n    }\n\n    /**\n     * Does the dumping.\n     */\n    public void dump() {\n        byte[] bytes = getBytes();\n        ByteArray ba = new ByteArray(bytes);\n\n        /*\n         * First, parse the file completely, so we can safely refer to\n         * attributes, etc.\n         */\n        classFile = new DirectClassFile(ba, getFilePath(), getStrictParse());\n        classFile.setAttributeFactory(StdAttributeFactory.THE_ONE);\n        classFile.getMagic(); // Force parsing to happen.\n\n        // Next, reparse it and observe the process.\n        DirectClassFile liveCf =\n            new DirectClassFile(ba, getFilePath(), getStrictParse());\n        liveCf.setAttributeFactory(StdAttributeFactory.THE_ONE);\n        liveCf.setObserver(this);\n        liveCf.getMagic(); // Force parsing to happen.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void changeIndent(int indentDelta) {\n        if (!suppressDump) {\n            super.changeIndent(indentDelta);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void parsed(ByteArray bytes, int offset, int len, String human) {\n        if (!suppressDump) {\n            super.parsed(bytes, offset, len, human);\n        }\n    }\n\n    /**\n     * @param name method name\n     * @return true if this method should be dumped\n     */\n    protected boolean shouldDumpMethod(String name) {\n        return args.method == null || args.method.equals(name);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void startParsingMember(ByteArray bytes, int offset, String name,\n            String descriptor) {\n        if (descriptor.indexOf('(') < 0) {\n            // It's a field, not a method\n            return;\n        }\n\n        if (!shouldDumpMethod(name)) {\n            return;\n        }\n\n        // Reset the dump cursor to the start of the method.\n        setAt(bytes, offset);\n\n        suppressDump = false;\n\n        if (first) {\n            first = false;\n        } else {\n            parsed(bytes, offset, 0, \"\\n\");\n        }\n\n        parsed(bytes, offset, 0, \"method \" + name + \" \" + descriptor);\n        suppressDump = true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void endParsingMember(ByteArray bytes, int offset, String name,\n            String descriptor, Member member) {\n        if (!(member instanceof Method)) {\n            return;\n        }\n\n        if (!shouldDumpMethod(name)) {\n            return;\n        }\n\n        if ((member.getAccessFlags() & (AccessFlags.ACC_ABSTRACT |\n                AccessFlags.ACC_NATIVE)) != 0) {\n            return;\n        }\n\n        ConcreteMethod meth =\n            new ConcreteMethod((Method) member, classFile, true, true);\n\n        if (rop) {\n            ropDump(meth);\n        } else {\n            regularDump(meth);\n        }\n    }\n\n    /**\n     * Does a regular basic block dump.\n     *\n     * @param meth {@code non-null;} method data to dump\n     */\n    private void regularDump(ConcreteMethod meth) {\n        BytecodeArray code = meth.getCode();\n        ByteArray bytes = code.getBytes();\n        ByteBlockList list = BasicBlocker.identifyBlocks(meth);\n        int sz = list.size();\n        CodeObserver codeObserver = new CodeObserver(bytes, BlockDumper.this);\n\n        // Reset the dump cursor to the start of the bytecode.\n        setAt(bytes, 0);\n\n        suppressDump = false;\n\n        int byteAt = 0;\n        for (int i = 0; i < sz; i++) {\n            ByteBlock bb = list.get(i);\n            int start = bb.getStart();\n            int end = bb.getEnd();\n\n            if (byteAt < start) {\n                parsed(bytes, byteAt, start - byteAt,\n                       \"dead code \" + Hex.u2(byteAt) + \"..\" + Hex.u2(start));\n            }\n\n            parsed(bytes, start, 0,\n                    \"block \" + Hex.u2(bb.getLabel()) + \": \" +\n                    Hex.u2(start) + \"..\" + Hex.u2(end));\n            changeIndent(1);\n\n            int len;\n            for (int j = start; j < end; j += len) {\n                len = code.parseInstruction(j, codeObserver);\n                codeObserver.setPreviousOffset(j);\n            }\n\n            IntList successors = bb.getSuccessors();\n            int ssz = successors.size();\n            if (ssz == 0) {\n                parsed(bytes, end, 0, \"returns\");\n            } else {\n                for (int j = 0; j < ssz; j++) {\n                    int succ = successors.get(j);\n                    parsed(bytes, end, 0, \"next \" + Hex.u2(succ));\n                }\n            }\n\n            ByteCatchList catches = bb.getCatches();\n            int csz = catches.size();\n            for (int j = 0; j < csz; j++) {\n                ByteCatchList.Item one = catches.get(j);\n                CstType exceptionClass = one.getExceptionClass();\n                parsed(bytes, end, 0,\n                       \"catch \" +\n                       ((exceptionClass == CstType.OBJECT) ? \"<any>\" :\n                        exceptionClass.toHuman()) + \" -> \" +\n                       Hex.u2(one.getHandlerPc()));\n            }\n\n            changeIndent(-1);\n            byteAt = end;\n        }\n\n        int end = bytes.size();\n        if (byteAt < end) {\n            parsed(bytes, byteAt, end - byteAt,\n                    \"dead code \" + Hex.u2(byteAt) + \"..\" + Hex.u2(end));\n        }\n\n        suppressDump = true;\n    }\n\n    /**\n     * Does a registerizing dump.\n     *\n     * @param meth {@code non-null;} method data to dump\n     */\n    private void ropDump(ConcreteMethod meth) {\n        TranslationAdvice advice = DexTranslationAdvice.THE_ONE;\n        BytecodeArray code = meth.getCode();\n        ByteArray bytes = code.getBytes();\n        RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods());\n        StringBuffer sb = new StringBuffer(2000);\n\n        if (optimize) {\n            boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());\n            int paramWidth = computeParamWidth(meth, isStatic);\n            rmeth =\n                Optimizer.optimize(rmeth, paramWidth, isStatic, true, advice);\n        }\n\n        BasicBlockList blocks = rmeth.getBlocks();\n        int[] order = blocks.getLabelsInOrder();\n\n        sb.append(\"first \" + Hex.u2(rmeth.getFirstLabel()) + \"\\n\");\n\n        for (int label : order) {\n            BasicBlock bb = blocks.get(blocks.indexOfLabel(label));\n            sb.append(\"block \");\n            sb.append(Hex.u2(label));\n            sb.append(\"\\n\");\n\n            IntList preds = rmeth.labelToPredecessors(label);\n            int psz = preds.size();\n            for (int i = 0; i < psz; i++) {\n                sb.append(\"  pred \");\n                sb.append(Hex.u2(preds.get(i)));\n                sb.append(\"\\n\");\n            }\n\n            InsnList il = bb.getInsns();\n            int ilsz = il.size();\n            for (int i = 0; i < ilsz; i++) {\n                Insn one = il.get(i);\n                sb.append(\"  \");\n                sb.append(il.get(i).toHuman());\n                sb.append(\"\\n\");\n            }\n\n            IntList successors = bb.getSuccessors();\n            int ssz = successors.size();\n            if (ssz == 0) {\n                sb.append(\"  returns\\n\");\n            } else {\n                int primary = bb.getPrimarySuccessor();\n                for (int i = 0; i < ssz; i++) {\n                    int succ = successors.get(i);\n                    sb.append(\"  next \");\n                    sb.append(Hex.u2(succ));\n\n                    if ((ssz != 1) && (succ == primary)) {\n                        sb.append(\" *\");\n                    }\n\n                    sb.append(\"\\n\");\n                }\n            }\n        }\n\n        suppressDump = false;\n        setAt(bytes, 0);\n        parsed(bytes, 0, bytes.size(), sb.toString());\n        suppressDump = true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/dump/ClassDumper.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command.dump;\n\nimport com.taobao.android.dx.cf.direct.DirectClassFile;\nimport com.taobao.android.dx.cf.direct.StdAttributeFactory;\nimport com.taobao.android.dx.util.ByteArray;\nimport java.io.PrintStream;\n\n/**\n * Utility to dump the contents of class files in a human-friendly form.\n */\npublic final class ClassDumper\n        extends BaseDumper {\n    /**\n     * Dumps the given array, interpreting it as a class file.\n     *\n     * @param bytes {@code non-null;} bytes of the (alleged) class file\n     * @param out {@code non-null;} where to dump to\n     * passed in as &lt;= 0\n     * @param filePath the file path for the class, excluding any base\n     * directory specification\n     * @param args bag of commandline arguments\n     */\n    public static void dump(byte[] bytes, PrintStream out,\n                            String filePath, Args args) {\n        ClassDumper cd =\n            new ClassDumper(bytes, out, filePath, args);\n        cd.dump();\n    }\n\n    /**\n     * Constructs an instance. This class is not publicly instantiable.\n     * Use {@link #dump}.\n     */\n    private ClassDumper(byte[] bytes, PrintStream out,\n                        String filePath, Args args) {\n        super(bytes, out, filePath, args);\n    }\n\n    /**\n     * Does the dumping.\n     */\n    public void dump() {\n        byte[] bytes = getBytes();\n        ByteArray ba = new ByteArray(bytes);\n        DirectClassFile cf =\n            new DirectClassFile(ba, getFilePath(), getStrictParse());\n\n        cf.setAttributeFactory(StdAttributeFactory.THE_ONE);\n        cf.setObserver(this);\n        cf.getMagic(); // Force parsing to happen.\n\n        int at = getAt();\n        if (at != bytes.length) {\n            parsed(ba, at, bytes.length - at, \"<extra data at end of file>\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/dump/DotDumper.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command.dump;\n\nimport com.taobao.android.dx.cf.code.ConcreteMethod;\nimport com.taobao.android.dx.cf.code.Ropper;\nimport com.taobao.android.dx.cf.direct.DirectClassFile;\nimport com.taobao.android.dx.cf.direct.StdAttributeFactory;\nimport com.taobao.android.dx.cf.iface.Member;\nimport com.taobao.android.dx.cf.iface.Method;\nimport com.taobao.android.dx.cf.iface.ParseObserver;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.code.BasicBlock;\nimport com.taobao.android.dx.rop.code.BasicBlockList;\nimport com.taobao.android.dx.rop.code.DexTranslationAdvice;\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.rop.code.TranslationAdvice;\nimport com.taobao.android.dx.ssa.Optimizer;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.IntList;\n\n/**\n * Dumps the pred/succ graph of methods into a format compatible\n * with the popular graph utility \"dot\".\n */\npublic class DotDumper implements ParseObserver {\n    private DirectClassFile classFile;\n\n    private final byte[] bytes;\n    private final String filePath;\n    private final boolean strictParse;\n    private final boolean optimize;\n    private final Args args;\n\n    static void dump(byte[] bytes, String filePath, Args args) {\n        new DotDumper(bytes, filePath, args).run();\n    }\n\n    DotDumper(byte[] bytes, String filePath, Args args) {\n        this.bytes = bytes;\n        this.filePath = filePath;\n        this.strictParse = args.strictParse;\n        this.optimize = args.optimize;\n        this.args = args;\n    }\n\n    private void run() {\n        ByteArray ba = new ByteArray(bytes);\n\n        /*\n         * First, parse the file completely, so we can safely refer to\n         * attributes, etc.\n         */\n        classFile = new DirectClassFile(ba, filePath, strictParse);\n        classFile.setAttributeFactory(StdAttributeFactory.THE_ONE);\n        classFile.getMagic(); // Force parsing to happen.\n\n        // Next, reparse it and observe the process.\n        DirectClassFile liveCf =\n            new DirectClassFile(ba, filePath, strictParse);\n        liveCf.setAttributeFactory(StdAttributeFactory.THE_ONE);\n        liveCf.setObserver(this);\n        liveCf.getMagic(); // Force parsing to happen.\n    }\n\n    /**\n     * @param name method name\n     * @return true if this method should be dumped\n     */\n    protected boolean shouldDumpMethod(String name) {\n        return args.method == null || args.method.equals(name);\n    }\n\n    public void changeIndent(int indentDelta) {\n        // This space intentionally left blank.\n    }\n\n    public void parsed(ByteArray bytes, int offset, int len, String human) {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    public void startParsingMember(ByteArray bytes, int offset, String name,\n                                   String descriptor) {\n        // This space intentionally left blank.\n    }\n\n    public void endParsingMember(ByteArray bytes, int offset, String name,\n                                 String descriptor, Member member) {\n        if (!(member instanceof Method)) {\n            return;\n        }\n\n        if (!shouldDumpMethod(name)) {\n            return;\n        }\n\n        ConcreteMethod meth = new ConcreteMethod((Method) member, classFile,\n                                                 true, true);\n\n        TranslationAdvice advice = DexTranslationAdvice.THE_ONE;\n        RopMethod rmeth =\n            Ropper.convert(meth, advice, classFile.getMethods());\n\n        if (optimize) {\n            boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());\n            rmeth = Optimizer.optimize(rmeth,\n                    BaseDumper.computeParamWidth(meth, isStatic), isStatic,\n                    true, advice);\n        }\n\n        System.out.println(\"digraph \"  + name + \"{\");\n\n        System.out.println(\"\\tfirst -> n\"\n                + Hex.u2(rmeth.getFirstLabel()) + \";\");\n\n        BasicBlockList blocks = rmeth.getBlocks();\n\n        int sz = blocks.size();\n        for (int i = 0; i < sz; i++) {\n            BasicBlock bb = blocks.get(i);\n            int label = bb.getLabel();\n            IntList successors = bb.getSuccessors();\n\n            if (successors.size() == 0) {\n                System.out.println(\"\\tn\" + Hex.u2(label) + \" -> returns;\");\n            } else if (successors.size() == 1) {\n                System.out.println(\"\\tn\" + Hex.u2(label) + \" -> n\"\n                        + Hex.u2(successors.get(0)) + \";\");\n            } else {\n                System.out.print(\"\\tn\" + Hex.u2(label) + \" -> {\");\n                for (int j = 0; j < successors.size(); j++ ) {\n                    int successor = successors.get(j);\n\n                    if (successor != bb.getPrimarySuccessor()) {\n                        System.out.print(\" n\" + Hex.u2(successor) + \" \");\n                    }\n\n                }\n                System.out.println(\"};\");\n\n                System.out.println(\"\\tn\" + Hex.u2(label) + \" -> n\"\n                        + Hex.u2(bb.getPrimarySuccessor())\n                        + \" [label=\\\"primary\\\"];\");\n\n\n            }\n        }\n\n        System.out.println(\"}\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/dump/Main.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command.dump;\n\nimport com.taobao.android.dex.util.FileUtils;\nimport com.taobao.android.dx.cf.iface.ParseException;\nimport com.taobao.android.dx.util.HexParser;\nimport java.io.UnsupportedEncodingException;\n\n/**\n * Main class for the class file dumper.\n */\npublic class Main {\n\n    static Args parsedArgs = new Args();\n\n    /**\n     * This class is uninstantiable.\n     */\n    private Main() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Run!\n     */\n    public static void main(String[] args) {\n        int at = 0;\n\n        for (/*at*/; at < args.length; at++) {\n            String arg = args[at];\n            if (arg.equals(\"--\") || !arg.startsWith(\"--\")) {\n                break;\n            } else if (arg.equals(\"--bytes\")) {\n                parsedArgs.rawBytes = true;\n            } else if (arg.equals(\"--basic-blocks\")) {\n                parsedArgs.basicBlocks = true;\n            } else if (arg.equals(\"--rop-blocks\")) {\n                parsedArgs.ropBlocks = true;\n            } else if (arg.equals(\"--optimize\")) {\n                parsedArgs.optimize = true;\n            } else if (arg.equals(\"--ssa-blocks\")) {\n                parsedArgs.ssaBlocks = true;\n            } else if (arg.startsWith(\"--ssa-step=\")) {\n                parsedArgs.ssaStep = arg.substring(arg.indexOf('=') + 1);\n            } else if (arg.equals(\"--debug\")) {\n                parsedArgs.debug = true;\n            } else if (arg.equals(\"--dot\")) {\n                parsedArgs.dotDump = true;\n            } else if (arg.equals(\"--strict\")) {\n                parsedArgs.strictParse = true;\n            } else if (arg.startsWith(\"--width=\")) {\n                arg = arg.substring(arg.indexOf('=') + 1);\n                parsedArgs.width = Integer.parseInt(arg);\n            } else if (arg.startsWith(\"--method=\")) {\n                arg = arg.substring(arg.indexOf('=') + 1);\n                parsedArgs.method = arg;\n            } else {\n                System.err.println(\"unknown option: \" + arg);\n                throw new RuntimeException(\"usage\");\n            }\n        }\n\n        if (at == args.length) {\n            System.err.println(\"no input files specified\");\n            throw new RuntimeException(\"usage\");\n        }\n\n        for (/*at*/; at < args.length; at++) {\n            try {\n                String name = args[at];\n                System.out.println(\"reading \" + name + \"...\");\n                byte[] bytes = FileUtils.readFile(name);\n                if (!name.endsWith(\".class\")) {\n                    String src;\n                    try {\n                        src = new String(bytes, \"utf-8\");\n                    } catch (UnsupportedEncodingException ex) {\n                        throw new RuntimeException(\"shouldn't happen\", ex);\n                    }\n                    bytes = HexParser.parse(src);\n                }\n                processOne(name, bytes);\n            } catch (ParseException ex) {\n                System.err.println(\"\\ntrouble parsing:\");\n                if (parsedArgs.debug) {\n                    ex.printStackTrace();\n                } else {\n                    ex.printContext(System.err);\n                }\n            }\n        }\n    }\n\n    /**\n     * Processes one file.\n     *\n     * @param name {@code non-null;} name of the file\n     * @param bytes {@code non-null;} contents of the file\n     */\n    private static void processOne(String name, byte[] bytes) {\n        if (parsedArgs.dotDump) {\n            DotDumper.dump(bytes, name, parsedArgs);\n        } else if (parsedArgs.basicBlocks) {\n            BlockDumper.dump(bytes, System.out, name, false, parsedArgs);\n        } else if (parsedArgs.ropBlocks) {\n            BlockDumper.dump(bytes, System.out, name, true, parsedArgs);\n        } else if (parsedArgs.ssaBlocks) {\n            // --optimize ignored with --ssa-blocks\n            parsedArgs.optimize = false;\n            SsaDumper.dump(bytes, System.out, name, parsedArgs);\n        } else {\n            ClassDumper.dump(bytes, System.out, name, parsedArgs);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/dump/SsaDumper.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command.dump;\n\nimport com.taobao.android.dx.cf.code.ConcreteMethod;\nimport com.taobao.android.dx.cf.code.Ropper;\nimport com.taobao.android.dx.cf.iface.Member;\nimport com.taobao.android.dx.cf.iface.Method;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.code.DexTranslationAdvice;\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.rop.code.TranslationAdvice;\nimport com.taobao.android.dx.ssa.Optimizer;\nimport com.taobao.android.dx.ssa.SsaBasicBlock;\nimport com.taobao.android.dx.ssa.SsaInsn;\nimport com.taobao.android.dx.ssa.SsaMethod;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.IntList;\nimport java.io.PrintStream;\nimport java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.Collections;\nimport java.util.EnumSet;\n\n/**\n * Dumper for the SSA-translated blocks of a method.\n */\npublic class SsaDumper extends BlockDumper {\n    /**\n     * Does the dump.\n     *\n     * @param bytes {@code non-null;} bytes of the original class file\n     * @param out {@code non-null;} where to dump to\n     * @param filePath the file path for the class, excluding any base\n     * directory specification\n     * @param args commandline parsedArgs\n     */\n    public static void dump(byte[] bytes, PrintStream out,\n            String filePath, Args args) {\n        SsaDumper sd = new SsaDumper(bytes, out, filePath, args);\n        sd.dump();\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param bytes {@code non-null;} bytes of the original class file\n     * @param out {@code non-null;} where to dump to\n     * @param filePath the file path for the class, excluding any base\n     * directory specification\n     * @param args commandline parsedArgs\n     */\n    private SsaDumper(byte[] bytes, PrintStream out, String filePath,\n            Args args) {\n        super(bytes, out, filePath, true, args);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void endParsingMember(ByteArray bytes, int offset, String name,\n            String descriptor, Member member) {\n        if (!(member instanceof Method)) {\n            return;\n        }\n\n        if (!shouldDumpMethod(name)) {\n            return;\n        }\n\n        if ((member.getAccessFlags() & (AccessFlags.ACC_ABSTRACT |\n                AccessFlags.ACC_NATIVE)) != 0) {\n            return;\n        }\n\n        ConcreteMethod meth =\n            new ConcreteMethod((Method) member, classFile, true, true);\n        TranslationAdvice advice = DexTranslationAdvice.THE_ONE;\n        RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods());\n        SsaMethod ssaMeth = null;\n        boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());\n        int paramWidth = computeParamWidth(meth, isStatic);\n\n        if (args.ssaStep == null) {\n            ssaMeth = Optimizer.debugNoRegisterAllocation(rmeth,\n                    paramWidth, isStatic, true, advice,\n                    EnumSet.allOf(Optimizer.OptionalStep.class));\n        } else if (\"edge-split\".equals(args.ssaStep)) {\n            ssaMeth = Optimizer.debugEdgeSplit(rmeth, paramWidth,\n                    isStatic, true, advice);\n        } else if (\"phi-placement\".equals(args.ssaStep)) {\n            ssaMeth = Optimizer.debugPhiPlacement(\n                    rmeth, paramWidth, isStatic, true, advice);\n        } else if (\"renaming\".equals(args.ssaStep)) {\n            ssaMeth = Optimizer.debugRenaming(\n                    rmeth, paramWidth, isStatic, true, advice);\n        } else if (\"dead-code\".equals(args.ssaStep)) {\n            ssaMeth = Optimizer.debugDeadCodeRemover(\n                    rmeth, paramWidth, isStatic,true, advice);\n        }\n\n        StringBuffer sb = new StringBuffer(2000);\n\n        sb.append(\"first \");\n        sb.append(Hex.u2(\n                ssaMeth.blockIndexToRopLabel(ssaMeth.getEntryBlockIndex())));\n        sb.append('\\n');\n\n        ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();\n        ArrayList<SsaBasicBlock> sortedBlocks =\n            (ArrayList<SsaBasicBlock>) blocks.clone();\n        Collections.sort(sortedBlocks, SsaBasicBlock.LABEL_COMPARATOR);\n\n        for (SsaBasicBlock block : sortedBlocks) {\n            sb.append(\"block \")\n                    .append(Hex.u2(block.getRopLabel())).append('\\n');\n\n            BitSet preds = block.getPredecessors();\n\n            for (int i = preds.nextSetBit(0); i >= 0;\n                 i = preds.nextSetBit(i+1)) {\n                sb.append(\"  pred \");\n                sb.append(Hex.u2(ssaMeth.blockIndexToRopLabel(i)));\n                sb.append('\\n');\n            }\n\n            sb.append(\"  live in:\" + block.getLiveInRegs());\n            sb.append(\"\\n\");\n\n            for (SsaInsn insn : block.getInsns()) {\n                sb.append(\"  \");\n                sb.append(insn.toHuman());\n                sb.append('\\n');\n            }\n\n            if (block.getSuccessors().cardinality() == 0) {\n                sb.append(\"  returns\\n\");\n            } else {\n                int primary = block.getPrimarySuccessorRopLabel();\n\n                IntList succLabelList = block.getRopLabelSuccessorList();\n\n                int szSuccLabels = succLabelList.size();\n\n                for (int i = 0; i < szSuccLabels; i++) {\n                    sb.append(\"  next \");\n                    sb.append(Hex.u2(succLabelList.get(i)));\n\n                    if (szSuccLabels != 1 && primary == succLabelList.get(i)) {\n                        sb.append(\" *\");\n                    }\n                    sb.append('\\n');\n                }\n            }\n\n            sb.append(\"  live out:\" + block.getLiveOutRegs());\n            sb.append(\"\\n\");\n        }\n\n        suppressDump = false;\n        setAt(bytes, 0);\n        parsed(bytes, 0, bytes.size(), sb.toString());\n        suppressDump = true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/findusages/FindUsages.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command.findusages;\n\nimport com.taobao.android.dex.ClassData;\nimport com.taobao.android.dex.ClassDef;\nimport com.taobao.android.dex.Dex;\nimport com.taobao.android.dex.FieldId;\nimport com.taobao.android.dex.MethodId;\nimport com.taobao.android.dx.io.CodeReader;\nimport com.taobao.android.dx.io.OpcodeInfo;\nimport com.taobao.android.dx.io.instructions.DecodedInstruction;\nimport java.io.PrintWriter;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.regex.Pattern;\n\npublic final class FindUsages {\n    private final Dex dex;\n    private final Set<Integer> methodIds;\n    private final Set<Integer> fieldIds;\n    private final CodeReader codeReader = new CodeReader();\n    private final PrintWriter out;\n\n    private ClassDef currentClass;\n    private ClassData.Method currentMethod;\n\n    public FindUsages(final Dex dex, String declaredBy, String memberName, final PrintWriter out) {\n        this.dex = dex;\n        this.out = out;\n\n        Set<Integer> typeStringIndexes = new HashSet<Integer>();\n        Set<Integer> memberNameIndexes = new HashSet<Integer>();\n        Pattern declaredByPattern = Pattern.compile(declaredBy);\n        Pattern memberNamePattern = Pattern.compile(memberName);\n        List<String> strings = dex.strings();\n        for (int i = 0; i < strings.size(); ++i) {\n            String string = strings.get(i);\n            if (declaredByPattern.matcher(string).matches()) {\n                typeStringIndexes.add(i);\n            }\n            if (memberNamePattern.matcher(string).matches()) {\n                memberNameIndexes.add(i);\n            }\n        }\n        if (typeStringIndexes.isEmpty() || memberNameIndexes.isEmpty()) {\n            methodIds = fieldIds = null;\n            return; // these symbols are not mentioned in this dex\n        }\n\n        methodIds = new HashSet<Integer>();\n        fieldIds = new HashSet<Integer>();\n        for (int typeStringIndex : typeStringIndexes) {\n            int typeIndex = Collections.binarySearch(dex.typeIds(), typeStringIndex);\n            if (typeIndex < 0) {\n                continue; // this type name isn't used as a type in this dex\n            }\n            methodIds.addAll(getMethodIds(dex, memberNameIndexes, typeIndex));\n            fieldIds.addAll(getFieldIds(dex, memberNameIndexes, typeIndex));\n        }\n\n        codeReader.setFieldVisitor(new CodeReader.Visitor() {\n            public void visit(DecodedInstruction[] all,\n                    DecodedInstruction one) {\n                int fieldId = one.getIndex();\n                if (fieldIds.contains(fieldId)) {\n                    out.println(location() + \": field reference \" + dex.fieldIds().get(fieldId)\n                            + \" (\" + OpcodeInfo.getName(one.getOpcode()) + \")\");\n                }\n            }\n        });\n\n        codeReader.setMethodVisitor(new CodeReader.Visitor() {\n            public void visit(DecodedInstruction[] all, DecodedInstruction one) {\n                int methodId = one.getIndex();\n                if (methodIds.contains(methodId)) {\n                    out.println(location() + \": method reference \" + dex.methodIds().get(methodId)\n                            + \" (\" + OpcodeInfo.getName(one.getOpcode()) + \")\");\n                }\n            }\n        });\n    }\n\n    private String location() {\n        String className = dex.typeNames().get(currentClass.getTypeIndex());\n        if (currentMethod != null) {\n            MethodId methodId = dex.methodIds().get(currentMethod.getMethodIndex());\n            return className + \".\" + dex.strings().get(methodId.getNameIndex());\n        } else {\n            return className;\n        }\n    }\n\n    /**\n     * Prints usages to out.\n     */\n    public void findUsages() {\n        if (fieldIds == null || methodIds == null) {\n            return;\n        }\n\n        for (ClassDef classDef : dex.classDefs()) {\n            currentClass = classDef;\n            currentMethod = null;\n\n            if (classDef.getClassDataOffset() == 0) {\n                continue;\n            }\n\n            ClassData classData = dex.readClassData(classDef);\n            for (ClassData.Field field : classData.allFields()) {\n                int fieldIndex = field.getFieldIndex();\n                if (fieldIds.contains(fieldIndex)) {\n                    out.println(location() + \" field declared \" + dex.fieldIds().get(fieldIndex));\n                }\n            }\n\n            for (ClassData.Method method : classData.allMethods()) {\n                currentMethod = method;\n                int methodIndex = method.getMethodIndex();\n                if (methodIds.contains(methodIndex)) {\n                    out.println(location() + \" method declared \" + dex.methodIds().get(methodIndex));\n                }\n                if (method.getCodeOffset() != 0) {\n                    codeReader.visitAll(dex.readCode(method).getInstructions());\n                }\n            }\n        }\n\n        currentClass = null;\n        currentMethod = null;\n    }\n\n    /**\n     * Returns the fields with {@code memberNameIndex} declared by {@code\n     * declaringType}.\n     */\n    private Set<Integer> getFieldIds(Dex dex, Set<Integer> memberNameIndexes, int declaringType) {\n        Set<Integer> fields = new HashSet<Integer>();\n        int fieldIndex = 0;\n        for (FieldId fieldId : dex.fieldIds()) {\n            if (memberNameIndexes.contains(fieldId.getNameIndex())\n                    && declaringType == fieldId.getDeclaringClassIndex()) {\n                fields.add(fieldIndex);\n            }\n            fieldIndex++;\n        }\n        return fields;\n    }\n\n    /**\n     * Returns the methods with {@code memberNameIndex} declared by {@code\n     * declaringType} and its subtypes.\n     */\n    private Set<Integer> getMethodIds(Dex dex, Set<Integer> memberNameIndexes, int declaringType) {\n        Set<Integer> subtypes = findAssignableTypes(dex, declaringType);\n\n        Set<Integer> methods = new HashSet<Integer>();\n        int methodIndex = 0;\n        for (MethodId method : dex.methodIds()) {\n            if (memberNameIndexes.contains(method.getNameIndex())\n                    && subtypes.contains(method.getDeclaringClassIndex())) {\n                methods.add(methodIndex);\n            }\n            methodIndex++;\n        }\n        return methods;\n    }\n\n    /**\n     * Returns the set of types that can be assigned to {@code typeIndex}.\n     */\n    private Set<Integer> findAssignableTypes(Dex dex, int typeIndex) {\n        Set<Integer> assignableTypes = new HashSet<Integer>();\n        assignableTypes.add(typeIndex);\n\n        for (ClassDef classDef : dex.classDefs()) {\n            if (assignableTypes.contains(classDef.getSupertypeIndex())) {\n                assignableTypes.add(classDef.getTypeIndex());\n                continue;\n            }\n\n            for (int implemented : classDef.getInterfaces()) {\n                if (assignableTypes.contains(implemented)) {\n                    assignableTypes.add(classDef.getTypeIndex());\n                    break;\n                }\n            }\n        }\n\n        return assignableTypes;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/findusages/Main.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command.findusages;\n\nimport com.taobao.android.dex.Dex;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.PrintWriter;\n\npublic final class Main {\n    public static void main(String[] args) throws IOException {\n        String dexFile = args[0];\n        String declaredBy = args[1];\n        String memberName = args[2];\n\n        Dex dex = new Dex(new File(dexFile));\n        PrintWriter out = new PrintWriter(System.out);\n        new FindUsages(dex, declaredBy, memberName, out).findUsages();\n        out.flush();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/grep/Grep.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command.grep;\n\nimport com.taobao.android.dex.ClassData;\nimport com.taobao.android.dex.ClassDef;\nimport com.taobao.android.dex.Dex;\nimport com.taobao.android.dex.EncodedValueReader;\nimport com.taobao.android.dex.MethodId;\nimport com.taobao.android.dx.io.CodeReader;\nimport com.taobao.android.dx.io.instructions.DecodedInstruction;\nimport java.io.PrintWriter;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.regex.Pattern;\n\npublic final class Grep {\n    private final Dex dex;\n    private final CodeReader codeReader = new CodeReader();\n    private final Set<Integer> stringIds;\n\n    private final PrintWriter out;\n    private int count = 0;\n\n    private ClassDef currentClass;\n    private ClassData.Method currentMethod;\n\n    public Grep(final Dex dex, Pattern pattern, final PrintWriter out) {\n        this.dex = dex;\n        this.out = out;\n\n        stringIds = getStringIds(dex, pattern);\n\n        codeReader.setStringVisitor(new CodeReader.Visitor() {\n            public void visit(DecodedInstruction[] all, DecodedInstruction one) {\n                encounterString(one.getIndex());\n            }\n        });\n    }\n\n    private void readArray(EncodedValueReader reader) {\n        for (int i = 0, size = reader.readArray(); i < size; i++) {\n            switch (reader.peek()) {\n            case EncodedValueReader.ENCODED_STRING:\n                encounterString(reader.readString());\n                break;\n            case EncodedValueReader.ENCODED_ARRAY:\n                readArray(reader);\n                break;\n            }\n        }\n    }\n\n    private void encounterString(int index) {\n        if (stringIds.contains(index)) {\n            out.println(location() + \" \" + dex.strings().get(index));\n            count++;\n        }\n    }\n\n    private String location() {\n        String className = dex.typeNames().get(currentClass.getTypeIndex());\n        if (currentMethod != null) {\n            MethodId methodId = dex.methodIds().get(currentMethod.getMethodIndex());\n            return className + \".\" + dex.strings().get(methodId.getNameIndex());\n        } else {\n            return className;\n        }\n    }\n\n    /**\n     * Prints usages to out. Returns the number of matches found.\n     */\n    public int grep() {\n        for (ClassDef classDef : dex.classDefs()) {\n            currentClass = classDef;\n            currentMethod = null;\n\n            if (classDef.getClassDataOffset() == 0) {\n                continue;\n            }\n\n            ClassData classData = dex.readClassData(classDef);\n\n            // find the strings in encoded constants\n            int staticValuesOffset = classDef.getStaticValuesOffset();\n            if (staticValuesOffset != 0) {\n                readArray(new EncodedValueReader(dex.open(staticValuesOffset)));\n            }\n\n            // find the strings in method bodies\n            for (ClassData.Method method : classData.allMethods()) {\n                currentMethod = method;\n                if (method.getCodeOffset() != 0) {\n                    codeReader.visitAll(dex.readCode(method).getInstructions());\n                }\n            }\n        }\n\n        currentClass = null;\n        currentMethod = null;\n        return count;\n    }\n\n    private Set<Integer> getStringIds(Dex dex, Pattern pattern) {\n        Set<Integer> stringIds = new HashSet<Integer>();\n        int stringIndex = 0;\n        for (String s : dex.strings()) {\n            if (pattern.matcher(s).find()) {\n                stringIds.add(stringIndex);\n            }\n            stringIndex++;\n        }\n        return stringIds;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/command/grep/Main.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.command.grep;\n\nimport com.taobao.android.dex.Dex;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.util.regex.Pattern;\n\npublic final class Main {\n    public static void main(String[] args) throws IOException {\n        String dexFile = args[0];\n        String pattern = args[1];\n\n        Dex dex = new Dex(new File(dexFile));\n        int count = new Grep(dex, Pattern.compile(pattern), new PrintWriter(System.out)).grep();\n        System.exit((count > 0) ? 0 : 1);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/DexOptions.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex;\n\nimport com.taobao.android.dex.DexFormat;\n\nimport com.taobao.android.dx.dex.code.DalvInsnList;\n\n/**\n * Container for options used to control details of dex file outputs.\n */\npublic class DexOptions {\n\n    /**\n     * Enable alignment support of 64-bit registers on Dalvik even registers. This is a temporary\n     * configuration flag allowing to quickly go back on the default behavior to face up to problem.\n     */\n    public static final boolean ALIGN_64BIT_REGS_SUPPORT = true;\n\n   /**\n    * Does final processing of 64-bit alignment into output finisher to gets output as\n    * {@link DalvInsnList} with 64-bit registers aligned at best. Disabled the final processing is\n    * required for tools such as Dasm to avoid modifying user inputs.\n    */\n    public boolean ALIGN_64BIT_REGS_IN_OUTPUT_FINISHER = ALIGN_64BIT_REGS_SUPPORT;\n\n    /** target API level */\n    public int targetApiLevel = DexFormat.API_NO_EXTENDED_OPCODES;\n\n    /** force outputs of jumbo opcodes */\n    public boolean forceJumbo = false;\n\n    /**\n     * Gets the dex file magic number corresponding to this instance.\n     */\n    public String getMagic() {\n        return DexFormat.apiToMagic(targetApiLevel);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/cf/AttributeTranslator.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.cf;\n\nimport com.taobao.android.dx.cf.attrib.AttAnnotationDefault;\nimport com.taobao.android.dx.cf.attrib.AttEnclosingMethod;\nimport com.taobao.android.dx.cf.attrib.AttExceptions;\nimport com.taobao.android.dx.cf.attrib.AttInnerClasses;\nimport com.taobao.android.dx.cf.attrib.AttRuntimeInvisibleAnnotations;\nimport com.taobao.android.dx.cf.attrib.AttRuntimeInvisibleParameterAnnotations;\nimport com.taobao.android.dx.cf.attrib.AttRuntimeVisibleAnnotations;\nimport com.taobao.android.dx.cf.attrib.AttRuntimeVisibleParameterAnnotations;\nimport com.taobao.android.dx.cf.attrib.AttSignature;\nimport com.taobao.android.dx.cf.attrib.InnerClassList;\nimport com.taobao.android.dx.cf.direct.DirectClassFile;\nimport com.taobao.android.dx.cf.iface.AttributeList;\nimport com.taobao.android.dx.cf.iface.Method;\nimport com.taobao.android.dx.cf.iface.MethodList;\nimport com.taobao.android.dx.dex.file.AnnotationUtils;\nimport com.taobao.android.dx.rop.annotation.Annotation;\nimport com.taobao.android.dx.rop.annotation.AnnotationVisibility;\nimport com.taobao.android.dx.rop.annotation.Annotations;\nimport com.taobao.android.dx.rop.annotation.AnnotationsList;\nimport com.taobao.android.dx.rop.annotation.NameValuePair;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.Warning;\nimport java.util.ArrayList;\n\n/**\n * Utility methods that translate various classfile attributes\n * into forms suitable for use in creating {@code dex} files.\n */\n/*package*/ class AttributeTranslator {\n    /**\n     * This class is uninstantiable.\n     */\n    private AttributeTranslator() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Gets the list of thrown exceptions for a given method.\n     *\n     * @param method {@code non-null;} the method in question\n     * @return {@code non-null;} the list of thrown exceptions\n     */\n    public static TypeList getExceptions(Method method) {\n        AttributeList attribs = method.getAttributes();\n        AttExceptions exceptions = (AttExceptions)\n            attribs.findFirst(AttExceptions.ATTRIBUTE_NAME);\n\n        if (exceptions == null) {\n            return StdTypeList.EMPTY;\n        }\n\n        return exceptions.getExceptions();\n    }\n\n    /**\n     * Gets the annotations out of a given {@link AttributeList}. This\n     * combines both visible and invisible annotations into a single\n     * result set and also adds in a system annotation for the\n     * {@code Signature} attribute if present.\n     *\n     * @param attribs {@code non-null;} the attributes list to search in\n     * @return {@code non-null;} the set of annotations, which may be empty\n     */\n    public static Annotations getAnnotations(AttributeList attribs) {\n        Annotations result = getAnnotations0(attribs);\n        Annotation signature = getSignature(attribs);\n\n        if (signature != null) {\n            result = Annotations.combine(result, signature);\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets the annotations out of a given class, similar to {@link\n     * #getAnnotations}, also including annotations for translations\n     * of class-level attributes {@code EnclosingMethod} and\n     * {@code InnerClasses}, if present. Additionally, if the\n     * class is an annotation class, then this also includes a\n     * representation of all the {@code AnnotationDefault}\n     * values.\n     *\n     * @param cf {@code non-null;} the class in question\n     * @param args {@code non-null;} the high-level options\n     * @return {@code non-null;} the set of annotations, which may be empty\n     */\n    public static Annotations getClassAnnotations(DirectClassFile cf,\n            CfOptions args) {\n        CstType thisClass = cf.getThisClass();\n        AttributeList attribs = cf.getAttributes();\n        Annotations result = getAnnotations(attribs);\n        Annotation enclosingMethod = translateEnclosingMethod(attribs);\n\n        try {\n            Annotations innerClassAnnotations =\n                translateInnerClasses(thisClass, attribs,\n                        enclosingMethod == null);\n            if (innerClassAnnotations != null) {\n                result = Annotations.combine(result, innerClassAnnotations);\n            }\n        } catch (Warning warn) {\n            args.warn.println(\"warning: \" + warn.getMessage());\n        }\n\n        if (enclosingMethod != null) {\n            result = Annotations.combine(result, enclosingMethod);\n        }\n\n        if (AccessFlags.isAnnotation(cf.getAccessFlags())) {\n            Annotation annotationDefault =\n                translateAnnotationDefaults(cf);\n            if (annotationDefault != null) {\n                result = Annotations.combine(result, annotationDefault);\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets the annotations out of a given method, similar to {@link\n     * #getAnnotations}, also including an annotation for the translation\n     * of the method-specific attribute {@code Exceptions}.\n     *\n     * @param method {@code non-null;} the method in question\n     * @return {@code non-null;} the set of annotations, which may be empty\n     */\n    public static Annotations getMethodAnnotations(Method method) {\n        Annotations result = getAnnotations(method.getAttributes());\n        TypeList exceptions = getExceptions(method);\n\n        if (exceptions.size() != 0) {\n            Annotation throwsAnnotation =\n                AnnotationUtils.makeThrows(exceptions);\n            result = Annotations.combine(result, throwsAnnotation);\n        }\n\n        return result;\n    }\n\n    /**\n     * Helper method for {@link #getAnnotations} which just gets the\n     * existing annotations, per se.\n     *\n     * @param attribs {@code non-null;} the attributes list to search in\n     * @return {@code non-null;} the set of annotations, which may be empty\n     */\n    private static Annotations getAnnotations0(AttributeList attribs) {\n        AttRuntimeVisibleAnnotations visible =\n            (AttRuntimeVisibleAnnotations)\n            attribs.findFirst(AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME);\n        AttRuntimeInvisibleAnnotations invisible =\n            (AttRuntimeInvisibleAnnotations)\n            attribs.findFirst(AttRuntimeInvisibleAnnotations.ATTRIBUTE_NAME);\n\n        if (visible == null) {\n            if (invisible == null) {\n                return Annotations.EMPTY;\n            }\n            return invisible.getAnnotations();\n        }\n\n        if (invisible == null) {\n            return visible.getAnnotations();\n        }\n\n        // Both are non-null, so combine them.\n\n        return Annotations.combine(visible.getAnnotations(),\n                invisible.getAnnotations());\n    }\n\n    /**\n     * Gets the {@code Signature} attribute out of a given\n     * {@link AttributeList}, if any, translating it to an annotation.\n     *\n     * @param attribs {@code non-null;} the attributes list to search in\n     * @return {@code null-ok;} the converted {@code Signature} annotation,\n     * if there was an attribute to translate\n     */\n    private static Annotation getSignature(AttributeList attribs) {\n        AttSignature signature = (AttSignature)\n            attribs.findFirst(AttSignature.ATTRIBUTE_NAME);\n\n        if (signature == null) {\n            return null;\n        }\n\n        return AnnotationUtils.makeSignature(signature.getSignature());\n    }\n\n    /**\n     * Gets the {@code EnclosingMethod} attribute out of a given\n     * {@link AttributeList}, if any, translating it to an annotation.\n     * If the class really has an enclosing method, this returns an\n     * {@code EnclosingMethod} annotation; if not, this returns\n     * an {@code EnclosingClass} annotation.\n     *\n     * @param attribs {@code non-null;} the attributes list to search in\n     * @return {@code null-ok;} the converted {@code EnclosingMethod} or\n     * {@code EnclosingClass} annotation, if there was an\n     * attribute to translate\n     */\n    private static Annotation translateEnclosingMethod(AttributeList attribs) {\n        AttEnclosingMethod enclosingMethod = (AttEnclosingMethod)\n            attribs.findFirst(AttEnclosingMethod.ATTRIBUTE_NAME);\n\n        if (enclosingMethod == null) {\n            return null;\n        }\n\n        CstType enclosingClass = enclosingMethod.getEnclosingClass();\n        CstNat nat = enclosingMethod.getMethod();\n\n        if (nat == null) {\n            /*\n             * Dalvik doesn't use EnclosingMethod annotations unless\n             * there really is an enclosing method. Anonymous classes\n             * are unambiguously identified by having an InnerClass\n             * annotation with an empty name along with an appropriate\n             * EnclosingClass.\n             */\n            return AnnotationUtils.makeEnclosingClass(enclosingClass);\n        }\n\n        return AnnotationUtils.makeEnclosingMethod(\n                new CstMethodRef(enclosingClass, nat));\n    }\n\n    /**\n     * Gets the {@code InnerClasses} attribute out of a given\n     * {@link AttributeList}, if any, translating it to one or more of an\n     * {@code InnerClass}, {@code EnclosingClass}, or\n     * {@code MemberClasses} annotation.\n     *\n     * @param thisClass {@code non-null;} type representing the class being\n     * processed\n     * @param attribs {@code non-null;} the attributes list to search in\n     * @param needEnclosingClass whether to include an\n     * {@code EnclosingClass} annotation\n     * @return {@code null-ok;} the converted list of annotations, if there\n     * was an attribute to translate\n     */\n    private static Annotations translateInnerClasses(CstType thisClass,\n            AttributeList attribs, boolean needEnclosingClass) {\n        AttInnerClasses innerClasses = (AttInnerClasses)\n            attribs.findFirst(AttInnerClasses.ATTRIBUTE_NAME);\n\n        if (innerClasses == null) {\n            return null;\n        }\n\n        /*\n         * Search the list for the element representing the current class\n         * as well as for any named member classes.\n         */\n\n        InnerClassList list = innerClasses.getInnerClasses();\n        int size = list.size();\n        InnerClassList.Item foundThisClass = null;\n        ArrayList<Type> membersList = new ArrayList<Type>();\n\n        for (int i = 0; i < size; i++) {\n            InnerClassList.Item item = list.get(i);\n            CstType innerClass = item.getInnerClass();\n            if (innerClass.equals(thisClass)) {\n                foundThisClass = item;\n            } else if (thisClass.equals(item.getOuterClass())) {\n                membersList.add(innerClass.getClassType());\n            }\n        }\n\n        int membersSize = membersList.size();\n\n        if ((foundThisClass == null) && (membersSize == 0)) {\n            return null;\n        }\n\n        Annotations result = new Annotations();\n\n        if (foundThisClass != null) {\n            result.add(AnnotationUtils.makeInnerClass(\n                               foundThisClass.getInnerName(),\n                               foundThisClass.getAccessFlags()));\n            if (needEnclosingClass) {\n                CstType outer = foundThisClass.getOuterClass();\n                if (outer == null) {\n                    throw new Warning(\n                            \"Ignoring InnerClasses attribute for an \" +\n                            \"anonymous inner class\\n\" +\n                            \"(\" + thisClass.toHuman() +\n                            \") that doesn't come with an\\n\" +\n                            \"associated EnclosingMethod attribute. \" +\n                            \"This class was probably produced by a\\n\" +\n                            \"compiler that did not target the modern \" +\n                            \".class file format. The recommended\\n\" +\n                            \"solution is to recompile the class from \" +\n                            \"source, using an up-to-date compiler\\n\" +\n                            \"and without specifying any \\\"-target\\\" type \" +\n                            \"options. The consequence of ignoring\\n\" +\n                            \"this warning is that reflective operations \" +\n                            \"on this class will incorrectly\\n\" +\n                            \"indicate that it is *not* an inner class.\");\n                }\n                result.add(AnnotationUtils.makeEnclosingClass(\n                                   foundThisClass.getOuterClass()));\n            }\n        }\n\n        if (membersSize != 0) {\n            StdTypeList typeList = new StdTypeList(membersSize);\n            for (int i = 0; i < membersSize; i++) {\n                typeList.set(i, membersList.get(i));\n            }\n            typeList.setImmutable();\n            result.add(AnnotationUtils.makeMemberClasses(typeList));\n        }\n\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Gets the parameter annotations out of a given method. This\n     * combines both visible and invisible annotations into a single\n     * result set.\n     *\n     * @param method {@code non-null;} the method in question\n     * @return {@code non-null;} the list of annotation sets, which may be\n     * empty\n     */\n    public static AnnotationsList getParameterAnnotations(Method method) {\n        AttributeList attribs = method.getAttributes();\n        AttRuntimeVisibleParameterAnnotations visible =\n            (AttRuntimeVisibleParameterAnnotations)\n            attribs.findFirst(\n                    AttRuntimeVisibleParameterAnnotations.ATTRIBUTE_NAME);\n        AttRuntimeInvisibleParameterAnnotations invisible =\n            (AttRuntimeInvisibleParameterAnnotations)\n            attribs.findFirst(\n                    AttRuntimeInvisibleParameterAnnotations.ATTRIBUTE_NAME);\n\n        if (visible == null) {\n            if (invisible == null) {\n                return AnnotationsList.EMPTY;\n            }\n            return invisible.getParameterAnnotations();\n        }\n\n        if (invisible == null) {\n            return visible.getParameterAnnotations();\n        }\n\n        // Both are non-null, so combine them.\n\n        return AnnotationsList.combine(visible.getParameterAnnotations(),\n                invisible.getParameterAnnotations());\n    }\n\n    /**\n     * Gets the {@code AnnotationDefault} attributes out of a\n     * given class, if any, reforming them as an\n     * {@code AnnotationDefault} annotation.\n     *\n     * @param cf {@code non-null;} the class in question\n     * @return {@code null-ok;} an appropriately-constructed\n     * {@code AnnotationDefault} annotation, if there were any\n     * annotation defaults in the class, or {@code null} if not\n     */\n    private static Annotation translateAnnotationDefaults(DirectClassFile cf) {\n        CstType thisClass = cf.getThisClass();\n        MethodList methods = cf.getMethods();\n        int sz = methods.size();\n        Annotation result =\n            new Annotation(thisClass, AnnotationVisibility.EMBEDDED);\n        boolean any = false;\n\n        for (int i = 0; i < sz; i++) {\n            Method one = methods.get(i);\n            AttributeList attribs = one.getAttributes();\n            AttAnnotationDefault oneDefault = (AttAnnotationDefault)\n                attribs.findFirst(AttAnnotationDefault.ATTRIBUTE_NAME);\n\n            if (oneDefault != null) {\n                NameValuePair pair = new NameValuePair(\n                        one.getNat().getName(),\n                        oneDefault.getValue());\n                result.add(pair);\n                any = true;\n            }\n        }\n\n        if (! any) {\n            return null;\n        }\n\n        result.setImmutable();\n        return AnnotationUtils.makeAnnotationDefault(result);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/cf/CfOptions.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.cf;\n\nimport com.taobao.android.dx.dex.code.PositionList;\nimport java.io.PrintStream;\n\n/**\n * A class to contain options passed into dex.cf\n */\npublic class CfOptions {\n    /** how much source position info to preserve */\n    public int positionInfo = PositionList.LINES;\n\n    /** whether to keep local variable information */\n    public boolean localInfo = false;\n\n    /** whether strict file-name-vs-class-name checking should be done */\n    public boolean strictNameCheck = true;\n\n    /** whether to do SSA/register optimization */\n    public boolean optimize = false;\n\n    /** filename containing list of methods to optimize */\n    public String optimizeListFile = null;\n\n    /** filename containing list of methods <i>not</i> to optimize */\n    public String dontOptimizeListFile = null;\n\n    /** whether to print statistics to stdout at end of compile cycle */\n    public boolean statistics;\n\n    /** where to issue warnings to */\n    public PrintStream warn = System.err;\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/cf/CfTranslator.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.cf;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dx.cf.code.ConcreteMethod;\nimport com.taobao.android.dx.cf.code.Ropper;\nimport com.taobao.android.dx.cf.direct.DirectClassFile;\nimport com.taobao.android.dx.cf.iface.Field;\nimport com.taobao.android.dx.cf.iface.FieldList;\nimport com.taobao.android.dx.cf.iface.Method;\nimport com.taobao.android.dx.cf.iface.MethodList;\nimport com.taobao.android.dx.dex.DexOptions;\nimport com.taobao.android.dx.dex.code.DalvCode;\nimport com.taobao.android.dx.dex.code.PositionList;\nimport com.taobao.android.dx.dex.code.RopTranslator;\nimport com.taobao.android.dx.dex.file.ClassDefItem;\nimport com.taobao.android.dx.dex.file.DexFile;\nimport com.taobao.android.dx.dex.file.EncodedField;\nimport com.taobao.android.dx.dex.file.EncodedMethod;\nimport com.taobao.android.dx.dex.file.FieldIdsSection;\nimport com.taobao.android.dx.dex.file.MethodIdsSection;\nimport com.taobao.android.dx.rop.annotation.Annotations;\nimport com.taobao.android.dx.rop.annotation.AnnotationsList;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.code.DexTranslationAdvice;\nimport com.taobao.android.dx.rop.code.LocalVariableExtractor;\nimport com.taobao.android.dx.rop.code.LocalVariableInfo;\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.rop.code.TranslationAdvice;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.ConstantPool;\nimport com.taobao.android.dx.rop.cst.CstBaseMethodRef;\nimport com.taobao.android.dx.rop.cst.CstBoolean;\nimport com.taobao.android.dx.rop.cst.CstByte;\nimport com.taobao.android.dx.rop.cst.CstChar;\nimport com.taobao.android.dx.rop.cst.CstEnumRef;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.cst.CstInterfaceMethodRef;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstShort;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.cst.TypedConstant;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.ssa.Optimizer;\n\n/**\n * Static method that turns {@code byte[]}s containing Java\n * classfiles into {@link ClassDefItem} instances.\n */\npublic class CfTranslator {\n    /** set to {@code true} to enable development-time debugging code */\n    private static final boolean DEBUG = false;\n\n    /**\n     * This class is uninstantiable.\n     */\n    private CfTranslator() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Takes a {@code byte[]}, interprets it as a Java classfile, and\n     * translates it into a {@link ClassDefItem}.\n     *\n     * @param cf {@code non-null;} the class file\n     * @param bytes {@code non-null;} contents of the file\n     * @param cfOptions options for class translation\n     * @param dexOptions options for dex output\n     * @param dexFile {@code non-null;} dex output\n     * @return {@code non-null;} the translated class\n     */\n    public static ClassDefItem translate(DirectClassFile cf, byte[] bytes,\n            CfOptions cfOptions, DexOptions dexOptions, DexFile dexFile) {\n        try {\n            return translate0(cf, bytes, cfOptions, dexOptions, dexFile);\n        } catch (RuntimeException ex) {\n            String msg = \"...while processing \" + cf.getFilePath();\n            throw ExceptionWithContext.withContext(ex, msg);\n        }\n    }\n\n    /**\n     * Performs the main act of translation. This method is separated\n     * from {@link #translate} just to keep things a bit simpler in\n     * terms of exception handling.\n     *\n     * @param cf {@code non-null;} the class file\n     * @param bytes {@code non-null;} contents of the file\n     * @param cfOptions options for class translation\n     * @param dexOptions options for dex output\n     * @param dexFile {@code non-null;} dex output\n     * @return {@code non-null;} the translated class\n     */\n    private static ClassDefItem translate0(DirectClassFile cf, byte[] bytes,\n            CfOptions cfOptions, DexOptions dexOptions, DexFile dexFile) {\n\n        OptimizerOptions.loadOptimizeLists(cfOptions.optimizeListFile,\n                cfOptions.dontOptimizeListFile);\n\n        // Build up a class to output.\n\n        CstType thisClass = cf.getThisClass();\n        int classAccessFlags = cf.getAccessFlags() & ~AccessFlags.ACC_SUPER;\n        CstString sourceFile = (cfOptions.positionInfo == PositionList.NONE) ? null :\n            cf.getSourceFile();\n        ClassDefItem out =\n            new ClassDefItem(thisClass, classAccessFlags,\n                    cf.getSuperclass(), cf.getInterfaces(), sourceFile);\n\n        Annotations classAnnotations =\n            AttributeTranslator.getClassAnnotations(cf, cfOptions);\n        if (classAnnotations.size() != 0) {\n            out.setClassAnnotations(classAnnotations, dexFile);\n        }\n\n        FieldIdsSection fieldIdsSection = dexFile.getFieldIds();\n        MethodIdsSection methodIdsSection = dexFile.getMethodIds();\n        processFields(cf, out, dexFile);\n        processMethods(cf, cfOptions, dexOptions, out, dexFile);\n\n        // intern constant pool method, field and type references\n        ConstantPool constantPool = cf.getConstantPool();\n        int constantPoolSize = constantPool.size();\n\n        for (int i = 0; i < constantPoolSize; i++) {\n            Constant constant = constantPool.getOrNull(i);\n            if (constant instanceof CstMethodRef) {\n                methodIdsSection.intern((CstBaseMethodRef) constant);\n            } else if (constant instanceof CstInterfaceMethodRef) {\n                methodIdsSection.intern(((CstInterfaceMethodRef) constant).toMethodRef());\n            } else if (constant instanceof CstFieldRef) {\n                fieldIdsSection.intern((CstFieldRef) constant);\n            } else if (constant instanceof CstEnumRef) {\n                fieldIdsSection.intern(((CstEnumRef) constant).getFieldRef());\n            }\n        }\n\n        return out;\n    }\n\n    /**\n     * Processes the fields of the given class.\n     *\n     * @param cf {@code non-null;} class being translated\n     * @param out {@code non-null;} output class\n     * @param dexFile {@code non-null;} dex output\n     */\n    private static void processFields(\n            DirectClassFile cf, ClassDefItem out, DexFile dexFile) {\n        CstType thisClass = cf.getThisClass();\n        FieldList fields = cf.getFields();\n        int sz = fields.size();\n\n        for (int i = 0; i < sz; i++) {\n            Field one = fields.get(i);\n            try {\n                CstFieldRef field = new CstFieldRef(thisClass, one.getNat());\n                int accessFlags = one.getAccessFlags();\n\n                if (AccessFlags.isStatic(accessFlags)) {\n                    TypedConstant constVal = one.getConstantValue();\n                    EncodedField fi = new EncodedField(field, accessFlags);\n                    if (constVal != null) {\n                        constVal = coerceConstant(constVal, field.getType());\n                    }\n                    out.addStaticField(fi, constVal);\n                } else {\n                    EncodedField fi = new EncodedField(field, accessFlags);\n                    out.addInstanceField(fi);\n                }\n\n                Annotations annotations =\n                    AttributeTranslator.getAnnotations(one.getAttributes());\n                if (annotations.size() != 0) {\n                    out.addFieldAnnotations(field, annotations, dexFile);\n                }\n                dexFile.getFieldIds().intern(field);\n            } catch (RuntimeException ex) {\n                String msg = \"...while processing \" + one.getName().toHuman() +\n                    \" \" + one.getDescriptor().toHuman();\n                throw ExceptionWithContext.withContext(ex, msg);\n            }\n        }\n    }\n\n    /**\n     * Helper for {@link #processFields}, which translates constants into\n     * more specific types if necessary.\n     *\n     * @param constant {@code non-null;} the constant in question\n     * @param type {@code non-null;} the desired type\n     */\n    private static TypedConstant coerceConstant(TypedConstant constant,\n            Type type) {\n        Type constantType = constant.getType();\n\n        if (constantType.equals(type)) {\n            return constant;\n        }\n\n        switch (type.getBasicType()) {\n            case Type.BT_BOOLEAN: {\n                return CstBoolean.make(((CstInteger) constant).getValue());\n            }\n            case Type.BT_BYTE: {\n                return CstByte.make(((CstInteger) constant).getValue());\n            }\n            case Type.BT_CHAR: {\n                return CstChar.make(((CstInteger) constant).getValue());\n            }\n            case Type.BT_SHORT: {\n                return CstShort.make(((CstInteger) constant).getValue());\n            }\n            default: {\n                throw new UnsupportedOperationException(\"can't coerce \" +\n                        constant + \" to \" + type);\n            }\n        }\n    }\n\n    /**\n     * Processes the methods of the given class.\n     *\n     * @param cf {@code non-null;} class being translated\n     * @param cfOptions {@code non-null;} options for class translation\n     * @param dexOptions {@code non-null;} options for dex output\n     * @param out {@code non-null;} output class\n     * @param dexFile {@code non-null;} dex output\n     */\n    private static void processMethods(DirectClassFile cf, CfOptions cfOptions,\n            DexOptions dexOptions, ClassDefItem out, DexFile dexFile) {\n        CstType thisClass = cf.getThisClass();\n        MethodList methods = cf.getMethods();\n        int sz = methods.size();\n\n        for (int i = 0; i < sz; i++) {\n            Method one = methods.get(i);\n            try {\n                CstMethodRef meth = new CstMethodRef(thisClass, one.getNat());\n                int accessFlags = one.getAccessFlags();\n                boolean isStatic = AccessFlags.isStatic(accessFlags);\n                boolean isPrivate = AccessFlags.isPrivate(accessFlags);\n                boolean isNative = AccessFlags.isNative(accessFlags);\n                boolean isAbstract = AccessFlags.isAbstract(accessFlags);\n                boolean isConstructor = meth.isInstanceInit() ||\n                    meth.isClassInit();\n                DalvCode code;\n\n                if (isNative || isAbstract) {\n                    // There's no code for native or abstract methods.\n                    code = null;\n                } else {\n                    ConcreteMethod concrete =\n                        new ConcreteMethod(one, cf,\n                                (cfOptions.positionInfo != PositionList.NONE),\n                                cfOptions.localInfo);\n\n                    TranslationAdvice advice;\n\n                    advice = DexTranslationAdvice.THE_ONE;\n\n                    RopMethod rmeth = Ropper.convert(concrete, advice, methods);\n                    RopMethod nonOptRmeth = null;\n                    int paramSize;\n\n                    paramSize = meth.getParameterWordCount(isStatic);\n\n                    String canonicalName\n                            = thisClass.getClassType().getDescriptor()\n                                + \".\" + one.getName().getString();\n\n                    if (cfOptions.optimize &&\n                            OptimizerOptions.shouldOptimize(canonicalName)) {\n                        if (DEBUG) {\n                            System.err.println(\"Optimizing \" + canonicalName);\n                        }\n\n                        nonOptRmeth = rmeth;\n                        rmeth = Optimizer.optimize(rmeth,\n                                paramSize, isStatic, cfOptions.localInfo, advice);\n\n                        if (DEBUG) {\n                            OptimizerOptions.compareOptimizerStep(nonOptRmeth,\n                                    paramSize, isStatic, cfOptions, advice, rmeth);\n                        }\n\n                        if (cfOptions.statistics) {\n                            CodeStatistics.updateRopStatistics(\n                                    nonOptRmeth, rmeth);\n                        }\n                    }\n\n                    LocalVariableInfo locals = null;\n\n                    if (cfOptions.localInfo) {\n                        locals = LocalVariableExtractor.extract(rmeth);\n                    }\n\n                    code = RopTranslator.translate(rmeth, cfOptions.positionInfo,\n                            locals, paramSize, dexOptions);\n\n                    if (cfOptions.statistics && nonOptRmeth != null) {\n                        updateDexStatistics(cfOptions, dexOptions, rmeth, nonOptRmeth, locals,\n                                paramSize, concrete.getCode().size());\n                    }\n                }\n\n                // Preserve the synchronized flag as its \"declared\" variant...\n                if (AccessFlags.isSynchronized(accessFlags)) {\n                    accessFlags |= AccessFlags.ACC_DECLARED_SYNCHRONIZED;\n\n                    /*\n                     * ...but only native methods are actually allowed to be\n                     * synchronized.\n                     */\n                    if (!isNative) {\n                        accessFlags &= ~AccessFlags.ACC_SYNCHRONIZED;\n                    }\n                }\n\n                if (isConstructor) {\n                    accessFlags |= AccessFlags.ACC_CONSTRUCTOR;\n                }\n\n                TypeList exceptions = AttributeTranslator.getExceptions(one);\n                EncodedMethod mi =\n                    new EncodedMethod(meth, accessFlags, code, exceptions);\n\n                if (meth.isInstanceInit() || meth.isClassInit() ||\n                    isStatic || isPrivate) {\n                    out.addDirectMethod(mi);\n                } else {\n                    out.addVirtualMethod(mi);\n                }\n\n                Annotations annotations =\n                    AttributeTranslator.getMethodAnnotations(one);\n                if (annotations.size() != 0) {\n                    out.addMethodAnnotations(meth, annotations, dexFile);\n                }\n\n                AnnotationsList list =\n                    AttributeTranslator.getParameterAnnotations(one);\n                if (list.size() != 0) {\n                    out.addParameterAnnotations(meth, list, dexFile);\n                }\n                dexFile.getMethodIds().intern(meth);\n            } catch (RuntimeException ex) {\n                String msg = \"...while processing \" + one.getName().toHuman() +\n                    \" \" + one.getDescriptor().toHuman();\n                throw ExceptionWithContext.withContext(ex, msg);\n            }\n        }\n    }\n\n    /**\n     * Helper that updates the dex statistics.\n     */\n    private static void updateDexStatistics(CfOptions cfOptions, DexOptions dexOptions,\n            RopMethod optRmeth, RopMethod nonOptRmeth,\n            LocalVariableInfo locals, int paramSize, int originalByteCount) {\n        /*\n         * Run rop->dex again on optimized vs. non-optimized method to\n         * collect statistics. We have to totally convert both ways,\n         * since converting the \"real\" method getting added to the\n         * file would corrupt it (by messing with its constant pool\n         * indices).\n         */\n\n        DalvCode optCode = RopTranslator.translate(optRmeth,\n                cfOptions.positionInfo, locals, paramSize, dexOptions);\n        DalvCode nonOptCode = RopTranslator.translate(nonOptRmeth,\n                cfOptions.positionInfo, locals, paramSize, dexOptions);\n\n        /*\n         * Fake out the indices, so code.getInsns() can work well enough\n         * for the current purpose.\n         */\n\n        DalvCode.AssignIndicesCallback callback =\n            new DalvCode.AssignIndicesCallback() {\n                public int getIndex(Constant cst) {\n                    // Everything is at index 0!\n                    return 0;\n                }\n            };\n\n        optCode.assignIndices(callback);\n        nonOptCode.assignIndices(callback);\n\n        CodeStatistics.updateDexStatistics(nonOptCode, optCode);\n        CodeStatistics.updateOriginalByteCount(originalByteCount);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/cf/CodeStatistics.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.cf;\n\nimport com.taobao.android.dx.dex.code.DalvCode;\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport java.io.PrintStream;\n\n/**\n * Static methods and variables for collecting statistics on generated\n * code.\n */\npublic final class CodeStatistics {\n    /** set to {@code true} to enable development-time debugging code */\n    private static final boolean DEBUG = false;\n\n    /**\n     * running sum of the number of registers added/removed in\n     * SSA form by the optimizer\n     */\n    public static int runningDeltaRegisters = 0;\n\n    /**\n     * running sum of the number of insns added/removed in\n     * SSA form by the optimizer\n     */\n    public static int runningDeltaInsns = 0;\n\n    /** running sum of the total number of Rop insns processed */\n    public static int runningTotalInsns = 0;\n\n    /**\n     * running sum of the number of dex-form registers added/removed in\n     * SSA form by the optimizer. Only valid if args.statistics is true.\n     */\n    public static int dexRunningDeltaRegisters = 0;\n\n    /**\n     * running sum of the number of dex-form insns (actually code\n     * units) added/removed in SSA form by the optimizer. Only valid\n     * if args.statistics is true.\n     */\n    public static int dexRunningDeltaInsns = 0;\n\n    /**\n     * running sum of the total number of dex insns (actually code\n     * units) processed\n     */\n    public static int dexRunningTotalInsns = 0;\n\n    /** running sum of original class bytecode bytes */\n    public static int runningOriginalBytes = 0;\n\n    /**\n     * This class is uninstantiable.\n     */\n    private CodeStatistics() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Updates the number of original bytecode bytes processed.\n     *\n     * @param count {@code >= 0;} the number of bytes to add\n     */\n    public static void updateOriginalByteCount(int count) {\n        runningOriginalBytes += count;\n    }\n\n    /**\n     * Updates the dex statistics.\n     *\n     * @param nonOptCode non-optimized code block\n     * @param code optimized code block\n     */\n    public static void updateDexStatistics(DalvCode nonOptCode,\n            DalvCode code) {\n        if (DEBUG) {\n            System.err.println(\"dex insns (old/new) \"\n                    + nonOptCode.getInsns().codeSize()\n                    + \"/\" + code.getInsns().codeSize()\n                    + \" regs (o/n) \"\n                    + nonOptCode.getInsns().getRegistersSize()\n                    + \"/\" + code.getInsns().getRegistersSize()\n            );\n        }\n\n        dexRunningDeltaInsns\n            += (code.getInsns().codeSize()\n                - nonOptCode.getInsns().codeSize());\n\n        dexRunningDeltaRegisters\n            += (code.getInsns().getRegistersSize()\n                - nonOptCode.getInsns().getRegistersSize());\n\n        dexRunningTotalInsns += code.getInsns().codeSize();\n    }\n\n    /**\n     * Updates the ROP statistics.\n     *\n     * @param nonOptRmeth non-optimized method\n     * @param rmeth optimized method\n     */\n    public static void updateRopStatistics(RopMethod nonOptRmeth,\n            RopMethod rmeth) {\n        int oldCountInsns\n                = nonOptRmeth.getBlocks().getEffectiveInstructionCount();\n        int oldCountRegs = nonOptRmeth.getBlocks().getRegCount();\n\n        if (DEBUG) {\n            System.err.println(\"insns (old/new): \"\n                    + oldCountInsns + \"/\"\n                    + rmeth.getBlocks().getEffectiveInstructionCount()\n                    + \" regs (o/n):\" + oldCountRegs\n                    + \"/\"  +  rmeth.getBlocks().getRegCount());\n        }\n\n        int newCountInsns\n                = rmeth.getBlocks().getEffectiveInstructionCount();\n\n        runningDeltaInsns\n            += (newCountInsns - oldCountInsns);\n\n        runningDeltaRegisters\n            += (rmeth.getBlocks().getRegCount() - oldCountRegs);\n\n        runningTotalInsns += newCountInsns;\n    }\n\n    /**\n     * Prints out the collected statistics.\n     *\n     * @param out {@code non-null;} where to output to\n     */\n    public static void dumpStatistics(PrintStream out) {\n        out.printf(\"Optimizer Delta Rop Insns: %d total: %d \"\n                + \"(%.2f%%) Delta Registers: %d\\n\",\n                runningDeltaInsns,\n                runningTotalInsns,\n                (100.0 * (((float) runningDeltaInsns)\n                        / (runningTotalInsns + Math.abs(runningDeltaInsns)))),\n                runningDeltaRegisters);\n\n        out.printf(\"Optimizer Delta Dex Insns: Insns: %d total: %d \"\n                + \"(%.2f%%) Delta Registers: %d\\n\",\n                dexRunningDeltaInsns,\n                dexRunningTotalInsns,\n                (100.0 * (((float) dexRunningDeltaInsns)\n                        / (dexRunningTotalInsns\n                                + Math.abs(dexRunningDeltaInsns)))),\n                dexRunningDeltaRegisters);\n\n        out.printf(\"Original bytecode byte count: %d\\n\",\n                runningOriginalBytes);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/cf/OptimizerOptions.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.cf;\n\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.rop.code.TranslationAdvice;\nimport com.taobao.android.dx.ssa.Optimizer;\nimport java.io.BufferedReader;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.util.EnumSet;\nimport java.util.HashSet;\n\n/**\n * Settings for optimization of code.\n */\npublic class OptimizerOptions {\n    /**\n     * {@code null-ok;} hash set of class name + method names that\n     * should be optimized. {@code null} if this constraint was not\n     * specified on the command line\n     */\n    private static HashSet<String> optimizeList;\n\n    /**\n     * {@code null-ok;} hash set of class name + method names that should NOT\n     * be optimized.  null if this constraint was not specified on the\n     * command line\n     */\n    private static HashSet<String> dontOptimizeList;\n\n    /** true if the above lists have been loaded */\n    private static boolean optimizeListsLoaded;\n\n    /**\n     * This class is uninstantiable.\n     */\n    private OptimizerOptions() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Loads the optimize/don't optimize lists from files.\n     *\n     * @param optimizeListFile Pathname\n     * @param dontOptimizeListFile Pathname\n     */\n    public static void loadOptimizeLists(String optimizeListFile,\n            String dontOptimizeListFile) {\n        if (optimizeListsLoaded) {\n            return;\n        }\n\n        if (optimizeListFile != null && dontOptimizeListFile != null) {\n            /*\n             * We shouldn't get this far. The condition should have\n             * been caught in the arg processor.\n             */\n            throw new RuntimeException(\"optimize and don't optimize lists \"\n                    + \" are mutually exclusive.\");\n        }\n\n        if (optimizeListFile != null) {\n            optimizeList = loadStringsFromFile(optimizeListFile);\n        }\n\n        if (dontOptimizeListFile != null) {\n            dontOptimizeList = loadStringsFromFile(dontOptimizeListFile);\n        }\n\n        optimizeListsLoaded = true;\n    }\n\n    /**\n     * Loads a list of newline-separated strings into a new HashSet and returns\n     * the HashSet.\n     *\n     * @param filename filename to process\n     * @return set of all unique lines in the file\n     */\n    private static HashSet<String> loadStringsFromFile(String filename) {\n        HashSet<String> result = new HashSet<String>();\n\n        try {\n            FileReader fr = new FileReader(filename);\n            BufferedReader bfr = new BufferedReader(fr);\n\n            String line;\n\n            while (null != (line = bfr.readLine())) {\n                result.add(line);\n            }\n\n            fr.close();\n        } catch (IOException ex) {\n            // Let the exception percolate up as a RuntimeException.\n            throw new RuntimeException(\"Error with optimize list: \" +\n                    filename, ex);\n        }\n\n        return result;\n    }\n\n    /**\n     * Compares the output of the optimizer run normally with a run skipping\n     * some optional steps. Results are printed to stderr.\n     *\n     * @param nonOptRmeth {@code non-null;} origional rop method\n     * @param paramSize {@code >= 0;} parameter size of method\n     * @param isStatic true if this method has no 'this' pointer argument.\n     * @param args {@code non-null;} translator arguments\n     * @param advice {@code non-null;} translation advice\n     * @param rmeth {@code non-null;} method with all optimization steps run.\n     */\n    public static void compareOptimizerStep(RopMethod nonOptRmeth,\n            int paramSize, boolean isStatic, CfOptions args,\n            TranslationAdvice advice, RopMethod rmeth) {\n        EnumSet<Optimizer.OptionalStep> steps;\n\n        steps = EnumSet.allOf(Optimizer.OptionalStep.class);\n\n        // This is the step to skip.\n        steps.remove(Optimizer.OptionalStep.CONST_COLLECTOR);\n\n        RopMethod skipRopMethod\n                = Optimizer.optimize(nonOptRmeth,\n                        paramSize, isStatic, args.localInfo, advice, steps);\n\n        int normalInsns\n                = rmeth.getBlocks().getEffectiveInstructionCount();\n        int skipInsns\n                = skipRopMethod.getBlocks().getEffectiveInstructionCount();\n\n        System.err.printf(\n                \"optimize step regs:(%d/%d/%.2f%%)\"\n                + \" insns:(%d/%d/%.2f%%)\\n\",\n                rmeth.getBlocks().getRegCount(),\n                skipRopMethod.getBlocks().getRegCount(),\n                100.0 * ((skipRopMethod.getBlocks().getRegCount()\n                        - rmeth.getBlocks().getRegCount())\n                        / (float) skipRopMethod.getBlocks().getRegCount()),\n                normalInsns, skipInsns,\n                100.0 * ((skipInsns - normalInsns) / (float) skipInsns));\n    }\n\n    /**\n     * Checks whether the specified method should be optimized\n     *\n     * @param canonicalMethodName name of method being considered\n     * @return true if it should be optimized\n     */\n    public static boolean shouldOptimize(String canonicalMethodName) {\n        // Optimize only what's in the optimize list.\n        if (optimizeList != null) {\n            return optimizeList.contains(canonicalMethodName);\n        }\n\n        /*\n         * Or don't optimize what's listed here. (The two lists are\n         * mutually exclusive.\n         */\n\n        if (dontOptimizeList != null) {\n            return !dontOptimizeList.contains(canonicalMethodName);\n        }\n\n        // If neither list has been specified, then optimize everything.\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/cf/package.html",
    "content": "<body>\n<p>Classes for translating Java classfiles into Dalvik classes.</p>\n\n<p><b>PACKAGES USED:</b>\n<ul>\n<li><code>com.taobao.android.dx.cf.code</code></li>\n<li><code>com.taobao.android.dx.cf.direct</code></li>\n<li><code>com.taobao.android.dx.cf.iface</code></li>\n<li><code>com.taobao.android.dx.dex.code</code></li>\n<li><code>com.taobao.android.dx.dex.file</code></li>\n<li><code>com.taobao.android.dx.rop.code</code></li>\n<li><code>com.taobao.android.dx.rop.cst</code></li>\n<li><code>com.taobao.android.dx.util</code></li>\n</ul>\n</body>\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/ArrayData.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.io.Opcodes;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstLiteral32;\nimport com.taobao.android.dx.rop.cst.CstLiteral64;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.ArrayList;\n\n/**\n * Pseudo-instruction which holds fill array data.\n */\npublic final class ArrayData extends VariableSizeInsn {\n    /**\n     * {@code non-null;} address representing the instruction that uses this\n     * instance\n     */\n    private final CodeAddress user;\n\n    /** {@code non-null;} initial values to be filled into an array */\n    private final ArrayList<Constant> values;\n\n    /** non-null: type of constant that initializes the array */\n    private final Constant arrayType;\n\n    /** Width of the init value element */\n    private final int elemWidth;\n\n    /** Length of the init list */\n    private final int initLength;\n\n    /**\n     * Constructs an instance. The output address of this instance is initially\n     * unknown ({@code -1}).\n     *\n     * @param position {@code non-null;} source position\n     * @param user {@code non-null;} address representing the instruction that\n     * uses this instance\n     * @param values {@code non-null;} initial values to be filled into an array\n     */\n    public ArrayData(SourcePosition position, CodeAddress user,\n                     ArrayList<Constant> values,\n                     Constant arrayType) {\n        super(position, RegisterSpecList.EMPTY);\n\n        if (user == null) {\n            throw new NullPointerException(\"user == null\");\n        }\n\n        if (values == null) {\n            throw new NullPointerException(\"values == null\");\n        }\n\n        int sz = values.size();\n\n        if (sz <= 0) {\n            throw new IllegalArgumentException(\"Illegal number of init values\");\n        }\n\n        this.arrayType = arrayType;\n\n        if (arrayType == CstType.BYTE_ARRAY ||\n                arrayType == CstType.BOOLEAN_ARRAY) {\n            elemWidth = 1;\n        } else if (arrayType == CstType.SHORT_ARRAY ||\n                arrayType == CstType.CHAR_ARRAY) {\n            elemWidth = 2;\n        } else if (arrayType == CstType.INT_ARRAY ||\n                arrayType == CstType.FLOAT_ARRAY) {\n            elemWidth = 4;\n        } else if (arrayType == CstType.LONG_ARRAY ||\n                arrayType == CstType.DOUBLE_ARRAY) {\n            elemWidth = 8;\n        } else {\n            throw new IllegalArgumentException(\"Unexpected constant type\");\n        }\n        this.user = user;\n        this.values = values;\n        initLength = values.size();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        int sz = initLength;\n        // Note: the unit here is 16-bit\n        return 4 + ((sz * elemWidth) + 1) / 2;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out) {\n        int sz = values.size();\n\n        out.writeShort(Opcodes.FILL_ARRAY_DATA_PAYLOAD);\n        out.writeShort(elemWidth);\n        out.writeInt(initLength);\n\n\n        // For speed reasons, replicate the for loop in each case\n        switch (elemWidth) {\n            case 1: {\n                for (int i = 0; i < sz; i++) {\n                    Constant cst = values.get(i);\n                    out.writeByte((byte) ((CstLiteral32) cst).getIntBits());\n                }\n                break;\n            }\n            case 2: {\n                for (int i = 0; i < sz; i++) {\n                    Constant cst = values.get(i);\n                    out.writeShort((short) ((CstLiteral32) cst).getIntBits());\n                }\n                break;\n            }\n            case 4: {\n                for (int i = 0; i < sz; i++) {\n                    Constant cst = values.get(i);\n                    out.writeInt(((CstLiteral32) cst).getIntBits());\n                }\n                break;\n            }\n            case 8: {\n                for (int i = 0; i < sz; i++) {\n                    Constant cst = values.get(i);\n                    out.writeLong(((CstLiteral64) cst).getLongBits());\n                }\n                break;\n            }\n            default:\n                break;\n        }\n\n        // Pad one byte to make the size of data table multiples of 16-bits\n        if (elemWidth == 1 && (sz % 2 != 0)) {\n            out.writeByte(0x00);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withRegisters(RegisterSpecList registers) {\n        return new ArrayData(getPosition(), user, values, arrayType);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String argString() {\n        StringBuffer sb = new StringBuffer(100);\n\n        int sz = values.size();\n        for (int i = 0; i < sz; i++) {\n            sb.append(\"\\n    \");\n            sb.append(i);\n            sb.append(\": \");\n            sb.append(values.get(i).toHuman());\n        }\n\n        return sb.toString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String listingString0(boolean noteIndices) {\n        int baseAddress = user.getAddress();\n        StringBuffer sb = new StringBuffer(100);\n        int sz = values.size();\n\n        sb.append(\"fill-array-data-payload // for fill-array-data @ \");\n        sb.append(Hex.u2(baseAddress));\n\n        for (int i = 0; i < sz; i++) {\n            sb.append(\"\\n  \");\n            sb.append(i);\n            sb.append(\": \");\n            sb.append(values.get(i).toHuman());\n        }\n\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/BlockAddresses.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.BasicBlock;\nimport com.taobao.android.dx.rop.code.BasicBlockList;\nimport com.taobao.android.dx.rop.code.Insn;\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.rop.code.SourcePosition;\n\n/**\n * Container for the set of {@link CodeAddress} instances associated with\n * the blocks of a particular method. Each block has a corresponding\n * start address, end address, and last instruction address.\n */\npublic final class BlockAddresses {\n    /** {@code non-null;} array containing addresses for the start of each basic\n     * block (indexed by basic block label) */\n    private final CodeAddress[] starts;\n\n    /** {@code non-null;} array containing addresses for the final instruction\n     * of each basic block (indexed by basic block label) */\n    private final CodeAddress[] lasts;\n\n    /** {@code non-null;} array containing addresses for the end (just past the\n     * final instruction) of each basic block (indexed by basic block\n     * label) */\n    private final CodeAddress[] ends;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param method {@code non-null;} the method to have block addresses for\n     */\n    public BlockAddresses(RopMethod method) {\n        BasicBlockList blocks = method.getBlocks();\n        int maxLabel = blocks.getMaxLabel();\n\n        this.starts = new CodeAddress[maxLabel];\n        this.lasts = new CodeAddress[maxLabel];\n        this.ends = new CodeAddress[maxLabel];\n\n        setupArrays(method);\n    }\n\n    /**\n     * Gets the instance for the start of the given block.\n     *\n     * @param block {@code non-null;} the block in question\n     * @return {@code non-null;} the appropriate instance\n     */\n    public CodeAddress getStart(BasicBlock block) {\n        return starts[block.getLabel()];\n    }\n\n    /**\n     * Gets the instance for the start of the block with the given label.\n     *\n     * @param label {@code non-null;} the label of the block in question\n     * @return {@code non-null;} the appropriate instance\n     */\n    public CodeAddress getStart(int label) {\n        return starts[label];\n    }\n\n    /**\n     * Gets the instance for the final instruction of the given block.\n     *\n     * @param block {@code non-null;} the block in question\n     * @return {@code non-null;} the appropriate instance\n     */\n    public CodeAddress getLast(BasicBlock block) {\n        return lasts[block.getLabel()];\n    }\n\n    /**\n     * Gets the instance for the final instruction of the block with\n     * the given label.\n     *\n     * @param label {@code non-null;} the label of the block in question\n     * @return {@code non-null;} the appropriate instance\n     */\n    public CodeAddress getLast(int label) {\n        return lasts[label];\n    }\n\n    /**\n     * Gets the instance for the end (address after the final instruction)\n     * of the given block.\n     *\n     * @param block {@code non-null;} the block in question\n     * @return {@code non-null;} the appropriate instance\n     */\n    public CodeAddress getEnd(BasicBlock block) {\n        return ends[block.getLabel()];\n    }\n\n    /**\n     * Gets the instance for the end (address after the final instruction)\n     * of the block with the given label.\n     *\n     * @param label {@code non-null;} the label of the block in question\n     * @return {@code non-null;} the appropriate instance\n     */\n    public CodeAddress getEnd(int label) {\n        return ends[label];\n    }\n\n    /**\n     * Sets up the address arrays.\n     */\n    private void setupArrays(RopMethod method) {\n        BasicBlockList blocks = method.getBlocks();\n        int sz = blocks.size();\n\n        for (int i = 0; i < sz; i++) {\n            BasicBlock one = blocks.get(i);\n            int label = one.getLabel();\n            Insn insn = one.getInsns().get(0);\n\n            starts[label] = new CodeAddress(insn.getPosition());\n\n            SourcePosition pos = one.getLastInsn().getPosition();\n\n            lasts[label] = new CodeAddress(pos);\n            ends[label] = new CodeAddress(pos);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/CatchBuilder.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.type.Type;\nimport java.util.HashSet;\n\n/**\n * Interface for the construction of {@link CatchTable} instances.\n */\npublic interface CatchBuilder {\n    /**\n     * Builds and returns the catch table for this instance.\n     *\n     * @return {@code non-null;} the constructed table\n     */\n    public CatchTable build();\n\n    /**\n     * Gets whether this instance has any catches at all (either typed\n     * or catch-all).\n     *\n     * @return whether this instance has any catches at all\n     */\n    public boolean hasAnyCatches();\n\n    /**\n     * Gets the set of catch types associated with this instance.\n     *\n     * @return {@code non-null;} the set of catch types\n     */\n    public HashSet<Type> getCatchTypes();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/CatchHandlerList.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.util.FixedSizeList;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Ordered list of (exception type, handler address) entries.\n */\npublic final class CatchHandlerList extends FixedSizeList\n        implements Comparable<CatchHandlerList> {\n    /** {@code non-null;} empty instance */\n    public static final CatchHandlerList EMPTY = new CatchHandlerList(0);\n\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size {@code >= 0;} the size of the list\n     */\n    public CatchHandlerList(int size) {\n        super(size);\n    }\n\n    /**\n     * Gets the element at the given index. It is an error to call\n     * this with the index for an element which was never set; if you\n     * do that, this will throw {@code NullPointerException}.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @return {@code non-null;} element at that index\n     */\n    public Entry get(int n) {\n        return (Entry) get0(n);\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return toHuman(\"\", \"\");\n    }\n\n    /**\n     * Get the human form of this instance, prefixed on each line\n     * with the string.\n     *\n     * @param prefix {@code non-null;} the prefix for every line\n     * @param header {@code non-null;} the header for the first line (after the\n     * first prefix)\n     * @return {@code non-null;} the human form\n     */\n    public String toHuman(String prefix, String header) {\n        StringBuilder sb = new StringBuilder(100);\n        int size = size();\n\n        sb.append(prefix);\n        sb.append(header);\n        sb.append(\"catch \");\n\n        for (int i = 0; i < size; i++) {\n            Entry entry = get(i);\n\n            if (i != 0) {\n                sb.append(\",\\n\");\n                sb.append(prefix);\n                sb.append(\"  \");\n            }\n\n            if ((i == (size - 1)) && catchesAll()) {\n                sb.append(\"<any>\");\n            } else {\n                sb.append(entry.getExceptionType().toHuman());\n            }\n\n            sb.append(\" -> \");\n            sb.append(Hex.u2or4(entry.getHandler()));\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Returns whether or not this instance ends with a \"catch-all\"\n     * handler.\n     *\n     * @return {@code true} if this instance ends with a \"catch-all\"\n     * handler or {@code false} if not\n     */\n    public boolean catchesAll() {\n        int size = size();\n\n        if (size == 0) {\n            return false;\n        }\n\n        Entry last = get(size - 1);\n        return last.getExceptionType().equals(CstType.OBJECT);\n    }\n\n    /**\n     * Sets the entry at the given index.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @param exceptionType {@code non-null;} type of exception handled\n     * @param handler {@code >= 0;} exception handler address\n     */\n    public void set(int n, CstType exceptionType, int handler) {\n        set0(n, new Entry(exceptionType, handler));\n    }\n\n    /**\n     * Sets the entry at the given index.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @param entry {@code non-null;} the entry to set at {@code n}\n     */\n    public void set(int n, Entry entry) {\n        set0(n, entry);\n    }\n\n    /** {@inheritDoc} */\n    public int compareTo(CatchHandlerList other) {\n        if (this == other) {\n            // Easy out.\n            return 0;\n        }\n\n        int thisSize = size();\n        int otherSize = other.size();\n        int checkSize = Math.min(thisSize, otherSize);\n\n        for (int i = 0; i < checkSize; i++) {\n            Entry thisEntry = get(i);\n            Entry otherEntry = other.get(i);\n            int compare = thisEntry.compareTo(otherEntry);\n            if (compare != 0) {\n                return compare;\n            }\n        }\n\n        if (thisSize < otherSize) {\n            return -1;\n        } else if (thisSize > otherSize) {\n            return 1;\n        }\n\n        return 0;\n    }\n\n    /**\n     * Entry in the list.\n     */\n    public static class Entry implements Comparable<Entry> {\n        /** {@code non-null;} type of exception handled */\n        private final CstType exceptionType;\n\n        /** {@code >= 0;} exception handler address */\n        private final int handler;\n\n        /**\n         * Constructs an instance.\n         *\n         * @param exceptionType {@code non-null;} type of exception handled\n         * @param handler {@code >= 0;} exception handler address\n         */\n        public Entry(CstType exceptionType, int handler) {\n            if (handler < 0) {\n                throw new IllegalArgumentException(\"handler < 0\");\n            }\n\n            if (exceptionType == null) {\n                throw new NullPointerException(\"exceptionType == null\");\n            }\n\n            this.handler = handler;\n            this.exceptionType = exceptionType;\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public int hashCode() {\n            return (handler * 31) + exceptionType.hashCode();\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public boolean equals(Object other) {\n            if (other instanceof Entry) {\n                return (compareTo((Entry) other) == 0);\n            }\n\n            return false;\n        }\n\n        /** {@inheritDoc} */\n        public int compareTo(Entry other) {\n            if (handler < other.handler) {\n                return -1;\n            } else if (handler > other.handler) {\n                return 1;\n            }\n\n            return exceptionType.compareTo(other.exceptionType);\n        }\n\n        /**\n         * Gets the exception type handled.\n         *\n         * @return {@code non-null;} the exception type\n         */\n        public CstType getExceptionType() {\n            return exceptionType;\n        }\n\n        /**\n         * Gets the handler address.\n         *\n         * @return {@code >= 0;} the handler address\n         */\n        public int getHandler() {\n            return handler;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/CatchTable.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.util.FixedSizeList;\n\n/**\n * Table of catch entries. Each entry includes a range of code\n * addresses for which it is valid and an associated {@link\n * CatchHandlerList}.\n */\npublic final class CatchTable extends FixedSizeList\n        implements Comparable<CatchTable> {\n    /** {@code non-null;} empty instance */\n    public static final CatchTable EMPTY = new CatchTable(0);\n\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size {@code >= 0;} the size of the table\n     */\n    public CatchTable(int size) {\n        super(size);\n    }\n\n    /**\n     * Gets the element at the given index. It is an error to call\n     * this with the index for an element which was never set; if you\n     * do that, this will throw {@code NullPointerException}.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @return {@code non-null;} element at that index\n     */\n    public Entry get(int n) {\n        return (Entry) get0(n);\n    }\n\n    /**\n     * Sets the entry at the given index.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @param entry {@code non-null;} the entry to set at {@code n}\n     */\n    public void set(int n, Entry entry) {\n        set0(n, entry);\n    }\n\n    /** {@inheritDoc} */\n    public int compareTo(CatchTable other) {\n        if (this == other) {\n            // Easy out.\n            return 0;\n        }\n\n        int thisSize = size();\n        int otherSize = other.size();\n        int checkSize = Math.min(thisSize, otherSize);\n\n        for (int i = 0; i < checkSize; i++) {\n            Entry thisEntry = get(i);\n            Entry otherEntry = other.get(i);\n            int compare = thisEntry.compareTo(otherEntry);\n            if (compare != 0) {\n                return compare;\n            }\n        }\n\n        if (thisSize < otherSize) {\n            return -1;\n        } else if (thisSize > otherSize) {\n            return 1;\n        }\n\n        return 0;\n    }\n\n    /**\n     * Entry in a catch list.\n     */\n    public static class Entry implements Comparable<Entry> {\n        /** {@code >= 0;} start address */\n        private final int start;\n\n        /** {@code > start;} end address (exclusive) */\n        private final int end;\n\n        /** {@code non-null;} list of catch handlers */\n        private final CatchHandlerList handlers;\n\n        /**\n         * Constructs an instance.\n         *\n         * @param start {@code >= 0;} start address\n         * @param end {@code > start;} end address (exclusive)\n         * @param handlers {@code non-null;} list of catch handlers\n         */\n        public Entry(int start, int end, CatchHandlerList handlers) {\n            if (start < 0) {\n                throw new IllegalArgumentException(\"start < 0\");\n            }\n\n            if (end <= start) {\n                throw new IllegalArgumentException(\"end <= start\");\n            }\n\n            if (handlers.isMutable()) {\n                throw new IllegalArgumentException(\"handlers.isMutable()\");\n            }\n\n            this.start = start;\n            this.end = end;\n            this.handlers = handlers;\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public int hashCode() {\n            int hash = (start * 31) + end;\n            hash = (hash * 31) + handlers.hashCode();\n            return hash;\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public boolean equals(Object other) {\n            if (other instanceof Entry) {\n                return (compareTo((Entry) other) == 0);\n            }\n\n            return false;\n        }\n\n        /** {@inheritDoc} */\n        public int compareTo(Entry other) {\n            if (start < other.start) {\n                return -1;\n            } else if (start > other.start) {\n                return 1;\n            }\n\n            if (end < other.end) {\n                return -1;\n            } else if (end > other.end) {\n                return 1;\n            }\n\n            return handlers.compareTo(other.handlers);\n        }\n\n        /**\n         * Gets the start address.\n         *\n         * @return {@code >= 0;} the start address\n         */\n        public int getStart() {\n            return start;\n        }\n\n        /**\n         * Gets the end address (exclusive).\n         *\n         * @return {@code > start;} the end address (exclusive)\n         */\n        public int getEnd() {\n            return end;\n        }\n\n        /**\n         * Gets the handlers.\n         *\n         * @return {@code non-null;} the handlers\n         */\n        public CatchHandlerList getHandlers() {\n            return handlers;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/CodeAddress.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.SourcePosition;\n\n/**\n * Pseudo-instruction which is used to track an address within a code\n * array. Instances are used for such things as branch targets and\n * exception handler ranges. Its code size is zero, and so instances\n * do not in general directly wind up in any output (either\n * human-oriented or binary file).\n */\npublic final class CodeAddress extends ZeroSizeInsn {\n    /** If this address should bind closely to the following real instruction */\n    private final boolean bindsClosely;\n\n    /**\n     * Constructs an instance. The output address of this instance is initially\n     * unknown ({@code -1}).\n     *\n     * @param position {@code non-null;} source position\n     */\n    public CodeAddress(SourcePosition position) {\n        this(position, false);\n    }\n\n    /**\n     * Constructs an instance. The output address of this instance is initially\n     * unknown ({@code -1}).\n     *\n     * @param position {@code non-null;} source position\n     * @param bindsClosely if the address should bind closely to the following\n     *                     real instruction.\n     */\n    public CodeAddress(SourcePosition position, boolean bindsClosely) {\n        super(position);\n        this.bindsClosely = bindsClosely;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final DalvInsn withRegisters(RegisterSpecList registers) {\n        return new CodeAddress(getPosition());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String argString() {\n        return null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String listingString0(boolean noteIndices) {\n        return \"code-address\";\n    }\n\n    /**\n     * Gets whether this address binds closely to the following \"real\"\n     * (non-zero-length) instruction.\n     *\n     * When a prefix is added to an instruction (for example, to move a value\n     * from a high register to a low register), this determines whether this\n     * {@code CodeAddress} will point to the prefix, or to the instruction\n     * itself.\n     *\n     * If bindsClosely is true, the address will point to the instruction\n     * itself, otherwise it will point to the prefix (if any)\n     *\n     * @return true if this address binds closely to the next real instruction\n     */\n    public boolean getBindsClosely() {\n        return bindsClosely;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/CstInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.rop.cst.Constant;\n\n/**\n * Instruction which has a single constant argument in addition\n * to all the normal instruction information.\n */\npublic final class CstInsn extends FixedSizeInsn {\n    /** {@code non-null;} the constant argument for this instruction */\n    private final Constant constant;\n\n    /**\n     * {@code >= -1;} the constant pool index for {@link #constant}, or\n     * {@code -1} if not yet set\n     */\n    private int index;\n\n    /**\n     * {@code >= -1;} the constant pool index for the class reference in\n     * {@link #constant} if any, or {@code -1} if not yet set\n     */\n    private int classIndex;\n\n    /**\n     * Constructs an instance. The output address of this instance is\n     * initially unknown ({@code -1}) as is the constant pool index.\n     *\n     * @param opcode the opcode; one of the constants from {@link Dops}\n     * @param position {@code non-null;} source position\n     * @param registers {@code non-null;} register list, including a\n     * result register if appropriate (that is, registers may be either\n     * ins or outs)\n     * @param constant {@code non-null;} constant argument\n     */\n    public CstInsn(Dop opcode, SourcePosition position,\n                   RegisterSpecList registers, Constant constant) {\n        super(opcode, position, registers);\n\n        if (constant == null) {\n            throw new NullPointerException(\"constant == null\");\n        }\n\n        this.constant = constant;\n        this.index = -1;\n        this.classIndex = -1;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withOpcode(Dop opcode) {\n        CstInsn result =\n            new CstInsn(opcode, getPosition(), getRegisters(), constant);\n\n        if (index >= 0) {\n            result.setIndex(index);\n        }\n\n        if (classIndex >= 0) {\n            result.setClassIndex(classIndex);\n        }\n\n        return result;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withRegisters(RegisterSpecList registers) {\n        CstInsn result =\n            new CstInsn(getOpcode(), getPosition(), registers, constant);\n\n        if (index >= 0) {\n            result.setIndex(index);\n        }\n\n        if (classIndex >= 0) {\n            result.setClassIndex(classIndex);\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets the constant argument.\n     *\n     * @return {@code non-null;} the constant argument\n     */\n    public Constant getConstant() {\n        return constant;\n    }\n\n    /**\n     * Gets the constant's index. It is only valid to call this after\n     * {@link #setIndex} has been called.\n     *\n     * @return {@code >= 0;} the constant pool index\n     */\n    public int getIndex() {\n        if (index < 0) {\n            throw new RuntimeException(\"index not yet set for \" + constant);\n        }\n\n        return index;\n    }\n\n    /**\n     * Returns whether the constant's index has been set for this instance.\n     *\n     * @see #setIndex\n     *\n     * @return {@code true} iff the index has been set\n     */\n    public boolean hasIndex() {\n        return (index >= 0);\n    }\n\n    /**\n     * Sets the constant's index. It is only valid to call this method once\n     * per instance.\n     *\n     * @param index {@code >= 0;} the constant pool index\n     */\n    public void setIndex(int index) {\n        if (index < 0) {\n            throw new IllegalArgumentException(\"index < 0\");\n        }\n\n        if (this.index >= 0) {\n            throw new RuntimeException(\"index already set\");\n        }\n\n        this.index = index;\n    }\n\n    /**\n     * Gets the constant's class index. It is only valid to call this after\n     * {@link #setClassIndex} has been called.\n     *\n     * @return {@code >= 0;} the constant's class's constant pool index\n     */\n    public int getClassIndex() {\n        if (classIndex < 0) {\n            throw new RuntimeException(\"class index not yet set\");\n        }\n\n        return classIndex;\n    }\n\n    /**\n     * Returns whether the constant's class index has been set for this\n     * instance.\n     *\n     * @see #setClassIndex\n     *\n     * @return {@code true} iff the index has been set\n     */\n    public boolean hasClassIndex() {\n        return (classIndex >= 0);\n    }\n\n    /**\n     * Sets the constant's class index. This is the constant pool index\n     * for the class referred to by this instance's constant. Only\n     * reference constants have a class, so it is only on instances\n     * with reference constants that this method should ever be\n     * called. It is only valid to call this method once per instance.\n     *\n     * @param index {@code >= 0;} the constant's class's constant pool index\n     */\n    public void setClassIndex(int index) {\n        if (index < 0) {\n            throw new IllegalArgumentException(\"index < 0\");\n        }\n\n        if (this.classIndex >= 0) {\n            throw new RuntimeException(\"class index already set\");\n        }\n\n        this.classIndex = index;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String argString() {\n        return constant.toHuman();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/DalvCode.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.type.Type;\nimport java.util.HashSet;\n\n/**\n * Container for all the pieces of a concrete method. Each instance\n * corresponds to a {@code code} structure in a {@code .dex} file.\n */\npublic final class DalvCode {\n    /**\n     * how much position info to preserve; one of the static\n     * constants in {@link PositionList}\n     */\n    private final int positionInfo;\n\n    /**\n     * {@code null-ok;} the instruction list, ready for final processing;\n     * nulled out in {@link #finishProcessingIfNecessary}\n     */\n    private OutputFinisher unprocessedInsns;\n\n    /**\n     * {@code non-null;} unprocessed catch table;\n     * nulled out in {@link #finishProcessingIfNecessary}\n     */\n    private CatchBuilder unprocessedCatches;\n\n    /**\n     * {@code null-ok;} catch table; set in\n     * {@link #finishProcessingIfNecessary}\n     */\n    private CatchTable catches;\n\n    /**\n     * {@code null-ok;} source positions list; set in\n     * {@link #finishProcessingIfNecessary}\n     */\n    private PositionList positions;\n\n    /**\n     * {@code null-ok;} local variable list; set in\n     * {@link #finishProcessingIfNecessary}\n     */\n    private LocalList locals;\n\n    /**\n     * {@code null-ok;} the processed instruction list; set in\n     * {@link #finishProcessingIfNecessary}\n     */\n    private DalvInsnList insns;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param positionInfo how much position info to preserve; one of the\n     * static constants in {@link PositionList}\n     * @param unprocessedInsns {@code non-null;} the instruction list, ready\n     * for final processing\n     * @param unprocessedCatches {@code non-null;} unprocessed catch\n     * (exception handler) table\n     */\n    public DalvCode(int positionInfo, OutputFinisher unprocessedInsns,\n            CatchBuilder unprocessedCatches) {\n        if (unprocessedInsns == null) {\n            throw new NullPointerException(\"unprocessedInsns == null\");\n        }\n\n        if (unprocessedCatches == null) {\n            throw new NullPointerException(\"unprocessedCatches == null\");\n        }\n\n        this.positionInfo = positionInfo;\n        this.unprocessedInsns = unprocessedInsns;\n        this.unprocessedCatches = unprocessedCatches;\n        this.catches = null;\n        this.positions = null;\n        this.locals = null;\n        this.insns = null;\n    }\n\n    /**\n     * Finish up processing of the method.\n     */\n    private void finishProcessingIfNecessary() {\n        if (insns != null) {\n            return;\n        }\n\n        insns = unprocessedInsns.finishProcessingAndGetList();\n        positions = PositionList.make(insns, positionInfo);\n        locals = LocalList.make(insns);\n        catches = unprocessedCatches.build();\n\n        // Let them be gc'ed.\n        unprocessedInsns = null;\n        unprocessedCatches = null;\n    }\n\n    /**\n     * Assign indices in all instructions that need them, using the\n     * given callback to perform lookups. This must be called before\n     * {@link #getInsns}.\n     *\n     * @param callback {@code non-null;} callback object\n     */\n    public void assignIndices(AssignIndicesCallback callback) {\n        unprocessedInsns.assignIndices(callback);\n    }\n\n    /**\n     * Gets whether this instance has any position data to represent.\n     *\n     * @return {@code true} iff this instance has any position\n     * data to represent\n     */\n    public boolean hasPositions() {\n        return (positionInfo != PositionList.NONE)\n            && unprocessedInsns.hasAnyPositionInfo();\n    }\n\n    /**\n     * Gets whether this instance has any local variable data to represent.\n     *\n     * @return {@code true} iff this instance has any local variable\n     * data to represent\n     */\n    public boolean hasLocals() {\n        return unprocessedInsns.hasAnyLocalInfo();\n    }\n\n    /**\n     * Gets whether this instance has any catches at all (either typed\n     * or catch-all).\n     *\n     * @return whether this instance has any catches at all\n     */\n    public boolean hasAnyCatches() {\n        return unprocessedCatches.hasAnyCatches();\n    }\n\n    /**\n     * Gets the set of catch types handled anywhere in the code.\n     *\n     * @return {@code non-null;} the set of catch types\n     */\n    public HashSet<Type> getCatchTypes() {\n        return unprocessedCatches.getCatchTypes();\n    }\n\n    /**\n     * Gets the set of all constants referred to by instructions in\n     * the code.\n     *\n     * @return {@code non-null;} the set of constants\n     */\n    public HashSet<Constant> getInsnConstants() {\n        return unprocessedInsns.getAllConstants();\n    }\n\n    /**\n     * Gets the list of instructions.\n     *\n     * @return {@code non-null;} the instruction list\n     */\n    public DalvInsnList getInsns() {\n        finishProcessingIfNecessary();\n        return insns;\n    }\n\n    /**\n     * Gets the catch (exception handler) table.\n     *\n     * @return {@code non-null;} the catch table\n     */\n    public CatchTable getCatches() {\n        finishProcessingIfNecessary();\n        return catches;\n    }\n\n    /**\n     * Gets the source positions list.\n     *\n     * @return {@code non-null;} the source positions list\n     */\n    public PositionList getPositions() {\n        finishProcessingIfNecessary();\n        return positions;\n    }\n\n    /**\n     * Gets the source positions list.\n     *\n     * @return {@code non-null;} the source positions list\n     */\n    public LocalList getLocals() {\n        finishProcessingIfNecessary();\n        return locals;\n    }\n\n    /**\n     * Class used as a callback for {@link #assignIndices}.\n     */\n    public static interface AssignIndicesCallback {\n        /**\n         * Gets the index for the given constant.\n         *\n         * @param cst {@code non-null;} the constant\n         * @return {@code >= -1;} the index or {@code -1} if the constant\n         * shouldn't actually be reified with an index\n         */\n        public int getIndex(Constant cst);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/DalvInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.ssa.RegisterMapper;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.TwoColumnOutput;\n\nimport java.util.BitSet;\n\n/**\n * Base class for Dalvik instructions.\n */\npublic abstract class DalvInsn {\n    /**\n     * the actual output address of this instance, if known, or\n     * {@code -1} if not\n     */\n    private int address;\n\n    /** the opcode; one of the constants from {@link Dops} */\n    private final Dop opcode;\n\n    /** {@code non-null;} source position */\n    private final SourcePosition position;\n\n    /** {@code non-null;} list of register arguments */\n    private final RegisterSpecList registers;\n\n    /**\n     * Makes a move instruction, appropriate and ideal for the given arguments.\n     *\n     * @param position {@code non-null;} source position information\n     * @param dest {@code non-null;} destination register\n     * @param src {@code non-null;} source register\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static SimpleInsn makeMove(SourcePosition position,\n            RegisterSpec dest, RegisterSpec src) {\n        boolean category1 = dest.getCategory() == 1;\n        boolean reference = dest.getType().isReference();\n        int destReg = dest.getReg();\n        int srcReg = src.getReg();\n        Dop opcode;\n\n        if ((srcReg | destReg) < 16) {\n            opcode = reference ? Dops.MOVE_OBJECT :\n                (category1 ? Dops.MOVE : Dops.MOVE_WIDE);\n        } else if (destReg < 256) {\n            opcode = reference ? Dops.MOVE_OBJECT_FROM16 :\n                (category1 ? Dops.MOVE_FROM16 : Dops.MOVE_WIDE_FROM16);\n        } else {\n            opcode = reference ? Dops.MOVE_OBJECT_16 :\n                (category1 ? Dops.MOVE_16 : Dops.MOVE_WIDE_16);\n        }\n\n        return new SimpleInsn(opcode, position,\n                              RegisterSpecList.make(dest, src));\n    }\n\n    /**\n     * Constructs an instance. The output address of this instance is initially\n     * unknown ({@code -1}).\n     *\n     * <p><b>Note:</b> In the unlikely event that an instruction takes\n     * absolutely no registers (e.g., a {@code nop} or a\n     * no-argument no-result static method call), then the given\n     * register list may be passed as {@link\n     * RegisterSpecList#EMPTY}.</p>\n     *\n     * @param opcode the opcode; one of the constants from {@link Dops}\n     * @param position {@code non-null;} source position\n     * @param registers {@code non-null;} register list, including a\n     * result register if appropriate (that is, registers may be either\n     * ins and outs)\n     */\n    public DalvInsn(Dop opcode, SourcePosition position,\n                    RegisterSpecList registers) {\n        if (opcode == null) {\n            throw new NullPointerException(\"opcode == null\");\n        }\n\n        if (position == null) {\n            throw new NullPointerException(\"position == null\");\n        }\n\n        if (registers == null) {\n            throw new NullPointerException(\"registers == null\");\n        }\n\n        this.address = -1;\n        this.opcode = opcode;\n        this.position = position;\n        this.registers = registers;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final String toString() {\n        StringBuffer sb = new StringBuffer(100);\n\n        sb.append(identifierString());\n        sb.append(' ');\n        sb.append(position);\n\n        sb.append(\": \");\n        sb.append(opcode.getName());\n\n        boolean needComma = false;\n        if (registers.size() != 0) {\n            sb.append(registers.toHuman(\" \", \", \", null));\n            needComma = true;\n        }\n\n        String extra = argString();\n        if (extra != null) {\n            if (needComma) {\n                sb.append(',');\n            }\n            sb.append(' ');\n            sb.append(extra);\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Gets whether the address of this instruction is known.\n     *\n     * @see #getAddress\n     * @see #setAddress\n     */\n    public final boolean hasAddress() {\n        return (address >= 0);\n    }\n\n    /**\n     * Gets the output address of this instruction, if it is known. This throws\n     * a {@code RuntimeException} if it has not yet been set.\n     *\n     * @see #setAddress\n     *\n     * @return {@code >= 0;} the output address\n     */\n    public final int getAddress() {\n        if (address < 0) {\n            throw new RuntimeException(\"address not yet known\");\n        }\n\n        return address;\n    }\n\n    /**\n     * Gets the opcode.\n     *\n     * @return {@code non-null;} the opcode\n     */\n    public final Dop getOpcode() {\n        return opcode;\n    }\n\n    /**\n     * Gets the source position.\n     *\n     * @return {@code non-null;} the source position\n     */\n    public final SourcePosition getPosition() {\n        return position;\n    }\n\n    /**\n     * Gets the register list for this instruction.\n     *\n     * @return {@code non-null;} the registers\n     */\n    public final RegisterSpecList getRegisters() {\n        return registers;\n    }\n\n    /**\n     * Returns whether this instance's opcode uses a result register.\n     * This method is a convenient shorthand for\n     * {@code getOpcode().hasResult()}.\n     *\n     * @return {@code true} iff this opcode uses a result register\n     */\n    public final boolean hasResult() {\n        return opcode.hasResult();\n    }\n\n    /**\n     * Gets the minimum distinct registers required for this instruction.\n     * Uses the given BitSet to determine which registers require\n     * replacement, and ignores registers that are already compatible.\n     * This assumes that the result (if any) can share registers with the\n     * sources (if any), that each source register is unique, and that\n     * (to be explicit here) category-2 values take up two consecutive\n     * registers.\n     *\n     * @param compatRegs {@code non-null;} set of compatible registers\n     * @return {@code >= 0;} the minimum distinct register requirement\n     */\n    public final int getMinimumRegisterRequirement(BitSet compatRegs) {\n        boolean hasResult = hasResult();\n        int regSz = registers.size();\n        int resultRequirement = 0;\n        int sourceRequirement = 0;\n\n        if (hasResult && !compatRegs.get(0)) {\n            resultRequirement = registers.get(0).getCategory();\n        }\n\n        for (int i = hasResult ? 1 : 0; i < regSz; i++) {\n            if (!compatRegs.get(i)) {\n                sourceRequirement += registers.get(i).getCategory();\n            }\n        }\n\n        return Math.max(sourceRequirement, resultRequirement);\n    }\n\n    /**\n     * Gets the instruction that is equivalent to this one, except that\n     * it uses sequential registers starting at {@code 0} (storing\n     * the result, if any, in register {@code 0} as well).\n     *\n     * @return {@code non-null;} the replacement\n     */\n    public DalvInsn getLowRegVersion() {\n        RegisterSpecList regs =\n            registers.withExpandedRegisters(0, hasResult(), null);\n        return withRegisters(regs);\n    }\n\n    /**\n     * Gets the instruction prefix required, if any, to use in an expanded\n     * version of this instance. Will not generate moves for registers\n     * marked compatible to the format by the given BitSet.\n     *\n     * @see #expandedVersion\n     *\n     * @param compatRegs {@code non-null;} set of compatible registers\n     * @return {@code null-ok;} the prefix, if any\n     */\n    public DalvInsn expandedPrefix(BitSet compatRegs) {\n        RegisterSpecList regs = registers;\n        boolean firstBit = compatRegs.get(0);\n\n        if (hasResult()) compatRegs.set(0);\n\n        regs = regs.subset(compatRegs);\n\n        if (hasResult()) compatRegs.set(0, firstBit);\n\n        if (regs.size() == 0) return null;\n\n        return new HighRegisterPrefix(position, regs);\n    }\n\n    /**\n     * Gets the instruction suffix required, if any, to use in an expanded\n     * version of this instance. Will not generate a move for a register\n     * marked compatible to the format by the given BitSet.\n     *\n     * @see #expandedVersion\n     *\n     * @param compatRegs {@code non-null;} set of compatible registers\n     * @return {@code null-ok;} the suffix, if any\n     */\n    public DalvInsn expandedSuffix(BitSet compatRegs) {\n        if (hasResult() && !compatRegs.get(0)) {\n            RegisterSpec r = registers.get(0);\n            return makeMove(position, r, r.withReg(0));\n        } else {\n            return null;\n        }\n    }\n\n    /**\n     * Gets the instruction that is equivalent to this one, except that\n     * it replaces incompatible registers with sequential registers\n     * starting at {@code 0} (storing the result, if any, in register\n     * {@code 0} as well). The sequence of instructions from\n     * {@link #expandedPrefix} and {@link #expandedSuffix} (if non-null)\n     * surrounding the result of a call to this method are the expanded\n     * transformation of this instance, and it is guaranteed that the\n     * number of low registers used will be the number returned by\n     * {@link #getMinimumRegisterRequirement}.\n     *\n     * @param compatRegs {@code non-null;} set of compatible registers\n     * @return {@code non-null;} the replacement\n     */\n    public DalvInsn expandedVersion(BitSet compatRegs) {\n        RegisterSpecList regs =\n            registers.withExpandedRegisters(0, hasResult(), compatRegs);\n        return withRegisters(regs);\n    }\n\n    /**\n     * Gets the short identifier for this instruction. This is its\n     * address, if assigned, or its identity hashcode if not.\n     *\n     * @return {@code non-null;} the identifier\n     */\n    public final String identifierString() {\n        if (address != -1) {\n            return String.format(\"%04x\", address);\n        }\n\n        return Hex.u4(System.identityHashCode(this));\n    }\n\n    /**\n     * Returns the string form of this instance suitable for inclusion in\n     * a human-oriented listing dump. This method will return {@code null}\n     * if this instance should not appear in a listing.\n     *\n     * @param prefix {@code non-null;} prefix before the address; each follow-on\n     * line will be indented to match as well\n     * @param width {@code >= 0;} the width of the output or {@code 0} for\n     * unlimited width\n     * @param noteIndices whether to include an explicit notation of\n     * constant pool indices\n     * @return {@code null-ok;} the string form or {@code null} if this\n     * instance should not appear in a listing\n     */\n    public final String listingString(String prefix, int width,\n            boolean noteIndices) {\n        String insnPerSe = listingString0(noteIndices);\n\n        if (insnPerSe == null) {\n            return null;\n        }\n\n        String addr = prefix + identifierString() + \": \";\n        int w1 = addr.length();\n        int w2 = (width == 0) ? insnPerSe.length() : (width - w1);\n\n        return TwoColumnOutput.toString(addr, w1, \"\", insnPerSe, w2);\n    }\n\n    /**\n     * Sets the output address.\n     *\n     * @param address {@code >= 0;} the output address\n     */\n    public final void setAddress(int address) {\n        if (address < 0) {\n            throw new IllegalArgumentException(\"address < 0\");\n        }\n\n        this.address = address;\n    }\n\n    /**\n     * Gets the address immediately after this instance. This is only\n     * calculable if this instance's address is known, and it is equal\n     * to the address plus the length of the instruction format of this\n     * instance's opcode.\n     *\n     * @return {@code >= 0;} the next address\n     */\n    public final int getNextAddress() {\n        return getAddress() + codeSize();\n    }\n\n    /**\n     * Returns an instance that is just like this one, except that the\n     * register list is mapped by using {@code mapper}.\n     *\n     * @param mapper {@code non-null;} used to map registers\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public DalvInsn withMapper(RegisterMapper mapper) {\n      return withRegisters(mapper.map(getRegisters()));\n    }\n\n    /**\n     * Gets the size of this instruction, in 16-bit code units.\n     *\n     * @return {@code >= 0;} the code size of this instruction\n     */\n    public abstract int codeSize();\n\n    /**\n     * Writes this instance to the given output. This method should\n     * never annotate the output.\n     *\n     * @param out {@code non-null;} where to write to\n     */\n    public abstract void writeTo(AnnotatedOutput out);\n\n    /**\n     * Returns an instance that is just like this one, except that its\n     * opcode is replaced by the one given, and its address is reset.\n     *\n     * @param opcode {@code non-null;} the new opcode\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public abstract DalvInsn withOpcode(Dop opcode);\n\n    /**\n     * Returns an instance that is just like this one, except that all\n     * register references have been offset by the given delta, and its\n     * address is reset.\n     *\n     * @param delta the amount to offset register references by\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public abstract DalvInsn withRegisterOffset(int delta);\n\n    /**\n     * Returns an instance that is just like this one, except that the\n     * register list is replaced by the given one, and its address is\n     * reset.\n     *\n     * @param registers {@code non-null;} new register list\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public abstract DalvInsn withRegisters(RegisterSpecList registers);\n\n    /**\n     * Gets the string form for any arguments to this instance. Subclasses\n     * must override this.\n     *\n     * @return {@code null-ok;} the string version of any arguments or\n     * {@code null} if there are none\n     */\n    protected abstract String argString();\n\n    /**\n     * Helper for {@link #listingString}, which returns the string\n     * form of this instance suitable for inclusion in a\n     * human-oriented listing dump, not including the instruction\n     * address and without respect for any output formatting. This\n     * method should return {@code null} if this instance should\n     * not appear in a listing.\n     *\n     * @param noteIndices whether to include an explicit notation of\n     * constant pool indices\n     * @return {@code null-ok;} the listing string\n     */\n    protected abstract String listingString0(boolean noteIndices);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/DalvInsnList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dx.io.Opcodes;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstBaseMethodRef;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.FixedSizeList;\nimport com.taobao.android.dx.util.IndentingWriter;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.io.OutputStreamWriter;\nimport java.io.Writer;\nimport java.util.ArrayList;\n\n/**\n * List of {@link DalvInsn} instances.\n */\npublic final class DalvInsnList extends FixedSizeList {\n\n    /**\n     * The amount of register space, in register units, required for this\n     * code block. This may be greater than the largest observed register+\n     * category because the method this code block exists in may\n     * specify arguments that are unused by the method.\n     */\n    private final int regCount;\n\n    /**\n     * Constructs and returns an immutable instance whose elements are\n     * identical to the ones in the given list, in the same order.\n     *\n     * @param list {@code non-null;} the list to use for elements\n     * @param regCount count, in register-units, of the number of registers\n     * this code block requires.\n     * @return {@code non-null;} an appropriately-constructed instance of this\n     * class\n     */\n    public static DalvInsnList makeImmutable(ArrayList<DalvInsn> list,\n            int regCount) {\n        int size = list.size();\n        DalvInsnList result = new DalvInsnList(size, regCount);\n\n        for (int i = 0; i < size; i++) {\n            result.set(i, list.get(i));\n        }\n\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size the size of the list\n     */\n    public DalvInsnList(int size, int regCount) {\n        super(size);\n        this.regCount = regCount;\n    }\n\n    /**\n     * Gets the element at the given index. It is an error to call\n     * this with the index for an element which was never set; if you\n     * do that, this will throw {@code NullPointerException}.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @return {@code non-null;} element at that index\n     */\n    public DalvInsn get(int n) {\n        return (DalvInsn) get0(n);\n    }\n\n    /**\n     * Sets the instruction at the given index.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @param insn {@code non-null;} the instruction to set at {@code n}\n     */\n    public void set(int n, DalvInsn insn) {\n        set0(n, insn);\n    }\n\n    /**\n     * Gets the size of this instance, in 16-bit code units. This will only\n     * return a meaningful result if the instructions in this instance all\n     * have valid addresses.\n     *\n     * @return {@code >= 0;} the size\n     */\n    public int codeSize() {\n        int sz = size();\n\n        if (sz == 0) {\n            return 0;\n        }\n\n        DalvInsn last = get(sz - 1);\n        return last.getNextAddress();\n    }\n\n    /**\n     * Writes all the instructions in this instance to the given output\n     * destination.\n     *\n     * @param out {@code non-null;} where to write to\n     */\n    public void writeTo(AnnotatedOutput out) {\n        int startCursor = out.getCursor();\n        int sz = size();\n\n        if (out.annotates()) {\n            boolean verbose = out.isVerbose();\n\n            for (int i = 0; i < sz; i++) {\n                DalvInsn insn = (DalvInsn) get0(i);\n                int codeBytes = insn.codeSize() * 2;\n                String s;\n\n                if ((codeBytes != 0) || verbose) {\n                    s = insn.listingString(\"  \", out.getAnnotationWidth(),\n                            true);\n                } else {\n                    s = null;\n                }\n\n                if (s != null) {\n                    out.annotate(codeBytes, s);\n                } else if (codeBytes != 0) {\n                    out.annotate(codeBytes, \"\");\n                }\n            }\n        }\n\n        for (int i = 0; i < sz; i++) {\n            DalvInsn insn = (DalvInsn) get0(i);\n            try {\n                insn.writeTo(out);\n            } catch (RuntimeException ex) {\n                throw ExceptionWithContext.withContext(ex,\n                        \"...while writing \" + insn);\n            }\n        }\n\n        // Sanity check of the amount written.\n        int written = (out.getCursor() - startCursor) / 2;\n        if (written != codeSize()) {\n            throw new RuntimeException(\"write length mismatch; expected \" +\n                    codeSize() + \" but actually wrote \" + written);\n        }\n    }\n\n    /**\n     * Gets the minimum required register count implied by this\n     * instance.  This includes any unused parameters that could\n     * potentially be at the top of the register space.\n     * @return {@code >= 0;} the required registers size\n     */\n    public int getRegistersSize() {\n        return regCount;\n    }\n\n    /**\n     * Gets the size of the outgoing arguments area required by this\n     * method. This is equal to the largest argument word count of any\n     * method referred to by this instance.\n     *\n     * @return {@code >= 0;} the required outgoing arguments size\n     */\n    public int getOutsSize() {\n        int sz = size();\n        int result = 0;\n\n        for (int i = 0; i < sz; i++) {\n            DalvInsn insn = (DalvInsn) get0(i);\n\n            if (!(insn instanceof CstInsn)) {\n                continue;\n            }\n\n            Constant cst = ((CstInsn) insn).getConstant();\n\n            if (!(cst instanceof CstBaseMethodRef)) {\n                continue;\n            }\n\n            boolean isStatic =\n                (insn.getOpcode().getFamily() == Opcodes.INVOKE_STATIC);\n            int count =\n                ((CstBaseMethodRef) cst).getParameterWordCount(isStatic);\n\n            if (count > result) {\n                result = count;\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * Does a human-friendly dump of this instance.\n     *\n     * @param out {@code non-null;} where to dump\n     * @param prefix {@code non-null;} prefix to attach to each line of output\n     * @param verbose whether to be verbose; verbose output includes\n     * lines for zero-size instructions and explicit constant pool indices\n     */\n    public void debugPrint(Writer out, String prefix, boolean verbose) {\n        IndentingWriter iw = new IndentingWriter(out, 0, prefix);\n        int sz = size();\n\n        try {\n            for (int i = 0; i < sz; i++) {\n                DalvInsn insn = (DalvInsn) get0(i);\n                String s;\n\n                if ((insn.codeSize() != 0) || verbose) {\n                    s = insn.listingString(\"\", 0, verbose);\n                } else {\n                    s = null;\n                }\n\n                if (s != null) {\n                    iw.write(s);\n                }\n            }\n\n            iw.flush();\n        } catch (IOException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n\n    /**\n     * Does a human-friendly dump of this instance.\n     *\n     * @param out {@code non-null;} where to dump\n     * @param prefix {@code non-null;} prefix to attach to each line of output\n     * @param verbose whether to be verbose; verbose output includes\n     * lines for zero-size instructions\n     */\n    public void debugPrint(OutputStream out, String prefix, boolean verbose) {\n        Writer w = new OutputStreamWriter(out);\n        debugPrint(w, prefix, verbose);\n\n        try {\n            w.flush();\n        } catch (IOException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/Dop.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.io.OpcodeInfo;\nimport com.taobao.android.dx.io.Opcodes;\n\n/**\n * Representation of an opcode.\n */\npublic final class Dop {\n    /** {@code Opcodes.isValid();} the opcode value itself */\n    private final int opcode;\n\n    /** {@code Opcodes.isValid();} the opcode family */\n    private final int family;\n\n    /**\n     * {@code Opcodes.isValid();} what opcode (by number) to try next\n     * when attempting to match an opcode to particular arguments;\n     * {@code Opcodes.NO_NEXT} to indicate that this is the last\n     * opcode to try in a particular chain\n     */\n    private final int nextOpcode;\n\n    /** {@code non-null;} the instruction format */\n    private final InsnFormat format;\n\n    /** whether this opcode uses a result register */\n    private final boolean hasResult;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param opcode {@code Opcodes.isValid();} the opcode value\n     * itself\n     * @param family {@code Opcodes.isValid();} the opcode family\n     * @param nextOpcode {@code Opcodes.isValid();} what opcode (by\n     * number) to try next when attempting to match an opcode to\n     * particular arguments; {@code Opcodes.NO_NEXT} to indicate that\n     * this is the last opcode to try in a particular chain\n     * @param format {@code non-null;} the instruction format\n     * @param hasResult whether the opcode has a result register; if so it\n     * is always the first register\n     */\n    public Dop(int opcode, int family, int nextOpcode, InsnFormat format,\n            boolean hasResult) {\n        if (!Opcodes.isValidShape(opcode)) {\n            throw new IllegalArgumentException(\"bogus opcode\");\n        }\n\n        if (!Opcodes.isValidShape(family)) {\n            throw new IllegalArgumentException(\"bogus family\");\n        }\n\n        if (!Opcodes.isValidShape(nextOpcode)) {\n            throw new IllegalArgumentException(\"bogus nextOpcode\");\n        }\n\n        if (format == null) {\n            throw new NullPointerException(\"format == null\");\n        }\n\n        this.opcode = opcode;\n        this.family = family;\n        this.nextOpcode = nextOpcode;\n        this.format = format;\n        this.hasResult = hasResult;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return getName();\n    }\n\n    /**\n     * Gets the opcode value.\n     *\n     * @return {@code Opcodes.MIN_VALUE..Opcodes.MAX_VALUE;} the opcode value\n     */\n    public int getOpcode() {\n        return opcode;\n    }\n\n    /**\n     * Gets the opcode family. The opcode family is the unmarked (no\n     * \"/...\") opcode that has equivalent semantics to this one.\n     *\n     * @return {@code Opcodes.MIN_VALUE..Opcodes.MAX_VALUE;} the opcode family\n     */\n    public int getFamily() {\n        return family;\n    }\n\n    /**\n     * Gets the instruction format.\n     *\n     * @return {@code non-null;} the instruction format\n     */\n    public InsnFormat getFormat() {\n        return format;\n    }\n\n    /**\n     * Returns whether this opcode uses a result register.\n     *\n     * @return {@code true} iff this opcode uses a result register\n     */\n    public boolean hasResult() {\n        return hasResult;\n    }\n\n    /**\n     * Gets the opcode name.\n     *\n     * @return {@code non-null;} the opcode name\n     */\n    public String getName() {\n        return OpcodeInfo.getName(opcode);\n    }\n\n    /**\n     * Gets the opcode value to try next when attempting to match an\n     * opcode to particular arguments. This returns {@code\n     * Opcodes.NO_NEXT} to indicate that this is the last opcode to\n     * try in a particular chain.\n     *\n     * @return {@code Opcodes.MIN_VALUE..Opcodes.MAX_VALUE;} the opcode value\n     */\n    public int getNextOpcode() {\n        return nextOpcode;\n    }\n\n    /**\n     * Gets the opcode for the opposite test of this instance. This is only\n     * valid for opcodes which are in fact tests.\n     *\n     * @return {@code non-null;} the opposite test\n     */\n    public Dop getOppositeTest() {\n        switch (opcode) {\n            case Opcodes.IF_EQ:  return Dops.IF_NE;\n            case Opcodes.IF_NE:  return Dops.IF_EQ;\n            case Opcodes.IF_LT:  return Dops.IF_GE;\n            case Opcodes.IF_GE:  return Dops.IF_LT;\n            case Opcodes.IF_GT:  return Dops.IF_LE;\n            case Opcodes.IF_LE:  return Dops.IF_GT;\n            case Opcodes.IF_EQZ: return Dops.IF_NEZ;\n            case Opcodes.IF_NEZ: return Dops.IF_EQZ;\n            case Opcodes.IF_LTZ: return Dops.IF_GEZ;\n            case Opcodes.IF_GEZ: return Dops.IF_LTZ;\n            case Opcodes.IF_GTZ: return Dops.IF_LEZ;\n            case Opcodes.IF_LEZ: return Dops.IF_GTZ;\n        }\n\n        throw new IllegalArgumentException(\"bogus opcode: \" + this);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/Dops.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.dex.DexOptions;\nimport com.taobao.android.dx.dex.code.form.Form10t;\nimport com.taobao.android.dx.dex.code.form.Form10x;\nimport com.taobao.android.dx.dex.code.form.Form11n;\nimport com.taobao.android.dx.dex.code.form.Form11x;\nimport com.taobao.android.dx.dex.code.form.Form12x;\nimport com.taobao.android.dx.dex.code.form.Form20t;\nimport com.taobao.android.dx.dex.code.form.Form21c;\nimport com.taobao.android.dx.dex.code.form.Form21h;\nimport com.taobao.android.dx.dex.code.form.Form21s;\nimport com.taobao.android.dx.dex.code.form.Form21t;\nimport com.taobao.android.dx.dex.code.form.Form22b;\nimport com.taobao.android.dx.dex.code.form.Form22c;\nimport com.taobao.android.dx.dex.code.form.Form22s;\nimport com.taobao.android.dx.dex.code.form.Form22t;\nimport com.taobao.android.dx.dex.code.form.Form22x;\nimport com.taobao.android.dx.dex.code.form.Form23x;\nimport com.taobao.android.dx.dex.code.form.Form30t;\nimport com.taobao.android.dx.dex.code.form.Form31c;\nimport com.taobao.android.dx.dex.code.form.Form31i;\nimport com.taobao.android.dx.dex.code.form.Form31t;\nimport com.taobao.android.dx.dex.code.form.Form32x;\nimport com.taobao.android.dx.dex.code.form.Form35c;\nimport com.taobao.android.dx.dex.code.form.Form3rc;\nimport com.taobao.android.dx.dex.code.form.Form51l;\nimport com.taobao.android.dx.dex.code.form.SpecialFormat;\nimport com.taobao.android.dx.io.Opcodes;\n\n/**\n * Standard instances of {@link Dop} and utility methods for getting\n * them.\n */\npublic final class Dops {\n    /** {@code non-null;} array containing all the standard instances */\n    private static final Dop[] DOPS;\n\n    /**\n     * pseudo-opcode used for nonstandard formatted \"instructions\"\n     * (which are mostly not actually instructions, though they do\n     * appear in instruction lists). TODO: Retire the usage of this\n     * constant.\n     */\n    public static final Dop SPECIAL_FORMAT =\n        new Dop(Opcodes.SPECIAL_FORMAT, Opcodes.SPECIAL_FORMAT,\n                Opcodes.NO_NEXT, SpecialFormat.THE_ONE, false);\n\n    // BEGIN(dops); GENERATED AUTOMATICALLY BY opcode-gen\n    public static final Dop NOP =\n        new Dop(Opcodes.NOP, Opcodes.NOP,\n            Opcodes.NO_NEXT, Form10x.THE_ONE, false);\n\n    public static final Dop MOVE =\n        new Dop(Opcodes.MOVE, Opcodes.MOVE,\n            Opcodes.MOVE_FROM16, Form12x.THE_ONE, true);\n\n    public static final Dop MOVE_FROM16 =\n        new Dop(Opcodes.MOVE_FROM16, Opcodes.MOVE,\n            Opcodes.MOVE_16, Form22x.THE_ONE, true);\n\n    public static final Dop MOVE_16 =\n        new Dop(Opcodes.MOVE_16, Opcodes.MOVE,\n            Opcodes.NO_NEXT, Form32x.THE_ONE, true);\n\n    public static final Dop MOVE_WIDE =\n        new Dop(Opcodes.MOVE_WIDE, Opcodes.MOVE_WIDE,\n            Opcodes.MOVE_WIDE_FROM16, Form12x.THE_ONE, true);\n\n    public static final Dop MOVE_WIDE_FROM16 =\n        new Dop(Opcodes.MOVE_WIDE_FROM16, Opcodes.MOVE_WIDE,\n            Opcodes.MOVE_WIDE_16, Form22x.THE_ONE, true);\n\n    public static final Dop MOVE_WIDE_16 =\n        new Dop(Opcodes.MOVE_WIDE_16, Opcodes.MOVE_WIDE,\n            Opcodes.NO_NEXT, Form32x.THE_ONE, true);\n\n    public static final Dop MOVE_OBJECT =\n        new Dop(Opcodes.MOVE_OBJECT, Opcodes.MOVE_OBJECT,\n            Opcodes.MOVE_OBJECT_FROM16, Form12x.THE_ONE, true);\n\n    public static final Dop MOVE_OBJECT_FROM16 =\n        new Dop(Opcodes.MOVE_OBJECT_FROM16, Opcodes.MOVE_OBJECT,\n            Opcodes.MOVE_OBJECT_16, Form22x.THE_ONE, true);\n\n    public static final Dop MOVE_OBJECT_16 =\n        new Dop(Opcodes.MOVE_OBJECT_16, Opcodes.MOVE_OBJECT,\n            Opcodes.NO_NEXT, Form32x.THE_ONE, true);\n\n    public static final Dop MOVE_RESULT =\n        new Dop(Opcodes.MOVE_RESULT, Opcodes.MOVE_RESULT,\n            Opcodes.NO_NEXT, Form11x.THE_ONE, true);\n\n    public static final Dop MOVE_RESULT_WIDE =\n        new Dop(Opcodes.MOVE_RESULT_WIDE, Opcodes.MOVE_RESULT_WIDE,\n            Opcodes.NO_NEXT, Form11x.THE_ONE, true);\n\n    public static final Dop MOVE_RESULT_OBJECT =\n        new Dop(Opcodes.MOVE_RESULT_OBJECT, Opcodes.MOVE_RESULT_OBJECT,\n            Opcodes.NO_NEXT, Form11x.THE_ONE, true);\n\n    public static final Dop MOVE_EXCEPTION =\n        new Dop(Opcodes.MOVE_EXCEPTION, Opcodes.MOVE_EXCEPTION,\n            Opcodes.NO_NEXT, Form11x.THE_ONE, true);\n\n    public static final Dop RETURN_VOID =\n        new Dop(Opcodes.RETURN_VOID, Opcodes.RETURN_VOID,\n            Opcodes.NO_NEXT, Form10x.THE_ONE, false);\n\n    public static final Dop RETURN =\n        new Dop(Opcodes.RETURN, Opcodes.RETURN,\n            Opcodes.NO_NEXT, Form11x.THE_ONE, false);\n\n    public static final Dop RETURN_WIDE =\n        new Dop(Opcodes.RETURN_WIDE, Opcodes.RETURN_WIDE,\n            Opcodes.NO_NEXT, Form11x.THE_ONE, false);\n\n    public static final Dop RETURN_OBJECT =\n        new Dop(Opcodes.RETURN_OBJECT, Opcodes.RETURN_OBJECT,\n            Opcodes.NO_NEXT, Form11x.THE_ONE, false);\n\n    public static final Dop CONST_4 =\n        new Dop(Opcodes.CONST_4, Opcodes.CONST,\n            Opcodes.CONST_16, Form11n.THE_ONE, true);\n\n    public static final Dop CONST_16 =\n        new Dop(Opcodes.CONST_16, Opcodes.CONST,\n            Opcodes.CONST_HIGH16, Form21s.THE_ONE, true);\n\n    public static final Dop CONST =\n        new Dop(Opcodes.CONST, Opcodes.CONST,\n            Opcodes.NO_NEXT, Form31i.THE_ONE, true);\n\n    public static final Dop CONST_HIGH16 =\n        new Dop(Opcodes.CONST_HIGH16, Opcodes.CONST,\n            Opcodes.CONST, Form21h.THE_ONE, true);\n\n    public static final Dop CONST_WIDE_16 =\n        new Dop(Opcodes.CONST_WIDE_16, Opcodes.CONST_WIDE,\n            Opcodes.CONST_WIDE_HIGH16, Form21s.THE_ONE, true);\n\n    public static final Dop CONST_WIDE_32 =\n        new Dop(Opcodes.CONST_WIDE_32, Opcodes.CONST_WIDE,\n            Opcodes.CONST_WIDE, Form31i.THE_ONE, true);\n\n    public static final Dop CONST_WIDE =\n        new Dop(Opcodes.CONST_WIDE, Opcodes.CONST_WIDE,\n            Opcodes.NO_NEXT, Form51l.THE_ONE, true);\n\n    public static final Dop CONST_WIDE_HIGH16 =\n        new Dop(Opcodes.CONST_WIDE_HIGH16, Opcodes.CONST_WIDE,\n            Opcodes.CONST_WIDE_32, Form21h.THE_ONE, true);\n\n    public static final Dop CONST_STRING =\n        new Dop(Opcodes.CONST_STRING, Opcodes.CONST_STRING,\n            Opcodes.CONST_STRING_JUMBO, Form21c.THE_ONE, true);\n\n    public static final Dop CONST_STRING_JUMBO =\n        new Dop(Opcodes.CONST_STRING_JUMBO, Opcodes.CONST_STRING,\n            Opcodes.NO_NEXT, Form31c.THE_ONE, true);\n\n    public static final Dop CONST_CLASS =\n        new Dop(Opcodes.CONST_CLASS, Opcodes.CONST_CLASS,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, true);\n\n    public static final Dop MONITOR_ENTER =\n        new Dop(Opcodes.MONITOR_ENTER, Opcodes.MONITOR_ENTER,\n            Opcodes.NO_NEXT, Form11x.THE_ONE, false);\n\n    public static final Dop MONITOR_EXIT =\n        new Dop(Opcodes.MONITOR_EXIT, Opcodes.MONITOR_EXIT,\n            Opcodes.NO_NEXT, Form11x.THE_ONE, false);\n\n    public static final Dop CHECK_CAST =\n        new Dop(Opcodes.CHECK_CAST, Opcodes.CHECK_CAST,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, true);\n\n    public static final Dop INSTANCE_OF =\n        new Dop(Opcodes.INSTANCE_OF, Opcodes.INSTANCE_OF,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, true);\n\n    public static final Dop ARRAY_LENGTH =\n        new Dop(Opcodes.ARRAY_LENGTH, Opcodes.ARRAY_LENGTH,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop NEW_INSTANCE =\n        new Dop(Opcodes.NEW_INSTANCE, Opcodes.NEW_INSTANCE,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, true);\n\n    public static final Dop NEW_ARRAY =\n        new Dop(Opcodes.NEW_ARRAY, Opcodes.NEW_ARRAY,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, true);\n\n    public static final Dop FILLED_NEW_ARRAY =\n        new Dop(Opcodes.FILLED_NEW_ARRAY, Opcodes.FILLED_NEW_ARRAY,\n            Opcodes.FILLED_NEW_ARRAY_RANGE, Form35c.THE_ONE, false);\n\n    public static final Dop FILLED_NEW_ARRAY_RANGE =\n        new Dop(Opcodes.FILLED_NEW_ARRAY_RANGE, Opcodes.FILLED_NEW_ARRAY,\n            Opcodes.NO_NEXT, Form3rc.THE_ONE, false);\n\n    public static final Dop FILL_ARRAY_DATA =\n        new Dop(Opcodes.FILL_ARRAY_DATA, Opcodes.FILL_ARRAY_DATA,\n            Opcodes.NO_NEXT, Form31t.THE_ONE, false);\n\n    public static final Dop THROW =\n        new Dop(Opcodes.THROW, Opcodes.THROW,\n            Opcodes.NO_NEXT, Form11x.THE_ONE, false);\n\n    public static final Dop GOTO =\n        new Dop(Opcodes.GOTO, Opcodes.GOTO,\n            Opcodes.GOTO_16, Form10t.THE_ONE, false);\n\n    public static final Dop GOTO_16 =\n        new Dop(Opcodes.GOTO_16, Opcodes.GOTO,\n            Opcodes.GOTO_32, Form20t.THE_ONE, false);\n\n    public static final Dop GOTO_32 =\n        new Dop(Opcodes.GOTO_32, Opcodes.GOTO,\n            Opcodes.NO_NEXT, Form30t.THE_ONE, false);\n\n    public static final Dop PACKED_SWITCH =\n        new Dop(Opcodes.PACKED_SWITCH, Opcodes.PACKED_SWITCH,\n            Opcodes.NO_NEXT, Form31t.THE_ONE, false);\n\n    public static final Dop SPARSE_SWITCH =\n        new Dop(Opcodes.SPARSE_SWITCH, Opcodes.SPARSE_SWITCH,\n            Opcodes.NO_NEXT, Form31t.THE_ONE, false);\n\n    public static final Dop CMPL_FLOAT =\n        new Dop(Opcodes.CMPL_FLOAT, Opcodes.CMPL_FLOAT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop CMPG_FLOAT =\n        new Dop(Opcodes.CMPG_FLOAT, Opcodes.CMPG_FLOAT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop CMPL_DOUBLE =\n        new Dop(Opcodes.CMPL_DOUBLE, Opcodes.CMPL_DOUBLE,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop CMPG_DOUBLE =\n        new Dop(Opcodes.CMPG_DOUBLE, Opcodes.CMPG_DOUBLE,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop CMP_LONG =\n        new Dop(Opcodes.CMP_LONG, Opcodes.CMP_LONG,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop IF_EQ =\n        new Dop(Opcodes.IF_EQ, Opcodes.IF_EQ,\n            Opcodes.NO_NEXT, Form22t.THE_ONE, false);\n\n    public static final Dop IF_NE =\n        new Dop(Opcodes.IF_NE, Opcodes.IF_NE,\n            Opcodes.NO_NEXT, Form22t.THE_ONE, false);\n\n    public static final Dop IF_LT =\n        new Dop(Opcodes.IF_LT, Opcodes.IF_LT,\n            Opcodes.NO_NEXT, Form22t.THE_ONE, false);\n\n    public static final Dop IF_GE =\n        new Dop(Opcodes.IF_GE, Opcodes.IF_GE,\n            Opcodes.NO_NEXT, Form22t.THE_ONE, false);\n\n    public static final Dop IF_GT =\n        new Dop(Opcodes.IF_GT, Opcodes.IF_GT,\n            Opcodes.NO_NEXT, Form22t.THE_ONE, false);\n\n    public static final Dop IF_LE =\n        new Dop(Opcodes.IF_LE, Opcodes.IF_LE,\n            Opcodes.NO_NEXT, Form22t.THE_ONE, false);\n\n    public static final Dop IF_EQZ =\n        new Dop(Opcodes.IF_EQZ, Opcodes.IF_EQZ,\n            Opcodes.NO_NEXT, Form21t.THE_ONE, false);\n\n    public static final Dop IF_NEZ =\n        new Dop(Opcodes.IF_NEZ, Opcodes.IF_NEZ,\n            Opcodes.NO_NEXT, Form21t.THE_ONE, false);\n\n    public static final Dop IF_LTZ =\n        new Dop(Opcodes.IF_LTZ, Opcodes.IF_LTZ,\n            Opcodes.NO_NEXT, Form21t.THE_ONE, false);\n\n    public static final Dop IF_GEZ =\n        new Dop(Opcodes.IF_GEZ, Opcodes.IF_GEZ,\n            Opcodes.NO_NEXT, Form21t.THE_ONE, false);\n\n    public static final Dop IF_GTZ =\n        new Dop(Opcodes.IF_GTZ, Opcodes.IF_GTZ,\n            Opcodes.NO_NEXT, Form21t.THE_ONE, false);\n\n    public static final Dop IF_LEZ =\n        new Dop(Opcodes.IF_LEZ, Opcodes.IF_LEZ,\n            Opcodes.NO_NEXT, Form21t.THE_ONE, false);\n\n    public static final Dop AGET =\n        new Dop(Opcodes.AGET, Opcodes.AGET,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop AGET_WIDE =\n        new Dop(Opcodes.AGET_WIDE, Opcodes.AGET_WIDE,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop AGET_OBJECT =\n        new Dop(Opcodes.AGET_OBJECT, Opcodes.AGET_OBJECT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop AGET_BOOLEAN =\n        new Dop(Opcodes.AGET_BOOLEAN, Opcodes.AGET_BOOLEAN,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop AGET_BYTE =\n        new Dop(Opcodes.AGET_BYTE, Opcodes.AGET_BYTE,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop AGET_CHAR =\n        new Dop(Opcodes.AGET_CHAR, Opcodes.AGET_CHAR,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop AGET_SHORT =\n        new Dop(Opcodes.AGET_SHORT, Opcodes.AGET_SHORT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop APUT =\n        new Dop(Opcodes.APUT, Opcodes.APUT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, false);\n\n    public static final Dop APUT_WIDE =\n        new Dop(Opcodes.APUT_WIDE, Opcodes.APUT_WIDE,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, false);\n\n    public static final Dop APUT_OBJECT =\n        new Dop(Opcodes.APUT_OBJECT, Opcodes.APUT_OBJECT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, false);\n\n    public static final Dop APUT_BOOLEAN =\n        new Dop(Opcodes.APUT_BOOLEAN, Opcodes.APUT_BOOLEAN,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, false);\n\n    public static final Dop APUT_BYTE =\n        new Dop(Opcodes.APUT_BYTE, Opcodes.APUT_BYTE,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, false);\n\n    public static final Dop APUT_CHAR =\n        new Dop(Opcodes.APUT_CHAR, Opcodes.APUT_CHAR,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, false);\n\n    public static final Dop APUT_SHORT =\n        new Dop(Opcodes.APUT_SHORT, Opcodes.APUT_SHORT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, false);\n\n    public static final Dop IGET =\n        new Dop(Opcodes.IGET, Opcodes.IGET,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, true);\n\n    public static final Dop IGET_WIDE =\n        new Dop(Opcodes.IGET_WIDE, Opcodes.IGET_WIDE,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, true);\n\n    public static final Dop IGET_OBJECT =\n        new Dop(Opcodes.IGET_OBJECT, Opcodes.IGET_OBJECT,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, true);\n\n    public static final Dop IGET_BOOLEAN =\n        new Dop(Opcodes.IGET_BOOLEAN, Opcodes.IGET_BOOLEAN,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, true);\n\n    public static final Dop IGET_BYTE =\n        new Dop(Opcodes.IGET_BYTE, Opcodes.IGET_BYTE,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, true);\n\n    public static final Dop IGET_CHAR =\n        new Dop(Opcodes.IGET_CHAR, Opcodes.IGET_CHAR,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, true);\n\n    public static final Dop IGET_SHORT =\n        new Dop(Opcodes.IGET_SHORT, Opcodes.IGET_SHORT,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, true);\n\n    public static final Dop IPUT =\n        new Dop(Opcodes.IPUT, Opcodes.IPUT,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, false);\n\n    public static final Dop IPUT_WIDE =\n        new Dop(Opcodes.IPUT_WIDE, Opcodes.IPUT_WIDE,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, false);\n\n    public static final Dop IPUT_OBJECT =\n        new Dop(Opcodes.IPUT_OBJECT, Opcodes.IPUT_OBJECT,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, false);\n\n    public static final Dop IPUT_BOOLEAN =\n        new Dop(Opcodes.IPUT_BOOLEAN, Opcodes.IPUT_BOOLEAN,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, false);\n\n    public static final Dop IPUT_BYTE =\n        new Dop(Opcodes.IPUT_BYTE, Opcodes.IPUT_BYTE,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, false);\n\n    public static final Dop IPUT_CHAR =\n        new Dop(Opcodes.IPUT_CHAR, Opcodes.IPUT_CHAR,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, false);\n\n    public static final Dop IPUT_SHORT =\n        new Dop(Opcodes.IPUT_SHORT, Opcodes.IPUT_SHORT,\n            Opcodes.NO_NEXT, Form22c.THE_ONE, false);\n\n    public static final Dop SGET =\n        new Dop(Opcodes.SGET, Opcodes.SGET,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, true);\n\n    public static final Dop SGET_WIDE =\n        new Dop(Opcodes.SGET_WIDE, Opcodes.SGET_WIDE,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, true);\n\n    public static final Dop SGET_OBJECT =\n        new Dop(Opcodes.SGET_OBJECT, Opcodes.SGET_OBJECT,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, true);\n\n    public static final Dop SGET_BOOLEAN =\n        new Dop(Opcodes.SGET_BOOLEAN, Opcodes.SGET_BOOLEAN,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, true);\n\n    public static final Dop SGET_BYTE =\n        new Dop(Opcodes.SGET_BYTE, Opcodes.SGET_BYTE,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, true);\n\n    public static final Dop SGET_CHAR =\n        new Dop(Opcodes.SGET_CHAR, Opcodes.SGET_CHAR,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, true);\n\n    public static final Dop SGET_SHORT =\n        new Dop(Opcodes.SGET_SHORT, Opcodes.SGET_SHORT,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, true);\n\n    public static final Dop SPUT =\n        new Dop(Opcodes.SPUT, Opcodes.SPUT,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, false);\n\n    public static final Dop SPUT_WIDE =\n        new Dop(Opcodes.SPUT_WIDE, Opcodes.SPUT_WIDE,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, false);\n\n    public static final Dop SPUT_OBJECT =\n        new Dop(Opcodes.SPUT_OBJECT, Opcodes.SPUT_OBJECT,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, false);\n\n    public static final Dop SPUT_BOOLEAN =\n        new Dop(Opcodes.SPUT_BOOLEAN, Opcodes.SPUT_BOOLEAN,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, false);\n\n    public static final Dop SPUT_BYTE =\n        new Dop(Opcodes.SPUT_BYTE, Opcodes.SPUT_BYTE,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, false);\n\n    public static final Dop SPUT_CHAR =\n        new Dop(Opcodes.SPUT_CHAR, Opcodes.SPUT_CHAR,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, false);\n\n    public static final Dop SPUT_SHORT =\n        new Dop(Opcodes.SPUT_SHORT, Opcodes.SPUT_SHORT,\n            Opcodes.NO_NEXT, Form21c.THE_ONE, false);\n\n    public static final Dop INVOKE_VIRTUAL =\n        new Dop(Opcodes.INVOKE_VIRTUAL, Opcodes.INVOKE_VIRTUAL,\n            Opcodes.INVOKE_VIRTUAL_RANGE, Form35c.THE_ONE, false);\n\n    public static final Dop INVOKE_SUPER =\n        new Dop(Opcodes.INVOKE_SUPER, Opcodes.INVOKE_SUPER,\n            Opcodes.INVOKE_SUPER_RANGE, Form35c.THE_ONE, false);\n\n    public static final Dop INVOKE_DIRECT =\n        new Dop(Opcodes.INVOKE_DIRECT, Opcodes.INVOKE_DIRECT,\n            Opcodes.INVOKE_DIRECT_RANGE, Form35c.THE_ONE, false);\n\n    public static final Dop INVOKE_STATIC =\n        new Dop(Opcodes.INVOKE_STATIC, Opcodes.INVOKE_STATIC,\n            Opcodes.INVOKE_STATIC_RANGE, Form35c.THE_ONE, false);\n\n    public static final Dop INVOKE_INTERFACE =\n        new Dop(Opcodes.INVOKE_INTERFACE, Opcodes.INVOKE_INTERFACE,\n            Opcodes.INVOKE_INTERFACE_RANGE, Form35c.THE_ONE, false);\n\n    public static final Dop INVOKE_VIRTUAL_RANGE =\n        new Dop(Opcodes.INVOKE_VIRTUAL_RANGE, Opcodes.INVOKE_VIRTUAL,\n            Opcodes.NO_NEXT, Form3rc.THE_ONE, false);\n\n    public static final Dop INVOKE_SUPER_RANGE =\n        new Dop(Opcodes.INVOKE_SUPER_RANGE, Opcodes.INVOKE_SUPER,\n            Opcodes.NO_NEXT, Form3rc.THE_ONE, false);\n\n    public static final Dop INVOKE_DIRECT_RANGE =\n        new Dop(Opcodes.INVOKE_DIRECT_RANGE, Opcodes.INVOKE_DIRECT,\n            Opcodes.NO_NEXT, Form3rc.THE_ONE, false);\n\n    public static final Dop INVOKE_STATIC_RANGE =\n        new Dop(Opcodes.INVOKE_STATIC_RANGE, Opcodes.INVOKE_STATIC,\n            Opcodes.NO_NEXT, Form3rc.THE_ONE, false);\n\n    public static final Dop INVOKE_INTERFACE_RANGE =\n        new Dop(Opcodes.INVOKE_INTERFACE_RANGE, Opcodes.INVOKE_INTERFACE,\n            Opcodes.NO_NEXT, Form3rc.THE_ONE, false);\n\n    public static final Dop NEG_INT =\n        new Dop(Opcodes.NEG_INT, Opcodes.NEG_INT,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop NOT_INT =\n        new Dop(Opcodes.NOT_INT, Opcodes.NOT_INT,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop NEG_LONG =\n        new Dop(Opcodes.NEG_LONG, Opcodes.NEG_LONG,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop NOT_LONG =\n        new Dop(Opcodes.NOT_LONG, Opcodes.NOT_LONG,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop NEG_FLOAT =\n        new Dop(Opcodes.NEG_FLOAT, Opcodes.NEG_FLOAT,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop NEG_DOUBLE =\n        new Dop(Opcodes.NEG_DOUBLE, Opcodes.NEG_DOUBLE,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop INT_TO_LONG =\n        new Dop(Opcodes.INT_TO_LONG, Opcodes.INT_TO_LONG,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop INT_TO_FLOAT =\n        new Dop(Opcodes.INT_TO_FLOAT, Opcodes.INT_TO_FLOAT,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop INT_TO_DOUBLE =\n        new Dop(Opcodes.INT_TO_DOUBLE, Opcodes.INT_TO_DOUBLE,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop LONG_TO_INT =\n        new Dop(Opcodes.LONG_TO_INT, Opcodes.LONG_TO_INT,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop LONG_TO_FLOAT =\n        new Dop(Opcodes.LONG_TO_FLOAT, Opcodes.LONG_TO_FLOAT,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop LONG_TO_DOUBLE =\n        new Dop(Opcodes.LONG_TO_DOUBLE, Opcodes.LONG_TO_DOUBLE,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop FLOAT_TO_INT =\n        new Dop(Opcodes.FLOAT_TO_INT, Opcodes.FLOAT_TO_INT,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop FLOAT_TO_LONG =\n        new Dop(Opcodes.FLOAT_TO_LONG, Opcodes.FLOAT_TO_LONG,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop FLOAT_TO_DOUBLE =\n        new Dop(Opcodes.FLOAT_TO_DOUBLE, Opcodes.FLOAT_TO_DOUBLE,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop DOUBLE_TO_INT =\n        new Dop(Opcodes.DOUBLE_TO_INT, Opcodes.DOUBLE_TO_INT,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop DOUBLE_TO_LONG =\n        new Dop(Opcodes.DOUBLE_TO_LONG, Opcodes.DOUBLE_TO_LONG,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop DOUBLE_TO_FLOAT =\n        new Dop(Opcodes.DOUBLE_TO_FLOAT, Opcodes.DOUBLE_TO_FLOAT,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop INT_TO_BYTE =\n        new Dop(Opcodes.INT_TO_BYTE, Opcodes.INT_TO_BYTE,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop INT_TO_CHAR =\n        new Dop(Opcodes.INT_TO_CHAR, Opcodes.INT_TO_CHAR,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop INT_TO_SHORT =\n        new Dop(Opcodes.INT_TO_SHORT, Opcodes.INT_TO_SHORT,\n            Opcodes.NO_NEXT, Form12x.THE_ONE, true);\n\n    public static final Dop ADD_INT =\n        new Dop(Opcodes.ADD_INT, Opcodes.ADD_INT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop SUB_INT =\n        new Dop(Opcodes.SUB_INT, Opcodes.SUB_INT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop MUL_INT =\n        new Dop(Opcodes.MUL_INT, Opcodes.MUL_INT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop DIV_INT =\n        new Dop(Opcodes.DIV_INT, Opcodes.DIV_INT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop REM_INT =\n        new Dop(Opcodes.REM_INT, Opcodes.REM_INT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop AND_INT =\n        new Dop(Opcodes.AND_INT, Opcodes.AND_INT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop OR_INT =\n        new Dop(Opcodes.OR_INT, Opcodes.OR_INT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop XOR_INT =\n        new Dop(Opcodes.XOR_INT, Opcodes.XOR_INT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop SHL_INT =\n        new Dop(Opcodes.SHL_INT, Opcodes.SHL_INT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop SHR_INT =\n        new Dop(Opcodes.SHR_INT, Opcodes.SHR_INT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop USHR_INT =\n        new Dop(Opcodes.USHR_INT, Opcodes.USHR_INT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop ADD_LONG =\n        new Dop(Opcodes.ADD_LONG, Opcodes.ADD_LONG,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop SUB_LONG =\n        new Dop(Opcodes.SUB_LONG, Opcodes.SUB_LONG,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop MUL_LONG =\n        new Dop(Opcodes.MUL_LONG, Opcodes.MUL_LONG,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop DIV_LONG =\n        new Dop(Opcodes.DIV_LONG, Opcodes.DIV_LONG,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop REM_LONG =\n        new Dop(Opcodes.REM_LONG, Opcodes.REM_LONG,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop AND_LONG =\n        new Dop(Opcodes.AND_LONG, Opcodes.AND_LONG,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop OR_LONG =\n        new Dop(Opcodes.OR_LONG, Opcodes.OR_LONG,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop XOR_LONG =\n        new Dop(Opcodes.XOR_LONG, Opcodes.XOR_LONG,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop SHL_LONG =\n        new Dop(Opcodes.SHL_LONG, Opcodes.SHL_LONG,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop SHR_LONG =\n        new Dop(Opcodes.SHR_LONG, Opcodes.SHR_LONG,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop USHR_LONG =\n        new Dop(Opcodes.USHR_LONG, Opcodes.USHR_LONG,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop ADD_FLOAT =\n        new Dop(Opcodes.ADD_FLOAT, Opcodes.ADD_FLOAT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop SUB_FLOAT =\n        new Dop(Opcodes.SUB_FLOAT, Opcodes.SUB_FLOAT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop MUL_FLOAT =\n        new Dop(Opcodes.MUL_FLOAT, Opcodes.MUL_FLOAT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop DIV_FLOAT =\n        new Dop(Opcodes.DIV_FLOAT, Opcodes.DIV_FLOAT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop REM_FLOAT =\n        new Dop(Opcodes.REM_FLOAT, Opcodes.REM_FLOAT,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop ADD_DOUBLE =\n        new Dop(Opcodes.ADD_DOUBLE, Opcodes.ADD_DOUBLE,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop SUB_DOUBLE =\n        new Dop(Opcodes.SUB_DOUBLE, Opcodes.SUB_DOUBLE,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop MUL_DOUBLE =\n        new Dop(Opcodes.MUL_DOUBLE, Opcodes.MUL_DOUBLE,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop DIV_DOUBLE =\n        new Dop(Opcodes.DIV_DOUBLE, Opcodes.DIV_DOUBLE,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop REM_DOUBLE =\n        new Dop(Opcodes.REM_DOUBLE, Opcodes.REM_DOUBLE,\n            Opcodes.NO_NEXT, Form23x.THE_ONE, true);\n\n    public static final Dop ADD_INT_2ADDR =\n        new Dop(Opcodes.ADD_INT_2ADDR, Opcodes.ADD_INT,\n            Opcodes.ADD_INT, Form12x.THE_ONE, true);\n\n    public static final Dop SUB_INT_2ADDR =\n        new Dop(Opcodes.SUB_INT_2ADDR, Opcodes.SUB_INT,\n            Opcodes.SUB_INT, Form12x.THE_ONE, true);\n\n    public static final Dop MUL_INT_2ADDR =\n        new Dop(Opcodes.MUL_INT_2ADDR, Opcodes.MUL_INT,\n            Opcodes.MUL_INT, Form12x.THE_ONE, true);\n\n    public static final Dop DIV_INT_2ADDR =\n        new Dop(Opcodes.DIV_INT_2ADDR, Opcodes.DIV_INT,\n            Opcodes.DIV_INT, Form12x.THE_ONE, true);\n\n    public static final Dop REM_INT_2ADDR =\n        new Dop(Opcodes.REM_INT_2ADDR, Opcodes.REM_INT,\n            Opcodes.REM_INT, Form12x.THE_ONE, true);\n\n    public static final Dop AND_INT_2ADDR =\n        new Dop(Opcodes.AND_INT_2ADDR, Opcodes.AND_INT,\n            Opcodes.AND_INT, Form12x.THE_ONE, true);\n\n    public static final Dop OR_INT_2ADDR =\n        new Dop(Opcodes.OR_INT_2ADDR, Opcodes.OR_INT,\n            Opcodes.OR_INT, Form12x.THE_ONE, true);\n\n    public static final Dop XOR_INT_2ADDR =\n        new Dop(Opcodes.XOR_INT_2ADDR, Opcodes.XOR_INT,\n            Opcodes.XOR_INT, Form12x.THE_ONE, true);\n\n    public static final Dop SHL_INT_2ADDR =\n        new Dop(Opcodes.SHL_INT_2ADDR, Opcodes.SHL_INT,\n            Opcodes.SHL_INT, Form12x.THE_ONE, true);\n\n    public static final Dop SHR_INT_2ADDR =\n        new Dop(Opcodes.SHR_INT_2ADDR, Opcodes.SHR_INT,\n            Opcodes.SHR_INT, Form12x.THE_ONE, true);\n\n    public static final Dop USHR_INT_2ADDR =\n        new Dop(Opcodes.USHR_INT_2ADDR, Opcodes.USHR_INT,\n            Opcodes.USHR_INT, Form12x.THE_ONE, true);\n\n    public static final Dop ADD_LONG_2ADDR =\n        new Dop(Opcodes.ADD_LONG_2ADDR, Opcodes.ADD_LONG,\n            Opcodes.ADD_LONG, Form12x.THE_ONE, true);\n\n    public static final Dop SUB_LONG_2ADDR =\n        new Dop(Opcodes.SUB_LONG_2ADDR, Opcodes.SUB_LONG,\n            Opcodes.SUB_LONG, Form12x.THE_ONE, true);\n\n    public static final Dop MUL_LONG_2ADDR =\n        new Dop(Opcodes.MUL_LONG_2ADDR, Opcodes.MUL_LONG,\n            Opcodes.MUL_LONG, Form12x.THE_ONE, true);\n\n    public static final Dop DIV_LONG_2ADDR =\n        new Dop(Opcodes.DIV_LONG_2ADDR, Opcodes.DIV_LONG,\n            Opcodes.DIV_LONG, Form12x.THE_ONE, true);\n\n    public static final Dop REM_LONG_2ADDR =\n        new Dop(Opcodes.REM_LONG_2ADDR, Opcodes.REM_LONG,\n            Opcodes.REM_LONG, Form12x.THE_ONE, true);\n\n    public static final Dop AND_LONG_2ADDR =\n        new Dop(Opcodes.AND_LONG_2ADDR, Opcodes.AND_LONG,\n            Opcodes.AND_LONG, Form12x.THE_ONE, true);\n\n    public static final Dop OR_LONG_2ADDR =\n        new Dop(Opcodes.OR_LONG_2ADDR, Opcodes.OR_LONG,\n            Opcodes.OR_LONG, Form12x.THE_ONE, true);\n\n    public static final Dop XOR_LONG_2ADDR =\n        new Dop(Opcodes.XOR_LONG_2ADDR, Opcodes.XOR_LONG,\n            Opcodes.XOR_LONG, Form12x.THE_ONE, true);\n\n    public static final Dop SHL_LONG_2ADDR =\n        new Dop(Opcodes.SHL_LONG_2ADDR, Opcodes.SHL_LONG,\n            Opcodes.SHL_LONG, Form12x.THE_ONE, true);\n\n    public static final Dop SHR_LONG_2ADDR =\n        new Dop(Opcodes.SHR_LONG_2ADDR, Opcodes.SHR_LONG,\n            Opcodes.SHR_LONG, Form12x.THE_ONE, true);\n\n    public static final Dop USHR_LONG_2ADDR =\n        new Dop(Opcodes.USHR_LONG_2ADDR, Opcodes.USHR_LONG,\n            Opcodes.USHR_LONG, Form12x.THE_ONE, true);\n\n    public static final Dop ADD_FLOAT_2ADDR =\n        new Dop(Opcodes.ADD_FLOAT_2ADDR, Opcodes.ADD_FLOAT,\n            Opcodes.ADD_FLOAT, Form12x.THE_ONE, true);\n\n    public static final Dop SUB_FLOAT_2ADDR =\n        new Dop(Opcodes.SUB_FLOAT_2ADDR, Opcodes.SUB_FLOAT,\n            Opcodes.SUB_FLOAT, Form12x.THE_ONE, true);\n\n    public static final Dop MUL_FLOAT_2ADDR =\n        new Dop(Opcodes.MUL_FLOAT_2ADDR, Opcodes.MUL_FLOAT,\n            Opcodes.MUL_FLOAT, Form12x.THE_ONE, true);\n\n    public static final Dop DIV_FLOAT_2ADDR =\n        new Dop(Opcodes.DIV_FLOAT_2ADDR, Opcodes.DIV_FLOAT,\n            Opcodes.DIV_FLOAT, Form12x.THE_ONE, true);\n\n    public static final Dop REM_FLOAT_2ADDR =\n        new Dop(Opcodes.REM_FLOAT_2ADDR, Opcodes.REM_FLOAT,\n            Opcodes.REM_FLOAT, Form12x.THE_ONE, true);\n\n    public static final Dop ADD_DOUBLE_2ADDR =\n        new Dop(Opcodes.ADD_DOUBLE_2ADDR, Opcodes.ADD_DOUBLE,\n            Opcodes.ADD_DOUBLE, Form12x.THE_ONE, true);\n\n    public static final Dop SUB_DOUBLE_2ADDR =\n        new Dop(Opcodes.SUB_DOUBLE_2ADDR, Opcodes.SUB_DOUBLE,\n            Opcodes.SUB_DOUBLE, Form12x.THE_ONE, true);\n\n    public static final Dop MUL_DOUBLE_2ADDR =\n        new Dop(Opcodes.MUL_DOUBLE_2ADDR, Opcodes.MUL_DOUBLE,\n            Opcodes.MUL_DOUBLE, Form12x.THE_ONE, true);\n\n    public static final Dop DIV_DOUBLE_2ADDR =\n        new Dop(Opcodes.DIV_DOUBLE_2ADDR, Opcodes.DIV_DOUBLE,\n            Opcodes.DIV_DOUBLE, Form12x.THE_ONE, true);\n\n    public static final Dop REM_DOUBLE_2ADDR =\n        new Dop(Opcodes.REM_DOUBLE_2ADDR, Opcodes.REM_DOUBLE,\n            Opcodes.REM_DOUBLE, Form12x.THE_ONE, true);\n\n    public static final Dop ADD_INT_LIT16 =\n        new Dop(Opcodes.ADD_INT_LIT16, Opcodes.ADD_INT,\n            Opcodes.NO_NEXT, Form22s.THE_ONE, true);\n\n    public static final Dop RSUB_INT =\n        new Dop(Opcodes.RSUB_INT, Opcodes.RSUB_INT,\n            Opcodes.NO_NEXT, Form22s.THE_ONE, true);\n\n    public static final Dop MUL_INT_LIT16 =\n        new Dop(Opcodes.MUL_INT_LIT16, Opcodes.MUL_INT,\n            Opcodes.NO_NEXT, Form22s.THE_ONE, true);\n\n    public static final Dop DIV_INT_LIT16 =\n        new Dop(Opcodes.DIV_INT_LIT16, Opcodes.DIV_INT,\n            Opcodes.NO_NEXT, Form22s.THE_ONE, true);\n\n    public static final Dop REM_INT_LIT16 =\n        new Dop(Opcodes.REM_INT_LIT16, Opcodes.REM_INT,\n            Opcodes.NO_NEXT, Form22s.THE_ONE, true);\n\n    public static final Dop AND_INT_LIT16 =\n        new Dop(Opcodes.AND_INT_LIT16, Opcodes.AND_INT,\n            Opcodes.NO_NEXT, Form22s.THE_ONE, true);\n\n    public static final Dop OR_INT_LIT16 =\n        new Dop(Opcodes.OR_INT_LIT16, Opcodes.OR_INT,\n            Opcodes.NO_NEXT, Form22s.THE_ONE, true);\n\n    public static final Dop XOR_INT_LIT16 =\n        new Dop(Opcodes.XOR_INT_LIT16, Opcodes.XOR_INT,\n            Opcodes.NO_NEXT, Form22s.THE_ONE, true);\n\n    public static final Dop ADD_INT_LIT8 =\n        new Dop(Opcodes.ADD_INT_LIT8, Opcodes.ADD_INT,\n            Opcodes.ADD_INT_LIT16, Form22b.THE_ONE, true);\n\n    public static final Dop RSUB_INT_LIT8 =\n        new Dop(Opcodes.RSUB_INT_LIT8, Opcodes.RSUB_INT,\n            Opcodes.RSUB_INT, Form22b.THE_ONE, true);\n\n    public static final Dop MUL_INT_LIT8 =\n        new Dop(Opcodes.MUL_INT_LIT8, Opcodes.MUL_INT,\n            Opcodes.MUL_INT_LIT16, Form22b.THE_ONE, true);\n\n    public static final Dop DIV_INT_LIT8 =\n        new Dop(Opcodes.DIV_INT_LIT8, Opcodes.DIV_INT,\n            Opcodes.DIV_INT_LIT16, Form22b.THE_ONE, true);\n\n    public static final Dop REM_INT_LIT8 =\n        new Dop(Opcodes.REM_INT_LIT8, Opcodes.REM_INT,\n            Opcodes.REM_INT_LIT16, Form22b.THE_ONE, true);\n\n    public static final Dop AND_INT_LIT8 =\n        new Dop(Opcodes.AND_INT_LIT8, Opcodes.AND_INT,\n            Opcodes.AND_INT_LIT16, Form22b.THE_ONE, true);\n\n    public static final Dop OR_INT_LIT8 =\n        new Dop(Opcodes.OR_INT_LIT8, Opcodes.OR_INT,\n            Opcodes.OR_INT_LIT16, Form22b.THE_ONE, true);\n\n    public static final Dop XOR_INT_LIT8 =\n        new Dop(Opcodes.XOR_INT_LIT8, Opcodes.XOR_INT,\n            Opcodes.XOR_INT_LIT16, Form22b.THE_ONE, true);\n\n    public static final Dop SHL_INT_LIT8 =\n        new Dop(Opcodes.SHL_INT_LIT8, Opcodes.SHL_INT,\n            Opcodes.NO_NEXT, Form22b.THE_ONE, true);\n\n    public static final Dop SHR_INT_LIT8 =\n        new Dop(Opcodes.SHR_INT_LIT8, Opcodes.SHR_INT,\n            Opcodes.NO_NEXT, Form22b.THE_ONE, true);\n\n    public static final Dop USHR_INT_LIT8 =\n        new Dop(Opcodes.USHR_INT_LIT8, Opcodes.USHR_INT,\n            Opcodes.NO_NEXT, Form22b.THE_ONE, true);\n\n    // END(dops)\n\n    // Static initialization.\n    static {\n        DOPS = new Dop[Opcodes.MAX_VALUE - Opcodes.MIN_VALUE + 1];\n\n        set(SPECIAL_FORMAT);\n\n        // BEGIN(dops-init); GENERATED AUTOMATICALLY BY opcode-gen\n        set(NOP);\n        set(MOVE);\n        set(MOVE_FROM16);\n        set(MOVE_16);\n        set(MOVE_WIDE);\n        set(MOVE_WIDE_FROM16);\n        set(MOVE_WIDE_16);\n        set(MOVE_OBJECT);\n        set(MOVE_OBJECT_FROM16);\n        set(MOVE_OBJECT_16);\n        set(MOVE_RESULT);\n        set(MOVE_RESULT_WIDE);\n        set(MOVE_RESULT_OBJECT);\n        set(MOVE_EXCEPTION);\n        set(RETURN_VOID);\n        set(RETURN);\n        set(RETURN_WIDE);\n        set(RETURN_OBJECT);\n        set(CONST_4);\n        set(CONST_16);\n        set(CONST);\n        set(CONST_HIGH16);\n        set(CONST_WIDE_16);\n        set(CONST_WIDE_32);\n        set(CONST_WIDE);\n        set(CONST_WIDE_HIGH16);\n        set(CONST_STRING);\n        set(CONST_STRING_JUMBO);\n        set(CONST_CLASS);\n        set(MONITOR_ENTER);\n        set(MONITOR_EXIT);\n        set(CHECK_CAST);\n        set(INSTANCE_OF);\n        set(ARRAY_LENGTH);\n        set(NEW_INSTANCE);\n        set(NEW_ARRAY);\n        set(FILLED_NEW_ARRAY);\n        set(FILLED_NEW_ARRAY_RANGE);\n        set(FILL_ARRAY_DATA);\n        set(THROW);\n        set(GOTO);\n        set(GOTO_16);\n        set(GOTO_32);\n        set(PACKED_SWITCH);\n        set(SPARSE_SWITCH);\n        set(CMPL_FLOAT);\n        set(CMPG_FLOAT);\n        set(CMPL_DOUBLE);\n        set(CMPG_DOUBLE);\n        set(CMP_LONG);\n        set(IF_EQ);\n        set(IF_NE);\n        set(IF_LT);\n        set(IF_GE);\n        set(IF_GT);\n        set(IF_LE);\n        set(IF_EQZ);\n        set(IF_NEZ);\n        set(IF_LTZ);\n        set(IF_GEZ);\n        set(IF_GTZ);\n        set(IF_LEZ);\n        set(AGET);\n        set(AGET_WIDE);\n        set(AGET_OBJECT);\n        set(AGET_BOOLEAN);\n        set(AGET_BYTE);\n        set(AGET_CHAR);\n        set(AGET_SHORT);\n        set(APUT);\n        set(APUT_WIDE);\n        set(APUT_OBJECT);\n        set(APUT_BOOLEAN);\n        set(APUT_BYTE);\n        set(APUT_CHAR);\n        set(APUT_SHORT);\n        set(IGET);\n        set(IGET_WIDE);\n        set(IGET_OBJECT);\n        set(IGET_BOOLEAN);\n        set(IGET_BYTE);\n        set(IGET_CHAR);\n        set(IGET_SHORT);\n        set(IPUT);\n        set(IPUT_WIDE);\n        set(IPUT_OBJECT);\n        set(IPUT_BOOLEAN);\n        set(IPUT_BYTE);\n        set(IPUT_CHAR);\n        set(IPUT_SHORT);\n        set(SGET);\n        set(SGET_WIDE);\n        set(SGET_OBJECT);\n        set(SGET_BOOLEAN);\n        set(SGET_BYTE);\n        set(SGET_CHAR);\n        set(SGET_SHORT);\n        set(SPUT);\n        set(SPUT_WIDE);\n        set(SPUT_OBJECT);\n        set(SPUT_BOOLEAN);\n        set(SPUT_BYTE);\n        set(SPUT_CHAR);\n        set(SPUT_SHORT);\n        set(INVOKE_VIRTUAL);\n        set(INVOKE_SUPER);\n        set(INVOKE_DIRECT);\n        set(INVOKE_STATIC);\n        set(INVOKE_INTERFACE);\n        set(INVOKE_VIRTUAL_RANGE);\n        set(INVOKE_SUPER_RANGE);\n        set(INVOKE_DIRECT_RANGE);\n        set(INVOKE_STATIC_RANGE);\n        set(INVOKE_INTERFACE_RANGE);\n        set(NEG_INT);\n        set(NOT_INT);\n        set(NEG_LONG);\n        set(NOT_LONG);\n        set(NEG_FLOAT);\n        set(NEG_DOUBLE);\n        set(INT_TO_LONG);\n        set(INT_TO_FLOAT);\n        set(INT_TO_DOUBLE);\n        set(LONG_TO_INT);\n        set(LONG_TO_FLOAT);\n        set(LONG_TO_DOUBLE);\n        set(FLOAT_TO_INT);\n        set(FLOAT_TO_LONG);\n        set(FLOAT_TO_DOUBLE);\n        set(DOUBLE_TO_INT);\n        set(DOUBLE_TO_LONG);\n        set(DOUBLE_TO_FLOAT);\n        set(INT_TO_BYTE);\n        set(INT_TO_CHAR);\n        set(INT_TO_SHORT);\n        set(ADD_INT);\n        set(SUB_INT);\n        set(MUL_INT);\n        set(DIV_INT);\n        set(REM_INT);\n        set(AND_INT);\n        set(OR_INT);\n        set(XOR_INT);\n        set(SHL_INT);\n        set(SHR_INT);\n        set(USHR_INT);\n        set(ADD_LONG);\n        set(SUB_LONG);\n        set(MUL_LONG);\n        set(DIV_LONG);\n        set(REM_LONG);\n        set(AND_LONG);\n        set(OR_LONG);\n        set(XOR_LONG);\n        set(SHL_LONG);\n        set(SHR_LONG);\n        set(USHR_LONG);\n        set(ADD_FLOAT);\n        set(SUB_FLOAT);\n        set(MUL_FLOAT);\n        set(DIV_FLOAT);\n        set(REM_FLOAT);\n        set(ADD_DOUBLE);\n        set(SUB_DOUBLE);\n        set(MUL_DOUBLE);\n        set(DIV_DOUBLE);\n        set(REM_DOUBLE);\n        set(ADD_INT_2ADDR);\n        set(SUB_INT_2ADDR);\n        set(MUL_INT_2ADDR);\n        set(DIV_INT_2ADDR);\n        set(REM_INT_2ADDR);\n        set(AND_INT_2ADDR);\n        set(OR_INT_2ADDR);\n        set(XOR_INT_2ADDR);\n        set(SHL_INT_2ADDR);\n        set(SHR_INT_2ADDR);\n        set(USHR_INT_2ADDR);\n        set(ADD_LONG_2ADDR);\n        set(SUB_LONG_2ADDR);\n        set(MUL_LONG_2ADDR);\n        set(DIV_LONG_2ADDR);\n        set(REM_LONG_2ADDR);\n        set(AND_LONG_2ADDR);\n        set(OR_LONG_2ADDR);\n        set(XOR_LONG_2ADDR);\n        set(SHL_LONG_2ADDR);\n        set(SHR_LONG_2ADDR);\n        set(USHR_LONG_2ADDR);\n        set(ADD_FLOAT_2ADDR);\n        set(SUB_FLOAT_2ADDR);\n        set(MUL_FLOAT_2ADDR);\n        set(DIV_FLOAT_2ADDR);\n        set(REM_FLOAT_2ADDR);\n        set(ADD_DOUBLE_2ADDR);\n        set(SUB_DOUBLE_2ADDR);\n        set(MUL_DOUBLE_2ADDR);\n        set(DIV_DOUBLE_2ADDR);\n        set(REM_DOUBLE_2ADDR);\n        set(ADD_INT_LIT16);\n        set(RSUB_INT);\n        set(MUL_INT_LIT16);\n        set(DIV_INT_LIT16);\n        set(REM_INT_LIT16);\n        set(AND_INT_LIT16);\n        set(OR_INT_LIT16);\n        set(XOR_INT_LIT16);\n        set(ADD_INT_LIT8);\n        set(RSUB_INT_LIT8);\n        set(MUL_INT_LIT8);\n        set(DIV_INT_LIT8);\n        set(REM_INT_LIT8);\n        set(AND_INT_LIT8);\n        set(OR_INT_LIT8);\n        set(XOR_INT_LIT8);\n        set(SHL_INT_LIT8);\n        set(SHR_INT_LIT8);\n        set(USHR_INT_LIT8);\n        // END(dops-init)\n    }\n\n    /**\n     * This class is uninstantiable.\n     */\n    private Dops() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Gets the {@link Dop} for the given opcode value.\n     *\n     * @param opcode {@code Opcodes.MIN_VALUE..Opcodes.MAX_VALUE;} the\n     * opcode value\n     * @return {@code non-null;} the associated opcode instance\n     */\n    public static Dop get(int opcode) {\n        int idx = opcode - Opcodes.MIN_VALUE;\n\n        try {\n            Dop result = DOPS[idx];\n            if (result != null) {\n                return result;\n            }\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Fall through.\n        }\n\n        throw new IllegalArgumentException(\"bogus opcode\");\n    }\n\n    /**\n     * Gets the next {@link Dop} in the instruction fitting chain after the\n     * given instance, if any.\n     *\n     * @param opcode {@code non-null;} the opcode\n     * @param options {@code non-null;} options, used to determine\n     * which opcodes are potentially off-limits\n     * @return {@code null-ok;} the next opcode in the same family, in the\n     * chain of opcodes to try, or {@code null} if the given opcode is\n     * the last in its chain\n     */\n    public static Dop getNextOrNull(Dop opcode, DexOptions options) {\n      int nextOpcode = opcode.getNextOpcode();\n\n      if (nextOpcode == Opcodes.NO_NEXT) {\n        return null;\n      }\n\n      opcode = get(nextOpcode);\n\n      return opcode;\n    }\n\n    /**\n     * Puts the given opcode into the table of all ops.\n     *\n     * @param opcode {@code non-null;} the opcode\n     */\n    private static void set(Dop opcode) {\n        int idx = opcode.getOpcode() - Opcodes.MIN_VALUE;\n        DOPS[idx] = opcode;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/FixedSizeInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.util.AnnotatedOutput;\n\n/**\n * Base class for instructions which are of a fixed code size and\n * which use {@link InsnFormat} methods to write themselves. This\n * includes most &mdash; but not all &mdash; instructions.\n */\npublic abstract class FixedSizeInsn extends DalvInsn {\n    /**\n     * Constructs an instance. The output address of this instance is initially\n     * unknown ({@code -1}).\n     *\n     * <p><b>Note:</b> In the unlikely event that an instruction takes\n     * absolutely no registers (e.g., a {@code nop} or a\n     * no-argument no-result * static method call), then the given\n     * register list may be passed as {@link\n     * RegisterSpecList#EMPTY}.</p>\n     *\n     * @param opcode the opcode; one of the constants from {@link Dops}\n     * @param position {@code non-null;} source position\n     * @param registers {@code non-null;} register list, including a\n     * result register if appropriate (that is, registers may be either\n     * ins or outs)\n     */\n    public FixedSizeInsn(Dop opcode, SourcePosition position,\n                         RegisterSpecList registers) {\n        super(opcode, position, registers);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final int codeSize() {\n        return getOpcode().getFormat().codeSize();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final void writeTo(AnnotatedOutput out) {\n        getOpcode().getFormat().writeTo(out, this);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final DalvInsn withRegisterOffset(int delta) {\n        return withRegisters(getRegisters().withOffset(delta));\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected final String listingString0(boolean noteIndices) {\n        return getOpcode().getFormat().listingString(this, noteIndices);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/HighRegisterPrefix.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.util.AnnotatedOutput;\n\n/**\n * Combination instruction which turns into a variable number of\n * {@code move*} instructions to move a set of registers into\n * registers starting at {@code 0} sequentially. This is used\n * in translating an instruction whose register requirements cannot\n * be met using a straightforward choice of a single opcode.\n */\npublic final class HighRegisterPrefix extends VariableSizeInsn {\n    /** {@code null-ok;} cached instructions, if constructed */\n    private SimpleInsn[] insns;\n\n    /**\n     * Constructs an instance. The output address of this instance is initially\n     * unknown ({@code -1}).\n     *\n     * @param position {@code non-null;} source position\n     * @param registers {@code non-null;} source registers\n     */\n    public HighRegisterPrefix(SourcePosition position,\n                              RegisterSpecList registers) {\n        super(position, registers);\n\n        if (registers.size() == 0) {\n            throw new IllegalArgumentException(\"registers.size() == 0\");\n        }\n\n        insns = null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        int result = 0;\n\n        calculateInsnsIfNecessary();\n\n        for (SimpleInsn insn : insns) {\n            result += insn.codeSize();\n        }\n\n        return result;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out) {\n        calculateInsnsIfNecessary();\n\n        for (SimpleInsn insn : insns) {\n            insn.writeTo(out);\n        }\n    }\n\n    /**\n     * Helper for {@link #codeSize} and {@link #writeTo} which sets up\n     * {@link #insns} if not already done.\n     */\n    private void calculateInsnsIfNecessary() {\n        if (insns != null) {\n            return;\n        }\n\n        RegisterSpecList registers = getRegisters();\n        int sz = registers.size();\n\n        insns = new SimpleInsn[sz];\n\n        for (int i = 0, outAt = 0; i < sz; i++) {\n          RegisterSpec src = registers.get(i);\n          insns[i] = moveInsnFor(src, outAt);\n          outAt += src.getCategory();\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withRegisters(RegisterSpecList registers) {\n        return new HighRegisterPrefix(getPosition(), registers);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String argString() {\n        return null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String listingString0(boolean noteIndices) {\n        RegisterSpecList registers = getRegisters();\n        int sz = registers.size();\n        StringBuffer sb = new StringBuffer(100);\n\n        for (int i = 0, outAt = 0; i < sz; i++) {\n            RegisterSpec src = registers.get(i);\n            SimpleInsn insn = moveInsnFor(src, outAt);\n\n            if (i != 0) {\n                sb.append('\\n');\n            }\n\n            sb.append(insn.listingString0(noteIndices));\n\n            outAt += src.getCategory();\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Returns the proper move instruction for the given source spec\n     * and destination index.\n     *\n     * @param src {@code non-null;} the source register spec\n     * @param destIndex {@code >= 0;} the destination register index\n     * @return {@code non-null;} the appropriate move instruction\n     */\n    private static SimpleInsn moveInsnFor(RegisterSpec src, int destIndex) {\n        return DalvInsn.makeMove(SourcePosition.NO_INFO,\n                RegisterSpec.make(destIndex, src.getType()),\n                src);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/InsnFormat.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.cst.CstKnownNull;\nimport com.taobao.android.dx.rop.cst.CstLiteral64;\nimport com.taobao.android.dx.rop.cst.CstLiteralBits;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.BitSet;\n\n/**\n * Base class for all instruction format handlers. Instruction format\n * handlers know how to translate {@link DalvInsn} instances into\n * streams of code units, as well as human-oriented listing strings\n * representing such translations.\n */\npublic abstract class InsnFormat {\n    /**\n     * flag to enable/disable the new extended opcode formats; meant as a\n     * temporary measure until VM support for the salient opcodes is\n     * added. TODO: Remove this declaration when the VM can deal.\n     */\n    public static boolean ALLOW_EXTENDED_OPCODES = true;\n\n    /**\n     * Returns the string form, suitable for inclusion in a listing\n     * dump, of the given instruction. The instruction must be of this\n     * instance's format for proper operation.\n     *\n     * @param insn {@code non-null;} the instruction\n     * @param noteIndices whether to include an explicit notation of\n     * constant pool indices\n     * @return {@code non-null;} the string form\n     */\n    public final String listingString(DalvInsn insn, boolean noteIndices) {\n        String op = insn.getOpcode().getName();\n        String arg = insnArgString(insn);\n        String comment = insnCommentString(insn, noteIndices);\n        StringBuilder sb = new StringBuilder(100);\n\n        sb.append(op);\n\n        if (arg.length() != 0) {\n            sb.append(' ');\n            sb.append(arg);\n        }\n\n        if (comment.length() != 0) {\n            sb.append(\" // \");\n            sb.append(comment);\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Returns the string form of the arguments to the given instruction.\n     * The instruction must be of this instance's format. If the instruction\n     * has no arguments, then the result should be {@code \"\"}, not\n     * {@code null}.\n     *\n     * <p>Subclasses must override this method.</p>\n     *\n     * @param insn {@code non-null;} the instruction\n     * @return {@code non-null;} the string form\n     */\n    public abstract String insnArgString(DalvInsn insn);\n\n    /**\n     * Returns the associated comment for the given instruction, if any.\n     * The instruction must be of this instance's format. If the instruction\n     * has no comment, then the result should be {@code \"\"}, not\n     * {@code null}.\n     *\n     * <p>Subclasses must override this method.</p>\n     *\n     * @param insn {@code non-null;} the instruction\n     * @param noteIndices whether to include an explicit notation of\n     * constant pool indices\n     * @return {@code non-null;} the string form\n     */\n    public abstract String insnCommentString(DalvInsn insn,\n            boolean noteIndices);\n\n    /**\n     * Gets the code size of instructions that use this format. The\n     * size is a number of 16-bit code units, not bytes. This should\n     * throw an exception if this format is of variable size.\n     *\n     * @return {@code >= 0;} the instruction length in 16-bit code units\n     */\n    public abstract int codeSize();\n\n    /**\n     * Returns whether or not the given instruction's arguments will\n     * fit in this instance's format. This includes such things as\n     * counting register arguments, checking register ranges, and\n     * making sure that additional arguments are of appropriate types\n     * and are in-range. If this format has a branch target but the\n     * instruction's branch offset is unknown, this method will simply\n     * not check the offset.\n     *\n     * <p>Subclasses must override this method.</p>\n     *\n     * @param insn {@code non-null;} the instruction to check\n     * @return {@code true} iff the instruction's arguments are\n     * appropriate for this instance, or {@code false} if not\n     */\n    public abstract boolean isCompatible(DalvInsn insn);\n\n    /**\n     * Returns which of a given instruction's registers will fit in\n     * this instance's format.\n     *\n     * <p>The default implementation of this method always returns\n     * an empty BitSet. Subclasses must override this method if they\n     * have registers.</p>\n     *\n     * @param insn {@code non-null;} the instruction to check\n     * @return {@code non-null;} a BitSet flagging registers in the\n     * register list that are compatible to this format\n     */\n    public BitSet compatibleRegs(DalvInsn insn) {\n        return new BitSet();\n    }\n\n    /**\n     * Returns whether or not the given instruction's branch offset will\n     * fit in this instance's format. This always returns {@code false}\n     * for formats that don't include a branch offset.\n     *\n     * <p>The default implementation of this method always returns\n     * {@code false}. Subclasses must override this method if they\n     * include branch offsets.</p>\n     *\n     * @param insn {@code non-null;} the instruction to check\n     * @return {@code true} iff the instruction's branch offset is\n     * appropriate for this instance, or {@code false} if not\n     */\n    public boolean branchFits(TargetInsn insn) {\n        return false;\n    }\n\n    /**\n     * Writes the code units for the given instruction to the given\n     * output destination. The instruction must be of this instance's format.\n     *\n     * <p>Subclasses must override this method.</p>\n     *\n     * @param out {@code non-null;} the output destination to write to\n     * @param insn {@code non-null;} the instruction to write\n     */\n    public abstract void writeTo(AnnotatedOutput out, DalvInsn insn);\n\n    /**\n     * Helper method to return a register list string.\n     *\n     * @param list {@code non-null;} the list of registers\n     * @return {@code non-null;} the string form\n     */\n    protected static String regListString(RegisterSpecList list) {\n        int sz = list.size();\n        StringBuffer sb = new StringBuffer(sz * 5 + 2);\n\n        sb.append('{');\n\n        for (int i = 0; i < sz; i++) {\n            if (i != 0) {\n                sb.append(\", \");\n            }\n            sb.append(list.get(i).regString());\n        }\n\n        sb.append('}');\n\n        return sb.toString();\n    }\n\n    /**\n     * Helper method to return a register range string.\n     *\n     * @param list {@code non-null;} the list of registers (which must be\n     * sequential)\n     * @return {@code non-null;} the string form\n     */\n    protected static String regRangeString(RegisterSpecList list) {\n        int size = list.size();\n        StringBuilder sb = new StringBuilder(30);\n\n        sb.append(\"{\");\n\n        switch (size) {\n            case 0: {\n                // Nothing to do.\n                break;\n            }\n            case 1: {\n                sb.append(list.get(0).regString());\n                break;\n            }\n            default: {\n                RegisterSpec lastReg = list.get(size - 1);\n                if (lastReg.getCategory() == 2) {\n                    /*\n                     * Add one to properly represent a list-final\n                     * category-2 register.\n                     */\n                    lastReg = lastReg.withOffset(1);\n                }\n\n                sb.append(list.get(0).regString());\n                sb.append(\"..\");\n                sb.append(lastReg.regString());\n            }\n        }\n\n        sb.append(\"}\");\n\n        return sb.toString();\n    }\n\n    /**\n     * Helper method to return a literal bits argument string.\n     *\n     * @param value the value\n     * @return {@code non-null;} the string form\n     */\n    protected static String literalBitsString(CstLiteralBits value) {\n        StringBuffer sb = new StringBuffer(100);\n\n        sb.append('#');\n\n        if (value instanceof CstKnownNull) {\n            sb.append(\"null\");\n        } else {\n            sb.append(value.typeName());\n            sb.append(' ');\n            sb.append(value.toHuman());\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Helper method to return a literal bits comment string.\n     *\n     * @param value the value\n     * @param width the width of the constant, in bits (used for displaying\n     * the uninterpreted bits; one of: {@code 4 8 16 32 64}\n     * @return {@code non-null;} the comment\n     */\n    protected static String literalBitsComment(CstLiteralBits value,\n            int width) {\n        StringBuffer sb = new StringBuffer(20);\n\n        sb.append(\"#\");\n\n        long bits;\n\n        if (value instanceof CstLiteral64) {\n            bits = ((CstLiteral64) value).getLongBits();\n        } else {\n            bits = value.getIntBits();\n        }\n\n        switch (width) {\n            case 4:  sb.append(Hex.uNibble((int) bits)); break;\n            case 8:  sb.append(Hex.u1((int) bits));      break;\n            case 16: sb.append(Hex.u2((int) bits));      break;\n            case 32: sb.append(Hex.u4((int) bits));      break;\n            case 64: sb.append(Hex.u8(bits));            break;\n            default: {\n                throw new RuntimeException(\"shouldn't happen\");\n            }\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Helper method to return a branch address string.\n     *\n     * @param insn {@code non-null;} the instruction in question\n     * @return {@code non-null;} the string form of the instruction's\n     * branch target\n     */\n    protected static String branchString(DalvInsn insn) {\n        TargetInsn ti = (TargetInsn) insn;\n        int address = ti.getTargetAddress();\n\n        return (address == (char) address) ? Hex.u2(address) : Hex.u4(address);\n    }\n\n    /**\n     * Helper method to return the comment for a branch.\n     *\n     * @param insn {@code non-null;} the instruction in question\n     * @return {@code non-null;} the comment\n     */\n    protected static String branchComment(DalvInsn insn) {\n        TargetInsn ti = (TargetInsn) insn;\n        int offset = ti.getTargetOffset();\n\n        return (offset == (short) offset) ? Hex.s2(offset) : Hex.s4(offset);\n    }\n\n    /**\n     * Helper method to return the constant string for a {@link CstInsn}\n     * in human form.\n     *\n     * @param insn {@code non-null;} a constant-bearing instruction\n     * @return {@code non-null;} the human string form of the contained\n     * constant\n     */\n    protected static String cstString(DalvInsn insn) {\n        CstInsn ci = (CstInsn) insn;\n        Constant cst = ci.getConstant();\n\n        return cst instanceof CstString ? ((CstString) cst).toQuoted() : cst.toHuman();\n    }\n\n    /**\n     * Helper method to return an instruction comment for a constant.\n     *\n     * @param insn {@code non-null;} a constant-bearing instruction\n     * @return {@code non-null;} comment string representing the constant\n     */\n    protected static String cstComment(DalvInsn insn) {\n        CstInsn ci = (CstInsn) insn;\n\n        if (! ci.hasIndex()) {\n            return \"\";\n        }\n\n        StringBuilder sb = new StringBuilder(20);\n        int index = ci.getIndex();\n\n        sb.append(ci.getConstant().typeName());\n        sb.append('@');\n\n        if (index < 65536) {\n            sb.append(Hex.u2(index));\n        } else {\n            sb.append(Hex.u4(index));\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Helper method to determine if a signed int value fits in a nibble.\n     *\n     * @param value the value in question\n     * @return {@code true} iff it's in the range -8..+7\n     */\n    protected static boolean signedFitsInNibble(int value) {\n        return (value >= -8) && (value <= 7);\n    }\n\n    /**\n     * Helper method to determine if an unsigned int value fits in a nibble.\n     *\n     * @param value the value in question\n     * @return {@code true} iff it's in the range 0..0xf\n     */\n    protected static boolean unsignedFitsInNibble(int value) {\n        return value == (value & 0xf);\n    }\n\n    /**\n     * Helper method to determine if a signed int value fits in a byte.\n     *\n     * @param value the value in question\n     * @return {@code true} iff it's in the range -0x80..+0x7f\n     */\n    protected static boolean signedFitsInByte(int value) {\n        return (byte) value == value;\n    }\n\n    /**\n     * Helper method to determine if an unsigned int value fits in a byte.\n     *\n     * @param value the value in question\n     * @return {@code true} iff it's in the range 0..0xff\n     */\n    protected static boolean unsignedFitsInByte(int value) {\n        return value == (value & 0xff);\n    }\n\n    /**\n     * Helper method to determine if a signed int value fits in a short.\n     *\n     * @param value the value in question\n     * @return {@code true} iff it's in the range -0x8000..+0x7fff\n     */\n    protected static boolean signedFitsInShort(int value) {\n        return (short) value == value;\n    }\n\n    /**\n     * Helper method to determine if an unsigned int value fits in a short.\n     *\n     * @param value the value in question\n     * @return {@code true} iff it's in the range 0..0xffff\n     */\n    protected static boolean unsignedFitsInShort(int value) {\n        return value == (value & 0xffff);\n    }\n\n    /**\n     * Helper method to determine if a list of registers are sequential,\n     * including degenerate cases for empty or single-element lists.\n     *\n     * @param list {@code non-null;} the list of registers\n     * @return {@code true} iff the list is sequentially ordered\n     */\n    protected static boolean isRegListSequential(RegisterSpecList list) {\n        int sz = list.size();\n\n        if (sz < 2) {\n            return true;\n        }\n\n        int first = list.get(0).getReg();\n        int next = first;\n\n        for (int i = 0; i < sz; i++) {\n            RegisterSpec one = list.get(i);\n            if (one.getReg() != next) {\n                return false;\n            }\n            next += one.getCategory();\n        }\n\n        return true;\n    }\n\n    /**\n     * Helper method to extract the callout-argument index from an\n     * appropriate instruction.\n     *\n     * @param insn {@code non-null;} the instruction\n     * @return {@code >= 0;} the callout argument index\n     */\n    protected static int argIndex(DalvInsn insn) {\n        int arg = ((CstInteger) ((CstInsn) insn).getConstant()).getValue();\n\n        if (arg < 0) {\n            throw new IllegalArgumentException(\"bogus insn\");\n        }\n\n        return arg;\n    }\n\n    /**\n     * Helper method to combine an opcode and a second byte of data into\n     * the appropriate form for emitting into a code buffer.\n     *\n     * @param insn {@code non-null;} the instruction containing the opcode\n     * @param arg {@code 0..255;} arbitrary other byte value\n     * @return combined value\n     */\n    protected static short opcodeUnit(DalvInsn insn, int arg) {\n        if ((arg & 0xff) != arg) {\n            throw new IllegalArgumentException(\"arg out of range 0..255\");\n        }\n\n        int opcode = insn.getOpcode().getOpcode();\n\n        if ((opcode & 0xff) != opcode) {\n            throw new IllegalArgumentException(\"opcode out of range 0..255\");\n        }\n\n        return (short) (opcode | (arg << 8));\n    }\n\n    /**\n     * Helper method to get an extended (16-bit) opcode out of an\n     * instruction, returning it as a code unit. The opcode\n     * <i>must</i> be an extended opcode.\n     *\n     * @param insn {@code non-null;} the instruction containing the\n     * extended opcode\n     * @return the opcode as a code unit\n     */\n    protected static short opcodeUnit(DalvInsn insn) {\n        int opcode = insn.getOpcode().getOpcode();\n\n        if ((opcode < 0x100) || (opcode > 0xffff)) {\n            throw new IllegalArgumentException(\"opcode out of range 0..65535\");\n        }\n\n        return (short) opcode;\n    }\n\n    /**\n     * Helper method to combine two bytes into a code unit.\n     *\n     * @param low {@code 0..255;} low byte\n     * @param high {@code 0..255;} high byte\n     * @return combined value\n     */\n    protected static short codeUnit(int low, int high) {\n        if ((low & 0xff) != low) {\n            throw new IllegalArgumentException(\"low out of range 0..255\");\n        }\n\n        if ((high & 0xff) != high) {\n            throw new IllegalArgumentException(\"high out of range 0..255\");\n        }\n\n        return (short) (low | (high << 8));\n    }\n\n    /**\n     * Helper method to combine four nibbles into a code unit.\n     *\n     * @param n0 {@code 0..15;} low nibble\n     * @param n1 {@code 0..15;} medium-low nibble\n     * @param n2 {@code 0..15;} medium-high nibble\n     * @param n3 {@code 0..15;} high nibble\n     * @return combined value\n     */\n    protected static short codeUnit(int n0, int n1, int n2, int n3) {\n        if ((n0 & 0xf) != n0) {\n            throw new IllegalArgumentException(\"n0 out of range 0..15\");\n        }\n\n        if ((n1 & 0xf) != n1) {\n            throw new IllegalArgumentException(\"n1 out of range 0..15\");\n        }\n\n        if ((n2 & 0xf) != n2) {\n            throw new IllegalArgumentException(\"n2 out of range 0..15\");\n        }\n\n        if ((n3 & 0xf) != n3) {\n            throw new IllegalArgumentException(\"n3 out of range 0..15\");\n        }\n\n        return (short) (n0 | (n1 << 4) | (n2 << 8) | (n3 << 12));\n    }\n\n    /**\n     * Helper method to combine two nibbles into a byte.\n     *\n     * @param low {@code 0..15;} low nibble\n     * @param high {@code 0..15;} high nibble\n     * @return {@code 0..255;} combined value\n     */\n    protected static int makeByte(int low, int high) {\n        if ((low & 0xf) != low) {\n            throw new IllegalArgumentException(\"low out of range 0..15\");\n        }\n\n        if ((high & 0xf) != high) {\n            throw new IllegalArgumentException(\"high out of range 0..15\");\n        }\n\n        return low | (high << 4);\n    }\n\n    /**\n     * Writes one code unit to the given output destination.\n     *\n     * @param out {@code non-null;} where to write to\n     * @param c0 code unit to write\n     */\n    protected static void write(AnnotatedOutput out, short c0) {\n        out.writeShort(c0);\n    }\n\n    /**\n     * Writes two code units to the given output destination.\n     *\n     * @param out {@code non-null;} where to write to\n     * @param c0 code unit to write\n     * @param c1 code unit to write\n     */\n    protected static void write(AnnotatedOutput out, short c0, short c1) {\n        out.writeShort(c0);\n        out.writeShort(c1);\n    }\n\n    /**\n     * Writes three code units to the given output destination.\n     *\n     * @param out {@code non-null;} where to write to\n     * @param c0 code unit to write\n     * @param c1 code unit to write\n     * @param c2 code unit to write\n     */\n    protected static void write(AnnotatedOutput out, short c0, short c1,\n            short c2) {\n        out.writeShort(c0);\n        out.writeShort(c1);\n        out.writeShort(c2);\n    }\n\n    /**\n     * Writes four code units to the given output destination.\n     *\n     * @param out {@code non-null;} where to write to\n     * @param c0 code unit to write\n     * @param c1 code unit to write\n     * @param c2 code unit to write\n     * @param c3 code unit to write\n     */\n    protected static void write(AnnotatedOutput out, short c0, short c1,\n            short c2, short c3) {\n        out.writeShort(c0);\n        out.writeShort(c1);\n        out.writeShort(c2);\n        out.writeShort(c3);\n    }\n\n    /**\n     * Writes five code units to the given output destination.\n     *\n     * @param out {@code non-null;} where to write to\n     * @param c0 code unit to write\n     * @param c1 code unit to write\n     * @param c2 code unit to write\n     * @param c3 code unit to write\n     * @param c4 code unit to write\n     */\n    protected static void write(AnnotatedOutput out, short c0, short c1,\n            short c2, short c3, short c4) {\n        out.writeShort(c0);\n        out.writeShort(c1);\n        out.writeShort(c2);\n        out.writeShort(c3);\n        out.writeShort(c4);\n    }\n\n    /**\n     * Writes three code units to the given output destination, where the\n     * second and third are represented as single <code>int</code> and emitted\n     * in little-endian order.\n     *\n     * @param out {@code non-null;} where to write to\n     * @param c0 code unit to write\n     * @param c1c2 code unit pair to write\n     */\n    protected static void write(AnnotatedOutput out, short c0, int c1c2) {\n        write(out, c0, (short) c1c2, (short) (c1c2 >> 16));\n    }\n\n    /**\n     * Writes four code units to the given output destination, where the\n     * second and third are represented as single <code>int</code> and emitted\n     * in little-endian order.\n     *\n     * @param out {@code non-null;} where to write to\n     * @param c0 code unit to write\n     * @param c1c2 code unit pair to write\n     * @param c3 code unit to write\n     */\n    protected static void write(AnnotatedOutput out, short c0, int c1c2,\n            short c3) {\n        write(out, c0, (short) c1c2, (short) (c1c2 >> 16), c3);\n    }\n\n    /**\n     * Writes five code units to the given output destination, where the\n     * second and third are represented as single <code>int</code> and emitted\n     * in little-endian order.\n     *\n     * @param out {@code non-null;} where to write to\n     * @param c0 code unit to write\n     * @param c1c2 code unit pair to write\n     * @param c3 code unit to write\n     * @param c4 code unit to write\n     */\n    protected static void write(AnnotatedOutput out, short c0, int c1c2,\n            short c3, short c4) {\n        write(out, c0, (short) c1c2, (short) (c1c2 >> 16), c3, c4);\n    }\n\n    /**\n     * Writes five code units to the given output destination, where the\n     * second through fifth are represented as single <code>long</code>\n     * and emitted in little-endian order.\n     *\n     * @param out {@code non-null;} where to write to\n     * @param c0 code unit to write\n     * @param c1c2c3c4 code unit quad to write\n     */\n    protected static void write(AnnotatedOutput out, short c0, long c1c2c3c4) {\n        write(out, c0, (short) c1c2c3c4, (short) (c1c2c3c4 >> 16),\n                (short) (c1c2c3c4 >> 32), (short) (c1c2c3c4 >> 48));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/LocalList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecSet;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.FixedSizeList;\nimport java.io.PrintStream;\nimport java.util.ArrayList;\nimport java.util.Arrays;\n\n/**\n * List of local variables. Each local variable entry indicates a\n * range of code which it is valid for, a register number, a name,\n * and a type.\n */\npublic final class LocalList extends FixedSizeList {\n    /** {@code non-null;} empty instance */\n    public static final LocalList EMPTY = new LocalList(0);\n\n    /** whether to run the self-check code */\n    private static final boolean DEBUG = false;\n\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size {@code >= 0;} the size of the list\n     */\n    public LocalList(int size) {\n        super(size);\n    }\n\n    /**\n     * Gets the element at the given index. It is an error to call\n     * this with the index for an element which was never set; if you\n     * do that, this will throw {@code NullPointerException}.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @return {@code non-null;} element at that index\n     */\n    public Entry get(int n) {\n        return (Entry) get0(n);\n    }\n\n    /**\n     * Sets the entry at the given index.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @param entry {@code non-null;} the entry to set at {@code n}\n     */\n    public void set(int n, Entry entry) {\n        set0(n, entry);\n    }\n\n    /**\n     * Does a human-friendly dump of this instance.\n     *\n     * @param out {@code non-null;} where to dump\n     * @param prefix {@code non-null;} prefix to attach to each line of output\n     */\n    public void debugPrint(PrintStream out, String prefix) {\n        int sz = size();\n\n        for (int i = 0; i < sz; i++) {\n            out.print(prefix);\n            out.println(get(i));\n        }\n    }\n\n    /**\n     * Disposition of a local entry.\n     */\n    public static enum Disposition {\n        /** local started (introduced) */\n        START,\n\n        /** local ended without being replaced */\n        END_SIMPLY,\n\n        /** local ended because it was directly replaced */\n        END_REPLACED,\n\n        /** local ended because it was moved to a different register */\n        END_MOVED,\n\n        /**\n         * local ended because the previous local clobbered this one\n         * (because it is category-2)\n         */\n        END_CLOBBERED_BY_PREV,\n\n        /**\n         * local ended because the next local clobbered this one\n         * (because this one is a category-2)\n         */\n        END_CLOBBERED_BY_NEXT;\n    }\n\n    /**\n     * Entry in a local list.\n     */\n    public static class Entry implements Comparable<Entry> {\n        /** {@code >= 0;} address */\n        private final int address;\n\n        /** {@code non-null;} disposition of the local */\n        private final Disposition disposition;\n\n        /** {@code non-null;} register spec representing the variable */\n        private final RegisterSpec spec;\n\n        /** {@code non-null;} variable type (derived from {@code spec}) */\n        private final CstType type;\n\n        /**\n         * Constructs an instance.\n         *\n         * @param address {@code >= 0;} address\n         * @param disposition {@code non-null;} disposition of the local\n         * @param spec {@code non-null;} register spec representing\n         * the variable\n         */\n        public Entry(int address, Disposition disposition, RegisterSpec spec) {\n            if (address < 0) {\n                throw new IllegalArgumentException(\"address < 0\");\n            }\n\n            if (disposition == null) {\n                throw new NullPointerException(\"disposition == null\");\n            }\n\n            try {\n                if (spec.getLocalItem() == null) {\n                    throw new NullPointerException(\n                            \"spec.getLocalItem() == null\");\n                }\n            } catch (NullPointerException ex) {\n                // Elucidate the exception.\n                throw new NullPointerException(\"spec == null\");\n            }\n\n            this.address = address;\n            this.disposition = disposition;\n            this.spec = spec;\n            this.type = CstType.intern(spec.getType());\n        }\n\n        /** {@inheritDoc} */\n        public String toString() {\n            return Integer.toHexString(address) + \" \" + disposition + \" \" +\n                spec;\n        }\n\n        /** {@inheritDoc} */\n        public boolean equals(Object other) {\n            if (!(other instanceof Entry)) {\n                return false;\n            }\n\n            return (compareTo((Entry) other) == 0);\n        }\n\n        /**\n         * Compares by (in priority order) address, end then start\n         * disposition (variants of end are all consistered\n         * equivalent), and spec.\n         *\n         * @param other {@code non-null;} entry to compare to\n         * @return {@code -1..1;} standard result of comparison\n         */\n        public int compareTo(Entry other) {\n            if (address < other.address) {\n                return -1;\n            } else if (address > other.address) {\n                return 1;\n            }\n\n            boolean thisIsStart = isStart();\n            boolean otherIsStart = other.isStart();\n\n            if (thisIsStart != otherIsStart) {\n                return thisIsStart ? 1 : -1;\n            }\n\n            return spec.compareTo(other.spec);\n        }\n\n        /**\n         * Gets the address.\n         *\n         * @return {@code >= 0;} the address\n         */\n        public int getAddress() {\n            return address;\n        }\n\n        /**\n         * Gets the disposition.\n         *\n         * @return {@code non-null;} the disposition\n         */\n        public Disposition getDisposition() {\n            return disposition;\n        }\n\n        /**\n         * Gets whether this is a local start. This is just shorthand for\n         * {@code getDisposition() == Disposition.START}.\n         *\n         * @return {@code true} iff this is a start\n         */\n        public boolean isStart() {\n            return disposition == Disposition.START;\n        }\n\n        /**\n         * Gets the variable name.\n         *\n         * @return {@code null-ok;} the variable name\n         */\n        public CstString getName() {\n            return spec.getLocalItem().getName();\n        }\n\n        /**\n         * Gets the variable signature.\n         *\n         * @return {@code null-ok;} the variable signature\n         */\n        public CstString getSignature() {\n            return spec.getLocalItem().getSignature();\n        }\n\n        /**\n         * Gets the variable's type.\n         *\n         * @return {@code non-null;} the type\n         */\n        public CstType getType() {\n            return type;\n        }\n\n        /**\n         * Gets the number of the register holding the variable.\n         *\n         * @return {@code >= 0;} the number of the register holding\n         * the variable\n         */\n        public int getRegister() {\n            return spec.getReg();\n        }\n\n        /**\n         * Gets the RegisterSpec of the register holding the variable.\n         *\n         * @return {@code non-null;} RegisterSpec of the holding register.\n         */\n        public RegisterSpec getRegisterSpec() {\n            return spec;\n        }\n\n        /**\n         * Returns whether or not this instance matches the given spec.\n         *\n         * @param otherSpec {@code non-null;} the spec in question\n         * @return {@code true} iff this instance matches\n         * {@code spec}\n         */\n        public boolean matches(RegisterSpec otherSpec) {\n            return spec.equalsUsingSimpleType(otherSpec);\n        }\n\n        /**\n         * Returns whether or not this instance matches the spec in\n         * the given instance.\n         *\n         * @param other {@code non-null;} another entry\n         * @return {@code true} iff this instance's spec matches\n         * {@code other}\n         */\n        public boolean matches(Entry other) {\n            return matches(other.spec);\n        }\n\n        /**\n         * Returns an instance just like this one but with the disposition\n         * set as given.\n         *\n         * @param disposition {@code non-null;} the new disposition\n         * @return {@code non-null;} an appropriately-constructed instance\n         */\n        public Entry withDisposition(Disposition disposition) {\n            if (disposition == this.disposition) {\n                return this;\n            }\n\n            return new Entry(address, disposition, spec);\n        }\n    }\n\n    /**\n     * Constructs an instance for the given method, based on the given\n     * block order and intermediate local information.\n     *\n     * @param insns {@code non-null;} instructions to convert\n     * @return {@code non-null;} the constructed list\n     */\n    public static LocalList make(DalvInsnList insns) {\n        int sz = insns.size();\n\n        /*\n         * Go through the insn list, looking for all the local\n         * variable pseudoinstructions, splitting out LocalSnapshots\n         * into separate per-variable starts, adding explicit ends\n         * wherever a variable is replaced or moved, and collecting\n         * these and all the other local variable \"activity\"\n         * together into an output list (without the other insns).\n         *\n         * Note: As of this writing, this method won't be handed any\n         * insn lists that contain local ends, but I (danfuzz) expect\n         * that to change at some point, when we start feeding that\n         * info explicitly into the rop layer rather than only trying\n         * to infer it. So, given that expectation, this code is\n         * written to deal with them.\n         */\n\n        MakeState state = new MakeState(sz);\n\n        for (int i = 0; i < sz; i++) {\n            DalvInsn insn = insns.get(i);\n\n            if (insn instanceof LocalSnapshot) {\n                RegisterSpecSet snapshot =\n                    ((LocalSnapshot) insn).getLocals();\n                state.snapshot(insn.getAddress(), snapshot);\n            } else if (insn instanceof LocalStart) {\n                RegisterSpec local = ((LocalStart) insn).getLocal();\n                state.startLocal(insn.getAddress(), local);\n            }\n        }\n\n        LocalList result = state.finish();\n\n        if (DEBUG) {\n            debugVerify(result);\n        }\n\n        return result;\n    }\n\n    /**\n     * Debugging helper that verifies the constraint that a list doesn't\n     * contain any redundant local starts and that local ends that are\n     * due to replacements are properly annotated.\n     */\n    private static void debugVerify(LocalList locals) {\n        try {\n            debugVerify0(locals);\n        } catch (RuntimeException ex) {\n            int sz = locals.size();\n            for (int i = 0; i < sz; i++) {\n                System.err.println(locals.get(i));\n            }\n            throw ex;\n        }\n\n    }\n\n    /**\n     * Helper for {@link #debugVerify} which does most of the work.\n     */\n    private static void debugVerify0(LocalList locals) {\n        int sz = locals.size();\n        Entry[] active = new Entry[65536];\n\n        for (int i = 0; i < sz; i++) {\n            Entry e = locals.get(i);\n            int reg = e.getRegister();\n\n            if (e.isStart()) {\n                Entry already = active[reg];\n\n                if ((already != null) && e.matches(already)) {\n                    throw new RuntimeException(\"redundant start at \" +\n                            Integer.toHexString(e.getAddress()) + \": got \" +\n                            e + \"; had \" + already);\n                }\n\n                active[reg] = e;\n            } else {\n                if (active[reg] == null) {\n                    throw new RuntimeException(\"redundant end at \" +\n                            Integer.toHexString(e.getAddress()));\n                }\n\n                int addr = e.getAddress();\n                boolean foundStart = false;\n\n                for (int j = i + 1; j < sz; j++) {\n                    Entry test = locals.get(j);\n                    if (test.getAddress() != addr) {\n                        break;\n                    }\n                    if (test.getRegisterSpec().getReg() == reg) {\n                        if (test.isStart()) {\n                            if (e.getDisposition()\n                                    != Disposition.END_REPLACED) {\n                                throw new RuntimeException(\n                                        \"improperly marked end at \" +\n                                        Integer.toHexString(addr));\n                            }\n                            foundStart = true;\n                        } else {\n                            throw new RuntimeException(\n                                    \"redundant end at \" +\n                                    Integer.toHexString(addr));\n                        }\n                    }\n                }\n\n                if (!foundStart &&\n                        (e.getDisposition() == Disposition.END_REPLACED)) {\n                    throw new RuntimeException(\n                            \"improper end replacement claim at \" +\n                            Integer.toHexString(addr));\n                }\n\n                active[reg] = null;\n            }\n        }\n    }\n\n    /**\n     * Intermediate state when constructing a local list.\n     */\n    public static class MakeState {\n        /** {@code non-null;} result being collected */\n        private final ArrayList<Entry> result;\n\n        /**\n         * {@code >= 0;} running count of nulled result entries, to help with\n         * sizing the final list\n         */\n        private int nullResultCount;\n\n        /** {@code null-ok;} current register mappings */\n        private RegisterSpecSet regs;\n\n        /** {@code null-ok;} result indices where local ends are stored */\n        private int[] endIndices;\n\n        /** {@code >= 0;} last address seen */\n        private int lastAddress;\n\n        /**\n         * Constructs an instance.\n         */\n        public MakeState(int initialSize) {\n            result = new ArrayList<Entry>(initialSize);\n            nullResultCount = 0;\n            regs = null;\n            endIndices = null;\n            lastAddress = 0;\n        }\n\n        /**\n         * Checks the address and other vitals as a prerequisite to\n         * further processing.\n         *\n         * @param address {@code >= 0;} address about to be processed\n         * @param reg {@code >= 0;} register number about to be processed\n         */\n        private void aboutToProcess(int address, int reg) {\n            boolean first = (endIndices == null);\n\n            if ((address == lastAddress) && !first) {\n                return;\n            }\n\n            if (address < lastAddress) {\n                throw new RuntimeException(\"shouldn't happen\");\n            }\n\n            if (first || (reg >= endIndices.length)) {\n                /*\n                 * This is the first allocation of the state set and\n                 * index array, or we need to grow. (The latter doesn't\n                 * happen much; in fact, we have only ever observed\n                 * it happening in test cases, never in \"real\" code.)\n                 */\n                int newSz = reg + 1;\n                RegisterSpecSet newRegs = new RegisterSpecSet(newSz);\n                int[] newEnds = new int[newSz];\n                Arrays.fill(newEnds, -1);\n\n                if (!first) {\n                    newRegs.putAll(regs);\n                    System.arraycopy(endIndices, 0, newEnds, 0,\n                            endIndices.length);\n                }\n\n                regs = newRegs;\n                endIndices = newEnds;\n            }\n        }\n\n        /**\n         * Sets the local state at the given address to the given snapshot.\n         * The first call on this instance must be to this method, so that\n         * the register state can be properly sized.\n         *\n         * @param address {@code >= 0;} the address\n         * @param specs {@code non-null;} spec set representing the locals\n         */\n        public void snapshot(int address, RegisterSpecSet specs) {\n            if (DEBUG) {\n                System.err.printf(\"%04x snapshot %s\\n\", address, specs);\n            }\n\n            int sz = specs.getMaxSize();\n            aboutToProcess(address, sz - 1);\n\n            for (int i = 0; i < sz; i++) {\n                RegisterSpec oldSpec = regs.get(i);\n                RegisterSpec newSpec = filterSpec(specs.get(i));\n\n                if (oldSpec == null) {\n                    if (newSpec != null) {\n                        startLocal(address, newSpec);\n                    }\n                } else if (newSpec == null) {\n                    endLocal(address, oldSpec);\n                } else if (! newSpec.equalsUsingSimpleType(oldSpec)) {\n                    endLocal(address, oldSpec);\n                    startLocal(address, newSpec);\n                }\n            }\n\n            if (DEBUG) {\n                System.err.printf(\"%04x snapshot done\\n\", address);\n            }\n        }\n\n        /**\n         * Starts a local at the given address.\n         *\n         * @param address {@code >= 0;} the address\n         * @param startedLocal {@code non-null;} spec representing the\n         * started local\n         */\n        public void startLocal(int address, RegisterSpec startedLocal) {\n            if (DEBUG) {\n                System.err.printf(\"%04x start %s\\n\", address, startedLocal);\n            }\n\n            int regNum = startedLocal.getReg();\n\n            startedLocal = filterSpec(startedLocal);\n            aboutToProcess(address, regNum);\n\n            RegisterSpec existingLocal = regs.get(regNum);\n\n            if (startedLocal.equalsUsingSimpleType(existingLocal)) {\n                // Silently ignore a redundant start.\n                return;\n            }\n\n            RegisterSpec movedLocal = regs.findMatchingLocal(startedLocal);\n            if (movedLocal != null) {\n                /*\n                 * The same variable was moved from one register to another.\n                 * So add an end for its old location.\n                 */\n                addOrUpdateEnd(address, Disposition.END_MOVED, movedLocal);\n            }\n\n            int endAt = endIndices[regNum];\n\n            if (existingLocal != null) {\n                /*\n                 * There is an existing (but non-matching) local.\n                 * Add an explicit end for it.\n                 */\n                add(address, Disposition.END_REPLACED, existingLocal);\n            } else if (endAt >= 0) {\n                /*\n                 * Look for an end local for the same register at the\n                 * same address. If found, then update it or delete\n                 * it, depending on whether or not it represents the\n                 * same variable as the one being started.\n                 */\n                Entry endEntry = result.get(endAt);\n                if (endEntry.getAddress() == address) {\n                    if (endEntry.matches(startedLocal)) {\n                        /*\n                         * There was already an end local for the same\n                         * variable at the same address. This turns\n                         * out to be superfluous, as we are starting\n                         * up the exact same local. This situation can\n                         * happen when a single local variable got\n                         * somehow \"split up\" during intermediate\n                         * processing. In any case, rather than represent\n                         * the end-then-start, just remove the old end.\n                         */\n                        result.set(endAt, null);\n                        nullResultCount++;\n                        regs.put(startedLocal);\n                        endIndices[regNum] = -1;\n                        return;\n                    } else {\n                        /*\n                         * There was a different variable ended at the\n                         * same address. Update it to indicate that\n                         * it was ended due to a replacement (rather than\n                         * ending for no particular reason).\n                         */\n                        endEntry = endEntry.withDisposition(\n                                Disposition.END_REPLACED);\n                        result.set(endAt, endEntry);\n                    }\n                }\n            }\n\n            /*\n             * The code above didn't find and remove an unnecessary\n             * local end, so we now have to add one or more entries to\n             * the output to capture the transition.\n             */\n\n            /*\n             * If the local just below (in the register set at reg-1)\n             * is of category-2, then it is ended by this new start.\n             */\n            if (regNum > 0) {\n                RegisterSpec justBelow = regs.get(regNum - 1);\n                if ((justBelow != null) && justBelow.isCategory2()) {\n                    addOrUpdateEnd(address,\n                            Disposition.END_CLOBBERED_BY_NEXT,\n                            justBelow);\n                }\n            }\n\n            /*\n             * Similarly, if this local is category-2, then the local\n             * just above (if any) is ended by the start now being\n             * emitted.\n             */\n            if (startedLocal.isCategory2()) {\n                RegisterSpec justAbove = regs.get(regNum + 1);\n                if (justAbove != null) {\n                    addOrUpdateEnd(address,\n                            Disposition.END_CLOBBERED_BY_PREV,\n                            justAbove);\n                }\n            }\n\n            /*\n             * TODO: Add an end for the same local in a different reg,\n             * if any (that is, if the local migrates from vX to vY,\n             * we should note that as a local end in vX).\n             */\n\n            add(address, Disposition.START, startedLocal);\n        }\n\n        /**\n         * Ends a local at the given address, using the disposition\n         * {@code END_SIMPLY}.\n         *\n         * @param address {@code >= 0;} the address\n         * @param endedLocal {@code non-null;} spec representing the\n         * local being ended\n         */\n        public void endLocal(int address, RegisterSpec endedLocal) {\n            endLocal(address, endedLocal, Disposition.END_SIMPLY);\n        }\n\n        /**\n         * Ends a local at the given address.\n         *\n         * @param address {@code >= 0;} the address\n         * @param endedLocal {@code non-null;} spec representing the\n         * local being ended\n         * @param disposition reason for the end\n         */\n        public void endLocal(int address, RegisterSpec endedLocal,\n                Disposition disposition) {\n            if (DEBUG) {\n                System.err.printf(\"%04x end %s\\n\", address, endedLocal);\n            }\n\n            int regNum = endedLocal.getReg();\n\n            endedLocal = filterSpec(endedLocal);\n            aboutToProcess(address, regNum);\n\n            int endAt = endIndices[regNum];\n\n            if (endAt >= 0) {\n                /*\n                 * The local in the given register is already ended.\n                 * Silently return without adding anything to the result.\n                 */\n                return;\n            }\n\n            // Check for start and end at the same address.\n            if (checkForEmptyRange(address, endedLocal)) {\n                return;\n            }\n\n            add(address, disposition, endedLocal);\n        }\n\n        /**\n         * Helper for {@link #endLocal}, which handles the cases where\n         * and end local is issued at the same address as a start local\n         * for the same register. If this case is found, then this\n         * method will remove the start (as the local was never actually\n         * active), update the {@link #endIndices} to be accurate, and\n         * if needed update the newly-active end to reflect an altered\n         * disposition.\n         *\n         * @param address {@code >= 0;} the address\n         * @param endedLocal {@code non-null;} spec representing the\n         * local being ended\n         * @return {@code true} iff this method found the case in question\n         * and adjusted things accordingly\n         */\n        private boolean checkForEmptyRange(int address,\n                RegisterSpec endedLocal) {\n            int at = result.size() - 1;\n            Entry entry;\n\n            // Look for a previous entry at the same address.\n            for (/*at*/; at >= 0; at--) {\n                entry = result.get(at);\n\n                if (entry == null) {\n                    continue;\n                }\n\n                if (entry.getAddress() != address) {\n                    // We didn't find any match at the same address.\n                    return false;\n                }\n\n                if (entry.matches(endedLocal)) {\n                    break;\n                }\n            }\n\n            /*\n             * In fact, we found that the endedLocal had started at the\n             * same address, so do all the requisite cleanup.\n             */\n\n            regs.remove(endedLocal);\n            result.set(at, null);\n            nullResultCount++;\n\n            int regNum = endedLocal.getReg();\n            boolean found = false;\n            entry = null;\n\n            // Now look back further to update where the register ended.\n            for (at--; at >= 0; at--) {\n                entry = result.get(at);\n\n                if (entry == null) {\n                    continue;\n                }\n\n                if (entry.getRegisterSpec().getReg() == regNum) {\n                    found = true;\n                    break;\n                }\n            }\n\n            if (found) {\n                // We found an end for the same register.\n                endIndices[regNum] = at;\n\n                if (entry.getAddress() == address) {\n                    /*\n                     * It's still the same address, so update the\n                     * disposition.\n                     */\n                    result.set(at,\n                            entry.withDisposition(Disposition.END_SIMPLY));\n                }\n            }\n\n            return true;\n        }\n\n        /**\n         * Converts a given spec into the form acceptable for use in a\n         * local list. This, in particular, transforms the \"known\n         * null\" type into simply {@code Object}. This method needs to\n         * be called for any spec that is on its way into a locals\n         * list.\n         *\n         * <p>This isn't necessarily the cleanest way to achieve the\n         * goal of not representing known nulls in a locals list, but\n         * it gets the job done.</p>\n         *\n         * @param orig {@code null-ok;} the original spec\n         * @return {@code null-ok;} an appropriately modified spec, or the\n         * original if nothing needs to be done\n         */\n        private static RegisterSpec filterSpec(RegisterSpec orig) {\n            if ((orig != null) && (orig.getType() == Type.KNOWN_NULL)) {\n                return orig.withType(Type.OBJECT);\n            }\n\n            return orig;\n        }\n\n        /**\n         * Adds an entry to the result, updating the adjunct tables\n         * accordingly.\n         *\n         * @param address {@code >= 0;} the address\n         * @param disposition {@code non-null;} the disposition\n         * @param spec {@code non-null;} spec representing the local\n         */\n        private void add(int address, Disposition disposition,\n                RegisterSpec spec) {\n            int regNum = spec.getReg();\n\n            result.add(new Entry(address, disposition, spec));\n\n            if (disposition == Disposition.START) {\n                regs.put(spec);\n                endIndices[regNum] = -1;\n            } else {\n                regs.remove(spec);\n                endIndices[regNum] = result.size() - 1;\n            }\n        }\n\n        /**\n         * Adds or updates an end local (changing its disposition). If\n         * this would cause an empty range for a local, this instead\n         * removes the local entirely.\n         *\n         * @param address {@code >= 0;} the address\n         * @param disposition {@code non-null;} the disposition\n         * @param spec {@code non-null;} spec representing the local\n         */\n        private void addOrUpdateEnd(int address, Disposition disposition,\n                RegisterSpec spec) {\n            if (disposition == Disposition.START) {\n                throw new RuntimeException(\"shouldn't happen\");\n            }\n\n            int regNum = spec.getReg();\n            int endAt = endIndices[regNum];\n\n            if (endAt >= 0) {\n                // There is a previous end.\n                Entry endEntry = result.get(endAt);\n                if ((endEntry.getAddress() == address) &&\n                        endEntry.getRegisterSpec().equals(spec)) {\n                    /*\n                     * The end is for the right address and variable, so\n                     * update it.\n                     */\n                    result.set(endAt, endEntry.withDisposition(disposition));\n                    regs.remove(spec); // TODO: Is this line superfluous?\n                    return;\n                }\n            }\n\n            endLocal(address, spec, disposition);\n        }\n\n        /**\n         * Finishes processing altogether and gets the result.\n         *\n         * @return {@code non-null;} the result list\n         */\n        public LocalList finish() {\n            aboutToProcess(Integer.MAX_VALUE, 0);\n\n            int resultSz = result.size();\n            int finalSz = resultSz - nullResultCount;\n\n            if (finalSz == 0) {\n                return EMPTY;\n            }\n\n            /*\n             * Collect an array of only the non-null entries, and then\n             * sort it to get a consistent order for everything: Local\n             * ends and starts for a given address could come in any\n             * order, but we want ends before starts as well as\n             * registers in order (within ends or starts).\n             */\n\n            Entry[] resultArr = new Entry[finalSz];\n\n            if (resultSz == finalSz) {\n                result.toArray(resultArr);\n            } else {\n                int at = 0;\n                for (Entry e : result) {\n                    if (e != null) {\n                        resultArr[at++] = e;\n                    }\n                }\n            }\n\n            Arrays.sort(resultArr);\n\n            LocalList resultList = new LocalList(finalSz);\n\n            for (int i = 0; i < finalSz; i++) {\n                resultList.set(i, resultArr[i]);\n            }\n\n            resultList.setImmutable();\n            return resultList;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/LocalSnapshot.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.RegisterSpecSet;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.ssa.RegisterMapper;\n\n/**\n * Pseudo-instruction which is used to hold a snapshot of the\n * state of local variable name mappings that exists immediately after\n * the instance in an instruction array.\n */\npublic final class LocalSnapshot extends ZeroSizeInsn {\n    /** {@code non-null;} local state associated with this instance */\n    private final RegisterSpecSet locals;\n\n    /**\n     * Constructs an instance. The output address of this instance is initially\n     * unknown ({@code -1}).\n     *\n     * @param position {@code non-null;} source position\n     * @param locals {@code non-null;} associated local variable state\n     */\n    public LocalSnapshot(SourcePosition position, RegisterSpecSet locals) {\n        super(position);\n\n        if (locals == null) {\n            throw new NullPointerException(\"locals == null\");\n        }\n\n        this.locals = locals;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withRegisterOffset(int delta) {\n        return new LocalSnapshot(getPosition(), locals.withOffset(delta));\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withRegisters(RegisterSpecList registers) {\n        return new LocalSnapshot(getPosition(), locals);\n    }\n\n    /**\n     * Gets the local state associated with this instance.\n     *\n     * @return {@code non-null;} the state\n     */\n    public RegisterSpecSet getLocals() {\n        return locals;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String argString() {\n        return locals.toString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String listingString0(boolean noteIndices) {\n        int sz = locals.size();\n        int max = locals.getMaxSize();\n        StringBuffer sb = new StringBuffer(100 + sz * 40);\n\n        sb.append(\"local-snapshot\");\n\n        for (int i = 0; i < max; i++) {\n            RegisterSpec spec = locals.get(i);\n            if (spec != null) {\n                sb.append(\"\\n  \");\n                sb.append(LocalStart.localString(spec));\n            }\n        }\n\n        return sb.toString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withMapper(RegisterMapper mapper) {\n      return new LocalSnapshot(getPosition(), mapper.map(locals));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/LocalStart.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.ssa.RegisterMapper;\n\n/**\n * Pseudo-instruction which is used to introduce a new local variable. That\n * is, an instance of this class in an instruction stream indicates that\n * starting with the subsequent instruction, the indicated variable\n * is bound.\n */\npublic final class LocalStart extends ZeroSizeInsn {\n    /**\n     * {@code non-null;} register spec representing the local variable introduced\n     * by this instance\n     */\n    private final RegisterSpec local;\n\n    /**\n     * Returns the local variable listing string for a single register spec.\n     *\n     * @param spec {@code non-null;} the spec to convert\n     * @return {@code non-null;} the string form\n     */\n    public static String localString(RegisterSpec spec) {\n        return spec.regString() + ' ' + spec.getLocalItem().toString() + \": \" +\n            spec.getTypeBearer().toHuman();\n    }\n\n    /**\n     * Constructs an instance. The output address of this instance is initially\n     * unknown ({@code -1}).\n     *\n     * @param position {@code non-null;} source position\n     * @param local {@code non-null;} register spec representing the local\n     * variable introduced by this instance\n     */\n    public LocalStart(SourcePosition position, RegisterSpec local) {\n        super(position);\n\n        if (local == null) {\n            throw new NullPointerException(\"local == null\");\n        }\n\n        this.local = local;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withRegisterOffset(int delta) {\n        return new LocalStart(getPosition(), local.withOffset(delta));\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withRegisters(RegisterSpecList registers) {\n        return new LocalStart(getPosition(), local);\n    }\n\n    /**\n     * Gets the register spec representing the local variable introduced\n     * by this instance.\n     *\n     * @return {@code non-null;} the register spec\n     */\n    public RegisterSpec getLocal() {\n        return local;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String argString() {\n        return local.toString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String listingString0(boolean noteIndices) {\n        return \"local-start \" + localString(local);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withMapper(RegisterMapper mapper) {\n      return new LocalStart(getPosition(), mapper.map(local));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/OddSpacer.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.io.Opcodes;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.util.AnnotatedOutput;\n\n/**\n * Pseudo-instruction which either turns into a {@code nop} or\n * nothingness, in order to make the subsequent instruction have an\n * even address. This is used to align (subsequent) instructions that\n * require it.\n */\npublic final class OddSpacer extends VariableSizeInsn {\n    /**\n     * Constructs an instance. The output address of this instance is initially\n     * unknown ({@code -1}).\n     *\n     * @param position {@code non-null;} source position\n     */\n    public OddSpacer(SourcePosition position) {\n        super(position, RegisterSpecList.EMPTY);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return (getAddress() & 1);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out) {\n        if (codeSize() != 0) {\n            out.writeShort(InsnFormat.codeUnit(Opcodes.NOP, 0));\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withRegisters(RegisterSpecList registers) {\n        return new OddSpacer(getPosition());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String argString() {\n        return null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String listingString0(boolean noteIndices) {\n        if (codeSize() == 0) {\n            return null;\n        }\n\n        return \"nop // spacer\";\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/OutputCollector.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.dex.DexOptions;\nimport java.util.ArrayList;\n\n/**\n * Destination for {@link DalvInsn} instances being output. This class\n * receives and collects instructions in two pieces &mdash; a primary\n * list and a suffix (generally consisting of adjunct data referred to\n * by the primary list, such as switch case tables) &mdash; which it\n * merges and emits back out in the form of a {@link DalvInsnList}\n * instance.\n */\npublic final class OutputCollector {\n    /**\n     * {@code non-null;} the associated finisher (which holds the instruction\n     * list in-progress)\n     */\n    private final OutputFinisher finisher;\n\n    /**\n     * {@code null-ok;} suffix for the output, or {@code null} if the suffix\n     * has been appended to the main output (by {@link #appendSuffixToOutput})\n     */\n    private ArrayList<DalvInsn> suffix;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param dexOptions {@code non-null;} options for dex output\n     * @param initialCapacity {@code >= 0;} initial capacity of the output list\n     * @param suffixInitialCapacity {@code >= 0;} initial capacity of the output\n     * suffix\n     * @param regCount {@code >= 0;} register count for the method\n     * @param paramSize size, in register units, of all the parameters for this method\n     */\n    public OutputCollector(DexOptions dexOptions, int initialCapacity, int suffixInitialCapacity,\n            int regCount, int paramSize) {\n        this.finisher = new OutputFinisher(dexOptions, initialCapacity, regCount, paramSize);\n        this.suffix = new ArrayList<DalvInsn>(suffixInitialCapacity);\n    }\n\n    /**\n     * Adds an instruction to the output.\n     *\n     * @param insn {@code non-null;} the instruction to add\n     */\n    public void add(DalvInsn insn) {\n        finisher.add(insn);\n    }\n\n    /**\n     * Reverses a branch which is buried a given number of instructions\n     * backward in the output. It is illegal to call this unless the\n     * indicated instruction really is a reversible branch.\n     *\n     * @param which how many instructions back to find the branch;\n     * {@code 0} is the most recently added instruction,\n     * {@code 1} is the instruction before that, etc.\n     * @param newTarget {@code non-null;} the new target for the reversed branch\n     */\n    public void reverseBranch(int which, CodeAddress newTarget) {\n        finisher.reverseBranch(which, newTarget);\n    }\n\n    /**\n     * Adds an instruction to the output suffix.\n     *\n     * @param insn {@code non-null;} the instruction to add\n     */\n    public void addSuffix(DalvInsn insn) {\n        suffix.add(insn);\n    }\n\n    /**\n     * Gets the results of all the calls on this instance, in the form of\n     * an {@link OutputFinisher}.\n     *\n     * @return {@code non-null;} the output finisher\n     * @throws UnsupportedOperationException if this method has\n     * already been called\n     */\n    public OutputFinisher getFinisher() {\n        if (suffix == null) {\n            throw new UnsupportedOperationException(\"already processed\");\n        }\n\n        appendSuffixToOutput();\n        return finisher;\n    }\n\n    /**\n     * Helper for {@link #getFinisher}, which appends the suffix to\n     * the primary output.\n     */\n    private void appendSuffixToOutput() {\n        int size = suffix.size();\n\n        for (int i = 0; i < size; i++) {\n            finisher.add(suffix.get(i));\n        }\n\n        suffix = null;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/OutputFinisher.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.dex.DexOptions;\nimport com.taobao.android.dx.io.Opcodes;\nimport com.taobao.android.dx.rop.code.LocalItem;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.RegisterSpecSet;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstMemberRef;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.ssa.BasicRegisterMapper;\n\nimport com.taobao.android.dex.DexException;\nimport java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.HashSet;\n\n/**\n * Processor for instruction lists, which takes a \"first cut\" of\n * instruction selection as a basis and produces a \"final cut\" in the\n * form of a {@link DalvInsnList} instance.\n */\npublic final class OutputFinisher {\n    /** {@code non-null;} options for dex output */\n    private final DexOptions dexOptions;\n\n    /**\n     * {@code >= 0;} register count for the method, not including any extra\n     * \"reserved\" registers needed to translate \"difficult\" instructions\n     */\n    private final int unreservedRegCount;\n\n    /** {@code non-null;} the list of instructions, per se */\n    private ArrayList<DalvInsn> insns;\n\n    /** whether any instruction has position info */\n    private boolean hasAnyPositionInfo;\n\n    /** whether any instruction has local variable info */\n    private boolean hasAnyLocalInfo;\n\n    /**\n     * {@code >= 0;} the count of reserved registers (low-numbered\n     * registers used when expanding instructions that can't be\n     * represented simply); becomes valid after a call to {@link\n     * #massageInstructions}\n     */\n    private int reservedCount;\n\n    /**\n     * {@code >= 0;} the count of reserved registers just before parameters in order to align them.\n     */\n    private int reservedParameterCount;\n\n    /**\n     * Size, in register units, of all the parameters to this method\n     */\n    private final int paramSize;\n\n    /**\n     * Constructs an instance. It initially contains no instructions.\n     *\n     * @param dexOptions {@code non-null;} options for dex output\n     * @param initialCapacity {@code >= 0;} initial capacity of the\n     * instructions list\n     * @param regCount {@code >= 0;} register count for the method\n     * @param paramSize size, in register units, of all the parameters for this method\n     */\n    public OutputFinisher(DexOptions dexOptions, int initialCapacity, int regCount, int paramSize) {\n        this.dexOptions = dexOptions;\n        this.unreservedRegCount = regCount;\n        this.insns = new ArrayList<DalvInsn>(initialCapacity);\n        this.reservedCount = -1;\n        this.hasAnyPositionInfo = false;\n        this.hasAnyLocalInfo = false;\n        this.paramSize = paramSize;\n    }\n\n    /**\n     * Returns whether any of the instructions added to this instance\n     * come with position info.\n     *\n     * @return whether any of the instructions added to this instance\n     * come with position info\n     */\n    public boolean hasAnyPositionInfo() {\n        return hasAnyPositionInfo;\n    }\n\n    /**\n     * Returns whether this instance has any local variable information.\n     *\n     * @return whether this instance has any local variable information\n     */\n    public boolean hasAnyLocalInfo() {\n        return hasAnyLocalInfo;\n    }\n\n    /**\n     * Helper for {@link #add} which scrutinizes a single\n     * instruction for local variable information.\n     *\n     * @param insn {@code non-null;} instruction to scrutinize\n     * @return {@code true} iff the instruction refers to any\n     * named locals\n     */\n    private static boolean hasLocalInfo(DalvInsn insn) {\n        if (insn instanceof LocalSnapshot) {\n            RegisterSpecSet specs = ((LocalSnapshot) insn).getLocals();\n            int size = specs.size();\n            for (int i = 0; i < size; i++) {\n                if (hasLocalInfo(specs.get(i))) {\n                    return true;\n                }\n            }\n        } else if (insn instanceof LocalStart) {\n            RegisterSpec spec = ((LocalStart) insn).getLocal();\n            if (hasLocalInfo(spec)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Helper for {@link #hasAnyLocalInfo} which scrutinizes a single\n     * register spec.\n     *\n     * @param spec {@code non-null;} spec to scrutinize\n     * @return {@code true} iff the spec refers to any\n     * named locals\n     */\n    private static boolean hasLocalInfo(RegisterSpec spec) {\n        return (spec != null)\n            && (spec.getLocalItem().getName() != null);\n    }\n\n    /**\n     * Returns the set of all constants referred to by instructions added\n     * to this instance.\n     *\n     * @return {@code non-null;} the set of constants\n     */\n    public HashSet<Constant> getAllConstants() {\n        HashSet<Constant> result = new HashSet<Constant>(20);\n\n        for (DalvInsn insn : insns) {\n            addConstants(result, insn);\n        }\n\n        return result;\n    }\n\n    /**\n     * Helper for {@link #getAllConstants} which adds all the info for\n     * a single instruction.\n     *\n     * @param result {@code non-null;} result set to add to\n     * @param insn {@code non-null;} instruction to scrutinize\n     */\n    private static void addConstants(HashSet<Constant> result,\n            DalvInsn insn) {\n        if (insn instanceof CstInsn) {\n            Constant cst = ((CstInsn) insn).getConstant();\n            result.add(cst);\n        } else if (insn instanceof LocalSnapshot) {\n            RegisterSpecSet specs = ((LocalSnapshot) insn).getLocals();\n            int size = specs.size();\n            for (int i = 0; i < size; i++) {\n                addConstants(result, specs.get(i));\n            }\n        } else if (insn instanceof LocalStart) {\n            RegisterSpec spec = ((LocalStart) insn).getLocal();\n            addConstants(result, spec);\n        }\n    }\n\n    /**\n     * Helper for {@link #getAllConstants} which adds all the info for\n     * a single {@code RegisterSpec}.\n     *\n     * @param result {@code non-null;} result set to add to\n     * @param spec {@code null-ok;} register spec to add\n     */\n    private static void addConstants(HashSet<Constant> result,\n            RegisterSpec spec) {\n        if (spec == null) {\n            return;\n        }\n\n        LocalItem local = spec.getLocalItem();\n        CstString name = local.getName();\n        CstString signature = local.getSignature();\n        Type type = spec.getType();\n\n        if (type != Type.KNOWN_NULL) {\n            result.add(CstType.intern(type));\n        }\n\n        if (name != null) {\n            result.add(name);\n        }\n\n        if (signature != null) {\n            result.add(signature);\n        }\n    }\n\n    /**\n     * Adds an instruction to the output.\n     *\n     * @param insn {@code non-null;} the instruction to add\n     */\n    public void add(DalvInsn insn) {\n        insns.add(insn);\n        updateInfo(insn);\n    }\n\n    /**\n     * Inserts an instruction in the output at the given offset.\n     *\n     * @param at {@code >= 0;} what index to insert at\n     * @param insn {@code non-null;} the instruction to insert\n     */\n    public void insert(int at, DalvInsn insn) {\n        insns.add(at, insn);\n        updateInfo(insn);\n    }\n\n    /**\n     * Helper for {@link #add} and {@link #insert},\n     * which updates the position and local info flags.\n     *\n     * @param insn {@code non-null;} an instruction that was just introduced\n     */\n    private void updateInfo(DalvInsn insn) {\n        if (! hasAnyPositionInfo) {\n            SourcePosition pos = insn.getPosition();\n            if (pos.getLine() >= 0) {\n                hasAnyPositionInfo = true;\n            }\n        }\n\n        if (! hasAnyLocalInfo) {\n            if (hasLocalInfo(insn)) {\n                hasAnyLocalInfo = true;\n            }\n        }\n    }\n\n    /**\n     * Reverses a branch which is buried a given number of instructions\n     * backward in the output. It is illegal to call this unless the\n     * indicated instruction really is a reversible branch.\n     *\n     * @param which how many instructions back to find the branch;\n     * {@code 0} is the most recently added instruction,\n     * {@code 1} is the instruction before that, etc.\n     * @param newTarget {@code non-null;} the new target for the\n     * reversed branch\n     */\n    public void reverseBranch(int which, CodeAddress newTarget) {\n        int size = insns.size();\n        int index = size - which - 1;\n        TargetInsn targetInsn;\n\n        try {\n            targetInsn = (TargetInsn) insns.get(index);\n        } catch (IndexOutOfBoundsException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"too few instructions\");\n        } catch (ClassCastException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"non-reversible instruction\");\n        }\n\n        /*\n         * No need to call this.set(), since the format and other info\n         * are the same.\n         */\n        insns.set(index, targetInsn.withNewTargetAndReversed(newTarget));\n    }\n\n    /**\n     * Assigns indices in all instructions that need them, using the\n     * given callback to perform lookups. This should be called before\n     * calling {@link #finishProcessingAndGetList}.\n     *\n     * @param callback {@code non-null;} callback object\n     */\n    public void assignIndices(DalvCode.AssignIndicesCallback callback) {\n        for (DalvInsn insn : insns) {\n            if (insn instanceof CstInsn) {\n                assignIndices((CstInsn) insn, callback);\n            }\n        }\n    }\n\n    /**\n     * Helper for {@link #assignIndices} which does assignment for one\n     * instruction.\n     *\n     * @param insn {@code non-null;} the instruction\n     * @param callback {@code non-null;} the callback\n     */\n    private static void assignIndices(CstInsn insn,\n            DalvCode.AssignIndicesCallback callback) {\n        Constant cst = insn.getConstant();\n        int index = callback.getIndex(cst);\n\n        if (index >= 0) {\n            insn.setIndex(index);\n        }\n\n        if (cst instanceof CstMemberRef) {\n            CstMemberRef member = (CstMemberRef) cst;\n            CstType definer = member.getDefiningClass();\n            index = callback.getIndex(definer);\n            if (index >= 0) {\n                insn.setClassIndex(index);\n            }\n        }\n    }\n\n    /**\n     * Does final processing on this instance and gets the output as\n     * a {@link DalvInsnList}. Final processing consists of:\n     *\n     * <ul>\n     *   <li>optionally renumbering registers (to make room as needed for\n     *   expanded instructions)</li>\n     *   <li>picking a final opcode for each instruction</li>\n     *   <li>rewriting instructions, because of register number,\n     *   constant pool index, or branch target size issues</li>\n     *   <li>assigning final addresses</li>\n     * </ul>\n     *\n     * <p><b>Note:</b> This method may only be called once per instance\n     * of this class.</p>\n     *\n     * @return {@code non-null;} the output list\n     * @throws UnsupportedOperationException if this method has\n     * already been called\n     */\n    public DalvInsnList finishProcessingAndGetList() {\n        if (reservedCount >= 0) {\n            throw new UnsupportedOperationException(\"already processed\");\n        }\n\n        Dop[] opcodes = makeOpcodesArray();\n        reserveRegisters(opcodes);\n        if (dexOptions.ALIGN_64BIT_REGS_IN_OUTPUT_FINISHER) {\n          align64bits(opcodes);\n        }\n        massageInstructions(opcodes);\n        assignAddressesAndFixBranches();\n\n        return DalvInsnList.makeImmutable(insns, reservedCount + unreservedRegCount\n            + reservedParameterCount);\n    }\n\n    /**\n     * Helper for {@link #finishProcessingAndGetList}, which extracts\n     * the opcode out of each instruction into a separate array, to be\n     * further manipulated as things progress.\n     *\n     * @return {@code non-null;} the array of opcodes\n     */\n    private Dop[] makeOpcodesArray() {\n        int size = insns.size();\n        Dop[] result = new Dop[size];\n\n        for (int i = 0; i < size; i++) {\n            result[i] = insns.get(i).getOpcode();\n        }\n\n        return result;\n    }\n\n    /**\n     * Helper for {@link #finishProcessingAndGetList}, which figures\n     * out how many reserved registers are required and then reserving\n     * them. It also updates the given {@code opcodes} array so\n     * as to avoid extra work when constructing the massaged\n     * instruction list.\n     *\n     * @param opcodes {@code non-null;} array of per-instruction\n     * opcode selections\n     * @return true if reservedCount is expanded, false otherwise\n     */\n    private boolean reserveRegisters(Dop[] opcodes) {\n        boolean reservedCountExpanded = false;\n        int oldReservedCount = (reservedCount < 0) ? 0 : reservedCount;\n\n        /*\n         * Call calculateReservedCount() and then perform register\n         * reservation, repeatedly until no new reservations happen.\n         */\n        for (;;) {\n            int newReservedCount = calculateReservedCount(opcodes);\n            if (oldReservedCount >= newReservedCount) {\n                break;\n            }\n\n            reservedCountExpanded = true;\n\n            int reservedDifference = newReservedCount - oldReservedCount;\n            int size = insns.size();\n\n            for (int i = 0; i < size; i++) {\n                /*\n                 * CodeAddress instance identity is used to link\n                 * TargetInsns to their targets, so it is\n                 * inappropriate to make replacements, and they don't\n                 * have registers in any case. Hence, the instanceof\n                 * test below.\n                 */\n                DalvInsn insn = insns.get(i);\n                if (!(insn instanceof CodeAddress)) {\n                    /*\n                     * No need to call this.set() since the format and\n                     * other info are the same.\n                     */\n                    insns.set(i, insn.withRegisterOffset(reservedDifference));\n                }\n            }\n\n            oldReservedCount = newReservedCount;\n        }\n\n        reservedCount = oldReservedCount;\n\n        return reservedCountExpanded;\n    }\n\n    /**\n     * Helper for {@link #reserveRegisters}, which does one\n     * pass over the instructions, calculating the number of\n     * registers that need to be reserved. It also updates the\n     * {@code opcodes} list to help avoid extra work in future\n     * register reservation passes.\n     *\n     * @param opcodes {@code non-null;} array of per-instruction\n     * opcode selections\n     * @return {@code >= 0;} the count of reserved registers\n     */\n    private int calculateReservedCount(Dop[] opcodes) {\n        int size = insns.size();\n\n        /*\n         * Potential new value of reservedCount, which gets updated in the\n         * following loop. It starts out with the existing reservedCount\n         * and gets increased if it turns out that additional registers\n         * need to be reserved.\n         */\n        int newReservedCount = reservedCount;\n\n        for (int i = 0; i < size; i++) {\n            DalvInsn insn = insns.get(i);\n            Dop originalOpcode = opcodes[i];\n            Dop newOpcode = findOpcodeForInsn(insn, originalOpcode);\n\n            if (newOpcode == null) {\n                /*\n                 * The instruction will need to be expanded, so find the\n                 * expanded opcode and reserve registers for it.\n                 */\n                Dop expandedOp = findExpandedOpcodeForInsn(insn);\n                BitSet compatRegs = expandedOp.getFormat().compatibleRegs(insn);\n                int reserve = insn.getMinimumRegisterRequirement(compatRegs);\n                if (reserve > newReservedCount) {\n                    newReservedCount = reserve;\n                }\n            } else if (originalOpcode == newOpcode) {\n                continue;\n            }\n\n            opcodes[i] = newOpcode;\n        }\n\n        return newReservedCount;\n    }\n\n    /**\n     * Attempts to fit the given instruction into a specific opcode,\n     * returning the opcode whose format that the instruction fits\n     * into or {@code null} to indicate that the instruction will need\n     * to be expanded. This fitting process starts with the given\n     * opcode as a first \"best guess\" and then pessimizes from there\n     * if necessary.\n     *\n     * @param insn {@code non-null;} the instruction in question\n     * @param guess {@code null-ok;} the current guess as to the best\n     * opcode; {@code null} means that no simple opcode fits\n     * @return {@code null-ok;} a possibly-different opcode; either a\n     * {@code non-null} good fit or {@code null} to indicate that no\n     * simple opcode fits\n     */\n    private Dop findOpcodeForInsn(DalvInsn insn, Dop guess) {\n        /*\n         * Note: The initial guess might be null, meaning that an\n         * earlier call to this method already determined that there\n         * was no possible simple opcode fit.\n         */\n\n        while (guess != null) {\n            if (guess.getFormat().isCompatible(insn)) {\n                /*\n                 * Don't break out for const_string to generate jumbo version\n                 * when option is enabled.\n                 */\n                if (!dexOptions.forceJumbo ||\n                    guess.getOpcode() != Opcodes.CONST_STRING) {\n                    break;\n                }\n            }\n\n            guess = Dops.getNextOrNull(guess, dexOptions);\n        }\n\n        return guess;\n    }\n\n    /**\n     * Finds the proper opcode for the given instruction, ignoring\n     * register constraints.\n     *\n     * @param insn {@code non-null;} the instruction in question\n     * @return {@code non-null;} the opcode that fits\n     */\n    private Dop findExpandedOpcodeForInsn(DalvInsn insn) {\n        Dop result = findOpcodeForInsn(insn.getLowRegVersion(), insn.getOpcode());\n        if (result == null) {\n            throw new DexException(\"No expanded opcode for \" + insn);\n        }\n        return result;\n    }\n\n    /**\n     * Helper for {@link #finishProcessingAndGetList}, which goes\n     * through each instruction in the output, making sure its opcode\n     * can accomodate its arguments. In cases where the opcode is\n     * unable to do so, this replaces the instruction with a larger\n     * instruction with identical semantics that <i>will</i> work.\n     *\n     * <p>This method may also reserve a number of low-numbered\n     * registers, renumbering the instructions' original registers, in\n     * order to have register space available in which to move\n     * very-high registers when expanding instructions into\n     * multi-instruction sequences. This expansion is done when no\n     * simple instruction format can be found for a given instruction that\n     * is able to accomodate that instruction's registers.</p>\n     *\n     * <p>This method ignores issues of branch target size, since\n     * final addresses aren't known at the point that this method is\n     * called.</p>\n     *\n     * @param opcodes {@code non-null;} array of per-instruction\n     * opcode selections\n     */\n    private void massageInstructions(Dop[] opcodes) {\n        if (reservedCount == 0) {\n            /*\n             * The easy common case: No registers were reserved, so we\n             * merely need to replace any instructions whose format\n             * (and hence whose opcode) changed during the reservation\n             * pass, but all instructions will stay at their original\n             * indices, and the instruction list doesn't grow.\n             */\n            int size = insns.size();\n\n            for (int i = 0; i < size; i++) {\n                DalvInsn insn = insns.get(i);\n                Dop originalOpcode = insn.getOpcode();\n                Dop currentOpcode = opcodes[i];\n\n                if (originalOpcode != currentOpcode) {\n                    insns.set(i, insn.withOpcode(currentOpcode));\n                }\n            }\n        } else {\n            /*\n             * The difficult uncommon case: Some instructions have to be\n             * expanded to deal with high registers.\n             */\n            insns = performExpansion(opcodes);\n        }\n    }\n\n    /**\n     * Helper for {@link #massageInstructions}, which constructs a\n     * replacement list, where each {link DalvInsn} instance that\n     * couldn't be represented simply (due to register representation\n     * problems) is expanded into a series of instances that together\n     * perform the proper function.\n     *\n     * @param opcodes {@code non-null;} array of per-instruction\n     * opcode selections\n     * @return {@code non-null;} the replacement list\n     */\n    private ArrayList<DalvInsn> performExpansion(Dop[] opcodes) {\n        int size = insns.size();\n        ArrayList<DalvInsn> result = new ArrayList<DalvInsn>(size * 2);\n\n        ArrayList<CodeAddress> closelyBoundAddresses = new ArrayList<CodeAddress>();\n\n        for (int i = 0; i < size; i++) {\n            DalvInsn insn = insns.get(i);\n            Dop originalOpcode = insn.getOpcode();\n            Dop currentOpcode = opcodes[i];\n            DalvInsn prefix;\n            DalvInsn suffix;\n\n            if (currentOpcode != null) {\n                // No expansion is necessary.\n                prefix = null;\n                suffix = null;\n            } else {\n                // Expansion is required.\n                currentOpcode = findExpandedOpcodeForInsn(insn);\n                BitSet compatRegs =\n                    currentOpcode.getFormat().compatibleRegs(insn);\n                prefix = insn.expandedPrefix(compatRegs);\n                suffix = insn.expandedSuffix(compatRegs);\n\n                // Expand necessary registers to fit the new format\n                insn = insn.expandedVersion(compatRegs);\n            }\n\n            if (insn instanceof CodeAddress) {\n                // If we have a closely bound address, don't add it yet,\n                // because we need to add it after the prefix for the\n                // instruction it is bound to.\n                if (((CodeAddress) insn).getBindsClosely()) {\n                    closelyBoundAddresses.add((CodeAddress)insn);\n                    continue;\n                }\n            }\n\n            if (prefix != null) {\n                result.add(prefix);\n            }\n\n            // Add any pending closely bound addresses\n            if (!(insn instanceof ZeroSizeInsn) && closelyBoundAddresses.size() > 0) {\n                for (CodeAddress codeAddress: closelyBoundAddresses) {\n                    result.add(codeAddress);\n                }\n                closelyBoundAddresses.clear();\n            }\n\n            if (currentOpcode != originalOpcode) {\n                insn = insn.withOpcode(currentOpcode);\n            }\n            result.add(insn);\n\n            if (suffix != null) {\n                result.add(suffix);\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * Helper for {@link #finishProcessingAndGetList}, which assigns\n     * addresses to each instruction, possibly rewriting branches to\n     * fix ones that wouldn't otherwise be able to reach their\n     * targets.\n     */\n    private void assignAddressesAndFixBranches() {\n        for (;;) {\n            assignAddresses();\n            if (!fixBranches()) {\n                break;\n            }\n        }\n    }\n\n    /**\n     * Helper for {@link #assignAddressesAndFixBranches}, which\n     * assigns an address to each instruction, in order.\n     */\n    private void assignAddresses() {\n        int address = 0;\n        int size = insns.size();\n\n        for (int i = 0; i < size; i++) {\n            DalvInsn insn = insns.get(i);\n            insn.setAddress(address);\n            address += insn.codeSize();\n        }\n    }\n\n    /**\n     * Helper for {@link #assignAddressesAndFixBranches}, which checks\n     * the branch target size requirement of each branch instruction\n     * to make sure it fits. For instructions that don't fit, this\n     * rewrites them to use a {@code goto} of some sort. In the\n     * case of a conditional branch that doesn't fit, the sense of the\n     * test is reversed in order to branch around a {@code goto}\n     * to the original target.\n     *\n     * @return whether any branches had to be fixed\n     */\n    private boolean fixBranches() {\n        int size = insns.size();\n        boolean anyFixed = false;\n\n        for (int i = 0; i < size; i++) {\n            DalvInsn insn = insns.get(i);\n            if (!(insn instanceof TargetInsn)) {\n                // This loop only needs to inspect TargetInsns.\n                continue;\n            }\n\n            Dop opcode = insn.getOpcode();\n            TargetInsn target = (TargetInsn) insn;\n\n            if (opcode.getFormat().branchFits(target)) {\n                continue;\n            }\n\n            if (opcode.getFamily() == Opcodes.GOTO) {\n                // It is a goto; widen it if possible.\n                opcode = findOpcodeForInsn(insn, opcode);\n                if (opcode == null) {\n                    /*\n                     * The branch is already maximally large. This should\n                     * only be possible if a method somehow manages to have\n                     * more than 2^31 code units.\n                     */\n                    throw new UnsupportedOperationException(\"method too long\");\n                }\n                insns.set(i, insn.withOpcode(opcode));\n            } else {\n                /*\n                 * It is a conditional: Reverse its sense, and arrange for\n                 * it to branch around an absolute goto to the original\n                 * branch target.\n                 *\n                 * Note: An invariant of the list being processed is\n                 * that every TargetInsn is followed by a CodeAddress.\n                 * Hence, it is always safe to get the next element\n                 * after a TargetInsn and cast it to CodeAddress, as\n                 * is happening a few lines down.\n                 *\n                 * Also note: Size gets incremented by one here, as we\n                 * have -- in the net -- added one additional element\n                 * to the list, so we increment i to match. The added\n                 * and changed elements will be inspected by a repeat\n                 * call to this method after this invocation returns.\n                 */\n                CodeAddress newTarget;\n                try {\n                    newTarget = (CodeAddress) insns.get(i + 1);\n                } catch (IndexOutOfBoundsException ex) {\n                    // The TargetInsn / CodeAddress invariant was violated.\n                    throw new IllegalStateException(\n                            \"unpaired TargetInsn (dangling)\");\n                } catch (ClassCastException ex) {\n                    // The TargetInsn / CodeAddress invariant was violated.\n                    throw new IllegalStateException(\"unpaired TargetInsn\");\n                }\n                TargetInsn gotoInsn =\n                    new TargetInsn(Dops.GOTO, target.getPosition(),\n                            RegisterSpecList.EMPTY, target.getTarget());\n                insns.set(i, gotoInsn);\n                insns.add(i, target.withNewTargetAndReversed(newTarget));\n                size++;\n                i++;\n            }\n\n            anyFixed = true;\n        }\n\n        return anyFixed;\n    }\n\n    private void align64bits(Dop[] opcodes) {\n      while (true) {\n        int notAligned64bitRegAccess = 0;\n        int aligned64bitRegAccess = 0;\n        int notAligned64bitParamAccess = 0;\n        int aligned64bitParamAccess = 0;\n        int lastParameter = unreservedRegCount + reservedCount + reservedParameterCount;\n        int firstParameter = lastParameter - paramSize;\n\n        // Collects the number of time that 64-bit registers are accessed aligned or not.\n        for (DalvInsn insn : insns) {\n          RegisterSpecList regs = insn.getRegisters();\n          for (int usedRegIdx = 0; usedRegIdx < regs.size(); usedRegIdx++) {\n            RegisterSpec reg = regs.get(usedRegIdx);\n            if (reg.isCategory2()) {\n              boolean isParameter = reg.getReg() >= firstParameter;\n              if (reg.isEvenRegister()) {\n                if (isParameter) {\n                  aligned64bitParamAccess++;\n                } else {\n                  aligned64bitRegAccess++;\n                }\n              } else {\n                if (isParameter) {\n                  notAligned64bitParamAccess++;\n                } else {\n                  notAligned64bitRegAccess++;\n                }\n              }\n            }\n          }\n        }\n\n        if (notAligned64bitParamAccess > aligned64bitParamAccess\n            && notAligned64bitRegAccess > aligned64bitRegAccess) {\n          addReservedRegisters(1);\n        } else if (notAligned64bitParamAccess > aligned64bitParamAccess) {\n          addReservedParameters(1);\n        } else if (notAligned64bitRegAccess > aligned64bitRegAccess) {\n          addReservedRegisters(1);\n\n          // Need to shift parameters if they exist and if number of unaligned is greater than\n          // aligned. We test the opposite because we previously shift all registers by one,\n          // so the number of aligned become the number of unaligned.\n          if (paramSize != 0 && aligned64bitParamAccess > notAligned64bitParamAccess) {\n            addReservedParameters(1);\n          }\n        } else {\n          break;\n        }\n\n        if (!reserveRegisters(opcodes)) {\n          break;\n        }\n      }\n    }\n\n    private void addReservedParameters(int delta) {\n      shiftParameters(delta);\n      reservedParameterCount += delta;\n    }\n\n    private void addReservedRegisters(int delta) {\n      shiftAllRegisters(delta);\n      reservedCount += delta;\n    }\n\n    private void shiftAllRegisters(int delta) {\n      int insnSize = insns.size();\n\n      for (int i = 0; i < insnSize; i++) {\n        DalvInsn insn = insns.get(i);\n        // Since there is no need to replace CodeAddress since it does not use registers, skips it to\n        // avoid to update all TargetInsn that contain a reference to CodeAddress\n        if (!(insn instanceof CodeAddress)) {\n          insns.set(i, insn.withRegisterOffset(delta));\n        }\n      }\n    }\n\n    private void shiftParameters(int delta) {\n      int insnSize = insns.size();\n      int lastParameter = unreservedRegCount + reservedCount + reservedParameterCount;\n      int firstParameter = lastParameter - paramSize;\n\n      BasicRegisterMapper mapper = new BasicRegisterMapper(lastParameter);\n      for (int i = 0; i < lastParameter; i++) {\n        if (i >= firstParameter) {\n          mapper.addMapping(i, i + delta, 1);\n        } else {\n          mapper.addMapping(i, i, 1);\n        }\n      }\n\n      for (int i = 0; i < insnSize; i++) {\n        DalvInsn insn = insns.get(i);\n        // Since there is no need to replace CodeAddress since it does not use registers, skips it to\n        // avoid to update all TargetInsn that contain a reference to CodeAddress\n        if (!(insn instanceof CodeAddress)) {\n          insns.set(i, insn.withMapper(mapper));\n        }\n      }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/PositionList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.util.FixedSizeList;\n\n/**\n * List of source position entries. This class includes a utility\n * method to extract an instance out of a {@link DalvInsnList}.\n */\npublic final class PositionList extends FixedSizeList {\n    /** {@code non-null;} empty instance */\n    public static final PositionList EMPTY = new PositionList(0);\n\n    /**\n     * constant for {@link #make} to indicate that no actual position\n     * information should be returned\n     */\n    public static final int NONE = 1;\n\n    /**\n     * constant for {@link #make} to indicate that only line number\n     * transitions should be returned\n     */\n    public static final int LINES = 2;\n\n    /**\n     * constant for {@link #make} to indicate that only \"important\" position\n     * information should be returned. This includes block starts and\n     * instructions that might throw.\n     */\n    public static final int IMPORTANT = 3;\n\n    /**\n     * Extracts and returns the source position information out of an\n     * instruction list.\n     *\n     * @param insns {@code non-null;} instructions to convert\n     * @param howMuch how much information should be included; one of the\n     * static constants defined by this class\n     * @return {@code non-null;} the positions list\n     */\n    public static PositionList make(DalvInsnList insns, int howMuch) {\n        switch (howMuch) {\n            case NONE: {\n                return EMPTY;\n            }\n            case LINES:\n            case IMPORTANT: {\n                // Valid.\n                break;\n            }\n            default: {\n                throw new IllegalArgumentException(\"bogus howMuch\");\n            }\n        }\n\n        SourcePosition noInfo = SourcePosition.NO_INFO;\n        SourcePosition cur = noInfo;\n        int sz = insns.size();\n        Entry[] arr = new Entry[sz];\n        boolean lastWasTarget = false;\n        int at = 0;\n\n        for (int i = 0; i < sz; i++) {\n            DalvInsn insn = insns.get(i);\n\n            if (insn instanceof CodeAddress) {\n                lastWasTarget = true;;\n                continue;\n            }\n\n            SourcePosition pos = insn.getPosition();\n\n            if (pos.equals(noInfo) || pos.sameLine(cur)) {\n                continue;\n            }\n\n            if ((howMuch == IMPORTANT) && !lastWasTarget) {\n                continue;\n            }\n\n            cur = pos;\n            arr[at] = new Entry(insn.getAddress(), pos);\n            at++;\n\n            lastWasTarget = false;\n        }\n\n        PositionList result = new PositionList(at);\n        for (int i = 0; i < at; i++) {\n            result.set(i, arr[i]);\n        }\n\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size {@code >= 0;} the size of the list\n     */\n    public PositionList(int size) {\n        super(size);\n    }\n\n    /**\n     * Gets the element at the given index. It is an error to call\n     * this with the index for an element which was never set; if you\n     * do that, this will throw {@code NullPointerException}.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @return {@code non-null;} element at that index\n     */\n    public Entry get(int n) {\n        return (Entry) get0(n);\n    }\n\n    /**\n     * Sets the entry at the given index.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @param entry {@code non-null;} the entry to set at {@code n}\n     */\n    public void set(int n, Entry entry) {\n        set0(n, entry);\n    }\n\n    /**\n     * Entry in a position list.\n     */\n    public static class Entry {\n        /** {@code >= 0;} address of this entry */\n        private final int address;\n\n        /** {@code non-null;} corresponding source position information */\n        private final SourcePosition position;\n\n        /**\n         * Constructs an instance.\n         *\n         * @param address {@code >= 0;} address of this entry\n         * @param position {@code non-null;} corresponding source position information\n         */\n        public Entry (int address, SourcePosition position) {\n            if (address < 0) {\n                throw new IllegalArgumentException(\"address < 0\");\n            }\n\n            if (position == null) {\n                throw new NullPointerException(\"position == null\");\n            }\n\n            this.address = address;\n            this.position = position;\n        }\n\n        /**\n         * Gets the address.\n         *\n         * @return {@code >= 0;} the address\n         */\n        public int getAddress() {\n            return address;\n        }\n\n        /**\n         * Gets the source position information.\n         *\n         * @return {@code non-null;} the position information\n         */\n        public SourcePosition getPosition() {\n            return position;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/RopToDop.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.Insn;\nimport com.taobao.android.dx.rop.code.RegOps;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.Rop;\nimport com.taobao.android.dx.rop.code.Rops;\nimport com.taobao.android.dx.rop.code.ThrowingCstInsn;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Type;\nimport java.util.HashMap;\n\n/**\n * Translator from rop-level {@link Insn} instances to corresponding\n * {@link Dop} instances.\n */\npublic final class RopToDop {\n    /** {@code non-null;} map from all the common rops to dalvik opcodes */\n    private static final HashMap<Rop, Dop> MAP;\n\n    /**\n     * This class is uninstantiable.\n     */\n    private RopToDop() {\n        // This space intentionally left blank.\n    }\n\n    /*\n     * The following comment lists each opcode that should be considered\n     * the \"head\" of an opcode chain, in terms of the process of fitting\n     * an instruction's arguments to an actual opcode. This list is\n     * automatically generated and may be of use in double-checking the\n     * manually-generated static initialization code for this class.\n     *\n     * TODO: Make opcode-gen produce useful code in this case instead\n     * of just a comment.\n     */\n\n    // BEGIN(first-opcodes); GENERATED AUTOMATICALLY BY opcode-gen\n    //     Opcodes.NOP\n    //     Opcodes.MOVE\n    //     Opcodes.MOVE_WIDE\n    //     Opcodes.MOVE_OBJECT\n    //     Opcodes.MOVE_RESULT\n    //     Opcodes.MOVE_RESULT_WIDE\n    //     Opcodes.MOVE_RESULT_OBJECT\n    //     Opcodes.MOVE_EXCEPTION\n    //     Opcodes.RETURN_VOID\n    //     Opcodes.RETURN\n    //     Opcodes.RETURN_WIDE\n    //     Opcodes.RETURN_OBJECT\n    //     Opcodes.CONST_4\n    //     Opcodes.CONST_WIDE_16\n    //     Opcodes.CONST_STRING\n    //     Opcodes.CONST_CLASS\n    //     Opcodes.MONITOR_ENTER\n    //     Opcodes.MONITOR_EXIT\n    //     Opcodes.CHECK_CAST\n    //     Opcodes.INSTANCE_OF\n    //     Opcodes.ARRAY_LENGTH\n    //     Opcodes.NEW_INSTANCE\n    //     Opcodes.NEW_ARRAY\n    //     Opcodes.FILLED_NEW_ARRAY\n    //     Opcodes.FILL_ARRAY_DATA\n    //     Opcodes.THROW\n    //     Opcodes.GOTO\n    //     Opcodes.PACKED_SWITCH\n    //     Opcodes.SPARSE_SWITCH\n    //     Opcodes.CMPL_FLOAT\n    //     Opcodes.CMPG_FLOAT\n    //     Opcodes.CMPL_DOUBLE\n    //     Opcodes.CMPG_DOUBLE\n    //     Opcodes.CMP_LONG\n    //     Opcodes.IF_EQ\n    //     Opcodes.IF_NE\n    //     Opcodes.IF_LT\n    //     Opcodes.IF_GE\n    //     Opcodes.IF_GT\n    //     Opcodes.IF_LE\n    //     Opcodes.IF_EQZ\n    //     Opcodes.IF_NEZ\n    //     Opcodes.IF_LTZ\n    //     Opcodes.IF_GEZ\n    //     Opcodes.IF_GTZ\n    //     Opcodes.IF_LEZ\n    //     Opcodes.AGET\n    //     Opcodes.AGET_WIDE\n    //     Opcodes.AGET_OBJECT\n    //     Opcodes.AGET_BOOLEAN\n    //     Opcodes.AGET_BYTE\n    //     Opcodes.AGET_CHAR\n    //     Opcodes.AGET_SHORT\n    //     Opcodes.APUT\n    //     Opcodes.APUT_WIDE\n    //     Opcodes.APUT_OBJECT\n    //     Opcodes.APUT_BOOLEAN\n    //     Opcodes.APUT_BYTE\n    //     Opcodes.APUT_CHAR\n    //     Opcodes.APUT_SHORT\n    //     Opcodes.IGET\n    //     Opcodes.IGET_WIDE\n    //     Opcodes.IGET_OBJECT\n    //     Opcodes.IGET_BOOLEAN\n    //     Opcodes.IGET_BYTE\n    //     Opcodes.IGET_CHAR\n    //     Opcodes.IGET_SHORT\n    //     Opcodes.IPUT\n    //     Opcodes.IPUT_WIDE\n    //     Opcodes.IPUT_OBJECT\n    //     Opcodes.IPUT_BOOLEAN\n    //     Opcodes.IPUT_BYTE\n    //     Opcodes.IPUT_CHAR\n    //     Opcodes.IPUT_SHORT\n    //     Opcodes.SGET\n    //     Opcodes.SGET_WIDE\n    //     Opcodes.SGET_OBJECT\n    //     Opcodes.SGET_BOOLEAN\n    //     Opcodes.SGET_BYTE\n    //     Opcodes.SGET_CHAR\n    //     Opcodes.SGET_SHORT\n    //     Opcodes.SPUT\n    //     Opcodes.SPUT_WIDE\n    //     Opcodes.SPUT_OBJECT\n    //     Opcodes.SPUT_BOOLEAN\n    //     Opcodes.SPUT_BYTE\n    //     Opcodes.SPUT_CHAR\n    //     Opcodes.SPUT_SHORT\n    //     Opcodes.INVOKE_VIRTUAL\n    //     Opcodes.INVOKE_SUPER\n    //     Opcodes.INVOKE_DIRECT\n    //     Opcodes.INVOKE_STATIC\n    //     Opcodes.INVOKE_INTERFACE\n    //     Opcodes.NEG_INT\n    //     Opcodes.NOT_INT\n    //     Opcodes.NEG_LONG\n    //     Opcodes.NOT_LONG\n    //     Opcodes.NEG_FLOAT\n    //     Opcodes.NEG_DOUBLE\n    //     Opcodes.INT_TO_LONG\n    //     Opcodes.INT_TO_FLOAT\n    //     Opcodes.INT_TO_DOUBLE\n    //     Opcodes.LONG_TO_INT\n    //     Opcodes.LONG_TO_FLOAT\n    //     Opcodes.LONG_TO_DOUBLE\n    //     Opcodes.FLOAT_TO_INT\n    //     Opcodes.FLOAT_TO_LONG\n    //     Opcodes.FLOAT_TO_DOUBLE\n    //     Opcodes.DOUBLE_TO_INT\n    //     Opcodes.DOUBLE_TO_LONG\n    //     Opcodes.DOUBLE_TO_FLOAT\n    //     Opcodes.INT_TO_BYTE\n    //     Opcodes.INT_TO_CHAR\n    //     Opcodes.INT_TO_SHORT\n    //     Opcodes.ADD_INT_2ADDR\n    //     Opcodes.SUB_INT_2ADDR\n    //     Opcodes.MUL_INT_2ADDR\n    //     Opcodes.DIV_INT_2ADDR\n    //     Opcodes.REM_INT_2ADDR\n    //     Opcodes.AND_INT_2ADDR\n    //     Opcodes.OR_INT_2ADDR\n    //     Opcodes.XOR_INT_2ADDR\n    //     Opcodes.SHL_INT_2ADDR\n    //     Opcodes.SHR_INT_2ADDR\n    //     Opcodes.USHR_INT_2ADDR\n    //     Opcodes.ADD_LONG_2ADDR\n    //     Opcodes.SUB_LONG_2ADDR\n    //     Opcodes.MUL_LONG_2ADDR\n    //     Opcodes.DIV_LONG_2ADDR\n    //     Opcodes.REM_LONG_2ADDR\n    //     Opcodes.AND_LONG_2ADDR\n    //     Opcodes.OR_LONG_2ADDR\n    //     Opcodes.XOR_LONG_2ADDR\n    //     Opcodes.SHL_LONG_2ADDR\n    //     Opcodes.SHR_LONG_2ADDR\n    //     Opcodes.USHR_LONG_2ADDR\n    //     Opcodes.ADD_FLOAT_2ADDR\n    //     Opcodes.SUB_FLOAT_2ADDR\n    //     Opcodes.MUL_FLOAT_2ADDR\n    //     Opcodes.DIV_FLOAT_2ADDR\n    //     Opcodes.REM_FLOAT_2ADDR\n    //     Opcodes.ADD_DOUBLE_2ADDR\n    //     Opcodes.SUB_DOUBLE_2ADDR\n    //     Opcodes.MUL_DOUBLE_2ADDR\n    //     Opcodes.DIV_DOUBLE_2ADDR\n    //     Opcodes.REM_DOUBLE_2ADDR\n    //     Opcodes.ADD_INT_LIT8\n    //     Opcodes.RSUB_INT_LIT8\n    //     Opcodes.MUL_INT_LIT8\n    //     Opcodes.DIV_INT_LIT8\n    //     Opcodes.REM_INT_LIT8\n    //     Opcodes.AND_INT_LIT8\n    //     Opcodes.OR_INT_LIT8\n    //     Opcodes.XOR_INT_LIT8\n    //     Opcodes.SHL_INT_LIT8\n    //     Opcodes.SHR_INT_LIT8\n    //     Opcodes.USHR_INT_LIT8\n    // END(first-opcodes)\n\n    static {\n        /*\n         * Note: The choices made here are to pick the optimistically\n         * smallest Dalvik opcode, and leave it to later processing to\n         * pessimize. See the automatically-generated comment above\n         * for reference.\n         */\n        MAP = new HashMap<Rop, Dop>(400);\n        MAP.put(Rops.NOP,               Dops.NOP);\n        MAP.put(Rops.MOVE_INT,          Dops.MOVE);\n        MAP.put(Rops.MOVE_LONG,         Dops.MOVE_WIDE);\n        MAP.put(Rops.MOVE_FLOAT,        Dops.MOVE);\n        MAP.put(Rops.MOVE_DOUBLE,       Dops.MOVE_WIDE);\n        MAP.put(Rops.MOVE_OBJECT,       Dops.MOVE_OBJECT);\n        MAP.put(Rops.MOVE_PARAM_INT,    Dops.MOVE);\n        MAP.put(Rops.MOVE_PARAM_LONG,   Dops.MOVE_WIDE);\n        MAP.put(Rops.MOVE_PARAM_FLOAT,  Dops.MOVE);\n        MAP.put(Rops.MOVE_PARAM_DOUBLE, Dops.MOVE_WIDE);\n        MAP.put(Rops.MOVE_PARAM_OBJECT, Dops.MOVE_OBJECT);\n\n        /*\n         * Note: No entry for MOVE_EXCEPTION, since it varies by\n         * exception type. (That is, there is no unique instance to\n         * add to the map.)\n         */\n\n        MAP.put(Rops.CONST_INT,         Dops.CONST_4);\n        MAP.put(Rops.CONST_LONG,        Dops.CONST_WIDE_16);\n        MAP.put(Rops.CONST_FLOAT,       Dops.CONST_4);\n        MAP.put(Rops.CONST_DOUBLE,      Dops.CONST_WIDE_16);\n\n        /*\n         * Note: No entry for CONST_OBJECT, since it needs to turn\n         * into either CONST_STRING or CONST_CLASS.\n         */\n\n        /*\n         * TODO: I think the only case of this is for null, and\n         * const/4 should cover that.\n         */\n        MAP.put(Rops.CONST_OBJECT_NOTHROW, Dops.CONST_4);\n\n        MAP.put(Rops.GOTO,                 Dops.GOTO);\n        MAP.put(Rops.IF_EQZ_INT,           Dops.IF_EQZ);\n        MAP.put(Rops.IF_NEZ_INT,           Dops.IF_NEZ);\n        MAP.put(Rops.IF_LTZ_INT,           Dops.IF_LTZ);\n        MAP.put(Rops.IF_GEZ_INT,           Dops.IF_GEZ);\n        MAP.put(Rops.IF_LEZ_INT,           Dops.IF_LEZ);\n        MAP.put(Rops.IF_GTZ_INT,           Dops.IF_GTZ);\n        MAP.put(Rops.IF_EQZ_OBJECT,        Dops.IF_EQZ);\n        MAP.put(Rops.IF_NEZ_OBJECT,        Dops.IF_NEZ);\n        MAP.put(Rops.IF_EQ_INT,            Dops.IF_EQ);\n        MAP.put(Rops.IF_NE_INT,            Dops.IF_NE);\n        MAP.put(Rops.IF_LT_INT,            Dops.IF_LT);\n        MAP.put(Rops.IF_GE_INT,            Dops.IF_GE);\n        MAP.put(Rops.IF_LE_INT,            Dops.IF_LE);\n        MAP.put(Rops.IF_GT_INT,            Dops.IF_GT);\n        MAP.put(Rops.IF_EQ_OBJECT,         Dops.IF_EQ);\n        MAP.put(Rops.IF_NE_OBJECT,         Dops.IF_NE);\n        MAP.put(Rops.SWITCH,               Dops.SPARSE_SWITCH);\n        MAP.put(Rops.ADD_INT,              Dops.ADD_INT_2ADDR);\n        MAP.put(Rops.ADD_LONG,             Dops.ADD_LONG_2ADDR);\n        MAP.put(Rops.ADD_FLOAT,            Dops.ADD_FLOAT_2ADDR);\n        MAP.put(Rops.ADD_DOUBLE,           Dops.ADD_DOUBLE_2ADDR);\n        MAP.put(Rops.SUB_INT,              Dops.SUB_INT_2ADDR);\n        MAP.put(Rops.SUB_LONG,             Dops.SUB_LONG_2ADDR);\n        MAP.put(Rops.SUB_FLOAT,            Dops.SUB_FLOAT_2ADDR);\n        MAP.put(Rops.SUB_DOUBLE,           Dops.SUB_DOUBLE_2ADDR);\n        MAP.put(Rops.MUL_INT,              Dops.MUL_INT_2ADDR);\n        MAP.put(Rops.MUL_LONG,             Dops.MUL_LONG_2ADDR);\n        MAP.put(Rops.MUL_FLOAT,            Dops.MUL_FLOAT_2ADDR);\n        MAP.put(Rops.MUL_DOUBLE,           Dops.MUL_DOUBLE_2ADDR);\n        MAP.put(Rops.DIV_INT,              Dops.DIV_INT_2ADDR);\n        MAP.put(Rops.DIV_LONG,             Dops.DIV_LONG_2ADDR);\n        MAP.put(Rops.DIV_FLOAT,            Dops.DIV_FLOAT_2ADDR);\n        MAP.put(Rops.DIV_DOUBLE,           Dops.DIV_DOUBLE_2ADDR);\n        MAP.put(Rops.REM_INT,              Dops.REM_INT_2ADDR);\n        MAP.put(Rops.REM_LONG,             Dops.REM_LONG_2ADDR);\n        MAP.put(Rops.REM_FLOAT,            Dops.REM_FLOAT_2ADDR);\n        MAP.put(Rops.REM_DOUBLE,           Dops.REM_DOUBLE_2ADDR);\n        MAP.put(Rops.NEG_INT,              Dops.NEG_INT);\n        MAP.put(Rops.NEG_LONG,             Dops.NEG_LONG);\n        MAP.put(Rops.NEG_FLOAT,            Dops.NEG_FLOAT);\n        MAP.put(Rops.NEG_DOUBLE,           Dops.NEG_DOUBLE);\n        MAP.put(Rops.AND_INT,              Dops.AND_INT_2ADDR);\n        MAP.put(Rops.AND_LONG,             Dops.AND_LONG_2ADDR);\n        MAP.put(Rops.OR_INT,               Dops.OR_INT_2ADDR);\n        MAP.put(Rops.OR_LONG,              Dops.OR_LONG_2ADDR);\n        MAP.put(Rops.XOR_INT,              Dops.XOR_INT_2ADDR);\n        MAP.put(Rops.XOR_LONG,             Dops.XOR_LONG_2ADDR);\n        MAP.put(Rops.SHL_INT,              Dops.SHL_INT_2ADDR);\n        MAP.put(Rops.SHL_LONG,             Dops.SHL_LONG_2ADDR);\n        MAP.put(Rops.SHR_INT,              Dops.SHR_INT_2ADDR);\n        MAP.put(Rops.SHR_LONG,             Dops.SHR_LONG_2ADDR);\n        MAP.put(Rops.USHR_INT,             Dops.USHR_INT_2ADDR);\n        MAP.put(Rops.USHR_LONG,            Dops.USHR_LONG_2ADDR);\n        MAP.put(Rops.NOT_INT,              Dops.NOT_INT);\n        MAP.put(Rops.NOT_LONG,             Dops.NOT_LONG);\n\n        MAP.put(Rops.ADD_CONST_INT,        Dops.ADD_INT_LIT8);\n        // Note: No dalvik ops for other types of add_const.\n\n        MAP.put(Rops.SUB_CONST_INT,        Dops.RSUB_INT_LIT8);\n        /*\n         * Note: No dalvik ops for any type of sub_const; instead\n         * there's a *reverse* sub (constant - reg) for ints only.\n         */\n\n        MAP.put(Rops.MUL_CONST_INT,        Dops.MUL_INT_LIT8);\n        // Note: No dalvik ops for other types of mul_const.\n\n        MAP.put(Rops.DIV_CONST_INT,        Dops.DIV_INT_LIT8);\n        // Note: No dalvik ops for other types of div_const.\n\n        MAP.put(Rops.REM_CONST_INT,        Dops.REM_INT_LIT8);\n        // Note: No dalvik ops for other types of rem_const.\n\n        MAP.put(Rops.AND_CONST_INT,        Dops.AND_INT_LIT8);\n        // Note: No dalvik op for and_const_long.\n\n        MAP.put(Rops.OR_CONST_INT,         Dops.OR_INT_LIT8);\n        // Note: No dalvik op for or_const_long.\n\n        MAP.put(Rops.XOR_CONST_INT,        Dops.XOR_INT_LIT8);\n        // Note: No dalvik op for xor_const_long.\n\n        MAP.put(Rops.SHL_CONST_INT,        Dops.SHL_INT_LIT8);\n        // Note: No dalvik op for shl_const_long.\n\n        MAP.put(Rops.SHR_CONST_INT,        Dops.SHR_INT_LIT8);\n        // Note: No dalvik op for shr_const_long.\n\n        MAP.put(Rops.USHR_CONST_INT,       Dops.USHR_INT_LIT8);\n        // Note: No dalvik op for shr_const_long.\n\n        MAP.put(Rops.CMPL_LONG,            Dops.CMP_LONG);\n        MAP.put(Rops.CMPL_FLOAT,           Dops.CMPL_FLOAT);\n        MAP.put(Rops.CMPL_DOUBLE,          Dops.CMPL_DOUBLE);\n        MAP.put(Rops.CMPG_FLOAT,           Dops.CMPG_FLOAT);\n        MAP.put(Rops.CMPG_DOUBLE,          Dops.CMPG_DOUBLE);\n        MAP.put(Rops.CONV_L2I,             Dops.LONG_TO_INT);\n        MAP.put(Rops.CONV_F2I,             Dops.FLOAT_TO_INT);\n        MAP.put(Rops.CONV_D2I,             Dops.DOUBLE_TO_INT);\n        MAP.put(Rops.CONV_I2L,             Dops.INT_TO_LONG);\n        MAP.put(Rops.CONV_F2L,             Dops.FLOAT_TO_LONG);\n        MAP.put(Rops.CONV_D2L,             Dops.DOUBLE_TO_LONG);\n        MAP.put(Rops.CONV_I2F,             Dops.INT_TO_FLOAT);\n        MAP.put(Rops.CONV_L2F,             Dops.LONG_TO_FLOAT);\n        MAP.put(Rops.CONV_D2F,             Dops.DOUBLE_TO_FLOAT);\n        MAP.put(Rops.CONV_I2D,             Dops.INT_TO_DOUBLE);\n        MAP.put(Rops.CONV_L2D,             Dops.LONG_TO_DOUBLE);\n        MAP.put(Rops.CONV_F2D,             Dops.FLOAT_TO_DOUBLE);\n        MAP.put(Rops.TO_BYTE,              Dops.INT_TO_BYTE);\n        MAP.put(Rops.TO_CHAR,              Dops.INT_TO_CHAR);\n        MAP.put(Rops.TO_SHORT,             Dops.INT_TO_SHORT);\n        MAP.put(Rops.RETURN_VOID,          Dops.RETURN_VOID);\n        MAP.put(Rops.RETURN_INT,           Dops.RETURN);\n        MAP.put(Rops.RETURN_LONG,          Dops.RETURN_WIDE);\n        MAP.put(Rops.RETURN_FLOAT,         Dops.RETURN);\n        MAP.put(Rops.RETURN_DOUBLE,        Dops.RETURN_WIDE);\n        MAP.put(Rops.RETURN_OBJECT,        Dops.RETURN_OBJECT);\n        MAP.put(Rops.ARRAY_LENGTH,         Dops.ARRAY_LENGTH);\n        MAP.put(Rops.THROW,                Dops.THROW);\n        MAP.put(Rops.MONITOR_ENTER,        Dops.MONITOR_ENTER);\n        MAP.put(Rops.MONITOR_EXIT,         Dops.MONITOR_EXIT);\n        MAP.put(Rops.AGET_INT,             Dops.AGET);\n        MAP.put(Rops.AGET_LONG,            Dops.AGET_WIDE);\n        MAP.put(Rops.AGET_FLOAT,           Dops.AGET);\n        MAP.put(Rops.AGET_DOUBLE,          Dops.AGET_WIDE);\n        MAP.put(Rops.AGET_OBJECT,          Dops.AGET_OBJECT);\n        MAP.put(Rops.AGET_BOOLEAN,         Dops.AGET_BOOLEAN);\n        MAP.put(Rops.AGET_BYTE,            Dops.AGET_BYTE);\n        MAP.put(Rops.AGET_CHAR,            Dops.AGET_CHAR);\n        MAP.put(Rops.AGET_SHORT,           Dops.AGET_SHORT);\n        MAP.put(Rops.APUT_INT,             Dops.APUT);\n        MAP.put(Rops.APUT_LONG,            Dops.APUT_WIDE);\n        MAP.put(Rops.APUT_FLOAT,           Dops.APUT);\n        MAP.put(Rops.APUT_DOUBLE,          Dops.APUT_WIDE);\n        MAP.put(Rops.APUT_OBJECT,          Dops.APUT_OBJECT);\n        MAP.put(Rops.APUT_BOOLEAN,         Dops.APUT_BOOLEAN);\n        MAP.put(Rops.APUT_BYTE,            Dops.APUT_BYTE);\n        MAP.put(Rops.APUT_CHAR,            Dops.APUT_CHAR);\n        MAP.put(Rops.APUT_SHORT,           Dops.APUT_SHORT);\n        MAP.put(Rops.NEW_INSTANCE,         Dops.NEW_INSTANCE);\n        MAP.put(Rops.CHECK_CAST,           Dops.CHECK_CAST);\n        MAP.put(Rops.INSTANCE_OF,          Dops.INSTANCE_OF);\n\n        MAP.put(Rops.GET_FIELD_LONG,       Dops.IGET_WIDE);\n        MAP.put(Rops.GET_FIELD_FLOAT,      Dops.IGET);\n        MAP.put(Rops.GET_FIELD_DOUBLE,     Dops.IGET_WIDE);\n        MAP.put(Rops.GET_FIELD_OBJECT,     Dops.IGET_OBJECT);\n        /*\n         * Note: No map entries for get_field_* for non-long integral types,\n         * since they need to be handled specially (see dopFor() below).\n         */\n\n        MAP.put(Rops.GET_STATIC_LONG,      Dops.SGET_WIDE);\n        MAP.put(Rops.GET_STATIC_FLOAT,     Dops.SGET);\n        MAP.put(Rops.GET_STATIC_DOUBLE,    Dops.SGET_WIDE);\n        MAP.put(Rops.GET_STATIC_OBJECT,    Dops.SGET_OBJECT);\n        /*\n         * Note: No map entries for get_static* for non-long integral types,\n         * since they need to be handled specially (see dopFor() below).\n         */\n\n        MAP.put(Rops.PUT_FIELD_LONG,       Dops.IPUT_WIDE);\n        MAP.put(Rops.PUT_FIELD_FLOAT,      Dops.IPUT);\n        MAP.put(Rops.PUT_FIELD_DOUBLE,     Dops.IPUT_WIDE);\n        MAP.put(Rops.PUT_FIELD_OBJECT,     Dops.IPUT_OBJECT);\n        /*\n         * Note: No map entries for put_field_* for non-long integral types,\n         * since they need to be handled specially (see dopFor() below).\n         */\n\n        MAP.put(Rops.PUT_STATIC_LONG,      Dops.SPUT_WIDE);\n        MAP.put(Rops.PUT_STATIC_FLOAT,     Dops.SPUT);\n        MAP.put(Rops.PUT_STATIC_DOUBLE,    Dops.SPUT_WIDE);\n        MAP.put(Rops.PUT_STATIC_OBJECT,    Dops.SPUT_OBJECT);\n        /*\n         * Note: No map entries for put_static* for non-long integral types,\n         * since they need to be handled specially (see dopFor() below).\n         */\n\n        /*\n         * Note: No map entries for invoke*, new_array, and\n         * filled_new_array, since they need to be handled specially\n         * (see dopFor() below).\n         */\n    }\n\n    /**\n     * Returns the dalvik opcode appropriate for the given register-based\n     * instruction.\n     *\n     * @param insn {@code non-null;} the original instruction\n     * @return the corresponding dalvik opcode; one of the constants in\n     * {@link Dops}\n     */\n    public static Dop dopFor(Insn insn) {\n        Rop rop = insn.getOpcode();\n\n        /*\n         * First, just try looking up the rop in the MAP of easy\n         * cases.\n         */\n        Dop result = MAP.get(rop);\n        if (result != null) {\n            return result;\n        }\n\n        /*\n         * There was no easy case for the rop, so look up the opcode, and\n         * do something special for each:\n         *\n         * The move_exception, new_array, filled_new_array, and\n         * invoke* opcodes won't be found in MAP, since they'll each\n         * have different source and/or result register types / lists.\n         *\n         * The get* and put* opcodes for (non-long) integral types\n         * aren't in the map, since the type signatures aren't\n         * sufficient to distinguish between the types (the salient\n         * source or result will always be just \"int\").\n         *\n         * And const instruction need to distinguish between strings and\n         * classes.\n         */\n\n        switch (rop.getOpcode()) {\n            case RegOps.MOVE_EXCEPTION:   return Dops.MOVE_EXCEPTION;\n            case RegOps.INVOKE_STATIC:    return Dops.INVOKE_STATIC;\n            case RegOps.INVOKE_VIRTUAL:   return Dops.INVOKE_VIRTUAL;\n            case RegOps.INVOKE_SUPER:     return Dops.INVOKE_SUPER;\n            case RegOps.INVOKE_DIRECT:    return Dops.INVOKE_DIRECT;\n            case RegOps.INVOKE_INTERFACE: return Dops.INVOKE_INTERFACE;\n            case RegOps.NEW_ARRAY:        return Dops.NEW_ARRAY;\n            case RegOps.FILLED_NEW_ARRAY: return Dops.FILLED_NEW_ARRAY;\n            case RegOps.FILL_ARRAY_DATA:  return Dops.FILL_ARRAY_DATA;\n            case RegOps.MOVE_RESULT: {\n                RegisterSpec resultReg = insn.getResult();\n\n                if (resultReg == null) {\n                    return Dops.NOP;\n                } else {\n                    switch (resultReg.getBasicType()) {\n                        case Type.BT_INT:\n                        case Type.BT_FLOAT:\n                        case Type.BT_BOOLEAN:\n                        case Type.BT_BYTE:\n                        case Type.BT_CHAR:\n                        case Type.BT_SHORT:\n                            return Dops.MOVE_RESULT;\n                        case Type.BT_LONG:\n                        case Type.BT_DOUBLE:\n                            return Dops.MOVE_RESULT_WIDE;\n                        case Type.BT_OBJECT:\n                            return Dops.MOVE_RESULT_OBJECT;\n                        default: {\n                            throw new RuntimeException(\"Unexpected basic type\");\n                        }\n                    }\n                }\n            }\n\n            case RegOps.GET_FIELD: {\n                CstFieldRef ref =\n                    (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();\n                int basicType = ref.getBasicType();\n                switch (basicType) {\n                    case Type.BT_BOOLEAN: return Dops.IGET_BOOLEAN;\n                    case Type.BT_BYTE:    return Dops.IGET_BYTE;\n                    case Type.BT_CHAR:    return Dops.IGET_CHAR;\n                    case Type.BT_SHORT:   return Dops.IGET_SHORT;\n                    case Type.BT_INT:     return Dops.IGET;\n                }\n                break;\n            }\n            case RegOps.PUT_FIELD: {\n                CstFieldRef ref =\n                    (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();\n                int basicType = ref.getBasicType();\n                switch (basicType) {\n                    case Type.BT_BOOLEAN: return Dops.IPUT_BOOLEAN;\n                    case Type.BT_BYTE:    return Dops.IPUT_BYTE;\n                    case Type.BT_CHAR:    return Dops.IPUT_CHAR;\n                    case Type.BT_SHORT:   return Dops.IPUT_SHORT;\n                    case Type.BT_INT:     return Dops.IPUT;\n                }\n                break;\n            }\n            case RegOps.GET_STATIC: {\n                CstFieldRef ref =\n                    (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();\n                int basicType = ref.getBasicType();\n                switch (basicType) {\n                    case Type.BT_BOOLEAN: return Dops.SGET_BOOLEAN;\n                    case Type.BT_BYTE:    return Dops.SGET_BYTE;\n                    case Type.BT_CHAR:    return Dops.SGET_CHAR;\n                    case Type.BT_SHORT:   return Dops.SGET_SHORT;\n                    case Type.BT_INT:     return Dops.SGET;\n                }\n                break;\n            }\n            case RegOps.PUT_STATIC: {\n                CstFieldRef ref =\n                    (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();\n                int basicType = ref.getBasicType();\n                switch (basicType) {\n                    case Type.BT_BOOLEAN: return Dops.SPUT_BOOLEAN;\n                    case Type.BT_BYTE:    return Dops.SPUT_BYTE;\n                    case Type.BT_CHAR:    return Dops.SPUT_CHAR;\n                    case Type.BT_SHORT:   return Dops.SPUT_SHORT;\n                    case Type.BT_INT:     return Dops.SPUT;\n                }\n                break;\n            }\n            case RegOps.CONST: {\n                Constant cst = ((ThrowingCstInsn) insn).getConstant();\n                if (cst instanceof CstType) {\n                    return Dops.CONST_CLASS;\n                } else if (cst instanceof CstString) {\n                    return Dops.CONST_STRING;\n                }\n                break;\n            }\n        }\n\n        throw new RuntimeException(\"unknown rop: \" + rop);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/RopTranslator.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.dex.DexOptions;\nimport com.taobao.android.dx.io.Opcodes;\nimport com.taobao.android.dx.rop.code.BasicBlock;\nimport com.taobao.android.dx.rop.code.BasicBlockList;\nimport com.taobao.android.dx.rop.code.FillArrayDataInsn;\nimport com.taobao.android.dx.rop.code.Insn;\nimport com.taobao.android.dx.rop.code.LocalVariableInfo;\nimport com.taobao.android.dx.rop.code.PlainCstInsn;\nimport com.taobao.android.dx.rop.code.PlainInsn;\nimport com.taobao.android.dx.rop.code.RegOps;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.RegisterSpecSet;\nimport com.taobao.android.dx.rop.code.Rop;\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.rop.code.SwitchInsn;\nimport com.taobao.android.dx.rop.code.ThrowingCstInsn;\nimport com.taobao.android.dx.rop.code.ThrowingInsn;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.util.Bits;\nimport com.taobao.android.dx.util.IntList;\nimport java.util.ArrayList;\n\n/**\n * Translator from {@link RopMethod} to {@link DalvCode}. The {@link\n * #translate} method is the thing to call on this class.\n */\npublic final class RopTranslator {\n    /** {@code non-null;} options for dex output */\n    private final DexOptions dexOptions;\n\n    /** {@code non-null;} method to translate */\n    private final RopMethod method;\n\n    /**\n     * how much position info to preserve; one of the static\n     * constants in {@link PositionList}\n     */\n    private final int positionInfo;\n\n    /** {@code null-ok;} local variable info to use */\n    private final LocalVariableInfo locals;\n\n    /** {@code non-null;} container for all the address objects for the method */\n    private final BlockAddresses addresses;\n\n    /** {@code non-null;} list of output instructions in-progress */\n    private final OutputCollector output;\n\n    /** {@code non-null;} visitor to use during translation */\n    private final TranslationVisitor translationVisitor;\n\n    /** {@code >= 0;} register count for the method */\n    private final int regCount;\n\n    /** {@code null-ok;} block output order; becomes non-null in {@link #pickOrder} */\n    private int[] order;\n\n    /** size, in register units, of all the parameters to this method */\n    private final int paramSize;\n\n    /**\n     * true if the parameters to this method happen to be in proper order\n     * at the end of the frame (as the optimizer emits them)\n     */\n    private boolean paramsAreInOrder;\n\n    /**\n     * Translates a {@link RopMethod}. This may modify the given\n     * input.\n     *\n     * @param method {@code non-null;} the original method\n     * @param positionInfo how much position info to preserve; one of the\n     * static constants in {@link PositionList}\n     * @param locals {@code null-ok;} local variable information to use\n     * @param paramSize size, in register units, of all the parameters to\n     * this method\n     * @param dexOptions {@code non-null;} options for dex output\n     * @return {@code non-null;} the translated version\n     */\n    public static DalvCode translate(RopMethod method, int positionInfo,\n            LocalVariableInfo locals, int paramSize, DexOptions dexOptions) {\n        RopTranslator translator =\n            new RopTranslator(method, positionInfo, locals, paramSize, dexOptions);\n        return translator.translateAndGetResult();\n    }\n\n    /**\n     * Constructs an instance. This method is private. Use {@link #translate}.\n     *\n     * @param method {@code non-null;} the original method\n     * @param positionInfo how much position info to preserve; one of the\n     * static constants in {@link PositionList}\n     * @param locals {@code null-ok;} local variable information to use\n     * @param paramSize size, in register units, of all the parameters to\n     * this method\n     * @param dexOptions {@code non-null;} options for dex output\n     */\n    private RopTranslator(RopMethod method, int positionInfo, LocalVariableInfo locals,\n            int paramSize, DexOptions dexOptions) {\n        this.dexOptions = dexOptions;\n        this.method = method;\n        this.positionInfo = positionInfo;\n        this.locals = locals;\n        this.addresses = new BlockAddresses(method);\n        this.paramSize = paramSize;\n        this.order = null;\n        this.paramsAreInOrder = calculateParamsAreInOrder(method, paramSize);\n\n        BasicBlockList blocks = method.getBlocks();\n        int bsz = blocks.size();\n\n        /*\n         * Max possible instructions includes three code address\n         * objects per basic block (to the first and last instruction,\n         * and just past the end of the block), and the possibility of\n         * an extra goto at the end of each basic block.\n         */\n        int maxInsns = (bsz * 3) + blocks.getInstructionCount();\n\n        if (locals != null) {\n            /*\n             * If we're tracking locals, then there's could be another\n             * extra instruction per block (for the locals state at the\n             * start of the block) as well as one for each interblock\n             * local introduction.\n             */\n            maxInsns += bsz + locals.getAssignmentCount();\n        }\n\n        /*\n         * If params are not in order, we will need register space\n         * for them before this is all over...\n         */\n        this.regCount = blocks.getRegCount()\n                + (paramsAreInOrder ? 0 : this.paramSize);\n\n        this.output = new OutputCollector(dexOptions, maxInsns, bsz * 3, regCount, paramSize);\n\n        if (locals != null) {\n            this.translationVisitor =\n                new LocalVariableAwareTranslationVisitor(output, locals);\n        } else {\n            this.translationVisitor = new TranslationVisitor(output);\n        }\n    }\n\n    /**\n     * Checks to see if the move-param instructions that occur in this\n     * method happen to slot the params in an order at the top of the\n     * stack frame that matches dalvik's calling conventions. This will\n     * alway result in \"true\" for methods that have run through the\n     * SSA optimizer.\n     *\n     * @param paramSize size, in register units, of all the parameters\n     * to this method\n     */\n    private static boolean calculateParamsAreInOrder(RopMethod method,\n            final int paramSize) {\n        final boolean[] paramsAreInOrder = { true };\n        final int initialRegCount = method.getBlocks().getRegCount();\n\n        /*\n         * We almost could just check the first block here, but the\n         * {@code cf} layer will put in a second move-param in a\n         * subsequent block in the case of synchronized methods.\n         */\n        method.getBlocks().forEachInsn(new Insn.BaseVisitor() {\n            @Override\n            public void visitPlainCstInsn(PlainCstInsn insn) {\n                if (insn.getOpcode().getOpcode()== RegOps.MOVE_PARAM) {\n                    int param =\n                        ((CstInteger) insn.getConstant()).getValue();\n\n                    paramsAreInOrder[0] = paramsAreInOrder[0]\n                            && ((initialRegCount - paramSize + param)\n                                == insn.getResult().getReg());\n                }\n            }\n        });\n\n        return paramsAreInOrder[0];\n    }\n\n    /**\n     * Does the translation and returns the result.\n     *\n     * @return {@code non-null;} the result\n     */\n    private DalvCode translateAndGetResult() {\n        pickOrder();\n        outputInstructions();\n\n        StdCatchBuilder catches =\n            new StdCatchBuilder(method, order, addresses);\n\n        return new DalvCode(positionInfo, output.getFinisher(), catches);\n    }\n\n    /**\n     * Performs initial creation of output instructions based on the\n     * original blocks.\n     */\n    private void outputInstructions() {\n        BasicBlockList blocks = method.getBlocks();\n        int[] order = this.order;\n        int len = order.length;\n\n        // Process the blocks in output order.\n        for (int i = 0; i < len; i++) {\n            int nextI = i + 1;\n            int nextLabel = (nextI == order.length) ? -1 : order[nextI];\n            outputBlock(blocks.labelToBlock(order[i]), nextLabel);\n        }\n    }\n\n    /**\n     * Helper for {@link #outputInstructions}, which does the processing\n     * and output of one block.\n     *\n     * @param block {@code non-null;} the block to process and output\n     * @param nextLabel {@code >= -1;} the next block that will be processed, or\n     * {@code -1} if there is no next block\n     */\n    private void outputBlock(BasicBlock block, int nextLabel) {\n        // Append the code address for this block.\n        CodeAddress startAddress = addresses.getStart(block);\n        output.add(startAddress);\n\n        // Append the local variable state for the block.\n        if (locals != null) {\n            RegisterSpecSet starts = locals.getStarts(block);\n            output.add(new LocalSnapshot(startAddress.getPosition(),\n                                         starts));\n        }\n\n        /*\n         * Choose and append an output instruction for each original\n         * instruction.\n         */\n        translationVisitor.setBlock(block, addresses.getLast(block));\n        block.getInsns().forEach(translationVisitor);\n\n        // Insert the block end code address.\n        output.add(addresses.getEnd(block));\n\n        // Set up for end-of-block activities.\n\n        int succ = block.getPrimarySuccessor();\n        Insn lastInsn = block.getLastInsn();\n\n        /*\n         * Check for (and possibly correct for) a non-optimal choice of\n         * which block will get output next.\n         */\n\n        if ((succ >= 0) && (succ != nextLabel)) {\n            /*\n             * The block has a \"primary successor\" and that primary\n             * successor isn't the next block to be output.\n             */\n            Rop lastRop = lastInsn.getOpcode();\n            if ((lastRop.getBranchingness() == Rop.BRANCH_IF) &&\n                    (block.getSecondarySuccessor() == nextLabel)) {\n                /*\n                 * The block ends with an \"if\" of some sort, and its\n                 * secondary successor (the \"then\") is in fact the\n                 * next block to output. So, reverse the sense of\n                 * the test, so that we can just emit the next block\n                 * without an interstitial goto.\n                 */\n                output.reverseBranch(1, addresses.getStart(succ));\n            } else {\n                /*\n                 * Our only recourse is to add a goto here to get the\n                 * flow to be correct.\n                 */\n                TargetInsn insn =\n                    new TargetInsn(Dops.GOTO, lastInsn.getPosition(),\n                            RegisterSpecList.EMPTY,\n                            addresses.getStart(succ));\n                output.add(insn);\n            }\n        }\n    }\n\n    /**\n     * Picks an order for the blocks by doing \"trace\" analysis.\n     */\n    private void pickOrder() {\n        BasicBlockList blocks = method.getBlocks();\n        int sz = blocks.size();\n        int maxLabel = blocks.getMaxLabel();\n        int[] workSet = Bits.makeBitSet(maxLabel);\n        int[] tracebackSet = Bits.makeBitSet(maxLabel);\n\n        for (int i = 0; i < sz; i++) {\n            BasicBlock one = blocks.get(i);\n            Bits.set(workSet, one.getLabel());\n        }\n\n        int[] order = new int[sz];\n        int at = 0;\n\n        /*\n         * Starting with the designated \"first label\" (that is, the\n         * first block of the method), add that label to the order,\n         * and then pick its first as-yet unordered successor to\n         * immediately follow it, giving top priority to the primary\n         * (aka default) successor (if any). Keep following successors\n         * until the trace runs out of possibilities. Then, continue\n         * by finding an unordered chain containing the first as-yet\n         * unordered block, and adding it to the order, and so on.\n         */\n        for (int label = method.getFirstLabel();\n             label != -1;\n             label = Bits.findFirst(workSet, 0)) {\n\n            /*\n             * Attempt to trace backward from the chosen block to an\n             * as-yet unordered predecessor which lists the chosen\n             * block as its primary successor, and so on, until we\n             * fail to find such an unordered predecessor. Start the\n             * trace with that block. Note that the first block in the\n             * method has no predecessors, so in that case this loop\n             * will simply terminate with zero iterations and without\n             * picking a new starter block.\n             */\n            traceBack:\n            for (;;) {\n                IntList preds = method.labelToPredecessors(label);\n                int psz = preds.size();\n\n                for (int i = 0; i < psz; i++) {\n                    int predLabel = preds.get(i);\n\n                    if (Bits.get(tracebackSet, predLabel)) {\n                        /*\n                         * We found a predecessor loop; stop tracing back\n                         * from here.\n                         */\n                        break;\n                    }\n\n                    if (!Bits.get(workSet, predLabel)) {\n                        // This one's already ordered.\n                        continue;\n                    }\n\n                    BasicBlock pred = blocks.labelToBlock(predLabel);\n                    if (pred.getPrimarySuccessor() == label) {\n                        // Found one!\n                        label = predLabel;\n                        Bits.set(tracebackSet, label);\n                        continue traceBack;\n                    }\n                }\n\n                // Failed to find a better block to start the trace.\n                break;\n            }\n\n            /*\n             * Trace a path from the chosen block to one of its\n             * unordered successors (hopefully the primary), and so\n             * on, until we run out of unordered successors.\n             */\n            while (label != -1) {\n                Bits.clear(workSet, label);\n                Bits.clear(tracebackSet, label);\n                order[at] = label;\n                at++;\n\n                BasicBlock one = blocks.labelToBlock(label);\n                BasicBlock preferredBlock = blocks.preferredSuccessorOf(one);\n\n                if (preferredBlock == null) {\n                    break;\n                }\n\n                int preferred = preferredBlock.getLabel();\n                int primary = one.getPrimarySuccessor();\n\n                if (Bits.get(workSet, preferred)) {\n                    /*\n                     * Order the current block's preferred successor\n                     * next, as it has yet to be scheduled.\n                     */\n                    label = preferred;\n                } else if ((primary != preferred) && (primary >= 0)\n                        && Bits.get(workSet, primary)) {\n                    /*\n                     * The primary is available, so use that.\n                     */\n                    label = primary;\n                } else {\n                    /*\n                     * There's no obvious candidate, so pick the first\n                     * one that's available, if any.\n                     */\n                    IntList successors = one.getSuccessors();\n                    int ssz = successors.size();\n                    label = -1;\n                    for (int i = 0; i < ssz; i++) {\n                        int candidate = successors.get(i);\n                        if (Bits.get(workSet, candidate)) {\n                            label = candidate;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (at != sz) {\n            // There was a duplicate block label.\n            throw new RuntimeException(\"shouldn't happen\");\n        }\n\n        this.order = order;\n    }\n\n    /**\n     * Gets the complete register list (result and sources) out of a\n     * given rop instruction. For insns that are commutative, have\n     * two register sources, and have a source equal to the result,\n     * place that source first.\n     *\n     * @param insn {@code non-null;} instruction in question\n     * @return {@code non-null;} the instruction's complete register list\n     */\n    private static RegisterSpecList getRegs(Insn insn) {\n        return getRegs(insn, insn.getResult());\n    }\n\n    /**\n     * Gets the complete register list (result and sources) out of a\n     * given rop instruction. For insns that are commutative, have\n     * two register sources, and have a source equal to the result,\n     * place that source first.\n     *\n     * @param insn {@code non-null;} instruction in question\n     * @param resultReg {@code null-ok;} the real result to use (ignore the insn's)\n     * @return {@code non-null;} the instruction's complete register list\n     */\n    private static RegisterSpecList getRegs(Insn insn,\n            RegisterSpec resultReg) {\n        RegisterSpecList regs = insn.getSources();\n\n        if (insn.getOpcode().isCommutative()\n                && (regs.size() == 2)\n                && (resultReg.getReg() == regs.get(1).getReg())) {\n\n            /*\n             * For commutative ops which have two register sources,\n             * if the second source is the same register as the result,\n             * swap the sources so that an opcode of form 12x can be selected\n             * instead of one of form 23x\n             */\n\n            regs = RegisterSpecList.make(regs.get(1), regs.get(0));\n        }\n\n        if (resultReg == null) {\n            return regs;\n        }\n\n        return regs.withFirst(resultReg);\n    }\n\n    /**\n     * Instruction visitor class for doing the instruction translation per se.\n     */\n    private class TranslationVisitor implements Insn.Visitor {\n        /** {@code non-null;} list of output instructions in-progress */\n        private final OutputCollector output;\n\n        /** {@code non-null;} basic block being worked on */\n        private BasicBlock block;\n\n        /**\n         * {@code null-ok;} code address for the salient last instruction of the\n         * block (used before switches and throwing instructions)\n         */\n        private CodeAddress lastAddress;\n\n        /**\n         * Constructs an instance.\n         *\n         * @param output {@code non-null;} destination for instruction output\n         */\n        public TranslationVisitor(OutputCollector output) {\n            this.output = output;\n        }\n\n        /**\n         * Sets the block currently being worked on.\n         *\n         * @param block {@code non-null;} the block\n         * @param lastAddress {@code non-null;} code address for the salient\n         * last instruction of the block\n         */\n        public void setBlock(BasicBlock block, CodeAddress lastAddress) {\n            this.block = block;\n            this.lastAddress = lastAddress;\n        }\n\n        /** {@inheritDoc} */\n        public void visitPlainInsn(PlainInsn insn) {\n            Rop rop = insn.getOpcode();\n            if (rop.getOpcode() == RegOps.MARK_LOCAL) {\n                /*\n                 * Ignore these. They're dealt with by\n                 * the LocalVariableAwareTranslationVisitor\n                 */\n                return;\n            }\n            if (rop.getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {\n                // These get skipped\n                return;\n            }\n\n            SourcePosition pos = insn.getPosition();\n            Dop opcode = RopToDop.dopFor(insn);\n            DalvInsn di;\n\n            switch (rop.getBranchingness()) {\n                case Rop.BRANCH_NONE:\n                case Rop.BRANCH_RETURN:\n                case Rop.BRANCH_THROW: {\n                    di = new SimpleInsn(opcode, pos, getRegs(insn));\n                    break;\n                }\n                case Rop.BRANCH_GOTO: {\n                    /*\n                     * Code in the main translation loop will emit a\n                     * goto if necessary (if the branch isn't to the\n                     * immediately subsequent block).\n                     */\n                    return;\n                }\n                case Rop.BRANCH_IF: {\n                    int target = block.getSuccessors().get(1);\n                    di = new TargetInsn(opcode, pos, getRegs(insn),\n                                        addresses.getStart(target));\n                    break;\n                }\n                default: {\n                    throw new RuntimeException(\"shouldn't happen\");\n                }\n            }\n\n            addOutput(di);\n        }\n\n        /** {@inheritDoc} */\n        public void visitPlainCstInsn(PlainCstInsn insn) {\n            SourcePosition pos = insn.getPosition();\n            Dop opcode = RopToDop.dopFor(insn);\n            Rop rop = insn.getOpcode();\n            int ropOpcode = rop.getOpcode();\n            DalvInsn di;\n\n            if (rop.getBranchingness() != Rop.BRANCH_NONE) {\n                throw new RuntimeException(\"shouldn't happen\");\n            }\n\n            if (ropOpcode == RegOps.MOVE_PARAM) {\n                if (!paramsAreInOrder) {\n                    /*\n                     * Parameters are not in order at the top of the reg space.\n                     * We need to add moves.\n                     */\n\n                    RegisterSpec dest = insn.getResult();\n                    int param =\n                        ((CstInteger) insn.getConstant()).getValue();\n                    RegisterSpec source =\n                        RegisterSpec.make(regCount - paramSize + param,\n                                dest.getType());\n                    di = new SimpleInsn(opcode, pos,\n                                        RegisterSpecList.make(dest, source));\n                    addOutput(di);\n                }\n            } else {\n                // No moves required for the parameters\n                RegisterSpecList regs = getRegs(insn);\n                di = new CstInsn(opcode, pos, regs, insn.getConstant());\n                addOutput(di);\n            }\n        }\n\n        /** {@inheritDoc} */\n        public void visitSwitchInsn(SwitchInsn insn) {\n            SourcePosition pos = insn.getPosition();\n            IntList cases = insn.getCases();\n            IntList successors = block.getSuccessors();\n            int casesSz = cases.size();\n            int succSz = successors.size();\n            int primarySuccessor = block.getPrimarySuccessor();\n\n            /*\n             * Check the assumptions that the number of cases is one\n             * less than the number of successors and that the last\n             * successor in the list is the primary (in this case, the\n             * default). This test is here to guard against forgetting\n             * to change this code if the way switch instructions are\n             * constructed also gets changed.\n             */\n            if ((casesSz != (succSz - 1)) ||\n                (primarySuccessor != successors.get(casesSz))) {\n                throw new RuntimeException(\"shouldn't happen\");\n            }\n\n            CodeAddress[] switchTargets = new CodeAddress[casesSz];\n\n            for (int i = 0; i < casesSz; i++) {\n                int label = successors.get(i);\n                switchTargets[i] = addresses.getStart(label);\n            }\n\n            CodeAddress dataAddress = new CodeAddress(pos);\n            // make a new address that binds closely to the switch instruction\n            CodeAddress switchAddress =\n                new CodeAddress(lastAddress.getPosition(), true);\n            SwitchData dataInsn =\n                new SwitchData(pos, switchAddress, cases, switchTargets);\n            Dop opcode = dataInsn.isPacked() ?\n                Dops.PACKED_SWITCH : Dops.SPARSE_SWITCH;\n            TargetInsn switchInsn =\n                new TargetInsn(opcode, pos, getRegs(insn), dataAddress);\n\n            addOutput(switchAddress);\n            addOutput(switchInsn);\n\n            addOutputSuffix(new OddSpacer(pos));\n            addOutputSuffix(dataAddress);\n            addOutputSuffix(dataInsn);\n        }\n\n        /**\n         * Looks forward to the current block's primary successor, returning\n         * the RegisterSpec of the result of the move-result-pseudo at the\n         * top of that block or null if none.\n         *\n         * @return {@code null-ok;} result of move-result-pseudo at the beginning of\n         * primary successor\n         */\n        private RegisterSpec getNextMoveResultPseudo()\n        {\n            int label = block.getPrimarySuccessor();\n\n            if (label < 0) {\n                return null;\n            }\n\n            Insn insn\n                    = method.getBlocks().labelToBlock(label).getInsns().get(0);\n\n            if (insn.getOpcode().getOpcode() != RegOps.MOVE_RESULT_PSEUDO) {\n                return null;\n            } else {\n                return insn.getResult();\n            }\n        }\n\n        /** {@inheritDoc} */\n        public void visitThrowingCstInsn(ThrowingCstInsn insn) {\n            SourcePosition pos = insn.getPosition();\n            Dop opcode = RopToDop.dopFor(insn);\n            Rop rop = insn.getOpcode();\n            Constant cst = insn.getConstant();\n\n            if (rop.getBranchingness() != Rop.BRANCH_THROW) {\n                throw new RuntimeException(\"shouldn't happen\");\n            }\n\n            addOutput(lastAddress);\n\n            if (rop.isCallLike()) {\n                RegisterSpecList regs = insn.getSources();\n                DalvInsn di = new CstInsn(opcode, pos, regs, cst);\n\n                addOutput(di);\n            } else {\n                RegisterSpec realResult = getNextMoveResultPseudo();\n\n                RegisterSpecList regs = getRegs(insn, realResult);\n                DalvInsn di;\n\n                boolean hasResult = opcode.hasResult()\n                        || (rop.getOpcode() == RegOps.CHECK_CAST);\n\n                if (hasResult != (realResult != null)) {\n                    throw new RuntimeException(\n                            \"Insn with result/move-result-pseudo mismatch \" +\n                            insn);\n                }\n\n                if ((rop.getOpcode() == RegOps.NEW_ARRAY) &&\n                    (opcode.getOpcode() != Opcodes.NEW_ARRAY)) {\n                    /*\n                     * It's a type-specific new-array-<primitive>, and\n                     * so it should be turned into a SimpleInsn (no\n                     * constant ref as it's implicit).\n                     */\n                    di = new SimpleInsn(opcode, pos, regs);\n                } else {\n                    /*\n                     * This is the general case for constant-bearing\n                     * instructions.\n                     */\n                    di = new CstInsn(opcode, pos, regs, cst);\n                }\n\n                addOutput(di);\n            }\n        }\n\n        /** {@inheritDoc} */\n        public void visitThrowingInsn(ThrowingInsn insn) {\n            SourcePosition pos = insn.getPosition();\n            Dop opcode = RopToDop.dopFor(insn);\n            Rop rop = insn.getOpcode();\n            RegisterSpec realResult;\n\n            if (rop.getBranchingness() != Rop.BRANCH_THROW) {\n                throw new RuntimeException(\"shouldn't happen\");\n            }\n\n            realResult = getNextMoveResultPseudo();\n\n            if (opcode.hasResult() != (realResult != null)) {\n                throw new RuntimeException(\n                        \"Insn with result/move-result-pseudo mismatch\" + insn);\n            }\n\n            addOutput(lastAddress);\n\n            DalvInsn di = new SimpleInsn(opcode, pos,\n                    getRegs(insn, realResult));\n\n            addOutput(di);\n        }\n\n        /** {@inheritDoc} */\n        public void visitFillArrayDataInsn(FillArrayDataInsn insn) {\n            SourcePosition pos = insn.getPosition();\n            Constant cst = insn.getConstant();\n            ArrayList<Constant> values = insn.getInitValues();\n            Rop rop = insn.getOpcode();\n\n            if (rop.getBranchingness() != Rop.BRANCH_NONE) {\n                throw new RuntimeException(\"shouldn't happen\");\n            }\n            CodeAddress dataAddress = new CodeAddress(pos);\n            ArrayData dataInsn =\n                new ArrayData(pos, lastAddress, values, cst);\n\n            TargetInsn fillArrayDataInsn =\n                new TargetInsn(Dops.FILL_ARRAY_DATA, pos, getRegs(insn),\n                        dataAddress);\n\n            addOutput(lastAddress);\n            addOutput(fillArrayDataInsn);\n\n            addOutputSuffix(new OddSpacer(pos));\n            addOutputSuffix(dataAddress);\n            addOutputSuffix(dataInsn);\n        }\n\n        /**\n         * Adds to the output.\n         *\n         * @param insn {@code non-null;} instruction to add\n         */\n        protected void addOutput(DalvInsn insn) {\n            output.add(insn);\n        }\n\n        /**\n         * Adds to the output suffix.\n         *\n         * @param insn {@code non-null;} instruction to add\n         */\n        protected void addOutputSuffix(DalvInsn insn) {\n            output.addSuffix(insn);\n        }\n    }\n\n    /**\n     * Instruction visitor class for doing instruction translation with\n     * local variable tracking\n     */\n    private class LocalVariableAwareTranslationVisitor\n            extends TranslationVisitor {\n        /** {@code non-null;} local variable info */\n        private LocalVariableInfo locals;\n\n        /**\n         * Constructs an instance.\n         *\n         * @param output {@code non-null;} destination for instruction output\n         * @param locals {@code non-null;} the local variable info\n         */\n        public LocalVariableAwareTranslationVisitor(OutputCollector output,\n                                                    LocalVariableInfo locals) {\n            super(output);\n            this.locals = locals;\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public void visitPlainInsn(PlainInsn insn) {\n            super.visitPlainInsn(insn);\n            addIntroductionIfNecessary(insn);\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public void visitPlainCstInsn(PlainCstInsn insn) {\n            super.visitPlainCstInsn(insn);\n            addIntroductionIfNecessary(insn);\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public void visitSwitchInsn(SwitchInsn insn) {\n            super.visitSwitchInsn(insn);\n            addIntroductionIfNecessary(insn);\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public void visitThrowingCstInsn(ThrowingCstInsn insn) {\n            super.visitThrowingCstInsn(insn);\n            addIntroductionIfNecessary(insn);\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public void visitThrowingInsn(ThrowingInsn insn) {\n            super.visitThrowingInsn(insn);\n            addIntroductionIfNecessary(insn);\n        }\n\n        /**\n         * Adds a {@link LocalStart} to the output if the given\n         * instruction in fact introduces a local variable.\n         *\n         * @param insn {@code non-null;} instruction in question\n         */\n        public void addIntroductionIfNecessary(Insn insn) {\n            RegisterSpec spec = locals.getAssignment(insn);\n\n            if (spec != null) {\n                addOutput(new LocalStart(insn.getPosition(), spec));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/SimpleInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.SourcePosition;\n\n/**\n * Instruction which has no extra info beyond the basics provided for in\n * the base class.\n */\npublic final class SimpleInsn extends FixedSizeInsn {\n    /**\n     * Constructs an instance. The output address of this instance is initially\n     * unknown ({@code -1}).\n     *\n     * @param opcode the opcode; one of the constants from {@link Dops}\n     * @param position {@code non-null;} source position\n     * @param registers {@code non-null;} register list, including a\n     * result register if appropriate (that is, registers may be either\n     * ins or outs)\n     */\n    public SimpleInsn(Dop opcode, SourcePosition position,\n                      RegisterSpecList registers) {\n        super(opcode, position, registers);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withOpcode(Dop opcode) {\n        return new SimpleInsn(opcode, getPosition(), getRegisters());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withRegisters(RegisterSpecList registers) {\n        return new SimpleInsn(getOpcode(), getPosition(), registers);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String argString() {\n        return null;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/StdCatchBuilder.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.BasicBlock;\nimport com.taobao.android.dx.rop.code.BasicBlockList;\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.IntList;\nimport java.util.ArrayList;\nimport java.util.HashSet;\n\n/**\n * Constructor of {@link CatchTable} instances from {@link RopMethod}\n * and associated data.\n */\npublic final class StdCatchBuilder implements CatchBuilder {\n    /** the maximum range of a single catch handler, in code units */\n    private static final int MAX_CATCH_RANGE = 65535;\n\n    /** {@code non-null;} method to build the list for */\n    private final RopMethod method;\n\n    /** {@code non-null;} block output order */\n    private final int[] order;\n\n    /** {@code non-null;} address objects for each block */\n    private final BlockAddresses addresses;\n\n    /**\n     * Constructs an instance. It merely holds onto its parameters for\n     * a subsequent call to {@link #build}.\n     *\n     * @param method {@code non-null;} method to build the list for\n     * @param order {@code non-null;} block output order\n     * @param addresses {@code non-null;} address objects for each block\n     */\n    public StdCatchBuilder(RopMethod method, int[] order,\n            BlockAddresses addresses) {\n        if (method == null) {\n            throw new NullPointerException(\"method == null\");\n        }\n\n        if (order == null) {\n            throw new NullPointerException(\"order == null\");\n        }\n\n        if (addresses == null) {\n            throw new NullPointerException(\"addresses == null\");\n        }\n\n        this.method = method;\n        this.order = order;\n        this.addresses = addresses;\n    }\n\n    /** {@inheritDoc} */\n    public CatchTable build() {\n        return build(method, order, addresses);\n    }\n\n    /** {@inheritDoc} */\n    public boolean hasAnyCatches() {\n        BasicBlockList blocks = method.getBlocks();\n        int size = blocks.size();\n\n        for (int i = 0; i < size; i++) {\n            BasicBlock block = blocks.get(i);\n            TypeList catches = block.getLastInsn().getCatches();\n            if (catches.size() != 0) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /** {@inheritDoc} */\n    public HashSet<Type> getCatchTypes() {\n        HashSet<Type> result = new HashSet<Type>(20);\n        BasicBlockList blocks = method.getBlocks();\n        int size = blocks.size();\n\n        for (int i = 0; i < size; i++) {\n            BasicBlock block = blocks.get(i);\n            TypeList catches = block.getLastInsn().getCatches();\n            int catchSize = catches.size();\n\n            for (int j = 0; j < catchSize; j++) {\n                result.add(catches.getType(j));\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * Builds and returns the catch table for a given method.\n     *\n     * @param method {@code non-null;} method to build the list for\n     * @param order {@code non-null;} block output order\n     * @param addresses {@code non-null;} address objects for each block\n     * @return {@code non-null;} the constructed table\n     */\n    public static CatchTable build(RopMethod method, int[] order,\n            BlockAddresses addresses) {\n        int len = order.length;\n        BasicBlockList blocks = method.getBlocks();\n        ArrayList<CatchTable.Entry> resultList =\n            new ArrayList<CatchTable.Entry>(len);\n        CatchHandlerList currentHandlers = CatchHandlerList.EMPTY;\n        BasicBlock currentStartBlock = null;\n        BasicBlock currentEndBlock = null;\n\n        for (int i = 0; i < len; i++) {\n            BasicBlock block = blocks.labelToBlock(order[i]);\n\n            if (!block.canThrow()) {\n                /*\n                 * There is no need to concern ourselves with the\n                 * placement of blocks that can't throw with respect\n                 * to the blocks that *can* throw.\n                 */\n                continue;\n            }\n\n            CatchHandlerList handlers = handlersFor(block, addresses);\n\n            if (currentHandlers.size() == 0) {\n                // This is the start of a new catch range.\n                currentStartBlock = block;\n                currentEndBlock = block;\n                currentHandlers = handlers;\n                continue;\n            }\n\n            if (currentHandlers.equals(handlers)\n                    && rangeIsValid(currentStartBlock, block, addresses)) {\n                /*\n                 * The block we are looking at now has the same handlers\n                 * as the block that started the currently open catch\n                 * range, and adding it to the currently open range won't\n                 * cause it to be too long.\n                 */\n                currentEndBlock = block;\n                continue;\n            }\n\n            /*\n             * The block we are looking at now has incompatible handlers,\n             * so we need to finish off the last entry and start a new\n             * one. Note: We only emit an entry if it has associated handlers.\n             */\n            if (currentHandlers.size() != 0) {\n                CatchTable.Entry entry =\n                    makeEntry(currentStartBlock, currentEndBlock,\n                            currentHandlers, addresses);\n                resultList.add(entry);\n            }\n\n            currentStartBlock = block;\n            currentEndBlock = block;\n            currentHandlers = handlers;\n        }\n\n        if (currentHandlers.size() != 0) {\n            // Emit an entry for the range that was left hanging.\n            CatchTable.Entry entry =\n                makeEntry(currentStartBlock, currentEndBlock,\n                        currentHandlers, addresses);\n            resultList.add(entry);\n        }\n\n        // Construct the final result.\n\n        int resultSz = resultList.size();\n\n        if (resultSz == 0) {\n            return CatchTable.EMPTY;\n        }\n\n        CatchTable result = new CatchTable(resultSz);\n\n        for (int i = 0; i < resultSz; i++) {\n            result.set(i, resultList.get(i));\n        }\n\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Makes the {@link CatchHandlerList} for the given basic block.\n     *\n     * @param block {@code non-null;} block to get entries for\n     * @param addresses {@code non-null;} address objects for each block\n     * @return {@code non-null;} array of entries\n     */\n    private static CatchHandlerList handlersFor(BasicBlock block,\n            BlockAddresses addresses) {\n        IntList successors = block.getSuccessors();\n        int succSize = successors.size();\n        int primary = block.getPrimarySuccessor();\n        TypeList catches = block.getLastInsn().getCatches();\n        int catchSize = catches.size();\n\n        if (catchSize == 0) {\n            return CatchHandlerList.EMPTY;\n        }\n\n        if (((primary == -1) && (succSize != catchSize))\n                || ((primary != -1) &&\n                        ((succSize != (catchSize + 1))\n                                || (primary != successors.get(catchSize))))) {\n            /*\n             * Blocks that throw are supposed to list their primary\n             * successor -- if any -- last in the successors list, but\n             * that constraint appears to be violated here.\n             */\n            throw new RuntimeException(\n                    \"shouldn't happen: weird successors list\");\n        }\n\n        /*\n         * Reduce the effective catchSize if we spot a catch-all that\n         * isn't at the end.\n         */\n        for (int i = 0; i < catchSize; i++) {\n            Type type = catches.getType(i);\n            if (type.equals(Type.OBJECT)) {\n                catchSize = i + 1;\n                break;\n            }\n        }\n\n        CatchHandlerList result = new CatchHandlerList(catchSize);\n\n        for (int i = 0; i < catchSize; i++) {\n            CstType oneType = new CstType(catches.getType(i));\n            CodeAddress oneHandler = addresses.getStart(successors.get(i));\n            result.set(i, oneType, oneHandler.getAddress());\n        }\n\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Makes a {@link CatchTable#Entry} for the given block range and\n     * handlers.\n     *\n     * @param start {@code non-null;} the start block for the range (inclusive)\n     * @param end {@code non-null;} the start block for the range (also inclusive)\n     * @param handlers {@code non-null;} the handlers for the range\n     * @param addresses {@code non-null;} address objects for each block\n     */\n    private static CatchTable.Entry makeEntry(BasicBlock start,\n            BasicBlock end, CatchHandlerList handlers,\n            BlockAddresses addresses) {\n        /*\n         * We start at the *last* instruction of the start block, since\n         * that's the instruction that can throw...\n         */\n        CodeAddress startAddress = addresses.getLast(start);\n\n        // ...And we end *after* the last instruction of the end block.\n        CodeAddress endAddress = addresses.getEnd(end);\n\n        return new CatchTable.Entry(startAddress.getAddress(),\n                endAddress.getAddress(), handlers);\n    }\n\n    /**\n     * Gets whether the address range for the given two blocks is valid\n     * for a catch handler. This is true as long as the covered range is\n     * under 65536 code units.\n     *\n     * @param start {@code non-null;} the start block for the range (inclusive)\n     * @param end {@code non-null;} the start block for the range (also inclusive)\n     * @param addresses {@code non-null;} address objects for each block\n     * @return {@code true} if the range is valid as a catch range\n     */\n    private static boolean rangeIsValid(BasicBlock start, BasicBlock end,\n            BlockAddresses addresses) {\n        if (start == null) {\n            throw new NullPointerException(\"start == null\");\n        }\n\n        if (end == null) {\n            throw new NullPointerException(\"end == null\");\n        }\n\n        // See above about selection of instructions.\n        int startAddress = addresses.getLast(start).getAddress();\n        int endAddress = addresses.getEnd(end).getAddress();\n\n        return (endAddress - startAddress) <= MAX_CATCH_RANGE;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/SwitchData.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.io.Opcodes;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.IntList;\n\n/**\n * Pseudo-instruction which holds switch data. The switch data is\n * a map of values to target addresses, and this class writes the data\n * in either a \"packed\" or \"sparse\" form.\n */\npublic final class SwitchData extends VariableSizeInsn {\n    /**\n     * {@code non-null;} address representing the instruction that uses this\n     * instance\n     */\n    private final CodeAddress user;\n\n    /** {@code non-null;} sorted list of switch cases (keys) */\n    private final IntList cases;\n\n    /**\n     * {@code non-null;} corresponding list of code addresses; the branch\n     * target for each case\n     */\n    private final CodeAddress[] targets;\n\n    /** whether the output table will be packed (vs. sparse) */\n    private final boolean packed;\n\n    /**\n     * Constructs an instance. The output address of this instance is initially\n     * unknown ({@code -1}).\n     *\n     * @param position {@code non-null;} source position\n     * @param user {@code non-null;} address representing the instruction that\n     * uses this instance\n     * @param cases {@code non-null;} sorted list of switch cases (keys)\n     * @param targets {@code non-null;} corresponding list of code addresses; the\n     * branch target for each case\n     */\n    public SwitchData(SourcePosition position, CodeAddress user,\n                      IntList cases, CodeAddress[] targets) {\n        super(position, RegisterSpecList.EMPTY);\n\n        if (user == null) {\n            throw new NullPointerException(\"user == null\");\n        }\n\n        if (cases == null) {\n            throw new NullPointerException(\"cases == null\");\n        }\n\n        if (targets == null) {\n            throw new NullPointerException(\"targets == null\");\n        }\n\n        int sz = cases.size();\n\n        if (sz != targets.length) {\n            throw new IllegalArgumentException(\"cases / targets mismatch\");\n        }\n\n        if (sz > 65535) {\n            throw new IllegalArgumentException(\"too many cases\");\n        }\n\n        this.user = user;\n        this.cases = cases;\n        this.targets = targets;\n        this.packed = shouldPack(cases);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return packed ? (int) packedCodeSize(cases) :\n            (int) sparseCodeSize(cases);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out) {\n        int baseAddress = user.getAddress();\n        int defaultTarget = Dops.PACKED_SWITCH.getFormat().codeSize();\n        int sz = targets.length;\n\n        if (packed) {\n            int firstCase = (sz == 0) ? 0 : cases.get(0);\n            int lastCase = (sz == 0) ? 0 : cases.get(sz - 1);\n            int outSz = lastCase - firstCase + 1;\n\n            out.writeShort(Opcodes.PACKED_SWITCH_PAYLOAD);\n            out.writeShort(outSz);\n            out.writeInt(firstCase);\n\n            int caseAt = 0;\n            for (int i = 0; i < outSz; i++) {\n                int outCase = firstCase + i;\n                int oneCase = cases.get(caseAt);\n                int relTarget;\n\n                if (oneCase > outCase) {\n                    relTarget = defaultTarget;\n                } else {\n                    relTarget = targets[caseAt].getAddress() - baseAddress;\n                    caseAt++;\n                }\n\n                out.writeInt(relTarget);\n            }\n        } else {\n            out.writeShort(Opcodes.SPARSE_SWITCH_PAYLOAD);\n            out.writeShort(sz);\n\n            for (int i = 0; i < sz; i++) {\n                out.writeInt(cases.get(i));\n            }\n\n            for (int i = 0; i < sz; i++) {\n                int relTarget = targets[i].getAddress() - baseAddress;\n                out.writeInt(relTarget);\n            }\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withRegisters(RegisterSpecList registers) {\n        return new SwitchData(getPosition(), user, cases, targets);\n    }\n\n    /**\n     * Returns whether or not this instance's data will be output as packed.\n     *\n     * @return {@code true} iff the data is to be packed\n     */\n    public boolean isPacked() {\n        return packed;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String argString() {\n        StringBuffer sb = new StringBuffer(100);\n\n        int sz = targets.length;\n        for (int i = 0; i < sz; i++) {\n            sb.append(\"\\n    \");\n            sb.append(cases.get(i));\n            sb.append(\": \");\n            sb.append(targets[i]);\n        }\n\n        return sb.toString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String listingString0(boolean noteIndices) {\n        int baseAddress = user.getAddress();\n        StringBuffer sb = new StringBuffer(100);\n        int sz = targets.length;\n\n        sb.append(packed ? \"packed\" : \"sparse\");\n        sb.append(\"-switch-payload // for switch @ \");\n        sb.append(Hex.u2(baseAddress));\n\n        for (int i = 0; i < sz; i++) {\n            int absTarget = targets[i].getAddress();\n            int relTarget = absTarget - baseAddress;\n            sb.append(\"\\n  \");\n            sb.append(cases.get(i));\n            sb.append(\": \");\n            sb.append(Hex.u4(absTarget));\n            sb.append(\" // \");\n            sb.append(Hex.s4(relTarget));\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Gets the size of a packed table for the given cases, in 16-bit code\n     * units.\n     *\n     * @param cases {@code non-null;} sorted list of cases\n     * @return {@code >= -1;} the packed table size or {@code -1} if the\n     * cases couldn't possibly be represented as a packed table\n     */\n    private static long packedCodeSize(IntList cases) {\n        int sz = cases.size();\n        long low = cases.get(0);\n        long high = cases.get(sz - 1);\n        long result = ((high - low + 1)) * 2 + 4;\n\n        return (result <= 0x7fffffff) ? result : -1;\n    }\n\n    /**\n     * Gets the size of a sparse table for the given cases, in 16-bit code\n     * units.\n     *\n     * @param cases {@code non-null;} sorted list of cases\n     * @return {@code > 0;} the sparse table size\n     */\n    private static long sparseCodeSize(IntList cases) {\n        int sz = cases.size();\n\n        return (sz * 4L) + 2;\n    }\n\n    /**\n     * Determines whether the given list of cases warrant being packed.\n     *\n     * @param cases {@code non-null;} sorted list of cases\n     * @return {@code true} iff the table encoding the cases\n     * should be packed\n     */\n    private static boolean shouldPack(IntList cases) {\n        int sz = cases.size();\n\n        if (sz < 2) {\n            return true;\n        }\n\n        long packedSize = packedCodeSize(cases);\n        long sparseSize = sparseCodeSize(cases);\n\n        /*\n         * We pick the packed representation if it is possible and\n         * would be as small or smaller than 5/4 of the sparse\n         * representation. That is, we accept some size overhead on\n         * the packed representation, since that format is faster to\n         * execute at runtime.\n         */\n        return (packedSize >= 0) && (packedSize <= ((sparseSize * 5) / 4));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/TargetInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.SourcePosition;\n\n/**\n * Instruction which has a single branch target.\n */\npublic final class TargetInsn extends FixedSizeInsn {\n    /** {@code non-null;} the branch target */\n    private CodeAddress target;\n\n    /**\n     * Constructs an instance. The output address of this instance is initially\n     * unknown ({@code -1}), and the target is initially\n     * {@code null}.\n     *\n     * @param opcode the opcode; one of the constants from {@link Dops}\n     * @param position {@code non-null;} source position\n     * @param registers {@code non-null;} register list, including a\n     * result register if appropriate (that is, registers may be either\n     * ins or outs)\n     * @param target {@code non-null;} the branch target\n     */\n    public TargetInsn(Dop opcode, SourcePosition position,\n                      RegisterSpecList registers, CodeAddress target) {\n        super(opcode, position, registers);\n\n        if (target == null) {\n            throw new NullPointerException(\"target == null\");\n        }\n\n        this.target = target;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withOpcode(Dop opcode) {\n        return new TargetInsn(opcode, getPosition(), getRegisters(), target);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withRegisters(RegisterSpecList registers) {\n        return new TargetInsn(getOpcode(), getPosition(), registers, target);\n    }\n\n    /**\n     * Returns an instance that is just like this one, except that its\n     * opcode has the opposite sense (as a test; e.g. a\n     * {@code lt} test becomes a {@code ge}), and its branch\n     * target is replaced by the one given, and all set-once values\n     * associated with the class (such as its address) are reset.\n     *\n     * @param target {@code non-null;} the new branch target\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public TargetInsn withNewTargetAndReversed(CodeAddress target) {\n        Dop opcode = getOpcode().getOppositeTest();\n\n        return new TargetInsn(opcode, getPosition(), getRegisters(), target);\n    }\n\n    /**\n     * Gets the unique branch target of this instruction.\n     *\n     * @return {@code non-null;} the branch target\n     */\n    public CodeAddress getTarget() {\n        return target;\n    }\n\n    /**\n     * Gets the target address of this instruction. This is only valid\n     * to call if the target instruction has been assigned an address,\n     * and it is merely a convenient shorthand for\n     * {@code getTarget().getAddress()}.\n     *\n     * @return {@code >= 0;} the target address\n     */\n    public int getTargetAddress() {\n        return target.getAddress();\n    }\n\n    /**\n     * Gets the branch offset of this instruction. This is only valid to\n     * call if both this and the target instruction each has been assigned\n     * an address, and it is merely a convenient shorthand for\n     * {@code getTargetAddress() - getAddress()}.\n     *\n     * @return the branch offset\n     */\n    public int getTargetOffset() {\n        return target.getAddress() - getAddress();\n    }\n\n    /**\n     * Returns whether the target offset is known.\n     *\n     * @return {@code true} if the target offset is known or\n     * {@code false} if not\n     */\n    public boolean hasTargetOffset() {\n        return hasAddress() && target.hasAddress();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String argString() {\n        if (target == null) {\n            return \"????\";\n        }\n\n        return target.identifierString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/VariableSizeInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.SourcePosition;\n\n/**\n * Pseudo-instruction base class for variable-sized instructions.\n */\npublic abstract class VariableSizeInsn extends DalvInsn {\n    /**\n     * Constructs an instance. The output address of this instance is initially\n     * unknown ({@code -1}).\n     *\n     * @param position {@code non-null;} source position\n     * @param registers {@code non-null;} source registers\n     */\n    public VariableSizeInsn(SourcePosition position,\n                            RegisterSpecList registers) {\n        super(Dops.SPECIAL_FORMAT, position, registers);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final DalvInsn withOpcode(Dop opcode) {\n        throw new RuntimeException(\"unsupported\");\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final DalvInsn withRegisterOffset(int delta) {\n        return withRegisters(getRegisters().withOffset(delta));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/ZeroSizeInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code;\n\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.util.AnnotatedOutput;\n\n/**\n * Pseudo-instruction base class for zero-size (no code emitted)\n * instructions, which are generally used for tracking metainformation\n * about the code they are adjacent to.\n */\npublic abstract class ZeroSizeInsn extends DalvInsn {\n    /**\n     * Constructs an instance. The output address of this instance is initially\n     * unknown ({@code -1}).\n     *\n     * @param position {@code non-null;} source position\n     */\n    public ZeroSizeInsn(SourcePosition position) {\n        super(Dops.SPECIAL_FORMAT, position, RegisterSpecList.EMPTY);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final int codeSize() {\n        return 0;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final void writeTo(AnnotatedOutput out) {\n        // Nothing to do here, for this class.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final DalvInsn withOpcode(Dop opcode) {\n        throw new RuntimeException(\"unsupported\");\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public DalvInsn withRegisterOffset(int delta) {\n        return withRegisters(getRegisters().withOffset(delta));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form10t.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.dex.code.TargetInsn;\nimport com.taobao.android.dx.util.AnnotatedOutput;\n\n/**\n * Instruction format {@code 10t}. See the instruction format spec\n * for details.\n */\npublic final class Form10t extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form10t();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form10t() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        return branchString(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        return branchComment(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 1;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        if (!((insn instanceof TargetInsn) &&\n              (insn.getRegisters().size() == 0))) {\n            return false;\n        }\n\n        TargetInsn ti = (TargetInsn) insn;\n        return ti.hasTargetOffset() ? branchFits(ti) : true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean branchFits(TargetInsn insn) {\n        int offset = insn.getTargetOffset();\n\n        // Note: A zero offset would fit, but it is prohibited by the spec.\n        return (offset != 0) && signedFitsInByte(offset);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        int offset = ((TargetInsn) insn).getTargetOffset();\n\n        write(out, opcodeUnit(insn, (offset & 0xff)));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form10x.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.dex.code.SimpleInsn;\nimport com.taobao.android.dx.util.AnnotatedOutput;\n\n/**\n * Instruction format {@code 10x}. See the instruction format spec\n * for details.\n */\npublic final class Form10x extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form10x();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form10x() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        // This format has no arguments.\n        return \"\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        // This format has no comment.\n        return \"\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 1;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        return (insn instanceof SimpleInsn) &&\n            (insn.getRegisters().size() == 0);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        write(out, opcodeUnit(insn, 0));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form11n.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.CstInsn;\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstLiteralBits;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 11n}. See the instruction format spec\n * for details.\n */\npublic final class Form11n extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form11n();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form11n() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();\n\n        return regs.get(0).regString() + \", \" + literalBitsString(value);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();\n        return literalBitsComment(value, 4);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 1;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n\n        if (!((insn instanceof CstInsn) &&\n              (regs.size() == 1) &&\n              unsignedFitsInNibble(regs.get(0).getReg()))) {\n            return false;\n        }\n\n        CstInsn ci = (CstInsn) insn;\n        Constant cst = ci.getConstant();\n\n        if (!(cst instanceof CstLiteralBits)) {\n            return false;\n        }\n\n        CstLiteralBits cb = (CstLiteralBits) cst;\n\n        return cb.fitsInInt() && signedFitsInNibble(cb.getIntBits());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(1);\n\n        bits.set(0, unsignedFitsInNibble(regs.get(0).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int value =\n            ((CstLiteralBits) ((CstInsn) insn).getConstant()).getIntBits();\n\n        write(out,\n              opcodeUnit(insn, makeByte(regs.get(0).getReg(), value & 0xf)));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form11x.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.dex.code.SimpleInsn;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 11x}. See the instruction format spec\n * for details.\n */\npublic final class Form11x extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form11x();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form11x() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        return regs.get(0).regString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        // This format has no comment.\n        return \"\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 1;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        return (insn instanceof SimpleInsn) &&\n            (regs.size() == 1) &&\n            unsignedFitsInByte(regs.get(0).getReg());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(1);\n\n        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        write(out, opcodeUnit(insn, regs.get(0).getReg()));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form12x.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.dex.code.SimpleInsn;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 12x}. See the instruction format spec\n * for details.\n */\npublic final class Form12x extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form12x();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form12x() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int sz = regs.size();\n\n        /*\n         * The (sz - 2) and (sz - 1) below makes this code work for\n         * both the two- and three-register ops. (See \"case 3\" in\n         * isCompatible(), below.)\n         */\n\n        return regs.get(sz - 2).regString() + \", \" +\n            regs.get(sz - 1).regString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        // This format has no comment.\n        return \"\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 1;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        if (!(insn instanceof SimpleInsn)) {\n            return false;\n        }\n\n        RegisterSpecList regs = insn.getRegisters();\n        RegisterSpec rs1;\n        RegisterSpec rs2;\n\n        switch (regs.size()) {\n            case 2: {\n                rs1 = regs.get(0);\n                rs2 = regs.get(1);\n                break;\n            }\n            case 3: {\n                /*\n                 * This format is allowed for ops that are effectively\n                 * 3-arg but where the first two args are identical.\n                 */\n                rs1 = regs.get(1);\n                rs2 = regs.get(2);\n                if (rs1.getReg() != regs.get(0).getReg()) {\n                    return false;\n                }\n                break;\n            }\n            default: {\n                return false;\n            }\n        }\n\n        return unsignedFitsInNibble(rs1.getReg()) &&\n            unsignedFitsInNibble(rs2.getReg());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(2);\n        int r0 = regs.get(0).getReg();\n        int r1 = regs.get(1).getReg();\n\n        switch (regs.size()) {\n          case 2: {\n            bits.set(0, unsignedFitsInNibble(r0));\n            bits.set(1, unsignedFitsInNibble(r1));\n            break;\n          }\n          case 3: {\n            if (r0 != r1) {\n                bits.set(0, false);\n                bits.set(1, false);\n            } else {\n                boolean dstRegComp = unsignedFitsInNibble(r1);\n                bits.set(0, dstRegComp);\n                bits.set(1, dstRegComp);\n            }\n\n            bits.set(2, unsignedFitsInNibble(regs.get(2).getReg()));\n            break;\n          }\n          default: {\n            throw new AssertionError();\n          }\n        }\n\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int sz = regs.size();\n\n        /*\n         * The (sz - 2) and (sz - 1) below makes this code work for\n         * both the two- and three-register ops. (See \"case 3\" in\n         * isCompatible(), above.)\n         */\n\n        write(out, opcodeUnit(insn,\n                              makeByte(regs.get(sz - 2).getReg(),\n                                       regs.get(sz - 1).getReg())));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form20t.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.dex.code.TargetInsn;\nimport com.taobao.android.dx.util.AnnotatedOutput;\n\n/**\n * Instruction format {@code 20t}. See the instruction format spec\n * for details.\n */\npublic final class Form20t extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form20t();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form20t() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        return branchString(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        return branchComment(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 2;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        if (!((insn instanceof TargetInsn) &&\n              (insn.getRegisters().size() == 0))) {\n            return false;\n        }\n\n        TargetInsn ti = (TargetInsn) insn;\n        return ti.hasTargetOffset() ? branchFits(ti) : true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean branchFits(TargetInsn insn) {\n        int offset = insn.getTargetOffset();\n\n        // Note: A zero offset would fit, but it is prohibited by the spec.\n        return (offset != 0) && signedFitsInShort(offset);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        int offset = ((TargetInsn) insn).getTargetOffset();\n\n        write(out, opcodeUnit(insn, 0), (short) offset);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form21c.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.CstInsn;\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 21c}. See the instruction format spec\n * for details.\n */\npublic final class Form21c extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form21c();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form21c() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        return regs.get(0).regString() + \", \" + cstString(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        if (noteIndices) {\n            return cstComment(insn);\n        } else {\n            return \"\";\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 2;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        if (!(insn instanceof CstInsn)) {\n            return false;\n        }\n\n        RegisterSpecList regs = insn.getRegisters();\n        RegisterSpec reg;\n\n        switch (regs.size()) {\n            case 1: {\n                reg = regs.get(0);\n                break;\n            }\n            case 2: {\n                /*\n                 * This format is allowed for ops that are effectively\n                 * 2-arg but where the two args are identical.\n                 */\n                reg = regs.get(0);\n                if (reg.getReg() != regs.get(1).getReg()) {\n                    return false;\n                }\n                break;\n            }\n            default: {\n                return false;\n            }\n        }\n\n        if (!unsignedFitsInByte(reg.getReg())) {\n            return false;\n        }\n\n        CstInsn ci = (CstInsn) insn;\n        int cpi = ci.getIndex();\n        Constant cst = ci.getConstant();\n\n        if (! unsignedFitsInShort(cpi)) {\n            return false;\n        }\n\n        return (cst instanceof CstType) ||\n            (cst instanceof CstFieldRef) ||\n            (cst instanceof CstString);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int sz = regs.size();\n        BitSet bits = new BitSet(sz);\n        boolean compat = unsignedFitsInByte(regs.get(0).getReg());\n\n        if (sz == 1) {\n            bits.set(0, compat);\n        } else {\n            if (regs.get(0).getReg() == regs.get(1).getReg()) {\n                bits.set(0, compat);\n                bits.set(1, compat);\n            }\n        }\n\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int cpi = ((CstInsn) insn).getIndex();\n\n        write(out,\n              opcodeUnit(insn, regs.get(0).getReg()),\n              (short) cpi);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form21h.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.CstInsn;\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstLiteralBits;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 21h}. See the instruction format spec\n * for details.\n */\npublic final class Form21h extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form21h();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form21h() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();\n\n        return regs.get(0).regString() + \", \" + literalBitsString(value);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        RegisterSpecList regs = insn.getRegisters();\n        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();\n\n        return\n            literalBitsComment(value,\n                    (regs.get(0).getCategory() == 1) ? 32 : 64);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 2;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        if (!((insn instanceof CstInsn) &&\n              (regs.size() == 1) &&\n              unsignedFitsInByte(regs.get(0).getReg()))) {\n            return false;\n        }\n\n        CstInsn ci = (CstInsn) insn;\n        Constant cst = ci.getConstant();\n\n        if (!(cst instanceof CstLiteralBits)) {\n            return false;\n        }\n\n        CstLiteralBits cb = (CstLiteralBits) cst;\n\n        // Where the high bits are depends on the category of the target.\n        if (regs.get(0).getCategory() == 1) {\n            int bits = cb.getIntBits();\n            return ((bits & 0xffff) == 0);\n        } else {\n            long bits = cb.getLongBits();\n            return ((bits & 0xffffffffffffL) == 0);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(1);\n\n        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        CstLiteralBits cb = (CstLiteralBits) ((CstInsn) insn).getConstant();\n        short bits;\n\n        // Where the high bits are depends on the category of the target.\n        if (regs.get(0).getCategory() == 1) {\n            bits = (short) (cb.getIntBits() >>> 16);\n        } else {\n            bits = (short) (cb.getLongBits() >>> 48);\n        }\n\n        write(out, opcodeUnit(insn, regs.get(0).getReg()), bits);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form21s.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.CstInsn;\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstLiteralBits;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 21s}. See the instruction format spec\n * for details.\n */\npublic final class Form21s extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form21s();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form21s() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();\n\n        return regs.get(0).regString() + \", \" + literalBitsString(value);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();\n        return literalBitsComment(value, 16);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 2;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        if (!((insn instanceof CstInsn) &&\n              (regs.size() == 1) &&\n              unsignedFitsInByte(regs.get(0).getReg()))) {\n            return false;\n        }\n\n        CstInsn ci = (CstInsn) insn;\n        Constant cst = ci.getConstant();\n\n        if (!(cst instanceof CstLiteralBits)) {\n            return false;\n        }\n\n        CstLiteralBits cb = (CstLiteralBits) cst;\n\n        return cb.fitsInInt() && signedFitsInShort(cb.getIntBits());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(1);\n\n        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int value =\n            ((CstLiteralBits) ((CstInsn) insn).getConstant()).getIntBits();\n\n        write(out,\n              opcodeUnit(insn, regs.get(0).getReg()),\n              (short) value);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form21t.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.dex.code.TargetInsn;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 21t}. See the instruction format spec\n * for details.\n */\npublic final class Form21t extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form21t();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form21t() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        return regs.get(0).regString() + \", \" + branchString(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        return branchComment(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 2;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n\n        if (!((insn instanceof TargetInsn) &&\n              (regs.size() == 1) &&\n              unsignedFitsInByte(regs.get(0).getReg()))) {\n            return false;\n        }\n\n        TargetInsn ti = (TargetInsn) insn;\n        return ti.hasTargetOffset() ? branchFits(ti) : true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(1);\n\n        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean branchFits(TargetInsn insn) {\n        int offset = insn.getTargetOffset();\n\n        // Note: A zero offset would fit, but it is prohibited by the spec.\n        return (offset != 0) && signedFitsInShort(offset);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int offset = ((TargetInsn) insn).getTargetOffset();\n\n        write(out,\n              opcodeUnit(insn, regs.get(0).getReg()),\n              (short) offset);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form22b.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.CstInsn;\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstLiteralBits;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 22b}. See the instruction format spec\n * for details.\n */\npublic final class Form22b extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form22b();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form22b() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();\n\n        return regs.get(0).regString() + \", \" + regs.get(1).regString() +\n            \", \" + literalBitsString(value);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();\n        return literalBitsComment(value, 8);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 2;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        if (!((insn instanceof CstInsn) &&\n              (regs.size() == 2) &&\n              unsignedFitsInByte(regs.get(0).getReg()) &&\n              unsignedFitsInByte(regs.get(1).getReg()))) {\n            return false;\n        }\n\n        CstInsn ci = (CstInsn) insn;\n        Constant cst = ci.getConstant();\n\n        if (!(cst instanceof CstLiteralBits)) {\n            return false;\n        }\n\n        CstLiteralBits cb = (CstLiteralBits) cst;\n\n        return cb.fitsInInt() && signedFitsInByte(cb.getIntBits());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(2);\n\n        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));\n        bits.set(1, unsignedFitsInByte(regs.get(1).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int value =\n            ((CstLiteralBits) ((CstInsn) insn).getConstant()).getIntBits();\n\n        write(out,\n              opcodeUnit(insn, regs.get(0).getReg()),\n              codeUnit(regs.get(1).getReg(), value & 0xff));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form22c.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.CstInsn;\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 22c}. See the instruction format spec\n * for details.\n */\npublic final class Form22c extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form22c();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form22c() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        return regs.get(0).regString() + \", \" + regs.get(1).regString() +\n            \", \" + cstString(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        if (noteIndices) {\n            return cstComment(insn);\n        } else {\n            return \"\";\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 2;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        if (!((insn instanceof CstInsn) &&\n              (regs.size() == 2) &&\n              unsignedFitsInNibble(regs.get(0).getReg()) &&\n              unsignedFitsInNibble(regs.get(1).getReg()))) {\n            return false;\n        }\n\n        CstInsn ci = (CstInsn) insn;\n        int cpi = ci.getIndex();\n\n        if (! unsignedFitsInShort(cpi)) {\n            return false;\n        }\n\n        Constant cst = ci.getConstant();\n        return (cst instanceof CstType) ||\n            (cst instanceof CstFieldRef);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(2);\n\n        bits.set(0, unsignedFitsInNibble(regs.get(0).getReg()));\n        bits.set(1, unsignedFitsInNibble(regs.get(1).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int cpi = ((CstInsn) insn).getIndex();\n\n        write(out,\n              opcodeUnit(insn,\n                         makeByte(regs.get(0).getReg(), regs.get(1).getReg())),\n              (short) cpi);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form22s.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.CstInsn;\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstLiteralBits;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 22s}. See the instruction format spec\n * for details.\n */\npublic final class Form22s extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form22s();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form22s() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();\n\n        return regs.get(0).regString() + \", \" + regs.get(1).regString()\n            + \", \" + literalBitsString(value);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();\n        return literalBitsComment(value, 16);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 2;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        if (!((insn instanceof CstInsn) &&\n              (regs.size() == 2) &&\n              unsignedFitsInNibble(regs.get(0).getReg()) &&\n              unsignedFitsInNibble(regs.get(1).getReg()))) {\n            return false;\n        }\n\n        CstInsn ci = (CstInsn) insn;\n        Constant cst = ci.getConstant();\n\n        if (!(cst instanceof CstLiteralBits)) {\n            return false;\n        }\n\n        CstLiteralBits cb = (CstLiteralBits) cst;\n\n        return cb.fitsInInt() && signedFitsInShort(cb.getIntBits());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(2);\n\n        bits.set(0, unsignedFitsInNibble(regs.get(0).getReg()));\n        bits.set(1, unsignedFitsInNibble(regs.get(1).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int value =\n            ((CstLiteralBits) ((CstInsn) insn).getConstant()).getIntBits();\n\n        write(out,\n              opcodeUnit(insn,\n                         makeByte(regs.get(0).getReg(), regs.get(1).getReg())),\n              (short) value);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form22t.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.dex.code.TargetInsn;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 22t}. See the instruction format spec\n * for details.\n */\npublic final class Form22t extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form22t();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form22t() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        return regs.get(0).regString() + \", \" + regs.get(1).regString() +\n            \", \" + branchString(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        return branchComment(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 2;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n\n        if (!((insn instanceof TargetInsn) &&\n              (regs.size() == 2) &&\n              unsignedFitsInNibble(regs.get(0).getReg()) &&\n              unsignedFitsInNibble(regs.get(1).getReg()))) {\n            return false;\n        }\n\n        TargetInsn ti = (TargetInsn) insn;\n        return ti.hasTargetOffset() ? branchFits(ti) : true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(2);\n\n        bits.set(0, unsignedFitsInNibble(regs.get(0).getReg()));\n        bits.set(1, unsignedFitsInNibble(regs.get(1).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean branchFits(TargetInsn insn) {\n        int offset = insn.getTargetOffset();\n\n        // Note: A zero offset would fit, but it is prohibited by the spec.\n        return (offset != 0) && signedFitsInShort(offset);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int offset = ((TargetInsn) insn).getTargetOffset();\n\n        write(out,\n              opcodeUnit(insn,\n                         makeByte(regs.get(0).getReg(), regs.get(1).getReg())),\n              (short) offset);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form22x.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.dex.code.SimpleInsn;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 22x}. See the instruction format spec\n * for details.\n */\npublic final class Form22x extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form22x();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form22x() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        return regs.get(0).regString() + \", \" + regs.get(1).regString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        // This format has no comment.\n        return \"\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 2;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n\n        return (insn instanceof SimpleInsn) &&\n            (regs.size() == 2) &&\n            unsignedFitsInByte(regs.get(0).getReg()) &&\n            unsignedFitsInShort(regs.get(1).getReg());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(2);\n\n        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));\n        bits.set(1, unsignedFitsInShort(regs.get(1).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        write(out,\n              opcodeUnit(insn, regs.get(0).getReg()),\n              (short) regs.get(1).getReg());\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form23x.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.dex.code.SimpleInsn;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 23x}. See the instruction format spec\n * for details.\n */\npublic final class Form23x extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form23x();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form23x() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        return regs.get(0).regString() + \", \" + regs.get(1).regString() +\n            \", \" + regs.get(2).regString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        // This format has no comment.\n        return \"\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 2;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n\n        return (insn instanceof SimpleInsn) &&\n            (regs.size() == 3) &&\n            unsignedFitsInByte(regs.get(0).getReg()) &&\n            unsignedFitsInByte(regs.get(1).getReg()) &&\n            unsignedFitsInByte(regs.get(2).getReg());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(3);\n\n        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));\n        bits.set(1, unsignedFitsInByte(regs.get(1).getReg()));\n        bits.set(2, unsignedFitsInByte(regs.get(2).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        write(out,\n              opcodeUnit(insn, regs.get(0).getReg()),\n              codeUnit(regs.get(1).getReg(), regs.get(2).getReg()));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form30t.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.dex.code.TargetInsn;\nimport com.taobao.android.dx.util.AnnotatedOutput;\n\n/**\n * Instruction format {@code 30t}. See the instruction format spec\n * for details.\n */\npublic final class Form30t extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form30t();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form30t() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        return branchString(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        return branchComment(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 3;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        if (!((insn instanceof TargetInsn) &&\n              (insn.getRegisters().size() == 0))) {\n            return false;\n        }\n\n        return true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean branchFits(TargetInsn insn) {\n        return true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        int offset = ((TargetInsn) insn).getTargetOffset();\n\n        write(out, opcodeUnit(insn, 0), offset);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form31c.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.CstInsn;\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 31c}. See the instruction format spec\n * for details.\n */\npublic final class Form31c extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form31c();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form31c() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        return regs.get(0).regString() + \", \" + cstString(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        if (noteIndices) {\n            return cstComment(insn);\n        } else {\n            return \"\";\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 3;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        if (!(insn instanceof CstInsn)) {\n            return false;\n        }\n\n        RegisterSpecList regs = insn.getRegisters();\n        RegisterSpec reg;\n\n        switch (regs.size()) {\n            case 1: {\n                reg = regs.get(0);\n                break;\n            }\n            case 2: {\n                /*\n                 * This format is allowed for ops that are effectively\n                 * 2-arg but where the two args are identical.\n                 */\n                reg = regs.get(0);\n                if (reg.getReg() != regs.get(1).getReg()) {\n                    return false;\n                }\n                break;\n            }\n            default: {\n                return false;\n            }\n        }\n\n        if (!unsignedFitsInByte(reg.getReg())) {\n            return false;\n        }\n\n        CstInsn ci = (CstInsn) insn;\n        Constant cst = ci.getConstant();\n\n        return (cst instanceof CstType) ||\n            (cst instanceof CstFieldRef) ||\n            (cst instanceof CstString);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int sz = regs.size();\n        BitSet bits = new BitSet(sz);\n        boolean compat = unsignedFitsInByte(regs.get(0).getReg());\n\n        if (sz == 1) {\n            bits.set(0, compat);\n        } else {\n            if (regs.get(0).getReg() == regs.get(1).getReg()) {\n                bits.set(0, compat);\n                bits.set(1, compat);\n            }\n        }\n\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int cpi = ((CstInsn) insn).getIndex();\n\n        write(out, opcodeUnit(insn, regs.get(0).getReg()), cpi);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form31i.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.CstInsn;\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstLiteralBits;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 31i}. See the instruction format spec\n * for details.\n */\npublic final class Form31i extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form31i();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form31i() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();\n\n        return regs.get(0).regString() + \", \" + literalBitsString(value);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();\n        return literalBitsComment(value, 32);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 3;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        if (!((insn instanceof CstInsn) &&\n              (regs.size() == 1) &&\n              unsignedFitsInByte(regs.get(0).getReg()))) {\n            return false;\n        }\n\n        CstInsn ci = (CstInsn) insn;\n        Constant cst = ci.getConstant();\n\n        if (!(cst instanceof CstLiteralBits)) {\n            return false;\n        }\n\n        return ((CstLiteralBits) cst).fitsInInt();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(1);\n\n        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int value =\n            ((CstLiteralBits) ((CstInsn) insn).getConstant()).getIntBits();\n\n        write(out, opcodeUnit(insn, regs.get(0).getReg()), value);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form31t.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.dex.code.TargetInsn;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 31t}. See the instruction format spec\n * for details.\n */\npublic final class Form31t extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form31t();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form31t() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        return regs.get(0).regString() + \", \" + branchString(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        return branchComment(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 3;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n\n        if (!((insn instanceof TargetInsn) &&\n              (regs.size() == 1) &&\n              unsignedFitsInByte(regs.get(0).getReg()))) {\n            return false;\n        }\n\n        return true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(1);\n\n        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean branchFits(TargetInsn insn) {\n        return true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int offset = ((TargetInsn) insn).getTargetOffset();\n\n        write(out, opcodeUnit(insn, regs.get(0).getReg()), offset);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form32x.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.dex.code.SimpleInsn;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 32x}. See the instruction format spec\n * for details.\n */\npublic final class Form32x extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form32x();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form32x() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        return regs.get(0).regString() + \", \" + regs.get(1).regString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        // This format has no comment.\n        return \"\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 3;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        return (insn instanceof SimpleInsn) &&\n            (regs.size() == 2) &&\n            unsignedFitsInShort(regs.get(0).getReg()) &&\n            unsignedFitsInShort(regs.get(1).getReg());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(2);\n\n        bits.set(0, unsignedFitsInShort(regs.get(0).getReg()));\n        bits.set(1, unsignedFitsInShort(regs.get(1).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n\n        write(out,\n              opcodeUnit(insn, 0),\n              (short) regs.get(0).getReg(),\n              (short) regs.get(1).getReg());\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form35c.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.CstInsn;\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 35c}. See the instruction format spec\n * for details.\n */\npublic final class Form35c extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form35c();\n\n    /** Maximal number of operands */\n    private static final int MAX_NUM_OPS = 5;\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form35c() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = explicitize(insn.getRegisters());\n        return regListString(regs) + \", \" + cstString(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        if (noteIndices) {\n            return cstComment(insn);\n        } else {\n            return \"\";\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 3;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        if (!(insn instanceof CstInsn)) {\n            return false;\n        }\n\n        CstInsn ci = (CstInsn) insn;\n        int cpi = ci.getIndex();\n\n        if (! unsignedFitsInShort(cpi)) {\n            return false;\n        }\n\n        Constant cst = ci.getConstant();\n        if (!((cst instanceof CstMethodRef) ||\n              (cst instanceof CstType))) {\n            return false;\n        }\n\n        RegisterSpecList regs = ci.getRegisters();\n        return (wordCount(regs) >= 0);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int sz = regs.size();\n        BitSet bits = new BitSet(sz);\n\n        for (int i = 0; i < sz; i++) {\n            RegisterSpec reg = regs.get(i);\n            /*\n             * The check below adds (category - 1) to the register, to\n             * account for the fact that the second half of a\n             * category-2 register has to be represented explicitly in\n             * the result.\n             */\n            bits.set(i, unsignedFitsInNibble(reg.getReg() +\n                                             reg.getCategory() - 1));\n        }\n\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        int cpi = ((CstInsn) insn).getIndex();\n        RegisterSpecList regs = explicitize(insn.getRegisters());\n        int sz = regs.size();\n        int r0 = (sz > 0) ? regs.get(0).getReg() : 0;\n        int r1 = (sz > 1) ? regs.get(1).getReg() : 0;\n        int r2 = (sz > 2) ? regs.get(2).getReg() : 0;\n        int r3 = (sz > 3) ? regs.get(3).getReg() : 0;\n        int r4 = (sz > 4) ? regs.get(4).getReg() : 0;\n\n        write(out,\n              opcodeUnit(insn,\n                         makeByte(r4, sz)), // encode the fifth operand here\n              (short) cpi,\n              codeUnit(r0, r1, r2, r3));\n    }\n\n    /**\n     * Gets the number of words required for the given register list, where\n     * category-2 values count as two words. Return {@code -1} if the\n     * list requires more than five words or contains registers that need\n     * more than a nibble to identify them.\n     *\n     * @param regs {@code non-null;} the register list in question\n     * @return {@code >= -1;} the number of words required, or {@code -1}\n     * if the list couldn't possibly fit in this format\n     */\n    private static int wordCount(RegisterSpecList regs) {\n        int sz = regs.size();\n\n        if (sz > MAX_NUM_OPS) {\n            // It can't possibly fit.\n            return -1;\n        }\n\n        int result = 0;\n\n        for (int i = 0; i < sz; i++) {\n            RegisterSpec one = regs.get(i);\n            result += one.getCategory();\n            /*\n             * The check below adds (category - 1) to the register, to\n             * account for the fact that the second half of a\n             * category-2 register has to be represented explicitly in\n             * the result.\n             */\n            if (!unsignedFitsInNibble(one.getReg() + one.getCategory() - 1)) {\n                return -1;\n            }\n        }\n\n        return (result <= MAX_NUM_OPS) ? result : -1;\n    }\n\n    /**\n     * Returns a register list which is equivalent to the given one,\n     * except that it splits category-2 registers into two explicit\n     * entries. This returns the original list if no modification is\n     * required\n     *\n     * @param orig {@code non-null;} the original list\n     * @return {@code non-null;} the list with the described transformation\n     */\n    private static RegisterSpecList explicitize(RegisterSpecList orig) {\n        int wordCount = wordCount(orig);\n        int sz = orig.size();\n\n        if (wordCount == sz) {\n            return orig;\n        }\n\n        RegisterSpecList result = new RegisterSpecList(wordCount);\n        int wordAt = 0;\n\n        for (int i = 0; i < sz; i++) {\n            RegisterSpec one = orig.get(i);\n            result.set(wordAt, one);\n            if (one.getCategory() == 2) {\n                result.set(wordAt + 1,\n                           RegisterSpec.make(one.getReg() + 1, Type.VOID));\n                wordAt += 2;\n            } else {\n                wordAt++;\n            }\n        }\n\n        result.setImmutable();\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form3rc.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.CstInsn;\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.util.AnnotatedOutput;\n\n/**\n * Instruction format {@code 3rc}. See the instruction format spec\n * for details.\n */\npublic final class Form3rc extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form3rc();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form3rc() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        return regRangeString(insn.getRegisters()) + \", \" +\n            cstString(insn);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        if (noteIndices) {\n            return cstComment(insn);\n        } else {\n            return \"\";\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 3;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        if (!(insn instanceof CstInsn)) {\n            return false;\n        }\n\n        CstInsn ci = (CstInsn) insn;\n        int cpi = ci.getIndex();\n        Constant cst = ci.getConstant();\n\n        if (! unsignedFitsInShort(cpi)) {\n            return false;\n        }\n\n        if (!((cst instanceof CstMethodRef) ||\n              (cst instanceof CstType))) {\n            return false;\n        }\n\n        RegisterSpecList regs = ci.getRegisters();\n        int sz = regs.size();\n\n        return (regs.size() == 0) ||\n            (isRegListSequential(regs) &&\n             unsignedFitsInShort(regs.get(0).getReg()) &&\n             unsignedFitsInByte(regs.getWordCount()));\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        int cpi = ((CstInsn) insn).getIndex();\n        int firstReg = (regs.size() == 0) ? 0 : regs.get(0).getReg();\n        int count = regs.getWordCount();\n\n        write(out, opcodeUnit(insn, count), (short) cpi, (short) firstReg);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/Form51l.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.CstInsn;\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstLiteral64;\nimport com.taobao.android.dx.rop.cst.CstLiteralBits;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.BitSet;\n\n/**\n * Instruction format {@code 51l}. See the instruction format spec\n * for details.\n */\npublic final class Form51l extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new Form51l();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private Form51l() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();\n\n        return regs.get(0).regString() + \", \" + literalBitsString(value);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();\n        return literalBitsComment(value, 64);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        return 5;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        if (!((insn instanceof CstInsn) &&\n              (regs.size() == 1) &&\n              unsignedFitsInByte(regs.get(0).getReg()))) {\n            return false;\n        }\n\n        CstInsn ci = (CstInsn) insn;\n        Constant cst = ci.getConstant();\n\n        return (cst instanceof CstLiteral64);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public BitSet compatibleRegs(DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        BitSet bits = new BitSet(1);\n\n        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        RegisterSpecList regs = insn.getRegisters();\n        long value =\n            ((CstLiteral64) ((CstInsn) insn).getConstant()).getLongBits();\n\n        write(out, opcodeUnit(insn, regs.get(0).getReg()), value);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/code/form/SpecialFormat.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.code.form;\n\nimport com.taobao.android.dx.dex.code.DalvInsn;\nimport com.taobao.android.dx.dex.code.InsnFormat;\nimport com.taobao.android.dx.util.AnnotatedOutput;\n\n/**\n * Instruction format for nonstandard format instructions, which aren't\n * generally real instructions but do end up appearing in instruction\n * lists. Most of the overridden methods on this class end up throwing\n * exceptions, as code should know (implicitly or explicitly) to avoid\n * using this class. The one exception is {@link #isCompatible}, which\n * always returns {@code true}.\n */\npublic final class SpecialFormat extends InsnFormat {\n    /** {@code non-null;} unique instance of this class */\n    public static final InsnFormat THE_ONE = new SpecialFormat();\n\n    /**\n     * Constructs an instance. This class is not publicly\n     * instantiable. Use {@link #THE_ONE}.\n     */\n    private SpecialFormat() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnArgString(DalvInsn insn) {\n        throw new RuntimeException(\"unsupported\");\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String insnCommentString(DalvInsn insn, boolean noteIndices) {\n        throw new RuntimeException(\"unsupported\");\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int codeSize() {\n        throw new RuntimeException(\"unsupported\");\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCompatible(DalvInsn insn) {\n        return true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(AnnotatedOutput out, DalvInsn insn) {\n        throw new RuntimeException(\"unsupported\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/AnnotationItem.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.annotation.Annotation;\nimport com.taobao.android.dx.rop.annotation.AnnotationVisibility;\nimport com.taobao.android.dx.rop.annotation.NameValuePair;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.ByteArrayAnnotatedOutput;\n\nimport java.util.Arrays;\nimport java.util.Comparator;\n\n/**\n * Single annotation, which consists of a type and a set of name-value\n * element pairs.\n */\npublic final class AnnotationItem extends OffsettedItem {\n    /** annotation visibility constant: visible at build time only */\n    private static final int VISIBILITY_BUILD = 0;\n\n    /** annotation visibility constant: visible at runtime */\n    private static final int VISIBILITY_RUNTIME = 1;\n\n    /** annotation visibility constant: visible at runtime only to system */\n    private static final int VISIBILITY_SYSTEM = 2;\n\n    /** the required alignment for instances of this class */\n    private static final int ALIGNMENT = 1;\n\n    /** {@code non-null;} unique instance of {@link #TypeIdSorter} */\n    private static final TypeIdSorter TYPE_ID_SORTER = new TypeIdSorter();\n\n    /** {@code non-null;} the annotation to represent */\n    private final Annotation annotation;\n\n    /**\n     * {@code null-ok;} type reference for the annotation type; set during\n     * {@link #addContents}\n     */\n    private TypeIdItem type;\n\n    /**\n     * {@code null-ok;} encoded form, ready for writing to a file; set during\n     * {@link #place0}\n     */\n    private byte[] encodedForm;\n\n    /**\n     * Comparator that sorts (outer) instances by type id index.\n     */\n    private static class TypeIdSorter implements Comparator<AnnotationItem> {\n        /** {@inheritDoc} */\n        public int compare(AnnotationItem item1, AnnotationItem item2) {\n            int index1 = item1.type.getIndex();\n            int index2 = item2.type.getIndex();\n\n            if (index1 < index2) {\n                return -1;\n            } else if (index1 > index2) {\n                return 1;\n            }\n\n            return 0;\n        }\n    }\n\n    /**\n     * Sorts an array of instances, in place, by type id index,\n     * ignoring all other aspects of the elements. This is only valid\n     * to use after type id indices are known.\n     *\n     * @param array {@code non-null;} array to sort\n     */\n    public static void sortByTypeIdIndex(AnnotationItem[] array) {\n        Arrays.sort(array, TYPE_ID_SORTER);\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param annotation {@code non-null;} annotation to represent\n     * @param dexFile {@code non-null;} dex output\n     */\n    public AnnotationItem(Annotation annotation, DexFile dexFile) {\n        /*\n         * The write size isn't known up-front because (the variable-lengthed)\n         * leb128 type is used to represent some things.\n         */\n        super(ALIGNMENT, -1);\n\n        if (annotation == null) {\n            throw new NullPointerException(\"annotation == null\");\n        }\n\n        this.annotation = annotation;\n        this.type = null;\n        this.encodedForm = null;\n        addContents(dexFile);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_ANNOTATION_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return annotation.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int compareTo0(OffsettedItem other) {\n        AnnotationItem otherAnnotation = (AnnotationItem) other;\n\n        return annotation.compareTo(otherAnnotation.annotation);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toHuman() {\n        return annotation.toHuman();\n    }\n\n    /** {@inheritDoc} */\n    public void addContents(DexFile file) {\n        type = file.getTypeIds().intern(annotation.getType());\n        ValueEncoder.addContents(file, annotation);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void place0(Section addedTo, int offset) {\n        // Encode the data and note the size.\n\n        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();\n        ValueEncoder encoder = new ValueEncoder(addedTo.getFile(), out);\n\n        encoder.writeAnnotation(annotation, false);\n        encodedForm = out.toByteArray();\n\n        // Add one for the visibility byte in front of the encoded annotation.\n        setWriteSize(encodedForm.length + 1);\n    }\n\n    /**\n     * Write a (listing file) annotation for this instance to the given\n     * output, that consumes no bytes of output. This is for annotating\n     * a reference to this instance at the point of the reference.\n     *\n     * @param out {@code non-null;} where to output to\n     * @param prefix {@code non-null;} prefix for each line of output\n     */\n    public void annotateTo(AnnotatedOutput out, String prefix) {\n        out.annotate(0, prefix + \"visibility: \" +\n                annotation.getVisibility().toHuman());\n        out.annotate(0, prefix + \"type: \" + annotation.getType().toHuman());\n\n        for (NameValuePair pair : annotation.getNameValuePairs()) {\n            CstString name = pair.getName();\n            Constant value = pair.getValue();\n\n            out.annotate(0, prefix + name.toHuman() + \": \" +\n                    ValueEncoder.constantToHuman(value));\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void writeTo0(DexFile file, AnnotatedOutput out) {\n        boolean annotates = out.annotates();\n        AnnotationVisibility visibility = annotation.getVisibility();\n\n        if (annotates) {\n            out.annotate(0, offsetString() + \" annotation\");\n            out.annotate(1, \"  visibility: VISBILITY_\" + visibility);\n        }\n\n        switch (visibility) {\n            case BUILD:   out.writeByte(VISIBILITY_BUILD); break;\n            case RUNTIME: out.writeByte(VISIBILITY_RUNTIME); break;\n            case SYSTEM:  out.writeByte(VISIBILITY_SYSTEM); break;\n            default: {\n                // EMBEDDED shouldn't appear at the top level.\n                throw new RuntimeException(\"shouldn't happen\");\n            }\n        }\n\n        if (annotates) {\n            /*\n             * The output is to be annotated, so redo the work previously\n             * done by place0(), except this time annotations will actually\n             * get emitted.\n             */\n            ValueEncoder encoder = new ValueEncoder(file, out);\n            encoder.writeAnnotation(annotation, true);\n        } else {\n            out.write(encodedForm);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/AnnotationSetItem.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.annotation.Annotation;\nimport com.taobao.android.dx.rop.annotation.Annotations;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Set of annotations, where no annotation type appears more than once.\n */\npublic final class AnnotationSetItem extends OffsettedItem {\n    /** the required alignment for instances of this class */\n    private static final int ALIGNMENT = 4;\n\n    /** the size of an entry int the set: one {@code uint} */\n    private static final int ENTRY_WRITE_SIZE = 4;\n\n    /** {@code non-null;} the set of annotations */\n    private final Annotations annotations;\n\n    /**\n     * {@code non-null;} set of annotations as individual items in an array.\n     * <b>Note:</b> The contents have to get sorted by type id before\n     * writing.\n     */\n    private final AnnotationItem[] items;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param annotations {@code non-null;} set of annotations\n     * @param dexFile {@code non-null;} dex output\n     */\n    public AnnotationSetItem(Annotations annotations, DexFile dexFile) {\n        super(ALIGNMENT, writeSize(annotations));\n\n        this.annotations = annotations;\n        this.items = new AnnotationItem[annotations.size()];\n\n        int at = 0;\n        for (Annotation a : annotations.getAnnotations()) {\n            items[at] = new AnnotationItem(a, dexFile);\n            at++;\n        }\n    }\n\n    /**\n     * Gets the write size for the given set.\n     *\n     * @param annotations {@code non-null;} the set\n     * @return {@code > 0;} the write size\n     */\n    private static int writeSize(Annotations annotations) {\n        // This includes an int size at the start of the list.\n\n        try {\n            return (annotations.size() * ENTRY_WRITE_SIZE) + 4;\n        } catch (NullPointerException ex) {\n            // Elucidate the exception.\n            throw new NullPointerException(\"list == null\");\n        }\n    }\n\n    /**\n     * Gets the underlying annotations of this instance\n     *\n     * @return {@code non-null;} the annotations\n     */\n    public Annotations getAnnotations() {\n        return annotations;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return annotations.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int compareTo0(OffsettedItem other) {\n        AnnotationSetItem otherSet = (AnnotationSetItem) other;\n\n        return annotations.compareTo(otherSet.annotations);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_ANNOTATION_SET_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toHuman() {\n        return annotations.toString();\n    }\n\n    /** {@inheritDoc} */\n    public void addContents(DexFile file) {\n        MixedItemSection byteData = file.getByteData();\n        int size = items.length;\n\n        for (int i = 0; i < size; i++) {\n            items[i] = byteData.intern(items[i]);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void place0(Section addedTo, int offset) {\n        // Sort the array to be in type id index order.\n        AnnotationItem.sortByTypeIdIndex(items);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void writeTo0(DexFile file, AnnotatedOutput out) {\n        boolean annotates = out.annotates();\n        int size = items.length;\n\n        if (annotates) {\n            out.annotate(0, offsetString() + \" annotation set\");\n            out.annotate(4, \"  size: \" + Hex.u4(size));\n        }\n\n        out.writeInt(size);\n\n        for (int i = 0; i < size; i++) {\n            AnnotationItem item = items[i];\n            int offset = item.getAbsoluteOffset();\n\n            if (annotates) {\n                out.annotate(4, \"  entries[\" + Integer.toHexString(i) + \"]: \" +\n                        Hex.u4(offset));\n                items[i].annotateTo(out, \"    \");\n            }\n\n            out.writeInt(offset);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/AnnotationSetRefItem.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Indirect reference to an {@link AnnotationSetItem}.\n */\npublic final class AnnotationSetRefItem extends OffsettedItem {\n    /** the required alignment for instances of this class */\n    private static final int ALIGNMENT = 4;\n\n    /** write size of this class, in bytes */\n    private static final int WRITE_SIZE = 4;\n\n    /** {@code non-null;} the annotation set to refer to */\n    private AnnotationSetItem annotations;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param annotations {@code non-null;} the annotation set to refer to\n     */\n    public AnnotationSetRefItem(AnnotationSetItem annotations) {\n        super(ALIGNMENT, WRITE_SIZE);\n\n        if (annotations == null) {\n            throw new NullPointerException(\"annotations == null\");\n        }\n\n        this.annotations = annotations;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_ANNOTATION_SET_REF_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    public void addContents(DexFile file) {\n        MixedItemSection wordData = file.getWordData();\n\n        annotations = wordData.intern(annotations);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toHuman() {\n        return annotations.toHuman();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void writeTo0(DexFile file, AnnotatedOutput out) {\n        int annotationsOff = annotations.getAbsoluteOffset();\n\n        if (out.annotates()) {\n            out.annotate(4, \"  annotations_off: \" + Hex.u4(annotationsOff));\n        }\n\n        out.writeInt(annotationsOff);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/AnnotationUtils.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport static com.taobao.android.dx.rop.annotation.AnnotationVisibility.SYSTEM;\n\nimport com.taobao.android.dx.rop.annotation.Annotation;\nimport com.taobao.android.dx.rop.annotation.NameValuePair;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstAnnotation;\nimport com.taobao.android.dx.rop.cst.CstArray;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.cst.CstKnownNull;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\n\nimport java.util.ArrayList;\n\n/**\n * Utility class for dealing with annotations.\n */\npublic final class AnnotationUtils {\n\n    /** {@code non-null;} type for {@code AnnotationDefault} annotations */\n    private static final CstType ANNOTATION_DEFAULT_TYPE =\n        CstType.intern(Type.intern(\"Ldalvik/annotation/AnnotationDefault;\"));\n\n    /** {@code non-null;} type for {@code EnclosingClass} annotations */\n    private static final CstType ENCLOSING_CLASS_TYPE =\n        CstType.intern(Type.intern(\"Ldalvik/annotation/EnclosingClass;\"));\n\n    /** {@code non-null;} type for {@code EnclosingMethod} annotations */\n    private static final CstType ENCLOSING_METHOD_TYPE =\n        CstType.intern(Type.intern(\"Ldalvik/annotation/EnclosingMethod;\"));\n\n    /** {@code non-null;} type for {@code InnerClass} annotations */\n    private static final CstType INNER_CLASS_TYPE =\n        CstType.intern(Type.intern(\"Ldalvik/annotation/InnerClass;\"));\n\n    /** {@code non-null;} type for {@code MemberClasses} annotations */\n    private static final CstType MEMBER_CLASSES_TYPE =\n        CstType.intern(Type.intern(\"Ldalvik/annotation/MemberClasses;\"));\n\n    /** {@code non-null;} type for {@code Signature} annotations */\n    private static final CstType SIGNATURE_TYPE =\n        CstType.intern(Type.intern(\"Ldalvik/annotation/Signature;\"));\n\n    /** {@code non-null;} type for {@code Throws} annotations */\n    private static final CstType THROWS_TYPE =\n        CstType.intern(Type.intern(\"Ldalvik/annotation/Throws;\"));\n\n    /** {@code non-null;} the UTF-8 constant {@code \"accessFlags\"} */\n    private static final CstString ACCESS_FLAGS_STRING = new CstString(\"accessFlags\");\n\n    /** {@code non-null;} the UTF-8 constant {@code \"name\"} */\n    private static final CstString NAME_STRING = new CstString(\"name\");\n\n    /** {@code non-null;} the UTF-8 constant {@code \"value\"} */\n    private static final CstString VALUE_STRING = new CstString(\"value\");\n\n    /**\n     * This class is uninstantiable.\n     */\n    private AnnotationUtils() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Constructs a standard {@code AnnotationDefault} annotation.\n     *\n     * @param defaults {@code non-null;} the defaults, itself as an annotation\n     * @return {@code non-null;} the constructed annotation\n     */\n    public static Annotation makeAnnotationDefault(Annotation defaults) {\n        Annotation result = new Annotation(ANNOTATION_DEFAULT_TYPE, SYSTEM);\n\n        result.put(new NameValuePair(VALUE_STRING, new CstAnnotation(defaults)));\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Constructs a standard {@code EnclosingClass} annotation.\n     *\n     * @param clazz {@code non-null;} the enclosing class\n     * @return {@code non-null;} the annotation\n     */\n    public static Annotation makeEnclosingClass(CstType clazz) {\n        Annotation result = new Annotation(ENCLOSING_CLASS_TYPE, SYSTEM);\n\n        result.put(new NameValuePair(VALUE_STRING, clazz));\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Constructs a standard {@code EnclosingMethod} annotation.\n     *\n     * @param method {@code non-null;} the enclosing method\n     * @return {@code non-null;} the annotation\n     */\n    public static Annotation makeEnclosingMethod(CstMethodRef method) {\n        Annotation result = new Annotation(ENCLOSING_METHOD_TYPE, SYSTEM);\n\n        result.put(new NameValuePair(VALUE_STRING, method));\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Constructs a standard {@code InnerClass} annotation.\n     *\n     * @param name {@code null-ok;} the original name of the class, or\n     * {@code null} to represent an anonymous class\n     * @param accessFlags the original access flags\n     * @return {@code non-null;} the annotation\n     */\n    public static Annotation makeInnerClass(CstString name, int accessFlags) {\n        Annotation result = new Annotation(INNER_CLASS_TYPE, SYSTEM);\n        Constant nameCst = (name != null) ? name : CstKnownNull.THE_ONE;\n\n        result.put(new NameValuePair(NAME_STRING, nameCst));\n        result.put(new NameValuePair(ACCESS_FLAGS_STRING,\n                        CstInteger.make(accessFlags)));\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Constructs a standard {@code MemberClasses} annotation.\n     *\n     * @param types {@code non-null;} the list of (the types of) the member classes\n     * @return {@code non-null;} the annotation\n     */\n    public static Annotation makeMemberClasses(TypeList types) {\n        CstArray array = makeCstArray(types);\n        Annotation result = new Annotation(MEMBER_CLASSES_TYPE, SYSTEM);\n        result.put(new NameValuePair(VALUE_STRING, array));\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Constructs a standard {@code Signature} annotation.\n     *\n     * @param signature {@code non-null;} the signature string\n     * @return {@code non-null;} the annotation\n     */\n    public static Annotation makeSignature(CstString signature) {\n        Annotation result = new Annotation(SIGNATURE_TYPE, SYSTEM);\n\n        /*\n         * Split the string into pieces that are likely to be common\n         * across many signatures and the rest of the file.\n         */\n\n        String raw = signature.getString();\n        int rawLength = raw.length();\n        ArrayList<String> pieces = new ArrayList<String>(20);\n\n        for (int at = 0; at < rawLength; /*at*/) {\n            char c = raw.charAt(at);\n            int endAt = at + 1;\n            if (c == 'L') {\n                // Scan to ';' or '<'. Consume ';' but not '<'.\n                while (endAt < rawLength) {\n                    c = raw.charAt(endAt);\n                    if (c == ';') {\n                        endAt++;\n                        break;\n                    } else if (c == '<') {\n                        break;\n                    }\n                    endAt++;\n                }\n            } else {\n                // Scan to 'L' without consuming it.\n                while (endAt < rawLength) {\n                    c = raw.charAt(endAt);\n                    if (c == 'L') {\n                        break;\n                    }\n                    endAt++;\n                }\n            }\n\n            pieces.add(raw.substring(at, endAt));\n            at = endAt;\n        }\n\n        int size = pieces.size();\n        CstArray.List list = new CstArray.List(size);\n\n        for (int i = 0; i < size; i++) {\n            list.set(i, new CstString(pieces.get(i)));\n        }\n\n        list.setImmutable();\n\n        result.put(new NameValuePair(VALUE_STRING, new CstArray(list)));\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Constructs a standard {@code Throws} annotation.\n     *\n     * @param types {@code non-null;} the list of thrown types\n     * @return {@code non-null;} the annotation\n     */\n    public static Annotation makeThrows(TypeList types) {\n        CstArray array = makeCstArray(types);\n        Annotation result = new Annotation(THROWS_TYPE, SYSTEM);\n        result.put(new NameValuePair(VALUE_STRING, array));\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Converts a {@link TypeList} to a {@link CstArray}.\n     *\n     * @param types {@code non-null;} the type list\n     * @return {@code non-null;} the corresponding array constant\n     */\n    private static CstArray makeCstArray(TypeList types) {\n        int size = types.size();\n        CstArray.List list = new CstArray.List(size);\n\n        for (int i = 0; i < size; i++) {\n            list.set(i, CstType.intern(types.getType(i)));\n        }\n\n        list.setImmutable();\n        return new CstArray(list);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/AnnotationsDirectoryItem.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.annotation.Annotations;\nimport com.taobao.android.dx.rop.annotation.AnnotationsList;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\n\nimport java.io.PrintWriter;\nimport java.util.ArrayList;\nimport java.util.Collections;\n\n/**\n * Per-class directory of annotations.\n */\npublic final class AnnotationsDirectoryItem extends OffsettedItem {\n    /** the required alignment for instances of this class */\n    private static final int ALIGNMENT = 4;\n\n    /** write size of this class's header, in bytes */\n    private static final int HEADER_SIZE = 16;\n\n    /** write size of a list element, in bytes */\n    private static final int ELEMENT_SIZE = 8;\n\n    /** {@code null-ok;} the class-level annotations, if any */\n    private AnnotationSetItem classAnnotations;\n\n    /** {@code null-ok;} the annotated fields, if any */\n    private ArrayList<FieldAnnotationStruct> fieldAnnotations;\n\n    /** {@code null-ok;} the annotated methods, if any */\n    private ArrayList<MethodAnnotationStruct> methodAnnotations;\n\n    /** {@code null-ok;} the annotated parameters, if any */\n    private ArrayList<ParameterAnnotationStruct> parameterAnnotations;\n\n    /**\n     * Constructs an empty instance.\n     */\n    public AnnotationsDirectoryItem() {\n        super(ALIGNMENT, -1);\n\n        classAnnotations = null;\n        fieldAnnotations = null;\n        methodAnnotations = null;\n        parameterAnnotations = null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM;\n    }\n\n    /**\n     * Returns whether this item is empty (has no contents).\n     *\n     * @return {@code true} if this item is empty, or {@code false}\n     * if not\n     */\n    public boolean isEmpty() {\n        return (classAnnotations == null) &&\n            (fieldAnnotations == null) &&\n            (methodAnnotations == null) &&\n            (parameterAnnotations == null);\n    }\n\n    /**\n     * Returns whether this item is a candidate for interning. The only\n     * interning candidates are ones that <i>only</i> have a non-null\n     * set of class annotations, with no other lists.\n     *\n     * @return {@code true} if this is an interning candidate, or\n     * {@code false} if not\n     */\n    public boolean isInternable() {\n        return (classAnnotations != null) &&\n            (fieldAnnotations == null) &&\n            (methodAnnotations == null) &&\n            (parameterAnnotations == null);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        if (classAnnotations == null) {\n            return 0;\n        }\n\n        return classAnnotations.hashCode();\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p><b>Note:</b>: This throws an exception if this item is not\n     * internable.</p>\n     *\n     * @see #isInternable\n     */\n    @Override\n    public int compareTo0(OffsettedItem other) {\n        if (! isInternable()) {\n            throw new UnsupportedOperationException(\"uninternable instance\");\n        }\n\n        AnnotationsDirectoryItem otherDirectory =\n            (AnnotationsDirectoryItem) other;\n        return classAnnotations.compareTo(otherDirectory.classAnnotations);\n    }\n\n    /**\n     * Sets the direct annotations on this instance. These are annotations\n     * made on the class, per se, as opposed to on one of its members.\n     * It is only valid to call this method at most once per instance.\n     *\n     * @param annotations {@code non-null;} annotations to set for this class\n     * @param dexFile {@code non-null;} dex output\n     */\n    public void setClassAnnotations(Annotations annotations, DexFile dexFile) {\n        if (annotations == null) {\n            throw new NullPointerException(\"annotations == null\");\n        }\n\n        if (classAnnotations != null) {\n            throw new UnsupportedOperationException(\n                    \"class annotations already set\");\n        }\n\n        classAnnotations = new AnnotationSetItem(annotations, dexFile);\n    }\n\n    /**\n     * Adds a field annotations item to this instance.\n     *\n     * @param field {@code non-null;} field in question\n     * @param annotations {@code non-null;} associated annotations to add\n     * @param dexFile {@code non-null;} dex output\n     */\n    public void addFieldAnnotations(CstFieldRef field,\n            Annotations annotations, DexFile dexFile) {\n        if (fieldAnnotations == null) {\n            fieldAnnotations = new ArrayList<FieldAnnotationStruct>();\n        }\n\n        fieldAnnotations.add(new FieldAnnotationStruct(field,\n                        new AnnotationSetItem(annotations, dexFile)));\n    }\n\n    /**\n     * Adds a method annotations item to this instance.\n     *\n     * @param method {@code non-null;} method in question\n     * @param annotations {@code non-null;} associated annotations to add\n     * @param dexFile {@code non-null;} dex output\n     */\n    public void addMethodAnnotations(CstMethodRef method,\n            Annotations annotations, DexFile dexFile) {\n        if (methodAnnotations == null) {\n            methodAnnotations = new ArrayList<MethodAnnotationStruct>();\n        }\n\n        methodAnnotations.add(new MethodAnnotationStruct(method,\n                        new AnnotationSetItem(annotations, dexFile)));\n    }\n\n    /**\n     * Adds a parameter annotations item to this instance.\n     *\n     * @param method {@code non-null;} method in question\n     * @param list {@code non-null;} associated list of annotation sets to add\n     * @param dexFile {@code non-null;} dex output\n     */\n    public void addParameterAnnotations(CstMethodRef method,\n            AnnotationsList list, DexFile dexFile) {\n        if (parameterAnnotations == null) {\n            parameterAnnotations = new ArrayList<ParameterAnnotationStruct>();\n        }\n\n        parameterAnnotations.add(new ParameterAnnotationStruct(method, list, dexFile));\n    }\n\n    /**\n     * Gets the method annotations for a given method, if any. This is\n     * meant for use by debugging / dumping code.\n     *\n     * @param method {@code non-null;} the method\n     * @return {@code null-ok;} the method annotations, if any\n     */\n    public Annotations getMethodAnnotations(CstMethodRef method) {\n        if (methodAnnotations == null) {\n            return null;\n        }\n\n        for (MethodAnnotationStruct item : methodAnnotations) {\n            if (item.getMethod().equals(method)) {\n                return item.getAnnotations();\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Gets the parameter annotations for a given method, if any. This is\n     * meant for use by debugging / dumping code.\n     *\n     * @param method {@code non-null;} the method\n     * @return {@code null-ok;} the parameter annotations, if any\n     */\n    public AnnotationsList getParameterAnnotations(CstMethodRef method) {\n        if (parameterAnnotations == null) {\n            return null;\n        }\n\n        for (ParameterAnnotationStruct item : parameterAnnotations) {\n            if (item.getMethod().equals(method)) {\n                return item.getAnnotationsList();\n            }\n        }\n\n        return null;\n    }\n\n    /** {@inheritDoc} */\n    public void addContents(DexFile file) {\n        MixedItemSection wordData = file.getWordData();\n\n        if (classAnnotations != null) {\n            classAnnotations = wordData.intern(classAnnotations);\n        }\n\n        if (fieldAnnotations != null) {\n            for (FieldAnnotationStruct item : fieldAnnotations) {\n                item.addContents(file);\n            }\n        }\n\n        if (methodAnnotations != null) {\n            for (MethodAnnotationStruct item : methodAnnotations) {\n                item.addContents(file);\n            }\n        }\n\n        if (parameterAnnotations != null) {\n            for (ParameterAnnotationStruct item : parameterAnnotations) {\n                item.addContents(file);\n            }\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toHuman() {\n        throw new RuntimeException(\"unsupported\");\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void place0(Section addedTo, int offset) {\n        // We just need to set the write size here.\n\n        int elementCount = listSize(fieldAnnotations)\n            + listSize(methodAnnotations) + listSize(parameterAnnotations);\n        setWriteSize(HEADER_SIZE + (elementCount * ELEMENT_SIZE));\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void writeTo0(DexFile file, AnnotatedOutput out) {\n        boolean annotates = out.annotates();\n        int classOff = OffsettedItem.getAbsoluteOffsetOr0(classAnnotations);\n        int fieldsSize = listSize(fieldAnnotations);\n        int methodsSize = listSize(methodAnnotations);\n        int parametersSize = listSize(parameterAnnotations);\n\n        if (annotates) {\n            out.annotate(0, offsetString() + \" annotations directory\");\n            out.annotate(4, \"  class_annotations_off: \" + Hex.u4(classOff));\n            out.annotate(4, \"  fields_size:           \" +\n                    Hex.u4(fieldsSize));\n            out.annotate(4, \"  methods_size:          \" +\n                    Hex.u4(methodsSize));\n            out.annotate(4, \"  parameters_size:       \" +\n                    Hex.u4(parametersSize));\n        }\n\n        out.writeInt(classOff);\n        out.writeInt(fieldsSize);\n        out.writeInt(methodsSize);\n        out.writeInt(parametersSize);\n\n        if (fieldsSize != 0) {\n            Collections.sort(fieldAnnotations);\n            if (annotates) {\n                out.annotate(0, \"  fields:\");\n            }\n            for (FieldAnnotationStruct item : fieldAnnotations) {\n                item.writeTo(file, out);\n            }\n        }\n\n        if (methodsSize != 0) {\n            Collections.sort(methodAnnotations);\n            if (annotates) {\n                out.annotate(0, \"  methods:\");\n            }\n            for (MethodAnnotationStruct item : methodAnnotations) {\n                item.writeTo(file, out);\n            }\n        }\n\n        if (parametersSize != 0) {\n            Collections.sort(parameterAnnotations);\n            if (annotates) {\n                out.annotate(0, \"  parameters:\");\n            }\n            for (ParameterAnnotationStruct item : parameterAnnotations) {\n                item.writeTo(file, out);\n            }\n        }\n    }\n\n    /**\n     * Gets the list size of the given list, or {@code 0} if given\n     * {@code null}.\n     *\n     * @param list {@code null-ok;} the list in question\n     * @return {@code >= 0;} its size\n     */\n    private static int listSize(ArrayList<?> list) {\n        if (list == null) {\n            return 0;\n        }\n\n        return list.size();\n    }\n\n    /**\n     * Prints out the contents of this instance, in a debugging-friendly\n     * way. This is meant to be called from {@link ClassDefItem#debugPrint}.\n     *\n     * @param out {@code non-null;} where to output to\n     */\n    /*package*/ void debugPrint(PrintWriter out) {\n        if (classAnnotations != null) {\n            out.println(\"  class annotations: \" + classAnnotations);\n        }\n\n        if (fieldAnnotations != null) {\n            out.println(\"  field annotations:\");\n            for (FieldAnnotationStruct item : fieldAnnotations) {\n                out.println(\"    \" + item.toHuman());\n            }\n        }\n\n        if (methodAnnotations != null) {\n            out.println(\"  method annotations:\");\n            for (MethodAnnotationStruct item : methodAnnotations) {\n                out.println(\"    \" + item.toHuman());\n            }\n        }\n\n        if (parameterAnnotations != null) {\n            out.println(\"  parameter annotations:\");\n            for (ParameterAnnotationStruct item : parameterAnnotations) {\n                out.println(\"    \" + item.toHuman());\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/CatchStructs.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.dex.code.CatchHandlerList;\nimport com.taobao.android.dx.dex.code.CatchTable;\nimport com.taobao.android.dx.dex.code.DalvCode;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.ByteArrayAnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport java.io.PrintWriter;\nimport java.util.Map;\nimport java.util.TreeMap;\n\n/**\n * List of exception handlers (tuples of covered range, catch type,\n * handler address) for a particular piece of code. Instances of this\n * class correspond to a {@code try_item[]} and a\n * {@code catch_handler_item[]}.\n */\npublic final class CatchStructs {\n    /**\n     * the size of a {@code try_item}: a {@code uint}\n     * and two {@code ushort}s\n     */\n    private static final int TRY_ITEM_WRITE_SIZE = 4 + (2 * 2);\n\n    /** {@code non-null;} code that contains the catches */\n    private final DalvCode code;\n\n    /**\n     * {@code null-ok;} the underlying table; set in\n     * {@link #finishProcessingIfNecessary}\n     */\n    private CatchTable table;\n\n    /**\n     * {@code null-ok;} the encoded handler list, if calculated; set in\n     * {@link #encode}\n     */\n    private byte[] encodedHandlers;\n\n    /**\n     * length of the handlers header (encoded size), if known; used for\n     * annotation\n     */\n    private int encodedHandlerHeaderSize;\n\n    /**\n     * {@code null-ok;} map from handler lists to byte offsets, if calculated; set in\n     * {@link #encode}\n     */\n    private TreeMap<CatchHandlerList, Integer> handlerOffsets;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param code {@code non-null;} code that contains the catches\n     */\n    public CatchStructs(DalvCode code) {\n        this.code = code;\n        this.table = null;\n        this.encodedHandlers = null;\n        this.encodedHandlerHeaderSize = 0;\n        this.handlerOffsets = null;\n    }\n\n    /**\n     * Finish processing the catches, if necessary.\n     */\n    private void finishProcessingIfNecessary() {\n        if (table == null) {\n            table = code.getCatches();\n        }\n    }\n\n    /**\n     * Gets the size of the tries list, in entries.\n     *\n     * @return {@code >= 0;} the tries list size\n     */\n    public int triesSize() {\n        finishProcessingIfNecessary();\n        return table.size();\n    }\n\n    /**\n     * Does a human-friendly dump of this instance.\n     *\n     * @param out {@code non-null;} where to dump\n     * @param prefix {@code non-null;} prefix to attach to each line of output\n     */\n    public void debugPrint(PrintWriter out, String prefix) {\n        annotateEntries(prefix, out, null);\n    }\n\n    /**\n     * Encodes the handler lists.\n     *\n     * @param file {@code non-null;} file this instance is part of\n     */\n    public void encode(DexFile file) {\n        finishProcessingIfNecessary();\n\n        TypeIdsSection typeIds = file.getTypeIds();\n        int size = table.size();\n\n        handlerOffsets = new TreeMap<CatchHandlerList, Integer>();\n\n        /*\n         * First add a map entry for each unique list. The tree structure\n         * will ensure they are sorted when we reiterate later.\n         */\n        for (int i = 0; i < size; i++) {\n            handlerOffsets.put(table.get(i).getHandlers(), null);\n        }\n\n        if (handlerOffsets.size() > 65535) {\n            throw new UnsupportedOperationException(\n                    \"too many catch handlers\");\n        }\n\n        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();\n\n        // Write out the handlers \"header\" consisting of its size in entries.\n        encodedHandlerHeaderSize =\n            out.writeUleb128(handlerOffsets.size());\n\n        // Now write the lists out in order, noting the offset of each.\n        for (Map.Entry<CatchHandlerList, Integer> mapping :\n                 handlerOffsets.entrySet()) {\n            CatchHandlerList list = mapping.getKey();\n            int listSize = list.size();\n            boolean catchesAll = list.catchesAll();\n\n            // Set the offset before we do any writing.\n            mapping.setValue(out.getCursor());\n\n            if (catchesAll) {\n                // A size <= 0 means that the list ends with a catch-all.\n                out.writeSleb128(-(listSize - 1));\n                listSize--;\n            } else {\n                out.writeSleb128(listSize);\n            }\n\n            for (int i = 0; i < listSize; i++) {\n                CatchHandlerList.Entry entry = list.get(i);\n                out.writeUleb128(\n                        typeIds.indexOf(entry.getExceptionType()));\n                out.writeUleb128(entry.getHandler());\n            }\n\n            if (catchesAll) {\n                out.writeUleb128(list.get(listSize).getHandler());\n            }\n        }\n\n        encodedHandlers = out.toByteArray();\n    }\n\n    /**\n     * Gets the write size of this instance, in bytes.\n     *\n     * @return {@code >= 0;} the write size\n     */\n    public int writeSize() {\n        return (triesSize() * TRY_ITEM_WRITE_SIZE) +\n                + encodedHandlers.length;\n    }\n\n    /**\n     * Writes this instance to the given stream.\n     *\n     * @param file {@code non-null;} file this instance is part of\n     * @param out {@code non-null;} where to write to\n     */\n    public void writeTo(DexFile file, AnnotatedOutput out) {\n        finishProcessingIfNecessary();\n\n        if (out.annotates()) {\n            annotateEntries(\"  \", null, out);\n        }\n\n        int tableSize = table.size();\n        for (int i = 0; i < tableSize; i++) {\n            CatchTable.Entry one = table.get(i);\n            int start = one.getStart();\n            int end = one.getEnd();\n            int insnCount = end - start;\n\n            if (insnCount >= 65536) {\n                throw new UnsupportedOperationException(\n                        \"bogus exception range: \" + Hex.u4(start) + \"..\" +\n                        Hex.u4(end));\n            }\n\n            out.writeInt(start);\n            out.writeShort(insnCount);\n            out.writeShort(handlerOffsets.get(one.getHandlers()));\n        }\n\n        out.write(encodedHandlers);\n    }\n\n    /**\n     * Helper method to annotate or simply print the exception handlers.\n     * Only one of {@code printTo} or {@code annotateTo} should\n     * be non-null.\n     *\n     * @param prefix {@code non-null;} prefix for each line\n     * @param printTo {@code null-ok;} where to print to\n     * @param annotateTo {@code null-ok;} where to consume bytes and annotate to\n     */\n    private void annotateEntries(String prefix, PrintWriter printTo,\n            AnnotatedOutput annotateTo) {\n        finishProcessingIfNecessary();\n\n        boolean consume = (annotateTo != null);\n        int amt1 = consume ? 6 : 0;\n        int amt2 = consume ? 2 : 0;\n        int size = table.size();\n        String subPrefix = prefix + \"  \";\n\n        if (consume) {\n            annotateTo.annotate(0, prefix + \"tries:\");\n        } else {\n            printTo.println(prefix + \"tries:\");\n        }\n\n        for (int i = 0; i < size; i++) {\n            CatchTable.Entry entry = table.get(i);\n            CatchHandlerList handlers = entry.getHandlers();\n            String s1 = subPrefix + \"try \" + Hex.u2or4(entry.getStart())\n                + \"..\" + Hex.u2or4(entry.getEnd());\n            String s2 = handlers.toHuman(subPrefix, \"\");\n\n            if (consume) {\n                annotateTo.annotate(amt1, s1);\n                annotateTo.annotate(amt2, s2);\n            } else {\n                printTo.println(s1);\n                printTo.println(s2);\n            }\n        }\n\n        if (! consume) {\n            // Only emit the handler lists if we are consuming bytes.\n            return;\n        }\n\n        annotateTo.annotate(0, prefix + \"handlers:\");\n        annotateTo.annotate(encodedHandlerHeaderSize,\n                subPrefix + \"size: \" + Hex.u2(handlerOffsets.size()));\n\n        int lastOffset = 0;\n        CatchHandlerList lastList = null;\n\n        for (Map.Entry<CatchHandlerList, Integer> mapping :\n                 handlerOffsets.entrySet()) {\n            CatchHandlerList list = mapping.getKey();\n            int offset = mapping.getValue();\n\n            if (lastList != null) {\n                annotateAndConsumeHandlers(lastList, lastOffset,\n                        offset - lastOffset, subPrefix, printTo, annotateTo);\n            }\n\n            lastList = list;\n            lastOffset = offset;\n        }\n\n        annotateAndConsumeHandlers(lastList, lastOffset,\n                encodedHandlers.length - lastOffset,\n                subPrefix, printTo, annotateTo);\n    }\n\n    /**\n     * Helper for {@link #annotateEntries} to annotate a catch handler list\n     * while consuming it.\n     *\n     * @param handlers {@code non-null;} handlers to annotate\n     * @param offset {@code >= 0;} the offset of this handler\n     * @param size {@code >= 1;} the number of bytes the handlers consume\n     * @param prefix {@code non-null;} prefix for each line\n     * @param printTo {@code null-ok;} where to print to\n     * @param annotateTo {@code non-null;} where to annotate to\n     */\n    private static void annotateAndConsumeHandlers(CatchHandlerList handlers,\n            int offset, int size, String prefix, PrintWriter printTo,\n            AnnotatedOutput annotateTo) {\n        String s = handlers.toHuman(prefix, Hex.u2(offset) + \": \");\n\n        if (printTo != null) {\n            printTo.println(s);\n        }\n\n        annotateTo.annotate(size, s);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/ClassDataItem.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstArray;\nimport com.taobao.android.dx.rop.cst.CstLiteralBits;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.cst.Zeroes;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.ByteArrayAnnotatedOutput;\nimport com.taobao.android.dx.util.Writers;\nimport java.io.PrintWriter;\nimport java.io.Writer;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\n\n/**\n * Representation of all the parts of a Dalvik class that are generally\n * \"inflated\" into an in-memory representation at runtime. Instances of\n * this class are represented in a compact streamable form in a\n * {@code dex} file, as opposed to a random-access form.\n */\npublic final class ClassDataItem extends OffsettedItem {\n    /** {@code non-null;} what class this data is for, just for listing outputs */\n    private final CstType thisClass;\n\n    /** {@code non-null;} list of static fields */\n    private final ArrayList<EncodedField> staticFields;\n\n    /** {@code non-null;} list of initial values for static fields */\n    private final HashMap<EncodedField, Constant> staticValues;\n\n    /** {@code non-null;} list of instance fields */\n    private final ArrayList<EncodedField> instanceFields;\n\n    /** {@code non-null;} list of direct methods */\n    private final ArrayList<EncodedMethod> directMethods;\n\n    /** {@code non-null;} list of virtual methods */\n    private final ArrayList<EncodedMethod> virtualMethods;\n\n    /** {@code null-ok;} static initializer list; set in {@link #addContents} */\n    private CstArray staticValuesConstant;\n\n    /**\n     * {@code null-ok;} encoded form, ready for writing to a file; set during\n     * {@link #place0}\n     */\n    private byte[] encodedForm;\n\n    /**\n     * Constructs an instance. Its sets of members are initially\n     * empty.\n     *\n     * @param thisClass {@code non-null;} what class this data is for, just\n     * for listing outputs\n     */\n    public ClassDataItem(CstType thisClass) {\n        super(1, -1);\n\n        if (thisClass == null) {\n            throw new NullPointerException(\"thisClass == null\");\n        }\n\n        this.thisClass = thisClass;\n        this.staticFields = new ArrayList<EncodedField>(20);\n        this.staticValues = new HashMap<EncodedField, Constant>(40);\n        this.instanceFields = new ArrayList<EncodedField>(20);\n        this.directMethods = new ArrayList<EncodedMethod>(20);\n        this.virtualMethods = new ArrayList<EncodedMethod>(20);\n        this.staticValuesConstant = null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_CLASS_DATA_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toHuman() {\n        return toString();\n    }\n\n    /**\n     * Returns whether this instance is empty.\n     *\n     * @return {@code true} if this instance is empty or\n     * {@code false} if at least one element has been added to it\n     */\n    public boolean isEmpty() {\n        return staticFields.isEmpty() && instanceFields.isEmpty()\n            && directMethods.isEmpty() && virtualMethods.isEmpty();\n    }\n\n    /**\n     * Adds a static field.\n     *\n     * @param field {@code non-null;} the field to add\n     * @param value {@code null-ok;} initial value for the field, if any\n     */\n    public void addStaticField(EncodedField field, Constant value) {\n        if (field == null) {\n            throw new NullPointerException(\"field == null\");\n        }\n\n        if (staticValuesConstant != null) {\n            throw new UnsupportedOperationException(\n                    \"static fields already sorted\");\n        }\n\n        staticFields.add(field);\n        staticValues.put(field, value);\n    }\n\n    /**\n     * Adds an instance field.\n     *\n     * @param field {@code non-null;} the field to add\n     */\n    public void addInstanceField(EncodedField field) {\n        if (field == null) {\n            throw new NullPointerException(\"field == null\");\n        }\n\n        instanceFields.add(field);\n    }\n\n    /**\n     * Adds a direct ({@code static} and/or {@code private}) method.\n     *\n     * @param method {@code non-null;} the method to add\n     */\n    public void addDirectMethod(EncodedMethod method) {\n        if (method == null) {\n            throw new NullPointerException(\"method == null\");\n        }\n\n        directMethods.add(method);\n    }\n\n    /**\n     * Adds a virtual method.\n     *\n     * @param method {@code non-null;} the method to add\n     */\n    public void addVirtualMethod(EncodedMethod method) {\n        if (method == null) {\n            throw new NullPointerException(\"method == null\");\n        }\n\n        virtualMethods.add(method);\n    }\n\n    /**\n     * Gets all the methods in this class. The returned list is not linked\n     * in any way to the underlying lists contained in this instance, but\n     * the objects contained in the list are shared.\n     *\n     * @return {@code non-null;} list of all methods\n     */\n    public ArrayList<EncodedMethod> getMethods() {\n        int sz = directMethods.size() + virtualMethods.size();\n        ArrayList<EncodedMethod> result = new ArrayList<EncodedMethod>(sz);\n\n        result.addAll(directMethods);\n        result.addAll(virtualMethods);\n\n        return result;\n    }\n\n\n    /**\n     * Prints out the contents of this instance, in a debugging-friendly\n     * way.\n     *\n     * @param out {@code non-null;} where to output to\n     * @param verbose whether to be verbose with the output\n     */\n    public void debugPrint(Writer out, boolean verbose) {\n        PrintWriter pw = Writers.printWriterFor(out);\n\n        int sz = staticFields.size();\n        for (int i = 0; i < sz; i++) {\n            pw.println(\"  sfields[\" + i + \"]: \" + staticFields.get(i));\n        }\n\n        sz = instanceFields.size();\n        for (int i = 0; i < sz; i++) {\n            pw.println(\"  ifields[\" + i + \"]: \" + instanceFields.get(i));\n        }\n\n        sz = directMethods.size();\n        for (int i = 0; i < sz; i++) {\n            pw.println(\"  dmeths[\" + i + \"]:\");\n            directMethods.get(i).debugPrint(pw, verbose);\n        }\n\n        sz = virtualMethods.size();\n        for (int i = 0; i < sz; i++) {\n            pw.println(\"  vmeths[\" + i + \"]:\");\n            virtualMethods.get(i).debugPrint(pw, verbose);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        if (!staticFields.isEmpty()) {\n            getStaticValuesConstant(); // Force the fields to be sorted.\n            for (EncodedField field : staticFields) {\n                field.addContents(file);\n            }\n        }\n\n        if (!instanceFields.isEmpty()) {\n            Collections.sort(instanceFields);\n            for (EncodedField field : instanceFields) {\n                field.addContents(file);\n            }\n        }\n\n        if (!directMethods.isEmpty()) {\n            Collections.sort(directMethods);\n            for (EncodedMethod method : directMethods) {\n                method.addContents(file);\n            }\n        }\n\n        if (!virtualMethods.isEmpty()) {\n            Collections.sort(virtualMethods);\n            for (EncodedMethod method : virtualMethods) {\n                method.addContents(file);\n            }\n        }\n    }\n\n    /**\n     * Gets a {@link CstArray} corresponding to {@link #staticValues} if\n     * it contains any non-zero non-{@code null} values.\n     *\n     * @return {@code null-ok;} the corresponding constant or {@code null} if\n     * there are no values to encode\n     */\n    public CstArray getStaticValuesConstant() {\n        if ((staticValuesConstant == null) && (staticFields.size() != 0)) {\n            staticValuesConstant = makeStaticValuesConstant();\n        }\n\n        return staticValuesConstant;\n    }\n\n    /**\n     * Gets a {@link CstArray} corresponding to {@link #staticValues} if\n     * it contains any non-zero non-{@code null} values.\n     *\n     * @return {@code null-ok;} the corresponding constant or {@code null} if\n     * there are no values to encode\n     */\n    private CstArray makeStaticValuesConstant() {\n        // First sort the statics into their final order.\n        Collections.sort(staticFields);\n\n        /*\n         * Get the size of staticValues minus any trailing zeros/nulls (both\n         * nulls per se as well as instances of CstKnownNull).\n         */\n\n        int size = staticFields.size();\n        while (size > 0) {\n            EncodedField field = staticFields.get(size - 1);\n            Constant cst = staticValues.get(field);\n            if (cst instanceof CstLiteralBits) {\n                // Note: CstKnownNull extends CstLiteralBits.\n                if (((CstLiteralBits) cst).getLongBits() != 0) {\n                    break;\n                }\n            } else if (cst != null) {\n                break;\n            }\n            size--;\n        }\n\n        if (size == 0) {\n            return null;\n        }\n\n        // There is something worth encoding, so build up a result.\n\n        CstArray.List list = new CstArray.List(size);\n        for (int i = 0; i < size; i++) {\n            EncodedField field = staticFields.get(i);\n            Constant cst = staticValues.get(field);\n            if (cst == null) {\n                cst = Zeroes.zeroFor(field.getRef().getType());\n            }\n            list.set(i, cst);\n        }\n        list.setImmutable();\n\n        return new CstArray(list);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void place0(Section addedTo, int offset) {\n        // Encode the data and note the size.\n\n        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();\n\n        encodeOutput(addedTo.getFile(), out);\n        encodedForm = out.toByteArray();\n        setWriteSize(encodedForm.length);\n    }\n\n    /**\n     * Writes out the encoded form of this instance.\n     *\n     * @param file {@code non-null;} file this instance is part of\n     * @param out {@code non-null;} where to write to\n     */\n    private void encodeOutput(DexFile file, AnnotatedOutput out) {\n        boolean annotates = out.annotates();\n\n        if (annotates) {\n            out.annotate(0, offsetString() + \" class data for \" +\n                    thisClass.toHuman());\n        }\n\n        encodeSize(file, out, \"static_fields\", staticFields.size());\n        encodeSize(file, out, \"instance_fields\", instanceFields.size());\n        encodeSize(file, out, \"direct_methods\", directMethods.size());\n        encodeSize(file, out, \"virtual_methods\", virtualMethods.size());\n\n        encodeList(file, out, \"static_fields\", staticFields);\n        encodeList(file, out, \"instance_fields\", instanceFields);\n        encodeList(file, out, \"direct_methods\", directMethods);\n        encodeList(file, out, \"virtual_methods\", virtualMethods);\n\n        if (annotates) {\n            out.endAnnotation();\n        }\n    }\n\n    /**\n     * Helper for {@link #encodeOutput}, which writes out the given\n     * size value, annotating it as well (if annotations are enabled).\n     *\n     * @param file {@code non-null;} file this instance is part of\n     * @param out {@code non-null;} where to write to\n     * @param label {@code non-null;} the label for the purposes of annotation\n     * @param size {@code >= 0;} the size to write\n     */\n    private static void encodeSize(DexFile file, AnnotatedOutput out,\n            String label, int size) {\n        if (out.annotates()) {\n            out.annotate(String.format(\"  %-21s %08x\", label + \"_size:\",\n                            size));\n        }\n\n        out.writeUleb128(size);\n    }\n\n    /**\n     * Helper for {@link #encodeOutput}, which writes out the given\n     * list. It also annotates the items (if any and if annotations\n     * are enabled).\n     *\n     * @param file {@code non-null;} file this instance is part of\n     * @param out {@code non-null;} where to write to\n     * @param label {@code non-null;} the label for the purposes of annotation\n     * @param list {@code non-null;} the list in question\n     */\n    private static void encodeList(DexFile file, AnnotatedOutput out,\n            String label, ArrayList<? extends EncodedMember> list) {\n        int size = list.size();\n        int lastIndex = 0;\n\n        if (size == 0) {\n            return;\n        }\n\n        if (out.annotates()) {\n            out.annotate(0, \"  \" + label + \":\");\n        }\n\n        for (int i = 0; i < size; i++) {\n            lastIndex = list.get(i).encode(file, out, lastIndex, i);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo0(DexFile file, AnnotatedOutput out) {\n        boolean annotates = out.annotates();\n\n        if (annotates) {\n            /*\n             * The output is to be annotated, so redo the work previously\n             * done by place0(), except this time annotations will actually\n             * get emitted.\n             */\n            encodeOutput(file, out);\n        } else {\n            out.write(encodedForm);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/ClassDefItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.SizeOf;\nimport com.taobao.android.dx.rop.annotation.Annotations;\nimport com.taobao.android.dx.rop.annotation.AnnotationsList;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstArray;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.Writers;\n\nimport java.io.PrintWriter;\nimport java.io.Writer;\nimport java.util.ArrayList;\n\n/**\n * Representation of a Dalvik class, which is basically a set of\n * members (fields or methods) along with a few more pieces of\n * information.\n */\npublic final class ClassDefItem extends IndexedItem {\n\n    /** {@code non-null;} type constant for this class */\n    private final CstType thisClass;\n\n    /** access flags */\n    private final int accessFlags;\n\n    /**\n     * {@code null-ok;} superclass or {@code null} if this class is a/the\n     * root class\n     */\n    private final CstType superclass;\n\n    /** {@code null-ok;} list of implemented interfaces */\n    private TypeListItem interfaces;\n\n    /** {@code null-ok;} source file name or {@code null} if unknown */\n    private final CstString sourceFile;\n\n    /** {@code non-null;} associated class data object */\n    private final ClassDataItem classData;\n\n    /**\n     * {@code null-ok;} item wrapper for the static values, initialized\n     * in {@link #addContents}\n     */\n    private EncodedArrayItem staticValuesItem;\n\n    /** {@code non-null;} annotations directory */\n    private AnnotationsDirectoryItem annotationsDirectory;\n\n    /**\n     * Constructs an instance. Its sets of members and annotations are\n     * initially empty.\n     *\n     * @param thisClass {@code non-null;} type constant for this class\n     * @param accessFlags access flags\n     * @param superclass {@code null-ok;} superclass or {@code null} if\n     * this class is a/the root class\n     * @param interfaces {@code non-null;} list of implemented interfaces\n     * @param sourceFile {@code null-ok;} source file name or\n     * {@code null} if unknown\n     */\n    public ClassDefItem(CstType thisClass, int accessFlags,\n            CstType superclass, TypeList interfaces, CstString sourceFile) {\n        if (thisClass == null) {\n            throw new NullPointerException(\"thisClass == null\");\n        }\n\n        /*\n         * TODO: Maybe check accessFlags and superclass, at\n         * least for easily-checked stuff?\n         */\n\n        if (interfaces == null) {\n            throw new NullPointerException(\"interfaces == null\");\n        }\n\n        this.thisClass = thisClass;\n        this.accessFlags = accessFlags;\n        this.superclass = superclass;\n        this.interfaces =\n            (interfaces.size() == 0) ? null :  new TypeListItem(interfaces);\n        this.sourceFile = sourceFile;\n        this.classData = new ClassDataItem(thisClass);\n        this.staticValuesItem = null;\n        this.annotationsDirectory = new AnnotationsDirectoryItem();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_CLASS_DEF_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int writeSize() {\n        return SizeOf.CLASS_DEF_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        TypeIdsSection typeIds = file.getTypeIds();\n        MixedItemSection byteData = file.getByteData();\n        MixedItemSection wordData = file.getWordData();\n        MixedItemSection typeLists = file.getTypeLists();\n        StringIdsSection stringIds = file.getStringIds();\n\n        typeIds.intern(thisClass);\n\n        if (!classData.isEmpty()) {\n            MixedItemSection classDataSection = file.getClassData();\n            classDataSection.add(classData);\n\n            CstArray staticValues = classData.getStaticValuesConstant();\n            if (staticValues != null) {\n                staticValuesItem =\n                    byteData.intern(new EncodedArrayItem(staticValues));\n            }\n        }\n\n        if (superclass != null) {\n            typeIds.intern(superclass);\n        }\n\n        if (interfaces != null) {\n            interfaces = typeLists.intern(interfaces);\n        }\n\n        if (sourceFile != null) {\n            stringIds.intern(sourceFile);\n        }\n\n        if (! annotationsDirectory.isEmpty()) {\n            if (annotationsDirectory.isInternable()) {\n                annotationsDirectory = wordData.intern(annotationsDirectory);\n            } else {\n                wordData.add(annotationsDirectory);\n            }\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(DexFile file, AnnotatedOutput out) {\n        boolean annotates = out.annotates();\n        TypeIdsSection typeIds = file.getTypeIds();\n        int classIdx = typeIds.indexOf(thisClass);\n        int superIdx = (superclass == null) ? -1 :\n            typeIds.indexOf(superclass);\n        int interOff = OffsettedItem.getAbsoluteOffsetOr0(interfaces);\n        int annoOff = annotationsDirectory.isEmpty() ? 0 :\n            annotationsDirectory.getAbsoluteOffset();\n        int sourceFileIdx = (sourceFile == null) ? -1 :\n            file.getStringIds().indexOf(sourceFile);\n        int dataOff = classData.isEmpty()? 0 : classData.getAbsoluteOffset();\n        int staticValuesOff =\n            OffsettedItem.getAbsoluteOffsetOr0(staticValuesItem);\n\n        if (annotates) {\n            out.annotate(0, indexString() + ' ' + thisClass.toHuman());\n            out.annotate(4, \"  class_idx:           \" + Hex.u4(classIdx));\n            out.annotate(4, \"  access_flags:        \" +\n                         AccessFlags.classString(accessFlags));\n            out.annotate(4, \"  superclass_idx:      \" + Hex.u4(superIdx) +\n                         \" // \" + ((superclass == null) ? \"<none>\" :\n                          superclass.toHuman()));\n            out.annotate(4, \"  interfaces_off:      \" + Hex.u4(interOff));\n            if (interOff != 0) {\n                TypeList list = interfaces.getList();\n                int sz = list.size();\n                for (int i = 0; i < sz; i++) {\n                    out.annotate(0, \"    \" + list.getType(i).toHuman());\n                }\n            }\n            out.annotate(4, \"  source_file_idx:     \" + Hex.u4(sourceFileIdx) +\n                         \" // \" + ((sourceFile == null) ? \"<none>\" :\n                          sourceFile.toHuman()));\n            out.annotate(4, \"  annotations_off:     \" + Hex.u4(annoOff));\n            out.annotate(4, \"  class_data_off:      \" + Hex.u4(dataOff));\n            out.annotate(4, \"  static_values_off:   \" +\n                    Hex.u4(staticValuesOff));\n        }\n\n        out.writeInt(classIdx);\n        out.writeInt(accessFlags);\n        out.writeInt(superIdx);\n        out.writeInt(interOff);\n        out.writeInt(sourceFileIdx);\n        out.writeInt(annoOff);\n        out.writeInt(dataOff);\n        out.writeInt(staticValuesOff);\n    }\n\n    /**\n     * Gets the constant corresponding to this class.\n     *\n     * @return {@code non-null;} the constant\n     */\n    public CstType getThisClass() {\n        return thisClass;\n    }\n\n    /**\n     * Gets the access flags.\n     *\n     * @return the access flags\n     */\n    public int getAccessFlags() {\n        return accessFlags;\n    }\n\n    /**\n     * Gets the superclass.\n     *\n     * @return {@code null-ok;} the superclass or {@code null} if\n     * this class is a/the root class\n     */\n    public CstType getSuperclass() {\n        return superclass;\n    }\n\n    /**\n     * Gets the list of interfaces implemented.\n     *\n     * @return {@code non-null;} the interfaces list\n     */\n    public TypeList getInterfaces() {\n        if (interfaces == null) {\n            return StdTypeList.EMPTY;\n        }\n\n        return interfaces.getList();\n    }\n\n    /**\n     * Gets the source file name.\n     *\n     * @return {@code null-ok;} the source file name or {@code null} if unknown\n     */\n    public CstString getSourceFile() {\n        return sourceFile;\n    }\n\n    /**\n     * Adds a static field.\n     *\n     * @param field {@code non-null;} the field to add\n     * @param value {@code null-ok;} initial value for the field, if any\n     */\n    public void addStaticField(EncodedField field, Constant value) {\n        classData.addStaticField(field, value);\n    }\n\n    /**\n     * Adds an instance field.\n     *\n     * @param field {@code non-null;} the field to add\n     */\n    public void addInstanceField(EncodedField field) {\n        classData.addInstanceField(field);\n    }\n\n    /**\n     * Adds a direct ({@code static} and/or {@code private}) method.\n     *\n     * @param method {@code non-null;} the method to add\n     */\n    public void addDirectMethod(EncodedMethod method) {\n        classData.addDirectMethod(method);\n    }\n\n    /**\n     * Adds a virtual method.\n     *\n     * @param method {@code non-null;} the method to add\n     */\n    public void addVirtualMethod(EncodedMethod method) {\n        classData.addVirtualMethod(method);\n    }\n\n    /**\n     * Gets all the methods in this class. The returned list is not linked\n     * in any way to the underlying lists contained in this instance, but\n     * the objects contained in the list are shared.\n     *\n     * @return {@code non-null;} list of all methods\n     */\n    public ArrayList<EncodedMethod> getMethods() {\n        return classData.getMethods();\n    }\n\n    /**\n     * Sets the direct annotations on this class. These are annotations\n     * made on the class, per se, as opposed to on one of its members.\n     * It is only valid to call this method at most once per instance.\n     *\n     * @param annotations {@code non-null;} annotations to set for this class\n     * @param dexFile {@code non-null;} dex output\n     */\n    public void setClassAnnotations(Annotations annotations, DexFile dexFile) {\n        annotationsDirectory.setClassAnnotations(annotations, dexFile);\n    }\n\n    /**\n     * Adds a field annotations item to this class.\n     *\n     * @param field {@code non-null;} field in question\n     * @param annotations {@code non-null;} associated annotations to add\n     * @param dexFile {@code non-null;} dex output\n     */\n    public void addFieldAnnotations(CstFieldRef field,\n            Annotations annotations, DexFile dexFile) {\n        annotationsDirectory.addFieldAnnotations(field, annotations, dexFile);\n    }\n\n    /**\n     * Adds a method annotations item to this class.\n     *\n     * @param method {@code non-null;} method in question\n     * @param annotations {@code non-null;} associated annotations to add\n     * @param dexFile {@code non-null;} dex output\n     */\n    public void addMethodAnnotations(CstMethodRef method,\n            Annotations annotations, DexFile dexFile) {\n        annotationsDirectory.addMethodAnnotations(method, annotations, dexFile);\n    }\n\n    /**\n     * Adds a parameter annotations item to this class.\n     *\n     * @param method {@code non-null;} method in question\n     * @param list {@code non-null;} associated list of annotation sets to add\n     * @param dexFile {@code non-null;} dex output\n     */\n    public void addParameterAnnotations(CstMethodRef method,\n            AnnotationsList list, DexFile dexFile) {\n        annotationsDirectory.addParameterAnnotations(method, list, dexFile);\n    }\n\n    /**\n     * Gets the method annotations for a given method, if any. This is\n     * meant for use by debugging / dumping code.\n     *\n     * @param method {@code non-null;} the method\n     * @return {@code null-ok;} the method annotations, if any\n     */\n    public Annotations getMethodAnnotations(CstMethodRef method) {\n        return annotationsDirectory.getMethodAnnotations(method);\n    }\n\n    /**\n     * Gets the parameter annotations for a given method, if any. This is\n     * meant for use by debugging / dumping code.\n     *\n     * @param method {@code non-null;} the method\n     * @return {@code null-ok;} the parameter annotations, if any\n     */\n    public AnnotationsList getParameterAnnotations(CstMethodRef method) {\n        return annotationsDirectory.getParameterAnnotations(method);\n    }\n\n    /**\n     * Prints out the contents of this instance, in a debugging-friendly\n     * way.\n     *\n     * @param out {@code non-null;} where to output to\n     * @param verbose whether to be verbose with the output\n     */\n    public void debugPrint(Writer out, boolean verbose) {\n        PrintWriter pw = Writers.printWriterFor(out);\n\n        pw.println(getClass().getName() + \" {\");\n        pw.println(\"  accessFlags: \" + Hex.u2(accessFlags));\n        pw.println(\"  superclass: \" + superclass);\n        pw.println(\"  interfaces: \" +\n                ((interfaces == null) ? \"<none>\" : interfaces));\n        pw.println(\"  sourceFile: \" +\n                ((sourceFile == null) ? \"<none>\" : sourceFile.toQuoted()));\n\n        classData.debugPrint(out, verbose);\n        annotationsDirectory.debugPrint(pw);\n\n        pw.println(\"}\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/ClassDefsSection.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.TreeMap;\n\n/**\n * Class definitions list section of a {@code .dex} file.\n */\npublic final class ClassDefsSection extends UniformItemSection {\n    /**\n     * {@code non-null;} map from type constants for classes to {@link\n     * ClassDefItem} instances that define those classes\n     */\n    private final TreeMap<Type, ClassDefItem> classDefs;\n\n    /** {@code null-ok;} ordered list of classes; set in {@link #orderItems} */\n    private ArrayList<ClassDefItem> orderedDefs;\n\n    /**\n     * Constructs an instance. The file offset is initially unknown.\n     *\n     * @param file {@code non-null;} file that this instance is part of\n     */\n    public ClassDefsSection(DexFile file) {\n        super(\"class_defs\", file, 4);\n\n        classDefs = new TreeMap<Type, ClassDefItem>();\n        orderedDefs = null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Collection<? extends Item> items() {\n        if (orderedDefs != null) {\n            return orderedDefs;\n        }\n\n        return classDefs.values();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public IndexedItem get(Constant cst) {\n        if (cst == null) {\n            throw new NullPointerException(\"cst == null\");\n        }\n\n        throwIfNotPrepared();\n\n        Type type = ((CstType) cst).getClassType();\n        IndexedItem result = classDefs.get(type);\n\n        if (result == null) {\n            throw new IllegalArgumentException(\"not found\");\n        }\n\n        return result;\n    }\n\n    /**\n     * Writes the portion of the file header that refers to this instance.\n     *\n     * @param out {@code non-null;} where to write\n     */\n    public void writeHeaderPart(AnnotatedOutput out) {\n        throwIfNotPrepared();\n\n        int sz = classDefs.size();\n        int offset = (sz == 0) ? 0 : getFileOffset();\n\n        if (out.annotates()) {\n            out.annotate(4, \"class_defs_size: \" + Hex.u4(sz));\n            out.annotate(4, \"class_defs_off:  \" + Hex.u4(offset));\n        }\n\n        out.writeInt(sz);\n        out.writeInt(offset);\n    }\n\n    /**\n     * Adds an element to this instance. It is illegal to attempt to add more\n     * than one class with the same name.\n     *\n     * @param clazz {@code non-null;} the class def to add\n     */\n    public void add(ClassDefItem clazz) {\n        Type type;\n\n        try {\n            type = clazz.getThisClass().getClassType();\n        } catch (NullPointerException ex) {\n            // Elucidate the exception.\n            throw new NullPointerException(\"clazz == null\");\n        }\n        if (classDefs.get(type)!= null){\n            return;\n        }\n        throwIfPrepared();\n\n        if (classDefs.get(type) != null) {\n            throw new IllegalArgumentException(\"already added: \" + type);\n        }\n\n        classDefs.put(type, clazz);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void orderItems() {\n        int sz = classDefs.size();\n        int idx = 0;\n\n        orderedDefs = new ArrayList<ClassDefItem>(sz);\n\n        /*\n         * Iterate over all the classes, recursively assigning an\n         * index to each, implicitly skipping the ones that have\n         * already been assigned by the time this (top-level)\n         * iteration reaches them.\n         */\n        for (Type type : classDefs.keySet()) {\n            idx = orderItems0(type, idx, sz - idx);\n        }\n    }\n\n    /**\n     * Helper for {@link #orderItems}, which recursively assigns indices\n     * to classes.\n     *\n     * @param type {@code null-ok;} type ref to assign, if any\n     * @param idx {@code >= 0;} the next index to assign\n     * @param maxDepth maximum recursion depth; if negative, this will\n     * throw an exception indicating class definition circularity\n     * @return {@code >= 0;} the next index to assign\n     */\n    private int orderItems0(Type type, int idx, int maxDepth) {\n        ClassDefItem c = classDefs.get(type);\n\n        if ((c == null) || (c.hasIndex())) {\n            return idx;\n        }\n\n        if (maxDepth < 0) {\n            throw new RuntimeException(\"class circularity with \" + type);\n        }\n\n        maxDepth--;\n\n        CstType superclassCst = c.getSuperclass();\n        if (superclassCst != null) {\n            Type superclass = superclassCst.getClassType();\n            idx = orderItems0(superclass, idx, maxDepth);\n        }\n\n        TypeList interfaces = c.getInterfaces();\n        int sz = interfaces.size();\n        for (int i = 0; i < sz; i++) {\n            idx = orderItems0(interfaces.getType(i), idx, maxDepth);\n        }\n\n        c.setIndex(idx);\n        orderedDefs.add(c);\n        return idx + 1;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/CodeItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dx.dex.code.DalvCode;\nimport com.taobao.android.dx.dex.code.DalvInsnList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport java.io.PrintWriter;\n\n/**\n * Representation of all the parts needed for concrete methods in a\n * {@code dex} file.\n */\npublic final class CodeItem extends OffsettedItem {\n    /** file alignment of this class, in bytes */\n    private static final int ALIGNMENT = 4;\n\n    /** write size of the header of this class, in bytes */\n    private static final int HEADER_SIZE = 16;\n\n    /** {@code non-null;} method that this code implements */\n    private final CstMethodRef ref;\n\n    /** {@code non-null;} the bytecode instructions and associated data */\n    private final DalvCode code;\n\n    /** {@code null-ok;} the catches, if needed; set in {@link #addContents} */\n    private CatchStructs catches;\n\n    /** whether this instance is for a {@code static} method */\n    private final boolean isStatic;\n\n    /**\n     * {@code non-null;} list of possibly-thrown exceptions; just used in\n     * generating debugging output (listings)\n     */\n    private final TypeList throwsList;\n\n    /**\n     * {@code null-ok;} the debug info or {@code null} if there is none;\n     * set in {@link #addContents}\n     */\n    private DebugInfoItem debugInfo;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param ref {@code non-null;} method that this code implements\n     * @param code {@code non-null;} the underlying code\n     * @param isStatic whether this instance is for a {@code static}\n     * method\n     * @param throwsList {@code non-null;} list of possibly-thrown exceptions,\n     * just used in generating debugging output (listings)\n     */\n    public CodeItem(CstMethodRef ref, DalvCode code, boolean isStatic,\n            TypeList throwsList) {\n        super(ALIGNMENT, -1);\n\n        if (ref == null) {\n            throw new NullPointerException(\"ref == null\");\n        }\n\n        if (code == null) {\n            throw new NullPointerException(\"code == null\");\n        }\n\n        if (throwsList == null) {\n            throw new NullPointerException(\"throwsList == null\");\n        }\n\n        this.ref = ref;\n        this.code = code;\n        this.isStatic = isStatic;\n        this.throwsList = throwsList;\n        this.catches = null;\n        this.debugInfo = null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_CODE_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    public void addContents(DexFile file) {\n        MixedItemSection byteData = file.getByteData();\n        TypeIdsSection typeIds = file.getTypeIds();\n\n        //去除debuginfo\n        if (code.hasPositions() || code.hasLocals()) {\n            debugInfo = new DebugInfoItem(code, isStatic, ref);\n            byteData.add(debugInfo);\n        }\n\n        if (code.hasAnyCatches()) {\n            for (Type type : code.getCatchTypes()) {\n                typeIds.intern(type);\n            }\n            catches = new CatchStructs(code);\n        }\n\n        for (Constant c : code.getInsnConstants()) {\n            file.internIfAppropriate(c);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return \"CodeItem{\" + toHuman() + \"}\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toHuman() {\n        return ref.toHuman();\n    }\n\n    /**\n     * Gets the reference to the method this instance implements.\n     *\n     * @return {@code non-null;} the method reference\n     */\n    public CstMethodRef getRef() {\n        return ref;\n    }\n\n    /**\n     * Does a human-friendly dump of this instance.\n     *\n     * @param out {@code non-null;} where to dump\n     * @param prefix {@code non-null;} per-line prefix to use\n     * @param verbose whether to be verbose with the output\n     */\n    public void debugPrint(PrintWriter out, String prefix, boolean verbose) {\n        out.println(ref.toHuman() + \":\");\n\n        DalvInsnList insns = code.getInsns();\n        out.println(\"regs: \" + Hex.u2(getRegistersSize()) +\n                \"; ins: \" + Hex.u2(getInsSize()) + \"; outs: \" +\n                Hex.u2(getOutsSize()));\n\n        insns.debugPrint(out, prefix, verbose);\n\n        String prefix2 = prefix + \"  \";\n\n        if (catches != null) {\n            out.print(prefix);\n            out.println(\"catches\");\n            catches.debugPrint(out, prefix2);\n        }\n\n        if (debugInfo != null) {\n            out.print(prefix);\n            out.println(\"debug info\");\n            debugInfo.debugPrint(out, prefix2);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void place0(Section addedTo, int offset) {\n        final DexFile file = addedTo.getFile();\n        int catchesSize;\n\n        /*\n         * In order to get the catches and insns, all the code's\n         * constants need to be assigned indices.\n         */\n        code.assignIndices(new DalvCode.AssignIndicesCallback() {\n                public int getIndex(Constant cst) {\n                    IndexedItem item = file.findItemOrNull(cst);\n                    if (item == null) {\n                        return -1;\n                    }\n                    return item.getIndex();\n                }\n            });\n\n        if (catches != null) {\n            catches.encode(file);\n            catchesSize = catches.writeSize();\n        } else {\n            catchesSize = 0;\n        }\n\n        /*\n         * The write size includes the header, two bytes per code\n         * unit, post-code padding if necessary, and however much\n         * space the catches need.\n         */\n\n        int insnsSize = code.getInsns().codeSize();\n        if ((insnsSize & 1) != 0) {\n            insnsSize++;\n        }\n\n        setWriteSize(HEADER_SIZE + (insnsSize * 2) + catchesSize);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void writeTo0(DexFile file, AnnotatedOutput out) {\n        boolean annotates = out.annotates();\n        int regSz = getRegistersSize();\n        int outsSz = getOutsSize();\n        int insSz = getInsSize();\n        int insnsSz = code.getInsns().codeSize();\n        boolean needPadding = (insnsSz & 1) != 0;\n        int triesSz = (catches == null) ? 0 : catches.triesSize();\n        int debugOff = (debugInfo == null) ? 0 : debugInfo.getAbsoluteOffset();\n\n        if (annotates) {\n            out.annotate(0, offsetString() + ' ' + ref.toHuman());\n            out.annotate(2, \"  registers_size: \" + Hex.u2(regSz));\n            out.annotate(2, \"  ins_size:       \" + Hex.u2(insSz));\n            out.annotate(2, \"  outs_size:      \" + Hex.u2(outsSz));\n            out.annotate(2, \"  tries_size:     \" + Hex.u2(triesSz));\n            out.annotate(4, \"  debug_off:      \" + Hex.u4(debugOff));\n            out.annotate(4, \"  insns_size:     \" + Hex.u4(insnsSz));\n\n            // This isn't represented directly here, but it is useful to see.\n            int size = throwsList.size();\n            if (size != 0) {\n                out.annotate(0, \"  throws \" + StdTypeList.toHuman(throwsList));\n            }\n        }\n\n        out.writeShort(regSz);\n        out.writeShort(insSz);\n        out.writeShort(outsSz);\n        out.writeShort(triesSz);\n        out.writeInt(debugOff);\n        out.writeInt(insnsSz);\n\n        writeCodes(file, out);\n\n        if (catches != null) {\n            if (needPadding) {\n                if (annotates) {\n                    out.annotate(2, \"  padding: 0\");\n                }\n                out.writeShort(0);\n            }\n\n            catches.writeTo(file, out);\n        }\n\n        if (annotates) {\n            /*\n             * These are pointed at in the code header (above), but it's less\n             * distracting to expand on them at the bottom of the code.\n             */\n            if (debugInfo != null) {\n                out.annotate(0, \"  debug info\");\n                debugInfo.annotateTo(file, out, \"    \");\n            }\n        }\n    }\n\n    /**\n     * Helper for {@link #writeTo0} which writes out the actual bytecode.\n     *\n     * @param file {@code non-null;} file we are part of\n     * @param out {@code non-null;} where to write to\n     */\n    private void writeCodes(DexFile file, AnnotatedOutput out) {\n        DalvInsnList insns = code.getInsns();\n\n        try {\n            insns.writeTo(out);\n        } catch (RuntimeException ex) {\n            throw ExceptionWithContext.withContext(ex, \"...while writing \" +\n                    \"instructions for \" + ref.toHuman());\n        }\n    }\n\n    /**\n     * Get the in registers count.\n     *\n     * @return the count\n     */\n    private int getInsSize() {\n        return ref.getParameterWordCount(isStatic);\n    }\n\n    /**\n     * Get the out registers count.\n     *\n     * @return the count\n     */\n    private int getOutsSize() {\n        return code.getInsns().getOutsSize();\n    }\n\n    /**\n     * Get the total registers count.\n     *\n     * @return the count\n     */\n    private int getRegistersSize() {\n        return code.getInsns().getRegistersSize();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/DebugInfoConstants.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\n/**\n * Constants for the dex debug info state machine format.\n */\npublic interface DebugInfoConstants {\n\n    /*\n     * normal opcodes\n     */\n\n    /**\n     * Terminates a debug info sequence for a method.<p>\n     * Args: none\n     *\n     */\n    static final int DBG_END_SEQUENCE = 0x00;\n\n    /**\n     * Advances the program counter/address register without emitting\n     * a positions entry.<p>\n     *\n     * Args:\n     * <ol>\n     * <li>Unsigned LEB128 &mdash; amount to advance pc by\n     * </ol>\n     */\n    static final int DBG_ADVANCE_PC = 0x01;\n\n    /**\n     * Advances the line register without emitting\n     * a positions entry.<p>\n     *\n     * Args:\n     * <ol>\n     * <li>Signed LEB128 &mdash; amount to change line register by.\n     * </ol>\n     */\n    static final int DBG_ADVANCE_LINE = 0x02;\n\n    /**\n     * Introduces a local variable at the current address.<p>\n     *\n     * Args:\n     * <ol>\n     * <li>Unsigned LEB128 &mdash; register that will contain local.\n     * <li>Unsigned LEB128 &mdash; string index (shifted by 1) of local name.\n     * <li>Unsigned LEB128 &mdash; type index (shifted by 1) of type.\n     * </ol>\n     */\n    static final int DBG_START_LOCAL = 0x03;\n\n    /**\n     * Introduces a local variable at the current address with a type\n     * signature specified.<p>\n     *\n     * Args:\n     * <ol>\n     * <li>Unsigned LEB128 &mdash; register that will contain local.\n     * <li>Unsigned LEB128 &mdash; string index (shifted by 1) of local name.\n     * <li>Unsigned LEB128 &mdash; type index (shifted by 1) of type.\n     * <li>Unsigned LEB128 &mdash; string index (shifted by 1) of\n     * type signature.\n     * </ol>\n     */\n    static final int DBG_START_LOCAL_EXTENDED = 0x04;\n\n    /**\n     * Marks a currently-live local variable as out of scope at the\n     * current address.<p>\n     *\n     * Args:\n     * <ol>\n     * <li>Unsigned LEB128 &mdash; register that contained local\n     * </ol>\n     */\n    static final int DBG_END_LOCAL = 0x05;\n\n    /**\n     * Re-introduces a local variable at the current address. The name\n     * and type are the same as the last local that was live in the specified\n     * register.<p>\n     *\n     * Args:\n     * <ol>\n     * <li>Unsigned LEB128 &mdash; register to re-start.\n     * </ol>\n     */\n    static final int DBG_RESTART_LOCAL = 0x06;\n\n\n    /**\n     * Sets the \"prologue_end\" state machine register, indicating that the\n     * next position entry that is added should be considered the end of\n     * a method prologue (an appropriate place for a method breakpoint).<p>\n     *\n     * The prologue_end register is cleared by any special\n     * ({@code >= OPCODE_BASE}) opcode.\n     */\n    static final int DBG_SET_PROLOGUE_END = 0x07;\n\n    /**\n     * Sets the \"epilogue_begin\" state machine register, indicating that the\n     * next position entry that is added should be considered the beginning of\n     * a method epilogue (an appropriate place to suspend execution before\n     * method exit).<p>\n     *\n     * The epilogue_begin register is cleared by any special\n     * ({@code >= OPCODE_BASE}) opcode.\n     */\n    static final int DBG_SET_EPILOGUE_BEGIN = 0x08;\n\n    /**\n     * Sets the current file that that line numbers refer to. All subsequent\n     * line number entries make reference to this source file name, instead\n     * of the default name specified in code_item.\n     *\n     * Args:\n     * <ol>\n     * <li>Unsigned LEB128 &mdash; string index (shifted by 1) of source\n     * file name.\n     * </ol>\n     */\n    static final int DBG_SET_FILE = 0x09;\n\n    /* IF YOU ADD A NEW OPCODE, increase OPCODE_BASE */\n\n    /*\n     * \"special opcode\" configuration, essentially what's found in\n     * the line number program header in DWARFv3, Section 6.2.4\n     */\n\n    /** the smallest value a special opcode can take */\n    static final int DBG_FIRST_SPECIAL = 0x0a;\n    static final int DBG_LINE_BASE = -4;\n    static final int DBG_LINE_RANGE = 15;\n    // MIN_INSN_LENGTH is always 1\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/DebugInfoDecoder.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.util.ByteArrayByteInput;\nimport com.taobao.android.dex.util.ByteInput;\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dex.Leb128;\nimport com.taobao.android.dx.dex.code.DalvCode;\nimport com.taobao.android.dx.dex.code.DalvInsnList;\nimport com.taobao.android.dx.dex.code.LocalList;\nimport com.taobao.android.dx.dex.code.PositionList;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_ADVANCE_LINE;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_ADVANCE_PC;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_END_LOCAL;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_END_SEQUENCE;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_FIRST_SPECIAL;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_LINE_BASE;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_LINE_RANGE;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_RESTART_LOCAL;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_SET_EPILOGUE_BEGIN;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_SET_FILE;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_SET_PROLOGUE_END;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_START_LOCAL;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_START_LOCAL_EXTENDED;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.type.Prototype;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * A decoder for the dex debug info state machine format.\n * This code exists mostly as a reference implementation and test for\n * for the {@code DebugInfoEncoder}\n */\npublic class DebugInfoDecoder {\n    /** encoded debug info */\n    private final byte[] encoded;\n\n    /** positions decoded */\n    private final ArrayList<PositionEntry> positions;\n\n    /** locals decoded */\n    private final ArrayList<LocalEntry> locals;\n\n    /** size of code block in code units */\n    private final int codesize;\n\n    /** indexed by register, the last local variable live in a reg */\n    private final LocalEntry[] lastEntryForReg;\n\n    /** method descriptor of method this debug info is for */\n    private final Prototype desc;\n\n    /** true if method is static */\n    private final boolean isStatic;\n\n    /** dex file this debug info will be stored in */\n    private final DexFile file;\n\n    /**\n     * register size, in register units, of the register space\n     * used by this method\n     */\n    private final int regSize;\n\n    /** current decoding state: line number */\n    private int line = 1;\n\n    /** current decoding state: bytecode address */\n    private int address = 0;\n\n    /** string index of the string \"this\" */\n    private final int thisStringIdx;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param encoded encoded debug info\n     * @param codesize size of code block in code units\n     * @param regSize register size, in register units, of the register space\n     * used by this method\n     * @param isStatic true if method is static\n     * @param ref method descriptor of method this debug info is for\n     * @param file dex file this debug info will be stored in\n     */\n    DebugInfoDecoder(byte[] encoded, int codesize, int regSize,\n            boolean isStatic, CstMethodRef ref, DexFile file) {\n        if (encoded == null) {\n            throw new NullPointerException(\"encoded == null\");\n        }\n\n        this.encoded = encoded;\n        this.isStatic = isStatic;\n        this.desc = ref.getPrototype();\n        this.file = file;\n        this.regSize = regSize;\n\n        positions = new ArrayList<PositionEntry>();\n        locals = new ArrayList<LocalEntry>();\n        this.codesize = codesize;\n        lastEntryForReg = new LocalEntry[regSize];\n\n        int idx = -1;\n\n        try {\n            idx = file.getStringIds().indexOf(new CstString(\"this\"));\n        } catch (IllegalArgumentException ex) {\n            /*\n             * Silently tolerate not finding \"this\". It just means that\n             * no method has local variable info that looks like\n             * a standard instance method.\n             */\n        }\n\n        thisStringIdx = idx;\n    }\n\n    /**\n     * An entry in the resulting postions table\n     */\n    static private class PositionEntry {\n        /** bytecode address */\n        public int address;\n\n        /** line number */\n        public int line;\n\n        public PositionEntry(int address, int line) {\n            this.address = address;\n            this.line = line;\n        }\n    }\n\n    /**\n     * An entry in the resulting locals table\n     */\n    static private class LocalEntry {\n        /** address of event */\n        public int address;\n\n        /** {@code true} iff it's a local start */\n        public boolean isStart;\n\n        /** register number */\n        public int reg;\n\n        /** index of name in strings table */\n        public int nameIndex;\n\n        /** index of type in types table */\n        public int typeIndex;\n\n        /** index of type signature in strings table */\n        public int signatureIndex;\n\n        public LocalEntry(int address, boolean isStart, int reg, int nameIndex,\n                int typeIndex, int signatureIndex) {\n            this.address        = address;\n            this.isStart        = isStart;\n            this.reg            = reg;\n            this.nameIndex      = nameIndex;\n            this.typeIndex      = typeIndex;\n            this.signatureIndex = signatureIndex;\n        }\n\n        public String toString() {\n            return String.format(\"[%x %s v%d %04x %04x %04x]\",\n                    address, isStart ? \"start\" : \"end\", reg,\n                    nameIndex, typeIndex, signatureIndex);\n        }\n    }\n\n    /**\n     * Gets the decoded positions list.\n     * Valid after calling {@code decode}.\n     *\n     * @return positions list in ascending address order.\n     */\n    public List<PositionEntry> getPositionList() {\n        return positions;\n    }\n\n    /**\n     * Gets the decoded locals list, in ascending start-address order.\n     * Valid after calling {@code decode}.\n     *\n     * @return locals list in ascending address order.\n     */\n    public List<LocalEntry> getLocals() {\n        return locals;\n    }\n\n    /**\n     * Decodes the debug info sequence.\n     */\n    public void decode() {\n        try {\n            decode0();\n        } catch (Exception ex) {\n            throw ExceptionWithContext.withContext(ex,\n                    \"...while decoding debug info\");\n        }\n    }\n\n    /**\n     * Reads a string index. String indicies are offset by 1, and a 0 value\n     * in the stream (-1 as returned by this method) means \"null\"\n     *\n     * @return index into file's string ids table, -1 means null\n     * @throws IOException\n     */\n    private int readStringIndex(ByteInput bs) throws IOException {\n        int offsetIndex = Leb128.readUnsignedLeb128(bs);\n\n        return offsetIndex - 1;\n    }\n\n    /**\n     * Gets the register that begins the method's parameter range (including\n     * the 'this' parameter for non-static methods). The range continues until\n     * {@code regSize}\n     *\n     * @return register as noted above.\n     */\n    private int getParamBase() {\n        return regSize\n                - desc.getParameterTypes().getWordCount() - (isStatic? 0 : 1);\n    }\n\n    private void decode0() throws IOException {\n        ByteInput bs = new ByteArrayByteInput(encoded);\n\n        line = Leb128.readUnsignedLeb128(bs);\n        int szParams = Leb128.readUnsignedLeb128(bs);\n        StdTypeList params = desc.getParameterTypes();\n        int curReg = getParamBase();\n\n        if (szParams != params.size()) {\n            throw new RuntimeException(\n                    \"Mismatch between parameters_size and prototype\");\n        }\n\n        if (!isStatic) {\n            // Start off with implicit 'this' entry\n            LocalEntry thisEntry =\n                new LocalEntry(0, true, curReg, thisStringIdx, 0, 0);\n            locals.add(thisEntry);\n            lastEntryForReg[curReg] = thisEntry;\n            curReg++;\n        }\n\n        for (int i = 0; i < szParams; i++) {\n            Type paramType = params.getType(i);\n            LocalEntry le;\n\n            int nameIdx = readStringIndex(bs);\n\n            if (nameIdx == -1) {\n                /*\n                 * Unnamed parameter; often but not always filled in by an\n                 * extended start op after the prologue\n                 */\n                le = new LocalEntry(0, true, curReg, -1, 0, 0);\n            } else {\n                // TODO: Final 0 should be idx of paramType.getDescriptor().\n                le = new LocalEntry(0, true, curReg, nameIdx, 0, 0);\n            }\n\n            locals.add(le);\n            lastEntryForReg[curReg] = le;\n            curReg += paramType.getCategory();\n        }\n\n        for (;;) {\n            int opcode = bs.readByte() & 0xff;\n\n            switch (opcode) {\n                case DBG_START_LOCAL: {\n                    int reg = Leb128.readUnsignedLeb128(bs);\n                    int nameIdx = readStringIndex(bs);\n                    int typeIdx = readStringIndex(bs);\n                    LocalEntry le = new LocalEntry(\n                            address, true, reg, nameIdx, typeIdx, 0);\n\n                    locals.add(le);\n                    lastEntryForReg[reg] = le;\n                }\n                break;\n\n                case DBG_START_LOCAL_EXTENDED: {\n                    int reg = Leb128.readUnsignedLeb128(bs);\n                    int nameIdx = readStringIndex(bs);\n                    int typeIdx = readStringIndex(bs);\n                    int sigIdx = readStringIndex(bs);\n                    LocalEntry le = new LocalEntry(\n                            address, true, reg, nameIdx, typeIdx, sigIdx);\n\n                    locals.add(le);\n                    lastEntryForReg[reg] = le;\n                }\n                break;\n\n                case DBG_RESTART_LOCAL: {\n                    int reg = Leb128.readUnsignedLeb128(bs);\n                    LocalEntry prevle;\n                    LocalEntry le;\n\n                    try {\n                        prevle = lastEntryForReg[reg];\n\n                        if (prevle.isStart) {\n                            throw new RuntimeException(\"nonsensical \"\n                                    + \"RESTART_LOCAL on live register v\"\n                                    + reg);\n                        }\n\n                        le = new LocalEntry(address, true, reg,\n                                prevle.nameIndex, prevle.typeIndex, 0);\n                    } catch (NullPointerException ex) {\n                        throw new RuntimeException(\n                                \"Encountered RESTART_LOCAL on new v\" + reg);\n                    }\n\n                    locals.add(le);\n                    lastEntryForReg[reg] = le;\n                }\n                break;\n\n                case DBG_END_LOCAL: {\n                    int reg = Leb128.readUnsignedLeb128(bs);\n                    LocalEntry prevle;\n                    LocalEntry le;\n\n                    try {\n                        prevle = lastEntryForReg[reg];\n\n                        if (!prevle.isStart) {\n                            throw new RuntimeException(\"nonsensical \"\n                                    + \"END_LOCAL on dead register v\" + reg);\n                        }\n\n                        le = new LocalEntry(address, false, reg,\n                                prevle.nameIndex, prevle.typeIndex,\n                                prevle.signatureIndex);\n                    } catch (NullPointerException ex) {\n                        throw new RuntimeException(\n                                \"Encountered END_LOCAL on new v\" + reg);\n                    }\n\n                    locals.add(le);\n                    lastEntryForReg[reg] = le;\n                }\n                break;\n\n                case DBG_END_SEQUENCE:\n                    // all done\n                return;\n\n                case DBG_ADVANCE_PC:\n                    address += Leb128.readUnsignedLeb128(bs);\n                break;\n\n                case DBG_ADVANCE_LINE:\n                    line += Leb128.readSignedLeb128(bs);\n                break;\n\n                case DBG_SET_PROLOGUE_END:\n                    //TODO do something with this.\n                break;\n\n                case DBG_SET_EPILOGUE_BEGIN:\n                    //TODO do something with this.\n                break;\n\n                case DBG_SET_FILE:\n                    //TODO do something with this.\n                break;\n\n                default:\n                    if (opcode < DBG_FIRST_SPECIAL) {\n                        throw new RuntimeException(\n                                \"Invalid extended opcode encountered \"\n                                        + opcode);\n                    }\n\n                    int adjopcode = opcode - DBG_FIRST_SPECIAL;\n\n                    address += adjopcode / DBG_LINE_RANGE;\n                    line += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE);\n\n                    positions.add(new PositionEntry(address, line));\n                break;\n\n            }\n        }\n    }\n\n    /**\n     * Validates an encoded debug info stream against data used to encode it,\n     * throwing an exception if they do not match. Used to validate the\n     * encoder.\n     *\n     * @param info encoded debug info\n     * @param file {@code non-null;} file to refer to during decoding\n     * @param ref {@code non-null;} method whose info is being decoded\n     * @param code {@code non-null;} original code object that was encoded\n     * @param isStatic whether the method is static\n     */\n    public static void validateEncode(byte[] info, DexFile file,\n            CstMethodRef ref, DalvCode code, boolean isStatic) {\n        PositionList pl = code.getPositions();\n        LocalList ll = code.getLocals();\n        DalvInsnList insns = code.getInsns();\n        int codeSize = insns.codeSize();\n        int countRegisters = insns.getRegistersSize();\n\n        try {\n            validateEncode0(info, codeSize, countRegisters,\n                    isStatic, ref, file, pl, ll);\n        } catch (RuntimeException ex) {\n            System.err.println(\"instructions:\");\n            insns.debugPrint(System.err, \"  \", true);\n            System.err.println(\"local list:\");\n            ll.debugPrint(System.err, \"  \");\n            throw ExceptionWithContext.withContext(ex,\n                    \"while processing \" + ref.toHuman());\n        }\n    }\n\n    private static void validateEncode0(byte[] info, int codeSize,\n            int countRegisters, boolean isStatic, CstMethodRef ref,\n            DexFile file, PositionList pl, LocalList ll) {\n        DebugInfoDecoder decoder\n                = new DebugInfoDecoder(info, codeSize, countRegisters,\n                    isStatic, ref, file);\n\n        decoder.decode();\n\n        /*\n         * Go through the decoded position entries, matching up\n         * with original entries.\n         */\n\n        List<PositionEntry> decodedEntries = decoder.getPositionList();\n\n        if (decodedEntries.size() != pl.size()) {\n            throw new RuntimeException(\n                    \"Decoded positions table not same size was \"\n                    + decodedEntries.size() + \" expected \" + pl.size());\n        }\n\n        for (PositionEntry entry : decodedEntries) {\n            boolean found = false;\n            for (int i = pl.size() - 1; i >= 0; i--) {\n                PositionList.Entry ple = pl.get(i);\n\n                if (entry.line == ple.getPosition().getLine()\n                        && entry.address == ple.getAddress()) {\n                    found = true;\n                    break;\n                }\n            }\n\n            if (!found) {\n                throw new RuntimeException (\"Could not match position entry: \"\n                        + entry.address + \", \" + entry.line);\n            }\n        }\n\n        /*\n         * Go through the original local list, in order, matching up\n         * with decoded entries.\n         */\n\n        List<LocalEntry> decodedLocals = decoder.getLocals();\n        int thisStringIdx = decoder.thisStringIdx;\n        int decodedSz = decodedLocals.size();\n        int paramBase = decoder.getParamBase();\n\n        /*\n         * Preflight to fill in any parameters that were skipped in\n         * the prologue (including an implied \"this\") but then\n         * identified by full signature.\n         */\n        for (int i = 0; i < decodedSz; i++) {\n            LocalEntry entry = decodedLocals.get(i);\n            int idx = entry.nameIndex;\n\n            if ((idx < 0) || (idx == thisStringIdx)) {\n                for (int j = i + 1; j < decodedSz; j++) {\n                    LocalEntry e2 = decodedLocals.get(j);\n                    if (e2.address != 0) {\n                        break;\n                    }\n                    if ((entry.reg == e2.reg) && e2.isStart) {\n                        decodedLocals.set(i, e2);\n                        decodedLocals.remove(j);\n                        decodedSz--;\n                        break;\n                    }\n                }\n            }\n        }\n\n        int origSz = ll.size();\n        int decodeAt = 0;\n        boolean problem = false;\n\n        for (int i = 0; i < origSz; i++) {\n            LocalList.Entry origEntry = ll.get(i);\n\n            if (origEntry.getDisposition()\n                    == LocalList.Disposition.END_REPLACED) {\n                /*\n                 * The encoded list doesn't represent replacements, so\n                 * ignore them for the sake of comparison.\n                 */\n                continue;\n            }\n\n            LocalEntry decodedEntry;\n\n            do {\n                decodedEntry = decodedLocals.get(decodeAt);\n                if (decodedEntry.nameIndex >= 0) {\n                    break;\n                }\n                /*\n                 * A negative name index means this is an anonymous\n                 * parameter, and we shouldn't expect to see it in the\n                 * original list. So, skip it.\n                 */\n                decodeAt++;\n            } while (decodeAt < decodedSz);\n\n            int decodedAddress = decodedEntry.address;\n\n            if (decodedEntry.reg != origEntry.getRegister()) {\n                System.err.println(\"local register mismatch at orig \" + i +\n                        \" / decoded \" + decodeAt);\n                problem = true;\n                break;\n            }\n\n            if (decodedEntry.isStart != origEntry.isStart()) {\n                System.err.println(\"local start/end mismatch at orig \" + i +\n                        \" / decoded \" + decodeAt);\n                problem = true;\n                break;\n            }\n\n            /*\n             * The secondary check here accounts for the fact that a\n             * parameter might not be marked as starting at 0 in the\n             * original list.\n             */\n            if ((decodedAddress != origEntry.getAddress())\n                    && !((decodedAddress == 0)\n                            && (decodedEntry.reg >= paramBase))) {\n                System.err.println(\"local address mismatch at orig \" + i +\n                        \" / decoded \" + decodeAt);\n                problem = true;\n                break;\n            }\n\n            decodeAt++;\n        }\n\n        if (problem) {\n            System.err.println(\"decoded locals:\");\n            for (LocalEntry e : decodedLocals) {\n                System.err.println(\"  \" + e);\n            }\n            throw new RuntimeException(\"local table problem\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/DebugInfoEncoder.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dx.dex.code.LocalList;\nimport com.taobao.android.dx.dex.code.PositionList;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_ADVANCE_LINE;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_ADVANCE_PC;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_END_LOCAL;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_END_SEQUENCE;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_FIRST_SPECIAL;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_LINE_BASE;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_LINE_RANGE;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_RESTART_LOCAL;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_SET_PROLOGUE_END;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_START_LOCAL;\nimport static com.taobao.android.dx.dex.file.DebugInfoConstants.DBG_START_LOCAL_EXTENDED;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Prototype;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.ByteArrayAnnotatedOutput;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.Collections;\nimport java.util.Comparator;\n\n/**\n * An encoder for the dex debug info state machine format. The format\n * for each method enrty is as follows:\n * <ol>\n * <li> signed LEB128: initial value for line register.\n * <li> n instances of signed LEB128: string indicies (offset by 1)\n * for each method argument in left-to-right order\n * with {@code this} excluded. A value of '0' indicates \"no name\"\n * <li> A sequence of special or normal opcodes as defined in\n * {@code DebugInfoConstants}.\n * <li> A single terminating {@code OP_END_SEQUENCE}\n * </ol>\n */\npublic final class DebugInfoEncoder {\n    private static final boolean DEBUG = false;\n\n    /** {@code null-ok;} positions (line numbers) to encode */\n    private final PositionList positions;\n\n    /** {@code null-ok;} local variables to encode */\n    private final LocalList locals;\n\n    private final ByteArrayAnnotatedOutput output;\n    private final DexFile file;\n    private final int codeSize;\n    private final int regSize;\n\n    private final Prototype desc;\n    private final boolean isStatic;\n\n    /** current encoding state: bytecode address */\n    private int address = 0;\n\n    /** current encoding state: line number */\n    private int line = 1;\n\n    /**\n     * if non-null: the output to write annotations to. No normal\n     * output is written to this.\n     */\n    private AnnotatedOutput annotateTo;\n\n    /** if non-null: another possible output for annotations */\n    private PrintWriter debugPrint;\n\n    /** if non-null: the prefix for each annotation or debugPrint line */\n    private String prefix;\n\n    /** true if output should be consumed during annotation */\n    private boolean shouldConsume;\n\n    /** indexed by register; last local alive in register */\n    private final LocalList.Entry[] lastEntryForReg;\n\n    /**\n     * Creates an instance.\n     *\n     * @param positions {@code null-ok;} positions (line numbers) to encode\n     * @param locals {@code null-ok;} local variables to encode\n     * @param file {@code null-ok;} may only be {@code null} if simply using\n     * this class to do a debug print\n     * @param codeSize\n     * @param regSize\n     * @param isStatic\n     * @param ref\n     */\n    public DebugInfoEncoder(PositionList positions, LocalList locals,\n            DexFile file, int codeSize, int regSize,\n            boolean isStatic, CstMethodRef ref) {\n        this.positions = positions;\n        this.locals = locals;\n        this.file = file;\n        this.desc = ref.getPrototype();\n        this.isStatic = isStatic;\n        this.codeSize = codeSize;\n        this.regSize = regSize;\n\n        output = new ByteArrayAnnotatedOutput();\n        lastEntryForReg = new LocalList.Entry[regSize];\n    }\n\n    /**\n     * Annotates or writes a message to the {@code debugPrint} writer\n     * if applicable.\n     *\n     * @param length the number of bytes associated with this message\n     * @param message the message itself\n     */\n    private void annotate(int length, String message) {\n        if (prefix != null) {\n            message = prefix + message;\n        }\n\n        if (annotateTo != null) {\n            annotateTo.annotate(shouldConsume ? length : 0, message);\n        }\n\n        if (debugPrint != null) {\n            debugPrint.println(message);\n        }\n    }\n\n    /**\n     * Converts this (PositionList, LocalList) pair into a state machine\n     * sequence.\n     *\n     * @return {@code non-null;} encoded byte sequence without padding and\n     * terminated with a {@code 0x00} byte\n     */\n    public byte[] convert() {\n        try {\n            byte[] ret;\n            ret = convert0();\n\n            if (DEBUG) {\n                for (int i = 0 ; i < ret.length; i++) {\n                    System.err.printf(\"byte %02x\\n\", (0xff & ret[i]));\n                }\n            }\n\n            return ret;\n        } catch (IOException ex) {\n            throw ExceptionWithContext\n                    .withContext(ex, \"...while encoding debug info\");\n        }\n    }\n\n    /**\n     * Converts and produces annotations on a stream. Does not write\n     * actual bits to the {@code AnnotatedOutput}.\n     *\n     * @param prefix {@code null-ok;} prefix to attach to each line of output\n     * @param debugPrint {@code null-ok;} if specified, an alternate output for\n     * annotations\n     * @param out {@code null-ok;} if specified, where annotations should go\n     * @param consume whether to claim to have consumed output for\n     * {@code out}\n     * @return {@code non-null;} encoded output\n     */\n    public byte[] convertAndAnnotate(String prefix, PrintWriter debugPrint,\n            AnnotatedOutput out, boolean consume) {\n        this.prefix = prefix;\n        this.debugPrint = debugPrint;\n        annotateTo = out;\n        shouldConsume = consume;\n\n        byte[] result = convert();\n\n        return result;\n    }\n\n    private byte[] convert0() throws IOException {\n        ArrayList<PositionList.Entry> sortedPositions = buildSortedPositions();\n        ArrayList<LocalList.Entry> methodArgs = extractMethodArguments();\n\n        emitHeader(sortedPositions, methodArgs);\n\n        // TODO: Make this mark be the actual prologue end.\n        output.writeByte(DBG_SET_PROLOGUE_END);\n\n        if (annotateTo != null || debugPrint != null) {\n            annotate(1, String.format(\"%04x: prologue end\",address));\n        }\n\n        int positionsSz = sortedPositions.size();\n        int localsSz = locals.size();\n\n        // Current index in sortedPositions\n        int curPositionIdx = 0;\n        // Current index in locals\n        int curLocalIdx = 0;\n\n        for (;;) {\n            /*\n             * Emit any information for the current address.\n             */\n\n            curLocalIdx = emitLocalsAtAddress(curLocalIdx);\n            curPositionIdx =\n                emitPositionsAtAddress(curPositionIdx, sortedPositions);\n\n            /*\n             * Figure out what the next important address is.\n             */\n\n            int nextAddrL = Integer.MAX_VALUE; // local variable\n            int nextAddrP = Integer.MAX_VALUE; // position (line number)\n\n            if (curLocalIdx < localsSz) {\n                nextAddrL = locals.get(curLocalIdx).getAddress();\n            }\n\n            if (curPositionIdx < positionsSz) {\n                nextAddrP = sortedPositions.get(curPositionIdx).getAddress();\n            }\n\n            int next = Math.min(nextAddrP, nextAddrL);\n\n            // No next important address == done.\n            if (next == Integer.MAX_VALUE) {\n                break;\n            }\n\n            /*\n             * If the only work remaining are local ends at the end of the\n             * block, stop here. Those are implied anyway.\n             */\n            if (next == codeSize\n                    && nextAddrL == Integer.MAX_VALUE\n                    && nextAddrP == Integer.MAX_VALUE) {\n                break;\n            }\n\n            if (next == nextAddrP) {\n                // Combined advance PC + position entry\n                emitPosition(sortedPositions.get(curPositionIdx++));\n            } else {\n                emitAdvancePc(next - address);\n            }\n        }\n\n        emitEndSequence();\n\n        return output.toByteArray();\n    }\n\n    /**\n     * Emits all local variable activity that occurs at the current\n     * {@link #address} starting at the given index into {@code\n     * locals} and including all subsequent activity at the same\n     * address.\n     *\n     * @param curLocalIdx Current index in locals\n     * @return new value for {@code curLocalIdx}\n     * @throws IOException\n     */\n    private int emitLocalsAtAddress(int curLocalIdx)\n            throws IOException {\n        int sz = locals.size();\n\n        // TODO: Don't emit ends implied by starts.\n\n        while ((curLocalIdx < sz)\n                && (locals.get(curLocalIdx).getAddress() == address)) {\n            LocalList.Entry entry = locals.get(curLocalIdx++);\n            int reg = entry.getRegister();\n            LocalList.Entry prevEntry = lastEntryForReg[reg];\n\n            if (entry == prevEntry) {\n                /*\n                 * Here we ignore locals entries for parameters,\n                 * which have already been represented and placed in the\n                 * lastEntryForReg array.\n                 */\n                continue;\n            }\n\n            // At this point we have a new entry one way or another.\n            lastEntryForReg[reg] = entry;\n\n            if (entry.isStart()) {\n                if ((prevEntry != null) && entry.matches(prevEntry)) {\n                    /*\n                     * The previous local in this register has the same\n                     * name and type as the one being introduced now, so\n                     * use the more efficient \"restart\" form.\n                     */\n                    if (prevEntry.isStart()) {\n                        /*\n                         * We should never be handed a start when a\n                         * a matching local is already active.\n                         */\n                        throw new RuntimeException(\"shouldn't happen\");\n                    }\n                    emitLocalRestart(entry);\n                } else {\n                    emitLocalStart(entry);\n                }\n            } else {\n                /*\n                 * Only emit a local end if it is *not* due to a direct\n                 * replacement. Direct replacements imply an end of the\n                 * previous local in the same register.\n                 *\n                 * TODO: Make sure the runtime can deal with implied\n                 * local ends from category-2 interactions, and when so,\n                 * also stop emitting local ends for those cases.\n                 */\n                if (entry.getDisposition()\n                        != LocalList.Disposition.END_REPLACED) {\n                    emitLocalEnd(entry);\n                }\n            }\n        }\n\n        return curLocalIdx;\n    }\n\n    /**\n     * Emits all positions that occur at the current {@code address}\n     *\n     * @param curPositionIdx Current index in sortedPositions\n     * @param sortedPositions positions, sorted by ascending address\n     * @return new value for {@code curPositionIdx}\n     * @throws IOException\n     */\n    private int emitPositionsAtAddress(int curPositionIdx,\n            ArrayList<PositionList.Entry> sortedPositions)\n            throws IOException {\n        int positionsSz = sortedPositions.size();\n        while ((curPositionIdx < positionsSz)\n                && (sortedPositions.get(curPositionIdx).getAddress()\n                        == address)) {\n            emitPosition(sortedPositions.get(curPositionIdx++));\n        }\n        return curPositionIdx;\n    }\n\n    /**\n     * Emits the header sequence, which consists of LEB128-encoded initial\n     * line number and string indicies for names of all non-\"this\" arguments.\n     *\n     * @param sortedPositions positions, sorted by ascending address\n     * @param methodArgs local list entries for method argumens arguments,\n     * in left-to-right order omitting \"this\"\n     * @throws IOException\n     */\n    private void emitHeader(ArrayList<PositionList.Entry> sortedPositions,\n            ArrayList<LocalList.Entry> methodArgs) throws IOException {\n        boolean annotate = (annotateTo != null) || (debugPrint != null);\n        int mark = output.getCursor();\n\n        // Start by initializing the line number register.\n        if (sortedPositions.size() > 0) {\n            PositionList.Entry entry = sortedPositions.get(0);\n            line = entry.getPosition().getLine();\n        }\n        output.writeUleb128(line);\n\n        if (annotate) {\n            annotate(output.getCursor() - mark, \"line_start: \" + line);\n        }\n\n        int curParam = getParamBase();\n        // paramTypes will not include 'this'\n        StdTypeList paramTypes = desc.getParameterTypes();\n        int szParamTypes = paramTypes.size();\n\n        /*\n         * Initialize lastEntryForReg to have an initial\n         * entry for the 'this' pointer.\n         */\n        if (!isStatic) {\n            for (LocalList.Entry arg : methodArgs) {\n                if (curParam == arg.getRegister()) {\n                    lastEntryForReg[curParam] = arg;\n                    break;\n                }\n            }\n            curParam++;\n        }\n\n        // Write out the number of parameter entries that will follow.\n        mark = output.getCursor();\n        output.writeUleb128(szParamTypes);\n\n        if (annotate) {\n            annotate(output.getCursor() - mark,\n                    String.format(\"parameters_size: %04x\", szParamTypes));\n        }\n\n        /*\n         * Then emit the string indicies of all the method parameters.\n         * Note that 'this', if applicable, is excluded.\n         */\n        for (int i = 0; i < szParamTypes; i++) {\n            Type pt = paramTypes.get(i);\n            LocalList.Entry found = null;\n\n            mark = output.getCursor();\n\n            for (LocalList.Entry arg : methodArgs) {\n                if (curParam == arg.getRegister()) {\n                    found = arg;\n\n                    if (arg.getSignature() != null) {\n                        /*\n                         * Parameters with signatures will be re-emitted\n                         * in complete as LOCAL_START_EXTENDED's below.\n                         */\n                        emitStringIndex(null);\n                    } else {\n                        emitStringIndex(arg.getName());\n                    }\n                    lastEntryForReg[curParam] = arg;\n\n                    break;\n                }\n            }\n\n            if (found == null) {\n                /*\n                 * Emit a null symbol for \"unnamed.\" This is common\n                 * for, e.g., synthesized methods and inner-class\n                 * this$0 arguments.\n                 */\n                emitStringIndex(null);\n            }\n\n            if (annotate) {\n                String parameterName\n                        = (found == null || found.getSignature() != null)\n                                ? \"<unnamed>\" : found.getName().toHuman();\n                annotate(output.getCursor() - mark,\n                        \"parameter \" + parameterName + \" \"\n                                + RegisterSpec.PREFIX + curParam);\n            }\n\n            curParam += pt.getCategory();\n        }\n\n        /*\n         * If anything emitted above has a type signature, emit it again as\n         * a LOCAL_RESTART_EXTENDED\n         */\n\n        for (LocalList.Entry arg : lastEntryForReg) {\n            if (arg == null) {\n                continue;\n            }\n\n            CstString signature = arg.getSignature();\n\n            if (signature != null) {\n                emitLocalStartExtended(arg);\n            }\n        }\n    }\n\n    /**\n     * Builds a list of position entries, sorted by ascending address.\n     *\n     * @return A sorted positions list\n     */\n    private ArrayList<PositionList.Entry> buildSortedPositions() {\n        int sz = (positions == null) ? 0 : positions.size();\n        ArrayList<PositionList.Entry> result = new ArrayList(sz);\n\n        for (int i = 0; i < sz; i++) {\n            result.add(positions.get(i));\n        }\n\n        // Sort ascending by address.\n        Collections.sort (result, new Comparator<PositionList.Entry>() {\n            public int compare (PositionList.Entry a, PositionList.Entry b) {\n                return a.getAddress() - b.getAddress();\n            }\n\n            public boolean equals (Object obj) {\n               return obj == this;\n            }\n        });\n        return result;\n    }\n\n    /**\n     * Gets the register that begins the method's parameter range (including\n     * the 'this' parameter for non-static methods). The range continues until\n     * {@code regSize}\n     *\n     * @return register as noted above\n     */\n    private int getParamBase() {\n        return regSize\n                - desc.getParameterTypes().getWordCount() - (isStatic? 0 : 1);\n    }\n\n    /**\n     * Extracts method arguments from a locals list. These will be collected\n     * from the input list and sorted by ascending register in the\n     * returned list.\n     *\n     * @return list of non-{@code this} method argument locals,\n     * sorted by ascending register\n     */\n    private ArrayList<LocalList.Entry> extractMethodArguments() {\n        ArrayList<LocalList.Entry> result\n                = new ArrayList(desc.getParameterTypes().size());\n        int argBase = getParamBase();\n        BitSet seen = new BitSet(regSize - argBase);\n        int sz = locals.size();\n\n        for (int i = 0; i < sz; i++) {\n            LocalList.Entry e = locals.get(i);\n            int reg = e.getRegister();\n\n            if (reg < argBase) {\n                continue;\n            }\n\n            // only the lowest-start-address entry is included.\n            if (seen.get(reg - argBase)) {\n                continue;\n            }\n\n            seen.set(reg - argBase);\n            result.add(e);\n        }\n\n        // Sort by ascending register.\n        Collections.sort(result, new Comparator<LocalList.Entry>() {\n            public int compare(LocalList.Entry a, LocalList.Entry b) {\n                return a.getRegister() - b.getRegister();\n            }\n\n            public boolean equals(Object obj) {\n               return obj == this;\n            }\n        });\n\n        return result;\n    }\n\n    /**\n     * Returns a string representation of this LocalList entry that is\n     * appropriate for emitting as an annotation.\n     *\n     * @param e {@code non-null;} entry\n     * @return {@code non-null;} annotation string\n     */\n    private String entryAnnotationString(LocalList.Entry e) {\n        StringBuilder sb = new StringBuilder();\n\n        sb.append(RegisterSpec.PREFIX);\n        sb.append(e.getRegister());\n        sb.append(' ');\n\n        CstString name = e.getName();\n        if (name == null) {\n            sb.append(\"null\");\n        } else {\n            sb.append(name.toHuman());\n        }\n        sb.append(' ');\n\n        CstType type = e.getType();\n        if (type == null) {\n            sb.append(\"null\");\n        } else {\n            sb.append(type.toHuman());\n        }\n\n        CstString signature = e.getSignature();\n\n        if (signature != null) {\n            sb.append(' ');\n            sb.append(signature.toHuman());\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Emits a {@link DebugInfoConstants#DBG_RESTART_LOCAL DBG_RESTART_LOCAL}\n     * sequence.\n     *\n     * @param entry entry associated with this restart\n     * @throws IOException\n     */\n    private void emitLocalRestart(LocalList.Entry entry)\n            throws IOException {\n\n        int mark = output.getCursor();\n\n        output.writeByte(DBG_RESTART_LOCAL);\n        emitUnsignedLeb128(entry.getRegister());\n\n        if (annotateTo != null || debugPrint != null) {\n            annotate(output.getCursor() - mark,\n                    String.format(\"%04x: +local restart %s\",\n                            address, entryAnnotationString(entry)));\n        }\n\n        if (DEBUG) {\n            System.err.println(\"emit local restart\");\n        }\n    }\n\n    /**\n     * Emits a string index as an unsigned LEB128. The actual value written\n     * is shifted by 1, so that the '0' value is reserved for \"null\". The\n     * null symbol is used in some cases by the parameter name list\n     * at the beginning of the sequence.\n     *\n     * @param string {@code null-ok;} string to emit\n     * @throws IOException\n     */\n    private void emitStringIndex(CstString string) throws IOException {\n        if ((string == null) || (file == null)) {\n            output.writeUleb128(0);\n        } else {\n            output.writeUleb128(\n                    1 + file.getStringIds().indexOf(string));\n        }\n\n        if (DEBUG) {\n            System.err.printf(\"Emit string %s\\n\",\n                    string == null ? \"<null>\" : string.toQuoted());\n        }\n    }\n\n    /**\n     * Emits a type index as an unsigned LEB128. The actual value written\n     * is shifted by 1, so that the '0' value is reserved for \"null\".\n     *\n     * @param type {@code null-ok;} type to emit\n     * @throws IOException\n     */\n    private void emitTypeIndex(CstType type) throws IOException {\n        if ((type == null) || (file == null)) {\n            output.writeUleb128(0);\n        } else {\n            output.writeUleb128(\n                    1 + file.getTypeIds().indexOf(type));\n        }\n\n        if (DEBUG) {\n            System.err.printf(\"Emit type %s\\n\",\n                    type == null ? \"<null>\" : type.toHuman());\n        }\n    }\n\n    /**\n     * Emits a {@link DebugInfoConstants#DBG_START_LOCAL DBG_START_LOCAL} or\n     * {@link DebugInfoConstants#DBG_START_LOCAL_EXTENDED\n     * DBG_START_LOCAL_EXTENDED} sequence.\n     *\n     * @param entry entry to emit\n     * @throws IOException\n     */\n    private void emitLocalStart(LocalList.Entry entry)\n        throws IOException {\n\n        if (entry.getSignature() != null) {\n            emitLocalStartExtended(entry);\n            return;\n        }\n\n        int mark = output.getCursor();\n\n        output.writeByte(DBG_START_LOCAL);\n\n        emitUnsignedLeb128(entry.getRegister());\n        emitStringIndex(entry.getName());\n        emitTypeIndex(entry.getType());\n\n        if (annotateTo != null || debugPrint != null) {\n            annotate(output.getCursor() - mark,\n                    String.format(\"%04x: +local %s\", address,\n                            entryAnnotationString(entry)));\n        }\n\n        if (DEBUG) {\n            System.err.println(\"emit local start\");\n        }\n    }\n\n    /**\n     * Emits a {@link DebugInfoConstants#DBG_START_LOCAL_EXTENDED\n     * DBG_START_LOCAL_EXTENDED} sequence.\n     *\n     * @param entry entry to emit\n     * @throws IOException\n     */\n    private void emitLocalStartExtended(LocalList.Entry entry)\n        throws IOException {\n\n        int mark = output.getCursor();\n\n        output.writeByte(DBG_START_LOCAL_EXTENDED);\n\n        emitUnsignedLeb128(entry.getRegister());\n        emitStringIndex(entry.getName());\n        emitTypeIndex(entry.getType());\n        emitStringIndex(entry.getSignature());\n\n        if (annotateTo != null || debugPrint != null) {\n            annotate(output.getCursor() - mark,\n                    String.format(\"%04x: +localx %s\", address,\n                            entryAnnotationString(entry)));\n        }\n\n        if (DEBUG) {\n            System.err.println(\"emit local start\");\n        }\n    }\n\n    /**\n     * Emits a {@link DebugInfoConstants#DBG_END_LOCAL DBG_END_LOCAL} sequence.\n     *\n     * @param entry {@code entry non-null;} entry associated with end.\n     * @throws IOException\n     */\n    private void emitLocalEnd(LocalList.Entry entry)\n            throws IOException {\n\n        int mark = output.getCursor();\n\n        output.writeByte(DBG_END_LOCAL);\n        output.writeUleb128(entry.getRegister());\n\n        if (annotateTo != null || debugPrint != null) {\n            annotate(output.getCursor() - mark,\n                    String.format(\"%04x: -local %s\", address,\n                            entryAnnotationString(entry)));\n        }\n\n        if (DEBUG) {\n            System.err.println(\"emit local end\");\n        }\n    }\n\n    /**\n     * Emits the necessary byte sequences to emit the given position table\n     * entry. This will typically be a single special opcode, although\n     * it may also require DBG_ADVANCE_PC or DBG_ADVANCE_LINE.\n     *\n     * @param entry position entry to emit.\n     * @throws IOException\n     */\n    private void emitPosition(PositionList.Entry entry)\n            throws IOException {\n\n        SourcePosition pos = entry.getPosition();\n        int newLine = pos.getLine();\n        int newAddress = entry.getAddress();\n\n        int opcode;\n\n        int deltaLines = newLine - line;\n        int deltaAddress = newAddress - address;\n\n        if (deltaAddress < 0) {\n            throw new RuntimeException(\n                    \"Position entries must be in ascending address order\");\n        }\n\n        if ((deltaLines < DBG_LINE_BASE)\n                || (deltaLines > (DBG_LINE_BASE + DBG_LINE_RANGE -1))) {\n            emitAdvanceLine(deltaLines);\n            deltaLines = 0;\n        }\n\n        opcode = computeOpcode (deltaLines, deltaAddress);\n\n        if ((opcode & ~0xff) > 0) {\n            emitAdvancePc(deltaAddress);\n            deltaAddress = 0;\n            opcode = computeOpcode (deltaLines, deltaAddress);\n\n            if ((opcode & ~0xff) > 0) {\n                emitAdvanceLine(deltaLines);\n                deltaLines = 0;\n                opcode = computeOpcode (deltaLines, deltaAddress);\n            }\n        }\n\n        output.writeByte(opcode);\n\n        line += deltaLines;\n        address += deltaAddress;\n\n        if (annotateTo != null || debugPrint != null) {\n            annotate(1,\n                    String.format(\"%04x: line %d\", address, line));\n        }\n    }\n\n    /**\n     * Computes a special opcode that will encode the given position change.\n     * If the return value is > 0xff, then the request cannot be fulfilled.\n     * Essentially the same as described in \"DWARF Debugging Format Version 3\"\n     * section 6.2.5.1.\n     *\n     * @param deltaLines {@code >= DBG_LINE_BASE, <= DBG_LINE_BASE +\n     * DBG_LINE_RANGE;} the line change to encode\n     * @param deltaAddress {@code >= 0;} the address change to encode\n     * @return {@code <= 0xff} if in range, otherwise parameters are out\n     * of range\n     */\n    private static int computeOpcode(int deltaLines, int deltaAddress) {\n        if (deltaLines < DBG_LINE_BASE\n                || deltaLines > (DBG_LINE_BASE + DBG_LINE_RANGE -1)) {\n\n            throw new RuntimeException(\"Parameter out of range\");\n        }\n\n        return (deltaLines - DBG_LINE_BASE)\n            + (DBG_LINE_RANGE * deltaAddress) + DBG_FIRST_SPECIAL;\n    }\n\n    /**\n     * Emits an {@link DebugInfoConstants#DBG_ADVANCE_LINE DBG_ADVANCE_LINE}\n     * sequence.\n     *\n     * @param deltaLines amount to change line number register by\n     * @throws IOException\n     */\n    private void emitAdvanceLine(int deltaLines) throws IOException {\n        int mark = output.getCursor();\n\n        output.writeByte(DBG_ADVANCE_LINE);\n        output.writeSleb128(deltaLines);\n        line += deltaLines;\n\n        if (annotateTo != null || debugPrint != null) {\n            annotate(output.getCursor() - mark,\n                    String.format(\"line = %d\", line));\n        }\n\n        if (DEBUG) {\n            System.err.printf(\"Emitting advance_line for %d\\n\", deltaLines);\n        }\n    }\n\n    /**\n     * Emits an  {@link DebugInfoConstants#DBG_ADVANCE_PC DBG_ADVANCE_PC}\n     * sequence.\n     *\n     * @param deltaAddress {@code >= 0;} amount to change program counter by\n     * @throws IOException\n     */\n    private void emitAdvancePc(int deltaAddress) throws IOException {\n        int mark = output.getCursor();\n\n        output.writeByte(DBG_ADVANCE_PC);\n        output.writeUleb128(deltaAddress);\n        address += deltaAddress;\n\n        if (annotateTo != null || debugPrint != null) {\n            annotate(output.getCursor() - mark,\n                    String.format(\"%04x: advance pc\", address));\n        }\n\n        if (DEBUG) {\n            System.err.printf(\"Emitting advance_pc for %d\\n\", deltaAddress);\n        }\n    }\n\n    /**\n     * Emits an unsigned LEB128 value.\n     *\n     * @param n {@code >= 0;} value to emit. Note that, although this can\n     * represent integers larger than Integer.MAX_VALUE, we currently don't\n     * allow that.\n     * @throws IOException\n     */\n    private void emitUnsignedLeb128(int n) throws IOException {\n        // We'll never need the top end of the unsigned range anyway.\n        if (n < 0) {\n            throw new RuntimeException(\n                    \"Signed value where unsigned required: \" + n);\n        }\n\n        output.writeUleb128(n);\n    }\n\n    /**\n     * Emits the {@link DebugInfoConstants#DBG_END_SEQUENCE DBG_END_SEQUENCE}\n     * bytecode.\n     */\n    private void emitEndSequence() {\n        output.writeByte(DBG_END_SEQUENCE);\n\n        if (annotateTo != null || debugPrint != null) {\n            annotate(1, \"end sequence\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/DebugInfoItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dx.dex.code.DalvCode;\nimport com.taobao.android.dx.dex.code.DalvInsnList;\nimport com.taobao.android.dx.dex.code.LocalList;\nimport com.taobao.android.dx.dex.code.PositionList;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.io.PrintWriter;\n\npublic class DebugInfoItem extends OffsettedItem {\n    /** the required alignment for instances of this class */\n    private static final int ALIGNMENT = 1;\n\n    private static final boolean ENABLE_ENCODER_SELF_CHECK = false;\n\n    /** {@code non-null;} the code this item represents */\n    private final DalvCode code;\n\n    private byte[] encoded;\n\n    private final boolean isStatic;\n    private final CstMethodRef ref;\n\n    public DebugInfoItem(DalvCode code, boolean isStatic, CstMethodRef ref) {\n        // We don't know the write size yet.\n        super (ALIGNMENT, -1);\n\n        if (code == null) {\n            throw new NullPointerException(\"code == null\");\n        }\n\n        this.code = code;\n        this.isStatic = isStatic;\n        this.ref = ref;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_DEBUG_INFO_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        // No contents to add.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void place0(Section addedTo, int offset) {\n        // Encode the data and note the size.\n\n        try {\n            encoded = encode(addedTo.getFile(), null, null, null, false);\n            setWriteSize(encoded.length);\n        } catch (RuntimeException ex) {\n            throw ExceptionWithContext.withContext(ex,\n                    \"...while placing debug info for \" + ref.toHuman());\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toHuman() {\n        throw new RuntimeException(\"unsupported\");\n    }\n\n    /**\n     * Writes annotations for the elements of this list, as\n     * zero-length. This is meant to be used for dumping this instance\n     * directly after a code dump (with the real local list actually\n     * existing elsewhere in the output).\n     *\n     * @param file {@code non-null;} the file to use for referencing other sections\n     * @param out {@code non-null;} where to annotate to\n     * @param prefix {@code null-ok;} prefix to attach to each line of output\n     */\n    public void annotateTo(DexFile file, AnnotatedOutput out, String prefix) {\n        encode(file, prefix, null, out, false);\n    }\n\n    /**\n     * Does a human-friendly dump of this instance.\n     *\n     * @param out {@code non-null;} where to dump\n     * @param prefix {@code non-null;} prefix to attach to each line of output\n     */\n    public void debugPrint(PrintWriter out, String prefix) {\n        encode(null, prefix, out, null, false);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void writeTo0(DexFile file, AnnotatedOutput out) {\n        if (out.annotates()) {\n            /*\n             * Re-run the encoder to generate the annotations,\n             * but write the bits from the original encode\n             */\n\n            out.annotate(offsetString() + \" debug info\");\n            encode(file, null, null, out, true);\n        }\n\n        out.write(encoded);\n    }\n\n    /**\n     * Performs debug info encoding.\n     *\n     * @param file {@code null-ok;} file to refer to during encoding\n     * @param prefix {@code null-ok;} prefix to attach to each line of output\n     * @param debugPrint {@code null-ok;} if specified, an alternate output for\n     * annotations\n     * @param out {@code null-ok;} if specified, where annotations should go\n     * @param consume whether to claim to have consumed output for\n     * {@code out}\n     * @return {@code non-null;} the encoded array\n     */\n    private byte[] encode(DexFile file, String prefix, PrintWriter debugPrint,\n            AnnotatedOutput out, boolean consume) {\n        byte[] result = encode0(file, prefix, debugPrint, out, consume);\n\n        if (ENABLE_ENCODER_SELF_CHECK && (file != null)) {\n            try {\n                DebugInfoDecoder.validateEncode(result, file, ref, code,\n                        isStatic);\n            } catch (RuntimeException ex) {\n                // Reconvert, annotating to System.err.\n                encode0(file, \"\", new PrintWriter(System.err, true), null,\n                        false);\n                throw ex;\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * Helper for {@link #encode} to do most of the work.\n     *\n     * @param file {@code null-ok;} file to refer to during encoding\n     * @param prefix {@code null-ok;} prefix to attach to each line of output\n     * @param debugPrint {@code null-ok;} if specified, an alternate output for\n     * annotations\n     * @param out {@code null-ok;} if specified, where annotations should go\n     * @param consume whether to claim to have consumed output for\n     * {@code out}\n     * @return {@code non-null;} the encoded array\n     */\n    private byte[] encode0(DexFile file, String prefix, PrintWriter debugPrint,\n            AnnotatedOutput out, boolean consume) {\n        PositionList positions = code.getPositions();\n        LocalList locals = code.getLocals();\n        DalvInsnList insns = code.getInsns();\n        int codeSize = insns.codeSize();\n        int regSize = insns.getRegistersSize();\n\n        DebugInfoEncoder encoder =\n            new DebugInfoEncoder(positions, locals,\n                    file, codeSize, regSize, isStatic, ref);\n\n        byte[] result;\n\n        if ((debugPrint == null) && (out == null)) {\n            result = encoder.convert();\n        } else {\n            result = encoder.convertAndAnnotate(prefix, debugPrint, out,\n                    consume);\n        }\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/DexFile.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dx.dex.DexOptions;\nimport com.taobao.android.dx.dex.file.MixedItemSection.SortType;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstBaseMethodRef;\nimport com.taobao.android.dx.rop.cst.CstEnumRef;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.ByteArrayAnnotatedOutput;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.io.Writer;\nimport java.security.DigestException;\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\nimport java.util.zip.Adler32;\n\n/**\n * Representation of an entire {@code .dex} (Dalvik EXecutable)\n * file, which itself consists of a set of Dalvik classes.\n */\npublic final class DexFile {\n    /** options controlling the creation of the file */\n    private DexOptions dexOptions;\n\n    /** {@code non-null;} word data section */\n    private final MixedItemSection wordData;\n\n    /**\n     * {@code non-null;} type lists section. This is word data, but separating\n     * it from {@link #wordData} helps break what would otherwise be a\n     * circular dependency between the that and {@link #protoIds}.\n     */\n    private final MixedItemSection typeLists;\n\n    /**\n     * {@code non-null;} map section. The map needs to be in a section by itself\n     * for the self-reference mechanics to work in a reasonably\n     * straightforward way. See {@link MapItem#addMap} for more detail.\n     */\n    private final MixedItemSection map;\n\n    /** {@code non-null;} string data section */\n    private final MixedItemSection stringData;\n\n    /** {@code non-null;} string identifiers section */\n    private final StringIdsSection stringIds;\n\n    /** {@code non-null;} type identifiers section */\n    private final TypeIdsSection typeIds;\n\n    /** {@code non-null;} prototype identifiers section */\n    private final ProtoIdsSection protoIds;\n\n    /** {@code non-null;} field identifiers section */\n    private final FieldIdsSection fieldIds;\n\n    /** {@code non-null;} method identifiers section */\n    private final MethodIdsSection methodIds;\n\n    /** {@code non-null;} class definitions section */\n    private final ClassDefsSection classDefs;\n\n    /** {@code non-null;} class data section */\n    private final MixedItemSection classData;\n\n    /** {@code non-null;} byte data section */\n    private final MixedItemSection byteData;\n\n    /** {@code non-null;} file header */\n    private final HeaderSection header;\n\n    /**\n     * {@code non-null;} array of sections in the order they will appear in the\n     * final output file\n     */\n    private final Section[] sections;\n\n    /** {@code >= -1;} total file size or {@code -1} if unknown */\n    private int fileSize;\n\n    /** {@code >= 40;} maximum width of the file dump */\n    private int dumpWidth;\n\n    /**\n     * Constructs an instance. It is initially empty.\n     */\n    public DexFile(DexOptions dexOptions) {\n        this.dexOptions = dexOptions;\n\n        header = new HeaderSection(this);\n        typeLists = new MixedItemSection(null, this, 4, SortType.NONE);\n        wordData = new MixedItemSection(\"word_data\", this, 4, SortType.TYPE);\n        stringData =\n            new MixedItemSection(\"string_data\", this, 1, SortType.INSTANCE);\n        classData = new MixedItemSection(null, this, 1, SortType.NONE);\n        byteData = new MixedItemSection(\"byte_data\", this, 1, SortType.TYPE);\n        stringIds = new StringIdsSection(this);\n        typeIds = new TypeIdsSection(this);\n        protoIds = new ProtoIdsSection(this);\n        fieldIds = new FieldIdsSection(this);\n        methodIds = new MethodIdsSection(this);\n        classDefs = new ClassDefsSection(this);\n        map = new MixedItemSection(\"map\", this, 4, SortType.NONE);\n\n        /*\n         * This is the list of sections in the order they appear in\n         * the final output.\n         */\n        sections = new Section[] {\n            header, stringIds, typeIds, protoIds, fieldIds, methodIds,\n            classDefs, wordData, typeLists, stringData, byteData,\n            classData, map };\n\n        fileSize = -1;\n        dumpWidth = 79;\n    }\n\n    /**\n     * Returns true if this dex doesn't contain any class defs.\n     */\n    public boolean isEmpty() {\n        return classDefs.items().isEmpty();\n    }\n\n    /**\n     * Gets the dex-creation options object.\n     */\n    public DexOptions getDexOptions() {\n        return dexOptions;\n    }\n\n    /**\n     * Adds a class to this instance. It is illegal to attempt to add more\n     * than one class with the same name.\n     *\n     * @param clazz {@code non-null;} the class to add\n     */\n    public void add(ClassDefItem clazz) {\n        classDefs.add(clazz);\n    }\n\n    /**\n     * Gets the class definition with the given name, if any.\n     *\n     * @param name {@code non-null;} the class name to look for\n     * @return {@code null-ok;} the class with the given name, or {@code null}\n     * if there is no such class\n     */\n    public ClassDefItem getClassOrNull(String name) {\n        try {\n            Type type = Type.internClassName(name);\n            return (ClassDefItem) classDefs.get(new CstType(type));\n        } catch (IllegalArgumentException ex) {\n            // Translate exception, per contract.\n            return null;\n        }\n    }\n\n    /**\n     * Writes the contents of this instance as either a binary or a\n     * human-readable form, or both.\n     *\n     * @param out {@code null-ok;} where to write to\n     * @param humanOut {@code null-ok;} where to write human-oriented output to\n     * @param verbose whether to be verbose when writing human-oriented output\n     */\n    public void writeTo(OutputStream out, Writer humanOut, boolean verbose)\n        throws IOException {\n        boolean annotate = (humanOut != null);\n        ByteArrayAnnotatedOutput result = toDex0(annotate, verbose);\n\n        if (out != null) {\n            out.write(result.getArray());\n        }\n\n        if (annotate) {\n            result.writeAnnotationsTo(humanOut);\n        }\n    }\n\n    /**\n     * Returns the contents of this instance as a {@code .dex} file,\n     * in {@code byte[]} form.\n     *\n     * @param humanOut {@code null-ok;} where to write human-oriented output to\n     * @param verbose whether to be verbose when writing human-oriented output\n     * @return {@code non-null;} a {@code .dex} file for this instance\n     */\n    public byte[] toDex(Writer humanOut, boolean verbose)\n        throws IOException {\n        boolean annotate = (humanOut != null);\n        ByteArrayAnnotatedOutput result = toDex0(annotate, verbose);\n\n        if (annotate) {\n            result.writeAnnotationsTo(humanOut);\n        }\n\n        return result.getArray();\n    }\n\n    /**\n     * Sets the maximum width of the human-oriented dump of the instance.\n     *\n     * @param dumpWidth {@code >= 40;} the width\n     */\n    public void setDumpWidth(int dumpWidth) {\n        if (dumpWidth < 40) {\n            throw new IllegalArgumentException(\"dumpWidth < 40\");\n        }\n\n        this.dumpWidth = dumpWidth;\n    }\n\n    /**\n     * Gets the total file size, if known.\n     *\n     * <p>This is package-scope in order to allow\n     * the {@link HeaderSection} to set itself up properly.</p>\n     *\n     * @return {@code >= 0;} the total file size\n     * @throws RuntimeException thrown if the file size is not yet known\n     */\n    public int getFileSize() {\n        if (fileSize < 0) {\n            throw new RuntimeException(\"file size not yet known\");\n        }\n\n        return fileSize;\n    }\n\n    /**\n     * Gets the string data section.\n     *\n     * <p>This is package-scope in order to allow\n     * the various {@link Item} instances to add items to the\n     * instance.</p>\n     *\n     * @return {@code non-null;} the string data section\n     */\n    /*package*/ MixedItemSection getStringData() {\n        return stringData;\n    }\n\n    /**\n     * Gets the word data section.\n     *\n     * <p>This is package-scope in order to allow\n     * the various {@link Item} instances to add items to the\n     * instance.</p>\n     *\n     * @return {@code non-null;} the word data section\n     */\n    /*package*/ MixedItemSection getWordData() {\n        return wordData;\n    }\n\n    /**\n     * Gets the type lists section.\n     *\n     * <p>This is package-scope in order to allow\n     * the various {@link Item} instances to add items to the\n     * instance.</p>\n     *\n     * @return {@code non-null;} the word data section\n     */\n    /*package*/ MixedItemSection getTypeLists() {\n        return typeLists;\n    }\n\n    /**\n     * Gets the map section.\n     *\n     * <p>This is package-scope in order to allow the header section\n     * to query it.</p>\n     *\n     * @return {@code non-null;} the map section\n     */\n    /*package*/ MixedItemSection getMap() {\n        return map;\n    }\n\n    /**\n     * Gets the string identifiers section.\n     *\n     * <p>This is package-scope in order to allow\n     * the various {@link Item} instances to add items to the\n     * instance.</p>\n     *\n     * @return {@code non-null;} the string identifiers section\n     */\n    /*package*/ StringIdsSection getStringIds() {\n        return stringIds;\n    }\n\n    /**\n     * Gets the class definitions section.\n     *\n     * <p>This is package-scope in order to allow\n     * the various {@link Item} instances to add items to the\n     * instance.</p>\n     *\n     * @return {@code non-null;} the class definitions section\n     */\n    public ClassDefsSection getClassDefs() {\n        return classDefs;\n    }\n\n    /**\n     * Gets the class data section.\n     *\n     * <p>This is package-scope in order to allow\n     * the various {@link Item} instances to add items to the\n     * instance.</p>\n     *\n     * @return {@code non-null;} the class data section\n     */\n    /*package*/ MixedItemSection getClassData() {\n        return classData;\n    }\n\n    /**\n     * Gets the type identifiers section.\n     *\n     * <p>This is public in order to allow\n     * the various {@link Item} instances to add items to the\n     * instance and help early counting of type ids.</p>\n     *\n     * @return {@code non-null;} the class identifiers section\n     */\n    public TypeIdsSection getTypeIds() {\n        return typeIds;\n    }\n\n    /**\n     * Gets the prototype identifiers section.\n     *\n     * <p>This is package-scope in order to allow\n     * the various {@link Item} instances to add items to the\n     * instance.</p>\n     *\n     * @return {@code non-null;} the prototype identifiers section\n     */\n    /*package*/ ProtoIdsSection getProtoIds() {\n        return protoIds;\n    }\n\n    /**\n     * Gets the field identifiers section.\n     *\n     * <p>This is public in order to allow\n     * the various {@link Item} instances to add items to the\n     * instance and help early counting of field ids.</p>\n     *\n     * @return {@code non-null;} the field identifiers section\n     */\n    public FieldIdsSection getFieldIds() {\n        return fieldIds;\n    }\n\n    /**\n     * Gets the method identifiers section.\n     *\n     * <p>This is public in order to allow\n     * the various {@link Item} instances to add items to the\n     * instance and help early counting of method ids.</p>\n     *\n     * @return {@code non-null;} the method identifiers section\n     */\n    public MethodIdsSection getMethodIds() {\n        return methodIds;\n    }\n\n    /**\n     * Gets the byte data section.\n     *\n     * <p>This is package-scope in order to allow\n     * the various {@link Item} instances to add items to the\n     * instance.</p>\n     *\n     * @return {@code non-null;} the byte data section\n     */\n    /*package*/ MixedItemSection getByteData() {\n        return byteData;\n    }\n\n    /**\n     * Gets the first section of the file that is to be considered\n     * part of the data section.\n     *\n     * <p>This is package-scope in order to allow the header section\n     * to query it.</p>\n     *\n     * @return {@code non-null;} the section\n     */\n    /*package*/ Section getFirstDataSection() {\n        return wordData;\n    }\n\n    /**\n     * Gets the last section of the file that is to be considered\n     * part of the data section.\n     *\n     * <p>This is package-scope in order to allow the header section\n     * to query it.</p>\n     *\n     * @return {@code non-null;} the section\n     */\n    /*package*/ Section getLastDataSection() {\n        return map;\n    }\n\n    /**\n     * Interns the given constant in the appropriate section of this\n     * instance, or do nothing if the given constant isn't the sort\n     * that should be interned.\n     *\n     * @param cst {@code non-null;} constant to possibly intern\n     */\n    /*package*/ void internIfAppropriate(Constant cst) {\n        if (cst instanceof CstString) {\n            stringIds.intern((CstString) cst);\n        } else if (cst instanceof CstType) {\n            typeIds.intern((CstType) cst);\n        } else if (cst instanceof CstBaseMethodRef) {\n            methodIds.intern((CstBaseMethodRef) cst);\n        } else if (cst instanceof CstFieldRef) {\n            fieldIds.intern((CstFieldRef) cst);\n        } else if (cst instanceof CstEnumRef) {\n            fieldIds.intern(((CstEnumRef) cst).getFieldRef());\n        } else if (cst == null) {\n            throw new NullPointerException(\"cst == null\");\n        }\n    }\n\n    /**\n     * Gets the {@link IndexedItem} corresponding to the given constant,\n     * if it is a constant that has such a correspondence, or return\n     * {@code null} if it isn't such a constant. This will throw\n     * an exception if the given constant <i>should</i> have been found\n     * but wasn't.\n     *\n     * @param cst {@code non-null;} the constant to look up\n     * @return {@code null-ok;} its corresponding item, if it has a corresponding\n     * item, or {@code null} if it's not that sort of constant\n     */\n    /*package*/ IndexedItem findItemOrNull(Constant cst) {\n        IndexedItem item;\n\n        if (cst instanceof CstString) {\n            return stringIds.get(cst);\n        } else if (cst instanceof CstType) {\n            return typeIds.get(cst);\n        } else if (cst instanceof CstBaseMethodRef) {\n            return methodIds.get(cst);\n        } else if (cst instanceof CstFieldRef) {\n            return fieldIds.get(cst);\n        } else {\n            return null;\n        }\n    }\n\n    /**\n     * Returns the contents of this instance as a {@code .dex} file,\n     * in a {@link ByteArrayAnnotatedOutput} instance.\n     *\n     * @param annotate whether or not to keep annotations\n     * @param verbose if annotating, whether to be verbose\n     * @return {@code non-null;} a {@code .dex} file for this instance\n     */\n    private ByteArrayAnnotatedOutput toDex0(boolean annotate,\n            boolean verbose) {\n        /*\n         * The following is ordered so that the prepare() calls which\n         * add items happen before the calls to the sections that get\n         * added to.\n         */\n\n        classDefs.prepare();\n        classData.prepare();\n        wordData.prepare();\n        byteData.prepare();\n        methodIds.prepare();\n        fieldIds.prepare();\n        protoIds.prepare();\n        typeLists.prepare();\n        typeIds.prepare();\n        stringIds.prepare();\n        stringData.prepare();\n        header.prepare();\n\n        // Place the sections within the file.\n\n        int count = sections.length;\n        int offset = 0;\n\n        for (int i = 0; i < count; i++) {\n            Section one = sections[i];\n            int placedAt = one.setFileOffset(offset);\n            if (placedAt < offset) {\n                throw new RuntimeException(\"bogus placement for section \" + i);\n            }\n\n            try {\n                if (one == map) {\n                    /*\n                     * Inform the map of all the sections, and add it\n                     * to the file. This can only be done after all\n                     * the other items have been sorted and placed.\n                     */\n                    MapItem.addMap(sections, map);\n                    map.prepare();\n                }\n\n                if (one instanceof MixedItemSection) {\n                    /*\n                     * Place the items of a MixedItemSection that just\n                     * got placed.\n                     */\n                    ((MixedItemSection) one).placeItems();\n                }\n\n                offset = placedAt + one.writeSize();\n            } catch (RuntimeException ex) {\n                throw ExceptionWithContext.withContext(ex,\n                        \"...while writing section \" + i);\n            }\n        }\n\n        // Write out all the sections.\n\n        fileSize = offset;\n        byte[] barr = new byte[fileSize];\n        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput(barr);\n\n        if (annotate) {\n            out.enableAnnotations(dumpWidth, verbose);\n        }\n\n        for (int i = 0; i < count; i++) {\n            try {\n                Section one = sections[i];\n                int zeroCount = one.getFileOffset() - out.getCursor();\n                if (zeroCount < 0) {\n                    throw new ExceptionWithContext(\"excess write of \" +\n                            (-zeroCount));\n                }\n                out.writeZeroes(one.getFileOffset() - out.getCursor());\n                one.writeTo(out);\n            } catch (RuntimeException ex) {\n                ExceptionWithContext ec;\n                if (ex instanceof ExceptionWithContext) {\n                    ec = (ExceptionWithContext) ex;\n                } else {\n                    ec = new ExceptionWithContext(ex);\n                }\n                ec.addContext(\"...while writing section \" + i);\n                throw ec;\n            }\n        }\n\n        if (out.getCursor() != fileSize) {\n            throw new RuntimeException(\"foreshortened write\");\n        }\n\n        // Perform final bookkeeping.\n\n        calcSignature(barr);\n        calcChecksum(barr);\n\n        if (annotate) {\n            wordData.writeIndexAnnotation(out, ItemType.TYPE_CODE_ITEM,\n                    \"\\nmethod code index:\\n\\n\");\n            getStatistics().writeAnnotation(out);\n            out.finishAnnotating();\n        }\n\n        return out;\n    }\n\n    /**\n     * Generates and returns statistics for all the items in the file.\n     *\n     * @return {@code non-null;} the statistics\n     */\n    public Statistics getStatistics() {\n        Statistics stats = new Statistics();\n\n        for (Section s : sections) {\n            stats.addAll(s);\n        }\n\n        return stats;\n    }\n\n    /**\n     * Calculates the signature for the {@code .dex} file in the\n     * given array, and modify the array to contain it.\n     *\n     * @param bytes {@code non-null;} the bytes of the file\n     */\n    private static void calcSignature(byte[] bytes) {\n        MessageDigest md;\n\n        try {\n            md = MessageDigest.getInstance(\"SHA-1\");\n        } catch (NoSuchAlgorithmException ex) {\n            throw new RuntimeException(ex);\n        }\n\n        md.update(bytes, 32, bytes.length - 32);\n\n        try {\n            int amt = md.digest(bytes, 12, 20);\n            if (amt != 20) {\n                throw new RuntimeException(\"unexpected digest write: \" + amt +\n                                           \" bytes\");\n            }\n        } catch (DigestException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n\n    /**\n     * Calculates the checksum for the {@code .dex} file in the\n     * given array, and modify the array to contain it.\n     *\n     * @param bytes {@code non-null;} the bytes of the file\n     */\n    private static void calcChecksum(byte[] bytes) {\n        Adler32 a32 = new Adler32();\n\n        a32.update(bytes, 12, bytes.length - 12);\n\n        int sum = (int) a32.getValue();\n\n        bytes[8]  = (byte) sum;\n        bytes[9]  = (byte) (sum >> 8);\n        bytes[10] = (byte) (sum >> 16);\n        bytes[11] = (byte) (sum >> 24);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/EncodedArrayItem.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.cst.CstArray;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.ByteArrayAnnotatedOutput;\n\n/**\n * Encoded array of constant values.\n */\npublic final class EncodedArrayItem extends OffsettedItem {\n    /** the required alignment for instances of this class */\n    private static final int ALIGNMENT = 1;\n\n    /** {@code non-null;} the array to represent */\n    private final CstArray array;\n\n    /**\n     * {@code null-ok;} encoded form, ready for writing to a file; set during\n     * {@link #place0}\n     */\n    private byte[] encodedForm;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param array {@code non-null;} array to represent\n     */\n    public EncodedArrayItem(CstArray array) {\n        /*\n         * The write size isn't known up-front because (the variable-lengthed)\n         * leb128 type is used to represent some things.\n         */\n        super(ALIGNMENT, -1);\n\n        if (array == null) {\n            throw new NullPointerException(\"array == null\");\n        }\n\n        this.array = array;\n        this.encodedForm = null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_ENCODED_ARRAY_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return array.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int compareTo0(OffsettedItem other) {\n        EncodedArrayItem otherArray = (EncodedArrayItem) other;\n\n        return array.compareTo(otherArray.array);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toHuman() {\n        return array.toHuman();\n    }\n\n    /** {@inheritDoc} */\n    public void addContents(DexFile file) {\n        ValueEncoder.addContents(file, array);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void place0(Section addedTo, int offset) {\n        // Encode the data and note the size.\n\n        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();\n        ValueEncoder encoder = new ValueEncoder(addedTo.getFile(), out);\n\n        encoder.writeArray(array, false);\n        encodedForm = out.toByteArray();\n        setWriteSize(encodedForm.length);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void writeTo0(DexFile file, AnnotatedOutput out) {\n        boolean annotates = out.annotates();\n\n        if (annotates) {\n            out.annotate(0, offsetString() + \" encoded array\");\n\n            /*\n             * The output is to be annotated, so redo the work previously\n             * done by place0(), except this time annotations will actually\n             * get emitted.\n             */\n            ValueEncoder encoder = new ValueEncoder(file, out);\n            encoder.writeArray(array, true);\n        } else {\n            out.write(encodedForm);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/EncodedField.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.Leb128;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport java.io.PrintWriter;\n\n/**\n * Representation of a field of a class, of any sort.\n */\npublic final class EncodedField extends EncodedMember\n        implements Comparable<EncodedField> {\n    /** {@code non-null;} constant for the field */\n    private final CstFieldRef field;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param field {@code non-null;} constant for the field\n     * @param accessFlags access flags\n     */\n    public EncodedField(CstFieldRef field, int accessFlags) {\n        super(accessFlags);\n\n        if (field == null) {\n            throw new NullPointerException(\"field == null\");\n        }\n\n        /*\n         * TODO: Maybe check accessFlags, at least for\n         * easily-checked stuff?\n         */\n\n        this.field = field;\n    }\n\n    /** {@inheritDoc} */\n    public int hashCode() {\n        return field.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    public boolean equals(Object other) {\n        if (! (other instanceof EncodedField)) {\n            return false;\n        }\n\n        return compareTo((EncodedField) other) == 0;\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p><b>Note:</b> This compares the method constants only,\n     * ignoring any associated code, because it should never be the\n     * case that two different items with the same method constant\n     * ever appear in the same list (or same file, even).</p>\n     */\n    public int compareTo(EncodedField other) {\n        return field.compareTo(other.field);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        StringBuffer sb = new StringBuffer(100);\n\n        sb.append(getClass().getName());\n        sb.append('{');\n        sb.append(Hex.u2(getAccessFlags()));\n        sb.append(' ');\n        sb.append(field);\n        sb.append('}');\n        return sb.toString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        FieldIdsSection fieldIds = file.getFieldIds();\n        fieldIds.intern(field);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public CstString getName() {\n        return field.getNat().getName();\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return field.toHuman();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void debugPrint(PrintWriter out, boolean verbose) {\n        // TODO: Maybe put something better here?\n        out.println(toString());\n    }\n\n    /**\n     * Gets the constant for the field.\n     *\n     * @return {@code non-null;} the constant\n     */\n    public CstFieldRef getRef() {\n        return field;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int encode(DexFile file, AnnotatedOutput out,\n            int lastIndex, int dumpSeq) {\n        int fieldIdx = file.getFieldIds().indexOf(field);\n        int diff = fieldIdx - lastIndex;\n        int accessFlags = getAccessFlags();\n\n        if (out.annotates()) {\n            out.annotate(0, String.format(\"  [%x] %s\", dumpSeq,\n                            field.toHuman()));\n            out.annotate(Leb128.unsignedLeb128Size(diff),\n                    \"    field_idx:    \" + Hex.u4(fieldIdx));\n            out.annotate(Leb128.unsignedLeb128Size(accessFlags),\n                    \"    access_flags: \" +\n                    AccessFlags.fieldString(accessFlags));\n        }\n\n        out.writeUleb128(diff);\n        out.writeUleb128(accessFlags);\n\n        return fieldIdx;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/EncodedMember.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.ToHuman;\nimport java.io.PrintWriter;\n\n/**\n * Representation of a member (field or method) of a class, for the\n * purposes of encoding it inside a {@link ClassDataItem}.\n */\npublic abstract class EncodedMember implements ToHuman {\n    /** access flags */\n    private final int accessFlags;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param accessFlags access flags for the member\n     */\n    public EncodedMember(int accessFlags) {\n        this.accessFlags = accessFlags;\n    }\n\n    /**\n     * Gets the access flags.\n     *\n     * @return the access flags\n     */\n    public final int getAccessFlags() {\n        return accessFlags;\n    }\n\n    /**\n     * Gets the name.\n     *\n     * @return {@code non-null;} the name\n     */\n    public abstract CstString getName();\n\n    /**\n     * Does a human-friendly dump of this instance.\n     *\n     * @param out {@code non-null;} where to dump\n     * @param verbose whether to be verbose with the output\n     */\n    public abstract void debugPrint(PrintWriter out, boolean verbose);\n\n    /**\n     * Populates a {@link DexFile} with items from within this instance.\n     *\n     * @param file {@code non-null;} the file to populate\n     */\n    public abstract void addContents(DexFile file);\n\n    /**\n     * Encodes this instance to the given output.\n     *\n     * @param file {@code non-null;} file this instance is part of\n     * @param out {@code non-null;} where to write to\n     * @param lastIndex {@code >= 0;} the previous member index value encoded, or\n     * {@code 0} if this is the first element to encode\n     * @param dumpSeq {@code >= 0;} sequence number of this instance for\n     * annotation purposes\n     * @return {@code >= 0;} the member index value that was encoded\n     */\n    public abstract int encode(DexFile file, AnnotatedOutput out,\n            int lastIndex, int dumpSeq);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/EncodedMethod.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.Leb128;\nimport com.taobao.android.dx.dex.code.DalvCode;\nimport com.taobao.android.dx.rop.code.AccessFlags;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport java.io.PrintWriter;\n\n/**\n * Class that representats a method of a class.\n */\npublic final class EncodedMethod extends EncodedMember\n        implements Comparable<EncodedMethod> {\n    /** {@code non-null;} constant for the method */\n    private final CstMethodRef method;\n\n    /**\n     * {@code null-ok;} code for the method, if the method is neither\n     * {@code abstract} nor {@code native}\n     */\n    private final CodeItem code;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param method {@code non-null;} constant for the method\n     * @param accessFlags access flags\n     * @param code {@code null-ok;} code for the method, if it is neither\n     * {@code abstract} nor {@code native}\n     * @param throwsList {@code non-null;} list of possibly-thrown exceptions,\n     * just used in generating debugging output (listings)\n     */\n    public EncodedMethod(CstMethodRef method, int accessFlags,\n            DalvCode code, TypeList throwsList) {\n        super(accessFlags);\n\n        if (method == null) {\n            throw new NullPointerException(\"method == null\");\n        }\n\n        this.method = method;\n\n        if (code == null) {\n            this.code = null;\n        } else {\n            boolean isStatic = (accessFlags & AccessFlags.ACC_STATIC) != 0;\n            this.code = new CodeItem(method, code, isStatic, throwsList);\n        }\n    }\n\n    /** {@inheritDoc} */\n    public boolean equals(Object other) {\n        if (! (other instanceof EncodedMethod)) {\n            return false;\n        }\n\n        return compareTo((EncodedMethod) other) == 0;\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p><b>Note:</b> This compares the method constants only,\n     * ignoring any associated code, because it should never be the\n     * case that two different items with the same method constant\n     * ever appear in the same list (or same file, even).</p>\n     */\n    public int compareTo(EncodedMethod other) {\n        return method.compareTo(other.method);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        StringBuffer sb = new StringBuffer(100);\n\n        sb.append(getClass().getName());\n        sb.append('{');\n        sb.append(Hex.u2(getAccessFlags()));\n        sb.append(' ');\n        sb.append(method);\n\n        if (code != null) {\n            sb.append(' ');\n            sb.append(code);\n        }\n\n        sb.append('}');\n\n        return sb.toString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        MethodIdsSection methodIds = file.getMethodIds();\n        MixedItemSection wordData = file.getWordData();\n\n        methodIds.intern(method);\n\n        if (code != null) {\n            wordData.add(code);\n        }\n    }\n\n    /** {@inheritDoc} */\n    public final String toHuman() {\n        return method.toHuman();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final CstString getName() {\n        return method.getNat().getName();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void debugPrint(PrintWriter out, boolean verbose) {\n        if (code == null) {\n            out.println(getRef().toHuman() + \": abstract or native\");\n        } else {\n            code.debugPrint(out, \"  \", verbose);\n        }\n    }\n\n    /**\n     * Gets the constant for the method.\n     *\n     * @return {@code non-null;} the constant\n     */\n    public final CstMethodRef getRef() {\n        return method;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int encode(DexFile file, AnnotatedOutput out,\n            int lastIndex, int dumpSeq) {\n        int methodIdx = file.getMethodIds().indexOf(method);\n        int diff = methodIdx - lastIndex;\n        int accessFlags = getAccessFlags();\n        int codeOff = OffsettedItem.getAbsoluteOffsetOr0(code);\n        boolean hasCode = (codeOff != 0);\n        boolean shouldHaveCode = (accessFlags &\n                (AccessFlags.ACC_ABSTRACT | AccessFlags.ACC_NATIVE)) == 0;\n\n        /*\n         * Verify that code appears if and only if a method is\n         * declared to have it.\n         */\n        if (hasCode != shouldHaveCode) {\n            throw new UnsupportedOperationException(\n                    \"code vs. access_flags mismatch\");\n        }\n\n        if (out.annotates()) {\n            out.annotate(0, String.format(\"  [%x] %s\", dumpSeq,\n                            method.toHuman()));\n            out.annotate(Leb128.unsignedLeb128Size(diff),\n                    \"    method_idx:   \" + Hex.u4(methodIdx));\n            out.annotate(Leb128.unsignedLeb128Size(accessFlags),\n                    \"    access_flags: \" +\n                    AccessFlags.methodString(accessFlags));\n            out.annotate(Leb128.unsignedLeb128Size(codeOff),\n                    \"    code_off:     \" + Hex.u4(codeOff));\n        }\n\n        out.writeUleb128(diff);\n        out.writeUleb128(accessFlags);\n        out.writeUleb128(codeOff);\n\n        return methodIdx;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/FieldAnnotationStruct.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.annotation.Annotations;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.ToHuman;\n\n/**\n * Association of a field and its annotations.\n */\npublic final class FieldAnnotationStruct\n        implements ToHuman, Comparable<FieldAnnotationStruct> {\n    /** {@code non-null;} the field in question */\n    private final CstFieldRef field;\n\n    /** {@code non-null;} the associated annotations */\n    private AnnotationSetItem annotations;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param field {@code non-null;} the field in question\n     * @param annotations {@code non-null;} the associated annotations\n     */\n    public FieldAnnotationStruct(CstFieldRef field,\n            AnnotationSetItem annotations) {\n        if (field == null) {\n            throw new NullPointerException(\"field == null\");\n        }\n\n        if (annotations == null) {\n            throw new NullPointerException(\"annotations == null\");\n        }\n\n        this.field = field;\n        this.annotations = annotations;\n    }\n\n    /** {@inheritDoc} */\n    public int hashCode() {\n        return field.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    public boolean equals(Object other) {\n        if (! (other instanceof FieldAnnotationStruct)) {\n            return false;\n        }\n\n        return field.equals(((FieldAnnotationStruct) other).field);\n    }\n\n    /** {@inheritDoc} */\n    public int compareTo(FieldAnnotationStruct other) {\n        return field.compareTo(other.field);\n    }\n\n    /** {@inheritDoc} */\n    public void addContents(DexFile file) {\n        FieldIdsSection fieldIds = file.getFieldIds();\n        MixedItemSection wordData = file.getWordData();\n\n        fieldIds.intern(field);\n        annotations = wordData.intern(annotations);\n    }\n\n    /** {@inheritDoc} */\n    public void writeTo(DexFile file, AnnotatedOutput out) {\n        int fieldIdx = file.getFieldIds().indexOf(field);\n        int annotationsOff = annotations.getAbsoluteOffset();\n\n        if (out.annotates()) {\n            out.annotate(0, \"    \" + field.toHuman());\n            out.annotate(4, \"      field_idx:       \" + Hex.u4(fieldIdx));\n            out.annotate(4, \"      annotations_off: \" +\n                    Hex.u4(annotationsOff));\n        }\n\n        out.writeInt(fieldIdx);\n        out.writeInt(annotationsOff);\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return field.toHuman() + \": \" + annotations;\n    }\n\n    /**\n     * Gets the field this item is for.\n     *\n     * @return {@code non-null;} the field\n     */\n    public CstFieldRef getField() {\n        return field;\n    }\n\n    /**\n     * Gets the associated annotations.\n     *\n     * @return {@code non-null;} the annotations\n     */\n    public Annotations getAnnotations() {\n        return annotations.getAnnotations();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/FieldIdItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\n\n/**\n * Representation of a field reference inside a Dalvik file.\n */\npublic final class FieldIdItem extends MemberIdItem {\n    /**\n     * Constructs an instance.\n     *\n     * @param field {@code non-null;} the constant for the field\n     */\n    public FieldIdItem(CstFieldRef field) {\n        super(field);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_FIELD_ID_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        super.addContents(file);\n\n        TypeIdsSection typeIds = file.getTypeIds();\n        typeIds.intern(getFieldRef().getType());\n    }\n\n    /**\n     * Gets the field constant.\n     *\n     * @return {@code non-null;} the constant\n     */\n    public CstFieldRef getFieldRef() {\n        return (CstFieldRef) getRef();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int getTypoidIdx(DexFile file) {\n        TypeIdsSection typeIds = file.getTypeIds();\n        return typeIds.indexOf(getFieldRef().getType());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String getTypoidName() {\n        return \"type_idx\";\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/FieldIdsSection.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\n\nimport java.util.Collection;\nimport java.util.TreeMap;\n\n/**\n * Field refs list section of a {@code .dex} file.\n */\npublic final class FieldIdsSection extends MemberIdsSection {\n    /**\n     * {@code non-null;} map from field constants to {@link\n     * FieldIdItem} instances\n     */\n    private final TreeMap<CstFieldRef, FieldIdItem> fieldIds;\n\n    /**\n     * Constructs an instance. The file offset is initially unknown.\n     *\n     * @param file {@code non-null;} file that this instance is part of\n     */\n    public FieldIdsSection(DexFile file) {\n        super(\"field_ids\", file);\n\n        fieldIds = new TreeMap<CstFieldRef, FieldIdItem>();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Collection<? extends Item> items() {\n        return fieldIds.values();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public IndexedItem get(Constant cst) {\n        if (cst == null) {\n            throw new NullPointerException(\"cst == null\");\n        }\n\n        throwIfNotPrepared();\n\n        IndexedItem result = fieldIds.get((CstFieldRef) cst);\n\n        if (result == null) {\n            throw new IllegalArgumentException(\"not found\");\n        }\n\n        return result;\n    }\n\n    /**\n     * Writes the portion of the file header that refers to this instance.\n     *\n     * @param out {@code non-null;} where to write\n     */\n    public void writeHeaderPart(AnnotatedOutput out) {\n        throwIfNotPrepared();\n\n        int sz = fieldIds.size();\n        int offset = (sz == 0) ? 0 : getFileOffset();\n\n        if (out.annotates()) {\n            out.annotate(4, \"field_ids_size:  \" + Hex.u4(sz));\n            out.annotate(4, \"field_ids_off:   \" + Hex.u4(offset));\n        }\n\n        out.writeInt(sz);\n        out.writeInt(offset);\n    }\n\n    /**\n     * Interns an element into this instance.\n     *\n     * @param field {@code non-null;} the reference to intern\n     * @return {@code non-null;} the interned reference\n     */\n    public synchronized FieldIdItem intern(CstFieldRef field) {\n        if (field == null) {\n            throw new NullPointerException(\"field == null\");\n        }\n\n        throwIfPrepared();\n\n        FieldIdItem result = fieldIds.get(field);\n\n        if (result == null) {\n            result = new FieldIdItem(field);\n            fieldIds.put(field, result);\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets the index of the given reference, which must have been added\n     * to this instance.\n     *\n     * @param ref {@code non-null;} the reference to look up\n     * @return {@code >= 0;} the reference's index\n     */\n    public int indexOf(CstFieldRef ref) {\n        if (ref == null) {\n            throw new NullPointerException(\"ref == null\");\n        }\n\n        throwIfNotPrepared();\n\n        FieldIdItem item = fieldIds.get(ref);\n\n        if (item == null) {\n            throw new IllegalArgumentException(\"not found\");\n        }\n\n        return item.getIndex();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/HeaderItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.DexFormat;\nimport com.taobao.android.dex.SizeOf;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * File header section of a {@code .dex} file.\n */\npublic final class HeaderItem extends IndexedItem {\n    /**\n     * Constructs an instance.\n     */\n    public HeaderItem() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_HEADER_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int writeSize() {\n        return SizeOf.HEADER_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        // Nothing to do here.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(DexFile file, AnnotatedOutput out) {\n        int mapOff = file.getMap().getFileOffset();\n        Section firstDataSection = file.getFirstDataSection();\n        Section lastDataSection = file.getLastDataSection();\n        int dataOff = firstDataSection.getFileOffset();\n        int dataSize = lastDataSection.getFileOffset() +\n            lastDataSection.writeSize() - dataOff;\n\n        String magic = file.getDexOptions().getMagic();\n\n        if (out.annotates()) {\n            out.annotate(8, \"magic: \" + new CstString(magic).toQuoted());\n            out.annotate(4, \"checksum\");\n            out.annotate(20, \"signature\");\n            out.annotate(4, \"file_size:       \" +\n                         Hex.u4(file.getFileSize()));\n            out.annotate(4, \"header_size:     \" + Hex.u4(SizeOf.HEADER_ITEM));\n            out.annotate(4, \"endian_tag:      \" + Hex.u4(DexFormat.ENDIAN_TAG));\n            out.annotate(4, \"link_size:       0\");\n            out.annotate(4, \"link_off:        0\");\n            out.annotate(4, \"map_off:         \" + Hex.u4(mapOff));\n        }\n\n        // Write the magic number.\n        for (int i = 0; i < 8; i++) {\n            out.writeByte(magic.charAt(i));\n        }\n\n        // Leave space for the checksum and signature.\n        out.writeZeroes(24);\n\n        out.writeInt(file.getFileSize());\n        out.writeInt(SizeOf.HEADER_ITEM);\n        out.writeInt(DexFormat.ENDIAN_TAG);\n\n        /*\n         * Write zeroes for the link size and data, as the output\n         * isn't a staticly linked file.\n         */\n        out.writeZeroes(8);\n\n        out.writeInt(mapOff);\n\n        // Write out each section's respective header part.\n        file.getStringIds().writeHeaderPart(out);\n        file.getTypeIds().writeHeaderPart(out);\n        file.getProtoIds().writeHeaderPart(out);\n        file.getFieldIds().writeHeaderPart(out);\n        file.getMethodIds().writeHeaderPart(out);\n        file.getClassDefs().writeHeaderPart(out);\n\n        if (out.annotates()) {\n            out.annotate(4, \"data_size:       \" + Hex.u4(dataSize));\n            out.annotate(4, \"data_off:        \" + Hex.u4(dataOff));\n        }\n\n        out.writeInt(dataSize);\n        out.writeInt(dataOff);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/HeaderSection.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * File header section of a {@code .dex} file.\n */\npublic final class HeaderSection extends UniformItemSection {\n    /** {@code non-null;} the list of the one item in the section */\n    private final List<HeaderItem> list;\n\n    /**\n     * Constructs an instance. The file offset is initially unknown.\n     *\n     * @param file {@code non-null;} file that this instance is part of\n     */\n    public HeaderSection(DexFile file) {\n        super(null, file, 4);\n\n        HeaderItem item = new HeaderItem();\n        item.setIndex(0);\n\n        this.list = Collections.singletonList(item);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public IndexedItem get(Constant cst) {\n        return null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Collection<? extends Item> items() {\n        return list;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void orderItems() {\n        // Nothing to do here.\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/IdItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.cst.CstType;\n\n/**\n * Representation of a reference to an item inside a Dalvik file.\n */\npublic abstract class IdItem extends IndexedItem {\n    /**\n     * {@code non-null;} the type constant for the defining class of\n     * the reference\n     */\n    private final CstType type;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param type {@code non-null;} the type constant for the defining\n     * class of the reference\n     */\n    public IdItem(CstType type) {\n        if (type == null) {\n            throw new NullPointerException(\"type == null\");\n        }\n\n        this.type = type;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        TypeIdsSection typeIds = file.getTypeIds();\n        typeIds.intern(type);\n    }\n\n    /**\n     * Gets the type constant for the defining class of the\n     * reference.\n     *\n     * @return {@code non-null;} the type constant\n     */\n    public final CstType getDefiningClass() {\n        return type;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/IndexedItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\n/**\n * An item in a Dalvik file which is referenced by index.\n */\npublic abstract class IndexedItem extends Item {\n    /** {@code >= -1;} assigned index of the item, or {@code -1} if not\n     * yet assigned */\n    private int index;\n\n    /**\n     * Constructs an instance. The index is initially unassigned.\n     */\n    public IndexedItem() {\n        index = -1;\n    }\n\n    /**\n     * Gets whether or not this instance has been assigned an index.\n     *\n     * @return {@code true} iff this instance has been assigned an index\n     */\n    public final boolean hasIndex() {\n        return (index >= 0);\n    }\n\n    /**\n     * Gets the item index.\n     *\n     * @return {@code >= 0;} the index\n     * @throws RuntimeException thrown if the item index is not yet assigned\n     */\n    public final int getIndex() {\n        if (index < 0) {\n            throw new RuntimeException(\"index not yet set\");\n        }\n\n        return index;\n    }\n\n    /**\n     * Sets the item index. This method may only ever be called once\n     * per instance, and this will throw a {@code RuntimeException} if\n     * called a second (or subsequent) time.\n     *\n     * @param index {@code >= 0;} the item index\n     */\n    public final void setIndex(int index) {\n        if (this.index != -1) {\n            throw new RuntimeException(\"index already set\");\n        }\n\n        this.index = index;\n    }\n\n    /**\n     * Gets the index of this item as a string, suitable for including in\n     * annotations.\n     *\n     * @return {@code non-null;} the index string\n     */\n    public final String indexString() {\n        return '[' + Integer.toHexString(index) + ']';\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/Item.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.util.AnnotatedOutput;\n\n/**\n * Base class for any structurally-significant and (potentially)\n * repeated piece of a Dalvik file.\n */\npublic abstract class Item {\n    /**\n     * Constructs an instance.\n     */\n    public Item() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Returns the item type for this instance.\n     *\n     * @return {@code non-null;} the item type\n     */\n    public abstract ItemType itemType();\n\n    /**\n     * Returns the human name for the particular type of item this\n     * instance is.\n     *\n     * @return {@code non-null;} the name\n     */\n    public final String typeName() {\n        return itemType().toHuman();\n    }\n\n    /**\n     * Gets the size of this instance when written, in bytes.\n     *\n     * @return {@code >= 0;} the write size\n     */\n    public abstract int writeSize();\n\n    /**\n     * Populates a {@link DexFile} with items from within this instance.\n     * This will <i>not</i> add an item to the file for this instance itself\n     * (which should have been done by whatever refers to this instance).\n     *\n     * <p><b>Note:</b> Subclasses must override this to do something\n     * appropriate.</p>\n     *\n     * @param file {@code non-null;} the file to populate\n     */\n    public abstract void addContents(DexFile file);\n\n    /**\n     * Writes the representation of this instance to the given data section,\n     * using the given {@link DexFile} to look things up as needed.\n     * If this instance keeps track of its offset, then this method will\n     * note the written offset and will also throw an exception if this\n     * instance has already been written.\n     *\n     * @param file {@code non-null;} the file to use for reference\n     * @param out {@code non-null;} where to write to\n     */\n    public abstract void writeTo(DexFile file, AnnotatedOutput out);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/ItemType.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.util.ToHuman;\n\n/**\n * Enumeration of all the top-level item types.\n */\npublic enum ItemType implements ToHuman {\n    TYPE_HEADER_ITEM(               0x0000, \"header_item\"),\n    TYPE_STRING_ID_ITEM(            0x0001, \"string_id_item\"),\n    TYPE_TYPE_ID_ITEM(              0x0002, \"type_id_item\"),\n    TYPE_PROTO_ID_ITEM(             0x0003, \"proto_id_item\"),\n    TYPE_FIELD_ID_ITEM(             0x0004, \"field_id_item\"),\n    TYPE_METHOD_ID_ITEM(            0x0005, \"method_id_item\"),\n    TYPE_CLASS_DEF_ITEM(            0x0006, \"class_def_item\"),\n    TYPE_MAP_LIST(                  0x1000, \"map_list\"),\n    TYPE_TYPE_LIST(                 0x1001, \"type_list\"),\n    TYPE_ANNOTATION_SET_REF_LIST(   0x1002, \"annotation_set_ref_list\"),\n    TYPE_ANNOTATION_SET_ITEM(       0x1003, \"annotation_set_item\"),\n    TYPE_CLASS_DATA_ITEM(           0x2000, \"class_data_item\"),\n    TYPE_CODE_ITEM(                 0x2001, \"code_item\"),\n    TYPE_STRING_DATA_ITEM(          0x2002, \"string_data_item\"),\n    TYPE_DEBUG_INFO_ITEM(           0x2003, \"debug_info_item\"),\n    TYPE_ANNOTATION_ITEM(           0x2004, \"annotation_item\"),\n    TYPE_ENCODED_ARRAY_ITEM(        0x2005, \"encoded_array_item\"),\n    TYPE_ANNOTATIONS_DIRECTORY_ITEM(0x2006, \"annotations_directory_item\"),\n    TYPE_MAP_ITEM(                  -1,     \"map_item\"),\n    TYPE_TYPE_ITEM(                 -1,     \"type_item\"),\n    TYPE_EXCEPTION_HANDLER_ITEM(    -1,     \"exception_handler_item\"),\n    TYPE_ANNOTATION_SET_REF_ITEM(   -1,     \"annotation_set_ref_item\");\n\n    /** value when represented in a {@link MapItem} */\n    private final int mapValue;\n\n    /** {@code non-null;} name of the type */\n    private final String typeName;\n\n    /** {@code non-null;} the short human name */\n    private final String humanName;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param mapValue value when represented in a {@link MapItem}\n     * @param typeName {@code non-null;} name of the type\n     */\n    private ItemType(int mapValue, String typeName) {\n        this.mapValue = mapValue;\n        this.typeName = typeName;\n\n        // Make the human name.\n        String human = typeName;\n        if (human.endsWith(\"_item\")) {\n            human = human.substring(0, human.length() - 5);\n        }\n        this.humanName = human.replace('_', ' ');\n    }\n\n    /**\n     * Gets the map value.\n     *\n     * @return the map value\n     */\n    public int getMapValue() {\n        return mapValue;\n    }\n\n    /**\n     * Gets the type name.\n     *\n     * @return {@code non-null;} the type name\n     */\n    public String getTypeName() {\n        return typeName;\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return humanName;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/MapItem.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.ArrayList;\n\n/**\n * Class that represents a map item.\n */\npublic final class MapItem extends OffsettedItem {\n    /** file alignment of this class, in bytes */\n    private static final int ALIGNMENT = 4;\n\n    /** write size of this class, in bytes: three {@code uint}s */\n    private static final int WRITE_SIZE = (4 * 3);\n\n    /** {@code non-null;} item type this instance covers */\n    private final ItemType type;\n\n    /** {@code non-null;} section this instance covers */\n    private final Section section;\n\n    /**\n     * {@code null-ok;} first item covered or {@code null} if this is\n     * a self-reference\n     */\n    private final Item firstItem;\n\n    /**\n     * {@code null-ok;} last item covered or {@code null} if this is\n     * a self-reference\n     */\n    private final Item lastItem;\n\n    /**\n     * {@code > 0;} count of items covered; {@code 1} if this\n     * is a self-reference\n     */\n    private final int itemCount;\n\n    /**\n     * Constructs a list item with instances of this class representing\n     * the contents of the given array of sections, adding it to the\n     * given map section.\n     *\n     * @param sections {@code non-null;} the sections\n     * @param mapSection {@code non-null;} the section that the resulting map\n     * should be added to; it should be empty on entry to this method\n     */\n    public static void addMap(Section[] sections,\n            MixedItemSection mapSection) {\n        if (sections == null) {\n            throw new NullPointerException(\"sections == null\");\n        }\n\n        if (mapSection.items().size() != 0) {\n            throw new IllegalArgumentException(\n                    \"mapSection.items().size() != 0\");\n        }\n\n        ArrayList<MapItem> items = new ArrayList<MapItem>(50);\n\n        for (Section section : sections) {\n            ItemType currentType = null;\n            Item firstItem = null;\n            Item lastItem = null;\n            int count = 0;\n\n            for (Item item : section.items()) {\n                ItemType type = item.itemType();\n                if (type != currentType) {\n                    if (count != 0) {\n                        items.add(new MapItem(currentType, section,\n                                        firstItem, lastItem, count));\n                    }\n                    currentType = type;\n                    firstItem = item;\n                    count = 0;\n                }\n                lastItem = item;\n                count++;\n            }\n\n            if (count != 0) {\n                // Add a MapItem for the final items in the section.\n                items.add(new MapItem(currentType, section,\n                                firstItem, lastItem, count));\n            } else if (section == mapSection) {\n                // Add a MapItem for the self-referential section.\n                items.add(new MapItem(mapSection));\n            }\n        }\n\n        mapSection.add(\n                new UniformListItem<MapItem>(ItemType.TYPE_MAP_LIST, items));\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param type {@code non-null;} item type this instance covers\n     * @param section {@code non-null;} section this instance covers\n     * @param firstItem {@code non-null;} first item covered\n     * @param lastItem {@code non-null;} last item covered\n     * @param itemCount {@code > 0;} count of items covered\n     */\n    private MapItem(ItemType type, Section section, Item firstItem,\n            Item lastItem, int itemCount) {\n        super(ALIGNMENT, WRITE_SIZE);\n\n        if (type == null) {\n            throw new NullPointerException(\"type == null\");\n        }\n\n        if (section == null) {\n            throw new NullPointerException(\"section == null\");\n        }\n\n        if (firstItem == null) {\n            throw new NullPointerException(\"firstItem == null\");\n        }\n\n        if (lastItem == null) {\n            throw new NullPointerException(\"lastItem == null\");\n        }\n\n        if (itemCount <= 0) {\n            throw new IllegalArgumentException(\"itemCount <= 0\");\n        }\n\n        this.type = type;\n        this.section = section;\n        this.firstItem = firstItem;\n        this.lastItem = lastItem;\n        this.itemCount = itemCount;\n    }\n\n    /**\n     * Constructs a self-referential instance. This instance is meant to\n     * represent the section containing the {@code map_list}.\n     *\n     * @param section {@code non-null;} section this instance covers\n     */\n    private MapItem(Section section) {\n        super(ALIGNMENT, WRITE_SIZE);\n\n        if (section == null) {\n            throw new NullPointerException(\"section == null\");\n        }\n\n        this.type = ItemType.TYPE_MAP_LIST;\n        this.section = section;\n        this.firstItem = null;\n        this.lastItem = null;\n        this.itemCount = 1;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_MAP_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        StringBuffer sb = new StringBuffer(100);\n\n        sb.append(getClass().getName());\n        sb.append('{');\n        sb.append(section.toString());\n        sb.append(' ');\n        sb.append(type.toHuman());\n        sb.append('}');\n\n        return sb.toString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        // We have nothing to add.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final String toHuman() {\n        return toString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void writeTo0(DexFile file, AnnotatedOutput out) {\n        int value = type.getMapValue();\n        int offset;\n\n        if (firstItem == null) {\n            offset = section.getFileOffset();\n        } else {\n            offset = section.getAbsoluteItemOffset(firstItem);\n        }\n\n        if (out.annotates()) {\n            out.annotate(0, offsetString() + ' ' + type.getTypeName() +\n                    \" map\");\n            out.annotate(2, \"  type:   \" + Hex.u2(value) + \" // \" +\n                    type.toString());\n            out.annotate(2, \"  unused: 0\");\n            out.annotate(4, \"  size:   \" + Hex.u4(itemCount));\n            out.annotate(4, \"  offset: \" + Hex.u4(offset));\n        }\n\n        out.writeShort(value);\n        out.writeShort(0); // unused\n        out.writeInt(itemCount);\n        out.writeInt(offset);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/MemberIdItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.SizeOf;\nimport com.taobao.android.dx.rop.cst.CstMemberRef;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Representation of a member (field or method) reference inside a\n * Dalvik file.\n */\npublic abstract class MemberIdItem extends IdItem {\n    /** {@code non-null;} the constant for the member */\n    private final CstMemberRef cst;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param cst {@code non-null;} the constant for the member\n     */\n    public MemberIdItem(CstMemberRef cst) {\n        super(cst.getDefiningClass());\n\n        this.cst = cst;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int writeSize() {\n        return SizeOf.MEMBER_ID_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        super.addContents(file);\n\n        StringIdsSection stringIds = file.getStringIds();\n        stringIds.intern(getRef().getNat().getName());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final void writeTo(DexFile file, AnnotatedOutput out) {\n        TypeIdsSection typeIds = file.getTypeIds();\n        StringIdsSection stringIds = file.getStringIds();\n        CstNat nat = cst.getNat();\n        int classIdx = typeIds.indexOf(getDefiningClass());\n        int nameIdx = stringIds.indexOf(nat.getName());\n        int typoidIdx = getTypoidIdx(file);\n\n        if (out.annotates()) {\n            out.annotate(0, indexString() + ' ' + cst.toHuman());\n            out.annotate(2, \"  class_idx: \" + Hex.u2(classIdx));\n            out.annotate(2, String.format(\"  %-10s %s\", getTypoidName() + ':',\n                            Hex.u2(typoidIdx)));\n            out.annotate(4, \"  name_idx:  \" + Hex.u4(nameIdx));\n        }\n\n        out.writeShort(classIdx);\n        out.writeShort(typoidIdx);\n        out.writeInt(nameIdx);\n    }\n\n    /**\n     * Returns the index of the type-like thing associated with\n     * this item, in order that it may be written out. Subclasses must\n     * override this to get whatever it is they need to store.\n     *\n     * @param file {@code non-null;} the file being written\n     * @return the index in question\n     */\n    protected abstract int getTypoidIdx(DexFile file);\n\n    /**\n     * Returns the field name of the type-like thing associated with\n     * this item, for listing-generating purposes. Subclasses must override\n     * this.\n     *\n     * @return {@code non-null;} the name in question\n     */\n    protected abstract String getTypoidName();\n\n    /**\n     * Gets the member constant.\n     *\n     * @return {@code non-null;} the constant\n     */\n    public final CstMemberRef getRef() {\n        return cst;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/MemberIdsSection.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.DexFormat;\nimport com.taobao.android.dex.DexIndexOverflowException;\nimport com.taobao.android.dx.command.dexer.Main;\n\nimport java.util.Formatter;\nimport java.util.Map;\nimport java.util.TreeMap;\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * Member (field or method) refs list section of a {@code .dex} file.\n */\npublic abstract class MemberIdsSection extends UniformItemSection {\n\n    /**\n     * Constructs an instance. The file offset is initially unknown.\n     *\n     * @param name {@code null-ok;} the name of this instance, for annotation\n     * purposes\n     * @param file {@code non-null;} file that this instance is part of\n     */\n    public MemberIdsSection(String name, DexFile file) {\n        super(name, file, 4);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void orderItems() {\n        int idx = 0;\n\n        if (items().size() > DexFormat.MAX_MEMBER_IDX + 1) {\n            throw new DexIndexOverflowException(getTooManyMembersMessage());\n        }\n\n        for (Object i : items()) {\n            ((MemberIdItem) i).setIndex(idx);\n            idx++;\n        }\n    }\n\n    private String getTooManyMembersMessage() {\n        Map<String, AtomicInteger> membersByPackage = new TreeMap<String, AtomicInteger>();\n        for (Object member : items()) {\n            String packageName = ((MemberIdItem) member).getDefiningClass().getPackageName();\n            AtomicInteger count = membersByPackage.get(packageName);\n            if (count == null) {\n                count = new AtomicInteger();\n                membersByPackage.put(packageName, count);\n            }\n            count.incrementAndGet();\n        }\n\n        Formatter formatter = new Formatter();\n        try {\n            String memberType = this instanceof MethodIdsSection ? \"method\" : \"field\";\n            formatter.format(\"Too many %s references: %d; max is %d.%n\" +\n                    new Main().getTooManyIdsErrorMessage() + \"%n\" +\n                    \"References by package:\",\n                    memberType, items().size(), DexFormat.MAX_MEMBER_IDX + 1);\n            for (Map.Entry<String, AtomicInteger> entry : membersByPackage.entrySet()) {\n                formatter.format(\"%n%6d %s\", entry.getValue().get(), entry.getKey());\n            }\n            return formatter.toString();\n        } finally {\n            formatter.close();\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/MethodAnnotationStruct.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.annotation.Annotations;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.ToHuman;\n\n/**\n * Association of a method and its annotations.\n */\npublic final class MethodAnnotationStruct\n        implements ToHuman, Comparable<MethodAnnotationStruct> {\n    /** {@code non-null;} the method in question */\n    private final CstMethodRef method;\n\n    /** {@code non-null;} the associated annotations */\n    private AnnotationSetItem annotations;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param method {@code non-null;} the method in question\n     * @param annotations {@code non-null;} the associated annotations\n     */\n    public MethodAnnotationStruct(CstMethodRef method,\n            AnnotationSetItem annotations) {\n        if (method == null) {\n            throw new NullPointerException(\"method == null\");\n        }\n\n        if (annotations == null) {\n            throw new NullPointerException(\"annotations == null\");\n        }\n\n        this.method = method;\n        this.annotations = annotations;\n    }\n\n    /** {@inheritDoc} */\n    public int hashCode() {\n        return method.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    public boolean equals(Object other) {\n        if (! (other instanceof MethodAnnotationStruct)) {\n            return false;\n        }\n\n        return method.equals(((MethodAnnotationStruct) other).method);\n    }\n\n    /** {@inheritDoc} */\n    public int compareTo(MethodAnnotationStruct other) {\n        return method.compareTo(other.method);\n    }\n\n    /** {@inheritDoc} */\n    public void addContents(DexFile file) {\n        MethodIdsSection methodIds = file.getMethodIds();\n        MixedItemSection wordData = file.getWordData();\n\n        methodIds.intern(method);\n        annotations = wordData.intern(annotations);\n    }\n\n    /** {@inheritDoc} */\n    public void writeTo(DexFile file, AnnotatedOutput out) {\n        int methodIdx = file.getMethodIds().indexOf(method);\n        int annotationsOff = annotations.getAbsoluteOffset();\n\n        if (out.annotates()) {\n            out.annotate(0, \"    \" + method.toHuman());\n            out.annotate(4, \"      method_idx:      \" + Hex.u4(methodIdx));\n            out.annotate(4, \"      annotations_off: \" +\n                    Hex.u4(annotationsOff));\n        }\n\n        out.writeInt(methodIdx);\n        out.writeInt(annotationsOff);\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return method.toHuman() + \": \" + annotations;\n    }\n\n    /**\n     * Gets the method this item is for.\n     *\n     * @return {@code non-null;} the method\n     */\n    public CstMethodRef getMethod() {\n        return method;\n    }\n\n    /**\n     * Gets the associated annotations.\n     *\n     * @return {@code non-null;} the annotations\n     */\n    public Annotations getAnnotations() {\n        return annotations.getAnnotations();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/MethodIdItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.cst.CstBaseMethodRef;\n\n/**\n * Representation of a method reference inside a Dalvik file.\n */\npublic final class MethodIdItem extends MemberIdItem {\n    /**\n     * Constructs an instance.\n     *\n     * @param method {@code non-null;} the constant for the method\n     */\n    public MethodIdItem(CstBaseMethodRef method) {\n        super(method);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_METHOD_ID_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        super.addContents(file);\n\n        ProtoIdsSection protoIds = file.getProtoIds();\n        protoIds.intern(getMethodRef().getPrototype());\n    }\n\n    /**\n     * Gets the method constant.\n     *\n     * @return {@code non-null;} the constant\n     */\n    public CstBaseMethodRef getMethodRef() {\n        return (CstBaseMethodRef) getRef();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int getTypoidIdx(DexFile file) {\n        ProtoIdsSection protoIds = file.getProtoIds();\n        return protoIds.indexOf(getMethodRef().getPrototype());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected String getTypoidName() {\n        return \"proto_idx\";\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/MethodIdsSection.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstBaseMethodRef;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\n\nimport java.util.Collection;\nimport java.util.TreeMap;\n\n/**\n * Method refs list section of a {@code .dex} file.\n */\npublic final class MethodIdsSection extends MemberIdsSection {\n    /**\n     * {@code non-null;} map from method constants to {@link\n     * MethodIdItem} instances\n     */\n    private final TreeMap<CstBaseMethodRef, MethodIdItem> methodIds;\n\n    /**\n     * Constructs an instance. The file offset is initially unknown.\n     *\n     * @param file {@code non-null;} file that this instance is part of\n     */\n    public MethodIdsSection(DexFile file) {\n        super(\"method_ids\", file);\n\n        methodIds = new TreeMap<CstBaseMethodRef, MethodIdItem>();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Collection<? extends Item> items() {\n        return methodIds.values();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public IndexedItem get(Constant cst) {\n        if (cst == null) {\n            throw new NullPointerException(\"cst == null\");\n        }\n\n        throwIfNotPrepared();\n\n        IndexedItem result = methodIds.get((CstBaseMethodRef) cst);\n\n        if (result == null) {\n            throw new IllegalArgumentException(\"not found\");\n        }\n\n        return result;\n    }\n\n    /**\n     * Writes the portion of the file header that refers to this instance.\n     *\n     * @param out {@code non-null;} where to write\n     */\n    public void writeHeaderPart(AnnotatedOutput out) {\n        throwIfNotPrepared();\n\n        int sz = methodIds.size();\n        int offset = (sz == 0) ? 0 : getFileOffset();\n\n        if (out.annotates()) {\n            out.annotate(4, \"method_ids_size: \" + Hex.u4(sz));\n            out.annotate(4, \"method_ids_off:  \" + Hex.u4(offset));\n        }\n\n        out.writeInt(sz);\n        out.writeInt(offset);\n    }\n\n    /**\n     * Interns an element into this instance.\n     *\n     * @param method {@code non-null;} the reference to intern\n     * @return {@code non-null;} the interned reference\n     */\n    public synchronized MethodIdItem intern(CstBaseMethodRef method) {\n        if (method == null) {\n            throw new NullPointerException(\"method == null\");\n        }\n\n        throwIfPrepared();\n\n        MethodIdItem result = methodIds.get(method);\n\n        if (result == null) {\n            result = new MethodIdItem(method);\n            methodIds.put(method, result);\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets the index of the given reference, which must have been added\n     * to this instance.\n     *\n     * @param ref {@code non-null;} the reference to look up\n     * @return {@code >= 0;} the reference's index\n     */\n    public int indexOf(CstBaseMethodRef ref) {\n        if (ref == null) {\n            throw new NullPointerException(\"ref == null\");\n        }\n\n        throwIfNotPrepared();\n\n        MethodIdItem item = methodIds.get(ref);\n\n        if (item == null) {\n            throw new IllegalArgumentException(\"not found\");\n        }\n\n        return item.getIndex();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/MixedItemSection.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.NoSuchElementException;\nimport java.util.TreeMap;\n\n/**\n * A section of a {@code .dex} file which consists of a sequence of\n * {@link OffsettedItem} objects, which may each be of a different concrete\n * class and/or size.\n *\n * <b>Note:</b> It is invalid for an item in an instance of this class to\n * have a larger alignment requirement than the alignment of this instance.\n */\npublic final class MixedItemSection extends Section {\n    static enum SortType {\n        /** no sorting */\n        NONE,\n\n        /** sort by type only */\n        TYPE,\n\n        /** sort in class-major order, with instances sorted per-class */\n        INSTANCE;\n    };\n\n    /** {@code non-null;} sorter which sorts instances by type */\n    private static final Comparator<OffsettedItem> TYPE_SORTER =\n        new Comparator<OffsettedItem>() {\n        public int compare(OffsettedItem item1, OffsettedItem item2) {\n            ItemType type1 = item1.itemType();\n            ItemType type2 = item2.itemType();\n            return type1.compareTo(type2);\n        }\n    };\n\n    /** {@code non-null;} the items in this part */\n    private final ArrayList<OffsettedItem> items;\n\n    /** {@code non-null;} items that have been explicitly interned */\n    private final HashMap<OffsettedItem, OffsettedItem> interns;\n\n    /** {@code non-null;} how to sort the items */\n    private final SortType sort;\n\n    /**\n     * {@code >= -1;} the current size of this part, in bytes, or {@code -1}\n     * if not yet calculated\n     */\n    private int writeSize;\n\n    /**\n     * Constructs an instance. The file offset is initially unknown.\n     *\n     * @param name {@code null-ok;} the name of this instance, for annotation\n     * purposes\n     * @param file {@code non-null;} file that this instance is part of\n     * @param alignment {@code > 0;} alignment requirement for the final output;\n     * must be a power of 2\n     * @param sort how the items should be sorted in the final output\n     */\n    public MixedItemSection(String name, DexFile file, int alignment,\n            SortType sort) {\n        super(name, file, alignment);\n\n        this.items = new ArrayList<OffsettedItem>(100);\n        this.interns = new HashMap<OffsettedItem, OffsettedItem>(100);\n        this.sort = sort;\n        this.writeSize = -1;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Collection<? extends Item> items() {\n        return items;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int writeSize() {\n        throwIfNotPrepared();\n        return writeSize;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int getAbsoluteItemOffset(Item item) {\n        OffsettedItem oi = (OffsettedItem) item;\n        return oi.getAbsoluteOffset();\n    }\n\n    /**\n     * Gets the size of this instance, in items.\n     *\n     * @return {@code >= 0;} the size\n     */\n    public int size() {\n        return items.size();\n    }\n\n    /**\n     * Writes the portion of the file header that refers to this instance.\n     *\n     * @param out {@code non-null;} where to write\n     */\n    public void writeHeaderPart(AnnotatedOutput out) {\n        throwIfNotPrepared();\n\n        if (writeSize == -1) {\n            throw new RuntimeException(\"write size not yet set\");\n        }\n\n        int sz = writeSize;\n        int offset = (sz == 0) ? 0 : getFileOffset();\n        String name = getName();\n\n        if (name == null) {\n            name = \"<unnamed>\";\n        }\n\n        int spaceCount = 15 - name.length();\n        char[] spaceArr = new char[spaceCount];\n        Arrays.fill(spaceArr, ' ');\n        String spaces = new String(spaceArr);\n\n        if (out.annotates()) {\n            out.annotate(4, name + \"_size:\" + spaces + Hex.u4(sz));\n            out.annotate(4, name + \"_off: \" + spaces + Hex.u4(offset));\n        }\n\n        out.writeInt(sz);\n        out.writeInt(offset);\n    }\n\n    /**\n     * Adds an item to this instance. This will in turn tell the given item\n     * that it has been added to this instance. It is invalid to add the\n     * same item to more than one instance, nor to add the same items\n     * multiple times to a single instance.\n     *\n     * @param item {@code non-null;} the item to add\n     */\n    public void add(OffsettedItem item) {\n        throwIfPrepared();\n\n        try {\n            if (item.getAlignment() > getAlignment()) {\n                throw new IllegalArgumentException(\n                        \"incompatible item alignment\");\n            }\n        } catch (NullPointerException ex) {\n            // Elucidate the exception.\n            throw new NullPointerException(\"item == null\");\n        }\n\n        items.add(item);\n    }\n\n    /**\n     * Interns an item in this instance, returning the interned instance\n     * (which may not be the one passed in). This will add the item if no\n     * equal item has been added.\n     *\n     * @param item {@code non-null;} the item to intern\n     * @return {@code non-null;} the equivalent interned instance\n     */\n    public synchronized <T extends OffsettedItem> T intern(T item) {\n        throwIfPrepared();\n\n        OffsettedItem result = interns.get(item);\n\n        if (result != null) {\n            return (T) result;\n        }\n\n        add(item);\n        interns.put(item, item);\n        return item;\n    }\n\n    /**\n     * Gets an item which was previously interned.\n     *\n     * @param item {@code non-null;} the item to look for\n     * @return {@code non-null;} the equivalent already-interned instance\n     */\n    public <T extends OffsettedItem> T get(T item) {\n        throwIfNotPrepared();\n\n        OffsettedItem result = interns.get(item);\n\n        if (result != null) {\n            return (T) result;\n        }\n\n        throw new NoSuchElementException(item.toString());\n    }\n\n    /**\n     * Writes an index of contents of the items in this instance of the\n     * given type. If there are none, this writes nothing. If there are any,\n     * then the index is preceded by the given intro string.\n     *\n     * @param out {@code non-null;} where to write to\n     * @param itemType {@code non-null;} the item type of interest\n     * @param intro {@code non-null;} the introductory string for non-empty indices\n     */\n    public void writeIndexAnnotation(AnnotatedOutput out, ItemType itemType,\n            String intro) {\n        throwIfNotPrepared();\n\n        TreeMap<String, OffsettedItem> index =\n            new TreeMap<String, OffsettedItem>();\n\n        for (OffsettedItem item : items) {\n            if (item.itemType() == itemType) {\n                String label = item.toHuman();\n                index.put(label, item);\n            }\n        }\n\n        if (index.size() == 0) {\n            return;\n        }\n\n        out.annotate(0, intro);\n\n        for (Map.Entry<String, OffsettedItem> entry : index.entrySet()) {\n            String label = entry.getKey();\n            OffsettedItem item = entry.getValue();\n            out.annotate(0, item.offsetString() + ' ' + label + '\\n');\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void prepare0() {\n        DexFile file = getFile();\n\n        /*\n         * It's okay for new items to be added as a result of an\n         * addContents() call; we just have to deal with the possibility.\n         */\n\n        int i = 0;\n        for (;;) {\n            int sz = items.size();\n            if (i >= sz) {\n                break;\n            }\n\n            for (/*i*/; i < sz; i++) {\n                OffsettedItem one = items.get(i);\n                one.addContents(file);\n            }\n        }\n    }\n\n    /**\n     * Places all the items in this instance at particular offsets. This\n     * will call {@link OffsettedItem#place} on each item. If an item\n     * does not know its write size before the call to {@code place},\n     * it is that call which is responsible for setting the write size.\n     * This method may only be called once per instance; subsequent calls\n     * will throw an exception.\n     */\n    public void placeItems() {\n        throwIfNotPrepared();\n\n        switch (sort) {\n            case INSTANCE: {\n                Collections.sort(items);\n                break;\n            }\n            case TYPE: {\n                Collections.sort(items, TYPE_SORTER);\n                break;\n            }\n        }\n\n        int sz = items.size();\n        int outAt = 0;\n        for (int i = 0; i < sz; i++) {\n            OffsettedItem one = items.get(i);\n            try {\n                int placedAt = one.place(this, outAt);\n\n                if (placedAt < outAt) {\n                    throw new RuntimeException(\"bogus place() result for \" +\n                            one);\n                }\n\n                outAt = placedAt + one.writeSize();\n            } catch (RuntimeException ex) {\n                throw ExceptionWithContext.withContext(ex,\n                        \"...while placing \" + one);\n            }\n        }\n\n        writeSize = outAt;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void writeTo0(AnnotatedOutput out) {\n        boolean annotates = out.annotates();\n        boolean first = true;\n        DexFile file = getFile();\n        int at = 0;\n\n        for (OffsettedItem one : items) {\n            if (annotates) {\n                if (first) {\n                    first = false;\n                } else {\n                    out.annotate(0, \"\\n\");\n                }\n            }\n\n            int alignMask = one.getAlignment() - 1;\n            int writeAt = (at + alignMask) & ~alignMask;\n\n            if (at != writeAt) {\n                out.writeZeroes(writeAt - at);\n                at = writeAt;\n            }\n\n            one.writeTo(file, out);\n            at += one.writeSize();\n        }\n\n        if (at != writeSize) {\n            throw new RuntimeException(\"output size mismatch\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/OffsettedItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dx.util.AnnotatedOutput;\n\n/**\n * An item in a Dalvik file which is referenced by absolute offset.\n */\npublic abstract class OffsettedItem extends Item\n        implements Comparable<OffsettedItem> {\n    /** {@code > 0;} alignment requirement */\n    private final int alignment;\n\n    /** {@code >= -1;} the size of this instance when written, in bytes, or\n     * {@code -1} if not yet known */\n    private int writeSize;\n\n    /**\n     * {@code null-ok;} section the item was added to, or {@code null} if\n     * not yet added\n     */\n    private Section addedTo;\n\n    /**\n     * {@code >= -1;} assigned offset of the item from the start of its section,\n     * or {@code -1} if not yet assigned\n     */\n    private int offset;\n\n    /**\n     * Gets the absolute offset of the given item, returning {@code 0}\n     * if handed {@code null}.\n     *\n     * @param item {@code null-ok;} the item in question\n     * @return {@code >= 0;} the item's absolute offset, or {@code 0}\n     * if {@code item == null}\n     */\n    public static int getAbsoluteOffsetOr0(OffsettedItem item) {\n        if (item == null) {\n            return 0;\n        }\n\n        return item.getAbsoluteOffset();\n    }\n\n    /**\n     * Constructs an instance. The offset is initially unassigned.\n     *\n     * @param alignment {@code > 0;} output alignment requirement; must be a\n     * power of 2\n     * @param writeSize {@code >= -1;} the size of this instance when written,\n     * in bytes, or {@code -1} if not immediately known\n     */\n    public OffsettedItem(int alignment, int writeSize) {\n        Section.validateAlignment(alignment);\n\n        if (writeSize < -1) {\n            throw new IllegalArgumentException(\"writeSize < -1\");\n        }\n\n        this.alignment = alignment;\n        this.writeSize = writeSize;\n        this.addedTo = null;\n        this.offset = -1;\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * Comparisons for this class are defined to be type-major (if the\n     * types don't match then the objects are not equal), with\n     * {@link #compareTo0} deciding same-type comparisons.\n     */\n    @Override\n    public final boolean equals(Object other) {\n        if (this == other) {\n            return true;\n        }\n\n        OffsettedItem otherItem = (OffsettedItem) other;\n        ItemType thisType = itemType();\n        ItemType otherType = otherItem.itemType();\n\n        if (thisType != otherType) {\n            return false;\n        }\n\n        return (compareTo0(otherItem) == 0);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * Comparisons for this class are defined to be class-major (if the\n     * classes don't match then the objects are not equal), with\n     * {@link #compareTo0} deciding same-class comparisons.\n     */\n    public final int compareTo(OffsettedItem other) {\n        if (this == other) {\n            return 0;\n        }\n\n        ItemType thisType = itemType();\n        ItemType otherType = other.itemType();\n\n        if (thisType != otherType) {\n            return thisType.compareTo(otherType);\n        }\n\n        return compareTo0(other);\n    }\n\n    /**\n     * Sets the write size of this item. This may only be called once\n     * per instance, and only if the size was unknown upon instance\n     * creation.\n     *\n     * @param writeSize {@code > 0;} the write size, in bytes\n     */\n    public final void setWriteSize(int writeSize) {\n        if (writeSize < 0) {\n            throw new IllegalArgumentException(\"writeSize < 0\");\n        }\n\n        if (this.writeSize >= 0) {\n            throw new UnsupportedOperationException(\"writeSize already set\");\n        }\n\n        this.writeSize = writeSize;\n    }\n\n    /** {@inheritDoc}\n     *\n     * @throws UnsupportedOperationException thrown if the write size\n     * is not yet known\n     */\n    @Override\n    public final int writeSize() {\n        if (writeSize < 0) {\n            throw new UnsupportedOperationException(\"writeSize is unknown\");\n        }\n\n        return writeSize;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final void writeTo(DexFile file, AnnotatedOutput out) {\n        out.alignTo(alignment);\n\n        try {\n            if (writeSize < 0) {\n                throw new UnsupportedOperationException(\n                        \"writeSize is unknown\");\n            }\n            out.assertCursor(getAbsoluteOffset());\n        } catch (RuntimeException ex) {\n            throw ExceptionWithContext.withContext(ex,\n                    \"...while writing \" + this);\n        }\n\n        writeTo0(file, out);\n    }\n\n    /**\n     * Gets the relative item offset. The offset is from the start of\n     * the section which the instance was written to.\n     *\n     * @return {@code >= 0;} the offset\n     * @throws RuntimeException thrown if the offset is not yet known\n     */\n    public final int getRelativeOffset() {\n        if (offset < 0) {\n            throw new RuntimeException(\"offset not yet known\");\n        }\n\n        return offset;\n    }\n\n    /**\n     * Gets the absolute item offset. The offset is from the start of\n     * the file which the instance was written to.\n     *\n     * @return {@code >= 0;} the offset\n     * @throws RuntimeException thrown if the offset is not yet known\n     */\n    public final int getAbsoluteOffset() {\n        if (offset < 0) {\n            throw new RuntimeException(\"offset not yet known\");\n        }\n\n        return addedTo.getAbsoluteOffset(offset);\n    }\n\n    /**\n     * Indicates that this item has been added to the given section at\n     * the given offset. It is only valid to call this method once per\n     * instance.\n     *\n     * @param addedTo {@code non-null;} the section this instance has\n     * been added to\n     * @param offset {@code >= 0;} the desired offset from the start of the\n     * section where this instance was placed\n     * @return {@code >= 0;} the offset that this instance should be placed at\n     * in order to meet its alignment constraint\n     */\n    public final int place(Section addedTo, int offset) {\n        if (addedTo == null) {\n            throw new NullPointerException(\"addedTo == null\");\n        }\n\n        if (offset < 0) {\n            throw new IllegalArgumentException(\"offset < 0\");\n        }\n\n        if (this.addedTo != null) {\n            throw new RuntimeException(\"already written\");\n        }\n\n        int mask = alignment - 1;\n        offset = (offset + mask) & ~mask;\n\n        this.addedTo = addedTo;\n        this.offset = offset;\n\n        place0(addedTo, offset);\n\n        return offset;\n    }\n\n    /**\n     * Gets the alignment requirement of this instance. An instance should\n     * only be written when so aligned.\n     *\n     * @return {@code > 0;} the alignment requirement; must be a power of 2\n     */\n    public final int getAlignment() {\n        return alignment;\n    }\n\n    /**\n     * Gets the absolute offset of this item as a string, suitable for\n     * including in annotations.\n     *\n     * @return {@code non-null;} the offset string\n     */\n    public final String offsetString() {\n        return '[' + Integer.toHexString(getAbsoluteOffset()) + ']';\n    }\n\n    /**\n     * Gets a short human-readable string representing this instance.\n     *\n     * @return {@code non-null;} the human form\n     */\n    public abstract String toHuman();\n\n    /**\n     * Compares this instance to another which is guaranteed to be of\n     * the same class. The default implementation of this method is to\n     * throw an exception (unsupported operation). If a particular\n     * class needs to actually sort, then it should override this\n     * method.\n     *\n     * @param other {@code non-null;} instance to compare to\n     * @return {@code -1}, {@code 0}, or {@code 1}, depending\n     * on the sort order of this instance and the other\n     */\n    protected int compareTo0(OffsettedItem other) {\n        throw new UnsupportedOperationException(\"unsupported\");\n    }\n\n    /**\n     * Does additional work required when placing an instance. The\n     * default implementation of this method is a no-op. If a\n     * particular class needs to do something special, then it should\n     * override this method. In particular, if this instance did not\n     * know its write size up-front, then this method is responsible\n     * for setting it.\n     *\n     * @param addedTo {@code non-null;} the section this instance has been added to\n     * @param offset {@code >= 0;} the offset from the start of the\n     * section where this instance was placed\n     */\n    protected void place0(Section addedTo, int offset) {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Performs the actual write of the contents of this instance to\n     * the given data section. This is called by {@link #writeTo},\n     * which will have taken care of ensuring alignment.\n     *\n     * @param file {@code non-null;} the file to use for reference\n     * @param out {@code non-null;} where to write to\n     */\n    protected abstract void writeTo0(DexFile file, AnnotatedOutput out);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/ParameterAnnotationStruct.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.annotation.Annotations;\nimport com.taobao.android.dx.rop.annotation.AnnotationsList;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.ToHuman;\n\nimport java.util.ArrayList;\n\n/**\n * Association of a method and its parameter annotations.\n */\npublic final class ParameterAnnotationStruct\n        implements ToHuman, Comparable<ParameterAnnotationStruct> {\n    /** {@code non-null;} the method in question */\n    private final CstMethodRef method;\n\n    /** {@code non-null;} the associated annotations list */\n    private final AnnotationsList annotationsList;\n\n    /** {@code non-null;} the associated annotations list, as an item */\n    private final UniformListItem<AnnotationSetRefItem> annotationsItem;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param method {@code non-null;} the method in question\n     * @param annotationsList {@code non-null;} the associated annotations list\n     * @param dexFile {@code non-null;} dex output\n     */\n    public ParameterAnnotationStruct(CstMethodRef method,\n            AnnotationsList annotationsList, DexFile dexFile) {\n        if (method == null) {\n            throw new NullPointerException(\"method == null\");\n        }\n\n        if (annotationsList == null) {\n            throw new NullPointerException(\"annotationsList == null\");\n        }\n\n        this.method = method;\n        this.annotationsList = annotationsList;\n\n        /*\n         * Construct an item for the annotations list. TODO: This\n         * requires way too much copying; fix it.\n         */\n\n        int size = annotationsList.size();\n        ArrayList<AnnotationSetRefItem> arrayList = new\n            ArrayList<AnnotationSetRefItem>(size);\n\n        for (int i = 0; i < size; i++) {\n            Annotations annotations = annotationsList.get(i);\n            AnnotationSetItem item = new AnnotationSetItem(annotations, dexFile);\n            arrayList.add(new AnnotationSetRefItem(item));\n        }\n\n        this.annotationsItem = new UniformListItem<AnnotationSetRefItem>(\n                ItemType.TYPE_ANNOTATION_SET_REF_LIST, arrayList);\n    }\n\n    /** {@inheritDoc} */\n    public int hashCode() {\n        return method.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    public boolean equals(Object other) {\n        if (! (other instanceof ParameterAnnotationStruct)) {\n            return false;\n        }\n\n        return method.equals(((ParameterAnnotationStruct) other).method);\n    }\n\n    /** {@inheritDoc} */\n    public int compareTo(ParameterAnnotationStruct other) {\n        return method.compareTo(other.method);\n    }\n\n    /** {@inheritDoc} */\n    public void addContents(DexFile file) {\n        MethodIdsSection methodIds = file.getMethodIds();\n        MixedItemSection wordData = file.getWordData();\n\n        methodIds.intern(method);\n        wordData.add(annotationsItem);\n    }\n\n    /** {@inheritDoc} */\n    public void writeTo(DexFile file, AnnotatedOutput out) {\n        int methodIdx = file.getMethodIds().indexOf(method);\n        int annotationsOff = annotationsItem.getAbsoluteOffset();\n\n        if (out.annotates()) {\n            out.annotate(0, \"    \" + method.toHuman());\n            out.annotate(4, \"      method_idx:      \" + Hex.u4(methodIdx));\n            out.annotate(4, \"      annotations_off: \" +\n                    Hex.u4(annotationsOff));\n        }\n\n        out.writeInt(methodIdx);\n        out.writeInt(annotationsOff);\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        StringBuilder sb = new StringBuilder();\n\n        sb.append(method.toHuman());\n        sb.append(\": \");\n\n        boolean first = true;\n        for (AnnotationSetRefItem item : annotationsItem.getItems()) {\n            if (first) {\n                first = false;\n            } else {\n                sb.append(\", \");\n            }\n            sb.append(item.toHuman());\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Gets the method this item is for.\n     *\n     * @return {@code non-null;} the method\n     */\n    public CstMethodRef getMethod() {\n        return method;\n    }\n\n    /**\n     * Gets the associated annotations list.\n     *\n     * @return {@code non-null;} the annotations list\n     */\n    public AnnotationsList getAnnotationsList() {\n        return annotationsList;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/ProtoIdItem.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.SizeOf;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.type.Prototype;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Representation of a method prototype reference inside a Dalvik file.\n */\npublic final class ProtoIdItem extends IndexedItem {\n    /** {@code non-null;} the wrapped prototype */\n    private final Prototype prototype;\n\n    /** {@code non-null;} the short-form of the prototype */\n    private final CstString shortForm;\n\n    /**\n     * {@code null-ok;} the list of parameter types or {@code null} if this\n     * prototype has no parameters\n     */\n    private TypeListItem parameterTypes;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param prototype {@code non-null;} the constant for the prototype\n     */\n    public ProtoIdItem(Prototype prototype) {\n        if (prototype == null) {\n            throw new NullPointerException(\"prototype == null\");\n        }\n\n        this.prototype = prototype;\n        this.shortForm = makeShortForm(prototype);\n\n        StdTypeList parameters = prototype.getParameterTypes();\n        this.parameterTypes = (parameters.size() == 0) ? null\n            : new TypeListItem(parameters);\n    }\n\n    /**\n     * Creates the short-form of the given prototype.\n     *\n     * @param prototype {@code non-null;} the prototype\n     * @return {@code non-null;} the short form\n     */\n    private static CstString makeShortForm(Prototype prototype) {\n        StdTypeList parameters = prototype.getParameterTypes();\n        int size = parameters.size();\n        StringBuilder sb = new StringBuilder(size + 1);\n\n        sb.append(shortFormCharFor(prototype.getReturnType()));\n\n        for (int i = 0; i < size; i++) {\n            sb.append(shortFormCharFor(parameters.getType(i)));\n        }\n\n        return new CstString(sb.toString());\n    }\n\n    /**\n     * Gets the short-form character for the given type.\n     *\n     * @param type {@code non-null;} the type\n     * @return the corresponding short-form character\n     */\n    private static char shortFormCharFor(Type type) {\n        char descriptorChar = type.getDescriptor().charAt(0);\n\n        if (descriptorChar == '[') {\n            return 'L';\n        }\n\n        return descriptorChar;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_PROTO_ID_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int writeSize() {\n        return SizeOf.PROTO_ID_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        StringIdsSection stringIds = file.getStringIds();\n        TypeIdsSection typeIds = file.getTypeIds();\n        MixedItemSection typeLists = file.getTypeLists();\n\n        typeIds.intern(prototype.getReturnType());\n        stringIds.intern(shortForm);\n\n        if (parameterTypes != null) {\n            parameterTypes = typeLists.intern(parameterTypes);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(DexFile file, AnnotatedOutput out) {\n        int shortyIdx = file.getStringIds().indexOf(shortForm);\n        int returnIdx = file.getTypeIds().indexOf(prototype.getReturnType());\n        int paramsOff = OffsettedItem.getAbsoluteOffsetOr0(parameterTypes);\n\n        if (out.annotates()) {\n            StringBuilder sb = new StringBuilder();\n            sb.append(prototype.getReturnType().toHuman());\n            sb.append(\" proto(\");\n\n            StdTypeList params = prototype.getParameterTypes();\n            int size = params.size();\n\n            for (int i = 0; i < size; i++) {\n                if (i != 0) {\n                    sb.append(\", \");\n                }\n                sb.append(params.getType(i).toHuman());\n            }\n\n            sb.append(\")\");\n            out.annotate(0, indexString() + ' ' + sb.toString());\n            out.annotate(4, \"  shorty_idx:      \" + Hex.u4(shortyIdx) +\n                    \" // \" + shortForm.toQuoted());\n            out.annotate(4, \"  return_type_idx: \" + Hex.u4(returnIdx) +\n                    \" // \" + prototype.getReturnType().toHuman());\n            out.annotate(4, \"  parameters_off:  \" + Hex.u4(paramsOff));\n        }\n\n        out.writeInt(shortyIdx);\n        out.writeInt(returnIdx);\n        out.writeInt(paramsOff);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/ProtoIdsSection.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.type.Prototype;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.Collection;\nimport java.util.TreeMap;\n\n/**\n * Proto (method prototype) identifiers list section of a\n * {@code .dex} file.\n */\npublic final class ProtoIdsSection extends UniformItemSection {\n    /**\n     * {@code non-null;} map from method prototypes to {@link ProtoIdItem} instances\n     */\n    private final TreeMap<Prototype, ProtoIdItem> protoIds;\n\n    /**\n     * Constructs an instance. The file offset is initially unknown.\n     *\n     * @param file {@code non-null;} file that this instance is part of\n     */\n    public ProtoIdsSection(DexFile file) {\n        super(\"proto_ids\", file, 4);\n\n        protoIds = new TreeMap<Prototype, ProtoIdItem>();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Collection<? extends Item> items() {\n        return protoIds.values();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public IndexedItem get(Constant cst) {\n        throw new UnsupportedOperationException(\"unsupported\");\n    }\n\n    /**\n     * Writes the portion of the file header that refers to this instance.\n     *\n     * @param out {@code non-null;} where to write\n     */\n    public void writeHeaderPart(AnnotatedOutput out) {\n        throwIfNotPrepared();\n\n        int sz = protoIds.size();\n        int offset = (sz == 0) ? 0 : getFileOffset();\n\n        if (sz > 65536) {\n            throw new UnsupportedOperationException(\"too many proto ids\");\n        }\n\n        if (out.annotates()) {\n            out.annotate(4, \"proto_ids_size:  \" + Hex.u4(sz));\n            out.annotate(4, \"proto_ids_off:   \" + Hex.u4(offset));\n        }\n\n        out.writeInt(sz);\n        out.writeInt(offset);\n    }\n\n    /**\n     * Interns an element into this instance.\n     *\n     * @param prototype {@code non-null;} the prototype to intern\n     * @return {@code non-null;} the interned reference\n     */\n    public synchronized ProtoIdItem intern(Prototype prototype) {\n        if (prototype == null) {\n            throw new NullPointerException(\"prototype == null\");\n        }\n\n        throwIfPrepared();\n\n        ProtoIdItem result = protoIds.get(prototype);\n\n        if (result == null) {\n            result = new ProtoIdItem(prototype);\n            protoIds.put(prototype, result);\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets the index of the given prototype, which must have\n     * been added to this instance.\n     *\n     * @param prototype {@code non-null;} the prototype to look up\n     * @return {@code >= 0;} the reference's index\n     */\n    public int indexOf(Prototype prototype) {\n        if (prototype == null) {\n            throw new NullPointerException(\"prototype == null\");\n        }\n\n        throwIfNotPrepared();\n\n        ProtoIdItem item = protoIds.get(prototype);\n\n        if (item == null) {\n            throw new IllegalArgumentException(\"not found\");\n        }\n\n        return item.getIndex();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void orderItems() {\n        int idx = 0;\n\n        for (Object i : items()) {\n            ((ProtoIdItem) i).setIndex(idx);\n            idx++;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/Section.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.Collection;\n\n/**\n * A section of a {@code .dex} file. Each section consists of a list\n * of items of some sort or other.\n */\npublic abstract class Section {\n    /** {@code null-ok;} name of this part, for annotation purposes */\n    private final String name;\n\n    /** {@code non-null;} file that this instance is part of */\n    private final DexFile file;\n\n    /** {@code > 0;} alignment requirement for the final output;\n     * must be a power of 2 */\n    private final int alignment;\n\n    /** {@code >= -1;} offset from the start of the file to this part, or\n     * {@code -1} if not yet known */\n    private int fileOffset;\n\n    /** whether {@link #prepare} has been called successfully on this\n     * instance */\n    private boolean prepared;\n\n    /**\n     * Validates an alignment.\n     *\n     * @param alignment the alignment\n     * @throws IllegalArgumentException thrown if {@code alignment}\n     * isn't a positive power of 2\n     */\n    public static void validateAlignment(int alignment) {\n        if ((alignment <= 0) ||\n            (alignment & (alignment - 1)) != 0) {\n            throw new IllegalArgumentException(\"invalid alignment\");\n        }\n    }\n\n    /**\n     * Constructs an instance. The file offset is initially unknown.\n     *\n     * @param name {@code null-ok;} the name of this instance, for annotation\n     * purposes\n     * @param file {@code non-null;} file that this instance is part of\n     * @param alignment {@code > 0;} alignment requirement for the final output;\n     * must be a power of 2\n     */\n    public Section(String name, DexFile file, int alignment) {\n        if (file == null) {\n            throw new NullPointerException(\"file == null\");\n        }\n\n        validateAlignment(alignment);\n\n        this.name = name;\n        this.file = file;\n        this.alignment = alignment;\n        this.fileOffset = -1;\n        this.prepared = false;\n    }\n\n    /**\n     * Gets the file that this instance is part of.\n     *\n     * @return {@code non-null;} the file\n     */\n    public final DexFile getFile() {\n        return file;\n    }\n\n    /**\n     * Gets the alignment for this instance's final output.\n     *\n     * @return {@code > 0;} the alignment\n     */\n    public final int getAlignment() {\n        return alignment;\n    }\n\n    /**\n     * Gets the offset from the start of the file to this part. This\n     * throws an exception if the offset has not yet been set.\n     *\n     * @return {@code >= 0;} the file offset\n     */\n    public final int getFileOffset() {\n        if (fileOffset < 0) {\n            throw new RuntimeException(\"fileOffset not set\");\n        }\n\n        return fileOffset;\n    }\n\n    /**\n     * Sets the file offset. It is only valid to call this method once\n     * once per instance.\n     *\n     * @param fileOffset {@code >= 0;} the desired offset from the start of the\n     * file where this for this instance\n     * @return {@code >= 0;} the offset that this instance should be placed at\n     * in order to meet its alignment constraint\n     */\n    public final int setFileOffset(int fileOffset) {\n        if (fileOffset < 0) {\n            throw new IllegalArgumentException(\"fileOffset < 0\");\n        }\n\n        if (this.fileOffset >= 0) {\n            throw new RuntimeException(\"fileOffset already set\");\n        }\n\n        int mask = alignment - 1;\n        fileOffset = (fileOffset + mask) & ~mask;\n\n        this.fileOffset = fileOffset;\n\n        return fileOffset;\n    }\n\n    /**\n     * Writes this instance to the given raw data object.\n     *\n     * @param out {@code non-null;} where to write to\n     */\n    public final void writeTo(AnnotatedOutput out) {\n        throwIfNotPrepared();\n        align(out);\n\n        int cursor = out.getCursor();\n\n        if (fileOffset < 0) {\n            fileOffset = cursor;\n        } else if (fileOffset != cursor) {\n            throw new RuntimeException(\"alignment mismatch: for \" + this +\n                                       \", at \" + cursor +\n                                       \", but expected \" + fileOffset);\n        }\n\n        if (out.annotates()) {\n            if (name != null) {\n                out.annotate(0, \"\\n\" + name + \":\");\n            } else if (cursor != 0) {\n                out.annotate(0, \"\\n\");\n            }\n        }\n\n        writeTo0(out);\n    }\n\n    /**\n     * Returns the absolute file offset, given an offset from the\n     * start of this instance's output. This is only valid to call\n     * once this instance has been assigned a file offset (via {@link\n     * #setFileOffset}).\n     *\n     * @param relative {@code >= 0;} the relative offset\n     * @return {@code >= 0;} the corresponding absolute file offset\n     */\n    public final int getAbsoluteOffset(int relative) {\n        if (relative < 0) {\n            throw new IllegalArgumentException(\"relative < 0\");\n        }\n\n        if (fileOffset < 0) {\n            throw new RuntimeException(\"fileOffset not yet set\");\n        }\n\n        return fileOffset + relative;\n    }\n\n    /**\n     * Returns the absolute file offset of the given item which must\n     * be contained in this section. This is only valid to call\n     * once this instance has been assigned a file offset (via {@link\n     * #setFileOffset}).\n     *\n     * <p><b>Note:</b> Subclasses must implement this as appropriate for\n     * their contents.</p>\n     *\n     * @param item {@code non-null;} the item in question\n     * @return {@code >= 0;} the item's absolute file offset\n     */\n    public abstract int getAbsoluteItemOffset(Item item);\n\n    /**\n     * Prepares this instance for writing. This performs any necessary\n     * prerequisites, including particularly adding stuff to other\n     * sections. This method may only be called once per instance;\n     * subsequent calls will throw an exception.\n     */\n    public final void prepare() {\n        throwIfPrepared();\n        prepare0();\n        System.out.println(\"prepare type:\"+name +\"in \"+file);\n        prepared = true;\n    }\n\n    /**\n     * Gets the collection of all the items in this section.\n     * It is not valid to attempt to change the returned list.\n     *\n     * @return {@code non-null;} the items\n     */\n    public abstract Collection<? extends Item> items();\n\n    /**\n     * Does the main work of {@link #prepare}.\n     */\n    protected abstract void prepare0();\n\n    /**\n     * Gets the size of this instance when output, in bytes.\n     *\n     * @return {@code >= 0;} the size of this instance, in bytes\n     */\n    public abstract int writeSize();\n\n    /**\n     * Throws an exception if {@link #prepare} has not been\n     * called on this instance.\n     */\n    protected final void throwIfNotPrepared() {\n        if (!prepared) {\n            throw new RuntimeException(\"not prepared\");\n        }\n    }\n\n    /**\n     * Throws an exception if {@link #prepare} has already been called\n     * on this instance.\n     */\n    protected final void throwIfPrepared() {\n        if (prepared) {\n            throw new RuntimeException(\"already prepared \"+name +\"in \"+file);\n        }\n    }\n\n    /**\n     * Aligns the output of the given data to the alignment of this instance.\n     *\n     * @param out {@code non-null;} the output to align\n     */\n    protected final void align(AnnotatedOutput out) {\n        out.alignTo(alignment);\n    }\n\n    /**\n     * Writes this instance to the given raw data object. This gets\n     * called by {@link #writeTo} after aligning the cursor of\n     * {@code out} and verifying that either the assigned file\n     * offset matches the actual cursor {@code out} or that the\n     * file offset was not previously assigned, in which case it gets\n     * assigned to {@code out}'s cursor.\n     *\n     * @param out {@code non-null;} where to write to\n     */\n    protected abstract void writeTo0(AnnotatedOutput out);\n\n    /**\n     * Returns the name of this section, for annotation purposes.\n     *\n     * @return {@code null-ok;} name of this part, for annotation purposes\n     */\n    protected final String getName() {\n        return name;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/Statistics.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.TreeMap;\n\n/**\n * Statistics about the contents of a file.\n */\npublic final class Statistics {\n    /** {@code non-null;} data about each type of item */\n    private final HashMap<String, Data> dataMap;\n\n    /**\n     * Constructs an instance.\n     */\n    public Statistics() {\n        dataMap = new HashMap<String, Data>(50);\n    }\n\n    /**\n     * Adds the given item to the statistics.\n     *\n     * @param item {@code non-null;} the item to add\n     */\n    public void add(Item item) {\n        String typeName = item.typeName();\n        Data data = dataMap.get(typeName);\n\n        if (data == null) {\n            dataMap.put(typeName, new Data(item, typeName));\n        } else {\n            data.add(item);\n        }\n    }\n\n    /**\n     * Adds the given list of items to the statistics.\n     *\n     * @param list {@code non-null;} the list of items to add\n     */\n    public void addAll(Section list) {\n        Collection<? extends Item> items = list.items();\n        for (Item item : items) {\n            add(item);\n        }\n    }\n\n    /**\n     * Writes the statistics as an annotation.\n     *\n     * @param out {@code non-null;} where to write to\n     */\n    public final void writeAnnotation(AnnotatedOutput out) {\n        if (dataMap.size() == 0) {\n            return;\n        }\n\n        out.annotate(0, \"\\nstatistics:\\n\");\n\n        TreeMap<String, Data> sortedData = new TreeMap<String, Data>();\n\n        for (Data data : dataMap.values()) {\n            sortedData.put(data.name, data);\n        }\n\n        for (Data data : sortedData.values()) {\n            data.writeAnnotation(out);\n        }\n    }\n\n    public String toHuman() {\n        StringBuilder sb = new StringBuilder();\n\n        sb.append(\"Statistics:\\n\");\n\n        TreeMap<String, Data> sortedData = new TreeMap<String, Data>();\n\n        for (Data data : dataMap.values()) {\n            sortedData.put(data.name, data);\n        }\n\n        for (Data data : sortedData.values()) {\n            sb.append(data.toHuman());\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Statistical data about a particular class.\n     */\n    private static class Data {\n        /** {@code non-null;} name to use as a label */\n        private final String name;\n\n        /** {@code >= 0;} number of instances */\n        private int count;\n\n        /** {@code >= 0;} total size of instances in bytes */\n        private int totalSize;\n\n        /** {@code >= 0;} largest size of any individual item */\n        private int largestSize;\n\n        /** {@code >= 0;} smallest size of any individual item */\n        private int smallestSize;\n\n        /**\n         * Constructs an instance for the given item.\n         *\n         * @param item {@code non-null;} item in question\n         * @param name {@code non-null;} type name to use\n         */\n        public Data(Item item, String name) {\n            int size = item.writeSize();\n\n            this.name = name;\n            this.count = 1;\n            this.totalSize = size;\n            this.largestSize = size;\n            this.smallestSize = size;\n        }\n\n        /**\n         * Incorporates a new item. This assumes the type name matches.\n         *\n         * @param item {@code non-null;} item to incorporate\n         */\n        public void add(Item item) {\n            int size = item.writeSize();\n\n            count++;\n            totalSize += size;\n\n            if (size > largestSize) {\n                largestSize = size;\n            }\n\n            if (size < smallestSize) {\n                smallestSize = size;\n            }\n        }\n\n        /**\n         * Writes this instance as an annotation.\n         *\n         * @param out {@code non-null;} where to write to\n         */\n        public void writeAnnotation(AnnotatedOutput out) {\n            out.annotate(toHuman());\n        }\n\n        /**\n         * Generates a human-readable string for this data item.\n         *\n         * @return string for human consumption.\n         */\n        public String toHuman() {\n            StringBuilder sb = new StringBuilder();\n\n            sb.append(\"  \" + name + \": \" +\n                         count + \" item\" + (count == 1 ? \"\" : \"s\") + \"; \" +\n                         totalSize + \" bytes total\\n\");\n\n            if (smallestSize == largestSize) {\n                sb.append(\"    \" + smallestSize + \" bytes/item\\n\");\n            } else {\n                int average = totalSize / count;\n                sb.append(\"    \" + smallestSize + \"..\" + largestSize +\n                             \" bytes/item; average \" + average + \"\\n\");\n            }\n\n            return sb.toString();\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/StringDataItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.Leb128;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Representation of string data for a particular string, in a Dalvik file.\n */\npublic final class StringDataItem extends OffsettedItem {\n    /** {@code non-null;} the string value */\n    private final CstString value;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param value {@code non-null;} the string value\n     */\n    public StringDataItem(CstString value) {\n        super(1, writeSize(value));\n\n        this.value = value;\n    }\n\n    /**\n     * Gets the write size for a given value.\n     *\n     * @param value {@code non-null;} the string value\n     * @return {@code >= 2}; the write size, in bytes\n     */\n    private static int writeSize(CstString value) {\n        int utf16Size = value.getUtf16Size();\n\n        // The +1 is for the '\\0' termination byte.\n        return Leb128.unsignedLeb128Size(utf16Size)\n            + value.getUtf8Size() + 1;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_STRING_DATA_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        // Nothing to do here.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo0(DexFile file, AnnotatedOutput out) {\n        ByteArray bytes = value.getBytes();\n        int utf16Size = value.getUtf16Size();\n\n        if (out.annotates()) {\n            out.annotate(Leb128.unsignedLeb128Size(utf16Size),\n                    \"utf16_size: \" + Hex.u4(utf16Size));\n            out.annotate(bytes.size() + 1, value.toQuoted());\n        }\n\n        out.writeUleb128(utf16Size);\n        out.write(bytes);\n        out.writeByte(0);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toHuman() {\n        return value.toQuoted();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int compareTo0(OffsettedItem other) {\n        StringDataItem otherData = (StringDataItem) other;\n\n        return value.compareTo(otherData.value);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/StringIdItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.SizeOf;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Representation of a string inside a Dalvik file.\n */\npublic final class StringIdItem\n        extends IndexedItem implements Comparable {\n    /** {@code non-null;} the string value */\n    private final CstString value;\n\n    /** {@code null-ok;} associated string data object, if known */\n    private StringDataItem data;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param value {@code non-null;} the string value\n     */\n    public StringIdItem(CstString value) {\n        if (value == null) {\n            throw new NullPointerException(\"value == null\");\n        }\n\n        this.value = value;\n        this.data = null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (!(other instanceof StringIdItem)) {\n            return false;\n        }\n\n        StringIdItem otherString = (StringIdItem) other;\n        return value.equals(otherString.value);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return value.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    public int compareTo(Object other) {\n        StringIdItem otherString = (StringIdItem) other;\n        return value.compareTo(otherString.value);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_STRING_ID_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int writeSize() {\n        return SizeOf.STRING_ID_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        if (data == null) {\n            // The string data hasn't yet been added, so add it.\n            MixedItemSection stringData = file.getStringData();\n            data = new StringDataItem(value);\n            stringData.add(data);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(DexFile file, AnnotatedOutput out) {\n        int dataOff = data.getAbsoluteOffset();\n\n        if (out.annotates()) {\n            out.annotate(0, indexString() + ' ' + value.toQuoted(100));\n            out.annotate(4, \"  string_data_off: \" + Hex.u4(dataOff));\n        }\n\n        out.writeInt(dataOff);\n    }\n\n    /**\n     * Gets the string value.\n     *\n     * @return {@code non-null;} the value\n     */\n    public CstString getValue() {\n        return value;\n    }\n\n    /**\n     * Gets the associated data object for this instance, if known.\n     *\n     * @return {@code null-ok;} the associated data object or {@code null}\n     * if not yet known\n     */\n    public StringDataItem getData() {\n        return data;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/StringIdsSection.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.Collection;\nimport java.util.TreeMap;\n\n/**\n * Strings list section of a {@code .dex} file.\n */\npublic final class StringIdsSection\n        extends UniformItemSection {\n    /**\n     * {@code non-null;} map from string constants to {@link\n     * StringIdItem} instances\n     */\n    private final TreeMap<CstString, StringIdItem> strings;\n\n    /**\n     * Constructs an instance. The file offset is initially unknown.\n     *\n     * @param file {@code non-null;} file that this instance is part of\n     */\n    public StringIdsSection(DexFile file) {\n        super(\"string_ids\", file, 4);\n\n        strings = new TreeMap<CstString, StringIdItem>();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Collection<? extends Item> items() {\n        return strings.values();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public IndexedItem get(Constant cst) {\n        if (cst == null) {\n            throw new NullPointerException(\"cst == null\");\n        }\n\n        throwIfNotPrepared();\n\n        IndexedItem result = strings.get((CstString) cst);\n\n        if (result == null) {\n            throw new IllegalArgumentException(\"not found\");\n        }\n\n        return result;\n    }\n\n    /**\n     * Writes the portion of the file header that refers to this instance.\n     *\n     * @param out {@code non-null;} where to write\n     */\n    public void writeHeaderPart(AnnotatedOutput out) {\n        throwIfNotPrepared();\n\n        int sz = strings.size();\n        int offset = (sz == 0) ? 0 : getFileOffset();\n\n        if (out.annotates()) {\n            out.annotate(4, \"string_ids_size: \" + Hex.u4(sz));\n            out.annotate(4, \"string_ids_off:  \" + Hex.u4(offset));\n        }\n\n        out.writeInt(sz);\n        out.writeInt(offset);\n    }\n\n    /**\n     * Interns an element into this instance.\n     *\n     * @param string {@code non-null;} the string to intern, as a regular Java\n     * {@code String}\n     * @return {@code non-null;} the interned string\n     */\n    public StringIdItem intern(String string) {\n        return intern(new StringIdItem(new CstString(string)));\n    }\n\n    /**\n     * Interns an element into this instance.\n     *\n     * @param string {@code non-null;} the string to intern, as a constant\n     * @return {@code non-null;} the interned string\n     */\n    public StringIdItem intern(CstString string) {\n        return intern(new StringIdItem(string));\n    }\n\n    /**\n     * Interns an element into this instance.\n     *\n     * @param string {@code non-null;} the string to intern\n     * @return {@code non-null;} the interned string\n     */\n    public synchronized StringIdItem intern(StringIdItem string) {\n        if (string == null) {\n            throw new NullPointerException(\"string == null\");\n        }\n\n        throwIfPrepared();\n\n        CstString value = string.getValue();\n        StringIdItem already = strings.get(value);\n\n        if (already != null) {\n            return already;\n        }\n\n        strings.put(value, string);\n        return string;\n    }\n\n    /**\n     * Interns the components of a name-and-type into this instance.\n     *\n     * @param nat {@code non-null;} the name-and-type\n     */\n    public synchronized void intern(CstNat nat) {\n        intern(nat.getName());\n        intern(nat.getDescriptor());\n    }\n\n    /**\n     * Gets the index of the given string, which must have been added\n     * to this instance.\n     *\n     * @param string {@code non-null;} the string to look up\n     * @return {@code >= 0;} the string's index\n     */\n    public int indexOf(CstString string) {\n        if (string == null) {\n            throw new NullPointerException(\"string == null\");\n        }\n\n        throwIfNotPrepared();\n\n        StringIdItem s = strings.get(string);\n\n        if (s == null) {\n            throw new IllegalArgumentException(\"not found\");\n        }\n\n        return s.getIndex();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void orderItems() {\n        int idx = 0;\n\n        for (StringIdItem s : strings.values()) {\n            s.setIndex(idx);\n            idx++;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/TypeIdItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.SizeOf;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Representation of a type reference inside a Dalvik file.\n */\npublic final class TypeIdItem extends IdItem {\n    /**\n     * Constructs an instance.\n     *\n     * @param type {@code non-null;} the constant for the type\n     */\n    public TypeIdItem(CstType type) {\n        super(type);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_TYPE_ID_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int writeSize() {\n        return SizeOf.TYPE_ID_ITEM;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        file.getStringIds().intern(getDefiningClass().getDescriptor());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void writeTo(DexFile file, AnnotatedOutput out) {\n        CstType type = getDefiningClass();\n        CstString descriptor = type.getDescriptor();\n        int idx = file.getStringIds().indexOf(descriptor);\n\n        if (out.annotates()) {\n            out.annotate(0, indexString() + ' ' + descriptor.toHuman());\n            out.annotate(4, \"  descriptor_idx: \" + Hex.u4(idx));\n        }\n\n        out.writeInt(idx);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/TypeIdsSection.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.DexFormat;\nimport com.taobao.android.dex.DexIndexOverflowException;\nimport com.taobao.android.dx.command.dexer.Main;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\n\nimport java.util.Collection;\nimport java.util.TreeMap;\n\n/**\n * Type identifiers list section of a {@code .dex} file.\n */\npublic final class TypeIdsSection extends UniformItemSection {\n    /**\n     * {@code non-null;} map from types to {@link TypeIdItem} instances\n     */\n    private final TreeMap<Type, TypeIdItem> typeIds;\n\n    /**\n     * Constructs an instance. The file offset is initially unknown.\n     *\n     * @param file {@code non-null;} file that this instance is part of\n     */\n    public TypeIdsSection(DexFile file) {\n        super(\"type_ids\", file, 4);\n\n        typeIds = new TreeMap<Type, TypeIdItem>();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Collection<? extends Item> items() {\n        return typeIds.values();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public IndexedItem get(Constant cst) {\n        if (cst == null) {\n            throw new NullPointerException(\"cst == null\");\n        }\n\n        throwIfNotPrepared();\n\n        Type type = ((CstType) cst).getClassType();\n        IndexedItem result = typeIds.get(type);\n\n        if (result == null) {\n            throw new IllegalArgumentException(\"not found: \" + cst);\n        }\n\n        return result;\n    }\n\n    /**\n     * Writes the portion of the file header that refers to this instance.\n     *\n     * @param out {@code non-null;} where to write\n     */\n    public void writeHeaderPart(AnnotatedOutput out) {\n        throwIfNotPrepared();\n\n        int sz = typeIds.size();\n        int offset = (sz == 0) ? 0 : getFileOffset();\n\n        if (sz > DexFormat.MAX_TYPE_IDX + 1) {\n            throw new DexIndexOverflowException(\"Too many type references: \" + sz +\n                    \"; max is \" + (DexFormat.MAX_TYPE_IDX + 1) + \".\\n\" +\n                    new Main().getTooManyIdsErrorMessage());\n        }\n\n        if (out.annotates()) {\n            out.annotate(4, \"type_ids_size:   \" + Hex.u4(sz));\n            out.annotate(4, \"type_ids_off:    \" + Hex.u4(offset));\n        }\n\n        out.writeInt(sz);\n        out.writeInt(offset);\n    }\n\n    /**\n     * Interns an element into this instance.\n     *\n     * @param type {@code non-null;} the type to intern\n     * @return {@code non-null;} the interned reference\n     */\n    public synchronized TypeIdItem intern(Type type) {\n        if (type == null) {\n            throw new NullPointerException(\"type == null\");\n        }\n\n        throwIfPrepared();\n\n        TypeIdItem result = typeIds.get(type);\n\n        if (result == null) {\n            result = new TypeIdItem(new CstType(type));\n            typeIds.put(type, result);\n        }\n\n        return result;\n    }\n\n    /**\n     * Interns an element into this instance.\n     *\n     * @param type {@code non-null;} the type to intern\n     * @return {@code non-null;} the interned reference\n     */\n    public synchronized TypeIdItem intern(CstType type) {\n        if (type == null) {\n            throw new NullPointerException(\"type == null\");\n        }\n\n        throwIfPrepared();\n\n        Type typePerSe = type.getClassType();\n        TypeIdItem result = typeIds.get(typePerSe);\n\n        if (result == null) {\n            result = new TypeIdItem(type);\n            typeIds.put(typePerSe, result);\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets the index of the given type, which must have\n     * been added to this instance.\n     *\n     * @param type {@code non-null;} the type to look up\n     * @return {@code >= 0;} the reference's index\n     */\n    public int indexOf(Type type) {\n        if (type == null) {\n            throw new NullPointerException(\"type == null\");\n        }\n\n        throwIfNotPrepared();\n\n        TypeIdItem item = typeIds.get(type);\n\n        if (item == null) {\n            throw new IllegalArgumentException(\"not found: \" + type);\n        }\n\n        return item.getIndex();\n    }\n\n    /**\n     * Gets the index of the given type, which must have\n     * been added to this instance.\n     *\n     * @param type {@code non-null;} the type to look up\n     * @return {@code >= 0;} the reference's index\n     */\n    public int indexOf(CstType type) {\n        if (type == null) {\n            throw new NullPointerException(\"type == null\");\n        }\n\n        return indexOf(type.getClassType());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void orderItems() {\n        int idx = 0;\n\n        for (Object i : items()) {\n            ((TypeIdItem) i).setIndex(idx);\n            idx++;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/TypeListItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Representation of a list of class references.\n */\npublic final class TypeListItem extends OffsettedItem {\n    /** alignment requirement */\n    private static final int ALIGNMENT = 4;\n\n    /** element size in bytes */\n    private static final int ELEMENT_SIZE = 2;\n\n    /** header size in bytes */\n    private static final int HEADER_SIZE = 4;\n\n    /** {@code non-null;} the actual list */\n    private final TypeList list;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param list {@code non-null;} the actual list\n     */\n    public TypeListItem(TypeList list) {\n        super(ALIGNMENT, (list.size() * ELEMENT_SIZE) + HEADER_SIZE);\n\n        this.list = list;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return StdTypeList.hashContents(list);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return ItemType.TYPE_TYPE_LIST;\n    }\n\n    /** {@inheritDoc} */\n    public void addContents(DexFile file) {\n        TypeIdsSection typeIds = file.getTypeIds();\n        int sz = list.size();\n\n        for (int i = 0; i < sz; i++) {\n            typeIds.intern(list.getType(i));\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toHuman() {\n        throw new RuntimeException(\"unsupported\");\n    }\n\n    /**\n     * Gets the underlying list.\n     *\n     * @return {@code non-null;} the list\n     */\n    public TypeList getList() {\n        return list;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void writeTo0(DexFile file, AnnotatedOutput out) {\n        TypeIdsSection typeIds = file.getTypeIds();\n        int sz = list.size();\n\n        if (out.annotates()) {\n            out.annotate(0, offsetString() + \" type_list\");\n            out.annotate(HEADER_SIZE, \"  size: \" + Hex.u4(sz));\n            for (int i = 0; i < sz; i++) {\n                Type one = list.getType(i);\n                int idx = typeIds.indexOf(one);\n                out.annotate(ELEMENT_SIZE,\n                             \"  \" + Hex.u2(idx) + \" // \" + one.toHuman());\n            }\n        }\n\n        out.writeInt(sz);\n\n        for (int i = 0; i < sz; i++) {\n            out.writeShort(typeIds.indexOf(list.getType(i)));\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int compareTo0(OffsettedItem other) {\n        TypeList thisList = this.list;\n        TypeList otherList = ((TypeListItem) other).list;\n\n        return StdTypeList.compareContents(thisList, otherList);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/UniformItemSection.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport java.util.Collection;\n\n/**\n * A section of a {@code .dex} file which consists of a sequence of\n * {@link Item} objects. Each of the items must have the same size in\n * the output.\n */\npublic abstract class UniformItemSection extends Section {\n    /**\n     * Constructs an instance. The file offset is initially unknown.\n     *\n     * @param name {@code null-ok;} the name of this instance, for annotation\n     * purposes\n     * @param file {@code non-null;} file that this instance is part of\n     * @param alignment {@code > 0;} alignment requirement for the final output;\n     * must be a power of 2\n     */\n    public UniformItemSection(String name, DexFile file, int alignment) {\n        super(name, file, alignment);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final int writeSize() {\n        Collection<? extends Item> items = items();\n        int sz = items.size();\n\n        if (sz == 0) {\n            return 0;\n        }\n\n        // Since each item has to be the same size, we can pick any.\n        return sz * items.iterator().next().writeSize();\n    }\n\n    /**\n     * Gets the item corresponding to the given {@link Constant}. This\n     * will throw an exception if the constant is not found, including\n     * if this instance isn't the sort that maps constants to {@link\n     * IndexedItem} instances.\n     *\n     * @param cst {@code non-null;} constant to look for\n     * @return {@code non-null;} the corresponding item found in this instance\n     */\n    public abstract IndexedItem get(Constant cst);\n\n    /** {@inheritDoc} */\n    @Override\n    protected final void prepare0() {\n        DexFile file = getFile();\n\n        orderItems();\n\n        for (Item one : items()) {\n            one.addContents(file);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected final void writeTo0(AnnotatedOutput out) {\n        DexFile file = getFile();\n        int alignment = getAlignment();\n\n        for (Item one : items()) {\n            one.writeTo(file, out);\n            out.alignTo(alignment);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final int getAbsoluteItemOffset(Item item) {\n        /*\n         * Since all items must be the same size, we can use the size\n         * of the one we're given to calculate its offset.\n         */\n        IndexedItem ii = (IndexedItem) item;\n        int relativeOffset = ii.getIndex() * ii.writeSize();\n\n        return getAbsoluteOffset(relativeOffset);\n    }\n\n    /**\n     * Alters or picks the order for items in this instance if desired,\n     * so that subsequent calls to {@link #items} will yield a\n     * so-ordered collection. If the items in this instance are indexed,\n     * then this method should also assign indices.\n     */\n    protected abstract void orderItems();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/UniformListItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.List;\n\n/**\n * Class that represents a contiguous list of uniform items. Each\n * item in the list, in particular, must have the same write size and\n * alignment.\n *\n * <p>This class inherits its alignment from its items, bumped up to\n * {@code 4} if the items have a looser alignment requirement. If\n * it is more than {@code 4}, then there will be a gap after the\n * output list size (which is four bytes) and before the first item.</p>\n *\n * @param <T> type of element contained in an instance\n */\npublic final class UniformListItem<T extends OffsettedItem>\n        extends OffsettedItem {\n    /** the size of the list header */\n    private static final int HEADER_SIZE = 4;\n\n    /** {@code non-null;} the item type */\n    private final ItemType itemType;\n\n    /** {@code non-null;} the contents */\n    private final List<T> items;\n\n    /**\n     * Constructs an instance. It is illegal to modify the given list once\n     * it is used to construct an instance of this class.\n     *\n     * @param itemType {@code non-null;} the type of the item\n     * @param items {@code non-null and non-empty;} list of items to represent\n     */\n    public UniformListItem(ItemType itemType, List<T> items) {\n        super(getAlignment(items), writeSize(items));\n\n        if (itemType == null) {\n            throw new NullPointerException(\"itemType == null\");\n        }\n\n        this.items = items;\n        this.itemType = itemType;\n    }\n\n    /**\n     * Helper for {@link #UniformListItem}, which returns the alignment\n     * requirement implied by the given list. See the header comment for\n     * more details.\n     *\n     * @param items {@code non-null;} list of items being represented\n     * @return {@code >= 4;} the alignment requirement\n     */\n    private static int getAlignment(List<? extends OffsettedItem> items) {\n        try {\n            // Since they all must have the same alignment, any one will do.\n            return Math.max(HEADER_SIZE, items.get(0).getAlignment());\n        } catch (IndexOutOfBoundsException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"items.size() == 0\");\n        } catch (NullPointerException ex) {\n            // Translate the exception.\n            throw new NullPointerException(\"items == null\");\n        }\n    }\n\n    /**\n     * Calculates the write size for the given list.\n     *\n     * @param items {@code non-null;} the list in question\n     * @return {@code >= 0;} the write size\n     */\n    private static int writeSize(List<? extends OffsettedItem> items) {\n        /*\n         * This class assumes all included items are the same size,\n         * an assumption which is verified in place0().\n         */\n        OffsettedItem first = items.get(0);\n        return (items.size() * first.writeSize()) + getAlignment(items);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public ItemType itemType() {\n        return itemType;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        StringBuffer sb = new StringBuffer(100);\n\n        sb.append(getClass().getName());\n        sb.append(items);\n\n        return sb.toString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addContents(DexFile file) {\n        for (OffsettedItem i : items) {\n            i.addContents(file);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final String toHuman() {\n        StringBuffer sb = new StringBuffer(100);\n        boolean first = true;\n\n        sb.append(\"{\");\n\n        for (OffsettedItem i : items) {\n            if (first) {\n                first = false;\n            } else {\n                sb.append(\", \");\n            }\n            sb.append(i.toHuman());\n        }\n\n        sb.append(\"}\");\n        return sb.toString();\n    }\n\n    /**\n     * Gets the underlying list of items.\n     *\n     * @return {@code non-null;} the list\n     */\n    public final List<T> getItems() {\n        return items;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void place0(Section addedTo, int offset) {\n        offset += headerSize();\n\n        boolean first = true;\n        int theSize = -1;\n        int theAlignment = -1;\n\n        for (OffsettedItem i : items) {\n            int size = i.writeSize();\n            if (first) {\n                theSize = size;\n                theAlignment = i.getAlignment();\n                first = false;\n            } else {\n                if (size != theSize) {\n                    throw new UnsupportedOperationException(\n                            \"item size mismatch\");\n                }\n                if (i.getAlignment() != theAlignment) {\n                    throw new UnsupportedOperationException(\n                            \"item alignment mismatch\");\n                }\n            }\n\n            offset = i.place(addedTo, offset) + size;\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected void writeTo0(DexFile file, AnnotatedOutput out) {\n        int size = items.size();\n\n        if (out.annotates()) {\n            out.annotate(0, offsetString() + \" \" + typeName());\n            out.annotate(4, \"  size: \" + Hex.u4(size));\n        }\n\n        out.writeInt(size);\n\n        for (OffsettedItem i : items) {\n            i.writeTo(file, out);\n        }\n    }\n\n    /**\n     * Get the size of the header of this list.\n     *\n     * @return {@code >= 0;} the header size\n     */\n    private int headerSize() {\n        /*\n         * Because of how this instance was set up, this is the same\n         * as the alignment.\n         */\n        return getAlignment();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/dex/file/ValueEncoder.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.dex.file;\n\nimport com.taobao.android.dex.EncodedValueCodec;\nimport com.taobao.android.dx.rop.annotation.Annotation;\nimport com.taobao.android.dx.rop.annotation.NameValuePair;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstAnnotation;\nimport com.taobao.android.dx.rop.cst.CstArray;\nimport com.taobao.android.dx.rop.cst.CstBoolean;\nimport com.taobao.android.dx.rop.cst.CstByte;\nimport com.taobao.android.dx.rop.cst.CstChar;\nimport com.taobao.android.dx.rop.cst.CstDouble;\nimport com.taobao.android.dx.rop.cst.CstEnumRef;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.rop.cst.CstFloat;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.cst.CstKnownNull;\nimport com.taobao.android.dx.rop.cst.CstLiteralBits;\nimport com.taobao.android.dx.rop.cst.CstLong;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstShort;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.util.AnnotatedOutput;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.Collection;\n\n/**\n * Handler for writing out {@code encoded_values} and parts\n * thereof.\n */\npublic final class ValueEncoder {\n    /** annotation value type constant: {@code byte} */\n    private static final int VALUE_BYTE = 0x00;\n\n    /** annotation value type constant: {@code short} */\n    private static final int VALUE_SHORT = 0x02;\n\n    /** annotation value type constant: {@code char} */\n    private static final int VALUE_CHAR = 0x03;\n\n    /** annotation value type constant: {@code int} */\n    private static final int VALUE_INT = 0x04;\n\n    /** annotation value type constant: {@code long} */\n    private static final int VALUE_LONG = 0x06;\n\n    /** annotation value type constant: {@code float} */\n    private static final int VALUE_FLOAT = 0x10;\n\n    /** annotation value type constant: {@code double} */\n    private static final int VALUE_DOUBLE = 0x11;\n\n    /** annotation value type constant: {@code string} */\n    private static final int VALUE_STRING = 0x17;\n\n    /** annotation value type constant: {@code type} */\n    private static final int VALUE_TYPE = 0x18;\n\n    /** annotation value type constant: {@code field} */\n    private static final int VALUE_FIELD = 0x19;\n\n    /** annotation value type constant: {@code method} */\n    private static final int VALUE_METHOD = 0x1a;\n\n    /** annotation value type constant: {@code enum} */\n    private static final int VALUE_ENUM = 0x1b;\n\n    /** annotation value type constant: {@code array} */\n    private static final int VALUE_ARRAY = 0x1c;\n\n    /** annotation value type constant: {@code annotation} */\n    private static final int VALUE_ANNOTATION = 0x1d;\n\n    /** annotation value type constant: {@code null} */\n    private static final int VALUE_NULL = 0x1e;\n\n    /** annotation value type constant: {@code boolean} */\n    private static final int VALUE_BOOLEAN = 0x1f;\n\n    /** {@code non-null;} file being written */\n    private final DexFile file;\n\n    /** {@code non-null;} output stream to write to */\n    private final AnnotatedOutput out;\n\n    /**\n     * Construct an instance.\n     *\n     * @param file {@code non-null;} file being written\n     * @param out {@code non-null;} output stream to write to\n     */\n    public ValueEncoder(DexFile file, AnnotatedOutput out) {\n        if (file == null) {\n            throw new NullPointerException(\"file == null\");\n        }\n\n        if (out == null) {\n            throw new NullPointerException(\"out == null\");\n        }\n\n        this.file = file;\n        this.out = out;\n    }\n\n    /**\n     * Writes out the encoded form of the given constant.\n     *\n     * @param cst {@code non-null;} the constant to write\n     */\n    public void writeConstant(Constant cst) {\n        int type = constantToValueType(cst);\n        int arg;\n\n        switch (type) {\n            case VALUE_BYTE:\n            case VALUE_SHORT:\n            case VALUE_INT:\n            case VALUE_LONG: {\n                long value = ((CstLiteralBits) cst).getLongBits();\n                EncodedValueCodec.writeSignedIntegralValue(out, type, value);\n                break;\n            }\n            case VALUE_CHAR: {\n                long value = ((CstLiteralBits) cst).getLongBits();\n                EncodedValueCodec.writeUnsignedIntegralValue(out, type, value);\n                break;\n            }\n            case VALUE_FLOAT: {\n                // Shift value left 32 so that right-zero-extension works.\n                long value = ((CstFloat) cst).getLongBits() << 32;\n                EncodedValueCodec.writeRightZeroExtendedValue(out, type, value);\n                break;\n            }\n            case VALUE_DOUBLE: {\n                long value = ((CstDouble) cst).getLongBits();\n                EncodedValueCodec.writeRightZeroExtendedValue(out, type, value);\n                break;\n            }\n            case VALUE_STRING: {\n                int index = file.getStringIds().indexOf((CstString) cst);\n                EncodedValueCodec.writeUnsignedIntegralValue(out, type, (long) index);\n                break;\n            }\n            case VALUE_TYPE: {\n                int index = file.getTypeIds().indexOf((CstType) cst);\n                EncodedValueCodec.writeUnsignedIntegralValue(out, type, (long) index);\n                break;\n            }\n            case VALUE_FIELD: {\n                int index = file.getFieldIds().indexOf((CstFieldRef) cst);\n                EncodedValueCodec.writeUnsignedIntegralValue(out, type, (long) index);\n                break;\n            }\n            case VALUE_METHOD: {\n                int index = file.getMethodIds().indexOf((CstMethodRef) cst);\n                EncodedValueCodec.writeUnsignedIntegralValue(out, type, (long) index);\n                break;\n            }\n            case VALUE_ENUM: {\n                CstFieldRef fieldRef = ((CstEnumRef) cst).getFieldRef();\n                int index = file.getFieldIds().indexOf(fieldRef);\n                EncodedValueCodec.writeUnsignedIntegralValue(out, type, (long) index);\n                break;\n            }\n            case VALUE_ARRAY: {\n                out.writeByte(type);\n                writeArray((CstArray) cst, false);\n                break;\n            }\n            case VALUE_ANNOTATION: {\n                out.writeByte(type);\n                writeAnnotation(((CstAnnotation) cst).getAnnotation(),\n                        false);\n                break;\n            }\n            case VALUE_NULL: {\n                out.writeByte(type);\n                break;\n            }\n            case VALUE_BOOLEAN: {\n                int value = ((CstBoolean) cst).getIntBits();\n                out.writeByte(type | (value << 5));\n                break;\n            }\n            default: {\n                throw new RuntimeException(\"Shouldn't happen\");\n            }\n        }\n    }\n\n    /**\n     * Gets the value type for the given constant.\n     *\n     * @param cst {@code non-null;} the constant\n     * @return the value type; one of the {@code VALUE_*} constants\n     * defined by this class\n     */\n    private static int constantToValueType(Constant cst) {\n        /*\n         * TODO: Constant should probable have an associated enum, so this\n         * can be a switch().\n         */\n        if (cst instanceof CstByte) {\n            return VALUE_BYTE;\n        } else if (cst instanceof CstShort) {\n            return VALUE_SHORT;\n        } else if (cst instanceof CstChar) {\n            return VALUE_CHAR;\n        } else if (cst instanceof CstInteger) {\n            return VALUE_INT;\n        } else if (cst instanceof CstLong) {\n            return VALUE_LONG;\n        } else if (cst instanceof CstFloat) {\n            return VALUE_FLOAT;\n        } else if (cst instanceof CstDouble) {\n            return VALUE_DOUBLE;\n        } else if (cst instanceof CstString) {\n            return VALUE_STRING;\n        } else if (cst instanceof CstType) {\n            return VALUE_TYPE;\n        } else if (cst instanceof CstFieldRef) {\n            return VALUE_FIELD;\n        } else if (cst instanceof CstMethodRef) {\n            return VALUE_METHOD;\n        } else if (cst instanceof CstEnumRef) {\n            return VALUE_ENUM;\n        } else if (cst instanceof CstArray) {\n            return VALUE_ARRAY;\n        } else if (cst instanceof CstAnnotation) {\n            return VALUE_ANNOTATION;\n        } else if (cst instanceof CstKnownNull) {\n            return VALUE_NULL;\n        } else if (cst instanceof CstBoolean) {\n            return VALUE_BOOLEAN;\n        } else {\n            throw new RuntimeException(\"Shouldn't happen\");\n        }\n    }\n\n    /**\n     * Writes out the encoded form of the given array, that is, as\n     * an {@code encoded_array} and not including a\n     * {@code value_type} prefix. If the output stream keeps\n     * (debugging) annotations and {@code topLevel} is\n     * {@code true}, then this method will write (debugging)\n     * annotations.\n     *\n     * @param array {@code non-null;} array instance to write\n     * @param topLevel {@code true} iff the given annotation is the\n     * top-level annotation or {@code false} if it is a sub-annotation\n     * of some other annotation\n     */\n    public void writeArray(CstArray array, boolean topLevel) {\n        boolean annotates = topLevel && out.annotates();\n        CstArray.List list = ((CstArray) array).getList();\n        int size = list.size();\n\n        if (annotates) {\n            out.annotate(\"  size: \" + Hex.u4(size));\n        }\n\n        out.writeUleb128(size);\n\n        for (int i = 0; i < size; i++) {\n            Constant cst = list.get(i);\n            if (annotates) {\n                out.annotate(\"  [\" + Integer.toHexString(i) + \"] \" +\n                        constantToHuman(cst));\n            }\n            writeConstant(cst);\n        }\n\n        if (annotates) {\n            out.endAnnotation();\n        }\n    }\n\n    /**\n     * Writes out the encoded form of the given annotation, that is,\n     * as an {@code encoded_annotation} and not including a\n     * {@code value_type} prefix. If the output stream keeps\n     * (debugging) annotations and {@code topLevel} is\n     * {@code true}, then this method will write (debugging)\n     * annotations.\n     *\n     * @param annotation {@code non-null;} annotation instance to write\n     * @param topLevel {@code true} iff the given annotation is the\n     * top-level annotation or {@code false} if it is a sub-annotation\n     * of some other annotation\n     */\n    public void writeAnnotation(Annotation annotation, boolean topLevel) {\n        boolean annotates = topLevel && out.annotates();\n        StringIdsSection stringIds = file.getStringIds();\n        TypeIdsSection typeIds = file.getTypeIds();\n\n        CstType type = annotation.getType();\n        int typeIdx = typeIds.indexOf(type);\n\n        if (annotates) {\n            out.annotate(\"  type_idx: \" + Hex.u4(typeIdx) + \" // \" +\n                    type.toHuman());\n        }\n\n        out.writeUleb128(typeIds.indexOf(annotation.getType()));\n\n        Collection<NameValuePair> pairs = annotation.getNameValuePairs();\n        int size = pairs.size();\n\n        if (annotates) {\n            out.annotate(\"  size: \" + Hex.u4(size));\n        }\n\n        out.writeUleb128(size);\n\n        int at = 0;\n        for (NameValuePair pair : pairs) {\n            CstString name = pair.getName();\n            int nameIdx = stringIds.indexOf(name);\n            Constant value = pair.getValue();\n\n            if (annotates) {\n                out.annotate(0, \"  elements[\" + at + \"]:\");\n                at++;\n                out.annotate(\"    name_idx: \" + Hex.u4(nameIdx) + \" // \" +\n                        name.toHuman());\n            }\n\n            out.writeUleb128(nameIdx);\n\n            if (annotates) {\n                out.annotate(\"    value: \" + constantToHuman(value));\n            }\n\n            writeConstant(value);\n        }\n\n        if (annotates) {\n            out.endAnnotation();\n        }\n    }\n\n    /**\n     * Gets the colloquial type name and human form of the type of the\n     * given constant, when used as an encoded value.\n     *\n     * @param cst {@code non-null;} the constant\n     * @return {@code non-null;} its type name and human form\n     */\n    public static String constantToHuman(Constant cst) {\n        int type = constantToValueType(cst);\n\n        if (type == VALUE_NULL) {\n            return \"null\";\n        }\n\n        StringBuilder sb = new StringBuilder();\n\n        sb.append(cst.typeName());\n        sb.append(' ');\n        sb.append(cst.toHuman());\n\n        return sb.toString();\n    }\n\n    /**\n     * Helper for {@code addContents()} methods, which adds\n     * contents for a particular {@link Annotation}, calling itself\n     * recursively should it encounter a nested annotation.\n     *\n     * @param file {@code non-null;} the file to add to\n     * @param annotation {@code non-null;} the annotation to add contents for\n     */\n    public static void addContents(DexFile file, Annotation annotation) {\n        TypeIdsSection typeIds = file.getTypeIds();\n        StringIdsSection stringIds = file.getStringIds();\n\n        typeIds.intern(annotation.getType());\n\n        for (NameValuePair pair : annotation.getNameValuePairs()) {\n            stringIds.intern(pair.getName());\n            addContents(file, pair.getValue());\n        }\n    }\n\n    /**\n     * Helper for {@code addContents()} methods, which adds\n     * contents for a particular constant, calling itself recursively\n     * should it encounter a {@link CstArray} and calling {@link\n     * #addContents(DexFile,Annotation)} recursively should it\n     * encounter a {@link CstAnnotation}.\n     *\n     * @param file {@code non-null;} the file to add to\n     * @param cst {@code non-null;} the constant to add contents for\n     */\n    public static void addContents(DexFile file, Constant cst) {\n        if (cst instanceof CstAnnotation) {\n            addContents(file, ((CstAnnotation) cst).getAnnotation());\n        } else if (cst instanceof CstArray) {\n            CstArray.List list = ((CstArray) cst).getList();\n            int size = list.size();\n            for (int i = 0; i < size; i++) {\n                addContents(file, list.get(i));\n            }\n        } else {\n            file.internIfAppropriate(cst);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/CodeReader.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io;\n\nimport com.taobao.android.dex.DexException;\nimport com.taobao.android.dx.io.instructions.DecodedInstruction;\n\n/**\n * Walks through a block of code and calls visitor call backs.\n */\npublic final class CodeReader {\n    private Visitor fallbackVisitor = null;\n    private Visitor stringVisitor = null;\n    private Visitor typeVisitor = null;\n    private Visitor fieldVisitor = null;\n    private Visitor methodVisitor = null;\n\n    /**\n     * Sets {@code visitor} as the visitor for all instructions.\n     */\n    public void setAllVisitors(Visitor visitor) {\n        fallbackVisitor = visitor;\n        stringVisitor = visitor;\n        typeVisitor = visitor;\n        fieldVisitor = visitor;\n        methodVisitor = visitor;\n    }\n\n    /**\n     * Sets {@code visitor} as the visitor for all instructions not\n     * otherwise handled.\n     */\n    public void setFallbackVisitor(Visitor visitor) {\n        fallbackVisitor = visitor;\n    }\n\n    /**\n     * Sets {@code visitor} as the visitor for all string instructions.\n     */\n    public void setStringVisitor(Visitor visitor) {\n        stringVisitor = visitor;\n    }\n\n    /**\n     * Sets {@code visitor} as the visitor for all type instructions.\n     */\n    public void setTypeVisitor(Visitor visitor) {\n        typeVisitor = visitor;\n    }\n\n    /**\n     * Sets {@code visitor} as the visitor for all field instructions.\n     */\n    public void setFieldVisitor(Visitor visitor) {\n        fieldVisitor = visitor;\n    }\n\n    /**\n     * Sets {@code visitor} as the visitor for all method instructions.\n     */\n    public void setMethodVisitor(Visitor visitor) {\n        methodVisitor = visitor;\n    }\n\n    public void visitAll(DecodedInstruction[] decodedInstructions)\n            throws DexException {\n        int size = decodedInstructions.length;\n\n        for (int i = 0; i < size; i++) {\n            DecodedInstruction one = decodedInstructions[i];\n            if (one == null) {\n                continue;\n            }\n\n            callVisit(decodedInstructions, one);\n        }\n    }\n\n    public void visitAll(short[] encodedInstructions) throws DexException {\n        DecodedInstruction[] decodedInstructions =\n            DecodedInstruction.decodeAll(encodedInstructions);\n        visitAll(decodedInstructions);\n    }\n\n    private void callVisit(DecodedInstruction[] all, DecodedInstruction one) {\n        Visitor visitor = null;\n\n        switch (OpcodeInfo.getIndexType(one.getOpcode())) {\n            case STRING_REF: visitor = stringVisitor; break;\n            case TYPE_REF:   visitor = typeVisitor;   break;\n            case FIELD_REF:  visitor = fieldVisitor;  break;\n            case METHOD_REF: visitor = methodVisitor; break;\n        }\n\n        if (visitor == null) {\n            visitor = fallbackVisitor;\n        }\n\n        if (visitor != null) {\n            visitor.visit(all, one);\n        }\n    }\n\n    public interface Visitor {\n        void visit(DecodedInstruction[] all, DecodedInstruction one);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/DexIndexPrinter.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io;\n\nimport com.taobao.android.dex.ClassDef;\nimport com.taobao.android.dex.Dex;\nimport com.taobao.android.dex.FieldId;\nimport com.taobao.android.dex.MethodId;\nimport com.taobao.android.dex.ProtoId;\nimport com.taobao.android.dex.TableOfContents;\nimport java.io.File;\nimport java.io.IOException;\n\n/**\n * Executable that prints all indices of a dex file.\n */\npublic final class DexIndexPrinter {\n    private final Dex dex;\n    private final TableOfContents tableOfContents;\n\n    public DexIndexPrinter(File file) throws IOException {\n        this.dex = new Dex(file);\n        this.tableOfContents = dex.getTableOfContents();\n    }\n\n    private void printMap() {\n        for (TableOfContents.Section section : tableOfContents.sections) {\n            if (section.off != -1) {\n                System.out.println(\"section \" + Integer.toHexString(section.type)\n                        + \" off=\" + Integer.toHexString(section.off)\n                        + \" size=\" + Integer.toHexString(section.size)\n                        + \" byteCount=\" + Integer.toHexString(section.byteCount));\n            }\n        }\n    }\n\n    private void printStrings() throws IOException {\n        int index = 0;\n        for (String string : dex.strings()) {\n            System.out.println(\"string \" + index + \": \" + string);\n            index++;\n        }\n    }\n\n    private void printTypeIds() throws IOException {\n        int index = 0;\n        for (Integer type : dex.typeIds()) {\n            System.out.println(\"type \" + index + \": \" + dex.strings().get(type));\n            index++;\n        }\n    }\n\n    private void printProtoIds() throws IOException {\n        int index = 0;\n        for (ProtoId protoId : dex.protoIds()) {\n            System.out.println(\"proto \" + index + \": \" + protoId);\n            index++;\n        }\n    }\n\n    private void printFieldIds() throws IOException {\n        int index = 0;\n        for (FieldId fieldId : dex.fieldIds()) {\n            System.out.println(\"field \" + index + \": \" + fieldId);\n            index++;\n        }\n    }\n\n    private void printMethodIds() throws IOException {\n        int index = 0;\n        for (MethodId methodId : dex.methodIds()) {\n            System.out.println(\"methodId \" + index + \": \" + methodId);\n            index++;\n        }\n    }\n\n    private void printTypeLists() throws IOException {\n        if (tableOfContents.typeLists.off == -1) {\n            System.out.println(\"No type lists\");\n            return;\n        }\n        Dex.Section in = dex.open(tableOfContents.typeLists.off);\n        for (int i = 0; i < tableOfContents.typeLists.size; i++) {\n            int size = in.readInt();\n            System.out.print(\"Type list i=\" + i + \", size=\" + size + \", elements=\");\n            for (int t = 0; t < size; t++) {\n                System.out.print(\" \" + dex.typeNames().get((int) in.readShort()));\n            }\n            if (size % 2 == 1) {\n                in.readShort(); // retain alignment\n            }\n            System.out.println();\n        }\n    }\n\n    private void printClassDefs() {\n        int index = 0;\n        for (ClassDef classDef : dex.classDefs()) {\n            System.out.println(\"class def \" + index + \": \" + classDef);\n            index++;\n        }\n    }\n\n    public static void main(String[] args) throws IOException {\n        DexIndexPrinter indexPrinter = new DexIndexPrinter(new File(args[0]));\n        indexPrinter.printMap();\n        indexPrinter.printStrings();\n        indexPrinter.printTypeIds();\n        indexPrinter.printProtoIds();\n        indexPrinter.printFieldIds();\n        indexPrinter.printMethodIds();\n        indexPrinter.printTypeLists();\n        indexPrinter.printClassDefs();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/IndexType.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io;\n\n/**\n * The various types that an index in a Dalvik instruction might refer to.\n */\npublic enum IndexType {\n    /** \"Unknown.\" Used for undefined opcodes. */\n    UNKNOWN,\n\n    /** no index used */\n    NONE,\n\n    /** \"It depends.\" Used for {@code throw-verification-error}. */\n    VARIES,\n\n    /** type reference index */\n    TYPE_REF,\n\n    /** string reference index */\n    STRING_REF,\n\n    /** method reference index */\n    METHOD_REF,\n\n    /** field reference index */\n    FIELD_REF,\n\n    /** inline method index (for inline linked method invocations) */\n    INLINE_METHOD,\n\n    /** direct vtable offset (for static linked method invocations) */\n    VTABLE_OFFSET,\n\n    /** direct field offset (for static linked field accesses) */\n    FIELD_OFFSET;\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/OpcodeInfo.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io;\n\nimport com.taobao.android.dx.io.instructions.InstructionCodec;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Information about each Dalvik opcode.\n */\npublic final class OpcodeInfo {\n    /*\n     * TODO: Merge at least most of the info from the Dops class into\n     * this one.\n     */\n\n    /** non-null; array containing all the information */\n    private static final Info[] INFO;\n\n    /**\n     * pseudo-opcode used for nonstandard formatted \"instructions\"\n     * (which are mostly not actually instructions, though they do\n     * appear in instruction lists). TODO: Retire the usage of this\n     * constant.\n     */\n    public static final Info SPECIAL_FORMAT =\n        new Info(Opcodes.SPECIAL_FORMAT, \"<special>\",\n                InstructionCodec.FORMAT_00X, IndexType.NONE);\n\n    // TODO: These payload opcodes should be generated by opcode-gen.\n\n    public static final Info PACKED_SWITCH_PAYLOAD =\n        new Info(Opcodes.PACKED_SWITCH_PAYLOAD, \"packed-switch-payload\",\n                InstructionCodec.FORMAT_PACKED_SWITCH_PAYLOAD,\n                IndexType.NONE);\n\n    public static final Info SPARSE_SWITCH_PAYLOAD =\n        new Info(Opcodes.SPARSE_SWITCH_PAYLOAD, \"sparse-switch-payload\",\n                InstructionCodec.FORMAT_SPARSE_SWITCH_PAYLOAD,\n                IndexType.NONE);\n\n    public static final Info FILL_ARRAY_DATA_PAYLOAD =\n        new Info(Opcodes.FILL_ARRAY_DATA_PAYLOAD, \"fill-array-data-payload\",\n                InstructionCodec.FORMAT_FILL_ARRAY_DATA_PAYLOAD,\n                IndexType.NONE);\n\n    // BEGIN(opcode-info-defs); GENERATED AUTOMATICALLY BY opcode-gen\n    public static final Info NOP =\n        new Info(Opcodes.NOP, \"nop\",\n            InstructionCodec.FORMAT_10X, IndexType.NONE);\n\n    public static final Info MOVE =\n        new Info(Opcodes.MOVE, \"move\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info MOVE_FROM16 =\n        new Info(Opcodes.MOVE_FROM16, \"move/from16\",\n            InstructionCodec.FORMAT_22X, IndexType.NONE);\n\n    public static final Info MOVE_16 =\n        new Info(Opcodes.MOVE_16, \"move/16\",\n            InstructionCodec.FORMAT_32X, IndexType.NONE);\n\n    public static final Info MOVE_WIDE =\n        new Info(Opcodes.MOVE_WIDE, \"move-wide\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info MOVE_WIDE_FROM16 =\n        new Info(Opcodes.MOVE_WIDE_FROM16, \"move-wide/from16\",\n            InstructionCodec.FORMAT_22X, IndexType.NONE);\n\n    public static final Info MOVE_WIDE_16 =\n        new Info(Opcodes.MOVE_WIDE_16, \"move-wide/16\",\n            InstructionCodec.FORMAT_32X, IndexType.NONE);\n\n    public static final Info MOVE_OBJECT =\n        new Info(Opcodes.MOVE_OBJECT, \"move-object\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info MOVE_OBJECT_FROM16 =\n        new Info(Opcodes.MOVE_OBJECT_FROM16, \"move-object/from16\",\n            InstructionCodec.FORMAT_22X, IndexType.NONE);\n\n    public static final Info MOVE_OBJECT_16 =\n        new Info(Opcodes.MOVE_OBJECT_16, \"move-object/16\",\n            InstructionCodec.FORMAT_32X, IndexType.NONE);\n\n    public static final Info MOVE_RESULT =\n        new Info(Opcodes.MOVE_RESULT, \"move-result\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info MOVE_RESULT_WIDE =\n        new Info(Opcodes.MOVE_RESULT_WIDE, \"move-result-wide\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info MOVE_RESULT_OBJECT =\n        new Info(Opcodes.MOVE_RESULT_OBJECT, \"move-result-object\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info MOVE_EXCEPTION =\n        new Info(Opcodes.MOVE_EXCEPTION, \"move-exception\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info RETURN_VOID =\n        new Info(Opcodes.RETURN_VOID, \"return-void\",\n            InstructionCodec.FORMAT_10X, IndexType.NONE);\n\n    public static final Info RETURN =\n        new Info(Opcodes.RETURN, \"return\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info RETURN_WIDE =\n        new Info(Opcodes.RETURN_WIDE, \"return-wide\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info RETURN_OBJECT =\n        new Info(Opcodes.RETURN_OBJECT, \"return-object\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info CONST_4 =\n        new Info(Opcodes.CONST_4, \"const/4\",\n            InstructionCodec.FORMAT_11N, IndexType.NONE);\n\n    public static final Info CONST_16 =\n        new Info(Opcodes.CONST_16, \"const/16\",\n            InstructionCodec.FORMAT_21S, IndexType.NONE);\n\n    public static final Info CONST =\n        new Info(Opcodes.CONST, \"const\",\n            InstructionCodec.FORMAT_31I, IndexType.NONE);\n\n    public static final Info CONST_HIGH16 =\n        new Info(Opcodes.CONST_HIGH16, \"const/high16\",\n            InstructionCodec.FORMAT_21H, IndexType.NONE);\n\n    public static final Info CONST_WIDE_16 =\n        new Info(Opcodes.CONST_WIDE_16, \"const-wide/16\",\n            InstructionCodec.FORMAT_21S, IndexType.NONE);\n\n    public static final Info CONST_WIDE_32 =\n        new Info(Opcodes.CONST_WIDE_32, \"const-wide/32\",\n            InstructionCodec.FORMAT_31I, IndexType.NONE);\n\n    public static final Info CONST_WIDE =\n        new Info(Opcodes.CONST_WIDE, \"const-wide\",\n            InstructionCodec.FORMAT_51L, IndexType.NONE);\n\n    public static final Info CONST_WIDE_HIGH16 =\n        new Info(Opcodes.CONST_WIDE_HIGH16, \"const-wide/high16\",\n            InstructionCodec.FORMAT_21H, IndexType.NONE);\n\n    public static final Info CONST_STRING =\n        new Info(Opcodes.CONST_STRING, \"const-string\",\n            InstructionCodec.FORMAT_21C, IndexType.STRING_REF);\n\n    public static final Info CONST_STRING_JUMBO =\n        new Info(Opcodes.CONST_STRING_JUMBO, \"const-string/jumbo\",\n            InstructionCodec.FORMAT_31C, IndexType.STRING_REF);\n\n    public static final Info CONST_CLASS =\n        new Info(Opcodes.CONST_CLASS, \"const-class\",\n            InstructionCodec.FORMAT_21C, IndexType.TYPE_REF);\n\n    public static final Info MONITOR_ENTER =\n        new Info(Opcodes.MONITOR_ENTER, \"monitor-enter\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info MONITOR_EXIT =\n        new Info(Opcodes.MONITOR_EXIT, \"monitor-exit\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info CHECK_CAST =\n        new Info(Opcodes.CHECK_CAST, \"check-cast\",\n            InstructionCodec.FORMAT_21C, IndexType.TYPE_REF);\n\n    public static final Info INSTANCE_OF =\n        new Info(Opcodes.INSTANCE_OF, \"instance-of\",\n            InstructionCodec.FORMAT_22C, IndexType.TYPE_REF);\n\n    public static final Info ARRAY_LENGTH =\n        new Info(Opcodes.ARRAY_LENGTH, \"array-length\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info NEW_INSTANCE =\n        new Info(Opcodes.NEW_INSTANCE, \"new-instance\",\n            InstructionCodec.FORMAT_21C, IndexType.TYPE_REF);\n\n    public static final Info NEW_ARRAY =\n        new Info(Opcodes.NEW_ARRAY, \"new-array\",\n            InstructionCodec.FORMAT_22C, IndexType.TYPE_REF);\n\n    public static final Info FILLED_NEW_ARRAY =\n        new Info(Opcodes.FILLED_NEW_ARRAY, \"filled-new-array\",\n            InstructionCodec.FORMAT_35C, IndexType.TYPE_REF);\n\n    public static final Info FILLED_NEW_ARRAY_RANGE =\n        new Info(Opcodes.FILLED_NEW_ARRAY_RANGE, \"filled-new-array/range\",\n            InstructionCodec.FORMAT_3RC, IndexType.TYPE_REF);\n\n    public static final Info FILL_ARRAY_DATA =\n        new Info(Opcodes.FILL_ARRAY_DATA, \"fill-array-data\",\n            InstructionCodec.FORMAT_31T, IndexType.NONE);\n\n    public static final Info THROW =\n        new Info(Opcodes.THROW, \"throw\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info GOTO =\n        new Info(Opcodes.GOTO, \"goto\",\n            InstructionCodec.FORMAT_10T, IndexType.NONE);\n\n    public static final Info GOTO_16 =\n        new Info(Opcodes.GOTO_16, \"goto/16\",\n            InstructionCodec.FORMAT_20T, IndexType.NONE);\n\n    public static final Info GOTO_32 =\n        new Info(Opcodes.GOTO_32, \"goto/32\",\n            InstructionCodec.FORMAT_30T, IndexType.NONE);\n\n    public static final Info PACKED_SWITCH =\n        new Info(Opcodes.PACKED_SWITCH, \"packed-switch\",\n            InstructionCodec.FORMAT_31T, IndexType.NONE);\n\n    public static final Info SPARSE_SWITCH =\n        new Info(Opcodes.SPARSE_SWITCH, \"sparse-switch\",\n            InstructionCodec.FORMAT_31T, IndexType.NONE);\n\n    public static final Info CMPL_FLOAT =\n        new Info(Opcodes.CMPL_FLOAT, \"cmpl-float\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info CMPG_FLOAT =\n        new Info(Opcodes.CMPG_FLOAT, \"cmpg-float\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info CMPL_DOUBLE =\n        new Info(Opcodes.CMPL_DOUBLE, \"cmpl-double\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info CMPG_DOUBLE =\n        new Info(Opcodes.CMPG_DOUBLE, \"cmpg-double\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info CMP_LONG =\n        new Info(Opcodes.CMP_LONG, \"cmp-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info IF_EQ =\n        new Info(Opcodes.IF_EQ, \"if-eq\",\n            InstructionCodec.FORMAT_22T, IndexType.NONE);\n\n    public static final Info IF_NE =\n        new Info(Opcodes.IF_NE, \"if-ne\",\n            InstructionCodec.FORMAT_22T, IndexType.NONE);\n\n    public static final Info IF_LT =\n        new Info(Opcodes.IF_LT, \"if-lt\",\n            InstructionCodec.FORMAT_22T, IndexType.NONE);\n\n    public static final Info IF_GE =\n        new Info(Opcodes.IF_GE, \"if-ge\",\n            InstructionCodec.FORMAT_22T, IndexType.NONE);\n\n    public static final Info IF_GT =\n        new Info(Opcodes.IF_GT, \"if-gt\",\n            InstructionCodec.FORMAT_22T, IndexType.NONE);\n\n    public static final Info IF_LE =\n        new Info(Opcodes.IF_LE, \"if-le\",\n            InstructionCodec.FORMAT_22T, IndexType.NONE);\n\n    public static final Info IF_EQZ =\n        new Info(Opcodes.IF_EQZ, \"if-eqz\",\n            InstructionCodec.FORMAT_21T, IndexType.NONE);\n\n    public static final Info IF_NEZ =\n        new Info(Opcodes.IF_NEZ, \"if-nez\",\n            InstructionCodec.FORMAT_21T, IndexType.NONE);\n\n    public static final Info IF_LTZ =\n        new Info(Opcodes.IF_LTZ, \"if-ltz\",\n            InstructionCodec.FORMAT_21T, IndexType.NONE);\n\n    public static final Info IF_GEZ =\n        new Info(Opcodes.IF_GEZ, \"if-gez\",\n            InstructionCodec.FORMAT_21T, IndexType.NONE);\n\n    public static final Info IF_GTZ =\n        new Info(Opcodes.IF_GTZ, \"if-gtz\",\n            InstructionCodec.FORMAT_21T, IndexType.NONE);\n\n    public static final Info IF_LEZ =\n        new Info(Opcodes.IF_LEZ, \"if-lez\",\n            InstructionCodec.FORMAT_21T, IndexType.NONE);\n\n    public static final Info AGET =\n        new Info(Opcodes.AGET, \"aget\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AGET_WIDE =\n        new Info(Opcodes.AGET_WIDE, \"aget-wide\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AGET_OBJECT =\n        new Info(Opcodes.AGET_OBJECT, \"aget-object\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AGET_BOOLEAN =\n        new Info(Opcodes.AGET_BOOLEAN, \"aget-boolean\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AGET_BYTE =\n        new Info(Opcodes.AGET_BYTE, \"aget-byte\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AGET_CHAR =\n        new Info(Opcodes.AGET_CHAR, \"aget-char\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AGET_SHORT =\n        new Info(Opcodes.AGET_SHORT, \"aget-short\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info APUT =\n        new Info(Opcodes.APUT, \"aput\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info APUT_WIDE =\n        new Info(Opcodes.APUT_WIDE, \"aput-wide\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info APUT_OBJECT =\n        new Info(Opcodes.APUT_OBJECT, \"aput-object\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info APUT_BOOLEAN =\n        new Info(Opcodes.APUT_BOOLEAN, \"aput-boolean\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info APUT_BYTE =\n        new Info(Opcodes.APUT_BYTE, \"aput-byte\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info APUT_CHAR =\n        new Info(Opcodes.APUT_CHAR, \"aput-char\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info APUT_SHORT =\n        new Info(Opcodes.APUT_SHORT, \"aput-short\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info IGET =\n        new Info(Opcodes.IGET, \"iget\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IGET_WIDE =\n        new Info(Opcodes.IGET_WIDE, \"iget-wide\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IGET_OBJECT =\n        new Info(Opcodes.IGET_OBJECT, \"iget-object\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IGET_BOOLEAN =\n        new Info(Opcodes.IGET_BOOLEAN, \"iget-boolean\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IGET_BYTE =\n        new Info(Opcodes.IGET_BYTE, \"iget-byte\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IGET_CHAR =\n        new Info(Opcodes.IGET_CHAR, \"iget-char\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IGET_SHORT =\n        new Info(Opcodes.IGET_SHORT, \"iget-short\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IPUT =\n        new Info(Opcodes.IPUT, \"iput\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IPUT_WIDE =\n        new Info(Opcodes.IPUT_WIDE, \"iput-wide\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IPUT_OBJECT =\n        new Info(Opcodes.IPUT_OBJECT, \"iput-object\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IPUT_BOOLEAN =\n        new Info(Opcodes.IPUT_BOOLEAN, \"iput-boolean\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IPUT_BYTE =\n        new Info(Opcodes.IPUT_BYTE, \"iput-byte\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IPUT_CHAR =\n        new Info(Opcodes.IPUT_CHAR, \"iput-char\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IPUT_SHORT =\n        new Info(Opcodes.IPUT_SHORT, \"iput-short\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info SGET =\n        new Info(Opcodes.SGET, \"sget\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SGET_WIDE =\n        new Info(Opcodes.SGET_WIDE, \"sget-wide\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SGET_OBJECT =\n        new Info(Opcodes.SGET_OBJECT, \"sget-object\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SGET_BOOLEAN =\n        new Info(Opcodes.SGET_BOOLEAN, \"sget-boolean\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SGET_BYTE =\n        new Info(Opcodes.SGET_BYTE, \"sget-byte\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SGET_CHAR =\n        new Info(Opcodes.SGET_CHAR, \"sget-char\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SGET_SHORT =\n        new Info(Opcodes.SGET_SHORT, \"sget-short\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SPUT =\n        new Info(Opcodes.SPUT, \"sput\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SPUT_WIDE =\n        new Info(Opcodes.SPUT_WIDE, \"sput-wide\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SPUT_OBJECT =\n        new Info(Opcodes.SPUT_OBJECT, \"sput-object\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SPUT_BOOLEAN =\n        new Info(Opcodes.SPUT_BOOLEAN, \"sput-boolean\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SPUT_BYTE =\n        new Info(Opcodes.SPUT_BYTE, \"sput-byte\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SPUT_CHAR =\n        new Info(Opcodes.SPUT_CHAR, \"sput-char\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SPUT_SHORT =\n        new Info(Opcodes.SPUT_SHORT, \"sput-short\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info INVOKE_VIRTUAL =\n        new Info(Opcodes.INVOKE_VIRTUAL, \"invoke-virtual\",\n            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_SUPER =\n        new Info(Opcodes.INVOKE_SUPER, \"invoke-super\",\n            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_DIRECT =\n        new Info(Opcodes.INVOKE_DIRECT, \"invoke-direct\",\n            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_STATIC =\n        new Info(Opcodes.INVOKE_STATIC, \"invoke-static\",\n            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_INTERFACE =\n        new Info(Opcodes.INVOKE_INTERFACE, \"invoke-interface\",\n            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_VIRTUAL_RANGE =\n        new Info(Opcodes.INVOKE_VIRTUAL_RANGE, \"invoke-virtual/range\",\n            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_SUPER_RANGE =\n        new Info(Opcodes.INVOKE_SUPER_RANGE, \"invoke-super/range\",\n            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_DIRECT_RANGE =\n        new Info(Opcodes.INVOKE_DIRECT_RANGE, \"invoke-direct/range\",\n            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_STATIC_RANGE =\n        new Info(Opcodes.INVOKE_STATIC_RANGE, \"invoke-static/range\",\n            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_INTERFACE_RANGE =\n        new Info(Opcodes.INVOKE_INTERFACE_RANGE, \"invoke-interface/range\",\n            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);\n\n    public static final Info NEG_INT =\n        new Info(Opcodes.NEG_INT, \"neg-int\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info NOT_INT =\n        new Info(Opcodes.NOT_INT, \"not-int\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info NEG_LONG =\n        new Info(Opcodes.NEG_LONG, \"neg-long\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info NOT_LONG =\n        new Info(Opcodes.NOT_LONG, \"not-long\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info NEG_FLOAT =\n        new Info(Opcodes.NEG_FLOAT, \"neg-float\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info NEG_DOUBLE =\n        new Info(Opcodes.NEG_DOUBLE, \"neg-double\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info INT_TO_LONG =\n        new Info(Opcodes.INT_TO_LONG, \"int-to-long\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info INT_TO_FLOAT =\n        new Info(Opcodes.INT_TO_FLOAT, \"int-to-float\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info INT_TO_DOUBLE =\n        new Info(Opcodes.INT_TO_DOUBLE, \"int-to-double\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info LONG_TO_INT =\n        new Info(Opcodes.LONG_TO_INT, \"long-to-int\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info LONG_TO_FLOAT =\n        new Info(Opcodes.LONG_TO_FLOAT, \"long-to-float\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info LONG_TO_DOUBLE =\n        new Info(Opcodes.LONG_TO_DOUBLE, \"long-to-double\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info FLOAT_TO_INT =\n        new Info(Opcodes.FLOAT_TO_INT, \"float-to-int\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info FLOAT_TO_LONG =\n        new Info(Opcodes.FLOAT_TO_LONG, \"float-to-long\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info FLOAT_TO_DOUBLE =\n        new Info(Opcodes.FLOAT_TO_DOUBLE, \"float-to-double\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info DOUBLE_TO_INT =\n        new Info(Opcodes.DOUBLE_TO_INT, \"double-to-int\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info DOUBLE_TO_LONG =\n        new Info(Opcodes.DOUBLE_TO_LONG, \"double-to-long\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info DOUBLE_TO_FLOAT =\n        new Info(Opcodes.DOUBLE_TO_FLOAT, \"double-to-float\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info INT_TO_BYTE =\n        new Info(Opcodes.INT_TO_BYTE, \"int-to-byte\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info INT_TO_CHAR =\n        new Info(Opcodes.INT_TO_CHAR, \"int-to-char\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info INT_TO_SHORT =\n        new Info(Opcodes.INT_TO_SHORT, \"int-to-short\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info ADD_INT =\n        new Info(Opcodes.ADD_INT, \"add-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SUB_INT =\n        new Info(Opcodes.SUB_INT, \"sub-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info MUL_INT =\n        new Info(Opcodes.MUL_INT, \"mul-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info DIV_INT =\n        new Info(Opcodes.DIV_INT, \"div-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info REM_INT =\n        new Info(Opcodes.REM_INT, \"rem-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AND_INT =\n        new Info(Opcodes.AND_INT, \"and-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info OR_INT =\n        new Info(Opcodes.OR_INT, \"or-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info XOR_INT =\n        new Info(Opcodes.XOR_INT, \"xor-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SHL_INT =\n        new Info(Opcodes.SHL_INT, \"shl-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SHR_INT =\n        new Info(Opcodes.SHR_INT, \"shr-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info USHR_INT =\n        new Info(Opcodes.USHR_INT, \"ushr-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info ADD_LONG =\n        new Info(Opcodes.ADD_LONG, \"add-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SUB_LONG =\n        new Info(Opcodes.SUB_LONG, \"sub-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info MUL_LONG =\n        new Info(Opcodes.MUL_LONG, \"mul-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info DIV_LONG =\n        new Info(Opcodes.DIV_LONG, \"div-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info REM_LONG =\n        new Info(Opcodes.REM_LONG, \"rem-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AND_LONG =\n        new Info(Opcodes.AND_LONG, \"and-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info OR_LONG =\n        new Info(Opcodes.OR_LONG, \"or-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info XOR_LONG =\n        new Info(Opcodes.XOR_LONG, \"xor-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SHL_LONG =\n        new Info(Opcodes.SHL_LONG, \"shl-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SHR_LONG =\n        new Info(Opcodes.SHR_LONG, \"shr-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info USHR_LONG =\n        new Info(Opcodes.USHR_LONG, \"ushr-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info ADD_FLOAT =\n        new Info(Opcodes.ADD_FLOAT, \"add-float\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SUB_FLOAT =\n        new Info(Opcodes.SUB_FLOAT, \"sub-float\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info MUL_FLOAT =\n        new Info(Opcodes.MUL_FLOAT, \"mul-float\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info DIV_FLOAT =\n        new Info(Opcodes.DIV_FLOAT, \"div-float\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info REM_FLOAT =\n        new Info(Opcodes.REM_FLOAT, \"rem-float\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info ADD_DOUBLE =\n        new Info(Opcodes.ADD_DOUBLE, \"add-double\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SUB_DOUBLE =\n        new Info(Opcodes.SUB_DOUBLE, \"sub-double\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info MUL_DOUBLE =\n        new Info(Opcodes.MUL_DOUBLE, \"mul-double\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info DIV_DOUBLE =\n        new Info(Opcodes.DIV_DOUBLE, \"div-double\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info REM_DOUBLE =\n        new Info(Opcodes.REM_DOUBLE, \"rem-double\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info ADD_INT_2ADDR =\n        new Info(Opcodes.ADD_INT_2ADDR, \"add-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SUB_INT_2ADDR =\n        new Info(Opcodes.SUB_INT_2ADDR, \"sub-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info MUL_INT_2ADDR =\n        new Info(Opcodes.MUL_INT_2ADDR, \"mul-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info DIV_INT_2ADDR =\n        new Info(Opcodes.DIV_INT_2ADDR, \"div-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info REM_INT_2ADDR =\n        new Info(Opcodes.REM_INT_2ADDR, \"rem-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info AND_INT_2ADDR =\n        new Info(Opcodes.AND_INT_2ADDR, \"and-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info OR_INT_2ADDR =\n        new Info(Opcodes.OR_INT_2ADDR, \"or-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info XOR_INT_2ADDR =\n        new Info(Opcodes.XOR_INT_2ADDR, \"xor-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SHL_INT_2ADDR =\n        new Info(Opcodes.SHL_INT_2ADDR, \"shl-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SHR_INT_2ADDR =\n        new Info(Opcodes.SHR_INT_2ADDR, \"shr-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info USHR_INT_2ADDR =\n        new Info(Opcodes.USHR_INT_2ADDR, \"ushr-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info ADD_LONG_2ADDR =\n        new Info(Opcodes.ADD_LONG_2ADDR, \"add-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SUB_LONG_2ADDR =\n        new Info(Opcodes.SUB_LONG_2ADDR, \"sub-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info MUL_LONG_2ADDR =\n        new Info(Opcodes.MUL_LONG_2ADDR, \"mul-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info DIV_LONG_2ADDR =\n        new Info(Opcodes.DIV_LONG_2ADDR, \"div-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info REM_LONG_2ADDR =\n        new Info(Opcodes.REM_LONG_2ADDR, \"rem-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info AND_LONG_2ADDR =\n        new Info(Opcodes.AND_LONG_2ADDR, \"and-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info OR_LONG_2ADDR =\n        new Info(Opcodes.OR_LONG_2ADDR, \"or-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info XOR_LONG_2ADDR =\n        new Info(Opcodes.XOR_LONG_2ADDR, \"xor-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SHL_LONG_2ADDR =\n        new Info(Opcodes.SHL_LONG_2ADDR, \"shl-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SHR_LONG_2ADDR =\n        new Info(Opcodes.SHR_LONG_2ADDR, \"shr-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info USHR_LONG_2ADDR =\n        new Info(Opcodes.USHR_LONG_2ADDR, \"ushr-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info ADD_FLOAT_2ADDR =\n        new Info(Opcodes.ADD_FLOAT_2ADDR, \"add-float/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SUB_FLOAT_2ADDR =\n        new Info(Opcodes.SUB_FLOAT_2ADDR, \"sub-float/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info MUL_FLOAT_2ADDR =\n        new Info(Opcodes.MUL_FLOAT_2ADDR, \"mul-float/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info DIV_FLOAT_2ADDR =\n        new Info(Opcodes.DIV_FLOAT_2ADDR, \"div-float/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info REM_FLOAT_2ADDR =\n        new Info(Opcodes.REM_FLOAT_2ADDR, \"rem-float/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info ADD_DOUBLE_2ADDR =\n        new Info(Opcodes.ADD_DOUBLE_2ADDR, \"add-double/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SUB_DOUBLE_2ADDR =\n        new Info(Opcodes.SUB_DOUBLE_2ADDR, \"sub-double/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info MUL_DOUBLE_2ADDR =\n        new Info(Opcodes.MUL_DOUBLE_2ADDR, \"mul-double/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info DIV_DOUBLE_2ADDR =\n        new Info(Opcodes.DIV_DOUBLE_2ADDR, \"div-double/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info REM_DOUBLE_2ADDR =\n        new Info(Opcodes.REM_DOUBLE_2ADDR, \"rem-double/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info ADD_INT_LIT16 =\n        new Info(Opcodes.ADD_INT_LIT16, \"add-int/lit16\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info RSUB_INT =\n        new Info(Opcodes.RSUB_INT, \"rsub-int\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info MUL_INT_LIT16 =\n        new Info(Opcodes.MUL_INT_LIT16, \"mul-int/lit16\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info DIV_INT_LIT16 =\n        new Info(Opcodes.DIV_INT_LIT16, \"div-int/lit16\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info REM_INT_LIT16 =\n        new Info(Opcodes.REM_INT_LIT16, \"rem-int/lit16\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info AND_INT_LIT16 =\n        new Info(Opcodes.AND_INT_LIT16, \"and-int/lit16\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info OR_INT_LIT16 =\n        new Info(Opcodes.OR_INT_LIT16, \"or-int/lit16\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info XOR_INT_LIT16 =\n        new Info(Opcodes.XOR_INT_LIT16, \"xor-int/lit16\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info ADD_INT_LIT8 =\n        new Info(Opcodes.ADD_INT_LIT8, \"add-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info RSUB_INT_LIT8 =\n        new Info(Opcodes.RSUB_INT_LIT8, \"rsub-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info MUL_INT_LIT8 =\n        new Info(Opcodes.MUL_INT_LIT8, \"mul-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info DIV_INT_LIT8 =\n        new Info(Opcodes.DIV_INT_LIT8, \"div-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info REM_INT_LIT8 =\n        new Info(Opcodes.REM_INT_LIT8, \"rem-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info AND_INT_LIT8 =\n        new Info(Opcodes.AND_INT_LIT8, \"and-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info OR_INT_LIT8 =\n        new Info(Opcodes.OR_INT_LIT8, \"or-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info XOR_INT_LIT8 =\n        new Info(Opcodes.XOR_INT_LIT8, \"xor-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info SHL_INT_LIT8 =\n        new Info(Opcodes.SHL_INT_LIT8, \"shl-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info SHR_INT_LIT8 =\n        new Info(Opcodes.SHR_INT_LIT8, \"shr-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info USHR_INT_LIT8 =\n        new Info(Opcodes.USHR_INT_LIT8, \"ushr-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    // END(opcode-info-defs)\n\n    // Static initialization.\n    static {\n        INFO = new Info[Opcodes.MAX_VALUE - Opcodes.MIN_VALUE + 1];\n\n        // TODO: Stop using this constant.\n        set(SPECIAL_FORMAT);\n\n        // TODO: These payload opcodes should be generated by opcode-gen.\n        set(PACKED_SWITCH_PAYLOAD);\n        set(SPARSE_SWITCH_PAYLOAD);\n        set(FILL_ARRAY_DATA_PAYLOAD);\n\n        // BEGIN(opcode-info-init); GENERATED AUTOMATICALLY BY opcode-gen\n        set(NOP);\n        set(MOVE);\n        set(MOVE_FROM16);\n        set(MOVE_16);\n        set(MOVE_WIDE);\n        set(MOVE_WIDE_FROM16);\n        set(MOVE_WIDE_16);\n        set(MOVE_OBJECT);\n        set(MOVE_OBJECT_FROM16);\n        set(MOVE_OBJECT_16);\n        set(MOVE_RESULT);\n        set(MOVE_RESULT_WIDE);\n        set(MOVE_RESULT_OBJECT);\n        set(MOVE_EXCEPTION);\n        set(RETURN_VOID);\n        set(RETURN);\n        set(RETURN_WIDE);\n        set(RETURN_OBJECT);\n        set(CONST_4);\n        set(CONST_16);\n        set(CONST);\n        set(CONST_HIGH16);\n        set(CONST_WIDE_16);\n        set(CONST_WIDE_32);\n        set(CONST_WIDE);\n        set(CONST_WIDE_HIGH16);\n        set(CONST_STRING);\n        set(CONST_STRING_JUMBO);\n        set(CONST_CLASS);\n        set(MONITOR_ENTER);\n        set(MONITOR_EXIT);\n        set(CHECK_CAST);\n        set(INSTANCE_OF);\n        set(ARRAY_LENGTH);\n        set(NEW_INSTANCE);\n        set(NEW_ARRAY);\n        set(FILLED_NEW_ARRAY);\n        set(FILLED_NEW_ARRAY_RANGE);\n        set(FILL_ARRAY_DATA);\n        set(THROW);\n        set(GOTO);\n        set(GOTO_16);\n        set(GOTO_32);\n        set(PACKED_SWITCH);\n        set(SPARSE_SWITCH);\n        set(CMPL_FLOAT);\n        set(CMPG_FLOAT);\n        set(CMPL_DOUBLE);\n        set(CMPG_DOUBLE);\n        set(CMP_LONG);\n        set(IF_EQ);\n        set(IF_NE);\n        set(IF_LT);\n        set(IF_GE);\n        set(IF_GT);\n        set(IF_LE);\n        set(IF_EQZ);\n        set(IF_NEZ);\n        set(IF_LTZ);\n        set(IF_GEZ);\n        set(IF_GTZ);\n        set(IF_LEZ);\n        set(AGET);\n        set(AGET_WIDE);\n        set(AGET_OBJECT);\n        set(AGET_BOOLEAN);\n        set(AGET_BYTE);\n        set(AGET_CHAR);\n        set(AGET_SHORT);\n        set(APUT);\n        set(APUT_WIDE);\n        set(APUT_OBJECT);\n        set(APUT_BOOLEAN);\n        set(APUT_BYTE);\n        set(APUT_CHAR);\n        set(APUT_SHORT);\n        set(IGET);\n        set(IGET_WIDE);\n        set(IGET_OBJECT);\n        set(IGET_BOOLEAN);\n        set(IGET_BYTE);\n        set(IGET_CHAR);\n        set(IGET_SHORT);\n        set(IPUT);\n        set(IPUT_WIDE);\n        set(IPUT_OBJECT);\n        set(IPUT_BOOLEAN);\n        set(IPUT_BYTE);\n        set(IPUT_CHAR);\n        set(IPUT_SHORT);\n        set(SGET);\n        set(SGET_WIDE);\n        set(SGET_OBJECT);\n        set(SGET_BOOLEAN);\n        set(SGET_BYTE);\n        set(SGET_CHAR);\n        set(SGET_SHORT);\n        set(SPUT);\n        set(SPUT_WIDE);\n        set(SPUT_OBJECT);\n        set(SPUT_BOOLEAN);\n        set(SPUT_BYTE);\n        set(SPUT_CHAR);\n        set(SPUT_SHORT);\n        set(INVOKE_VIRTUAL);\n        set(INVOKE_SUPER);\n        set(INVOKE_DIRECT);\n        set(INVOKE_STATIC);\n        set(INVOKE_INTERFACE);\n        set(INVOKE_VIRTUAL_RANGE);\n        set(INVOKE_SUPER_RANGE);\n        set(INVOKE_DIRECT_RANGE);\n        set(INVOKE_STATIC_RANGE);\n        set(INVOKE_INTERFACE_RANGE);\n        set(NEG_INT);\n        set(NOT_INT);\n        set(NEG_LONG);\n        set(NOT_LONG);\n        set(NEG_FLOAT);\n        set(NEG_DOUBLE);\n        set(INT_TO_LONG);\n        set(INT_TO_FLOAT);\n        set(INT_TO_DOUBLE);\n        set(LONG_TO_INT);\n        set(LONG_TO_FLOAT);\n        set(LONG_TO_DOUBLE);\n        set(FLOAT_TO_INT);\n        set(FLOAT_TO_LONG);\n        set(FLOAT_TO_DOUBLE);\n        set(DOUBLE_TO_INT);\n        set(DOUBLE_TO_LONG);\n        set(DOUBLE_TO_FLOAT);\n        set(INT_TO_BYTE);\n        set(INT_TO_CHAR);\n        set(INT_TO_SHORT);\n        set(ADD_INT);\n        set(SUB_INT);\n        set(MUL_INT);\n        set(DIV_INT);\n        set(REM_INT);\n        set(AND_INT);\n        set(OR_INT);\n        set(XOR_INT);\n        set(SHL_INT);\n        set(SHR_INT);\n        set(USHR_INT);\n        set(ADD_LONG);\n        set(SUB_LONG);\n        set(MUL_LONG);\n        set(DIV_LONG);\n        set(REM_LONG);\n        set(AND_LONG);\n        set(OR_LONG);\n        set(XOR_LONG);\n        set(SHL_LONG);\n        set(SHR_LONG);\n        set(USHR_LONG);\n        set(ADD_FLOAT);\n        set(SUB_FLOAT);\n        set(MUL_FLOAT);\n        set(DIV_FLOAT);\n        set(REM_FLOAT);\n        set(ADD_DOUBLE);\n        set(SUB_DOUBLE);\n        set(MUL_DOUBLE);\n        set(DIV_DOUBLE);\n        set(REM_DOUBLE);\n        set(ADD_INT_2ADDR);\n        set(SUB_INT_2ADDR);\n        set(MUL_INT_2ADDR);\n        set(DIV_INT_2ADDR);\n        set(REM_INT_2ADDR);\n        set(AND_INT_2ADDR);\n        set(OR_INT_2ADDR);\n        set(XOR_INT_2ADDR);\n        set(SHL_INT_2ADDR);\n        set(SHR_INT_2ADDR);\n        set(USHR_INT_2ADDR);\n        set(ADD_LONG_2ADDR);\n        set(SUB_LONG_2ADDR);\n        set(MUL_LONG_2ADDR);\n        set(DIV_LONG_2ADDR);\n        set(REM_LONG_2ADDR);\n        set(AND_LONG_2ADDR);\n        set(OR_LONG_2ADDR);\n        set(XOR_LONG_2ADDR);\n        set(SHL_LONG_2ADDR);\n        set(SHR_LONG_2ADDR);\n        set(USHR_LONG_2ADDR);\n        set(ADD_FLOAT_2ADDR);\n        set(SUB_FLOAT_2ADDR);\n        set(MUL_FLOAT_2ADDR);\n        set(DIV_FLOAT_2ADDR);\n        set(REM_FLOAT_2ADDR);\n        set(ADD_DOUBLE_2ADDR);\n        set(SUB_DOUBLE_2ADDR);\n        set(MUL_DOUBLE_2ADDR);\n        set(DIV_DOUBLE_2ADDR);\n        set(REM_DOUBLE_2ADDR);\n        set(ADD_INT_LIT16);\n        set(RSUB_INT);\n        set(MUL_INT_LIT16);\n        set(DIV_INT_LIT16);\n        set(REM_INT_LIT16);\n        set(AND_INT_LIT16);\n        set(OR_INT_LIT16);\n        set(XOR_INT_LIT16);\n        set(ADD_INT_LIT8);\n        set(RSUB_INT_LIT8);\n        set(MUL_INT_LIT8);\n        set(DIV_INT_LIT8);\n        set(REM_INT_LIT8);\n        set(AND_INT_LIT8);\n        set(OR_INT_LIT8);\n        set(XOR_INT_LIT8);\n        set(SHL_INT_LIT8);\n        set(SHR_INT_LIT8);\n        set(USHR_INT_LIT8);\n        // END(opcode-info-init)\n    }\n\n    /**\n     * This class is uninstantiable.\n     */\n    private OpcodeInfo() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Gets the {@link @Info} for the given opcode value.\n     *\n     * @param opcode {@code Opcodes.MIN_VALUE..Opcodes.MAX_VALUE;} the\n     * opcode value\n     * @return non-null; the associated opcode information instance\n     */\n    public static Info get(int opcode) {\n        int idx = opcode - Opcodes.MIN_VALUE;\n\n        try {\n            Info result = INFO[idx];\n            if (result != null) {\n                return result;\n            }\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Fall through.\n        }\n\n        throw new IllegalArgumentException(\"bogus opcode: \"\n                + Hex.u2or4(opcode));\n    }\n\n    /**\n     * Gets the name of the given opcode.\n     */\n    public static String getName(int opcode) {\n        return get(opcode).getName();\n    }\n\n    /**\n     * Gets the format (an {@link InstructionCodec}) for the given opcode\n     * value.\n     */\n    public static InstructionCodec getFormat(int opcode) {\n        return get(opcode).getFormat();\n    }\n\n    /**\n     * Gets the {@link IndexType} for the given opcode value.\n     */\n    public static IndexType getIndexType(int opcode) {\n        return get(opcode).getIndexType();\n    }\n\n    /**\n     * Puts the given opcode into the table of all ops.\n     *\n     * @param opcode non-null; the opcode\n     */\n    private static void set(Info opcode) {\n        int idx = opcode.getOpcode() - Opcodes.MIN_VALUE;\n        INFO[idx] = opcode;\n    }\n\n    /**\n     * Information about an opcode.\n     */\n    public static class Info {\n        private final int opcode;\n        private final String name;\n        private final InstructionCodec format;\n        private final IndexType indexType;\n\n        public Info(int opcode, String name, InstructionCodec format,\n                IndexType indexType) {\n            this.opcode = opcode;\n            this.name = name;\n            this.format = format;\n            this.indexType = indexType;\n        }\n\n        public int getOpcode() {\n            return opcode;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public InstructionCodec getFormat() {\n            return format;\n        }\n\n        public IndexType getIndexType() {\n            return indexType;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/Opcodes.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io;\n\n/**\n * All the Dalvik opcode value constants. See the related spec\n * document for the meaning and instruction format of each opcode.\n */\npublic final class Opcodes {\n    /**\n     * pseudo-opcode used for nonstandard format payload \"instructions\". TODO:\n     * Retire this concept, and start treating the payload instructions\n     * more like the rest.\n     */\n    public static final int SPECIAL_FORMAT = -1;\n\n    /**\n     * pseudo-opcode used to indicate there is no next opcode; used\n     * in opcode chaining lists\n     */\n    public static final int NO_NEXT = -1;\n\n    /** minimum valid opcode value */\n    public static final int MIN_VALUE = -1;\n\n    /** maximum valid opcode value */\n    public static final int MAX_VALUE = 0xffff;\n\n    // BEGIN(opcodes); GENERATED AUTOMATICALLY BY opcode-gen\n    public static final int NOP = 0x00;\n    public static final int MOVE = 0x01;\n    public static final int MOVE_FROM16 = 0x02;\n    public static final int MOVE_16 = 0x03;\n    public static final int MOVE_WIDE = 0x04;\n    public static final int MOVE_WIDE_FROM16 = 0x05;\n    public static final int MOVE_WIDE_16 = 0x06;\n    public static final int MOVE_OBJECT = 0x07;\n    public static final int MOVE_OBJECT_FROM16 = 0x08;\n    public static final int MOVE_OBJECT_16 = 0x09;\n    public static final int MOVE_RESULT = 0x0a;\n    public static final int MOVE_RESULT_WIDE = 0x0b;\n    public static final int MOVE_RESULT_OBJECT = 0x0c;\n    public static final int MOVE_EXCEPTION = 0x0d;\n    public static final int RETURN_VOID = 0x0e;\n    public static final int RETURN = 0x0f;\n    public static final int RETURN_WIDE = 0x10;\n    public static final int RETURN_OBJECT = 0x11;\n    public static final int CONST_4 = 0x12;\n    public static final int CONST_16 = 0x13;\n    public static final int CONST = 0x14;\n    public static final int CONST_HIGH16 = 0x15;\n    public static final int CONST_WIDE_16 = 0x16;\n    public static final int CONST_WIDE_32 = 0x17;\n    public static final int CONST_WIDE = 0x18;\n    public static final int CONST_WIDE_HIGH16 = 0x19;\n    public static final int CONST_STRING = 0x1a;\n    public static final int CONST_STRING_JUMBO = 0x1b;\n    public static final int CONST_CLASS = 0x1c;\n    public static final int MONITOR_ENTER = 0x1d;\n    public static final int MONITOR_EXIT = 0x1e;\n    public static final int CHECK_CAST = 0x1f;\n    public static final int INSTANCE_OF = 0x20;\n    public static final int ARRAY_LENGTH = 0x21;\n    public static final int NEW_INSTANCE = 0x22;\n    public static final int NEW_ARRAY = 0x23;\n    public static final int FILLED_NEW_ARRAY = 0x24;\n    public static final int FILLED_NEW_ARRAY_RANGE = 0x25;\n    public static final int FILL_ARRAY_DATA = 0x26;\n    public static final int THROW = 0x27;\n    public static final int GOTO = 0x28;\n    public static final int GOTO_16 = 0x29;\n    public static final int GOTO_32 = 0x2a;\n    public static final int PACKED_SWITCH = 0x2b;\n    public static final int SPARSE_SWITCH = 0x2c;\n    public static final int CMPL_FLOAT = 0x2d;\n    public static final int CMPG_FLOAT = 0x2e;\n    public static final int CMPL_DOUBLE = 0x2f;\n    public static final int CMPG_DOUBLE = 0x30;\n    public static final int CMP_LONG = 0x31;\n    public static final int IF_EQ = 0x32;\n    public static final int IF_NE = 0x33;\n    public static final int IF_LT = 0x34;\n    public static final int IF_GE = 0x35;\n    public static final int IF_GT = 0x36;\n    public static final int IF_LE = 0x37;\n    public static final int IF_EQZ = 0x38;\n    public static final int IF_NEZ = 0x39;\n    public static final int IF_LTZ = 0x3a;\n    public static final int IF_GEZ = 0x3b;\n    public static final int IF_GTZ = 0x3c;\n    public static final int IF_LEZ = 0x3d;\n    public static final int AGET = 0x44;\n    public static final int AGET_WIDE = 0x45;\n    public static final int AGET_OBJECT = 0x46;\n    public static final int AGET_BOOLEAN = 0x47;\n    public static final int AGET_BYTE = 0x48;\n    public static final int AGET_CHAR = 0x49;\n    public static final int AGET_SHORT = 0x4a;\n    public static final int APUT = 0x4b;\n    public static final int APUT_WIDE = 0x4c;\n    public static final int APUT_OBJECT = 0x4d;\n    public static final int APUT_BOOLEAN = 0x4e;\n    public static final int APUT_BYTE = 0x4f;\n    public static final int APUT_CHAR = 0x50;\n    public static final int APUT_SHORT = 0x51;\n    public static final int IGET = 0x52;\n    public static final int IGET_WIDE = 0x53;\n    public static final int IGET_OBJECT = 0x54;\n    public static final int IGET_BOOLEAN = 0x55;\n    public static final int IGET_BYTE = 0x56;\n    public static final int IGET_CHAR = 0x57;\n    public static final int IGET_SHORT = 0x58;\n    public static final int IPUT = 0x59;\n    public static final int IPUT_WIDE = 0x5a;\n    public static final int IPUT_OBJECT = 0x5b;\n    public static final int IPUT_BOOLEAN = 0x5c;\n    public static final int IPUT_BYTE = 0x5d;\n    public static final int IPUT_CHAR = 0x5e;\n    public static final int IPUT_SHORT = 0x5f;\n    public static final int SGET = 0x60;\n    public static final int SGET_WIDE = 0x61;\n    public static final int SGET_OBJECT = 0x62;\n    public static final int SGET_BOOLEAN = 0x63;\n    public static final int SGET_BYTE = 0x64;\n    public static final int SGET_CHAR = 0x65;\n    public static final int SGET_SHORT = 0x66;\n    public static final int SPUT = 0x67;\n    public static final int SPUT_WIDE = 0x68;\n    public static final int SPUT_OBJECT = 0x69;\n    public static final int SPUT_BOOLEAN = 0x6a;\n    public static final int SPUT_BYTE = 0x6b;\n    public static final int SPUT_CHAR = 0x6c;\n    public static final int SPUT_SHORT = 0x6d;\n    public static final int INVOKE_VIRTUAL = 0x6e;\n    public static final int INVOKE_SUPER = 0x6f;\n    public static final int INVOKE_DIRECT = 0x70;\n    public static final int INVOKE_STATIC = 0x71;\n    public static final int INVOKE_INTERFACE = 0x72;\n    public static final int INVOKE_VIRTUAL_RANGE = 0x74;\n    public static final int INVOKE_SUPER_RANGE = 0x75;\n    public static final int INVOKE_DIRECT_RANGE = 0x76;\n    public static final int INVOKE_STATIC_RANGE = 0x77;\n    public static final int INVOKE_INTERFACE_RANGE = 0x78;\n    public static final int NEG_INT = 0x7b;\n    public static final int NOT_INT = 0x7c;\n    public static final int NEG_LONG = 0x7d;\n    public static final int NOT_LONG = 0x7e;\n    public static final int NEG_FLOAT = 0x7f;\n    public static final int NEG_DOUBLE = 0x80;\n    public static final int INT_TO_LONG = 0x81;\n    public static final int INT_TO_FLOAT = 0x82;\n    public static final int INT_TO_DOUBLE = 0x83;\n    public static final int LONG_TO_INT = 0x84;\n    public static final int LONG_TO_FLOAT = 0x85;\n    public static final int LONG_TO_DOUBLE = 0x86;\n    public static final int FLOAT_TO_INT = 0x87;\n    public static final int FLOAT_TO_LONG = 0x88;\n    public static final int FLOAT_TO_DOUBLE = 0x89;\n    public static final int DOUBLE_TO_INT = 0x8a;\n    public static final int DOUBLE_TO_LONG = 0x8b;\n    public static final int DOUBLE_TO_FLOAT = 0x8c;\n    public static final int INT_TO_BYTE = 0x8d;\n    public static final int INT_TO_CHAR = 0x8e;\n    public static final int INT_TO_SHORT = 0x8f;\n    public static final int ADD_INT = 0x90;\n    public static final int SUB_INT = 0x91;\n    public static final int MUL_INT = 0x92;\n    public static final int DIV_INT = 0x93;\n    public static final int REM_INT = 0x94;\n    public static final int AND_INT = 0x95;\n    public static final int OR_INT = 0x96;\n    public static final int XOR_INT = 0x97;\n    public static final int SHL_INT = 0x98;\n    public static final int SHR_INT = 0x99;\n    public static final int USHR_INT = 0x9a;\n    public static final int ADD_LONG = 0x9b;\n    public static final int SUB_LONG = 0x9c;\n    public static final int MUL_LONG = 0x9d;\n    public static final int DIV_LONG = 0x9e;\n    public static final int REM_LONG = 0x9f;\n    public static final int AND_LONG = 0xa0;\n    public static final int OR_LONG = 0xa1;\n    public static final int XOR_LONG = 0xa2;\n    public static final int SHL_LONG = 0xa3;\n    public static final int SHR_LONG = 0xa4;\n    public static final int USHR_LONG = 0xa5;\n    public static final int ADD_FLOAT = 0xa6;\n    public static final int SUB_FLOAT = 0xa7;\n    public static final int MUL_FLOAT = 0xa8;\n    public static final int DIV_FLOAT = 0xa9;\n    public static final int REM_FLOAT = 0xaa;\n    public static final int ADD_DOUBLE = 0xab;\n    public static final int SUB_DOUBLE = 0xac;\n    public static final int MUL_DOUBLE = 0xad;\n    public static final int DIV_DOUBLE = 0xae;\n    public static final int REM_DOUBLE = 0xaf;\n    public static final int ADD_INT_2ADDR = 0xb0;\n    public static final int SUB_INT_2ADDR = 0xb1;\n    public static final int MUL_INT_2ADDR = 0xb2;\n    public static final int DIV_INT_2ADDR = 0xb3;\n    public static final int REM_INT_2ADDR = 0xb4;\n    public static final int AND_INT_2ADDR = 0xb5;\n    public static final int OR_INT_2ADDR = 0xb6;\n    public static final int XOR_INT_2ADDR = 0xb7;\n    public static final int SHL_INT_2ADDR = 0xb8;\n    public static final int SHR_INT_2ADDR = 0xb9;\n    public static final int USHR_INT_2ADDR = 0xba;\n    public static final int ADD_LONG_2ADDR = 0xbb;\n    public static final int SUB_LONG_2ADDR = 0xbc;\n    public static final int MUL_LONG_2ADDR = 0xbd;\n    public static final int DIV_LONG_2ADDR = 0xbe;\n    public static final int REM_LONG_2ADDR = 0xbf;\n    public static final int AND_LONG_2ADDR = 0xc0;\n    public static final int OR_LONG_2ADDR = 0xc1;\n    public static final int XOR_LONG_2ADDR = 0xc2;\n    public static final int SHL_LONG_2ADDR = 0xc3;\n    public static final int SHR_LONG_2ADDR = 0xc4;\n    public static final int USHR_LONG_2ADDR = 0xc5;\n    public static final int ADD_FLOAT_2ADDR = 0xc6;\n    public static final int SUB_FLOAT_2ADDR = 0xc7;\n    public static final int MUL_FLOAT_2ADDR = 0xc8;\n    public static final int DIV_FLOAT_2ADDR = 0xc9;\n    public static final int REM_FLOAT_2ADDR = 0xca;\n    public static final int ADD_DOUBLE_2ADDR = 0xcb;\n    public static final int SUB_DOUBLE_2ADDR = 0xcc;\n    public static final int MUL_DOUBLE_2ADDR = 0xcd;\n    public static final int DIV_DOUBLE_2ADDR = 0xce;\n    public static final int REM_DOUBLE_2ADDR = 0xcf;\n    public static final int ADD_INT_LIT16 = 0xd0;\n    public static final int RSUB_INT = 0xd1;\n    public static final int MUL_INT_LIT16 = 0xd2;\n    public static final int DIV_INT_LIT16 = 0xd3;\n    public static final int REM_INT_LIT16 = 0xd4;\n    public static final int AND_INT_LIT16 = 0xd5;\n    public static final int OR_INT_LIT16 = 0xd6;\n    public static final int XOR_INT_LIT16 = 0xd7;\n    public static final int ADD_INT_LIT8 = 0xd8;\n    public static final int RSUB_INT_LIT8 = 0xd9;\n    public static final int MUL_INT_LIT8 = 0xda;\n    public static final int DIV_INT_LIT8 = 0xdb;\n    public static final int REM_INT_LIT8 = 0xdc;\n    public static final int AND_INT_LIT8 = 0xdd;\n    public static final int OR_INT_LIT8 = 0xde;\n    public static final int XOR_INT_LIT8 = 0xdf;\n    public static final int SHL_INT_LIT8 = 0xe0;\n    public static final int SHR_INT_LIT8 = 0xe1;\n    public static final int USHR_INT_LIT8 = 0xe2;\n    // END(opcodes)\n\n    // TODO: Generate these payload opcodes with opcode-gen.\n\n    /**\n     * special pseudo-opcode value for packed-switch data payload\n     * instructions\n     */\n    public static final int PACKED_SWITCH_PAYLOAD = 0x100;\n\n    /** special pseudo-opcode value for packed-switch data payload\n     * instructions\n     */\n    public static final int SPARSE_SWITCH_PAYLOAD = 0x200;\n\n    /** special pseudo-opcode value for fill-array-data data payload\n     * instructions\n     */\n    public static final int FILL_ARRAY_DATA_PAYLOAD = 0x300;\n\n    /**\n     * This class is uninstantiable.\n     */\n    private Opcodes() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Determines if the given opcode has the right \"shape\" to be\n     * valid. This includes the range {@code 0x01..0xfe}, the range\n     * {@code 0x00ff..0xffff} where the low-order byte is either\n     * {@code 0} or {@code 0xff}, and the special opcode values {@code\n     * SPECIAL_FORMAT} and {@code NO_NEXT}. Note that not all of the\n     * opcode values that pass this test are in fact used. This method\n     * is meant to perform a quick check to reject blatantly wrong\n     * values (e.g. when validating arguments).\n     *\n     * @param opcode the opcode value\n     * @return {@code true} iff the value has the right \"shape\" to be\n     * possibly valid\n     */\n    public static boolean isValidShape(int opcode) {\n        /*\n         * Note: This method bakes in knowledge that all opcodes are\n         * one of the forms:\n         *\n         *   * single byte in range 0x01..0xfe -- normal opcodes\n         *   * (byteValue << 8) -- nop and data payload opcodes\n         *   * ((byteValue << 8) | 0xff) -- 16-bit extended opcodes\n         *   * SPECIAL_FORMAT or NO_NEXT -- pseudo-opcodes\n         */\n\n        // Note: SPECIAL_FORMAT == NO_NEXT.\n        if (opcode < SPECIAL_FORMAT) {\n            return false;\n        } else if (opcode == SPECIAL_FORMAT) {\n            return true;\n        }\n\n        int lowByte = opcode & 0xff;\n        if ((lowByte == 0) || (lowByte == 0xff)) {\n            return true;\n        }\n\n        return (opcode & 0xff00) == 0;\n    }\n\n    /**\n     * Gets the opcode out of an opcode unit, the latter of which may also\n     * include one or more argument values.\n     *\n     * @param opcodeUnit the opcode-containing code unit\n     * @return the extracted opcode\n     */\n    public static int extractOpcodeFromUnit(int opcodeUnit) {\n        /*\n         * Note: This method bakes in knowledge that all opcodes are\n         * either single-byte or of the forms (byteValue << 8) or\n         * ((byteValue << 8) | 0xff).\n         */\n\n        int lowByte = opcodeUnit & 0xff;\n        return ((lowByte == 0) || (lowByte == 0xff)) ? opcodeUnit : lowByte;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/AddressMap.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\nimport java.util.HashMap;\n\n/**\n * Map from addresses to addresses, where addresses are all\n * {@code int}s.\n */\npublic final class AddressMap {\n    /** underlying map. TODO: This might be too inefficient. */\n    private final HashMap<Integer,Integer> map;\n\n    /**\n     * Constructs an instance.\n     */\n    public AddressMap() {\n        map = new HashMap<Integer,Integer>();\n    }\n\n    /**\n     * Gets the value address corresponding to the given key address. Returns\n     * {@code -1} if there is no mapping.\n     */\n    public int get(int keyAddress) {\n        Integer value = map.get(keyAddress);\n        return (value == null) ? -1 : value;\n    }\n\n    /**\n     * Sets the value address associated with the given key address.\n     */\n    public void put(int keyAddress, int valueAddress) {\n        map.put(keyAddress, valueAddress);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/BaseCodeCursor.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\n/**\n * Base implementation of {@link CodeCursor}.\n */\npublic abstract class BaseCodeCursor implements CodeCursor {\n    /** base address map */\n    private final AddressMap baseAddressMap;\n\n    /** next index within {@link #array} to read from or write to */\n    private int cursor;\n\n    /**\n     * Constructs an instance.\n     */\n    public BaseCodeCursor() {\n        this.baseAddressMap = new AddressMap();\n        this.cursor = 0;\n    }\n\n    /** @inheritDoc */\n    public final int cursor() {\n        return cursor;\n    }\n\n    /** @inheritDoc */\n    public final int baseAddressForCursor() {\n        int mapped = baseAddressMap.get(cursor);\n        return (mapped >= 0) ? mapped : cursor;\n    }\n\n    /** @inheritDoc */\n    public final void setBaseAddress(int targetAddress, int baseAddress) {\n        baseAddressMap.put(targetAddress, baseAddress);\n    }\n\n    /**\n     * Advance the cursor by the indicated amount.\n     */\n    protected final void advance(int amount) {\n        cursor += amount;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/CodeCursor.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\n/**\n * Cursor over code units, for reading or writing out Dalvik bytecode.\n */\npublic interface CodeCursor {\n    /**\n     * Gets the cursor. The cursor is the offset in code units from\n     * the start of the input of the next code unit to be read or\n     * written, where the input generally consists of the code for a\n     * single method.\n     */\n    public int cursor();\n\n    /**\n     * Gets the base address associated with the current cursor. This\n     * differs from the cursor value when explicitly set (by {@link\n     * #setBaseAddress). This is used, in particular, to convey base\n     * addresses to switch data payload instructions, whose relative\n     * addresses are relative to the address of a dependant switch\n     * instruction.\n     */\n    public int baseAddressForCursor();\n\n    /**\n     * Sets the base address for the given target address to be as indicated.\n     *\n     * @see #baseAddressForCursor\n     */\n    public void setBaseAddress(int targetAddress, int baseAddress);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/CodeInput.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\nimport java.io.EOFException;\n\n/**\n * Input stream of code units, for reading in Dalvik bytecode.\n */\npublic interface CodeInput extends CodeCursor {\n    /**\n     * Returns whether there are any more code units to read. This\n     * is analogous to {@code hasNext()} on an interator.\n     */\n    public boolean hasMore();\n\n    /**\n     * Reads a code unit.\n     */\n    public int read() throws EOFException;\n\n    /**\n     * Reads two code units, treating them as a little-endian {@code int}.\n     */\n    public int readInt() throws EOFException;\n\n    /**\n     * Reads four code units, treating them as a little-endian {@code long}.\n     */\n    public long readLong() throws EOFException;\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/CodeOutput.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\n/**\n * Output stream of code units, for writing out Dalvik bytecode.\n */\npublic interface CodeOutput extends CodeCursor {\n    /**\n     * Writes a code unit.\n     */\n    public void write(short codeUnit);\n\n    /**\n     * Writes two code units.\n     */\n    public void write(short u0, short u1);\n\n    /**\n     * Writes three code units.\n     */\n    public void write(short u0, short u1, short u2);\n\n    /**\n     * Writes four code units.\n     */\n    public void write(short u0, short u1, short u2, short u3);\n\n    /**\n     * Writes five code units.\n     */\n    public void write(short u0, short u1, short u2, short u3, short u4);\n\n    /**\n     * Writes an {@code int}, little-endian.\n     */\n    public void writeInt(int value);\n\n    /**\n     * Writes a {@code long}, little-endian.\n     */\n    public void writeLong(long value);\n\n    /**\n     * Writes the contents of the given array.\n     */\n    public void write(byte[] data);\n\n    /**\n     * Writes the contents of the given array.\n     */\n    public void write(short[] data);\n\n    /**\n     * Writes the contents of the given array.\n     */\n    public void write(int[] data);\n\n    /**\n     * Writes the contents of the given array.\n     */\n    public void write(long[] data);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/DecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\nimport com.taobao.android.dex.DexException;\nimport com.taobao.android.dx.io.IndexType;\nimport com.taobao.android.dx.io.OpcodeInfo;\nimport com.taobao.android.dx.io.Opcodes;\nimport com.taobao.android.dx.util.Hex;\nimport java.io.EOFException;\n\n/**\n * A decoded Dalvik instruction. This consists of a format codec, a\n * numeric opcode, an optional index type, and any additional\n * arguments of the instruction. The additional arguments (if any) are\n * represented as uninterpreted data.\n *\n * <p><b>Note:</b> The names of the arguments are <i>not</i> meant to\n * match the names given in the Dalvik instruction format\n * specification, specification which just names fields (somewhat)\n * arbitrarily alphabetically from A. In this class, non-register\n * fields are given descriptive names and register fields are\n * consistently named alphabetically.</p>\n */\npublic abstract class DecodedInstruction {\n    /** non-null; instruction format / codec */\n    private final InstructionCodec format;\n\n    /** opcode number */\n    private final int opcode;\n\n    /** constant index argument */\n    private final int index;\n\n    /** null-ok; index type */\n    private final IndexType indexType;\n\n    /**\n     * target address argument. This is an absolute address, not just\n     * a signed offset. <b>Note:</b> The address is unsigned, even\n     * though it is stored in an {@code int}.\n     */\n    private final int target;\n\n    /**\n     * literal value argument; also used for special verification error\n     * constants (format 20bc) as well as should-be-zero values\n     * (formats 10x, 20t, 30t, and 32x)\n     */\n    private final long literal;\n\n    /**\n     * Decodes an instruction from the given input source.\n     */\n    public static DecodedInstruction decode(CodeInput in) throws EOFException {\n        int opcodeUnit = in.read();\n        int opcode = Opcodes.extractOpcodeFromUnit(opcodeUnit);\n        InstructionCodec format = OpcodeInfo.getFormat(opcode);\n\n        return format.decode(opcodeUnit, in);\n    }\n\n    /**\n     * Decodes an array of instructions. The result has non-null\n     * elements at each offset that represents the start of an\n     * instruction.\n     */\n    public static DecodedInstruction[] decodeAll(short[] encodedInstructions) {\n        int size = encodedInstructions.length;\n        DecodedInstruction[] decoded = new DecodedInstruction[size];\n        ShortArrayCodeInput in = new ShortArrayCodeInput(encodedInstructions);\n\n        try {\n            while (in.hasMore()) {\n                decoded[in.cursor()] = DecodedInstruction.decode(in);\n            }\n        } catch (EOFException ex) {\n            throw new DexException(ex);\n        }\n\n        return decoded;\n    }\n\n    /**\n     * Constructs an instance.\n     */\n    public DecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal) {\n        if (format == null) {\n            throw new NullPointerException(\"format == null\");\n        }\n\n        if (!Opcodes.isValidShape(opcode)) {\n            throw new IllegalArgumentException(\"invalid opcode\");\n        }\n\n        this.format = format;\n        this.opcode = opcode;\n        this.index = index;\n        this.indexType = indexType;\n        this.target = target;\n        this.literal = literal;\n    }\n\n    public final InstructionCodec getFormat() {\n        return format;\n    }\n\n    public final int getOpcode() {\n        return opcode;\n    }\n\n    /**\n     * Gets the opcode, as a code unit.\n     */\n    public final short getOpcodeUnit() {\n        return (short) opcode;\n    }\n\n    public final int getIndex() {\n        return index;\n    }\n\n    /**\n     * Gets the index, as a code unit.\n     */\n    public final short getIndexUnit() {\n        return (short) index;\n    }\n\n    public final IndexType getIndexType() {\n        return indexType;\n    }\n\n    /**\n     * Gets the raw target.\n     */\n    public final int getTarget() {\n        return target;\n    }\n\n    /**\n     * Gets the target as a relative offset from the given address.\n     */\n    public final int getTarget(int baseAddress) {\n        return target - baseAddress;\n    }\n\n    /**\n     * Gets the target as a relative offset from the given base\n     * address, as a code unit. This will throw if the value is out of\n     * the range of a signed code unit.\n     */\n    public final short getTargetUnit(int baseAddress) {\n        int relativeTarget = getTarget(baseAddress);\n\n        if (relativeTarget != (short) relativeTarget) {\n            throw new DexException(\"Target out of range: \"\n                    + Hex.s4(relativeTarget));\n        }\n\n        return (short) relativeTarget;\n    }\n\n    /**\n     * Gets the target as a relative offset from the given base\n     * address, masked to be a byte in size. This will throw if the\n     * value is out of the range of a signed byte.\n     */\n    public final int getTargetByte(int baseAddress) {\n        int relativeTarget = getTarget(baseAddress);\n\n        if (relativeTarget != (byte) relativeTarget) {\n            throw new DexException(\"Target out of range: \"\n                    + Hex.s4(relativeTarget));\n        }\n\n        return relativeTarget & 0xff;\n    }\n\n    public final long getLiteral() {\n        return literal;\n    }\n\n    /**\n     * Gets the literal value, masked to be an int in size. This will\n     * throw if the value is out of the range of a signed int.\n     */\n    public final int getLiteralInt() {\n        if (literal != (int) literal) {\n            throw new DexException(\"Literal out of range: \" + Hex.u8(literal));\n        }\n\n        return (int) literal;\n    }\n\n    /**\n     * Gets the literal value, as a code unit. This will throw if the\n     * value is out of the range of a signed code unit.\n     */\n    public final short getLiteralUnit() {\n        if (literal != (short) literal) {\n            throw new DexException(\"Literal out of range: \" + Hex.u8(literal));\n        }\n\n        return (short) literal;\n    }\n\n    /**\n     * Gets the literal value, masked to be a byte in size. This will\n     * throw if the value is out of the range of a signed byte.\n     */\n    public final int getLiteralByte() {\n        if (literal != (byte) literal) {\n            throw new DexException(\"Literal out of range: \" + Hex.u8(literal));\n        }\n\n        return (int) literal & 0xff;\n    }\n\n    /**\n     * Gets the literal value, masked to be a nibble in size. This\n     * will throw if the value is out of the range of a signed nibble.\n     */\n    public final int getLiteralNibble() {\n        if ((literal < -8) || (literal > 7)) {\n            throw new DexException(\"Literal out of range: \" + Hex.u8(literal));\n        }\n\n        return (int) literal & 0xf;\n    }\n\n    public abstract int getRegisterCount();\n\n    public int getA() {\n        return 0;\n    }\n\n    public int getB() {\n        return 0;\n    }\n\n    public int getC() {\n        return 0;\n    }\n\n    public int getD() {\n        return 0;\n    }\n\n    public int getE() {\n        return 0;\n    }\n\n    /**\n     * Gets the register count, as a code unit. This will throw if the\n     * value is out of the range of an unsigned code unit.\n     */\n    public final short getRegisterCountUnit() {\n        int registerCount = getRegisterCount();\n\n        if ((registerCount & ~0xffff) != 0) {\n            throw new DexException(\"Register count out of range: \"\n                    + Hex.u8(registerCount));\n        }\n\n        return (short) registerCount;\n    }\n\n    /**\n     * Gets the A register number, as a code unit. This will throw if the\n     * value is out of the range of an unsigned code unit.\n     */\n    public final short getAUnit() {\n        int a = getA();\n\n        if ((a & ~0xffff) != 0) {\n            throw new DexException(\"Register A out of range: \" + Hex.u8(a));\n        }\n\n        return (short) a;\n    }\n\n    /**\n     * Gets the A register number, as a byte. This will throw if the\n     * value is out of the range of an unsigned byte.\n     */\n    public final short getAByte() {\n        int a = getA();\n\n        if ((a & ~0xff) != 0) {\n            throw new DexException(\"Register A out of range: \" + Hex.u8(a));\n        }\n\n        return (short) a;\n    }\n\n    /**\n     * Gets the A register number, as a nibble. This will throw if the\n     * value is out of the range of an unsigned nibble.\n     */\n    public final short getANibble() {\n        int a = getA();\n\n        if ((a & ~0xf) != 0) {\n            throw new DexException(\"Register A out of range: \" + Hex.u8(a));\n        }\n\n        return (short) a;\n    }\n\n    /**\n     * Gets the B register number, as a code unit. This will throw if the\n     * value is out of the range of an unsigned code unit.\n     */\n    public final short getBUnit() {\n        int b = getB();\n\n        if ((b & ~0xffff) != 0) {\n            throw new DexException(\"Register B out of range: \" + Hex.u8(b));\n        }\n\n        return (short) b;\n    }\n\n    /**\n     * Gets the B register number, as a byte. This will throw if the\n     * value is out of the range of an unsigned byte.\n     */\n    public final short getBByte() {\n        int b = getB();\n\n        if ((b & ~0xff) != 0) {\n            throw new DexException(\"Register B out of range: \" + Hex.u8(b));\n        }\n\n        return (short) b;\n    }\n\n    /**\n     * Gets the B register number, as a nibble. This will throw if the\n     * value is out of the range of an unsigned nibble.\n     */\n    public final short getBNibble() {\n        int b = getB();\n\n        if ((b & ~0xf) != 0) {\n            throw new DexException(\"Register B out of range: \" + Hex.u8(b));\n        }\n\n        return (short) b;\n    }\n\n    /**\n     * Gets the C register number, as a code unit. This will throw if the\n     * value is out of the range of an unsigned code unit.\n     */\n    public final short getCUnit() {\n        int c = getC();\n\n        if ((c & ~0xffff) != 0) {\n            throw new DexException(\"Register C out of range: \" + Hex.u8(c));\n        }\n\n        return (short) c;\n    }\n\n    /**\n     * Gets the C register number, as a byte. This will throw if the\n     * value is out of the range of an unsigned byte.\n     */\n    public final short getCByte() {\n        int c = getC();\n\n        if ((c & ~0xff) != 0) {\n            throw new DexException(\"Register C out of range: \" + Hex.u8(c));\n        }\n\n        return (short) c;\n    }\n\n    /**\n     * Gets the C register number, as a nibble. This will throw if the\n     * value is out of the range of an unsigned nibble.\n     */\n    public final short getCNibble() {\n        int c = getC();\n\n        if ((c & ~0xf) != 0) {\n            throw new DexException(\"Register C out of range: \" + Hex.u8(c));\n        }\n\n        return (short) c;\n    }\n\n    /**\n     * Gets the D register number, as a code unit. This will throw if the\n     * value is out of the range of an unsigned code unit.\n     */\n    public final short getDUnit() {\n        int d = getD();\n\n        if ((d & ~0xffff) != 0) {\n            throw new DexException(\"Register D out of range: \" + Hex.u8(d));\n        }\n\n        return (short) d;\n    }\n\n    /**\n     * Gets the D register number, as a byte. This will throw if the\n     * value is out of the range of an unsigned byte.\n     */\n    public final short getDByte() {\n        int d = getD();\n\n        if ((d & ~0xff) != 0) {\n            throw new DexException(\"Register D out of range: \" + Hex.u8(d));\n        }\n\n        return (short) d;\n    }\n\n    /**\n     * Gets the D register number, as a nibble. This will throw if the\n     * value is out of the range of an unsigned nibble.\n     */\n    public final short getDNibble() {\n        int d = getD();\n\n        if ((d & ~0xf) != 0) {\n            throw new DexException(\"Register D out of range: \" + Hex.u8(d));\n        }\n\n        return (short) d;\n    }\n\n    /**\n     * Gets the E register number, as a nibble. This will throw if the\n     * value is out of the range of an unsigned nibble.\n     */\n    public final short getENibble() {\n        int e = getE();\n\n        if ((e & ~0xf) != 0) {\n            throw new DexException(\"Register E out of range: \" + Hex.u8(e));\n        }\n\n        return (short) e;\n    }\n\n    /**\n     * Encodes this instance to the given output.\n     */\n    public final void encode(CodeOutput out) {\n        format.encode(this, out);\n    }\n\n    /**\n     * Returns an instance just like this one, except with the index replaced\n     * with the given one.\n     */\n    public abstract DecodedInstruction withIndex(int newIndex);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/FillArrayDataPayloadDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\n/**\n * A decoded Dalvik instruction which contains the payload for\n * a {@code packed-switch} instruction.\n */\npublic final class FillArrayDataPayloadDecodedInstruction\n        extends DecodedInstruction {\n    /** data array */\n    private final Object data;\n\n    /** number of elements */\n    private final int size;\n\n    /** element width */\n    private final int elementWidth;\n\n    /**\n     * Constructs an instance. This private instance doesn't check the\n     * type of the data array.\n     */\n    private FillArrayDataPayloadDecodedInstruction(InstructionCodec format,\n            int opcode, Object data, int size, int elementWidth) {\n        super(format, opcode, 0, null, 0, 0L);\n\n        this.data = data;\n        this.size = size;\n        this.elementWidth = elementWidth;\n    }\n\n    /**\n     * Constructs an instance.\n     */\n    public FillArrayDataPayloadDecodedInstruction(InstructionCodec format,\n            int opcode, byte[] data) {\n        this(format, opcode, data, data.length, 1);\n    }\n\n    /**\n     * Constructs an instance.\n     */\n    public FillArrayDataPayloadDecodedInstruction(InstructionCodec format,\n            int opcode, short[] data) {\n        this(format, opcode, data, data.length, 2);\n    }\n\n    /**\n     * Constructs an instance.\n     */\n    public FillArrayDataPayloadDecodedInstruction(InstructionCodec format,\n            int opcode, int[] data) {\n        this(format, opcode, data, data.length, 4);\n    }\n\n    /**\n     * Constructs an instance.\n     */\n    public FillArrayDataPayloadDecodedInstruction(InstructionCodec format,\n            int opcode, long[] data) {\n        this(format, opcode, data, data.length, 8);\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 0;\n    }\n\n    public short getElementWidthUnit() {\n        return (short) elementWidth;\n    }\n\n    public int getSize() {\n        return size;\n    }\n\n    public Object getData() {\n        return data;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        throw new UnsupportedOperationException(\"no index in instruction\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/FiveRegisterDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\nimport com.taobao.android.dx.io.IndexType;\n\n/**\n * A decoded Dalvik instruction which has five register arguments.\n */\npublic final class FiveRegisterDecodedInstruction extends DecodedInstruction {\n    /** register argument \"A\" */\n    private final int a;\n\n    /** register argument \"B\" */\n    private final int b;\n\n    /** register argument \"C\" */\n    private final int c;\n\n    /** register argument \"D\" */\n    private final int d;\n\n    /** register argument \"E\" */\n    private final int e;\n\n    /**\n     * Constructs an instance.\n     */\n    public FiveRegisterDecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal,\n            int a, int b, int c, int d, int e) {\n        super(format, opcode, index, indexType, target, literal);\n\n        this.a = a;\n        this.b = b;\n        this.c = c;\n        this.d = d;\n        this.e = e;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 5;\n    }\n\n    /** @inheritDoc */\n    public int getA() {\n        return a;\n    }\n\n    /** @inheritDoc */\n    public int getB() {\n        return b;\n    }\n\n    /** @inheritDoc */\n    public int getC() {\n        return c;\n    }\n\n    /** @inheritDoc */\n    public int getD() {\n        return d;\n    }\n\n    /** @inheritDoc */\n    public int getE() {\n        return e;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        return new FiveRegisterDecodedInstruction(\n                getFormat(), getOpcode(), newIndex, getIndexType(),\n                getTarget(), getLiteral(), a, b, c, d, e);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/FourRegisterDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\nimport com.taobao.android.dx.io.IndexType;\n\n/**\n * A decoded Dalvik instruction which has five register arguments.\n */\npublic final class FourRegisterDecodedInstruction extends DecodedInstruction {\n    /** register argument \"A\" */\n    private final int a;\n\n    /** register argument \"B\" */\n    private final int b;\n\n    /** register argument \"C\" */\n    private final int c;\n\n    /** register argument \"D\" */\n    private final int d;\n\n    /**\n     * Constructs an instance.\n     */\n    public FourRegisterDecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal,\n            int a, int b, int c, int d) {\n        super(format, opcode, index, indexType, target, literal);\n\n        this.a = a;\n        this.b = b;\n        this.c = c;\n        this.d = d;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 4;\n    }\n\n    /** @inheritDoc */\n    public int getA() {\n        return a;\n    }\n\n    /** @inheritDoc */\n    public int getB() {\n        return b;\n    }\n\n    /** @inheritDoc */\n    public int getC() {\n        return c;\n    }\n\n    /** @inheritDoc */\n    public int getD() {\n        return d;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        return new FourRegisterDecodedInstruction(\n                getFormat(), getOpcode(), newIndex, getIndexType(),\n                getTarget(), getLiteral(), a, b, c, d);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/InstructionCodec.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\nimport com.taobao.android.dex.DexException;\nimport com.taobao.android.dx.io.IndexType;\nimport com.taobao.android.dx.io.OpcodeInfo;\nimport com.taobao.android.dx.io.Opcodes;\nimport com.taobao.android.dx.util.Hex;\nimport java.io.EOFException;\n\n/**\n * Representation of an instruction format, which knows how to decode into\n * and encode from instances of {@link DecodedInstruction}.\n */\npublic enum InstructionCodec {\n    FORMAT_00X() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            return new ZeroRegisterDecodedInstruction(\n                    this, opcodeUnit, 0, null,\n                    0, 0L);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(insn.getOpcodeUnit());\n        }\n    },\n\n    FORMAT_10X() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int literal = byte1(opcodeUnit); // should be zero\n            return new ZeroRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(insn.getOpcodeUnit());\n        }\n    },\n\n    FORMAT_12X() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = nibble2(opcodeUnit);\n            int b = nibble3(opcodeUnit);\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, 0L,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcodeUnit(),\n                             makeByte(insn.getA(), insn.getB())));\n        }\n    },\n\n    FORMAT_11N() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = nibble2(opcodeUnit);\n            int literal = (nibble3(opcodeUnit) << 28) >> 28; // sign-extend\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcodeUnit(),\n                             makeByte(insn.getA(), insn.getLiteralNibble())));\n        }\n    },\n\n    FORMAT_11X() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, 0L,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(codeUnit(insn.getOpcode(), insn.getA()));\n        }\n    },\n\n    FORMAT_10T() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.cursor() - 1;\n            int opcode = byte0(opcodeUnit);\n            int target = (byte) byte1(opcodeUnit); // sign-extend\n            return new ZeroRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    baseAddress + target, 0L);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            int relativeTarget = insn.getTargetByte(out.cursor());\n            out.write(codeUnit(insn.getOpcode(), relativeTarget));\n        }\n    },\n\n    FORMAT_20T() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.cursor() - 1;\n            int opcode = byte0(opcodeUnit);\n            int literal = byte1(opcodeUnit); // should be zero\n            int target = (short) in.read(); // sign-extend\n            return new ZeroRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    baseAddress + target, literal);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            short relativeTarget = insn.getTargetUnit(out.cursor());\n            out.write(insn.getOpcodeUnit(), relativeTarget);\n        }\n    },\n\n    FORMAT_20BC() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            // Note: We use the literal field to hold the decoded AA value.\n            int opcode = byte0(opcodeUnit);\n            int literal = byte1(opcodeUnit);\n            int index = in.read();\n            return new ZeroRegisterDecodedInstruction(\n                    this, opcode, index, IndexType.VARIES,\n                    0, literal);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getLiteralByte()),\n                    insn.getIndexUnit());\n        }\n    },\n\n    FORMAT_22X() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int b = in.read();\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, 0L,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    insn.getBUnit());\n        }\n    },\n\n    FORMAT_21T() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.cursor() - 1;\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int target = (short) in.read(); // sign-extend\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    baseAddress + target, 0L,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            short relativeTarget = insn.getTargetUnit(out.cursor());\n            out.write(codeUnit(insn.getOpcode(), insn.getA()), relativeTarget);\n        }\n    },\n\n    FORMAT_21S() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int literal = (short) in.read(); // sign-extend\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    insn.getLiteralUnit());\n        }\n    },\n\n    FORMAT_21H() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            long literal = (short) in.read(); // sign-extend\n\n            /*\n             * Format 21h decodes differently depending on the opcode,\n             * because the \"signed hat\" might represent either a 32-\n             * or 64- bit value.\n             */\n            literal <<= (opcode == Opcodes.CONST_HIGH16) ? 16 : 48;\n\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            // See above.\n            int opcode = insn.getOpcode();\n            int shift = (opcode == Opcodes.CONST_HIGH16) ? 16 : 48;\n            short literal = (short) (insn.getLiteral() >> shift);\n\n            out.write(codeUnit(opcode, insn.getA()), literal);\n        }\n    },\n\n    FORMAT_21C() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int index = in.read();\n            IndexType indexType = OpcodeInfo.getIndexType(opcode);\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, index, indexType,\n                    0, 0L,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    insn.getIndexUnit());\n        }\n    },\n\n    FORMAT_23X() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int bc = in.read();\n            int b = byte0(bc);\n            int c = byte1(bc);\n            return new ThreeRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, 0L,\n                    a, b, c);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    codeUnit(insn.getB(), insn.getC()));\n        }\n    },\n\n    FORMAT_22B() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int bc = in.read();\n            int b = byte0(bc);\n            int literal = (byte) byte1(bc); // sign-extend\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    codeUnit(insn.getB(),\n                             insn.getLiteralByte()));\n        }\n    },\n\n    FORMAT_22T() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.cursor() - 1;\n            int opcode = byte0(opcodeUnit);\n            int a = nibble2(opcodeUnit);\n            int b = nibble3(opcodeUnit);\n            int target = (short) in.read(); // sign-extend\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    baseAddress + target, 0L,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            short relativeTarget = insn.getTargetUnit(out.cursor());\n            out.write(\n                    codeUnit(insn.getOpcode(),\n                             makeByte(insn.getA(), insn.getB())),\n                    relativeTarget);\n        }\n    },\n\n    FORMAT_22S() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = nibble2(opcodeUnit);\n            int b = nibble3(opcodeUnit);\n            int literal = (short) in.read(); // sign-extend\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(),\n                             makeByte(insn.getA(), insn.getB())),\n                    insn.getLiteralUnit());\n        }\n    },\n\n    FORMAT_22C() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = nibble2(opcodeUnit);\n            int b = nibble3(opcodeUnit);\n            int index = in.read();\n            IndexType indexType = OpcodeInfo.getIndexType(opcode);\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, index, indexType,\n                    0, 0L,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(),\n                             makeByte(insn.getA(), insn.getB())),\n                    insn.getIndexUnit());\n        }\n    },\n\n    FORMAT_22CS() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = nibble2(opcodeUnit);\n            int b = nibble3(opcodeUnit);\n            int index = in.read();\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, index, IndexType.FIELD_OFFSET,\n                    0, 0L,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(),\n                             makeByte(insn.getA(), insn.getB())),\n                    insn.getIndexUnit());\n        }\n    },\n\n    FORMAT_30T() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.cursor() - 1;\n            int opcode = byte0(opcodeUnit);\n            int literal = byte1(opcodeUnit); // should be zero\n            int target = in.readInt();\n            return new ZeroRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    baseAddress + target, literal);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            int relativeTarget = insn.getTarget(out.cursor());\n            out.write(insn.getOpcodeUnit(),\n                    unit0(relativeTarget), unit1(relativeTarget));\n        }\n    },\n\n    FORMAT_32X() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int literal = byte1(opcodeUnit); // should be zero\n            int a = in.read();\n            int b = in.read();\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(insn.getOpcodeUnit(), insn.getAUnit(), insn.getBUnit());\n        }\n    },\n\n    FORMAT_31I() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int literal = in.readInt();\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            int literal = insn.getLiteralInt();\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    unit0(literal),\n                    unit1(literal));\n        }\n    },\n\n    FORMAT_31T() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.cursor() - 1;\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int target = baseAddress + in.readInt();\n\n            /*\n             * Switch instructions need to \"forward\" their addresses to their\n             * payload target instructions.\n             */\n            switch (opcode) {\n                case Opcodes.PACKED_SWITCH:\n                case Opcodes.SPARSE_SWITCH: {\n                    in.setBaseAddress(target, baseAddress);\n                    break;\n                }\n            }\n\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    target, 0L,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            int relativeTarget = insn.getTarget(out.cursor());\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    unit0(relativeTarget), unit1(relativeTarget));\n        }\n    },\n\n    FORMAT_31C() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int index = in.readInt();\n            IndexType indexType = OpcodeInfo.getIndexType(opcode);\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, index, indexType,\n                    0, 0L,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            int index = insn.getIndex();\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    unit0(index),\n                    unit1(index));\n        }\n    },\n\n    FORMAT_35C() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            return decodeRegisterList(this, opcodeUnit, in);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            encodeRegisterList(insn, out);\n        }\n    },\n\n    FORMAT_35MS() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            return decodeRegisterList(this, opcodeUnit, in);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            encodeRegisterList(insn, out);\n        }\n    },\n\n    FORMAT_35MI() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            return decodeRegisterList(this, opcodeUnit, in);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            encodeRegisterList(insn, out);\n        }\n    },\n\n    FORMAT_3RC() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            return decodeRegisterRange(this, opcodeUnit, in);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            encodeRegisterRange(insn, out);\n        }\n    },\n\n    FORMAT_3RMS() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            return decodeRegisterRange(this, opcodeUnit, in);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            encodeRegisterRange(insn, out);\n        }\n    },\n\n    FORMAT_3RMI() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            return decodeRegisterRange(this, opcodeUnit, in);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            encodeRegisterRange(insn, out);\n        }\n    },\n\n    FORMAT_51L() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            long literal = in.readLong();\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            long literal = insn.getLiteral();\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    unit0(literal),\n                    unit1(literal),\n                    unit2(literal),\n                    unit3(literal));\n        }\n    },\n\n    FORMAT_PACKED_SWITCH_PAYLOAD() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.baseAddressForCursor() - 1; // already read opcode\n            int size = in.read();\n            int firstKey = in.readInt();\n            int[] targets = new int[size];\n\n            for (int i = 0; i < size; i++) {\n                targets[i] = baseAddress + in.readInt();\n            }\n\n            return new PackedSwitchPayloadDecodedInstruction(\n                    this, opcodeUnit, firstKey, targets);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            PackedSwitchPayloadDecodedInstruction payload =\n                (PackedSwitchPayloadDecodedInstruction) insn;\n            int[] targets = payload.getTargets();\n            int baseAddress = out.baseAddressForCursor();\n\n            out.write(payload.getOpcodeUnit());\n            out.write(asUnsignedUnit(targets.length));\n            out.writeInt(payload.getFirstKey());\n\n            for (int target : targets) {\n                out.writeInt(target - baseAddress);\n            }\n        }\n    },\n\n    FORMAT_SPARSE_SWITCH_PAYLOAD() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.baseAddressForCursor() - 1; // already read opcode\n            int size = in.read();\n            int[] keys = new int[size];\n            int[] targets = new int[size];\n\n            for (int i = 0; i < size; i++) {\n                keys[i] = in.readInt();\n            }\n\n            for (int i = 0; i < size; i++) {\n                targets[i] = baseAddress + in.readInt();\n            }\n\n            return new SparseSwitchPayloadDecodedInstruction(\n                    this, opcodeUnit, keys, targets);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            SparseSwitchPayloadDecodedInstruction payload =\n                (SparseSwitchPayloadDecodedInstruction) insn;\n            int[] keys = payload.getKeys();\n            int[] targets = payload.getTargets();\n            int baseAddress = out.baseAddressForCursor();\n\n            out.write(payload.getOpcodeUnit());\n            out.write(asUnsignedUnit(targets.length));\n\n            for (int key : keys) {\n                out.writeInt(key);\n            }\n\n            for (int target : targets) {\n                out.writeInt(target - baseAddress);\n            }\n        }\n    },\n\n    FORMAT_FILL_ARRAY_DATA_PAYLOAD() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int elementWidth = in.read();\n            int size = in.readInt();\n\n            switch (elementWidth) {\n                case 1: {\n                    byte[] array = new byte[size];\n                    boolean even = true;\n                    for (int i = 0, value = 0; i < size; i++, even = !even) {\n                        if (even) {\n                            value = in.read();\n                        }\n                        array[i] = (byte) (value & 0xff);\n                        value >>= 8;\n                    }\n                    return new FillArrayDataPayloadDecodedInstruction(\n                            this, opcodeUnit, array);\n                }\n                case 2: {\n                    short[] array = new short[size];\n                    for (int i = 0; i < size; i++) {\n                        array[i] = (short) in.read();\n                    }\n                    return new FillArrayDataPayloadDecodedInstruction(\n                            this, opcodeUnit, array);\n                }\n                case 4: {\n                    int[] array = new int[size];\n                    for (int i = 0; i < size; i++) {\n                        array[i] = in.readInt();\n                    }\n                    return new FillArrayDataPayloadDecodedInstruction(\n                            this, opcodeUnit, array);\n                }\n                case 8: {\n                    long[] array = new long[size];\n                    for (int i = 0; i < size; i++) {\n                        array[i] = in.readLong();\n                    }\n                    return new FillArrayDataPayloadDecodedInstruction(\n                            this, opcodeUnit, array);\n                }\n            }\n\n            throw new DexException(\"bogus element_width: \"\n                    + Hex.u2(elementWidth));\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            FillArrayDataPayloadDecodedInstruction payload =\n                (FillArrayDataPayloadDecodedInstruction) insn;\n            short elementWidth = payload.getElementWidthUnit();\n            Object data = payload.getData();\n\n            out.write(payload.getOpcodeUnit());\n            out.write(elementWidth);\n            out.writeInt(payload.getSize());\n\n            switch (elementWidth) {\n                case 1: out.write((byte[]) data);  break;\n                case 2: out.write((short[]) data); break;\n                case 4: out.write((int[]) data);   break;\n                case 8: out.write((long[]) data);  break;\n                default: {\n                    throw new DexException(\"bogus element_width: \"\n                            + Hex.u2(elementWidth));\n                }\n            }\n        }\n    };\n\n    /**\n     * Decodes an instruction specified by the given opcode unit, reading\n     * any required additional code units from the given input source.\n     */\n    public abstract DecodedInstruction decode(int opcodeUnit, CodeInput in)\n        throws EOFException;\n\n    /**\n     * Encodes the given instruction.\n     */\n    public abstract void encode(DecodedInstruction insn, CodeOutput out);\n\n    /**\n     * Helper method that decodes any of the register-list formats.\n     */\n    private static DecodedInstruction decodeRegisterList(\n            InstructionCodec format, int opcodeUnit, CodeInput in)\n            throws EOFException {\n        int opcode = byte0(opcodeUnit);\n        int e = nibble2(opcodeUnit);\n        int registerCount = nibble3(opcodeUnit);\n        int index = in.read();\n        int abcd = in.read();\n        int a = nibble0(abcd);\n        int b = nibble1(abcd);\n        int c = nibble2(abcd);\n        int d = nibble3(abcd);\n        IndexType indexType = OpcodeInfo.getIndexType(opcode);\n\n        // TODO: Having to switch like this is less than ideal.\n        switch (registerCount) {\n            case 0:\n                return new ZeroRegisterDecodedInstruction(\n                        format, opcode, index, indexType,\n                        0, 0L);\n            case 1:\n                return new OneRegisterDecodedInstruction(\n                        format, opcode, index, indexType,\n                        0, 0L,\n                        a);\n            case 2:\n                return new TwoRegisterDecodedInstruction(\n                        format, opcode, index, indexType,\n                        0, 0L,\n                        a, b);\n            case 3:\n                return new ThreeRegisterDecodedInstruction(\n                        format, opcode, index, indexType,\n                        0, 0L,\n                        a, b, c);\n            case 4:\n                return new FourRegisterDecodedInstruction(\n                        format, opcode, index, indexType,\n                        0, 0L,\n                        a, b, c, d);\n            case 5:\n                return new FiveRegisterDecodedInstruction(\n                        format, opcode, index, indexType,\n                        0, 0L,\n                        a, b, c, d, e);\n        }\n\n        throw new DexException(\"bogus registerCount: \"\n                + Hex.uNibble(registerCount));\n    }\n\n    /**\n     * Helper method that encodes any of the register-list formats.\n     */\n    private static void encodeRegisterList(DecodedInstruction insn,\n            CodeOutput out) {\n        out.write(codeUnit(insn.getOpcode(),\n                        makeByte(insn.getE(), insn.getRegisterCount())),\n                insn.getIndexUnit(),\n                codeUnit(insn.getA(), insn.getB(), insn.getC(), insn.getD()));\n    }\n\n    /**\n     * Helper method that decodes any of the three-unit register-range formats.\n     */\n    private static DecodedInstruction decodeRegisterRange(\n            InstructionCodec format, int opcodeUnit, CodeInput in)\n            throws EOFException {\n        int opcode = byte0(opcodeUnit);\n        int registerCount = byte1(opcodeUnit);\n        int index = in.read();\n        int a = in.read();\n        IndexType indexType = OpcodeInfo.getIndexType(opcode);\n        return new RegisterRangeDecodedInstruction(\n                format, opcode, index, indexType,\n                0, 0L,\n                a, registerCount);\n    }\n\n    /**\n     * Helper method that encodes any of the three-unit register-range formats.\n     */\n    private static void encodeRegisterRange(DecodedInstruction insn,\n            CodeOutput out) {\n        out.write(codeUnit(insn.getOpcode(), insn.getRegisterCount()),\n                insn.getIndexUnit(),\n                insn.getAUnit());\n    }\n\n    private static short codeUnit(int lowByte, int highByte) {\n        if ((lowByte & ~0xff) != 0) {\n            throw new IllegalArgumentException(\"bogus lowByte\");\n        }\n\n        if ((highByte & ~0xff) != 0) {\n            throw new IllegalArgumentException(\"bogus highByte\");\n        }\n\n        return (short) (lowByte | (highByte << 8));\n    }\n\n    private static short codeUnit(int nibble0, int nibble1, int nibble2,\n            int nibble3) {\n        if ((nibble0 & ~0xf) != 0) {\n            throw new IllegalArgumentException(\"bogus nibble0\");\n        }\n\n        if ((nibble1 & ~0xf) != 0) {\n            throw new IllegalArgumentException(\"bogus nibble1\");\n        }\n\n        if ((nibble2 & ~0xf) != 0) {\n            throw new IllegalArgumentException(\"bogus nibble2\");\n        }\n\n        if ((nibble3 & ~0xf) != 0) {\n            throw new IllegalArgumentException(\"bogus nibble3\");\n        }\n\n        return (short) (nibble0 | (nibble1 << 4)\n                | (nibble2 << 8) | (nibble3 << 12));\n    }\n\n    private static int makeByte(int lowNibble, int highNibble) {\n        if ((lowNibble & ~0xf) != 0) {\n            throw new IllegalArgumentException(\"bogus lowNibble\");\n        }\n\n        if ((highNibble & ~0xf) != 0) {\n            throw new IllegalArgumentException(\"bogus highNibble\");\n        }\n\n        return lowNibble | (highNibble << 4);\n    }\n\n    private static short asUnsignedUnit(int value) {\n        if ((value & ~0xffff) != 0) {\n            throw new IllegalArgumentException(\"bogus unsigned code unit\");\n        }\n\n        return (short) value;\n    }\n\n    private static short unit0(int value) {\n        return (short) value;\n    }\n\n    private static short unit1(int value) {\n        return (short) (value >> 16);\n    }\n\n    private static short unit0(long value) {\n        return (short) value;\n    }\n\n    private static short unit1(long value) {\n        return (short) (value >> 16);\n    }\n\n    private static short unit2(long value) {\n        return (short) (value >> 32);\n    }\n\n    private static short unit3(long value) {\n        return (short) (value >> 48);\n    }\n\n    private static int byte0(int value) {\n        return value & 0xff;\n    }\n\n    private static int byte1(int value) {\n        return (value >> 8) & 0xff;\n    }\n\n    private static int byte2(int value) {\n        return (value >> 16) & 0xff;\n    }\n\n    private static int byte3(int value) {\n        return value >>> 24;\n    }\n\n    private static int nibble0(int value) {\n        return value & 0xf;\n    }\n\n    private static int nibble1(int value) {\n        return (value >> 4) & 0xf;\n    }\n\n    private static int nibble2(int value) {\n        return (value >> 8) & 0xf;\n    }\n\n    private static int nibble3(int value) {\n        return (value >> 12) & 0xf;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/OneRegisterDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\nimport com.taobao.android.dx.io.IndexType;\n\n/**\n * A decoded Dalvik instruction which has one register argument.\n */\npublic final class OneRegisterDecodedInstruction extends DecodedInstruction {\n    /** register argument \"A\" */\n    private final int a;\n\n    /**\n     * Constructs an instance.\n     */\n    public OneRegisterDecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal,\n            int a) {\n        super(format, opcode, index, indexType, target, literal);\n\n        this.a = a;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 1;\n    }\n\n    /** @inheritDoc */\n    public int getA() {\n        return a;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        return new OneRegisterDecodedInstruction(\n                getFormat(), getOpcode(), newIndex, getIndexType(),\n                getTarget(), getLiteral(), a);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/PackedSwitchPayloadDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\n/**\n * A decoded Dalvik instruction which contains the payload for\n * a {@code packed-switch} instruction.\n */\npublic final class PackedSwitchPayloadDecodedInstruction\n        extends DecodedInstruction {\n    /** first key value */\n    private final int firstKey;\n\n    /**\n     * array of target addresses. These are absolute, not relative,\n     * addresses.\n     */\n    private final int[] targets;\n\n    /**\n     * Constructs an instance.\n     */\n    public PackedSwitchPayloadDecodedInstruction(InstructionCodec format,\n            int opcode, int firstKey, int[] targets) {\n        super(format, opcode, 0, null, 0, 0L);\n\n        this.firstKey = firstKey;\n        this.targets = targets;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 0;\n    }\n\n    public int getFirstKey() {\n        return firstKey;\n    }\n\n    public int[] getTargets() {\n        return targets;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        throw new UnsupportedOperationException(\"no index in instruction\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/RegisterRangeDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\nimport com.taobao.android.dx.io.IndexType;\n\n/**\n * A decoded Dalvik instruction which has register range arguments (an\n * \"A\" start register and a register count).\n */\npublic final class RegisterRangeDecodedInstruction extends DecodedInstruction {\n    /** register argument \"A\" */\n    private final int a;\n\n    /** register count */\n    private final int registerCount;\n\n    /**\n     * Constructs an instance.\n     */\n    public RegisterRangeDecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal,\n            int a, int registerCount) {\n        super(format, opcode, index, indexType, target, literal);\n\n        this.a = a;\n        this.registerCount = registerCount;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return registerCount;\n    }\n\n    /** @inheritDoc */\n    public int getA() {\n        return a;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        return new RegisterRangeDecodedInstruction(\n                getFormat(), getOpcode(), newIndex, getIndexType(),\n                getTarget(), getLiteral(), a, registerCount);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/ShortArrayCodeInput.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\nimport java.io.EOFException;\n\n/**\n * Implementation of {@code CodeInput} that reads from a {@code short[]}.\n */\npublic final class ShortArrayCodeInput extends BaseCodeCursor\n        implements CodeInput {\n    /** source array to read from */\n    private final short[] array;\n\n    /**\n     * Constructs an instance.\n     */\n    public ShortArrayCodeInput(short[] array) {\n        if (array == null) {\n            throw new NullPointerException(\"array == null\");\n        }\n\n        this.array = array;\n    }\n\n    /** @inheritDoc */\n    public boolean hasMore() {\n        return cursor() < array.length;\n    }\n\n    /** @inheritDoc */\n    public int read() throws EOFException {\n        try {\n            int value = array[cursor()];\n            advance(1);\n            return value & 0xffff;\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            throw new EOFException();\n        }\n    }\n\n    /** @inheritDoc */\n    public int readInt() throws EOFException {\n        int short0 = read();\n        int short1 = read();\n\n        return short0 | (short1 << 16);\n    }\n\n    /** @inheritDoc */\n    public long readLong() throws EOFException {\n        long short0 = read();\n        long short1 = read();\n        long short2 = read();\n        long short3 = read();\n\n        return short0 | (short1 << 16) | (short2 << 32) | (short3 << 48);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/ShortArrayCodeOutput.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\n/**\n * Implementation of {@code CodeOutput} that writes to a {@code short[]}.\n */\npublic final class ShortArrayCodeOutput extends BaseCodeCursor\n        implements CodeOutput {\n    /** array to write to */\n    private final short[] array;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param maxSize the maximum number of code units that will be written\n     */\n    public ShortArrayCodeOutput(int maxSize) {\n        if (maxSize < 0) {\n            throw new IllegalArgumentException(\"maxSize < 0\");\n        }\n\n        this.array = new short[maxSize];\n    }\n\n    /**\n     * Gets the array. The returned array contains exactly the data\n     * written (e.g. no leftover space at the end).\n     */\n    public short[] getArray() {\n        int cursor = cursor();\n\n        if (cursor == array.length) {\n            return array;\n        }\n\n        short[] result = new short[cursor];\n        System.arraycopy(array, 0, result, 0, cursor);\n        return result;\n    }\n\n    /** @inheritDoc */\n    public void write(short codeUnit) {\n        array[cursor()] = codeUnit;\n        advance(1);\n    }\n\n    /** @inheritDoc */\n    public void write(short u0, short u1) {\n        write(u0);\n        write(u1);\n    }\n\n    /** @inheritDoc */\n    public void write(short u0, short u1, short u2) {\n        write(u0);\n        write(u1);\n        write(u2);\n    }\n\n    /** @inheritDoc */\n    public void write(short u0, short u1, short u2, short u3) {\n        write(u0);\n        write(u1);\n        write(u2);\n        write(u3);\n    }\n\n    /** @inheritDoc */\n    public void write(short u0, short u1, short u2, short u3, short u4) {\n        write(u0);\n        write(u1);\n        write(u2);\n        write(u3);\n        write(u4);\n    }\n\n    /** @inheritDoc */\n    public void writeInt(int value) {\n        write((short) value);\n        write((short) (value >> 16));\n    }\n\n    /** @inheritDoc */\n    public void writeLong(long value) {\n        write((short) value);\n        write((short) (value >> 16));\n        write((short) (value >> 32));\n        write((short) (value >> 48));\n    }\n\n    /** @inheritDoc */\n    public void write(byte[] data) {\n        int value = 0;\n        boolean even = true;\n        for (byte b : data) {\n            if (even) {\n                value = b & 0xff;\n                even = false;\n            } else {\n                value |= b << 8;\n                write((short) value);\n                even = true;\n            }\n        }\n\n        if (!even) {\n            write((short) value);\n        }\n    }\n\n    /** @inheritDoc */\n    public void write(short[] data) {\n        for (short unit : data) {\n            write(unit);\n        }\n    }\n\n    /** @inheritDoc */\n    public void write(int[] data) {\n        for (int i : data) {\n            writeInt(i);\n        }\n    }\n\n    /** @inheritDoc */\n    public void write(long[] data) {\n        for (long l : data) {\n            writeLong(l);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/SparseSwitchPayloadDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\n/**\n * A decoded Dalvik instruction which contains the payload for\n * a {@code packed-switch} instruction.\n */\npublic final class SparseSwitchPayloadDecodedInstruction\n        extends DecodedInstruction {\n    /** array of key values */\n    private final int[] keys;\n\n    /**\n     * array of target addresses. These are absolute, not relative,\n     * addresses.\n     */\n    private final int[] targets;\n\n    /**\n     * Constructs an instance.\n     */\n    public SparseSwitchPayloadDecodedInstruction(InstructionCodec format,\n            int opcode, int[] keys, int[] targets) {\n        super(format, opcode, 0, null, 0, 0L);\n\n        if (keys.length != targets.length) {\n            throw new IllegalArgumentException(\"keys/targets length mismatch\");\n        }\n\n        this.keys = keys;\n        this.targets = targets;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 0;\n    }\n\n    public int[] getKeys() {\n        return keys;\n    }\n\n    public int[] getTargets() {\n        return targets;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        throw new UnsupportedOperationException(\"no index in instruction\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/ThreeRegisterDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\nimport com.taobao.android.dx.io.IndexType;\n\n/**\n * A decoded Dalvik instruction which has three register arguments.\n */\npublic final class ThreeRegisterDecodedInstruction extends DecodedInstruction {\n    /** register argument \"A\" */\n    private final int a;\n\n    /** register argument \"B\" */\n    private final int b;\n\n    /** register argument \"C\" */\n    private final int c;\n\n    /**\n     * Constructs an instance.\n     */\n    public ThreeRegisterDecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal,\n            int a, int b, int c) {\n        super(format, opcode, index, indexType, target, literal);\n\n        this.a = a;\n        this.b = b;\n        this.c = c;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 3;\n    }\n\n    /** @inheritDoc */\n    public int getA() {\n        return a;\n    }\n\n    /** @inheritDoc */\n    public int getB() {\n        return b;\n    }\n\n    /** @inheritDoc */\n    public int getC() {\n        return c;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        return new ThreeRegisterDecodedInstruction(\n                getFormat(), getOpcode(), newIndex, getIndexType(),\n                getTarget(), getLiteral(), a, b, c);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/TwoRegisterDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\nimport com.taobao.android.dx.io.IndexType;\n\n/**\n * A decoded Dalvik instruction which has two register arguments.\n */\npublic final class TwoRegisterDecodedInstruction extends DecodedInstruction {\n    /** register argument \"A\" */\n    private final int a;\n\n    /** register argument \"B\" */\n    private final int b;\n\n    /**\n     * Constructs an instance.\n     */\n    public TwoRegisterDecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal,\n            int a, int b) {\n        super(format, opcode, index, indexType, target, literal);\n\n        this.a = a;\n        this.b = b;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 2;\n    }\n\n    /** @inheritDoc */\n    public int getA() {\n        return a;\n    }\n\n    /** @inheritDoc */\n    public int getB() {\n        return b;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        return new TwoRegisterDecodedInstruction(\n                getFormat(), getOpcode(), newIndex, getIndexType(),\n                getTarget(), getLiteral(), a, b);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/io/instructions/ZeroRegisterDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.io.instructions;\n\nimport com.taobao.android.dx.io.IndexType;\n\n/**\n * A decoded Dalvik instruction which has no register arguments.\n */\npublic final class ZeroRegisterDecodedInstruction extends DecodedInstruction {\n    /**\n     * Constructs an instance.\n     */\n    public ZeroRegisterDecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal) {\n        super(format, opcode, index, indexType, target, literal);\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 0;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        return new ZeroRegisterDecodedInstruction(\n                getFormat(), getOpcode(), newIndex, getIndexType(),\n                getTarget(), getLiteral());\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/merge/CollisionPolicy.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.merge;\n\n/**\n * What to do when two dex files define the same class.\n */\npublic enum CollisionPolicy {\n\n    /**\n     * Keep the class def from the first dex file and discard the def from the\n     * second dex file. This policy is appropriate for incremental builds.\n     */\n    KEEP_FIRST,\n\n    /**\n     * Forbid collisions. This policy is appropriate for merging libraries.\n     */\n    FAIL\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/merge/DexMerger.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.merge;\n\nimport com.taobao.android.dex.Annotation;\nimport com.taobao.android.dex.ClassData;\nimport com.taobao.android.dex.ClassDef;\nimport com.taobao.android.dex.Code;\nimport com.taobao.android.dex.Dex;\nimport com.taobao.android.dex.DexException;\nimport com.taobao.android.dex.DexIndexOverflowException;\nimport com.taobao.android.dex.FieldId;\nimport com.taobao.android.dex.MethodId;\nimport com.taobao.android.dex.ProtoId;\nimport com.taobao.android.dex.SizeOf;\nimport com.taobao.android.dex.TableOfContents;\nimport com.taobao.android.dex.TypeList;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\n\n/**\n * Combine two dex files into one.\n */\npublic final class DexMerger {\n    private final Dex[] dexes;\n    private final IndexMap[] indexMaps;\n\n    private final CollisionPolicy collisionPolicy;\n    private final WriterSizes writerSizes;\n\n    private final Dex dexOut;\n\n    private final Dex.Section headerOut;\n\n    /** All IDs and definitions sections */\n    private final Dex.Section idsDefsOut;\n\n    private final Dex.Section mapListOut;\n\n    private final Dex.Section typeListOut;\n\n    private final Dex.Section classDataOut;\n\n    private final Dex.Section codeOut;\n\n    private final Dex.Section stringDataOut;\n\n    private final Dex.Section debugInfoOut;\n\n    private final Dex.Section encodedArrayOut;\n\n    /** annotations directory on a type */\n    private final Dex.Section annotationsDirectoryOut;\n\n    /** sets of annotations on a member, parameter or type */\n    private final Dex.Section annotationSetOut;\n\n    /** parameter lists */\n    private final Dex.Section annotationSetRefListOut;\n\n    /** individual annotations, each containing zero or more fields */\n    private final Dex.Section annotationOut;\n\n    private final TableOfContents contentsOut;\n\n    private final InstructionTransformer instructionTransformer;\n\n    /** minimum number of wasted bytes before it's worthwhile to compact the result */\n    private int compactWasteThreshold = 1024 * 1024; // 1MiB\n\n    public DexMerger(Dex[] dexes, CollisionPolicy collisionPolicy)\n            throws IOException {\n        this(dexes, collisionPolicy, new WriterSizes(dexes));\n    }\n\n    public DexMerger(Dex[] dexes, CollisionPolicy collisionPolicy,\n                     WriterSizes writerSizes) throws IOException {\n        this.dexes = dexes;\n        this.collisionPolicy = collisionPolicy;\n        this.writerSizes = writerSizes;\n\n        dexOut = new Dex(writerSizes.size());\n\n        indexMaps = new IndexMap[dexes.length];\n        for (int i = 0; i < dexes.length; i++) {\n            indexMaps[i] = new IndexMap(dexOut, dexes[i].getTableOfContents());\n        }\n        instructionTransformer = new InstructionTransformer();\n\n        headerOut = dexOut.appendSection(writerSizes.header, \"header\");\n        idsDefsOut = dexOut.appendSection(writerSizes.idsDefs, \"ids defs\");\n\n        contentsOut = dexOut.getTableOfContents();\n        contentsOut.dataOff = dexOut.getNextSectionStart();\n\n        contentsOut.mapList.off = dexOut.getNextSectionStart();\n        contentsOut.mapList.size = 1;\n        mapListOut = dexOut.appendSection(writerSizes.mapList, \"map list\");\n\n        contentsOut.typeLists.off = dexOut.getNextSectionStart();\n        typeListOut = dexOut.appendSection(writerSizes.typeList, \"type list\");\n\n        contentsOut.annotationSetRefLists.off = dexOut.getNextSectionStart();\n        annotationSetRefListOut = dexOut.appendSection(\n                writerSizes.annotationsSetRefList, \"annotation set ref list\");\n\n        contentsOut.annotationSets.off = dexOut.getNextSectionStart();\n        annotationSetOut = dexOut.appendSection(writerSizes.annotationsSet, \"annotation sets\");\n\n        contentsOut.classDatas.off = dexOut.getNextSectionStart();\n        classDataOut = dexOut.appendSection(writerSizes.classData, \"class data\");\n\n        contentsOut.codes.off = dexOut.getNextSectionStart();\n        codeOut = dexOut.appendSection(writerSizes.code, \"code\");\n\n        contentsOut.stringDatas.off = dexOut.getNextSectionStart();\n        stringDataOut = dexOut.appendSection(writerSizes.stringData, \"string data\");\n\n        contentsOut.debugInfos.off = dexOut.getNextSectionStart();\n        debugInfoOut = dexOut.appendSection(writerSizes.debugInfo, \"debug info\");\n\n        contentsOut.annotations.off = dexOut.getNextSectionStart();\n        annotationOut = dexOut.appendSection(writerSizes.annotation, \"annotation\");\n\n        contentsOut.encodedArrays.off = dexOut.getNextSectionStart();\n        encodedArrayOut = dexOut.appendSection(writerSizes.encodedArray, \"encoded array\");\n\n        contentsOut.annotationsDirectories.off = dexOut.getNextSectionStart();\n        annotationsDirectoryOut = dexOut.appendSection(\n                writerSizes.annotationsDirectory, \"annotations directory\");\n\n        contentsOut.dataSize = dexOut.getNextSectionStart() - contentsOut.dataOff;\n    }\n\n    public void setCompactWasteThreshold(int compactWasteThreshold) {\n        this.compactWasteThreshold = compactWasteThreshold;\n    }\n\n    public Dex mergeDexes() throws IOException {\n        mergeStringIds();\n        mergeTypeIds();\n        mergeTypeLists();\n        mergeProtoIds();\n        mergeFieldIds();\n        mergeMethodIds();\n        mergeAnnotations();\n        unionAnnotationSetsAndDirectories();\n        mergeClassDefs();\n\n        // write the header\n        contentsOut.header.off = 0;\n        contentsOut.header.size = 1;\n        contentsOut.fileSize = dexOut.getLength();\n        contentsOut.computeSizesFromOffsets();\n        contentsOut.writeHeader(headerOut);\n        contentsOut.writeMap(mapListOut);\n\n        // generate and write the hashes\n        dexOut.writeHashes();\n\n        return dexOut;\n    }\n\n    public Dex merge() throws IOException {\n        if (dexes.length == 1) {\n            return dexes[0];\n        } else if (dexes.length == 0) {\n            return null;\n        }\n\n        long start = System.nanoTime();\n        Dex result = mergeDexes();\n\n        /*\n         * We use pessimistic sizes when merging dex files. If those sizes\n         * result in too many bytes wasted, compact the result. To compact,\n         * simply merge the result with itself.\n         */\n        WriterSizes compactedSizes = new WriterSizes(this);\n        int wastedByteCount = writerSizes.size() - compactedSizes.size();\n        if (wastedByteCount >  + compactWasteThreshold) {\n            DexMerger compacter = new DexMerger(\n                    new Dex[] {dexOut, new Dex(0)}, CollisionPolicy.FAIL, compactedSizes);\n            result = compacter.mergeDexes();\n            System.out.printf(\"Result compacted from %.1fKiB to %.1fKiB to save %.1fKiB%n\",\n                    dexOut.getLength() / 1024f,\n                    result.getLength() / 1024f,\n                    wastedByteCount / 1024f);\n        }\n\n        long elapsed = System.nanoTime() - start;\n        for (int i = 0; i < dexes.length; i++) {\n            System.out.printf(\"Merged dex #%d (%d defs/%.1fKiB)%n\",\n                i + 1,\n                dexes[i].getTableOfContents().classDefs.size,\n                dexes[i].getLength() / 1024f);\n        }\n        System.out.printf(\"Result is %d defs/%.1fKiB. Took %.1fs%n\",\n                result.getTableOfContents().classDefs.size,\n                result.getLength() / 1024f,\n                elapsed / 1000000000f);\n\n        return result;\n    }\n\n    /**\n     * Reads an IDs section of two dex files and writes an IDs section of a\n     * merged dex file. Populates maps from old to new indices in the process.\n     */\n    abstract class IdMerger<T extends Comparable<T>> {\n        private final Dex.Section out;\n\n        protected IdMerger(Dex.Section out) {\n            this.out = out;\n        }\n\n        /**\n         * Merges already-sorted sections, reading one value from each dex into memory\n         * at a time.\n         */\n        public final void mergeSorted() {\n            TableOfContents.Section[] sections = new TableOfContents.Section[dexes.length];\n            Dex.Section[] dexSections = new Dex.Section[dexes.length];\n            int[] offsets = new int[dexes.length];\n            int[] indexes = new int[dexes.length];\n\n            // values contains one value from each dex, sorted for fast retrieval of\n            // the smallest value. The list associated with a value has the indexes\n            // of the dexes that had that value.\n            TreeMap<T, List<Integer>> values = new TreeMap<T, List<Integer>>();\n\n            for (int i = 0; i < dexes.length; i++) {\n                sections[i] = getSection(dexes[i].getTableOfContents());\n                dexSections[i] = sections[i].exists() ? dexes[i].open(sections[i].off) : null;\n                // Fill in values with the first value of each dex.\n                offsets[i] = readIntoMap(\n                        dexSections[i], sections[i], indexMaps[i], indexes[i], values, i);\n            }\n\n            getSection(contentsOut).off = out.getPosition();\n\n\n\n            int outCount = 0;\n            while (!values.isEmpty()) {\n                Map.Entry<T, List<Integer>> first = values.pollFirstEntry();\n                for (Integer dex : first.getValue()) {\n                    updateIndex(offsets[dex], indexMaps[dex], indexes[dex]++, outCount);\n                    // Fetch the next value of the dexes we just polled out\n                    offsets[dex] = readIntoMap(dexSections[dex], sections[dex],\n                            indexMaps[dex], indexes[dex], values, dex);\n                }\n                write(first.getKey());\n                outCount++;\n            }\n\n            getSection(contentsOut).size = outCount;\n        }\n\n        private int readIntoMap(Dex.Section in, TableOfContents.Section section, IndexMap indexMap,\n                                int index, TreeMap<T, List<Integer>> values, int dex) {\n            int offset = in != null ? in.getPosition() : -1;\n            if (index < section.size) {\n                T v = read(in, indexMap, index);\n                List<Integer> l = values.get(v);\n                if (l == null) {\n                    l = new ArrayList<Integer>();\n                    values.put(v, l);\n                }\n                l.add(new Integer(dex));\n            }\n            return offset;\n        }\n\n        /**\n         * Merges unsorted sections by reading them completely into memory and\n         * sorting in memory.\n         */\n        public final void mergeUnsorted() {\n            getSection(contentsOut).off = out.getPosition();\n\n            List<UnsortedValue> all = new ArrayList<UnsortedValue>();\n            for (int i = 0; i < dexes.length; i++) {\n                all.addAll(readUnsortedValues(dexes[i], indexMaps[i]));\n            }\n            Collections.sort(all);\n\n            int outCount = 0;\n            for (int i = 0; i < all.size(); ) {\n                UnsortedValue e1 = all.get(i++);\n                updateIndex(e1.offset, e1.indexMap, e1.index, outCount - 1);\n\n                while (i < all.size() && e1.compareTo(all.get(i)) == 0) {\n                    UnsortedValue e2 = all.get(i++);\n                    updateIndex(e2.offset, e2.indexMap, e2.index, outCount - 1);\n                }\n\n                write(e1.value);\n                outCount++;\n            }\n\n            getSection(contentsOut).size = outCount;\n        }\n\n        private List<UnsortedValue> readUnsortedValues(Dex source, IndexMap indexMap) {\n            TableOfContents.Section section = getSection(source.getTableOfContents());\n            if (!section.exists()) {\n                return Collections.emptyList();\n            }\n\n            List<UnsortedValue> result = new ArrayList<UnsortedValue>();\n            Dex.Section in = source.open(section.off);\n            for (int i = 0; i < section.size; i++) {\n                int offset = in.getPosition();\n                T value = read(in, indexMap, 0);\n                result.add(new UnsortedValue(source, indexMap, value, i, offset));\n            }\n            return result;\n        }\n\n        abstract TableOfContents.Section getSection(TableOfContents tableOfContents);\n        abstract T read(Dex.Section in, IndexMap indexMap, int index);\n        abstract void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex);\n        abstract void write(T value);\n\n        class UnsortedValue implements Comparable<UnsortedValue> {\n            final Dex source;\n            final IndexMap indexMap;\n            final T value;\n            final int index;\n            final int offset;\n\n            UnsortedValue(Dex source, IndexMap indexMap, T value, int index, int offset) {\n                this.source = source;\n                this.indexMap = indexMap;\n                this.value = value;\n                this.index = index;\n                this.offset = offset;\n            }\n\n            public int compareTo(UnsortedValue unsortedValue) {\n                return value.compareTo(unsortedValue.value);\n            }\n        }\n    }\n\n\n    private void mergeStringIds() {\n        new IdMerger<String>(idsDefsOut) {\n            @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.stringIds;\n            }\n\n            @Override String read(Dex.Section in, IndexMap indexMap, int index) {\n                return in.readString();\n            }\n\n            @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                indexMap.stringIds[oldIndex] = newIndex;\n            }\n\n            @Override void write(String value) {\n                contentsOut.stringDatas.size++;\n                idsDefsOut.writeInt(stringDataOut.getPosition());\n                stringDataOut.writeStringData(value);\n            }\n        }.mergeSorted();\n    }\n\n    private void mergeTypeIds() {\n        new IdMerger<Integer>(idsDefsOut) {\n            @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.typeIds;\n            }\n\n            @Override Integer read(Dex.Section in, IndexMap indexMap, int index) {\n                int stringIndex = in.readInt();\n                return indexMap.adjustString(stringIndex);\n            }\n\n            @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                if (newIndex < 0 || newIndex > 0xffff) {\n                    throw new DexIndexOverflowException(\"type ID not in [0, 0xffff]: \" + newIndex);\n                }\n                indexMap.typeIds[oldIndex] = (short) newIndex;\n            }\n\n            @Override void write(Integer value) {\n                idsDefsOut.writeInt(value);\n            }\n        }.mergeSorted();\n    }\n\n    private void mergeTypeLists() {\n        new IdMerger<TypeList>(typeListOut) {\n            @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.typeLists;\n            }\n\n            @Override TypeList read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjustTypeList(in.readTypeList());\n            }\n\n            @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                indexMap.putTypeListOffset(offset, typeListOut.getPosition());\n            }\n\n            @Override void write(TypeList value) {\n                typeListOut.writeTypeList(value);\n            }\n        }.mergeUnsorted();\n    }\n\n    private void mergeProtoIds() {\n        new IdMerger<ProtoId>(idsDefsOut) {\n            @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.protoIds;\n            }\n\n            @Override ProtoId read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjust(in.readProtoId());\n            }\n\n            @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                if (newIndex < 0 || newIndex > 0xffff) {\n                    throw new DexIndexOverflowException(\"proto ID not in [0, 0xffff]: \" + newIndex);\n                }\n                indexMap.protoIds[oldIndex] = (short) newIndex;\n            }\n\n            @Override void write(ProtoId value) {\n                value.writeTo(idsDefsOut);\n            }\n        }.mergeSorted();\n    }\n\n    private void mergeFieldIds() {\n        new IdMerger<FieldId>(idsDefsOut) {\n            @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.fieldIds;\n            }\n\n            @Override FieldId read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjust(in.readFieldId());\n            }\n\n            @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                if (newIndex < 0 || newIndex > 0xffff) {\n                    throw new DexIndexOverflowException(\"field ID not in [0, 0xffff]: \" + newIndex);\n                }\n                indexMap.fieldIds[oldIndex] = (short) newIndex;\n            }\n\n            @Override void write(FieldId value) {\n                value.writeTo(idsDefsOut);\n            }\n        }.mergeSorted();\n    }\n\n    private void mergeMethodIds() {\n        new IdMerger<MethodId>(idsDefsOut) {\n            @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.methodIds;\n            }\n\n            @Override MethodId read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjust(in.readMethodId());\n            }\n\n            @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                if (newIndex < 0 || newIndex > 0xffff) {\n                    throw new DexIndexOverflowException(\n                        \"method ID not in [0, 0xffff]: \" + newIndex);\n                }\n                indexMap.methodIds[oldIndex] = (short) newIndex;\n            }\n\n            @Override void write(MethodId methodId) {\n                methodId.writeTo(idsDefsOut);\n            }\n        }.mergeSorted();\n    }\n\n    private void mergeAnnotations() {\n        new IdMerger<Annotation>(annotationOut) {\n            @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.annotations;\n            }\n\n            @Override Annotation read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjust(in.readAnnotation());\n            }\n\n            @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                indexMap.putAnnotationOffset(offset, annotationOut.getPosition());\n            }\n\n            @Override void write(Annotation value) {\n                value.writeTo(annotationOut);\n            }\n        }.mergeUnsorted();\n    }\n\n    private void mergeClassDefs() {\n        SortableType[] types = getSortedTypes();\n        contentsOut.classDefs.off = idsDefsOut.getPosition();\n        contentsOut.classDefs.size = types.length;\n\n        for (SortableType type : types) {\n            Dex in = type.getDex();\n            transformClassDef(in, type.getClassDef(), type.getIndexMap());\n        }\n    }\n\n    /**\n     * Returns the union of classes from both files, sorted in order such that\n     * a class is always preceded by its supertype and implemented interfaces.\n     */\n    private SortableType[] getSortedTypes() {\n        // size is pessimistic; doesn't include arrays\n        SortableType[] sortableTypes = new SortableType[contentsOut.typeIds.size];\n        for (int i = 0; i < dexes.length; i++) {\n            readSortableTypes(sortableTypes, dexes[i], indexMaps[i]);\n        }\n\n        /*\n         * Populate the depths of each sortable type. This makes D iterations\n         * through all N types, where 'D' is the depth of the deepest type. For\n         * example, the deepest class in libcore is Xalan's KeyIterator, which\n         * is 11 types deep.\n         */\n        while (true) {\n            boolean allDone = true;\n            for (SortableType sortableType : sortableTypes) {\n                if (sortableType != null && !sortableType.isDepthAssigned()) {\n                    allDone &= sortableType.tryAssignDepth(sortableTypes);\n                }\n            }\n            if (allDone) {\n                break;\n            }\n        }\n\n        // Now that all types have depth information, the result can be sorted\n        Arrays.sort(sortableTypes, SortableType.NULLS_LAST_ORDER);\n\n        // Strip nulls from the end\n        int firstNull = Arrays.asList(sortableTypes).indexOf(null);\n        return firstNull != -1\n                ? Arrays.copyOfRange(sortableTypes, 0, firstNull)\n                : sortableTypes;\n    }\n\n    /**\n     * Reads just enough data on each class so that we can sort it and then find\n     * it later.\n     */\n    private void readSortableTypes(SortableType[] sortableTypes, Dex buffer,\n            IndexMap indexMap) {\n        for (ClassDef classDef : buffer.classDefs()) {\n            SortableType sortableType = indexMap.adjust(\n                    new SortableType(buffer, indexMap, classDef));\n            int t = sortableType.getTypeIndex();\n            if (sortableTypes[t] == null) {\n                sortableTypes[t] = sortableType;\n            } else if (collisionPolicy != CollisionPolicy.KEEP_FIRST) {\n                throw new DexException(\"Multiple dex files define \"\n                        + buffer.typeNames().get(classDef.getTypeIndex()));\n            }\n        }\n    }\n\n    /**\n     * Copy annotation sets from each input to the output.\n     *\n     * TODO: this may write multiple copies of the same annotation set.\n     * We should shrink the output by merging rather than unioning\n     */\n    private void unionAnnotationSetsAndDirectories() {\n        for (int i = 0; i < dexes.length; i++) {\n            transformAnnotationSets(dexes[i], indexMaps[i]);\n        }\n        for (int i = 0; i < dexes.length; i++) {\n            transformAnnotationSetRefLists(dexes[i], indexMaps[i]);\n        }\n        for (int i = 0; i < dexes.length; i++) {\n            transformAnnotationDirectories(dexes[i], indexMaps[i]);\n        }\n        for (int i = 0; i < dexes.length; i++) {\n            transformStaticValues(dexes[i], indexMaps[i]);\n        }\n    }\n\n    private void transformAnnotationSets(Dex in, IndexMap indexMap) {\n        TableOfContents.Section section = in.getTableOfContents().annotationSets;\n        if (section.exists()) {\n            Dex.Section setIn = in.open(section.off);\n            for (int i = 0; i < section.size; i++) {\n                transformAnnotationSet(indexMap, setIn);\n            }\n        }\n    }\n\n    private void transformAnnotationSetRefLists(Dex in, IndexMap indexMap) {\n        TableOfContents.Section section = in.getTableOfContents().annotationSetRefLists;\n        if (section.exists()) {\n            Dex.Section setIn = in.open(section.off);\n            for (int i = 0; i < section.size; i++) {\n                transformAnnotationSetRefList(indexMap, setIn);\n            }\n        }\n    }\n\n    private void transformAnnotationDirectories(Dex in, IndexMap indexMap) {\n        TableOfContents.Section section = in.getTableOfContents().annotationsDirectories;\n        if (section.exists()) {\n            Dex.Section directoryIn = in.open(section.off);\n            for (int i = 0; i < section.size; i++) {\n                transformAnnotationDirectory(directoryIn, indexMap);\n            }\n        }\n    }\n\n    private void transformStaticValues(Dex in, IndexMap indexMap) {\n        TableOfContents.Section section = in.getTableOfContents().encodedArrays;\n        if (section.exists()) {\n            Dex.Section staticValuesIn = in.open(section.off);\n            for (int i = 0; i < section.size; i++) {\n                transformStaticValues(staticValuesIn, indexMap);\n            }\n        }\n    }\n\n    /**\n     * Reads a class_def_item beginning at {@code in} and writes the index and\n     * data.\n     */\n    private void transformClassDef(Dex in, ClassDef classDef, IndexMap indexMap) {\n        idsDefsOut.assertFourByteAligned();\n        idsDefsOut.writeInt(classDef.getTypeIndex());\n        idsDefsOut.writeInt(classDef.getAccessFlags());\n        idsDefsOut.writeInt(classDef.getSupertypeIndex());\n        idsDefsOut.writeInt(classDef.getInterfacesOffset());\n\n        int sourceFileIndex = indexMap.adjustString(classDef.getSourceFileIndex());\n        idsDefsOut.writeInt(sourceFileIndex);\n\n        int annotationsOff = classDef.getAnnotationsOffset();\n        idsDefsOut.writeInt(indexMap.adjustAnnotationDirectory(annotationsOff));\n\n        int classDataOff = classDef.getClassDataOffset();\n        if (classDataOff == 0) {\n            idsDefsOut.writeInt(0);\n        } else {\n            idsDefsOut.writeInt(classDataOut.getPosition());\n            ClassData classData = in.readClassData(classDef);\n            transformClassData(in, classData, indexMap);\n        }\n\n        int staticValuesOff = classDef.getStaticValuesOffset();\n        idsDefsOut.writeInt(indexMap.adjustStaticValues(staticValuesOff));\n    }\n\n    /**\n     * Transform all annotations on a class.\n     */\n    private void transformAnnotationDirectory(\n            Dex.Section directoryIn, IndexMap indexMap) {\n        contentsOut.annotationsDirectories.size++;\n        annotationsDirectoryOut.assertFourByteAligned();\n        indexMap.putAnnotationDirectoryOffset(\n                directoryIn.getPosition(), annotationsDirectoryOut.getPosition());\n\n        int classAnnotationsOffset = indexMap.adjustAnnotationSet(directoryIn.readInt());\n        annotationsDirectoryOut.writeInt(classAnnotationsOffset);\n\n        int fieldsSize = directoryIn.readInt();\n        annotationsDirectoryOut.writeInt(fieldsSize);\n\n        int methodsSize = directoryIn.readInt();\n        annotationsDirectoryOut.writeInt(methodsSize);\n\n        int parameterListSize = directoryIn.readInt();\n        annotationsDirectoryOut.writeInt(parameterListSize);\n\n        for (int i = 0; i < fieldsSize; i++) {\n            // field index\n            annotationsDirectoryOut.writeInt(indexMap.adjustField(directoryIn.readInt()));\n\n            // annotations offset\n            annotationsDirectoryOut.writeInt(indexMap.adjustAnnotationSet(directoryIn.readInt()));\n        }\n\n        for (int i = 0; i < methodsSize; i++) {\n            // method index\n            annotationsDirectoryOut.writeInt(indexMap.adjustMethod(directoryIn.readInt()));\n\n            // annotation set offset\n            annotationsDirectoryOut.writeInt(\n                    indexMap.adjustAnnotationSet(directoryIn.readInt()));\n        }\n\n        for (int i = 0; i < parameterListSize; i++) {\n            // method index\n            annotationsDirectoryOut.writeInt(indexMap.adjustMethod(directoryIn.readInt()));\n\n            // annotations offset\n            annotationsDirectoryOut.writeInt(\n                    indexMap.adjustAnnotationSetRefList(directoryIn.readInt()));\n        }\n    }\n\n    /**\n     * Transform all annotations on a single type, member or parameter.\n     */\n    private void transformAnnotationSet(IndexMap indexMap, Dex.Section setIn) {\n        contentsOut.annotationSets.size++;\n        annotationSetOut.assertFourByteAligned();\n        indexMap.putAnnotationSetOffset(setIn.getPosition(), annotationSetOut.getPosition());\n\n        int size = setIn.readInt();\n        annotationSetOut.writeInt(size);\n\n        for (int j = 0; j < size; j++) {\n            annotationSetOut.writeInt(indexMap.adjustAnnotation(setIn.readInt()));\n        }\n    }\n\n    /**\n     * Transform all annotation set ref lists.\n     */\n    private void transformAnnotationSetRefList(IndexMap indexMap, Dex.Section refListIn) {\n        contentsOut.annotationSetRefLists.size++;\n        annotationSetRefListOut.assertFourByteAligned();\n        indexMap.putAnnotationSetRefListOffset(\n                refListIn.getPosition(), annotationSetRefListOut.getPosition());\n\n        int parameterCount = refListIn.readInt();\n        annotationSetRefListOut.writeInt(parameterCount);\n        for (int p = 0; p < parameterCount; p++) {\n            annotationSetRefListOut.writeInt(indexMap.adjustAnnotationSet(refListIn.readInt()));\n        }\n    }\n\n    private void transformClassData(Dex in, ClassData classData, IndexMap indexMap) {\n        contentsOut.classDatas.size++;\n\n        ClassData.Field[] staticFields = classData.getStaticFields();\n        ClassData.Field[] instanceFields = classData.getInstanceFields();\n        ClassData.Method[] directMethods = classData.getDirectMethods();\n        ClassData.Method[] virtualMethods = classData.getVirtualMethods();\n\n        classDataOut.writeUleb128(staticFields.length);\n        classDataOut.writeUleb128(instanceFields.length);\n        classDataOut.writeUleb128(directMethods.length);\n        classDataOut.writeUleb128(virtualMethods.length);\n\n        transformFields(indexMap, staticFields);\n        transformFields(indexMap, instanceFields);\n        transformMethods(in, indexMap, directMethods);\n        transformMethods(in, indexMap, virtualMethods);\n    }\n\n    private void transformFields(IndexMap indexMap, ClassData.Field[] fields) {\n        int lastOutFieldIndex = 0;\n        for (ClassData.Field field : fields) {\n            int outFieldIndex = indexMap.adjustField(field.getFieldIndex());\n            classDataOut.writeUleb128(outFieldIndex - lastOutFieldIndex);\n            lastOutFieldIndex = outFieldIndex;\n            classDataOut.writeUleb128(field.getAccessFlags());\n        }\n    }\n\n    private void transformMethods(Dex in, IndexMap indexMap, ClassData.Method[] methods) {\n        int lastOutMethodIndex = 0;\n        for (ClassData.Method method : methods) {\n            int outMethodIndex = indexMap.adjustMethod(method.getMethodIndex());\n            classDataOut.writeUleb128(outMethodIndex - lastOutMethodIndex);\n            lastOutMethodIndex = outMethodIndex;\n\n            classDataOut.writeUleb128(method.getAccessFlags());\n\n            if (method.getCodeOffset() == 0) {\n                classDataOut.writeUleb128(0);\n            } else {\n                codeOut.alignToFourBytesWithZeroFill();\n                classDataOut.writeUleb128(codeOut.getPosition());\n                transformCode(in, in.readCode(method), indexMap);\n            }\n        }\n    }\n\n    private void transformCode(Dex in, Code code, IndexMap indexMap) {\n        contentsOut.codes.size++;\n        codeOut.assertFourByteAligned();\n\n        codeOut.writeUnsignedShort(code.getRegistersSize());\n        codeOut.writeUnsignedShort(code.getInsSize());\n        codeOut.writeUnsignedShort(code.getOutsSize());\n\n        Code.Try[] tries = code.getTries();\n        Code.CatchHandler[] catchHandlers = code.getCatchHandlers();\n        codeOut.writeUnsignedShort(tries.length);\n\n        int debugInfoOffset = code.getDebugInfoOffset();\n        if (debugInfoOffset != 0) {\n            codeOut.writeInt(debugInfoOut.getPosition());\n            transformDebugInfoItem(in.open(debugInfoOffset), indexMap);\n        } else {\n            codeOut.writeInt(0);\n        }\n\n        short[] instructions = code.getInstructions();\n        short[] newInstructions = instructionTransformer.transform(indexMap, instructions);\n        codeOut.writeInt(newInstructions.length);\n        codeOut.write(newInstructions);\n\n        if (tries.length > 0) {\n            if (newInstructions.length % 2 == 1) {\n                codeOut.writeShort((short) 0); // padding\n            }\n\n            /*\n             * We can't write the tries until we've written the catch handlers.\n             * Unfortunately they're in the opposite order in the dex file so we\n             * need to transform them out-of-order.\n             */\n            Dex.Section triesSection = dexOut.open(codeOut.getPosition());\n            codeOut.skip(tries.length * SizeOf.TRY_ITEM);\n            int[] offsets = transformCatchHandlers(indexMap, catchHandlers);\n            transformTries(triesSection, tries, offsets);\n        }\n    }\n\n    /**\n     * Writes the catch handlers to {@code codeOut} and returns their indices.\n     */\n    private int[] transformCatchHandlers(IndexMap indexMap, Code.CatchHandler[] catchHandlers) {\n        int baseOffset = codeOut.getPosition();\n        codeOut.writeUleb128(catchHandlers.length);\n        int[] offsets = new int[catchHandlers.length];\n        for (int i = 0; i < catchHandlers.length; i++) {\n            offsets[i] = codeOut.getPosition() - baseOffset;\n            transformEncodedCatchHandler(catchHandlers[i], indexMap);\n        }\n        return offsets;\n    }\n\n    private void transformTries(Dex.Section out, Code.Try[] tries,\n            int[] catchHandlerOffsets) {\n        for (Code.Try tryItem : tries) {\n            out.writeInt(tryItem.getStartAddress());\n            out.writeUnsignedShort(tryItem.getInstructionCount());\n            out.writeUnsignedShort(catchHandlerOffsets[tryItem.getCatchHandlerIndex()]);\n        }\n    }\n\n    private static final byte DBG_END_SEQUENCE = 0x00;\n    private static final byte DBG_ADVANCE_PC = 0x01;\n    private static final byte DBG_ADVANCE_LINE = 0x02;\n    private static final byte DBG_START_LOCAL = 0x03;\n    private static final byte DBG_START_LOCAL_EXTENDED = 0x04;\n    private static final byte DBG_END_LOCAL = 0x05;\n    private static final byte DBG_RESTART_LOCAL = 0x06;\n    private static final byte DBG_SET_PROLOGUE_END = 0x07;\n    private static final byte DBG_SET_EPILOGUE_BEGIN = 0x08;\n    private static final byte DBG_SET_FILE = 0x09;\n\n    private void transformDebugInfoItem(Dex.Section in, IndexMap indexMap) {\n        contentsOut.debugInfos.size++;\n        int lineStart = in.readUleb128();\n        debugInfoOut.writeUleb128(lineStart);\n\n        int parametersSize = in.readUleb128();\n        debugInfoOut.writeUleb128(parametersSize);\n\n        for (int p = 0; p < parametersSize; p++) {\n            int parameterName = in.readUleb128p1();\n            debugInfoOut.writeUleb128p1(indexMap.adjustString(parameterName));\n        }\n\n        int addrDiff;    // uleb128   address delta.\n        int lineDiff;    // sleb128   line delta.\n        int registerNum; // uleb128   register number.\n        int nameIndex;   // uleb128p1 string index.    Needs indexMap adjustment.\n        int typeIndex;   // uleb128p1 type index.      Needs indexMap adjustment.\n        int sigIndex;    // uleb128p1 string index.    Needs indexMap adjustment.\n\n        while (true) {\n            int opcode = in.readByte();\n            debugInfoOut.writeByte(opcode);\n\n            switch (opcode) {\n            case DBG_END_SEQUENCE:\n                return;\n\n            case DBG_ADVANCE_PC:\n                addrDiff = in.readUleb128();\n                debugInfoOut.writeUleb128(addrDiff);\n                break;\n\n            case DBG_ADVANCE_LINE:\n                lineDiff = in.readSleb128();\n                debugInfoOut.writeSleb128(lineDiff);\n                break;\n\n            case DBG_START_LOCAL:\n            case DBG_START_LOCAL_EXTENDED:\n                registerNum = in.readUleb128();\n                debugInfoOut.writeUleb128(registerNum);\n                nameIndex = in.readUleb128p1();\n                debugInfoOut.writeUleb128p1(indexMap.adjustString(nameIndex));\n                typeIndex = in.readUleb128p1();\n                debugInfoOut.writeUleb128p1(indexMap.adjustType(typeIndex));\n                if (opcode == DBG_START_LOCAL_EXTENDED) {\n                    sigIndex = in.readUleb128p1();\n                    debugInfoOut.writeUleb128p1(indexMap.adjustString(sigIndex));\n                }\n                break;\n\n            case DBG_END_LOCAL:\n            case DBG_RESTART_LOCAL:\n                registerNum = in.readUleb128();\n                debugInfoOut.writeUleb128(registerNum);\n                break;\n\n            case DBG_SET_FILE:\n                nameIndex = in.readUleb128p1();\n                debugInfoOut.writeUleb128p1(indexMap.adjustString(nameIndex));\n                break;\n\n            case DBG_SET_PROLOGUE_END:\n            case DBG_SET_EPILOGUE_BEGIN:\n            default:\n                break;\n            }\n        }\n    }\n\n    private void transformEncodedCatchHandler(Code.CatchHandler catchHandler, IndexMap indexMap) {\n        int catchAllAddress = catchHandler.getCatchAllAddress();\n        int[] typeIndexes = catchHandler.getTypeIndexes();\n        int[] addresses = catchHandler.getAddresses();\n\n        if (catchAllAddress != -1) {\n            codeOut.writeSleb128(-typeIndexes.length);\n        } else {\n            codeOut.writeSleb128(typeIndexes.length);\n        }\n\n        for (int i = 0; i < typeIndexes.length; i++) {\n            codeOut.writeUleb128(indexMap.adjustType(typeIndexes[i]));\n            codeOut.writeUleb128(addresses[i]);\n        }\n\n        if (catchAllAddress != -1) {\n            codeOut.writeUleb128(catchAllAddress);\n        }\n    }\n\n    private void transformStaticValues(Dex.Section in, IndexMap indexMap) {\n        contentsOut.encodedArrays.size++;\n        indexMap.putStaticValuesOffset(in.getPosition(), encodedArrayOut.getPosition());\n        indexMap.adjustEncodedArray(in.readEncodedArray()).writeTo(encodedArrayOut);\n    }\n\n    /**\n     * Byte counts for the sections written when creating a dex. Target sizes\n     * are defined in one of two ways:\n     * <ul>\n     * <li>By pessimistically guessing how large the union of dex files will be.\n     *     We're pessimistic because we can't predict the amount of duplication\n     *     between dex files, nor can we predict the length of ULEB-encoded\n     *     offsets or indices.\n     * <li>By exactly measuring an existing dex.\n     * </ul>\n     */\n    private static class WriterSizes {\n        private int header = SizeOf.HEADER_ITEM;\n        private int idsDefs;\n        private int mapList;\n        private int typeList;\n        private int classData;\n        private int code;\n        private int stringData;\n        private int debugInfo;\n        private int encodedArray;\n        private int annotationsDirectory;\n        private int annotationsSet;\n        private int annotationsSetRefList;\n        private int annotation;\n\n        /**\n         * Compute sizes for merging several dexes.\n         */\n        public WriterSizes(Dex[] dexes) {\n            for (int i = 0; i < dexes.length; i++) {\n                plus(dexes[i].getTableOfContents(), false);\n            }\n            fourByteAlign();\n        }\n\n        public WriterSizes(DexMerger dexMerger) {\n            header = dexMerger.headerOut.used();\n            idsDefs = dexMerger.idsDefsOut.used();\n            mapList = dexMerger.mapListOut.used();\n            typeList = dexMerger.typeListOut.used();\n            classData = dexMerger.classDataOut.used();\n            code = dexMerger.codeOut.used();\n            stringData = dexMerger.stringDataOut.used();\n            debugInfo = dexMerger.debugInfoOut.used();\n            encodedArray = dexMerger.encodedArrayOut.used();\n            annotationsDirectory = dexMerger.annotationsDirectoryOut.used();\n            annotationsSet = dexMerger.annotationSetOut.used();\n            annotationsSetRefList = dexMerger.annotationSetRefListOut.used();\n            annotation = dexMerger.annotationOut.used();\n            fourByteAlign();\n        }\n\n        private void plus(TableOfContents contents, boolean exact) {\n            idsDefs += contents.stringIds.size * SizeOf.STRING_ID_ITEM\n                    + contents.typeIds.size * SizeOf.TYPE_ID_ITEM\n                    + contents.protoIds.size * SizeOf.PROTO_ID_ITEM\n                    + contents.fieldIds.size * SizeOf.MEMBER_ID_ITEM\n                    + contents.methodIds.size * SizeOf.MEMBER_ID_ITEM\n                    + contents.classDefs.size * SizeOf.CLASS_DEF_ITEM;\n            mapList = SizeOf.UINT + (contents.sections.length * SizeOf.MAP_ITEM);\n            typeList += fourByteAlign(contents.typeLists.byteCount); // We count each dex's\n            // typelists section as realigned on 4 bytes, because each typelist of each dex's\n            // typelists section is aligned on 4 bytes. If we didn't, there is a case where each\n            // size of both dex's typelists section is a multiple of 2 but not a multiple of 4,\n            // and the sum of both sizes is a multiple of 4 but would not be sufficient to write\n            // each typelist aligned on 4 bytes.\n            stringData += contents.stringDatas.byteCount;\n            annotationsDirectory += contents.annotationsDirectories.byteCount;\n            annotationsSet += contents.annotationSets.byteCount;\n            annotationsSetRefList += contents.annotationSetRefLists.byteCount;\n\n            if (exact) {\n                code += contents.codes.byteCount;\n                classData += contents.classDatas.byteCount;\n                encodedArray += contents.encodedArrays.byteCount;\n                annotation += contents.annotations.byteCount;\n                debugInfo += contents.debugInfos.byteCount;\n            } else {\n                // at most 1/4 of the bytes in a code section are uleb/sleb\n                code += (int) Math.ceil(contents.codes.byteCount * 1.25);\n                // at most 2/3 of the bytes in a class data section are uleb/sleb that may change\n                // (assuming the worst case that section contains only methods and no fields)\n                classData += (int) Math.ceil(contents.classDatas.byteCount * 1.67);\n                // all of the bytes in an encoding arrays section may be uleb/sleb\n                encodedArray += contents.encodedArrays.byteCount * 2;\n                // all of the bytes in an annotations section may be uleb/sleb\n                annotation += (int) Math.ceil(contents.annotations.byteCount * 2);\n                // all of the bytes in a debug info section may be uleb/sleb\n                debugInfo += contents.debugInfos.byteCount * 2;\n            }\n        }\n\n        private void fourByteAlign() {\n            header = fourByteAlign(header);\n            idsDefs = fourByteAlign(idsDefs);\n            mapList = fourByteAlign(mapList);\n            typeList = fourByteAlign(typeList);\n            classData = fourByteAlign(classData);\n            code = fourByteAlign(code);\n            stringData = fourByteAlign(stringData);\n            debugInfo = fourByteAlign(debugInfo);\n            encodedArray = fourByteAlign(encodedArray);\n            annotationsDirectory = fourByteAlign(annotationsDirectory);\n            annotationsSet = fourByteAlign(annotationsSet);\n            annotationsSetRefList = fourByteAlign(annotationsSetRefList);\n            annotation = fourByteAlign(annotation);\n        }\n\n        private static int fourByteAlign(int position) {\n            return (position + 3) & ~3;\n        }\n\n        public int size() {\n            return header + idsDefs + mapList + typeList + classData + code + stringData + debugInfo\n                    + encodedArray + annotationsDirectory + annotationsSet + annotationsSetRefList\n                    + annotation;\n        }\n    }\n\n    public static void main(String[] args) throws IOException {\n        if (args.length < 2) {\n            printUsage();\n            return;\n        }\n\n        Dex[] dexes = new Dex[args.length - 1];\n        for (int i = 1; i < args.length; i++) {\n            dexes[i - 1] = new Dex(new File(args[i]));\n        }\n        Dex merged = new DexMerger(dexes, CollisionPolicy.KEEP_FIRST).merge();\n        merged.writeTo(new File(args[0]));\n    }\n\n    private static void printUsage() {\n        System.out.println(\"Usage: DexMerger <out.dex> <a.dex> <b.dex> ...\");\n        System.out.println();\n        System.out.println(\n            \"If a class is defined in several dex, the class found in the first dex will be used.\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/merge/IndexMap.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.merge;\n\nimport com.taobao.android.dex.*;\nimport com.taobao.android.dex.EncodedValueReader;\nimport com.taobao.android.dex.util.ByteOutput;\nimport com.taobao.android.dx.util.ByteArrayAnnotatedOutput;\n\nimport java.util.HashMap;\n\nimport static com.taobao.android.dex.EncodedValueReader.*;\n\n/**\n * Maps the index offsets from one dex file to those in another. For example, if\n * you have string #5 in the old dex file, its position in the new dex file is\n * {@code strings[5]}.\n */\npublic final class IndexMap {\n    private final Dex target;\n    public final int[] stringIds;\n    public final short[] typeIds;\n    public final short[] protoIds;\n    public final short[] fieldIds;\n    public final short[] methodIds;\n    private final HashMap<Integer, Integer> typeListOffsets;\n    private final HashMap<Integer, Integer> annotationOffsets;\n    private final HashMap<Integer, Integer> annotationSetOffsets;\n    private final HashMap<Integer, Integer> annotationSetRefListOffsets;\n    private final HashMap<Integer, Integer> annotationDirectoryOffsets;\n    private final HashMap<Integer, Integer> staticValuesOffsets;\n\n    public IndexMap(Dex target, TableOfContents tableOfContents) {\n        this.target = target;\n        this.stringIds = new int[tableOfContents.stringIds.size];\n        this.typeIds = new short[tableOfContents.typeIds.size];\n        this.protoIds = new short[tableOfContents.protoIds.size];\n        this.fieldIds = new short[tableOfContents.fieldIds.size];\n        this.methodIds = new short[tableOfContents.methodIds.size];\n        this.typeListOffsets = new HashMap<Integer, Integer>();\n        this.annotationOffsets = new HashMap<Integer, Integer>();\n        this.annotationSetOffsets = new HashMap<Integer, Integer>();\n        this.annotationSetRefListOffsets = new HashMap<Integer, Integer>();\n        this.annotationDirectoryOffsets = new HashMap<Integer, Integer>();\n        this.staticValuesOffsets = new HashMap<Integer, Integer>();\n\n        /*\n         * A type list, annotation set, annotation directory, or static value at\n         * offset 0 is always empty. Always map offset 0 to 0.\n         */\n        this.typeListOffsets.put(0, 0);\n        this.annotationSetOffsets.put(0, 0);\n        this.annotationDirectoryOffsets.put(0, 0);\n        this.staticValuesOffsets.put(0, 0);\n    }\n\n    public void putTypeListOffset(int oldOffset, int newOffset) {\n        if (oldOffset <= 0 || newOffset <= 0) {\n            throw new IllegalArgumentException();\n        }\n        typeListOffsets.put(oldOffset, newOffset);\n    }\n\n    public void putAnnotationOffset(int oldOffset, int newOffset) {\n        if (oldOffset <= 0 || newOffset <= 0) {\n            throw new IllegalArgumentException();\n        }\n        annotationOffsets.put(oldOffset, newOffset);\n    }\n\n    public void putAnnotationSetOffset(int oldOffset, int newOffset) {\n        if (oldOffset <= 0 || newOffset <= 0) {\n            throw new IllegalArgumentException();\n        }\n        annotationSetOffsets.put(oldOffset, newOffset);\n    }\n\n    public void putAnnotationSetRefListOffset(int oldOffset, int newOffset) {\n        if (oldOffset <= 0 || newOffset <= 0) {\n            throw new IllegalArgumentException();\n        }\n        annotationSetRefListOffsets.put(oldOffset, newOffset);\n    }\n\n    public void putAnnotationDirectoryOffset(int oldOffset, int newOffset) {\n        if (oldOffset <= 0 || newOffset <= 0) {\n            throw new IllegalArgumentException();\n        }\n        annotationDirectoryOffsets.put(oldOffset, newOffset);\n    }\n\n    public void putStaticValuesOffset(int oldOffset, int newOffset) {\n        if (oldOffset <= 0 || newOffset <= 0) {\n            throw new IllegalArgumentException();\n        }\n        staticValuesOffsets.put(oldOffset, newOffset);\n    }\n\n    public int adjustString(int stringIndex) {\n        return stringIndex == ClassDef.NO_INDEX ? ClassDef.NO_INDEX : stringIds[stringIndex];\n    }\n\n    public int adjustType(int typeIndex) {\n        return (typeIndex == ClassDef.NO_INDEX) ? ClassDef.NO_INDEX : (typeIds[typeIndex] & 0xffff);\n    }\n\n    public TypeList adjustTypeList(TypeList typeList) {\n        if (typeList == TypeList.EMPTY) {\n            return typeList;\n        }\n        short[] types = typeList.getTypes().clone();\n        for (int i = 0; i < types.length; i++) {\n            types[i] = (short) adjustType(types[i]);\n        }\n        return new TypeList(target, types);\n    }\n\n    public int adjustProto(int protoIndex) {\n        return protoIds[protoIndex] & 0xffff;\n    }\n\n    public int adjustField(int fieldIndex) {\n        return fieldIds[fieldIndex] & 0xffff;\n    }\n\n    public int adjustMethod(int methodIndex) {\n        return methodIds[methodIndex] & 0xffff;\n    }\n\n    public int adjustTypeListOffset(int typeListOffset) {\n        return typeListOffsets.get(typeListOffset);\n    }\n\n    public int adjustAnnotation(int annotationOffset) {\n        return annotationOffsets.get(annotationOffset);\n    }\n\n    public int adjustAnnotationSet(int annotationSetOffset) {\n        return annotationSetOffsets.get(annotationSetOffset);\n    }\n\n    public int adjustAnnotationSetRefList(int annotationSetRefListOffset) {\n        return annotationSetRefListOffsets.get(annotationSetRefListOffset);\n    }\n\n    public int adjustAnnotationDirectory(int annotationDirectoryOffset) {\n        return annotationDirectoryOffsets.get(annotationDirectoryOffset);\n    }\n\n    public int adjustStaticValues(int staticValuesOffset) {\n        return staticValuesOffsets.get(staticValuesOffset);\n    }\n\n    public MethodId adjust(MethodId methodId) {\n        return new MethodId(target,\n                adjustType(methodId.getDeclaringClassIndex()),\n                adjustProto(methodId.getProtoIndex()),\n                adjustString(methodId.getNameIndex()));\n    }\n\n    public FieldId adjust(FieldId fieldId) {\n        return new FieldId(target,\n                adjustType(fieldId.getDeclaringClassIndex()),\n                adjustType(fieldId.getTypeIndex()),\n                adjustString(fieldId.getNameIndex()));\n\n    }\n\n    public ProtoId adjust(ProtoId protoId) {\n        return new ProtoId(target,\n                adjustString(protoId.getShortyIndex()),\n                adjustType(protoId.getReturnTypeIndex()),\n                adjustTypeListOffset(protoId.getParametersOffset()));\n    }\n\n    public ClassDef adjust(ClassDef classDef) {\n        return new ClassDef(target, classDef.getOffset(), adjustType(classDef.getTypeIndex()),\n                classDef.getAccessFlags(), adjustType(classDef.getSupertypeIndex()),\n                adjustTypeListOffset(classDef.getInterfacesOffset()), classDef.getSourceFileIndex(),\n                classDef.getAnnotationsOffset(), classDef.getClassDataOffset(),\n                classDef.getStaticValuesOffset());\n    }\n\n    public SortableType adjust(SortableType sortableType) {\n        return new SortableType(sortableType.getDex(),\n                sortableType.getIndexMap(), adjust(sortableType.getClassDef()));\n    }\n\n    public EncodedValue adjustEncodedValue(EncodedValue encodedValue) {\n        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput(32);\n        new EncodedValueTransformer(out).transform(new EncodedValueReader(encodedValue));\n        return new EncodedValue(out.toByteArray());\n    }\n\n    public EncodedValue adjustEncodedArray(EncodedValue encodedArray) {\n        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput(32);\n        new EncodedValueTransformer(out).transformArray(\n                new EncodedValueReader(encodedArray, ENCODED_ARRAY));\n        return new EncodedValue(out.toByteArray());\n    }\n\n    public Annotation adjust(Annotation annotation) {\n        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput(32);\n        new EncodedValueTransformer(out).transformAnnotation(\n                annotation.getReader());\n        return new Annotation(target, annotation.getVisibility(),\n                new EncodedValue(out.toByteArray()));\n    }\n\n    /**\n     * Adjust an encoded value or array.\n     */\n    private final class EncodedValueTransformer {\n        private final ByteOutput out;\n\n        public EncodedValueTransformer(ByteOutput out) {\n            this.out = out;\n        }\n\n        public void transform(EncodedValueReader reader) {\n            // TODO: extract this into a helper class, EncodedValueWriter\n            switch (reader.peek()) {\n            case ENCODED_BYTE:\n                EncodedValueCodec.writeSignedIntegralValue(out, ENCODED_BYTE, reader.readByte());\n                break;\n            case ENCODED_SHORT:\n                EncodedValueCodec.writeSignedIntegralValue(out, ENCODED_SHORT, reader.readShort());\n                break;\n            case ENCODED_INT:\n                EncodedValueCodec.writeSignedIntegralValue(out, ENCODED_INT, reader.readInt());\n                break;\n            case ENCODED_LONG:\n                EncodedValueCodec.writeSignedIntegralValue(out, ENCODED_LONG, reader.readLong());\n                break;\n            case ENCODED_CHAR:\n                EncodedValueCodec.writeUnsignedIntegralValue(out, ENCODED_CHAR, reader.readChar());\n                break;\n            case ENCODED_FLOAT:\n                // Shift value left 32 so that right-zero-extension works.\n                long longBits = ((long) Float.floatToIntBits(reader.readFloat())) << 32;\n                EncodedValueCodec.writeRightZeroExtendedValue(out, ENCODED_FLOAT, longBits);\n                break;\n            case ENCODED_DOUBLE:\n                EncodedValueCodec.writeRightZeroExtendedValue(\n                        out, ENCODED_DOUBLE, Double.doubleToLongBits(reader.readDouble()));\n                break;\n            case ENCODED_STRING:\n                EncodedValueCodec.writeUnsignedIntegralValue(\n                        out, ENCODED_STRING, adjustString(reader.readString()));\n                break;\n            case ENCODED_TYPE:\n                EncodedValueCodec.writeUnsignedIntegralValue(\n                        out, ENCODED_TYPE, adjustType(reader.readType()));\n                break;\n            case ENCODED_FIELD:\n                EncodedValueCodec.writeUnsignedIntegralValue(\n                        out, ENCODED_FIELD, adjustField(reader.readField()));\n                break;\n            case ENCODED_ENUM:\n                EncodedValueCodec.writeUnsignedIntegralValue(\n                        out, ENCODED_ENUM, adjustField(reader.readEnum()));\n                break;\n            case ENCODED_METHOD:\n                EncodedValueCodec.writeUnsignedIntegralValue(\n                        out, ENCODED_METHOD, adjustMethod(reader.readMethod()));\n                break;\n            case ENCODED_ARRAY:\n                writeTypeAndArg(ENCODED_ARRAY, 0);\n                transformArray(reader);\n                break;\n            case ENCODED_ANNOTATION:\n                writeTypeAndArg(ENCODED_ANNOTATION, 0);\n                transformAnnotation(reader);\n                break;\n            case ENCODED_NULL:\n                reader.readNull();\n                writeTypeAndArg(ENCODED_NULL, 0);\n                break;\n            case ENCODED_BOOLEAN:\n                boolean value = reader.readBoolean();\n                writeTypeAndArg(ENCODED_BOOLEAN, value ? 1 : 0);\n                break;\n            default:\n                throw new DexException(\"Unexpected type: \" + Integer.toHexString(reader.peek()));\n            }\n        }\n\n        private void transformAnnotation(EncodedValueReader reader) {\n            int fieldCount = reader.readAnnotation();\n            Leb128.writeUnsignedLeb128(out, adjustType(reader.getAnnotationType()));\n            Leb128.writeUnsignedLeb128(out, fieldCount);\n            for (int i = 0; i < fieldCount; i++) {\n                Leb128.writeUnsignedLeb128(out, adjustString(reader.readAnnotationName()));\n                transform(reader);\n            }\n        }\n\n        private void transformArray(EncodedValueReader reader) {\n            int size = reader.readArray();\n            Leb128.writeUnsignedLeb128(out, size);\n            for (int i = 0; i < size; i++) {\n                transform(reader);\n            }\n        }\n\n        private void writeTypeAndArg(int type, int arg) {\n            out.writeByte((arg << 5) | type);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/merge/InstructionTransformer.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.merge;\n\nimport com.taobao.android.dex.DexException;\nimport com.taobao.android.dex.DexIndexOverflowException;\nimport com.taobao.android.dx.io.CodeReader;\nimport com.taobao.android.dx.io.Opcodes;\nimport com.taobao.android.dx.io.instructions.DecodedInstruction;\nimport com.taobao.android.dx.io.instructions.ShortArrayCodeOutput;\n\npublic final class InstructionTransformer {\n    private final CodeReader reader;\n\n    private DecodedInstruction[] mappedInstructions;\n    private int mappedAt;\n    private IndexMap indexMap;\n\n    public InstructionTransformer() {\n        this.reader = new CodeReader();\n        this.reader.setAllVisitors(new GenericVisitor());\n        this.reader.setStringVisitor(new StringVisitor());\n        this.reader.setTypeVisitor(new TypeVisitor());\n        this.reader.setFieldVisitor(new FieldVisitor());\n        this.reader.setMethodVisitor(new MethodVisitor());\n    }\n\n    public short[] transform(IndexMap indexMap, short[] encodedInstructions) throws DexException {\n        DecodedInstruction[] decodedInstructions =\n            DecodedInstruction.decodeAll(encodedInstructions);\n        int size = decodedInstructions.length;\n\n        this.indexMap = indexMap;\n        mappedInstructions = new DecodedInstruction[size];\n        mappedAt = 0;\n        reader.visitAll(decodedInstructions);\n\n        ShortArrayCodeOutput out = new ShortArrayCodeOutput(size);\n        for (DecodedInstruction instruction : mappedInstructions) {\n            if (instruction != null) {\n                instruction.encode(out);\n            }\n        }\n\n        this.indexMap = null;\n        return out.getArray();\n    }\n\n    private class GenericVisitor implements CodeReader.Visitor {\n        public void visit(DecodedInstruction[] all, DecodedInstruction one) {\n            mappedInstructions[mappedAt++] = one;\n        }\n    }\n\n    private class StringVisitor implements CodeReader.Visitor {\n        public void visit(DecodedInstruction[] all, DecodedInstruction one) {\n            int stringId = one.getIndex();\n            int mappedId = indexMap.adjustString(stringId);\n            boolean isJumbo = (one.getOpcode() == Opcodes.CONST_STRING_JUMBO);\n            jumboCheck(isJumbo, mappedId);\n            mappedInstructions[mappedAt++] = one.withIndex(mappedId);\n        }\n    }\n\n    private class FieldVisitor implements CodeReader.Visitor {\n        public void visit(DecodedInstruction[] all, DecodedInstruction one) {\n            int fieldId = one.getIndex();\n            int mappedId = indexMap.adjustField(fieldId);\n            boolean isJumbo = (one.getOpcode() == Opcodes.CONST_STRING_JUMBO);\n            jumboCheck(isJumbo, mappedId);\n            mappedInstructions[mappedAt++] = one.withIndex(mappedId);\n        }\n    }\n\n    private class TypeVisitor implements CodeReader.Visitor {\n        public void visit(DecodedInstruction[] all, DecodedInstruction one) {\n            int typeId = one.getIndex();\n            int mappedId = indexMap.adjustType(typeId);\n            boolean isJumbo = (one.getOpcode() == Opcodes.CONST_STRING_JUMBO);\n            jumboCheck(isJumbo, mappedId);\n            mappedInstructions[mappedAt++] = one.withIndex(mappedId);\n        }\n    }\n\n    private class MethodVisitor implements CodeReader.Visitor {\n        public void visit(DecodedInstruction[] all, DecodedInstruction one) {\n            int methodId = one.getIndex();\n            int mappedId = indexMap.adjustMethod(methodId);\n            boolean isJumbo = (one.getOpcode() == Opcodes.CONST_STRING_JUMBO);\n            jumboCheck(isJumbo, mappedId);\n            mappedInstructions[mappedAt++] = one.withIndex(mappedId);\n        }\n    }\n\n    private static void jumboCheck(boolean isJumbo, int newIndex) {\n        if (!isJumbo && (newIndex > 0xffff)) {\n            throw new DexIndexOverflowException(\"Cannot merge new index \" + newIndex +\n                                   \" into a non-jumbo instruction!\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/merge/SortableType.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.merge;\n\nimport com.taobao.android.dex.ClassDef;\nimport com.taobao.android.dex.Dex;\nimport java.util.Comparator;\n\n/**\n * Name and structure of a type. Used to order types such that each type is\n * preceded by its supertype and implemented interfaces.\n */\npublic final class SortableType {\n    public static final Comparator<SortableType> NULLS_LAST_ORDER = new Comparator<SortableType>() {\n        public int compare(SortableType a, SortableType b) {\n            if (a == b) {\n                return 0;\n            }\n            if (b == null) {\n                return -1;\n            }\n            if (a == null) {\n                return 1;\n            }\n            if (a.depth != b.depth) {\n                return a.depth - b.depth;\n            }\n            return a.getTypeIndex() - b.getTypeIndex();\n        }\n    };\n\n    private final Dex dex;\n    private final IndexMap indexMap;\n    private ClassDef classDef;\n    private int depth = -1;\n\n    public SortableType(Dex dex, IndexMap indexMap, ClassDef classDef) {\n        this.dex = dex;\n        this.indexMap = indexMap;\n        this.classDef = classDef;\n    }\n\n    public Dex getDex() {\n        return dex;\n    }\n\n    public IndexMap getIndexMap() {\n        return indexMap;\n    }\n\n    public ClassDef getClassDef() {\n        return classDef;\n    }\n\n    public int getTypeIndex() {\n        return classDef.getTypeIndex();\n    }\n\n    /**\n     * Assigns this type's depth if the depths of its supertype and implemented\n     * interfaces are known. Returns false if the depth couldn't be computed\n     * yet.\n     */\n    public boolean tryAssignDepth(SortableType[] types) {\n        int max;\n        if (classDef.getSupertypeIndex() == ClassDef.NO_INDEX) {\n            max = 0; // this is Object.class or an interface\n        } else {\n            SortableType sortableSupertype = types[classDef.getSupertypeIndex()];\n            if (sortableSupertype == null) {\n                max = 1; // unknown, so assume it's a root.\n            } else if (sortableSupertype.depth == -1) {\n                return false;\n            } else {\n                max = sortableSupertype.depth;\n            }\n        }\n\n        for (short interfaceIndex : classDef.getInterfaces()) {\n            SortableType implemented = types[interfaceIndex];\n            if (implemented == null) {\n                max = Math.max(max, 1); // unknown, so assume it's a root.\n            } else if (implemented.depth == -1) {\n                return false;\n            } else {\n                max = Math.max(max, implemented.depth);\n            }\n        }\n\n        depth = max + 1;\n        return true;\n    }\n\n    public boolean isDepthAssigned() {\n        return depth != -1;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/annotation/Annotation.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.annotation;\n\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.util.MutabilityControl;\nimport com.taobao.android.dx.util.ToHuman;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.TreeMap;\n\n/**\n * An annotation on an element of a class. Annotations have an\n * associated type and additionally consist of a set of (name, value)\n * pairs, where the names are unique.\n */\npublic final class Annotation extends MutabilityControl\n        implements Comparable<Annotation>, ToHuman {\n    /** {@code non-null;} type of the annotation */\n    private final CstType type;\n\n    /** {@code non-null;} the visibility of the annotation */\n    private final AnnotationVisibility visibility;\n\n    /** {@code non-null;} map from names to {@link NameValuePair} instances */\n    private final TreeMap<CstString, NameValuePair> elements;\n\n    /**\n     * Construct an instance. It initially contains no elements.\n     *\n     * @param type {@code non-null;} type of the annotation\n     * @param visibility {@code non-null;} the visibility of the annotation\n     */\n    public Annotation(CstType type, AnnotationVisibility visibility) {\n        if (type == null) {\n            throw new NullPointerException(\"type == null\");\n        }\n\n        if (visibility == null) {\n            throw new NullPointerException(\"visibility == null\");\n        }\n\n        this.type = type;\n        this.visibility = visibility;\n        this.elements = new TreeMap<CstString, NameValuePair>();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (! (other instanceof Annotation)) {\n            return false;\n        }\n\n        Annotation otherAnnotation = (Annotation) other;\n\n        if (! (type.equals(otherAnnotation.type)\n                        && (visibility == otherAnnotation.visibility))) {\n            return false;\n        }\n\n        return elements.equals(otherAnnotation.elements);\n    }\n\n    /** {@inheritDoc} */\n    public int hashCode() {\n        int hash = type.hashCode();\n        hash = (hash * 31) + elements.hashCode();\n        hash = (hash * 31) + visibility.hashCode();\n        return hash;\n    }\n\n    /** {@inheritDoc} */\n    public int compareTo(Annotation other) {\n        int result = type.compareTo(other.type);\n\n        if (result != 0) {\n            return result;\n        }\n\n        result = visibility.compareTo(other.visibility);\n\n        if (result != 0) {\n            return result;\n        }\n\n        Iterator<NameValuePair> thisIter = elements.values().iterator();\n        Iterator<NameValuePair> otherIter = other.elements.values().iterator();\n\n        while (thisIter.hasNext() && otherIter.hasNext()) {\n            NameValuePair thisOne = thisIter.next();\n            NameValuePair otherOne = otherIter.next();\n\n            result = thisOne.compareTo(otherOne);\n            if (result != 0) {\n                return result;\n            }\n        }\n\n        if (thisIter.hasNext()) {\n            return 1;\n        } else if (otherIter.hasNext()) {\n            return -1;\n        }\n\n        return 0;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return toHuman();\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        StringBuilder sb = new StringBuilder();\n\n        sb.append(visibility.toHuman());\n        sb.append(\"-annotation \");\n        sb.append(type.toHuman());\n        sb.append(\" {\");\n\n        boolean first = true;\n        for (NameValuePair pair : elements.values()) {\n            if (first) {\n                first = false;\n            } else {\n                sb.append(\", \");\n            }\n            sb.append(pair.getName().toHuman());\n            sb.append(\": \");\n            sb.append(pair.getValue().toHuman());\n        }\n\n        sb.append(\"}\");\n        return sb.toString();\n    }\n\n    /**\n     * Gets the type of this instance.\n     *\n     * @return {@code non-null;} the type\n     */\n    public CstType getType() {\n        return type;\n    }\n\n    /**\n     * Gets the visibility of this instance.\n     *\n     * @return {@code non-null;} the visibility\n     */\n    public AnnotationVisibility getVisibility() {\n        return visibility;\n    }\n\n    /**\n     * Put an element into the set of (name, value) pairs for this instance.\n     * If there is a preexisting element with the same name, it will be\n     * replaced by this method.\n     *\n     * @param pair {@code non-null;} the (name, value) pair to place into this instance\n     */\n    public void put(NameValuePair pair) {\n        throwIfImmutable();\n\n        if (pair == null) {\n            throw new NullPointerException(\"pair == null\");\n        }\n\n        elements.put(pair.getName(), pair);\n    }\n\n    /**\n     * Add an element to the set of (name, value) pairs for this instance.\n     * It is an error to call this method if there is a preexisting element\n     * with the same name.\n     *\n     * @param pair {@code non-null;} the (name, value) pair to add to this instance\n     */\n    public void add(NameValuePair pair) {\n        throwIfImmutable();\n\n        if (pair == null) {\n            throw new NullPointerException(\"pair == null\");\n        }\n\n        CstString name = pair.getName();\n\n        if (elements.get(name) != null) {\n            throw new IllegalArgumentException(\"name already added: \" + name);\n        }\n\n        elements.put(name, pair);\n    }\n\n    /**\n     * Gets the set of name-value pairs contained in this instance. The\n     * result is always unmodifiable.\n     *\n     * @return {@code non-null;} the set of name-value pairs\n     */\n    public Collection<NameValuePair> getNameValuePairs() {\n        return Collections.unmodifiableCollection(elements.values());\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/annotation/AnnotationVisibility.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.annotation;\n\nimport com.taobao.android.dx.util.ToHuman;\n\n/**\n * Visibility scope of an annotation.\n */\npublic enum AnnotationVisibility implements ToHuman {\n    RUNTIME(\"runtime\"),\n    BUILD(\"build\"),\n    SYSTEM(\"system\"),\n    EMBEDDED(\"embedded\");\n\n    /** {@code non-null;} the human-oriented string representation */\n    private final String human;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param human {@code non-null;} the human-oriented string representation\n     */\n    private AnnotationVisibility(String human) {\n        this.human = human;\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return human;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/annotation/Annotations.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.annotation;\n\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.util.MutabilityControl;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.TreeMap;\n\n/**\n * List of {@link Annotation} instances.\n */\npublic final class Annotations extends MutabilityControl\n        implements Comparable<Annotations> {\n    /** {@code non-null;} immutable empty instance */\n    public static final Annotations EMPTY = new Annotations();\n\n    static {\n        EMPTY.setImmutable();\n    }\n\n    /** {@code non-null;} map from types to annotations */\n    private final TreeMap<CstType, Annotation> annotations;\n\n    /**\n     * Constructs an immutable instance which is the combination of the\n     * two given instances. The two instances must contain disjoint sets\n     * of types.\n     *\n     * @param a1 {@code non-null;} an instance\n     * @param a2 {@code non-null;} the other instance\n     * @return {@code non-null;} the combination\n     * @throws IllegalArgumentException thrown if there is a duplicate type\n     */\n    public static Annotations combine(Annotations a1, Annotations a2) {\n        Annotations result = new Annotations();\n\n        result.addAll(a1);\n        result.addAll(a2);\n        result.setImmutable();\n\n        return result;\n    }\n\n    /**\n     * Constructs an immutable instance which is the combination of the\n     * given instance with the given additional annotation. The latter's\n     * type must not already appear in the former.\n     *\n     * @param annotations {@code non-null;} the instance to augment\n     * @param annotation {@code non-null;} the additional annotation\n     * @return {@code non-null;} the combination\n     * @throws IllegalArgumentException thrown if there is a duplicate type\n     */\n    public static Annotations combine(Annotations annotations,\n            Annotation annotation) {\n        Annotations result = new Annotations();\n\n        result.addAll(annotations);\n        result.add(annotation);\n        result.setImmutable();\n\n        return result;\n    }\n\n    /**\n     * Constructs an empty instance.\n     */\n    public Annotations() {\n        annotations = new TreeMap<CstType, Annotation>();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return annotations.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (! (other instanceof Annotations)) {\n            return false;\n        }\n\n        Annotations otherAnnotations = (Annotations) other;\n\n        return annotations.equals(otherAnnotations.annotations);\n    }\n\n    /** {@inheritDoc} */\n    public int compareTo(Annotations other) {\n        Iterator<Annotation> thisIter = annotations.values().iterator();\n        Iterator<Annotation> otherIter = other.annotations.values().iterator();\n\n        while (thisIter.hasNext() && otherIter.hasNext()) {\n            Annotation thisOne = thisIter.next();\n            Annotation otherOne = otherIter.next();\n\n            int result = thisOne.compareTo(otherOne);\n            if (result != 0) {\n                return result;\n            }\n        }\n\n        if (thisIter.hasNext()) {\n            return 1;\n        } else if (otherIter.hasNext()) {\n            return -1;\n        }\n\n        return 0;\n    }\n\n    /** {@inheritDoc} */\n    public String toString() {\n        StringBuilder sb = new StringBuilder();\n        boolean first = true;\n\n        sb.append(\"annotations{\");\n\n        for (Annotation a : annotations.values()) {\n            if (first) {\n                first = false;\n            } else {\n                sb.append(\", \");\n            }\n            sb.append(a.toHuman());\n        }\n\n        sb.append(\"}\");\n        return sb.toString();\n    }\n\n    /**\n     * Gets the number of elements in this instance.\n     *\n     * @return {@code >= 0;} the size\n     */\n    public int size() {\n        return annotations.size();\n    }\n\n    /**\n     * Adds an element to this instance. There must not already be an\n     * element of the same type.\n     *\n     * @param annotation {@code non-null;} the element to add\n     * @throws IllegalArgumentException thrown if there is a duplicate type\n     */\n    public void add(Annotation annotation) {\n        throwIfImmutable();\n\n        if (annotation == null) {\n            throw new NullPointerException(\"annotation == null\");\n        }\n\n        CstType type = annotation.getType();\n\n        if (annotations.containsKey(type)) {\n            throw new IllegalArgumentException(\"duplicate type: \" +\n                    type.toHuman());\n        }\n\n        annotations.put(type, annotation);\n    }\n\n    /**\n     * Adds all of the elements of the given instance to this one. The\n     * instances must not have any duplicate types.\n     *\n     * @param toAdd {@code non-null;} the annotations to add\n     * @throws IllegalArgumentException thrown if there is a duplicate type\n     */\n    public void addAll(Annotations toAdd) {\n        throwIfImmutable();\n\n        if (toAdd == null) {\n            throw new NullPointerException(\"toAdd == null\");\n        }\n\n        for (Annotation a : toAdd.annotations.values()) {\n            add(a);\n        }\n    }\n\n    /**\n     * Gets the set of annotations contained in this instance. The\n     * result is always unmodifiable.\n     *\n     * @return {@code non-null;} the set of annotations\n     */\n    public Collection<Annotation> getAnnotations() {\n        return Collections.unmodifiableCollection(annotations.values());\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/annotation/AnnotationsList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.annotation;\n\nimport com.taobao.android.dx.util.FixedSizeList;\n\n/**\n * List of {@link Annotations} instances.\n */\npublic final class AnnotationsList\n        extends FixedSizeList {\n    /** {@code non-null;} immutable empty instance */\n    public static final AnnotationsList EMPTY = new AnnotationsList(0);\n\n    /**\n     * Constructs an immutable instance which is the combination of\n     * the two given instances. The two instances must each have the\n     * same number of elements, and each pair of elements must contain\n     * disjoint sets of types.\n     *\n     * @param list1 {@code non-null;} an instance\n     * @param list2 {@code non-null;} the other instance\n     * @return {@code non-null;} the combination\n     */\n    public static AnnotationsList combine(AnnotationsList list1,\n            AnnotationsList list2) {\n        int size = list1.size();\n\n        if (size != list2.size()) {\n            throw new IllegalArgumentException(\"list1.size() != list2.size()\");\n        }\n\n        AnnotationsList result = new AnnotationsList(size);\n\n        for (int i = 0; i < size; i++) {\n            Annotations a1 = list1.get(i);\n            Annotations a2 = list2.get(i);\n            result.set(i, Annotations.combine(a1, a2));\n        }\n\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size the size of the list\n     */\n    public AnnotationsList(int size) {\n        super(size);\n    }\n\n    /**\n     * Gets the element at the given index. It is an error to call\n     * this with the index for an element which was never set; if you\n     * do that, this will throw {@code NullPointerException}.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @return {@code non-null;} element at that index\n     */\n    public Annotations get(int n) {\n        return (Annotations) get0(n);\n    }\n\n    /**\n     * Sets the element at the given index. The given element must be\n     * immutable.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @param a {@code null-ok;} the element to set at {@code n}\n     */\n    public void set(int n, Annotations a) {\n        a.throwIfMutable();\n        set0(n, a);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/annotation/NameValuePair.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.annotation;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstString;\n\n/**\n * A (name, value) pair. These are used as the contents of an annotation.\n */\npublic final class NameValuePair implements Comparable<NameValuePair> {\n    /** {@code non-null;} the name */\n    private final CstString name;\n\n    /** {@code non-null;} the value */\n    private final Constant value;\n\n    /**\n     * Construct an instance.\n     *\n     * @param name {@code non-null;} the name\n     * @param value {@code non-null;} the value\n     */\n    public NameValuePair(CstString name, Constant value) {\n        if (name == null) {\n            throw new NullPointerException(\"name == null\");\n        }\n\n        if (value == null) {\n            throw new NullPointerException(\"value == null\");\n        }\n\n        this.name = name;\n        this.value = value;\n    }\n\n    /** {@inheritDoc} */\n    public String toString() {\n        return name.toHuman() + \":\" + value;\n    }\n\n    /** {@inheritDoc} */\n    public int hashCode() {\n        return name.hashCode() * 31 + value.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    public boolean equals(Object other) {\n        if (! (other instanceof NameValuePair)) {\n            return false;\n        }\n\n        NameValuePair otherPair = (NameValuePair) other;\n\n        return name.equals(otherPair.name)\n            && value.equals(otherPair.value);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p>Instances of this class compare in name-major and value-minor\n     * order.</p>\n     */\n    public int compareTo(NameValuePair other) {\n        int result = name.compareTo(other.name);\n\n        if (result != 0) {\n            return result;\n        }\n\n        return value.compareTo(other.value);\n    }\n\n    /**\n     * Gets the name.\n     *\n     * @return {@code non-null;} the name\n     */\n    public CstString getName() {\n        return name;\n    }\n\n    /**\n     * Gets the value.\n     *\n     * @return {@code non-null;} the value\n     */\n    public Constant getValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/AccessFlags.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Constants used as \"access flags\" in various places in classes, and\n * related utilities. Although, at the rop layer, flags are generally\n * ignored, this is the layer of communication, and as such, this\n * package is where these definitions belong. The flag definitions are\n * identical to Java access flags, but {@code ACC_SUPER} isn't\n * used at all in translated code, and {@code ACC_SYNCHRONIZED}\n * is only used in a very limited way.\n */\npublic final class AccessFlags {\n    /** public member / class */\n    public static final int ACC_PUBLIC = 0x0001;\n\n    /** private member */\n    public static final int ACC_PRIVATE = 0x0002;\n\n    /** protected member */\n    public static final int ACC_PROTECTED = 0x0004;\n\n    /** static member */\n    public static final int ACC_STATIC = 0x0008;\n\n    /** final member / class */\n    public static final int ACC_FINAL = 0x0010;\n\n    /**\n     * synchronized method; only valid in dex files for {@code native}\n     * methods\n     */\n    public static final int ACC_SYNCHRONIZED = 0x0020;\n\n    /**\n     * class with new-style {@code invokespecial} for superclass\n     * method access\n     */\n    public static final int ACC_SUPER = 0x0020;\n\n    /** volatile field */\n    public static final int ACC_VOLATILE = 0x0040;\n\n    /** bridge method (generated) */\n    public static final int ACC_BRIDGE = 0x0040;\n\n    /** transient field */\n    public static final int ACC_TRANSIENT = 0x0080;\n\n    /** varargs method */\n    public static final int ACC_VARARGS = 0x0080;\n\n    /** native method */\n    public static final int ACC_NATIVE = 0x0100;\n\n    /** \"class\" is in fact an public static final interface */\n    public static final int ACC_INTERFACE = 0x0200;\n\n    /** abstract method / class */\n    public static final int ACC_ABSTRACT = 0x0400;\n\n    /**\n     * method with strict floating point ({@code strictfp})\n     * behavior\n     */\n    public static final int ACC_STRICT = 0x0800;\n\n    /** synthetic member */\n    public static final int ACC_SYNTHETIC = 0x1000;\n\n    /** class is an annotation type */\n    public static final int ACC_ANNOTATION = 0x2000;\n\n    /**\n     * class is an enumerated type; field is an element of an enumerated\n     * type\n     */\n    public static final int ACC_ENUM = 0x4000;\n\n    /** method is a constructor */\n    public static final int ACC_CONSTRUCTOR = 0x10000;\n\n    /**\n     * method was declared {@code synchronized}; has no effect on\n     * execution (other than inspecting this flag, per se)\n     */\n    public static final int ACC_DECLARED_SYNCHRONIZED = 0x20000;\n\n    /** flags defined on classes */\n    public static final int CLASS_FLAGS =\n        ACC_PUBLIC | ACC_FINAL | ACC_SUPER | ACC_INTERFACE | ACC_ABSTRACT |\n        ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM;\n\n    /** flags defined on inner classes */\n    public static final int INNER_CLASS_FLAGS =\n        ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL |\n        ACC_INTERFACE | ACC_ABSTRACT | ACC_SYNTHETIC | ACC_ANNOTATION |\n        ACC_ENUM;\n\n    /** flags defined on fields */\n    public static final int FIELD_FLAGS =\n        ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL |\n        ACC_VOLATILE | ACC_TRANSIENT | ACC_SYNTHETIC | ACC_ENUM;\n\n    /** flags defined on methods */\n    public static final int METHOD_FLAGS =\n        ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL |\n        ACC_SYNCHRONIZED | ACC_BRIDGE | ACC_VARARGS | ACC_NATIVE |\n        ACC_ABSTRACT | ACC_STRICT | ACC_SYNTHETIC | ACC_CONSTRUCTOR |\n        ACC_DECLARED_SYNCHRONIZED;\n\n    /** indicates conversion of class flags */\n    private static final int CONV_CLASS = 1;\n\n    /** indicates conversion of field flags */\n    private static final int CONV_FIELD = 2;\n\n    /** indicates conversion of method flags */\n    private static final int CONV_METHOD = 3;\n\n    /**\n     * This class is uninstantiable.\n     */\n    private AccessFlags() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Returns a human-oriented string representing the given access flags,\n     * as defined on classes (not fields or methods).\n     *\n     * @param flags the flags\n     * @return {@code non-null;} human-oriented string\n     */\n    public static String classString(int flags) {\n        return humanHelper(flags, CLASS_FLAGS, CONV_CLASS);\n    }\n\n    /**\n     * Returns a human-oriented string representing the given access flags,\n     * as defined on inner classes.\n     *\n     * @param flags the flags\n     * @return {@code non-null;} human-oriented string\n     */\n    public static String innerClassString(int flags) {\n        return humanHelper(flags, INNER_CLASS_FLAGS, CONV_CLASS);\n    }\n\n    /**\n     * Returns a human-oriented string representing the given access flags,\n     * as defined on fields (not classes or methods).\n     *\n     * @param flags the flags\n     * @return {@code non-null;} human-oriented string\n     */\n    public static String fieldString(int flags) {\n        return humanHelper(flags, FIELD_FLAGS, CONV_FIELD);\n    }\n\n    /**\n     * Returns a human-oriented string representing the given access flags,\n     * as defined on methods (not classes or fields).\n     *\n     * @param flags the flags\n     * @return {@code non-null;} human-oriented string\n     */\n    public static String methodString(int flags) {\n        return humanHelper(flags, METHOD_FLAGS, CONV_METHOD);\n    }\n\n    /**\n     * Returns whether the flag {@code ACC_PUBLIC} is on in the given\n     * flags.\n     *\n     * @param flags the flags to check\n     * @return the value of the {@code ACC_PUBLIC} flag\n     */\n    public static boolean isPublic(int flags) {\n        return (flags & ACC_PUBLIC) != 0;\n    }\n\n    /**\n     * Returns whether the flag {@code ACC_PROTECTED} is on in the given\n     * flags.\n     *\n     * @param flags the flags to check\n     * @return the value of the {@code ACC_PROTECTED} flag\n     */\n    public static boolean isProtected(int flags) {\n        return (flags & ACC_PROTECTED) != 0;\n    }\n\n    /**\n     * Returns whether the flag {@code ACC_PRIVATE} is on in the given\n     * flags.\n     *\n     * @param flags the flags to check\n     * @return the value of the {@code ACC_PRIVATE} flag\n     */\n    public static boolean isPrivate(int flags) {\n        return (flags & ACC_PRIVATE) != 0;\n    }\n\n    /**\n     * Returns whether the flag {@code ACC_STATIC} is on in the given\n     * flags.\n     *\n     * @param flags the flags to check\n     * @return the value of the {@code ACC_STATIC} flag\n     */\n    public static boolean isStatic(int flags) {\n        return (flags & ACC_STATIC) != 0;\n    }\n\n    /**\n     * Returns whether the flag {@code ACC_CONSTRUCTOR} is on in\n     * the given flags.\n     *\n     * @param flags the flags to check\n     * @return the value of the {@code ACC_CONSTRUCTOR} flag\n     */\n    public static boolean isConstructor(int flags) {\n        return (flags & ACC_CONSTRUCTOR) != 0;\n    }\n\n    /**\n     * Returns whether the flag {@code ACC_INTERFACE} is on in\n     * the given flags.\n     *\n     * @param flags the flags to check\n     * @return the value of the {@code ACC_INTERFACE} flag\n     */\n    public static boolean isInterface(int flags) {\n        return (flags & ACC_INTERFACE) != 0;\n    }\n\n    /**\n     * Returns whether the flag {@code ACC_SYNCHRONIZED} is on in\n     * the given flags.\n     *\n     * @param flags the flags to check\n     * @return the value of the {@code ACC_SYNCHRONIZED} flag\n     */\n    public static boolean isSynchronized(int flags) {\n        return (flags & ACC_SYNCHRONIZED) != 0;\n    }\n\n    /**\n     * Returns whether the flag {@code ACC_ABSTRACT} is on in the given\n     * flags.\n     *\n     * @param flags the flags to check\n     * @return the value of the {@code ACC_ABSTRACT} flag\n     */\n    public static boolean isAbstract(int flags) {\n        return (flags & ACC_ABSTRACT) != 0;\n    }\n\n    /**\n     * Returns whether the flag {@code ACC_NATIVE} is on in the given\n     * flags.\n     *\n     * @param flags the flags to check\n     * @return the value of the {@code ACC_NATIVE} flag\n     */\n    public static boolean isNative(int flags) {\n        return (flags & ACC_NATIVE) != 0;\n    }\n\n    /**\n     * Returns whether the flag {@code ACC_ANNOTATION} is on in the given\n     * flags.\n     *\n     * @param flags the flags to check\n     * @return the value of the {@code ACC_ANNOTATION} flag\n     */\n    public static boolean isAnnotation(int flags) {\n        return (flags & ACC_ANNOTATION) != 0;\n    }\n\n    /**\n     * Returns whether the flag {@code ACC_DECLARED_SYNCHRONIZED} is\n     * on in the given flags.\n     *\n     * @param flags the flags to check\n     * @return the value of the {@code ACC_DECLARED_SYNCHRONIZED} flag\n     */\n    public static boolean isDeclaredSynchronized(int flags) {\n        return (flags & ACC_DECLARED_SYNCHRONIZED) != 0;\n    }\n\n    /**\n     * Returns whether the flag {@code ACC_ENUM} is on in the given flags.\n     *\n     * @param flags the flags to check\n     * @return the value of the {@code ACC_ENUM} flag\n     */\n    public static boolean isEnum(int flags) {\n        return (flags & ACC_ENUM) != 0;\n    }\n\n    /**\n     * Helper to return a human-oriented string representing the given\n     * access flags.\n     *\n     * @param flags the defined flags\n     * @param mask mask for the \"defined\" bits\n     * @param what what the flags represent (one of {@code CONV_*})\n     * @return {@code non-null;} human-oriented string\n     */\n    private static String humanHelper(int flags, int mask, int what) {\n        StringBuffer sb = new StringBuffer(80);\n        int extra = flags & ~mask;\n\n        flags &= mask;\n\n        if ((flags & ACC_PUBLIC) != 0) {\n            sb.append(\"|public\");\n        }\n        if ((flags & ACC_PRIVATE) != 0) {\n            sb.append(\"|private\");\n        }\n        if ((flags & ACC_PROTECTED) != 0) {\n            sb.append(\"|protected\");\n        }\n        if ((flags & ACC_STATIC) != 0) {\n            sb.append(\"|static\");\n        }\n        if ((flags & ACC_FINAL) != 0) {\n            sb.append(\"|final\");\n        }\n        if ((flags & ACC_SYNCHRONIZED) != 0) {\n            if (what == CONV_CLASS) {\n                sb.append(\"|super\");\n            } else {\n                sb.append(\"|synchronized\");\n            }\n        }\n        if ((flags & ACC_VOLATILE) != 0) {\n            if (what == CONV_METHOD) {\n                sb.append(\"|bridge\");\n            } else {\n                sb.append(\"|volatile\");\n            }\n        }\n        if ((flags & ACC_TRANSIENT) != 0) {\n            if (what == CONV_METHOD) {\n                sb.append(\"|varargs\");\n            } else {\n                sb.append(\"|transient\");\n            }\n        }\n        if ((flags & ACC_NATIVE) != 0) {\n            sb.append(\"|native\");\n        }\n        if ((flags & ACC_INTERFACE) != 0) {\n            sb.append(\"|interface\");\n        }\n        if ((flags & ACC_ABSTRACT) != 0) {\n            sb.append(\"|abstract\");\n        }\n        if ((flags & ACC_STRICT) != 0) {\n            sb.append(\"|strictfp\");\n        }\n        if ((flags & ACC_SYNTHETIC) != 0) {\n            sb.append(\"|synthetic\");\n        }\n        if ((flags & ACC_ANNOTATION) != 0) {\n            sb.append(\"|annotation\");\n        }\n        if ((flags & ACC_ENUM) != 0) {\n            sb.append(\"|enum\");\n        }\n        if ((flags & ACC_CONSTRUCTOR) != 0) {\n            sb.append(\"|constructor\");\n        }\n        if ((flags & ACC_DECLARED_SYNCHRONIZED) != 0) {\n            sb.append(\"|declared_synchronized\");\n        }\n\n        if ((extra != 0) || (sb.length() == 0)) {\n            sb.append('|');\n            sb.append(Hex.u2(extra));\n        }\n\n        return sb.substring(1);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/BasicBlock.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.IntList;\nimport com.taobao.android.dx.util.LabeledItem;\n\n/**\n * Basic block of register-based instructions.\n */\npublic final class BasicBlock implements LabeledItem {\n    /** {@code >= 0;} target label for this block */\n    private final int label;\n\n    /** {@code non-null;} list of instructions in this block */\n    private final InsnList insns;\n\n    /**\n     * {@code non-null;} full list of successors that this block may\n     * branch to\n     */\n    private final IntList successors;\n\n    /**\n     * {@code >= -1;} the primary / standard-flow / \"default\" successor, or\n     * {@code -1} if this block has no successors (that is, it\n     * exits the function/method)\n     */\n    private final int primarySuccessor;\n\n    /**\n     * Constructs an instance. The predecessor set is set to {@code null}.\n     *\n     * @param label {@code >= 0;} target label for this block\n     * @param insns {@code non-null;} list of instructions in this block\n     * @param successors {@code non-null;} full list of successors that this\n     * block may branch to\n     * @param primarySuccessor {@code >= -1;} the primary / standard-flow /\n     * \"default\" successor, or {@code -1} if this block has no\n     * successors (that is, it exits the function/method or is an\n     * unconditional throw)\n     */\n    public BasicBlock(int label, InsnList insns, IntList successors,\n                      int primarySuccessor) {\n        if (label < 0) {\n            throw new IllegalArgumentException(\"label < 0\");\n        }\n\n        try {\n            insns.throwIfMutable();\n        } catch (NullPointerException ex) {\n            // Elucidate exception.\n            throw new NullPointerException(\"insns == null\");\n        }\n\n        int sz = insns.size();\n\n        if (sz == 0) {\n            throw new IllegalArgumentException(\"insns.size() == 0\");\n        }\n\n        for (int i = sz - 2; i >= 0; i--) {\n            Rop one = insns.get(i).getOpcode();\n            if (one.getBranchingness() != Rop.BRANCH_NONE) {\n                throw new IllegalArgumentException(\"insns[\" + i + \"] is a \" +\n                                                   \"branch or can throw\");\n            }\n        }\n\n        Insn lastInsn = insns.get(sz - 1);\n        if (lastInsn.getOpcode().getBranchingness() == Rop.BRANCH_NONE) {\n            throw new IllegalArgumentException(\"insns does not end with \" +\n                                               \"a branch or throwing \" +\n                                               \"instruction\");\n        }\n\n        try {\n            successors.throwIfMutable();\n        } catch (NullPointerException ex) {\n            // Elucidate exception.\n            throw new NullPointerException(\"successors == null\");\n        }\n\n        if (primarySuccessor < -1) {\n            throw new IllegalArgumentException(\"primarySuccessor < -1\");\n        }\n\n        if (primarySuccessor >= 0 && !successors.contains(primarySuccessor)) {\n            throw new IllegalArgumentException(\n                    \"primarySuccessor \" + primarySuccessor + \" not in successors \" + successors);\n        }\n\n        this.label = label;\n        this.insns = insns;\n        this.successors = successors;\n        this.primarySuccessor = primarySuccessor;\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * Instances of this class compare by identity. That is,\n     * {@code x.equals(y)} is only true if {@code x == y}.\n     */\n    @Override\n    public boolean equals(Object other) {\n        return (this == other);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * Return the identity hashcode of this instance. This is proper,\n     * since instances of this class compare by identity (see {@link #equals}).\n     */\n    @Override\n    public int hashCode() {\n        return System.identityHashCode(this);\n    }\n\n    /**\n     * Gets the target label of this block.\n     *\n     * @return {@code >= 0;} the label\n     */\n    public int getLabel() {\n        return label;\n    }\n\n    /**\n     * Gets the list of instructions inside this block.\n     *\n     * @return {@code non-null;} the instruction list\n     */\n    public InsnList getInsns() {\n        return insns;\n    }\n\n    /**\n     * Gets the list of successors that this block may branch to.\n     *\n     * @return {@code non-null;} the successors list\n     */\n    public IntList getSuccessors() {\n        return successors;\n    }\n\n    /**\n     * Gets the primary successor of this block.\n     *\n     * @return {@code >= -1;} the primary successor, or {@code -1} if this\n     * block has no successors at all\n     */\n    public int getPrimarySuccessor() {\n        return primarySuccessor;\n    }\n\n    /**\n     * Gets the secondary successor of this block. It is only valid to call\n     * this method on blocks that have exactly two successors.\n     *\n     * @return {@code >= 0;} the secondary successor\n     */\n    public int getSecondarySuccessor() {\n        if (successors.size() != 2) {\n            throw new UnsupportedOperationException(\n                    \"block doesn't have exactly two successors\");\n        }\n\n        int succ = successors.get(0);\n        if (succ == primarySuccessor) {\n            succ = successors.get(1);\n        }\n\n        return succ;\n    }\n\n    /**\n     * Gets the first instruction of this block. This is just a\n     * convenient shorthand for {@code getInsns().get(0)}.\n     *\n     * @return {@code non-null;} the first instruction\n     */\n    public Insn getFirstInsn() {\n        return insns.get(0);\n    }\n\n    /**\n     * Gets the last instruction of this block. This is just a\n     * convenient shorthand for {@code getInsns().getLast()}.\n     *\n     * @return {@code non-null;} the last instruction\n     */\n    public Insn getLastInsn() {\n        return insns.getLast();\n    }\n\n    /**\n     * Returns whether this block might throw an exception. This is\n     * just a convenient shorthand for {@code getLastInsn().canThrow()}.\n     *\n     * @return {@code true} iff this block might throw an\n     * exception\n     */\n    public boolean canThrow() {\n        return insns.getLast().canThrow();\n    }\n\n    /**\n     * Returns whether this block has any associated exception handlers.\n     * This is just a shorthand for inspecting the last instruction in\n     * the block to see if it could throw, and if so, whether it in fact\n     * has any associated handlers.\n     *\n     * @return {@code true} iff this block has any associated\n     * exception handlers\n     */\n    public boolean hasExceptionHandlers() {\n        Insn lastInsn = insns.getLast();\n        return lastInsn.getCatches().size() != 0;\n    }\n\n    /**\n     * Returns the exception handler types associated with this block,\n     * if any. This is just a shorthand for inspecting the last\n     * instruction in the block to see if it could throw, and if so,\n     * grabbing the catch list out of it. If not, this returns an\n     * empty list (not {@code null}).\n     *\n     * @return {@code non-null;} the exception handler types associated with\n     * this block\n     */\n    public TypeList getExceptionHandlerTypes() {\n        Insn lastInsn = insns.getLast();\n        return lastInsn.getCatches();\n    }\n\n    /**\n     * Returns an instance that is identical to this one, except that\n     * the registers in each instruction are offset by the given\n     * amount.\n     *\n     * @param delta the amount to offset register numbers by\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public BasicBlock withRegisterOffset(int delta) {\n        return new BasicBlock(label, insns.withRegisterOffset(delta),\n                              successors, primarySuccessor);\n    }\n\n    public String toString() {\n        return '{' + Hex.u2(label) + '}';\n    }\n\n    /**\n     * BasicBlock visitor interface\n     */\n    public interface Visitor {\n        /**\n         * Visits a basic block\n         * @param b block visited\n         */\n        public void visitBlock(BasicBlock b);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/BasicBlockList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.IntList;\nimport com.taobao.android.dx.util.LabeledList;\n\n/**\n * List of {@link BasicBlock} instances.\n */\npublic final class BasicBlockList extends LabeledList {\n    /**\n     * {@code >= -1;} the count of registers required by this method or\n     * {@code -1} if not yet calculated\n     */\n    private int regCount;\n\n    /**\n     * Constructs an instance. All indices initially contain {@code null},\n     * and the first-block label is initially {@code -1}.\n     *\n     * @param size the size of the list\n     */\n    public BasicBlockList(int size) {\n        super(size);\n\n        regCount = -1;\n    }\n\n    /**\n     * Constructs a mutable copy for {@code getMutableCopy()}.\n     *\n     * @param old block to copy\n     */\n    private BasicBlockList(BasicBlockList old) {\n        super(old);\n        regCount = old.regCount;\n    }\n\n\n    /**\n     * Gets the element at the given index. It is an error to call\n     * this with the index for an element which was never set; if you\n     * do that, this will throw {@code NullPointerException}.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @return {@code non-null;} element at that index\n     */\n    public BasicBlock get(int n) {\n        return (BasicBlock) get0(n);\n    }\n\n    /**\n     * Sets the basic block at the given index.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @param bb {@code null-ok;} the element to set at {@code n}\n     */\n    public void set(int n, BasicBlock bb) {\n        super.set(n, bb);\n\n        // Reset regCount, since it will need to be recalculated.\n        regCount = -1;\n    }\n\n    /**\n     * Returns how many registers this method requires. This is simply\n     * the maximum of register-number-plus-category referred to by this\n     * instance's instructions (indirectly through {@link BasicBlock}\n     * instances).\n     *\n     * @return {@code >= 0;} the register count\n     */\n    public int getRegCount() {\n        if (regCount == -1) {\n            RegCountVisitor visitor = new RegCountVisitor();\n            forEachInsn(visitor);\n            regCount = visitor.getRegCount();\n        }\n\n        return regCount;\n    }\n\n    /**\n     * Gets the total instruction count for this instance. This is the\n     * sum of the instruction counts of each block.\n     *\n     * @return {@code >= 0;} the total instruction count\n     */\n    public int getInstructionCount() {\n        int sz = size();\n        int result = 0;\n\n        for (int i = 0; i < sz; i++) {\n            BasicBlock one = (BasicBlock) getOrNull0(i);\n            if (one != null) {\n                result += one.getInsns().size();\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets the total instruction count for this instance, ignoring\n     * mark-local instructions which are not actually emitted.\n     *\n     * @return {@code >= 0;} the total instruction count\n     */\n    public int getEffectiveInstructionCount() {\n        int sz = size();\n        int result = 0;\n\n        for (int i = 0; i < sz; i++) {\n            BasicBlock one = (BasicBlock) getOrNull0(i);\n            if (one != null) {\n                InsnList insns = one.getInsns();\n                int insnsSz = insns.size();\n\n                for (int j = 0; j < insnsSz; j++) {\n                    Insn insn = insns.get(j);\n\n                    if (insn.getOpcode().getOpcode() != RegOps.MARK_LOCAL) {\n                        result++;\n                    }\n                }\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets the first block in the list with the given label, if any.\n     *\n     * @param label {@code >= 0;} the label to look for\n     * @return {@code non-null;} the so-labelled block\n     * @throws IllegalArgumentException thrown if the label isn't found\n     */\n    public BasicBlock labelToBlock(int label) {\n        int idx = indexOfLabel(label);\n\n        if (idx < 0) {\n            throw new IllegalArgumentException(\"no such label: \"\n                    + Hex.u2(label));\n        }\n\n        return get(idx);\n    }\n\n    /**\n     * Visits each instruction of each block in the list, in order.\n     *\n     * @param visitor {@code non-null;} visitor to use\n     */\n    public void forEachInsn(Insn.Visitor visitor) {\n        int sz = size();\n\n        for (int i = 0; i < sz; i++) {\n            BasicBlock one = get(i);\n            InsnList insns = one.getInsns();\n            insns.forEach(visitor);\n        }\n    }\n\n    /**\n     * Returns an instance that is identical to this one, except that\n     * the registers in each instruction are offset by the given\n     * amount. Mutability of the result is inherited from the\n     * original.\n     *\n     * @param delta the amount to offset register numbers by\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public BasicBlockList withRegisterOffset(int delta) {\n        int sz = size();\n        BasicBlockList result = new BasicBlockList(sz);\n\n        for (int i = 0; i < sz; i++) {\n            BasicBlock one = (BasicBlock) get0(i);\n            if (one != null) {\n                result.set(i, one.withRegisterOffset(delta));\n            }\n        }\n\n        if (isImmutable()) {\n            result.setImmutable();\n        }\n\n        return result;\n    }\n\n    /**\n     * Returns a mutable copy of this list.\n     *\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public BasicBlockList getMutableCopy() {\n        return new BasicBlockList(this);\n    }\n\n    /**\n     * Gets the preferred successor for the given block. If the block\n     * only has one successor, then that is the preferred successor.\n     * Otherwise, if the block has a primay successor, then that is\n     * the preferred successor. If the block has no successors, then\n     * this returns {@code null}.\n     *\n     * @param block {@code non-null;} the block in question\n     * @return {@code null-ok;} the preferred successor, if any\n     */\n    public BasicBlock preferredSuccessorOf(BasicBlock block) {\n        int primarySuccessor = block.getPrimarySuccessor();\n        IntList successors = block.getSuccessors();\n        int succSize = successors.size();\n\n        switch (succSize) {\n            case 0: {\n                return null;\n            }\n            case 1: {\n                return labelToBlock(successors.get(0));\n            }\n        }\n\n        if (primarySuccessor != -1) {\n            return labelToBlock(primarySuccessor);\n        } else {\n            return labelToBlock(successors.get(0));\n        }\n    }\n\n    /**\n     * Compares the catches of two blocks for equality. This includes\n     * both the catch types and target labels.\n     *\n     * @param block1 {@code non-null;} one block to compare\n     * @param block2 {@code non-null;} the other block to compare\n     * @return {@code true} if the two blocks' non-primary successors\n     * are identical\n     */\n    public boolean catchesEqual(BasicBlock block1, BasicBlock block2) {\n        TypeList catches1 = block1.getExceptionHandlerTypes();\n        TypeList catches2 = block2.getExceptionHandlerTypes();\n\n        if (!StdTypeList.equalContents(catches1, catches2)) {\n            return false;\n        }\n\n        IntList succ1 = block1.getSuccessors();\n        IntList succ2 = block2.getSuccessors();\n        int size = succ1.size(); // Both are guaranteed to be the same size.\n\n        int primary1 = block1.getPrimarySuccessor();\n        int primary2 = block2.getPrimarySuccessor();\n\n        if (((primary1 == -1) || (primary2 == -1))\n                && (primary1 != primary2)) {\n            /*\n             * For the current purpose, both blocks in question must\n             * either both have a primary or both not have a primary to\n             * be considered equal, and it turns out here that that's not\n             * the case.\n             */\n            return false;\n        }\n\n        for (int i = 0; i < size; i++) {\n            int label1 = succ1.get(i);\n            int label2 = succ2.get(i);\n\n            if (label1 == primary1) {\n                /*\n                 * It should be the case that block2's primary is at the\n                 * same index. If not, we consider the blocks unequal for\n                 * the current purpose.\n                 */\n                if (label2 != primary2) {\n                    return false;\n                }\n                continue;\n            }\n\n            if (label1 != label2) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Instruction visitor class for counting registers used.\n     */\n    private static class RegCountVisitor\n            implements Insn.Visitor {\n        /** {@code >= 0;} register count in-progress */\n        private int regCount;\n\n        /**\n         * Constructs an instance.\n         */\n        public RegCountVisitor() {\n            regCount = 0;\n        }\n\n        /**\n         * Gets the register count.\n         *\n         * @return {@code >= 0;} the count\n         */\n        public int getRegCount() {\n            return regCount;\n        }\n\n        /** {@inheritDoc} */\n        public void visitPlainInsn(PlainInsn insn) {\n            visit(insn);\n        }\n\n        /** {@inheritDoc} */\n        public void visitPlainCstInsn(PlainCstInsn insn) {\n            visit(insn);\n        }\n\n        /** {@inheritDoc} */\n        public void visitSwitchInsn(SwitchInsn insn) {\n            visit(insn);\n        }\n\n        /** {@inheritDoc} */\n        public void visitThrowingCstInsn(ThrowingCstInsn insn) {\n            visit(insn);\n        }\n\n        /** {@inheritDoc} */\n        public void visitThrowingInsn(ThrowingInsn insn) {\n            visit(insn);\n        }\n\n        /** {@inheritDoc} */\n        public void visitFillArrayDataInsn(FillArrayDataInsn insn) {\n            visit(insn);\n        }\n\n        /**\n         * Helper for all the {@code visit*} methods.\n         *\n         * @param insn {@code non-null;} instruction being visited\n         */\n        private void visit(Insn insn) {\n            RegisterSpec result = insn.getResult();\n\n            if (result != null) {\n                processReg(result);\n            }\n\n            RegisterSpecList sources = insn.getSources();\n            int sz = sources.size();\n\n            for (int i = 0; i < sz; i++) {\n                processReg(sources.get(i));\n            }\n        }\n\n        /**\n         * Processes the given register spec.\n         *\n         * @param spec {@code non-null;} the register spec\n         */\n        private void processReg(RegisterSpec spec) {\n            int reg = spec.getNextReg();\n\n            if (reg > regCount) {\n                regCount = reg;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/ConservativeTranslationAdvice.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\n/**\n * Implementation of {@link TranslationAdvice} which conservatively answers\n * {@code false} to all methods.\n */\npublic final class ConservativeTranslationAdvice\n        implements TranslationAdvice {\n    /** {@code non-null;} standard instance of this class */\n    public static final ConservativeTranslationAdvice THE_ONE =\n        new ConservativeTranslationAdvice();\n\n    /**\n     * This class is not publicly instantiable. Use {@link #THE_ONE}.\n     */\n    private ConservativeTranslationAdvice() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    public boolean hasConstantOperation(Rop opcode,\n            RegisterSpec sourceA, RegisterSpec sourceB) {\n        return false;\n    }\n\n    /** {@inheritDoc} */\n    public boolean requiresSourcesInOrder(Rop opcode,\n            RegisterSpecList sources) {\n        return false;\n    }\n\n    /** {@inheritDoc} */\n    public int getMaxOptimalRegisterCount() {\n        return Integer.MAX_VALUE;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/CstInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.cst.Constant;\n\n/**\n * Instruction which contains an explicit reference to a constant.\n */\npublic abstract class CstInsn\n        extends Insn {\n    /** {@code non-null;} the constant */\n    private final Constant cst;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param opcode {@code non-null;} the opcode\n     * @param position {@code non-null;} source position\n     * @param result {@code null-ok;} spec for the result, if any\n     * @param sources {@code non-null;} specs for all the sources\n     * @param cst {@code non-null;} constant\n     */\n    public CstInsn(Rop opcode, SourcePosition position, RegisterSpec result,\n                   RegisterSpecList sources, Constant cst) {\n        super(opcode, position, result, sources);\n\n        if (cst == null) {\n            throw new NullPointerException(\"cst == null\");\n        }\n\n        this.cst = cst;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String getInlineString() {\n        return cst.toHuman();\n    }\n\n    /**\n     * Gets the constant.\n     *\n     * @return {@code non-null;} the constant\n     */\n    public Constant getConstant() {\n        return cst;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean contentEquals(Insn b) {\n        /*\n         * The cast (CstInsn)b below should always succeed since\n         * Insn.contentEquals compares classes of this and b.\n         */\n        return super.contentEquals(b)\n                && cst.equals(((CstInsn)b).getConstant());\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/DexTranslationAdvice.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.type.Type;\n\n/**\n * Implementation of {@link TranslationAdvice} which represents what\n * the dex format will be able to represent.\n */\npublic final class DexTranslationAdvice\n        implements TranslationAdvice {\n    /** {@code non-null;} standard instance of this class */\n    public static final DexTranslationAdvice THE_ONE =\n        new DexTranslationAdvice();\n\n    /** debug advice for disabling invoke-range optimization */\n    public static final DexTranslationAdvice NO_SOURCES_IN_ORDER =\n        new DexTranslationAdvice(true);\n\n    /**\n     * The minimum source width, in register units, for an invoke\n     * instruction that requires its sources to be in order and contiguous.\n     */\n    private static final int MIN_INVOKE_IN_ORDER = 6;\n\n    /** when true: always returns false for requiresSourcesInOrder */\n    private final boolean disableSourcesInOrder;\n\n    /**\n     * This class is not publicly instantiable. Use {@link #THE_ONE}.\n     */\n    private DexTranslationAdvice() {\n        disableSourcesInOrder = false;\n    }\n\n    private DexTranslationAdvice(boolean disableInvokeRange) {\n        this.disableSourcesInOrder = disableInvokeRange;\n    }\n\n    /** {@inheritDoc} */\n    public boolean hasConstantOperation(Rop opcode,\n            RegisterSpec sourceA, RegisterSpec sourceB) {\n        if (sourceA.getType() != Type.INT) {\n            return false;\n        }\n\n        // Return false if second source isn't a constant\n        if (! (sourceB.getTypeBearer() instanceof CstInteger)) {\n            // Except for rsub-int (reverse sub) where first source is constant\n            if (sourceA.getTypeBearer() instanceof CstInteger &&\n                    opcode.getOpcode() == RegOps.SUB) {\n                CstInteger cst = (CstInteger) sourceA.getTypeBearer();\n                return cst.fitsIn16Bits();\n            } else {\n                return false;\n            }\n        }\n\n        CstInteger cst = (CstInteger) sourceB.getTypeBearer();\n\n        switch (opcode.getOpcode()) {\n            // These have 8 and 16 bit cst representations\n            case RegOps.REM:\n            case RegOps.ADD:\n            case RegOps.MUL:\n            case RegOps.DIV:\n            case RegOps.AND:\n            case RegOps.OR:\n            case RegOps.XOR:\n                return cst.fitsIn16Bits();\n            // These only have 8 bit cst reps\n            case RegOps.SHL:\n            case RegOps.SHR:\n            case RegOps.USHR:\n                return cst.fitsIn8Bits();\n            // No sub-const insn, so check if equivalent add-const fits\n            case RegOps.SUB:\n                CstInteger cst2 = CstInteger.make(-cst.getValue());\n                return cst2.fitsIn16Bits();\n            default:\n                return false;\n        }\n    }\n\n    /** {@inheritDoc} */\n    public boolean requiresSourcesInOrder(Rop opcode,\n            RegisterSpecList sources) {\n\n        return !disableSourcesInOrder && opcode.isCallLike()\n                && totalRopWidth(sources) >= MIN_INVOKE_IN_ORDER;\n    }\n\n    /**\n     * Calculates the total rop width of the list of SSA registers\n     *\n     * @param sources {@code non-null;} list of SSA registers\n     * @return {@code >= 0;} rop-form width in register units\n     */\n    private int totalRopWidth(RegisterSpecList sources) {\n        int sz = sources.size();\n        int total = 0;\n\n        for (int i = 0; i < sz; i++) {\n            total += sources.get(i).getCategory();\n        }\n\n        return total;\n    }\n\n    /** {@inheritDoc} */\n    public int getMaxOptimalRegisterCount() {\n        return 16;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/Exceptions.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\n\n/**\n * Common exception types.\n */\npublic final class Exceptions {\n    /** {@code non-null;} the type {@code java.lang.ArithmeticException} */\n    public static final Type TYPE_ArithmeticException =\n        Type.intern(\"Ljava/lang/ArithmeticException;\");\n\n    /**\n     * {@code non-null;} the type\n     * {@code java.lang.ArrayIndexOutOfBoundsException}\n     */\n    public static final Type TYPE_ArrayIndexOutOfBoundsException =\n        Type.intern(\"Ljava/lang/ArrayIndexOutOfBoundsException;\");\n\n    /** {@code non-null;} the type {@code java.lang.ArrayStoreException} */\n    public static final Type TYPE_ArrayStoreException =\n        Type.intern(\"Ljava/lang/ArrayStoreException;\");\n\n    /** {@code non-null;} the type {@code java.lang.ClassCastException} */\n    public static final Type TYPE_ClassCastException =\n        Type.intern(\"Ljava/lang/ClassCastException;\");\n\n    /** {@code non-null;} the type {@code java.lang.Error} */\n    public static final Type TYPE_Error = Type.intern(\"Ljava/lang/Error;\");\n\n    /**\n     * {@code non-null;} the type\n     * {@code java.lang.IllegalMonitorStateException}\n     */\n    public static final Type TYPE_IllegalMonitorStateException =\n        Type.intern(\"Ljava/lang/IllegalMonitorStateException;\");\n\n    /** {@code non-null;} the type {@code java.lang.NegativeArraySizeException} */\n    public static final Type TYPE_NegativeArraySizeException =\n        Type.intern(\"Ljava/lang/NegativeArraySizeException;\");\n\n    /** {@code non-null;} the type {@code java.lang.NullPointerException} */\n    public static final Type TYPE_NullPointerException =\n        Type.intern(\"Ljava/lang/NullPointerException;\");\n\n    /** {@code non-null;} the list {@code [java.lang.Error]} */\n    public static final StdTypeList LIST_Error = StdTypeList.make(TYPE_Error);\n\n    /**\n     * {@code non-null;} the list {@code[java.lang.Error,\n     * java.lang.ArithmeticException]}\n     */\n    public static final StdTypeList LIST_Error_ArithmeticException =\n        StdTypeList.make(TYPE_Error, TYPE_ArithmeticException);\n\n    /**\n     * {@code non-null;} the list {@code[java.lang.Error,\n     * java.lang.ClassCastException]}\n     */\n    public static final StdTypeList LIST_Error_ClassCastException =\n        StdTypeList.make(TYPE_Error, TYPE_ClassCastException);\n\n    /**\n     * {@code non-null;} the list {@code [java.lang.Error,\n     * java.lang.NegativeArraySizeException]}\n     */\n    public static final StdTypeList LIST_Error_NegativeArraySizeException =\n        StdTypeList.make(TYPE_Error, TYPE_NegativeArraySizeException);\n\n    /**\n     * {@code non-null;} the list {@code [java.lang.Error,\n     * java.lang.NullPointerException]}\n     */\n    public static final StdTypeList LIST_Error_NullPointerException =\n        StdTypeList.make(TYPE_Error, TYPE_NullPointerException);\n\n    /**\n     * {@code non-null;} the list {@code [java.lang.Error,\n     * java.lang.NullPointerException,\n     * java.lang.ArrayIndexOutOfBoundsException]}\n     */\n    public static final StdTypeList LIST_Error_Null_ArrayIndexOutOfBounds =\n        StdTypeList.make(TYPE_Error,\n                      TYPE_NullPointerException,\n                      TYPE_ArrayIndexOutOfBoundsException);\n\n    /**\n     * {@code non-null;} the list {@code [java.lang.Error,\n     * java.lang.NullPointerException,\n     * java.lang.ArrayIndexOutOfBoundsException,\n     * java.lang.ArrayStoreException]}\n     */\n    public static final StdTypeList LIST_Error_Null_ArrayIndex_ArrayStore =\n        StdTypeList.make(TYPE_Error,\n                      TYPE_NullPointerException,\n                      TYPE_ArrayIndexOutOfBoundsException,\n                      TYPE_ArrayStoreException);\n\n    /**\n     * {@code non-null;} the list {@code [java.lang.Error,\n     * java.lang.NullPointerException,\n     * java.lang.IllegalMonitorStateException]}\n     */\n    public static final StdTypeList\n        LIST_Error_Null_IllegalMonitorStateException =\n        StdTypeList.make(TYPE_Error,\n                      TYPE_NullPointerException,\n                      TYPE_IllegalMonitorStateException);\n\n    /**\n     * This class is uninstantiable.\n     */\n    private Exceptions() {\n        // This space intentionally left blank.\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/FillArrayDataInsn.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport java.util.ArrayList;\n\n/**\n * Instruction which fills a newly created array with a predefined list of\n * constant values.\n */\npublic final class FillArrayDataInsn\n        extends Insn {\n\n    /** non-null: initial values to fill the newly created array */\n    private final ArrayList<Constant> initValues;\n\n    /**\n     * non-null: type of the array. Will be used to determine the width of\n     * elements in the array-data table.\n     */\n    private final Constant arrayType;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param opcode {@code non-null;} the opcode\n     * @param position {@code non-null;} source position\n     * @param sources {@code non-null;} specs for all the sources\n     * @param initValues {@code non-null;} list of initial values to fill the array\n     * @param cst {@code non-null;} type of the new array\n     */\n    public FillArrayDataInsn(Rop opcode, SourcePosition position,\n                             RegisterSpecList sources,\n                             ArrayList<Constant> initValues,\n                             Constant cst) {\n        super(opcode, position, null, sources);\n\n        if (opcode.getBranchingness() != Rop.BRANCH_NONE) {\n            throw new IllegalArgumentException(\"bogus branchingness\");\n        }\n\n        this.initValues = initValues;\n        this.arrayType = cst;\n    }\n\n\n    /** {@inheritDoc} */\n    @Override\n    public TypeList getCatches() {\n        return StdTypeList.EMPTY;\n    }\n\n    /**\n     * Return the list of init values\n     * @return {@code non-null;} list of init values\n     */\n    public ArrayList<Constant> getInitValues() {\n        return initValues;\n    }\n\n    /**\n     * Return the type of the newly created array\n     * @return {@code non-null;} array type\n     */\n    public Constant getConstant() {\n        return arrayType;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void accept(Visitor visitor) {\n        visitor.visitFillArrayDataInsn(this);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withAddedCatch(Type type) {\n        throw new  UnsupportedOperationException(\"unsupported\");\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withRegisterOffset(int delta) {\n        return new FillArrayDataInsn(getOpcode(), getPosition(),\n                                     getSources().withOffset(delta),\n                                     initValues, arrayType);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withNewRegisters(RegisterSpec result,\n            RegisterSpecList sources) {\n\n        return new FillArrayDataInsn(getOpcode(), getPosition(),\n                                     sources, initValues, arrayType);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/Insn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.ToHuman;\n\n/**\n * A register-based instruction. An instruction is the combination of\n * an opcode (which specifies operation and source/result types), a\n * list of actual sources and result registers/values, and additional\n * information.\n */\npublic abstract class Insn implements ToHuman {\n    /** {@code non-null;} opcode */\n    private final Rop opcode;\n\n    /** {@code non-null;} source position */\n    private final SourcePosition position;\n\n    /** {@code null-ok;} spec for the result of this instruction, if any */\n    private final RegisterSpec result;\n\n    /** {@code non-null;} specs for all the sources of this instruction */\n    private final RegisterSpecList sources;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param opcode {@code non-null;} the opcode\n     * @param position {@code non-null;} source position\n     * @param result {@code null-ok;} spec for the result, if any\n     * @param sources {@code non-null;} specs for all the sources\n     */\n    public Insn(Rop opcode, SourcePosition position, RegisterSpec result,\n                RegisterSpecList sources) {\n        if (opcode == null) {\n            throw new NullPointerException(\"opcode == null\");\n        }\n\n        if (position == null) {\n            throw new NullPointerException(\"position == null\");\n        }\n\n        if (sources == null) {\n            throw new NullPointerException(\"sources == null\");\n        }\n\n        this.opcode = opcode;\n        this.position = position;\n        this.result = result;\n        this.sources = sources;\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * Instances of this class compare by identity. That is,\n     * {@code x.equals(y)} is only true if {@code x == y}.\n     */\n    @Override\n    public final boolean equals(Object other) {\n        return (this == other);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * This implementation returns the identity hashcode of this\n     * instance. This is proper, since instances of this class compare\n     * by identity (see {@link #equals}).\n     */\n    @Override\n    public final int hashCode() {\n        return System.identityHashCode(this);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return toStringWithInline(getInlineString());\n    }\n\n    /**\n     * Gets a human-oriented (and slightly lossy) string for this instance.\n     *\n     * @return {@code non-null;} the human string form\n     */\n    public String toHuman() {\n        return toHumanWithInline(getInlineString());\n    }\n\n    /**\n     * Gets an \"inline\" string portion for toHuman(), if available. This\n     * is the portion that appears after the Rop opcode\n     *\n     * @return {@code null-ok;} if non-null, the inline text for toHuman()\n     */\n    public String getInlineString() {\n        return null;\n    }\n\n    /**\n     * Gets the opcode.\n     *\n     * @return {@code non-null;} the opcode\n     */\n    public final Rop getOpcode() {\n        return opcode;\n    }\n\n    /**\n     * Gets the source position.\n     *\n     * @return {@code non-null;} the source position\n     */\n    public final SourcePosition getPosition() {\n        return position;\n    }\n\n    /**\n     * Gets the result spec, if any. A return value of {@code null}\n     * means this instruction returns nothing.\n     *\n     * @return {@code null-ok;} the result spec, if any\n     */\n    public final RegisterSpec getResult() {\n        return result;\n    }\n\n    /**\n     * Gets the spec of a local variable assignment that occurs at this\n     * instruction, or null if no local variable assignment occurs. This\n     * may be the result register, or for {@code mark-local} insns\n     * it may be the source.\n     *\n     * @return {@code null-ok;} a named register spec or null\n     */\n    public final RegisterSpec getLocalAssignment() {\n        RegisterSpec assignment;\n        if (opcode.getOpcode() == RegOps.MARK_LOCAL) {\n            assignment = sources.get(0);\n        } else {\n            assignment = result;\n        }\n\n        if (assignment == null) {\n            return null;\n        }\n\n        LocalItem localItem = assignment.getLocalItem();\n\n        if (localItem == null) {\n            return null;\n        }\n\n        return assignment;\n    }\n\n    /**\n     * Gets the source specs.\n     *\n     * @return {@code non-null;} the source specs\n     */\n    public final RegisterSpecList getSources() {\n        return sources;\n    }\n\n    /**\n     * Gets whether this instruction can possibly throw an exception. This\n     * is just a convenient wrapper for {@code getOpcode().canThrow()}.\n     *\n     * @return {@code true} iff this instruction can possibly throw\n     */\n    public final boolean canThrow() {\n        return opcode.canThrow();\n    }\n\n    /**\n     * Gets the list of possibly-caught exceptions. This returns {@link\n     * StdTypeList#EMPTY} if this instruction has no handlers,\n     * which can be <i>either</i> if this instruction can't possibly\n     * throw or if it merely doesn't handle any of its possible\n     * exceptions. To determine whether this instruction can throw,\n     * use {@link #canThrow}.\n     *\n     * @return {@code non-null;} the catches list\n     */\n    public abstract TypeList getCatches();\n\n    /**\n     * Calls the appropriate method on the given visitor, depending on the\n     * class of this instance. Subclasses must override this.\n     *\n     * @param visitor {@code non-null;} the visitor to call on\n     */\n    public abstract void accept(Visitor visitor);\n\n    /**\n     * Returns an instance that is just like this one, except that it\n     * has a catch list with the given item appended to the end. This\n     * method throws an exception if this instance can't possibly\n     * throw. To determine whether this instruction can throw, use\n     * {@link #canThrow}.\n     *\n     * @param type {@code non-null;} type to append to the catch list\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public abstract Insn withAddedCatch(Type type);\n\n    /**\n     * Returns an instance that is just like this one, except that all\n     * register references have been offset by the given delta.\n     *\n     * @param delta the amount to offset register references by\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public abstract Insn withRegisterOffset(int delta);\n\n    /**\n     * Returns an instance that is just like this one, except that, if\n     * possible, the insn is converted into a version in which a source\n     * (if it is a constant) is represented directly rather than as a\n     * register reference. {@code this} is returned in cases where the\n     * translation is not possible.\n     *\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public Insn withSourceLiteral() {\n        return this;\n    }\n\n    /**\n     * Returns an exact copy of this Insn\n     *\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public Insn copy() {\n        return withRegisterOffset(0);\n    }\n\n\n    /**\n     * Compares, handling nulls safely\n     *\n     * @param a first object\n     * @param b second object\n     * @return true if they're equal or both null.\n     */\n    private static boolean equalsHandleNulls (Object a, Object b) {\n        return (a == b) || ((a != null) && a.equals(b));\n    }\n\n    /**\n     * Compares Insn contents, since {@code Insn.equals()} is defined\n     * to be an identity compare. Insn's are {@code contentEquals()}\n     * if they have the same opcode, registers, source position, and other\n     * metadata.\n     *\n     * @return true in the case described above\n     */\n    public boolean contentEquals(Insn b) {\n        return opcode == b.getOpcode()\n                && position.equals(b.getPosition())\n                && (getClass() == b.getClass())\n                && equalsHandleNulls(result, b.getResult())\n                && equalsHandleNulls(sources, b.getSources())\n                && StdTypeList.equalContents(getCatches(), b.getCatches());\n    }\n\n    /**\n     * Returns an instance that is just like this one, except\n     * with new result and source registers.\n     *\n     * @param result {@code null-ok;} new result register\n     * @param sources {@code non-null;} new sources registers\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public abstract Insn withNewRegisters(RegisterSpec result,\n            RegisterSpecList sources);\n\n    /**\n     * Returns the string form of this instance, with the given bit added in\n     * the standard location for an inline argument.\n     *\n     * @param extra {@code null-ok;} the inline argument string\n     * @return {@code non-null;} the string form\n     */\n    protected final String toStringWithInline(String extra) {\n        StringBuffer sb = new StringBuffer(80);\n\n        sb.append(\"Insn{\");\n        sb.append(position);\n        sb.append(' ');\n        sb.append(opcode);\n\n        if (extra != null) {\n            sb.append(' ');\n            sb.append(extra);\n        }\n\n        sb.append(\" :: \");\n\n        if (result != null) {\n            sb.append(result);\n            sb.append(\" <- \");\n        }\n\n        sb.append(sources);\n        sb.append('}');\n\n        return sb.toString();\n    }\n\n    /**\n     * Returns the human string form of this instance, with the given\n     * bit added in the standard location for an inline argument.\n     *\n     * @param extra {@code null-ok;} the inline argument string\n     * @return {@code non-null;} the human string form\n     */\n    protected final String toHumanWithInline(String extra) {\n        StringBuffer sb = new StringBuffer(80);\n\n        sb.append(position);\n        sb.append(\": \");\n        sb.append(opcode.getNickname());\n\n        if (extra != null) {\n            sb.append(\"(\");\n            sb.append(extra);\n            sb.append(\")\");\n        }\n\n        if (result == null) {\n            sb.append(\" .\");\n        } else {\n            sb.append(\" \");\n            sb.append(result.toHuman());\n        }\n\n        sb.append(\" <-\");\n\n        int sz = sources.size();\n        if (sz == 0) {\n            sb.append(\" .\");\n        } else {\n            for (int i = 0; i < sz; i++) {\n                sb.append(\" \");\n                sb.append(sources.get(i).toHuman());\n            }\n        }\n\n        return sb.toString();\n    }\n\n\n    /**\n     * Visitor interface for this (outer) class.\n     */\n    public static interface Visitor {\n        /**\n         * Visits a {@link PlainInsn}.\n         *\n         * @param insn {@code non-null;} the instruction to visit\n         */\n        public void visitPlainInsn(PlainInsn insn);\n\n        /**\n         * Visits a {@link PlainCstInsn}.\n         *\n         * @param insn {@code non-null;} the instruction to visit\n         */\n        public void visitPlainCstInsn(PlainCstInsn insn);\n\n        /**\n         * Visits a {@link SwitchInsn}.\n         *\n         * @param insn {@code non-null;} the instruction to visit\n         */\n        public void visitSwitchInsn(SwitchInsn insn);\n\n        /**\n         * Visits a {@link ThrowingCstInsn}.\n         *\n         * @param insn {@code non-null;} the instruction to visit\n         */\n        public void visitThrowingCstInsn(ThrowingCstInsn insn);\n\n        /**\n         * Visits a {@link ThrowingInsn}.\n         *\n         * @param insn {@code non-null;} the instruction to visit\n         */\n        public void visitThrowingInsn(ThrowingInsn insn);\n\n        /**\n         * Visits a {@link FillArrayDataInsn}.\n         *\n         * @param insn {@code non-null;} the instruction to visit\n         */\n        public void visitFillArrayDataInsn(FillArrayDataInsn insn);\n    }\n\n    /**\n     * Base implementation of {@link Visitor}, which has empty method\n     * bodies for all methods.\n     */\n    public static class BaseVisitor implements Visitor {\n        /** {@inheritDoc} */\n        public void visitPlainInsn(PlainInsn insn) {\n            // This space intentionally left blank.\n        }\n\n        /** {@inheritDoc} */\n        public void visitPlainCstInsn(PlainCstInsn insn) {\n            // This space intentionally left blank.\n        }\n\n        /** {@inheritDoc} */\n        public void visitSwitchInsn(SwitchInsn insn) {\n            // This space intentionally left blank.\n        }\n\n        /** {@inheritDoc} */\n        public void visitThrowingCstInsn(ThrowingCstInsn insn) {\n            // This space intentionally left blank.\n        }\n\n        /** {@inheritDoc} */\n        public void visitThrowingInsn(ThrowingInsn insn) {\n            // This space intentionally left blank.\n        }\n\n        /** {@inheritDoc} */\n        public void visitFillArrayDataInsn(FillArrayDataInsn insn) {\n            // This space intentionally left blank.\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/InsnList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.util.FixedSizeList;\n\n/**\n * List of {@link Insn} instances.\n */\npublic final class InsnList\n        extends FixedSizeList {\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size the size of the list\n     */\n    public InsnList(int size) {\n        super(size);\n    }\n\n    /**\n     * Gets the element at the given index. It is an error to call\n     * this with the index for an element which was never set; if you\n     * do that, this will throw {@code NullPointerException}.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @return {@code non-null;} element at that index\n     */\n    public Insn get(int n) {\n        return (Insn) get0(n);\n    }\n\n    /**\n     * Sets the instruction at the given index.\n     *\n     * @param n {@code >= 0, < size();} which index\n     * @param insn {@code non-null;} the instruction to set at {@code n}\n     */\n    public void set(int n, Insn insn) {\n        set0(n, insn);\n    }\n\n    /**\n     * Gets the last instruction. This is just a convenient shorthand for\n     * {@code get(size() - 1)}.\n     *\n     * @return {@code non-null;} the last instruction\n     */\n    public Insn getLast() {\n        return get(size() - 1);\n    }\n\n    /**\n     * Visits each instruction in the list, in order.\n     *\n     * @param visitor {@code non-null;} visitor to use\n     */\n    public void forEach(Insn.Visitor visitor) {\n        int sz = size();\n\n        for (int i = 0; i < sz; i++) {\n            get(i).accept(visitor);\n        }\n    }\n\n    /**\n     * Compares the contents of this {@code InsnList} with another.\n     * The blocks must have the same number of insns, and each Insn must\n     * also return true to {@code Insn.contentEquals()}.\n     *\n     * @param b to compare\n     * @return true in the case described above.\n     */\n    public boolean contentEquals(InsnList b) {\n        if (b == null) return false;\n\n        int sz = size();\n\n        if (sz != b.size()) return false;\n\n        for (int i = 0; i < sz; i++) {\n            if (!get(i).contentEquals(b.get(i))) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Returns an instance that is identical to this one, except that\n     * the registers in each instruction are offset by the given\n     * amount. Mutability of the result is inherited from the\n     * original.\n     *\n     * @param delta the amount to offset register numbers by\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public InsnList withRegisterOffset(int delta) {\n        int sz = size();\n        InsnList result = new InsnList(sz);\n\n        for (int i = 0; i < sz; i++) {\n            Insn one = (Insn) get0(i);\n            if (one != null) {\n                result.set0(i, one.withRegisterOffset(delta));\n            }\n        }\n\n        if (isImmutable()) {\n            result.setImmutable();\n        }\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/LocalItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.cst.CstString;\n\n/**\n * A local variable item: either a name or a signature or both.\n */\npublic class LocalItem implements Comparable<LocalItem> {\n    /** {@code null-ok;} local variable name */\n    private final CstString name;\n\n    /** {@code null-ok;} local variable signature */\n    private final CstString signature;\n\n    /**\n     * Make a new item. If both name and signature are null, null is returned.\n     *\n     * TODO: intern these\n     *\n     * @param name {@code null-ok;} local variable name\n     * @param signature {@code null-ok;} local variable signature\n     * @return {@code non-null;} appropriate instance.\n     */\n    public static LocalItem make(CstString name, CstString signature) {\n        if (name == null && signature == null) {\n            return null;\n        }\n\n        return new LocalItem (name, signature);\n    }\n\n    /**\n     * Constructs instance.\n     *\n     * @param name {@code null-ok;} local variable name\n     * @param signature {@code null-ok;} local variable signature\n     */\n    private LocalItem(CstString name, CstString signature) {\n        this.name = name;\n        this.signature = signature;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (!(other instanceof LocalItem)) {\n            return false;\n        }\n\n        LocalItem local = (LocalItem) other;\n\n        return 0 == compareTo(local);\n    }\n\n    /**\n     * Compares two strings like String.compareTo(), excepts treats a null\n     * as the least-possible string value.\n     *\n     * @return negative integer, zero, or positive integer in accordance\n     * with Comparable.compareTo()\n     */\n    private static int compareHandlesNulls(CstString a, CstString b) {\n        if (a == b) {\n            return 0;\n        } else if (a == null) {\n            return -1;\n        } else if (b == null) {\n            return 1;\n        } else {\n            return a.compareTo(b);\n        }\n    }\n\n    /** {@inheritDoc} */\n    public int compareTo(LocalItem local) {\n        int ret;\n\n        ret = compareHandlesNulls(name, local.name);\n\n        if (ret != 0) {\n            return ret;\n        }\n\n        ret = compareHandlesNulls(signature, local.signature);\n\n        return ret;\n    }\n\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return (name == null ? 0 : name.hashCode()) * 31\n                + (signature == null ? 0 : signature.hashCode());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        if (name != null && signature == null) {\n            return name.toQuoted();\n        } else if (name == null && signature == null) {\n            return \"\";\n        }\n\n        return \"[\" + (name == null ? \"\" : name.toQuoted())\n                + \"|\" + (signature == null ? \"\" : signature.toQuoted());\n    }\n\n    /**\n     * Gets name.\n     *\n     * @return {@code null-ok;} name\n     */\n    public CstString getName() {\n        return name;\n    }\n\n    /**\n     * Gets signature.\n     *\n     * @return {@code null-ok;} signature\n     */\n    public CstString getSignature() {\n        return signature;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/LocalVariableExtractor.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.util.Bits;\nimport com.taobao.android.dx.util.IntList;\n\n/**\n * Code to figure out which local variables are active at which points in\n * a method.\n */\npublic final class LocalVariableExtractor {\n    /** {@code non-null;} method being extracted from */\n    private final RopMethod method;\n\n    /** {@code non-null;} block list for the method */\n    private final BasicBlockList blocks;\n\n    /** {@code non-null;} result in-progress */\n    private final LocalVariableInfo resultInfo;\n\n    /** {@code non-null;} work set indicating blocks needing to be processed */\n    private final int[] workSet;\n\n    /**\n     * Extracts out all the local variable information from the given method.\n     *\n     * @param method {@code non-null;} the method to extract from\n     * @return {@code non-null;} the extracted information\n     */\n    public static LocalVariableInfo extract(RopMethod method) {\n        LocalVariableExtractor lve = new LocalVariableExtractor(method);\n        return lve.doit();\n    }\n\n    /**\n     * Constructs an instance. This method is private. Use {@link #extract}.\n     *\n     * @param method {@code non-null;} the method to extract from\n     */\n    private LocalVariableExtractor(RopMethod method) {\n        if (method == null) {\n            throw new NullPointerException(\"method == null\");\n        }\n\n        BasicBlockList blocks = method.getBlocks();\n        int maxLabel = blocks.getMaxLabel();\n\n        this.method = method;\n        this.blocks = blocks;\n        this.resultInfo = new LocalVariableInfo(method);\n        this.workSet = Bits.makeBitSet(maxLabel);\n    }\n\n    /**\n     * Does the extraction.\n     *\n     * @return {@code non-null;} the extracted information\n     */\n    private LocalVariableInfo doit() {\n        for (int label = method.getFirstLabel();\n             label >= 0;\n             label = Bits.findFirst(workSet, 0)) {\n            Bits.clear(workSet, label);\n            processBlock(label);\n        }\n\n        resultInfo.setImmutable();\n        return resultInfo;\n    }\n\n    /**\n     * Processes a single block.\n     *\n     * @param label {@code >= 0;} label of the block to process\n     */\n    private void processBlock(int label) {\n        RegisterSpecSet primaryState = resultInfo.mutableCopyOfStarts(label);\n        BasicBlock block = blocks.labelToBlock(label);\n        InsnList insns = block.getInsns();\n        int insnSz = insns.size();\n\n        /*\n         * We may have to treat the last instruction specially: If it\n         * can (but doesn't always) throw, and the exception can be\n         * caught within the same method, then we need to use the\n         * state *before* executing it to be what is merged into\n         * exception targets.\n         */\n        boolean canThrowDuringLastInsn = block.hasExceptionHandlers() &&\n            (insns.getLast().getResult() != null);\n        int freezeSecondaryStateAt = insnSz - 1;\n        RegisterSpecSet secondaryState = primaryState;\n\n        /*\n         * Iterate over the instructions, adding information for each place\n         * that the active variable set changes.\n         */\n\n        for (int i = 0; i < insnSz; i++) {\n            if (canThrowDuringLastInsn && (i == freezeSecondaryStateAt)) {\n                // Until this point, primaryState == secondaryState.\n                primaryState.setImmutable();\n                primaryState = primaryState.mutableCopy();\n            }\n\n            Insn insn = insns.get(i);\n            RegisterSpec result;\n\n            result = insn.getLocalAssignment();\n\n            if (result == null) {\n                /*\n                 * If an assignment assigns over an existing local, make\n                 * sure to mark the local as going out of scope.\n                 */\n\n                result = insn.getResult();\n\n                if (result != null\n                        && primaryState.get(result.getReg()) != null) {\n                    primaryState.remove(primaryState.get(result.getReg()));\n                }\n                continue;\n            }\n\n            result = result.withSimpleType();\n\n            RegisterSpec already = primaryState.get(result);\n            /*\n             * The equals() check ensures we only add new info if\n             * the instruction causes a change to the set of\n             * active variables.\n             */\n            if (!result.equals(already)) {\n                /*\n                 * If this insn represents a local moving from one register\n                 * to another, remove the association between the old register\n                 * and the local.\n                 */\n                RegisterSpec previous\n                        = primaryState.localItemToSpec(result.getLocalItem());\n\n                if (previous != null\n                        && (previous.getReg() != result.getReg())) {\n\n                    primaryState.remove(previous);\n                }\n\n                resultInfo.addAssignment(insn, result);\n                primaryState.put(result);\n            }\n        }\n\n        primaryState.setImmutable();\n\n        /*\n         * Merge this state into the start state for each successor,\n         * and update the work set where required (that is, in cases\n         * where the start state for a block changes).\n         */\n\n        IntList successors = block.getSuccessors();\n        int succSz = successors.size();\n        int primarySuccessor = block.getPrimarySuccessor();\n\n        for (int i = 0; i < succSz; i++) {\n            int succ = successors.get(i);\n            RegisterSpecSet state = (succ == primarySuccessor) ?\n                primaryState : secondaryState;\n\n            if (resultInfo.mergeStarts(succ, state)) {\n                Bits.set(workSet, succ);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/LocalVariableInfo.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport com.taobao.android.dx.util.MutabilityControl;\nimport java.util.HashMap;\n\n/**\n * Container for local variable information for a particular {@link\n * RopMethod}.\n */\npublic final class LocalVariableInfo\n        extends MutabilityControl {\n    /** {@code >= 0;} the register count for the method */\n    private final int regCount;\n\n    /**\n     * {@code non-null;} {@link RegisterSpecSet} to use when indicating a block\n     * that has no locals; it is empty and immutable but has an appropriate\n     * max size for the method\n     */\n    private final RegisterSpecSet emptySet;\n\n    /**\n     * {@code non-null;} array consisting of register sets representing the\n     * sets of variables already assigned upon entry to each block,\n     * where array indices correspond to block labels\n     */\n    private final RegisterSpecSet[] blockStarts;\n\n    /** {@code non-null;} map from instructions to the variable each assigns */\n    private final HashMap<Insn, RegisterSpec> insnAssignments;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param method {@code non-null;} the method being represented by this instance\n     */\n    public LocalVariableInfo(RopMethod method) {\n        if (method == null) {\n            throw new NullPointerException(\"method == null\");\n        }\n\n        BasicBlockList blocks = method.getBlocks();\n        int maxLabel = blocks.getMaxLabel();\n\n        this.regCount = blocks.getRegCount();\n        this.emptySet = new RegisterSpecSet(regCount);\n        this.blockStarts = new RegisterSpecSet[maxLabel];\n        this.insnAssignments =\n            new HashMap<Insn, RegisterSpec>(blocks.getInstructionCount());\n\n        emptySet.setImmutable();\n    }\n\n    /**\n     * Sets the register set associated with the start of the block with\n     * the given label.\n     *\n     * @param label {@code >= 0;} the block label\n     * @param specs {@code non-null;} the register set to associate with the block\n     */\n    public void setStarts(int label, RegisterSpecSet specs) {\n        throwIfImmutable();\n\n        if (specs == null) {\n            throw new NullPointerException(\"specs == null\");\n        }\n\n        try {\n            blockStarts[label] = specs;\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"bogus label\");\n        }\n    }\n\n    /**\n     * Merges the given register set into the set for the block with the\n     * given label. If there was not already an associated set, then this\n     * is the same as calling {@link #setStarts}. Otherwise, this will\n     * merge the two sets and call {@link #setStarts} on the result of the\n     * merge.\n     *\n     * @param label {@code >= 0;} the block label\n     * @param specs {@code non-null;} the register set to merge into the start set\n     * for the block\n     * @return {@code true} if the merge resulted in an actual change\n     * to the associated set (including storing one for the first time) or\n     * {@code false} if there was no change\n     */\n    public boolean mergeStarts(int label, RegisterSpecSet specs) {\n        RegisterSpecSet start = getStarts0(label);\n        boolean changed = false;\n\n        if (start == null) {\n            setStarts(label, specs);\n            return true;\n        }\n\n        RegisterSpecSet newStart = start.mutableCopy();\n        if (start.size() != 0) {\n            newStart.intersect(specs, true);\n        } else {\n            newStart = specs.mutableCopy();\n        }\n\n        if (start.equals(newStart)) {\n            return false;\n        }\n\n        newStart.setImmutable();\n        setStarts(label, newStart);\n\n        return true;\n    }\n\n    /**\n     * Gets the register set associated with the start of the block\n     * with the given label. This returns an empty set with the appropriate\n     * max size if no set was associated with the block in question.\n     *\n     * @param label {@code >= 0;} the block label\n     * @return {@code non-null;} the associated register set\n     */\n    public RegisterSpecSet getStarts(int label) {\n        RegisterSpecSet result = getStarts0(label);\n\n        return (result != null) ? result : emptySet;\n    }\n\n    /**\n     * Gets the register set associated with the start of the given\n     * block. This is just convenient shorthand for\n     * {@code getStarts(block.getLabel())}.\n     *\n     * @param block {@code non-null;} the block in question\n     * @return {@code non-null;} the associated register set\n     */\n    public RegisterSpecSet getStarts(BasicBlock block) {\n        return getStarts(block.getLabel());\n    }\n\n    /**\n     * Gets a mutable copy of the register set associated with the\n     * start of the block with the given label. This returns a\n     * newly-allocated empty {@link RegisterSpecSet} of appropriate\n     * max size if there is not yet any set associated with the block.\n     *\n     * @param label {@code >= 0;} the block label\n     * @return {@code non-null;} the associated register set\n     */\n    public RegisterSpecSet mutableCopyOfStarts(int label) {\n        RegisterSpecSet result = getStarts0(label);\n\n        return (result != null) ?\n            result.mutableCopy() : new RegisterSpecSet(regCount);\n    }\n\n    /**\n     * Adds an assignment association for the given instruction and\n     * register spec. This throws an exception if the instruction\n     * doesn't actually perform a named variable assignment.\n     *\n     * <b>Note:</b> Although the instruction contains its own spec for\n     * the result, it still needs to be passed in explicitly to this\n     * method, since the spec that is stored here should always have a\n     * simple type and the one in the instruction can be an arbitrary\n     * {@link TypeBearer} (such as a constant value).\n     *\n     * @param insn {@code non-null;} the instruction in question\n     * @param spec {@code non-null;} the associated register spec\n     */\n    public void addAssignment(Insn insn, RegisterSpec spec) {\n        throwIfImmutable();\n\n        if (insn == null) {\n            throw new NullPointerException(\"insn == null\");\n        }\n\n        if (spec == null) {\n            throw new NullPointerException(\"spec == null\");\n        }\n\n        insnAssignments.put(insn, spec);\n    }\n\n    /**\n     * Gets the named register being assigned by the given instruction, if\n     * previously stored in this instance.\n     *\n     * @param insn {@code non-null;} instruction in question\n     * @return {@code null-ok;} the named register being assigned, if any\n     */\n    public RegisterSpec getAssignment(Insn insn) {\n        return insnAssignments.get(insn);\n    }\n\n    /**\n     * Gets the number of assignments recorded by this instance.\n     *\n     * @return {@code >= 0;} the number of assignments\n     */\n    public int getAssignmentCount() {\n        return insnAssignments.size();\n    }\n\n    public void debugDump() {\n        for (int label = 0 ; label < blockStarts.length; label++) {\n            if (blockStarts[label] == null) {\n                continue;\n            }\n\n            if (blockStarts[label] == emptySet) {\n                System.out.printf(\"%04x: empty set\\n\", label);\n            } else {\n                System.out.printf(\"%04x: %s\\n\", label, blockStarts[label]);\n            }\n        }\n    }\n\n    /**\n     * Helper method, to get the starts for a label, throwing the\n     * right exception for range problems.\n     *\n     * @param label {@code >= 0;} the block label\n     * @return {@code null-ok;} associated register set or {@code null} if there\n     * is none\n     */\n    private RegisterSpecSet getStarts0(int label) {\n        try {\n            return blockStarts[label];\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"bogus label\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/PlainCstInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\n\n/**\n * Instruction which contains an explicit reference to a constant\n * but which cannot throw an exception.\n */\npublic final class PlainCstInsn\n        extends CstInsn {\n    /**\n     * Constructs an instance.\n     *\n     * @param opcode {@code non-null;} the opcode\n     * @param position {@code non-null;} source position\n     * @param result {@code null-ok;} spec for the result, if any\n     * @param sources {@code non-null;} specs for all the sources\n     * @param cst {@code non-null;} the constant\n     */\n    public PlainCstInsn(Rop opcode, SourcePosition position,\n                        RegisterSpec result, RegisterSpecList sources,\n                        Constant cst) {\n        super(opcode, position, result, sources, cst);\n\n        if (opcode.getBranchingness() != Rop.BRANCH_NONE) {\n            throw new IllegalArgumentException(\"bogus branchingness\");\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public TypeList getCatches() {\n        return StdTypeList.EMPTY;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void accept(Visitor visitor) {\n        visitor.visitPlainCstInsn(this);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withAddedCatch(Type type) {\n        throw new UnsupportedOperationException(\"unsupported\");\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withRegisterOffset(int delta) {\n        return new PlainCstInsn(getOpcode(), getPosition(),\n                                getResult().withOffset(delta),\n                                getSources().withOffset(delta),\n                                getConstant());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withNewRegisters(RegisterSpec result,\n            RegisterSpecList sources) {\n\n        return new PlainCstInsn(getOpcode(), getPosition(),\n                                result,\n                                sources,\n                                getConstant());\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/PlainInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport com.taobao.android.dx.rop.type.TypeList;\n\n/**\n * Plain instruction, which has no embedded data and which cannot possibly\n * throw an exception.\n */\npublic final class PlainInsn\n        extends Insn {\n    /**\n     * Constructs an instance.\n     *\n     * @param opcode {@code non-null;} the opcode\n     * @param position {@code non-null;} source position\n     * @param result {@code null-ok;} spec for the result, if any\n     * @param sources {@code non-null;} specs for all the sources\n     */\n    public PlainInsn(Rop opcode, SourcePosition position,\n                     RegisterSpec result, RegisterSpecList sources) {\n        super(opcode, position, result, sources);\n\n        switch (opcode.getBranchingness()) {\n            case Rop.BRANCH_SWITCH:\n            case Rop.BRANCH_THROW: {\n                throw new IllegalArgumentException(\"bogus branchingness\");\n            }\n        }\n\n        if (result != null && opcode.getBranchingness() != Rop.BRANCH_NONE) {\n            // move-result-pseudo is required here\n            throw new IllegalArgumentException\n                    (\"can't mix branchingness with result\");\n        }\n    }\n\n    /**\n     * Constructs a single-source instance.\n     *\n     * @param opcode {@code non-null;} the opcode\n     * @param position {@code non-null;} source position\n     * @param result {@code null-ok;} spec for the result, if any\n     * @param source {@code non-null;} spec for the source\n     */\n    public PlainInsn(Rop opcode, SourcePosition position, RegisterSpec result,\n                     RegisterSpec source) {\n        this(opcode, position, result, RegisterSpecList.make(source));\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public TypeList getCatches() {\n        return StdTypeList.EMPTY;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void accept(Visitor visitor) {\n        visitor.visitPlainInsn(this);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withAddedCatch(Type type) {\n        throw new UnsupportedOperationException(\"unsupported\");\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withRegisterOffset(int delta) {\n        return new PlainInsn(getOpcode(), getPosition(),\n                             getResult().withOffset(delta),\n                             getSources().withOffset(delta));\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withSourceLiteral() {\n        RegisterSpecList sources = getSources();\n        int szSources = sources.size();\n\n        if (szSources == 0) {\n            return this;\n        }\n\n        TypeBearer lastType = sources.get(szSources - 1).getTypeBearer();\n\n        if (!lastType.isConstant()) {\n            // Check for reverse subtraction, where first source is constant\n            TypeBearer firstType = sources.get(0).getTypeBearer();\n            if (szSources == 2 && firstType.isConstant()) {\n                Constant cst = (Constant) firstType;\n                RegisterSpecList newSources = sources.withoutFirst();\n                Rop newRop = Rops.ropFor(getOpcode().getOpcode(), getResult(),\n                                             newSources, cst);\n                return new PlainCstInsn(newRop, getPosition(), getResult(),\n                                            newSources, cst);\n            }\n            return this;\n        } else {\n\n            Constant cst = (Constant) lastType;\n\n            RegisterSpecList newSources = sources.withoutLast();\n\n            Rop newRop;\n            try {\n                // Check for constant subtraction and flip it to be addition\n                int opcode = getOpcode().getOpcode();\n                if (opcode == RegOps.SUB && cst instanceof CstInteger) {\n                    opcode = RegOps.ADD;\n                    cst = CstInteger.make(-((CstInteger)cst).getValue());\n                }\n                newRop = Rops.ropFor(opcode, getResult(), newSources, cst);\n            } catch (IllegalArgumentException ex) {\n                // There's no rop for this case\n                return this;\n            }\n\n            return new PlainCstInsn(newRop, getPosition(),\n                    getResult(), newSources, cst);\n        }\n    }\n\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withNewRegisters(RegisterSpec result,\n            RegisterSpecList sources) {\n\n        return new PlainInsn(getOpcode(), getPosition(),\n                             result,\n                             sources);\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/RegOps.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * All the register-based opcodes, and related utilities.\n *\n * <p><b>Note:</b> Opcode descriptions use a rough pseudocode. {@code r}\n * is the result register, {@code x} is the first argument,\n * {@code y} is the second argument, and {@code z} is the\n * third argument. The expression which describes\n * the operation uses Java-ish syntax but is preceded by type indicators for\n * each of the values.\n */\npublic final class RegOps {\n    /** {@code nop()} */\n    public static final int NOP = 1;\n\n    /** {@code T: any type; r,x: T :: r = x;} */\n    public static final int MOVE = 2;\n\n    /** {@code T: any type; r,param(x): T :: r = param(x)} */\n    public static final int MOVE_PARAM = 3;\n\n    /**\n     * {@code T: Throwable; r: T :: r = caught_exception}.\n     * <b>Note:</b> This opcode should only ever be used in the\n     * first instruction of a block, and such blocks must be\n     * the start of an exception handler.\n     */\n    public static final int MOVE_EXCEPTION = 4;\n\n    /** {@code T: any type; r, literal: T :: r = literal;} */\n    public static final int CONST = 5;\n\n    /** {@code goto label} */\n    public static final int GOTO = 6;\n\n    /**\n     * {@code T: int or Object; x,y: T :: if (x == y) goto\n     * label}\n     */\n    public static final int IF_EQ = 7;\n\n    /**\n     * {@code T: int or Object; x,y: T :: if (x != y) goto\n     * label}\n     */\n    public static final int IF_NE = 8;\n\n    /** {@code x,y: int :: if (x < y) goto label} */\n    public static final int IF_LT = 9;\n\n    /** {@code x,y: int :: if (x >= y) goto label} */\n    public static final int IF_GE = 10;\n\n    /** {@code x,y: int :: if (x <= y) goto label} */\n    public static final int IF_LE = 11;\n\n    /** {@code x,y: int :: if (x > y) goto label} */\n    public static final int IF_GT = 12;\n\n    /** {@code x: int :: goto table[x]} */\n    public static final int SWITCH = 13;\n\n    /** {@code T: any numeric type; r,x,y: T :: r = x + y} */\n    public static final int ADD = 14;\n\n    /** {@code T: any numeric type; r,x,y: T :: r = x - y} */\n    public static final int SUB = 15;\n\n    /** {@code T: any numeric type; r,x,y: T :: r = x * y} */\n    public static final int MUL = 16;\n\n    /** {@code T: any numeric type; r,x,y: T :: r = x / y} */\n    public static final int DIV = 17;\n\n    /**\n     * {@code T: any numeric type; r,x,y: T :: r = x % y}\n     * (Java-style remainder)\n     */\n    public static final int REM = 18;\n\n    /** {@code T: any numeric type; r,x: T :: r = -x} */\n    public static final int NEG = 19;\n\n    /** {@code T: any integral type; r,x,y: T :: r = x & y} */\n    public static final int AND = 20;\n\n    /** {@code T: any integral type; r,x,y: T :: r = x | y} */\n    public static final int OR = 21;\n\n    /** {@code T: any integral type; r,x,y: T :: r = x ^ y} */\n    public static final int XOR = 22;\n\n    /**\n     * {@code T: any integral type; r,x: T; y: int :: r = x << y}\n     */\n    public static final int SHL = 23;\n\n    /**\n     * {@code T: any integral type; r,x: T; y: int :: r = x >> y}\n     * (signed right-shift)\n     */\n    public static final int SHR = 24;\n\n    /**\n     * {@code T: any integral type; r,x: T; y: int :: r = x >>> y}\n     * (unsigned right-shift)\n     */\n    public static final int USHR = 25;\n\n    /** {@code T: any integral type; r,x: T :: r = ~x} */\n    public static final int NOT = 26;\n\n    /**\n     * {@code T: any numeric type; r: int; x,y: T :: r = (x == y) ? 0\n     * : (x > y) ? 1 : -1} (Java-style \"cmpl\" where a NaN is\n     * considered \"less than\" all other values; also used for integral\n     * comparisons)\n     */\n    public static final int CMPL = 27;\n\n    /**\n     * {@code T: any floating point type; r: int; x,y: T :: r = (x == y) ? 0\n     * : (x < y) ? -1 : 1} (Java-style \"cmpg\" where a NaN is\n     * considered \"greater than\" all other values)\n     */\n    public static final int CMPG = 28;\n\n    /**\n     * {@code T: any numeric type; U: any numeric type; r: T; x: U ::\n     * r = (T) x} (numeric type conversion between the four\n     * \"real\" numeric types)\n     */\n    public static final int CONV = 29;\n\n    /**\n     * {@code r,x: int :: r = (x << 24) >> 24} (Java-style\n     * convert int to byte)\n     */\n    public static final int TO_BYTE = 30;\n\n    /**\n     * {@code r,x: int :: r = x & 0xffff} (Java-style convert int to char)\n     */\n    public static final int TO_CHAR = 31;\n\n    /**\n     * {@code r,x: int :: r = (x << 16) >> 16} (Java-style\n     * convert int to short)\n     */\n    public static final int TO_SHORT = 32;\n\n    /** {@code T: return type for the method; x: T; return x} */\n    public static final int RETURN = 33;\n\n    /** {@code T: any type; r: int; x: T[]; :: r = x.length} */\n    public static final int ARRAY_LENGTH = 34;\n\n    /** {@code x: Throwable :: throw(x)} */\n    public static final int THROW = 35;\n\n    /** {@code x: Object :: monitorenter(x)} */\n    public static final int MONITOR_ENTER = 36;\n\n    /** {@code x: Object :: monitorexit(x)} */\n    public static final int MONITOR_EXIT = 37;\n\n    /** {@code T: any type; r: T; x: T[]; y: int :: r = x[y]} */\n    public static final int AGET = 38;\n\n    /** {@code T: any type; x: T; y: T[]; z: int :: x[y] = z} */\n    public static final int APUT = 39;\n\n    /**\n     * {@code T: any non-array object type :: r =\n     * alloc(T)} (allocate heap space for an object)\n     */\n    public static final int NEW_INSTANCE = 40;\n\n    /** {@code T: any array type; r: T; x: int :: r = new T[x]} */\n    public static final int NEW_ARRAY = 41;\n\n    /**\n     * {@code T: any array type; r: T; x: int; v0..vx: T :: r = new T[x]\n     * {v0, ..., vx}}\n     */\n    public static final int FILLED_NEW_ARRAY = 42;\n\n    /**\n     * {@code T: any object type; x: Object :: (T) x} (can\n     * throw {@code ClassCastException})\n     */\n    public static final int CHECK_CAST = 43;\n\n    /**\n     * {@code T: any object type; x: Object :: x instanceof T}\n     */\n    public static final int INSTANCE_OF = 44;\n\n    /**\n     * {@code T: any type; r: T; x: Object; f: instance field spec of\n     * type T :: r = x.f}\n     */\n    public static final int GET_FIELD = 45;\n\n    /**\n     * {@code T: any type; r: T; f: static field spec of type T :: r =\n     * f}\n     */\n    public static final int GET_STATIC = 46;\n\n    /**\n     * {@code T: any type; x: T; y: Object; f: instance field spec of type\n     * T :: y.f = x}\n     */\n    public static final int PUT_FIELD = 47;\n\n    /**\n     * {@code T: any type; f: static field spec of type T; x: T :: f = x}\n     */\n    public static final int PUT_STATIC = 48;\n\n    /**\n     * {@code Tr, T0, T1...: any types; r: Tr; m: static method spec;\n     * y0: T0; y1: T1 ... :: r = m(y0, y1, ...)} (call static\n     * method)\n     */\n    public static final int INVOKE_STATIC = 49;\n\n    /**\n     * {@code Tr, T0, T1...: any types; r: Tr; x: Object; m: instance method\n     * spec; y0: T0; y1: T1 ... :: r = x.m(y0, y1, ...)} (call normal\n     * virtual method)\n     */\n    public static final int INVOKE_VIRTUAL = 50;\n\n    /**\n     * {@code Tr, T0, T1...: any types; r: Tr; x: Object; m: instance method\n     * spec; y0: T0; y1: T1 ... :: r = x.m(y0, y1, ...)} (call\n     * superclass virtual method)\n     */\n    public static final int INVOKE_SUPER = 51;\n\n    /**\n     * {@code Tr, T0, T1...: any types; r: Tr; x: Object; m: instance method\n     * spec; y0: T0; y1: T1 ... :: r = x.m(y0, y1, ...)} (call\n     * direct/special method)\n     */\n    public static final int INVOKE_DIRECT = 52;\n\n    /**\n     * {@code Tr, T0, T1...: any types; r: Tr; x: Object; m: interface\n     * (instance) method spec; y0: T0; y1: T1 ... :: r = x.m(y0, y1,\n     * ...)} (call interface method)\n     */\n    public static final int INVOKE_INTERFACE = 53;\n\n    /**\n     * {@code T0: any type; name: local variable name  :: mark(name,T0)}\n     * (mark beginning or end of local variable name)\n     */\n    public static final int MARK_LOCAL = 54;\n\n    /**\n     * {@code T: Any type; r: T :: r = return_type}.\n     * <b>Note:</b> This opcode should only ever be used in the\n     * first instruction of a block following an invoke-*.\n     */\n    public static final int MOVE_RESULT = 55;\n\n    /**\n     * {@code T: Any type; r: T :: r = return_type}.\n     * <b>Note:</b> This opcode should only ever be used in the\n     * first instruction of a block following a non-invoke throwing insn\n     */\n    public static final int MOVE_RESULT_PSEUDO = 56;\n\n    /** {@code T: Any primitive type; v0..vx: T :: {v0, ..., vx}} */\n    public static final int FILL_ARRAY_DATA = 57;\n\n    /**\n     * This class is uninstantiable.\n     */\n    private RegOps() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Gets the name of the given opcode.\n     *\n     * @param opcode the opcode\n     * @return {@code non-null;} its name\n     */\n    public static String opName(int opcode) {\n        switch (opcode) {\n            case NOP: return \"nop\";\n            case MOVE: return \"move\";\n            case MOVE_PARAM: return \"move-param\";\n            case MOVE_EXCEPTION: return \"move-exception\";\n            case CONST: return \"const\";\n            case GOTO: return \"goto\";\n            case IF_EQ: return \"if-eq\";\n            case IF_NE: return \"if-ne\";\n            case IF_LT: return \"if-lt\";\n            case IF_GE: return \"if-ge\";\n            case IF_LE: return \"if-le\";\n            case IF_GT: return \"if-gt\";\n            case SWITCH: return \"switch\";\n            case ADD: return \"add\";\n            case SUB: return \"sub\";\n            case MUL: return \"mul\";\n            case DIV: return \"div\";\n            case REM: return \"rem\";\n            case NEG: return \"neg\";\n            case AND: return \"and\";\n            case OR: return \"or\";\n            case XOR: return \"xor\";\n            case SHL: return \"shl\";\n            case SHR: return \"shr\";\n            case USHR: return \"ushr\";\n            case NOT: return \"not\";\n            case CMPL: return \"cmpl\";\n            case CMPG: return \"cmpg\";\n            case CONV: return \"conv\";\n            case TO_BYTE: return \"to-byte\";\n            case TO_CHAR: return \"to-char\";\n            case TO_SHORT: return \"to-short\";\n            case RETURN: return \"return\";\n            case ARRAY_LENGTH: return \"array-length\";\n            case THROW: return \"throw\";\n            case MONITOR_ENTER: return \"monitor-enter\";\n            case MONITOR_EXIT: return \"monitor-exit\";\n            case AGET: return \"aget\";\n            case APUT: return \"aput\";\n            case NEW_INSTANCE: return \"new-instance\";\n            case NEW_ARRAY: return \"new-array\";\n            case FILLED_NEW_ARRAY: return \"filled-new-array\";\n            case CHECK_CAST: return \"check-cast\";\n            case INSTANCE_OF: return \"instance-of\";\n            case GET_FIELD: return \"get-field\";\n            case GET_STATIC: return \"get-static\";\n            case PUT_FIELD: return \"put-field\";\n            case PUT_STATIC: return \"put-static\";\n            case INVOKE_STATIC: return \"invoke-static\";\n            case INVOKE_VIRTUAL: return \"invoke-virtual\";\n            case INVOKE_SUPER: return \"invoke-super\";\n            case INVOKE_DIRECT: return \"invoke-direct\";\n            case INVOKE_INTERFACE: return \"invoke-interface\";\n            case MOVE_RESULT: return \"move-result\";\n            case MOVE_RESULT_PSEUDO: return \"move-result-pseudo\";\n            case FILL_ARRAY_DATA: return \"fill-array-data\";\n        }\n\n        return \"unknown-\" + Hex.u1(opcode);\n    }\n\n    /**\n     * Given an IF_* RegOp, returns the right-to-left flipped version. For\n     * example, IF_GT becomes IF_LT.\n     *\n     * @param opcode An IF_* RegOp\n     * @return flipped IF Regop\n     */\n    public static int flippedIfOpcode(final int opcode) {\n        switch (opcode) {\n            case RegOps.IF_EQ:\n            case RegOps.IF_NE:\n                return opcode;\n            case RegOps.IF_LT:\n                return RegOps.IF_GT;\n            case RegOps.IF_GE:\n                return RegOps.IF_LE;\n            case RegOps.IF_LE:\n                return RegOps.IF_GE;\n            case RegOps.IF_GT:\n                return RegOps.IF_LT;\n            default:\n                throw new RuntimeException(\"Unrecognized IF regop: \" + opcode);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/RegisterSpec.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport com.taobao.android.dx.util.ToHuman;\nimport java.util.HashMap;\n\n/**\n * Combination of a register number and a type, used as the sources and\n * destinations of register-based operations.\n */\npublic final class RegisterSpec\n        implements TypeBearer, ToHuman, Comparable<RegisterSpec> {\n    /** {@code non-null;} string to prefix register numbers with */\n    public static final String PREFIX = \"v\";\n\n    /** {@code non-null;} intern table for instances */\n    private static final HashMap<Object, RegisterSpec> theInterns =\n        new HashMap<Object, RegisterSpec>(1000);\n\n    /** {@code non-null;} common comparison instance used while interning */\n    private static final ForComparison theInterningItem = new ForComparison();\n\n    /** {@code >= 0;} register number */\n    private final int reg;\n\n    /** {@code non-null;} type loaded or stored */\n    private final TypeBearer type;\n\n    /**\n     * {@code null-ok;} local variable info associated with this register,\n     * if any\n     */\n    private final LocalItem local;\n\n    /**\n     * Intern the given triple as an instance of this class.\n     *\n     * @param reg {@code >= 0;} the register number\n     * @param type {@code non-null;} the type (or possibly actual value) which\n     * is loaded from or stored to the indicated register\n     * @param local {@code null-ok;} the associated local variable, if any\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    private static RegisterSpec intern(int reg, TypeBearer type,\n            LocalItem local) {\n        synchronized (theInterns) {\n            theInterningItem.set(reg, type, local);\n            RegisterSpec found = theInterns.get(theInterningItem);\n\n            if (found != null) {\n                return found;\n            }\n\n            found = theInterningItem.toRegisterSpec();\n            theInterns.put(found, found);\n            return found;\n        }\n    }\n\n    /**\n     * Returns an instance for the given register number and type, with\n     * no variable info. This method is allowed to return shared\n     * instances (but doesn't necessarily do so).\n     *\n     * @param reg {@code >= 0;} the register number\n     * @param type {@code non-null;} the type (or possibly actual value) which\n     * is loaded from or stored to the indicated register\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static RegisterSpec make(int reg, TypeBearer type) {\n        return intern(reg, type, null);\n    }\n\n    /**\n     * Returns an instance for the given register number, type, and\n     * variable info. This method is allowed to return shared\n     * instances (but doesn't necessarily do so).\n     *\n     * @param reg {@code >= 0;} the register number\n     * @param type {@code non-null;} the type (or possibly actual value) which\n     * is loaded from or stored to the indicated register\n     * @param local {@code non-null;} the associated local variable\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static RegisterSpec make(int reg, TypeBearer type,\n            LocalItem local) {\n        if (local == null) {\n            throw new NullPointerException(\"local  == null\");\n        }\n\n        return intern(reg, type, local);\n    }\n\n    /**\n     * Returns an instance for the given register number, type, and\n     * variable info. This method is allowed to return shared\n     * instances (but doesn't necessarily do so).\n     *\n     * @param reg {@code >= 0;} the register number\n     * @param type {@code non-null;} the type (or possibly actual value) which\n     * is loaded from or stored to the indicated register\n     * @param local {@code null-ok;} the associated variable info or null for\n     * none\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static RegisterSpec makeLocalOptional(\n            int reg, TypeBearer type, LocalItem local) {\n\n        return intern(reg, type, local);\n    }\n\n    /**\n     * Gets the string form for the given register number.\n     *\n     * @param reg {@code >= 0;} the register number\n     * @return {@code non-null;} the string form\n     */\n    public static String regString(int reg) {\n        return PREFIX + reg;\n    }\n\n    /**\n     * Constructs an instance. This constructor is private. Use\n     * {@link #make}.\n     *\n     * @param reg {@code >= 0;} the register number\n     * @param type {@code non-null;} the type (or possibly actual value) which\n     * is loaded from or stored to the indicated register\n     * @param local {@code null-ok;} the associated local variable, if any\n     */\n    private RegisterSpec(int reg, TypeBearer type, LocalItem local) {\n        if (reg < 0) {\n            throw new IllegalArgumentException(\"reg < 0\");\n        }\n\n        if (type == null) {\n            throw new NullPointerException(\"type == null\");\n        }\n\n        this.reg = reg;\n        this.type = type;\n        this.local = local;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (!(other instanceof RegisterSpec)) {\n            if (other instanceof ForComparison) {\n                ForComparison fc = (ForComparison) other;\n                return equals(fc.reg, fc.type, fc.local);\n            }\n            return false;\n        }\n\n        RegisterSpec spec = (RegisterSpec) other;\n        return equals(spec.reg, spec.type, spec.local);\n    }\n\n    /**\n     * Like {@code equals}, but only consider the simple types of the\n     * registers. That is, this compares {@code getType()} on the types\n     * to ignore whatever arbitrary extra stuff might be carried around\n     * by an outer {@link TypeBearer}.\n     *\n     * @param other {@code null-ok;} spec to compare to\n     * @return {@code true} iff {@code this} and {@code other} are equal\n     * in the stated way\n     */\n    public boolean equalsUsingSimpleType(RegisterSpec other) {\n        if (!matchesVariable(other)) {\n            return false;\n        }\n\n        return (reg == other.reg);\n    }\n\n    /**\n     * Like {@link #equalsUsingSimpleType} but ignoring the register number.\n     * This is useful to determine if two instances refer to the \"same\"\n     * local variable.\n     *\n     * @param other {@code null-ok;} spec to compare to\n     * @return {@code true} iff {@code this} and {@code other} are equal\n     * in the stated way\n     */\n    public boolean matchesVariable(RegisterSpec other) {\n        if (other == null) {\n            return false;\n        }\n\n        return type.getType().equals(other.type.getType())\n            && ((local == other.local)\n                    || ((local != null) && local.equals(other.local)));\n    }\n\n    /**\n     * Helper for {@link #equals} and {@link #ForComparison.equals},\n     * which actually does the test.\n     *\n     * @param reg value of the instance variable, for another instance\n     * @param type value of the instance variable, for another instance\n     * @param local value of the instance variable, for another instance\n     * @return whether this instance is equal to one with the given\n     * values\n     */\n    private boolean equals(int reg, TypeBearer type, LocalItem local) {\n        return (this.reg == reg)\n            && this.type.equals(type)\n            && ((this.local == local)\n                    || ((this.local != null) && this.local.equals(local)));\n    }\n\n    /**\n     * Compares by (in priority order) register number, unwrapped type\n     * (that is types not {@link TypeBearer}s, and local info.\n     *\n     * @param other {@code non-null;} spec to compare to\n     * @return {@code -1..1;} standard result of comparison\n     */\n    public int compareTo(RegisterSpec other) {\n        if (this.reg < other.reg) {\n            return -1;\n        } else if (this.reg > other.reg) {\n            return 1;\n        }\n\n        int compare = type.getType().compareTo(other.type.getType());\n\n        if (compare != 0) {\n            return compare;\n        }\n\n        if (this.local == null) {\n            return (other.local == null) ? 0 : -1;\n        } else if (other.local == null) {\n            return 1;\n        }\n\n        return this.local.compareTo(other.local);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return hashCodeOf(reg, type, local);\n    }\n\n    /**\n     * Helper for {@link #hashCode} and {@link #ForComparison.hashCode},\n     * which actually does the calculation.\n     *\n     * @param reg value of the instance variable\n     * @param type value of the instance variable\n     * @param local value of the instance variable\n     * @return the hash code\n     */\n    private static int hashCodeOf(int reg, TypeBearer type, LocalItem local) {\n        int hash = (local != null) ? local.hashCode() : 0;\n\n        hash = (hash * 31 + type.hashCode()) * 31 + reg;\n        return hash;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return toString0(false);\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return toString0(true);\n    }\n\n    /** {@inheritDoc} */\n    public Type getType() {\n        return type.getType();\n    }\n\n    /** {@inheritDoc} */\n    public TypeBearer getFrameType() {\n        return type.getFrameType();\n    }\n\n    /** {@inheritDoc} */\n    public final int getBasicType() {\n        return type.getBasicType();\n    }\n\n    /** {@inheritDoc} */\n    public final int getBasicFrameType() {\n        return type.getBasicFrameType();\n    }\n\n    /** {@inheritDoc} */\n    public final boolean isConstant() {\n        return false;\n    }\n\n    /**\n     * Gets the register number.\n     *\n     * @return {@code >= 0;} the register number\n     */\n    public int getReg() {\n        return reg;\n    }\n\n    /**\n     * Gets the type (or actual value) which is loaded from or stored\n     * to the register associated with this instance.\n     *\n     * @return {@code non-null;} the type\n     */\n    public TypeBearer getTypeBearer() {\n        return type;\n    }\n\n    /**\n     * Gets the variable info associated with this instance, if any.\n     *\n     * @return {@code null-ok;} the variable info, or {@code null} if this\n     * instance has none\n     */\n    public LocalItem getLocalItem() {\n        return local;\n    }\n\n    /**\n     * Gets the next available register number after the one in this\n     * instance. This is equal to the register number plus the width\n     * (category) of the type used. Among other things, this may also\n     * be used to determine the minimum required register count\n     * implied by this instance.\n     *\n     * @return {@code >= 0;} the required registers size\n     */\n    public int getNextReg() {\n        return reg + getCategory();\n    }\n\n    /**\n     * Gets the category of this instance's type. This is just a convenient\n     * shorthand for {@code getType().getCategory()}.\n     *\n     * @see #isCategory1\n     * @see #isCategory2\n     * @return {@code 1..2;} the category of this instance's type\n     */\n    public int getCategory() {\n        return type.getType().getCategory();\n    }\n\n    /**\n     * Gets whether this instance's type is category 1. This is just a\n     * convenient shorthand for {@code getType().isCategory1()}.\n     *\n     * @see #getCategory\n     * @see #isCategory2\n     * @return whether or not this instance's type is of category 1\n     */\n    public boolean isCategory1() {\n        return type.getType().isCategory1();\n    }\n\n    /**\n     * Gets whether this instance's type is category 2. This is just a\n     * convenient shorthand for {@code getType().isCategory2()}.\n     *\n     * @see #getCategory\n     * @see #isCategory1\n     * @return whether or not this instance's type is of category 2\n     */\n    public boolean isCategory2() {\n        return type.getType().isCategory2();\n    }\n\n    /**\n     * Gets the string form for just the register number of this instance.\n     *\n     * @return {@code non-null;} the register string form\n     */\n    public String regString() {\n        return regString(reg);\n    }\n\n    /**\n     * Returns an instance that is the intersection between this instance\n     * and the given one, if any. The intersection is defined as follows:\n     *\n     * <ul>\n     *   <li>If {@code other} is {@code null}, then the result\n     *     is {@code null}.\n     *   <li>If the register numbers don't match, then the intersection\n     *     is {@code null}. Otherwise, the register number of the\n     *     intersection is the same as the one in the two instances.</li>\n     *   <li>If the types returned by {@code getType()} are not\n     *     {@code equals()}, then the intersection is null.</li>\n     *   <li>If the type bearers returned by {@code getTypeBearer()}\n     *     are {@code equals()}, then the intersection's type bearer\n     *     is the one from this instance. Otherwise, the intersection's\n     *     type bearer is the {@code getType()} of this instance.</li>\n     *   <li>If the locals are {@code equals()}, then the local info\n     *     of the intersection is the local info of this instance. Otherwise,\n     *     the local info of the intersection is {@code null}.</li>\n     * </ul>\n     *\n     * @param other {@code null-ok;} instance to intersect with (or {@code null})\n     * @param localPrimary whether local variables are primary to the\n     * intersection; if {@code true}, then the only non-null\n     * results occur when registers being intersected have equal local\n     * infos (or both have {@code null} local infos)\n     * @return {@code null-ok;} the intersection\n     */\n    public RegisterSpec intersect(RegisterSpec other, boolean localPrimary) {\n        if (this == other) {\n            // Easy out.\n            return this;\n        }\n\n        if ((other == null) || (reg != other.getReg())) {\n            return null;\n        }\n\n        LocalItem resultLocal =\n            ((local == null) || !local.equals(other.getLocalItem()))\n            ? null : local;\n        boolean sameName = (resultLocal == local);\n\n        if (localPrimary && !sameName) {\n            return null;\n        }\n\n        Type thisType = getType();\n        Type otherType = other.getType();\n\n        // Note: Types are always interned.\n        if (thisType != otherType) {\n            return null;\n        }\n\n        TypeBearer resultTypeBearer =\n            type.equals(other.getTypeBearer()) ? type : thisType;\n\n        if ((resultTypeBearer == type) && sameName) {\n            // It turns out that the intersection is \"this\" after all.\n            return this;\n        }\n\n        return (resultLocal == null) ? make(reg, resultTypeBearer) :\n            make(reg, resultTypeBearer, resultLocal);\n    }\n\n    /**\n     * Returns an instance that is identical to this one, except that the\n     * register number is replaced by the given one.\n     *\n     * @param newReg {@code >= 0;} the new register number\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public RegisterSpec withReg(int newReg) {\n        if (reg == newReg) {\n            return this;\n        }\n\n        return makeLocalOptional(newReg, type, local);\n    }\n\n    /**\n     * Returns an instance that is identical to this one, except that\n     * the type is replaced by the given one.\n     *\n     * @param newType {@code non-null;} the new type\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public RegisterSpec withType(TypeBearer newType) {\n        return makeLocalOptional(reg, newType, local);\n    }\n\n    /**\n     * Returns an instance that is identical to this one, except that the\n     * register number is offset by the given amount.\n     *\n     * @param delta the amount to offset the register number by\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public RegisterSpec withOffset(int delta) {\n        if (delta == 0) {\n            return this;\n        }\n\n        return withReg(reg + delta);\n    }\n\n    /**\n     * Returns an instance that is identical to this one, except that\n     * the type bearer is replaced by the actual underlying type\n     * (thereby stripping off non-type information) with any\n     * initialization information stripped away as well.\n     *\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public RegisterSpec withSimpleType() {\n        TypeBearer orig = type;\n        Type newType;\n\n        if (orig instanceof Type) {\n            newType = (Type) orig;\n        } else {\n            newType = orig.getType();\n        }\n\n        if (newType.isUninitialized()) {\n            newType = newType.getInitializedType();\n        }\n\n        if (newType == orig) {\n            return this;\n        }\n\n        return makeLocalOptional(reg, newType, local);\n    }\n\n    /**\n     * Returns an instance that is identical to this one except that the\n     * local variable is as specified in the parameter.\n     *\n     * @param local {@code null-ok;} the local item or null for none\n     * @return an appropriate instance\n     */\n    public RegisterSpec withLocalItem(LocalItem local) {\n        if ((this.local== local)\n                    || ((this.local != null) && this.local.equals(local))) {\n\n            return this;\n        }\n\n        return makeLocalOptional(reg, type, local);\n    }\n\n    /**\n     * @return boolean specifying if this instance is an even register or not.\n     */\n    public boolean isEvenRegister() {\n      return ((getReg() & 1) == 0);\n    }\n\n    /**\n     * Helper for {@link #toString} and {@link #toHuman}.\n     *\n     * @param human whether to be human-oriented\n     * @return {@code non-null;} the string form\n     */\n    private String toString0(boolean human) {\n        StringBuffer sb = new StringBuffer(40);\n\n        sb.append(regString());\n        sb.append(\":\");\n\n        if (local != null) {\n            sb.append(local.toString());\n        }\n\n        Type justType = type.getType();\n        sb.append(justType);\n\n        if (justType != type) {\n            sb.append(\"=\");\n            if (human && (type instanceof CstString)) {\n                sb.append(((CstString) type).toQuoted());\n            } else if (human && (type instanceof Constant)) {\n                sb.append(type.toHuman());\n            } else {\n                sb.append(type);\n            }\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Holder of register spec data for the purposes of comparison (so that\n     * {@code RegisterSpec} itself can still keep {@code final}\n     * instance variables.\n     */\n    private static class ForComparison {\n        /** {@code >= 0;} register number */\n        private int reg;\n\n        /** {@code non-null;} type loaded or stored */\n        private TypeBearer type;\n\n        /**\n         * {@code null-ok;} local variable associated with this\n         * register, if any\n         */\n        private LocalItem local;\n\n        /**\n         * Set all the instance variables.\n         *\n         * @param reg {@code >= 0;} the register number\n         * @param type {@code non-null;} the type (or possibly actual\n         * value) which is loaded from or stored to the indicated\n         * register\n         * @param local {@code null-ok;} the associated local variable, if any\n         * @return {@code non-null;} an appropriately-constructed instance\n         */\n        public void set(int reg, TypeBearer type, LocalItem local) {\n            this.reg = reg;\n            this.type = type;\n            this.local = local;\n        }\n\n        /**\n         * Construct a {@code RegisterSpec} of this instance's\n         * contents.\n         *\n         * @return {@code non-null;} an appropriately-constructed instance\n         */\n        public RegisterSpec toRegisterSpec() {\n            return new RegisterSpec(reg, type, local);\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public boolean equals(Object other) {\n            if (!(other instanceof RegisterSpec)) {\n                return false;\n            }\n\n            RegisterSpec spec = (RegisterSpec) other;\n            return spec.equals(reg, type, local);\n        }\n\n        /** {@inheritDoc} */\n        @Override\n        public int hashCode() {\n            return hashCodeOf(reg, type, local);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/RegisterSpecList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.FixedSizeList;\nimport java.util.BitSet;\n\n/**\n * List of {@link RegisterSpec} instances.\n */\npublic final class RegisterSpecList\n        extends FixedSizeList implements TypeList {\n    /** {@code non-null;} no-element instance */\n    public static final RegisterSpecList EMPTY = new RegisterSpecList(0);\n\n    /**\n     * Makes a single-element instance.\n     *\n     * @param spec {@code non-null;} the element\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static RegisterSpecList make(RegisterSpec spec) {\n        RegisterSpecList result = new RegisterSpecList(1);\n        result.set(0, spec);\n        return result;\n    }\n\n    /**\n     * Makes a two-element instance.\n     *\n     * @param spec0 {@code non-null;} the first element\n     * @param spec1 {@code non-null;} the second element\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static RegisterSpecList make(RegisterSpec spec0,\n                                        RegisterSpec spec1) {\n        RegisterSpecList result = new RegisterSpecList(2);\n        result.set(0, spec0);\n        result.set(1, spec1);\n        return result;\n    }\n\n    /**\n     * Makes a three-element instance.\n     *\n     * @param spec0 {@code non-null;} the first element\n     * @param spec1 {@code non-null;} the second element\n     * @param spec2 {@code non-null;} the third element\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static RegisterSpecList make(RegisterSpec spec0, RegisterSpec spec1,\n                                        RegisterSpec spec2) {\n        RegisterSpecList result = new RegisterSpecList(3);\n        result.set(0, spec0);\n        result.set(1, spec1);\n        result.set(2, spec2);\n        return result;\n    }\n\n    /**\n     * Makes a four-element instance.\n     *\n     * @param spec0 {@code non-null;} the first element\n     * @param spec1 {@code non-null;} the second element\n     * @param spec2 {@code non-null;} the third element\n     * @param spec3 {@code non-null;} the fourth element\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static RegisterSpecList make(RegisterSpec spec0, RegisterSpec spec1,\n                                        RegisterSpec spec2,\n                                        RegisterSpec spec3) {\n        RegisterSpecList result = new RegisterSpecList(4);\n        result.set(0, spec0);\n        result.set(1, spec1);\n        result.set(2, spec2);\n        result.set(3, spec3);\n        return result;\n    }\n\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size the size of the list\n     */\n    public RegisterSpecList(int size) {\n        super(size);\n    }\n\n    /** {@inheritDoc} */\n    public Type getType(int n) {\n        return get(n).getType().getType();\n    }\n\n    /** {@inheritDoc} */\n    public int getWordCount() {\n        int sz = size();\n        int result = 0;\n\n        for (int i = 0; i < sz; i++) {\n            result += getType(i).getCategory();\n        }\n\n        return result;\n    }\n\n    /** {@inheritDoc} */\n    public TypeList withAddedType(Type type) {\n        throw new UnsupportedOperationException(\"unsupported\");\n    }\n\n    /**\n     * Gets the indicated element. It is an error to call this with the\n     * index for an element which was never set; if you do that, this\n     * will throw {@code NullPointerException}.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @return {@code non-null;} the indicated element\n     */\n    public RegisterSpec get(int n) {\n        return (RegisterSpec) get0(n);\n    }\n\n    /**\n     * Returns a RegisterSpec in this list that uses the specified register,\n     * or null if there is none in this list.\n     * @param reg Register to find\n     * @return RegisterSpec that uses argument or null.\n     */\n    public RegisterSpec specForRegister(int reg) {\n        int sz = size();\n        for (int i = 0; i < sz; i++) {\n            RegisterSpec rs;\n\n            rs = get(i);\n\n            if (rs.getReg() == reg) {\n                return rs;\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Returns the index of a RegisterSpec in this list that uses the specified\n     * register, or -1 if none in this list uses the register.\n     * @param reg Register to find\n     * @return index of RegisterSpec or -1\n     */\n    public int indexOfRegister(int reg) {\n        int sz = size();\n        for (int i = 0; i < sz; i++) {\n            RegisterSpec rs;\n\n            rs = get(i);\n\n            if (rs.getReg() == reg) {\n                return i;\n            }\n        }\n\n        return -1;\n    }\n\n    /**\n     * Sets the element at the given index.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @param spec {@code non-null;} the value to store\n     */\n    public void set(int n, RegisterSpec spec) {\n        set0(n, spec);\n    }\n\n    /**\n     * Gets the minimum required register count implied by this\n     * instance. This is equal to the highest register number referred\n     * to plus the widest width (largest category) of the type used in\n     * that register.\n     *\n     * @return {@code >= 0;} the required registers size\n     */\n    public int getRegistersSize() {\n        int sz = size();\n        int result = 0;\n\n        for (int i = 0; i < sz; i++) {\n            RegisterSpec spec = (RegisterSpec) get0(i);\n            if (spec != null) {\n                int min = spec.getNextReg();\n                if (min > result) {\n                    result = min;\n                }\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * Returns a new instance, which is the same as this instance,\n     * except that it has an additional element prepended to the original.\n     * Mutability of the result is inherited from the original.\n     *\n     * @param spec {@code non-null;} the new first spec (to prepend)\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public RegisterSpecList withFirst(RegisterSpec spec) {\n        int sz = size();\n        RegisterSpecList result = new RegisterSpecList(sz + 1);\n\n        for (int i = 0; i < sz; i++) {\n            result.set0(i + 1, get0(i));\n        }\n\n        result.set0(0, spec);\n        if (isImmutable()) {\n            result.setImmutable();\n        }\n\n        return result;\n    }\n\n    /**\n     * Returns a new instance, which is the same as this instance,\n     * except that its first element is removed. Mutability of the\n     * result is inherited from the original.\n     *\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public RegisterSpecList withoutFirst() {\n        int newSize = size() - 1;\n\n        if (newSize == 0) {\n            return EMPTY;\n        }\n\n        RegisterSpecList result = new RegisterSpecList(newSize);\n\n        for (int i = 0; i < newSize; i++) {\n            result.set0(i, get0(i + 1));\n        }\n\n        if (isImmutable()) {\n            result.setImmutable();\n        }\n\n        return result;\n    }\n\n    /**\n     * Returns a new instance, which is the same as this instance,\n     * except that its last element is removed. Mutability of the\n     * result is inherited from the original.\n     *\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public RegisterSpecList withoutLast() {\n        int newSize = size() - 1;\n\n        if (newSize == 0) {\n            return EMPTY;\n        }\n\n        RegisterSpecList result = new RegisterSpecList(newSize);\n\n        for (int i = 0; i < newSize; i++) {\n            result.set0(i, get0(i));\n        }\n\n        if (isImmutable()) {\n            result.setImmutable();\n        }\n\n        return result;\n    }\n\n    /**\n     * Returns a new instance, which contains a subset of the elements\n     * specified by the given BitSet. Indexes in the BitSet with a zero\n     * are included, while indexes with a one are excluded. Mutability\n     * of the result is inherited from the original.\n     *\n     * @param exclusionSet {@code non-null;} set of registers to exclude\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public RegisterSpecList subset(BitSet exclusionSet) {\n        int newSize = size() - exclusionSet.cardinality();\n\n        if (newSize == 0) {\n            return EMPTY;\n        }\n\n        RegisterSpecList result = new RegisterSpecList(newSize);\n\n        int newIndex = 0;\n        for (int oldIndex = 0; oldIndex < size(); oldIndex++) {\n            if (!exclusionSet.get(oldIndex)) {\n                result.set0(newIndex, get0(oldIndex));\n                newIndex++;\n            }\n        }\n\n        if (isImmutable()) {\n            result.setImmutable();\n        }\n\n        return result;\n    }\n\n    /**\n     * Returns an instance that is identical to this one, except that\n     * all register numbers are offset by the given amount. Mutability\n     * of the result is inherited from the original.\n     *\n     * @param delta the amount to offset the register numbers by\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public RegisterSpecList withOffset(int delta) {\n        int sz = size();\n\n        if (sz == 0) {\n            // Don't bother making a new zero-element instance.\n            return this;\n        }\n\n        RegisterSpecList result = new RegisterSpecList(sz);\n\n        for (int i = 0; i < sz; i++) {\n            RegisterSpec one = (RegisterSpec) get0(i);\n            if (one != null) {\n                result.set0(i, one.withOffset(delta));\n            }\n        }\n\n        if (isImmutable()) {\n            result.setImmutable();\n        }\n\n        return result;\n    }\n\n    /**\n     * Returns an instance that is identical to this one, except that\n     * all incompatible register numbers are renumbered sequentially from\n     * the given base, with the first number duplicated if indicated. If\n     * a null BitSet is given, it indicates all registers are incompatible.\n     *\n     * @param base the base register number\n     * @param duplicateFirst whether to duplicate the first number\n     * @param compatRegs {@code null-ok;} either a {@code non-null} set of\n     * compatible registers, or {@code null} to indicate all registers are\n     * incompatible\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public RegisterSpecList withExpandedRegisters(int base,\n                                                  boolean duplicateFirst,\n                                                  BitSet compatRegs) {\n        int sz = size();\n\n        if (sz == 0) {\n            // Don't bother making a new zero-element instance.\n            return this;\n        }\n\n        Expander expander = new Expander(this, compatRegs, base, duplicateFirst);\n\n        for (int regIdx = 0; regIdx < sz; regIdx++) {\n          expander.expandRegister(regIdx);\n        }\n\n        return expander.getResult();\n    }\n\n    private static class Expander {\n      private BitSet compatRegs;\n      private RegisterSpecList regSpecList;\n      private int base;\n      private RegisterSpecList result;\n      private boolean duplicateFirst;\n\n      private Expander(RegisterSpecList regSpecList, BitSet compatRegs, int base,\n          boolean duplicateFirst) {\n        this.regSpecList = regSpecList;\n        this.compatRegs = compatRegs;\n        this.base = base;\n        this.result = new RegisterSpecList(regSpecList.size());\n        this.duplicateFirst = duplicateFirst;\n      }\n\n      private void expandRegister(int regIdx) {\n        expandRegister(regIdx, (RegisterSpec) regSpecList.get0(regIdx));\n      }\n\n      private void expandRegister(int regIdx, RegisterSpec registerToExpand) {\n        boolean replace = (compatRegs == null) ? true : !compatRegs.get(regIdx);\n        RegisterSpec expandedReg;\n\n        if (replace) {\n          expandedReg = registerToExpand.withReg(base);\n          if (!duplicateFirst) {\n            base += expandedReg.getCategory();\n          }\n          duplicateFirst = false;\n        } else {\n          expandedReg = registerToExpand;\n        }\n\n        result.set0(regIdx, expandedReg);\n      }\n\n      private RegisterSpecList getResult() {\n        if (regSpecList.isImmutable()) {\n          result.setImmutable();\n        }\n\n        return result;\n      }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/RegisterSpecSet.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.util.MutabilityControl;\n\n/**\n * Set of {@link RegisterSpec} instances, where a given register number\n * may appear only once in the set.\n */\npublic final class RegisterSpecSet\n        extends MutabilityControl {\n    /** {@code non-null;} no-element instance */\n    public static final RegisterSpecSet EMPTY = new RegisterSpecSet(0);\n\n    /**\n     * {@code non-null;} array of register specs, where each element is\n     * {@code null} or is an instance whose {@code reg}\n     * matches the array index\n     */\n    private final RegisterSpec[] specs;\n\n    /** {@code >= -1;} size of the set or {@code -1} if not yet calculated */\n    private int size;\n\n    /**\n     * Constructs an instance. The instance is initially empty.\n     *\n     * @param maxSize {@code >= 0;} the maximum register number (exclusive) that\n     * may be represented in this instance\n     */\n    public RegisterSpecSet(int maxSize) {\n        super(maxSize != 0);\n\n        this.specs = new RegisterSpec[maxSize];\n        this.size = 0;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (!(other instanceof RegisterSpecSet)) {\n            return false;\n        }\n\n        RegisterSpecSet otherSet = (RegisterSpecSet) other;\n        RegisterSpec[] otherSpecs = otherSet.specs;\n        int len = specs.length;\n\n        if ((len != otherSpecs.length) || (size() != otherSet.size())) {\n            return false;\n        }\n\n        for (int i = 0; i < len; i++) {\n            RegisterSpec s1 = specs[i];\n            RegisterSpec s2 = otherSpecs[i];\n\n            if (s1 == s2) {\n                continue;\n            }\n\n            if ((s1 == null) || !s1.equals(s2)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        int len = specs.length;\n        int hash = 0;\n\n        for (int i = 0; i < len; i++) {\n            RegisterSpec spec = specs[i];\n            int oneHash = (spec == null) ? 0 : spec.hashCode();\n            hash = (hash * 31) + oneHash;\n        }\n\n        return hash;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        int len = specs.length;\n        StringBuffer sb = new StringBuffer(len * 25);\n\n        sb.append('{');\n\n        boolean any = false;\n        for (int i = 0; i < len; i++) {\n            RegisterSpec spec = specs[i];\n            if (spec != null) {\n                if (any) {\n                    sb.append(\", \");\n                } else {\n                    any = true;\n                }\n                sb.append(spec);\n            }\n        }\n\n        sb.append('}');\n        return sb.toString();\n    }\n\n    /**\n     * Gets the maximum number of registers that may be in this instance, which\n     * is also the maximum-plus-one of register numbers that may be\n     * represented.\n     *\n     * @return {@code >= 0;} the maximum size\n     */\n    public int getMaxSize() {\n        return specs.length;\n    }\n\n    /**\n     * Gets the current size of this instance.\n     *\n     * @return {@code >= 0;} the size\n     */\n    public int size() {\n        int result = size;\n\n        if (result < 0) {\n            int len = specs.length;\n\n            result = 0;\n            for (int i = 0; i < len; i++) {\n                if (specs[i] != null) {\n                    result++;\n                }\n            }\n\n            size = result;\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets the element with the given register number, if any.\n     *\n     * @param reg {@code >= 0;} the desired register number\n     * @return {@code null-ok;} the element with the given register number or\n     * {@code null} if there is none\n     */\n    public RegisterSpec get(int reg) {\n        try {\n            return specs[reg];\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"bogus reg\");\n        }\n    }\n\n    /**\n     * Gets the element with the same register number as the given\n     * spec, if any. This is just a convenient shorthand for\n     * {@code get(spec.getReg())}.\n     *\n     * @param spec {@code non-null;} spec with the desired register number\n     * @return {@code null-ok;} the element with the matching register number or\n     * {@code null} if there is none\n     */\n    public RegisterSpec get(RegisterSpec spec) {\n        return get(spec.getReg());\n    }\n\n    /**\n     * Returns the spec in this set that's currently associated with a\n     * given local (type, name, and signature), or {@code null} if there is\n     * none. This ignores the register number of the given spec but\n     * matches on everything else.\n     *\n     * @param spec {@code non-null;} local to look for\n     * @return {@code null-ok;} first register found that matches, if any\n     */\n    public RegisterSpec findMatchingLocal(RegisterSpec spec) {\n        int length = specs.length;\n\n        for (int reg = 0; reg < length; reg++) {\n            RegisterSpec s = specs[reg];\n\n            if (s == null) {\n                continue;\n            }\n\n            if (spec.matchesVariable(s)) {\n                return s;\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Returns the spec in this set that's currently associated with a given\n     * local (name and signature), or {@code null} if there is none.\n     *\n     * @param local {@code non-null;} local item to search for\n     * @return {@code null-ok;} first register found with matching name and signature\n     */\n    public RegisterSpec localItemToSpec(LocalItem local) {\n        int length = specs.length;\n\n        for (int reg = 0; reg < length; reg++) {\n            RegisterSpec spec = specs[reg];\n\n            if ((spec != null) && local.equals(spec.getLocalItem())) {\n                return spec;\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Removes a spec from the set. Only the register number\n     * of the parameter is significant.\n     *\n     * @param toRemove {@code non-null;} register to remove.\n     */\n    public void remove(RegisterSpec toRemove) {\n        try {\n            specs[toRemove.getReg()] = null;\n            size = -1;\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"bogus reg\");\n        }\n    }\n\n    /**\n     * Puts the given spec into the set. If there is already an element in\n     * the set with the same register number, it is replaced. Additionally,\n     * if the previous element is for a category-2 register, then that\n     * previous element is nullified. Finally, if the given spec is for\n     * a category-2 register, then the immediately subsequent element\n     * is nullified.\n     *\n     * @param spec {@code non-null;} the register spec to put in the instance\n     */\n    public void put(RegisterSpec spec) {\n        throwIfImmutable();\n\n        if (spec == null) {\n            throw new NullPointerException(\"spec == null\");\n        }\n\n        size = -1;\n\n        try {\n            int reg = spec.getReg();\n            specs[reg] = spec;\n\n            if (reg > 0) {\n                int prevReg = reg - 1;\n                RegisterSpec prevSpec = specs[prevReg];\n                if ((prevSpec != null) && (prevSpec.getCategory() == 2)) {\n                    specs[prevReg] = null;\n                }\n            }\n\n            if (spec.getCategory() == 2) {\n                specs[reg + 1] = null;\n            }\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"spec.getReg() out of range\");\n        }\n    }\n\n    /**\n     * Put the entire contents of the given set into this one.\n     *\n     * @param set {@code non-null;} the set to put into this instance\n     */\n    public void putAll(RegisterSpecSet set) {\n        int max = set.getMaxSize();\n\n        for (int i = 0; i < max; i++) {\n            RegisterSpec spec = set.get(i);\n            if (spec != null) {\n                put(spec);\n            }\n        }\n    }\n\n    /**\n     * Intersects this instance with the given one, modifying this\n     * instance. The intersection consists of the pairwise\n     * {@link RegisterSpec#intersect} of corresponding elements from\n     * this instance and the given one where both are non-null.\n     *\n     * @param other {@code non-null;} set to intersect with\n     * @param localPrimary whether local variables are primary to\n     * the intersection; if {@code true}, then the only non-null\n     * result elements occur when registers being intersected have\n     * equal names (or both have {@code null} names)\n     */\n    public void intersect(RegisterSpecSet other, boolean localPrimary) {\n        throwIfImmutable();\n\n        RegisterSpec[] otherSpecs = other.specs;\n        int thisLen = specs.length;\n        int len = Math.min(thisLen, otherSpecs.length);\n\n        size = -1;\n\n        for (int i = 0; i < len; i++) {\n            RegisterSpec spec = specs[i];\n\n            if (spec == null) {\n                continue;\n            }\n\n            RegisterSpec intersection =\n                spec.intersect(otherSpecs[i], localPrimary);\n            if (intersection != spec) {\n                specs[i] = intersection;\n            }\n        }\n\n        for (int i = len; i < thisLen; i++) {\n            specs[i] = null;\n        }\n    }\n\n    /**\n     * Returns an instance that is identical to this one, except that\n     * all register numbers are offset by the given amount. Mutability\n     * of the result is inherited from the original.\n     *\n     * @param delta the amount to offset the register numbers by\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public RegisterSpecSet withOffset(int delta) {\n        int len = specs.length;\n        RegisterSpecSet result = new RegisterSpecSet(len + delta);\n\n        for (int i = 0; i < len; i++) {\n            RegisterSpec spec = specs[i];\n            if (spec != null) {\n                result.put(spec.withOffset(delta));\n            }\n        }\n\n        result.size = size;\n\n        if (isImmutable()) {\n            result.setImmutable();\n        }\n\n        return result;\n    }\n\n    /**\n     * Makes and return a mutable copy of this instance.\n     *\n     * @return {@code non-null;} the mutable copy\n     */\n    public RegisterSpecSet mutableCopy() {\n        int len = specs.length;\n        RegisterSpecSet copy = new RegisterSpecSet(len);\n\n        for (int i = 0; i < len; i++) {\n            RegisterSpec spec = specs[i];\n            if (spec != null) {\n                copy.put(spec);\n            }\n        }\n\n        copy.size = size;\n\n        return copy;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/Rop.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Class that describes all the immutable parts of register-based operations.\n */\npublic final class Rop {\n    /** minimum {@code BRANCH_*} value */\n    public static final int BRANCH_MIN = 1;\n\n    /** indicates a non-branching op */\n    public static final int BRANCH_NONE = 1;\n\n    /** indicates a function/method return */\n    public static final int BRANCH_RETURN = 2;\n\n    /** indicates an unconditional goto */\n    public static final int BRANCH_GOTO = 3;\n\n    /** indicates a two-way branch */\n    public static final int BRANCH_IF = 4;\n\n    /** indicates a switch-style branch */\n    public static final int BRANCH_SWITCH = 5;\n\n    /** indicates a throw-style branch (both always-throws and may-throw) */\n    public static final int BRANCH_THROW = 6;\n\n    /** maximum {@code BRANCH_*} value */\n    public static final int BRANCH_MAX = 6;\n\n    /** the opcode; one of the constants in {@link RegOps} */\n    private final int opcode;\n\n    /**\n     * {@code non-null;} result type of this operation; {@link Type#VOID} for\n     * no-result operations\n     */\n    private final Type result;\n\n    /** {@code non-null;} types of all the sources of this operation */\n    private final TypeList sources;\n\n    /** {@code non-null;} list of possible types thrown by this operation */\n    private final TypeList exceptions;\n\n    /**\n     * the branchingness of this op; one of the {@code BRANCH_*}\n     * constants in this class\n     */\n    private final int branchingness;\n\n    /** whether this is a function/method call op or similar */\n    private final boolean isCallLike;\n\n    /** {@code null-ok;} nickname, if specified (used for debugging) */\n    private final String nickname;\n\n    /**\n     * Constructs an instance. This method is private. Use one of the\n     * public constructors.\n     *\n     * @param opcode the opcode; one of the constants in {@link RegOps}\n     * @param result {@code non-null;} result type of this operation; {@link\n     * Type#VOID} for no-result operations\n     * @param sources {@code non-null;} types of all the sources of this operation\n     * @param exceptions {@code non-null;} list of possible types thrown by this\n     * operation\n     * @param branchingness the branchingness of this op; one of the\n     * {@code BRANCH_*} constants\n     * @param isCallLike whether the op is a function/method call or similar\n     * @param nickname {@code null-ok;} optional nickname (used for debugging)\n     */\n    public Rop(int opcode, Type result, TypeList sources,\n               TypeList exceptions, int branchingness, boolean isCallLike,\n               String nickname) {\n        if (result == null) {\n            throw new NullPointerException(\"result == null\");\n        }\n\n        if (sources == null) {\n            throw new NullPointerException(\"sources == null\");\n        }\n\n        if (exceptions == null) {\n            throw new NullPointerException(\"exceptions == null\");\n        }\n\n        if ((branchingness < BRANCH_MIN) || (branchingness > BRANCH_MAX)) {\n            throw new IllegalArgumentException(\"bogus branchingness\");\n        }\n\n        if ((exceptions.size() != 0) && (branchingness != BRANCH_THROW)) {\n            throw new IllegalArgumentException(\"exceptions / branchingness \" +\n                                               \"mismatch\");\n        }\n\n        this.opcode = opcode;\n        this.result = result;\n        this.sources = sources;\n        this.exceptions = exceptions;\n        this.branchingness = branchingness;\n        this.isCallLike = isCallLike;\n        this.nickname = nickname;\n    }\n\n    /**\n     * Constructs an instance. The constructed instance is never a\n     * call-like op (see {@link #isCallLike}).\n     *\n     * @param opcode the opcode; one of the constants in {@link RegOps}\n     * @param result {@code non-null;} result type of this operation; {@link\n     * Type#VOID} for no-result operations\n     * @param sources {@code non-null;} types of all the sources of this operation\n     * @param exceptions {@code non-null;} list of possible types thrown by this\n     * operation\n     * @param branchingness the branchingness of this op; one of the\n     * {@code BRANCH_*} constants\n     * @param nickname {@code null-ok;} optional nickname (used for debugging)\n     */\n    public Rop(int opcode, Type result, TypeList sources,\n               TypeList exceptions, int branchingness, String nickname) {\n        this(opcode, result, sources, exceptions, branchingness, false,\n             nickname);\n    }\n\n    /**\n     * Constructs a no-exception instance. The constructed instance is never a\n     * call-like op (see {@link #isCallLike}).\n     *\n     * @param opcode the opcode; one of the constants in {@link RegOps}\n     * @param result {@code non-null;} result type of this operation; {@link\n     * Type#VOID} for no-result operations\n     * @param sources {@code non-null;} types of all the sources of this operation\n     * @param branchingness the branchingness of this op; one of the\n     * {@code BRANCH_*} constants\n     * @param nickname {@code null-ok;} optional nickname (used for debugging)\n     */\n    public Rop(int opcode, Type result, TypeList sources, int branchingness,\n               String nickname) {\n        this(opcode, result, sources, StdTypeList.EMPTY, branchingness, false,\n             nickname);\n    }\n\n    /**\n     * Constructs a non-branching no-exception instance. The\n     * {@code branchingness} is always {@code BRANCH_NONE},\n     * and it is never a call-like op (see {@link #isCallLike}).\n     *\n     * @param opcode the opcode; one of the constants in {@link RegOps}\n     * @param result {@code non-null;} result type of this operation; {@link\n     * Type#VOID} for no-result operations\n     * @param sources {@code non-null;} types of all the sources of this operation\n     * @param nickname {@code null-ok;} optional nickname (used for debugging)\n     */\n    public Rop(int opcode, Type result, TypeList sources, String nickname) {\n        this(opcode, result, sources, StdTypeList.EMPTY, Rop.BRANCH_NONE,\n             false, nickname);\n    }\n\n    /**\n     * Constructs a non-empty exceptions instance. Its\n     * {@code branchingness} is always {@code BRANCH_THROW},\n     * but it is never a call-like op (see {@link #isCallLike}).\n     *\n     * @param opcode the opcode; one of the constants in {@link RegOps}\n     * @param result {@code non-null;} result type of this operation; {@link\n     * Type#VOID} for no-result operations\n     * @param sources {@code non-null;} types of all the sources of this operation\n     * @param exceptions {@code non-null;} list of possible types thrown by this\n     * operation\n     * @param nickname {@code null-ok;} optional nickname (used for debugging)\n     */\n    public Rop(int opcode, Type result, TypeList sources, TypeList exceptions,\n               String nickname) {\n        this(opcode, result, sources, exceptions, Rop.BRANCH_THROW, false,\n             nickname);\n    }\n\n    /**\n     * Constructs a non-nicknamed instance with non-empty exceptions, which\n     * is always a call-like op (see {@link #isCallLike}). Its\n     * {@code branchingness} is always {@code BRANCH_THROW}.\n     *\n     * @param opcode the opcode; one of the constants in {@link RegOps}\n     * @param sources {@code non-null;} types of all the sources of this operation\n     * @param exceptions {@code non-null;} list of possible types thrown by this\n     * operation\n     */\n    public Rop(int opcode, TypeList sources, TypeList exceptions) {\n        this(opcode, Type.VOID, sources, exceptions, Rop.BRANCH_THROW, true,\n             null);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (this == other) {\n            // Easy out.\n            return true;\n        }\n\n        if (!(other instanceof Rop)) {\n            return false;\n        }\n\n        Rop rop = (Rop) other;\n\n        return (opcode == rop.opcode) &&\n            (branchingness == rop.branchingness) &&\n            (result == rop.result) &&\n            sources.equals(rop.sources) &&\n            exceptions.equals(rop.exceptions);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        int h = (opcode * 31) + branchingness;\n        h = (h * 31) + result.hashCode();\n        h = (h * 31) + sources.hashCode();\n        h = (h * 31) + exceptions.hashCode();\n\n        return h;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        StringBuffer sb = new StringBuffer(40);\n\n        sb.append(\"Rop{\");\n\n        sb.append(RegOps.opName(opcode));\n\n        if (result != Type.VOID) {\n            sb.append(\" \");\n            sb.append(result);\n        } else {\n            sb.append(\" .\");\n        }\n\n        sb.append(\" <-\");\n\n        int sz = sources.size();\n        if (sz == 0) {\n            sb.append(\" .\");\n        } else {\n            for (int i = 0; i < sz; i++) {\n                sb.append(' ');\n                sb.append(sources.getType(i));\n            }\n        }\n\n        if (isCallLike) {\n            sb.append(\" call\");\n        }\n\n        sz = exceptions.size();\n        if (sz != 0) {\n            sb.append(\" throws\");\n            for (int i = 0; i < sz; i++) {\n                sb.append(' ');\n                Type one = exceptions.getType(i);\n                if (one == Type.THROWABLE) {\n                    sb.append(\"<any>\");\n                } else {\n                    sb.append(exceptions.getType(i));\n                }\n            }\n        } else {\n            switch (branchingness) {\n                case BRANCH_NONE:   sb.append(\" flows\"); break;\n                case BRANCH_RETURN: sb.append(\" returns\"); break;\n                case BRANCH_GOTO:   sb.append(\" gotos\"); break;\n                case BRANCH_IF:     sb.append(\" ifs\"); break;\n                case BRANCH_SWITCH: sb.append(\" switches\"); break;\n                default: sb.append(\" \" + Hex.u1(branchingness)); break;\n            }\n        }\n\n        sb.append('}');\n\n        return sb.toString();\n    }\n\n    /**\n     * Gets the opcode.\n     *\n     * @return the opcode\n     */\n    public int getOpcode() {\n        return opcode;\n    }\n\n    /**\n     * Gets the result type. A return value of {@link Type#VOID}\n     * means this operation returns nothing.\n     *\n     * @return {@code null-ok;} the result spec\n     */\n    public Type getResult() {\n        return result;\n    }\n\n    /**\n     * Gets the source types.\n     *\n     * @return {@code non-null;} the source types\n     */\n    public TypeList getSources() {\n        return sources;\n    }\n\n    /**\n     * Gets the list of exception types that might be thrown.\n     *\n     * @return {@code non-null;} the list of exception types\n     */\n    public TypeList getExceptions() {\n        return exceptions;\n    }\n\n    /**\n     * Gets the branchingness of this instance.\n     *\n     * @return the branchingness\n     */\n    public int getBranchingness() {\n        return branchingness;\n    }\n\n    /**\n     * Gets whether this opcode is a function/method call or similar.\n     *\n     * @return {@code true} iff this opcode is call-like\n     */\n    public boolean isCallLike() {\n        return isCallLike;\n    }\n\n\n    /**\n     * Gets whether this opcode is commutative (the order of its sources are\n     * unimportant) or not. All commutative Rops have exactly two sources and\n     * have no branchiness.\n     *\n     * @return true if rop is commutative\n     */\n    public boolean isCommutative() {\n        switch (opcode) {\n            case RegOps.AND:\n            case RegOps.OR:\n            case RegOps.XOR:\n            case RegOps.ADD:\n            case RegOps.MUL:\n                return true;\n            default:\n                return false;\n        }\n    }\n\n    /**\n     * Gets the nickname. If this instance has no nickname, this returns\n     * the result of calling {@link #toString}.\n     *\n     * @return {@code non-null;} the nickname\n     */\n    public String getNickname() {\n        if (nickname != null) {\n            return nickname;\n        }\n\n        return toString();\n    }\n\n    /**\n     * Gets whether this operation can possibly throw an exception. This\n     * is just a convenient wrapper for\n     * {@code getExceptions().size() != 0}.\n     *\n     * @return {@code true} iff this operation can possibly throw\n     */\n    public final boolean canThrow() {\n        return (exceptions.size() != 0);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/RopMethod.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.IntList;\n\n/**\n * All of the parts that make up a method at the rop layer.\n */\npublic final class RopMethod {\n    /** {@code non-null;} basic block list of the method */\n    private final BasicBlockList blocks;\n\n    /** {@code >= 0;} label for the block which starts the method */\n    private final int firstLabel;\n\n    /**\n     * {@code null-ok;} array of predecessors for each block, indexed by block\n     * label\n     */\n    private IntList[] predecessors;\n\n    /**\n     * {@code null-ok;} the predecessors for the implicit \"exit\" block, that is\n     * the labels for the blocks that return, if calculated\n     */\n    private IntList exitPredecessors;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param blocks {@code non-null;} basic block list of the method\n     * @param firstLabel {@code >= 0;} the label of the first block to execute\n     */\n    public RopMethod(BasicBlockList blocks, int firstLabel) {\n        if (blocks == null) {\n            throw new NullPointerException(\"blocks == null\");\n        }\n\n        if (firstLabel < 0) {\n            throw new IllegalArgumentException(\"firstLabel < 0\");\n        }\n\n        this.blocks = blocks;\n        this.firstLabel = firstLabel;\n\n        this.predecessors = null;\n        this.exitPredecessors = null;\n    }\n\n    /**\n     * Gets the basic block list for this method.\n     *\n     * @return {@code non-null;} the list\n     */\n    public BasicBlockList getBlocks() {\n        return blocks;\n    }\n\n    /**\n     * Gets the label for the first block in the method that this list\n     * represents.\n     *\n     * @return {@code >= 0;} the first-block label\n     */\n    public int getFirstLabel() {\n        return firstLabel;\n    }\n\n    /**\n     * Gets the predecessors associated with the given block. This throws\n     * an exception if there is no block with the given label.\n     *\n     * @param label {@code >= 0;} the label of the block in question\n     * @return {@code non-null;} the predecessors of that block\n     */\n    public IntList labelToPredecessors(int label) {\n        if (exitPredecessors == null) {\n            calcPredecessors();\n        }\n\n        IntList result = predecessors[label];\n\n        if (result == null) {\n            throw new RuntimeException(\"no such block: \" + Hex.u2(label));\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets the exit predecessors for this instance.\n     *\n     * @return {@code non-null;} the exit predecessors\n     */\n    public IntList getExitPredecessors() {\n        if (exitPredecessors == null) {\n            calcPredecessors();\n        }\n\n        return exitPredecessors;\n    }\n\n\n    /**\n     * Returns an instance that is identical to this one, except that\n     * the registers in each instruction are offset by the given\n     * amount.\n     *\n     * @param delta the amount to offset register numbers by\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public RopMethod withRegisterOffset(int delta) {\n        RopMethod result = new RopMethod(blocks.withRegisterOffset(delta),\n                                         firstLabel);\n\n        if (exitPredecessors != null) {\n            /*\n             * The predecessors have been calculated. It's safe to\n             * inject these into the new instance, since the\n             * transformation being applied doesn't affect the\n             * predecessors.\n             */\n            result.exitPredecessors = exitPredecessors;\n            result.predecessors = predecessors;\n        }\n\n        return result;\n    }\n\n    /**\n     * Calculates the predecessor sets for each block as well as for the\n     * exit.\n     */\n    private void calcPredecessors() {\n        int maxLabel = blocks.getMaxLabel();\n        IntList[] predecessors = new IntList[maxLabel];\n        IntList exitPredecessors = new IntList(10);\n        int sz = blocks.size();\n\n        /*\n         * For each block, find its successors, and add the block's label to\n         * the successor's predecessors.\n         */\n        for (int i = 0; i < sz; i++) {\n            BasicBlock one = blocks.get(i);\n            int label = one.getLabel();\n            IntList successors = one.getSuccessors();\n            int ssz = successors.size();\n            if (ssz == 0) {\n                // This block exits.\n                exitPredecessors.add(label);\n            } else {\n                for (int j = 0; j < ssz; j++) {\n                    int succLabel = successors.get(j);\n                    IntList succPreds = predecessors[succLabel];\n                    if (succPreds == null) {\n                        succPreds = new IntList(10);\n                        predecessors[succLabel] = succPreds;\n                    }\n                    succPreds.add(label);\n                }\n            }\n        }\n\n        // Sort and immutablize all the predecessor lists.\n        for (int i = 0; i < maxLabel; i++) {\n            IntList preds = predecessors[i];\n            if (preds != null) {\n                preds.sort();\n                preds.setImmutable();\n            }\n        }\n\n        exitPredecessors.sort();\n        exitPredecessors.setImmutable();\n\n        /*\n         * The start label might not ever have had any predecessors\n         * added to it (probably doesn't, because of how Java gets\n         * translated into rop form). So, check for this and rectify\n         * the situation if required.\n         */\n        if (predecessors[firstLabel] == null) {\n            predecessors[firstLabel] = IntList.EMPTY;\n        }\n\n        this.predecessors = predecessors;\n        this.exitPredecessors = exitPredecessors;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/Rops.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstBaseMethodRef;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Prototype;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport com.taobao.android.dx.rop.type.TypeList;\n\n/**\n * Standard instances of {@link Rop}.\n */\npublic final class Rops {\n    /** {@code nop()} */\n    public static final Rop NOP =\n        new Rop(RegOps.NOP, Type.VOID, StdTypeList.EMPTY, \"nop\");\n\n    /** {@code r,x: int :: r = x;} */\n    public static final Rop MOVE_INT =\n        new Rop(RegOps.MOVE, Type.INT, StdTypeList.INT, \"move-int\");\n\n    /** {@code r,x: long :: r = x;} */\n    public static final Rop MOVE_LONG =\n        new Rop(RegOps.MOVE, Type.LONG, StdTypeList.LONG, \"move-long\");\n\n    /** {@code r,x: float :: r = x;} */\n    public static final Rop MOVE_FLOAT =\n        new Rop(RegOps.MOVE, Type.FLOAT, StdTypeList.FLOAT, \"move-float\");\n\n    /** {@code r,x: double :: r = x;} */\n    public static final Rop MOVE_DOUBLE =\n        new Rop(RegOps.MOVE, Type.DOUBLE, StdTypeList.DOUBLE, \"move-double\");\n\n    /** {@code r,x: Object :: r = x;} */\n    public static final Rop MOVE_OBJECT =\n        new Rop(RegOps.MOVE, Type.OBJECT, StdTypeList.OBJECT, \"move-object\");\n\n    /**\n     * {@code r,x: ReturnAddress :: r = x;}\n     *\n     * Note that this rop-form instruction has no dex-form equivilent and\n     * must be removed before the dex conversion.\n     */\n    public static final Rop MOVE_RETURN_ADDRESS =\n        new Rop(RegOps.MOVE, Type.RETURN_ADDRESS,\n                StdTypeList.RETURN_ADDRESS, \"move-return-address\");\n\n    /** {@code r,param(x): int :: r = param(x);} */\n    public static final Rop MOVE_PARAM_INT =\n        new Rop(RegOps.MOVE_PARAM, Type.INT, StdTypeList.EMPTY,\n                \"move-param-int\");\n\n    /** {@code r,param(x): long :: r = param(x);} */\n    public static final Rop MOVE_PARAM_LONG =\n        new Rop(RegOps.MOVE_PARAM, Type.LONG, StdTypeList.EMPTY,\n                \"move-param-long\");\n\n    /** {@code r,param(x): float :: r = param(x);} */\n    public static final Rop MOVE_PARAM_FLOAT =\n        new Rop(RegOps.MOVE_PARAM, Type.FLOAT, StdTypeList.EMPTY,\n                \"move-param-float\");\n\n    /** {@code r,param(x): double :: r = param(x);} */\n    public static final Rop MOVE_PARAM_DOUBLE =\n        new Rop(RegOps.MOVE_PARAM, Type.DOUBLE, StdTypeList.EMPTY,\n                \"move-param-double\");\n\n    /** {@code r,param(x): Object :: r = param(x);} */\n    public static final Rop MOVE_PARAM_OBJECT =\n        new Rop(RegOps.MOVE_PARAM, Type.OBJECT, StdTypeList.EMPTY,\n                \"move-param-object\");\n\n    /** {@code r, literal: int :: r = literal;} */\n    public static final Rop CONST_INT =\n        new Rop(RegOps.CONST, Type.INT, StdTypeList.EMPTY, \"const-int\");\n\n    /** {@code r, literal: long :: r = literal;} */\n    public static final Rop CONST_LONG =\n        new Rop(RegOps.CONST, Type.LONG, StdTypeList.EMPTY, \"const-long\");\n\n    /** {@code r, literal: float :: r = literal;} */\n    public static final Rop CONST_FLOAT =\n        new Rop(RegOps.CONST, Type.FLOAT, StdTypeList.EMPTY, \"const-float\");\n\n    /** {@code r, literal: double :: r = literal;} */\n    public static final Rop CONST_DOUBLE =\n        new Rop(RegOps.CONST, Type.DOUBLE, StdTypeList.EMPTY, \"const-double\");\n\n    /** {@code r, literal: Object :: r = literal;} */\n    public static final Rop CONST_OBJECT =\n        new Rop(RegOps.CONST, Type.OBJECT, StdTypeList.EMPTY,\n                Exceptions.LIST_Error, \"const-object\");\n\n    /** {@code r, literal: Object :: r = literal;} */\n    public static final Rop CONST_OBJECT_NOTHROW =\n        new Rop(RegOps.CONST, Type.OBJECT, StdTypeList.EMPTY,\n                \"const-object-nothrow\");\n\n    /** {@code goto label} */\n    public static final Rop GOTO =\n        new Rop(RegOps.GOTO, Type.VOID, StdTypeList.EMPTY, Rop.BRANCH_GOTO,\n                \"goto\");\n\n    /** {@code x: int :: if (x == 0) goto label} */\n    public static final Rop IF_EQZ_INT =\n        new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,\n                \"if-eqz-int\");\n\n    /** {@code x: int :: if (x != 0) goto label} */\n    public static final Rop IF_NEZ_INT =\n        new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,\n                \"if-nez-int\");\n\n    /** {@code x: int :: if (x < 0) goto label} */\n    public static final Rop IF_LTZ_INT =\n        new Rop(RegOps.IF_LT, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,\n                \"if-ltz-int\");\n\n    /** {@code x: int :: if (x >= 0) goto label} */\n    public static final Rop IF_GEZ_INT =\n        new Rop(RegOps.IF_GE, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,\n                \"if-gez-int\");\n\n    /** {@code x: int :: if (x <= 0) goto label} */\n    public static final Rop IF_LEZ_INT =\n        new Rop(RegOps.IF_LE, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,\n                \"if-lez-int\");\n\n    /** {@code x: int :: if (x > 0) goto label} */\n    public static final Rop IF_GTZ_INT =\n        new Rop(RegOps.IF_GT, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,\n                \"if-gtz-int\");\n\n    /** {@code x: Object :: if (x == null) goto label} */\n    public static final Rop IF_EQZ_OBJECT =\n        new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.OBJECT, Rop.BRANCH_IF,\n                \"if-eqz-object\");\n\n    /** {@code x: Object :: if (x != null) goto label} */\n    public static final Rop IF_NEZ_OBJECT =\n        new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.OBJECT, Rop.BRANCH_IF,\n                \"if-nez-object\");\n\n    /** {@code x,y: int :: if (x == y) goto label} */\n    public static final Rop IF_EQ_INT =\n        new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,\n                \"if-eq-int\");\n\n    /** {@code x,y: int :: if (x != y) goto label} */\n    public static final Rop IF_NE_INT =\n        new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,\n                \"if-ne-int\");\n\n    /** {@code x,y: int :: if (x < y) goto label} */\n    public static final Rop IF_LT_INT =\n        new Rop(RegOps.IF_LT, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,\n                \"if-lt-int\");\n\n    /** {@code x,y: int :: if (x >= y) goto label} */\n    public static final Rop IF_GE_INT =\n        new Rop(RegOps.IF_GE, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,\n                \"if-ge-int\");\n\n    /** {@code x,y: int :: if (x <= y) goto label} */\n    public static final Rop IF_LE_INT =\n        new Rop(RegOps.IF_LE, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,\n                \"if-le-int\");\n\n    /** {@code x,y: int :: if (x > y) goto label} */\n    public static final Rop IF_GT_INT =\n        new Rop(RegOps.IF_GT, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,\n                \"if-gt-int\");\n\n    /** {@code x,y: Object :: if (x == y) goto label} */\n    public static final Rop IF_EQ_OBJECT =\n        new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.OBJECT_OBJECT,\n                Rop.BRANCH_IF, \"if-eq-object\");\n\n    /** {@code x,y: Object :: if (x != y) goto label} */\n    public static final Rop IF_NE_OBJECT =\n        new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.OBJECT_OBJECT,\n                Rop.BRANCH_IF, \"if-ne-object\");\n\n    /** {@code x: int :: goto switchtable[x]} */\n    public static final Rop SWITCH =\n        new Rop(RegOps.SWITCH, Type.VOID, StdTypeList.INT, Rop.BRANCH_SWITCH,\n                \"switch\");\n\n    /** {@code r,x,y: int :: r = x + y;} */\n    public static final Rop ADD_INT =\n        new Rop(RegOps.ADD, Type.INT, StdTypeList.INT_INT, \"add-int\");\n\n    /** {@code r,x,y: long :: r = x + y;} */\n    public static final Rop ADD_LONG =\n        new Rop(RegOps.ADD, Type.LONG, StdTypeList.LONG_LONG, \"add-long\");\n\n    /** {@code r,x,y: float :: r = x + y;} */\n    public static final Rop ADD_FLOAT =\n        new Rop(RegOps.ADD, Type.FLOAT, StdTypeList.FLOAT_FLOAT, \"add-float\");\n\n    /** {@code r,x,y: double :: r = x + y;} */\n    public static final Rop ADD_DOUBLE =\n        new Rop(RegOps.ADD, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,\n                Rop.BRANCH_NONE, \"add-double\");\n\n    /** {@code r,x,y: int :: r = x - y;} */\n    public static final Rop SUB_INT =\n        new Rop(RegOps.SUB, Type.INT, StdTypeList.INT_INT, \"sub-int\");\n\n    /** {@code r,x,y: long :: r = x - y;} */\n    public static final Rop SUB_LONG =\n        new Rop(RegOps.SUB, Type.LONG, StdTypeList.LONG_LONG, \"sub-long\");\n\n    /** {@code r,x,y: float :: r = x - y;} */\n    public static final Rop SUB_FLOAT =\n        new Rop(RegOps.SUB, Type.FLOAT, StdTypeList.FLOAT_FLOAT, \"sub-float\");\n\n    /** {@code r,x,y: double :: r = x - y;} */\n    public static final Rop SUB_DOUBLE =\n        new Rop(RegOps.SUB, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,\n                Rop.BRANCH_NONE, \"sub-double\");\n\n    /** {@code r,x,y: int :: r = x * y;} */\n    public static final Rop MUL_INT =\n        new Rop(RegOps.MUL, Type.INT, StdTypeList.INT_INT, \"mul-int\");\n\n    /** {@code r,x,y: long :: r = x * y;} */\n    public static final Rop MUL_LONG =\n        new Rop(RegOps.MUL, Type.LONG, StdTypeList.LONG_LONG, \"mul-long\");\n\n    /** {@code r,x,y: float :: r = x * y;} */\n    public static final Rop MUL_FLOAT =\n        new Rop(RegOps.MUL, Type.FLOAT, StdTypeList.FLOAT_FLOAT, \"mul-float\");\n\n    /** {@code r,x,y: double :: r = x * y;} */\n    public static final Rop MUL_DOUBLE =\n        new Rop(RegOps.MUL, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,\n                Rop.BRANCH_NONE, \"mul-double\");\n\n    /** {@code r,x,y: int :: r = x / y;} */\n    public static final Rop DIV_INT =\n        new Rop(RegOps.DIV, Type.INT, StdTypeList.INT_INT,\n                Exceptions.LIST_Error_ArithmeticException, \"div-int\");\n\n    /** {@code r,x,y: long :: r = x / y;} */\n    public static final Rop DIV_LONG =\n        new Rop(RegOps.DIV, Type.LONG, StdTypeList.LONG_LONG,\n                Exceptions.LIST_Error_ArithmeticException, \"div-long\");\n\n    /** {@code r,x,y: float :: r = x / y;} */\n    public static final Rop DIV_FLOAT =\n        new Rop(RegOps.DIV, Type.FLOAT, StdTypeList.FLOAT_FLOAT, \"div-float\");\n\n    /** {@code r,x,y: double :: r = x / y;} */\n    public static final Rop DIV_DOUBLE =\n        new Rop(RegOps.DIV, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,\n                \"div-double\");\n\n    /** {@code r,x,y: int :: r = x % y;} */\n    public static final Rop REM_INT =\n        new Rop(RegOps.REM, Type.INT, StdTypeList.INT_INT,\n                Exceptions.LIST_Error_ArithmeticException, \"rem-int\");\n\n    /** {@code r,x,y: long :: r = x % y;} */\n    public static final Rop REM_LONG =\n        new Rop(RegOps.REM, Type.LONG, StdTypeList.LONG_LONG,\n                Exceptions.LIST_Error_ArithmeticException, \"rem-long\");\n\n    /** {@code r,x,y: float :: r = x % y;} */\n    public static final Rop REM_FLOAT =\n        new Rop(RegOps.REM, Type.FLOAT, StdTypeList.FLOAT_FLOAT, \"rem-float\");\n\n    /** {@code r,x,y: double :: r = x % y;} */\n    public static final Rop REM_DOUBLE =\n        new Rop(RegOps.REM, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,\n                \"rem-double\");\n\n    /** {@code r,x: int :: r = -x;} */\n    public static final Rop NEG_INT =\n        new Rop(RegOps.NEG, Type.INT, StdTypeList.INT, \"neg-int\");\n\n    /** {@code r,x: long :: r = -x;} */\n    public static final Rop NEG_LONG =\n        new Rop(RegOps.NEG, Type.LONG, StdTypeList.LONG, \"neg-long\");\n\n    /** {@code r,x: float :: r = -x;} */\n    public static final Rop NEG_FLOAT =\n        new Rop(RegOps.NEG, Type.FLOAT, StdTypeList.FLOAT, \"neg-float\");\n\n    /** {@code r,x: double :: r = -x;} */\n    public static final Rop NEG_DOUBLE =\n        new Rop(RegOps.NEG, Type.DOUBLE, StdTypeList.DOUBLE, \"neg-double\");\n\n    /** {@code r,x,y: int :: r = x & y;} */\n    public static final Rop AND_INT =\n        new Rop(RegOps.AND, Type.INT, StdTypeList.INT_INT, \"and-int\");\n\n    /** {@code r,x,y: long :: r = x & y;} */\n    public static final Rop AND_LONG =\n        new Rop(RegOps.AND, Type.LONG, StdTypeList.LONG_LONG, \"and-long\");\n\n    /** {@code r,x,y: int :: r = x | y;} */\n    public static final Rop OR_INT =\n        new Rop(RegOps.OR, Type.INT, StdTypeList.INT_INT, \"or-int\");\n\n    /** {@code r,x,y: long :: r = x | y;} */\n    public static final Rop OR_LONG =\n        new Rop(RegOps.OR, Type.LONG, StdTypeList.LONG_LONG, \"or-long\");\n\n    /** {@code r,x,y: int :: r = x ^ y;} */\n    public static final Rop XOR_INT =\n        new Rop(RegOps.XOR, Type.INT, StdTypeList.INT_INT, \"xor-int\");\n\n    /** {@code r,x,y: long :: r = x ^ y;} */\n    public static final Rop XOR_LONG =\n        new Rop(RegOps.XOR, Type.LONG, StdTypeList.LONG_LONG, \"xor-long\");\n\n    /** {@code r,x,y: int :: r = x << y;} */\n    public static final Rop SHL_INT =\n        new Rop(RegOps.SHL, Type.INT, StdTypeList.INT_INT, \"shl-int\");\n\n    /** {@code r,x: long; y: int :: r = x << y;} */\n    public static final Rop SHL_LONG =\n        new Rop(RegOps.SHL, Type.LONG, StdTypeList.LONG_INT, \"shl-long\");\n\n    /** {@code r,x,y: int :: r = x >> y;} */\n    public static final Rop SHR_INT =\n        new Rop(RegOps.SHR, Type.INT, StdTypeList.INT_INT, \"shr-int\");\n\n    /** {@code r,x: long; y: int :: r = x >> y;} */\n    public static final Rop SHR_LONG =\n        new Rop(RegOps.SHR, Type.LONG, StdTypeList.LONG_INT, \"shr-long\");\n\n    /** {@code r,x,y: int :: r = x >>> y;} */\n    public static final Rop USHR_INT =\n        new Rop(RegOps.USHR, Type.INT, StdTypeList.INT_INT, \"ushr-int\");\n\n    /** {@code r,x: long; y: int :: r = x >>> y;} */\n    public static final Rop USHR_LONG =\n        new Rop(RegOps.USHR, Type.LONG, StdTypeList.LONG_INT, \"ushr-long\");\n\n    /** {@code r,x: int :: r = ~x;} */\n    public static final Rop NOT_INT =\n        new Rop(RegOps.NOT, Type.INT, StdTypeList.INT, \"not-int\");\n\n    /** {@code r,x: long :: r = ~x;} */\n    public static final Rop NOT_LONG =\n        new Rop(RegOps.NOT, Type.LONG, StdTypeList.LONG, \"not-long\");\n\n    /** {@code r,x,c: int :: r = x + c;} */\n    public static final Rop ADD_CONST_INT =\n        new Rop(RegOps.ADD, Type.INT, StdTypeList.INT, \"add-const-int\");\n\n    /** {@code r,x,c: long :: r = x + c;} */\n    public static final Rop ADD_CONST_LONG =\n        new Rop(RegOps.ADD, Type.LONG, StdTypeList.LONG, \"add-const-long\");\n\n    /** {@code r,x,c: float :: r = x + c;} */\n    public static final Rop ADD_CONST_FLOAT =\n        new Rop(RegOps.ADD, Type.FLOAT, StdTypeList.FLOAT, \"add-const-float\");\n\n    /** {@code r,x,c: double :: r = x + c;} */\n    public static final Rop ADD_CONST_DOUBLE =\n        new Rop(RegOps.ADD, Type.DOUBLE, StdTypeList.DOUBLE,\n                \"add-const-double\");\n\n    /** {@code r,x,c: int :: r = x - c;} */\n    public static final Rop SUB_CONST_INT =\n        new Rop(RegOps.SUB, Type.INT, StdTypeList.INT, \"sub-const-int\");\n\n    /** {@code r,x,c: long :: r = x - c;} */\n    public static final Rop SUB_CONST_LONG =\n        new Rop(RegOps.SUB, Type.LONG, StdTypeList.LONG, \"sub-const-long\");\n\n    /** {@code r,x,c: float :: r = x - c;} */\n    public static final Rop SUB_CONST_FLOAT =\n        new Rop(RegOps.SUB, Type.FLOAT, StdTypeList.FLOAT, \"sub-const-float\");\n\n    /** {@code r,x,c: double :: r = x - c;} */\n    public static final Rop SUB_CONST_DOUBLE =\n        new Rop(RegOps.SUB, Type.DOUBLE, StdTypeList.DOUBLE,\n                \"sub-const-double\");\n\n    /** {@code r,x,c: int :: r = x * c;} */\n    public static final Rop MUL_CONST_INT =\n        new Rop(RegOps.MUL, Type.INT, StdTypeList.INT, \"mul-const-int\");\n\n    /** {@code r,x,c: long :: r = x * c;} */\n    public static final Rop MUL_CONST_LONG =\n        new Rop(RegOps.MUL, Type.LONG, StdTypeList.LONG, \"mul-const-long\");\n\n    /** {@code r,x,c: float :: r = x * c;} */\n    public static final Rop MUL_CONST_FLOAT =\n        new Rop(RegOps.MUL, Type.FLOAT, StdTypeList.FLOAT, \"mul-const-float\");\n\n    /** {@code r,x,c: double :: r = x * c;} */\n    public static final Rop MUL_CONST_DOUBLE =\n        new Rop(RegOps.MUL, Type.DOUBLE, StdTypeList.DOUBLE,\n                \"mul-const-double\");\n\n    /** {@code r,x,c: int :: r = x / c;} */\n    public static final Rop DIV_CONST_INT =\n        new Rop(RegOps.DIV, Type.INT, StdTypeList.INT,\n                Exceptions.LIST_Error_ArithmeticException, \"div-const-int\");\n\n    /** {@code r,x,c: long :: r = x / c;} */\n    public static final Rop DIV_CONST_LONG =\n        new Rop(RegOps.DIV, Type.LONG, StdTypeList.LONG,\n                Exceptions.LIST_Error_ArithmeticException, \"div-const-long\");\n\n    /** {@code r,x,c: float :: r = x / c;} */\n    public static final Rop DIV_CONST_FLOAT =\n        new Rop(RegOps.DIV, Type.FLOAT, StdTypeList.FLOAT, \"div-const-float\");\n\n    /** {@code r,x,c: double :: r = x / c;} */\n    public static final Rop DIV_CONST_DOUBLE =\n        new Rop(RegOps.DIV, Type.DOUBLE, StdTypeList.DOUBLE,\n                \"div-const-double\");\n\n    /** {@code r,x,c: int :: r = x % c;} */\n    public static final Rop REM_CONST_INT =\n        new Rop(RegOps.REM, Type.INT, StdTypeList.INT,\n                Exceptions.LIST_Error_ArithmeticException, \"rem-const-int\");\n\n    /** {@code r,x,c: long :: r = x % c;} */\n    public static final Rop REM_CONST_LONG =\n        new Rop(RegOps.REM, Type.LONG, StdTypeList.LONG,\n                Exceptions.LIST_Error_ArithmeticException, \"rem-const-long\");\n\n    /** {@code r,x,c: float :: r = x % c;} */\n    public static final Rop REM_CONST_FLOAT =\n        new Rop(RegOps.REM, Type.FLOAT, StdTypeList.FLOAT, \"rem-const-float\");\n\n    /** {@code r,x,c: double :: r = x % c;} */\n    public static final Rop REM_CONST_DOUBLE =\n        new Rop(RegOps.REM, Type.DOUBLE, StdTypeList.DOUBLE,\n                \"rem-const-double\");\n\n    /** {@code r,x,c: int :: r = x & c;} */\n    public static final Rop AND_CONST_INT =\n        new Rop(RegOps.AND, Type.INT, StdTypeList.INT, \"and-const-int\");\n\n    /** {@code r,x,c: long :: r = x & c;} */\n    public static final Rop AND_CONST_LONG =\n        new Rop(RegOps.AND, Type.LONG, StdTypeList.LONG, \"and-const-long\");\n\n    /** {@code r,x,c: int :: r = x | c;} */\n    public static final Rop OR_CONST_INT =\n        new Rop(RegOps.OR, Type.INT, StdTypeList.INT, \"or-const-int\");\n\n    /** {@code r,x,c: long :: r = x | c;} */\n    public static final Rop OR_CONST_LONG =\n        new Rop(RegOps.OR, Type.LONG, StdTypeList.LONG, \"or-const-long\");\n\n    /** {@code r,x,c: int :: r = x ^ c;} */\n    public static final Rop XOR_CONST_INT =\n        new Rop(RegOps.XOR, Type.INT, StdTypeList.INT, \"xor-const-int\");\n\n    /** {@code r,x,c: long :: r = x ^ c;} */\n    public static final Rop XOR_CONST_LONG =\n        new Rop(RegOps.XOR, Type.LONG, StdTypeList.LONG, \"xor-const-long\");\n\n    /** {@code r,x,c: int :: r = x << c;} */\n    public static final Rop SHL_CONST_INT =\n        new Rop(RegOps.SHL, Type.INT, StdTypeList.INT, \"shl-const-int\");\n\n    /** {@code r,x: long; c: int :: r = x << c;} */\n    public static final Rop SHL_CONST_LONG =\n        new Rop(RegOps.SHL, Type.LONG, StdTypeList.INT, \"shl-const-long\");\n\n    /** {@code r,x,c: int :: r = x >> c;} */\n    public static final Rop SHR_CONST_INT =\n        new Rop(RegOps.SHR, Type.INT, StdTypeList.INT, \"shr-const-int\");\n\n    /** {@code r,x: long; c: int :: r = x >> c;} */\n    public static final Rop SHR_CONST_LONG =\n        new Rop(RegOps.SHR, Type.LONG, StdTypeList.INT, \"shr-const-long\");\n\n    /** {@code r,x,c: int :: r = x >>> c;} */\n    public static final Rop USHR_CONST_INT =\n        new Rop(RegOps.USHR, Type.INT, StdTypeList.INT, \"ushr-const-int\");\n\n    /** {@code r,x: long; c: int :: r = x >>> c;} */\n    public static final Rop USHR_CONST_LONG =\n        new Rop(RegOps.USHR, Type.LONG, StdTypeList.INT, \"ushr-const-long\");\n\n    /** {@code r: int; x,y: long :: r = cmp(x, y);} */\n    public static final Rop CMPL_LONG =\n        new Rop(RegOps.CMPL, Type.INT, StdTypeList.LONG_LONG, \"cmpl-long\");\n\n    /** {@code r: int; x,y: float :: r = cmpl(x, y);} */\n    public static final Rop CMPL_FLOAT =\n        new Rop(RegOps.CMPL, Type.INT, StdTypeList.FLOAT_FLOAT, \"cmpl-float\");\n\n    /** {@code r: int; x,y: double :: r = cmpl(x, y);} */\n    public static final Rop CMPL_DOUBLE =\n        new Rop(RegOps.CMPL, Type.INT, StdTypeList.DOUBLE_DOUBLE,\n                \"cmpl-double\");\n\n    /** {@code r: int; x,y: float :: r = cmpg(x, y);} */\n    public static final Rop CMPG_FLOAT =\n        new Rop(RegOps.CMPG, Type.INT, StdTypeList.FLOAT_FLOAT, \"cmpg-float\");\n\n    /** {@code r: int; x,y: double :: r = cmpg(x, y);} */\n    public static final Rop CMPG_DOUBLE =\n        new Rop(RegOps.CMPG, Type.INT, StdTypeList.DOUBLE_DOUBLE,\n                \"cmpg-double\");\n\n    /** {@code r: int; x: long :: r = (int) x} */\n    public static final Rop CONV_L2I =\n        new Rop(RegOps.CONV, Type.INT, StdTypeList.LONG, \"conv-l2i\");\n\n    /** {@code r: int; x: float :: r = (int) x} */\n    public static final Rop CONV_F2I =\n        new Rop(RegOps.CONV, Type.INT, StdTypeList.FLOAT, \"conv-f2i\");\n\n    /** {@code r: int; x: double :: r = (int) x} */\n    public static final Rop CONV_D2I =\n        new Rop(RegOps.CONV, Type.INT, StdTypeList.DOUBLE, \"conv-d2i\");\n\n    /** {@code r: long; x: int :: r = (long) x} */\n    public static final Rop CONV_I2L =\n        new Rop(RegOps.CONV, Type.LONG, StdTypeList.INT, \"conv-i2l\");\n\n    /** {@code r: long; x: float :: r = (long) x} */\n    public static final Rop CONV_F2L =\n        new Rop(RegOps.CONV, Type.LONG, StdTypeList.FLOAT, \"conv-f2l\");\n\n    /** {@code r: long; x: double :: r = (long) x} */\n    public static final Rop CONV_D2L =\n        new Rop(RegOps.CONV, Type.LONG, StdTypeList.DOUBLE, \"conv-d2l\");\n\n    /** {@code r: float; x: int :: r = (float) x} */\n    public static final Rop CONV_I2F =\n        new Rop(RegOps.CONV, Type.FLOAT, StdTypeList.INT, \"conv-i2f\");\n\n    /** {@code r: float; x: long :: r = (float) x} */\n    public static final Rop CONV_L2F =\n        new Rop(RegOps.CONV, Type.FLOAT, StdTypeList.LONG, \"conv-l2f\");\n\n    /** {@code r: float; x: double :: r = (float) x} */\n    public static final Rop CONV_D2F =\n        new Rop(RegOps.CONV, Type.FLOAT, StdTypeList.DOUBLE, \"conv-d2f\");\n\n    /** {@code r: double; x: int :: r = (double) x} */\n    public static final Rop CONV_I2D =\n        new Rop(RegOps.CONV, Type.DOUBLE, StdTypeList.INT, \"conv-i2d\");\n\n    /** {@code r: double; x: long :: r = (double) x} */\n    public static final Rop CONV_L2D =\n        new Rop(RegOps.CONV, Type.DOUBLE, StdTypeList.LONG, \"conv-l2d\");\n\n    /** {@code r: double; x: float :: r = (double) x} */\n    public static final Rop CONV_F2D =\n        new Rop(RegOps.CONV, Type.DOUBLE, StdTypeList.FLOAT, \"conv-f2d\");\n\n    /**\n     * {@code r,x: int :: r = (x << 24) >> 24} (Java-style\n     * convert int to byte)\n     */\n    public static final Rop TO_BYTE =\n        new Rop(RegOps.TO_BYTE, Type.INT, StdTypeList.INT, \"to-byte\");\n\n    /**\n     * {@code r,x: int :: r = x & 0xffff} (Java-style\n     * convert int to char)\n     */\n    public static final Rop TO_CHAR =\n        new Rop(RegOps.TO_CHAR, Type.INT, StdTypeList.INT, \"to-char\");\n\n    /**\n     * {@code r,x: int :: r = (x << 16) >> 16} (Java-style\n     * convert int to short)\n     */\n    public static final Rop TO_SHORT =\n        new Rop(RegOps.TO_SHORT, Type.INT, StdTypeList.INT, \"to-short\");\n\n    /** {@code return void} */\n    public static final Rop RETURN_VOID =\n        new Rop(RegOps.RETURN, Type.VOID, StdTypeList.EMPTY, Rop.BRANCH_RETURN,\n                \"return-void\");\n\n    /** {@code x: int; return x} */\n    public static final Rop RETURN_INT =\n        new Rop(RegOps.RETURN, Type.VOID, StdTypeList.INT, Rop.BRANCH_RETURN,\n                \"return-int\");\n\n    /** {@code x: long; return x} */\n    public static final Rop RETURN_LONG =\n        new Rop(RegOps.RETURN, Type.VOID, StdTypeList.LONG, Rop.BRANCH_RETURN,\n                \"return-long\");\n\n    /** {@code x: float; return x} */\n    public static final Rop RETURN_FLOAT =\n        new Rop(RegOps.RETURN, Type.VOID, StdTypeList.FLOAT, Rop.BRANCH_RETURN,\n                \"return-float\");\n\n    /** {@code x: double; return x} */\n    public static final Rop RETURN_DOUBLE =\n        new Rop(RegOps.RETURN, Type.VOID, StdTypeList.DOUBLE,\n                Rop.BRANCH_RETURN, \"return-double\");\n\n    /** {@code x: Object; return x} */\n    public static final Rop RETURN_OBJECT =\n        new Rop(RegOps.RETURN, Type.VOID, StdTypeList.OBJECT,\n                Rop.BRANCH_RETURN, \"return-object\");\n\n    /** {@code T: any type; r: int; x: T[]; :: r = x.length} */\n    public static final Rop ARRAY_LENGTH =\n        new Rop(RegOps.ARRAY_LENGTH, Type.INT, StdTypeList.OBJECT,\n                Exceptions.LIST_Error_NullPointerException, \"array-length\");\n\n    /** {@code x: Throwable :: throw(x)} */\n    public static final Rop THROW =\n        new Rop(RegOps.THROW, Type.VOID, StdTypeList.THROWABLE,\n                StdTypeList.THROWABLE, \"throw\");\n\n    /** {@code x: Object :: monitorenter(x)} */\n    public static final Rop MONITOR_ENTER =\n        new Rop(RegOps.MONITOR_ENTER, Type.VOID, StdTypeList.OBJECT,\n                Exceptions.LIST_Error_NullPointerException, \"monitor-enter\");\n\n    /** {@code x: Object :: monitorexit(x)} */\n    public static final Rop MONITOR_EXIT =\n        new Rop(RegOps.MONITOR_EXIT, Type.VOID, StdTypeList.OBJECT,\n                Exceptions.LIST_Error_Null_IllegalMonitorStateException,\n                \"monitor-exit\");\n\n    /** {@code r,y: int; x: int[] :: r = x[y]} */\n    public static final Rop AGET_INT =\n        new Rop(RegOps.AGET, Type.INT, StdTypeList.INTARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,\n                \"aget-int\");\n\n    /** {@code r: long; x: long[]; y: int :: r = x[y]} */\n    public static final Rop AGET_LONG =\n        new Rop(RegOps.AGET, Type.LONG, StdTypeList.LONGARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,\n                \"aget-long\");\n\n    /** {@code r: float; x: float[]; y: int :: r = x[y]} */\n    public static final Rop AGET_FLOAT =\n        new Rop(RegOps.AGET, Type.FLOAT, StdTypeList.FLOATARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,\n                \"aget-float\");\n\n    /** {@code r: double; x: double[]; y: int :: r = x[y]} */\n    public static final Rop AGET_DOUBLE =\n        new Rop(RegOps.AGET, Type.DOUBLE, StdTypeList.DOUBLEARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,\n                \"aget-double\");\n\n    /** {@code r: Object; x: Object[]; y: int :: r = x[y]} */\n    public static final Rop AGET_OBJECT =\n        new Rop(RegOps.AGET, Type.OBJECT, StdTypeList.OBJECTARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,\n                \"aget-object\");\n\n    /** {@code r: boolean; x: boolean[]; y: int :: r = x[y]} */\n    public static final Rop AGET_BOOLEAN =\n        new Rop(RegOps.AGET, Type.INT, StdTypeList.BOOLEANARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,\n                \"aget-boolean\");\n\n    /** {@code r: byte; x: byte[]; y: int :: r = x[y]} */\n    public static final Rop AGET_BYTE =\n        new Rop(RegOps.AGET, Type.INT, StdTypeList.BYTEARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, \"aget-byte\");\n\n    /** {@code r: char; x: char[]; y: int :: r = x[y]} */\n    public static final Rop AGET_CHAR =\n        new Rop(RegOps.AGET, Type.INT, StdTypeList.CHARARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, \"aget-char\");\n\n    /** {@code r: short; x: short[]; y: int :: r = x[y]} */\n    public static final Rop AGET_SHORT =\n        new Rop(RegOps.AGET, Type.INT, StdTypeList.SHORTARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,\n                \"aget-short\");\n\n    /** {@code x,z: int; y: int[] :: y[z] = x} */\n    public static final Rop APUT_INT =\n        new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_INTARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, \"aput-int\");\n\n    /** {@code x: long; y: long[]; z: int :: y[z] = x} */\n    public static final Rop APUT_LONG =\n        new Rop(RegOps.APUT, Type.VOID, StdTypeList.LONG_LONGARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, \"aput-long\");\n\n    /** {@code x: float; y: float[]; z: int :: y[z] = x} */\n    public static final Rop APUT_FLOAT =\n        new Rop(RegOps.APUT, Type.VOID, StdTypeList.FLOAT_FLOATARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,\n                \"aput-float\");\n\n    /** {@code x: double; y: double[]; z: int :: y[z] = x} */\n    public static final Rop APUT_DOUBLE =\n        new Rop(RegOps.APUT, Type.VOID, StdTypeList.DOUBLE_DOUBLEARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,\n                \"aput-double\");\n\n    /** {@code x: Object; y: Object[]; z: int :: y[z] = x} */\n    public static final Rop APUT_OBJECT =\n        new Rop(RegOps.APUT, Type.VOID, StdTypeList.OBJECT_OBJECTARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore,\n                \"aput-object\");\n\n    /** {@code x: boolean; y: boolean[]; z: int :: y[z] = x} */\n    public static final Rop APUT_BOOLEAN =\n        new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_BOOLEANARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore,\n                \"aput-boolean\");\n\n    /** {@code x: byte; y: byte[]; z: int :: y[z] = x} */\n    public static final Rop APUT_BYTE =\n        new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_BYTEARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore, \"aput-byte\");\n\n    /** {@code x: char; y: char[]; z: int :: y[z] = x} */\n    public static final Rop APUT_CHAR =\n        new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_CHARARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore, \"aput-char\");\n\n    /** {@code x: short; y: short[]; z: int :: y[z] = x} */\n    public static final Rop APUT_SHORT =\n        new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_SHORTARR_INT,\n                Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore,\n                \"aput-short\");\n\n    /**\n     * {@code T: any non-array object type :: r =\n     * alloc(T)} (allocate heap space for an object)\n     */\n    public static final Rop NEW_INSTANCE =\n        new Rop(RegOps.NEW_INSTANCE, Type.OBJECT, StdTypeList.EMPTY,\n                Exceptions.LIST_Error, \"new-instance\");\n\n    /** {@code r: int[]; x: int :: r = new int[x]} */\n    public static final Rop NEW_ARRAY_INT =\n        new Rop(RegOps.NEW_ARRAY, Type.INT_ARRAY, StdTypeList.INT,\n                Exceptions.LIST_Error_NegativeArraySizeException,\n                \"new-array-int\");\n\n    /** {@code r: long[]; x: int :: r = new long[x]} */\n    public static final Rop NEW_ARRAY_LONG =\n        new Rop(RegOps.NEW_ARRAY, Type.LONG_ARRAY, StdTypeList.INT,\n                Exceptions.LIST_Error_NegativeArraySizeException,\n                \"new-array-long\");\n\n    /** {@code r: float[]; x: int :: r = new float[x]} */\n    public static final Rop NEW_ARRAY_FLOAT =\n        new Rop(RegOps.NEW_ARRAY, Type.FLOAT_ARRAY, StdTypeList.INT,\n                Exceptions.LIST_Error_NegativeArraySizeException,\n                \"new-array-float\");\n\n    /** {@code r: double[]; x: int :: r = new double[x]} */\n    public static final Rop NEW_ARRAY_DOUBLE =\n        new Rop(RegOps.NEW_ARRAY, Type.DOUBLE_ARRAY, StdTypeList.INT,\n                Exceptions.LIST_Error_NegativeArraySizeException,\n                \"new-array-double\");\n\n    /** {@code r: boolean[]; x: int :: r = new boolean[x]} */\n    public static final Rop NEW_ARRAY_BOOLEAN =\n        new Rop(RegOps.NEW_ARRAY, Type.BOOLEAN_ARRAY, StdTypeList.INT,\n                Exceptions.LIST_Error_NegativeArraySizeException,\n                \"new-array-boolean\");\n\n    /** {@code r: byte[]; x: int :: r = new byte[x]} */\n    public static final Rop NEW_ARRAY_BYTE =\n        new Rop(RegOps.NEW_ARRAY, Type.BYTE_ARRAY, StdTypeList.INT,\n                Exceptions.LIST_Error_NegativeArraySizeException,\n                \"new-array-byte\");\n\n    /** {@code r: char[]; x: int :: r = new char[x]} */\n    public static final Rop NEW_ARRAY_CHAR =\n        new Rop(RegOps.NEW_ARRAY, Type.CHAR_ARRAY, StdTypeList.INT,\n                Exceptions.LIST_Error_NegativeArraySizeException,\n                \"new-array-char\");\n\n    /** {@code r: short[]; x: int :: r = new short[x]} */\n    public static final Rop NEW_ARRAY_SHORT =\n        new Rop(RegOps.NEW_ARRAY, Type.SHORT_ARRAY, StdTypeList.INT,\n                Exceptions.LIST_Error_NegativeArraySizeException,\n                \"new-array-short\");\n\n    /**\n     * {@code T: any non-array object type; x: Object :: (T) x} (can\n     * throw {@code ClassCastException})\n     */\n    public static final Rop CHECK_CAST =\n        new Rop(RegOps.CHECK_CAST, Type.VOID, StdTypeList.OBJECT,\n                Exceptions.LIST_Error_ClassCastException, \"check-cast\");\n\n    /**\n     * {@code T: any non-array object type; x: Object :: x instanceof\n     * T}. Note: This is listed as throwing {@code Error}\n     * explicitly because the op <i>can</i> throw, but there are no\n     * other predefined exceptions for it.\n     */\n    public static final Rop INSTANCE_OF =\n        new Rop(RegOps.INSTANCE_OF, Type.INT, StdTypeList.OBJECT,\n                Exceptions.LIST_Error, \"instance-of\");\n\n    /**\n     * {@code r: int; x: Object; f: instance field spec of\n     * type int :: r = x.f}\n     */\n    public static final Rop GET_FIELD_INT =\n        new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,\n                Exceptions.LIST_Error_NullPointerException, \"get-field-int\");\n\n    /**\n     * {@code r: long; x: Object; f: instance field spec of\n     * type long :: r = x.f}\n     */\n    public static final Rop GET_FIELD_LONG =\n        new Rop(RegOps.GET_FIELD, Type.LONG, StdTypeList.OBJECT,\n                Exceptions.LIST_Error_NullPointerException, \"get-field-long\");\n\n    /**\n     * {@code r: float; x: Object; f: instance field spec of\n     * type float :: r = x.f}\n     */\n    public static final Rop GET_FIELD_FLOAT =\n        new Rop(RegOps.GET_FIELD, Type.FLOAT, StdTypeList.OBJECT,\n                Exceptions.LIST_Error_NullPointerException,\n                \"get-field-float\");\n\n    /**\n     * {@code r: double; x: Object; f: instance field spec of\n     * type double :: r = x.f}\n     */\n    public static final Rop GET_FIELD_DOUBLE =\n        new Rop(RegOps.GET_FIELD, Type.DOUBLE, StdTypeList.OBJECT,\n                Exceptions.LIST_Error_NullPointerException,\n                \"get-field-double\");\n\n    /**\n     * {@code r: Object; x: Object; f: instance field spec of\n     * type Object :: r = x.f}\n     */\n    public static final Rop GET_FIELD_OBJECT =\n        new Rop(RegOps.GET_FIELD, Type.OBJECT, StdTypeList.OBJECT,\n                Exceptions.LIST_Error_NullPointerException,\n                \"get-field-object\");\n\n    /**\n     * {@code r: boolean; x: Object; f: instance field spec of\n     * type boolean :: r = x.f}\n     */\n    public static final Rop GET_FIELD_BOOLEAN =\n        new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,\n                Exceptions.LIST_Error_NullPointerException,\n                \"get-field-boolean\");\n\n    /**\n     * {@code r: byte; x: Object; f: instance field spec of\n     * type byte :: r = x.f}\n     */\n    public static final Rop GET_FIELD_BYTE =\n        new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,\n                Exceptions.LIST_Error_NullPointerException,\n                \"get-field-byte\");\n\n    /**\n     * {@code r: char; x: Object; f: instance field spec of\n     * type char :: r = x.f}\n     */\n    public static final Rop GET_FIELD_CHAR =\n        new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,\n                Exceptions.LIST_Error_NullPointerException,\n                \"get-field-char\");\n\n    /**\n     * {@code r: short; x: Object; f: instance field spec of\n     * type short :: r = x.f}\n     */\n    public static final Rop GET_FIELD_SHORT =\n        new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,\n                Exceptions.LIST_Error_NullPointerException,\n                \"get-field-short\");\n\n    /** {@code r: int; f: static field spec of type int :: r = f} */\n    public static final Rop GET_STATIC_INT =\n        new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,\n                Exceptions.LIST_Error, \"get-static-int\");\n\n    /** {@code r: long; f: static field spec of type long :: r = f} */\n    public static final Rop GET_STATIC_LONG =\n        new Rop(RegOps.GET_STATIC, Type.LONG, StdTypeList.EMPTY,\n                Exceptions.LIST_Error, \"get-static-long\");\n\n    /** {@code r: float; f: static field spec of type float :: r = f} */\n    public static final Rop GET_STATIC_FLOAT =\n        new Rop(RegOps.GET_STATIC, Type.FLOAT, StdTypeList.EMPTY,\n                Exceptions.LIST_Error, \"get-static-float\");\n\n    /** {@code r: double; f: static field spec of type double :: r = f} */\n    public static final Rop GET_STATIC_DOUBLE =\n        new Rop(RegOps.GET_STATIC, Type.DOUBLE, StdTypeList.EMPTY,\n                Exceptions.LIST_Error, \"get-static-double\");\n\n    /** {@code r: Object; f: static field spec of type Object :: r = f} */\n    public static final Rop GET_STATIC_OBJECT =\n        new Rop(RegOps.GET_STATIC, Type.OBJECT, StdTypeList.EMPTY,\n                Exceptions.LIST_Error, \"get-static-object\");\n\n    /** {@code r: boolean; f: static field spec of type boolean :: r = f} */\n    public static final Rop GET_STATIC_BOOLEAN =\n        new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,\n                Exceptions.LIST_Error, \"get-field-boolean\");\n\n    /** {@code r: byte; f: static field spec of type byte :: r = f} */\n    public static final Rop GET_STATIC_BYTE =\n        new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,\n                Exceptions.LIST_Error, \"get-field-byte\");\n\n    /** {@code r: char; f: static field spec of type char :: r = f} */\n    public static final Rop GET_STATIC_CHAR =\n        new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,\n                Exceptions.LIST_Error, \"get-field-char\");\n\n    /** {@code r: short; f: static field spec of type short :: r = f} */\n    public static final Rop GET_STATIC_SHORT =\n        new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,\n                Exceptions.LIST_Error, \"get-field-short\");\n\n    /**\n     * {@code x: int; y: Object; f: instance field spec of type\n     * int :: y.f = x}\n     */\n    public static final Rop PUT_FIELD_INT =\n        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,\n                Exceptions.LIST_Error_NullPointerException, \"put-field-int\");\n\n    /**\n     * {@code x: long; y: Object; f: instance field spec of type\n     * long :: y.f = x}\n     */\n    public static final Rop PUT_FIELD_LONG =\n        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.LONG_OBJECT,\n                Exceptions.LIST_Error_NullPointerException, \"put-field-long\");\n\n    /**\n     * {@code x: float; y: Object; f: instance field spec of type\n     * float :: y.f = x}\n     */\n    public static final Rop PUT_FIELD_FLOAT =\n        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.FLOAT_OBJECT,\n                Exceptions.LIST_Error_NullPointerException,\n                \"put-field-float\");\n\n    /**\n     * {@code x: double; y: Object; f: instance field spec of type\n     * double :: y.f = x}\n     */\n    public static final Rop PUT_FIELD_DOUBLE =\n        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.DOUBLE_OBJECT,\n                Exceptions.LIST_Error_NullPointerException,\n                \"put-field-double\");\n\n    /**\n     * {@code x: Object; y: Object; f: instance field spec of type\n     * Object :: y.f = x}\n     */\n    public static final Rop PUT_FIELD_OBJECT =\n        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.OBJECT_OBJECT,\n                Exceptions.LIST_Error_NullPointerException,\n                \"put-field-object\");\n\n    /**\n     * {@code x: int; y: Object; f: instance field spec of type\n     * boolean :: y.f = x}\n     */\n    public static final Rop PUT_FIELD_BOOLEAN =\n        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,\n                Exceptions.LIST_Error_NullPointerException,\n                \"put-field-boolean\");\n\n    /**\n     * {@code x: int; y: Object; f: instance field spec of type\n     * byte :: y.f = x}\n     */\n    public static final Rop PUT_FIELD_BYTE =\n        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,\n                Exceptions.LIST_Error_NullPointerException,\n                \"put-field-byte\");\n\n    /**\n     * {@code x: int; y: Object; f: instance field spec of type\n     * char :: y.f = x}\n     */\n    public static final Rop PUT_FIELD_CHAR =\n        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,\n                Exceptions.LIST_Error_NullPointerException,\n                \"put-field-char\");\n\n    /**\n     * {@code x: int; y: Object; f: instance field spec of type\n     * short :: y.f = x}\n     */\n    public static final Rop PUT_FIELD_SHORT =\n        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,\n                Exceptions.LIST_Error_NullPointerException,\n                \"put-field-short\");\n\n    /** {@code f: static field spec of type int; x: int :: f = x} */\n    public static final Rop PUT_STATIC_INT =\n        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,\n                Exceptions.LIST_Error, \"put-static-int\");\n\n    /** {@code f: static field spec of type long; x: long :: f = x} */\n    public static final Rop PUT_STATIC_LONG =\n        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.LONG,\n                Exceptions.LIST_Error, \"put-static-long\");\n\n    /** {@code f: static field spec of type float; x: float :: f = x} */\n    public static final Rop PUT_STATIC_FLOAT =\n        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.FLOAT,\n                Exceptions.LIST_Error, \"put-static-float\");\n\n    /** {@code f: static field spec of type double; x: double :: f = x} */\n    public static final Rop PUT_STATIC_DOUBLE =\n        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.DOUBLE,\n                Exceptions.LIST_Error, \"put-static-double\");\n\n    /** {@code f: static field spec of type Object; x: Object :: f = x} */\n    public static final Rop PUT_STATIC_OBJECT =\n        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.OBJECT,\n                Exceptions.LIST_Error, \"put-static-object\");\n\n    /**\n     * {@code f: static field spec of type boolean; x: boolean :: f =\n     * x}\n     */\n    public static final Rop PUT_STATIC_BOOLEAN =\n        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,\n                Exceptions.LIST_Error, \"put-static-boolean\");\n\n    /** {@code f: static field spec of type byte; x: byte :: f = x} */\n    public static final Rop PUT_STATIC_BYTE =\n        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,\n                Exceptions.LIST_Error, \"put-static-byte\");\n\n    /** {@code f: static field spec of type char; x: char :: f = x} */\n    public static final Rop PUT_STATIC_CHAR =\n        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,\n                Exceptions.LIST_Error, \"put-static-char\");\n\n    /** {@code f: static field spec of type short; x: short :: f = x} */\n    public static final Rop PUT_STATIC_SHORT =\n        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,\n                Exceptions.LIST_Error, \"put-static-short\");\n\n    /** {@code x: Int :: local variable begins in x} */\n    public static final Rop MARK_LOCAL_INT =\n            new Rop (RegOps.MARK_LOCAL, Type.VOID,\n                    StdTypeList.INT, \"mark-local-int\");\n\n    /** {@code x: Long :: local variable begins in x} */\n    public static final Rop MARK_LOCAL_LONG =\n            new Rop (RegOps.MARK_LOCAL, Type.VOID,\n                    StdTypeList.LONG, \"mark-local-long\");\n\n    /** {@code x: Float :: local variable begins in x} */\n    public static final Rop MARK_LOCAL_FLOAT =\n            new Rop (RegOps.MARK_LOCAL, Type.VOID,\n                    StdTypeList.FLOAT, \"mark-local-float\");\n\n    /** {@code x: Double :: local variable begins in x} */\n    public static final Rop MARK_LOCAL_DOUBLE =\n            new Rop (RegOps.MARK_LOCAL, Type.VOID,\n                    StdTypeList.DOUBLE, \"mark-local-double\");\n\n    /** {@code x: Object :: local variable begins in x} */\n    public static final Rop MARK_LOCAL_OBJECT =\n            new Rop (RegOps.MARK_LOCAL, Type.VOID,\n                    StdTypeList.OBJECT, \"mark-local-object\");\n\n    /** {@code T: Any primitive type; v0..vx: T :: {v0, ..., vx}} */\n    public static final Rop FILL_ARRAY_DATA =\n        new Rop(RegOps.FILL_ARRAY_DATA, Type.VOID, StdTypeList.EMPTY,\n                \"fill-array-data\");\n\n    /**\n     * Returns the appropriate rop for the given opcode, destination,\n     * and sources. The result is typically, but not necessarily, a\n     * shared instance.\n     *\n     * <p><b>Note:</b> This method does not do complete error checking on\n     * its arguments, and so it may return an instance which seemed \"right\n     * enough\" even though in actuality the passed arguments don't quite\n     * match what is returned. TODO: Revisit this issue.</p>\n     *\n     * @param opcode the opcode\n     * @param dest {@code non-null;} destination (result) type, or\n     * {@link Type#VOID} if none\n     * @param sources {@code non-null;} list of source types\n     * @param cst {@code null-ok;} associated constant, if any\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop ropFor(int opcode, TypeBearer dest, TypeList sources,\n            Constant cst) {\n        switch (opcode) {\n            case RegOps.NOP: return NOP;\n            case RegOps.MOVE: return opMove(dest);\n            case RegOps.MOVE_PARAM: return opMoveParam(dest);\n            case RegOps.MOVE_EXCEPTION: return opMoveException(dest);\n            case RegOps.CONST: return opConst(dest);\n            case RegOps.GOTO: return GOTO;\n            case RegOps.IF_EQ: return opIfEq(sources);\n            case RegOps.IF_NE: return opIfNe(sources);\n            case RegOps.IF_LT: return opIfLt(sources);\n            case RegOps.IF_GE: return opIfGe(sources);\n            case RegOps.IF_LE: return opIfLe(sources);\n            case RegOps.IF_GT: return opIfGt(sources);\n            case RegOps.SWITCH: return SWITCH;\n            case RegOps.ADD: return opAdd(sources);\n            case RegOps.SUB: return opSub(sources);\n            case RegOps.MUL: return opMul(sources);\n            case RegOps.DIV: return opDiv(sources);\n            case RegOps.REM: return opRem(sources);\n            case RegOps.NEG: return opNeg(dest);\n            case RegOps.AND: return opAnd(sources);\n            case RegOps.OR: return opOr(sources);\n            case RegOps.XOR: return opXor(sources);\n            case RegOps.SHL: return opShl(sources);\n            case RegOps.SHR: return opShr(sources);\n            case RegOps.USHR: return opUshr(sources);\n            case RegOps.NOT: return opNot(dest);\n            case RegOps.CMPL: return opCmpl(sources.getType(0));\n            case RegOps.CMPG: return opCmpg(sources.getType(0));\n            case RegOps.CONV: return opConv(dest, sources.getType(0));\n            case RegOps.TO_BYTE: return TO_BYTE;\n            case RegOps.TO_CHAR: return TO_CHAR;\n            case RegOps.TO_SHORT: return TO_SHORT;\n            case RegOps.RETURN: {\n                if (sources.size() == 0) {\n                    return RETURN_VOID;\n                }\n                return opReturn(sources.getType(0));\n            }\n            case RegOps.ARRAY_LENGTH: return ARRAY_LENGTH;\n            case RegOps.THROW: return THROW;\n            case RegOps.MONITOR_ENTER: return MONITOR_ENTER;\n            case RegOps.MONITOR_EXIT: return MONITOR_EXIT;\n            case RegOps.AGET: {\n                Type source = sources.getType(0);\n                Type componentType;\n                if (source == Type.KNOWN_NULL) {\n                    /*\n                     * Treat a known-null as an array of the expected\n                     * result type.\n                     */\n                    componentType = dest.getType();\n                } else {\n                    componentType = source.getComponentType();\n                }\n                return opAget(componentType);\n            }\n            case RegOps.APUT: {\n                Type source = sources.getType(1);\n                Type componentType;\n                if (source == Type.KNOWN_NULL) {\n                    /*\n                     * Treat a known-null as an array of the type being\n                     * stored.\n                     */\n                    componentType = sources.getType(0);\n                } else {\n                    componentType = source.getComponentType();\n                }\n                return opAput(componentType);\n            }\n            case RegOps.NEW_INSTANCE: return NEW_INSTANCE;\n            case RegOps.NEW_ARRAY: return opNewArray(dest.getType());\n            case RegOps.CHECK_CAST: return CHECK_CAST;\n            case RegOps.INSTANCE_OF: return INSTANCE_OF;\n            case RegOps.GET_FIELD: return opGetField(dest);\n            case RegOps.GET_STATIC: return opGetStatic(dest);\n            case RegOps.PUT_FIELD: return opPutField(sources.getType(0));\n            case RegOps.PUT_STATIC: return opPutStatic(sources.getType(0));\n            case RegOps.INVOKE_STATIC: {\n                return opInvokeStatic(((CstMethodRef) cst).getPrototype());\n            }\n            case RegOps.INVOKE_VIRTUAL: {\n                CstBaseMethodRef cstMeth = (CstMethodRef) cst;\n                Prototype meth = cstMeth.getPrototype();\n                CstType definer = cstMeth.getDefiningClass();\n                meth = meth.withFirstParameter(definer.getClassType());\n                return opInvokeVirtual(meth);\n            }\n            case RegOps.INVOKE_SUPER: {\n                CstBaseMethodRef cstMeth = (CstMethodRef) cst;\n                Prototype meth = cstMeth.getPrototype();\n                CstType definer = cstMeth.getDefiningClass();\n                meth = meth.withFirstParameter(definer.getClassType());\n                return opInvokeSuper(meth);\n            }\n            case RegOps.INVOKE_DIRECT: {\n                CstBaseMethodRef cstMeth = (CstMethodRef) cst;\n                Prototype meth = cstMeth.getPrototype();\n                CstType definer = cstMeth.getDefiningClass();\n                meth = meth.withFirstParameter(definer.getClassType());\n                return opInvokeDirect(meth);\n            }\n            case RegOps.INVOKE_INTERFACE: {\n                CstBaseMethodRef cstMeth = (CstMethodRef) cst;\n                Prototype meth = cstMeth.getPrototype();\n                CstType definer = cstMeth.getDefiningClass();\n                meth = meth.withFirstParameter(definer.getClassType());\n                return opInvokeInterface(meth);\n            }\n        }\n\n        throw new RuntimeException(\"unknown opcode \" + RegOps.opName(opcode));\n    }\n\n    /**\n     * Returns the appropriate {@code move} rop for the given type. The\n     * result is a shared instance.\n     *\n     * @param type {@code non-null;} type of value being moved\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opMove(TypeBearer type) {\n        switch (type.getBasicFrameType()) {\n            case Type.BT_INT:    return MOVE_INT;\n            case Type.BT_LONG:   return MOVE_LONG;\n            case Type.BT_FLOAT:  return MOVE_FLOAT;\n            case Type.BT_DOUBLE: return MOVE_DOUBLE;\n            case Type.BT_OBJECT: return MOVE_OBJECT;\n            case Type.BT_ADDR:   return MOVE_RETURN_ADDRESS;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code move-param} rop for the\n     * given type. The result is a shared instance.\n     *\n     * @param type {@code non-null;} type of value being moved\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opMoveParam(TypeBearer type) {\n        switch (type.getBasicFrameType()) {\n            case Type.BT_INT:    return MOVE_PARAM_INT;\n            case Type.BT_LONG:   return MOVE_PARAM_LONG;\n            case Type.BT_FLOAT:  return MOVE_PARAM_FLOAT;\n            case Type.BT_DOUBLE: return MOVE_PARAM_DOUBLE;\n            case Type.BT_OBJECT: return MOVE_PARAM_OBJECT;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code move-exception} rop for the\n     * given type. The result may be a shared instance.\n     *\n     * @param type {@code non-null;} type of the exception\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opMoveException(TypeBearer type) {\n        return new Rop(RegOps.MOVE_EXCEPTION, type.getType(),\n                       StdTypeList.EMPTY, (String) null);\n    }\n\n    /**\n     * Returns the appropriate {@code move-result} rop for the\n     * given type. The result may be a shared instance.\n     *\n     * @param type {@code non-null;} type of the parameter\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opMoveResult(TypeBearer type) {\n        return new Rop(RegOps.MOVE_RESULT, type.getType(),\n                       StdTypeList.EMPTY, (String) null);\n    }\n\n    /**\n     * Returns the appropriate {@code move-result-pseudo} rop for the\n     * given type. The result may be a shared instance.\n     *\n     * @param type {@code non-null;} type of the parameter\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opMoveResultPseudo(TypeBearer type) {\n        return new Rop(RegOps.MOVE_RESULT_PSEUDO, type.getType(),\n                       StdTypeList.EMPTY, (String) null);\n    }\n\n    /**\n     * Returns the appropriate {@code const} rop for the given\n     * type. The result is a shared instance.\n     *\n     * @param type {@code non-null;} type of the constant\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opConst(TypeBearer type) {\n        if (type.getType() == Type.KNOWN_NULL) {\n            return CONST_OBJECT_NOTHROW;\n        }\n\n        switch (type.getBasicFrameType()) {\n            case Type.BT_INT:    return CONST_INT;\n            case Type.BT_LONG:   return CONST_LONG;\n            case Type.BT_FLOAT:  return CONST_FLOAT;\n            case Type.BT_DOUBLE: return CONST_DOUBLE;\n            case Type.BT_OBJECT: return CONST_OBJECT;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code if-eq} rop for the given\n     * sources. The result is a shared instance.\n     *\n     * @param types {@code non-null;} source types\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opIfEq(TypeList types) {\n        return pickIf(types, IF_EQZ_INT, IF_EQZ_OBJECT,\n                      IF_EQ_INT, IF_EQ_OBJECT);\n    }\n\n    /**\n     * Returns the appropriate {@code if-ne} rop for the given\n     * sources. The result is a shared instance.\n     *\n     * @param types {@code non-null;} source types\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opIfNe(TypeList types) {\n        return pickIf(types, IF_NEZ_INT, IF_NEZ_OBJECT,\n                      IF_NE_INT, IF_NE_OBJECT);\n    }\n\n    /**\n     * Returns the appropriate {@code if-lt} rop for the given\n     * sources. The result is a shared instance.\n     *\n     * @param types {@code non-null;} source types\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opIfLt(TypeList types) {\n        return pickIf(types, IF_LTZ_INT, null, IF_LT_INT, null);\n    }\n\n    /**\n     * Returns the appropriate {@code if-ge} rop for the given\n     * sources. The result is a shared instance.\n     *\n     * @param types {@code non-null;} source types\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opIfGe(TypeList types) {\n        return pickIf(types, IF_GEZ_INT, null, IF_GE_INT, null);\n    }\n\n    /**\n     * Returns the appropriate {@code if-gt} rop for the given\n     * sources. The result is a shared instance.\n     *\n     * @param types {@code non-null;} source types\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opIfGt(TypeList types) {\n        return pickIf(types, IF_GTZ_INT, null, IF_GT_INT, null);\n    }\n\n    /**\n     * Returns the appropriate {@code if-le} rop for the given\n     * sources. The result is a shared instance.\n     *\n     * @param types {@code non-null;} source types\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opIfLe(TypeList types) {\n        return pickIf(types, IF_LEZ_INT, null, IF_LE_INT, null);\n    }\n\n    /**\n     * Helper for all the {@code if*}-related methods, which\n     * checks types and picks one of the four variants, throwing if\n     * there's a problem.\n     *\n     * @param types {@code non-null;} the types\n     * @param intZ {@code non-null;} the int-to-0 comparison\n     * @param objZ {@code null-ok;} the object-to-null comparison\n     * @param intInt {@code non-null;} the int-to-int comparison\n     * @param objObj {@code non-null;} the object-to-object comparison\n     * @return {@code non-null;} the appropriate instance\n     */\n    private static Rop pickIf(TypeList types, Rop intZ, Rop objZ, Rop intInt,\n                              Rop objObj) {\n        switch(types.size()) {\n            case 1: {\n                switch (types.getType(0).getBasicFrameType()) {\n                    case Type.BT_INT: {\n                        return intZ;\n                    }\n                    case Type.BT_OBJECT: {\n                        if (objZ != null) {\n                            return objZ;\n                        }\n                    }\n                }\n                break;\n            }\n            case 2: {\n                int bt = types.getType(0).getBasicFrameType();\n                if (bt == types.getType(1).getBasicFrameType()) {\n                    switch (bt) {\n                        case Type.BT_INT: {\n                            return intInt;\n                        }\n                        case Type.BT_OBJECT: {\n                            if (objObj != null) {\n                                return objObj;\n                            }\n                        }\n                    }\n                }\n                break;\n            }\n        }\n\n        return throwBadTypes(types);\n    }\n\n    /**\n     * Returns the appropriate {@code add} rop for the given\n     * types. The result is a shared instance.\n     *\n     * @param types {@code non-null;} types of the sources\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opAdd(TypeList types) {\n        return pickBinaryOp(types, ADD_CONST_INT, ADD_CONST_LONG,\n                            ADD_CONST_FLOAT, ADD_CONST_DOUBLE, ADD_INT,\n                            ADD_LONG, ADD_FLOAT, ADD_DOUBLE);\n    }\n\n    /**\n     * Returns the appropriate {@code sub} rop for the given\n     * types. The result is a shared instance.\n     *\n     * @param types {@code non-null;} types of the sources\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opSub(TypeList types) {\n        return pickBinaryOp(types, SUB_CONST_INT, SUB_CONST_LONG,\n                            SUB_CONST_FLOAT, SUB_CONST_DOUBLE, SUB_INT,\n                            SUB_LONG, SUB_FLOAT, SUB_DOUBLE);\n    }\n\n    /**\n     * Returns the appropriate {@code mul} rop for the given\n     * types. The result is a shared instance.\n     *\n     * @param types {@code non-null;} types of the sources\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opMul(TypeList types) {\n        return pickBinaryOp(types, MUL_CONST_INT, MUL_CONST_LONG,\n                            MUL_CONST_FLOAT, MUL_CONST_DOUBLE, MUL_INT,\n                            MUL_LONG, MUL_FLOAT, MUL_DOUBLE);\n    }\n\n    /**\n     * Returns the appropriate {@code div} rop for the given\n     * types. The result is a shared instance.\n     *\n     * @param types {@code non-null;} types of the sources\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opDiv(TypeList types) {\n        return pickBinaryOp(types, DIV_CONST_INT, DIV_CONST_LONG,\n                            DIV_CONST_FLOAT, DIV_CONST_DOUBLE, DIV_INT,\n                            DIV_LONG, DIV_FLOAT, DIV_DOUBLE);\n    }\n\n    /**\n     * Returns the appropriate {@code rem} rop for the given\n     * types. The result is a shared instance.\n     *\n     * @param types {@code non-null;} types of the sources\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opRem(TypeList types) {\n        return pickBinaryOp(types, REM_CONST_INT, REM_CONST_LONG,\n                            REM_CONST_FLOAT, REM_CONST_DOUBLE, REM_INT,\n                            REM_LONG, REM_FLOAT, REM_DOUBLE);\n    }\n\n    /**\n     * Returns the appropriate {@code and} rop for the given\n     * types. The result is a shared instance.\n     *\n     * @param types {@code non-null;} types of the sources\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opAnd(TypeList types) {\n        return pickBinaryOp(types, AND_CONST_INT, AND_CONST_LONG, null, null,\n                            AND_INT, AND_LONG, null, null);\n    }\n\n    /**\n     * Returns the appropriate {@code or} rop for the given\n     * types. The result is a shared instance.\n     *\n     * @param types {@code non-null;} types of the sources\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opOr(TypeList types) {\n        return pickBinaryOp(types, OR_CONST_INT, OR_CONST_LONG, null, null,\n                            OR_INT, OR_LONG, null, null);\n    }\n\n    /**\n     * Returns the appropriate {@code xor} rop for the given\n     * types. The result is a shared instance.\n     *\n     * @param types {@code non-null;} types of the sources\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opXor(TypeList types) {\n        return pickBinaryOp(types, XOR_CONST_INT, XOR_CONST_LONG, null, null,\n                            XOR_INT, XOR_LONG, null, null);\n    }\n\n    /**\n     * Returns the appropriate {@code shl} rop for the given\n     * types. The result is a shared instance.\n     *\n     * @param types {@code non-null;} types of the sources\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opShl(TypeList types) {\n        return pickBinaryOp(types, SHL_CONST_INT, SHL_CONST_LONG, null, null,\n                            SHL_INT, SHL_LONG, null, null);\n    }\n\n    /**\n     * Returns the appropriate {@code shr} rop for the given\n     * types. The result is a shared instance.\n     *\n     * @param types {@code non-null;} types of the sources\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opShr(TypeList types) {\n        return pickBinaryOp(types, SHR_CONST_INT, SHR_CONST_LONG, null, null,\n                            SHR_INT, SHR_LONG, null, null);\n    }\n\n    /**\n     * Returns the appropriate {@code ushr} rop for the given\n     * types. The result is a shared instance.\n     *\n     * @param types {@code non-null;} types of the sources\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opUshr(TypeList types) {\n        return pickBinaryOp(types, USHR_CONST_INT, USHR_CONST_LONG, null, null,\n                            USHR_INT, USHR_LONG, null, null);\n    }\n\n    /**\n     * Returns the appropriate binary arithmetic rop for the given type\n     * and arguments. The result is a shared instance.\n     *\n     * @param types {@code non-null;} sources of the operation\n     * @param int1 {@code non-null;} the int-to-constant rop\n     * @param long1 {@code non-null;} the long-to-constant rop\n     * @param float1 {@code null-ok;} the float-to-constant rop, if any\n     * @param double1 {@code null-ok;} the double-to-constant rop, if any\n     * @param int2 {@code non-null;} the int-to-int rop\n     * @param long2 {@code non-null;} the long-to-long or long-to-int rop\n     * @param float2 {@code null-ok;} the float-to-float rop, if any\n     * @param double2 {@code null-ok;} the double-to-double rop, if any\n     * @return {@code non-null;} an appropriate instance\n     */\n    private static Rop pickBinaryOp(TypeList types, Rop int1, Rop long1,\n                                    Rop float1, Rop double1, Rop int2,\n                                    Rop long2, Rop float2, Rop double2) {\n        int bt1 = types.getType(0).getBasicFrameType();\n        Rop result = null;\n\n        switch (types.size()) {\n            case 1: {\n                switch(bt1) {\n                    case Type.BT_INT:    return int1;\n                    case Type.BT_LONG:   return long1;\n                    case Type.BT_FLOAT:  result = float1; break;\n                    case Type.BT_DOUBLE: result = double1; break;\n                }\n                break;\n            }\n            case 2: {\n                switch(bt1) {\n                    case Type.BT_INT:    return int2;\n                    case Type.BT_LONG:   return long2;\n                    case Type.BT_FLOAT:  result = float2; break;\n                    case Type.BT_DOUBLE: result = double2; break;\n                }\n                break;\n            }\n        }\n\n        if (result == null) {\n            return throwBadTypes(types);\n        }\n\n        return result;\n    }\n\n    /**\n     * Returns the appropriate {@code neg} rop for the given type. The\n     * result is a shared instance.\n     *\n     * @param type {@code non-null;} type of value being operated on\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opNeg(TypeBearer type) {\n        switch (type.getBasicFrameType()) {\n            case Type.BT_INT:    return NEG_INT;\n            case Type.BT_LONG:   return NEG_LONG;\n            case Type.BT_FLOAT:  return NEG_FLOAT;\n            case Type.BT_DOUBLE: return NEG_DOUBLE;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code not} rop for the given type. The\n     * result is a shared instance.\n     *\n     * @param type {@code non-null;} type of value being operated on\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opNot(TypeBearer type) {\n        switch (type.getBasicFrameType()) {\n            case Type.BT_INT:  return NOT_INT;\n            case Type.BT_LONG: return NOT_LONG;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code cmpl} rop for the given type. The\n     * result is a shared instance.\n     *\n     * @param type {@code non-null;} type of value being compared\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opCmpl(TypeBearer type) {\n        switch (type.getBasicType()) {\n            case Type.BT_LONG:   return CMPL_LONG;\n            case Type.BT_FLOAT:  return CMPL_FLOAT;\n            case Type.BT_DOUBLE: return CMPL_DOUBLE;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code cmpg} rop for the given type. The\n     * result is a shared instance.\n     *\n     * @param type {@code non-null;} type of value being compared\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opCmpg(TypeBearer type) {\n        switch (type.getBasicType()) {\n            case Type.BT_FLOAT:  return CMPG_FLOAT;\n            case Type.BT_DOUBLE: return CMPG_DOUBLE;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code conv} rop for the given types. The\n     * result is a shared instance.\n     *\n     * @param dest {@code non-null;} target value type\n     * @param source {@code non-null;} source value type\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opConv(TypeBearer dest, TypeBearer source) {\n        int dbt = dest.getBasicFrameType();\n        switch (source.getBasicFrameType()) {\n            case Type.BT_INT: {\n                switch (dbt) {\n                    case Type.BT_LONG:   return CONV_I2L;\n                    case Type.BT_FLOAT:  return CONV_I2F;\n                    case Type.BT_DOUBLE: return CONV_I2D;\n                    default:             break;\n                }\n            }\n            case Type.BT_LONG: {\n                switch (dbt) {\n                    case Type.BT_INT:    return CONV_L2I;\n                    case Type.BT_FLOAT:  return CONV_L2F;\n                    case Type.BT_DOUBLE: return CONV_L2D;\n                    default:             break;\n                }\n            }\n            case Type.BT_FLOAT: {\n                switch (dbt) {\n                    case Type.BT_INT:    return CONV_F2I;\n                    case Type.BT_LONG:   return CONV_F2L;\n                    case Type.BT_DOUBLE: return CONV_F2D;\n                    default:             break;\n                }\n            }\n            case Type.BT_DOUBLE: {\n                switch (dbt) {\n                    case Type.BT_INT:    return CONV_D2I;\n                    case Type.BT_LONG:   return CONV_D2L;\n                    case Type.BT_FLOAT:  return CONV_D2F;\n                    default:             break;\n                }\n            }\n        }\n\n        return throwBadTypes(StdTypeList.make(dest.getType(),\n                                              source.getType()));\n    }\n\n    /**\n     * Returns the appropriate {@code return} rop for the given type. The\n     * result is a shared instance.\n     *\n     * @param type {@code non-null;} type of value being returned\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opReturn(TypeBearer type) {\n        switch (type.getBasicFrameType()) {\n            case Type.BT_INT:    return RETURN_INT;\n            case Type.BT_LONG:   return RETURN_LONG;\n            case Type.BT_FLOAT:  return RETURN_FLOAT;\n            case Type.BT_DOUBLE: return RETURN_DOUBLE;\n            case Type.BT_OBJECT: return RETURN_OBJECT;\n            case Type.BT_VOID:   return RETURN_VOID;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code aget} rop for the given type. The\n     * result is a shared instance.\n     *\n     * @param type {@code non-null;} element type of array being accessed\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opAget(TypeBearer type) {\n        switch (type.getBasicType()) {\n            case Type.BT_INT:     return AGET_INT;\n            case Type.BT_LONG:    return AGET_LONG;\n            case Type.BT_FLOAT:   return AGET_FLOAT;\n            case Type.BT_DOUBLE:  return AGET_DOUBLE;\n            case Type.BT_OBJECT:  return AGET_OBJECT;\n            case Type.BT_BOOLEAN: return AGET_BOOLEAN;\n            case Type.BT_BYTE:    return AGET_BYTE;\n            case Type.BT_CHAR:    return AGET_CHAR;\n            case Type.BT_SHORT:   return AGET_SHORT;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code aput} rop for the given type. The\n     * result is a shared instance.\n     *\n     * @param type {@code non-null;} element type of array being accessed\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opAput(TypeBearer type) {\n        switch (type.getBasicType()) {\n            case Type.BT_INT:     return APUT_INT;\n            case Type.BT_LONG:    return APUT_LONG;\n            case Type.BT_FLOAT:   return APUT_FLOAT;\n            case Type.BT_DOUBLE:  return APUT_DOUBLE;\n            case Type.BT_OBJECT:  return APUT_OBJECT;\n            case Type.BT_BOOLEAN: return APUT_BOOLEAN;\n            case Type.BT_BYTE:    return APUT_BYTE;\n            case Type.BT_CHAR:    return APUT_CHAR;\n            case Type.BT_SHORT:   return APUT_SHORT;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code new-array} rop for the given\n     * type. The result is a shared instance.\n     *\n     * @param arrayType {@code non-null;} array type of array being created\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opNewArray(TypeBearer arrayType) {\n        Type type = arrayType.getType();\n        Type elementType = type.getComponentType();\n\n        switch (elementType.getBasicType()) {\n            case Type.BT_INT:     return NEW_ARRAY_INT;\n            case Type.BT_LONG:    return NEW_ARRAY_LONG;\n            case Type.BT_FLOAT:   return NEW_ARRAY_FLOAT;\n            case Type.BT_DOUBLE:  return NEW_ARRAY_DOUBLE;\n            case Type.BT_BOOLEAN: return NEW_ARRAY_BOOLEAN;\n            case Type.BT_BYTE:    return NEW_ARRAY_BYTE;\n            case Type.BT_CHAR:    return NEW_ARRAY_CHAR;\n            case Type.BT_SHORT:   return NEW_ARRAY_SHORT;\n            case Type.BT_OBJECT: {\n                return new Rop(RegOps.NEW_ARRAY, type, StdTypeList.INT,\n                        Exceptions.LIST_Error_NegativeArraySizeException,\n                        \"new-array-object\");\n            }\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code filled-new-array} rop for the given\n     * type. The result may be a shared instance.\n     *\n     * @param arrayType {@code non-null;} type of array being created\n     * @param count {@code >= 0;} number of elements that the array should have\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opFilledNewArray(TypeBearer arrayType, int count) {\n        Type type = arrayType.getType();\n        Type elementType = type.getComponentType();\n\n        if (elementType.isCategory2()) {\n            return throwBadType(arrayType);\n        }\n\n        if (count < 0) {\n            throw new IllegalArgumentException(\"count < 0\");\n        }\n\n        StdTypeList sourceTypes = new StdTypeList(count);\n\n        for (int i = 0; i < count; i++) {\n            sourceTypes.set(i, elementType);\n        }\n\n        // Note: The resulting rop is considered call-like.\n        return new Rop(RegOps.FILLED_NEW_ARRAY,\n                       sourceTypes,\n                       Exceptions.LIST_Error);\n    }\n\n    /**\n     * Returns the appropriate {@code get-field} rop for the given\n     * type. The result is a shared instance.\n     *\n     * @param type {@code non-null;} type of the field in question\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opGetField(TypeBearer type) {\n        switch (type.getBasicType()) {\n            case Type.BT_INT:     return GET_FIELD_INT;\n            case Type.BT_LONG:    return GET_FIELD_LONG;\n            case Type.BT_FLOAT:   return GET_FIELD_FLOAT;\n            case Type.BT_DOUBLE:  return GET_FIELD_DOUBLE;\n            case Type.BT_OBJECT:  return GET_FIELD_OBJECT;\n            case Type.BT_BOOLEAN: return GET_FIELD_BOOLEAN;\n            case Type.BT_BYTE:    return GET_FIELD_BYTE;\n            case Type.BT_CHAR:    return GET_FIELD_CHAR;\n            case Type.BT_SHORT:   return GET_FIELD_SHORT;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code put-field} rop for the given\n     * type. The result is a shared instance.\n     *\n     * @param type {@code non-null;} type of the field in question\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opPutField(TypeBearer type) {\n        switch (type.getBasicType()) {\n            case Type.BT_INT:     return PUT_FIELD_INT;\n            case Type.BT_LONG:    return PUT_FIELD_LONG;\n            case Type.BT_FLOAT:   return PUT_FIELD_FLOAT;\n            case Type.BT_DOUBLE:  return PUT_FIELD_DOUBLE;\n            case Type.BT_OBJECT:  return PUT_FIELD_OBJECT;\n            case Type.BT_BOOLEAN: return PUT_FIELD_BOOLEAN;\n            case Type.BT_BYTE:    return PUT_FIELD_BYTE;\n            case Type.BT_CHAR:    return PUT_FIELD_CHAR;\n            case Type.BT_SHORT:   return PUT_FIELD_SHORT;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code get-static} rop for the given\n     * type. The result is a shared instance.\n     *\n     * @param type {@code non-null;} type of the field in question\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opGetStatic(TypeBearer type) {\n        switch (type.getBasicType()) {\n            case Type.BT_INT:     return GET_STATIC_INT;\n            case Type.BT_LONG:    return GET_STATIC_LONG;\n            case Type.BT_FLOAT:   return GET_STATIC_FLOAT;\n            case Type.BT_DOUBLE:  return GET_STATIC_DOUBLE;\n            case Type.BT_OBJECT:  return GET_STATIC_OBJECT;\n            case Type.BT_BOOLEAN: return GET_STATIC_BOOLEAN;\n            case Type.BT_BYTE:    return GET_STATIC_BYTE;\n            case Type.BT_CHAR:    return GET_STATIC_CHAR;\n            case Type.BT_SHORT:   return GET_STATIC_SHORT;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code put-static} rop for the given\n     * type. The result is a shared instance.\n     *\n     * @param type {@code non-null;} type of the field in question\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opPutStatic(TypeBearer type) {\n        switch (type.getBasicType()) {\n            case Type.BT_INT:     return PUT_STATIC_INT;\n            case Type.BT_LONG:    return PUT_STATIC_LONG;\n            case Type.BT_FLOAT:   return PUT_STATIC_FLOAT;\n            case Type.BT_DOUBLE:  return PUT_STATIC_DOUBLE;\n            case Type.BT_OBJECT:  return PUT_STATIC_OBJECT;\n            case Type.BT_BOOLEAN: return PUT_STATIC_BOOLEAN;\n            case Type.BT_BYTE:    return PUT_STATIC_BYTE;\n            case Type.BT_CHAR:    return PUT_STATIC_CHAR;\n            case Type.BT_SHORT:   return PUT_STATIC_SHORT;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * Returns the appropriate {@code invoke-static} rop for the\n     * given type. The result is typically a newly-allocated instance.\n     *\n     * @param meth {@code non-null;} descriptor of the method\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opInvokeStatic(Prototype meth) {\n        return new Rop(RegOps.INVOKE_STATIC,\n                       meth.getParameterFrameTypes(),\n                       StdTypeList.THROWABLE);\n    }\n\n    /**\n     * Returns the appropriate {@code invoke-virtual} rop for the\n     * given type. The result is typically a newly-allocated instance.\n     *\n     * @param meth {@code non-null;} descriptor of the method, including the\n     * {@code this} parameter\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opInvokeVirtual(Prototype meth) {\n        return new Rop(RegOps.INVOKE_VIRTUAL,\n                       meth.getParameterFrameTypes(),\n                       StdTypeList.THROWABLE);\n    }\n\n    /**\n     * Returns the appropriate {@code invoke-super} rop for the\n     * given type. The result is typically a newly-allocated instance.\n     *\n     * @param meth {@code non-null;} descriptor of the method, including the\n     * {@code this} parameter\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opInvokeSuper(Prototype meth) {\n        return new Rop(RegOps.INVOKE_SUPER,\n                       meth.getParameterFrameTypes(),\n                       StdTypeList.THROWABLE);\n    }\n\n    /**\n     * Returns the appropriate {@code invoke-direct} rop for the\n     * given type. The result is typically a newly-allocated instance.\n     *\n     * @param meth {@code non-null;} descriptor of the method, including the\n     * {@code this} parameter\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opInvokeDirect(Prototype meth) {\n        return new Rop(RegOps.INVOKE_DIRECT,\n                       meth.getParameterFrameTypes(),\n                       StdTypeList.THROWABLE);\n    }\n\n    /**\n     * Returns the appropriate {@code invoke-interface} rop for the\n     * given type. The result is typically a newly-allocated instance.\n     *\n     * @param meth {@code non-null;} descriptor of the method, including the\n     * {@code this} parameter\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opInvokeInterface(Prototype meth) {\n        return new Rop(RegOps.INVOKE_INTERFACE,\n                       meth.getParameterFrameTypes(),\n                       StdTypeList.THROWABLE);\n    }\n\n    /**\n     * Returns the appropriate {@code mark-local} rop for the given type.\n     * The result is a shared instance.\n     *\n     * @param type {@code non-null;} type of value being marked\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static Rop opMarkLocal(TypeBearer type) {\n        switch (type.getBasicFrameType()) {\n            case Type.BT_INT:    return MARK_LOCAL_INT;\n            case Type.BT_LONG:   return MARK_LOCAL_LONG;\n            case Type.BT_FLOAT:  return MARK_LOCAL_FLOAT;\n            case Type.BT_DOUBLE: return MARK_LOCAL_DOUBLE;\n            case Type.BT_OBJECT: return MARK_LOCAL_OBJECT;\n        }\n\n        return throwBadType(type);\n    }\n\n    /**\n     * This class is uninstantiable.\n     */\n    private Rops() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Throws the right exception to complain about a bogus type.\n     *\n     * @param type {@code non-null;} the bad type\n     * @return never\n     */\n    private static Rop throwBadType(TypeBearer type) {\n        throw new IllegalArgumentException(\"bad type: \" + type);\n    }\n\n    /**\n     * Throws the right exception to complain about a bogus list of types.\n     *\n     * @param types {@code non-null;} the bad types\n     * @return never\n     */\n    private static Rop throwBadTypes(TypeList types) {\n        throw new IllegalArgumentException(\"bad types: \" + types);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/SourcePosition.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Information about a source position for code, which includes both a\n * line number and original bytecode address.\n */\npublic final class SourcePosition {\n    /** {@code non-null;} convenient \"no information known\" instance */\n    public static final SourcePosition NO_INFO =\n        new SourcePosition(null, -1, -1);\n\n    /** {@code null-ok;} name of the file of origin or {@code null} if unknown */\n    private final CstString sourceFile;\n\n    /**\n     * {@code >= -1;} the bytecode address, or {@code -1} if that\n     * information is unknown\n     */\n    private final int address;\n\n    /**\n     * {@code >= -1;} the line number, or {@code -1} if that\n     * information is unknown\n     */\n    private final int line;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param sourceFile {@code null-ok;} name of the file of origin or\n     * {@code null} if unknown\n     * @param address {@code >= -1;} original bytecode address or {@code -1}\n     * if unknown\n     * @param line {@code >= -1;} original line number or {@code -1} if\n     * unknown\n     */\n    public SourcePosition(CstString sourceFile, int address, int line) {\n        if (address < -1) {\n            throw new IllegalArgumentException(\"address < -1\");\n        }\n\n        if (line < -1) {\n            throw new IllegalArgumentException(\"line < -1\");\n        }\n\n        this.sourceFile = sourceFile;\n        this.address = address;\n        this.line = line;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        StringBuffer sb = new StringBuffer(50);\n\n        if (sourceFile != null) {\n            sb.append(sourceFile.toHuman());\n            sb.append(\":\");\n        }\n\n        if (line >= 0) {\n            sb.append(line);\n        }\n\n        sb.append('@');\n\n        if (address < 0) {\n            sb.append(\"????\");\n        } else {\n            sb.append(Hex.u2(address));\n        }\n\n        return sb.toString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (!(other instanceof SourcePosition)) {\n            return false;\n        }\n\n        if (this == other) {\n            return true;\n        }\n\n        SourcePosition pos = (SourcePosition) other;\n\n        return (address == pos.address) && sameLineAndFile(pos);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return sourceFile.hashCode() + address + line;\n    }\n\n    /**\n     * Returns whether the lines match between this instance and\n     * the one given.\n     *\n     * @param other {@code non-null;} the instance to compare to\n     * @return {@code true} iff the lines match\n     */\n    public boolean sameLine(SourcePosition other) {\n        return (line == other.line);\n    }\n\n    /**\n     * Returns whether the lines and files match between this instance and\n     * the one given.\n     *\n     * @param other {@code non-null;} the instance to compare to\n     * @return {@code true} iff the lines and files match\n     */\n    public boolean sameLineAndFile(SourcePosition other) {\n        return (line == other.line) &&\n            ((sourceFile == other.sourceFile) ||\n             ((sourceFile != null) && sourceFile.equals(other.sourceFile)));\n    }\n\n    /**\n     * Gets the source file, if known.\n     *\n     * @return {@code null-ok;} the source file or {@code null} if unknown\n     */\n    public CstString getSourceFile() {\n        return sourceFile;\n    }\n\n    /**\n     * Gets the original bytecode address.\n     *\n     * @return {@code >= -1;} the address or {@code -1} if unknown\n     */\n    public int getAddress() {\n        return address;\n    }\n\n    /**\n     * Gets the original line number.\n     *\n     * @return {@code >= -1;} the original line number or {@code -1} if\n     * unknown\n     */\n    public int getLine() {\n        return line;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/SwitchInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\nimport com.taobao.android.dx.util.IntList;\n\n/**\n * Instruction which contains switch cases.\n */\npublic final class SwitchInsn\n        extends Insn {\n    /** {@code non-null;} list of switch cases */\n    private final IntList cases;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param opcode {@code non-null;} the opcode\n     * @param position {@code non-null;} source position\n     * @param result {@code null-ok;} spec for the result, if any\n     * @param sources {@code non-null;} specs for all the sources\n     * @param cases {@code non-null;} list of switch cases\n     */\n    public SwitchInsn(Rop opcode, SourcePosition position, RegisterSpec result,\n                      RegisterSpecList sources, IntList cases) {\n        super(opcode, position, result, sources);\n\n        if (opcode.getBranchingness() != Rop.BRANCH_SWITCH) {\n            throw new IllegalArgumentException(\"bogus branchingness\");\n        }\n\n        if (cases == null) {\n            throw new NullPointerException(\"cases == null\");\n        }\n\n        this.cases = cases;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String getInlineString() {\n        return cases.toString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public TypeList getCatches() {\n        return StdTypeList.EMPTY;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void accept(Visitor visitor) {\n        visitor.visitSwitchInsn(this);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withAddedCatch(Type type) {\n        throw new UnsupportedOperationException(\"unsupported\");\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withRegisterOffset(int delta) {\n        return new SwitchInsn(getOpcode(), getPosition(),\n                              getResult().withOffset(delta),\n                              getSources().withOffset(delta),\n                              cases);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p> SwitchInsn always compares false. The current use for this method\n     * never encounters {@code SwitchInsn}s\n     */\n    @Override\n    public boolean contentEquals(Insn b) {\n        return false;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withNewRegisters(RegisterSpec result,\n            RegisterSpecList sources) {\n\n        return new SwitchInsn(getOpcode(), getPosition(),\n                              result,\n                              sources,\n                              cases);\n    }\n\n    /**\n     * Gets the list of switch cases.\n     *\n     * @return {@code non-null;} the case list\n     */\n    public IntList getCases() {\n        return cases;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/ThrowingCstInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\n\n/**\n * Instruction which contains an explicit reference to a constant\n * and which might throw an exception.\n */\npublic final class ThrowingCstInsn\n        extends CstInsn {\n    /** {@code non-null;} list of exceptions caught */\n    private final TypeList catches;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param opcode {@code non-null;} the opcode\n     * @param position {@code non-null;} source position\n     * @param sources {@code non-null;} specs for all the sources\n     * @param catches {@code non-null;} list of exceptions caught\n     * @param cst {@code non-null;} the constant\n     */\n    public ThrowingCstInsn(Rop opcode, SourcePosition position,\n                           RegisterSpecList sources,\n                           TypeList catches, Constant cst) {\n        super(opcode, position, null, sources, cst);\n\n        if (opcode.getBranchingness() != Rop.BRANCH_THROW) {\n            throw new IllegalArgumentException(\"bogus branchingness\");\n        }\n\n        if (catches == null) {\n            throw new NullPointerException(\"catches == null\");\n        }\n\n        this.catches = catches;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String getInlineString() {\n        Constant cst = getConstant();\n        String constantString = cst.toHuman();\n        if (cst instanceof CstString) {\n            constantString = ((CstString) cst).toQuoted();\n        }\n        return constantString + \" \" + ThrowingInsn.toCatchString(catches);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public TypeList getCatches() {\n        return catches;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void accept(Visitor visitor) {\n        visitor.visitThrowingCstInsn(this);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withAddedCatch(Type type) {\n        return new ThrowingCstInsn(getOpcode(), getPosition(),\n                                   getSources(), catches.withAddedType(type),\n                                   getConstant());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withRegisterOffset(int delta) {\n        return new ThrowingCstInsn(getOpcode(), getPosition(),\n                                   getSources().withOffset(delta),\n                                   catches,\n                                   getConstant());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withNewRegisters(RegisterSpec result,\n            RegisterSpecList sources) {\n\n        return new ThrowingCstInsn(getOpcode(), getPosition(),\n                                   sources,\n                                   catches,\n                                   getConstant());\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/ThrowingInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeList;\n\n/**\n * Instruction which possibly throws. The {@code successors} list in the\n * basic block an instance of this class is inside corresponds in-order to\n * the list of exceptions handled by this instruction, with the\n * no-exception case appended as the final target.\n */\npublic final class ThrowingInsn\n        extends Insn {\n    /** {@code non-null;} list of exceptions caught */\n    private final TypeList catches;\n\n    /**\n     * Gets the string form of a register spec list to be used as a catches\n     * list.\n     *\n     * @param catches {@code non-null;} the catches list\n     * @return {@code non-null;} the string form\n     */\n    public static String toCatchString(TypeList catches) {\n        StringBuffer sb = new StringBuffer(100);\n\n        sb.append(\"catch\");\n\n        int sz = catches.size();\n        for (int i = 0; i < sz; i++) {\n            sb.append(\" \");\n            sb.append(catches.getType(i).toHuman());\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param opcode {@code non-null;} the opcode\n     * @param position {@code non-null;} source position\n     * @param sources {@code non-null;} specs for all the sources\n     * @param catches {@code non-null;} list of exceptions caught\n     */\n    public ThrowingInsn(Rop opcode, SourcePosition position,\n                        RegisterSpecList sources,\n                        TypeList catches) {\n        super(opcode, position, null, sources);\n\n        if (opcode.getBranchingness() != Rop.BRANCH_THROW) {\n            throw new IllegalArgumentException(\"bogus branchingness\");\n        }\n\n        if (catches == null) {\n            throw new NullPointerException(\"catches == null\");\n        }\n\n        this.catches = catches;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String getInlineString() {\n        return toCatchString(catches);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public TypeList getCatches() {\n        return catches;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void accept(Visitor visitor) {\n        visitor.visitThrowingInsn(this);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withAddedCatch(Type type) {\n        return new ThrowingInsn(getOpcode(), getPosition(),\n                                getSources(), catches.withAddedType(type));\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withRegisterOffset(int delta) {\n        return new ThrowingInsn(getOpcode(), getPosition(),\n                                getSources().withOffset(delta),\n                                catches);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn withNewRegisters(RegisterSpec result,\n            RegisterSpecList sources) {\n\n        return new ThrowingInsn(getOpcode(), getPosition(),\n                                sources,\n                                catches);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/TranslationAdvice.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.code;\n\n/**\n * Interface for \"advice\" passed from the late stage of translation back\n * to the early stage. This allows for the final target architecture to\n * exert its influence early in the translation process without having\n * the early stage code be explicitly tied to the target.\n */\npublic interface TranslationAdvice {\n    /**\n     * Returns an indication of whether the target can directly represent an\n     * instruction with the given opcode operating on the given arguments,\n     * where the last source argument is used as a constant. (That is, the\n     * last argument must have a type which indicates it is a known constant.)\n     * The instruction associated must have exactly two sources.\n     *\n     * @param opcode {@code non-null;} the opcode\n     * @param sourceA {@code non-null;} the first source\n     * @param sourceB {@code non-null;} the second source\n     * @return {@code true} iff the target can represent the operation\n     * using a constant for the last argument\n     */\n    public boolean hasConstantOperation(Rop opcode,\n                                        RegisterSpec sourceA, RegisterSpec sourceB);\n\n    /**\n     * Returns true if the translation target requires the sources of the\n     * specified opcode to be in order and contiguous (eg, for an invoke-range)\n     *\n     * @param opcode {@code non-null;} opcode\n     * @param sources {@code non-null;} source list\n     * @return {@code true} iff the target requires the sources to be\n     * in order and contiguous.\n     */\n    public boolean requiresSourcesInOrder(Rop opcode, RegisterSpecList sources);\n\n    /**\n     * Gets the maximum register width that can be represented optimally.\n     * For example, Dex bytecode does not have instruction forms that take\n     * register numbers larger than 15 for all instructions so\n     * DexTranslationAdvice returns 15 here.\n     *\n     * @return register count noted above\n     */\n    public int getMaxOptimalRegisterCount();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/code/package.html",
    "content": "<body>\n<p>Classes relating to a register-based opcode system.</p>\n\n<p><b>PACKAGES USED:</b>\n<ul>\n<li><code>com.taobao.android.dx.util</code></li>\n</ul>\n</body>\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/Constant.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.util.ToHuman;\n\n/**\n * Base class for constants of all sorts.\n */\npublic abstract class Constant\n        implements ToHuman, Comparable<Constant> {\n    /**\n     * Returns {@code true} if this instance is a category-2 constant,\n     * meaning it takes up two slots in the constant pool, or\n     * {@code false} if this instance is category-1.\n     *\n     * @return {@code true} iff this instance is category-2\n     */\n    public abstract boolean isCategory2();\n\n    /**\n     * Returns the human name for the particular type of constant\n     * this instance is.\n     *\n     * @return {@code non-null;} the name\n     */\n    public abstract String typeName();\n\n    /**\n     * {@inheritDoc}\n     *\n     * This compares in class-major and value-minor order.\n     */\n    public final int compareTo(Constant other) {\n        Class clazz = getClass();\n        Class otherClazz = other.getClass();\n\n        if (clazz != otherClazz) {\n            return clazz.getName().compareTo(otherClazz.getName());\n        }\n\n        return compareTo0(other);\n    }\n\n    /**\n     * Compare the values of this and another instance, which are guaranteed\n     * to be of the same class. Subclasses must implement this.\n     *\n     * @param other {@code non-null;} the instance to compare to\n     * @return {@code -1}, {@code 0}, or {@code 1}, as usual\n     * for a comparison\n     */\n    protected abstract int compareTo0(Constant other);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/ConstantPool.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\n/**\n * Interface for constant pools, which are, more or less, just lists of\n * {@link Constant} objects.\n */\npublic interface ConstantPool {\n    /**\n     * Get the \"size\" of the constant pool. This corresponds to the\n     * class file field {@code constant_pool_count}, and is in fact\n     * always at least one more than the actual size of the constant pool,\n     * as element {@code 0} is always invalid.\n     *\n     * @return {@code >= 1;} the size\n     */\n    public int size();\n\n    /**\n     * Get the {@code n}th entry in the constant pool, which must\n     * be valid.\n     *\n     * @param n {@code n >= 0, n < size();} the constant pool index\n     * @return {@code non-null;} the corresponding entry\n     * @throws IllegalArgumentException thrown if {@code n} is\n     * in-range but invalid\n     */\n    public Constant get(int n);\n\n    /**\n     * Get the {@code n}th entry in the constant pool, which must\n     * be valid unless {@code n == 0}, in which case {@code null}\n     * is returned.\n     *\n     * @param n {@code n >= 0, n < size();} the constant pool index\n     * @return {@code null-ok;} the corresponding entry, if {@code n != 0}\n     * @throws IllegalArgumentException thrown if {@code n} is\n     * in-range and non-zero but invalid\n     */\n    public Constant get0Ok(int n);\n\n    /**\n     * Get the {@code n}th entry in the constant pool, or\n     * {@code null} if the index is in-range but invalid. In\n     * particular, {@code null} is returned for index {@code 0}\n     * as well as the index after any entry which is defined to take up\n     * two slots (that is, {@code Long} and {@code Double}\n     * entries).\n     *\n     * @param n {@code n >= 0, n < size();} the constant pool index\n     * @return {@code null-ok;} the corresponding entry, or {@code null} if\n     * the index is in-range but invalid\n     */\n    public Constant getOrNull(int n);\n\n    /**\n     * Get all entries in this constant pool.\n     *\n     * @return the returned array may contain null entries.\n     */\n    public Constant[] getEntries();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstAnnotation.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.annotation.Annotation;\n\n/**\n * Constant type that represents an annotation.\n */\npublic final class CstAnnotation extends Constant {\n    /** {@code non-null;} the actual annotation */\n    private final Annotation annotation;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param annotation {@code non-null;} the annotation to hold\n     */\n    public CstAnnotation(Annotation annotation) {\n        if (annotation == null) {\n            throw new NullPointerException(\"annotation == null\");\n        }\n\n        annotation.throwIfMutable();\n\n        this.annotation = annotation;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (! (other instanceof CstAnnotation)) {\n            return false;\n        }\n\n        return annotation.equals(((CstAnnotation) other).annotation);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return annotation.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int compareTo0(Constant other) {\n        return annotation.compareTo(((CstAnnotation) other).annotation);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return annotation.toString();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"annotation\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCategory2() {\n        return false;\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return annotation.toString();\n    }\n\n    /**\n     * Get the underlying annotation.\n     *\n     * @return {@code non-null;} the annotation\n     */\n    public Annotation getAnnotation() {\n        return annotation;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstArray.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.util.FixedSizeList;\n\n/**\n * Constant type to represent a fixed array of other constants.\n */\npublic final class CstArray extends Constant {\n    /** {@code non-null;} the actual list of contents */\n    private final List list;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param list {@code non-null;} the actual list of contents\n     */\n    public CstArray(List list) {\n        if (list == null) {\n            throw new NullPointerException(\"list == null\");\n        }\n\n        list.throwIfMutable();\n\n        this.list = list;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (! (other instanceof CstArray)) {\n            return false;\n        }\n\n        return list.equals(((CstArray) other).list);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return list.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int compareTo0(Constant other) {\n        return list.compareTo(((CstArray) other).list);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return list.toString(\"array{\", \", \", \"}\");\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"array\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCategory2() {\n        return false;\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return list.toHuman(\"{\", \", \", \"}\");\n    }\n\n    /**\n     * Get the underlying list.\n     *\n     * @return {@code non-null;} the list\n     */\n    public List getList() {\n        return list;\n    }\n\n    /**\n     * List of {@link Constant} instances.\n     */\n    public static final class List\n            extends FixedSizeList implements Comparable<List> {\n        /**\n         * Constructs an instance. All indices initially contain\n         * {@code null}.\n         *\n         * @param size the size of the list\n         */\n        public List(int size) {\n            super(size);\n        }\n\n        /** {@inheritDoc} */\n        public int compareTo(List other) {\n            int thisSize = size();\n            int otherSize = other.size();\n            int compareSize = (thisSize < otherSize) ? thisSize : otherSize;\n\n            for (int i = 0; i < compareSize; i++) {\n                Constant thisItem = (Constant) get0(i);\n                Constant otherItem = (Constant) other.get0(i);\n                int compare = thisItem.compareTo(otherItem);\n                if (compare != 0) {\n                    return compare;\n                }\n            }\n\n            if (thisSize < otherSize) {\n                return -1;\n            } else if (thisSize > otherSize) {\n                return 1;\n            }\n\n            return 0;\n        }\n\n        /**\n         * Gets the element at the given index. It is an error to call\n         * this with the index for an element which was never set; if you\n         * do that, this will throw {@code NullPointerException}.\n         *\n         * @param n {@code >= 0, < size();} which index\n         * @return {@code non-null;} element at that index\n         */\n        public Constant get(int n) {\n            return (Constant) get0(n);\n        }\n\n        /**\n         * Sets the element at the given index.\n         *\n         * @param n {@code >= 0, < size();} which index\n         * @param a {@code null-ok;} the element to set at {@code n}\n         */\n        public void set(int n, Constant a) {\n            set0(n, a);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstBaseMethodRef.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Prototype;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\n\n/**\n * Base class for constants of \"methodish\" type.\n *\n * <p><b>Note:</b> As a {@link TypeBearer}, this class bears the return type\n * of the method.</p>\n */\npublic abstract class CstBaseMethodRef\n        extends CstMemberRef {\n    /** {@code non-null;} the raw prototype for this method */\n    private final Prototype prototype;\n\n    /**\n     * {@code null-ok;} the prototype for this method taken to be an instance\n     * method, or {@code null} if not yet calculated\n     */\n    private Prototype instancePrototype;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param definingClass {@code non-null;} the type of the defining class\n     * @param nat {@code non-null;} the name-and-type\n     */\n    /*package*/ CstBaseMethodRef(CstType definingClass, CstNat nat) {\n        super(definingClass, nat);\n\n        String descriptor = getNat().getDescriptor().getString();\n        this.prototype = Prototype.intern(descriptor);\n        this.instancePrototype = null;\n    }\n\n    /**\n     * Gets the raw prototype of this method. This doesn't include a\n     * {@code this} argument.\n     *\n     * @return {@code non-null;} the method prototype\n     */\n    public final Prototype getPrototype() {\n        return prototype;\n    }\n\n    /**\n     * Gets the prototype of this method as either a\n     * {@code static} or instance method. In the case of a\n     * {@code static} method, this is the same as the raw\n     * prototype. In the case of an instance method, this has an\n     * appropriately-typed {@code this} argument as the first\n     * one.\n     *\n     * @param isStatic whether the method should be considered static\n     * @return {@code non-null;} the method prototype\n     */\n    public final Prototype getPrototype(boolean isStatic) {\n        if (isStatic) {\n            return prototype;\n        } else {\n            if (instancePrototype == null) {\n                Type thisType = getDefiningClass().getClassType();\n                instancePrototype = prototype.withFirstParameter(thisType);\n            }\n            return instancePrototype;\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected final int compareTo0(Constant other) {\n        int cmp = super.compareTo0(other);\n\n        if (cmp != 0) {\n            return cmp;\n        }\n\n        CstBaseMethodRef otherMethod = (CstBaseMethodRef) other;\n        return prototype.compareTo(otherMethod.prototype);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * In this case, this method returns the <i>return type</i> of this method.\n     *\n     * @return {@code non-null;} the method's return type\n     */\n    public final Type getType() {\n        return prototype.getReturnType();\n    }\n\n    /**\n     * Gets the number of words of parameters required by this\n     * method's descriptor. Since instances of this class have no way\n     * to know if they will be used in a {@code static} or\n     * instance context, one has to indicate this explicitly as an\n     * argument. This method is just a convenient shorthand for\n     * {@code getPrototype().getParameterTypes().getWordCount()},\n     * plus {@code 1} if the method is to be treated as an\n     * instance method.\n     *\n     * @param isStatic whether the method should be considered static\n     * @return {@code >= 0;} the argument word count\n     */\n    public final int getParameterWordCount(boolean isStatic) {\n        return getPrototype(isStatic).getParameterTypes().getWordCount();\n    }\n\n    /**\n     * Gets whether this is a reference to an instance initialization\n     * method. This is just a convenient shorthand for\n     * {@code getNat().isInstanceInit()}.\n     *\n     * @return {@code true} iff this is a reference to an\n     * instance initialization method\n     */\n    public final boolean isInstanceInit() {\n        return getNat().isInstanceInit();\n    }\n\n    /**\n     * Gets whether this is a reference to a class initialization\n     * method. This is just a convenient shorthand for\n     * {@code getNat().isClassInit()}.\n     *\n     * @return {@code true} iff this is a reference to an\n     * instance initialization method\n     */\n    public final boolean isClassInit() {\n        return getNat().isClassInit();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstBoolean.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\n\n/**\n * Constants of type {@code boolean}.\n */\npublic final class CstBoolean\n        extends CstLiteral32 {\n    /** {@code non-null;} instance representing {@code false} */\n    public static final CstBoolean VALUE_FALSE = new CstBoolean(false);\n\n    /** {@code non-null;} instance representing {@code true} */\n    public static final CstBoolean VALUE_TRUE = new CstBoolean(true);\n\n    /**\n     * Makes an instance for the given value. This will return an\n     * already-allocated instance.\n     *\n     * @param value the {@code boolean} value\n     * @return {@code non-null;} the appropriate instance\n     */\n    public static CstBoolean make(boolean value) {\n        return value ? VALUE_TRUE : VALUE_FALSE;\n    }\n\n    /**\n     * Makes an instance for the given {@code int} value. This\n     * will return an already-allocated instance.\n     *\n     * @param value must be either {@code 0} or {@code 1}\n     * @return {@code non-null;} the appropriate instance\n     */\n    public static CstBoolean make(int value) {\n        if (value == 0) {\n            return VALUE_FALSE;\n        } else if (value == 1) {\n            return VALUE_TRUE;\n        } else {\n            throw new IllegalArgumentException(\"bogus value: \" + value);\n        }\n    }\n\n    /**\n     * Constructs an instance. This constructor is private; use {@link #make}.\n     *\n     * @param value the {@code boolean} value\n     */\n    private CstBoolean(boolean value) {\n        super(value ? 1 : 0);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return getValue() ? \"boolean{true}\" : \"boolean{false}\";\n    }\n\n    /** {@inheritDoc} */\n    public Type getType() {\n        return Type.BOOLEAN;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"boolean\";\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return getValue() ? \"true\" : \"false\";\n    }\n\n    /**\n     * Gets the {@code boolean} value.\n     *\n     * @return the value\n     */\n    public boolean getValue() {\n        return (getIntBits() == 0) ? false : true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstByte.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Constants of type {@code byte}.\n */\npublic final class CstByte\n        extends CstLiteral32 {\n    /** {@code non-null;} the value {@code 0} as an instance of this class */\n    public static final CstByte VALUE_0 = make((byte) 0);\n\n    /**\n     * Makes an instance for the given value. This may (but does not\n     * necessarily) return an already-allocated instance.\n     *\n     * @param value the {@code byte} value\n     */\n    public static CstByte make(byte value) {\n        return new CstByte(value);\n    }\n\n    /**\n     * Makes an instance for the given {@code int} value. This\n     * may (but does not necessarily) return an already-allocated\n     * instance.\n     *\n     * @param value the value, which must be in range for a {@code byte}\n     * @return {@code non-null;} the appropriate instance\n     */\n    public static CstByte make(int value) {\n        byte cast = (byte) value;\n\n        if (cast != value) {\n            throw new IllegalArgumentException(\"bogus byte value: \" +\n                    value);\n        }\n\n        return make(cast);\n    }\n\n    /**\n     * Constructs an instance. This constructor is private; use {@link #make}.\n     *\n     * @param value the {@code byte} value\n     */\n    private CstByte(byte value) {\n        super(value);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        int value = getIntBits();\n        return \"byte{0x\" + Hex.u1(value) + \" / \" + value + '}';\n    }\n\n    /** {@inheritDoc} */\n    public Type getType() {\n        return Type.BYTE;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"byte\";\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return Integer.toString(getIntBits());\n    }\n\n    /**\n     * Gets the {@code byte} value.\n     *\n     * @return the value\n     */\n    public byte getValue() {\n        return (byte) getIntBits();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstChar.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Constants of type {@code char}.\n */\npublic final class CstChar\n        extends CstLiteral32 {\n    /** {@code non-null;} the value {@code 0} as an instance of this class */\n    public static final CstChar VALUE_0 = make((char) 0);\n\n    /**\n     * Makes an instance for the given value. This may (but does not\n     * necessarily) return an already-allocated instance.\n     *\n     * @param value the {@code char} value\n     */\n    public static CstChar make(char value) {\n        return new CstChar(value);\n    }\n\n    /**\n     * Makes an instance for the given {@code int} value. This\n     * may (but does not necessarily) return an already-allocated\n     * instance.\n     *\n     * @param value the value, which must be in range for a {@code char}\n     * @return {@code non-null;} the appropriate instance\n     */\n    public static CstChar make(int value) {\n        char cast = (char) value;\n\n        if (cast != value) {\n            throw new IllegalArgumentException(\"bogus char value: \" +\n                    value);\n        }\n\n        return make(cast);\n    }\n\n    /**\n     * Constructs an instance. This constructor is private; use {@link #make}.\n     *\n     * @param value the {@code char} value\n     */\n    private CstChar(char value) {\n        super(value);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        int value = getIntBits();\n        return \"char{0x\" + Hex.u2(value) + \" / \" + value + '}';\n    }\n\n    /** {@inheritDoc} */\n    public Type getType() {\n        return Type.CHAR;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"char\";\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return Integer.toString(getIntBits());\n    }\n\n    /**\n     * Gets the {@code char} value.\n     *\n     * @return the value\n     */\n    public char getValue() {\n        return (char) getIntBits();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstDouble.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Constants of type {@code CONSTANT_Double_info}.\n */\npublic final class CstDouble\n        extends CstLiteral64 {\n    /** {@code non-null;} instance representing {@code 0} */\n    public static final CstDouble VALUE_0 =\n        new CstDouble(Double.doubleToLongBits(0.0));\n\n    /** {@code non-null;} instance representing {@code 1} */\n    public static final CstDouble VALUE_1 =\n        new CstDouble(Double.doubleToLongBits(1.0));\n\n    /**\n     * Makes an instance for the given value. This may (but does not\n     * necessarily) return an already-allocated instance.\n     *\n     * @param bits the {@code double} value as {@code long} bits\n     */\n    public static CstDouble make(long bits) {\n        /*\n         * Note: Javadoc notwithstanding, this implementation always\n         * allocates.\n         */\n        return new CstDouble(bits);\n    }\n\n    /**\n     * Constructs an instance. This constructor is private; use {@link #make}.\n     *\n     * @param bits the {@code double} value as {@code long} bits\n     */\n    private CstDouble(long bits) {\n        super(bits);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        long bits = getLongBits();\n        return \"double{0x\" + Hex.u8(bits) + \" / \" +\n            Double.longBitsToDouble(bits) + '}';\n    }\n\n    /** {@inheritDoc} */\n    public Type getType() {\n        return Type.DOUBLE;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"double\";\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return Double.toString(Double.longBitsToDouble(getLongBits()));\n    }\n\n    /**\n     * Gets the {@code double} value.\n     *\n     * @return the value\n     */\n    public double getValue() {\n        return Double.longBitsToDouble(getLongBits());\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstEnumRef.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\n\n/**\n * Constant type to represent a reference to a particular constant\n * value of an enumerated type.\n */\npublic final class CstEnumRef extends CstMemberRef {\n    /** {@code null-ok;} the corresponding field ref, lazily initialized */\n    private CstFieldRef fieldRef;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param nat {@code non-null;} the name-and-type; the defining class is derived\n     * from this\n     */\n    public CstEnumRef(CstNat nat) {\n        super(new CstType(nat.getFieldType()), nat);\n\n        fieldRef = null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"enum\";\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <b>Note:</b> This returns the enumerated type.\n     */\n    public Type getType() {\n        return getDefiningClass().getClassType();\n    }\n\n    /**\n     * Get a {@link CstFieldRef} that corresponds with this instance.\n     *\n     * @return {@code non-null;} the corresponding field reference\n     */\n    public CstFieldRef getFieldRef() {\n        if (fieldRef == null) {\n            fieldRef = new CstFieldRef(getDefiningClass(), getNat());\n        }\n\n        return fieldRef;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstFieldRef.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\n\n/**\n * Constants of type {@code CONSTANT_Fieldref_info}.\n */\npublic final class CstFieldRef extends CstMemberRef {\n    /**\n     * Returns an instance of this class that represents the static\n     * field which should hold the class corresponding to a given\n     * primitive type. For example, if given {@link Type#INT}, this\n     * method returns an instance corresponding to the field\n     * {@code java.lang.Integer.TYPE}.\n     *\n     * @param primitiveType {@code non-null;} the primitive type\n     * @return {@code non-null;} the corresponding static field\n     */\n    public static CstFieldRef forPrimitiveType(Type primitiveType) {\n        return new CstFieldRef(CstType.forBoxedPrimitiveType(primitiveType),\n                CstNat.PRIMITIVE_TYPE_NAT);\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param definingClass {@code non-null;} the type of the defining class\n     * @param nat {@code non-null;} the name-and-type\n     */\n    public CstFieldRef(CstType definingClass, CstNat nat) {\n        super(definingClass, nat);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"field\";\n    }\n\n    /**\n     * Returns the type of this field.\n     *\n     * @return {@code non-null;} the field's type\n     */\n    public Type getType() {\n        return getNat().getFieldType();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int compareTo0(Constant other) {\n        int cmp = super.compareTo0(other);\n\n        if (cmp != 0) {\n            return cmp;\n        }\n\n        CstFieldRef otherField = (CstFieldRef) other;\n        CstString thisDescriptor = getNat().getDescriptor();\n        CstString otherDescriptor = otherField.getNat().getDescriptor();\n        return thisDescriptor.compareTo(otherDescriptor);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstFloat.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Constants of type {@code CONSTANT_Float_info}.\n */\npublic final class CstFloat\n        extends CstLiteral32 {\n    /** {@code non-null;} instance representing {@code 0} */\n    public static final CstFloat VALUE_0 = make(Float.floatToIntBits(0.0f));\n\n    /** {@code non-null;} instance representing {@code 1} */\n    public static final CstFloat VALUE_1 = make(Float.floatToIntBits(1.0f));\n\n    /** {@code non-null;} instance representing {@code 2} */\n    public static final CstFloat VALUE_2 = make(Float.floatToIntBits(2.0f));\n\n    /**\n     * Makes an instance for the given value. This may (but does not\n     * necessarily) return an already-allocated instance.\n     *\n     * @param bits the {@code float} value as {@code int} bits\n     */\n    public static CstFloat make(int bits) {\n        /*\n         * Note: Javadoc notwithstanding, this implementation always\n         * allocates.\n         */\n        return new CstFloat(bits);\n    }\n\n    /**\n     * Constructs an instance. This constructor is private; use {@link #make}.\n     *\n     * @param bits the {@code float} value as {@code int} bits\n     */\n    private CstFloat(int bits) {\n        super(bits);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        int bits = getIntBits();\n        return \"float{0x\" + Hex.u4(bits) + \" / \" +\n            Float.intBitsToFloat(bits) + '}';\n    }\n\n    /** {@inheritDoc} */\n    public Type getType() {\n        return Type.FLOAT;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"float\";\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return Float.toString(Float.intBitsToFloat(getIntBits()));\n    }\n\n    /**\n     * Gets the {@code float} value.\n     *\n     * @return the value\n     */\n    public float getValue() {\n        return Float.intBitsToFloat(getIntBits());\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstInteger.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Constants of type {@code CONSTANT_Integer_info}.\n */\npublic final class CstInteger\n        extends CstLiteral32 {\n    /** {@code non-null;} array of cached instances */\n    private static final CstInteger[] cache = new CstInteger[511];\n\n    /** {@code non-null;} instance representing {@code -1} */\n    public static final CstInteger VALUE_M1 = make(-1);\n\n    /** {@code non-null;} instance representing {@code 0} */\n    public static final CstInteger VALUE_0 = make(0);\n\n    /** {@code non-null;} instance representing {@code 1} */\n    public static final CstInteger VALUE_1 = make(1);\n\n    /** {@code non-null;} instance representing {@code 2} */\n    public static final CstInteger VALUE_2 = make(2);\n\n    /** {@code non-null;} instance representing {@code 3} */\n    public static final CstInteger VALUE_3 = make(3);\n\n    /** {@code non-null;} instance representing {@code 4} */\n    public static final CstInteger VALUE_4 = make(4);\n\n    /** {@code non-null;} instance representing {@code 5} */\n    public static final CstInteger VALUE_5 = make(5);\n\n    /**\n     * Makes an instance for the given value. This may (but does not\n     * necessarily) return an already-allocated instance.\n     *\n     * @param value the {@code int} value\n     * @return {@code non-null;} the appropriate instance\n     */\n    public static CstInteger make(int value) {\n        /*\n         * Note: No need to synchronize, since we don't make any sort\n         * of guarantee about ==, and it's okay to overwrite existing\n         * entries too.\n         */\n        int idx = (value & 0x7fffffff) % cache.length;\n        CstInteger obj = cache[idx];\n\n        if ((obj != null) && (obj.getValue() == value)) {\n            return obj;\n        }\n\n        obj = new CstInteger(value);\n        cache[idx] = obj;\n        return obj;\n    }\n\n    /**\n     * Constructs an instance. This constructor is private; use {@link #make}.\n     *\n     * @param value the {@code int} value\n     */\n    private CstInteger(int value) {\n        super(value);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        int value = getIntBits();\n        return \"int{0x\" + Hex.u4(value) + \" / \" + value + '}';\n    }\n\n    /** {@inheritDoc} */\n    public Type getType() {\n        return Type.INT;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"int\";\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return Integer.toString(getIntBits());\n    }\n\n    /**\n     * Gets the {@code int} value.\n     *\n     * @return the value\n     */\n    public int getValue() {\n        return getIntBits();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstInterfaceMethodRef.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\n/**\n * Constants of type {@code CONSTANT_InterfaceMethodref_info}.\n */\npublic final class CstInterfaceMethodRef\n        extends CstBaseMethodRef {\n    /**\n     * {@code null-ok;} normal {@link CstMethodRef} that corresponds to this\n     * instance, if calculated\n     */\n    private CstMethodRef methodRef;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param definingClass {@code non-null;} the type of the defining class\n     * @param nat {@code non-null;} the name-and-type\n     */\n    public CstInterfaceMethodRef(CstType definingClass, CstNat nat) {\n        super(definingClass, nat);\n        methodRef = null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"ifaceMethod\";\n    }\n\n    /**\n     * Gets a normal (non-interface) {@link CstMethodRef} that corresponds to\n     * this instance.\n     *\n     * @return {@code non-null;} an appropriate instance\n     */\n    public CstMethodRef toMethodRef() {\n        if (methodRef == null) {\n            methodRef = new CstMethodRef(getDefiningClass(), getNat());\n        }\n\n        return methodRef;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstKnownNull.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\n\n/**\n * Constant type to represent a known-{@code null} value.\n */\npublic final class CstKnownNull extends CstLiteralBits {\n    /** {@code non-null;} unique instance of this class */\n    public static final CstKnownNull THE_ONE = new CstKnownNull();\n\n    /**\n     * Constructs an instance. This class is not publicly instantiable. Use\n     * {@link #THE_ONE}.\n     */\n    private CstKnownNull() {\n        // This space intentionally left blank.\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        return (other instanceof CstKnownNull);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return 0x4466757a;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int compareTo0(Constant other) {\n        return 0;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return \"known-null\";\n    }\n\n    /** {@inheritDoc} */\n    public Type getType() {\n        return Type.KNOWN_NULL;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"known-null\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCategory2() {\n        return false;\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return \"null\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean fitsInInt() {\n        // See comment in getIntBits().\n        return true;\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * As \"literal bits,\" a known-null is always represented as the\n     * number zero.\n     */\n    @Override\n    public int getIntBits() {\n        return 0;\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * As \"literal bits,\" a known-null is always represented as the\n     * number zero.\n     */\n    @Override\n    public long getLongBits() {\n        return 0;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstLiteral32.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\n/**\n * Constants which are literal 32-bit values of some sort.\n */\npublic abstract class CstLiteral32\n        extends CstLiteralBits {\n    /** the value as {@code int} bits */\n    private final int bits;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param bits the value as {@code int} bits\n     */\n    /*package*/ CstLiteral32(int bits) {\n        this.bits = bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final boolean equals(Object other) {\n        return (other != null) &&\n            (getClass() == other.getClass()) &&\n            bits == ((CstLiteral32) other).bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final int hashCode() {\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int compareTo0(Constant other) {\n        int otherBits = ((CstLiteral32) other).bits;\n\n        if (bits < otherBits) {\n            return -1;\n        } else if (bits > otherBits) {\n            return 1;\n        } else {\n            return 0;\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final boolean isCategory2() {\n        return false;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final boolean fitsInInt() {\n        return true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final int getIntBits() {\n        return bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final long getLongBits() {\n        return (long) bits;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstLiteral64.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\n/**\n * Constants which are literal 64-bit values of some sort.\n */\npublic abstract class CstLiteral64\n        extends CstLiteralBits {\n    /** the value as {@code long} bits */\n    private final long bits;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param bits the value as {@code long} bits\n     */\n    /*package*/ CstLiteral64(long bits) {\n        this.bits = bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final boolean equals(Object other) {\n        return (other != null) &&\n            (getClass() == other.getClass()) &&\n            bits == ((CstLiteral64) other).bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final int hashCode() {\n        return (int) bits ^ (int) (bits >> 32);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int compareTo0(Constant other) {\n        long otherBits = ((CstLiteral64) other).bits;\n\n        if (bits < otherBits) {\n            return -1;\n        } else if (bits > otherBits) {\n            return 1;\n        } else {\n            return 0;\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final boolean isCategory2() {\n        return true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final boolean fitsInInt() {\n        return (int) bits == bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final int getIntBits() {\n        return (int) bits;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final long getLongBits() {\n        return bits;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstLiteralBits.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\n/**\n * Constants which are literal bitwise values of some sort.\n */\npublic abstract class CstLiteralBits\n        extends TypedConstant {\n    /**\n     * Returns whether or not this instance's value may be accurately\n     * represented as an {@code int}. The rule is that if there\n     * is an {@code int} which may be sign-extended to yield this\n     * instance's value, then this method returns {@code true}.\n     * Otherwise, it returns {@code false}.\n     *\n     * @return {@code true} iff this instance fits in an {@code int}\n     */\n    public abstract boolean fitsInInt();\n\n    /**\n     * Gets the value as {@code int} bits. If this instance contains\n     * more bits than fit in an {@code int}, then this returns only\n     * the low-order bits.\n     *\n     * @return the bits\n     */\n    public abstract int getIntBits();\n\n    /**\n     * Gets the value as {@code long} bits. If this instance contains\n     * fewer bits than fit in a {@code long}, then the result of this\n     * method is the sign extension of the value.\n     *\n     * @return the bits\n     */\n    public abstract long getLongBits();\n\n    /**\n     * Returns true if this value can fit in 16 bits with sign-extension.\n     *\n     * @return true if the sign-extended lower 16 bits are the same as\n     * the value.\n     */\n    public boolean fitsIn16Bits() {\n        if (! fitsInInt()) {\n            return false;\n        }\n\n        int bits = getIntBits();\n        return (short) bits == bits;\n    }\n\n    /**\n     * Returns true if this value can fit in 8 bits with sign-extension.\n     *\n     * @return true if the sign-extended lower 8 bits are the same as\n     * the value.\n     */\n    public boolean fitsIn8Bits() {\n        if (! fitsInInt()) {\n            return false;\n        }\n\n        int bits = getIntBits();\n        return (byte) bits == bits;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstLong.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Constants of type {@code CONSTANT_Long_info}.\n */\npublic final class CstLong\n        extends CstLiteral64 {\n    /** {@code non-null;} instance representing {@code 0} */\n    public static final CstLong VALUE_0 = make(0);\n\n    /** {@code non-null;} instance representing {@code 1} */\n    public static final CstLong VALUE_1 = make(1);\n\n    /**\n     * Makes an instance for the given value. This may (but does not\n     * necessarily) return an already-allocated instance.\n     *\n     * @param value the {@code long} value\n     */\n    public static CstLong make(long value) {\n        /*\n         * Note: Javadoc notwithstanding, this implementation always\n         * allocates.\n         */\n        return new CstLong(value);\n    }\n\n    /**\n     * Constructs an instance. This constructor is private; use {@link #make}.\n     *\n     * @param value the {@code long} value\n     */\n    private CstLong(long value) {\n        super(value);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        long value = getLongBits();\n        return \"long{0x\" + Hex.u8(value) + \" / \" + value + '}';\n    }\n\n    /** {@inheritDoc} */\n    public Type getType() {\n        return Type.LONG;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"long\";\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return Long.toString(getLongBits());\n    }\n\n    /**\n     * Gets the {@code long} value.\n     *\n     * @return the value\n     */\n    public long getValue() {\n        return getLongBits();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstMemberRef.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\n/**\n * Constants of type {@code CONSTANT_*ref_info}.\n */\npublic abstract class CstMemberRef extends TypedConstant {\n    /** {@code non-null;} the type of the defining class */\n    private final CstType definingClass;\n\n    /** {@code non-null;} the name-and-type */\n    private final CstNat nat;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param definingClass {@code non-null;} the type of the defining class\n     * @param nat {@code non-null;} the name-and-type\n     */\n    /*package*/ CstMemberRef(CstType definingClass, CstNat nat) {\n        if (definingClass == null) {\n            throw new NullPointerException(\"definingClass == null\");\n        }\n\n        if (nat == null) {\n            throw new NullPointerException(\"nat == null\");\n        }\n\n        this.definingClass = definingClass;\n        this.nat = nat;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final boolean equals(Object other) {\n        if ((other == null) || (getClass() != other.getClass())) {\n            return false;\n        }\n\n        CstMemberRef otherRef = (CstMemberRef) other;\n        return definingClass.equals(otherRef.definingClass) &&\n            nat.equals(otherRef.nat);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final int hashCode() {\n        return (definingClass.hashCode() * 31) ^ nat.hashCode();\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p><b>Note:</b> This implementation just compares the defining\n     * class and name, and it is up to subclasses to compare the rest\n     * after calling {@code super.compareTo0()}.</p>\n     */\n    @Override\n    protected int compareTo0(Constant other) {\n        CstMemberRef otherMember = (CstMemberRef) other;\n        int cmp = definingClass.compareTo(otherMember.definingClass);\n\n        if (cmp != 0) {\n            return cmp;\n        }\n\n        CstString thisName = nat.getName();\n        CstString otherName = otherMember.nat.getName();\n\n        return thisName.compareTo(otherName);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final String toString() {\n        return typeName() + '{' + toHuman() + '}';\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final boolean isCategory2() {\n        return false;\n    }\n\n    /** {@inheritDoc} */\n    public final String toHuman() {\n        return definingClass.toHuman() + '.' + nat.toHuman();\n    }\n\n    /**\n     * Gets the type of the defining class.\n     *\n     * @return {@code non-null;} the type of defining class\n     */\n    public final CstType getDefiningClass() {\n        return definingClass;\n    }\n\n    /**\n     * Gets the defining name-and-type.\n     *\n     * @return {@code non-null;} the name-and-type\n     */\n    public final CstNat getNat() {\n        return nat;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstMethodRef.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\n/**\n * Constants of type {@code CONSTANT_Methodref_info}.\n */\npublic final class CstMethodRef\n        extends CstBaseMethodRef {\n    /**\n     * Constructs an instance.\n     *\n     * @param definingClass {@code non-null;} the type of the defining class\n     * @param nat {@code non-null;} the name-and-type\n     */\n    public CstMethodRef(CstType definingClass, CstNat nat) {\n        super(definingClass, nat);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"method\";\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstNat.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\n\n/**\n * Constants of type {@code CONSTANT_NameAndType_info}.\n */\npublic final class CstNat extends Constant {\n    /**\n     * {@code non-null;} the instance for name {@code TYPE} and descriptor\n     * {@code java.lang.Class}, which is useful when dealing with\n     * wrapped primitives\n     */\n    public static final CstNat PRIMITIVE_TYPE_NAT =\n        new CstNat(new CstString(\"TYPE\"),\n                   new CstString(\"Ljava/lang/Class;\"));\n\n    /** {@code non-null;} the name */\n    private final CstString name;\n\n    /** {@code non-null;} the descriptor (type) */\n    private final CstString descriptor;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param name {@code non-null;} the name\n     * @param descriptor {@code non-null;} the descriptor\n     */\n    public CstNat(CstString name, CstString descriptor) {\n        if (name == null) {\n            throw new NullPointerException(\"name == null\");\n        }\n\n        if (descriptor == null) {\n            throw new NullPointerException(\"descriptor == null\");\n        }\n\n        this.name = name;\n        this.descriptor = descriptor;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (!(other instanceof CstNat)) {\n            return false;\n        }\n\n        CstNat otherNat = (CstNat) other;\n        return name.equals(otherNat.name) &&\n            descriptor.equals(otherNat.descriptor);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return (name.hashCode() * 31) ^ descriptor.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int compareTo0(Constant other) {\n        CstNat otherNat = (CstNat) other;\n        int cmp = name.compareTo(otherNat.name);\n\n        if (cmp != 0) {\n            return cmp;\n        }\n\n        return descriptor.compareTo(otherNat.descriptor);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return \"nat{\" + toHuman() + '}';\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"nat\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCategory2() {\n        return false;\n    }\n\n    /**\n     * Gets the name.\n     *\n     * @return {@code non-null;} the name\n     */\n    public CstString getName() {\n        return name;\n    }\n\n    /**\n     * Gets the descriptor.\n     *\n     * @return {@code non-null;} the descriptor\n     */\n    public CstString getDescriptor() {\n        return descriptor;\n    }\n\n    /**\n     * Returns an unadorned but human-readable version of the name-and-type\n     * value.\n     *\n     * @return {@code non-null;} the human form\n     */\n    public String toHuman() {\n        return name.toHuman() + ':' + descriptor.toHuman();\n    }\n\n    /**\n     * Gets the field type corresponding to this instance's descriptor.\n     * This method is only valid to call if the descriptor in fact describes\n     * a field (and not a method).\n     *\n     * @return {@code non-null;} the field type\n     */\n    public Type getFieldType() {\n        return Type.intern(descriptor.getString());\n    }\n\n    /**\n     * Gets whether this instance has the name of a standard instance\n     * initialization method. This is just a convenient shorthand for\n     * {@code getName().getString().equals(\"<init>\")}.\n     *\n     * @return {@code true} iff this is a reference to an\n     * instance initialization method\n     */\n    public final boolean isInstanceInit() {\n        return name.getString().equals(\"<init>\");\n    }\n\n    /**\n     * Gets whether this instance has the name of a standard class\n     * initialization method. This is just a convenient shorthand for\n     * {@code getName().getString().equals(\"<clinit>\")}.\n     *\n     * @return {@code true} iff this is a reference to an\n     * instance initialization method\n     */\n    public final boolean isClassInit() {\n        return name.getString().equals(\"<clinit>\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstShort.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Constants of type {@code short}.\n */\npublic final class CstShort\n        extends CstLiteral32 {\n    /** {@code non-null;} the value {@code 0} as an instance of this class */\n    public static final CstShort VALUE_0 = make((short) 0);\n\n    /**\n     * Makes an instance for the given value. This may (but does not\n     * necessarily) return an already-allocated instance.\n     *\n     * @param value the {@code short} value\n     * @return {@code non-null;} the appropriate instance\n     */\n    public static CstShort make(short value) {\n        return new CstShort(value);\n    }\n\n    /**\n     * Makes an instance for the given {@code int} value. This\n     * may (but does not necessarily) return an already-allocated\n     * instance.\n     *\n     * @param value the value, which must be in range for a {@code short}\n     * @return {@code non-null;} the appropriate instance\n     */\n    public static CstShort make(int value) {\n        short cast = (short) value;\n\n        if (cast != value) {\n            throw new IllegalArgumentException(\"bogus short value: \" +\n                    value);\n        }\n\n        return make(cast);\n    }\n\n    /**\n     * Constructs an instance. This constructor is private; use {@link #make}.\n     *\n     * @param value the {@code short} value\n     */\n    private CstShort(short value) {\n        super(value);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        int value = getIntBits();\n        return \"short{0x\" + Hex.u2(value) + \" / \" + value + '}';\n    }\n\n    /** {@inheritDoc} */\n    public Type getType() {\n        return Type.SHORT;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"short\";\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return Integer.toString(getIntBits());\n    }\n\n    /**\n     * Gets the {@code short} value.\n     *\n     * @return the value\n     */\n    public short getValue() {\n        return (short) getIntBits();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstString.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.ByteArray;\nimport com.taobao.android.dx.util.Hex;\n\n/**\n * Constants of type {@code CONSTANT_Utf8_info} or {@code CONSTANT_String_info}.\n */\npublic final class CstString extends TypedConstant {\n    /**\n     * {@code non-null;} instance representing {@code \"\"}, that is, the\n     * empty string\n     */\n    public static final CstString EMPTY_STRING = new CstString(\"\");\n\n    /** {@code non-null;} the UTF-8 value as a string */\n    private final String string;\n\n    /** {@code non-null;} the UTF-8 value as bytes */\n    private final ByteArray bytes;\n\n    /**\n     * Converts a string into its MUTF-8 form. MUTF-8 differs from normal UTF-8\n     * in the handling of character '\\0' and surrogate pairs.\n     *\n     * @param string {@code non-null;} the string to convert\n     * @return {@code non-null;} the UTF-8 bytes for it\n     */\n    public static byte[] stringToUtf8Bytes(String string) {\n        int len = string.length();\n        byte[] bytes = new byte[len * 3]; // Avoid having to reallocate.\n        int outAt = 0;\n\n        for (int i = 0; i < len; i++) {\n            char c = string.charAt(i);\n            if ((c != 0) && (c < 0x80)) {\n                bytes[outAt] = (byte) c;\n                outAt++;\n            } else if (c < 0x800) {\n                bytes[outAt] = (byte) (((c >> 6) & 0x1f) | 0xc0);\n                bytes[outAt + 1] = (byte) ((c & 0x3f) | 0x80);\n                outAt += 2;\n            } else {\n                bytes[outAt] = (byte) (((c >> 12) & 0x0f) | 0xe0);\n                bytes[outAt + 1] = (byte) (((c >> 6) & 0x3f) | 0x80);\n                bytes[outAt + 2] = (byte) ((c & 0x3f) | 0x80);\n                outAt += 3;\n            }\n        }\n\n        byte[] result = new byte[outAt];\n        System.arraycopy(bytes, 0, result, 0, outAt);\n        return result;\n    }\n\n    /**\n     * Converts an array of UTF-8 bytes into a string.\n     *\n     * @param bytes {@code non-null;} the bytes to convert\n     * @return {@code non-null;} the converted string\n     */\n    public static String utf8BytesToString(ByteArray bytes) {\n        int length = bytes.size();\n        char[] chars = new char[length]; // This is sized to avoid a realloc.\n        int outAt = 0;\n\n        for (int at = 0; length > 0; /*at*/) {\n            int v0 = bytes.getUnsignedByte(at);\n            char out;\n            switch (v0 >> 4) {\n                case 0x00: case 0x01: case 0x02: case 0x03:\n                case 0x04: case 0x05: case 0x06: case 0x07: {\n                    // 0XXXXXXX -- single-byte encoding\n                    length--;\n                    if (v0 == 0) {\n                        // A single zero byte is illegal.\n                        return throwBadUtf8(v0, at);\n                    }\n                    out = (char) v0;\n                    at++;\n                    break;\n                }\n                case 0x0c: case 0x0d: {\n                    // 110XXXXX -- two-byte encoding\n                    length -= 2;\n                    if (length < 0) {\n                        return throwBadUtf8(v0, at);\n                    }\n                    int v1 = bytes.getUnsignedByte(at + 1);\n                    if ((v1 & 0xc0) != 0x80) {\n                        return throwBadUtf8(v1, at + 1);\n                    }\n                    int value = ((v0 & 0x1f) << 6) | (v1 & 0x3f);\n                    if ((value != 0) && (value < 0x80)) {\n                        /*\n                         * This should have been represented with\n                         * one-byte encoding.\n                         */\n                        return throwBadUtf8(v1, at + 1);\n                    }\n                    out = (char) value;\n                    at += 2;\n                    break;\n                }\n                case 0x0e: {\n                    // 1110XXXX -- three-byte encoding\n                    length -= 3;\n                    if (length < 0) {\n                        return throwBadUtf8(v0, at);\n                    }\n                    int v1 = bytes.getUnsignedByte(at + 1);\n                    if ((v1 & 0xc0) != 0x80) {\n                        return throwBadUtf8(v1, at + 1);\n                    }\n                    int v2 = bytes.getUnsignedByte(at + 2);\n                    if ((v1 & 0xc0) != 0x80) {\n                        return throwBadUtf8(v2, at + 2);\n                    }\n                    int value = ((v0 & 0x0f) << 12) | ((v1 & 0x3f) << 6) |\n                        (v2 & 0x3f);\n                    if (value < 0x800) {\n                        /*\n                         * This should have been represented with one- or\n                         * two-byte encoding.\n                         */\n                        return throwBadUtf8(v2, at + 2);\n                    }\n                    out = (char) value;\n                    at += 3;\n                    break;\n                }\n                default: {\n                    // 10XXXXXX, 1111XXXX -- illegal\n                    return throwBadUtf8(v0, at);\n                }\n            }\n            chars[outAt] = out;\n            outAt++;\n        }\n\n        return new String(chars, 0, outAt);\n    }\n\n    /**\n     * Helper for {@link #utf8BytesToString}, which throws the right\n     * exception for a bogus utf-8 byte.\n     *\n     * @param value the byte value\n     * @param offset the file offset\n     * @return never\n     * @throws IllegalArgumentException always thrown\n     */\n    private static String throwBadUtf8(int value, int offset) {\n        throw new IllegalArgumentException(\"bad utf-8 byte \" + Hex.u1(value) +\n                                           \" at offset \" + Hex.u4(offset));\n    }\n\n    /**\n     * Constructs an instance from a {@code String}.\n     *\n     * @param string {@code non-null;} the UTF-8 value as a string\n     */\n    public CstString(String string) {\n        if (string == null) {\n            throw new NullPointerException(\"string == null\");\n        }\n\n        this.string = string.intern();\n        this.bytes = new ByteArray(stringToUtf8Bytes(string));\n    }\n\n    /**\n     * Constructs an instance from some UTF-8 bytes.\n     *\n     * @param bytes {@code non-null;} array of the UTF-8 bytes\n     */\n    public CstString(ByteArray bytes) {\n        if (bytes == null) {\n            throw new NullPointerException(\"bytes == null\");\n        }\n\n        this.bytes = bytes;\n        this.string = utf8BytesToString(bytes).intern();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (!(other instanceof CstString)) {\n            return false;\n        }\n\n        return string.equals(((CstString) other).string);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return string.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int compareTo0(Constant other) {\n        return string.compareTo(((CstString) other).string);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return \"string{\\\"\" + toHuman() + \"\\\"}\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"utf8\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCategory2() {\n        return false;\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        int len = string.length();\n        StringBuilder sb = new StringBuilder(len * 3 / 2);\n\n        for (int i = 0; i < len; i++) {\n            char c = string.charAt(i);\n            if ((c >= ' ') && (c < 0x7f)) {\n                if ((c == '\\'') || (c == '\\\"') || (c == '\\\\')) {\n                    sb.append('\\\\');\n                }\n                sb.append(c);\n            } else if (c <= 0x7f) {\n                switch (c) {\n                    case '\\n': sb.append(\"\\\\n\"); break;\n                    case '\\r': sb.append(\"\\\\r\"); break;\n                    case '\\t': sb.append(\"\\\\t\"); break;\n                    default: {\n                        /*\n                         * Represent the character as an octal escape.\n                         * If the next character is a valid octal\n                         * digit, disambiguate by using the\n                         * three-digit form.\n                         */\n                        char nextChar =\n                            (i < (len - 1)) ? string.charAt(i + 1) : 0;\n                        boolean displayZero =\n                            (nextChar >= '0') && (nextChar <= '7');\n                        sb.append('\\\\');\n                        for (int shift = 6; shift >= 0; shift -= 3) {\n                            char outChar = (char) (((c >> shift) & 7) + '0');\n                            if ((outChar != '0') || displayZero) {\n                                sb.append(outChar);\n                                displayZero = true;\n                            }\n                        }\n                        if (! displayZero) {\n                            // Ironic edge case: The original value was 0.\n                            sb.append('0');\n                        }\n                        break;\n                    }\n                }\n            } else {\n                sb.append(\"\\\\u\");\n                sb.append(Character.forDigit(c >> 12, 16));\n                sb.append(Character.forDigit((c >> 8) & 0x0f, 16));\n                sb.append(Character.forDigit((c >> 4) & 0x0f, 16));\n                sb.append(Character.forDigit(c & 0x0f, 16));\n            }\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Gets the value as a human-oriented string, surrounded by double\n     * quotes.\n     *\n     * @return {@code non-null;} the quoted string\n     */\n    public String toQuoted() {\n        return '\\\"' + toHuman() + '\\\"';\n    }\n\n    /**\n     * Gets the value as a human-oriented string, surrounded by double\n     * quotes, but ellipsizes the result if it is longer than the given\n     * maximum length\n     *\n     * @param maxLength {@code >= 5;} the maximum length of the string to return\n     * @return {@code non-null;} the quoted string\n     */\n    public String toQuoted(int maxLength) {\n        String string = toHuman();\n        int length = string.length();\n        String ellipses;\n\n        if (length <= (maxLength - 2)) {\n            ellipses = \"\";\n        } else {\n            string = string.substring(0, maxLength - 5);\n            ellipses = \"...\";\n        }\n\n        return '\\\"' + string + ellipses + '\\\"';\n    }\n\n    /**\n     * Gets the UTF-8 value as a string.\n     * The returned string is always already interned.\n     *\n     * @return {@code non-null;} the UTF-8 value as a string\n     */\n    public String getString() {\n        return string;\n    }\n\n    /**\n     * Gets the UTF-8 value as UTF-8 encoded bytes.\n     *\n     * @return {@code non-null;} an array of the UTF-8 bytes\n     */\n    public ByteArray getBytes() {\n        return bytes;\n    }\n\n    /**\n     * Gets the size of this instance as UTF-8 code points. That is,\n     * get the number of bytes in the UTF-8 encoding of this instance.\n     *\n     * @return {@code >= 0;} the UTF-8 size\n     */\n    public int getUtf8Size() {\n        return bytes.size();\n    }\n\n    /**\n     * Gets the size of this instance as UTF-16 code points. That is,\n     * get the number of 16-bit chars in the UTF-16 encoding of this\n     * instance. This is the same as the {@code length} of the\n     * Java {@code String} representation of this instance.\n     *\n     * @return {@code >= 0;} the UTF-16 size\n     */\n    public int getUtf16Size() {\n        return string.length();\n    }\n\n    public Type getType() {\n        return Type.STRING;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/CstType.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\n\nimport java.util.HashMap;\n\n/**\n * Constants that represent an arbitrary type (reference or primitive).\n */\npublic final class CstType extends TypedConstant {\n    /** {@code non-null;} map of interned types */\n    private static final HashMap<Type, CstType> interns =\n        new HashMap<Type, CstType>(100);\n\n    /** {@code non-null;} instance corresponding to the class {@code Object} */\n    public static final CstType OBJECT = intern(Type.OBJECT);\n\n    /** {@code non-null;} instance corresponding to the class {@code Boolean} */\n    public static final CstType BOOLEAN = intern(Type.BOOLEAN_CLASS);\n\n    /** {@code non-null;} instance corresponding to the class {@code Byte} */\n    public static final CstType BYTE = intern(Type.BYTE_CLASS);\n\n    /** {@code non-null;} instance corresponding to the class {@code Character} */\n    public static final CstType CHARACTER = intern(Type.CHARACTER_CLASS);\n\n    /** {@code non-null;} instance corresponding to the class {@code Double} */\n    public static final CstType DOUBLE = intern(Type.DOUBLE_CLASS);\n\n    /** {@code non-null;} instance corresponding to the class {@code Float} */\n    public static final CstType FLOAT = intern(Type.FLOAT_CLASS);\n\n    /** {@code non-null;} instance corresponding to the class {@code Long} */\n    public static final CstType LONG = intern(Type.LONG_CLASS);\n\n    /** {@code non-null;} instance corresponding to the class {@code Integer} */\n    public static final CstType INTEGER = intern(Type.INTEGER_CLASS);\n\n    /** {@code non-null;} instance corresponding to the class {@code Short} */\n    public static final CstType SHORT = intern(Type.SHORT_CLASS);\n\n    /** {@code non-null;} instance corresponding to the class {@code Void} */\n    public static final CstType VOID = intern(Type.VOID_CLASS);\n\n    /** {@code non-null;} instance corresponding to the type {@code boolean[]} */\n    public static final CstType BOOLEAN_ARRAY = intern(Type.BOOLEAN_ARRAY);\n\n    /** {@code non-null;} instance corresponding to the type {@code byte[]} */\n    public static final CstType BYTE_ARRAY = intern(Type.BYTE_ARRAY);\n\n    /** {@code non-null;} instance corresponding to the type {@code char[]} */\n    public static final CstType CHAR_ARRAY = intern(Type.CHAR_ARRAY);\n\n    /** {@code non-null;} instance corresponding to the type {@code double[]} */\n    public static final CstType DOUBLE_ARRAY = intern(Type.DOUBLE_ARRAY);\n\n    /** {@code non-null;} instance corresponding to the type {@code float[]} */\n    public static final CstType FLOAT_ARRAY = intern(Type.FLOAT_ARRAY);\n\n    /** {@code non-null;} instance corresponding to the type {@code long[]} */\n    public static final CstType LONG_ARRAY = intern(Type.LONG_ARRAY);\n\n    /** {@code non-null;} instance corresponding to the type {@code int[]} */\n    public static final CstType INT_ARRAY = intern(Type.INT_ARRAY);\n\n    /** {@code non-null;} instance corresponding to the type {@code short[]} */\n    public static final CstType SHORT_ARRAY = intern(Type.SHORT_ARRAY);\n\n    /** {@code non-null;} the underlying type */\n    private final Type type;\n\n    /**\n     * {@code null-ok;} the type descriptor corresponding to this instance, if\n     * calculated\n     */\n    private CstString descriptor;\n\n    /**\n     * Returns an instance of this class that represents the wrapper\n     * class corresponding to a given primitive type. For example, if\n     * given {@link Type#INT}, this method returns the class reference\n     * {@code java.lang.Integer}.\n     *\n     * @param primitiveType {@code non-null;} the primitive type\n     * @return {@code non-null;} the corresponding wrapper class\n     */\n    public static CstType forBoxedPrimitiveType(Type primitiveType) {\n        switch (primitiveType.getBasicType()) {\n            case Type.BT_BOOLEAN: return BOOLEAN;\n            case Type.BT_BYTE:    return BYTE;\n            case Type.BT_CHAR:    return CHARACTER;\n            case Type.BT_DOUBLE:  return DOUBLE;\n            case Type.BT_FLOAT:   return FLOAT;\n            case Type.BT_INT:     return INTEGER;\n            case Type.BT_LONG:    return LONG;\n            case Type.BT_SHORT:   return SHORT;\n            case Type.BT_VOID:    return VOID;\n        }\n\n        throw new IllegalArgumentException(\"not primitive: \" + primitiveType);\n    }\n\n    /**\n     * Returns an interned instance of this class for the given type.\n     *\n     * @param type {@code non-null;} the underlying type\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static CstType intern(Type type) {\n        synchronized (interns) {\n            CstType cst = interns.get(type);\n\n            if (cst == null) {\n                cst = new CstType(type);\n                interns.put(type, cst);\n            }\n\n            return cst;\n        }\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param type {@code non-null;} the underlying type\n     */\n    public CstType(Type type) {\n        if (type == null) {\n            throw new NullPointerException(\"type == null\");\n        }\n\n        if (type == Type.KNOWN_NULL) {\n            throw new UnsupportedOperationException(\n                    \"KNOWN_NULL is not representable\");\n        }\n\n        this.type = type;\n        this.descriptor = null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (!(other instanceof CstType)) {\n            return false;\n        }\n\n        return type == ((CstType) other).type;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return type.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    protected int compareTo0(Constant other) {\n        String thisDescriptor = type.getDescriptor();\n        String otherDescriptor = ((CstType) other).type.getDescriptor();\n        return thisDescriptor.compareTo(otherDescriptor);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return \"type{\" + toHuman() + '}';\n    }\n\n    /** {@inheritDoc} */\n    public Type getType() {\n        return Type.CLASS;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String typeName() {\n        return \"type\";\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isCategory2() {\n        return false;\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return type.toHuman();\n    }\n\n    /**\n     * Gets the underlying type (as opposed to the type corresponding\n     * to this instance as a constant, which is always\n     * {@code Class}).\n     *\n     * @return {@code non-null;} the type corresponding to the name\n     */\n    public Type getClassType() {\n        return type;\n    }\n\n    /**\n     * Gets the type descriptor for this instance.\n     *\n     * @return {@code non-null;} the descriptor\n     */\n    public CstString getDescriptor() {\n        if (descriptor == null) {\n            descriptor = new CstString(type.getDescriptor());\n        }\n\n        return descriptor;\n    }\n\n    /**\n     * Returns a human readable package name for this type, like \"java.util\".\n     * If this is an array type, this returns the package name of the array's\n     * component type. If this is a primitive type, this returns \"default\".\n     */\n    public String getPackageName() {\n        // descriptor is a string like \"[[Ljava/util/String;\"\n        String descriptor = getDescriptor().getString();\n        int lastSlash = descriptor.lastIndexOf('/');\n        int lastLeftSquare = descriptor.lastIndexOf('['); // -1 unless this is an array\n        if (lastSlash == -1) {\n            return \"default\";\n        } else {\n            // +2 to skip the '[' and the 'L' prefix\n            return descriptor.substring(lastLeftSquare + 2, lastSlash).replace('/', '.');\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/StdConstantPool.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.MutabilityControl;\n\n/**\n * Standard implementation of {@link ConstantPool}, which directly stores\n * an array of {@link Constant} objects and can be made immutable.\n */\npublic final class StdConstantPool\n        extends MutabilityControl implements ConstantPool {\n    /** {@code non-null;} array of entries */\n    private final Constant[] entries;\n\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size the size of the pool; this corresponds to the\n     * class file field {@code constant_pool_count}, and is in fact\n     * always at least one more than the actual size of the constant pool,\n     * as element {@code 0} is always invalid.\n     */\n    public StdConstantPool(int size) {\n        super(size > 1);\n\n        if (size < 1) {\n            throw new IllegalArgumentException(\"size < 1\");\n        }\n\n        entries = new Constant[size];\n    }\n\n    /** {@inheritDoc} */\n    public int size() {\n        return entries.length;\n    }\n\n    /** {@inheritDoc} */\n    public Constant getOrNull(int n) {\n        try {\n            return entries[n];\n        } catch (IndexOutOfBoundsException ex) {\n            // Translate the exception.\n            return throwInvalid(n);\n        }\n    }\n\n    /** {@inheritDoc} */\n    public Constant get0Ok(int n) {\n        if (n == 0) {\n            return null;\n        }\n\n        return get(n);\n    }\n\n    /** {@inheritDoc} */\n    public Constant get(int n) {\n        try {\n            Constant result = entries[n];\n\n            if (result == null) {\n                throwInvalid(n);\n            }\n\n            return result;\n        } catch (IndexOutOfBoundsException ex) {\n            // Translate the exception.\n            return throwInvalid(n);\n        }\n    }\n\n    /**\n     * Get all entries in this constant pool.\n     *\n     * @return the returned array may contain null entries.\n     */\n    public Constant[] getEntries() {\n        return entries;\n    }\n\n    /**\n     * Sets the entry at the given index.\n     *\n     * @param n {@code >= 1, < size();} which entry\n     * @param cst {@code null-ok;} the constant to store\n     */\n    public void set(int n, Constant cst) {\n        throwIfImmutable();\n\n        boolean cat2 = (cst != null) && cst.isCategory2();\n\n        if (n < 1) {\n            throw new IllegalArgumentException(\"n < 1\");\n        }\n\n        if (cat2) {\n            // Storing a category-2 entry nulls out the next index.\n            if (n == (entries.length - 1)) {\n                throw new IllegalArgumentException(\"(n == size - 1) && \" +\n                                                   \"cst.isCategory2()\");\n            }\n            entries[n + 1] = null;\n        }\n\n        if ((cst != null) && (entries[n] == null)) {\n            /*\n             * Overwriting the second half of a category-2 entry nulls out\n             * the first half.\n             */\n            Constant prev = entries[n - 1];\n            if ((prev != null) && prev.isCategory2()) {\n                entries[n - 1] = null;\n            }\n        }\n\n        entries[n] = cst;\n    }\n\n    /**\n     * Throws the right exception for an invalid cpi.\n     *\n     * @param idx the bad cpi\n     * @return never\n     * @throws ExceptionWithContext always thrown\n     */\n    private static Constant throwInvalid(int idx) {\n        throw new ExceptionWithContext(\"invalid constant pool index \" +\n                                       Hex.u2(idx));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/TypedConstant.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.TypeBearer;\n\n/**\n * Base class for constants which implement {@link TypeBearer}.\n */\npublic abstract class TypedConstant\n        extends Constant implements TypeBearer {\n    /**\n     * {@inheritDoc}\n     *\n     * This implementation always returns {@code this}.\n     */\n    public final TypeBearer getFrameType() {\n        return this;\n    }\n\n    /** {@inheritDoc} */\n    public final int getBasicType() {\n        return getType().getBasicType();\n    }\n\n    /** {@inheritDoc} */\n    public final int getBasicFrameType() {\n        return getType().getBasicFrameType();\n    }\n\n    /** {@inheritDoc} */\n    public final boolean isConstant() {\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/Zeroes.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.cst;\n\nimport com.taobao.android.dx.rop.type.Type;\n\n/**\n * Utility for turning types into zeroes.\n */\npublic final class Zeroes {\n    /**\n     * This class is uninstantiable.\n     */\n    private Zeroes() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Gets the \"zero\" (or {@code null}) value for the given type.\n     *\n     * @param type {@code non-null;} the type in question\n     * @return {@code non-null;} its \"zero\" value\n     */\n    public static Constant zeroFor(Type type) {\n        switch (type.getBasicType()) {\n            case Type.BT_BOOLEAN: return CstBoolean.VALUE_FALSE;\n            case Type.BT_BYTE:    return CstByte.VALUE_0;\n            case Type.BT_CHAR:    return CstChar.VALUE_0;\n            case Type.BT_DOUBLE:  return CstDouble.VALUE_0;\n            case Type.BT_FLOAT:   return CstFloat.VALUE_0;\n            case Type.BT_INT:     return CstInteger.VALUE_0;\n            case Type.BT_LONG:    return CstLong.VALUE_0;\n            case Type.BT_SHORT:   return CstShort.VALUE_0;\n            case Type.BT_OBJECT:  return CstKnownNull.THE_ONE;\n            default: {\n                throw new UnsupportedOperationException(\"no zero for type: \" +\n                        type.toHuman());\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/cst/package.html",
    "content": "<body>\n<p>Interfaces and implementation of things related to the constant pool.</p>\n\n<p><b>PACKAGES USED:</b>\n<ul>\n<li><code>com.taobao.android.dx.rop.type</code></li>\n<li><code>com.taobao.android.dx.util</code></li>\n</ul>\n</body>\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/package-info.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop;\n\n/**\n * <h1>An Introduction to Rop Form</h1>\n *\n * This package contains classes associated with dx's {@code Rop}\n * intermediate form.<p>\n *\n * The Rop form is intended to represent the instructions and the control-flow\n * graph in a reasonably programmatically useful form while closely mirroring\n * the dex instruction set.<p>\n *\n * <h2>Key Classes</h2>\n *\n * <ul>\n * <li> {@link RopMethod}, the representation of an individual method\n * <li> {@link BasicBlock} and its per-method container, {@link BasicBlockList},\n * the representation of control flow elements.\n * <li> {@link Insn} and its subclasses along with its per-basic block\n * container {@link InsnList}. {@code Insn} instances represent\n * individual instructions in the abstract register machine.\n * <li> {@link RegisterSpec} and its container {@link RegisterSpecList}. A\n * register spec encodes register number, register width, type information,\n * and potentially local variable information as well for instruction sources\n * and results.\n * <li> {@link Rop} instances represent opcodes in the abstract machine. Many\n * {@code Rop} instances are singletons defined in static fields in\n * {@link Rops}. The rest are constructed dynamically using static methods\n * in {@code Rops}\n * <li> {@link RegOps} lists numeric constants for the opcodes\n * <li> {@link Constant} and its subclasses represent constant data values\n * that opcodes may refer to.\n * <li> {@link Type} instances represent the core data types that can be\n * handled by the abstract machine.\n * <li> The {@link TypeBearer} interface is implemented by classes that\n * represent a core data type, but may also have secondary information\n * (such as constant value) associated with them.\n * <ul>\n *\n * <h2>Control-Flow Graph</h2>\n *\n * Each method is separated into a list of basic blocks. For the most part,\n * basic blocks are referred to by a positive integer\n * {@link BasicBlock#getLabel label}, which is always unique per method. The\n * label value is typically derived from a bytecode address from the source\n * bytecode. Blocks that don't originate directly from source bytecode have\n * labels generated for them in a mostly arbitrary order.<p>\n *\n * Blocks are referred to by their label, for the most part, because\n * {@code BasicBlock} instances are immutable and thus any modification to\n * the control flow graph or the instruction list results in replacement\n * instances (with identical labels) being created.<p>\n *\n * A method has a single {@link RopMethod#getFirstLabel entry block} and 0\n * to N {@link RopMethod#getExitPredecessors exit predecessor blocks} which\n * will return. All blocks that are not the entry block will have at least\n * one predecessor (or are unreachable and should be removed from the block\n * list). All blocks that are not exit predecessors must have at least one\n * successor.<p>\n *\n * Since all blocks must branch, all blocks must have, as their final\n * instruction, an instruction whose opcode has a {@link Rop#getBranchingness\n * branchingness} other than {@link Rop.BRANCH_NONE}. Furthermore, branching\n * instructions may only be the final instruction in any basic block. If\n * no other terminating opcode is appropriate, use a {@link Rops#GOTO GOTO}.<p>\n *\n * Typically a block will have a {@link BasicBlock#getPrimarySuccessor\n * primary successor} which distinguishes a particular control flow path.\n * For {Rops#isCallLike}call or call-like} opcodes, this is the path taken\n * in the non-exceptional case, where all other successors represent\n * various exception paths. For comparison operators such as\n * {@link Rops#IF_EQZ_INT}, the primary successor represents the path taken\n * if the <b>condition evaluates to false</b>. For {@link SwitchInsn switch\n * instructions}, the primary successor is the default case.<p>\n *\n * A basic block's successor list is ordered and may refer to unique labels\n * multiple times. For example, if a switch statement contains multiple case\n * statements for the same code path, a single basic block will likely\n * appear in the successor list multiple times. In general, the\n * significance of the successor list's order (like the significance of\n * the primary successor) is a property of the final instruction of the basic\n * block. A basic block containing a {@link ThrowingInsn}, for example, has\n * its successor list in an order identical to the\n * {@link ThrowingInsn#getCatches} instruction's catches list, with the\n * primary successor (the no-exception case) listed at the end.\n *\n * It is legal for a basic block to have no primary successor. An obvious\n * example of this is a block that terminates in a {@link Rops#THROW throw}\n * instruction where a catch block exists inside the current method for that\n * exception class. Since the only possible path is the exception path, only\n * the exception path (which cannot be a primary successor) is a successor.\n * An example of this is shown in {@code dx/tests/092-ssa-cfg-edge-cases}.\n *\n * <h2>Rop Instructions</h2>\n *\n * <h3>move-result and move-result-pseudo</h3>\n *\n * An instruction that may throw an exception may not specify a result. This\n * is necessary because the result register will not be assigned to if an\n * exception occurs while processing said instruction and a result assignment\n * may not occur. Since result assignments only occur in the non-exceptional\n * case,  the result assignments for throwing instructions can be said to occur\n * at the beginning of the primary successor block rather than at the end of\n * the current block. The Rop form represents the result assignments this way.\n * Throwing instructions may not directly specify results. Instead, result\n * assignments are represented by {@link\n * Rops#MOVE_RESULT move-result} or {@link Rops#MOVE_RESULT_PSEUDO\n * move-result-pseudo} instructions at the top of the primary successor block.\n *\n * Only a single {@code move-result} or {@code move-result-pseudo}\n * may exist in any block and it must be exactly the first instruction in the\n * block.\n *\n * A {@code move-result} instruction is used for the results of call-like\n * instructions. If the value produced by a {@code move-result} is not\n * used by the method, it may be eliminated as dead code.\n *\n * A {@code move-result-pseudo} instruction is used for the results of\n * non-call-like throwing instructions. It may never be considered dead code\n * since the final dex instruction will always indicate a result register.\n * If a required {@code move-result-pseudo} instruction is not found\n * during conversion to dex bytecode, an exception will be thrown.\n *\n * <h3>move-exception</h3>\n *\n * A {@link RegOps.MOVE_EXCEPTION move-exception} instruction may appear at\n * the start of a catch block, and represents the obtaining of the thrown\n * exception instance. It may only occur as the first instruction in a\n * basic block, and any basic block in which it occurs must be reachable only\n * as an exception successor.\n *\n * <h3>move-param</h3>\n *\n * A {@link RegOps.MOVE_PARAM move-param} instruction represents a method\n * parameter. Every {@code move-param} instruction is a\n * {@link PlainCstInsn}. The index of the method parameter they refer to is\n * carried as the {@link CstInteger integer constant} associated with the\n * instruction.\n *\n * Any number of {@code move-param} instructions referring to the same\n * parameter index may be included in a method's instruction lists. They\n * have no restrictions on placement beyond those of any other\n * {@link Rop.BRANCH_NONE} instruction. Note that the SSA optimizer arranges the\n * parameter assignments to align with the dex bytecode calling conventions.\n * With parameter assignments so arranged, the\n * {@link com.taobao.android.dx.dex.code.RopTranslator} sees Rop {@code move-param}\n * instructions as unnecessary in dex form and eliminates them.\n *\n * <h3>mark-local</h3>\n *\n * A {@link RegOps.MARK_LOCAL mark-local} instruction indicates that a local\n * variable becomes live in a specified register specified register for the\n * purposes of debug information. A {@code mark-local} instruction has\n * a single source (the register which will now be considered a local variable)\n * and no results. The instruction has no side effect.<p>\n *\n * In a typical case, a local variable's lifetime begins with an\n * assignment. The local variable whose information is present in a result's\n * {@link RegisterSpec#getLocalItem LocalItem} is considered to begin (or move\n * between registers) when the instruction is executed.<p>\n *\n * However, sometimes a local variable can begin its life or move without\n * an assignment occurring. A common example of this is occurs in the Rop\n * representation of the following code:<p>\n *\n * <pre>\n * try {\n *     Object foo = null;\n *     foo = new Object();\n * } catch (Throwable ex) { }\n * </pre>\n *\n * An object's initialization occurs in two steps. First, a\n * {@code new-instance} instruction is executed, whose result is stored in a\n * register. However, that register can not yet be considered to contain\n * \"foo\". That's because the instance's constructor method must be called\n * via an {@code invoke} instruction. The constructor method, however, may\n * throw an exception. And if an exception occurs, then \"foo\" should remain\n * null. So \"foo\" becomes the value of the result of the {@code new-instance}\n * instruction after the (void) constructor method is invoked and\n * returns successfully. In such a case, a {@code mark-local} will\n * typically occur at the beginning of the primary successor block following\n * the invocation to the constructor.\n */\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/type/Prototype.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.type;\n\nimport java.util.HashMap;\n\n/**\n * Representation of a method descriptor. Instances of this class are\n * generally interned and may be usefully compared with each other\n * using {@code ==}.\n */\npublic final class Prototype implements Comparable<Prototype> {\n    /** {@code non-null;} intern table mapping string descriptors to instances */\n    private static final HashMap<String, Prototype> internTable =\n        new HashMap<String, Prototype>(500);\n\n    /** {@code non-null;} method descriptor */\n    private final String descriptor;\n\n    /** {@code non-null;} return type */\n    private final Type returnType;\n\n    /** {@code non-null;} list of parameter types */\n    private final StdTypeList parameterTypes;\n\n    /** {@code null-ok;} list of parameter frame types, if calculated */\n    private StdTypeList parameterFrameTypes;\n\n    /**\n     * Returns the unique instance corresponding to the\n     * given method descriptor. See vmspec-2 sec4.3.3 for details on the\n     * field descriptor syntax.\n     *\n     * @param descriptor {@code non-null;} the descriptor\n     * @return {@code non-null;} the corresponding instance\n     * @throws IllegalArgumentException thrown if the descriptor has\n     * invalid syntax\n     */\n    public static Prototype intern(String descriptor) {\n        if (descriptor == null) {\n            throw new NullPointerException(\"descriptor == null\");\n        }\n\n        Prototype result;\n        synchronized (internTable) {\n            result = internTable.get(descriptor);\n        }\n        if (result != null) {\n            return result;\n        }\n\n        Type[] params = makeParameterArray(descriptor);\n        int paramCount = 0;\n        int at = 1;\n\n        for (;;) {\n            int startAt = at;\n            char c = descriptor.charAt(at);\n            if (c == ')') {\n                at++;\n                break;\n            }\n\n            // Skip array markers.\n            while (c == '[') {\n                at++;\n                c = descriptor.charAt(at);\n            }\n\n            if (c == 'L') {\n                // It looks like the start of a class name; find the end.\n                int endAt = descriptor.indexOf(';', at);\n                if (endAt == -1) {\n                    throw new IllegalArgumentException(\"bad descriptor\");\n                }\n                at = endAt + 1;\n            } else {\n                at++;\n            }\n\n            params[paramCount] =\n                Type.intern(descriptor.substring(startAt, at));\n            paramCount++;\n        }\n\n        Type returnType = Type.internReturnType(descriptor.substring(at));\n        StdTypeList parameterTypes = new StdTypeList(paramCount);\n\n        for (int i = 0; i < paramCount; i++) {\n            parameterTypes.set(i, params[i]);\n        }\n\n        result = new Prototype(descriptor, returnType, parameterTypes);\n        return putIntern(result);\n    }\n\n    /**\n     * Helper for {@link #intern} which returns an empty array to\n     * populate with parsed parameter types, and which also ensures\n     * that there is a '(' at the start of the descriptor and a\n     * single ')' somewhere before the end.\n     *\n     * @param descriptor {@code non-null;} the descriptor string\n     * @return {@code non-null;} array large enough to hold all parsed parameter\n     * types, but which is likely actually larger than needed\n     */\n    private static Type[] makeParameterArray(String descriptor) {\n        int length = descriptor.length();\n\n        if (descriptor.charAt(0) != '(') {\n            throw new IllegalArgumentException(\"bad descriptor\");\n        }\n\n        /*\n         * This is a cheesy way to establish an upper bound on the\n         * number of parameters: Just count capital letters.\n         */\n        int closeAt = 0;\n        int maxParams = 0;\n        for (int i = 1; i < length; i++) {\n            char c = descriptor.charAt(i);\n            if (c == ')') {\n                closeAt = i;\n                break;\n            }\n            if ((c >= 'A') && (c <= 'Z')) {\n                maxParams++;\n            }\n        }\n\n        if ((closeAt == 0) || (closeAt == (length - 1))) {\n            throw new IllegalArgumentException(\"bad descriptor\");\n        }\n\n        if (descriptor.indexOf(')', closeAt + 1) != -1) {\n            throw new IllegalArgumentException(\"bad descriptor\");\n        }\n\n        return new Type[maxParams];\n    }\n\n    /**\n     * Interns an instance, adding to the descriptor as necessary based\n     * on the given definer, name, and flags. For example, an init\n     * method has an uninitialized object of type {@code definer}\n     * as its first argument.\n     *\n     * @param descriptor {@code non-null;} the descriptor string\n     * @param definer {@code non-null;} class the method is defined on\n     * @param isStatic whether this is a static method\n     * @param isInit whether this is an init method\n     * @return {@code non-null;} the interned instance\n     */\n    public static Prototype intern(String descriptor, Type definer,\n            boolean isStatic, boolean isInit) {\n        Prototype base = intern(descriptor);\n\n        if (isStatic) {\n            return base;\n        }\n\n        if (isInit) {\n            definer = definer.asUninitialized(Integer.MAX_VALUE);\n        }\n\n        return base.withFirstParameter(definer);\n    }\n\n    /**\n     * Interns an instance which consists of the given number of\n     * {@code int}s along with the given return type\n     *\n     * @param returnType {@code non-null;} the return type\n     * @param count {@code > 0;} the number of elements in the prototype\n     * @return {@code non-null;} the interned instance\n     */\n    public static Prototype internInts(Type returnType, int count) {\n        // Make the descriptor...\n\n        StringBuffer sb = new StringBuffer(100);\n\n        sb.append('(');\n\n        for (int i = 0; i < count; i++) {\n            sb.append('I');\n        }\n\n        sb.append(')');\n        sb.append(returnType.getDescriptor());\n\n        // ...and intern it.\n        return intern(sb.toString());\n    }\n\n    /**\n     * Constructs an instance. This is a private constructor; use one\n     * of the public static methods to get instances.\n     *\n     * @param descriptor {@code non-null;} the descriptor string\n     */\n    private Prototype(String descriptor, Type returnType,\n            StdTypeList parameterTypes) {\n        if (descriptor == null) {\n            throw new NullPointerException(\"descriptor == null\");\n        }\n\n        if (returnType == null) {\n            throw new NullPointerException(\"returnType == null\");\n        }\n\n        if (parameterTypes == null) {\n            throw new NullPointerException(\"parameterTypes == null\");\n        }\n\n        this.descriptor = descriptor;\n        this.returnType = returnType;\n        this.parameterTypes = parameterTypes;\n        this.parameterFrameTypes = null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (this == other) {\n            /*\n             * Since externally-visible instances are interned, this\n             * check helps weed out some easy cases.\n             */\n            return true;\n        }\n\n        if (!(other instanceof Prototype)) {\n            return false;\n        }\n\n        return descriptor.equals(((Prototype) other).descriptor);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return descriptor.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    public int compareTo(Prototype other) {\n        if (this == other) {\n            return 0;\n        }\n\n        /*\n         * The return type is the major order, and then args in order,\n         * and then the shorter list comes first (similar to string\n         * sorting).\n         */\n\n        int result = returnType.compareTo(other.returnType);\n\n        if (result != 0) {\n            return result;\n        }\n\n        int thisSize = parameterTypes.size();\n        int otherSize = other.parameterTypes.size();\n        int size = Math.min(thisSize, otherSize);\n\n        for (int i = 0; i < size; i++) {\n            Type thisType = parameterTypes.get(i);\n            Type otherType = other.parameterTypes.get(i);\n\n            result = thisType.compareTo(otherType);\n\n            if (result != 0) {\n                return result;\n            }\n        }\n\n        if (thisSize < otherSize) {\n            return -1;\n        } else if (thisSize > otherSize) {\n            return 1;\n        } else {\n            return 0;\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return descriptor;\n    }\n\n    /**\n     * Gets the descriptor string.\n     *\n     * @return {@code non-null;} the descriptor\n     */\n    public String getDescriptor() {\n        return descriptor;\n    }\n\n    /**\n     * Gets the return type.\n     *\n     * @return {@code non-null;} the return type\n     */\n    public Type getReturnType() {\n        return returnType;\n    }\n\n    /**\n     * Gets the list of parameter types.\n     *\n     * @return {@code non-null;} the list of parameter types\n     */\n    public StdTypeList getParameterTypes() {\n        return parameterTypes;\n    }\n\n    /**\n     * Gets the list of frame types corresponding to the list of parameter\n     * types. The difference between the two lists (if any) is that all\n     * \"intlike\" types (see {@link Type#isIntlike}) are replaced by\n     * {@link Type#INT}.\n     *\n     * @return {@code non-null;} the list of parameter frame types\n     */\n    public StdTypeList getParameterFrameTypes() {\n        if (parameterFrameTypes == null) {\n            int sz = parameterTypes.size();\n            StdTypeList list = new StdTypeList(sz);\n            boolean any = false;\n            for (int i = 0; i < sz; i++) {\n                Type one = parameterTypes.get(i);\n                if (one.isIntlike()) {\n                    any = true;\n                    one = Type.INT;\n                }\n                list.set(i, one);\n            }\n            parameterFrameTypes = any ? list : parameterTypes;\n        }\n\n        return parameterFrameTypes;\n    }\n\n    /**\n     * Returns a new interned instance, which is the same as this instance,\n     * except that it has an additional parameter prepended to the original's\n     * argument list.\n     *\n     * @param param {@code non-null;} the new first parameter\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public Prototype withFirstParameter(Type param) {\n        String newDesc = \"(\" + param.getDescriptor() + descriptor.substring(1);\n        StdTypeList newParams = parameterTypes.withFirst(param);\n\n        newParams.setImmutable();\n\n        Prototype result =\n            new Prototype(newDesc, returnType, newParams);\n\n        return putIntern(result);\n    }\n\n    /**\n     * Puts the given instance in the intern table if it's not already\n     * there. If a conflicting value is already in the table, then leave it.\n     * Return the interned value.\n     *\n     * @param desc {@code non-null;} instance to make interned\n     * @return {@code non-null;} the actual interned object\n     */\n    private static Prototype putIntern(Prototype desc) {\n        synchronized (internTable) {\n            String descriptor = desc.getDescriptor();\n            Prototype already = internTable.get(descriptor);\n            if (already != null) {\n                return already;\n            }\n            internTable.put(descriptor, desc);\n            return desc;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/type/StdTypeList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.type;\n\nimport com.taobao.android.dx.util.FixedSizeList;\n\n/**\n * Standard implementation of {@link TypeList}.\n */\npublic final class StdTypeList\n        extends FixedSizeList implements TypeList {\n    /** {@code non-null;} no-element instance */\n    public static final StdTypeList EMPTY = new StdTypeList(0);\n\n    /** {@code non-null;} the list {@code [int]} */\n    public static final StdTypeList INT = StdTypeList.make(Type.INT);\n\n    /** {@code non-null;} the list {@code [long]} */\n    public static final StdTypeList LONG = StdTypeList.make(Type.LONG);\n\n    /** {@code non-null;} the list {@code [float]} */\n    public static final StdTypeList FLOAT = StdTypeList.make(Type.FLOAT);\n\n    /** {@code non-null;} the list {@code [double]} */\n    public static final StdTypeList DOUBLE = StdTypeList.make(Type.DOUBLE);\n\n    /** {@code non-null;} the list {@code [Object]} */\n    public static final StdTypeList OBJECT = StdTypeList.make(Type.OBJECT);\n\n    /** {@code non-null;} the list {@code [ReturnAddress]} */\n    public static final StdTypeList RETURN_ADDRESS\n            = StdTypeList.make(Type.RETURN_ADDRESS);\n\n    /** {@code non-null;} the list {@code [Throwable]} */\n    public static final StdTypeList THROWABLE =\n        StdTypeList.make(Type.THROWABLE);\n\n    /** {@code non-null;} the list {@code [int, int]} */\n    public static final StdTypeList INT_INT =\n        StdTypeList.make(Type.INT, Type.INT);\n\n    /** {@code non-null;} the list {@code [long, long]} */\n    public static final StdTypeList LONG_LONG =\n        StdTypeList.make(Type.LONG, Type.LONG);\n\n    /** {@code non-null;} the list {@code [float, float]} */\n    public static final StdTypeList FLOAT_FLOAT =\n        StdTypeList.make(Type.FLOAT, Type.FLOAT);\n\n    /** {@code non-null;} the list {@code [double, double]} */\n    public static final StdTypeList DOUBLE_DOUBLE =\n        StdTypeList.make(Type.DOUBLE, Type.DOUBLE);\n\n    /** {@code non-null;} the list {@code [Object, Object]} */\n    public static final StdTypeList OBJECT_OBJECT =\n        StdTypeList.make(Type.OBJECT, Type.OBJECT);\n\n    /** {@code non-null;} the list {@code [int, Object]} */\n    public static final StdTypeList INT_OBJECT =\n        StdTypeList.make(Type.INT, Type.OBJECT);\n\n    /** {@code non-null;} the list {@code [long, Object]} */\n    public static final StdTypeList LONG_OBJECT =\n        StdTypeList.make(Type.LONG, Type.OBJECT);\n\n    /** {@code non-null;} the list {@code [float, Object]} */\n    public static final StdTypeList FLOAT_OBJECT =\n        StdTypeList.make(Type.FLOAT, Type.OBJECT);\n\n    /** {@code non-null;} the list {@code [double, Object]} */\n    public static final StdTypeList DOUBLE_OBJECT =\n        StdTypeList.make(Type.DOUBLE, Type.OBJECT);\n\n    /** {@code non-null;} the list {@code [long, int]} */\n    public static final StdTypeList LONG_INT =\n        StdTypeList.make(Type.LONG, Type.INT);\n\n    /** {@code non-null;} the list {@code [int[], int]} */\n    public static final StdTypeList INTARR_INT =\n        StdTypeList.make(Type.INT_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [long[], int]} */\n    public static final StdTypeList LONGARR_INT =\n        StdTypeList.make(Type.LONG_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [float[], int]} */\n    public static final StdTypeList FLOATARR_INT =\n        StdTypeList.make(Type.FLOAT_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [double[], int]} */\n    public static final StdTypeList DOUBLEARR_INT =\n        StdTypeList.make(Type.DOUBLE_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [Object[], int]} */\n    public static final StdTypeList OBJECTARR_INT =\n        StdTypeList.make(Type.OBJECT_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [boolean[], int]} */\n    public static final StdTypeList BOOLEANARR_INT =\n        StdTypeList.make(Type.BOOLEAN_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [byte[], int]} */\n    public static final StdTypeList BYTEARR_INT =\n        StdTypeList.make(Type.BYTE_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [char[], int]} */\n    public static final StdTypeList CHARARR_INT =\n        StdTypeList.make(Type.CHAR_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [short[], int]} */\n    public static final StdTypeList SHORTARR_INT =\n        StdTypeList.make(Type.SHORT_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [int, int[], int]} */\n    public static final StdTypeList INT_INTARR_INT =\n        StdTypeList.make(Type.INT, Type.INT_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [long, long[], int]} */\n    public static final StdTypeList LONG_LONGARR_INT =\n        StdTypeList.make(Type.LONG, Type.LONG_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [float, float[], int]} */\n    public static final StdTypeList FLOAT_FLOATARR_INT =\n        StdTypeList.make(Type.FLOAT, Type.FLOAT_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [double, double[], int]} */\n    public static final StdTypeList DOUBLE_DOUBLEARR_INT =\n        StdTypeList.make(Type.DOUBLE, Type.DOUBLE_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [Object, Object[], int]} */\n    public static final StdTypeList OBJECT_OBJECTARR_INT =\n        StdTypeList.make(Type.OBJECT, Type.OBJECT_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [int, boolean[], int]} */\n    public static final StdTypeList INT_BOOLEANARR_INT =\n        StdTypeList.make(Type.INT, Type.BOOLEAN_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [int, byte[], int]} */\n    public static final StdTypeList INT_BYTEARR_INT =\n        StdTypeList.make(Type.INT, Type.BYTE_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [int, char[], int]} */\n    public static final StdTypeList INT_CHARARR_INT =\n        StdTypeList.make(Type.INT, Type.CHAR_ARRAY, Type.INT);\n\n    /** {@code non-null;} the list {@code [int, short[], int]} */\n    public static final StdTypeList INT_SHORTARR_INT =\n        StdTypeList.make(Type.INT, Type.SHORT_ARRAY, Type.INT);\n\n    /**\n     * Makes a single-element instance.\n     *\n     * @param type {@code non-null;} the element\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static StdTypeList make(Type type) {\n        StdTypeList result = new StdTypeList(1);\n        result.set(0, type);\n        return result;\n    }\n\n    /**\n     * Makes a two-element instance.\n     *\n     * @param type0 {@code non-null;} the first element\n     * @param type1 {@code non-null;} the second element\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static StdTypeList make(Type type0, Type type1) {\n        StdTypeList result = new StdTypeList(2);\n        result.set(0, type0);\n        result.set(1, type1);\n        return result;\n    }\n\n    /**\n     * Makes a three-element instance.\n     *\n     * @param type0 {@code non-null;} the first element\n     * @param type1 {@code non-null;} the second element\n     * @param type2 {@code non-null;} the third element\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static StdTypeList make(Type type0, Type type1, Type type2) {\n        StdTypeList result = new StdTypeList(3);\n        result.set(0, type0);\n        result.set(1, type1);\n        result.set(2, type2);\n        return result;\n    }\n\n    /**\n     * Makes a four-element instance.\n     *\n     * @param type0 {@code non-null;} the first element\n     * @param type1 {@code non-null;} the second element\n     * @param type2 {@code non-null;} the third element\n     * @param type3 {@code non-null;} the fourth element\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static StdTypeList make(Type type0, Type type1, Type type2,\n                                   Type type3) {\n        StdTypeList result = new StdTypeList(4);\n        result.set(0, type0);\n        result.set(1, type1);\n        result.set(2, type2);\n        result.set(3, type3);\n        return result;\n    }\n\n    /**\n     * Returns the given list as a comma-separated list of human forms. This\n     * is a static method so as to work on arbitrary {@link TypeList}\n     * instances.\n     *\n     * @param list {@code non-null;} the list to convert\n     * @return {@code non-null;} the human form\n     */\n    public static String toHuman(TypeList list) {\n        int size = list.size();\n\n        if (size == 0) {\n            return \"<empty>\";\n        }\n\n        StringBuffer sb = new StringBuffer(100);\n\n        for (int i = 0; i < size; i++) {\n            if (i != 0) {\n                sb.append(\", \");\n            }\n            sb.append(list.getType(i).toHuman());\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * Returns a hashcode of the contents of the given list. This\n     * is a static method so as to work on arbitrary {@link TypeList}\n     * instances.\n     *\n     * @param list {@code non-null;} the list to inspect\n     * @return {@code non-null;} the hash code\n     */\n    public static int hashContents(TypeList list) {\n        int size = list.size();\n        int hash = 0;\n\n        for (int i = 0; i < size; i++) {\n            hash = (hash * 31) + list.getType(i).hashCode();\n        }\n\n        return hash;\n    }\n\n    /**\n     * Compares the contents of the given two instances for equality. This\n     * is a static method so as to work on arbitrary {@link TypeList}\n     * instances.\n     *\n     * @param list1 {@code non-null;} one list to compare\n     * @param list2 {@code non-null;} another list to compare\n     * @return whether the two lists contain corresponding equal elements\n     */\n    public static boolean equalContents(TypeList list1, TypeList list2) {\n        int size = list1.size();\n\n        if (list2.size() != size) {\n            return false;\n        }\n\n        for (int i = 0; i < size; i++) {\n            if (! list1.getType(i).equals(list2.getType(i))) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Compares the contents of the given two instances for ordering. This\n     * is a static method so as to work on arbitrary {@link TypeList}\n     * instances.\n     *\n     * @param list1 {@code non-null;} one list to compare\n     * @param list2 {@code non-null;} another list to compare\n     * @return the order of the two lists\n     */\n    public static int compareContents(TypeList list1, TypeList list2) {\n        int size1 = list1.size();\n        int size2 = list2.size();\n        int size = Math.min(size1, size2);\n\n        for (int i = 0; i < size; i++) {\n            int comparison = list1.getType(i).compareTo(list2.getType(i));\n            if (comparison != 0) {\n                return comparison;\n            }\n        }\n\n        if (size1 == size2) {\n            return 0;\n        } else if (size1 < size2) {\n            return -1;\n        } else {\n            return 1;\n        }\n    }\n\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size the size of the list\n     */\n    public StdTypeList(int size) {\n        super(size);\n    }\n\n    /** {@inheritDoc} */\n    public Type getType(int n) {\n        return get(n);\n    }\n\n    /** {@inheritDoc} */\n    public int getWordCount() {\n        int sz = size();\n        int result = 0;\n\n        for (int i = 0; i < sz; i++) {\n            result += get(i).getCategory();\n        }\n\n        return result;\n    }\n\n    /** {@inheritDoc} */\n    public TypeList withAddedType(Type type) {\n        int sz = size();\n        StdTypeList result = new StdTypeList(sz + 1);\n\n        for (int i = 0; i < sz; i++) {\n            result.set0(i, get0(i));\n        }\n\n        result.set(sz, type);\n        result.setImmutable();\n        return result;\n    }\n\n    /**\n     * Gets the indicated element. It is an error to call this with the\n     * index for an element which was never set; if you do that, this\n     * will throw {@code NullPointerException}.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @return {@code non-null;} the indicated element\n     */\n    public Type get(int n) {\n        return (Type) get0(n);\n    }\n\n    /**\n     * Sets the type at the given index.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @param type {@code non-null;} the type to store\n     */\n    public void set(int n, Type type) {\n        set0(n, type);\n    }\n\n    /**\n     * Returns a new instance, which is the same as this instance,\n     * except that it has an additional type prepended to the\n     * original.\n     *\n     * @param type {@code non-null;} the new first element\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public StdTypeList withFirst(Type type) {\n        int sz = size();\n        StdTypeList result = new StdTypeList(sz + 1);\n\n        result.set0(0, type);\n        for (int i = 0; i < sz; i++) {\n            result.set0(i + 1, getOrNull0(i));\n        }\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/type/Type.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.type;\n\nimport com.taobao.android.dx.util.Hex;\nimport java.util.HashMap;\n\n/**\n * Representation of a value type, such as may appear in a field, in a\n * local, on a stack, or in a method descriptor. Instances of this\n * class are generally interned and may be usefully compared with each\n * other using {@code ==}.\n */\npublic final class Type implements TypeBearer, Comparable<Type> {\n    /**\n     * {@code non-null;} intern table mapping string descriptors to\n     * instances\n     */\n    private static final HashMap<String, Type> internTable =\n        new HashMap<String, Type>(500);\n\n    /** basic type constant for {@code void} */\n    public static final int BT_VOID = 0;\n\n    /** basic type constant for {@code boolean} */\n    public static final int BT_BOOLEAN = 1;\n\n    /** basic type constant for {@code byte} */\n    public static final int BT_BYTE = 2;\n\n    /** basic type constant for {@code char} */\n    public static final int BT_CHAR = 3;\n\n    /** basic type constant for {@code double} */\n    public static final int BT_DOUBLE = 4;\n\n    /** basic type constant for {@code float} */\n    public static final int BT_FLOAT = 5;\n\n    /** basic type constant for {@code int} */\n    public static final int BT_INT = 6;\n\n    /** basic type constant for {@code long} */\n    public static final int BT_LONG = 7;\n\n    /** basic type constant for {@code short} */\n    public static final int BT_SHORT = 8;\n\n    /** basic type constant for {@code Object} */\n    public static final int BT_OBJECT = 9;\n\n    /** basic type constant for a return address */\n    public static final int BT_ADDR = 10;\n\n    /** count of basic type constants */\n    public static final int BT_COUNT = 11;\n\n    /** {@code non-null;} instance representing {@code boolean} */\n    public static final Type BOOLEAN = new Type(\"Z\", BT_BOOLEAN);\n\n    /** {@code non-null;} instance representing {@code byte} */\n    public static final Type BYTE = new Type(\"B\", BT_BYTE);\n\n    /** {@code non-null;} instance representing {@code char} */\n    public static final Type CHAR = new Type(\"C\", BT_CHAR);\n\n    /** {@code non-null;} instance representing {@code double} */\n    public static final Type DOUBLE = new Type(\"D\", BT_DOUBLE);\n\n    /** {@code non-null;} instance representing {@code float} */\n    public static final Type FLOAT = new Type(\"F\", BT_FLOAT);\n\n    /** {@code non-null;} instance representing {@code int} */\n    public static final Type INT = new Type(\"I\", BT_INT);\n\n    /** {@code non-null;} instance representing {@code long} */\n    public static final Type LONG = new Type(\"J\", BT_LONG);\n\n    /** {@code non-null;} instance representing {@code short} */\n    public static final Type SHORT = new Type(\"S\", BT_SHORT);\n\n    /** {@code non-null;} instance representing {@code void} */\n    public static final Type VOID = new Type(\"V\", BT_VOID);\n\n    /** {@code non-null;} instance representing a known-{@code null} */\n    public static final Type KNOWN_NULL = new Type(\"<null>\", BT_OBJECT);\n\n    /** {@code non-null;} instance representing a subroutine return address */\n    public static final Type RETURN_ADDRESS = new Type(\"<addr>\", BT_ADDR);\n\n    static {\n        /*\n         * Put all the primitive types into the intern table. This needs\n         * to happen before the array types below get interned.\n         */\n        putIntern(BOOLEAN);\n        putIntern(BYTE);\n        putIntern(CHAR);\n        putIntern(DOUBLE);\n        putIntern(FLOAT);\n        putIntern(INT);\n        putIntern(LONG);\n        putIntern(SHORT);\n        /*\n         * Note: VOID isn't put in the intern table, since it's special and\n         * shouldn't be found by a normal call to intern().\n         */\n    }\n\n    /**\n     * {@code non-null;} instance representing\n     * {@code java.lang.annotation.Annotation}\n     */\n    public static final Type ANNOTATION =\n        intern(\"Ljava/lang/annotation/Annotation;\");\n\n    /** {@code non-null;} instance representing {@code java.lang.Class} */\n    public static final Type CLASS = intern(\"Ljava/lang/Class;\");\n\n    /** {@code non-null;} instance representing {@code java.lang.Cloneable} */\n    public static final Type CLONEABLE = intern(\"Ljava/lang/Cloneable;\");\n\n    /** {@code non-null;} instance representing {@code java.lang.Object} */\n    public static final Type OBJECT = intern(\"Ljava/lang/Object;\");\n\n    /** {@code non-null;} instance representing {@code java.io.Serializable} */\n    public static final Type SERIALIZABLE = intern(\"Ljava/io/Serializable;\");\n\n    /** {@code non-null;} instance representing {@code java.lang.String} */\n    public static final Type STRING = intern(\"Ljava/lang/String;\");\n\n    /** {@code non-null;} instance representing {@code java.lang.Throwable} */\n    public static final Type THROWABLE = intern(\"Ljava/lang/Throwable;\");\n\n    /**\n     * {@code non-null;} instance representing {@code java.lang.Boolean}; the\n     * suffix on the name helps disambiguate this from the instance\n     * representing a primitive type\n     */\n    public static final Type BOOLEAN_CLASS = intern(\"Ljava/lang/Boolean;\");\n\n    /**\n     * {@code non-null;} instance representing {@code java.lang.Byte}; the\n     * suffix on the name helps disambiguate this from the instance\n     * representing a primitive type\n     */\n    public static final Type BYTE_CLASS = intern(\"Ljava/lang/Byte;\");\n\n    /**\n     * {@code non-null;} instance representing {@code java.lang.Character}; the\n     * suffix on the name helps disambiguate this from the instance\n     * representing a primitive type\n     */\n    public static final Type CHARACTER_CLASS = intern(\"Ljava/lang/Character;\");\n\n    /**\n     * {@code non-null;} instance representing {@code java.lang.Double}; the\n     * suffix on the name helps disambiguate this from the instance\n     * representing a primitive type\n     */\n    public static final Type DOUBLE_CLASS = intern(\"Ljava/lang/Double;\");\n\n    /**\n     * {@code non-null;} instance representing {@code java.lang.Float}; the\n     * suffix on the name helps disambiguate this from the instance\n     * representing a primitive type\n     */\n    public static final Type FLOAT_CLASS = intern(\"Ljava/lang/Float;\");\n\n    /**\n     * {@code non-null;} instance representing {@code java.lang.Integer}; the\n     * suffix on the name helps disambiguate this from the instance\n     * representing a primitive type\n     */\n    public static final Type INTEGER_CLASS = intern(\"Ljava/lang/Integer;\");\n\n    /**\n     * {@code non-null;} instance representing {@code java.lang.Long}; the\n     * suffix on the name helps disambiguate this from the instance\n     * representing a primitive type\n     */\n    public static final Type LONG_CLASS = intern(\"Ljava/lang/Long;\");\n\n    /**\n     * {@code non-null;} instance representing {@code java.lang.Short}; the\n     * suffix on the name helps disambiguate this from the instance\n     * representing a primitive type\n     */\n    public static final Type SHORT_CLASS = intern(\"Ljava/lang/Short;\");\n\n    /**\n     * {@code non-null;} instance representing {@code java.lang.Void}; the\n     * suffix on the name helps disambiguate this from the instance\n     * representing a primitive type\n     */\n    public static final Type VOID_CLASS = intern(\"Ljava/lang/Void;\");\n\n    /** {@code non-null;} instance representing {@code boolean[]} */\n    public static final Type BOOLEAN_ARRAY = BOOLEAN.getArrayType();\n\n    /** {@code non-null;} instance representing {@code byte[]} */\n    public static final Type BYTE_ARRAY = BYTE.getArrayType();\n\n    /** {@code non-null;} instance representing {@code char[]} */\n    public static final Type CHAR_ARRAY = CHAR.getArrayType();\n\n    /** {@code non-null;} instance representing {@code double[]} */\n    public static final Type DOUBLE_ARRAY = DOUBLE.getArrayType();\n\n    /** {@code non-null;} instance representing {@code float[]} */\n    public static final Type FLOAT_ARRAY = FLOAT.getArrayType();\n\n    /** {@code non-null;} instance representing {@code int[]} */\n    public static final Type INT_ARRAY = INT.getArrayType();\n\n    /** {@code non-null;} instance representing {@code long[]} */\n    public static final Type LONG_ARRAY = LONG.getArrayType();\n\n    /** {@code non-null;} instance representing {@code Object[]} */\n    public static final Type OBJECT_ARRAY = OBJECT.getArrayType();\n\n    /** {@code non-null;} instance representing {@code short[]} */\n    public static final Type SHORT_ARRAY = SHORT.getArrayType();\n\n    /** {@code non-null;} field descriptor for the type */\n    private final String descriptor;\n\n    /**\n     * basic type corresponding to this type; one of the\n     * {@code BT_*} constants\n     */\n    private final int basicType;\n\n    /**\n     * {@code >= -1;} for an uninitialized type, bytecode index that this\n     * instance was allocated at; {@code Integer.MAX_VALUE} if it\n     * was an incoming uninitialized instance; {@code -1} if this\n     * is an <i>inititialized</i> instance\n     */\n    private final int newAt;\n\n    /**\n     * {@code null-ok;} the internal-form class name corresponding to\n     * this type, if calculated; only valid if {@code this} is a\n     * reference type and additionally not a return address\n     */\n    private String className;\n\n    /**\n     * {@code null-ok;} the type corresponding to an array of this type, if\n     * calculated\n     */\n    private Type arrayType;\n\n    /**\n     * {@code null-ok;} the type corresponding to elements of this type, if\n     * calculated; only valid if {@code this} is an array type\n     */\n    private Type componentType;\n\n    /**\n     * {@code null-ok;} the type corresponding to the initialized version of\n     * this type, if this instance is in fact an uninitialized type\n     */\n    private Type initializedType;\n\n    /**\n     * Returns the unique instance corresponding to the type with the\n     * given descriptor. See vmspec-2 sec4.3.2 for details on the\n     * field descriptor syntax. This method does <i>not</i> allow\n     * {@code \"V\"} (that is, type {@code void}) as a valid\n     * descriptor.\n     *\n     * @param descriptor {@code non-null;} the descriptor\n     * @return {@code non-null;} the corresponding instance\n     * @throws IllegalArgumentException thrown if the descriptor has\n     * invalid syntax\n     */\n    public static Type intern(String descriptor) {\n        Type result;\n        synchronized (internTable) {\n            result = internTable.get(descriptor);\n        }\n        if (result != null) {\n            return result;\n        }\n\n        char firstChar;\n        try {\n            firstChar = descriptor.charAt(0);\n        } catch (IndexOutOfBoundsException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"descriptor is empty\");\n        } catch (NullPointerException ex) {\n            // Elucidate the exception.\n            throw new NullPointerException(\"descriptor == null\");\n        }\n\n        if (firstChar == '[') {\n            /*\n             * Recursively strip away array markers to get at the underlying\n             * type, and build back on to form the result.\n             */\n            result = intern(descriptor.substring(1));\n            return result.getArrayType();\n        }\n\n        /*\n         * If the first character isn't '[' and it wasn't found in the\n         * intern cache, then it had better be the descriptor for a class.\n         */\n\n        int length = descriptor.length();\n        if ((firstChar != 'L') ||\n            (descriptor.charAt(length - 1) != ';')) {\n            throw new IllegalArgumentException(\"bad descriptor: \" + descriptor);\n        }\n\n        /*\n         * Validate the characters of the class name itself. Note that\n         * vmspec-2 does not have a coherent definition for valid\n         * internal-form class names, and the definition here is fairly\n         * liberal: A name is considered valid as long as it doesn't\n         * contain any of '[' ';' '.' '(' ')', and it has no more than one\n         * '/' in a row, and no '/' at either end.\n         */\n\n        int limit = (length - 1); // Skip the final ';'.\n        for (int i = 1; i < limit; i++) {\n            char c = descriptor.charAt(i);\n            switch (c) {\n                case '[':\n                case ';':\n                case '.':\n                case '(':\n                case ')': {\n                    throw new IllegalArgumentException(\"bad descriptor: \" + descriptor);\n                }\n                case '/': {\n                    if ((i == 1) ||\n                        (i == (length - 1)) ||\n                        (descriptor.charAt(i - 1) == '/')) {\n                        throw new IllegalArgumentException(\"bad descriptor: \" + descriptor);\n                    }\n                    break;\n                }\n            }\n        }\n\n        result = new Type(descriptor, BT_OBJECT);\n        return putIntern(result);\n    }\n\n    /**\n     * Returns the unique instance corresponding to the type with the\n     * given descriptor, allowing {@code \"V\"} to return the type\n     * for {@code void}. Other than that one caveat, this method\n     * is identical to {@link #intern}.\n     *\n     * @param descriptor {@code non-null;} the descriptor\n     * @return {@code non-null;} the corresponding instance\n     * @throws IllegalArgumentException thrown if the descriptor has\n     * invalid syntax\n     */\n    public static Type internReturnType(String descriptor) {\n        try {\n            if (descriptor.equals(\"V\")) {\n                // This is the one special case where void may be returned.\n                return VOID;\n            }\n        } catch (NullPointerException ex) {\n            // Elucidate the exception.\n            throw new NullPointerException(\"descriptor == null\");\n        }\n\n        return intern(descriptor);\n    }\n\n    /**\n     * Returns the unique instance corresponding to the type of the\n     * class with the given name. Calling this method is equivalent to\n     * calling {@code intern(name)} if {@code name} begins\n     * with {@code \"[\"} and calling {@code intern(\"L\" + name + \";\")}\n     * in all other cases.\n     *\n     * @param name {@code non-null;} the name of the class whose type\n     * is desired\n     * @return {@code non-null;} the corresponding type\n     * @throws IllegalArgumentException thrown if the name has\n     * invalid syntax\n     */\n    public static Type internClassName(String name) {\n        if (name == null) {\n            throw new NullPointerException(\"name == null\");\n        }\n\n        if (name.startsWith(\"[\")) {\n            return intern(name);\n        }\n\n        return intern('L' + name + ';');\n    }\n\n    /**\n     * Constructs an instance corresponding to an \"uninitialized type.\"\n     * This is a private constructor; use one of the public static\n     * methods to get instances.\n     *\n     * @param descriptor {@code non-null;} the field descriptor for the type\n     * @param basicType basic type corresponding to this type; one of the\n     * {@code BT_*} constants\n     * @param newAt {@code >= -1;} allocation bytecode index\n     */\n    private Type(String descriptor, int basicType, int newAt) {\n        if (descriptor == null) {\n            throw new NullPointerException(\"descriptor == null\");\n        }\n\n        if ((basicType < 0) || (basicType >= BT_COUNT)) {\n            throw new IllegalArgumentException(\"bad basicType\");\n        }\n\n        if (newAt < -1) {\n            throw new IllegalArgumentException(\"newAt < -1\");\n        }\n\n        this.descriptor = descriptor;\n        this.basicType = basicType;\n        this.newAt = newAt;\n        this.arrayType = null;\n        this.componentType = null;\n        this.initializedType = null;\n    }\n\n    /**\n     * Constructs an instance corresponding to an \"initialized type.\"\n     * This is a private constructor; use one of the public static\n     * methods to get instances.\n     *\n     * @param descriptor {@code non-null;} the field descriptor for the type\n     * @param basicType basic type corresponding to this type; one of the\n     * {@code BT_*} constants\n     */\n    private Type(String descriptor, int basicType) {\n        this(descriptor, basicType, -1);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (this == other) {\n            /*\n             * Since externally-visible types are interned, this check\n             * helps weed out some easy cases.\n             */\n            return true;\n        }\n\n        if (!(other instanceof Type)) {\n            return false;\n        }\n\n        return descriptor.equals(((Type) other).descriptor);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return descriptor.hashCode();\n    }\n\n    /** {@inheritDoc} */\n    public int compareTo(Type other) {\n        return descriptor.compareTo(other.descriptor);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return descriptor;\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        switch (basicType) {\n            case BT_VOID:    return \"void\";\n            case BT_BOOLEAN: return \"boolean\";\n            case BT_BYTE:    return \"byte\";\n            case BT_CHAR:    return \"char\";\n            case BT_DOUBLE:  return \"double\";\n            case BT_FLOAT:   return \"float\";\n            case BT_INT:     return \"int\";\n            case BT_LONG:    return \"long\";\n            case BT_SHORT:   return \"short\";\n            case BT_OBJECT:  break;\n            default:         return descriptor;\n        }\n\n        if (isArray()) {\n            return getComponentType().toHuman() + \"[]\";\n        }\n\n        // Remove the \"L...;\" around the type and convert \"/\" to \".\".\n        return getClassName().replace(\"/\", \".\");\n    }\n\n    /** {@inheritDoc} */\n    public Type getType() {\n        return this;\n    }\n\n    /** {@inheritDoc} */\n    public Type getFrameType() {\n        switch (basicType) {\n            case BT_BOOLEAN:\n            case BT_BYTE:\n            case BT_CHAR:\n            case BT_INT:\n            case BT_SHORT: {\n                return INT;\n            }\n        }\n\n        return this;\n    }\n\n    /** {@inheritDoc} */\n    public int getBasicType() {\n        return basicType;\n    }\n\n    /** {@inheritDoc} */\n    public int getBasicFrameType() {\n        switch (basicType) {\n            case BT_BOOLEAN:\n            case BT_BYTE:\n            case BT_CHAR:\n            case BT_INT:\n            case BT_SHORT: {\n                return BT_INT;\n            }\n        }\n\n        return basicType;\n    }\n\n    /** {@inheritDoc} */\n    public boolean isConstant() {\n        return false;\n    }\n\n    /**\n     * Gets the descriptor.\n     *\n     * @return {@code non-null;} the descriptor\n     */\n    public String getDescriptor() {\n        return descriptor;\n    }\n\n    /**\n     * Gets the name of the class this type corresponds to, in internal\n     * form. This method is only valid if this instance is for a\n     * normal reference type (that is, a reference type and\n     * additionally not a return address).\n     *\n     * @return {@code non-null;} the internal-form class name\n     */\n    public String getClassName() {\n        if (className == null) {\n            if (!isReference()) {\n                throw new IllegalArgumentException(\"not an object type: \" +\n                                                   descriptor);\n            }\n\n            if (descriptor.charAt(0) == '[') {\n                className = descriptor;\n            } else {\n                className = descriptor.substring(1, descriptor.length() - 1);\n            }\n        }\n\n        return className;\n    }\n\n    /**\n     * Gets the category. Most instances are category 1. {@code long}\n     * and {@code double} are the only category 2 types.\n     *\n     * @see #isCategory1\n     * @see #isCategory2\n     * @return the category\n     */\n    public int getCategory() {\n        switch (basicType) {\n            case BT_LONG:\n            case BT_DOUBLE: {\n                return 2;\n            }\n        }\n\n        return 1;\n    }\n\n    /**\n     * Returns whether or not this is a category 1 type.\n     *\n     * @see #getCategory\n     * @see #isCategory2\n     * @return whether or not this is a category 1 type\n     */\n    public boolean isCategory1() {\n        switch (basicType) {\n            case BT_LONG:\n            case BT_DOUBLE: {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Returns whether or not this is a category 2 type.\n     *\n     * @see #getCategory\n     * @see #isCategory1\n     * @return whether or not this is a category 2 type\n     */\n    public boolean isCategory2() {\n        switch (basicType) {\n            case BT_LONG:\n            case BT_DOUBLE: {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Gets whether this type is \"intlike.\" An intlike type is one which, when\n     * placed on a stack or in a local, is automatically converted to an\n     * {@code int}.\n     *\n     * @return whether this type is \"intlike\"\n     */\n    public boolean isIntlike() {\n        switch (basicType) {\n            case BT_BOOLEAN:\n            case BT_BYTE:\n            case BT_CHAR:\n            case BT_INT:\n            case BT_SHORT: {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Gets whether this type is a primitive type. All types are either\n     * primitive or reference types.\n     *\n     * @return whether this type is primitive\n     */\n    public boolean isPrimitive() {\n        switch (basicType) {\n            case BT_BOOLEAN:\n            case BT_BYTE:\n            case BT_CHAR:\n            case BT_DOUBLE:\n            case BT_FLOAT:\n            case BT_INT:\n            case BT_LONG:\n            case BT_SHORT:\n            case BT_VOID: {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Gets whether this type is a normal reference type. A normal\n     * reference type is a reference type that is not a return\n     * address. This method is just convenient shorthand for\n     * {@code getBasicType() == Type.BT_OBJECT}.\n     *\n     * @return whether this type is a normal reference type\n     */\n    public boolean isReference() {\n        return (basicType == BT_OBJECT);\n    }\n\n    /**\n     * Gets whether this type is an array type. If this method returns\n     * {@code true}, then it is safe to use {@link #getComponentType}\n     * to determine the component type.\n     *\n     * @return whether this type is an array type\n     */\n    public boolean isArray() {\n        return (descriptor.charAt(0) == '[');\n    }\n\n    /**\n     * Gets whether this type is an array type or is a known-null, and\n     * hence is compatible with array types.\n     *\n     * @return whether this type is an array type\n     */\n    public boolean isArrayOrKnownNull() {\n        return isArray() || equals(KNOWN_NULL);\n    }\n\n    /**\n     * Gets whether this type represents an uninitialized instance. An\n     * uninitialized instance is what one gets back from the {@code new}\n     * opcode, and remains uninitialized until a valid constructor is\n     * invoked on it.\n     *\n     * @return whether this type is \"uninitialized\"\n     */\n    public boolean isUninitialized() {\n        return (newAt >= 0);\n    }\n\n    /**\n     * Gets the bytecode index at which this uninitialized type was\n     * allocated.  This returns {@code Integer.MAX_VALUE} if this\n     * type is an uninitialized incoming parameter (i.e., the\n     * {@code this} of an {@code <init>} method) or\n     * {@code -1} if this type is in fact <i>initialized</i>.\n     *\n     * @return {@code >= -1;} the allocation bytecode index\n     */\n    public int getNewAt() {\n        return newAt;\n    }\n\n    /**\n     * Gets the initialized type corresponding to this instance, but only\n     * if this instance is in fact an uninitialized object type.\n     *\n     * @return {@code non-null;} the initialized type\n     */\n    public Type getInitializedType() {\n        if (initializedType == null) {\n            throw new IllegalArgumentException(\"initialized type: \" +\n                                               descriptor);\n        }\n\n        return initializedType;\n    }\n\n    /**\n     * Gets the type corresponding to an array of this type.\n     *\n     * @return {@code non-null;} the array type\n     */\n    public Type getArrayType() {\n        if (arrayType == null) {\n            arrayType = putIntern(new Type('[' + descriptor, BT_OBJECT));\n        }\n\n        return arrayType;\n    }\n\n    /**\n     * Gets the component type of this type. This method is only valid on\n     * array types.\n     *\n     * @return {@code non-null;} the component type\n     */\n    public Type getComponentType() {\n        if (componentType == null) {\n            if (descriptor.charAt(0) != '[') {\n                throw new IllegalArgumentException(\"not an array type: \" +\n                                                   descriptor);\n            }\n            componentType = intern(descriptor.substring(1));\n        }\n\n        return componentType;\n    }\n\n    /**\n     * Returns a new interned instance which is identical to this one, except\n     * it is indicated as uninitialized and allocated at the given bytecode\n     * index. This instance must be an initialized object type.\n     *\n     * @param newAt {@code >= 0;} the allocation bytecode index\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public Type asUninitialized(int newAt) {\n        if (newAt < 0) {\n            throw new IllegalArgumentException(\"newAt < 0\");\n        }\n\n        if (!isReference()) {\n            throw new IllegalArgumentException(\"not a reference type: \" +\n                                               descriptor);\n        }\n\n        if (isUninitialized()) {\n            /*\n             * Dealing with uninitialized types as a starting point is\n             * a pain, and it's not clear that it'd ever be used, so\n             * just disallow it.\n             */\n            throw new IllegalArgumentException(\"already uninitialized: \" +\n                                               descriptor);\n        }\n\n        /*\n         * Create a new descriptor that is unique and shouldn't conflict\n         * with \"normal\" type descriptors\n         */\n        String newDesc = 'N' + Hex.u2(newAt) + descriptor;\n        Type result = new Type(newDesc, BT_OBJECT, newAt);\n        result.initializedType = this;\n        return putIntern(result);\n    }\n\n    /**\n     * Puts the given instance in the intern table if it's not already\n     * there. If a conflicting value is already in the table, then leave it.\n     * Return the interned value.\n     *\n     * @param type {@code non-null;} instance to make interned\n     * @return {@code non-null;} the actual interned object\n     */\n    private static Type putIntern(Type type) {\n        synchronized (internTable) {\n            String descriptor = type.getDescriptor();\n            Type already = internTable.get(descriptor);\n            if (already != null) {\n                return already;\n            }\n            internTable.put(descriptor, type);\n            return type;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/type/TypeBearer.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.type;\n\nimport com.taobao.android.dx.util.ToHuman;\n\n/**\n * Object which has an associated type, possibly itself.\n */\npublic interface TypeBearer\n        extends ToHuman {\n    /**\n     * Gets the type associated with this instance.\n     *\n     * @return {@code non-null;} the type\n     */\n    public Type getType();\n\n    /**\n     * Gets the frame type corresponding to this type. This method returns\n     * {@code this}, except if {@link Type#isIntlike} on the underlying\n     * type returns {@code true} but the underlying type is not in\n     * fact {@link Type#INT}, in which case this method returns an instance\n     * whose underlying type <i>is</i> {@code INT}.\n     *\n     * @return {@code non-null;} the frame type for this instance\n     */\n    public TypeBearer getFrameType();\n\n    /**\n     * Gets the basic type corresponding to this instance.\n     *\n     * @return the basic type; one of the {@code BT_*} constants\n     * defined by {@link Type}\n     */\n    public int getBasicType();\n\n    /**\n     * Gets the basic type corresponding to this instance's frame type. This\n     * is equivalent to {@code getFrameType().getBasicType()}, and\n     * is the same as calling {@code getFrameType()} unless this\n     * instance is an int-like type, in which case this method returns\n     * {@code BT_INT}.\n     *\n     * @see #getBasicType\n     * @see #getFrameType\n     *\n     * @return the basic frame type; one of the {@code BT_*} constants\n     * defined by {@link Type}\n     */\n    public int getBasicFrameType();\n\n    /**\n     * Returns whether this instance represents a constant value.\n     *\n     * @return {@code true} if this instance represents a constant value\n     * and {@code false} if not\n     */\n    public boolean isConstant();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/type/TypeList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.rop.type;\n\n/**\n * List of {@link Type} instances (or of things that contain types).\n */\npublic interface TypeList {\n    /**\n     * Returns whether this instance is mutable. Note that the\n     * {@code TypeList} interface itself doesn't provide any\n     * means of mutation, but that doesn't mean that there isn't an\n     * extra-interface way of mutating an instance.\n     *\n     * @return {@code true} if this instance is mutable or\n     * {@code false} if it is immutable\n     */\n    public boolean isMutable();\n\n    /**\n     * Gets the size of this list.\n     *\n     * @return {@code >= 0;} the size\n     */\n    public int size();\n\n    /**\n     * Gets the indicated element. It is an error to call this with the\n     * index for an element which was never set; if you do that, this\n     * will throw {@code NullPointerException}.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @return {@code non-null;} the indicated element\n     */\n    public Type getType(int n);\n\n    /**\n     * Gets the number of 32-bit words required to hold instances of\n     * all the elements of this list. This is a sum of the widths (categories)\n     * of all the elements.\n     *\n     * @return {@code >= 0;} the required number of words\n     */\n    public int getWordCount();\n\n    /**\n     * Returns a new instance which is identical to this one, except that\n     * the given item is appended to the end and it is guaranteed to be\n     * immutable.\n     *\n     * @param type {@code non-null;} item to append\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public TypeList withAddedType(Type type);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/rop/type/package.html",
    "content": "<body>\n<p>Implementation of classes that represent types (classes or primitives).</p>\n\n<p><b>PACKAGES USED:</b>\n<ul>\n<li><code>com.taobao.android.dx.util</code></li>\n</ul>\n</body>\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/BasicRegisterMapper.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.util.IntList;\n\n/**\n * This class maps one register space into another, with\n * each mapping built up individually and added via addMapping()\n */\npublic class BasicRegisterMapper extends RegisterMapper {\n    /** indexed by old register, containing new name */\n    private IntList oldToNew;\n\n    /** running count of used registers in new namespace */\n    private int runningCountNewRegisters;\n\n    /**\n     * Creates a new OneToOneRegisterMapper.\n     *\n     * @param countOldRegisters the number of registers in the old name space\n     */\n    public BasicRegisterMapper(int countOldRegisters) {\n        oldToNew = new IntList(countOldRegisters);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int getNewRegisterCount() {\n        return runningCountNewRegisters;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public RegisterSpec map(RegisterSpec registerSpec) {\n        if (registerSpec == null) {\n            return null;\n        }\n\n        int newReg;\n        try {\n            newReg = oldToNew.get(registerSpec.getReg());\n        } catch (IndexOutOfBoundsException ex) {\n            newReg = -1;\n        }\n\n        if (newReg < 0) {\n            throw new RuntimeException(\"no mapping specified for register\");\n        }\n\n        return registerSpec.withReg(newReg);\n    }\n\n    /**\n     * Returns the new-namespace mapping for the specified\n     * old-namespace register, or -1 if one exists.\n     *\n     * @param oldReg {@code >= 0;} old-namespace register\n     * @return new-namespace register or -1 if none\n     */\n    public int oldToNew(int oldReg) {\n        if (oldReg >= oldToNew.size()) {\n            return -1;\n        }\n\n        return oldToNew.get(oldReg);\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        StringBuilder sb = new StringBuilder();\n\n        sb.append(\"Old\\tNew\\n\");\n        int sz = oldToNew.size();\n\n        for (int i = 0; i < sz; i++) {\n            sb.append(i);\n            sb.append('\\t');\n            sb.append(oldToNew.get(i));\n            sb.append('\\n');\n        }\n\n        sb.append(\"new reg count:\");\n\n        sb.append(runningCountNewRegisters);\n        sb.append('\\n');\n\n        return sb.toString();\n    }\n\n    /**\n     * Adds a mapping to the mapper. If oldReg has already been mapped,\n     * overwrites previous mapping with new mapping.\n     *\n     * @param oldReg {@code >= 0;} old register\n     * @param newReg {@code >= 0;} new register\n     * @param category {@code 1..2;} width of reg\n     */\n    public void addMapping(int oldReg, int newReg, int category) {\n        if (oldReg >= oldToNew.size()) {\n            // expand the array as necessary\n            for (int i = oldReg - oldToNew.size(); i >= 0; i--) {\n                oldToNew.add(-1);\n            }\n        }\n\n        oldToNew.set(oldReg, newReg);\n\n        if (runningCountNewRegisters < (newReg + category)) {\n            runningCountNewRegisters = newReg + category;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/ConstCollector.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.LocalItem;\nimport com.taobao.android.dx.rop.code.PlainCstInsn;\nimport com.taobao.android.dx.rop.code.PlainInsn;\nimport com.taobao.android.dx.rop.code.RegOps;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rop;\nimport com.taobao.android.dx.rop.code.Rops;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.rop.code.ThrowingCstInsn;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.TypedConstant;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\n\n/**\n * Collects constants that are used more than once at the top of the\n * method block. This increases register usage by about 5% but decreases\n * insn size by about 3%.\n */\npublic class ConstCollector {\n    /** Maximum constants to collect per method. Puts cap on reg use */\n    private static final int MAX_COLLECTED_CONSTANTS = 5;\n\n    /**\n     * Also collect string consts, although they can throw exceptions.\n     * This is off now because it just doesn't seem to gain a whole lot.\n     * TODO if you turn this on, you must change SsaInsn.hasSideEffect()\n     * to return false for const-string insns whose exceptions are not\n     * caught in the current method.\n     */\n    private static boolean COLLECT_STRINGS = false;\n\n    /**\n     * If true, allow one local var to be involved with a collected const.\n     * Turned off because it mostly just inserts more moves.\n     */\n    private static boolean COLLECT_ONE_LOCAL = false;\n\n    /** method we're processing */\n    private final SsaMethod ssaMeth;\n\n    /**\n     * Processes a method.\n     *\n     * @param ssaMethod {@code non-null;} method to process\n     */\n    public static void process(SsaMethod ssaMethod) {\n        ConstCollector cc = new ConstCollector(ssaMethod);\n        cc.run();\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param ssaMethod {@code non-null;} method to process\n     */\n    private ConstCollector(SsaMethod ssaMethod) {\n        this.ssaMeth = ssaMethod;\n    }\n\n    /**\n     * Applies the optimization.\n     */\n    private void run() {\n        int regSz = ssaMeth.getRegCount();\n\n        ArrayList<TypedConstant> constantList\n                = getConstsSortedByCountUse();\n\n        int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS);\n\n        SsaBasicBlock start = ssaMeth.getEntryBlock();\n\n        // Constant to new register containing the constant\n        HashMap<TypedConstant, RegisterSpec> newRegs\n                = new HashMap<TypedConstant, RegisterSpec> (toCollect);\n\n        for (int i = 0; i < toCollect; i++) {\n            TypedConstant cst = constantList.get(i);\n            RegisterSpec result\n                    = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst);\n\n            Rop constRop = Rops.opConst(cst);\n\n            if (constRop.getBranchingness() == Rop.BRANCH_NONE) {\n                start.addInsnToHead(\n                        new PlainCstInsn(Rops.opConst(cst),\n                                SourcePosition.NO_INFO, result,\n                                RegisterSpecList.EMPTY, cst));\n            } else {\n                // We need two new basic blocks along with the new insn\n                SsaBasicBlock entryBlock = ssaMeth.getEntryBlock();\n                SsaBasicBlock successorBlock\n                        = entryBlock.getPrimarySuccessor();\n\n                // Insert a block containing the const insn.\n                SsaBasicBlock constBlock\n                        = entryBlock.insertNewSuccessor(successorBlock);\n\n                constBlock.replaceLastInsn(\n                        new ThrowingCstInsn(constRop, SourcePosition.NO_INFO,\n                                RegisterSpecList.EMPTY,\n                                StdTypeList.EMPTY, cst));\n\n                // Insert a block containing the move-result-pseudo insn.\n\n                SsaBasicBlock resultBlock\n                        = constBlock.insertNewSuccessor(successorBlock);\n                PlainInsn insn\n                    = new PlainInsn(\n                            Rops.opMoveResultPseudo(result.getTypeBearer()),\n                            SourcePosition.NO_INFO,\n                            result, RegisterSpecList.EMPTY);\n\n                resultBlock.addInsnToHead(insn);\n            }\n\n            newRegs.put(cst, result);\n        }\n\n        updateConstUses(newRegs, regSz);\n    }\n\n    /**\n     * Gets all of the collectable constant values used in this method,\n     * sorted by most used first. Skips non-collectable consts, such as\n     * non-string object constants\n     *\n     * @return {@code non-null;} list of constants in most-to-least used order\n     */\n    private ArrayList<TypedConstant> getConstsSortedByCountUse() {\n        int regSz = ssaMeth.getRegCount();\n\n        final HashMap<TypedConstant, Integer> countUses\n                = new HashMap<TypedConstant, Integer>();\n\n        /*\n         * Each collected constant can be used by just one local\n         * (used only if COLLECT_ONE_LOCAL is true).\n         */\n        final HashSet<TypedConstant> usedByLocal\n                = new HashSet<TypedConstant>();\n\n        // Count how many times each const value is used.\n        for (int i = 0; i < regSz; i++) {\n            SsaInsn insn = ssaMeth.getDefinitionForRegister(i);\n\n            if (insn == null || insn.getOpcode() == null) continue;\n\n            RegisterSpec result = insn.getResult();\n            TypeBearer typeBearer = result.getTypeBearer();\n\n            if (!typeBearer.isConstant()) continue;\n\n            TypedConstant cst = (TypedConstant) typeBearer;\n\n            // Find defining instruction for move-result-pseudo instructions\n            if (insn.getOpcode().getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {\n                int pred = insn.getBlock().getPredecessors().nextSetBit(0);\n                ArrayList<SsaInsn> predInsns;\n                predInsns = ssaMeth.getBlocks().get(pred).getInsns();\n                insn = predInsns.get(predInsns.size()-1);\n            }\n\n            if (insn.canThrow()) {\n                /*\n                 * Don't move anything other than strings -- the risk\n                 * of changing where an exception is thrown is too high.\n                 */\n                if (!(cst instanceof CstString) || !COLLECT_STRINGS) {\n                    continue;\n                }\n                /*\n                 * We can't move any throwable const whose throw will be\n                 * caught, so don't count them.\n                 */\n                if (insn.getBlock().getSuccessors().cardinality() > 1) {\n                    continue;\n                }\n            }\n\n            /*\n             * TODO: Might be nice to try and figure out which local\n             * wins most when collected.\n             */\n            if (ssaMeth.isRegALocal(result)) {\n                if (!COLLECT_ONE_LOCAL) {\n                    continue;\n                } else {\n                    if (usedByLocal.contains(cst)) {\n                        // Count one local usage only.\n                        continue;\n                    } else {\n                        usedByLocal.add(cst);\n                    }\n                }\n            }\n\n            Integer has = countUses.get(cst);\n            if (has == null) {\n                countUses.put(cst, 1);\n            } else {\n                countUses.put(cst, has + 1);\n            }\n        }\n\n        // Collect constants that have been reused.\n        ArrayList<TypedConstant> constantList = new ArrayList<TypedConstant>();\n        for (Map.Entry<TypedConstant, Integer> entry : countUses.entrySet()) {\n            if (entry.getValue() > 1) {\n                constantList.add(entry.getKey());\n            }\n        }\n\n        // Sort by use, with most used at the beginning of the list.\n        Collections.sort(constantList, new Comparator<Constant>() {\n            public int compare(Constant a, Constant b) {\n                int ret;\n                ret = countUses.get(b) - countUses.get(a);\n\n                if (ret == 0) {\n                    /*\n                     * Provide sorting determinisim for constants with same\n                     * usage count.\n                     */\n                    ret = a.compareTo(b);\n                }\n\n                return ret;\n            }\n\n            @Override\n            public boolean equals (Object obj) {\n                return obj == this;\n            }\n        });\n\n        return constantList;\n    }\n\n    /**\n     * Inserts mark-locals if necessary when changing a register. If\n     * the definition of {@code origReg} is associated with a local\n     * variable, then insert a mark-local for {@code newReg} just below\n     * it. We expect the definition of  {@code origReg} to ultimately\n     * be removed by the dead code eliminator\n     *\n     * @param origReg {@code non-null;} original register\n     * @param newReg {@code non-null;} new register that will replace\n     * {@code origReg}\n     */\n    private void fixLocalAssignment(RegisterSpec origReg,\n            RegisterSpec newReg) {\n        for (SsaInsn use : ssaMeth.getUseListForRegister(origReg.getReg())) {\n            RegisterSpec localAssignment = use.getLocalAssignment();\n            if (localAssignment == null) {\n                continue;\n            }\n\n            if (use.getResult() == null) {\n                /*\n                 * This is a mark-local. it will be updated when all uses\n                 * are updated.\n                 */\n                continue;\n            }\n\n            LocalItem local = localAssignment.getLocalItem();\n\n            // Un-associate original use.\n            use.setResultLocal(null);\n\n            // Now add a mark-local to the new reg immediately after.\n            newReg = newReg.withLocalItem(local);\n\n            SsaInsn newInsn\n                    = SsaInsn.makeFromRop(\n                        new PlainInsn(Rops.opMarkLocal(newReg),\n                        SourcePosition.NO_INFO, null,\n                                RegisterSpecList.make(newReg)),\n                    use.getBlock());\n\n            ArrayList<SsaInsn> insns = use.getBlock().getInsns();\n\n            insns.add(insns.indexOf(use) + 1, newInsn);\n        }\n    }\n\n    /**\n     * Updates all uses of various consts to use the values in the newly\n     * assigned registers.\n     *\n     * @param newRegs {@code non-null;} mapping between constant and new reg\n     * @param origRegCount {@code >=0;} original SSA reg count, not including\n     * newly added constant regs\n     */\n    private void updateConstUses(HashMap<TypedConstant, RegisterSpec> newRegs,\n            int origRegCount) {\n\n        /*\n         * set of constants associated with a local variable; used\n         * only if COLLECT_ONE_LOCAL is true.\n         */\n        final HashSet<TypedConstant> usedByLocal\n                = new HashSet<TypedConstant>();\n\n        final ArrayList<SsaInsn>[] useList = ssaMeth.getUseListCopy();\n\n        for (int i = 0; i < origRegCount; i++) {\n            SsaInsn insn = ssaMeth.getDefinitionForRegister(i);\n\n            if (insn == null) {\n                continue;\n            }\n\n            final RegisterSpec origReg = insn.getResult();\n            TypeBearer typeBearer = insn.getResult().getTypeBearer();\n\n            if (!typeBearer.isConstant()) continue;\n\n            TypedConstant cst = (TypedConstant) typeBearer;\n            final RegisterSpec newReg = newRegs.get(cst);\n\n            if (newReg == null) {\n                continue;\n            }\n\n            if (ssaMeth.isRegALocal(origReg)) {\n                if (!COLLECT_ONE_LOCAL) {\n                    continue;\n                } else {\n                    /*\n                     * TODO: If the same local gets the same cst\n                     * multiple times, it would be nice to reuse the\n                     * register.\n                     */\n                    if (usedByLocal.contains(cst)) {\n                        continue;\n                    } else {\n                        usedByLocal.add(cst);\n                        fixLocalAssignment(origReg, newRegs.get(cst));\n                    }\n                }\n            }\n\n            // maps an original const register to the new collected register\n            RegisterMapper mapper = new RegisterMapper() {\n                @Override\n                public int getNewRegisterCount() {\n                    return ssaMeth.getRegCount();\n                }\n\n                @Override\n                public RegisterSpec map(RegisterSpec registerSpec) {\n                    if (registerSpec.getReg() == origReg.getReg()) {\n                        return newReg.withLocalItem(\n                                registerSpec.getLocalItem());\n                    }\n\n                    return registerSpec;\n                }\n            };\n\n            for (SsaInsn use : useList[origReg.getReg()]) {\n                if (use.canThrow()\n                        && use.getBlock().getSuccessors().cardinality() > 1) {\n                    continue;\n                }\n                use.mapSourceRegisters(mapper);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/DeadCodeRemover.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.HashSet;\n\n/**\n * A variation on Appel Algorithm 19.12 \"Dead code elimination in SSA form\".\n *\n * TODO this algorithm is more efficient if run in reverse from exit\n * block to entry block.\n */\npublic class DeadCodeRemover {\n    /** method we're processing */\n    private final SsaMethod ssaMeth;\n\n    /** ssaMeth.getRegCount() */\n    private final int regCount;\n\n    /**\n     * indexed by register: whether reg should be examined\n     * (does it correspond to a no-side-effect insn?)\n     */\n    private final BitSet worklist;\n\n    /** use list indexed by register; modified during operation */\n    private final ArrayList<SsaInsn>[] useList;\n\n    /**\n     * Process a method with the dead-code remver\n     *\n     * @param ssaMethod method to process\n     */\n    public static void process(SsaMethod ssaMethod) {\n        DeadCodeRemover dc = new DeadCodeRemover(ssaMethod);\n        dc.run();\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param ssaMethod method to process\n     */\n    private DeadCodeRemover(SsaMethod ssaMethod) {\n        this.ssaMeth = ssaMethod;\n\n        regCount = ssaMethod.getRegCount();\n        worklist = new BitSet(regCount);\n        useList = ssaMeth.getUseListCopy();\n    }\n\n    /**\n     * Runs the dead code remover.\n     */\n    private void run() {\n        pruneDeadInstructions();\n\n        HashSet<SsaInsn> deletedInsns = new HashSet<SsaInsn>();\n\n        ssaMeth.forEachInsn(new NoSideEffectVisitor(worklist));\n\n        int regV;\n\n        while ( 0 <= (regV = worklist.nextSetBit(0)) ) {\n            worklist.clear(regV);\n\n            if (useList[regV].size() == 0\n                    || isCircularNoSideEffect(regV, null)) {\n\n                SsaInsn insnS = ssaMeth.getDefinitionForRegister(regV);\n\n                // This insn has already been deleted.\n                if (deletedInsns.contains(insnS)) {\n                    continue;\n                }\n\n                RegisterSpecList sources = insnS.getSources();\n\n                int sz = sources.size();\n                for (int i = 0; i < sz; i++) {\n                    // Delete this insn from all usage lists.\n                    RegisterSpec source = sources.get(i);\n                    useList[source.getReg()].remove(insnS);\n\n                    if (!hasSideEffect(\n                            ssaMeth.getDefinitionForRegister(\n                                    source.getReg()))) {\n                        /*\n                         * Only registers whose definition has no side effect\n                         * should be added back to the worklist.\n                         */\n                        worklist.set(source.getReg());\n                    }\n                }\n\n                // Schedule this insn for later deletion.\n                deletedInsns.add(insnS);\n            }\n        }\n\n        ssaMeth.deleteInsns(deletedInsns);\n    }\n\n    /**\n     * Removes all instructions from every unreachable block.\n     */\n    private void pruneDeadInstructions() {\n        HashSet<SsaInsn> deletedInsns = new HashSet<SsaInsn>();\n\n        ssaMeth.computeReachability();\n\n        for (SsaBasicBlock block : ssaMeth.getBlocks()) {\n            if (block.isReachable()) continue;\n\n            // Prune instructions from unreachable blocks\n            for (int i = 0; i < block.getInsns().size(); i++) {\n                SsaInsn insn = block.getInsns().get(i);\n                RegisterSpecList sources = insn.getSources();\n                int sourcesSize = sources.size();\n\n                // Delete this instruction completely if it has sources\n                if (sourcesSize != 0) {\n                    deletedInsns.add(insn);\n                }\n\n                // Delete this instruction from all usage lists.\n                for (int j = 0; j < sourcesSize; j++) {\n                    RegisterSpec source = sources.get(j);\n                    useList[source.getReg()].remove(insn);\n                }\n\n                // Remove this instruction result from the sources of any phis\n                RegisterSpec result = insn.getResult();\n                if (result == null) continue;\n                for (SsaInsn use : useList[result.getReg()]) {\n                    if (use instanceof PhiInsn) {\n                        PhiInsn phiUse = (PhiInsn) use;\n                        phiUse.removePhiRegister(result);\n                    }\n                }\n            }\n        }\n\n        ssaMeth.deleteInsns(deletedInsns);\n    }\n\n    /**\n     * Returns true if the only uses of this register form a circle of\n     * operations with no side effects.\n     *\n     * @param regV register to examine\n     * @param set a set of registers that we've already determined\n     * are only used as sources in operations with no side effect or null\n     * if this is the first recursion\n     * @return true if usage is circular without side effect\n     */\n    private boolean isCircularNoSideEffect(int regV, BitSet set) {\n        if ((set != null) && set.get(regV)) {\n            return true;\n        }\n\n        for (SsaInsn use : useList[regV]) {\n            if (hasSideEffect(use)) {\n                return false;\n            }\n        }\n\n        if (set == null) {\n            set = new BitSet(regCount);\n        }\n\n        // This register is only used in operations that have no side effect.\n        set.set(regV);\n\n        for (SsaInsn use : useList[regV]) {\n            RegisterSpec result = use.getResult();\n\n            if (result == null\n                    || !isCircularNoSideEffect(result.getReg(), set)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Returns true if this insn has a side-effect. Returns true\n     * if the insn is null for reasons stated in the code block.\n     *\n     * @param insn {@code null-ok;} instruction in question\n     * @return true if it has a side-effect\n     */\n    private static boolean hasSideEffect(SsaInsn insn) {\n        if (insn == null) {\n            /* While false would seem to make more sense here, true\n             * prevents us from adding this back to a worklist unnecessarally.\n             */\n            return true;\n        }\n\n        return insn.hasSideEffect();\n    }\n\n    /**\n     * A callback class used to build up the initial worklist of\n     * registers defined by an instruction with no side effect.\n     */\n    static private class NoSideEffectVisitor implements SsaInsn.Visitor {\n        BitSet noSideEffectRegs;\n\n        /**\n         * Passes in data structures that will be filled out after\n         * ssaMeth.forEachInsn() is called with this instance.\n         *\n         * @param noSideEffectRegs to-build bitset of regs that are\n         * results of regs with no side effects\n         */\n        public NoSideEffectVisitor(BitSet noSideEffectRegs) {\n            this.noSideEffectRegs = noSideEffectRegs;\n        }\n\n        /** {@inheritDoc} */\n        public void visitMoveInsn (NormalSsaInsn insn) {\n            // If we're tracking local vars, some moves have side effects.\n            if (!hasSideEffect(insn)) {\n                noSideEffectRegs.set(insn.getResult().getReg());\n            }\n        }\n\n        /** {@inheritDoc} */\n        public void visitPhiInsn (PhiInsn phi) {\n            // If we're tracking local vars, then some phis have side effects.\n            if (!hasSideEffect(phi)) {\n                noSideEffectRegs.set(phi.getResult().getReg());\n            }\n        }\n\n        /** {@inheritDoc} */\n        public void visitNonMoveInsn (NormalSsaInsn insn) {\n            RegisterSpec result = insn.getResult();\n            if (!hasSideEffect(insn) && result != null) {\n                noSideEffectRegs.set(result.getReg());\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/DomFront.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.util.IntSet;\nimport java.util.ArrayList;\nimport java.util.BitSet;\n\n/**\n * Calculates the dominance-frontiers of a methot's basic blocks.\n * Algorithm from \"A Simple, Fast Dominance Algorithm\" by Cooper,\n * Harvey, and Kennedy; transliterated to Java.\n */\npublic class DomFront {\n    /** local debug flag */\n    private static boolean DEBUG = false;\n\n    /** {@code non-null;} method being processed */\n    private final SsaMethod meth;\n\n    private final ArrayList<SsaBasicBlock> nodes;\n\n    private final DomInfo[] domInfos;\n\n    /**\n     * Dominance-frontier information for a single basic block.\n     */\n    public static class DomInfo {\n        /**\n         * {@code null-ok;} the dominance frontier set indexed by\n         * block index\n         */\n        public IntSet dominanceFrontiers;\n\n        /** {@code >= 0 after run();} the index of the immediate dominator */\n        public int idom = -1;\n    }\n\n    /**\n     * Constructs instance. Call {@link DomFront#run} to process.\n     *\n     * @param meth {@code non-null;} method to process\n     */\n    public DomFront(SsaMethod meth) {\n        this.meth = meth;\n        nodes = meth.getBlocks();\n\n        int szNodes = nodes.size();\n        domInfos = new DomInfo[szNodes];\n\n        for (int i = 0; i < szNodes; i++) {\n            domInfos[i] = new DomInfo();\n        }\n    }\n\n    /**\n     * Calculates the dominance frontier information for the method.\n     *\n     * @return {@code non-null;} an array of DomInfo structures\n     */\n    public DomInfo[] run() {\n        int szNodes = nodes.size();\n\n        if (DEBUG) {\n            for (int i = 0; i < szNodes; i++) {\n                SsaBasicBlock node = nodes.get(i);\n                System.out.println(\"pred[\" + i + \"]: \"\n                        + node.getPredecessors());\n            }\n        }\n\n        Dominators methDom = Dominators.make(meth, domInfos, false);\n\n        if (DEBUG) {\n            for (int i = 0; i < szNodes; i++) {\n                DomInfo info = domInfos[i];\n                System.out.println(\"idom[\" + i + \"]: \"\n                        + info.idom);\n            }\n        }\n\n        buildDomTree();\n\n        if (DEBUG) {\n            debugPrintDomChildren();\n        }\n\n        for (int i = 0; i < szNodes; i++) {\n            domInfos[i].dominanceFrontiers\n                    = SetFactory.makeDomFrontSet(szNodes);\n        }\n\n        calcDomFronts();\n\n        if (DEBUG) {\n            for (int i = 0; i < szNodes; i++) {\n                System.out.println(\"df[\" + i + \"]: \"\n                        + domInfos[i].dominanceFrontiers);\n            }\n        }\n\n        return domInfos;\n    }\n\n    private void debugPrintDomChildren() {\n        int szNodes = nodes.size();\n\n        for (int i = 0; i < szNodes; i++) {\n            SsaBasicBlock node = nodes.get(i);\n            StringBuffer sb = new StringBuffer();\n\n            sb.append('{');\n            boolean comma = false;\n            for (SsaBasicBlock child : node.getDomChildren()) {\n                if (comma) {\n                    sb.append(',');\n                }\n                sb.append(child);\n                comma = true;\n            }\n            sb.append('}');\n\n            System.out.println(\"domChildren[\" + node + \"]: \"\n                    + sb);\n        }\n    }\n\n    /**\n     * The dominators algorithm leaves us knowing who the immediate dominator\n     * is for each node. This sweeps the node list and builds the proper\n     * dominance tree.\n     */\n    private void buildDomTree() {\n        int szNodes = nodes.size();\n\n        for (int i = 0; i < szNodes; i++) {\n            DomInfo info = domInfos[i];\n\n            if (info.idom == -1) continue;\n\n            SsaBasicBlock domParent = nodes.get(info.idom);\n            domParent.addDomChild(nodes.get(i));\n        }\n    }\n\n    /**\n     * Calculates the dominance-frontier set.\n     * from \"A Simple, Fast Dominance Algorithm\" by Cooper,\n     * Harvey, and Kennedy; transliterated to Java.\n     */\n    private void calcDomFronts() {\n        int szNodes = nodes.size();\n\n        for (int b = 0; b < szNodes; b++) {\n            SsaBasicBlock nb = nodes.get(b);\n            DomInfo nbInfo = domInfos[b];\n            BitSet pred = nb.getPredecessors();\n\n            if (pred.cardinality() > 1) {\n                for (int i = pred.nextSetBit(0); i >= 0;\n                     i = pred.nextSetBit(i + 1)) {\n\n                    for (int runnerIndex = i;\n                         runnerIndex != nbInfo.idom; /* empty */) {\n                        /*\n                         * We can stop if we hit a block we already\n                         * added label to, since we must be at a part\n                         * of the dom tree we have seen before.\n                         */\n                        if (runnerIndex == -1) break;\n\n                        DomInfo runnerInfo = domInfos[runnerIndex];\n\n                        if (runnerInfo.dominanceFrontiers.has(b)) {\n                            break;\n                        }\n\n                        // Add b to runner's dominance frontier set.\n                        runnerInfo.dominanceFrontiers.add(b);\n                        runnerIndex = runnerInfo.idom;\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/Dominators.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.HashSet;\n\n/**\n * This class computes dominator and post-dominator information using the\n * Lengauer-Tarjan method.\n *\n * See A Fast Algorithm for Finding Dominators in a Flowgraph\n * T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141.\n *\n * This implementation runs in time O(n log n).  The time bound\n * could be changed to O(n * ack(n)) with a small change to the link and eval,\n * and an addition of a child field to the DFS info. In reality, the constant\n * overheads are high enough that the current method is faster in all but the\n * strangest artificially constructed examples.\n *\n * The basic idea behind this algorithm is to perform a DFS walk, keeping track\n * of various info about parents.  We then use this info to calculate the\n * dominators, using union-find structures to link together the DFS info,\n * then finally evaluate the union-find results to get the dominators.\n * This implementation is m log n because it does not perform union by\n * rank to keep the union-find tree balanced.\n */\npublic final class Dominators {\n    /* postdom is true if we want post dominators */\n    private final boolean postdom;\n\n    /* {@code non-null;} method being processed */\n    private final SsaMethod meth;\n\n    /* Method's basic blocks. */\n    private final ArrayList<SsaBasicBlock> blocks;\n\n    /** indexed by basic block index */\n    private final DFSInfo[] info;\n\n    private final ArrayList<SsaBasicBlock> vertex;\n\n    /** {@code non-null;} the raw dominator info */\n    private final DomFront.DomInfo domInfos[];\n\n    /**\n     * Constructs an instance.\n     *\n     * @param meth {@code non-null;} method to process\n     * @param domInfos {@code non-null;} the raw dominator info\n     * @param postdom true for postdom information, false for normal dom info\n     */\n    private Dominators(SsaMethod meth, DomFront.DomInfo[] domInfos,\n            boolean postdom) {\n        this.meth = meth;\n        this.domInfos = domInfos;\n        this.postdom = postdom;\n        this.blocks = meth.getBlocks();\n        this.info = new DFSInfo[blocks.size() + 2];\n        this.vertex = new ArrayList<SsaBasicBlock>();\n    }\n\n    /**\n     * Constructs a fully-initialized instance. (This method exists so as\n     * to avoid calling a large amount of code in the constructor.)\n     *\n     * @param meth {@code non-null;} method to process\n     * @param domInfos {@code non-null;} the raw dominator info\n     * @param postdom true for postdom information, false for normal dom info\n     */\n    public static Dominators make(SsaMethod meth, DomFront.DomInfo[] domInfos,\n            boolean postdom) {\n        Dominators result = new Dominators(meth, domInfos, postdom);\n\n        result.run();\n        return result;\n    }\n\n    private BitSet getSuccs(SsaBasicBlock block) {\n        if (postdom) {\n            return block.getPredecessors();\n        } else {\n            return block.getSuccessors();\n        }\n    }\n\n    private BitSet getPreds(SsaBasicBlock block) {\n        if (postdom) {\n            return block.getSuccessors();\n        } else {\n            return block.getPredecessors();\n        }\n    }\n\n    /**\n     * Performs path compress on the DFS info.\n     *\n     * @param in Basic block whose DFS info we are path compressing.\n     */\n    private void compress(SsaBasicBlock in) {\n        DFSInfo bbInfo = info[in.getIndex()];\n        DFSInfo ancestorbbInfo = info[bbInfo.ancestor.getIndex()];\n\n        if (ancestorbbInfo.ancestor != null) {\n            ArrayList<SsaBasicBlock> worklist = new ArrayList<SsaBasicBlock>();\n            HashSet<SsaBasicBlock> visited = new HashSet<SsaBasicBlock>();\n            worklist.add(in);\n\n            while (!worklist.isEmpty()) {\n                int wsize = worklist.size();\n                SsaBasicBlock v = worklist.get(wsize - 1);\n                DFSInfo vbbInfo = info[v.getIndex()];\n                SsaBasicBlock vAncestor = vbbInfo.ancestor;\n                DFSInfo vabbInfo = info[vAncestor.getIndex()];\n\n                // Make sure we process our ancestor before ourselves.\n                if (visited.add(vAncestor) && vabbInfo.ancestor != null) {\n                    worklist.add(vAncestor);\n                    continue;\n                }\n                worklist.remove(wsize - 1);\n\n                // Update based on ancestor info.\n                if (vabbInfo.ancestor == null) {\n                    continue;\n                }\n                SsaBasicBlock vAncestorRep = vabbInfo.rep;\n                SsaBasicBlock vRep = vbbInfo.rep;\n                if (info[vAncestorRep.getIndex()].semidom\n                        < info[vRep.getIndex()].semidom) {\n                    vbbInfo.rep = vAncestorRep;\n                }\n                vbbInfo.ancestor = vabbInfo.ancestor;\n            }\n        }\n    }\n\n    private SsaBasicBlock eval(SsaBasicBlock v) {\n        DFSInfo bbInfo = info[v.getIndex()];\n\n        if (bbInfo.ancestor == null) {\n            return v;\n        }\n\n        compress(v);\n        return bbInfo.rep;\n    }\n\n    /**\n     * Performs dominator/post-dominator calculation for the control\n     * flow graph.\n     *\n     * @param meth {@code non-null;} method to analyze\n     */\n    private void run() {\n        SsaBasicBlock root = postdom\n                ? meth.getExitBlock() : meth.getEntryBlock();\n\n        if (root != null) {\n            vertex.add(root);\n            domInfos[root.getIndex()].idom = root.getIndex();\n        }\n\n        /*\n         * First we perform a DFS numbering of the blocks, by\n         * numbering the dfs tree roots.\n         */\n\n        DfsWalker walker = new DfsWalker();\n        meth.forEachBlockDepthFirst(postdom, walker);\n\n        // the largest semidom number assigned\n        int dfsMax = vertex.size() - 1;\n\n        // Now calculate semidominators.\n        for (int i = dfsMax; i >= 2; --i) {\n            SsaBasicBlock w = vertex.get(i);\n            DFSInfo wInfo = info[w.getIndex()];\n\n            BitSet preds = getPreds(w);\n            for (int j = preds.nextSetBit(0);\n                 j >= 0;\n                 j = preds.nextSetBit(j + 1)) {\n                SsaBasicBlock predBlock = blocks.get(j);\n                DFSInfo predInfo = info[predBlock.getIndex()];\n\n                /*\n                 * PredInfo may not exist in case the predecessor is\n                 * not reachable.\n                 */\n                if (predInfo != null) {\n                    int predSemidom = info[eval(predBlock).getIndex()].semidom;\n                    if (predSemidom < wInfo.semidom) {\n                        wInfo.semidom = predSemidom;\n                    }\n                }\n            }\n            info[vertex.get(wInfo.semidom).getIndex()].bucket.add(w);\n\n            /*\n             * Normally we would call link here, but in our O(m log n)\n             * implementation this is equivalent to the following\n             * single line.\n             */\n            wInfo.ancestor = wInfo.parent;\n\n            // Implicity define idom for each vertex.\n            ArrayList<SsaBasicBlock> wParentBucket;\n            wParentBucket = info[wInfo.parent.getIndex()].bucket;\n\n            while (!wParentBucket.isEmpty()) {\n                int lastItem = wParentBucket.size() - 1;\n                SsaBasicBlock last = wParentBucket.remove(lastItem);\n                SsaBasicBlock U = eval(last);\n                if (info[U.getIndex()].semidom\n                        < info[last.getIndex()].semidom) {\n                    domInfos[last.getIndex()].idom = U.getIndex();\n                } else {\n                    domInfos[last.getIndex()].idom = wInfo.parent.getIndex();\n                }\n            }\n        }\n\n        // Now explicitly define the immediate dominator of each vertex\n        for (int i =  2; i <= dfsMax; ++i) {\n            SsaBasicBlock w = vertex.get(i);\n            if (domInfos[w.getIndex()].idom\n                    != vertex.get(info[w.getIndex()].semidom).getIndex()) {\n                domInfos[w.getIndex()].idom\n                        = domInfos[domInfos[w.getIndex()].idom].idom;\n            }\n        }\n    }\n\n    /**\n     * Callback for depth-first walk through control flow graph (either\n     * from the entry block or the exit block). Records the traversal order\n     * in the {@code info}list.\n     */\n    private class DfsWalker implements SsaBasicBlock.Visitor {\n        private int dfsNum = 0;\n\n        public void visitBlock(SsaBasicBlock v, SsaBasicBlock parent) {\n            DFSInfo bbInfo = new DFSInfo();\n            bbInfo.semidom = ++dfsNum;\n            bbInfo.rep = v;\n            bbInfo.parent = parent;\n            vertex.add(v);\n            info[v.getIndex()] = bbInfo;\n        }\n    }\n\n    private static final class DFSInfo {\n        public int semidom;\n        public SsaBasicBlock parent;\n\n        /**\n         * rep(resentative) is known as \"label\" in the paper. It is the node\n         * that our block's DFS info has been unioned to.\n         */\n        public SsaBasicBlock rep;\n\n        public SsaBasicBlock ancestor;\n        public ArrayList<SsaBasicBlock> bucket;\n\n        public DFSInfo() {\n            bucket = new ArrayList<SsaBasicBlock>();\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/EscapeAnalysis.java",
    "content": "/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.Exceptions;\nimport com.taobao.android.dx.rop.code.FillArrayDataInsn;\nimport com.taobao.android.dx.rop.code.Insn;\nimport com.taobao.android.dx.rop.code.PlainCstInsn;\nimport com.taobao.android.dx.rop.code.PlainInsn;\nimport com.taobao.android.dx.rop.code.RegOps;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rop;\nimport com.taobao.android.dx.rop.code.Rops;\nimport com.taobao.android.dx.rop.code.ThrowingCstInsn;\nimport com.taobao.android.dx.rop.code.ThrowingInsn;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstLiteralBits;\nimport com.taobao.android.dx.rop.cst.CstMethodRef;\nimport com.taobao.android.dx.rop.cst.CstNat;\nimport com.taobao.android.dx.rop.cst.CstString;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.cst.TypedConstant;\nimport com.taobao.android.dx.rop.cst.Zeroes;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.HashSet;\nimport java.util.List;\n\n/**\n * Simple intraprocedural escape analysis. Finds new arrays that don't escape\n * the method they are created in and replaces the array values with registers.\n */\npublic class EscapeAnalysis {\n    /**\n     * Struct used to generate and maintain escape analysis results.\n     */\n    static class EscapeSet {\n        /** set containing all registers related to an object */\n        BitSet regSet;\n        /** escape state of the object */\n        EscapeState escape;\n        /** list of objects that are put into this object */\n        ArrayList<EscapeSet> childSets;\n        /** list of objects that this object is put into */\n        ArrayList<EscapeSet> parentSets;\n        /** flag to indicate this object is a scalar replaceable array */\n        boolean replaceableArray;\n\n        /**\n         * Constructs an instance of an EscapeSet\n         *\n         * @param reg the SSA register that defines the object\n         * @param size the number of registers in the method\n         * @param escState the lattice value to initially set this to\n         */\n        EscapeSet(int reg, int size, EscapeState escState) {\n            regSet = new BitSet(size);\n            regSet.set(reg);\n            escape = escState;\n            childSets = new ArrayList<EscapeSet>();\n            parentSets = new ArrayList<EscapeSet>();\n            replaceableArray = false;\n        }\n    }\n\n    /**\n     * Lattice values used to indicate escape state for an object. Analysis can\n     * only raise escape state values, not lower them.\n     *\n     * TOP - Used for objects that haven't been analyzed yet\n     * NONE - Object does not escape, and is eligible for scalar replacement.\n     * METHOD - Object remains local to method, but can't be scalar replaced.\n     * INTER - Object is passed between methods. (treated as globally escaping\n     *         since this is an intraprocedural analysis)\n     * GLOBAL - Object escapes globally.\n     */\n    public enum EscapeState {\n        TOP, NONE, METHOD, INTER, GLOBAL\n    }\n\n    /** method we're processing */\n    private SsaMethod ssaMeth;\n    /** ssaMeth.getRegCount() */\n    private int regCount;\n    /** Lattice values for each object register group */\n    private ArrayList<EscapeSet> latticeValues;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param ssaMeth method to process\n     */\n    private EscapeAnalysis(SsaMethod ssaMeth) {\n        this.ssaMeth = ssaMeth;\n        this.regCount = ssaMeth.getRegCount();\n        this.latticeValues = new ArrayList<EscapeSet>();\n    }\n\n    /**\n     * Finds the index in the lattice for a particular register.\n     * Returns the size of the lattice if the register wasn't found.\n     *\n     * @param reg {@code non-null;} register being looked up\n     * @return index of the register or size of the lattice if it wasn't found.\n     */\n    private int findSetIndex(RegisterSpec reg) {\n        int i;\n        for (i = 0; i < latticeValues.size(); i++) {\n            EscapeSet e = latticeValues.get(i);\n            if (e.regSet.get(reg.getReg())) {\n                return i;\n            }\n        }\n        return i;\n    }\n\n    /**\n     * Finds the corresponding instruction for a given move result\n     *\n     * @param moveInsn {@code non-null;} a move result instruction\n     * @return {@code non-null;} the instruction that produces the result for\n     * the move\n     */\n    private SsaInsn getInsnForMove(SsaInsn moveInsn) {\n        int pred = moveInsn.getBlock().getPredecessors().nextSetBit(0);\n        ArrayList<SsaInsn> predInsns = ssaMeth.getBlocks().get(pred).getInsns();\n        return predInsns.get(predInsns.size()-1);\n    }\n\n    /**\n     * Finds the corresponding move result for a given instruction\n     *\n     * @param insn {@code non-null;} an instruction that must always be\n     * followed by a move result\n     * @return {@code non-null;} the move result for the given instruction\n     */\n    private SsaInsn getMoveForInsn(SsaInsn insn) {\n        int succ = insn.getBlock().getSuccessors().nextSetBit(0);\n        ArrayList<SsaInsn> succInsns = ssaMeth.getBlocks().get(succ).getInsns();\n        return succInsns.get(0);\n    }\n\n    /**\n     * Creates a link in the lattice between two EscapeSets due to a put\n     * instruction. The object being put is the child and the object being put\n     * into is the parent. A child set must always have an escape state at\n     * least as high as its parent.\n     *\n     * @param parentSet {@code non-null;} the EscapeSet for the object being put\n     * into\n     * @param childSet {@code non-null;} the EscapeSet for the object being put\n     */\n    private void addEdge(EscapeSet parentSet, EscapeSet childSet) {\n        if (!childSet.parentSets.contains(parentSet)) {\n            childSet.parentSets.add(parentSet);\n        }\n        if (!parentSet.childSets.contains(childSet)) {\n            parentSet.childSets.add(childSet);\n        }\n    }\n\n    /**\n     * Merges all links in the lattice among two EscapeSets. On return, the\n     * newNode will have its old links as well as all links from the oldNode.\n     * The oldNode has all its links removed.\n     *\n     * @param newNode {@code non-null;} the EscapeSet to merge all links into\n     * @param oldNode {@code non-null;} the EscapeSet to remove all links from\n     */\n    private void replaceNode(EscapeSet newNode, EscapeSet oldNode) {\n        for (EscapeSet e : oldNode.parentSets) {\n            e.childSets.remove(oldNode);\n            e.childSets.add(newNode);\n            newNode.parentSets.add(e);\n        }\n        for (EscapeSet e : oldNode.childSets) {\n            e.parentSets.remove(oldNode);\n            e.parentSets.add(newNode);\n            newNode.childSets.add(e);\n        }\n    }\n\n    /**\n     * Performs escape analysis on a method. Finds scalar replaceable arrays and\n     * replaces them with equivalent registers.\n     *\n     * @param ssaMethod {@code non-null;} method to process\n     */\n    public static void process(SsaMethod ssaMethod) {\n        new EscapeAnalysis(ssaMethod).run();\n    }\n\n    /**\n     * Process a single instruction, looking for new objects resulting from\n     * move result or move param.\n     *\n     * @param insn {@code non-null;} instruction to process\n     */\n    private void processInsn(SsaInsn insn) {\n        int op = insn.getOpcode().getOpcode();\n        RegisterSpec result = insn.getResult();\n        EscapeSet escSet;\n\n        // Identify new objects\n        if (op == RegOps.MOVE_RESULT_PSEUDO &&\n                result.getTypeBearer().getBasicType() == Type.BT_OBJECT) {\n            // Handle objects generated through move_result_pseudo\n            escSet = processMoveResultPseudoInsn(insn);\n            processRegister(result, escSet);\n        } else if (op == RegOps.MOVE_PARAM &&\n                      result.getTypeBearer().getBasicType() == Type.BT_OBJECT) {\n            // Track method arguments that are objects\n            escSet = new EscapeSet(result.getReg(), regCount, EscapeState.NONE);\n            latticeValues.add(escSet);\n            processRegister(result, escSet);\n        } else if (op == RegOps.MOVE_RESULT &&\n                result.getTypeBearer().getBasicType() == Type.BT_OBJECT) {\n            // Track method return values that are objects\n            escSet = new EscapeSet(result.getReg(), regCount, EscapeState.NONE);\n            latticeValues.add(escSet);\n            processRegister(result, escSet);\n        }\n    }\n\n    /**\n     * Determine the origin of a move result pseudo instruction that generates\n     * an object. Creates a new EscapeSet for the new object accordingly.\n     *\n     * @param insn {@code non-null;} move result pseudo instruction to process\n     * @return {@code non-null;} an EscapeSet for the object referred to by the\n     * move result pseudo instruction\n     */\n    private EscapeSet processMoveResultPseudoInsn(SsaInsn insn) {\n        RegisterSpec result = insn.getResult();\n        SsaInsn prevSsaInsn = getInsnForMove(insn);\n        int prevOpcode = prevSsaInsn.getOpcode().getOpcode();\n        EscapeSet escSet;\n        RegisterSpec prevSource;\n\n        switch(prevOpcode) {\n           // New instance / Constant\n            case RegOps.NEW_INSTANCE:\n            case RegOps.CONST:\n                escSet = new EscapeSet(result.getReg(), regCount,\n                                           EscapeState.NONE);\n                break;\n            // New array\n            case RegOps.NEW_ARRAY:\n            case RegOps.FILLED_NEW_ARRAY:\n                prevSource = prevSsaInsn.getSources().get(0);\n                if (prevSource.getTypeBearer().isConstant()) {\n                    // New fixed array\n                    escSet = new EscapeSet(result.getReg(), regCount,\n                                               EscapeState.NONE);\n                    escSet.replaceableArray = true;\n                } else {\n                    // New variable array\n                    escSet = new EscapeSet(result.getReg(), regCount,\n                                               EscapeState.GLOBAL);\n                }\n                break;\n            // Loading a static object\n            case RegOps.GET_STATIC:\n                escSet = new EscapeSet(result.getReg(), regCount,\n                                           EscapeState.GLOBAL);\n                break;\n            // Type cast / load an object from a field or array\n            case RegOps.CHECK_CAST:\n            case RegOps.GET_FIELD:\n            case RegOps.AGET:\n                prevSource = prevSsaInsn.getSources().get(0);\n                int setIndex = findSetIndex(prevSource);\n\n                // Set should already exist, try to find it\n                if (setIndex != latticeValues.size()) {\n                    escSet = latticeValues.get(setIndex);\n                    escSet.regSet.set(result.getReg());\n                    return escSet;\n                }\n\n                // Set not found, must be either null or unknown\n                if (prevSource.getType() == Type.KNOWN_NULL) {\n                    escSet = new EscapeSet(result.getReg(), regCount,\n                                               EscapeState.NONE);\n               } else {\n                    escSet = new EscapeSet(result.getReg(), regCount,\n                                               EscapeState.GLOBAL);\n                }\n                break;\n            default:\n                return null;\n        }\n\n        // Add the newly created escSet to the lattice and return it\n        latticeValues.add(escSet);\n        return escSet;\n    }\n\n    /**\n     * Iterate through all the uses of a new object.\n     *\n     * @param result {@code non-null;} register where new object is stored\n     * @param escSet {@code non-null;} EscapeSet for the new object\n     */\n    private void processRegister(RegisterSpec result, EscapeSet escSet) {\n        ArrayList<RegisterSpec> regWorklist = new ArrayList<RegisterSpec>();\n        regWorklist.add(result);\n\n        // Go through the worklist\n        while (!regWorklist.isEmpty()) {\n            int listSize = regWorklist.size() - 1;\n            RegisterSpec def = regWorklist.remove(listSize);\n            List<SsaInsn> useList = ssaMeth.getUseListForRegister(def.getReg());\n\n            // Handle all the uses of this register\n            for (SsaInsn use : useList) {\n                Rop useOpcode = use.getOpcode();\n\n                if (useOpcode == null) {\n                    // Handle phis\n                    processPhiUse(use, escSet, regWorklist);\n                } else {\n                    // Handle other opcodes\n                    processUse(def, use, escSet, regWorklist);\n                }\n            }\n        }\n    }\n\n    /**\n     * Handles phi uses of new objects. Will merge together the sources of a phi\n     * into a single EscapeSet. Adds the result of the phi to the worklist so\n     * its uses can be followed.\n     *\n     * @param use {@code non-null;} phi use being processed\n     * @param escSet {@code non-null;} EscapeSet for the object\n     * @param regWorklist {@code non-null;} worklist of instructions left to\n     * process for this object\n     */\n    private void processPhiUse(SsaInsn use, EscapeSet escSet,\n                                   ArrayList<RegisterSpec> regWorklist) {\n        int setIndex = findSetIndex(use.getResult());\n        if (setIndex != latticeValues.size()) {\n            // Check if result is in a set already\n            EscapeSet mergeSet = latticeValues.get(setIndex);\n            if (mergeSet != escSet) {\n                // If it is, merge the sets and states, then delete the copy\n                escSet.replaceableArray = false;\n                escSet.regSet.or(mergeSet.regSet);\n                if (escSet.escape.compareTo(mergeSet.escape) < 0) {\n                    escSet.escape = mergeSet.escape;\n                }\n                replaceNode(escSet, mergeSet);\n                latticeValues.remove(setIndex);\n            }\n        } else {\n            // If no set is found, add it to this escSet and the worklist\n            escSet.regSet.set(use.getResult().getReg());\n            regWorklist.add(use.getResult());\n        }\n    }\n\n    /**\n     * Handles non-phi uses of new objects. Checks to see how instruction is\n     * used and updates the escape state accordingly.\n     *\n     * @param def {@code non-null;} register holding definition of new object\n     * @param use {@code non-null;} use of object being processed\n     * @param escSet {@code non-null;} EscapeSet for the object\n     * @param regWorklist {@code non-null;} worklist of instructions left to\n     * process for this object\n     */\n    private void processUse(RegisterSpec def, SsaInsn use, EscapeSet escSet,\n                                ArrayList<RegisterSpec> regWorklist) {\n        int useOpcode = use.getOpcode().getOpcode();\n        switch (useOpcode) {\n            case RegOps.MOVE:\n                // Follow uses of the move by adding it to the worklist\n                escSet.regSet.set(use.getResult().getReg());\n                regWorklist.add(use.getResult());\n                break;\n            case RegOps.IF_EQ:\n            case RegOps.IF_NE:\n            case RegOps.CHECK_CAST:\n                // Compared objects can't be replaced, so promote if necessary\n                if (escSet.escape.compareTo(EscapeState.METHOD) < 0) {\n                    escSet.escape = EscapeState.METHOD;\n                }\n                break;\n            case RegOps.APUT:\n                // For array puts, check for a constant array index\n                RegisterSpec putIndex = use.getSources().get(2);\n                if (!putIndex.getTypeBearer().isConstant()) {\n                    // If not constant, array can't be replaced\n                    escSet.replaceableArray = false;\n                }\n                // Intentional fallthrough\n            case RegOps.PUT_FIELD:\n                // Skip non-object puts\n                RegisterSpec putValue = use.getSources().get(0);\n                if (putValue.getTypeBearer().getBasicType() != Type.BT_OBJECT) {\n                    break;\n                }\n                escSet.replaceableArray = false;\n\n                // Raise 1st object's escape state to 2nd if 2nd is higher\n                RegisterSpecList sources = use.getSources();\n                if (sources.get(0).getReg() == def.getReg()) {\n                    int setIndex = findSetIndex(sources.get(1));\n                    if (setIndex != latticeValues.size()) {\n                        EscapeSet parentSet = latticeValues.get(setIndex);\n                        addEdge(parentSet, escSet);\n                        if (escSet.escape.compareTo(parentSet.escape) < 0) {\n                            escSet.escape = parentSet.escape;\n                        }\n                    }\n                } else {\n                    int setIndex = findSetIndex(sources.get(0));\n                    if (setIndex != latticeValues.size()) {\n                        EscapeSet childSet = latticeValues.get(setIndex);\n                        addEdge(escSet, childSet);\n                        if (childSet.escape.compareTo(escSet.escape) < 0) {\n                            childSet.escape = escSet.escape;\n                        }\n                    }\n                }\n                break;\n            case RegOps.AGET:\n                // For array gets, check for a constant array index\n                RegisterSpec getIndex = use.getSources().get(1);\n                if (!getIndex.getTypeBearer().isConstant()) {\n                    // If not constant, array can't be replaced\n                    escSet.replaceableArray = false;\n                }\n                break;\n            case RegOps.PUT_STATIC:\n                // Static puts cause an object to escape globally\n                escSet.escape = EscapeState.GLOBAL;\n                break;\n            case RegOps.INVOKE_STATIC:\n            case RegOps.INVOKE_VIRTUAL:\n            case RegOps.INVOKE_SUPER:\n            case RegOps.INVOKE_DIRECT:\n            case RegOps.INVOKE_INTERFACE:\n            case RegOps.RETURN:\n            case RegOps.THROW:\n                // These operations cause an object to escape interprocedurally\n                escSet.escape = EscapeState.INTER;\n                break;\n            default:\n                break;\n        }\n    }\n\n    /**\n     * Performs scalar replacement on all eligible arrays.\n     */\n    private void scalarReplacement() {\n        // Iterate through lattice, looking for non-escaping replaceable arrays\n        for (EscapeSet escSet : latticeValues) {\n            if (!escSet.replaceableArray || escSet.escape != EscapeState.NONE) {\n                continue;\n            }\n\n            // Get the instructions for the definition and move of the array\n            int e = escSet.regSet.nextSetBit(0);\n            SsaInsn def = ssaMeth.getDefinitionForRegister(e);\n            SsaInsn prev = getInsnForMove(def);\n\n            // Create a map for the new registers that will be created\n            TypeBearer lengthReg = prev.getSources().get(0).getTypeBearer();\n            int length = ((CstLiteralBits) lengthReg).getIntBits();\n            ArrayList<RegisterSpec> newRegs =\n                new ArrayList<RegisterSpec>(length);\n            HashSet<SsaInsn> deletedInsns = new HashSet<SsaInsn>();\n\n            // Replace the definition of the array with registers\n            replaceDef(def, prev, length, newRegs);\n\n            // Mark definition instructions for deletion\n            deletedInsns.add(prev);\n            deletedInsns.add(def);\n\n            // Go through all uses of the array\n            List<SsaInsn> useList = ssaMeth.getUseListForRegister(e);\n            for (SsaInsn use : useList) {\n                // Replace the use with scalars and then mark it for deletion\n                replaceUse(use, prev, newRegs, deletedInsns);\n                deletedInsns.add(use);\n            }\n\n            // Delete all marked instructions\n            ssaMeth.deleteInsns(deletedInsns);\n            ssaMeth.onInsnsChanged();\n\n            // Convert the method back to SSA form\n            SsaConverter.updateSsaMethod(ssaMeth, regCount);\n\n            // Propagate and remove extra moves added by scalar replacement\n            movePropagate();\n        }\n    }\n\n    /**\n     * Replaces the instructions that define an array with equivalent registers.\n     * For each entry in the array, a register is created, initialized to zero.\n     * A mapping between this register and the corresponding array index is\n     * added.\n     *\n     * @param def {@code non-null;} move result instruction for array\n     * @param prev {@code non-null;} instruction for instantiating new array\n     * @param length size of the new array\n     * @param newRegs {@code non-null;} mapping of array indices to new\n     * registers to be populated\n     */\n    private void replaceDef(SsaInsn def, SsaInsn prev, int length,\n                                ArrayList<RegisterSpec> newRegs) {\n        Type resultType = def.getResult().getType();\n\n        // Create new zeroed out registers for each element in the array\n        for (int i = 0; i < length; i++) {\n            Constant newZero = Zeroes.zeroFor(resultType.getComponentType());\n            TypedConstant typedZero = (TypedConstant) newZero;\n            RegisterSpec newReg =\n                RegisterSpec.make(ssaMeth.makeNewSsaReg(), typedZero);\n            newRegs.add(newReg);\n            insertPlainInsnBefore(def, RegisterSpecList.EMPTY, newReg,\n                                      RegOps.CONST, newZero);\n        }\n    }\n\n    /**\n     * Replaces the use for a scalar replaceable array. Gets and puts become\n     * move instructions, and array lengths and fills are handled. Can also\n     * identify ArrayIndexOutOfBounds exceptions and throw them if detected.\n     *\n     * @param use {@code non-null;} move result instruction for array\n     * @param prev {@code non-null;} instruction for instantiating new array\n     * @param newRegs {@code non-null;} mapping of array indices to new\n     * registers\n     * @param deletedInsns {@code non-null;} set of instructions marked for\n     * deletion\n     */\n    private void replaceUse(SsaInsn use, SsaInsn prev,\n                                ArrayList<RegisterSpec> newRegs,\n                                HashSet<SsaInsn> deletedInsns) {\n        int index;\n        int length = newRegs.size();\n        SsaInsn next;\n        RegisterSpecList sources;\n        RegisterSpec source, result;\n        CstLiteralBits indexReg;\n\n        switch (use.getOpcode().getOpcode()) {\n            case RegOps.AGET:\n                // Replace array gets with moves\n                next = getMoveForInsn(use);\n                sources = use.getSources();\n                indexReg = ((CstLiteralBits) sources.get(1).getTypeBearer());\n                index = indexReg.getIntBits();\n                if (index < length) {\n                    source = newRegs.get(index);\n                    result = source.withReg(next.getResult().getReg());\n                    insertPlainInsnBefore(next, RegisterSpecList.make(source),\n                                              result, RegOps.MOVE, null);\n                } else {\n                    // Throw an exception if the index is out of bounds\n                    insertExceptionThrow(next, sources.get(1), deletedInsns);\n                    deletedInsns.add(next.getBlock().getInsns().get(2));\n                }\n                deletedInsns.add(next);\n                break;\n            case RegOps.APUT:\n                // Replace array puts with moves\n                sources = use.getSources();\n                indexReg = ((CstLiteralBits) sources.get(2).getTypeBearer());\n                index = indexReg.getIntBits();\n                if (index < length) {\n                    source = sources.get(0);\n                    result = source.withReg(newRegs.get(index).getReg());\n                    insertPlainInsnBefore(use, RegisterSpecList.make(source),\n                                              result, RegOps.MOVE, null);\n                    // Update the newReg entry to mark value as unknown now\n                    newRegs.set(index, result.withSimpleType());\n                } else {\n                    // Throw an exception if the index is out of bounds\n                    insertExceptionThrow(use, sources.get(2), deletedInsns);\n                }\n                break;\n            case RegOps.ARRAY_LENGTH:\n                // Replace array lengths with const instructions\n                TypeBearer lengthReg = prev.getSources().get(0).getTypeBearer();\n                //CstInteger lengthReg = CstInteger.make(length);\n                next = getMoveForInsn(use);\n                insertPlainInsnBefore(next, RegisterSpecList.EMPTY,\n                                          next.getResult(), RegOps.CONST,\n                                          (Constant) lengthReg);\n                deletedInsns.add(next);\n                break;\n            case RegOps.MARK_LOCAL:\n                // Remove mark local instructions\n                break;\n            case RegOps.FILL_ARRAY_DATA:\n                // Create const instructions for each fill value\n                Insn ropUse = use.getOriginalRopInsn();\n                FillArrayDataInsn fill = (FillArrayDataInsn) ropUse;\n                ArrayList<Constant> constList = fill.getInitValues();\n                for (int i = 0; i < length; i++) {\n                    RegisterSpec newFill =\n                        RegisterSpec.make(newRegs.get(i).getReg(),\n                                              (TypeBearer) constList.get(i));\n                    insertPlainInsnBefore(use, RegisterSpecList.EMPTY, newFill,\n                                              RegOps.CONST, constList.get(i));\n                    // Update the newRegs to hold the new const value\n                    newRegs.set(i, newFill);\n                }\n                break;\n            default:\n        }\n    }\n\n    /**\n     * Identifies extra moves added by scalar replacement and propagates the\n     * source of the move to any users of the result.\n     */\n    private void movePropagate() {\n        for (int i = 0; i < ssaMeth.getRegCount(); i++) {\n            SsaInsn insn = ssaMeth.getDefinitionForRegister(i);\n\n            // Look for move instructions only\n            if (insn == null || insn.getOpcode() == null ||\n                insn.getOpcode().getOpcode() != RegOps.MOVE) {\n                continue;\n            }\n\n            final ArrayList<SsaInsn>[] useList = ssaMeth.getUseListCopy();\n            final RegisterSpec source = insn.getSources().get(0);\n            final RegisterSpec result = insn.getResult();\n\n            // Ignore moves that weren't added due to scalar replacement\n            if (source.getReg() < regCount && result.getReg() < regCount) {\n                continue;\n            }\n\n            // Create a mapping from source to result\n            RegisterMapper mapper = new RegisterMapper() {\n                @Override\n                public int getNewRegisterCount() {\n                    return ssaMeth.getRegCount();\n                }\n\n                @Override\n                public RegisterSpec map(RegisterSpec registerSpec) {\n                    if (registerSpec.getReg() == result.getReg()) {\n                        return source;\n                    }\n\n                    return registerSpec;\n                }\n            };\n\n            // Modify all uses of the move to use the source of the move instead\n            for (SsaInsn use : useList[result.getReg()]) {\n                use.mapSourceRegisters(mapper);\n            }\n        }\n    }\n\n    /**\n     * Runs escape analysis and scalar replacement of arrays.\n     */\n    private void run() {\n        ssaMeth.forEachBlockDepthFirstDom(new SsaBasicBlock.Visitor() {\n            public void visitBlock (SsaBasicBlock block,\n                    SsaBasicBlock unused) {\n                block.forEachInsn(new SsaInsn.Visitor() {\n                    public void visitMoveInsn(NormalSsaInsn insn) {\n                        // do nothing\n                    }\n\n                    public void visitPhiInsn(PhiInsn insn) {\n                        // do nothing\n                    }\n\n                    public void visitNonMoveInsn(NormalSsaInsn insn) {\n                        processInsn(insn);\n                    }\n                });\n            }\n        });\n\n        // Go through lattice and promote fieldSets as necessary\n        for (EscapeSet e : latticeValues) {\n            if (e.escape != EscapeState.NONE) {\n                for (EscapeSet field : e.childSets) {\n                    if (e.escape.compareTo(field.escape) > 0) {\n                        field.escape = e.escape;\n                    }\n                }\n            }\n        }\n\n        // Perform scalar replacement for arrays\n        scalarReplacement();\n    }\n\n    /**\n     * Replaces instructions that trigger an ArrayIndexOutofBounds exception\n     * with an actual throw of the exception.\n     *\n     * @param insn {@code non-null;} instruction causing the exception\n     * @param index {@code non-null;} index value that is out of bounds\n     * @param deletedInsns {@code non-null;} set of instructions marked for\n     * deletion\n     */\n    private void insertExceptionThrow(SsaInsn insn, RegisterSpec index,\n                                          HashSet<SsaInsn> deletedInsns) {\n        // Create a new ArrayIndexOutOfBoundsException\n        CstType exception =\n            new CstType(Exceptions.TYPE_ArrayIndexOutOfBoundsException);\n        insertThrowingInsnBefore(insn, RegisterSpecList.EMPTY, null,\n                                     RegOps.NEW_INSTANCE, exception);\n\n        // Add a successor block with a move result pseudo for the exception\n        SsaBasicBlock currBlock = insn.getBlock();\n        SsaBasicBlock newBlock =\n            currBlock.insertNewSuccessor(currBlock.getPrimarySuccessor());\n        SsaInsn newInsn = newBlock.getInsns().get(0);\n        RegisterSpec newReg =\n            RegisterSpec.make(ssaMeth.makeNewSsaReg(), exception);\n        insertPlainInsnBefore(newInsn, RegisterSpecList.EMPTY, newReg,\n                                  RegOps.MOVE_RESULT_PSEUDO, null);\n\n        // Add another successor block to initialize the exception\n        SsaBasicBlock newBlock2 =\n            newBlock.insertNewSuccessor(newBlock.getPrimarySuccessor());\n        SsaInsn newInsn2 = newBlock2.getInsns().get(0);\n        CstNat newNat = new CstNat(new CstString(\"<init>\"), new CstString(\"(I)V\"));\n        CstMethodRef newRef = new CstMethodRef(exception, newNat);\n        insertThrowingInsnBefore(newInsn2, RegisterSpecList.make(newReg, index),\n                                     null, RegOps.INVOKE_DIRECT, newRef);\n        deletedInsns.add(newInsn2);\n\n        // Add another successor block to throw the new exception\n        SsaBasicBlock newBlock3 =\n            newBlock2.insertNewSuccessor(newBlock2.getPrimarySuccessor());\n        SsaInsn newInsn3 = newBlock3.getInsns().get(0);\n        insertThrowingInsnBefore(newInsn3, RegisterSpecList.make(newReg), null,\n                                     RegOps.THROW, null);\n        newBlock3.replaceSuccessor(newBlock3.getPrimarySuccessorIndex(),\n                                       ssaMeth.getExitBlock().getIndex());\n        deletedInsns.add(newInsn3);\n    }\n\n    /**\n     * Inserts a new PlainInsn before the given instruction.\n     * TODO: move this somewhere more appropriate\n     *\n     * @param insn {@code non-null;} instruction to insert before\n     * @param newSources {@code non-null;} sources of new instruction\n     * @param newResult {@code non-null;} result of new instruction\n     * @param newOpcode opcode of new instruction\n     * @param cst {@code null-ok;} constant for new instruction, if any\n     */\n    private void insertPlainInsnBefore(SsaInsn insn,\n        RegisterSpecList newSources, RegisterSpec newResult, int newOpcode,\n        Constant cst) {\n\n        Insn originalRopInsn = insn.getOriginalRopInsn();\n        Rop newRop;\n        if (newOpcode == RegOps.MOVE_RESULT_PSEUDO) {\n            newRop = Rops.opMoveResultPseudo(newResult.getType());\n        } else {\n            newRop = Rops.ropFor(newOpcode, newResult, newSources, cst);\n        }\n\n        Insn newRopInsn;\n        if (cst == null) {\n            newRopInsn = new PlainInsn(newRop,\n                    originalRopInsn.getPosition(), newResult, newSources);\n        } else {\n            newRopInsn = new PlainCstInsn(newRop,\n                originalRopInsn.getPosition(), newResult, newSources, cst);\n        }\n\n        NormalSsaInsn newInsn = new NormalSsaInsn(newRopInsn, insn.getBlock());\n        List<SsaInsn> insns = insn.getBlock().getInsns();\n\n        insns.add(insns.lastIndexOf(insn), newInsn);\n        ssaMeth.onInsnAdded(newInsn);\n    }\n\n    /**\n     * Inserts a new ThrowingInsn before the given instruction.\n     * TODO: move this somewhere more appropriate\n     *\n     * @param insn {@code non-null;} instruction to insert before\n     * @param newSources {@code non-null;} sources of new instruction\n     * @param newResult {@code non-null;} result of new instruction\n     * @param newOpcode opcode of new instruction\n     * @param cst {@code null-ok;} constant for new instruction, if any\n     */\n    private void insertThrowingInsnBefore(SsaInsn insn,\n        RegisterSpecList newSources, RegisterSpec newResult, int newOpcode,\n        Constant cst) {\n\n        Insn origRopInsn = insn.getOriginalRopInsn();\n        Rop newRop = Rops.ropFor(newOpcode, newResult, newSources, cst);\n        Insn newRopInsn;\n        if (cst == null) {\n            newRopInsn = new ThrowingInsn(newRop,\n                origRopInsn.getPosition(), newSources, StdTypeList.EMPTY);\n        } else {\n            newRopInsn = new ThrowingCstInsn(newRop,\n                origRopInsn.getPosition(), newSources, StdTypeList.EMPTY, cst);\n        }\n\n        NormalSsaInsn newInsn = new NormalSsaInsn(newRopInsn, insn.getBlock());\n        List<SsaInsn> insns = insn.getBlock().getInsns();\n\n        insns.add(insns.lastIndexOf(insn), newInsn);\n        ssaMeth.onInsnAdded(newInsn);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/InterferenceRegisterMapper.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.ssa.back.InterferenceGraph;\nimport com.taobao.android.dx.util.BitIntSet;\nimport com.taobao.android.dx.util.IntSet;\nimport java.util.ArrayList;\n\n/**\n * A register mapper that keeps track of the accumulated interference\n * information for the registers in the new namespace.\n *\n * Please note that this mapper requires that the old namespace does not\n * have variable register widths/categories, and the new namespace does.\n */\npublic class InterferenceRegisterMapper extends BasicRegisterMapper {\n    /**\n     * Array of interference sets. ArrayList is indexed by new namespace\n     * and BitIntSet's are indexed by old namespace.  The list expands\n     * as needed and missing items are assumed to interfere with nothing.\n     *\n     * Bit sets are always used here, unlike elsewhere, because the max\n     * size of this matrix will be (countSsaRegs * countRopRegs), which may\n     * grow to hundreds of K but not megabytes.\n     */\n    private final ArrayList<BitIntSet> newRegInterference;\n\n    /** the interference graph for the old namespace */\n    private final InterferenceGraph oldRegInterference;\n\n    /**\n     * Constructs an instance\n     *\n     * @param countOldRegisters number of registers in old namespace\n     */\n    public InterferenceRegisterMapper(InterferenceGraph oldRegInterference,\n            int countOldRegisters) {\n        super(countOldRegisters);\n\n        newRegInterference = new ArrayList<BitIntSet>();\n        this.oldRegInterference = oldRegInterference;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void addMapping(int oldReg, int newReg, int category) {\n        super.addMapping(oldReg, newReg, category);\n\n        addInterfence(newReg, oldReg);\n\n        if (category == 2) {\n            addInterfence(newReg + 1, oldReg);\n        }\n    }\n\n    /**\n     * Checks to see if old namespace reg {@code oldReg} interferes\n     * with what currently maps to {@code newReg}.\n     *\n     * @param oldReg old namespace register\n     * @param newReg new namespace register\n     * @param category category of old namespace register\n     * @return true if oldReg will interfere with newReg\n     */\n    public boolean interferes(int oldReg, int newReg, int category) {\n        if (newReg >= newRegInterference.size()) {\n            return false;\n        } else {\n            IntSet existing = newRegInterference.get(newReg);\n\n            if (existing == null) {\n                return false;\n            } else if (category == 1) {\n                return existing.has(oldReg);\n            } else {\n                return existing.has(oldReg)\n                        || (interferes(oldReg, newReg+1, category-1));\n            }\n        }\n    }\n\n    /**\n     * Checks to see if old namespace reg {@code oldReg} interferes\n     * with what currently maps to {@code newReg}.\n     *\n     * @param oldSpec {@code non-null;} old namespace register\n     * @param newReg new namespace register\n     * @return true if oldReg will interfere with newReg\n     */\n    public boolean interferes(RegisterSpec oldSpec, int newReg) {\n        return interferes(oldSpec.getReg(), newReg, oldSpec.getCategory());\n    }\n\n    /**\n     * Adds a register's interference set to the interference list,\n     * growing it if necessary.\n     *\n     * @param newReg register in new namespace\n     * @param oldReg register in old namespace\n     */\n    private void addInterfence(int newReg, int oldReg) {\n        newRegInterference.ensureCapacity(newReg + 1);\n\n        while (newReg >= newRegInterference.size()) {\n            newRegInterference.add(new BitIntSet(newReg +1));\n        }\n\n        oldRegInterference.mergeInterferenceSet(\n                oldReg, newRegInterference.get(newReg));\n    }\n\n    /**\n     * Checks to see if any of a set of old-namespace registers are\n     * pinned to the specified new-namespace reg + category. Takes into\n     * account the category of the old-namespace registers.\n     *\n     * @param oldSpecs {@code non-null;} set of old-namespace regs\n     * @param newReg {@code >= 0;} new-namespace register\n     * @param targetCategory {@code 1..2;} the number of adjacent new-namespace\n     * registers (starting at ropReg) to consider\n     * @return true if any of the old-namespace register have been mapped\n     * to the new-namespace register + category\n     */\n    public boolean areAnyPinned(RegisterSpecList oldSpecs,\n            int newReg, int targetCategory) {\n        int sz = oldSpecs.size();\n\n        for (int i = 0; i < sz; i++) {\n            RegisterSpec oldSpec = oldSpecs.get(i);\n            int r = oldToNew(oldSpec.getReg());\n\n            /*\n             * If oldSpec is a category-2 register, then check both newReg\n             * and newReg - 1.\n             */\n            if (r == newReg\n                || (oldSpec.getCategory() == 2 && (r + 1) == newReg)\n                || (targetCategory == 2 && (r == newReg + 1))) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/LiteralOpUpgrader.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.Insn;\nimport com.taobao.android.dx.rop.code.PlainCstInsn;\nimport com.taobao.android.dx.rop.code.PlainInsn;\nimport com.taobao.android.dx.rop.code.RegOps;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rop;\nimport com.taobao.android.dx.rop.code.Rops;\nimport com.taobao.android.dx.rop.code.TranslationAdvice;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstLiteralBits;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Upgrades insn to their literal (constant-immediate) equivalent if possible.\n * Also switches IF instructions that compare with a constant zero or null\n * to be their IF_*Z equivalents.\n */\npublic class LiteralOpUpgrader {\n\n    /** method we're processing */\n    private final SsaMethod ssaMeth;\n\n    /**\n     * Process a method.\n     *\n     * @param ssaMethod {@code non-null;} method to process\n     */\n    public static void process(SsaMethod ssaMethod) {\n        LiteralOpUpgrader dc;\n\n        dc = new LiteralOpUpgrader(ssaMethod);\n\n        dc.run();\n    }\n\n    private LiteralOpUpgrader(SsaMethod ssaMethod) {\n        this.ssaMeth = ssaMethod;\n    }\n\n    /**\n     * Returns true if the register contains an integer 0 or a known-null\n     * object reference\n     *\n     * @param spec non-null spec\n     * @return true for 0 or null type bearers\n     */\n    private static boolean isConstIntZeroOrKnownNull(RegisterSpec spec) {\n        TypeBearer tb = spec.getTypeBearer();\n        if (tb instanceof CstLiteralBits) {\n            CstLiteralBits clb = (CstLiteralBits) tb;\n            return (clb.getLongBits() == 0);\n        }\n        return false;\n    }\n\n    /**\n     * Run the literal op upgrader\n     */\n    private void run() {\n        final TranslationAdvice advice = Optimizer.getAdvice();\n\n        ssaMeth.forEachInsn(new SsaInsn.Visitor() {\n            public void visitMoveInsn(NormalSsaInsn insn) {\n                // do nothing\n            }\n\n            public void visitPhiInsn(PhiInsn insn) {\n                // do nothing\n            }\n\n            public void visitNonMoveInsn(NormalSsaInsn insn) {\n\n                Insn originalRopInsn = insn.getOriginalRopInsn();\n                Rop opcode = originalRopInsn.getOpcode();\n                RegisterSpecList sources = insn.getSources();\n\n                // Replace insns with constant results with const insns\n                if (tryReplacingWithConstant(insn)) return;\n\n                if (sources.size() != 2 ) {\n                    // We're only dealing with two-source insns here.\n                    return;\n                }\n\n                if (opcode.getBranchingness() == Rop.BRANCH_IF) {\n                    /*\n                     * An if instruction can become an if-*z instruction.\n                     */\n                    if (isConstIntZeroOrKnownNull(sources.get(0))) {\n                        replacePlainInsn(insn, sources.withoutFirst(),\n                              RegOps.flippedIfOpcode(opcode.getOpcode()), null);\n                    } else if (isConstIntZeroOrKnownNull(sources.get(1))) {\n                        replacePlainInsn(insn, sources.withoutLast(),\n                              opcode.getOpcode(), null);\n                    }\n                } else if (advice.hasConstantOperation(\n                        opcode, sources.get(0), sources.get(1))) {\n                    insn.upgradeToLiteral();\n                } else  if (opcode.isCommutative()\n                        && advice.hasConstantOperation(\n                        opcode, sources.get(1), sources.get(0))) {\n                    /*\n                     * An instruction can be commuted to a literal operation\n                     */\n\n                    insn.setNewSources(\n                            RegisterSpecList.make(\n                                    sources.get(1), sources.get(0)));\n\n                    insn.upgradeToLiteral();\n                }\n            }\n        });\n    }\n\n    /**\n     * Tries to replace an instruction with a const instruction. The given\n     * instruction must have a constant result for it to be replaced.\n     *\n     * @param insn {@code non-null;} instruction to try to replace\n     * @return true if the instruction was replaced\n     */\n    private boolean tryReplacingWithConstant(NormalSsaInsn insn) {\n        Insn originalRopInsn = insn.getOriginalRopInsn();\n        Rop opcode = originalRopInsn.getOpcode();\n        RegisterSpec result = insn.getResult();\n\n        if (result != null && !ssaMeth.isRegALocal(result) &&\n                opcode.getOpcode() != RegOps.CONST) {\n            TypeBearer type = insn.getResult().getTypeBearer();\n            if (type.isConstant() && type.getBasicType() == Type.BT_INT) {\n                // Replace the instruction with a constant\n                replacePlainInsn(insn, RegisterSpecList.EMPTY,\n                        RegOps.CONST, (Constant) type);\n\n                // Remove the source as well if this is a move-result-pseudo\n                if (opcode.getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {\n                    int pred = insn.getBlock().getPredecessors().nextSetBit(0);\n                    ArrayList<SsaInsn> predInsns =\n                            ssaMeth.getBlocks().get(pred).getInsns();\n                    NormalSsaInsn sourceInsn =\n                            (NormalSsaInsn) predInsns.get(predInsns.size()-1);\n                    replacePlainInsn(sourceInsn, RegisterSpecList.EMPTY,\n                            RegOps.GOTO, null);\n                }\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Replaces an SsaInsn containing a PlainInsn with a new PlainInsn. The\n     * new PlainInsn is constructed with a new RegOp and new sources.\n     *\n     * TODO move this somewhere else.\n     *\n     * @param insn {@code non-null;} an SsaInsn containing a PlainInsn\n     * @param newSources {@code non-null;} new sources list for new insn\n     * @param newOpcode A RegOp from {@link RegOps}\n     * @param cst {@code null-ok;} constant for new instruction, if any\n     */\n    private void replacePlainInsn(NormalSsaInsn insn,\n            RegisterSpecList newSources, int newOpcode, Constant cst) {\n\n        Insn originalRopInsn = insn.getOriginalRopInsn();\n        Rop newRop = Rops.ropFor(newOpcode, insn.getResult(), newSources, cst);\n        Insn newRopInsn;\n        if (cst == null) {\n            newRopInsn = new PlainInsn(newRop, originalRopInsn.getPosition(),\n                    insn.getResult(), newSources);\n        } else {\n            newRopInsn = new PlainCstInsn(newRop, originalRopInsn.getPosition(),\n                    insn.getResult(), newSources, cst);\n        }\n        NormalSsaInsn newInsn = new NormalSsaInsn(newRopInsn, insn.getBlock());\n\n        List<SsaInsn> insns = insn.getBlock().getInsns();\n\n        ssaMeth.onInsnRemoved(insn);\n        insns.set(insns.lastIndexOf(insn), newInsn);\n        ssaMeth.onInsnAdded(newInsn);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/LocalVariableExtractor.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecSet;\nimport com.taobao.android.dx.util.IntList;\nimport java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.List;\n\n/**\n * Code to figure out which local variables are active at which points in\n * a method. Stolen and retrofitted from\n * com.taobao.android.dx.rop.code.LocalVariableExtractor\n *\n * TODO remove this. Allow Rop-form LocalVariableInfo to be passed in,\n * converted, and adapted through edge-splitting.\n */\npublic class LocalVariableExtractor {\n    /** {@code non-null;} method being extracted from */\n    private final SsaMethod method;\n\n    /** {@code non-null;} block list for the method */\n    private final ArrayList<SsaBasicBlock> blocks;\n\n    /** {@code non-null;} result in-progress */\n    private final LocalVariableInfo resultInfo;\n\n    /** {@code non-null;} work set indicating blocks needing to be processed */\n    private final BitSet workSet;\n\n    /**\n     * Extracts out all the local variable information from the given method.\n     *\n     * @param method {@code non-null;} the method to extract from\n     * @return {@code non-null;} the extracted information\n     */\n    public static LocalVariableInfo extract(SsaMethod method) {\n        LocalVariableExtractor lve = new LocalVariableExtractor(method);\n        return lve.doit();\n    }\n\n    /**\n     * Constructs an instance. This method is private. Use {@link #extract}.\n     *\n     * @param method {@code non-null;} the method to extract from\n     */\n    private LocalVariableExtractor(SsaMethod method) {\n        if (method == null) {\n            throw new NullPointerException(\"method == null\");\n        }\n\n        ArrayList<SsaBasicBlock> blocks = method.getBlocks();\n\n        this.method = method;\n        this.blocks = blocks;\n        this.resultInfo = new LocalVariableInfo(method);\n        this.workSet = new BitSet(blocks.size());\n    }\n\n    /**\n     * Does the extraction.\n     *\n     * @return {@code non-null;} the extracted information\n     */\n    private LocalVariableInfo doit() {\n\n        //FIXME why is this needed here?\n        if (method.getRegCount() > 0 ) {\n            for (int bi = method.getEntryBlockIndex();\n                 bi >= 0;\n                 bi = workSet.nextSetBit(0)) {\n                workSet.clear(bi);\n                processBlock(bi);\n            }\n        }\n\n        resultInfo.setImmutable();\n        return resultInfo;\n    }\n\n    /**\n     * Processes a single block.\n     *\n     * @param blockIndex {@code >= 0;} block index of the block to process\n     */\n    private void processBlock(int blockIndex) {\n        RegisterSpecSet primaryState\n                = resultInfo.mutableCopyOfStarts(blockIndex);\n        SsaBasicBlock block = blocks.get(blockIndex);\n        List<SsaInsn> insns = block.getInsns();\n        int insnSz = insns.size();\n\n        // The exit block has no insns and no successors\n        if (blockIndex == method.getExitBlockIndex()) {\n            return;\n        }\n\n        /*\n         * We may have to treat the last instruction specially: If it\n         * can (but doesn't always) throw, and the exception can be\n         * caught within the same method, then we need to use the\n         * state *before* executing it to be what is merged into\n         * exception targets.\n         */\n        SsaInsn lastInsn = insns.get(insnSz - 1);\n        boolean hasExceptionHandlers\n                = lastInsn.getOriginalRopInsn().getCatches().size() !=0 ;\n        boolean canThrowDuringLastInsn = hasExceptionHandlers\n                && (lastInsn.getResult() != null);\n        int freezeSecondaryStateAt = insnSz - 1;\n        RegisterSpecSet secondaryState = primaryState;\n\n        /*\n         * Iterate over the instructions, adding information for each place\n         * that the active variable set changes.\n         */\n\n        for (int i = 0; i < insnSz; i++) {\n            if (canThrowDuringLastInsn && (i == freezeSecondaryStateAt)) {\n                // Until this point, primaryState == secondaryState.\n                primaryState.setImmutable();\n                primaryState = primaryState.mutableCopy();\n            }\n\n            SsaInsn insn = insns.get(i);\n            RegisterSpec result;\n\n            result = insn.getLocalAssignment();\n\n            if (result == null) {\n                // We may be nuking an existing local\n\n                result = insn.getResult();\n\n                if (result != null && primaryState.get(result.getReg()) != null) {\n                    primaryState.remove(primaryState.get(result.getReg()));\n                }\n                continue;\n            }\n\n            result = result.withSimpleType();\n\n            RegisterSpec already = primaryState.get(result);\n            /*\n             * The equals() check ensures we only add new info if\n             * the instruction causes a change to the set of\n             * active variables.\n             */\n            if (!result.equals(already)) {\n                /*\n                 * If this insn represents a local moving from one register\n                 * to another, remove the association between the old register\n                 * and the local.\n                 */\n                RegisterSpec previous\n                        = primaryState.localItemToSpec(result.getLocalItem());\n\n                if (previous != null\n                        && (previous.getReg() != result.getReg())) {\n\n                    primaryState.remove(previous);\n                }\n\n                resultInfo.addAssignment(insn, result);\n                primaryState.put(result);\n            }\n        }\n\n        primaryState.setImmutable();\n\n        /*\n         * Merge this state into the start state for each successor,\n         * and update the work set where required (that is, in cases\n         * where the start state for a block changes).\n         */\n\n        IntList successors = block.getSuccessorList();\n        int succSz = successors.size();\n        int primarySuccessor = block.getPrimarySuccessorIndex();\n\n        for (int i = 0; i < succSz; i++) {\n            int succ = successors.get(i);\n            RegisterSpecSet state = (succ == primarySuccessor) ?\n                primaryState : secondaryState;\n\n            if (resultInfo.mergeStarts(succ, state)) {\n                workSet.set(succ);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/LocalVariableInfo.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecSet;\nimport com.taobao.android.dx.util.MutabilityControl;\nimport java.util.HashMap;\nimport java.util.List;\n\n/**\n * Container for local variable information for a particular {@link\n * com.taobao.android.dx.ssa.SsaMethod}.\n * Stolen from {@link com.taobao.android.dx.rop.code.LocalVariableInfo}.\n */\npublic class LocalVariableInfo         extends MutabilityControl {\n    /** {@code >= 0;} the register count for the method */\n    private final int regCount;\n\n    /**\n     * {@code non-null;} {@link com.taobao.android.dx.rop.code.RegisterSpecSet} to use when indicating a block\n     * that has no locals; it is empty and immutable but has an appropriate\n     * max size for the method\n     */\n    private final RegisterSpecSet emptySet;\n\n    /**\n     * {@code non-null;} array consisting of register sets representing the\n     * sets of variables already assigned upon entry to each block,\n     * where array indices correspond to block indices\n     */\n    private final RegisterSpecSet[] blockStarts;\n\n    /** {@code non-null;} map from instructions to the variable each assigns */\n    private final HashMap<SsaInsn, RegisterSpec> insnAssignments;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param method {@code non-null;} the method being represented by this instance\n     */\n    public LocalVariableInfo(SsaMethod method) {\n        if (method == null) {\n            throw new NullPointerException(\"method == null\");\n        }\n\n        List<SsaBasicBlock> blocks = method.getBlocks();\n\n        this.regCount = method.getRegCount();\n        this.emptySet = new RegisterSpecSet(regCount);\n        this.blockStarts = new RegisterSpecSet[blocks.size()];\n        this.insnAssignments =\n            new HashMap<SsaInsn, RegisterSpec>(/*hint here*/);\n\n        emptySet.setImmutable();\n    }\n\n    /**\n     * Sets the register set associated with the start of the block with\n     * the given index.\n     *\n     * @param index {@code >= 0;} the block index\n     * @param specs {@code non-null;} the register set to associate with the block\n     */\n    public void setStarts(int index, RegisterSpecSet specs) {\n        throwIfImmutable();\n\n        if (specs == null) {\n            throw new NullPointerException(\"specs == null\");\n        }\n\n        try {\n            blockStarts[index] = specs;\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"bogus index\");\n        }\n    }\n\n    /**\n     * Merges the given register set into the set for the block with the\n     * given index. If there was not already an associated set, then this\n     * is the same as calling {@link #setStarts}. Otherwise, this will\n     * merge the two sets and call {@link #setStarts} on the result of the\n     * merge.\n     *\n     * @param index {@code >= 0;} the block index\n     * @param specs {@code non-null;} the register set to merge into the start set\n     * for the block\n     * @return {@code true} if the merge resulted in an actual change\n     * to the associated set (including storing one for the first time) or\n     * {@code false} if there was no change\n     */\n    public boolean mergeStarts(int index, RegisterSpecSet specs) {\n        RegisterSpecSet start = getStarts0(index);\n        boolean changed = false;\n\n        if (start == null) {\n            setStarts(index, specs);\n            return true;\n        }\n\n        RegisterSpecSet newStart = start.mutableCopy();\n        newStart.intersect(specs, true);\n\n        if (start.equals(newStart)) {\n            return false;\n        }\n\n        newStart.setImmutable();\n        setStarts(index, newStart);\n\n        return true;\n    }\n\n    /**\n     * Gets the register set associated with the start of the block\n     * with the given index. This returns an empty set with the appropriate\n     * max size if no set was associated with the block in question.\n     *\n     * @param index {@code >= 0;} the block index\n     * @return {@code non-null;} the associated register set\n     */\n    public RegisterSpecSet getStarts(int index) {\n        RegisterSpecSet result = getStarts0(index);\n\n        return (result != null) ? result : emptySet;\n    }\n\n    /**\n     * Gets the register set associated with the start of the given\n     * block. This is just convenient shorthand for\n     * {@code getStarts(block.getLabel())}.\n     *\n     * @param block {@code non-null;} the block in question\n     * @return {@code non-null;} the associated register set\n     */\n    public RegisterSpecSet getStarts(SsaBasicBlock block) {\n        return getStarts(block.getIndex());\n    }\n\n    /**\n     * Gets a mutable copy of the register set associated with the\n     * start of the block with the given index. This returns a\n     * newly-allocated empty {@link RegisterSpecSet} of appropriate\n     * max size if there is not yet any set associated with the block.\n     *\n     * @param index {@code >= 0;} the block index\n     * @return {@code non-null;} the associated register set\n     */\n    public RegisterSpecSet mutableCopyOfStarts(int index) {\n        RegisterSpecSet result = getStarts0(index);\n\n        return (result != null) ?\n            result.mutableCopy() : new RegisterSpecSet(regCount);\n    }\n\n    /**\n     * Adds an assignment association for the given instruction and\n     * register spec. This throws an exception if the instruction\n     * doesn't actually perform a named variable assignment.\n     *\n     * <b>Note:</b> Although the instruction contains its own spec for\n     * the result, it still needs to be passed in explicitly to this\n     * method, since the spec that is stored here should always have a\n     * simple type and the one in the instruction can be an arbitrary\n     * {@link com.taobao.android.dx.rop.type.TypeBearer} (such as a constant value).\n     *\n     * @param insn {@code non-null;} the instruction in question\n     * @param spec {@code non-null;} the associated register spec\n     */\n    public void addAssignment(SsaInsn insn, RegisterSpec spec) {\n        throwIfImmutable();\n\n        if (insn == null) {\n            throw new NullPointerException(\"insn == null\");\n        }\n\n        if (spec == null) {\n            throw new NullPointerException(\"spec == null\");\n        }\n\n        insnAssignments.put(insn, spec);\n    }\n\n    /**\n     * Gets the named register being assigned by the given instruction, if\n     * previously stored in this instance.\n     *\n     * @param insn {@code non-null;} instruction in question\n     * @return {@code null-ok;} the named register being assigned, if any\n     */\n    public RegisterSpec getAssignment(SsaInsn insn) {\n        return insnAssignments.get(insn);\n    }\n\n    /**\n     * Gets the number of assignments recorded by this instance.\n     *\n     * @return {@code >= 0;} the number of assignments\n     */\n    public int getAssignmentCount() {\n        return insnAssignments.size();\n    }\n\n    public void debugDump() {\n        for (int index = 0 ; index < blockStarts.length; index++) {\n            if (blockStarts[index] == null) {\n                continue;\n            }\n\n            if (blockStarts[index] == emptySet) {\n                System.out.printf(\"%04x: empty set\\n\", index);\n            } else {\n                System.out.printf(\"%04x: %s\\n\", index, blockStarts[index]);\n            }\n        }\n    }\n\n    /**\n     * Helper method, to get the starts for a index, throwing the\n     * right exception for range problems.\n     *\n     * @param index {@code >= 0;} the block index\n     * @return {@code null-ok;} associated register set or {@code null} if there\n     * is none\n     */\n    private RegisterSpecSet getStarts0(int index) {\n        try {\n            return blockStarts[index];\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"bogus index\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/MoveParamCombiner.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.CstInsn;\nimport com.taobao.android.dx.rop.code.LocalItem;\nimport com.taobao.android.dx.rop.code.RegOps;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport java.util.HashSet;\nimport java.util.List;\n\n/**\n * Combine identical move-param insns, which may result from Ropper's\n * handling of synchronized methods.\n */\npublic class MoveParamCombiner {\n\n    /** method to process */\n    private final SsaMethod ssaMeth;\n\n    /**\n     * Processes a method with this optimization step.\n     *\n     * @param ssaMethod method to process\n     */\n    public static void process(SsaMethod ssaMethod) {\n        new MoveParamCombiner(ssaMethod).run();\n    }\n\n    private MoveParamCombiner(SsaMethod ssaMeth) {\n        this.ssaMeth = ssaMeth;\n    }\n\n    /**\n     * Runs this optimization step.\n     */\n    private void run() {\n        // This will contain the definition specs for each parameter\n        final RegisterSpec[] paramSpecs\n                = new RegisterSpec[ssaMeth.getParamWidth()];\n\n        // Insns to delete when all done\n        final HashSet<SsaInsn> deletedInsns = new HashSet();\n\n        ssaMeth.forEachInsn(new SsaInsn.Visitor() {\n            public void visitMoveInsn (NormalSsaInsn insn) {\n            }\n            public void visitPhiInsn (PhiInsn phi) {\n            }\n            public void visitNonMoveInsn (NormalSsaInsn insn) {\n                if (insn.getOpcode().getOpcode() != RegOps.MOVE_PARAM) {\n                    return;\n                }\n\n                int param = getParamIndex(insn);\n\n                if (paramSpecs[param] == null) {\n                    paramSpecs[param] = insn.getResult();\n                } else {\n                    final RegisterSpec specA = paramSpecs[param];\n                    final RegisterSpec specB = insn.getResult();\n                    LocalItem localA = specA.getLocalItem();\n                    LocalItem localB = specB.getLocalItem();\n                    LocalItem newLocal;\n\n                    /*\n                     * Is there local information to preserve?\n                     */\n\n                    if (localA == null) {\n                        newLocal = localB;\n                    } else if (localB == null) {\n                        newLocal = localA;\n                    } else if (localA.equals(localB)) {\n                        newLocal = localA;\n                    } else {\n                        /*\n                         * Oddly, these two identical move-params have distinct\n                         * debug info. We'll just keep them distinct.\n                         */\n                        return;\n                    }\n\n                    ssaMeth.getDefinitionForRegister(specA.getReg())\n                            .setResultLocal(newLocal);\n\n                    /*\n                     * Map all uses of specB to specA\n                     */\n\n                    RegisterMapper mapper = new RegisterMapper() {\n                        /** @inheritDoc */\n                        public int getNewRegisterCount() {\n                            return ssaMeth.getRegCount();\n                        }\n\n                        /** @inheritDoc */\n                        public RegisterSpec map(RegisterSpec registerSpec) {\n                            if (registerSpec.getReg() == specB.getReg()) {\n                                return specA;\n                            }\n\n                            return registerSpec;\n                        }\n                    };\n\n                    List<SsaInsn> uses\n                            = ssaMeth.getUseListForRegister(specB.getReg());\n\n                    // Use list is modified by mapSourceRegisters\n                    for (int i = uses.size() - 1; i >= 0; i--) {\n                        SsaInsn use = uses.get(i);\n                        use.mapSourceRegisters(mapper);\n                    }\n\n                    deletedInsns.add(insn);\n                }\n\n            }\n        });\n\n        ssaMeth.deleteInsns(deletedInsns);\n    }\n\n    /**\n     * Returns the parameter index associated with a move-param insn. Does\n     * not verify that the insn is a move-param insn.\n     *\n     * @param insn {@code non-null;} a move-param insn\n     * @return {@code >=0;} parameter index\n     */\n    private int getParamIndex(NormalSsaInsn insn) {\n        CstInsn cstInsn = (CstInsn)(insn.getOriginalRopInsn());\n\n        int param = ((CstInteger)cstInsn.getConstant()).getValue();\n        return param;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/NormalSsaInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.Insn;\nimport com.taobao.android.dx.rop.code.LocalItem;\nimport com.taobao.android.dx.rop.code.RegOps;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rop;\n\n/**\n * A \"normal\" (non-phi) instruction in SSA form. Always wraps a rop insn.\n */\npublic final class NormalSsaInsn extends SsaInsn implements Cloneable {\n    /** {@code non-null;} rop insn that we're wrapping */\n    private Insn insn;\n\n    /**\n     * Creates an instance.\n     *\n     * @param insn Rop insn to wrap\n     * @param block block that contains this insn\n     */\n    NormalSsaInsn(final Insn insn, final SsaBasicBlock block) {\n        super(insn.getResult(), block);\n        this.insn = insn;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final void mapSourceRegisters(RegisterMapper mapper) {\n        RegisterSpecList oldSources = insn.getSources();\n        RegisterSpecList newSources = mapper.map(oldSources);\n\n        if (newSources != oldSources) {\n            insn = insn.withNewRegisters(getResult(), newSources);\n            getBlock().getParent().onSourcesChanged(this, oldSources);\n        }\n    }\n\n    /**\n     * Changes one of the insn's sources. New source should be of same type\n     * and category.\n     *\n     * @param index {@code >=0;} index of source to change\n     * @param newSpec spec for new source\n     */\n    public final void changeOneSource(int index, RegisterSpec newSpec) {\n        RegisterSpecList origSources = insn.getSources();\n        int sz = origSources.size();\n        RegisterSpecList newSources = new RegisterSpecList(sz);\n\n        for (int i = 0; i < sz; i++) {\n            newSources.set(i, i == index ? newSpec : origSources.get(i));\n        }\n\n        newSources.setImmutable();\n\n        RegisterSpec origSpec = origSources.get(index);\n        if (origSpec.getReg() != newSpec.getReg()) {\n            /*\n             * If the register remains unchanged, we're only changing\n             * the type or local var name so don't update use list\n             */\n            getBlock().getParent().onSourceChanged(this, origSpec, newSpec);\n        }\n\n        insn = insn.withNewRegisters(getResult(), newSources);\n    }\n\n    /**\n     * Changes the source list of the insn. New source list should be the\n     * same size and consist of sources of identical types.\n     *\n     * @param newSources non-null new sources list.\n     */\n    public final void setNewSources (RegisterSpecList newSources) {\n        RegisterSpecList origSources = insn.getSources();\n\n        if (origSources.size() != newSources.size()) {\n            throw new RuntimeException(\"Sources counts don't match\");\n        }\n\n        insn = insn.withNewRegisters(getResult(), newSources);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public NormalSsaInsn clone() {\n        return (NormalSsaInsn) super.clone();\n    }\n\n    /**\n     * Like rop.Insn.getSources().\n     *\n     * @return {@code null-ok;} sources list\n     */\n    @Override\n    public RegisterSpecList getSources() {\n        return insn.getSources();\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return toRopInsn().toHuman();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn toRopInsn() {\n        return insn.withNewRegisters(getResult(), insn.getSources());\n    }\n\n    /**\n     * @return the Rop opcode for this insn\n     */\n    @Override\n    public Rop getOpcode() {\n        return insn.getOpcode();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public Insn getOriginalRopInsn() {\n        return insn;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public RegisterSpec getLocalAssignment() {\n        RegisterSpec assignment;\n\n        if (insn.getOpcode().getOpcode() == RegOps.MARK_LOCAL) {\n            assignment = insn.getSources().get(0);\n        } else {\n            assignment = getResult();\n        }\n\n        if (assignment == null) {\n            return null;\n        }\n\n        LocalItem local = assignment.getLocalItem();\n\n        if (local == null) {\n            return null;\n        }\n\n        return assignment;\n    }\n\n    /**\n     * Upgrades this insn to a version that represents the constant source\n     * literally. If the upgrade is not possible, this does nothing.\n     *\n     * @see Insn#withSourceLiteral\n     */\n    public void upgradeToLiteral() {\n        RegisterSpecList oldSources = insn.getSources();\n\n        insn = insn.withSourceLiteral();\n        getBlock().getParent().onSourcesChanged(this, oldSources);\n    }\n\n    /**\n     * @return true if this is a move (but not a move-operand) instruction\n     */\n    @Override\n    public boolean isNormalMoveInsn() {\n        return insn.getOpcode().getOpcode() == RegOps.MOVE;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isMoveException() {\n        return insn.getOpcode().getOpcode() == RegOps.MOVE_EXCEPTION;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean canThrow() {\n        return insn.canThrow();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void accept(Visitor v) {\n        if (isNormalMoveInsn()) {\n            v.visitMoveInsn(this);\n        } else {\n            v.visitNonMoveInsn(this);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public  boolean isPhiOrMove() {\n        return isNormalMoveInsn();\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * TODO: Increase the scope of this.\n     */\n    @Override\n    public boolean hasSideEffect() {\n        Rop opcode = getOpcode();\n\n        if (opcode.getBranchingness() != Rop.BRANCH_NONE) {\n            return true;\n        }\n\n        boolean hasLocalSideEffect\n            = Optimizer.getPreserveLocals() && getLocalAssignment() != null;\n\n        switch (opcode.getOpcode()) {\n            case RegOps.MOVE_RESULT:\n            case RegOps.MOVE:\n            case RegOps.CONST:\n                return hasLocalSideEffect;\n            default:\n                return true;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/Optimizer.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.rop.code.TranslationAdvice;\nimport com.taobao.android.dx.ssa.back.LivenessAnalyzer;\nimport com.taobao.android.dx.ssa.back.SsaToRop;\nimport java.util.EnumSet;\n\n/**\n * Runs a method through the SSA form conversion, any optimization algorithms,\n * and returns it to rop form.\n */\npublic class Optimizer {\n    private static boolean preserveLocals = true;\n\n    private static TranslationAdvice advice;\n\n    /** optional optimizer steps */\n    public enum OptionalStep {\n        MOVE_PARAM_COMBINER, SCCP, LITERAL_UPGRADE, CONST_COLLECTOR,\n            ESCAPE_ANALYSIS\n    }\n\n    /**\n     * @return true if local variable information should be preserved, even\n     * at code size/register size cost\n     */\n    public static boolean getPreserveLocals() {\n        return preserveLocals;\n    }\n\n    /**\n     * @return {@code non-null;} translation advice\n     */\n    public static TranslationAdvice getAdvice() {\n        return advice;\n    }\n\n    /**\n     * Runs optimization algorthims over this method, and returns a new\n     * instance of RopMethod with the changes.\n     *\n     * @param rmeth method to process\n     * @param paramWidth the total width, in register-units, of this method's\n     * parameters\n     * @param isStatic true if this method has no 'this' pointer argument.\n     * @param inPreserveLocals true if local variable info should be preserved,\n     * at the cost of some registers and insns\n     * @param inAdvice {@code non-null;} translation advice\n     * @return optimized method\n     */\n    public static RopMethod optimize(RopMethod rmeth, int paramWidth,\n            boolean isStatic, boolean inPreserveLocals,\n            TranslationAdvice inAdvice) {\n\n        return optimize(rmeth, paramWidth, isStatic, inPreserveLocals, inAdvice,\n                EnumSet.allOf(OptionalStep.class));\n    }\n\n    /**\n     * Runs optimization algorthims over this method, and returns a new\n     * instance of RopMethod with the changes.\n     *\n     * @param rmeth method to process\n     * @param paramWidth the total width, in register-units, of this method's\n     * parameters\n     * @param isStatic true if this method has no 'this' pointer argument.\n     * @param inPreserveLocals true if local variable info should be preserved,\n     * at the cost of some registers and insns\n     * @param inAdvice {@code non-null;} translation advice\n     * @param steps set of optional optimization steps to run\n     * @return optimized method\n     */\n    public static RopMethod optimize(RopMethod rmeth, int paramWidth,\n            boolean isStatic, boolean inPreserveLocals,\n            TranslationAdvice inAdvice, EnumSet<OptionalStep> steps) {\n        SsaMethod ssaMeth = null;\n\n        preserveLocals = inPreserveLocals;\n        advice = inAdvice;\n\n        ssaMeth = SsaConverter.convertToSsaMethod(rmeth, paramWidth, isStatic);\n        runSsaFormSteps(ssaMeth, steps);\n\n        RopMethod resultMeth = SsaToRop.convertToRopMethod(ssaMeth, false);\n\n        if (resultMeth.getBlocks().getRegCount()\n                > advice.getMaxOptimalRegisterCount()) {\n            // Try to see if we can squeeze it under the register count bar\n            resultMeth = optimizeMinimizeRegisters(rmeth, paramWidth, isStatic,\n                    steps);\n        }\n        return resultMeth;\n    }\n\n    /**\n     * Runs the optimizer with a strategy to minimize the number of rop-form\n     * registers used by the end result. Dex bytecode does not have instruction\n     * forms that take register numbers larger than 15 for all instructions.\n     * If we've produced a method that uses more than 16 registers, try again\n     * with a different strategy to see if we can get under the bar. The end\n     * result will be much more efficient.\n     *\n     * @param rmeth method to process\n     * @param paramWidth the total width, in register-units, of this method's\n     * parameters\n     * @param isStatic true if this method has no 'this' pointer argument.\n     * @param steps set of optional optimization steps to run\n     * @return optimized method\n     */\n    private static RopMethod optimizeMinimizeRegisters(RopMethod rmeth,\n            int paramWidth, boolean isStatic,\n            EnumSet<OptionalStep> steps) {\n        SsaMethod ssaMeth;\n        RopMethod resultMeth;\n\n        ssaMeth = SsaConverter.convertToSsaMethod(\n                rmeth, paramWidth, isStatic);\n\n        EnumSet<OptionalStep> newSteps = steps.clone();\n\n        /*\n         * CONST_COLLECTOR trades insns for registers, which is not an\n         * appropriate strategy here.\n         */\n        newSteps.remove(OptionalStep.CONST_COLLECTOR);\n\n        runSsaFormSteps(ssaMeth, newSteps);\n\n        resultMeth = SsaToRop.convertToRopMethod(ssaMeth, true);\n        return resultMeth;\n    }\n\n    private static void runSsaFormSteps(SsaMethod ssaMeth,\n            EnumSet<OptionalStep> steps) {\n        boolean needsDeadCodeRemover = true;\n\n        if (steps.contains(OptionalStep.MOVE_PARAM_COMBINER)) {\n            MoveParamCombiner.process(ssaMeth);\n        }\n\n        if (steps.contains(OptionalStep.SCCP)) {\n            SCCP.process(ssaMeth);\n            DeadCodeRemover.process(ssaMeth);\n            needsDeadCodeRemover = false;\n        }\n\n        if (steps.contains(OptionalStep.LITERAL_UPGRADE)) {\n            LiteralOpUpgrader.process(ssaMeth);\n            DeadCodeRemover.process(ssaMeth);\n            needsDeadCodeRemover = false;\n        }\n\n        /*\n         * ESCAPE_ANALYSIS impacts debuggability, so left off by default\n         */\n        steps.remove(OptionalStep.ESCAPE_ANALYSIS);\n        if (steps.contains(OptionalStep.ESCAPE_ANALYSIS)) {\n            EscapeAnalysis.process(ssaMeth);\n            DeadCodeRemover.process(ssaMeth);\n            needsDeadCodeRemover = false;\n        }\n\n        if (steps.contains(OptionalStep.CONST_COLLECTOR)) {\n            ConstCollector.process(ssaMeth);\n            DeadCodeRemover.process(ssaMeth);\n            needsDeadCodeRemover = false;\n        }\n\n        // dead code remover must be run before phi type resolver\n        if (needsDeadCodeRemover) {\n            DeadCodeRemover.process(ssaMeth);\n        }\n\n        PhiTypeResolver.process(ssaMeth);\n    }\n\n    public static SsaMethod debugEdgeSplit(RopMethod rmeth, int paramWidth,\n            boolean isStatic, boolean inPreserveLocals,\n            TranslationAdvice inAdvice) {\n\n        preserveLocals = inPreserveLocals;\n        advice = inAdvice;\n\n        return SsaConverter.testEdgeSplit(rmeth, paramWidth, isStatic);\n    }\n\n    public static SsaMethod debugPhiPlacement(RopMethod rmeth, int paramWidth,\n            boolean isStatic, boolean inPreserveLocals,\n            TranslationAdvice inAdvice) {\n\n        preserveLocals = inPreserveLocals;\n        advice = inAdvice;\n\n        return SsaConverter.testPhiPlacement(rmeth, paramWidth, isStatic);\n    }\n\n    public static SsaMethod debugRenaming(RopMethod rmeth, int paramWidth,\n            boolean isStatic, boolean inPreserveLocals,\n            TranslationAdvice inAdvice) {\n\n        preserveLocals = inPreserveLocals;\n        advice = inAdvice;\n\n        return SsaConverter.convertToSsaMethod(rmeth, paramWidth, isStatic);\n    }\n\n    public static SsaMethod debugDeadCodeRemover(RopMethod rmeth,\n            int paramWidth, boolean isStatic, boolean inPreserveLocals,\n            TranslationAdvice inAdvice) {\n\n        SsaMethod ssaMeth;\n\n        preserveLocals = inPreserveLocals;\n        advice = inAdvice;\n\n        ssaMeth = SsaConverter.convertToSsaMethod(rmeth, paramWidth, isStatic);\n        DeadCodeRemover.process(ssaMeth);\n\n        return ssaMeth;\n    }\n\n    public static SsaMethod debugNoRegisterAllocation(RopMethod rmeth,\n            int paramWidth, boolean isStatic, boolean inPreserveLocals,\n            TranslationAdvice inAdvice, EnumSet<OptionalStep> steps) {\n\n        SsaMethod ssaMeth;\n\n        preserveLocals = inPreserveLocals;\n        advice = inAdvice;\n\n        ssaMeth = SsaConverter.convertToSsaMethod(rmeth, paramWidth, isStatic);\n\n        runSsaFormSteps(ssaMeth, steps);\n\n        LivenessAnalyzer.constructInterferenceGraph(ssaMeth);\n\n        return ssaMeth;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/PhiInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.Insn;\nimport com.taobao.android.dx.rop.code.LocalItem;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rop;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport com.taobao.android.dx.util.Hex;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * A Phi instruction (magical post-control-flow-merge) instruction\n * in SSA form. Will be converted to moves in predecessor blocks before\n * conversion back to ROP form.\n */\npublic final class PhiInsn extends SsaInsn {\n    /**\n     * result register. The original result register of the phi insn\n     * is needed during the renaming process after the new result\n     * register has already been chosen.\n     */\n    private final int ropResultReg;\n\n    /**\n     * {@code non-null;} operands of the instruction; built up by\n     * {@link #addPhiOperand}\n     */\n    private final ArrayList<Operand> operands = new ArrayList<Operand>();\n\n    /** {@code null-ok;} source registers; constructed lazily */\n    private RegisterSpecList sources;\n\n    /**\n     * Constructs a new phi insn with no operands.\n     *\n     * @param resultReg the result reg for this phi insn\n     * @param block block containing this insn.\n     */\n    public PhiInsn(RegisterSpec resultReg, SsaBasicBlock block) {\n        super(resultReg, block);\n        ropResultReg = resultReg.getReg();\n    }\n\n    /**\n     * Makes a phi insn with a void result type.\n     *\n     * @param resultReg the result register for this phi insn.\n     * @param block block containing this insn.\n     */\n    public PhiInsn(final int resultReg, final SsaBasicBlock block) {\n        /*\n         * The result type here is bogus: The type depends on the\n         * operand and will be derived later.\n         */\n        super(RegisterSpec.make(resultReg, Type.VOID), block);\n        ropResultReg = resultReg;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public PhiInsn clone() {\n        throw new UnsupportedOperationException(\"can't clone phi\");\n    }\n\n    /**\n     * Updates the TypeBearers of all the sources (phi operands) to be\n     * the current TypeBearer of the register-defining instruction's result.\n     * This is used during phi-type resolution.<p>\n     *\n     * Note that local association of operands are preserved in this step.\n     *\n     * @param ssaMeth method that contains this insn\n     */\n    public void updateSourcesToDefinitions(SsaMethod ssaMeth) {\n        for (Operand o : operands) {\n            RegisterSpec def\n                = ssaMeth.getDefinitionForRegister(\n                    o.regSpec.getReg()).getResult();\n\n            o.regSpec = o.regSpec.withType(def.getType());\n        }\n\n        sources = null;\n    }\n\n    /**\n     * Changes the result type. Used during phi type resolution\n     *\n     * @param type {@code non-null;} new TypeBearer\n     * @param local {@code null-ok;} new local info, if available\n     */\n    public void changeResultType(TypeBearer type, LocalItem local) {\n        setResult(RegisterSpec.makeLocalOptional(\n                          getResult().getReg(), type, local));\n    }\n\n    /**\n     * Gets the original rop-form result reg. This is useful during renaming.\n     *\n     * @return the original rop-form result reg\n     */\n    public int getRopResultReg() {\n        return ropResultReg;\n    }\n\n    /**\n     * Adds an operand to this phi instruction.\n     *\n     * @param registerSpec register spec, including type and reg of operand\n     * @param predBlock predecessor block to be associated with this operand\n     */\n    public void addPhiOperand(RegisterSpec registerSpec,\n            SsaBasicBlock predBlock) {\n        operands.add(new Operand(registerSpec, predBlock.getIndex(),\n                predBlock.getRopLabel()));\n\n        // Un-cache sources, in case someone has already called getSources().\n        sources = null;\n    }\n\n    /**\n     * Removes all operand uses of a register from this phi instruction.\n     *\n     * @param registerSpec register spec, including type and reg of operand\n     */\n    public void removePhiRegister(RegisterSpec registerSpec) {\n        ArrayList<Operand> operandsToRemove = new ArrayList<Operand>();\n        for (Operand o : operands) {\n            if (o.regSpec.getReg() == registerSpec.getReg()) {\n                operandsToRemove.add(o);\n            }\n        }\n\n        operands.removeAll(operandsToRemove);\n\n        // Un-cache sources, in case someone has already called getSources().\n        sources = null;\n    }\n\n    /**\n     * Gets the index of the pred block associated with the RegisterSpec\n     * at the particular getSources() index.\n     *\n     * @param sourcesIndex index of source in getSources()\n     * @return block index\n     */\n    public int predBlockIndexForSourcesIndex(int sourcesIndex) {\n        return operands.get(sourcesIndex).blockIndex;\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * Always returns null for {@code PhiInsn}s.\n     */\n    @Override\n    public Rop getOpcode() {\n        return null;\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * Always returns null for {@code PhiInsn}s.\n     */\n    @Override\n    public Insn getOriginalRopInsn() {\n        return null;\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * Always returns false for {@code PhiInsn}s.\n     */\n    @Override\n    public boolean canThrow() {\n        return false;\n    }\n\n    /**\n     * Gets sources. Constructed lazily from phi operand data structures and\n     * then cached.\n     *\n     * @return {@code non-null;} sources list\n     */\n    @Override\n    public RegisterSpecList getSources() {\n        if (sources != null) {\n            return sources;\n        }\n\n        if (operands.size() == 0) {\n            // How'd this happen? A phi insn with no operand?\n            return RegisterSpecList.EMPTY;\n        }\n\n        int szSources = operands.size();\n        sources = new RegisterSpecList(szSources);\n\n        for (int i = 0; i < szSources; i++) {\n            Operand o = operands.get(i);\n\n            sources.set(i, o.regSpec);\n        }\n\n        sources.setImmutable();\n        return sources;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isRegASource(int reg) {\n        /*\n         * Avoid creating a sources list in case it has not already been\n         * created.\n         */\n\n        for (Operand o : operands) {\n            if (o.regSpec.getReg() == reg) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * @return true if all operands use the same register\n     */\n    public boolean areAllOperandsEqual() {\n        if (operands.size() == 0 ) {\n            // This should never happen.\n            return true;\n        }\n\n        int firstReg = operands.get(0).regSpec.getReg();\n        for (Operand o : operands) {\n            if (firstReg != o.regSpec.getReg()) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public final void mapSourceRegisters(RegisterMapper mapper) {\n        for (Operand o : operands) {\n            RegisterSpec old = o.regSpec;\n            o.regSpec = mapper.map(old);\n            if (old != o.regSpec) {\n                getBlock().getParent().onSourceChanged(this, old, o.regSpec);\n            }\n        }\n        sources = null;\n    }\n\n    /**\n     * Always throws an exeption, since a phi insn may not be\n     * converted back to rop form.\n     *\n     * @return always throws exception\n     */\n    @Override\n    public Insn toRopInsn() {\n        throw new IllegalArgumentException(\n                \"Cannot convert phi insns to rop form\");\n    }\n\n    /**\n     * Returns the list of predecessor blocks associated with all operands\n     * that have {@code reg} as an operand register.\n     *\n     * @param reg register to look up\n     * @param ssaMeth method we're operating on\n     * @return list of predecessor blocks, empty if none\n     */\n    public List<SsaBasicBlock> predBlocksForReg(int reg, SsaMethod ssaMeth) {\n        ArrayList<SsaBasicBlock> ret = new ArrayList<SsaBasicBlock>();\n\n        for (Operand o : operands) {\n            if (o.regSpec.getReg() == reg) {\n                ret.add(ssaMeth.getBlocks().get(o.blockIndex));\n            }\n        }\n\n        return ret;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean isPhiOrMove() {\n        return true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean hasSideEffect() {\n        return Optimizer.getPreserveLocals() && getLocalAssignment() != null;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void accept(SsaInsn.Visitor v) {\n        v.visitPhiInsn(this);\n    }\n\n    /** {@inheritDoc} */\n    public String toHuman() {\n        return toHumanWithInline(null);\n    }\n\n    /**\n     * Returns human-readable string for listing dumps. This method\n     * allows sub-classes to specify extra text.\n     *\n     * @param extra {@code null-ok;} the argument to print after the opcode\n     * @return human-readable string for listing dumps\n     */\n    protected final String toHumanWithInline(String extra) {\n        StringBuffer sb = new StringBuffer(80);\n\n        sb.append(SourcePosition.NO_INFO);\n        sb.append(\": phi\");\n\n        if (extra != null) {\n            sb.append(\"(\");\n            sb.append(extra);\n            sb.append(\")\");\n        }\n\n        RegisterSpec result = getResult();\n\n        if (result == null) {\n            sb.append(\" .\");\n        } else {\n            sb.append(\" \");\n            sb.append(result.toHuman());\n        }\n\n        sb.append(\" <-\");\n\n        int sz = getSources().size();\n        if (sz == 0) {\n            sb.append(\" .\");\n        } else {\n            for (int i = 0; i < sz; i++) {\n                sb.append(\" \");\n                sb.append(sources.get(i).toHuman()\n                        + \"[b=\"\n                        + Hex.u2(operands.get(i).ropLabel)  + \"]\");\n            }\n        }\n\n        return sb.toString();\n    }\n\n    /**\n     * A single phi operand, consiting of source register and block index\n     * for move.\n     */\n    private static class Operand {\n        public RegisterSpec regSpec;\n        public final int blockIndex;\n        public final int ropLabel;       // only used for debugging\n\n        public Operand(RegisterSpec regSpec, int blockIndex, int ropLabel) {\n            this.regSpec = regSpec;\n            this.blockIndex = blockIndex;\n            this.ropLabel = ropLabel;\n        }\n    }\n\n    /**\n     * Visitor interface for instances of this (outer) class.\n     */\n    public static interface Visitor {\n        public void visitPhiInsn(PhiInsn insn);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/PhiTypeResolver.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.cf.code.Merger;\nimport com.taobao.android.dx.rop.code.LocalItem;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport java.util.BitSet;\nimport java.util.List;\n\n/**\n * Resolves the result types of phi instructions. When phi instructions\n * are inserted, their result types are set to BT_VOID (which is a nonsensical\n * type for a register) but must be resolve to a real type before converting\n * out of SSA form.<p>\n *\n * The resolve is done as an iterative merge of each phi's operand types.\n * Phi operands may be themselves be the result of unresolved phis,\n * and the algorithm tries to find the most-fit type (for example, if every\n * operand is the same constant value or the same local variable info, we want\n * that to be reflected).<p>\n *\n * This algorithm assumes a dead-code remover has already removed all\n * circular-only phis that may have been inserted.\n */\npublic class PhiTypeResolver {\n\n    SsaMethod ssaMeth;\n    /** indexed by register; all registers still defined by unresolved phis */\n    private final BitSet worklist;\n\n    /**\n     * Resolves all phi types in the method\n     * @param ssaMeth method to process\n     */\n    public static void process (SsaMethod ssaMeth) {\n        new PhiTypeResolver(ssaMeth).run();\n    }\n\n    private PhiTypeResolver(SsaMethod ssaMeth) {\n        this.ssaMeth = ssaMeth;\n        worklist = new BitSet(ssaMeth.getRegCount());\n    }\n\n    /**\n     * Runs the phi-type resolver.\n     */\n    private void run() {\n\n        int regCount = ssaMeth.getRegCount();\n\n        for (int reg = 0; reg < regCount; reg++) {\n            SsaInsn definsn = ssaMeth.getDefinitionForRegister(reg);\n\n            if (definsn != null\n                    && (definsn.getResult().getBasicType() == Type.BT_VOID)) {\n                worklist.set(reg);\n            }\n        }\n\n        int reg;\n        while ( 0 <= (reg = worklist.nextSetBit(0))) {\n            worklist.clear(reg);\n\n            /*\n             * definitions on the worklist have a type of BT_VOID, which\n             * must have originated from a PhiInsn.\n             */\n            PhiInsn definsn = (PhiInsn)ssaMeth.getDefinitionForRegister(reg);\n\n            if (resolveResultType(definsn)) {\n                /*\n                 * If the result type has changed, re-resolve all phis\n                 * that use this.\n                 */\n\n                List<SsaInsn> useList = ssaMeth.getUseListForRegister(reg);\n\n                int sz = useList.size();\n                for (int i = 0; i < sz; i++ ) {\n                    SsaInsn useInsn = useList.get(i);\n                    RegisterSpec resultReg = useInsn.getResult();\n                    if (resultReg != null && useInsn instanceof PhiInsn) {\n                        worklist.set(resultReg.getReg());\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * Returns true if a and b are equal, whether\n     * or not either of them are null.\n     * @param a\n     * @param b\n     * @return true if equal\n     */\n    private static boolean equalsHandlesNulls(LocalItem a, LocalItem b) {\n        return (a == b) || ((a != null) && a.equals(b));\n    }\n\n    /**\n     * Resolves the result of a phi insn based on its operands. The \"void\"\n     * type, which is a nonsensical type for a register, is used for\n     * registers defined by as-of-yet-unresolved phi operations.\n     *\n     * @return true if the result type changed, false if no change\n     */\n    boolean resolveResultType(PhiInsn insn) {\n        insn.updateSourcesToDefinitions(ssaMeth);\n\n        RegisterSpecList sources = insn.getSources();\n\n        // Start by finding the first non-void operand\n        RegisterSpec first = null;\n        int firstIndex = -1;\n\n        int szSources = sources.size();\n        for (int i = 0 ; i <szSources ; i++) {\n            RegisterSpec rs = sources.get(i);\n\n            if (rs.getBasicType() != Type.BT_VOID) {\n                first = rs;\n                firstIndex = i;\n            }\n        }\n\n        if (first == null) {\n            // All operands are void -- we're not ready to resolve yet\n            return false;\n        }\n\n        LocalItem firstLocal = first.getLocalItem();\n        TypeBearer mergedType = first.getType();\n        boolean sameLocals = true;\n        for (int i = 0 ; i < szSources ; i++) {\n            if (i == firstIndex) {\n                continue;\n            }\n\n            RegisterSpec rs = sources.get(i);\n\n            // Just skip void (unresolved phi results) for now\n            if (rs.getBasicType() == Type.BT_VOID){\n                continue;\n            }\n\n            sameLocals = sameLocals\n                    && equalsHandlesNulls(firstLocal, rs.getLocalItem());\n\n            mergedType = Merger.mergeType(mergedType, rs.getType());\n        }\n\n        TypeBearer newResultType;\n\n        if (mergedType != null) {\n            newResultType = mergedType;\n        } else {\n            StringBuilder sb = new StringBuilder();\n\n            for (int i = 0; i < szSources; i++) {\n                sb.append(sources.get(i).toString());\n                sb.append(' ');\n            }\n\n            throw new RuntimeException (\"Couldn't map types in phi insn:\" + sb);\n        }\n\n        LocalItem newLocal = sameLocals ? firstLocal : null;\n\n        RegisterSpec result = insn.getResult();\n\n        if ((result.getTypeBearer() == newResultType)\n                && equalsHandlesNulls(newLocal, result.getLocalItem())) {\n            return false;\n        }\n\n        insn.changeResultType(newResultType, newLocal);\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/RegisterMapper.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.RegisterSpecSet;\n\n/**\n * Represents a mapping between two register numbering schemes.\n * Subclasses of this may be mutable, and as such the mapping provided\n * is only valid for the lifetime of the method call in which\n * instances of this class are passed.\n */\npublic abstract class RegisterMapper {\n    /**\n     * Gets the count of registers (really, the total register width, since\n     * category width is counted) in the new namespace.\n     * @return >= 0 width of new namespace.\n     */\n    public abstract int getNewRegisterCount();\n\n    /**\n     * @param registerSpec old register\n     * @return register in new space\n     */\n    public abstract RegisterSpec map(RegisterSpec registerSpec);\n\n    /**\n     *\n     * @param sources old register list\n     * @return new mapped register list, or old if nothing has changed.\n     */\n    public final RegisterSpecList map(RegisterSpecList sources) {\n        int sz = sources.size();\n        RegisterSpecList newSources = new RegisterSpecList(sz);\n\n        for (int i = 0; i < sz; i++) {\n            newSources.set(i, map(sources.get(i)));\n        }\n\n        newSources.setImmutable();\n\n        // Return the old sources if nothing has changed.\n        return newSources.equals(sources) ? sources : newSources;\n    }\n\n    /**\n     *\n     * @param sources old register set\n     * @return new mapped register set, or old if nothing has changed.\n     */\n    public final RegisterSpecSet map(RegisterSpecSet sources) {\n        int sz = sources.getMaxSize();\n        RegisterSpecSet newSources = new RegisterSpecSet(getNewRegisterCount());\n\n        for (int i = 0; i < sz; i++) {\n            RegisterSpec registerSpec = sources.get(i);\n            if (registerSpec != null) {\n                newSources.put(map(registerSpec));\n            }\n        }\n\n        newSources.setImmutable();\n\n        // Return the old sources if nothing has changed.\n        return newSources.equals(sources) ? sources : newSources;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/SCCP.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.CstInsn;\nimport com.taobao.android.dx.rop.code.Insn;\nimport com.taobao.android.dx.rop.code.PlainInsn;\nimport com.taobao.android.dx.rop.code.RegOps;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rop;\nimport com.taobao.android.dx.rop.code.Rops;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.rop.cst.TypedConstant;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.rop.type.TypeBearer;\nimport java.util.ArrayList;\nimport java.util.BitSet;\n\n/**\n * A small variant of Wegman and Zadeck's Sparse Conditional Constant\n * Propagation algorithm.\n */\npublic class SCCP {\n    /** Lattice values  */\n    private static final int TOP = 0;\n    private static final int CONSTANT = 1;\n    private static final int VARYING = 2;\n    /** method we're processing */\n    private SsaMethod ssaMeth;\n    /** ssaMeth.getRegCount() */\n    private int regCount;\n    /** Lattice values for each SSA register */\n    private int[] latticeValues;\n    /** For those registers that are constant, this is the constant value */\n    private Constant[] latticeConstants;\n    /** Worklist of basic blocks to be processed */\n    private ArrayList<SsaBasicBlock> cfgWorklist;\n    /** Worklist of executed basic blocks with phis to be processed */\n    private ArrayList<SsaBasicBlock> cfgPhiWorklist;\n    /** Bitset containing bits for each block that has been found executable */\n    private BitSet executableBlocks;\n    /** Worklist for SSA edges.  This is a list of registers to process */\n    private ArrayList<SsaInsn> ssaWorklist;\n    /**\n     * Worklist for SSA edges that represent varying values.  It makes the\n     * algorithm much faster if you move all values to VARYING as fast as\n     * possible.\n     */\n    private ArrayList<SsaInsn> varyingWorklist;\n    /** Worklist of potential branches to convert to gotos */\n    private ArrayList<SsaInsn> branchWorklist;\n\n    private SCCP(SsaMethod ssaMeth) {\n        this.ssaMeth = ssaMeth;\n        this.regCount = ssaMeth.getRegCount();\n        this.latticeValues = new int[this.regCount];\n        this.latticeConstants = new Constant[this.regCount];\n        this.cfgWorklist = new ArrayList<SsaBasicBlock>();\n        this.cfgPhiWorklist = new ArrayList<SsaBasicBlock>();\n        this.executableBlocks = new BitSet(ssaMeth.getBlocks().size());\n        this.ssaWorklist = new ArrayList<SsaInsn>();\n        this.varyingWorklist = new ArrayList<SsaInsn>();\n        this.branchWorklist = new ArrayList<SsaInsn>();\n        for (int i = 0; i < this.regCount; i++) {\n            latticeValues[i] = TOP;\n            latticeConstants[i] = null;\n        }\n    }\n\n    /**\n     * Performs sparse conditional constant propagation on a method.\n     * @param ssaMethod Method to process\n     */\n    public static void process (SsaMethod ssaMethod) {\n        new SCCP(ssaMethod).run();\n    }\n\n    /**\n     * Adds a SSA basic block to the CFG worklist if it's unexecuted, or\n     * to the CFG phi worklist if it's already executed.\n     * @param ssaBlock Block to add\n     */\n    private void addBlockToWorklist(SsaBasicBlock ssaBlock) {\n        if (!executableBlocks.get(ssaBlock.getIndex())) {\n            cfgWorklist.add(ssaBlock);\n            executableBlocks.set(ssaBlock.getIndex());\n        } else {\n            cfgPhiWorklist.add(ssaBlock);\n        }\n    }\n\n    /**\n     * Adds an SSA register's uses to the SSA worklist.\n     * @param reg SSA register\n     * @param latticeValue new lattice value for @param reg.\n     */\n    private void addUsersToWorklist(int reg, int latticeValue) {\n        if (latticeValue == VARYING) {\n            for (SsaInsn insn : ssaMeth.getUseListForRegister(reg)) {\n                varyingWorklist.add(insn);\n            }\n        } else {\n            for (SsaInsn insn : ssaMeth.getUseListForRegister(reg)) {\n                ssaWorklist.add(insn);\n            }\n        }\n    }\n\n    /**\n     * Sets a lattice value for a register to value.\n     * @param reg SSA register\n     * @param value Lattice value\n     * @param cst Constant value (may be null)\n     * @return true if the lattice value changed.\n     */\n    private boolean setLatticeValueTo(int reg, int value, Constant cst) {\n        if (value != CONSTANT) {\n            if (latticeValues[reg] != value) {\n                latticeValues[reg] = value;\n                return true;\n            }\n            return false;\n        } else {\n            if (latticeValues[reg] != value\n                    || !latticeConstants[reg].equals(cst)) {\n                latticeValues[reg] = value;\n                latticeConstants[reg] = cst;\n                return true;\n            }\n            return false;\n        }\n    }\n\n    /**\n     * Simulates a PHI node and set the lattice for the result\n     * to the appropriate value.\n     * Meet values:\n     * TOP x anything = TOP\n     * VARYING x anything = VARYING\n     * CONSTANT x CONSTANT = CONSTANT if equal constants, VARYING otherwise\n     * @param insn PHI to simulate.\n     */\n    private void simulatePhi(PhiInsn insn) {\n        int phiResultReg = insn.getResult().getReg();\n\n        if (latticeValues[phiResultReg] == VARYING) {\n            return;\n        }\n\n        RegisterSpecList sources = insn.getSources();\n        int phiResultValue = TOP;\n        Constant phiConstant = null;\n        int sourceSize = sources.size();\n\n        for (int i = 0; i < sourceSize; i++) {\n            int predBlockIndex = insn.predBlockIndexForSourcesIndex(i);\n            int sourceReg = sources.get(i).getReg();\n            int sourceRegValue = latticeValues[sourceReg];\n\n            if (!executableBlocks.get(predBlockIndex)) {\n                continue;\n            }\n\n            if (sourceRegValue == CONSTANT) {\n                if (phiConstant == null) {\n                    phiConstant = latticeConstants[sourceReg];\n                    phiResultValue = CONSTANT;\n                 } else if (!latticeConstants[sourceReg].equals(phiConstant)){\n                    phiResultValue = VARYING;\n                    break;\n                }\n            } else {\n                phiResultValue = sourceRegValue;\n                break;\n            }\n        }\n        if (setLatticeValueTo(phiResultReg, phiResultValue, phiConstant)) {\n            addUsersToWorklist(phiResultReg, phiResultValue);\n        }\n    }\n\n    /**\n     * Simulate a block and note the results in the lattice.\n     * @param block Block to visit\n     */\n    private void simulateBlock(SsaBasicBlock block) {\n        for (SsaInsn insn : block.getInsns()) {\n            if (insn instanceof PhiInsn) {\n                simulatePhi((PhiInsn) insn);\n            } else {\n                simulateStmt(insn);\n            }\n        }\n    }\n\n    /**\n     * Simulate the phis in a block and note the results in the lattice.\n     * @param block Block to visit\n     */\n    private void simulatePhiBlock(SsaBasicBlock block) {\n        for (SsaInsn insn : block.getInsns()) {\n            if (insn instanceof PhiInsn) {\n                simulatePhi((PhiInsn) insn);\n            } else {\n                return;\n            }\n        }\n    }\n\n    private static String latticeValName(int latticeVal) {\n        switch (latticeVal) {\n            case TOP: return \"TOP\";\n            case CONSTANT: return \"CONSTANT\";\n            case VARYING: return \"VARYING\";\n            default: return \"UNKNOWN\";\n        }\n    }\n\n    /**\n     * Simulates branch insns, if possible. Adds reachable successor blocks\n     * to the CFG worklists.\n     * @param insn branch to simulate\n     */\n    private void simulateBranch(SsaInsn insn) {\n        Rop opcode = insn.getOpcode();\n        RegisterSpecList sources = insn.getSources();\n\n        boolean constantBranch = false;\n        boolean constantSuccessor = false;\n\n        // Check if the insn is a branch with a constant condition\n        if (opcode.getBranchingness() == Rop.BRANCH_IF) {\n            Constant cA = null;\n            Constant cB = null;\n\n            RegisterSpec specA = sources.get(0);\n            int regA = specA.getReg();\n            if (!ssaMeth.isRegALocal(specA) &&\n                    latticeValues[regA] == CONSTANT) {\n                cA = latticeConstants[regA];\n            }\n\n            if (sources.size() == 2) {\n                RegisterSpec specB = sources.get(1);\n                int regB = specB.getReg();\n                if (!ssaMeth.isRegALocal(specB) &&\n                        latticeValues[regB] == CONSTANT) {\n                    cB = latticeConstants[regB];\n                }\n            }\n\n            // Calculate the result of the condition\n            if (cA != null && sources.size() == 1) {\n                switch (((TypedConstant) cA).getBasicType()) {\n                    case Type.BT_INT:\n                        constantBranch = true;\n                        int vA = ((CstInteger) cA).getValue();\n                        switch (opcode.getOpcode()) {\n                            case RegOps.IF_EQ:\n                                constantSuccessor = (vA == 0);\n                                break;\n                            case RegOps.IF_NE:\n                                constantSuccessor = (vA != 0);\n                                break;\n                            case RegOps.IF_LT:\n                                constantSuccessor = (vA < 0);\n                                break;\n                            case RegOps.IF_GE:\n                                constantSuccessor = (vA >= 0);\n                                break;\n                            case RegOps.IF_LE:\n                                constantSuccessor = (vA <= 0);\n                                break;\n                            case RegOps.IF_GT:\n                                constantSuccessor = (vA > 0);\n                                break;\n                            default:\n                                throw new RuntimeException(\"Unexpected op\");\n                        }\n                        break;\n                    default:\n                        // not yet supported\n                }\n            } else if (cA != null && cB != null) {\n                switch (((TypedConstant) cA).getBasicType()) {\n                    case Type.BT_INT:\n                        constantBranch = true;\n                        int vA = ((CstInteger) cA).getValue();\n                        int vB = ((CstInteger) cB).getValue();\n                        switch (opcode.getOpcode()) {\n                            case RegOps.IF_EQ:\n                                constantSuccessor = (vA == vB);\n                                break;\n                            case RegOps.IF_NE:\n                                constantSuccessor = (vA != vB);\n                                break;\n                            case RegOps.IF_LT:\n                                constantSuccessor = (vA < vB);\n                                break;\n                            case RegOps.IF_GE:\n                                constantSuccessor = (vA >= vB);\n                                break;\n                            case RegOps.IF_LE:\n                                constantSuccessor = (vA <= vB);\n                                break;\n                            case RegOps.IF_GT:\n                                constantSuccessor = (vA > vB);\n                                break;\n                            default:\n                                throw new RuntimeException(\"Unexpected op\");\n                        }\n                        break;\n                    default:\n                        // not yet supported\n                }\n            }\n        }\n\n        /*\n         * If condition is constant, add only the target block to the\n         * worklist. Otherwise, add all successors to the worklist.\n         */\n        SsaBasicBlock block = insn.getBlock();\n\n        if (constantBranch) {\n            int successorBlock;\n            if (constantSuccessor) {\n                successorBlock = block.getSuccessorList().get(1);\n            } else {\n                successorBlock = block.getSuccessorList().get(0);\n            }\n            addBlockToWorklist(ssaMeth.getBlocks().get(successorBlock));\n            branchWorklist.add(insn);\n        } else {\n            for (int i = 0; i < block.getSuccessorList().size(); i++) {\n                int successorBlock = block.getSuccessorList().get(i);\n                addBlockToWorklist(ssaMeth.getBlocks().get(successorBlock));\n            }\n        }\n    }\n\n    /**\n     * Simulates math insns, if possible.\n     *\n     * @param insn non-null insn to simulate\n     * @param resultType basic type of the result\n     * @return constant result or null if not simulatable.\n     */\n    private Constant simulateMath(SsaInsn insn, int resultType) {\n        Insn ropInsn = insn.getOriginalRopInsn();\n        int opcode = insn.getOpcode().getOpcode();\n        RegisterSpecList sources = insn.getSources();\n        int regA = sources.get(0).getReg();\n        Constant cA;\n        Constant cB;\n\n        if (latticeValues[regA] != CONSTANT) {\n            cA = null;\n        } else {\n            cA = latticeConstants[regA];\n        }\n\n        if (sources.size() == 1) {\n            CstInsn cstInsn = (CstInsn) ropInsn;\n            cB = cstInsn.getConstant();\n        } else { /* sources.size() == 2 */\n            int regB = sources.get(1).getReg();\n            if (latticeValues[regB] != CONSTANT) {\n                cB = null;\n            } else {\n                cB = latticeConstants[regB];\n            }\n        }\n\n        if (cA == null || cB == null) {\n            //TODO handle a constant of 0 with MUL or AND\n            return null;\n        }\n\n        switch (resultType) {\n            case Type.BT_INT:\n                int vR;\n                boolean skip=false;\n\n                int vA = ((CstInteger) cA).getValue();\n                int vB = ((CstInteger) cB).getValue();\n\n                switch (opcode) {\n                    case RegOps.ADD:\n                        vR = vA + vB;\n                        break;\n                    case RegOps.SUB:\n                        // 1 source for reverse sub, 2 sources for regular sub\n                        if (sources.size() == 1) {\n                            vR = vB - vA;\n                        } else {\n                            vR = vA - vB;\n                        }\n                        break;\n                    case RegOps.MUL:\n                        vR = vA * vB;\n                        break;\n                    case RegOps.DIV:\n                        if (vB == 0) {\n                            skip = true;\n                            vR = 0; // just to hide a warning\n                        } else {\n                            vR = vA / vB;\n                        }\n                        break;\n                    case RegOps.AND:\n                        vR = vA & vB;\n                        break;\n                    case RegOps.OR:\n                        vR = vA | vB;\n                        break;\n                    case RegOps.XOR:\n                        vR = vA ^ vB;\n                        break;\n                    case RegOps.SHL:\n                        vR = vA << vB;\n                        break;\n                    case RegOps.SHR:\n                        vR = vA >> vB;\n                        break;\n                    case RegOps.USHR:\n                        vR = vA >>> vB;\n                        break;\n                    case RegOps.REM:\n                        if (vB == 0) {\n                            skip = true;\n                            vR = 0; // just to hide a warning\n                        } else {\n                            vR = vA % vB;\n                        }\n                        break;\n                    default:\n                        throw new RuntimeException(\"Unexpected op\");\n                }\n\n                return skip ? null : CstInteger.make(vR);\n\n            default:\n                // not yet supported\n                return null;\n        }\n    }\n\n    /**\n     * Simulates a statement and set the result lattice value.\n     * @param insn instruction to simulate\n     */\n    private void simulateStmt(SsaInsn insn) {\n        Insn ropInsn = insn.getOriginalRopInsn();\n        if (ropInsn.getOpcode().getBranchingness() != Rop.BRANCH_NONE\n                || ropInsn.getOpcode().isCallLike()) {\n            simulateBranch(insn);\n        }\n\n        int opcode = insn.getOpcode().getOpcode();\n        RegisterSpec result = insn.getResult();\n\n        if (result == null) {\n            // Find move-result-pseudo result for int div and int rem\n            if (opcode == RegOps.DIV || opcode == RegOps.REM) {\n                SsaBasicBlock succ = insn.getBlock().getPrimarySuccessor();\n                result = succ.getInsns().get(0).getResult();\n            } else {\n                return;\n            }\n        }\n\n        int resultReg = result.getReg();\n        int resultValue = VARYING;\n        Constant resultConstant = null;\n\n        switch (opcode) {\n            case RegOps.CONST: {\n                CstInsn cstInsn = (CstInsn)ropInsn;\n                resultValue = CONSTANT;\n                resultConstant = cstInsn.getConstant();\n                break;\n            }\n            case RegOps.MOVE: {\n                if (insn.getSources().size() == 1) {\n                    int sourceReg = insn.getSources().get(0).getReg();\n                    resultValue = latticeValues[sourceReg];\n                    resultConstant = latticeConstants[sourceReg];\n                }\n                break;\n            }\n            case RegOps.ADD:\n            case RegOps.SUB:\n            case RegOps.MUL:\n            case RegOps.DIV:\n            case RegOps.AND:\n            case RegOps.OR:\n            case RegOps.XOR:\n            case RegOps.SHL:\n            case RegOps.SHR:\n            case RegOps.USHR:\n            case RegOps.REM: {\n                resultConstant = simulateMath(insn, result.getBasicType());\n                if (resultConstant != null) {\n                    resultValue = CONSTANT;\n                }\n                break;\n            }\n            case RegOps.MOVE_RESULT_PSEUDO: {\n                if (latticeValues[resultReg] == CONSTANT) {\n                    resultValue = latticeValues[resultReg];\n                    resultConstant = latticeConstants[resultReg];\n                }\n                break;\n            }\n            // TODO: Handle non-int arithmetic.\n            // TODO: Eliminate check casts that we can prove the type of.\n            default: {}\n        }\n        if (setLatticeValueTo(resultReg, resultValue, resultConstant)) {\n            addUsersToWorklist(resultReg, resultValue);\n        }\n    }\n\n    private void run() {\n        SsaBasicBlock firstBlock = ssaMeth.getEntryBlock();\n        addBlockToWorklist(firstBlock);\n\n        /* Empty all the worklists by propagating our values */\n        while (!cfgWorklist.isEmpty()\n                || !cfgPhiWorklist.isEmpty()\n                || !ssaWorklist.isEmpty()\n                || !varyingWorklist.isEmpty()) {\n            while (!cfgWorklist.isEmpty()) {\n                int listSize = cfgWorklist.size() - 1;\n                SsaBasicBlock block = cfgWorklist.remove(listSize);\n                simulateBlock(block);\n            }\n\n            while (!cfgPhiWorklist.isEmpty()) {\n                int listSize = cfgPhiWorklist.size() - 1;\n                SsaBasicBlock block = cfgPhiWorklist.remove(listSize);\n                simulatePhiBlock(block);\n            }\n\n            while (!varyingWorklist.isEmpty()) {\n                int listSize = varyingWorklist.size() - 1;\n                SsaInsn insn = varyingWorklist.remove(listSize);\n\n                if (!executableBlocks.get(insn.getBlock().getIndex())) {\n                    continue;\n                }\n\n                if (insn instanceof PhiInsn) {\n                    simulatePhi((PhiInsn)insn);\n                } else {\n                    simulateStmt(insn);\n                }\n            }\n            while (!ssaWorklist.isEmpty()) {\n                int listSize = ssaWorklist.size() - 1;\n                SsaInsn insn = ssaWorklist.remove(listSize);\n\n                if (!executableBlocks.get(insn.getBlock().getIndex())) {\n                    continue;\n                }\n\n                if (insn instanceof PhiInsn) {\n                    simulatePhi((PhiInsn)insn);\n                } else {\n                    simulateStmt(insn);\n                }\n            }\n        }\n\n        replaceConstants();\n        replaceBranches();\n    }\n\n    /**\n     * Replaces TypeBearers in source register specs with constant type\n     * bearers if possible. These are then referenced in later optimization\n     * steps.\n     */\n    private void replaceConstants() {\n        for (int reg = 0; reg < regCount; reg++) {\n            if (latticeValues[reg] != CONSTANT) {\n                continue;\n            }\n            if (!(latticeConstants[reg] instanceof TypedConstant)) {\n                // We can't do much with these\n                continue;\n            }\n\n            SsaInsn defn = ssaMeth.getDefinitionForRegister(reg);\n            TypeBearer typeBearer = defn.getResult().getTypeBearer();\n\n            if (typeBearer.isConstant()) {\n                /*\n                 * The definition was a constant already.\n                 * The uses should be as well.\n                 */\n                continue;\n            }\n\n            // Update the destination RegisterSpec with the constant value\n            RegisterSpec dest = defn.getResult();\n            RegisterSpec newDest\n                    = dest.withType((TypedConstant)latticeConstants[reg]);\n            defn.setResult(newDest);\n\n            /*\n             * Update the sources RegisterSpec's of all non-move uses.\n             * These will be used in later steps.\n             */\n            for (SsaInsn insn : ssaMeth.getUseListForRegister(reg)) {\n                if (insn.isPhiOrMove()) {\n                    continue;\n                }\n\n                NormalSsaInsn nInsn = (NormalSsaInsn) insn;\n                RegisterSpecList sources = insn.getSources();\n\n                int index = sources.indexOfRegister(reg);\n\n                RegisterSpec spec = sources.get(index);\n                RegisterSpec newSpec\n                        = spec.withType((TypedConstant)latticeConstants[reg]);\n\n                nInsn.changeOneSource(index, newSpec);\n            }\n        }\n    }\n\n    /**\n     * Replaces branches that have constant conditions with gotos\n     */\n    private void replaceBranches() {\n        for (SsaInsn insn : branchWorklist) {\n            // Find if a successor block is never executed\n            int oldSuccessor = -1;\n            SsaBasicBlock block = insn.getBlock();\n            int successorSize = block.getSuccessorList().size();\n            for (int i = 0; i < successorSize; i++) {\n                int successorBlock = block.getSuccessorList().get(i);\n                if (!executableBlocks.get(successorBlock)) {\n                    oldSuccessor = successorBlock;\n                }\n            }\n\n            /*\n             * Prune branches that have already been handled and ones that no\n             * longer have constant conditions (no nonexecutable successors)\n             */\n            if (successorSize != 2 || oldSuccessor == -1) continue;\n\n            // Replace branch with goto\n            Insn originalRopInsn = insn.getOriginalRopInsn();\n            block.replaceLastInsn(new PlainInsn(Rops.GOTO,\n                originalRopInsn.getPosition(), null, RegisterSpecList.EMPTY));\n            block.removeSuccessor(oldSuccessor);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/SetFactory.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.util.BitIntSet;\nimport com.taobao.android.dx.util.IntSet;\nimport com.taobao.android.dx.util.ListIntSet;\n\n\n/**\n * Makes int sets for various parts of the optimizer.\n */\npublic final class SetFactory {\n\n    /**\n     * BitIntSet/ListIntSet threshold for dominance frontier sets. These\n     * sets are kept per basic block until phi placement and tend to be,\n     * like the CFG itself, very sparse at large sizes.\n     *\n     * A value of 3072 here is somewhere around 1.125mb of total bitset size.\n     */\n    private static final int DOMFRONT_SET_THRESHOLD_SIZE = 3072;\n\n    /**\n     * BitIntSet/ListIntSet threshold for interference graph sets. These\n     * sets are kept per register until register allocation is done.\n     *\n     * A value of 3072 here is somewhere around 1.125mb of total bitset size.\n     */\n    private static final int INTERFERENCE_SET_THRESHOLD_SIZE = 3072;\n\n    /**\n     * BitIntSet/ListIntSet threshold for the live in/out sets kept by\n     * {@link SsaBasicBlock}. These are sets of SSA registers kept per basic\n     * block during register allocation.\n     *\n     * The total size of a bitset for this would be the count of blocks\n     * times the size of registers. The threshold value here is merely\n     * the register count, which is typically on the order of the block\n     * count as well.\n     */\n    private static final int LIVENESS_SET_THRESHOLD_SIZE = 3072;\n\n\n    /**\n     * Make IntSet for the dominance-frontier sets.\n     *\n     * @param szBlocks {@code >=0;} count of basic blocks in method\n     * @return {@code non-null;} appropriate set\n     */\n    /*package*/ static IntSet makeDomFrontSet(int szBlocks) {\n        return szBlocks <= DOMFRONT_SET_THRESHOLD_SIZE\n                ? new BitIntSet(szBlocks)\n                : new ListIntSet();\n    }\n\n    /**\n     * Make IntSet for the interference graph sets. Public because\n     * InterferenceGraph is in another package.\n     *\n     * @param countRegs {@code >=0;} count of SSA registers used in method\n     * @return {@code non-null;} appropriate set\n     */\n    public static IntSet makeInterferenceSet(int countRegs) {\n        return countRegs <= INTERFERENCE_SET_THRESHOLD_SIZE\n                ? new BitIntSet(countRegs)\n                : new ListIntSet();\n    }\n\n    /**\n     * Make IntSet for register live in/out sets.\n     *\n     * @param countRegs {@code >=0;} count of SSA registers used in method\n     * @return {@code non-null;} appropriate set\n     */\n    /*package*/ static IntSet makeLivenessSet(int countRegs) {\n        return countRegs <= LIVENESS_SET_THRESHOLD_SIZE\n                ? new BitIntSet(countRegs)\n                : new ListIntSet();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/SsaBasicBlock.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.BasicBlock;\nimport com.taobao.android.dx.rop.code.BasicBlockList;\nimport com.taobao.android.dx.rop.code.Insn;\nimport com.taobao.android.dx.rop.code.InsnList;\nimport com.taobao.android.dx.rop.code.PlainInsn;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rop;\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.rop.code.Rops;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.IntList;\nimport com.taobao.android.dx.util.IntSet;\nimport java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\n\n/**\n * An SSA representation of a basic block.\n */\npublic final class SsaBasicBlock {\n    /**\n     * {@code non-null;} comparator for instances of this class that\n     * just compares block labels\n     */\n    public static final Comparator<SsaBasicBlock> LABEL_COMPARATOR =\n        new LabelComparator();\n\n    /** {@code non-null;} insn list associated with this instance */\n    private ArrayList<SsaInsn> insns;\n\n    /** {@code non-null;} predecessor set (by block list index) */\n    private BitSet predecessors;\n\n    /** {@code non-null;} successor set (by block list index) */\n    private BitSet successors;\n\n    /**\n     * {@code non-null;} ordered successor list\n     * (same block may be listed more than once)\n     */\n    private IntList successorList;\n\n    /**\n     * block list index of primary successor, or {@code -1} for no primary\n     * successor\n     */\n    private int primarySuccessor = -1;\n\n    /** label of block in rop form */\n    private int ropLabel;\n\n    /** {@code non-null;} method we belong to */\n    private SsaMethod parent;\n\n    /** our index into parent.getBlock() */\n    private int index;\n\n    /** list of dom children */\n    private final ArrayList<SsaBasicBlock> domChildren;\n\n    /**\n     * the number of moves added to the end of the block during the\n     * phi-removal process. Retained for subsequent move scheduling.\n     */\n    private int movesFromPhisAtEnd = 0;\n\n    /**\n     * the number of moves added to the beginning of the block during the\n     * phi-removal process. Retained for subsequent move scheduling.\n     */\n    private int movesFromPhisAtBeginning = 0;\n\n    /**\n     * contains last computed value of reachability of this block, or -1\n     * if reachability hasn't been calculated yet\n     */\n    private int reachable = -1;\n\n    /**\n     * {@code null-ok;} indexed by reg: the regs that are live-in at\n     * this block\n     */\n    private IntSet liveIn;\n\n    /**\n     * {@code null-ok;} indexed by reg: the regs that are live-out at\n     * this block\n     */\n    private IntSet liveOut;\n\n    /**\n     * Creates a new empty basic block.\n     *\n     * @param basicBlockIndex index this block will have\n     * @param ropLabel original rop-form label\n     * @param parent method of this block\n     */\n    public SsaBasicBlock(final int basicBlockIndex, final int ropLabel,\n            final SsaMethod parent) {\n        this.parent = parent;\n        this.index = basicBlockIndex;\n        this.insns = new ArrayList<SsaInsn>();\n        this.ropLabel = ropLabel;\n\n        this.predecessors = new BitSet(parent.getBlocks().size());\n        this.successors = new BitSet(parent.getBlocks().size());\n        this.successorList = new IntList();\n\n        domChildren = new ArrayList<SsaBasicBlock>();\n    }\n\n    /**\n     * Creates a new SSA basic block from a ROP form basic block.\n     *\n     * @param rmeth original method\n     * @param basicBlockIndex index this block will have\n     * @param parent method of this block predecessor set will be\n     * updated\n     * @return new instance\n     */\n    public static SsaBasicBlock newFromRop(RopMethod rmeth,\n            int basicBlockIndex, final SsaMethod parent) {\n        BasicBlockList ropBlocks = rmeth.getBlocks();\n        BasicBlock bb = ropBlocks.get(basicBlockIndex);\n        SsaBasicBlock result =\n            new SsaBasicBlock(basicBlockIndex, bb.getLabel(), parent);\n        InsnList ropInsns = bb.getInsns();\n\n        result.insns.ensureCapacity(ropInsns.size());\n\n        for (int i = 0, sz = ropInsns.size() ; i < sz ; i++) {\n            result.insns.add(new NormalSsaInsn (ropInsns.get(i), result));\n        }\n\n        result.predecessors = SsaMethod.bitSetFromLabelList(\n                ropBlocks,\n                rmeth.labelToPredecessors(bb.getLabel()));\n\n        result.successors\n                = SsaMethod.bitSetFromLabelList(ropBlocks, bb.getSuccessors());\n\n        result.successorList\n                = SsaMethod.indexListFromLabelList(ropBlocks,\n                    bb.getSuccessors());\n\n        if (result.successorList.size() != 0) {\n            int primarySuccessor = bb.getPrimarySuccessor();\n\n            result.primarySuccessor = (primarySuccessor < 0)\n                    ? -1 : ropBlocks.indexOfLabel(primarySuccessor);\n        }\n\n        return result;\n    }\n\n    /**\n     * Adds a basic block as a dom child for this block. Used when constructing\n     * the dom tree.\n     *\n     * @param child {@code non-null;} new dom child\n     */\n    public void addDomChild(SsaBasicBlock child) {\n        domChildren.add(child);\n    }\n\n    /**\n     * Gets the dom children for this node. Don't modify this list.\n     *\n     * @return {@code non-null;} list of dom children\n     */\n    public ArrayList<SsaBasicBlock> getDomChildren() {\n        return domChildren;\n    }\n\n    /**\n     * Adds a phi insn to the beginning of this block. The result type of\n     * the phi will be set to void, to indicate that it's currently unknown.\n     *\n     * @param reg {@code >=0;} result reg\n     */\n    public void addPhiInsnForReg(int reg) {\n        insns.add(0, new PhiInsn(reg, this));\n    }\n\n    /**\n     * Adds a phi insn to the beginning of this block. This is to be used\n     * when the result type or local-association can be determined at phi\n     * insert time.\n     *\n     * @param resultSpec {@code non-null;} reg\n     */\n    public void addPhiInsnForReg(RegisterSpec resultSpec) {\n        insns.add(0, new PhiInsn(resultSpec, this));\n    }\n\n    /**\n     * Adds an insn to the head of this basic block, just after any phi\n     * insns.\n     *\n     * @param insn {@code non-null;} rop-form insn to add\n     */\n    public void addInsnToHead(Insn insn) {\n        SsaInsn newInsn = SsaInsn.makeFromRop(insn, this);\n        insns.add(getCountPhiInsns(), newInsn);\n        parent.onInsnAdded(newInsn);\n    }\n\n    /**\n     * Replaces the last insn in this block. The provided insn must have\n     * some branchingness.\n     *\n     * @param insn {@code non-null;} rop-form insn to add, which must branch.\n     */\n    public void replaceLastInsn(Insn insn) {\n        if (insn.getOpcode().getBranchingness() == Rop.BRANCH_NONE) {\n            throw new IllegalArgumentException(\"last insn must branch\");\n        }\n\n        SsaInsn oldInsn = insns.get(insns.size() - 1);\n        SsaInsn newInsn = SsaInsn.makeFromRop(insn, this);\n\n        insns.set(insns.size() - 1, newInsn);\n\n        parent.onInsnRemoved(oldInsn);\n        parent.onInsnAdded(newInsn);\n    }\n\n    /**\n     * Visits each phi insn.\n     *\n     * @param v {@code non-null;} the callback\n     */\n    public void forEachPhiInsn(PhiInsn.Visitor v) {\n        int sz = insns.size();\n\n        for (int i = 0; i < sz; i++) {\n            SsaInsn insn = insns.get(i);\n            if (insn instanceof PhiInsn) {\n                v.visitPhiInsn((PhiInsn) insn);\n            } else {\n                /*\n                 * Presently we assume PhiInsn's are in a continuous\n                 * block at the top of the list\n                 */\n                break;\n            }\n        }\n    }\n\n    /**\n     * Deletes all phi insns. Do this after adding appropriate move insns.\n     */\n    public void removeAllPhiInsns() {\n        /*\n         * Presently we assume PhiInsn's are in a continuous\n         * block at the top of the list.\n         */\n\n        insns.subList(0, getCountPhiInsns()).clear();\n    }\n\n    /**\n     * Gets the number of phi insns at the top of this basic block.\n     *\n     * @return count of phi insns\n     */\n    private int getCountPhiInsns() {\n        int countPhiInsns;\n\n        int sz = insns.size();\n        for (countPhiInsns = 0; countPhiInsns < sz; countPhiInsns++) {\n            SsaInsn insn = insns.get(countPhiInsns);\n            if (!(insn instanceof PhiInsn)) {\n                break;\n            }\n        }\n\n        return countPhiInsns;\n    }\n\n    /**\n     * @return {@code non-null;} the (mutable) instruction list for this block,\n     * with phi insns at the beginning\n     */\n    public ArrayList<SsaInsn> getInsns() {\n        return insns;\n    }\n\n    /**\n     * @return {@code non-null;} the (mutable) list of phi insns for this block\n     */\n    public List<SsaInsn> getPhiInsns() {\n        return insns.subList(0, getCountPhiInsns());\n    }\n\n    /**\n     * @return the block index of this block\n     */\n    public int getIndex() {\n        return index;\n    }\n\n    /**\n     * @return the label of this block in rop form\n     */\n    public int getRopLabel() {\n        return ropLabel;\n    }\n\n    /**\n     * @return the label of this block in rop form as a hex string\n     */\n    public String getRopLabelString() {\n        return Hex.u2(ropLabel);\n    }\n\n    /**\n     * @return {@code non-null;} predecessors set, indexed by block index\n     */\n    public BitSet getPredecessors() {\n        return predecessors;\n    }\n\n    /**\n     * @return {@code non-null;} successors set, indexed by block index\n     */\n    public BitSet getSuccessors() {\n        return successors;\n    }\n\n    /**\n     * @return {@code non-null;} ordered successor list, containing block\n     * indicies\n     */\n    public IntList getSuccessorList() {\n        return successorList;\n    }\n\n    /**\n     * @return {@code >= -1;} block index of primary successor or\n     * {@code -1} if no primary successor\n     */\n    public int getPrimarySuccessorIndex() {\n        return primarySuccessor;\n    }\n\n    /**\n     * @return rop label of primary successor\n     */\n    public int getPrimarySuccessorRopLabel() {\n        return parent.blockIndexToRopLabel(primarySuccessor);\n    }\n\n    /**\n     * @return {@code null-ok;} the primary successor block or {@code null}\n     * if there is none\n     */\n    public SsaBasicBlock getPrimarySuccessor() {\n        if (primarySuccessor < 0) {\n            return null;\n        } else {\n            return parent.getBlocks().get(primarySuccessor);\n        }\n    }\n\n    /**\n     * @return successor list of rop labels\n     */\n    public IntList getRopLabelSuccessorList() {\n        IntList result = new IntList(successorList.size());\n\n        int sz = successorList.size();\n\n        for (int i = 0; i < sz; i++) {\n            result.add(parent.blockIndexToRopLabel(successorList.get(i)));\n        }\n        return result;\n    }\n\n    /**\n     * @return {@code non-null;} method that contains this block\n     */\n    public SsaMethod getParent() {\n        return parent;\n    }\n\n    /**\n     * Inserts a new empty GOTO block as a predecessor to this block.\n     * All previous predecessors will be predecessors to the new block.\n     *\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public SsaBasicBlock insertNewPredecessor() {\n        SsaBasicBlock newPred = parent.makeNewGotoBlock();\n\n        // Update the new block.\n        newPred.predecessors = predecessors;\n        newPred.successors.set(index) ;\n        newPred.successorList.add(index);\n        newPred.primarySuccessor = index;\n\n\n        // Update us.\n        predecessors = new BitSet(parent.getBlocks().size());\n        predecessors.set(newPred.index);\n\n        // Update our (soon-to-be) old predecessors.\n        for (int i = newPred.predecessors.nextSetBit(0); i >= 0;\n                i = newPred.predecessors.nextSetBit(i + 1)) {\n\n            SsaBasicBlock predBlock = parent.getBlocks().get(i);\n\n            predBlock.replaceSuccessor(index, newPred.index);\n        }\n\n        return newPred;\n    }\n\n    /**\n     * Constructs and inserts a new empty GOTO block {@code Z} between\n     * this block ({@code A}) and a current successor block\n     * ({@code B}). The new block will replace B as A's successor and\n     * A as B's predecessor. A and B will no longer be directly connected.\n     * If B is listed as a successor multiple times, all references\n     * are replaced.\n     *\n     * @param other current successor (B)\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public SsaBasicBlock insertNewSuccessor(SsaBasicBlock other) {\n        SsaBasicBlock newSucc = parent.makeNewGotoBlock();\n\n        if (!successors.get(other.index)) {\n            throw new RuntimeException(\"Block \" + other.getRopLabelString()\n                    + \" not successor of \" + getRopLabelString());\n        }\n\n        // Update the new block.\n        newSucc.predecessors.set(this.index);\n        newSucc.successors.set(other.index) ;\n        newSucc.successorList.add(other.index);\n        newSucc.primarySuccessor = other.index;\n\n        // Update us.\n        for (int i = successorList.size() - 1 ;  i >= 0; i--) {\n            if (successorList.get(i) == other.index) {\n                successorList.set(i, newSucc.index);\n            }\n        }\n\n        if (primarySuccessor == other.index) {\n            primarySuccessor = newSucc.index;\n        }\n        successors.clear(other.index);\n        successors.set(newSucc.index);\n\n        // Update \"other\".\n        other.predecessors.set(newSucc.index);\n        other.predecessors.set(index, successors.get(other.index));\n\n        return newSucc;\n    }\n\n    /**\n     * Replaces an old successor with a new successor. This will throw\n     * RuntimeException if {@code oldIndex} was not a successor.\n     *\n     * @param oldIndex index of old successor block\n     * @param newIndex index of new successor block\n     */\n    public void replaceSuccessor(int oldIndex, int newIndex) {\n        if (oldIndex == newIndex) {\n            return;\n        }\n\n        // Update us.\n        successors.set(newIndex);\n\n        if (primarySuccessor == oldIndex) {\n            primarySuccessor = newIndex;\n        }\n\n        for (int i = successorList.size() - 1 ;  i >= 0; i--) {\n            if (successorList.get(i) == oldIndex) {\n                successorList.set(i, newIndex);\n            }\n        }\n\n        successors.clear(oldIndex);\n\n        // Update new successor.\n        parent.getBlocks().get(newIndex).predecessors.set(index);\n\n        // Update old successor.\n        parent.getBlocks().get(oldIndex).predecessors.clear(index);\n    }\n\n    /**\n     * Removes a successor from this block's successor list.\n     *\n     * @param oldIndex index of successor block to remove\n     */\n    public void removeSuccessor(int oldIndex) {\n        int removeIndex = 0;\n\n        for (int i = successorList.size() - 1; i >= 0; i--) {\n            if (successorList.get(i) == oldIndex) {\n                removeIndex = i;\n            } else {\n                primarySuccessor = successorList.get(i);\n            }\n        }\n\n        successorList.removeIndex(removeIndex);\n        successors.clear(oldIndex);\n        parent.getBlocks().get(oldIndex).predecessors.clear(index);\n    }\n\n    /**\n     * Attaches block to an exit block if necessary. If this block\n     * is not an exit predecessor or is the exit block, this block does\n     * nothing. For use by {@link com.taobao.android.dx.ssa.SsaMethod#makeExitBlock}\n     *\n     * @param exitBlock {@code non-null;} exit block\n     */\n    public void exitBlockFixup(SsaBasicBlock exitBlock) {\n        if (this == exitBlock) {\n            return;\n        }\n\n        if (successorList.size() == 0) {\n            /*\n             * This is an exit predecessor.\n             * Set the successor to the exit block\n             */\n            successors.set(exitBlock.index);\n            successorList.add(exitBlock.index);\n            primarySuccessor = exitBlock.index;\n            exitBlock.predecessors.set(this.index);\n        }\n    }\n\n    /**\n     * Adds a move instruction to the end of this basic block, just\n     * before the last instruction. If the result of the final instruction\n     * is the source in question, then the move is placed at the beginning of\n     * the primary successor block. This is for unversioned registers.\n     *\n     * @param result move destination\n     * @param source move source\n     */\n    public void addMoveToEnd(RegisterSpec result, RegisterSpec source) {\n\n        if (result.getReg() == source.getReg()) {\n            // Sometimes we end up with no-op moves. Ignore them here.\n            return;\n        }\n\n        /*\n         * The last Insn has to be a normal SSA insn: a phi can't branch\n         * or return or cause an exception, etc.\n         */\n        NormalSsaInsn lastInsn;\n        lastInsn = (NormalSsaInsn)insns.get(insns.size()-1);\n\n        if (lastInsn.getResult() != null || lastInsn.getSources().size() > 0) {\n            /*\n             * The final insn in this block has a source or result\n             * register, and the moves we may need to place and\n             * schedule may interfere. We need to insert this\n             * instruction at the beginning of the primary successor\n             * block instead. We know this is safe, because when we\n             * edge-split earlier, we ensured that each successor has\n             * only us as a predecessor.\n             */\n\n            for (int i = successors.nextSetBit(0)\n                    ; i >= 0\n                    ; i = successors.nextSetBit(i + 1)) {\n\n                SsaBasicBlock succ;\n\n                succ = parent.getBlocks().get(i);\n                succ.addMoveToBeginning(result, source);\n            }\n        } else {\n            /*\n             * We can safely add a move to the end of the block just\n             * before the last instruction, because the final insn does\n             * not assign to anything.\n             */\n            RegisterSpecList sources = RegisterSpecList.make(source);\n            NormalSsaInsn toAdd = new NormalSsaInsn(\n                    new PlainInsn(Rops.opMove(result.getType()),\n                            SourcePosition.NO_INFO, result, sources), this);\n\n            insns.add(insns.size() - 1, toAdd);\n\n            movesFromPhisAtEnd++;\n        }\n    }\n\n    /**\n     * Adds a move instruction after the phi insn block.\n     *\n     * @param result move destination\n     * @param source move source\n     */\n    public void addMoveToBeginning (RegisterSpec result, RegisterSpec source) {\n        if (result.getReg() == source.getReg()) {\n            // Sometimes we end up with no-op moves. Ignore them here.\n            return;\n        }\n\n        RegisterSpecList sources = RegisterSpecList.make(source);\n        NormalSsaInsn toAdd = new NormalSsaInsn(\n                new PlainInsn(Rops.opMove(result.getType()),\n                        SourcePosition.NO_INFO, result, sources), this);\n\n        insns.add(getCountPhiInsns(), toAdd);\n        movesFromPhisAtBeginning++;\n    }\n\n    /**\n     * Sets the register as used in a bitset, taking into account its\n     * category/width.\n     *\n     * @param regsUsed set, indexed by register number\n     * @param rs register to mark as used\n     */\n    private static void setRegsUsed (BitSet regsUsed, RegisterSpec rs) {\n        regsUsed.set(rs.getReg());\n        if (rs.getCategory() > 1) {\n            regsUsed.set(rs.getReg() + 1);\n        }\n    }\n\n    /**\n     * Checks to see if the register is used in a bitset, taking\n     * into account its category/width.\n     *\n     * @param regsUsed set, indexed by register number\n     * @param rs register to mark as used\n     * @return true if register is fully or partially (for the case of wide\n     * registers) used.\n     */\n    private static boolean checkRegUsed (BitSet regsUsed, RegisterSpec rs) {\n        int reg = rs.getReg();\n        int category = rs.getCategory();\n\n        return regsUsed.get(reg)\n                || (category == 2 ? regsUsed.get(reg + 1) : false);\n    }\n\n    /**\n     * Ensures that all move operations in this block occur such that\n     * reads of any register happen before writes to that register.\n     * NOTE: caller is expected to returnSpareRegisters()!\n     *\n     * TODO: See Briggs, et al \"Practical Improvements to the Construction and\n     * Destruction of Static Single Assignment Form\" section 5. a) This can\n     * be done in three passes.\n     *\n     * @param toSchedule List of instructions. Must consist only of moves.\n     */\n    private void scheduleUseBeforeAssigned(List<SsaInsn> toSchedule) {\n        BitSet regsUsedAsSources = new BitSet(parent.getRegCount());\n\n        // TODO: Get rid of this.\n        BitSet regsUsedAsResults = new BitSet(parent.getRegCount());\n\n        int sz = toSchedule.size();\n\n        int insertPlace = 0;\n\n        while (insertPlace < sz) {\n            int oldInsertPlace = insertPlace;\n\n            // Record all registers used as sources in this block.\n            for (int i = insertPlace; i < sz; i++) {\n                setRegsUsed(regsUsedAsSources,\n                        toSchedule.get(i).getSources().get(0));\n\n                setRegsUsed(regsUsedAsResults,\n                        toSchedule.get(i).getResult());\n            }\n\n            /*\n             * If there are no circular dependencies, then there exists\n             * n instructions where n > 1 whose result is not used as a source.\n             */\n            for (int i = insertPlace; i <sz; i++) {\n                SsaInsn insn = toSchedule.get(i);\n\n                /*\n                 * Move these n registers to the front, since they overwrite\n                 * nothing.\n                 */\n                if (!checkRegUsed(regsUsedAsSources, insn.getResult())) {\n                    Collections.swap(toSchedule, i, insertPlace++);\n                }\n            }\n\n            /*\n             * If we've made no progress in this iteration, there's a\n             * circular dependency. Split it using the temp reg.\n             */\n            if (oldInsertPlace == insertPlace) {\n\n                SsaInsn insnToSplit = null;\n\n                // Find an insn whose result is used as a source.\n                for (int i = insertPlace; i < sz; i++) {\n                    SsaInsn insn = toSchedule.get(i);\n                    if (checkRegUsed(regsUsedAsSources, insn.getResult())\n                            && checkRegUsed(regsUsedAsResults,\n                                insn.getSources().get(0))) {\n\n                        insnToSplit = insn;\n                        /*\n                         * We're going to split this insn; move it to the\n                         * front.\n                         */\n                        Collections.swap(toSchedule, insertPlace, i);\n                        break;\n                    }\n                }\n\n                // At least one insn will be set above.\n\n                RegisterSpec result = insnToSplit.getResult();\n                RegisterSpec tempSpec = result.withReg(\n                        parent.borrowSpareRegister(result.getCategory()));\n\n                NormalSsaInsn toAdd = new NormalSsaInsn(\n                        new PlainInsn(Rops.opMove(result.getType()),\n                                SourcePosition.NO_INFO,\n                                tempSpec,\n                                insnToSplit.getSources()), this);\n\n                toSchedule.add(insertPlace++, toAdd);\n\n                RegisterSpecList newSources = RegisterSpecList.make(tempSpec);\n\n                NormalSsaInsn toReplace = new NormalSsaInsn(\n                        new PlainInsn(Rops.opMove(result.getType()),\n                                SourcePosition.NO_INFO,\n                                result,\n                                newSources), this);\n\n                toSchedule.set(insertPlace, toReplace);\n\n                // The size changed.\n                sz = toSchedule.size();\n            }\n\n            regsUsedAsSources.clear();\n            regsUsedAsResults.clear();\n        }\n    }\n\n    /**\n     * Adds {@code regV} to the live-out list for this block. This is called\n     * by the liveness analyzer.\n     *\n     * @param regV register that is live-out for this block.\n     */\n    public void addLiveOut (int regV) {\n        if (liveOut == null) {\n            liveOut = SetFactory.makeLivenessSet(parent.getRegCount());\n        }\n\n        liveOut.add(regV);\n    }\n\n    /**\n     * Adds {@code regV} to the live-in list for this block. This is\n     * called by the liveness analyzer.\n     *\n     * @param regV register that is live-in for this block.\n     */\n    public void addLiveIn (int regV) {\n        if (liveIn == null) {\n            liveIn = SetFactory.makeLivenessSet(parent.getRegCount());\n        }\n\n        liveIn.add(regV);\n    }\n\n    /**\n     * Returns the set of live-in registers. Valid after register\n     * interference graph has been generated, otherwise empty.\n     *\n     * @return {@code non-null;} live-in register set.\n     */\n    public IntSet getLiveInRegs() {\n        if (liveIn == null) {\n            liveIn = SetFactory.makeLivenessSet(parent.getRegCount());\n        }\n        return liveIn;\n    }\n\n    /**\n     * Returns the set of live-out registers. Valid after register\n     * interference graph has been generated, otherwise empty.\n     *\n     * @return {@code non-null;} live-out register set\n     */\n    public IntSet getLiveOutRegs() {\n        if (liveOut == null) {\n            liveOut = SetFactory.makeLivenessSet(parent.getRegCount());\n        }\n        return liveOut;\n    }\n\n    /**\n     * @return true if this is the one-and-only exit block for this method\n     */\n    public boolean isExitBlock() {\n        return index == parent.getExitBlockIndex();\n    }\n\n    /**\n     * Returns true if this block was last calculated to be reachable.\n     * Recalculates reachability if value has never been computed.\n     *\n     * @return {@code true} if reachable\n     */\n    public boolean isReachable() {\n        if (reachable == -1) {\n            parent.computeReachability();\n        }\n        return (reachable == 1);\n    }\n\n    /**\n     * Sets reachability of block to specified value\n     *\n     * @param reach new value of reachability for block\n     */\n    public void setReachable(int reach) {\n        reachable = reach;\n    }\n\n    /**\n     * Sorts move instructions added via {@code addMoveToEnd} during\n     * phi removal so that results don't overwrite sources that are used.\n     * For use after all phis have been removed and all calls to\n     * addMoveToEnd() have been made.<p>\n     *\n     * This is necessary because copy-propogation may have left us in a state\n     * where the same basic block has the same register as a phi operand\n     * and a result. In this case, the register in the phi operand always\n     * refers value before any other phis have executed.\n     */\n    public void scheduleMovesFromPhis() {\n        if (movesFromPhisAtBeginning > 1) {\n            List<SsaInsn> toSchedule;\n\n            toSchedule = insns.subList(0, movesFromPhisAtBeginning);\n\n            scheduleUseBeforeAssigned(toSchedule);\n\n            SsaInsn firstNonPhiMoveInsn = insns.get(movesFromPhisAtBeginning);\n\n            /*\n             * TODO: It's actually possible that this case never happens,\n             * because a move-exception block, having only one predecessor\n             * in SSA form, perhaps is never on a dominance frontier.\n             */\n            if (firstNonPhiMoveInsn.isMoveException()) {\n                if (true) {\n                    /*\n                     * We've yet to observe this case, and if it can\n                     * occur the code written to handle it probably\n                     * does not work.\n                     */\n                    throw new RuntimeException(\n                            \"Unexpected: moves from \"\n                                    +\"phis before move-exception\");\n                } else {\n                    /*\n                     * A move-exception insn must be placed first in this block\n                     * We need to move it there, and deal with possible\n                     * interference.\n                     */\n                    boolean moveExceptionInterferes = false;\n\n                    int moveExceptionResult\n                            = firstNonPhiMoveInsn.getResult().getReg();\n\n                    /*\n                     * Does the move-exception result reg interfere with the\n                     * phi moves?\n                     */\n                    for (SsaInsn insn : toSchedule) {\n                        if (insn.isResultReg(moveExceptionResult)\n                                || insn.isRegASource(moveExceptionResult)) {\n                            moveExceptionInterferes = true;\n                            break;\n                        }\n                    }\n\n                    if (!moveExceptionInterferes) {\n                        // This is the easy case.\n                        insns.remove(movesFromPhisAtBeginning);\n                        insns.add(0, firstNonPhiMoveInsn);\n                    } else {\n                        /*\n                         * We need to move the result to a spare reg\n                         * and move it back.\n                         */\n                        RegisterSpec originalResultSpec\n                            = firstNonPhiMoveInsn.getResult();\n                        int spareRegister = parent.borrowSpareRegister(\n                                originalResultSpec.getCategory());\n\n                        // We now move it to a spare register.\n                        firstNonPhiMoveInsn.changeResultReg(spareRegister);\n                        RegisterSpec tempSpec =\n                            firstNonPhiMoveInsn.getResult();\n\n                        insns.add(0, firstNonPhiMoveInsn);\n\n                        // And here we move it back.\n\n                        NormalSsaInsn toAdd = new NormalSsaInsn(\n                                new PlainInsn(\n                                        Rops.opMove(tempSpec.getType()),\n                                        SourcePosition.NO_INFO,\n                                        originalResultSpec,\n                                        RegisterSpecList.make(tempSpec)),\n                                this);\n\n\n                        /*\n                         * Place it immediately after the phi-moves,\n                         * overwriting the move-exception that was there.\n                         */\n                        insns.set(movesFromPhisAtBeginning + 1, toAdd);\n                    }\n                }\n            }\n        }\n\n        if (movesFromPhisAtEnd > 1) {\n            scheduleUseBeforeAssigned(\n                    insns.subList(insns.size() - movesFromPhisAtEnd - 1,\n                                insns.size() - 1));\n        }\n\n        // Return registers borrowed here and in scheduleUseBeforeAssigned().\n        parent.returnSpareRegisters();\n\n    }\n\n    /**\n     * Visits all insns in this block.\n     *\n     * @param visitor {@code non-null;} callback interface\n     */\n    public void forEachInsn(SsaInsn.Visitor visitor) {\n        // This gets called a LOT, and not using an iterator\n        // saves a lot of allocations and reduces memory usage\n        int len = insns.size();\n        for (int i = 0; i < len; i++) {\n            insns.get(i).accept(visitor);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        return \"{\" + index + \":\" + Hex.u2(ropLabel) + '}';\n    }\n\n    /**\n     * Visitor interface for basic blocks.\n     */\n    public interface Visitor {\n        /**\n         * Indicates a block has been visited by an iterator method.\n         *\n         * @param v {@code non-null;} block visited\n         * @param parent {@code null-ok;} parent node if applicable\n         */\n        void visitBlock(SsaBasicBlock v, SsaBasicBlock parent);\n    }\n\n    /**\n     * Label comparator.\n     */\n    public static final class LabelComparator\n            implements Comparator<SsaBasicBlock> {\n        /** {@inheritDoc} */\n        public int compare(SsaBasicBlock b1, SsaBasicBlock b2) {\n            int label1 = b1.ropLabel;\n            int label2 = b2.ropLabel;\n\n            if (label1 < label2) {\n                return -1;\n            } else if (label1 > label2) {\n                return 1;\n            } else {\n                return 0;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/SsaConverter.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.util.IntIterator;\nimport java.util.ArrayList;\nimport java.util.BitSet;\n\n/**\n * Converts ROP methods to SSA Methods\n */\npublic class SsaConverter {\n    public static final boolean DEBUG = false;\n\n    /**\n     * Returns an SSA representation, edge-split and with phi\n     * functions placed.\n     *\n     * @param rmeth input\n     * @param paramWidth the total width, in register-units, of the method's\n     * parameters\n     * @param isStatic {@code true} if this method has no {@code this}\n     * pointer argument\n     * @return output in SSA form\n     */\n    public static SsaMethod convertToSsaMethod(RopMethod rmeth,\n            int paramWidth, boolean isStatic) {\n        SsaMethod result\n            = SsaMethod.newFromRopMethod(rmeth, paramWidth, isStatic);\n\n        edgeSplit(result);\n\n        LocalVariableInfo localInfo = LocalVariableExtractor.extract(result);\n\n        placePhiFunctions(result, localInfo, 0);\n        new SsaRenamer(result).run();\n\n        /*\n         * The exit block, added here, is not considered for edge splitting\n         * or phi placement since no actual control flows to it.\n         */\n        result.makeExitBlock();\n\n        return result;\n    }\n\n    /**\n     * Updates an SSA representation, placing phi functions and renaming all\n     * registers above a certain threshold number.\n     *\n     * @param ssaMeth input\n     * @param threshold registers below this number are unchanged\n     */\n    public static void updateSsaMethod(SsaMethod ssaMeth, int threshold) {\n        LocalVariableInfo localInfo = LocalVariableExtractor.extract(ssaMeth);\n        placePhiFunctions(ssaMeth, localInfo, threshold);\n        new SsaRenamer(ssaMeth, threshold).run();\n    }\n\n    /**\n     * Returns an SSA represention with only the edge-splitter run.\n     *\n     * @param rmeth method to process\n     * @param paramWidth width of all arguments in the method\n     * @param isStatic {@code true} if this method has no {@code this}\n     * pointer argument\n     * @return an SSA represention with only the edge-splitter run\n     */\n    public static SsaMethod testEdgeSplit (RopMethod rmeth, int paramWidth,\n            boolean isStatic) {\n        SsaMethod result;\n\n        result = SsaMethod.newFromRopMethod(rmeth, paramWidth, isStatic);\n\n        edgeSplit(result);\n        return result;\n    }\n\n    /**\n     * Returns an SSA represention with only the steps through the\n     * phi placement run.\n     *\n     * @param rmeth method to process\n     * @param paramWidth width of all arguments in the method\n     * @param isStatic {@code true} if this method has no {@code this}\n     * pointer argument\n     * @return an SSA represention with only the edge-splitter run\n     */\n    public static SsaMethod testPhiPlacement (RopMethod rmeth, int paramWidth,\n            boolean isStatic) {\n        SsaMethod result;\n\n        result = SsaMethod.newFromRopMethod(rmeth, paramWidth, isStatic);\n\n        edgeSplit(result);\n\n        LocalVariableInfo localInfo = LocalVariableExtractor.extract(result);\n\n        placePhiFunctions(result, localInfo, 0);\n        return result;\n    }\n\n    /**\n     * See Appel section 19.1:\n     *\n     * Converts CFG into \"edge-split\" form, such that each node either a\n     * unique successor or unique predecessor.<p>\n     *\n     * In addition, the SSA form we use enforces a further constraint,\n     * requiring each block with a final instruction that returns a\n     * value to have a primary successor that has no other\n     * predecessor. This ensures move statements can always be\n     * inserted correctly when phi statements are removed.\n     *\n     * @param result method to process\n     */\n    private static void edgeSplit(SsaMethod result) {\n        edgeSplitPredecessors(result);\n        edgeSplitMoveExceptionsAndResults(result);\n        edgeSplitSuccessors(result);\n    }\n\n    /**\n     * Inserts Z nodes as new predecessors for every node that has multiple\n     * successors and multiple predecessors.\n     *\n     * @param result {@code non-null;} method to process\n     */\n    private static void edgeSplitPredecessors(SsaMethod result) {\n        ArrayList<SsaBasicBlock> blocks = result.getBlocks();\n\n        /*\n         * New blocks are added to the end of the block list during\n         * this iteration.\n         */\n        for (int i = blocks.size() - 1; i >= 0; i-- ) {\n            SsaBasicBlock block = blocks.get(i);\n            if (nodeNeedsUniquePredecessor(block)) {\n                block.insertNewPredecessor();\n            }\n        }\n    }\n\n    /**\n     * @param block {@code non-null;} block in question\n     * @return {@code true} if this node needs to have a unique\n     * predecessor created for it\n     */\n    private static boolean nodeNeedsUniquePredecessor(SsaBasicBlock block) {\n        /*\n         * Any block with that has both multiple successors and multiple\n         * predecessors needs a new predecessor node.\n         */\n\n        int countPredecessors = block.getPredecessors().cardinality();\n        int countSuccessors = block.getSuccessors().cardinality();\n\n        return  (countPredecessors > 1 && countSuccessors > 1);\n    }\n\n    /**\n     * In ROP form, move-exception must occur as the first insn in a block\n     * immediately succeeding the insn that could thrown an exception.\n     * We may need room to insert move insns later, so make sure to split\n     * any block that starts with a move-exception such that there is a\n     * unique move-exception block for each predecessor.\n     *\n     * @param ssaMeth method to process\n     */\n    private static void edgeSplitMoveExceptionsAndResults(SsaMethod ssaMeth) {\n        ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();\n\n        /*\n         * New blocks are added to the end of the block list during\n         * this iteration.\n         */\n        for (int i = blocks.size() - 1; i >= 0; i-- ) {\n            SsaBasicBlock block = blocks.get(i);\n\n            /*\n             * Any block that starts with a move-exception and has more than\n             * one predecessor...\n             */\n            if (!block.isExitBlock()\n                    && block.getPredecessors().cardinality() > 1\n                    && block.getInsns().get(0).isMoveException()) {\n\n                // block.getPredecessors() is changed in the loop below.\n                BitSet preds = (BitSet)block.getPredecessors().clone();\n                for (int j = preds.nextSetBit(0); j >= 0;\n                     j = preds.nextSetBit(j + 1)) {\n                    SsaBasicBlock predecessor = blocks.get(j);\n                    SsaBasicBlock zNode\n                        = predecessor.insertNewSuccessor(block);\n\n                    /*\n                     * Make sure to place the move-exception as the\n                     * first insn.\n                     */\n                    zNode.getInsns().add(0, block.getInsns().get(0).clone());\n                }\n\n                // Remove the move-exception from the original block.\n                block.getInsns().remove(0);\n            }\n        }\n    }\n\n    /**\n     * Inserts Z nodes for every node that needs a new\n     * successor.\n     *\n     * @param result {@code non-null;} method to process\n     */\n    private static void edgeSplitSuccessors(SsaMethod result) {\n        ArrayList<SsaBasicBlock> blocks = result.getBlocks();\n\n        /*\n         * New blocks are added to the end of the block list during\n         * this iteration.\n         */\n        for (int i = blocks.size() - 1; i >= 0; i-- ) {\n            SsaBasicBlock block = blocks.get(i);\n\n            // Successors list is modified in loop below.\n            BitSet successors = (BitSet)block.getSuccessors().clone();\n            for (int j = successors.nextSetBit(0);\n                 j >= 0; j = successors.nextSetBit(j+1)) {\n\n                SsaBasicBlock succ = blocks.get(j);\n\n                if (needsNewSuccessor(block, succ)) {\n                    block.insertNewSuccessor(succ);\n                }\n            }\n        }\n    }\n\n    /**\n     * Returns {@code true} if block and successor need a Z-node\n     * between them. Presently, this is {@code true} if the final\n     * instruction has any sources or results and the current\n     * successor block has more than one predecessor.\n     *\n     * @param block predecessor node\n     * @param succ successor node\n     * @return {@code true} if a Z node is needed\n     */\n    private static boolean needsNewSuccessor(SsaBasicBlock block,\n            SsaBasicBlock succ) {\n        ArrayList<SsaInsn> insns = block.getInsns();\n        SsaInsn lastInsn = insns.get(insns.size() - 1);\n\n        return ((lastInsn.getResult() != null)\n                    || (lastInsn.getSources().size() > 0))\n                && succ.getPredecessors().cardinality() > 1;\n    }\n\n    /**\n     * See Appel algorithm 19.6:\n     *\n     * Place Phi functions in appropriate locations.\n     *\n     * @param ssaMeth {@code non-null;} method to process.\n     * Modifications are made in-place.\n     * @param localInfo {@code non-null;} local variable info, used\n     * when placing phis\n     * @param threshold registers below this number are ignored\n     */\n    private static void placePhiFunctions (SsaMethod ssaMeth,\n            LocalVariableInfo localInfo, int threshold) {\n        ArrayList<SsaBasicBlock> ssaBlocks;\n        int regCount;\n        int blockCount;\n\n        ssaBlocks = ssaMeth.getBlocks();\n        blockCount = ssaBlocks.size();\n        regCount = ssaMeth.getRegCount() - threshold;\n\n        DomFront df = new DomFront(ssaMeth);\n        DomFront.DomInfo[] domInfos = df.run();\n\n        // Bit set of registers vs block index \"definition sites\"\n        BitSet[] defsites = new BitSet[regCount];\n\n        // Bit set of registers vs block index \"phi placement sites\"\n        BitSet[] phisites = new BitSet[regCount];\n\n        for (int i = 0; i < regCount; i++) {\n            defsites[i] = new BitSet(blockCount);\n            phisites[i] = new BitSet(blockCount);\n        }\n\n        /*\n         * For each register, build a set of all basic blocks where\n         * containing an assignment to that register.\n         */\n        for (int bi = 0, s = ssaBlocks.size(); bi < s; bi++) {\n            SsaBasicBlock b = ssaBlocks.get(bi);\n\n            for (SsaInsn insn : b.getInsns()) {\n                RegisterSpec rs = insn.getResult();\n\n                if (rs != null && rs.getReg() - threshold >= 0) {\n                    defsites[rs.getReg() - threshold].set(bi);\n                }\n            }\n        }\n\n        if (DEBUG) {\n            System.out.println(\"defsites\");\n\n            for (int i = 0; i < regCount; i++) {\n                StringBuilder sb = new StringBuilder();\n                sb.append('v').append(i).append(\": \");\n                sb.append(defsites[i].toString());\n                System.out.println(sb);\n            }\n        }\n\n        BitSet worklist;\n\n        /*\n         * For each register, compute all locations for phi placement\n         * based on dominance-frontier algorithm.\n         */\n        for (int reg = 0, s = regCount; reg < s; reg++) {\n            int workBlockIndex;\n\n            /* Worklist set starts out with each node where reg is assigned. */\n\n            worklist = (BitSet) (defsites[reg].clone());\n\n            while (0 <= (workBlockIndex = worklist.nextSetBit(0))) {\n                worklist.clear(workBlockIndex);\n                IntIterator dfIterator\n                    = domInfos[workBlockIndex].dominanceFrontiers.iterator();\n\n                while (dfIterator.hasNext()) {\n                    int dfBlockIndex = dfIterator.next();\n\n                    if (!phisites[reg].get(dfBlockIndex)) {\n                        phisites[reg].set(dfBlockIndex);\n\n                        int tReg = reg + threshold;\n                        RegisterSpec rs\n                            = localInfo.getStarts(dfBlockIndex).get(tReg);\n\n                        if (rs == null) {\n                            ssaBlocks.get(dfBlockIndex).addPhiInsnForReg(tReg);\n                        } else {\n                            ssaBlocks.get(dfBlockIndex).addPhiInsnForReg(rs);\n                        }\n\n                        if (!defsites[reg].get(dfBlockIndex)) {\n                            worklist.set(dfBlockIndex);\n                        }\n                    }\n                }\n            }\n        }\n\n        if (DEBUG) {\n            System.out.println(\"phisites\");\n\n            for (int i = 0; i < regCount; i++) {\n                StringBuilder sb = new StringBuilder();\n                sb.append('v').append(i).append(\": \");\n                sb.append(phisites[i].toString());\n                System.out.println(sb);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/SsaInsn.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.Insn;\nimport com.taobao.android.dx.rop.code.LocalItem;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rop;\nimport com.taobao.android.dx.util.ToHuman;\n\n/**\n * An instruction in SSA form\n */\npublic abstract class SsaInsn implements ToHuman, Cloneable {\n    /** {@code non-null;} the block that contains this instance */\n    private final SsaBasicBlock block;\n\n    /** {@code null-ok;} result register */\n    private RegisterSpec result;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param result {@code null-ok;} initial result register. May be changed.\n     * @param block {@code non-null;} block containing this insn. Can\n     * never change.\n     */\n    protected SsaInsn(RegisterSpec result, SsaBasicBlock block) {\n        if (block == null) {\n            throw new NullPointerException(\"block == null\");\n        }\n\n        this.block = block;\n        this.result = result;\n    }\n\n    /**\n     * Makes a new SSA insn form a rop insn.\n     *\n     * @param insn {@code non-null;} rop insn\n     * @param block {@code non-null;} owning block\n     * @return {@code non-null;} an appropriately constructed instance\n     */\n    public static SsaInsn makeFromRop(Insn insn, SsaBasicBlock block) {\n        return new NormalSsaInsn(insn, block);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public SsaInsn clone() {\n        try {\n            return (SsaInsn)super.clone();\n        } catch (CloneNotSupportedException ex) {\n            throw new RuntimeException (\"unexpected\", ex);\n        }\n    }\n\n    /**\n     * Like {@link com.taobao.android.dx.rop.code.Insn getResult()}.\n     *\n     * @return result register\n     */\n    public RegisterSpec getResult() {\n        return result;\n    }\n\n    /**\n     * Set the result register.\n     *\n     * @param result {@code non-null;} the new result register\n     */\n    protected void setResult(RegisterSpec result) {\n        if (result == null) {\n            throw new NullPointerException(\"result == null\");\n        }\n\n        this.result = result;\n    }\n\n    /**\n     * Like {@link com.taobao.android.dx.rop.code.Insn getSources()}.\n     *\n     * @return {@code non-null;} sources list\n     */\n    abstract public RegisterSpecList getSources();\n\n    /**\n     * Gets the block to which this insn instance belongs.\n     *\n     * @return owning block\n     */\n    public SsaBasicBlock getBlock() {\n        return block;\n    }\n\n    /**\n     * Returns whether or not the specified reg is the result reg.\n     *\n     * @param reg register to test\n     * @return true if there is a result and it is stored in the specified\n     * register\n     */\n    public boolean isResultReg(int reg) {\n        return result != null && result.getReg() == reg;\n    }\n\n\n    /**\n     * Changes the result register if this insn has a result. This is used\n     * during renaming.\n     *\n     * @param reg new result register\n     */\n    public void changeResultReg(int reg) {\n        if (result != null) {\n            result = result.withReg(reg);\n        }\n    }\n\n    /**\n     * Sets the local association for the result of this insn. This is\n     * sometimes updated during the SsaRenamer process.\n     *\n     * @param local {@code null-ok;} new debug/local variable info\n     */\n    public final void setResultLocal(LocalItem local) {\n        LocalItem oldItem = result.getLocalItem();\n\n        if (local != oldItem && (local == null\n                || !local.equals(result.getLocalItem()))) {\n            result = RegisterSpec.makeLocalOptional(\n                    result.getReg(), result.getType(), local);\n        }\n    }\n\n    /**\n     * Map registers after register allocation.\n     *\n     * @param mapper {@code non-null;} mapping from old to new registers\n     */\n    public final void mapRegisters(RegisterMapper mapper) {\n        RegisterSpec oldResult = result;\n\n        result = mapper.map(result);\n        block.getParent().updateOneDefinition(this, oldResult);\n        mapSourceRegisters(mapper);\n    }\n\n    /**\n     * Maps only source registers.\n     *\n     * @param mapper new mapping\n     */\n    abstract public void mapSourceRegisters(RegisterMapper mapper);\n\n    /**\n     * Returns the Rop opcode for this insn, or null if this is a phi insn.\n     *\n     * TODO: Move this up into NormalSsaInsn.\n     *\n     * @return {@code null-ok;} Rop opcode if there is one.\n     */\n    abstract public Rop getOpcode();\n\n    /**\n     * Returns the original Rop insn for this insn, or null if this is\n     * a phi insn.\n     *\n     * TODO: Move this up into NormalSsaInsn.\n     *\n     * @return {@code null-ok;} Rop insn if there is one.\n     */\n    abstract public Insn getOriginalRopInsn();\n\n    /**\n     * Gets the spec of a local variable assignment that occurs at this\n     * instruction, or null if no local variable assignment occurs. This\n     * may be the result register, or for {@code mark-local} insns\n     * it may be the source.\n     *\n     * @see com.taobao.android.dx.rop.code.Insn#getLocalAssignment()\n     *\n     * @return {@code null-ok;} a local-associated register spec or null\n     */\n    public RegisterSpec getLocalAssignment() {\n        if (result != null && result.getLocalItem() != null) {\n            return result;\n        }\n\n        return null;\n    }\n\n    /**\n     * Indicates whether the specified register is amongst the registers\n     * used as sources for this instruction.\n     *\n     * @param reg the register in question\n     * @return true if the reg is a source\n     */\n    public boolean isRegASource(int reg) {\n        return null != getSources().specForRegister(reg);\n    }\n\n    /**\n     * Transform back to ROP form.\n     *\n     * TODO: Move this up into NormalSsaInsn.\n     *\n     * @return {@code non-null;} a ROP representation of this instruction, with\n     * updated registers.\n     */\n    public abstract Insn toRopInsn();\n\n    /**\n     * @return true if this is a PhiInsn or a normal move insn\n     */\n    public abstract boolean isPhiOrMove();\n\n    /**\n     * Returns true if this insn is considered to have a side effect beyond\n     * that of assigning to the result reg.\n     *\n     * @return true if this insn is considered to have a side effect beyond\n     * that of assigning to the result reg.\n     */\n    public abstract boolean hasSideEffect();\n\n    /**\n     * @return true if this is a move (but not a move-operand or\n     * move-exception) instruction\n     */\n    public boolean isNormalMoveInsn() {\n        return false;\n    }\n\n    /**\n     * @return true if this is a move-exception instruction.\n     * These instructions must immediately follow a preceeding invoke*\n     */\n    public boolean isMoveException() {\n        return false;\n    }\n\n    /**\n     * @return true if this instruction can throw.\n     */\n    abstract public boolean canThrow();\n\n    /**\n     * Accepts a visitor.\n     *\n     * @param v {@code non-null} the visitor\n     */\n    public abstract void accept(Visitor v);\n\n    /**\n     * Visitor interface for this class.\n     */\n    public static interface Visitor {\n        /**\n         * Any non-phi move instruction\n         * @param insn {@code non-null;} the instruction to visit\n         */\n        public void visitMoveInsn(NormalSsaInsn insn);\n\n        /**\n         * Any phi insn\n         * @param insn {@code non-null;} the instruction to visit\n         */\n        public void visitPhiInsn(PhiInsn insn);\n\n        /**\n         * Any insn that isn't a move or a phi (which is also a move).\n         * @param insn {@code non-null;} the instruction to visit\n         */\n        public void visitNonMoveInsn(NormalSsaInsn insn);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/SsaMethod.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.BasicBlockList;\nimport com.taobao.android.dx.rop.code.Insn;\nimport com.taobao.android.dx.rop.code.PlainInsn;\nimport com.taobao.android.dx.rop.code.RegOps;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rop;\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.rop.code.Rops;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.util.IntList;\nimport java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.Stack;\n\n/**\n * A method in SSA form.\n */\npublic final class SsaMethod {\n    /** basic blocks, indexed by block index */\n    private ArrayList<SsaBasicBlock> blocks;\n\n    /** Index of first executed block in method */\n    private int entryBlockIndex;\n\n    /**\n     * Index of exit block, which exists only in SSA form,\n     * or or {@code -1} if there is none\n     */\n    private int exitBlockIndex;\n\n    /** total number of registers required */\n    private int registerCount;\n\n    /** first register number to use for any temporary \"spares\" */\n    private int spareRegisterBase;\n\n    /** current count of spare registers used */\n    private int borrowedSpareRegisters;\n\n    /** really one greater than the max label */\n    private int maxLabel;\n\n    /** the total width, in register-units, of the method's parameters */\n    private final int paramWidth;\n\n    /** true if this method has no {@code this} pointer argument */\n    private final boolean isStatic;\n\n    /**\n     * indexed by register: the insn where said register is defined or null\n     * if undefined. null until (lazily) created.\n     */\n    private SsaInsn[] definitionList;\n\n    /** indexed by register: the list of all insns that use a register */\n    private ArrayList<SsaInsn>[] useList;\n\n    /** A version of useList with each List unmodifiable */\n    private List<SsaInsn>[] unmodifiableUseList;\n\n    /**\n     * \"back-convert mode\". Set during back-conversion when registers\n     * are about to be mapped into a non-SSA namespace. When true,\n     * use and def lists are unavailable.\n     *\n     * TODO: Remove this mode, and place the functionality elsewhere\n     */\n    private boolean backMode;\n\n    /**\n     * @param ropMethod rop-form method to convert from\n     * @param paramWidth the total width, in register-units, of the\n     * method's parameters\n     * @param isStatic {@code true} if this method has no {@code this}\n     * pointer argument\n     */\n    public static SsaMethod newFromRopMethod(RopMethod ropMethod,\n            int paramWidth, boolean isStatic) {\n        SsaMethod result = new SsaMethod(ropMethod, paramWidth, isStatic);\n\n        result.convertRopToSsaBlocks(ropMethod);\n\n        return result;\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param ropMethod {@code non-null;} the original rop-form method that\n     * this instance is based on\n     * @param paramWidth the total width, in register-units, of the\n     * method's parameters\n     * @param isStatic {@code true} if this method has no {@code this}\n     * pointer argument\n     */\n    private SsaMethod(RopMethod ropMethod, int paramWidth, boolean isStatic) {\n        this.paramWidth = paramWidth;\n        this.isStatic = isStatic;\n        this.backMode = false;\n        this.maxLabel = ropMethod.getBlocks().getMaxLabel();\n        this.registerCount = ropMethod.getBlocks().getRegCount();\n        this.spareRegisterBase = registerCount;\n    }\n\n    /**\n     * Builds a BitSet of block indices from a basic block list and a list\n     * of labels taken from Rop form.\n     *\n     * @param blocks Rop blocks\n     * @param labelList list of rop block labels\n     * @return BitSet of block indices\n     */\n    static BitSet bitSetFromLabelList(BasicBlockList blocks,\n            IntList labelList) {\n        BitSet result = new BitSet(blocks.size());\n\n        for (int i = 0, sz = labelList.size(); i < sz; i++) {\n            result.set(blocks.indexOfLabel(labelList.get(i)));\n        }\n\n        return result;\n    }\n\n    /**\n     * Builds an IntList of block indices from a basic block list and a list\n     * of labels taken from Rop form.\n     *\n     * @param ropBlocks Rop blocks\n     * @param labelList list of rop block labels\n     * @return IntList of block indices\n     */\n    public static IntList indexListFromLabelList(BasicBlockList ropBlocks,\n            IntList labelList) {\n\n        IntList result = new IntList(labelList.size());\n\n        for (int i = 0, sz = labelList.size(); i < sz; i++) {\n            result.add(ropBlocks.indexOfLabel(labelList.get(i)));\n        }\n\n        return result;\n    }\n\n    private void convertRopToSsaBlocks(RopMethod rmeth) {\n        BasicBlockList ropBlocks = rmeth.getBlocks();\n        int sz = ropBlocks.size();\n\n        blocks = new ArrayList<SsaBasicBlock>(sz + 2);\n\n        for (int i = 0; i < sz; i++) {\n            SsaBasicBlock sbb = SsaBasicBlock.newFromRop(rmeth, i, this);\n            blocks.add(sbb);\n        }\n\n        // Add an no-op entry block.\n        int origEntryBlockIndex = rmeth.getBlocks()\n                .indexOfLabel(rmeth.getFirstLabel());\n\n        SsaBasicBlock entryBlock\n                = blocks.get(origEntryBlockIndex).insertNewPredecessor();\n\n        entryBlockIndex = entryBlock.getIndex();\n        exitBlockIndex = -1; // This gets made later.\n    }\n\n    /**\n     * Creates an exit block and attaches it to the CFG if this method\n     * exits. Methods that never exit will not have an exit block. This\n     * is called after edge-splitting and phi insertion, since the edges\n     * going into the exit block should not be considered in those steps.\n     */\n    /*package*/ void makeExitBlock() {\n        if (exitBlockIndex >= 0) {\n            throw new RuntimeException(\"must be called at most once\");\n        }\n\n        exitBlockIndex = blocks.size();\n        SsaBasicBlock exitBlock\n                = new SsaBasicBlock(exitBlockIndex, maxLabel++, this);\n\n        blocks.add(exitBlock);\n\n        for (SsaBasicBlock block : blocks) {\n            block.exitBlockFixup(exitBlock);\n        }\n\n        if (exitBlock.getPredecessors().cardinality() == 0) {\n            // In cases where there is no exit...\n            blocks.remove(exitBlockIndex);\n            exitBlockIndex = -1;\n            maxLabel--;\n        }\n    }\n\n    /**\n     * Gets a new {@code GOTO} insn.\n     *\n     * @param block block to which this GOTO will be added\n     * (not it's destination!)\n     * @return an appropriately-constructed instance.\n     */\n    private static SsaInsn getGoto(SsaBasicBlock block) {\n        return new NormalSsaInsn (\n                new PlainInsn(Rops.GOTO, SourcePosition.NO_INFO,\n                    null, RegisterSpecList.EMPTY), block);\n    }\n\n    /**\n     * Makes a new basic block for this method, which is empty besides\n     * a single {@code GOTO}. Successors and predecessors are not yet\n     * set.\n     *\n     * @return new block\n     */\n    public SsaBasicBlock makeNewGotoBlock() {\n        int newIndex = blocks.size();\n        SsaBasicBlock newBlock = new SsaBasicBlock(newIndex, maxLabel++, this);\n\n        newBlock.getInsns().add(getGoto(newBlock));\n        blocks.add(newBlock);\n\n        return newBlock;\n    }\n\n    /**\n     * @return block index of first execution block\n     */\n    public int getEntryBlockIndex() {\n        return entryBlockIndex;\n    }\n\n    /**\n     * @return first execution block\n     */\n    public SsaBasicBlock getEntryBlock() {\n        return blocks.get(entryBlockIndex);\n    }\n\n    /**\n     * @return block index of exit block or {@code -1} if there is none\n     */\n    public int getExitBlockIndex() {\n        return exitBlockIndex;\n    }\n\n    /**\n     * @return {@code null-ok;} block of exit block or {@code null} if\n     * there is none\n     */\n    public SsaBasicBlock getExitBlock() {\n        return exitBlockIndex < 0 ? null : blocks.get(exitBlockIndex);\n    }\n\n    /**\n     * @param bi block index or {@code -1} for none\n     * @return rop label or {code -1} if {@code bi} was {@code -1}\n     */\n    public int blockIndexToRopLabel(int bi) {\n        if (bi < 0) {\n            return -1;\n        }\n        return blocks.get(bi).getRopLabel();\n    }\n\n    /**\n     * @return count of registers used in this method\n     */\n    public int getRegCount() {\n        return registerCount;\n    }\n\n    /**\n     * @return the total width, in register units, of the method's\n     * parameters\n     */\n    public int getParamWidth() {\n        return paramWidth;\n    }\n\n    /**\n     * Returns {@code true} if this is a static method.\n     *\n     * @return {@code true} if this is a static method\n     */\n    public boolean isStatic() {\n        return isStatic;\n    }\n\n    /**\n     * Borrows a register to use as a temp. Used in the phi removal process.\n     * Call returnSpareRegisters() when done.\n     *\n     * @param category width (1 or 2) of the register\n     * @return register number to use\n     */\n    public int borrowSpareRegister(int category) {\n        int result = spareRegisterBase + borrowedSpareRegisters;\n\n        borrowedSpareRegisters += category;\n        registerCount = Math.max(registerCount, result + category);\n\n        return result;\n    }\n\n    /**\n     * Returns all borrowed registers.\n     */\n    public void returnSpareRegisters() {\n        borrowedSpareRegisters = 0;\n    }\n\n    /**\n     * @return {@code non-null;} basic block list. Do not modify.\n     */\n    public ArrayList<SsaBasicBlock> getBlocks() {\n        return blocks;\n    }\n\n    /**\n     * Returns the count of reachable blocks in this method: blocks that have\n     * predecessors (or are the start block)\n     *\n     * @return {@code >= 0;} number of reachable basic blocks\n     */\n    public int getCountReachableBlocks() {\n        int ret = 0;\n\n        for (SsaBasicBlock b : blocks) {\n            // Blocks that have been disconnected don't count.\n            if (b.isReachable()) {\n                ret++;\n            }\n        }\n\n        return ret;\n    }\n\n    /**\n     * Computes reachability for all blocks in the method. First clears old\n     * values from all blocks, then starts with the entry block and walks down\n     * the control flow graph, marking all blocks it finds as reachable.\n     */\n    public void computeReachability() {\n        for (SsaBasicBlock block : blocks) {\n            block.setReachable(0);\n        }\n\n        ArrayList<SsaBasicBlock> blockList = new ArrayList<SsaBasicBlock>();\n        blockList.add(this.getEntryBlock());\n\n        while (!blockList.isEmpty()) {\n            SsaBasicBlock block = blockList.remove(0);\n            if (block.isReachable()) continue;\n\n            block.setReachable(1);\n            BitSet succs = block.getSuccessors();\n            for (int i = succs.nextSetBit(0); i >= 0;\n                     i = succs.nextSetBit(i + 1)) {\n                blockList.add(blocks.get(i));\n            }\n        }\n    }\n\n    /**\n     * Remaps unversioned registers.\n     *\n     * @param mapper maps old registers to new.\n     */\n    public void mapRegisters(RegisterMapper mapper) {\n        for (SsaBasicBlock block : getBlocks()) {\n            for (SsaInsn insn : block.getInsns()) {\n                insn.mapRegisters(mapper);\n            }\n        }\n\n        registerCount = mapper.getNewRegisterCount();\n        spareRegisterBase = registerCount;\n    }\n\n    /**\n     * Returns the insn that defines the given register\n     * @param reg register in question\n     * @return insn (actual instance from code) that defined this reg or null\n     * if reg is not defined.\n     */\n    public SsaInsn getDefinitionForRegister(int reg) {\n        if (backMode) {\n            throw new RuntimeException(\"No def list in back mode\");\n        }\n\n        if (definitionList != null) {\n            return definitionList[reg];\n        }\n\n        definitionList = new SsaInsn[getRegCount()];\n\n        forEachInsn(new SsaInsn.Visitor() {\n            public void visitMoveInsn (NormalSsaInsn insn) {\n                definitionList[insn.getResult().getReg()] = insn;\n            }\n            public void visitPhiInsn (PhiInsn phi) {\n                definitionList[phi.getResult().getReg()] = phi;\n            }\n            public void visitNonMoveInsn (NormalSsaInsn insn) {\n                RegisterSpec result = insn.getResult();\n                if (result != null) {\n                    definitionList[insn.getResult().getReg()] = insn;\n                }\n            }\n        });\n\n        return definitionList[reg];\n    }\n\n    /**\n     * Builds useList and unmodifiableUseList.\n     */\n    private void buildUseList() {\n        if (backMode) {\n            throw new RuntimeException(\"No use list in back mode\");\n        }\n\n        useList = new ArrayList[registerCount];\n\n        for (int i = 0; i < registerCount; i++) {\n            useList[i] = new ArrayList();\n        }\n\n        forEachInsn(new SsaInsn.Visitor() {\n            /** {@inheritDoc} */\n            public void visitMoveInsn (NormalSsaInsn insn) {\n                addToUses(insn);\n            }\n            /** {@inheritDoc} */\n            public void visitPhiInsn (PhiInsn phi) {\n                addToUses(phi);\n            }\n            /** {@inheritDoc} */\n            public void visitNonMoveInsn (NormalSsaInsn insn) {\n                addToUses(insn);\n            }\n            /**\n             * Adds specified insn to the uses list for all of its sources.\n             * @param insn {@code non-null;} insn to process\n             */\n            private void addToUses(SsaInsn insn) {\n                RegisterSpecList rl = insn.getSources();\n                int sz = rl.size();\n\n                for (int i = 0; i < sz; i++) {\n                    useList[rl.get(i).getReg()].add(insn);\n                }\n            }\n        });\n\n        unmodifiableUseList = new List[registerCount];\n\n        for (int i = 0; i < registerCount; i++) {\n            unmodifiableUseList[i] = Collections.unmodifiableList(useList[i]);\n        }\n    }\n\n    /**\n     * Updates the use list for a single change in source register.\n     *\n     * @param insn {@code non-null;} insn being changed\n     * @param oldSource {@code null-ok;} The source that was used, if\n     * applicable\n     * @param newSource {@code non-null;} the new source being used\n     */\n    /*package*/ void onSourceChanged(SsaInsn insn,\n            RegisterSpec oldSource, RegisterSpec newSource) {\n        if (useList == null) return;\n\n        if (oldSource != null) {\n            int reg = oldSource.getReg();\n            useList[reg].remove(insn);\n        }\n\n        int reg = newSource.getReg();\n        if (useList.length <= reg) {\n            useList = null;\n            return;\n        }\n        useList[reg].add(insn);\n    }\n\n    /**\n     * Updates the use list for a source list change.\n     *\n     * @param insn {@code insn non-null;} insn being changed.\n     * {@code insn.getSources()} must return the new source list.\n     * @param oldSources {@code null-ok;} list of sources that were\n     * previously used\n     */\n    /*package*/ void onSourcesChanged(SsaInsn insn,\n            RegisterSpecList oldSources) {\n        if (useList == null) return;\n\n        if (oldSources != null) {\n            removeFromUseList(insn, oldSources);\n        }\n\n        RegisterSpecList sources = insn.getSources();\n        int szNew = sources.size();\n\n        for (int i = 0; i < szNew; i++) {\n            int reg = sources.get(i).getReg();\n            useList[reg].add(insn);\n        }\n    }\n\n    /**\n     * Removes a given {@code insn} from the use lists for the given\n     * {@code oldSources} (rather than the sources currently\n     * returned by insn.getSources()).\n     *\n     * @param insn {@code non-null;} insn in question\n     * @param oldSources {@code null-ok;} registers whose use lists\n     * {@code insn} should be removed form\n     */\n    private void removeFromUseList(SsaInsn insn, RegisterSpecList oldSources) {\n        if (oldSources == null) {\n            return;\n        }\n\n        int szNew = oldSources.size();\n        for (int i = 0; i < szNew; i++) {\n            if (!useList[oldSources.get(i).getReg()].remove(insn)) {\n                throw new RuntimeException(\"use not found\");\n            }\n        }\n    }\n\n    /**\n     * Adds an insn to both the use and def lists. For use when adding\n     * a new insn to the method.\n     *\n     * @param insn {@code non-null;} insn to add\n     */\n    /*package*/ void onInsnAdded(SsaInsn insn) {\n        onSourcesChanged(insn, null);\n        updateOneDefinition(insn, null);\n    }\n\n    /**\n     * Removes an instruction from use and def lists. For use during\n     * instruction removal.\n     *\n     * @param insn {@code non-null;} insn to remove\n     */\n    /*package*/ void onInsnRemoved(SsaInsn insn) {\n        if (useList != null) {\n            removeFromUseList(insn, insn.getSources());\n        }\n\n        RegisterSpec resultReg = insn.getResult();\n        if (definitionList != null && resultReg != null) {\n            definitionList[resultReg.getReg()] = null;\n        }\n    }\n\n    /**\n     * Indicates that the instruction list has changed or the SSA register\n     * count has increased, so that internal datastructures that rely on\n     * it should be rebuild. In general, the various other on* methods\n     * should be called in preference when changes occur if they are\n     * applicable.\n     */\n    public void onInsnsChanged() {\n        // Definition list will need to be recomputed\n        definitionList = null;\n\n        // Use list will need to be recomputed\n        useList = null;\n        unmodifiableUseList = null;\n    }\n\n    /**\n     * Updates a single definition.\n     *\n     * @param insn {@code non-null;} insn who's result should be recorded as\n     * a definition\n     * @param oldResult {@code null-ok;} a previous result that should\n     * be no longer considered a definition by this insn\n     */\n    /*package*/ void updateOneDefinition(SsaInsn insn,\n            RegisterSpec oldResult) {\n        if (definitionList == null) return;\n\n        if (oldResult != null) {\n            int reg = oldResult.getReg();\n            definitionList[reg] = null;\n        }\n\n        RegisterSpec resultReg = insn.getResult();\n\n        if (resultReg != null) {\n            int reg = resultReg.getReg();\n\n            if (definitionList[reg] != null) {\n                throw new RuntimeException(\"Duplicate add of insn\");\n            } else {\n                definitionList[resultReg.getReg()] = insn;\n            }\n        }\n    }\n\n    /**\n     * Returns the list of all source uses (not results) for a register.\n     *\n     * @param reg register in question\n     * @return unmodifiable instruction list\n     */\n    public List<SsaInsn> getUseListForRegister(int reg) {\n\n        if (unmodifiableUseList == null) {\n            buildUseList();\n        }\n\n        return unmodifiableUseList[reg];\n    }\n\n    /**\n     * Returns a modifiable copy of the register use list.\n     *\n     * @return modifiable copy of the use-list, indexed by register\n     */\n    public ArrayList<SsaInsn>[] getUseListCopy() {\n        if (useList == null) {\n            buildUseList();\n        }\n\n        ArrayList<SsaInsn>[] useListCopy\n                = (ArrayList<SsaInsn>[])(new ArrayList[registerCount]);\n\n        for (int i = 0; i < registerCount; i++) {\n            useListCopy[i] = (ArrayList<SsaInsn>)(new ArrayList(useList[i]));\n        }\n\n        return useListCopy;\n    }\n\n    /**\n     * Checks to see if the given SSA reg is ever associated with a local\n     * local variable. Each SSA reg may be associated with at most one\n     * local var.\n     *\n     * @param spec {@code non-null;} ssa reg\n     * @return true if reg is ever associated with a local\n     */\n    public boolean isRegALocal(RegisterSpec spec) {\n        SsaInsn defn = getDefinitionForRegister(spec.getReg());\n\n        if (defn == null) {\n            // version 0 registers are never used as locals\n            return false;\n        }\n\n        // Does the definition have a local associated with it?\n        if (defn.getLocalAssignment() != null) return true;\n\n        // If not, is there a mark-local insn?\n        for (SsaInsn use : getUseListForRegister(spec.getReg())) {\n            Insn insn = use.getOriginalRopInsn();\n\n            if (insn != null\n                    && insn.getOpcode().getOpcode() == RegOps.MARK_LOCAL) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Sets the new register count after renaming.\n     *\n     * @param newRegCount new register count\n     */\n    /*package*/ void setNewRegCount(int newRegCount) {\n        registerCount = newRegCount;\n        spareRegisterBase = registerCount;\n        onInsnsChanged();\n    }\n\n    /**\n     * Makes a new SSA register. For use after renaming has completed.\n     *\n     * @return {@code >=0;} new SSA register.\n     */\n    public int makeNewSsaReg() {\n        int reg = registerCount++;\n        spareRegisterBase = registerCount;\n        onInsnsChanged();\n        return reg;\n    }\n\n    /**\n     * Visits all insns in this method.\n     *\n     * @param visitor {@code non-null;} callback interface\n     */\n    public void forEachInsn(SsaInsn.Visitor visitor) {\n        for (SsaBasicBlock block : blocks) {\n            block.forEachInsn(visitor);\n        }\n    }\n\n    /**\n     * Visits each phi insn in this method\n     * @param v {@code non-null;} callback.\n     *\n     */\n    public void forEachPhiInsn(PhiInsn.Visitor v) {\n        for (SsaBasicBlock block : blocks) {\n            block.forEachPhiInsn(v);\n        }\n    }\n\n\n    /**\n     * Walks the basic block tree in depth-first order, calling the visitor\n     * method once for every block. This depth-first walk may be run forward\n     * from the method entry point or backwards from the method exit points.\n     *\n     * @param reverse true if this should walk backwards from the exit points\n     * @param v {@code non-null;} callback interface. {@code parent} is set\n     * unless this is the root node\n     */\n    public void forEachBlockDepthFirst(boolean reverse,\n            SsaBasicBlock.Visitor v) {\n        BitSet visited = new BitSet(blocks.size());\n\n        // We push the parent first, then the child on the stack.\n        Stack<SsaBasicBlock> stack = new Stack<SsaBasicBlock>();\n\n        SsaBasicBlock rootBlock = reverse ? getExitBlock() : getEntryBlock();\n\n        if (rootBlock == null) {\n            // in the case there's no exit block\n            return;\n        }\n\n        stack.add(null);    // Start with null parent.\n        stack.add(rootBlock);\n\n        while (stack.size() > 0) {\n            SsaBasicBlock cur = stack.pop();\n            SsaBasicBlock parent = stack.pop();\n\n            if (!visited.get(cur.getIndex())) {\n                BitSet children\n                    = reverse ? cur.getPredecessors() : cur.getSuccessors();\n                for (int i = children.nextSetBit(0); i >= 0\n                        ; i = children.nextSetBit(i + 1)) {\n                    stack.add(cur);\n                    stack.add(blocks.get(i));\n                }\n                visited.set(cur.getIndex());\n                v.visitBlock(cur, parent);\n            }\n        }\n    }\n\n    /**\n     * Visits blocks in dom-tree order, starting at the current node.\n     * The {@code parent} parameter of the Visitor.visitBlock callback\n     * is currently always set to null.\n     *\n     * @param v {@code non-null;} callback interface\n     */\n    public void forEachBlockDepthFirstDom(SsaBasicBlock.Visitor v) {\n        BitSet visited = new BitSet(getBlocks().size());\n        Stack<SsaBasicBlock> stack = new Stack<SsaBasicBlock>();\n\n        stack.add(getEntryBlock());\n\n        while (stack.size() > 0) {\n            SsaBasicBlock cur = stack.pop();\n            ArrayList<SsaBasicBlock> curDomChildren = cur.getDomChildren();\n\n            if (!visited.get(cur.getIndex())) {\n                // We walk the tree this way for historical reasons...\n                for (int i = curDomChildren.size() - 1; i >= 0; i--) {\n                    SsaBasicBlock child = curDomChildren.get(i);\n                    stack.add(child);\n                }\n                visited.set(cur.getIndex());\n                v.visitBlock(cur, null);\n            }\n        }\n    }\n\n    /**\n     * Deletes all insns in the set from this method.\n     *\n     * @param deletedInsns {@code non-null;} insns to delete\n     */\n    public void deleteInsns(Set<SsaInsn> deletedInsns) {\n        for (SsaBasicBlock block : getBlocks()) {\n            ArrayList<SsaInsn> insns = block.getInsns();\n\n            for (int i = insns.size() - 1; i >= 0; i--) {\n                SsaInsn insn = insns.get(i);\n\n                if (deletedInsns.contains(insn)) {\n                    onInsnRemoved(insn);\n                    insns.remove(i);\n                }\n            }\n\n            // Check to see if we need to add a GOTO\n\n            int insnsSz = insns.size();\n            SsaInsn lastInsn = (insnsSz == 0) ? null : insns.get(insnsSz - 1);\n\n            if (block != getExitBlock() && (insnsSz == 0\n                    || lastInsn.getOriginalRopInsn() == null\n                    || lastInsn.getOriginalRopInsn().getOpcode()\n                        .getBranchingness() == Rop.BRANCH_NONE)) {\n                // We managed to eat a throwable insn\n\n                Insn gotoInsn = new PlainInsn(Rops.GOTO,\n                        SourcePosition.NO_INFO, null, RegisterSpecList.EMPTY);\n                insns.add(SsaInsn.makeFromRop(gotoInsn, block));\n\n                // Remove secondary successors from this block\n                BitSet succs = block.getSuccessors();\n                for (int i = succs.nextSetBit(0); i >= 0;\n                         i = succs.nextSetBit(i + 1)) {\n                    if (i != block.getPrimarySuccessorIndex()) {\n                        block.removeSuccessor(i);\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * Sets \"back-convert mode\". Set during back-conversion when registers\n     * are about to be mapped into a non-SSA namespace. When true,\n     * use and def lists are unavailable.\n     */\n    public void setBackMode() {\n        backMode = true;\n        useList = null;\n        definitionList = null;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/SsaRenamer.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\nimport com.taobao.android.dx.rop.code.LocalItem;\nimport com.taobao.android.dx.rop.code.PlainInsn;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rops;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.rop.type.Type;\nimport com.taobao.android.dx.util.IntList;\nimport java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.HashMap;\nimport java.util.HashSet;\n\n/**\n * Complete transformation to SSA form by renaming all registers accessed.<p>\n *\n * See Appel algorithm 19.7<p>\n *\n * Unlike the original algorithm presented in Appel, this renamer converts\n * to a new flat (versionless) register space. The \"version 0\" registers,\n * which represent the initial state of the Rop registers and should never\n * actually be meaningfully accessed in a legal program, are represented\n * as the first N registers in the SSA namespace. Subsequent assignments\n * are assigned new unique names. Note that the incoming Rop representation\n * has a concept of register widths, where 64-bit values are stored into\n * two adjoining Rop registers. This adjoining register representation is\n * ignored in SSA form conversion and while in SSA form, each register can be e\n * either 32 or 64 bits wide depending on use. The adjoining-register\n * represention is re-created later when converting back to Rop form. <p>\n *\n * But, please note, the SSA Renamer's ignoring of the adjoining-register ROP\n * representation means that unaligned accesses to 64-bit registers are not\n * supported. For example, you cannot do a 32-bit operation on a portion of\n * a 64-bit register. This will never be observed to happen when coming\n * from Java code, of course.<p>\n *\n * The implementation here, rather than keeping a single register version\n * stack for the entire method as the dom tree is walked, instead keeps\n * a mapping table for the current block being processed. Once the\n * current block has been processed, this mapping table is then copied\n * and used as the initial state for child blocks.<p>\n */\npublic class SsaRenamer implements Runnable {\n    /** debug flag */\n    private static final boolean DEBUG = false;\n\n    /** method we're processing */\n    private final SsaMethod ssaMeth;\n\n    /** next available SSA register */\n    private int nextSsaReg;\n\n    /** the number of original rop registers */\n    private final int ropRegCount;\n\n    /** work only on registers above this value */\n    private int threshold;\n\n    /**\n     * indexed by block index; register version state for each block start.\n     * This list is updated by each dom parent for its children. The only\n     * sub-arrays that exist at any one time are the start states for blocks\n     * yet to be processed by a {@code BlockRenamer} instance.\n     */\n    private final RegisterSpec[][] startsForBlocks;\n\n    /** map of SSA register number to debug (local var names) or null of n/a */\n    private final ArrayList<LocalItem> ssaRegToLocalItems;\n\n    /**\n     * maps SSA registers back to the original rop number. Used for\n     * debug only.\n     */\n    private IntList ssaRegToRopReg;\n\n    /**\n     * Constructs an instance of the renamer\n     *\n     * @param ssaMeth {@code non-null;} un-renamed SSA method that will\n     * be renamed.\n     */\n    public SsaRenamer(SsaMethod ssaMeth) {\n        ropRegCount = ssaMeth.getRegCount();\n\n        this.ssaMeth = ssaMeth;\n\n        /*\n         * Reserve the first N registers in the SSA register space for\n         * \"version 0\" registers.\n         */\n        nextSsaReg = ropRegCount;\n        threshold = 0;\n        startsForBlocks = new RegisterSpec[ssaMeth.getBlocks().size()][];\n\n        ssaRegToLocalItems = new ArrayList<LocalItem>();\n\n        if (DEBUG) {\n            ssaRegToRopReg = new IntList(ropRegCount);\n        }\n\n        /*\n         * Appel 19.7\n         *\n         * Initialization:\n         *   for each variable a        // register i\n         *      Count[a] <- 0           // nextSsaReg, flattened\n         *      Stack[a] <- 0           // versionStack\n         *      push 0 onto Stack[a]\n         *\n         */\n\n        // top entry for the version stack is version 0\n        RegisterSpec[] initialRegMapping = new RegisterSpec[ropRegCount];\n        for (int i = 0; i < ropRegCount; i++) {\n            // everyone starts with a version 0 register\n            initialRegMapping[i] = RegisterSpec.make(i, Type.VOID);\n\n            if (DEBUG) {\n                ssaRegToRopReg.add(i);\n            }\n        }\n\n        // Initial state for entry block\n        startsForBlocks[ssaMeth.getEntryBlockIndex()] = initialRegMapping;\n    }\n\n    /**\n    * Constructs an instance of the renamer with threshold set\n    *\n    * @param ssaMeth {@code non-null;} un-renamed SSA method that will\n    * be renamed.\n    * @param thresh registers below this number are unchanged\n    */\n   public SsaRenamer(SsaMethod ssaMeth, int thresh) {\n       this(ssaMeth);\n       threshold = thresh;\n   }\n\n    /**\n     * Performs renaming transformation, modifying the method's instructions\n     * in-place.\n     */\n    public void run() {\n        // Rename each block in dom-tree DFS order.\n        ssaMeth.forEachBlockDepthFirstDom(new SsaBasicBlock.Visitor() {\n            public void visitBlock (SsaBasicBlock block,\n                    SsaBasicBlock unused) {\n                new BlockRenamer(block).process();\n            }\n        });\n\n        ssaMeth.setNewRegCount(nextSsaReg);\n        ssaMeth.onInsnsChanged();\n\n        if (DEBUG) {\n            System.out.println(\"SSA\\tRop\");\n            /*\n             * We're going to compute the version of the rop register\n             * by keeping a running total of how many times the rop\n             * register has been mapped.\n             */\n            int[] versions = new int[ropRegCount];\n\n            int sz = ssaRegToRopReg.size();\n            for (int i = 0; i < sz; i++) {\n                int ropReg = ssaRegToRopReg.get(i);\n                System.out.println(i + \"\\t\" + ropReg + \"[\"\n                        + versions[ropReg] + \"]\");\n                versions[ropReg]++;\n            }\n        }\n    }\n\n    /**\n     * Duplicates a RegisterSpec array.\n     *\n     * @param orig {@code non-null;} array to duplicate\n     * @return {@code non-null;} new instance\n     */\n    private static  RegisterSpec[] dupArray(RegisterSpec[] orig) {\n        RegisterSpec[] copy = new RegisterSpec[orig.length];\n\n        System.arraycopy(orig, 0, copy, 0, orig.length);\n\n        return copy;\n    }\n\n    /**\n     * Gets a local variable item for a specified register.\n     *\n     * @param ssaReg register in SSA name space\n     * @return {@code null-ok;} Local variable name or null if none\n     */\n    private LocalItem getLocalForNewReg(int ssaReg) {\n        if (ssaReg < ssaRegToLocalItems.size()) {\n            return ssaRegToLocalItems.get(ssaReg);\n        } else {\n            return null;\n        }\n    }\n\n    /**\n     * Records a debug (local variable) name for a specified register.\n     *\n     * @param ssaReg non-null named register spec in SSA name space\n     */\n    private void setNameForSsaReg(RegisterSpec ssaReg) {\n        int reg = ssaReg.getReg();\n        LocalItem local = ssaReg.getLocalItem();\n\n        ssaRegToLocalItems.ensureCapacity(reg + 1);\n        while (ssaRegToLocalItems.size() <= reg) {\n            ssaRegToLocalItems.add(null);\n        }\n\n        ssaRegToLocalItems.set(reg, local);\n    }\n\n    /**\n     * Returns true if this SSA register is below the specified threshold.\n     * Used when most code is already in SSA form, and renaming is needed only\n     * for registers above a certain threshold.\n     *\n     * @param ssaReg the SSA register in question\n     * @return {@code true} if its register number is below the threshold\n     */\n    private boolean isBelowThresholdRegister(int ssaReg) {\n        return ssaReg < threshold;\n    }\n\n    /**\n     * Returns true if this SSA register is a \"version 0\"\n     * register. All version 0 registers are assigned the first N register\n     * numbers, where N is the count of original rop registers.\n     *\n     * @param ssaReg the SSA register in question\n     * @return true if it is a version 0 register.\n     */\n    private boolean isVersionZeroRegister(int ssaReg) {\n        return ssaReg < ropRegCount;\n    }\n\n    /**\n     * Returns true if a and b are equal or are both null.\n     *\n     * @param a null-ok\n     * @param b null-ok\n     * @return Returns true if a and b are equal or are both null\n     */\n    private static boolean equalsHandlesNulls(Object a, Object b) {\n        return a == b ||  (a != null && a.equals(b));\n    }\n\n    /**\n     * Processes all insns in a block and renames their registers\n     * as appropriate.\n     */\n    private class BlockRenamer implements SsaInsn.Visitor{\n        /** {@code non-null;} block we're processing. */\n        private final SsaBasicBlock block;\n\n        /**\n         * {@code non-null;} indexed by old register name. The current\n         * top of the version stack as seen by this block. It's\n         * initialized from the ending state of its dom parent,\n         * updated as the block's instructions are processed, and then\n         * copied to each one of its dom children.\n         */\n        private final RegisterSpec[] currentMapping;\n\n        /**\n         * contains the set of moves we need to keep to preserve local\n         * var info. All other moves will be deleted.\n         */\n        private final HashSet<SsaInsn> movesToKeep;\n\n        /**\n         * maps the set of insns to replace after renaming is finished\n         * on the block.\n         */\n        private final HashMap<SsaInsn, SsaInsn> insnsToReplace;\n\n        private final RenamingMapper mapper;\n\n        /**\n         * Constructs a block renamer instance. Call {@code process}\n         * to process.\n         *\n         * @param block {@code non-null;} block to process\n         */\n        BlockRenamer(final SsaBasicBlock block) {\n            this.block = block;\n            currentMapping = startsForBlocks[block.getIndex()];\n            movesToKeep = new HashSet<SsaInsn>();\n            insnsToReplace = new HashMap<SsaInsn, SsaInsn>();\n            mapper =  new RenamingMapper();\n\n            // We don't need our own start state anymore\n            startsForBlocks[block.getIndex()] = null;\n        }\n\n        /**\n         * Provides a register mapping between the old register space\n         * and the current renaming mapping. The mapping is updated\n         * as the current block's instructions are processed.\n         */\n        private class RenamingMapper extends RegisterMapper {\n            public RenamingMapper() {\n                // This space intentionally left blank.\n            }\n\n            /** {@inheritDoc} */\n            @Override\n            public int getNewRegisterCount() {\n                return nextSsaReg;\n            }\n\n            /** {@inheritDoc} */\n            @Override\n            public RegisterSpec map(RegisterSpec registerSpec) {\n                if (registerSpec == null) return null;\n\n                int reg = registerSpec.getReg();\n\n                // For debugging: assert that the mapped types are compatible.\n                if (DEBUG) {\n                    RegisterSpec newVersion = currentMapping[reg];\n                    if (newVersion.getBasicType() != Type.BT_VOID\n                            && registerSpec.getBasicFrameType()\n                                != newVersion.getBasicFrameType()) {\n\n                        throw new RuntimeException(\n                                \"mapping registers of incompatible types! \"\n                                + registerSpec\n                                + \" \" + currentMapping[reg]);\n                    }\n                }\n\n                return registerSpec.withReg(currentMapping[reg].getReg());\n            }\n        }\n\n        /**\n         * Renames all the variables in this block and inserts appriopriate\n         * phis in successor blocks.\n         */\n        public void process() {\n            /*\n             * From Appel:\n             *\n             * Rename(n) =\n             *   for each statement S in block n   // 'statement' in 'block'\n             */\n\n            block.forEachInsn(this);\n\n            updateSuccessorPhis();\n\n            // Delete all move insns in this block.\n            ArrayList<SsaInsn> insns = block.getInsns();\n            int szInsns = insns.size();\n\n            for (int i = szInsns - 1; i >= 0 ; i--) {\n                SsaInsn insn = insns.get(i);\n                SsaInsn replaceInsn;\n\n                replaceInsn = insnsToReplace.get(insn);\n\n                if (replaceInsn != null) {\n                    insns.set(i, replaceInsn);\n                } else if (insn.isNormalMoveInsn()\n                        && !movesToKeep.contains(insn)) {\n                    insns.remove(i);\n                }\n            }\n\n            // Store the start states for our dom children.\n            boolean first = true;\n            for (SsaBasicBlock child : block.getDomChildren()) {\n                if (child != block) {\n                    // Don't bother duplicating the array for the first child.\n                    RegisterSpec[] childStart = first ? currentMapping\n                        : dupArray(currentMapping);\n\n                    startsForBlocks[child.getIndex()] = childStart;\n                    first = false;\n                }\n            }\n\n            // currentMapping is owned by a child now.\n        }\n\n        /**\n         * Enforces a few contraints when a register mapping is added.\n         *\n         * <ol>\n         * <li> Ensures that all new SSA registers specs in the mapping\n         * table with the same register number are identical. In effect, once\n         * an SSA register spec has received or lost a local variable name,\n         * then every old-namespace register that maps to it should gain or\n         * lose its local variable name as well.\n         * <li> Records the local name associated with the\n         * register so that a register is never associated with more than one\n         * local.\n         * <li> ensures that only one SSA register\n         * at a time is considered to be associated with a local variable. When\n         * {@code currentMapping} is updated and the newly added element\n         * is named, strip that name from any other SSA registers.\n         * </ol>\n         *\n         * @param ropReg {@code >= 0;} rop register number\n         * @param ssaReg {@code non-null;} an SSA register that has just\n         * been added to {@code currentMapping}\n         */\n        private void addMapping(int ropReg, RegisterSpec ssaReg) {\n            int ssaRegNum = ssaReg.getReg();\n            LocalItem ssaRegLocal = ssaReg.getLocalItem();\n\n            currentMapping[ropReg] = ssaReg;\n\n            /*\n             * Ensure all SSA register specs with the same reg are identical.\n             */\n            for (int i = currentMapping.length - 1; i >= 0; i--) {\n                RegisterSpec cur = currentMapping[i];\n\n                if (ssaRegNum == cur.getReg()) {\n                    currentMapping[i] = ssaReg;\n                }\n            }\n\n            // All further steps are for registers with local information.\n            if (ssaRegLocal == null) {\n                return;\n            }\n\n            // Record that this SSA reg has been associated with a local.\n            setNameForSsaReg(ssaReg);\n\n            // Ensure that no other SSA regs are associated with this local.\n            for (int i = currentMapping.length - 1; i >= 0; i--) {\n                RegisterSpec cur = currentMapping[i];\n\n                if (ssaRegNum != cur.getReg()\n                        && ssaRegLocal.equals(cur.getLocalItem())) {\n                    currentMapping[i] = cur.withLocalItem(null);\n                }\n            }\n        }\n\n        /**\n         * {@inheritDoc}\n         *\n         * Phi insns have their result registers renamed.\n         */\n        public void visitPhiInsn(PhiInsn phi) {\n            /* don't process sources for phi's */\n            processResultReg(phi);\n        }\n\n        /**\n         * {@inheritDoc}\n         *\n         * Move insns are treated as a simple mapping operation, and\n         * will later be removed unless they represent a local variable\n         * assignment. If they represent a local variable assignement, they\n         * are preserved.\n         */\n        public void visitMoveInsn(NormalSsaInsn insn) {\n            /*\n             * For moves: copy propogate the move if we can, but don't\n             * if we need to preserve local variable info and the\n             * result has a different name than the source.\n             */\n\n            RegisterSpec ropResult = insn.getResult();\n            int ropResultReg = ropResult.getReg();\n            int ropSourceReg = insn.getSources().get(0).getReg();\n\n            insn.mapSourceRegisters(mapper);\n            int ssaSourceReg = insn.getSources().get(0).getReg();\n\n            LocalItem sourceLocal\n                = currentMapping[ropSourceReg].getLocalItem();\n            LocalItem resultLocal = ropResult.getLocalItem();\n\n            /*\n             * A move from a register that's currently associated with a local\n             * to one that will not be associated with a local does not need\n             * to be preserved, but the local association should remain.\n             * Hence, we inherit the sourceLocal where the resultLocal is null.\n             */\n\n            LocalItem newLocal\n                = (resultLocal == null) ? sourceLocal : resultLocal;\n            LocalItem associatedLocal = getLocalForNewReg(ssaSourceReg);\n\n            /*\n             * If we take the new local, will only one local have ever\n             * been associated with this SSA reg?\n             */\n            boolean onlyOneAssociatedLocal\n                    = associatedLocal == null || newLocal == null\n                    || newLocal.equals(associatedLocal);\n\n            /*\n             * If we're going to copy-propogate, then the ssa register\n             * spec that's going to go into the mapping is made up of\n             * the source register number mapped from above, the type\n             * of the result, and the name either from the result (if\n             * specified) or inherited from the existing mapping.\n             *\n             * The move source has incomplete type information in null\n             * object cases, so the result type is used.\n             */\n            RegisterSpec ssaReg\n                    = RegisterSpec.makeLocalOptional(\n                        ssaSourceReg, ropResult.getType(), newLocal);\n\n            if (!Optimizer.getPreserveLocals() || (onlyOneAssociatedLocal\n                    && equalsHandlesNulls(newLocal, sourceLocal)) &&\n                    threshold == 0) {\n                /*\n                 * We don't have to keep this move to preserve local\n                 * information. Either the name is the same, or the result\n                 * register spec is unnamed.\n                 */\n\n                addMapping(ropResultReg, ssaReg);\n            } else if (onlyOneAssociatedLocal && sourceLocal == null &&\n                    threshold == 0) {\n                /*\n                 * The register was previously unnamed. This means that a\n                 * local starts after it's first assignment in SSA form\n                 */\n\n                RegisterSpecList ssaSources = RegisterSpecList.make(\n                        RegisterSpec.make(ssaReg.getReg(),\n                                ssaReg.getType(), newLocal));\n\n                SsaInsn newInsn\n                        = SsaInsn.makeFromRop(\n                            new PlainInsn(Rops.opMarkLocal(ssaReg),\n                            SourcePosition.NO_INFO, null, ssaSources),block);\n\n                insnsToReplace.put(insn, newInsn);\n\n                // Just map as above.\n                addMapping(ropResultReg, ssaReg);\n            } else {\n                /*\n                 * Do not copy-propogate, since the two registers have\n                 * two different local-variable names.\n                 */\n                processResultReg(insn);\n\n                movesToKeep.add(insn);\n            }\n        }\n\n        /**\n         * {@inheritDoc}\n         *\n         * All insns that are not move or phi insns have their source registers\n         * mapped ot the current mapping. Their result registers are then\n         * renamed to a new SSA register which is then added to the current\n         * register mapping.\n         */\n        public void visitNonMoveInsn(NormalSsaInsn insn) {\n            /* for each use of some variable X in S */\n            insn.mapSourceRegisters(mapper);\n\n            processResultReg(insn);\n        }\n\n        /**\n         * Renames the result register of this insn and updates the\n         * current register mapping. Does nothing if this insn has no result.\n         * Applied to all non-move insns.\n         *\n         * @param insn insn to process.\n         */\n        void processResultReg(SsaInsn insn) {\n            RegisterSpec ropResult = insn.getResult();\n\n            if (ropResult == null) {\n                return;\n            }\n\n            int ropReg = ropResult.getReg();\n            if (isBelowThresholdRegister(ropReg)) {\n                return;\n            }\n\n            insn.changeResultReg(nextSsaReg);\n            addMapping(ropReg, insn.getResult());\n\n            if (DEBUG) {\n                ssaRegToRopReg.add(ropReg);\n            }\n\n            nextSsaReg++;\n        }\n\n        /**\n         * Updates the phi insns in successor blocks with operands based\n         * on the current mapping of the rop register the phis represent.\n         */\n        private void updateSuccessorPhis() {\n            PhiInsn.Visitor visitor = new PhiInsn.Visitor() {\n                public void visitPhiInsn (PhiInsn insn) {\n                    int ropReg;\n\n                    ropReg = insn.getRopResultReg();\n                    if (isBelowThresholdRegister(ropReg)) {\n                        return;\n                    }\n\n                    /*\n                     * Never add a version 0 register as a phi\n                     * operand. Version 0 registers represent the\n                     * initial register state, and thus are never\n                     * significant. Furthermore, the register liveness\n                     * algorithm doesn't properly count them as \"live\n                     * in\" at the beginning of the method.\n                     */\n\n                    RegisterSpec stackTop = currentMapping[ropReg];\n                    if (!isVersionZeroRegister(stackTop.getReg())) {\n                        insn.addPhiOperand(stackTop, block);\n                    }\n                }\n            };\n\n            BitSet successors = block.getSuccessors();\n            for (int i = successors.nextSetBit(0); i >= 0;\n                    i = successors.nextSetBit(i + 1)) {\n                SsaBasicBlock successor = ssaMeth.getBlocks().get(i);\n                successor.forEachPhiInsn(visitor);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/back/FirstFitAllocator.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa.back;\n\nimport com.taobao.android.dx.rop.code.CstInsn;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.ssa.BasicRegisterMapper;\nimport com.taobao.android.dx.ssa.NormalSsaInsn;\nimport com.taobao.android.dx.ssa.RegisterMapper;\nimport com.taobao.android.dx.ssa.SsaMethod;\nimport com.taobao.android.dx.util.BitIntSet;\nimport com.taobao.android.dx.util.IntSet;\nimport java.util.BitSet;\n\n/**\n * Allocates registers via a naive n^2 register allocator.\n * This allocator does not try to co-locate local variables or deal\n * intelligently with different size register uses.\n */\npublic class FirstFitAllocator extends RegisterAllocator {\n    /**\n     * If true, allocator places parameters at the top of the frame\n     * in calling-convention order.\n     */\n    private static final boolean PRESLOT_PARAMS = true;\n\n    /** indexed by old reg; the set of old regs we've mapped */\n    private final BitSet mapped;\n\n    /** {@inheritDoc} */\n    public FirstFitAllocator(\n            final SsaMethod ssaMeth, final InterferenceGraph interference) {\n        super(ssaMeth, interference);\n\n        mapped = new BitSet(ssaMeth.getRegCount());\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean wantsParamsMovedHigh() {\n        return PRESLOT_PARAMS;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public RegisterMapper allocateRegisters() {\n        int oldRegCount = ssaMeth.getRegCount();\n\n        BasicRegisterMapper mapper\n                = new BasicRegisterMapper(oldRegCount);\n\n        int nextNewRegister = 0;\n\n        if (PRESLOT_PARAMS) {\n            /*\n             * Reserve space for the params at the bottom of the register\n             * space. Later, we'll flip the params to the end of the register\n             * space.\n             */\n\n            nextNewRegister = ssaMeth.getParamWidth();\n        }\n\n        for (int i = 0; i < oldRegCount; i++) {\n            if (mapped.get(i)) {\n                // we already got this one\n                continue;\n            }\n\n            int maxCategory = getCategoryForSsaReg(i);\n            IntSet current = new BitIntSet(oldRegCount);\n\n            interference.mergeInterferenceSet(i, current);\n\n            boolean isPreslotted = false;\n            int newReg = 0;\n\n            if (PRESLOT_PARAMS && isDefinitionMoveParam(i)) {\n                // Any move-param definition must be a NormalSsaInsn\n                NormalSsaInsn defInsn = (NormalSsaInsn)\n                       ssaMeth.getDefinitionForRegister(i);\n\n                newReg = paramNumberFromMoveParam(defInsn);\n\n                mapper.addMapping(i, newReg, maxCategory);\n                isPreslotted = true;\n            } else {\n                mapper.addMapping(i, nextNewRegister, maxCategory);\n                newReg = nextNewRegister;\n            }\n\n            for (int j = i + 1; j < oldRegCount; j++) {\n                if (mapped.get(j) || isDefinitionMoveParam(j)) {\n                    continue;\n                }\n\n                /*\n                 * If reg j doesn't interfere with the current mapping.\n                 * Also, if this is a pre-slotted method parameter, we\n                 * can't use more than the original param width.\n                 */\n                if (!current.has(j)\n                        && !(isPreslotted\n                            && (maxCategory < getCategoryForSsaReg(j)))) {\n\n                    interference.mergeInterferenceSet(j, current);\n\n                    maxCategory = Math.max(maxCategory,\n                            getCategoryForSsaReg(j));\n\n                    mapper.addMapping(j, newReg, maxCategory);\n                    mapped.set(j);\n                }\n            }\n\n            mapped.set(i);\n            if (!isPreslotted) {\n                nextNewRegister += maxCategory;\n            }\n        }\n\n        return mapper;\n    }\n\n    /**\n     * Returns the parameter number that this move-param insn refers to\n     * @param ndefInsn a move-param insn (otherwise, exceptions will be thrown)\n     * @return parameter number (offset in the total parameter width)\n     */\n    private int paramNumberFromMoveParam(NormalSsaInsn ndefInsn) {\n        CstInsn origInsn = (CstInsn) ndefInsn.getOriginalRopInsn();\n\n        return ((CstInteger) origInsn.getConstant()).getValue();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/back/FirstFitLocalCombiningAllocator.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa.back;\n\nimport com.taobao.android.dx.dex.DexOptions;\nimport com.taobao.android.dx.rop.code.CstInsn;\nimport com.taobao.android.dx.rop.code.LocalItem;\nimport com.taobao.android.dx.rop.code.RegOps;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rop;\nimport com.taobao.android.dx.rop.cst.CstInteger;\nimport com.taobao.android.dx.ssa.InterferenceRegisterMapper;\nimport com.taobao.android.dx.ssa.NormalSsaInsn;\nimport com.taobao.android.dx.ssa.Optimizer;\nimport com.taobao.android.dx.ssa.PhiInsn;\nimport com.taobao.android.dx.ssa.RegisterMapper;\nimport com.taobao.android.dx.ssa.SsaBasicBlock;\nimport com.taobao.android.dx.ssa.SsaInsn;\nimport com.taobao.android.dx.ssa.SsaMethod;\nimport com.taobao.android.dx.util.IntIterator;\nimport com.taobao.android.dx.util.IntSet;\nimport java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.Map;\nimport java.util.TreeMap;\n\n/**\n * Allocates registers in a first-fit fashion, with the bottom reserved for\n * method parameters and all SSAregisters representing the same local variable\n * kept together if possible.\n */\npublic class FirstFitLocalCombiningAllocator extends RegisterAllocator {\n\n    /**\n     * Alignment constraint that can be used during search of free registers.\n     */\n    private enum Alignment {\n      EVEN {\n        @Override\n        int nextClearBit(BitSet bitSet, int startIdx) {\n          int bitNumber = bitSet.nextClearBit(startIdx);\n          while (!isEven(bitNumber)) {\n            bitNumber = bitSet.nextClearBit(bitNumber + 1);\n          }\n          return bitNumber;\n        }\n      },\n      ODD {\n        @Override\n        int nextClearBit(BitSet bitSet, int startIdx) {\n          int bitNumber = bitSet.nextClearBit(startIdx);\n          while (isEven(bitNumber)) {\n            bitNumber = bitSet.nextClearBit(bitNumber + 1);\n          }\n          return bitNumber;\n        }\n      },\n      UNSPECIFIED {\n        @Override\n        int nextClearBit(BitSet bitSet, int startIdx) {\n          return bitSet.nextClearBit(startIdx);\n        }\n      };\n\n      /**\n       * Returns the index of the first bit that is set to {@code false} that occurs on or after the\n       * specified starting index and that respect {@link Alignment}.\n       *\n       * @param bitSet bitSet working on.\n       * @param startIdx {@code >= 0;} the index to start checking from (inclusive).\n       * @return the index of the next clear bit respecting alignment.\n       */\n      abstract int nextClearBit(BitSet bitSet, int startIdx);\n    }\n\n    /** local debug flag */\n    private static final boolean DEBUG = false;\n\n    /** maps local variable to a list of associated SSA registers */\n    private final Map<LocalItem, ArrayList<RegisterSpec>> localVariables;\n\n    /** list of move-result-pesudo instructions seen in this method */\n    private final ArrayList<NormalSsaInsn> moveResultPseudoInsns;\n\n    /** list of invoke-range instructions seen in this method */\n    private final ArrayList<NormalSsaInsn> invokeRangeInsns;\n\n    /** list of phi instructions seen in this method */\n    private final ArrayList<PhiInsn> phiInsns;\n\n    /** indexed by SSA reg; the set of SSA regs we've mapped */\n    private final BitSet ssaRegsMapped;\n\n    /** Register mapper which will be our result */\n    private final InterferenceRegisterMapper mapper;\n\n    /** end of rop registers range (starting at 0) reserved for parameters */\n    private final int paramRangeEnd;\n\n    /** set of rop registers reserved for parameters or local variables */\n    private final BitSet reservedRopRegs;\n\n    /** set of rop registers that have been used by anything */\n    private final BitSet usedRopRegs;\n\n    /** true if converter should take steps to minimize rop-form registers */\n    private final boolean minimizeRegisters;\n\n    /**\n     * Constructs instance.\n     *\n     * @param ssaMeth {@code non-null;} method to process\n     * @param interference non-null interference graph for SSA registers\n     * @param minimizeRegisters true if converter should take steps to\n     * minimize rop-form registers\n     */\n    public FirstFitLocalCombiningAllocator(\n            SsaMethod ssaMeth, InterferenceGraph interference,\n            boolean minimizeRegisters) {\n        super(ssaMeth, interference);\n\n        ssaRegsMapped = new BitSet(ssaMeth.getRegCount());\n\n        mapper = new InterferenceRegisterMapper(\n                interference, ssaMeth.getRegCount());\n\n        this.minimizeRegisters = minimizeRegisters;\n\n        /*\n         * Reserve space for the params at the bottom of the register\n         * space. Later, we'll flip the params to the end of the register\n         * space.\n         */\n\n        paramRangeEnd = ssaMeth.getParamWidth();\n\n        reservedRopRegs = new BitSet(paramRangeEnd * 2);\n        reservedRopRegs.set(0, paramRangeEnd);\n        usedRopRegs = new BitSet(paramRangeEnd * 2);\n        localVariables = new TreeMap<LocalItem, ArrayList<RegisterSpec>>();\n        moveResultPseudoInsns = new ArrayList<NormalSsaInsn>();\n        invokeRangeInsns = new ArrayList<NormalSsaInsn>();\n        phiInsns = new ArrayList<PhiInsn>();\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean wantsParamsMovedHigh() {\n        return true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public RegisterMapper allocateRegisters() {\n\n        analyzeInstructions();\n\n        if (DEBUG) {\n            printLocalVars();\n        }\n\n        if (DEBUG) System.out.println(\"--->Mapping local-associated params\");\n        handleLocalAssociatedParams();\n\n        if (DEBUG) System.out.println(\"--->Mapping other params\");\n        handleUnassociatedParameters();\n\n        if (DEBUG) System.out.println(\"--->Mapping invoke-range\");\n        handleInvokeRangeInsns();\n\n        if (DEBUG) {\n            System.out.println(\"--->Mapping local-associated non-params\");\n        }\n        handleLocalAssociatedOther();\n\n        if (DEBUG) System.out.println(\"--->Mapping check-cast results\");\n        handleCheckCastResults();\n\n        if (DEBUG) System.out.println(\"--->Mapping phis\");\n        handlePhiInsns();\n\n        if (DEBUG) System.out.println(\"--->Mapping others\");\n        handleNormalUnassociated();\n\n        return mapper;\n    }\n\n    /**\n     * Dumps local variable table to stdout for debugging.\n     */\n    private void printLocalVars() {\n        System.out.println(\"Printing local vars\");\n        for (Map.Entry<LocalItem, ArrayList<RegisterSpec>> e :\n                localVariables.entrySet()) {\n            StringBuilder regs = new StringBuilder();\n\n            regs.append('{');\n            regs.append(' ');\n            for (RegisterSpec reg : e.getValue()) {\n                regs.append('v');\n                regs.append(reg.getReg());\n                regs.append(' ');\n            }\n            regs.append('}');\n            System.out.printf(\"Local: %s Registers: %s\\n\", e.getKey(), regs);\n        }\n    }\n\n    /**\n     * Maps all local-associated parameters to rop registers.\n     */\n    private void handleLocalAssociatedParams() {\n        for (ArrayList<RegisterSpec> ssaRegs : localVariables.values()) {\n            int sz = ssaRegs.size();\n            int paramIndex = -1;\n            int paramCategory = 0;\n\n            // First, find out if this local variable is a parameter.\n            for (int i = 0; i < sz; i++) {\n                RegisterSpec ssaSpec = ssaRegs.get(i);\n                int ssaReg = ssaSpec.getReg();\n\n                paramIndex = getParameterIndexForReg(ssaReg);\n\n                if (paramIndex >= 0) {\n                    paramCategory = ssaSpec.getCategory();\n                    addMapping(ssaSpec, paramIndex);\n                    break;\n                }\n            }\n\n            if (paramIndex < 0) {\n                // This local wasn't a parameter.\n                continue;\n            }\n\n            // Any remaining local-associated registers will be mapped later.\n            tryMapRegs(ssaRegs, paramIndex, paramCategory, true);\n        }\n    }\n\n    /**\n     * Gets the parameter index for SSA registers that are method parameters.\n     * {@code -1} is returned for non-parameter registers.\n     *\n     * @param ssaReg {@code >=0;} SSA register to look up\n     * @return parameter index or {@code -1} if not a parameter\n     */\n    private int getParameterIndexForReg(int ssaReg) {\n        SsaInsn defInsn = ssaMeth.getDefinitionForRegister(ssaReg);\n        if (defInsn == null) {\n            return -1;\n        }\n\n        Rop opcode = defInsn.getOpcode();\n\n        // opcode == null for phi insns.\n        if (opcode != null && opcode.getOpcode() == RegOps.MOVE_PARAM) {\n            CstInsn origInsn = (CstInsn) defInsn.getOriginalRopInsn();\n            return  ((CstInteger) origInsn.getConstant()).getValue();\n        }\n\n        return -1;\n    }\n\n    /**\n     * Maps all local-associated registers that are not parameters.\n     * Tries to find an unreserved range that's wide enough for all of\n     * the SSA registers, and then tries to map them all to that\n     * range. If not all fit, a new range is tried until all registers\n     * have been fit.\n     */\n    private void handleLocalAssociatedOther() {\n        for (ArrayList<RegisterSpec> specs : localVariables.values()) {\n            int ropReg = paramRangeEnd;\n\n            boolean done = false;\n            do {\n                int maxCategory = 1;\n\n                // Compute max category for remaining unmapped registers.\n                int sz = specs.size();\n                for (int i = 0; i < sz; i++) {\n                    RegisterSpec ssaSpec = specs.get(i);\n                    int category = ssaSpec.getCategory();\n                    if (!ssaRegsMapped.get(ssaSpec.getReg())\n                            && category > maxCategory) {\n                        maxCategory = category;\n                    }\n                }\n\n                ropReg = findRopRegForLocal(ropReg, maxCategory);\n                if (canMapRegs(specs, ropReg)) {\n                    done = tryMapRegs(specs, ropReg, maxCategory, true);\n                }\n\n                // Increment for next call to findRopRegForLocal.\n                ropReg++;\n            } while (!done);\n        }\n    }\n\n    /**\n     * Tries to map a list of SSA registers into the a rop reg, marking\n     * used rop space as reserved. SSA registers that don't fit are left\n     * unmapped.\n     *\n     * @param specs {@code non-null;} SSA registers to attempt to map\n     * @param ropReg {@code >=0;} rop register to map to\n     * @param maxAllowedCategory {@code 1..2;} maximum category\n     * allowed in mapping.\n     * @param markReserved do so if {@code true}\n     * @return {@code true} if all registers were mapped, {@code false}\n     * if some remain unmapped\n     */\n    private boolean tryMapRegs(\n            ArrayList<RegisterSpec> specs, int ropReg,\n            int maxAllowedCategory, boolean markReserved) {\n        boolean remaining = false;\n        for (RegisterSpec spec : specs) {\n            if (ssaRegsMapped.get(spec.getReg())) {\n                continue;\n            }\n\n            boolean succeeded;\n            succeeded = tryMapReg(spec, ropReg, maxAllowedCategory);\n            remaining = !succeeded || remaining;\n            if (succeeded && markReserved) {\n                // This only needs to be called once really with\n                // the widest category used, but <shrug>\n                markReserved(ropReg, spec.getCategory());\n            }\n        }\n        return !remaining;\n    }\n\n    /**\n     * Tries to map an SSA register to a rop register.\n     *\n     * @param ssaSpec {@code non-null;} SSA register\n     * @param ropReg {@code >=0;} rop register\n     * @param maxAllowedCategory {@code 1..2;} the maximum category\n     * that the SSA register is allowed to be\n     * @return {@code true} if map succeeded, {@code false} if not\n     */\n    private boolean tryMapReg(RegisterSpec ssaSpec, int ropReg,\n            int maxAllowedCategory) {\n        if (ssaSpec.getCategory() <= maxAllowedCategory\n                && !ssaRegsMapped.get(ssaSpec.getReg())\n                && canMapReg(ssaSpec, ropReg)) {\n            addMapping(ssaSpec, ropReg);\n            return true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Marks a range of rop registers as \"reserved for a local variable.\"\n     *\n     * @param ropReg {@code >= 0;} rop register to reserve\n     * @param category {@code > 0;} width to reserve\n     */\n    private void markReserved(int ropReg, int category) {\n        reservedRopRegs.set(ropReg, ropReg + category, true);\n    }\n\n    /**\n     * Checks to see if any rop registers in the specified range are reserved\n     * for local variables or parameters.\n     *\n     * @param ropRangeStart {@code >= 0;} lowest rop register\n     * @param width {@code > 0;} number of rop registers in range.\n     * @return {@code true} if any register in range is marked reserved\n     */\n    private boolean rangeContainsReserved(int ropRangeStart, int width) {\n        for (int i = ropRangeStart; i < (ropRangeStart + width); i++) {\n            if (reservedRopRegs.get(i)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Returns true if given rop register represents the {@code this} pointer\n     * for a non-static method.\n     *\n     * @param startReg rop register\n     * @return true if the \"this\" pointer is located here.\n     */\n    private boolean isThisPointerReg(int startReg) {\n        // \"this\" is always the first parameter.\n        return startReg == 0 && !ssaMeth.isStatic();\n    }\n\n    /**\n     * Return the register alignment constraint to have 64-bits registers that will be align on even\n     * dalvik registers after that parameter registers are move up to the top of the frame to match\n     * the calling convention.\n     *\n     * @param regCategory category of the register that will be aligned.\n     * @return the register alignment constraint.\n     */\n    private Alignment getAlignment(int regCategory) {\n      Alignment alignment = Alignment.UNSPECIFIED;\n\n      if (DexOptions.ALIGN_64BIT_REGS_SUPPORT && regCategory == 2) {\n        if (isEven(paramRangeEnd)) {\n          alignment = Alignment.EVEN;\n        } else {\n          alignment = Alignment.ODD;\n        }\n      }\n\n      return alignment;\n    }\n\n    /**\n     * Finds unreserved rop registers with a specific category.\n     *\n     * @param startReg {@code >= 0;} a rop register to start the search at\n     * @param regCategory {@code > 0;} category of the searched registers.\n     * @return {@code >= 0;} start of available registers.\n     */\n    private int findNextUnreservedRopReg(int startReg, int regCategory) {\n      return findNextUnreservedRopReg(startReg, regCategory, getAlignment(regCategory));\n    }\n\n    /**\n     * Finds a range of unreserved rop registers.\n     *\n     * @param startReg {@code >= 0;} a rop register to start the search at\n     * @param width {@code > 0;} the width, in registers, required.\n     * @param alignment the alignment constraint.\n     * @return {@code >= 0;} start of available register range.\n     */\n    private int findNextUnreservedRopReg(int startReg, int width, Alignment alignment) {\n      int reg = alignment.nextClearBit(reservedRopRegs, startReg);\n\n      while (true) {\n        int i = 1;\n\n        while (i < width && !reservedRopRegs.get(reg + i)) {\n          i++;\n        }\n\n        if (i == width) {\n          return reg;\n        }\n\n        reg = alignment.nextClearBit(reservedRopRegs, reg + i);\n      }\n    }\n\n    /**\n     * Finds rop registers that can be used for local variables.\n     * If {@code MIX_LOCALS_AND_OTHER} is {@code false}, this means any\n     * rop register that has not yet been used.\n     *\n     * @param startReg {@code >= 0;} a rop register to start the search at\n     * @param category {@code > 0;} the register category required.\n     * @return {@code >= 0;} start of available registers.\n     */\n    private int findRopRegForLocal(int startReg, int category) {\n      Alignment alignment = getAlignment(category);\n      int reg = alignment.nextClearBit(usedRopRegs, startReg);\n\n      while (true) {\n        int i = 1;\n\n        while (i < category && !usedRopRegs.get(reg + i)) {\n          i++;\n        }\n\n        if (i == category) {\n          return reg;\n        }\n\n        reg = alignment.nextClearBit(usedRopRegs, reg + i);\n      }\n    }\n\n    /**\n     * Maps any parameter that isn't local-associated, which can happen\n     * in the case where there is no java debug info.\n     */\n    private void handleUnassociatedParameters() {\n        int szSsaRegs = ssaMeth.getRegCount();\n\n        for (int ssaReg = 0; ssaReg < szSsaRegs; ssaReg++) {\n            if (ssaRegsMapped.get(ssaReg)) {\n                // We already did this one above\n                continue;\n            }\n\n            int paramIndex = getParameterIndexForReg(ssaReg);\n\n            RegisterSpec ssaSpec = getDefinitionSpecForSsaReg(ssaReg);\n            if (paramIndex >= 0) {\n                addMapping(ssaSpec, paramIndex);\n            }\n        }\n    }\n\n    /**\n     * Handles all insns that want a register range for their sources.\n     */\n    private void handleInvokeRangeInsns() {\n        for (NormalSsaInsn insn : invokeRangeInsns) {\n            adjustAndMapSourceRangeRange(insn);\n        }\n    }\n\n    /**\n     * Handles check cast results to reuse the same source register.\n     * Inserts a move if it can't map the same register to both and the\n     * check cast is not caught.\n     */\n    private void handleCheckCastResults() {\n        for (NormalSsaInsn insn : moveResultPseudoInsns) {\n            RegisterSpec moveRegSpec = insn.getResult();\n            int moveReg = moveRegSpec.getReg();\n            BitSet predBlocks = insn.getBlock().getPredecessors();\n\n            // Expect one predecessor block only\n            if (predBlocks.cardinality() != 1) {\n                continue;\n            }\n\n            SsaBasicBlock predBlock =\n                    ssaMeth.getBlocks().get(predBlocks.nextSetBit(0));\n            ArrayList<SsaInsn> insnList = predBlock.getInsns();\n\n            /**\n             * If the predecessor block has a check-cast, it will be the last\n             * instruction\n             */\n            SsaInsn checkCastInsn = insnList.get(insnList.size() - 1);\n            if (checkCastInsn.getOpcode().getOpcode() != RegOps.CHECK_CAST) {\n                continue;\n            }\n\n            RegisterSpec checkRegSpec = checkCastInsn.getSources().get(0);\n            int checkReg = checkRegSpec.getReg();\n\n            /**\n             * See if either register is already mapped. Most likely the move\n             * result will be mapped already since the cast result is stored\n             * in a local variable.\n             */\n            int category = checkRegSpec.getCategory();\n            boolean moveMapped = ssaRegsMapped.get(moveReg);\n            boolean checkMapped = ssaRegsMapped.get(checkReg);\n            if (moveMapped & !checkMapped) {\n                int moveRopReg = mapper.oldToNew(moveReg);\n                checkMapped = tryMapReg(checkRegSpec, moveRopReg, category);\n            }\n            if (checkMapped & !moveMapped) {\n                int checkRopReg = mapper.oldToNew(checkReg);\n                moveMapped = tryMapReg(moveRegSpec, checkRopReg, category);\n            }\n\n            // Map any unmapped registers to anything available\n            if (!moveMapped || !checkMapped) {\n                int ropReg = findNextUnreservedRopReg(paramRangeEnd, category);\n                ArrayList<RegisterSpec> ssaRegs =\n                    new ArrayList<RegisterSpec>(2);\n                ssaRegs.add(moveRegSpec);\n                ssaRegs.add(checkRegSpec);\n\n                while (!tryMapRegs(ssaRegs, ropReg, category, false)) {\n                    ropReg = findNextUnreservedRopReg(ropReg + 1, category);\n                }\n            }\n\n            /*\n             * If source and result have a different mapping, insert a move so\n             * they can have the same mapping. Don't do this if the check cast\n             * is caught, since it will overwrite a potentially live value.\n             */\n            boolean hasExceptionHandlers =\n                checkCastInsn.getOriginalRopInsn().getCatches().size() != 0;\n            int moveRopReg = mapper.oldToNew(moveReg);\n            int checkRopReg = mapper.oldToNew(checkReg);\n            if (moveRopReg != checkRopReg && !hasExceptionHandlers) {\n                ((NormalSsaInsn) checkCastInsn).changeOneSource(0,\n                        insertMoveBefore(checkCastInsn, checkRegSpec));\n                addMapping(checkCastInsn.getSources().get(0), moveRopReg);\n            }\n        }\n    }\n\n    /**\n    * Handles all phi instructions, trying to map them to a common register.\n    */\n    private void handlePhiInsns() {\n        for (PhiInsn insn : phiInsns) {\n            processPhiInsn(insn);\n        }\n    }\n\n    /**\n     * Maps all non-parameter, non-local variable registers.\n     */\n    private void handleNormalUnassociated() {\n        int szSsaRegs = ssaMeth.getRegCount();\n\n        for (int ssaReg = 0; ssaReg < szSsaRegs; ssaReg++) {\n            if (ssaRegsMapped.get(ssaReg)) {\n                // We already did this one\n                continue;\n            }\n\n            RegisterSpec ssaSpec = getDefinitionSpecForSsaReg(ssaReg);\n\n            if (ssaSpec == null) continue;\n\n            int category = ssaSpec.getCategory();\n            // Find a rop reg that does not interfere\n            int ropReg = findNextUnreservedRopReg(paramRangeEnd, category);\n            while (!canMapReg(ssaSpec, ropReg)) {\n                ropReg = findNextUnreservedRopReg(ropReg + 1, category);\n            }\n\n            addMapping(ssaSpec, ropReg);\n        }\n    }\n\n    /**\n     * Checks to see if a list of SSA registers can all be mapped into\n     * the same rop reg. Ignores registers that have already been mapped,\n     * and checks the interference graph and ensures the range does not\n     * cross the parameter range.\n     *\n     * @param specs {@code non-null;} SSA registers to check\n     * @param ropReg {@code >=0;} rop register to check mapping to\n     * @return {@code true} if all unmapped registers can be mapped\n     */\n    private boolean canMapRegs(ArrayList<RegisterSpec> specs, int ropReg) {\n        for (RegisterSpec spec : specs) {\n            if (ssaRegsMapped.get(spec.getReg())) continue;\n            if (!canMapReg(spec, ropReg)) return false;\n        }\n        return true;\n    }\n\n    /**\n     * Checks to see if {@code ssaSpec} can be mapped to\n     * {@code ropReg}. Checks interference graph and ensures\n     * the range does not cross the parameter range.\n     *\n     * @param ssaSpec {@code non-null;} SSA spec\n     * @param ropReg prosepctive new-namespace reg\n     * @return {@code true} if mapping is possible\n     */\n    private boolean canMapReg(RegisterSpec ssaSpec, int ropReg) {\n        int category = ssaSpec.getCategory();\n        return !(spansParamRange(ropReg, category)\n                || mapper.interferes(ssaSpec, ropReg));\n    }\n\n    /**\n     * Returns true if the specified rop register + category\n     * will cross the boundry between the lower {@code paramWidth}\n     * registers reserved for method params and the upper registers. We cannot\n     * allocate a register that spans the param block and the normal block,\n     * because we will be moving the param block to high registers later.\n     *\n     * @param ssaReg register in new namespace\n     * @param category width that the register will have\n     * @return {@code true} in the case noted above\n     */\n    private boolean spansParamRange(int ssaReg, int category) {\n        return ((ssaReg < paramRangeEnd)\n                && ((ssaReg + category) > paramRangeEnd));\n    }\n\n    /**\n     * Analyze each instruction and find out all the local variable assignments\n     * and move-result-pseudo/invoke-range instrucitons.\n     */\n    private void analyzeInstructions() {\n        ssaMeth.forEachInsn(new SsaInsn.Visitor() {\n            /** {@inheritDoc} */\n            public void visitMoveInsn(NormalSsaInsn insn) {\n                processInsn(insn);\n            }\n\n            /** {@inheritDoc} */\n            public void visitPhiInsn(PhiInsn insn) {\n                processInsn(insn);\n            }\n\n            /** {@inheritDoc} */\n            public void visitNonMoveInsn(NormalSsaInsn insn) {\n                processInsn(insn);\n            }\n\n            /**\n             * This method collects three types of instructions:\n             *\n             * 1) Adds a local variable assignment to the\n             *    {@code localVariables} map.\n             * 2) Add move-result-pseudo to the\n             *    {@code moveResultPseudoInsns} list.\n             * 3) Add invoke-range to the\n             *    {@code invokeRangeInsns} list.\n             *\n             * @param insn {@code non-null;} insn that may represent a\n             * local variable assignment\n             */\n            private void processInsn(SsaInsn insn) {\n                RegisterSpec assignment;\n                assignment = insn.getLocalAssignment();\n\n                if (assignment != null) {\n                    LocalItem local = assignment.getLocalItem();\n\n                    ArrayList<RegisterSpec> regList\n                        = localVariables.get(local);\n\n                    if (regList == null) {\n                        regList = new ArrayList<RegisterSpec>();\n                        localVariables.put(local, regList);\n                    }\n\n                    regList.add(assignment);\n                }\n\n                if (insn instanceof NormalSsaInsn) {\n                    if (insn.getOpcode().getOpcode() ==\n                            RegOps.MOVE_RESULT_PSEUDO) {\n                        moveResultPseudoInsns.add((NormalSsaInsn) insn);\n                    } else if (Optimizer.getAdvice().requiresSourcesInOrder(\n                            insn.getOriginalRopInsn().getOpcode(),\n                            insn.getSources())) {\n                        invokeRangeInsns.add((NormalSsaInsn) insn);\n                    }\n                } else if (insn instanceof PhiInsn) {\n                    phiInsns.add((PhiInsn) insn);\n                }\n\n            }\n        });\n    }\n\n    /**\n     * Adds a mapping from an SSA register to a rop register.\n     * {@link #canMapReg} should have already been called.\n     *\n     * @param ssaSpec {@code non-null;} SSA register to map from\n     * @param ropReg {@code >=0;} rop register to map to\n     */\n    private void addMapping(RegisterSpec ssaSpec, int ropReg) {\n        int ssaReg = ssaSpec.getReg();\n\n        // An assertion.\n        if (ssaRegsMapped.get(ssaReg) || !canMapReg(ssaSpec, ropReg)) {\n            throw new RuntimeException(\n                    \"attempt to add invalid register mapping\");\n        }\n\n        if (DEBUG) {\n            System.out.printf(\"Add mapping s%d -> v%d c:%d\\n\",\n                    ssaSpec.getReg(), ropReg, ssaSpec.getCategory());\n        }\n\n        int category = ssaSpec.getCategory();\n        mapper.addMapping(ssaSpec.getReg(), ropReg, category);\n        ssaRegsMapped.set(ssaReg);\n        usedRopRegs.set(ropReg, ropReg + category);\n    }\n\n\n    /**\n     * Maps the source registers of the specified instruction such that they\n     * will fall in a contiguous range in rop form. Moves are inserted as\n     * necessary to allow the range to be allocated.\n     *\n     * @param insn {@code non-null;} insn whos sources to process\n     */\n    private void adjustAndMapSourceRangeRange(NormalSsaInsn insn) {\n        int newRegStart = findRangeAndAdjust(insn);\n\n        RegisterSpecList sources = insn.getSources();\n        int szSources = sources.size();\n        int nextRopReg = newRegStart;\n\n        for (int i = 0; i < szSources; i++) {\n            RegisterSpec source = sources.get(i);\n            int sourceReg = source.getReg();\n            int category = source.getCategory();\n            int curRopReg = nextRopReg;\n            nextRopReg += category;\n\n            if (ssaRegsMapped.get(sourceReg)) {\n                continue;\n            }\n\n            LocalItem localItem = getLocalItemForReg(sourceReg);\n            addMapping(source, curRopReg);\n\n            if (localItem != null) {\n                markReserved(curRopReg, category);\n                ArrayList<RegisterSpec> similarRegisters\n                        = localVariables.get(localItem);\n\n                int szSimilar = similarRegisters.size();\n\n                /*\n                 * Try to map all SSA registers also associated with\n                 * this local.\n                 */\n                for (int j = 0; j < szSimilar; j++) {\n                    RegisterSpec similarSpec = similarRegisters.get(j);\n                    int similarReg = similarSpec.getReg();\n\n                    // Don't map anything that's also a source.\n                    if (-1 != sources.indexOfRegister(similarReg)) {\n                        continue;\n                    }\n\n                    // Registers left unmapped will get handled later.\n                    tryMapReg(similarSpec, curRopReg, category);\n                }\n            }\n        }\n    }\n\n    /**\n     * Find a contiguous rop register range that fits the specified\n     * instruction's sources. First, try to center the range around\n     * sources that have already been mapped to rop registers. If that fails,\n     * just find a new contiguous range that doesn't interfere.\n     *\n     * @param insn {@code non-null;} the insn whose sources need to\n     * fit. Must be last insn in basic block.\n     * @return {@code >= 0;} rop register of start of range\n     */\n    private int findRangeAndAdjust(NormalSsaInsn insn) {\n        RegisterSpecList sources = insn.getSources();\n        int szSources = sources.size();\n        // the category for each source index\n        int categoriesForIndex[] = new int[szSources];\n        int rangeLength = 0;\n\n        // Compute rangeLength and categoriesForIndex\n        for (int i = 0; i < szSources; i++) {\n            int category = sources.get(i).getCategory();\n            categoriesForIndex[i] = category;\n            rangeLength += categoriesForIndex[i];\n        }\n\n        // the highest score of fits tried so far\n        int maxScore = Integer.MIN_VALUE;\n        // the high scoring range's start\n        int resultRangeStart = -1;\n        // by source index: set of sources needing moves in high scoring plan\n        BitSet resultMovesRequired = null;\n\n        /*\n         * First, go through each source that's already been mapped. Try\n         * to center the range around the rop register this source is mapped\n         * to.\n         */\n        int rangeStartOffset = 0;\n        for (int i = 0; i < szSources; i++) {\n            int ssaCenterReg = sources.get(i).getReg();\n\n            if (i != 0) {\n                rangeStartOffset -= categoriesForIndex[i - 1];\n            }\n            if (!ssaRegsMapped.get(ssaCenterReg)) {\n                continue;\n            }\n\n            int rangeStart = mapper.oldToNew(ssaCenterReg) + rangeStartOffset;\n\n            if (rangeStart < 0 || spansParamRange(rangeStart, rangeLength)) {\n                continue;\n            }\n\n            BitSet curMovesRequired = new BitSet(szSources);\n\n            int fitWidth\n                    = fitPlanForRange(rangeStart, insn, categoriesForIndex,\n                    curMovesRequired);\n\n            if (fitWidth < 0) {\n                continue;\n            }\n\n            int score = fitWidth - curMovesRequired.cardinality();\n\n            if (score > maxScore) {\n                maxScore = score;\n                resultRangeStart = rangeStart;\n                resultMovesRequired = curMovesRequired;\n            }\n\n            if (fitWidth == rangeLength) {\n                // We can't do any better than this, so stop here\n                break;\n            }\n        }\n\n        /*\n         * If we were unable to find a plan for a fit centered around\n         * an already-mapped source, just try to find a range of\n         * registers we can move the range into.\n         */\n\n        if (resultRangeStart == -1) {\n            resultMovesRequired = new BitSet(szSources);\n\n            resultRangeStart = findAnyFittingRange(insn, rangeLength,\n                    categoriesForIndex, resultMovesRequired);\n        }\n\n        /*\n         * Now, insert any moves required.\n         */\n\n        for (int i = resultMovesRequired.nextSetBit(0); i >= 0;\n             i = resultMovesRequired.nextSetBit(i+1)) {\n            insn.changeOneSource(i, insertMoveBefore(insn, sources.get(i)));\n        }\n\n        return resultRangeStart;\n    }\n\n    /**\n     * Finds an unreserved range that will fit the sources of the\n     * specified instruction. Does not bother trying to center the range\n     * around an already-mapped source register;\n     *\n     * @param insn {@code non-null;} insn to build range for\n     * @param rangeLength {@code >=0;} length required in register units\n     * @param categoriesForIndex {@code non-null;} indexed by source index;\n     * the category for each source\n     * @param outMovesRequired {@code non-null;} an output parameter indexed by\n     * source index that will contain the set of sources which need\n     * moves inserted\n     * @return the rop register that starts the fitting range\n     */\n    private int findAnyFittingRange(NormalSsaInsn insn, int rangeLength,\n            int[] categoriesForIndex, BitSet outMovesRequired) {\n        Alignment alignment = Alignment.UNSPECIFIED;\n\n        if (DexOptions.ALIGN_64BIT_REGS_SUPPORT) {\n          int regNumber = 0;\n          int p64bitsAligned = 0;\n          int p64bitsNotAligned = 0;\n          for (int category : categoriesForIndex) {\n            if (category == 2) {\n              if (isEven(regNumber)) {\n                p64bitsAligned++;\n              } else {\n                p64bitsNotAligned++;\n              }\n              regNumber += 2;\n            } else {\n              regNumber += 1;\n            }\n          }\n\n          if (p64bitsNotAligned > p64bitsAligned) {\n            if (isEven(paramRangeEnd)) {\n              alignment = Alignment.ODD;\n            } else {\n              alignment = Alignment.EVEN;\n            }\n          } else if (p64bitsAligned > 0) {\n            if (isEven(paramRangeEnd)) {\n              alignment = Alignment.EVEN;\n            } else {\n              alignment = Alignment.ODD;\n            }\n          }\n        }\n\n        int rangeStart = paramRangeEnd;\n        while (true) {\n          rangeStart = findNextUnreservedRopReg(rangeStart, rangeLength, alignment);\n\n          int fitWidth = fitPlanForRange(rangeStart, insn, categoriesForIndex, outMovesRequired);\n\n          if (fitWidth >= 0) {\n            break;\n          }\n          rangeStart++;\n          outMovesRequired.clear();\n        }\n\n        return rangeStart;\n    }\n\n    /**\n     * Attempts to build a plan for fitting a range of sources into rop\n     * registers.\n     *\n     * @param ropReg {@code >= 0;} rop reg that begins range\n     * @param insn {@code non-null;} insn to plan range for\n     * @param categoriesForIndex {@code non-null;} indexed by source index;\n     * the category for each source\n     * @param outMovesRequired {@code non-null;} an output parameter indexed by\n     * source index that will contain the set of sources which need\n     * moves inserted\n     * @return the width of the fit that that does not involve added moves or\n     * {@code -1} if \"no fit possible\"\n     */\n    private int fitPlanForRange(int ropReg, NormalSsaInsn insn,\n            int[] categoriesForIndex, BitSet outMovesRequired) {\n        RegisterSpecList sources = insn.getSources();\n        int szSources = sources.size();\n        int fitWidth = 0;\n        IntSet liveOut = insn.getBlock().getLiveOutRegs();\n        RegisterSpecList liveOutSpecs = ssaSetToSpecs(liveOut);\n\n        // An SSA reg may only be mapped into a range once.\n        BitSet seen = new BitSet(ssaMeth.getRegCount());\n\n        for (int i = 0; i < szSources ; i++) {\n            RegisterSpec ssaSpec = sources.get(i);\n            int ssaReg = ssaSpec.getReg();\n            int category = categoriesForIndex[i];\n\n            if (i != 0) {\n                ropReg += categoriesForIndex[i-1];\n            }\n\n            if (ssaRegsMapped.get(ssaReg)\n                    && mapper.oldToNew(ssaReg) == ropReg) {\n                // This is a register that is already mapped appropriately.\n                fitWidth += category;\n            } else if (rangeContainsReserved(ropReg, category)) {\n                fitWidth = -1;\n                break;\n            } else if (!ssaRegsMapped.get(ssaReg)\n                    && canMapReg(ssaSpec, ropReg)\n                    && !seen.get(ssaReg)) {\n                // This is a register that can be mapped appropriately.\n                fitWidth += category;\n            } else if (!mapper.areAnyPinned(liveOutSpecs, ropReg, category)\n                    && !mapper.areAnyPinned(sources, ropReg, category)) {\n                /*\n                 * This is a source that can be moved. We can insert a\n                 * move as long as:\n                 *\n                 *   * no SSA register pinned to the desired rop reg\n                 *     is live out on the block\n                 *\n                 *   * no SSA register pinned to desired rop reg is\n                 *     a source of this insn (since this may require\n                 *     overlapping moves, which we can't presently handle)\n                 */\n\n                outMovesRequired.set(i);\n            } else {\n                fitWidth = -1;\n                break;\n            }\n\n            seen.set(ssaReg);\n        }\n        return fitWidth;\n    }\n\n    /**\n     * Converts a bit set of SSA registers into a RegisterSpecList containing\n     * the definition specs of all the registers.\n     *\n     * @param ssaSet {@code non-null;} set of SSA registers\n     * @return list of RegisterSpecs as noted above\n     */\n    RegisterSpecList ssaSetToSpecs(IntSet ssaSet) {\n        RegisterSpecList result = new RegisterSpecList(ssaSet.elements());\n\n        IntIterator iter = ssaSet.iterator();\n\n        int i = 0;\n        while (iter.hasNext()) {\n            result.set(i++, getDefinitionSpecForSsaReg(iter.next()));\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets a local item associated with an ssa register, if one exists.\n     *\n     * @param ssaReg {@code >= 0;} SSA register\n     * @return {@code null-ok;} associated local item or null\n     */\n    private LocalItem getLocalItemForReg(int ssaReg) {\n        for (Map.Entry<LocalItem, ArrayList<RegisterSpec>> entry :\n                 localVariables.entrySet()) {\n            for (RegisterSpec spec : entry.getValue()) {\n                if (spec.getReg() == ssaReg) {\n                    return entry.getKey();\n                }\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Attempts to map the sources and result of a phi to a common register.\n     * Will try existing mappings first, from most to least common. If none\n     * of the registers have mappings yet, a new mapping is created.\n     */\n    private void processPhiInsn(PhiInsn insn) {\n        RegisterSpec result = insn.getResult();\n        int resultReg = result.getReg();\n        int category = result.getCategory();\n\n        RegisterSpecList sources = insn.getSources();\n        int sourcesSize = sources.size();\n\n        // List of phi sources / result that need mapping\n        ArrayList<RegisterSpec> ssaRegs = new ArrayList<RegisterSpec>();\n\n        // Track how many times a particular mapping is found\n        Multiset mapSet = new Multiset(sourcesSize + 1);\n\n        /*\n         * If the result of the phi has an existing mapping, get it.\n         * Otherwise, add it to the list of regs that need mapping.\n         */\n        if (ssaRegsMapped.get(resultReg)) {\n            mapSet.add(mapper.oldToNew(resultReg));\n        } else {\n            ssaRegs.add(result);\n        }\n\n        for (int i = 0; i < sourcesSize; i++) {\n            RegisterSpec source = sources.get(i);\n            SsaInsn def = ssaMeth.getDefinitionForRegister(source.getReg());\n            RegisterSpec sourceDef = def.getResult();\n            int sourceReg = sourceDef.getReg();\n\n            /*\n             * If a source of the phi has an existing mapping, get it.\n             * Otherwise, add it to the list of regs that need mapping.\n             */\n            if (ssaRegsMapped.get(sourceReg)) {\n                mapSet.add(mapper.oldToNew(sourceReg));\n            } else {\n                ssaRegs.add(sourceDef);\n            }\n        }\n\n        // Try all existing mappings, with the most common ones first\n        for (int i = 0; i < mapSet.getSize(); i++) {\n            int maxReg = mapSet.getAndRemoveHighestCount();\n            tryMapRegs(ssaRegs, maxReg, category, false);\n        }\n\n        // Map any remaining unmapped regs with whatever fits\n        int mapReg = findNextUnreservedRopReg(paramRangeEnd, category);\n        while (!tryMapRegs(ssaRegs, mapReg, category, false)) {\n            mapReg = findNextUnreservedRopReg(mapReg + 1, category);\n        }\n    }\n\n    private static boolean isEven(int regNumger) {\n      return ((regNumger & 1) == 0);\n    }\n\n    // A set that tracks how often elements are added to it.\n    private static class Multiset {\n        private final int[] reg;\n        private final int[] count;\n        private int size;\n\n        /**\n         * Constructs an instance.\n         *\n         * @param maxSize the maximum distinct elements the set may have\n         */\n        public Multiset(int maxSize) {\n            reg = new int[maxSize];\n            count = new int[maxSize];\n            size = 0;\n        }\n\n        /**\n         * Adds an element to the set.\n         *\n         * @param element element to add\n         */\n        public void add(int element) {\n            for (int i = 0; i < size; i++) {\n                if (reg[i] == element) {\n                    count[i]++;\n                    return;\n                }\n            }\n\n            reg[size] = element;\n            count[size] = 1;\n            size++;\n        }\n\n        /**\n         * Searches the set for the element that has been added the most.\n         * In the case of a tie, the element that was added first is returned.\n         * Then, it clears the count on that element. The size of the set\n         * remains unchanged.\n         *\n         * @return element with the highest count\n         */\n        public int getAndRemoveHighestCount() {\n            int maxIndex = -1;\n            int maxReg = -1;\n            int maxCount = 0;\n\n            for (int i = 0; i < size; i++) {\n                if (maxCount < count[i]) {\n                    maxIndex = i;\n                    maxReg = reg[i];\n                    maxCount = count[i];\n                }\n            }\n\n            count[maxIndex] = 0;\n            return maxReg;\n        }\n\n        /**\n         * Gets the number of distinct elements in the set.\n         *\n         * @return size of the set\n         */\n        public int getSize() {\n            return size;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/back/IdenticalBlockCombiner.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa.back;\n\nimport com.taobao.android.dx.rop.code.BasicBlock;\nimport com.taobao.android.dx.rop.code.BasicBlockList;\nimport com.taobao.android.dx.rop.code.RegOps;\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.util.IntList;\nimport java.util.BitSet;\n\n/**\n * Searches for basic blocks that all have the same successor and insns\n * but different predecessors. These blocks are then combined into a single\n * block and the now-unused blocks are deleted. These identical blocks\n * frequently are created when catch blocks are edge-split.\n */\npublic class IdenticalBlockCombiner {\n    private final RopMethod ropMethod;\n    private final BasicBlockList blocks;\n    private final BasicBlockList newBlocks;\n\n    /**\n     * Constructs instance. Call {@code process()} to run.\n     *\n     * @param rm {@code non-null;} instance to process\n     */\n    public IdenticalBlockCombiner(RopMethod rm) {\n        ropMethod = rm;\n        blocks = ropMethod.getBlocks();\n        newBlocks = blocks.getMutableCopy();\n    }\n\n    /**\n     * Runs algorithm. TODO: This is n^2, and could be made linear-ish with\n     * a hash. In particular, hash the contents of each block and only\n     * compare blocks with the same hash.\n     *\n     * @return {@code non-null;} new method that has been processed\n     */\n    public RopMethod process() {\n        int szBlocks = blocks.size();\n        // indexed by label\n        BitSet toDelete = new BitSet(blocks.getMaxLabel());\n\n        // For each non-deleted block...\n        for (int bindex = 0; bindex < szBlocks; bindex++) {\n            BasicBlock b = blocks.get(bindex);\n\n            if (toDelete.get(b.getLabel())) {\n                // doomed block\n                continue;\n            }\n\n            IntList preds = ropMethod.labelToPredecessors(b.getLabel());\n\n            // ...look at all of it's predecessors that have only one succ...\n            int szPreds = preds.size();\n            for (int i = 0; i < szPreds; i++) {\n                int iLabel = preds.get(i);\n\n                BasicBlock iBlock = blocks.labelToBlock(iLabel);\n\n                if (toDelete.get(iLabel)\n                        || iBlock.getSuccessors().size() > 1\n                        || iBlock.getFirstInsn().getOpcode().getOpcode() ==\n                            RegOps.MOVE_RESULT) {\n                    continue;\n                }\n\n                IntList toCombine = new IntList();\n\n                // ...and see if they can be combined with any other preds...\n                for (int j = i + 1; j < szPreds; j++) {\n                    int jLabel = preds.get(j);\n                    BasicBlock jBlock = blocks.labelToBlock(jLabel);\n\n                    if (jBlock.getSuccessors().size() == 1\n                            && compareInsns(iBlock, jBlock)) {\n\n                        toCombine.add(jLabel);\n                        toDelete.set(jLabel);\n                    }\n                }\n\n                combineBlocks(iLabel, toCombine);\n            }\n        }\n\n        for (int i = szBlocks - 1; i >= 0; i--) {\n            if (toDelete.get(newBlocks.get(i).getLabel())) {\n                newBlocks.set(i, null);\n            }\n        }\n\n        newBlocks.shrinkToFit();\n        newBlocks.setImmutable();\n\n        return new RopMethod(newBlocks, ropMethod.getFirstLabel());\n    }\n\n    /**\n     * Helper method to compare the contents of two blocks.\n     *\n     * @param a {@code non-null;} a block to compare\n     * @param b {@code non-null;} another block to compare\n     * @return {@code true} iff the two blocks' instructions are the same\n     */\n    private static boolean compareInsns(BasicBlock a, BasicBlock b) {\n        return a.getInsns().contentEquals(b.getInsns());\n    }\n\n    /**\n     * Combines blocks proven identical into one alpha block, re-writing\n     * all of the successor links that point to the beta blocks to point\n     * to the alpha block instead.\n     *\n     * @param alphaLabel block that will replace all the beta block\n     * @param betaLabels label list of blocks to combine\n     */\n    private void combineBlocks(int alphaLabel, IntList betaLabels) {\n        int szBetas = betaLabels.size();\n\n        for (int i = 0; i < szBetas; i++) {\n            int betaLabel = betaLabels.get(i);\n            BasicBlock bb = blocks.labelToBlock(betaLabel);\n            IntList preds = ropMethod.labelToPredecessors(bb.getLabel());\n            int szPreds = preds.size();\n\n            for (int j = 0; j < szPreds; j++) {\n                BasicBlock predBlock = newBlocks.labelToBlock(preds.get(j));\n                replaceSucc(predBlock, betaLabel, alphaLabel);\n            }\n        }\n    }\n\n    /**\n     * Replaces one of a block's successors with a different label. Constructs\n     * an updated BasicBlock instance and places it in {@code newBlocks}.\n     *\n     * @param block block to replace\n     * @param oldLabel label of successor to replace\n     * @param newLabel label of new successor\n     */\n    private void replaceSucc(BasicBlock block, int oldLabel, int newLabel) {\n        IntList newSuccessors = block.getSuccessors().mutableCopy();\n        int newPrimarySuccessor;\n\n        newSuccessors.set(newSuccessors.indexOf(oldLabel), newLabel);\n        newPrimarySuccessor = block.getPrimarySuccessor();\n\n        if (newPrimarySuccessor == oldLabel) {\n            newPrimarySuccessor = newLabel;\n        }\n\n        newSuccessors.setImmutable();\n\n        BasicBlock newBB = new BasicBlock(block.getLabel(),\n                block.getInsns(), newSuccessors, newPrimarySuccessor);\n\n        newBlocks.set(newBlocks.indexOfLabel(block.getLabel()), newBB);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/back/InterferenceGraph.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa.back;\n\nimport com.taobao.android.dx.ssa.SetFactory;\nimport com.taobao.android.dx.util.IntSet;\nimport java.util.ArrayList;\n\n/**\n * A register interference graph\n */\npublic class InterferenceGraph {\n    /**\n     * {@code non-null;} interference graph, indexed by register in\n     * both dimensions\n     */\n    private final ArrayList<IntSet> interference;\n\n    /**\n     * Creates a new graph.\n     *\n     * @param countRegs {@code >= 0;} the start count of registers in\n     * the namespace. New registers can be added subsequently.\n     */\n    public InterferenceGraph(int countRegs) {\n        interference = new ArrayList<IntSet>(countRegs);\n\n        for (int i = 0; i < countRegs; i++) {\n            interference.add(SetFactory.makeInterferenceSet(countRegs));\n        }\n    }\n\n    /**\n     * Adds a register pair to the interference/liveness graph. Parameter\n     * order is insignificant.\n     *\n     * @param regV one register index\n     * @param regW another register index\n     */\n    public void add(int regV, int regW) {\n        ensureCapacity(Math.max(regV, regW) + 1);\n\n        interference.get(regV).add(regW);\n        interference.get(regW).add(regV);\n    }\n\n    /**\n     * Dumps interference graph to stdout for debugging.\n     */\n    public void dumpToStdout() {\n        int oldRegCount = interference.size();\n\n        for (int i = 0; i < oldRegCount; i++) {\n            StringBuilder sb = new StringBuilder();\n\n            sb.append(\"Reg \" + i + \":\" + interference.get(i).toString());\n\n            System.out.println(sb.toString());\n        }\n    }\n\n    /**\n     * Merges the interference set for a register into a given bit set\n     *\n     * @param reg {@code >= 0;} register\n     * @param set {@code non-null;} interference set; will be merged\n     * with set for given register\n     */\n    public void mergeInterferenceSet(int reg, IntSet set) {\n        if (reg < interference.size()) {\n            set.merge(interference.get(reg));\n        }\n    }\n\n    /**\n     * Ensures that the interference graph is appropriately sized.\n     *\n     * @param size requested minumum size\n     */\n    private void ensureCapacity(int size) {\n        int countRegs = interference.size();\n\n        interference.ensureCapacity(size);\n\n        for (int i = countRegs; i < size; i++) {\n            interference.add(SetFactory.makeInterferenceSet(size));\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/back/LivenessAnalyzer.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa.back;\n\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.ssa.PhiInsn;\nimport com.taobao.android.dx.ssa.SsaBasicBlock;\nimport com.taobao.android.dx.ssa.SsaInsn;\nimport com.taobao.android.dx.ssa.SsaMethod;\nimport java.util.ArrayList;\nimport java.util.BitSet;\nimport java.util.List;\n\n/**\n * From Appel \"Modern Compiler Implementation in Java\" algorithm 19.17\n * Calculate the live ranges for register {@code reg}.<p>\n *\n * v = regV <p>\n * s = insn <p>\n * M = visitedBlocks <p>\n */\npublic class LivenessAnalyzer {\n    /**\n     * {@code non-null;} index by basic block indexed set of basic blocks\n     * that have already been visited. \"M\" as written in the original Appel\n     * algorithm.\n     */\n    private final BitSet visitedBlocks;\n\n    /**\n     * {@code non-null;} set of blocks remaing to visit as \"live out as block\"\n     */\n    private final BitSet liveOutBlocks;\n\n    /**\n     * {@code >=0;} SSA register currently being analyzed.\n     * \"v\" in the original Appel algorithm.\n     */\n    private final int regV;\n\n    /** method to process */\n    private final SsaMethod ssaMeth;\n\n    /** interference graph being updated */\n    private final InterferenceGraph interference;\n\n    /** block \"n\" in Appel 19.17 */\n    private SsaBasicBlock blockN;\n\n    /** index of statement {@code s} in {@code blockN} */\n    private int statementIndex;\n\n    /** the next function to call */\n    private NextFunction nextFunction;\n\n    /** constants for {@link #nextFunction} */\n    private static enum NextFunction {\n        LIVE_IN_AT_STATEMENT,\n            LIVE_OUT_AT_STATEMENT,\n            LIVE_OUT_AT_BLOCK,\n            DONE;\n    }\n\n    /**\n     * Runs register liveness algorithm for a method, updating the\n     * live in/out information in {@code SsaBasicBlock} instances and\n     * returning an interference graph.\n     *\n     * @param ssaMeth {@code non-null;} method to process\n     * @return {@code non-null;} interference graph indexed by SSA\n     * registers in both directions\n     */\n    public static InterferenceGraph constructInterferenceGraph(\n            SsaMethod ssaMeth) {\n        int szRegs = ssaMeth.getRegCount();\n        InterferenceGraph interference = new InterferenceGraph(szRegs);\n\n        for (int i = 0; i < szRegs; i++) {\n            new LivenessAnalyzer(ssaMeth, i, interference).run();\n        }\n\n        coInterferePhis(ssaMeth, interference);\n\n        return interference;\n    }\n\n    /**\n     * Makes liveness analyzer instance for specific register.\n     *\n     * @param ssaMeth {@code non-null;} method to process\n     * @param reg register whose liveness to analyze\n     * @param interference {@code non-null;} indexed by SSA reg in\n     * both dimensions; graph to update\n     *\n     */\n    private LivenessAnalyzer(SsaMethod ssaMeth, int reg,\n            InterferenceGraph interference) {\n        int blocksSz = ssaMeth.getBlocks().size();\n\n        this.ssaMeth = ssaMeth;\n        this.regV = reg;\n        visitedBlocks = new BitSet(blocksSz);\n        liveOutBlocks = new BitSet(blocksSz);\n        this.interference = interference;\n    }\n\n    /**\n     * The algorithm in Appel is presented in partial tail-recursion\n     * form. Obviously, that's not efficient in java, so this function\n     * serves as the dispatcher instead.\n     */\n    private void handleTailRecursion() {\n        while (nextFunction != NextFunction.DONE) {\n            switch (nextFunction) {\n                case LIVE_IN_AT_STATEMENT:\n                    nextFunction = NextFunction.DONE;\n                    liveInAtStatement();\n                    break;\n\n                case LIVE_OUT_AT_STATEMENT:\n                    nextFunction = NextFunction.DONE;\n                    liveOutAtStatement();\n                    break;\n\n                case LIVE_OUT_AT_BLOCK:\n                    nextFunction = NextFunction.DONE;\n                    liveOutAtBlock();\n                    break;\n\n                default:\n            }\n        }\n    }\n\n    /**\n     * From Appel algorithm 19.17.\n     */\n    public void run() {\n        List<SsaInsn> useList = ssaMeth.getUseListForRegister(regV);\n\n        for (SsaInsn insn : useList) {\n            nextFunction = NextFunction.DONE;\n\n            if (insn instanceof PhiInsn) {\n                // If s is a phi-function with V as it's ith argument.\n                PhiInsn phi = (PhiInsn) insn;\n\n                for (SsaBasicBlock pred :\n                         phi.predBlocksForReg(regV, ssaMeth)) {\n                    blockN = pred;\n\n                    nextFunction = NextFunction.LIVE_OUT_AT_BLOCK;\n                    handleTailRecursion();\n                }\n            } else {\n                blockN = insn.getBlock();\n                statementIndex = blockN.getInsns().indexOf(insn);\n\n                if (statementIndex < 0) {\n                    throw new RuntimeException(\n                            \"insn not found in it's own block\");\n                }\n\n                nextFunction = NextFunction.LIVE_IN_AT_STATEMENT;\n                handleTailRecursion();\n            }\n        }\n\n        int nextLiveOutBlock;\n        while ((nextLiveOutBlock = liveOutBlocks.nextSetBit(0)) >= 0) {\n            blockN = ssaMeth.getBlocks().get(nextLiveOutBlock);\n            liveOutBlocks.clear(nextLiveOutBlock);\n            nextFunction = NextFunction.LIVE_OUT_AT_BLOCK;\n            handleTailRecursion();\n        }\n    }\n\n    /**\n     * \"v is live-out at n.\"\n     */\n    private void liveOutAtBlock() {\n        if (! visitedBlocks.get(blockN.getIndex())) {\n            visitedBlocks.set(blockN.getIndex());\n\n            blockN.addLiveOut(regV);\n\n            ArrayList<SsaInsn> insns;\n\n            insns = blockN.getInsns();\n\n            // Live out at last statement in blockN\n            statementIndex = insns.size() - 1;\n            nextFunction = NextFunction.LIVE_OUT_AT_STATEMENT;\n        }\n    }\n\n    /**\n     * \"v is live-in at s.\"\n     */\n    private void liveInAtStatement() {\n        // if s is the first statement in block N\n        if (statementIndex == 0) {\n            // v is live-in at n\n            blockN.addLiveIn(regV);\n\n            BitSet preds = blockN.getPredecessors();\n\n            liveOutBlocks.or(preds);\n        } else {\n            // Let s' be the statement preceeding s\n            statementIndex -= 1;\n            nextFunction = NextFunction.LIVE_OUT_AT_STATEMENT;\n        }\n    }\n\n    /**\n     * \"v is live-out at s.\"\n     */\n    private void liveOutAtStatement() {\n        SsaInsn statement = blockN.getInsns().get(statementIndex);\n        RegisterSpec rs = statement.getResult();\n\n        if (!statement.isResultReg(regV)) {\n            if (rs != null) {\n                interference.add(regV, rs.getReg());\n            }\n            nextFunction = NextFunction.LIVE_IN_AT_STATEMENT;\n        }\n    }\n\n    /**\n     * Ensures that all the phi result registers for all the phis in the\n     * same basic block interfere with each other. This is needed since\n     * the dead code remover has allowed through \"dead-end phis\" whose\n     * results are not used except as local assignments. Without this step,\n     * a the result of a dead-end phi might be assigned the same register\n     * as the result of another phi, and the phi removal move scheduler may\n     * generate moves that over-write the live result.\n     *\n     * @param ssaMeth {@code non-null;} method to pricess\n     * @param interference {@code non-null;} interference graph\n     */\n    private static void coInterferePhis(SsaMethod ssaMeth,\n            InterferenceGraph interference) {\n        for (SsaBasicBlock b : ssaMeth.getBlocks()) {\n            List<SsaInsn> phis = b.getPhiInsns();\n\n            int szPhis = phis.size();\n\n            for (int i = 0; i < szPhis; i++) {\n                for (int j = 0; j < szPhis; j++) {\n                    if (i == j) {\n                        continue;\n                    }\n\n                    interference.add(phis.get(i).getResult().getReg(),\n                        phis.get(j).getResult().getReg());\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/back/NullRegisterAllocator.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa.back;\n\nimport com.taobao.android.dx.ssa.BasicRegisterMapper;\nimport com.taobao.android.dx.ssa.RegisterMapper;\nimport com.taobao.android.dx.ssa.SsaMethod;\n\n/**\n * A register allocator that maps SSA register n to Rop register 2*n,\n * essentially preserving the original mapping and remaining agnostic\n * about normal or wide categories. Used for debugging.\n */\npublic class NullRegisterAllocator extends RegisterAllocator {\n    /** {@inheritDoc} */\n    public NullRegisterAllocator(SsaMethod ssaMeth,\n            InterferenceGraph interference) {\n        super(ssaMeth, interference);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean wantsParamsMovedHigh() {\n        // We're not smart enough for this.\n        return false;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public RegisterMapper allocateRegisters() {\n        int oldRegCount = ssaMeth.getRegCount();\n\n        BasicRegisterMapper mapper = new BasicRegisterMapper(oldRegCount);\n\n        for (int i = 0; i < oldRegCount; i++) {\n            mapper.addMapping(i, i*2, 2);\n        }\n\n        return mapper;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/back/RegisterAllocator.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa.back;\n\nimport com.taobao.android.dx.rop.code.PlainInsn;\nimport com.taobao.android.dx.rop.code.RegOps;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rops;\nimport com.taobao.android.dx.rop.code.SourcePosition;\nimport com.taobao.android.dx.ssa.NormalSsaInsn;\nimport com.taobao.android.dx.ssa.RegisterMapper;\nimport com.taobao.android.dx.ssa.SsaBasicBlock;\nimport com.taobao.android.dx.ssa.SsaInsn;\nimport com.taobao.android.dx.ssa.SsaMethod;\nimport com.taobao.android.dx.util.IntIterator;\nimport com.taobao.android.dx.util.IntSet;\nimport java.util.ArrayList;\n\n/**\n * Base class of all register allocators.\n */\npublic abstract class RegisterAllocator {\n    /** method being processed */\n    protected final SsaMethod ssaMeth;\n\n    /** interference graph, indexed by register in both dimensions */\n    protected final InterferenceGraph interference;\n\n    /**\n     * Creates an instance. Call {@code allocateRegisters} to run.\n     * @param ssaMeth method to process.\n     * @param interference Interference graph, indexed by register in both\n     * dimensions.\n     */\n    public RegisterAllocator(SsaMethod ssaMeth,\n            InterferenceGraph interference) {\n        this.ssaMeth = ssaMeth;\n        this.interference = interference;\n    }\n\n    /**\n     * Indicates whether the method params were allocated at the bottom\n     * of the namespace, and thus should be moved up to the top of the\n     * namespace after phi removal.\n     *\n     * @return {@code true} if params should be moved from low to high\n     */\n    public abstract boolean wantsParamsMovedHigh();\n\n    /**\n     * Runs the algorithm.\n     *\n     * @return a register mapper to apply to the {@code SsaMethod}\n     */\n    public abstract RegisterMapper allocateRegisters();\n\n    /**\n     * Returns the category (width) of the definition site of the register.\n     * Returns {@code 1} for undefined registers.\n     *\n     * @param reg register\n     * @return {@code 1..2}\n     */\n    protected final int getCategoryForSsaReg(int reg) {\n        SsaInsn definition = ssaMeth.getDefinitionForRegister(reg);\n\n        if (definition == null) {\n            // an undefined reg\n            return 1;\n        } else {\n            return definition.getResult().getCategory();\n        }\n    }\n\n    /**\n     * Returns the RegisterSpec of the definition of the register.\n     *\n     * @param reg {@code >= 0;} SSA register\n     * @return definition spec of the register or null if it is never defined\n     * (for the case of \"version 0\" SSA registers)\n     */\n    protected final RegisterSpec getDefinitionSpecForSsaReg(int reg) {\n        SsaInsn definition = ssaMeth.getDefinitionForRegister(reg);\n\n        return definition == null ? null : definition.getResult();\n    }\n\n    /**\n     * Returns true if the definition site of this register is a\n     * move-param (ie, this is a method parameter).\n     *\n     * @param reg register in question\n     * @return {@code true} if this is a method parameter\n     */\n    protected boolean isDefinitionMoveParam(int reg) {\n        SsaInsn defInsn = ssaMeth.getDefinitionForRegister(reg);\n\n        if (defInsn instanceof NormalSsaInsn) {\n            NormalSsaInsn ndefInsn = (NormalSsaInsn) defInsn;\n\n            return ndefInsn.getOpcode().getOpcode() == RegOps.MOVE_PARAM;\n        }\n\n        return false;\n    }\n\n    /**\n     * Inserts a move instruction for a specified SSA register before a\n     * specified instruction, creating a new SSA register and adjusting the\n     * interference graph in the process. The insn currently must be the\n     * last insn in a block.\n     *\n     * @param insn {@code non-null;} insn to insert move before, must\n     * be last insn in block\n     * @param reg {@code non-null;} SSA register to duplicate\n     * @return {@code non-null;} spec of new SSA register created by move\n     */\n    protected final RegisterSpec insertMoveBefore(SsaInsn insn,\n            RegisterSpec reg) {\n        SsaBasicBlock block = insn.getBlock();\n        ArrayList<SsaInsn> insns = block.getInsns();\n        int insnIndex = insns.indexOf(insn);\n\n        if (insnIndex < 0) {\n            throw new IllegalArgumentException (\n                    \"specified insn is not in this block\");\n        }\n\n        if (insnIndex != insns.size() - 1) {\n            /*\n             * Presently, the interference updater only works when\n             * adding before the last insn, and the last insn must have no\n             * result\n             */\n            throw new IllegalArgumentException(\n                    \"Adding move here not supported:\" + insn.toHuman());\n        }\n\n        /*\n         * Get new register and make new move instruction.\n         */\n\n        // The new result must not have an associated local variable.\n        RegisterSpec newRegSpec = RegisterSpec.make(ssaMeth.makeNewSsaReg(),\n                reg.getTypeBearer());\n\n        SsaInsn toAdd = SsaInsn.makeFromRop(\n                new PlainInsn(Rops.opMove(newRegSpec.getType()),\n                        SourcePosition.NO_INFO, newRegSpec,\n                        RegisterSpecList.make(reg)), block);\n\n        insns.add(insnIndex, toAdd);\n\n        int newReg = newRegSpec.getReg();\n\n        /*\n         * Adjust interference graph based on what's live out of the current\n         * block and what's used by the final instruction.\n         */\n\n        IntSet liveOut = block.getLiveOutRegs();\n        IntIterator liveOutIter = liveOut.iterator();\n\n        while (liveOutIter.hasNext()) {\n            interference.add(newReg, liveOutIter.next());\n        }\n\n        // Everything that's a source in the last insn interferes.\n        RegisterSpecList sources = insn.getSources();\n        int szSources = sources.size();\n\n        for (int i = 0; i < szSources; i++) {\n            interference.add(newReg, sources.get(i).getReg());\n        }\n\n        ssaMeth.onInsnsChanged();\n\n        return newRegSpec;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/back/SsaToRop.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa.back;\n\nimport com.taobao.android.dx.rop.code.BasicBlock;\nimport com.taobao.android.dx.rop.code.BasicBlockList;\nimport com.taobao.android.dx.rop.code.InsnList;\nimport com.taobao.android.dx.rop.code.RegisterSpec;\nimport com.taobao.android.dx.rop.code.RegisterSpecList;\nimport com.taobao.android.dx.rop.code.Rop;\nimport com.taobao.android.dx.rop.code.RopMethod;\nimport com.taobao.android.dx.rop.code.Rops;\nimport com.taobao.android.dx.ssa.BasicRegisterMapper;\nimport com.taobao.android.dx.ssa.PhiInsn;\nimport com.taobao.android.dx.ssa.RegisterMapper;\nimport com.taobao.android.dx.ssa.SsaBasicBlock;\nimport com.taobao.android.dx.ssa.SsaInsn;\nimport com.taobao.android.dx.ssa.SsaMethod;\nimport com.taobao.android.dx.util.Hex;\nimport com.taobao.android.dx.util.IntList;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.BitSet;\nimport java.util.Comparator;\n\n/**\n * Converts a method in SSA form to ROP form.\n */\npublic class SsaToRop {\n    /** local debug flag */\n    private static final boolean DEBUG = false;\n\n    /** {@code non-null;} method to process */\n    private final SsaMethod ssaMeth;\n\n    /**\n     * {@code true} if the converter should attempt to minimize\n     * the rop-form register count\n     */\n    private final boolean minimizeRegisters;\n\n    /** {@code non-null;} interference graph */\n    private final InterferenceGraph interference;\n\n    /**\n     * Converts a method in SSA form to ROP form.\n     *\n     * @param ssaMeth {@code non-null;} method to process\n     * @param minimizeRegisters {@code true} if the converter should\n     * attempt to minimize the rop-form register count\n     * @return {@code non-null;} rop-form output\n     */\n    public static RopMethod convertToRopMethod(SsaMethod ssaMeth,\n            boolean minimizeRegisters) {\n        return new SsaToRop(ssaMeth, minimizeRegisters).convert();\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param ssaMeth {@code non-null;} method to process\n     * @param minimizeRegisters {@code true} if the converter should\n     * attempt to minimize the rop-form register count\n     */\n    private SsaToRop(SsaMethod ssaMethod, boolean minimizeRegisters) {\n        this.minimizeRegisters = minimizeRegisters;\n        this.ssaMeth = ssaMethod;\n        this.interference =\n            LivenessAnalyzer.constructInterferenceGraph(ssaMethod);\n    }\n\n    /**\n     * Performs the conversion.\n     *\n     * @return {@code non-null;} rop-form output\n     */\n    private RopMethod convert() {\n        if (DEBUG) {\n            interference.dumpToStdout();\n        }\n\n        // These are other allocators for debugging or historical comparison:\n        // allocator = new NullRegisterAllocator(ssaMeth, interference);\n        // allocator = new FirstFitAllocator(ssaMeth, interference);\n\n        RegisterAllocator allocator =\n            new FirstFitLocalCombiningAllocator(ssaMeth, interference,\n                    minimizeRegisters);\n\n        RegisterMapper mapper = allocator.allocateRegisters();\n\n        if (DEBUG) {\n            System.out.println(\"Printing reg map\");\n            System.out.println(((BasicRegisterMapper)mapper).toHuman());\n        }\n\n        ssaMeth.setBackMode();\n\n        ssaMeth.mapRegisters(mapper);\n\n        removePhiFunctions();\n\n        if (allocator.wantsParamsMovedHigh()) {\n            moveParametersToHighRegisters();\n        }\n\n        removeEmptyGotos();\n\n        RopMethod ropMethod = new RopMethod(convertBasicBlocks(),\n                ssaMeth.blockIndexToRopLabel(ssaMeth.getEntryBlockIndex()));\n        ropMethod = new IdenticalBlockCombiner(ropMethod).process();\n\n        return ropMethod;\n    }\n\n    /**\n     * Removes all blocks containing only GOTOs from the control flow.\n     * Although much of this work will be done later when converting\n     * from rop to dex, not all simplification cases can be handled\n     * there. Furthermore, any no-op block between the exit block and\n     * blocks containing the real return or throw statements must be\n     * removed.\n     */\n    private void removeEmptyGotos() {\n        final ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();\n\n        ssaMeth.forEachBlockDepthFirst(false, new SsaBasicBlock.Visitor() {\n            public void visitBlock(SsaBasicBlock b, SsaBasicBlock parent) {\n                ArrayList<SsaInsn> insns = b.getInsns();\n\n                if ((insns.size() == 1)\n                        && (insns.get(0).getOpcode() == Rops.GOTO)) {\n                    BitSet preds = (BitSet) b.getPredecessors().clone();\n\n                    for (int i = preds.nextSetBit(0); i >= 0;\n                            i = preds.nextSetBit(i + 1)) {\n                        SsaBasicBlock pb = blocks.get(i);\n                        pb.replaceSuccessor(b.getIndex(),\n                                b.getPrimarySuccessorIndex());\n                    }\n                }\n            }\n        });\n    }\n\n    /**\n     * See Appel 19.6. To remove the phi instructions in an edge-split\n     * SSA representation we know we can always insert a move in a\n     * predecessor block.\n     */\n    private void removePhiFunctions() {\n        ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();\n\n        for (SsaBasicBlock block : blocks) {\n            // Add moves in all the pred blocks for each phi insn.\n            block.forEachPhiInsn(new PhiVisitor(blocks));\n\n            // Delete the phi insns.\n            block.removeAllPhiInsns();\n        }\n\n        /*\n         * After all move insns have been added, sort them so they don't\n         * destructively interfere.\n         */\n        for (SsaBasicBlock block : blocks) {\n            block.scheduleMovesFromPhis();\n        }\n    }\n\n    /**\n     * Helper for {@link #removePhiFunctions}: PhiSuccessorUpdater for\n     * adding move instructions to predecessors based on phi insns.\n     */\n    private static class PhiVisitor implements PhiInsn.Visitor {\n        private final ArrayList<SsaBasicBlock> blocks;\n\n        public PhiVisitor(ArrayList<SsaBasicBlock> blocks) {\n            this.blocks = blocks;\n        }\n\n        public void visitPhiInsn(PhiInsn insn) {\n            RegisterSpecList sources = insn.getSources();\n            RegisterSpec result = insn.getResult();\n            int sz = sources.size();\n\n            for (int i = 0; i < sz; i++) {\n                RegisterSpec source = sources.get(i);\n                SsaBasicBlock predBlock = blocks.get(\n                        insn.predBlockIndexForSourcesIndex(i));\n\n                predBlock.addMoveToEnd(result, source);\n            }\n        }\n    }\n\n    /**\n     * Moves the parameter registers, which allocateRegisters() places\n     * at the bottom of the frame, up to the top of the frame to match\n     * Dalvik calling convention.\n     */\n    private void moveParametersToHighRegisters() {\n        int paramWidth = ssaMeth.getParamWidth();\n        BasicRegisterMapper mapper\n                = new BasicRegisterMapper(ssaMeth.getRegCount());\n        int regCount = ssaMeth.getRegCount();\n\n        for (int i = 0; i < regCount; i++) {\n            if (i < paramWidth) {\n                mapper.addMapping(i, regCount - paramWidth + i, 1);\n            } else {\n                mapper.addMapping(i, i - paramWidth, 1);\n            }\n        }\n\n        if (DEBUG) {\n            System.out.printf(\"Moving %d registers from 0 to %d\\n\",\n                    paramWidth, regCount - paramWidth);\n        }\n\n        ssaMeth.mapRegisters(mapper);\n    }\n\n    /**\n     * @return rop-form basic block list\n     */\n    private BasicBlockList convertBasicBlocks() {\n        ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();\n\n        // Exit block may be null.\n        SsaBasicBlock exitBlock = ssaMeth.getExitBlock();\n\n        ssaMeth.computeReachability();\n        int ropBlockCount = ssaMeth.getCountReachableBlocks();\n\n        // Don't count the exit block, if it exists and is reachable.\n        ropBlockCount -= (exitBlock != null && exitBlock.isReachable()) ? 1 : 0;\n\n        BasicBlockList result = new BasicBlockList(ropBlockCount);\n\n        // Convert all the reachable blocks except the exit block.\n        int ropBlockIndex = 0;\n        for (SsaBasicBlock b : blocks) {\n            if (b.isReachable() && b != exitBlock) {\n                result.set(ropBlockIndex++, convertBasicBlock(b));\n            }\n        }\n\n        // The exit block, which is discarded, must do nothing.\n        if (exitBlock != null && exitBlock.getInsns().size() != 0) {\n            throw new RuntimeException(\n                    \"Exit block must have no insns when leaving SSA form\");\n        }\n\n        return result;\n    }\n\n    /**\n     * Validates that a basic block is a valid end predecessor. It must\n     * end in a RETURN or a THROW. Throws a runtime exception on error.\n     *\n     * @param b {@code non-null;} block to validate\n     * @throws RuntimeException on error\n     */\n    private void verifyValidExitPredecessor(SsaBasicBlock b) {\n        ArrayList<SsaInsn> insns = b.getInsns();\n        SsaInsn lastInsn = insns.get(insns.size() - 1);\n        Rop opcode = lastInsn.getOpcode();\n\n        if (opcode.getBranchingness() != Rop.BRANCH_RETURN\n                && opcode != Rops.THROW) {\n            throw new RuntimeException(\"Exit predecessor must end\"\n                    + \" in valid exit statement.\");\n        }\n    }\n\n    /**\n     * Converts a single basic block to rop form.\n     *\n     * @param block SSA block to process\n     * @return {@code non-null;} ROP block\n     */\n    private BasicBlock convertBasicBlock(SsaBasicBlock block) {\n        IntList successorList = block.getRopLabelSuccessorList();\n        int primarySuccessorLabel = block.getPrimarySuccessorRopLabel();\n\n        // Filter out any reference to the SSA form's exit block.\n\n        // Exit block may be null.\n        SsaBasicBlock exitBlock = ssaMeth.getExitBlock();\n        int exitRopLabel = (exitBlock == null) ? -1 : exitBlock.getRopLabel();\n\n        if (successorList.contains(exitRopLabel)) {\n            if (successorList.size() > 1) {\n                throw new RuntimeException(\n                        \"Exit predecessor must have no other successors\"\n                                + Hex.u2(block.getRopLabel()));\n            } else {\n                successorList = IntList.EMPTY;\n                primarySuccessorLabel = -1;\n\n                verifyValidExitPredecessor(block);\n            }\n        }\n\n        successorList.setImmutable();\n\n        BasicBlock result = new BasicBlock(\n                block.getRopLabel(), convertInsns(block.getInsns()),\n                successorList,\n                primarySuccessorLabel);\n\n        return result;\n    }\n\n    /**\n     * Converts an insn list to rop form.\n     *\n     * @param ssaInsns {@code non-null;} old instructions\n     * @return {@code non-null;} immutable instruction list\n     */\n    private InsnList convertInsns(ArrayList<SsaInsn> ssaInsns) {\n        int insnCount = ssaInsns.size();\n        InsnList result = new InsnList(insnCount);\n\n        for (int i = 0; i < insnCount; i++) {\n            result.set(i, ssaInsns.get(i).toRopInsn());\n        }\n\n        result.setImmutable();\n\n        return result;\n    }\n\n    /**\n     * <b>Note:</b> This method is not presently used.\n     *\n     * @return a list of registers ordered by most-frequently-used to\n     * least-frequently-used. Each register is listed once and only\n     * once.\n     */\n    public int[] getRegistersByFrequency() {\n        int regCount = ssaMeth.getRegCount();\n        Integer[] ret = new Integer[regCount];\n\n        for (int i = 0; i < regCount; i++) {\n            ret[i] = i;\n        }\n\n        Arrays.sort(ret, new Comparator<Integer>() {\n            public int compare(Integer o1, Integer o2) {\n                return ssaMeth.getUseListForRegister(o2).size()\n                        - ssaMeth.getUseListForRegister(o1).size();\n            }\n        });\n\n        int result[] = new int[regCount];\n\n        for (int i = 0; i < regCount; i++) {\n            result[i] = ret[i];\n        }\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/ssa/package-info.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.ssa;\n\n/**\n * <h1>An introduction to SSA Form</h1>\n *\n * This package contains classes associated with dx's {@code SSA}\n * intermediate form. This form is a static-single-assignment representation of\n * Rop-form a method with Rop-form-like instructions (with the addition of a\n * {@link PhiInsn phi instriction}. This form is intended to make it easy to\n * implement basic optimization steps and register allocation so that a\n * reasonably efficient register machine representation can be produced from a\n * stack machine source bytecode.<p>\n *\n * <h2>Key Classes</h2>\n *\n * <h3>Classes related to conversion and lifetime</h3>\n * <ul>\n * <li> {@link Optimizer} is a singleton class containing methods for\n * converting, optimizing, and then back-converting Rop-form methods. It's the\n * typical gateway into the rest of the package.\n * <li> {@link SsaConverter} converts a Rop-form method to SSA form.\n * <li> {@link SsaToRop} converts an SSA-form method back to Rop form.\n * </ul>\n *\n * <h3>Classes related to method representation</h3>\n * <ul>\n * <li> A {@link SsaMethod} instance represents a method.\n * <li> A {@link SsaBasicBlock} instance represents a basic block, whose\n * semantics are quite similar to basic blocks in\n * {@link com.taobao.android.dx.rop Rop form}.\n * <li> {@link PhiInsn} instances represent \"phi\" operators defined in SSA\n * literature. They must be the first N instructions in a basic block.\n * <li> {@link NormalSsaInsn} instances represent instructions that directly\n * correspond to {@code Rop} form.\n * </ul>\n *\n * <h3>Classes related to optimization steps</h3>\n * <ul>\n * <li> {@link MoveParamCombiner} is a simple step that ensures each method\n * parameter is represented by at most one SSA register.\n * <li> {@link SCCP} is a (partially implemented) sparse-conditional\n * constant propogator.\n * <li> {@link LiteralOpUpgrader} is a step that attempts to use constant\n * information to convert math and comparison instructions into\n * constant-bearing \"literal ops\" in cases where they can be represented in the\n * output form (see {@link TranslationAdvice#hasConstantOperation}).\n * <li> {@link ConstCollector} is a step that attempts to trade (modest)\n * increased register space for decreased instruction count in cases where\n * the same constant value is used repeatedly in a single method.\n * <li> {@link DeadCodeRemover} is a dead code remover. This phase must\n * always be run to remove unused phi instructions.\n * </ul>\n *\n * <h2>SSA Lifetime</h2>\n * The representation of a method in SSA form obeys slightly different\n * constraints depending upon whether it is in the process of being converted\n * into or out of SSA form.\n *\n * <h3>Conversion into SSA Form</h3>\n *\n * {@link SsaConverter#convertToSsaMethod} takes a {@code RopMethod} and\n * returns a fully-converted {@code SsaMethod}. The conversion process\n * is roughly as follows:\n *\n * <ol>\n * <li> The Rop-form method, its blocks and their instructions are directly\n * wrapped in {@code SsaMethod}, {@code SsaBasicBlock} and\n * {@code SsaInsn} instances. Nothing else changes.\n * <li> Critical control-flow graph edges are {@link SsaConverter#edgeSplit\n * split} and new basic blocks inserted as required to meet the constraints\n * necessary for the ultimate SSA representation.\n * <li> A {@link LocalVariableExtractor} is run to produce a table of\n * Rop registers to local variables necessary during phi placement. This\n * step could also be done in Rop form and then updated through the preceding\n * steps.\n * <li> {@code Phi} instructions are {link SsaConverter#placePhiFunctions}\n * placed in a semi-pruned fashion, which requires computation of {@link\n * Dominators dominance graph} and each node's {@link DomFront\n * dominance-frontier set}.\n * <li> Finally, source and result registers for all instructions are {@link\n * SsaRenamer renamed} such that each assignment is given a unique register\n * number (register categories or widths, significant in Rop form, do not\n * exist in SSA). Move instructions are eliminated except where necessary\n * to preserve local variable assignments.\n * </ol>\n *\n */\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/AnnotatedOutput.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\n/**\n * Interface for a binary output destination that may be augmented\n * with textual annotations.\n */\npublic interface AnnotatedOutput\n        extends Output {\n    /**\n     * Get whether this instance will actually keep annotations.\n     *\n     * @return {@code true} iff annotations are being kept\n     */\n    public boolean annotates();\n\n    /**\n     * Get whether this instance is intended to keep verbose annotations.\n     * Annotators may use the result of calling this method to inform their\n     * annotation activity.\n     *\n     * @return {@code true} iff annotations are to be verbose\n     */\n    public boolean isVerbose();\n\n    /**\n     * Add an annotation for the subsequent output. Any previously\n     * open annotation will be closed by this call, and the new\n     * annotation marks all subsequent output until another annotation\n     * call.\n     *\n     * @param msg {@code non-null;} the annotation message\n     */\n    public void annotate(String msg);\n\n    /**\n     * Add an annotation for a specified amount of subsequent\n     * output. Any previously open annotation will be closed by this\n     * call. If there is already pending annotation from one or more\n     * previous calls to this method, the new call \"consumes\" output\n     * after all the output covered by the previous calls.\n     *\n     * @param amt {@code >= 0;} the amount of output for this annotation to\n     * cover\n     * @param msg {@code non-null;} the annotation message\n     */\n    public void annotate(int amt, String msg);\n\n    /**\n     * End the most recent annotation. Subsequent output will be unannotated,\n     * until the next call to {@link #annotate}.\n     */\n    public void endAnnotation();\n\n    /**\n     * Get the maximum width of the annotated output. This is advisory:\n     * Implementations of this interface are encouraged to deal with too-wide\n     * output, but annotaters are encouraged to attempt to avoid exceeding\n     * the indicated width.\n     *\n     * @return {@code >= 1;} the maximum width\n     */\n    public int getAnnotationWidth();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/BitIntSet.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\nimport java.util.NoSuchElementException;\n\n/**\n * A set of integers, represented by a bit set\n */\npublic class BitIntSet implements IntSet {\n\n    /** also accessed in ListIntSet */\n    int[] bits;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param max the maximum value of ints in this set.\n     */\n    public BitIntSet(int max) {\n        bits = Bits.makeBitSet(max);\n    }\n\n    /** @inheritDoc */\n    public void add(int value) {\n        ensureCapacity(value);\n        Bits.set(bits, value, true);\n    }\n\n    /**\n     * Ensures that the bit set has the capacity to represent the given value.\n     *\n     * @param value {@code >= 0;} value to represent\n     */\n    private void ensureCapacity(int value) {\n        if (value >= Bits.getMax(bits)) {\n            int[] newBits = Bits.makeBitSet(\n                    Math.max(value + 1, 2 * Bits.getMax(bits)));\n            System.arraycopy(bits, 0, newBits, 0, bits.length);\n            bits = newBits;\n        }\n    }\n\n    /** @inheritDoc */\n    public void remove(int value) {\n        if (value < Bits.getMax(bits)) {\n            Bits.set(bits, value, false);\n        }\n    }\n\n    /** @inheritDoc */\n    public boolean has(int value) {\n        return (value < Bits.getMax(bits)) && Bits.get(bits, value);\n    }\n\n    /** @inheritDoc */\n    public void merge(IntSet other) {\n        if (other instanceof BitIntSet) {\n            BitIntSet o = (BitIntSet) other;\n            ensureCapacity(Bits.getMax(o.bits) + 1);\n            Bits.or(bits, o.bits);\n        } else if (other instanceof ListIntSet) {\n            ListIntSet o = (ListIntSet) other;\n            int sz = o.ints.size();\n\n            if (sz > 0) {\n                ensureCapacity(o.ints.get(sz - 1));\n            }\n            for (int i = 0; i < o.ints.size(); i++) {\n                Bits.set(bits, o.ints.get(i), true);\n            }\n        } else {\n            IntIterator iter = other.iterator();\n            while (iter.hasNext()) {\n                add(iter.next());\n            }\n        }\n    }\n\n    /** @inheritDoc */\n    public int elements() {\n        return Bits.bitCount(bits);\n    }\n\n    /** @inheritDoc */\n    public IntIterator iterator() {\n        return new IntIterator() {\n            private int idx = Bits.findFirst(bits, 0);\n\n            /** @inheritDoc */\n            public boolean hasNext() {\n                return idx >= 0;\n            }\n\n            /** @inheritDoc */\n            public int next() {\n                if (!hasNext()) {\n                    throw new NoSuchElementException();\n                }\n\n                int ret = idx;\n\n                idx = Bits.findFirst(bits, idx+1);\n\n                return ret;\n            }\n        };\n    }\n\n    /** @inheritDoc */\n    public String toString() {\n        StringBuilder sb = new StringBuilder();\n\n        sb.append('{');\n\n        boolean first = true;\n        for (int i = Bits.findFirst(bits, 0)\n                ; i >= 0\n                ; i = Bits.findFirst(bits, i + 1)) {\n            if (!first) {\n                sb.append(\", \");\n            }\n            first = false;\n            sb.append(i);\n        }\n\n        sb.append('}');\n\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/Bits.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\n/**\n * Utilities for treating {@code int[]}s as bit sets.\n */\npublic final class Bits {\n    /**\n     * This class is uninstantiable.\n     */\n    private Bits() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Constructs a bit set to contain bits up to the given index (exclusive).\n     *\n     * @param max {@code >= 0;} the maximum bit index (exclusive)\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static int[] makeBitSet(int max) {\n        int size = (max + 0x1f) >> 5;\n        return new int[size];\n    }\n\n    /**\n     * Gets the maximum index (exclusive) for the given bit set.\n     *\n     * @param bits {@code non-null;} bit set in question\n     * @return {@code >= 0;} the maximum index (exclusive) that may be set\n     */\n    public static int getMax(int[] bits) {\n        return bits.length * 0x20;\n    }\n\n    /**\n     * Gets the value of the bit at the given index.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @param idx {@code >= 0, < getMax(set);} which bit\n     * @return the value of the indicated bit\n     */\n    public static boolean get(int[] bits, int idx) {\n        int arrayIdx = idx >> 5;\n        int bit = 1 << (idx & 0x1f);\n        return (bits[arrayIdx] & bit) != 0;\n    }\n\n    /**\n     * Sets the given bit to the given value.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @param idx {@code >= 0, < getMax(set);} which bit\n     * @param value the new value for the bit\n     */\n    public static void set(int[] bits, int idx, boolean value) {\n        int arrayIdx = idx >> 5;\n        int bit = 1 << (idx & 0x1f);\n\n        if (value) {\n            bits[arrayIdx] |= bit;\n        } else {\n            bits[arrayIdx] &= ~bit;\n        }\n    }\n\n    /**\n     * Sets the given bit to {@code true}.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @param idx {@code >= 0, < getMax(set);} which bit\n     */\n    public static void set(int[] bits, int idx) {\n        int arrayIdx = idx >> 5;\n        int bit = 1 << (idx & 0x1f);\n        bits[arrayIdx] |= bit;\n    }\n\n    /**\n     * Sets the given bit to {@code false}.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @param idx {@code >= 0, < getMax(set);} which bit\n     */\n    public static void clear(int[] bits, int idx) {\n        int arrayIdx = idx >> 5;\n        int bit = 1 << (idx & 0x1f);\n        bits[arrayIdx] &= ~bit;\n    }\n\n    /**\n     * Returns whether or not the given bit set is empty, that is, whether\n     * no bit is set to {@code true}.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @return {@code true} iff all bits are {@code false}\n     */\n    public static boolean isEmpty(int[] bits) {\n        int len = bits.length;\n\n        for (int i = 0; i < len; i++) {\n            if (bits[i] != 0) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Gets the number of bits set to {@code true} in the given bit set.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @return {@code >= 0;} the bit count (aka population count) of the set\n     */\n    public static int bitCount(int[] bits) {\n        int len = bits.length;\n        int count = 0;\n\n        for (int i = 0; i < len; i++) {\n            count += Integer.bitCount(bits[i]);\n        }\n\n        return count;\n    }\n\n    /**\n     * Returns whether any bits are set to {@code true} in the\n     * specified range.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @param start {@code >= 0;} index of the first bit in the range (inclusive)\n     * @param end {@code >= 0;} index of the last bit in the range (exclusive)\n     * @return {@code true} if any bit is set to {@code true} in\n     * the indicated range\n     */\n    public static boolean anyInRange(int[] bits, int start, int end) {\n        int idx = findFirst(bits, start);\n        return (idx >= 0) && (idx < end);\n    }\n\n    /**\n     * Finds the lowest-order bit set at or after the given index in the\n     * given bit set.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @param idx {@code >= 0;} minimum index to return\n     * @return {@code >= -1;} lowest-order bit set at or after {@code idx},\n     * or {@code -1} if there is no appropriate bit index to return\n     */\n    public static int findFirst(int[] bits, int idx) {\n        int len = bits.length;\n        int minBit = idx & 0x1f;\n\n        for (int arrayIdx = idx >> 5; arrayIdx < len; arrayIdx++) {\n            int word = bits[arrayIdx];\n            if (word != 0) {\n                int bitIdx = findFirst(word, minBit);\n                if (bitIdx >= 0) {\n                    return (arrayIdx << 5) + bitIdx;\n                }\n            }\n            minBit = 0;\n        }\n\n        return -1;\n    }\n\n    /**\n     * Finds the lowest-order bit set at or after the given index in the\n     * given {@code int}.\n     *\n     * @param value the value in question\n     * @param idx 0..31 the minimum bit index to return\n     * @return {@code >= -1;} lowest-order bit set at or after {@code idx},\n     * or {@code -1} if there is no appropriate bit index to return\n     */\n    public static int findFirst(int value, int idx) {\n        value &= ~((1 << idx) - 1); // Mask off too-low bits.\n        int result = Integer.numberOfTrailingZeros(value);\n        return (result == 32) ? -1 : result;\n    }\n\n    /**\n     * Ors bit array {@code b} into bit array {@code a}.\n     * {@code a.length} must be greater than or equal to\n     * {@code b.length}.\n     *\n     * @param a {@code non-null;} int array to be ored with other argument. This\n     * argument is modified.\n     * @param b {@code non-null;} int array to be ored into {@code a}. This\n     * argument is not modified.\n     */\n    public static void or(int[] a, int[] b) {\n        for (int i = 0; i < b.length; i++) {\n            a[i] |= b[i];\n        }\n    }\n\n    public static String toHuman(int[] bits) {\n        StringBuilder sb = new StringBuilder();\n\n        boolean needsComma = false;\n\n        sb.append('{');\n\n        int bitsLength = 32 * bits.length;\n        for (int i = 0; i < bitsLength; i++) {\n            if (Bits.get(bits, i)) {\n                if (needsComma) {\n                    sb.append(',');\n                }\n                needsComma = true;\n                sb.append(i);\n            }\n        }\n        sb.append('}');\n\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/ByteArray.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\nimport java.io.DataInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\n\n/**\n * Wrapper for a {@code byte[]}, which provides read-only access and\n * can \"reveal\" a partial slice of the underlying array.\n *\n * <b>Note:</b> Multibyte accessors all use big-endian order.\n */\npublic final class ByteArray {\n    /** {@code non-null;} underlying array */\n    private final byte[] bytes;\n\n    /** {@code >= 0}; start index of the slice (inclusive) */\n    private final int start;\n\n    /** {@code >= 0, <= bytes.length}; size computed as\n     * {@code end - start} (in the constructor) */\n    private final int size;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param bytes {@code non-null;} the underlying array\n     * @param start {@code >= 0;} start index of the slice (inclusive)\n     * @param end {@code >= start, <= bytes.length;} end index of\n     * the slice (exclusive)\n     */\n    public ByteArray(byte[] bytes, int start, int end) {\n        if (bytes == null) {\n            throw new NullPointerException(\"bytes == null\");\n        }\n\n        if (start < 0) {\n            throw new IllegalArgumentException(\"start < 0\");\n        }\n\n        if (end < start) {\n            throw new IllegalArgumentException(\"end < start\");\n        }\n\n        if (end > bytes.length) {\n            throw new IllegalArgumentException(\"end > bytes.length\");\n        }\n\n        this.bytes = bytes;\n        this.start = start;\n        this.size = end - start;\n    }\n\n    /**\n     * Constructs an instance from an entire {@code byte[]}.\n     *\n     * @param bytes {@code non-null;} the underlying array\n     */\n    public ByteArray(byte[] bytes) {\n        this(bytes, 0, bytes.length);\n    }\n\n    /**\n     * Gets the size of the array, in bytes.\n     *\n     * @return {@code >= 0;} the size\n     */\n    public int size() {\n        return size;\n    }\n\n    /**\n     * Returns a slice (that is, a sub-array) of this instance.\n     *\n     * @param start {@code >= 0;} start index of the slice (inclusive)\n     * @param end {@code >= start, <= size();} end index of\n     * the slice (exclusive)\n     * @return {@code non-null;} the slice\n     */\n    public ByteArray slice(int start, int end) {\n        checkOffsets(start, end);\n        return new ByteArray(bytes, start + this.start, end + this.start);\n    }\n\n    /**\n     * Returns the offset into the given array represented by the given\n     * offset into this instance.\n     *\n     * @param offset offset into this instance\n     * @param bytes {@code non-null;} (alleged) underlying array\n     * @return corresponding offset into {@code bytes}\n     * @throws IllegalArgumentException thrown if {@code bytes} is\n     * not the underlying array of this instance\n     */\n    public int underlyingOffset(int offset, byte[] bytes) {\n        if (bytes != this.bytes) {\n            throw new IllegalArgumentException(\"wrong bytes\");\n        }\n\n        return start + offset;\n    }\n\n    /**\n     * Gets the {@code signed byte} value at a particular offset.\n     *\n     * @param off {@code >= 0, < size();} offset to fetch\n     * @return {@code signed byte} at that offset\n     */\n    public int getByte(int off) {\n        checkOffsets(off, off + 1);\n        return getByte0(off);\n    }\n\n    /**\n     * Gets the {@code signed short} value at a particular offset.\n     *\n     * @param off {@code >= 0, < (size() - 1);} offset to fetch\n     * @return {@code signed short} at that offset\n     */\n    public int getShort(int off) {\n        checkOffsets(off, off + 2);\n        return (getByte0(off) << 8) | getUnsignedByte0(off + 1);\n    }\n\n    /**\n     * Gets the {@code signed int} value at a particular offset.\n     *\n     * @param off {@code >= 0, < (size() - 3);} offset to fetch\n     * @return {@code signed int} at that offset\n     */\n    public int getInt(int off) {\n        checkOffsets(off, off + 4);\n        return (getByte0(off) << 24) |\n            (getUnsignedByte0(off + 1) << 16) |\n            (getUnsignedByte0(off + 2) << 8) |\n            getUnsignedByte0(off + 3);\n    }\n\n    /**\n     * Gets the {@code signed long} value at a particular offset.\n     *\n     * @param off {@code >= 0, < (size() - 7);} offset to fetch\n     * @return {@code signed int} at that offset\n     */\n    public long getLong(int off) {\n        checkOffsets(off, off + 8);\n        int part1 = (getByte0(off) << 24) |\n            (getUnsignedByte0(off + 1) << 16) |\n            (getUnsignedByte0(off + 2) << 8) |\n            getUnsignedByte0(off + 3);\n        int part2 = (getByte0(off + 4) << 24) |\n            (getUnsignedByte0(off + 5) << 16) |\n            (getUnsignedByte0(off + 6) << 8) |\n            getUnsignedByte0(off + 7);\n\n        return (part2 & 0xffffffffL) | ((long) part1) << 32;\n    }\n\n    /**\n     * Gets the {@code unsigned byte} value at a particular offset.\n     *\n     * @param off {@code >= 0, < size();} offset to fetch\n     * @return {@code unsigned byte} at that offset\n     */\n    public int getUnsignedByte(int off) {\n        checkOffsets(off, off + 1);\n        return getUnsignedByte0(off);\n    }\n\n    /**\n     * Gets the {@code unsigned short} value at a particular offset.\n     *\n     * @param off {@code >= 0, < (size() - 1);} offset to fetch\n     * @return {@code unsigned short} at that offset\n     */\n    public int getUnsignedShort(int off) {\n        checkOffsets(off, off + 2);\n        return (getUnsignedByte0(off) << 8) | getUnsignedByte0(off + 1);\n    }\n\n    /**\n     * Copies the contents of this instance into the given raw\n     * {@code byte[]} at the given offset. The given array must be\n     * large enough.\n     *\n     * @param out {@code non-null;} array to hold the output\n     * @param offset {@code non-null;} index into {@code out} for the first\n     * byte of output\n     */\n    public void getBytes(byte[] out, int offset) {\n        if ((out.length - offset) < size) {\n            throw new IndexOutOfBoundsException(\"(out.length - offset) < \" +\n                                                \"size()\");\n        }\n\n        System.arraycopy(bytes, start, out, offset, size);\n    }\n\n    /**\n     * Checks a range of offsets for validity, throwing if invalid.\n     *\n     * @param s start offset (inclusive)\n     * @param e end offset (exclusive)\n     */\n    private void checkOffsets(int s, int e) {\n        if ((s < 0) || (e < s) || (e > size)) {\n            throw new IllegalArgumentException(\"bad range: \" + s + \"..\" + e +\n                                               \"; actual size \" + size);\n        }\n    }\n\n    /**\n     * Gets the {@code signed byte} value at the given offset,\n     * without doing any argument checking.\n     *\n     * @param off offset to fetch\n     * @return byte at that offset\n     */\n    private int getByte0(int off) {\n        return bytes[start + off];\n    }\n\n    /**\n     * Gets the {@code unsigned byte} value at the given offset,\n     * without doing any argument checking.\n     *\n     * @param off offset to fetch\n     * @return byte at that offset\n     */\n    private int getUnsignedByte0(int off) {\n        return bytes[start + off] & 0xff;\n    }\n\n    /**\n     * Gets a {@code DataInputStream} that reads from this instance,\n     * with the cursor starting at the beginning of this instance's data.\n     * <b>Note:</b> The returned instance may be cast to {@link #GetCursor}\n     * if needed.\n     *\n     * @return {@code non-null;} an appropriately-constructed\n     * {@code DataInputStream} instance\n     */\n    public MyDataInputStream makeDataInputStream() {\n        return new MyDataInputStream(makeInputStream());\n    }\n\n    /**\n     * Gets a {@code InputStream} that reads from this instance,\n     * with the cursor starting at the beginning of this instance's data.\n     * <b>Note:</b> The returned instance may be cast to {@link #GetCursor}\n     * if needed.\n     *\n     * @return {@code non-null;} an appropriately-constructed\n     * {@code InputStream} instancex\n     */\n    public MyInputStream makeInputStream() {\n        return new MyInputStream();\n    }\n\n    /**\n     * Helper interface that allows one to get the cursor (of a stream).\n     */\n    public interface GetCursor {\n        /**\n         * Gets the current cursor.\n         *\n         * @return {@code 0..size();} the cursor\n         */\n        public int getCursor();\n    }\n\n    /**\n     * Helper class for {@link #makeInputStream}, which implements the\n     * stream functionality.\n     */\n    public class MyInputStream extends InputStream {\n        /** 0..size; the cursor */\n        private int cursor;\n\n        /** 0..size; the mark */\n        private int mark;\n\n        public MyInputStream() {\n            cursor = 0;\n            mark = 0;\n        }\n\n        public int read() throws IOException {\n            if (cursor >= size) {\n                return -1;\n            }\n\n            int result = getUnsignedByte0(cursor);\n            cursor++;\n            return result;\n        }\n\n        public int read(byte[] arr, int offset, int length) {\n            if ((offset + length) > arr.length) {\n                length = arr.length - offset;\n            }\n\n            int maxLength = size - cursor;\n            if (length > maxLength) {\n                length = maxLength;\n            }\n\n            System.arraycopy(bytes, cursor + start, arr, offset, length);\n            cursor += length;\n            return length;\n        }\n\n        public int available() {\n            return size - cursor;\n        }\n\n        public void mark(int reserve) {\n            mark = cursor;\n        }\n\n        public void reset() {\n            cursor = mark;\n        }\n\n        public boolean markSupported() {\n            return true;\n        }\n    }\n\n    /**\n     * Helper class for {@link #makeDataInputStream}. This is used\n     * simply so that the cursor of a wrapped {@link #MyInputStream}\n     * instance may be easily determined.\n     */\n    public static class MyDataInputStream extends DataInputStream {\n        /** {@code non-null;} the underlying {@link #MyInputStream} */\n        private final MyInputStream wrapped;\n\n        public MyDataInputStream(MyInputStream wrapped) {\n            super(wrapped);\n\n            this.wrapped = wrapped;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/ByteArrayAnnotatedOutput.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\nimport com.taobao.android.dex.util.ByteOutput;\nimport com.taobao.android.dex.util.ExceptionWithContext;\nimport com.taobao.android.dex.Leb128;\nimport java.io.IOException;\nimport java.io.Writer;\nimport java.util.ArrayList;\n\n/**\n * Implementation of {@link AnnotatedOutput} which stores the written data\n * into a {@code byte[]}.\n *\n * <p><b>Note:</b> As per the {@link Output} interface, multi-byte\n * writes all use little-endian order.</p>\n */\npublic final class ByteArrayAnnotatedOutput\n        implements AnnotatedOutput, ByteOutput {\n    /** default size for stretchy instances */\n    private static final int DEFAULT_SIZE = 1000;\n\n    /**\n     * whether the instance is stretchy, that is, whether its array\n     * may be resized to increase capacity\n     */\n    private final boolean stretchy;\n\n    /** {@code non-null;} the data itself */\n    private byte[] data;\n\n    /** {@code >= 0;} current output cursor */\n    private int cursor;\n\n    /** whether annotations are to be verbose */\n    private boolean verbose;\n\n    /**\n     * {@code null-ok;} list of annotations, or {@code null} if this instance\n     * isn't keeping them\n     */\n    private ArrayList<Annotation> annotations;\n\n    /** {@code >= 40 (if used);} the desired maximum annotation width */\n    private int annotationWidth;\n\n    /**\n     * {@code >= 8 (if used);} the number of bytes of hex output to use\n     * in annotations\n     */\n    private int hexCols;\n\n    /**\n     * Constructs an instance with a fixed maximum size. Note that the\n     * given array is the only one that will be used to store data. In\n     * particular, no reallocation will occur in order to expand the\n     * capacity of the resulting instance. Also, the constructed\n     * instance does not keep annotations by default.\n     *\n     * @param data {@code non-null;} data array to use for output\n     */\n    public ByteArrayAnnotatedOutput(byte[] data) {\n        this(data, false);\n    }\n\n    /**\n     * Constructs a \"stretchy\" instance. The underlying array may be\n     * reallocated. The constructed instance does not keep annotations\n     * by default.\n     */\n    public ByteArrayAnnotatedOutput() {\n        this(DEFAULT_SIZE);\n    }\n\n    /**\n     * Constructs a \"stretchy\" instance with initial size {@code size}. The\n     * underlying array may be reallocated. The constructed instance does not\n     * keep annotations by default.\n     */\n    public ByteArrayAnnotatedOutput(int size) {\n        this(new byte[size], true);\n    }\n\n    /**\n     * Internal constructor.\n     *\n     * @param data {@code non-null;} data array to use for output\n     * @param stretchy whether the instance is to be stretchy\n     */\n    private ByteArrayAnnotatedOutput(byte[] data, boolean stretchy) {\n        if (data == null) {\n            throw new NullPointerException(\"data == null\");\n        }\n\n        this.stretchy = stretchy;\n        this.data = data;\n        this.cursor = 0;\n        this.verbose = false;\n        this.annotations = null;\n        this.annotationWidth = 0;\n        this.hexCols = 0;\n    }\n\n    /**\n     * Gets the underlying {@code byte[]} of this instance, which\n     * may be larger than the number of bytes written\n     *\n     * @see #toByteArray\n     *\n     * @return {@code non-null;} the {@code byte[]}\n     */\n    public byte[] getArray() {\n        return data;\n    }\n\n    /**\n     * Constructs and returns a new {@code byte[]} that contains\n     * the written contents exactly (that is, with no extra unwritten\n     * bytes at the end).\n     *\n     * @see #getArray\n     *\n     * @return {@code non-null;} an appropriately-constructed array\n     */\n    public byte[] toByteArray() {\n        byte[] result = new byte[cursor];\n        System.arraycopy(data, 0, result, 0, cursor);\n        return result;\n    }\n\n    /** {@inheritDoc} */\n    public int getCursor() {\n        return cursor;\n    }\n\n    /** {@inheritDoc} */\n    public void assertCursor(int expectedCursor) {\n        if (cursor != expectedCursor) {\n            throw new ExceptionWithContext(\"expected cursor \" +\n                    expectedCursor + \"; actual value: \" + cursor);\n        }\n    }\n\n    /** {@inheritDoc} */\n    public void writeByte(int value) {\n        int writeAt = cursor;\n        int end = writeAt + 1;\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        data[writeAt] = (byte) value;\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public void writeShort(int value) {\n        int writeAt = cursor;\n        int end = writeAt + 2;\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        data[writeAt] = (byte) value;\n        data[writeAt + 1] = (byte) (value >> 8);\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public void writeInt(int value) {\n        int writeAt = cursor;\n        int end = writeAt + 4;\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        data[writeAt] = (byte) value;\n        data[writeAt + 1] = (byte) (value >> 8);\n        data[writeAt + 2] = (byte) (value >> 16);\n        data[writeAt + 3] = (byte) (value >> 24);\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public void writeLong(long value) {\n        int writeAt = cursor;\n        int end = writeAt + 8;\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        int half = (int) value;\n        data[writeAt] = (byte) half;\n        data[writeAt + 1] = (byte) (half >> 8);\n        data[writeAt + 2] = (byte) (half >> 16);\n        data[writeAt + 3] = (byte) (half >> 24);\n\n        half = (int) (value >> 32);\n        data[writeAt + 4] = (byte) half;\n        data[writeAt + 5] = (byte) (half >> 8);\n        data[writeAt + 6] = (byte) (half >> 16);\n        data[writeAt + 7] = (byte) (half >> 24);\n\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public int writeUleb128(int value) {\n        if (stretchy) {\n            ensureCapacity(cursor + 5); // pessimistic\n        }\n        int cursorBefore = cursor;\n        Leb128.writeUnsignedLeb128(this, value);\n        return (cursor - cursorBefore);\n    }\n\n    /** {@inheritDoc} */\n    public int writeSleb128(int value) {\n        if (stretchy) {\n            ensureCapacity(cursor + 5); // pessimistic\n        }\n        int cursorBefore = cursor;\n        Leb128.writeSignedLeb128(this, value);\n        return (cursor - cursorBefore);\n    }\n\n    /** {@inheritDoc} */\n    public void write(ByteArray bytes) {\n        int blen = bytes.size();\n        int writeAt = cursor;\n        int end = writeAt + blen;\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        bytes.getBytes(data, writeAt);\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public void write(byte[] bytes, int offset, int length) {\n        int writeAt = cursor;\n        int end = writeAt + length;\n        int bytesEnd = offset + length;\n\n        // twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0)\n        if (((offset | length | end) < 0) || (bytesEnd > bytes.length)) {\n            throw new IndexOutOfBoundsException(\"bytes.length \" +\n                                                bytes.length + \"; \" +\n                                                offset + \"..!\" + end);\n        }\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        System.arraycopy(bytes, offset, data, writeAt, length);\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public void write(byte[] bytes) {\n        write(bytes, 0, bytes.length);\n    }\n\n    /** {@inheritDoc} */\n    public void writeZeroes(int count) {\n        if (count < 0) {\n            throw new IllegalArgumentException(\"count < 0\");\n        }\n\n        int end = cursor + count;\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        /*\n         * There is no need to actually write zeroes, since the array is\n         * already preinitialized with zeroes.\n         */\n\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public void alignTo(int alignment) {\n        int mask = alignment - 1;\n\n        if ((alignment < 0) || ((mask & alignment) != 0)) {\n            throw new IllegalArgumentException(\"bogus alignment\");\n        }\n\n        int end = (cursor + mask) & ~mask;\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        /*\n         * There is no need to actually write zeroes, since the array is\n         * already preinitialized with zeroes.\n         */\n\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public boolean annotates() {\n        return (annotations != null);\n    }\n\n    /** {@inheritDoc} */\n    public boolean isVerbose() {\n        return verbose;\n    }\n\n    /** {@inheritDoc} */\n    public void annotate(String msg) {\n        if (annotations == null) {\n            return;\n        }\n\n        endAnnotation();\n        annotations.add(new Annotation(cursor, msg));\n    }\n\n    /** {@inheritDoc} */\n    public void annotate(int amt, String msg) {\n        if (annotations == null) {\n            return;\n        }\n\n        endAnnotation();\n\n        int asz = annotations.size();\n        int lastEnd = (asz == 0) ? 0 : annotations.get(asz - 1).getEnd();\n        int startAt;\n\n        if (lastEnd <= cursor) {\n            startAt = cursor;\n        } else {\n            startAt = lastEnd;\n        }\n\n        annotations.add(new Annotation(startAt, startAt + amt, msg));\n    }\n\n    /** {@inheritDoc} */\n    public void endAnnotation() {\n        if (annotations == null) {\n            return;\n        }\n\n        int sz = annotations.size();\n\n        if (sz != 0) {\n            annotations.get(sz - 1).setEndIfUnset(cursor);\n        }\n    }\n\n    /** {@inheritDoc} */\n    public int getAnnotationWidth() {\n        int leftWidth = 8 + (hexCols * 2) + (hexCols / 2);\n\n        return annotationWidth - leftWidth;\n    }\n\n    /**\n     * Indicates that this instance should keep annotations. This method may\n     * be called only once per instance, and only before any data has been\n     * written to the it.\n     *\n     * @param annotationWidth {@code >= 40;} the desired maximum annotation width\n     * @param verbose whether or not to indicate verbose annotations\n     */\n    public void enableAnnotations(int annotationWidth, boolean verbose) {\n        if ((annotations != null) || (cursor != 0)) {\n            throw new RuntimeException(\"cannot enable annotations\");\n        }\n\n        if (annotationWidth < 40) {\n            throw new IllegalArgumentException(\"annotationWidth < 40\");\n        }\n\n        int hexCols = (((annotationWidth - 7) / 15) + 1) & ~1;\n        if (hexCols < 6) {\n            hexCols = 6;\n        } else if (hexCols > 10) {\n            hexCols = 10;\n        }\n\n        this.annotations = new ArrayList<Annotation>(1000);\n        this.annotationWidth = annotationWidth;\n        this.hexCols = hexCols;\n        this.verbose = verbose;\n    }\n\n    /**\n     * Finishes up annotation processing. This closes off any open\n     * annotations and removes annotations that don't refer to written\n     * data.\n     */\n    public void finishAnnotating() {\n        // Close off the final annotation, if any.\n        endAnnotation();\n\n        // Remove annotations that refer to unwritten data.\n        if (annotations != null) {\n            int asz = annotations.size();\n            while (asz > 0) {\n                Annotation last = annotations.get(asz - 1);\n                if (last.getStart() > cursor) {\n                    annotations.remove(asz - 1);\n                    asz--;\n                } else if (last.getEnd() > cursor) {\n                    last.setEnd(cursor);\n                    break;\n                } else {\n                    break;\n                }\n            }\n        }\n    }\n\n    /**\n     * Writes the annotated content of this instance to the given writer.\n     *\n     * @param out {@code non-null;} where to write to\n     */\n    public void writeAnnotationsTo(Writer out) throws IOException {\n        int width2 = getAnnotationWidth();\n        int width1 = annotationWidth - width2 - 1;\n\n        TwoColumnOutput twoc = new TwoColumnOutput(out, width1, width2, \"|\");\n        Writer left = twoc.getLeft();\n        Writer right = twoc.getRight();\n        int leftAt = 0; // left-hand byte output cursor\n        int rightAt = 0; // right-hand annotation index\n        int rightSz = annotations.size();\n\n        while ((leftAt < cursor) && (rightAt < rightSz)) {\n            Annotation a = annotations.get(rightAt);\n            int start = a.getStart();\n            int end;\n            String text;\n\n            if (leftAt < start) {\n                // This is an area with no annotation.\n                end = start;\n                start = leftAt;\n                text = \"\";\n            } else {\n                // This is an area with an annotation.\n                end = a.getEnd();\n                text = a.getText();\n                rightAt++;\n            }\n\n            left.write(Hex.dump(data, start, end - start, start, hexCols, 6));\n            right.write(text);\n            twoc.flush();\n            leftAt = end;\n        }\n\n        if (leftAt < cursor) {\n            // There is unannotated output at the end.\n            left.write(Hex.dump(data, leftAt, cursor - leftAt, leftAt,\n                                hexCols, 6));\n        }\n\n        while (rightAt < rightSz) {\n            // There are zero-byte annotations at the end.\n            right.write(annotations.get(rightAt).getText());\n            rightAt++;\n        }\n\n        twoc.flush();\n    }\n\n    /**\n     * Throws the excpetion for when an attempt is made to write past the\n     * end of the instance.\n     */\n    private static void throwBounds() {\n        throw new IndexOutOfBoundsException(\"attempt to write past the end\");\n    }\n\n    /**\n     * Reallocates the underlying array if necessary. Calls to this method\n     * should be guarded by a test of {@link #stretchy}.\n     *\n     * @param desiredSize {@code >= 0;} the desired minimum total size of the array\n     */\n    private void ensureCapacity(int desiredSize) {\n        if (data.length < desiredSize) {\n            byte[] newData = new byte[desiredSize * 2 + 1000];\n            System.arraycopy(data, 0, newData, 0, cursor);\n            data = newData;\n        }\n    }\n\n    /**\n     * Annotation on output.\n     */\n    private static class Annotation {\n        /** {@code >= 0;} start of annotated range (inclusive) */\n        private final int start;\n\n        /**\n         * {@code >= 0;} end of annotated range (exclusive);\n         * {@code Integer.MAX_VALUE} if unclosed\n         */\n        private int end;\n\n        /** {@code non-null;} annotation text */\n        private final String text;\n\n        /**\n         * Constructs an instance.\n         *\n         * @param start {@code >= 0;} start of annotated range\n         * @param end {@code >= start;} end of annotated range (exclusive) or\n         * {@code Integer.MAX_VALUE} if unclosed\n         * @param text {@code non-null;} annotation text\n         */\n        public Annotation(int start, int end, String text) {\n            this.start = start;\n            this.end = end;\n            this.text = text;\n        }\n\n        /**\n         * Constructs an instance. It is initally unclosed.\n         *\n         * @param start {@code >= 0;} start of annotated range\n         * @param text {@code non-null;} annotation text\n         */\n        public Annotation(int start, String text) {\n            this(start, Integer.MAX_VALUE, text);\n        }\n\n        /**\n         * Sets the end as given, but only if the instance is unclosed;\n         * otherwise, do nothing.\n         *\n         * @param end {@code >= start;} the end\n         */\n        public void setEndIfUnset(int end) {\n            if (this.end == Integer.MAX_VALUE) {\n                this.end = end;\n            }\n        }\n\n        /**\n         * Sets the end as given.\n         *\n         * @param end {@code >= start;} the end\n         */\n        public void setEnd(int end) {\n            this.end = end;\n        }\n\n        /**\n         * Gets the start.\n         *\n         * @return the start\n         */\n        public int getStart() {\n            return start;\n        }\n\n        /**\n         * Gets the end.\n         *\n         * @return the end\n         */\n        public int getEnd() {\n            return end;\n        }\n\n        /**\n         * Gets the text.\n         *\n         * @return {@code non-null;} the text\n         */\n        public String getText() {\n            return text;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/FixedSizeList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\nimport java.util.Arrays;\n\n/**\n * Simple (mostly) fixed-size list of objects, which may be made immutable.\n */\npublic class FixedSizeList\n        extends MutabilityControl implements ToHuman {\n    /** {@code non-null;} array of elements */\n    private Object[] arr;\n\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size the size of the list\n     */\n    public FixedSizeList(int size) {\n        super(size != 0);\n\n        try {\n            arr = new Object[size];\n        } catch (NegativeArraySizeException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"size < 0\");\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (this == other) {\n            // Easy out.\n            return true;\n        }\n\n        if ((other == null) || (getClass() != other.getClass())) {\n            // Another easy out.\n            return false;\n        }\n\n        FixedSizeList list = (FixedSizeList) other;\n        return Arrays.equals(arr, list.arr);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return Arrays.hashCode(arr);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        String name = getClass().getName();\n\n        return toString0(name.substring(name.lastIndexOf('.') + 1) + '{',\n                         \", \",\n                         \"}\",\n                         false);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * This method will only work if every element of the list\n     * implements {@link ToHuman}.\n     */\n    public String toHuman() {\n        String name = getClass().getName();\n\n        return toString0(name.substring(name.lastIndexOf('.') + 1) + '{',\n                         \", \",\n                         \"}\",\n                         true);\n    }\n\n    /**\n     * Gets a customized string form for this instance.\n     *\n     * @param prefix {@code null-ok;} prefix for the start of the result\n     * @param separator {@code null-ok;} separator to insert between each item\n     * @param suffix {@code null-ok;} suffix for the end of the result\n     * @return {@code non-null;} the custom string\n     */\n    public String toString(String prefix, String separator, String suffix) {\n        return toString0(prefix, separator, suffix, false);\n    }\n\n    /**\n     * Gets a customized human string for this instance. This method will\n     * only work if every element of the list implements {@link\n     * ToHuman}.\n     *\n     * @param prefix {@code null-ok;} prefix for the start of the result\n     * @param separator {@code null-ok;} separator to insert between each item\n     * @param suffix {@code null-ok;} suffix for the end of the result\n     * @return {@code non-null;} the custom string\n     */\n    public String toHuman(String prefix, String separator, String suffix) {\n        return toString0(prefix, separator, suffix, true);\n    }\n\n    /**\n     * Gets the number of elements in this list.\n     */\n    public final int size() {\n        return arr.length;\n    }\n\n    /**\n     * Shrinks this instance to fit, by removing any unset\n     * ({@code null}) elements, leaving the remaining elements in\n     * their original order.\n     */\n    public void shrinkToFit() {\n        int sz = arr.length;\n        int newSz = 0;\n\n        for (int i = 0; i < sz; i++) {\n            if (arr[i] != null) {\n                newSz++;\n            }\n        }\n\n        if (sz == newSz) {\n            return;\n        }\n\n        throwIfImmutable();\n\n        Object[] newa = new Object[newSz];\n        int at = 0;\n\n        for (int i = 0; i < sz; i++) {\n            Object one = arr[i];\n            if (one != null) {\n                newa[at] = one;\n                at++;\n            }\n        }\n\n        arr = newa;\n        if (newSz == 0) {\n            setImmutable();\n        }\n    }\n\n    /**\n     * Gets the indicated element. It is an error to call this with the\n     * index for an element which was never set; if you do that, this\n     * will throw {@code NullPointerException}. This method is\n     * protected so that subclasses may offer a safe type-checked\n     * public interface to their clients.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @return {@code non-null;} the indicated element\n     */\n    protected final Object get0(int n) {\n        try {\n            Object result = arr[n];\n\n            if (result == null) {\n                throw new NullPointerException(\"unset: \" + n);\n            }\n\n            return result;\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            return throwIndex(n);\n        }\n    }\n\n    /**\n     * Gets the indicated element, allowing {@code null}s to be\n     * returned. This method is protected so that subclasses may\n     * (optionally) offer a safe type-checked public interface to\n     * their clients.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @return {@code null-ok;} the indicated element\n     */\n    protected final Object getOrNull0(int n) {\n        return arr[n];\n    }\n\n    /**\n     * Sets the element at the given index, but without doing any type\n     * checks on the element. This method is protected so that\n     * subclasses may offer a safe type-checked public interface to\n     * their clients.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @param obj {@code null-ok;} the value to store\n     */\n    protected final void set0(int n, Object obj) {\n        throwIfImmutable();\n\n        try {\n            arr[n] = obj;\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            throwIndex(n);\n        }\n    }\n\n    /**\n     * Throws the appropriate exception for the given index value.\n     *\n     * @param n the index value\n     * @return never\n     * @throws IndexOutOfBoundsException always thrown\n     */\n    private Object throwIndex(int n) {\n        if (n < 0) {\n            throw new IndexOutOfBoundsException(\"n < 0\");\n        }\n\n        throw new IndexOutOfBoundsException(\"n >= size()\");\n    }\n\n    /**\n     * Helper for {@link #toString} and {@link #toHuman}, which both of\n     * those call to pretty much do everything.\n     *\n     * @param prefix {@code null-ok;} prefix for the start of the result\n     * @param separator {@code null-ok;} separator to insert between each item\n     * @param suffix {@code null-ok;} suffix for the end of the result\n     * @param human whether the output is to be human\n     * @return {@code non-null;} the custom string\n     */\n    private String toString0(String prefix, String separator, String suffix,\n                             boolean human) {\n        int len = arr.length;\n        StringBuffer sb = new StringBuffer(len * 10 + 10);\n\n        if (prefix != null) {\n            sb.append(prefix);\n        }\n\n        for (int i = 0; i < len; i++) {\n            if ((i != 0) && (separator != null)) {\n                sb.append(separator);\n            }\n\n            if (human) {\n                sb.append(((ToHuman) arr[i]).toHuman());\n            } else {\n                sb.append(arr[i]);\n            }\n        }\n\n        if (suffix != null) {\n            sb.append(suffix);\n        }\n\n        return sb.toString();\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/Hex.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\n/**\n * Utilities for formatting numbers as hexadecimal.\n */\npublic final class Hex {\n    /**\n     * This class is uninstantiable.\n     */\n    private Hex() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Formats a {@code long} as an 8-byte unsigned hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String u8(long v) {\n        char[] result = new char[16];\n        for (int i = 0; i < 16; i++) {\n            result[15 - i] = Character.forDigit((int) v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as a 4-byte unsigned hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String u4(int v) {\n        char[] result = new char[8];\n        for (int i = 0; i < 8; i++) {\n            result[7 - i] = Character.forDigit(v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as a 3-byte unsigned hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String u3(int v) {\n        char[] result = new char[6];\n        for (int i = 0; i < 6; i++) {\n            result[5 - i] = Character.forDigit(v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as a 2-byte unsigned hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String u2(int v) {\n        char[] result = new char[4];\n        for (int i = 0; i < 4; i++) {\n            result[3 - i] = Character.forDigit(v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as either a 2-byte unsigned hex value\n     * (if the value is small enough) or a 4-byte unsigned hex value (if\n     * not).\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String u2or4(int v) {\n        if (v == (char) v) {\n            return u2(v);\n        } else {\n            return u4(v);\n        }\n    }\n\n    /**\n     * Formats an {@code int} as a 1-byte unsigned hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String u1(int v) {\n        char[] result = new char[2];\n        for (int i = 0; i < 2; i++) {\n            result[1 - i] = Character.forDigit(v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as a 4-bit unsigned hex nibble.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String uNibble(int v) {\n        char[] result = new char[1];\n\n        result[0] = Character.forDigit(v & 0x0f, 16);\n        return new String(result);\n    }\n\n    /**\n     * Formats a {@code long} as an 8-byte signed hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String s8(long v) {\n        char[] result = new char[17];\n\n        if (v < 0) {\n            result[0] = '-';\n            v = -v;\n        } else {\n            result[0] = '+';\n        }\n\n        for (int i = 0; i < 16; i++) {\n            result[16 - i] = Character.forDigit((int) v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as a 4-byte signed hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String s4(int v) {\n        char[] result = new char[9];\n\n        if (v < 0) {\n            result[0] = '-';\n            v = -v;\n        } else {\n            result[0] = '+';\n        }\n\n        for (int i = 0; i < 8; i++) {\n            result[8 - i] = Character.forDigit(v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as a 2-byte signed hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String s2(int v) {\n        char[] result = new char[5];\n\n        if (v < 0) {\n            result[0] = '-';\n            v = -v;\n        } else {\n            result[0] = '+';\n        }\n\n        for (int i = 0; i < 4; i++) {\n            result[4 - i] = Character.forDigit(v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as a 1-byte signed hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String s1(int v) {\n        char[] result = new char[3];\n\n        if (v < 0) {\n            result[0] = '-';\n            v = -v;\n        } else {\n            result[0] = '+';\n        }\n\n        for (int i = 0; i < 2; i++) {\n            result[2 - i] = Character.forDigit(v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats a hex dump of a portion of a {@code byte[]}. The result\n     * is always newline-terminated, unless the passed-in length was zero,\n     * in which case the result is always the empty string ({@code \"\"}).\n     *\n     * @param arr {@code non-null;} array to format\n     * @param offset {@code >= 0;} offset to the part to dump\n     * @param length {@code >= 0;} number of bytes to dump\n     * @param outOffset {@code >= 0;} first output offset to print\n     * @param bpl {@code >= 0;} number of bytes of output per line\n     * @param addressLength {@code {2,4,6,8};} number of characters for each address\n     * header\n     * @return {@code non-null;} a string of the dump\n     */\n    public static String dump(byte[] arr, int offset, int length,\n                              int outOffset, int bpl, int addressLength) {\n        int end = offset + length;\n\n        // twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0)\n        if (((offset | length | end) < 0) || (end > arr.length)) {\n            throw new IndexOutOfBoundsException(\"arr.length \" +\n                                                arr.length + \"; \" +\n                                                offset + \"..!\" + end);\n        }\n\n        if (outOffset < 0) {\n            throw new IllegalArgumentException(\"outOffset < 0\");\n        }\n\n        if (length == 0) {\n            return \"\";\n        }\n\n        StringBuffer sb = new StringBuffer(length * 4 + 6);\n        boolean bol = true;\n        int col = 0;\n\n        while (length > 0) {\n            if (col == 0) {\n                String astr;\n                switch (addressLength) {\n                    case 2:  astr = Hex.u1(outOffset); break;\n                    case 4:  astr = Hex.u2(outOffset); break;\n                    case 6:  astr = Hex.u3(outOffset); break;\n                    default: astr = Hex.u4(outOffset); break;\n                }\n                sb.append(astr);\n                sb.append(\": \");\n            } else if ((col & 1) == 0) {\n                sb.append(' ');\n            }\n            sb.append(Hex.u1(arr[offset]));\n            outOffset++;\n            offset++;\n            col++;\n            if (col == bpl) {\n                sb.append('\\n');\n                col = 0;\n            }\n            length--;\n        }\n\n        if (col != 0) {\n            sb.append('\\n');\n        }\n\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/HexParser.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\n/**\n * Utilities for parsing hexadecimal text.\n */\npublic final class HexParser {\n    /**\n     * This class is uninstantiable.\n     */\n    private HexParser() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Parses the given text as hex, returning a {@code byte[]}\n     * corresponding to the text. The format is simple: Each line may\n     * start with a hex offset followed by a colon (which is verified\n     * and presumably used just as a comment), and then consists of\n     * hex digits freely interspersed with whitespace. If a pound sign\n     * is encountered, it and the rest of the line are ignored as a\n     * comment. If a double quote is encountered, then the ASCII value\n     * of the subsequent characters is used, until the next double\n     * quote. Quoted strings may not span multiple lines.\n     *\n     * @param src {@code non-null;} the source string\n     * @return {@code non-null;} the parsed form\n     */\n    public static byte[] parse(String src) {\n        int len = src.length();\n        byte[] result = new byte[len / 2];\n        int at = 0;\n        int outAt = 0;\n\n        while (at < len) {\n            int nlAt = src.indexOf('\\n', at);\n            if (nlAt < 0) {\n                nlAt = len;\n            }\n            int poundAt = src.indexOf('#', at);\n\n            String line;\n            if ((poundAt >= 0) && (poundAt < nlAt)) {\n                line = src.substring(at, poundAt);\n            } else {\n                line = src.substring(at, nlAt);\n            }\n            at = nlAt + 1;\n\n            int colonAt = line.indexOf(':');\n\n            atCheck:\n            if (colonAt != -1) {\n                int quoteAt = line.indexOf('\\\"');\n                if ((quoteAt != -1) && (quoteAt < colonAt)) {\n                    break atCheck;\n                }\n\n                String atStr = line.substring(0, colonAt).trim();\n                line = line.substring(colonAt + 1);\n                int alleged = Integer.parseInt(atStr, 16);\n                if (alleged != outAt) {\n                    throw new RuntimeException(\"bogus offset marker: \" +\n                                               atStr);\n                }\n            }\n\n            int lineLen = line.length();\n            int value = -1;\n            boolean quoteMode = false;\n\n            for (int i = 0; i < lineLen; i++) {\n                char c = line.charAt(i);\n\n                if (quoteMode) {\n                    if (c == '\\\"') {\n                        quoteMode = false;\n                    } else {\n                        result[outAt] = (byte) c;\n                        outAt++;\n                    }\n                    continue;\n                }\n\n                if (c <= ' ') {\n                    continue;\n                }\n                if (c == '\\\"') {\n                    if (value != -1) {\n                        throw new RuntimeException(\"spare digit around \" +\n                                                   \"offset \" + Hex.u4(outAt));\n                    }\n                    quoteMode = true;\n                    continue;\n                }\n\n                int digVal = Character.digit(c, 16);\n                if (digVal == -1) {\n                    throw new RuntimeException(\"bogus digit character: \\\"\" +\n                                               c + \"\\\"\");\n                }\n                if (value == -1) {\n                    value = digVal;\n                } else {\n                    result[outAt] = (byte) ((value << 4) | digVal);\n                    outAt++;\n                    value = -1;\n                }\n            }\n\n            if (value != -1) {\n                throw new RuntimeException(\"spare digit around offset \" +\n                                           Hex.u4(outAt));\n            }\n\n            if (quoteMode) {\n                throw new RuntimeException(\"unterminated quote around \" +\n                                           \"offset \" + Hex.u4(outAt));\n            }\n        }\n\n        if (outAt < result.length) {\n            byte[] newr = new byte[outAt];\n            System.arraycopy(result, 0, newr, 0, outAt);\n            result = newr;\n        }\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/IndentingWriter.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\nimport java.io.FilterWriter;\nimport java.io.IOException;\nimport java.io.Writer;\n\n/**\n * Writer that wraps another writer and passes width-limited and\n * optionally-prefixed output to its subordinate. When lines are\n * wrapped they are automatically indented based on the start of the\n * line.\n */\npublic final class IndentingWriter extends FilterWriter {\n    /** {@code null-ok;} optional prefix for every line */\n    private final String prefix;\n\n    /** {@code > 0;} the maximum output width */\n    private final int width;\n\n    /** {@code > 0;} the maximum indent */\n    private final int maxIndent;\n\n    /** {@code >= 0;} current output column (zero-based) */\n    private int column;\n\n    /** whether indent spaces are currently being collected */\n    private boolean collectingIndent;\n\n    /** {@code >= 0;} current indent amount */\n    private int indent;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param out {@code non-null;} writer to send final output to\n     * @param width {@code >= 0;} the maximum output width (not including\n     * {@code prefix}), or {@code 0} for no maximum\n     * @param prefix {@code non-null;} the prefix for each line\n     */\n    public IndentingWriter(Writer out, int width, String prefix) {\n        super(out);\n\n        if (out == null) {\n            throw new NullPointerException(\"out == null\");\n        }\n\n        if (width < 0) {\n            throw new IllegalArgumentException(\"width < 0\");\n        }\n\n        if (prefix == null) {\n            throw new NullPointerException(\"prefix == null\");\n        }\n\n        this.width = (width != 0) ? width : Integer.MAX_VALUE;\n        this.maxIndent = width >> 1;\n        this.prefix = (prefix.length() == 0) ? null : prefix;\n\n        bol();\n    }\n\n    /**\n     * Constructs a no-prefix instance.\n     *\n     * @param out {@code non-null;} writer to send final output to\n     * @param width {@code >= 0;} the maximum output width (not including\n     * {@code prefix}), or {@code 0} for no maximum\n     */\n    public IndentingWriter(Writer out, int width) {\n        this(out, width, \"\");\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void write(int c) throws IOException {\n        synchronized (lock) {\n            if (collectingIndent) {\n                if (c == ' ') {\n                    indent++;\n                    if (indent >= maxIndent) {\n                        indent = maxIndent;\n                        collectingIndent = false;\n                    }\n                } else {\n                    collectingIndent = false;\n                }\n            }\n\n            if ((column == width) && (c != '\\n')) {\n                out.write('\\n');\n                column = 0;\n                /*\n                 * Note: No else, so this should fall through to the next\n                 * if statement.\n                 */\n            }\n\n            if (column == 0) {\n                if (prefix != null) {\n                    out.write(prefix);\n                }\n\n                if (!collectingIndent) {\n                    for (int i = 0; i < indent; i++) {\n                        out.write(' ');\n                    }\n                    column = indent;\n                }\n            }\n\n            out.write(c);\n\n            if (c == '\\n') {\n                bol();\n            } else {\n                column++;\n            }\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void write(char[] cbuf, int off, int len) throws IOException {\n        synchronized (lock) {\n            while (len > 0) {\n                write(cbuf[off]);\n                off++;\n                len--;\n            }\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void write(String str, int off, int len) throws IOException {\n        synchronized (lock) {\n            while (len > 0) {\n                write(str.charAt(off));\n                off++;\n                len--;\n            }\n        }\n    }\n\n    /**\n     * Indicates that output is at the beginning of a line.\n     */\n    private void bol() {\n        column = 0;\n        collectingIndent = (maxIndent != 0);\n        indent = 0;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/IntIterator.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\n/**\n * An iterator for a list of ints.\n */\npublic interface IntIterator {\n\n    /**\n     * Checks to see if the iterator has a next value.\n     *\n     * @return true if next() will succeed\n     */\n    boolean hasNext();\n\n    /**\n     * Returns the next value in the iterator.\n     *\n     * @return next value\n     * @throws java.util.NoSuchElementException if no next element exists\n     */\n    int next();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/IntList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\nimport java.util.Arrays;\n\n/**\n * Simple list of {@code int}s.\n */\npublic final class IntList extends MutabilityControl {\n    /** {@code non-null;} immutable, no-element instance */\n    public static final IntList EMPTY = new IntList(0);\n\n    /** {@code non-null;} array of elements */\n    private int[] values;\n\n    /** {@code >= 0;} current size of the list */\n    private int size;\n\n    /** whether the values are currently sorted */\n    private boolean sorted;\n\n    static {\n        EMPTY.setImmutable();\n    }\n\n    /**\n     * Constructs a new immutable instance with the given element.\n     *\n     * @param value the sole value in the list\n     */\n    public static IntList makeImmutable(int value) {\n        IntList result = new IntList(1);\n\n        result.add(value);\n        result.setImmutable();\n\n        return result;\n    }\n\n    /**\n     * Constructs a new immutable instance with the given elements.\n     *\n     * @param value0 the first value in the list\n     * @param value1 the second value in the list\n     */\n    public static IntList makeImmutable(int value0, int value1) {\n        IntList result = new IntList(2);\n\n        result.add(value0);\n        result.add(value1);\n        result.setImmutable();\n\n        return result;\n    }\n\n    /**\n     * Constructs an empty instance with a default initial capacity.\n     */\n    public IntList() {\n        this(4);\n    }\n\n    /**\n     * Constructs an empty instance.\n     *\n     * @param initialCapacity {@code >= 0;} initial capacity of the list\n     */\n    public IntList(int initialCapacity) {\n        super(true);\n\n        try {\n            values = new int[initialCapacity];\n        } catch (NegativeArraySizeException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"size < 0\");\n        }\n\n        size = 0;\n        sorted = true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        int result = 0;\n\n        for (int i = 0; i < size; i++) {\n            result = (result * 31) + values[i];\n        }\n\n        return result;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (other == this) {\n            return true;\n        }\n\n        if (! (other instanceof IntList)) {\n            return false;\n        }\n\n        IntList otherList = (IntList) other;\n\n        if (sorted != otherList.sorted) {\n            return false;\n        }\n\n        if (size != otherList.size) {\n            return false;\n        }\n\n        for (int i = 0; i < size; i++) {\n            if (values[i] != otherList.values[i]) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        StringBuffer sb = new StringBuffer(size * 5 + 10);\n\n        sb.append('{');\n\n        for (int i = 0; i < size; i++) {\n            if (i != 0) {\n                sb.append(\", \");\n            }\n            sb.append(values[i]);\n        }\n\n        sb.append('}');\n\n        return sb.toString();\n    }\n\n    /**\n     * Gets the number of elements in this list.\n     */\n    public int size() {\n        return size;\n    }\n\n    /**\n     * Gets the indicated value.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @return the indicated element's value\n     */\n    public int get(int n) {\n        if (n >= size) {\n            throw new IndexOutOfBoundsException(\"n >= size()\");\n        }\n\n        try {\n            return values[n];\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate exception.\n            throw new IndexOutOfBoundsException(\"n < 0\");\n        }\n    }\n\n    /**\n     * Sets the value at the given index.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @param value value to store\n     */\n    public void set(int n, int value) {\n        throwIfImmutable();\n\n        if (n >= size) {\n            throw new IndexOutOfBoundsException(\"n >= size()\");\n        }\n\n        try {\n            values[n] = value;\n            sorted = false;\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            if (n < 0) {\n                throw new IllegalArgumentException(\"n < 0\");\n            }\n        }\n    }\n\n    /**\n     * Adds an element to the end of the list. This will increase the\n     * list's capacity if necessary.\n     *\n     * @param value the value to add\n     */\n    public void add(int value) {\n        throwIfImmutable();\n\n        growIfNeeded();\n\n        values[size++] = value;\n\n        if (sorted && (size > 1)) {\n            sorted = (value >= values[size - 2]);\n        }\n    }\n\n    /**\n     * Inserts element into specified index, moving elements at and above\n     * that index up one. May not be used to insert at an index beyond the\n     * current size (that is, insertion as a last element is legal but\n     * no further).\n     *\n     * @param n {@code >= 0, <=size();} index of where to insert\n     * @param value value to insert\n     */\n    public void insert(int n, int value) {\n        if (n > size) {\n            throw new IndexOutOfBoundsException(\"n > size()\");\n        }\n\n        growIfNeeded();\n\n        System.arraycopy (values, n, values, n+1, size - n);\n        values[n] = value;\n        size++;\n\n        sorted = sorted\n                && (n == 0 || value > values[n-1])\n                && (n == (size - 1) || value < values[n+1]);\n    }\n\n    /**\n     * Removes an element at a given index, shifting elements at greater\n     * indicies down one.\n     *\n     * @param n  {@code >=0, < size();} index of element to remove\n     */\n    public void removeIndex(int n) {\n        if (n >= size) {\n            throw new IndexOutOfBoundsException(\"n >= size()\");\n        }\n\n        System.arraycopy (values, n + 1, values, n, size - n - 1);\n        size--;\n\n        // sort status is unchanged\n    }\n\n    /**\n     * Increases size of array if needed\n     */\n    private void growIfNeeded() {\n        if (size == values.length) {\n            // Resize.\n            int[] newv = new int[size * 3 / 2 + 10];\n            System.arraycopy(values, 0, newv, 0, size);\n            values = newv;\n        }\n    }\n\n    /**\n     * Returns the last element in the array without modifying the array\n     *\n     * @return last value in the array\n     * @throws IndexOutOfBoundsException if stack is empty\n     */\n    public int top() {\n        return get(size - 1);\n    }\n\n    /**\n     * Pops an element off the end of the list and decreasing the size by one.\n     *\n     * @return value from what was the last element\n     * @throws IndexOutOfBoundsException if stack is empty\n     */\n    public int pop() {\n        throwIfImmutable();\n\n        int result;\n\n        result = get(size-1);\n        size--;\n\n        return result;\n    }\n\n    /**\n     * Pops N elements off the end of the list and decreasing the size by N.\n     *\n     * @param n {@code >= 0;} number of elements to remove from end\n     * @throws IndexOutOfBoundsException if stack is smaller than N\n     */\n    public void pop(int n) {\n        throwIfImmutable();\n\n        size -= n;\n    }\n\n    /**\n     * Shrinks the size of the list.\n     *\n     * @param newSize {@code >= 0;} the new size\n     */\n    public void shrink(int newSize) {\n        if (newSize < 0) {\n            throw new IllegalArgumentException(\"newSize < 0\");\n        }\n\n        if (newSize > size) {\n            throw new IllegalArgumentException(\"newSize > size\");\n        }\n\n        throwIfImmutable();\n\n        size = newSize;\n    }\n\n    /**\n     * Makes and returns a mutable copy of the list.\n     *\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public IntList mutableCopy() {\n        int sz = size;\n        IntList result = new IntList(sz);\n\n        for (int i = 0; i < sz; i++) {\n            result.add(values[i]);\n        }\n\n        return result;\n    }\n\n    /**\n     * Sorts the elements in the list in-place.\n     */\n    public void sort() {\n        throwIfImmutable();\n\n        if (!sorted) {\n            Arrays.sort(values, 0, size);\n            sorted = true;\n        }\n    }\n\n    /**\n     * Returns the index of the given value, or -1 if the value does not\n     * appear in the list.  This will do a binary search if the list is\n     * sorted or a linear search if not.\n     *\n     * @param value value to find\n     * @return index of value or -1\n     */\n    public int indexOf(int value) {\n        int ret = binarysearch(value);\n\n        return ret >= 0 ? ret : -1;\n\n    }\n\n    /**\n     * Performs a binary search on a sorted list, returning the index of\n     * the given value if it is present or\n     * {@code (-(insertion point) - 1)} if the value is not present.\n     * If the list is not sorted, then reverts to linear search and returns\n     * {@code -size()} if the element is not found.\n     *\n     * @param value value to find\n     * @return index of value or {@code (-(insertion point) - 1)} if the\n     * value is not present\n     */\n    public int binarysearch(int value) {\n        int sz = size;\n\n        if (!sorted) {\n            // Linear search.\n            for (int i = 0; i < sz; i++) {\n                if (values[i] == value) {\n                    return i;\n                }\n            }\n\n            return -sz;\n        }\n\n        /*\n         * Binary search. This variant does only one value comparison\n         * per iteration but does one more iteration on average than\n         * the variant that includes a value equality check per\n         * iteration.\n         */\n\n        int min = -1;\n        int max = sz;\n\n        while (max > (min + 1)) {\n            /*\n             * The guessIdx calculation is equivalent to ((min + max)\n             * / 2) but won't go wonky when min and max are close to\n             * Integer.MAX_VALUE.\n             */\n            int guessIdx = min + ((max - min) >> 1);\n            int guess = values[guessIdx];\n\n            if (value <= guess) {\n                max = guessIdx;\n            } else {\n                min = guessIdx;\n            }\n        }\n\n        if ((max != sz)) {\n            return (value == values[max]) ? max : (-max - 1);\n        } else {\n            return -sz - 1;\n        }\n    }\n\n\n    /**\n     * Returns whether or not the given value appears in the list.\n     * This will do a binary search if the list is sorted or a linear\n     * search if not.\n     *\n     * @see #sort\n     *\n     * @param value value to look for\n     * @return whether the list contains the given value\n     */\n    public boolean contains(int value) {\n        return indexOf(value) >= 0;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/IntSet.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\n/**\n * A set of integers\n */\npublic interface IntSet {\n\n    /**\n     * Adds an int to a set\n     *\n     * @param value int to add\n     */\n    void add(int value);\n\n    /**\n     * Removes an int from a set.\n     *\n     * @param value int to remove\n     */\n    void remove(int value);\n\n    /**\n     * Checks to see if a value is in the set\n     *\n     * @param value int to check\n     * @return true if in set\n     */\n    boolean has(int value);\n\n    /**\n     * Merges {@code other} into this set, so this set becomes the\n     * union of the two.\n     *\n     * @param other {@code non-null;} other set to merge with.\n     */\n    void merge(IntSet other);\n\n    /**\n     * Returns the count of unique elements in this set.\n     *\n     * @return {@code > = 0;} count of unique elements\n     */\n    int elements();\n\n    /**\n     * Iterates the set\n     *\n     * @return {@code non-null;} a set iterator\n     */\n    IntIterator iterator();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/LabeledItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\n/**\n * An item that has an integer label.\n */\npublic interface LabeledItem {\n\n    /*\n     * Gets the label of this block.\n     *\n     * @return {@code >= 0;} the label\n     */\n    public int getLabel();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/LabeledList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\nimport java.util.Arrays;\n\n/**\n * A list of labeled items, allowing easy lookup by label.\n */\npublic class LabeledList extends FixedSizeList {\n    /**\n     * Sparse array indexed by label to FixedSizeList index;\n     * {@code -1} for an invalid label.\n     */\n    private final IntList labelToIndex;\n\n    /** @inheritDoc */\n    public LabeledList(int size) {\n        super(size);\n\n        labelToIndex = new IntList(size);\n    }\n\n    /**\n     * Constructs a new instance that is a copy of the old instance.\n     *\n     * @param old instance to copy\n     */\n    public LabeledList(LabeledList old) {\n        super(old.size());\n        labelToIndex = old.labelToIndex.mutableCopy();\n\n        int sz = old.size();\n\n        for (int i = 0; i < sz; i++) {\n            Object one = old.get0(i);\n            if (one != null) {\n                set0(i, one);\n            }\n        }\n    }\n\n    /**\n     * Gets the maximum label (exclusive) of any block added to this instance.\n     *\n     * @return {@code >= 0;} the maximum label\n     */\n    public final int getMaxLabel() {\n        int sz = labelToIndex.size();\n\n        // Gobble any deleted labels that may be at the end.\n        int i;\n        for (i = sz - 1; (i >= 0) && (labelToIndex.get(i) < 0); i--)\n            /*empty*/ ;\n\n        int newSize = i + 1;\n\n        labelToIndex.shrink(newSize);\n\n        return newSize;\n    }\n\n    /**\n     * Removes a label from the label-to-index mapping.\n     *\n     * @param oldLabel label to remove\n     */\n    private void removeLabel(int oldLabel) {\n        labelToIndex.set(oldLabel, -1);\n    }\n\n    /**\n     * Adds a label and index to the label-to-index mapping.\n     *\n     * @param label new label\n     * @param index index of block.\n     */\n    private void addLabelIndex(int label, int index) {\n        int origSz = labelToIndex.size();\n\n        for (int i = 0; i <= (label - origSz); i++) {\n            labelToIndex.add(-1);\n        }\n\n        labelToIndex.set(label, index);\n    }\n\n    /**\n     * Gets the index of the first item in the list with the given\n     * label, if any.\n     *\n     * @param label {@code >= 0;} the label to look for\n     * @return {@code >= -1;} the index of the so-labelled item, or {@code -1}\n     * if none is found\n     */\n    public final int indexOfLabel(int label) {\n        if (label >= labelToIndex.size()) {\n            return -1;\n        } else {\n            return labelToIndex.get(label);\n        }\n    }\n\n    /**\n     * Gets an array containing all of the labels used in this instance,\n     * in order. The returned array is freshly-allocated and so may be\n     * modified safely by the caller without impacting this instance.\n     *\n     * @return {@code non-null;} ordered array of labels\n     * @throws NullPointerException thrown if there are any {@code null}\n     * items in this instance\n     */\n    public final int[] getLabelsInOrder() {\n        int sz = size();\n        int[] result = new int[sz];\n\n        for (int i = 0; i < sz; i++) {\n            LabeledItem li = (LabeledItem) get0(i);\n            if (li == null) {\n                throw new NullPointerException(\"null at index \" + i);\n            }\n            result[i] = li.getLabel();\n        }\n\n        Arrays.sort(result);\n        return result;\n    }\n\n    /** @inheritDoc */\n    @Override\n    public void shrinkToFit() {\n        super.shrinkToFit();\n\n        rebuildLabelToIndex();\n    }\n\n    /**\n     * Rebuilds the label-to-index mapping after a {@code shrinkToFit()}.\n     * Note: This assumes that the labels that are in the list are the\n     * same, although the indicies may have changed.\n     */\n    private void rebuildLabelToIndex() {\n        int szItems = size();\n\n        for (int i = 0; i < szItems; i++) {\n            LabeledItem li = (LabeledItem) get0(i);\n\n            if (li != null) {\n                labelToIndex.set(li.getLabel(), i);\n            }\n        }\n    }\n\n    /**\n     * Sets the element at the given index.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @param item {@code null-ok;} the value to store\n     */\n    protected void set(int n, LabeledItem item) {\n        LabeledItem old = (LabeledItem) getOrNull0(n);\n\n        set0(n, item);\n\n        if (old != null) {\n            removeLabel(old.getLabel());\n        }\n\n        if (item != null) {\n            addLabelIndex(item.getLabel(), n);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/ListIntSet.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\nimport java.util.NoSuchElementException;\n\n/**\n * A set of integers, represented by a list\n */\npublic class ListIntSet implements IntSet {\n\n    /** also accessed in BitIntSet */\n    final IntList ints;\n\n    /**\n     * Constructs an instance\n     */\n    public ListIntSet() {\n        ints = new IntList();\n        ints.sort();\n    }\n\n    /** @inheritDoc */\n    public void add(int value) {\n        int index = ints.binarysearch(value);\n\n        if (index < 0) {\n            ints.insert(-(index + 1), value);\n        }\n    }\n\n    /** @inheritDoc */\n    public void remove(int value) {\n        int index = ints.indexOf(value);\n\n        if (index >= 0) {\n            ints.removeIndex(index);\n        }\n    }\n\n    /** @inheritDoc */\n    public boolean has(int value) {\n        return ints.indexOf(value) >= 0;\n    }\n\n    /** @inheritDoc */\n    public void merge(IntSet other) {\n        if (other instanceof ListIntSet) {\n            ListIntSet o = (ListIntSet) other;\n            int szThis = ints.size();\n            int szOther = o.ints.size();\n\n            int i = 0;\n            int j = 0;\n\n            while (j < szOther && i < szThis) {\n                while (j < szOther && o.ints.get(j) < ints.get(i)) {\n                    add(o.ints.get(j++));\n                }\n                if (j == szOther) {\n                    break;\n                }\n                while (i < szThis && o.ints.get(j) >= ints.get(i)) {\n                    i++;\n                }\n            }\n\n            while (j < szOther) {\n                add(o.ints.get(j++));\n            }\n\n            ints.sort();\n        } else if (other instanceof BitIntSet) {\n            BitIntSet o = (BitIntSet) other;\n\n            for (int i = 0; i >= 0; i = Bits.findFirst(o.bits, i + 1)) {\n                ints.add(i);\n            }\n            ints.sort();\n        } else {\n            IntIterator iter = other.iterator();\n            while (iter.hasNext()) {\n                add(iter.next());\n            }\n        }\n    }\n\n    /** @inheritDoc */\n    public int elements() {\n        return ints.size();\n    }\n\n    /** @inheritDoc */\n    public IntIterator iterator() {\n        return new IntIterator() {\n            private int idx = 0;\n\n            /** @inheritDoc */\n            public boolean hasNext() {\n                return idx < ints.size();\n            }\n\n            /** @inheritDoc */\n            public int next() {\n                if (!hasNext()) {\n                    throw new NoSuchElementException();\n                }\n\n                return ints.get(idx++);\n            }\n        };\n    }\n\n    /** @inheritDoc */\n    public String toString() {\n        return ints.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/MutabilityControl.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\n/**\n * Very simple base class that implements a flag to control the mutability\n * of instances. This class just provides the flag and a utility to check\n * and throw the right exception, but it is up to subclasses to place calls\n * to the checker in all the right places.\n */\npublic class MutabilityControl {\n    /** whether this instance is mutable */\n    private boolean mutable;\n\n    /**\n     * Constructs an instance. It is initially mutable.\n     */\n    public MutabilityControl() {\n        mutable = true;\n    }\n\n    /**\n     * Constructs an instance, explicitly indicating the mutability.\n     *\n     * @param mutable {@code true} iff this instance is mutable\n     */\n    public MutabilityControl(boolean mutable) {\n        this.mutable = mutable;\n    }\n\n    /**\n     * Makes this instance immutable.\n     */\n    public void setImmutable() {\n        mutable = false;\n    }\n\n    /**\n     * Checks to see whether or not this instance is immutable. This is the\n     * same as calling {@code !isMutable()}.\n     *\n     * @return {@code true} iff this instance is immutable\n     */\n    public final boolean isImmutable() {\n        return !mutable;\n    }\n\n    /**\n     * Checks to see whether or not this instance is mutable.\n     *\n     * @return {@code true} iff this instance is mutable\n     */\n    public final boolean isMutable() {\n        return mutable;\n    }\n\n    /**\n     * Throws {@link MutabilityException} if this instance is\n     * immutable.\n     */\n    public final void throwIfImmutable() {\n        if (!mutable) {\n            throw new MutabilityException(\"immutable instance\");\n        }\n    }\n\n    /**\n     * Throws {@link MutabilityException} if this instance is mutable.\n     */\n    public final void throwIfMutable() {\n        if (mutable) {\n            throw new MutabilityException(\"mutable instance\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/MutabilityException.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\nimport com.taobao.android.dex.util.ExceptionWithContext;\n\n/**\n * Exception due to a mutability problem.\n */\npublic class MutabilityException\n        extends ExceptionWithContext {\n    public MutabilityException(String message) {\n        super(message);\n    }\n\n    public MutabilityException(Throwable cause) {\n        super(cause);\n    }\n\n    public MutabilityException(String message, Throwable cause) {\n        super(message, cause);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/Output.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\nimport com.taobao.android.dex.util.ByteOutput;\n\n/**\n * Interface for a sink for binary output. This is similar to\n * {@code java.util.DataOutput}, but no {@code IOExceptions}\n * are declared, and multibyte output is defined to be little-endian.\n */\npublic interface Output extends ByteOutput {\n    /**\n     * Gets the current cursor position. This is the same as the number of\n     * bytes written to this instance.\n     *\n     * @return {@code >= 0;} the cursor position\n     */\n    public int getCursor();\n\n    /**\n     * Asserts that the cursor is the given value.\n     *\n     * @param expectedCursor the expected cursor value\n     * @throws RuntimeException thrown if {@code getCursor() !=\n     * expectedCursor}\n     */\n    public void assertCursor(int expectedCursor);\n\n    /**\n     * Writes a {@code byte} to this instance.\n     *\n     * @param value the value to write; all but the low 8 bits are ignored\n     */\n    public void writeByte(int value);\n\n    /**\n     * Writes a {@code short} to this instance.\n     *\n     * @param value the value to write; all but the low 16 bits are ignored\n     */\n    public void writeShort(int value);\n\n    /**\n     * Writes an {@code int} to this instance.\n     *\n     * @param value the value to write\n     */\n    public void writeInt(int value);\n\n    /**\n     * Writes a {@code long} to this instance.\n     *\n     * @param value the value to write\n     */\n    public void writeLong(long value);\n\n    /**\n     * Writes a DWARFv3-style unsigned LEB128 integer. For details,\n     * see the \"Dalvik Executable Format\" document or DWARF v3 section\n     * 7.6.\n     *\n     * @param value value to write, treated as an unsigned value\n     * @return {@code 1..5;} the number of bytes actually written\n     */\n    public int writeUleb128(int value);\n\n    /**\n     * Writes a DWARFv3-style unsigned LEB128 integer. For details,\n     * see the \"Dalvik Executable Format\" document or DWARF v3 section\n     * 7.6.\n     *\n     * @param value value to write\n     * @return {@code 1..5;} the number of bytes actually written\n     */\n    public int writeSleb128(int value);\n\n    /**\n     * Writes a {@link ByteArray} to this instance.\n     *\n     * @param bytes {@code non-null;} the array to write\n     */\n    public void write(ByteArray bytes);\n\n    /**\n     * Writes a portion of a {@code byte[]} to this instance.\n     *\n     * @param bytes {@code non-null;} the array to write\n     * @param offset {@code >= 0;} offset into {@code bytes} for the first\n     * byte to write\n     * @param length {@code >= 0;} number of bytes to write\n     */\n    public void write(byte[] bytes, int offset, int length);\n\n    /**\n     * Writes a {@code byte[]} to this instance. This is just\n     * a convenient shorthand for {@code write(bytes, 0, bytes.length)}.\n     *\n     * @param bytes {@code non-null;} the array to write\n     */\n    public void write(byte[] bytes);\n\n    /**\n     * Writes the given number of {@code 0} bytes.\n     *\n     * @param count {@code >= 0;} the number of zeroes to write\n     */\n    public void writeZeroes(int count);\n\n    /**\n     * Adds extra bytes if necessary (with value {@code 0}) to\n     * force alignment of the output cursor as given.\n     *\n     * @param alignment {@code > 0;} the alignment; must be a power of two\n     */\n    public void alignTo(int alignment);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/ToHuman.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\n/**\n * Simple interface for objects that can return a \"human\" (as opposed to\n * a complete but often hard to read) string form.\n */\npublic interface ToHuman {\n    /**\n     * Return the \"human\" string form of this instance.  This is\n     * generally less \"debuggy\" than {@code toString()}.\n     *\n     * @return {@code non-null;} the human string form\n     */\n    public String toHuman();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/TwoColumnOutput.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.io.OutputStreamWriter;\nimport java.io.StringWriter;\nimport java.io.Writer;\n\n/**\n * Class that takes a combined output destination and provides two\n * output writers, one of which ends up writing to the left column and\n * one which goes on the right.\n */\npublic final class TwoColumnOutput {\n    /** {@code non-null;} underlying writer for final output */\n    private final Writer out;\n\n    /** {@code > 0;} the left column width */\n    private final int leftWidth;\n\n    /** {@code non-null;} pending left column output */\n    private final StringBuffer leftBuf;\n\n    /** {@code non-null;} pending right column output */\n    private final StringBuffer rightBuf;\n\n    /** {@code non-null;} left column writer */\n    private final IndentingWriter leftColumn;\n\n    /** {@code non-null;} right column writer */\n    private final IndentingWriter rightColumn;\n\n    /**\n     * Turns the given two strings (with widths) and spacer into a formatted\n     * two-column string.\n     *\n     * @param s1 {@code non-null;} first string\n     * @param width1 {@code > 0;} width of the first column\n     * @param spacer {@code non-null;} spacer string\n     * @param s2 {@code non-null;} second string\n     * @param width2 {@code > 0;} width of the second column\n     * @return {@code non-null;} an appropriately-formatted string\n     */\n    public static String toString(String s1, int width1, String spacer,\n                                  String s2, int width2) {\n        int len1 = s1.length();\n        int len2 = s2.length();\n\n        StringWriter sw = new StringWriter((len1 + len2) * 3);\n        TwoColumnOutput twoOut =\n            new TwoColumnOutput(sw, width1, width2, spacer);\n\n        try {\n            twoOut.getLeft().write(s1);\n            twoOut.getRight().write(s2);\n        } catch (IOException ex) {\n            throw new RuntimeException(\"shouldn't happen\", ex);\n        }\n\n        twoOut.flush();\n        return sw.toString();\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param out {@code non-null;} writer to send final output to\n     * @param leftWidth {@code > 0;} width of the left column, in characters\n     * @param rightWidth {@code > 0;} width of the right column, in characters\n     * @param spacer {@code non-null;} spacer string to sit between the two columns\n     */\n    public TwoColumnOutput(Writer out, int leftWidth, int rightWidth,\n                           String spacer) {\n        if (out == null) {\n            throw new NullPointerException(\"out == null\");\n        }\n\n        if (leftWidth < 1) {\n            throw new IllegalArgumentException(\"leftWidth < 1\");\n        }\n\n        if (rightWidth < 1) {\n            throw new IllegalArgumentException(\"rightWidth < 1\");\n        }\n\n        if (spacer == null) {\n            throw new NullPointerException(\"spacer == null\");\n        }\n\n        StringWriter leftWriter = new StringWriter(1000);\n        StringWriter rightWriter = new StringWriter(1000);\n\n        this.out = out;\n        this.leftWidth = leftWidth;\n        this.leftBuf = leftWriter.getBuffer();\n        this.rightBuf = rightWriter.getBuffer();\n        this.leftColumn = new IndentingWriter(leftWriter, leftWidth);\n        this.rightColumn =\n            new IndentingWriter(rightWriter, rightWidth, spacer);\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param out {@code non-null;} stream to send final output to\n     * @param leftWidth {@code >= 1;} width of the left column, in characters\n     * @param rightWidth {@code >= 1;} width of the right column, in characters\n     * @param spacer {@code non-null;} spacer string to sit between the two columns\n     */\n    public TwoColumnOutput(OutputStream out, int leftWidth, int rightWidth,\n                           String spacer) {\n        this(new OutputStreamWriter(out), leftWidth, rightWidth, spacer);\n    }\n\n    /**\n     * Gets the writer to use to write to the left column.\n     *\n     * @return {@code non-null;} the left column writer\n     */\n    public Writer getLeft() {\n        return leftColumn;\n    }\n\n    /**\n     * Gets the writer to use to write to the right column.\n     *\n     * @return {@code non-null;} the right column writer\n     */\n    public Writer getRight() {\n        return rightColumn;\n    }\n\n    /**\n     * Flushes the output. If there are more lines of pending output in one\n     * column, then the other column will get filled with blank lines.\n     */\n    public void flush() {\n        try {\n            appendNewlineIfNecessary(leftBuf, leftColumn);\n            appendNewlineIfNecessary(rightBuf, rightColumn);\n            outputFullLines();\n            flushLeft();\n            flushRight();\n        } catch (IOException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n\n    /**\n     * Outputs to the final destination as many full line pairs as\n     * there are in the pending output, removing those lines from\n     * their respective buffers. This method terminates when at\n     * least one of the two column buffers is empty.\n     */\n    private void outputFullLines() throws IOException {\n        for (;;) {\n            int leftLen = leftBuf.indexOf(\"\\n\");\n            if (leftLen < 0) {\n                return;\n            }\n\n            int rightLen = rightBuf.indexOf(\"\\n\");\n            if (rightLen < 0) {\n                return;\n            }\n\n            if (leftLen != 0) {\n                out.write(leftBuf.substring(0, leftLen));\n            }\n\n            if (rightLen != 0) {\n                writeSpaces(out, leftWidth - leftLen);\n                out.write(rightBuf.substring(0, rightLen));\n            }\n\n            out.write('\\n');\n\n            leftBuf.delete(0, leftLen + 1);\n            rightBuf.delete(0, rightLen + 1);\n        }\n    }\n\n    /**\n     * Flushes the left column buffer, printing it and clearing the buffer.\n     * If the buffer is already empty, this does nothing.\n     */\n    private void flushLeft() throws IOException {\n        appendNewlineIfNecessary(leftBuf, leftColumn);\n\n        while (leftBuf.length() != 0) {\n            rightColumn.write('\\n');\n            outputFullLines();\n        }\n    }\n\n    /**\n     * Flushes the right column buffer, printing it and clearing the buffer.\n     * If the buffer is already empty, this does nothing.\n     */\n    private void flushRight() throws IOException {\n        appendNewlineIfNecessary(rightBuf, rightColumn);\n\n        while (rightBuf.length() != 0) {\n            leftColumn.write('\\n');\n            outputFullLines();\n        }\n    }\n\n    /**\n     * Appends a newline to the given buffer via the given writer, but\n     * only if it isn't empty and doesn't already end with one.\n     *\n     * @param buf {@code non-null;} the buffer in question\n     * @param out {@code non-null;} the writer to use\n     */\n    private static void appendNewlineIfNecessary(StringBuffer buf,\n                                                 Writer out)\n            throws IOException {\n        int len = buf.length();\n\n        if ((len != 0) && (buf.charAt(len - 1) != '\\n')) {\n            out.write('\\n');\n        }\n    }\n\n    /**\n     * Writes the given number of spaces to the given writer.\n     *\n     * @param out {@code non-null;} where to write\n     * @param amt {@code >= 0;} the number of spaces to write\n     */\n    private static void writeSpaces(Writer out, int amt) throws IOException {\n        while (amt > 0) {\n            out.write(' ');\n            amt--;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/Warning.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\n/**\n * Exception which is meant to indicate a non-fatal warning.\n */\npublic class Warning extends RuntimeException {\n    /**\n     * Constructs an instance.\n     *\n     * @param message human-oriented message\n     */\n    public Warning(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/Writers.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.dx.util;\n\nimport java.io.PrintWriter;\nimport java.io.Writer;\n\n/**\n * Utilities for dealing with {@code Writer}s.\n */\npublic final class Writers {\n    /**\n     * This class is uninstantiable.\n     */\n    private Writers() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Makes a {@code PrintWriter} for the given {@code Writer},\n     * returning the given writer if it already happens to be the right\n     * class.\n     *\n     * @param writer {@code non-null;} writer to (possibly) wrap\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static PrintWriter printWriterFor(Writer writer) {\n        if (writer instanceof PrintWriter) {\n            return (PrintWriter) writer;\n        }\n\n        return new PrintWriter(writer);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/dx/util/package.html",
    "content": "<body>\n<p>Utility classes for class file access/manipulation.</p>\n</body>\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/filter/AbstractDexFilter.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.filter;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\n\nimport com.taobao.android.differ.dex.PatchException;\nimport com.taobao.android.object.ClassDiffInfo;\nimport com.taobao.android.object.DexDiffInfo;\nimport com.taobao.android.object.FieldDiffInfo;\nimport com.taobao.android.object.MethodDiffInfo;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * Created by lilong on 16/6/18.\n */\npublic abstract class AbstractDexFilter implements DexDiffFilter {\n\n    protected DexDiffInfo diffInfo;\n\n\n    public AbstractDexFilter(DexDiffInfo diffInfo) throws PatchException {\n        this.diffInfo = diffInfo;\n    }\n\n    @Override\n    public abstract boolean filterClass(ClassDiffInfo classDiffInfo) throws PatchException;\n\n    @Override\n    public abstract boolean filterMethod(MethodDiffInfo methodDiffInfo) throws PatchException;\n\n    @Override\n    public abstract boolean filterField(FieldDiffInfo fieldDiffInfo) throws PatchException;\n\n    @Override\n    public void filterDex() throws PatchException {\n        if (diffInfo == null) {\n            return;\n        }\n        if (diffInfo.getClassDiffInfoMap().size() > 0) {\n            Set<String>filterClass = new HashSet<String>();\n            for (ClassDiffInfo classDiffInfo : diffInfo.getClassDiffInfoMap().values()) {\n                if (filterClass(classDiffInfo)){\n                    filterClass.add(classDiffInfo.getName());\n                }\n            }\n            for (String className:filterClass) {\n                diffInfo.getClassDiffInfoMap().remove(className);\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/filter/DexDiffFilter.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.filter;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.taobao.android.differ.dex.PatchException;\nimport com.taobao.android.object.ClassDiffInfo;\nimport com.taobao.android.object.FieldDiffInfo;\nimport com.taobao.android.object.MethodDiffInfo;\n\n/**\n * Created by lilong on 16/6/17.\n */\npublic interface DexDiffFilter {\n\n\n    boolean filterClass(ClassDiffInfo classDiffInfo) throws PatchException;\n\n    boolean filterMethod(MethodDiffInfo methodDiffInfo) throws PatchException;\n\n    boolean filterField(FieldDiffInfo fieldDiffInfo) throws PatchException;\n\n    void filterDex() throws PatchException;\n}"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/filter/Filter.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.filter;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport java.io.BufferedReader;\nimport java.io.FileNotFoundException;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/*\n * 该类主要是读取类白名单，通过传入的文件路径，将白名单中的类存储在filteredClassNames的list中\n */\n\npublic class Filter {\n    private String path;                               //白名单文件路径\n    private List<String> filteredClassNames = null;//存储白名单中的类名\n\n    public Filter(String path) {\n        this.path = path;\n        filteredClassNames = new ArrayList<String>();\n\n        try {\n            getFilteredClasses();\n        } catch (Exception e) {\n\n        }\n    }\n\n    //获取白名单的类，存放在filteredClassNames数组中\n    public void getFilteredClasses() throws IOException {\n        BufferedReader bufferedReader = null;\n        try {\n            FileReader fileReader = new FileReader(this.path);\n            bufferedReader = new BufferedReader(fileReader);\n            String line = null;\n            while ((line = bufferedReader.readLine()) != null) {\n                if (!line.trim().equals(\"\")) {\n                        filteredClassNames.add(line.trim());\n                    }\n            }\n        } catch (FileNotFoundException e) {\n            // TODO Auto-generated catch block\n            e.printStackTrace();\n        } finally {\n            bufferedReader.close();\n        }\n\n        System.out.println(\"白名单类个数是：\" + filteredClassNames.size());\n    }\n\n    //判断传入的类是否是一个白名单中被过滤的类\n    //参数className表示dex中的类\n    public boolean isFiltered(String className) {\n        boolean isFiltered = true;\n        for (String clazz:filteredClassNames){\n            if (clazz.equals(className)){\n                return false;\n            }\n        }\n        return isFiltered;\n    }\n\n    public static void main(String []args){\n        Filter filter = new Filter(\"/Users/lilong/Downloads/log\");\n        filter.isFiltered(\"Landroid/util/aa;\");\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/inputs/ApatchInput.java",
    "content": "package com.taobao.android.inputs;\n\nimport java.io.File;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * @author lilong\n * @create 2017-11-02 下午11:58\n */\n\npublic class ApatchInput extends BaseInput {\n\n    public  String replaceAnnotation = \"Lcom/alipay/euler/andfix/annotation/MethodReplace;\";\n\n    public boolean onlyIncludeModifyBundle = true;\n    public String filterPath;                                 // 类白名单路径\n\n    public  File mappingFile;\n\n    public String andfixMainBundleName = \"com_taobao_maindex\";\n\n    public String projectArtifactId;\n\n    public Map<String,String> mappingMap = new HashMap<String, String>();\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/inputs/BaseInput.java",
    "content": "package com.taobao.android.inputs;\n\nimport com.android.utils.Pair;\nimport com.google.common.collect.Sets;\nimport com.taobao.android.PatchType;\nimport com.taobao.android.object.ArtifactBundleInfo;\nimport com.taobao.android.tpatch.model.ApkBO;\nimport com.taobao.android.tpatch.model.BundleBO;\n\nimport java.io.File;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * @author lilong\n * @create 2017-11-02 下午11:50\n */\n\npublic class BaseInput {\n\n    public ApkBO baseApkBo;\n\n    public ApkBO newApkBo;\n\n    public Set<ArtifactBundleInfo> artifactBundleInfos = Sets.newHashSet();\n\n    public PatchType patchType;\n\n    public File baseApkFileList;\n\n    public File newApkFileList;\n\n    public File outPutFile;\n\n    public List<Pair<BundleBO,BundleBO>> splitDiffBundle;\n\n    public String[] notIncludeFiles;\n\n    public boolean diffBundleDex;\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/inputs/DexPatchInput.java",
    "content": "package com.taobao.android.inputs;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * @author lilong\n * @create 2017-11-02 下午11:57\n */\n\npublic class DexPatchInput extends TpatchInput {\n\n    public Set<String>excludeClasses;\n\n    public Set<String>patchClasses = new HashSet<>();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/inputs/HotPatchInput.java",
    "content": "package com.taobao.android.inputs;\n\nimport java.io.File;\n\n/**\n * @author lilong\n * @create 2017-11-07 下午2:15\n */\n\npublic class HotPatchInput extends DexPatchInput {\n\n    public File hotClassListFile;\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/inputs/TpatchInput.java",
    "content": "package com.taobao.android.inputs;\n\nimport com.google.common.collect.Lists;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * @author lilong\n * @create 2017-11-02 下午11:51\n */\n\npublic class TpatchInput extends BaseInput {\n\n\n    public boolean retainMainBundleRes = true;\n\n    public boolean createAll = false;\n\n    public boolean diffNativeSo;\n\n    public boolean diffBundleSo;\n\n    public File baseApkFileList;\n\n    public File newApkFileList;\n\n    public boolean hasMainBundle;\n\n    public List<String> noPatchBundles = Lists.newArrayList();\n\n    public List<String> versionList = new ArrayList<String>();\n\n    public String productName;\n\n    public String hisPatchUrl;\n\n    public boolean createHisPatch;\n\n    public String LAST_PATCH_URL;\n\n    public File outPatchDir;\n\n    public File outPutJson;\n\n    public File bundleWhiteList;\n\n    public boolean newPatch = true;\n\n    //dexpatch name:com.taobao.maindex\n    public String mainBundleName = \"libcom_taobao_maindex\";\n\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/multidex/ArchivePathElement.java",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.multidex;\n\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.Enumeration;\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n/**\n * A zip element.\n */\nclass ArchivePathElement implements ClassPathElement {\n\n    static class DirectoryEntryException extends IOException {\n    }\n\n    private final ZipFile archive;\n\n    public ArchivePathElement(ZipFile archive) {\n        this.archive = archive;\n    }\n\n    @Override\n    public InputStream open(String path) throws IOException {\n        ZipEntry entry = archive.getEntry(path);\n        if (entry == null) {\n            throw new FileNotFoundException(\"File \\\"\" + path + \"\\\" not found\");\n        } else if (entry.isDirectory()) {\n            throw new DirectoryEntryException();\n        } else {\n            return archive.getInputStream(entry);\n        }\n    }\n\n    @Override\n    public void close() throws IOException {\n        archive.close();\n    }\n\n    @Override\n    public Iterable<String> list() {\n        return new Iterable<String>() {\n\n            @Override\n            public Iterator<String> iterator() {\n                return new Iterator<String>() {\n                    Enumeration<? extends ZipEntry> delegate = archive.entries();\n                    ZipEntry next = null;\n\n                    @Override\n                    public boolean hasNext() {\n                        while (next == null && delegate.hasMoreElements()) {\n                            next = delegate.nextElement();\n                            if (next.isDirectory()) {\n                                next = null;\n                            }\n                        }\n                        return next != null;\n                    }\n\n                    @Override\n                    public String next() {\n                        if (hasNext()) {\n                            String name = next.getName();\n                            next = null;\n                            return name;\n                        } else {\n                            throw new NoSuchElementException();\n                        }\n                    }\n\n                    @Override\n                    public void remove() {\n                        throw new UnsupportedOperationException();\n                    }\n                };\n            }\n        };\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/multidex/ClassPathElement.java",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.multidex;\n\nimport java.io.IOException;\nimport java.io.InputStream;\n\n/**\n * An element of the class path in which class files can be found.\n */\ninterface ClassPathElement {\n\n    char SEPARATOR_CHAR = '/';\n\n    /**\n     * Open a \"file\" from this {@code ClassPathElement}.\n     * @param path a '/' separated relative path to the wanted file.\n     * @return an {@code InputStream} ready to read the requested file.\n     * @throws IOException if the path can not be found or if an error occurred while opening it.\n     */\n    InputStream open(String path) throws IOException;\n\n    void close() throws IOException;\n\n    Iterable<String> list();\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/multidex/ClassReferenceListBuilder.java",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.multidex;\n\nimport com.taobao.android.dx.cf.direct.DirectClassFile;\nimport com.taobao.android.dx.cf.iface.FieldList;\nimport com.taobao.android.dx.cf.iface.MethodList;\nimport com.taobao.android.dx.rop.cst.Constant;\nimport com.taobao.android.dx.rop.cst.CstBaseMethodRef;\nimport com.taobao.android.dx.rop.cst.CstFieldRef;\nimport com.taobao.android.dx.rop.cst.CstType;\nimport com.taobao.android.dx.rop.type.Prototype;\nimport com.taobao.android.dx.rop.type.StdTypeList;\nimport com.taobao.android.dx.rop.type.TypeList;\n\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.util.Enumeration;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n/**\n * Tool to find direct class references to other classes.\n */\npublic class ClassReferenceListBuilder {\n    private static final String CLASS_EXTENSION = \".class\";\n\n    private final Path path;\n    private final Set<String> classNames = new HashSet<String>();\n\n    public ClassReferenceListBuilder(Path path) {\n        this.path = path;\n    }\n\n    /**\n     * Kept for compatibility with the gradle integration, this method just forwards to\n     * {@link MainDexListBuilder#main(String[])}.\n     * @deprecated use {@link MainDexListBuilder#main(String[])} instead.\n     */\n    @Deprecated\n    public static void main(String[] args) {\n        MainDexListBuilder.main(args);\n    }\n\n    /**\n     * @param jarOfRoots Archive containing the class files resulting of the tracing, typically\n     * this is the result of running ProGuard.\n     */\n    public void addRoots(ZipFile jarOfRoots) throws IOException {\n\n        // keep roots\n        for (Enumeration<? extends ZipEntry> entries = jarOfRoots.entries();\n                entries.hasMoreElements();) {\n            ZipEntry entry = entries.nextElement();\n            String name = entry.getName();\n            if (name.endsWith(CLASS_EXTENSION)) {\n                classNames.add(name.substring(0, name.length() - CLASS_EXTENSION.length()));\n            }\n        }\n\n        // keep direct references of roots (+ direct references hierarchy)\n        for (Enumeration<? extends ZipEntry> entries = jarOfRoots.entries();\n                entries.hasMoreElements();) {\n            ZipEntry entry = entries.nextElement();\n            String name = entry.getName();\n            if (name.endsWith(CLASS_EXTENSION)) {\n                DirectClassFile classFile;\n                try {\n                    classFile = path.getClass(name);\n                } catch (FileNotFoundException e) {\n                    throw new IOException(\"Class \" + name +\n                            \" is missing form original class path \" + path, e);\n                }\n                addDependencies(classFile);\n            }\n        }\n    }\n\n    Set<String> getClassNames() {\n        return classNames;\n    }\n\n    private void addDependencies(DirectClassFile classFile) {\n        for (Constant constant : classFile.getConstantPool().getEntries()) {\n            if (constant instanceof CstType) {\n                checkDescriptor(((CstType) constant).getClassType().getDescriptor());\n            } else if (constant instanceof CstFieldRef) {\n                checkDescriptor(((CstFieldRef) constant).getType().getDescriptor());\n            } else if (constant instanceof CstBaseMethodRef) {\n                checkPrototype(((CstBaseMethodRef) constant).getPrototype());\n            }\n        }\n\n        FieldList fields = classFile.getFields();\n        int nbField = fields.size();\n        for (int i = 0; i < nbField; i++) {\n          checkDescriptor(fields.get(i).getDescriptor().getString());\n        }\n\n        MethodList methods = classFile.getMethods();\n        int nbMethods = methods.size();\n        for (int i = 0; i < nbMethods; i++) {\n          checkPrototype(Prototype.intern(methods.get(i).getDescriptor().getString()));\n        }\n    }\n\n    private void checkPrototype(Prototype proto) {\n      checkDescriptor(proto.getReturnType().getDescriptor());\n      StdTypeList args = proto.getParameterTypes();\n      for (int i = 0; i < args.size(); i++) {\n          checkDescriptor(args.get(i).getDescriptor());\n      }\n    }\n\n    private void checkDescriptor(String typeDescriptor) {\n        if (typeDescriptor.endsWith(\";\")) {\n            int lastBrace = typeDescriptor.lastIndexOf('[');\n            if (lastBrace < 0) {\n                addClassWithHierachy(typeDescriptor.substring(1, typeDescriptor.length()-1));\n            } else {\n                assert typeDescriptor.length() > lastBrace + 3\n                && typeDescriptor.charAt(lastBrace + 1) == 'L';\n                addClassWithHierachy(typeDescriptor.substring(lastBrace + 2,\n                        typeDescriptor.length() - 1));\n            }\n        }\n    }\n\n    private void addClassWithHierachy(String classBinaryName) {\n        if (classNames.contains(classBinaryName)) {\n            return;\n        }\n\n        try {\n            DirectClassFile classFile = path.getClass(classBinaryName + CLASS_EXTENSION);\n            classNames.add(classBinaryName);\n            CstType superClass = classFile.getSuperclass();\n            if (superClass != null) {\n                addClassWithHierachy(superClass.getClassType().getClassName());\n            }\n\n            TypeList interfaceList = classFile.getInterfaces();\n            int interfaceNumber = interfaceList.size();\n            for (int i = 0; i < interfaceNumber; i++) {\n                addClassWithHierachy(interfaceList.getType(i).getClassName());\n            }\n        } catch (FileNotFoundException e) {\n            // Ignore: The referenced type is not in the path it must be part of the libraries.\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/multidex/FolderPathElement.java",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.multidex;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.InputStream;\nimport java.util.ArrayList;\n\n/**\n * A folder element.\n */\nclass FolderPathElement implements ClassPathElement {\n\n    private File baseFolder;\n\n    public FolderPathElement(File baseFolder) {\n        this.baseFolder = baseFolder;\n    }\n\n    @Override\n    public InputStream open(String path) throws FileNotFoundException {\n        return new FileInputStream(new File(baseFolder,\n                path.replace(SEPARATOR_CHAR, File.separatorChar)));\n    }\n\n    @Override\n    public void close() {\n    }\n\n    @Override\n    public Iterable<String> list() {\n        ArrayList<String> result = new ArrayList<String>();\n        collect(baseFolder, \"\", result);\n        return result;\n    }\n\n    private void collect(File folder, String prefix, ArrayList<String> result) {\n        for (File file : folder.listFiles()) {\n            if (file.isDirectory()) {\n                collect(file, prefix + SEPARATOR_CHAR + file.getName(), result);\n            } else {\n                result.add(prefix + SEPARATOR_CHAR + file.getName());\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/multidex/MainDexListBuilder.java",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.multidex;\n\nimport com.taobao.android.dx.cf.attrib.AttRuntimeVisibleAnnotations;\nimport com.taobao.android.dx.cf.direct.DirectClassFile;\nimport com.taobao.android.dx.cf.iface.Attribute;\nimport com.taobao.android.dx.cf.iface.FieldList;\nimport com.taobao.android.dx.cf.iface.HasAttribute;\nimport com.taobao.android.dx.cf.iface.MethodList;\n\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.zip.ZipFile;\n\n/**\n * This is a command line tool used by mainDexClasses script to build a main dex classes list. First\n * argument of the command line is an archive, each class file contained in this archive is used to\n * identify a class that can be used during secondary dex installation, those class files\n * are not opened by this tool only their names matter. Other arguments must be zip files or\n * directories, they constitute in a classpath in with the classes named by the first argument\n * will be searched. Each searched class must be found. On each of this classes are searched for\n * their dependencies to other classes. The tool also browses for classes annotated by runtime\n * visible annotations and adds them to the list/ Finally the tools prints on standard output a list\n * of class files names suitable as content of the file argument --main-dex-list of dx.\n */\npublic class MainDexListBuilder {\n    private static final String CLASS_EXTENSION = \".class\";\n\n    private static final int STATUS_ERROR = 1;\n\n    private static final String EOL = System.getProperty(\"line.separator\");\n\n    private static String USAGE_MESSAGE =\n            \"Usage:\" + EOL + EOL +\n            \"Short version: Don't use this.\" + EOL + EOL +\n            \"Slightly longer version: This tool is used by mainDexClasses script to build\" + EOL +\n            \"the main dex list.\" + EOL;\n\n    /**\n     * By default we force all classes annotated with runtime annotation to be kept in the\n     * main dex list. This option disable the workaround, limiting the index pressure in the main\n     * dex but exposing to the Dalvik resolution bug. The resolution bug occurs when accessing\n     * annotations of a class that is not in the main dex and one of the annotations as an enum\n     * parameter.\n     *\n     * @see <a href=\"https://code.google.com/p/android/issues/detail?id=78144\">bug discussion</a>\n     *\n     */\n    private static final String DISABLE_ANNOTATION_RESOLUTION_WORKAROUND =\n            \"--disable-annotation-resolution-workaround\";\n\n    private Set<String> filesToKeep = new HashSet<String>();\n\n    public static void main(String[] args) {\n\n        int argIndex = 0;\n        boolean keepAnnotated = true;\n        while (argIndex < args.length -2) {\n            if (args[argIndex].equals(DISABLE_ANNOTATION_RESOLUTION_WORKAROUND)) {\n                keepAnnotated = false;\n            } else {\n                System.err.println(\"Invalid option \" + args[argIndex]);\n                printUsage();\n                System.exit(STATUS_ERROR);\n            }\n            argIndex++;\n        }\n        if (args.length - argIndex != 2) {\n            printUsage();\n            System.exit(STATUS_ERROR);\n        }\n\n        try {\n            MainDexListBuilder builder = new MainDexListBuilder(keepAnnotated, args[argIndex],\n                    args[argIndex + 1]);\n            Set<String> toKeep = builder.getMainDexList();\n            printList(toKeep);\n        } catch (IOException e) {\n            System.err.println(\"A fatal error occured: \" + e.getMessage());\n            System.exit(STATUS_ERROR);\n            return;\n        }\n    }\n\n    public MainDexListBuilder(boolean keepAnnotated, String rootJar, String pathString)\n            throws IOException {\n        ZipFile jarOfRoots = null;\n        Path path = null;\n        try {\n            try {\n                jarOfRoots = new ZipFile(rootJar);\n            } catch (IOException e) {\n                throw new IOException(\"\\\"\" + rootJar + \"\\\" can not be read as a zip archive. (\"\n                        + e.getMessage() + \")\", e);\n            }\n            path = new Path(pathString);\n\n            ClassReferenceListBuilder mainListBuilder = new ClassReferenceListBuilder(path);\n            mainListBuilder.addRoots(jarOfRoots);\n            for (String className : mainListBuilder.getClassNames()) {\n                filesToKeep.add(className + CLASS_EXTENSION);\n            }\n            if (keepAnnotated) {\n                keepAnnotated(path);\n            }\n        } finally {\n            try {\n                jarOfRoots.close();\n            } catch (IOException e) {\n                // ignore\n            }\n            if (path != null) {\n                for (ClassPathElement element : path.elements) {\n                    try {\n                        element.close();\n                    } catch (IOException e) {\n                        // keep going, lets do our best.\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * Returns a list of classes to keep. This can be passed to dx as a file with --main-dex-list.\n     */\n    public Set<String> getMainDexList() {\n        return filesToKeep;\n    }\n\n    private static void printUsage() {\n        System.err.print(USAGE_MESSAGE);\n    }\n\n    private static void printList(Set<String> fileNames) {\n        for (String fileName : fileNames) {\n            System.out.println(fileName);\n        }\n    }\n\n    /**\n     * Keep classes annotated with runtime annotations.\n     */\n    private void keepAnnotated(Path path) throws FileNotFoundException {\n        for (ClassPathElement element : path.getElements()) {\n            forClazz:\n                for (String name : element.list()) {\n                    if (name.endsWith(CLASS_EXTENSION)) {\n                        DirectClassFile clazz = path.getClass(name);\n                        if (hasRuntimeVisibleAnnotation(clazz)) {\n                            filesToKeep.add(name);\n                        } else {\n                            MethodList methods = clazz.getMethods();\n                            for (int i = 0; i<methods.size(); i++) {\n                                if (hasRuntimeVisibleAnnotation(methods.get(i))) {\n                                    filesToKeep.add(name);\n                                    continue forClazz;\n                                }\n                            }\n                            FieldList fields = clazz.getFields();\n                            for (int i = 0; i<fields.size(); i++) {\n                                if (hasRuntimeVisibleAnnotation(fields.get(i))) {\n                                    filesToKeep.add(name);\n                                    continue forClazz;\n                                }\n                            }\n                        }\n                    }\n                }\n        }\n    }\n\n    private boolean hasRuntimeVisibleAnnotation(HasAttribute element) {\n        Attribute att = element.getAttributes().findFirst(\n                AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME);\n        return (att != null && ((AttRuntimeVisibleAnnotations)att).getAnnotations().size()>0);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/multidex/Path.java",
    "content": "/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.android.multidex;\n\nimport com.taobao.android.dx.cf.direct.DirectClassFile;\nimport com.taobao.android.dx.cf.direct.StdAttributeFactory;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.regex.Pattern;\nimport java.util.zip.ZipException;\nimport java.util.zip.ZipFile;\n\nclass Path {\n\n    static ClassPathElement getClassPathElement(File file)\n            throws ZipException, IOException {\n        if (file.isDirectory()) {\n            return new FolderPathElement(file);\n        } else if (file.isFile()) {\n            return new ArchivePathElement(new ZipFile(file));\n        } else if (file.exists()) {\n            throw new IOException(\"\\\"\" + file.getPath() +\n                    \"\\\" is not a directory neither a zip file\");\n        } else {\n            throw new FileNotFoundException(\"File \\\"\" + file.getPath() + \"\\\" not found\");\n        }\n    }\n\n    List<ClassPathElement> elements = new ArrayList<ClassPathElement>();\n    private final String definition;\n    private final ByteArrayOutputStream baos = new ByteArrayOutputStream(40 * 1024);\n    private final byte[] readBuffer = new byte[20 * 1024];\n\n    Path(String definition) throws IOException {\n        this.definition = definition;\n        for (String filePath : definition.split(Pattern.quote(File.pathSeparator))) {\n            try {\n                addElement(getClassPathElement(new File(filePath)));\n            } catch (IOException e) {\n                throw new IOException(\"Wrong classpath: \" + e.getMessage(), e);\n            }\n        }\n    }\n\n    private static byte[] readStream(InputStream in, ByteArrayOutputStream baos, byte[] readBuffer)\n            throws IOException {\n        try {\n            for (;;) {\n                int amt = in.read(readBuffer);\n                if (amt < 0) {\n                    break;\n                }\n\n                baos.write(readBuffer, 0, amt);\n            }\n        } finally {\n            in.close();\n        }\n        return baos.toByteArray();\n    }\n\n    @Override\n    public String toString() {\n        return definition;\n    }\n\n    Iterable<ClassPathElement> getElements() {\n      return elements;\n    }\n\n    private void addElement(ClassPathElement element) {\n        assert element != null;\n        elements.add(element);\n    }\n\n    synchronized DirectClassFile getClass(String path) throws FileNotFoundException {\n        DirectClassFile classFile = null;\n        for (ClassPathElement element : elements) {\n            try {\n                InputStream in = element.open(path);\n                try {\n                    byte[] bytes = readStream(in, baos, readBuffer);\n                    baos.reset();\n                    classFile = new DirectClassFile(bytes, path, false);\n                    classFile.setAttributeFactory(StdAttributeFactory.THE_ONE);\n                    break;\n                } finally {\n                    in.close();\n                }\n            } catch (IOException e) {\n                // search next element\n            }\n        }\n        if (classFile == null) {\n            throw new FileNotFoundException(\"File \\\"\" + path + \"\\\" not found\");\n        }\n        return classFile;\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/object/ApkFileList.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.object;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.google.common.collect.Maps;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * APK文件中的一个文件列表\n * Created by shenghua.nish on 2015-11-03 下午9:09.\n */\npublic class ApkFileList {\n\n    private HashMap<String, String> mainBundle = new HashMap<String, String>();\n    private Map<String, HashMap<String, String>> awbs       = new HashMap<String, HashMap<String, String>>();\n\n    public HashMap<String, String> getMainBundle() {\n        return mainBundle;\n    }\n\n    public void setMainBundle(HashMap<String, String> mainBundle) {\n        this.mainBundle = mainBundle;\n    }\n\n    public String get(String key) {\n        return mainBundle.get(key);\n    }\n\n    public void put(String key, String value) {\n        mainBundle.put(key, value);\n    }\n\n    public void putAll(Map<String, String> map) {\n        mainBundle.putAll(map);\n    }\n\n    public void setAwbs(Map<String, HashMap<String, String>> awbs) {\n        this.awbs = awbs;\n    }\n\n    public Map<String, HashMap<String, String>> getAwbs() {\n        return awbs;\n    }\n\n    public String getAwbFile(String awbName, String key) {\n        if (null == awbs) {\n            return null;\n        }\n        HashMap<String, String> awbInfo = awbs.get(awbName);\n        if (null != awbInfo) {\n            return awbInfo.get(key);\n        }\n        return null;\n    }\n\n    public void addAwb(String awbName, String key, String value) {\n        if (null == awbs) {\n            awbs = new HashMap<String, HashMap<String, String>>();\n        }\n        HashMap<String, String> apkFileList = awbs.get(awbName);\n        if (null == apkFileList) {\n            apkFileList = new HashMap<String, String>();\n        }\n        apkFileList.put(key, value);\n        awbs.put(awbName, apkFileList);\n    }\n\n    public void addAwb(String awbName, Map<String, String> map) {\n        if (null == awbs) {\n            awbs = new HashMap<String, HashMap<String, String>>();\n        }\n        HashMap<String,String> apkFileList = awbs.get(awbName);\n        if (null == apkFileList) {\n            apkFileList = Maps.newHashMap();\n        }\n        apkFileList.putAll(map);\n        awbs.put(awbName, apkFileList);\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/object/ArtifactBundleInfo.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.object;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport java.io.Serializable;\nimport java.util.List;\n\n/**\n * Created by shenghua.nish on 2016-03-20 下午10:05.\n */\npublic class ArtifactBundleInfo implements Serializable{\n\n    private Boolean      mainBundle =false;\n    private String       version;\n    private String       name;\n    private String       pkgName;\n    private String       applicationName;\n    private String       artifactId;\n    private String       baseVersion;\n    private String       depVersions;\n    private String       baseDepVersions;\n\n    public String getUnitTag() {\n        return unitTag;\n    }\n\n    public void setUnitTag(String unitTag) {\n        this.unitTag = unitTag;\n    }\n\n    private String       unitTag;\n\n    public String getSrcUnitTag() {\n        return srcUnitTag;\n    }\n\n    public void setSrcUnitTag(String srcUnitTag) {\n        this.srcUnitTag = srcUnitTag;\n    }\n\n    private String       srcUnitTag;\n    private List<String> dependency;\n    private DiffType     diffType;\n\n    public ArtifactBundleInfo(){\n\n    }\n\n    public ArtifactBundleInfo(Boolean mainBundle, String version, String name, String pkgName, String applicationName,\n                              String artifactId, String baseVersion, String depVersions, String baseDepVersions,\n                              List<String> dependency){\n        this.mainBundle = mainBundle;\n        this.version = version;\n        this.name = name;\n        this.pkgName = pkgName;\n        this.applicationName = applicationName;\n        this.artifactId = artifactId;\n        this.baseVersion = baseVersion;\n        this.depVersions = depVersions;\n        this.baseDepVersions = baseDepVersions;\n        this.dependency = dependency;\n    }\n\n    public Boolean getMainBundle() {\n        return mainBundle;\n    }\n\n    public void setMainBundle(Boolean mainBundle) {\n        this.mainBundle = mainBundle;\n    }\n\n    public String getVersion() {\n        return version;\n    }\n\n    public void setVersion(String version) {\n        this.version = version;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getPkgName() {\n        return pkgName;\n    }\n\n    public void setPkgName(String pkgName) {\n        this.pkgName = pkgName;\n    }\n\n    public String getApplicationName() {\n        return applicationName;\n    }\n\n    public void setApplicationName(String applicationName) {\n        this.applicationName = applicationName;\n    }\n\n    public String getArtifactId() {\n        return artifactId;\n    }\n\n    public void setArtifactId(String artifactId) {\n        this.artifactId = artifactId;\n    }\n\n    public String getBaseVersion() {\n        return baseVersion;\n    }\n\n    public void setBaseVersion(String baseVersion) {\n        this.baseVersion = baseVersion;\n    }\n\n    public String getDepVersions() {\n        return depVersions;\n    }\n\n    public void setDepVersions(String depVersions) {\n        this.depVersions = depVersions;\n    }\n\n    public String getBaseDepVersions() {\n        return baseDepVersions;\n    }\n\n    public void setBaseDepVersions(String baseDepVersions) {\n        this.baseDepVersions = baseDepVersions;\n    }\n\n    public List<String> getDependency() {\n        return dependency;\n    }\n\n    public void setDependency(List<String> dependency) {\n        this.dependency = dependency;\n    }\n\n    public DiffType getDiffType() {\n        return diffType;\n    }\n\n    public void setDiffType(DiffType diffType) {\n        this.diffType = diffType;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        ArtifactBundleInfo that = (ArtifactBundleInfo) o;\n\n        if (version != null ? !version.equals(that.version) : that.version != null) return false;\n        if (name != null ? !name.equals(that.name) : that.name != null) return false;\n        if (applicationName != null ? !applicationName.equals(that.applicationName) : that.applicationName != null)\n            return false;\n        if (artifactId != null ? !artifactId.equals(that.artifactId) : that.artifactId != null) return false;\n        if (baseVersion != null ? !baseVersion.equals(that.baseVersion) : that.baseVersion != null) return false;\n        if (depVersions != null ? !depVersions.equals(that.depVersions) : that.depVersions != null) return false;\n        return !(baseDepVersions != null ? !baseDepVersions.equals(that.baseDepVersions) : that.baseDepVersions != null);\n\n    }\n\n    @Override\n    public int hashCode() {\n        int result = version != null ? version.hashCode() : 0;\n        result = 31 * result + (name != null ? name.hashCode() : 0);\n        result = 31 * result + (applicationName != null ? applicationName.hashCode() : 0);\n        result = 31 * result + (artifactId != null ? artifactId.hashCode() : 0);\n        result = 31 * result + (baseVersion != null ? baseVersion.hashCode() : 0);\n        result = 31 * result + (depVersions != null ? depVersions.hashCode() : 0);\n        result = 31 * result + (baseDepVersions != null ? baseDepVersions.hashCode() : 0);\n        return result;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/object/BuildPatchInfos.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.object;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * 编译生成的patch的信息\n * Created by shenghua.nish on 2015-12-21 下午3:35.\n */\npublic class BuildPatchInfos {\n\n    private String          baseVersion;                         // 容器版本\n    private boolean         diffBundleDex;\n\n    public String getDexcode() {\n        return dexcode;\n    }\n\n    public void setDexcode(String dexcode) {\n        this.dexcode = dexcode;\n    }\n\n    private String          dexcode;\n\n    public boolean isDiffBundleDex() {\n        return diffBundleDex;\n    }\n\n    public void setDiffBundleDex(boolean diffBundleDex) {\n        this.diffBundleDex = diffBundleDex;\n    }\n\n    private List<PatchInfo> patches = new ArrayList<PatchInfo>();\n\n    public String getBaseVersion() {\n        return baseVersion;\n    }\n\n    public void setBaseVersion(String baseVersion) {\n        this.baseVersion = baseVersion;\n    }\n\n    public List<PatchInfo> getPatches() {\n        return patches;\n    }\n\n    public void setPatches(List<PatchInfo> patches) {\n        this.patches = patches;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/object/ClassDiffInfo.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.object;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.google.common.collect.Sets;\n\nimport org.jf.dexlib2.dexbacked.DexBackedClassDef;\n\nimport java.util.Set;\n\n/**\n * Created by shenghua.nish on 2016-03-13 上午10:07.\n */\npublic class ClassDiffInfo {\n\n    private String              name;\n    private DexBackedClassDef classDef;\n    private DiffType            type;\n    private Set<MethodDiffInfo> modifyMethods = Sets.newHashSet();\n    private Set<FieldDiffInfo>  modifyFields  = Sets.newHashSet();\n\n    public DexBackedClassDef getClassDef() {\n        return classDef;\n    }\n\n    public void setClassDef(DexBackedClassDef classDef) {\n        this.classDef = classDef;\n    }\n\n    public DiffType getType() {\n        return type;\n    }\n\n    public void setType(DiffType type) {\n        this.type = type;\n    }\n\n    public Set<MethodDiffInfo> getModifyMethods() {\n        return modifyMethods;\n    }\n\n    public void setModifyMethods(Set<MethodDiffInfo> modifyMethods) {\n        this.modifyMethods = modifyMethods;\n    }\n\n    public Set<FieldDiffInfo> getModifyFields() {\n        return modifyFields;\n    }\n\n    public void setModifyFields(Set<FieldDiffInfo> modifyFields) {\n        this.modifyFields = modifyFields;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/object/DexDiffInfo.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.object;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.alibaba.fastjson.JSON;\nimport com.alibaba.fastjson.JSONArray;\nimport com.alibaba.fastjson.JSONObject;\nimport com.taobao.android.tools.APatchTool;\nimport com.taobao.android.apatch.Build;\nimport com.taobao.android.apatch.utils.Formater;\nimport com.taobao.android.differ.dex.BundleDiffResult;\nimport com.taobao.android.differ.dex.PatchException;\nimport org.apache.commons.io.FileUtils;\nimport org.jf.dexlib2.dexbacked.DexBackedClassDef;\nimport org.jf.dexlib2.dexbacked.DexBackedField;\nimport org.jf.dexlib2.dexbacked.DexBackedMethod;\nimport org.jf.dexlib2.iface.ClassDef;\nimport org.jf.dexlib2.iface.reference.MethodReference;\nimport org.jf.dexlib2.util.ReferenceUtil;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.function.Consumer;\nimport java.util.regex.Pattern;\n\n/**\n * Created by shenghua.nish on 2016-03-13 上午10:02.\n */\npublic class DexDiffInfo {\n\n    private static final Pattern p = Pattern.compile(\"Ljava/lang/|Ljava/util/|Landroid/app/|Landroid/util/\");\n    private Map<DexBackedClassDef,Integer> oldClasses = new ConcurrentHashMap<>();\n    private TreeMap<Integer,Set<? extends ClassDef>>dexs = new TreeMap<>();\n    private Set<DexBackedClassDef> newClasses = Collections.synchronizedSet(new HashSet<DexBackedClassDef>());\n    public static Set<DexBackedClassDef> addedClasses = Collections.synchronizedSet(new HashSet<DexBackedClassDef>());\n    public static Set<DexBackedClassDef> modifiedClasses = Collections.synchronizedSet(new HashSet<DexBackedClassDef>());\n    private Set<DexBackedField> addedFields = Collections.synchronizedSet(new HashSet<DexBackedField>());\n    private Set<DexBackedField> modifiedFields = Collections.synchronizedSet(new HashSet<DexBackedField>());\n    public static Set<DexBackedMethod> addedMethods = Collections.synchronizedSet(new HashSet<DexBackedMethod>());\n    public static Set<DexBackedMethod> modifiedMethods = Collections.synchronizedSet(new HashSet<DexBackedMethod>());\n    private Map<String, ClassDiffInfo> classDiffInfoMap = new HashMap<String, ClassDiffInfo>();\n    private Set<String> usedMethods = Collections.synchronizedSet(new HashSet<String>());\n\n    public DexDiffInfo() {\n\n    }\n\n    public Map<String, ClassDiffInfo> getClassDiffInfoMap() {\n        return classDiffInfoMap;\n    }\n\n    public Set<DexBackedClassDef> getModifiedClasses() {\n        return modifiedClasses;\n    }\n\n    public void setAddedClasses(ClassDef classDef){\n        if (!addedClasses.contains(classDef)){\n            addedClasses.add((DexBackedClassDef) classDef);\n        }\n    }\n\n\n    public Set<DexBackedClassDef> getAddedClasses(){\n        return addedClasses;\n    }\n\n    public Set<DexBackedMethod> getModifiedMethods() {\n        return modifiedMethods;\n    }\n\n    public Set<DexBackedMethod> getAddedMethods() {\n        return addedMethods;\n    }\n\n    public static DexBackedClassDef getModifiedClasses(String clazz) {\n        for (DexBackedClassDef classDef : modifiedClasses) {\n            if (classDef.getType().equals(clazz)) {\n                return classDef;\n            }\n        }\n        return null;\n    }\n\n\n    public void addModifiedMethods(DexBackedMethod method) throws PatchException {\n        System.out.println(\"add modified Method:\" + method.getReturnType()\n                + \"  \" + method.getName() + \"(\"\n                + Formater.formatStringList(method.getParameterTypes())\n                + \")  in Class:\" + method.getDefiningClass());\n        this.modifiedMethods.add(method);\n\n        if (!modifiedClasses.contains(method.classDef)) {\n            modifiedClasses.add(method.classDef);\n            String className = method.classDef.getType();\n            addManifestModifiedClass(className);\n        }\n    }\n\n\n    private void addManifestModifiedClass(String className) {\n        Build.modifiedClasses.add(className.substring(1, className.length() - 1).replace('/', '.'));\n        System.out.println(\"addModifiedClass: \" + className.substring(1, className.length() - 1).replace('/', '.'));\n    }\n\n\n    public void addManifestAddClass(String className) {\n        Build.addClasses.add(className.substring(1, className.length() - 1).replace('/', '.'));\n        System.out.println(\"addClass: \" + className.substring(1, className.length() - 1).replace('/', '.'));\n    }\n\n\n    public static void addUsedMethods(MethodReference methodReference) {\n        String className = methodReference.getDefiningClass();\n//        if (Build.addClasses.contains(className.substring(1, className.length() - 1).replace('/', '.'))){\n//            return;\n//        }\n        String method = methodReference.getName();\n        String params;\n        if (APatchTool.mappingMap == null) {\n            params = methodReference.getParameterTypes().toString().replace(',', '|').replaceAll(\" \", \"\");\n        } else {\n            params = getParamsType(methodReference.getParameterTypes());\n        }\n\n\n        System.out.println(\"add used method:\" + className + \"->\" + method + \":\" + params\n                + \" \" + methodReference.getReturnType());\n\n        String record = className.substring(1, className.length() - 1).replace('/', '.') + \":\" +\n                method + \":\" + params + \":\" + methodReference.getReturnType();\n        if (Build.usedMethods.contains(record)) {\n            return;\n        }\n        if (p.matcher(className).find()) {\n            return;\n        }\n        Build.usedMethods.add(record);\n    }\n\n    private static String getParamsType(List<? extends CharSequence> parameterTypes) {\n        StringBuilder params = new StringBuilder();\n        for (CharSequence charSequence : parameterTypes) {\n            boolean isArray = false;\n            String s = null;\n            if (charSequence.toString().startsWith(\"[\")) {\n                s = charSequence.subSequence(1, charSequence.length()).toString();\n                isArray = true;\n            } else {\n                s = charSequence.toString();\n            }\n            if (!APatchTool.mappingMap.containsValue(s)) {\n                params.append(isArray ? \"[\" + s + \"|\" : s + \"|\");\n                continue;\n            } else {\n                for (Map.Entry<String, String> entry : APatchTool.mappingMap.entrySet()) {\n                    if (entry.getValue().equals(charSequence.toString())) {\n                        params.append(isArray ? \"[\" + entry.getKey() + \"|\" : entry.getKey() + \"|\");\n                    }\n                }\n\n            }\n        }\n        if (params.length() > 1) {\n            return \"[\" + params.substring(0, params.length() - 1).toString() + \"]\";\n        }else {\n            return \"[\" + params.toString() +\"]\";\n        }\n    }\n\n    public static void addUsedClass(String className) {\n//        if (Build.addClasses.contains(className.substring(1, className.length() - 1).replace('/', '.'))){\n//            return;\n//        }\n        if (className == null || className.length() <= 3) {\n            return;\n        }\n        String clazz = className;\n        if (clazz.charAt(0) == '[') {\n            clazz = clazz.substring(1);\n        }\n        if (p.matcher(className).find()) {\n            return;\n        }\n\n        Build.usedClasses.add(clazz.substring(1, clazz.length() - 1).replace('/', '.'));\n    }\n\n\n    /**\n     * 将变动的信息写入到一个文件\n     *\n     * @param append\n     * @param outFile\n     */\n    public void save(BundleDiffResult bundleDiffResult) throws IOException {\n            List<BundleDiffResult.ClassDiff>classDiffs = new ArrayList<>();\n            for (ClassDiffInfo classDiffInfo:classDiffInfoMap.values()){\n                BundleDiffResult.ClassDiff classDiff = new BundleDiffResult.ClassDiff();\n                classDiff.setClassName(classDiffInfo.getName());\n                classDiff.setDiffType(classDiffInfo.getType());\n                classDiffs.add(classDiff);\n                if (classDiffInfo.getModifyFields().size() > 0){\n                    List<BundleDiffResult.FieldDiff>fieldDiffs = new ArrayList<>();\n                    for (FieldDiffInfo fieldDiffInfo:classDiffInfo.getModifyFields()) {\n                        BundleDiffResult.FieldDiff fieldDiff = new BundleDiffResult.FieldDiff();\n                        fieldDiffs.add(fieldDiff);\n                        fieldDiff.setDiffType(fieldDiffInfo.getType());\n                        fieldDiff.setFieldDesc(ReferenceUtil.getFieldDescriptor(fieldDiffInfo.getBackedField()));\n                    }\n                    classDiff.setFieldDiffs(fieldDiffs);\n                }\n                if (classDiffInfo.getModifyMethods().size() > 0){\n                    List<BundleDiffResult.MethodDiff>methodDiffs = new ArrayList<>();\n                    for (MethodDiffInfo methodDiffInfo:classDiffInfo.getModifyMethods()) {\n                        BundleDiffResult.MethodDiff methodDiff = new BundleDiffResult.MethodDiff();\n                        methodDiffs.add(methodDiff);\n                        methodDiff.setDiffType(methodDiffInfo.getType());\n                        methodDiff.setMethodDesc(ReferenceUtil.getMethodDescriptor(methodDiffInfo.getBackedMethod()));\n                    }\n                    classDiff.setMethodDiffs(methodDiffs);\n                }\n            }\n\n        bundleDiffResult.setClassDiffs(classDiffs);\n    }\n\n    public void writeToFile(String bundleName, File diffFile, File diffJsonFile) throws IOException {\n        JSONArray jsonArray = new JSONArray();\n        if (diffJsonFile.exists()) {\n            String content = FileUtils.readFileToString(diffJsonFile);\n            jsonArray = JSONArray.parseArray(content);\n        }\n        JSONObject jsonObject = new JSONObject();\n        jsonObject.put(\"bundleName\", bundleName);\n        if (addedMethods.size() > 0) {\n            List<String> addMethods = new ArrayList<String>();\n            List<MethodDiffInfoObject> diffInfoObjects = new ArrayList<MethodDiffInfoObject>();\n            for (DexBackedMethod method : addedMethods) {\n                addMethods.add(\"[add new Method:]\" + method.getReturnType()\n                        + \"  \" + method.getName() + \"(\"\n                        + Formater.formatStringList(method.getParameterTypes())\n                        + \")  in Class:\" + method.getDefiningClass());\n                MethodDiffInfoObject diffInfoObject = new MethodDiffInfoObject();\n                diffInfoObject.setDiffType(DiffType.ADD);\n                diffInfoObject.setReturnType(method.getReturnType());\n                diffInfoObject.setMethodDeclaration(method.getName() + \"(\"\n                        + Formater.formatStringList(method.getParameterTypes())\n                        + \")\");\n                diffInfoObject.setInClass(method.getDefiningClass());\n                diffInfoObjects.add(diffInfoObject);\n            }\n            FileUtils.writeLines(diffFile, addMethods, true);\n            jsonObject.put(\"addedMethods\", diffInfoObjects);\n        }\n        if (modifiedMethods.size() > 0) {\n            List<String> modifyMethods = new ArrayList<String>();\n            List<MethodDiffInfoObject> diffInfoObjects = new ArrayList<MethodDiffInfoObject>();\n\n            for (DexBackedMethod method : modifiedMethods) {\n                modifyMethods.add(\"[modify Method:]\" + method.getReturnType()\n                        + \"  \" + method.getName() + \"(\"\n                        + Formater.formatStringList(method.getParameterTypes())\n                        + \")  in Class:\" + method.getDefiningClass());\n                MethodDiffInfoObject diffInfoObject = new MethodDiffInfoObject();\n                diffInfoObject.setDiffType(DiffType.MODIFY);\n                diffInfoObject.setReturnType(method.getReturnType());\n                diffInfoObject.setMethodDeclaration(method.getName() + \"(\"\n                        + Formater.formatStringList(method.getParameterTypes())\n                        + \")\");\n                diffInfoObject.setInClass(method.getDefiningClass());\n                diffInfoObjects.add(diffInfoObject);\n            }\n            FileUtils.writeLines(diffFile, modifyMethods, true);\n            jsonObject.put(\"modifiedMethods\", diffInfoObjects);\n        }\n        jsonArray.add(jsonObject);\n        FileUtils.writeStringToFile(diffJsonFile, JSON.toJSONString(jsonArray));\n    }\n\n    public Map<DexBackedClassDef,Integer> getOldClasses() {\n        return oldClasses;\n    }\n\n    public Set<DexBackedClassDef> getNewClasses() {\n        return newClasses;\n    }\n\n\n    public void setNewClasses(Set<? extends DexBackedClassDef> newClasses) {\n        this.newClasses.addAll(newClasses);\n    }\n\n    public static void release() {\n        modifiedClasses.clear();\n        addedMethods.clear();\n        modifiedMethods.clear();\n        addedClasses.clear();\n    }\n\n\n    public void update() throws PatchException {\n        if (classDiffInfoMap.size() > 0) {\n            for (ClassDiffInfo classDiffInfo : classDiffInfoMap.values()) {\n                for (MethodDiffInfo methodDiffInfo : classDiffInfo.getModifyMethods()) {\n                    if (methodDiffInfo.getType().equals(DiffType.MODIFY)) {\n                        addModifiedMethods(methodDiffInfo.getBackedMethod());\n                    }\n                }\n                if (classDiffInfo.getType().equals(DiffType.ADD)) {\n                    setAddedClasses(classDiffInfo.getClassDef());\n                    addManifestAddClass(classDiffInfo.getClassDef().getType());\n                }\n            }\n        }\n    }\n\n    public void setOldClasses(String dexNum, Set<? extends DexBackedClassDef> baseClassDefs) {\n        baseClassDefs.forEach(new Consumer<DexBackedClassDef>() {\n            @Override\n            public void accept(DexBackedClassDef dexBackedClassDef) {\n                oldClasses.put(dexBackedClassDef,Integer.valueOf(dexNum));\n            }\n        });\n\n    }\n\n    public Integer getBaseClassDefNum(ClassDef classDef){\n       return oldClasses.get(classDef);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/object/DiffType.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.object;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\n/**\n * Created by shenghua.nish on 2015-09-30 下午4:40.\n */\npublic enum DiffType {\n    ADD, MODIFY ,REMOVE, NONE,OVERRIDE;\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/object/FieldDiffInfo.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.object;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport org.jf.dexlib2.dexbacked.DexBackedField;\n\n/**\n * Created by shenghua.nish on 2016-03-13 上午10:06.\n */\npublic class FieldDiffInfo {\n    private DexBackedField backedField;\n    private DiffType        type;\n\n    public DexBackedField getBackedField() {\n        return backedField;\n    }\n\n    public void setBackedField(DexBackedField backedField) {\n        this.backedField = backedField;\n    }\n\n    public DiffType getType() {\n        return type;\n    }\n\n    public void setType(DiffType type) {\n        this.type = type;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/object/FieldObject.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.object;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.google.common.collect.ImmutableSet;\n\nimport org.jf.dexlib2.iface.Annotation;\nimport org.jf.dexlib2.iface.value.EncodedValue;\nimport org.jf.dexlib2.immutable.ImmutableAnnotation;\nimport org.jf.dexlib2.immutable.ImmutableField;\n\nimport java.util.Set;\n\n/**\n * Created by lilong on 16/6/18.\n */\npublic class FieldObject {\n\n    private String definingClass;\n    private String fieldName;\n    private String valueType;\n    private int accessFlags;\n    private EncodedValue initialValue;\n    private Set<? extends Annotation>annotations;\n\n    public FieldObject(String definingClass,String fieldName, String valueType, int accessFlags, EncodedValue initialValue,ImmutableSet<? extends ImmutableAnnotation>annotations) {\n        this.definingClass= definingClass;\n        this.fieldName = fieldName;\n        this.valueType = valueType;\n        this.accessFlags = accessFlags;\n        this.initialValue = initialValue;\n        this.annotations = annotations;\n    }\n\n    public ImmutableField build(){\n        return new ImmutableField(definingClass,fieldName,valueType,accessFlags,initialValue,annotations);\n\n    }\n\n    public static ImmutableField of(ImmutableField field){\n       return ImmutableField.of(field);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/object/MethodDiffInfo.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.object;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport org.jf.dexlib2.dexbacked.DexBackedMethod;\n\n/**\n * Created by shenghua.nish on 2016-03-13 上午10:06.\n */\npublic class MethodDiffInfo {\n\n    private DexBackedMethod backedMethod;\n    private DiffType        type;\n\n    public DexBackedMethod getBackedMethod() {\n        return backedMethod;\n    }\n\n    public void setBackedMethod(DexBackedMethod backedMethod) {\n        this.backedMethod = backedMethod;\n    }\n\n    public DiffType getType() {\n        return type;\n    }\n\n    public void setType(DiffType type) {\n        this.type = type;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/object/MethodDiffInfoObject.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.object;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\n/**\n * Created by zhongyu.hn on 16/4/28.\n */\npublic class MethodDiffInfoObject {\n    private DiffType diffType;\n    private String methodDeclaration;\n    private String returnType;\n    private String inClass;\n\n    public DiffType getDiffType() {\n        return diffType;\n    }\n\n    public void setDiffType(DiffType diffType) {\n        this.diffType = diffType;\n    }\n\n    public String getMethodDeclaration() {\n        return methodDeclaration;\n    }\n\n    public void setMethodDeclaration(String methodDeclaration) {\n        this.methodDeclaration = methodDeclaration;\n    }\n\n    public String getReturnType() {\n        return returnType;\n    }\n\n    public void setReturnType(String returnType) {\n        this.returnType = returnType;\n    }\n\n    public String getInClass() {\n        return inClass;\n    }\n\n    public void setInClass(String inClass) {\n        this.inClass = inClass;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/object/MethodObject.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.object;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\n/**\n * Created by lilong on 16/6/18.\n */\npublic class MethodObject {\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/object/PatchBundleInfo.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.object;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport java.util.List;\n\n/**\n * Created by shenghua.nish on 2016-03-18 下午10:59.\n */\npublic class PatchBundleInfo {\n\n    private Boolean mainBundle;\n    private Boolean newBundle;\n    private String  version;\n    private String  name;\n    private String  pkgName;\n    private String  applicationName;\n    private String  artifactId;\n    private String baseVersion;\n\n    public int getPatchType() {\n        return patchType;\n    }\n\n    public void setPatchType(int patchType) {\n        this.patchType = patchType;\n    }\n\n    private int patchType = 0;\n\n    public boolean isInherit() {\n        return inherit;\n    }\n\n    public void setInherit(boolean inherit) {\n        this.inherit = inherit;\n    }\n\n    private boolean inherit;\n\n    public boolean isReset() {\n        return reset;\n    }\n\n    public void setReset(boolean reset) {\n        this.reset = reset;\n    }\n\n    boolean reset;\n\n    public String getUnitTag() {\n        return unitTag;\n    }\n\n    public void setUnitTag(String unitTag) {\n        this.unitTag = unitTag;\n    }\n\n    private String unitTag;\n\n    public String getSrcUnitTag() {\n        return srcUnitTag;\n    }\n\n    public void setSrcUnitTag(String srcUnitTag) {\n        this.srcUnitTag = srcUnitTag;\n    }\n\n    private String srcUnitTag;\n\n    public String getBaseVersion() {\n        return baseVersion;\n    }\n\n    public void setBaseVersion(String baseVersion) {\n        this.baseVersion = baseVersion;\n    }\n\n    public List<String> getDependency() {\n        return dependency;\n    }\n\n    public void setDependency(List<String> dependency) {\n        this.dependency = dependency;\n    }\n\n    private List<String>  dependency;\n\n    public PatchBundleInfo(){\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public Boolean getMainBundle() {\n        return mainBundle;\n    }\n\n    public void setMainBundle(Boolean mainBundle) {\n        this.mainBundle = mainBundle;\n    }\n\n    public String getVersion() {\n        return version;\n    }\n\n    public void setVersion(String version) {\n        this.version = version;\n    }\n\n    public Boolean getNewBundle() {\n        return newBundle;\n    }\n\n    public void setNewBundle(Boolean newBundle) {\n        this.newBundle = newBundle;\n    }\n\n    public String getPkgName() {\n        return pkgName;\n    }\n\n    public void setPkgName(String pkgName) {\n        this.pkgName = pkgName;\n    }\n\n    public String getApplicationName() {\n        return applicationName;\n    }\n\n    public void setApplicationName(String applicationName) {\n        this.applicationName = applicationName;\n    }\n\n    public String getArtifactId() {\n        return artifactId;\n    }\n\n    public void setArtifactId(String artifactId) {\n        this.artifactId = artifactId;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/object/PatchInfo.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.object;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class PatchInfo {\n\n    private String                patchVersion;                              // patch后的版本号\n    private String                targetVersion;                             // 目标的生效版本\n    private List<PatchBundleInfo> bundles = new ArrayList<PatchBundleInfo>();\n    private String                fileName;\n    private String                md5;\n    private Long                  size;\n    private String                downloadUrl;\n\n    public String getPatchVersion() {\n        return patchVersion;\n    }\n\n    public void setPatchVersion(String patchVersion) {\n        this.patchVersion = patchVersion;\n    }\n\n    public String getTargetVersion() {\n        return targetVersion;\n    }\n\n    public void setTargetVersion(String targetVersion) {\n        this.targetVersion = targetVersion;\n    }\n\n    public List<PatchBundleInfo> getBundles() {\n        return bundles;\n    }\n\n    public void setBundles(List<PatchBundleInfo> bundles) {\n        this.bundles = bundles;\n    }\n\n    public String getFileName() {\n        return fileName;\n    }\n\n    public void setFileName(String fileName) {\n        this.fileName = fileName;\n    }\n\n    public String getMd5() {\n        return md5;\n    }\n\n    public void setMd5(String md5) {\n        this.md5 = md5;\n    }\n\n    public Long getSize() {\n        return size;\n    }\n\n    public void setSize(Long size) {\n        this.size = size;\n    }\n\n    public String getDownloadUrl() {\n        return downloadUrl;\n    }\n\n    public void setDownloadUrl(String downloadUrl) {\n        this.downloadUrl = downloadUrl;\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/object/SoFileDef.java",
    "content": "package com.taobao.android.object;\n\nimport com.taobao.android.tpatch.utils.MD5Util;\n\nimport java.io.File;\nimport java.io.IOException;\n\n/**\n * SoFileDef\n *\n * @author zhayu.ll\n * @date 18/4/25\n */\npublic class SoFileDef {\n    public File baseSoFile;\n    public File newSoFile;\n    public File patchFile;\n    public String relativePath;\n\n    public SoFileDef(File baseSoFile, File newSoFile, File patchFile,String relativePath) {\n        this.baseSoFile = baseSoFile;\n        this.newSoFile = newSoFile;\n        this.patchFile = patchFile;\n        this.relativePath = relativePath;\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/outputs/APatchFile.java",
    "content": "package com.taobao.android.outputs;\n\nimport java.io.File;\n\n/**\n * @author lilong\n * @create 2017-11-02 下午11:42\n */\n\npublic class APatchFile extends PatchFile {\n\n        public File aDiffText;\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/outputs/DexPatchFile.java",
    "content": "package com.taobao.android.outputs;\n\n/**\n * @author lilong\n * @create 2017-11-02 下午11:49\n */\n\npublic class DexPatchFile extends TpatchFile {\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/outputs/PatchFile.java",
    "content": "package com.taobao.android.outputs;\n\nimport java.io.File;\n\n/**\n * @author lilong\n * @create 2017-11-02 下午11:41\n */\n\npublic class PatchFile {\n\n    public File patchFile;\n\n    public File diffJson;\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/outputs/TpatchFile.java",
    "content": "package com.taobao.android.outputs;\n\nimport java.io.File;\nimport java.util.List;\n\n/**\n * @author lilong\n * @create 2017-11-02 下午11:45\n */\n\npublic class TpatchFile extends PatchFile {\n\n    public File patchsJson;\n\n    public List<File>updateJsons;\n\n    public File patchInfo;\n\n    public File patchChecker;\n\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/reader/AtlasFrameworkPropertiesReader.java",
    "content": "package com.taobao.android.reader;\n\nimport org.jf.dexlib2.iface.Method;\nimport org.jf.dexlib2.iface.instruction.Instruction;\nimport org.jf.dexlib2.iface.instruction.ReferenceInstruction;\nimport org.jf.dexlib2.iface.reference.StringReference;\n\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\n/**\n * @author lilong\n * @create 2017-08-15 下午1:26\n */\n\npublic class AtlasFrameworkPropertiesReader implements Reader {\n    private Reader reader;\n    private Map map;\n\n    public AtlasFrameworkPropertiesReader(Reader reader,LinkedHashMap map) {\n            this.reader = reader;\n            this.map = map;\n    }\n    public LinkedHashMap<String,BundleListing.BundleInfo>read(String className,String memberName) throws Exception {\n\n        if (reader!= null) {\n            Method method = (Method) reader.read(className, memberName);\n            if (method!= null){\n                Iterable<? extends Instruction> instructions = method.getImplementation().getInstructions();\n                for (Instruction instruction:instructions){\n                    if (instruction instanceof ReferenceInstruction){\n                        if (((ReferenceInstruction) instruction).getReferenceType()== 0){\n                            StringReference s = (StringReference) ((ReferenceInstruction) instruction).getReference();\n                            return BundleListingUtil.parseArray(s.getString(), (LinkedHashMap<String, BundleListing.BundleInfo>) map);\n                        }\n                    }\n                }\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/reader/BundleListing.java",
    "content": "package com.taobao.android.reader;\n\nimport java.io.Serializable;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.List;\n\n/**\n * @author lilong\n * @create 2017-08-15 下午1:40\n */\n\npublic class BundleListing implements Serializable {\n\n    private LinkedHashMap<String, BundleInfo> bundles = new LinkedHashMap<String, BundleInfo>();\n\n    public LinkedHashMap<String, BundleInfo> getBundles() {\n        return bundles;\n    }\n\n    public void setBundles(LinkedHashMap<String, BundleInfo> bundles) {\n        this.bundles = bundles;\n    }\n\n\n    public static class BundleInfo {\n        private String name;\n        private String pkgName;\n        private String applicationName;\n        private String version;\n        private String desc;\n        private String url;\n        private String md5;\n        private boolean isInternal = true;\n        private List<String> dependency;\n        private List<String> totalDependency;\n        private HashMap<String, Boolean> activities;\n        private HashMap<String, Boolean> services;\n        private HashMap<String, Boolean> receivers;\n        private HashMap<String, Boolean> contentProviders;\n        private String unique_tag;\n\n        public String getCurrent_unique_tag() {\n            return current_unique_tag;\n        }\n\n        public void setCurrent_unique_tag(String current_unique_tag) {\n            this.current_unique_tag = current_unique_tag;\n        }\n\n        private String current_unique_tag;\n        private long size;\n\n        public long getSize() {\n            return size;\n        }\n\n        public void setSize(long size) {\n            this.size = size;\n        }\n\n        public boolean isInternal() {\n            return isInternal;\n        }\n\n        public void setIsInternal(boolean isInternal) {\n            this.isInternal = isInternal;\n        }\n\n        public String getApplicationName() {\n            return applicationName;\n        }\n\n        public void setApplicationName(String applicationName) {\n            this.applicationName = applicationName;\n        }\n\n        public HashMap<String, Boolean> getReceivers() {\n            return receivers;\n        }\n\n        public void setReceivers(HashMap<String, Boolean> receivers) {\n            this.receivers = receivers;\n        }\n\n        public HashMap<String, Boolean> getContentProviders() {\n            return contentProviders;\n        }\n\n        public void setContentProviders(HashMap<String, Boolean> contentProviders) {\n            this.contentProviders = contentProviders;\n        }\n\n        public String getUnique_tag() {\n            return unique_tag;\n        }\n\n        public void setUnique_tag(String unique_tag) {\n            this.unique_tag = unique_tag;\n        }\n\n        public String getMd5() {\n            return md5;\n        }\n\n        public void setMd5(String md5) {\n            this.md5 = md5;\n        }\n\n        public String getUrl() {\n            return url;\n        }\n\n        public void setUrl(String url) {\n            this.url = url;\n        }\n\n        public String getDesc() {\n            return desc;\n        }\n\n        public void setDesc(String desc) {\n            this.desc = desc;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public String getPkgName() {\n            return pkgName;\n        }\n\n        public void setPkgName(String pkgName) {\n            this.pkgName = pkgName;\n        }\n\n        public String getVersion() {\n            return version;\n        }\n\n        public void setVersion(String version) {\n            this.version = version;\n        }\n\n        public HashMap<String, Boolean> getActivities() {\n            return activities;\n        }\n\n        public void setActivities(HashMap<String, Boolean> activities) {\n            this.activities = activities;\n        }\n\n        public HashMap<String, Boolean> getServices() {\n            return services;\n        }\n\n        public void setServices(HashMap<String, Boolean> services) {\n            this.services = services;\n        }\n\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/reader/BundleListingUtil.java",
    "content": "package com.taobao.android.reader;\n\nimport com.alibaba.fastjson.JSON;\nimport com.alibaba.fastjson.JSONArray;\nimport com.alibaba.fastjson.JSONObject;\nimport org.apache.commons.lang3.StringUtils;\n\nimport java.io.IOException;\nimport java.util.LinkedHashMap;\n\n/**\n * @author lilong\n * @create 2017-08-15 下午1:43\n */\n\npublic class BundleListingUtil {\n\n    public static LinkedHashMap<String,BundleListing.BundleInfo> parseArray(String listingStr,LinkedHashMap<String,BundleListing.BundleInfo>currentBundleInfo) throws Exception{\n        LinkedHashMap<String,BundleListing.BundleInfo> infos= new LinkedHashMap<>();\n        JSONArray array = JSON.parseArray(listingStr);\n        for(int x=0; x<array.size(); x++){\n            JSONObject object = array.getJSONObject(x);\n            BundleListing.BundleInfo info = new BundleListing.BundleInfo();\n            info.setName(object.getString(\"name\"));\n            info.setPkgName(object.getString(\"pkgName\"));\n            info.setApplicationName(object.getString(\"applicationName\"));\n            info.setVersion(object.getString(\"version\"));\n            info.setDesc(object.getString(\"desc\"));\n            info.setUrl(object.getString(\"url\"));\n            info.setMd5(object.getString(\"md5\"));\n            String uniqueTag = object.getString(\"unique_tag\");\n            if(StringUtils.isEmpty(uniqueTag)){\n                throw new IOException(\"uniqueTag is empty\");\n            }\n            info.setUnique_tag(object.getString(\"unique_tag\"));\n            if (currentBundleInfo==null) {\n                info.setCurrent_unique_tag(info.getUnique_tag());\n            }else {\n                if (currentBundleInfo.get(info.getPkgName())!= null){\n                    info.setCurrent_unique_tag(currentBundleInfo.get(info.getPkgName()).getUnique_tag());\n                }\n            }\n\n            infos.put(info.getPkgName(),info);\n\n        }\n        return infos.size()>0 ? infos : null;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/reader/ClassReader.java",
    "content": "package com.taobao.android.reader;\n\nimport org.jf.dexlib2.iface.ClassDef;\n\nimport java.util.Set;\n\n/**\n * @author lilong\n * @create 2017-08-15 下午1:52\n */\n\npublic class ClassReader implements Reader {\n    private Set<ClassDef>classDefs;\n\n    public ClassReader(Reader reader) throws Exception {\n        if (reader!= null && reader instanceof DexReader){\n            classDefs = (Set<ClassDef>) reader.read(null,null);\n        }\n    }\n    public ClassDef read(String className,String memberName){\n        if (classDefs == null){\n            return null;\n        }\n        for (ClassDef classDef:classDefs){\n            if (classDef.getType().equals(className)){\n                return classDef;\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/reader/DexReader.java",
    "content": "package com.taobao.android.reader;\n\nimport org.jf.dexlib2.DexFileFactory;\nimport org.jf.dexlib2.Opcodes;\nimport org.jf.dexlib2.iface.DexFile;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.List;\n\n/**\n * @author lilong\n * @create 2017-08-15 下午1:47\n */\n\npublic class DexReader implements Reader {\n    protected Collection classDefs = new HashSet();\n\n    public DexReader(File file) throws IOException {\n        if (file.exists()){\n            org.jf.dexlib2.iface.DexFile dexFile = DexFileFactory.loadDexFile(file,Opcodes.getDefault());\n            this.classDefs = dexFile.getClasses();\n        }\n    }\n    public DexReader(List<File>files) throws IOException {\n        for (File file:files){\n            DexFile dexFile =DexFileFactory.loadDexFile(file, Opcodes.getDefault());\n            classDefs.addAll(dexFile.getClasses());\n        }\n    }\n\n    @Override\n    public Collection read(String name,String memberName) {\n        return classDefs;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/reader/FieldReader.java",
    "content": "package com.taobao.android.reader;\n\n\nimport org.jf.dexlib2.iface.ClassDef;\nimport org.jf.dexlib2.iface.Field;\n\n/**\n * @author lilong\n * @create 2017-08-15 下午1:18\n */\n\npublic class FieldReader implements Reader{\n    private ClassDef classDef;\n    private Reader reader;\n\n    public FieldReader(Reader reader)throws Exception {\n           if (reader instanceof ClassReader){\n               this.reader = reader;\n           }\n    }\n    public Field read(String className,String member) throws Exception {\n        if (reader == null){\n            return null;\n        }\n        classDef = (ClassDef) reader.read(className,null);\n        Iterable<? extends Field> fields = classDef.getFields();\n        for (Field field:fields){\n            if (field.getName().equals(member)){\n                return field;\n            }\n        }\n    return null;\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/reader/MethodReader.java",
    "content": "package com.taobao.android.reader;\nimport org.jf.dexlib2.iface.Method;\n\n/**\n * @author lilong\n * @create 2017-08-15 下午4:35\n */\n\npublic class MethodReader implements Reader {\n\n    private Reader reader;\n\n    public MethodReader(Reader reader) {\n        if (reader!= null){\n            this.reader = reader;\n        }\n    }\n\n    @Override\n    public Method read(String className, String member) throws Exception {\n        org.jf.dexlib2.iface.ClassDef classDef = (org.jf.dexlib2.iface.ClassDef) reader.read(className,null);\n        for(Method method:classDef.getMethods()){\n            if (method.getName().equals(member)){\n                return method;\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/reader/Reader.java",
    "content": "package com.taobao.android.reader;\n\n/**\n * @author lilong\n * @create 2017-08-15 下午1:24\n */\n\npublic interface Reader<T> {\n\n    public T read(String className,String member) throws Exception;\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/repatch/AbIClassDef.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.repatch;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport org.jf.dexlib2.iface.Annotation;\nimport org.jf.dexlib2.iface.ClassDef;\nimport org.jf.dexlib2.iface.Field;\nimport org.jf.dexlib2.iface.Method;\nimport org.jf.dexlib2.immutable.ImmutableClassDef;\n\nimport java.util.*;\n\n/**\n * Created by lilong on 16/7/1.\n */\npublic abstract class AbIClassDef implements IClassDef {\n\n    protected static Map<String,String> basicType = new HashMap<String, String>();\n    protected static List<String>basicValue = Arrays.asList(new String[]{\"<\",\">;\",\"()\",\"Ljava/util/\",\"<*>\",\"Ljava/lang/\",\"[Ljava/util/\",\"[Ljava/lang/\"});\n\n    static {\n        basicType.put(\"Z\",\"boolean\");\n        basicType.put(\"B\",\"byte\");\n        basicType.put(\"S\",\"short\");\n        basicType.put(\"C\",\"char\");\n        basicType.put(\"I\",\"int\");\n        basicType.put(\"J\",\"long\");\n        basicType.put(\"F\",\"float\");\n        basicType.put(\"D\",\"double\");\n        basicType.put(\"V\",\"void\");\n        basicType.put(\"[D\",\"double[]\");\n        basicType.put(\"[F\",\"float[]\");\n        basicType.put(\"[J\",\"long[]\");\n        basicType.put(\"[I\",\"int[]\");\n        basicType.put(\"[C\",\"char[]\");\n        basicType.put(\"[S\",\"short[]\");\n        basicType.put(\"[B\",\"byte[]\");\n        basicType.put(\"[Z\",\"boolean[]\");\n        basicType.put(\"[V\",\"void[]\");\n\n\n\n    }\n\n    protected String reType = null;\n\n    @Override\n    public ClassDef reClassDef(ClassDef classDef) {\n        Iterable<? extends Method> methods = classDef.getMethods();\n        LinkedHashSet<Method> newMethods = new LinkedHashSet<Method>();\n        Iterable<? extends Field> fields = classDef.getFields();\n        LinkedHashSet<Field>newFields = new LinkedHashSet<Field>();\n        Set<? extends Annotation> annotations = classDef.getAnnotations();\n        List<String>interfaces = classDef.getInterfaces();\n        Set<String>newInterfaces = new HashSet<String>();\n        Set<Annotation>immutableAnnotations = new HashSet<Annotation>();\n        String type = classDef.getType();\n        reType = reType(type);\n        String superClass = classDef.getSuperclass();\n        for (String inter:interfaces){\n            newInterfaces.add(reInterface(inter));\n        }\n        String reSuperClass = reSuperClass(superClass);\n        for (Annotation annotation:annotations){\n\n            immutableAnnotations.add(reAnnotation(annotation));\n        }\n        for (Field field:fields){\n            newFields.add(reField(field));\n        }\n        for (Method method:methods){\n            if (method.getName().equals(\"<cinit>\")||method.getName().equals(\"<init>\")){\n               newMethods.add(reMethod(method));\n                continue;\n            }\n//            if (method.getName().equals(\"getArchiveFile\")) {\n                newMethods.add(reMethod(method));\n//            }\n        }\n\n\n\n        return new ImmutableClassDef(\n                reType,\n                classDef.getAccessFlags(),\n                reSuperClass,\n                newInterfaces,\n                classDef.getSourceFile(),\n                immutableAnnotations,\n                newFields,\n                newMethods);\n        }\n\n    protected abstract String reType(String type);\n\n    protected abstract String reSuperClass(String superClass);\n\n    protected abstract String reInterface(String inter);\n\n    protected abstract Annotation reAnnotation(Annotation annotation);\n\n    protected abstract Field reField(Field field);\n\n    public abstract Method reMethod(Method method);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/repatch/ClassReIClassDef.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.repatch;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.taobao.android.repatch.Utils.DefineUtils;\nimport com.taobao.android.repatch.processor.ClassProcessor;\nimport com.taobao.android.tpatch.utils.SmaliUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.jf.dexlib2.iface.Annotation;\nimport org.jf.dexlib2.iface.AnnotationElement;\nimport org.jf.dexlib2.iface.Field;\nimport org.jf.dexlib2.iface.Method;\nimport org.jf.dexlib2.iface.reference.MethodReference;\nimport org.jf.dexlib2.iface.value.*;\nimport org.jf.dexlib2.immutable.ImmutableAnnotation;\nimport org.jf.dexlib2.immutable.ImmutableAnnotationElement;\nimport org.jf.dexlib2.immutable.ImmutableField;\nimport org.jf.dexlib2.immutable.reference.ImmutableMethodReference;\nimport org.jf.dexlib2.immutable.value.ImmutableArrayEncodedValue;\nimport org.jf.dexlib2.immutable.value.ImmutableMethodEncodedValue;\nimport org.jf.dexlib2.immutable.value.ImmutableStringEncodedValue;\nimport org.jf.dexlib2.immutable.value.ImmutableTypeEncodedValue;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * Created by lilong on 16/7/1.\n */\npublic abstract class ClassReIClassDef extends AbIClassDef {\n\n    protected ClassProcessor classProcessor;\n\n    public ClassReIClassDef(ClassProcessor classProcessor) {\n\n        this.classProcessor = classProcessor;\n\n    }\n\n    @Override\n    protected String reType(String type) {\n\n        return DefineUtils.getDefineClassName(classProcessor.classProcess(SmaliUtils.getDalvikClassName(type)).className, false);\n    }\n\n    @Override\n    protected String reSuperClass(String superClass) {\n        return DefineUtils.getDefineClassName(classProcessor.classProcess(SmaliUtils.getDalvikClassName(superClass)).className, false);\n    }\n\n    @Override\n    protected String reInterface(String inter) {\n\n        return DefineUtils.getDefineClassName(classProcessor.classProcess(SmaliUtils.getDalvikClassName(inter)).className, false);\n    }\n\n    @Override\n    protected Annotation reAnnotation(Annotation annotation) {\n        String type = annotation.getType();\n        boolean isArray = false;\n        if (type.startsWith(\"[\")) {\n            isArray = true;\n        }\n        String newType = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(type)).className, isArray);\n        Set<? extends AnnotationElement> sets = annotation.getElements();\n        Set<ImmutableAnnotationElement> newAnnotationElement = new HashSet<ImmutableAnnotationElement>();\n        for (AnnotationElement annotationElement : sets) {\n            String name = annotationElement.getName();\n            EncodedValue encodedValue = annotationElement.getValue();\n            if (encodedValue instanceof ArrayEncodedValue) {\n                List<EncodedValue> lists = new ArrayList<EncodedValue>();\n                for (EncodedValue encodedValueSub : ((ArrayEncodedValue) encodedValue).getValue()) {\n                    if (encodedValueSub instanceof StringEncodedValue) {\n                        String newValue = null;\n                        boolean isArray1 = false;\n                        String value = ((StringEncodedValue) encodedValueSub).getValue();\n                        if (value.startsWith(\"[\")) {\n                            isArray1 = true;\n                        }\n                        if (basicValue.contains(value)) {\n                            newValue = value;\n                        } else if (value.startsWith(\"Ljava/util/\") || value.startsWith(\"Ljava/lang/\") || !value.startsWith(\"L\")) {\n                            newValue = value;\n                        } else {\n                            if (value.endsWith(\";\")) {\n                                newValue = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray1);\n                            }else {\n                                newValue = DefineUtils.getDotDefineClassName(classProcessor.classProcess(DefineUtils.getDotDalvikClassName(value)).className, isArray1);\n\n                            }\n                        }\n                        ImmutableStringEncodedValue immutableStringEncodedValue = new ImmutableStringEncodedValue(newValue);\n                        lists.add(immutableStringEncodedValue);\n                    } else if (encodedValueSub instanceof TypeEncodedValue) {\n                        String newValueSub = null;\n                        String value = ((TypeEncodedValue) encodedValueSub).getValue();\n                        boolean isArray2 = false;\n                        if (value.startsWith(\"[\")) {\n                            isArray2 = true;\n                        }\n                        if (basicValue.contains(value)) {\n                            newValueSub = value;\n                        } else if (value.startsWith(\"Ljava/util/\") || !value.endsWith(\";\")) {\n                            newValueSub = value;\n                        } else {\n                            newValueSub = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray2);\n                        }\n                        ImmutableTypeEncodedValue immutableTypeEncodedValue = new ImmutableTypeEncodedValue(newValueSub);\n                        lists.add(immutableTypeEncodedValue);\n\n                    } else {\n                        lists.add(encodedValue);\n                    }\n                }\n                ImmutableArrayEncodedValue immutableArrayEncodedValue = new ImmutableArrayEncodedValue(lists);\n                ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableArrayEncodedValue);\n                newAnnotationElement.add(immutableAnnotationElement);\n\n            } else if (encodedValue instanceof StringEncodedValue) {\n                String value = ((StringEncodedValue) encodedValue).getValue();\n                String newValue = null;\n                isArray = false;\n                if (value.startsWith(\"[\")) {\n                    isArray = true;\n                }\n                if (basicValue.contains(value)) {\n                    newValue = value;\n                } else if (value.startsWith(\"Ljava/util/\") || value.startsWith(\"Ljava/lang/\") || !value.startsWith(\"L\")) {\n                    newValue = value;\n                } else {\n                    if (value.endsWith(\";\")) {\n                        newValue = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray);\n                    }else {\n                        newValue = DefineUtils.getDotDefineClassName(classProcessor.classProcess(DefineUtils.getDotDalvikClassName(value)).className, isArray);\n\n                    }\n                }\n                ImmutableStringEncodedValue immutableStringEncodedValue = new ImmutableStringEncodedValue(newValue);\n                ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableStringEncodedValue);\n                newAnnotationElement.add(immutableAnnotationElement);\n            } else if (encodedValue instanceof TypeEncodedValue) {\n                String newValue = null;\n                String value = ((TypeEncodedValue) encodedValue).getValue();\n                boolean isArray2 = false;\n                if (value.startsWith(\"[\")) {\n                    isArray2 = true;\n                }\n                if (basicValue.contains(value)) {\n                    newValue = value;\n                } else if (value.startsWith(\"Ljava/util/\") || !value.endsWith(\";\")) {\n                    newValue = value;\n                } else {\n                    newValue = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray2);\n                }\n                ImmutableTypeEncodedValue immutableTypeEncodedValue = new ImmutableTypeEncodedValue(newValue);\n                ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableTypeEncodedValue);\n\n                newAnnotationElement.add(immutableAnnotationElement);\n            } else if (encodedValue instanceof MethodEncodedValue) {\n                MethodReference methodReference = ((MethodEncodedValue) encodedValue).getValue();\n                String returnType = methodReference.getReturnType();\n                boolean isArray3 = false;\n\n                if (returnType.startsWith(\"[\")){\n                    isArray3 = true;\n                }\n                boolean isBasic = basicType.containsKey(returnType);\n                List<? extends CharSequence> paramTypes = methodReference.getParameterTypes();\n                List<CharSequence> dalvikParamTypes = new ArrayList<CharSequence>();\n\n                List<CharSequence> newParamTypes = new ArrayList<CharSequence>();\n\n                for (CharSequence charSequence : paramTypes) {\n                    boolean isArray1 = false;\n                    if (charSequence.toString().startsWith(\"[\")){\n                        isArray1 = true;\n                    }\n                    if (basicType.containsKey(charSequence.toString())) {\n                        newParamTypes.add(charSequence);\n                        dalvikParamTypes.add(basicType.get(charSequence.toString()));\n                        continue;\n                    }\n                    dalvikParamTypes.add(DefineUtils.getDalvikClassName(charSequence.toString()) + (isArray1 ? \"[]\" : \"\"));\n                    newParamTypes.add(\n                            DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(charSequence.toString())).className, isArray1));\n                }\n                final ImmutableMethodReference immutableReference = new ImmutableMethodReference(\n                        DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(methodReference.getDefiningClass())).className, false),\n\n                        classProcessor.methodProcess(DefineUtils.getDalvikClassName(methodReference.getDefiningClass()),\n                                methodReference.getName(),\n                                isBasic ? basicType.get(methodReference.getReturnType()) : DefineUtils.getDalvikClassName(methodReference.getReturnType()) + (isArray3 ? \"[]\" : \"\"),\n                                StringUtils.join(dalvikParamTypes.toArray(), \",\")).methodName,\n                        newParamTypes,\n\n                        isBasic ? returnType : DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(methodReference.getReturnType())).className, methodReference.getReturnType().startsWith(\"[\"))\n                );\n                ImmutableMethodEncodedValue immutableMethodEncodedValue = new ImmutableMethodEncodedValue(immutableReference);\n                ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableMethodEncodedValue);\n\n                newAnnotationElement.add(immutableAnnotationElement);\n\n            } else {\n                newAnnotationElement.add(ImmutableAnnotationElement.of(annotationElement));\n            }\n        }\n        return new ImmutableAnnotation(annotation.getVisibility(), newType, newAnnotationElement);\n\n\n    }\n\n    @Override\n    protected Field reField(Field field) {\n        String name = field.getName();\n        String newType;\n        boolean isBasic = false;\n        boolean isArray = false;\n        if (field.getType().startsWith(\"[\")) {\n            isArray = true;\n        }\n        if (basicType.containsKey(field.getType())) {\n            newType = field.getType();\n            isBasic = true;\n        } else {\n\n            newType = DefineUtils.getDalvikClassName(field.getType());\n        }\n        String defineClass = DefineUtils.getDalvikClassName(field.getDefiningClass());\n        return new ImmutableField(\n                reType,\n                classProcessor.filedProcess(defineClass, isBasic ? basicType.get(newType) : newType + (isArray ? \"[]\" : \"\"), name).fieldName,\n                isBasic ? newType :\n                        DefineUtils.getDefineClassName(classProcessor.classProcess(isBasic ? basicType.get(newType) : newType).className, isArray),\n                field.getAccessFlags(),\n                field.getInitialValue(),\n                getAnnotation(field.getAnnotations()));\n    }\n\n    @Override\n    public abstract Method reMethod(Method method);\n\n\n    public Set<? extends Annotation> getAnnotation(Set<? extends Annotation> annotations) {\n        Set<ImmutableAnnotation> newAnnotations = new HashSet<ImmutableAnnotation>();\n        for (Annotation annotation : annotations) {\n            String type = annotation.getType();\n            boolean isArray = false;\n            if (type.startsWith(\"[\")) {\n                isArray = true;\n            }\n            String newType = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(type)).className, isArray);\n            Set<? extends AnnotationElement> sets = annotation.getElements();\n            Set<ImmutableAnnotationElement> newAnnotationElement = new HashSet<ImmutableAnnotationElement>();\n            for (AnnotationElement annotationElement : sets) {\n                String name = annotationElement.getName();\n                EncodedValue encodedValue = annotationElement.getValue();\n                if (encodedValue instanceof ArrayEncodedValue) {\n                    List<EncodedValue> lists = new ArrayList<EncodedValue>();\n                    for (EncodedValue encodedValueSub : ((ArrayEncodedValue) encodedValue).getValue()) {\n                        if (encodedValueSub instanceof StringEncodedValue) {\n                            String newValue = null;\n                            boolean isArray1 = false;\n                            String value = ((StringEncodedValue) encodedValueSub).getValue();\n                            if (value.startsWith(\"[\")) {\n                                isArray1 = true;\n                            }\n                            if (basicValue.contains(value)) {\n                                newValue = value;\n                            } else if (value.startsWith(\"Ljava/util/\") || !value.endsWith(\";\") || value.startsWith(\"Ljava/lang/\")||!value.startsWith(\"L\")) {\n                                newValue = value;\n                            } else {\n                                newValue = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray1);\n                            }\n                            ImmutableStringEncodedValue immutableStringEncodedValue = new ImmutableStringEncodedValue(newValue);\n                            lists.add(immutableStringEncodedValue);\n                        } else if (encodedValueSub instanceof TypeEncodedValue) {\n                            String newValueSub = null;\n                            String value = ((TypeEncodedValue) encodedValueSub).getValue();\n                            boolean isArray2 = false;\n                            if (value.startsWith(\"[\")) {\n                                isArray2 = true;\n                            }\n                            if (basicValue.contains(value)) {\n                                newValueSub = value;\n                            } else if (value.startsWith(\"Ljava/util/\") || value.startsWith(\"Ljava/lang/\") || !value.endsWith(\";\")) {\n                                newValueSub = value;\n                            } else {\n                                newValueSub = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray2);\n                            }\n                            ImmutableTypeEncodedValue immutableTypeEncodedValue = new ImmutableTypeEncodedValue(newValueSub);\n                            lists.add(immutableTypeEncodedValue);\n\n                        } else {\n                            lists.add(encodedValue);\n                        }\n                    }\n                    ImmutableArrayEncodedValue immutableArrayEncodedValue = new ImmutableArrayEncodedValue(lists);\n                    ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableArrayEncodedValue);\n                    newAnnotationElement.add(immutableAnnotationElement);\n\n                } else if (encodedValue instanceof StringEncodedValue) {\n                    String value = ((StringEncodedValue) encodedValue).getValue();\n                    boolean isArray3 = false;\n                    if (value.startsWith(\"[\")) {\n                        isArray3 = true;\n                    }\n                    String newValue = null;\n                    if (basicValue.contains(value)) {\n                        newValue = value;\n                    } else if (value.startsWith(\"Ljava/util/\") || value.startsWith(\"Ljava/lang/\") || !value.endsWith(\";\")) {\n                        newValue = value;\n                    } else {\n                        newValue = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray3);\n                    }\n                    ImmutableStringEncodedValue immutableStringEncodedValue = new ImmutableStringEncodedValue(newValue);\n                    ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableStringEncodedValue);\n                    newAnnotationElement.add(immutableAnnotationElement);\n\n\n                } else if (encodedValue instanceof MethodEncodedValue) {\n                    MethodReference methodReference = ((MethodEncodedValue) encodedValue).getValue();\n                    String returnType = methodReference.getReturnType();\n                    boolean isBasic = false;\n                    List<? extends CharSequence> paramTypes = methodReference.getParameterTypes();\n                    List<CharSequence> dalvikParamTypes = new ArrayList<CharSequence>();\n\n                    List<CharSequence> newParamTypes = new ArrayList<CharSequence>();\n\n                    for (CharSequence charSequence : paramTypes) {\n                        if (basicType.containsKey(charSequence.toString())) {\n                            newParamTypes.add(charSequence);\n                            dalvikParamTypes.add(basicType.get(charSequence.toString()));\n                            continue;\n                        }\n                        dalvikParamTypes.add(DefineUtils.getDalvikClassName(charSequence.toString()) + (isArray ? \"[]\" : \"\"));\n                        newParamTypes.add(\n                                DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(charSequence.toString())).className, isArray));\n                    }\n                    final ImmutableMethodReference immutableReference = new ImmutableMethodReference(\n                            DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(methodReference.getDefiningClass())).className, false),\n\n                            classProcessor.methodProcess(DefineUtils.getDalvikClassName(methodReference.getDefiningClass()),\n                                    methodReference.getName(),\n                                    isBasic ? basicType.get(methodReference.getReturnType()) : DefineUtils.getDalvikClassName(methodReference.getReturnType()) + (isArray ? \"[]\" : \"\"),\n                                    StringUtils.join(dalvikParamTypes.toArray(), \",\")).methodName,\n                            newParamTypes,\n\n                            isBasic ? returnType : DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(methodReference.getReturnType())).className, methodReference.getReturnType().startsWith(\"[\"))\n                    );\n                    ImmutableMethodEncodedValue immutableMethodEncodedValue = new ImmutableMethodEncodedValue(immutableReference);\n                    ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableMethodEncodedValue);\n\n                    newAnnotationElement.add(immutableAnnotationElement);\n\n\n                } else if (encodedValue instanceof TypeEncodedValue) {\n                    String newValueSub = null;\n                    String value = ((TypeEncodedValue) encodedValue).getValue();\n                    boolean isArray2 = false;\n                    if (value.startsWith(\"[\")) {\n                        isArray2 = true;\n                    }\n                    if (basicValue.contains(value)) {\n                        newValueSub = value;\n                    } else if (value.startsWith(\"Ljava/util/\") || value.startsWith(\"Ljava/lang/\") || !value.endsWith(\";\")) {\n                        newValueSub = value;\n                    } else {\n                        newValueSub = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(value)).className, isArray2);\n                    }\n                    ImmutableTypeEncodedValue immutableTypeEncodedValue = new ImmutableTypeEncodedValue(newValueSub);\n                    ImmutableAnnotationElement immutableAnnotationElement = new ImmutableAnnotationElement(name, immutableTypeEncodedValue);\n                    newAnnotationElement.add(immutableAnnotationElement);\n\n                } else {\n                    newAnnotationElement.add(ImmutableAnnotationElement.of(annotationElement));\n                }\n            }\n\n            ImmutableAnnotation immutableAnnotation = new ImmutableAnnotation(annotation.getVisibility(), newType, newAnnotationElement);\n            newAnnotations.add(immutableAnnotation);\n        }\n        return newAnnotations;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/repatch/FastPatchObject.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.repatch;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport java.io.File;\nimport java.util.*;\n\n/**\n * Created by lilong on 16/7/9.\n */\npublic class FastPatchObject {\n\n    public List<File> DexFiles = new ArrayList<File>();\n    public Map<String, List<String>> modifyClasses = new HashMap<String, List<String>>();\n    public Set<String>addedClass = new HashSet<String>();\n    public String bundleName;\n    public List<String> prepareClasses = new ArrayList<String>();\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/repatch/IClassDef.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.repatch;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport org.jf.dexlib2.iface.ClassDef;\n\n/**\n * Created by lilong on 16/7/1.\n */\npublic interface IClassDef {\n\n    public ClassDef reClassDef(ClassDef classDef);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/repatch/InsTructionsReIClassDef.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.repatch;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.taobao.android.DexObfuscatedTool;\nimport com.taobao.android.repatch.Utils.DefineUtils;\nimport com.taobao.android.repatch.processor.ClassProcessor;\nimport org.apache.commons.lang3.StringUtils;\nimport org.jf.dexlib2.Opcode;\nimport org.jf.dexlib2.ReferenceType;\nimport org.jf.dexlib2.iface.ExceptionHandler;\nimport org.jf.dexlib2.iface.TryBlock;\nimport org.jf.dexlib2.iface.debug.DebugItem;\nimport org.jf.dexlib2.iface.instruction.Instruction;\nimport org.jf.dexlib2.iface.instruction.ReferenceInstruction;\nimport org.jf.dexlib2.iface.instruction.formats.*;\nimport org.jf.dexlib2.iface.reference.FieldReference;\nimport org.jf.dexlib2.iface.reference.MethodReference;\nimport org.jf.dexlib2.iface.reference.StringReference;\nimport org.jf.dexlib2.iface.reference.TypeReference;\nimport org.jf.dexlib2.immutable.ImmutableTryBlock;\nimport org.jf.dexlib2.immutable.debug.ImmutableEndLocal;\nimport org.jf.dexlib2.immutable.debug.ImmutableRestartLocal;\nimport org.jf.dexlib2.immutable.debug.ImmutableStartLocal;\nimport org.jf.dexlib2.immutable.instruction.*;\nimport org.jf.dexlib2.immutable.reference.ImmutableFieldReference;\nimport org.jf.dexlib2.immutable.reference.ImmutableMethodReference;\nimport org.jf.dexlib2.immutable.reference.ImmutableStringReference;\nimport org.jf.dexlib2.immutable.reference.ImmutableTypeReference;\n\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\n\n/**\n * Created by lilong on 16/7/1.\n */\npublic class InsTructionsReIClassDef extends MethodImplReIClassDef {\n\n    public InsTructionsReIClassDef(ClassProcessor classProcessor) {\n        super(classProcessor);\n    }\n\n    @Override\n    protected Iterable<? extends Instruction> reInstructions(Iterable<? extends Instruction> instructions) {\n        final List<Instruction> reinstructions = new ArrayList<Instruction>();\n        for (final Instruction instruction : instructions) {\n            if (instruction instanceof ReferenceInstruction) {\n                Opcode opcode = instruction.getOpcode();\n                if (opcode.referenceType == ReferenceType.METHOD) {\n                    boolean isBasic = false;\n                    MethodReference methodReference = null;\n\n                    try {\n                        methodReference = (MethodReference) ((ReferenceInstruction) instruction).getReference();\n                        if (DexObfuscatedTool.aliProguard && methodReference.getName().equals(\"getName\") && methodReference.getDefiningClass().equals(\"Ljava/lang/Class;\")&&opcode.equals(Opcode.INVOKE_VIRTUAL)){\n                            opcode = Opcode.INVOKE_STATIC;\n                            List<CharSequence>list = new ArrayList<>();\n                            list.add(\"Ljava/lang/Class;\");\n                            Iterable iterable = new Iterable() {\n                                @Override\n                                public Iterator iterator() {\n                                    return list.iterator();\n                                }\n                            };\n                            ImmutableMethodReference immutableMethodReference = new ImmutableMethodReference(\"Lcom/ali/mobisecenhance/ReflectMap;\",\"getName\",iterable,\"Ljava/lang/String;\");\n                            reinstructions.add(new ImmutableInstruction35c(opcode,\n                                    ((Instruction35c) instruction).getRegisterCount(),\n                                    ((Instruction35c) instruction).getRegisterC(),\n                                    ((Instruction35c) instruction).getRegisterD(),\n                                    ((Instruction35c) instruction).getRegisterE(),\n                                    ((Instruction35c) instruction).getRegisterF(),\n                                    ((Instruction35c) instruction).getRegisterG(),\n                                    immutableMethodReference));\n                            continue;\n\n                        }\n                        if (methodReference.getDefiningClass().contains(\"Ljava/lang\") ||\n                                methodReference.getDefiningClass().startsWith(\"Ljava/util/\")||\n                                methodReference.getDefiningClass().startsWith(\"[Ljava/lang\")) {\n                            reinstructions.add(ImmutableInstruction.of(instruction));\n                            continue;\n                        }\n\n                        String returnType = methodReference.getReturnType();\n                        boolean isArray = false;\n                        if (returnType.startsWith(\"[\")){\n                            isArray = true;\n                        }\n                        String methodName = methodReference.getName();\n\n                        if (basicType.containsKey(returnType)) {\n                            isBasic = true;\n                        }\n                        List<? extends CharSequence> paramTypes = methodReference.getParameterTypes();\n                        List<CharSequence> dalvikParamTypes = new ArrayList<CharSequence>();\n\n                        List<CharSequence> newParamTypes = new ArrayList<CharSequence>();\n\n                        for (CharSequence charSequence : paramTypes) {\n                            if (basicType.containsKey(charSequence.toString())) {\n                                newParamTypes.add(charSequence);\n                                dalvikParamTypes.add(basicType.get(charSequence.toString()));\n                                continue;\n                            }\n                            boolean isArray1 = charSequence.toString().startsWith(\"[\");\n                            dalvikParamTypes.add(DefineUtils.getDalvikClassName(charSequence.toString())+(isArray?\"[]\":\"\"));\n                            newParamTypes.add(\n                                    DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(charSequence.toString())).className,isArray1));\n                        }\n                        final ImmutableMethodReference immutableReference = new ImmutableMethodReference(\n                                DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(methodReference.getDefiningClass())).className,methodReference.getDefiningClass().startsWith(\"[\")),\n\n                                classProcessor.methodProcess(DefineUtils.getDalvikClassName(methodReference.getDefiningClass()),\n                                        methodReference.getName(),\n                                        isBasic ? basicType.get(methodReference.getReturnType()): DefineUtils.getDalvikClassName(methodReference.getReturnType())+(isArray?\"[]\":\"\"),\n                                        StringUtils.join(dalvikParamTypes.toArray(), \",\")).methodName,\n                                newParamTypes,\n\n                                isBasic ? returnType : DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(methodReference.getReturnType())).className,methodReference.getReturnType().startsWith(\"[\"))\n                        );\n                        if (instruction instanceof Instruction3rc) {\n\n                            reinstructions.add(new ImmutableInstruction3rc(instruction.getOpcode(),\n                                    ((Instruction3rc) instruction).getStartRegister(),\n                                    ((Instruction3rc) instruction).getRegisterCount(),\n                                    immutableReference));\n\n                        } else if (instruction instanceof Instruction20bc) {\n                            reinstructions.add(new ImmutableInstruction20bc(instruction.getOpcode(),\n                                    ((Instruction20bc) instruction).getVerificationError(),\n                                    immutableReference));\n\n                        } else if (instruction instanceof Instruction21c) {\n                            reinstructions.add(new ImmutableInstruction21c(instruction.getOpcode(),\n                                    ((Instruction21c) instruction).getRegisterA(),\n                                    immutableReference));\n\n                        } else if (instruction instanceof Instruction22c) {\n                            reinstructions.add(new ImmutableInstruction22c(instruction.getOpcode(),\n                                    ((Instruction22c) instruction).getRegisterA(),\n                                    ((Instruction22c) instruction).getRegisterB(),\n                                    immutableReference));\n\n                        } else if (instruction instanceof Instruction31c) {\n                            reinstructions.add(new ImmutableInstruction31c(instruction.getOpcode(),\n                                    ((Instruction31c) instruction).getRegisterA(),\n                                    immutableReference));\n\n                        } else if (instruction instanceof Instruction35c) {\n                            reinstructions.add(new ImmutableInstruction35c(instruction.getOpcode(),\n                                    ((Instruction35c) instruction).getRegisterCount(),\n                                    ((Instruction35c) instruction).getRegisterC(),\n                                    ((Instruction35c) instruction).getRegisterD(),\n                                    ((Instruction35c) instruction).getRegisterE(),\n                                    ((Instruction35c) instruction).getRegisterF(),\n                                    ((Instruction35c) instruction).getRegisterG(),\n                                    immutableReference));\n\n                        }\n\n                    } catch (Exception e) {\n\n                    }\n                } else if (opcode.referenceType == ReferenceType.FIELD) {\n                    FieldReference fieldReference = null;\n                    boolean isBasic = false;\n                    boolean isBasicArray = false;\n                    fieldReference = (FieldReference) ((ReferenceInstruction) instruction).getReference();\n                    if (fieldReference.getDefiningClass().startsWith(\"Ljava/lang/\") ||\n                            fieldReference.getDefiningClass().startsWith(\"Ljava/util/\") ||\n                            fieldReference.getDefiningClass().startsWith(\"[Ljava/lang/\")) {\n                        reinstructions.add(ImmutableInstruction.of(instruction));\n                        continue;\n                    }\n                    if (basicType.containsKey(fieldReference.getType())) {\n                        isBasic = true;\n                    }\n\n                    final ImmutableFieldReference immutableFieldReference = new ImmutableFieldReference(\n\n                            DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(fieldReference.getDefiningClass())).className,fieldReference.getDefiningClass().startsWith(\"[\")),\n                            classProcessor.filedProcess(DefineUtils.getDalvikClassName(fieldReference.getDefiningClass()), isBasic?basicType.get(fieldReference.getType()):DefineUtils.getDalvikClassName(fieldReference.getType()), fieldReference.getName()).fieldName,\n                            isBasic? fieldReference.getType():DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(fieldReference.getType())).className,fieldReference.getType().startsWith(\"[\"))\n                    );\n\n                    if (instruction instanceof Instruction3rc) {\n\n                        reinstructions.add(new ImmutableInstruction3rc(instruction.getOpcode(),\n                                ((Instruction3rc) instruction).getStartRegister(),\n                                ((Instruction3rc) instruction).getRegisterCount(),\n                                immutableFieldReference));\n\n                    } else if (instruction instanceof Instruction20bc) {\n                        reinstructions.add(new ImmutableInstruction20bc(instruction.getOpcode(),\n                                ((Instruction20bc) instruction).getVerificationError(),\n                                immutableFieldReference));\n\n                    } else if (instruction instanceof Instruction21c) {\n                        reinstructions.add(new ImmutableInstruction21c(instruction.getOpcode(),\n                                ((Instruction21c) instruction).getRegisterA(),\n                                immutableFieldReference));\n\n                    } else if (instruction instanceof Instruction22c) {\n                        reinstructions.add(new ImmutableInstruction22c(instruction.getOpcode(),\n                                ((Instruction22c) instruction).getRegisterA(),\n                                ((Instruction22c) instruction).getRegisterB(),\n                                immutableFieldReference));\n\n                    } else if (instruction instanceof Instruction31c) {\n                        reinstructions.add(new ImmutableInstruction31c(instruction.getOpcode(),\n                                ((Instruction31c) instruction).getRegisterA(),\n                                immutableFieldReference));\n\n                    } else if (instruction instanceof Instruction35c) {\n                        reinstructions.add(new ImmutableInstruction35c(instruction.getOpcode(),\n                                ((Instruction35c) instruction).getRegisterCount(),\n                                ((Instruction35c) instruction).getRegisterC(),\n                                ((Instruction35c) instruction).getRegisterD(),\n                                ((Instruction35c) instruction).getRegisterE(),\n                                ((Instruction35c) instruction).getRegisterF(),\n                                ((Instruction35c) instruction).getRegisterG(),\n                                immutableFieldReference));\n\n                    }\n\n                } else if (opcode.referenceType == ReferenceType.TYPE) {\n                    TypeReference typeReference = (TypeReference) ((ReferenceInstruction) instruction).getReference();\n                    String type = typeReference.getType();\n                    if (!basicType.containsKey(type) && !type.startsWith(\"Ljava/lang\")&&!type.startsWith(\"Ljava/util/\")&&!type.startsWith(\"[Ljava/lang\")) {\n                        type = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(type)).className,type.startsWith(\"[\"));\n                    }\n                    ImmutableTypeReference immutableTypeReference = new ImmutableTypeReference(type);\n                    if (instruction instanceof Instruction3rc) {\n\n                        reinstructions.add(new ImmutableInstruction3rc(instruction.getOpcode(),\n                                ((Instruction3rc) instruction).getStartRegister(),\n                                ((Instruction3rc) instruction).getRegisterCount(),\n                                immutableTypeReference));\n\n                    } else if (instruction instanceof Instruction20bc) {\n                        reinstructions.add(new ImmutableInstruction20bc(instruction.getOpcode(),\n                                ((Instruction20bc) instruction).getVerificationError(),\n                                immutableTypeReference));\n\n                    } else if (instruction instanceof Instruction21c) {\n                        reinstructions.add(new ImmutableInstruction21c(instruction.getOpcode(),\n                                ((Instruction21c) instruction).getRegisterA(),\n                                immutableTypeReference));\n\n                    } else if (instruction instanceof Instruction22c) {\n                        reinstructions.add(new ImmutableInstruction22c(instruction.getOpcode(),\n                                ((Instruction22c) instruction).getRegisterA(),\n                                ((Instruction22c) instruction).getRegisterB(),\n                                immutableTypeReference));\n\n                    } else if (instruction instanceof Instruction31c) {\n                        reinstructions.add(new ImmutableInstruction31c(instruction.getOpcode(),\n                                ((Instruction31c) instruction).getRegisterA(),\n                                immutableTypeReference));\n\n                    } else if (instruction instanceof Instruction35c) {\n                        reinstructions.add(new ImmutableInstruction35c(instruction.getOpcode(),\n                                ((Instruction35c) instruction).getRegisterCount(),\n                                ((Instruction35c) instruction).getRegisterC(),\n                                ((Instruction35c) instruction).getRegisterD(),\n                                ((Instruction35c) instruction).getRegisterE(),\n                                ((Instruction35c) instruction).getRegisterF(),\n                                ((Instruction35c) instruction).getRegisterG(),\n                                immutableTypeReference));\n\n                    }\n\n\n                } else if (opcode.referenceType == ReferenceType.STRING) {\n                    StringReference stringReference = (StringReference) ((ReferenceInstruction) instruction).getReference();\n                    String type = stringReference.getString();\n//                    if (!basicType.contains(type) && !type.startsWith(\"[Ljava/lang\")) {\n//                        type = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(type)).className);\n//                    }\n                    ImmutableStringReference immutableStringReference = new ImmutableStringReference(type);\n                    if (instruction instanceof Instruction3rc) {\n\n                        reinstructions.add(new ImmutableInstruction3rc(instruction.getOpcode(),\n                                ((Instruction3rc) instruction).getStartRegister(),\n                                ((Instruction3rc) instruction).getRegisterCount(),\n                                immutableStringReference));\n\n                    } else if (instruction instanceof Instruction20bc) {\n                        reinstructions.add(new ImmutableInstruction20bc(instruction.getOpcode(),\n                                ((Instruction20bc) instruction).getVerificationError(),\n                                immutableStringReference));\n\n                    } else if (instruction instanceof Instruction21c) {\n                        reinstructions.add(new ImmutableInstruction21c(instruction.getOpcode(),\n                                ((Instruction21c) instruction).getRegisterA(),\n                                immutableStringReference));\n\n                    } else if (instruction instanceof Instruction22c) {\n                        reinstructions.add(new ImmutableInstruction22c(instruction.getOpcode(),\n                                ((Instruction22c) instruction).getRegisterA(),\n                                ((Instruction22c) instruction).getRegisterB(),\n                                immutableStringReference));\n\n                    } else if (instruction instanceof Instruction31c) {\n                        reinstructions.add(new ImmutableInstruction31c(instruction.getOpcode(),\n                                ((Instruction31c) instruction).getRegisterA(),\n                                immutableStringReference));\n\n                    } else if (instruction instanceof Instruction35c) {\n                        reinstructions.add(new ImmutableInstruction35c(instruction.getOpcode(),\n                                ((Instruction35c) instruction).getRegisterCount(),\n                                ((Instruction35c) instruction).getRegisterC(),\n                                ((Instruction35c) instruction).getRegisterD(),\n                                ((Instruction35c) instruction).getRegisterE(),\n                                ((Instruction35c) instruction).getRegisterF(),\n                                ((Instruction35c) instruction).getRegisterG(),\n                                immutableStringReference));\n\n                    }\n\n\n                } else {\n                    reinstructions.add(ImmutableInstruction.of(instruction));\n\n                }\n            } else {\n                reinstructions.add(ImmutableInstruction.of(instruction));\n            }\n        }\n\n        return new Iterable<Instruction>() {\n            @Override\n            public Iterator<Instruction> iterator() {\n                return reinstructions.iterator();\n\n            }\n\n        };\n    }\n\n    @Override\n    protected Iterable<? extends DebugItem> reDebugItem(Iterable<? extends DebugItem> debugItems) {\n        if (debugItems == null) {\n            return null;\n        }\n        Iterator iterator = debugItems.iterator();\n        final List<DebugItem> immableDebugItems = new ArrayList<DebugItem>();\n        while (iterator.hasNext()) {\n            DebugItem debugItem = (DebugItem) iterator.next();\n            if (debugItem instanceof ImmutableStartLocal) {\n                String newType = null;\n                String type = ((ImmutableStartLocal) debugItem).getType();\n                if (!basicType.containsKey(type)) {\n                    newType = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(type)).className,type.startsWith(\"[\"));\n                } else newType = type;\n                immableDebugItems.add(new ImmutableStartLocal(debugItem.getCodeAddress(),\n                        ((ImmutableStartLocal) debugItem).getRegister(),\n                        ((ImmutableStartLocal) debugItem).getName(),\n                        newType,\n                        ((ImmutableStartLocal) debugItem).getSignature()));\n            } else if (debugItem instanceof ImmutableEndLocal) {\n                String newType = null;\n                String type = ((ImmutableEndLocal) debugItem).getType();\n                if (!basicType.containsKey(type)) {\n                    newType = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(type)).className,type.startsWith(\"[\"));\n                } else newType = type;\n                immableDebugItems.add(new ImmutableEndLocal(debugItem.getCodeAddress(),\n                        ((ImmutableEndLocal) debugItem).getRegister(),\n                        ((ImmutableEndLocal) debugItem).getName(),\n                        newType,\n                        ((ImmutableEndLocal) debugItem).getSignature()));\n\n            } else if (debugItem instanceof ImmutableRestartLocal) {\n                String newType = null;\n                String type = ((ImmutableRestartLocal) debugItem).getType();\n                if (!basicType.containsKey(type)) {\n                    newType = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(type)).className,type.startsWith(\"[\"));\n                } else newType = type;\n                immableDebugItems.add(new ImmutableRestartLocal(debugItem.getCodeAddress(),\n                        ((ImmutableRestartLocal) debugItem).getRegister(),\n                        ((ImmutableRestartLocal) debugItem).getName(),\n                        newType,\n                        ((ImmutableRestartLocal) debugItem).getSignature()));\n\n            } else immableDebugItems.add(debugItem);\n\n        }\n\n\n        return new Iterable<DebugItem>() {\n            @Override\n            public Iterator<DebugItem> iterator() {\n                return immableDebugItems.iterator();\n            }\n        };\n    }\n\n    @Override\n    protected List<? extends TryBlock<? extends ExceptionHandler>> reTryCatchBlock(List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks) {\n        if (tryBlocks == null || tryBlocks.size() == 0) {\n            return null;\n        }\n        List<ImmutableTryBlock> newTryCatchBlocks = new ArrayList<ImmutableTryBlock>();\n        for (TryBlock<? extends ExceptionHandler> tryBlock : tryBlocks) {\n            newTryCatchBlocks.add(ImmutableTryBlock.of(tryBlock));\n        }\n        return newTryCatchBlocks;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/repatch/MethodImplReIClassDef.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.repatch;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.taobao.android.repatch.Utils.DefineUtils;\nimport com.taobao.android.repatch.processor.ClassProcessor;\n\nimport org.jf.dexlib2.iface.ExceptionHandler;\nimport org.jf.dexlib2.iface.MethodImplementation;\nimport org.jf.dexlib2.iface.MethodParameter;\nimport org.jf.dexlib2.iface.TryBlock;\nimport org.jf.dexlib2.iface.debug.DebugItem;\nimport org.jf.dexlib2.iface.instruction.Instruction;\nimport org.jf.dexlib2.immutable.ImmutableMethodImplementation;\nimport org.jf.dexlib2.immutable.ImmutableMethodParameter;\n\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\n\n/**\n * Created by lilong on 16/7/1.\n */\npublic abstract class MethodImplReIClassDef extends MethodReIClassDef {\n\n    public MethodImplReIClassDef(ClassProcessor classProcessor) {\n        super(classProcessor);\n    }\n\n    @Override\n    protected MethodImplementation reMethodImpl(MethodImplementation methodImplementation) {\n        if (methodImplementation == null){\n            return null;\n        }\n        Iterable<? extends Instruction> instructions = methodImplementation.getInstructions();\n        Iterable<? extends DebugItem> debugItems = methodImplementation.getDebugItems();\n        List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks = methodImplementation.getTryBlocks();\n        return new ImmutableMethodImplementation(methodImplementation.getRegisterCount(), reInstructions(instructions), reTryCatchBlock(methodImplementation.getTryBlocks()), reDebugItem(methodImplementation.getDebugItems()));\n\n    }\n\n\n    protected abstract Iterable<? extends Instruction> reInstructions(Iterable<? extends Instruction> instructions);\n\n    protected abstract Iterable<? extends DebugItem> reDebugItem(Iterable<? extends DebugItem> debugItems);\n\n    protected abstract List<? extends TryBlock<? extends ExceptionHandler>> reTryCatchBlock(List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks);\n\n\n    @Override\n    protected Iterable<? extends MethodParameter> reParameters(final List<? extends MethodParameter> paramters) {\n        final List<ImmutableMethodParameter> list = new ArrayList<ImmutableMethodParameter>();\n        for (MethodParameter methodParameter : paramters) {\n            boolean isBasic = false;\n            if (basicType.containsKey(methodParameter.getType())) {\n                isBasic = true;\n            }\n            list.add(new ImmutableMethodParameter(\n                    isBasic ? methodParameter.getType() : DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(methodParameter.getType())).className,methodParameter.getType().startsWith(\"[\")),\n                    methodParameter.getAnnotations(), methodParameter.getName()));\n        }\n        return new Iterable<ImmutableMethodParameter>() {\n            @Override\n            public Iterator<ImmutableMethodParameter> iterator() {\n                return list.iterator();\n\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/repatch/MethodReIClassDef.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.repatch;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.taobao.android.repatch.Utils.DefineUtils;\nimport com.taobao.android.repatch.processor.ClassProcessor;\nimport org.apache.commons.lang3.StringUtils;\nimport org.jf.dexlib2.iface.Method;\nimport org.jf.dexlib2.iface.MethodImplementation;\nimport org.jf.dexlib2.iface.MethodParameter;\nimport org.jf.dexlib2.immutable.ImmutableMethod;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Created by lilong on 16/7/1.\n */\npublic abstract class MethodReIClassDef extends ClassReIClassDef {\n\n    public MethodReIClassDef(ClassProcessor classProcessor) {\n        super(classProcessor);\n    }\n\n    @Override\n    public Method reMethod(Method method) {\n        String newType = null;\n        boolean isBasic = false;\n        boolean isInit = false;\n        boolean changeOpcode = false;\n        String methodName = method.getName();\n        String returnType = method.getReturnType();\n        MethodImplementation methodImplementation = method.getImplementation();\n        List<? extends MethodParameter> paramters = method.getParameters();\n        if (methodName.equals(\"<init>\") || methodName.equals(\"<cinit>\")) {\n            isInit = true;\n        }\n\n\n        if (basicType.containsKey(returnType)) {\n            newType = returnType;\n            isBasic = true;\n        } else {\n            newType = classProcessor.classProcess(DefineUtils.getDalvikClassName(returnType)).className;\n        }\n\n        String[] argsOringn = new String[paramters.size()];\n        String[] args = new String[paramters.size()];\n        for (int i = 0; i < paramters.size(); i++) {\n            //型参数不混淆\n            if (basicType.containsKey(paramters.get(i).getType())) {\n                argsOringn[i] = basicType.get(paramters.get(i).getType());\n                args[i] = argsOringn[i];\n                continue;\n            }\n            argsOringn[i] = DefineUtils.getDalvikClassName(paramters.get(i).getType());\n            args[i] = classProcessor.classProcess(DefineUtils.getDalvikClassName(paramters.get(i).getType())).className;\n        }\n        String type = method.getReturnType();\n        \n        return new ImmutableMethod(reType,\n                classProcessor.methodProcess(isInit ? methodName :\n                        DefineUtils.getDalvikClassName(method.getDefiningClass()), methodName, isBasic ? basicType.get(returnType) : DefineUtils.getDalvikClassName(returnType), StringUtils.join(argsOringn, \",\")).methodName,\n                reParameters(paramters),\n                isBasic ? newType:\n                        DefineUtils.getDefineClassName(newType,type.startsWith(\"[\")),\n                    method.getAccessFlags(),\n                getAnnotation(method.getAnnotations()),\n                reMethodImpl(methodImplementation));\n\n    }\n\n    private List<String> toTypes(List<? extends MethodParameter> paramters) {\n        List<String>types = new ArrayList<>();\n        for (MethodParameter methodParameter:paramters){\n            types.add(methodParameter.getType());\n        }\n        return types;\n    }\n\n    protected abstract MethodImplementation reMethodImpl(MethodImplementation methodImplementation);\n\n    protected abstract Iterable<? extends MethodParameter> reParameters(List<? extends MethodParameter> paramters);\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/repatch/Utils/DefineUtils.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.repatch.Utils;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport org.apache.commons.lang3.StringUtils;\n\n/**\n * Created by lilong on 16/7/5.\n */\npublic class DefineUtils {\n\n    public static String getDalvikClassName(String className) {\n        if (className.startsWith(\"[\")){\n            className = className.substring(1);\n        }\n        if (className.charAt(0) != 'L'||!className.endsWith(\";\")) {\n            return className;\n        }\n        return StringUtils.replace(className.substring(1, className.length() - 1), \"/\", \".\");\n    }\n\n\n    public static String getDefineClassName(String type,boolean isArray){\n        if (isArray){\n            return \"[L\"+type.replace(\".\",\"/\")+\";\";\n        }\n        return \"L\"+type.replace(\".\",\"/\")+\";\";\n    }\n\n    public static String getDotDalvikClassName(String className) {\n        if (className.startsWith(\"[\")) {\n            className = className.substring(1);\n        }\n        if (className.charAt(0) != 'L') {\n            return className;\n        }\n        if (!className.endsWith(\";\")) {\n            return StringUtils.replace(className.substring(1), \"/\", \".\");\n        }\n\n        return className;\n    }\n    public static String getDotDefineClassName(String type,boolean isArray){\n        if (isArray){\n            return \"[L\"+type.replace(\".\",\"/\");\n        }\n        return \"L\"+type.replace(\".\",\"/\");\n    }\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/repatch/mapping/MappingProcessor.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.repatch.mapping;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\n/**\n * Created by lilong on 16/6/30.\n */\npublic interface MappingProcessor {\n\n    public boolean processClassMapping(String className,\n                                       String newClassName);\n\n    public void processMethodMapping(String className,\n                                     int firstLineNumber,\n                                     int lastLineNumber,\n                                     String methodReturnType,\n                                     String methodName,\n                                     String methodArguments,\n                                     String newClassName,\n                                     int newFirstLineNumber,\n                                     int newLastLineNumber,\n                                     String newMethodName);\n\n    public void processFieldMapping(String className,\n                                    String fieldType,\n                                    String fieldName,\n                                    String newClassName,\n                                    String newFieldName);\n\n    public MappingProcessorImpl.ClassObject.NewClassObject getNewClassName(String oldClassName);\n\n    public MappingProcessorImpl.MethodObject.NewMethodObject getNewClassNameAndMethodName(String oldClassName, String methodName, String methodReturnType,String args);\n\n    public MappingProcessorImpl.FieldObject.NewFieldObject getNewFieldName(String oldClassName, String fieldType,String oldFieldName);\n\n    public void updateMethod();\n\n    public void updateFieldType();\n    }\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/repatch/mapping/MappingProcessorImpl.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.repatch.mapping;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport org.apache.commons.lang3.StringUtils;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Created by lilong on 16/6/30.\n */\npublic class MappingProcessorImpl implements MappingProcessor {\n\n    private Map<String, ClassObject> classMap = new HashMap<String, ClassObject>();\n    private Map<String, MethodObject> methodMap = new HashMap<String, MethodObject>();\n    private Map<String, FieldObject> fieldMap = new HashMap<String, FieldObject>();\n\n\n    private Map<String,String>superClassMap = new HashMap<String, String>();\n\n    public MappingProcessorImpl(Map<String, String> superClassMap) {\n        this.superClassMap = superClassMap;\n    }\n\n    @Override\n    public boolean processClassMapping(String className, String newClassName) {\n        classMap.put(className, new ClassObject(className, newClassName));\n        return true;\n    }\n\n    @Override\n    public void processMethodMapping(String className, int firstLineNumber, int lastLineNumber, String methodReturnType, String methodName, String methodArguments, String newClassName, int newFirstLineNumber, int newLastLineNumber, String newMethodName) {\n        methodMap.put(className + \":\" + methodName + \":\" + methodReturnType + \":\" + methodArguments, new MethodObject(className, firstLineNumber, lastLineNumber, methodReturnType, methodName, methodArguments, newClassName, newMethodName));\n        if (methodName.equals(\"InitBundleInfoByVersionIfNeed\")) {\n            System.out.println(\"xxxx\");\n        }\n    }\n\n    @Override\n    public void processFieldMapping(String className, String fieldType, String fieldName, String newClassName, String newFieldName) {\n        fieldMap.put(className + \":\" + fieldType + \":\" + fieldName, new FieldObject(className, fieldType, fieldName, newClassName, newFieldName));\n    }\n\n    public static class ClassObject {\n        public OldClassObject oldClassObject;\n        public NewClassObject newClassObject;\n\n        public static class OldClassObject {\n\n            public OldClassObject(String className) {\n                this.className = className;\n            }\n\n            public String className;\n\n        }\n\n        public static class NewClassObject {\n\n            public NewClassObject(String className) {\n                this.className = className;\n            }\n\n            public String className;\n\n        }\n\n        public ClassObject(String className, String newClassName) {\n\n            this.oldClassObject = new OldClassObject(className);\n            this.newClassObject = new NewClassObject(newClassName);\n        }\n    }\n\n    public static class MethodObject {\n        public OldMethodObject oldMethodObject;\n        public NewMethodObject newMethodObject;\n        public int firstLineNumber;\n        public int lastLineNumber;\n\n        public static class OldMethodObject {\n            public String className;\n\n            public OldMethodObject(String className, String methodName, String methodReturnType, String methodParam) {\n                this.className = className;\n                this.methodName = methodName;\n                this.methodReturnType = methodReturnType;\n                this.methodParam = methodParam;\n            }\n\n            public String methodName;\n            public String methodReturnType;\n            public String methodParam;\n\n        }\n\n        public static class NewMethodObject {\n            public String className;\n\n            public NewMethodObject(String className, String methodName, String methodReturnType, String methodParam) {\n                this.className = className;\n                this.methodName = methodName;\n                this.methodReturnType = methodReturnType;\n                this.methodParam = methodParam;\n            }\n\n            public String methodName;\n            public String methodReturnType;\n            public String methodParam;\n\n        }\n\n        public MethodObject(String className, int firstLineNumber, int lastLineNumber, String methodReturnType, String methodName, String methodArguments, String newClassName, String newMethodName) {\n            oldMethodObject = new OldMethodObject(className, methodName, methodReturnType, methodArguments);\n            newMethodObject = new NewMethodObject(newClassName, newMethodName, null, null);\n        }\n    }\n\n    public static class FieldObject {\n\n        public OldFieldObject oldFieldObject;\n        public NewFieldObject newFieldObject;\n\n        public static class OldFieldObject {\n\n\n            public OldFieldObject(String className, String fieldType, String fieldName) {\n                this.className = className;\n                this.fieldType = fieldType;\n                this.fieldName = fieldName;\n            }\n\n            public String className;\n            public String fieldType;\n            public String fieldName;\n\n        }\n\n        public static class NewFieldObject {\n\n            public NewFieldObject(String className, String fieldType, String fieldName) {\n                this.className = className;\n                this.fieldType = fieldType;\n                this.fieldName = fieldName;\n            }\n\n            public String className;\n            public String fieldType;\n            public String fieldName;\n        }\n\n        public FieldObject(String className, String fieldType, String fieldName, String newClassName, String newFieldName) {\n            this.oldFieldObject = new OldFieldObject(className, fieldType, fieldName);\n            this.newFieldObject = new NewFieldObject(newClassName, null, newFieldName);\n        }\n    }\n\n    @Override\n    public ClassObject.NewClassObject getNewClassName(String oldClassName) {\n        ClassObject classObject = classMap.get(oldClassName);\n        if (classObject == null) {\n            return new ClassObject.NewClassObject(oldClassName);\n        }\n        return classObject.newClassObject;\n    }\n\n    @Override\n    public MethodObject.NewMethodObject getNewClassNameAndMethodName(String oldClassName, String methodName, String methodReturnType, String args) {\n        MethodObject methodObject = methodMap.get(oldClassName + \":\" + methodName + \":\" +methodReturnType +\":\" + args);\n        if (methodObject == null) {\n            if (superClassMap.get(oldClassName)!= null){\n                return getNewClassNameAndMethodName(superClassMap.get(oldClassName),methodName,methodReturnType,args);\n            }\n            return new MethodObject.NewMethodObject(oldClassName, methodName, methodReturnType, args);\n        }\n        return methodObject.newMethodObject;\n\n    }\n\n    @Override\n    public FieldObject.NewFieldObject getNewFieldName(String oldClassName, String fieldType, String oldFieldName) {\n        FieldObject fieldObject = fieldMap.get(oldClassName + \":\" + fieldType + \":\" + oldFieldName);\n        if (fieldObject == null) {\n            if (superClassMap.get(oldClassName)!= null){\n                return getNewFieldName(superClassMap.get(oldClassName),fieldType,oldFieldName);\n            }\n            return new FieldObject.NewFieldObject(oldClassName, fieldType, oldFieldName);\n        }\n        return fieldObject.newFieldObject;\n    }\n\n    public void updateMethod() {\n        for (Map.Entry entry : methodMap.entrySet()) {\n            MethodObject methodObject = (MethodObject) entry.getValue();\n            String args = methodObject.oldMethodObject.methodParam;\n            String className = methodObject.oldMethodObject.className;\n            String methodReturnType = methodObject.oldMethodObject.methodReturnType;\n            if (args != null && args.indexOf(\",\") != -1) {\n                String[] argArray = args.split(\",\");\n                String[] newArgArray = new String[argArray.length];\n                for (int i = 0; i < argArray.length; i++) {\n                    boolean isArrayParam = false;\n                    if (argArray[i].contains(\"[]\")) {\n                        isArrayParam = true;\n                    }\n                    if (isArrayParam) {\n                        if (classMap.get(argArray[i].substring(0, argArray[i].length() - 2)) != null) {\n                            newArgArray[i] = classMap.get(argArray[i].substring(0, argArray[i].length() - 2)).newClassObject.className + \"[]\";\n                        } else newArgArray[i] = argArray[i];\n                    } else {\n                        if (classMap.get(argArray[i]) != null) {\n                            newArgArray[i] = classMap.get(argArray[i]).newClassObject.className;\n                        } else newArgArray[i] = argArray[i];\n                    }\n                }\n                methodObject.newMethodObject.methodParam = StringUtils.join(newArgArray, \",\");\n            }\n            boolean isArrayType = false;\n            if (methodReturnType.contains(\"[]\")) {\n                isArrayType = true;\n                methodReturnType = methodReturnType.substring(0, methodReturnType.length() - 2);\n            }\n            if (classMap.get(methodReturnType) != null) {\n                if (isArrayType) {\n                    methodObject.newMethodObject.methodReturnType = classMap.get(methodReturnType).newClassObject.className + \"[]\";\n                } else\n                    methodObject.newMethodObject.methodReturnType = classMap.get(methodReturnType).newClassObject.className;\n\n            } else {\n                methodObject.newMethodObject.methodReturnType = methodObject.oldMethodObject.methodReturnType;\n            }\n\n            if (classMap.get(className) != null) {\n                methodObject.newMethodObject.className = classMap.get(className).newClassObject.className;\n            }\n\n        }\n\n\n    }\n\n    public void updateFieldType() {\n        for (Map.Entry entry : fieldMap.entrySet()) {\n            FieldObject fieldObject = (FieldObject) entry.getValue();\n            FieldObject.NewFieldObject newFieldObject = fieldObject.newFieldObject;\n            FieldObject.OldFieldObject oldFieldObject = fieldObject.oldFieldObject;\n            String fieldType = oldFieldObject.fieldType;\n            boolean isArrayType = false;\n            if (fieldType.contains(\"[]\")) {\n                isArrayType = true;\n            }\n            if (isArrayType) {\n                fieldType = fieldType.substring(0, fieldType.length() - 2);\n            }\n\n            if (classMap.get(fieldType) != null) {\n                newFieldObject.fieldType = isArrayType ? classMap.get(fieldType).newClassObject.className + \"[]\" : classMap.get(fieldType).newClassObject.className;\n            } else {\n                newFieldObject.fieldType = fieldObject.oldFieldObject.fieldType;\n            }\n\n            if (classMap.get(newFieldObject.className) != null) {\n                newFieldObject.className = classMap.get(newFieldObject.className).newClassObject.className;\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/repatch/mapping/MappingReader.java",
    "content": "\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */package com.taobao.android.repatch.mapping;\n /*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.io.LineNumberReader;\n\n/**\n * Created by lilong on 16/6/30.\n */\npublic class MappingReader {\n    private final File mappingFile;\n\n\n    public MappingReader(File mappingFile) {\n        this.mappingFile = mappingFile;\n    }\n\n\n    public void pump(MappingProcessor mappingProcessor) throws IOException {\n        LineNumberReader reader = new LineNumberReader(\n                new BufferedReader(\n                        new FileReader(mappingFile)));\n        try {\n            String className = null;\n\n            // Read the subsequent class mappings and class member mappings.\n            while (true) {\n                String line = reader.readLine();\n\n                if (line == null) {\n                    break;\n                }\n\n                line = line.trim();\n\n                // Is it a non-comment line?\n                if (!line.startsWith(\"#\")) {\n                    // Is it a class mapping or a class member mapping?\n                    if (line.endsWith(\":\")) {\n                        // Process the class mapping and remember the class's\n                        // old name.\n                        className = processClassMapping(line, mappingProcessor);\n                    } else if (className != null) {\n                        // Process the class member mapping, in the context of\n                        // the current old class name.\n                        processClassMemberMapping(className, line, mappingProcessor);\n                    }\n                }\n            }\n        } catch (IOException ex) {\n            throw new IOException(\"Can't process mapping file (\" + ex.getMessage() + \")\");\n        } finally {\n            try {\n                reader.close();\n            } catch (IOException ex) {\n                // This shouldn't happen.\n            }\n        }\n    }\n\n\n    private String processClassMapping(String line,\n                                       MappingProcessor mappingProcessor) {\n\n        int arrowIndex = line.indexOf(\"->\");\n        if (arrowIndex < 0) {\n            return null;\n        }\n\n        int colonIndex = line.indexOf(':', arrowIndex + 2);\n        if (colonIndex < 0) {\n            return null;\n        }\n\n        // Extract the elements.\n        String className = line.substring(0, arrowIndex).trim();\n        String newClassName = line.substring(arrowIndex + 2, colonIndex).trim();\n\n        // Process this class name mapping.\n        boolean interested = mappingProcessor.processClassMapping(className, newClassName);\n\n        return interested ? className : null;\n    }\n\n\n    private void processClassMemberMapping(String className,\n                                           String line,\n                                           MappingProcessor mappingProcessor) {\n\n        int colonIndex1 = line.indexOf(':');\n        int colonIndex2 = colonIndex1 < 0 ? -1 : line.indexOf(':', colonIndex1 + 1);\n        int spaceIndex = line.indexOf(' ', colonIndex2 + 2);\n        int argumentIndex1 = line.indexOf('(', spaceIndex + 1);\n        int argumentIndex2 = argumentIndex1 < 0 ? -1 : line.indexOf(')', argumentIndex1 + 1);\n        int colonIndex3 = argumentIndex2 < 0 ? -1 : line.indexOf(':', argumentIndex2 + 1);\n        int colonIndex4 = colonIndex3 < 0 ? -1 : line.indexOf(':', colonIndex3 + 1);\n        int arrowIndex = line.indexOf(\"->\", (colonIndex4 >= 0 ? colonIndex4 :\n                colonIndex3 >= 0 ? colonIndex3 :\n                        argumentIndex2 >= 0 ? argumentIndex2 :\n                                spaceIndex) + 1);\n\n        if (spaceIndex < 0 ||\n                arrowIndex < 0) {\n            return;\n        }\n        if (colonIndex3 > 0) {\n            return;\n        }\n\n        // Extract the elements.\n        String type = line.substring(colonIndex2 + 1, spaceIndex).trim();\n        String name = line.substring(spaceIndex + 1, argumentIndex1 >= 0 ? argumentIndex1 : arrowIndex).trim();\n        String newName = line.substring(arrowIndex + 2).trim();\n\n        // Does the method name contain an explicit original class name?\n        String newClassName = className;\n        int dotIndex = name.lastIndexOf('.');\n        if (dotIndex >= 0) {\n            className = name.substring(0, dotIndex);\n            name = name.substring(dotIndex + 1);\n        }\n\n        // Process this class member mapping.\n        if (type.length() > 0 &&\n                name.length() > 0 &&\n                newName.length() > 0) {\n            // Is it a field or a method?\n            if (argumentIndex2 < 0) {\n                mappingProcessor.processFieldMapping(className,\n                        type,\n                        name,\n                        newClassName,\n                        newName);\n            } else {\n                int firstLineNumber = 0;\n                int lastLineNumber = 0;\n                int newFirstLineNumber = 0;\n                int newLastLineNumber = 0;\n\n                if (colonIndex2 >= 0) {\n                    firstLineNumber = newFirstLineNumber = Integer.parseInt(line.substring(0, colonIndex1).trim());\n                    lastLineNumber = newLastLineNumber = Integer.parseInt(line.substring(colonIndex1 + 1, colonIndex2).trim());\n                }\n\n                if (colonIndex3 >= 0) {\n                    firstLineNumber = Integer.parseInt(line.substring(colonIndex3 + 1, colonIndex4 > 0 ? colonIndex4 : arrowIndex).trim());\n                    lastLineNumber = colonIndex4 < 0 ? firstLineNumber :\n                            Integer.parseInt(line.substring(colonIndex4 + 1, arrowIndex).trim());\n                }\n\n                String arguments = line.substring(argumentIndex1 + 1, argumentIndex2).trim();\n\n                mappingProcessor.processMethodMapping(className,\n                        firstLineNumber,\n                        lastLineNumber,\n                        type,\n                        name,\n                        arguments,\n                        newClassName,\n                        newFirstLineNumber,\n                        newLastLineNumber,\n                        newName);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/repatch/processor/ClassProcessor.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.repatch.processor;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.taobao.android.repatch.mapping.MappingProcessorImpl;\n\n/**\n * Created by lilong on 16/7/1.\n */\npublic interface ClassProcessor {\n\n    MappingProcessorImpl.ClassObject.NewClassObject classProcess(String className);\n\n     MappingProcessorImpl.MethodObject.NewMethodObject methodProcess(String className, String methodName, String returnType, String args);\n\n    MappingProcessorImpl.FieldObject.NewFieldObject filedProcess(String className, String fieldType, String fieldName);\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/repatch/processor/MappingClassProcessor.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.repatch.processor;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.taobao.android.repatch.mapping.MappingProcessor;\nimport com.taobao.android.repatch.mapping.MappingProcessorImpl;\n\n/**\n * Created by lilong on 16/7/1.\n */\npublic class MappingClassProcessor implements ClassProcessor {\n    private MappingProcessor mappingProcessor;\n\n    public MappingClassProcessor(MappingProcessor mappingProcessor){\n\n        this.mappingProcessor = mappingProcessor;\n\n    }\n    @Override\n    public MappingProcessorImpl.ClassObject.NewClassObject classProcess(String className) {\n        return mappingProcessor.getNewClassName(className);\n\n    }\n\n    @Override\n    public MappingProcessorImpl.MethodObject.NewMethodObject methodProcess(String className, String methodName, String methodType, String args) {\n         return mappingProcessor.getNewClassNameAndMethodName(className,methodName,methodType,args);\n    }\n\n    @Override\n    public MappingProcessorImpl.FieldObject.NewFieldObject filedProcess(String className, String fieldType, String fieldName) {\n        return mappingProcessor.getNewFieldName(className,fieldType,fieldName);\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/smali/AfBakSmali.java",
    "content": "\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */package com.taobao.android.smali;\n /*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.taobao.android.apatch.utils.TypeGenUtil;\nimport com.taobao.android.baksmali.adaptors.ClassDefinition;\n\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.dexlib2.iface.ClassDef;\nimport org.jf.util.ClassFileNameHandler;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.BufferedWriter;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.OutputStreamWriter;\nimport java.io.Writer;\n\n/**\n * Created by shenghua.nish on 2016-03-17 下午10:01.\n */\npublic class AfBakSmali {\n    /**\n     * 生成apatch的smali文件\n     * @param classDef\n     * @param fileNameHandler\n     * @param options\n     * @param isScan\n     * @param fullMethod\n     * @return\n     */\n    public static boolean disassembleClass(ClassDef classDef, ClassFileNameHandler fileNameHandler,\n                                           BaksmaliOptions options, boolean isScan, boolean fullMethod) {\n        /**\n         * The path for the disassembly file is based on the package name\n         * The class descriptor will look something like:\n         * Ljava/lang/Object;\n         * Where the there is leading 'L' and a trailing ';', and the parts of the\n         * package name are separated by '/'\n         */\n\n        String classDescriptor = TypeGenUtil.newType(classDef.getType());\n\n        //validate that the descriptor is formatted like we expect\n        if (classDescriptor.charAt(0) != 'L' ||\n                classDescriptor.charAt(classDescriptor.length()-1) != ';') {\n            System.err.println(\"Unrecognized class descriptor - \" + classDescriptor + \" - skipping class\");\n            return false;\n        }\n\n        File smaliFile = fileNameHandler.getUniqueFilenameForClass(classDescriptor);\n\n        //create and initialize the top level string template\n        ClassDefinition classDefinition = new ClassDefinition(options, classDef,isScan,fullMethod);\n\n        //write the disassembly\n        Writer writer = null;\n        try\n        {\n            File smaliParent = smaliFile.getParentFile();\n            if (!smaliParent.exists()) {\n                if (!smaliParent.mkdirs()) {\n                    // check again, it's likely it was created in a different thread\n                    if (!smaliParent.exists()) {\n                        System.err.println(\"Unable to create directory \" + smaliParent.toString() + \" - skipping class\");\n                        return false;\n                    }\n                }\n            }\n\n            if (!smaliFile.exists()){\n                if (!smaliFile.createNewFile()) {\n                    System.err.println(\"Unable to create file \" + smaliFile.toString() + \" - skipping class\");\n                    return false;\n                }\n            }\n\n            BufferedWriter bufWriter = new BufferedWriter(new OutputStreamWriter(\n                    new FileOutputStream(smaliFile), \"UTF8\"));\n\n            writer = new IndentingWriter(bufWriter);\n            classDefinition.writeTo((IndentingWriter)writer);\n        } catch (Exception ex) {\n            System.err.println(\"\\n\\nError occurred while disassembling class \" + classDescriptor.replace('/', '.') + \" - skipping class\");\n            ex.printStackTrace();\n            // noinspection ResultOfMethodCallIgnored\n            smaliFile.delete();\n            return false;\n        }\n        finally\n        {\n            if (writer != null) {\n                try {\n                    writer.close();\n                } catch (Throwable ex) {\n                    System.err.println(\"\\n\\nError occurred while closing file \" + smaliFile.toString());\n                    ex.printStackTrace();\n                }\n            }\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/smali/BakSmali.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.smali;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Iterables;\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Ordering;\nimport com.taobao.android.baksmali.adaptors.ClassDefinition;\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.dexlib2.analysis.ClassPath;\nimport org.jf.dexlib2.analysis.CustomInlineMethodResolver;\nimport org.jf.dexlib2.iface.ClassDef;\nimport org.jf.dexlib2.iface.DexFile;\nimport org.jf.dexlib2.util.SyntheticAccessorResolver;\nimport org.jf.util.ClassFileNameHandler;\nimport org.jf.util.IndentingWriter;\nimport org.xml.sax.Attributes;\nimport org.xml.sax.SAXException;\nimport org.xml.sax.helpers.DefaultHandler;\n\nimport javax.xml.parsers.ParserConfigurationException;\nimport javax.xml.parsers.SAXParser;\nimport javax.xml.parsers.SAXParserFactory;\nimport java.io.*;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.*;\n\n/**\n * 将Dex或者ClassDef文件转换为smali文件\n * Created by shenghua.nish on 2016-03-16 下午4:34.\n */\npublic class BakSmali {\n\n\n    public static boolean disassembleClass(ClassDef classDef, ClassFileNameHandler fileNameHandler,\n                                            BaksmaliOptions options) {\n        /**\n         * The path for the disassembly file is based on the package name\n         * The class descriptor will look something like:\n         * Ljava/lang/Object;\n         * Where the there is leading 'L' and a trailing ';', and the parts of the\n         * package name are separated by '/'\n         */\n        String classDescriptor = classDef.getType();\n\n        //validate that the descriptor is formatted like we expect\n        if (classDescriptor.charAt(0) != 'L' ||\n                classDescriptor.charAt(classDescriptor.length()-1) != ';') {\n            System.err.println(\"Unrecognized class descriptor - \" + classDescriptor + \" - skipping class\");\n            return false;\n        }\n\n        File smaliFile = fileNameHandler.getUniqueFilenameForClass(classDescriptor);\n\n        //create and initialize the top level string template\n        ClassDefinition classDefinition = new ClassDefinition(options, classDef);\n\n        //write the disassembly\n        Writer writer = null;\n        try\n        {\n            File smaliParent = smaliFile.getParentFile();\n            if (!smaliParent.exists()) {\n                if (!smaliParent.mkdirs()) {\n                    // check again, it's likely it was created in a different thread\n                    if (!smaliParent.exists()) {\n                        System.err.println(\"Unable to create directory \" + smaliParent.toString() + \" - skipping class\");\n                        return false;\n                    }\n                }\n            }\n\n            if (!smaliFile.exists()){\n                if (!smaliFile.createNewFile()) {\n                    System.err.println(\"Unable to create file \" + smaliFile.toString() + \" - skipping class\");\n                    return false;\n                }\n            }\n\n            BufferedWriter bufWriter = new BufferedWriter(new OutputStreamWriter(\n                    new FileOutputStream(smaliFile), \"UTF8\"));\n\n            writer = new IndentingWriter(bufWriter);\n            classDefinition.writeTo((IndentingWriter)writer);\n        } catch (Exception ex) {\n            System.err.println(\"\\n\\nError occurred while disassembling class \" + classDescriptor.replace('/', '.') + \" - skipping class\");\n            ex.printStackTrace();\n            // noinspection ResultOfMethodCallIgnored\n            smaliFile.delete();\n            return false;\n        }\n        finally\n        {\n            if (writer != null) {\n                try {\n                    writer.close();\n                } catch (Throwable ex) {\n                    System.err.println(\"\\n\\nError occurred while closing file \" + smaliFile.toString());\n                    ex.printStackTrace();\n                }\n            }\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/smali/SmaliMod.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.smali;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport org.antlr.runtime.CommonTokenStream;\nimport org.antlr.runtime.RecognitionException;\nimport org.antlr.runtime.Token;\nimport org.antlr.runtime.TokenSource;\nimport org.antlr.runtime.tree.CommonTree;\nimport org.antlr.runtime.tree.CommonTreeNodeStream;\nimport org.apache.commons.io.IOUtils;\nimport org.jf.dexlib2.writer.builder.DexBuilder;\nimport org.jf.smali.LexerErrorInterface;\nimport org.jf.smali.smaliFlexLexer;\nimport org.jf.smali.smaliParser;\nimport org.jf.smali.smaliTreeWalker;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.OutputStream;\n\n/**\n * 将smali文件重新编译为dex文件\n * Created by shenghua.nish on 2016-03-16 下午4:36.\n */\npublic class SmaliMod {\n    public static boolean assembleSmaliFile(String smali, DexBuilder dexBuilder, boolean verboseErrors,\n                                            boolean printTokens, File smaliFile) throws IOException, RuntimeException, RecognitionException {\n\n        InputStream is = new ByteArrayInputStream(smali.getBytes());\n        return assembleSmaliFile(is, dexBuilder, verboseErrors, printTokens, smaliFile);\n    }\n\n    public static boolean assembleSmaliFile(InputStream is,DexBuilder dexBuilder, boolean verboseErrors,\n                                            boolean printTokens, File smaliFile) throws IOException, RecognitionException {\n\n        // copy our filestream into a tmp file, so we don't overwrite\n        File tmp = File.createTempFile(\"BRUT\",\".bak\");\n        tmp.deleteOnExit();\n\n        OutputStream os = new FileOutputStream(tmp);\n        IOUtils.copy(is, os);\n        os.close();\n\n        return assembleSmaliFile(tmp,dexBuilder, verboseErrors, printTokens);\n    }\n\n    public static boolean assembleSmaliFile(File smaliFile,DexBuilder dexBuilder, boolean verboseErrors,\n                                            boolean printTokens) throws IOException, RecognitionException {\n\n        CommonTokenStream tokens;\n        LexerErrorInterface lexer;\n\n        InputStream is = new FileInputStream(smaliFile);\n        InputStreamReader reader = new InputStreamReader(is, \"UTF-8\");\n\n        lexer = new smaliFlexLexer(reader);\n        ((smaliFlexLexer)lexer).setSourceFile(smaliFile);\n        tokens = new CommonTokenStream((TokenSource) lexer);\n\n        if (printTokens) {\n            tokens.getTokens();\n\n            for (int i=0; i<tokens.size(); i++) {\n                Token token = tokens.get(i);\n                if (token.getChannel() == smaliParser.HIDDEN) {\n                    continue;\n                }\n\n                System.out.println(smaliParser.tokenNames[token.getType()] + \": \" + token.getText());\n            }\n        }\n\n        smaliParser parser = new smaliParser(tokens);\n        parser.setVerboseErrors(verboseErrors);\n\n        smaliParser.smali_file_return result = parser.smali_file();\n\n        if (parser.getNumberOfSyntaxErrors() > 0 || lexer.getNumberOfSyntaxErrors() > 0) {\n            return false;\n        }\n\n        CommonTree t = (CommonTree) result.getTree();\n\n        CommonTreeNodeStream treeStream = new CommonTreeNodeStream(t);\n        treeStream.setTokenStream(tokens);\n\n        smaliTreeWalker dexGen = new smaliTreeWalker(treeStream);\n\n        dexGen.setVerboseErrors(verboseErrors);\n        dexGen.setDexBuilder(dexBuilder);\n        dexGen.smali_file();\n\n        return dexGen.getNumberOfSyntaxErrors() == 0;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/task/ExecutorServicesHelper.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.task;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.Future;\n\n/**\n * Created by lilong on 16/7/14.\n */\npublic class ExecutorServicesHelper {\n    private Integer threadCount;\n    private ExecutorService executorService = null;\n    private Map<String, List<Future<Boolean>>> futureListMap = new ConcurrentHashMap<String, List<Future<Boolean>>>();\n\n\n    public ExecutorServicesHelper() {\n        initExecutorPool();\n    }\n\n\n\n    private synchronized void initExecutorPool() {\n        if (null == executorService) {\n            if (null == threadCount || threadCount <= 0) {\n                threadCount = (Runtime.getRuntime().availableProcessors() / 2) + 1;\n            }\n\n            executorService = Executors.newFixedThreadPool(threadCount);\n        }\n    }\n\n    public synchronized void stop() {\n        if (null != executorService) {\n            executorService.shutdown();\n        }\n    }\n\n\n    public synchronized void submitTask(String taskName, Callable<Boolean> task) {\n        initExecutorPool();\n        Future<Boolean> future = executorService.submit(task);\n        List<Future<Boolean>> futureList = null;\n        if (futureListMap.get(taskName) != null) {\n            futureList = futureListMap.get(taskName);\n        } else {\n            futureList = new ArrayList<Future<Boolean>>();\n        }\n        futureList.add(future);\n        futureListMap.put(taskName, futureList);\n    }\n\n\n    public boolean waitTaskCompleted(String taskName) throws InterruptedException, ExecutionException {\n        List<Future<Boolean>> futureList = futureListMap.get(taskName);\n        boolean flag = true;\n        if (null == futureList) {\n            return true;\n        } else {\n            for (Future<Boolean> future : futureList) {\n                if (!future.get()) {\n                    flag = false;\n                }\n            }\n        }\n        return flag;\n    }\n}\n\n\n\n\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tools/APatchTool.java",
    "content": "package com.taobao.android.tools;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.android.utils.Pair;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.apatch.ApkPatch;\nimport com.taobao.android.apatch.MergePatch;\nimport com.taobao.android.apatch.annotation.MethodReplaceAnnotation;\nimport com.taobao.android.differ.dex.PatchException;\nimport com.taobao.android.inputs.ApatchInput;\nimport com.taobao.android.outputs.APatchFile;\nimport com.taobao.android.outputs.PatchFile;\nimport com.taobao.android.tpatch.model.BundleBO;\nimport com.taobao.android.tpatch.utils.PatchUtils;\nimport com.taobao.android.tpatch.utils.PathUtils;\nimport com.taobao.android.utils.PathMatcher;\nimport com.taobao.android.utils.ZipUtils;\nimport org.antlr.runtime.RecognitionException;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.FilenameUtils;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Map;\n\n\n/**\n * this is tool for generate apatch.jar\n *\n */\npublic class APatchTool extends AbstractTool {\n\n    public static Map<String, String> mappingMap;\n    private final PathMatcher pathMatcher = new PathMatcher();\n\n\n    /**\n     *\n     *\n     * @param newBundleFile\n     * @param baseBundleFile\n     * @param patchTmpDir\n     * @return\n     */\n    private List<File> processBundleFiles(File newBundleFile, File baseBundleFile, File patchTmpDir, File diffFile,\n                                          File diffJsonFile) throws PatchException, IOException, RecognitionException {\n        String bundleName = FilenameUtils.getBaseName(newBundleFile.getName());\n\n        if (!isModifyBundle(newBundleFile.getName()) || !((ApatchInput)input).onlyIncludeModifyBundle) {\n            return null;\n        }\n        if (null != logger) {\n            logger.info(\"[DiffApatch]\" + bundleName);\n        }\n        final File newBundleUnzipFolder = new File(newBundleFile.getParentFile(), bundleName);\n        final File baseBundleUnzipFolder = new File(baseBundleFile.getParentFile(), bundleName);\n\n        if (null != baseBundleFile && baseBundleFile.isFile() && baseBundleFile.exists()) {\n            // unzip apk\n            ZipUtils.unzip(newBundleFile, newBundleUnzipFolder.getAbsolutePath());\n            ZipUtils.unzip(baseBundleFile, baseBundleUnzipFolder.getAbsolutePath());\n            // String patchBundleName = getBundleName(newBundleFile.getName());\n            String patchBundleName = FilenameUtils.getBaseName(newBundleFile.getName().replace(\"lib\", \"\"));\n            if (null != patchBundleName) {\n                patchBundleName = patchBundleName.replace(\".\", \"_\");\n                List<File> bundlePatchs = createBundleAPatch(newBundleUnzipFolder, baseBundleUnzipFolder, patchTmpDir,\n                        patchBundleName, diffFile, diffJsonFile);\n                return bundlePatchs;\n            } else {\n                throw new PatchException(\"Cannot found bundle:\" + newBundleFile.getName() + \" in modifyBundleInfos.\");\n            }\n\n        }\n        return null;\n    }\n\n\n    /**\n     * create bundle apatch file\n     *\n     * @param newApkUnzipFolder\n     * @param baseApkUnzipFolder\n     * @param patchTmpDir\n     * @return\n     * @throws IOException\n     * @throws RecognitionException\n     */\n    private List<File> createBundleAPatch(File newApkUnzipFolder, File baseApkUnzipFolder, File patchTmpDir,\n                                          String bundleName, File diffFile,\n                                          File diffJsonFile) throws IOException, RecognitionException, PatchException {\n        List<File> apatchs = Lists.newArrayList();\n\n        List<File> baseDexFiles = getFolderDexFiles(baseApkUnzipFolder);\n        List<File> newDexFiles = getFolderDexFiles(newApkUnzipFolder);\n        ApkPatch apkPatch = new ApkPatch(baseDexFiles, newDexFiles, bundleName, patchTmpDir);\n        apkPatch.setDiffFile(diffFile);\n        apkPatch.setDiffJsonFile(diffJsonFile);\n        if (null != ((ApatchInput)input).filterPath) {\n            apkPatch.setPath(((ApatchInput)input).filterPath);\n        }\n\n        File mainDexPatch = apkPatch.doPatch();\n        if (null != mainDexPatch && mainDexPatch.exists()) {\n            apatchs.add(mainDexPatch);\n        }\n        return apatchs;\n    }\n\n    @Override\n    public PatchFile doPatch() throws Exception {\n        APatchFile patchFile = new APatchFile();\n        ApatchInput apatchInput = (ApatchInput) input;\n        mappingMap= apatchInput.mappingMap;\n        if (apatchInput.mappingMap.get(apatchInput.replaceAnnotation) != null) {\n            MethodReplaceAnnotation.ANNOTATION = apatchInput.mappingMap.get(apatchInput.replaceAnnotation);\n        }\n        File patchTmpDir = new File(input.outPutFile.getParentFile(), \"apatch-tmp\");\n        patchTmpDir.mkdirs();\n        patchFile.aDiffText = new File(input.outPutFile.getParentFile(), \"apatch-diff.txt\");\n        patchFile.diffJson = new File(input.outPutFile.getParentFile(), \"apatch-diff.json\");\n        FileUtils.deleteQuietly(patchFile.aDiffText);\n        patchFile.aDiffText.createNewFile();\n        // unzip apk\n        File unzipFolder = unzipApk(patchTmpDir);\n        final File newApkUnzipFolder = new File(unzipFolder, NEW_APK_UNZIP_NAME);\n        final File baseApkUnzipFolder = new File(unzipFolder, BASE_APK_UNZIP_NAME);\n\n        // first generate main bundle patch file\n        List<File> aPatches = createBundleAPatch(newApkUnzipFolder, baseApkUnzipFolder, patchTmpDir,\n                apatchInput.andfixMainBundleName, patchFile.aDiffText, patchFile.diffJson);\n\n        // second generate common bundle patch file\n        //\n        Collection<File> soFiles = FileUtils.listFiles(newApkUnzipFolder, new String[]{\"so\"}, true);\n        if (input.splitDiffBundle!= null) {\n            for (Pair<BundleBO, BundleBO> bundle : input.splitDiffBundle) {\n                if (bundle.getFirst() == null||bundle.getSecond() == null){\n                    continue;\n                }\n                List<File> aPatchFiles = processBundleFiles(bundle.getSecond().getBundleFile(), bundle.getFirst().getBundleFile(), patchTmpDir, patchFile.aDiffText, patchFile.diffJson);\n                if (null != aPatchFiles) {\n                    for (File aPatchFile : aPatchFiles) {\n                        if (null != aPatchFile && aPatchFile.exists()) {\n                            aPatches.add(aPatchFile);\n                        }\n                    }\n                }\n            }\n        }\n        for (File soFile : soFiles) {\n            String relativePath = PathUtils.toRelative(newApkUnzipFolder, soFile.getAbsolutePath());\n            if (null != apatchInput.notIncludeFiles && pathMatcher.match(apatchInput.notIncludeFiles, relativePath)) {\n                continue;\n            }\n            File baseSoFile = new File(baseApkUnzipFolder, relativePath);\n            if (PatchUtils.isBundleFile(soFile)) { // if bundle file\n                List<File> aPatchFiles = processBundleFiles(soFile, baseSoFile, patchTmpDir, patchFile.aDiffText, patchFile.diffJson);\n                if (null != aPatchFiles) {\n                    for (File aPatchFile : aPatchFiles) {\n                        if (null != aPatchFile && aPatchFile.exists()) {\n                            aPatches.add(aPatchFile);\n                        }\n                    }\n                }\n            }\n        }\n\n        if (aPatches.size() <= 0) {\n            throw new Exception(\"No apatch files! No classes modify!\");\n        }\n\n        // merge apatch file\n        File[] aPatchFiles = new File[aPatches.size()];\n        aPatchFiles = aPatches.toArray(aPatchFiles);\n        File mergePatchFile = null;\n        if (null != aPatchFiles && aPatchFiles.length > 1) {\n            MergePatch mergePatch = new MergePatch(aPatchFiles, apatchInput.projectArtifactId, patchTmpDir);\n            mergePatchFile = mergePatch.doMerge();\n        } else if (null != aPatchFiles && aPatchFiles.length == 1) {\n            mergePatchFile = aPatchFiles[0];\n        }\n        if (null != mergePatchFile && mergePatchFile.exists()) {\n            FileUtils.moveFile(mergePatchFile, input.outPutFile);\n        }\n        FileUtils.deleteDirectory(unzipFolder);\n        FileUtils.deleteDirectory(patchTmpDir);\n        patchFile.patchFile = input.outPutFile;\n\n        return patchFile;\n    }\n\n    @Override\n    public boolean isRetainMainBundleRes() {\n        return false;\n    }\n\n\n//    public static void main(String []args){\n//        ApkBO apkBO = new ApkBO(new File(\"/Users/lilong/Downloads/xiamimusic-6.0.0-20170518.084443-4-release/android.apk\"),\"1.0.0\",\"aaa\");\n//        ApkBO newApkBO = new ApkBO(new File(\"/Users/lilong/Downloads/xiamiv5-release.apk\"),\"2.0.0\",\"aaa\");\n//        APatchTool aPatchTool = new APatchTool(apkBO,newApkBO);\n//        try {\n//            aPatchTool.doPatch(new File(\"/Users/lilong/Downloads/ccc\"),\"vvv\");\n//        } catch (Exception e) {\n//            e.printStackTrace();\n//        }\n//    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tools/AbstractTool.java",
    "content": "package com.taobao.android.tools;\n\nimport com.alibaba.fastjson.JSON;\nimport com.android.utils.ILogger;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.inputs.BaseInput;\nimport com.taobao.android.inputs.TpatchInput;\nimport com.taobao.android.object.ApkFileList;\nimport com.taobao.android.object.ArtifactBundleInfo;\nimport com.taobao.android.object.DiffType;\nimport com.taobao.android.outputs.PatchFile;\nimport com.taobao.android.utils.CommandUtils;\nimport com.taobao.android.utils.SystemUtils;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.FilenameUtils;\nimport org.apache.commons.lang3.StringUtils;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.URL;\nimport java.net.URLConnection;\nimport java.util.List;\n\n/**\n * @author lilong\n * @create 2017-11-03 上午12:07\n */\n\npublic abstract class AbstractTool {\n\n    protected ILogger logger;\n\n    public static final String BASE_APK_UNZIP_NAME = \"base.apk\";\n    public static final String NEW_APK_UNZIP_NAME = \"new.apk\";\n    protected static final String DEX_NAME = \"classes.dex\";\n    protected static final String DEX_SUFFIX = \".dex\";\n    protected static final String CLASSES = \"classes\";\n    protected static final int DEFAULT_API_LEVEL = 19;\n\n    public void setInput(BaseInput input) {\n        this.input = input;\n    }\n\n    protected BaseInput input;\n\n    public abstract PatchFile doPatch() throws Exception;\n\n    public boolean isModifyBundle(String bundleSoFileName) {\n\n        DiffType diffType = getModifyType(bundleSoFileName);\n\n        if (diffType == DiffType.NONE){\n            return false;\n        }\n        return DiffType.ADD.equals(diffType) || DiffType.MODIFY.equals(diffType);\n\n    }\n\n\n    public DiffType getModifyType(String bundleSoFileName) {\n        for (ArtifactBundleInfo artifactBundleInfo : input.artifactBundleInfos) {\n            String packageName = artifactBundleInfo.getPkgName();\n            if (null == packageName) {\n                return DiffType.NONE;\n            }\n            String bundleName = \"lib\" + packageName.replace('.', '_') + \".so\";\n            if (bundleName.equals(bundleSoFileName)) {\n                if (null != logger) {\n                    logger.info(\"[BundleDiffType]\" + bundleSoFileName + \":\" + artifactBundleInfo.getDiffType());\n                }\n                return artifactBundleInfo.getDiffType();\n            }\n        }\n        return DiffType.NONE;\n    }\n\n\n    public String getBundleName(String bundleSoFileName) {\n        return FilenameUtils.getBaseName(bundleSoFileName.replace(\"lib\", \"\"));\n    }\n\n    public DiffType getMainBundleDiffType() {\n\n        for (ArtifactBundleInfo artifactBundleInfo:input.artifactBundleInfos){\n            if(artifactBundleInfo.getMainBundle()){\n                return artifactBundleInfo.getDiffType();\n            }\n        }\n        return DiffType.NONE;\n    }\n\n\n    public List<File> getFolderDexFiles(File folder) {\n        List<File> dexFiles = Lists.newArrayList();\n        File baseDex = new File(folder, DEX_NAME);\n        if (baseDex.exists()) {\n            dexFiles.add(baseDex);\n            // 比较是否存在着多dex\n            int dexIndex = 2;\n            File newIndexDex = getNextDexFile(folder, dexIndex);\n            while (null != newIndexDex && newIndexDex.exists()) {\n                dexFiles.add(newIndexDex);\n                dexIndex++;\n                newIndexDex = getNextDexFile(folder, dexIndex);\n            }\n        }\n        return dexFiles;\n    }\n\n    /**\n     * unzip 2 apk file\n     *\n     * @param outPatchDir\n     */\n    protected File unzipApk(File outPatchDir) throws IOException {\n        File unzipFolder = new File(outPatchDir, \"unzip\");\n        if (!unzipFolder.exists()){\n            unzipFolder.mkdirs();\n        }\n        File baseApkUnzipFolder = new File(unzipFolder, BASE_APK_UNZIP_NAME);\n        File newApkUnzipFolder = new File(unzipFolder, NEW_APK_UNZIP_NAME);\n        CommandUtils.exec(outPatchDir,\"unzip \"+input.baseApkBo.getApkFile().getAbsolutePath()+\" -d \"+baseApkUnzipFolder.getAbsolutePath());\n\n        if (input.newApkBo.getApkFile().isDirectory()){\n            FileUtils.moveDirectory(input.newApkBo.getApkFile(), newApkUnzipFolder);\n        }else {\n            CommandUtils.exec(outPatchDir,\"unzip \"+input.newApkBo.getApkFile().getAbsolutePath()+\" -d \"+ newApkUnzipFolder.getAbsolutePath());\n        }\n\n        return unzipFolder;\n    }\n\n\n    public void downloadTPath(String httpUrl, File saveFile) throws IOException {\n        if (!saveFile.exists() || !saveFile.isFile()) {\n            downloadFile(httpUrl, saveFile);\n        }\n    }\n\n    /**\n     * http download\n     */\n    private void downloadFile(String httpUrl, File saveFile) throws IOException {\n        // 下载网络文件\n        int bytesum = 0;\n        int byteread = 0;\n        URL url = new URL(httpUrl);\n        URLConnection conn = url.openConnection();\n        InputStream inStream = conn.getInputStream();\n        FileOutputStream fs = new FileOutputStream(saveFile);\n\n        byte[] buffer = new byte[1204];\n        while ((byteread = inStream.read(buffer)) != -1) {\n            bytesum += byteread;\n            fs.write(buffer, 0, byteread);\n        }\n        fs.flush();\n        inStream.close();\n        fs.close();\n    }\n\n    public void setLogger(ILogger logger) {\n        this.logger = logger;\n    }\n\n    public File getNextDexFile(File dexParentFolder, int dexNumber) {\n        return new File(dexParentFolder, CLASSES + dexNumber + DEX_SUFFIX);\n    }\n\n    public File getNextDexFile(File dexParentFolder, int dexNumber, String dexName) {\n        return new File(dexParentFolder, dexName + dexNumber + DEX_SUFFIX);\n    }\n\n    public abstract boolean isRetainMainBundleRes();\n\n\n    /**\n     * 获取新版本的apkFileList\n     *\n     * @return\n     */\n    public ApkFileList getNewApkFileList() {\n        String newApkFileListStr = null;\n        try {\n            if (null != input.newApkFileList && input.newApkFileList.exists()) {\n                newApkFileListStr = FileUtils.readFileToString(input.newApkFileList);\n                if (StringUtils.isNoneBlank(newApkFileListStr)) {\n                    return JSON.parseObject(newApkFileListStr, ApkFileList.class);\n                }\n            }\n        } catch (IOException e) {\n        }\n\n        return null;\n    }\n\n\n\n    /**\n     * get base apkFileList\n     *\n     * @return\n     */\n    public ApkFileList getBaseApkFileList() {\n        String baseApkFileListStr = null;\n        try {\n            if (null != ((TpatchInput)input).baseApkFileList && ((TpatchInput)input).baseApkFileList.exists()) {\n                baseApkFileListStr = FileUtils.readFileToString(((TpatchInput)input).baseApkFileList);\n                if (StringUtils.isNoneBlank(baseApkFileListStr)) {\n                    return JSON.parseObject(baseApkFileListStr, ApkFileList.class);\n                }\n            }\n        } catch (IOException e) {\n        }\n\n        return null;\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tools/DexObfuscatedTool.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.taobao.android.repatch.InsTructionsReIClassDef;\nimport com.taobao.android.repatch.mapping.MappingProcessor;\nimport com.taobao.android.repatch.mapping.MappingProcessorImpl;\nimport com.taobao.android.repatch.mapping.MappingReader;\nimport com.taobao.android.repatch.processor.MappingClassProcessor;\nimport org.jf.dexlib2.DexFileFactory;\nimport org.jf.dexlib2.Opcodes;\nimport org.jf.dexlib2.iface.ClassDef;\nimport org.jf.dexlib2.iface.DexFile;\n\nimport javax.annotation.Nonnull;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\n\n/**\n * Created by lilong on 16/7/23.\n */\npublic class DexObfuscatedTool {\n\n    public Map<String, String> getMap() {\n        return map;\n    }\n\n    public void setMap(Map<String, String> map) {\n        this.map = map;\n    }\n\n    public Map<String,String>map = new HashMap<String, String>();\n\n    public static boolean aliProguard = false;\n\n    public DexObfuscatedTool(File mappingFile) {\n        this.mappingFile = mappingFile;\n        if (mappingFile.getName().equals(\"full-mapping.txt\")){\n            aliProguard = true;\n        }\n    }\n\n    private File mappingFile;\n\n    public void obfuscateDex(File inputFile, File outPutFile) throws IOException {\n        if (mappingFile == null || !mappingFile.exists()) {\n            throw new IOException(\"mapping file is not exits!\");\n\n        }\n        if (inputFile == null || !inputFile.exists()) {\n            throw new IOException(\"input dexFile is not exits!\");\n        }\n        MappingReader mappingReader = null;\n        MappingProcessor mappingProcessor = null;\n        mappingReader = new MappingReader(mappingFile);\n        mappingProcessor = new MappingProcessorImpl(map);\n        mappingReader.pump(mappingProcessor);\n        mappingProcessor.updateMethod();\n        mappingProcessor.updateFieldType();\n        InsTructionsReIClassDef insTructionsReDef = new InsTructionsReIClassDef(new MappingClassProcessor(mappingProcessor));\n        DexFile dFile = DexFileFactory.loadDexFile(inputFile.getAbsolutePath(), Opcodes.getDefault());\n        Set<ClassDef> classes = new HashSet<ClassDef>();\n        classes.addAll(dFile.getClasses());\n        final Set<ClassDef> obfuscateClasses = new HashSet<ClassDef>();\n        for (ClassDef classDef : classes) {\n            obfuscateClasses.add(insTructionsReDef.reClassDef(classDef));\n        }\n        DexFileFactory.writeDexFile(outPutFile.getAbsolutePath(), new DexFile() {\n            @Nonnull\n            @Override\n            public Set<? extends ClassDef> getClasses() {\n                return new AbstractSet<ClassDef>() {\n                    @Nonnull\n                    @Override\n                    public Iterator<ClassDef> iterator() {\n                        return obfuscateClasses.iterator();\n                    }\n\n                    @Override\n                    public int size() {\n                        return obfuscateClasses.size();\n                    }\n                };\n            }\n\n            @Nonnull\n            @Override\n            public Opcodes getOpcodes() {\n                return Opcodes.getDefault();\n            }\n        });\n\n\n    }\n\n//    public static void main(String []args) throws IOException {\n//        DexObfuscatedTool dexObfuscatedTool = new DexObfuscatedTool(new File(\"/Users/lilong/Documents/main_builder/build/intermediates/exploded-ap/full-mapping.txt\"));\n//        dexObfuscatedTool.obfuscateDex(new File(\"/Users/lilong/Documents/main_builder/build/outputs/diff/diffAwbDex/com.taobao.tao.update/update-test/classes.dex\"),new File(\"/Users/lilong/Documents/b.dex\"));\n//    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tools/DexPatchDexTool.java",
    "content": "package com.taobao.android.tools;\n\nimport com.taobao.android.differ.dex.PatchException;\nimport org.jf.dexlib2.iface.ClassDef;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * @author lilong\n * @create 2017-11-07 下午2:42\n */\n\npublic class DexPatchDexTool extends PatchDexTool {\n    private Set<String>excludeClasses = new HashSet<>();\n    private Set<String>patchClasses = new HashSet<>();\n\n    public DexPatchDexTool(List<File> baseDexFiles, List<File> newDexFiles, int apiLevel, Map<String, ClassDef> map, boolean mainBundle) {\n        super(baseDexFiles, newDexFiles, apiLevel, map, mainBundle);\n    }\n\n    public DexPatchDexTool(File baseDex, File newDex, int apiLevel, boolean mainBundle) {\n        super(baseDex, newDex, apiLevel, mainBundle);\n    }\n\n    @Override\n    public Set<ClassDef> createModifyClasses() throws IOException, PatchException {\n        dexDiffer.setTpatch(false);\n        dexDiffer.setExludeClasses(excludeClasses);\n        dexDiffer.setPatchClasses(patchClasses);\n        return super.createModifyClasses();\n    }\n\n    @Override\n    public void setExculdeClasses(Set<String> classes) {\n        this.excludeClasses = classes;\n    }\n\n    @Override\n    public void setPatchClasses(Set<String> classes) {\n        this.patchClasses = classes;\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tools/DexPatchTool.java",
    "content": "package com.taobao.android.tools;\n\nimport com.alibaba.fastjson.JSON;\nimport com.android.utils.Pair;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.differ.dex.BundleDiffResult;\nimport com.taobao.android.inputs.DexPatchInput;\nimport com.taobao.android.inputs.TpatchInput;\nimport com.taobao.android.object.BuildPatchInfos;\nimport com.taobao.android.object.DexDiffInfo;\nimport com.taobao.android.object.PatchInfo;\nimport com.taobao.android.outputs.DexPatchFile;\nimport com.taobao.android.outputs.PatchFile;\nimport com.taobao.android.task.ExecutorServicesHelper;\nimport com.taobao.android.tpatch.model.BundleBO;\nimport com.taobao.android.tpatch.utils.MD5Util;\nimport com.taobao.android.tpatch.utils.PathUtils;\nimport com.taobao.android.utils.CommandUtils;\nimport com.taobao.android.utils.Profiler;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.filefilter.TrueFileFilter;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.concurrent.Callable;\n\n/**\n * @author lilong\n * @create 2017-11-03 上午10:13\n */\n\npublic class DexPatchTool extends TPatchTool {\n\n\n    @Override\n    public PatchFile doPatch() throws Exception {\n\n        TpatchInput tpatchInput = (TpatchInput) input;\n        DexPatchFile tpatchFile = new DexPatchFile();\n        tpatchFile.diffJson = new File(tpatchInput.outPatchDir, \"diff.json\");\n        tpatchFile.patchInfo = new File(tpatchInput.outPatchDir, \"patchInfo.json\");\n        final File patchTmpDir = new File(tpatchInput.outPatchDir, \"dexpatch-tmp\");\n        final File mainDiffFolder = new File(patchTmpDir, tpatchInput.mainBundleName);\n        patchTmpDir.mkdirs();\n        FileUtils.cleanDirectory(patchTmpDir);\n        mainDiffFolder.mkdirs();\n        Profiler.release();\n        Profiler.enter(\"unzip apks\");\n        // unzip apk\n        File unzipFolder = unzipApk(((TpatchInput) input).outPatchDir);\n        final File newApkUnzipFolder = new File(unzipFolder, NEW_APK_UNZIP_NAME);\n        final File baseApkUnzipFolder = new File(unzipFolder, BASE_APK_UNZIP_NAME);\n        Profiler.release();\n        ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper();\n        String taskName = \"diffBundleTask\";\n        //\n\n        Collection<File> soFiles = FileUtils.listFiles(newApkUnzipFolder, new String[] {\"so\"}, true);\n\n        //process remote bumdle\n        if (tpatchInput.splitDiffBundle != null) {\n            for (final Pair<BundleBO, BundleBO> bundle : ((TpatchInput) input).splitDiffBundle) {\n                executorServicesHelper.submitTask(taskName, new Callable<Boolean>() {\n                    @Override\n                    public Boolean call() throws Exception {\n                        processBundleFiles(bundle.getSecond().getBundleFile(), bundle.getFirst().getBundleFile(), patchTmpDir);\n                        return true;\n                    }\n                });\n            }\n        }\n\n\n        Profiler.enter(\"awbspatch\");\n\n        executorServicesHelper.submitTask(taskName, new Callable<Boolean>() {\n            @Override\n            public Boolean call() throws Exception {\n                // 得到主bundle的dex diff文件\n                createBundleDexPatch(newApkUnzipFolder,\n                        baseApkUnzipFolder,\n                        mainDiffFolder,\n                        true);\n\n                return true;\n            }\n        });\n\n        for (final File soFile : soFiles) {\n            System.out.println(\"do dexpatch:\" + soFile.getAbsolutePath());\n            final String relativePath = PathUtils.toRelative(newApkUnzipFolder,\n                    soFile.getAbsolutePath());\n            if (null != tpatchInput.notIncludeFiles && pathMatcher.match(tpatchInput.notIncludeFiles, relativePath)) {\n                continue;\n            }\n            executorServicesHelper.submitTask(taskName, new Callable<Boolean>() {\n\n                @Override\n                public Boolean call() throws Exception {\n                    File destFile = new File(patchTmpDir, tpatchInput.mainBundleName + \"/\" +\n                            relativePath);\n                    File baseSoFile = new File(baseApkUnzipFolder, relativePath);\n                    if (isBundleFile(soFile)) {\n                        processBundleFiles(soFile, baseSoFile, patchTmpDir);\n\n                    }\n\n                    return true;\n                }\n            });\n        }\n\n        executorServicesHelper.waitTaskCompleted(taskName);\n        executorServicesHelper.stop();\n        Profiler.release();\n\n        Profiler.enter(\"ziptpatchfile\");\n        // zip file\n        File patchFile = createDexPatchFile(tpatchInput.outPatchDir, patchTmpDir);\n        tpatchFile.patchFile = patchFile;\n        if (!patchFile.exists()){\n            return null;\n        }\n        PatchInfo curPatchInfo = createBasePatchInfo(patchFile);\n\n\n        Profiler.release();\n        \n\n        Profiler.enter(\"writejson\");\n        BuildPatchInfos buildPatchInfos = new BuildPatchInfos();\n        buildPatchInfos.getPatches().add(curPatchInfo);\n        buildPatchInfos.setBaseVersion(input.baseApkBo.getVersionName());\n        buildPatchInfos.setDiffBundleDex(true);\n\n        FileUtils.writeStringToFile(tpatchInput.outPutJson, JSON.toJSONString(buildPatchInfos));\n        // 删除临时的目录\n        FileUtils.deleteDirectory(patchTmpDir);\n        apkDiff.setBaseApkVersion(input.baseApkBo.getVersionName());\n        apkDiff.setNewApkVersion(input.newApkBo.getVersionName());\n        apkDiff.setBundleDiffResults(bundleDiffResults);\n        boolean newApkFileExist = input.newApkBo.getApkFile().exists() && input.newApkBo.getApkFile().isFile();\n        if (newApkFileExist) {\n            apkDiff.setNewApkMd5(MD5Util.getFileMD5String(input.newApkBo.getApkFile()));\n        }\n        apkDiff.setFileName(input.newApkBo.getApkName());\n        apkPatchInfos.setBaseApkVersion(input.baseApkBo.getVersionName());\n        apkPatchInfos.setNewApkVersion(input.newApkBo.getVersionName());\n        apkPatchInfos.setBundleDiffResults(diffPatchInfos);\n        apkPatchInfos.setFileName(patchFile.getName());\n        apkPatchInfos.setNewApkMd5(MD5Util.getFileMD5String(patchFile));\n        FileUtils.writeStringToFile(tpatchFile.diffJson, JSON.toJSONString(apkDiff));\n        FileUtils.writeStringToFile(tpatchFile.patchInfo, JSON.toJSONString(apkPatchInfos));\n        FileUtils.copyFileToDirectory(tpatchFile.diffJson, tpatchInput.outPatchDir.getParentFile(), true);\n        if (newApkFileExist) {\n            FileUtils.copyFileToDirectory(input.newApkBo.getApkFile(), tpatchInput.outPatchDir.getParentFile(), true);\n        }\n        Profiler.release();\n        logger.warning(Profiler.dump());\n        return tpatchFile;\n    }\n\n    private File createDexPatchFile(File outPatchDir, File patchTmpDir) throws IOException {\n        File mainBundleFoder = new File(patchTmpDir, ((TpatchInput)input).mainBundleName);\n        File mainBundleFile = new File(patchTmpDir, \"lib\"+((TpatchInput)input).mainBundleName.replace(\".\",\"_\") + \".so\");\n        if (FileUtils.listFiles(mainBundleFoder, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE)\n                .size() > 0) {\n            CommandUtils.exec(mainBundleFoder, \"zip -r \" + mainBundleFile.getAbsolutePath() + \" . -x */ -x .*\");\n        }\n        FileUtils.deleteDirectory(mainBundleFoder);\n\n        // 再压缩各自的bundle\n        File patchFile = null;\n\n        patchFile = new File(outPatchDir,\n                input.newApkBo.getVersionName() + \"@\" + input.baseApkBo.getVersionName() + \".tpatch\");\n        if (patchFile.exists()) {\n            FileUtils.deleteQuietly(patchFile);\n        }\n        //        zipBundle(patchTmpDir, patchFile);\n        CommandUtils.exec(patchTmpDir, \"zip -r \" + patchFile.getAbsolutePath() + \" . -x */ -x .*\");\n        FileUtils.deleteDirectory(patchTmpDir);\n        return patchFile;\n\n    }\n\n    @Override\n    public boolean isRetainMainBundleRes() {\n\n        return false;\n    }\n\n\n    @Override\n    public void doBundleResPatch(String bundleName, File destPatchBundleDir, File newBundleUnzipFolder, File baseBundleUnzipFolder) throws IOException {\n\n    }\n\n    @Override\n    public List<File> createBundleDexPatch(File newApkUnzipFolder,\n                                           File baseApkUnzipFolder,\n                                           File mainDiffFolder,\n                                           boolean mainDex) throws Exception {\n        List<File> dexs = Lists.newArrayList();\n        // 比较主bundle的dex\n\n        String bundleName = null;\n        if (mainDex) {\n            bundleName = \"com.taobao.maindex\";\n        } else {\n            bundleName = baseApkUnzipFolder.getName().substring(3).replace(\"_\", \".\");\n        }\n        List<File> baseDexFiles = getFolderDexFiles(baseApkUnzipFolder);\n        List<File> newDexFiles = getFolderDexFiles(newApkUnzipFolder);\n        File dexDiffFile = new File(mainDiffFolder, TPatchTool.DEX_NAME);\n        PatchDexTool dexTool = new DexPatchDexTool(baseDexFiles,\n                newDexFiles,\n                DEFAULT_API_LEVEL,\n                null,\n                mainDex);\n        dexTool.setNewPatch(((DexPatchInput)input).newPatch);\n        dexTool.setExculdeClasses(((DexPatchInput)input).excludeClasses);\n        dexTool.setPatchClasses(((DexPatchInput)input).patchClasses);\n\n        DexDiffInfo dexDiffInfo = dexTool.createPatchDex(mainDiffFolder);\n        if (dexDiffFile.exists()) {\n            dexs.add(dexDiffFile);\n            BundleDiffResult bundleDiffResult = new BundleDiffResult();\n            bundleDiffResult.setBundleName(bundleName);\n            bundleDiffResults.add(bundleDiffResult);\n            diffPatchInfos.add(bundleDiffResult);\n            dexDiffInfo.save(bundleDiffResult);\n        }\n        if (dexs.size() > 0) {\n            bundleTypes.put(bundleName,1);\n        }\n\n        return dexs;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tools/FastPatchTool.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.tools;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.google.common.collect.Lists;\nimport com.taobao.android.apatch.AndFixFilterImpl;\nimport com.taobao.android.apatch.ApkPatch;\nimport com.taobao.android.apatch.FastBuild;\nimport com.taobao.android.apatch.MergePatch;\nimport com.taobao.android.apatch.annotation.MethodReplaceAnnotation;\nimport com.taobao.android.apatch.utils.SmaliDiffUtils;\nimport com.taobao.android.differ.dex.PatchException;\nimport com.taobao.android.object.DexDiffInfo;\nimport com.taobao.android.repatch.FastPatchObject;\nimport com.taobao.android.repatch.InsTructionsReIClassDef;\nimport com.taobao.android.repatch.Utils.DefineUtils;\nimport com.taobao.android.repatch.mapping.MappingProcessor;\nimport com.taobao.android.repatch.mapping.MappingProcessorImpl;\nimport com.taobao.android.repatch.mapping.MappingReader;\nimport com.taobao.android.repatch.processor.MappingClassProcessor;\nimport com.taobao.android.tpatch.utils.SmaliUtils;\nimport org.antlr.runtime.RecognitionException;\nimport org.apache.commons.io.FileUtils;\nimport org.jf.dexlib2.DexFileFactory;\nimport org.jf.dexlib2.Opcodes;\nimport org.jf.dexlib2.dexbacked.DexBackedClassDef;\nimport org.jf.dexlib2.dexbacked.DexBackedMethod;\nimport org.jf.dexlib2.iface.ClassDef;\nimport org.jf.dexlib2.iface.DexFile;\nimport org.jf.dexlib2.iface.Method;\nimport org.jf.dexlib2.immutable.ImmutableDexFile;\n\nimport javax.annotation.Nonnull;\nimport java.io.File;\nimport java.io.IOException;\nimport java.security.KeyStoreException;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.UnrecoverableEntryException;\nimport java.security.cert.CertificateException;\nimport java.util.*;\n\n/**\n * Created by lilong on 16/6/30.\n */\npublic class FastPatchTool {\n\n    private List<FastPatchObject> patchObjects = new ArrayList<FastPatchObject>();\n    private File outDir;\n    private File mappingFile;\n    private String bundleName = \"com_taobao_maindex\";\n    private List<File> patchJarFiles = new ArrayList<File>();\n\n    public Map<String, String> getSuperClassMap() {\n        return superClassMap;\n    }\n\n    public void setSuperClassMap(Map<String, String> superClassMap) {\n        this.superClassMap = superClassMap;\n    }\n\n    private Map<String,String>superClassMap = new HashMap<String, String>();\n    File outPatchFile;\n\n    public void setOutDir(File outDir) {\n        this.outDir = outDir;\n    }\n\n    public void setModifyClasses(List<FastPatchObject> list) {\n        this.patchObjects = list;\n    }\n\n    public void setMappingFile(File mappingFile) {\n        this.mappingFile = mappingFile;\n    }\n\n\n    public void doPatch() throws IOException, PatchException, RecognitionException {\n        MappingReader mappingReader = null;\n        MappingProcessor mappingProcessor = null;\n\n        if (outDir == null || !outDir.exists()) {\n            return;\n        }\n        outPatchFile = new File(outDir, \"apatch-unsigned.apatch\");\n\n        if (mappingFile != null && mappingFile.exists()) {\n            mappingReader = new MappingReader(mappingFile);\n            mappingProcessor = new MappingProcessorImpl(superClassMap);\n            mappingReader.pump(mappingProcessor);\n            mappingProcessor.updateMethod();\n            mappingProcessor.updateFieldType();\n        }\n\n        for (FastPatchObject fastPatchObject : patchObjects) {\n            Set<ClassDef> classes = new HashSet<ClassDef>();\n            Map<ClassDef, List<Method>> patchClassDefs = new HashMap<ClassDef, List<Method>>();\n            Set<ClassDef>addedClasses = new HashSet<ClassDef>();\n            Map<ClassDef, List<Method>> newClassDef = new HashMap<ClassDef, List<Method>>();\n\n            ArrayList<Method> methods = new ArrayList<Method>();\n\n            for (File dexFile : fastPatchObject.DexFiles) {\n                DexFile dFile = DexFileFactory.loadDexFile(dexFile.getAbsolutePath(), Opcodes.getDefault());\n                classes.addAll(dFile.getClasses());\n            }\n            final Set<ClassDef> newClasses = new HashSet<ClassDef>();\n            for (ClassDef classDef : classes) {\n                String type = classDef.getType();\n                if (fastPatchObject.addedClass.contains(SmaliUtils.getDalvikClassName(type))){\n                    System.out.println(\"patch added class:\"+type);\n                    addedClasses.add(classDef);\n                    continue;\n                }\n                for (Map.Entry<String,List<String>> entry : fastPatchObject.modifyClasses.entrySet()) {\n                    if (entry.getKey().equals(SmaliUtils.getDalvikClassName(type))) {\n                        ArrayList<Method> newMethods = new ArrayList<Method>();\n                        for (Method method : classDef.getMethods()) {\n                            System.err.println(getMethodFullName(method));\n                            if (entry.getValue().contains(getMethodFullName(method))) {\n                                newMethods.add(method);\n                            }\n\n                        }\n                        patchClassDefs.put(classDef, newMethods);\n                        break;\n                    }\n                }\n            }\n            if (patchClassDefs.size() == 0&&addedClasses.size() == 0) {\n                continue;\n            }\n\n\n            if (mappingFile != null && mappingFile.exists()) {\n                //第一步先将prepareclass混淆掉\n                for (String className : fastPatchObject.prepareClasses) {\n                    ApkPatch.prepareClasses.add(mappingProcessor.getNewClassName(className).className);\n                }\n                //将replaceanatation混淆掉\n                MethodReplaceAnnotation.ANNOTATION= DefineUtils.getDefineClassName(mappingProcessor.getNewClassName(DefineUtils.getDalvikClassName(\"Lcom/alipay/euler/andfix/annotation/MethodReplace;\")).className,false);\n                //将dex代码混淆掉\n                InsTructionsReIClassDef insTructionsReDef = new InsTructionsReIClassDef(new MappingClassProcessor(mappingProcessor));\n                for (ClassDef c : classes) {\n                    if (patchClassDefs.containsKey(c)) {\n                        for (Method method : c.getMethods()) {\n                            if (patchClassDefs.get(c).contains(method)) {\n                                methods.add(insTructionsReDef.reMethod(method));\n                            }\n                        }\n                        newClassDef.put(insTructionsReDef.reClassDef(c), methods);\n                    }else if (addedClasses.contains(c)){\n                        newClassDef.put(insTructionsReDef.reClassDef(c),new ArrayList<Method>());\n                    }\n                    if (c.getType().contains(\"/R$\")) {\n                        continue;\n                    }\n                    newClasses.add(insTructionsReDef.reClassDef(c));\n                }\n\n            }else {\n                ApkPatch.prepareClasses.addAll(fastPatchObject.prepareClasses);\n            }\n\n            File patchDexFile = new File(outDir, \"patch.dex\");\n            for (ClassDef classDef:newClassDef.keySet()){\n                System.out.println(\"modify class:\"+classDef.getType());\n            }\n            if (newClassDef.size() > 0) {\n                DexFileFactory.writeDexFile(patchDexFile.getAbsolutePath(), new ImmutableDexFile(Opcodes.getDefault(),newClassDef.keySet()));\n            } else if (patchClassDefs.size() > 0) {\n                DexFileFactory.writeDexFile(patchDexFile.getAbsolutePath(), new ImmutableDexFile(Opcodes.getDefault(),patchClassDefs.keySet()));\n            }\n\n            File tempDexFile = new File(outDir, \"temp.dex\");\n            if (newClasses.size() > 0) {\n                DexFileFactory.writeDexFile(tempDexFile.getAbsolutePath(), new DexFile() {\n                    @Nonnull\n                    @Override\n                    public Set<? extends ClassDef> getClasses() {\n                        return new AbstractSet<ClassDef>() {\n                            @Nonnull\n                            @Override\n                            public Iterator<ClassDef> iterator() {\n                                return newClasses.iterator();\n                            }\n\n                            @Override\n                            public int size() {\n                                return newClasses.size();\n                            }\n                        };\n                    }\n\n                    @Nonnull\n                    @Override\n                    public Opcodes getOpcodes() {\n                        return Opcodes.getDefault();\n                    }\n                });\n            } else if (classes.size() > 0) {\n                DexFileFactory.writeDexFile(tempDexFile.getAbsolutePath(), new ImmutableDexFile(Opcodes.getDefault(),classes));\n\n            }\n\n            SmaliDiffUtils.scanClasses(new File(outDir,\"smali2\"), Lists.newArrayList(tempDexFile));\n\n\n\n            DexFile patchDex = DexFileFactory.loadDexFile(patchDexFile.getAbsolutePath(), Opcodes.getDefault());\n            DexFile tempDex = DexFileFactory.loadDexFile(tempDexFile.getAbsolutePath(), Opcodes.getDefault());\n            Set<? extends ClassDef> patchClasses = patchDex.getClasses();\n            DexDiffInfo dexDiffInfo = new DexDiffInfo();\n            for (ClassDef patchClassDef : patchClasses) {\n                String type = patchClassDef.getType();\n                if (fastPatchObject.addedClass.contains(SmaliUtils.getDalvikClassName(type))){\n                    dexDiffInfo.getAddedClasses().add((DexBackedClassDef) patchClassDef);\n                    dexDiffInfo.addManifestAddClass(type);\n                    continue;\n                }\n\n                for (Method method : patchClassDef.getMethods()) {\n                    List<? extends CharSequence> parameters = method.getParameterTypes();\n                    if (methods.size() > 0) {\n                        for (Method modifyMethod : methods) {\n                            List<? extends CharSequence> modifyParameters = modifyMethod.getParameterTypes();\n                            if (parameters.size() != modifyParameters.size()||!isEqualObj(parameters,modifyParameters)){\n                                continue;\n                            }\n\n                            if (modifyMethod.getName().equals(method.getName()))\n                                dexDiffInfo.addModifiedMethods((DexBackedMethod) method);\n                        }\n                    } else if (patchClassDefs.size() > 0) {\n                        for (ClassDef classDef : patchClassDefs.keySet()) {\n                            if (classDef.getType().equals(patchClassDef.getType())) {\n                                List<Method> methodList = patchClassDefs.get(classDef);\n                                for (Method method1 : methodList) {\n                                    if (method1.getName().equals(method.getName())) {\n                                        dexDiffInfo.addModifiedMethods((DexBackedMethod) method);\n                                    }\n                                }\n                            }\n                        }\n\n\n                    }\n                }\n            }\n            FastBuild fastBuild = new FastBuild(fastPatchObject.bundleName, new File(outDir,bundleName));\n            fastBuild.setClasses(tempDex.getClasses());\n            fastBuild.setDiffInfo(dexDiffInfo);\n            new AndFixFilterImpl(dexDiffInfo).filterDex();\n            dexDiffInfo.update();\n            File adiffFile = new File(outDir, \"apatch-diff.txt\");\n            File adiffJsonFile = new File(outDir, \"apatch-diff.json\");\n            dexDiffInfo.writeToFile(fastPatchObject.bundleName,adiffFile,adiffJsonFile);\n            try {\n                File patchJarFile = fastBuild.dopatch();\n                patchJarFiles.add(patchJarFile);\n            } catch (CertificateException e) {\n                e.printStackTrace();\n            } catch (NoSuchAlgorithmException e) {\n                e.printStackTrace();\n            } catch (KeyStoreException e) {\n                e.printStackTrace();\n            } catch (UnrecoverableEntryException e) {\n                e.printStackTrace();\n            }\n        }\n\n        File[] aPatchFiles = new File[patchJarFiles.size()];\n        aPatchFiles = patchJarFiles.toArray(aPatchFiles);\n        File mergePatchFile = null;\n        if (null != aPatchFiles && aPatchFiles.length > 1) {\n            MergePatch mergePatch = new MergePatch(aPatchFiles, \"com_taobao_android\", outDir);\n            mergePatchFile = mergePatch.doMerge();\n        } else if (null != aPatchFiles && aPatchFiles.length == 1) {\n            mergePatchFile = aPatchFiles[0];\n        }\n        if (null != mergePatchFile && mergePatchFile.exists()) {\n            FileUtils.moveFile(mergePatchFile, outPatchFile);\n        }\n\n    }\n\n    private String getMethodFullName(Method method) {\n        StringBuilder stringBuilder = new StringBuilder();\n        String methodName = method.getName();\n        stringBuilder.append(methodName).append(\"(\");\n        for (CharSequence c:method.getParameterTypes()){\n            stringBuilder.append(c);\n        }\n        stringBuilder.append(\")\").append(method.getReturnType());\n        return stringBuilder.toString();\n\n    }\n\n    private boolean isEqualObj(List<? extends CharSequence> parameters, List<? extends CharSequence> modifyParameters) {\n        if (parameters.size() != modifyParameters.size()){\n            return false;\n        }\n        if (!parameters.toString().equals(modifyParameters.toString())){\n            return false;\n        }\n\n        return true;\n\n    }\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tools/HotDexPatchDexTool.java",
    "content": "package com.taobao.android.tools;\n\nimport com.taobao.android.dex.util.FileUtils;\nimport com.taobao.android.differ.dex.PatchException;\nimport com.taobao.android.object.DexDiffInfo;\nimport com.taobao.android.tpatch.utils.SmaliUtils;\nimport org.antlr.runtime.RecognitionException;\nimport org.jf.dexlib2.iface.ClassDef;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.util.*;\n\n/**\n * @author lilong\n * @create 2017-11-07 下午2:42\n */\n\npublic class HotDexPatchDexTool extends DexPatchDexTool {\n\n    private static final String HOT_DEXNAME = \"hot-diff.dex\";\n\n    private Set<ClassDef>hotClassDefs;\n\n    public HotDexPatchDexTool(List<File> baseDexFiles, List<File> newDexFiles, int apiLevel, Map<String, ClassDef> map, boolean mainBundle) {\n        super(baseDexFiles, newDexFiles, apiLevel, map, mainBundle);\n    }\n\n    public HotDexPatchDexTool(File baseDex, File newDex, int apiLevel, boolean mainBundle) {\n        super(baseDex, newDex, apiLevel, mainBundle);\n    }\n\n    @Override\n    public Set<ClassDef> createModifyClasses() throws IOException, PatchException {\n        dexDiffer.setTpatch(false);\n        Set<ClassDef>mClasses =  super.createModifyClasses();\n        if (hotClassList == null || hotClassList.size() == 0){\n            return mClasses;\n        }\n        hotClassDefs = new HashSet<>();\n        Iterator<ClassDef>iterator = mClasses.iterator();\n        while (iterator.hasNext()) {\n            ClassDef classDef = iterator.next();\n            if (hotClassList.contains(classDef.getType()) || hotClassList.contains(SmaliUtils.getDalvikClassName(classDef.getType()))) {\n                    hotClassDefs.add(classDef);\n                    iterator.remove();\n                }\n        }\n        return mClasses;\n\n    }\n\n    @Override\n    public DexDiffInfo createPatchDex(File outDexFolder) throws IOException, RecognitionException, PatchException {\n        DexDiffInfo dexDiffInfo = super.createPatchDex(outDexFolder);\n        File hotDex = new File(outDexFolder,\"hot.dex\");\n        if (hotClassDefs!= null && hotClassDefs.size() > 0){\n            File hotDexFolder = new File(outDexFolder,\"hot\");\n            hotDexFolder.mkdirs();\n            writeDex(hotDexFolder,hotClassDefs);\n            if (new File(hotDexFolder,TPatchTool.DEX_NAME).exists()){\n                new File(hotDexFolder,TPatchTool.DEX_NAME).renameTo(hotDex);\n                org.apache.commons.io.FileUtils.deleteDirectory(hotDexFolder);\n            }\n\n        }\n        return dexDiffInfo;\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tools/HotPatchTool.java",
    "content": "package com.taobao.android.tools;\n\nimport com.taobao.android.differ.dex.BundleDiffResult;\nimport com.taobao.android.inputs.HotPatchInput;\nimport com.taobao.android.inputs.TpatchInput;\nimport com.taobao.android.object.DexDiffInfo;\nimport org.apache.commons.io.FileUtils;\n\nimport java.io.*;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * @author lilong\n * @create 2017-11-07 下午2:16\n */\n\npublic class HotPatchTool extends DexPatchTool {\n\n\n        private Set<String>hotClassList = new HashSet<>();\n\n        @Override\n        public List<File> createBundleDexPatch(File newApkUnzipFolder,\n                File baseApkUnzipFolder,\n                File destDexFolder,\n        boolean mainDex) throws Exception {\n            if (input instanceof HotPatchInput){\n                readClassFile(((HotPatchInput) input).hotClassListFile);\n            }\n            boolean hasDexPatch = false;\n            boolean hasHotDexPatch = false;\n            List<File>dexs = new ArrayList<>();\n\n            String bundleName = null;\n            if (mainDex){\n                bundleName = \"com.taobao.maindex\";\n            }else {\n                bundleName = baseApkUnzipFolder.getName().substring(3).replace(\"_\", \".\");\n            }\n            List<File> baseDexFiles = getFolderDexFiles(baseApkUnzipFolder);\n            List<File> newDexFiles = getFolderDexFiles(newApkUnzipFolder);\n            File hotdestDexFile = null;\n            if (mainDex) {\n                hotdestDexFile = new File(destDexFolder, \"hot.dex\");\n            }else {\n                hotdestDexFile = new File(destDexFolder, \"hot.dex\");\n\n            }\n            PatchDexTool dexTool = new HotDexPatchDexTool(baseDexFiles,\n                    newDexFiles,\n                    DEFAULT_API_LEVEL,\n                    null,\n                    mainDex);\n            dexTool.setNewPatch(((HotPatchInput)input).newPatch);\n            dexTool.setExculdeClasses(((HotPatchInput)input).excludeClasses);\n            dexTool.setPatchClassList(hotClassList);\n            DexDiffInfo dexDiffInfo = dexTool.createPatchDex(destDexFolder);\n            if (destDexFolder.exists() && destDexFolder.listFiles()!= null) {\n                File dexDiffFile = new File(destDexFolder,TPatchTool.DEX_NAME);\n                hasDexPatch = true;\n                BundleDiffResult bundleDiffResult = new BundleDiffResult();\n                bundleDiffResult.setBundleName(bundleName);\n                bundleDiffResults.add(bundleDiffResult);\n                diffPatchInfos.add(bundleDiffResult);\n                dexDiffInfo.save(bundleDiffResult);\n                dexs.add(dexDiffFile);\n\n            }\n            if (hotdestDexFile.exists()){\n                dexs.add(hotdestDexFile);\n                hasHotDexPatch = true;\n\n            }\n            if (hasDexPatch&&!hasHotDexPatch){\n                bundleTypes.put(bundleName,1);\n            }else if (hasDexPatch && hasHotDexPatch){\n                bundleTypes.put(bundleName,3);\n            }else if (!hasDexPatch && hasHotDexPatch){\n                bundleTypes.put(bundleName,2);\n            }\n\n            return dexs;\n           }\n\n    private void readClassFile(File hotClassListFile) throws IOException {\n        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(hotClassListFile)));\n        String line = null;\n        while ((line = bufferedReader.readLine())!= null){\n            hotClassList.add(line);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tools/PatchDexTool.java",
    "content": "package com.taobao.android.tools;\n\nimport com.google.common.collect.Lists;\nimport com.taobao.android.differ.dex.DexDiffer;\nimport com.taobao.android.differ.dex.PatchException;\nimport com.taobao.android.filter.DexDiffFilter;\nimport com.taobao.android.object.ClassDiffInfo;\nimport com.taobao.android.object.DexDiffInfo;\nimport com.taobao.android.object.DiffType;\nimport org.antlr.runtime.RecognitionException;\nimport org.apache.commons.io.FileUtils;\nimport org.jf.dexlib2.DexFileFactory;\nimport org.jf.dexlib2.Opcodes;\nimport org.jf.dexlib2.iface.ClassDef;\nimport org.jf.dexlib2.iface.DexFile;\nimport org.jf.dexlib2.writer.io.FileDataStore;\nimport org.jf.dexlib2.writer.pool.BasePool;\nimport org.jf.dexlib2.writer.pool.DexPool;\n\nimport javax.annotation.Nonnull;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.function.Consumer;\n\n/**\n * tpatch diff tool\n *\n /**\n * Created by lilong on 16/6/17.\n */\n\npublic abstract class PatchDexTool {\n\n    private List<File> baseDexFiles;\n    private List<File> newDexFiles;\n    private int apiLevel;\n    public DexDiffer dexDiffer;\n    private DexDiffFilter dexDiffFilter;\n    public Set<String>hotClassList;\n    DexDiffInfo dexDiffInfo = null;\n    private boolean mainBundle;\n    private static final int MAX_COUNT = 64000;\n    private Map<String, ClassDef>lastBundleClassMap = new HashMap<String, ClassDef>();\n\n    public void setTPatch(boolean tpatch) {\n        this.tpatch = tpatch;\n    }\n\n    private boolean tpatch;\n\n    public boolean isNewPatch() {\n        return newPatch;\n    }\n\n    public void setNewPatch(boolean newPatch) {\n        this.newPatch = newPatch;\n    }\n\n    private boolean newPatch = true;\n\n    public PatchDexTool(List<File> baseDexFiles, List<File> newDexFiles, int apiLevel, Map<String,ClassDef> map,boolean mainBundle) {\n        this.baseDexFiles = baseDexFiles;\n        this.newDexFiles = newDexFiles;\n        this.apiLevel = apiLevel;\n        this.mainBundle = mainBundle;\n        assert (null != baseDexFiles && baseDexFiles.size() > 0);\n        assert (null != newDexFiles && newDexFiles.size() > 0);\n        this.dexDiffer = new DexDiffer(baseDexFiles, newDexFiles, apiLevel);\n        if (map == null) {\n            dexDiffer.setLastBundleClassMap(lastBundleClassMap);\n        }else {\n            dexDiffer.setLastBundleClassMap(map);\n        }\n\n\n    }\n\n    public PatchDexTool(File baseDex, File newDex, int apiLevel,boolean mainBundle) {\n        baseDexFiles = Lists.newArrayList();\n        baseDexFiles.add(baseDex);\n        newDexFiles = Lists.newArrayList();\n        newDexFiles.add(newDex);\n        this.mainBundle = mainBundle;\n        this.dexDiffer = new DexDiffer(baseDex, newDex, apiLevel);\n        dexDiffer.setLastBundleClassMap(lastBundleClassMap);\n\n    }\n\n    public void setDexDiffFilter(DexDiffFilter dexDiffFilter) {\n        this.dexDiffFilter = dexDiffFilter;\n        this.dexDiffer.setDexDiffFilter(dexDiffFilter);\n    }\n\n    /**\n     * 生成淘宝的动态部署的patch的Dex文件\n     *\n     * @param outDexFile\n     */\n\n\n    public Set<ClassDef> createModifyClasses() throws IOException, PatchException {\n        dexDiffer.setNewPatch(newPatch);\n        dexDiffInfo = dexDiffer.doDiff();\n        final Set<ClassDef> modifyClasses = new HashSet<ClassDef>();\n        for (ClassDiffInfo classDiffInfo : dexDiffInfo.getClassDiffInfoMap().values()) {\n            if (DiffType.MODIFY.equals(classDiffInfo.getType()) || DiffType.ADD.equals(classDiffInfo.getType()) || DiffType.OVERRIDE.equals(classDiffInfo.getType())) {\n                modifyClasses.add(classDiffInfo.getClassDef());\n            }\n        }\n        return modifyClasses;\n\n    }\n\n    public DexDiffInfo createPatchDex(File outDexFolder) throws IOException, RecognitionException, PatchException {\n         Set<ClassDef>modifyClasses = createModifyClasses();\n            if (modifyClasses.size() > 0) {\n                writeDex(outDexFolder,modifyClasses);\n                writePatchInfo(outDexFolder);\n\n            }\n        return dexDiffInfo;\n    }\n\n    public void writeDex(File outDexFolder,Set<ClassDef>classDefs) throws IOException {\n        int i = 0 ;\n        File outDexFile = getDexFile(outDexFolder,i);\n        if (!outDexFile.getParentFile().exists()){\n            outDexFile.getParentFile().mkdirs();\n        }\n        if (mainBundle){\n            List<ClassDef> sortClassDefs = sort(classDefs);\n            DexPool dexPool = new DexPool(Opcodes.getDefault());\n            Iterator<ClassDef>iterator = sortClassDefs.iterator();\n            while (iterator.hasNext()) {\n                ClassDef classDef = iterator.next();\n                    dexPool.internClass(classDef);\n                    if (((BasePool)dexPool.methodSection).getItemCount() > MAX_COUNT||((BasePool)dexPool.fieldSection).getItemCount() > MAX_COUNT){\n                        dexPool.writeTo(new FileDataStore(outDexFile));\n                        outDexFile = getDexFile(outDexFolder,++i);\n                        dexPool = new DexPool(Opcodes.getDefault());\n                    }\n            }\n            dexPool.writeTo(new FileDataStore(outDexFile));\n\n\n        }else {\n            DexFileFactory.writeDexFile(outDexFile.getAbsolutePath(), new DexFile() {\n                @Nonnull\n                @Override\n                public Set<? extends ClassDef> getClasses() {\n                    return new AbstractSet<ClassDef>() {\n                        @Nonnull\n                        @Override\n                        public Iterator<ClassDef> iterator() {\n                            return classDefs.iterator();\n                        }\n\n                        @Override\n                        public int size() {\n                            return classDefs.size();\n                        }\n                    };\n                }\n\n                @Nonnull\n                @Override\n                public Opcodes getOpcodes() {\n                    return Opcodes.getDefault();\n                }\n            });\n        }\n\n    }\n\n    private void writePatchInfo(File outDexFolder) {\n        File patchInfo = new File(outDexFolder,TPatchTool.DEX_PATCH_META);\n        Collections.sort(dexDiffer.getDiffClasses());\n        try {\n            FileUtils.writeLines(patchInfo,dexDiffer.getDiffClasses());\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n\n    }\n\n    private List<ClassDef> sort(Set<ClassDef> classDefs){\n        List<ClassDef>lastDexClasses = new ArrayList<>();\n        classDefs.forEach(classDef -> {\n            if (classDef.getType().equals(\"Landroid/taobao/atlas/framework/FrameworkProperties;\")||classDef.getType().equals(\"Landroid/taobao/atlas/bundleInfo/AtlasBundleInfoGenerator;\")){\n                lastDexClasses.add(classDef);\n            }\n        });\n        classDefs.removeAll(lastDexClasses);\n\n        classDefs.forEach(classDef -> lastDexClasses.add(0,classDef));\n\n        return lastDexClasses;\n    }\n\n    private File getDexFile(File dexFolder,int i) {\n\n        return new File(dexFolder,TPatchTool.CLASSES+(i==0?\"\":i)+TPatchTool.DEX_SUFFIX);\n    }\n\n    public void setPatchClassList(Set<String> hotClassList){\n        this.hotClassList = hotClassList;\n    }\n\n    public abstract void setExculdeClasses(Set<String>classes);\n\n    public abstract void setPatchClasses(Set<String>classes);\n\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tools/PatchFieldTool.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Iterables;\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Sets;\nimport com.taobao.android.tpatch.utils.SmaliUtils;\nimport org.antlr.runtime.RecognitionException;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.jf.dexlib2.AccessFlags;\nimport org.jf.dexlib2.DexFileFactory;\nimport org.jf.dexlib2.Opcodes;\nimport org.jf.dexlib2.builder.MutableMethodImplementation;\nimport org.jf.dexlib2.dexbacked.DexBackedClassDef;\nimport org.jf.dexlib2.iface.*;\nimport org.jf.dexlib2.immutable.ImmutableClassDef;\nimport org.jf.dexlib2.immutable.ImmutableField;\nimport org.jf.dexlib2.immutable.ImmutableMethod;\nimport org.jf.dexlib2.rewriter.*;\n\nimport javax.annotation.Nonnull;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\n\n/**\n * Created by lilong on 16/6/18.\n */\npublic class PatchFieldTool {\n\n    private static final Set<ClassDef> classes = Sets.newConcurrentHashSet();\n\n    public static void addField(String srcDexFile, String outDexFile, ImmutableField immutableField) throws IOException {\n        addField(srcDexFile, outDexFile, null, immutableField);\n\n    }\n\n    public static void addField(String inFile, String outFile, DexBackedClassDef dexBackedClassDef, ImmutableField immutableField) throws IOException {\n\n        DexFile dexFile = readDexFile(inFile);\n        for (ClassDef classDef : dexFile.getClasses()) {\n            if (dexBackedClassDef != null && dexBackedClassDef.getType().equals(classDef.getType())) {\n                dexFile = addField(dexFile, classDef.getType(), immutableField);\n            } else if (dexBackedClassDef == null) {\n                dexFile = addField(dexFile, classDef.getType(), immutableField);\n\n            }\n        }\n        reDexFile(dexFile);\n\n        DexFileFactory.writeDexFile(outFile, new DexFile() {\n            @Nonnull\n            @Override\n            public Set<? extends ClassDef> getClasses() {\n                return new AbstractSet<ClassDef>() {\n                    @Nonnull\n                    @Override\n                    public Iterator<ClassDef> iterator() {\n                        return classes.iterator();\n                    }\n\n                    @Override\n                    public int size() {\n                        return classes.size();\n                    }\n                };\n            }\n\n            @Nonnull\n            @Override\n            public Opcodes getOpcodes() {\n                return Opcodes.getDefault();\n            }\n        });\n    }\n\n    public static DexFile addField(DexFile dexFile, final String className, final Field field) {\n        DexRewriter rewriter = new DexRewriter(new RewriterModule() {\n            @Nonnull\n            @Override\n            public Rewriter<ClassDef> getClassDefRewriter(@Nonnull Rewriters rewriters) {\n                return new ClassDefRewriter(rewriters) {\n                    @Nonnull\n                    @Override\n                    public ClassDef rewrite(@Nonnull ClassDef classDef) {\n                        if (classDef.getType().equals(className)) {\n                            return new RewrittenClassDef(classDef) {\n                                @Nonnull\n                                @Override\n                                public Iterable<? extends Field> getInstanceFields() {\n                                    if ((field.getAccessFlags() & AccessFlags.STATIC.getValue()) == 0) {\n                                        return Iterables.concat(super.getInstanceFields(), ImmutableList.of(field));\n                                    }\n                                    return super.getInstanceFields();\n                                }\n\n                                @Nonnull\n                                @Override\n                                public Iterable<? extends Field> getStaticFields() {\n                                    if ((field.getAccessFlags() & AccessFlags.STATIC.getValue()) != 0) {\n                                        return Iterables.concat(super.getStaticFields(), ImmutableList.of(field));\n                                    }\n                                    return super.getStaticFields();\n                                }\n                            };\n                        }\n                        return super.rewrite(classDef);\n                    }\n                };\n            }\n        });\n\n        return rewriter.rewriteDexFile(dexFile);\n    }\n\n    private static DexFile readDexFile(String fileName) throws IOException {\n        File srcFile = new File(fileName);\n        return DexFileFactory.loadDexFile(srcFile, Opcodes.getDefault());\n    }\n\n    private static void reDexFile(@Nonnull DexFile dexFile) {\n        for (ClassDef classDef : dexFile.getClasses()) {\n            classes.add(reDexClass(classDef));\n        }\n    }\n\n    private static ClassDef reDexClass(@Nonnull ClassDef classDef) {\n        return new ImmutableClassDef(classDef.getType(),\n                classDef.getAccessFlags(),\n                classDef.getSuperclass(),\n                classDef.getInterfaces(),\n                classDef.getSourceFile(),\n                classDef.getAnnotations(),\n                classDef.getFields(),\n                reDexMethods(classDef));\n    }\n\n    private static List<Method> reDexMethods(@Nonnull ClassDef classDef) {\n        List<Method> taintedMethods = Lists.newArrayList();\n        for (Method method : classDef.getMethods()) {\n            MethodImplementation implementation = method.getImplementation();\n            MutableMethodImplementation mutableImplementation = new MutableMethodImplementation(implementation);\n            taintedMethods.add(new ImmutableMethod(\n                    method.getDefiningClass(),\n                    method.getName(),\n                    method.getParameters(),\n                    method.getReturnType(),\n                    method.getAccessFlags(),\n                    method.getAnnotations(),\n                    mutableImplementation));\n        }\n        return taintedMethods;\n    }\n\n    /**\n     * relace const string in dexFile\n     *\n     * @param dexFile\n     * @param outDexFile\n     * @param orgFieldValue\n     * @param newFieldValue\n     * @return\n     */\n    public static boolean modifyFieldValue(File dexFile, File outDexFile, String orgFieldValue,\n                                           String newFieldValue) throws IOException, RecognitionException {\n        File smaliFolder = new File(outDexFile.getParentFile(), \"smali\");\n        if (smaliFolder.exists()) {\n            FileUtils.deleteDirectory(smaliFolder);\n        }\n        smaliFolder.mkdirs();\n        boolean disassembled = SmaliUtils.disassembleDexFile(dexFile, smaliFolder);\n        if (disassembled) {\n            Collection<File> smaliFiles = FileUtils.listFiles(smaliFolder, new String[]{\"smali\"}, true);\n            for (File smaliFile : smaliFiles) {\n                List<String> lines = FileUtils.readLines(smaliFile);\n                for (int index = 0; index < lines.size(); index++) {\n                    String line = lines.get(index);\n                    String newLine = StringUtils.replace(line, \"\\\"\" + orgFieldValue + \"\\\"\", \"\\\"\" + newFieldValue + \"\\\"\");\n                    lines.set(index, newLine);\n                }\n                FileUtils.writeLines(smaliFile, lines);\n            }\n\n            //转换为dex文件\n            boolean assembled = SmaliUtils.assembleSmaliFile(smaliFolder, outDexFile);\n            if (assembled) {\n                FileUtils.deleteDirectory(smaliFolder);\n                return true;\n            }\n        }\n        return false;\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tools/PatchMethodTool.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.tools;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Sets;\nimport org.jf.dexlib2.DexFileFactory;\nimport org.jf.dexlib2.Opcode;\nimport org.jf.dexlib2.Opcodes;\nimport org.jf.dexlib2.builder.BuilderInstruction;\nimport org.jf.dexlib2.builder.MutableMethodImplementation;\nimport org.jf.dexlib2.builder.instruction.BuilderInstruction21c;\nimport org.jf.dexlib2.builder.instruction.BuilderInstruction35c;\nimport org.jf.dexlib2.dexbacked.DexBackedClassDef;\nimport org.jf.dexlib2.iface.ClassDef;\nimport org.jf.dexlib2.iface.DexFile;\nimport org.jf.dexlib2.iface.Method;\nimport org.jf.dexlib2.iface.MethodImplementation;\nimport org.jf.dexlib2.immutable.ImmutableClassDef;\nimport org.jf.dexlib2.immutable.ImmutableMethod;\nimport org.jf.dexlib2.immutable.reference.ImmutableMethodReference;\nimport org.jf.dexlib2.immutable.reference.ImmutableStringReference;\n\nimport javax.annotation.Nonnull;\nimport java.io.IOException;\nimport java.util.AbstractSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * Created by lilong on 16/6/18.\n */\npublic class PatchMethodTool {\n\n    public static void modifyMethod(String srcDexFile, String outDexFile, boolean isAndFix) throws IOException {\n\n        DexFile dexFile = DexFileFactory.loadDexFile(srcDexFile, Opcodes.getDefault());\n\n        final Set<ClassDef> classes = Sets.newConcurrentHashSet();\n\n        for (ClassDef classDef : dexFile.getClasses()) {\n            Set<Method> methods = Sets.newConcurrentHashSet();\n            boolean modifiedMethod = false;\n            for (Method method : classDef.getMethods()) {\n                    MethodImplementation implementation = method.getImplementation();\n                    if (implementation != null&&(methodNeedsModification(classDef, method, isAndFix))) {\n                        modifiedMethod = true;\n                        methods.add(new ImmutableMethod(\n                                method.getDefiningClass(),\n                                method.getName(),\n                                method.getParameters(),\n                                method.getReturnType(),\n                                method.getAccessFlags(),\n                                method.getAnnotations(),\n                                isAndFix ?\n                                        modifyMethodAndFix(implementation, method) : modifyMethodTpatch(implementation, method)));\n                    } else {\n                        methods.add(method);\n                    }\n                }\n            if (!modifiedMethod) {\n                classes.add(classDef);\n            } else {\n                classes.add(new ImmutableClassDef(\n                        classDef.getType(),\n                        classDef.getAccessFlags(),\n                        classDef.getSuperclass(),\n                        classDef.getInterfaces(),\n                        classDef.getSourceFile(),\n                        classDef.getAnnotations(),\n                        classDef.getFields(),\n                        methods));\n            }\n\n        }\n\n        DexFileFactory.writeDexFile(outDexFile, new DexFile() {\n            @Nonnull\n            @Override\n            public Set<? extends ClassDef> getClasses() {\n                return new AbstractSet<ClassDef>() {\n                    @Nonnull\n                    @Override\n                    public Iterator<ClassDef> iterator() {\n                        return classes.iterator();\n                    }\n\n                    @Override\n                    public int size() {\n                        return classes.size();\n                    }\n                };\n            }\n\n            @Nonnull\n            @Override\n            public Opcodes getOpcodes() {\n                return Opcodes.getDefault();\n            }\n        });\n    }\n\n    private static boolean methodNeedsModification(@Nonnull ClassDef classDef, @Nonnull Method method, boolean isAndFix) {\n\n        if (isAndFix) {\n            return true;\n        } else if (method.getName().equals(\"<init>\")) {\n            return true;\n        }\n        return false;\n\n    }\n\n    private static MethodImplementation modifyMethodAndFix(@Nonnull MethodImplementation implementation, Method method) {\n        MutableMethodImplementation mutableImplementation = new MutableMethodImplementation(implementation);\n        System.out.println(mutableImplementation.getRegisterCount());\n        List<BuilderInstruction> instructions = mutableImplementation.getInstructions();\n        mutableImplementation.addInstruction(0,\n                new BuilderInstruction21c(Opcode.CONST_STRING, 0,\n                        new ImmutableStringReference(\"AndFix:\" + method.getDefiningClass().replace(\"/\", \".\"))));\n        mutableImplementation.addInstruction(1,\n                new BuilderInstruction35c(Opcode.INVOKE_STATIC, 1,\n                        0, 0, 0, 0, 0,\n                        new ImmutableMethodReference(\"Landroid/util/Log;\", \"e\",\n                                Lists.newArrayList(\"Ljava/lang/String;\", \"Ljava/lang/String;\"), \"I\")));\n\n        return mutableImplementation;\n    }\n\n\n    private static MethodImplementation modifyMethodTpatch(@Nonnull MethodImplementation implementation, Method method) {\n        MutableMethodImplementation mutableImplementation = new MutableMethodImplementation(implementation);\n        System.out.println(mutableImplementation.getRegisterCount());\n        List<BuilderInstruction> instructions = mutableImplementation.getInstructions();\n        boolean isModified = false;\n        for (int i = 0; i < instructions.size(); i++) {\n            isModified = false;\n            if (instructions.get(i).getOpcode() == Opcode.INVOKE_DIRECT) {\n                if (!isModified) {\n                    mutableImplementation.addInstruction(i++,\n                            new BuilderInstruction21c(Opcode.CONST_STRING, 0,\n                                    new ImmutableStringReference(\"tpatch:\" + method.getDefiningClass().replace(\"/\", \".\"))));\n                    mutableImplementation.addInstruction(i++,\n                            new BuilderInstruction35c(Opcode.INVOKE_STATIC, 1,\n                                    0, 0, 0, 0, 0,\n                                    new ImmutableMethodReference(\"Landroid/util/Log;\", \"e\",\n                                            Lists.newArrayList(\"Ljava/lang/String;\", \"Ljava/lang/String;\"), \"I\")));\n                    isModified = true;\n                    break;\n\n                }\n\n            }\n//            mutableImplementation.addInstruction(instructions.get(i));\n        }\n\n        return mutableImplementation;\n    }\n\n    public static void addMethod(String srcDexFile, String outDexFile, DexBackedClassDef dexBackedClassDef, ImmutableMethod immutableMethod) throws IOException {\n\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tools/TPatchTool.java",
    "content": "package com.taobao.android.tools;\n\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport java.io.*;\nimport java.sql.Date;\nimport java.util.*;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.atomic.AtomicReference;\nimport java.util.function.Consumer;\nimport java.util.function.UnaryOperator;\nimport java.util.jar.Attributes;\nimport java.util.jar.JarOutputStream;\nimport java.util.jar.Manifest;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\nimport com.alibaba.fastjson.JSON;\n\nimport com.android.utils.Pair;\nimport com.google.common.collect.Lists;\nimport com.taobao.android.differ.dex.ApkDiff;\nimport com.taobao.android.differ.dex.BundleDiffResult;\nimport com.taobao.android.differ.dex.PatchException;\nimport com.taobao.android.inputs.TpatchInput;\nimport com.taobao.android.object.*;\nimport com.taobao.android.outputs.PatchFile;\nimport com.taobao.android.outputs.TpatchFile;\nimport com.taobao.android.task.ExecutorServicesHelper;\nimport com.taobao.android.tpatch.builder.PatchFileBuilder;\nimport com.taobao.android.tpatch.manifest.AndroidManifestDiffFactory;\nimport com.taobao.android.tpatch.model.BundleBO;\nimport com.taobao.android.tpatch.utils.HttpClientUtils;\nimport com.taobao.android.tpatch.utils.MD5Util;\nimport com.taobao.android.tpatch.utils.PatchUtils;\nimport com.taobao.android.tpatch.utils.PathUtils;\nimport com.taobao.android.utils.CommandUtils;\nimport com.taobao.android.utils.PathMatcher;\nimport com.taobao.android.utils.Profiler;\nimport com.taobao.android.utils.SoDiffUtils;\nimport com.taobao.checker.Checker;\nimport com.taobao.update.UpdateInfo;\nimport org.antlr.runtime.RecognitionException;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.FilenameUtils;\nimport org.apache.commons.io.IOUtils;\nimport org.apache.commons.io.filefilter.IOFileFilter;\nimport org.apache.commons.io.filefilter.TrueFileFilter;\nimport org.apache.commons.lang3.StringEscapeUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.jf.dexlib2.iface.ClassDef;\n\n/**\n * generate atlas dynamic tpatch\n * <p/>\n *\n * Created by lilong on 16/6/17.\n */\n\npublic class TPatchTool extends AbstractTool {\n\n    public ApkDiff apkDiff = new ApkDiff();\n\n\n    public Map<String,Integer> bundleTypes = new HashMap<>();\n\n    public ApkDiff apkPatchInfos = new ApkDiff();\n\n    public static List<SoFileDef>soFileDefs = new ArrayList<>();\n\n    public List<BundleDiffResult> bundleDiffResults = Collections.synchronizedList(new ArrayList<BundleDiffResult>());\n\n    public List<BundleDiffResult> diffPatchInfos = Collections.synchronizedList(new ArrayList<BundleDiffResult>());\n\n    public final PathMatcher pathMatcher = new PathMatcher();\n\n    private final String ANDROID_MANIFEST = \"AndroidManifest.xml\";\n\n    private static final String[] DEFAULT_NOT_INCLUDE_RESOURCES = new String[] {\"*.dex\",\n        \"lib/**\",\n        \"META-INF/**\"};\n\n    public static File hisTpatchFolder;\n\n    public static final String SO_PATCH_META = \"SO-PATCH-INF\";\n\n\n    public static final String DEX_PATCH_META = \"DEX-PATCH-INF\";\n\n\n    private boolean hasMainBundle;\n\n    public static Map<String,LinkedHashMap>bundleInfos = new HashMap<String, LinkedHashMap>();\n\n    private final Map<String, Map<String, ClassDef>> bundleClassMap\n        = new ConcurrentHashMap<String, Map<String, ClassDef>>();\n\n    private final List<String> whiteList = new ArrayList<>();\n    \n\n    private List<String> msgToString(List<Checker.ReasonMsg> msgs) {\n        List<String>ss = new ArrayList<>();\n        for (Checker.ReasonMsg reasonMsg:msgs){\n            ss.add(reasonMsg.toString());\n        }\n        return ss;\n    }\n    public boolean isBundleFile(File file) {\n        if (whiteList.size() > 1) {\n            for (String bundleName : whiteList) {\n                if (file.getAbsolutePath().replace(\"\\\\\", \"/\").endsWith(bundleName)) {\n                    return true;\n                }\n            }\n        } else {\n            return PatchUtils.isBundleFile(file);\n        }\n\n        return false;\n\n    }\n\n    private void readWhiteList(File whiteListFile) throws Exception {\n//        File whiteListFile = new File(parentFile, \"bundleList.cfg\");\n        if (whiteListFile.exists()) {\n            BufferedReader br = null;\n            br = new BufferedReader(new InputStreamReader(new FileInputStream(whiteListFile),\n                                                          \"UTF-8\"));\n            String lineTxt = null;\n            while ((lineTxt = br.readLine()) != null) {\n                whiteList.add(lineTxt);\n            }\n            br.close();\n        }\n    }\n\n    private File createTPatchFile(File outPatchDir, File patchTmpDir) throws IOException {\n        // 首先压缩主bundle,先判断主bundle里有没有文件\n        File mainBundleFoder = new File(patchTmpDir, ((TpatchInput)input).mainBundleName);\n        File metaFile = new File(mainBundleFoder,SO_PATCH_META);\n        if (soFileDefs.size() > 0){\n            com.taobao.android.tpatch.model.PatchFile patchFile = new com.taobao.android.tpatch.model.PatchFile(metaFile);\n            soFileDefs.stream().forEach(new Consumer<SoFileDef>() {\n                @Override\n                public void accept(SoFileDef soFileDef) {\n                    patchFile.append(soFileDef);\n                }\n            });\n            patchFile.close();\n        }\n        File mainBundleFile = new File(patchTmpDir, ((TpatchInput)input).mainBundleName + \".so\");\n        if (FileUtils.listFiles(mainBundleFoder, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE)\n            .size() > 0) {\n            hasMainBundle = true;\n            CommandUtils.exec(mainBundleFoder, \"zip -r \" + mainBundleFile.getAbsolutePath() + \" . -x */ -x .*\");\n        }\n        FileUtils.deleteDirectory(mainBundleFoder);\n\n        // 再压缩各自的bundle\n        File patchFile = null;\n\n            patchFile = new File(outPatchDir,\n                    \"patch-\" + input.newApkBo.getVersionName() + \"@\" + input.baseApkBo.getVersionName() + \".tpatch\");\n        if (patchFile.exists()) {\n            FileUtils.deleteQuietly(patchFile);\n        }\n\n        File infoFile = new File(patchTmpDir,\"patchInfo\");\n        FileUtils.writeStringToFile(infoFile, \"patch-\" + input.newApkBo.getVersionName() + \"@\" + input.baseApkBo.getVersionName() + \".tpatch\");\n\n        //        zipBundle(patchTmpDir, patchFile);\n        CommandUtils.exec(patchTmpDir, \"zip -r \" + patchFile.getAbsolutePath() + \" . -x */ -x .*\");\n        FileUtils.deleteDirectory(patchTmpDir);\n        return patchFile;\n    }\n\n\n    /**\n     * process bundle files\n     *\n     * @param newBundleFile\n     * @param baseBundleFile\n     * @param patchTmpDir\n     * @param diffTxtFile\n     */\n    public void processBundleFiles(File newBundleFile,\n                                    File baseBundleFile,\n                                    File patchTmpDir) throws Exception {\n        String bundleName = FilenameUtils.getBaseName(newBundleFile.getName());\n        File destPatchBundleDir = new File(patchTmpDir, bundleName);\n        final File newBundleUnzipFolder = new File(newBundleFile.getParentFile(), bundleName);\n        final File baseBundleUnzipFolder = new File(baseBundleFile.getParentFile(), bundleName);\n\n        DiffType modifyType = getModifyType(newBundleFile.getName());\n\n        long startTime = System.currentTimeMillis();\n\n        logger.warning(\">>> start to process bundle for patch \" + bundleName + \" >> difftype \" + modifyType.toString() + \" createALl:\" + ((TpatchInput)input).createAll);\n\n        if (modifyType == DiffType.ADD) {\n\n            FileUtils.copyFileToDirectory(newBundleFile, patchTmpDir);\n\n        } else if (((TpatchInput)input).createAll || (modifyType == DiffType.MODIFY) )  {\n\n            if (null != baseBundleFile &&\n                baseBundleFile.isFile() &&\n                baseBundleFile.exists() &&\n                !((TpatchInput)input).noPatchBundles.contains(baseBundleFile.getName()\n                                             .replace(\"_\", \".\")\n                                             .substring(3,\n                                                        baseBundleFile.getName().length() -\n                                                            3)) &&\n                input.diffBundleDex) {\n                doBundlePatch(newBundleFile, baseBundleFile, patchTmpDir, bundleName, destPatchBundleDir,\n                              newBundleUnzipFolder,\n                              baseBundleUnzipFolder);\n            }\n        }\n\n        logger.warning(\">>> fininsh to process bundle for patch \" + bundleName + \" >> difftype \" + modifyType.toString() + \" consume:\" + (System.currentTimeMillis() - startTime));\n    }\n\n    public void doBundlePatch(File newBundleFile, File baseBundleFile, File patchTmpDir, String bundleName,\n                               File destPatchBundleDir, final File newBundleUnzipFolder, File baseBundleUnzipFolder)\n        throws Exception {\n\n\n        doBundleDexPatch(newBundleFile,baseBundleFile,patchTmpDir,bundleName,destPatchBundleDir,newBundleUnzipFolder,baseBundleUnzipFolder);\n\n        doBundleResPatch(bundleName,destPatchBundleDir,newBundleUnzipFolder,baseBundleUnzipFolder);\n        // unzip\n        // compare dex changes\n\n\n\n    }\n\n    public void doBundleResPatch(String bundleName, File destPatchBundleDir, File newBundleUnzipFolder, File baseBundleUnzipFolder) throws IOException {\n        // compare resource changes\n        Collection<File> newBundleResFiles = FileUtils.listFiles(newBundleUnzipFolder,\n                new IOFileFilter() {\n\n                    @Override\n                    public boolean accept(File file) {\n                        // 不包括dex文件\n                        if (file.getName()\n                                .endsWith(\n                                        \".dex\")) {\n                            return false;\n                        }\n                        String relativePath = PathUtils\n                                .toRelative(\n                                        newBundleUnzipFolder,\n                                        file.getAbsolutePath());\n                        if (null !=\n                                ((TpatchInput)(input)).notIncludeFiles &&\n                                pathMatcher.match(\n                                        ((TpatchInput)(input)).notIncludeFiles,\n                                        relativePath)) {\n                            return false;\n                        }\n                        return true;\n                    }\n\n                    @Override\n                    public boolean accept(File file,\n                                          String s) {\n                        return accept(new File(\n                                file,\n                                s));\n                    }\n                },\n                TrueFileFilter.INSTANCE);\n\n        for (File newBundleResFile : newBundleResFiles) {\n            String resPath = PathUtils.toRelative(newBundleUnzipFolder,\n                    newBundleResFile.getAbsolutePath());\n            File baseBundleResFile = new File(baseBundleUnzipFolder, resPath);\n            File destResFile = new File(destPatchBundleDir, resPath);\n            if (baseBundleResFile.exists()) {\n                if (isFileModify(newBundleResFile,\n                        baseBundleResFile,\n                        bundleName,\n                        resPath)) { // modify resource\n                    if (baseBundleResFile.getName().endsWith(\".so\")){\n                        if (((TpatchInput)input).diffNativeSo && ((TpatchInput) input).diffBundleSo){\n                            destResFile = new File(destPatchBundleDir,resPath.concat(\".patch\"));\n                            SoDiffUtils.diffSo(baseBundleResFile.getParentFile(),baseBundleResFile,newBundleResFile,destResFile);\n\n                        }else {\n                            FileUtils.copyFile(newBundleResFile, destResFile);\n                        }\n\n                    }else {\n                        FileUtils.copyFile(newBundleResFile, destResFile);\n                    }\n                }\n            } else {// new resource\n                FileUtils.copyFile(newBundleResFile, destResFile);\n            }\n        }\n    }\n\n    public void doBundleDexPatch(File newBundleFile, File baseBundleFile, File patchTmpDir, String bundleName, File destPatchBundleDir, File newBundleUnzipFolder, File baseBundleUnzipFolder) throws Exception {\n        CommandUtils.exec(patchTmpDir,\n                \"unzip \" + newBundleFile.getAbsolutePath() + \" -d \" + newBundleUnzipFolder.getAbsolutePath());\n        CommandUtils.exec(patchTmpDir, \"unzip \" + baseBundleFile.getAbsolutePath() + \" -d \" + baseBundleUnzipFolder\n                .getAbsolutePath());\n//        File destDex = new File(destPatchBundleDir, DEX_NAME);\n//        File tmpDexFolder = new File(patchTmpDir, bundleName + \"-dex\");\n        createBundleDexPatch(newBundleUnzipFolder,\n                baseBundleUnzipFolder,\n                destPatchBundleDir,\n                false);\n\n    }\n\n    /**\n     * resource changes in main bundle\n     *\n     * @param newApkUnzipFolder\n     * @param baseApkUnzipFolder\n     * @param patchTmpDir\n     * @param retainFiles\n     * @throws IOException\n     */\n    public void copyMainBundleResources(final File newApkUnzipFolder, final File baseApkUnzipFolder, File patchTmpDir,\n                                        Collection<File> retainFiles) throws IOException {\n        boolean resoureModified = false;\n\n        for (File retainFile : retainFiles) {\n            String relativePath = PathUtils.toRelative(newApkUnzipFolder,\n                                                       retainFile.getAbsolutePath());\n            File baseFile = new File(baseApkUnzipFolder, relativePath);\n            if (isBundleFile(retainFile)) {\n            } else if (isFileModify(retainFile, baseFile)) {\n                resoureModified = true;\n                File destFile = new File(patchTmpDir, relativePath);\n                FileUtils.copyFile(retainFile, destFile);\n            }\n        }\n        if (resoureModified) {\n            File AndroidMenifestFile = new File(newApkUnzipFolder, ANDROID_MANIFEST);\n            FileUtils.copyFileToDirectory(AndroidMenifestFile, patchTmpDir);\n        }\n    }\n\n    /**\n     * get bundle diff dex file\n     *\n     * @param newApkUnzipFolder\n     * @param baseApkUnzipFolder\n     * @param destDex\n     * @param tmpDexFile\n     * @param diffTxtFile\n     * @return\n     * @throws IOException\n     * @throws RecognitionException\n     */\n    public List<File> createBundleDexPatch(File newApkUnzipFolder,\n                                      File baseApkUnzipFolder,\n                                      File diffDexFolder,\n                                      boolean mainDex) throws Exception {\n        List<File> dexs = Lists.newArrayList();\n        // 比较主bundle的dex\n//        if (!tmpDexFile.exists()) {\n//            tmpDexFile.mkdirs();\n//        }\n        List<File> baseDexFiles = getFolderDexFiles(baseApkUnzipFolder);\n        List<File> newDexFiles = getFolderDexFiles(newApkUnzipFolder);\n        PatchDexTool dexTool = new TpatchDexTool(baseDexFiles,\n                                                  newDexFiles,\n                                                  DEFAULT_API_LEVEL,\n                                                  bundleClassMap.get(diffDexFolder.getName()),\n                                                  mainDex);\n        dexTool.setNewPatch(((TpatchInput)input).newPatch);\n        DexDiffInfo dexDiffInfo = dexTool.createPatchDex(diffDexFolder);\n        if (diffDexFolder.listFiles()!= null && diffDexFolder.listFiles().length > 0) {\n            dexs.addAll(FileUtils.listFiles(diffDexFolder,new String[]{\"dex\"},true));\n            BundleDiffResult bundleDiffResult = new BundleDiffResult();\n            if (mainDex) {\n                bundleDiffResult.setBundleName(\"com.taobao.maindex\");\n\n            } else {\n                bundleDiffResult.setBundleName(baseApkUnzipFolder.getName().substring(3).replace(\"_\", \".\"));\n            }\n            bundleDiffResults.add(bundleDiffResult);\n            diffPatchInfos.add(bundleDiffResult);\n            dexDiffInfo.save(bundleDiffResult);\n        }\n//        if (dexs.size() > 0) {\n//\n//            FileUtils.copyFile(dexs.get(0), destDex);\n//        }\n//\n//        FileUtils.deleteDirectory(tmpDexFile);\n//        if (mainDex){\n//            try {\n//\n//                bundleInfos.put(input.newApkBo.getVersionName(), new AtlasFrameworkPropertiesReader(\n//                        new MethodReader(\n//                                new ClassReader(\n//                                        new DexReader(destDex))), null).read(\"Landroid/taobao/atlas/framework/FrameworkProperties;\", \"<clinit>\"));\n//                bundleInfos.put(input.baseApkBo.getVersionName(), new AtlasFrameworkPropertiesReader(\n//                        new MethodReader(\n//                                new ClassReader(\n//                                        new DexReader(baseDexFiles))), bundleInfos.get(input.newApkBo.getVersionName())).read(\"Landroid/taobao/atlas/framework/FrameworkProperties;\", \"<clinit>\"));\n//            }catch (Throwable e){\n//                e.printStackTrace();\n//            }\n//\n//            }\n\n        return dexs;\n    }\n\n    /**\n     * 获取基准patch包的patchInfo对象\n     *\n     * @param fileName\n     * @return\n     */\n    public PatchInfo createBasePatchInfo(File file) {\n        PatchInfo patchInfo = new PatchInfo();\n        patchInfo.setPatchVersion(input.newApkBo.getVersionName());\n        patchInfo.setTargetVersion(input.baseApkBo.getVersionName());\n        patchInfo.setFileName(file.getName());\n        Set<String> modifyBundles = new HashSet<>();\n        ZipFile zipFile = newZipFile(file);\n        Enumeration<? extends ZipEntry> enumeration = zipFile.entries();\n        while (enumeration.hasMoreElements()) {\n            ZipEntry zipEntry = enumeration.nextElement();\n            if (zipEntry.getName().startsWith(\"lib\") && zipEntry.getName().indexOf(\"/\") != -1) {\n                modifyBundles.add(zipEntry.getName().substring(3, zipEntry.getName().indexOf(\"/\")).replace(\"_\", \".\"));\n            } else if (zipEntry.getName().endsWith(\".so\") && zipEntry.getName().indexOf(\"/\") == -1) {\n                modifyBundles.add(\n                    zipEntry.getName().substring(3, zipEntry.getName().lastIndexOf(\".\")).replace(\"_\", \".\"));\n            }\n\n        }\n\n        for (ArtifactBundleInfo artifactBundleInfo : input.artifactBundleInfos) {\n            if (artifactBundleInfo.getMainBundle()) {\n                if (DiffType.MODIFY.equals(artifactBundleInfo.getDiffType()) || hasMainBundle) {\n                    PatchBundleInfo patchBundleInfo = new PatchBundleInfo();\n                    patchBundleInfo.setNewBundle(DiffType.ADD.equals(artifactBundleInfo.getDiffType()));\n                    patchBundleInfo.setMainBundle(true);\n                    patchBundleInfo.setVersion(artifactBundleInfo.getVersion());\n                    patchBundleInfo.setName(((TpatchInput)input).mainBundleName);\n                    patchBundleInfo.setSrcUnitTag(artifactBundleInfo.getSrcUnitTag());\n                    patchBundleInfo.setUnitTag(artifactBundleInfo.getUnitTag());\n                    patchBundleInfo.setPatchType(bundleTypes.get(((TpatchInput)input).mainBundleName) == null? 0:bundleTypes.get(((TpatchInput)input).mainBundleName));\n                    patchBundleInfo.setApplicationName(artifactBundleInfo.getApplicationName());\n                    patchBundleInfo.setArtifactId(artifactBundleInfo.getArtifactId());\n                    patchBundleInfo.setPkgName(artifactBundleInfo.getPkgName());\n                    patchBundleInfo.setDependency(artifactBundleInfo.getDependency());\n                    patchBundleInfo.setBaseVersion(artifactBundleInfo.getBaseVersion());\n                    patchInfo.getBundles().add(patchBundleInfo);\n                    continue;\n                }\n            } else if (DiffType.MODIFY.equals(artifactBundleInfo.getDiffType()) ||\n                DiffType.ADD.equals(artifactBundleInfo.getDiffType())) {\n                PatchBundleInfo patchBundleInfo = new PatchBundleInfo();\n                patchBundleInfo.setNewBundle(DiffType.ADD.equals(artifactBundleInfo.getDiffType()));\n                patchBundleInfo.setMainBundle(false);\n                patchBundleInfo.setSrcUnitTag(artifactBundleInfo.getSrcUnitTag());\n                patchBundleInfo.setUnitTag(artifactBundleInfo.getUnitTag());\n                patchBundleInfo.setVersion(artifactBundleInfo.getVersion());\n                patchBundleInfo.setPatchType(bundleTypes.get(artifactBundleInfo.getPkgName()) == null? 0:bundleTypes.get(artifactBundleInfo.getPkgName()));\n                patchBundleInfo.setName(artifactBundleInfo.getPkgName());\n                if (!modifyBundles.contains(artifactBundleInfo.getPkgName().replace(\"_\",\".\"))){\n                    patchBundleInfo.setInherit(true);\n                }\n                patchBundleInfo.setApplicationName(artifactBundleInfo.getApplicationName());\n                patchBundleInfo.setArtifactId(artifactBundleInfo.getArtifactId());\n                patchBundleInfo.setPkgName(artifactBundleInfo.getPkgName());\n                patchBundleInfo.setDependency(artifactBundleInfo.getDependency());\n                patchBundleInfo.setBaseVersion(artifactBundleInfo.getBaseVersion());\n                patchInfo.getBundles().add(patchBundleInfo);\n            } else if (modifyBundles.contains(artifactBundleInfo.getPkgName().replace(\"_\",\".\"))) {\n                PatchBundleInfo patchBundleInfo = new PatchBundleInfo();\n                patchBundleInfo.setNewBundle(false);\n                patchBundleInfo.setMainBundle(false);\n                patchBundleInfo.setPatchType(bundleTypes.get(artifactBundleInfo.getPkgName()) == null? 0:bundleTypes.get(artifactBundleInfo.getPkgName()));\n                patchBundleInfo.setSrcUnitTag(artifactBundleInfo.getSrcUnitTag());\n                patchBundleInfo.setUnitTag(artifactBundleInfo.getUnitTag());\n                patchBundleInfo.setVersion(artifactBundleInfo.getVersion());\n                patchBundleInfo.setName(artifactBundleInfo.getName());\n                patchBundleInfo.setApplicationName(artifactBundleInfo.getApplicationName());\n                patchBundleInfo.setArtifactId(artifactBundleInfo.getArtifactId());\n                patchBundleInfo.setPkgName(artifactBundleInfo.getPkgName());\n                patchBundleInfo.setDependency(artifactBundleInfo.getDependency());\n                patchBundleInfo.setBaseVersion(artifactBundleInfo.getBaseVersion());\n                patchInfo.getBundles().add(patchBundleInfo);\n                if (artifactBundleInfo.getUnitTag().equals(artifactBundleInfo.getSrcUnitTag())){\n                    throw new RuntimeException(artifactBundleInfo.getPkgName()+\"has contents change,but unitTag equals srcUnitTag\"+artifactBundleInfo.getUnitTag()+\",please upgrade bundle version and reintegration\");\n                }\n            }\n        }\n\n        try {\n            zipFile.close();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        return patchInfo;\n    }\n\n    private ZipFile newZipFile(File file) {\n        try {\n            return new ZipFile(file);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        return null;\n    }\n\n    /**\n     * create increment patch\n     * file\n     */\n    private BuildPatchInfos createIncrementPatchFiles(String productionName,\n                                                      File curTPatchFile,\n                                                      File targetDirectory,\n                                                      File newApkUnzipFolder,\n                                                      PatchInfo curPatchInfo,\n                                                      String patchHistoryUrl) throws IOException, PatchException {\n\n        BuildPatchInfos historyBuildPatchInfos = null;\n        String response = null;\n        if (!StringUtils.isEmpty(patchHistoryUrl)) {\n            String patchHisUrl = patchHistoryUrl +\n                \"?baseVersion=\" +\n                input.baseApkBo.getVersionName() +\n                \"&productIdentifier=\" +\n                productionName;\n            try {\n            response = HttpClientUtils.getUrl(patchHisUrl);\n            historyBuildPatchInfos = JSON.parseObject(response, BuildPatchInfos.class);\n            }catch (Throwable e){\n                historyBuildPatchInfos = null;\n            }\n        } else {\n            File[] files = hisTpatchFolder.listFiles(new FilenameFilter() {\n                @Override\n                public boolean accept(File dir, String filename) {\n                    return filename.startsWith(\"patchs-\") && filename.endsWith(\".json\");\n                }\n            });\n            if (files != null && files.length > 0) {\n                historyBuildPatchInfos = mergeHisPatchInfo(files);\n            }\n        }\n        if (historyBuildPatchInfos == null) {\n            return new BuildPatchInfos();\n        }\n        Iterator<PatchInfo> patchInfos = historyBuildPatchInfos.getPatches().iterator();\n        while (patchInfos.hasNext()) {\n            PatchInfo patchInfo = patchInfos.next();\n            if (!patchInfo.getTargetVersion().equals(input.baseApkBo.getVersionName())) {\n                patchInfos.remove();\n            }\n        }\n\n        Map<String, File> awbBundleMap = new HashMap<String, File>();\n        for (ArtifactBundleInfo artifactBundleInfo : input.artifactBundleInfos) {\n            String bundleFileSoName = \"lib\" +\n                    artifactBundleInfo.getPkgName().replace('.', '_') +\n                    \".so\";\n            File bundleFile = new File(newApkUnzipFolder,\n                    \"lib\" +\n                            \"/\" +\n                            \"armeabi\" +\n                            \"/\" +\n                            bundleFileSoName);\n            File assetsBundleFile = new File(newApkUnzipFolder,\n                    \"assets\" +\n                            \"/\" +\n                            bundleFileSoName);\n            if (bundleFile.exists()) {\n                awbBundleMap.put(artifactBundleInfo.getArtifactId(), bundleFile);\n            }else if (assetsBundleFile.exists()){\n                awbBundleMap.put(artifactBundleInfo.getArtifactId(), assetsBundleFile);\n\n            }\n        }\n        if (((TpatchInput)input).splitDiffBundle != null) {\n            for (Pair<BundleBO, BundleBO> bundle : ((TpatchInput)input).splitDiffBundle) {\n                awbBundleMap.put(bundle.getSecond().getBundleName(), bundle.getSecond().getBundleFile());\n\n            }\n        }\n\n\n        PatchFileBuilder patchFileBuilder = new PatchFileBuilder(historyBuildPatchInfos,\n                                                                 curTPatchFile,\n                                                                 curPatchInfo,\n                                                                 awbBundleMap,\n                                                                 targetDirectory,\n                                                                 input.baseApkBo.getVersionName());\n        patchFileBuilder.setNoPatchBundles(((TpatchInput) input).noPatchBundles);\n        patchFileBuilder.setHistroyVersionList(((TpatchInput) input).versionList);\n\n        return patchFileBuilder.createHistoryTPatches(input.diffBundleDex, logger);\n    }\n\n    private BuildPatchInfos mergeHisPatchInfo(File[] files) {\n        BuildPatchInfos mergeBuildPatchInfo = new BuildPatchInfos();\n        List<PatchInfo>patchInfos = new ArrayList<>();\n        mergeBuildPatchInfo.setPatches(patchInfos);\n        try {\n            for (File localPatchInfo:files) {\n                String response = FileUtils.readFileToString(localPatchInfo);\n                BuildPatchInfos historyBuildPatchInfos = JSON.parseObject(response, BuildPatchInfos.class);\n                patchInfos.addAll(historyBuildPatchInfos.getPatches());\n                mergeBuildPatchInfo.setBaseVersion(historyBuildPatchInfos.getBaseVersion());\n                mergeBuildPatchInfo.setDiffBundleDex(true);\n             }\n        } catch (IOException e) {\n                e.printStackTrace();\n            }\n        return mergeBuildPatchInfo;\n    }\n\n    /**\n     * create manifest for patch file\n     *\n     * @return\n     */\n    private Manifest createManifest() {\n        Manifest manifest = new Manifest();\n        Attributes main = manifest.getMainAttributes();\n        main.putValue(\"Manifest-Version\", \"1.0\");\n        main.putValue(\"Created-By\", \"1.0 (DexPatch)\");\n        main.putValue(\"Created-Time\", new Date(System.currentTimeMillis()).toGMTString());\n        return manifest;\n    }\n\n    /**\n     * judge if is file modified\n     *\n     * @param newFile  new File\n     * @param baseFile\n     * @return\n     */\n    public synchronized boolean isFileModify(File newFile, File baseFile) throws IOException {\n        if (null == baseFile || !baseFile.exists()) {\n            return true;\n        }\n\n        String newFileMd5 = MD5Util.getFileMD5String(newFile);\n        String baseFileMd5 = MD5Util.getFileMD5String(baseFile);\n        if (StringUtils.equals(newFileMd5, baseFileMd5)) {\n            return false;\n        } else {\n            return true;\n        }\n    }\n\n    /**\n     * if a file is modify\n     *\n     * @param newFile\n     * @param baseFile\n     * @param bundleFileName\n     * @param filePath\n     * @return\n     * @throws IOException\n     */\n    private synchronized boolean isFileModify(File newFile,\n                                              File baseFile,\n                                              String bundleFileName,\n                                              String filePath) throws IOException {\n        if (null == baseFile || !baseFile.exists()) {\n            return true;\n        }\n\n        String newFileMd5 = MD5Util.getFileMD5String(newFile);\n        String baseFileMd5 = MD5Util.getFileMD5String(baseFile);\n        newFileMd5 = getBundleFileMappingMd5(getNewApkFileList(),\n                                             bundleFileName,\n                                             filePath,\n                                             newFileMd5);\n        baseFileMd5 = getBundleFileMappingMd5(getBaseApkFileList(),\n                                              bundleFileName,\n                                              filePath,\n                                              baseFileMd5);\n        if (StringUtils.equals(newFileMd5, baseFileMd5)) {\n            return false;\n        } else if (newFile.getName().equals(ANDROID_MANIFEST)) {\n            return isManifestModify(baseFile, newFile);\n\n        } else {\n            return true;\n        }\n    }\n\n    private boolean isManifestModify(File baseFile, File newFile) {\n        AndroidManifestDiffFactory androidManifestDiffFactory = new AndroidManifestDiffFactory();\n        try {\n            androidManifestDiffFactory.diff(baseFile, newFile);\n            for (AndroidManifestDiffFactory.DiffItem diffItem : androidManifestDiffFactory.diffResuit) {\n                if (diffItem.Component instanceof com.taobao.android.tpatch.manifest.Manifest.Activity ||\n                    diffItem.Component instanceof com.taobao.android.tpatch.manifest.Manifest.Service) {\n                    return true;\n                }\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return false;\n    }\n\n    /**\n     * get file md5 from apkFileList\n     *\n     * @param apkFileList\n     * @param bundleFileName,如果为null,则表示是主bundle\n     * @param filePath\n     * @param curMd5\n     * @return\n     */\n    private String getBundleFileMappingMd5(ApkFileList apkFileList,\n                                           String bundleFileName,\n                                           String filePath,\n                                           String curMd5) {\n        if (null == apkFileList) {\n            return curMd5;\n        }\n        String bundleName = null;\n        if (null != bundleFileName) {\n            bundleName = getBundleName(bundleFileName);\n            if (null != bundleName) {\n                String mappingMd5 = apkFileList.getAwbFile(bundleName, filePath);\n                if (null != mappingMd5) {\n                    return mappingMd5;\n                }\n            }\n        } else { // 主bundle\n            String mappingMd5 = apkFileList.getMainBundle().get(filePath);\n            if (null != mappingMd5) {\n                return mappingMd5;\n            }\n        }\n        return curMd5;\n    }\n\n    /**\n     * add files to jar\n     *\n     * @param jos\n     * @param file\n     */\n    private void addFile(JarOutputStream jos, File file) throws IOException {\n        byte[] buf = new byte[8064];\n        String path = file.getName();\n        InputStream in = null;\n        try {\n            in = new FileInputStream(file);\n            ZipEntry fileEntry = new ZipEntry(path);\n            jos.putNextEntry(fileEntry);\n            // Transfer bytes from the file to the ZIP file\n            int len;\n            while ((len = in.read(buf)) > 0) {\n                jos.write(buf, 0, len);\n            }\n            // Complete the entry\n            jos.closeEntry();\n        } finally {\n            IOUtils.closeQuietly(in);\n        }\n    }\n\n    /**\n     * Adds a directory to a {@link} with a directory prefix.\n     *\n     * @param jos       ZipArchiver to use to archive the file.\n     * @param directory The directory to add.\n     * @param prefix    An optional prefix for where in the Jar file the directory's contents should go.\n     */\n    protected void addDirectory(JarOutputStream jos,\n                                File directory,\n                                String prefix) throws IOException {\n        if (directory != null && directory.exists()) {\n            Collection<File> files = FileUtils.listFiles(directory,\n                                                         TrueFileFilter.INSTANCE,\n                                                         TrueFileFilter.INSTANCE);\n            byte[] buf = new byte[8064];\n            for (File file : files) {\n                if (file.isDirectory()) {\n                    continue;\n                }\n                String path = prefix +\n                    \"/\" +\n                    PathUtils.toRelative(directory, file.getAbsolutePath());\n                InputStream in = null;\n                try {\n                    in = new FileInputStream(file);\n                    ZipEntry fileEntry = new ZipEntry(path);\n                    jos.putNextEntry(fileEntry);\n                    // Transfer bytes from the file to the ZIP file\n                    int len;\n                    while ((len = in.read(buf)) > 0) {\n                        jos.write(buf, 0, len);\n                    }\n                    // Complete the entry\n                    jos.closeEntry();\n                    in.close();\n                } finally {\n                    IOUtils.closeQuietly(in);\n                }\n            }\n        }\n    }\n\n\n\n\n\n\n    @Override\n    public PatchFile doPatch() throws Exception {\n        TpatchInput tpatchInput = (TpatchInput) input;\n        TpatchFile tpatchFile = new TpatchFile();\n        File hisPatchJsonFile = new File(tpatchInput.outPutJson.getParentFile(),\"patchs-\"+input.newApkBo.getVersionName()+\".json\");\n        hisTpatchFolder = new File(tpatchInput.outPatchDir.getParentFile().getParentFile().getParentFile().getParentFile(),\"hisTpatch\");\n         tpatchFile.diffJson = new File(((TpatchInput) input).outPatchDir, \"diff.json\");\n         tpatchFile.patchInfo = new File(((TpatchInput) input).outPatchDir, \"patchInfo.json\");\n        final File patchTmpDir = new File(((TpatchInput) input).outPatchDir, \"tpatch-tmp\");\n        final File mainDiffFolder = new File(patchTmpDir, ((TpatchInput)input).mainBundleName);\n        patchTmpDir.mkdirs();\n        FileUtils.cleanDirectory(patchTmpDir);\n        mainDiffFolder.mkdirs();\n        File lastPatchFile = null;\n        readWhiteList(((TpatchInput) input).bundleWhiteList);\n        lastPatchFile = getLastPatchFile(input.baseApkBo.getVersionName(), ((TpatchInput) input).productName, ((TpatchInput) input).outPatchDir);\n        PatchUtils.getTpatchClassDef(lastPatchFile, bundleClassMap);\n        Profiler.release();\n        Profiler.enter(\"unzip apks\");\n        // unzip apk\n        File unzipFolder = unzipApk(((TpatchInput) input).outPatchDir);\n        final File newApkUnzipFolder = new File(unzipFolder, NEW_APK_UNZIP_NAME);\n        final File baseApkUnzipFolder = new File(unzipFolder, BASE_APK_UNZIP_NAME);\n        Profiler.release();\n        ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper();\n        String taskName = \"diffBundleTask\";\n        //\n\n        Collection<File> soFiles = FileUtils.listFiles(newApkUnzipFolder, new String[] {\"so\"}, true);\n\n        //process remote bumdle\n        if ((((TpatchInput) input).splitDiffBundle != null)) {\n            for (final Pair<BundleBO, BundleBO> bundle : ((TpatchInput) input).splitDiffBundle) {\n                if (bundle.getFirst() == null || bundle.getSecond() == null){\n                    logger.warning(\"remote bundle is not set to splitDiffBundles\");\n                    continue;\n                }\n                executorServicesHelper.submitTask(taskName, new Callable<Boolean>() {\n                    @Override\n                    public Boolean call() throws Exception {\n                        TPatchTool.this.processBundleFiles(bundle.getSecond().getBundleFile(), bundle.getFirst().getBundleFile(), patchTmpDir);\n                        return true;\n                    }\n                });\n            }\n        }\n\n\n        Profiler.enter(\"awbspatch\");\n\n        Collection<File> retainFiles = FileUtils.listFiles(newApkUnzipFolder, new IOFileFilter() {\n\n\n            @Override\n            public boolean accept(File file) {\n                String relativePath = PathUtils.toRelative(newApkUnzipFolder, file.getAbsolutePath());\n                if (pathMatcher.match(DEFAULT_NOT_INCLUDE_RESOURCES, relativePath)) {\n                    return false;\n                }\n                if (null != ((TpatchInput)(input)).notIncludeFiles && pathMatcher\n                    .match(((TpatchInput)(input)).notIncludeFiles, relativePath)) {\n                    return false;\n                }\n                return true;\n            }\n\n            @Override\n            public boolean accept(File file, String s) {\n                return accept(new File(file, s));\n            }\n        }, TrueFileFilter.INSTANCE);\n\n\n        executorServicesHelper.submitTask(taskName, new Callable<Boolean>() {\n            @Override\n            public Boolean call() throws Exception {\n                // 得到主bundle的dex diff文件\n//                File mianDiffDestDex = new File(mainDiffFolder, DEX_NAME);\n//                File tmpDexFolder = new File(patchTmpDir, ((TpatchInput)input).mainBundleName + \"-dex\");\n                createBundleDexPatch(newApkUnzipFolder,\n                        baseApkUnzipFolder,\n                        mainDiffFolder,\n//                        tmpDexFolder,\n                        true);\n\n                // 是否保留主bundle的资源文件\n                if (isRetainMainBundleRes()) {\n                    copyMainBundleResources(newApkUnzipFolder,\n                            baseApkUnzipFolder,\n                    new File(patchTmpDir, ((TpatchInput)input).mainBundleName),\n                    retainFiles);\n                }\n                return true;\n            }\n\n        }\n        );\n\n\n        for (final File soFile : soFiles) {\n            System.out.println(\"do patch:\" + soFile.getAbsolutePath());\n            final String relativePath = PathUtils.toRelative(newApkUnzipFolder,\n                    soFile.getAbsolutePath());\n            if (null != ((TpatchInput) input).notIncludeFiles && pathMatcher.match(((TpatchInput)input).notIncludeFiles, relativePath)) {\n                continue;\n            }\n            executorServicesHelper.submitTask(taskName, new Callable<Boolean>() {\n\n                @Override\n                public Boolean call() throws Exception {\n                    File destFile = new File(patchTmpDir, ((TpatchInput)input).mainBundleName + \"/\" +\n                            relativePath);\n                    File baseSoFile = new File(baseApkUnzipFolder, relativePath);\n                    if (isBundleFile(soFile)) {\n                        processBundleFiles(soFile, baseSoFile, patchTmpDir);\n\n                    } else if (isFileModify(soFile, baseSoFile)) {\n                        if (destFile.exists()){\n                            FileUtils.deleteQuietly(destFile);\n                        }\n                        if (!baseSoFile.exists()||!((TpatchInput) input).diffNativeSo) {\n                            //新增\n                            FileUtils.copyFile(soFile, destFile);\n                        }else {\n\n                            destFile = new File(destFile.getParentFile(),destFile.getName()+\".patch\");\n                            SoDiffUtils.diffSo(patchTmpDir,baseSoFile,soFile,destFile);\n                            soFileDefs.add(new SoFileDef(baseSoFile,soFile,destFile,relativePath));\n\n                        }\n                    }\n\n                    return true;\n                }\n            });\n        }\n\n        executorServicesHelper.waitTaskCompleted(taskName);\n        executorServicesHelper.stop();\n        Profiler.release();\n\n        Profiler.enter(\"ziptpatchfile\");\n        // zip file\n        File patchFile = createTPatchFile(((TpatchInput) input).outPatchDir, patchTmpDir);\n        tpatchFile.patchFile = patchFile;\n        PatchInfo curPatchInfo = createBasePatchInfo(patchFile);\n\n        Profiler.release();\n\n        Profiler.enter(\"createhistpatch\");\n        BuildPatchInfos buildPatchInfos = createIncrementPatchFiles(((TpatchInput) input).productName,\n                patchFile,\n                ((TpatchInput) input).outPatchDir,\n                newApkUnzipFolder,\n                curPatchInfo,\n                ((TpatchInput) input).hisPatchUrl);\n        Profiler.release();\n\n        Profiler.enter(\"writejson\");\n        buildPatchInfos.getPatches().add(curPatchInfo);\n        buildPatchInfos.setBaseVersion(input.baseApkBo.getVersionName());\n        buildPatchInfos.setDiffBundleDex(input.diffBundleDex);\n\n            FileUtils.writeStringToFile(((TpatchInput) input).outPutJson, JSON.toJSONString(buildPatchInfos));\n            BuildPatchInfos testForBuildPatchInfos = new BuildPatchInfos();\n            testForBuildPatchInfos.setBaseVersion(buildPatchInfos.getBaseVersion());\n            List<PatchInfo>patchInfos = new ArrayList<>();\n            testForBuildPatchInfos.setPatches(patchInfos);\n            testForBuildPatchInfos.setDiffBundleDex(buildPatchInfos.isDiffBundleDex());\n            for(PatchInfo patchInfo:buildPatchInfos.getPatches()){\n                if (patchInfo.getTargetVersion().equals(buildPatchInfos.getBaseVersion())){\n                    patchInfos.add(patchInfo);\n                }\n            }\n            FileUtils.writeStringToFile(hisPatchJsonFile, JSON.toJSONString(testForBuildPatchInfos));\n            tpatchFile.updateJsons = new ArrayList<File>();\n            Map<String,List<String>>map = new HashMap<>();\n        for (PatchInfo patchInfo : buildPatchInfos.getPatches()) {\n            UpdateInfo updateInfo = new UpdateInfo(patchInfo, buildPatchInfos.getBaseVersion());\n//            System.out.println(\"start to check:\"+patchInfo.getTargetVersion()+\"......\");\n//            List<PatchChecker.ReasonMsg> msgs = new PatchChecker(updateInfo,bundleInfos.get(patchInfo.getTargetVersion()),new File(((TpatchInput) input).outPatchDir,patchInfo.getFileName())).check();\n//            map.put(patchInfo.getFileName(),msgToString(msgs));\n            File updateJson = new File(((TpatchInput) input).outPatchDir, \"update-\" + patchInfo.getTargetVersion() + \".json\");\n            FileUtils.writeStringToFile(updateJson, JSON.toJSONString(updateInfo, true));\n            tpatchFile.updateJsons.add(updateJson);\n        }\n//        tpatchFile.patchChecker = new File(((TpatchInput) input).outPatchDir,\"patch-check.json\");\n//        FileUtils.writeStringToFile(tpatchFile.patchChecker, JSON.toJSONString(map, true));\n        // 删除临时的目录\n        FileUtils.deleteDirectory(patchTmpDir);\n        apkDiff.setBaseApkVersion(input.baseApkBo.getVersionName());\n        apkDiff.setNewApkVersion(input.newApkBo.getVersionName());\n        apkDiff.setBundleDiffResults(bundleDiffResults);\n        boolean newApkFileExist = input.newApkBo.getApkFile().exists() && input.newApkBo.getApkFile().isFile();\n        if (newApkFileExist) {\n            apkDiff.setNewApkMd5(MD5Util.getFileMD5String(input.newApkBo.getApkFile()));\n        }\n        apkDiff.setFileName(input.newApkBo.getApkName());\n        apkPatchInfos.setBaseApkVersion(input.baseApkBo.getVersionName());\n        apkPatchInfos.setNewApkVersion(input.newApkBo.getVersionName());\n        apkPatchInfos.setBundleDiffResults(diffPatchInfos);\n        apkPatchInfos.setFileName(patchFile.getName());\n        apkPatchInfos.setNewApkMd5(MD5Util.getFileMD5String(patchFile));\n        FileUtils.writeStringToFile(tpatchFile.diffJson, JSON.toJSONString(apkDiff));\n        FileUtils.writeStringToFile(tpatchFile.patchInfo, JSON.toJSONString(apkPatchInfos));\n        FileUtils.copyFileToDirectory(tpatchFile.diffJson, ((TpatchInput) input).outPatchDir.getParentFile(), true);\n        if (newApkFileExist) {\n            FileUtils.copyFileToDirectory(input.newApkBo.getApkFile(), ((TpatchInput) input).outPatchDir.getParentFile(), true);\n        }\n        Profiler.release();\n        logger.warning(Profiler.dump());\n        return tpatchFile;\n    }\n\n    @Override\n    public boolean isRetainMainBundleRes() {\n        return true;\n    }\n\n    protected File getLastPatchFile(String baseApkVersion,\n                                    String productName,\n                                    File outPatchDir) throws IOException {\n        try {\n            String httpUrl = ((TpatchInput)input).LAST_PATCH_URL +\n                    \"baseVersion=\" +\n                    baseApkVersion +\n                    \"&productIdentifier=\" +\n                    productName;\n            String response = HttpClientUtils.getUrl(httpUrl);\n            if (StringUtils.isBlank(response) ||\n                    response.equals(\"\\\"\\\"\")) {\n                return null;\n            }\n            File downLoadFolder = new File(outPatchDir, \"LastPatch\");\n            downLoadFolder.mkdirs();\n            File downLoadFile = new File(downLoadFolder, \"lastpatch.tpatch\");\n            String downLoadUrl = StringEscapeUtils.unescapeJava(response);\n            downloadTPath(downLoadUrl.substring(1, downLoadUrl.length() - 1), downLoadFile);\n\n            return downLoadFile;\n        } catch (Exception e) {\n            return null;\n        }\n    }\n\n    public static void main(String[]args) throws IOException {\n\n\n//        TPatchTool.class.getProtectionDomain().getCodeSource().getLocation();\n//        File workingDir = new File(\"/Users/lilong/Downloads/patch-7.7.4.67686@7.7.3\");\n//        File oldFile = new File(\"/Users/lilong/Documents/main_builder/aa/lib/armeabi/libalinnkit-v7a.so\");\n//        File newFile = new File(\"/Users/lilong/Downloads/patch-7.7.4.67686@7.7.3/libcom_taobao_maindex/lib/armeabi/libalinnkit-v7a.so\");\n//        File patchFile = new File(\"/Users/lilong/Downloads/libalinnkit-v7a.so.patch\");\n//        File new2File = new File(\"/Users/lilong/Downloads/libalinnkit-v7a.so\");\n//        File bsDiffFile = new File(TPatchTool.class.getClassLoader().getResource(\"mac/bsdiff\").getFile());\n//        File bsPatchFile = new File(TPatchTool.class.getClassLoader().getResource(\"mac/bspatch\").getFile());\n//\n//        CommandUtils.exec(workingDir,bsDiffFile.getAbsolutePath()+ \" \"+oldFile.getAbsolutePath() + \" \"+newFile.getAbsolutePath()+\" \"+patchFile.getAbsolutePath());\n//        CommandUtils.exec(workingDir,bsPatchFile.getAbsolutePath()+\" \"+oldFile.getAbsolutePath() + \" \"+new2File.getAbsolutePath()+\" \"+patchFile.getAbsolutePath());\n//\n//        assert MD5Util.getFileMD5String(new2File).equals(MD5Util.getFileMD5String(newFile));\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tools/TpatchDexTool.java",
    "content": "package com.taobao.android.tools;\n\nimport com.taobao.android.differ.dex.PatchException;\nimport org.antlr.runtime.RecognitionException;\nimport org.jf.dexlib2.iface.ClassDef;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * @author lilong\n * @create 2017-11-07 下午2:42\n */\n\npublic class TpatchDexTool extends PatchDexTool {\n\n    public TpatchDexTool(List<File> baseDexFiles, List<File> newDexFiles, int apiLevel, Map<String, ClassDef> map, boolean mainBundle) {\n        super(baseDexFiles, newDexFiles, apiLevel, map, mainBundle);\n    }\n\n    public TpatchDexTool(File baseDex, File newDex, int apiLevel, boolean mainBundle) {\n        super(baseDex, newDex, apiLevel, mainBundle);\n    }\n\n    @Override\n    public Set<ClassDef> createModifyClasses() throws IOException, PatchException {\n            dexDiffer.setTpatch(true);\n        return super.createModifyClasses();\n    }\n\n    @Override\n    public void setExculdeClasses(Set<String> classes) {\n\n    }\n\n    @Override\n    public void setPatchClasses(Set<String> classes) {\n\n    }\n\n    public static void main(String []args){\n        TpatchDexTool tpatchDexTool = new TpatchDexTool(new File(\"/Users/lilong/Downloads/taobao-android-release/classes.dex\"),new File(\"/Users/lilong/Downloads/taobao-android-release0/classes.dex\"),21,false);\n        File outDex = new File(\"/Users/lilong/Downloads/taobao-android-debug1/lib/armeabi/libcom_taobao_taolive/patch.dex\");\n        try {\n            tpatchDexTool.createPatchDex(outDex);\n        } catch (IOException e) {\n            e.printStackTrace();\n        } catch (RecognitionException e) {\n            e.printStackTrace();\n        } catch (PatchException e) {\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/builder/PatchFileBuilder.java",
    "content": "package com.taobao.android.tpatch.builder;\n\nimport java.io.BufferedOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.URL;\nimport java.net.URLConnection;\nimport java.sql.Date;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.function.Consumer;\nimport java.util.jar.Attributes;\nimport java.util.jar.JarOutputStream;\nimport java.util.jar.Manifest;\nimport java.util.zip.ZipEntry;\n\nimport com.android.utils.ILogger;\nimport com.taobao.android.object.SoFileDef;\nimport com.taobao.android.tools.TPatchTool;\nimport com.taobao.android.differ.dex.PatchException;\nimport com.taobao.android.object.BuildPatchInfos;\nimport com.taobao.android.object.PatchBundleInfo;\nimport com.taobao.android.object.PatchInfo;\nimport com.taobao.android.reader.*;\nimport com.taobao.android.tpatch.utils.JarSplitUtils;\nimport com.taobao.android.tpatch.utils.MD5Util;\nimport com.taobao.android.tpatch.utils.PathUtils;\nimport com.taobao.android.utils.CommandUtils;\nimport com.taobao.android.utils.SoDiffUtils;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.FilenameUtils;\nimport org.apache.commons.io.IOUtils;\nimport org.apache.commons.io.filefilter.TrueFileFilter;\nimport org.apache.commons.lang3.StringUtils;\nimport org.gradle.api.GradleException;\n\npublic class PatchFileBuilder {\n\n    private static final String ROLLBACK_VERSION = \"-1\";\n\n    private final BuildPatchInfos historyBuildPatchInfos;\n    private final PatchInfo currentBuildPatchInfo;\n    private final File currentPatchFile;\n    private final String baseVersion;\n    private final File tPatchTmpFolder;\n    private Map<String, File> awbMaps;\n    private Map<String, PatchInfo> hisPatchInfos = new HashMap<String, PatchInfo>();\n    private List<String> versionList = new ArrayList<>();\n    private final File patchsFolder;\n\n    private List<String> noPatchBundles;\n\n    public PatchFileBuilder(BuildPatchInfos historyBuildPatchInfos, File currentPatchFile,\n                            PatchInfo currentBuildPatchInfo, Map<String, File> awbMaps, File targetFolder,\n                            String baseVersion) {\n        if (null == historyBuildPatchInfos) {\n            this.historyBuildPatchInfos = new BuildPatchInfos();\n        } else {\n            this.historyBuildPatchInfos = historyBuildPatchInfos;\n        }\n        this.currentBuildPatchInfo = currentBuildPatchInfo;\n        this.awbMaps = awbMaps;\n        this.currentPatchFile = currentPatchFile;\n        this.baseVersion = baseVersion;\n        this.tPatchTmpFolder = new File(targetFolder.getParentFile(), \"tpatch-tmp\");\n        this.patchsFolder = targetFolder;\n    }\n\n    public void setNoPatchBundles(List<String> noPatchBundles) {\n        this.noPatchBundles = noPatchBundles;\n    }\n\n    /**\n     * create history tpatch\n     */\n    public BuildPatchInfos createHistoryTPatches(boolean diffBundleDex, final ILogger logger) throws PatchException {\n        final BuildPatchInfos buildPatchInfos = new BuildPatchInfos();\n        List<PatchInfo> patchInfos = historyBuildPatchInfos.getPatches();\n\n        patchInfos.parallelStream().filter(new java.util.function.Predicate<PatchInfo>() {\n            @Override\n            public boolean test(PatchInfo patchInfo) {\n                if (!versionList.isEmpty() && !versionList.contains(patchInfo.getPatchVersion())) {\n                    return false;\n                }\n                return true;\n            }\n        }).forEach(new Consumer<PatchInfo>() {\n            @Override\n            public void accept(PatchInfo patchInfo) {\n                if (null != logger) {\n                    logger.info(\"[CreateHisPatch]\" + patchInfo.getPatchVersion() + \"....\");\n                }\n                hisPatchInfos.put(patchInfo.getPatchVersion(), patchInfo);\n                PatchInfo newPatchInfo = null;\n                try {\n                    newPatchInfo = createHisTPatch(patchInfo.getPatchVersion(), logger);\n                } catch (Exception e) {\n                    throw new GradleException(e.getMessage(), e);\n                }\n\n                synchronized (buildPatchInfos) {\n                    buildPatchInfos.getPatches().add(newPatchInfo);\n                }\n\n            }\n        });\n\n        return buildPatchInfos;\n    }\n\n    // 获取主bundle\n    private PatchBundleInfo getMainBundleInfo(PatchInfo patchInfo) {\n        for (PatchBundleInfo bundleInfo : patchInfo.getBundles()) {\n            if (bundleInfo.getMainBundle()) {\n                return bundleInfo;\n            }\n        }\n        return null;\n    }\n\n    /**\n     * create patch for target version\n     *\n     * @param targetVersion\n     */\n    private PatchInfo createHisTPatch(String targetVersion, ILogger logger) throws IOException, PatchException {\n        PatchInfo hisPatchInfo = hisPatchInfos.get(targetVersion);\n        String patchName = \"patch-\" + currentBuildPatchInfo.getPatchVersion() + \"@\" + hisPatchInfo.getPatchVersion();\n        File destTPathTmpFolder = new File(tPatchTmpFolder, patchName);\n        destTPathTmpFolder.mkdirs();\n        File infoFile = new File(destTPathTmpFolder, \"patchInfo\");\n        FileUtils.writeStringToFile(infoFile, patchName);\n        File curTPatchUnzipFolder = unzipCurTPatchFolder(patchName);\n        // 处理awb的更新\n        List<BundlePatch> bundlePatches = diffPatch(hisPatchInfo, currentBuildPatchInfo);\n        PatchInfo newPatchInfo = processBundlePatch(hisPatchInfo, bundlePatches, curTPatchUnzipFolder);\n\n        // 比对主bundle的信息\n        PatchBundleInfo curMainBundleInfo = getMainBundleInfo(currentBuildPatchInfo);\n        PatchBundleInfo mainBundleInfo = new PatchBundleInfo();\n        mainBundleInfo.setMainBundle(true);\n        mainBundleInfo.setNewBundle(false);\n        if (null != curMainBundleInfo) {\n            File mainBundleFile = new File(curTPatchUnzipFolder, curMainBundleInfo.getName() + \".so\");\n            FileUtils.copyFileToDirectory(mainBundleFile, destTPathTmpFolder);\n            mainBundleInfo.setVersion(curMainBundleInfo.getVersion());\n            mainBundleInfo.setPkgName(curMainBundleInfo.getPkgName());\n            mainBundleInfo.setBaseVersion(curMainBundleInfo.getBaseVersion());\n            mainBundleInfo.setUnitTag(curMainBundleInfo.getUnitTag());\n            mainBundleInfo.setSrcUnitTag(curMainBundleInfo.getSrcUnitTag());\n            mainBundleInfo.setName(curMainBundleInfo.getName());\n            mainBundleInfo.setPkgName(curMainBundleInfo.getPkgName());\n            mainBundleInfo.setApplicationName(curMainBundleInfo.getApplicationName());\n            newPatchInfo.getBundles().add(mainBundleInfo);\n        }\n\n        // 生成tpatch文件\n        for (PatchBundleInfo bundleInfo : newPatchInfo.getBundles()) {\n            if (bundleInfo.getMainBundle() || bundleInfo.getNewBundle() || noPatchBundles.contains(\n                    bundleInfo.getPkgName())) {\n                File bundleFolder = new File(destTPathTmpFolder, bundleInfo.getName());\n                File soFile = new File(destTPathTmpFolder, bundleInfo.getName() + \".so\");\n                if (soFile.exists() || bundleInfo.getVersion().equals(ROLLBACK_VERSION)) {\n                    continue;\n                }\n                CommandUtils.exec(bundleFolder, \"zip -r \" + soFile.getAbsolutePath() + \" . -x */ -x .*\");\n                //                zipBunldeSo(bundleFolder, soFile);\n                FileUtils.deleteDirectory(bundleFolder);\n            }\n        }\n        File tPatchFile = new File(patchsFolder, newPatchInfo.getFileName());\n        if (tPatchFile.exists()) {\n            FileUtils.deleteQuietly(tPatchFile);\n        }\n        CommandUtils.exec(destTPathTmpFolder, \"zip -r \" + tPatchFile.getAbsolutePath() + \" . -x */ -x .*\");\n        if (null != logger) {\n            logger.info(\"[TPatchFile]\" + tPatchFile.getAbsolutePath());\n        }\n        return newPatchInfo;\n    }\n\n    /**\n     * generate main dex so\n     *\n     * @param bundleFolder\n     * @param soOutputFile\n     */\n    private void zipBunldeSo(File bundleFolder, File soOutputFile) throws PatchException {\n        try {\n            Manifest manifest = createManifest();\n            FileOutputStream fileOutputStream = new FileOutputStream(soOutputFile);\n            JarOutputStream jos = new JarOutputStream(new BufferedOutputStream(fileOutputStream), manifest);\n            // Add ZIP entry to output stream.\n            //            jos.setComment(patchVersion+\"@\"+targetVersion);\n            File[] files = bundleFolder.listFiles();\n            for (File file : files) {\n                if (file.isDirectory()) {\n                    addDirectory(jos, file, file.getName());\n                } else {\n                    addFile(jos, file);\n                }\n            }\n            IOUtils.closeQuietly(jos);\n            if (null != fileOutputStream) {\n                IOUtils.closeQuietly(fileOutputStream);\n            }\n        } catch (IOException e) {\n            throw new PatchException(e.getMessage(), e);\n        }\n    }\n\n    /**\n     * compare two patch\n     *\n     * @param hisPatchInfo\n     * @param currentPatchInfo\n     * @return\n     */\n    private List<BundlePatch> diffPatch(PatchInfo hisPatchInfo, PatchInfo currentPatchInfo) {\n        List<BundlePatch> list = new LinkedList<BundlePatch>();\n        Map<String, PatchBundleInfo> hisBundles = toMap(hisPatchInfo.getBundles());\n        Map<String, PatchBundleInfo> curBundles = toMap(currentPatchInfo.getBundles());\n        for (Map.Entry<String, PatchBundleInfo> entry : curBundles.entrySet()) {\n            String bundleName = entry.getKey();\n            PatchBundleInfo curBundleInfo = entry.getValue();\n            BundlePatch bundlePatch = new BundlePatch();\n            bundlePatch.name = curBundleInfo.getName();\n            bundlePatch.dependency = curBundleInfo.getDependency();\n            bundlePatch.pkgName = curBundleInfo.getPkgName();\n            bundlePatch.artifactId = curBundleInfo.getArtifactId();\n            bundlePatch.unitTag = curBundleInfo.getUnitTag();\n            bundlePatch.version = curBundleInfo.getVersion();\n            //            bundlePatch.srcUnitTag = curBundleInfo.getSrcUnitTag();\n            bundlePatch.newBundle = curBundleInfo.getNewBundle();\n            bundlePatch.hisPatchUrl = hisPatchInfo.getDownloadUrl();\n            bundlePatch.mainBundle = curBundleInfo.getMainBundle();\n            //            bundlePatch.baseVersion = curBundleInfo.getBaseVersion();\n            if (hisBundles.containsKey(bundleName)) { // 如果之前的patch版本也包含这个bundle的patch\n                bundlePatch.newBundle = false;\n                PatchBundleInfo hisBundleInfo = hisBundles.get(bundleName);\n                bundlePatch.baseVersion = hisBundleInfo.getVersion();\n                bundlePatch.srcUnitTag = hisBundleInfo.getUnitTag();\n                if (curBundleInfo.getVersion().equalsIgnoreCase(hisBundleInfo.getVersion())) { // 如果2个patch版本没变化\n                    // 说明:为了防止虽然版本号没变化但是文件内容也有变化的情况，直接也做merge操作\n\n                    if (curBundleInfo.getNewBundle()) {\n                        hisBundles.remove(bundleName);\n                        continue;\n                    }\n\n                    bundlePatch.bundlePolicy = BundlePolicy.MERGE;\n                } else {// 如果版本有变化，进行merge操作\n                    bundlePatch.bundlePolicy = BundlePolicy.MERGE;\n                }\n                hisBundles.remove(bundleName);\n            } else { // 如果历史的patch中没有包含该bundle\n                bundlePatch.bundlePolicy = BundlePolicy.ADD;\n                bundlePatch.srcUnitTag = curBundleInfo.getSrcUnitTag();\n            }\n            list.add(bundlePatch);\n        }\n\n        // 继续添加在历史版本里有变动的，在新的版本进行回滚的操作\n        for (Map.Entry<String, PatchBundleInfo> entry : hisBundles.entrySet()) {\n            PatchBundleInfo hisBundleInfo = entry.getValue();\n            BundlePatch bundlePatch = new BundlePatch();\n            bundlePatch.name = hisBundleInfo.getName();\n            bundlePatch.unitTag = hisBundleInfo.getUnitTag();\n            bundlePatch.srcUnitTag = hisBundleInfo.getSrcUnitTag();\n            bundlePatch.dependency = hisBundleInfo.getDependency();\n            bundlePatch.pkgName = hisBundleInfo.getPkgName();\n            bundlePatch.artifactId = hisBundleInfo.getArtifactId();\n            bundlePatch.bundlePolicy = BundlePolicy.ROLLBACK;\n            bundlePatch.version = ROLLBACK_VERSION;\n            bundlePatch.reset = true;\n            bundlePatch.baseVersion = hisBundleInfo.getVersion();\n            list.add(bundlePatch);\n        }\n        return list;\n    }\n\n    /**\n     * 解压当前的tpatch文件\n     */\n\n    private File unzipCurTPatchFolder(String patchName) throws IOException {\n        File curTPatchUnzipFolder = new File(currentPatchFile.getParentFile(), \"curTpatch\");\n        synchronized (this) {\n            if (curTPatchUnzipFolder.exists() && curTPatchUnzipFolder.isDirectory()) {\n                return curTPatchUnzipFolder;\n            }\n            curTPatchUnzipFolder.mkdirs();\n            CommandUtils.exec(tPatchTmpFolder,\n                    \"unzip \" + currentPatchFile.getAbsolutePath() + \" -d \" + curTPatchUnzipFolder\n                            .getAbsolutePath());\n            //            ZipUtils.unzip(currentPatchFile, curTPatchUnzipFolder.getAbsolutePath());\n            File[] libs = curTPatchUnzipFolder.listFiles();\n            if (libs != null && libs.length > 0) {\n                for (File lib : libs) {\n                    if (lib.isFile() && lib.getName().endsWith(\".so\")) {\n                        File destFolder = new File(lib.getParentFile(), FilenameUtils.getBaseName(lib.getName()));\n                        System.out.println(lib.getAbsolutePath());\n                        CommandUtils.exec(tPatchTmpFolder,\n                                \"unzip \" + lib.getAbsolutePath() + \" -d \" + destFolder.getAbsolutePath());\n                        //                        ZipUtils.unzip(lib, destFolder.getAbsolutePath());\n                    }\n                }\n            }\n        }\n        return curTPatchUnzipFolder;\n\n    }\n\n    /**\n     * process so file\n     *\n     * @param hisPatchInfo\n     * @param bundlePatchs\n     */\n    private PatchInfo processBundlePatch(PatchInfo hisPatchInfo, List<BundlePatch> bundlePatchs,\n                                         File curTPatchUnzipFolder) throws IOException,\n            PatchException {\n        String patchName = \"patch-\" + currentBuildPatchInfo.getPatchVersion() + \"@\" + hisPatchInfo.getPatchVersion();\n        PatchInfo patchInfo = new PatchInfo();\n        patchInfo.setFileName(patchName + \".tpatch\");\n        patchInfo.setTargetVersion(hisPatchInfo.getPatchVersion());\n        patchInfo.setPatchVersion(currentBuildPatchInfo.getPatchVersion());\n        File hisTPatchFile = new File(tPatchTmpFolder, hisPatchInfo.getPatchVersion() + \"-download.tpatch\");\n        File hisTPatchUnzipFolder = new File(tPatchTmpFolder, hisPatchInfo.getPatchVersion());\n        File destTPathTmpFolder = new File(tPatchTmpFolder, patchName);\n        if (!destTPathTmpFolder.exists()) {\n            destTPathTmpFolder.mkdirs();\n        }\n        File infoFile = new File(destTPathTmpFolder, \"patchInfo\");\n        FileUtils.writeStringToFile(infoFile, patchName);\n\n        for (BundlePatch bundlePatch : bundlePatchs) {\n            boolean addToPatch = true;\n            String bundleName = \"lib\" + bundlePatch.pkgName.replace('.', '_');\n            if (bundlePatch.mainBundle) {\n\n                continue;\n            } else if (noPatchBundles.contains(bundlePatch.pkgName)) {\n                File currentBundle = new File(curTPatchUnzipFolder,\n                        \"lib\" + bundlePatch.pkgName.replace(\".\", \"_\") + \".so\");\n                if (!currentBundle.exists()) {\n                    continue;\n                }\n                FileUtils.copyFileToDirectory(currentBundle, destTPathTmpFolder);\n                PatchBundleInfo patchBundleInfo = new PatchBundleInfo();\n                patchBundleInfo.setApplicationName(bundlePatch.applicationName);\n                patchBundleInfo.setArtifactId(bundlePatch.artifactId);\n                patchBundleInfo.setMainBundle(false);\n                patchBundleInfo.setSrcUnitTag(bundlePatch.srcUnitTag);\n                patchBundleInfo.setUnitTag(bundlePatch.unitTag);\n                patchBundleInfo.setNewBundle(bundlePatch.newBundle);\n                patchBundleInfo.setName(bundleName);\n                patchBundleInfo.setPkgName(bundlePatch.pkgName);\n                patchBundleInfo.setVersion(bundlePatch.version);\n                patchBundleInfo.setBaseVersion(bundlePatch.baseVersion);\n                patchBundleInfo.setDependency(bundlePatch.dependency);\n                patchInfo.getBundles().add(patchBundleInfo);\n                continue;\n            }\n\n            File curBundleFolder = new File(curTPatchUnzipFolder, bundleName);\n            File bundleDestFolder = new File(destTPathTmpFolder, bundleName);\n            PatchBundleInfo patchBundleInfo = new PatchBundleInfo();\n            patchBundleInfo.setApplicationName(bundlePatch.applicationName);\n            patchBundleInfo.setArtifactId(bundlePatch.artifactId);\n            patchBundleInfo.setSrcUnitTag(bundlePatch.srcUnitTag);\n            patchBundleInfo.setMainBundle(false);\n            patchBundleInfo.setUnitTag(bundlePatch.unitTag);\n            patchBundleInfo.setReset(bundlePatch.reset);\n            patchBundleInfo.setNewBundle(bundlePatch.newBundle);\n            patchBundleInfo.setName(bundleName);\n            patchBundleInfo.setPkgName(bundlePatch.pkgName);\n            patchBundleInfo.setVersion(bundlePatch.version);\n            patchBundleInfo.setBaseVersion(bundlePatch.baseVersion);\n            patchBundleInfo.setDependency(bundlePatch.dependency);\n            switch (bundlePatch.bundlePolicy) {\n                case ADD:\n                    if (bundlePatch.newBundle){\n                        File currentBundle = new File(curTPatchUnzipFolder,\n                                \"lib\" + bundlePatch.pkgName.replace(\".\", \"_\") + \".so\");\n                        FileUtils.copyFileToDirectory(currentBundle, tPatchTmpFolder);\n\n                    }else {\n                        bundleDestFolder.mkdirs();\n                        FileUtils.copyDirectory(curBundleFolder, bundleDestFolder);\n                    }\n                    break;\n                case REMOVE:\n                    addToPatch = false;\n                    break; // donothing\n                case ROLLBACK:// donothing\n                    break;\n                case MERGE:\n                    File hisBundleFolder = new File(hisTPatchUnzipFolder, bundleName);\n                    File hisBundle = new File(hisTPatchUnzipFolder, \"lib\" + bundlePatch.pkgName.replace(\".\", \"_\") + \".so\");\n\n                    if (!hisTPatchFile.exists()) {\n                        if (StringUtils.isBlank(hisPatchInfo.getDownloadUrl()) && new File(TPatchTool.hisTpatchFolder,\n                                hisPatchInfo.getFileName())\n                                .exists()) {\n                            File hisPatchFile = new File(TPatchTool.hisTpatchFolder, hisPatchInfo.getFileName());\n                            System.out.println(\"hisPatchFile:\" + hisPatchFile.getAbsolutePath());\n                            if (hisPatchFile.exists()) {\n                                FileUtils.copyFile(new File(TPatchTool.hisTpatchFolder, hisPatchInfo.getFileName()),\n                                        hisTPatchFile);\n                                CommandUtils.exec(tPatchTmpFolder,\n                                        \"unzip \" + hisPatchFile + \" -d \" + hisTPatchUnzipFolder\n                                                .getAbsolutePath());\n                                //                            ZipUtils.unzip(hisTPatchFile, hisTPatchUnzipFolder\n                                // .getAbsolutePath());\n                            }\n                        } else {\n                            downloadTPathAndUnzip(hisPatchInfo.getDownloadUrl(), hisTPatchFile, hisTPatchUnzipFolder);\n//                            File mainDexFile = new File(hisTPatchUnzipFolder,\"libcom_taobao_maindex.so\");\n//                            if (mainDexFile.exists()){\n//                                try {\n//                                    System.out.println(\"start put bundleInfos for version:\"+hisPatchInfo.getPatchVersion()+\"......\");\n//                                    TPatchTool.bundleInfos.put(hisPatchInfo.getPatchVersion(),new AtlasFrameworkPropertiesReader(\n//                                                                                                new MethodReader(\n//                                                                                                new ClassReader(\n//                                                                                                new DexReader(mainDexFile))),TPatchTool.bundleInfos.get(currentBuildPatchInfo.getPatchVersion())).read(\"Landroid/taobao/atlas/framework/FrameworkProperties;\",\"<clinit>\"));\n//                                } catch (Exception e) {\n//                                    e.printStackTrace();\n//                                }\n//                            }\n                        }\n                    }\n                    if (!hisBundleFolder.exists() && !hisBundle.exists()) {\n                        throw new IOException(hisBundleFolder.getAbsolutePath() + \" is not exist in history bundle!\");\n                    } else if (hisBundle.exists() && bundlePatch.bundlePolicy == BundlePolicy.MERGE) {\n                        File currentBundle = new File(curTPatchUnzipFolder,\n                                \"lib\" + bundlePatch.pkgName.replace(\".\", \"_\") + \".so\");\n                        if (currentBundle.exists() && awbMaps.get(bundlePatch.artifactId).exists()) {\n                            FileUtils.copyFileToDirectory(awbMaps.get(bundlePatch.artifactId), destTPathTmpFolder);\n                        }\n                    } else {\n                        File fullAwbFile = awbMaps.get(bundlePatch.artifactId);\n                        if (fullAwbFile == null) {\n                            System.out.println(bundlePatch.artifactId + \" is not exits!\");\n                            FileUtils.copyDirectory(curBundleFolder, bundleDestFolder);\n                            break;\n\n                        }\n                        copyDiffFiles(fullAwbFile, curBundleFolder, hisBundleFolder, bundleDestFolder, patchBundleInfo.getSrcUnitTag().equals(patchBundleInfo.getUnitTag()));\n                        if (!bundleDestFolder.exists() || FileUtils.listFiles(bundleDestFolder, null, true).size() == 0) {\n                            if (patchBundleInfo.getUnitTag().equals(patchBundleInfo.getSrcUnitTag())) {\n                                addToPatch = false;\n                            } else {\n//                                throw new PatchException(patchName+\"patch中:\"+patchBundleInfo.getPkgName()+\"的srcunittag和unittag不一致,\"+patchBundleInfo.getUnitTag()+\",\"+patchBundleInfo.getSrcUnitTag()+\"但是无任何变更,无法动态部署，请重新集成!\");\n                                patchBundleInfo.setInherit(true);\n                            }\n                        }\n                    }\n                    break;\n            }\n\n            if (addToPatch && patchBundleInfo.getUnitTag().equals(patchBundleInfo.getSrcUnitTag())) {\n\n                if (hisPatchInfo.getPatchVersion().split(\"\\\\.\").length == 3) {\n\n                    throw new PatchException(patchName + patchBundleInfo.getPkgName() + \" in patch srcunittag equals unittag,\" + patchBundleInfo.getUnitTag() + \",please upgrade bundle version and Reintegration!\");\n                }else {\n\n                    System.err.println(patchName + patchBundleInfo.getPkgName() + \" in patch srcunittag equals unittag,\" + patchBundleInfo.getUnitTag() + \",please upgrade bundle version and Reintegration!\");\n                }\n\n            } else if (addToPatch) {\n                patchInfo.getBundles().add(patchBundleInfo);\n            }\n        }\n        return patchInfo;\n    }\n\n    /**\n     * 复制拷贝有diff的文件\n     *\n     * @param fullLibFile\n     * @param curBundleFolder\n     * @param hisBundleFolder\n     * @param destBundleFolder\n     * @param bundleName\n     */\n    private void copyDiffFiles(File fullLibFile, File curBundleFolder, File hisBundleFolder,\n                               File destBundleFolder, boolean equalUnitTag) throws IOException, PatchException {\n        Map<String, FileDef> curBundleFileMap = getListFileMap(curBundleFolder);\n        Map<String, FileDef> hisBundleFileMap = getListFileMap(hisBundleFolder);\n        Set<String> rollbackFiles = new HashSet<String>();\n        // 判断差别\n        for (Map.Entry<String, FileDef> entry : curBundleFileMap.entrySet()) {\n            String curFilePath = entry.getKey();\n            FileDef curFileDef = entry.getValue();\n            if (curFileDef.file.getName().endsWith(\"abc_wb_textfield_cdf.jpg\") && equalUnitTag) {\n                hisBundleFileMap.remove(curFilePath);\n                continue;\n            }\n\n            File destFile = new File(destBundleFolder, curFilePath);\n            if (hisBundleFileMap.containsKey(curFilePath)) {\n                FileDef hisFileDef = hisBundleFileMap.get(curFilePath);\n                if (curFileDef.md5.equals(hisFileDef.md5)) {\n                    // donothing\n                } else if (curFileDef.file.getName().endsWith(\".patch\")) {\n                    genHisSoPatch(hisFileDef, destFile);\n                } else {\n                    FileUtils.copyFile(curFileDef.file, destFile);\n                }\n                hisBundleFileMap.remove(curFilePath);\n            } else { // 如果新的patch里有这个文件\n                FileUtils.copyFile(curFileDef.file, destFile);\n            }\n        }\n\n        for (Map.Entry<String, FileDef> entry : hisBundleFileMap.entrySet()) {\n            rollbackFiles.add(entry.getKey());\n        }\n        if (rollbackFiles.size() > 0) {\n            JarSplitUtils.splitZipToFolder(fullLibFile, destBundleFolder, rollbackFiles);\n        }\n    }\n\n    private void genHisSoPatch(FileDef hisFileDef, File destFile) throws IOException {\n        if (TPatchTool.soFileDefs.size() > 0) {\n            for (SoFileDef soFileDef : TPatchTool.soFileDefs) {\n                if (soFileDef.patchFile.getName().equals(hisFileDef.file.getName())) {\n                    File hisFullSo = new File(destFile.getParentFile(), soFileDef.baseSoFile.getName());\n                    SoDiffUtils.patchSo(hisFileDef.file.getParentFile(), soFileDef.baseSoFile, hisFullSo, hisFileDef.file);\n                    SoDiffUtils.diffSo(destFile.getParentFile(), hisFullSo, soFileDef.newSoFile, destFile);\n                    FileUtils.deleteQuietly(hisFullSo);\n                }\n            }\n\n        }\n\n    }\n\n\n    /**\n     * 将指定文件夹下的文件转换为map\n     *\n     * @param folder\n     * @return\n     * @throws PatchException\n     */\n    private Map<String, FileDef> getListFileMap(File folder) throws PatchException, IOException {\n        Map<String, FileDef> map = new HashMap<String, FileDef>();\n        if (!folder.exists() || !folder.isDirectory()) {\n            throw new PatchException(\"The input folder:\" + folder.getAbsolutePath()\n                    + \" does not existed or is not a directory!\");\n        }\n        Collection<File> files = FileUtils.listFiles(folder, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);\n        for (File file : files) {\n            String path = PathUtils.toRelative(folder, file.getAbsolutePath());\n            String md5 = MD5Util.getFileMD5String(file);\n            FileDef fileDef = new FileDef(md5, path, file);\n            map.put(path, fileDef);\n        }\n        return map;\n    }\n\n    public void setHistroyVersionList(List<String> versionList) {\n        this.versionList = versionList;\n\n    }\n\n    // 简易文件定义\n    class FileDef {\n\n        String md5;\n        String relativePath;\n        File file;\n\n        public FileDef(String md5, String relativePath, File file) {\n            this.md5 = md5;\n            this.relativePath = relativePath;\n            this.file = file;\n        }\n    }\n\n    /**\n     * download file\n     *\n     * @param httpUrl\n     * @param saveFile\n     * @param tmpUnzipFolder\n     * @throws IOException\n     */\n    private void downloadTPathAndUnzip(String httpUrl, File saveFile, File tmpUnzipFolder) throws IOException {\n        if (!saveFile.exists() || !saveFile.isFile()) {\n            downloadFile(httpUrl, saveFile);\n        }\n        //        ZipUtils.unzip(saveFile, tmpUnzipFolder.getAbsolutePath());\n        CommandUtils.exec(tPatchTmpFolder,\n                \"unzip \" + saveFile.getAbsolutePath() + \" -d \" + tmpUnzipFolder.getAbsolutePath());\n    }\n\n    /**\n     * http下载\n     */\n    private void downloadFile(String httpUrl, File saveFile) throws IOException {\n        // 下载网络文件\n        int bytesum = 0;\n        int byteread = 0;\n        URL url = new URL(httpUrl);\n        URLConnection conn = url.openConnection();\n        InputStream inStream = conn.getInputStream();\n        FileOutputStream fs = new FileOutputStream(saveFile);\n\n        byte[] buffer = new byte[1204];\n        while ((byteread = inStream.read(buffer)) != -1) {\n            bytesum += byteread;\n            fs.write(buffer, 0, byteread);\n        }\n        fs.flush();\n        inStream.close();\n        fs.close();\n    }\n\n    /**\n     * @param bundles\n     * @return\n     */\n    private Map<String, PatchBundleInfo> toMap(List<PatchBundleInfo> bundles) {\n        Map<String, PatchBundleInfo> bundleMap = new HashMap<String, PatchBundleInfo>();\n        for (PatchBundleInfo bundle : bundles) {\n            bundleMap.put(bundle.getArtifactId(), bundle);\n        }\n        return bundleMap;\n    }\n\n    /**\n     * @return\n     */\n    private Manifest createManifest() {\n        Manifest manifest = new Manifest();\n        Attributes main = manifest.getMainAttributes();\n        main.putValue(\"Manifest-Version\", \"1.0\");\n        main.putValue(\"Created-By\", \"1.0 (JarPatch)\");\n        main.putValue(\"Created-Time\", new Date(System.currentTimeMillis()).toGMTString());\n        return manifest;\n    }\n\n    /**\n     * @param jos\n     * @param file\n     */\n    private void addFile(JarOutputStream jos, File file) throws PatchException {\n        byte[] buf = new byte[8064];\n        String path = file.getName();\n        InputStream in = null;\n        try {\n            in = new FileInputStream(file);\n            ZipEntry fileEntry = new ZipEntry(path);\n            jos.putNextEntry(fileEntry);\n            // Transfer bytes from the file to the ZIP file\n            int len;\n            while ((len = in.read(buf)) > 0) {\n                jos.write(buf, 0, len);\n            }\n            // Complete the entry\n            jos.closeEntry();\n            in.close();\n        } catch (IOException e) {\n            throw new PatchException(e.getMessage(), e);\n        }\n    }\n\n    /**\n     * Adds a directory to a  with a directory prefix.\n     *\n     * @param jos       ZipArchiver to use to archive the file.\n     * @param directory The directory to add.\n     * @param prefix    An optional prefix for where in the Jar file the directory's contents should go.\n     */\n    protected void addDirectory(JarOutputStream jos, File directory, String prefix) throws PatchException {\n        if (directory != null && directory.exists()) {\n            Collection<File> files = FileUtils.listFiles(directory, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);\n            byte[] buf = new byte[8064];\n            for (File file : files) {\n                if (file.isDirectory()) {\n                    continue;\n                }\n                String path = prefix + File.separator + PathUtils.toRelative(directory, file.getAbsolutePath());\n                InputStream in = null;\n                try {\n                    in = new FileInputStream(file);\n                    ZipEntry fileEntry = new ZipEntry(path);\n                    jos.putNextEntry(fileEntry);\n                    // Transfer bytes from the file to the ZIP file\n                    int len;\n                    while ((len = in.read(buf)) > 0) {\n                        jos.write(buf, 0, len);\n                    }\n                    // Complete the entry\n                    jos.closeEntry();\n                    in.close();\n                } catch (IOException e) {\n                    throw new PatchException(e.getMessage(), e);\n                }\n            }\n        }\n    }\n\n    class BundlePatch {\n\n        String pkgName;\n        String applicationName;\n        List<String> dependency;\n        String name;\n        String artifactId;\n        boolean newBundle;\n        BundlePolicy bundlePolicy;\n        String version;\n        String hisPatchUrl;\n        boolean mainBundle;\n        String baseVersion;\n        String unitTag;\n        String srcUnitTag;\n        boolean reset;\n    }\n\n    /**\n     * 表示当前patch的bundle与之前patch版本的策略，包括合并,回滚,无变化\n     */\n    enum BundlePolicy {\n        ADD,\n        MERGE,\n        REMOVE,\n        ROLLBACK;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/manifest/AXMLPrint.java",
    "content": "package com.taobao.android.tpatch.manifest;\n\nimport android.content.res.AXMLResource;\nimport org.apache.commons.io.IOUtils;\n\nimport javax.xml.bind.JAXBContext;\nimport javax.xml.bind.JAXBException;\nimport javax.xml.bind.Unmarshaller;\nimport java.io.ByteArrayInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\n\n/**\n */\npublic class AXMLPrint {\n    public static String decodeManifest(File manifestFile){\n        FileInputStream in = null;\n\n        try {\n            AXMLResource axmlResource = new AXMLResource();\n            in = new FileInputStream(manifestFile);\n            axmlResource.read(in);\n            return axmlResource.toXmlString();\n        } catch (Exception e) {\n            e.printStackTrace();\n        } finally {\n            IOUtils.closeQuietly(in);\n\n        }\n        return null;\n    }\n\n    public static Manifest paresManfiest(File manifestFile) throws JAXBException {\n        String manifestXml =  AXMLPrint.decodeManifest(manifestFile);\n        JAXBContext context = JAXBContext.newInstance(Manifest.class);\n        Unmarshaller unmarshaller = context.createUnmarshaller();\n        InputStream stream = new ByteArrayInputStream(manifestXml.getBytes(StandardCharsets.UTF_8));\n        Manifest manifest = (Manifest) unmarshaller.unmarshal(stream);\n        return manifest;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/manifest/AndroidManifestDiffFactory.java",
    "content": "package com.taobao.android.tpatch.manifest;\n\nimport java.io.File;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * @author lilong\n * @create 2017-03-13 上午9:55\n */\n\npublic class AndroidManifestDiffFactory {\n\n    public Set<DiffItem>diffResuit = new HashSet<DiffItem>();\n\n    public void diff(File baseAndroidManifest,File newAndroidManifest) throws Exception {\n        Manifest baseManifest = AXMLPrint.paresManfiest(baseAndroidManifest);\n        Manifest newManifest = AXMLPrint.paresManfiest(newAndroidManifest);\n        diff(baseManifest,newManifest);\n\n\n    }\n\n    private void diff(Manifest baseManifest, Manifest newManifest) {\n\n       diff(baseManifest.getApplication().activitys,newManifest.getApplication().activitys);\n       diff(baseManifest.getApplication().providers,newManifest.getApplication().providers);\n       diff(baseManifest.getApplication().services,newManifest.getApplication().services);\n       diff(baseManifest.getApplication().receivers,newManifest.getApplication().receivers);\n    }\n\n    private void diff(Collection<? extends Manifest.AndroidBase> baseCollection, Collection<? extends Manifest.AndroidBase>newCollection){\n        if (newCollection == null||baseCollection == null){\n            return;\n        }\n        for (Manifest.AndroidBase newAndroidBase:newCollection){\n            String name = newAndroidBase.name;\n            boolean find = false;\n            for (Manifest.AndroidBase baseAndroidBase:baseCollection){\n                String baseName = baseAndroidBase.name;\n                if (baseName.equals(name)){\n                    find = true;\n                    if (baseAndroidBase.toString().equals(newAndroidBase.toString())){\n                        //do nothind\n//                        diffResuit.add(new DiffItem(DiffType.NONE,newAndroidBase));\n                    }else {\n                        diffResuit.add(new DiffItem(DiffType.MODIFY,newAndroidBase));\n                    }\n\n                    break;\n                }\n            }\n            if (!find){\n                diffResuit.add(new DiffItem(DiffType.ADD,newAndroidBase));\n            }\n        }\n\n\n\n    }\n\n\n    public class DiffItem {\n\n        public DiffType diffType;\n        public Manifest.AndroidBase Component;\n\n        public DiffItem(DiffType diffType, Manifest.AndroidBase name) {\n            this.diffType = diffType;\n            this.Component = name;\n        }\n    }\n\n    enum DiffType{\n        ADD,REMOVE,MODIFY,NONE\n    }\n\n    public static void main(String[]args) throws Exception {\n        AndroidManifestDiffFactory androidManifestDiffFactory = new AndroidManifestDiffFactory();\n        androidManifestDiffFactory.diff(new File(\"/Users/lilong/Downloads/10004583@taobao_android_6.5.0/AndroidManifest.xml\"),new File(\"/Users/lilong/Downloads/tpatch-diff/AndroidManifest.xml\"));\n        Set<DiffItem>sets = androidManifestDiffFactory.diffResuit;\n        System.out.println(\"xxx\");\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/manifest/Manifest.java",
    "content": "package com.taobao.android.tpatch.manifest;\n\n\nimport org.apache.commons.lang3.StringUtils;\n\nimport javax.xml.bind.annotation.XmlAccessType;\nimport javax.xml.bind.annotation.XmlAccessorType;\nimport javax.xml.bind.annotation.XmlAttribute;\nimport javax.xml.bind.annotation.XmlElement;\nimport javax.xml.bind.annotation.XmlElements;\nimport javax.xml.bind.annotation.XmlRootElement;\nimport java.util.List;\n\n/***\n *\n *\n */\n@XmlRootElement(name= \"manifest\")\n@XmlAccessorType(XmlAccessType.FIELD)\npublic class Manifest {\n\n\t@XmlAttribute(name = \"package\")\n\tpublic String packageName;\n\t@XmlAttribute(name = \"versionCode\", namespace = \"http://schemas.android.com/apk/res/android\")\n\tpublic int versionCode;\n\n\t@XmlAttribute(name = \"versionName\", namespace = \"http://schemas.android.com/apk/res/android\")\n\tpublic String versionName;\n\n\t@XmlElement(name =\"uses-sdk\")\n\tpublic UsesSdk usesSdk;\n\n\t@XmlElements({@XmlElement(name=\"permission\", type=Permission.class)})\n\tpublic List<Permission> permissions;\n\n\t@XmlElements({@XmlElement(name=\"users-permission\", type=UsePermission.class)})\n\tpublic List<UsePermission> usePermissions;\n\n\t@XmlElement(name =\"application\")\n\tprivate Application application;\n\n\tpublic Application getApplication(){\n\t\tif(application == null){\n\t\t\tapplication=new Application();\n\t\t}\n\t\treturn application;\n\t}\n\t@Override\n\tpublic String toString() {\n\t\treturn \"Manifest [\\n packageName=\" + packageName + \", versionCode=\" + versionCode + \", versionName=\"\n\t\t\t\t+ versionName + \",\\n usesSdk=\" + usesSdk + \"\\n    permissions=\\n\\t\" + permissions\n\t\t\t\t+ \"\\n    usePermissions=\\n\\t\" + usePermissions + \"\\n application=\" + application + \"\\n]\";\n\t}\n\n\tpublic static class UsesSdk {\n\t\t@XmlAttribute(name = \"minSdkVersion\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic int minSdkVersion;\n\t\t@XmlAttribute(name = \"maxSdkVersion\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic int maxSdkVersion;\n\t\t@XmlAttribute(name = \"targetSdkVersion\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic int targetSdkVersion;\n\n\t\t@Override\n\t\tpublic String toString() {\n\t\t\treturn \"[minSdkVersion=\" + minSdkVersion + \", maxSdkVersion=\" + maxSdkVersion + \", targetSdkVersion=\"\n\t\t\t\t\t+ targetSdkVersion + \"]\";\n\t\t}\n\n\t}\n\n\tprivate static class NameBase {\n\t\t@XmlAttribute(name = \"name\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic String name;\n\n\t\t@Override\n\t\tpublic String toString() {\n\t\t\treturn \"\\n\\t\" + name;\n\t\t}\n\t}\n\n\tpublic static class UsePermission extends NameBase {\n\t}\n\n\tpublic static class Permission extends NameBase {\n\t\t@XmlAttribute(name = \"protectionLevel\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic String protectionLevel;\n\n\t\t@Override\n\t\tpublic String toString() {\n\t\t\treturn \"name=\" + name + \",protectionLevel=\" + protectionLevel;\n\t\t}\n\t}\n\n\tpublic static class MetaData {\n\t\t@XmlAttribute(name = \"name\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic String name;\n\t\t@XmlAttribute(name = \"value\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic String value;\n\n\t\tpublic MetaData(){\n\t\t\t\n\t\t}\n\t\tpublic MetaData(String name, String value) {\n\t\t\tsuper();\n\t\t\tthis.name = name;\n\t\t\tthis.value = value;\n\t\t}\n\n\t\t@Override\n\t\tpublic String toString() {\n\t\t\treturn \"\\n\\t\\t\" + name + \"=\" + value;\n\t\t}\n\n\t\tpublic String getValue(){\n\t\t\treturn value;\n\t\t}\n\t}\n\n\tpublic static class AndroidBase {\n\t\t@XmlAttribute(name = \"theme\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic String theme;\n\t\t@XmlAttribute(name = \"label\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic String label;\n\t\t@XmlAttribute(name = \"icon\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic String icon;\n\t\t@XmlAttribute(name = \"name\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic String name;\n\n\t\t@XmlElements({@XmlElement(name=\"meta-data\", type=MetaData.class)})\n\t\tpublic List<MetaData> metadatas;\n\n\t\tpublic int getTheme() {\n\t\t\treturn getInteger(theme);\n\t\t}\n\t\tpublic int getIcon() {\n\t\t\treturn getInteger(icon);\n\t\t}\n\n\t\tpublic int getLabel() {\n\t\t\treturn getInteger(label);\n\t\t}\n\n\t\tprivate int getInteger(String str) {\n\t\t\tif (str == null || str.trim().length() == 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\treturn Integer.parseInt(str.replace(\"@\", \"\"));\n\t\t}\n\t\tpublic MetaData getMetaData(String name){\n\t\t\tif(metadatas!=null){\n\t\t\t\tfor(MetaData data:metadatas){\n\t\t\t\t\tif(StringUtils.equals(data.name, name)){\n\t\t\t\t\t\treturn data;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new MetaData(name, null);\n\t\t}\n\t\tpublic List<MetaData> getMetaDatas(){\n\t\t\treturn metadatas;\n\t\t}\n\t}\n\n\tpublic static class Application extends AndroidBase {\n\t\t@XmlAttribute(name = \"hardwareAccelerated\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic boolean hardwareAccelerated;\n\t\t@XmlAttribute(name = \"allowBackup\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic boolean allowBackup;\n\n\t\t@XmlElements({@XmlElement(name=\"activity\", type=Activity.class)})\n\t\tpublic List<Activity> activitys;\n\t\t@XmlElements({@XmlElement(name=\"provider\", type=Provider.class)})\n\t\tpublic List<Provider> providers;\n\t\t@XmlElements({@XmlElement(name=\"receiver\", type=Receiver.class)})\n\t\tpublic List<Receiver> receivers;\n\t\t@XmlElements({@XmlElement(name=\"service\", type=Service.class)})\n\t\tpublic List<Service> services;\n\n\t\t@Override\n\t\tpublic String toString() {\n\t\t\treturn \"[name=\" + name + \",\\n\\tallowBackup=\" + allowBackup + \",hardwareAccelerated=\" + hardwareAccelerated\n\t\t\t\t\t+ \",\\n\\t\" + \"theme=\" + theme + \",label=\" + label + \",icon=\" + icon + \",\\n\\tmetadata=\" + metadatas\n\t\t\t\t\t+ \"\\n\\tactivitys=\" + activitys + \"\\n\\tproviders=\" + providers + \"\\n\\treceivers=\" + receivers\n\t\t\t\t\t+ \"\\n\\tservices=\" + services + \"\\n\\t]\";\n\t\t}\n\t}\n\n\tpublic static class IntentFilter {\n\t\t@XmlElements({@XmlElement(name=\"action\", type=NameBase.class)})\n\t\tpublic List<NameBase> actions;\n\t\t@XmlElements({@XmlElement(name=\"category\", type=NameBase.class)})\n\t\tpublic List<NameBase> categorys;\n\t\t@XmlAttribute(name = \"priority\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic long priority;\n\t\t@XmlElements({@XmlElement(name=\"data\", type=IntentData.class)})\n\t\tpublic List<IntentData> datas;\n\n\t\tprivate String getDatas() {\n\t\t\tif (datas == null) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tint count = datas.size();\n\t\t\tint i = 0;\n\t\t\tStringBuffer stringBuffer = new StringBuffer(\"[\\n\\t\\t\\t\");\n\t\t\tfor (IntentData data : datas) {\n\t\t\t\ti++;\n\t\t\t\tstringBuffer.append(data);\n\t\t\t\tif (i != count) {\n\t\t\t\t\tstringBuffer.append(\",\\n\\t\\t\\t\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tstringBuffer.append(\"]\");\n\t\t\treturn stringBuffer.toString();\n\t\t}\n\n\t\t@Override\n\t\tpublic String toString() {\n\t\t\treturn \"\\n\\t\\tIntentFilter [priority=\" + priority + \",\\n\\t\\tactions=\" + actions + \",\\n\\t\\tcategorys=\"\n\t\t\t\t\t+ categorys + \",\\n\\t\\tdatas=\" + getDatas() + \"\\n\\t\\t]\";\n\t\t}\n\n\t}\n\n\tpublic static class IntentData {\n\t\t@XmlAttribute(name = \"scheme\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic String scheme;\n\t\t@XmlAttribute(name = \"host\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic String host;\n\t\t@XmlAttribute(name = \"path\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic String path;\n\n\t\t@Override\n\t\tpublic String toString() {\n\t\t\treturn \"data[scheme=\" + scheme + \",host=\" + host + \",path=\" + path + \"]\";\n\t\t}\n\t}\n\n\tpublic static class ContextBase extends AndroidBase {\n\t\t@XmlAttribute(name = \"exported\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic boolean exported = false;\n\t\t@XmlAttribute(name = \"enabled\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic boolean enabled = true;\n\t\t@XmlAttribute(name = \"permission\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic String permission;\n\t\t@XmlElements({@XmlElement(name=\"intent-filter\", type=IntentFilter.class)})\n\t\tpublic List<IntentFilter> intentFilters;\n\t}\n\n\tpublic static class Service extends ContextBase {\n\t\t@Override\n\t\tpublic String toString() {\n\t\t\treturn \"\\n\\tService[name=\" + name + \",enabled=\" + enabled + \",exported=\" + exported + \",\\n\\tpermission=\"\n\t\t\t\t\t+ permission + \",\\n\\t\" + \"theme=\" + theme + \",label=\" + label + \",icon=\" + icon + \",\\n\\tmetadata=\"\n\t\t\t\t\t+ metadatas + \"\\n\\t]\";\n\t\t}\n\t}\n\n\tpublic static class Receiver extends ContextBase {\n\t\t@Override\n\t\tpublic String toString() {\n\t\t\treturn \"\\n\\tReceiver[name=\" + name + \",enabled=\" + enabled + \",exported=\" + exported + \",\\n\\tpermission=\"\n\t\t\t\t\t+ permission + \",\\n\\t\" + \"theme=\" + theme + \",label=\" + label + \",icon=\" + icon + \",\\n\\tmetadata=\"\n\t\t\t\t\t+ metadatas + \"\\n\\t]\";\n\t\t}\n\t}\n\n\tpublic static class Provider extends ContextBase {\n\t\t@Override\n\t\tpublic String toString() {\n\t\t\treturn \"\\n\\tProvider[name=\" + name + \",enabled=\" + enabled + \",exported=\" + exported + \",\\n\\tpermission=\"\n\t\t\t\t\t+ permission + \",\\n\\t\" + \"theme=\" + theme + \",label=\" + label + \",icon=\" + icon + \",\\n\\tmetadata=\"\n\t\t\t\t\t+ metadatas + \"\\n\\t]\";\n\t\t}\n\t}\n\n\tpublic static class Activity extends ContextBase {\n\t\t@XmlAttribute(name = \"launchMode\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic int launchMode;\n\t\t@XmlAttribute(name = \"screenOrientation\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic int screenOrientation;\n\t\t@XmlAttribute(name = \"configChanges\", namespace = \"http://schemas.android.com/apk/res/android\")\n\t\tpublic String configChanges;\n\n\t\t@Override\n\t\tpublic String toString() {\n\t\t\treturn \"\\n\\tActivity[name=\" + name + \",enabled=\" + enabled + \",exported=\" + exported + \",\\n\\tpermission=\"\n\t\t\t\t\t+ \",launchMode=\" + launchMode + \",permission=\" + permission + \",enabled=\" + enabled + \",exported=\"\n\t\t\t\t\t+ exported + \",configChanges=\" + configChanges + \",screenOrientation=\" + screenOrientation + \",\\n\\t\"\n\t\t\t\t\t+ \"theme=\" + theme + \",label=\" + label + \",icon=\" + icon + \",\\n\\tmetadata=\" + metadatas\n\t\t\t\t\t+ \",\\n\\tintentFilters=\" + intentFilters + \"\\n\\t]\";\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/model/ApkBO.java",
    "content": "package com.taobao.android.tpatch.model;\n\nimport java.io.File;\n\n/**\n * @author lilong\n * @create 2017-03-27 下午1:22\n */\n\npublic class ApkBO {\n\n\n    public ApkBO(File apkFile, String versionName, String apkName) {\n        this.apkFile = apkFile;\n        this.versionName = versionName;\n        this.apkName = apkName;\n    }\n\n    private File apkFile;\n\n    public File getApkFile() {\n        return apkFile;\n    }\n\n    public String getVersionName() {\n        return versionName;\n    }\n\n    public String getApkName() {\n        return apkName;\n    }\n    private String versionName;\n    private String apkName;\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/model/BundleBO.java",
    "content": "package com.taobao.android.tpatch.model;\n\nimport java.io.File;\n\n/**\n * @author lilong\n * @create 2017-03-27 下午1:23\n */\n\npublic class BundleBO {\n    private String bundleName;\n\n    public String getBundleName() {\n        return bundleName;\n    }\n\n    public File getBundleFile() {\n        return bundleFile;\n    }\n\n    public String getBundleVersion() {\n        return bundleVersion;\n    }\n\n    private File bundleFile;\n    private String bundleVersion;\n\n    public BundleBO(String bundleName, File bundleFile, String bundleVersion) {\n        this.bundleName = bundleName;\n        this.bundleFile = bundleFile;\n        this.bundleVersion = bundleVersion;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/model/PatchFile.java",
    "content": "package com.taobao.android.tpatch.model;\n\nimport com.taobao.android.object.SoFileDef;\nimport com.taobao.android.tpatch.utils.MD5Util;\nimport org.apache.commons.io.FileUtils;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * PatchFile\n *\n * @author zhayu.ll\n * @date 18/5/10\n */\npublic class PatchFile {\n\n    private File patchFile;\n\n    private List<String>patchInfo = new ArrayList<>();\n\n    public PatchFile(File patchFile) {\n        assert patchFile!= null;\n        this.patchFile = patchFile;\n\n    }\n\n    public void append(SoFileDef soFileDef){\n        String newSoMd5 = null;\n        try {\n            newSoMd5 = MD5Util.getFileMD5String(soFileDef.newSoFile);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        patchInfo.add(soFileDef.relativePath+\":\"+ newSoMd5);\n    }\n\n    public void close(){\n        try {\n            FileUtils.writeLines(patchFile,patchInfo);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/utils/DexBuilderUtils.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.tpatch.utils;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.taobao.android.dx.command.dexer.Main;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.List;\n\n/**\n * Created by shenghua.nish on 2016-03-15 下午9:11.\n */\npublic class DexBuilderUtils {\n    /**\n     * 获取签名文件\n     * @param dexFile\n     * @return\n     */\n    public static File getDexSignFile(File dexFile) {\n        File signFile = new File(dexFile.getParentFile(), dexFile.getName() + \".md5\");\n        return signFile;\n\n    }\n\n    /**\n     * 在jvm中编译dex\n     * @param inJar\n     * @param outDex\n     * @param commandArgs\n     * @return\n     * @throws IOException\n     */\n    public static File buildDexInJvm(File inJar, File outDex, List<String> commandArgs) throws IOException {\n        File parentDir = outDex.getParentFile();\n        parentDir.mkdirs();\n        //先用3个线程来运行\n        commandArgs.add(\"--num-threads=3\");\n        commandArgs.add(\"--output=\" + outDex.getAbsolutePath());\n        commandArgs.add(inJar.getAbsolutePath());\n        String[] args = new String[commandArgs.size()];\n        commandArgs.toArray(args);\n//        Main.Arguments arguments = new Main.Arguments();\n//        arguments.parse(args);\n        new Main().main(args);\n\n        return outDex;\n    }\n\n\n\n//    /**\n//     * 合并dex\n//     * @param dexs\n//     * @param outDexFile\n//     * @param policy\n//     * @return\n//     * @throws IOException\n//     */\n//    public static File mergeDex(List<File> dexs, File outDexFile,CollisionPolicy policy) throws IOException {\n//        List<Dex> dexList = new ArrayList<Dex>();\n//        for (File dexFile : dexs) {\n//            dexList.add(new Dex(dexFile));\n//        }\n////        Dex[] dexArray = new Dex[dexList.size()];\n////        dexList.toArray(dexArray);\n//        DexMerger merger = new DexMerger(dexList.toArray(), policy);\n//        Dex outDex = merger.merge();\n//        outDex.writeTo(outDexFile);\n//        return outDexFile;\n//    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/utils/FileLock.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.tpatch.utils;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\nimport java.nio.channels.FileChannel;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\n/**\n * Created by lilong on 16/7/14.\n */\npublic class FileLock {\n\n    private static class FileLockCount {\n        RandomAccessFile fOs;\n        FileChannel fChannel;\n        java.nio.channels.FileLock mFileLock;\n        int mRefCount;\n\n        FileLockCount(java.nio.channels.FileLock mFileLock, int mRefCount, RandomAccessFile fOs, FileChannel fChannel) {\n            this.mFileLock = mFileLock;\n            this.mRefCount = mRefCount;\n            this.fOs = fOs;\n            this.fChannel = fChannel;\n        }\n    }\n\n    private static Map<String, FileLockCount> mRefCountMap = new ConcurrentHashMap<String, FileLockCount>();\n\n\n    private static int RefCntInc(String name, java.nio.channels.FileLock fileLock, RandomAccessFile fOs, FileChannel fChannel) {\n        Integer val = 0;\n\n        if (mRefCountMap.containsKey(name)) {\n            val = mRefCountMap.get(name).mRefCount++;\n        } else {\n            val = 1;\n            FileLockCount newFileLockCount = new FileLockCount(fileLock, val, fOs, fChannel);\n            mRefCountMap.put(name, newFileLockCount);\n        }\n\n        return val;\n    }\n\n\n    private static int RefCntDec(String name) {\n        Integer val = 0;\n\n        if (mRefCountMap.containsKey(name)) {\n            val = --mRefCountMap.get(name).mRefCount;\n            /*\n             * Remove the item once value is already 0\n\t\t\t */\n            if (val <= 0) {\n                mRefCountMap.remove(name);\n            }\n        }\n\n        return val;\n    }\n\n\n    public static boolean Lock(File orgFile) {\n        RandomAccessFile fOs = null;\n        FileChannel fChannel = null;\n        try {\n            if (orgFile == null) {\n                return false;\n            }\n\n            File file = new File(orgFile.getParentFile().getAbsolutePath().concat(\"/lock\"));\n            if (file.exists() != true) {\n                file.createNewFile();\n            }\n\n            fOs = new RandomAccessFile(file.getAbsolutePath(), \"rw\");\n            fChannel = fOs.getChannel();\n\n            java.nio.channels.FileLock fFileLock = fChannel.lock();\n            if (fFileLock.isValid()) {\n                RefCntInc(file.getAbsolutePath(), fFileLock, fOs, fChannel);\n                return true;\n            }\n        } catch (Exception e) {\n\n        }\n        return false;\n    }\n\n\n    public static void unLock(File orgFile) {\n\n        File file = new File(orgFile.getParentFile().getAbsolutePath().concat(\"/lock\"));\n        if (file.exists() == false) {\n            return;\n        }\n\n        if ((file != null) && !mRefCountMap.containsKey(file.getAbsolutePath())) {\n            return;\n        }\n\n        FileLockCount flc = mRefCountMap.get(file.getAbsolutePath());\n        if (flc == null) {\n            return;\n        }\n\n        java.nio.channels.FileLock fl = flc.mFileLock;\n        RandomAccessFile fOs = flc.fOs;\n        FileChannel fChannel = flc.fChannel;\n\n        try {\n            if (RefCntDec(file.getAbsolutePath()) <= 0) {\n                if (fl != null && fl.isValid()) {\n                    fl.release();\n                }\n                if (fOs != null) {\n                    fOs.close();\n                }\n                if (fChannel != null) {\n                    fChannel.close();\n                }\n            }\n        } catch (IOException e) {\n\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/utils/HttpClientUtils.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.tpatch.utils;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport org.apache.http.HttpEntity;\nimport org.apache.http.HttpResponse;\nimport org.apache.http.client.HttpClient;\nimport org.apache.http.client.methods.HttpGet;\nimport org.apache.http.impl.client.DefaultHttpClient;\nimport org.apache.http.params.CoreConnectionPNames;\nimport org.apache.http.util.EntityUtils;\n\nimport java.io.IOException;\n\n\n/**\n * 简易的Http工具类\n * Created by shenghua.nish on 2015-12-22 下午11:27.\n */\npublic class HttpClientUtils {\n\n    /**\n     * 简单的获取http get结果\n     * @param url\n     * @return\n     * @throws IOException\n     */\n    public static String getUrl(String url) throws IOException {\n        HttpClient httpclient = new DefaultHttpClient();\n        httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 3000);\n        HttpGet httpget = new HttpGet(url);\n        HttpResponse response = httpclient.execute(httpget);\n        HttpEntity entity = response.getEntity();\n        String html = EntityUtils.toString(entity, \"UTF-8\");\n        httpget.releaseConnection();\n        return html;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/utils/JarSplitUtils.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.tpatch.utils;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport org.apache.commons.io.FileUtils;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.jar.JarEntry;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\nimport java.util.zip.ZipOutputStream;\n\n/**\n * jar包分割的工具类\n * Created by shenghua.nish on 2015-11-05 下午4:15.\n */\npublic class JarSplitUtils {\n\n    /**\n     * 移除指定jar文件中的class\n     * @param inJar\n     * @param removeClasses\n     */\n    public static void removeFilesFromJar(File inJar, List<String> removeClasses) throws IOException {\n        if(null == removeClasses || removeClasses.isEmpty()){\n            return;\n        }\n        File outJar = new File(inJar.getParentFile(), inJar.getName() + \".tmp\");\n        File outParentFolder = outJar.getParentFile();\n        if (!outParentFolder.exists()) {\n            outParentFolder.mkdirs();\n        }\n        FileOutputStream fos = new FileOutputStream(outJar);\n        ZipOutputStream jos = new ZipOutputStream(fos);\n        final byte[] buffer = new byte[8192];\n        FileInputStream fis = new FileInputStream(inJar);\n        ZipInputStream zis = new ZipInputStream(fis);\n\n        try {\n            // loop on the entries of the jar file package and put them in the final jar\n            ZipEntry entry;\n            while ((entry = zis.getNextEntry()) != null) {\n                // do not take directories or anything inside a potential META-INF folder.\n                if (entry.isDirectory()||!entry.getName().endsWith(\".class\")) {\n                    continue;\n                }\n                String name = entry.getName();\n                String className = getClassName(name);\n                if (removeClasses.contains(className)) {\n                    continue;\n                }\n                JarEntry newEntry;\n                // Preserve the STORED method of the input entry.\n                if (entry.getMethod() == JarEntry.STORED) {\n                    newEntry = new JarEntry(entry);\n                } else {\n                    // Create a new entry so that the compressed len is recomputed.\n                    newEntry = new JarEntry(name);\n                }\n                // add the entry to the jar archive\n                jos.putNextEntry(newEntry);\n\n                // read the content of the entry from the input stream, and write it into the archive.\n                int count;\n                while ((count = zis.read(buffer)) != -1) {\n                    jos.write(buffer, 0, count);\n                }\n                // close the entries for this file\n                jos.closeEntry();\n                zis.closeEntry();\n            }\n        } finally {\n            zis.close();\n        }\n        fis.close();\n        jos.close();\n        FileUtils.deleteQuietly(inJar);\n        FileUtils.moveFile(outJar,inJar);\n    }\n\n    /**\n     * 对2个jar做对比,产生包含没有变化的jar\n     * @param baseJar\n     * @param diffJar\n     * @param outJar\n     */\n    public static void unionJar(File baseJar, File diffJar, File outJar) throws IOException {\n        File outParentFolder = outJar.getParentFile();\n        if (!outParentFolder.exists()) {\n            outParentFolder.mkdirs();\n        }\n        List<String> diffEntries = getZipEntries(diffJar);\n        FileOutputStream fos = new FileOutputStream(outJar);\n        ZipOutputStream jos = new ZipOutputStream(fos);\n        final byte[] buffer = new byte[8192];\n        FileInputStream fis = new FileInputStream(baseJar);\n        ZipInputStream zis = new ZipInputStream(fis);\n\n        try {\n            // loop on the entries of the jar file package and put them in the final jar\n            ZipEntry entry;\n            while ((entry = zis.getNextEntry()) != null) {\n                // do not take directories or anything inside a potential META-INF folder.\n                if (entry.isDirectory()) {\n                    continue;\n                }\n                String name = entry.getName();\n                if (diffEntries.contains(name)) {\n                    continue;\n                }\n                JarEntry newEntry;\n                // Preserve the STORED method of the input entry.\n                if (entry.getMethod() == JarEntry.STORED) {\n                    newEntry = new JarEntry(entry);\n                } else {\n                    // Create a new entry so that the compressed len is recomputed.\n                    newEntry = new JarEntry(name);\n                }\n                // add the entry to the jar archive\n                jos.putNextEntry(newEntry);\n\n                // read the content of the entry from the input stream, and write it into the archive.\n                int count;\n                while ((count = zis.read(buffer)) != -1) {\n                    jos.write(buffer, 0, count);\n                }\n                // close the entries for this file\n                jos.closeEntry();\n                zis.closeEntry();\n            }\n        } finally {\n            zis.close();\n        }\n        fis.close();\n        jos.close();\n\n    }\n\n    /**\n     * 获取jar文件的entry列表\n     *\n     * @param jarFile\n     * @return\n     */\n    public static List<String> getZipEntries(File jarFile) throws IOException {\n        List<String> entries = new ArrayList<String>();\n        FileInputStream fis = new FileInputStream(jarFile);\n        ZipInputStream zis = new ZipInputStream(fis);\n        try {\n            // loop on the entries of the jar file package and put them in the final jar\n            ZipEntry entry;\n            while ((entry = zis.getNextEntry()) != null) {\n                // do not take directories or anything inside a potential META-INF folder.\n                if (entry.isDirectory()) {\n                    continue;\n                }\n                String name = entry.getName();\n                entries.add(name);\n            }\n        } finally {\n            zis.close();\n        }\n        return entries;\n    }\n\n\n    public static void splitZip(File inputFile, File outputFile, Set<String> includeEnties) throws IOException {\n        if (outputFile.exists()) {\n            FileUtils.deleteQuietly(outputFile);\n        }\n        if (null == includeEnties || includeEnties.size() < 1) {\n            return;\n        }\n        FileOutputStream fos = new FileOutputStream(outputFile);\n        ZipOutputStream jos = new ZipOutputStream(fos);\n        final byte[] buffer = new byte[8192];\n        FileInputStream fis = new FileInputStream(inputFile);\n        ZipInputStream zis = new ZipInputStream(fis);\n\n        try {\n            // loop on the entries of the jar file package and put them in the final jar\n            ZipEntry entry;\n            while ((entry = zis.getNextEntry()) != null) {\n                // do not take directories or anything inside a potential META-INF folder.\n                if (entry.isDirectory()) {\n                    continue;\n                }\n                String name = entry.getName();\n                if (!includeEnties.contains(name)) {\n                    continue;\n                }\n                JarEntry newEntry;\n                // Preserve the STORED method of the input entry.\n                if (entry.getMethod() == JarEntry.STORED) {\n                    newEntry = new JarEntry(entry);\n                } else {\n                    // Create a new entry so that the compressed len is recomputed.\n                    newEntry = new JarEntry(name);\n                }\n                // add the entry to the jar archive\n                jos.putNextEntry(newEntry);\n\n                // read the content of the entry from the input stream, and write it into the archive.\n                int count;\n                while ((count = zis.read(buffer)) != -1) {\n                    jos.write(buffer, 0, count);\n                }\n                // close the entries for this file\n                jos.closeEntry();\n                zis.closeEntry();\n            }\n        } finally {\n            zis.close();\n        }\n        fis.close();\n        jos.close();\n    }\n\n    public static void splitZipToFolder(File inputFile, File outputFolder,\n                                        Set<String> includeEnties) throws IOException {\n        if (!outputFolder.exists()) {\n            outputFolder.mkdirs();\n        }\n        if (null == includeEnties || includeEnties.size() < 1) {\n            return;\n        }\n        final byte[] buffer = new byte[8192];\n        FileInputStream fis = new FileInputStream(inputFile);\n        ZipInputStream zis = new ZipInputStream(fis);\n\n        try {\n            // loop on the entries of the jar file package and put them in the final jar\n            ZipEntry entry;\n            while ((entry = zis.getNextEntry()) != null) {\n                // do not take directories or anything inside a potential META-INF folder.\n                if (entry.isDirectory()) {\n                    continue;\n                }\n                String name = entry.getName();\n                if (!includeEnties.contains(name)) {\n                    continue;\n                }\n                File destFile = new File(outputFolder, name);\n                destFile.getParentFile().mkdirs();\n                // read the content of the entry from the input stream, and write it into the archive.\n                int count;\n                FileOutputStream fout = FileUtils.openOutputStream(destFile);\n                while ((count = zis.read(buffer)) != -1) {\n                    fout.write(buffer, 0, count);\n                }\n                fout.close();\n                zis.closeEntry();\n            }\n        } finally {\n            zis.close();\n        }\n        fis.close();\n    }\n    /**\n     * 从entry的名字从获取\n     *\n     * @param zipEntryName\n     * @return\n     */\n    public static String getClassName(String zipEntryName) {\n        String className = zipEntryName.replaceAll(\"/\", \".\");\n        className = className.substring(0, className.lastIndexOf(\".\"));\n        return className;\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/utils/MD5Util.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.tpatch.utils;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport org.apache.commons.io.IOUtils;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.nio.MappedByteBuffer;\nimport java.nio.channels.FileChannel;\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\n\n/**<p>MD5的工具类</p>\n * Created by shenghua.nish on 2015-09-30 下午5:54.\n */\npublic class MD5Util {\n    /**\n     * 默认的密码字符串组合，apache校验下载的文件的正确性用的就是默认的这个组合\n     */\n    private final static String[] hexDigits = { \"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"a\", \"b\", \"c\", \"d\",\n            \"e\", \"f\" };\n    protected static MessageDigest messagedigest = null;\n    static {\n        try {\n            messagedigest = MessageDigest.getInstance(\"MD5\");\n        } catch (NoSuchAlgorithmException nsaex) {\n        }\n    }\n    /**\n     * 向getMD5方法传入一个你需要转换的原始字符串，将返回字符串的MD5码\n     *\n     * @param bytes\n     *            原始字符串\n     * @return 返回字符串的MD5码\n     */\n    public static String getMD5(byte[] bytes) throws NoSuchAlgorithmException {\n        MessageDigest messageDigest = MessageDigest.getInstance(\"MD5\");\n        byte[] results = messageDigest.digest(bytes);\n        StringBuilder stringBuilder = new StringBuilder();\n        for (byte result : results) {\n            // 将byte数组转化为16进制字符存入stringbuilder中\n            stringBuilder.append(String.format(\"%02x\", result));\n        }\n        return stringBuilder.toString();\n    }\n\n\n    public synchronized static String getFileMD5String(File file) throws IOException {\n        FileInputStream in = null;\n        try {\n             in = new FileInputStream(file);\n            FileChannel ch = in.getChannel();\n            MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,\n                    file.length());\n            messagedigest.update(byteBuffer);\n            return bufferToHex(messagedigest.digest());\n        }finally {\n            IOUtils.closeQuietly(in);\n        }\n    }\n\n    private static String bufferToHex(byte bytes[]) {\n        return bufferToHex(bytes, 0, bytes.length);\n    }\n\n    private static String bufferToHex(byte bytes[], int m, int n) {\n        StringBuffer stringbuffer = new StringBuffer(2 * n);\n        int k = m + n;\n        for (int l = m; l < k; l++) {\n            appendHexPair(bytes[l], stringbuffer);\n        }\n        return stringbuffer.toString();\n    }\n\n    private static void appendHexPair(byte bt, StringBuffer stringbuffer) {\n        String c0 = hexDigits[(bt & 0xf0) >> 4];\n        String c1 = hexDigits[bt & 0xf];\n        stringbuffer.append(c0);\n        stringbuffer.append(c1);\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/utils/PatchUtils.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.tpatch.utils;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.taobao.android.utils.ZipUtils;\n\nimport org.apache.commons.compress.archivers.zip.ZipArchiveEntry;\nimport org.apache.commons.compress.archivers.zip.ZipFile;\nimport org.apache.commons.io.FileUtils;\nimport org.jf.dexlib2.DexFileFactory;\nimport org.jf.dexlib2.Opcodes;\nimport org.jf.dexlib2.iface.ClassDef;\n\nimport java.io.File;\nimport java.io.FileFilter;\nimport java.io.FilenameFilter;\nimport java.io.IOException;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\n\n/**\n * Created by shenghua.nish on 2016-03-20 下午5:26.\n */\npublic class PatchUtils {\n\n    private final static String[] BUNDLE_FILES = new String[]{\"AndroidManifest.xml\"};\n\n    /**\n     * 判断当前so文件是否为bundle\n     *\n     * @param soFile\n     * @return\n     */\n    public static boolean isBundleFile(File soFile) {\n        ZipFile zf = null;\n        try {\n            zf = new ZipFile(soFile);\n            Enumeration<ZipArchiveEntry> en = zf.getEntries();\n            if (en.hasMoreElements()) {\n                for (String name : BUNDLE_FILES) {\n                    ZipArchiveEntry zipArchiveEntry = zf.getEntry(name);\n                    if (null == zipArchiveEntry) {\n                        return false;\n                    }\n\n                }\n                return true;\n            }\n            return false;\n        } catch (IOException e) {\n            return false;\n        } finally {\n            if (null != zf) {\n                try {\n                    zf.close();\n                } catch (IOException e) {\n                }\n            }\n        }\n    }\n\n    public static void getTpatchClassDef(File tpatchFile, Map<String, Map<String, ClassDef>> bundleMap) throws IOException {\n        if (tpatchFile == null || !tpatchFile.exists()) {\n            return;\n        }\n        File unZipFolder = new File(tpatchFile.getParentFile(), tpatchFile.getName().split(\"\\\\.\")[0]);\n        unZipFolder.mkdirs();\n        ZipUtils.unzip(tpatchFile, unZipFolder.getAbsolutePath());\n        File[] bundleFolder = unZipFolder.listFiles(new FileFilter() {\n            @Override\n            public boolean accept(File pathname) {\n                return pathname.isDirectory() && pathname.getName().startsWith(\"lib\");\n            }\n        });\n\n        for (File file : bundleFolder) {\n            Map<String, ClassDef> dexClasses = getBundleClassDef(file);\n            bundleMap.put(file.getName(), dexClasses);\n\n        }\n\n        FileUtils.deleteDirectory(tpatchFile.getParentFile());\n    }\n\n    private static Map<String, ClassDef> getBundleClassDef(File file) throws IOException {\n        HashMap<String, ClassDef> classDefMap = new HashMap<String, ClassDef>();\n        File[] dexFiles = getDexFiles(file);\n        HashSet<ClassDef> classDefs = new HashSet<ClassDef>();\n        for (File dexFile : dexFiles) {\n            classDefs.addAll(DexFileFactory.loadDexFile(dexFile, Opcodes.getDefault()).getClasses());\n        }\n        for (ClassDef classDef : classDefs) {\n            classDefMap.put(classDef.getType(), classDef);\n        }\n\n        return classDefMap;\n    }\n\n    private static File[] getDexFiles(File file) {\n        return file.listFiles(new FilenameFilter() {\n            @Override\n            public boolean accept(File dir, String name) {\n                return name.endsWith(\".dex\");\n            }\n        });\n    }\n\n\n    public static void main(String[] args) {\n        File soFile = new File(\"/Users/shenghua/Downloads/patch-5.5.3@5.5.0.tpatch/1\");\n        System.out.println(PatchUtils.isBundleFile(soFile));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/utils/PathUtils.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.tpatch.utils;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport java.io.File;\nimport java.util.StringTokenizer;\n\n/**\n * Created by shenghua.nish on 2016-03-19 下午9:17.\n */\npublic class PathUtils {\n    private PathUtils() {\n    }\n\n    public static String dirname(String path) {\n        int i = path.lastIndexOf(\"/\");\n        return i >= 0?path.substring(0, i):\"\";\n    }\n\n    public static String filename(String path) {\n        int i = path.lastIndexOf(\"/\");\n        return i >= 0?path.substring(i + 1):path;\n    }\n\n    public static String[] dirnames(String path) {\n        String dirname = dirname(path);\n        return split(dirname, \"/\", -1);\n    }\n\n    private static String[] split(String str, String separator, int max) {\n        StringTokenizer tok;\n        if(separator == null) {\n            tok = new StringTokenizer(str);\n        } else {\n            tok = new StringTokenizer(str, separator);\n        }\n\n        int listSize = tok.countTokens();\n        if(max > 0 && listSize > max) {\n            listSize = max;\n        }\n\n        String[] list = new String[listSize];\n        int i = 0;\n\n        for(int lastTokenEnd = 0; tok.hasMoreTokens(); ++i) {\n            int lastTokenBegin;\n            if(max > 0 && i == listSize - 1) {\n                String endToken = tok.nextToken();\n                lastTokenBegin = str.indexOf(endToken, lastTokenEnd);\n                list[i] = str.substring(lastTokenBegin);\n                break;\n            }\n\n            list[i] = tok.nextToken();\n            lastTokenBegin = str.indexOf(list[i], lastTokenEnd);\n            lastTokenEnd = lastTokenBegin + list[i].length();\n        }\n\n        return list;\n    }\n\n    public static String host(String url) {\n        String authorization = authorization(url);\n        int index = authorization.indexOf(64);\n        return index >= 0?authorization.substring(index + 1):authorization;\n    }\n\n    static String authorization(String url) {\n        if(url == null) {\n            return \"localhost\";\n        } else {\n            String protocol = protocol(url);\n            if(protocol != null && !protocol.equalsIgnoreCase(\"file\")) {\n                String host = url;\n                if(protocol.equalsIgnoreCase(\"scm\")) {\n                    host = url.substring(url.indexOf(\":\", 4) + 1).trim();\n                }\n\n                host = host.substring(host.indexOf(\":\") + 1).trim();\n                if(host.startsWith(\"//\")) {\n                    host = host.substring(2);\n                }\n\n                int pos = host.indexOf(\"/\");\n                if(pos > 0) {\n                    host = host.substring(0, pos);\n                }\n\n                pos = host.indexOf(64);\n                if(pos > 0) {\n                    pos = host.indexOf(58, pos);\n                } else {\n                    pos = host.indexOf(\":\");\n                }\n\n                if(pos > 0) {\n                    host = host.substring(0, pos);\n                }\n\n                return host;\n            } else {\n                return \"localhost\";\n            }\n        }\n    }\n\n    public static String protocol(String url) {\n        int pos = url.indexOf(\":\");\n        return pos == -1?\"\":url.substring(0, pos).trim();\n    }\n\n    public static int port(String url) {\n        String protocol = protocol(url);\n        if(protocol != null && !protocol.equalsIgnoreCase(\"file\")) {\n            String authorization = authorization(url);\n            if(authorization == null) {\n                return -1;\n            } else {\n                if(protocol.equalsIgnoreCase(\"scm\")) {\n                    url = url.substring(url.indexOf(\":\", 4) + 1).trim();\n                }\n\n                if(!url.regionMatches(true, 0, \"file:\", 0, 5) && !url.regionMatches(true, 0, \"local:\", 0, 6)) {\n                    url = url.substring(url.indexOf(\":\") + 1).trim();\n                    if(url.startsWith(\"//\")) {\n                        url = url.substring(2);\n                    }\n\n                    int start = authorization.length();\n                    if(url.length() > start && url.charAt(start) == 58) {\n                        int end = url.indexOf(47, start);\n                        if(end == start + 1) {\n                            return -1;\n                        } else {\n                            if(end == -1) {\n                                end = url.length();\n                            }\n\n                            return Integer.parseInt(url.substring(start + 1, end));\n                        }\n                    } else {\n                        return -1;\n                    }\n                } else {\n                    return -1;\n                }\n            }\n        } else {\n            return -1;\n        }\n    }\n\n    public static String basedir(String url) {\n        String protocol = protocol(url);\n        String retValue = null;\n        if(protocol.equalsIgnoreCase(\"scm\") && url.regionMatches(true, 0, \"scm:svn:\", 0, 8)) {\n            url = url.substring(url.indexOf(\":\", 4) + 1);\n            protocol = protocol(url);\n        }\n\n        if(protocol.equalsIgnoreCase(\"file\")) {\n            retValue = url.substring(protocol.length() + 1);\n            retValue = decode(retValue);\n            if(retValue.startsWith(\"//\")) {\n                retValue = retValue.substring(2);\n                if(retValue.length() < 2 || retValue.charAt(1) != 124 && retValue.charAt(1) != 58) {\n                    int authorization = retValue.indexOf(\"/\");\n                    if(authorization >= 0) {\n                        retValue = retValue.substring(authorization + 1);\n                    }\n\n                    if(retValue.length() >= 2 && (retValue.charAt(1) == 124 || retValue.charAt(1) == 58)) {\n                        retValue = retValue.charAt(0) + \":\" + retValue.substring(2);\n                    } else if(authorization >= 0) {\n                        retValue = \"/\" + retValue;\n                    }\n                } else {\n                    retValue = retValue.charAt(0) + \":\" + retValue.substring(2);\n                }\n            }\n\n            if(retValue.length() >= 2 && retValue.charAt(1) == 124) {\n                retValue = retValue.charAt(0) + \":\" + retValue.substring(2);\n            }\n        } else {\n            String authorization1 = authorization(url);\n            int port = port(url);\n            int pos = 0;\n            if(protocol.equalsIgnoreCase(\"scm\")) {\n                pos = url.indexOf(\":\", 4) + 1;\n                pos = url.indexOf(\":\", pos) + 1;\n            } else {\n                int index = url.indexOf(\"://\");\n                if(index != -1) {\n                    pos = index + 3;\n                }\n            }\n\n            pos += authorization1.length();\n            if(port != -1) {\n                pos = pos + Integer.toString(port).length() + 1;\n            }\n\n            if(url.length() > pos) {\n                retValue = url.substring(pos);\n                if(retValue.startsWith(\":\")) {\n                    retValue = retValue.substring(1);\n                }\n\n                retValue = retValue.replace(':', '/');\n            }\n        }\n\n        if(retValue == null) {\n            retValue = \"/\";\n        }\n\n        return retValue.trim();\n    }\n\n    private static String decode(String url) {\n        String decoded = url;\n        if(url != null) {\n            int pos = -1;\n\n            while((pos = decoded.indexOf(37, pos + 1)) >= 0) {\n                if(pos + 2 < decoded.length()) {\n                    String hexStr = decoded.substring(pos + 1, pos + 3);\n                    char ch = (char)Integer.parseInt(hexStr, 16);\n                    decoded = decoded.substring(0, pos) + ch + decoded.substring(pos + 3);\n                }\n            }\n        }\n\n        return decoded;\n    }\n\n    public static String user(String url) {\n        String host = authorization(url);\n        int index = host.indexOf(64);\n        if(index > 0) {\n            String userInfo = host.substring(0, index);\n            index = userInfo.indexOf(58);\n            if(index > 0) {\n                return userInfo.substring(0, index);\n            }\n\n            if(index < 0) {\n                return userInfo;\n            }\n        }\n\n        return null;\n    }\n\n    public static String password(String url) {\n        String host = authorization(url);\n        int index = host.indexOf(64);\n        if(index > 0) {\n            String userInfo = host.substring(0, index);\n            index = userInfo.indexOf(58);\n            if(index >= 0) {\n                return userInfo.substring(index + 1);\n            }\n        }\n\n        return null;\n    }\n\n    public static String toRelative(File basedir, String absolutePath) {\n        absolutePath = absolutePath.replace('\\\\', '/');\n        String basedirPath = basedir.getAbsolutePath().replace('\\\\', '/');\n        String relative;\n        if(absolutePath.startsWith(basedirPath)) {\n            relative = absolutePath.substring(basedirPath.length());\n            if(relative.startsWith(\"/\")) {\n                relative = relative.substring(1);\n            }\n\n            if(relative.length() <= 0) {\n                relative = \".\";\n            }\n        } else {\n            relative = absolutePath;\n        }\n\n        return relative;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/tpatch/utils/SmaliUtils.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.tpatch.utils;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.google.common.collect.ImmutableList;\nimport com.google.common.collect.Iterables;\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Ordering;\nimport com.taobao.android.smali.BakSmali;\nimport com.taobao.android.smali.SmaliMod;\nimport org.antlr.runtime.RecognitionException;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.jf.baksmali.Adaptors.ClassDefinition;\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.dexlib2.DexFileFactory;\nimport org.jf.dexlib2.Opcode;\nimport org.jf.dexlib2.Opcodes;\nimport org.jf.dexlib2.analysis.ClassPath;\nimport org.jf.dexlib2.analysis.CustomInlineMethodResolver;\nimport org.jf.dexlib2.iface.ClassDef;\nimport org.jf.dexlib2.iface.DexFile;\nimport org.jf.dexlib2.util.SyntheticAccessorResolver;\nimport org.jf.dexlib2.writer.builder.DexBuilder;\nimport org.jf.dexlib2.writer.io.FileDataStore;\nimport org.jf.util.ClassFileNameHandler;\nimport org.jf.util.IndentingWriter;\nimport org.xml.sax.Attributes;\nimport org.xml.sax.SAXException;\nimport org.xml.sax.helpers.DefaultHandler;\n\nimport javax.annotation.Nullable;\nimport javax.xml.parsers.ParserConfigurationException;\nimport javax.xml.parsers.SAXParser;\nimport javax.xml.parsers.SAXParserFactory;\nimport java.io.*;\nimport java.util.*;\nimport java.util.concurrent.*;\n\n/**\n * Created by shenghua.nish on 2016-04-11 上午12:22.\n */\npublic class SmaliUtils {\n    protected static final int    DEFAULT_API_LEVEL   = 19;\n\n\n    /**\n     * 将dex文件转换为smali文件\n     * @param dex\n     * @param outputDir\n     * @param includeClasses 需要做过滤的文件\n     */\n    public static boolean disassembleDexFile(File dex, File outputDir,\n                                             final Set<String> includeClasses) throws IOException {\n        final BaksmaliOptions options = createBaksmaliOptions();\n        if (!outputDir.exists()) {\n            outputDir.mkdirs();\n        }\n\n        DexFile dexFile = DexFileFactory.loadDexFile(dex,Opcodes.getDefault());\n        List<? extends ClassDef> classDefs = Ordering.natural().sortedCopy(dexFile.getClasses());\n\n        final ClassFileNameHandler fileNameHandler = new ClassFileNameHandler(outputDir, \".smali\");\n\n        ExecutorService executor = Executors.newFixedThreadPool(4);\n        List<Future<Boolean>> tasks = Lists.newArrayList();\n\n        Set<String> classSet = null;\n        if (includeClasses != null) {\n            classSet = new HashSet<String>(includeClasses);\n        }\n\n        for (final ClassDef classDef: classDefs) {\n            String className = getDalvikClassName(classDef.getType());\n\n            if (classSet != null && !classSet.contains(className)) {\n                continue;\n            }\n            tasks.add(executor.submit(new Callable<Boolean>() {\n                @Override public Boolean call() throws Exception {\n                    return BakSmali.disassembleClass(classDef, fileNameHandler, options);\n                }\n            }));\n        }\n\n        boolean errorOccurred = false;\n        try {\n            for (Future<Boolean> task: tasks) {\n                while(true) {\n                    try {\n                        if (!task.get()) {\n                            errorOccurred = true;\n                        }\n                    } catch (InterruptedException ex) {\n                        continue;\n                    } catch (ExecutionException ex) {\n                        throw new RuntimeException(ex);\n                    }\n                    break;\n                }\n            }\n        } finally {\n            executor.shutdown();\n        }\n        return !errorOccurred;\n    }\n\n\n    private static boolean disassembleClass(ClassDef classDef, ClassFileNameHandler fileNameHandler,\n                                            BaksmaliOptions options) {\n        /**\n         * The path for the disassembly file is based on the package name\n         * The class descriptor will look something like:\n         * Ljava/lang/Object;\n         * Where the there is leading 'L' and a trailing ';', and the parts of the\n         * package name are separated by '/'\n         */\n        String classDescriptor = classDef.getType();\n\n        //validate that the descriptor is formatted like we expect\n        if (classDescriptor.charAt(0) != 'L' ||\n                classDescriptor.charAt(classDescriptor.length()-1) != ';') {\n            System.err.println(\"Unrecognized class descriptor - \" + classDescriptor + \" - skipping class\");\n            return false;\n        }\n\n        File smaliFile = fileNameHandler.getUniqueFilenameForClass(classDescriptor);\n\n        //create and initialize the top level string template\n        ClassDefinition classDefinition = new ClassDefinition(options, classDef);\n\n        //write the disassembly\n        Writer writer = null;\n        try\n        {\n            File smaliParent = smaliFile.getParentFile();\n            if (!smaliParent.exists()) {\n                if (!smaliParent.mkdirs()) {\n                    // check again, it's likely it was created in a different thread\n                    if (!smaliParent.exists()) {\n                        System.err.println(\"Unable to create directory \" + smaliParent.toString() + \" - skipping class\");\n                        return false;\n                    }\n                }\n            }\n\n            if (!smaliFile.exists()){\n                if (!smaliFile.createNewFile()) {\n                    System.err.println(\"Unable to create file \" + smaliFile.toString() + \" - skipping class\");\n                    return false;\n                }\n            }\n\n            BufferedWriter bufWriter = new BufferedWriter(new OutputStreamWriter(\n                    new FileOutputStream(smaliFile), \"UTF8\"));\n\n            writer = new IndentingWriter(bufWriter);\n            classDefinition.writeTo((IndentingWriter)writer);\n        } catch (Exception ex) {\n            System.err.println(\"\\n\\nError occurred while disassembling class \" + classDescriptor.replace('/', '.') + \" - skipping class\");\n            ex.printStackTrace();\n            // noinspection ResultOfMethodCallIgnored\n            smaliFile.delete();\n            return false;\n        }\n        finally\n        {\n            if (writer != null) {\n                try {\n                    writer.close();\n                } catch (Throwable ex) {\n                    System.err.println(\"\\n\\nError occurred while closing file \" + smaliFile.toString());\n                    ex.printStackTrace();\n                }\n            }\n        }\n        return true;\n    }\n\n    /**\n     * 将dex文件转换为smali文件\n     * @param dexFile\n     * @param outputDir\n     */\n    public static boolean disassembleDexFile(File dexFile, File outputDir) throws IOException {\n       return disassembleDexFile(dexFile,outputDir,null);\n    }\n\n\n    /**\n     * 将smali文件夹转换为dex文件\n     * @param smaliFolder\n     * @param outDexFile\n     * @return\n     */\n    public static boolean assembleSmaliFile(File smaliFolder,File outDexFile) throws IOException, RecognitionException {\n        Collection<File> smaliFiles =  FileUtils.listFiles(smaliFolder, new String[]{\"smali\"}, true);\n        if(null!= smaliFiles && smaliFiles.size() > 0){\n            DexBuilder dexBuilder = new DexBuilder(Opcodes.getDefault());\n            for(File smaliFile:smaliFiles){\n                SmaliMod.assembleSmaliFile(smaliFile, dexBuilder, true, true);\n            }\n            dexBuilder.writeTo(new FileDataStore(outDexFile));\n            return true;\n        }else{\n            return false;\n        }\n    }\n\n    /**\n     * 生成解析成smali代码的选项\n     * @return\n     */\n    private static BaksmaliOptions createBaksmaliOptions() {\n        BaksmaliOptions options = new BaksmaliOptions();\n        options.deodex = false;\n        options.parameterRegisters = false;\n        options.localsDirective = true;\n        options.sequentialLabels = true;\n        options.debugInfo = true;\n        options.codeOffsets = false;\n        options.accessorComments = false;\n        options.registerInfo = 0;// 128\n        options.inlineResolver = null;\n        options.apiLevel = DEFAULT_API_LEVEL;\n        return options;\n    }\n\n    /**\n     * 获取davik中的class名字\n     * @param className\n     * @return\n     */\n    public static String getDalvikClassName(String className) {\n        if (className.charAt(0) != 'L' || className.charAt(className.length() - 1) != ';') {\n            throw new RuntimeException(\"Not a valid dalvik class name\"+className);\n        }\n        return StringUtils.replace(className.substring(1, className.length() - 1), \"/\", \".\");\n    }\n\n    public static void main(String [] args) throws IOException {\n        File dexFile = new File(\"/Users/shenghua/Downloads/taobao-android.ap/android.apk/classes.dex\");\n        SmaliUtils.disassembleDexFile(dexFile,new File(\"/Users/shenghua/Downloads/taobao-android.ap/smali\"));\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/transform/DexTransform.java",
    "content": "package com.taobao.android.transform;\n\nimport com.taobao.android.dex.*;\nimport com.taobao.android.dx.merge.*;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\n\n/**\n * @author lilong\n * @create 2017-07-10 下午2:32\n */\n\npublic class DexTransform {\n        private final Dex[] dexes;\n        private final IndexMap[] indexMaps;\n\n        private final CollisionPolicy collisionPolicy;\n        private final WriterSizes writerSizes;\n\n        private final Dex dexOut;\n\n        private final Dex.Section headerOut;\n\n        /** All IDs and definitions sections */\n        private final Dex.Section idsDefsOut;\n\n        private final Dex.Section mapListOut;\n\n        private final Dex.Section typeListOut;\n\n        private final Dex.Section classDataOut;\n\n        private final Dex.Section codeOut;\n\n        private final Dex.Section stringDataOut;\n\n        private final Dex.Section debugInfoOut;\n\n        private final Dex.Section encodedArrayOut;\n\n        /** annotations directory on a type */\n        private final Dex.Section annotationsDirectoryOut;\n\n        /** sets of annotations on a member, parameter or type */\n        private final Dex.Section annotationSetOut;\n\n        /** parameter lists */\n        private final Dex.Section annotationSetRefListOut;\n\n        /** individual annotations, each containing zero or more fields */\n        private final Dex.Section annotationOut;\n\n        private final TableOfContents contentsOut;\n\n        private final InstructionTransformer instructionTransformer;\n\n        /** minimum number of wasted bytes before it's worthwhile to compact the result */\n        private int compactWasteThreshold = 1024 * 1024; // 1MiB\n        private List<String> classDefList;\n\n    public DexTransform(Dex[] dexes, CollisionPolicy collisionPolicy)\n                throws IOException {\n            this(dexes, collisionPolicy, new WriterSizes(dexes));\n        }\n\n        private DexTransform(Dex[] dexes, CollisionPolicy collisionPolicy,\n                          WriterSizes writerSizes) throws IOException {\n            this.dexes = dexes;\n            this.collisionPolicy = collisionPolicy;\n            this.writerSizes = writerSizes;\n\n            dexOut = new Dex(writerSizes.size());\n\n            indexMaps = new IndexMap[dexes.length];\n            for (int i = 0; i < dexes.length; i++) {\n                indexMaps[i] = new IndexMap(dexOut, dexes[i].getTableOfContents());\n            }\n            instructionTransformer = new InstructionTransformer();\n\n            headerOut = dexOut.appendSection(writerSizes.header, \"header\");\n            idsDefsOut = dexOut.appendSection(writerSizes.idsDefs, \"ids defs\");\n\n            contentsOut = dexOut.getTableOfContents();\n            contentsOut.dataOff = dexOut.getNextSectionStart();\n\n            contentsOut.mapList.off = dexOut.getNextSectionStart();\n            contentsOut.mapList.size = 1;\n            mapListOut = dexOut.appendSection(writerSizes.mapList, \"map list\");\n\n            contentsOut.typeLists.off = dexOut.getNextSectionStart();\n            typeListOut = dexOut.appendSection(writerSizes.typeList, \"type list\");\n\n            contentsOut.annotationSetRefLists.off = dexOut.getNextSectionStart();\n            annotationSetRefListOut = dexOut.appendSection(\n                    writerSizes.annotationsSetRefList, \"annotation set ref list\");\n\n            contentsOut.annotationSets.off = dexOut.getNextSectionStart();\n            annotationSetOut = dexOut.appendSection(writerSizes.annotationsSet, \"annotation sets\");\n\n            contentsOut.classDatas.off = dexOut.getNextSectionStart();\n            classDataOut = dexOut.appendSection(writerSizes.classData, \"class data\");\n\n            contentsOut.codes.off = dexOut.getNextSectionStart();\n            codeOut = dexOut.appendSection(writerSizes.code, \"code\");\n\n            contentsOut.stringDatas.off = dexOut.getNextSectionStart();\n            stringDataOut = dexOut.appendSection(writerSizes.stringData, \"string data\");\n\n            contentsOut.debugInfos.off = dexOut.getNextSectionStart();\n            debugInfoOut = dexOut.appendSection(writerSizes.debugInfo, \"debug info\");\n\n            contentsOut.annotations.off = dexOut.getNextSectionStart();\n            annotationOut = dexOut.appendSection(writerSizes.annotation, \"annotation\");\n\n            contentsOut.encodedArrays.off = dexOut.getNextSectionStart();\n            encodedArrayOut = dexOut.appendSection(writerSizes.encodedArray, \"encoded array\");\n\n            contentsOut.annotationsDirectories.off = dexOut.getNextSectionStart();\n            annotationsDirectoryOut = dexOut.appendSection(\n                    writerSizes.annotationsDirectory, \"annotations directory\");\n\n            contentsOut.dataSize = dexOut.getNextSectionStart() - contentsOut.dataOff;\n        }\n\n        public void setCompactWasteThreshold(int compactWasteThreshold) {\n            this.compactWasteThreshold = compactWasteThreshold;\n        }\n\n        private Dex mergeDexes() throws IOException {\n            mergeStringIds();\n            mergeTypeIds();\n            mergeTypeLists();\n            mergeProtoIds();\n            mergeFieldIds();\n            mergeMethodIds();\n            mergeAnnotations();\n            unionAnnotationSetsAndDirectories();\n            mergeClassDefs();\n\n            // write the header\n            contentsOut.header.off = 0;\n            contentsOut.header.size = 1;\n            contentsOut.fileSize = dexOut.getLength();\n            contentsOut.computeSizesFromOffsets();\n            contentsOut.writeHeader(headerOut);\n            contentsOut.writeMap(mapListOut);\n\n            // generate and write the hashes\n            dexOut.writeHashes();\n\n            return dexOut;\n        }\n\n        public Dex transform() throws IOException {\n            if (dexes.length == 1) {\n                return dexes[0];\n            } else if (dexes.length == 0) {\n                return null;\n            }\n            Dex result = mergeDexes();\n            return result;\n        }\n\n    public void setClassList(List<String> classList) {\n        this.classDefList = classList;\n    }\n\n    /**\n         * Reads an IDs section of two dex files and writes an IDs section of a\n         * merged dex file. Populates maps from old to new indices in the process.\n         */\n        abstract class IdMerger<T extends Comparable<T>> {\n            private final Dex.Section out;\n\n            protected IdMerger(Dex.Section out) {\n                this.out = out;\n            }\n\n            /**\n             * Merges already-sorted sections, reading one value from each dex into memory\n             * at a time.\n             */\n            public final void mergeSorted() {\n                TableOfContents.Section[] sections = new TableOfContents.Section[dexes.length];\n                Dex.Section[] dexSections = new Dex.Section[dexes.length];\n                int[] offsets = new int[dexes.length];\n                int[] indexes = new int[dexes.length];\n\n                // values contains one value from each dex, sorted for fast retrieval of\n                // the smallest value. The list associated with a value has the indexes\n                // of the dexes that had that value.\n                TreeMap<T, List<Integer>> values = new TreeMap<T, List<Integer>>();\n\n                for (int i = 0; i < dexes.length; i++) {\n                    sections[i] = getSection(dexes[i].getTableOfContents());\n                    dexSections[i] = sections[i].exists() ? dexes[i].open(sections[i].off) : null;\n                    // Fill in values with the first value of each dex.\n                    offsets[i] = readIntoMap(\n                            dexSections[i], sections[i], indexMaps[i], indexes[i], values, i);\n                }\n                getSection(contentsOut).off = out.getPosition();\n\n                int outCount = 0;\n                while (!values.isEmpty()) {\n                    Map.Entry<T, List<Integer>> first = values.pollFirstEntry();\n                    for (Integer dex : first.getValue()) {\n                        updateIndex(offsets[dex], indexMaps[dex], indexes[dex]++, outCount);\n                        // Fetch the next value of the dexes we just polled out\n                        offsets[dex] = readIntoMap(dexSections[dex], sections[dex],\n                                indexMaps[dex], indexes[dex], values, dex);\n                    }\n                    write(first.getKey());\n                    outCount++;\n                }\n\n                getSection(contentsOut).size = outCount;\n            }\n\n            private int readIntoMap(Dex.Section in, TableOfContents.Section section, IndexMap indexMap,\n                                    int index, TreeMap<T, List<Integer>> values, int dex) {\n                int offset = in != null ? in.getPosition() : -1;\n                if (index < section.size) {\n                    T v = read(in, indexMap, index);\n                    List<Integer> l = values.get(v);\n                    if (l == null) {\n                        l = new ArrayList<Integer>();\n                        values.put(v, l);\n                    }\n                    l.add(new Integer(dex));\n                }\n                return offset;\n            }\n\n            /**\n             * Merges unsorted sections by reading them completely into memory and\n             * sorting in memory.\n             */\n            public final void mergeUnsorted() {\n                getSection(contentsOut).off = out.getPosition();\n\n                List<IdMerger.UnsortedValue> all = new ArrayList<IdMerger.UnsortedValue>();\n                for (int i = 0; i < dexes.length; i++) {\n                    all.addAll(readUnsortedValues(dexes[i], indexMaps[i]));\n                }\n                Collections.sort(all);\n\n                int outCount = 0;\n                for (int i = 0; i < all.size(); ) {\n                    IdMerger.UnsortedValue e1 = all.get(i++);\n                    updateIndex(e1.offset, e1.indexMap, e1.index, outCount - 1);\n\n                    while (i < all.size() && e1.compareTo(all.get(i)) == 0) {\n                        IdMerger.UnsortedValue e2 = all.get(i++);\n                        updateIndex(e2.offset, e2.indexMap, e2.index, outCount - 1);\n                    }\n\n                    write((T) e1.value);\n                    outCount++;\n                }\n\n                getSection(contentsOut).size = outCount;\n            }\n\n            private List<IdMerger.UnsortedValue> readUnsortedValues(Dex source, IndexMap indexMap) {\n                TableOfContents.Section section = getSection(source.getTableOfContents());\n                if (!section.exists()) {\n                    return Collections.emptyList();\n                }\n\n                List<IdMerger.UnsortedValue> result = new ArrayList<IdMerger.UnsortedValue>();\n                Dex.Section in = source.open(section.off);\n                for (int i = 0; i < section.size; i++) {\n                    int offset = in.getPosition();\n                    T value = read(in, indexMap, 0);\n                    result.add(new IdMerger.UnsortedValue(source, indexMap, value, i, offset));\n                }\n                return result;\n            }\n\n            abstract TableOfContents.Section getSection(TableOfContents tableOfContents);\n            abstract T read(Dex.Section in, IndexMap indexMap, int index);\n            abstract void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex);\n            abstract void write(T value);\n\n            class UnsortedValue implements Comparable<IdMerger.UnsortedValue> {\n                final Dex source;\n                final IndexMap indexMap;\n                final T value;\n                final int index;\n                final int offset;\n\n                UnsortedValue(Dex source, IndexMap indexMap, T value, int index, int offset) {\n                    this.source = source;\n                    this.indexMap = indexMap;\n                    this.value = value;\n                    this.index = index;\n                    this.offset = offset;\n                }\n\n                public int compareTo(IdMerger.UnsortedValue unsortedValue) {\n                    return value.compareTo((T) unsortedValue.value);\n                }\n            }\n        }\n\n\n        private void mergeStringIds() {\n            new IdMerger<String>(idsDefsOut) {\n                @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                    return tableOfContents.stringIds;\n                }\n\n                @Override String read(Dex.Section in, IndexMap indexMap, int index) {\n                    return in.readString();\n                }\n\n                @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                    indexMap.stringIds[oldIndex] = newIndex;\n                }\n\n                @Override void write(String value) {\n                    contentsOut.stringDatas.size++;\n                    idsDefsOut.writeInt(stringDataOut.getPosition());\n                    stringDataOut.writeStringData(value);\n                }\n            }.mergeSorted();\n        }\n\n        private void mergeTypeIds() {\n            new IdMerger<Integer>(idsDefsOut) {\n                @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                    return tableOfContents.typeIds;\n                }\n\n                @Override Integer read(Dex.Section in, IndexMap indexMap, int index) {\n                    int stringIndex = in.readInt();\n                    return indexMap.adjustString(stringIndex);\n                }\n\n                @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                    if (newIndex < 0 || newIndex > 0xffff) {\n                        throw new DexIndexOverflowException(\"type ID not in [0, 0xffff]: \" + newIndex);\n                    }\n                    indexMap.typeIds[oldIndex] = (short) newIndex;\n                }\n\n                @Override void write(Integer value) {\n                    idsDefsOut.writeInt(value);\n                }\n            }.mergeSorted();\n        }\n\n        private void mergeTypeLists() {\n            new IdMerger<TypeList>(typeListOut) {\n                @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                    return tableOfContents.typeLists;\n                }\n\n                @Override TypeList read(Dex.Section in, IndexMap indexMap, int index) {\n                    return indexMap.adjustTypeList(in.readTypeList());\n                }\n\n                @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                    indexMap.putTypeListOffset(offset, typeListOut.getPosition());\n                }\n\n                @Override void write(TypeList value) {\n                    typeListOut.writeTypeList(value);\n                }\n            }.mergeUnsorted();\n        }\n\n        private void mergeProtoIds() {\n            new IdMerger<ProtoId>(idsDefsOut) {\n                @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                    return tableOfContents.protoIds;\n                }\n\n                @Override ProtoId read(Dex.Section in, IndexMap indexMap, int index) {\n                    return indexMap.adjust(in.readProtoId());\n                }\n\n                @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                    if (newIndex < 0 || newIndex > 0xffff) {\n                        throw new DexIndexOverflowException(\"proto ID not in [0, 0xffff]: \" + newIndex);\n                    }\n                    indexMap.protoIds[oldIndex] = (short) newIndex;\n                }\n\n                @Override void write(ProtoId value) {\n                    value.writeTo(idsDefsOut);\n                }\n            }.mergeSorted();\n        }\n\n        private void mergeFieldIds() {\n            new IdMerger<FieldId>(idsDefsOut) {\n                @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                    return tableOfContents.fieldIds;\n                }\n\n                @Override FieldId read(Dex.Section in, IndexMap indexMap, int index) {\n                    return indexMap.adjust(in.readFieldId());\n                }\n\n                @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                    if (newIndex < 0 || newIndex > 0xffff) {\n                        throw new DexIndexOverflowException(\"field ID not in [0, 0xffff]: \" + newIndex);\n                    }\n                    indexMap.fieldIds[oldIndex] = (short) newIndex;\n                }\n\n                @Override void write(FieldId value) {\n                    value.writeTo(idsDefsOut);\n                }\n            }.mergeSorted();\n        }\n\n        private void mergeMethodIds() {\n            new IdMerger<MethodId>(idsDefsOut) {\n                @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                    return tableOfContents.methodIds;\n                }\n\n                @Override MethodId read(Dex.Section in, IndexMap indexMap, int index) {\n                    return indexMap.adjust(in.readMethodId());\n                }\n\n                @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                    if (newIndex < 0 || newIndex > 0xffff) {\n                        throw new DexIndexOverflowException(\n                                \"method ID not in [0, 0xffff]: \" + newIndex);\n                    }\n                    indexMap.methodIds[oldIndex] = (short) newIndex;\n                }\n\n                @Override void write(MethodId methodId) {\n                    methodId.writeTo(idsDefsOut);\n                }\n            }.mergeSorted();\n        }\n\n        private void mergeAnnotations() {\n            new IdMerger<Annotation>(annotationOut) {\n                @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                    return tableOfContents.annotations;\n                }\n\n                @Override Annotation read(Dex.Section in, IndexMap indexMap, int index) {\n                    return indexMap.adjust(in.readAnnotation());\n                }\n\n                @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                    indexMap.putAnnotationOffset(offset, annotationOut.getPosition());\n                }\n\n                @Override void write(Annotation value) {\n                    value.writeTo(annotationOut);\n                }\n            }.mergeUnsorted();\n        }\n\n        private void mergeClassDefs() {\n            SortableType[] types = getSortedTypes();\n            contentsOut.classDefs.off = idsDefsOut.getPosition();\n            contentsOut.classDefs.size = types.length;\n\n            for (SortableType type : types) {\n                Dex in = type.getDex();\n                transformClassDef(in, type.getClassDef(), type.getIndexMap());\n            }\n        }\n\n        /**\n         * Returns the union of classes from both files, sorted in order such that\n         * a class is always preceded by its supertype and implemented interfaces.\n         */\n        private SortableType[] getSortedTypes() {\n            // size is pessimistic; doesn't include arrays\n            SortableType[] sortableTypes = new SortableType[contentsOut.typeIds.size];\n            for (int i = 0; i < dexes.length; i++) {\n                    readDexSortableTypes(sortableTypes,dexes[i],indexMaps[i]);\n\n            }\n\n        /*\n         * Populate the depths of each sortable type. This makes D iterations\n         * through all N types, where 'D' is the depth of the deepest type. For\n         * example, the deepest class in libcore is Xalan's KeyIterator, which\n         * is 11 types deep.\n         */\n            while (true) {\n                boolean allDone = true;\n                for (SortableType sortableType : sortableTypes) {\n                    if (sortableType != null && !sortableType.isDepthAssigned()) {\n                        allDone &= sortableType.tryAssignDepth(sortableTypes);\n                    }\n                }\n                if (allDone) {\n                    break;\n                }\n            }\n\n            Arrays.sort(sortableTypes, new Comparator<SortableType>() {\n\n                @Override\n                public int compare(SortableType o1, SortableType o2) {\n                    if (o1 == o2) {\n                        return 0;\n                    }\n                    if (o2 == null) {\n                        return -1;\n                    }\n                    if (o1 == null) {\n                        return 1;\n                    }\n                    if (classDefList.contains(o1.getDex().typeNames().get(o1.getTypeIndex()))&& classDefList.contains(o1.getDex().typeNames().get(o2.getTypeIndex()))) {\n                        return classDefList.indexOf(o1.getDex().typeNames().get(o1.getTypeIndex())) - classDefList.indexOf(o1.getDex().typeNames().get(o2.getTypeIndex()));\n\n                    } else if (classDefList.contains(o1.getDex().typeNames().get(o1.getTypeIndex())) && !classDefList.contains(o1.getDex().typeNames().get(o2.getTypeIndex()))) {\n                        return -1;\n                    } else if (!classDefList.contains(o1.getDex().typeNames().get(o1.getTypeIndex())) && classDefList.contains(o1.getDex().typeNames().get(o2.getTypeIndex()))) {\n                        return 1;\n                    } else return o1.getTypeIndex()-(o2.getTypeIndex());\n                }\n            });\n            int firstNull = Arrays.asList(sortableTypes).indexOf(null);\n            return Arrays.copyOfRange(sortableTypes, 0, firstNull);\n        }\n\n    private void readDexSortableTypes(SortableType[] sortableTypes, Dex dex, IndexMap indexMap) {\n//        int i = 0;\n        for (ClassDef classDef : dex.classDefs()) {\n            SortableType sortableType = indexMap.adjust(\n                    new SortableType(dex, indexMap, classDef));\n            int t = sortableType.getTypeIndex();\n            if (sortableTypes[t] == null) {\n                sortableTypes[t] = sortableType;\n            } else if (collisionPolicy != CollisionPolicy.KEEP_FIRST) {\n                throw new DexException(\"Multiple dex files define \"\n                        + dex.typeNames().get(classDef.getTypeIndex()));\n            }\n        }\n        }\n\n    /**\n         * Reads just enough data on each class so that we can sort it and then find\n         * it later.\n         */\n        private void readSortableTypes(SortableType[] sortableTypes, Dex buffer,\n                                       IndexMap indexMap) {\n\n            for (ClassDef classDef : buffer.classDefs()) {\n                SortableType sortableType = indexMap.adjust(\n                        new SortableType(buffer, indexMap, classDef));\n                int t = sortableType.getTypeIndex();\n                if (sortableTypes[t] == null) {\n                    sortableTypes[t] = sortableType;\n                } else if (collisionPolicy != CollisionPolicy.KEEP_FIRST) {\n                    throw new DexException(\"Multiple dex files define \"\n                            + buffer.typeNames().get(classDef.getTypeIndex()));\n                }\n            }\n        }\n\n        /**\n         * Copy annotation sets from each input to the output.\n         *\n         * TODO: this may write multiple copies of the same annotation set.\n         * We should shrink the output by merging rather than unioning\n         */\n        private void unionAnnotationSetsAndDirectories() {\n            for (int i = 0; i < dexes.length; i++) {\n                transformAnnotationSets(dexes[i], indexMaps[i]);\n            }\n            for (int i = 0; i < dexes.length; i++) {\n                transformAnnotationSetRefLists(dexes[i], indexMaps[i]);\n            }\n            for (int i = 0; i < dexes.length; i++) {\n                transformAnnotationDirectories(dexes[i], indexMaps[i]);\n            }\n            for (int i = 0; i < dexes.length; i++) {\n                transformStaticValues(dexes[i], indexMaps[i]);\n            }\n        }\n\n        private void transformAnnotationSets(Dex in, IndexMap indexMap) {\n            TableOfContents.Section section = in.getTableOfContents().annotationSets;\n            if (section.exists()) {\n                Dex.Section setIn = in.open(section.off);\n                for (int i = 0; i < section.size; i++) {\n                    transformAnnotationSet(indexMap, setIn);\n                }\n            }\n        }\n\n        private void transformAnnotationSetRefLists(Dex in, IndexMap indexMap) {\n            TableOfContents.Section section = in.getTableOfContents().annotationSetRefLists;\n            if (section.exists()) {\n                Dex.Section setIn = in.open(section.off);\n                for (int i = 0; i < section.size; i++) {\n                    transformAnnotationSetRefList(indexMap, setIn);\n                }\n            }\n        }\n\n        private void transformAnnotationDirectories(Dex in, IndexMap indexMap) {\n            TableOfContents.Section section = in.getTableOfContents().annotationsDirectories;\n            if (section.exists()) {\n                Dex.Section directoryIn = in.open(section.off);\n                for (int i = 0; i < section.size; i++) {\n                    transformAnnotationDirectory(directoryIn, indexMap);\n                }\n            }\n        }\n\n        private void transformStaticValues(Dex in, IndexMap indexMap) {\n            TableOfContents.Section section = in.getTableOfContents().encodedArrays;\n            if (section.exists()) {\n                Dex.Section staticValuesIn = in.open(section.off);\n                for (int i = 0; i < section.size; i++) {\n                    transformStaticValues(staticValuesIn, indexMap);\n                }\n            }\n        }\n\n        /**\n         * Reads a class_def_item beginning at {@code in} and writes the index and\n         * data.\n         */\n        private void transformClassDef(Dex in, ClassDef classDef, IndexMap indexMap) {\n            idsDefsOut.assertFourByteAligned();\n            idsDefsOut.writeInt(classDef.getTypeIndex());\n            idsDefsOut.writeInt(classDef.getAccessFlags());\n            idsDefsOut.writeInt(classDef.getSupertypeIndex());\n            idsDefsOut.writeInt(classDef.getInterfacesOffset());\n\n            int sourceFileIndex = indexMap.adjustString(classDef.getSourceFileIndex());\n            idsDefsOut.writeInt(sourceFileIndex);\n\n            int annotationsOff = classDef.getAnnotationsOffset();\n            idsDefsOut.writeInt(indexMap.adjustAnnotationDirectory(annotationsOff));\n\n            int classDataOff = classDef.getClassDataOffset();\n            if (classDataOff == 0) {\n                idsDefsOut.writeInt(0);\n            } else {\n                idsDefsOut.writeInt(classDataOut.getPosition());\n                ClassData classData = in.readClassData(classDef);\n                transformClassData(in, classData, indexMap);\n            }\n\n            int staticValuesOff = classDef.getStaticValuesOffset();\n            idsDefsOut.writeInt(indexMap.adjustStaticValues(staticValuesOff));\n        }\n\n        /**\n         * Transform all annotations on a class.\n         */\n        private void transformAnnotationDirectory(\n                Dex.Section directoryIn, IndexMap indexMap) {\n            contentsOut.annotationsDirectories.size++;\n            annotationsDirectoryOut.assertFourByteAligned();\n            indexMap.putAnnotationDirectoryOffset(\n                    directoryIn.getPosition(), annotationsDirectoryOut.getPosition());\n\n            int classAnnotationsOffset = indexMap.adjustAnnotationSet(directoryIn.readInt());\n            annotationsDirectoryOut.writeInt(classAnnotationsOffset);\n\n            int fieldsSize = directoryIn.readInt();\n            annotationsDirectoryOut.writeInt(fieldsSize);\n\n            int methodsSize = directoryIn.readInt();\n            annotationsDirectoryOut.writeInt(methodsSize);\n\n            int parameterListSize = directoryIn.readInt();\n            annotationsDirectoryOut.writeInt(parameterListSize);\n\n            for (int i = 0; i < fieldsSize; i++) {\n                // field index\n                annotationsDirectoryOut.writeInt(indexMap.adjustField(directoryIn.readInt()));\n\n                // annotations offset\n                annotationsDirectoryOut.writeInt(indexMap.adjustAnnotationSet(directoryIn.readInt()));\n            }\n\n            for (int i = 0; i < methodsSize; i++) {\n                // method index\n                annotationsDirectoryOut.writeInt(indexMap.adjustMethod(directoryIn.readInt()));\n\n                // annotation set offset\n                annotationsDirectoryOut.writeInt(\n                        indexMap.adjustAnnotationSet(directoryIn.readInt()));\n            }\n\n            for (int i = 0; i < parameterListSize; i++) {\n                // method index\n                annotationsDirectoryOut.writeInt(indexMap.adjustMethod(directoryIn.readInt()));\n\n                // annotations offset\n                annotationsDirectoryOut.writeInt(\n                        indexMap.adjustAnnotationSetRefList(directoryIn.readInt()));\n            }\n        }\n\n        /**\n         * Transform all annotations on a single type, member or parameter.\n         */\n        private void transformAnnotationSet(IndexMap indexMap, Dex.Section setIn) {\n            contentsOut.annotationSets.size++;\n            annotationSetOut.assertFourByteAligned();\n            indexMap.putAnnotationSetOffset(setIn.getPosition(), annotationSetOut.getPosition());\n\n            int size = setIn.readInt();\n            annotationSetOut.writeInt(size);\n\n            for (int j = 0; j < size; j++) {\n                annotationSetOut.writeInt(indexMap.adjustAnnotation(setIn.readInt()));\n            }\n        }\n\n        /**\n         * Transform all annotation set ref lists.\n         */\n        private void transformAnnotationSetRefList(IndexMap indexMap, Dex.Section refListIn) {\n            contentsOut.annotationSetRefLists.size++;\n            annotationSetRefListOut.assertFourByteAligned();\n            indexMap.putAnnotationSetRefListOffset(\n                    refListIn.getPosition(), annotationSetRefListOut.getPosition());\n\n            int parameterCount = refListIn.readInt();\n            annotationSetRefListOut.writeInt(parameterCount);\n            for (int p = 0; p < parameterCount; p++) {\n                annotationSetRefListOut.writeInt(indexMap.adjustAnnotationSet(refListIn.readInt()));\n            }\n        }\n\n        private void transformClassData(Dex in, ClassData classData, IndexMap indexMap) {\n            contentsOut.classDatas.size++;\n\n            ClassData.Field[] staticFields = classData.getStaticFields();\n            ClassData.Field[] instanceFields = classData.getInstanceFields();\n            ClassData.Method[] directMethods = classData.getDirectMethods();\n            ClassData.Method[] virtualMethods = classData.getVirtualMethods();\n\n            classDataOut.writeUleb128(staticFields.length);\n            classDataOut.writeUleb128(instanceFields.length);\n            classDataOut.writeUleb128(directMethods.length);\n            classDataOut.writeUleb128(virtualMethods.length);\n\n            transformFields(indexMap, staticFields);\n            transformFields(indexMap, instanceFields);\n            transformMethods(in, indexMap, directMethods);\n            transformMethods(in, indexMap, virtualMethods);\n        }\n\n        private void transformFields(IndexMap indexMap, ClassData.Field[] fields) {\n            int lastOutFieldIndex = 0;\n            for (ClassData.Field field : fields) {\n                int outFieldIndex = indexMap.adjustField(field.getFieldIndex());\n                classDataOut.writeUleb128(outFieldIndex - lastOutFieldIndex);\n                lastOutFieldIndex = outFieldIndex;\n                classDataOut.writeUleb128(field.getAccessFlags());\n            }\n        }\n\n        private void transformMethods(Dex in, IndexMap indexMap, ClassData.Method[] methods) {\n            int lastOutMethodIndex = 0;\n            for (ClassData.Method method : methods) {\n                int outMethodIndex = indexMap.adjustMethod(method.getMethodIndex());\n                classDataOut.writeUleb128(outMethodIndex - lastOutMethodIndex);\n                lastOutMethodIndex = outMethodIndex;\n\n                classDataOut.writeUleb128(method.getAccessFlags());\n\n                if (method.getCodeOffset() == 0) {\n                    classDataOut.writeUleb128(0);\n                } else {\n                    codeOut.alignToFourBytesWithZeroFill();\n                    classDataOut.writeUleb128(codeOut.getPosition());\n                    transformCode(in, in.readCode(method), indexMap);\n                }\n            }\n        }\n\n        private void transformCode(Dex in, Code code, IndexMap indexMap) {\n            contentsOut.codes.size++;\n            codeOut.assertFourByteAligned();\n\n            codeOut.writeUnsignedShort(code.getRegistersSize());\n            codeOut.writeUnsignedShort(code.getInsSize());\n            codeOut.writeUnsignedShort(code.getOutsSize());\n\n            Code.Try[] tries = code.getTries();\n            Code.CatchHandler[] catchHandlers = code.getCatchHandlers();\n            codeOut.writeUnsignedShort(tries.length);\n\n            int debugInfoOffset = code.getDebugInfoOffset();\n            if (debugInfoOffset != 0) {\n                codeOut.writeInt(debugInfoOut.getPosition());\n                transformDebugInfoItem(in.open(debugInfoOffset), indexMap);\n            } else {\n                codeOut.writeInt(0);\n            }\n\n            short[] instructions = code.getInstructions();\n            short[] newInstructions = instructionTransformer.transform(indexMap, instructions);\n            codeOut.writeInt(newInstructions.length);\n            codeOut.write(newInstructions);\n\n            if (tries.length > 0) {\n                if (newInstructions.length % 2 == 1) {\n                    codeOut.writeShort((short) 0); // padding\n                }\n\n            /*\n             * We can't write the tries until we've written the catch handlers.\n             * Unfortunately they're in the opposite order in the dex file so we\n             * need to transform them out-of-order.\n             */\n                Dex.Section triesSection = dexOut.open(codeOut.getPosition());\n                codeOut.skip(tries.length * SizeOf.TRY_ITEM);\n                int[] offsets = transformCatchHandlers(indexMap, catchHandlers);\n                transformTries(triesSection, tries, offsets);\n            }\n        }\n\n        /**\n         * Writes the catch handlers to {@code codeOut} and returns their indices.\n         */\n        private int[] transformCatchHandlers(IndexMap indexMap, Code.CatchHandler[] catchHandlers) {\n            int baseOffset = codeOut.getPosition();\n            codeOut.writeUleb128(catchHandlers.length);\n            int[] offsets = new int[catchHandlers.length];\n            for (int i = 0; i < catchHandlers.length; i++) {\n                offsets[i] = codeOut.getPosition() - baseOffset;\n                transformEncodedCatchHandler(catchHandlers[i], indexMap);\n            }\n            return offsets;\n        }\n\n        private void transformTries(Dex.Section out, Code.Try[] tries,\n                                    int[] catchHandlerOffsets) {\n            for (Code.Try tryItem : tries) {\n                out.writeInt(tryItem.getStartAddress());\n                out.writeUnsignedShort(tryItem.getInstructionCount());\n                out.writeUnsignedShort(catchHandlerOffsets[tryItem.getCatchHandlerIndex()]);\n            }\n        }\n\n        private static final byte DBG_END_SEQUENCE = 0x00;\n        private static final byte DBG_ADVANCE_PC = 0x01;\n        private static final byte DBG_ADVANCE_LINE = 0x02;\n        private static final byte DBG_START_LOCAL = 0x03;\n        private static final byte DBG_START_LOCAL_EXTENDED = 0x04;\n        private static final byte DBG_END_LOCAL = 0x05;\n        private static final byte DBG_RESTART_LOCAL = 0x06;\n        private static final byte DBG_SET_PROLOGUE_END = 0x07;\n        private static final byte DBG_SET_EPILOGUE_BEGIN = 0x08;\n        private static final byte DBG_SET_FILE = 0x09;\n\n        private void transformDebugInfoItem(Dex.Section in, IndexMap indexMap) {\n            contentsOut.debugInfos.size++;\n            int lineStart = in.readUleb128();\n            debugInfoOut.writeUleb128(lineStart);\n\n            int parametersSize = in.readUleb128();\n            debugInfoOut.writeUleb128(parametersSize);\n\n            for (int p = 0; p < parametersSize; p++) {\n                int parameterName = in.readUleb128p1();\n                debugInfoOut.writeUleb128p1(indexMap.adjustString(parameterName));\n            }\n\n            int addrDiff;    // uleb128   address delta.\n            int lineDiff;    // sleb128   line delta.\n            int registerNum; // uleb128   register number.\n            int nameIndex;   // uleb128p1 string index.    Needs indexMap adjustment.\n            int typeIndex;   // uleb128p1 type index.      Needs indexMap adjustment.\n            int sigIndex;    // uleb128p1 string index.    Needs indexMap adjustment.\n\n            while (true) {\n                int opcode = in.readByte();\n                debugInfoOut.writeByte(opcode);\n\n                switch (opcode) {\n                    case DBG_END_SEQUENCE:\n                        return;\n\n                    case DBG_ADVANCE_PC:\n                        addrDiff = in.readUleb128();\n                        debugInfoOut.writeUleb128(addrDiff);\n                        break;\n\n                    case DBG_ADVANCE_LINE:\n                        lineDiff = in.readSleb128();\n                        debugInfoOut.writeSleb128(lineDiff);\n                        break;\n\n                    case DBG_START_LOCAL:\n                    case DBG_START_LOCAL_EXTENDED:\n                        registerNum = in.readUleb128();\n                        debugInfoOut.writeUleb128(registerNum);\n                        nameIndex = in.readUleb128p1();\n                        debugInfoOut.writeUleb128p1(indexMap.adjustString(nameIndex));\n                        typeIndex = in.readUleb128p1();\n                        debugInfoOut.writeUleb128p1(indexMap.adjustType(typeIndex));\n                        if (opcode == DBG_START_LOCAL_EXTENDED) {\n                            sigIndex = in.readUleb128p1();\n                            debugInfoOut.writeUleb128p1(indexMap.adjustString(sigIndex));\n                        }\n                        break;\n\n                    case DBG_END_LOCAL:\n                    case DBG_RESTART_LOCAL:\n                        registerNum = in.readUleb128();\n                        debugInfoOut.writeUleb128(registerNum);\n                        break;\n\n                    case DBG_SET_FILE:\n                        nameIndex = in.readUleb128p1();\n                        debugInfoOut.writeUleb128p1(indexMap.adjustString(nameIndex));\n                        break;\n\n                    case DBG_SET_PROLOGUE_END:\n                    case DBG_SET_EPILOGUE_BEGIN:\n                    default:\n                        break;\n                }\n            }\n        }\n\n        private void transformEncodedCatchHandler(Code.CatchHandler catchHandler, IndexMap indexMap) {\n            int catchAllAddress = catchHandler.getCatchAllAddress();\n            int[] typeIndexes = catchHandler.getTypeIndexes();\n            int[] addresses = catchHandler.getAddresses();\n\n            if (catchAllAddress != -1) {\n                codeOut.writeSleb128(-typeIndexes.length);\n            } else {\n                codeOut.writeSleb128(typeIndexes.length);\n            }\n\n            for (int i = 0; i < typeIndexes.length; i++) {\n                codeOut.writeUleb128(indexMap.adjustType(typeIndexes[i]));\n                codeOut.writeUleb128(addresses[i]);\n            }\n\n            if (catchAllAddress != -1) {\n                codeOut.writeUleb128(catchAllAddress);\n            }\n        }\n\n        private void transformStaticValues(Dex.Section in, IndexMap indexMap) {\n            contentsOut.encodedArrays.size++;\n            indexMap.putStaticValuesOffset(in.getPosition(), encodedArrayOut.getPosition());\n            indexMap.adjustEncodedArray(in.readEncodedArray()).writeTo(encodedArrayOut);\n        }\n\n        /**\n         * Byte counts for the sections written when creating a dex. Target sizes\n         * are defined in one of two ways:\n         * <ul>\n         * <li>By pessimistically guessing how large the union of dex files will be.\n         *     We're pessimistic because we can't predict the amount of duplication\n         *     between dex files, nor can we predict the length of ULEB-encoded\n         *     offsets or indices.\n         * <li>By exactly measuring an existing dex.\n         * </ul>\n         */\n        private static class WriterSizes {\n            private int header = SizeOf.HEADER_ITEM;\n            private int idsDefs;\n            private int mapList;\n            private int typeList;\n            private int classData;\n            private int code;\n            private int stringData;\n            private int debugInfo;\n            private int encodedArray;\n            private int annotationsDirectory;\n            private int annotationsSet;\n            private int annotationsSetRefList;\n            private int annotation;\n\n            /**\n             * Compute sizes for merging several dexes.\n             */\n            public WriterSizes(Dex[] dexes) {\n                for (int i = 0; i < dexes.length; i++) {\n                    plus(dexes[i].getTableOfContents(), false);\n                }\n                fourByteAlign();\n            }\n\n            public WriterSizes(DexTransform dexMerger) {\n                header = dexMerger.headerOut.used();\n                idsDefs = dexMerger.idsDefsOut.used();\n                mapList = dexMerger.mapListOut.used();\n                typeList = dexMerger.typeListOut.used();\n                classData = dexMerger.classDataOut.used();\n                code = dexMerger.codeOut.used();\n                stringData = dexMerger.stringDataOut.used();\n                debugInfo = dexMerger.debugInfoOut.used();\n                encodedArray = dexMerger.encodedArrayOut.used();\n                annotationsDirectory = dexMerger.annotationsDirectoryOut.used();\n                annotationsSet = dexMerger.annotationSetOut.used();\n                annotationsSetRefList = dexMerger.annotationSetRefListOut.used();\n                annotation = dexMerger.annotationOut.used();\n                fourByteAlign();\n            }\n\n            private void plus(TableOfContents contents, boolean exact) {\n                idsDefs += contents.stringIds.size * SizeOf.STRING_ID_ITEM\n                        + contents.typeIds.size * SizeOf.TYPE_ID_ITEM\n                        + contents.protoIds.size * SizeOf.PROTO_ID_ITEM\n                        + contents.fieldIds.size * SizeOf.MEMBER_ID_ITEM\n                        + contents.methodIds.size * SizeOf.MEMBER_ID_ITEM\n                        + contents.classDefs.size * SizeOf.CLASS_DEF_ITEM;\n                mapList = SizeOf.UINT + (contents.sections.length * SizeOf.MAP_ITEM);\n                typeList += fourByteAlign(contents.typeLists.byteCount); // We count each dex's\n                // typelists section as realigned on 4 bytes, because each typelist of each dex's\n                // typelists section is aligned on 4 bytes. If we didn't, there is a case where each\n                // size of both dex's typelists section is a multiple of 2 but not a multiple of 4,\n                // and the sum of both sizes is a multiple of 4 but would not be sufficient to write\n                // each typelist aligned on 4 bytes.\n                stringData += contents.stringDatas.byteCount;\n                annotationsDirectory += contents.annotationsDirectories.byteCount;\n                annotationsSet += contents.annotationSets.byteCount;\n                annotationsSetRefList += contents.annotationSetRefLists.byteCount;\n\n                if (exact) {\n                    code += contents.codes.byteCount;\n                    classData += contents.classDatas.byteCount;\n                    encodedArray += contents.encodedArrays.byteCount;\n                    annotation += contents.annotations.byteCount;\n                    debugInfo += contents.debugInfos.byteCount;\n                } else {\n                    // at most 1/4 of the bytes in a code section are uleb/sleb\n                    code += (int) Math.ceil(contents.codes.byteCount * 1.25);\n                    // at most 2/3 of the bytes in a class data section are uleb/sleb that may change\n                    // (assuming the worst case that section contains only methods and no fields)\n                    classData += (int) Math.ceil(contents.classDatas.byteCount * 1.67);\n                    // all of the bytes in an encoding arrays section may be uleb/sleb\n                    encodedArray += contents.encodedArrays.byteCount * 2;\n                    // all of the bytes in an annotations section may be uleb/sleb\n                    annotation += (int) Math.ceil(contents.annotations.byteCount * 2);\n                    // all of the bytes in a debug info section may be uleb/sleb\n                    debugInfo += contents.debugInfos.byteCount * 2;\n                }\n            }\n\n            private void fourByteAlign() {\n                header = fourByteAlign(header);\n                idsDefs = fourByteAlign(idsDefs);\n                mapList = fourByteAlign(mapList);\n                typeList = fourByteAlign(typeList);\n                classData = fourByteAlign(classData);\n                code = fourByteAlign(code);\n                stringData = fourByteAlign(stringData);\n                debugInfo = fourByteAlign(debugInfo);\n                encodedArray = fourByteAlign(encodedArray);\n                annotationsDirectory = fourByteAlign(annotationsDirectory);\n                annotationsSet = fourByteAlign(annotationsSet);\n                annotationsSetRefList = fourByteAlign(annotationsSetRefList);\n                annotation = fourByteAlign(annotation);\n            }\n\n            private static int fourByteAlign(int position) {\n                return (position + 3) & ~3;\n            }\n\n            public int size() {\n                return header + idsDefs + mapList + typeList + classData + code + stringData + debugInfo\n                        + encodedArray + annotationsDirectory + annotationsSet + annotationsSetRefList\n                        + annotation;\n            }\n        }\n\n        public static void main(String[] args) throws IOException {\n            if (args.length < 2) {\n                printUsage();\n                return;\n            }\n\n            Dex[] dexes = new Dex[args.length - 1];\n            for (int i = 1; i < args.length; i++) {\n                dexes[i - 1] = new Dex(new File(args[i]));\n            }\n            Dex merged = new com.taobao.android.dx.merge.DexMerger(dexes, CollisionPolicy.KEEP_FIRST).merge();\n            merged.writeTo(new File(args[0]));\n        }\n\n        private static void printUsage() {\n            System.out.println(\"Usage: DexMerger <out.dex> <a.dex> <b.dex> ...\");\n            System.out.println();\n            System.out.println(\n                    \"If a class is defined in several dex, the class found in the first dex will be used.\");\n        }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/utils/CommandUtils.java",
    "content": "package com.taobao.android.utils;\n\nimport org.slf4j.LoggerFactory;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.InputStreamReader;\nimport java.util.logging.Logger;\n\n/**\n * @author lilong\n * @create 2017-05-12 下午2:16\n */\n\npublic class CommandUtils {\n\n    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(CommandUtils.class);\n\n    public static void exec(File workingDir,String command) {\n\n        logger.info(\"start excute commond:\"+command);\n\n        String[]commands = command.split(\" \");\n        try {\n            ProcessBuilder processBuilder = new ProcessBuilder(commands);\n            processBuilder.directory(workingDir);\n            Process process = processBuilder.start();\n            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));\n            String line = null;\n            while ((line = bufferedReader.readLine())!= null){\n                System.out.println(line);\n            }\n            process.waitFor();\n            process.destroy();\n        } catch (Throwable e) {\n            if (commands[0].equals(\"zip\")){\n                try {\n                    ZipUtils.addFileAndDirectoryToZip(new File(commands[2]),workingDir);\n                } catch (Exception e1) {\n                    e1.printStackTrace();\n                }\n\n            }else if (commands[0].equals(\"unzip\")){\n                ZipUtils.unzip(new File(commands[1]),commands[3]);\n            }\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/utils/DexCompareUtils.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.utils;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.jf.dexlib2.dexbacked.DexBackedMethodImplementation;\nimport org.jf.dexlib2.dexbacked.DexBackedTryBlock;\nimport org.jf.dexlib2.iface.instruction.Instruction;\n\nimport java.util.List;\n\n/**\n * Created by shenghua.nish on 2016-03-15 下午11:17.\n */\npublic class DexCompareUtils {\n\n    /**\n     * 判断2个方法的实现是否equal\n     *\n     * @param baseMethod\n     * @param newMethod\n     * @return\n     */\n    public static boolean compareMethod(DexBackedMethodImplementation baseMethod, DexBackedMethodImplementation newMethod) {\n        String baseMethodStr = SmaliCodeUtils.methodImplementionToCode(baseMethod, false);\n        String newMethodStr = SmaliCodeUtils.methodImplementionToCode(newMethod, false);\n        if (StringUtils.equals(baseMethodStr, newMethodStr)) {\n            return true;\n        } else {\n            return false;\n        }\n//        if (null != baseMethod && null != newMethod) {\n//            List< Instruction> a = Lists.newArrayList();\n//            List<Instruction> b = Lists.newArrayList();\n//            for(Instruction instruction:baseMethod.getInstructions()){\n//                a.add(instruction);\n//            }\n//            for(Instruction instruction:newMethod.getInstructions()){\n//                b.add(instruction);\n//            }\n//\n//            return baseMethod.getRegisterCount() == newMethod.getRegisterCount()\n//                    && equalTryBlocks(baseMethod.getTryBlocks(), newMethod.getTryBlocks()) && equalsInstruction(a,b);\n//        } else if (null == baseMethod && null == newMethod) {\n//            return true;\n//        } else {\n//            return false;\n//        }\n\n    }\n\n    /**\n     * 比较method重的tryBlock块\n     *\n     * @param a\n     * @param b\n     * @return\n     */\n    private static boolean equalTryBlocks(List<? extends DexBackedTryBlock> a, List<? extends DexBackedTryBlock> b) {\n        if (a.size() != b.size()) {\n            return false;\n        }\n        DexBackedTryBlock at, bt;\n        for (int i = 0; i < a.size(); i++) {\n            at = a.get(i);\n            bt = b.get(i);\n            if (!at.equals(bt)) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * 比较method重的tryBlock块\n     *\n     * @param a\n     * @param b\n     * @return\n     */\n    private static boolean equalsInstruction(List<Instruction> a, List<Instruction> b) {\n        if (a.size() != b.size()) {\n            return false;\n        }\n        Instruction at, bt;\n        for (int i = 0; i < a.size(); i++) {\n            at = a.get(i);\n            bt = b.get(i);\n            if (!at.getOpcode().equals(bt.getOpcode()) || !(at.getCodeUnits() == bt.getCodeUnits())) {\n                return false;\n            }\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/utils/PathMatcher.java",
    "content": "/*\n * Copyright 2014 Alibaba.com All right reserved. This software is the\n * confidential and proprietary information of Alibaba.com (\"Confidential\n * Information\"). You shall not disclose such Confidential Information and shall\n * use it only in accordance with the terms of the license agreement you entered\n * into with Alibaba.com.\n */\n\npackage com.taobao.android.utils;\n\nimport org.apache.commons.lang3.StringUtils;\n\n/**\n * <p>\n * PathMatcher implementation for Ant-style path patterns. Examples are provided below.\n * </p>\n * <p>\n * Part of this mapping code has been kindly borrowed from <a href=\"http://ant.apache.org\">Apache Ant</a>.\n * <p>\n * The mapping matches URLs using the following rules:<br>\n * <ul>\n * <li>? matches one character</li>\n * <li>* matches zero or more characters</li>\n * <li>** matches zero or more 'directories' in a path</li>\n * </ul>\n * <p>\n * Some examples:<br>\n * <ul>\n * <li><code>com/t?st.jsp</code> - matches <code>com/test.jsp</code> but also <code>com/tast.jsp</code> or\n * <code>com/txst.jsp</code></li>\n * <li><code>com/*.jsp</code> - matches all <code>.jsp</code> files in the <code>com</code> directory</li>\n * <li><code>com/&#42;&#42;/test.jsp</code> - matches all <code>test.jsp</code> files underneath the <code>com</code>\n * path</li>\n * <li><code>org/apache/shiro/&#42;&#42;/*.jsp</code> - matches all <code>.jsp</code> files underneath the\n * <code>org/apache/shiro</code> path</li>\n * <li><code>org/&#42;&#42;/servlet/bla.jsp</code> - matches <code>org/apache/shiro/servlet/bla.jsp</code> but also\n * <code>org/apache/shiro/testing/servlet/bla.jsp</code> and <code>org/servlet/bla.jsp</code></li>\n * </ul>\n * <p>\n * <b>N.B.</b>: This class was borrowed (with much appreciation) from the <a\n * href=\"http://www.springframework.org\">Spring Framework</a> with modifications. We didn't want to reinvent the wheel\n * of great work they've done, but also didn't want to force every Shiro user to depend on Spring\n * </p>\n * <p>\n * As per the Apache 2.0 license, the original copyright notice and all author and copyright information have remained\n * in tact.\n * </p>\n *\n * @since 16.07.2003\n */\npublic class PathMatcher {\n    /**\n     * Default path separator: \"/\"\n     */\n    public static final String DEFAULT_PATH_SEPARATOR = \"/\";\n\n    private String pathSeparator = DEFAULT_PATH_SEPARATOR;\n\n    /**\n     * Set the path separator to use for pattern parsing. Default is \"/\", as in\n     * Ant.\n     */\n    public void setPathSeparator(String pathSeparator) {\n        this.pathSeparator = (pathSeparator != null ? pathSeparator : DEFAULT_PATH_SEPARATOR);\n    }\n\n    public boolean isPattern(String str) {\n        return (str.indexOf('*') != -1 || str.indexOf('?') != -1);\n    }\n\n\n    public boolean match(String[] patterns, String str) {\n        if (null == patterns) {\n            return false;\n        }\n        for (String pattern : patterns) {\n            if (match(pattern, str)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public boolean match(String pattern, String str) {\n        if (str == null) {\n            return false;\n        }\n        if (pattern == null) {\n            return false;\n        }\n        if (str.startsWith(this.pathSeparator) != pattern.startsWith(this.pathSeparator)) {\n            return false;\n        }\n\n        String[] patDirs = StringUtils.split(pattern, this.pathSeparator);\n        String[] strDirs = StringUtils.split(str, this.pathSeparator);\n\n        int patIdxStart = 0;\n        int patIdxEnd = patDirs.length - 1;\n        int strIdxStart = 0;\n        int strIdxEnd = strDirs.length - 1;\n\n        // Match all elements up to the first **\n        while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {\n            String patDir = (String) patDirs[patIdxStart];\n            if (patDir.equals(\"**\")) {\n                break;\n            }\n            if (!matchStrings(patDir, (String) strDirs[strIdxStart])) {\n                return false;\n            }\n            patIdxStart++;\n            strIdxStart++;\n        }\n\n        if (strIdxStart > strIdxEnd) {\n            // String is exhausted, only match if rest of pattern is * or **'s\n            if (patIdxStart == patIdxEnd && patDirs[patIdxStart].equals(\"*\") && str.endsWith(this.pathSeparator)) {\n                return true;\n            }\n            for (int i = patIdxStart; i <= patIdxEnd; i++) {\n                if (!patDirs[i].equals(\"**\")) {\n                    return false;\n                }\n            }\n            return true;\n        } else {\n            if (patIdxStart > patIdxEnd) {\n                // String not exhausted, but pattern is. Failure.\n                return false;\n            }\n        }\n\n        // up to last '**'\n        while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {\n            String patDir = (String) patDirs[patIdxEnd];\n            if (patDir.equals(\"**\")) {\n                break;\n            }\n            if (!matchStrings(patDir, (String) strDirs[strIdxEnd])) {\n                return false;\n            }\n            patIdxEnd--;\n            strIdxEnd--;\n        }\n        if (strIdxStart > strIdxEnd) {\n            // String is exhausted\n            for (int i = patIdxStart; i <= patIdxEnd; i++) {\n                if (!patDirs[i].equals(\"**\")) {\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {\n            int patIdxTmp = -1;\n            for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {\n                if (patDirs[i].equals(\"**\")) {\n                    patIdxTmp = i;\n                    break;\n                }\n            }\n            if (patIdxTmp == patIdxStart + 1) {\n                // '**/**' situation, so skip one\n                patIdxStart++;\n                continue;\n            }\n            // Find the pattern between padIdxStart & padIdxTmp in str between\n            // strIdxStart & strIdxEnd\n            int patLength = (patIdxTmp - patIdxStart - 1);\n            int strLength = (strIdxEnd - strIdxStart + 1);\n            int foundIdx = -1;\n            strLoop:\n            for (int i = 0; i <= strLength - patLength; i++) {\n                for (int j = 0; j < patLength; j++) {\n                    String subPat = (String) patDirs[patIdxStart + j + 1];\n                    String subStr = (String) strDirs[strIdxStart + i + j];\n                    if (!matchStrings(subPat, subStr)) {\n                        continue strLoop;\n                    }\n                }\n\n                foundIdx = strIdxStart + i;\n                break;\n            }\n\n            if (foundIdx == -1) {\n                return false;\n            }\n\n            patIdxStart = patIdxTmp;\n            strIdxStart = foundIdx + patLength;\n        }\n\n        for (int i = patIdxStart; i <= patIdxEnd; i++) {\n            if (!patDirs[i].equals(\"**\")) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Tests whether or not a string matches against a pattern. The pattern may\n     * contain two special characters:<br>\n     * '*' means zero or more characters<br>\n     * '?' means one and only one character\n     *\n     * @param pattern pattern to match against. Must not be <code>null</code>.\n     * @param str     string which must be matched against the pattern. Must not be\n     *                <code>null</code>.\n     * @return <code>true</code> if the string matches against the pattern, or\n     * <code>false</code> otherwise.\n     */\n    private boolean matchStrings(String pattern, String str) {\n        char[] patArr = pattern.toCharArray();\n        char[] strArr = str.toCharArray();\n        int patIdxStart = 0;\n        int patIdxEnd = patArr.length - 1;\n        int strIdxStart = 0;\n        int strIdxEnd = strArr.length - 1;\n        char ch;\n\n        boolean containsStar = false;\n        for (int i = 0; i < patArr.length; i++) {\n            if (patArr[i] == '*') {\n                containsStar = true;\n                break;\n            }\n        }\n\n        if (!containsStar) {\n            // No '*'s, so we make a shortcut\n            if (patIdxEnd != strIdxEnd) {\n                return false; // Pattern and string do not have the same size\n            }\n            for (int i = 0; i <= patIdxEnd; i++) {\n                ch = patArr[i];\n                if (ch != '?') {\n                    if (ch != strArr[i]) {\n                        return false;// Character mismatch\n                    }\n                }\n            }\n            return true; // String matches against pattern\n        }\n\n        if (patIdxEnd == 0) {\n            return true; // Pattern contains only '*', which matches anything\n        }\n\n        // Process characters before first star\n        while ((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) {\n            if (ch != '?') {\n                if (ch != strArr[strIdxStart]) {\n                    return false;// Character mismatch\n                }\n            }\n            patIdxStart++;\n            strIdxStart++;\n        }\n        if (strIdxStart > strIdxEnd) {\n            // All characters in the string are used. Check if only '*'s are\n            // left in the pattern. If so, we succeeded. Otherwise failure.\n            for (int i = patIdxStart; i <= patIdxEnd; i++) {\n                if (patArr[i] != '*') {\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        // Process characters after last star\n        while ((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) {\n            if (ch != '?') {\n                if (ch != strArr[strIdxEnd]) {\n                    return false;// Character mismatch\n                }\n            }\n            patIdxEnd--;\n            strIdxEnd--;\n        }\n        if (strIdxStart > strIdxEnd) {\n            // All characters in the string are used. Check if only '*'s are\n            // left in the pattern. If so, we succeeded. Otherwise failure.\n            for (int i = patIdxStart; i <= patIdxEnd; i++) {\n                if (patArr[i] != '*') {\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        // process pattern between stars. padIdxStart and patIdxEnd point\n        // always to a '*'.\n        while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {\n            int patIdxTmp = -1;\n            for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {\n                if (patArr[i] == '*') {\n                    patIdxTmp = i;\n                    break;\n                }\n            }\n            if (patIdxTmp == patIdxStart + 1) {\n                // Two stars next to each other, skip the first one.\n                patIdxStart++;\n                continue;\n            }\n            // Find the pattern between padIdxStart & padIdxTmp in str between\n            // strIdxStart & strIdxEnd\n            int patLength = (patIdxTmp - patIdxStart - 1);\n            int strLength = (strIdxEnd - strIdxStart + 1);\n            int foundIdx = -1;\n            strLoop:\n            for (int i = 0; i <= strLength - patLength; i++) {\n                for (int j = 0; j < patLength; j++) {\n                    ch = patArr[patIdxStart + j + 1];\n                    if (ch != '?') {\n                        if (ch != strArr[strIdxStart + i + j]) {\n                            continue strLoop;\n                        }\n                    }\n                }\n\n                foundIdx = strIdxStart + i;\n                break;\n            }\n\n            if (foundIdx == -1) {\n                return false;\n            }\n\n            patIdxStart = patIdxTmp;\n            strIdxStart = foundIdx + patLength;\n        }\n\n        // All characters in the string are used. Check if only '*'s are left\n        // in the pattern. If so, we succeeded. Otherwise failure.\n        for (int i = patIdxStart; i <= patIdxEnd; i++) {\n            if (patArr[i] != '*') {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Given a pattern and a full path, returns the non-pattern mapped part.\n     * E.g.:\n     * <ul>\n     * <li>'<code>/docs/*</code>' and '<code>/docs/cvs/commit</code> -> '\n     * <code>cvs/commit</code>'</li>\n     * <li>'<code>/docs/cvs/*.html</code>' and '\n     * <code>/docs/cvs/commit.html</code> -> '<code>commit</code>'</li>\n     * <li>'<code>/docs/**</code>' and '<code>/docs/cvs/commit</code> -> '\n     * <code>cvs/commit</code>'</li>\n     * <li>'<code>/docs/**\\/*.html</code>' and '<code>/docs/cvs/commit</code> ->\n     * '<code>cvs/commit</code>'</li>\n     * </ul>\n     * <p/>\n     * Assumes that {@link #match} returns <code>true</code> for '\n     * <code>pattern</code>' and '<code>path</code>', but does\n     * <strong>not</strong> enforce this.\n     */\n    public String extractPathWithinPattern(String pattern, String path) {\n        String[] patternParts = StringUtils.split(pattern, this.pathSeparator);\n        String[] pathParts = StringUtils.split(path, this.pathSeparator);\n\n        StringBuffer buffer = new StringBuffer();\n\n        // Add any path parts that have a wildcarded pattern part.\n        int puts = 0;\n        for (int i = 0; i < patternParts.length; i++) {\n            String patternPart = patternParts[i];\n            if (patternPart.indexOf('*') > -1 || patternPart.indexOf('?') > -1) {\n                if (puts != 0) {\n                    buffer.append(this.pathSeparator);\n                }\n                if (pathParts.length >= i + 1) {\n                    buffer.append(pathParts[i]);\n                    puts++;\n                }\n            }\n        }\n\n        // Append any trailing path parts.\n        for (int i = patternParts.length; i < pathParts.length; i++) {\n            if (puts > 0 || i > 0) {\n                buffer.append(this.pathSeparator);\n            }\n            buffer.append(pathParts[i]);\n        }\n\n        return buffer.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/utils/Profiler.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\n//\n// Source code recreated from a .class file by IntelliJ IDEA\n// (powered by Fernflower decompiler)\n//\n\npackage com.taobao.android.utils;\n\nimport java.text.MessageFormat;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\nimport org.apache.commons.lang3.ObjectUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic final class Profiler {\n\n    public static Logger sLogger = LoggerFactory.getLogger(Profiler.class);\n\n    private static final ThreadLocal entryStack = new ThreadLocal();\n\n    public Profiler() {\n    }\n\n    public static void start() {\n        start((String)null);\n    }\n\n    public static void start(String message) {\n        entryStack.set(new Profiler.Entry(message, (Profiler.Entry)null, (Profiler.Entry)null));\n    }\n\n    public static void start(Profiler.Message message) {\n        entryStack.set(new Profiler.Entry(message, (Profiler.Entry)null, (Profiler.Entry)null));\n    }\n\n    public static void reset() {\n        entryStack.set((Object)null);\n    }\n\n    public static void enter(String message) {\n        Profiler.Entry currentEntry = getCurrentEntry();\n        if (currentEntry != null) {\n            currentEntry.enterSubEntry(message);\n        }\n\n    }\n\n    public static void enter(Profiler.Message message) {\n        Profiler.Entry currentEntry = getCurrentEntry();\n        if (currentEntry != null) {\n            currentEntry.enterSubEntry(message);\n        }\n\n    }\n\n    public static void release() {\n        Profiler.Entry currentEntry = getCurrentEntry();\n        if (currentEntry != null) {\n            currentEntry.release();\n        }\n\n    }\n\n    public static long getDuration() {\n        Profiler.Entry entry = (Profiler.Entry)entryStack.get();\n        return entry != null ? entry.getDuration() : -1L;\n    }\n\n    public static String dump() {\n        return dump(\"\", \"\");\n    }\n\n    public static String dump(String prefix) {\n        return dump(prefix, prefix);\n    }\n\n    public static String dump(String prefix1, String prefix2) {\n        Profiler.Entry entry = (Profiler.Entry)entryStack.get();\n        return entry != null ? entry.toString(prefix1, prefix2) : \"\";\n    }\n\n    public static Profiler.Entry getEntry() {\n        return (Profiler.Entry)entryStack.get();\n    }\n\n    private static Profiler.Entry getCurrentEntry() {\n        Profiler.Entry subEntry = (Profiler.Entry)entryStack.get();\n        Profiler.Entry entry = null;\n        if (subEntry != null) {\n            do {\n                entry = subEntry;\n                subEntry = subEntry.getUnreleasedEntry();\n            } while (subEntry != null);\n        }\n\n        return entry;\n    }\n\n    public interface Message {\n\n        String getBriefMessage();\n\n        String getDetailedMessage();\n    }\n\n    public static final class Entry {\n        private final List subEntries;\n        private final Object message;\n        private final Profiler.Entry parentEntry;\n        private final Profiler.Entry firstEntry;\n        private final long baseTime;\n        private final long startTime;\n        private long endTime;\n\n        private Entry(Object message, Profiler.Entry parentEntry, Profiler.Entry firstEntry) {\n            this.subEntries = new ArrayList(4);\n            this.message = message;\n            this.startTime = System.currentTimeMillis();\n            this.parentEntry = parentEntry;\n            this.firstEntry = (Profiler.Entry)ObjectUtils.defaultIfNull(firstEntry, this);\n            this.baseTime = firstEntry == null ? 0L : firstEntry.startTime;\n        }\n\n        public String getMessage() {\n            String messageString = null;\n            if (this.message instanceof String) {\n                messageString = (String)this.message;\n            } else if (this.message instanceof Profiler.Message) {\n                Profiler.Message messageObject = (Profiler.Message)this.message;\n\n                messageString = messageObject.getDetailedMessage();\n\n            }\n\n            return StringUtils.defaultIfEmpty(messageString, (String)null);\n        }\n\n        public long getStartTime() {\n            return this.baseTime > 0L ? this.startTime - this.baseTime : 0L;\n        }\n\n        public long getEndTime() {\n            return this.endTime < this.baseTime ? -1L : this.endTime - this.baseTime;\n        }\n\n        public long getDuration() {\n            return this.endTime < this.startTime ? -1L : this.endTime - this.startTime;\n        }\n\n        public long getDurationOfSelf() {\n            long duration = this.getDuration();\n            if (duration < 0L) {\n                return -1L;\n            } else if (this.subEntries.isEmpty()) {\n                return duration;\n            } else {\n                for (int i = 0; i < this.subEntries.size(); ++i) {\n                    Profiler.Entry subEntry = (Profiler.Entry)this.subEntries.get(i);\n                    duration -= subEntry.getDuration();\n                }\n\n                return duration < 0L ? -1L : duration;\n            }\n        }\n\n        public double getPecentage() {\n            double parentDuration = 0.0D;\n            double duration = (double)this.getDuration();\n            if (this.parentEntry != null && this.parentEntry.isReleased()) {\n                parentDuration = (double)this.parentEntry.getDuration();\n            }\n\n            return duration > 0.0D && parentDuration > 0.0D ? duration / parentDuration : 0.0D;\n        }\n\n        public double getPecentageOfAll() {\n            double firstDuration = 0.0D;\n            double duration = (double)this.getDuration();\n            if (this.firstEntry != null && this.firstEntry.isReleased()) {\n                firstDuration = (double)this.firstEntry.getDuration();\n            }\n\n            return duration > 0.0D && firstDuration > 0.0D ? duration / firstDuration : 0.0D;\n        }\n\n        public List getSubEntries() {\n            return Collections.unmodifiableList(this.subEntries);\n        }\n\n        private void release() {\n            this.endTime = System.currentTimeMillis();\n        }\n\n        private boolean isReleased() {\n            return this.endTime > 0L;\n        }\n\n        private void enterSubEntry(Object message) {\n            Profiler.Entry subEntry = new Profiler.Entry(message, this, this.firstEntry);\n            this.subEntries.add(subEntry);\n        }\n\n        private Profiler.Entry getUnreleasedEntry() {\n            Profiler.Entry subEntry = null;\n            if (!this.subEntries.isEmpty()) {\n                subEntry = (Profiler.Entry)this.subEntries.get(this.subEntries.size() - 1);\n                if (subEntry.isReleased()) {\n                    subEntry = null;\n                }\n            }\n\n            return subEntry;\n        }\n\n        @Override\n        public String toString() {\n            return this.toString(\"\", \"\");\n        }\n\n        private String toString(String prefix1, String prefix2) {\n            StringBuffer buffer = new StringBuffer();\n            this.toString(buffer, prefix1, prefix2);\n            return buffer.toString();\n        }\n\n        private void toString(StringBuffer buffer, String prefix1, String prefix2) {\n            buffer.append(prefix1);\n            String message = this.getMessage();\n            long startTime = this.getStartTime();\n            long duration = this.getDuration();\n            long durationOfSelf = this.getDurationOfSelf();\n            double percent = this.getPecentage();\n            double percentOfAll = this.getPecentageOfAll();\n            Object[] params = new Object[] {message, new Long(startTime), new Long(duration), new Long(durationOfSelf),\n                new Double(percent), new Double(percentOfAll)};\n            StringBuffer pattern = new StringBuffer(\"{1,number} \");\n            if (this.isReleased()) {\n                pattern.append(\"[{2,number}ms\");\n                if (durationOfSelf > 0L && durationOfSelf != duration) {\n                    pattern.append(\" ({3,number}ms)\");\n                }\n\n                if (percent > 0.0D) {\n                    pattern.append(\", {4,number,##%}\");\n                }\n\n                if (percentOfAll > 0.0D) {\n                    pattern.append(\", {5,number,##%}\");\n                }\n\n                pattern.append(\"]\");\n            } else {\n                pattern.append(\"[UNRELEASED]\");\n            }\n\n            if (message != null) {\n                pattern.append(\" - {0}\");\n            }\n\n            buffer.append(MessageFormat.format(pattern.toString(), params));\n\n            for (int i = 0; i < this.subEntries.size(); ++i) {\n                Profiler.Entry subEntry = (Profiler.Entry)this.subEntries.get(i);\n                buffer.append('\\n');\n                if (i == this.subEntries.size() - 1) {\n                    subEntry.toString(buffer, prefix2 + \"`---\", prefix2 + \"    \");\n                } else if (i == 0) {\n                    subEntry.toString(buffer, prefix2 + \"+---\", prefix2 + \"|   \");\n                } else {\n                    subEntry.toString(buffer, prefix2 + \"+---\", prefix2 + \"|   \");\n                }\n            }\n\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/utils/SmaliCodeUtils.java",
    "content": "/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\npackage com.taobao.android.utils;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport com.google.common.collect.Lists;\n\nimport com.taobao.android.smali.BakSmali;\nimport org.apache.commons.lang3.StringUtils;\nimport org.jf.baksmali.Adaptors.ClassDefinition;\nimport org.jf.baksmali.Adaptors.MethodDefinition;\nimport org.jf.baksmali.BaksmaliOptions;\nimport org.jf.dexlib2.Opcodes;\nimport org.jf.dexlib2.dexbacked.DexBackedMethodImplementation;\nimport org.jf.dexlib2.iface.ClassDef;\nimport org.jf.dexlib2.util.SyntheticAccessorResolver;\nimport org.jf.util.IndentingWriter;\n\nimport java.io.IOException;\nimport java.io.StringWriter;\nimport java.util.List;\n\n/**\n * 将field,类等转换为smali代码\n * Created by shenghua.nish on 2016-04-29 上午10:21.\n */\npublic class SmaliCodeUtils {\n\n    protected static final int DEFAULT_API_LEVEL = 19;\n\n\n    /**\n     * 将方法的实现转换为smali代码\n     *\n     * @param dexBackedMethodImplementation\n     * @param withLineNo                    是否包含行号\n     * @return\n     */\n    public static String methodImplementionToCode(DexBackedMethodImplementation dexBackedMethodImplementation, boolean withLineNo) {\n        if (null == dexBackedMethodImplementation) {\n            return null;\n        }\n        StringWriter stringWriter = new StringWriter();\n        IndentingWriter writer = new IndentingWriter(stringWriter);\n        MethodDefinition methodDefinition = new MethodDefinition(toClassDefinition(dexBackedMethodImplementation),\n                dexBackedMethodImplementation.method,\n                dexBackedMethodImplementation);\n        try {\n            methodDefinition.writeTo(writer);\n        } catch (IOException e) {\n            throw new RuntimeException(e.getMessage(), e);\n        }\n        if (withLineNo) {\n            return stringWriter.toString();\n        } else {\n            List<String> codes = Lists.newArrayList();\n            String[] lines = StringUtils.split(stringWriter.toString(), \"\\n\");\n            for (String line : lines) {\n                if (StringUtils.isNoneBlank(line) && !line.matches(\"\\\\s+\\\\.line\\\\s+[0-9]+$\")) {\n                    codes.add(line);\n                }\n            }\n            return StringUtils.join(codes, \"\\n\");\n        }\n\n    }\n\n    private static ClassDefinition toClassDefinition(ClassDef classDef) {\n        ClassDefinition classDefinition = new ClassDefinition(createBaksmaliOptions(classDef), classDef);\n        return classDefinition;\n    }\n\n    private static ClassDefinition toClassDefinition(DexBackedMethodImplementation dexBackedMethodImplementation) {\n        ClassDefinition classDefinition = new ClassDefinition(createBaksmaliOptions(dexBackedMethodImplementation.method.classDef),\n                dexBackedMethodImplementation.method.classDef);\n        return classDefinition;\n    }\n\n    /**\n     * 生成解析成smali代码的选项\n     *\n     * @return\n     */\n    private static BaksmaliOptions createBaksmaliOptions(ClassDef classDef) {\n        BaksmaliOptions options = new BaksmaliOptions();\n        options.deodex = false;\n        options.parameterRegisters = false;\n        options.localsDirective = true;\n        options.sequentialLabels = true;\n        options.debugInfo = false;\n        options.codeOffsets = false;\n        options.accessorComments = false;\n        options.registerInfo = 0;// 128\n        options.inlineResolver = null;\n        options.apiLevel = DEFAULT_API_LEVEL;\n        List<ClassDef> classDefs = Lists.newArrayList();\n        classDefs.add(classDef);\n        options.syntheticAccessorResolver = new SyntheticAccessorResolver(Opcodes.getDefault(),classDefs);\n        return options;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/utils/SoDiffUtils.java",
    "content": "package com.taobao.android.utils;\n\nimport com.taobao.android.dex.util.FileUtils;\n\nimport java.io.File;\nimport java.io.IOException;\n\n/**\n * SoDiffUtils\n *\n * @author zhayu.ll\n * @date 18/4/25\n */\npublic class SoDiffUtils {\n\n    public  static void diffSo(File workingDir, File baseSo, File newSo, File patchFile) throws IOException {\n        File bsDiffFile = SystemUtils.getDiffFile();\n        bsDiffFile.setExecutable(true);\n        if (!patchFile.getParentFile().exists()){\n            org.apache.commons.io.FileUtils.forceMkdir(patchFile.getParentFile());\n        }\n        CommandUtils.exec(workingDir,bsDiffFile.getAbsolutePath()+ \" \"+baseSo.getAbsolutePath() + \" \"+newSo.getAbsolutePath()+\" \"+patchFile.getAbsolutePath());\n        if (!patchFile.exists()){\n            throw new IOException(\"SO DIFF failed! \"+ patchFile.getAbsolutePath() + \" generate failed!\");\n        }\n\n    }\n\n    public  static void patchSo(File workingDir,File baseSo,File newSo,File patchFile) throws IOException {\n        File bsPatchFile = SystemUtils.getPatchFile();\n        bsPatchFile.setExecutable(true);\n        if (!newSo.getParentFile().exists()){\n            org.apache.commons.io.FileUtils.forceMkdir(newSo.getParentFile());\n        }\n        CommandUtils.exec(workingDir,bsPatchFile.getAbsolutePath()+ \" \"+baseSo.getAbsolutePath() + \" \"+newSo.getAbsolutePath()+\" \"+patchFile.getAbsolutePath());\n        if (!newSo.exists()){\n            throw new IOException(\"SO DIFF failed! \" + newSo.getAbsolutePath() + \"generate failed!\");\n        }\n\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/utils/SystemUtils.java",
    "content": "package com.taobao.android.utils;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.gradle.internal.io.IoUtils;\n\nimport java.io.*;\n\n/**\n * SystemUtils\n *\n * @author zhayu.ll\n * @date 18/4/23\n */\npublic class SystemUtils {\n\n\n    public static File getDiffFile() {\n\n\n        String osName = \"mac\";\n        String fileName = \"bsdiff\";\n\n        if (StringUtils.containsIgnoreCase(System.getProperty(\"os.name\"), \"Mac\")) {\n            osName = \"mac\";\n        } else if (StringUtils.containsIgnoreCase(System.getProperty(\"os.name\"), \"Linux\")) {\n            osName = \"linux\";\n        } else if (StringUtils.containsIgnoreCase(System.getProperty(\"os.name\"), \"windows\")) {\n            osName = \"win\";\n            fileName = \"bsdiff.exe\";\n        }\n        String diffPath = osName + \"/\" + fileName;\n\n        File temp = new File(new File(SystemUtils.class.getProtectionDomain().getCodeSource().getLocation().getFile()).getParentFile(),fileName);\n        FileOutputStream fileOutputStream = null;\n        InputStream inputStream = null;\n        try {\n\n            fileOutputStream = new FileOutputStream(temp);\n\n             inputStream = SystemUtils.class.getClassLoader().getResourceAsStream(diffPath);\n\n            IOUtils.copy(inputStream,fileOutputStream);\n\n        }catch (Exception e){\n            e.printStackTrace();\n        }finally {\n            IOUtils.closeQuietly(inputStream);\n            IOUtils.closeQuietly(fileOutputStream);\n\n        }\n\n//        File tempFile = new File(workingDir,)\n        return temp;\n\n\n\n//        return new File(SystemUtils.class.getClassLoader().getResourceAsStream(diffPath).getFile());\n    }\n\n\n\n    public static File getPatchFile() {\n\n\n        String osName = \"mac\";\n        String fileName = \"bspatch\";\n\n        if (StringUtils.containsIgnoreCase(System.getProperty(\"os.name\"), \"Mac\")) {\n            osName = \"mac\";\n        } else if (StringUtils.containsIgnoreCase(System.getProperty(\"os.name\"), \"Linux\")) {\n            osName = \"linux\";\n        } else if (StringUtils.containsIgnoreCase(System.getProperty(\"os.name\"), \"windows\")) {\n            osName = \"win\";\n            fileName = \"bspatch.exe\";\n        }\n        String diffPath = osName + \"/\" + fileName;\n\n        InputStream in = null;\n        FileOutputStream fileOutputStream = null;\n\n        File temp = new File(new File(SystemUtils.class.getProtectionDomain().getCodeSource().getLocation().getFile()).getParentFile(),fileName);\n\n        try {\n\n            fileOutputStream = new FileOutputStream(temp);\n\n            in = SystemUtils.class.getClassLoader().getResourceAsStream(diffPath);\n\n            IOUtils.copy(in,fileOutputStream);\n\n        }catch (Exception e){\n            e.printStackTrace();\n        }finally {\n            IOUtils.closeQuietly(in);\n            IOUtils.closeQuietly(fileOutputStream);\n\n        }\n\n\n        return  temp;\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/android/utils/ZipUtils.java",
    "content": "/*\n * Copyright 2014 Taobao.com All right reserved. This software is the\n * confidential and proprietary information of Tlibaba.com (\"Confidential\n * Information\"). You shall not disclose such Confidential Information and shall\n * use it only in accordance with the terms of the license agreement you entered\n * into with Taobao.com.\n */\npackage com.taobao.android.utils;\n/*\n *\n *\n *                                  Apache License\n *                            Version 2.0, January 2004\n *                         http://www.apache.org/licenses/\n *\n *    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *    1. Definitions.\n *\n *       \"License\" shall mean the terms and conditions for use, reproduction,\n *       and distribution as defined by Sections 1 through 9 of this document.\n *\n *       \"Licensor\" shall mean the copyright owner or entity authorized by\n *       the copyright owner that is granting the License.\n *\n *       \"Legal Entity\" shall mean the union of the acting entity and all\n *       other entities that control, are controlled by, or are under common\n *       control with that entity. For the purposes of this definition,\n *       \"control\" means (i) the power, direct or indirect, to cause the\n *       direction or management of such entity, whether by contract or\n *       otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *       outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *       \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *       exercising permissions granted by this License.\n *\n *       \"Source\" form shall mean the preferred form for making modifications,\n *       including but not limited to software source code, documentation\n *       source, and configuration files.\n *\n *       \"Object\" form shall mean any form resulting from mechanical\n *       transformation or translation of a Source form, including but\n *       not limited to compiled object code, generated documentation,\n *       and conversions to other media types.\n *\n *       \"Work\" shall mean the work of authorship, whether in Source or\n *       Object form, made available under the License, as indicated by a\n *       copyright notice that is included in or attached to the work\n *       (an example is provided in the Appendix below).\n *\n *       \"Derivative Works\" shall mean any work, whether in Source or Object\n *       form, that is based on (or derived from) the Work and for which the\n *       editorial revisions, annotations, elaborations, or other modifications\n *       represent, as a whole, an original work of authorship. For the purposes\n *       of this License, Derivative Works shall not include works that remain\n *       separable from, or merely link (or bind by name) to the interfaces of,\n *       the Work and Derivative Works thereof.\n *\n *       \"Contribution\" shall mean any work of authorship, including\n *       the original version of the Work and any modifications or additions\n *       to that Work or Derivative Works thereof, that is intentionally\n *       submitted to Licensor for inclusion in the Work by the copyright owner\n *       or by an individual or Legal Entity authorized to submit on behalf of\n *       the copyright owner. For the purposes of this definition, \"submitted\"\n *       means any form of electronic, verbal, or written communication sent\n *       to the Licensor or its representatives, including but not limited to\n *       communication on electronic mailing lists, source code control systems,\n *       and issue tracking systems that are managed by, or on behalf of, the\n *       Licensor for the purpose of discussing and improving the Work, but\n *       excluding communication that is conspicuously marked or otherwise\n *       designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *       \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *       on behalf of whom a Contribution has been received by Licensor and\n *       subsequently incorporated within the Work.\n *\n *    2. Grant of Copyright License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       copyright license to reproduce, prepare Derivative Works of,\n *       publicly display, publicly perform, sublicense, and distribute the\n *       Work and such Derivative Works in Source or Object form.\n *\n *    3. Grant of Patent License. Subject to the terms and conditions of\n *       this License, each Contributor hereby grants to You a perpetual,\n *       worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *       (except as stated in this section) patent license to make, have made,\n *       use, offer to sell, sell, import, and otherwise transfer the Work,\n *       where such license applies only to those patent claims licensable\n *       by such Contributor that are necessarily infringed by their\n *       Contribution(s) alone or by combination of their Contribution(s)\n *       with the Work to which such Contribution(s) was submitted. If You\n *       institute patent litigation against any entity (including a\n *       cross-claim or counterclaim in a lawsuit) alleging that the Work\n *       or a Contribution incorporated within the Work constitutes direct\n *       or contributory patent infringement, then any patent licenses\n *       granted to You under this License for that Work shall terminate\n *       as of the date such litigation is filed.\n *\n *    4. Redistribution. You may reproduce and distribute copies of the\n *       Work or Derivative Works thereof in any medium, with or without\n *       modifications, and in Source or Object form, provided that You\n *       meet the following conditions:\n *\n *       (a) You must give any other recipients of the Work or\n *           Derivative Works a copy of this License; and\n *\n *       (b) You must cause any modified files to carry prominent notices\n *           stating that You changed the files; and\n *\n *       (c) You must retain, in the Source form of any Derivative Works\n *           that You distribute, all copyright, patent, trademark, and\n *           attribution notices from the Source form of the Work,\n *           excluding those notices that do not pertain to any part of\n *           the Derivative Works; and\n *\n *       (d) If the Work includes a \"NOTICE\" text file as part of its\n *           distribution, then any Derivative Works that You distribute must\n *           include a readable copy of the attribution notices contained\n *           within such NOTICE file, excluding those notices that do not\n *           pertain to any part of the Derivative Works, in at least one\n *           of the following places: within a NOTICE text file distributed\n *           as part of the Derivative Works; within the Source form or\n *           documentation, if provided along with the Derivative Works; or,\n *           within a display generated by the Derivative Works, if and\n *           wherever such third-party notices normally appear. The contents\n *           of the NOTICE file are for informational purposes only and\n *           do not modify the License. You may add Your own attribution\n *           notices within Derivative Works that You distribute, alongside\n *           or as an addendum to the NOTICE text from the Work, provided\n *           that such additional attribution notices cannot be construed\n *           as modifying the License.\n *\n *       You may add Your own copyright statement to Your modifications and\n *       may provide additional or different license terms and conditions\n *       for use, reproduction, or distribution of Your modifications, or\n *       for any such Derivative Works as a whole, provided Your use,\n *       reproduction, and distribution of the Work otherwise complies with\n *       the conditions stated in this License.\n *\n *    5. Submission of Contributions. Unless You explicitly state otherwise,\n *       any Contribution intentionally submitted for inclusion in the Work\n *       by You to the Licensor shall be under the terms and conditions of\n *       this License, without any additional terms or conditions.\n *       Notwithstanding the above, nothing herein shall supersede or modify\n *       the terms of any separate license agreement you may have executed\n *       with Licensor regarding such Contributions.\n *\n *    6. Trademarks. This License does not grant permission to use the trade\n *       names, trademarks, service marks, or product names of the Licensor,\n *       except as required for reasonable and customary use in describing the\n *       origin of the Work and reproducing the content of the NOTICE file.\n *\n *    7. Disclaimer of Warranty. Unless required by applicable law or\n *       agreed to in writing, Licensor provides the Work (and each\n *       Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *       implied, including, without limitation, any warranties or conditions\n *       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *       PARTICULAR PURPOSE. You are solely responsible for determining the\n *       appropriateness of using or redistributing the Work and assume any\n *       risks associated with Your exercise of permissions under this License.\n *\n *    8. Limitation of Liability. In no event and under no legal theory,\n *       whether in tort (including negligence), contract, or otherwise,\n *       unless required by applicable law (such as deliberate and grossly\n *       negligent acts) or agreed to in writing, shall any Contributor be\n *       liable to You for damages, including any direct, indirect, special,\n *       incidental, or consequential damages of any character arising as a\n *       result of this License or out of the use or inability to use the\n *       Work (including but not limited to damages for loss of goodwill,\n *       work stoppage, computer failure or malfunction, or any and all\n *       other commercial damages or losses), even if such Contributor\n *       has been advised of the possibility of such damages.\n *\n *    9. Accepting Warranty or Additional Liability. While redistributing\n *       the Work or Derivative Works thereof, You may choose to offer,\n *       and charge a fee for, acceptance of support, warranty, indemnity,\n *       or other liability obligations and/or rights consistent with this\n *       License. However, in accepting such obligations, You may act only\n *       on Your own behalf and on Your sole responsibility, not on behalf\n *       of any other Contributor, and only if You agree to indemnify,\n *       defend, and hold each Contributor harmless for any liability\n *       incurred by, or claims asserted against, such Contributor by reason\n *       of your accepting any such warranty or additional liability.\n *\n *    END OF TERMS AND CONDITIONS\n *\n *    APPENDIX: How to apply the Apache License to your work.\n *\n *       To apply the Apache License to your work, attach the following\n *       boilerplate notice, with the fields enclosed by brackets \"[]\"\n *       replaced with your own identifying information. (Don't include\n *       the brackets!)  The text should be enclosed in the appropriate\n *       comment syntax for the file format. We also recommend that a\n *       file or class name and description of purpose be included on the\n *       same \"printed page\" as the copyright notice for easier\n *       identification within third-party archives.\n *\n *    Copyright 2016 Alibaba Group\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n *\n */\n\nimport org.apache.commons.compress.archivers.zip.ZipArchiveEntry;\nimport org.apache.commons.compress.archivers.zip.ZipFile;\nimport org.apache.commons.io.FilenameUtils;\nimport org.apache.commons.io.IOUtils;\nimport org.apache.commons.lang3.StringUtils;\n\nimport java.io.BufferedInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.List;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\nimport java.util.zip.ZipOutputStream;\n\n/**\n * 解压工具类\n *\n * @author shenghua.nish 2014-6-17 上午9:48:32\n */\npublic class ZipUtils {\n\n    /**\n     * <p>\n     * unzip.\n     * </p>\n     *\n     * @param zipFile     a {@link File} object.\n     * @param destination a {@link String} object.\n     * @return a {@link List} object.\n     */\n    public static List<String> unzip(final File zipFile, final String destination) {\n        return unzip(zipFile, destination, null);\n    }\n\n    /**\n     * <p>\n     * unzip.\n     * </p>\n     *\n     * @param zipFile     a {@link File} object.\n     * @param destination a {@link String} object.\n     * @param encoding    a {@link String} object.\n     * @return a {@link List} object.\n     */\n    public static List<String> unzip(final File zipFile, final String destination, String encoding) {\n        List<String> fileNames = new ArrayList<String>();\n        String dest = destination;\n        if (!destination.endsWith(\"/\")) {\n            dest = destination + \"/\";\n        }\n        ZipFile file;\n        try {\n            file = null;\n            if (null == encoding) file = new ZipFile(zipFile);\n            else file = new ZipFile(zipFile, encoding);\n            Enumeration<ZipArchiveEntry> en = file.getEntries();\n            ZipArchiveEntry ze = null;\n            while (en.hasMoreElements()) {\n                ze = en.nextElement();\n                File f = new File(dest, ze.getName());\n                if (ze.isDirectory()) {\n                    f.mkdirs();\n                    continue;\n                } else {\n                    f.getParentFile().mkdirs();\n                    InputStream is = file.getInputStream(ze);\n                    OutputStream os = new FileOutputStream(f);\n                    IOUtils.copy(is, os);\n                    is.close();\n                    os.close();\n                    fileNames.add(f.getAbsolutePath());\n                }\n            }\n            file.close();\n        } catch (IOException e) {\n            throw new RuntimeException(e.getMessage(), e);\n        }\n        return fileNames;\n    }\n\n    /**\n     * <p>\n     * isZipFile.\n     * </p>\n     *\n     * @param zipFile a {@link File} object.\n     * @return a boolean.\n     */\n    public static boolean isZipFile(File zipFile) {\n        try {\n            ZipFile zf = new ZipFile(zipFile);\n            boolean isZip = zf.getEntries().hasMoreElements();\n            zf.close();\n            return isZip;\n        } catch (IOException e) {\n            return false;\n        }\n    }\n\n\n    private static String getFileName(File folder, File file) {\n        String name = StringUtils.replace(file.getAbsolutePath(), folder.getAbsolutePath() + \"/\", \"\");\n        return name;\n    }\n\n    /**\n     * 解压zip文件中的某个文件到指定地方\n     *\n     * @param zipFile\n     * @param path\n     * @param destFolder\n     * @throws IOException\n     */\n    public static File extractZipFileToFolder(File zipFile, String path, File destFolder) {\n        ZipFile zip;\n        File destFile = null;\n        try {\n            zip = new ZipFile(zipFile);\n            ZipArchiveEntry zipArchiveEntry = zip.getEntry(path);\n            if (null != zipArchiveEntry) {\n                String name = zipArchiveEntry.getName();\n                name = FilenameUtils.getName(name);\n                destFile = new File(destFolder, name);\n                destFolder.mkdirs();\n                destFile.createNewFile();\n                InputStream is = zip.getInputStream(zipArchiveEntry);\n                FileOutputStream fos = new FileOutputStream(destFile);\n                int length = 0;\n                byte[] b = new byte[1024];\n                while ((length = is.read(b, 0, 1024)) != -1) {\n                    fos.write(b, 0, length);\n                }\n                is.close();\n                fos.close();\n            }\n            if (null != zip) ZipFile.closeQuietly(zip);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        return destFile;\n    }\n\n    /**\n     * 增加文件到zip文件\n     *\n     * @param zipFile\n     * @param file\n     * @param destPath  要放的路径\n     * @param overwrite 是否覆盖\n     * @throws IOException\n     */\n    public static void addFileToZipFile(File zipFile, File outZipFile, File file, String destPath, boolean overwrite)\n            throws IOException {\n        byte[] buf = new byte[1024];\n        ZipInputStream zin = new ZipInputStream(new FileInputStream(zipFile));\n        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outZipFile));\n        ZipEntry entry = zin.getNextEntry();\n        boolean addFile = true;\n        while (entry != null) {\n            boolean addEntry = true;\n            String name = entry.getName();\n            if (StringUtils.equalsIgnoreCase(name, destPath)) {\n                if (overwrite) {\n                    addEntry = false;\n                } else {\n                    addFile = false;\n                }\n            }\n            if (addEntry) {\n                ZipEntry zipEntry = null;\n                if (ZipEntry.STORED == entry.getMethod()) {\n                    zipEntry = new ZipEntry(entry);\n                } else {\n                    zipEntry = new ZipEntry(name);\n                }\n                out.putNextEntry(zipEntry);\n                int len;\n                while ((len = zin.read(buf)) > 0) {\n                    out.write(buf, 0, len);\n                }\n            }\n            entry = zin.getNextEntry();\n        }\n\n        if (addFile) {\n            InputStream in = new FileInputStream(file);\n            // Add ZIP entry to output stream.\n            ZipEntry zipEntry = new ZipEntry(destPath);\n            out.putNextEntry(zipEntry);\n            // Transfer bytes from the file to the ZIP file\n            int len;\n            while ((len = in.read(buf)) > 0) {\n                out.write(buf, 0, len);\n            }\n            // Complete the entry\n            out.closeEntry();\n            in.close();\n        }\n        // Close the streams\n        zin.close();\n        out.close();\n    }\n\n\n    /**\n     * 指定文件压缩成一个zip包，主要给solib发布使用\n     *\n     * @param output\n     * @param srcDir\n     * @throws Exception\n     */\n    public static void addFileAndDirectoryToZip(File output, File srcDir) throws Exception {\n        if (output.isDirectory()) {\n            throw new IOException(\"This is a directory!\");\n        }\n        if (!output.getParentFile().exists()) {\n            output.getParentFile().mkdirs();\n        }\n\n        if (!output.exists()) {\n            output.createNewFile();\n        }\n        List fileList = getSubFiles(srcDir);\n        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(output));\n        ZipEntry ze = null;\n        byte[] buf = new byte[1024];\n        int readLen = 0;\n        for (int i = 0; i < fileList.size(); i++) {\n            File f = (File) fileList.get(i);\n            ze = new ZipEntry(getAbsFileName(srcDir.getPath(), f));\n            ze.setSize(f.length());\n            ze.setTime(f.lastModified());\n            zos.putNextEntry(ze);\n            InputStream is = new BufferedInputStream(new FileInputStream(f));\n            while ((readLen = is.read(buf, 0, 1024)) != -1) {\n                zos.write(buf, 0, readLen);\n            }\n            is.close();\n        }\n        zos.close();\n    }\n\n    public static List<String> listZipEntries(File zipFile) {\n        List<String> list = new ArrayList<String>();\n        ZipFile zip;\n        try {\n            zip = new ZipFile(zipFile);\n            Enumeration<ZipArchiveEntry> en = zip.getEntries();\n            ZipArchiveEntry ze = null;\n            while (en.hasMoreElements()) {\n                ze = en.nextElement();\n                String name = ze.getName();\n                list.add(name);\n            }\n            if (null != zip) ZipFile.closeQuietly(zip);\n        } catch (IOException e) {\n        }\n        return list;\n    }\n\n    private static String getAbsFileName(String baseDir, File realFileName) {\n        File real = realFileName;\n        File base = new File(baseDir);\n        String ret = real.getName();\n        while (true) {\n            real = real.getParentFile();\n            if (real == null) {\n                break;\n            }\n            if (real.equals(base)) {\n                break;\n            } else {\n                ret = real.getName() + \"/\" + ret;\n            }\n        }\n        return ret;\n    }\n\n    private static List<File> getSubFiles(File baseDir) {\n        List<File> ret = new ArrayList<File>();\n        File[] tmp = baseDir.listFiles();\n        for (int i = 0; i < tmp.length; i++) {\n            if (tmp[i].isFile()) ret.add(tmp[i]);\n            if (tmp[i].isDirectory()) ret.addAll(getSubFiles(tmp[i]));\n        }\n        return ret;\n    }\n\n    /**\n     * 判断在指定的zip目录下，指定的文件夹是否存在\n     *\n     * @param zipFile\n     * @param pathName\n     * @return\n     */\n    public static boolean isFolderExist(File zipFile, String pathName) {\n\n        ZipFile file = null;\n        try {\n            file = new ZipFile(zipFile);\n            Enumeration<ZipArchiveEntry> en = file.getEntries();\n            while (en.hasMoreElements()) {\n                ZipArchiveEntry entry = en.nextElement();\n                String name = entry.getName();\n                if (name.startsWith(pathName)) {\n                    return true;\n                }\n\n            }\n            return false;\n        } catch (IOException e) {\n        } finally {\n            if (null != file) {\n                try {\n                    file.close();\n                } catch (IOException e) {\n\n                }\n            }\n\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/checker/Checker.java",
    "content": "package com.taobao.checker;\n\nimport java.io.IOException;\nimport java.io.Serializable;\nimport java.util.List;\n\n/**\n * @author lilong\n * @create 2017-08-15 下午1:18\n */\n\npublic interface Checker {\n\n     List<ReasonMsg> check() throws IOException;\n\n    public enum ReasonType {\n        SUCCESS(\"校验成功\"),\n        ERROR1(\"patch包中bundle个数和json中不匹配\"),\n        ERROR2(\"动态部署的bundle srcunittag和unittag相同\"),\n        ERROR3(\"对应的patch包未打出\"),\n        ERROR4(\"unittag变化了但是不在patch包中\"),\n        ERROR5(\"FrameworkProperties中的unittag和patch信息中的不一致\"),\n        ERROR6(\"FrameworkProperties中unittag发生了变化,但是patch中不存在\"),\n        ERROR7(\"FrameworkProperties中unittag没有发生变化,但是patch中有这个bundle\"),\n        ERROR8(\"patch中的srcunittag和历史的bundle匹配不上\"),\n        ERROR9(\"TEST\");\n\n\n\n        public String getMsg() {\n            return msg;\n        }\n\n        private String msg;\n\n        ReasonType(String s) {\n            this.msg = s;\n        }\n\n    }\n    public class ReasonMsg implements Serializable {\n        private ReasonType reasonType;\n        private String msg;\n\n        public ReasonMsg(ReasonType reasonType,String msg) {\n            this.reasonType = reasonType;\n            this.msg = msg;\n        }\n\n        @Override\n        public String toString() {\n            return reasonType.getMsg() + msg;\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/checker/PatchChecker.java",
    "content": "package com.taobao.checker;\n\nimport com.taobao.android.reader.BundleListing;\nimport com.taobao.update.UpdateInfo;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n/**\n * @author lilong\n * @create 2017-08-15 上午11:41\n */\n\npublic class PatchChecker implements Checker{\n    private UpdateInfo updateInfo;\n    private File file;\n    private LinkedHashMap<String,BundleListing.BundleInfo> bundleInfos = new LinkedHashMap<>();\n\n    public PatchChecker(UpdateInfo updateInfo, LinkedHashMap linkedHashMap, File patchFile) {\n        this.updateInfo = updateInfo;\n        this.file = patchFile;\n        this.bundleInfos = linkedHashMap;\n    }\n\n    public List<ReasonMsg> check() throws IOException {\n        List<ReasonMsg>reasonMsgs = new ArrayList<>();\n        List<String>changedBundles = new ArrayList<>();\n        if (bundleInfos == null){\n            System.out.println(\"skip check \"+file.getName()+\" bundleInfos is null!\");\n            reasonMsgs.add(new ReasonMsg(ReasonType.SUCCESS, file.getName()));\n            return reasonMsgs;\n        }\n        for (Map.Entry entry:bundleInfos.entrySet()){\n            BundleListing.BundleInfo bundleInfo = (BundleListing.BundleInfo) entry.getValue();\n            if (bundleInfo.getCurrent_unique_tag()!= null) {\n                if (!bundleInfo.getCurrent_unique_tag().equals(bundleInfo.getUnique_tag())) {\n                    changedBundles.add(bundleInfo.getPkgName());\n                }\n            }\n        }\n        if (!file.exists()){\n            reasonMsgs.add(new ReasonMsg(ReasonType.ERROR3,file.getName()));\n        }\n        ZipFile zipFile = new ZipFile(file);\n        for (UpdateInfo.Item item:updateInfo.updateBundles){\n            Enumeration<? extends ZipEntry>enumeration =  zipFile.entries();\n            if (!item.name.equals(\"com.taobao.maindex\")&&!changedBundles.contains(item.name)){\n                reasonMsgs.add(new ReasonMsg(ReasonType.ERROR7,item.name));\n            }\n            if (item.unitTag!= null &&!item.name.equals(\"com.taobao.maindex\")&&!item.unitTag.equals(bundleInfos.get(item.name).getCurrent_unique_tag())){\n                reasonMsgs.add(new ReasonMsg(ReasonType.ERROR5,item.name));\n            }\n            if (item.unitTag!= null &&!item.name.equals(\"com.taobao.maindex\")&&!item.srcUnitTag.equals(bundleInfos.get(item.name).getUnique_tag())){\n                reasonMsgs.add(new ReasonMsg(ReasonType.ERROR8,item.name));\n            }\n            if (item.srcUnitTag!=null && item.srcUnitTag.equals(item.unitTag)){\n                reasonMsgs.add(new ReasonMsg(ReasonType.ERROR2,item.name));\n            }\n            boolean contains = false;\n            while (enumeration.hasMoreElements()){\n                    ZipEntry zipEntry = enumeration.nextElement();\n                    String name = zipEntry.getName();\n                    if (name.startsWith(\"lib\"+item.name.replace(\".\",\"_\"))){\n                        contains = true;\n                        break;\n                    }\n                }\n                if (!contains){\n                    reasonMsgs.add(new ReasonMsg(ReasonType.ERROR1,item.name));\n                }\n            changedBundles.remove(item.name);\n        }\n\n        if (changedBundles.size() > 0){\n            for (String bundleName:changedBundles){\n                reasonMsgs.add(new ReasonMsg(ReasonType.ERROR6,bundleName));\n            }\n        }\n        if (reasonMsgs.size() == 0) {\n            reasonMsgs.add(new ReasonMsg(ReasonType.SUCCESS, file.getName()));\n        }\n        return reasonMsgs;\n\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/update/UpdateInfo.java",
    "content": "/*\n *\n *\n *\n *                                   Apache License\n *                             Version 2.0, January 2004\n *                          http://www.apache.org/licenses/\n *\n *     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n *\n *     1. Definitions.\n *\n *        \"License\" shall mean the terms and conditions for use, reproduction,\n *        and distribution as defined by Sections 1 through 9 of this document.\n *\n *        \"Licensor\" shall mean the copyright owner or entity authorized by\n *        the copyright owner that is granting the License.\n *\n *        \"Legal Entity\" shall mean the union of the acting entity and all\n *        other entities that control, are controlled by, or are under common\n *        control with that entity. For the purposes of this definition,\n *        \"control\" means (i) the power, direct or indirect, to cause the\n *        direction or management of such entity, whether by contract or\n *        otherwise, or (ii) ownership of fifty percent (50%) or more of the\n *        outstanding shares, or (iii) beneficial ownership of such entity.\n *\n *        \"You\" (or \"Your\") shall mean an individual or Legal Entity\n *        exercising permissions granted by this License.\n *\n *        \"Source\" form shall mean the preferred form for making modifications,\n *        including but not limited to software source code, documentation\n *        source, and configuration files.\n *\n *        \"Object\" form shall mean any form resulting from mechanical\n *        transformation or translation of a Source form, including but\n *        not limited to compiled object code, generated documentation,\n *        and conversions to other media types.\n *\n *        \"Work\" shall mean the work of authorship, whether in Source or\n *        Object form, made available under the License, as indicated by a\n *        copyright notice that is included in or attached to the work\n *        (an example is provided in the Appendix below).\n *\n *        \"Derivative Works\" shall mean any work, whether in Source or Object\n *        form, that is based on (or derived from) the Work and for which the\n *        editorial revisions, annotations, elaborations, or other modifications\n *        represent, as a whole, an original work of authorship. For the purposes\n *        of this License, Derivative Works shall not include works that remain\n *        separable from, or merely link (or bind by name) to the interfaces of,\n *        the Work and Derivative Works thereof.\n *\n *        \"Contribution\" shall mean any work of authorship, including\n *        the original version of the Work and any modifications or additions\n *        to that Work or Derivative Works thereof, that is intentionally\n *        submitted to Licensor for inclusion in the Work by the copyright owner\n *        or by an individual or Legal Entity authorized to submit on behalf of\n *        the copyright owner. For the purposes of this definition, \"submitted\"\n *        means any form of electronic, verbal, or written communication sent\n *        to the Licensor or its representatives, including but not limited to\n *        communication on electronic mailing lists, source code control systems,\n *        and issue tracking systems that are managed by, or on behalf of, the\n *        Licensor for the purpose of discussing and improving the Work, but\n *        excluding communication that is conspicuously marked or otherwise\n *        designated in writing by the copyright owner as \"Not a Contribution.\"\n *\n *        \"Contributor\" shall mean Licensor and any individual or Legal Entity\n *        on behalf of whom a Contribution has been received by Licensor and\n *        subsequently incorporated within the Work.\n *\n *     2. Grant of Copyright License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        copyright license to reproduce, prepare Derivative Works of,\n *        publicly display, publicly perform, sublicense, and distribute the\n *        Work and such Derivative Works in Source or Object form.\n *\n *     3. Grant of Patent License. Subject to the terms and conditions of\n *        this License, each Contributor hereby grants to You a perpetual,\n *        worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n *        (except as stated in this section) patent license to make, have made,\n *        use, offer to sell, sell, import, and otherwise transfer the Work,\n *        where such license applies only to those patent claims licensable\n *        by such Contributor that are necessarily infringed by their\n *        Contribution(s) alone or by combination of their Contribution(s)\n *        with the Work to which such Contribution(s) was submitted. If You\n *        institute patent litigation against any entity (including a\n *        cross-claim or counterclaim in a lawsuit) alleging that the Work\n *        or a Contribution incorporated within the Work constitutes direct\n *        or contributory patent infringement, then any patent licenses\n *        granted to You under this License for that Work shall terminate\n *        as of the date such litigation is filed.\n *\n *     4. Redistribution. You may reproduce and distribute copies of the\n *        Work or Derivative Works thereof in any medium, with or without\n *        modifications, and in Source or Object form, provided that You\n *        meet the following conditions:\n *\n *        (a) You must give any other recipients of the Work or\n *            Derivative Works a copy of this License; and\n *\n *        (b) You must cause any modified files to carry prominent notices\n *            stating that You changed the files; and\n *\n *        (c) You must retain, in the Source form of any Derivative Works\n *            that You distribute, all copyright, patent, trademark, and\n *            attribution notices from the Source form of the Work,\n *            excluding those notices that do not pertain to any part of\n *            the Derivative Works; and\n *\n *        (d) If the Work includes a \"NOTICE\" text file as part of its\n *            distribution, then any Derivative Works that You distribute must\n *            include a readable copy of the attribution notices contained\n *            within such NOTICE file, excluding those notices that do not\n *            pertain to any part of the Derivative Works, in at least one\n *            of the following places: within a NOTICE text file distributed\n *            as part of the Derivative Works; within the Source form or\n *            documentation, if provided along with the Derivative Works; or,\n *            within a display generated by the Derivative Works, if and\n *            wherever such third-party notices normally appear. The contents\n *            of the NOTICE file are for informational purposes only and\n *            do not modify the License. You may add Your own attribution\n *            notices within Derivative Works that You distribute, alongside\n *            or as an addendum to the NOTICE text from the Work, provided\n *            that such additional attribution notices cannot be construed\n *            as modifying the License.\n *\n *        You may add Your own copyright statement to Your modifications and\n *        may provide additional or different license terms and conditions\n *        for use, reproduction, or distribution of Your modifications, or\n *        for any such Derivative Works as a whole, provided Your use,\n *        reproduction, and distribution of the Work otherwise complies with\n *        the conditions stated in this License.\n *\n *     5. Submission of Contributions. Unless You explicitly state otherwise,\n *        any Contribution intentionally submitted for inclusion in the Work\n *        by You to the Licensor shall be under the terms and conditions of\n *        this License, without any additional terms or conditions.\n *        Notwithstanding the above, nothing herein shall supersede or modify\n *        the terms of any separate license agreement you may have executed\n *        with Licensor regarding such Contributions.\n *\n *     6. Trademarks. This License does not grant permission to use the trade\n *        names, trademarks, service marks, or product names of the Licensor,\n *        except as required for reasonable and customary use in describing the\n *        origin of the Work and reproducing the content of the NOTICE file.\n *\n *     7. Disclaimer of Warranty. Unless required by applicable law or\n *        agreed to in writing, Licensor provides the Work (and each\n *        Contributor provides its Contributions) on an \"AS IS\" BASIS,\n *        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n *        implied, including, without limitation, any warranties or conditions\n *        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n *        PARTICULAR PURPOSE. You are solely responsible for determining the\n *        appropriateness of using or redistributing the Work and assume any\n *        risks associated with Your exercise of permissions under this License.\n *\n *     8. Limitation of Liability. In no event and under no legal theory,\n *        whether in tort (including negligence), contract, or otherwise,\n *        unless required by applicable law (such as deliberate and grossly\n *        negligent acts) or agreed to in writing, shall any Contributor be\n *        liable to You for damages, including any direct, indirect, special,\n *        incidental, or consequential damages of any character arising as a\n *        result of this License or out of the use or inability to use the\n *        Work (including but not limited to damages for loss of goodwill,\n *        work stoppage, computer failure or malfunction, or any and all\n *        other commercial damages or losses), even if such Contributor\n *        has been advised of the possibility of such damages.\n *\n *     9. Accepting Warranty or Additional Liability. While redistributing\n *        the Work or Derivative Works thereof, You may choose to offer,\n *        and charge a fee for, acceptance of support, warranty, indemnity,\n *        or other liability obligations and/or rights consistent with this\n *        License. However, in accepting such obligations, You may act only\n *        on Your own behalf and on Your sole responsibility, not on behalf\n *        of any other Contributor, and only if You agree to indemnify,\n *        defend, and hold each Contributor harmless for any liability\n *        incurred by, or claims asserted against, such Contributor by reason\n *        of your accepting any such warranty or additional liability.\n *\n *     END OF TERMS AND CONDITIONS\n *\n *     APPENDIX: How to apply the Apache License to your work.\n *\n *        To apply the Apache License to your work, attach the following\n *        boilerplate notice, with the fields enclosed by brackets \"[]\"\n *        replaced with your own identifying information. (Don't include\n *        the brackets!)  The text should be enclosed in the appropriate\n *        comment syntax for the file format. We also recommend that a\n *        file or class name and description of purpose be included on the\n *        same \"printed page\" as the copyright notice for easier\n *        identification within third-party archives.\n *\n *     Copyright 2016 Alibaba Group\n *\n *     Licensed under the Apache License, Version 2.0 (the \"License\");\n *     you may not use this file except in compliance with the License.\n *     You may obtain a copy of the License at\n *\n *         http://www.apache.org/licenses/LICENSE-2.0\n *\n *     Unless required by applicable law or agreed to in writing, software\n *     distributed under the License is distributed on an \"AS IS\" BASIS,\n *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *     See the License for the specific language governing permissions and\n *     limitations under the License.\n *\n *\n */\n\n//\n// Source code recreated from a .class file by IntelliJ IDEA\n// (powered by Fernflower decompiler)\n//\n\npackage com.taobao.update;\n\nimport com.taobao.android.object.PatchBundleInfo;\nimport com.taobao.android.object.PatchInfo;\nimport java.io.File;\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class UpdateInfo implements Serializable {\n    public String baseVersion;\n    public String updateVersion;\n    public List<Item> updateBundles;\n    public File workDir;\n\n    public UpdateInfo() {\n    }\n\n    public UpdateInfo(PatchInfo patchInfo,String baseVersion) {\n        UpdateInfo updateInfo = this;\n        updateInfo.baseVersion = patchInfo.getTargetVersion();\n        updateInfo.updateVersion = patchInfo.getPatchVersion();\n\n        List<Item> items = new ArrayList<Item>();\n        for (PatchBundleInfo patchBundleInfo : patchInfo.getBundles()) {\n            UpdateInfo.Item item = new UpdateInfo.Item();\n            items.add(item);\n            item.dependency = patchBundleInfo.getDependency();\n            item.isMainDex = patchBundleInfo.getMainBundle();\n            item.unitTag = patchBundleInfo.getUnitTag();\n            item.srcUnitTag = patchBundleInfo.getSrcUnitTag();\n            if (item.isMainDex){\n                item.name = \"com.taobao.maindex\";\n            }else {\n                item.name = patchBundleInfo.getPkgName();\n            }\n//            item.srcVersion = patchBundleInfo.getVersion();\n            item.version = baseVersion + \"@\" + patchBundleInfo.getVersion();\n        }\n        updateInfo.updateBundles = items;\n    }\n\n    public static class Item implements Serializable {\n        public boolean isMainDex;\n        public String name;\n        public String version;\n        public String srcVersion;\n        public String unitTag;\n        public String srcUnitTag;\n        public List<String> dependency;\n\n        public Item() {\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/dexpatch/src/main/java/com/taobao/utils/SparseIntArray.java",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.utils;\n\n/**\n * SparseIntArrays map integers to integers.  Unlike a normal array of integers,\n * there can be gaps in the indices.  It is intended to be more memory efficient\n * than using a HashMap to map Integers to Integers, both because it avoids\n * auto-boxing keys and values and its data structure doesn't rely on an extra entry object\n * for each mapping.\n *\n * <p>Note that this container keeps its mappings in an array data structure,\n * using a binary search to find keys.  The implementation is not intended to be appropriate for\n * data structures\n * that may contain large numbers of items.  It is generally slower than a traditional\n * HashMap, since lookups require a binary search and adds and removes require inserting\n * and deleting entries in the array.  For containers holding up to hundreds of items,\n * the performance difference is not significant, less than 50%.</p>\n *\n * <p>It is possible to iterate over the items in this container using\n * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using\n * <code>keyAt(int)</code> with ascending values of the index will return the\n * keys in ascending order, or the values corresponding to the keys in ascending\n * order in the case of <code>valueAt(int)</code>.</p>\n */\npublic class SparseIntArray implements Cloneable {\n    private static final int[] EMPTY_INT_ARRAY = new int[0];\n    private int[] mKeys;\n    private int[] mValues;\n    private int   mSize;\n\n    /**\n     * Creates a new SparseIntArray containing no mappings.\n     */\n    public SparseIntArray() {\n        this(10);\n    }\n\n    /**\n     * Creates a new SparseIntArray containing no mappings that will not\n     * require any additional memory allocation to store the specified\n     * number of mappings.  If you supply an initial capacity of 0, the\n     * sparse array will be initialized with a light-weight representation\n     * not requiring any additional array allocations.\n     */\n    public SparseIntArray(int initialCapacity) {\n        if (initialCapacity == 0) {\n            mKeys = SparseIntArray.EMPTY_INT_ARRAY;\n            mValues = SparseIntArray.EMPTY_INT_ARRAY;\n        } else {\n            mKeys = new int[initialCapacity];\n            mValues = new int[mKeys.length];\n        }\n        mSize = 0;\n    }\n\n    /**\n     * Given the current size of an array, returns an ideal size to which the array should grow.\n     * This is typically double the given size, but should not be relied upon to do so in the\n     * future.\n     */\n    public static int growSize(int currentSize) {\n        return currentSize <= 4 ? 8 : currentSize + (currentSize >> 1);\n    }\n\n    @Override\n    public SparseIntArray clone() {\n        SparseIntArray clone = null;\n        try {\n            clone = (SparseIntArray) super.clone();\n            clone.mKeys = mKeys.clone();\n            clone.mValues = mValues.clone();\n        } catch (CloneNotSupportedException cnse) {\n            /* ignore */\n        }\n        return clone;\n    }\n\n    /**\n     * Gets the int mapped from the specified key, or <code>0</code>\n     * if no such mapping has been made.\n     */\n    public int get(int key) {\n        return get(key, 0);\n    }\n\n    /**\n     * Gets the int mapped from the specified key, or the specified value\n     * if no such mapping has been made.\n     */\n    public int get(int key, int valueIfKeyNotFound) {\n        int i = binarySearch(mKeys, mSize, key);\n\n        if (i < 0) {\n            return valueIfKeyNotFound;\n        } else {\n            return mValues[i];\n        }\n    }\n\n    /**\n     * Removes the mapping from the specified key, if there was any.\n     */\n    public void delete(int key) {\n        int i = binarySearch(mKeys, mSize, key);\n\n        if (i >= 0) {\n            removeAt(i);\n        }\n    }\n\n    /**\n     * Removes the mapping at the given index.\n     */\n    public void removeAt(int index) {\n        System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));\n        System.arraycopy(mValues, index + 1, mValues, index, mSize - (index + 1));\n        --mSize;\n    }\n\n    /**\n     * Adds a mapping from the specified key to the specified value,\n     * replacing the previous mapping from the specified key if there\n     * was one.\n     */\n    public void put(int key, int value) {\n        int i = binarySearch(mKeys, mSize, key);\n\n        if (i >= 0) {\n            mValues[i] = value;\n        } else {\n            i = ~i;\n            mKeys = insertElementIntoIntArray(mKeys, mSize, i, key);\n            mValues = insertElementIntoIntArray(mValues, mSize, i, value);\n            ++mSize;\n        }\n    }\n\n    /**\n     * Returns the number of key-value mappings that this SparseIntArray\n     * currently stores.\n     */\n    public int size() {\n        return mSize;\n    }\n\n    /**\n     * Given an index in the range <code>0...size()-1</code>, returns\n     * the key from the <code>index</code>th key-value mapping that this\n     * SparseIntArray stores.\n     *\n     * <p>The keys corresponding to indices in ascending order are guaranteed to\n     * be in ascending order, e.g., <code>keyAt(0)</code> will return the\n     * smallest key and <code>keyAt(size()-1)</code> will return the largest\n     * key.</p>\n     */\n    public int keyAt(int index) {\n        return mKeys[index];\n    }\n\n    /**\n     * Given an index in the range <code>0...size()-1</code>, returns\n     * the value from the <code>index</code>th key-value mapping that this\n     * SparseIntArray stores.\n     *\n     * <p>The values corresponding to indices in ascending order are guaranteed\n     * to be associated with keys in ascending order, e.g.,\n     * <code>valueAt(0)</code> will return the value associated with the\n     * smallest key and <code>valueAt(size()-1)</code> will return the value\n     * associated with the largest key.</p>\n     */\n    public int valueAt(int index) {\n        return mValues[index];\n    }\n\n    /**\n     * Returns the index for which {@link #keyAt} would return the\n     * specified key, or a negative number if the specified\n     * key is not mapped.\n     */\n    public int indexOfKey(int key) {\n        return binarySearch(mKeys, mSize, key);\n    }\n\n    /**\n     * Returns an index for which {@link #valueAt} would return the\n     * specified key, or a negative number if no keys map to the\n     * specified value.\n     * Beware that this is a linear search, unlike lookups by key,\n     * and that multiple keys can map to the same value and this will\n     * find only one of them.\n     */\n    public int indexOfValue(int value) {\n        for (int i = 0; i < mSize; ++i) {\n            if (mValues[i] == value) {\n                return i;\n            }\n        }\n        return -1;\n    }\n\n    /**\n     * Removes all key-value mappings from this SparseIntArray.\n     */\n    public void clear() {\n        mSize = 0;\n    }\n\n    /**\n     * Puts a key/value pair into the array, optimizing for the case where\n     * the key is greater than all existing keys in the array.\n     */\n    public void append(int key, int value) {\n        if (mSize != 0 && key <= mKeys[mSize - 1]) {\n            put(key, value);\n            return;\n        }\n\n        mKeys = appendElementIntoIntArray(mKeys, mSize, key);\n        mValues = appendElementIntoIntArray(mValues, mSize, value);\n        mSize++;\n    }\n\n    private int binarySearch(int[] array, int size, int value) {\n        int lo = 0;\n        int hi = size - 1;\n\n        while (lo <= hi) {\n            int mid = (lo + hi) >>> 1;\n            int midVal = array[mid];\n\n            if (midVal < value) {\n                lo = mid + 1;\n            } else if (midVal > value) {\n                hi = mid - 1;\n            } else {\n                return mid;  // value found\n            }\n        }\n        return ~lo;  // value not present\n    }\n\n    private int[] appendElementIntoIntArray(int[] array, int currentSize, int element) {\n        if (currentSize > array.length) {\n            throw new IllegalArgumentException(\"Bad currentSize, originalSize: \" + array.length + \" currentSize: \" + currentSize);\n        }\n        if (currentSize + 1 > array.length) {\n            int[] newArray = new int[SparseIntArray.growSize(currentSize)];\n            System.arraycopy(array, 0, newArray, 0, currentSize);\n            array = newArray;\n        }\n        array[currentSize] = element;\n        return array;\n    }\n\n    private int[] insertElementIntoIntArray(int[] array, int currentSize, int index, int element) {\n        if (currentSize > array.length) {\n            throw new IllegalArgumentException(\"Bad currentSize, originalSize: \" + array.length + \" currentSize: \" + currentSize);\n        }\n\n        if (currentSize + 1 <= array.length) {\n            System.arraycopy(array, index, array, index + 1, currentSize - index);\n            array[index] = element;\n            return array;\n        }\n\n        int[] newArray = new int[SparseIntArray.growSize(currentSize)];\n        System.arraycopy(array, 0, newArray, 0, index);\n        newArray[index] = element;\n        System.arraycopy(array, index, newArray, index + 1, array.length - index);\n        return newArray;\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p>This implementation composes a string by iterating over its mappings.\n     */\n    @Override\n    public String toString() {\n        if (size() <= 0) {\n            return \"{}\";\n        }\n\n        StringBuilder buffer = new StringBuilder(mSize * 28);\n        buffer.append('{');\n        for (int i = 0; i < mSize; i++) {\n            if (i > 0) {\n                buffer.append(\", \");\n            }\n            int key = keyAt(i);\n            buffer.append(key);\n            buffer.append('=');\n            int value = valueAt(i);\n            buffer.append(value);\n        }\n        buffer.append('}');\n        return buffer.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-gradle-plugin/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.2.1-all.zip\n"
  },
  {
    "path": "atlas-gradle-plugin/gradle.properties",
    "content": ""
  },
  {
    "path": "atlas-gradle-plugin/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "atlas-gradle-plugin/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "atlas-gradle-plugin/publish_bintray.gradle",
    "content": "apply plugin: 'maven'\napply plugin: 'maven-publish'\napply plugin: 'com.jfrog.bintray'\ndef siteUrl = 'https://github.com/alibaba/atlas'\n// 项目的主页\ndef gitUrl = 'https://github.com/alibaba/atlas'\n// Git仓库的url\ntask sourcesJar(type: Jar) {\n    from('src/main/java') {\n        include '**'\n    }\n    classifier = 'sources'\n}\npublishing {\n    publications {\n        MyPublication(MavenPublication) {\n            from components.java\n            artifact sourcesJar\n\n        }\n    }\n}\n\nProperties properties = new Properties()\ndef file = project.rootProject.file('local.properties')\nif (file.exists()) {\n    properties.load(file.newDataInputStream())\n}\nbintray {\n    user = project.hasProperty('BINTRAY_USER') ? BINTRAY_USER : properties.getProperty(\"bintray.user\")\n    key = project.hasProperty('BINTRAY_APIKEY') ? BINTRAY_APIKEY : properties.getProperty(\"bintray.apikey\")\n    publications = ['MyPublication']\n    pkg {\n        repo = \"maven\"\n        name = project.name\t//发布到JCenter上的项目名字\n        websiteUrl = siteUrl\n        vcsUrl = gitUrl\n        licenses = [\"Apache-2.0\"]\n        publish = true\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/publish_mvn.gradle",
    "content": "//是否需要把项目发送到远程maven库\next.publishToRemote = true\next.publishDefaultArtifact = !\"true\".equals(project.getProperties().get(\"org.gradle.parallel\"))\next.publishApk = false\next.isApplication = false\n\nif (!project.getBuildFile().exists()) {\n    return;\n}\n\ndef versionFile = new File(project.getRootDir(), \"version.properties\");\nHashMap<String, String> versionMap = new HashMap<String, String>();\nif (versionFile.exists()) {\n    versionFile.eachLine {line ->\n        String[] arr = line.split(\".version=\");\n        if (arr.length == 2) {\n            StringBuilder b = new StringBuilder(arr[0]);\n            b.replace(arr[0].lastIndexOf(\".\"), arr[0].lastIndexOf(\".\") + 1, \":\");\n            versionMap.put(b.toString(), arr[1])\n        }\n    }\n}\n\napply plugin: 'maven'\napply plugin: 'maven-publish'\n\nconfigurations {\n    providedCompile\n    compile.extendsFrom providedCompile\n}\n\nconfigurations.all {\n    resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds'\n    resolutionStrategy.cacheChangingModulesFor 0, 'seconds'\n    resolutionStrategy {\n        for (String key : versionMap.keySet()) {\n            force(key + \":\" + versionMap.get(key))\n        }\n    }\n}\n\nrepositories {\n    mavenLocal()\n    jcenter()\n}\n\n\nif (!project.getRootProject().hasProperty(\"aarMap\")) {\n    project.getRootProject().ext.set(\"aarMap\", new HashSet<String>())\n}\n\ndef deployVersion = System.getProperty('deployVersion')\ndef mtlVersion = System.getenv(\"MUPP_VERSION_NAME\");\n\nproject.afterEvaluate {\n\n    if (project.plugins.hasPlugin(\"com.taobao.android.library\") || project.plugins.hasPlugin(\"com.android.library\")) {\n        project.getRootProject().aarMap.add(project.name)\n    }\n\n    ext.isApplication = (project.plugins.hasPlugin(\"com.android.application\") || project.plugins.hasPlugin(\n            \"com.taobao.android.application\"))\n\n    tasks.whenTaskAdded {task ->\n        if (task.name.startsWith(\"generatePomFileForMavenPublication\")) {\n            task.mustRunAfter(project.getTasks().withType(Zip.class));\n            task.doFirst {\n                project.publishing.publications.maven(MavenPublication) {\n                    if (!components.hasWithName(\"java\") && !isApplication) {\n                        File publishFile = file(\"${project.buildDir}/outputs/awb/${project.name}-release.awb\");\n                        if (!publishFile.exists()) {\n                            publishFile = file(\"${project.buildDir}/outputs/aar/${project.name}-release.aar\");\n                        }\n                        if (!publishFile.exists()) {\n                            publishFile = file(\"${project.buildDir}/outputs/awb/${project.name}-debug.awb\");\n                        }\n                        if (!publishFile.exists()) {\n                            publishFile = file(\"${project.buildDir}/outputs/aar/${project.name}-debug.aar\");\n                        }\n                        artifact publishFile.getPath()\n                    }\n                }\n            }\n        }\n\n        if (isApplication && !publishApk) {\n            if (task.name.startsWith(\"publish\")) {\n                task.setEnabled(false)\n            }\n        }\n    }\n}\n\n\n\npublishing {\n\n    if (null != deployVersion) {\n        version = deployVersion\n    } else if (null != mtlVersion) {\n        version = mtlVersion\n    }\n\n    publications {\n        maven(MavenPublication) {\n            version version\n\n            task sourceJar(type: Jar) {\n                classifier = 'source'\n                version = version\n                try {\n                    if (components.hasWithName(\"java\")) {\n                        from sourceSets.main.allJava\n                    } else {\n                        from android.sourceSets.main.java.srcDirs\n                    }\n                } catch (Throwable e) {\n                }\n            }\n\n            artifact sourceJar\n\n            if (components.hasWithName(\"java\")) {\n                from components.java\n            } else if (components.hasWithName(\"android\") && !isApplication) {\n                from components.android\n\n                updatePom(pom, versionMap, groupId)\n\n                if (components.hasWithName(\"android\")) {\n                    pom.withXml {\n                        def dependenciesNode = asNode().dependencies[0]\n                        if (getGradle().startParameter.toString().contains(\"assembleDebug\")) {\n                            configurations.debugCompile.allDependencies.each {\n                                appendBuildTypeDependency(it, versionMap, dependenciesNode, groupId)\n                            }\n                        } else {\n                            configurations.releaseCompile.allDependencies.each {\n                                appendBuildTypeDependency(it, versionMap, dependenciesNode, groupId)\n                            }\n                        }\n                    }\n                }\n            } else if (!isApplication) {\n\n                pom.withXml {\n\n                    def dependenciesNode = asNode().appendNode('dependencies')\n                    def providedCompiles = new HashSet();\n                    configurations.providedCompile.allDependencies.each {\n                        addBuildTypeDependency(it, versionMap, dependenciesNode, groupId, providedCompiles , true)\n                    }\n\n                    configurations.compile.allDependencies.each {\n                        addBuildTypeDependency(it, versionMap, dependenciesNode, groupId, providedCompiles)\n                    }\n\n                    if (getGradle().startParameter.toString().contains(\"assembleDebug\")) {\n                        configurations.debugCompile.allDependencies.each {\n                            addBuildTypeDependency(it, versionMap, dependenciesNode, groupId, providedCompiles)\n                        }\n                    } else {\n                        configurations.releaseCompile.allDependencies.each {\n                            addBuildTypeDependency(it, versionMap, dependenciesNode, groupId, providedCompiles)\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    repositories {\n        mavenLocal()\n        if (publishToRemote) {\n            if (version.endsWith(\"-SNAPSHOT\")) {\n                maven {\n                    url 'http://mvnrepo.alibaba-inc.com/nexus/content/repositories/snapshots'\n                    credentials {\n                        username = 'snapshotsAdmin'\n                        password = '123456'\n                    }\n                }\n            } else {\n                def accountMap = getAccount();\n//                maven {\n//                   url RELEASE_REPOSITORY_URL\n//                  credentials {\n//                       username = accountMap.get(\"username\")\n//                       password = accountMap.get(\"password\")\n//                   }\n//                }\n            }\n        }\n    }\n}\n\nprivate HashMap getAccount() {\n    HashMap<String, String> accountMap = new HashMap()\n    def parsedSettingsXml\n    def settingsFile = '/home/admin/software/apache-maven-3.2.1/conf/settings.xml'\n    def defaultSettingsFile = System.getProperty(\"user.home\") + \"/.m2/settings.xml\"\n\n    if (file(settingsFile).exists() || file(defaultSettingsFile).exists()) {\n        if (file(settingsFile).exists()) {\n            parsedSettingsXml = (new XmlParser()).parse(settingsFile);\n        } else if (file(defaultSettingsFile).exists()) {\n            parsedSettingsXml = (new XmlParser()).parse(defaultSettingsFile);\n        }\n\n        parsedSettingsXml.servers[0].server.each {server ->\n            if (\"releases\" == server.id.text()) {\n                accountMap.put(\"id\", server.id.text())\n                accountMap.put(\"username\", server.username.text())\n                accountMap.put(\"password\", server.password.text())\n            }\n        }\n    } else {\n        accountMap.put(\"id\", \"releases\")\n        accountMap.put(\"username\", \"admin\")\n        accountMap.put(\"password\", \"screct\")\n    }\n\n    return accountMap\n}\n\nprivate void updatePom(pom, versionMap, groupId) {\n    pom.withXml {\n        asNode().dependencies.'*'.each {\n            if (it.groupId.text() == \"\" || it.artifactId.text() == \"\" ){\n                it.parent().remove(it)\n                return\n            }\n            String key = it.groupId.text() + \":\" + it.artifactId.text();\n            String version = versionMap.get(key);\n            if (version) {\n                it.version*.value = version\n            }\n\n            if (project.configurations.providedCompile.allDependencies.find {dep -> dep.name == it.artifactId.text()}) {\n                it.scope*.value = 'provided'\n            } else if (project.configurations.compile.allDependencies.find {dep -> dep.name == it.artifactId.text()}) {\n                it.scope*.value = 'compile'\n            }\n\n            if (it.groupId.text() == groupId && project.getRootProject().aarMap.contains(it.artifactId.text())) {\n                //TODO\n                it.appendNode('type', 'aar')\n            }\n        }\n    }\n}\n\nprivate void appendBuildTypeDependency(it, versionMap, dependenciesNode, groupId) {\n    if (it.group != null && (it.name != null || \"unspecified\" == it.name) && it.version != null) {\n        def dependencyNode = dependenciesNode.appendNode('dependency')\n        dependencyNode.appendNode('groupId', it.group)\n        dependencyNode.appendNode('artifactId', it.name)\n        String version = versionMap.get(it.groupId.text() + \":\" + it.artifactId.text());\n        dependencyNode.appendNode('version', version ? version : it.version)\n        if (it.group == groupId && project.getRootProject().aarMap.contains(it.name)) {\n            dependencyNode.appendNode('type', 'aar')\n        }\n    }\n}\n\nprivate void addBuildTypeDependency(it, versionMap, dependenciesNode, groupId, providedCompiles , provided = false) {\n    if (it.group != null && (it.name != null || \"unspecified\" == it.name) && it.version != null) {\n        if (providedCompiles.contains(it.group + \".\" + it.name)) {\n            return\n        }\n        def dependencyNode = dependenciesNode.appendNode('dependency')\n        dependencyNode.appendNode('groupId', it.group)\n        dependencyNode.appendNode('artifactId', it.name)\n        String version = versionMap.get(it.group + \":\" + it.name);\n        dependencyNode.appendNode('version', version ? version : it.version)\n        dependencyNode.appendNode('scope', provided ? 'provided' : 'compile')\n        if (it.group == groupId && project.getRootProject().aarMap.contains(it.name)) {\n            dependencyNode.appendNode('type', 'aar')\n        }else{\n            Set types = it.artifacts;\n            if (types && types.size()>0){\n                dependencyNode.appendNode('type', types[0].type)\n            }\n        }\n        providedCompiles.add(it.group + \".\" + it.name)\n    }\n}"
  },
  {
    "path": "atlas-gradle-plugin/settings.gradle",
    "content": "include 'atlas-plugin'\n//include 'dexpatch'\n\n//include 'aapt'\n//include 'dexpatch'\nfindProject(':atlas-plugin')?.name = 'atlasplugin'\nfindProject(':dexpatch')?.name = 'dex_patch'\n//\n"
  },
  {
    "path": "atlas-update/README.md",
    "content": "## Feature\n\n1. Bundle dynamic update\n\n### Note\n\nUnlike hotpatch takes effect immediately, Atlas bundle update requires the user to restart the application after the patch installed.\n\n## Interface Api\n\ncom.taobao.atlas.update.AtlasUpdater#update\n\n1. Update interface\n\n\t\t/**\n\t\t * Update the main entrance\n\t\t * @param updateInfo  The basis information of update\n\t\t * @param patchFile   tpatch package\n\t\t * @throws MergeException\n\t\t * @throws BundleException\n\t\t */\n\t\tpublic static void update(UpdateInfo updateInfo, File patchFile) throws MergeException, BundleException\n\n2. The basis information of update  \n\n\t    /**\n\t     * the current version of the client\n\t     */\n\t    public String baseVersion;\n\t    /**\n\t     * the updated version of the client\n\t     */\n\t    public String updateVersion;\n\n\t    /**\n\t     * update module information list\n\t     */\n\t    public List<Item> updateBundles;\n\n\t    public File workDir = new File(RuntimeVariables.androidApplication.getCacheDir(), \"atlas_update\");\n\n\t    /**\n\t     * update module information\n\t     */\n\t    public static class Item implements Serializable {\n\t        /**\n\t         * is the main dex\n\t         */\n\t        public boolean isMainDex;\n\t        /**\n\t         * the name of the bundle\n\t         */\n\t        public String name;\n\t        /**\n\t         * the bundle version information\n\t         */\n\t        public String version;\n\t        /**\n\t         * git tag version of the bundle\n\t         */\n\t        public String srcVersion;\n\t        /**\n\t         * depend on the bundle list\n\t         */\n\t        public List<String> dependency;\n\t    }\n\n## Update process\n\n1. Unzip the patch package\n2. Merger patch of the original apk package and bundle (in a separate process)\n3. Install The combined new bundle\n4. Update the bundle list information\n5. Wait for the user starts to reload"
  },
  {
    "path": "atlas-update/README.zh-cn.md",
    "content": "## feature\n\n1. bundle的动态更新\n\n### 注意\n\natlas更新不像hotpatch的立即生效，而是需要用户在patch成功安装之后，重启应用才能生效\n\n## 接口Api\n\ncom.taobao.atlas.update.AtlasUpdater#update\n\n1. 更新的接口\n\n\t\t/**\n\t\t * 更新主入口\n\t\t * @param updateInfo  更新的基础信息\n\t\t * @param patchFile   tpatch包\n\t\t * @throws MergeException\n\t\t * @throws BundleException\n\t\t */\n\t\tpublic static void update(UpdateInfo updateInfo, File patchFile) throws MergeException, BundleException\n\n2. 更新的基础信息    \n\n\t    /**\n\t     * 当前的客户端版本\n\t     */\n\t    public String baseVersion;\n\t    /**\n\t     * 更新后的客户端版本\n\t     */\n\t    public String updateVersion;\n\n\t    /**\n\t     * 更新的模块列表信息\n\t     */\n\t    public List<Item> updateBundles;\n\n\t    public File workDir = new File(RuntimeVariables.androidApplication.getCacheDir(), \"atlas_update\");\n\n\t    /**\n\t     * 更新的模块信息\n\t     */\n\t    public static class Item implements Serializable {\n\t        /**\n\t         * 是不是主dex\n\t         */\n\t        public boolean isMainDex;\n\t        /**\n\t         * bundle 的名称\n\t         */\n\t        public String name;\n\t        /**\n\t         * bundle 版本信息\n\t         */\n\t        public String version;\n\t        /**\n\t         * bundle 的代码仓库对应的版本\n\t         */\n\t        public String srcVersion;\n\t        /**\n\t         * 依赖的 bundle 列表\n\t         */\n\t        public List<String> dependency;\n\t    }\n\n## 更新过程\n\n1. 解压patch包\n2. 合并patch包和原始apk中的bundle（在独立进程进行）\n3. 将合并后新的bundle进行重新的安装\n4. 更新bundle的列表信息\n5. 等待用户启动重新加载"
  },
  {
    "path": "atlas-update/build.gradle",
    "content": "buildscript {\n\n    repositories {\n        mavenLocal()\n        jcenter()\n    }\n    dependencies {\n        classpath \"com.android.tools.build:gradle:2.1.0\"\n        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'\n        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'\n    }\n}\n\ngroup = 'com.taobao.android'\n\nversion = '1.1.4.22-rc8'\n\n\n\napply plugin: 'com.android.library'\n//apply plugin: 'maven-publish'\napply plugin: 'com.github.dcendents.android-maven'\napply plugin: 'com.jfrog.bintray'\n//apply from: 'http://gitlab.alibaba-inc.com/android-build-system/buildscript/raw/master/mtl-publish.gradle'\n\n\nandroid {\n    compileSdkVersion 23\n    buildToolsVersion \"23.0.2\"\n    lintOptions {\n        checkReleaseBuilds false\n        abortOnError false\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_7\n        targetCompatibility JavaVersion.VERSION_1_7\n    }\n\n\n}\n\nrepositories {\n    mavenLocal()\n    jcenter()\n}\n\ndependencies {\n\n    compile 'com.taobao.android:atlas_core:5.1.0.9-rc2'\n    compile 'io.reactivex.rxjava2:rxjava:2.0.1'\n    compile 'org.reactivestreams:reactive-streams:1.0.0@jar'\n}\n\ndef siteUrl = 'https://github.com/alibaba/atlas'\n// 项目的主页\ndef gitUrl = 'https://github.com/alibaba/atlas'\n// Git仓库的url\ninstall {\n    repositories.mavenInstaller {\n        // This generates POM.xml with proper parameters\n        pom {\n            project {\n                packaging 'aar'\n                // Add your description here\n                name 'atlasupdate' //项目描述\n                // Set your license\n                licenses {\n                    license {\n                        name 'The Apache Software License, Version 2.0'\n                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'\n                    }\n                }\n                developers {\n                    developer {\n                        id 'alibabaatlas' //填写的一些基本信息\n                        name project.name\n                        email 'alibabaatlasframework@gmail.com'\n                    }\n                }\n                scm {\n                    connection gitUrl\n                    developerConnection gitUrl\n                    url siteUrl\n                }\n            }\n        }\n    }\n}\n\nProperties properties = new Properties()\nproperties.load(project.rootProject.file('local.properties').newDataInputStream())\nbintray {\n    user = properties.getProperty(\"bintray.user\")\n    key = properties.getProperty(\"bintray.apikey\")\n\n    // publications = ['mavenJava']\n   configurations = ['archives']\n    // publications = ['maven']\n    pkg {\n        repo = \"maven\"\n        name = project.name\t//发布到JCenter上的项目名字\n        websiteUrl = \"atlas.alibaba.net\"\n        vcsUrl = gitUrl\n        licenses = [\"Apache-2.0\"]\n        publish = true\n    }\n}\n\ntask sourcesJar(type: Jar) {\n    from('src/main/java') {\n        include '**'\n    }\n    classifier = 'sources'\n}\n\nartifacts {\n    archives sourcesJar\n}\n"
  },
  {
    "path": "atlas-update/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Thu Sep 01 11:00:49 CST 2016\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-2.14.1-all.zip\n"
  },
  {
    "path": "atlas-update/gradle.properties",
    "content": "android.useDeprecatedNdk=true"
  },
  {
    "path": "atlas-update/gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "atlas-update/settings.gradle",
    "content": "rootProject.name = \"atlasupdate\"\n"
  },
  {
    "path": "atlas-update/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.taobao.atlas.update\">\n\n    <uses-sdk\n        android:minSdkVersion=\"14\"\n        android:targetSdkVersion=\"23\" />\n\n    <application>\n        <service\n            android:name=\"com.taobao.atlas.dexmerge.DexMergeService\"\n            android:process=\":dexmerge\">\n            <intent-filter>\n                <action android:name=\"com.taobao.atlas.dexmerge.DexMergeService\"></action>\n            </intent-filter>\n        </service>\n        <receiver android:name=\"com.taobao.atlas.update.AwoPatchReceiver\" >\n        <intent-filter>\n        <action android:name=\"com.taobao.atlas.intent.PATCH_APP\"/>\n        </intent-filter>\n        <intent-filter>\n        <action android:name=\"com.taobao.atlas.intent.DEX_PATCH_APP\"/>\n        </intent-filter>\n        <intent-filter>\n        <action android:name=\"com.taobao.atlas.intent.ROLLBACK_PATCH\"/>\n        </intent-filter>\n        <intent-filter>\n        <action android:name=\"com.taobao.atlas.intent.ROLLBACK_DEX_PATCH\"/>\n        </intent-filter>\n        </receiver>\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/MainThreadDisposable.java",
    "content": "package com.taobao;\n\nimport android.os.Looper;\nimport com.taobao.schedulers.AndroidSchedulers;\nimport io.reactivex.disposables.Disposable;\n\nimport java.util.concurrent.atomic.AtomicBoolean;\n\n/**\n * @author lilong\n * @create 2017-06-05 上午9:53\n */\n\npublic abstract class MainThreadDisposable implements Disposable {\n    /**\n     * Verify that the calling thread is the Android main thread.\n     * <p>\n     * Calls to this method are usually preconditions for subscription behavior which instances of\n     * this class later undo. See the class documentation for an example.\n     *\n     * @throws IllegalStateException when called from any other thread.\n     */\n    public static void verifyMainThread() {\n        if (Looper.myLooper() != Looper.getMainLooper()) {\n            throw new IllegalStateException(\n                    \"Expected to be called on the main thread but was \" + Thread.currentThread().getName());\n        }\n    }\n\n    private final AtomicBoolean unsubscribed = new AtomicBoolean();\n\n    @Override\n    public final boolean isDisposed() {\n        return unsubscribed.get();\n    }\n\n    @Override\n    public final void dispose() {\n        if (unsubscribed.compareAndSet(false, true)) {\n            if (Looper.myLooper() == Looper.getMainLooper()) {\n                onDispose();\n            } else {\n                AndroidSchedulers.mainThread().scheduleDirect(new Runnable() {\n                    @Override public void run() {\n                        onDispose();\n                    }\n                });\n            }\n        }\n    }\n\n    protected abstract void onDispose();\n}\n\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/Annotation.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\nimport static com.taobao.atlas.dex.EncodedValueReader.ENCODED_ANNOTATION;\n\n/**\n * An annotation.\n */\npublic final class Annotation implements Comparable<Annotation> {\n    private final Dex dex;\n    private final byte visibility;\n    private final EncodedValue encodedAnnotation;\n\n    public Annotation(Dex dex, byte visibility, EncodedValue encodedAnnotation) {\n        this.dex = dex;\n        this.visibility = visibility;\n        this.encodedAnnotation = encodedAnnotation;\n    }\n\n    public byte getVisibility() {\n        return visibility;\n    }\n\n    public EncodedValueReader getReader() {\n        return new EncodedValueReader(encodedAnnotation, ENCODED_ANNOTATION);\n    }\n\n    public int getTypeIndex() {\n        EncodedValueReader reader = getReader();\n        reader.readAnnotation();\n        return reader.getAnnotationType();\n    }\n\n    public void writeTo(Dex.Section out) {\n        out.writeByte(visibility);\n        encodedAnnotation.writeTo(out);\n    }\n\n    @Override public int compareTo(Annotation other) {\n        return encodedAnnotation.compareTo(other.encodedAnnotation);\n    }\n\n    @Override public String toString() {\n        return dex == null\n                ? visibility + \" \" + getTypeIndex()\n                : visibility + \" \" + dex.typeNames().get(getTypeIndex());\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/ClassData.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\npublic final class ClassData {\n    private final Field[] staticFields;\n    private final Field[] instanceFields;\n    private final Method[] directMethods;\n    private final Method[] virtualMethods;\n\n    public ClassData(Field[] staticFields, Field[] instanceFields,\n            Method[] directMethods, Method[] virtualMethods) {\n        this.staticFields = staticFields;\n        this.instanceFields = instanceFields;\n        this.directMethods = directMethods;\n        this.virtualMethods = virtualMethods;\n    }\n\n    public Field[] getStaticFields() {\n        return staticFields;\n    }\n\n    public Field[] getInstanceFields() {\n        return instanceFields;\n    }\n\n    public Method[] getDirectMethods() {\n        return directMethods;\n    }\n\n    public Method[] getVirtualMethods() {\n        return virtualMethods;\n    }\n\n    public Field[] allFields() {\n        Field[] result = new Field[staticFields.length + instanceFields.length];\n        System.arraycopy(staticFields, 0, result, 0, staticFields.length);\n        System.arraycopy(instanceFields, 0, result, staticFields.length, instanceFields.length);\n        return result;\n    }\n\n    public Method[] allMethods() {\n        Method[] result = new Method[directMethods.length + virtualMethods.length];\n        System.arraycopy(directMethods, 0, result, 0, directMethods.length);\n        System.arraycopy(virtualMethods, 0, result, directMethods.length, virtualMethods.length);\n        return result;\n    }\n\n    public static class Field {\n        private final int fieldIndex;\n        private final int accessFlags;\n\n        public Field(int fieldIndex, int accessFlags) {\n            this.fieldIndex = fieldIndex;\n            this.accessFlags = accessFlags;\n        }\n\n        public int getFieldIndex() {\n            return fieldIndex;\n        }\n\n        public int getAccessFlags() {\n            return accessFlags;\n        }\n    }\n\n    public static class Method {\n        private final int methodIndex;\n        private final int accessFlags;\n        private final int codeOffset;\n\n        public Method(int methodIndex, int accessFlags, int codeOffset) {\n            this.methodIndex = methodIndex;\n            this.accessFlags = accessFlags;\n            this.codeOffset = codeOffset;\n        }\n\n        public int getMethodIndex() {\n            return methodIndex;\n        }\n\n        public int getAccessFlags() {\n            return accessFlags;\n        }\n\n        public int getCodeOffset() {\n            return codeOffset;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/ClassDef.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\n/**\n * A type definition.\n */\npublic final class ClassDef {\n    public static final int NO_INDEX = -1;\n    private final Dex buffer;\n    private final int offset;\n    private final int typeIndex;\n    private final int accessFlags;\n    private final int supertypeIndex;\n    private final int interfacesOffset;\n    private final int sourceFileIndex;\n    private final int annotationsOffset;\n    private final int classDataOffset;\n    private final int staticValuesOffset;\n\n    public ClassDef(Dex buffer, int offset, int typeIndex, int accessFlags,\n            int supertypeIndex, int interfacesOffset, int sourceFileIndex,\n            int annotationsOffset, int classDataOffset, int staticValuesOffset) {\n        this.buffer = buffer;\n        this.offset = offset;\n        this.typeIndex = typeIndex;\n        this.accessFlags = accessFlags;\n        this.supertypeIndex = supertypeIndex;\n        this.interfacesOffset = interfacesOffset;\n        this.sourceFileIndex = sourceFileIndex;\n        this.annotationsOffset = annotationsOffset;\n        this.classDataOffset = classDataOffset;\n        this.staticValuesOffset = staticValuesOffset;\n    }\n\n    public int getOffset() {\n        return offset;\n    }\n\n    public int getTypeIndex() {\n        return typeIndex;\n    }\n\n    public int getSupertypeIndex() {\n        return supertypeIndex;\n    }\n\n    public int getInterfacesOffset() {\n        return interfacesOffset;\n    }\n\n    public short[] getInterfaces() {\n        return buffer.readTypeList(interfacesOffset).getTypes();\n    }\n\n    public int getAccessFlags() {\n        return accessFlags;\n    }\n\n    public int getSourceFileIndex() {\n        return sourceFileIndex;\n    }\n\n    public int getAnnotationsOffset() {\n        return annotationsOffset;\n    }\n\n    public int getClassDataOffset() {\n        return classDataOffset;\n    }\n\n    public int getStaticValuesOffset() {\n        return staticValuesOffset;\n    }\n\n    @Override public String toString() {\n        if (buffer == null) {\n            return typeIndex + \" \" + supertypeIndex;\n        }\n\n        StringBuilder result = new StringBuilder();\n        result.append(buffer.typeNames().get(typeIndex));\n        if (supertypeIndex != NO_INDEX) {\n            result.append(\" extends \").append(buffer.typeNames().get(supertypeIndex));\n        }\n        return result.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/Code.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\npublic final class Code {\n    private final int registersSize;\n    private final int insSize;\n    private final int outsSize;\n    private final int debugInfoOffset;\n    private final short[] instructions;\n    private final Try[] tries;\n    private final CatchHandler[] catchHandlers;\n\n    public Code(int registersSize, int insSize, int outsSize, int debugInfoOffset,\n            short[] instructions, Try[] tries, CatchHandler[] catchHandlers) {\n        this.registersSize = registersSize;\n        this.insSize = insSize;\n        this.outsSize = outsSize;\n        this.debugInfoOffset = debugInfoOffset;\n        this.instructions = instructions;\n        this.tries = tries;\n        this.catchHandlers = catchHandlers;\n    }\n\n    public int getRegistersSize() {\n        return registersSize;\n    }\n\n    public int getInsSize() {\n        return insSize;\n    }\n\n    public int getOutsSize() {\n        return outsSize;\n    }\n\n    public int getDebugInfoOffset() {\n        return debugInfoOffset;\n    }\n\n    public short[] getInstructions() {\n        return instructions;\n    }\n\n    public Try[] getTries() {\n        return tries;\n    }\n\n    public CatchHandler[] getCatchHandlers() {\n        return catchHandlers;\n    }\n\n    public static class Try {\n        final int startAddress;\n        final int instructionCount;\n        final int catchHandlerIndex;\n\n        Try(int startAddress, int instructionCount, int catchHandlerIndex) {\n            this.startAddress = startAddress;\n            this.instructionCount = instructionCount;\n            this.catchHandlerIndex = catchHandlerIndex;\n        }\n\n        public int getStartAddress() {\n            return startAddress;\n        }\n\n        public int getInstructionCount() {\n            return instructionCount;\n        }\n\n        /**\n         * Returns this try's catch handler <strong>index</strong>. Note that\n         * this is distinct from the its catch handler <strong>offset</strong>.\n         */\n        public int getCatchHandlerIndex() {\n            return catchHandlerIndex;\n        }\n    }\n\n    public static class CatchHandler {\n        final int[] typeIndexes;\n        final int[] addresses;\n        final int catchAllAddress;\n        final int offset;\n\n        public CatchHandler(int[] typeIndexes, int[] addresses, int catchAllAddress, int offset) {\n            this.typeIndexes = typeIndexes;\n            this.addresses = addresses;\n            this.catchAllAddress = catchAllAddress;\n            this.offset = offset;\n        }\n\n        public int[] getTypeIndexes() {\n            return typeIndexes;\n        }\n\n        public int[] getAddresses() {\n            return addresses;\n        }\n\n        public int getCatchAllAddress() {\n            return catchAllAddress;\n        }\n\n        public int getOffset() {\n            return offset;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/Dex.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\nimport com.taobao.atlas.dex.Code.CatchHandler;\nimport com.taobao.atlas.dex.Code.Try;\nimport com.taobao.atlas.dex.util.ByteInput;\nimport com.taobao.atlas.dex.util.ByteOutput;\nimport com.taobao.atlas.dex.util.FileUtils;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.io.UTFDataFormatException;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\nimport java.util.AbstractList;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.NoSuchElementException;\nimport java.util.RandomAccess;\nimport java.util.zip.Adler32;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n/**\n * The bytes of a dex file in memory for reading and writing. All int offsets\n * are unsigned.\n */\npublic final class Dex {\n\n    private static final int                      CHECKSUM_OFFSET   = 8;\n    private static final int                      CHECKSUM_SIZE     = 4;\n    private static final int                      SIGNATURE_OFFSET  = CHECKSUM_OFFSET + CHECKSUM_SIZE;\n    private static final int                      SIGNATURE_SIZE    = 20;\n    // Provided as a convenience to avoid a memory allocation to benefit Dalvik.\n    // Note: libcore.util.EmptyArray cannot be accessed when this code isn't run on Dalvik.\n    static final short[]                          EMPTY_SHORT_ARRAY = new short[0];\n\n    private ByteBuffer                            data;\n    private final TableOfContents                 tableOfContents   = new TableOfContents();\n    private int                                   nextSectionStart  = 0;\n    private final StringTable                     strings           = new StringTable();\n    private final TypeIndexToDescriptorIndexTable typeIds           = new TypeIndexToDescriptorIndexTable();\n    private final TypeIndexToDescriptorTable      typeNames         = new TypeIndexToDescriptorTable();\n    private final ProtoIdTable                    protoIds          = new ProtoIdTable();\n    private final FieldIdTable                    fieldIds          = new FieldIdTable();\n    private final MethodIdTable                   methodIds         = new MethodIdTable();\n\n    /**\n     * Creates a new dex that reads from {@code data}. It is an error to modify\n     * {@code data} after using it to create a dex buffer.\n     */\n    public Dex(byte[] data) throws IOException{\n        this(ByteBuffer.wrap(data));\n    }\n\n    private Dex(ByteBuffer data) throws IOException{\n        this.data = data;\n        this.data.order(ByteOrder.LITTLE_ENDIAN);\n        this.tableOfContents.readFrom(this);\n    }\n\n    /**\n     * Creates a new empty dex of the specified size.\n     */\n    public Dex(int byteCount) throws IOException{\n        this.data = ByteBuffer.wrap(new byte[byteCount]);\n        this.data.order(ByteOrder.LITTLE_ENDIAN);\n    }\n\n    /**\n     * Creates a new dex buffer of the dex in {@code in}, and closes {@code in}.\n     */\n    public Dex(InputStream in) throws IOException{\n        try {\n            loadFrom(in);\n        } finally {\n            in.close();\n        }\n    }\n\n    /**\n     * Creates a new dex buffer from the dex file {@code file}.\n     */\n    public Dex(File file) throws IOException{\n        if (FileUtils.hasArchiveSuffix(file.getName())) {\n            ZipFile zipFile = new ZipFile(file);\n            ZipEntry entry = zipFile.getEntry(DexFormat.DEX_IN_JAR_NAME);\n            if (entry != null) {\n                loadFrom(zipFile.getInputStream(entry));\n                zipFile.close();\n            } else {\n                throw new DexException2(\"Expected \" + DexFormat.DEX_IN_JAR_NAME + \" in \" + file);\n            }\n        } else if (file.getName().endsWith(\".dex\")) {\n            loadFrom(new FileInputStream(file));\n        } else {\n            throw new DexException2(\"unknown output extension: \" + file);\n        }\n    }\n\n    /**\n     * Creates a new dex from the contents of {@code bytes}. This API supports\n     * both {@code .dex} and {@code .odex} input. Calling this constructor\n     * transfers ownership of {@code bytes} to the returned Dex: it is an error\n     * to access the buffer after calling this method.\n     */\n    public static Dex create(ByteBuffer data) throws IOException {\n        data.order(ByteOrder.LITTLE_ENDIAN);\n\n        // if it's an .odex file, set position and limit to the .dex section\n        if (data.get(0) == 'd' && data.get(1) == 'e' && data.get(2) == 'y' && data.get(3) == '\\n') {\n            data.position(8);\n            int offset = data.getInt();\n            int length = data.getInt();\n            data.position(offset);\n            data.limit(offset + length);\n            data = data.slice();\n        }\n\n        return new Dex(data);\n    }\n\n    /**\n     * It is the caller's responsibility to close {@code in}.\n     */\n    private void loadFrom(InputStream in) throws IOException {\n        ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();\n        byte[] buffer = new byte[8192];\n\n        int count;\n        while ((count = in.read(buffer)) != -1) {\n            bytesOut.write(buffer, 0, count);\n        }\n\n        this.data = ByteBuffer.wrap(bytesOut.toByteArray());\n        this.data.order(ByteOrder.LITTLE_ENDIAN);\n        this.tableOfContents.readFrom(this);\n    }\n\n    private static void checkBounds(int index, int length) {\n        if (index < 0 || index >= length) {\n            throw new IndexOutOfBoundsException(\"index:\" + index + \", length=\" + length);\n        }\n    }\n\n    public void writeTo(OutputStream out) throws IOException {\n        byte[] buffer = new byte[8192];\n        ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe\n        data.clear();\n        while (data.hasRemaining()) {\n            int count = Math.min(buffer.length, data.remaining());\n            data.get(buffer, 0, count);\n            out.write(buffer, 0, count);\n        }\n    }\n\n    public void writeTo(File dexOut) throws IOException {\n        OutputStream out = new FileOutputStream(dexOut);\n        writeTo(out);\n        out.close();\n    }\n\n    public TableOfContents getTableOfContents() {\n        return tableOfContents;\n    }\n\n    public Section open(int position) {\n        if (position < 0 || position >= data.capacity()) {\n            throw new IllegalArgumentException(\"position=\" + position + \" length=\" + data.capacity());\n        }\n        ByteBuffer sectionData = data.duplicate();\n        sectionData.order(ByteOrder.LITTLE_ENDIAN); // necessary?\n        sectionData.position(position);\n        sectionData.limit(data.capacity());\n        return new Section(\"section\", sectionData);\n    }\n\n    public Section appendSection(int maxByteCount, String name) {\n        if ((maxByteCount & 3) != 0) {\n            throw new IllegalStateException(\"Not four byte aligned!\");\n        }\n        int limit = nextSectionStart + maxByteCount;\n        ByteBuffer sectionData = data.duplicate();\n        sectionData.order(ByteOrder.LITTLE_ENDIAN); // necessary?\n        sectionData.position(nextSectionStart);\n        sectionData.limit(limit);\n        Section result = new Section(name, sectionData);\n        nextSectionStart = limit;\n        return result;\n    }\n\n    public int getLength() {\n        return data.capacity();\n    }\n\n    public int getNextSectionStart() {\n        return nextSectionStart;\n    }\n\n    /**\n     * Returns a copy of the the bytes of this dex.\n     */\n    public byte[] getBytes() {\n        ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe\n        byte[] result = new byte[data.capacity()];\n        data.position(0);\n        data.get(result);\n        return result;\n    }\n\n    public List<String> strings() {\n        return strings;\n    }\n\n    public List<Integer> typeIds() {\n        return typeIds;\n    }\n\n    public List<String> typeNames() {\n        return typeNames;\n    }\n\n    public List<ProtoId> protoIds() {\n        return protoIds;\n    }\n\n    public List<FieldId> fieldIds() {\n        return fieldIds;\n    }\n\n    public List<MethodId> methodIds() {\n        return methodIds;\n    }\n\n    public Iterable<ClassDef> classDefs() {\n        return new ClassDefIterable();\n    }\n\n    public TypeList readTypeList(int offset) {\n        if (offset == 0) {\n            return TypeList.EMPTY;\n        }\n        return open(offset).readTypeList();\n    }\n\n    public ClassData readClassData(ClassDef classDef) {\n        int offset = classDef.getClassDataOffset();\n        if (offset == 0) {\n            throw new IllegalArgumentException(\"offset == 0\");\n        }\n        return open(offset).readClassData();\n    }\n\n    public Code readCode(ClassData.Method method) {\n        int offset = method.getCodeOffset();\n        if (offset == 0) {\n            throw new IllegalArgumentException(\"offset == 0\");\n        }\n        return open(offset).readCode();\n    }\n\n    /**\n     * Returns the signature of all but the first 32 bytes of this dex. The\n     * first 32 bytes of dex files are not specified to be included in the\n     * signature.\n     */\n    public byte[] computeSignature() throws IOException {\n        MessageDigest digest;\n        try {\n            digest = MessageDigest.getInstance(\"SHA-1\");\n        } catch (NoSuchAlgorithmException e) {\n            throw new AssertionError();\n        }\n        byte[] buffer = new byte[8192];\n        ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe\n        data.limit(data.capacity());\n        data.position(SIGNATURE_OFFSET + SIGNATURE_SIZE);\n        while (data.hasRemaining()) {\n            int count = Math.min(buffer.length, data.remaining());\n            data.get(buffer, 0, count);\n            digest.update(buffer, 0, count);\n        }\n        return digest.digest();\n    }\n\n    /**\n     * Returns the checksum of all but the first 12 bytes of {@code dex}.\n     */\n    public int computeChecksum() throws IOException {\n        Adler32 adler32 = new Adler32();\n        byte[] buffer = new byte[8192];\n        ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe\n        data.limit(data.capacity());\n        data.position(CHECKSUM_OFFSET + CHECKSUM_SIZE);\n        while (data.hasRemaining()) {\n            int count = Math.min(buffer.length, data.remaining());\n            data.get(buffer, 0, count);\n            adler32.update(buffer, 0, count);\n        }\n        return (int) adler32.getValue();\n    }\n\n    /**\n     * Generates the signature and checksum of the dex file {@code out} and\n     * writes them to the file.\n     */\n    public void writeHashes() throws IOException {\n        open(SIGNATURE_OFFSET).write(computeSignature());\n        open(CHECKSUM_OFFSET).writeInt(computeChecksum());\n    }\n\n    /**\n     * Look up a field id name index from a field index. Cheaper than:\n     * {@code fieldIds().get(fieldDexIndex).getNameIndex();}\n     */\n    public int nameIndexFromFieldIndex(int fieldIndex) {\n        checkBounds(fieldIndex, tableOfContents.fieldIds.size);\n        int position = tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * fieldIndex);\n        position += SizeOf.USHORT; // declaringClassIndex\n        position += SizeOf.USHORT; // typeIndex\n        return data.getInt(position); // nameIndex\n    }\n\n    public int findStringIndex(String s) {\n        return Collections.binarySearch(strings, s);\n    }\n\n    public int findTypeIndex(String descriptor) {\n        return Collections.binarySearch(typeNames, descriptor);\n    }\n\n    public int findFieldIndex(FieldId fieldId) {\n        return Collections.binarySearch(fieldIds, fieldId);\n    }\n\n    public int findMethodIndex(MethodId methodId) {\n        return Collections.binarySearch(methodIds, methodId);\n    }\n\n    public int findClassDefIndexFromTypeIndex(int typeIndex) {\n        checkBounds(typeIndex, tableOfContents.typeIds.size);\n        if (!tableOfContents.classDefs.exists()) {\n            return -1;\n        }\n        for (int i = 0; i < tableOfContents.classDefs.size; i++) {\n            if (typeIndexFromClassDefIndex(i) == typeIndex) {\n                return i;\n            }\n        }\n        return -1;\n    }\n\n    /**\n     * Look up a field id type index from a field index. Cheaper than:\n     * {@code fieldIds().get(fieldDexIndex).getTypeIndex();}\n     */\n    public int typeIndexFromFieldIndex(int fieldIndex) {\n        checkBounds(fieldIndex, tableOfContents.fieldIds.size);\n        int position = tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * fieldIndex);\n        position += SizeOf.USHORT; // declaringClassIndex\n        return data.getShort(position) & 0xFFFF; // typeIndex\n    }\n\n    /**\n     * Look up a method id declaring class index from a method index. Cheaper than:\n     * {@code methodIds().get(methodIndex).getDeclaringClassIndex();}\n     */\n    public int declaringClassIndexFromMethodIndex(int methodIndex) {\n        checkBounds(methodIndex, tableOfContents.methodIds.size);\n        int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);\n        return data.getShort(position) & 0xFFFF; // declaringClassIndex\n    }\n\n    /**\n     * Look up a method id name index from a method index. Cheaper than:\n     * {@code methodIds().get(methodIndex).getNameIndex();}\n     */\n    public int nameIndexFromMethodIndex(int methodIndex) {\n        checkBounds(methodIndex, tableOfContents.methodIds.size);\n        int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);\n        position += SizeOf.USHORT; // declaringClassIndex\n        position += SizeOf.USHORT; // protoIndex\n        return data.getInt(position); // nameIndex\n    }\n\n    /**\n     * Look up a parameter type ids from a method index. Cheaper than:\n     * {@code readTypeList(protoIds.get(methodIds().get(methodDexIndex).getProtoIndex()).getParametersOffset()).getTypes();}\n     */\n    public short[] parameterTypeIndicesFromMethodIndex(int methodIndex) {\n        checkBounds(methodIndex, tableOfContents.methodIds.size);\n        int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);\n        position += SizeOf.USHORT; // declaringClassIndex\n        int protoIndex = data.getShort(position) & 0xFFFF;\n        checkBounds(protoIndex, tableOfContents.protoIds.size);\n        position = tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * protoIndex);\n        position += SizeOf.UINT; // shortyIndex\n        position += SizeOf.UINT; // returnTypeIndex\n        int parametersOffset = data.getInt(position);\n        if (parametersOffset == 0) {\n            return EMPTY_SHORT_ARRAY;\n        }\n        position = parametersOffset;\n        int size = data.getInt(position);\n        if (size <= 0) {\n            throw new AssertionError(\"Unexpected parameter type list size: \" + size);\n        }\n        position += SizeOf.UINT;\n        short[] types = new short[size];\n        for (int i = 0; i < size; i++) {\n            types[i] = data.getShort(position);\n            position += SizeOf.USHORT;\n        }\n        return types;\n    }\n\n    /**\n     * Look up a method id return type index from a method index. Cheaper than:\n     * {@code protoIds().get(methodIds().get(methodDexIndex).getProtoIndex()).getReturnTypeIndex();}\n     */\n    public int returnTypeIndexFromMethodIndex(int methodIndex) {\n        checkBounds(methodIndex, tableOfContents.methodIds.size);\n        int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);\n        position += SizeOf.USHORT; // declaringClassIndex\n        int protoIndex = data.getShort(position) & 0xFFFF;\n        checkBounds(protoIndex, tableOfContents.protoIds.size);\n        position = tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * protoIndex);\n        position += SizeOf.UINT; // shortyIndex\n        return data.getInt(position); // returnTypeIndex\n    }\n\n    /**\n     * Look up a descriptor index from a type index. Cheaper than:\n     * {@code open(tableOfContents.typeIds.off + (index * SizeOf.TYPE_ID_ITEM)).readInt();}\n     */\n    public int descriptorIndexFromTypeIndex(int typeIndex) {\n        checkBounds(typeIndex, tableOfContents.typeIds.size);\n        int position = tableOfContents.typeIds.off + (SizeOf.TYPE_ID_ITEM * typeIndex);\n        return data.getInt(position);\n    }\n\n    /**\n     * Look up a type index index from a class def index.\n     */\n    public int typeIndexFromClassDefIndex(int classDefIndex) {\n        checkBounds(classDefIndex, tableOfContents.classDefs.size);\n        int position = tableOfContents.classDefs.off + (SizeOf.CLASS_DEF_ITEM * classDefIndex);\n        return data.getInt(position);\n    }\n\n    /**\n     * Look up an annotation directory offset from a class def index.\n     */\n    public int annotationDirectoryOffsetFromClassDefIndex(int classDefIndex) {\n        checkBounds(classDefIndex, tableOfContents.classDefs.size);\n        int position = tableOfContents.classDefs.off + (SizeOf.CLASS_DEF_ITEM * classDefIndex);\n        position += SizeOf.UINT; // type\n        position += SizeOf.UINT; // accessFlags\n        position += SizeOf.UINT; // superType\n        position += SizeOf.UINT; // interfacesOffset\n        position += SizeOf.UINT; // sourceFileIndex\n        return data.getInt(position);\n    }\n\n    /**\n     * Look up interface types indices from a  return type index from a method index. Cheaper than:\n     * {@code ...getClassDef(classDefIndex).getInterfaces();}\n     */\n    public short[] interfaceTypeIndicesFromClassDefIndex(int classDefIndex) {\n        checkBounds(classDefIndex, tableOfContents.classDefs.size);\n        int position = tableOfContents.classDefs.off + (SizeOf.CLASS_DEF_ITEM * classDefIndex);\n        position += SizeOf.UINT; // type\n        position += SizeOf.UINT; // accessFlags\n        position += SizeOf.UINT; // superType\n        int interfacesOffset = data.getInt(position);\n        if (interfacesOffset == 0) {\n            return EMPTY_SHORT_ARRAY;\n        }\n        position = interfacesOffset;\n        int size = data.getInt(position);\n        if (size <= 0) {\n            throw new AssertionError(\"Unexpected interfaces list size: \" + size);\n        }\n        position += SizeOf.UINT;\n        short[] types = new short[size];\n        for (int i = 0; i < size; i++) {\n            types[i] = data.getShort(position);\n            position += SizeOf.USHORT;\n        }\n        return types;\n    }\n\n    public final class Section implements ByteInput, ByteOutput {\n\n        private final String     name;\n        private final ByteBuffer data;\n        private final int        initialPosition;\n\n        private Section(String name, ByteBuffer data){\n            this.name = name;\n            this.data = data;\n            this.initialPosition = data.position();\n        }\n\n        public ByteBuffer getData() {\n            return data;\n        }\n\n        public int getPosition() {\n            return data.position();\n        }\n\n        public int readInt() {\n            return data.getInt();\n        }\n\n        public short readShort() {\n            return data.getShort();\n        }\n\n        public int readUnsignedShort() {\n            return readShort() & 0xffff;\n        }\n\n        public byte readByte() {\n            return data.get();\n        }\n\n        public byte[] readByteArray(int length) {\n            byte[] result = new byte[length];\n            data.get(result);\n            return result;\n        }\n\n        public short[] readShortArray(int length) {\n            if (length == 0) {\n                return EMPTY_SHORT_ARRAY;\n            }\n            short[] result = new short[length];\n            for (int i = 0; i < length; i++) {\n                result[i] = readShort();\n            }\n            return result;\n        }\n\n        public int readUleb128() {\n            return Leb128.readUnsignedLeb128(this);\n        }\n\n        public int readUleb128p1() {\n            return Leb128.readUnsignedLeb128(this) - 1;\n        }\n\n        public int readSleb128() {\n            return Leb128.readSignedLeb128(this);\n        }\n\n        public void writeUleb128p1(int i) {\n            writeUleb128(i + 1);\n        }\n\n        public TypeList readTypeList() {\n            int size = readInt();\n            short[] types = readShortArray(size);\n            alignToFourBytes();\n            return new TypeList(Dex.this, types);\n        }\n\n        public String readString() {\n            int offset = readInt();\n            int savedPosition = data.position();\n            int savedLimit = data.limit();\n            data.position(offset);\n            data.limit(data.capacity());\n            try {\n                int expectedLength = readUleb128();\n                String result = Mutf8.decode(this, new char[expectedLength]);\n                if (result.length() != expectedLength) {\n                    throw new DexException2(\"Declared length \" + expectedLength + \" doesn't match decoded length of \"\n                            + result.length());\n                }\n                return result;\n            } catch (UTFDataFormatException e) {\n                throw new DexException2(e);\n            } finally {\n                data.position(savedPosition);\n                data.limit(savedLimit);\n            }\n        }\n\n        public FieldId readFieldId() {\n            int declaringClassIndex = readUnsignedShort();\n            int typeIndex = readUnsignedShort();\n            int nameIndex = readInt();\n            return new FieldId(Dex.this, declaringClassIndex, typeIndex, nameIndex);\n        }\n\n        public MethodId readMethodId() {\n            int declaringClassIndex = readUnsignedShort();\n            int protoIndex = readUnsignedShort();\n            int nameIndex = readInt();\n            return new MethodId(Dex.this, declaringClassIndex, protoIndex, nameIndex);\n        }\n\n        public ProtoId readProtoId() {\n            int shortyIndex = readInt();\n            int returnTypeIndex = readInt();\n            int parametersOffset = readInt();\n            return new ProtoId(Dex.this, shortyIndex, returnTypeIndex, parametersOffset);\n        }\n\n        public ClassDef readClassDef() {\n            int offset = getPosition();\n            int type = readInt();\n            int accessFlags = readInt();\n            int supertype = readInt();\n            int interfacesOffset = readInt();\n            int sourceFileIndex = readInt();\n            int annotationsOffset = readInt();\n            int classDataOffset = readInt();\n            int staticValuesOffset = readInt();\n            return new ClassDef(Dex.this, offset, type, accessFlags, supertype, interfacesOffset, sourceFileIndex,\n                    annotationsOffset, classDataOffset, staticValuesOffset);\n        }\n\n        private Code readCode() {\n            int registersSize = readUnsignedShort();\n            int insSize = readUnsignedShort();\n            int outsSize = readUnsignedShort();\n            int triesSize = readUnsignedShort();\n            int debugInfoOffset = readInt();\n            int instructionsSize = readInt();\n            short[] instructions = readShortArray(instructionsSize);\n            Try[] tries;\n            CatchHandler[] catchHandlers;\n            if (triesSize > 0) {\n                if (instructions.length % 2 == 1) {\n                    readShort(); // padding\n                }\n\n                /*\n                 * We can't read the tries until we've read the catch handlers.\n                 * Unfortunately they're in the opposite order in the dex file\n                 * so we need to read them out-of-order.\n                 */\n                Section triesSection = open(data.position());\n                skip(triesSize * SizeOf.TRY_ITEM);\n                catchHandlers = readCatchHandlers();\n                tries = triesSection.readTries(triesSize, catchHandlers);\n            } else {\n                tries = new Try[0];\n                catchHandlers = new CatchHandler[0];\n            }\n            return new Code(registersSize, insSize, outsSize, debugInfoOffset, instructions, tries, catchHandlers);\n        }\n\n        private CatchHandler[] readCatchHandlers() {\n            int baseOffset = data.position();\n            int catchHandlersSize = readUleb128();\n            CatchHandler[] result = new CatchHandler[catchHandlersSize];\n            for (int i = 0; i < catchHandlersSize; i++) {\n                int offset = data.position() - baseOffset;\n                result[i] = readCatchHandler(offset);\n            }\n            return result;\n        }\n\n        private Try[] readTries(int triesSize, CatchHandler[] catchHandlers) {\n            Try[] result = new Try[triesSize];\n            for (int i = 0; i < triesSize; i++) {\n                int startAddress = readInt();\n                int instructionCount = readUnsignedShort();\n                int handlerOffset = readUnsignedShort();\n                int catchHandlerIndex = findCatchHandlerIndex(catchHandlers, handlerOffset);\n                result[i] = new Try(startAddress, instructionCount, catchHandlerIndex);\n            }\n            return result;\n        }\n\n        private int findCatchHandlerIndex(CatchHandler[] catchHandlers, int offset) {\n            for (int i = 0; i < catchHandlers.length; i++) {\n                CatchHandler catchHandler = catchHandlers[i];\n                if (catchHandler.getOffset() == offset) {\n                    return i;\n                }\n            }\n            throw new IllegalArgumentException();\n        }\n\n        private CatchHandler readCatchHandler(int offset) {\n            int size = readSleb128();\n            int handlersCount = Math.abs(size);\n            int[] typeIndexes = new int[handlersCount];\n            int[] addresses = new int[handlersCount];\n            for (int i = 0; i < handlersCount; i++) {\n                typeIndexes[i] = readUleb128();\n                addresses[i] = readUleb128();\n            }\n            int catchAllAddress = size <= 0 ? readUleb128() : -1;\n            return new CatchHandler(typeIndexes, addresses, catchAllAddress, offset);\n        }\n\n        private ClassData readClassData() {\n            int staticFieldsSize = readUleb128();\n            int instanceFieldsSize = readUleb128();\n            int directMethodsSize = readUleb128();\n            int virtualMethodsSize = readUleb128();\n            ClassData.Field[] staticFields = readFields(staticFieldsSize);\n            ClassData.Field[] instanceFields = readFields(instanceFieldsSize);\n            ClassData.Method[] directMethods = readMethods(directMethodsSize);\n            ClassData.Method[] virtualMethods = readMethods(virtualMethodsSize);\n            return new ClassData(staticFields, instanceFields, directMethods, virtualMethods);\n        }\n\n        private ClassData.Field[] readFields(int count) {\n            ClassData.Field[] result = new ClassData.Field[count];\n            int fieldIndex = 0;\n            for (int i = 0; i < count; i++) {\n                fieldIndex += readUleb128(); // field index diff\n                int accessFlags = readUleb128();\n                result[i] = new ClassData.Field(fieldIndex, accessFlags);\n            }\n            return result;\n        }\n\n        private ClassData.Method[] readMethods(int count) {\n            ClassData.Method[] result = new ClassData.Method[count];\n            int methodIndex = 0;\n            for (int i = 0; i < count; i++) {\n                methodIndex += readUleb128(); // method index diff\n                int accessFlags = readUleb128();\n                int codeOff = readUleb128();\n                result[i] = new ClassData.Method(methodIndex, accessFlags, codeOff);\n            }\n            return result;\n        }\n\n        /**\n         * Returns a byte array containing the bytes from {@code start} to this\n         * section's current position.\n         */\n        private byte[] getBytesFrom(int start) {\n            int end = data.position();\n            byte[] result = new byte[end - start];\n            data.position(start);\n            data.get(result);\n            return result;\n        }\n\n        public Annotation readAnnotation() {\n            byte visibility = readByte();\n            int start = data.position();\n            new EncodedValueReader(this, EncodedValueReader.ENCODED_ANNOTATION).skipValue();\n            return new Annotation(Dex.this, visibility, new EncodedValue(getBytesFrom(start)));\n        }\n\n        public EncodedValue readEncodedArray() {\n            int start = data.position();\n            new EncodedValueReader(this, EncodedValueReader.ENCODED_ARRAY).skipValue();\n            return new EncodedValue(getBytesFrom(start));\n        }\n\n        public void skip(int count) {\n            if (count < 0) {\n                throw new IllegalArgumentException();\n            }\n            data.position(data.position() + count);\n        }\n\n        /**\n         * Skips bytes until the position is aligned to a multiple of 4.\n         */\n        public void alignToFourBytes() {\n            data.position((data.position() + 3) & ~3);\n        }\n\n        /**\n         * Writes 0x00 until the position is aligned to a multiple of 4.\n         */\n        public void alignToFourBytesWithZeroFill() {\n            while ((data.position() & 3) != 0) {\n                data.put((byte) 0);\n            }\n        }\n\n        public void assertFourByteAligned() {\n            if ((data.position() & 3) != 0) {\n                throw new IllegalStateException(\"Not four byte aligned!\");\n            }\n        }\n\n        public void write(byte[] bytes) {\n            this.data.put(bytes);\n        }\n\n        public void writeByte(int b) {\n            data.put((byte) b);\n        }\n\n        public void writeShort(short i) {\n            data.putShort(i);\n        }\n\n        public void writeUnsignedShort(int i) {\n            short s = (short) i;\n            if (i != (s & 0xffff)) {\n                throw new IllegalArgumentException(\"Expected an unsigned short: \" + i);\n            }\n            writeShort(s);\n        }\n\n        public void write(short[] shorts) {\n            for (short s : shorts) {\n                writeShort(s);\n            }\n        }\n\n        public void writeInt(int i) {\n            data.putInt(i);\n        }\n\n        public void writeUleb128(int i) {\n            try {\n                Leb128.writeUnsignedLeb128(this, i);\n            } catch (ArrayIndexOutOfBoundsException e) {\n                throw new DexException2(\"Section limit \" + data.limit() + \" exceeded by \" + name);\n            }\n        }\n\n        public void writeSleb128(int i) {\n            try {\n                Leb128.writeSignedLeb128(this, i);\n            } catch (ArrayIndexOutOfBoundsException e) {\n                throw new DexException2(\"Section limit \" + data.limit() + \" exceeded by \" + name);\n            }\n        }\n\n        public void writeStringData(String value) {\n            try {\n                int length = value.length();\n                writeUleb128(length);\n                write(Mutf8.encode(value));\n                writeByte(0);\n            } catch (UTFDataFormatException e) {\n                throw new AssertionError();\n            }\n        }\n\n        public void writeTypeList(TypeList typeList) {\n            short[] types = typeList.getTypes();\n            writeInt(types.length);\n            for (short type : types) {\n                writeShort(type);\n            }\n            alignToFourBytesWithZeroFill();\n        }\n\n        /**\n         * Returns the number of bytes remaining in this section.\n         */\n        public int remaining() {\n            return data.remaining();\n        }\n\n        /**\n         * Returns the number of bytes used by this section.\n         */\n        public int used() {\n            return data.position() - initialPosition;\n        }\n    }\n\n    private final class StringTable extends AbstractList<String> implements RandomAccess {\n\n        @Override\n        public String get(int index) {\n            checkBounds(index, tableOfContents.stringIds.size);\n            return open(tableOfContents.stringIds.off + (index * SizeOf.STRING_ID_ITEM)).readString();\n        }\n\n        @Override\n        public int size() {\n            return tableOfContents.stringIds.size;\n        }\n    }\n\n    private final class TypeIndexToDescriptorIndexTable extends AbstractList<Integer> implements RandomAccess {\n\n        @Override\n        public Integer get(int index) {\n            return descriptorIndexFromTypeIndex(index);\n        }\n\n        @Override\n        public int size() {\n            return tableOfContents.typeIds.size;\n        }\n    }\n\n    private final class TypeIndexToDescriptorTable extends AbstractList<String> implements RandomAccess {\n\n        @Override\n        public String get(int index) {\n            return strings.get(descriptorIndexFromTypeIndex(index));\n        }\n\n        @Override\n        public int size() {\n            return tableOfContents.typeIds.size;\n        }\n    }\n\n    private final class ProtoIdTable extends AbstractList<ProtoId> implements RandomAccess {\n\n        @Override\n        public ProtoId get(int index) {\n            checkBounds(index, tableOfContents.protoIds.size);\n            return open(tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * index)).readProtoId();\n        }\n\n        @Override\n        public int size() {\n            return tableOfContents.protoIds.size;\n        }\n    }\n\n    private final class FieldIdTable extends AbstractList<FieldId> implements RandomAccess {\n\n        @Override\n        public FieldId get(int index) {\n            checkBounds(index, tableOfContents.fieldIds.size);\n            return open(tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * index)).readFieldId();\n        }\n\n        @Override\n        public int size() {\n            return tableOfContents.fieldIds.size;\n        }\n    }\n\n    private final class MethodIdTable extends AbstractList<MethodId> implements RandomAccess {\n\n        @Override\n        public MethodId get(int index) {\n            checkBounds(index, tableOfContents.methodIds.size);\n            return open(tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * index)).readMethodId();\n        }\n\n        @Override\n        public int size() {\n            return tableOfContents.methodIds.size;\n        }\n    }\n\n    private final class ClassDefIterator implements Iterator<ClassDef> {\n\n        private final Section in    = open(tableOfContents.classDefs.off);\n        private int           count = 0;\n\n        @Override\n        public boolean hasNext() {\n            return count < tableOfContents.classDefs.size;\n        }\n\n        @Override\n        public ClassDef next() {\n            if (!hasNext()) {\n                throw new NoSuchElementException();\n            }\n            count++;\n            return in.readClassDef();\n        }\n\n        @Override\n        public void remove() {\n            throw new UnsupportedOperationException();\n        }\n    }\n\n    private final class ClassDefIterable implements Iterable<ClassDef> {\n\n        public Iterator<ClassDef> iterator() {\n            return !tableOfContents.classDefs.exists() ? Collections.<ClassDef> emptySet().iterator() : new ClassDefIterator();\n        }\n    }\n}\n\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/DexException2.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\nimport com.taobao.atlas.dex.util.ExceptionWithContext;\n\n/**\n * Thrown when there's a format problem reading, writing, or generally\n * processing a dex file.\n */\npublic class DexException2 extends ExceptionWithContext {\n    public DexException2(String message) {\n        super(message);\n    }\n\n    public DexException2(Throwable cause) {\n        super(cause);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/DexFormat.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\n/**\n * Constants that show up in and are otherwise related to {@code .dex}\n * files, and helper methods for same.\n */\n final class DexFormat {\n    private DexFormat() {}\n\n    /**\n     * API level to target in order to produce the most modern file\n     * format\n     */\n    public static final int API_CURRENT = 24;\n\n    /** API level to target in order to suppress extended opcode usage */\n    public static final int API_NO_EXTENDED_OPCODES = 13;\n\n    /**\n     * file name of the primary {@code .dex} file inside an\n     * application or library {@code .jar} file\n     */\n    public static final String DEX_IN_JAR_NAME = \"classes.dex\";\n\n    /** common prefix for all dex file \"magic numbers\" */\n    public static final String MAGIC_PREFIX = \"dex\\n\";\n\n    /** common suffix for all dex file \"magic numbers\" */\n    public static final String MAGIC_SUFFIX = \"\\0\";\n\n    /**\n     * Dex file version number for dalvik.\n     * <p>\n     * Note: Dex version 36 was loadable in some versions of Dalvik but was never fully supported or\n     * completed and is not considered a valid dex file format.\n     * </p>\n     */\n    public static final String VERSION_CURRENT = \"037\";\n\n    /** dex file version number for API level 13 and earlier */\n    public static final String VERSION_FOR_API_13 = \"035\";\n\n    /**\n     * value used to indicate endianness of file contents\n     */\n    public static final int ENDIAN_TAG = 0x12345678;\n\n    /**\n     * Maximum addressable field or method index.\n     * The largest addressable member is 0xffff, in the \"instruction formats\" spec as field@CCCC or\n     * meth@CCCC.\n     */\n    public static final int MAX_MEMBER_IDX = 0xFFFF;\n\n    /**\n     * Maximum addressable type index.\n     * The largest addressable type is 0xffff, in the \"instruction formats\" spec as type@CCCC.\n     */\n    public static final int MAX_TYPE_IDX = 0xFFFF;\n\n    /**\n     * Returns the API level corresponding to the given magic number,\n     * or {@code -1} if the given array is not a well-formed dex file\n     * magic number.\n     */\n    public static int magicToApi(byte[] magic) {\n        if (magic.length != 8) {\n            return -1;\n        }\n\n        if ((magic[0] != 'd') || (magic[1] != 'e') || (magic[2] != 'x') || (magic[3] != '\\n') ||\n                (magic[7] != '\\0')) {\n            return -1;\n        }\n\n        String version = \"\" + ((char) magic[4]) + ((char) magic[5]) +((char) magic[6]);\n\n        if (version.equals(VERSION_CURRENT)) {\n            return API_CURRENT;\n        } else if (version.equals(VERSION_FOR_API_13)) {\n            return API_NO_EXTENDED_OPCODES;\n        }\n\n        return -1;\n    }\n\n    /**\n     * Returns the magic number corresponding to the given target API level.\n     */\n    public static String apiToMagic(int targetApiLevel) {\n        String version;\n\n        if (targetApiLevel >= API_CURRENT) {\n            version = VERSION_CURRENT;\n        } else {\n            version = VERSION_FOR_API_13;\n        }\n\n        return MAGIC_PREFIX + version + MAGIC_SUFFIX;\n    }\n\n    public static boolean isSupportedDexMagic(byte[] magic) {\n        int api = magicToApi(magic);\n        return api == API_NO_EXTENDED_OPCODES || api == API_CURRENT;\n    }\n}\n\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/DexIndexOverflowException.java",
    "content": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\n/**\n * Thrown when there's an index overflow writing a dex file.\n */\npublic class DexIndexOverflowException extends DexException2 {\n    public DexIndexOverflowException(String message) {\n        super(message);\n    }\n\n    public DexIndexOverflowException(Throwable cause) {\n        super(cause);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/EncodedValue.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\nimport com.taobao.atlas.dex.util.ByteArrayByteInput;\nimport com.taobao.atlas.dex.util.ByteInput;\n\n/**\n * An encoded value or array.\n */\npublic final class EncodedValue implements Comparable<EncodedValue> {\n    private final byte[] data;\n\n    public EncodedValue(byte[] data) {\n        this.data = data;\n    }\n\n    public ByteInput asByteInput() {\n        return new ByteArrayByteInput(data);\n    }\n\n    public byte[] getBytes() {\n        return data;\n    }\n\n    public void writeTo(Dex.Section out) {\n        out.write(data);\n    }\n\n    @Override public int compareTo(EncodedValue other) {\n        int size = Math.min(data.length, other.data.length);\n        for (int i = 0; i < size; i++) {\n            if (data[i] != other.data[i]) {\n                return (data[i] & 0xff) - (other.data[i] & 0xff);\n            }\n        }\n        return data.length - other.data.length;\n    }\n\n    @Override public String toString() {\n        return Integer.toHexString(data[0] & 0xff) + \"...(\" + data.length + \")\";\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/EncodedValueCodec.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\nimport com.taobao.atlas.dex.util.ByteInput;\nimport com.taobao.atlas.dex.util.ByteOutput;\n\n/**\n * Read and write {@code encoded_value} primitives.\n */\npublic final class EncodedValueCodec {\n    private EncodedValueCodec() {\n    }\n\n    /**\n     * Writes a signed integral to {@code out}.\n     */\n    public static void writeSignedIntegralValue(ByteOutput out, int type, long value) {\n        /*\n         * Figure out how many bits are needed to represent the value,\n         * including a sign bit: The bit count is subtracted from 65\n         * and not 64 to account for the sign bit. The xor operation\n         * has the effect of leaving non-negative values alone and\n         * unary complementing negative values (so that a leading zero\n         * count always returns a useful number for our present\n         * purpose).\n         */\n        int requiredBits = 65 - Long.numberOfLeadingZeros(value ^ (value >> 63));\n\n        // Round up the requiredBits to a number of bytes.\n        int requiredBytes = (requiredBits + 0x07) >> 3;\n\n        /*\n         * Write the header byte, which includes the type and\n         * requiredBytes - 1.\n         */\n        out.writeByte(type | ((requiredBytes - 1) << 5));\n\n        // Write the value, per se.\n        while (requiredBytes > 0) {\n            out.writeByte((byte) value);\n            value >>= 8;\n            requiredBytes--;\n        }\n    }\n\n    /**\n     * Writes an unsigned integral to {@code out}.\n     */\n    public static void writeUnsignedIntegralValue(ByteOutput out, int type, long value) {\n        // Figure out how many bits are needed to represent the value.\n        int requiredBits = 64 - Long.numberOfLeadingZeros(value);\n        if (requiredBits == 0) {\n            requiredBits = 1;\n        }\n\n        // Round up the requiredBits to a number of bytes.\n        int requiredBytes = (requiredBits + 0x07) >> 3;\n\n        /*\n         * Write the header byte, which includes the type and\n         * requiredBytes - 1.\n         */\n        out.writeByte(type | ((requiredBytes - 1) << 5));\n\n        // Write the value, per se.\n        while (requiredBytes > 0) {\n            out.writeByte((byte) value);\n            value >>= 8;\n            requiredBytes--;\n        }\n    }\n\n    /**\n     * Writes a right-zero-extended value to {@code out}.\n     */\n    public static void writeRightZeroExtendedValue(ByteOutput out, int type, long value) {\n        // Figure out how many bits are needed to represent the value.\n        int requiredBits = 64 - Long.numberOfTrailingZeros(value);\n        if (requiredBits == 0) {\n            requiredBits = 1;\n        }\n\n        // Round up the requiredBits to a number of bytes.\n        int requiredBytes = (requiredBits + 0x07) >> 3;\n\n        // Scootch the first bits to be written down to the low-order bits.\n        value >>= 64 - (requiredBytes * 8);\n\n        /*\n         * Write the header byte, which includes the type and\n         * requiredBytes - 1.\n         */\n        out.writeByte(type | ((requiredBytes - 1) << 5));\n\n        // Write the value, per se.\n        while (requiredBytes > 0) {\n            out.writeByte((byte) value);\n            value >>= 8;\n            requiredBytes--;\n        }\n    }\n\n    /**\n     * Read a signed integer.\n     *\n     * @param zwidth byte count minus one\n     */\n    public static int readSignedInt(ByteInput in, int zwidth) {\n        int result = 0;\n        for (int i = zwidth; i >= 0; i--) {\n            result = (result >>> 8) | ((in.readByte() & 0xff) << 24);\n        }\n        result >>= (3 - zwidth) * 8;\n        return result;\n    }\n\n    /**\n     * Read an unsigned integer.\n     *\n     * @param zwidth byte count minus one\n     * @param fillOnRight true to zero fill on the right; false on the left\n     */\n    public static int readUnsignedInt(ByteInput in, int zwidth, boolean fillOnRight) {\n        int result = 0;\n        if (!fillOnRight) {\n            for (int i = zwidth; i >= 0; i--) {\n                result = (result >>> 8) | ((in.readByte() & 0xff) << 24);\n            }\n            result >>>= (3 - zwidth) * 8;\n        } else {\n            for (int i = zwidth; i >= 0; i--) {\n                result = (result >>> 8) | ((in.readByte() & 0xff) << 24);\n            }\n        }\n        return result;\n    }\n\n    /**\n     * Read a signed long.\n     *\n     * @param zwidth byte count minus one\n     */\n    public static long readSignedLong(ByteInput in, int zwidth) {\n        long result = 0;\n        for (int i = zwidth; i >= 0; i--) {\n            result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);\n        }\n        result >>= (7 - zwidth) * 8;\n        return result;\n    }\n\n    /**\n     * Read an unsigned long.\n     *\n     * @param zwidth byte count minus one\n     * @param fillOnRight true to zero fill on the right; false on the left\n     */\n    public static long readUnsignedLong(ByteInput in, int zwidth, boolean fillOnRight) {\n        long result = 0;\n        if (!fillOnRight) {\n            for (int i = zwidth; i >= 0; i--) {\n                result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);\n            }\n            result >>>= (7 - zwidth) * 8;\n        } else {\n            for (int i = zwidth; i >= 0; i--) {\n                result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);\n            }\n        }\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/EncodedValueReader.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\nimport com.taobao.atlas.dex.util.ByteInput;\n\n/**\n * Pull parser for encoded values.\n */\npublic final class EncodedValueReader {\n    public static final int ENCODED_BYTE = 0x00;\n    public static final int ENCODED_SHORT = 0x02;\n    public static final int ENCODED_CHAR = 0x03;\n    public static final int ENCODED_INT = 0x04;\n    public static final int ENCODED_LONG = 0x06;\n    public static final int ENCODED_FLOAT = 0x10;\n    public static final int ENCODED_DOUBLE = 0x11;\n    public static final int ENCODED_STRING = 0x17;\n    public static final int ENCODED_TYPE = 0x18;\n    public static final int ENCODED_FIELD = 0x19;\n    public static final int ENCODED_ENUM = 0x1b;\n    public static final int ENCODED_METHOD = 0x1a;\n    public static final int ENCODED_ARRAY = 0x1c;\n    public static final int ENCODED_ANNOTATION = 0x1d;\n    public static final int ENCODED_NULL = 0x1e;\n    public static final int ENCODED_BOOLEAN = 0x1f;\n\n    /** placeholder type if the type is not yet known */\n    private static final int MUST_READ = -1;\n\n    protected final ByteInput in;\n    private int type = MUST_READ;\n    private int annotationType;\n    private int arg;\n\n    public EncodedValueReader(ByteInput in) {\n        this.in = in;\n    }\n\n    public EncodedValueReader(EncodedValue in) {\n        this(in.asByteInput());\n    }\n\n    /**\n     * Creates a new encoded value reader whose only value is the specified\n     * known type. This is useful for encoded values without a type prefix,\n     * such as class_def_item's encoded_array or annotation_item's\n     * encoded_annotation.\n     */\n    public EncodedValueReader(ByteInput in, int knownType) {\n        this.in = in;\n        this.type = knownType;\n    }\n\n    public EncodedValueReader(EncodedValue in, int knownType) {\n        this(in.asByteInput(), knownType);\n    }\n\n    /**\n     * Returns the type of the next value to read.\n     */\n    public int peek() {\n        if (type == MUST_READ) {\n            int argAndType = in.readByte() & 0xff;\n            type = argAndType & 0x1f;\n            arg = (argAndType & 0xe0) >> 5;\n        }\n        return type;\n    }\n\n    /**\n     * Begins reading the elements of an array, returning the array's size. The\n     * caller must follow up by calling a read method for each element in the\n     * array. For example, this reads a byte array: <pre>   {@code\n     *   int arraySize = readArray();\n     *   for (int i = 0, i < arraySize; i++) {\n     *     readByte();\n     *   }\n     * }</pre>\n     */\n    public int readArray() {\n        checkType(ENCODED_ARRAY);\n        type = MUST_READ;\n        return Leb128.readUnsignedLeb128(in);\n    }\n\n    /**\n     * Begins reading the fields of an annotation, returning the number of\n     * fields. The caller must follow up by making alternating calls to {@link\n     * #readAnnotationName()} and another read method. For example, this reads\n     * an annotation whose fields are all bytes: <pre>   {@code\n     *   int fieldCount = readAnnotation();\n     *   int annotationType = getAnnotationType();\n     *   for (int i = 0; i < fieldCount; i++) {\n     *       readAnnotationName();\n     *       readByte();\n     *   }\n     * }</pre>\n     */\n    public int readAnnotation() {\n        checkType(ENCODED_ANNOTATION);\n        type = MUST_READ;\n        annotationType = Leb128.readUnsignedLeb128(in);\n        return Leb128.readUnsignedLeb128(in);\n    }\n\n    /**\n     * Returns the type of the annotation just returned by {@link\n     * #readAnnotation()}. This method's value is undefined unless the most\n     * recent call was to {@link #readAnnotation()}.\n     */\n    public int getAnnotationType() {\n        return annotationType;\n    }\n\n    public int readAnnotationName() {\n        return Leb128.readUnsignedLeb128(in);\n    }\n\n    public byte readByte() {\n        checkType(ENCODED_BYTE);\n        type = MUST_READ;\n        return (byte) EncodedValueCodec.readSignedInt(in, arg);\n    }\n\n    public short readShort() {\n        checkType(ENCODED_SHORT);\n        type = MUST_READ;\n        return (short) EncodedValueCodec.readSignedInt(in, arg);\n    }\n\n    public char readChar() {\n        checkType(ENCODED_CHAR);\n        type = MUST_READ;\n        return (char) EncodedValueCodec.readUnsignedInt(in, arg, false);\n    }\n\n    public int readInt() {\n        checkType(ENCODED_INT);\n        type = MUST_READ;\n        return EncodedValueCodec.readSignedInt(in, arg);\n    }\n\n    public long readLong() {\n        checkType(ENCODED_LONG);\n        type = MUST_READ;\n        return EncodedValueCodec.readSignedLong(in, arg);\n    }\n\n    public float readFloat() {\n        checkType(ENCODED_FLOAT);\n        type = MUST_READ;\n        return Float.intBitsToFloat(EncodedValueCodec.readUnsignedInt(in, arg, true));\n    }\n\n    public double readDouble() {\n        checkType(ENCODED_DOUBLE);\n        type = MUST_READ;\n        return Double.longBitsToDouble(EncodedValueCodec.readUnsignedLong(in, arg, true));\n    }\n\n    public int readString() {\n        checkType(ENCODED_STRING);\n        type = MUST_READ;\n        return EncodedValueCodec.readUnsignedInt(in, arg, false);\n    }\n\n    public int readType() {\n        checkType(ENCODED_TYPE);\n        type = MUST_READ;\n        return EncodedValueCodec.readUnsignedInt(in, arg, false);\n    }\n\n    public int readField() {\n        checkType(ENCODED_FIELD);\n        type = MUST_READ;\n        return EncodedValueCodec.readUnsignedInt(in, arg, false);\n    }\n\n    public int readEnum() {\n        checkType(ENCODED_ENUM);\n        type = MUST_READ;\n        return EncodedValueCodec.readUnsignedInt(in, arg, false);\n    }\n\n    public int readMethod() {\n        checkType(ENCODED_METHOD);\n        type = MUST_READ;\n        return EncodedValueCodec.readUnsignedInt(in, arg, false);\n    }\n\n    public void readNull() {\n        checkType(ENCODED_NULL);\n        type = MUST_READ;\n    }\n\n    public boolean readBoolean() {\n        checkType(ENCODED_BOOLEAN);\n        type = MUST_READ;\n        return arg != 0;\n    }\n\n    /**\n     * Skips a single value, including its nested values if it is an array or\n     * annotation.\n     */\n    public void skipValue() {\n        switch (peek()) {\n        case ENCODED_BYTE:\n            readByte();\n            break;\n        case ENCODED_SHORT:\n            readShort();\n            break;\n        case ENCODED_CHAR:\n            readChar();\n            break;\n        case ENCODED_INT:\n            readInt();\n            break;\n        case ENCODED_LONG:\n            readLong();\n            break;\n        case ENCODED_FLOAT:\n            readFloat();\n            break;\n        case ENCODED_DOUBLE:\n            readDouble();\n            break;\n        case ENCODED_STRING:\n            readString();\n            break;\n        case ENCODED_TYPE:\n            readType();\n            break;\n        case ENCODED_FIELD:\n            readField();\n            break;\n        case ENCODED_ENUM:\n            readEnum();\n            break;\n        case ENCODED_METHOD:\n            readMethod();\n            break;\n        case ENCODED_ARRAY:\n            for (int i = 0, size = readArray(); i < size; i++) {\n                skipValue();\n            }\n            break;\n        case ENCODED_ANNOTATION:\n            for (int i = 0, size = readAnnotation(); i < size; i++) {\n                readAnnotationName();\n                skipValue();\n            }\n            break;\n        case ENCODED_NULL:\n            readNull();\n            break;\n        case ENCODED_BOOLEAN:\n            readBoolean();\n            break;\n        default:\n            throw new DexException2(\"Unexpected type: \" + Integer.toHexString(type));\n        }\n    }\n\n    private void checkType(int expected) {\n        if (peek() != expected) {\n            throw new IllegalStateException(\n                    String.format(\"Expected %x but was %x\", expected, peek()));\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/FieldId.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\nimport com.taobao.atlas.dex.util.Unsigned;\n\npublic final class FieldId implements Comparable<FieldId> {\n    private final Dex dex;\n    private final int declaringClassIndex;\n    private final int typeIndex;\n    private final int nameIndex;\n\n    public FieldId(Dex dex, int declaringClassIndex, int typeIndex, int nameIndex) {\n        this.dex = dex;\n        this.declaringClassIndex = declaringClassIndex;\n        this.typeIndex = typeIndex;\n        this.nameIndex = nameIndex;\n    }\n\n    public int getDeclaringClassIndex() {\n        return declaringClassIndex;\n    }\n\n    public int getTypeIndex() {\n        return typeIndex;\n    }\n\n    public int getNameIndex() {\n        return nameIndex;\n    }\n\n    public int compareTo(FieldId other) {\n        if (declaringClassIndex != other.declaringClassIndex) {\n            return Unsigned.compare(declaringClassIndex, other.declaringClassIndex);\n        }\n        if (nameIndex != other.nameIndex) {\n            return Unsigned.compare(nameIndex, other.nameIndex);\n        }\n        return Unsigned.compare(typeIndex, other.typeIndex); // should always be 0\n    }\n\n    public void writeTo(Dex.Section out) {\n        out.writeUnsignedShort(declaringClassIndex);\n        out.writeUnsignedShort(typeIndex);\n        out.writeInt(nameIndex);\n    }\n\n    @Override public String toString() {\n        if (dex == null) {\n            return declaringClassIndex + \" \" + typeIndex + \" \" + nameIndex;\n        }\n        return dex.typeNames().get(typeIndex) + \".\" + dex.strings().get(nameIndex);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/Leb128.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\nimport com.taobao.atlas.dex.util.ByteInput;\nimport com.taobao.atlas.dex.util.ByteOutput;\n\n/**\n * Reads and writes DWARFv3 LEB 128 signed and unsigned integers. See DWARF v3\n * section 7.6.\n */\npublic final class Leb128 {\n    private Leb128() {\n    }\n\n    /**\n     * Gets the number of bytes in the unsigned LEB128 encoding of the\n     * given value.\n     *\n     * @param value the value in question\n     * @return its write size, in bytes\n     */\n    public static int unsignedLeb128Size(int value) {\n        // TODO: This could be much cleverer.\n\n        int remaining = value >> 7;\n        int count = 0;\n\n        while (remaining != 0) {\n            remaining >>= 7;\n            count++;\n        }\n\n        return count + 1;\n    }\n\n    /**\n     * Gets the number of bytes in the signed LEB128 encoding of the\n     * given value.\n     *\n     * @param value the value in question\n     * @return its write size, in bytes\n     */\n    public static int signedLeb128Size(int value) {\n        // TODO: This could be much cleverer.\n\n        int remaining = value >> 7;\n        int count = 0;\n        boolean hasMore = true;\n        int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;\n\n        while (hasMore) {\n            hasMore = (remaining != end)\n                || ((remaining & 1) != ((value >> 6) & 1));\n\n            value = remaining;\n            remaining >>= 7;\n            count++;\n        }\n\n        return count;\n    }\n\n    /**\n     * Reads an signed integer from {@code in}.\n     */\n    public static int readSignedLeb128(ByteInput in) {\n        int result = 0;\n        int cur;\n        int count = 0;\n        int signBits = -1;\n\n        do {\n            cur = in.readByte() & 0xff;\n            result |= (cur & 0x7f) << (count * 7);\n            signBits <<= 7;\n            count++;\n        } while (((cur & 0x80) == 0x80) && count < 5);\n\n        if ((cur & 0x80) == 0x80) {\n            throw new DexException2(\"invalid LEB128 sequence\");\n        }\n\n        // Sign extend if appropriate\n        if (((signBits >> 1) & result) != 0 ) {\n            result |= signBits;\n        }\n\n        return result;\n    }\n\n    /**\n     * Reads an unsigned integer from {@code in}.\n     */\n    public static int readUnsignedLeb128(ByteInput in) {\n        int result = 0;\n        int cur;\n        int count = 0;\n\n        do {\n            cur = in.readByte() & 0xff;\n            result |= (cur & 0x7f) << (count * 7);\n            count++;\n        } while (((cur & 0x80) == 0x80) && count < 5);\n\n        if ((cur & 0x80) == 0x80) {\n            throw new DexException2(\"invalid LEB128 sequence\");\n        }\n\n        return result;\n    }\n\n    /**\n     * Writes {@code value} as an unsigned integer to {@code out}, starting at\n     * {@code offset}. Returns the number of bytes written.\n     */\n    public static void writeUnsignedLeb128(ByteOutput out, int value) {\n        int remaining = value >>> 7;\n\n        while (remaining != 0) {\n            out.writeByte((byte) ((value & 0x7f) | 0x80));\n            value = remaining;\n            remaining >>>= 7;\n        }\n\n        out.writeByte((byte) (value & 0x7f));\n    }\n\n    /**\n     * Writes {@code value} as a signed integer to {@code out}, starting at\n     * {@code offset}. Returns the number of bytes written.\n     */\n    public static void writeSignedLeb128(ByteOutput out, int value) {\n        int remaining = value >> 7;\n        boolean hasMore = true;\n        int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;\n\n        while (hasMore) {\n            hasMore = (remaining != end)\n                    || ((remaining & 1) != ((value >> 6) & 1));\n\n            out.writeByte((byte) ((value & 0x7f) | (hasMore ? 0x80 : 0)));\n            value = remaining;\n            remaining >>= 7;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/MethodId.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\nimport com.taobao.atlas.dex.util.Unsigned;\n\npublic final class MethodId implements Comparable<MethodId> {\n    private final Dex dex;\n    private final int declaringClassIndex;\n    private final int protoIndex;\n    private final int nameIndex;\n\n    public MethodId(Dex dex, int declaringClassIndex, int protoIndex, int nameIndex) {\n        this.dex = dex;\n        this.declaringClassIndex = declaringClassIndex;\n        this.protoIndex = protoIndex;\n        this.nameIndex = nameIndex;\n    }\n\n    public int getDeclaringClassIndex() {\n        return declaringClassIndex;\n    }\n\n    public int getProtoIndex() {\n        return protoIndex;\n    }\n\n    public int getNameIndex() {\n        return nameIndex;\n    }\n\n    public int compareTo(MethodId other) {\n        if (declaringClassIndex != other.declaringClassIndex) {\n            return Unsigned.compare(declaringClassIndex, other.declaringClassIndex);\n        }\n        if (nameIndex != other.nameIndex) {\n            return Unsigned.compare(nameIndex, other.nameIndex);\n        }\n        return Unsigned.compare(protoIndex, other.protoIndex);\n    }\n\n    public void writeTo(Dex.Section out) {\n        out.writeUnsignedShort(declaringClassIndex);\n        out.writeUnsignedShort(protoIndex);\n        out.writeInt(nameIndex);\n    }\n\n    @Override public String toString() {\n        if (dex == null) {\n            return declaringClassIndex + \" \" + protoIndex + \" \" + nameIndex;\n        }\n        return dex.typeNames().get(declaringClassIndex)\n                + \".\" + dex.strings().get(nameIndex)\n                + dex.readTypeList(dex.protoIds().get(protoIndex).getParametersOffset());\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/Mutf8.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\nimport com.taobao.atlas.dex.util.ByteInput;\n\nimport java.io.UTFDataFormatException;\n\n/**\n * Modified UTF-8 as described in the dex file format spec.\n *\n * <p>Derived from libcore's MUTF-8 encoder at java.nio.charset.ModifiedUtf8.\n */\npublic final class Mutf8 {\n    private Mutf8() {}\n\n    /**\n     * Decodes bytes from {@code in} into {@code out} until a delimiter 0x00 is\n     * encountered. Returns a new string containing the decoded characters.\n     */\n    public static String decode(ByteInput in, char[] out) throws UTFDataFormatException {\n        int s = 0;\n        while (true) {\n            char a = (char) (in.readByte() & 0xff);\n            if (a == 0) {\n                return new String(out, 0, s);\n            }\n            out[s] = a;\n            if (a < '\\u0080') {\n                s++;\n            } else if ((a & 0xe0) == 0xc0) {\n                int b = in.readByte() & 0xff;\n                if ((b & 0xC0) != 0x80) {\n                    throw new UTFDataFormatException(\"bad second byte\");\n                }\n                out[s++] = (char) (((a & 0x1F) << 6) | (b & 0x3F));\n            } else if ((a & 0xf0) == 0xe0) {\n                int b = in.readByte() & 0xff;\n                int c = in.readByte() & 0xff;\n                if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80)) {\n                    throw new UTFDataFormatException(\"bad second or third byte\");\n                }\n                out[s++] = (char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F));\n            } else {\n                throw new UTFDataFormatException(\"bad byte\");\n            }\n        }\n    }\n\n    /**\n     * Returns the number of bytes the modified UTF8 representation of 's' would take.\n     */\n    private static long countBytes(String s, boolean shortLength) throws UTFDataFormatException {\n        long result = 0;\n        final int length = s.length();\n        for (int i = 0; i < length; ++i) {\n            char ch = s.charAt(i);\n            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.\n                ++result;\n            } else if (ch <= 2047) {\n                result += 2;\n            } else {\n                result += 3;\n            }\n            if (shortLength && result > 65535) {\n                throw new UTFDataFormatException(\"String more than 65535 UTF bytes long\");\n            }\n        }\n        return result;\n    }\n\n    /**\n     * Encodes the modified UTF-8 bytes corresponding to {@code s} into  {@code\n     * dst}, starting at {@code offset}.\n     */\n    public static void encode(byte[] dst, int offset, String s) {\n        final int length = s.length();\n        for (int i = 0; i < length; i++) {\n            char ch = s.charAt(i);\n            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.\n                dst[offset++] = (byte) ch;\n            } else if (ch <= 2047) {\n                dst[offset++] = (byte) (0xc0 | (0x1f & (ch >> 6)));\n                dst[offset++] = (byte) (0x80 | (0x3f & ch));\n            } else {\n                dst[offset++] = (byte) (0xe0 | (0x0f & (ch >> 12)));\n                dst[offset++] = (byte) (0x80 | (0x3f & (ch >> 6)));\n                dst[offset++] = (byte) (0x80 | (0x3f & ch));\n            }\n        }\n    }\n\n    /**\n     * Returns an array containing the <i>modified UTF-8</i> form of {@code s}.\n     */\n    public static byte[] encode(String s) throws UTFDataFormatException {\n        int utfCount = (int) countBytes(s, true);\n        byte[] result = new byte[utfCount];\n        encode(result, 0, s);\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/ProtoId.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\nimport com.taobao.atlas.dex.util.Unsigned;\n\npublic final class ProtoId implements Comparable<ProtoId> {\n    private final Dex dex;\n    private final int shortyIndex;\n    private final int returnTypeIndex;\n    private final int parametersOffset;\n\n    public ProtoId(Dex dex, int shortyIndex, int returnTypeIndex, int parametersOffset) {\n        this.dex = dex;\n        this.shortyIndex = shortyIndex;\n        this.returnTypeIndex = returnTypeIndex;\n        this.parametersOffset = parametersOffset;\n    }\n\n    public int compareTo(ProtoId other) {\n        if (returnTypeIndex != other.returnTypeIndex) {\n            return Unsigned.compare(returnTypeIndex, other.returnTypeIndex);\n        }\n        return Unsigned.compare(parametersOffset, other.parametersOffset);\n    }\n\n    public int getShortyIndex() {\n        return shortyIndex;\n    }\n\n    public int getReturnTypeIndex() {\n        return returnTypeIndex;\n    }\n\n    public int getParametersOffset() {\n        return parametersOffset;\n    }\n\n    public void writeTo(Dex.Section out) {\n        out.writeInt(shortyIndex);\n        out.writeInt(returnTypeIndex);\n        out.writeInt(parametersOffset);\n    }\n\n    @Override public String toString() {\n        if (dex == null) {\n            return shortyIndex + \" \" + returnTypeIndex + \" \" + parametersOffset;\n        }\n\n        return dex.strings().get(shortyIndex)\n                + \": \" + dex.typeNames().get(returnTypeIndex)\n                + \" \" + dex.readTypeList(parametersOffset);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/SizeOf.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\npublic final class SizeOf {\n    private SizeOf() {}\n\n    public static final int UBYTE = 1;\n    public static final int USHORT = 2;\n    public static final int UINT = 4;\n\n    public static final int SIGNATURE = UBYTE * 20;\n\n    /**\n     * magic ubyte[8]\n     * checksum uint\n     * signature ubyte[20]\n     * file_size uint\n     * header_size uint\n     * endian_tag uint\n     * link_size uint\n     * link_off uint\n     * map_off uint\n     * string_ids_size uint\n     * string_ids_off uint\n     * type_ids_size uint\n     * type_ids_off uint\n     * proto_ids_size uint\n     * proto_ids_off uint\n     * field_ids_size uint\n     * field_ids_off uint\n     * method_ids_size uint\n     * method_ids_off uint\n     * class_defs_size uint\n     * class_defs_off uint\n     * data_size uint\n     * data_off uint\n     */\n    public static final int HEADER_ITEM = (8 * UBYTE) + UINT + SIGNATURE + (20 * UINT); // 0x70\n\n    /**\n     * string_data_off uint\n     */\n    public static final int STRING_ID_ITEM = UINT;\n\n    /**\n     * descriptor_idx uint\n     */\n    public static final int TYPE_ID_ITEM = UINT;\n\n    /**\n     * type_idx ushort\n     */\n    public static final int TYPE_ITEM = USHORT;\n\n    /**\n     * shorty_idx uint\n     * return_type_idx uint\n     * return_type_idx uint\n     */\n    public static final int PROTO_ID_ITEM = UINT + UINT + UINT;\n\n    /**\n     * class_idx ushort\n     * type_idx/proto_idx ushort\n     * name_idx uint\n     */\n    public static final int MEMBER_ID_ITEM = USHORT + USHORT + UINT;\n\n    /**\n     * class_idx uint\n     * access_flags uint\n     * superclass_idx uint\n     * interfaces_off uint\n     * source_file_idx uint\n     * annotations_off uint\n     * class_data_off uint\n     * static_values_off uint\n     */\n    public static final int CLASS_DEF_ITEM = 8 * UINT;\n\n    /**\n     * type ushort\n     * unused ushort\n     * size uint\n     * offset uint\n     */\n    public static final int MAP_ITEM = USHORT + USHORT + UINT + UINT;\n\n    /**\n     * start_addr uint\n     * insn_count ushort\n     * handler_off ushort\n     */\n    public static final int TRY_ITEM = UINT + USHORT + USHORT;\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/TableOfContents.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\nimport java.io.IOException;\nimport java.io.UnsupportedEncodingException;\nimport java.util.Arrays;\n\n/**\n * The file header and map.\n */\npublic final class TableOfContents {\n\n    /*\n     * TODO: factor out ID constants.\n     */\n\n    public final Section header = new Section(0x0000);\n    public final Section stringIds = new Section(0x0001);\n    public final Section typeIds = new Section(0x0002);\n    public final Section protoIds = new Section(0x0003);\n    public final Section fieldIds = new Section(0x0004);\n    public final Section methodIds = new Section(0x0005);\n    public final Section classDefs = new Section(0x0006);\n    public final Section mapList = new Section(0x1000);\n    public final Section typeLists = new Section(0x1001);\n    public final Section annotationSetRefLists = new Section(0x1002);\n    public final Section annotationSets = new Section(0x1003);\n    public final Section classDatas = new Section(0x2000);\n    public final Section codes = new Section(0x2001);\n    public final Section stringDatas = new Section(0x2002);\n    public final Section debugInfos = new Section(0x2003);\n    public final Section annotations = new Section(0x2004);\n    public final Section encodedArrays = new Section(0x2005);\n    public final Section annotationsDirectories = new Section(0x2006);\n    public final Section[] sections = {\n            header, stringIds, typeIds, protoIds, fieldIds, methodIds, classDefs, mapList,\n            typeLists, annotationSetRefLists, annotationSets, classDatas, codes, stringDatas,\n            debugInfos, annotations, encodedArrays, annotationsDirectories\n    };\n\n    public int apiLevel;\n    public int checksum;\n    public byte[] signature;\n    public int fileSize;\n    public int linkSize;\n    public int linkOff;\n    public int dataSize;\n    public int dataOff;\n\n    public TableOfContents() {\n        signature = new byte[20];\n    }\n\n    public void readFrom(Dex dex) throws IOException {\n        readHeader(dex.open(0));\n        readMap(dex.open(mapList.off));\n        computeSizesFromOffsets();\n    }\n\n    private void readHeader(Dex.Section headerIn) throws UnsupportedEncodingException {\n        byte[] magic = headerIn.readByteArray(8);\n\n        if (!DexFormat.isSupportedDexMagic(magic)) {\n            throw new DexException2(\"Unexpected magic: \" + Arrays.toString(magic));\n        }\n\n        apiLevel = DexFormat.magicToApi(magic);\n        checksum = headerIn.readInt();\n        signature = headerIn.readByteArray(20);\n        fileSize = headerIn.readInt();\n        int headerSize = headerIn.readInt();\n        if (headerSize != SizeOf.HEADER_ITEM) {\n            throw new DexException2(\"Unexpected header: 0x\" + Integer.toHexString(headerSize));\n        }\n        int endianTag = headerIn.readInt();\n        if (endianTag != DexFormat.ENDIAN_TAG) {\n            throw new DexException2(\"Unexpected endian tag: 0x\" + Integer.toHexString(endianTag));\n        }\n        linkSize = headerIn.readInt();\n        linkOff = headerIn.readInt();\n        mapList.off = headerIn.readInt();\n        if (mapList.off == 0) {\n            throw new DexException2(\"Cannot merge dex files that do not contain a map\");\n        }\n        stringIds.size = headerIn.readInt();\n        stringIds.off = headerIn.readInt();\n        typeIds.size = headerIn.readInt();\n        typeIds.off = headerIn.readInt();\n        protoIds.size = headerIn.readInt();\n        protoIds.off = headerIn.readInt();\n        fieldIds.size = headerIn.readInt();\n        fieldIds.off = headerIn.readInt();\n        methodIds.size = headerIn.readInt();\n        methodIds.off = headerIn.readInt();\n        classDefs.size = headerIn.readInt();\n        classDefs.off = headerIn.readInt();\n        dataSize = headerIn.readInt();\n        dataOff = headerIn.readInt();\n    }\n\n    private void readMap(Dex.Section in) throws IOException {\n        int mapSize = in.readInt();\n        Section previous = null;\n        for (int i = 0; i < mapSize; i++) {\n            short type = in.readShort();\n            in.readShort(); // unused\n            Section section = getSection(type);\n            int size = in.readInt();\n            int offset = in.readInt();\n\n            if ((section.size != 0 && section.size != size)\n                    || (section.off != -1 && section.off != offset)) {\n                throw new DexException2(\"Unexpected map value for 0x\" + Integer.toHexString(type));\n            }\n\n            section.size = size;\n            section.off = offset;\n\n            if (previous != null && previous.off > section.off) {\n                throw new DexException2(\"Map is unsorted at \" + previous + \", \" + section);\n            }\n\n            previous = section;\n        }\n        Arrays.sort(sections);\n    }\n\n    public void computeSizesFromOffsets() {\n        int end = dataOff + dataSize;\n        for (int i = sections.length - 1; i >= 0; i--) {\n            Section section = sections[i];\n            if (section.off == -1) {\n                continue;\n            }\n            if (section.off > end) {\n                throw new DexException2(\"Map is unsorted at \" + section + \",off: \"+section.off+\",end:\" + end);\n            }\n            section.byteCount = end - section.off;\n            if(section.off > 0) {\n                end = section.off;\n            }\n        }\n    }\n\n    private Section getSection(short type) {\n        for (Section section : sections) {\n            if (section.type == type) {\n                return section;\n            }\n        }\n        throw new IllegalArgumentException(\"No such map item: \" + type);\n    }\n\n    public void writeHeader(Dex.Section out, int api) throws IOException {\n        out.write(DexFormat.apiToMagic(api).getBytes(\"UTF-8\"));\n        out.writeInt(checksum);\n        out.write(signature);\n        out.writeInt(fileSize);\n        out.writeInt(SizeOf.HEADER_ITEM);\n        out.writeInt(DexFormat.ENDIAN_TAG);\n        out.writeInt(linkSize);\n        out.writeInt(linkOff);\n        out.writeInt(mapList.off);\n        out.writeInt(stringIds.size);\n        out.writeInt(stringIds.off);\n        out.writeInt(typeIds.size);\n        out.writeInt(typeIds.off);\n        out.writeInt(protoIds.size);\n        out.writeInt(protoIds.off);\n        out.writeInt(fieldIds.size);\n        out.writeInt(fieldIds.off);\n        out.writeInt(methodIds.size);\n        out.writeInt(methodIds.off);\n        out.writeInt(classDefs.size);\n        out.writeInt(classDefs.off);\n        out.writeInt(dataSize);\n        out.writeInt(dataOff);\n    }\n\n    public void writeMap(Dex.Section out) throws IOException {\n        int count = 0;\n        for (Section section : sections) {\n            if (section.exists()) {\n                count++;\n            }\n        }\n\n        out.writeInt(count);\n        for (Section section : sections) {\n            if (section.exists()) {\n                out.writeShort(section.type);\n                out.writeShort((short) 0);\n                out.writeInt(section.size);\n                out.writeInt(section.off);\n            }\n        }\n    }\n\n    public static class Section implements Comparable<Section> {\n        public final short type;\n        public int size = 0;\n        public int off = -1;\n        public int byteCount = 0;\n\n        public Section(int type) {\n            this.type = (short) type;\n        }\n\n        public boolean exists() {\n            return size > 0;\n        }\n\n        public int compareTo(Section section) {\n            if (off != section.off) {\n                return off < section.off ? -1 : 1;\n            }\n            return 0;\n        }\n\n        @Override public String toString() {\n            return String.format(\"Section[type=%#x,off=%#x,size=%#x]\", type, off, size);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/TypeList.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex;\n\nimport com.taobao.atlas.dex.util.Unsigned;\n\npublic final class TypeList implements Comparable<TypeList> {\n\n    public static final TypeList EMPTY = new TypeList(null, Dex.EMPTY_SHORT_ARRAY);\n\n    private final Dex dex;\n    private final short[] types;\n\n    public TypeList(Dex dex, short[] types) {\n        this.dex = dex;\n        this.types = types;\n    }\n\n    public short[] getTypes() {\n        return types;\n    }\n\n    @Override public int compareTo(TypeList other) {\n        for (int i = 0; i < types.length && i < other.types.length; i++) {\n            if (types[i] != other.types[i]) {\n                return Unsigned.compare(types[i], other.types[i]);\n            }\n        }\n        return Unsigned.compare(types.length, other.types.length);\n    }\n\n    @Override public String toString() {\n        StringBuilder result = new StringBuilder();\n        result.append(\"(\");\n        for (int i = 0, typesLength = types.length; i < typesLength; i++) {\n            result.append(dex != null ? dex.typeNames().get(types[i]) : types[i]);\n        }\n        result.append(\")\");\n        return result.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/util/AnnotatedOutput.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex.util;\n\nimport com.taobao.atlas.dexmerge.dx.util.Output;\n\n/**\n * Interface for a binary output destination that may be augmented\n * with textual annotations.\n */\npublic interface AnnotatedOutput\n        extends Output {\n    /**\n     * Get whether this instance will actually keep annotations.\n     *\n     * @return {@code true} iff annotations are being kept\n     */\n    public boolean annotates();\n\n    /**\n     * Get whether this instance is intended to keep verbose annotations.\n     * Annotators may use the result of calling this method to inform their\n     * annotation activity.\n     *\n     * @return {@code true} iff annotations are to be verbose\n     */\n    public boolean isVerbose();\n\n    /**\n     * Add an annotation for the subsequent output. Any previously\n     * open annotation will be closed by this call, and the new\n     * annotation marks all subsequent output until another annotation\n     * call.\n     *\n     * @param msg {@code non-null;} the annotation message\n     */\n    public void annotate(String msg);\n\n    /**\n     * Add an annotation for a specified amount of subsequent\n     * output. Any previously open annotation will be closed by this\n     * call. If there is already pending annotation from one or more\n     * previous calls to this method, the new call \"consumes\" output\n     * after all the output covered by the previous calls.\n     *\n     * @param amt {@code >= 0;} the amount of output for this annotation to\n     * cover\n     * @param msg {@code non-null;} the annotation message\n     */\n    public void annotate(int amt, String msg);\n\n    /**\n     * End the most recent annotation. Subsequent output will be unannotated,\n     * until the next call to {@link #annotate}.\n     */\n    public void endAnnotation();\n\n    /**\n     * Get the maximum width of the annotated output. This is advisory:\n     * Implementations of this interface are encouraged to deal with too-wide\n     * output, but annotaters are encouraged to attempt to avoid exceeding\n     * the indicated width.\n     *\n     * @return {@code >= 1;} the maximum width\n     */\n    public int getAnnotationWidth();\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/util/ByteArrayByteInput.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex.util;\n\npublic final class ByteArrayByteInput implements ByteInput {\n\n    private final byte[] bytes;\n    private int position;\n\n    public ByteArrayByteInput(byte... bytes) {\n        this.bytes = bytes;\n    }\n\n    @Override public byte readByte() {\n        return bytes[position++];\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/util/ByteInput.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex.util;\n\n/**\n * A byte source.\n */\npublic interface ByteInput {\n\n    /**\n     * Returns a byte.\n     *\n     * @throws IndexOutOfBoundsException if all bytes have been read.\n     */\n    byte readByte();\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/util/ByteOutput.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex.util;\n\n/**\n * A byte sink.\n */\npublic interface ByteOutput {\n\n    /**\n     * Writes a byte.\n     *\n     * @throws IndexOutOfBoundsException if all bytes have been written.\n     */\n    void writeByte(int i);\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/util/ExceptionWithContext.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex.util;\n\nimport java.io.PrintStream;\nimport java.io.PrintWriter;\n\n/**\n * Exception which carries around structured context.\n */\npublic class ExceptionWithContext extends RuntimeException {\n    /** {@code non-null;} human-oriented context of the exception */\n    private StringBuffer context;\n\n    /**\n     * Augments the given exception with the given context, and return the\n     * result. The result is either the given exception if it was an\n     * {@link ExceptionWithContext}, or a newly-constructed exception if it\n     * was not.\n     *\n     * @param ex {@code non-null;} the exception to augment\n     * @param str {@code non-null;} context to add\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static ExceptionWithContext withContext(Throwable ex, String str) {\n        ExceptionWithContext ewc;\n\n        if (ex instanceof ExceptionWithContext) {\n            ewc = (ExceptionWithContext) ex;\n        } else {\n            ewc = new ExceptionWithContext(ex);\n        }\n\n        ewc.addContext(str);\n        return ewc;\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param message human-oriented message\n     */\n    public ExceptionWithContext(String message) {\n        this(message, null);\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param cause {@code null-ok;} exception that caused this one\n     */\n    public ExceptionWithContext(Throwable cause) {\n        this(null, cause);\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param message human-oriented message\n     * @param cause {@code null-ok;} exception that caused this one\n     */\n    public ExceptionWithContext(String message, Throwable cause) {\n        super((message != null) ? message :\n              (cause != null) ? cause.getMessage() : null,\n              cause);\n\n        if (cause instanceof ExceptionWithContext) {\n            String ctx = ((ExceptionWithContext) cause).context.toString();\n            context = new StringBuffer(ctx.length() + 200);\n            context.append(ctx);\n        } else {\n            context = new StringBuffer(200);\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void printStackTrace(PrintStream out) {\n        super.printStackTrace(out);\n        out.println(context);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void printStackTrace(PrintWriter out) {\n        super.printStackTrace(out);\n        out.println(context);\n    }\n\n    /**\n     * Adds a line of context to this instance.\n     *\n     * @param str {@code non-null;} new context\n     */\n    public void addContext(String str) {\n        if (str == null) {\n            throw new NullPointerException(\"str == null\");\n        }\n\n        context.append(str);\n        if (!str.endsWith(\"\\n\")) {\n            context.append('\\n');\n        }\n    }\n\n    /**\n     * Gets the context.\n     *\n     * @return {@code non-null;} the context\n     */\n    public String getContext() {\n        return context.toString();\n    }\n\n    /**\n     * Prints the message and context.\n     *\n     * @param out {@code non-null;} where to print to\n     */\n    public void printContext(PrintStream out) {\n        out.println(getMessage());\n        out.print(context);\n    }\n\n    /**\n     * Prints the message and context.\n     *\n     * @param out {@code non-null;} where to print to\n     */\n    public void printContext(PrintWriter out) {\n        out.println(getMessage());\n        out.print(context);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/util/FileUtils.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex.util;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\n\n/**\n * File I/O utilities.\n */\npublic final class FileUtils {\n    private FileUtils() {\n    }\n\n    /**\n     * Reads the named file, translating {@link IOException} to a\n     * {@link RuntimeException} of some sort.\n     *\n     * @param fileName {@code non-null;} name of the file to read\n     * @return {@code non-null;} contents of the file\n     */\n    public static byte[] readFile(String fileName) {\n        File file = new File(fileName);\n        return readFile(file);\n    }\n\n    /**\n     * Reads the given file, translating {@link IOException} to a\n     * {@link RuntimeException} of some sort.\n     *\n     * @param file {@code non-null;} the file to read\n     * @return {@code non-null;} contents of the file\n     */\n    public static byte[] readFile(File file) {\n        if (!file.exists()) {\n            throw new RuntimeException(file + \": file not found\");\n        }\n\n        if (!file.isFile()) {\n            throw new RuntimeException(file + \": not a file\");\n        }\n\n        if (!file.canRead()) {\n            throw new RuntimeException(file + \": file not readable\");\n        }\n\n        long longLength = file.length();\n        int length = (int) longLength;\n        if (length != longLength) {\n            throw new RuntimeException(file + \": file too long\");\n        }\n\n        byte[] result = new byte[length];\n\n        try {\n            FileInputStream in = new FileInputStream(file);\n            int at = 0;\n            while (length > 0) {\n                int amt = in.read(result, at, length);\n                if (amt == -1) {\n                    throw new RuntimeException(file + \": unexpected EOF\");\n                }\n                at += amt;\n                length -= amt;\n            }\n            in.close();\n        } catch (IOException ex) {\n            throw new RuntimeException(file + \": trouble reading\", ex);\n        }\n\n        return result;\n    }\n\n    /**\n     * Returns true if {@code fileName} names a .zip, .jar, or .apk.\n     */\n    public static boolean hasArchiveSuffix(String fileName) {\n        return fileName.endsWith(\".zip\")\n                || fileName.endsWith(\".jar\")\n                || fileName.endsWith(\".apk\");\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/util/Iterators.java",
    "content": "package com.taobao.atlas.dex.util;\n\nimport java.util.Comparator;\nimport java.util.Iterator;\nimport java.util.PriorityQueue;\nimport java.util.Queue;\n\n/**\n * 遍历工具类\n * Created by shenghua.nish on 2016-01-05 下午4:26.\n */\npublic class Iterators {\n\n    private static class MergingIterator<T> implements Iterator<T>{\n\n        final Queue<PeekingIterator<T>> queue;\n\n        public MergingIterator(Iterable<? extends Iterator<? extends T>> iterators,\n                               final Comparator<? super T> itemComparator){\n            // A comparator that's used by the heap, allowing the heap\n            // to be sorted based on the top of each iterator.\n            Comparator<PeekingIterator<T>> heapComparator = new Comparator<PeekingIterator<T>>() {\n\n                @Override\n                public int compare(PeekingIterator<T> o1, PeekingIterator<T> o2) {\n                    return itemComparator.compare(o1.peek(), o2.peek());\n                }\n            };\n\n            queue = new PriorityQueue<PeekingIterator<T>>(2, heapComparator);\n            for (Iterator<? extends T> iterator : iterators) {\n                if (iterator.hasNext()) {\n                    queue.add(Iterators.peekingIterator(iterator));\n                }\n            }\n        }\n\n        public boolean hasNext() {\n            return !queue.isEmpty();\n        }\n\n        public T next() {\n            PeekingIterator<T> nextIter = queue.remove();\n            T next = nextIter.next();\n            if (nextIter.hasNext()) {\n                queue.add(nextIter);\n            }\n            return next;\n        }\n\n        @Override\n        public void remove() {\n            throw new UnsupportedOperationException();\n        }\n    }\n\n    public static <T> MergingIterator<T> mergeSorted(Iterable<? extends Iterator<? extends T>> iterators,\n                                                     Comparator<? super T> comparator) {\n        checkNotNull(iterators);\n        checkNotNull(comparator);\n        return new MergingIterator<T>(iterators, comparator);\n    }\n\n    public static <T> PeekingIterator<T> peekingIterator(Iterator<? extends T> iterator) {\n        if (iterator instanceof PeekingImpl) {\n            // Safe to cast <? extends T> to <T> because PeekingImpl only uses T\n            // covariantly (and cannot be subclassed to add non-covariant uses).\n            @SuppressWarnings(\"unchecked\")\n            PeekingImpl<T> peeking = (PeekingImpl<T>) iterator;\n            return peeking;\n        }\n        return new PeekingImpl<T>(iterator);\n    }\n\n    /**\n     * Implementation of PeekingIterator that avoids peeking unless necessary.\n     */\n    private static class PeekingImpl<E> implements PeekingIterator<E> {\n\n        private final Iterator<? extends E> iterator;\n        private boolean                     hasPeeked;\n        private E                           peekedElement;\n\n        public PeekingImpl(Iterator<? extends E> iterator){\n            this.iterator = checkNotNull(iterator);\n        }\n\n        @Override\n        public boolean hasNext() {\n            return hasPeeked || iterator.hasNext();\n        }\n\n        @Override\n        public E next() {\n            if (!hasPeeked) {\n                return iterator.next();\n            }\n            E result = peekedElement;\n            hasPeeked = false;\n            peekedElement = null;\n            return result;\n        }\n\n        @Override\n        public void remove() {\n            checkState(!hasPeeked, \"Can't remove after you've peeked at next\");\n            iterator.remove();\n        }\n\n        @Override\n        public E peek() {\n            if (!hasPeeked) {\n                peekedElement = iterator.next();\n                hasPeeked = true;\n            }\n            return peekedElement;\n        }\n    }\n\n    /**\n     * Ensures that an object reference passed as a parameter to the calling method is not null.\n     *\n     * @param reference an object reference\n     * @return the non-null reference that was validated\n     * @throws NullPointerException if {@code reference} is null\n     */\n    public static <T> T checkNotNull(T reference) {\n        if (reference == null) {\n            throw new NullPointerException();\n        }\n        return reference;\n    }\n\n    /**\n     * Ensures the truth of an expression involving the state of the calling instance, but not\n     * involving any parameters to the calling method.\n     *\n     * @param expression a boolean expression\n     * @param errorMessage the exception message to use if the check fails; will be converted to a\n     *     string using {@link String#valueOf(Object)}\n     * @throws IllegalStateException if {@code expression} is false\n     */\n    public static void checkState(boolean expression, Object errorMessage) {\n        if (!expression) {\n            throw new IllegalStateException(String.valueOf(errorMessage));\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/util/NaturalOrdering.java",
    "content": "package com.taobao.atlas.dex.util;\n\nimport java.util.Comparator;\n\n/**\n * Created by shenghua.nish on 2016-01-05 下午4:41.\n */\npublic class NaturalOrdering implements Comparator<Comparable> {\n    @Override\n    public int compare(Comparable left, Comparable right) {\n        return left.compareTo(right);\n\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/util/PeekingIterator.java",
    "content": "package com.taobao.atlas.dex.util;\n\n\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\n\n/**\n * An iterator that supports a one-element lookahead while iterating.\n *\n * <p>See the Guava User Guide article on <a href=\n * \"http://code.google.com/p/guava-libraries/wiki/CollectionHelpersExplained#PeekingIterator\">\n * {@code PeekingIterator}</a>.\n *\n * @author Mick Killianey\n * @since 2.0 (imported from Google Collections Library)\n */\npublic interface PeekingIterator<E> extends Iterator<E> {\n    /**\n     * Returns the next element in the iteration, without advancing the iteration.\n     *\n     * <p>Calls to {@code peek()} should not change the state of the iteration,\n     * except that it <i>may</i> prevent removal of the most recent element via\n     * {@link #remove()}.\n     *\n     * @throws NoSuchElementException if the iteration has no more elements\n     *     according to {@link #hasNext()}\n     */\n    E peek();\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p>The objects returned by consecutive calls to {@link #peek()} then {@link\n     * #next()} are guaranteed to be equal to each other.\n     */\n    @Override\n    E next();\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p>Implementations may or may not support removal when a call to {@link\n     * #peek()} has occurred since the most recent call to {@link #next()}.\n     *\n     * @throws IllegalStateException if there has been a call to {@link #peek()}\n     *     since the most recent call to {@link #next()} and this implementation\n     *     does not support this sequence of calls (optional)\n     */\n    @Override\n    void remove();\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dex/util/Unsigned.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dex.util;\n\n/**\n * Unsigned arithmetic over Java's signed types.\n */\npublic final class Unsigned {\n    private Unsigned() {}\n\n    public static int compare(short ushortA, short ushortB) {\n        if (ushortA == ushortB) {\n            return 0;\n        }\n        int a = ushortA & 0xFFFF;\n        int b = ushortB & 0xFFFF;\n        return a < b ? -1 : 1;\n    }\n\n    public static int compare(int uintA, int uintB) {\n        if (uintA == uintB) {\n            return 0;\n        }\n        long a = uintA & 0xFFFFFFFFL;\n        long b = uintB & 0xFFFFFFFFL;\n        return a < b ? -1 : 1;\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/DexMergeClient.java",
    "content": "package com.taobao.atlas.dexmerge;\n\nimport android.content.*;\nimport android.os.IBinder;\nimport android.os.RemoteException;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.util.Log;\n\nimport java.util.List;\n\n/**\n * Created by xieguo.xg on 1/21/16.\n */\npublic class DexMergeClient {\n\n    public static final int REMOTE_TIMEOUT = 60 * 1000;\n\n    private Object lock = new Object();\n\n//    private Object mergeLock = new Object();\n\n    private boolean isFinished;\n\n    private boolean isBinded;\n\n    private long mStartTime;\n\n    private final static String TAG = \"DexMergeClient\";\n\n    private boolean isTimeout = true; // Whether unlock caused by timeout\n\n    private boolean isBinderDied = false;\n\n    private final static int numBinderDieTries = 3;\n    IDexMergeBinder dexMergeBinder;\n\n    private IBinder.DeathRecipient mDeathRecipient = new MyServiceDeathHandler();\n\n    private MergeCallback mergeCallBack;\n\n    public DexMergeClient(MergeCallback mergeCallBack) {\n        this.mergeCallBack = mergeCallBack;\n        IntentFilter intentFilter = new IntentFilter(\"com.taobao.atlas.intent.PATCH_VERSION\");\n        RuntimeVariables.androidApplication.registerReceiver(new PatchVersionReceiver(),intentFilter);\n    }\n\n    public boolean prepare() {\n        Intent intent = new Intent();\n        intent.setClassName(RuntimeVariables.androidApplication,\n                \"com.taobao.atlas.dexmerge.DexMergeService\");\n\n        mStartTime = System.currentTimeMillis();\n\n        /**\n         * try to Bind dexmerge service\n         */\n        if (!RuntimeVariables.androidApplication.bindService(intent,\n                conn,\n                Context.BIND_AUTO_CREATE |\n                        Context.BIND_IMPORTANT)) {\n            return false;\n        }\n\n        /**\n         * Block wait service bind\n         */\n        if (!isBinded) {\n            try {\n                synchronized (lock) {\n                    // 10 minutes timeout\n                    lock.wait(REMOTE_TIMEOUT);\n                }\n            } catch (InterruptedException e) {\n            }\n        }\n\n\n        if (!isBinded) {\n\n            /**\n             * unbind once timeout\n             */\n//            AppMonitor.Counter.commit(\"dexMerge\", \"RemoteException\", \"bind timeout \" +\n//                    VERSION.SDK_INT +\n//                    \" \" +\n//                    (mPowerManager.isScreenOn() ? 1 : 0), 1);\n            RuntimeVariables.androidApplication.unbindService(conn);\n        }\n        return isBinded;\n    }\n\n    public void unPrepare() {\n        RuntimeVariables.androidApplication.unbindService(conn);\n    }\n\n\n    public boolean dexMerge(String patchFilePath, List toMergeList, boolean diffBundleDex) {\n        if (toMergeList.size() == 0) {\n            return true;\n        }\n        mStartTime = System.currentTimeMillis();\n\n        if (!dexMergeInternal(patchFilePath,toMergeList, diffBundleDex) && isBinderDied) {\n\n            /**\n             * handle binder died case\n             */\n            for (int i = 0; i < numBinderDieTries && isBinderDied; i++) {\n                isBinderDied = false;\n                if (prepare() == false) {\n                    return isFinished;\n                }\n\n                if (dexMergeInternal(patchFilePath,toMergeList, diffBundleDex)) {\n\n                    break;\n                }\n            }\n        }\n\n        return isFinished;\n\n    }\n\n    private boolean dexMergeInternal(String patchFilePath,List toMergeList, boolean diffBundleDex) {\n        isFinished = false;\n\n        try {\n            dexMergeBinder.dexMerge(patchFilePath,toMergeList, diffBundleDex);\n//            synchronized (mergeLock){\n//                try {\n//                    mergeLock.wait();\n//                } catch (InterruptedException e) {\n//                    e.printStackTrace();\n//                }\n//            }\n        } catch (RemoteException e) {\n            e.printStackTrace();\n        }\n\n\n        return isFinished;\n    }\n\n\n    ServiceConnection conn = new ServiceConnection() {\n        @Override\n        public void onServiceDisconnected(ComponentName name) {\n        }\n\n        @Override\n        public void onServiceConnected(ComponentName name, IBinder service) {\n            //返回一个IDexMergeBinder对象\n            Log.d(TAG, \"Get binder\" + (System.currentTimeMillis() - mStartTime) + \" ms\");\n            dexMergeBinder = IDexMergeBinder.Stub.asInterface(service);\n\n            isBinded = true;\n\n            //注册回调接口\n            try {\n                dexMergeBinder.registerListener(new IDexMergeCallback.Stub() {\n\n                    @Override\n                    public void onMergeFinish(String filePath, boolean result, String reason) {\n                        if (!result) {\n                            if (mergeCallBack != null) {\n                                mergeCallBack.onMergeResult(false, filePath);\n                            }\n                            Log.e(TAG, \"merge Failed:\" + filePath);\n\n                        } else if (mergeCallBack != null) {\n\n                            mergeCallBack.onMergeResult(true, filePath);\n                        }\n\n                    }\n\n                    @Override\n                    public void onMergeAllFinish(boolean result, String reason) {\n                        isFinished = result;\n                        synchronized (lock) {\n                            isTimeout = false;\n                            lock.notifyAll();\n                        }\n\n                        Log.d(TAG, \"dexMerge  \" + result + (System.currentTimeMillis() - mStartTime) + \" ms\");\n\n\n                    }\n\n                });\n            } catch (RemoteException e) {\n\n                isTimeout = false;\n                Log.d(TAG, \"dexMerge registerListener RemoteException\" +\n                        (System.currentTimeMillis() - mStartTime) +\n                        \" ms\");\n                return;\n\n            } finally {\n                synchronized (lock) {\n                    lock.notifyAll();\n                }\n            }\n\n            try {\n                service.linkToDeath(mDeathRecipient, 0);\n            } catch (RemoteException e) {\n                // TODO Auto-generated catch block\n                e.printStackTrace();\n            }\n        }\n    };\n\n\n    private class MyServiceDeathHandler implements IBinder.DeathRecipient {\n        public MyServiceDeathHandler() {\n        }\n\n        @Override\n        public void binderDied() {\n            synchronized (lock) {\n                isTimeout = false;\n                isBinderDied = true;\n                lock.notifyAll();\n//                mergeLock.notifyAll();\n            }\n            Log.e(TAG, \"dexMerge service died\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/DexMergeService.java",
    "content": "package com.taobao.atlas.dexmerge;\n\nimport android.app.Service;\nimport android.content.Intent;\nimport android.os.IBinder;\nimport android.os.RemoteException;\n\nimport java.util.List;\nimport java.util.concurrent.ExecutionException;\n\n/**\n * @author zhayu.ll\n */\npublic class DexMergeService extends Service {\n\n    IDexMergeCallback mCallback = null;\n\n    @Override\n    public IBinder onBind(Intent intent) {\n        return mBinder;\n    }\n\n    private final IDexMergeBinder.Stub mBinder = new IDexMergeBinder.Stub() {\n\n        @Override\n        public void dexMerge(String patchFilePath,List<MergeObject> list, boolean b) throws RemoteException {\n            MergeExcutorServices mergeExcutorServices = new MergeExcutorServices(mCallback);\n            try {\n                mergeExcutorServices.excute(patchFilePath,list, b);\n            } catch (ExecutionException e) {\n                e.printStackTrace();\n                if (mCallback!= null){\n                    mCallback.onMergeAllFinish(false,\"ExecutionException\");\n                }\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n                if (mCallback!= null){\n                    mCallback.onMergeAllFinish(false,\"InterruptedException\");\n                }\n            }\n        }\n\n\n        public void registerListener(IDexMergeCallback cb) {\n            if (cb != null) {\n                mCallback = cb;\n            }\n        }\n    };\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/IDexMergeBinder.java",
    "content": "/*\n * This file is auto-generated.  DO NOT MODIFY.\n * Original file: /Users/lilong/Documents/atlas/atlas-update/src/main/aidl/com/taobao/atlas/dexmerge/IDexMergeBinder.aidl\n */\npackage com.taobao.atlas.dexmerge;\n/**\n * Created by xieguo.xg on 1/20/16.\n */\npublic interface IDexMergeBinder extends android.os.IInterface\n{\n/** Local-side IPC implementation stub class. */\npublic static abstract class Stub extends android.os.Binder implements IDexMergeBinder\n{\nprivate static final String DESCRIPTOR = \"com.taobao.atlas.dexmerge.IDexMergeBinder\";\n/** Construct the stub at attach it to the interface. */\npublic Stub()\n{\nthis.attachInterface(this, DESCRIPTOR);\n}\n/**\n * Cast an IBinder object into an com.taobao.atlas.dexmerge.IDexMergeBinder interface,\n * generating a proxy if needed.\n */\npublic static IDexMergeBinder asInterface(android.os.IBinder obj)\n{\nif ((obj==null)) {\nreturn null;\n}\nandroid.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);\nif (((iin!=null)&&(iin instanceof IDexMergeBinder))) {\nreturn ((IDexMergeBinder)iin);\n}\nreturn new Proxy(obj);\n}\n@Override public android.os.IBinder asBinder()\n{\nreturn this;\n}\n@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException\n{\nswitch (code)\n{\ncase INTERFACE_TRANSACTION:\n{\nreply.writeString(DESCRIPTOR);\nreturn true;\n}\ncase TRANSACTION_dexMerge:\n{\ndata.enforceInterface(DESCRIPTOR);\nString _arg0;\n_arg0 = data.readString();\njava.util.List<MergeObject> _arg1;\n_arg1 = data.createTypedArrayList(MergeObject.CREATOR);\nboolean _arg2;\n_arg2 = (0!=data.readInt());\nthis.dexMerge(_arg0, _arg1, _arg2);\nreply.writeNoException();\nreturn true;\n}\ncase TRANSACTION_registerListener:\n{\ndata.enforceInterface(DESCRIPTOR);\nIDexMergeCallback _arg0;\n_arg0 = IDexMergeCallback.Stub.asInterface(data.readStrongBinder());\nthis.registerListener(_arg0);\nreply.writeNoException();\nreturn true;\n}\n}\nreturn super.onTransact(code, data, reply, flags);\n}\nprivate static class Proxy implements IDexMergeBinder\n{\nprivate android.os.IBinder mRemote;\nProxy(android.os.IBinder remote)\n{\nmRemote = remote;\n}\n@Override public android.os.IBinder asBinder()\n{\nreturn mRemote;\n}\npublic String getInterfaceDescriptor()\n{\nreturn DESCRIPTOR;\n}\n@Override public void dexMerge(String patchFilePath, java.util.List<MergeObject> toMergeList, boolean diffBundleDex) throws android.os.RemoteException\n{\nandroid.os.Parcel _data = android.os.Parcel.obtain();\nandroid.os.Parcel _reply = android.os.Parcel.obtain();\ntry {\n_data.writeInterfaceToken(DESCRIPTOR);\n_data.writeString(patchFilePath);\n_data.writeTypedList(toMergeList);\n_data.writeInt(((diffBundleDex)?(1):(0)));\nmRemote.transact(Stub.TRANSACTION_dexMerge, _data, _reply, 0);\n_reply.readException();\n}\nfinally {\n_reply.recycle();\n_data.recycle();\n}\n}\n@Override public void registerListener(IDexMergeCallback listener) throws android.os.RemoteException\n{\nandroid.os.Parcel _data = android.os.Parcel.obtain();\nandroid.os.Parcel _reply = android.os.Parcel.obtain();\ntry {\n_data.writeInterfaceToken(DESCRIPTOR);\n_data.writeStrongBinder((((listener!=null))?(listener.asBinder()):(null)));\nmRemote.transact(Stub.TRANSACTION_registerListener, _data, _reply, 0);\n_reply.readException();\n}\nfinally {\n_reply.recycle();\n_data.recycle();\n}\n}\n}\nstatic final int TRANSACTION_dexMerge = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);\nstatic final int TRANSACTION_registerListener = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);\n}\npublic void dexMerge(String patchFilePath, java.util.List<MergeObject> toMergeList, boolean diffBundleDex) throws android.os.RemoteException;\npublic void registerListener(IDexMergeCallback listener) throws android.os.RemoteException;\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/IDexMergeCallback.java",
    "content": "/*\n * This file is auto-generated.  DO NOT MODIFY.\n * Original file: /Users/lilong/Documents/atlas/atlas-update/src/main/aidl/com/taobao/atlas/dexmerge/IDexMergeCallback.aidl\n */\npackage com.taobao.atlas.dexmerge;\n/**\n * Created by xieguo.xg on 1/20/16.\n */\npublic interface IDexMergeCallback extends android.os.IInterface\n{\n/** Local-side IPC implementation stub class. */\npublic static abstract class Stub extends android.os.Binder implements IDexMergeCallback\n{\nprivate static final String DESCRIPTOR = \"com.taobao.atlas.dexmerge.IDexMergeCallback\";\n/** Construct the stub at attach it to the interface. */\npublic Stub()\n{\nthis.attachInterface(this, DESCRIPTOR);\n}\n/**\n * Cast an IBinder object into an com.taobao.atlas.dexmerge.IDexMergeCallback interface,\n * generating a proxy if needed.\n */\npublic static IDexMergeCallback asInterface(android.os.IBinder obj)\n{\nif ((obj==null)) {\nreturn null;\n}\nandroid.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);\nif (((iin!=null)&&(iin instanceof IDexMergeCallback))) {\nreturn ((IDexMergeCallback)iin);\n}\nreturn new Proxy(obj);\n}\n@Override public android.os.IBinder asBinder()\n{\nreturn this;\n}\n@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException\n{\nswitch (code)\n{\ncase INTERFACE_TRANSACTION:\n{\nreply.writeString(DESCRIPTOR);\nreturn true;\n}\ncase TRANSACTION_onMergeFinish:\n{\ndata.enforceInterface(DESCRIPTOR);\nString _arg0;\n_arg0 = data.readString();\nboolean _arg1;\n_arg1 = (0!=data.readInt());\nString _arg2;\n_arg2 = data.readString();\nthis.onMergeFinish(_arg0, _arg1, _arg2);\nreply.writeNoException();\nreturn true;\n}\ncase TRANSACTION_onMergeAllFinish:\n{\ndata.enforceInterface(DESCRIPTOR);\nboolean _arg0;\n_arg0 = (0!=data.readInt());\nString _arg1;\n_arg1 = data.readString();\nthis.onMergeAllFinish(_arg0, _arg1);\nreply.writeNoException();\nreturn true;\n}\n}\nreturn super.onTransact(code, data, reply, flags);\n}\nprivate static class Proxy implements IDexMergeCallback\n{\nprivate android.os.IBinder mRemote;\nProxy(android.os.IBinder remote)\n{\nmRemote = remote;\n}\n@Override public android.os.IBinder asBinder()\n{\nreturn mRemote;\n}\npublic String getInterfaceDescriptor()\n{\nreturn DESCRIPTOR;\n}\n@Override public void onMergeFinish(String filePath, boolean result, String reason) throws android.os.RemoteException\n{\nandroid.os.Parcel _data = android.os.Parcel.obtain();\nandroid.os.Parcel _reply = android.os.Parcel.obtain();\ntry {\n_data.writeInterfaceToken(DESCRIPTOR);\n_data.writeString(filePath);\n_data.writeInt(((result)?(1):(0)));\n_data.writeString(reason);\nmRemote.transact(Stub.TRANSACTION_onMergeFinish, _data, _reply, 0);\n_reply.readException();\n}\nfinally {\n_reply.recycle();\n_data.recycle();\n}\n}\n@Override public void onMergeAllFinish(boolean result, String reason) throws android.os.RemoteException\n{\nandroid.os.Parcel _data = android.os.Parcel.obtain();\nandroid.os.Parcel _reply = android.os.Parcel.obtain();\ntry {\n_data.writeInterfaceToken(DESCRIPTOR);\n_data.writeInt(((result)?(1):(0)));\n_data.writeString(reason);\nmRemote.transact(Stub.TRANSACTION_onMergeAllFinish, _data, _reply, 0);\n_reply.readException();\n}\nfinally {\n_reply.recycle();\n_data.recycle();\n}\n}\n}\nstatic final int TRANSACTION_onMergeFinish = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);\nstatic final int TRANSACTION_onMergeAllFinish = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);\n}\npublic void onMergeFinish(String filePath, boolean result, String reason) throws android.os.RemoteException;\npublic void onMergeAllFinish(boolean result, String reason) throws android.os.RemoteException;\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/MergeCallback.java",
    "content": "package com.taobao.atlas.dexmerge;\n\n/**\n * Created by wuzhong on 2016/11/22.\n */\n\npublic interface MergeCallback {\n\n    public void onMergeResult(boolean result, String bundleName);\n\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/MergeConstants.java",
    "content": "package com.taobao.atlas.dexmerge;\n\n/**\n * MergeConstants\n *\n * @author zhayu.ll\n * @date 18/8/15\n */\npublic class MergeConstants {\n\n\n    public static final String MAIN_DEX = \"com.taobao.maindex\";\n\n    public static final String CLASS = \"classes\";\n\n    public static final String DEX_SUFFIX = \".dex\";\n\n    public static final String SO_SUFFIX = \".so\";\n\n    public static final String DEX_PATCH_META = \"DEX-PATCH-INF\";\n\n    public static final String NO_PATCH_DEX = \"NO_PATCH_DEX\";\n\n    public static final String PATCH_VERSION = \"PATCH_VERSION\";\n\n\n}\n\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/MergeException.java",
    "content": "package com.taobao.atlas.dexmerge;\n\n/**\n * Created by xieguo on 15-9-16.\n */\npublic class MergeException extends Exception{\n    /**\n     * Nested exception.\n     */\n    private transient Throwable throwable;\n\n\n    /**\n     * Creates a <tt>LowDiskException</tt> that wraps another exception.\n     *\n     * @param msg The associated message.\n     * @param throwable The nested exception.\n     */\n    public MergeException(String msg, Throwable throwable)\n    {\n        super(msg, throwable);\n        this.throwable = throwable;\n    }\n\n    /**\n     * Creates a <tt>LowDiskException</tt> object with the specified message.\n     *\n     * @param msg The message.\n     */\n    public MergeException(String msg)\n    {\n        super(msg);\n        this.throwable = null;\n    }\n\n    /**\n     * Returns any nested exceptions included in this exception.\n     *\n     * @return The nested exception; <tt>null</tt> if there is\n     * no nested exception.\n     */\n    public Throwable getNestedException()\n    {\n        return(throwable);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/MergeExcutorServices.java",
    "content": "package com.taobao.atlas.dexmerge;\n\nimport android.os.RemoteException;\nimport android.util.Log;\nimport com.taobao.atlas.dex.Dex;\nimport com.taobao.atlas.dexmerge.dx.merge.CollisionPolicy;\nimport com.taobao.atlas.dexmerge.dx.merge.DexMerger;\nimport io.reactivex.Observable;\nimport io.reactivex.ObservableSource;\nimport io.reactivex.Observer;\nimport io.reactivex.disposables.Disposable;\nimport io.reactivex.functions.Consumer;\nimport io.reactivex.functions.Function;\nimport io.reactivex.plugins.RxJavaPlugins;\nimport io.reactivex.schedulers.Schedulers;\n\nimport java.io.*;\nimport java.util.*;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.ExecutionException;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n/**\n * Created by lilong on 16/7/5.\n */\npublic class MergeExcutorServices {\n\n    private IDexMergeCallback mCallback = null;\n    public static ZipFile sZipPatch;\n    private static final String TAG = \"mergeTask\";\n    HashMap<String, List<ZipEntry>> bundleEntryGroup = new HashMap<String, List<ZipEntry>>();\n\n    public static OS os = OS.mac;\n\n\n    public MergeExcutorServices(IDexMergeCallback mCallback) throws RemoteException {\n        this.mCallback = mCallback;\n\n    }\n\n    public void excute(String patchFilePath, final List<MergeObject> list, final boolean b) throws ExecutionException, InterruptedException {\n        io.reactivex.Observable.just(patchFilePath).map(new Function<String, Map>() {\n            @Override\n            public Map<String, List<ZipEntry>> apply(String s) throws Exception {\n                try {\n                    sZipPatch = new ZipFile(s);\n                    Enumeration<? extends ZipEntry> zes = sZipPatch.entries();\n                    ZipEntry entry = null;\n                    String key = null;\n\n                    while (zes.hasMoreElements()) {\n                        entry = zes.nextElement();\n                        if (entry.getName().equals(\"libcom_taobao_maindex.so\")) {\n                            List<ZipEntry> mainDex = new ArrayList<>();\n                            mainDex.add(entry);\n                            bundleEntryGroup.put(\"com_taobao_maindex\", mainDex);\n                        } else if (entry.getName().startsWith(\"lib\")) {\n                            if (entry.getName().indexOf(\"/\") != -1) {\n                                key = entry.getName().substring(3, entry.getName().indexOf(\"/\"));\n                                os = OS.mac;\n                            } else if (entry.getName().indexOf(\"\\\\\") != -1) {\n                                key = entry.getName().substring(3, entry.getName().indexOf(\"\\\\\"));\n                                os = OS.windows;\n\n                            }\n                            List<ZipEntry> bundleEntry = null;\n                            if ((bundleEntry = bundleEntryGroup.get(key)) == null) {\n                                bundleEntry = new ArrayList<ZipEntry>();\n                                bundleEntryGroup.put(key, bundleEntry);\n                                bundleEntry.add(entry);\n                            } else {\n                                bundleEntryGroup.get(key).add(entry);\n                            }\n                        }\n                    }\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n                return bundleEntryGroup;\n            }\n\n        }).subscribe(new io.reactivex.Observer<Map>() {\n\n            @Override\n            public void onError(Throwable e) {\n                try {\n                    mCallback.onMergeAllFinish(false,e.getMessage());\n                } catch (RemoteException e1) {\n                    e1.printStackTrace();\n                }\n\n            }\n\n            @Override\n            public void onComplete() {\n                Log.e(\"MergeExcutorServices\",\"merge bundle size:\"+bundleEntryGroup.size());\n\n            }\n\n            @Override\n            public void onSubscribe(Disposable disposable) {\n\n            }\n\n            @Override\n            public void onNext(Map map) {\n\n            }\n\n        });\n\n        MergeTask[]tasks = new MergeTask[list.size()];\n        for (int i =0;i < list.size(); i ++){\n            MergeTask mergeTask = new MergeTask(new File(list.get(i).originalFile),bundleEntryGroup.get(list.get(i).patchName.replace(\".\",\"_\")),list.get(i).patchName, new File(list.get(i).mergeFile), b);\n            tasks[i] = mergeTask;\n        }\n        System.setProperty(\"rx2.computation-threads\",String.valueOf(Runtime.getRuntime().availableProcessors()/2));\n        RxJavaPlugins.setErrorHandler(new Consumer<Throwable>() {\n            @Override\n            public void accept(Throwable throwable) throws Exception {\n                mCallback.onMergeAllFinish(false,throwable.getMessage());\n            }\n        });\n        final CountDownLatch countDownLatch = new CountDownLatch(1);\n        try {\n            Observable.fromArray(tasks).flatMap(new Function<MergeTask, ObservableSource<File>>() {\n                @Override\n                public ObservableSource<File> apply(MergeTask mergeTask) throws Exception {\n                    return Observable.just(mergeTask).map(new Function<MergeTask, File>() {\n                        @Override\n                        public File apply(MergeTask mergeTask) throws Exception {\n                            File file = null;\n                            try {\n                                file = mergeTask.call();\n                            }catch (IllegalStateException e){\n                                e.printStackTrace();\n                            }\n                            return file;\n                        }\n                    }).subscribeOn(Schedulers.computation());\n                }\n            }).subscribe(new Observer<File>() {\n\n                @Override\n                public void onError(Throwable e) {\n                    try {\n                        mCallback.onMergeAllFinish(false,e.getMessage());\n                    } catch (RemoteException e1) {\n                        e1.printStackTrace();\n                    }\n                    countDownLatch.countDown();\n                }\n\n                @Override\n                public void onComplete() {\n                    try {\n                        mCallback.onMergeAllFinish(true,null);\n                    } catch (RemoteException e) {\n                        e.printStackTrace();\n                    }\n                    countDownLatch.countDown();\n                }\n\n                @Override\n                public void onSubscribe(Disposable disposable) {\n                    if (disposable.isDisposed()){\n                        onError(new IllegalStateException(\"connection closed!\"));\n                    }\n\n                }\n\n                @Override\n                public void onNext(File file) {\n                    if (file!= null && file.exists()){\n                        try {\n                            mCallback.onMergeFinish(file.getAbsolutePath(),true,null);\n                        } catch (RemoteException e) {\n                            e.printStackTrace();\n                        }\n                    }\n\n                }\n            });\n            countDownLatch.await();\n        }catch (Throwable e){\n            try {\n                mCallback.onMergeAllFinish(false,e.getMessage());\n            } catch (RemoteException e1) {\n                e1.printStackTrace();\n            }\n        }finally {\n            Schedulers.shutdown();\n\n            if (sZipPatch != null){\n                try {\n                    sZipPatch.close();\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n            }\n        }\n\n        }\n\n\n\n\n    public class MergeTask implements Callable<File> {\n\n\n        public MergeTask(File sourceFile, List<ZipEntry> patchEntries,String patchName, File outFile, boolean diff) {\n            this.sourceFile = sourceFile;\n            this.patchName = patchName;\n            this.patchEntries = patchEntries;\n            this.outFile = outFile;\n            this.diffDex = diff;\n        }\n\n        private File sourceFile;\n        private String patchName;\n        private File outFile;\n        private List<ZipEntry> patchEntries;\n        private boolean diffDex;\n\n\n        @Override\n        public File call() throws IOException, MergeException {\n            MergeTool.mergePrepare(sourceFile, patchEntries,patchName, outFile, diffDex, new PrepareCallBack() {\n\n                @Override\n                public void prepareMerge(String patchBundleName,ZipFile sourceFile, ZipEntry patchDex, OutputStream newDexStream) throws IOException {\n                    boolean classMerge = false;\n                    InputStream[] inputStreams = new InputStream[2];\n                    try {\n                        inputStreams[0] = sourceFile.getInputStream(new ZipEntry(\"classes.dex\"));\n                        inputStreams[1] = MergeExcutorServices.sZipPatch.getInputStream(patchDex);\n//                        if (patchDex.getName().endsWith(\".tdex\")){\n//                            classMerge = true;\n//                        }\n                        dexMergeInternal(inputStreams, newDexStream,patchBundleName);\n\n                    } catch (IOException e) {\n                        e.printStackTrace();\n                    } finally {\n                        for (InputStream inputStream:inputStreams){\n                            if (inputStream != null){\n                                inputStream.close();\n                            }\n\n                        }\n\n                    }\n\n                }\n\n            });\n            return outFile;\n        }\n    }\n\n\n    private void dexMergeInternal(InputStream[] inputStreams, OutputStream newDexStream, String bundleName) throws IOException {\n        FileOutputStream fileOutputStream = null;\n        if (inputStreams[0] == null || inputStreams[1] == null) {\n            try {\n                mCallback.onMergeFinish(bundleName,false, \"argNUll\");\n            } catch (RemoteException e) {\n                e.printStackTrace();\n            }\n            return ;\n        }\n\n        try {\n\n            //方式一\n//            DexPatchApplier dexPatchApplier = new DexPatchApplier(inputStreams[0],inputStreams[1]);\n//            dexPatchApplier.executeAndSaveTo(newDexStream);\n            //方式二\n            Dex dex1 = new Dex(inputStreams[1]);\n            Dex dex2 = new Dex(inputStreams[0]);\n            List<Dex> dexs = new ArrayList<Dex>();\n            dexs.add(dex1);\n            dexs.add(dex2);\n            DexMerger mDexMerge = new DexMerger(new Dex[]{dex1, dex2}, CollisionPolicy.KEEP_FIRST);\n            mDexMerge.setCompactWasteThreshold(1);\n            Dex outDex = mDexMerge.merge();\n            outDex.writeTo(newDexStream);\n            newDexStream.flush();\n\n        }finally {\n            if (fileOutputStream != null){\n                try {\n                    fileOutputStream.close();\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n            }\n\n        }\n    }\n\n\n    public interface PrepareCallBack {\n\n        void prepareMerge(String patchBundleName,ZipFile sourceFile, ZipEntry patchDex, OutputStream newDexStream) throws IOException;\n\n    }\n    enum OS{\n        mac,windows,linux\n    }\n\n\n    public static void main(String []args) throws InterruptedException {\n        final MergeObject mergeTask = new MergeObject(null,null,null);\n        final MergeObject mergeTask1 = new MergeObject(null,null,null);\n\n        String[]aa = new String[]{\"a\",\"b\",\"c\",\"d\",\"e\"};\n        final CountDownLatch countDownLatch = new CountDownLatch(1);\n        Observable.fromArray(aa).flatMap(new Function<String, ObservableSource<String>>() {\n            @Override\n            public ObservableSource<String> apply(String s) throws Exception {\n                return Observable.just(s).map(new Function<String, String>() {\n                    @Override\n                    public String apply(String s) throws Exception {\n                        return s+s;\n                    }\n                }).subscribeOn(Schedulers.computation());\n            }\n        }).observeOn(Schedulers.newThread()).subscribe(new Observer<String>() {\n            @Override\n            public void onSubscribe(Disposable d) {\n\n            }\n\n            @Override\n            public void onNext(String value) {\n                System.out.println(value);\n                System.out.println(\"xxxx\");\n\n            }\n\n            @Override\n            public void onError(Throwable e) {\n                System.out.println(\"onError\");\n\n\n            }\n\n            @Override\n            public void onComplete() {\n                System.out.println(\"onComplete\");\n                countDownLatch.countDown();\n\n            }\n        });\n        countDownLatch.await();\n//       Observable.just(1,2,3,4).doOnSubscribe(new Consumer<Disposable>() {\n//           @Override\n//           public void accept(Disposable disposable) throws Exception {\n//               System.out.println(\"doOnSubscribe0 +\"+Thread.currentThread().getName());\n//\n//           }\n//       }).map(new Function<Integer, Integer>() {\n//\n//           @Override\n//           public Integer apply(Integer integer) throws Exception {\n//               System.out.println(\"map0 +\"+Thread.currentThread().getName());\n//\n//               return integer;\n//           }\n//       }).subscribeOn(Schedulers.newThread()).map(new Function<Integer, Integer>() {\n//           @Override\n//           public Integer apply(Integer integer) throws Exception {\n//               System.out.println(\"map +\"+Thread.currentThread().getName());\n//               return integer+1;\n//           }\n//       }).subscribeOn(Schedulers.computation()).map(new Function<Integer, Integer>() {\n//           @Override\n//           public Integer apply(Integer integer) throws Exception {\n//               System.out.println(\"map5 +\"+Thread.currentThread().getName());\n//\n//               return integer;\n//           }\n//       }).doOnSubscribe(new Consumer<Disposable>() {\n//           @Override\n//           public void accept(Disposable disposable) throws Exception {\n//               System.out.println(\"doOnSubscribe +\"+Thread.currentThread().getName());\n//\n//\n//           }\n//       }).subscribeOn(Schedulers.io()).observeOn(Schedulers.single()).doOnSubscribe(new Consumer<Disposable>() {\n//           @Override\n//           public void accept(Disposable disposable) throws Exception {\n//               System.out.println(\"doOnSubscribe1 +\"+Thread.currentThread().getName());\n//\n//           }\n//       }).subscribeOn(Schedulers.computation()).map(new Function<Integer, Integer>() {\n//           @Override\n//           public Integer apply(Integer integer) throws Exception {\n//               System.out.println(\"map1 +\"+Thread.currentThread().getName());\n//\n//               return integer+1;\n//           }\n//       }).observeOn(Schedulers.computation()).map(new Function<Integer, Integer>() {\n//           @Override\n//           public Integer apply(Integer integer) throws Exception {\n//               System.out.println(\"map3 +\"+Thread.currentThread().getName());\n//\n//               return integer;\n//           }\n//       }).blockingSubscribe(new Consumer<Integer>() {\n//           @Override\n//           public void accept(Integer integer) throws Exception {\n//               System.out.println(\"Consumer +\"+integer+Thread.currentThread().getName());\n//\n//           }\n//       });\n\n//        Set<String>set = new HashSet<>();\n//        set.add(\"a\");\n//        set.add(\"b\");\n//        set.add(\"f\");\n//        set.add(\"c\");\n//        System.out.println(set.toArray()[0]);\n//       Thread.sleep(5000);\n    }\n\n\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/MergeObject.java",
    "content": "package com.taobao.atlas.dexmerge;\n\nimport android.os.Parcel;\nimport android.os.Parcelable;\n\n/**\n * Created by lilong on 16/7/5.\n */\npublic class MergeObject implements Parcelable{\n    public String originalFile;\n    public String patchName;\n    public String mergeFile;\n    protected MergeObject(Parcel in) {\n    }\n\n    public static final Creator<MergeObject> CREATOR = new Creator<MergeObject>() {\n        @Override\n        public MergeObject createFromParcel(Parcel in) {\n\n            return new MergeObject(in.readString(),in.readString(),in.readString());\n        }\n\n        @Override\n        public MergeObject[] newArray(int size) {\n            return new MergeObject[size];\n        }\n    };\n\n    public MergeObject(String originalFile, String patchFile, String mergeFile) {\n        this.originalFile = originalFile;\n        this.patchName = patchFile;\n        this.mergeFile = mergeFile;\n    }\n\n    @Override\n    public int describeContents() {\n        return 0;\n    }\n\n    @Override\n    public void writeToParcel(Parcel dest, int flags) {\n        dest.writeString(originalFile);\n        dest.writeString(patchName);\n        dest.writeString(mergeFile);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/MergeTool.java",
    "content": "package com.taobao.atlas.dexmerge;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.SharedPreferences;\nimport android.os.Build;\nimport android.preference.PreferenceManager;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.taobao.atlas.startup.patch.releaser.DexReleaser;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport com.alibaba.patch.PatchUtils;\nimport com.taobao.atlas.dex.ClassDef;\nimport com.taobao.atlas.dex.Dex;\nimport com.taobao.atlas.dex.ProtoId;\nimport com.taobao.atlas.dex.util.FileUtils;\nimport com.taobao.atlas.dexmerge.dx.merge.CollisionPolicy;\nimport com.taobao.atlas.dexmerge.dx.merge.DexMerger;\n\nimport java.io.*;\nimport java.util.*;\nimport java.util.concurrent.atomic.AtomicReference;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\nimport java.util.zip.ZipOutputStream;\n\n/**\n * Created by lilong on 16/7/5.\n */\npublic class MergeTool {\n    private static final int BUFFEREDSIZE = 1024;\n\n\n    private static String noPatchDexIndex;\n\n    private static int patchVersion = 1;\n\n\n    private static TreeMap<Integer, List<String>> classes = new TreeMap();\n\n\n    public static void mergePrepare(File oldBundle, List<ZipEntry> entryList, String patchName, File targetBundle, boolean isDiff, MergeExcutorServices.PrepareCallBack prepareCallBack) throws IOException, MergeException {\n        if (oldBundle.exists() && entryList != null) {\n            ZipFile sourceZip = new ZipFile(oldBundle);\n            try {\n                File tempFile = File.createTempFile(patchName, null, targetBundle.getParentFile());\n                tempFile.deleteOnExit();\n                if (patchName.equals(MergeConstants.MAIN_DEX)) {\n                    createNewMainApkInternal(sourceZip, entryList, tempFile, isDiff, prepareCallBack);\n                } else {\n                    createNewBundleInternal(patchName, sourceZip, entryList, tempFile, isDiff, prepareCallBack);\n                }\n                if (tempFile.exists()) {\n                    if (!tempFile.renameTo(targetBundle)) throw new IOException(\"merge failed!\");\n//                        deleteDir(patchBundle);\n                }\n            } catch (IOException e) {\n                targetBundle.delete();\n                targetBundle = null;\n                throw new IOException(e);\n            } finally {\n                try {\n                    sourceZip.close();\n                } catch (Throwable e) {\n                }\n            }\n        }\n\n    }\n\n    private static void createNewMainApkInternal(ZipFile sourceZip, List<ZipEntry> entryList, File tempFile, boolean isDiff, MergeExcutorServices.PrepareCallBack prepareCallBack) throws IOException {\n        byte[] buffer = new byte[BUFFEREDSIZE];\n        ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(tempFile)));\n        BufferedOutputStream bo = new BufferedOutputStream(out);\n        InputStream in;\n        //先写入source中未变的文件\n        java.util.Enumeration e = sourceZip.entries();\n        int i = 1;\n        File mainDexFile = new File(tempFile.getParentFile(), \"libcom_taobao_maindex.zip\");\n        inputStreamToFile(MergeExcutorServices.sZipPatch.getInputStream(entryList.get(0)), mainDexFile);\n        ZipFile zipFile = new ZipFile(mainDexFile);\n        if (zipFile.getEntry(MergeConstants.DEX_PATCH_META) != null) {\n            readPatchClasses(zipFile, zipFile.getEntry(MergeConstants.DEX_PATCH_META));\n        }\n        Enumeration entries = zipFile.entries();\n        switch (patchVersion) {\n            case 1:\n                i = writePatch(entries, out, bo,zipFile, i);\n\n                writeSourceApkDex(e, sourceZip,bo, out, i);\n                break;\n\n            case 2:\n                while (e.hasMoreElements()) {\n                        ZipEntry zipEnt = (ZipEntry) e.nextElement();\n                        String name = zipEnt.getName();\n                        if (name.endsWith(MergeConstants.DEX_SUFFIX)) {\n                            String s = name.substring(7);\n                            Integer sourceDexIndex = s.startsWith(\".\") ? 0 : Integer.valueOf(s.substring(0, s.indexOf(\".\")));\n                            if (classes.get(sourceDexIndex) != null) {\n                                Log.e(\"MergeTool\", \"process sourceDex:\" + sourceDexIndex + \" and classes size:\" + classes.get(sourceDexIndex).size());\n                                InputStream inputStream = sourceZip.getInputStream(zipEnt);\n                                Dex dex = processDex(inputStream, classes.get(sourceDexIndex));\n                                ZipEntry newEntry = new ZipEntry(zipEnt.getName());\n                                out.putNextEntry(newEntry);\n                                write(new ByteArrayInputStream(dex.getBytes()), out, buffer);\n                                bo.flush();\n                            } else if (isArt() && !isEnhanceDex(name)) {\n                                ZipEntry newEntry = new ZipEntry(zipEnt.getName());\n                                out.putNextEntry(newEntry);\n                                write(sourceZip.getInputStream(zipEnt), out, buffer);\n                                bo.flush();\n                            }\n                            i++;\n                        }\n                    }\n\n                writePatch(entries, out, bo,zipFile, i);\n                break;\n\n            default:\n                break;\n\n        }\n\n        mainDexFile.delete();\n        zipFile.close();\n        closeQuitely(out);\n        closeQuitely(bo);\n\n\n    }\n\n    private static int writeSourceApkDex(Enumeration e, ZipFile sourceZip, BufferedOutputStream bo,ZipOutputStream out, int i) throws IOException {\n        byte[] buffer = new byte[BUFFEREDSIZE];\n        while (e.hasMoreElements()) {\n            ZipEntry zipEnt = (ZipEntry) e.nextElement();\n            String name = zipEnt.getName();\n            if (!name.endsWith(MergeConstants.DEX_SUFFIX)) {\n                continue;\n            }\n            ZipEntry newEntry = new ZipEntry(String.format(\"%s%s%s\", MergeConstants.CLASS, i == 1 ? \"\" : i, MergeConstants.DEX_SUFFIX));\n            if (isArt() && !isEnhanceDex(name)) {\n                InputStream inputStream = sourceZip.getInputStream(zipEnt);\n                out.putNextEntry(newEntry);\n                write(inputStream, out, buffer);\n                bo.flush();\n            } else if (!isArt()) {\n                String s = name.substring(7);\n                Integer sourceDexIndex = s.startsWith(\".\") ? 0 : Integer.valueOf(s.substring(0, s.indexOf(\".\")));\n                if (classes.get(sourceDexIndex) != null) {\n                    Log.e(\"MergeTool\", \"process sourceDex:\" + sourceDexIndex + \" and classes size:\" + classes.get(sourceDexIndex).size());\n                    InputStream inputStream = sourceZip.getInputStream(zipEnt);\n                    Dex dex = processDex(inputStream, classes.get(sourceDexIndex));\n                    out.putNextEntry(newEntry);\n                    write(new ByteArrayInputStream(dex.getBytes()), out, buffer);\n                    bo.flush();\n                }\n            }\n            i++;\n        }\n\n        return i;\n\n    }\n\n    private static int writePatch(Enumeration entries, ZipOutputStream out, BufferedOutputStream bo,ZipFile zipFile, int i) throws IOException {\n        byte[] buffer = new byte[BUFFEREDSIZE];\n        while (entries.hasMoreElements()) {\n            ZipEntry zipEnt = (ZipEntry) entries.nextElement();\n            String name = zipEnt.getName();\n            if (name.endsWith(MergeConstants.DEX_SUFFIX)) {\n                ZipEntry zipEntry = new ZipEntry(String.format(\"%s%s%s\", MergeConstants.CLASS, i == 1 ? \"\" : i, MergeConstants.DEX_SUFFIX));\n                out.putNextEntry(zipEntry);\n                write(zipFile.getInputStream(zipEnt), out, buffer);\n                bo.flush();\n                i++;\n                continue;\n            }\n            ZipEntry newEntry = new ZipEntry(name);\n            if (name.contains(\"raw/\") || name.contains(\"assets/\") || name.equals(\"resources.arsc\")) {\n                newEntry.setMethod(ZipEntry.STORED);\n                newEntry.setCrc(zipEnt.getCrc());\n                newEntry.setSize(zipEnt.getSize());\n            }\n            out.putNextEntry(newEntry);\n            InputStream in = zipFile.getInputStream(zipEnt);\n            write(in, out, buffer);\n            bo.flush();\n        }\n\n        return i;\n\n    }\n\n    private static boolean isEnhanceDex(String name) {\n\n        return !TextUtils.isEmpty(noPatchDexIndex) && name.equals(String.format(\"classes%s.dex\", noPatchDexIndex)) && (Build.VERSION.SDK_INT > 27 || Build.VERSION.SDK_INT < 21);\n\n    }\n\n    private static void readPatchClasses(ZipFile zipFile, ZipEntry entry) {\n        try {\n            InputStream is = zipFile.getInputStream(entry);\n            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));\n            String s = null;\n            while (!TextUtils.isEmpty(s = bufferedReader.readLine())) {\n                String dexIndex = s.split(\"-\")[0];\n                String clazz = s.split(\"-\")[1];\n                if (!TextUtils.isEmpty(clazz) && clazz.equals(MergeConstants.NO_PATCH_DEX)) {\n                    noPatchDexIndex = dexIndex;\n                    continue;\n                }\n\n                if (!TextUtils.isEmpty(clazz) && clazz.equals(MergeConstants.PATCH_VERSION)) {\n//                    patchVersion = Integer.valueOf(dexIndex);\n//                    notifyPatchVersion(patchVersion);\n                    continue;\n                }\n\n                if (classes.containsKey(Integer.valueOf(dexIndex))) {\n                    classes.get(Integer.valueOf(dexIndex)).add(clazz);\n                } else {\n                    List<String> cc = new ArrayList<>();\n                    cc.add(clazz);\n                    classes.put(Integer.valueOf(dexIndex), cc);\n                }\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n            classes.clear();\n        }\n\n    }\n\n    private static void notifyPatchVersion(int patchVersion) {\n        Intent intent = new Intent(\"com.taobao.atlas.intent.PATCH_VERSION\");\n        intent.putExtra(\"patch_version\", patchVersion);\n        RuntimeVariables.androidApplication.sendBroadcast(intent);\n    }\n\n\n    private static Dex processDex(InputStream inputStream, List<String> patchClassNames) throws IOException {\n        Dex oringnalDex = new Dex(inputStream);\n        DexMerger dexMerger = new DexMerger(new Dex[]{oringnalDex, new Dex(0)}, CollisionPolicy.FAIL);\n        dexMerger.setRemoveTypeClasses(patchClassNames);\n        dexMerger.setCompactWasteThreshold(1);\n        Dex dex = dexMerger.merge();\n        return dex;\n    }\n\n    private static boolean isBundleFileUpdated(ZipEntry sourceEntry, List<ZipEntry> entryList, AtomicReference patchEntry) {\n        for (ZipEntry entry : entryList) {\n            if (entry.getName().contains(sourceEntry.getName())) {\n                patchEntry.compareAndSet(null, entry);\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public static void createNewBundleInternal(String patchBundleName, ZipFile source, List<ZipEntry> entryList, File target, boolean isDiff, MergeExcutorServices.PrepareCallBack prepareCallBack) throws IOException, MergeException {\n\n        // get a temp file\n        byte[] buffer = new byte[BUFFEREDSIZE];\n        ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(target)));\n        BufferedOutputStream bo = new BufferedOutputStream(out);\n        InputStream in;\n        //先写入source中未变的文件\n        java.util.Enumeration e = source.entries();\n        Boolean isSourceHasDex = false;\n        Boolean isPatchHasDex = false;\n        ZipEntry originalDex = null;\n        ZipEntry patchDex = null;\n        File outDex;\n        AtomicReference<ZipEntry> zipEntryAtomicReference = new AtomicReference<>();\n        while (e.hasMoreElements()) {\n            ZipEntry zipEnt = (ZipEntry) e.nextElement();\n            String name = zipEnt.getName();\n            /**\n             * 差量更新需要做dex merge, 过滤出classes.dex\n             */\n            if (isDiff && name.equals(MergeConstants.CLASS + MergeConstants.DEX_SUFFIX)) {\n//                originalDex = zipEnt;\n                isSourceHasDex = true;\n                continue;\n            }\n\n            boolean toBeDeleted = isBundleFileUpdated(zipEnt, entryList, zipEntryAtomicReference);\n            if (!toBeDeleted) {\n\n                ZipEntry newEntry = new ZipEntry(name);\n                if (MergeExcutorServices.os == MergeExcutorServices.OS.mac) {\n                    if (name.contains(\"raw/\") || name.contains(\"assets/\")) {\n                        newEntry.setMethod(ZipEntry.STORED);\n                        newEntry.setCrc(zipEnt.getCrc());\n                        newEntry.setSize(zipEnt.getSize());\n                    }\n                } else {\n                    if (name.contains(\"raw\\\\\") || name.contains(\"assets\\\\\")) {\n                        newEntry.setMethod(ZipEntry.STORED);\n                        newEntry.setCrc(zipEnt.getCrc());\n                        newEntry.setSize(zipEnt.getSize());\n                    }\n                }\n                out.putNextEntry(newEntry);\n                in = source.getInputStream(zipEnt);\n                write(in, out, buffer);\n                bo.flush();\n\n            }\n            if (toBeDeleted && zipEnt.getName().endsWith(MergeConstants.SO_SUFFIX) && zipEntryAtomicReference.get() != null && zipEntryAtomicReference.get().getName().endsWith(\".patch\")) {\n                File oringalOut = new File(target.getParentFile(), zipEnt.getName());\n                File patchOut = new File(target.getParentFile(), zipEnt.getName() + \".patch\");\n                File newFileOut = new File(target.getParentFile(), zipEnt.getName() + \".new.so\");\n                if (!oringalOut.getParentFile().exists()) {\n                    oringalOut.getParentFile().mkdirs();\n                }\n                inputStreamToFile(source.getInputStream(zipEnt), oringalOut);\n                inputStreamToFile(MergeExcutorServices.sZipPatch.getInputStream(zipEntryAtomicReference.get()), patchOut);\n                errorCheck(oringalOut, patchOut);\n                PatchUtils.applyPatch(oringalOut.getAbsolutePath(), newFileOut.getAbsolutePath(), patchOut.getAbsolutePath());\n                errorCheck(newFileOut);\n                if (!oringalOut.delete() || !newFileOut.renameTo(oringalOut)) {\n                    throw new IOException(\"file deleted failed or file rename failed:\" + oringalOut.getAbsolutePath() + \" \" + newFileOut.getAbsolutePath());\n                }\n\n                entryList.remove(zipEntryAtomicReference.getAndSet(null));\n                out.putNextEntry(new ZipEntry(zipEnt.getName()));\n                write(new BufferedInputStream(new FileInputStream(oringalOut)), out, buffer);\n            }\n        }\n\n        if (!isSourceHasDex && isDiff) {\n            throw new MergeException(\"Original bundle has no dex\");\n        }\n\n        //最后写入patch中的内容\n//        File[] patchFiles = patch.listFiles();\n//        for (File patchFile : patchFiles) {\n//            /**\n//             * 差量更新需要做dex merge, 过滤出classes.dex\n//             */\n//            if (isDiff && patchFile.getName().equals(\"classes.dex\")) {\n//                patchDex = patchFile;\n//                isPatchHasDex = true;\n//                MergeExcutorServices.needMergeCount.incrementAndGet();\n//                continue;\n//            }\n//            zip(out, patchFile, patchFile.getName(), bo);\n//\n//        }\n        for (ZipEntry entry : entryList) {\n            if (isDiff && (entry.getName().endsWith(MergeConstants.CLASS + MergeConstants.DEX_SUFFIX))) {\n                patchDex = entry;\n                isPatchHasDex = true;\n                continue;\n            }\n\n            ZipEntry newEntry = null;\n            if (MergeExcutorServices.os == MergeExcutorServices.OS.mac) {\n                newEntry = new ZipEntry(entry.getName().substring(entry.getName().indexOf(\"/\") + 1));\n                if (newEntry.getName().contains(\"raw/\") || newEntry.getName().contains(\"assets/\")) {\n                    newEntry.setMethod(ZipEntry.STORED);\n                    newEntry.setCrc(entry.getCrc());\n                    newEntry.setSize(entry.getSize());\n                }\n            } else {\n                newEntry = new ZipEntry(entry.getName().substring(entry.getName().indexOf(\"\\\\\") + 1));\n                if (newEntry.getName().contains(\"raw\\\\\") || newEntry.getName().contains(\"assets\\\\\")) {\n                    newEntry.setMethod(ZipEntry.STORED);\n                    newEntry.setCrc(entry.getCrc());\n                    newEntry.setSize(entry.getSize());\n                }\n            }\n            out.putNextEntry(newEntry);\n            in = MergeExcutorServices.sZipPatch.getInputStream(entry);\n            write(in, out, buffer);\n            bo.flush();\n        }\n        /**\n         * 差量更新需要做dex merge\n         */\n        if (isDiff) {\n            // Merge patch dex with origin dex\n            if (isPatchHasDex && isSourceHasDex) {\n                //发出merge申请\n//                File outDexDir = new File(patch, \"out\");\n                ByteArrayOutputStream outDexStream = new ByteArrayOutputStream();\n                dexMerge(patchBundleName, source, patchDex, outDexStream, prepareCallBack);\n//                if (outDexStream.exists()) {\n//                    /**\n//                     * caculate the merged dex md5 and report\n//                     */\n//                    String md5 = Md5Utils.getFileMD5String(outDex);\n//                    MonitorReport.getInstance().trace(source.getName(), md5, \"\" + outDex.length());\n//                }\n//                zip(out, outDex, outDex.getName(), bo);\n                ByteArrayInputStream swapStream = new ByteArrayInputStream(outDexStream.toByteArray());\n                ZipEntry entry = new ZipEntry(MergeConstants.CLASS + MergeConstants.DEX_SUFFIX);\n                out.putNextEntry(entry);\n                write(swapStream, out, buffer);\n                bo.flush();\n            } else if (isSourceHasDex) {\n                // Patch has no classes.dex, just use the original dex\n//                outDex = new File(patch, \"classes.dex\");\n//                inputStreamToFile(source.getInputStream(originalDex), outDex);\n//                zip(out, outDex, outDex.getName(), bo);\n                ZipEntry entry = new ZipEntry(MergeConstants.CLASS + MergeConstants.DEX_SUFFIX);\n                out.putNextEntry(entry);\n                in = source.getInputStream(source.getEntry(MergeConstants.CLASS + MergeConstants.DEX_SUFFIX));\n                write(in, out, buffer);\n                bo.flush();\n            }\n        } else {\n        }\n\n        closeQuitely(out);\n        closeQuitely(bo);\n    }\n\n    private static void errorCheck(File... files) throws IOException {\n        if (files == null) {\n            return;\n        }\n        for (File file : files) {\n            if (file == null) {\n                throw new IOException(\"file is null\");\n            } else if (!file.exists()) {\n                throw new IOException(\"file no exit:\" + file.getAbsolutePath());\n            }\n        }\n    }\n\n    private static void dexMerge(String bundleName, ZipFile source, ZipEntry patchDex, OutputStream newDexStream, MergeExcutorServices.PrepareCallBack prepareCallBack) throws IOException {\n\n\n        prepareCallBack.prepareMerge(bundleName, source, patchDex, newDexStream);\n\n\n    }\n\n\n    private static void inputStreamToFile(InputStream ins, File file) throws IOException {\n        if (file.exists()) {\n            file.delete();\n        }\n        OutputStream os = new FileOutputStream(file);\n        int bytesRead = 0;\n        byte[] buffer = new byte[8192];\n        while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {\n            os.write(buffer, 0, bytesRead);\n        }\n        os.close();\n        ins.close();\n    }\n\n//    private static void zip(ZipOutputStream out, File f, String base,\n//                            BufferedOutputStream bo) throws IOException {\n//        if (f.isDirectory()) {\n//            File[] fl = f.listFiles();\n//            if (fl.length == 0) {\n//                out.putNextEntry(new ZipEntry(base + File.separator));\n//            }\n//            for (int i = 0; i < fl.length; i++) {\n//                zip(out, fl[i], base + File.separator + fl[i].getName(), bo);\n//            }\n//        } else {\n//            CRC32 crc = new CRC32();\n//            ZipEntry newEntry = new ZipEntry(base);\n//            int bytesRead;\n//            byte[] buffer = new byte[BUFFEREDSIZE];\n//            if(base.contains(\"raw/\") || base.contains(\"assets/\")){\n//                BufferedInputStream bis = new BufferedInputStream(\n//                        new FileInputStream(f));\n//                crc.reset();\n//                while ((bytesRead = bis.read(buffer)) != -1) {\n//                    crc.update(buffer, 0, bytesRead);\n//                }\n//                closeQuitely(bis);\n//                newEntry.setMethod(ZipEntry.STORED);\n//                newEntry.setCrc(crc.getValue());\n//                newEntry.setSize(f.length());\n//            }\n//            out.putNextEntry(newEntry);\n//            FileInputStream in = new FileInputStream(f);\n//            BufferedInputStream bi = new BufferedInputStream(in);\n//            int b;\n//            while ((b = bi.read()) != -1) {\n//                bo.write(b);\n//            }\n//            bo.flush();\n//            closeQuitely(bi);\n//            closeQuitely(in);\n//        }\n//    }\n\n    private static void write(InputStream in, OutputStream out, byte[] buffer) throws IOException {\n        int length = in.read(buffer);\n        while (length != -1) {\n            out.write(buffer, 0, length);\n            length = in.read(buffer);\n        }\n        closeQuitely(in);\n    }\n\n\n    private static void closeQuitely(Closeable closeable) {\n        if (closeable != null) {\n            try {\n                closeable.close();\n            } catch (Throwable e) {\n            }\n        }\n    }\n\n    private static boolean deleteDir(File dir) {\n        if (dir.isDirectory()) {\n            String[] children = dir.list();\n            for (int i = 0; i < children.length; i++) {\n                boolean success = deleteDir(new File(dir, children[i]));\n                if (!success) {\n                    return false;\n                }\n            }\n        }\n        return dir.delete();\n    }\n\n    public static boolean isArt() {\n//        return true;\n\n        return Build.VERSION.SDK_INT > 20;\n\n    }\n\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/PatchVersionReceiver.java",
    "content": "package com.taobao.atlas.dexmerge;\n\nimport android.content.BroadcastReceiver;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.taobao.atlas.runtime.RuntimeVariables;\n\n/**\n * PatchVersionReceiver\n *\n * @author zhayu.ll\n * @date 18/9/7\n */\npublic class PatchVersionReceiver extends BroadcastReceiver {\n    @Override\n    public void onReceive(Context context, Intent intent) {\n        int version = intent.getIntExtra(\"patch_version\",2);\n        RuntimeVariables.patchVersion = version;\n        RuntimeVariables.androidApplication.unregisterReceiver(this);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/CodeReader.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io;\n\nimport com.taobao.atlas.dex.DexException2;\nimport com.taobao.atlas.dexmerge.dx.io.instructions.DecodedInstruction;\n\n/**\n * Walks through a block of code and calls visitor call backs.\n */\npublic final class CodeReader {\n    private Visitor fallbackVisitor = null;\n    private Visitor stringVisitor = null;\n    private Visitor typeVisitor = null;\n    private Visitor fieldVisitor = null;\n    private Visitor methodVisitor = null;\n\n    /**\n     * Sets {@code visitor} as the visitor for all instructions.\n     */\n    public void setAllVisitors(Visitor visitor) {\n        fallbackVisitor = visitor;\n        stringVisitor = visitor;\n        typeVisitor = visitor;\n        fieldVisitor = visitor;\n        methodVisitor = visitor;\n    }\n\n    /**\n     * Sets {@code visitor} as the visitor for all instructions not\n     * otherwise handled.\n     */\n    public void setFallbackVisitor(Visitor visitor) {\n        fallbackVisitor = visitor;\n    }\n\n    /**\n     * Sets {@code visitor} as the visitor for all string instructions.\n     */\n    public void setStringVisitor(Visitor visitor) {\n        stringVisitor = visitor;\n    }\n\n    /**\n     * Sets {@code visitor} as the visitor for all type instructions.\n     */\n    public void setTypeVisitor(Visitor visitor) {\n        typeVisitor = visitor;\n    }\n\n    /**\n     * Sets {@code visitor} as the visitor for all field instructions.\n     */\n    public void setFieldVisitor(Visitor visitor) {\n        fieldVisitor = visitor;\n    }\n\n    /**\n     * Sets {@code visitor} as the visitor for all method instructions.\n     */\n    public void setMethodVisitor(Visitor visitor) {\n        methodVisitor = visitor;\n    }\n\n    public void visitAll(DecodedInstruction[] decodedInstructions)\n            throws DexException2 {\n        int size = decodedInstructions.length;\n\n        for (int i = 0; i < size; i++) {\n            DecodedInstruction one = decodedInstructions[i];\n            if (one == null) {\n                continue;\n            }\n\n            callVisit(decodedInstructions, one);\n        }\n    }\n\n    public void visitAll(short[] encodedInstructions) throws DexException2 {\n        DecodedInstruction[] decodedInstructions =\n            DecodedInstruction.decodeAll(encodedInstructions);\n        visitAll(decodedInstructions);\n    }\n\n    private void callVisit(DecodedInstruction[] all, DecodedInstruction one) {\n        Visitor visitor = null;\n\n        switch (OpcodeInfo.getIndexType(one.getOpcode())) {\n            case STRING_REF: visitor = stringVisitor; break;\n            case TYPE_REF:   visitor = typeVisitor;   break;\n            case FIELD_REF:  visitor = fieldVisitor;  break;\n            case METHOD_REF: visitor = methodVisitor; break;\n        }\n\n        if (visitor == null) {\n            visitor = fallbackVisitor;\n        }\n\n        if (visitor != null) {\n            visitor.visit(all, one);\n        }\n    }\n\n    public interface Visitor {\n        void visit(DecodedInstruction[] all, DecodedInstruction one);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/DexIndexPrinter.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io;\n\nimport android.util.Log;\nimport com.taobao.atlas.dex.ClassDef;\nimport com.taobao.atlas.dex.Dex;\nimport com.taobao.atlas.dex.FieldId;\nimport com.taobao.atlas.dex.MethodId;\nimport com.taobao.atlas.dex.ProtoId;\nimport com.taobao.atlas.dex.TableOfContents;\nimport java.io.File;\nimport java.io.IOException;\n\n/**\n * Executable that prints all indices of a dex file.\n */\npublic final class DexIndexPrinter {\n    private static final String TAG = \"DexIndexPrinter\";\n    private final Dex dex;\n    private final TableOfContents tableOfContents;\n\n    public DexIndexPrinter(File file) throws IOException {\n        this.dex = new Dex(file);\n        this.tableOfContents = dex.getTableOfContents();\n    }\n\n    private void printMap() {\n        for (TableOfContents.Section section : tableOfContents.sections) {\n            if (section.off != -1) {\n                Log.d(\"DexIndexPrinter\",\"section \" + Integer.toHexString(section.type)\n                        + \" off=\" + Integer.toHexString(section.off)\n                        + \" size=\" + Integer.toHexString(section.size)\n                        + \" byteCount=\" + Integer.toHexString(section.byteCount));\n            }\n        }\n    }\n\n    private void printStrings() throws IOException {\n        int index = 0;\n        for (String string : dex.strings()) {\n            Log.d(\"DexIndexPrinter\",\"string \" + index + \": \" + string);\n            index++;\n        }\n    }\n\n    private void printTypeIds() throws IOException {\n        int index = 0;\n        for (Integer type : dex.typeIds()) {\n            Log.d(\"DexIndexPrinter\",\"type \" + index + \": \" + dex.strings().get(type));\n            index++;\n        }\n    }\n\n    private void printProtoIds() throws IOException {\n        int index = 0;\n        for (ProtoId protoId : dex.protoIds()) {\n            Log.d(\"DexIndexPrinter\",\"proto \" + index + \": \" + protoId);\n            index++;\n        }\n    }\n\n    private void printFieldIds() throws IOException {\n        int index = 0;\n        for (FieldId fieldId : dex.fieldIds()) {\n            Log.d(\"DexIndexPrinter\",\"field \" + index + \": \" + fieldId);\n            index++;\n        }\n    }\n\n    private void printMethodIds() throws IOException {\n        int index = 0;\n        for (MethodId methodId : dex.methodIds()) {\n            Log.d(\"DexIndexPrinter\",\"methodId \" + index + \": \" + methodId);\n            index++;\n        }\n    }\n\n    private void printTypeLists() throws IOException {\n        if (tableOfContents.typeLists.off == -1) {\n            Log.d(\"DexIndexPrinter\",\"No type lists\");\n            return;\n        }\n        Dex.Section in = dex.open(tableOfContents.typeLists.off);\n        for (int i = 0; i < tableOfContents.typeLists.size; i++) {\n            int size = in.readInt();\n            Log.d(\"DexIndexPrinter\",\"Type list i=\" + i + \", size=\" + size + \", elements=\");\n            for (int t = 0; t < size; t++) {\n                Log.d(\"DexIndexPrinter\",\" \" + dex.typeNames().get((int) in.readShort()));\n            }\n            if (size % 2 == 1) {\n                in.readShort(); // retain alignment\n            }\n//            System.out.println();\n        }\n    }\n\n    private void printClassDefs() {\n        int index = 0;\n        for (ClassDef classDef : dex.classDefs()) {\n            Log.d(\"DexIndexPrinter\",\"class def \" + index + \": \" + classDef);\n            index++;\n        }\n    }\n\n    public static void main(String[] args) throws IOException {\n        DexIndexPrinter indexPrinter = new DexIndexPrinter(new File(args[0]));\n        indexPrinter.printMap();\n        indexPrinter.printStrings();\n        indexPrinter.printTypeIds();\n        indexPrinter.printProtoIds();\n        indexPrinter.printFieldIds();\n        indexPrinter.printMethodIds();\n        indexPrinter.printTypeLists();\n        indexPrinter.printClassDefs();\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/IndexType.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io;\n\n/**\n * The various types that an index in a Dalvik instruction might refer to.\n */\npublic enum IndexType {\n    /** \"Unknown.\" Used for undefined opcodes. */\n    UNKNOWN,\n\n    /** no index used */\n    NONE,\n\n    /** \"It depends.\" Used for {@code throw-verification-error}. */\n    VARIES,\n\n    /** type reference index */\n    TYPE_REF,\n\n    /** string reference index */\n    STRING_REF,\n\n    /** method reference index */\n    METHOD_REF,\n\n    /** field reference index */\n    FIELD_REF,\n\n    /** inline method index (for inline linked method invocations) */\n    INLINE_METHOD,\n\n    /** direct vtable offset (for static linked method invocations) */\n    VTABLE_OFFSET,\n\n    /** direct field offset (for static linked field accesses) */\n    FIELD_OFFSET;\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/OpcodeInfo.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io;\n\nimport com.taobao.atlas.dexmerge.dx.io.instructions.InstructionCodec;\nimport com.taobao.atlas.dexmerge.dx.util.Hex;\n\n/**\n * Information about each Dalvik opcode.\n */\npublic final class OpcodeInfo {\n    /*\n     * TODO: Merge at least most of the info from the Dops class into\n     * this one.\n     */\n\n    /** non-null; array containing all the information */\n    private static final Info[] INFO;\n\n    /**\n     * pseudo-opcode used for nonstandard formatted \"instructions\"\n     * (which are mostly not actually instructions, though they do\n     * appear in instruction lists). TODO: Retire the usage of this\n     * constant.\n     */\n    public static final Info SPECIAL_FORMAT =\n        new Info(Opcodes.SPECIAL_FORMAT, \"<special>\",\n                InstructionCodec.FORMAT_00X, IndexType.NONE);\n\n    // TODO: These payload opcodes should be generated by opcode-gen.\n\n    public static final Info PACKED_SWITCH_PAYLOAD =\n        new Info(Opcodes.PACKED_SWITCH_PAYLOAD, \"packed-switch-payload\",\n                InstructionCodec.FORMAT_PACKED_SWITCH_PAYLOAD,\n                IndexType.NONE);\n\n    public static final Info SPARSE_SWITCH_PAYLOAD =\n        new Info(Opcodes.SPARSE_SWITCH_PAYLOAD, \"sparse-switch-payload\",\n                InstructionCodec.FORMAT_SPARSE_SWITCH_PAYLOAD,\n                IndexType.NONE);\n\n    public static final Info FILL_ARRAY_DATA_PAYLOAD =\n        new Info(Opcodes.FILL_ARRAY_DATA_PAYLOAD, \"fill-array-data-payload\",\n                InstructionCodec.FORMAT_FILL_ARRAY_DATA_PAYLOAD,\n                IndexType.NONE);\n\n    // BEGIN(opcode-info-defs); GENERATED AUTOMATICALLY BY opcode-gen\n    public static final Info NOP =\n        new Info(Opcodes.NOP, \"nop\",\n            InstructionCodec.FORMAT_10X, IndexType.NONE);\n\n    public static final Info MOVE =\n        new Info(Opcodes.MOVE, \"move\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info MOVE_FROM16 =\n        new Info(Opcodes.MOVE_FROM16, \"move/from16\",\n            InstructionCodec.FORMAT_22X, IndexType.NONE);\n\n    public static final Info MOVE_16 =\n        new Info(Opcodes.MOVE_16, \"move/16\",\n            InstructionCodec.FORMAT_32X, IndexType.NONE);\n\n    public static final Info MOVE_WIDE =\n        new Info(Opcodes.MOVE_WIDE, \"move-wide\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info MOVE_WIDE_FROM16 =\n        new Info(Opcodes.MOVE_WIDE_FROM16, \"move-wide/from16\",\n            InstructionCodec.FORMAT_22X, IndexType.NONE);\n\n    public static final Info MOVE_WIDE_16 =\n        new Info(Opcodes.MOVE_WIDE_16, \"move-wide/16\",\n            InstructionCodec.FORMAT_32X, IndexType.NONE);\n\n    public static final Info MOVE_OBJECT =\n        new Info(Opcodes.MOVE_OBJECT, \"move-object\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info MOVE_OBJECT_FROM16 =\n        new Info(Opcodes.MOVE_OBJECT_FROM16, \"move-object/from16\",\n            InstructionCodec.FORMAT_22X, IndexType.NONE);\n\n    public static final Info MOVE_OBJECT_16 =\n        new Info(Opcodes.MOVE_OBJECT_16, \"move-object/16\",\n            InstructionCodec.FORMAT_32X, IndexType.NONE);\n\n    public static final Info MOVE_RESULT =\n        new Info(Opcodes.MOVE_RESULT, \"move-result\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info MOVE_RESULT_WIDE =\n        new Info(Opcodes.MOVE_RESULT_WIDE, \"move-result-wide\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info MOVE_RESULT_OBJECT =\n        new Info(Opcodes.MOVE_RESULT_OBJECT, \"move-result-object\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info MOVE_EXCEPTION =\n        new Info(Opcodes.MOVE_EXCEPTION, \"move-exception\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info RETURN_VOID =\n        new Info(Opcodes.RETURN_VOID, \"return-void\",\n            InstructionCodec.FORMAT_10X, IndexType.NONE);\n\n    public static final Info RETURN =\n        new Info(Opcodes.RETURN, \"return\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info RETURN_WIDE =\n        new Info(Opcodes.RETURN_WIDE, \"return-wide\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info RETURN_OBJECT =\n        new Info(Opcodes.RETURN_OBJECT, \"return-object\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info CONST_4 =\n        new Info(Opcodes.CONST_4, \"const/4\",\n            InstructionCodec.FORMAT_11N, IndexType.NONE);\n\n    public static final Info CONST_16 =\n        new Info(Opcodes.CONST_16, \"const/16\",\n            InstructionCodec.FORMAT_21S, IndexType.NONE);\n\n    public static final Info CONST =\n        new Info(Opcodes.CONST, \"const\",\n            InstructionCodec.FORMAT_31I, IndexType.NONE);\n\n    public static final Info CONST_HIGH16 =\n        new Info(Opcodes.CONST_HIGH16, \"const/high16\",\n            InstructionCodec.FORMAT_21H, IndexType.NONE);\n\n    public static final Info CONST_WIDE_16 =\n        new Info(Opcodes.CONST_WIDE_16, \"const-wide/16\",\n            InstructionCodec.FORMAT_21S, IndexType.NONE);\n\n    public static final Info CONST_WIDE_32 =\n        new Info(Opcodes.CONST_WIDE_32, \"const-wide/32\",\n            InstructionCodec.FORMAT_31I, IndexType.NONE);\n\n    public static final Info CONST_WIDE =\n        new Info(Opcodes.CONST_WIDE, \"const-wide\",\n            InstructionCodec.FORMAT_51L, IndexType.NONE);\n\n    public static final Info CONST_WIDE_HIGH16 =\n        new Info(Opcodes.CONST_WIDE_HIGH16, \"const-wide/high16\",\n            InstructionCodec.FORMAT_21H, IndexType.NONE);\n\n    public static final Info CONST_STRING =\n        new Info(Opcodes.CONST_STRING, \"const-string\",\n            InstructionCodec.FORMAT_21C, IndexType.STRING_REF);\n\n    public static final Info CONST_STRING_JUMBO =\n        new Info(Opcodes.CONST_STRING_JUMBO, \"const-string/jumbo\",\n            InstructionCodec.FORMAT_31C, IndexType.STRING_REF);\n\n    public static final Info CONST_CLASS =\n        new Info(Opcodes.CONST_CLASS, \"const-class\",\n            InstructionCodec.FORMAT_21C, IndexType.TYPE_REF);\n\n    public static final Info MONITOR_ENTER =\n        new Info(Opcodes.MONITOR_ENTER, \"monitor-enter\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info MONITOR_EXIT =\n        new Info(Opcodes.MONITOR_EXIT, \"monitor-exit\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info CHECK_CAST =\n        new Info(Opcodes.CHECK_CAST, \"check-cast\",\n            InstructionCodec.FORMAT_21C, IndexType.TYPE_REF);\n\n    public static final Info INSTANCE_OF =\n        new Info(Opcodes.INSTANCE_OF, \"instance-of\",\n            InstructionCodec.FORMAT_22C, IndexType.TYPE_REF);\n\n    public static final Info ARRAY_LENGTH =\n        new Info(Opcodes.ARRAY_LENGTH, \"array-length\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info NEW_INSTANCE =\n        new Info(Opcodes.NEW_INSTANCE, \"new-instance\",\n            InstructionCodec.FORMAT_21C, IndexType.TYPE_REF);\n\n    public static final Info NEW_ARRAY =\n        new Info(Opcodes.NEW_ARRAY, \"new-array\",\n            InstructionCodec.FORMAT_22C, IndexType.TYPE_REF);\n\n    public static final Info FILLED_NEW_ARRAY =\n        new Info(Opcodes.FILLED_NEW_ARRAY, \"filled-new-array\",\n            InstructionCodec.FORMAT_35C, IndexType.TYPE_REF);\n\n    public static final Info FILLED_NEW_ARRAY_RANGE =\n        new Info(Opcodes.FILLED_NEW_ARRAY_RANGE, \"filled-new-array/range\",\n            InstructionCodec.FORMAT_3RC, IndexType.TYPE_REF);\n\n    public static final Info FILL_ARRAY_DATA =\n        new Info(Opcodes.FILL_ARRAY_DATA, \"fill-array-data\",\n            InstructionCodec.FORMAT_31T, IndexType.NONE);\n\n    public static final Info THROW =\n        new Info(Opcodes.THROW, \"throw\",\n            InstructionCodec.FORMAT_11X, IndexType.NONE);\n\n    public static final Info GOTO =\n        new Info(Opcodes.GOTO, \"goto\",\n            InstructionCodec.FORMAT_10T, IndexType.NONE);\n\n    public static final Info GOTO_16 =\n        new Info(Opcodes.GOTO_16, \"goto/16\",\n            InstructionCodec.FORMAT_20T, IndexType.NONE);\n\n    public static final Info GOTO_32 =\n        new Info(Opcodes.GOTO_32, \"goto/32\",\n            InstructionCodec.FORMAT_30T, IndexType.NONE);\n\n    public static final Info PACKED_SWITCH =\n        new Info(Opcodes.PACKED_SWITCH, \"packed-switch\",\n            InstructionCodec.FORMAT_31T, IndexType.NONE);\n\n    public static final Info SPARSE_SWITCH =\n        new Info(Opcodes.SPARSE_SWITCH, \"sparse-switch\",\n            InstructionCodec.FORMAT_31T, IndexType.NONE);\n\n    public static final Info CMPL_FLOAT =\n        new Info(Opcodes.CMPL_FLOAT, \"cmpl-float\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info CMPG_FLOAT =\n        new Info(Opcodes.CMPG_FLOAT, \"cmpg-float\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info CMPL_DOUBLE =\n        new Info(Opcodes.CMPL_DOUBLE, \"cmpl-double\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info CMPG_DOUBLE =\n        new Info(Opcodes.CMPG_DOUBLE, \"cmpg-double\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info CMP_LONG =\n        new Info(Opcodes.CMP_LONG, \"cmp-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info IF_EQ =\n        new Info(Opcodes.IF_EQ, \"if-eq\",\n            InstructionCodec.FORMAT_22T, IndexType.NONE);\n\n    public static final Info IF_NE =\n        new Info(Opcodes.IF_NE, \"if-ne\",\n            InstructionCodec.FORMAT_22T, IndexType.NONE);\n\n    public static final Info IF_LT =\n        new Info(Opcodes.IF_LT, \"if-lt\",\n            InstructionCodec.FORMAT_22T, IndexType.NONE);\n\n    public static final Info IF_GE =\n        new Info(Opcodes.IF_GE, \"if-ge\",\n            InstructionCodec.FORMAT_22T, IndexType.NONE);\n\n    public static final Info IF_GT =\n        new Info(Opcodes.IF_GT, \"if-gt\",\n            InstructionCodec.FORMAT_22T, IndexType.NONE);\n\n    public static final Info IF_LE =\n        new Info(Opcodes.IF_LE, \"if-le\",\n            InstructionCodec.FORMAT_22T, IndexType.NONE);\n\n    public static final Info IF_EQZ =\n        new Info(Opcodes.IF_EQZ, \"if-eqz\",\n            InstructionCodec.FORMAT_21T, IndexType.NONE);\n\n    public static final Info IF_NEZ =\n        new Info(Opcodes.IF_NEZ, \"if-nez\",\n            InstructionCodec.FORMAT_21T, IndexType.NONE);\n\n    public static final Info IF_LTZ =\n        new Info(Opcodes.IF_LTZ, \"if-ltz\",\n            InstructionCodec.FORMAT_21T, IndexType.NONE);\n\n    public static final Info IF_GEZ =\n        new Info(Opcodes.IF_GEZ, \"if-gez\",\n            InstructionCodec.FORMAT_21T, IndexType.NONE);\n\n    public static final Info IF_GTZ =\n        new Info(Opcodes.IF_GTZ, \"if-gtz\",\n            InstructionCodec.FORMAT_21T, IndexType.NONE);\n\n    public static final Info IF_LEZ =\n        new Info(Opcodes.IF_LEZ, \"if-lez\",\n            InstructionCodec.FORMAT_21T, IndexType.NONE);\n\n    public static final Info AGET =\n        new Info(Opcodes.AGET, \"aget\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AGET_WIDE =\n        new Info(Opcodes.AGET_WIDE, \"aget-wide\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AGET_OBJECT =\n        new Info(Opcodes.AGET_OBJECT, \"aget-object\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AGET_BOOLEAN =\n        new Info(Opcodes.AGET_BOOLEAN, \"aget-boolean\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AGET_BYTE =\n        new Info(Opcodes.AGET_BYTE, \"aget-byte\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AGET_CHAR =\n        new Info(Opcodes.AGET_CHAR, \"aget-char\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AGET_SHORT =\n        new Info(Opcodes.AGET_SHORT, \"aget-short\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info APUT =\n        new Info(Opcodes.APUT, \"aput\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info APUT_WIDE =\n        new Info(Opcodes.APUT_WIDE, \"aput-wide\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info APUT_OBJECT =\n        new Info(Opcodes.APUT_OBJECT, \"aput-object\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info APUT_BOOLEAN =\n        new Info(Opcodes.APUT_BOOLEAN, \"aput-boolean\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info APUT_BYTE =\n        new Info(Opcodes.APUT_BYTE, \"aput-byte\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info APUT_CHAR =\n        new Info(Opcodes.APUT_CHAR, \"aput-char\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info APUT_SHORT =\n        new Info(Opcodes.APUT_SHORT, \"aput-short\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info IGET =\n        new Info(Opcodes.IGET, \"iget\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IGET_WIDE =\n        new Info(Opcodes.IGET_WIDE, \"iget-wide\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IGET_OBJECT =\n        new Info(Opcodes.IGET_OBJECT, \"iget-object\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IGET_BOOLEAN =\n        new Info(Opcodes.IGET_BOOLEAN, \"iget-boolean\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IGET_BYTE =\n        new Info(Opcodes.IGET_BYTE, \"iget-byte\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IGET_CHAR =\n        new Info(Opcodes.IGET_CHAR, \"iget-char\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IGET_SHORT =\n        new Info(Opcodes.IGET_SHORT, \"iget-short\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IPUT =\n        new Info(Opcodes.IPUT, \"iput\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IPUT_WIDE =\n        new Info(Opcodes.IPUT_WIDE, \"iput-wide\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IPUT_OBJECT =\n        new Info(Opcodes.IPUT_OBJECT, \"iput-object\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IPUT_BOOLEAN =\n        new Info(Opcodes.IPUT_BOOLEAN, \"iput-boolean\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IPUT_BYTE =\n        new Info(Opcodes.IPUT_BYTE, \"iput-byte\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IPUT_CHAR =\n        new Info(Opcodes.IPUT_CHAR, \"iput-char\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info IPUT_SHORT =\n        new Info(Opcodes.IPUT_SHORT, \"iput-short\",\n            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);\n\n    public static final Info SGET =\n        new Info(Opcodes.SGET, \"sget\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SGET_WIDE =\n        new Info(Opcodes.SGET_WIDE, \"sget-wide\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SGET_OBJECT =\n        new Info(Opcodes.SGET_OBJECT, \"sget-object\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SGET_BOOLEAN =\n        new Info(Opcodes.SGET_BOOLEAN, \"sget-boolean\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SGET_BYTE =\n        new Info(Opcodes.SGET_BYTE, \"sget-byte\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SGET_CHAR =\n        new Info(Opcodes.SGET_CHAR, \"sget-char\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SGET_SHORT =\n        new Info(Opcodes.SGET_SHORT, \"sget-short\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SPUT =\n        new Info(Opcodes.SPUT, \"sput\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SPUT_WIDE =\n        new Info(Opcodes.SPUT_WIDE, \"sput-wide\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SPUT_OBJECT =\n        new Info(Opcodes.SPUT_OBJECT, \"sput-object\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SPUT_BOOLEAN =\n        new Info(Opcodes.SPUT_BOOLEAN, \"sput-boolean\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SPUT_BYTE =\n        new Info(Opcodes.SPUT_BYTE, \"sput-byte\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SPUT_CHAR =\n        new Info(Opcodes.SPUT_CHAR, \"sput-char\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info SPUT_SHORT =\n        new Info(Opcodes.SPUT_SHORT, \"sput-short\",\n            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);\n\n    public static final Info INVOKE_VIRTUAL =\n        new Info(Opcodes.INVOKE_VIRTUAL, \"invoke-virtual\",\n            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_SUPER =\n        new Info(Opcodes.INVOKE_SUPER, \"invoke-super\",\n            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_DIRECT =\n        new Info(Opcodes.INVOKE_DIRECT, \"invoke-direct\",\n            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_STATIC =\n        new Info(Opcodes.INVOKE_STATIC, \"invoke-static\",\n            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_INTERFACE =\n        new Info(Opcodes.INVOKE_INTERFACE, \"invoke-interface\",\n            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_VIRTUAL_RANGE =\n        new Info(Opcodes.INVOKE_VIRTUAL_RANGE, \"invoke-virtual/range\",\n            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_SUPER_RANGE =\n        new Info(Opcodes.INVOKE_SUPER_RANGE, \"invoke-super/range\",\n            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_DIRECT_RANGE =\n        new Info(Opcodes.INVOKE_DIRECT_RANGE, \"invoke-direct/range\",\n            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_STATIC_RANGE =\n        new Info(Opcodes.INVOKE_STATIC_RANGE, \"invoke-static/range\",\n            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);\n\n    public static final Info INVOKE_INTERFACE_RANGE =\n        new Info(Opcodes.INVOKE_INTERFACE_RANGE, \"invoke-interface/range\",\n            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);\n\n    public static final Info NEG_INT =\n        new Info(Opcodes.NEG_INT, \"neg-int\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info NOT_INT =\n        new Info(Opcodes.NOT_INT, \"not-int\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info NEG_LONG =\n        new Info(Opcodes.NEG_LONG, \"neg-long\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info NOT_LONG =\n        new Info(Opcodes.NOT_LONG, \"not-long\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info NEG_FLOAT =\n        new Info(Opcodes.NEG_FLOAT, \"neg-float\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info NEG_DOUBLE =\n        new Info(Opcodes.NEG_DOUBLE, \"neg-double\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info INT_TO_LONG =\n        new Info(Opcodes.INT_TO_LONG, \"int-to-long\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info INT_TO_FLOAT =\n        new Info(Opcodes.INT_TO_FLOAT, \"int-to-float\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info INT_TO_DOUBLE =\n        new Info(Opcodes.INT_TO_DOUBLE, \"int-to-double\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info LONG_TO_INT =\n        new Info(Opcodes.LONG_TO_INT, \"long-to-int\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info LONG_TO_FLOAT =\n        new Info(Opcodes.LONG_TO_FLOAT, \"long-to-float\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info LONG_TO_DOUBLE =\n        new Info(Opcodes.LONG_TO_DOUBLE, \"long-to-double\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info FLOAT_TO_INT =\n        new Info(Opcodes.FLOAT_TO_INT, \"float-to-int\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info FLOAT_TO_LONG =\n        new Info(Opcodes.FLOAT_TO_LONG, \"float-to-long\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info FLOAT_TO_DOUBLE =\n        new Info(Opcodes.FLOAT_TO_DOUBLE, \"float-to-double\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info DOUBLE_TO_INT =\n        new Info(Opcodes.DOUBLE_TO_INT, \"double-to-int\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info DOUBLE_TO_LONG =\n        new Info(Opcodes.DOUBLE_TO_LONG, \"double-to-long\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info DOUBLE_TO_FLOAT =\n        new Info(Opcodes.DOUBLE_TO_FLOAT, \"double-to-float\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info INT_TO_BYTE =\n        new Info(Opcodes.INT_TO_BYTE, \"int-to-byte\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info INT_TO_CHAR =\n        new Info(Opcodes.INT_TO_CHAR, \"int-to-char\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info INT_TO_SHORT =\n        new Info(Opcodes.INT_TO_SHORT, \"int-to-short\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info ADD_INT =\n        new Info(Opcodes.ADD_INT, \"add-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SUB_INT =\n        new Info(Opcodes.SUB_INT, \"sub-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info MUL_INT =\n        new Info(Opcodes.MUL_INT, \"mul-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info DIV_INT =\n        new Info(Opcodes.DIV_INT, \"div-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info REM_INT =\n        new Info(Opcodes.REM_INT, \"rem-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AND_INT =\n        new Info(Opcodes.AND_INT, \"and-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info OR_INT =\n        new Info(Opcodes.OR_INT, \"or-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info XOR_INT =\n        new Info(Opcodes.XOR_INT, \"xor-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SHL_INT =\n        new Info(Opcodes.SHL_INT, \"shl-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SHR_INT =\n        new Info(Opcodes.SHR_INT, \"shr-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info USHR_INT =\n        new Info(Opcodes.USHR_INT, \"ushr-int\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info ADD_LONG =\n        new Info(Opcodes.ADD_LONG, \"add-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SUB_LONG =\n        new Info(Opcodes.SUB_LONG, \"sub-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info MUL_LONG =\n        new Info(Opcodes.MUL_LONG, \"mul-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info DIV_LONG =\n        new Info(Opcodes.DIV_LONG, \"div-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info REM_LONG =\n        new Info(Opcodes.REM_LONG, \"rem-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info AND_LONG =\n        new Info(Opcodes.AND_LONG, \"and-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info OR_LONG =\n        new Info(Opcodes.OR_LONG, \"or-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info XOR_LONG =\n        new Info(Opcodes.XOR_LONG, \"xor-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SHL_LONG =\n        new Info(Opcodes.SHL_LONG, \"shl-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SHR_LONG =\n        new Info(Opcodes.SHR_LONG, \"shr-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info USHR_LONG =\n        new Info(Opcodes.USHR_LONG, \"ushr-long\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info ADD_FLOAT =\n        new Info(Opcodes.ADD_FLOAT, \"add-float\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SUB_FLOAT =\n        new Info(Opcodes.SUB_FLOAT, \"sub-float\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info MUL_FLOAT =\n        new Info(Opcodes.MUL_FLOAT, \"mul-float\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info DIV_FLOAT =\n        new Info(Opcodes.DIV_FLOAT, \"div-float\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info REM_FLOAT =\n        new Info(Opcodes.REM_FLOAT, \"rem-float\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info ADD_DOUBLE =\n        new Info(Opcodes.ADD_DOUBLE, \"add-double\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info SUB_DOUBLE =\n        new Info(Opcodes.SUB_DOUBLE, \"sub-double\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info MUL_DOUBLE =\n        new Info(Opcodes.MUL_DOUBLE, \"mul-double\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info DIV_DOUBLE =\n        new Info(Opcodes.DIV_DOUBLE, \"div-double\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info REM_DOUBLE =\n        new Info(Opcodes.REM_DOUBLE, \"rem-double\",\n            InstructionCodec.FORMAT_23X, IndexType.NONE);\n\n    public static final Info ADD_INT_2ADDR =\n        new Info(Opcodes.ADD_INT_2ADDR, \"add-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SUB_INT_2ADDR =\n        new Info(Opcodes.SUB_INT_2ADDR, \"sub-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info MUL_INT_2ADDR =\n        new Info(Opcodes.MUL_INT_2ADDR, \"mul-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info DIV_INT_2ADDR =\n        new Info(Opcodes.DIV_INT_2ADDR, \"div-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info REM_INT_2ADDR =\n        new Info(Opcodes.REM_INT_2ADDR, \"rem-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info AND_INT_2ADDR =\n        new Info(Opcodes.AND_INT_2ADDR, \"and-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info OR_INT_2ADDR =\n        new Info(Opcodes.OR_INT_2ADDR, \"or-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info XOR_INT_2ADDR =\n        new Info(Opcodes.XOR_INT_2ADDR, \"xor-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SHL_INT_2ADDR =\n        new Info(Opcodes.SHL_INT_2ADDR, \"shl-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SHR_INT_2ADDR =\n        new Info(Opcodes.SHR_INT_2ADDR, \"shr-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info USHR_INT_2ADDR =\n        new Info(Opcodes.USHR_INT_2ADDR, \"ushr-int/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info ADD_LONG_2ADDR =\n        new Info(Opcodes.ADD_LONG_2ADDR, \"add-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SUB_LONG_2ADDR =\n        new Info(Opcodes.SUB_LONG_2ADDR, \"sub-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info MUL_LONG_2ADDR =\n        new Info(Opcodes.MUL_LONG_2ADDR, \"mul-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info DIV_LONG_2ADDR =\n        new Info(Opcodes.DIV_LONG_2ADDR, \"div-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info REM_LONG_2ADDR =\n        new Info(Opcodes.REM_LONG_2ADDR, \"rem-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info AND_LONG_2ADDR =\n        new Info(Opcodes.AND_LONG_2ADDR, \"and-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info OR_LONG_2ADDR =\n        new Info(Opcodes.OR_LONG_2ADDR, \"or-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info XOR_LONG_2ADDR =\n        new Info(Opcodes.XOR_LONG_2ADDR, \"xor-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SHL_LONG_2ADDR =\n        new Info(Opcodes.SHL_LONG_2ADDR, \"shl-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SHR_LONG_2ADDR =\n        new Info(Opcodes.SHR_LONG_2ADDR, \"shr-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info USHR_LONG_2ADDR =\n        new Info(Opcodes.USHR_LONG_2ADDR, \"ushr-long/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info ADD_FLOAT_2ADDR =\n        new Info(Opcodes.ADD_FLOAT_2ADDR, \"add-float/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SUB_FLOAT_2ADDR =\n        new Info(Opcodes.SUB_FLOAT_2ADDR, \"sub-float/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info MUL_FLOAT_2ADDR =\n        new Info(Opcodes.MUL_FLOAT_2ADDR, \"mul-float/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info DIV_FLOAT_2ADDR =\n        new Info(Opcodes.DIV_FLOAT_2ADDR, \"div-float/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info REM_FLOAT_2ADDR =\n        new Info(Opcodes.REM_FLOAT_2ADDR, \"rem-float/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info ADD_DOUBLE_2ADDR =\n        new Info(Opcodes.ADD_DOUBLE_2ADDR, \"add-double/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info SUB_DOUBLE_2ADDR =\n        new Info(Opcodes.SUB_DOUBLE_2ADDR, \"sub-double/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info MUL_DOUBLE_2ADDR =\n        new Info(Opcodes.MUL_DOUBLE_2ADDR, \"mul-double/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info DIV_DOUBLE_2ADDR =\n        new Info(Opcodes.DIV_DOUBLE_2ADDR, \"div-double/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info REM_DOUBLE_2ADDR =\n        new Info(Opcodes.REM_DOUBLE_2ADDR, \"rem-double/2addr\",\n            InstructionCodec.FORMAT_12X, IndexType.NONE);\n\n    public static final Info ADD_INT_LIT16 =\n        new Info(Opcodes.ADD_INT_LIT16, \"add-int/lit16\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info RSUB_INT =\n        new Info(Opcodes.RSUB_INT, \"rsub-int\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info MUL_INT_LIT16 =\n        new Info(Opcodes.MUL_INT_LIT16, \"mul-int/lit16\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info DIV_INT_LIT16 =\n        new Info(Opcodes.DIV_INT_LIT16, \"div-int/lit16\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info REM_INT_LIT16 =\n        new Info(Opcodes.REM_INT_LIT16, \"rem-int/lit16\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info AND_INT_LIT16 =\n        new Info(Opcodes.AND_INT_LIT16, \"and-int/lit16\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info OR_INT_LIT16 =\n        new Info(Opcodes.OR_INT_LIT16, \"or-int/lit16\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info XOR_INT_LIT16 =\n        new Info(Opcodes.XOR_INT_LIT16, \"xor-int/lit16\",\n            InstructionCodec.FORMAT_22S, IndexType.NONE);\n\n    public static final Info ADD_INT_LIT8 =\n        new Info(Opcodes.ADD_INT_LIT8, \"add-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info RSUB_INT_LIT8 =\n        new Info(Opcodes.RSUB_INT_LIT8, \"rsub-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info MUL_INT_LIT8 =\n        new Info(Opcodes.MUL_INT_LIT8, \"mul-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info DIV_INT_LIT8 =\n        new Info(Opcodes.DIV_INT_LIT8, \"div-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info REM_INT_LIT8 =\n        new Info(Opcodes.REM_INT_LIT8, \"rem-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info AND_INT_LIT8 =\n        new Info(Opcodes.AND_INT_LIT8, \"and-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info OR_INT_LIT8 =\n        new Info(Opcodes.OR_INT_LIT8, \"or-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info XOR_INT_LIT8 =\n        new Info(Opcodes.XOR_INT_LIT8, \"xor-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info SHL_INT_LIT8 =\n        new Info(Opcodes.SHL_INT_LIT8, \"shl-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info SHR_INT_LIT8 =\n        new Info(Opcodes.SHR_INT_LIT8, \"shr-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    public static final Info USHR_INT_LIT8 =\n        new Info(Opcodes.USHR_INT_LIT8, \"ushr-int/lit8\",\n            InstructionCodec.FORMAT_22B, IndexType.NONE);\n\n    // END(opcode-info-defs)\n\n    // Static initialization.\n    static {\n        INFO = new Info[Opcodes.MAX_VALUE - Opcodes.MIN_VALUE + 1];\n\n        // TODO: Stop using this constant.\n        set(SPECIAL_FORMAT);\n\n        // TODO: These payload opcodes should be generated by opcode-gen.\n        set(PACKED_SWITCH_PAYLOAD);\n        set(SPARSE_SWITCH_PAYLOAD);\n        set(FILL_ARRAY_DATA_PAYLOAD);\n\n        // BEGIN(opcode-info-init); GENERATED AUTOMATICALLY BY opcode-gen\n        set(NOP);\n        set(MOVE);\n        set(MOVE_FROM16);\n        set(MOVE_16);\n        set(MOVE_WIDE);\n        set(MOVE_WIDE_FROM16);\n        set(MOVE_WIDE_16);\n        set(MOVE_OBJECT);\n        set(MOVE_OBJECT_FROM16);\n        set(MOVE_OBJECT_16);\n        set(MOVE_RESULT);\n        set(MOVE_RESULT_WIDE);\n        set(MOVE_RESULT_OBJECT);\n        set(MOVE_EXCEPTION);\n        set(RETURN_VOID);\n        set(RETURN);\n        set(RETURN_WIDE);\n        set(RETURN_OBJECT);\n        set(CONST_4);\n        set(CONST_16);\n        set(CONST);\n        set(CONST_HIGH16);\n        set(CONST_WIDE_16);\n        set(CONST_WIDE_32);\n        set(CONST_WIDE);\n        set(CONST_WIDE_HIGH16);\n        set(CONST_STRING);\n        set(CONST_STRING_JUMBO);\n        set(CONST_CLASS);\n        set(MONITOR_ENTER);\n        set(MONITOR_EXIT);\n        set(CHECK_CAST);\n        set(INSTANCE_OF);\n        set(ARRAY_LENGTH);\n        set(NEW_INSTANCE);\n        set(NEW_ARRAY);\n        set(FILLED_NEW_ARRAY);\n        set(FILLED_NEW_ARRAY_RANGE);\n        set(FILL_ARRAY_DATA);\n        set(THROW);\n        set(GOTO);\n        set(GOTO_16);\n        set(GOTO_32);\n        set(PACKED_SWITCH);\n        set(SPARSE_SWITCH);\n        set(CMPL_FLOAT);\n        set(CMPG_FLOAT);\n        set(CMPL_DOUBLE);\n        set(CMPG_DOUBLE);\n        set(CMP_LONG);\n        set(IF_EQ);\n        set(IF_NE);\n        set(IF_LT);\n        set(IF_GE);\n        set(IF_GT);\n        set(IF_LE);\n        set(IF_EQZ);\n        set(IF_NEZ);\n        set(IF_LTZ);\n        set(IF_GEZ);\n        set(IF_GTZ);\n        set(IF_LEZ);\n        set(AGET);\n        set(AGET_WIDE);\n        set(AGET_OBJECT);\n        set(AGET_BOOLEAN);\n        set(AGET_BYTE);\n        set(AGET_CHAR);\n        set(AGET_SHORT);\n        set(APUT);\n        set(APUT_WIDE);\n        set(APUT_OBJECT);\n        set(APUT_BOOLEAN);\n        set(APUT_BYTE);\n        set(APUT_CHAR);\n        set(APUT_SHORT);\n        set(IGET);\n        set(IGET_WIDE);\n        set(IGET_OBJECT);\n        set(IGET_BOOLEAN);\n        set(IGET_BYTE);\n        set(IGET_CHAR);\n        set(IGET_SHORT);\n        set(IPUT);\n        set(IPUT_WIDE);\n        set(IPUT_OBJECT);\n        set(IPUT_BOOLEAN);\n        set(IPUT_BYTE);\n        set(IPUT_CHAR);\n        set(IPUT_SHORT);\n        set(SGET);\n        set(SGET_WIDE);\n        set(SGET_OBJECT);\n        set(SGET_BOOLEAN);\n        set(SGET_BYTE);\n        set(SGET_CHAR);\n        set(SGET_SHORT);\n        set(SPUT);\n        set(SPUT_WIDE);\n        set(SPUT_OBJECT);\n        set(SPUT_BOOLEAN);\n        set(SPUT_BYTE);\n        set(SPUT_CHAR);\n        set(SPUT_SHORT);\n        set(INVOKE_VIRTUAL);\n        set(INVOKE_SUPER);\n        set(INVOKE_DIRECT);\n        set(INVOKE_STATIC);\n        set(INVOKE_INTERFACE);\n        set(INVOKE_VIRTUAL_RANGE);\n        set(INVOKE_SUPER_RANGE);\n        set(INVOKE_DIRECT_RANGE);\n        set(INVOKE_STATIC_RANGE);\n        set(INVOKE_INTERFACE_RANGE);\n        set(NEG_INT);\n        set(NOT_INT);\n        set(NEG_LONG);\n        set(NOT_LONG);\n        set(NEG_FLOAT);\n        set(NEG_DOUBLE);\n        set(INT_TO_LONG);\n        set(INT_TO_FLOAT);\n        set(INT_TO_DOUBLE);\n        set(LONG_TO_INT);\n        set(LONG_TO_FLOAT);\n        set(LONG_TO_DOUBLE);\n        set(FLOAT_TO_INT);\n        set(FLOAT_TO_LONG);\n        set(FLOAT_TO_DOUBLE);\n        set(DOUBLE_TO_INT);\n        set(DOUBLE_TO_LONG);\n        set(DOUBLE_TO_FLOAT);\n        set(INT_TO_BYTE);\n        set(INT_TO_CHAR);\n        set(INT_TO_SHORT);\n        set(ADD_INT);\n        set(SUB_INT);\n        set(MUL_INT);\n        set(DIV_INT);\n        set(REM_INT);\n        set(AND_INT);\n        set(OR_INT);\n        set(XOR_INT);\n        set(SHL_INT);\n        set(SHR_INT);\n        set(USHR_INT);\n        set(ADD_LONG);\n        set(SUB_LONG);\n        set(MUL_LONG);\n        set(DIV_LONG);\n        set(REM_LONG);\n        set(AND_LONG);\n        set(OR_LONG);\n        set(XOR_LONG);\n        set(SHL_LONG);\n        set(SHR_LONG);\n        set(USHR_LONG);\n        set(ADD_FLOAT);\n        set(SUB_FLOAT);\n        set(MUL_FLOAT);\n        set(DIV_FLOAT);\n        set(REM_FLOAT);\n        set(ADD_DOUBLE);\n        set(SUB_DOUBLE);\n        set(MUL_DOUBLE);\n        set(DIV_DOUBLE);\n        set(REM_DOUBLE);\n        set(ADD_INT_2ADDR);\n        set(SUB_INT_2ADDR);\n        set(MUL_INT_2ADDR);\n        set(DIV_INT_2ADDR);\n        set(REM_INT_2ADDR);\n        set(AND_INT_2ADDR);\n        set(OR_INT_2ADDR);\n        set(XOR_INT_2ADDR);\n        set(SHL_INT_2ADDR);\n        set(SHR_INT_2ADDR);\n        set(USHR_INT_2ADDR);\n        set(ADD_LONG_2ADDR);\n        set(SUB_LONG_2ADDR);\n        set(MUL_LONG_2ADDR);\n        set(DIV_LONG_2ADDR);\n        set(REM_LONG_2ADDR);\n        set(AND_LONG_2ADDR);\n        set(OR_LONG_2ADDR);\n        set(XOR_LONG_2ADDR);\n        set(SHL_LONG_2ADDR);\n        set(SHR_LONG_2ADDR);\n        set(USHR_LONG_2ADDR);\n        set(ADD_FLOAT_2ADDR);\n        set(SUB_FLOAT_2ADDR);\n        set(MUL_FLOAT_2ADDR);\n        set(DIV_FLOAT_2ADDR);\n        set(REM_FLOAT_2ADDR);\n        set(ADD_DOUBLE_2ADDR);\n        set(SUB_DOUBLE_2ADDR);\n        set(MUL_DOUBLE_2ADDR);\n        set(DIV_DOUBLE_2ADDR);\n        set(REM_DOUBLE_2ADDR);\n        set(ADD_INT_LIT16);\n        set(RSUB_INT);\n        set(MUL_INT_LIT16);\n        set(DIV_INT_LIT16);\n        set(REM_INT_LIT16);\n        set(AND_INT_LIT16);\n        set(OR_INT_LIT16);\n        set(XOR_INT_LIT16);\n        set(ADD_INT_LIT8);\n        set(RSUB_INT_LIT8);\n        set(MUL_INT_LIT8);\n        set(DIV_INT_LIT8);\n        set(REM_INT_LIT8);\n        set(AND_INT_LIT8);\n        set(OR_INT_LIT8);\n        set(XOR_INT_LIT8);\n        set(SHL_INT_LIT8);\n        set(SHR_INT_LIT8);\n        set(USHR_INT_LIT8);\n        // END(opcode-info-init)\n    }\n\n    /**\n     * This class is uninstantiable.\n     */\n    private OpcodeInfo() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Gets the {@link @Info} for the given opcode value.\n     *\n     * @param opcode {@code Opcodes.MIN_VALUE..Opcodes.MAX_VALUE;} the\n     * opcode value\n     * @return non-null; the associated opcode information instance\n     */\n    public static Info get(int opcode) {\n        int idx = opcode - Opcodes.MIN_VALUE;\n\n        try {\n            Info result = INFO[idx];\n            if (result != null) {\n                return result;\n            }\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Fall through.\n        }\n\n        throw new IllegalArgumentException(\"bogus opcode: \"\n                + Hex.u2or4(opcode));\n    }\n\n    /**\n     * Gets the name of the given opcode.\n     */\n    public static String getName(int opcode) {\n        return get(opcode).getName();\n    }\n\n    /**\n     * value.\n     */\n    public static InstructionCodec getFormat(int opcode) {\n        return get(opcode).getFormat();\n    }\n\n    /**\n     * Gets the {@link IndexType} for the given opcode value.\n     */\n    public static IndexType getIndexType(int opcode) {\n        return get(opcode).getIndexType();\n    }\n\n    /**\n     * Puts the given opcode into the table of all ops.\n     *\n     * @param opcode non-null; the opcode\n     */\n    private static void set(Info opcode) {\n        int idx = opcode.getOpcode() - Opcodes.MIN_VALUE;\n        INFO[idx] = opcode;\n    }\n\n    /**\n     * Information about an opcode.\n     */\n    public static class Info {\n        private final int opcode;\n        private final String name;\n        private final InstructionCodec format;\n        private final IndexType indexType;\n\n        public Info(int opcode, String name, InstructionCodec format,\n                IndexType indexType) {\n            this.opcode = opcode;\n            this.name = name;\n            this.format = format;\n            this.indexType = indexType;\n        }\n\n        public int getOpcode() {\n            return opcode;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public InstructionCodec getFormat() {\n            return format;\n        }\n\n        public IndexType getIndexType() {\n            return indexType;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/Opcodes.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io;\n\n/**\n * All the Dalvik opcode value constants. See the related spec\n * document for the meaning and instruction format of each opcode.\n */\npublic final class Opcodes {\n    /**\n     * pseudo-opcode used for nonstandard format payload \"instructions\". TODO:\n     * Retire this concept, and start treating the payload instructions\n     * more like the rest.\n     */\n    public static final int SPECIAL_FORMAT = -1;\n\n    /**\n     * pseudo-opcode used to indicate there is no next opcode; used\n     * in opcode chaining lists\n     */\n    public static final int NO_NEXT = -1;\n\n    /** minimum valid opcode value */\n    public static final int MIN_VALUE = -1;\n\n    /** maximum valid opcode value */\n    public static final int MAX_VALUE = 0xffff;\n\n    // BEGIN(opcodes); GENERATED AUTOMATICALLY BY opcode-gen\n    public static final int NOP = 0x00;\n    public static final int MOVE = 0x01;\n    public static final int MOVE_FROM16 = 0x02;\n    public static final int MOVE_16 = 0x03;\n    public static final int MOVE_WIDE = 0x04;\n    public static final int MOVE_WIDE_FROM16 = 0x05;\n    public static final int MOVE_WIDE_16 = 0x06;\n    public static final int MOVE_OBJECT = 0x07;\n    public static final int MOVE_OBJECT_FROM16 = 0x08;\n    public static final int MOVE_OBJECT_16 = 0x09;\n    public static final int MOVE_RESULT = 0x0a;\n    public static final int MOVE_RESULT_WIDE = 0x0b;\n    public static final int MOVE_RESULT_OBJECT = 0x0c;\n    public static final int MOVE_EXCEPTION = 0x0d;\n    public static final int RETURN_VOID = 0x0e;\n    public static final int RETURN = 0x0f;\n    public static final int RETURN_WIDE = 0x10;\n    public static final int RETURN_OBJECT = 0x11;\n    public static final int CONST_4 = 0x12;\n    public static final int CONST_16 = 0x13;\n    public static final int CONST = 0x14;\n    public static final int CONST_HIGH16 = 0x15;\n    public static final int CONST_WIDE_16 = 0x16;\n    public static final int CONST_WIDE_32 = 0x17;\n    public static final int CONST_WIDE = 0x18;\n    public static final int CONST_WIDE_HIGH16 = 0x19;\n    public static final int CONST_STRING = 0x1a;\n    public static final int CONST_STRING_JUMBO = 0x1b;\n    public static final int CONST_CLASS = 0x1c;\n    public static final int MONITOR_ENTER = 0x1d;\n    public static final int MONITOR_EXIT = 0x1e;\n    public static final int CHECK_CAST = 0x1f;\n    public static final int INSTANCE_OF = 0x20;\n    public static final int ARRAY_LENGTH = 0x21;\n    public static final int NEW_INSTANCE = 0x22;\n    public static final int NEW_ARRAY = 0x23;\n    public static final int FILLED_NEW_ARRAY = 0x24;\n    public static final int FILLED_NEW_ARRAY_RANGE = 0x25;\n    public static final int FILL_ARRAY_DATA = 0x26;\n    public static final int THROW = 0x27;\n    public static final int GOTO = 0x28;\n    public static final int GOTO_16 = 0x29;\n    public static final int GOTO_32 = 0x2a;\n    public static final int PACKED_SWITCH = 0x2b;\n    public static final int SPARSE_SWITCH = 0x2c;\n    public static final int CMPL_FLOAT = 0x2d;\n    public static final int CMPG_FLOAT = 0x2e;\n    public static final int CMPL_DOUBLE = 0x2f;\n    public static final int CMPG_DOUBLE = 0x30;\n    public static final int CMP_LONG = 0x31;\n    public static final int IF_EQ = 0x32;\n    public static final int IF_NE = 0x33;\n    public static final int IF_LT = 0x34;\n    public static final int IF_GE = 0x35;\n    public static final int IF_GT = 0x36;\n    public static final int IF_LE = 0x37;\n    public static final int IF_EQZ = 0x38;\n    public static final int IF_NEZ = 0x39;\n    public static final int IF_LTZ = 0x3a;\n    public static final int IF_GEZ = 0x3b;\n    public static final int IF_GTZ = 0x3c;\n    public static final int IF_LEZ = 0x3d;\n    public static final int AGET = 0x44;\n    public static final int AGET_WIDE = 0x45;\n    public static final int AGET_OBJECT = 0x46;\n    public static final int AGET_BOOLEAN = 0x47;\n    public static final int AGET_BYTE = 0x48;\n    public static final int AGET_CHAR = 0x49;\n    public static final int AGET_SHORT = 0x4a;\n    public static final int APUT = 0x4b;\n    public static final int APUT_WIDE = 0x4c;\n    public static final int APUT_OBJECT = 0x4d;\n    public static final int APUT_BOOLEAN = 0x4e;\n    public static final int APUT_BYTE = 0x4f;\n    public static final int APUT_CHAR = 0x50;\n    public static final int APUT_SHORT = 0x51;\n    public static final int IGET = 0x52;\n    public static final int IGET_WIDE = 0x53;\n    public static final int IGET_OBJECT = 0x54;\n    public static final int IGET_BOOLEAN = 0x55;\n    public static final int IGET_BYTE = 0x56;\n    public static final int IGET_CHAR = 0x57;\n    public static final int IGET_SHORT = 0x58;\n    public static final int IPUT = 0x59;\n    public static final int IPUT_WIDE = 0x5a;\n    public static final int IPUT_OBJECT = 0x5b;\n    public static final int IPUT_BOOLEAN = 0x5c;\n    public static final int IPUT_BYTE = 0x5d;\n    public static final int IPUT_CHAR = 0x5e;\n    public static final int IPUT_SHORT = 0x5f;\n    public static final int SGET = 0x60;\n    public static final int SGET_WIDE = 0x61;\n    public static final int SGET_OBJECT = 0x62;\n    public static final int SGET_BOOLEAN = 0x63;\n    public static final int SGET_BYTE = 0x64;\n    public static final int SGET_CHAR = 0x65;\n    public static final int SGET_SHORT = 0x66;\n    public static final int SPUT = 0x67;\n    public static final int SPUT_WIDE = 0x68;\n    public static final int SPUT_OBJECT = 0x69;\n    public static final int SPUT_BOOLEAN = 0x6a;\n    public static final int SPUT_BYTE = 0x6b;\n    public static final int SPUT_CHAR = 0x6c;\n    public static final int SPUT_SHORT = 0x6d;\n    public static final int INVOKE_VIRTUAL = 0x6e;\n    public static final int INVOKE_SUPER = 0x6f;\n    public static final int INVOKE_DIRECT = 0x70;\n    public static final int INVOKE_STATIC = 0x71;\n    public static final int INVOKE_INTERFACE = 0x72;\n    public static final int INVOKE_VIRTUAL_RANGE = 0x74;\n    public static final int INVOKE_SUPER_RANGE = 0x75;\n    public static final int INVOKE_DIRECT_RANGE = 0x76;\n    public static final int INVOKE_STATIC_RANGE = 0x77;\n    public static final int INVOKE_INTERFACE_RANGE = 0x78;\n    public static final int NEG_INT = 0x7b;\n    public static final int NOT_INT = 0x7c;\n    public static final int NEG_LONG = 0x7d;\n    public static final int NOT_LONG = 0x7e;\n    public static final int NEG_FLOAT = 0x7f;\n    public static final int NEG_DOUBLE = 0x80;\n    public static final int INT_TO_LONG = 0x81;\n    public static final int INT_TO_FLOAT = 0x82;\n    public static final int INT_TO_DOUBLE = 0x83;\n    public static final int LONG_TO_INT = 0x84;\n    public static final int LONG_TO_FLOAT = 0x85;\n    public static final int LONG_TO_DOUBLE = 0x86;\n    public static final int FLOAT_TO_INT = 0x87;\n    public static final int FLOAT_TO_LONG = 0x88;\n    public static final int FLOAT_TO_DOUBLE = 0x89;\n    public static final int DOUBLE_TO_INT = 0x8a;\n    public static final int DOUBLE_TO_LONG = 0x8b;\n    public static final int DOUBLE_TO_FLOAT = 0x8c;\n    public static final int INT_TO_BYTE = 0x8d;\n    public static final int INT_TO_CHAR = 0x8e;\n    public static final int INT_TO_SHORT = 0x8f;\n    public static final int ADD_INT = 0x90;\n    public static final int SUB_INT = 0x91;\n    public static final int MUL_INT = 0x92;\n    public static final int DIV_INT = 0x93;\n    public static final int REM_INT = 0x94;\n    public static final int AND_INT = 0x95;\n    public static final int OR_INT = 0x96;\n    public static final int XOR_INT = 0x97;\n    public static final int SHL_INT = 0x98;\n    public static final int SHR_INT = 0x99;\n    public static final int USHR_INT = 0x9a;\n    public static final int ADD_LONG = 0x9b;\n    public static final int SUB_LONG = 0x9c;\n    public static final int MUL_LONG = 0x9d;\n    public static final int DIV_LONG = 0x9e;\n    public static final int REM_LONG = 0x9f;\n    public static final int AND_LONG = 0xa0;\n    public static final int OR_LONG = 0xa1;\n    public static final int XOR_LONG = 0xa2;\n    public static final int SHL_LONG = 0xa3;\n    public static final int SHR_LONG = 0xa4;\n    public static final int USHR_LONG = 0xa5;\n    public static final int ADD_FLOAT = 0xa6;\n    public static final int SUB_FLOAT = 0xa7;\n    public static final int MUL_FLOAT = 0xa8;\n    public static final int DIV_FLOAT = 0xa9;\n    public static final int REM_FLOAT = 0xaa;\n    public static final int ADD_DOUBLE = 0xab;\n    public static final int SUB_DOUBLE = 0xac;\n    public static final int MUL_DOUBLE = 0xad;\n    public static final int DIV_DOUBLE = 0xae;\n    public static final int REM_DOUBLE = 0xaf;\n    public static final int ADD_INT_2ADDR = 0xb0;\n    public static final int SUB_INT_2ADDR = 0xb1;\n    public static final int MUL_INT_2ADDR = 0xb2;\n    public static final int DIV_INT_2ADDR = 0xb3;\n    public static final int REM_INT_2ADDR = 0xb4;\n    public static final int AND_INT_2ADDR = 0xb5;\n    public static final int OR_INT_2ADDR = 0xb6;\n    public static final int XOR_INT_2ADDR = 0xb7;\n    public static final int SHL_INT_2ADDR = 0xb8;\n    public static final int SHR_INT_2ADDR = 0xb9;\n    public static final int USHR_INT_2ADDR = 0xba;\n    public static final int ADD_LONG_2ADDR = 0xbb;\n    public static final int SUB_LONG_2ADDR = 0xbc;\n    public static final int MUL_LONG_2ADDR = 0xbd;\n    public static final int DIV_LONG_2ADDR = 0xbe;\n    public static final int REM_LONG_2ADDR = 0xbf;\n    public static final int AND_LONG_2ADDR = 0xc0;\n    public static final int OR_LONG_2ADDR = 0xc1;\n    public static final int XOR_LONG_2ADDR = 0xc2;\n    public static final int SHL_LONG_2ADDR = 0xc3;\n    public static final int SHR_LONG_2ADDR = 0xc4;\n    public static final int USHR_LONG_2ADDR = 0xc5;\n    public static final int ADD_FLOAT_2ADDR = 0xc6;\n    public static final int SUB_FLOAT_2ADDR = 0xc7;\n    public static final int MUL_FLOAT_2ADDR = 0xc8;\n    public static final int DIV_FLOAT_2ADDR = 0xc9;\n    public static final int REM_FLOAT_2ADDR = 0xca;\n    public static final int ADD_DOUBLE_2ADDR = 0xcb;\n    public static final int SUB_DOUBLE_2ADDR = 0xcc;\n    public static final int MUL_DOUBLE_2ADDR = 0xcd;\n    public static final int DIV_DOUBLE_2ADDR = 0xce;\n    public static final int REM_DOUBLE_2ADDR = 0xcf;\n    public static final int ADD_INT_LIT16 = 0xd0;\n    public static final int RSUB_INT = 0xd1;\n    public static final int MUL_INT_LIT16 = 0xd2;\n    public static final int DIV_INT_LIT16 = 0xd3;\n    public static final int REM_INT_LIT16 = 0xd4;\n    public static final int AND_INT_LIT16 = 0xd5;\n    public static final int OR_INT_LIT16 = 0xd6;\n    public static final int XOR_INT_LIT16 = 0xd7;\n    public static final int ADD_INT_LIT8 = 0xd8;\n    public static final int RSUB_INT_LIT8 = 0xd9;\n    public static final int MUL_INT_LIT8 = 0xda;\n    public static final int DIV_INT_LIT8 = 0xdb;\n    public static final int REM_INT_LIT8 = 0xdc;\n    public static final int AND_INT_LIT8 = 0xdd;\n    public static final int OR_INT_LIT8 = 0xde;\n    public static final int XOR_INT_LIT8 = 0xdf;\n    public static final int SHL_INT_LIT8 = 0xe0;\n    public static final int SHR_INT_LIT8 = 0xe1;\n    public static final int USHR_INT_LIT8 = 0xe2;\n    // END(opcodes)\n\n    // TODO: Generate these payload opcodes with opcode-gen.\n\n    /**\n     * special pseudo-opcode value for packed-switch data payload\n     * instructions\n     */\n    public static final int PACKED_SWITCH_PAYLOAD = 0x100;\n\n    /** special pseudo-opcode value for packed-switch data payload\n     * instructions\n     */\n    public static final int SPARSE_SWITCH_PAYLOAD = 0x200;\n\n    /** special pseudo-opcode value for fill-array-data data payload\n     * instructions\n     */\n    public static final int FILL_ARRAY_DATA_PAYLOAD = 0x300;\n\n    /**\n     * This class is uninstantiable.\n     */\n    private Opcodes() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Determines if the given opcode has the right \"shape\" to be\n     * valid. This includes the range {@code 0x01..0xfe}, the range\n     * {@code 0x00ff..0xffff} where the low-order byte is either\n     * {@code 0} or {@code 0xff}, and the special opcode values {@code\n     * SPECIAL_FORMAT} and {@code NO_NEXT}. Note that not all of the\n     * opcode values that pass this test are in fact used. This method\n     * is meant to perform a quick check to reject blatantly wrong\n     * values (e.g. when validating arguments).\n     *\n     * @param opcode the opcode value\n     * @return {@code true} iff the value has the right \"shape\" to be\n     * possibly valid\n     */\n    public static boolean isValidShape(int opcode) {\n        /*\n         * Note: This method bakes in knowledge that all opcodes are\n         * one of the forms:\n         *\n         *   * single byte in range 0x01..0xfe -- normal opcodes\n         *   * (byteValue << 8) -- nop and data payload opcodes\n         *   * ((byteValue << 8) | 0xff) -- 16-bit extended opcodes\n         *   * SPECIAL_FORMAT or NO_NEXT -- pseudo-opcodes\n         */\n\n        // Note: SPECIAL_FORMAT == NO_NEXT.\n        if (opcode < SPECIAL_FORMAT) {\n            return false;\n        } else if (opcode == SPECIAL_FORMAT) {\n            return true;\n        }\n\n        int lowByte = opcode & 0xff;\n        if ((lowByte == 0) || (lowByte == 0xff)) {\n            return true;\n        }\n\n        return (opcode & 0xff00) == 0;\n    }\n\n    /**\n     * Gets the opcode out of an opcode unit, the latter of which may also\n     * include one or more argument values.\n     *\n     * @param opcodeUnit the opcode-containing code unit\n     * @return the extracted opcode\n     */\n    public static int extractOpcodeFromUnit(int opcodeUnit) {\n        /*\n         * Note: This method bakes in knowledge that all opcodes are\n         * either single-byte or of the forms (byteValue << 8) or\n         * ((byteValue << 8) | 0xff).\n         */\n\n        int lowByte = opcodeUnit & 0xff;\n        return ((lowByte == 0) || (lowByte == 0xff)) ? opcodeUnit : lowByte;\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/AddressMap.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\nimport java.util.HashMap;\n\n/**\n * Map from addresses to addresses, where addresses are all\n * {@code int}s.\n */\npublic final class AddressMap {\n    /** underlying map. TODO: This might be too inefficient. */\n    private final HashMap<Integer,Integer> map;\n\n    /**\n     * Constructs an instance.\n     */\n    public AddressMap() {\n        map = new HashMap<Integer,Integer>();\n    }\n\n    /**\n     * Gets the value address corresponding to the given key address. Returns\n     * {@code -1} if there is no mapping.\n     */\n    public int get(int keyAddress) {\n        Integer value = map.get(keyAddress);\n        return (value == null) ? -1 : value;\n    }\n\n    /**\n     * Sets the value address associated with the given key address.\n     */\n    public void put(int keyAddress, int valueAddress) {\n        map.put(keyAddress, valueAddress);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/BaseCodeCursor.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\n/**\n * Base implementation of {@link CodeCursor}.\n */\npublic abstract class BaseCodeCursor implements CodeCursor {\n    /** base address map */\n    private final AddressMap baseAddressMap;\n\n    /** next index within {@link #array} to read from or write to */\n    private int cursor;\n\n    /**\n     * Constructs an instance.\n     */\n    public BaseCodeCursor() {\n        this.baseAddressMap = new AddressMap();\n        this.cursor = 0;\n    }\n\n    /** @inheritDoc */\n    public final int cursor() {\n        return cursor;\n    }\n\n    /** @inheritDoc */\n    public final int baseAddressForCursor() {\n        int mapped = baseAddressMap.get(cursor);\n        return (mapped >= 0) ? mapped : cursor;\n    }\n\n    /** @inheritDoc */\n    public final void setBaseAddress(int targetAddress, int baseAddress) {\n        baseAddressMap.put(targetAddress, baseAddress);\n    }\n\n    /**\n     * Advance the cursor by the indicated amount.\n     */\n    protected final void advance(int amount) {\n        cursor += amount;\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/CodeCursor.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\n/**\n * Cursor over code units, for reading or writing out Dalvik bytecode.\n */\npublic interface CodeCursor {\n    /**\n     * Gets the cursor. The cursor is the offset in code units from\n     * the start of the input of the next code unit to be read or\n     * written, where the input generally consists of the code for a\n     * single method.\n     */\n    public int cursor();\n\n    /**\n     * Gets the base address associated with the current cursor. This\n     * differs from the cursor value when explicitly set (by {@link\n     * #setBaseAddress). This is used, in particular, to convey base\n     * addresses to switch data payload instructions, whose relative\n     * addresses are relative to the address of a dependant switch\n     * instruction.\n     */\n    public int baseAddressForCursor();\n\n    /**\n     * Sets the base address for the given target address to be as indicated.\n     *\n     * @see #baseAddressForCursor\n     */\n    public void setBaseAddress(int targetAddress, int baseAddress);\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/CodeInput.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\nimport java.io.EOFException;\n\n/**\n * Input stream of code units, for reading in Dalvik bytecode.\n */\npublic interface CodeInput extends CodeCursor {\n    /**\n     * Returns whether there are any more code units to read. This\n     * is analogous to {@code hasNext()} on an interator.\n     */\n    public boolean hasMore();\n\n    /**\n     * Reads a code unit.\n     */\n    public int read() throws EOFException;\n\n    /**\n     * Reads two code units, treating them as a little-endian {@code int}.\n     */\n    public int readInt() throws EOFException;\n\n    /**\n     * Reads four code units, treating them as a little-endian {@code long}.\n     */\n    public long readLong() throws EOFException;\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/CodeOutput.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\n/**\n * Output stream of code units, for writing out Dalvik bytecode.\n */\npublic interface CodeOutput extends CodeCursor {\n    /**\n     * Writes a code unit.\n     */\n    public void write(short codeUnit);\n\n    /**\n     * Writes two code units.\n     */\n    public void write(short u0, short u1);\n\n    /**\n     * Writes three code units.\n     */\n    public void write(short u0, short u1, short u2);\n\n    /**\n     * Writes four code units.\n     */\n    public void write(short u0, short u1, short u2, short u3);\n\n    /**\n     * Writes five code units.\n     */\n    public void write(short u0, short u1, short u2, short u3, short u4);\n\n    /**\n     * Writes an {@code int}, little-endian.\n     */\n    public void writeInt(int value);\n\n    /**\n     * Writes a {@code long}, little-endian.\n     */\n    public void writeLong(long value);\n\n    /**\n     * Writes the contents of the given array.\n     */\n    public void write(byte[] data);\n\n    /**\n     * Writes the contents of the given array.\n     */\n    public void write(short[] data);\n\n    /**\n     * Writes the contents of the given array.\n     */\n    public void write(int[] data);\n\n    /**\n     * Writes the contents of the given array.\n     */\n    public void write(long[] data);\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/DecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\nimport java.io.EOFException;\n\nimport com.taobao.atlas.dex.DexException2;\nimport com.taobao.atlas.dexmerge.dx.io.IndexType;\nimport com.taobao.atlas.dexmerge.dx.io.OpcodeInfo;\nimport com.taobao.atlas.dexmerge.dx.io.Opcodes;\nimport com.taobao.atlas.dexmerge.dx.util.Hex;\n\n/**\n * A decoded Dalvik instruction. This consists of a format codec, a\n * numeric opcode, an optional index type, and any additional\n * arguments of the instruction. The additional arguments (if any) are\n * represented as uninterpreted data.\n *\n * <p><b>Note:</b> The names of the arguments are <i>not</i> meant to\n * match the names given in the Dalvik instruction format\n * specification, specification which just names fields (somewhat)\n * arbitrarily alphabetically from A. In this class, non-register\n * fields are given descriptive names and register fields are\n * consistently named alphabetically.</p>\n */\npublic abstract class DecodedInstruction {\n    /** non-null; instruction format / codec */\n    private final InstructionCodec format;\n\n    /** opcode number */\n    private final int opcode;\n\n    /** constant index argument */\n    private final int index;\n\n    /** null-ok; index type */\n    private final IndexType indexType;\n\n    /**\n     * target address argument. This is an absolute address, not just\n     * a signed offset. <b>Note:</b> The address is unsigned, even\n     * though it is stored in an {@code int}.\n     */\n    private final int target;\n\n    /**\n     * literal value argument; also used for special verification error\n     * constants (format 20bc) as well as should-be-zero values\n     * (formats 10x, 20t, 30t, and 32x)\n     */\n    private final long literal;\n\n    /**\n     * Decodes an instruction from the given input source.\n     */\n    public static DecodedInstruction decode(CodeInput in) throws EOFException {\n        int opcodeUnit = in.read();\n        int opcode = Opcodes.extractOpcodeFromUnit(opcodeUnit);\n        InstructionCodec format = OpcodeInfo.getFormat(opcode);\n\n        return format.decode(opcodeUnit, in);\n    }\n\n    /**\n     * Decodes an array of instructions. The result has non-null\n     * elements at each offset that represents the start of an\n     * instruction.\n     */\n    public static DecodedInstruction[] decodeAll(short[] encodedInstructions) {\n        int size = encodedInstructions.length;\n        DecodedInstruction[] decoded = new DecodedInstruction[size];\n        ShortArrayCodeInput in = new ShortArrayCodeInput(encodedInstructions);\n\n        try {\n            while (in.hasMore()) {\n                decoded[in.cursor()] = DecodedInstruction.decode(in);\n            }\n        } catch (EOFException ex) {\n            throw new DexException2(ex);\n        }\n\n        return decoded;\n    }\n\n    /**\n     * Constructs an instance.\n     */\n    public DecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal) {\n        if (format == null) {\n            throw new NullPointerException(\"format == null\");\n        }\n\n        if (!Opcodes.isValidShape(opcode)) {\n            throw new IllegalArgumentException(\"invalid opcode\");\n        }\n\n        this.format = format;\n        this.opcode = opcode;\n        this.index = index;\n        this.indexType = indexType;\n        this.target = target;\n        this.literal = literal;\n    }\n\n    public final InstructionCodec getFormat() {\n        return format;\n    }\n\n    public final int getOpcode() {\n        return opcode;\n    }\n\n    /**\n     * Gets the opcode, as a code unit.\n     */\n    public final short getOpcodeUnit() {\n        return (short) opcode;\n    }\n\n    public final int getIndex() {\n        return index;\n    }\n\n    /**\n     * Gets the index, as a code unit.\n     */\n    public final short getIndexUnit() {\n        return (short) index;\n    }\n\n    public final IndexType getIndexType() {\n        return indexType;\n    }\n\n    /**\n     * Gets the raw target.\n     */\n    public final int getTarget() {\n        return target;\n    }\n\n    /**\n     * Gets the target as a relative offset from the given address.\n     */\n    public final int getTarget(int baseAddress) {\n        return target - baseAddress;\n    }\n\n    /**\n     * Gets the target as a relative offset from the given base\n     * address, as a code unit. This will throw if the value is out of\n     * the range of a signed code unit.\n     */\n    public final short getTargetUnit(int baseAddress) {\n        int relativeTarget = getTarget(baseAddress);\n\n        if (relativeTarget != (short) relativeTarget) {\n            throw new DexException2(\"Target out of range: \"\n                    + Hex.s4(relativeTarget));\n        }\n\n        return (short) relativeTarget;\n    }\n\n    /**\n     * Gets the target as a relative offset from the given base\n     * address, masked to be a byte in size. This will throw if the\n     * value is out of the range of a signed byte.\n     */\n    public final int getTargetByte(int baseAddress) {\n        int relativeTarget = getTarget(baseAddress);\n\n        if (relativeTarget != (byte) relativeTarget) {\n            throw new DexException2(\"Target out of range: \"\n                    + Hex.s4(relativeTarget));\n        }\n\n        return relativeTarget & 0xff;\n    }\n\n    public final long getLiteral() {\n        return literal;\n    }\n\n    /**\n     * Gets the literal value, masked to be an int in size. This will\n     * throw if the value is out of the range of a signed int.\n     */\n    public final int getLiteralInt() {\n        if (literal != (int) literal) {\n            throw new DexException2(\"Literal out of range: \" + Hex.u8(literal));\n        }\n\n        return (int) literal;\n    }\n\n    /**\n     * Gets the literal value, as a code unit. This will throw if the\n     * value is out of the range of a signed code unit.\n     */\n    public final short getLiteralUnit() {\n        if (literal != (short) literal) {\n            throw new DexException2(\"Literal out of range: \" + Hex.u8(literal));\n        }\n\n        return (short) literal;\n    }\n\n    /**\n     * Gets the literal value, masked to be a byte in size. This will\n     * throw if the value is out of the range of a signed byte.\n     */\n    public final int getLiteralByte() {\n        if (literal != (byte) literal) {\n            throw new DexException2(\"Literal out of range: \" + Hex.u8(literal));\n        }\n\n        return (int) literal & 0xff;\n    }\n\n    /**\n     * Gets the literal value, masked to be a nibble in size. This\n     * will throw if the value is out of the range of a signed nibble.\n     */\n    public final int getLiteralNibble() {\n        if ((literal < -8) || (literal > 7)) {\n            throw new DexException2(\"Literal out of range: \" + Hex.u8(literal));\n        }\n\n        return (int) literal & 0xf;\n    }\n\n    public abstract int getRegisterCount();\n\n    public int getA() {\n        return 0;\n    }\n\n    public int getB() {\n        return 0;\n    }\n\n    public int getC() {\n        return 0;\n    }\n\n    public int getD() {\n        return 0;\n    }\n\n    public int getE() {\n        return 0;\n    }\n\n    /**\n     * Gets the register count, as a code unit. This will throw if the\n     * value is out of the range of an unsigned code unit.\n     */\n    public final short getRegisterCountUnit() {\n        int registerCount = getRegisterCount();\n\n        if ((registerCount & ~0xffff) != 0) {\n            throw new DexException2(\"Register count out of range: \"\n                    + Hex.u8(registerCount));\n        }\n\n        return (short) registerCount;\n    }\n\n    /**\n     * Gets the A register number, as a code unit. This will throw if the\n     * value is out of the range of an unsigned code unit.\n     */\n    public final short getAUnit() {\n        int a = getA();\n\n        if ((a & ~0xffff) != 0) {\n            throw new DexException2(\"Register A out of range: \" + Hex.u8(a));\n        }\n\n        return (short) a;\n    }\n\n    /**\n     * Gets the A register number, as a byte. This will throw if the\n     * value is out of the range of an unsigned byte.\n     */\n    public final short getAByte() {\n        int a = getA();\n\n        if ((a & ~0xff) != 0) {\n            throw new DexException2(\"Register A out of range: \" + Hex.u8(a));\n        }\n\n        return (short) a;\n    }\n\n    /**\n     * Gets the A register number, as a nibble. This will throw if the\n     * value is out of the range of an unsigned nibble.\n     */\n    public final short getANibble() {\n        int a = getA();\n\n        if ((a & ~0xf) != 0) {\n            throw new DexException2(\"Register A out of range: \" + Hex.u8(a));\n        }\n\n        return (short) a;\n    }\n\n    /**\n     * Gets the B register number, as a code unit. This will throw if the\n     * value is out of the range of an unsigned code unit.\n     */\n    public final short getBUnit() {\n        int b = getB();\n\n        if ((b & ~0xffff) != 0) {\n            throw new DexException2(\"Register B out of range: \" + Hex.u8(b));\n        }\n\n        return (short) b;\n    }\n\n    /**\n     * Gets the B register number, as a byte. This will throw if the\n     * value is out of the range of an unsigned byte.\n     */\n    public final short getBByte() {\n        int b = getB();\n\n        if ((b & ~0xff) != 0) {\n            throw new DexException2(\"Register B out of range: \" + Hex.u8(b));\n        }\n\n        return (short) b;\n    }\n\n    /**\n     * Gets the B register number, as a nibble. This will throw if the\n     * value is out of the range of an unsigned nibble.\n     */\n    public final short getBNibble() {\n        int b = getB();\n\n        if ((b & ~0xf) != 0) {\n            throw new DexException2(\"Register B out of range: \" + Hex.u8(b));\n        }\n\n        return (short) b;\n    }\n\n    /**\n     * Gets the C register number, as a code unit. This will throw if the\n     * value is out of the range of an unsigned code unit.\n     */\n    public final short getCUnit() {\n        int c = getC();\n\n        if ((c & ~0xffff) != 0) {\n            throw new DexException2(\"Register C out of range: \" + Hex.u8(c));\n        }\n\n        return (short) c;\n    }\n\n    /**\n     * Gets the C register number, as a byte. This will throw if the\n     * value is out of the range of an unsigned byte.\n     */\n    public final short getCByte() {\n        int c = getC();\n\n        if ((c & ~0xff) != 0) {\n            throw new DexException2(\"Register C out of range: \" + Hex.u8(c));\n        }\n\n        return (short) c;\n    }\n\n    /**\n     * Gets the C register number, as a nibble. This will throw if the\n     * value is out of the range of an unsigned nibble.\n     */\n    public final short getCNibble() {\n        int c = getC();\n\n        if ((c & ~0xf) != 0) {\n            throw new DexException2(\"Register C out of range: \" + Hex.u8(c));\n        }\n\n        return (short) c;\n    }\n\n    /**\n     * Gets the D register number, as a code unit. This will throw if the\n     * value is out of the range of an unsigned code unit.\n     */\n    public final short getDUnit() {\n        int d = getD();\n\n        if ((d & ~0xffff) != 0) {\n            throw new DexException2(\"Register D out of range: \" + Hex.u8(d));\n        }\n\n        return (short) d;\n    }\n\n    /**\n     * Gets the D register number, as a byte. This will throw if the\n     * value is out of the range of an unsigned byte.\n     */\n    public final short getDByte() {\n        int d = getD();\n\n        if ((d & ~0xff) != 0) {\n            throw new DexException2(\"Register D out of range: \" + Hex.u8(d));\n        }\n\n        return (short) d;\n    }\n\n    /**\n     * Gets the D register number, as a nibble. This will throw if the\n     * value is out of the range of an unsigned nibble.\n     */\n    public final short getDNibble() {\n        int d = getD();\n\n        if ((d & ~0xf) != 0) {\n            throw new DexException2(\"Register D out of range: \" + Hex.u8(d));\n        }\n\n        return (short) d;\n    }\n\n    /**\n     * Gets the E register number, as a nibble. This will throw if the\n     * value is out of the range of an unsigned nibble.\n     */\n    public final short getENibble() {\n        int e = getE();\n\n        if ((e & ~0xf) != 0) {\n            throw new DexException2(\"Register E out of range: \" + Hex.u8(e));\n        }\n\n        return (short) e;\n    }\n\n    /**\n     * Encodes this instance to the given output.\n     */\n    public final void encode(CodeOutput out) {\n        format.encode(this, out);\n    }\n\n    /**\n     * Returns an instance just like this one, except with the index replaced\n     * with the given one.\n     */\n    public abstract DecodedInstruction withIndex(int newIndex);\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/FillArrayDataPayloadDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\n/**\n * A decoded Dalvik instruction which contains the payload for\n * a {@code packed-switch} instruction.\n */\npublic final class FillArrayDataPayloadDecodedInstruction\n        extends DecodedInstruction {\n    /** data array */\n    private final Object data;\n\n    /** number of elements */\n    private final int size;\n\n    /** element width */\n    private final int elementWidth;\n\n    /**\n     * Constructs an instance. This private instance doesn't check the\n     * type of the data array.\n     */\n    private FillArrayDataPayloadDecodedInstruction(InstructionCodec format,\n            int opcode, Object data, int size, int elementWidth) {\n        super(format, opcode, 0, null, 0, 0L);\n\n        this.data = data;\n        this.size = size;\n        this.elementWidth = elementWidth;\n    }\n\n    /**\n     * Constructs an instance.\n     */\n    public FillArrayDataPayloadDecodedInstruction(InstructionCodec format,\n            int opcode, byte[] data) {\n        this(format, opcode, data, data.length, 1);\n    }\n\n    /**\n     * Constructs an instance.\n     */\n    public FillArrayDataPayloadDecodedInstruction(InstructionCodec format,\n            int opcode, short[] data) {\n        this(format, opcode, data, data.length, 2);\n    }\n\n    /**\n     * Constructs an instance.\n     */\n    public FillArrayDataPayloadDecodedInstruction(InstructionCodec format,\n            int opcode, int[] data) {\n        this(format, opcode, data, data.length, 4);\n    }\n\n    /**\n     * Constructs an instance.\n     */\n    public FillArrayDataPayloadDecodedInstruction(InstructionCodec format,\n            int opcode, long[] data) {\n        this(format, opcode, data, data.length, 8);\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 0;\n    }\n\n    public short getElementWidthUnit() {\n        return (short) elementWidth;\n    }\n\n    public int getSize() {\n        return size;\n    }\n\n    public Object getData() {\n        return data;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        throw new UnsupportedOperationException(\"no index in instruction\");\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/FiveRegisterDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\nimport com.taobao.atlas.dexmerge.dx.io.IndexType;\n\n/**\n * A decoded Dalvik instruction which has five register arguments.\n */\npublic final class FiveRegisterDecodedInstruction extends DecodedInstruction {\n    /** register argument \"A\" */\n    private final int a;\n\n    /** register argument \"B\" */\n    private final int b;\n\n    /** register argument \"C\" */\n    private final int c;\n\n    /** register argument \"D\" */\n    private final int d;\n\n    /** register argument \"E\" */\n    private final int e;\n\n    /**\n     * Constructs an instance.\n     */\n    public FiveRegisterDecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal,\n            int a, int b, int c, int d, int e) {\n        super(format, opcode, index, indexType, target, literal);\n\n        this.a = a;\n        this.b = b;\n        this.c = c;\n        this.d = d;\n        this.e = e;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 5;\n    }\n\n    /** @inheritDoc */\n    public int getA() {\n        return a;\n    }\n\n    /** @inheritDoc */\n    public int getB() {\n        return b;\n    }\n\n    /** @inheritDoc */\n    public int getC() {\n        return c;\n    }\n\n    /** @inheritDoc */\n    public int getD() {\n        return d;\n    }\n\n    /** @inheritDoc */\n    public int getE() {\n        return e;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        return new FiveRegisterDecodedInstruction(\n                getFormat(), getOpcode(), newIndex, getIndexType(),\n                getTarget(), getLiteral(), a, b, c, d, e);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/FourRegisterDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\nimport com.taobao.atlas.dexmerge.dx.io.IndexType;\n\n/**\n * A decoded Dalvik instruction which has five register arguments.\n */\npublic final class FourRegisterDecodedInstruction extends DecodedInstruction {\n    /** register argument \"A\" */\n    private final int a;\n\n    /** register argument \"B\" */\n    private final int b;\n\n    /** register argument \"C\" */\n    private final int c;\n\n    /** register argument \"D\" */\n    private final int d;\n\n    /**\n     * Constructs an instance.\n     */\n    public FourRegisterDecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal,\n            int a, int b, int c, int d) {\n        super(format, opcode, index, indexType, target, literal);\n\n        this.a = a;\n        this.b = b;\n        this.c = c;\n        this.d = d;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 4;\n    }\n\n    /** @inheritDoc */\n    public int getA() {\n        return a;\n    }\n\n    /** @inheritDoc */\n    public int getB() {\n        return b;\n    }\n\n    /** @inheritDoc */\n    public int getC() {\n        return c;\n    }\n\n    /** @inheritDoc */\n    public int getD() {\n        return d;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        return new FourRegisterDecodedInstruction(\n                getFormat(), getOpcode(), newIndex, getIndexType(),\n                getTarget(), getLiteral(), a, b, c, d);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/InstructionCodec.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\nimport com.taobao.atlas.dex.DexException2;\nimport com.taobao.atlas.dexmerge.dx.io.IndexType;\nimport com.taobao.atlas.dexmerge.dx.io.OpcodeInfo;\nimport com.taobao.atlas.dexmerge.dx.io.Opcodes;\nimport com.taobao.atlas.dexmerge.dx.util.Hex;\n\nimport java.io.EOFException;\n\n/**\n * Representation of an instruction format, which knows how to decode into\n * and encode from instances of {@link DecodedInstruction}.\n */\npublic enum InstructionCodec {\n    FORMAT_00X() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            return new ZeroRegisterDecodedInstruction(\n                    this, opcodeUnit, 0, null,\n                    0, 0L);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(insn.getOpcodeUnit());\n        }\n    },\n\n    FORMAT_10X() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int literal = byte1(opcodeUnit); // should be zero\n            return new ZeroRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(insn.getOpcodeUnit());\n        }\n    },\n\n    FORMAT_12X() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = nibble2(opcodeUnit);\n            int b = nibble3(opcodeUnit);\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, 0L,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcodeUnit(),\n                             makeByte(insn.getA(), insn.getB())));\n        }\n    },\n\n    FORMAT_11N() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = nibble2(opcodeUnit);\n            int literal = (nibble3(opcodeUnit) << 28) >> 28; // sign-extend\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcodeUnit(),\n                             makeByte(insn.getA(), insn.getLiteralNibble())));\n        }\n    },\n\n    FORMAT_11X() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, 0L,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(codeUnit(insn.getOpcode(), insn.getA()));\n        }\n    },\n\n    FORMAT_10T() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.cursor() - 1;\n            int opcode = byte0(opcodeUnit);\n            int target = (byte) byte1(opcodeUnit); // sign-extend\n            return new ZeroRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    baseAddress + target, 0L);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            int relativeTarget = insn.getTargetByte(out.cursor());\n            out.write(codeUnit(insn.getOpcode(), relativeTarget));\n        }\n    },\n\n    FORMAT_20T() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.cursor() - 1;\n            int opcode = byte0(opcodeUnit);\n            int literal = byte1(opcodeUnit); // should be zero\n            int target = (short) in.read(); // sign-extend\n            return new ZeroRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    baseAddress + target, literal);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            short relativeTarget = insn.getTargetUnit(out.cursor());\n            out.write(insn.getOpcodeUnit(), relativeTarget);\n        }\n    },\n\n    FORMAT_20BC() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            // Note: We use the literal field to hold the decoded AA value.\n            int opcode = byte0(opcodeUnit);\n            int literal = byte1(opcodeUnit);\n            int index = in.read();\n            return new ZeroRegisterDecodedInstruction(\n                    this, opcode, index, IndexType.VARIES,\n                    0, literal);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getLiteralByte()),\n                    insn.getIndexUnit());\n        }\n    },\n\n    FORMAT_22X() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int b = in.read();\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, 0L,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    insn.getBUnit());\n        }\n    },\n\n    FORMAT_21T() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.cursor() - 1;\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int target = (short) in.read(); // sign-extend\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    baseAddress + target, 0L,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            short relativeTarget = insn.getTargetUnit(out.cursor());\n            out.write(codeUnit(insn.getOpcode(), insn.getA()), relativeTarget);\n        }\n    },\n\n    FORMAT_21S() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int literal = (short) in.read(); // sign-extend\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    insn.getLiteralUnit());\n        }\n    },\n\n    FORMAT_21H() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            long literal = (short) in.read(); // sign-extend\n\n            /*\n             * Format 21h decodes differently depending on the opcode,\n             * because the \"signed hat\" might represent either a 32-\n             * or 64- bit value.\n             */\n            literal <<= (opcode == Opcodes.CONST_HIGH16) ? 16 : 48;\n\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            // See above.\n            int opcode = insn.getOpcode();\n            int shift = (opcode == Opcodes.CONST_HIGH16) ? 16 : 48;\n            short literal = (short) (insn.getLiteral() >> shift);\n\n            out.write(codeUnit(opcode, insn.getA()), literal);\n        }\n    },\n\n    FORMAT_21C() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int index = in.read();\n            IndexType indexType = OpcodeInfo.getIndexType(opcode);\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, index, indexType,\n                    0, 0L,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    insn.getIndexUnit());\n        }\n    },\n\n    FORMAT_23X() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int bc = in.read();\n            int b = byte0(bc);\n            int c = byte1(bc);\n            return new ThreeRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, 0L,\n                    a, b, c);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    codeUnit(insn.getB(), insn.getC()));\n        }\n    },\n\n    FORMAT_22B() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int bc = in.read();\n            int b = byte0(bc);\n            int literal = (byte) byte1(bc); // sign-extend\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    codeUnit(insn.getB(),\n                             insn.getLiteralByte()));\n        }\n    },\n\n    FORMAT_22T() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.cursor() - 1;\n            int opcode = byte0(opcodeUnit);\n            int a = nibble2(opcodeUnit);\n            int b = nibble3(opcodeUnit);\n            int target = (short) in.read(); // sign-extend\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    baseAddress + target, 0L,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            short relativeTarget = insn.getTargetUnit(out.cursor());\n            out.write(\n                    codeUnit(insn.getOpcode(),\n                             makeByte(insn.getA(), insn.getB())),\n                    relativeTarget);\n        }\n    },\n\n    FORMAT_22S() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = nibble2(opcodeUnit);\n            int b = nibble3(opcodeUnit);\n            int literal = (short) in.read(); // sign-extend\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(),\n                             makeByte(insn.getA(), insn.getB())),\n                    insn.getLiteralUnit());\n        }\n    },\n\n    FORMAT_22C() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = nibble2(opcodeUnit);\n            int b = nibble3(opcodeUnit);\n            int index = in.read();\n            IndexType indexType = OpcodeInfo.getIndexType(opcode);\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, index, indexType,\n                    0, 0L,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(),\n                             makeByte(insn.getA(), insn.getB())),\n                    insn.getIndexUnit());\n        }\n    },\n\n    FORMAT_22CS() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = nibble2(opcodeUnit);\n            int b = nibble3(opcodeUnit);\n            int index = in.read();\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, index, IndexType.FIELD_OFFSET,\n                    0, 0L,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(\n                    codeUnit(insn.getOpcode(),\n                             makeByte(insn.getA(), insn.getB())),\n                    insn.getIndexUnit());\n        }\n    },\n\n    FORMAT_30T() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.cursor() - 1;\n            int opcode = byte0(opcodeUnit);\n            int literal = byte1(opcodeUnit); // should be zero\n            int target = in.readInt();\n            return new ZeroRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    baseAddress + target, literal);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            int relativeTarget = insn.getTarget(out.cursor());\n            out.write(insn.getOpcodeUnit(),\n                    unit0(relativeTarget), unit1(relativeTarget));\n        }\n    },\n\n    FORMAT_32X() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int literal = byte1(opcodeUnit); // should be zero\n            int a = in.read();\n            int b = in.read();\n            return new TwoRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a, b);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            out.write(insn.getOpcodeUnit(), insn.getAUnit(), insn.getBUnit());\n        }\n    },\n\n    FORMAT_31I() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int literal = in.readInt();\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            int literal = insn.getLiteralInt();\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    unit0(literal),\n                    unit1(literal));\n        }\n    },\n\n    FORMAT_31T() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.cursor() - 1;\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int target = baseAddress + in.readInt();\n\n            /*\n             * Switch instructions need to \"forward\" their addresses to their\n             * payload target instructions.\n             */\n            switch (opcode) {\n                case Opcodes.PACKED_SWITCH:\n                case Opcodes.SPARSE_SWITCH: {\n                    in.setBaseAddress(target, baseAddress);\n                    break;\n                }\n            }\n\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    target, 0L,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            int relativeTarget = insn.getTarget(out.cursor());\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    unit0(relativeTarget), unit1(relativeTarget));\n        }\n    },\n\n    FORMAT_31C() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            int index = in.readInt();\n            IndexType indexType = OpcodeInfo.getIndexType(opcode);\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, index, indexType,\n                    0, 0L,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            int index = insn.getIndex();\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    unit0(index),\n                    unit1(index));\n        }\n    },\n\n    FORMAT_35C() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            return decodeRegisterList(this, opcodeUnit, in);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            encodeRegisterList(insn, out);\n        }\n    },\n\n    FORMAT_35MS() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            return decodeRegisterList(this, opcodeUnit, in);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            encodeRegisterList(insn, out);\n        }\n    },\n\n    FORMAT_35MI() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            return decodeRegisterList(this, opcodeUnit, in);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            encodeRegisterList(insn, out);\n        }\n    },\n\n    FORMAT_3RC() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            return decodeRegisterRange(this, opcodeUnit, in);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            encodeRegisterRange(insn, out);\n        }\n    },\n\n    FORMAT_3RMS() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            return decodeRegisterRange(this, opcodeUnit, in);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            encodeRegisterRange(insn, out);\n        }\n    },\n\n    FORMAT_3RMI() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            return decodeRegisterRange(this, opcodeUnit, in);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            encodeRegisterRange(insn, out);\n        }\n    },\n\n    FORMAT_51L() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int opcode = byte0(opcodeUnit);\n            int a = byte1(opcodeUnit);\n            long literal = in.readLong();\n            return new OneRegisterDecodedInstruction(\n                    this, opcode, 0, null,\n                    0, literal,\n                    a);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            long literal = insn.getLiteral();\n            out.write(\n                    codeUnit(insn.getOpcode(), insn.getA()),\n                    unit0(literal),\n                    unit1(literal),\n                    unit2(literal),\n                    unit3(literal));\n        }\n    },\n\n    FORMAT_PACKED_SWITCH_PAYLOAD() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.baseAddressForCursor() - 1; // already read opcode\n            int size = in.read();\n            int firstKey = in.readInt();\n            int[] targets = new int[size];\n\n            for (int i = 0; i < size; i++) {\n                targets[i] = baseAddress + in.readInt();\n            }\n\n            return new PackedSwitchPayloadDecodedInstruction(\n                    this, opcodeUnit, firstKey, targets);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            PackedSwitchPayloadDecodedInstruction payload =\n                (PackedSwitchPayloadDecodedInstruction) insn;\n            int[] targets = payload.getTargets();\n            int baseAddress = out.baseAddressForCursor();\n\n            out.write(payload.getOpcodeUnit());\n            out.write(asUnsignedUnit(targets.length));\n            out.writeInt(payload.getFirstKey());\n\n            for (int target : targets) {\n                out.writeInt(target - baseAddress);\n            }\n        }\n    },\n\n    FORMAT_SPARSE_SWITCH_PAYLOAD() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int baseAddress = in.baseAddressForCursor() - 1; // already read opcode\n            int size = in.read();\n            int[] keys = new int[size];\n            int[] targets = new int[size];\n\n            for (int i = 0; i < size; i++) {\n                keys[i] = in.readInt();\n            }\n\n            for (int i = 0; i < size; i++) {\n                targets[i] = baseAddress + in.readInt();\n            }\n\n            return new SparseSwitchPayloadDecodedInstruction(\n                    this, opcodeUnit, keys, targets);\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            SparseSwitchPayloadDecodedInstruction payload =\n                (SparseSwitchPayloadDecodedInstruction) insn;\n            int[] keys = payload.getKeys();\n            int[] targets = payload.getTargets();\n            int baseAddress = out.baseAddressForCursor();\n\n            out.write(payload.getOpcodeUnit());\n            out.write(asUnsignedUnit(targets.length));\n\n            for (int key : keys) {\n                out.writeInt(key);\n            }\n\n            for (int target : targets) {\n                out.writeInt(target - baseAddress);\n            }\n        }\n    },\n\n    FORMAT_FILL_ARRAY_DATA_PAYLOAD() {\n        @Override public DecodedInstruction decode(int opcodeUnit,\n                CodeInput in) throws EOFException {\n            int elementWidth = in.read();\n            int size = in.readInt();\n\n            switch (elementWidth) {\n                case 1: {\n                    byte[] array = new byte[size];\n                    boolean even = true;\n                    for (int i = 0, value = 0; i < size; i++, even = !even) {\n                        if (even) {\n                            value = in.read();\n                        }\n                        array[i] = (byte) (value & 0xff);\n                        value >>= 8;\n                    }\n                    return new FillArrayDataPayloadDecodedInstruction(\n                            this, opcodeUnit, array);\n                }\n                case 2: {\n                    short[] array = new short[size];\n                    for (int i = 0; i < size; i++) {\n                        array[i] = (short) in.read();\n                    }\n                    return new FillArrayDataPayloadDecodedInstruction(\n                            this, opcodeUnit, array);\n                }\n                case 4: {\n                    int[] array = new int[size];\n                    for (int i = 0; i < size; i++) {\n                        array[i] = in.readInt();\n                    }\n                    return new FillArrayDataPayloadDecodedInstruction(\n                            this, opcodeUnit, array);\n                }\n                case 8: {\n                    long[] array = new long[size];\n                    for (int i = 0; i < size; i++) {\n                        array[i] = in.readLong();\n                    }\n                    return new FillArrayDataPayloadDecodedInstruction(\n                            this, opcodeUnit, array);\n                }\n            }\n\n            throw new DexException2(\"bogus element_width: \"\n                    + Hex.u2(elementWidth));\n        }\n\n        @Override public void encode(DecodedInstruction insn, CodeOutput out) {\n            FillArrayDataPayloadDecodedInstruction payload =\n                (FillArrayDataPayloadDecodedInstruction) insn;\n            short elementWidth = payload.getElementWidthUnit();\n            Object data = payload.getData();\n\n            out.write(payload.getOpcodeUnit());\n            out.write(elementWidth);\n            out.writeInt(payload.getSize());\n\n            switch (elementWidth) {\n                case 1: out.write((byte[]) data);  break;\n                case 2: out.write((short[]) data); break;\n                case 4: out.write((int[]) data);   break;\n                case 8: out.write((long[]) data);  break;\n                default: {\n                    throw new DexException2(\"bogus element_width: \"\n                            + Hex.u2(elementWidth));\n                }\n            }\n        }\n    };\n\n    /**\n     * Decodes an instruction specified by the given opcode unit, reading\n     * any required additional code units from the given input source.\n     */\n    public abstract DecodedInstruction decode(int opcodeUnit, CodeInput in)\n        throws EOFException;\n\n    /**\n     * Encodes the given instruction.\n     */\n    public abstract void encode(DecodedInstruction insn, CodeOutput out);\n\n    /**\n     * Helper method that decodes any of the register-list formats.\n     */\n    private static DecodedInstruction decodeRegisterList(\n            InstructionCodec format, int opcodeUnit, CodeInput in)\n            throws EOFException {\n        int opcode = byte0(opcodeUnit);\n        int e = nibble2(opcodeUnit);\n        int registerCount = nibble3(opcodeUnit);\n        int index = in.read();\n        int abcd = in.read();\n        int a = nibble0(abcd);\n        int b = nibble1(abcd);\n        int c = nibble2(abcd);\n        int d = nibble3(abcd);\n        IndexType indexType = OpcodeInfo.getIndexType(opcode);\n\n        // TODO: Having to switch like this is less than ideal.\n        switch (registerCount) {\n            case 0:\n                return new ZeroRegisterDecodedInstruction(\n                        format, opcode, index, indexType,\n                        0, 0L);\n            case 1:\n                return new OneRegisterDecodedInstruction(\n                        format, opcode, index, indexType,\n                        0, 0L,\n                        a);\n            case 2:\n                return new TwoRegisterDecodedInstruction(\n                        format, opcode, index, indexType,\n                        0, 0L,\n                        a, b);\n            case 3:\n                return new ThreeRegisterDecodedInstruction(\n                        format, opcode, index, indexType,\n                        0, 0L,\n                        a, b, c);\n            case 4:\n                return new FourRegisterDecodedInstruction(\n                        format, opcode, index, indexType,\n                        0, 0L,\n                        a, b, c, d);\n            case 5:\n                return new FiveRegisterDecodedInstruction(\n                        format, opcode, index, indexType,\n                        0, 0L,\n                        a, b, c, d, e);\n        }\n\n        throw new DexException2(\"bogus registerCount: \"\n                + Hex.uNibble(registerCount));\n    }\n\n    /**\n     * Helper method that encodes any of the register-list formats.\n     */\n    private static void encodeRegisterList(DecodedInstruction insn,\n            CodeOutput out) {\n        out.write(codeUnit(insn.getOpcode(),\n                        makeByte(insn.getE(), insn.getRegisterCount())),\n                insn.getIndexUnit(),\n                codeUnit(insn.getA(), insn.getB(), insn.getC(), insn.getD()));\n    }\n\n    /**\n     * Helper method that decodes any of the three-unit register-range formats.\n     */\n    private static DecodedInstruction decodeRegisterRange(\n            InstructionCodec format, int opcodeUnit, CodeInput in)\n            throws EOFException {\n        int opcode = byte0(opcodeUnit);\n        int registerCount = byte1(opcodeUnit);\n        int index = in.read();\n        int a = in.read();\n        IndexType indexType = OpcodeInfo.getIndexType(opcode);\n        return new RegisterRangeDecodedInstruction(\n                format, opcode, index, indexType,\n                0, 0L,\n                a, registerCount);\n    }\n\n    /**\n     * Helper method that encodes any of the three-unit register-range formats.\n     */\n    private static void encodeRegisterRange(DecodedInstruction insn,\n            CodeOutput out) {\n        out.write(codeUnit(insn.getOpcode(), insn.getRegisterCount()),\n                insn.getIndexUnit(),\n                insn.getAUnit());\n    }\n\n    private static short codeUnit(int lowByte, int highByte) {\n        if ((lowByte & ~0xff) != 0) {\n            throw new IllegalArgumentException(\"bogus lowByte\");\n        }\n\n        if ((highByte & ~0xff) != 0) {\n            throw new IllegalArgumentException(\"bogus highByte\");\n        }\n\n        return (short) (lowByte | (highByte << 8));\n    }\n\n    private static short codeUnit(int nibble0, int nibble1, int nibble2,\n            int nibble3) {\n        if ((nibble0 & ~0xf) != 0) {\n            throw new IllegalArgumentException(\"bogus nibble0\");\n        }\n\n        if ((nibble1 & ~0xf) != 0) {\n            throw new IllegalArgumentException(\"bogus nibble1\");\n        }\n\n        if ((nibble2 & ~0xf) != 0) {\n            throw new IllegalArgumentException(\"bogus nibble2\");\n        }\n\n        if ((nibble3 & ~0xf) != 0) {\n            throw new IllegalArgumentException(\"bogus nibble3\");\n        }\n\n        return (short) (nibble0 | (nibble1 << 4)\n                | (nibble2 << 8) | (nibble3 << 12));\n    }\n\n    private static int makeByte(int lowNibble, int highNibble) {\n        if ((lowNibble & ~0xf) != 0) {\n            throw new IllegalArgumentException(\"bogus lowNibble\");\n        }\n\n        if ((highNibble & ~0xf) != 0) {\n            throw new IllegalArgumentException(\"bogus highNibble\");\n        }\n\n        return lowNibble | (highNibble << 4);\n    }\n\n    private static short asUnsignedUnit(int value) {\n        if ((value & ~0xffff) != 0) {\n            throw new IllegalArgumentException(\"bogus unsigned code unit\");\n        }\n\n        return (short) value;\n    }\n\n    private static short unit0(int value) {\n        return (short) value;\n    }\n\n    private static short unit1(int value) {\n        return (short) (value >> 16);\n    }\n\n    private static short unit0(long value) {\n        return (short) value;\n    }\n\n    private static short unit1(long value) {\n        return (short) (value >> 16);\n    }\n\n    private static short unit2(long value) {\n        return (short) (value >> 32);\n    }\n\n    private static short unit3(long value) {\n        return (short) (value >> 48);\n    }\n\n    private static int byte0(int value) {\n        return value & 0xff;\n    }\n\n    private static int byte1(int value) {\n        return (value >> 8) & 0xff;\n    }\n\n    private static int byte2(int value) {\n        return (value >> 16) & 0xff;\n    }\n\n    private static int byte3(int value) {\n        return value >>> 24;\n    }\n\n    private static int nibble0(int value) {\n        return value & 0xf;\n    }\n\n    private static int nibble1(int value) {\n        return (value >> 4) & 0xf;\n    }\n\n    private static int nibble2(int value) {\n        return (value >> 8) & 0xf;\n    }\n\n    private static int nibble3(int value) {\n        return (value >> 12) & 0xf;\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/OneRegisterDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\nimport com.taobao.atlas.dexmerge.dx.io.IndexType;\n\n/**\n * A decoded Dalvik instruction which has one register argument.\n */\npublic final class OneRegisterDecodedInstruction extends DecodedInstruction {\n    /** register argument \"A\" */\n    private final int a;\n\n    /**\n     * Constructs an instance.\n     */\n    public OneRegisterDecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal,\n            int a) {\n        super(format, opcode, index, indexType, target, literal);\n\n        this.a = a;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 1;\n    }\n\n    /** @inheritDoc */\n    public int getA() {\n        return a;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        return new OneRegisterDecodedInstruction(\n                getFormat(), getOpcode(), newIndex, getIndexType(),\n                getTarget(), getLiteral(), a);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/PackedSwitchPayloadDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\n/**\n * A decoded Dalvik instruction which contains the payload for\n * a {@code packed-switch} instruction.\n */\npublic final class PackedSwitchPayloadDecodedInstruction\n        extends DecodedInstruction {\n    /** first key value */\n    private final int firstKey;\n\n    /**\n     * array of target addresses. These are absolute, not relative,\n     * addresses.\n     */\n    private final int[] targets;\n\n    /**\n     * Constructs an instance.\n     */\n    public PackedSwitchPayloadDecodedInstruction(InstructionCodec format,\n            int opcode, int firstKey, int[] targets) {\n        super(format, opcode, 0, null, 0, 0L);\n\n        this.firstKey = firstKey;\n        this.targets = targets;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 0;\n    }\n\n    public int getFirstKey() {\n        return firstKey;\n    }\n\n    public int[] getTargets() {\n        return targets;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        throw new UnsupportedOperationException(\"no index in instruction\");\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/RegisterRangeDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\nimport com.taobao.atlas.dexmerge.dx.io.IndexType;\n\n/**\n * A decoded Dalvik instruction which has register range arguments (an\n * \"A\" start register and a register count).\n */\npublic final class RegisterRangeDecodedInstruction extends DecodedInstruction {\n    /** register argument \"A\" */\n    private final int a;\n\n    /** register count */\n    private final int registerCount;\n\n    /**\n     * Constructs an instance.\n     */\n    public RegisterRangeDecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal,\n            int a, int registerCount) {\n        super(format, opcode, index, indexType, target, literal);\n\n        this.a = a;\n        this.registerCount = registerCount;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return registerCount;\n    }\n\n    /** @inheritDoc */\n    public int getA() {\n        return a;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        return new RegisterRangeDecodedInstruction(\n                getFormat(), getOpcode(), newIndex, getIndexType(),\n                getTarget(), getLiteral(), a, registerCount);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/ShortArrayCodeInput.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\nimport java.io.EOFException;\n\n/**\n * Implementation of {@code CodeInput} that reads from a {@code short[]}.\n */\npublic final class ShortArrayCodeInput extends BaseCodeCursor\n        implements CodeInput {\n    /** source array to read from */\n    private final short[] array;\n\n    /**\n     * Constructs an instance.\n     */\n    public ShortArrayCodeInput(short[] array) {\n        if (array == null) {\n            throw new NullPointerException(\"array == null\");\n        }\n\n        this.array = array;\n    }\n\n    /** @inheritDoc */\n    public boolean hasMore() {\n        return cursor() < array.length;\n    }\n\n    /** @inheritDoc */\n    public int read() throws EOFException {\n        try {\n            int value = array[cursor()];\n            advance(1);\n            return value & 0xffff;\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            throw new EOFException();\n        }\n    }\n\n    /** @inheritDoc */\n    public int readInt() throws EOFException {\n        int short0 = read();\n        int short1 = read();\n\n        return short0 | (short1 << 16);\n    }\n\n    /** @inheritDoc */\n    public long readLong() throws EOFException {\n        long short0 = read();\n        long short1 = read();\n        long short2 = read();\n        long short3 = read();\n\n        return short0 | (short1 << 16) | (short2 << 32) | (short3 << 48);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/ShortArrayCodeOutput.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\n/**\n * Implementation of {@code CodeOutput} that writes to a {@code short[]}.\n */\npublic final class ShortArrayCodeOutput extends BaseCodeCursor\n        implements CodeOutput {\n    /** array to write to */\n    private final short[] array;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param maxSize the maximum number of code units that will be written\n     */\n    public ShortArrayCodeOutput(int maxSize) {\n        if (maxSize < 0) {\n            throw new IllegalArgumentException(\"maxSize < 0\");\n        }\n\n        this.array = new short[maxSize];\n    }\n\n    /**\n     * Gets the array. The returned array contains exactly the data\n     * written (e.g. no leftover space at the end).\n     */\n    public short[] getArray() {\n        int cursor = cursor();\n\n        if (cursor == array.length) {\n            return array;\n        }\n\n        short[] result = new short[cursor];\n        System.arraycopy(array, 0, result, 0, cursor);\n        return result;\n    }\n\n    /** @inheritDoc */\n    public void write(short codeUnit) {\n        array[cursor()] = codeUnit;\n        advance(1);\n    }\n\n    /** @inheritDoc */\n    public void write(short u0, short u1) {\n        write(u0);\n        write(u1);\n    }\n\n    /** @inheritDoc */\n    public void write(short u0, short u1, short u2) {\n        write(u0);\n        write(u1);\n        write(u2);\n    }\n\n    /** @inheritDoc */\n    public void write(short u0, short u1, short u2, short u3) {\n        write(u0);\n        write(u1);\n        write(u2);\n        write(u3);\n    }\n\n    /** @inheritDoc */\n    public void write(short u0, short u1, short u2, short u3, short u4) {\n        write(u0);\n        write(u1);\n        write(u2);\n        write(u3);\n        write(u4);\n    }\n\n    /** @inheritDoc */\n    public void writeInt(int value) {\n        write((short) value);\n        write((short) (value >> 16));\n    }\n\n    /** @inheritDoc */\n    public void writeLong(long value) {\n        write((short) value);\n        write((short) (value >> 16));\n        write((short) (value >> 32));\n        write((short) (value >> 48));\n    }\n\n    /** @inheritDoc */\n    public void write(byte[] data) {\n        int value = 0;\n        boolean even = true;\n        for (byte b : data) {\n            if (even) {\n                value = b & 0xff;\n                even = false;\n            } else {\n                value |= b << 8;\n                write((short) value);\n                even = true;\n            }\n        }\n\n        if (!even) {\n            write((short) value);\n        }\n    }\n\n    /** @inheritDoc */\n    public void write(short[] data) {\n        for (short unit : data) {\n            write(unit);\n        }\n    }\n\n    /** @inheritDoc */\n    public void write(int[] data) {\n        for (int i : data) {\n            writeInt(i);\n        }\n    }\n\n    /** @inheritDoc */\n    public void write(long[] data) {\n        for (long l : data) {\n            writeLong(l);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/SparseSwitchPayloadDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\n/**\n * A decoded Dalvik instruction which contains the payload for\n * a {@code packed-switch} instruction.\n */\npublic final class SparseSwitchPayloadDecodedInstruction\n        extends DecodedInstruction {\n    /** array of key values */\n    private final int[] keys;\n\n    /**\n     * array of target addresses. These are absolute, not relative,\n     * addresses.\n     */\n    private final int[] targets;\n\n    /**\n     * Constructs an instance.\n     */\n    public SparseSwitchPayloadDecodedInstruction(InstructionCodec format,\n            int opcode, int[] keys, int[] targets) {\n        super(format, opcode, 0, null, 0, 0L);\n\n        if (keys.length != targets.length) {\n            throw new IllegalArgumentException(\"keys/targets length mismatch\");\n        }\n\n        this.keys = keys;\n        this.targets = targets;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 0;\n    }\n\n    public int[] getKeys() {\n        return keys;\n    }\n\n    public int[] getTargets() {\n        return targets;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        throw new UnsupportedOperationException(\"no index in instruction\");\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/ThreeRegisterDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\nimport com.taobao.atlas.dexmerge.dx.io.IndexType;\n\n/**\n * A decoded Dalvik instruction which has three register arguments.\n */\npublic final class ThreeRegisterDecodedInstruction extends DecodedInstruction {\n    /** register argument \"A\" */\n    private final int a;\n\n    /** register argument \"B\" */\n    private final int b;\n\n    /** register argument \"C\" */\n    private final int c;\n\n    /**\n     * Constructs an instance.\n     */\n    public ThreeRegisterDecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal,\n            int a, int b, int c) {\n        super(format, opcode, index, indexType, target, literal);\n\n        this.a = a;\n        this.b = b;\n        this.c = c;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 3;\n    }\n\n    /** @inheritDoc */\n    public int getA() {\n        return a;\n    }\n\n    /** @inheritDoc */\n    public int getB() {\n        return b;\n    }\n\n    /** @inheritDoc */\n    public int getC() {\n        return c;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        return new ThreeRegisterDecodedInstruction(\n                getFormat(), getOpcode(), newIndex, getIndexType(),\n                getTarget(), getLiteral(), a, b, c);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/TwoRegisterDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\nimport com.taobao.atlas.dexmerge.dx.io.IndexType;\n\n/**\n * A decoded Dalvik instruction which has two register arguments.\n */\npublic final class TwoRegisterDecodedInstruction extends DecodedInstruction {\n    /** register argument \"A\" */\n    private final int a;\n\n    /** register argument \"B\" */\n    private final int b;\n\n    /**\n     * Constructs an instance.\n     */\n    public TwoRegisterDecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal,\n            int a, int b) {\n        super(format, opcode, index, indexType, target, literal);\n\n        this.a = a;\n        this.b = b;\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 2;\n    }\n\n    /** @inheritDoc */\n    public int getA() {\n        return a;\n    }\n\n    /** @inheritDoc */\n    public int getB() {\n        return b;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        return new TwoRegisterDecodedInstruction(\n                getFormat(), getOpcode(), newIndex, getIndexType(),\n                getTarget(), getLiteral(), a, b);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/io/instructions/ZeroRegisterDecodedInstruction.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.io.instructions;\n\nimport com.taobao.atlas.dexmerge.dx.io.IndexType;\n\n/**\n * A decoded Dalvik instruction which has no register arguments.\n */\npublic final class ZeroRegisterDecodedInstruction extends DecodedInstruction {\n    /**\n     * Constructs an instance.\n     */\n    public ZeroRegisterDecodedInstruction(InstructionCodec format, int opcode,\n            int index, IndexType indexType, int target, long literal) {\n        super(format, opcode, index, indexType, target, literal);\n    }\n\n    /** @inheritDoc */\n    public int getRegisterCount() {\n        return 0;\n    }\n\n    /** @inheritDoc */\n    public DecodedInstruction withIndex(int newIndex) {\n        return new ZeroRegisterDecodedInstruction(\n                getFormat(), getOpcode(), newIndex, getIndexType(),\n                getTarget(), getLiteral());\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/merge/CollisionPolicy.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.merge;\n\n/**\n * What to do when two dex files define the same class.\n */\npublic enum CollisionPolicy {\n\n    /**\n     * Keep the class def from the first dex file and discard the def from the\n     * second dex file. This policy is appropriate for incremental builds.\n     */\n    KEEP_FIRST,\n\n    /**\n     * Forbid collisions. This policy is appropriate for merging libraries.\n     */\n    FAIL,\n    /*兼容新型的merge策略*/\n\n    MERGE_CLASS_KEEP_FIRST\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/merge/DexMerger.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.merge;\n\nimport android.util.Log;\nimport com.taobao.atlas.dex.*;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\n\n/**\n * Combine two dex files into one.\n */\npublic final class DexMerger {\n\n    private final Dex[]                  dexes;\n    private final IndexMap[]             indexMaps;\n\n    private final CollisionPolicy        collisionPolicy;\n    private final WriterSizes            writerSizes;\n\n    private final Dex                    dexOut;\n\n    private final Dex.Section            headerOut;\n\n    /** All IDs and definitions sections */\n    private final Dex.Section            idsDefsOut;\n\n    private final Dex.Section            mapListOut;\n\n    private final Dex.Section            typeListOut;\n\n    private final Dex.Section            classDataOut;\n\n    private final Dex.Section            codeOut;\n\n    private final Dex.Section            stringDataOut;\n\n    private final Dex.Section            debugInfoOut;\n\n    private final Dex.Section            encodedArrayOut;\n\n    /** annotations directory on a type */\n    private final Dex.Section            annotationsDirectoryOut;\n\n    /** sets of annotations on a member, parameter or type */\n    private final Dex.Section            annotationSetOut;\n\n    /** parameter lists */\n    private final Dex.Section            annotationSetRefListOut;\n\n    /** individual annotations, each containing zero or more fields */\n    private final Dex.Section            annotationOut;\n\n    private final TableOfContents        contentsOut;\n\n    private final InstructionTransformer instructionTransformer;\n\n    /** minimum number of wasted bytes before it's worthwhile to compact the result */\n    private int                          compactWasteThreshold = 1024 * 1024; // 1MiB\n\n    private List<Integer>removeClasses = new ArrayList<Integer>();\n\n    public void setRemoveTypeClasses(List<String> removeTypeClasses) {\n        this.removeTypeClasses = removeTypeClasses;\n    }\n\n    private List<String>removeTypeClasses = new ArrayList<String>();\n\n    public DexMerger(Dex[] dexes, CollisionPolicy collisionPolicy) throws IOException{\n        this(dexes, collisionPolicy, new WriterSizes(dexes, false));\n    }\n\n    private DexMerger(Dex[] dexes, CollisionPolicy collisionPolicy, WriterSizes writerSizes) throws IOException{\n        this.dexes = dexes;\n        this.collisionPolicy = collisionPolicy;\n        this.writerSizes = writerSizes;\n\n        dexOut = new Dex(writerSizes.size());\n\n        indexMaps = new IndexMap[dexes.length];\n        for (int i = 0; i < dexes.length; i++) {\n            indexMaps[i] = new IndexMap(dexOut, dexes[i].getTableOfContents());\n        }\n        instructionTransformer = new InstructionTransformer();\n\n        headerOut = dexOut.appendSection(writerSizes.header, \"header\");\n        idsDefsOut = dexOut.appendSection(writerSizes.idsDefs, \"ids defs\");\n\n        contentsOut = dexOut.getTableOfContents();\n        contentsOut.dataOff = dexOut.getNextSectionStart();\n\n        contentsOut.mapList.off = dexOut.getNextSectionStart();\n        contentsOut.mapList.size = 1;\n        mapListOut = dexOut.appendSection(writerSizes.mapList, \"map list\");\n\n        contentsOut.typeLists.off = dexOut.getNextSectionStart();\n        typeListOut = dexOut.appendSection(writerSizes.typeList, \"type list\");\n\n        contentsOut.annotationSetRefLists.off = dexOut.getNextSectionStart();\n        annotationSetRefListOut = dexOut.appendSection(writerSizes.annotationsSetRefList, \"annotation set ref list\");\n\n        contentsOut.annotationSets.off = dexOut.getNextSectionStart();\n        annotationSetOut = dexOut.appendSection(writerSizes.annotationsSet, \"annotation sets\");\n\n        contentsOut.classDatas.off = dexOut.getNextSectionStart();\n        classDataOut = dexOut.appendSection(writerSizes.classData, \"class data\");\n\n        contentsOut.codes.off = dexOut.getNextSectionStart();\n        codeOut = dexOut.appendSection(writerSizes.code, \"code\");\n\n        contentsOut.stringDatas.off = dexOut.getNextSectionStart();\n        stringDataOut = dexOut.appendSection(writerSizes.stringData, \"string data\");\n\n        contentsOut.debugInfos.off = dexOut.getNextSectionStart();\n        debugInfoOut = dexOut.appendSection(writerSizes.debugInfo, \"debug info\");\n\n        contentsOut.annotations.off = dexOut.getNextSectionStart();\n        annotationOut = dexOut.appendSection(writerSizes.annotation, \"annotation\");\n\n        contentsOut.encodedArrays.off = dexOut.getNextSectionStart();\n        encodedArrayOut = dexOut.appendSection(writerSizes.encodedArray, \"encoded array\");\n\n        contentsOut.annotationsDirectories.off = dexOut.getNextSectionStart();\n        annotationsDirectoryOut = dexOut.appendSection(writerSizes.annotationsDirectory, \"annotations directory\");\n\n        contentsOut.dataSize = dexOut.getNextSectionStart() - contentsOut.dataOff;\n    }\n\n    public void setCompactWasteThreshold(int compactWasteThreshold) {\n        this.compactWasteThreshold = compactWasteThreshold;\n    }\n\n    protected Dex mergeDexes() throws IOException {\n        mergeStringIds();\n//        mergeStringIdsOld();\n        mergeTypeIds();\n        mergeTypeLists();\n        mergeProtoIds();\n        mergeFieldIds();\n        mergeMethodIds();\n        mergeAnnotations();\n        unionAnnotationSetsAndDirectories();\n        mergeClassDefs();\n\n        // write the header\n        contentsOut.header.off = 0;\n        contentsOut.header.size = 1;\n        contentsOut.fileSize = dexOut.getLength();\n        contentsOut.computeSizesFromOffsets();\n        contentsOut.writeHeader(headerOut, mergeApiLevels());\n        contentsOut.writeMap(mapListOut);\n\n        // generate and write the hashes\n        dexOut.writeHashes();\n\n        return dexOut;\n    }\n\n    public Dex merge() throws IOException {\n        if (dexes.length == 1) {\n            return dexes[0];\n        } else if (dexes.length == 0) {\n            return null;\n        }\n\n        long start = System.nanoTime();\n        Dex result = mergeDexes();\n\n        /*\n         * We use pessimistic sizes when merging dex files. If those sizes\n         * result in too many bytes wasted, compact the result. To compact,\n         * simply merge the result with itself.\n         */\n        WriterSizes compactedSizes = new WriterSizes(this);\n        int wastedByteCount = writerSizes.size() - compactedSizes.size();\n        if (wastedByteCount > +compactWasteThreshold) {\n            DexMerger compacter = new DexMerger(new Dex[] { dexOut, new Dex(0) }, CollisionPolicy.FAIL, compactedSizes);\n            result = compacter.mergeDexes();\n            System.out.printf(\"Result compacted from %.1fKiB to %.1fKiB to save %.1fKiB%n\", dexOut.getLength() / 1024f,\n                    result.getLength() / 1024f, wastedByteCount / 1024f);\n        }\n\n        long elapsed = System.nanoTime() - start;\n        for (int i = 0; i < dexes.length; i++) {\n            System.out.printf(\"Merged dex #%d (%d defs/%.1fKiB)%n\", i + 1, dexes[i].getTableOfContents().classDefs.size,\n                    dexes[i].getLength() / 1024f);\n        }\n        System.out.printf(\"Result is %d defs/%.1fKiB. Took %.1fs%n\", result.getTableOfContents().classDefs.size,\n                result.getLength() / 1024f, elapsed / 1000000000f);\n\n        return result;\n    }\n\n    /**\n     * Reads an IDs section of two dex files and writes an IDs section of a\n     * merged dex file. Populates maps from old to new indices in the merge.\n     */\n    abstract class IdMerger<T extends Comparable<T>> {\n\n        private final Dex.Section out;\n\n        protected IdMerger(Dex.Section out){\n            this.out = out;\n        }\n\n        /**\n         * Merges already-sorted sections, reading one value from each dex into memory\n         * at a time.\n         */\n        public final void mergeSorted() {\n            TableOfContents.Section[] sections = new TableOfContents.Section[dexes.length];\n            Dex.Section[] dexSections = new Dex.Section[dexes.length];\n            int[] offsets = new int[dexes.length];\n            int[] indexes = new int[dexes.length];\n\n            // values contains one value from each dex, sorted for fast retrieval of\n            // the smallest value. The list associated with a value has the indexes\n            // of the dexes that had that value.\n            TreeMap<T, List<Integer>> values = new TreeMap<T, List<Integer>>();\n            boolean hasValue = false;\n            for (int i = 0; i < dexes.length; i++) {\n                sections[i] = getSection(dexes[i].getTableOfContents());\n                dexSections[i] = sections[i].exists() ? dexes[i].open(sections[i].off) : null;\n                // Fill in values with the first value of each dex.\n                offsets[i] = readIntoMap(dexSections[i], sections[i], indexMaps[i], indexes[i], values, i);\n                if (offsets[i] > 0) {\n                    hasValue = true;\n                }\n            }\n            if (hasValue) {\n                getSection(contentsOut).off = out.getPosition();\n            } else {\n                getSection(contentsOut).off = 0;\n            }\n\n            int outCount = 0;\n            while (!values.isEmpty()) {\n                Map.Entry<T, List<Integer>> first = values.pollFirstEntry();\n                for (Integer dex : first.getValue()) {\n                    updateIndex(offsets[dex], indexMaps[dex], indexes[dex]++, outCount);\n                    // Fetch the next value of the dexes we just polled out\n                    offsets[dex] = readIntoMap(dexSections[dex], sections[dex], indexMaps[dex], indexes[dex], values,\n                            dex);\n                }\n                write(first.getKey());\n                outCount++;\n            }\n\n            getSection(contentsOut).size = outCount;\n        }\n\n        private int readIntoMap(Dex.Section in, TableOfContents.Section section, IndexMap indexMap, int index,\n                                TreeMap<T, List<Integer>> values, int dex) {\n            int offset = in != null ? in.getPosition() : -1;\n            if (index < section.size) {\n                T v = read(in, indexMap, index);\n                List<Integer> l = values.get(v);\n                if (l == null) {\n                    l = new ArrayList<Integer>();\n                    values.put(v, l);\n                }\n                l.add(new Integer(dex));\n            }\n            return offset;\n        }\n\n        /**\n         * Merges unsorted sections by reading them completely into memory and\n         * sorting in memory.\n         */\n        public final void mergeUnsorted() {\n            getSection(contentsOut).off = out.getPosition();\n\n            List<UnsortedValue> all = new ArrayList<UnsortedValue>();\n            for (int i = 0; i < dexes.length; i++) {\n                all.addAll(readUnsortedValues(dexes[i], indexMaps[i]));\n            }\n            Collections.sort(all);\n\n            int outCount = 0;\n            for (int i = 0; i < all.size();) {\n                UnsortedValue e1 = all.get(i++);\n                updateIndex(e1.offset, e1.indexMap, e1.index, outCount - 1);\n\n                while (i < all.size() && e1.compareTo(all.get(i)) == 0) {\n                    UnsortedValue e2 = all.get(i++);\n                    updateIndex(e2.offset, e2.indexMap, e2.index, outCount - 1);\n                }\n\n                write(e1.value);\n                outCount++;\n            }\n\n            getSection(contentsOut).size = outCount;\n        }\n\n        private List<UnsortedValue> readUnsortedValues(Dex source, IndexMap indexMap) {\n            TableOfContents.Section section = getSection(source.getTableOfContents());\n            if (!section.exists()) {\n                return Collections.emptyList();\n            }\n\n            List<UnsortedValue> result = new ArrayList<UnsortedValue>();\n            Dex.Section in = source.open(section.off);\n            for (int i = 0; i < section.size; i++) {\n                int offset = in.getPosition();\n                T value = read(in, indexMap, 0);\n                result.add(new UnsortedValue(source, indexMap, value, i, offset));\n            }\n            return result;\n        }\n\n        abstract TableOfContents.Section getSection(TableOfContents tableOfContents);\n\n        abstract T read(Dex.Section in, IndexMap indexMap, int index);\n\n        abstract void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex);\n\n        abstract void write(T value);\n\n        class UnsortedValue implements Comparable<UnsortedValue> {\n\n            final Dex      source;\n            final IndexMap indexMap;\n            final T        value;\n            final int      index;\n            final int      offset;\n\n            UnsortedValue(Dex source, IndexMap indexMap, T value, int index, int offset){\n                this.source = source;\n                this.indexMap = indexMap;\n                this.value = value;\n                this.index = index;\n                this.offset = offset;\n            }\n\n            public int compareTo(UnsortedValue unsortedValue) {\n                return value.compareTo(unsortedValue.value);\n            }\n        }\n    }\n\n    private int mergeApiLevels() {\n        int maxApi = -1;\n        for (int i = 0; i < dexes.length; i++) {\n            int dexMinApi = dexes[i].getTableOfContents().apiLevel;\n            if (maxApi < dexMinApi) {\n                maxApi = dexMinApi;\n            }\n        }\n        return maxApi;\n    }\n\n    /**\n     * 对于StringId做特殊的处理,兼容offset为负数的情况<br/>\n     * 如果offset为负数,则说明取下一个dex的index\n     *\n     */\n    private void mergeStringIds() {\n        TableOfContents.Section[] sections = new TableOfContents.Section[dexes.length];\n        Dex.Section[] dexSections = new Dex.Section[dexes.length];\n        int[] offsets = new int[dexes.length];\n        int[] indexes = new int[dexes.length];\n\n        // values contains one value from each dex, sorted for fast retrieval of\n        // the smallest value. The list associated with a value has the indexes\n        // of the dexes that had that value.\n        TreeMap<String, List<Integer>> values = new TreeMap<String, List<Integer>>();\n        boolean hasValue = false;\n        for (int i = 0; i < dexes.length; i++) {\n            sections[i] = dexes[i].getTableOfContents().stringIds;\n            dexSections[i] = sections[i].exists() ? dexes[i].open(sections[i].off) : null;\n            // Fill in values with the first value of each dex.\n            if(null!= dexSections[i]) {\n                offsets[i] = dexSections[i].getPosition();\n                if (offsets[i] > 0) {\n                    hasValue = true;\n                }\n            }\n            // 读取values\n            for (int j = 0; j < sections[i].size; j++) {\n                int position = dexSections[i].getPosition();\n                int off = dexSections[i].readInt();\n                String value = null;\n                if(off < 0){//如果为负数,则表示取下一个dex的值\n                    int nexDexOff = off *-1 -1;\n                    if(dexes.length > i+1 && dexes[i+1].strings().size() >= nexDexOff+1) {\n                        value = dexes[i + 1].strings().get(nexDexOff);\n                    }else{\n                        throw new IllegalArgumentException(\"The string index: \"+nexDexOff+\" does not existed on next dex!\");\n                    }\n                }else{\n                    dexSections[i].getData().position(position);\n                    value = dexSections[i].readString();\n                }\n                List<Integer>  l = values.get(value);\n                if(null ==l){\n                    l = new ArrayList<Integer>();\n                }\n                l.add(new Integer(i));\n                values.put(value,l);\n            }\n\n        }\n        if (hasValue) {\n            contentsOut.stringIds.off = idsDefsOut.getPosition();\n        } else {\n            contentsOut.stringIds.off = 0;\n        }\n\n        int outCount = 0;\n        while (!values.isEmpty()) {\n            Map.Entry<String, List<Integer>> first = values.pollFirstEntry();\n            for (Integer dex : first.getValue()) {\n                indexMaps[dex].stringIds[indexes[dex]++] = outCount;\n            }\n            contentsOut.stringDatas.size++;\n            idsDefsOut.writeInt(stringDataOut.getPosition());\n            stringDataOut.writeStringData(first.getKey());\n            outCount++;\n        }\n        contentsOut.stringIds.size = outCount;\n    }\n\n    private void mergeStringIdsOld() {\n        new IdMerger<String>(idsDefsOut) {\n            @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.stringIds;\n            }\n\n            @Override String read(Dex.Section in, IndexMap indexMap, int index) {\n                return in.readString();\n            }\n\n            @Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                indexMap.stringIds[oldIndex] = newIndex;\n            }\n\n            @Override void write(String value) {\n                contentsOut.stringDatas.size++;\n                idsDefsOut.writeInt(stringDataOut.getPosition());\n                stringDataOut.writeStringData(value);\n            }\n        }.mergeSorted();\n    }\n\n    private void mergeTypeIds() {\n        new IdMerger<Integer>(idsDefsOut) {\n\n            @Override\n            TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.typeIds;\n            }\n\n            @Override\n            Integer read(Dex.Section in, IndexMap indexMap, int index) {\n                int stringIndex = in.readInt();\n                return indexMap.adjustString(stringIndex);\n            }\n\n            @Override\n            void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                if (newIndex < 0 || newIndex > 0xffff) {\n                    throw new DexIndexOverflowException(\"type ID not in [0, 0xffff]: \" + newIndex);\n                }\n                indexMap.typeIds[oldIndex] = (short) newIndex;\n            }\n\n            @Override\n            void write(Integer value) {\n                idsDefsOut.writeInt(value);\n            }\n        }.mergeSorted();\n    }\n\n    private void mergeTypeLists() {\n        new IdMerger<TypeList>(typeListOut) {\n\n            @Override\n            TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.typeLists;\n            }\n\n            @Override\n            TypeList read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjustTypeList(in.readTypeList());\n            }\n\n            @Override\n            void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                indexMap.putTypeListOffset(offset, typeListOut.getPosition());\n            }\n\n            @Override\n            void write(TypeList value) {\n                typeListOut.writeTypeList(value);\n            }\n        }.mergeUnsorted();\n    }\n\n    private void mergeProtoIds() {\n        new IdMerger<ProtoId>(idsDefsOut) {\n\n            @Override\n            TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.protoIds;\n            }\n\n            @Override\n            ProtoId read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjust(in.readProtoId());\n            }\n\n            @Override\n            void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                if (newIndex < 0 || newIndex > 0xffff) {\n                    throw new DexIndexOverflowException(\"proto ID not in [0, 0xffff]: \" + newIndex);\n                }\n                indexMap.protoIds[oldIndex] = (short) newIndex;\n            }\n\n            @Override\n            void write(ProtoId value) {\n                value.writeTo(idsDefsOut);\n            }\n        }.mergeSorted();\n    }\n\n    private void mergeFieldIds() {\n        new IdMerger<FieldId>(idsDefsOut) {\n\n            @Override\n            TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.fieldIds;\n            }\n\n            @Override\n            FieldId read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjust(in.readFieldId());\n            }\n\n            @Override\n            void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                if (newIndex < 0 || newIndex > 0xffff) {\n                    throw new DexIndexOverflowException(\"field ID not in [0, 0xffff]: \" + newIndex);\n                }\n                indexMap.fieldIds[oldIndex] = (short) newIndex;\n            }\n\n            @Override\n            void write(FieldId value) {\n                value.writeTo(idsDefsOut);\n            }\n        }.mergeSorted();\n    }\n\n    private void mergeMethodIds() {\n        new IdMerger<MethodId>(idsDefsOut) {\n\n            @Override\n            TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.methodIds;\n            }\n\n            @Override\n            MethodId read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjust(in.readMethodId());\n            }\n\n            @Override\n            void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                if (newIndex < 0 || newIndex > 0xffff) {\n                    throw new DexIndexOverflowException(\"method ID not in [0, 0xffff]: \" + newIndex);\n                }\n                indexMap.methodIds[oldIndex] = (short) newIndex;\n            }\n\n            @Override\n            void write(MethodId methodId) {\n                methodId.writeTo(idsDefsOut);\n            }\n        }.mergeSorted();\n    }\n\n    private void mergeAnnotations() {\n        new IdMerger<Annotation>(annotationOut) {\n\n            @Override\n            TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.annotations;\n            }\n\n            @Override\n            Annotation read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjust(in.readAnnotation());\n            }\n\n            @Override\n            void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                indexMap.putAnnotationOffset(offset, annotationOut.getPosition());\n            }\n\n            @Override\n            void write(Annotation value) {\n                value.writeTo(annotationOut);\n            }\n        }.mergeUnsorted();\n    }\n\n    private void mergeClassDefs() {\n        SortableType[] types = getSortedTypes();\n        contentsOut.classDefs.off = idsDefsOut.getPosition();\n        contentsOut.classDefs.size = types.length;\n\n        for (SortableType type : types) {\n            Dex in = type.getDex();\n            List<DexSectionItem<ClassDef>> dupClassDefs = new ArrayList<DexSectionItem<ClassDef>>();\n            if (null != type.getDupTypes()) {\n                for (SortableType dupType : type.getDupTypes()) {\n                    DexSectionItem<ClassDef> classDefDexItem = new DexSectionItem<ClassDef>();\n                    classDefDexItem.indexMap = dupType.getIndexMap();\n                    classDefDexItem.item = dupType.getClassDef();\n                    classDefDexItem.target = dupType.getDex();\n                    dupClassDefs.add(classDefDexItem);\n                }\n            }\n            transformClassDef(in, type.getClassDef(), type.getIndexMap(), dupClassDefs);\n        }\n    }\n\n    /**\n     * Returns the union of classes from both files, sorted in order such that\n     * a class is always preceded by its supertype and implemented interfaces.\n     */\n    private SortableType[] getSortedTypes() {\n        // size is pessimistic; doesn't include arrays\n        SortableType[] sortableTypes = new SortableType[contentsOut.typeIds.size];\n        for (int i = 0; i < dexes.length; i++) {\n            readSortableTypes(sortableTypes, dexes[i], indexMaps[i]);\n        }\n\n        /*\n         * Populate the depths of each sortable type. This makes D iterations\n         * through all N types, where 'D' is the depth of the deepest type. For\n         * example, the deepest class in libcore is Xalan's KeyIterator, which\n         * is 11 types deep.\n         */\n        while (true) {\n            boolean allDone = true;\n            for (SortableType sortableType : sortableTypes) {\n                if (sortableType != null && !sortableType.isDepthAssigned()) {\n                    allDone &= sortableType.tryAssignDepth(sortableTypes);\n                }\n            }\n            if (allDone) {\n                break;\n            }\n        }\n\n        // Now that all types have depth information, the result can be sorted\n        Arrays.sort(sortableTypes, SortableType.NULLS_LAST_ORDER);\n\n        // Strip nulls from the end\n        int firstNull = Arrays.asList(sortableTypes).indexOf(null);\n        return firstNull != -1 ? Arrays.copyOfRange(sortableTypes, 0, firstNull) : sortableTypes;\n    }\n\n    /**\n     * Reads just enough data on each class so that we can sort it and then find\n     * it later.\n     */\n    private void readSortableTypes(SortableType[] sortableTypes, Dex buffer, IndexMap indexMap) {\n        for (ClassDef classDef : buffer.classDefs()) {\n            int classDataOffSet = classDef.getClassDataOffset();\n            if (classDef.getClassDataOffset() < 0){\n                removeClasses.add(classDataOffSet*-1);\n                continue;\n            }\n            if (removeClasses.contains(classDataOffSet)){\n                continue;\n            }\n           if (removeTypeClasses.size() > 0) {\n               int typeId = classDef.getTypeIndex();\n               String type = buffer.typeNames().get(typeId);\n               if (removeTypeClasses.contains(type)) {\n                   Log.e(\"DexMerger\", \"remove oringal class:\" + type);\n                   continue;\n               }\n           }\n\n            SortableType sortableType = indexMap.adjust(new SortableType(buffer, indexMap, classDef));\n            int t = sortableType.getTypeIndex();\n            if (sortableTypes[t] == null) {\n                sortableTypes[t] = sortableType;\n            } else if (collisionPolicy == CollisionPolicy.MERGE_CLASS_KEEP_FIRST) {\n                // 记录有重复类存在的dex\n                sortableTypes[t].addDupSortableType(sortableType);\n            } else if (collisionPolicy != CollisionPolicy.KEEP_FIRST) {\n                throw new DexException2(\"Multiple dex files define \" + buffer.typeNames().get(classDef.getTypeIndex()));\n            }\n        }\n    }\n\n    /**\n     * Copy annotation sets from each input to the output.\n     *\n     * TODO: this may write multiple copies of the same annotation set.\n     * We should shrink the output by merging rather than unioning\n     */\n    private void unionAnnotationSetsAndDirectories() {\n        for (int i = 0; i < dexes.length; i++) {\n            transformAnnotationSets(dexes[i], indexMaps[i]);\n        }\n        for (int i = 0; i < dexes.length; i++) {\n            transformAnnotationSetRefLists(dexes[i], indexMaps[i]);\n        }\n        for (int i = 0; i < dexes.length; i++) {\n            transformAnnotationDirectories(dexes[i], indexMaps[i]);\n        }\n        for (int i = 0; i < dexes.length; i++) {\n            transformStaticValues(dexes[i], indexMaps[i]);\n        }\n    }\n\n    private void transformAnnotationSets(Dex in, IndexMap indexMap) {\n        TableOfContents.Section section = in.getTableOfContents().annotationSets;\n        if (section.exists()) {\n            Dex.Section setIn = in.open(section.off);\n            for (int i = 0; i < section.size; i++) {\n                transformAnnotationSet(indexMap, setIn);\n            }\n        }\n    }\n\n    private void transformAnnotationSetRefLists(Dex in, IndexMap indexMap) {\n        TableOfContents.Section section = in.getTableOfContents().annotationSetRefLists;\n        if (section.exists()) {\n            Dex.Section setIn = in.open(section.off);\n            for (int i = 0; i < section.size; i++) {\n                transformAnnotationSetRefList(indexMap, setIn);\n            }\n        }\n    }\n\n    private void transformAnnotationDirectories(Dex in, IndexMap indexMap) {\n        TableOfContents.Section section = in.getTableOfContents().annotationsDirectories;\n        if (section.exists()) {\n            Dex.Section directoryIn = in.open(section.off);\n            for (int i = 0; i < section.size; i++) {\n                transformAnnotationDirectory(directoryIn, indexMap);\n            }\n        }\n    }\n\n    private void transformStaticValues(Dex in, IndexMap indexMap) {\n        TableOfContents.Section section = in.getTableOfContents().encodedArrays;\n        if (section.exists()) {\n            Dex.Section staticValuesIn = in.open(section.off);\n            for (int i = 0; i < section.size; i++) {\n                transformStaticValues(staticValuesIn, indexMap);\n            }\n        }\n    }\n\n    /**\n     * Reads a class_def_item beginning at {@code in} and writes the index and\n     * data.\n     */\n    private void transformClassDef(Dex in, ClassDef classDef, IndexMap indexMap, List<DexSectionItem<ClassDef>> dupClassDefs) {\n        idsDefsOut.assertFourByteAligned();\n        idsDefsOut.writeInt(classDef.getTypeIndex());\n        idsDefsOut.writeInt(classDef.getAccessFlags());\n        idsDefsOut.writeInt(classDef.getSupertypeIndex());\n        idsDefsOut.writeInt(classDef.getInterfacesOffset());\n\n        int sourceFileIndex = indexMap.adjustString(classDef.getSourceFileIndex());\n        idsDefsOut.writeInt(sourceFileIndex);\n\n        int annotationsOff = classDef.getAnnotationsOffset();\n        idsDefsOut.writeInt(indexMap.adjustAnnotationDirectory(annotationsOff));\n\n        int classDataOff = classDef.getClassDataOffset();\n        if (classDataOff == 0) {\n            idsDefsOut.writeInt(0);\n        } else {\n            idsDefsOut.writeInt(classDataOut.getPosition());\n            ClassData classData = in.readClassData(classDef);\n            List<DexSectionItem<ClassData>> dupClassDatas = new ArrayList<DexSectionItem<ClassData>>();\n            for (DexSectionItem<ClassDef> dupClassDef : dupClassDefs) {\n                ClassData dupClassData = dupClassDef.target.readClassData(dupClassDef.item);\n                DexSectionItem<ClassData> dupClassDataItem = new DexSectionItem<ClassData>();\n                dupClassDataItem.target = dupClassDef.target;\n                dupClassDataItem.item = dupClassData;\n                dupClassDataItem.indexMap = dupClassDef.indexMap;\n                dupClassDatas.add(dupClassDataItem);\n            }\n            transformClassData(in, classData, indexMap, dupClassDatas);\n        }\n\n        int staticValuesOff = classDef.getStaticValuesOffset();\n        idsDefsOut.writeInt(indexMap.adjustStaticValues(staticValuesOff));\n    }\n\n    /**\n     * Transform all annotations on a class.\n     */\n    private void transformAnnotationDirectory(Dex.Section directoryIn, IndexMap indexMap) {\n        contentsOut.annotationsDirectories.size++;\n        annotationsDirectoryOut.assertFourByteAligned();\n        indexMap.putAnnotationDirectoryOffset(directoryIn.getPosition(), annotationsDirectoryOut.getPosition());\n\n        int classAnnotationsOffset = indexMap.adjustAnnotationSet(directoryIn.readInt());\n        annotationsDirectoryOut.writeInt(classAnnotationsOffset);\n\n        int fieldsSize = directoryIn.readInt();\n        annotationsDirectoryOut.writeInt(fieldsSize);\n\n        int methodsSize = directoryIn.readInt();\n        annotationsDirectoryOut.writeInt(methodsSize);\n\n        int parameterListSize = directoryIn.readInt();\n        annotationsDirectoryOut.writeInt(parameterListSize);\n\n        for (int i = 0; i < fieldsSize; i++) {\n            // field index\n            annotationsDirectoryOut.writeInt(indexMap.adjustField(directoryIn.readInt()));\n\n            // annotations offset\n            annotationsDirectoryOut.writeInt(indexMap.adjustAnnotationSet(directoryIn.readInt()));\n        }\n\n        for (int i = 0; i < methodsSize; i++) {\n            // method index\n            annotationsDirectoryOut.writeInt(indexMap.adjustMethod(directoryIn.readInt()));\n\n            // annotation set offset\n            annotationsDirectoryOut.writeInt(indexMap.adjustAnnotationSet(directoryIn.readInt()));\n        }\n\n        for (int i = 0; i < parameterListSize; i++) {\n            // method index\n            annotationsDirectoryOut.writeInt(indexMap.adjustMethod(directoryIn.readInt()));\n\n            // annotations offset\n            annotationsDirectoryOut.writeInt(indexMap.adjustAnnotationSetRefList(directoryIn.readInt()));\n        }\n    }\n\n    /**\n     * Transform all annotations on a single type, member or parameter.\n     */\n    private void transformAnnotationSet(IndexMap indexMap, Dex.Section setIn) {\n        contentsOut.annotationSets.size++;\n        annotationSetOut.assertFourByteAligned();\n        indexMap.putAnnotationSetOffset(setIn.getPosition(), annotationSetOut.getPosition());\n\n        int size = setIn.readInt();\n        annotationSetOut.writeInt(size);\n\n        for (int j = 0; j < size; j++) {\n            annotationSetOut.writeInt(indexMap.adjustAnnotation(setIn.readInt()));\n        }\n    }\n\n    /**\n     * Transform all annotation set ref lists.\n     */\n    private void transformAnnotationSetRefList(IndexMap indexMap, Dex.Section refListIn) {\n        contentsOut.annotationSetRefLists.size++;\n        annotationSetRefListOut.assertFourByteAligned();\n        indexMap.putAnnotationSetRefListOffset(refListIn.getPosition(), annotationSetRefListOut.getPosition());\n\n        int parameterCount = refListIn.readInt();\n        annotationSetRefListOut.writeInt(parameterCount);\n        for (int p = 0; p < parameterCount; p++) {\n            annotationSetRefListOut.writeInt(indexMap.adjustAnnotationSet(refListIn.readInt()));\n        }\n    }\n\n    private String getMethodIdIndex(MethodId methodId){\n        StringBuilder sb = new StringBuilder();\n        sb.append(methodId.getDeclaringClassIndex()).append(\".\").append(methodId.getNameIndex()).append(\"-\").append(methodId.getProtoIndex());\n        return methodId.toString();\n    }\n    private void transformClassData(Dex in, ClassData classData, IndexMap indexMap,\n                                    List<DexSectionItem<ClassData>> dupClassDatas) {\n        contentsOut.classDatas.size++;\n\n        ClassData.Field[] staticFields = classData.getStaticFields();\n        ClassData.Field[] instanceFields = classData.getInstanceFields();\n        ClassData.Method[] directMethods = classData.getDirectMethods();\n        ClassData.Method[] virtualMethods = classData.getVirtualMethods();\n\n        classDataOut.writeUleb128(staticFields.length);\n        classDataOut.writeUleb128(instanceFields.length);\n        classDataOut.writeUleb128(directMethods.length);\n        classDataOut.writeUleb128(virtualMethods.length);\n\n        transformFields(indexMap, staticFields);\n        transformFields(indexMap, instanceFields);\n        Map<String, ArrayList<DexSectionItem<ClassData.Method>>> dupMethods = new HashMap<String, ArrayList<DexSectionItem<ClassData.Method>>>();\n        for (DexSectionItem<ClassData> dupClassData : dupClassDatas) {\n            ClassData.Method[] methods = dupClassData.item.getDirectMethods();\n\n            if (null != methods && methods.length > 0) {\n                for (ClassData.Method method : methods) {\n                    DexSectionItem<ClassData.Method> methodItem = new DexSectionItem<ClassData.Method>();\n                    methodItem.target = dupClassData.target;\n                    methodItem.indexMap = dupClassData.indexMap;\n                    methodItem.item = method;\n                    Dex dex = dupClassData.target;\n                    MethodId methodId = dupClassData.indexMap.adjust(dex.methodIds().get(method.getMethodIndex()));\n                    String index = getMethodIdIndex(methodId);\n                    ArrayList<DexSectionItem<ClassData.Method>> methodList = dupMethods.get(index);\n                    if (null == methodList) {\n                        methodList = new ArrayList<DexSectionItem<ClassData.Method>>();\n                    }\n                    methodList.add(methodItem);\n                    dupMethods.put(index, methodList);\n                }\n            }\n        }\n        for (DexSectionItem<ClassData> dupClassData : dupClassDatas) {\n            ClassData.Method[] methods = dupClassData.item.getVirtualMethods();\n            if (null != methods && methods.length > 0) {\n                for (ClassData.Method method : methods) {\n                    DexSectionItem<ClassData.Method> methodItem = new DexSectionItem<ClassData.Method>();\n                    methodItem.target = dupClassData.target;\n                    methodItem.indexMap = dupClassData.indexMap;\n                    methodItem.item = method;\n                    Dex dex = dupClassData.target;\n                    MethodId methodId = dupClassData.indexMap.adjust(dex.methodIds().get(method.getMethodIndex()));\n                    String index = getMethodIdIndex(methodId);\n                    ArrayList<DexSectionItem<ClassData.Method>> methodList = dupMethods.get(index);\n                    if (null == methodList) {\n                        methodList = new ArrayList<DexSectionItem<ClassData.Method>>();\n                    }\n                    methodList.add(methodItem);\n                    dupMethods.put(index, methodList);\n                }\n            }\n        }\n        transformMethods(in, indexMap, directMethods, dupMethods);\n        transformMethods(in, indexMap, virtualMethods, dupMethods);\n    }\n\n    private void transformFields(IndexMap indexMap, ClassData.Field[] fields) {\n        int lastOutFieldIndex = 0;\n        for (ClassData.Field field : fields) {\n            int outFieldIndex = indexMap.adjustField(field.getFieldIndex());\n            classDataOut.writeUleb128(outFieldIndex - lastOutFieldIndex);\n            lastOutFieldIndex = outFieldIndex;\n            classDataOut.writeUleb128(field.getAccessFlags());\n        }\n    }\n\n    private void transformMethods(Dex in, IndexMap indexMap, ClassData.Method[] methods,\n                                  Map<String, ArrayList<DexSectionItem<ClassData.Method>>> dupMethodMaps) {\n        int lastOutMethodIndex = 0;\n        for (ClassData.Method method : methods) {\n            int outMethodIndex = indexMap.adjustMethod(method.getMethodIndex());\n            classDataOut.writeUleb128(outMethodIndex - lastOutMethodIndex);\n            lastOutMethodIndex = outMethodIndex;\n\n            classDataOut.writeUleb128(method.getAccessFlags());\n\n            if (method.getCodeOffset() == 0) {\n                classDataOut.writeUleb128(0);\n            } else if (method.getCodeOffset() == 1) { // 1这个我们认为是取下一个dex的数据\n                MethodId methodId = indexMap.adjust(in.methodIds().get(method.getMethodIndex()));\n                String index = getMethodIdIndex(methodId);\n                ArrayList<DexSectionItem<ClassData.Method>> dupMethods = dupMethodMaps.get(index);\n                if (null != dupMethods && dupMethods.size() > 0) {\n                    boolean matchCodes = false;\n                    for (DexSectionItem<ClassData.Method> methodDexSectionItem : dupMethods) {\n                        ClassData.Method preMethod = methodDexSectionItem.item;\n                        if (preMethod.getCodeOffset() > 1) {\n                            codeOut.alignToFourBytesWithZeroFill();\n                            classDataOut.writeUleb128(codeOut.getPosition());\n                            transformCode(methodDexSectionItem.target, methodDexSectionItem.target.readCode(preMethod),\n                                    methodDexSectionItem.indexMap);\n                            matchCodes = true;\n                            break;\n                        }\n                    }\n                    if (!matchCodes) {\n                        classDataOut.writeUleb128(0);\n                    }\n                } else {\n                    throw new IllegalArgumentException(\"Method does not existed in pre dex! method is:\"\n                            + methodId.toString());\n                }\n            } else {\n                codeOut.alignToFourBytesWithZeroFill();\n                classDataOut.writeUleb128(codeOut.getPosition());\n                transformCode(in, in.readCode(method), indexMap);\n            }\n        }\n    }\n\n    private void transformCode(Dex in, Code code, IndexMap indexMap) {\n        contentsOut.codes.size++;\n        codeOut.assertFourByteAligned();\n\n        codeOut.writeUnsignedShort(code.getRegistersSize());\n        codeOut.writeUnsignedShort(code.getInsSize());\n        codeOut.writeUnsignedShort(code.getOutsSize());\n\n        Code.Try[] tries = code.getTries();\n        Code.CatchHandler[] catchHandlers = code.getCatchHandlers();\n        codeOut.writeUnsignedShort(tries.length);\n\n        int debugInfoOffset = code.getDebugInfoOffset();\n        if (debugInfoOffset != 0) {\n            codeOut.writeInt(debugInfoOut.getPosition());\n            transformDebugInfoItem(in.open(debugInfoOffset), indexMap);\n        } else {\n            codeOut.writeInt(0);\n        }\n\n        short[] instructions = code.getInstructions();\n        short[] newInstructions = instructionTransformer.transform(indexMap, instructions);\n        codeOut.writeInt(newInstructions.length);\n        codeOut.write(newInstructions);\n\n        if (tries.length > 0) {\n            if (newInstructions.length % 2 == 1) {\n                codeOut.writeShort((short) 0); // padding\n            }\n\n            /*\n             * We can't write the tries until we've written the catch handlers.\n             * Unfortunately they're in the opposite order in the dex file so we\n             * need to transform them out-of-order.\n             */\n            Dex.Section triesSection = dexOut.open(codeOut.getPosition());\n            codeOut.skip(tries.length * SizeOf.TRY_ITEM);\n            int[] offsets = transformCatchHandlers(indexMap, catchHandlers);\n            transformTries(triesSection, tries, offsets);\n        }\n    }\n\n    /**\n     * Writes the catch handlers to {@code codeOut} and returns their indices.\n     */\n    private int[] transformCatchHandlers(IndexMap indexMap, Code.CatchHandler[] catchHandlers) {\n        int baseOffset = codeOut.getPosition();\n        codeOut.writeUleb128(catchHandlers.length);\n        int[] offsets = new int[catchHandlers.length];\n        for (int i = 0; i < catchHandlers.length; i++) {\n            offsets[i] = codeOut.getPosition() - baseOffset;\n            transformEncodedCatchHandler(catchHandlers[i], indexMap);\n        }\n        return offsets;\n    }\n\n    private void transformTries(Dex.Section out, Code.Try[] tries, int[] catchHandlerOffsets) {\n        for (Code.Try tryItem : tries) {\n            out.writeInt(tryItem.getStartAddress());\n            out.writeUnsignedShort(tryItem.getInstructionCount());\n            out.writeUnsignedShort(catchHandlerOffsets[tryItem.getCatchHandlerIndex()]);\n        }\n    }\n\n    private static final byte DBG_END_SEQUENCE         = 0x00;\n    private static final byte DBG_ADVANCE_PC           = 0x01;\n    private static final byte DBG_ADVANCE_LINE         = 0x02;\n    private static final byte DBG_START_LOCAL          = 0x03;\n    private static final byte DBG_START_LOCAL_EXTENDED = 0x04;\n    private static final byte DBG_END_LOCAL            = 0x05;\n    private static final byte DBG_RESTART_LOCAL        = 0x06;\n    private static final byte DBG_SET_PROLOGUE_END     = 0x07;\n    private static final byte DBG_SET_EPILOGUE_BEGIN   = 0x08;\n    private static final byte DBG_SET_FILE             = 0x09;\n\n    private void transformDebugInfoItem(Dex.Section in, IndexMap indexMap) {\n        contentsOut.debugInfos.size++;\n        int lineStart = in.readUleb128();\n        debugInfoOut.writeUleb128(lineStart);\n\n        int parametersSize = in.readUleb128();\n        debugInfoOut.writeUleb128(parametersSize);\n\n        for (int p = 0; p < parametersSize; p++) {\n            int parameterName = in.readUleb128p1();\n            debugInfoOut.writeUleb128p1(indexMap.adjustString(parameterName));\n        }\n\n        int addrDiff; // uleb128 address delta.\n        int lineDiff; // sleb128 line delta.\n        int registerNum; // uleb128 register number.\n        int nameIndex; // uleb128p1 string index. Needs indexMap adjustment.\n        int typeIndex; // uleb128p1 type index. Needs indexMap adjustment.\n        int sigIndex; // uleb128p1 string index. Needs indexMap adjustment.\n\n        while (true) {\n            int opcode = in.readByte();\n            debugInfoOut.writeByte(opcode);\n\n            switch (opcode) {\n                case DBG_END_SEQUENCE:\n                    return;\n\n                case DBG_ADVANCE_PC:\n                    addrDiff = in.readUleb128();\n                    debugInfoOut.writeUleb128(addrDiff);\n                    break;\n\n                case DBG_ADVANCE_LINE:\n                    lineDiff = in.readSleb128();\n                    debugInfoOut.writeSleb128(lineDiff);\n                    break;\n\n                case DBG_START_LOCAL:\n                case DBG_START_LOCAL_EXTENDED:\n                    registerNum = in.readUleb128();\n                    debugInfoOut.writeUleb128(registerNum);\n                    nameIndex = in.readUleb128p1();\n                    debugInfoOut.writeUleb128p1(indexMap.adjustString(nameIndex));\n                    typeIndex = in.readUleb128p1();\n                    debugInfoOut.writeUleb128p1(indexMap.adjustType(typeIndex));\n                    if (opcode == DBG_START_LOCAL_EXTENDED) {\n                        sigIndex = in.readUleb128p1();\n                        debugInfoOut.writeUleb128p1(indexMap.adjustString(sigIndex));\n                    }\n                    break;\n\n                case DBG_END_LOCAL:\n                case DBG_RESTART_LOCAL:\n                    registerNum = in.readUleb128();\n                    debugInfoOut.writeUleb128(registerNum);\n                    break;\n\n                case DBG_SET_FILE:\n                    nameIndex = in.readUleb128p1();\n                    debugInfoOut.writeUleb128p1(indexMap.adjustString(nameIndex));\n                    break;\n\n                case DBG_SET_PROLOGUE_END:\n                case DBG_SET_EPILOGUE_BEGIN:\n                default:\n                    break;\n            }\n        }\n    }\n\n    private void transformEncodedCatchHandler(Code.CatchHandler catchHandler, IndexMap indexMap) {\n        int catchAllAddress = catchHandler.getCatchAllAddress();\n        int[] typeIndexes = catchHandler.getTypeIndexes();\n        int[] addresses = catchHandler.getAddresses();\n\n        if (catchAllAddress != -1) {\n            codeOut.writeSleb128(-typeIndexes.length);\n        } else {\n            codeOut.writeSleb128(typeIndexes.length);\n        }\n\n        for (int i = 0; i < typeIndexes.length; i++) {\n            codeOut.writeUleb128(indexMap.adjustType(typeIndexes[i]));\n            codeOut.writeUleb128(addresses[i]);\n        }\n\n        if (catchAllAddress != -1) {\n            codeOut.writeUleb128(catchAllAddress);\n        }\n    }\n\n    private void transformStaticValues(Dex.Section in, IndexMap indexMap) {\n        contentsOut.encodedArrays.size++;\n        indexMap.putStaticValuesOffset(in.getPosition(), encodedArrayOut.getPosition());\n        indexMap.adjustEncodedArray(in.readEncodedArray()).writeTo(encodedArrayOut);\n    }\n\n    /**\n     * Byte counts for the sections written when creating a dex. Target sizes\n     * are defined in one of two ways:\n     * <ul>\n     * <li>By pessimistically guessing how large the union of dex files will be.\n     *     We're pessimistic because we can't predict the amount of duplication\n     *     between dex files, nor can we predict the length of ULEB-encoded\n     *     offsets or indices.\n     * <li>By exactly measuring an existing dex.\n     * </ul>\n     */\n    private static class WriterSizes {\n\n        private int header = SizeOf.HEADER_ITEM;\n        private int idsDefs;\n        private int mapList;\n        private int typeList;\n        private int classData;\n        private int code;\n        private int stringData;\n        private int debugInfo;\n        private int encodedArray;\n        private int annotationsDirectory;\n        private int annotationsSet;\n        private int annotationsSetRefList;\n        private int annotation;\n\n        /**\n         * Compute sizes for merging several dexes.\n         */\n        public WriterSizes(Dex[] dexes, boolean exact){\n            for (int i = 0; i < dexes.length; i++) {\n                plus(dexes[i].getTableOfContents(), exact);\n            }\n            fourByteAlign();\n        }\n\n        public WriterSizes(DexMerger dexMerger){\n            header = dexMerger.headerOut.used();\n            idsDefs = dexMerger.idsDefsOut.used();\n            mapList = dexMerger.mapListOut.used();\n            typeList = dexMerger.typeListOut.used();\n            classData = dexMerger.classDataOut.used();\n            code = dexMerger.codeOut.used();\n            stringData = dexMerger.stringDataOut.used();\n            debugInfo = dexMerger.debugInfoOut.used();\n            encodedArray = dexMerger.encodedArrayOut.used();\n            annotationsDirectory = dexMerger.annotationsDirectoryOut.used();\n            annotationsSet = dexMerger.annotationSetOut.used();\n            annotationsSetRefList = dexMerger.annotationSetRefListOut.used();\n            annotation = dexMerger.annotationOut.used();\n            fourByteAlign();\n        }\n\n        private void plus(TableOfContents contents, boolean exact) {\n            idsDefs += contents.stringIds.size * SizeOf.STRING_ID_ITEM + contents.typeIds.size * SizeOf.TYPE_ID_ITEM\n                    + contents.protoIds.size * SizeOf.PROTO_ID_ITEM + contents.fieldIds.size * SizeOf.MEMBER_ID_ITEM\n                    + contents.methodIds.size * SizeOf.MEMBER_ID_ITEM\n                    + contents.classDefs.size * SizeOf.CLASS_DEF_ITEM;\n            mapList = SizeOf.UINT + (contents.sections.length * SizeOf.MAP_ITEM);\n            typeList += fourByteAlign(contents.typeLists.byteCount); // We count each dex's\n            // typelists section as realigned on 4 bytes, because each typelist of each dex's\n            // typelists section is aligned on 4 bytes. If we didn't, there is a case where each\n            // size of both dex's typelists section is a multiple of 2 but not a multiple of 4,\n            // and the sum of both sizes is a multiple of 4 but would not be sufficient to write\n            // each typelist aligned on 4 bytes.\n            stringData += contents.stringDatas.byteCount;\n            annotationsDirectory += contents.annotationsDirectories.byteCount;\n            annotationsSet += contents.annotationSets.byteCount;\n            annotationsSetRefList += contents.annotationSetRefLists.byteCount;\n\n            if (exact) {\n                code += contents.codes.byteCount;\n                classData += contents.classDatas.byteCount;\n                encodedArray += contents.encodedArrays.byteCount;\n                annotation += contents.annotations.byteCount;\n                debugInfo += contents.debugInfos.byteCount;\n            } else {\n                // at most 1/4 of the bytes in a code section are uleb/sleb\n                code += (int) Math.ceil(contents.codes.byteCount * 1.25);\n                // at most 1/3 of the bytes in a class data section are uleb/sleb\n                classData += (int) Math.ceil(contents.classDatas.byteCount * 1.34);\n                // all of the bytes in an encoding arrays section may be uleb/sleb\n                encodedArray += contents.encodedArrays.byteCount * 2;\n                // all of the bytes in an annotations section may be uleb/sleb\n                annotation += (int) Math.ceil(contents.annotations.byteCount * 2);\n                // all of the bytes in a debug info section may be uleb/sleb\n                debugInfo += contents.debugInfos.byteCount * 2;\n            }\n        }\n\n        private void fourByteAlign() {\n            header = fourByteAlign(header);\n            idsDefs = fourByteAlign(idsDefs);\n            mapList = fourByteAlign(mapList);\n            typeList = fourByteAlign(typeList);\n            classData = fourByteAlign(classData);\n            code = fourByteAlign(code);\n            stringData = fourByteAlign(stringData);\n            debugInfo = fourByteAlign(debugInfo);\n            encodedArray = fourByteAlign(encodedArray);\n            annotationsDirectory = fourByteAlign(annotationsDirectory);\n            annotationsSet = fourByteAlign(annotationsSet);\n            annotationsSetRefList = fourByteAlign(annotationsSetRefList);\n            annotation = fourByteAlign(annotation);\n        }\n\n        private static int fourByteAlign(int position) {\n            return (position + 3) & ~3;\n        }\n\n        public int size() {\n            return header + idsDefs + mapList + typeList + classData + code + stringData + debugInfo + encodedArray\n                    + annotationsDirectory + annotationsSet + annotationsSetRefList + annotation;\n        }\n    }\n\n    public static void main(String[] args) throws IOException {\n        if (args.length < 2) {\n            printUsage();\n            return;\n        }\n\n        Dex[] dexes = new Dex[args.length - 1];\n        for (int i = 1; i < args.length; i++) {\n            dexes[i - 1] = new Dex(new File(args[i]));\n        }\n        Dex merged = new DexMerger(dexes, CollisionPolicy.KEEP_FIRST).merge();\n        merged.writeTo(new File(args[0]));\n    }\n\n    private static void printUsage() {\n        System.out.println(\"Usage: DexMerger <out.dex> <a.dex> <b.dex> ...\");\n        System.out.println();\n        System.out.println(\"If a class is defined in several dex, the class found in the first dex will be used.\");\n    }\n}\n\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/merge/DexSectionItem.java",
    "content": "package com.taobao.atlas.dexmerge.dx.merge;\n\nimport com.taobao.atlas.dex.Dex;\n\n/**\n * Created by lilong on 16/10/13.\n */\n    public class DexSectionItem<T> {\n\n        public IndexMap indexMap;\n        public T        item;\n        public Dex target;\n    }\n\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/merge/DexTransform.java",
    "content": "package com.taobao.atlas.dexmerge.dx.merge;\n\n/**\n * Created by lilong on 16/10/13.\n */\n/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport com.taobao.atlas.dex.*;\n\nimport java.io.IOException;\nimport java.util.*;\n\n/**\n * Combine two dex files into one.\n */\npublic final class DexTransform {\n\n    private final Dex dex;\n    private final IndexMap               indexMap;\n    private final WriterSizes            writerSizes;\n    private final Dex                    dexOut;\n\n    private final Dex.Section            headerOut;\n\n    /** All IDs and definitions sections */\n    private final Dex.Section            idsDefsOut;\n\n    private final Dex.Section            mapListOut;\n\n    private final Dex.Section            typeListOut;\n\n    private final Dex.Section            classDataOut;\n\n    private final Dex.Section            codeOut;\n\n    private final Dex.Section            stringDataOut;\n\n    private final Dex.Section            debugInfoOut;\n\n    private final Dex.Section            encodedArrayOut;\n\n    /** annotations directory on a type */\n    private final Dex.Section            annotationsDirectoryOut;\n\n    /** sets of annotations on a member, parameter or type */\n    private final Dex.Section            annotationSetOut;\n\n    /** parameter lists */\n    private final Dex.Section            annotationSetRefListOut;\n\n    /** individual annotations, each containing zero or more fields */\n    private final Dex.Section            annotationOut;\n\n    private final TableOfContents contentsOut;\n\n    private final InstructionTransformer instructionTransformer;\n    private TreeMap<String, DexItem> stringValueOffMaps      = new TreeMap<String, DexItem>(); // 字符串的maps,key为value,value为index\n    private Map<String, DexItem> methodCodeOffMaps       = new HashMap<String, DexItem>(); // 方法名和字节码的off的对应关系\n    private List<Integer> debugInfoRemoveMethodss = new ArrayList<Integer>();\n    private Map<Integer,Integer>     removeClassDefs = new HashMap<Integer, Integer>();\n    private final boolean onlyShrink;\n\n    public DexTransform(Dex dex) throws IOException {\n        this(dex, new WriterSizes(dex, true),false);\n    }\n\n    private DexTransform(Dex dex, WriterSizes writerSizes,boolean onlyShrink) throws IOException{\n        this.dex = dex;\n        this.writerSizes = writerSizes;\n        this.onlyShrink = onlyShrink;\n\n        dexOut = new Dex(writerSizes.size());\n\n        indexMap = new IndexMap(dexOut, dex.getTableOfContents());\n\n        instructionTransformer = new InstructionTransformer();\n\n        headerOut = dexOut.appendSection(writerSizes.header, \"header\");\n        idsDefsOut = dexOut.appendSection(writerSizes.idsDefs, \"ids defs\");\n\n        contentsOut = dexOut.getTableOfContents();\n        contentsOut.dataOff = dexOut.getNextSectionStart();\n\n        contentsOut.mapList.off = dexOut.getNextSectionStart();\n        contentsOut.mapList.size = 1;\n        mapListOut = dexOut.appendSection(writerSizes.mapList, \"map list\");\n\n        contentsOut.typeLists.off = dexOut.getNextSectionStart();\n        typeListOut = dexOut.appendSection(writerSizes.typeList, \"type list\");\n\n        contentsOut.annotationSetRefLists.off = dexOut.getNextSectionStart();\n        annotationSetRefListOut = dexOut.appendSection(writerSizes.annotationsSetRefList, \"annotation set ref list\");\n\n        contentsOut.annotationSets.off = dexOut.getNextSectionStart();\n        annotationSetOut = dexOut.appendSection(writerSizes.annotationsSet, \"annotation sets\");\n\n        contentsOut.classDatas.off = dexOut.getNextSectionStart();\n        classDataOut = dexOut.appendSection(writerSizes.classData, \"class data\");\n\n        contentsOut.codes.off = dexOut.getNextSectionStart();\n        codeOut = dexOut.appendSection(writerSizes.code, \"code\");\n\n        contentsOut.stringDatas.off = dexOut.getNextSectionStart();\n        stringDataOut = dexOut.appendSection(writerSizes.stringData, \"string data\");\n\n        contentsOut.debugInfos.off = dexOut.getNextSectionStart();\n        debugInfoOut = dexOut.appendSection(writerSizes.debugInfo, \"debug info\");\n\n        contentsOut.annotations.off = dexOut.getNextSectionStart();\n        annotationOut = dexOut.appendSection(writerSizes.annotation, \"annotation\");\n\n        contentsOut.encodedArrays.off = dexOut.getNextSectionStart();\n        encodedArrayOut = dexOut.appendSection(writerSizes.encodedArray, \"encoded array\");\n\n        contentsOut.annotationsDirectories.off = dexOut.getNextSectionStart();\n        annotationsDirectoryOut = dexOut.appendSection(writerSizes.annotationsDirectory, \"annotations directory\");\n\n        contentsOut.dataSize = dexOut.getNextSectionStart() - contentsOut.dataOff;\n        if(!onlyShrink) {\n            initIndexMaps();\n        }\n    }\n\n    /**\n     * 初始化所有的Maps\n     */\n    private void initIndexMaps() {\n        intStringIndexMaps(dex);\n        initCodeMaps(dex);\n    }\n\n    private void intStringIndexMaps(Dex dex) {\n        TableOfContents.Section stringIds = dex.getTableOfContents().stringIds;\n        Dex.Section stringDataSection = dex.open(stringIds.off);\n        for (int i = 0; i < stringIds.size; i++) {\n            int position = stringDataSection.getPosition();\n            int off = stringDataSection.readInt();\n            String value = null;\n            if (off < 0) {// 如果为负数,则表示取下一个dex的值\n                value =  String.valueOf(off);\n                stringValueOffMaps.put(value, new DexItem(off, i, off));\n            } else {\n                stringDataSection.getData().position(position);\n                value = stringDataSection.readString();\n                stringValueOffMaps.put(value, new DexItem(off, i, off));\n            }\n        }\n    }\n\n    private void initCodeMaps(Dex dex) {\n        Iterable<ClassDef> classDefs = dex.classDefs();\n        for (ClassDef classDef : classDefs) {\n            if(classDef.getClassDataOffset() > 0) {\n                ClassData classData = dex.readClassData(classDef);\n                ClassData.Method[] directMethods = classData.getDirectMethods();\n                ClassData.Method[] virtualMethods = classData.getVirtualMethods();\n                initMethodsMaps(dex, directMethods);\n                initMethodsMaps(dex, virtualMethods);\n            }\n\n        }\n    }\n\n    private void initMethodsMaps(Dex dex, ClassData.Method[] methods) {\n        for (ClassData.Method method : methods) {\n            MethodId methodId = dex.methodIds().get(method.getMethodIndex());\n            String className = dex.typeNames().get(methodId.getDeclaringClassIndex());\n            String methodName = dex.strings().get(methodId.getNameIndex())\n                    + dex.readTypeList(dex.protoIds().get(methodId.getProtoIndex()).getParametersOffset());\n            methodCodeOffMaps.put(className + \".\" + methodName,\n                    new DexItem(method.getCodeOffset(), method.getMethodIndex(), method.getCodeOffset()));\n        }\n    }\n\n    private Set<String> getMethodMaps(Dex dex){\n        Set<String> methods = new HashSet<String>();\n        Iterable<ClassDef> classDefs = dex.classDefs();\n        for (ClassDef classDef : classDefs) {\n            if(classDef.getClassDataOffset() > 0) {\n                ClassData classData = dex.readClassData(classDef);\n                ClassData.Method[] directMethods = classData.getDirectMethods();\n                ClassData.Method[] virtualMethods = classData.getVirtualMethods();\n                initMethodsMaps(dex, directMethods, methods);\n                initMethodsMaps(dex, virtualMethods, methods);\n            }\n\n        }\n        return methods;\n    }\n\n    private void initMethodsMaps(Dex dex, ClassData.Method[] methods, Set<String> methodSets) {\n        for (ClassData.Method method : methods) {\n            MethodId methodId = dex.methodIds().get(method.getMethodIndex());\n            String className = dex.typeNames().get(methodId.getDeclaringClassIndex());\n            String methodName = dex.strings().get(methodId.getNameIndex())\n                    + dex.readTypeList(dex.protoIds().get(methodId.getProtoIndex()).getParametersOffset());\n            methodSets.add(className + \".\" + methodName);\n        }\n    }\n\n    /**\n     * 根据基线的dex,去除重复的string值\n     *\n     * @param baseDex\n     * @return\n     */\n    public DexTransform uninoStringValues(Dex baseDex) {\n        TableOfContents.Section stringIds = baseDex.getTableOfContents().stringIds;\n        Dex.Section stringSection = baseDex.open(stringIds.off);\n        for (int i = 0; i < stringIds.size; i++) {\n            String value = stringSection.readString();\n            if (stringValueOffMaps.containsKey(value)) {\n                DexItem dexItem = stringValueOffMaps.get(value);\n                dexItem.newOffset = (i + 1) * -1;\n                stringValueOffMaps.put(value, dexItem);\n            }\n        }\n        return this;\n    }\n\n    public DexTransform markClassDef(Dex baseDex,List<String>classNames) {\n        for (ClassDef classDef:dex.classDefs()) {\n            int typeId = classDef.getTypeIndex();\n            String value = dex.typeNames().get(typeId);\n            if (classNames.contains(value)) {\n                for (ClassDef baseClassDef : baseDex.classDefs()) {\n                    if (baseDex.typeNames().get(baseClassDef.getTypeIndex()).equals(value)) {\n                        removeClassDefs.put(typeId, baseClassDef.getClassDataOffset() * -1);\n                    }\n                }\n            }\n        }\n        return this;\n    }\n\n    /**\n     * 移除没有变动的方法的code和debug info信息\n     *\n     * @param modifyMethods\n     * @return\n     */\n    public DexTransform removeMethodCodes(HashMap<String, ArrayList<String>> modifyMethods) {\n        assert null != modifyMethods;\n        List<String> fullModifyMethods = new ArrayList<String>();\n        for (Map.Entry<String, ArrayList<String>> entry : modifyMethods.entrySet()) {\n            String className = entry.getKey();\n            for (String modifyMethodName : entry.getValue()) {\n                String fullMehtodName = className + \".\" + modifyMethodName;\n                fullModifyMethods.add(fullMehtodName);\n            }\n        }\n        for (Map.Entry<String, DexItem> entry : methodCodeOffMaps.entrySet()) {\n            String name = entry.getKey();\n            if (!fullModifyMethods.contains(name)) {\n                DexItem dexItem = entry.getValue();\n                dexItem.newOffset = 1;\n                methodCodeOffMaps.put(name, dexItem);\n            }\n        }\n\n        return this;\n    }\n\n    public DexTransform removeMethodCodes(HashMap<String, ArrayList<String>> modifyMethods,Dex baseDex) {\n        assert null != modifyMethods;\n        List<String> fullModifyMethods = new ArrayList<String>();\n        for (Map.Entry<String, ArrayList<String>> entry : modifyMethods.entrySet()) {\n            String className = entry.getKey();\n            for (String modifyMethodName : entry.getValue()) {\n                String fullMehtodName = className + \".\" + modifyMethodName;\n                fullModifyMethods.add(fullMehtodName);\n            }\n        }\n        Set<String>  baseMethods =  getMethodMaps(baseDex);\n        for (Map.Entry<String, DexItem> entry : methodCodeOffMaps.entrySet()) {\n            String name = entry.getKey();\n            if (!fullModifyMethods.contains(name) &&  baseMethods.contains(name)) {\n                DexItem dexItem = entry.getValue();\n                dexItem.newOffset = 1;\n                methodCodeOffMaps.put(name, dexItem);\n            }\n        }\n\n        return this;\n    }\n\n    /**\n     * 要单独移除debugInfo的类\n     *\n     * @param removeClasses\n     * @return\n     */\n    public DexTransform removeDebugInfos(List<String> removeClasses) {\n        assert null != removeClasses;\n        for (Map.Entry<String, DexItem> entry : methodCodeOffMaps.entrySet()) {\n            String name = entry.getKey();\n            String className = name.substring(0, name.indexOf(\".\"));\n            if (removeClasses.contains(className)) {\n                debugInfoRemoveMethodss.add(entry.getValue().index);\n            }\n        }\n        return this;\n    }\n\n    protected Dex transfromDex() throws IOException {\n        transformStringIds();\n        transformTypeIds();\n        transformTypeLists();\n        transformProtoIds();\n        transformFieldIds();\n        transformMethodIds();\n        transformAnnotations();\n\n        transformAnnotationSets(dex, indexMap);\n        transformAnnotationSetRefLists(dex, indexMap);\n        transformAnnotationDirectories(dex, indexMap);\n        transformStaticValues(dex, indexMap);\n\n        // 处理ClassDef的值\n        transformClassDefs();\n\n        // write the header\n        contentsOut.header.off = 0;\n        contentsOut.header.size = 1;\n        contentsOut.fileSize = dexOut.getLength();\n        contentsOut.computeSizesFromOffsets();\n        contentsOut.writeHeader(headerOut, dex.getTableOfContents().apiLevel);\n        contentsOut.writeMap(mapListOut);\n\n        // generate and write the hashes\n        dexOut.writeHashes();\n\n        return dexOut;\n    }\n\n    /**\n     * 处理StringIds的操作\n     */\n    private void transformStringIds() {\n        if(onlyShrink){\n            contentsOut.stringIds.off = idsDefsOut.getPosition();\n            TableOfContents.Section stringIds = dex.getTableOfContents().stringIds;\n            Dex.Section stringDataSection = dex.open(stringIds.off);\n            for (int i = 0; i < stringIds.size; i++) {\n                int position = stringDataSection.getPosition();\n                int off = stringDataSection.readInt();\n                if (off < 0) {// 如果为负数,则表示取下一个dex的值\n                    idsDefsOut.writeInt(off);\n                } else {\n                    stringDataSection.getData().position(position);\n                    contentsOut.stringDatas.size++;\n                    idsDefsOut.writeInt(stringDataOut.getPosition());\n                    stringDataOut.writeStringData(stringDataSection.readString());\n                }\n                indexMap.stringIds[i] = (short) i;\n            }\n            contentsOut.stringIds.size = stringIds.size;\n\n        }else {\n            contentsOut.stringIds.off = idsDefsOut.getPosition();\n            int index = 0;\n            for (Map.Entry<String, DexItem> entry : stringValueOffMaps.entrySet()) {\n                String value = entry.getKey();\n                DexItem item = entry.getValue();\n                if (item.newOffset > 0) {\n                    contentsOut.stringDatas.size++;\n                    idsDefsOut.writeInt(stringDataOut.getPosition());\n                    stringDataOut.writeStringData(value);\n                } else {\n                    idsDefsOut.writeInt(item.newOffset);\n                }\n                indexMap.stringIds[index] = (short) index;\n                index++;\n\n            }\n            contentsOut.stringIds.size = stringValueOffMaps.size();\n        }\n    }\n\n    public Dex process() throws IOException {\n        Dex result = transfromDex();\n        DexTransform dexShrink = new DexTransform(result, new WriterSizes(this),true);\n        result = dexShrink.transfromDex();\n        return result;\n    }\n\n    /**\n     * Reads an IDs section of two dex files and writes an IDs section of a\n     * merged dex file. Populates maps from old to new indices in the merge.\n     */\n    abstract class IdTransform<T extends Comparable<T>> {\n\n        private final Dex.Section out;\n\n        protected IdTransform(Dex.Section out){\n            this.out = out;\n        }\n\n        public void execute() {\n            TableOfContents.Section dexSection = getSection(dex.getTableOfContents());\n            int size = dexSection.size;\n            if (dexSection.exists()) {\n                Dex.Section inSection = dex.open(dexSection.off);\n                getSection(contentsOut).off = out.getPosition();\n                for (int i = 0; i < size; i++) {\n                    updateIndex(inSection.getPosition(), indexMap, i, i);\n                    T value = read(inSection, indexMap, i);\n                    write(value);\n                }\n            } else {\n                getSection(contentsOut).off = 0;\n            }\n            getSection(contentsOut).size = dexSection.size;\n        }\n\n        abstract TableOfContents.Section getSection(TableOfContents tableOfContents);\n\n        abstract T read(Dex.Section in, IndexMap indexMap, int index);\n\n        abstract void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex);\n\n        abstract void write(T value);\n\n    }\n\n    private void transformTypeIds() {\n        new IdTransform<Integer>(idsDefsOut) {\n\n            @Override\n            TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.typeIds;\n            }\n\n            @Override\n            Integer read(Dex.Section in, IndexMap indexMap, int index) {\n                int stringIndex = in.readInt();\n                return indexMap.adjustString(stringIndex);\n            }\n\n            @Override\n            void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                indexMap.typeIds[oldIndex] = (short) newIndex;\n            }\n\n            @Override\n            void write(Integer value) {\n                idsDefsOut.writeInt(value);\n            }\n        }.execute();\n    }\n\n    private void transformTypeLists() {\n        new IdTransform<TypeList>(typeListOut) {\n\n            @Override\n            TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.typeLists;\n            }\n\n            @Override\n            TypeList read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjustTypeList(in.readTypeList());\n            }\n\n            @Override\n            void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                indexMap.putTypeListOffset(offset, typeListOut.getPosition());\n            }\n\n            @Override\n            void write(TypeList value) {\n                typeListOut.writeTypeList(value);\n            }\n        }.execute();\n    }\n\n    private void transformProtoIds() {\n        new IdTransform<ProtoId>(idsDefsOut) {\n\n            @Override\n            TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.protoIds;\n            }\n\n            @Override\n            ProtoId read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjust(in.readProtoId());\n            }\n\n            @Override\n            void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                indexMap.protoIds[oldIndex] = (short) newIndex;\n            }\n\n            @Override\n            void write(ProtoId value) {\n                value.writeTo(idsDefsOut);\n            }\n        }.execute();\n    }\n\n    private void transformFieldIds() {\n        new IdTransform<FieldId>(idsDefsOut) {\n\n            @Override\n            TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.fieldIds;\n            }\n\n            @Override\n            FieldId read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjust(in.readFieldId());\n            }\n\n            @Override\n            void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                indexMap.fieldIds[oldIndex] = (short) newIndex;\n            }\n\n            @Override\n            void write(FieldId value) {\n                value.writeTo(idsDefsOut);\n            }\n        }.execute();\n    }\n\n    private void transformMethodIds() {\n        new IdTransform<MethodId>(idsDefsOut) {\n\n            @Override\n            TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.methodIds;\n            }\n\n            @Override\n            MethodId read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjust(in.readMethodId());\n            }\n\n            @Override\n            void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                indexMap.methodIds[oldIndex] = (short) newIndex;\n            }\n\n            @Override\n            void write(MethodId methodId) {\n                methodId.writeTo(idsDefsOut);\n            }\n        }.execute();\n    }\n\n    private void transformAnnotations() {\n        new IdTransform<Annotation>(annotationOut) {\n\n            @Override\n            TableOfContents.Section getSection(TableOfContents tableOfContents) {\n                return tableOfContents.annotations;\n            }\n\n            @Override\n            Annotation read(Dex.Section in, IndexMap indexMap, int index) {\n                return indexMap.adjust(in.readAnnotation());\n            }\n\n            @Override\n            void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {\n                indexMap.putAnnotationOffset(offset, annotationOut.getPosition());\n            }\n\n            @Override\n            void write(Annotation value) {\n                value.writeTo(annotationOut);\n            }\n        }.execute();\n    }\n\n    private void transformClassDefs() {\n        TableOfContents.Section dexSection = dex.getTableOfContents().classDefs;\n        if (dexSection.exists()) {\n            contentsOut.classDefs.off = idsDefsOut.getPosition();\n            contentsOut.classDefs.size = dexSection.size;\n            // 书写classData\n            for (ClassDef oldClassDef : dex.classDefs()) {\n                ClassDef classDef = indexMap.adjust(oldClassDef);\n                transformClassDef(dex, classDef, indexMap);\n            }\n        }\n    }\n\n    private void transformAnnotationSets(Dex in, IndexMap indexMap) {\n        TableOfContents.Section section = in.getTableOfContents().annotationSets;\n        if (section.exists()) {\n            Dex.Section setIn = in.open(section.off);\n            for (int i = 0; i < section.size; i++) {\n                transformAnnotationSet(indexMap, setIn);\n            }\n        }\n    }\n\n    private void transformAnnotationSetRefLists(Dex in, IndexMap indexMap) {\n        TableOfContents.Section section = in.getTableOfContents().annotationSetRefLists;\n        if (section.exists()) {\n            Dex.Section setIn = in.open(section.off);\n            for (int i = 0; i < section.size; i++) {\n                transformAnnotationSetRefList(indexMap, setIn);\n            }\n        }\n    }\n\n    private void transformAnnotationDirectories(Dex in, IndexMap indexMap) {\n        TableOfContents.Section section = in.getTableOfContents().annotationsDirectories;\n        if (section.exists()) {\n            Dex.Section directoryIn = in.open(section.off);\n            for (int i = 0; i < section.size; i++) {\n                transformAnnotationDirectory(directoryIn, indexMap);\n            }\n        }\n    }\n\n    private void transformStaticValues(Dex in, IndexMap indexMap) {\n        TableOfContents.Section section = in.getTableOfContents().encodedArrays;\n        if (section.exists()) {\n            Dex.Section staticValuesIn = in.open(section.off);\n            for (int i = 0; i < section.size; i++) {\n                transformStaticValues(staticValuesIn, indexMap);\n            }\n        }\n    }\n\n    /**\n     * Reads a class_def_item beginning at {@code in} and writes the index and\n     * data.\n     */\n    private void transformClassDef(Dex in, ClassDef classDef, IndexMap indexMap) {\n        idsDefsOut.assertFourByteAligned();\n        idsDefsOut.writeInt(classDef.getTypeIndex());\n        idsDefsOut.writeInt(classDef.getAccessFlags());\n        idsDefsOut.writeInt(classDef.getSupertypeIndex());\n        idsDefsOut.writeInt(classDef.getInterfacesOffset());\n\n        int sourceFileIndex = indexMap.adjustString(classDef.getSourceFileIndex());\n        idsDefsOut.writeInt(sourceFileIndex);\n\n        int annotationsOff = classDef.getAnnotationsOffset();\n        idsDefsOut.writeInt(indexMap.adjustAnnotationDirectory(annotationsOff));\n\n        int classDataOff = classDef.getClassDataOffset();\n        if (removeClassDefs.containsKey(classDef.getTypeIndex())&&!onlyShrink) {\n            idsDefsOut.writeInt(removeClassDefs.get(classDef.getTypeIndex()));\n        }else if (onlyShrink && classDataOff < 0){\n            idsDefsOut.writeInt(classDataOff);\n\n        }else if (classDataOff == 0) {\n            idsDefsOut.writeInt(0);\n        } else {\n            idsDefsOut.writeInt(classDataOut.getPosition());\n            ClassData classData = in.readClassData(classDef);\n            transformClassData(in, classData, indexMap);\n        }\n\n        int staticValuesOff = classDef.getStaticValuesOffset();\n        idsDefsOut.writeInt(indexMap.adjustStaticValues(staticValuesOff));\n    }\n\n    /**\n     * Transform all annotations on a class.\n     */\n    private void transformAnnotationDirectory(Dex.Section directoryIn, IndexMap indexMap) {\n        contentsOut.annotationsDirectories.size++;\n        annotationsDirectoryOut.assertFourByteAligned();\n        indexMap.putAnnotationDirectoryOffset(directoryIn.getPosition(), annotationsDirectoryOut.getPosition());\n\n        int classAnnotationsOffset = indexMap.adjustAnnotationSet(directoryIn.readInt());\n        annotationsDirectoryOut.writeInt(classAnnotationsOffset);\n\n        int fieldsSize = directoryIn.readInt();\n        annotationsDirectoryOut.writeInt(fieldsSize);\n\n        int methodsSize = directoryIn.readInt();\n        annotationsDirectoryOut.writeInt(methodsSize);\n\n        int parameterListSize = directoryIn.readInt();\n        annotationsDirectoryOut.writeInt(parameterListSize);\n\n        for (int i = 0; i < fieldsSize; i++) {\n            // field index\n            annotationsDirectoryOut.writeInt(indexMap.adjustField(directoryIn.readInt()));\n\n            // annotations offset\n            annotationsDirectoryOut.writeInt(indexMap.adjustAnnotationSet(directoryIn.readInt()));\n        }\n\n        for (int i = 0; i < methodsSize; i++) {\n            // method index\n            annotationsDirectoryOut.writeInt(indexMap.adjustMethod(directoryIn.readInt()));\n\n            // annotation set offset\n            annotationsDirectoryOut.writeInt(indexMap.adjustAnnotationSet(directoryIn.readInt()));\n        }\n\n        for (int i = 0; i < parameterListSize; i++) {\n            // method index\n            annotationsDirectoryOut.writeInt(indexMap.adjustMethod(directoryIn.readInt()));\n\n            // annotations offset\n            annotationsDirectoryOut.writeInt(indexMap.adjustAnnotationSetRefList(directoryIn.readInt()));\n        }\n    }\n\n    /**\n     * Transform all annotations on a single type, member or parameter.\n     */\n    private void transformAnnotationSet(IndexMap indexMap, Dex.Section setIn) {\n        contentsOut.annotationSets.size++;\n        annotationSetOut.assertFourByteAligned();\n        indexMap.putAnnotationSetOffset(setIn.getPosition(), annotationSetOut.getPosition());\n\n        int size = setIn.readInt();\n        annotationSetOut.writeInt(size);\n\n        for (int j = 0; j < size; j++) {\n            annotationSetOut.writeInt(indexMap.adjustAnnotation(setIn.readInt()));\n        }\n    }\n\n    /**\n     * Transform all annotation set ref lists.\n     */\n    private void transformAnnotationSetRefList(IndexMap indexMap, Dex.Section refListIn) {\n        contentsOut.annotationSetRefLists.size++;\n        annotationSetRefListOut.assertFourByteAligned();\n        indexMap.putAnnotationSetRefListOffset(refListIn.getPosition(), annotationSetRefListOut.getPosition());\n\n        int parameterCount = refListIn.readInt();\n        annotationSetRefListOut.writeInt(parameterCount);\n        for (int p = 0; p < parameterCount; p++) {\n            annotationSetRefListOut.writeInt(indexMap.adjustAnnotationSet(refListIn.readInt()));\n        }\n    }\n\n    private void transformClassData(Dex in, ClassData classData, IndexMap indexMap) {\n        contentsOut.classDatas.size++;\n\n        ClassData.Field[] staticFields = classData.getStaticFields();\n        ClassData.Field[] instanceFields = classData.getInstanceFields();\n        ClassData.Method[] directMethods = classData.getDirectMethods();\n        ClassData.Method[] virtualMethods = classData.getVirtualMethods();\n\n        classDataOut.writeUleb128(staticFields.length);\n        classDataOut.writeUleb128(instanceFields.length);\n        classDataOut.writeUleb128(directMethods.length);\n        classDataOut.writeUleb128(virtualMethods.length);\n\n        transformFields(indexMap, staticFields);\n        transformFields(indexMap, instanceFields);\n        transformMethods(in, indexMap, directMethods);\n        transformMethods(in, indexMap, virtualMethods);\n    }\n\n    private void transformFields(IndexMap indexMap, ClassData.Field[] fields) {\n        int lastOutFieldIndex = 0;\n        for (ClassData.Field field : fields) {\n            int outFieldIndex = indexMap.adjustField(field.getFieldIndex());\n            classDataOut.writeUleb128(outFieldIndex - lastOutFieldIndex);\n            lastOutFieldIndex = outFieldIndex;\n            classDataOut.writeUleb128(field.getAccessFlags());\n        }\n    }\n\n    private void transformMethods(Dex in, IndexMap indexMap, ClassData.Method[] methods) {\n        int lastOutMethodIndex = 0;\n        for (ClassData.Method method : methods) {\n            int outMethodIndex = indexMap.adjustMethod(method.getMethodIndex());\n            classDataOut.writeUleb128(outMethodIndex - lastOutMethodIndex);\n            lastOutMethodIndex = outMethodIndex;\n\n            classDataOut.writeUleb128(method.getAccessFlags());\n\n            if(onlyShrink) {\n                if (method.getCodeOffset() <= 1) {\n                    classDataOut.writeUleb128(method.getCodeOffset());\n                } else {\n                    codeOut.alignToFourBytesWithZeroFill();\n                    classDataOut.writeUleb128(codeOut.getPosition());\n                    transformCode(in, in.readCode(method), indexMap,method.getMethodIndex());\n                }\n            }else{\n                MethodId methodId = dex.methodIds().get(method.getMethodIndex());\n                String className = dex.typeNames().get(methodId.getDeclaringClassIndex());\n                String methodName = dex.strings().get(methodId.getNameIndex())\n                        + dex.readTypeList(dex.protoIds().get(methodId.getProtoIndex()).getParametersOffset());\n                String fullMethodName = className + \".\" + methodName;\n                DexItem dexItem = methodCodeOffMaps.get(fullMethodName);\n\n                if (dexItem.newOffset <= 1) {\n                    classDataOut.writeUleb128(dexItem.newOffset);\n                } else {\n                    codeOut.alignToFourBytesWithZeroFill();\n                    classDataOut.writeUleb128(codeOut.getPosition());\n                    transformCode(in, in.readCode(method), indexMap, method.getMethodIndex());\n                }\n            }\n        }\n    }\n\n    private void transformCode(Dex in, Code code, IndexMap indexMap, int methodIndex) {\n        contentsOut.codes.size++;\n        codeOut.assertFourByteAligned();\n\n        codeOut.writeUnsignedShort(code.getRegistersSize());\n        codeOut.writeUnsignedShort(code.getInsSize());\n        codeOut.writeUnsignedShort(code.getOutsSize());\n\n        Code.Try[] tries = code.getTries();\n        Code.CatchHandler[] catchHandlers = code.getCatchHandlers();\n        codeOut.writeUnsignedShort(tries.length);\n\n        int debugInfoOffset = code.getDebugInfoOffset();\n\n        // 判断是否移除debugInfo\n        if (debugInfoRemoveMethodss.contains(methodIndex) || debugInfoOffset <= 0) {\n            codeOut.writeInt(0);\n        } else {\n            codeOut.writeInt(debugInfoOut.getPosition());\n            transformDebugInfoItem(in.open(debugInfoOffset), indexMap);\n        }\n\n        short[] instructions = code.getInstructions();\n        short[] newInstructions = instructionTransformer.transform(indexMap, instructions);\n        codeOut.writeInt(newInstructions.length);\n        codeOut.write(newInstructions);\n\n        if (tries.length > 0) {\n            if (newInstructions.length % 2 == 1) {\n                codeOut.writeShort((short) 0); // padding\n            }\n\n            /*\n             * We can't write the tries until we've written the catch handlers.\n             * Unfortunately they're in the opposite order in the dex file so we\n             * need to transform them out-of-order.\n             */\n            Dex.Section triesSection = dexOut.open(codeOut.getPosition());\n            codeOut.skip(tries.length * SizeOf.TRY_ITEM);\n            int[] offsets = transformCatchHandlers(indexMap, catchHandlers);\n            transformTries(triesSection, tries, offsets);\n        }\n    }\n\n    /**\n     * Writes the catch handlers to {@code codeOut} and returns their indices.\n     */\n    private int[] transformCatchHandlers(IndexMap indexMap, Code.CatchHandler[] catchHandlers) {\n        int baseOffset = codeOut.getPosition();\n        codeOut.writeUleb128(catchHandlers.length);\n        int[] offsets = new int[catchHandlers.length];\n        for (int i = 0; i < catchHandlers.length; i++) {\n            offsets[i] = codeOut.getPosition() - baseOffset;\n            transformEncodedCatchHandler(catchHandlers[i], indexMap);\n        }\n        return offsets;\n    }\n\n    private void transformTries(Dex.Section out, Code.Try[] tries, int[] catchHandlerOffsets) {\n        for (Code.Try tryItem : tries) {\n            out.writeInt(tryItem.getStartAddress());\n            out.writeUnsignedShort(tryItem.getInstructionCount());\n            out.writeUnsignedShort(catchHandlerOffsets[tryItem.getCatchHandlerIndex()]);\n        }\n    }\n\n    private static final byte DBG_END_SEQUENCE         = 0x00;\n    private static final byte DBG_ADVANCE_PC           = 0x01;\n    private static final byte DBG_ADVANCE_LINE         = 0x02;\n    private static final byte DBG_START_LOCAL          = 0x03;\n    private static final byte DBG_START_LOCAL_EXTENDED = 0x04;\n    private static final byte DBG_END_LOCAL            = 0x05;\n    private static final byte DBG_RESTART_LOCAL        = 0x06;\n    private static final byte DBG_SET_PROLOGUE_END     = 0x07;\n    private static final byte DBG_SET_EPILOGUE_BEGIN   = 0x08;\n    private static final byte DBG_SET_FILE             = 0x09;\n\n    private void transformDebugInfoItem(Dex.Section in, IndexMap indexMap) {\n        contentsOut.debugInfos.size++;\n        int lineStart = in.readUleb128();\n        debugInfoOut.writeUleb128(lineStart);\n\n        int parametersSize = in.readUleb128();\n        debugInfoOut.writeUleb128(parametersSize);\n\n        for (int p = 0; p < parametersSize; p++) {\n            int parameterName = in.readUleb128p1();\n            debugInfoOut.writeUleb128p1(indexMap.adjustString(parameterName));\n        }\n\n        int addrDiff; // uleb128 address delta.\n        int lineDiff; // sleb128 line delta.\n        int registerNum; // uleb128 register number.\n        int nameIndex; // uleb128p1 string index. Needs indexMap adjustment.\n        int typeIndex; // uleb128p1 type index. Needs indexMap adjustment.\n        int sigIndex; // uleb128p1 string index. Needs indexMap adjustment.\n\n        while (true) {\n            int opcode = in.readByte();\n            debugInfoOut.writeByte(opcode);\n\n            switch (opcode) {\n                case DBG_END_SEQUENCE:\n                    return;\n\n                case DBG_ADVANCE_PC:\n                    addrDiff = in.readUleb128();\n                    debugInfoOut.writeUleb128(addrDiff);\n                    break;\n\n                case DBG_ADVANCE_LINE:\n                    lineDiff = in.readSleb128();\n                    debugInfoOut.writeSleb128(lineDiff);\n                    break;\n\n                case DBG_START_LOCAL:\n                case DBG_START_LOCAL_EXTENDED:\n                    registerNum = in.readUleb128();\n                    debugInfoOut.writeUleb128(registerNum);\n                    nameIndex = in.readUleb128p1();\n                    debugInfoOut.writeUleb128p1(indexMap.adjustString(nameIndex));\n                    typeIndex = in.readUleb128p1();\n                    debugInfoOut.writeUleb128p1(indexMap.adjustType(typeIndex));\n                    if (opcode == DBG_START_LOCAL_EXTENDED) {\n                        sigIndex = in.readUleb128p1();\n                        debugInfoOut.writeUleb128p1(indexMap.adjustString(sigIndex));\n                    }\n                    break;\n\n                case DBG_END_LOCAL:\n                case DBG_RESTART_LOCAL:\n                    registerNum = in.readUleb128();\n                    debugInfoOut.writeUleb128(registerNum);\n                    break;\n\n                case DBG_SET_FILE:\n                    nameIndex = in.readUleb128p1();\n                    debugInfoOut.writeUleb128p1(indexMap.adjustString(nameIndex));\n                    break;\n\n                case DBG_SET_PROLOGUE_END:\n                case DBG_SET_EPILOGUE_BEGIN:\n                default:\n                    break;\n            }\n        }\n    }\n\n    private void transformEncodedCatchHandler(Code.CatchHandler catchHandler, IndexMap indexMap) {\n        int catchAllAddress = catchHandler.getCatchAllAddress();\n        int[] typeIndexes = catchHandler.getTypeIndexes();\n        int[] addresses = catchHandler.getAddresses();\n\n        if (catchAllAddress != -1) {\n            codeOut.writeSleb128(-typeIndexes.length);\n        } else {\n            codeOut.writeSleb128(typeIndexes.length);\n        }\n\n        for (int i = 0; i < typeIndexes.length; i++) {\n            codeOut.writeUleb128(indexMap.adjustType(typeIndexes[i]));\n            codeOut.writeUleb128(addresses[i]);\n        }\n\n        if (catchAllAddress != -1) {\n            codeOut.writeUleb128(catchAllAddress);\n        }\n    }\n\n    private void transformStaticValues(Dex.Section in, IndexMap indexMap) {\n        contentsOut.encodedArrays.size++;\n        indexMap.putStaticValuesOffset(in.getPosition(), encodedArrayOut.getPosition());\n        indexMap.adjustEncodedArray(in.readEncodedArray()).writeTo(encodedArrayOut);\n    }\n\n    /**\n     * Byte counts for the sections written when creating a dex. Target sizes\n     * are defined in one of two ways:\n     * <ul>\n     * <li>By pessimistically guessing how large the union of dex files will be.\n     *     We're pessimistic because we can't predict the amount of duplication\n     *     between dex files, nor can we predict the length of ULEB-encoded\n     *     offsets or indices.\n     * <li>By exactly measuring an existing dex.\n     * </ul>\n     */\n    private static class WriterSizes {\n\n        private int header = SizeOf.HEADER_ITEM;\n        private int idsDefs;\n        private int mapList;\n        private int typeList;\n        private int classData;\n        private int code;\n        private int stringData;\n        private int debugInfo;\n        private int encodedArray;\n        private int annotationsDirectory;\n        private int annotationsSet;\n        private int annotationsSetRefList;\n        private int annotation;\n\n        /**\n         * Compute sizes for merging several dexes.\n         */\n        public WriterSizes(Dex dex, boolean exact){\n            plus(dex.getTableOfContents(), exact);\n            fourByteAlign();\n        }\n\n        public WriterSizes(DexTransform dexTransform){\n            header = dexTransform.headerOut.used();\n            idsDefs = dexTransform.idsDefsOut.used();\n            mapList = dexTransform.mapListOut.used();\n            typeList = dexTransform.typeListOut.used();\n            classData = dexTransform.classDataOut.used();\n            code = dexTransform.codeOut.used();\n            stringData = dexTransform.stringDataOut.used();\n            debugInfo = dexTransform.debugInfoOut.used();\n            encodedArray = dexTransform.encodedArrayOut.used();\n            annotationsDirectory = dexTransform.annotationsDirectoryOut.used();\n            annotationsSet = dexTransform.annotationSetOut.used();\n            annotationsSetRefList = dexTransform.annotationSetRefListOut.used();\n            annotation = dexTransform.annotationOut.used();\n            fourByteAlign();\n        }\n\n        private void plus(TableOfContents contents, boolean exact) {\n            idsDefs += contents.stringIds.size * SizeOf.STRING_ID_ITEM + contents.typeIds.size * SizeOf.TYPE_ID_ITEM\n                    + contents.protoIds.size * SizeOf.PROTO_ID_ITEM + contents.fieldIds.size * SizeOf.MEMBER_ID_ITEM\n                    + contents.methodIds.size * SizeOf.MEMBER_ID_ITEM\n                    + contents.classDefs.size * SizeOf.CLASS_DEF_ITEM;\n            mapList = SizeOf.UINT + (contents.sections.length * SizeOf.MAP_ITEM);\n            typeList += fourByteAlign(contents.typeLists.byteCount); // We count each dex's\n            // typelists section as realigned on 4 bytes, because each typelist of each dex's\n            // typelists section is aligned on 4 bytes. If we didn't, there is a case where each\n            // size of both dex's typelists section is a multiple of 2 but not a multiple of 4,\n            // and the sum of both sizes is a multiple of 4 but would not be sufficient to write\n            // each typelist aligned on 4 bytes.\n            stringData += contents.stringDatas.byteCount;\n            annotationsDirectory += contents.annotationsDirectories.byteCount;\n            annotationsSet += contents.annotationSets.byteCount;\n            annotationsSetRefList += contents.annotationSetRefLists.byteCount;\n\n            if (exact) {\n                code += contents.codes.byteCount;\n                classData += contents.classDatas.byteCount;\n                encodedArray += contents.encodedArrays.byteCount;\n                annotation += contents.annotations.byteCount;\n                debugInfo += contents.debugInfos.byteCount;\n            } else {\n                // at most 1/4 of the bytes in a code section are uleb/sleb\n                code += (int) Math.ceil(contents.codes.byteCount * 1.25);\n                // at most 1/3 of the bytes in a class data section are uleb/sleb\n                classData += (int) Math.ceil(contents.classDatas.byteCount * 1.34);\n                // all of the bytes in an encoding arrays section may be uleb/sleb\n                encodedArray += contents.encodedArrays.byteCount * 2;\n                // all of the bytes in an annotations section may be uleb/sleb\n                annotation += (int) Math.ceil(contents.annotations.byteCount * 2);\n                // all of the bytes in a debug info section may be uleb/sleb\n                debugInfo += contents.debugInfos.byteCount * 2;\n            }\n        }\n\n        private void fourByteAlign() {\n            header = fourByteAlign(header);\n            idsDefs = fourByteAlign(idsDefs);\n            mapList = fourByteAlign(mapList);\n            typeList = fourByteAlign(typeList);\n            classData = fourByteAlign(classData);\n            code = fourByteAlign(code);\n            stringData = fourByteAlign(stringData);\n            debugInfo = fourByteAlign(debugInfo);\n            encodedArray = fourByteAlign(encodedArray);\n            annotationsDirectory = fourByteAlign(annotationsDirectory);\n            annotationsSet = fourByteAlign(annotationsSet);\n            annotationsSetRefList = fourByteAlign(annotationsSetRefList);\n            annotation = fourByteAlign(annotation);\n        }\n\n        private static int fourByteAlign(int position) {\n            return (position + 3) & ~3;\n        }\n\n        public int size() {\n            return header + idsDefs + mapList + typeList + classData + code + stringData + debugInfo + encodedArray\n                    + annotationsDirectory + annotationsSet + annotationsSetRefList + annotation;\n        }\n    }\n\n    class DexItem {\n\n        int offset;\n        int index;\n        int newOffset;\n\n        public DexItem(int offset, int index, int newOffset){\n            this.offset = offset;\n            this.index = index;\n            this.newOffset = newOffset;\n        }\n    }\n}\n\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/merge/IndexMap.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.merge;\n\nimport com.taobao.atlas.dex.*;\nimport com.taobao.atlas.dex.util.ByteOutput;\nimport com.taobao.atlas.dexmerge.dx.util.ByteArrayAnnotatedOutput;\n\nimport java.util.HashMap;\n\nimport static com.taobao.atlas.dex.EncodedValueReader.*;\n\n/**\n * Maps the index offsets from one dex file to those in another. For example, if\n * you have string #5 in the old dex file, its position in the new dex file is\n * {@code strings[5]}.\n */\npublic final class IndexMap {\n    private final Dex target;\n    public final int[] stringIds;\n    public final short[] typeIds;\n    public final short[] protoIds;\n    public final short[] fieldIds;\n    public final short[] methodIds;\n    private final HashMap<Integer, Integer> typeListOffsets;\n    private final HashMap<Integer, Integer> annotationOffsets;\n    private final HashMap<Integer, Integer> annotationSetOffsets;\n    private final HashMap<Integer, Integer> annotationSetRefListOffsets;\n    private final HashMap<Integer, Integer> annotationDirectoryOffsets;\n    private final HashMap<Integer, Integer> staticValuesOffsets;\n\n    public IndexMap(Dex target, TableOfContents tableOfContents) {\n        this.target = target;\n        this.stringIds = new int[tableOfContents.stringIds.size];\n        this.typeIds = new short[tableOfContents.typeIds.size];\n        this.protoIds = new short[tableOfContents.protoIds.size];\n        this.fieldIds = new short[tableOfContents.fieldIds.size];\n        this.methodIds = new short[tableOfContents.methodIds.size];\n        this.typeListOffsets = new HashMap<Integer, Integer>();\n        this.annotationOffsets = new HashMap<Integer, Integer>();\n        this.annotationSetOffsets = new HashMap<Integer, Integer>();\n        this.annotationSetRefListOffsets = new HashMap<Integer, Integer>();\n        this.annotationDirectoryOffsets = new HashMap<Integer, Integer>();\n        this.staticValuesOffsets = new HashMap<Integer, Integer>();\n\n        /*\n         * A type list, annotation set, annotation directory, or static value at\n         * offset 0 is always empty. Always map offset 0 to 0.\n         */\n        this.typeListOffsets.put(0, 0);\n        this.annotationSetOffsets.put(0, 0);\n        this.annotationDirectoryOffsets.put(0, 0);\n        this.staticValuesOffsets.put(0, 0);\n    }\n\n    public void putTypeListOffset(int oldOffset, int newOffset) {\n        if (oldOffset <= 0 || newOffset <= 0) {\n            throw new IllegalArgumentException();\n        }\n        typeListOffsets.put(oldOffset, newOffset);\n    }\n\n    public void putAnnotationOffset(int oldOffset, int newOffset) {\n        if (oldOffset <= 0 || newOffset <= 0) {\n            throw new IllegalArgumentException();\n        }\n        annotationOffsets.put(oldOffset, newOffset);\n    }\n\n    public void putAnnotationSetOffset(int oldOffset, int newOffset) {\n        if (oldOffset <= 0 || newOffset <= 0) {\n            throw new IllegalArgumentException();\n        }\n        annotationSetOffsets.put(oldOffset, newOffset);\n    }\n\n    public void putAnnotationSetRefListOffset(int oldOffset, int newOffset) {\n        if (oldOffset <= 0 || newOffset <= 0) {\n            throw new IllegalArgumentException();\n        }\n        annotationSetRefListOffsets.put(oldOffset, newOffset);\n    }\n\n    public void putAnnotationDirectoryOffset(int oldOffset, int newOffset) {\n        if (oldOffset <= 0 || newOffset <= 0) {\n            throw new IllegalArgumentException();\n        }\n        annotationDirectoryOffsets.put(oldOffset, newOffset);\n    }\n\n    public void putStaticValuesOffset(int oldOffset, int newOffset) {\n        if (oldOffset <= 0 || newOffset <= 0) {\n            throw new IllegalArgumentException();\n        }\n        staticValuesOffsets.put(oldOffset, newOffset);\n    }\n\n    public int adjustString(int stringIndex) {\n        return stringIndex == ClassDef.NO_INDEX ? ClassDef.NO_INDEX : stringIds[stringIndex];\n    }\n\n    public int adjustType(int typeIndex) {\n        return (typeIndex == ClassDef.NO_INDEX) ? ClassDef.NO_INDEX : (typeIds[typeIndex] & 0xffff);\n    }\n\n    public TypeList adjustTypeList(TypeList typeList) {\n        if (typeList == TypeList.EMPTY) {\n            return typeList;\n        }\n        short[] types = typeList.getTypes().clone();\n        for (int i = 0; i < types.length; i++) {\n            types[i] = (short) adjustType(types[i]);\n        }\n        return new TypeList(target, types);\n    }\n\n    public int adjustProto(int protoIndex) {\n        return protoIds[protoIndex] & 0xffff;\n    }\n\n    public int adjustField(int fieldIndex) {\n        return fieldIds[fieldIndex] & 0xffff;\n    }\n\n    public int adjustMethod(int methodIndex) {\n        return methodIds[methodIndex] & 0xffff;\n    }\n\n    public int adjustTypeListOffset(int typeListOffset) {\n        return typeListOffsets.get(typeListOffset);\n    }\n\n    public int adjustAnnotation(int annotationOffset) {\n        return annotationOffsets.get(annotationOffset);\n    }\n\n    public int adjustAnnotationSet(int annotationSetOffset) {\n        return annotationSetOffsets.get(annotationSetOffset);\n    }\n\n    public int adjustAnnotationSetRefList(int annotationSetRefListOffset) {\n        return annotationSetRefListOffsets.get(annotationSetRefListOffset);\n    }\n\n    public int adjustAnnotationDirectory(int annotationDirectoryOffset) {\n        return annotationDirectoryOffsets.get(annotationDirectoryOffset);\n    }\n\n    public int adjustStaticValues(int staticValuesOffset) {\n        return staticValuesOffsets.get(staticValuesOffset);\n    }\n\n    public MethodId adjust(MethodId methodId) {\n        return new MethodId(target,\n                adjustType(methodId.getDeclaringClassIndex()),\n                adjustProto(methodId.getProtoIndex()),\n                adjustString(methodId.getNameIndex()));\n    }\n\n    public FieldId adjust(FieldId fieldId) {\n        return new FieldId(target,\n                adjustType(fieldId.getDeclaringClassIndex()),\n                adjustType(fieldId.getTypeIndex()),\n                adjustString(fieldId.getNameIndex()));\n\n    }\n\n    public ProtoId adjust(ProtoId protoId) {\n        return new ProtoId(target,\n                adjustString(protoId.getShortyIndex()),\n                adjustType(protoId.getReturnTypeIndex()),\n                adjustTypeListOffset(protoId.getParametersOffset()));\n    }\n\n    public ClassDef adjust(ClassDef classDef) {\n        return new ClassDef(target, classDef.getOffset(), adjustType(classDef.getTypeIndex()),\n                classDef.getAccessFlags(), adjustType(classDef.getSupertypeIndex()),\n                adjustTypeListOffset(classDef.getInterfacesOffset()), classDef.getSourceFileIndex(),\n                classDef.getAnnotationsOffset(), classDef.getClassDataOffset(),\n                classDef.getStaticValuesOffset());\n    }\n\n    public SortableType adjust(SortableType sortableType) {\n        return new SortableType(sortableType.getDex(),\n                sortableType.getIndexMap(), adjust(sortableType.getClassDef()));\n    }\n\n    public EncodedValue adjustEncodedValue(EncodedValue encodedValue) {\n        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput(32);\n        new EncodedValueTransformer(out).transform(new EncodedValueReader(encodedValue));\n        return new EncodedValue(out.toByteArray());\n    }\n\n    public EncodedValue adjustEncodedArray(EncodedValue encodedArray) {\n        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput(32);\n        new EncodedValueTransformer(out).transformArray(\n                new EncodedValueReader(encodedArray, ENCODED_ARRAY));\n        return new EncodedValue(out.toByteArray());\n    }\n\n    public Annotation adjust(Annotation annotation) {\n        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput(32);\n        new EncodedValueTransformer(out).transformAnnotation(\n                annotation.getReader());\n        return new Annotation(target, annotation.getVisibility(),\n                new EncodedValue(out.toByteArray()));\n    }\n\n    /**\n     * Adjust an encoded value or array.\n     */\n    private final class EncodedValueTransformer {\n        private final ByteOutput out;\n\n        public EncodedValueTransformer(ByteOutput out) {\n            this.out = out;\n        }\n\n        public void transform(EncodedValueReader reader) {\n            // TODO: extract this into a helper class, EncodedValueWriter\n            switch (reader.peek()) {\n                case ENCODED_BYTE:\n                    EncodedValueCodec.writeSignedIntegralValue(out, ENCODED_BYTE, reader.readByte());\n                    break;\n                case ENCODED_SHORT:\n                    EncodedValueCodec.writeSignedIntegralValue(out, ENCODED_SHORT, reader.readShort());\n                    break;\n                case ENCODED_INT:\n                    EncodedValueCodec.writeSignedIntegralValue(out, ENCODED_INT, reader.readInt());\n                    break;\n                case ENCODED_LONG:\n                    EncodedValueCodec.writeSignedIntegralValue(out, ENCODED_LONG, reader.readLong());\n                    break;\n                case ENCODED_CHAR:\n                    EncodedValueCodec.writeUnsignedIntegralValue(out, ENCODED_CHAR, reader.readChar());\n                    break;\n                case ENCODED_FLOAT:\n                    // Shift value left 32 so that right-zero-extension works.\n                    long longBits = ((long) Float.floatToIntBits(reader.readFloat())) << 32;\n                    EncodedValueCodec.writeRightZeroExtendedValue(out, ENCODED_FLOAT, longBits);\n                    break;\n                case ENCODED_DOUBLE:\n                    EncodedValueCodec.writeRightZeroExtendedValue(\n                            out, ENCODED_DOUBLE, Double.doubleToLongBits(reader.readDouble()));\n                    break;\n                case ENCODED_STRING:\n                    EncodedValueCodec.writeUnsignedIntegralValue(\n                            out, ENCODED_STRING, adjustString(reader.readString()));\n                    break;\n                case ENCODED_TYPE:\n                    EncodedValueCodec.writeUnsignedIntegralValue(\n                            out, ENCODED_TYPE, adjustType(reader.readType()));\n                    break;\n                case ENCODED_FIELD:\n                    EncodedValueCodec.writeUnsignedIntegralValue(\n                            out, ENCODED_FIELD, adjustField(reader.readField()));\n                    break;\n                case ENCODED_ENUM:\n                    EncodedValueCodec.writeUnsignedIntegralValue(\n                            out, ENCODED_ENUM, adjustField(reader.readEnum()));\n                    break;\n                case ENCODED_METHOD:\n                    EncodedValueCodec.writeUnsignedIntegralValue(\n                            out, ENCODED_METHOD, adjustMethod(reader.readMethod()));\n                    break;\n                case ENCODED_ARRAY:\n                    writeTypeAndArg(ENCODED_ARRAY, 0);\n                    transformArray(reader);\n                    break;\n                case ENCODED_ANNOTATION:\n                    writeTypeAndArg(ENCODED_ANNOTATION, 0);\n                    transformAnnotation(reader);\n                    break;\n                case ENCODED_NULL:\n                    reader.readNull();\n                    writeTypeAndArg(ENCODED_NULL, 0);\n                    break;\n                case ENCODED_BOOLEAN:\n                    boolean value = reader.readBoolean();\n                    writeTypeAndArg(ENCODED_BOOLEAN, value ? 1 : 0);\n                    break;\n                default:\n                    throw new DexException2(\"Unexpected type: \" + Integer.toHexString(reader.peek()));\n            }\n        }\n\n        private void transformAnnotation(EncodedValueReader reader) {\n            int fieldCount = reader.readAnnotation();\n            Leb128.writeUnsignedLeb128(out, adjustType(reader.getAnnotationType()));\n            Leb128.writeUnsignedLeb128(out, fieldCount);\n            for (int i = 0; i < fieldCount; i++) {\n                Leb128.writeUnsignedLeb128(out, adjustString(reader.readAnnotationName()));\n                transform(reader);\n            }\n        }\n\n        private void transformArray(EncodedValueReader reader) {\n            int size = reader.readArray();\n            Leb128.writeUnsignedLeb128(out, size);\n            for (int i = 0; i < size; i++) {\n                transform(reader);\n            }\n        }\n\n        private void writeTypeAndArg(int type, int arg) {\n            out.writeByte((arg << 5) | type);\n        }\n    }\n}"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/merge/InstructionTransformer.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.merge;\n\nimport com.taobao.atlas.dex.DexException2;\nimport com.taobao.atlas.dex.DexIndexOverflowException;\nimport com.taobao.atlas.dexmerge.dx.io.CodeReader;\nimport com.taobao.atlas.dexmerge.dx.io.Opcodes;\nimport com.taobao.atlas.dexmerge.dx.io.instructions.DecodedInstruction;\nimport com.taobao.atlas.dexmerge.dx.io.instructions.ShortArrayCodeOutput;\n\nfinal class InstructionTransformer {\n    private final CodeReader reader;\n\n    private DecodedInstruction[] mappedInstructions;\n    private int mappedAt;\n    private IndexMap indexMap;\n\n    public InstructionTransformer() {\n        this.reader = new CodeReader();\n        this.reader.setAllVisitors(new GenericVisitor());\n        this.reader.setStringVisitor(new StringVisitor());\n        this.reader.setTypeVisitor(new TypeVisitor());\n        this.reader.setFieldVisitor(new FieldVisitor());\n        this.reader.setMethodVisitor(new MethodVisitor());\n    }\n\n    public short[] transform(IndexMap indexMap, short[] encodedInstructions) throws DexException2 {\n        DecodedInstruction[] decodedInstructions =\n                DecodedInstruction.decodeAll(encodedInstructions);\n        int size = decodedInstructions.length;\n\n        this.indexMap = indexMap;\n        mappedInstructions = new DecodedInstruction[size];\n        mappedAt = 0;\n        reader.visitAll(decodedInstructions);\n\n        ShortArrayCodeOutput out = new ShortArrayCodeOutput(size);\n        for (DecodedInstruction instruction : mappedInstructions) {\n            if (instruction != null) {\n                instruction.encode(out);\n            }\n        }\n\n        this.indexMap = null;\n        return out.getArray();\n    }\n\n    private class GenericVisitor implements CodeReader.Visitor {\n        public void visit(DecodedInstruction[] all, DecodedInstruction one) {\n            mappedInstructions[mappedAt++] = one;\n        }\n    }\n\n    private class StringVisitor implements CodeReader.Visitor {\n        public void visit(DecodedInstruction[] all, DecodedInstruction one) {\n            int stringId = one.getIndex();\n            int mappedId = indexMap.adjustString(stringId);\n            boolean isJumbo = (one.getOpcode() == Opcodes.CONST_STRING_JUMBO);\n            jumboCheck(isJumbo, mappedId);\n            mappedInstructions[mappedAt++] = one.withIndex(mappedId);\n        }\n    }\n\n    private class FieldVisitor implements CodeReader.Visitor {\n        public void visit(DecodedInstruction[] all, DecodedInstruction one) {\n            int fieldId = one.getIndex();\n            int mappedId = indexMap.adjustField(fieldId);\n            boolean isJumbo = (one.getOpcode() == Opcodes.CONST_STRING_JUMBO);\n            jumboCheck(isJumbo, mappedId);\n            mappedInstructions[mappedAt++] = one.withIndex(mappedId);\n        }\n    }\n\n    private class TypeVisitor implements CodeReader.Visitor {\n        public void visit(DecodedInstruction[] all, DecodedInstruction one) {\n            int typeId = one.getIndex();\n            int mappedId = indexMap.adjustType(typeId);\n            boolean isJumbo = (one.getOpcode() == Opcodes.CONST_STRING_JUMBO);\n            jumboCheck(isJumbo, mappedId);\n            mappedInstructions[mappedAt++] = one.withIndex(mappedId);\n        }\n    }\n\n    private class MethodVisitor implements CodeReader.Visitor {\n        public void visit(DecodedInstruction[] all, DecodedInstruction one) {\n            int methodId = one.getIndex();\n            int mappedId = indexMap.adjustMethod(methodId);\n            boolean isJumbo = (one.getOpcode() == Opcodes.CONST_STRING_JUMBO);\n            jumboCheck(isJumbo, mappedId);\n            mappedInstructions[mappedAt++] = one.withIndex(mappedId);\n        }\n    }\n\n    private static void jumboCheck(boolean isJumbo, int newIndex) {\n        if (!isJumbo && (newIndex > 0xffff)) {\n            throw new DexIndexOverflowException(\"Cannot merge new index \" + newIndex +\n                    \" into a non-jumbo instruction!\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/merge/SortableType.java",
    "content": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.merge;\n\nimport com.taobao.atlas.dex.ClassDef;\nimport com.taobao.atlas.dex.Dex;\nimport com.taobao.atlas.dex.DexException2;\n\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.List;\n\n/**\n * Name and structure of a type. Used to order types such that each type is\n * preceded by its supertype and implemented interfaces.\n */\nfinal class SortableType {\n    public static final Comparator<SortableType> NULLS_LAST_ORDER = new Comparator<SortableType>() {\n        public int compare(SortableType a, SortableType b) {\n            if (a == b) {\n                return 0;\n            }\n            if (b == null) {\n                return -1;\n            }\n            if (a == null) {\n                return 1;\n            }\n            if (a.depth != b.depth) {\n                return a.depth - b.depth;\n            }\n            return a.getTypeIndex() - b.getTypeIndex();\n        }\n    };\n\n    private final Dex dex;\n    private final IndexMap indexMap;\n    private ClassDef classDef;\n    private int depth = -1;\n    private List<SortableType> dupTypes;\n\n\n    public SortableType(Dex dex, IndexMap indexMap, ClassDef classDef) {\n        this.dex = dex;\n        this.indexMap = indexMap;\n        this.classDef = classDef;\n    }\n\n    public Dex getDex() {\n        return dex;\n    }\n\n    public IndexMap getIndexMap() {\n        return indexMap;\n    }\n\n    public ClassDef getClassDef() {\n        return classDef;\n    }\n\n    public int getTypeIndex() {\n        return classDef.getTypeIndex();\n    }\n\n\n    public List<SortableType> getDupTypes() {\n        return dupTypes;\n    }\n\n    public void addDupSortableType(SortableType sortableType){\n        if(null == dupTypes){\n            dupTypes = new ArrayList<SortableType>();\n        }\n        dupTypes.add(sortableType);\n    }\n\n\n    /**\n     * Assigns this type's depth if the depths of its supertype and implemented\n     * interfaces are known. Returns false if the depth couldn't be computed\n     * yet.\n     */\n    public boolean tryAssignDepth(SortableType[] types) {\n        int max;\n        if (classDef.getSupertypeIndex() == ClassDef.NO_INDEX) {\n            max = 0; // this is Object.class or an interface\n        } else if (classDef.getSupertypeIndex() == classDef.getTypeIndex()) {\n            // This is an invalid class extending itself.\n            throw new DexException2(\"Class with type index \" + classDef.getTypeIndex()\n                    + \" extends itself\");\n        } else {\n            SortableType sortableSupertype = types[classDef.getSupertypeIndex()];\n            if (sortableSupertype == null) {\n                max = 1; // unknown, so assume it's a root.\n            } else if (sortableSupertype.depth == -1) {\n                return false;\n            } else {\n                max = sortableSupertype.depth;\n            }\n        }\n\n        for (short interfaceIndex : classDef.getInterfaces()) {\n            SortableType implemented = types[interfaceIndex];\n            if (implemented == null) {\n                max = Math.max(max, 1); // unknown, so assume it's a root.\n            } else if (implemented.depth == -1) {\n                return false;\n            } else {\n                max = Math.max(max, implemented.depth);\n            }\n        }\n\n        depth = max + 1;\n        return true;\n    }\n\n    public boolean isDepthAssigned() {\n        return depth != -1;\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/AnnotatedOutput.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\n/**\n * Interface for a binary output destination that may be augmented\n * with textual annotations.\n */\npublic interface AnnotatedOutput\n        extends Output {\n    /**\n     * Get whether this instance will actually keep annotations.\n     *\n     * @return {@code true} iff annotations are being kept\n     */\n    public boolean annotates();\n\n    /**\n     * Get whether this instance is intended to keep verbose annotations.\n     * Annotators may use the result of calling this method to inform their\n     * annotation activity.\n     *\n     * @return {@code true} iff annotations are to be verbose\n     */\n    public boolean isVerbose();\n\n    /**\n     * Add an annotation for the subsequent output. Any previously\n     * open annotation will be closed by this call, and the new\n     * annotation marks all subsequent output until another annotation\n     * call.\n     *\n     * @param msg {@code non-null;} the annotation message\n     */\n    public void annotate(String msg);\n\n    /**\n     * Add an annotation for a specified amount of subsequent\n     * output. Any previously open annotation will be closed by this\n     * call. If there is already pending annotation from one or more\n     * previous calls to this method, the new call \"consumes\" output\n     * after all the output covered by the previous calls.\n     *\n     * @param amt {@code >= 0;} the amount of output for this annotation to\n     * cover\n     * @param msg {@code non-null;} the annotation message\n     */\n    public void annotate(int amt, String msg);\n\n    /**\n     * End the most recent annotation. Subsequent output will be unannotated,\n     * until the next call to {@link #annotate}.\n     */\n    public void endAnnotation();\n\n    /**\n     * Get the maximum width of the annotated output. This is advisory:\n     * Implementations of this interface are encouraged to deal with too-wide\n     * output, but annotaters are encouraged to attempt to avoid exceeding\n     * the indicated width.\n     *\n     * @return {@code >= 1;} the maximum width\n     */\n    public int getAnnotationWidth();\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/BitIntSet.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\nimport java.util.NoSuchElementException;\n\n/**\n * A set of integers, represented by a bit set\n */\npublic class BitIntSet implements IntSet {\n\n    /** also accessed in ListIntSet */\n    int[] bits;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param max the maximum value of ints in this set.\n     */\n    public BitIntSet(int max) {\n        bits = Bits.makeBitSet(max);\n    }\n\n    /** @inheritDoc */\n    public void add(int value) {\n        ensureCapacity(value);\n        Bits.set(bits, value, true);\n    }\n\n    /**\n     * Ensures that the bit set has the capacity to represent the given value.\n     *\n     * @param value {@code >= 0;} value to represent\n     */\n    private void ensureCapacity(int value) {\n        if (value >= Bits.getMax(bits)) {\n            int[] newBits = Bits.makeBitSet(\n                    Math.max(value + 1, 2 * Bits.getMax(bits)));\n            System.arraycopy(bits, 0, newBits, 0, bits.length);\n            bits = newBits;\n        }\n    }\n\n    /** @inheritDoc */\n    public void remove(int value) {\n        if (value < Bits.getMax(bits)) {\n            Bits.set(bits, value, false);\n        }\n    }\n\n    /** @inheritDoc */\n    public boolean has(int value) {\n        return (value < Bits.getMax(bits)) && Bits.get(bits, value);\n    }\n\n    /** @inheritDoc */\n    public void merge(IntSet other) {\n        if (other instanceof BitIntSet) {\n            BitIntSet o = (BitIntSet) other;\n            ensureCapacity(Bits.getMax(o.bits) + 1);\n            Bits.or(bits, o.bits);\n        } else if (other instanceof ListIntSet) {\n            ListIntSet o = (ListIntSet) other;\n            int sz = o.ints.size();\n\n            if (sz > 0) {\n                ensureCapacity(o.ints.get(sz - 1));\n            }\n            for (int i = 0; i < o.ints.size(); i++) {\n                Bits.set(bits, o.ints.get(i), true);\n            }\n        } else {\n            IntIterator iter = other.iterator();\n            while (iter.hasNext()) {\n                add(iter.next());\n            }\n        }\n    }\n\n    /** @inheritDoc */\n    public int elements() {\n        return Bits.bitCount(bits);\n    }\n\n    /** @inheritDoc */\n    public IntIterator iterator() {\n        return new IntIterator() {\n            private int idx = Bits.findFirst(bits, 0);\n\n            /** @inheritDoc */\n            public boolean hasNext() {\n                return idx >= 0;\n            }\n\n            /** @inheritDoc */\n            public int next() {\n                if (!hasNext()) {\n                    throw new NoSuchElementException();\n                }\n\n                int ret = idx;\n\n                idx = Bits.findFirst(bits, idx + 1);\n\n                return ret;\n            }\n        };\n    }\n\n    /** @inheritDoc */\n    public String toString() {\n        StringBuilder sb = new StringBuilder();\n\n        sb.append('{');\n\n        boolean first = true;\n        for (int i = Bits.findFirst(bits, 0)\n                ; i >= 0\n                ; i = Bits.findFirst(bits, i + 1)) {\n            if (!first) {\n                sb.append(\", \");\n            }\n            first = false;\n            sb.append(i);\n        }\n\n        sb.append('}');\n\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/Bits.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\n/**\n * Utilities for treating {@code int[]}s as bit sets.\n */\npublic final class Bits {\n    /**\n     * This class is uninstantiable.\n     */\n    private Bits() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Constructs a bit set to contain bits up to the given index (exclusive).\n     *\n     * @param max {@code >= 0;} the maximum bit index (exclusive)\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public static int[] makeBitSet(int max) {\n        int size = (max + 0x1f) >> 5;\n        return new int[size];\n    }\n\n    /**\n     * Gets the maximum index (exclusive) for the given bit set.\n     *\n     * @param bits {@code non-null;} bit set in question\n     * @return {@code >= 0;} the maximum index (exclusive) that may be set\n     */\n    public static int getMax(int[] bits) {\n        return bits.length * 0x20;\n    }\n\n    /**\n     * Gets the value of the bit at the given index.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @param idx {@code >= 0, < getMax(set);} which bit\n     * @return the value of the indicated bit\n     */\n    public static boolean get(int[] bits, int idx) {\n        int arrayIdx = idx >> 5;\n        int bit = 1 << (idx & 0x1f);\n        return (bits[arrayIdx] & bit) != 0;\n    }\n\n    /**\n     * Sets the given bit to the given value.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @param idx {@code >= 0, < getMax(set);} which bit\n     * @param value the new value for the bit\n     */\n    public static void set(int[] bits, int idx, boolean value) {\n        int arrayIdx = idx >> 5;\n        int bit = 1 << (idx & 0x1f);\n\n        if (value) {\n            bits[arrayIdx] |= bit;\n        } else {\n            bits[arrayIdx] &= ~bit;\n        }\n    }\n\n    /**\n     * Sets the given bit to {@code true}.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @param idx {@code >= 0, < getMax(set);} which bit\n     */\n    public static void set(int[] bits, int idx) {\n        int arrayIdx = idx >> 5;\n        int bit = 1 << (idx & 0x1f);\n        bits[arrayIdx] |= bit;\n    }\n\n    /**\n     * Sets the given bit to {@code false}.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @param idx {@code >= 0, < getMax(set);} which bit\n     */\n    public static void clear(int[] bits, int idx) {\n        int arrayIdx = idx >> 5;\n        int bit = 1 << (idx & 0x1f);\n        bits[arrayIdx] &= ~bit;\n    }\n\n    /**\n     * Returns whether or not the given bit set is empty, that is, whether\n     * no bit is set to {@code true}.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @return {@code true} iff all bits are {@code false}\n     */\n    public static boolean isEmpty(int[] bits) {\n        int len = bits.length;\n\n        for (int i = 0; i < len; i++) {\n            if (bits[i] != 0) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Gets the number of bits set to {@code true} in the given bit set.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @return {@code >= 0;} the bit count (aka population count) of the set\n     */\n    public static int bitCount(int[] bits) {\n        int len = bits.length;\n        int count = 0;\n\n        for (int i = 0; i < len; i++) {\n            count += Integer.bitCount(bits[i]);\n        }\n\n        return count;\n    }\n\n    /**\n     * Returns whether any bits are set to {@code true} in the\n     * specified range.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @param start {@code >= 0;} index of the first bit in the range (inclusive)\n     * @param end {@code >= 0;} index of the last bit in the range (exclusive)\n     * @return {@code true} if any bit is set to {@code true} in\n     * the indicated range\n     */\n    public static boolean anyInRange(int[] bits, int start, int end) {\n        int idx = findFirst(bits, start);\n        return (idx >= 0) && (idx < end);\n    }\n\n    /**\n     * Finds the lowest-order bit set at or after the given index in the\n     * given bit set.\n     *\n     * @param bits {@code non-null;} bit set to operate on\n     * @param idx {@code >= 0;} minimum index to return\n     * @return {@code >= -1;} lowest-order bit set at or after {@code idx},\n     * or {@code -1} if there is no appropriate bit index to return\n     */\n    public static int findFirst(int[] bits, int idx) {\n        int len = bits.length;\n        int minBit = idx & 0x1f;\n\n        for (int arrayIdx = idx >> 5; arrayIdx < len; arrayIdx++) {\n            int word = bits[arrayIdx];\n            if (word != 0) {\n                int bitIdx = findFirst(word, minBit);\n                if (bitIdx >= 0) {\n                    return (arrayIdx << 5) + bitIdx;\n                }\n            }\n            minBit = 0;\n        }\n\n        return -1;\n    }\n\n    /**\n     * Finds the lowest-order bit set at or after the given index in the\n     * given {@code int}.\n     *\n     * @param value the value in question\n     * @param idx 0..31 the minimum bit index to return\n     * @return {@code >= -1;} lowest-order bit set at or after {@code idx},\n     * or {@code -1} if there is no appropriate bit index to return\n     */\n    public static int findFirst(int value, int idx) {\n        value &= ~((1 << idx) - 1); // Mask off too-low bits.\n        int result = Integer.numberOfTrailingZeros(value);\n        return (result == 32) ? -1 : result;\n    }\n\n    /**\n     * Ors bit array {@code b} into bit array {@code a}.\n     * {@code a.length} must be greater than or equal to\n     * {@code b.length}.\n     *\n     * @param a {@code non-null;} int array to be ored with other argument. This\n     * argument is modified.\n     * @param b {@code non-null;} int array to be ored into {@code a}. This\n     * argument is not modified.\n     */\n    public static void or(int[] a, int[] b) {\n        for (int i = 0; i < b.length; i++) {\n            a[i] |= b[i];\n        }\n    }\n\n    public static String toHuman(int[] bits) {\n        StringBuilder sb = new StringBuilder();\n\n        boolean needsComma = false;\n\n        sb.append('{');\n\n        int bitsLength = 32 * bits.length;\n        for (int i = 0; i < bitsLength; i++) {\n            if (Bits.get(bits, i)) {\n                if (needsComma) {\n                    sb.append(',');\n                }\n                needsComma = true;\n                sb.append(i);\n            }\n        }\n        sb.append('}');\n\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/ByteArray.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\nimport java.io.DataInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\n\n/**\n * Wrapper for a {@code byte[]}, which provides read-only access and\n * can \"reveal\" a partial slice of the underlying array.\n *\n * <b>Note:</b> Multibyte accessors all use big-endian order.\n */\npublic final class ByteArray {\n    /** {@code non-null;} underlying array */\n    private final byte[] bytes;\n\n    /** {@code >= 0}; start index of the slice (inclusive) */\n    private final int start;\n\n    /** {@code >= 0, <= bytes.length}; size computed as\n     * {@code end - start} (in the constructor) */\n    private final int size;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param bytes {@code non-null;} the underlying array\n     * @param start {@code >= 0;} start index of the slice (inclusive)\n     * @param end {@code >= start, <= bytes.length;} end index of\n     * the slice (exclusive)\n     */\n    public ByteArray(byte[] bytes, int start, int end) {\n        if (bytes == null) {\n            throw new NullPointerException(\"bytes == null\");\n        }\n\n        if (start < 0) {\n            throw new IllegalArgumentException(\"start < 0\");\n        }\n\n        if (end < start) {\n            throw new IllegalArgumentException(\"end < start\");\n        }\n\n        if (end > bytes.length) {\n            throw new IllegalArgumentException(\"end > bytes.length\");\n        }\n\n        this.bytes = bytes;\n        this.start = start;\n        this.size = end - start;\n    }\n\n    /**\n     * Constructs an instance from an entire {@code byte[]}.\n     *\n     * @param bytes {@code non-null;} the underlying array\n     */\n    public ByteArray(byte[] bytes) {\n        this(bytes, 0, bytes.length);\n    }\n\n    /**\n     * Gets the size of the array, in bytes.\n     *\n     * @return {@code >= 0;} the size\n     */\n    public int size() {\n        return size;\n    }\n\n    /**\n     * Returns a slice (that is, a sub-array) of this instance.\n     *\n     * @param start {@code >= 0;} start index of the slice (inclusive)\n     * @param end {@code >= start, <= size();} end index of\n     * the slice (exclusive)\n     * @return {@code non-null;} the slice\n     */\n    public ByteArray slice(int start, int end) {\n        checkOffsets(start, end);\n        return new ByteArray(bytes, start + this.start, end + this.start);\n    }\n\n    /**\n     * Returns the offset into the given array represented by the given\n     * offset into this instance.\n     *\n     * @param offset offset into this instance\n     * @param bytes {@code non-null;} (alleged) underlying array\n     * @return corresponding offset into {@code bytes}\n     * @throws IllegalArgumentException thrown if {@code bytes} is\n     * not the underlying array of this instance\n     */\n    public int underlyingOffset(int offset, byte[] bytes) {\n        if (bytes != this.bytes) {\n            throw new IllegalArgumentException(\"wrong bytes\");\n        }\n\n        return start + offset;\n    }\n\n    /**\n     * Gets the {@code signed byte} value at a particular offset.\n     *\n     * @param off {@code >= 0, < size();} offset to fetch\n     * @return {@code signed byte} at that offset\n     */\n    public int getByte(int off) {\n        checkOffsets(off, off + 1);\n        return getByte0(off);\n    }\n\n    /**\n     * Gets the {@code signed short} value at a particular offset.\n     *\n     * @param off {@code >= 0, < (size() - 1);} offset to fetch\n     * @return {@code signed short} at that offset\n     */\n    public int getShort(int off) {\n        checkOffsets(off, off + 2);\n        return (getByte0(off) << 8) | getUnsignedByte0(off + 1);\n    }\n\n    /**\n     * Gets the {@code signed int} value at a particular offset.\n     *\n     * @param off {@code >= 0, < (size() - 3);} offset to fetch\n     * @return {@code signed int} at that offset\n     */\n    public int getInt(int off) {\n        checkOffsets(off, off + 4);\n        return (getByte0(off) << 24) |\n            (getUnsignedByte0(off + 1) << 16) |\n            (getUnsignedByte0(off + 2) << 8) |\n            getUnsignedByte0(off + 3);\n    }\n\n    /**\n     * Gets the {@code signed long} value at a particular offset.\n     *\n     * @param off {@code >= 0, < (size() - 7);} offset to fetch\n     * @return {@code signed int} at that offset\n     */\n    public long getLong(int off) {\n        checkOffsets(off, off + 8);\n        int part1 = (getByte0(off) << 24) |\n            (getUnsignedByte0(off + 1) << 16) |\n            (getUnsignedByte0(off + 2) << 8) |\n            getUnsignedByte0(off + 3);\n        int part2 = (getByte0(off + 4) << 24) |\n            (getUnsignedByte0(off + 5) << 16) |\n            (getUnsignedByte0(off + 6) << 8) |\n            getUnsignedByte0(off + 7);\n\n        return (part2 & 0xffffffffL) | ((long) part1) << 32;\n    }\n\n    /**\n     * Gets the {@code unsigned byte} value at a particular offset.\n     *\n     * @param off {@code >= 0, < size();} offset to fetch\n     * @return {@code unsigned byte} at that offset\n     */\n    public int getUnsignedByte(int off) {\n        checkOffsets(off, off + 1);\n        return getUnsignedByte0(off);\n    }\n\n    /**\n     * Gets the {@code unsigned short} value at a particular offset.\n     *\n     * @param off {@code >= 0, < (size() - 1);} offset to fetch\n     * @return {@code unsigned short} at that offset\n     */\n    public int getUnsignedShort(int off) {\n        checkOffsets(off, off + 2);\n        return (getUnsignedByte0(off) << 8) | getUnsignedByte0(off + 1);\n    }\n\n    /**\n     * Copies the contents of this instance into the given raw\n     * {@code byte[]} at the given offset. The given array must be\n     * large enough.\n     *\n     * @param out {@code non-null;} array to hold the output\n     * @param offset {@code non-null;} index into {@code out} for the first\n     * byte of output\n     */\n    public void getBytes(byte[] out, int offset) {\n        if ((out.length - offset) < size) {\n            throw new IndexOutOfBoundsException(\"(out.length - offset) < \" +\n                                                \"size()\");\n        }\n\n        System.arraycopy(bytes, start, out, offset, size);\n    }\n\n    /**\n     * Checks a range of offsets for validity, throwing if invalid.\n     *\n     * @param s start offset (inclusive)\n     * @param e end offset (exclusive)\n     */\n    private void checkOffsets(int s, int e) {\n        if ((s < 0) || (e < s) || (e > size)) {\n            throw new IllegalArgumentException(\"bad range: \" + s + \"..\" + e +\n                                               \"; actual size \" + size);\n        }\n    }\n\n    /**\n     * Gets the {@code signed byte} value at the given offset,\n     * without doing any argument checking.\n     *\n     * @param off offset to fetch\n     * @return byte at that offset\n     */\n    private int getByte0(int off) {\n        return bytes[start + off];\n    }\n\n    /**\n     * Gets the {@code unsigned byte} value at the given offset,\n     * without doing any argument checking.\n     *\n     * @param off offset to fetch\n     * @return byte at that offset\n     */\n    private int getUnsignedByte0(int off) {\n        return bytes[start + off] & 0xff;\n    }\n\n    /**\n     * Gets a {@code DataInputStream} that reads from this instance,\n     * with the cursor starting at the beginning of this instance's data.\n     * <b>Note:</b> The returned instance may be cast to {@link #GetCursor}\n     * if needed.\n     *\n     * @return {@code non-null;} an appropriately-constructed\n     * {@code DataInputStream} instance\n     */\n    public MyDataInputStream makeDataInputStream() {\n        return new MyDataInputStream(makeInputStream());\n    }\n\n    /**\n     * Gets a {@code InputStream} that reads from this instance,\n     * with the cursor starting at the beginning of this instance's data.\n     * <b>Note:</b> The returned instance may be cast to {@link #GetCursor}\n     * if needed.\n     *\n     * @return {@code non-null;} an appropriately-constructed\n     * {@code InputStream} instancex\n     */\n    public MyInputStream makeInputStream() {\n        return new MyInputStream();\n    }\n\n    /**\n     * Helper interface that allows one to get the cursor (of a stream).\n     */\n    public interface GetCursor {\n        /**\n         * Gets the current cursor.\n         *\n         * @return {@code 0..size();} the cursor\n         */\n        public int getCursor();\n    }\n\n    /**\n     * Helper class for {@link #makeInputStream}, which implements the\n     * stream functionality.\n     */\n    public class MyInputStream extends InputStream {\n        /** 0..size; the cursor */\n        private int cursor;\n\n        /** 0..size; the mark */\n        private int mark;\n\n        public MyInputStream() {\n            cursor = 0;\n            mark = 0;\n        }\n\n        public int read() throws IOException {\n            if (cursor >= size) {\n                return -1;\n            }\n\n            int result = getUnsignedByte0(cursor);\n            cursor++;\n            return result;\n        }\n\n        public int read(byte[] arr, int offset, int length) {\n            if ((offset + length) > arr.length) {\n                length = arr.length - offset;\n            }\n\n            int maxLength = size - cursor;\n            if (length > maxLength) {\n                length = maxLength;\n            }\n\n            System.arraycopy(bytes, cursor + start, arr, offset, length);\n            cursor += length;\n            return length;\n        }\n\n        public int available() {\n            return size - cursor;\n        }\n\n        public void mark(int reserve) {\n            mark = cursor;\n        }\n\n        public void reset() {\n            cursor = mark;\n        }\n\n        public boolean markSupported() {\n            return true;\n        }\n    }\n\n    /**\n     * Helper class for {@link #makeDataInputStream}. This is used\n     * simply so that the cursor of a wrapped {@link #MyInputStream}\n     * instance may be easily determined.\n     */\n    public static class MyDataInputStream extends DataInputStream {\n        /** {@code non-null;} the underlying {@link #MyInputStream} */\n        private final MyInputStream wrapped;\n\n        public MyDataInputStream(MyInputStream wrapped) {\n            super(wrapped);\n\n            this.wrapped = wrapped;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/ByteArrayAnnotatedOutput.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\nimport java.io.IOException;\nimport java.io.Writer;\nimport java.util.ArrayList;\n\nimport com.taobao.atlas.dex.Leb128;\nimport com.taobao.atlas.dex.util.ByteOutput;\nimport com.taobao.atlas.dex.util.ExceptionWithContext;\n\n/**\n * Implementation of {@link AnnotatedOutput} which stores the written data\n * into a {@code byte[]}.\n *\n * <p><b>Note:</b> As per the {@link Output} interface, multi-byte\n * writes all use little-endian order.</p>\n */\npublic final class ByteArrayAnnotatedOutput\n        implements AnnotatedOutput, ByteOutput {\n    /** default size for stretchy instances */\n    private static final int DEFAULT_SIZE = 1000;\n\n    /**\n     * whether the instance is stretchy, that is, whether its array\n     * may be resized to increase capacity\n     */\n    private final boolean stretchy;\n\n    /** {@code non-null;} the data itself */\n    private byte[] data;\n\n    /** {@code >= 0;} current output cursor */\n    private int cursor;\n\n    /** whether annotations are to be verbose */\n    private boolean verbose;\n\n    /**\n     * {@code null-ok;} list of annotations, or {@code null} if this instance\n     * isn't keeping them\n     */\n    private ArrayList<Annotation> annotations;\n\n    /** {@code >= 40 (if used);} the desired maximum annotation width */\n    private int annotationWidth;\n\n    /**\n     * {@code >= 8 (if used);} the number of bytes of hex output to use\n     * in annotations\n     */\n    private int hexCols;\n\n    /**\n     * Constructs an instance with a fixed maximum size. Note that the\n     * given array is the only one that will be used to store data. In\n     * particular, no reallocation will occur in order to expand the\n     * capacity of the resulting instance. Also, the constructed\n     * instance does not keep annotations by default.\n     *\n     * @param data {@code non-null;} data array to use for output\n     */\n    public ByteArrayAnnotatedOutput(byte[] data) {\n        this(data, false);\n    }\n\n    /**\n     * Constructs a \"stretchy\" instance. The underlying array may be\n     * reallocated. The constructed instance does not keep annotations\n     * by default.\n     */\n    public ByteArrayAnnotatedOutput() {\n        this(DEFAULT_SIZE);\n    }\n\n    /**\n     * Constructs a \"stretchy\" instance with initial size {@code size}. The\n     * underlying array may be reallocated. The constructed instance does not\n     * keep annotations by default.\n     */\n    public ByteArrayAnnotatedOutput(int size) {\n        this(new byte[size], true);\n    }\n\n    /**\n     * Internal constructor.\n     *\n     * @param data {@code non-null;} data array to use for output\n     * @param stretchy whether the instance is to be stretchy\n     */\n    private ByteArrayAnnotatedOutput(byte[] data, boolean stretchy) {\n        if (data == null) {\n            throw new NullPointerException(\"data == null\");\n        }\n\n        this.stretchy = stretchy;\n        this.data = data;\n        this.cursor = 0;\n        this.verbose = false;\n        this.annotations = null;\n        this.annotationWidth = 0;\n        this.hexCols = 0;\n    }\n\n    /**\n     * Gets the underlying {@code byte[]} of this instance, which\n     * may be larger than the number of bytes written\n     *\n     * @see #toByteArray\n     *\n     * @return {@code non-null;} the {@code byte[]}\n     */\n    public byte[] getArray() {\n        return data;\n    }\n\n    /**\n     * Constructs and returns a new {@code byte[]} that contains\n     * the written contents exactly (that is, with no extra unwritten\n     * bytes at the end).\n     *\n     * @see #getArray\n     *\n     * @return {@code non-null;} an appropriately-constructed array\n     */\n    public byte[] toByteArray() {\n        byte[] result = new byte[cursor];\n        System.arraycopy(data, 0, result, 0, cursor);\n        return result;\n    }\n\n    /** {@inheritDoc} */\n    public int getCursor() {\n        return cursor;\n    }\n\n    /** {@inheritDoc} */\n    public void assertCursor(int expectedCursor) {\n        if (cursor != expectedCursor) {\n            throw new ExceptionWithContext(\"expected cursor \" +\n                    expectedCursor + \"; actual value: \" + cursor);\n        }\n    }\n\n    /** {@inheritDoc} */\n    public void writeByte(int value) {\n        int writeAt = cursor;\n        int end = writeAt + 1;\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        data[writeAt] = (byte) value;\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public void writeShort(int value) {\n        int writeAt = cursor;\n        int end = writeAt + 2;\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        data[writeAt] = (byte) value;\n        data[writeAt + 1] = (byte) (value >> 8);\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public void writeInt(int value) {\n        int writeAt = cursor;\n        int end = writeAt + 4;\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        data[writeAt] = (byte) value;\n        data[writeAt + 1] = (byte) (value >> 8);\n        data[writeAt + 2] = (byte) (value >> 16);\n        data[writeAt + 3] = (byte) (value >> 24);\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public void writeLong(long value) {\n        int writeAt = cursor;\n        int end = writeAt + 8;\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        int half = (int) value;\n        data[writeAt] = (byte) half;\n        data[writeAt + 1] = (byte) (half >> 8);\n        data[writeAt + 2] = (byte) (half >> 16);\n        data[writeAt + 3] = (byte) (half >> 24);\n\n        half = (int) (value >> 32);\n        data[writeAt + 4] = (byte) half;\n        data[writeAt + 5] = (byte) (half >> 8);\n        data[writeAt + 6] = (byte) (half >> 16);\n        data[writeAt + 7] = (byte) (half >> 24);\n\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public int writeUleb128(int value) {\n        if (stretchy) {\n            ensureCapacity(cursor + 5); // pessimistic\n        }\n        int cursorBefore = cursor;\n        Leb128.writeUnsignedLeb128(this, value);\n        return (cursor - cursorBefore);\n    }\n\n    /** {@inheritDoc} */\n    public int writeSleb128(int value) {\n        if (stretchy) {\n            ensureCapacity(cursor + 5); // pessimistic\n        }\n        int cursorBefore = cursor;\n        Leb128.writeSignedLeb128(this, value);\n        return (cursor - cursorBefore);\n    }\n\n    /** {@inheritDoc} */\n    public void write(ByteArray bytes) {\n        int blen = bytes.size();\n        int writeAt = cursor;\n        int end = writeAt + blen;\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        bytes.getBytes(data, writeAt);\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public void write(byte[] bytes, int offset, int length) {\n        int writeAt = cursor;\n        int end = writeAt + length;\n        int bytesEnd = offset + length;\n\n        // twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0)\n        if (((offset | length | end) < 0) || (bytesEnd > bytes.length)) {\n            throw new IndexOutOfBoundsException(\"bytes.length \" +\n                                                bytes.length + \"; \" +\n                                                offset + \"..!\" + end);\n        }\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        System.arraycopy(bytes, offset, data, writeAt, length);\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public void write(byte[] bytes) {\n        write(bytes, 0, bytes.length);\n    }\n\n    /** {@inheritDoc} */\n    public void writeZeroes(int count) {\n        if (count < 0) {\n            throw new IllegalArgumentException(\"count < 0\");\n        }\n\n        int end = cursor + count;\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        /*\n         * There is no need to actually write zeroes, since the array is\n         * already preinitialized with zeroes.\n         */\n\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public void alignTo(int alignment) {\n        int mask = alignment - 1;\n\n        if ((alignment < 0) || ((mask & alignment) != 0)) {\n            throw new IllegalArgumentException(\"bogus alignment\");\n        }\n\n        int end = (cursor + mask) & ~mask;\n\n        if (stretchy) {\n            ensureCapacity(end);\n        } else if (end > data.length) {\n            throwBounds();\n            return;\n        }\n\n        /*\n         * There is no need to actually write zeroes, since the array is\n         * already preinitialized with zeroes.\n         */\n\n        cursor = end;\n    }\n\n    /** {@inheritDoc} */\n    public boolean annotates() {\n        return (annotations != null);\n    }\n\n    /** {@inheritDoc} */\n    public boolean isVerbose() {\n        return verbose;\n    }\n\n    /** {@inheritDoc} */\n    public void annotate(String msg) {\n        if (annotations == null) {\n            return;\n        }\n\n        endAnnotation();\n        annotations.add(new Annotation(cursor, msg));\n    }\n\n    /** {@inheritDoc} */\n    public void annotate(int amt, String msg) {\n        if (annotations == null) {\n            return;\n        }\n\n        endAnnotation();\n\n        int asz = annotations.size();\n        int lastEnd = (asz == 0) ? 0 : annotations.get(asz - 1).getEnd();\n        int startAt;\n\n        if (lastEnd <= cursor) {\n            startAt = cursor;\n        } else {\n            startAt = lastEnd;\n        }\n\n        annotations.add(new Annotation(startAt, startAt + amt, msg));\n    }\n\n    /** {@inheritDoc} */\n    public void endAnnotation() {\n        if (annotations == null) {\n            return;\n        }\n\n        int sz = annotations.size();\n\n        if (sz != 0) {\n            annotations.get(sz - 1).setEndIfUnset(cursor);\n        }\n    }\n\n    /** {@inheritDoc} */\n    public int getAnnotationWidth() {\n        int leftWidth = 8 + (hexCols * 2) + (hexCols / 2);\n\n        return annotationWidth - leftWidth;\n    }\n\n    /**\n     * Indicates that this instance should keep annotations. This method may\n     * be called only once per instance, and only before any data has been\n     * written to the it.\n     *\n     * @param annotationWidth {@code >= 40;} the desired maximum annotation width\n     * @param verbose whether or not to indicate verbose annotations\n     */\n    public void enableAnnotations(int annotationWidth, boolean verbose) {\n        if ((annotations != null) || (cursor != 0)) {\n            throw new RuntimeException(\"cannot enable annotations\");\n        }\n\n        if (annotationWidth < 40) {\n            throw new IllegalArgumentException(\"annotationWidth < 40\");\n        }\n\n        int hexCols = (((annotationWidth - 7) / 15) + 1) & ~1;\n        if (hexCols < 6) {\n            hexCols = 6;\n        } else if (hexCols > 10) {\n            hexCols = 10;\n        }\n\n        this.annotations = new ArrayList<Annotation>(1000);\n        this.annotationWidth = annotationWidth;\n        this.hexCols = hexCols;\n        this.verbose = verbose;\n    }\n\n    /**\n     * Finishes up annotation processing. This closes off any open\n     * annotations and removes annotations that don't refer to written\n     * data.\n     */\n    public void finishAnnotating() {\n        // Close off the final annotation, if any.\n        endAnnotation();\n\n        // Remove annotations that refer to unwritten data.\n        if (annotations != null) {\n            int asz = annotations.size();\n            while (asz > 0) {\n                Annotation last = annotations.get(asz - 1);\n                if (last.getStart() > cursor) {\n                    annotations.remove(asz - 1);\n                    asz--;\n                } else if (last.getEnd() > cursor) {\n                    last.setEnd(cursor);\n                    break;\n                } else {\n                    break;\n                }\n            }\n        }\n    }\n\n    /**\n     * Writes the annotated content of this instance to the given writer.\n     *\n     * @param out {@code non-null;} where to write to\n     */\n    public void writeAnnotationsTo(Writer out) throws IOException {\n        int width2 = getAnnotationWidth();\n        int width1 = annotationWidth - width2 - 1;\n\n        TwoColumnOutput twoc = new TwoColumnOutput(out, width1, width2, \"|\");\n        Writer left = twoc.getLeft();\n        Writer right = twoc.getRight();\n        int leftAt = 0; // left-hand byte output cursor\n        int rightAt = 0; // right-hand annotation index\n        int rightSz = annotations.size();\n\n        while ((leftAt < cursor) && (rightAt < rightSz)) {\n            Annotation a = annotations.get(rightAt);\n            int start = a.getStart();\n            int end;\n            String text;\n\n            if (leftAt < start) {\n                // This is an area with no annotation.\n                end = start;\n                start = leftAt;\n                text = \"\";\n            } else {\n                // This is an area with an annotation.\n                end = a.getEnd();\n                text = a.getText();\n                rightAt++;\n            }\n\n            left.write(Hex.dump(data, start, end - start, start, hexCols, 6));\n            right.write(text);\n            twoc.flush();\n            leftAt = end;\n        }\n\n        if (leftAt < cursor) {\n            // There is unannotated output at the end.\n            left.write(Hex.dump(data, leftAt, cursor - leftAt, leftAt,\n                    hexCols, 6));\n        }\n\n        while (rightAt < rightSz) {\n            // There are zero-byte annotations at the end.\n            right.write(annotations.get(rightAt).getText());\n            rightAt++;\n        }\n\n        twoc.flush();\n    }\n\n    /**\n     * Throws the excpetion for when an attempt is made to write past the\n     * end of the instance.\n     */\n    private static void throwBounds() {\n        throw new IndexOutOfBoundsException(\"attempt to write past the end\");\n    }\n\n    /**\n     * Reallocates the underlying array if necessary. Calls to this method\n     * should be guarded by a test of {@link #stretchy}.\n     *\n     * @param desiredSize {@code >= 0;} the desired minimum total size of the array\n     */\n    private void ensureCapacity(int desiredSize) {\n        if (data.length < desiredSize) {\n            byte[] newData = new byte[desiredSize * 2 + 1000];\n            System.arraycopy(data, 0, newData, 0, cursor);\n            data = newData;\n        }\n    }\n\n    /**\n     * Annotation on output.\n     */\n    private static class Annotation {\n        /** {@code >= 0;} start of annotated range (inclusive) */\n        private final int start;\n\n        /**\n         * {@code >= 0;} end of annotated range (exclusive);\n         * {@code Integer.MAX_VALUE} if unclosed\n         */\n        private int end;\n\n        /** {@code non-null;} annotation text */\n        private final String text;\n\n        /**\n         * Constructs an instance.\n         *\n         * @param start {@code >= 0;} start of annotated range\n         * @param end {@code >= start;} end of annotated range (exclusive) or\n         * {@code Integer.MAX_VALUE} if unclosed\n         * @param text {@code non-null;} annotation text\n         */\n        public Annotation(int start, int end, String text) {\n            this.start = start;\n            this.end = end;\n            this.text = text;\n        }\n\n        /**\n         * Constructs an instance. It is initally unclosed.\n         *\n         * @param start {@code >= 0;} start of annotated range\n         * @param text {@code non-null;} annotation text\n         */\n        public Annotation(int start, String text) {\n            this(start, Integer.MAX_VALUE, text);\n        }\n\n        /**\n         * Sets the end as given, but only if the instance is unclosed;\n         * otherwise, do nothing.\n         *\n         * @param end {@code >= start;} the end\n         */\n        public void setEndIfUnset(int end) {\n            if (this.end == Integer.MAX_VALUE) {\n                this.end = end;\n            }\n        }\n\n        /**\n         * Sets the end as given.\n         *\n         * @param end {@code >= start;} the end\n         */\n        public void setEnd(int end) {\n            this.end = end;\n        }\n\n        /**\n         * Gets the start.\n         *\n         * @return the start\n         */\n        public int getStart() {\n            return start;\n        }\n\n        /**\n         * Gets the end.\n         *\n         * @return the end\n         */\n        public int getEnd() {\n            return end;\n        }\n\n        /**\n         * Gets the text.\n         *\n         * @return {@code non-null;} the text\n         */\n        public String getText() {\n            return text;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/FixedSizeList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\nimport java.util.Arrays;\n\n/**\n * Simple (mostly) fixed-size list of objects, which may be made immutable.\n */\npublic class FixedSizeList\n        extends MutabilityControl implements ToHuman {\n    /** {@code non-null;} array of elements */\n    private Object[] arr;\n\n    /**\n     * Constructs an instance. All indices initially contain {@code null}.\n     *\n     * @param size the size of the list\n     */\n    public FixedSizeList(int size) {\n        super(size != 0);\n\n        try {\n            arr = new Object[size];\n        } catch (NegativeArraySizeException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"size < 0\");\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (this == other) {\n            // Easy out.\n            return true;\n        }\n\n        if ((other == null) || (getClass() != other.getClass())) {\n            // Another easy out.\n            return false;\n        }\n\n        FixedSizeList list = (FixedSizeList) other;\n        return Arrays.equals(arr, list.arr);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        return Arrays.hashCode(arr);\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        String name = getClass().getName();\n\n        return toString0(name.substring(name.lastIndexOf('.') + 1) + '{',\n                         \", \",\n                         \"}\",\n                         false);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * This method will only work if every element of the list\n     * implements {@link ToHuman}.\n     */\n    public String toHuman() {\n        String name = getClass().getName();\n\n        return toString0(name.substring(name.lastIndexOf('.') + 1) + '{',\n                         \", \",\n                         \"}\",\n                         true);\n    }\n\n    /**\n     * Gets a customized string form for this instance.\n     *\n     * @param prefix {@code null-ok;} prefix for the start of the result\n     * @param separator {@code null-ok;} separator to insert between each item\n     * @param suffix {@code null-ok;} suffix for the end of the result\n     * @return {@code non-null;} the custom string\n     */\n    public String toString(String prefix, String separator, String suffix) {\n        return toString0(prefix, separator, suffix, false);\n    }\n\n    /**\n     * Gets a customized human string for this instance. This method will\n     * only work if every element of the list implements {@link\n     * ToHuman}.\n     *\n     * @param prefix {@code null-ok;} prefix for the start of the result\n     * @param separator {@code null-ok;} separator to insert between each item\n     * @param suffix {@code null-ok;} suffix for the end of the result\n     * @return {@code non-null;} the custom string\n     */\n    public String toHuman(String prefix, String separator, String suffix) {\n        return toString0(prefix, separator, suffix, true);\n    }\n\n    /**\n     * Gets the number of elements in this list.\n     */\n    public final int size() {\n        return arr.length;\n    }\n\n    /**\n     * Shrinks this instance to fit, by removing any unset\n     * ({@code null}) elements, leaving the remaining elements in\n     * their original order.\n     */\n    public void shrinkToFit() {\n        int sz = arr.length;\n        int newSz = 0;\n\n        for (int i = 0; i < sz; i++) {\n            if (arr[i] != null) {\n                newSz++;\n            }\n        }\n\n        if (sz == newSz) {\n            return;\n        }\n\n        throwIfImmutable();\n\n        Object[] newa = new Object[newSz];\n        int at = 0;\n\n        for (int i = 0; i < sz; i++) {\n            Object one = arr[i];\n            if (one != null) {\n                newa[at] = one;\n                at++;\n            }\n        }\n\n        arr = newa;\n        if (newSz == 0) {\n            setImmutable();\n        }\n    }\n\n    /**\n     * Gets the indicated element. It is an error to call this with the\n     * index for an element which was never set; if you do that, this\n     * will throw {@code NullPointerException}. This method is\n     * protected so that subclasses may offer a safe type-checked\n     * public interface to their clients.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @return {@code non-null;} the indicated element\n     */\n    protected final Object get0(int n) {\n        try {\n            Object result = arr[n];\n\n            if (result == null) {\n                throw new NullPointerException(\"unset: \" + n);\n            }\n\n            return result;\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            return throwIndex(n);\n        }\n    }\n\n    /**\n     * Gets the indicated element, allowing {@code null}s to be\n     * returned. This method is protected so that subclasses may\n     * (optionally) offer a safe type-checked public interface to\n     * their clients.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @return {@code null-ok;} the indicated element\n     */\n    protected final Object getOrNull0(int n) {\n        return arr[n];\n    }\n\n    /**\n     * Sets the element at the given index, but without doing any type\n     * checks on the element. This method is protected so that\n     * subclasses may offer a safe type-checked public interface to\n     * their clients.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @param obj {@code null-ok;} the value to store\n     */\n    protected final void set0(int n, Object obj) {\n        throwIfImmutable();\n\n        try {\n            arr[n] = obj;\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            throwIndex(n);\n        }\n    }\n\n    /**\n     * Throws the appropriate exception for the given index value.\n     *\n     * @param n the index value\n     * @return never\n     * @throws IndexOutOfBoundsException always thrown\n     */\n    private Object throwIndex(int n) {\n        if (n < 0) {\n            throw new IndexOutOfBoundsException(\"n < 0\");\n        }\n\n        throw new IndexOutOfBoundsException(\"n >= size()\");\n    }\n\n    /**\n     * Helper for {@link #toString} and {@link #toHuman}, which both of\n     * those call to pretty much do everything.\n     *\n     * @param prefix {@code null-ok;} prefix for the start of the result\n     * @param separator {@code null-ok;} separator to insert between each item\n     * @param suffix {@code null-ok;} suffix for the end of the result\n     * @param human whether the output is to be human\n     * @return {@code non-null;} the custom string\n     */\n    private String toString0(String prefix, String separator, String suffix,\n                             boolean human) {\n        int len = arr.length;\n        StringBuffer sb = new StringBuffer(len * 10 + 10);\n\n        if (prefix != null) {\n            sb.append(prefix);\n        }\n\n        for (int i = 0; i < len; i++) {\n            if ((i != 0) && (separator != null)) {\n                sb.append(separator);\n            }\n\n            if (human) {\n                sb.append(((ToHuman) arr[i]).toHuman());\n            } else {\n                sb.append(arr[i]);\n            }\n        }\n\n        if (suffix != null) {\n            sb.append(suffix);\n        }\n\n        return sb.toString();\n    }\n\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/Hex.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\n/**\n * Utilities for formatting numbers as hexadecimal.\n */\npublic final class Hex {\n    /**\n     * This class is uninstantiable.\n     */\n    private Hex() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Formats a {@code long} as an 8-byte unsigned hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String u8(long v) {\n        char[] result = new char[16];\n        for (int i = 0; i < 16; i++) {\n            result[15 - i] = Character.forDigit((int) v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as a 4-byte unsigned hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String u4(int v) {\n        char[] result = new char[8];\n        for (int i = 0; i < 8; i++) {\n            result[7 - i] = Character.forDigit(v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as a 3-byte unsigned hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String u3(int v) {\n        char[] result = new char[6];\n        for (int i = 0; i < 6; i++) {\n            result[5 - i] = Character.forDigit(v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as a 2-byte unsigned hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String u2(int v) {\n        char[] result = new char[4];\n        for (int i = 0; i < 4; i++) {\n            result[3 - i] = Character.forDigit(v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as either a 2-byte unsigned hex value\n     * (if the value is small enough) or a 4-byte unsigned hex value (if\n     * not).\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String u2or4(int v) {\n        if (v == (char) v) {\n            return u2(v);\n        } else {\n            return u4(v);\n        }\n    }\n\n    /**\n     * Formats an {@code int} as a 1-byte unsigned hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String u1(int v) {\n        char[] result = new char[2];\n        for (int i = 0; i < 2; i++) {\n            result[1 - i] = Character.forDigit(v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as a 4-bit unsigned hex nibble.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String uNibble(int v) {\n        char[] result = new char[1];\n\n        result[0] = Character.forDigit(v & 0x0f, 16);\n        return new String(result);\n    }\n\n    /**\n     * Formats a {@code long} as an 8-byte signed hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String s8(long v) {\n        char[] result = new char[17];\n\n        if (v < 0) {\n            result[0] = '-';\n            v = -v;\n        } else {\n            result[0] = '+';\n        }\n\n        for (int i = 0; i < 16; i++) {\n            result[16 - i] = Character.forDigit((int) v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as a 4-byte signed hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String s4(int v) {\n        char[] result = new char[9];\n\n        if (v < 0) {\n            result[0] = '-';\n            v = -v;\n        } else {\n            result[0] = '+';\n        }\n\n        for (int i = 0; i < 8; i++) {\n            result[8 - i] = Character.forDigit(v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as a 2-byte signed hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String s2(int v) {\n        char[] result = new char[5];\n\n        if (v < 0) {\n            result[0] = '-';\n            v = -v;\n        } else {\n            result[0] = '+';\n        }\n\n        for (int i = 0; i < 4; i++) {\n            result[4 - i] = Character.forDigit(v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats an {@code int} as a 1-byte signed hex value.\n     *\n     * @param v value to format\n     * @return {@code non-null;} formatted form\n     */\n    public static String s1(int v) {\n        char[] result = new char[3];\n\n        if (v < 0) {\n            result[0] = '-';\n            v = -v;\n        } else {\n            result[0] = '+';\n        }\n\n        for (int i = 0; i < 2; i++) {\n            result[2 - i] = Character.forDigit(v & 0x0f, 16);\n            v >>= 4;\n        }\n\n        return new String(result);\n    }\n\n    /**\n     * Formats a hex dump of a portion of a {@code byte[]}. The result\n     * is always newline-terminated, unless the passed-in length was zero,\n     * in which case the result is always the empty string ({@code \"\"}).\n     *\n     * @param arr {@code non-null;} array to format\n     * @param offset {@code >= 0;} offset to the part to dump\n     * @param length {@code >= 0;} number of bytes to dump\n     * @param outOffset {@code >= 0;} first output offset to print\n     * @param bpl {@code >= 0;} number of bytes of output per line\n     * @param addressLength {@code {2,4,6,8};} number of characters for each address\n     * header\n     * @return {@code non-null;} a string of the dump\n     */\n    public static String dump(byte[] arr, int offset, int length,\n                              int outOffset, int bpl, int addressLength) {\n        int end = offset + length;\n\n        // twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0)\n        if (((offset | length | end) < 0) || (end > arr.length)) {\n            throw new IndexOutOfBoundsException(\"arr.length \" +\n                                                arr.length + \"; \" +\n                                                offset + \"..!\" + end);\n        }\n\n        if (outOffset < 0) {\n            throw new IllegalArgumentException(\"outOffset < 0\");\n        }\n\n        if (length == 0) {\n            return \"\";\n        }\n\n        StringBuffer sb = new StringBuffer(length * 4 + 6);\n        boolean bol = true;\n        int col = 0;\n\n        while (length > 0) {\n            if (col == 0) {\n                String astr;\n                switch (addressLength) {\n                    case 2:  astr = Hex.u1(outOffset); break;\n                    case 4:  astr = Hex.u2(outOffset); break;\n                    case 6:  astr = Hex.u3(outOffset); break;\n                    default: astr = Hex.u4(outOffset); break;\n                }\n                sb.append(astr);\n                sb.append(\": \");\n            } else if ((col & 1) == 0) {\n                sb.append(' ');\n            }\n            sb.append(Hex.u1(arr[offset]));\n            outOffset++;\n            offset++;\n            col++;\n            if (col == bpl) {\n                sb.append('\\n');\n                col = 0;\n            }\n            length--;\n        }\n\n        if (col != 0) {\n            sb.append('\\n');\n        }\n\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/HexParser.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\n/**\n * Utilities for parsing hexadecimal text.\n */\npublic final class HexParser {\n    /**\n     * This class is uninstantiable.\n     */\n    private HexParser() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Parses the given text as hex, returning a {@code byte[]}\n     * corresponding to the text. The format is simple: Each line may\n     * start with a hex offset followed by a colon (which is verified\n     * and presumably used just as a comment), and then consists of\n     * hex digits freely interspersed with whitespace. If a pound sign\n     * is encountered, it and the rest of the line are ignored as a\n     * comment. If a double quote is encountered, then the ASCII value\n     * of the subsequent characters is used, until the next double\n     * quote. Quoted strings may not span multiple lines.\n     *\n     * @param src {@code non-null;} the source string\n     * @return {@code non-null;} the parsed form\n     */\n    public static byte[] parse(String src) {\n        int len = src.length();\n        byte[] result = new byte[len / 2];\n        int at = 0;\n        int outAt = 0;\n\n        while (at < len) {\n            int nlAt = src.indexOf('\\n', at);\n            if (nlAt < 0) {\n                nlAt = len;\n            }\n            int poundAt = src.indexOf('#', at);\n\n            String line;\n            if ((poundAt >= 0) && (poundAt < nlAt)) {\n                line = src.substring(at, poundAt);\n            } else {\n                line = src.substring(at, nlAt);\n            }\n            at = nlAt + 1;\n\n            int colonAt = line.indexOf(':');\n\n            atCheck:\n            if (colonAt != -1) {\n                int quoteAt = line.indexOf('\\\"');\n                if ((quoteAt != -1) && (quoteAt < colonAt)) {\n                    break atCheck;\n                }\n\n                String atStr = line.substring(0, colonAt).trim();\n                line = line.substring(colonAt + 1);\n                int alleged = Integer.parseInt(atStr, 16);\n                if (alleged != outAt) {\n                    throw new RuntimeException(\"bogus offset marker: \" +\n                                               atStr);\n                }\n            }\n\n            int lineLen = line.length();\n            int value = -1;\n            boolean quoteMode = false;\n\n            for (int i = 0; i < lineLen; i++) {\n                char c = line.charAt(i);\n\n                if (quoteMode) {\n                    if (c == '\\\"') {\n                        quoteMode = false;\n                    } else {\n                        result[outAt] = (byte) c;\n                        outAt++;\n                    }\n                    continue;\n                }\n\n                if (c <= ' ') {\n                    continue;\n                }\n                if (c == '\\\"') {\n                    if (value != -1) {\n                        throw new RuntimeException(\"spare digit around \" +\n                                                   \"offset \" + Hex.u4(outAt));\n                    }\n                    quoteMode = true;\n                    continue;\n                }\n\n                int digVal = Character.digit(c, 16);\n                if (digVal == -1) {\n                    throw new RuntimeException(\"bogus digit character: \\\"\" +\n                                               c + \"\\\"\");\n                }\n                if (value == -1) {\n                    value = digVal;\n                } else {\n                    result[outAt] = (byte) ((value << 4) | digVal);\n                    outAt++;\n                    value = -1;\n                }\n            }\n\n            if (value != -1) {\n                throw new RuntimeException(\"spare digit around offset \" +\n                                           Hex.u4(outAt));\n            }\n\n            if (quoteMode) {\n                throw new RuntimeException(\"unterminated quote around \" +\n                                           \"offset \" + Hex.u4(outAt));\n            }\n        }\n\n        if (outAt < result.length) {\n            byte[] newr = new byte[outAt];\n            System.arraycopy(result, 0, newr, 0, outAt);\n            result = newr;\n        }\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/IndentingWriter.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\nimport java.io.FilterWriter;\nimport java.io.IOException;\nimport java.io.Writer;\n\n/**\n * Writer that wraps another writer and passes width-limited and\n * optionally-prefixed output to its subordinate. When lines are\n * wrapped they are automatically indented based on the start of the\n * line.\n */\npublic final class IndentingWriter extends FilterWriter {\n    /** {@code null-ok;} optional prefix for every line */\n    private final String prefix;\n\n    /** {@code > 0;} the maximum output width */\n    private final int width;\n\n    /** {@code > 0;} the maximum indent */\n    private final int maxIndent;\n\n    /** {@code >= 0;} current output column (zero-based) */\n    private int column;\n\n    /** whether indent spaces are currently being collected */\n    private boolean collectingIndent;\n\n    /** {@code >= 0;} current indent amount */\n    private int indent;\n\n    /**\n     * Constructs an instance.\n     *\n     * @param out {@code non-null;} writer to send final output to\n     * @param width {@code >= 0;} the maximum output width (not including\n     * {@code prefix}), or {@code 0} for no maximum\n     * @param prefix {@code non-null;} the prefix for each line\n     */\n    public IndentingWriter(Writer out, int width, String prefix) {\n        super(out);\n\n        if (out == null) {\n            throw new NullPointerException(\"out == null\");\n        }\n\n        if (width < 0) {\n            throw new IllegalArgumentException(\"width < 0\");\n        }\n\n        if (prefix == null) {\n            throw new NullPointerException(\"prefix == null\");\n        }\n\n        this.width = (width != 0) ? width : Integer.MAX_VALUE;\n        this.maxIndent = width >> 1;\n        this.prefix = (prefix.length() == 0) ? null : prefix;\n\n        bol();\n    }\n\n    /**\n     * Constructs a no-prefix instance.\n     *\n     * @param out {@code non-null;} writer to send final output to\n     * @param width {@code >= 0;} the maximum output width (not including\n     * {@code prefix}), or {@code 0} for no maximum\n     */\n    public IndentingWriter(Writer out, int width) {\n        this(out, width, \"\");\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void write(int c) throws IOException {\n        synchronized (lock) {\n            if (collectingIndent) {\n                if (c == ' ') {\n                    indent++;\n                    if (indent >= maxIndent) {\n                        indent = maxIndent;\n                        collectingIndent = false;\n                    }\n                } else {\n                    collectingIndent = false;\n                }\n            }\n\n            if ((column == width) && (c != '\\n')) {\n                out.write('\\n');\n                column = 0;\n                /*\n                 * Note: No else, so this should fall through to the next\n                 * if statement.\n                 */\n            }\n\n            if (column == 0) {\n                if (prefix != null) {\n                    out.write(prefix);\n                }\n\n                if (!collectingIndent) {\n                    for (int i = 0; i < indent; i++) {\n                        out.write(' ');\n                    }\n                    column = indent;\n                }\n            }\n\n            out.write(c);\n\n            if (c == '\\n') {\n                bol();\n            } else {\n                column++;\n            }\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void write(char[] cbuf, int off, int len) throws IOException {\n        synchronized (lock) {\n            while (len > 0) {\n                write(cbuf[off]);\n                off++;\n                len--;\n            }\n        }\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public void write(String str, int off, int len) throws IOException {\n        synchronized (lock) {\n            while (len > 0) {\n                write(str.charAt(off));\n                off++;\n                len--;\n            }\n        }\n    }\n\n    /**\n     * Indicates that output is at the beginning of a line.\n     */\n    private void bol() {\n        column = 0;\n        collectingIndent = (maxIndent != 0);\n        indent = 0;\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/IntIterator.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\n/**\n * An iterator for a list of ints.\n */\npublic interface IntIterator {\n\n    /**\n     * Checks to see if the iterator has a next value.\n     *\n     * @return true if next() will succeed\n     */\n    boolean hasNext();\n\n    /**\n     * Returns the next value in the iterator.\n     *\n     * @return next value\n     * @throws java.util.NoSuchElementException if no next element exists\n     */\n    int next();\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/IntList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\nimport java.util.Arrays;\n\n/**\n * Simple list of {@code int}s.\n */\npublic final class IntList extends MutabilityControl {\n    /** {@code non-null;} immutable, no-element instance */\n    public static final IntList EMPTY = new IntList(0);\n\n    /** {@code non-null;} array of elements */\n    private int[] values;\n\n    /** {@code >= 0;} current size of the list */\n    private int size;\n\n    /** whether the values are currently sorted */\n    private boolean sorted;\n\n    static {\n        EMPTY.setImmutable();\n    }\n\n    /**\n     * Constructs a new immutable instance with the given element.\n     *\n     * @param value the sole value in the list\n     */\n    public static IntList makeImmutable(int value) {\n        IntList result = new IntList(1);\n\n        result.add(value);\n        result.setImmutable();\n\n        return result;\n    }\n\n    /**\n     * Constructs a new immutable instance with the given elements.\n     *\n     * @param value0 the first value in the list\n     * @param value1 the second value in the list\n     */\n    public static IntList makeImmutable(int value0, int value1) {\n        IntList result = new IntList(2);\n\n        result.add(value0);\n        result.add(value1);\n        result.setImmutable();\n\n        return result;\n    }\n\n    /**\n     * Constructs an empty instance with a default initial capacity.\n     */\n    public IntList() {\n        this(4);\n    }\n\n    /**\n     * Constructs an empty instance.\n     *\n     * @param initialCapacity {@code >= 0;} initial capacity of the list\n     */\n    public IntList(int initialCapacity) {\n        super(true);\n\n        try {\n            values = new int[initialCapacity];\n        } catch (NegativeArraySizeException ex) {\n            // Translate the exception.\n            throw new IllegalArgumentException(\"size < 0\");\n        }\n\n        size = 0;\n        sorted = true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public int hashCode() {\n        int result = 0;\n\n        for (int i = 0; i < size; i++) {\n            result = (result * 31) + values[i];\n        }\n\n        return result;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public boolean equals(Object other) {\n        if (other == this) {\n            return true;\n        }\n\n        if (! (other instanceof IntList)) {\n            return false;\n        }\n\n        IntList otherList = (IntList) other;\n\n        if (sorted != otherList.sorted) {\n            return false;\n        }\n\n        if (size != otherList.size) {\n            return false;\n        }\n\n        for (int i = 0; i < size; i++) {\n            if (values[i] != otherList.values[i]) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /** {@inheritDoc} */\n    @Override\n    public String toString() {\n        StringBuffer sb = new StringBuffer(size * 5 + 10);\n\n        sb.append('{');\n\n        for (int i = 0; i < size; i++) {\n            if (i != 0) {\n                sb.append(\", \");\n            }\n            sb.append(values[i]);\n        }\n\n        sb.append('}');\n\n        return sb.toString();\n    }\n\n    /**\n     * Gets the number of elements in this list.\n     */\n    public int size() {\n        return size;\n    }\n\n    /**\n     * Gets the indicated value.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @return the indicated element's value\n     */\n    public int get(int n) {\n        if (n >= size) {\n            throw new IndexOutOfBoundsException(\"n >= size()\");\n        }\n\n        try {\n            return values[n];\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate exception.\n            throw new IndexOutOfBoundsException(\"n < 0\");\n        }\n    }\n\n    /**\n     * Sets the value at the given index.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @param value value to store\n     */\n    public void set(int n, int value) {\n        throwIfImmutable();\n\n        if (n >= size) {\n            throw new IndexOutOfBoundsException(\"n >= size()\");\n        }\n\n        try {\n            values[n] = value;\n            sorted = false;\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            // Translate the exception.\n            if (n < 0) {\n                throw new IllegalArgumentException(\"n < 0\");\n            }\n        }\n    }\n\n    /**\n     * Adds an element to the end of the list. This will increase the\n     * list's capacity if necessary.\n     *\n     * @param value the value to add\n     */\n    public void add(int value) {\n        throwIfImmutable();\n\n        growIfNeeded();\n\n        values[size++] = value;\n\n        if (sorted && (size > 1)) {\n            sorted = (value >= values[size - 2]);\n        }\n    }\n\n    /**\n     * Inserts element into specified index, moving elements at and above\n     * that index up one. May not be used to insert at an index beyond the\n     * current size (that is, insertion as a last element is legal but\n     * no further).\n     *\n     * @param n {@code >= 0, <=size();} index of where to insert\n     * @param value value to insert\n     */\n    public void insert(int n, int value) {\n        throwIfImmutable();\n\n        if (n > size) {\n            throw new IndexOutOfBoundsException(\"n > size()\");\n        }\n\n        growIfNeeded();\n\n        System.arraycopy (values, n, values, n+1, size - n);\n        values[n] = value;\n        size++;\n\n        sorted = sorted\n                && (n == 0 || value > values[n-1])\n                && (n == (size - 1) || value < values[n+1]);\n    }\n\n    /**\n     * Removes an element at a given index, shifting elements at greater\n     * indicies down one.\n     *\n     * @param n  {@code >=0, < size();} index of element to remove\n     */\n    public void removeIndex(int n) {\n        throwIfImmutable();\n\n        if (n >= size) {\n            throw new IndexOutOfBoundsException(\"n >= size()\");\n        }\n\n        System.arraycopy (values, n + 1, values, n, size - n - 1);\n        size--;\n\n        // sort status is unchanged\n    }\n\n    /**\n     * Increases size of array if needed\n     */\n    private void growIfNeeded() {\n        if (size == values.length) {\n            // Resize.\n            int[] newv = new int[size * 3 / 2 + 10];\n            System.arraycopy(values, 0, newv, 0, size);\n            values = newv;\n        }\n    }\n\n    /**\n     * Returns the last element in the array without modifying the array\n     *\n     * @return last value in the array\n     * @throws IndexOutOfBoundsException if stack is empty\n     */\n    public int top() {\n        return get(size - 1);\n    }\n\n    /**\n     * Pops an element off the end of the list and decreasing the size by one.\n     *\n     * @return value from what was the last element\n     * @throws IndexOutOfBoundsException if stack is empty\n     */\n    public int pop() {\n        throwIfImmutable();\n\n        int result;\n\n        result = get(size-1);\n        size--;\n\n        return result;\n    }\n\n    /**\n     * Pops N elements off the end of the list and decreasing the size by N.\n     *\n     * @param n {@code >= 0;} number of elements to remove from end\n     * @throws IndexOutOfBoundsException if stack is smaller than N\n     */\n    public void pop(int n) {\n        throwIfImmutable();\n\n        size -= n;\n    }\n\n    /**\n     * Shrinks the size of the list.\n     *\n     * @param newSize {@code >= 0;} the new size\n     */\n    public void shrink(int newSize) {\n        if (newSize < 0) {\n            throw new IllegalArgumentException(\"newSize < 0\");\n        }\n\n        if (newSize > size) {\n            throw new IllegalArgumentException(\"newSize > size\");\n        }\n\n        throwIfImmutable();\n\n        size = newSize;\n    }\n\n    /**\n     * Makes and returns a mutable copy of the list.\n     *\n     * @return {@code non-null;} an appropriately-constructed instance\n     */\n    public IntList mutableCopy() {\n        int sz = size;\n        IntList result = new IntList(sz);\n\n        for (int i = 0; i < sz; i++) {\n            result.add(values[i]);\n        }\n\n        return result;\n    }\n\n    /**\n     * Sorts the elements in the list in-place.\n     */\n    public void sort() {\n        throwIfImmutable();\n\n        if (!sorted) {\n            Arrays.sort(values, 0, size);\n            sorted = true;\n        }\n    }\n\n    /**\n     * Returns the index of the given value, or -1 if the value does not\n     * appear in the list.  This will do a binary search if the list is\n     * sorted or a linear search if not.\n     *\n     * @param value value to find\n     * @return index of value or -1\n     */\n    public int indexOf(int value) {\n        int ret = binarysearch(value);\n\n        return ret >= 0 ? ret : -1;\n\n    }\n\n    /**\n     * Performs a binary search on a sorted list, returning the index of\n     * the given value if it is present or\n     * {@code (-(insertion point) - 1)} if the value is not present.\n     * If the list is not sorted, then reverts to linear search and returns\n     * {@code -size()} if the element is not found.\n     *\n     * @param value value to find\n     * @return index of value or {@code (-(insertion point) - 1)} if the\n     * value is not present\n     */\n    public int binarysearch(int value) {\n        int sz = size;\n\n        if (!sorted) {\n            // Linear search.\n            for (int i = 0; i < sz; i++) {\n                if (values[i] == value) {\n                    return i;\n                }\n            }\n\n            return -sz;\n        }\n\n        /*\n         * Binary search. This variant does only one value comparison\n         * per iteration but does one more iteration on average than\n         * the variant that includes a value equality check per\n         * iteration.\n         */\n\n        int min = -1;\n        int max = sz;\n\n        while (max > (min + 1)) {\n            /*\n             * The guessIdx calculation is equivalent to ((min + max)\n             * / 2) but won't go wonky when min and max are close to\n             * Integer.MAX_VALUE.\n             */\n            int guessIdx = min + ((max - min) >> 1);\n            int guess = values[guessIdx];\n\n            if (value <= guess) {\n                max = guessIdx;\n            } else {\n                min = guessIdx;\n            }\n        }\n\n        if ((max != sz)) {\n            return (value == values[max]) ? max : (-max - 1);\n        } else {\n            return -sz - 1;\n        }\n    }\n\n\n    /**\n     * Returns whether or not the given value appears in the list.\n     * This will do a binary search if the list is sorted or a linear\n     * search if not.\n     *\n     * @see #sort\n     *\n     * @param value value to look for\n     * @return whether the list contains the given value\n     */\n    public boolean contains(int value) {\n        return indexOf(value) >= 0;\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/IntSet.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\n/**\n * A set of integers\n */\npublic interface IntSet {\n\n    /**\n     * Adds an int to a set\n     *\n     * @param value int to add\n     */\n    void add(int value);\n\n    /**\n     * Removes an int from a set.\n     *\n     * @param value int to remove\n     */\n    void remove(int value);\n\n    /**\n     * Checks to see if a value is in the set\n     *\n     * @param value int to check\n     * @return true if in set\n     */\n    boolean has(int value);\n\n    /**\n     * Merges {@code other} into this set, so this set becomes the\n     * union of the two.\n     *\n     * @param other {@code non-null;} other set to merge with.\n     */\n    void merge(IntSet other);\n\n    /**\n     * Returns the count of unique elements in this set.\n     *\n     * @return {@code > = 0;} count of unique elements\n     */\n    int elements();\n\n    /**\n     * Iterates the set\n     *\n     * @return {@code non-null;} a set iterator\n     */\n    IntIterator iterator();\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/LabeledItem.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\n/**\n * An item that has an integer label.\n */\npublic interface LabeledItem {\n\n    /*\n     * Gets the label of this block.\n     *\n     * @return {@code >= 0;} the label\n     */\n    public int getLabel();\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/LabeledList.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\nimport java.util.Arrays;\n\n/**\n * A list of labeled items, allowing easy lookup by label.\n */\npublic class LabeledList extends FixedSizeList {\n    /**\n     * Sparse array indexed by label to FixedSizeList index;\n     * {@code -1} for an invalid label.\n     */\n    private final IntList labelToIndex;\n\n    /** @inheritDoc */\n    public LabeledList(int size) {\n        super(size);\n\n        labelToIndex = new IntList(size);\n    }\n\n    /**\n     * Constructs a new instance that is a copy of the old instance.\n     *\n     * @param old instance to copy\n     */\n    public LabeledList(LabeledList old) {\n        super(old.size());\n        labelToIndex = old.labelToIndex.mutableCopy();\n\n        int sz = old.size();\n\n        for (int i = 0; i < sz; i++) {\n            Object one = old.get0(i);\n            if (one != null) {\n                set0(i, one);\n            }\n        }\n    }\n\n    /**\n     * Gets the maximum label (exclusive) of any block added to this instance.\n     *\n     * @return {@code >= 0;} the maximum label\n     */\n    public final int getMaxLabel() {\n        int sz = labelToIndex.size();\n\n        // Gobble any deleted labels that may be at the end.\n        int i;\n        for (i = sz - 1; (i >= 0) && (labelToIndex.get(i) < 0); i--)\n            /*empty*/ ;\n\n        int newSize = i + 1;\n\n        labelToIndex.shrink(newSize);\n\n        return newSize;\n    }\n\n    /**\n     * Removes a label from the label-to-index mapping.\n     *\n     * @param oldLabel label to remove\n     */\n    private void removeLabel(int oldLabel) {\n        labelToIndex.set(oldLabel, -1);\n    }\n\n    /**\n     * Adds a label and index to the label-to-index mapping.\n     *\n     * @param label new label\n     * @param index index of block.\n     */\n    private void addLabelIndex(int label, int index) {\n        int origSz = labelToIndex.size();\n\n        for (int i = 0; i <= (label - origSz); i++) {\n            labelToIndex.add(-1);\n        }\n\n        labelToIndex.set(label, index);\n    }\n\n    /**\n     * Gets the index of the first item in the list with the given\n     * label, if any.\n     *\n     * @param label {@code >= 0;} the label to look for\n     * @return {@code >= -1;} the index of the so-labelled item, or {@code -1}\n     * if none is found\n     */\n    public final int indexOfLabel(int label) {\n        if (label >= labelToIndex.size()) {\n            return -1;\n        } else {\n            return labelToIndex.get(label);\n        }\n    }\n\n    /**\n     * Gets an array containing all of the labels used in this instance,\n     * in order. The returned array is freshly-allocated and so may be\n     * modified safely by the caller without impacting this instance.\n     *\n     * @return {@code non-null;} ordered array of labels\n     * @throws NullPointerException thrown if there are any {@code null}\n     * items in this instance\n     */\n    public final int[] getLabelsInOrder() {\n        int sz = size();\n        int[] result = new int[sz];\n\n        for (int i = 0; i < sz; i++) {\n            LabeledItem li = (LabeledItem) get0(i);\n            if (li == null) {\n                throw new NullPointerException(\"null at index \" + i);\n            }\n            result[i] = li.getLabel();\n        }\n\n        Arrays.sort(result);\n        return result;\n    }\n\n    /** @inheritDoc */\n    @Override\n    public void shrinkToFit() {\n        super.shrinkToFit();\n\n        rebuildLabelToIndex();\n    }\n\n    /**\n     * Rebuilds the label-to-index mapping after a {@code shrinkToFit()}.\n     * Note: This assumes that the labels that are in the list are the\n     * same, although the indicies may have changed.\n     */\n    private void rebuildLabelToIndex() {\n        int szItems = size();\n\n        for (int i = 0; i < szItems; i++) {\n            LabeledItem li = (LabeledItem) get0(i);\n\n            if (li != null) {\n                labelToIndex.set(li.getLabel(), i);\n            }\n        }\n    }\n\n    /**\n     * Sets the element at the given index.\n     *\n     * @param n {@code >= 0, < size();} which element\n     * @param item {@code null-ok;} the value to store\n     */\n    protected void set(int n, LabeledItem item) {\n        LabeledItem old = (LabeledItem) getOrNull0(n);\n\n        set0(n, item);\n\n        if (old != null) {\n            removeLabel(old.getLabel());\n        }\n\n        if (item != null) {\n            addLabelIndex(item.getLabel(), n);\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/ListIntSet.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\nimport java.util.NoSuchElementException;\n\n/**\n * A set of integers, represented by a list\n */\npublic class ListIntSet implements IntSet {\n\n    /** also accessed in BitIntSet */\n    final IntList ints;\n\n    /**\n     * Constructs an instance\n     */\n    public ListIntSet() {\n        ints = new IntList();\n        ints.sort();\n    }\n\n    /** @inheritDoc */\n    public void add(int value) {\n        int index = ints.binarysearch(value);\n\n        if (index < 0) {\n            ints.insert(-(index + 1), value);\n        }\n    }\n\n    /** @inheritDoc */\n    public void remove(int value) {\n        int index = ints.indexOf(value);\n\n        if (index >= 0) {\n            ints.removeIndex(index);\n        }\n    }\n\n    /** @inheritDoc */\n    public boolean has(int value) {\n        return ints.indexOf(value) >= 0;\n    }\n\n    /** @inheritDoc */\n    public void merge(IntSet other) {\n        if (other instanceof ListIntSet) {\n            ListIntSet o = (ListIntSet) other;\n            int szThis = ints.size();\n            int szOther = o.ints.size();\n\n            int i = 0;\n            int j = 0;\n\n            while (j < szOther && i < szThis) {\n                while (j < szOther && o.ints.get(j) < ints.get(i)) {\n                    add(o.ints.get(j++));\n                }\n                if (j == szOther) {\n                    break;\n                }\n                while (i < szThis && o.ints.get(j) >= ints.get(i)) {\n                    i++;\n                }\n            }\n\n            while (j < szOther) {\n                add(o.ints.get(j++));\n            }\n\n            ints.sort();\n        } else if (other instanceof BitIntSet) {\n            BitIntSet o = (BitIntSet) other;\n\n            for (int i = 0; i >= 0; i = Bits.findFirst(o.bits, i + 1)) {\n                ints.add(i);\n            }\n            ints.sort();\n        } else {\n            IntIterator iter = other.iterator();\n            while (iter.hasNext()) {\n                add(iter.next());\n            }\n        }\n    }\n\n    /** @inheritDoc */\n    public int elements() {\n        return ints.size();\n    }\n\n    /** @inheritDoc */\n    public IntIterator iterator() {\n        return new IntIterator() {\n            private int idx = 0;\n\n            /** @inheritDoc */\n            public boolean hasNext() {\n                return idx < ints.size();\n            }\n\n            /** @inheritDoc */\n            public int next() {\n                if (!hasNext()) {\n                    throw new NoSuchElementException();\n                }\n\n                return ints.get(idx++);\n            }\n        };\n    }\n\n    /** @inheritDoc */\n    public String toString() {\n        return ints.toString();\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/MutabilityControl.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\n/**\n * Very simple base class that implements a flag to control the mutability\n * of instances. This class just provides the flag and a utility to check\n * and throw the right exception, but it is up to subclasses to place calls\n * to the checker in all the right places.\n */\npublic class MutabilityControl {\n    /** whether this instance is mutable */\n    private boolean mutable;\n\n    /**\n     * Constructs an instance. It is initially mutable.\n     */\n    public MutabilityControl() {\n        mutable = true;\n    }\n\n    /**\n     * Constructs an instance, explicitly indicating the mutability.\n     *\n     * @param mutable {@code true} iff this instance is mutable\n     */\n    public MutabilityControl(boolean mutable) {\n        this.mutable = mutable;\n    }\n\n    /**\n     * Makes this instance immutable.\n     */\n    public void setImmutable() {\n        mutable = false;\n    }\n\n    /**\n     * Checks to see whether or not this instance is immutable. This is the\n     * same as calling {@code !isMutable()}.\n     *\n     * @return {@code true} iff this instance is immutable\n     */\n    public final boolean isImmutable() {\n        return !mutable;\n    }\n\n    /**\n     * Checks to see whether or not this instance is mutable.\n     *\n     * @return {@code true} iff this instance is mutable\n     */\n    public final boolean isMutable() {\n        return mutable;\n    }\n\n    /**\n     * Throws {@link MutabilityException} if this instance is\n     * immutable.\n     */\n    public final void throwIfImmutable() {\n        if (!mutable) {\n            throw new MutabilityException(\"immutable instance\");\n        }\n    }\n\n    /**\n     * Throws {@link MutabilityException} if this instance is mutable.\n     */\n    public final void throwIfMutable() {\n        if (mutable) {\n            throw new MutabilityException(\"mutable instance\");\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/MutabilityException.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\nimport com.taobao.atlas.dex.util.ExceptionWithContext;\n\n/**\n * Exception due to a mutability problem.\n */\npublic class MutabilityException\n        extends ExceptionWithContext {\n    public MutabilityException(String message) {\n        super(message);\n    }\n\n    public MutabilityException(Throwable cause) {\n        super(cause);\n    }\n\n    public MutabilityException(String message, Throwable cause) {\n        super(message, cause);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/Output.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\nimport com.taobao.atlas.dex.util.ByteOutput;\n\n/**\n * Interface for a sink for binary output. This is similar to\n * {@code java.util.DataOutput}, but no {@code IOExceptions}\n * are declared, and multibyte output is defined to be little-endian.\n */\npublic interface Output extends ByteOutput {\n    /**\n     * Gets the current cursor position. This is the same as the number of\n     * bytes written to this instance.\n     *\n     * @return {@code >= 0;} the cursor position\n     */\n    public int getCursor();\n\n    /**\n     * Asserts that the cursor is the given value.\n     *\n     * @param expectedCursor the expected cursor value\n     * @throws RuntimeException thrown if {@code getCursor() !=\n     * expectedCursor}\n     */\n    public void assertCursor(int expectedCursor);\n\n    /**\n     * Writes a {@code byte} to this instance.\n     *\n     * @param value the value to write; all but the low 8 bits are ignored\n     */\n    public void writeByte(int value);\n\n    /**\n     * Writes a {@code short} to this instance.\n     *\n     * @param value the value to write; all but the low 16 bits are ignored\n     */\n    public void writeShort(int value);\n\n    /**\n     * Writes an {@code int} to this instance.\n     *\n     * @param value the value to write\n     */\n    public void writeInt(int value);\n\n    /**\n     * Writes a {@code long} to this instance.\n     *\n     * @param value the value to write\n     */\n    public void writeLong(long value);\n\n    /**\n     * Writes a DWARFv3-style unsigned LEB128 integer. For details,\n     * see the \"Dalvik Executable Format\" document or DWARF v3 section\n     * 7.6.\n     *\n     * @param value value to write, treated as an unsigned value\n     * @return {@code 1..5;} the number of bytes actually written\n     */\n    public int writeUleb128(int value);\n\n    /**\n     * Writes a DWARFv3-style unsigned LEB128 integer. For details,\n     * see the \"Dalvik Executable Format\" document or DWARF v3 section\n     * 7.6.\n     *\n     * @param value value to write\n     * @return {@code 1..5;} the number of bytes actually written\n     */\n    public int writeSleb128(int value);\n\n    /**\n     * Writes a {@link ByteArray} to this instance.\n     *\n     * @param bytes {@code non-null;} the array to write\n     */\n    public void write(ByteArray bytes);\n\n    /**\n     * Writes a portion of a {@code byte[]} to this instance.\n     *\n     * @param bytes {@code non-null;} the array to write\n     * @param offset {@code >= 0;} offset into {@code bytes} for the first\n     * byte to write\n     * @param length {@code >= 0;} number of bytes to write\n     */\n    public void write(byte[] bytes, int offset, int length);\n\n    /**\n     * Writes a {@code byte[]} to this instance. This is just\n     * a convenient shorthand for {@code write(bytes, 0, bytes.length)}.\n     *\n     * @param bytes {@code non-null;} the array to write\n     */\n    public void write(byte[] bytes);\n\n    /**\n     * Writes the given number of {@code 0} bytes.\n     *\n     * @param count {@code >= 0;} the number of zeroes to write\n     */\n    public void writeZeroes(int count);\n\n    /**\n     * Adds extra bytes if necessary (with value {@code 0}) to\n     * force alignment of the output cursor as given.\n     *\n     * @param alignment {@code > 0;} the alignment; must be a power of two\n     */\n    public void alignTo(int alignment);\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/ToHuman.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\n/**\n * Simple interface for objects that can return a \"human\" (as opposed to\n * a complete but often hard to read) string form.\n */\npublic interface ToHuman {\n    /**\n     * Return the \"human\" string form of this instance.  This is\n     * generally less \"debuggy\" than {@code toString()}.\n     *\n     * @return {@code non-null;} the human string form\n     */\n    public String toHuman();\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/TwoColumnOutput.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.io.OutputStreamWriter;\nimport java.io.StringWriter;\nimport java.io.Writer;\n\n/**\n * Class that takes a combined output destination and provides two\n * output writers, one of which ends up writing to the left column and\n * one which goes on the right.\n */\npublic final class TwoColumnOutput {\n    /** {@code non-null;} underlying writer for final output */\n    private final Writer out;\n\n    /** {@code > 0;} the left column width */\n    private final int leftWidth;\n\n    /** {@code non-null;} pending left column output */\n    private final StringBuffer leftBuf;\n\n    /** {@code non-null;} pending right column output */\n    private final StringBuffer rightBuf;\n\n    /** {@code non-null;} left column writer */\n    private final IndentingWriter leftColumn;\n\n    /** {@code non-null;} right column writer */\n    private final IndentingWriter rightColumn;\n\n    /**\n     * Turns the given two strings (with widths) and spacer into a formatted\n     * two-column string.\n     *\n     * @param s1 {@code non-null;} first string\n     * @param width1 {@code > 0;} width of the first column\n     * @param spacer {@code non-null;} spacer string\n     * @param s2 {@code non-null;} second string\n     * @param width2 {@code > 0;} width of the second column\n     * @return {@code non-null;} an appropriately-formatted string\n     */\n    public static String toString(String s1, int width1, String spacer,\n                                  String s2, int width2) {\n        int len1 = s1.length();\n        int len2 = s2.length();\n\n        StringWriter sw = new StringWriter((len1 + len2) * 3);\n        TwoColumnOutput twoOut =\n            new TwoColumnOutput(sw, width1, width2, spacer);\n\n        try {\n            twoOut.getLeft().write(s1);\n            twoOut.getRight().write(s2);\n        } catch (IOException ex) {\n            throw new RuntimeException(\"shouldn't happen\", ex);\n        }\n\n        twoOut.flush();\n        return sw.toString();\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param out {@code non-null;} writer to send final output to\n     * @param leftWidth {@code > 0;} width of the left column, in characters\n     * @param rightWidth {@code > 0;} width of the right column, in characters\n     * @param spacer {@code non-null;} spacer string to sit between the two columns\n     */\n    public TwoColumnOutput(Writer out, int leftWidth, int rightWidth,\n                           String spacer) {\n        if (out == null) {\n            throw new NullPointerException(\"out == null\");\n        }\n\n        if (leftWidth < 1) {\n            throw new IllegalArgumentException(\"leftWidth < 1\");\n        }\n\n        if (rightWidth < 1) {\n            throw new IllegalArgumentException(\"rightWidth < 1\");\n        }\n\n        if (spacer == null) {\n            throw new NullPointerException(\"spacer == null\");\n        }\n\n        StringWriter leftWriter = new StringWriter(1000);\n        StringWriter rightWriter = new StringWriter(1000);\n\n        this.out = out;\n        this.leftWidth = leftWidth;\n        this.leftBuf = leftWriter.getBuffer();\n        this.rightBuf = rightWriter.getBuffer();\n        this.leftColumn = new IndentingWriter(leftWriter, leftWidth);\n        this.rightColumn =\n            new IndentingWriter(rightWriter, rightWidth, spacer);\n    }\n\n    /**\n     * Constructs an instance.\n     *\n     * @param out {@code non-null;} stream to send final output to\n     * @param leftWidth {@code >= 1;} width of the left column, in characters\n     * @param rightWidth {@code >= 1;} width of the right column, in characters\n     * @param spacer {@code non-null;} spacer string to sit between the two columns\n     */\n    public TwoColumnOutput(OutputStream out, int leftWidth, int rightWidth,\n                           String spacer) {\n        this(new OutputStreamWriter(out), leftWidth, rightWidth, spacer);\n    }\n\n    /**\n     * Gets the writer to use to write to the left column.\n     *\n     * @return {@code non-null;} the left column writer\n     */\n    public Writer getLeft() {\n        return leftColumn;\n    }\n\n    /**\n     * Gets the writer to use to write to the right column.\n     *\n     * @return {@code non-null;} the right column writer\n     */\n    public Writer getRight() {\n        return rightColumn;\n    }\n\n    /**\n     * Flushes the output. If there are more lines of pending output in one\n     * column, then the other column will get filled with blank lines.\n     */\n    public void flush() {\n        try {\n            appendNewlineIfNecessary(leftBuf, leftColumn);\n            appendNewlineIfNecessary(rightBuf, rightColumn);\n            outputFullLines();\n            flushLeft();\n            flushRight();\n        } catch (IOException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n\n    /**\n     * Outputs to the final destination as many full line pairs as\n     * there are in the pending output, removing those lines from\n     * their respective buffers. This method terminates when at\n     * least one of the two column buffers is empty.\n     */\n    private void outputFullLines() throws IOException {\n        for (;;) {\n            int leftLen = leftBuf.indexOf(\"\\n\");\n            if (leftLen < 0) {\n                return;\n            }\n\n            int rightLen = rightBuf.indexOf(\"\\n\");\n            if (rightLen < 0) {\n                return;\n            }\n\n            if (leftLen != 0) {\n                out.write(leftBuf.substring(0, leftLen));\n            }\n\n            if (rightLen != 0) {\n                writeSpaces(out, leftWidth - leftLen);\n                out.write(rightBuf.substring(0, rightLen));\n            }\n\n            out.write('\\n');\n\n            leftBuf.delete(0, leftLen + 1);\n            rightBuf.delete(0, rightLen + 1);\n        }\n    }\n\n    /**\n     * Flushes the left column buffer, printing it and clearing the buffer.\n     * If the buffer is already empty, this does nothing.\n     */\n    private void flushLeft() throws IOException {\n        appendNewlineIfNecessary(leftBuf, leftColumn);\n\n        while (leftBuf.length() != 0) {\n            rightColumn.write('\\n');\n            outputFullLines();\n        }\n    }\n\n    /**\n     * Flushes the right column buffer, printing it and clearing the buffer.\n     * If the buffer is already empty, this does nothing.\n     */\n    private void flushRight() throws IOException {\n        appendNewlineIfNecessary(rightBuf, rightColumn);\n\n        while (rightBuf.length() != 0) {\n            leftColumn.write('\\n');\n            outputFullLines();\n        }\n    }\n\n    /**\n     * Appends a newline to the given buffer via the given writer, but\n     * only if it isn't empty and doesn't already end with one.\n     *\n     * @param buf {@code non-null;} the buffer in question\n     * @param out {@code non-null;} the writer to use\n     */\n    private static void appendNewlineIfNecessary(StringBuffer buf,\n                                                 Writer out)\n            throws IOException {\n        int len = buf.length();\n\n        if ((len != 0) && (buf.charAt(len - 1) != '\\n')) {\n            out.write('\\n');\n        }\n    }\n\n    /**\n     * Writes the given number of spaces to the given writer.\n     *\n     * @param out {@code non-null;} where to write\n     * @param amt {@code >= 0;} the number of spaces to write\n     */\n    private static void writeSpaces(Writer out, int amt) throws IOException {\n        while (amt > 0) {\n            out.write(' ');\n            amt--;\n        }\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/Warning.java",
    "content": "/*\n * Copyright (C) 2008 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\n/**\n * Exception which is meant to indicate a non-fatal warning.\n */\npublic class Warning extends RuntimeException {\n    /**\n     * Constructs an instance.\n     *\n     * @param message human-oriented message\n     */\n    public Warning(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/dexmerge/dx/util/Writers.java",
    "content": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.atlas.dexmerge.dx.util;\n\nimport java.io.PrintWriter;\nimport java.io.Writer;\n\n/**\n * Utilities for dealing with {@code Writer}s.\n */\npublic final class Writers {\n    /**\n     * This class is uninstantiable.\n     */\n    private Writers() {\n        // This space intentionally left blank.\n    }\n\n    /**\n     * Makes a {@code PrintWriter} for the given {@code Writer},\n     * returning the given writer if it already happens to be the right\n     * class.\n     *\n     * @param writer {@code non-null;} writer to (possibly) wrap\n     * @return {@code non-null;} an appropriate instance\n     */\n    public static PrintWriter printWriterFor(Writer writer) {\n        if (writer instanceof PrintWriter) {\n            return (PrintWriter) writer;\n        }\n\n        return new PrintWriter(writer);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/update/AtlasUpdater.java",
    "content": "package com.taobao.atlas.update;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.List;\n\nimport android.content.Context;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport com.taobao.atlas.dexmerge.MergeCallback;\nimport com.taobao.atlas.update.exception.MergeException;\nimport com.taobao.atlas.update.model.UpdateInfo;\nimport com.taobao.atlas.update.model.UpdateInfo.Item;\nimport com.taobao.atlas.update.util.PatchCleaner;\nimport com.taobao.atlas.update.util.PatchInstaller;\nimport com.taobao.atlas.update.util.PatchMerger;\nimport org.osgi.framework.BundleException;\n\n/**\n * Created by wuzhong on 2016/11/23.\n */\n\npublic class AtlasUpdater {\n\n    /**\n     * 更新主入口\n     *\n     * @param updateInfo 更新的基础信息\n     * @param patchFile  tpatch包\n     * @throws MergeException\n     * @throws BundleException\n     */\n    public static void update(UpdateInfo updateInfo, File patchFile) throws MergeException, BundleException {\n\n        if (null == updateInfo || updateInfo.dexPatch) {\n            //with dexPatch,please call \"dexPatchUpdate\"\n            return;\n        }\n\n        MergeCallback mergeCallback = new MergeCallback() {\n            @Override\n            public void onMergeResult(boolean result, String bundleName) {\n                if (result) {\n                    Log.d(\"[dexmerge]\", \"merge bundle \" + bundleName + \" success \");\n                } else {\n                    Log.e(\"[dexmerge]\", \"merge bundle \" + bundleName + \" fail \");\n                }\n            }\n        };\n\n        PatchMerger patchMerger = new PatchMerger(updateInfo, patchFile, mergeCallback);\n\n        try {\n            patchMerger.merge();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        PatchInstaller patchInstaller = new PatchInstaller(patchMerger.mergeOutputs, updateInfo);\n\n        patchInstaller.install();\n\n        PatchCleaner.clearUpdatePath(updateInfo.workDir.getAbsolutePath());\n\n    }\n\n    public static void dexpatchUpdate(Context context, UpdateInfo updateInfo, File patchFile,\n                                      final IDexpatchMonitor coldMonitor, boolean enableHot,\n                                      IDexpatchMonitor hotMonitor)\n        throws Exception {\n\n        if (null == updateInfo || !updateInfo.dexPatch) {\n            return;\n        }\n        String versionName = null;\n        try {\n            Context c = RuntimeVariables.androidApplication;\n            versionName = c.getPackageManager().getPackageInfo(c.getPackageName(), 0).versionName;\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        if (TextUtils.isEmpty(versionName) || !versionName.equals(updateInfo.baseVersion)) {\n            return;\n        }\n\n        if (enableHot) {\n            List<UpdateInfo.Item> needPatchHotBundles = DexPatchUpdater.filterNeedHotPatchList(\n                UpdateBundleDivider.dividePatchInfo(updateInfo.updateBundles, Item.PATCH_DEX_HOT)\n            );\n            DexPatchUpdater.installHotPatch(updateInfo.updateVersion, needPatchHotBundles, patchFile, hotMonitor);\n        }\n        updateInfo.updateBundles = DexPatchUpdater.filterNeedColdPatchList(\n            UpdateBundleDivider.dividePatchInfo(updateInfo.updateBundles, Item.PATCH_DEX_COLD)\n        );\n        DexPatchUpdater.installColdPatch(updateInfo, patchFile, coldMonitor);\n    }\n\n    public static void dexpatchUpdate(Context context, UpdateInfo updateInfo, File patchFile,\n                                      final IDexpatchMonitor monitor) throws Exception {\n        dexpatchUpdate(context, updateInfo, patchFile, monitor, false, null);\n    }\n\n    public interface IDexpatchMonitor {\n        public void merge(boolean success, String bundleName, long version, String errMsg);\n\n        public void install(boolean success, String bundleName, long version, String errMsg);\n    }\n\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/update/AwoPatchReceiver.java",
    "content": "package com.taobao.atlas.update;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FilenameFilter;\nimport java.io.IOException;\nimport java.util.List;\n\nimport android.app.ActivityManager;\nimport android.content.BroadcastReceiver;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.pm.PackageInfo;\nimport android.content.pm.ResolveInfo;\nimport android.taobao.atlas.framework.Framework;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.taobao.atlas.util.ApkUtils;\nimport android.util.Log;\nimport android.widget.Toast;\n\n/**\n * Created by guanjie on 2017/1/23.\n */\n\npublic class AwoPatchReceiver extends BroadcastReceiver{\n\n    public static String ATLAS_DEBUG_DIRECTORY;\n    public static final String PATCH_ACTION = \"com.taobao.atlas.intent.PATCH_APP\";\n    public static final String ROLLBACK_ACTION = \"com.taobao.atlas.intent.ROLLBACK_PATCH\";\n\n    static{\n        try {\n            ATLAS_DEBUG_DIRECTORY = RuntimeVariables.androidApplication.getExternalFilesDir(\"atlas-debug\").getAbsolutePath();\n        } catch (Exception e) {\n            ATLAS_DEBUG_DIRECTORY = \"/sdcard/Android/data/\" + RuntimeVariables.androidApplication.getPackageName() + \"/files/atlas-debug\";\n        }\n        if(!new File(ATLAS_DEBUG_DIRECTORY).exists()){\n            new File(ATLAS_DEBUG_DIRECTORY).mkdirs();\n        }\n    }\n\n    @Override\n    public void onReceive(Context context, Intent intent) {\n        if (!Framework.isDeubgMode()) {\n            return;\n        }\n        if (context.getApplicationContext().getPackageName().equals(intent.getStringExtra(\"pkg\"))) {\n            if (intent.getAction().equals(PATCH_ACTION)) {\n                Toast.makeText(context.getApplicationContext(), \"DebugPatch安装中,请稍后...\", Toast.LENGTH_LONG).show();\n                doPatch();\n                restart();\n            }else if (intent.getAction().equals(ROLLBACK_ACTION)) {\n                Toast.makeText(context.getApplicationContext(), \"动态部署回滚,请稍后...\", Toast.LENGTH_LONG).show();\n            }\n        }\n    }\n\n    private void doPatch(){\n        try {\n            File debugDirectory = new File(ATLAS_DEBUG_DIRECTORY);\n            File[] bundles = debugDirectory.listFiles(new FilenameFilter() {\n                @Override\n                public boolean accept(File dir, String filename) {\n                    if (filename.endsWith(\".so\")) {\n                        return true;\n                    }\n                    return false;\n                }\n            });\n            if(bundles!=null && bundles.length>0){\n                for(int x=0;x<bundles.length;x++){\n                    PackageInfo pkgInfo = RuntimeVariables.androidApplication.getPackageManager().getPackageArchiveInfo(bundles[0].getAbsolutePath(), 0);\n                    String packageName = pkgInfo.packageName;\n                    File debug_storage_bundle_dir = new File(RuntimeVariables.androidApplication.getExternalFilesDir(\"debug_storage\"),packageName);\n                    if(!debug_storage_bundle_dir.exists()){\n                        debug_storage_bundle_dir.mkdirs();\n                    }\n                    File targetPatchZip = new File(debug_storage_bundle_dir,\"patch.zip\");\n                    if(targetPatchZip.exists()){\n                        targetPatchZip.delete();\n                    }\n                    bundles[0].renameTo(targetPatchZip);\n                    if(!targetPatchZip.exists()){\n                        ApkUtils.copyInputStreamToFile(new FileInputStream(bundles[0]),targetPatchZip);\n                    }\n                    if(!targetPatchZip.exists()){\n                        throw new IOException(\"move \"+bundles[0]+\"failed\");\n                    }\n                }\n            }\n        }catch(Throwable e){\n            e.printStackTrace();\n        }\n    }\n\n    private void restart() {\n        Intent\n            intent = RuntimeVariables.androidApplication.getPackageManager().getLaunchIntentForPackage(RuntimeVariables.androidApplication.getPackageName());\n        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |\n                Intent.FLAG_ACTIVITY_NEW_TASK);\n        ResolveInfo info = RuntimeVariables.androidApplication.getPackageManager().resolveActivity(intent, 0);\n        if (info != null) {\n            Log.d(\"PatchReceiver\", info.activityInfo.name);\n        } else {\n            Log.d(\"PatchReceiver\", \"no activity\");\n\n        }\n        // RuntimeVariables.androidApplication.startActivity(intent);\n        kill();\n        android.os.Process.killProcess(android.os.Process.myPid());\n        // System.exit(0);\n    }\n\n    private void kill() {\n            try {\n                ActivityManager am = (ActivityManager) RuntimeVariables.androidApplication.getSystemService(Context.ACTIVITY_SERVICE);\n                List<ActivityManager.RunningAppProcessInfo> a = am.getRunningAppProcesses();\n                for (int i = 0; i < a.size(); i++) {\n                    ActivityManager.RunningAppProcessInfo b = a.get(i);\n                    if (b.processName.startsWith(RuntimeVariables.androidApplication.getPackageName()+\":\")) {\n                        android.os.Process.killProcess(b.pid);\n                        continue;\n                    }\n                }\n            } catch (Exception e) {\n\n            }\n        }\n\n\n\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/update/DexPatchUpdater.java",
    "content": "package com.taobao.atlas.update;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.zip.ZipFile;\n\nimport android.content.Context;\nimport android.taobao.atlas.patch.AtlasHotPatchManager;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.taobao.atlas.util.IOUtil;\nimport android.taobao.atlas.versionInfo.BaselineInfoManager;\nimport android.text.TextUtils;\nimport android.util.Pair;\nimport com.taobao.atlas.update.AtlasUpdater.IDexpatchMonitor;\nimport com.taobao.atlas.update.model.UpdateInfo;\nimport com.taobao.atlas.update.model.UpdateInfo.Item;\nimport com.taobao.atlas.update.util.PatchCleaner;\nimport com.taobao.atlas.update.util.PatchInstaller;\nimport com.taobao.atlas.update.util.PatchMerger;\n\n/**\n * Created by zhongcang on 2017/11/7.\n * .\n */\n\npublic class DexPatchUpdater {\n\n    public static void installHotPatch(String updateVersion,List<UpdateInfo.Item> updateList, File patchFile,IDexpatchMonitor monitor) throws Exception{\n        if (null == updateList || updateList.isEmpty()){\n            return;\n        }\n        ZipFile patchZip = null;\n        try {\n            patchZip = new ZipFile(patchFile);\n            HashMap<String, Pair<Long, InputStream>> updateBundles = new HashMap<>(updateList.size());\n            for (UpdateInfo.Item bundle : updateList) {\n                String entryName = \"com.taobao.maindex\".equals(bundle.name)\n                    ? \"hot.dex\"\n                    : String.format(\"%s%s/hot.dex\", \"lib\", bundle.name.replace(\".\", \"_\"));\n                InputStream entryIn = patchZip.getInputStream(patchZip.getEntry(entryName));\n                updateBundles.put(bundle.name, new Pair<>(bundle.dexpatchVersion, entryIn));\n            }\n            AtlasHotPatchManager.getInstance().installHotFixPatch(updateVersion, updateBundles);\n        } catch (IOException e) {\n            e.printStackTrace();\n            throw e;\n        } finally {\n            IOUtil.quietClose(patchZip);\n        }\n        if (null != monitor) {\n            Map<String, Long> hotPatchInstall = AtlasHotPatchManager.getInstance().getAllInstallPatch();\n            if (null == hotPatchInstall) {\n                hotPatchInstall = new HashMap<>(1);\n            }\n            for (UpdateInfo.Item item : updateList) {\n                boolean success = hotPatchInstall.containsKey(item.name);\n                monitor.install(success, item.name, item.dexpatchVersion, \"\");\n            }\n        }\n    }\n\n    public static void installColdPatch(UpdateInfo updateInfo, File patchFile,IDexpatchMonitor monitor) throws Exception{\n        if (null == updateInfo.updateBundles || updateInfo.updateBundles.isEmpty()){\n            return;\n        }\n        PatchMerger patchMerger = null;\n        try {\n            patchMerger = new PatchMerger(updateInfo, patchFile, null);\n            patchMerger.merge();\n\n            List<UpdateInfo.Item> result = new ArrayList<>();\n            for (int i = 0; i < updateInfo.updateBundles.size(); i++) {\n                UpdateInfo.Item item = updateInfo.updateBundles.get(i);\n                if (patchMerger.mergeOutputs.containsKey(item.name)) {\n                    //对于merge成功的bundle列表进行更新\n                    Pair<String, Item> pair = patchMerger.mergeOutputs.get(item.name);\n                    boolean succeed = new File(pair.first).exists();\n                    if (item.reset){\n                        result.add(item);\n                        succeed = true;\n                    }\n                    if (succeed) {\n                        result.add(item);\n                    }\n                    if (monitor != null) {\n                        monitor.merge(succeed, item.name, item.dexpatchVersion, \"\");\n                    }\n                }\n            }\n            updateInfo.updateBundles = result;\n\n            PatchInstaller patchInstaller = new PatchInstaller(patchMerger.mergeOutputs, updateInfo);\n            patchInstaller.install();\n        } catch (Exception e) {\n            e.printStackTrace();\n            throw e;\n        } finally {\n            PatchCleaner.clearUpdatePath(updateInfo.workDir.getAbsolutePath());\n        }\n\n        ConcurrentHashMap<String, Long> installList = BaselineInfoManager.instance().getDexPatchBundles();\n        if (installList == null || installList.size() == 0) {\n            return;\n        }\n\n        if (null != monitor) {\n            for (UpdateInfo.Item item : updateInfo.updateBundles) {\n                boolean succeed = installList.containsKey(item.name) && item.dexpatchVersion == installList.get(\n                    item.name);\n                monitor.install(succeed, item.name, item.dexpatchVersion, \"\");\n                if (!succeed && item.reset){\n                    monitor.install(true, item.name, item.dexpatchVersion, \"\");\n                }\n            }\n        }\n    }\n\n\n\n    /**\n     * @return hotPatch的数据\n     */\n    public static List<UpdateInfo.Item> filterNeedHotPatchList(List<Item> hotPatchList) {\n        List<Item> resultList = new ArrayList<>(hotPatchList.size());\n        Map<String, Long> installMap = AtlasHotPatchManager.getInstance().getAllInstallPatch();\n        if (null == installMap) {\n            installMap = new HashMap<>(1);\n        }\n        for (Item item : hotPatchList) {\n            if (item.patchType != Item.PATCH_DEX_HOT) {\n                continue;\n            }\n            Long version = installMap.get(item.name);\n            if (null == version || item.dexpatchVersion > version) {\n                resultList.add(Item.makeCopy(item));\n            }\n        }\n        return resultList;\n    }\n\n\n    /**\n     * @return 普通DexPatch (cold)的数据\n     */\n    public static List<UpdateInfo.Item> filterNeedColdPatchList(List<Item> coldPatchList) {\n        List<Item> resultList = new ArrayList<>(coldPatchList.size());\n        Map<String, Long> installMap = BaselineInfoManager.instance().getDexPatchBundles();\n        if (null == installMap) {\n            installMap = new HashMap<>(1);\n        }\n        for (Item item : coldPatchList) {\n            if (item.patchType != Item.PATCH_DEX_COLD) {\n                continue;\n            }\n            Long version = installMap.get(item.name);\n\n            if (item.reset) {\n                //本地已经安装过，并且处于未回滚状态\n                if (null != version && version != -1) {\n                    resultList.add(Item.makeCopy(item));\n                }\n                continue;\n            }\n            if (null == version || item.dexpatchVersion > version) {\n                resultList.add(Item.makeCopy(item));\n            }\n        }\n        return resultList;\n    }\n\n}"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/update/UpdateBundleDivider.java",
    "content": "package com.taobao.atlas.update;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.taobao.atlas.update.model.UpdateInfo;\nimport com.taobao.atlas.update.model.UpdateInfo.Item;\n\n/**\n * Created by 种藏 on 2017/11/14.\n * .\n */\n\npublic class UpdateBundleDivider {\n\n    public static List<Item> dividePatchInfo(List<Item> allItem, int patchType) {\n        List<UpdateInfo.Item> list = new ArrayList<>();\n        if (null == allItem) {\n            return list;\n        }\n        for (UpdateInfo.Item item : allItem) {\n            if (item.patchType == patchType) {\n                Item newItem = Item.makeCopy(item);\n                newItem.patchType = patchType;\n                list.add(newItem);\n                continue;\n            }\n            if (item.patchType == Item.PATCH_DEX_C_AND_H && (patchType == Item.PATCH_DEX_COLD || patchType == Item.PATCH_DEX_HOT) ) {\n                Item newItem = Item.makeCopy(item);\n                newItem.patchType = patchType;\n                list.add(newItem);\n            }\n        }\n        return list;\n    }\n}"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/update/exception/MergeException.java",
    "content": "package com.taobao.atlas.update.exception;\n\n/**\n * Created by wuzhong on 2016/11/23.\n */\n\npublic class MergeException extends Exception {\n\n    public MergeException() {\n    }\n\n    public MergeException(String detailMessage) {\n        super(detailMessage);\n    }\n\n    public MergeException(String detailMessage, Throwable throwable) {\n        super(detailMessage, throwable);\n    }\n\n    public MergeException(Throwable throwable) {\n        super(throwable);\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/update/model/UpdateInfo.java",
    "content": "package com.taobao.atlas.update.model;\n\nimport android.taobao.atlas.runtime.RuntimeVariables;\n\nimport java.io.File;\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Created by wuzhong on 2016/11/23.\n */\n\npublic class UpdateInfo implements Serializable {\n\n    /**\n     * 当前的客户端版本\n     */\n    public String baseVersion;\n    /**\n     * 更新后的客户端版本\n     */\n    public String updateVersion;\n\n    public boolean dexPatch;\n\n    public boolean lowDisk = false;\n\n    /**\n     * 更新的模块列表信息\n     */\n    public List<Item> updateBundles;\n\n    public File workDir = new File(RuntimeVariables.androidApplication.getCacheDir(), \"atlas_update\");\n\n    /**\n     * 更新的模块信息\n     */\n    public static class Item implements Serializable {\n        public static final int PATCH_DYNAMIC_ = 0;\n        public static final int PATCH_DEX_COLD = 1;\n        public static final int PATCH_DEX_HOT = 2;\n        public static final int PATCH_DEX_C_AND_H = 3;\n\n        /**\n         * 是不是主dex\n         */\n        public boolean isMainDex;\n        /**\n         * bundle 的名称\n         */\n        public String name;\n        /**\n         * bundle 版本信息\n         */\n        //        public String version;\n        //        /**\n        //         * bundle 的代码仓库对应的版本\n        //         */\n        //        public String srcVersion;\n\n        public String unitTag;\n        public String srcUnitTag;\n        /**\n         * this version is compatible with new app version\n         * no need to update\n         */\n        public boolean inherit = false;\n        /**\n         * 依赖的 bundle 列表\n         */\n        public List<String> dependency;\n\n        public int patchType;\n\n        public boolean resetHotPatch = false;\n\n        public long dexpatchVersion = -1;\n\n        public boolean reset = false;\n\n        public static Item makeCopy(Item origin) {\n            Item item = new Item();\n            item.isMainDex = origin.isMainDex;\n            item.name = origin.name;\n            item.unitTag = origin.unitTag;\n            item.srcUnitTag = origin.srcUnitTag;\n            item.inherit = origin.inherit;\n            item.patchType = origin.patchType;\n            item.dexpatchVersion = origin.dexpatchVersion;\n            item.reset = origin.reset;\n            item.resetHotPatch = origin.resetHotPatch;\n            if (null != origin.dependency) {\n                List<String> copyDependency = new ArrayList<>(origin.dependency.size());\n                copyDependency.addAll(origin.dependency);\n                item.dependency = copyDependency;\n            }\n            return item;\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/update/util/PatchCleaner.java",
    "content": "package com.taobao.atlas.update.util;\n\nimport java.io.File;\n\n/**\n * Created by wuzhong on 2016/11/23.\n */\n\npublic class PatchCleaner {\n\n    public static void clearUpdatePath(String bundleUpdatePath) {\n        File updatePath = new File(bundleUpdatePath);\n        if (updatePath.exists()) {\n            File[] updatePathArray = updatePath.listFiles();\n            for (File file : updatePathArray) {\n                if (file.isDirectory()) {\n                    clearUpdatePath(file.getAbsolutePath());\n                } else {\n                    file.delete();\n                }\n            }\n            updatePath.delete();\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/update/util/PatchInstaller.java",
    "content": "package com.taobao.atlas.update.util;\n\nimport android.taobao.atlas.bundleInfo.AtlasBundleInfoManager;\nimport android.taobao.atlas.bundleInfo.BundleListing;\nimport android.taobao.atlas.framework.Atlas;\nimport android.taobao.atlas.framework.Framework;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.taobao.atlas.versionInfo.BaselineInfoManager;\nimport android.util.Pair;\n\nimport com.taobao.atlas.update.model.UpdateInfo;\n\nimport org.osgi.framework.BundleException;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\n\n\npublic class PatchInstaller {\n\n    private Map<String, Pair<String,UpdateInfo.Item>> mergeOutputs;\n    private UpdateInfo updateInfo;\n\n    public PatchInstaller(Map<String, Pair<String,UpdateInfo.Item>> mergeOutputs, UpdateInfo updateInfo) {\n        this.mergeOutputs = mergeOutputs;\n        this.updateInfo = updateInfo;\n    }\n\n\n    public void install() throws BundleException {\n\n        if (mergeOutputs.isEmpty()) {\n            throw new BundleException(\"merge bundles is empty\");\n        }\n\n        Iterator entries = mergeOutputs.entrySet().iterator();\n        List<String> bundleNameList = new ArrayList<>();\n        List<File> bundleFilePathList = new ArrayList<>();\n        List<String> upgradeVersions = new ArrayList<>();\n        List<Long> dexPatchVersions = new ArrayList<>();\n        while (entries.hasNext()) {\n            Map.Entry entry = (Map.Entry) entries.next();\n            bundleNameList.add((String) entry.getKey());\n            Pair<String, UpdateInfo.Item> bundlePair = (Pair<String, UpdateInfo.Item>) entry.getValue();\n            if(bundlePair.second.reset){\n                if (!updateInfo.dexPatch) {\n                    upgradeVersions.add(\"-1\");\n                    bundleFilePathList.add(new File(\"reset\"));\n                } else {\n                    dexPatchVersions.add(Long.valueOf(-1));\n                    bundleFilePathList.add(new File(\"reset\"));\n                }\n            }else {\n                File bundleFile = new File(bundlePair.first);\n                bundleFilePathList.add(bundleFile);\n                if (!bundleFile.exists()) {\n                    throw new BundleException(\"bundle input is wrong : \" + bundleFilePathList);\n                }\n                if (!updateInfo.dexPatch) {\n                    upgradeVersions.add(bundlePair.second.unitTag);\n                } else {\n                    dexPatchVersions.add(bundlePair.second.dexpatchVersion);\n                }\n            }\n        }\n\n        for (UpdateInfo.Item bundle : updateInfo.updateBundles) {\n            if (!bundleNameList.contains(bundle.name) && AtlasBundleInfoManager.instance().isInternalBundle(bundle.name)) {\n                if(bundle.inherit) {\n                    bundleNameList.add(bundle.name);\n                    bundleFilePathList.add(new File(\"inherit\"));\n                    if(!updateInfo.dexPatch){\n                        upgradeVersions.add(bundle.unitTag);\n                    }else{\n                        dexPatchVersions.add(bundle.dexpatchVersion);\n                    }\n                }else{\n                    throw new BundleException(\"bundle  \" + bundle.name + \" is error\");\n                }\n            }\n        }\n\n        String[] bundleNameArray = bundleNameList.toArray(new String[bundleNameList.size()]);\n        File[] bundleFilePathArray = bundleFilePathList.toArray(new File[bundleFilePathList.size()]);\n        String[] updateVersionArray = upgradeVersions.toArray(new String[upgradeVersions.size()]);\n        long[] dexPatchVersionArray = new long[dexPatchVersions.size()];\n        for(int x=0;x<dexPatchVersions.size();x++){\n            dexPatchVersionArray[x] = dexPatchVersions.get(x);\n        }\n        Framework.update(!updateInfo.dexPatch,bundleNameArray,bundleFilePathArray,updateVersionArray,dexPatchVersionArray,updateInfo.updateVersion,updateInfo.lowDisk);\n\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/update/util/PatchMerger.java",
    "content": "package com.taobao.atlas.update.util;\n\nimport android.os.Build;\nimport android.taobao.atlas.bundleInfo.AtlasBundleInfoManager;\nimport android.taobao.atlas.framework.Atlas;\nimport android.taobao.atlas.framework.BundleImpl;\nimport android.taobao.atlas.framework.Framework;\nimport android.taobao.atlas.framework.bundlestorage.BundleArchive;\nimport android.taobao.atlas.runtime.RuntimeVariables;\nimport android.taobao.atlas.util.ApkUtils;\nimport android.taobao.atlas.util.IOUtil;\nimport android.taobao.atlas.util.WrapperUtil;\nimport android.taobao.atlas.versionInfo.BaselineInfoManager;\nimport android.text.TextUtils;\nimport android.util.Pair;\n\nimport com.taobao.atlas.dexmerge.DexMergeClient;\nimport com.taobao.atlas.dexmerge.MergeCallback;\nimport com.taobao.atlas.dexmerge.MergeObject;\nimport com.taobao.atlas.update.exception.MergeException;\nimport com.taobao.atlas.update.model.UpdateInfo;\n\nimport java.io.*;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n/**\n * Created by guanjie on 15/10/8.\n */\npublic class PatchMerger {\n\n    private UpdateInfo updateInfo;\n    private File patchFile;\n    private MergeCallback mergeCallback;\n    private ZipFile apkZip;\n    private static int BUFFEREDSIZE = 1024;\n\n    public Map<String, Pair<String,UpdateInfo.Item>> mergeOutputs = new HashMap<>();\n    private static boolean supportMerge;\n    private static String MAIN_DEX = \"com.taobao.maindex\";\n    private boolean lowDisk = false;\n    static {\n        supportMerge = Build.VERSION.SDK_INT < 21;\n    }\n\n\n    public PatchMerger(UpdateInfo updateInfo, File patchFile, MergeCallback mergeCallback) throws MergeException {\n        this.updateInfo = updateInfo;\n        this.patchFile = patchFile;\n        this.mergeCallback = mergeCallback;\n        if(updateInfo.lowDisk){\n            lowDisk = true;\n        }else{\n            lowDisk = false;\n        }\n        try {\n            this.apkZip = new ZipFile(RuntimeVariables.androidApplication.getApplicationInfo().sourceDir);\n        } catch (IOException e) {\n            throw new MergeException(e);\n        }\n\n\n    }\n\n    public void merge() throws MergeException, IOException {\n\n        try {\n            File outputDirectory = updateInfo.workDir;\n            File oringnalDir = new File(outputDirectory.getParentFile(), \"orignal_\" + updateInfo.baseVersion);\n            if (!outputDirectory.exists()){\n                outputDirectory.mkdirs();\n            }\n            if (!oringnalDir.exists()){\n                oringnalDir.mkdirs();\n            }\n            ZipFile patchZip = new ZipFile(patchFile);\n            Pair<File, String>[] updateBundles = new Pair[updateInfo.updateBundles.size()];\n            List<MergeObject> toMergeList = new ArrayList<MergeObject>();\n            //find original bundle and store in pair struct\n            for (int x = 0; x < updateInfo.updateBundles.size(); x++) {\n                UpdateInfo.Item item = updateInfo.updateBundles.get(x);\n                if(item.inherit){\n                    continue;\n                }\n                String bundleName = item.name;\n                String entryNamePrefix = String.format(\"%s%s\", \"lib\", bundleName.replace(\".\", \"_\"));\n                String entryName = entryNamePrefix + \".so\";\n                ZipEntry entry = patchZip.getEntry(entryName);\n                if (patchZip.getEntry(entryName) != null && !supportMerge(bundleName)) {\n                    //全量部署\n                    File targetBundle = new File(outputDirectory, entryName);\n                    OutputStream outputStream = new FileOutputStream(targetBundle);\n                    InputStream inputStream = patchZip.getInputStream(entry);\n                    IOUtil.copyStream(inputStream, outputStream);\n                    mergeOutputs.put(bundleName, new Pair<>(targetBundle.getAbsolutePath(), item));\n                } else {\n                    if(item.reset){\n                        //回滚到基线的bundle\n                        mergeOutputs.put(bundleName, new Pair<>(\"\", item));\n                    }else {\n                        //差量部署\n//                        File baselineBundle = findOriginalBundleFile(bundleName, oringnalDir.getAbsolutePath(), item);\n                        File originalBundle = findOriginalBundleFile(bundleName, oringnalDir.getAbsolutePath(), item);\n                        if (originalBundle != null && originalBundle.exists()) {\n                            updateBundles[x] = new Pair<File, String>(originalBundle, bundleName);\n                            File targetBundle = new File(outputDirectory, \"lib\" + bundleName.replace(\".\", \"_\") + \".so\");\n                            if (targetBundle.exists()) {\n                                targetBundle.delete();\n                            }\n                            toMergeList.add(new MergeObject(updateBundles[x].first.getAbsolutePath(), updateBundles[x].second, targetBundle.getAbsolutePath()));\n                            mergeOutputs.put(bundleName, new Pair<>(targetBundle.getAbsolutePath(), item));\n                        }\n                    }\n                }\n            }\n\n            if (toMergeList.size() > 0) {\n\n                DexMergeClient dexMergeClient = getMergeClient();\n\n                boolean mergeFinish = dexMergeClient.dexMerge(patchFile.getAbsolutePath(),toMergeList, true);\n\n                dexMergeClient.unPrepare();\n\n                if (!updateInfo.dexPatch && !mergeFinish) {\n                    throw new MergeException(\"merge failed!\");\n                }\n            }\n\n\n        } catch (Exception e){\n            e.printStackTrace();\n            throw new MergeException(\"merge failed!\");\n        } finally{\n            if (apkZip != null) {\n                try {\n                    apkZip.close();\n                } catch (Throwable e) {\n                }\n            }\n\n        }\n\n    }\n\n\n\n    /**\n     * be not call in main thread\n     */\n\n\n    /**\n     * get original bundle\n     *\n     * @param bundleName\n     * @return\n     */\n    public File findOriginalBundleFile(String bundleName, String bundleDirIfNeedCreate, UpdateInfo.Item item) throws IOException {\n        if(\"com.taobao.dynamic.test\".equals(bundleName)){\n            return getOriginalBundleFromApk(bundleName,bundleDirIfNeedCreate);\n        }\n        if (bundleName.equals(MAIN_DEX)){\n            if(!updateInfo.dexPatch) {\n                return new File(RuntimeVariables.androidApplication.getApplicationInfo().sourceDir);\n            }else{\n                String maindexVersion = BaselineInfoManager.instance().getBaseBundleVersion(\"com.taobao.maindex\");\n                String currentVersionName = WrapperUtil.getPackageInfo(RuntimeVariables.androidApplication).versionName;\n                if(currentVersionName.equals(updateInfo.baseVersion)) {\n                    if (!TextUtils.isEmpty(maindexVersion)) {\n                        File old = Framework.getInstalledBundle(\"com.taobao.maindex\",maindexVersion);\n                        if (old.exists()) {\n                            return old;\n                        }\n                    } else if (updateInfo.baseVersion.equals(RuntimeVariables.sInstalledVersionName)) {\n                        return new File(RuntimeVariables.androidApplication.getApplicationInfo().sourceDir);\n                    }\n                }\n                throw new IllegalStateException(\"src version can not be null\");\n            }\n        }\n\n        if (TextUtils.isEmpty(item.srcUnitTag)) {\n            throw new IllegalStateException(\"src version can not be null\");\n        }\n\n        File oldBundle = null;\n        BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(bundleName);\n        if (impl != null && !BaselineInfoManager.instance().isDexPatched(bundleName)) {\n            String path = impl.getArchive().getCurrentRevision().getRevisionDir().getAbsolutePath();\n            if(!path.contains(BundleArchive.DEXPATCH_DIR) && AtlasBundleInfoManager.instance().getBundleInfo(bundleName).getUnique_tag().equals(item.srcUnitTag)){\n                oldBundle = impl.getArchive().getArchiveFile();\n            }\n        } else {\n            oldBundle = Framework.getInstalledBundle(bundleName, item.srcUnitTag);\n        }\n\n        if (oldBundle == null && AtlasBundleInfoManager.instance().getBundleInfo(bundleName).getUnique_tag().equals(item.srcUnitTag) && !BaselineInfoManager.instance().isUpdated(bundleName)) {\n            oldBundle = getOriginalBundleFromApk(bundleName,bundleDirIfNeedCreate);\n        }\n        if(oldBundle!=null || !AtlasBundleInfoManager.instance().isInternalBundle(bundleName)) {\n            return oldBundle;\n        }else{\n            throw new IOException(\"can not find valid src bundle of \" + bundleName);\n        }\n    }\n\n    private File getOriginalBundleFromApk(String bundleName,String bundleDirIfNeedCreate) throws IOException{\n        String oldBundleFileName = String.format(\"lib%s.so\", bundleName.replace(\".\", \"_\"));\n        File libDir = new File(RuntimeVariables.androidApplication.getFilesDir().getParentFile(), \"lib\");\n        File oldBundle = new File(libDir,oldBundleFileName);\n        if(!oldBundle.exists()){\n            oldBundle = new File(RuntimeVariables.androidApplication.getApplicationInfo().nativeLibraryDir,oldBundleFileName);\n        }\n        if (oldBundle.exists()) {\n            return oldBundle;\n        } else {\n            InputStream oldBundleStream = null;\n            try {\n                oldBundleStream = RuntimeVariables.originalResources.getAssets().open(oldBundleFileName);\n            }catch (Throwable e){}\n            if(oldBundleStream==null) {\n                if (apkZip == null) {\n                    apkZip = new ZipFile(RuntimeVariables.androidApplication.getApplicationInfo().sourceDir);\n                }\n                String entryName = String.format(\"lib/armeabi/%s\", oldBundleFileName);\n                if (apkZip.getEntry(entryName) != null) {\n                    oldBundleStream = apkZip.getInputStream(apkZip.getEntry(entryName));\n//                    return oldBundle;\n                }\n            }\n            if(oldBundleStream!= null){\n                oldBundle = new File(bundleDirIfNeedCreate, oldBundleFileName);\n                ApkUtils.copyInputStreamToFile(oldBundleStream, oldBundle);\n            }\n        }\n        return oldBundle;\n    }\n\n    private DexMergeClient getMergeClient() {\n        DexMergeClient mergeClient = new DexMergeClient(mergeCallback);\n        boolean result = mergeClient.prepare();\n        if (result) {\n            return mergeClient;\n        }\n        throw new RuntimeException(\"prepare client error\");\n    }\n\n\n    private boolean supportMerge(String bundleName) {\n\n        return (lowDisk || supportMerge)&&bundleName.equals(MAIN_DEX);\n\n    }\n}"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/atlas/update/util/ZipUtils.java",
    "content": "package com.taobao.atlas.update.util;\n\nimport java.io.Closeable;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.Enumeration;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n/**\n * Created by wuzhong on 2016/11/23.\n */\n\npublic class ZipUtils {\n\n    private static int BUFFEREDSIZE = 1024;\n\n    public static void unzip(String zipFilename, String outputDirectory)\n            throws IOException {\n        File outFile = new File(outputDirectory);\n        if (!outFile.exists()) {\n            outFile.mkdirs();\n        }\n        if (!outFile.exists()) {\n            throw new IOException(\"file not exist\");\n        }\n        ZipFile zipFile = new ZipFile(zipFilename);\n        Enumeration en = zipFile.entries();\n        ZipEntry zipEntry = null;\n        while (en.hasMoreElements()) {\n            zipEntry = (ZipEntry) en.nextElement();\n            if (zipEntry.isDirectory()) {\n                String dirName = zipEntry.getName();\n                dirName = dirName.substring(0, dirName.length() - 1);\n                File f = new File(outFile.getPath() + File.separator + dirName);\n                f.mkdirs();\n            } else {\n                String strFilePath = outFile.getPath() + File.separator\n                        + zipEntry.getName();\n                File f = new File(strFilePath);\n\n                // 判断文件不存在的话，就创建该文件所在文件夹的目录\n                if (!f.exists()) {\n                    String[] arrFolderName = zipEntry.getName().split(\"/\");\n                    String strRealFolder = \"\";\n                    for (int i = 0; i < (arrFolderName.length - 1); i++) {\n                        strRealFolder += arrFolderName[i] + File.separator;\n                    }\n                    strRealFolder = outFile.getPath() + File.separator\n                            + strRealFolder;\n                    File tempDir = new File(strRealFolder);\n                    tempDir.mkdirs();\n                }\n                f.createNewFile();\n                InputStream in = zipFile.getInputStream(zipEntry);\n                FileOutputStream out = new FileOutputStream(f);\n                try {\n                    int c;\n                    byte[] by = new byte[BUFFEREDSIZE];\n                    while ((c = in.read(by)) != -1) {\n                        out.write(by, 0, c);\n                    }\n                    out.flush();\n                } catch (IOException e) {\n                    throw e;\n                } finally {\n                    closeQuitely(out);\n                    closeQuitely(in);\n                }\n            }\n        }\n        zipFile.close();\n    }\n\n    private static void closeQuitely(Closeable stream) {\n        try {\n            if (stream != null)\n                stream.close();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/plugins/RxAndroidPlugins.java",
    "content": "package com.taobao.plugins;\n\nimport io.reactivex.Scheduler;\nimport io.reactivex.exceptions.Exceptions;\nimport io.reactivex.functions.Function;\n\nimport java.util.concurrent.Callable;\n\n/**\n * @author lilong\n * @create 2017-06-05 上午9:48\n */\n\npublic final class RxAndroidPlugins {\n\n    private static volatile Function<Callable<Scheduler>, Scheduler> onInitMainThreadHandler;\n    private static volatile Function<Scheduler, Scheduler> onMainThreadHandler;\n\n    public static void setInitMainThreadSchedulerHandler(Function<Callable<Scheduler>, Scheduler> handler) {\n        onInitMainThreadHandler = handler;\n    }\n\n    public static Scheduler initMainThreadScheduler(Callable<Scheduler> scheduler) {\n        if (scheduler == null) {\n            throw new NullPointerException(\"scheduler == null\");\n        }\n\n        Function<Callable<Scheduler>, Scheduler> f = onInitMainThreadHandler;\n        if (f == null) {\n            return callRequireNonNull(scheduler);\n        }\n        return applyRequireNonNull(f, scheduler);\n    }\n\n    public static void setMainThreadSchedulerHandler(Function<Scheduler, Scheduler> handler) {\n        onMainThreadHandler = handler;\n    }\n\n    public static Scheduler onMainThreadScheduler(Scheduler scheduler) {\n        if (scheduler == null) {\n            throw new NullPointerException(\"scheduler == null\");\n        }\n        Function<Scheduler, Scheduler> f = onMainThreadHandler;\n        if (f == null) {\n            return scheduler;\n        }\n        return apply(f, scheduler);\n    }\n\n    /**\n     * Returns the current hook function.\n     * @return the hook function, may be null\n     */\n    public static Function<Callable<Scheduler>, Scheduler> getInitMainThreadSchedulerHandler() {\n        return onInitMainThreadHandler;\n    }\n\n    /**\n     * Returns the current hook function.\n     * @return the hook function, may be null\n     */\n    public static Function<Scheduler, Scheduler> getOnMainThreadSchedulerHandler() {\n        return onMainThreadHandler;\n    }\n\n    /**\n     * Removes all handlers and resets the default behavior.\n     */\n    public static void reset() {\n        setInitMainThreadSchedulerHandler(null);\n        setMainThreadSchedulerHandler(null);\n    }\n\n    static Scheduler callRequireNonNull(Callable<Scheduler> s) {\n        try {\n            Scheduler scheduler = s.call();\n            if (scheduler == null) {\n                throw new NullPointerException(\"Scheduler Callable returned null\");\n            }\n            return scheduler;\n        } catch (Throwable ex) {\n            throw Exceptions.propagate(ex);\n        }\n    }\n\n    static Scheduler applyRequireNonNull(Function<Callable<Scheduler>, Scheduler> f, Callable<Scheduler> s) {\n        Scheduler scheduler = apply(f,s);\n        if (scheduler == null) {\n            throw new NullPointerException(\"Scheduler Callable returned null\");\n        }\n        return scheduler;\n    }\n\n    static <T, R> R apply(Function<T, R> f, T t) {\n        try {\n            return f.apply(t);\n        } catch (Throwable ex) {\n            throw Exceptions.propagate(ex);\n        }\n    }\n\n    private RxAndroidPlugins() {\n        throw new AssertionError(\"No instances.\");\n    }\n}\n\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/schedulers/AndroidSchedulers.java",
    "content": "package com.taobao.schedulers;\n\nimport android.os.Handler;\nimport android.os.Looper;\nimport com.taobao.plugins.RxAndroidPlugins;\nimport io.reactivex.Scheduler;\n\nimport java.util.concurrent.Callable;\n\n/**\n * @author lilong\n * @create 2017-06-05 上午9:50\n */\npublic final class AndroidSchedulers {\n\n    private static final class MainHolder {\n\n        static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));\n    }\n\n    private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(\n            new Callable<Scheduler>() {\n                @Override public Scheduler call() throws Exception {\n                    return MainHolder.DEFAULT;\n                }\n            });\n\n    /** A {@link Scheduler} which executes actions on the Android main thread. */\n    public static Scheduler mainThread() {\n        return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);\n    }\n\n    /** A {@link Scheduler} which executes actions on {@code looper}. */\n    public static Scheduler from(Looper looper) {\n        if (looper == null) throw new NullPointerException(\"looper == null\");\n        return new HandlerScheduler(new Handler(looper));\n    }\n\n    private AndroidSchedulers() {\n        throw new AssertionError(\"No instances.\");\n    }\n}\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/schedulers/HandlerScheduler.java",
    "content": "package com.taobao.schedulers;\n\nimport android.os.Handler;\nimport android.os.Message;\nimport io.reactivex.Scheduler;\nimport io.reactivex.disposables.Disposable;\nimport io.reactivex.disposables.Disposables;\nimport io.reactivex.plugins.RxJavaPlugins;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * @author lilong\n * @create 2017-06-05 上午9:51\n */\n\nfinal class HandlerScheduler extends Scheduler {\n    private final Handler handler;\n\n    HandlerScheduler(Handler handler) {\n        this.handler = handler;\n    }\n\n    @Override\n    public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) {\n        if (run == null) throw new NullPointerException(\"run == null\");\n        if (unit == null) throw new NullPointerException(\"unit == null\");\n\n        run = RxJavaPlugins.onSchedule(run);\n        ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);\n        handler.postDelayed(scheduled, Math.max(0L, unit.toMillis(delay)));\n        return scheduled;\n    }\n\n    @Override\n    public Worker createWorker() {\n        return new HandlerWorker(handler);\n    }\n\n    private static final class HandlerWorker extends Worker {\n        private final Handler handler;\n\n        private volatile boolean disposed;\n\n        HandlerWorker(Handler handler) {\n            this.handler = handler;\n        }\n\n        @Override\n        public Disposable schedule(Runnable run, long delay, TimeUnit unit) {\n            if (run == null) throw new NullPointerException(\"run == null\");\n            if (unit == null) throw new NullPointerException(\"unit == null\");\n\n            if (disposed) {\n                return Disposables.disposed();\n            }\n\n            run = RxJavaPlugins.onSchedule(run);\n\n            ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);\n\n            Message message = Message.obtain(handler, scheduled);\n            message.obj = this; // Used as token for batch disposal of this worker's runnables.\n\n            handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));\n\n            // Re-check disposed state for removing in case we were racing a call to dispose().\n            if (disposed) {\n                handler.removeCallbacks(scheduled);\n                return Disposables.disposed();\n            }\n\n            return scheduled;\n        }\n\n        @Override\n        public void dispose() {\n            disposed = true;\n            handler.removeCallbacksAndMessages(this /* token */);\n        }\n\n        @Override\n        public boolean isDisposed() {\n            return disposed;\n        }\n    }\n\n    private static final class ScheduledRunnable implements Runnable, Disposable {\n        private final Handler handler;\n        private final Runnable delegate;\n\n        private volatile boolean disposed;\n\n        ScheduledRunnable(Handler handler, Runnable delegate) {\n            this.handler = handler;\n            this.delegate = delegate;\n        }\n\n        @Override\n        public void run() {\n            try {\n                delegate.run();\n            } catch (Throwable t) {\n                IllegalStateException ie =\n                        new IllegalStateException(\"Fatal Exception thrown on Scheduler.\", t);\n                RxJavaPlugins.onError(ie);\n                Thread thread = Thread.currentThread();\n                thread.getUncaughtExceptionHandler().uncaughtException(thread, ie);\n            }\n        }\n\n        @Override\n        public void dispose() {\n            disposed = true;\n            handler.removeCallbacks(this);\n        }\n\n        @Override\n        public boolean isDisposed() {\n            return disposed;\n        }\n    }\n}\n\n"
  },
  {
    "path": "atlas-update/src/main/java/com/taobao/utils/SparseIntArray.java",
    "content": "/*\n * Copyright (C) 2006 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.taobao.utils;\n\n/**\n * SparseIntArrays map integers to integers.  Unlike a normal array of integers,\n * there can be gaps in the indices.  It is intended to be more memory efficient\n * than using a HashMap to map Integers to Integers, both because it avoids\n * auto-boxing keys and values and its data structure doesn't rely on an extra entry object\n * for each mapping.\n *\n * <p>Note that this container keeps its mappings in an array data structure,\n * using a binary search to find keys.  The implementation is not intended to be appropriate for\n * data structures\n * that may contain large numbers of items.  It is generally slower than a traditional\n * HashMap, since lookups require a binary search and adds and removes require inserting\n * and deleting entries in the array.  For containers holding up to hundreds of items,\n * the performance difference is not significant, less than 50%.</p>\n *\n * <p>It is possible to iterate over the items in this container using\n * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using\n * <code>keyAt(int)</code> with ascending values of the index will return the\n * keys in ascending order, or the values corresponding to the keys in ascending\n * order in the case of <code>valueAt(int)</code>.</p>\n */\npublic class SparseIntArray implements Cloneable {\n    private static final int[] EMPTY_INT_ARRAY = new int[0];\n    private int[] mKeys;\n    private int[] mValues;\n    private int   mSize;\n\n    /**\n     * Creates a new SparseIntArray containing no mappings.\n     */\n    public SparseIntArray() {\n        this(10);\n    }\n\n    /**\n     * Creates a new SparseIntArray containing no mappings that will not\n     * require any additional memory allocation to store the specified\n     * number of mappings.  If you supply an initial capacity of 0, the\n     * sparse array will be initialized with a light-weight representation\n     * not requiring any additional array allocations.\n     */\n    public SparseIntArray(int initialCapacity) {\n        if (initialCapacity == 0) {\n            mKeys = SparseIntArray.EMPTY_INT_ARRAY;\n            mValues = SparseIntArray.EMPTY_INT_ARRAY;\n        } else {\n            mKeys = new int[initialCapacity];\n            mValues = new int[mKeys.length];\n        }\n        mSize = 0;\n    }\n\n    /**\n     * Given the current size of an array, returns an ideal size to which the array should grow.\n     * This is typically double the given size, but should not be relied upon to do so in the\n     * future.\n     */\n    public static int growSize(int currentSize) {\n        return currentSize <= 4 ? 8 : currentSize + (currentSize >> 1);\n    }\n\n    @Override\n    public SparseIntArray clone() {\n        SparseIntArray clone = null;\n        try {\n            clone = (SparseIntArray) super.clone();\n            clone.mKeys = mKeys.clone();\n            clone.mValues = mValues.clone();\n        } catch (CloneNotSupportedException cnse) {\n            /* ignore */\n        }\n        return clone;\n    }\n\n    /**\n     * Gets the int mapped from the specified key, or <code>0</code>\n     * if no such mapping has been made.\n     */\n    public int get(int key) {\n        return get(key, 0);\n    }\n\n    /**\n     * Gets the int mapped from the specified key, or the specified value\n     * if no such mapping has been made.\n     */\n    public int get(int key, int valueIfKeyNotFound) {\n        int i = binarySearch(mKeys, mSize, key);\n\n        if (i < 0) {\n            return valueIfKeyNotFound;\n        } else {\n            return mValues[i];\n        }\n    }\n\n    /**\n     * Removes the mapping from the specified key, if there was any.\n     */\n    public void delete(int key) {\n        int i = binarySearch(mKeys, mSize, key);\n\n        if (i >= 0) {\n            removeAt(i);\n        }\n    }\n\n    /**\n     * Removes the mapping at the given index.\n     */\n    public void removeAt(int index) {\n        System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));\n        System.arraycopy(mValues, index + 1, mValues, index, mSize - (index + 1));\n        --mSize;\n    }\n\n    /**\n     * Adds a mapping from the specified key to the specified value,\n     * replacing the previous mapping from the specified key if there\n     * was one.\n     */\n    public void put(int key, int value) {\n        int i = binarySearch(mKeys, mSize, key);\n\n        if (i >= 0) {\n            mValues[i] = value;\n        } else {\n            i = ~i;\n            mKeys = insertElementIntoIntArray(mKeys, mSize, i, key);\n            mValues = insertElementIntoIntArray(mValues, mSize, i, value);\n            ++mSize;\n        }\n    }\n\n    /**\n     * Returns the number of key-value mappings that this SparseIntArray\n     * currently stores.\n     */\n    public int size() {\n        return mSize;\n    }\n\n    /**\n     * Given an index in the range <code>0...size()-1</code>, returns\n     * the key from the <code>index</code>th key-value mapping that this\n     * SparseIntArray stores.\n     *\n     * <p>The keys corresponding to indices in ascending order are guaranteed to\n     * be in ascending order, e.g., <code>keyAt(0)</code> will return the\n     * smallest key and <code>keyAt(size()-1)</code> will return the largest\n     * key.</p>\n     */\n    public int keyAt(int index) {\n        return mKeys[index];\n    }\n\n    /**\n     * Given an index in the range <code>0...size()-1</code>, returns\n     * the value from the <code>index</code>th key-value mapping that this\n     * SparseIntArray stores.\n     *\n     * <p>The values corresponding to indices in ascending order are guaranteed\n     * to be associated with keys in ascending order, e.g.,\n     * <code>valueAt(0)</code> will return the value associated with the\n     * smallest key and <code>valueAt(size()-1)</code> will return the value\n     * associated with the largest key.</p>\n     */\n    public int valueAt(int index) {\n        return mValues[index];\n    }\n\n    /**\n     * Returns the index for which {@link #keyAt} would return the\n     * specified key, or a negative number if the specified\n     * key is not mapped.\n     */\n    public int indexOfKey(int key) {\n        return binarySearch(mKeys, mSize, key);\n    }\n\n    /**\n     * Returns an index for which {@link #valueAt} would return the\n     * specified key, or a negative number if no keys map to the\n     * specified value.\n     * Beware that this is a linear search, unlike lookups by key,\n     * and that multiple keys can map to the same value and this will\n     * find only one of them.\n     */\n    public int indexOfValue(int value) {\n        for (int i = 0; i < mSize; ++i) {\n            if (mValues[i] == value) {\n                return i;\n            }\n        }\n        return -1;\n    }\n\n    /**\n     * Removes all key-value mappings from this SparseIntArray.\n     */\n    public void clear() {\n        mSize = 0;\n    }\n\n    /**\n     * Puts a key/value pair into the array, optimizing for the case where\n     * the key is greater than all existing keys in the array.\n     */\n    public void append(int key, int value) {\n        if (mSize != 0 && key <= mKeys[mSize - 1]) {\n            put(key, value);\n            return;\n        }\n\n        mKeys = appendElementIntoIntArray(mKeys, mSize, key);\n        mValues = appendElementIntoIntArray(mValues, mSize, value);\n        mSize++;\n    }\n\n    private int binarySearch(int[] array, int size, int value) {\n        int lo = 0;\n        int hi = size - 1;\n\n        while (lo <= hi) {\n            int mid = (lo + hi) >>> 1;\n            int midVal = array[mid];\n\n            if (midVal < value) {\n                lo = mid + 1;\n            } else if (midVal > value) {\n                hi = mid - 1;\n            } else {\n                return mid;  // value found\n            }\n        }\n        return ~lo;  // value not present\n    }\n\n    private int[] appendElementIntoIntArray(int[] array, int currentSize, int element) {\n        if (currentSize > array.length) {\n            throw new IllegalArgumentException(\"Bad currentSize, originalSize: \" + array.length + \" currentSize: \" + currentSize);\n        }\n        if (currentSize + 1 > array.length) {\n            int[] newArray = new int[SparseIntArray.growSize(currentSize)];\n            System.arraycopy(array, 0, newArray, 0, currentSize);\n            array = newArray;\n        }\n        array[currentSize] = element;\n        return array;\n    }\n\n    private int[] insertElementIntoIntArray(int[] array, int currentSize, int index, int element) {\n        if (currentSize > array.length) {\n            throw new IllegalArgumentException(\"Bad currentSize, originalSize: \" + array.length + \" currentSize: \" + currentSize);\n        }\n\n        if (currentSize + 1 <= array.length) {\n            System.arraycopy(array, index, array, index + 1, currentSize - index);\n            array[index] = element;\n            return array;\n        }\n\n        int[] newArray = new int[SparseIntArray.growSize(currentSize)];\n        System.arraycopy(array, 0, newArray, 0, index);\n        newArray[index] = element;\n        System.arraycopy(array, index, newArray, index + 1, array.length - index);\n        return newArray;\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p>This implementation composes a string by iterating over its mappings.\n     */\n    @Override\n    public String toString() {\n        if (size() <= 0) {\n            return \"{}\";\n        }\n\n        StringBuilder buffer = new StringBuilder(mSize * 28);\n        buffer.append('{');\n        for (int i = 0; i < mSize; i++) {\n            if (i > 0) {\n                buffer.append(\", \");\n            }\n            int key = keyAt(i);\n            buffer.append(key);\n            buffer.append('=');\n            int value = valueAt(i);\n            buffer.append(value);\n        }\n        buffer.append('}');\n        return buffer.toString();\n    }\n}\n"
  }
]